summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbrianluau <brianluau@54d463be-8e91-2dee-dedb-b68131a5f0ec>2012-12-05 02:53:33 +0000
committerbrianluau <brianluau@54d463be-8e91-2dee-dedb-b68131a5f0ec>2012-12-05 02:53:33 +0000
commit60a426c0742b3e7d8c5b557c7578df6eeeea377b (patch)
tree5d01f9ccc2798309f9b13f07c0096ed97c6a85c8 /src
parent621db2441f69736a6c8f10d26bf966d5414fac74 (diff)
downloadhercules-60a426c0742b3e7d8c5b557c7578df6eeeea377b.tar.gz
hercules-60a426c0742b3e7d8c5b557c7578df6eeeea377b.tar.bz2
hercules-60a426c0742b3e7d8c5b557c7578df6eeeea377b.tar.xz
hercules-60a426c0742b3e7d8c5b557c7578df6eeeea377b.zip
- Undid r16968: SVN Replaced with source:/trunk/src/@16966 (tid:74924).
[16969:16991/trunk/src/] will be re-committed in the next 24 hours. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@16992 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src')
-rw-r--r--src/char/char.c8167
-rw-r--r--src/char/char.h19
-rw-r--r--src/char/int_auction.c754
-rw-r--r--src/char/int_elemental.c266
-rw-r--r--src/char/int_guild.c3072
-rw-r--r--src/char/int_guild.h26
-rw-r--r--src/char/int_homun.c469
-rw-r--r--src/char/int_homun.h4
-rw-r--r--src/char/int_mail.c721
-rw-r--r--src/char/int_mail.h4
-rw-r--r--src/char/int_mercenary.c266
-rw-r--r--src/char/int_party.c1367
-rw-r--r--src/char/int_party.h12
-rw-r--r--src/char/int_pet.c505
-rw-r--r--src/char/int_quest.c250
-rw-r--r--src/char/int_storage.c352
-rw-r--r--src/char/int_storage.h2
-rw-r--r--src/char/inter.c2022
-rw-r--r--src/char/inter.h4
-rw-r--r--src/common/atomic.h139
-rw-r--r--src/common/cbasetypes.h147
-rw-r--r--src/common/conf.c147
-rw-r--r--src/common/core.c447
-rw-r--r--src/common/core.h29
-rw-r--r--src/common/db.c3246
-rw-r--r--src/common/db.h1041
-rw-r--r--src/common/des.c316
-rw-r--r--src/common/des.h12
-rw-r--r--src/common/ers.c316
-rw-r--r--src/common/ers.h106
-rw-r--r--src/common/evdp.h130
-rw-r--r--src/common/evdp_epoll.c356
-rw-r--r--src/common/grfio.c1205
-rw-r--r--src/common/grfio.h14
-rw-r--r--src/common/malloc.c1006
-rw-r--r--src/common/malloc.h58
-rw-r--r--src/common/mapindex.c251
-rw-r--r--src/common/mapindex.h10
-rw-r--r--src/common/md5calc.c362
-rw-r--r--src/common/md5calc.h6
-rw-r--r--src/common/mempool.c899
-rw-r--r--src/common/mempool.h62
-rw-r--r--src/common/mmo.h929
-rw-r--r--src/common/mutex.c256
-rw-r--r--src/common/mutex.h50
-rw-r--r--src/common/netbuffer.c349
-rw-r--r--src/common/netbuffer.h78
-rw-r--r--src/common/network.c1809
-rw-r--r--src/common/network.h220
-rw-r--r--src/common/nullpo.c96
-rw-r--r--src/common/nullpo.h30
-rw-r--r--src/common/raconf.c1037
-rw-r--r--src/common/raconf.h34
-rw-r--r--src/common/random.c36
-rw-r--r--src/common/showmsg.c1351
-rw-r--r--src/common/showmsg.h104
-rw-r--r--src/common/socket.c1983
-rw-r--r--src/common/socket.h75
-rw-r--r--src/common/spinlock.h108
-rw-r--r--src/common/sql.c1216
-rw-r--r--src/common/sql.h139
-rw-r--r--src/common/strlib.c1729
-rw-r--r--src/common/strlib.h119
-rw-r--r--src/common/thread.c384
-rw-r--r--src/common/thread.h62
-rw-r--r--src/common/timer.c479
-rw-r--r--src/common/timer.h32
-rw-r--r--src/common/utils.c403
-rw-r--r--src/common/utils.h8
-rw-r--r--src/common/winapi.h6
-rw-r--r--src/config/const.h74
-rw-r--r--src/login/account.h227
-rw-r--r--src/login/account_sql.c1123
-rw-r--r--src/login/ipban.h2
-rw-r--r--src/login/ipban_sql.c340
-rw-r--r--src/login/login.c3198
-rw-r--r--src/login/login.h123
-rw-r--r--src/login/loginlog.h4
-rw-r--r--src/login/loginlog_sql.c241
-rw-r--r--src/map/atcommand.c14104
-rw-r--r--src/map/atcommand.h28
-rw-r--r--src/map/battle.c10852
-rw-r--r--src/map/battle.h850
-rw-r--r--src/map/battleground.c329
-rw-r--r--src/map/battleground.h26
-rw-r--r--src/map/buyingstore.c804
-rw-r--r--src/map/buyingstore.h32
-rw-r--r--src/map/chat.c570
-rw-r--r--src/map/chat.h50
-rw-r--r--src/map/chrif.c2531
-rw-r--r--src/map/chrif.h38
-rw-r--r--src/map/clif.c21224
-rw-r--r--src/map/clif.h842
-rw-r--r--src/map/date.c66
-rw-r--r--src/map/duel.c248
-rw-r--r--src/map/duel.h20
-rw-r--r--src/map/elemental.c1458
-rw-r--r--src/map/elemental.h56
-rw-r--r--src/map/guild.c2853
-rw-r--r--src/map/guild.h26
-rw-r--r--src/map/homunculus.c2062
-rw-r--r--src/map/homunculus.h110
-rw-r--r--src/map/instance.c631
-rw-r--r--src/map/instance.h32
-rw-r--r--src/map/intif.c3021
-rw-r--r--src/map/intif.h20
-rw-r--r--src/map/itemdb.c2238
-rw-r--r--src/map/itemdb.h226
-rw-r--r--src/map/log.c878
-rw-r--r--src/map/log.h107
-rw-r--r--src/map/mail.c226
-rw-r--r--src/map/mail.h2
-rw-r--r--src/map/map.c5622
-rw-r--r--src/map/map.h967
-rw-r--r--src/map/mapreg.h6
-rw-r--r--src/map/mapreg_sql.c311
-rw-r--r--src/map/mercenary.c640
-rw-r--r--src/map/mercenary.h58
-rw-r--r--src/map/mob.c7791
-rw-r--r--src/map/mob.h359
-rw-r--r--src/map/npc.c6196
-rw-r--r--src/map/npc.h219
-rw-r--r--src/map/npc_chat.c568
-rw-r--r--src/map/party.c1823
-rw-r--r--src/map/party.h52
-rw-r--r--src/map/path.c686
-rw-r--r--src/map/path.h10
-rw-r--r--src/map/pc.c16190
-rw-r--r--src/map/pc.h1190
-rw-r--r--src/map/pc_groups.c657
-rw-r--r--src/map/pc_groups.h92
-rw-r--r--src/map/pet.c2286
-rw-r--r--src/map/pet.h140
-rw-r--r--src/map/quest.c516
-rw-r--r--src/map/quest.h26
-rw-r--r--src/map/script.c26263
-rw-r--r--src/map/script.h238
-rw-r--r--src/map/searchstore.c593
-rw-r--r--src/map/searchstore.h77
-rw-r--r--src/map/skill.c33312
-rw-r--r--src/map/skill.h3268
-rw-r--r--src/map/status.c20358
-rw-r--r--src/map/status.h3129
-rw-r--r--src/map/storage.c922
-rw-r--r--src/map/storage.h4
-rw-r--r--src/map/trade.c1014
-rw-r--r--src/map/trade.h4
-rw-r--r--src/map/unit.c4228
-rw-r--r--src/map/unit.h104
-rw-r--r--src/map/vending.c654
-rw-r--r--src/map/vending.h24
-rw-r--r--src/test/test_spinlock.c160
-rw-r--r--src/tool/mapcache.c484
153 files changed, 127489 insertions, 127353 deletions
diff --git a/src/char/char.c b/src/char/char.c
index dc1dd6a72..234a91b79 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -30,9 +30,9 @@
#include <stdlib.h>
// private declarations
-#define CHAR_CONF_NAME "conf/char_athena.conf"
-#define LAN_CONF_NAME "conf/subnet_athena.conf"
-#define SQL_CONF_NAME "conf/inter_athena.conf"
+#define CHAR_CONF_NAME "conf/char_athena.conf"
+#define LAN_CONF_NAME "conf/subnet_athena.conf"
+#define SQL_CONF_NAME "conf/inter_athena.conf"
char char_db[256] = "char";
char scdata_db[256] = "sc_data";
@@ -68,18 +68,18 @@ char ragsrvinfo_db[256] = "ragsrvinfo";
// show loading/saving messages
int save_log = 1;
-static DBMap *char_db_; // int char_id -> struct mmo_charstatus*
+static DBMap* char_db_; // int char_id -> struct mmo_charstatus*
char db_path[1024] = "db";
int db_use_sqldbs;
struct mmo_map_server {
- int fd;
- uint32 ip;
- uint16 port;
- int users;
- unsigned short map[MAX_MAP_PER_SERVER];
+ int fd;
+ uint32 ip;
+ uint16 port;
+ int users;
+ unsigned short map[MAX_MAP_PER_SERVER];
} server[MAX_MAP_SERVERS];
int login_fd=-1, char_fd=-1;
@@ -109,28 +109,28 @@ int char_per_account = 0; //Maximum chars per account (default unlimited) [Siriu
int char_del_level = 0; //From which level u can delete character [Lupus]
int char_del_delay = 86400;
-int log_char = 1; // loggin char or not [devil]
-int log_inter = 1; // loggin inter or not [devil]
+int log_char = 1; // loggin char or not [devil]
+int log_inter = 1; // loggin inter or not [devil]
// Advanced subnet check [LuzZza]
struct s_subnet {
- uint32 mask;
- uint32 char_ip;
- uint32 map_ip;
+ uint32 mask;
+ uint32 char_ip;
+ uint32 map_ip;
} subnet[16];
int subnet_count = 0;
struct char_session_data {
- bool auth; // whether the session is authed or not
- int account_id, login_id1, login_id2, sex;
- int found_char[MAX_CHARS]; // ids of chars on this account
- char email[40]; // e-mail (default: a@a.com) by [Yor]
- time_t expiration_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited)
- int group_id; // permission
- uint32 version;
- uint8 clienttype;
- char new_name[NAME_LENGTH];
- char birthdate[10+1]; // YYYY-MM-DD
+ bool auth; // whether the session is authed or not
+ int account_id, login_id1, login_id2, sex;
+ int found_char[MAX_CHARS]; // ids of chars on this account
+ char email[40]; // e-mail (default: a@a.com) by [Yor]
+ time_t expiration_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited)
+ int group_id; // permission
+ uint32 version;
+ uint8 clienttype;
+ char new_name[NAME_LENGTH];
+ char birthdate[10+1]; // YYYY-MM-DD
};
int max_connect_user = 0;
@@ -167,32 +167,32 @@ int console = 0;
#define AUTH_TIMEOUT 30000
struct auth_node {
- int account_id;
- int char_id;
- uint32 login_id1;
- uint32 login_id2;
- uint32 ip;
- int sex;
- time_t expiration_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited)
- int group_id;
- unsigned changing_mapservers : 1;
+ int account_id;
+ int char_id;
+ uint32 login_id1;
+ uint32 login_id2;
+ uint32 ip;
+ int sex;
+ time_t expiration_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited)
+ int group_id;
+ unsigned changing_mapservers : 1;
};
-static DBMap *auth_db; // int account_id -> struct auth_node*
+static DBMap* auth_db; // int account_id -> struct auth_node*
//-----------------------------------------------------
// Online User Database
//-----------------------------------------------------
struct online_char_data {
- int account_id;
- int char_id;
- int fd;
- int waiting_disconnect;
- short server; // -2: unknown server, -1: not connected, 0+: id of server
+ int account_id;
+ int char_id;
+ int fd;
+ int waiting_disconnect;
+ short server; // -2: unknown server, -1: not connected, 0+: id of server
};
-static DBMap *online_char_db; // int account_id -> struct online_char_data*
+static DBMap* online_char_db; // int account_id -> struct online_char_data*
static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr_t data);
int delete_char_sql(int char_id);
@@ -201,129 +201,137 @@ int delete_char_sql(int char_id);
*/
static DBData create_online_char_data(DBKey key, va_list args)
{
- struct online_char_data *character;
- CREATE(character, struct online_char_data, 1);
- character->account_id = key.i;
- character->char_id = -1;
- character->server = -1;
- character->fd = -1;
- character->waiting_disconnect = INVALID_TIMER;
- return db_ptr2data(character);
+ struct online_char_data* character;
+ CREATE(character, struct online_char_data, 1);
+ character->account_id = key.i;
+ character->char_id = -1;
+ character->server = -1;
+ character->fd = -1;
+ character->waiting_disconnect = INVALID_TIMER;
+ return db_ptr2data(character);
}
void set_char_charselect(int account_id)
{
- struct online_char_data *character;
+ struct online_char_data* character;
- character = (struct online_char_data *)idb_ensure(online_char_db, account_id, create_online_char_data);
+ character = (struct online_char_data*)idb_ensure(online_char_db, account_id, create_online_char_data);
- if (character->server > -1)
- if (server[character->server].users > 0) // Prevent this value from going negative.
- server[character->server].users--;
+ if( character->server > -1 )
+ if( server[character->server].users > 0 ) // Prevent this value from going negative.
+ server[character->server].users--;
- character->char_id = -1;
- character->server = -1;
+ character->char_id = -1;
+ character->server = -1;
- if (character->waiting_disconnect != INVALID_TIMER) {
- delete_timer(character->waiting_disconnect, chardb_waiting_disconnect);
- character->waiting_disconnect = INVALID_TIMER;
- }
+ if(character->waiting_disconnect != INVALID_TIMER) {
+ delete_timer(character->waiting_disconnect, chardb_waiting_disconnect);
+ character->waiting_disconnect = INVALID_TIMER;
+ }
- if (login_fd > 0 && !session[login_fd]->flag.eof) {
- WFIFOHEAD(login_fd,6);
- WFIFOW(login_fd,0) = 0x272b;
- WFIFOL(login_fd,2) = account_id;
- WFIFOSET(login_fd,6);
- }
+ if (login_fd > 0 && !session[login_fd]->flag.eof)
+ {
+ WFIFOHEAD(login_fd,6);
+ WFIFOW(login_fd,0) = 0x272b;
+ WFIFOL(login_fd,2) = account_id;
+ WFIFOSET(login_fd,6);
+ }
}
void set_char_online(int map_id, int char_id, int account_id)
{
- struct online_char_data *character;
- struct mmo_charstatus *cp;
-
- //Update DB
- if (SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `online`='1' WHERE `char_id`='%d' LIMIT 1", char_db, char_id))
- Sql_ShowDebug(sql_handle);
-
- //Check to see for online conflicts
- character = (struct online_char_data *)idb_ensure(online_char_db, account_id, create_online_char_data);
- if (character->char_id != -1 && character->server > -1 && character->server != map_id) {
- ShowNotice("set_char_online: Character %d:%d marked in map server %d, but map server %d claims to have (%d:%d) online!\n",
- character->account_id, character->char_id, character->server, map_id, account_id, char_id);
- mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 2);
- }
-
- //Update state data
- character->char_id = char_id;
- character->server = map_id;
-
- if (character->server > -1)
- server[character->server].users++;
-
- //Get rid of disconnect timer
- if (character->waiting_disconnect != INVALID_TIMER) {
- delete_timer(character->waiting_disconnect, chardb_waiting_disconnect);
- character->waiting_disconnect = INVALID_TIMER;
- }
-
- //Set char online in guild cache. If char is in memory, use the guild id on it, otherwise seek it.
- cp = (struct mmo_charstatus *)idb_get(char_db_,char_id);
- inter_guild_CharOnline(char_id, cp?cp->guild_id:-1);
-
- //Notify login server
- if (login_fd > 0 && !session[login_fd]->flag.eof) {
- WFIFOHEAD(login_fd,6);
- WFIFOW(login_fd,0) = 0x272b;
- WFIFOL(login_fd,2) = account_id;
- WFIFOSET(login_fd,6);
- }
+ struct online_char_data* character;
+ struct mmo_charstatus *cp;
+
+ //Update DB
+ if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `online`='1' WHERE `char_id`='%d' LIMIT 1", char_db, char_id) )
+ Sql_ShowDebug(sql_handle);
+
+ //Check to see for online conflicts
+ character = (struct online_char_data*)idb_ensure(online_char_db, account_id, create_online_char_data);
+ if( character->char_id != -1 && character->server > -1 && character->server != map_id )
+ {
+ ShowNotice("set_char_online: Character %d:%d marked in map server %d, but map server %d claims to have (%d:%d) online!\n",
+ character->account_id, character->char_id, character->server, map_id, account_id, char_id);
+ mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 2);
+ }
+
+ //Update state data
+ character->char_id = char_id;
+ character->server = map_id;
+
+ if( character->server > -1 )
+ server[character->server].users++;
+
+ //Get rid of disconnect timer
+ if(character->waiting_disconnect != INVALID_TIMER) {
+ delete_timer(character->waiting_disconnect, chardb_waiting_disconnect);
+ character->waiting_disconnect = INVALID_TIMER;
+ }
+
+ //Set char online in guild cache. If char is in memory, use the guild id on it, otherwise seek it.
+ cp = (struct mmo_charstatus*)idb_get(char_db_,char_id);
+ inter_guild_CharOnline(char_id, cp?cp->guild_id:-1);
+
+ //Notify login server
+ if (login_fd > 0 && !session[login_fd]->flag.eof)
+ {
+ WFIFOHEAD(login_fd,6);
+ 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)
{
- struct online_char_data *character;
-
- if (char_id == -1) {
- if (SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `online`='0' WHERE `account_id`='%d'", char_db, account_id))
- Sql_ShowDebug(sql_handle);
- } else {
- struct mmo_charstatus *cp = (struct mmo_charstatus *)idb_get(char_db_,char_id);
- inter_guild_CharOffline(char_id, cp?cp->guild_id:-1);
- if (cp)
- idb_remove(char_db_,char_id);
-
- if (SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `online`='0' WHERE `char_id`='%d' LIMIT 1", char_db, char_id))
- Sql_ShowDebug(sql_handle);
- }
-
- if ((character = (struct online_char_data *)idb_get(online_char_db, account_id)) != NULL) {
- //We don't free yet to avoid aCalloc/aFree spamming during char change. [Skotlex]
- if (character->server > -1)
- if (server[character->server].users > 0) // Prevent this value from going negative.
- server[character->server].users--;
-
- if (character->waiting_disconnect != INVALID_TIMER) {
- delete_timer(character->waiting_disconnect, chardb_waiting_disconnect);
- character->waiting_disconnect = INVALID_TIMER;
- }
-
- if (character->char_id == char_id) {
- character->char_id = -1;
- character->server = -1;
- }
-
- //FIXME? Why Kevin free'd the online information when the char was effectively in the map-server?
- }
-
- //Remove char if 1- Set all offline, or 2- character is no longer connected to char-server.
- if (login_fd > 0 && !session[login_fd]->flag.eof && (char_id == -1 || character == NULL || character->fd == -1)) {
- WFIFOHEAD(login_fd,6);
- WFIFOW(login_fd,0) = 0x272c;
- WFIFOL(login_fd,2) = account_id;
- WFIFOSET(login_fd,6);
- }
+ struct online_char_data* character;
+
+ if ( char_id == -1 )
+ {
+ if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `online`='0' WHERE `account_id`='%d'", char_db, account_id) )
+ Sql_ShowDebug(sql_handle);
+ }
+ else
+ {
+ struct mmo_charstatus* cp = (struct mmo_charstatus*)idb_get(char_db_,char_id);
+ inter_guild_CharOffline(char_id, cp?cp->guild_id:-1);
+ if (cp)
+ idb_remove(char_db_,char_id);
+
+ if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `online`='0' WHERE `char_id`='%d' LIMIT 1", char_db, char_id) )
+ Sql_ShowDebug(sql_handle);
+ }
+
+ if ((character = (struct online_char_data*)idb_get(online_char_db, account_id)) != NULL)
+ { //We don't free yet to avoid aCalloc/aFree spamming during char change. [Skotlex]
+ if( character->server > -1 )
+ if( server[character->server].users > 0 ) // Prevent this value from going negative.
+ server[character->server].users--;
+
+ if(character->waiting_disconnect != INVALID_TIMER){
+ delete_timer(character->waiting_disconnect, chardb_waiting_disconnect);
+ character->waiting_disconnect = INVALID_TIMER;
+ }
+
+ if(character->char_id == char_id)
+ {
+ character->char_id = -1;
+ character->server = -1;
+ }
+
+ //FIXME? Why Kevin free'd the online information when the char was effectively in the map-server?
+ }
+
+ //Remove char if 1- Set all offline, or 2- character is no longer connected to char-server.
+ if (login_fd > 0 && !session[login_fd]->flag.eof && (char_id == -1 || character == NULL || character->fd == -1))
+ {
+ WFIFOHEAD(login_fd,6);
+ WFIFOW(login_fd,0) = 0x272c;
+ WFIFOL(login_fd,2) = account_id;
+ WFIFOSET(login_fd,6);
+ }
}
/**
@@ -331,18 +339,18 @@ void set_char_offline(int char_id, int account_id)
*/
static int char_db_setoffline(DBKey key, DBData *data, va_list ap)
{
- struct online_char_data *character = (struct online_char_data *)db_data2ptr(data);
- int server = va_arg(ap, int);
- if (server == -1) {
- character->char_id = -1;
- character->server = -1;
- if (character->waiting_disconnect != INVALID_TIMER) {
- delete_timer(character->waiting_disconnect, chardb_waiting_disconnect);
- character->waiting_disconnect = INVALID_TIMER;
- }
- } else if (character->server == server)
- character->server = -2; //In some map server that we aren't connected to.
- return 0;
+ struct online_char_data* character = (struct online_char_data*)db_data2ptr(data);
+ int server = va_arg(ap, int);
+ if (server == -1) {
+ character->char_id = -1;
+ character->server = -1;
+ if(character->waiting_disconnect != INVALID_TIMER){
+ delete_timer(character->waiting_disconnect, chardb_waiting_disconnect);
+ character->waiting_disconnect = INVALID_TIMER;
+ }
+ } else if (character->server == server)
+ character->server = -2; //In some map server that we aren't connected to.
+ return 0;
}
/**
@@ -350,48 +358,48 @@ static int char_db_setoffline(DBKey key, DBData *data, va_list ap)
*/
static int char_db_kickoffline(DBKey key, DBData *data, va_list ap)
{
- struct online_char_data *character = (struct online_char_data *)db_data2ptr(data);
- int server_id = va_arg(ap, int);
+ struct online_char_data* character = (struct online_char_data*)db_data2ptr(data);
+ int server_id = va_arg(ap, int);
- if (server_id > -1 && character->server != server_id)
- return 0;
+ if (server_id > -1 && character->server != server_id)
+ return 0;
- //Kick out any connected characters, and set them offline as appropriate.
- if (character->server > -1)
- mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 1);
- else if (character->waiting_disconnect == INVALID_TIMER)
- set_char_offline(character->char_id, character->account_id);
- else
- return 0; // fail
+ //Kick out any connected characters, and set them offline as appropriate.
+ if (character->server > -1)
+ mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 1);
+ else if (character->waiting_disconnect == INVALID_TIMER)
+ set_char_offline(character->char_id, character->account_id);
+ else
+ return 0; // fail
- return 1;
+ return 1;
}
void set_all_offline(int id)
{
- if (id < 0)
- ShowNotice("Sending all users offline.\n");
- else
- ShowNotice("Sending users of map-server %d offline.\n",id);
- online_char_db->foreach(online_char_db,char_db_kickoffline,id);
-
- if (id >= 0 || login_fd <= 0 || session[login_fd]->flag.eof)
- return;
- //Tell login-server to also mark all our characters as offline.
- WFIFOHEAD(login_fd,2);
- WFIFOW(login_fd,0) = 0x2737;
- WFIFOSET(login_fd,2);
+ if (id < 0)
+ ShowNotice("Sending all users offline.\n");
+ else
+ ShowNotice("Sending users of map-server %d offline.\n",id);
+ online_char_db->foreach(online_char_db,char_db_kickoffline,id);
+
+ if (id >= 0 || login_fd <= 0 || session[login_fd]->flag.eof)
+ return;
+ //Tell login-server to also mark all our characters as offline.
+ WFIFOHEAD(login_fd,2);
+ WFIFOW(login_fd,0) = 0x2737;
+ WFIFOSET(login_fd,2);
}
void set_all_offline_sql(void)
{
- //Set all players to 'OFFLINE'
- if (SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `online` = '0'", char_db))
- Sql_ShowDebug(sql_handle);
- if (SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `online` = '0'", guild_member_db))
- Sql_ShowDebug(sql_handle);
- if (SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `connect_member` = '0'", guild_db))
- Sql_ShowDebug(sql_handle);
+ //Set all players to 'OFFLINE'
+ if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `online` = '0'", char_db) )
+ Sql_ShowDebug(sql_handle);
+ if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `online` = '0'", guild_member_db) )
+ Sql_ShowDebug(sql_handle);
+ if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `connect_member` = '0'", guild_db) )
+ Sql_ShowDebug(sql_handle);
}
/**
@@ -399,920 +407,949 @@ void set_all_offline_sql(void)
*/
static DBData create_charstatus(DBKey key, va_list args)
{
- struct mmo_charstatus *cp;
- cp = (struct mmo_charstatus *) aCalloc(1,sizeof(struct mmo_charstatus));
- cp->char_id = key.i;
- return db_ptr2data(cp);
+ struct mmo_charstatus *cp;
+ cp = (struct mmo_charstatus *) aCalloc(1,sizeof(struct mmo_charstatus));
+ cp->char_id = key.i;
+ return db_ptr2data(cp);
}
int inventory_to_sql(const struct item items[], int max, int id);
-int mmo_char_tosql(int char_id, struct mmo_charstatus *p)
+int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
{
- int i = 0;
- int count = 0;
- int diff = 0;
- char save_status[128]; //For displaying save information. [Skotlex]
- struct mmo_charstatus *cp;
- int errors = 0; //If there are any errors while saving, "cp" will not be updated at the end.
- StringBuf buf;
-
- if (char_id!=p->char_id) return 0;
-
- cp = idb_ensure(char_db_, char_id, create_charstatus);
-
- StringBuf_Init(&buf);
- memset(save_status, 0, sizeof(save_status));
-
- //map inventory data
- if (memcmp(p->inventory, cp->inventory, sizeof(p->inventory))) {
- if (!inventory_to_sql(p->inventory, MAX_INVENTORY, p->char_id))
- strcat(save_status, " inventory");
- else
- errors++;
- }
-
- //map cart data
- if (memcmp(p->cart, cp->cart, sizeof(p->cart))) {
- if (!memitemdata_to_sql(p->cart, MAX_CART, p->char_id, TABLE_CART))
- strcat(save_status, " cart");
- else
- errors++;
- }
-
- //map storage data
- if (memcmp(p->storage.items, cp->storage.items, sizeof(p->storage.items))) {
- if (!memitemdata_to_sql(p->storage.items, MAX_STORAGE, p->account_id, TABLE_STORAGE))
- strcat(save_status, " storage");
- else
- errors++;
- }
-
- if (
- (p->base_exp != cp->base_exp) || (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.map != cp->last_point.map) ||
- (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->party_id != cp->party_id) || (p->guild_id != cp->guild_id) ||
- (p->pet_id != cp->pet_id) || (p->weapon != cp->weapon) || (p->hom_id != cp->hom_id) ||
- (p->ele_id != cp->ele_id) || (p->shield != cp->shield) || (p->head_top != cp->head_top) ||
- (p->head_mid != cp->head_mid) || (p->head_bottom != cp->head_bottom) || (p->delete_date != cp->delete_date) ||
- (p->rename != cp->rename) || (p->robe != cp->robe)
- ) {
- //Save status
- if (SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `base_level`='%d', `job_level`='%d',"
- "`base_exp`='%u', `job_exp`='%u', `zeny`='%d',"
- "`max_hp`='%d',`hp`='%d',`max_sp`='%d',`sp`='%d',`status_point`='%d',`skill_point`='%d',"
- "`str`='%d',`agi`='%d',`vit`='%d',`int`='%d',`dex`='%d',`luk`='%d',"
- "`option`='%d',`party_id`='%d',`guild_id`='%d',`pet_id`='%d',`homun_id`='%d',`elemental_id`='%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', `rename`='%d',"
- "`delete_date`='%lu',`robe`='%d'"
- " WHERE `account_id`='%d' AND `char_id` = '%d'",
- char_db, 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,
- p->option, p->party_id, p->guild_id, p->pet_id, p->hom_id, p->ele_id,
- p->weapon, p->shield, p->head_top, p->head_mid, p->head_bottom,
- mapindex_id2name(p->last_point.map), p->last_point.x, p->last_point.y,
- mapindex_id2name(p->save_point.map), p->save_point.x, p->save_point.y, p->rename,
- (unsigned long)p->delete_date, // FIXME: platform-dependent size
- p->robe,
- p->account_id, p->char_id)) {
- Sql_ShowDebug(sql_handle);
- errors++;
- } else
- strcat(save_status, " status");
- }
-
- //Values that will seldom change (to speed up saving)
- if (
- (p->hair != cp->hair) || (p->hair_color != cp->hair_color) || (p->clothes_color != cp->clothes_color) ||
- (p->class_ != cp->class_) ||
- (p->partner_id != cp->partner_id) || (p->father != cp->father) ||
- (p->mother != cp->mother) || (p->child != cp->child) ||
- (p->karma != cp->karma) || (p->manner != cp->manner) ||
- (p->fame != cp->fame)
- ) {
- if (SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `class`='%d',"
- "`hair`='%d',`hair_color`='%d',`clothes_color`='%d',"
- "`partner_id`='%d', `father`='%d', `mother`='%d', `child`='%d',"
- "`karma`='%d',`manner`='%d', `fame`='%d'"
- " WHERE `account_id`='%d' AND `char_id` = '%d'",
- char_db, p->class_,
- p->hair, p->hair_color, p->clothes_color,
- p->partner_id, p->father, p->mother, p->child,
- p->karma, p->manner, p->fame,
- p->account_id, p->char_id)) {
- Sql_ShowDebug(sql_handle);
- errors++;
- } else
- strcat(save_status, " status2");
- }
-
- /* Mercenary Owner */
- if ((p->mer_id != cp->mer_id) ||
- (p->arch_calls != cp->arch_calls) || (p->arch_faith != cp->arch_faith) ||
- (p->spear_calls != cp->spear_calls) || (p->spear_faith != cp->spear_faith) ||
- (p->sword_calls != cp->sword_calls) || (p->sword_faith != cp->sword_faith)) {
- if (mercenary_owner_tosql(char_id, p))
- strcat(save_status, " mercenary");
- else
- errors++;
- }
-
- //memo points
- if (memcmp(p->memo_point, cp->memo_point, sizeof(p->memo_point))) {
- char esc_mapname[NAME_LENGTH*2+1];
-
- //`memo` (`memo_id`,`char_id`,`map`,`x`,`y`)
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", memo_db, p->char_id)) {
- Sql_ShowDebug(sql_handle);
- errors++;
- }
-
- //insert here.
- StringBuf_Clear(&buf);
- StringBuf_Printf(&buf, "INSERT INTO `%s`(`char_id`,`map`,`x`,`y`) VALUES ", memo_db);
- for (i = 0, count = 0; i < MAX_MEMOPOINTS; ++i) {
- if (p->memo_point[i].map) {
- if (count)
- StringBuf_AppendStr(&buf, ",");
- Sql_EscapeString(sql_handle, esc_mapname, mapindex_id2name(p->memo_point[i].map));
- StringBuf_Printf(&buf, "('%d', '%s', '%d', '%d')", char_id, esc_mapname, p->memo_point[i].x, p->memo_point[i].y);
- ++count;
- }
- }
- if (count) {
- if (SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf))) {
- Sql_ShowDebug(sql_handle);
- errors++;
- }
- }
- strcat(save_status, " memo");
- }
-
- //FIXME: is this neccessary? [ultramage]
- 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
-
-
- //skills
- if (memcmp(p->skill, cp->skill, sizeof(p->skill))) {
- //`skill` (`char_id`, `id`, `lv`)
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", skill_db, p->char_id)) {
- Sql_ShowDebug(sql_handle);
- errors++;
- }
-
- StringBuf_Clear(&buf);
- StringBuf_Printf(&buf, "INSERT INTO `%s`(`char_id`,`id`,`lv`) VALUES ", skill_db);
- //insert here.
- for (i = 0, count = 0; i < MAX_SKILL; ++i) {
- if (p->skill[i].id != 0 && p->skill[i].flag != SKILL_FLAG_TEMPORARY) {
- if (p->skill[i].flag == SKILL_FLAG_PERMANENT && p->skill[i].lv == 0)
- continue;
- if (p->skill[i].flag != SKILL_FLAG_PERMANENT && (p->skill[i].flag - SKILL_FLAG_REPLACED_LV_0) == 0)
- continue;
- if (count)
- StringBuf_AppendStr(&buf, ",");
- StringBuf_Printf(&buf, "('%d','%d','%d')", char_id, p->skill[i].id, (p->skill[i].flag == SKILL_FLAG_PERMANENT ? p->skill[i].lv : p->skill[i].flag - SKILL_FLAG_REPLACED_LV_0));
- ++count;
- }
- }
- if (count) {
- if (SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf))) {
- Sql_ShowDebug(sql_handle);
- errors++;
- }
- }
-
- strcat(save_status, " skills");
- }
-
- diff = 0;
- for (i = 0; i < MAX_FRIENDS; i++) {
- if (p->friends[i].char_id != cp->friends[i].char_id ||
- p->friends[i].account_id != cp->friends[i].account_id) {
- diff = 1;
- break;
- }
- }
-
- if (diff == 1) {
- //Save friends
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", friend_db, char_id)) {
- Sql_ShowDebug(sql_handle);
- errors++;
- }
-
- StringBuf_Clear(&buf);
- StringBuf_Printf(&buf, "INSERT INTO `%s` (`char_id`, `friend_account`, `friend_id`) VALUES ", friend_db);
- for (i = 0, count = 0; i < MAX_FRIENDS; ++i) {
- if (p->friends[i].char_id > 0) {
- if (count)
- StringBuf_AppendStr(&buf, ",");
- StringBuf_Printf(&buf, "('%d','%d','%d')", char_id, p->friends[i].account_id, p->friends[i].char_id);
- count++;
- }
- }
- if (count) {
- if (SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf))) {
- Sql_ShowDebug(sql_handle);
- errors++;
- }
- }
- strcat(save_status, " friends");
- }
+ int i = 0;
+ int count = 0;
+ int diff = 0;
+ char save_status[128]; //For displaying save information. [Skotlex]
+ struct mmo_charstatus *cp;
+ int errors = 0; //If there are any errors while saving, "cp" will not be updated at the end.
+ StringBuf buf;
+
+ if (char_id!=p->char_id) return 0;
+
+ cp = idb_ensure(char_db_, char_id, create_charstatus);
+
+ StringBuf_Init(&buf);
+ memset(save_status, 0, sizeof(save_status));
+
+ //map inventory data
+ if( memcmp(p->inventory, cp->inventory, sizeof(p->inventory)) ) {
+ if (!inventory_to_sql(p->inventory, MAX_INVENTORY, p->char_id))
+ strcat(save_status, " inventory");
+ else
+ errors++;
+ }
+
+ //map cart data
+ if( memcmp(p->cart, cp->cart, sizeof(p->cart)) ) {
+ if (!memitemdata_to_sql(p->cart, MAX_CART, p->char_id, TABLE_CART))
+ strcat(save_status, " cart");
+ else
+ errors++;
+ }
+
+ //map storage data
+ if( memcmp(p->storage.items, cp->storage.items, sizeof(p->storage.items)) ) {
+ if (!memitemdata_to_sql(p->storage.items, MAX_STORAGE, p->account_id, TABLE_STORAGE))
+ strcat(save_status, " storage");
+ else
+ errors++;
+ }
+
+ if (
+ (p->base_exp != cp->base_exp) || (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.map != cp->last_point.map) ||
+ (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->party_id != cp->party_id) || (p->guild_id != cp->guild_id) ||
+ (p->pet_id != cp->pet_id) || (p->weapon != cp->weapon) || (p->hom_id != cp->hom_id) ||
+ (p->ele_id != cp->ele_id) || (p->shield != cp->shield) || (p->head_top != cp->head_top) ||
+ (p->head_mid != cp->head_mid) || (p->head_bottom != cp->head_bottom) || (p->delete_date != cp->delete_date) ||
+ (p->rename != cp->rename) || (p->robe != cp->robe)
+ )
+ { //Save status
+ if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `base_level`='%d', `job_level`='%d',"
+ "`base_exp`='%u', `job_exp`='%u', `zeny`='%d',"
+ "`max_hp`='%d',`hp`='%d',`max_sp`='%d',`sp`='%d',`status_point`='%d',`skill_point`='%d',"
+ "`str`='%d',`agi`='%d',`vit`='%d',`int`='%d',`dex`='%d',`luk`='%d',"
+ "`option`='%d',`party_id`='%d',`guild_id`='%d',`pet_id`='%d',`homun_id`='%d',`elemental_id`='%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', `rename`='%d',"
+ "`delete_date`='%lu',`robe`='%d'"
+ " WHERE `account_id`='%d' AND `char_id` = '%d'",
+ char_db, 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,
+ p->option, p->party_id, p->guild_id, p->pet_id, p->hom_id, p->ele_id,
+ p->weapon, p->shield, p->head_top, p->head_mid, p->head_bottom,
+ mapindex_id2name(p->last_point.map), p->last_point.x, p->last_point.y,
+ mapindex_id2name(p->save_point.map), p->save_point.x, p->save_point.y, p->rename,
+ (unsigned long)p->delete_date, // FIXME: platform-dependent size
+ p->robe,
+ p->account_id, p->char_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ errors++;
+ } else
+ strcat(save_status, " status");
+ }
+
+ //Values that will seldom change (to speed up saving)
+ if (
+ (p->hair != cp->hair) || (p->hair_color != cp->hair_color) || (p->clothes_color != cp->clothes_color) ||
+ (p->class_ != cp->class_) ||
+ (p->partner_id != cp->partner_id) || (p->father != cp->father) ||
+ (p->mother != cp->mother) || (p->child != cp->child) ||
+ (p->karma != cp->karma) || (p->manner != cp->manner) ||
+ (p->fame != cp->fame)
+ )
+ {
+ if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `class`='%d',"
+ "`hair`='%d',`hair_color`='%d',`clothes_color`='%d',"
+ "`partner_id`='%d', `father`='%d', `mother`='%d', `child`='%d',"
+ "`karma`='%d',`manner`='%d', `fame`='%d'"
+ " WHERE `account_id`='%d' AND `char_id` = '%d'",
+ char_db, p->class_,
+ p->hair, p->hair_color, p->clothes_color,
+ p->partner_id, p->father, p->mother, p->child,
+ p->karma, p->manner, p->fame,
+ p->account_id, p->char_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ errors++;
+ } else
+ strcat(save_status, " status2");
+ }
+
+ /* Mercenary Owner */
+ if( (p->mer_id != cp->mer_id) ||
+ (p->arch_calls != cp->arch_calls) || (p->arch_faith != cp->arch_faith) ||
+ (p->spear_calls != cp->spear_calls) || (p->spear_faith != cp->spear_faith) ||
+ (p->sword_calls != cp->sword_calls) || (p->sword_faith != cp->sword_faith) )
+ {
+ if (mercenary_owner_tosql(char_id, p))
+ strcat(save_status, " mercenary");
+ else
+ errors++;
+ }
+
+ //memo points
+ if( memcmp(p->memo_point, cp->memo_point, sizeof(p->memo_point)) )
+ {
+ char esc_mapname[NAME_LENGTH*2+1];
+
+ //`memo` (`memo_id`,`char_id`,`map`,`x`,`y`)
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", memo_db, p->char_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ errors++;
+ }
+
+ //insert here.
+ StringBuf_Clear(&buf);
+ StringBuf_Printf(&buf, "INSERT INTO `%s`(`char_id`,`map`,`x`,`y`) VALUES ", memo_db);
+ for( i = 0, count = 0; i < MAX_MEMOPOINTS; ++i )
+ {
+ if( p->memo_point[i].map )
+ {
+ if( count )
+ StringBuf_AppendStr(&buf, ",");
+ Sql_EscapeString(sql_handle, esc_mapname, mapindex_id2name(p->memo_point[i].map));
+ StringBuf_Printf(&buf, "('%d', '%s', '%d', '%d')", char_id, esc_mapname, p->memo_point[i].x, p->memo_point[i].y);
+ ++count;
+ }
+ }
+ if( count )
+ {
+ if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) )
+ {
+ Sql_ShowDebug(sql_handle);
+ errors++;
+ }
+ }
+ strcat(save_status, " memo");
+ }
+
+ //FIXME: is this neccessary? [ultramage]
+ 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
+
+
+ //skills
+ if( memcmp(p->skill, cp->skill, sizeof(p->skill)) )
+ {
+ //`skill` (`char_id`, `id`, `lv`)
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", skill_db, p->char_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ errors++;
+ }
+
+ StringBuf_Clear(&buf);
+ StringBuf_Printf(&buf, "INSERT INTO `%s`(`char_id`,`id`,`lv`) VALUES ", skill_db);
+ //insert here.
+ for( i = 0, count = 0; i < MAX_SKILL; ++i )
+ {
+ if( p->skill[i].id != 0 && p->skill[i].flag != SKILL_FLAG_TEMPORARY )
+ {
+ if( p->skill[i].flag == SKILL_FLAG_PERMANENT && p->skill[i].lv == 0 )
+ continue;
+ if( p->skill[i].flag != SKILL_FLAG_PERMANENT && (p->skill[i].flag - SKILL_FLAG_REPLACED_LV_0) == 0 )
+ continue;
+ if( count )
+ StringBuf_AppendStr(&buf, ",");
+ StringBuf_Printf(&buf, "('%d','%d','%d')", char_id, p->skill[i].id, (p->skill[i].flag == SKILL_FLAG_PERMANENT ? p->skill[i].lv : p->skill[i].flag - SKILL_FLAG_REPLACED_LV_0));
+ ++count;
+ }
+ }
+ if( count )
+ {
+ if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) )
+ {
+ Sql_ShowDebug(sql_handle);
+ errors++;
+ }
+ }
+
+ strcat(save_status, " skills");
+ }
+
+ diff = 0;
+ for(i = 0; i < MAX_FRIENDS; i++){
+ if(p->friends[i].char_id != cp->friends[i].char_id ||
+ p->friends[i].account_id != cp->friends[i].account_id){
+ diff = 1;
+ break;
+ }
+ }
+
+ if(diff == 1)
+ { //Save friends
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", friend_db, char_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ errors++;
+ }
+
+ StringBuf_Clear(&buf);
+ StringBuf_Printf(&buf, "INSERT INTO `%s` (`char_id`, `friend_account`, `friend_id`) VALUES ", friend_db);
+ for( i = 0, count = 0; i < MAX_FRIENDS; ++i )
+ {
+ if( p->friends[i].char_id > 0 )
+ {
+ if( count )
+ StringBuf_AppendStr(&buf, ",");
+ StringBuf_Printf(&buf, "('%d','%d','%d')", char_id, p->friends[i].account_id, p->friends[i].char_id);
+ count++;
+ }
+ }
+ if( count )
+ {
+ if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) )
+ {
+ Sql_ShowDebug(sql_handle);
+ errors++;
+ }
+ }
+ strcat(save_status, " friends");
+ }
#ifdef HOTKEY_SAVING
- // hotkeys
- StringBuf_Clear(&buf);
- StringBuf_Printf(&buf, "REPLACE INTO `%s` (`char_id`, `hotkey`, `type`, `itemskill_id`, `skill_lvl`) VALUES ", hotkey_db);
- diff = 0;
- for (i = 0; i < ARRAYLENGTH(p->hotkeys); i++) {
- if (memcmp(&p->hotkeys[i], &cp->hotkeys[i], sizeof(struct hotkey))) {
- if (diff)
- StringBuf_AppendStr(&buf, ",");// not the first hotkey
- StringBuf_Printf(&buf, "('%d','%u','%u','%u','%u')", char_id, (unsigned int)i, (unsigned int)p->hotkeys[i].type, p->hotkeys[i].id , (unsigned int)p->hotkeys[i].lv);
- diff = 1;
- }
- }
- if (diff) {
- if (SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf))) {
- Sql_ShowDebug(sql_handle);
- errors++;
- } else
- strcat(save_status, " hotkeys");
- }
+ // hotkeys
+ StringBuf_Clear(&buf);
+ StringBuf_Printf(&buf, "REPLACE INTO `%s` (`char_id`, `hotkey`, `type`, `itemskill_id`, `skill_lvl`) VALUES ", hotkey_db);
+ diff = 0;
+ for(i = 0; i < ARRAYLENGTH(p->hotkeys); i++){
+ if(memcmp(&p->hotkeys[i], &cp->hotkeys[i], sizeof(struct hotkey)))
+ {
+ if( diff )
+ StringBuf_AppendStr(&buf, ",");// not the first hotkey
+ StringBuf_Printf(&buf, "('%d','%u','%u','%u','%u')", char_id, (unsigned int)i, (unsigned int)p->hotkeys[i].type, p->hotkeys[i].id , (unsigned int)p->hotkeys[i].lv);
+ diff = 1;
+ }
+ }
+ if(diff) {
+ if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) )
+ {
+ Sql_ShowDebug(sql_handle);
+ errors++;
+ } else
+ strcat(save_status, " hotkeys");
+ }
#endif
- StringBuf_Destroy(&buf);
- if (save_status[0]!='\0' && save_log)
- ShowInfo("Saved char %d - %s:%s.\n", char_id, p->name, save_status);
- if (!errors)
- memcpy(cp, p, sizeof(struct mmo_charstatus));
- return 0;
+ StringBuf_Destroy(&buf);
+ if (save_status[0]!='\0' && save_log)
+ ShowInfo("Saved char %d - %s:%s.\n", char_id, p->name, save_status);
+ if (!errors)
+ memcpy(cp, p, sizeof(struct mmo_charstatus));
+ return 0;
}
/// Saves an array of 'item' entries into the specified table.
int memitemdata_to_sql(const struct item items[], int max, int id, int tableswitch)
{
- StringBuf buf;
- SqlStmt *stmt;
- int i;
- int j;
- const char *tablename;
- const char *selectoption;
- struct item item; // temp storage variable
- bool *flag; // bit array for inventory matching
- bool found;
- int errors = 0;
-
- switch (tableswitch) {
- case TABLE_INVENTORY:
- tablename = inventory_db;
- selectoption = "char_id";
- break;
- case TABLE_CART:
- tablename = cart_db;
- selectoption = "char_id";
- break;
- case TABLE_STORAGE:
- tablename = storage_db;
- selectoption = "account_id";
- break;
- case TABLE_GUILD_STORAGE:
- tablename = guild_storage_db;
- selectoption = "guild_id";
- break;
- default:
- ShowError("Invalid table name!\n");
- return 1;
- }
-
-
- // The following code compares inventory with current database values
- // and performs modification/deletion/insertion only on relevant rows.
- // This approach is more complicated than a trivial delete&insert, but
- // it significantly reduces cpu load on the database server.
-
- StringBuf_Init(&buf);
- StringBuf_AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`");
- for (j = 0; j < MAX_SLOTS; ++j)
- StringBuf_Printf(&buf, ", `card%d`", j);
- StringBuf_Printf(&buf, " FROM `%s` WHERE `%s`='%d'", tablename, selectoption, id);
-
- stmt = SqlStmt_Malloc(sql_handle);
- if (SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf))
- || SQL_ERROR == SqlStmt_Execute(stmt)) {
- SqlStmt_ShowDebug(stmt);
- SqlStmt_Free(stmt);
- StringBuf_Destroy(&buf);
- return 1;
- }
-
- SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &item.id, 0, NULL, NULL);
- SqlStmt_BindColumn(stmt, 1, SQLDT_SHORT, &item.nameid, 0, NULL, NULL);
- SqlStmt_BindColumn(stmt, 2, SQLDT_SHORT, &item.amount, 0, NULL, NULL);
- SqlStmt_BindColumn(stmt, 3, SQLDT_USHORT, &item.equip, 0, NULL, NULL);
- SqlStmt_BindColumn(stmt, 4, SQLDT_CHAR, &item.identify, 0, NULL, NULL);
- SqlStmt_BindColumn(stmt, 5, SQLDT_CHAR, &item.refine, 0, NULL, NULL);
- SqlStmt_BindColumn(stmt, 6, SQLDT_CHAR, &item.attribute, 0, NULL, NULL);
- SqlStmt_BindColumn(stmt, 7, SQLDT_UINT, &item.expire_time, 0, NULL, NULL);
- for (j = 0; j < MAX_SLOTS; ++j)
- SqlStmt_BindColumn(stmt, 8+j, SQLDT_SHORT, &item.card[j], 0, NULL, NULL);
-
- // bit array indicating which inventory items have already been matched
- flag = (bool *) aCalloc(max, sizeof(bool));
-
- while (SQL_SUCCESS == SqlStmt_NextRow(stmt)) {
- found = false;
- // search for the presence of the item in the char's inventory
- for (i = 0; i < max; ++i) {
- // skip empty and already matched entries
- if (items[i].nameid == 0 || flag[i])
- continue;
-
- if (items[i].nameid == item.nameid
- && items[i].card[0] == item.card[0]
- && items[i].card[2] == item.card[2]
- && items[i].card[3] == item.card[3]
- ) { //They are the same item.
- ARR_FIND(0, MAX_SLOTS, j, items[i].card[j] != item.card[j]);
- if (j == MAX_SLOTS &&
- items[i].amount == item.amount &&
- items[i].equip == item.equip &&
- items[i].identify == item.identify &&
- items[i].refine == item.refine &&
- items[i].attribute == item.attribute &&
- items[i].expire_time == item.expire_time)
- ; //Do nothing.
- else {
- // update all fields.
- StringBuf_Clear(&buf);
- StringBuf_Printf(&buf, "UPDATE `%s` SET `amount`='%d', `equip`='%d', `identify`='%d', `refine`='%d',`attribute`='%d', `expire_time`='%u'",
- tablename, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time);
- for (j = 0; j < MAX_SLOTS; ++j)
- StringBuf_Printf(&buf, ", `card%d`=%d", j, items[i].card[j]);
- StringBuf_Printf(&buf, " WHERE `id`='%d' LIMIT 1", item.id);
-
- if (SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf))) {
- Sql_ShowDebug(sql_handle);
- errors++;
- }
- }
-
- found = flag[i] = true; //Item dealt with,
- break; //skip to next item in the db.
- }
- }
- if (!found) {
- // Item not present in inventory, remove it.
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE from `%s` where `id`='%d' LIMIT 1", tablename, item.id)) {
- Sql_ShowDebug(sql_handle);
- errors++;
- }
- }
- }
- SqlStmt_Free(stmt);
-
- StringBuf_Clear(&buf);
- StringBuf_Printf(&buf, "INSERT INTO `%s`(`%s`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`", tablename, selectoption);
- for (j = 0; j < MAX_SLOTS; ++j)
- StringBuf_Printf(&buf, ", `card%d`", j);
- StringBuf_AppendStr(&buf, ") VALUES ");
-
- found = false;
- // insert non-matched items into the db as new items
- for (i = 0; i < max; ++i) {
- // skip empty and already matched entries
- if (items[i].nameid == 0 || flag[i])
- continue;
-
- if (found)
- StringBuf_AppendStr(&buf, ",");
- else
- found = true;
-
- StringBuf_Printf(&buf, "('%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u'",
- id, items[i].nameid, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time);
- for (j = 0; j < MAX_SLOTS; ++j)
- StringBuf_Printf(&buf, ", '%d'", items[i].card[j]);
- StringBuf_AppendStr(&buf, ")");
- }
-
- if (found && SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf))) {
- Sql_ShowDebug(sql_handle);
- errors++;
- }
-
- StringBuf_Destroy(&buf);
- aFree(flag);
-
- return errors;
+ StringBuf buf;
+ SqlStmt* stmt;
+ int i;
+ int j;
+ const char* tablename;
+ const char* selectoption;
+ struct item item; // temp storage variable
+ bool* flag; // bit array for inventory matching
+ bool found;
+ int errors = 0;
+
+ switch (tableswitch) {
+ case TABLE_INVENTORY: tablename = inventory_db; selectoption = "char_id"; break;
+ case TABLE_CART: tablename = cart_db; selectoption = "char_id"; break;
+ case TABLE_STORAGE: tablename = storage_db; selectoption = "account_id"; break;
+ case TABLE_GUILD_STORAGE: tablename = guild_storage_db; selectoption = "guild_id"; break;
+ default:
+ ShowError("Invalid table name!\n");
+ return 1;
+ }
+
+
+ // The following code compares inventory with current database values
+ // and performs modification/deletion/insertion only on relevant rows.
+ // This approach is more complicated than a trivial delete&insert, but
+ // it significantly reduces cpu load on the database server.
+
+ StringBuf_Init(&buf);
+ StringBuf_AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`");
+ for( j = 0; j < MAX_SLOTS; ++j )
+ StringBuf_Printf(&buf, ", `card%d`", j);
+ StringBuf_Printf(&buf, " FROM `%s` WHERE `%s`='%d'", tablename, selectoption, id);
+
+ stmt = SqlStmt_Malloc(sql_handle);
+ if( SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf))
+ || SQL_ERROR == SqlStmt_Execute(stmt) )
+ {
+ SqlStmt_ShowDebug(stmt);
+ SqlStmt_Free(stmt);
+ StringBuf_Destroy(&buf);
+ return 1;
+ }
+
+ SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &item.id, 0, NULL, NULL);
+ SqlStmt_BindColumn(stmt, 1, SQLDT_SHORT, &item.nameid, 0, NULL, NULL);
+ SqlStmt_BindColumn(stmt, 2, SQLDT_SHORT, &item.amount, 0, NULL, NULL);
+ SqlStmt_BindColumn(stmt, 3, SQLDT_USHORT, &item.equip, 0, NULL, NULL);
+ SqlStmt_BindColumn(stmt, 4, SQLDT_CHAR, &item.identify, 0, NULL, NULL);
+ SqlStmt_BindColumn(stmt, 5, SQLDT_CHAR, &item.refine, 0, NULL, NULL);
+ SqlStmt_BindColumn(stmt, 6, SQLDT_CHAR, &item.attribute, 0, NULL, NULL);
+ SqlStmt_BindColumn(stmt, 7, SQLDT_UINT, &item.expire_time, 0, NULL, NULL);
+ for( j = 0; j < MAX_SLOTS; ++j )
+ SqlStmt_BindColumn(stmt, 8+j, SQLDT_SHORT, &item.card[j], 0, NULL, NULL);
+
+ // bit array indicating which inventory items have already been matched
+ flag = (bool*) aCalloc(max, sizeof(bool));
+
+ while( SQL_SUCCESS == SqlStmt_NextRow(stmt) )
+ {
+ found = false;
+ // search for the presence of the item in the char's inventory
+ for( i = 0; i < max; ++i )
+ {
+ // skip empty and already matched entries
+ if( items[i].nameid == 0 || flag[i] )
+ continue;
+
+ if( items[i].nameid == item.nameid
+ && items[i].card[0] == item.card[0]
+ && items[i].card[2] == item.card[2]
+ && items[i].card[3] == item.card[3]
+ ) { //They are the same item.
+ ARR_FIND( 0, MAX_SLOTS, j, items[i].card[j] != item.card[j] );
+ if( j == MAX_SLOTS &&
+ items[i].amount == item.amount &&
+ items[i].equip == item.equip &&
+ items[i].identify == item.identify &&
+ items[i].refine == item.refine &&
+ items[i].attribute == item.attribute &&
+ items[i].expire_time == item.expire_time )
+ ; //Do nothing.
+ else
+ {
+ // update all fields.
+ StringBuf_Clear(&buf);
+ StringBuf_Printf(&buf, "UPDATE `%s` SET `amount`='%d', `equip`='%d', `identify`='%d', `refine`='%d',`attribute`='%d', `expire_time`='%u'",
+ tablename, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time);
+ for( j = 0; j < MAX_SLOTS; ++j )
+ StringBuf_Printf(&buf, ", `card%d`=%d", j, items[i].card[j]);
+ StringBuf_Printf(&buf, " WHERE `id`='%d' LIMIT 1", item.id);
+
+ if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) )
+ {
+ Sql_ShowDebug(sql_handle);
+ errors++;
+ }
+ }
+
+ found = flag[i] = true; //Item dealt with,
+ break; //skip to next item in the db.
+ }
+ }
+ if( !found )
+ {// Item not present in inventory, remove it.
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE from `%s` where `id`='%d' LIMIT 1", tablename, item.id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ errors++;
+ }
+ }
+ }
+ SqlStmt_Free(stmt);
+
+ StringBuf_Clear(&buf);
+ StringBuf_Printf(&buf, "INSERT INTO `%s`(`%s`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`", tablename, selectoption);
+ for( j = 0; j < MAX_SLOTS; ++j )
+ StringBuf_Printf(&buf, ", `card%d`", j);
+ StringBuf_AppendStr(&buf, ") VALUES ");
+
+ found = false;
+ // insert non-matched items into the db as new items
+ for( i = 0; i < max; ++i )
+ {
+ // skip empty and already matched entries
+ if( items[i].nameid == 0 || flag[i] )
+ continue;
+
+ if( found )
+ StringBuf_AppendStr(&buf, ",");
+ else
+ found = true;
+
+ StringBuf_Printf(&buf, "('%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u'",
+ id, items[i].nameid, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time);
+ for( j = 0; j < MAX_SLOTS; ++j )
+ StringBuf_Printf(&buf, ", '%d'", items[i].card[j]);
+ StringBuf_AppendStr(&buf, ")");
+ }
+
+ if( found && SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) )
+ {
+ Sql_ShowDebug(sql_handle);
+ errors++;
+ }
+
+ StringBuf_Destroy(&buf);
+ aFree(flag);
+
+ return errors;
}
/* pretty much a copy of memitemdata_to_sql except it handles inventory_db exclusively,
* - this is required because inventory db is the only one with the 'favorite' column. */
-int inventory_to_sql(const struct item items[], int max, int id)
-{
- StringBuf buf;
- SqlStmt *stmt;
- int i;
- int j;
- struct item item; // temp storage variable
- bool *flag; // bit array for inventory matching
- bool found;
- int errors = 0;
-
-
- // The following code compares inventory with current database values
- // and performs modification/deletion/insertion only on relevant rows.
- // This approach is more complicated than a trivial delete&insert, but
- // it significantly reduces cpu load on the database server.
-
- StringBuf_Init(&buf);
- StringBuf_AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`");
- for (j = 0; j < MAX_SLOTS; ++j)
- StringBuf_Printf(&buf, ", `card%d`", j);
- StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`='%d'", inventory_db, id);
-
- stmt = SqlStmt_Malloc(sql_handle);
- if (SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf))
- || SQL_ERROR == SqlStmt_Execute(stmt)) {
- SqlStmt_ShowDebug(stmt);
- SqlStmt_Free(stmt);
- StringBuf_Destroy(&buf);
- return 1;
- }
-
- SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &item.id, 0, NULL, NULL);
- SqlStmt_BindColumn(stmt, 1, SQLDT_SHORT, &item.nameid, 0, NULL, NULL);
- SqlStmt_BindColumn(stmt, 2, SQLDT_SHORT, &item.amount, 0, NULL, NULL);
- SqlStmt_BindColumn(stmt, 3, SQLDT_USHORT, &item.equip, 0, NULL, NULL);
- SqlStmt_BindColumn(stmt, 4, SQLDT_CHAR, &item.identify, 0, NULL, NULL);
- SqlStmt_BindColumn(stmt, 5, SQLDT_CHAR, &item.refine, 0, NULL, NULL);
- SqlStmt_BindColumn(stmt, 6, SQLDT_CHAR, &item.attribute, 0, NULL, NULL);
- SqlStmt_BindColumn(stmt, 7, SQLDT_UINT, &item.expire_time, 0, NULL, NULL);
- SqlStmt_BindColumn(stmt, 8, SQLDT_CHAR, &item.favorite, 0, NULL, NULL);
- for (j = 0; j < MAX_SLOTS; ++j)
- SqlStmt_BindColumn(stmt, 9+j, SQLDT_SHORT, &item.card[j], 0, NULL, NULL);
-
- // bit array indicating which inventory items have already been matched
- flag = (bool *) aCalloc(max, sizeof(bool));
-
- while (SQL_SUCCESS == SqlStmt_NextRow(stmt)) {
- found = false;
- // search for the presence of the item in the char's inventory
- for (i = 0; i < max; ++i) {
- // skip empty and already matched entries
- if (items[i].nameid == 0 || flag[i])
- continue;
-
- if (items[i].nameid == item.nameid
- && items[i].card[0] == item.card[0]
- && items[i].card[2] == item.card[2]
- && items[i].card[3] == item.card[3]
- ) { //They are the same item.
- ARR_FIND(0, MAX_SLOTS, j, items[i].card[j] != item.card[j]);
- if (j == MAX_SLOTS &&
- items[i].amount == item.amount &&
- items[i].equip == item.equip &&
- items[i].identify == item.identify &&
- items[i].refine == item.refine &&
- items[i].attribute == item.attribute &&
- items[i].expire_time == item.expire_time &&
- items[i].favorite == item.favorite)
- ; //Do nothing.
- else {
- // update all fields.
- StringBuf_Clear(&buf);
- StringBuf_Printf(&buf, "UPDATE `%s` SET `amount`='%d', `equip`='%d', `identify`='%d', `refine`='%d',`attribute`='%d', `expire_time`='%u', `favorite`='%d'",
- inventory_db, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].favorite);
- for (j = 0; j < MAX_SLOTS; ++j)
- StringBuf_Printf(&buf, ", `card%d`=%d", j, items[i].card[j]);
- StringBuf_Printf(&buf, " WHERE `id`='%d' LIMIT 1", item.id);
-
- if (SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf))) {
- Sql_ShowDebug(sql_handle);
- errors++;
- }
- }
-
- found = flag[i] = true; //Item dealt with,
- break; //skip to next item in the db.
- }
- }
- if (!found) { // Item not present in inventory, remove it.
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE from `%s` where `id`='%d' LIMIT 1", inventory_db, item.id)) {
- Sql_ShowDebug(sql_handle);
- errors++;
- }
- }
- }
- SqlStmt_Free(stmt);
-
- StringBuf_Clear(&buf);
- StringBuf_Printf(&buf, "INSERT INTO `%s` (`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`", inventory_db);
- for (j = 0; j < MAX_SLOTS; ++j)
- StringBuf_Printf(&buf, ", `card%d`", j);
- StringBuf_AppendStr(&buf, ") VALUES ");
-
- found = false;
- // insert non-matched items into the db as new items
- for (i = 0; i < max; ++i) {
- // skip empty and already matched entries
- if (items[i].nameid == 0 || flag[i])
- continue;
-
- if (found)
- StringBuf_AppendStr(&buf, ",");
- else
- found = true;
-
- StringBuf_Printf(&buf, "('%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u', '%d'",
- id, items[i].nameid, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].favorite);
- for (j = 0; j < MAX_SLOTS; ++j)
- StringBuf_Printf(&buf, ", '%d'", items[i].card[j]);
- StringBuf_AppendStr(&buf, ")");
- }
-
- if (found && SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf))) {
- Sql_ShowDebug(sql_handle);
- errors++;
- }
-
- StringBuf_Destroy(&buf);
- aFree(flag);
-
- return errors;
+int inventory_to_sql(const struct item items[], int max, int id) {
+ StringBuf buf;
+ SqlStmt* stmt;
+ int i;
+ int j;
+ struct item item; // temp storage variable
+ bool* flag; // bit array for inventory matching
+ bool found;
+ int errors = 0;
+
+
+ // The following code compares inventory with current database values
+ // and performs modification/deletion/insertion only on relevant rows.
+ // This approach is more complicated than a trivial delete&insert, but
+ // it significantly reduces cpu load on the database server.
+
+ StringBuf_Init(&buf);
+ StringBuf_AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`");
+ for( j = 0; j < MAX_SLOTS; ++j )
+ StringBuf_Printf(&buf, ", `card%d`", j);
+ StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`='%d'", inventory_db, id);
+
+ stmt = SqlStmt_Malloc(sql_handle);
+ if( SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf))
+ || SQL_ERROR == SqlStmt_Execute(stmt) )
+ {
+ SqlStmt_ShowDebug(stmt);
+ SqlStmt_Free(stmt);
+ StringBuf_Destroy(&buf);
+ return 1;
+ }
+
+ SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &item.id, 0, NULL, NULL);
+ SqlStmt_BindColumn(stmt, 1, SQLDT_SHORT, &item.nameid, 0, NULL, NULL);
+ SqlStmt_BindColumn(stmt, 2, SQLDT_SHORT, &item.amount, 0, NULL, NULL);
+ SqlStmt_BindColumn(stmt, 3, SQLDT_USHORT, &item.equip, 0, NULL, NULL);
+ SqlStmt_BindColumn(stmt, 4, SQLDT_CHAR, &item.identify, 0, NULL, NULL);
+ SqlStmt_BindColumn(stmt, 5, SQLDT_CHAR, &item.refine, 0, NULL, NULL);
+ SqlStmt_BindColumn(stmt, 6, SQLDT_CHAR, &item.attribute, 0, NULL, NULL);
+ SqlStmt_BindColumn(stmt, 7, SQLDT_UINT, &item.expire_time, 0, NULL, NULL);
+ SqlStmt_BindColumn(stmt, 8, SQLDT_CHAR, &item.favorite, 0, NULL, NULL);
+ for( j = 0; j < MAX_SLOTS; ++j )
+ SqlStmt_BindColumn(stmt, 9+j, SQLDT_SHORT, &item.card[j], 0, NULL, NULL);
+
+ // bit array indicating which inventory items have already been matched
+ flag = (bool*) aCalloc(max, sizeof(bool));
+
+ while( SQL_SUCCESS == SqlStmt_NextRow(stmt) ) {
+ found = false;
+ // search for the presence of the item in the char's inventory
+ for( i = 0; i < max; ++i ) {
+ // skip empty and already matched entries
+ if( items[i].nameid == 0 || flag[i] )
+ continue;
+
+ if( items[i].nameid == item.nameid
+ && items[i].card[0] == item.card[0]
+ && items[i].card[2] == item.card[2]
+ && items[i].card[3] == item.card[3]
+ ) { //They are the same item.
+ ARR_FIND( 0, MAX_SLOTS, j, items[i].card[j] != item.card[j] );
+ if( j == MAX_SLOTS &&
+ items[i].amount == item.amount &&
+ items[i].equip == item.equip &&
+ items[i].identify == item.identify &&
+ items[i].refine == item.refine &&
+ items[i].attribute == item.attribute &&
+ items[i].expire_time == item.expire_time &&
+ items[i].favorite == item.favorite )
+ ; //Do nothing.
+ else {
+ // update all fields.
+ StringBuf_Clear(&buf);
+ StringBuf_Printf(&buf, "UPDATE `%s` SET `amount`='%d', `equip`='%d', `identify`='%d', `refine`='%d',`attribute`='%d', `expire_time`='%u', `favorite`='%d'",
+ inventory_db, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].favorite);
+ for( j = 0; j < MAX_SLOTS; ++j )
+ StringBuf_Printf(&buf, ", `card%d`=%d", j, items[i].card[j]);
+ StringBuf_Printf(&buf, " WHERE `id`='%d' LIMIT 1", item.id);
+
+ if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) ) {
+ Sql_ShowDebug(sql_handle);
+ errors++;
+ }
+ }
+
+ found = flag[i] = true; //Item dealt with,
+ break; //skip to next item in the db.
+ }
+ }
+ if( !found ) {// Item not present in inventory, remove it.
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE from `%s` where `id`='%d' LIMIT 1", inventory_db, item.id) ) {
+ Sql_ShowDebug(sql_handle);
+ errors++;
+ }
+ }
+ }
+ SqlStmt_Free(stmt);
+
+ StringBuf_Clear(&buf);
+ StringBuf_Printf(&buf, "INSERT INTO `%s` (`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`", inventory_db);
+ for( j = 0; j < MAX_SLOTS; ++j )
+ StringBuf_Printf(&buf, ", `card%d`", j);
+ StringBuf_AppendStr(&buf, ") VALUES ");
+
+ found = false;
+ // insert non-matched items into the db as new items
+ for( i = 0; i < max; ++i ) {
+ // skip empty and already matched entries
+ if( items[i].nameid == 0 || flag[i] )
+ continue;
+
+ if( found )
+ StringBuf_AppendStr(&buf, ",");
+ else
+ found = true;
+
+ StringBuf_Printf(&buf, "('%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u', '%d'",
+ id, items[i].nameid, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].favorite);
+ for( j = 0; j < MAX_SLOTS; ++j )
+ StringBuf_Printf(&buf, ", '%d'", items[i].card[j]);
+ StringBuf_AppendStr(&buf, ")");
+ }
+
+ if( found && SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) ) {
+ Sql_ShowDebug(sql_handle);
+ errors++;
+ }
+
+ StringBuf_Destroy(&buf);
+ aFree(flag);
+
+ return errors;
}
-int mmo_char_tobuf(uint8 *buf, struct mmo_charstatus *p);
+int mmo_char_tobuf(uint8* buf, struct mmo_charstatus* p);
//=====================================================================================================
// Loads the basic character rooster for the given account. Returns total buffer used.
-int mmo_chars_fromsql(struct char_session_data *sd, uint8 *buf)
+int mmo_chars_fromsql(struct char_session_data* sd, uint8* buf)
{
- SqlStmt *stmt;
- struct mmo_charstatus p;
- int j = 0, i;
- char last_map[MAP_NAME_LENGTH_EXT];
-
- stmt = SqlStmt_Malloc(sql_handle);
- if (stmt == NULL) {
- SqlStmt_ShowDebug(stmt);
- return 0;
- }
- memset(&p, 0, sizeof(p));
-
- // read char data
- if (SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT "
- "`char_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`,`option`,`karma`,`manner`,`hair`,`hair_color`,"
- "`clothes_color`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,`last_map`,`rename`,`delete_date`,"
- "`robe`"
- " FROM `%s` WHERE `account_id`='%d' AND `char_num` < '%d'", char_db, sd->account_id, MAX_CHARS)
- || SQL_ERROR == SqlStmt_Execute(stmt)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &p.char_id, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_UCHAR, &p.slot, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_STRING, &p.name, sizeof(p.name), NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 3, SQLDT_SHORT, &p.class_, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 4, SQLDT_UINT, &p.base_level, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 5, SQLDT_UINT, &p.job_level, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 6, SQLDT_UINT, &p.base_exp, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 7, SQLDT_UINT, &p.job_exp, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 8, SQLDT_INT, &p.zeny, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 9, SQLDT_SHORT, &p.str, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 10, SQLDT_SHORT, &p.agi, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 11, SQLDT_SHORT, &p.vit, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 12, SQLDT_SHORT, &p.int_, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 13, SQLDT_SHORT, &p.dex, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 14, SQLDT_SHORT, &p.luk, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 15, SQLDT_INT, &p.max_hp, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 16, SQLDT_INT, &p.hp, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 17, SQLDT_INT, &p.max_sp, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 18, SQLDT_INT, &p.sp, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 19, SQLDT_UINT, &p.status_point, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 20, SQLDT_UINT, &p.skill_point, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 21, SQLDT_UINT, &p.option, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 22, SQLDT_UCHAR, &p.karma, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 23, SQLDT_SHORT, &p.manner, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 24, SQLDT_SHORT, &p.hair, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 25, SQLDT_SHORT, &p.hair_color, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 26, SQLDT_SHORT, &p.clothes_color, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 27, SQLDT_SHORT, &p.weapon, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 28, SQLDT_SHORT, &p.shield, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 29, SQLDT_SHORT, &p.head_top, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 30, SQLDT_SHORT, &p.head_mid, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 31, SQLDT_SHORT, &p.head_bottom, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 32, SQLDT_STRING, &last_map, sizeof(last_map), NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 33, SQLDT_SHORT, &p.rename, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 34, SQLDT_UINT32, &p.delete_date, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 35, SQLDT_SHORT, &p.robe, 0, NULL, NULL)
- ) {
- SqlStmt_ShowDebug(stmt);
- SqlStmt_Free(stmt);
- return 0;
- }
- for (i = 0; i < MAX_CHARS && SQL_SUCCESS == SqlStmt_NextRow(stmt); i++) {
- p.last_point.map = mapindex_name2id(last_map);
- sd->found_char[i] = p.char_id;
- j += mmo_char_tobuf(WBUFP(buf, j), &p);
- }
- for (; i < MAX_CHARS; i++)
- sd->found_char[i] = -1;
-
- memset(sd->new_name,0,sizeof(sd->new_name));
-
- SqlStmt_Free(stmt);
- return j;
+ SqlStmt* stmt;
+ struct mmo_charstatus p;
+ int j = 0, i;
+ char last_map[MAP_NAME_LENGTH_EXT];
+
+ stmt = SqlStmt_Malloc(sql_handle);
+ if( stmt == NULL )
+ {
+ SqlStmt_ShowDebug(stmt);
+ return 0;
+ }
+ memset(&p, 0, sizeof(p));
+
+ // read char data
+ if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT "
+ "`char_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`,`option`,`karma`,`manner`,`hair`,`hair_color`,"
+ "`clothes_color`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,`last_map`,`rename`,`delete_date`,"
+ "`robe`"
+ " FROM `%s` WHERE `account_id`='%d' AND `char_num` < '%d'", char_db, sd->account_id, MAX_CHARS)
+ || SQL_ERROR == SqlStmt_Execute(stmt)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &p.char_id, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_UCHAR, &p.slot, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_STRING, &p.name, sizeof(p.name), NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 3, SQLDT_SHORT, &p.class_, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 4, SQLDT_UINT, &p.base_level, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 5, SQLDT_UINT, &p.job_level, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 6, SQLDT_UINT, &p.base_exp, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 7, SQLDT_UINT, &p.job_exp, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 8, SQLDT_INT, &p.zeny, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 9, SQLDT_SHORT, &p.str, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 10, SQLDT_SHORT, &p.agi, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 11, SQLDT_SHORT, &p.vit, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 12, SQLDT_SHORT, &p.int_, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 13, SQLDT_SHORT, &p.dex, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 14, SQLDT_SHORT, &p.luk, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 15, SQLDT_INT, &p.max_hp, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 16, SQLDT_INT, &p.hp, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 17, SQLDT_INT, &p.max_sp, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 18, SQLDT_INT, &p.sp, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 19, SQLDT_UINT, &p.status_point, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 20, SQLDT_UINT, &p.skill_point, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 21, SQLDT_UINT, &p.option, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 22, SQLDT_UCHAR, &p.karma, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 23, SQLDT_SHORT, &p.manner, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 24, SQLDT_SHORT, &p.hair, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 25, SQLDT_SHORT, &p.hair_color, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 26, SQLDT_SHORT, &p.clothes_color, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 27, SQLDT_SHORT, &p.weapon, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 28, SQLDT_SHORT, &p.shield, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 29, SQLDT_SHORT, &p.head_top, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 30, SQLDT_SHORT, &p.head_mid, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 31, SQLDT_SHORT, &p.head_bottom, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 32, SQLDT_STRING, &last_map, sizeof(last_map), NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 33, SQLDT_SHORT, &p.rename, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 34, SQLDT_UINT32, &p.delete_date, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 35, SQLDT_SHORT, &p.robe, 0, NULL, NULL)
+ )
+ {
+ SqlStmt_ShowDebug(stmt);
+ SqlStmt_Free(stmt);
+ return 0;
+ }
+ for( i = 0; i < MAX_CHARS && SQL_SUCCESS == SqlStmt_NextRow(stmt); i++ )
+ {
+ p.last_point.map = mapindex_name2id(last_map);
+ sd->found_char[i] = p.char_id;
+ j += mmo_char_tobuf(WBUFP(buf, j), &p);
+ }
+ for( ; i < MAX_CHARS; i++ )
+ sd->found_char[i] = -1;
+
+ memset(sd->new_name,0,sizeof(sd->new_name));
+
+ SqlStmt_Free(stmt);
+ return j;
}
//=====================================================================================================
-int mmo_char_fromsql(int char_id, struct mmo_charstatus *p, bool load_everything)
+int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything)
{
- int i,j;
- char t_msg[128] = "";
- struct mmo_charstatus *cp;
- StringBuf buf;
- SqlStmt *stmt;
- char last_map[MAP_NAME_LENGTH_EXT];
- char save_map[MAP_NAME_LENGTH_EXT];
- char point_map[MAP_NAME_LENGTH_EXT];
- struct point tmp_point;
- struct item tmp_item;
- struct s_skill tmp_skill;
- struct s_friend tmp_friend;
+ int i,j;
+ char t_msg[128] = "";
+ struct mmo_charstatus* cp;
+ StringBuf buf;
+ SqlStmt* stmt;
+ char last_map[MAP_NAME_LENGTH_EXT];
+ char save_map[MAP_NAME_LENGTH_EXT];
+ char point_map[MAP_NAME_LENGTH_EXT];
+ struct point tmp_point;
+ struct item tmp_item;
+ struct s_skill tmp_skill;
+ struct s_friend tmp_friend;
#ifdef HOTKEY_SAVING
- struct hotkey tmp_hotkey;
- int hotkey_num;
+ struct hotkey tmp_hotkey;
+ int hotkey_num;
#endif
- memset(p, 0, sizeof(struct mmo_charstatus));
-
- if (save_log) ShowInfo("Char load request (%d)\n", char_id);
-
- stmt = SqlStmt_Malloc(sql_handle);
- if (stmt == NULL) {
- SqlStmt_ShowDebug(stmt);
- return 0;
- }
-
- // read char data
- if (SQL_ERROR == SqlStmt_Prepare(stmt, "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`,`option`,`karma`,`manner`,`party_id`,`guild_id`,`pet_id`,`homun_id`,`elemental_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`,`fame`,`rename`,`delete_date`,`robe`"
- " FROM `%s` WHERE `char_id`=? LIMIT 1", char_db)
- || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
- || SQL_ERROR == SqlStmt_Execute(stmt)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &p->char_id, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_INT, &p->account_id, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_UCHAR, &p->slot, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 3, SQLDT_STRING, &p->name, sizeof(p->name), NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 4, SQLDT_SHORT, &p->class_, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 5, SQLDT_UINT, &p->base_level, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 6, SQLDT_UINT, &p->job_level, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 7, SQLDT_UINT, &p->base_exp, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 8, SQLDT_UINT, &p->job_exp, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 9, SQLDT_INT, &p->zeny, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 10, SQLDT_SHORT, &p->str, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 11, SQLDT_SHORT, &p->agi, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 12, SQLDT_SHORT, &p->vit, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 13, SQLDT_SHORT, &p->int_, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 14, SQLDT_SHORT, &p->dex, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 15, SQLDT_SHORT, &p->luk, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 16, SQLDT_INT, &p->max_hp, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 17, SQLDT_INT, &p->hp, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 18, SQLDT_INT, &p->max_sp, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 19, SQLDT_INT, &p->sp, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 20, SQLDT_UINT, &p->status_point, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 21, SQLDT_UINT, &p->skill_point, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 22, SQLDT_UINT, &p->option, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 23, SQLDT_UCHAR, &p->karma, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 24, SQLDT_SHORT, &p->manner, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 25, SQLDT_INT, &p->party_id, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 26, SQLDT_INT, &p->guild_id, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 27, SQLDT_INT, &p->pet_id, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 28, SQLDT_INT, &p->hom_id, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 29, SQLDT_INT, &p->ele_id, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 30, SQLDT_SHORT, &p->hair, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 31, SQLDT_SHORT, &p->hair_color, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 32, SQLDT_SHORT, &p->clothes_color, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 33, SQLDT_SHORT, &p->weapon, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 34, SQLDT_SHORT, &p->shield, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 35, SQLDT_SHORT, &p->head_top, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 36, SQLDT_SHORT, &p->head_mid, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 37, SQLDT_SHORT, &p->head_bottom, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 38, SQLDT_STRING, &last_map, sizeof(last_map), NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 39, SQLDT_SHORT, &p->last_point.x, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 40, SQLDT_SHORT, &p->last_point.y, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 41, SQLDT_STRING, &save_map, sizeof(save_map), NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 42, SQLDT_SHORT, &p->save_point.x, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 43, SQLDT_SHORT, &p->save_point.y, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 44, SQLDT_INT, &p->partner_id, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 45, SQLDT_INT, &p->father, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 46, SQLDT_INT, &p->mother, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 47, SQLDT_INT, &p->child, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 48, SQLDT_INT, &p->fame, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 49, SQLDT_SHORT, &p->rename, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 50, SQLDT_UINT32, &p->delete_date, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 51, SQLDT_SHORT, &p->robe, 0, NULL, NULL)
- ) {
- SqlStmt_ShowDebug(stmt);
- SqlStmt_Free(stmt);
- return 0;
- }
- if (SQL_ERROR == SqlStmt_NextRow(stmt)) {
- ShowError("Requested non-existant character id: %d!\n", char_id);
- SqlStmt_Free(stmt);
- return 0;
- }
- p->last_point.map = mapindex_name2id(last_map);
- p->save_point.map = mapindex_name2id(save_map);
-
- strcat(t_msg, " status");
-
- if (!load_everything) { // For quick selection of data when displaying the char menu
- SqlStmt_Free(stmt);
- return 1;
- }
-
- //read memo data
- //`memo` (`memo_id`,`char_id`,`map`,`x`,`y`)
- if (SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `map`,`x`,`y` FROM `%s` WHERE `char_id`=? ORDER by `memo_id` LIMIT %d", memo_db, MAX_MEMOPOINTS)
- || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
- || SQL_ERROR == SqlStmt_Execute(stmt)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_STRING, &point_map, sizeof(point_map), NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_SHORT, &tmp_point.x, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_SHORT, &tmp_point.y, 0, NULL, NULL))
- SqlStmt_ShowDebug(stmt);
-
- for (i = 0; i < MAX_MEMOPOINTS && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i) {
- tmp_point.map = mapindex_name2id(point_map);
- memcpy(&p->memo_point[i], &tmp_point, sizeof(tmp_point));
- }
- strcat(t_msg, " memo");
-
- //read inventory
- //`inventory` (`id`,`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`)
- StringBuf_Init(&buf);
- StringBuf_AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`");
- for (i = 0; i < MAX_SLOTS; ++i)
- StringBuf_Printf(&buf, ", `card%d`", i);
- StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`=? LIMIT %d", inventory_db, MAX_INVENTORY);
-
- if (SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf))
- || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
- || SQL_ERROR == SqlStmt_Execute(stmt)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &tmp_item.id, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_SHORT, &tmp_item.nameid, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_SHORT, &tmp_item.amount, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 3, SQLDT_USHORT, &tmp_item.equip, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 4, SQLDT_CHAR, &tmp_item.identify, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 5, SQLDT_CHAR, &tmp_item.refine, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 6, SQLDT_CHAR, &tmp_item.attribute, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 7, SQLDT_UINT, &tmp_item.expire_time, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 8, SQLDT_CHAR, &tmp_item.favorite, 0, NULL, NULL))
- SqlStmt_ShowDebug(stmt);
- for (i = 0; i < MAX_SLOTS; ++i)
- if (SQL_ERROR == SqlStmt_BindColumn(stmt, 9+i, SQLDT_SHORT, &tmp_item.card[i], 0, NULL, NULL))
- SqlStmt_ShowDebug(stmt);
-
- for (i = 0; i < MAX_INVENTORY && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i)
- memcpy(&p->inventory[i], &tmp_item, sizeof(tmp_item));
-
- strcat(t_msg, " inventory");
-
- //read cart
- //`cart_inventory` (`id`,`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`)
- StringBuf_Clear(&buf);
- StringBuf_AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`");
- for (j = 0; j < MAX_SLOTS; ++j)
- StringBuf_Printf(&buf, ", `card%d`", j);
- StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`=? LIMIT %d", cart_db, MAX_CART);
-
- if (SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf))
- || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
- || SQL_ERROR == SqlStmt_Execute(stmt)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &tmp_item.id, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_SHORT, &tmp_item.nameid, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_SHORT, &tmp_item.amount, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 3, SQLDT_USHORT, &tmp_item.equip, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 4, SQLDT_CHAR, &tmp_item.identify, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 5, SQLDT_CHAR, &tmp_item.refine, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 6, SQLDT_CHAR, &tmp_item.attribute, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 7, SQLDT_UINT, &tmp_item.expire_time, 0, NULL, NULL))
- SqlStmt_ShowDebug(stmt);
- for (i = 0; i < MAX_SLOTS; ++i)
- if (SQL_ERROR == SqlStmt_BindColumn(stmt, 8+i, SQLDT_SHORT, &tmp_item.card[i], 0, NULL, NULL))
- SqlStmt_ShowDebug(stmt);
-
- for (i = 0; i < MAX_CART && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i)
- memcpy(&p->cart[i], &tmp_item, sizeof(tmp_item));
- strcat(t_msg, " cart");
-
- //read storage
- storage_fromsql(p->account_id, &p->storage);
- strcat(t_msg, " storage");
-
- //read skill
- //`skill` (`char_id`, `id`, `lv`)
- if (SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `id`, `lv` FROM `%s` WHERE `char_id`=? LIMIT %d", skill_db, MAX_SKILL)
- || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
- || SQL_ERROR == SqlStmt_Execute(stmt)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_USHORT, &tmp_skill.id, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_USHORT, &tmp_skill.lv, 0, NULL, NULL))
- SqlStmt_ShowDebug(stmt);
- tmp_skill.flag = SKILL_FLAG_PERMANENT;
-
- for (i = 0; i < MAX_SKILL && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i) {
- if (tmp_skill.id < ARRAYLENGTH(p->skill))
- memcpy(&p->skill[tmp_skill.id], &tmp_skill, sizeof(tmp_skill));
- else
- ShowWarning("mmo_char_fromsql: ignoring invalid skill (id=%u,lv=%u) of character %s (AID=%d,CID=%d)\n", tmp_skill.id, tmp_skill.lv, p->name, p->account_id, p->char_id);
- }
- strcat(t_msg, " skills");
-
- //read friends
- //`friends` (`char_id`, `friend_account`, `friend_id`)
- if (SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT c.`account_id`, c.`char_id`, c.`name` FROM `%s` c LEFT JOIN `%s` f ON f.`friend_account` = c.`account_id` AND f.`friend_id` = c.`char_id` WHERE f.`char_id`=? LIMIT %d", char_db, friend_db, MAX_FRIENDS)
- || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
- || SQL_ERROR == SqlStmt_Execute(stmt)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &tmp_friend.account_id, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_INT, &tmp_friend.char_id, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_STRING, &tmp_friend.name, sizeof(tmp_friend.name), NULL, NULL))
- SqlStmt_ShowDebug(stmt);
-
- for (i = 0; i < MAX_FRIENDS && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i)
- memcpy(&p->friends[i], &tmp_friend, sizeof(tmp_friend));
- strcat(t_msg, " friends");
+ memset(p, 0, sizeof(struct mmo_charstatus));
+
+ if (save_log) ShowInfo("Char load request (%d)\n", char_id);
+
+ stmt = SqlStmt_Malloc(sql_handle);
+ if( stmt == NULL )
+ {
+ SqlStmt_ShowDebug(stmt);
+ return 0;
+ }
+
+ // read char data
+ if( SQL_ERROR == SqlStmt_Prepare(stmt, "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`,`option`,`karma`,`manner`,`party_id`,`guild_id`,`pet_id`,`homun_id`,`elemental_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`,`fame`,`rename`,`delete_date`,`robe`"
+ " FROM `%s` WHERE `char_id`=? LIMIT 1", char_db)
+ || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
+ || SQL_ERROR == SqlStmt_Execute(stmt)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &p->char_id, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_INT, &p->account_id, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_UCHAR, &p->slot, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 3, SQLDT_STRING, &p->name, sizeof(p->name), NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 4, SQLDT_SHORT, &p->class_, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 5, SQLDT_UINT, &p->base_level, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 6, SQLDT_UINT, &p->job_level, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 7, SQLDT_UINT, &p->base_exp, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 8, SQLDT_UINT, &p->job_exp, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 9, SQLDT_INT, &p->zeny, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 10, SQLDT_SHORT, &p->str, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 11, SQLDT_SHORT, &p->agi, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 12, SQLDT_SHORT, &p->vit, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 13, SQLDT_SHORT, &p->int_, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 14, SQLDT_SHORT, &p->dex, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 15, SQLDT_SHORT, &p->luk, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 16, SQLDT_INT, &p->max_hp, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 17, SQLDT_INT, &p->hp, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 18, SQLDT_INT, &p->max_sp, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 19, SQLDT_INT, &p->sp, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 20, SQLDT_UINT, &p->status_point, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 21, SQLDT_UINT, &p->skill_point, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 22, SQLDT_UINT, &p->option, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 23, SQLDT_UCHAR, &p->karma, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 24, SQLDT_SHORT, &p->manner, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 25, SQLDT_INT, &p->party_id, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 26, SQLDT_INT, &p->guild_id, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 27, SQLDT_INT, &p->pet_id, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 28, SQLDT_INT, &p->hom_id, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 29, SQLDT_INT, &p->ele_id, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 30, SQLDT_SHORT, &p->hair, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 31, SQLDT_SHORT, &p->hair_color, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 32, SQLDT_SHORT, &p->clothes_color, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 33, SQLDT_SHORT, &p->weapon, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 34, SQLDT_SHORT, &p->shield, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 35, SQLDT_SHORT, &p->head_top, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 36, SQLDT_SHORT, &p->head_mid, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 37, SQLDT_SHORT, &p->head_bottom, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 38, SQLDT_STRING, &last_map, sizeof(last_map), NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 39, SQLDT_SHORT, &p->last_point.x, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 40, SQLDT_SHORT, &p->last_point.y, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 41, SQLDT_STRING, &save_map, sizeof(save_map), NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 42, SQLDT_SHORT, &p->save_point.x, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 43, SQLDT_SHORT, &p->save_point.y, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 44, SQLDT_INT, &p->partner_id, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 45, SQLDT_INT, &p->father, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 46, SQLDT_INT, &p->mother, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 47, SQLDT_INT, &p->child, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 48, SQLDT_INT, &p->fame, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 49, SQLDT_SHORT, &p->rename, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 50, SQLDT_UINT32, &p->delete_date, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 51, SQLDT_SHORT, &p->robe, 0, NULL, NULL)
+ )
+ {
+ SqlStmt_ShowDebug(stmt);
+ SqlStmt_Free(stmt);
+ return 0;
+ }
+ if( SQL_ERROR == SqlStmt_NextRow(stmt) )
+ {
+ ShowError("Requested non-existant character id: %d!\n", char_id);
+ SqlStmt_Free(stmt);
+ return 0;
+ }
+ p->last_point.map = mapindex_name2id(last_map);
+ p->save_point.map = mapindex_name2id(save_map);
+
+ strcat(t_msg, " status");
+
+ if (!load_everything) // For quick selection of data when displaying the char menu
+ {
+ SqlStmt_Free(stmt);
+ return 1;
+ }
+
+ //read memo data
+ //`memo` (`memo_id`,`char_id`,`map`,`x`,`y`)
+ if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `map`,`x`,`y` FROM `%s` WHERE `char_id`=? ORDER by `memo_id` LIMIT %d", memo_db, MAX_MEMOPOINTS)
+ || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
+ || SQL_ERROR == SqlStmt_Execute(stmt)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_STRING, &point_map, sizeof(point_map), NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_SHORT, &tmp_point.x, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_SHORT, &tmp_point.y, 0, NULL, NULL) )
+ SqlStmt_ShowDebug(stmt);
+
+ for( i = 0; i < MAX_MEMOPOINTS && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i )
+ {
+ tmp_point.map = mapindex_name2id(point_map);
+ memcpy(&p->memo_point[i], &tmp_point, sizeof(tmp_point));
+ }
+ strcat(t_msg, " memo");
+
+ //read inventory
+ //`inventory` (`id`,`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`)
+ StringBuf_Init(&buf);
+ StringBuf_AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`");
+ for( i = 0; i < MAX_SLOTS; ++i )
+ StringBuf_Printf(&buf, ", `card%d`", i);
+ StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`=? LIMIT %d", inventory_db, MAX_INVENTORY);
+
+ if( SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf))
+ || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
+ || SQL_ERROR == SqlStmt_Execute(stmt)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &tmp_item.id, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_SHORT, &tmp_item.nameid, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_SHORT, &tmp_item.amount, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 3, SQLDT_USHORT, &tmp_item.equip, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 4, SQLDT_CHAR, &tmp_item.identify, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 5, SQLDT_CHAR, &tmp_item.refine, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 6, SQLDT_CHAR, &tmp_item.attribute, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 7, SQLDT_UINT, &tmp_item.expire_time, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 8, SQLDT_CHAR, &tmp_item.favorite, 0, NULL, NULL) )
+ SqlStmt_ShowDebug(stmt);
+ for( i = 0; i < MAX_SLOTS; ++i )
+ if( SQL_ERROR == SqlStmt_BindColumn(stmt, 9+i, SQLDT_SHORT, &tmp_item.card[i], 0, NULL, NULL) )
+ SqlStmt_ShowDebug(stmt);
+
+ for( i = 0; i < MAX_INVENTORY && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i )
+ memcpy(&p->inventory[i], &tmp_item, sizeof(tmp_item));
+
+ strcat(t_msg, " inventory");
+
+ //read cart
+ //`cart_inventory` (`id`,`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`)
+ StringBuf_Clear(&buf);
+ StringBuf_AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`");
+ for( j = 0; j < MAX_SLOTS; ++j )
+ StringBuf_Printf(&buf, ", `card%d`", j);
+ StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`=? LIMIT %d", cart_db, MAX_CART);
+
+ if( SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf))
+ || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
+ || SQL_ERROR == SqlStmt_Execute(stmt)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &tmp_item.id, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_SHORT, &tmp_item.nameid, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_SHORT, &tmp_item.amount, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 3, SQLDT_USHORT, &tmp_item.equip, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 4, SQLDT_CHAR, &tmp_item.identify, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 5, SQLDT_CHAR, &tmp_item.refine, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 6, SQLDT_CHAR, &tmp_item.attribute, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 7, SQLDT_UINT, &tmp_item.expire_time, 0, NULL, NULL) )
+ SqlStmt_ShowDebug(stmt);
+ for( i = 0; i < MAX_SLOTS; ++i )
+ if( SQL_ERROR == SqlStmt_BindColumn(stmt, 8+i, SQLDT_SHORT, &tmp_item.card[i], 0, NULL, NULL) )
+ SqlStmt_ShowDebug(stmt);
+
+ for( i = 0; i < MAX_CART && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i )
+ memcpy(&p->cart[i], &tmp_item, sizeof(tmp_item));
+ strcat(t_msg, " cart");
+
+ //read storage
+ storage_fromsql(p->account_id, &p->storage);
+ strcat(t_msg, " storage");
+
+ //read skill
+ //`skill` (`char_id`, `id`, `lv`)
+ if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `id`, `lv` FROM `%s` WHERE `char_id`=? LIMIT %d", skill_db, MAX_SKILL)
+ || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
+ || SQL_ERROR == SqlStmt_Execute(stmt)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_USHORT, &tmp_skill.id, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_USHORT, &tmp_skill.lv, 0, NULL, NULL) )
+ SqlStmt_ShowDebug(stmt);
+ tmp_skill.flag = SKILL_FLAG_PERMANENT;
+
+ for( i = 0; i < MAX_SKILL && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i )
+ {
+ if( tmp_skill.id < ARRAYLENGTH(p->skill) )
+ memcpy(&p->skill[tmp_skill.id], &tmp_skill, sizeof(tmp_skill));
+ else
+ ShowWarning("mmo_char_fromsql: ignoring invalid skill (id=%u,lv=%u) of character %s (AID=%d,CID=%d)\n", tmp_skill.id, tmp_skill.lv, p->name, p->account_id, p->char_id);
+ }
+ strcat(t_msg, " skills");
+
+ //read friends
+ //`friends` (`char_id`, `friend_account`, `friend_id`)
+ if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT c.`account_id`, c.`char_id`, c.`name` FROM `%s` c LEFT JOIN `%s` f ON f.`friend_account` = c.`account_id` AND f.`friend_id` = c.`char_id` WHERE f.`char_id`=? LIMIT %d", char_db, friend_db, MAX_FRIENDS)
+ || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
+ || SQL_ERROR == SqlStmt_Execute(stmt)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &tmp_friend.account_id, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_INT, &tmp_friend.char_id, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_STRING, &tmp_friend.name, sizeof(tmp_friend.name), NULL, NULL) )
+ SqlStmt_ShowDebug(stmt);
+
+ for( i = 0; i < MAX_FRIENDS && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i )
+ memcpy(&p->friends[i], &tmp_friend, sizeof(tmp_friend));
+ strcat(t_msg, " friends");
#ifdef HOTKEY_SAVING
- //read hotkeys
- //`hotkey` (`char_id`, `hotkey`, `type`, `itemskill_id`, `skill_lvl`
- if (SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `hotkey`, `type`, `itemskill_id`, `skill_lvl` FROM `%s` WHERE `char_id`=?", hotkey_db)
- || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
- || SQL_ERROR == SqlStmt_Execute(stmt)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &hotkey_num, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_UCHAR, &tmp_hotkey.type, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_UINT, &tmp_hotkey.id, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 3, SQLDT_USHORT, &tmp_hotkey.lv, 0, NULL, NULL))
- SqlStmt_ShowDebug(stmt);
-
- while (SQL_SUCCESS == SqlStmt_NextRow(stmt)) {
- if (hotkey_num >= 0 && hotkey_num < MAX_HOTKEYS)
- memcpy(&p->hotkeys[hotkey_num], &tmp_hotkey, sizeof(tmp_hotkey));
- else
- ShowWarning("mmo_char_fromsql: ignoring invalid hotkey (hotkey=%d,type=%u,id=%u,lv=%u) of character %s (AID=%d,CID=%d)\n", hotkey_num, tmp_hotkey.type, tmp_hotkey.id, tmp_hotkey.lv, p->name, p->account_id, p->char_id);
- }
- strcat(t_msg, " hotkeys");
+ //read hotkeys
+ //`hotkey` (`char_id`, `hotkey`, `type`, `itemskill_id`, `skill_lvl`
+ if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `hotkey`, `type`, `itemskill_id`, `skill_lvl` FROM `%s` WHERE `char_id`=?", hotkey_db)
+ || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
+ || SQL_ERROR == SqlStmt_Execute(stmt)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &hotkey_num, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_UCHAR, &tmp_hotkey.type, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_UINT, &tmp_hotkey.id, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 3, SQLDT_USHORT, &tmp_hotkey.lv, 0, NULL, NULL) )
+ SqlStmt_ShowDebug(stmt);
+
+ while( SQL_SUCCESS == SqlStmt_NextRow(stmt) )
+ {
+ if( hotkey_num >= 0 && hotkey_num < MAX_HOTKEYS )
+ memcpy(&p->hotkeys[hotkey_num], &tmp_hotkey, sizeof(tmp_hotkey));
+ else
+ ShowWarning("mmo_char_fromsql: ignoring invalid hotkey (hotkey=%d,type=%u,id=%u,lv=%u) of character %s (AID=%d,CID=%d)\n", hotkey_num, tmp_hotkey.type, tmp_hotkey.id, tmp_hotkey.lv, p->name, p->account_id, p->char_id);
+ }
+ strcat(t_msg, " hotkeys");
#endif
- /* Mercenary Owner DataBase */
- mercenary_owner_fromsql(char_id, p);
- strcat(t_msg, " mercenary");
+ /* Mercenary Owner DataBase */
+ mercenary_owner_fromsql(char_id, p);
+ strcat(t_msg, " mercenary");
- if (save_log) ShowInfo("Loaded char (%d - %s): %s\n", char_id, p->name, t_msg); //ok. all data load successfuly!
- SqlStmt_Free(stmt);
- StringBuf_Destroy(&buf);
+ if (save_log) ShowInfo("Loaded char (%d - %s): %s\n", char_id, p->name, t_msg); //ok. all data load successfuly!
+ SqlStmt_Free(stmt);
+ StringBuf_Destroy(&buf);
- cp = idb_ensure(char_db_, char_id, create_charstatus);
- memcpy(cp, p, sizeof(struct mmo_charstatus));
- return 1;
+ cp = idb_ensure(char_db_, char_id, create_charstatus);
+ memcpy(cp, p, sizeof(struct mmo_charstatus));
+ return 1;
}
//==========================================================================================================
int mmo_char_sql_init(void)
{
- char_db_= idb_alloc(DB_OPT_RELEASE_DATA);
+ char_db_= idb_alloc(DB_OPT_RELEASE_DATA);
- ShowStatus("Characters per Account: '%d'.\n", char_per_account);
+ ShowStatus("Characters per Account: '%d'.\n", char_per_account);
- //the 'set offline' part is now in check_login_conn ...
- //if the server connects to loginserver
- //it will dc all off players
- //and send the loginserver the new state....
+ //the 'set offline' part is now in check_login_conn ...
+ //if the server connects to loginserver
+ //it will dc all off players
+ //and send the loginserver the new state....
- // Force all users offline in sql when starting char-server
- // (useful when servers crashs and don't clean the database)
- set_all_offline_sql();
+ // Force all users offline in sql when starting char-server
+ // (useful when servers crashs and don't clean the database)
+ set_all_offline_sql();
- return 0;
+ return 0;
}
//-----------------------------------
@@ -1320,193 +1357,199 @@ int mmo_char_sql_init(void)
//-----------------------------------
int rename_char_sql(struct char_session_data *sd, int char_id)
{
- struct mmo_charstatus char_dat;
- char esc_name[NAME_LENGTH*2+1];
-
- if (sd->new_name[0] == 0) // Not ready for rename
- return 2;
-
- if (!mmo_char_fromsql(char_id, &char_dat, false)) // Only the short data is needed.
- return 2;
-
- if (char_dat.rename == 0)
- return 1;
-
- Sql_EscapeStringLen(sql_handle, esc_name, sd->new_name, strnlen(sd->new_name, NAME_LENGTH));
-
- // check if the char exist
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE `name` LIKE '%s' LIMIT 1", char_db, esc_name)) {
- Sql_ShowDebug(sql_handle);
- return 4;
- }
-
- if (SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `name` = '%s', `rename` = '%d' WHERE `char_id` = '%d'", char_db, esc_name, --char_dat.rename, char_id)) {
- Sql_ShowDebug(sql_handle);
- return 3;
- }
-
- // Change character's name into guild_db.
- if (char_dat.guild_id)
- inter_guild_charname_changed(char_dat.guild_id, sd->account_id, char_id, sd->new_name);
-
- safestrncpy(char_dat.name, sd->new_name, NAME_LENGTH);
- memset(sd->new_name,0,sizeof(sd->new_name));
-
- // log change
- if (log_char) {
- if (SQL_ERROR == Sql_Query(sql_handle, "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', '0', '0', '0', '0', '0', '0', '0', '0')",
- charlog_db, "change char name", sd->account_id, char_dat.slot, esc_name))
- Sql_ShowDebug(sql_handle);
- }
-
- return 0;
+ struct mmo_charstatus char_dat;
+ char esc_name[NAME_LENGTH*2+1];
+
+ if( sd->new_name[0] == 0 ) // Not ready for rename
+ return 2;
+
+ if( !mmo_char_fromsql(char_id, &char_dat, false) ) // Only the short data is needed.
+ return 2;
+
+ if( char_dat.rename == 0 )
+ return 1;
+
+ Sql_EscapeStringLen(sql_handle, esc_name, sd->new_name, strnlen(sd->new_name, NAME_LENGTH));
+
+ // check if the char exist
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE `name` LIKE '%s' LIMIT 1", char_db, esc_name) )
+ {
+ Sql_ShowDebug(sql_handle);
+ return 4;
+ }
+
+ if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `name` = '%s', `rename` = '%d' WHERE `char_id` = '%d'", char_db, esc_name, --char_dat.rename, char_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ return 3;
+ }
+
+ // Change character's name into guild_db.
+ if( char_dat.guild_id )
+ inter_guild_charname_changed(char_dat.guild_id, sd->account_id, char_id, sd->new_name);
+
+ safestrncpy(char_dat.name, sd->new_name, NAME_LENGTH);
+ memset(sd->new_name,0,sizeof(sd->new_name));
+
+ // log change
+ if( log_char )
+ {
+ if( SQL_ERROR == Sql_Query(sql_handle, "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', '0', '0', '0', '0', '0', '0', '0', '0')",
+ charlog_db, "change char name", sd->account_id, char_dat.slot, esc_name) )
+ Sql_ShowDebug(sql_handle);
+ }
+
+ return 0;
}
-int check_char_name(char *name, char *esc_name)
+int check_char_name(char * name, char * esc_name)
{
- int i;
-
- // check length of character name
- if (name[0] == '\0')
- return -2; // empty character name
- /**
- * The client does not allow you to create names with less than 4 characters, however,
- * the use of WPE can bypass this, and this fixes the exploit.
- **/
- if (strlen(name) < 4)
- return -2;
- // check content of character name
- if (remove_control_chars(name))
- return -2; // control chars in name
-
- // check for reserved names
- if (strcmpi(name, main_chat_nick) == 0 || strcmpi(name, wisp_server_name) == 0)
- return -1; // nick reserved for internal server messages
-
- // 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 < NAME_LENGTH && name[i]; i++)
- if (strchr(char_name_letters, name[i]) == NULL)
- return -2;
- } else if (char_name_option == 2) {
- // letters/symbols in char_name_letters are forbidden
- for (i = 0; i < NAME_LENGTH && name[i]; i++)
- if (strchr(char_name_letters, name[i]) != NULL)
- return -2;
- }
- if (name_ignoring_case) {
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE BINARY `name` = '%s' LIMIT 1", char_db, esc_name)) {
- Sql_ShowDebug(sql_handle);
- return -2;
- }
- } else {
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE `name` = '%s' LIMIT 1", char_db, esc_name)) {
- Sql_ShowDebug(sql_handle);
- return -2;
- }
- }
- if (Sql_NumRows(sql_handle) > 0)
- return -1; // name already exists
-
- return 0;
+ int i;
+
+ // check length of character name
+ if( name[0] == '\0' )
+ return -2; // empty character name
+ /**
+ * The client does not allow you to create names with less than 4 characters, however,
+ * the use of WPE can bypass this, and this fixes the exploit.
+ **/
+ if( strlen( name ) < 4 )
+ return -2;
+ // check content of character name
+ if( remove_control_chars(name) )
+ return -2; // control chars in name
+
+ // check for reserved names
+ if( strcmpi(name, main_chat_nick) == 0 || strcmpi(name, wisp_server_name) == 0 )
+ return -1; // nick reserved for internal server messages
+
+ // 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 < NAME_LENGTH && name[i]; i++ )
+ if( strchr(char_name_letters, name[i]) == NULL )
+ return -2;
+ }
+ else if( char_name_option == 2 )
+ { // letters/symbols in char_name_letters are forbidden
+ for( i = 0; i < NAME_LENGTH && name[i]; i++ )
+ if( strchr(char_name_letters, name[i]) != NULL )
+ return -2;
+ }
+ if( name_ignoring_case ) {
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE BINARY `name` = '%s' LIMIT 1", char_db, esc_name) ) {
+ Sql_ShowDebug(sql_handle);
+ return -2;
+ }
+ } else {
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE `name` = '%s' LIMIT 1", char_db, esc_name) ) {
+ Sql_ShowDebug(sql_handle);
+ return -2;
+ }
+ }
+ if( Sql_NumRows(sql_handle) > 0 )
+ return -1; // name already exists
+
+ return 0;
}
//-----------------------------------
// Function to create a new character
//-----------------------------------
#if PACKETVER >= 20120307
-int make_new_char_sql(struct char_session_data *sd, char *name_, int slot, int hair_color, int hair_style)
-{
- int str = 1, agi = 1, vit = 1, int_ = 1, dex = 1, luk = 1;
+int make_new_char_sql(struct char_session_data* sd, char* name_, int slot, int hair_color, int hair_style) {
+ int str = 1, agi = 1, vit = 1, int_ = 1, dex = 1, luk = 1;
#else
-int make_new_char_sql(struct char_session_data *sd, char *name_, int str, int agi, int vit, int int_, int dex, int luk, int slot, int hair_color, int hair_style)
-{
+int make_new_char_sql(struct char_session_data* sd, char* name_, int str, int agi, int vit, int int_, int dex, int luk, int slot, int hair_color, int hair_style) {
#endif
- char name[NAME_LENGTH];
- char esc_name[NAME_LENGTH*2+1];
- int char_id, flag;
+ char name[NAME_LENGTH];
+ char esc_name[NAME_LENGTH*2+1];
+ int char_id, flag;
- safestrncpy(name, name_, NAME_LENGTH);
- normalize_name(name,TRIM_CHARS);
- Sql_EscapeStringLen(sql_handle, esc_name, name, strnlen(name, NAME_LENGTH));
+ safestrncpy(name, name_, NAME_LENGTH);
+ normalize_name(name,TRIM_CHARS);
+ Sql_EscapeStringLen(sql_handle, esc_name, name, strnlen(name, NAME_LENGTH));
- flag = check_char_name(name,esc_name);
- if (flag < 0)
- return flag;
+ flag = check_char_name(name,esc_name);
+ if( flag < 0 )
+ return flag;
- //check other inputs
+ //check other inputs
#if PACKETVER >= 20120307
- if (slot >= MAX_CHARS)
+ if(slot >= MAX_CHARS)
#else
- if ((slot >= MAX_CHARS) // slots
- || (str + agi + vit + int_ + dex + luk != 6*5) // stats
- || (str < 1 || str > 9 || agi < 1 || agi > 9 || vit < 1 || vit > 9 || int_ < 1 || int_ > 9 || dex < 1 || dex > 9 || luk < 1 || luk > 9) // individual stat values
- || (str + int_ != 10 || agi + luk != 10 || vit + dex != 10)) // pairs
+ if((slot >= MAX_CHARS) // slots
+ || (str + agi + vit + int_ + dex + luk != 6*5 ) // stats
+ || (str < 1 || str > 9 || agi < 1 || agi > 9 || vit < 1 || vit > 9 || int_ < 1 || int_ > 9 || dex < 1 || dex > 9 || luk < 1 || luk > 9) // individual stat values
+ || (str + int_ != 10 || agi + luk != 10 || vit + dex != 10) ) // pairs
#endif
- return -2; // invalid input
-
-
- // check the number of already existing chars in this account
- if (char_per_account != 0) {
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE `account_id` = '%d'", char_db, sd->account_id))
- Sql_ShowDebug(sql_handle);
- if (Sql_NumRows(sql_handle) >= char_per_account)
- return -2; // character account limit exceeded
- }
-
- // check char slot
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE `account_id` = '%d' AND `char_num` = '%d' LIMIT 1", char_db, sd->account_id, slot))
- Sql_ShowDebug(sql_handle);
- if (Sql_NumRows(sql_handle) > 0)
- return -2; // slot already in use
-
- // validation success, log result
- if (log_char) {
- if (SQL_ERROR == Sql_Query(sql_handle, "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", sd->account_id, slot, esc_name, str, agi, vit, int_, dex, luk, hair_style, hair_color))
- Sql_ShowDebug(sql_handle);
- }
+ return -2; // invalid input
+
+ if (hair_style > 17 || hair_color > 8)
+ return -2;
+
+ // check the number of already existing chars in this account
+ if( char_per_account != 0 ) {
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE `account_id` = '%d'", char_db, sd->account_id) )
+ Sql_ShowDebug(sql_handle);
+ if( Sql_NumRows(sql_handle) >= char_per_account )
+ return -2; // character account limit exceeded
+ }
+
+ // check char slot
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE `account_id` = '%d' AND `char_num` = '%d' LIMIT 1", char_db, sd->account_id, slot) )
+ Sql_ShowDebug(sql_handle);
+ if( Sql_NumRows(sql_handle) > 0 )
+ return -2; // slot already in use
+
+ // validation success, log result
+ if (log_char) {
+ if( SQL_ERROR == Sql_Query(sql_handle, "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", sd->account_id, slot, esc_name, str, agi, vit, int_, dex, luk, hair_style, hair_color) )
+ Sql_ShowDebug(sql_handle);
+ }
#if PACKETVER >= 20120307
- //Insert the new char entry to the database
- if (SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`account_id`, `char_num`, `name`, `zeny`, `status_point`,`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', '%d', '%s', '%d', '%d', '%s', '%d', '%d')",
- char_db, sd->account_id , slot, esc_name, start_zeny, 48, str, agi, vit, int_, dex, luk,
- (40 * (100 + vit)/100) , (40 * (100 + vit)/100), (11 * (100 + int_)/100), (11 * (100 + int_)/100), hair_style, hair_color,
- mapindex_id2name(start_point.map), start_point.x, start_point.y, mapindex_id2name(start_point.map), start_point.x, start_point.y)) {
- Sql_ShowDebug(sql_handle);
- return -2; //No, stop the procedure!
- }
+ //Insert the new char entry to the database
+ if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`account_id`, `char_num`, `name`, `zeny`, `status_point`,`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', '%d', '%s', '%d', '%d', '%s', '%d', '%d')",
+ char_db, sd->account_id , slot, esc_name, start_zeny, 48, str, agi, vit, int_, dex, luk,
+ (40 * (100 + vit)/100) , (40 * (100 + vit)/100 ), (11 * (100 + int_)/100), (11 * (100 + int_)/100), hair_style, hair_color,
+ mapindex_id2name(start_point.map), start_point.x, start_point.y, mapindex_id2name(start_point.map), start_point.x, start_point.y) )
+ {
+ Sql_ShowDebug(sql_handle);
+ return -2; //No, stop the procedure!
+ }
#else
- //Insert the new char entry to the database
- if (SQL_ERROR == Sql_Query(sql_handle, "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 , slot, esc_name, start_zeny, str, agi, vit, int_, dex, luk,
- (40 * (100 + vit)/100) , (40 * (100 + vit)/100), (11 * (100 + int_)/100), (11 * (100 + int_)/100), hair_style, hair_color,
- mapindex_id2name(start_point.map), start_point.x, start_point.y, mapindex_id2name(start_point.map), start_point.x, start_point.y)) {
- Sql_ShowDebug(sql_handle);
- return -2; //No, stop the procedure!
- }
+ //Insert the new char entry to the database
+ if( SQL_ERROR == Sql_Query(sql_handle, "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 , slot, esc_name, start_zeny, str, agi, vit, int_, dex, luk,
+ (40 * (100 + vit)/100) , (40 * (100 + vit)/100 ), (11 * (100 + int_)/100), (11 * (100 + int_)/100), hair_style, hair_color,
+ mapindex_id2name(start_point.map), start_point.x, start_point.y, mapindex_id2name(start_point.map), start_point.x, start_point.y) )
+ {
+ Sql_ShowDebug(sql_handle);
+ return -2; //No, stop the procedure!
+ }
#endif
- //Retrieve the newly auto-generated char id
- char_id = (int)Sql_LastInsertId(sql_handle);
- //Give the char the default items
- if (start_weapon > 0) { //add Start Weapon (Knife?)
- if (SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`char_id`,`nameid`, `amount`, `identify`) VALUES ('%d', '%d', '%d', '%d')", inventory_db, char_id, start_weapon, 1, 1))
- Sql_ShowDebug(sql_handle);
- }
- if (start_armor > 0) { //Add default armor (cotton shirt?)
- if (SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`char_id`,`nameid`, `amount`, `identify`) VALUES ('%d', '%d', '%d', '%d')", inventory_db, char_id, start_armor, 1, 1))
- Sql_ShowDebug(sql_handle);
- }
-
- ShowInfo("Created char: account: %d, char: %d, slot: %d, name: %s\n", sd->account_id, char_id, slot, name);
- return char_id;
+ //Retrieve the newly auto-generated char id
+ char_id = (int)Sql_LastInsertId(sql_handle);
+ //Give the char the default items
+ if (start_weapon > 0) { //add Start Weapon (Knife?)
+ if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`char_id`,`nameid`, `amount`, `identify`) VALUES ('%d', '%d', '%d', '%d')", inventory_db, char_id, start_weapon, 1, 1) )
+ Sql_ShowDebug(sql_handle);
+ }
+ if (start_armor > 0) { //Add default armor (cotton shirt?)
+ if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`char_id`,`nameid`, `amount`, `identify`) VALUES ('%d', '%d', '%d', '%d')", inventory_db, char_id, start_armor, 1, 1) )
+ Sql_ShowDebug(sql_handle);
+ }
+
+ ShowInfo("Created char: account: %d, char: %d, slot: %d, name: %s\n", sd->account_id, char_id, slot, name);
+ return char_id;
}
/*----------------------------------------------------------------------------------------------------------*/
@@ -1514,19 +1557,19 @@ int make_new_char_sql(struct char_session_data *sd, char *name_, int str, int ag
/*----------------------------------------------------------------------------------------------------------*/
int divorce_char_sql(int partner_id1, int partner_id2)
{
- unsigned char buf[64];
+ unsigned char buf[64];
- if (SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `partner_id`='0' WHERE `char_id`='%d' OR `char_id`='%d' LIMIT 2", char_db, partner_id1, partner_id2))
- Sql_ShowDebug(sql_handle);
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE (`nameid`='%d' OR `nameid`='%d') AND (`char_id`='%d' OR `char_id`='%d') LIMIT 2", inventory_db, WEDDING_RING_M, WEDDING_RING_F, partner_id1, partner_id2))
- Sql_ShowDebug(sql_handle);
+ if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `partner_id`='0' WHERE `char_id`='%d' OR `char_id`='%d' LIMIT 2", char_db, partner_id1, partner_id2) )
+ Sql_ShowDebug(sql_handle);
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE (`nameid`='%d' OR `nameid`='%d') AND (`char_id`='%d' OR `char_id`='%d') LIMIT 2", inventory_db, WEDDING_RING_M, WEDDING_RING_F, partner_id1, partner_id2) )
+ Sql_ShowDebug(sql_handle);
- WBUFW(buf,0) = 0x2b12;
- WBUFL(buf,2) = partner_id1;
- WBUFL(buf,6) = partner_id2;
- mapif_sendall(buf,10);
+ WBUFW(buf,0) = 0x2b12;
+ WBUFL(buf,2) = partner_id1;
+ WBUFL(buf,6) = partner_id2;
+ mapif_sendall(buf,10);
- return 0;
+ return 0;
}
/*----------------------------------------------------------------------------------------------------------*/
@@ -1537,169 +1580,151 @@ int divorce_char_sql(int partner_id1, int partner_id2)
*/
int delete_char_sql(int char_id)
{
- char name[NAME_LENGTH];
- char esc_name[NAME_LENGTH*2+1]; //Name needs be escaped.
- int account_id, party_id, guild_id, hom_id, base_level, partner_id, father_id, mother_id, elemental_id;
- char *data;
- size_t len;
-
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `name`,`account_id`,`party_id`,`guild_id`,`base_level`,`homun_id`,`partner_id`,`father`,`mother`,`elemental_id` FROM `%s` WHERE `char_id`='%d'", char_db, char_id))
- Sql_ShowDebug(sql_handle);
-
- if (SQL_SUCCESS != Sql_NextRow(sql_handle)) {
- ShowError("delete_char_sql: Unable to fetch character data, deletion aborted.\n");
- Sql_FreeResult(sql_handle);
- return -1;
- }
-
- Sql_GetData(sql_handle, 0, &data, &len);
- safestrncpy(name, data, NAME_LENGTH);
- Sql_GetData(sql_handle, 1, &data, NULL);
- account_id = atoi(data);
- Sql_GetData(sql_handle, 2, &data, NULL);
- party_id = atoi(data);
- Sql_GetData(sql_handle, 3, &data, NULL);
- guild_id = atoi(data);
- Sql_GetData(sql_handle, 4, &data, NULL);
- base_level = atoi(data);
- Sql_GetData(sql_handle, 5, &data, NULL);
- hom_id = atoi(data);
- Sql_GetData(sql_handle, 6, &data, NULL);
- partner_id = atoi(data);
- Sql_GetData(sql_handle, 7, &data, NULL);
- father_id = atoi(data);
- Sql_GetData(sql_handle, 8, &data, NULL);
- mother_id = atoi(data);
- Sql_GetData(sql_handle, 9, &data, NULL);
- elemental_id = atoi(data);
-
- Sql_EscapeStringLen(sql_handle, esc_name, name, min(len, NAME_LENGTH));
- Sql_FreeResult(sql_handle);
-
- //check for config char del condition [Lupus]
- // TODO: Move this out to packet processing (0x68/0x1fb).
- if ((char_del_level > 0 && base_level >= char_del_level)
- || (char_del_level < 0 && base_level <= -char_del_level)
- ) {
- ShowInfo("Char deletion aborted: %s, BaseLevel: %i\n", name, base_level);
- return -1;
- }
-
- /* Divorce [Wizputer] */
- if (partner_id)
- divorce_char_sql(char_id, partner_id);
-
- /* De-addopt [Zephyrus] */
- if (father_id || mother_id) {
- // Char is Baby
- unsigned char buf[64];
-
- if (SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `child`='0' WHERE `char_id`='%d' OR `char_id`='%d'", char_db, father_id, mother_id))
- Sql_ShowDebug(sql_handle);
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `id` = '410'AND (`char_id`='%d' OR `char_id`='%d')", skill_db, father_id, mother_id))
- Sql_ShowDebug(sql_handle);
-
- WBUFW(buf,0) = 0x2b25;
- WBUFL(buf,2) = father_id;
- WBUFL(buf,6) = mother_id;
- WBUFL(buf,10) = char_id; // Baby
- mapif_sendall(buf,14);
- }
-
- //Make the character leave the party [Skotlex]
- if (party_id)
- inter_party_leave(party_id, account_id, char_id);
-
- /* delete char's pet */
- //Delete the hatched pet if you have one...
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d' AND `incuvate` = '0'", pet_db, char_id))
- Sql_ShowDebug(sql_handle);
-
- //Delete all pets that are stored in eggs (inventory + cart)
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` USING `%s` JOIN `%s` ON `pet_id` = `card1`|`card2`<<16 WHERE `%s`.char_id = '%d' AND card0 = -256", pet_db, pet_db, inventory_db, inventory_db, char_id))
- Sql_ShowDebug(sql_handle);
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` USING `%s` JOIN `%s` ON `pet_id` = `card1`|`card2`<<16 WHERE `%s`.char_id = '%d' AND card0 = -256", pet_db, pet_db, cart_db, cart_db, char_id))
- Sql_ShowDebug(sql_handle);
-
- /* remove homunculus */
- if (hom_id)
- mapif_homunculus_delete(hom_id);
-
- /* remove elemental */
- if (elemental_id)
- mapif_elemental_delete(elemental_id);
-
- /* remove mercenary data */
- mercenary_owner_delete(char_id);
-
- /* delete char's friends list */
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id` = '%d'", friend_db, char_id))
- Sql_ShowDebug(sql_handle);
-
- /* delete char from other's friend list */
- //NOTE: Won't this cause problems for people who are already online? [Skotlex]
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `friend_id` = '%d'", friend_db, char_id))
- Sql_ShowDebug(sql_handle);
+ char name[NAME_LENGTH];
+ char esc_name[NAME_LENGTH*2+1]; //Name needs be escaped.
+ int account_id, party_id, guild_id, hom_id, base_level, partner_id, father_id, mother_id;
+ char* data;
+ size_t len;
+
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `name`,`account_id`,`party_id`,`guild_id`,`base_level`,`homun_id`,`partner_id`,`father`,`mother` FROM `%s` WHERE `char_id`='%d'", char_db, char_id) )
+ Sql_ShowDebug(sql_handle);
+
+ if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
+ {
+ ShowError("delete_char_sql: Unable to fetch character data, deletion aborted.\n");
+ Sql_FreeResult(sql_handle);
+ return -1;
+ }
+
+ Sql_GetData(sql_handle, 0, &data, &len); safestrncpy(name, data, NAME_LENGTH);
+ Sql_GetData(sql_handle, 1, &data, NULL); account_id = atoi(data);
+ Sql_GetData(sql_handle, 2, &data, NULL); party_id = atoi(data);
+ Sql_GetData(sql_handle, 3, &data, NULL); guild_id = atoi(data);
+ Sql_GetData(sql_handle, 4, &data, NULL); base_level = atoi(data);
+ Sql_GetData(sql_handle, 5, &data, NULL); hom_id = atoi(data);
+ Sql_GetData(sql_handle, 6, &data, NULL); partner_id = atoi(data);
+ Sql_GetData(sql_handle, 7, &data, NULL); father_id = atoi(data);
+ Sql_GetData(sql_handle, 8, &data, NULL); mother_id = atoi(data);
+
+ Sql_EscapeStringLen(sql_handle, esc_name, name, min(len, NAME_LENGTH));
+ Sql_FreeResult(sql_handle);
+
+ //check for config char del condition [Lupus]
+ // TODO: Move this out to packet processing (0x68/0x1fb).
+ if( ( char_del_level > 0 && base_level >= char_del_level )
+ || ( char_del_level < 0 && base_level <= -char_del_level )
+ ) {
+ ShowInfo("Char deletion aborted: %s, BaseLevel: %i\n", name, base_level);
+ return -1;
+ }
+
+ /* Divorce [Wizputer] */
+ if( partner_id )
+ divorce_char_sql(char_id, partner_id);
+
+ /* De-addopt [Zephyrus] */
+ if( father_id || mother_id )
+ { // Char is Baby
+ unsigned char buf[64];
+
+ if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `child`='0' WHERE `char_id`='%d' OR `char_id`='%d'", char_db, father_id, mother_id) )
+ Sql_ShowDebug(sql_handle);
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `id` = '410'AND (`char_id`='%d' OR `char_id`='%d')", skill_db, father_id, mother_id) )
+ Sql_ShowDebug(sql_handle);
+
+ WBUFW(buf,0) = 0x2b25;
+ WBUFL(buf,2) = father_id;
+ WBUFL(buf,6) = mother_id;
+ WBUFL(buf,10) = char_id; // Baby
+ mapif_sendall(buf,14);
+ }
+
+ //Make the character leave the party [Skotlex]
+ if (party_id)
+ inter_party_leave(party_id, account_id, char_id);
+
+ /* delete char's pet */
+ //Delete the hatched pet if you have one...
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d' AND `incuvate` = '0'", pet_db, char_id) )
+ Sql_ShowDebug(sql_handle);
+
+ //Delete all pets that are stored in eggs (inventory + cart)
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` USING `%s` JOIN `%s` ON `pet_id` = `card1`|`card2`<<16 WHERE `%s`.char_id = '%d' AND card0 = -256", pet_db, pet_db, inventory_db, inventory_db, char_id) )
+ Sql_ShowDebug(sql_handle);
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` USING `%s` JOIN `%s` ON `pet_id` = `card1`|`card2`<<16 WHERE `%s`.char_id = '%d' AND card0 = -256", pet_db, pet_db, cart_db, cart_db, char_id) )
+ Sql_ShowDebug(sql_handle);
+
+ /* remove homunculus */
+ if( hom_id )
+ mapif_homunculus_delete(hom_id);
+
+ /* remove mercenary data */
+ mercenary_owner_delete(char_id);
+
+ /* delete char's friends list */
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id` = '%d'", friend_db, char_id) )
+ Sql_ShowDebug(sql_handle);
+
+ /* delete char from other's friend list */
+ //NOTE: Won't this cause problems for people who are already online? [Skotlex]
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `friend_id` = '%d'", friend_db, char_id) )
+ Sql_ShowDebug(sql_handle);
#ifdef HOTKEY_SAVING
- /* delete hotkeys */
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", hotkey_db, char_id))
- Sql_ShowDebug(sql_handle);
+ /* delete hotkeys */
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", hotkey_db, char_id) )
+ Sql_ShowDebug(sql_handle);
#endif
- /* delete inventory */
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", inventory_db, char_id))
- Sql_ShowDebug(sql_handle);
-
- /* delete cart inventory */
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", cart_db, char_id))
- Sql_ShowDebug(sql_handle);
-
- /* delete memo areas */
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", memo_db, char_id))
- Sql_ShowDebug(sql_handle);
-
- /* delete character registry */
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `type`=3 AND `char_id`='%d'", reg_db, char_id))
- Sql_ShowDebug(sql_handle);
-
- /* delete skills */
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", skill_db, char_id))
- Sql_ShowDebug(sql_handle);
-
- /* delete mails (only received) */
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `dest_id`='%d'", mail_db, char_id))
- Sql_ShowDebug(sql_handle);
-
+ /* delete inventory */
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", inventory_db, char_id) )
+ Sql_ShowDebug(sql_handle);
+
+ /* delete cart inventory */
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", cart_db, char_id) )
+ Sql_ShowDebug(sql_handle);
+
+ /* delete memo areas */
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", memo_db, char_id) )
+ Sql_ShowDebug(sql_handle);
+
+ /* delete character registry */
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `type`=3 AND `char_id`='%d'", reg_db, char_id) )
+ Sql_ShowDebug(sql_handle);
+
+ /* delete skills */
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", skill_db, char_id) )
+ Sql_ShowDebug(sql_handle);
+
#ifdef ENABLE_SC_SAVING
- /* status changes */
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `char_id`='%d'", scdata_db, account_id, char_id))
- Sql_ShowDebug(sql_handle);
+ /* status changes */
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `char_id`='%d'", scdata_db, account_id, char_id) )
+ Sql_ShowDebug(sql_handle);
#endif
- if (log_char) {
- if (SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s`(`time`, `account_id`,`char_num`,`char_msg`,`name`) VALUES (NOW(), '%d', '%d', 'Deleted char (CID %d)', '%s')",
- charlog_db, account_id, 0, char_id, esc_name))
- Sql_ShowDebug(sql_handle);
- }
-
- /* delete character */
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", char_db, char_id))
- Sql_ShowDebug(sql_handle);
-
- /* No need as we used inter_guild_leave [Skotlex]
- // Also delete info from guildtables.
- if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", guild_member_db, char_id) )
- Sql_ShowDebug(sql_handle);
- */
-
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `guild_id` FROM `%s` WHERE `char_id` = '%d'", guild_db, char_id))
- Sql_ShowDebug(sql_handle);
- else if (Sql_NumRows(sql_handle) > 0)
- mapif_parse_BreakGuild(0,guild_id);
- else if (guild_id)
- inter_guild_leave(guild_id, account_id, char_id);// Leave your guild.
- return 0;
+ if (log_char) {
+ if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s`(`time`, `account_id`,`char_num`,`char_msg`,`name`) VALUES (NOW(), '%d', '%d', 'Deleted char (CID %d)', '%s')",
+ charlog_db, account_id, 0, char_id, esc_name) )
+ Sql_ShowDebug(sql_handle);
+ }
+
+ /* delete character */
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", char_db, char_id) )
+ Sql_ShowDebug(sql_handle);
+
+ /* No need as we used inter_guild_leave [Skotlex]
+ // Also delete info from guildtables.
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", guild_member_db, char_id) )
+ Sql_ShowDebug(sql_handle);
+ */
+
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `guild_id` FROM `%s` WHERE `char_id` = '%d'", guild_db, char_id) )
+ Sql_ShowDebug(sql_handle);
+ else if( Sql_NumRows(sql_handle) > 0 )
+ mapif_parse_BreakGuild(0,guild_id);
+ else if( guild_id )
+ inter_guild_leave(guild_id, account_id, char_id);// Leave your guild.
+ return 0;
}
//---------------------------------------------------------------------
@@ -1707,187 +1732,190 @@ int delete_char_sql(int char_id)
//---------------------------------------------------------------------
int count_users(void)
{
- int i, users;
-
- users = 0;
- for (i = 0; i < ARRAYLENGTH(server); i++) {
- if (server[i].fd > 0) {
- users += server[i].users;
- }
- }
- return users;
+ int i, users;
+
+ users = 0;
+ for(i = 0; i < ARRAYLENGTH(server); i++) {
+ if (server[i].fd > 0) {
+ users += server[i].users;
+ }
+ }
+ return users;
}
// Writes char data to the buffer in the format used by the client.
// Used in packets 0x6b (chars info) and 0x6d (new char info)
// Returns the size
#define MAX_CHAR_BUF 144 //Max size (for WFIFOHEAD calls)
-int mmo_char_tobuf(uint8 *buffer, struct mmo_charstatus *p)
+int mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p)
{
- unsigned short offset = 0;
- uint8 *buf;
-
- if (buffer == NULL || p == NULL)
- return 0;
-
- buf = WBUFP(buffer,0);
- WBUFL(buf,0) = p->char_id;
- WBUFL(buf,4) = min(p->base_exp, INT32_MAX);
- WBUFL(buf,8) = p->zeny;
- WBUFL(buf,12) = min(p->job_exp, INT32_MAX);
- WBUFL(buf,16) = p->job_level;
- WBUFL(buf,20) = 0; // probably opt1
- WBUFL(buf,24) = 0; // probably opt2
- WBUFL(buf,28) = p->option;
- WBUFL(buf,32) = p->karma;
- WBUFL(buf,36) = p->manner;
- WBUFW(buf,40) = min(p->status_point, INT16_MAX);
- WBUFL(buf,42) = p->hp;
- WBUFL(buf,46) = p->max_hp;
- offset+=4;
- buf = WBUFP(buffer,offset);
- WBUFW(buf,46) = min(p->sp, INT16_MAX);
- WBUFW(buf,48) = min(p->max_sp, INT16_MAX);
- WBUFW(buf,50) = DEFAULT_WALK_SPEED; // p->speed;
- WBUFW(buf,52) = p->class_;
- WBUFW(buf,54) = p->hair;
-
- //When the weapon is sent and your option is riding, the client crashes on login!?
- WBUFW(buf,56) = p->option&(0x20|0x80000|0x100000|0x200000|0x400000|0x800000|0x1000000|0x2000000|0x4000000|0x8000000) ? 0 : p->weapon;
-
- WBUFW(buf,58) = p->base_level;
- WBUFW(buf,60) = min(p->skill_point, INT16_MAX);
- WBUFW(buf,62) = p->head_bottom;
- WBUFW(buf,64) = p->shield;
- WBUFW(buf,66) = p->head_top;
- WBUFW(buf,68) = p->head_mid;
- WBUFW(buf,70) = p->hair_color;
- WBUFW(buf,72) = p->clothes_color;
- memcpy(WBUFP(buf,74), p->name, NAME_LENGTH);
- WBUFB(buf,98) = min(p->str, UINT8_MAX);
- WBUFB(buf,99) = min(p->agi, UINT8_MAX);
- WBUFB(buf,100) = min(p->vit, UINT8_MAX);
- WBUFB(buf,101) = min(p->int_, UINT8_MAX);
- WBUFB(buf,102) = min(p->dex, UINT8_MAX);
- WBUFB(buf,103) = min(p->luk, UINT8_MAX);
- WBUFW(buf,104) = p->slot;
- WBUFW(buf,106) = (p->rename > 0) ? 0 : 1;
- offset += 2;
+ unsigned short offset = 0;
+ uint8* buf;
+
+ if( buffer == NULL || p == NULL )
+ return 0;
+
+ buf = WBUFP(buffer,0);
+ WBUFL(buf,0) = p->char_id;
+ WBUFL(buf,4) = min(p->base_exp, INT32_MAX);
+ WBUFL(buf,8) = p->zeny;
+ WBUFL(buf,12) = min(p->job_exp, INT32_MAX);
+ WBUFL(buf,16) = p->job_level;
+ WBUFL(buf,20) = 0; // probably opt1
+ WBUFL(buf,24) = 0; // probably opt2
+ WBUFL(buf,28) = p->option;
+ WBUFL(buf,32) = p->karma;
+ WBUFL(buf,36) = p->manner;
+ WBUFW(buf,40) = min(p->status_point, INT16_MAX);
+ WBUFL(buf,42) = p->hp;
+ WBUFL(buf,46) = p->max_hp;
+ offset+=4;
+ buf = WBUFP(buffer,offset);
+ WBUFW(buf,46) = min(p->sp, INT16_MAX);
+ WBUFW(buf,48) = min(p->max_sp, INT16_MAX);
+ WBUFW(buf,50) = DEFAULT_WALK_SPEED; // p->speed;
+ WBUFW(buf,52) = p->class_;
+ WBUFW(buf,54) = p->hair;
+
+ //When the weapon is sent and your option is riding, the client crashes on login!?
+ WBUFW(buf,56) = p->option&(0x20|0x80000|0x100000|0x200000|0x400000|0x800000|0x1000000|0x2000000|0x4000000|0x8000000) ? 0 : p->weapon;
+
+ WBUFW(buf,58) = p->base_level;
+ WBUFW(buf,60) = min(p->skill_point, INT16_MAX);
+ WBUFW(buf,62) = p->head_bottom;
+ WBUFW(buf,64) = p->shield;
+ WBUFW(buf,66) = p->head_top;
+ WBUFW(buf,68) = p->head_mid;
+ WBUFW(buf,70) = p->hair_color;
+ WBUFW(buf,72) = p->clothes_color;
+ memcpy(WBUFP(buf,74), p->name, NAME_LENGTH);
+ WBUFB(buf,98) = min(p->str, UINT8_MAX);
+ WBUFB(buf,99) = min(p->agi, UINT8_MAX);
+ WBUFB(buf,100) = min(p->vit, UINT8_MAX);
+ WBUFB(buf,101) = min(p->int_, UINT8_MAX);
+ WBUFB(buf,102) = min(p->dex, UINT8_MAX);
+ WBUFB(buf,103) = min(p->luk, UINT8_MAX);
+ WBUFW(buf,104) = p->slot;
+ WBUFW(buf,106) = ( p->rename > 0 ) ? 0 : 1;
+ offset += 2;
#if (PACKETVER >= 20100720 && PACKETVER <= 20100727) || PACKETVER >= 20100803
- mapindex_getmapname_ext(mapindex_id2name(p->last_point.map), (char *)WBUFP(buf,108));
- offset += MAP_NAME_LENGTH_EXT;
+ mapindex_getmapname_ext(mapindex_id2name(p->last_point.map), (char*)WBUFP(buf,108));
+ offset += MAP_NAME_LENGTH_EXT;
#endif
#if PACKETVER >= 20100803
- WBUFL(buf,124) = TOL(p->delete_date);
- offset += 4;
+ WBUFL(buf,124) = TOL(p->delete_date);
+ offset += 4;
#endif
#if PACKETVER >= 20110111
- WBUFL(buf,128) = p->robe;
- offset += 4;
+ WBUFL(buf,128) = p->robe;
+ offset += 4;
#endif
#if PACKETVER != 20111116 //2011-11-16 wants 136, ask gravity.
-#if PACKETVER >= 20110928
- WBUFL(buf,132) = 0; // change slot feature (0 = disabled, otherwise enabled)
- offset += 4;
-#endif
-#if PACKETVER >= 20111025
- WBUFL(buf,136) = (p->rename > 0) ? 1 : 0; // (0 = disabled, otherwise displays "Add-Ons" sidebar)
- offset += 4;
-#endif
+ #if PACKETVER >= 20110928
+ WBUFL(buf,132) = 0; // change slot feature (0 = disabled, otherwise enabled)
+ offset += 4;
+ #endif
+ #if PACKETVER >= 20111025
+ WBUFL(buf,136) = ( p->rename > 0 ) ? 1 : 0; // (0 = disabled, otherwise displays "Add-Ons" sidebar)
+ offset += 4;
+ #endif
#endif
- return 106+offset;
+ return 106+offset;
}
//----------------------------------------
// Function to send characters to a player
//----------------------------------------
-int mmo_char_send006b(int fd, struct char_session_data *sd)
+int mmo_char_send006b(int fd, struct char_session_data* sd)
{
- int j, offset = 0;
+ int j, offset = 0;
#if PACKETVER >= 20100413
- offset += 3;
+ offset += 3;
#endif
- if (save_log)
- ShowInfo("Loading Char Data ("CL_BOLD"%d"CL_RESET")\n",sd->account_id);
+ if (save_log)
+ ShowInfo("Loading Char Data ("CL_BOLD"%d"CL_RESET")\n",sd->account_id);
- j = 24 + offset; // offset
- WFIFOHEAD(fd,j + MAX_CHARS*MAX_CHAR_BUF);
- WFIFOW(fd,0) = 0x6b;
+ j = 24 + offset; // offset
+ WFIFOHEAD(fd,j + MAX_CHARS*MAX_CHAR_BUF);
+ WFIFOW(fd,0) = 0x6b;
#if PACKETVER >= 20100413
- WFIFOB(fd,4) = MAX_CHARS; // Max slots.
- WFIFOB(fd,5) = MAX_CHARS; // Available slots.
- WFIFOB(fd,6) = MAX_CHARS; // Premium slots.
+ WFIFOB(fd,4) = MAX_CHARS; // Max slots.
+ WFIFOB(fd,5) = MAX_CHARS; // Available slots.
+ WFIFOB(fd,6) = MAX_CHARS; // Premium slots.
#endif
- memset(WFIFOP(fd,4 + offset), 0, 20); // unknown bytes
- j+=mmo_chars_fromsql(sd, WFIFOP(fd,j));
- WFIFOW(fd,2) = j; // packet len
- WFIFOSET(fd,j);
+ memset(WFIFOP(fd,4 + offset), 0, 20); // unknown bytes
+ j+=mmo_chars_fromsql(sd, WFIFOP(fd,j));
+ WFIFOW(fd,2) = j; // packet len
+ WFIFOSET(fd,j);
- return 0;
+ return 0;
}
int char_married(int pl1, int pl2)
{
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `partner_id` FROM `%s` WHERE `char_id` = '%d'", char_db, pl1))
- Sql_ShowDebug(sql_handle);
- else if (SQL_SUCCESS == Sql_NextRow(sql_handle)) {
- char *data;
-
- Sql_GetData(sql_handle, 0, &data, NULL);
- if (pl2 == atoi(data)) {
- Sql_FreeResult(sql_handle);
- return 1;
- }
- }
- Sql_FreeResult(sql_handle);
- return 0;
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `partner_id` FROM `%s` WHERE `char_id` = '%d'", char_db, pl1) )
+ Sql_ShowDebug(sql_handle);
+ else if( SQL_SUCCESS == Sql_NextRow(sql_handle) )
+ {
+ char* data;
+
+ Sql_GetData(sql_handle, 0, &data, NULL);
+ if( pl2 == atoi(data) )
+ {
+ Sql_FreeResult(sql_handle);
+ return 1;
+ }
+ }
+ Sql_FreeResult(sql_handle);
+ return 0;
}
int char_child(int parent_id, int child_id)
{
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `child` FROM `%s` WHERE `char_id` = '%d'", char_db, parent_id))
- Sql_ShowDebug(sql_handle);
- else if (SQL_SUCCESS == Sql_NextRow(sql_handle)) {
- char *data;
-
- Sql_GetData(sql_handle, 0, &data, NULL);
- if (child_id == atoi(data)) {
- Sql_FreeResult(sql_handle);
- return 1;
- }
- }
- Sql_FreeResult(sql_handle);
- return 0;
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `child` FROM `%s` WHERE `char_id` = '%d'", char_db, parent_id) )
+ Sql_ShowDebug(sql_handle);
+ else if( SQL_SUCCESS == Sql_NextRow(sql_handle) )
+ {
+ char* data;
+
+ Sql_GetData(sql_handle, 0, &data, NULL);
+ if( child_id == atoi(data) )
+ {
+ Sql_FreeResult(sql_handle);
+ return 1;
+ }
+ }
+ Sql_FreeResult(sql_handle);
+ return 0;
}
int char_family(int cid1, int cid2, int cid3)
{
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `char_id`,`partner_id`,`child` FROM `%s` WHERE `char_id` IN ('%d','%d','%d')", char_db, cid1, cid2, cid3))
- Sql_ShowDebug(sql_handle);
- else while (SQL_SUCCESS == Sql_NextRow(sql_handle)) {
- int charid;
- int partnerid;
- int childid;
- char *data;
-
- Sql_GetData(sql_handle, 0, &data, NULL);
- charid = atoi(data);
- Sql_GetData(sql_handle, 1, &data, NULL);
- partnerid = atoi(data);
- Sql_GetData(sql_handle, 2, &data, NULL);
- childid = atoi(data);
-
- if ((cid1 == charid && ((cid2 == partnerid && cid3 == childid) || (cid2 == childid && cid3 == partnerid))) ||
- (cid1 == partnerid && ((cid2 == charid && cid3 == childid) || (cid2 == childid && cid3 == charid))) ||
- (cid1 == childid && ((cid2 == charid && cid3 == partnerid) || (cid2 == partnerid && cid3 == charid)))) {
- Sql_FreeResult(sql_handle);
- return childid;
- }
- }
- Sql_FreeResult(sql_handle);
- return 0;
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `char_id`,`partner_id`,`child` FROM `%s` WHERE `char_id` IN ('%d','%d','%d')", char_db, cid1, cid2, cid3) )
+ Sql_ShowDebug(sql_handle);
+ else while( SQL_SUCCESS == Sql_NextRow(sql_handle) )
+ {
+ int charid;
+ int partnerid;
+ int childid;
+ char* data;
+
+ Sql_GetData(sql_handle, 0, &data, NULL); charid = atoi(data);
+ Sql_GetData(sql_handle, 1, &data, NULL); partnerid = atoi(data);
+ Sql_GetData(sql_handle, 2, &data, NULL); childid = atoi(data);
+
+ if( (cid1 == charid && ((cid2 == partnerid && cid3 == childid ) || (cid2 == childid && cid3 == partnerid))) ||
+ (cid1 == partnerid && ((cid2 == charid && cid3 == childid ) || (cid2 == childid && cid3 == charid ))) ||
+ (cid1 == childid && ((cid2 == charid && cid3 == partnerid) || (cid2 == partnerid && cid3 == charid ))) )
+ {
+ Sql_FreeResult(sql_handle);
+ return childid;
+ }
+ }
+ Sql_FreeResult(sql_handle);
+ return 0;
}
//----------------------------------------------------------------------
@@ -1895,58 +1923,58 @@ int char_family(int cid1, int cid2, int cid3)
//----------------------------------------------------------------------
void disconnect_player(int account_id)
{
- int i;
- struct char_session_data *sd;
+ int i;
+ struct char_session_data* sd;
- // disconnect player if online on char-server
- ARR_FIND(0, fd_max, i, session[i] && (sd = (struct char_session_data *)session[i]->session_data) && sd->account_id == account_id);
- if (i < fd_max)
- set_eof(i);
+ // disconnect player if online on char-server
+ ARR_FIND( 0, fd_max, i, session[i] && (sd = (struct char_session_data*)session[i]->session_data) && sd->account_id == account_id );
+ if( i < fd_max )
+ set_eof(i);
}
static void char_auth_ok(int fd, struct char_session_data *sd)
{
- struct online_char_data *character;
-
- if ((character = (struct online_char_data *)idb_get(online_char_db, sd->account_id)) != NULL) {
- // check if character is not online already. [Skotlex]
- if (character->server > -1) {
- //Character already online. KICK KICK KICK
- mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 2);
- if (character->waiting_disconnect == INVALID_TIMER)
- character->waiting_disconnect = add_timer(gettick()+20000, chardb_waiting_disconnect, character->account_id, 0);
- WFIFOHEAD(fd,3);
- WFIFOW(fd,0) = 0x81;
- WFIFOB(fd,2) = 8;
- WFIFOSET(fd,3);
- return;
- }
- if (character->fd >= 0 && character->fd != fd) {
- //There's already a connection from this account that hasn't picked a char yet.
- WFIFOHEAD(fd,3);
- WFIFOW(fd,0) = 0x81;
- WFIFOB(fd,2) = 8;
- WFIFOSET(fd,3);
- return;
- }
- character->fd = fd;
- }
-
- if (login_fd > 0) {
- // request account data
- WFIFOHEAD(login_fd,6);
- WFIFOW(login_fd,0) = 0x2716;
- WFIFOL(login_fd,2) = sd->account_id;
- WFIFOSET(login_fd,6);
- }
-
- // mark session as 'authed'
- sd->auth = true;
-
- // set char online on charserver
- set_char_charselect(sd->account_id);
-
- // continues when account data is received...
+ struct online_char_data* character;
+
+ if( (character = (struct online_char_data*)idb_get(online_char_db, sd->account_id)) != NULL )
+ { // check if character is not online already. [Skotlex]
+ if (character->server > -1)
+ { //Character already online. KICK KICK KICK
+ mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 2);
+ if (character->waiting_disconnect == INVALID_TIMER)
+ character->waiting_disconnect = add_timer(gettick()+20000, chardb_waiting_disconnect, character->account_id, 0);
+ WFIFOHEAD(fd,3);
+ WFIFOW(fd,0) = 0x81;
+ WFIFOB(fd,2) = 8;
+ WFIFOSET(fd,3);
+ return;
+ }
+ if (character->fd >= 0 && character->fd != fd)
+ { //There's already a connection from this account that hasn't picked a char yet.
+ WFIFOHEAD(fd,3);
+ WFIFOW(fd,0) = 0x81;
+ WFIFOB(fd,2) = 8;
+ WFIFOSET(fd,3);
+ return;
+ }
+ character->fd = fd;
+ }
+
+ if (login_fd > 0) {
+ // request account data
+ WFIFOHEAD(login_fd,6);
+ WFIFOW(login_fd,0) = 0x2716;
+ WFIFOL(login_fd,2) = sd->account_id;
+ WFIFOSET(login_fd,6);
+ }
+
+ // mark session as 'authed'
+ sd->auth = true;
+
+ // set char online on charserver
+ set_char_charselect(sd->account_id);
+
+ // continues when account data is received...
}
int send_accounts_tologin(int tid, unsigned int tick, int id, intptr_t data);
@@ -1956,12 +1984,12 @@ void mapif_server_reset(int id);
/// Resets all the data.
void loginif_reset(void)
{
- int id;
- // TODO kick everyone out and reset everything or wait for connect and try to reaquire locks [FlavioJS]
- for (id = 0; id < ARRAYLENGTH(server); ++id)
- mapif_server_reset(id);
- flush_fifos();
- exit(EXIT_FAILURE);
+ int id;
+ // TODO kick everyone out and reset everything or wait for connect and try to reaquire locks [FlavioJS]
+ for( id = 0; id < ARRAYLENGTH(server); ++id )
+ mapif_server_reset(id);
+ flush_fifos();
+ exit(EXIT_FAILURE);
}
@@ -1970,361 +1998,366 @@ void loginif_reset(void)
/// If all the conditions are met, it stops the core loop.
void loginif_check_shutdown(void)
{
- if (runflag != CHARSERVER_ST_SHUTDOWN)
- return;
- runflag = CORE_ST_STOP;
+ if( runflag != CHARSERVER_ST_SHUTDOWN )
+ return;
+ runflag = CORE_ST_STOP;
}
/// Called when the connection to Login Server is disconnected.
void loginif_on_disconnect(void)
{
- ShowWarning("Connection to Login Server lost.\n\n");
+ ShowWarning("Connection to Login Server lost.\n\n");
}
/// Called when all the connection steps are completed.
void loginif_on_ready(void)
{
- int i;
+ int i;
- loginif_check_shutdown();
+ loginif_check_shutdown();
+
+ //Send online accounts to login server.
+ send_accounts_tologin(INVALID_TIMER, gettick(), 0, 0);
- //Send online accounts to login server.
- send_accounts_tologin(INVALID_TIMER, gettick(), 0, 0);
-
- // if no map-server already connected, display a message...
- ARR_FIND(0, ARRAYLENGTH(server), i, server[i].fd > 0 && server[i].map[0]);
- if (i == ARRAYLENGTH(server))
- ShowStatus("Awaiting maps from map-server.\n");
+ // if no map-server already connected, display a message...
+ ARR_FIND( 0, ARRAYLENGTH(server), i, server[i].fd > 0 && server[i].map[0] );
+ if( i == ARRAYLENGTH(server) )
+ ShowStatus("Awaiting maps from map-server.\n");
}
-int parse_fromlogin(int fd)
-{
- struct char_session_data *sd = NULL;
- int i;
-
- // only process data from the login-server
- if (fd != login_fd) {
- ShowDebug("parse_fromlogin: Disconnecting invalid session #%d (is not the login-server)\n", fd);
- do_close(fd);
- return 0;
- }
-
- if (session[fd]->flag.eof) {
- do_close(fd);
- login_fd = -1;
- loginif_on_disconnect();
- return 0;
- } else if (session[fd]->flag.ping) { /* we've reached stall time */
- if (DIFF_TICK(last_tick, session[fd]->rdata_tick) > (stall_time * 2)) { /* we can't wait any longer */
- set_eof(fd);
- return 0;
- } else if (session[fd]->flag.ping != 2) { /* we haven't sent ping out yet */
- WFIFOHEAD(fd,2);// sends a ping packet to login server (will receive pong 0x2718)
- WFIFOW(fd,0) = 0x2719;
- WFIFOSET(fd,2);
-
- session[fd]->flag.ping = 2;
- }
- }
-
- sd = (struct char_session_data *)session[fd]->session_data;
-
- while (RFIFOREST(fd) >= 2) {
- uint16 command = RFIFOW(fd,0);
-
- switch (command) {
-
- // acknowledgement of connect-to-loginserver request
- case 0x2711:
- if (RFIFOREST(fd) < 3)
- return 0;
-
- if (RFIFOB(fd,2)) {
- //printf("connect login server error : %d\n", RFIFOB(fd,2));
- ShowError("Can not connect to login-server.\n");
- ShowError("The server communication passwords (default s1/p1) are probably invalid.\n");
- ShowError("Also, please make sure your login db has the correct communication username/passwords and the gender of the account is S.\n");
- ShowError("The communication passwords are set in map_athena.conf and char_athena.conf\n");
- set_eof(fd);
- return 0;
- } else {
- ShowStatus("Connected to login-server (connection #%d).\n", fd);
- loginif_on_ready();
- }
- RFIFOSKIP(fd,3);
- break;
-
- // acknowledgement of account authentication request
- case 0x2713:
- if (RFIFOREST(fd) < 25)
- return 0;
- {
- int account_id = RFIFOL(fd,2);
- uint32 login_id1 = RFIFOL(fd,6);
- uint32 login_id2 = RFIFOL(fd,10);
- uint8 sex = RFIFOB(fd,14);
- uint8 result = RFIFOB(fd,15);
- int request_id = RFIFOL(fd,16);
- uint32 version = RFIFOL(fd,20);
- uint8 clienttype = RFIFOB(fd,24);
- RFIFOSKIP(fd,25);
-
- if (session_isActive(request_id) && (sd=(struct char_session_data *)session[request_id]->session_data) &&
- !sd->auth && sd->account_id == account_id && sd->login_id1 == login_id1 && sd->login_id2 == login_id2 && sd->sex == sex) {
- int client_fd = request_id;
- sd->version = version;
- sd->clienttype = clienttype;
- switch (result) {
- case 0:// ok
- char_auth_ok(client_fd, sd);
- break;
- case 1:// auth failed
- WFIFOHEAD(client_fd,3);
- WFIFOW(client_fd,0) = 0x6c;
- WFIFOB(client_fd,2) = 0;// rejected from server
- WFIFOSET(client_fd,3);
- break;
- }
- }
- }
- break;
-
- case 0x2717: // account data
- if (RFIFOREST(fd) < 62)
- return 0;
-
- // find the authenticated session with this account id
- ARR_FIND(0, fd_max, i, session[i] && (sd = (struct char_session_data *)session[i]->session_data) && sd->auth && sd->account_id == RFIFOL(fd,2));
- if (i < fd_max) {
- int server_id;
- memcpy(sd->email, RFIFOP(fd,6), 40);
- sd->expiration_time = (time_t)RFIFOL(fd,46);
- sd->group_id = RFIFOB(fd,50);
- safestrncpy(sd->birthdate, (const char *)RFIFOP(fd,51), sizeof(sd->birthdate));
- ARR_FIND(0, ARRAYLENGTH(server), server_id, server[server_id].fd > 0 && server[server_id].map[0]);
- // continued from char_auth_ok...
- if (server_id == ARRAYLENGTH(server) || //server not online, bugreport:2359
- (max_connect_user && count_users() >= max_connect_user && sd->group_id != gm_allow_group)) {
- // refuse connection (over populated)
- WFIFOHEAD(i,3);
- WFIFOW(i,0) = 0x6c;
- WFIFOW(i,2) = 0;
- WFIFOSET(i,3);
- } else {
- // send characters to player
- mmo_char_send006b(i, sd);
+int parse_fromlogin(int fd) {
+ struct char_session_data* sd = NULL;
+ int i;
+
+ // only process data from the login-server
+ if( fd != login_fd ) {
+ ShowDebug("parse_fromlogin: Disconnecting invalid session #%d (is not the login-server)\n", fd);
+ do_close(fd);
+ return 0;
+ }
+
+ if( session[fd]->flag.eof ) {
+ do_close(fd);
+ login_fd = -1;
+ loginif_on_disconnect();
+ return 0;
+ } else if ( session[fd]->flag.ping ) {/* we've reached stall time */
+ if( DIFF_TICK(last_tick, session[fd]->rdata_tick) > (stall_time * 2) ) {/* we can't wait any longer */
+ set_eof(fd);
+ return 0;
+ } else if( session[fd]->flag.ping != 2 ) { /* we haven't sent ping out yet */
+ WFIFOHEAD(fd,2);// sends a ping packet to login server (will receive pong 0x2718)
+ WFIFOW(fd,0) = 0x2719;
+ WFIFOSET(fd,2);
+
+ session[fd]->flag.ping = 2;
+ }
+ }
+
+ sd = (struct char_session_data*)session[fd]->session_data;
+
+ while(RFIFOREST(fd) >= 2) {
+ uint16 command = RFIFOW(fd,0);
+
+ switch( command )
+ {
+
+ // acknowledgement of connect-to-loginserver request
+ case 0x2711:
+ if (RFIFOREST(fd) < 3)
+ return 0;
+
+ if (RFIFOB(fd,2)) {
+ //printf("connect login server error : %d\n", RFIFOB(fd,2));
+ ShowError("Can not connect to login-server.\n");
+ ShowError("The server communication passwords (default s1/p1) are probably invalid.\n");
+ ShowError("Also, please make sure your login db has the correct communication username/passwords and the gender of the account is S.\n");
+ ShowError("The communication passwords are set in map_athena.conf and char_athena.conf\n");
+ set_eof(fd);
+ return 0;
+ } else {
+ ShowStatus("Connected to login-server (connection #%d).\n", fd);
+ loginif_on_ready();
+ }
+ RFIFOSKIP(fd,3);
+ break;
+
+ // acknowledgement of account authentication request
+ case 0x2713:
+ if (RFIFOREST(fd) < 25)
+ return 0;
+ {
+ int account_id = RFIFOL(fd,2);
+ uint32 login_id1 = RFIFOL(fd,6);
+ uint32 login_id2 = RFIFOL(fd,10);
+ uint8 sex = RFIFOB(fd,14);
+ uint8 result = RFIFOB(fd,15);
+ int request_id = RFIFOL(fd,16);
+ uint32 version = RFIFOL(fd,20);
+ uint8 clienttype = RFIFOB(fd,24);
+ RFIFOSKIP(fd,25);
+
+ if( session_isActive(request_id) && (sd=(struct char_session_data*)session[request_id]->session_data) &&
+ !sd->auth && sd->account_id == account_id && sd->login_id1 == login_id1 && sd->login_id2 == login_id2 && sd->sex == sex )
+ {
+ int client_fd = request_id;
+ sd->version = version;
+ sd->clienttype = clienttype;
+ switch( result )
+ {
+ case 0:// ok
+ char_auth_ok(client_fd, sd);
+ break;
+ case 1:// auth failed
+ WFIFOHEAD(client_fd,3);
+ WFIFOW(client_fd,0) = 0x6c;
+ WFIFOB(client_fd,2) = 0;// rejected from server
+ WFIFOSET(client_fd,3);
+ break;
+ }
+ }
+ }
+ break;
+
+ case 0x2717: // account data
+ if (RFIFOREST(fd) < 62)
+ return 0;
+
+ // find the authenticated session with this account id
+ ARR_FIND( 0, fd_max, i, session[i] && (sd = (struct char_session_data*)session[i]->session_data) && sd->auth && sd->account_id == RFIFOL(fd,2) );
+ if( i < fd_max )
+ {
+ int server_id;
+ memcpy(sd->email, RFIFOP(fd,6), 40);
+ sd->expiration_time = (time_t)RFIFOL(fd,46);
+ sd->group_id = RFIFOB(fd,50);
+ safestrncpy(sd->birthdate, (const char*)RFIFOP(fd,51), sizeof(sd->birthdate));
+ ARR_FIND( 0, ARRAYLENGTH(server), server_id, server[server_id].fd > 0 && server[server_id].map[0] );
+ // continued from char_auth_ok...
+ if( server_id == ARRAYLENGTH(server) || //server not online, bugreport:2359
+ ( max_connect_user && count_users() >= max_connect_user && sd->group_id != gm_allow_group ) ) {
+ // refuse connection (over populated)
+ WFIFOHEAD(i,3);
+ WFIFOW(i,0) = 0x6c;
+ WFIFOW(i,2) = 0;
+ WFIFOSET(i,3);
+ } else {
+ // send characters to player
+ mmo_char_send006b(i, sd);
#if PACKETVER >= 20110309
- // PIN code system, disabled
- WFIFOHEAD(i, 12);
- WFIFOW(i, 0) = 0x08B9;
- WFIFOW(i, 2) = 0;
- WFIFOW(i, 4) = 0;
- WFIFOL(i, 6) = sd->account_id;
- WFIFOW(i, 10) = 0;
- WFIFOSET(i, 12);
+ // PIN code system, disabled
+ WFIFOHEAD(i, 12);
+ WFIFOW(i, 0) = 0x08B9;
+ WFIFOW(i, 2) = 0;
+ WFIFOW(i, 4) = 0;
+ WFIFOL(i, 6) = sd->account_id;
+ WFIFOW(i, 10) = 0;
+ WFIFOSET(i, 12);
#endif
- }
- }
- RFIFOSKIP(fd,62);
- break;
-
- // login-server alive packet
- case 0x2718:
- if (RFIFOREST(fd) < 2)
- return 0;
- RFIFOSKIP(fd,2);
- session[fd]->flag.ping = 0;
- break;
-
- // changesex reply
- case 0x2723:
- if (RFIFOREST(fd) < 7)
- return 0;
- {
- unsigned char buf[7];
-
- int acc = RFIFOL(fd,2);
- int sex = RFIFOB(fd,6);
- RFIFOSKIP(fd,7);
-
- if (acc > 0) {
- // TODO: Is this even possible?
- int char_id[MAX_CHARS];
- int class_[MAX_CHARS];
- int guild_id[MAX_CHARS];
- int num;
- char *data;
-
- struct auth_node *node = (struct auth_node *)idb_get(auth_db, acc);
- if (node != NULL)
- node->sex = sex;
-
- // get characters
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `char_id`,`class`,`guild_id` FROM `%s` WHERE `account_id` = '%d'", char_db, acc))
- Sql_ShowDebug(sql_handle);
- for (i = 0; i < MAX_CHARS && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i) {
- Sql_GetData(sql_handle, 0, &data, NULL);
- char_id[i] = atoi(data);
- Sql_GetData(sql_handle, 1, &data, NULL);
- class_[i] = atoi(data);
- Sql_GetData(sql_handle, 2, &data, NULL);
- guild_id[i] = atoi(data);
- }
- num = i;
- for (i = 0; i < num; ++i) {
- if (class_[i] == JOB_BARD || class_[i] == JOB_DANCER ||
- class_[i] == JOB_CLOWN || class_[i] == JOB_GYPSY ||
- class_[i] == JOB_BABY_BARD || class_[i] == JOB_BABY_DANCER ||
- class_[i] == JOB_MINSTREL || class_[i] == JOB_WANDERER ||
- class_[i] == JOB_MINSTREL_T || class_[i] == JOB_WANDERER_T ||
- class_[i] == JOB_BABY_MINSTREL || class_[i] == JOB_BABY_WANDERER ||
- class_[i] == JOB_KAGEROU || class_[i] == JOB_OBORO) {
- // job modification
- if (class_[i] == JOB_BARD || class_[i] == JOB_DANCER)
- class_[i] = (sex ? JOB_BARD : JOB_DANCER);
- else if (class_[i] == JOB_CLOWN || class_[i] == JOB_GYPSY)
- class_[i] = (sex ? JOB_CLOWN : JOB_GYPSY);
- else if (class_[i] == JOB_BABY_BARD || class_[i] == JOB_BABY_DANCER)
- class_[i] = (sex ? JOB_BABY_BARD : JOB_BABY_DANCER);
- else if (class_[i] == JOB_MINSTREL || class_[i] == JOB_WANDERER)
- class_[i] = (sex ? JOB_MINSTREL : JOB_WANDERER);
- else if (class_[i] == JOB_MINSTREL_T || class_[i] == JOB_WANDERER_T)
- class_[i] = (sex ? JOB_MINSTREL_T : JOB_WANDERER_T);
- else if (class_[i] == JOB_BABY_MINSTREL || class_[i] == JOB_BABY_WANDERER)
- class_[i] = (sex ? JOB_BABY_MINSTREL : JOB_BABY_WANDERER);
- else if (class_[i] == JOB_KAGEROU || class_[i] == JOB_OBORO)
- class_[i] = (sex ? JOB_KAGEROU : JOB_OBORO);
- }
-
- if (SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `class`='%d', `weapon`='0', `shield`='0', `head_top`='0', `head_mid`='0', `head_bottom`='0' WHERE `char_id`='%d'", char_db, class_[i], char_id[i]))
- Sql_ShowDebug(sql_handle);
-
- if (guild_id[i]) // If there is a guild, update the guild_member data [Skotlex]
- inter_guild_sex_changed(guild_id[i], acc, char_id[i], sex);
- }
- Sql_FreeResult(sql_handle);
-
- // disconnect player if online on char-server
- disconnect_player(acc);
- }
-
- // notify all mapservers about this change
- WBUFW(buf,0) = 0x2b0d;
- WBUFL(buf,2) = acc;
- WBUFB(buf,6) = sex;
- mapif_sendall(buf, 7);
- }
- break;
-
- // reply to an account_reg2 registry request
- case 0x2729:
- if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
- return 0;
-
- {
- //Receive account_reg2 registry, forward to map servers.
- unsigned char buf[13+ACCOUNT_REG2_NUM*sizeof(struct global_reg)];
- memcpy(buf,RFIFOP(fd,0), RFIFOW(fd,2));
- WBUFW(buf,0) = 0x3804; //Map server can now receive all kinds of reg values with the same packet. [Skotlex]
- mapif_sendall(buf, WBUFW(buf,2));
- RFIFOSKIP(fd, RFIFOW(fd,2));
- }
- break;
-
- // State change of account/ban notification (from login-server)
- case 0x2731:
- if (RFIFOREST(fd) < 11)
- return 0;
-
- {
- // send to all map-servers to disconnect the player
- unsigned char buf[11];
- 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
- disconnect_player(RFIFOL(fd,2));
-
- RFIFOSKIP(fd,11);
- break;
-
- // Login server request to kick a character out. [Skotlex]
- case 0x2734:
- if (RFIFOREST(fd) < 6)
- return 0;
- {
- int aid = RFIFOL(fd,2);
- struct online_char_data *character = (struct online_char_data *)idb_get(online_char_db, aid);
- RFIFOSKIP(fd,6);
- if (character != NULL) {
- // account is already marked as online!
- if (character->server > -1) {
- //Kick it from the map server it is on.
- mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 2);
- if (character->waiting_disconnect == INVALID_TIMER)
- character->waiting_disconnect = add_timer(gettick()+AUTH_TIMEOUT, chardb_waiting_disconnect, character->account_id, 0);
- } else {
- // Manual kick from char server.
- struct char_session_data *tsd;
- int i;
- ARR_FIND(0, fd_max, i, session[i] && (tsd = (struct char_session_data *)session[i]->session_data) && tsd->account_id == aid);
- if (i < fd_max) {
- WFIFOHEAD(i,3);
- WFIFOW(i,0) = 0x81;
- WFIFOB(i,2) = 2; // "Someone has already logged in with this id"
- WFIFOSET(i,3);
- set_eof(i);
- } else // still moving to the map-server
- set_char_offline(-1, aid);
- }
- }
- idb_remove(auth_db, aid);// reject auth attempts from map-server
- }
- break;
-
- // ip address update signal from login server
- case 0x2735: {
- unsigned char buf[2];
- uint32 new_ip = 0;
-
- WBUFW(buf,0) = 0x2b1e;
- mapif_sendall(buf, 2);
-
- new_ip = host2ip(login_ip_str);
- if (new_ip && new_ip != login_ip)
- login_ip = new_ip; //Update login ip, too.
-
- new_ip = host2ip(char_ip_str);
- if (new_ip && new_ip != char_ip) {
- //Update ip.
- char_ip = new_ip;
- ShowInfo("Updating IP for [%s].\n", char_ip_str);
- // notify login server about the change
- WFIFOHEAD(fd,6);
- WFIFOW(fd,0) = 0x2736;
- WFIFOL(fd,2) = htonl(char_ip);
- WFIFOSET(fd,6);
- }
-
- RFIFOSKIP(fd,2);
- }
- break;
-
- default:
- ShowError("Unknown packet 0x%04x received from login-server, disconnecting.\n", command);
- set_eof(fd);
- return 0;
- }
- }
-
- RFIFOFLUSH(fd);
- return 0;
+ }
+ }
+ RFIFOSKIP(fd,62);
+ break;
+
+ // login-server alive packet
+ case 0x2718:
+ if (RFIFOREST(fd) < 2)
+ return 0;
+ RFIFOSKIP(fd,2);
+ session[fd]->flag.ping = 0;
+ break;
+
+ // changesex reply
+ case 0x2723:
+ if (RFIFOREST(fd) < 7)
+ return 0;
+ {
+ unsigned char buf[7];
+
+ int acc = RFIFOL(fd,2);
+ int sex = RFIFOB(fd,6);
+ RFIFOSKIP(fd,7);
+
+ if( acc > 0 )
+ {// TODO: Is this even possible?
+ int char_id[MAX_CHARS];
+ int class_[MAX_CHARS];
+ int guild_id[MAX_CHARS];
+ int num;
+ char* data;
+
+ struct auth_node* node = (struct auth_node*)idb_get(auth_db, acc);
+ if( node != NULL )
+ node->sex = sex;
+
+ // get characters
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `char_id`,`class`,`guild_id` FROM `%s` WHERE `account_id` = '%d'", char_db, acc) )
+ Sql_ShowDebug(sql_handle);
+ for( i = 0; i < MAX_CHARS && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
+ {
+ Sql_GetData(sql_handle, 0, &data, NULL); char_id[i] = atoi(data);
+ Sql_GetData(sql_handle, 1, &data, NULL); class_[i] = atoi(data);
+ Sql_GetData(sql_handle, 2, &data, NULL); guild_id[i] = atoi(data);
+ }
+ num = i;
+ for( i = 0; i < num; ++i )
+ {
+ if( class_[i] == JOB_BARD || class_[i] == JOB_DANCER ||
+ class_[i] == JOB_CLOWN || class_[i] == JOB_GYPSY ||
+ class_[i] == JOB_BABY_BARD || class_[i] == JOB_BABY_DANCER ||
+ class_[i] == JOB_MINSTREL || class_[i] == JOB_WANDERER ||
+ class_[i] == JOB_MINSTREL_T || class_[i] == JOB_WANDERER_T ||
+ class_[i] == JOB_BABY_MINSTREL || class_[i] == JOB_BABY_WANDERER ||
+ class_[i] == JOB_KAGEROU || class_[i] == JOB_OBORO )
+ {
+ // job modification
+ if( class_[i] == JOB_BARD || class_[i] == JOB_DANCER )
+ class_[i] = (sex ? JOB_BARD : JOB_DANCER);
+ else if( class_[i] == JOB_CLOWN || class_[i] == JOB_GYPSY )
+ class_[i] = (sex ? JOB_CLOWN : JOB_GYPSY);
+ else if( class_[i] == JOB_BABY_BARD || class_[i] == JOB_BABY_DANCER )
+ class_[i] = (sex ? JOB_BABY_BARD : JOB_BABY_DANCER);
+ else if( class_[i] == JOB_MINSTREL || class_[i] == JOB_WANDERER )
+ class_[i] = (sex ? JOB_MINSTREL : JOB_WANDERER);
+ else if( class_[i] == JOB_MINSTREL_T || class_[i] == JOB_WANDERER_T )
+ class_[i] = (sex ? JOB_MINSTREL_T : JOB_WANDERER_T);
+ else if( class_[i] == JOB_BABY_MINSTREL || class_[i] == JOB_BABY_WANDERER )
+ class_[i] = (sex ? JOB_BABY_MINSTREL : JOB_BABY_WANDERER);
+ else if( class_[i] == JOB_KAGEROU || class_[i] == JOB_OBORO )
+ class_[i] = (sex ? JOB_KAGEROU : JOB_OBORO);
+ }
+
+ if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `class`='%d', `weapon`='0', `shield`='0', `head_top`='0', `head_mid`='0', `head_bottom`='0' WHERE `char_id`='%d'", char_db, class_[i], char_id[i]) )
+ Sql_ShowDebug(sql_handle);
+
+ if( guild_id[i] )// If there is a guild, update the guild_member data [Skotlex]
+ inter_guild_sex_changed(guild_id[i], acc, char_id[i], sex);
+ }
+ Sql_FreeResult(sql_handle);
+
+ // disconnect player if online on char-server
+ disconnect_player(acc);
+ }
+
+ // notify all mapservers about this change
+ WBUFW(buf,0) = 0x2b0d;
+ WBUFL(buf,2) = acc;
+ WBUFB(buf,6) = sex;
+ mapif_sendall(buf, 7);
+ }
+ break;
+
+ // reply to an account_reg2 registry request
+ case 0x2729:
+ if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
+ return 0;
+
+ { //Receive account_reg2 registry, forward to map servers.
+ unsigned char buf[13+ACCOUNT_REG2_NUM*sizeof(struct global_reg)];
+ memcpy(buf,RFIFOP(fd,0), RFIFOW(fd,2));
+ WBUFW(buf,0) = 0x3804; //Map server can now receive all kinds of reg values with the same packet. [Skotlex]
+ mapif_sendall(buf, WBUFW(buf,2));
+ RFIFOSKIP(fd, RFIFOW(fd,2));
+ }
+ break;
+
+ // State change of account/ban notification (from login-server)
+ case 0x2731:
+ if (RFIFOREST(fd) < 11)
+ return 0;
+
+ { // send to all map-servers to disconnect the player
+ unsigned char buf[11];
+ 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
+ disconnect_player(RFIFOL(fd,2));
+
+ RFIFOSKIP(fd,11);
+ break;
+
+ // Login server request to kick a character out. [Skotlex]
+ case 0x2734:
+ if (RFIFOREST(fd) < 6)
+ return 0;
+ {
+ int aid = RFIFOL(fd,2);
+ struct online_char_data* character = (struct online_char_data*)idb_get(online_char_db, aid);
+ RFIFOSKIP(fd,6);
+ if( character != NULL )
+ {// account is already marked as online!
+ if( character->server > -1 )
+ { //Kick it from the map server it is on.
+ mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 2);
+ if (character->waiting_disconnect == INVALID_TIMER)
+ character->waiting_disconnect = add_timer(gettick()+AUTH_TIMEOUT, chardb_waiting_disconnect, character->account_id, 0);
+ }
+ else
+ {// Manual kick from char server.
+ struct char_session_data *tsd;
+ int i;
+ ARR_FIND( 0, fd_max, i, session[i] && (tsd = (struct char_session_data*)session[i]->session_data) && tsd->account_id == aid );
+ if( i < fd_max )
+ {
+ WFIFOHEAD(i,3);
+ WFIFOW(i,0) = 0x81;
+ WFIFOB(i,2) = 2; // "Someone has already logged in with this id"
+ WFIFOSET(i,3);
+ set_eof(i);
+ }
+ else // still moving to the map-server
+ set_char_offline(-1, aid);
+ }
+ }
+ idb_remove(auth_db, aid);// reject auth attempts from map-server
+ }
+ break;
+
+ // ip address update signal from login server
+ case 0x2735:
+ {
+ unsigned char buf[2];
+ uint32 new_ip = 0;
+
+ WBUFW(buf,0) = 0x2b1e;
+ mapif_sendall(buf, 2);
+
+ new_ip = host2ip(login_ip_str);
+ if (new_ip && new_ip != login_ip)
+ login_ip = new_ip; //Update login ip, too.
+
+ new_ip = host2ip(char_ip_str);
+ if (new_ip && new_ip != char_ip)
+ { //Update ip.
+ char_ip = new_ip;
+ ShowInfo("Updating IP for [%s].\n", char_ip_str);
+ // notify login server about the change
+ WFIFOHEAD(fd,6);
+ WFIFOW(fd,0) = 0x2736;
+ WFIFOL(fd,2) = htonl(char_ip);
+ WFIFOSET(fd,6);
+ }
+
+ RFIFOSKIP(fd,2);
+ }
+ break;
+
+ default:
+ ShowError("Unknown packet 0x%04x received from login-server, disconnecting.\n", command);
+ set_eof(fd);
+ return 0;
+ }
+ }
+
+ RFIFOFLUSH(fd);
+ return 0;
}
int check_connect_login_server(int tid, unsigned int tick, int id, intptr_t data);
@@ -2332,169 +2365,176 @@ int send_accounts_tologin(int tid, unsigned int tick, int id, intptr_t data);
void do_init_loginif(void)
{
- // establish char-login connection if not present
- add_timer_func_list(check_connect_login_server, "check_connect_login_server");
- add_timer_interval(gettick() + 1000, check_connect_login_server, 0, 0, 10 * 1000);
-
- // send a list of all online account IDs to login server
- add_timer_func_list(send_accounts_tologin, "send_accounts_tologin");
- add_timer_interval(gettick() + 1000, send_accounts_tologin, 0, 0, 3600 * 1000); //Sync online accounts every hour
+ // establish char-login connection if not present
+ add_timer_func_list(check_connect_login_server, "check_connect_login_server");
+ add_timer_interval(gettick() + 1000, check_connect_login_server, 0, 0, 10 * 1000);
+
+ // send a list of all online account IDs to login server
+ add_timer_func_list(send_accounts_tologin, "send_accounts_tologin");
+ add_timer_interval(gettick() + 1000, send_accounts_tologin, 0, 0, 3600 * 1000); //Sync online accounts every hour
}
void do_final_loginif(void)
{
- if (login_fd != -1) {
- do_close(login_fd);
- login_fd = -1;
- }
+ if( login_fd != -1 )
+ {
+ do_close(login_fd);
+ login_fd = -1;
+ }
}
int request_accreg2(int account_id, int char_id)
{
- if (login_fd > 0) {
- WFIFOHEAD(login_fd,10);
- WFIFOW(login_fd,0) = 0x272e;
- WFIFOL(login_fd,2) = account_id;
- WFIFOL(login_fd,6) = char_id;
- WFIFOSET(login_fd,10);
- return 1;
- }
- return 0;
+ if (login_fd > 0) {
+ WFIFOHEAD(login_fd,10);
+ WFIFOW(login_fd,0) = 0x272e;
+ WFIFOL(login_fd,2) = account_id;
+ WFIFOL(login_fd,6) = char_id;
+ WFIFOSET(login_fd,10);
+ return 1;
+ }
+ return 0;
}
//Send packet forward to login-server for account saving
-int save_accreg2(unsigned char *buf, int len)
+int save_accreg2(unsigned char* buf, int len)
{
- if (login_fd > 0) {
- WFIFOHEAD(login_fd,len+4);
- memcpy(WFIFOP(login_fd,4), buf, len);
- WFIFOW(login_fd,0) = 0x2728;
- WFIFOW(login_fd,2) = len+4;
- WFIFOSET(login_fd,len+4);
- return 1;
- }
- return 0;
+ if (login_fd > 0) {
+ WFIFOHEAD(login_fd,len+4);
+ memcpy(WFIFOP(login_fd,4), buf, len);
+ WFIFOW(login_fd,0) = 0x2728;
+ WFIFOW(login_fd,2) = len+4;
+ WFIFOSET(login_fd,len+4);
+ return 1;
+ }
+ return 0;
}
void char_read_fame_list(void)
{
- int i;
- char *data;
- size_t len;
-
- // Empty ranking lists
- memset(smith_fame_list, 0, sizeof(smith_fame_list));
- memset(chemist_fame_list, 0, sizeof(chemist_fame_list));
- memset(taekwon_fame_list, 0, sizeof(taekwon_fame_list));
- // Build Blacksmith ranking list
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `char_id`,`fame`,`name` FROM `%s` WHERE `fame`>0 AND (`class`='%d' OR `class`='%d' OR `class`='%d' OR `class`='%d' OR `class`='%d' OR `class`='%d') ORDER BY `fame` DESC LIMIT 0,%d", char_db, JOB_BLACKSMITH, JOB_WHITESMITH, JOB_BABY_BLACKSMITH, JOB_MECHANIC, JOB_MECHANIC_T, JOB_BABY_MECHANIC, fame_list_size_smith))
- Sql_ShowDebug(sql_handle);
- for (i = 0; i < fame_list_size_smith && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i) {
- // char_id
- Sql_GetData(sql_handle, 0, &data, NULL);
- smith_fame_list[i].id = atoi(data);
- // fame
- Sql_GetData(sql_handle, 1, &data, &len);
- smith_fame_list[i].fame = atoi(data);
- // name
- Sql_GetData(sql_handle, 2, &data, &len);
- memcpy(smith_fame_list[i].name, data, min(len, NAME_LENGTH));
- }
- // Build Alchemist ranking list
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `char_id`,`fame`,`name` FROM `%s` WHERE `fame`>0 AND (`class`='%d' OR `class`='%d' OR `class`='%d' OR `class`='%d' OR `class`='%d' OR `class`='%d') ORDER BY `fame` DESC LIMIT 0,%d", char_db, JOB_ALCHEMIST, JOB_CREATOR, JOB_BABY_ALCHEMIST, JOB_GENETIC, JOB_GENETIC_T, JOB_BABY_GENETIC, fame_list_size_chemist))
- Sql_ShowDebug(sql_handle);
- for (i = 0; i < fame_list_size_chemist && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i) {
- // char_id
- Sql_GetData(sql_handle, 0, &data, NULL);
- chemist_fame_list[i].id = atoi(data);
- // fame
- Sql_GetData(sql_handle, 1, &data, &len);
- chemist_fame_list[i].fame = atoi(data);
- // name
- Sql_GetData(sql_handle, 2, &data, &len);
- memcpy(chemist_fame_list[i].name, data, min(len, NAME_LENGTH));
- }
- // Build Taekwon ranking list
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `char_id`,`fame`,`name` FROM `%s` WHERE `fame`>0 AND (`class`='%d') ORDER BY `fame` DESC LIMIT 0,%d", char_db, JOB_TAEKWON, fame_list_size_taekwon))
- Sql_ShowDebug(sql_handle);
- for (i = 0; i < fame_list_size_taekwon && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i) {
- // char_id
- Sql_GetData(sql_handle, 0, &data, NULL);
- taekwon_fame_list[i].id = atoi(data);
- // fame
- Sql_GetData(sql_handle, 1, &data, &len);
- taekwon_fame_list[i].fame = atoi(data);
- // name
- Sql_GetData(sql_handle, 2, &data, &len);
- memcpy(taekwon_fame_list[i].name, data, min(len, NAME_LENGTH));
- }
- Sql_FreeResult(sql_handle);
+ int i;
+ char* data;
+ size_t len;
+
+ // Empty ranking lists
+ memset(smith_fame_list, 0, sizeof(smith_fame_list));
+ memset(chemist_fame_list, 0, sizeof(chemist_fame_list));
+ memset(taekwon_fame_list, 0, sizeof(taekwon_fame_list));
+ // Build Blacksmith ranking list
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `char_id`,`fame`,`name` FROM `%s` WHERE `fame`>0 AND (`class`='%d' OR `class`='%d' OR `class`='%d' OR `class`='%d' OR `class`='%d' OR `class`='%d') ORDER BY `fame` DESC LIMIT 0,%d", char_db, JOB_BLACKSMITH, JOB_WHITESMITH, JOB_BABY_BLACKSMITH, JOB_MECHANIC, JOB_MECHANIC_T, JOB_BABY_MECHANIC, fame_list_size_smith) )
+ Sql_ShowDebug(sql_handle);
+ for( i = 0; i < fame_list_size_smith && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
+ {
+ // char_id
+ Sql_GetData(sql_handle, 0, &data, NULL);
+ smith_fame_list[i].id = atoi(data);
+ // fame
+ Sql_GetData(sql_handle, 1, &data, &len);
+ smith_fame_list[i].fame = atoi(data);
+ // name
+ Sql_GetData(sql_handle, 2, &data, &len);
+ memcpy(smith_fame_list[i].name, data, min(len, NAME_LENGTH));
+ }
+ // Build Alchemist ranking list
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `char_id`,`fame`,`name` FROM `%s` WHERE `fame`>0 AND (`class`='%d' OR `class`='%d' OR `class`='%d' OR `class`='%d' OR `class`='%d' OR `class`='%d') ORDER BY `fame` DESC LIMIT 0,%d", char_db, JOB_ALCHEMIST, JOB_CREATOR, JOB_BABY_ALCHEMIST, JOB_GENETIC, JOB_GENETIC_T, JOB_BABY_GENETIC, fame_list_size_chemist) )
+ Sql_ShowDebug(sql_handle);
+ for( i = 0; i < fame_list_size_chemist && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
+ {
+ // char_id
+ Sql_GetData(sql_handle, 0, &data, NULL);
+ chemist_fame_list[i].id = atoi(data);
+ // fame
+ Sql_GetData(sql_handle, 1, &data, &len);
+ chemist_fame_list[i].fame = atoi(data);
+ // name
+ Sql_GetData(sql_handle, 2, &data, &len);
+ memcpy(chemist_fame_list[i].name, data, min(len, NAME_LENGTH));
+ }
+ // Build Taekwon ranking list
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `char_id`,`fame`,`name` FROM `%s` WHERE `fame`>0 AND (`class`='%d') ORDER BY `fame` DESC LIMIT 0,%d", char_db, JOB_TAEKWON, fame_list_size_taekwon) )
+ Sql_ShowDebug(sql_handle);
+ for( i = 0; i < fame_list_size_taekwon && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
+ {
+ // char_id
+ Sql_GetData(sql_handle, 0, &data, NULL);
+ taekwon_fame_list[i].id = atoi(data);
+ // fame
+ Sql_GetData(sql_handle, 1, &data, &len);
+ taekwon_fame_list[i].fame = atoi(data);
+ // name
+ Sql_GetData(sql_handle, 2, &data, &len);
+ memcpy(taekwon_fame_list[i].name, data, min(len, NAME_LENGTH));
+ }
+ Sql_FreeResult(sql_handle);
}
// Send map-servers the fame ranking lists
int char_send_fame_list(int fd)
{
- int i, len = 8;
- unsigned char buf[32000];
-
- WBUFW(buf,0) = 0x2b1b;
-
- for (i = 0; i < fame_list_size_smith && smith_fame_list[i].id; i++) {
- memcpy(WBUFP(buf, len), &smith_fame_list[i], sizeof(struct fame_list));
- len += sizeof(struct fame_list);
- }
- // add blacksmith's block length
- WBUFW(buf, 6) = len;
-
- for (i = 0; i < fame_list_size_chemist && chemist_fame_list[i].id; i++) {
- memcpy(WBUFP(buf, len), &chemist_fame_list[i], sizeof(struct fame_list));
- len += sizeof(struct fame_list);
- }
- // add alchemist's block length
- WBUFW(buf, 4) = len;
-
- for (i = 0; i < fame_list_size_taekwon && taekwon_fame_list[i].id; i++) {
- memcpy(WBUFP(buf, len), &taekwon_fame_list[i], sizeof(struct fame_list));
- len += sizeof(struct fame_list);
- }
- // add total packet length
- WBUFW(buf, 2) = len;
-
- if (fd != -1)
- mapif_send(fd, buf, len);
- else
- mapif_sendall(buf, len);
-
- return 0;
+ int i, len = 8;
+ unsigned char buf[32000];
+
+ WBUFW(buf,0) = 0x2b1b;
+
+ for(i = 0; i < fame_list_size_smith && smith_fame_list[i].id; i++) {
+ memcpy(WBUFP(buf, len), &smith_fame_list[i], sizeof(struct fame_list));
+ len += sizeof(struct fame_list);
+ }
+ // add blacksmith's block length
+ WBUFW(buf, 6) = len;
+
+ for(i = 0; i < fame_list_size_chemist && chemist_fame_list[i].id; i++) {
+ memcpy(WBUFP(buf, len), &chemist_fame_list[i], sizeof(struct fame_list));
+ len += sizeof(struct fame_list);
+ }
+ // add alchemist's block length
+ WBUFW(buf, 4) = len;
+
+ for(i = 0; i < fame_list_size_taekwon && taekwon_fame_list[i].id; i++) {
+ memcpy(WBUFP(buf, len), &taekwon_fame_list[i], sizeof(struct fame_list));
+ len += sizeof(struct fame_list);
+ }
+ // add total packet length
+ WBUFW(buf, 2) = len;
+
+ if (fd != -1)
+ mapif_send(fd, buf, len);
+ else
+ mapif_sendall(buf, len);
+
+ return 0;
}
void char_update_fame_list(int type, int index, int fame)
{
- unsigned char buf[8];
- WBUFW(buf,0) = 0x2b22;
- WBUFB(buf,2) = type;
- WBUFB(buf,3) = index;
- WBUFL(buf,4) = fame;
- mapif_sendall(buf, 8);
+ unsigned char buf[8];
+ WBUFW(buf,0) = 0x2b22;
+ WBUFB(buf,2) = type;
+ WBUFB(buf,3) = index;
+ WBUFL(buf,4) = fame;
+ mapif_sendall(buf, 8);
}
//Loads a character's name and stores it in the buffer given (must be NAME_LENGTH in size)
//Returns 1 on found, 0 on not found (buffer is filled with Unknown char name)
-int char_loadName(int char_id, char *name)
+int char_loadName(int char_id, char* name)
{
- char *data;
- size_t len;
-
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `name` FROM `%s` WHERE `char_id`='%d'", char_db, char_id))
- Sql_ShowDebug(sql_handle);
- else if (SQL_SUCCESS == Sql_NextRow(sql_handle)) {
- Sql_GetData(sql_handle, 0, &data, &len);
- safestrncpy(name, data, NAME_LENGTH);
- return 1;
- } else {
- safestrncpy(name, unknown_char_name, NAME_LENGTH);
- }
- return 0;
+ char* data;
+ size_t len;
+
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `name` FROM `%s` WHERE `char_id`='%d'", char_db, char_id) )
+ Sql_ShowDebug(sql_handle);
+ else if( SQL_SUCCESS == Sql_NextRow(sql_handle) )
+ {
+ Sql_GetData(sql_handle, 0, &data, &len);
+ safestrncpy(name, data, NAME_LENGTH);
+ return 1;
+ }
+ else
+ {
+ safestrncpy(name, unknown_char_name, NAME_LENGTH);
+ }
+ return 0;
}
int search_mapserver(unsigned short map, uint32 ip, uint16 port);
@@ -2503,825 +2543,833 @@ int search_mapserver(unsigned short map, uint32 ip, uint16 port);
/// Initializes a server structure.
void mapif_server_init(int id)
{
- memset(&server[id], 0, sizeof(server[id]));
- server[id].fd = -1;
+ memset(&server[id], 0, sizeof(server[id]));
+ server[id].fd = -1;
}
/// Destroys a server structure.
void mapif_server_destroy(int id)
{
- if (server[id].fd == -1) {
- do_close(server[id].fd);
- server[id].fd = -1;
- }
+ if( server[id].fd == -1 )
+ {
+ do_close(server[id].fd);
+ server[id].fd = -1;
+ }
}
/// Resets all the data related to a server.
void mapif_server_reset(int id)
{
- int i,j;
- unsigned char buf[16384];
- int fd = server[id].fd;
- //Notify other map servers that this one is gone. [Skotlex]
- WBUFW(buf,0) = 0x2b20;
- WBUFL(buf,4) = htonl(server[id].ip);
- WBUFW(buf,8) = htons(server[id].port);
- j = 0;
- for (i = 0; i < MAX_MAP_PER_SERVER; i++)
- if (server[id].map[i])
- WBUFW(buf,10+(j++)*4) = server[id].map[i];
- if (j > 0) {
- WBUFW(buf,2) = j * 4 + 10;
- mapif_sendallwos(fd, buf, WBUFW(buf,2));
- }
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `index`='%d'", ragsrvinfo_db, server[id].fd))
- Sql_ShowDebug(sql_handle);
- online_char_db->foreach(online_char_db,char_db_setoffline,id); //Tag relevant chars as 'in disconnected' server.
- mapif_server_destroy(id);
- mapif_server_init(id);
+ int i,j;
+ unsigned char buf[16384];
+ int fd = server[id].fd;
+ //Notify other map servers that this one is gone. [Skotlex]
+ WBUFW(buf,0) = 0x2b20;
+ WBUFL(buf,4) = htonl(server[id].ip);
+ WBUFW(buf,8) = htons(server[id].port);
+ j = 0;
+ for(i = 0; i < MAX_MAP_PER_SERVER; i++)
+ if (server[id].map[i])
+ WBUFW(buf,10+(j++)*4) = server[id].map[i];
+ if (j > 0) {
+ WBUFW(buf,2) = j * 4 + 10;
+ mapif_sendallwos(fd, buf, WBUFW(buf,2));
+ }
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `index`='%d'", ragsrvinfo_db, server[id].fd) )
+ Sql_ShowDebug(sql_handle);
+ online_char_db->foreach(online_char_db,char_db_setoffline,id); //Tag relevant chars as 'in disconnected' server.
+ mapif_server_destroy(id);
+ mapif_server_init(id);
}
/// Called when the connection to a Map Server is disconnected.
void mapif_on_disconnect(int id)
{
- ShowStatus("Map-server #%d has disconnected.\n", id);
- mapif_server_reset(id);
+ ShowStatus("Map-server #%d has disconnected.\n", id);
+ mapif_server_reset(id);
}
int parse_frommap(int fd)
{
- int i, j;
- int id;
-
- ARR_FIND(0, ARRAYLENGTH(server), id, server[id].fd == fd);
- if (id == ARRAYLENGTH(server)) {
- // not a map server
- ShowDebug("parse_frommap: Disconnecting invalid session #%d (is not a map-server)\n", fd);
- do_close(fd);
- return 0;
- }
- if (session[fd]->flag.eof) {
- do_close(fd);
- server[id].fd = -1;
- mapif_on_disconnect(id);
- return 0;
- }
-
- while (RFIFOREST(fd) >= 2) {
- switch (RFIFOW(fd,0)) {
-
- case 0x2afa: // Receiving map names list from the map-server
- 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 += 4) {
- server[id].map[j] = RFIFOW(fd,i);
- j++;
- }
-
- ShowStatus("Map-Server %d connected: %d maps, from IP %d.%d.%d.%d port %d.\n",
- id, j, CONVIP(server[id].ip), server[id].port);
- ShowStatus("Map-server %d loading complete.\n", id);
-
- // send name for wisp to player
- WFIFOHEAD(fd, 3 + NAME_LENGTH);
- WFIFOW(fd,0) = 0x2afb;
- WFIFOB(fd,2) = 0;
- memcpy(WFIFOP(fd,3), wisp_server_name, NAME_LENGTH);
- WFIFOSET(fd,3+NAME_LENGTH);
-
- char_send_fame_list(fd); //Send fame list.
-
- {
- unsigned char buf[16384];
- int x;
- if (j == 0) {
- ShowWarning("Map-server %d has NO maps.\n", id);
- } else {
- // Transmitting maps information to the other map-servers
- WBUFW(buf,0) = 0x2b04;
- WBUFW(buf,2) = j * 4 + 10;
- WBUFL(buf,4) = htonl(server[id].ip);
- WBUFW(buf,8) = htons(server[id].port);
- memcpy(WBUFP(buf,10), RFIFOP(fd,4), j * 4);
- mapif_sendallwos(fd, buf, WBUFW(buf,2));
- }
- // Transmitting the maps of the other map-servers to the new map-server
- for (x = 0; x < ARRAYLENGTH(server); x++) {
- if (server[x].fd > 0 && x != id) {
- WFIFOHEAD(fd,10 +4*ARRAYLENGTH(server[x].map));
- WFIFOW(fd,0) = 0x2b04;
- WFIFOL(fd,4) = htonl(server[x].ip);
- WFIFOW(fd,8) = htons(server[x].port);
- j = 0;
- for (i = 0; i < ARRAYLENGTH(server[x].map); i++)
- if (server[x].map[i])
- WFIFOW(fd,10+(j++)*4) = server[x].map[i];
- if (j > 0) {
- WFIFOW(fd,2) = j * 4 + 10;
- WFIFOSET(fd,WFIFOW(fd,2));
- }
- }
- }
- }
- RFIFOSKIP(fd,RFIFOW(fd,2));
- break;
-
- case 0x2afc: //Packet command is now used for sc_data request. [Skotlex]
- if (RFIFOREST(fd) < 10)
- return 0;
- {
+ int i, j;
+ int id;
+
+ ARR_FIND( 0, ARRAYLENGTH(server), id, server[id].fd == fd );
+ if( id == ARRAYLENGTH(server) )
+ {// not a map server
+ ShowDebug("parse_frommap: Disconnecting invalid session #%d (is not a map-server)\n", fd);
+ do_close(fd);
+ return 0;
+ }
+ if( session[fd]->flag.eof )
+ {
+ do_close(fd);
+ server[id].fd = -1;
+ mapif_on_disconnect(id);
+ return 0;
+ }
+
+ while(RFIFOREST(fd) >= 2)
+ {
+ switch(RFIFOW(fd,0))
+ {
+
+ case 0x2afa: // Receiving map names list from the map-server
+ 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 += 4) {
+ server[id].map[j] = RFIFOW(fd,i);
+ j++;
+ }
+
+ ShowStatus("Map-Server %d connected: %d maps, from IP %d.%d.%d.%d port %d.\n",
+ id, j, CONVIP(server[id].ip), server[id].port);
+ ShowStatus("Map-server %d loading complete.\n", id);
+
+ // send name for wisp to player
+ WFIFOHEAD(fd, 3 + NAME_LENGTH);
+ WFIFOW(fd,0) = 0x2afb;
+ WFIFOB(fd,2) = 0;
+ memcpy(WFIFOP(fd,3), wisp_server_name, NAME_LENGTH);
+ WFIFOSET(fd,3+NAME_LENGTH);
+
+ char_send_fame_list(fd); //Send fame list.
+
+ {
+ unsigned char buf[16384];
+ int x;
+ if (j == 0) {
+ ShowWarning("Map-server %d has NO maps.\n", id);
+ } else {
+ // Transmitting maps information to the other map-servers
+ WBUFW(buf,0) = 0x2b04;
+ WBUFW(buf,2) = j * 4 + 10;
+ WBUFL(buf,4) = htonl(server[id].ip);
+ WBUFW(buf,8) = htons(server[id].port);
+ memcpy(WBUFP(buf,10), RFIFOP(fd,4), j * 4);
+ mapif_sendallwos(fd, buf, WBUFW(buf,2));
+ }
+ // Transmitting the maps of the other map-servers to the new map-server
+ for(x = 0; x < ARRAYLENGTH(server); x++) {
+ if (server[x].fd > 0 && x != id) {
+ WFIFOHEAD(fd,10 +4*ARRAYLENGTH(server[x].map));
+ WFIFOW(fd,0) = 0x2b04;
+ WFIFOL(fd,4) = htonl(server[x].ip);
+ WFIFOW(fd,8) = htons(server[x].port);
+ j = 0;
+ for(i = 0; i < ARRAYLENGTH(server[x].map); i++)
+ if (server[x].map[i])
+ WFIFOW(fd,10+(j++)*4) = server[x].map[i];
+ if (j > 0) {
+ WFIFOW(fd,2) = j * 4 + 10;
+ WFIFOSET(fd,WFIFOW(fd,2));
+ }
+ }
+ }
+ }
+ RFIFOSKIP(fd,RFIFOW(fd,2));
+ break;
+
+ case 0x2afc: //Packet command is now used for sc_data request. [Skotlex]
+ if (RFIFOREST(fd) < 10)
+ return 0;
+ {
#ifdef ENABLE_SC_SAVING
- int aid, cid;
- aid = RFIFOL(fd,2);
- cid = RFIFOL(fd,6);
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT type, tick, val1, val2, val3, val4 from `%s` WHERE `account_id` = '%d' AND `char_id`='%d'",
- scdata_db, aid, cid)) {
- Sql_ShowDebug(sql_handle);
- break;
- }
- if (Sql_NumRows(sql_handle) > 0) {
- struct status_change_data scdata;
- int count;
- char *data;
-
- WFIFOHEAD(fd,14+50*sizeof(struct status_change_data));
- WFIFOW(fd,0) = 0x2b1d;
- WFIFOL(fd,4) = aid;
- WFIFOL(fd,8) = cid;
- for (count = 0; count < 50 && SQL_SUCCESS == Sql_NextRow(sql_handle); ++count) {
- Sql_GetData(sql_handle, 0, &data, NULL);
- scdata.type = atoi(data);
- Sql_GetData(sql_handle, 1, &data, NULL);
- scdata.tick = atoi(data);
- Sql_GetData(sql_handle, 2, &data, NULL);
- scdata.val1 = atoi(data);
- Sql_GetData(sql_handle, 3, &data, NULL);
- scdata.val2 = atoi(data);
- Sql_GetData(sql_handle, 4, &data, NULL);
- scdata.val3 = atoi(data);
- Sql_GetData(sql_handle, 5, &data, NULL);
- scdata.val4 = atoi(data);
- memcpy(WFIFOP(fd, 14+count*sizeof(struct status_change_data)), &scdata, sizeof(struct status_change_data));
- }
- if (count >= 50)
- ShowWarning("Too many status changes for %d:%d, some of them were not loaded.\n", aid, cid);
- if (count > 0) {
- WFIFOW(fd,2) = 14 + count*sizeof(struct status_change_data);
- WFIFOW(fd,12) = count;
- WFIFOSET(fd,WFIFOW(fd,2));
-
- //Clear the data once loaded.
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `char_id`='%d'", scdata_db, aid, cid))
- Sql_ShowDebug(sql_handle);
- }
- }
- Sql_FreeResult(sql_handle);
+ int aid, cid;
+ aid = RFIFOL(fd,2);
+ cid = RFIFOL(fd,6);
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT type, tick, val1, val2, val3, val4 from `%s` WHERE `account_id` = '%d' AND `char_id`='%d'",
+ scdata_db, aid, cid) )
+ {
+ Sql_ShowDebug(sql_handle);
+ break;
+ }
+ if( Sql_NumRows(sql_handle) > 0 )
+ {
+ struct status_change_data scdata;
+ int count;
+ char* data;
+
+ WFIFOHEAD(fd,14+50*sizeof(struct status_change_data));
+ WFIFOW(fd,0) = 0x2b1d;
+ WFIFOL(fd,4) = aid;
+ WFIFOL(fd,8) = cid;
+ for( count = 0; count < 50 && SQL_SUCCESS == Sql_NextRow(sql_handle); ++count )
+ {
+ Sql_GetData(sql_handle, 0, &data, NULL); scdata.type = atoi(data);
+ Sql_GetData(sql_handle, 1, &data, NULL); scdata.tick = atoi(data);
+ Sql_GetData(sql_handle, 2, &data, NULL); scdata.val1 = atoi(data);
+ Sql_GetData(sql_handle, 3, &data, NULL); scdata.val2 = atoi(data);
+ Sql_GetData(sql_handle, 4, &data, NULL); scdata.val3 = atoi(data);
+ Sql_GetData(sql_handle, 5, &data, NULL); scdata.val4 = atoi(data);
+ memcpy(WFIFOP(fd, 14+count*sizeof(struct status_change_data)), &scdata, sizeof(struct status_change_data));
+ }
+ if (count >= 50)
+ ShowWarning("Too many status changes for %d:%d, some of them were not loaded.\n", aid, cid);
+ if (count > 0)
+ {
+ WFIFOW(fd,2) = 14 + count*sizeof(struct status_change_data);
+ WFIFOW(fd,12) = count;
+ WFIFOSET(fd,WFIFOW(fd,2));
+
+ //Clear the data once loaded.
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `char_id`='%d'", scdata_db, aid, cid) )
+ Sql_ShowDebug(sql_handle);
+ }
+ }
+ Sql_FreeResult(sql_handle);
#endif
- RFIFOSKIP(fd, 10);
- }
- break;
-
- case 0x2afe: //set MAP user count
- if (RFIFOREST(fd) < 4)
- return 0;
- if (RFIFOW(fd,2) != server[id].users) {
- server[id].users = RFIFOW(fd,2);
- ShowInfo("User Count: %d (Server: %d)\n", server[id].users, id);
- }
- RFIFOSKIP(fd, 4);
- break;
-
- case 0x2aff: //set MAP users
- if (RFIFOREST(fd) < 6 || RFIFOREST(fd) < RFIFOW(fd,2))
- return 0;
- {
- //TODO: When data mismatches memory, update guild/party online/offline states.
- int aid, cid;
- struct online_char_data *character;
-
- server[id].users = RFIFOW(fd,4);
- online_char_db->foreach(online_char_db,char_db_setoffline,id); //Set all chars from this server as 'unknown'
- for (i = 0; i < server[id].users; i++) {
- aid = RFIFOL(fd,6+i*8);
- cid = RFIFOL(fd,6+i*8+4);
- character = idb_ensure(online_char_db, aid, create_online_char_data);
- if (character->server > -1 && character->server != id) {
- ShowNotice("Set map user: Character (%d:%d) marked on map server %d, but map server %d claims to have (%d:%d) online!\n",
- character->account_id, character->char_id, character->server, id, aid, cid);
- mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 2);
- }
- character->server = id;
- character->char_id = cid;
- }
- //If any chars remain in -2, they will be cleaned in the cleanup timer.
- RFIFOSKIP(fd,RFIFOW(fd,2));
- }
- break;
-
- case 0x2b01: // Receive character data from map-server for saving
- if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
- return 0;
- {
- int aid = RFIFOL(fd,4), cid = RFIFOL(fd,8), size = RFIFOW(fd,2);
- struct online_char_data *character;
-
- if (size - 13 != sizeof(struct mmo_charstatus)) {
- ShowError("parse_from_map (save-char): Size mismatch! %d != %d\n", size-13, sizeof(struct mmo_charstatus));
- RFIFOSKIP(fd,size);
- break;
- }
- //Check account only if this ain't final save. Final-save goes through because of the char-map reconnect
- if (RFIFOB(fd,12) || (
- (character = (struct online_char_data *)idb_get(online_char_db, aid)) != NULL &&
- character->char_id == cid)) {
- struct mmo_charstatus char_dat;
- memcpy(&char_dat, RFIFOP(fd,13), sizeof(struct mmo_charstatus));
- mmo_char_tosql(cid, &char_dat);
- } else { //This may be valid on char-server reconnection, when re-sending characters that already logged off.
- ShowError("parse_from_map (save-char): Received data for non-existant/offline character (%d:%d).\n", aid, cid);
- set_char_online(id, cid, aid);
- }
-
- if (RFIFOB(fd,12)) {
- //Flag, set character offline after saving. [Skotlex]
- set_char_offline(cid, aid);
- WFIFOHEAD(fd,10);
- WFIFOW(fd,0) = 0x2b21; //Save ack only needed on final save.
- WFIFOL(fd,2) = aid;
- WFIFOL(fd,6) = cid;
- WFIFOSET(fd,10);
- }
- RFIFOSKIP(fd,size);
- }
- break;
-
- case 0x2b02: // req char selection
- if (RFIFOREST(fd) < 18)
- return 0;
- {
- struct auth_node *node;
-
- int account_id = RFIFOL(fd,2);
- uint32 login_id1 = RFIFOL(fd,6);
- uint32 login_id2 = RFIFOL(fd,10);
- uint32 ip = RFIFOL(fd,14);
- RFIFOSKIP(fd,18);
-
- if (runflag != CHARSERVER_ST_RUNNING) {
- WFIFOHEAD(fd,7);
- WFIFOW(fd,0) = 0x2b03;
- WFIFOL(fd,2) = account_id;
- WFIFOB(fd,6) = 0;// not ok
- WFIFOSET(fd,7);
- } else {
- // create temporary auth entry
- CREATE(node, struct auth_node, 1);
- node->account_id = account_id;
- node->char_id = 0;
- node->login_id1 = login_id1;
- node->login_id2 = login_id2;
- //node->sex = 0;
- node->ip = ntohl(ip);
- //node->expiration_time = 0; // unlimited/unknown time by default (not display in map-server)
- //node->gmlevel = 0;
- idb_put(auth_db, account_id, node);
-
- //Set char to "@ char select" in online db [Kevin]
- set_char_charselect(account_id);
-
- WFIFOHEAD(fd,7);
- WFIFOW(fd,0) = 0x2b03;
- WFIFOL(fd,2) = account_id;
- WFIFOB(fd,6) = 1;// ok
- WFIFOSET(fd,7);
- }
- }
- break;
-
- case 0x2b05: // request "change map server"
- if (RFIFOREST(fd) < 39)
- return 0;
- {
- int map_id, map_fd = -1;
- struct online_char_data *data;
- struct mmo_charstatus *char_data;
- struct mmo_charstatus char_dat;
-
- map_id = search_mapserver(RFIFOW(fd,18), ntohl(RFIFOL(fd,24)), ntohs(RFIFOW(fd,28))); //Locate mapserver by ip and port.
- if (map_id >= 0)
- map_fd = server[map_id].fd;
- //Char should just had been saved before this packet, so this should be safe. [Skotlex]
- char_data = (struct mmo_charstatus *)uidb_get(char_db_,RFIFOL(fd,14));
- if (char_data == NULL) { //Really shouldn't happen.
- mmo_char_fromsql(RFIFOL(fd,14), &char_dat, true);
- char_data = (struct mmo_charstatus *)uidb_get(char_db_,RFIFOL(fd,14));
- }
-
- if (runflag == CHARSERVER_ST_RUNNING &&
- session_isActive(map_fd) &&
- char_data) {
- //Send the map server the auth of this player.
- struct auth_node *node;
-
- //Update the "last map" as this is where the player must be spawned on the new map server.
- char_data->last_point.map = RFIFOW(fd,18);
- char_data->last_point.x = RFIFOW(fd,20);
- char_data->last_point.y = RFIFOW(fd,22);
- char_data->sex = RFIFOB(fd,30);
-
- // create temporary auth entry
- CREATE(node, struct auth_node, 1);
- node->account_id = RFIFOL(fd,2);
- node->char_id = RFIFOL(fd,14);
- node->login_id1 = RFIFOL(fd,6);
- node->login_id2 = RFIFOL(fd,10);
- node->sex = RFIFOB(fd,30);
- node->expiration_time = 0; // FIXME (this thing isn't really supported we could as well purge it instead of fixing)
- node->ip = ntohl(RFIFOL(fd,31));
- node->group_id = RFIFOL(fd,35);
- node->changing_mapservers = 1;
- idb_put(auth_db, RFIFOL(fd,2), node);
-
- data = idb_ensure(online_char_db, RFIFOL(fd,2), create_online_char_data);
- data->char_id = char_data->char_id;
- data->server = map_id; //Update server where char is.
-
- //Reply with an ack.
- WFIFOHEAD(fd,30);
- WFIFOW(fd,0) = 0x2b06;
- memcpy(WFIFOP(fd,2), RFIFOP(fd,2), 28);
- WFIFOSET(fd,30);
- } else { //Reply with nak
- WFIFOHEAD(fd,30);
- WFIFOW(fd,0) = 0x2b06;
- memcpy(WFIFOP(fd,2), RFIFOP(fd,2), 28);
- WFIFOL(fd,6) = 0; //Set login1 to 0.
- WFIFOSET(fd,30);
- }
- RFIFOSKIP(fd,39);
- }
- break;
-
- case 0x2b07: // Remove RFIFOL(fd,6) (friend_id) from RFIFOL(fd,2) (char_id) friend list [Ind]
- if (RFIFOREST(fd) < 10)
- return 0;
- {
- int char_id, friend_id;
- char_id = RFIFOL(fd,2);
- friend_id = RFIFOL(fd,6);
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d' AND `friend_id`='%d' LIMIT 1",
- friend_db, char_id, friend_id)) {
- Sql_ShowDebug(sql_handle);
- break;
- }
- RFIFOSKIP(fd,10);
- }
- break;
-
- case 0x2b08: // char name request
- if (RFIFOREST(fd) < 6)
- return 0;
-
- WFIFOHEAD(fd,30);
- WFIFOW(fd,0) = 0x2b09;
- WFIFOL(fd,2) = RFIFOL(fd,2);
- char_loadName((int)RFIFOL(fd,2), (char *)WFIFOP(fd,6));
- WFIFOSET(fd,30);
-
- RFIFOSKIP(fd,6);
- break;
-
- case 0x2b0c: // Map server send information to change an email of an account -> login-server
- if (RFIFOREST(fd) < 86)
- return 0;
- if (login_fd > 0) { // don't send request if no login-server
- WFIFOHEAD(login_fd,86);
- 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;
-
- case 0x2b0e: // Request from map-server to change an account's status (will just be forwarded to login server)
- if (RFIFOREST(fd) < 44)
- return 0;
- {
- int result = 0; // 0-login-server request done, 1-player not found, 2-gm level too low, 3-login-server offline
- char esc_name[NAME_LENGTH*2+1];
-
- int acc = RFIFOL(fd,2); // account_id of who ask (-1 if server itself made this request)
- const char *name = (char *)RFIFOP(fd,6); // name of the target character
- int type = RFIFOW(fd,30); // type of operation: 1-block, 2-ban, 3-unblock, 4-unban
- short year = RFIFOW(fd,32);
- short month = RFIFOW(fd,34);
- short day = RFIFOW(fd,36);
- short hour = RFIFOW(fd,38);
- short minute = RFIFOW(fd,40);
- short second = RFIFOW(fd,42);
- RFIFOSKIP(fd,44);
-
- Sql_EscapeStringLen(sql_handle, esc_name, name, strnlen(name, NAME_LENGTH));
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`name` FROM `%s` WHERE `name` = '%s'", char_db, esc_name))
- Sql_ShowDebug(sql_handle);
- else if (Sql_NumRows(sql_handle) == 0) {
- result = 1; // 1-player not found
- } else if (SQL_SUCCESS != Sql_NextRow(sql_handle))
- Sql_ShowDebug(sql_handle);
- //FIXME: set proper result value?
- else {
- char name[NAME_LENGTH];
- int account_id;
- char *data;
-
- Sql_GetData(sql_handle, 0, &data, NULL);
- account_id = atoi(data);
- Sql_GetData(sql_handle, 1, &data, NULL);
- safestrncpy(name, data, sizeof(name));
-
- if (login_fd <= 0)
- result = 3; // 3-login-server offline
- //FIXME: need to move this check to login server [ultramage]
- // else
- // if( acc != -1 && isGM(acc) < isGM(account_id) )
- // result = 2; // 2-gm level too low
- else
- switch (type) {
- case 1: // block
- WFIFOHEAD(login_fd,10);
- WFIFOW(login_fd,0) = 0x2724;
- WFIFOL(login_fd,2) = account_id;
- WFIFOL(login_fd,6) = 5; // new account status
- WFIFOSET(login_fd,10);
- break;
- case 2: // ban
- WFIFOHEAD(login_fd,18);
- WFIFOW(login_fd, 0) = 0x2725;
- WFIFOL(login_fd, 2) = account_id;
- WFIFOW(login_fd, 6) = year;
- WFIFOW(login_fd, 8) = month;
- WFIFOW(login_fd,10) = day;
- WFIFOW(login_fd,12) = hour;
- WFIFOW(login_fd,14) = minute;
- WFIFOW(login_fd,16) = second;
- WFIFOSET(login_fd,18);
- break;
- case 3: // unblock
- WFIFOHEAD(login_fd,10);
- WFIFOW(login_fd,0) = 0x2724;
- WFIFOL(login_fd,2) = account_id;
- WFIFOL(login_fd,6) = 0; // new account status
- WFIFOSET(login_fd,10);
- break;
- case 4: // unban
- WFIFOHEAD(login_fd,6);
- WFIFOW(login_fd,0) = 0x272a;
- WFIFOL(login_fd,2) = account_id;
- WFIFOSET(login_fd,6);
- break;
- case 5: // changesex
- WFIFOHEAD(login_fd,6);
- WFIFOW(login_fd,0) = 0x2727;
- WFIFOL(login_fd,2) = account_id;
- WFIFOSET(login_fd,6);
- break;
- }
- }
-
- Sql_FreeResult(sql_handle);
-
- // send answer if a player ask, not if the server ask
- if (acc != -1 && type != 5) { // Don't send answer for changesex
- WFIFOHEAD(fd,34);
- WFIFOW(fd, 0) = 0x2b0f;
- WFIFOL(fd, 2) = acc;
- safestrncpy((char *)WFIFOP(fd,6), name, NAME_LENGTH);
- WFIFOW(fd,30) = type;
- WFIFOW(fd,32) = result;
- WFIFOSET(fd,34);
- }
- }
- break;
-
- case 0x2b10: // Update and send fame ranking list
- if (RFIFOREST(fd) < 11)
- return 0;
- {
- int cid = RFIFOL(fd, 2);
- int fame = RFIFOL(fd, 6);
- char type = RFIFOB(fd, 10);
- int size;
- struct fame_list *list;
- int player_pos;
- int fame_pos;
-
- switch (type) {
- case 1:
- size = fame_list_size_smith;
- list = smith_fame_list;
- break;
- case 2:
- size = fame_list_size_chemist;
- list = chemist_fame_list;
- break;
- case 3:
- size = fame_list_size_taekwon;
- list = taekwon_fame_list;
- break;
- default:
- size = 0;
- list = NULL;
- break;
- }
-
- ARR_FIND(0, size, player_pos, list[player_pos].id == cid);// position of the player
- ARR_FIND(0, size, fame_pos, list[fame_pos].fame <= fame);// where the player should be
-
- if (player_pos == size && fame_pos == size)
- ;// not on list and not enough fame to get on it
- else if (fame_pos == player_pos) {
- // same position
- list[player_pos].fame = fame;
- char_update_fame_list(type, player_pos, fame);
- } else {
- // move in the list
- if (player_pos == size) {
- // new ranker - not in the list
- ARR_MOVE(size - 1, fame_pos, list, struct fame_list);
- list[fame_pos].id = cid;
- list[fame_pos].fame = fame;
- char_loadName(cid, list[fame_pos].name);
- } else {
- // already in the list
- if (fame_pos == size)
- --fame_pos;// move to the end of the list
- ARR_MOVE(player_pos, fame_pos, list, struct fame_list);
- list[fame_pos].fame = fame;
- }
- char_send_fame_list(-1);
- }
-
- RFIFOSKIP(fd,11);
- }
- break;
-
- // Divorce chars
- case 0x2b11:
- if (RFIFOREST(fd) < 10)
- return 0;
-
- divorce_char_sql(RFIFOL(fd,2), RFIFOL(fd,6));
- RFIFOSKIP(fd,10);
- break;
-
- case 0x2b16: // Receive rates [Wizputer]
- if (RFIFOREST(fd) < 14)
- return 0;
- {
- char esc_server_name[sizeof(server_name)*2+1];
-
- Sql_EscapeString(sql_handle, esc_server_name, server_name);
-
- if (SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` SET `index`='%d',`name`='%s',`exp`='%d',`jexp`='%d',`drop`='%d'",
- ragsrvinfo_db, fd, esc_server_name, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10)))
- Sql_ShowDebug(sql_handle);
- RFIFOSKIP(fd,14);
- }
- break;
-
- case 0x2b17: // Character disconnected set online 0 [Wizputer]
- if (RFIFOREST(fd) < 6)
- return 0;
- set_char_offline(RFIFOL(fd,2),RFIFOL(fd,6));
- RFIFOSKIP(fd,10);
- break;
-
- case 0x2b18: // Reset all chars to offline [Wizputer]
- set_all_offline(id);
- RFIFOSKIP(fd,2);
- break;
-
- case 0x2b19: // Character set online [Wizputer]
- if (RFIFOREST(fd) < 10)
- return 0;
- set_char_online(id, RFIFOL(fd,2),RFIFOL(fd,6));
- RFIFOSKIP(fd,10);
- break;
-
- case 0x2b1a: // Build and send fame ranking lists [DracoRPG]
- if (RFIFOREST(fd) < 2)
- return 0;
- char_read_fame_list();
- char_send_fame_list(-1);
- RFIFOSKIP(fd,2);
- break;
-
- case 0x2b1c: //Request to save status change data. [Skotlex]
- if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
- return 0;
- {
+ RFIFOSKIP(fd, 10);
+ }
+ break;
+
+ case 0x2afe: //set MAP user count
+ if (RFIFOREST(fd) < 4)
+ return 0;
+ if (RFIFOW(fd,2) != server[id].users) {
+ server[id].users = RFIFOW(fd,2);
+ ShowInfo("User Count: %d (Server: %d)\n", server[id].users, id);
+ }
+ RFIFOSKIP(fd, 4);
+ break;
+
+ case 0x2aff: //set MAP users
+ if (RFIFOREST(fd) < 6 || RFIFOREST(fd) < RFIFOW(fd,2))
+ return 0;
+ {
+ //TODO: When data mismatches memory, update guild/party online/offline states.
+ int aid, cid;
+ struct online_char_data* character;
+
+ server[id].users = RFIFOW(fd,4);
+ online_char_db->foreach(online_char_db,char_db_setoffline,id); //Set all chars from this server as 'unknown'
+ for(i = 0; i < server[id].users; i++) {
+ aid = RFIFOL(fd,6+i*8);
+ cid = RFIFOL(fd,6+i*8+4);
+ character = idb_ensure(online_char_db, aid, create_online_char_data);
+ if( character->server > -1 && character->server != id )
+ {
+ ShowNotice("Set map user: Character (%d:%d) marked on map server %d, but map server %d claims to have (%d:%d) online!\n",
+ character->account_id, character->char_id, character->server, id, aid, cid);
+ mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 2);
+ }
+ character->server = id;
+ character->char_id = cid;
+ }
+ //If any chars remain in -2, they will be cleaned in the cleanup timer.
+ RFIFOSKIP(fd,RFIFOW(fd,2));
+ }
+ break;
+
+ case 0x2b01: // Receive character data from map-server for saving
+ if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
+ return 0;
+ {
+ int aid = RFIFOL(fd,4), cid = RFIFOL(fd,8), size = RFIFOW(fd,2);
+ struct online_char_data* character;
+
+ if (size - 13 != sizeof(struct mmo_charstatus))
+ {
+ ShowError("parse_from_map (save-char): Size mismatch! %d != %d\n", size-13, sizeof(struct mmo_charstatus));
+ RFIFOSKIP(fd,size);
+ break;
+ }
+ //Check account only if this ain't final save. Final-save goes through because of the char-map reconnect
+ if (RFIFOB(fd,12) || (
+ (character = (struct online_char_data*)idb_get(online_char_db, aid)) != NULL &&
+ character->char_id == cid))
+ {
+ struct mmo_charstatus char_dat;
+ memcpy(&char_dat, RFIFOP(fd,13), sizeof(struct mmo_charstatus));
+ mmo_char_tosql(cid, &char_dat);
+ } else { //This may be valid on char-server reconnection, when re-sending characters that already logged off.
+ ShowError("parse_from_map (save-char): Received data for non-existant/offline character (%d:%d).\n", aid, cid);
+ set_char_online(id, cid, aid);
+ }
+
+ if (RFIFOB(fd,12))
+ { //Flag, set character offline after saving. [Skotlex]
+ set_char_offline(cid, aid);
+ WFIFOHEAD(fd,10);
+ WFIFOW(fd,0) = 0x2b21; //Save ack only needed on final save.
+ WFIFOL(fd,2) = aid;
+ WFIFOL(fd,6) = cid;
+ WFIFOSET(fd,10);
+ }
+ RFIFOSKIP(fd,size);
+ }
+ break;
+
+ case 0x2b02: // req char selection
+ if( RFIFOREST(fd) < 18 )
+ return 0;
+ {
+ struct auth_node* node;
+
+ int account_id = RFIFOL(fd,2);
+ uint32 login_id1 = RFIFOL(fd,6);
+ uint32 login_id2 = RFIFOL(fd,10);
+ uint32 ip = RFIFOL(fd,14);
+ RFIFOSKIP(fd,18);
+
+ if( runflag != CHARSERVER_ST_RUNNING )
+ {
+ WFIFOHEAD(fd,7);
+ WFIFOW(fd,0) = 0x2b03;
+ WFIFOL(fd,2) = account_id;
+ WFIFOB(fd,6) = 0;// not ok
+ WFIFOSET(fd,7);
+ }
+ else
+ {
+ // create temporary auth entry
+ CREATE(node, struct auth_node, 1);
+ node->account_id = account_id;
+ node->char_id = 0;
+ node->login_id1 = login_id1;
+ node->login_id2 = login_id2;
+ //node->sex = 0;
+ node->ip = ntohl(ip);
+ //node->expiration_time = 0; // unlimited/unknown time by default (not display in map-server)
+ //node->gmlevel = 0;
+ idb_put(auth_db, account_id, node);
+
+ //Set char to "@ char select" in online db [Kevin]
+ set_char_charselect(account_id);
+
+ WFIFOHEAD(fd,7);
+ WFIFOW(fd,0) = 0x2b03;
+ WFIFOL(fd,2) = account_id;
+ WFIFOB(fd,6) = 1;// ok
+ WFIFOSET(fd,7);
+ }
+ }
+ break;
+
+ case 0x2b05: // request "change map server"
+ if (RFIFOREST(fd) < 39)
+ return 0;
+ {
+ int map_id, map_fd = -1;
+ struct online_char_data* data;
+ struct mmo_charstatus* char_data;
+ struct mmo_charstatus char_dat;
+
+ map_id = search_mapserver(RFIFOW(fd,18), ntohl(RFIFOL(fd,24)), ntohs(RFIFOW(fd,28))); //Locate mapserver by ip and port.
+ if (map_id >= 0)
+ map_fd = server[map_id].fd;
+ //Char should just had been saved before this packet, so this should be safe. [Skotlex]
+ char_data = (struct mmo_charstatus*)uidb_get(char_db_,RFIFOL(fd,14));
+ if (char_data == NULL) { //Really shouldn't happen.
+ mmo_char_fromsql(RFIFOL(fd,14), &char_dat, true);
+ char_data = (struct mmo_charstatus*)uidb_get(char_db_,RFIFOL(fd,14));
+ }
+
+ if( runflag == CHARSERVER_ST_RUNNING &&
+ session_isActive(map_fd) &&
+ char_data )
+ { //Send the map server the auth of this player.
+ struct auth_node* node;
+
+ //Update the "last map" as this is where the player must be spawned on the new map server.
+ char_data->last_point.map = RFIFOW(fd,18);
+ char_data->last_point.x = RFIFOW(fd,20);
+ char_data->last_point.y = RFIFOW(fd,22);
+ char_data->sex = RFIFOB(fd,30);
+
+ // create temporary auth entry
+ CREATE(node, struct auth_node, 1);
+ node->account_id = RFIFOL(fd,2);
+ node->char_id = RFIFOL(fd,14);
+ node->login_id1 = RFIFOL(fd,6);
+ node->login_id2 = RFIFOL(fd,10);
+ node->sex = RFIFOB(fd,30);
+ node->expiration_time = 0; // FIXME (this thing isn't really supported we could as well purge it instead of fixing)
+ node->ip = ntohl(RFIFOL(fd,31));
+ node->group_id = RFIFOL(fd,35);
+ node->changing_mapservers = 1;
+ idb_put(auth_db, RFIFOL(fd,2), node);
+
+ data = idb_ensure(online_char_db, RFIFOL(fd,2), create_online_char_data);
+ data->char_id = char_data->char_id;
+ data->server = map_id; //Update server where char is.
+
+ //Reply with an ack.
+ WFIFOHEAD(fd,30);
+ WFIFOW(fd,0) = 0x2b06;
+ memcpy(WFIFOP(fd,2), RFIFOP(fd,2), 28);
+ WFIFOSET(fd,30);
+ } else { //Reply with nak
+ WFIFOHEAD(fd,30);
+ WFIFOW(fd,0) = 0x2b06;
+ memcpy(WFIFOP(fd,2), RFIFOP(fd,2), 28);
+ WFIFOL(fd,6) = 0; //Set login1 to 0.
+ WFIFOSET(fd,30);
+ }
+ RFIFOSKIP(fd,39);
+ }
+ break;
+
+ case 0x2b07: // Remove RFIFOL(fd,6) (friend_id) from RFIFOL(fd,2) (char_id) friend list [Ind]
+ if (RFIFOREST(fd) < 10)
+ return 0;
+ {
+ int char_id, friend_id;
+ char_id = RFIFOL(fd,2);
+ friend_id = RFIFOL(fd,6);
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d' AND `friend_id`='%d' LIMIT 1",
+ friend_db, char_id, friend_id) ) {
+ Sql_ShowDebug(sql_handle);
+ break;
+ }
+ RFIFOSKIP(fd,10);
+ }
+ break;
+
+ case 0x2b08: // char name request
+ if (RFIFOREST(fd) < 6)
+ return 0;
+
+ WFIFOHEAD(fd,30);
+ WFIFOW(fd,0) = 0x2b09;
+ WFIFOL(fd,2) = RFIFOL(fd,2);
+ char_loadName((int)RFIFOL(fd,2), (char*)WFIFOP(fd,6));
+ WFIFOSET(fd,30);
+
+ RFIFOSKIP(fd,6);
+ break;
+
+ case 0x2b0c: // Map server send information to change an email of an account -> login-server
+ if (RFIFOREST(fd) < 86)
+ return 0;
+ if (login_fd > 0) { // don't send request if no login-server
+ WFIFOHEAD(login_fd,86);
+ 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;
+
+ case 0x2b0e: // Request from map-server to change an account's status (will just be forwarded to login server)
+ if (RFIFOREST(fd) < 44)
+ return 0;
+ {
+ int result = 0; // 0-login-server request done, 1-player not found, 2-gm level too low, 3-login-server offline
+ char esc_name[NAME_LENGTH*2+1];
+
+ int acc = RFIFOL(fd,2); // account_id of who ask (-1 if server itself made this request)
+ const char* name = (char*)RFIFOP(fd,6); // name of the target character
+ int type = RFIFOW(fd,30); // type of operation: 1-block, 2-ban, 3-unblock, 4-unban
+ short year = RFIFOW(fd,32);
+ short month = RFIFOW(fd,34);
+ short day = RFIFOW(fd,36);
+ short hour = RFIFOW(fd,38);
+ short minute = RFIFOW(fd,40);
+ short second = RFIFOW(fd,42);
+ RFIFOSKIP(fd,44);
+
+ Sql_EscapeStringLen(sql_handle, esc_name, name, strnlen(name, NAME_LENGTH));
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`name` FROM `%s` WHERE `name` = '%s'", char_db, esc_name) )
+ Sql_ShowDebug(sql_handle);
+ else
+ if( Sql_NumRows(sql_handle) == 0 )
+ {
+ result = 1; // 1-player not found
+ }
+ else
+ if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
+ Sql_ShowDebug(sql_handle);
+ //FIXME: set proper result value?
+ else
+ {
+ char name[NAME_LENGTH];
+ int account_id;
+ char* data;
+
+ Sql_GetData(sql_handle, 0, &data, NULL); account_id = atoi(data);
+ Sql_GetData(sql_handle, 1, &data, NULL); safestrncpy(name, data, sizeof(name));
+
+ if( login_fd <= 0 )
+ result = 3; // 3-login-server offline
+ //FIXME: need to move this check to login server [ultramage]
+// else
+// if( acc != -1 && isGM(acc) < isGM(account_id) )
+// result = 2; // 2-gm level too low
+ else
+ switch( type ) {
+ case 1: // block
+ WFIFOHEAD(login_fd,10);
+ WFIFOW(login_fd,0) = 0x2724;
+ WFIFOL(login_fd,2) = account_id;
+ WFIFOL(login_fd,6) = 5; // new account status
+ WFIFOSET(login_fd,10);
+ break;
+ case 2: // ban
+ WFIFOHEAD(login_fd,18);
+ WFIFOW(login_fd, 0) = 0x2725;
+ WFIFOL(login_fd, 2) = account_id;
+ WFIFOW(login_fd, 6) = year;
+ WFIFOW(login_fd, 8) = month;
+ WFIFOW(login_fd,10) = day;
+ WFIFOW(login_fd,12) = hour;
+ WFIFOW(login_fd,14) = minute;
+ WFIFOW(login_fd,16) = second;
+ WFIFOSET(login_fd,18);
+ break;
+ case 3: // unblock
+ WFIFOHEAD(login_fd,10);
+ WFIFOW(login_fd,0) = 0x2724;
+ WFIFOL(login_fd,2) = account_id;
+ WFIFOL(login_fd,6) = 0; // new account status
+ WFIFOSET(login_fd,10);
+ break;
+ case 4: // unban
+ WFIFOHEAD(login_fd,6);
+ WFIFOW(login_fd,0) = 0x272a;
+ WFIFOL(login_fd,2) = account_id;
+ WFIFOSET(login_fd,6);
+ break;
+ case 5: // changesex
+ WFIFOHEAD(login_fd,6);
+ WFIFOW(login_fd,0) = 0x2727;
+ WFIFOL(login_fd,2) = account_id;
+ WFIFOSET(login_fd,6);
+ break;
+ }
+ }
+
+ Sql_FreeResult(sql_handle);
+
+ // send answer if a player ask, not if the server ask
+ if( acc != -1 && type != 5) { // Don't send answer for changesex
+ WFIFOHEAD(fd,34);
+ WFIFOW(fd, 0) = 0x2b0f;
+ WFIFOL(fd, 2) = acc;
+ safestrncpy((char*)WFIFOP(fd,6), name, NAME_LENGTH);
+ WFIFOW(fd,30) = type;
+ WFIFOW(fd,32) = result;
+ WFIFOSET(fd,34);
+ }
+ }
+ break;
+
+ case 0x2b10: // Update and send fame ranking list
+ if (RFIFOREST(fd) < 11)
+ return 0;
+ {
+ int cid = RFIFOL(fd, 2);
+ int fame = RFIFOL(fd, 6);
+ char type = RFIFOB(fd, 10);
+ int size;
+ struct fame_list* list;
+ int player_pos;
+ int fame_pos;
+
+ switch(type)
+ {
+ case 1: size = fame_list_size_smith; list = smith_fame_list; break;
+ case 2: size = fame_list_size_chemist; list = chemist_fame_list; break;
+ case 3: size = fame_list_size_taekwon; list = taekwon_fame_list; break;
+ default: size = 0; list = NULL; break;
+ }
+
+ ARR_FIND(0, size, player_pos, list[player_pos].id == cid);// position of the player
+ ARR_FIND(0, size, fame_pos, list[fame_pos].fame <= fame);// where the player should be
+
+ if( player_pos == size && fame_pos == size )
+ ;// not on list and not enough fame to get on it
+ else if( fame_pos == player_pos )
+ {// same position
+ list[player_pos].fame = fame;
+ char_update_fame_list(type, player_pos, fame);
+ }
+ else
+ {// move in the list
+ if( player_pos == size )
+ {// new ranker - not in the list
+ ARR_MOVE(size - 1, fame_pos, list, struct fame_list);
+ list[fame_pos].id = cid;
+ list[fame_pos].fame = fame;
+ char_loadName(cid, list[fame_pos].name);
+ }
+ else
+ {// already in the list
+ if( fame_pos == size )
+ --fame_pos;// move to the end of the list
+ ARR_MOVE(player_pos, fame_pos, list, struct fame_list);
+ list[fame_pos].fame = fame;
+ }
+ char_send_fame_list(-1);
+ }
+
+ RFIFOSKIP(fd,11);
+ }
+ break;
+
+ // Divorce chars
+ case 0x2b11:
+ if( RFIFOREST(fd) < 10 )
+ return 0;
+
+ divorce_char_sql(RFIFOL(fd,2), RFIFOL(fd,6));
+ RFIFOSKIP(fd,10);
+ break;
+
+ case 0x2b16: // Receive rates [Wizputer]
+ if( RFIFOREST(fd) < 14 )
+ return 0;
+ {
+ char esc_server_name[sizeof(server_name)*2+1];
+
+ Sql_EscapeString(sql_handle, esc_server_name, server_name);
+
+ if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` SET `index`='%d',`name`='%s',`exp`='%d',`jexp`='%d',`drop`='%d'",
+ ragsrvinfo_db, fd, esc_server_name, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10)) )
+ Sql_ShowDebug(sql_handle);
+ RFIFOSKIP(fd,14);
+ }
+ break;
+
+ case 0x2b17: // Character disconnected set online 0 [Wizputer]
+ if (RFIFOREST(fd) < 6)
+ return 0;
+ set_char_offline(RFIFOL(fd,2),RFIFOL(fd,6));
+ RFIFOSKIP(fd,10);
+ break;
+
+ case 0x2b18: // Reset all chars to offline [Wizputer]
+ set_all_offline(id);
+ RFIFOSKIP(fd,2);
+ break;
+
+ case 0x2b19: // Character set online [Wizputer]
+ if (RFIFOREST(fd) < 10)
+ return 0;
+ set_char_online(id, RFIFOL(fd,2),RFIFOL(fd,6));
+ RFIFOSKIP(fd,10);
+ break;
+
+ case 0x2b1a: // Build and send fame ranking lists [DracoRPG]
+ if (RFIFOREST(fd) < 2)
+ return 0;
+ char_read_fame_list();
+ char_send_fame_list(-1);
+ RFIFOSKIP(fd,2);
+ break;
+
+ case 0x2b1c: //Request to save status change data. [Skotlex]
+ if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
+ return 0;
+ {
#ifdef ENABLE_SC_SAVING
- int count, aid, cid;
-
- aid = RFIFOL(fd, 4);
- cid = RFIFOL(fd, 8);
- count = RFIFOW(fd, 12);
-
- if (count > 0) {
- struct status_change_data data;
- StringBuf buf;
- int i;
-
- StringBuf_Init(&buf);
- StringBuf_Printf(&buf, "INSERT INTO `%s` (`account_id`, `char_id`, `type`, `tick`, `val1`, `val2`, `val3`, `val4`) VALUES ", scdata_db);
- for (i = 0; i < count; ++i) {
- memcpy(&data, RFIFOP(fd, 14+i*sizeof(struct status_change_data)), sizeof(struct status_change_data));
- if (i > 0)
- StringBuf_AppendStr(&buf, ", ");
- StringBuf_Printf(&buf, "('%d','%d','%hu','%d','%d','%d','%d','%d')", aid, cid,
- data.type, data.tick, data.val1, data.val2, data.val3, data.val4);
- }
- if (SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)))
- Sql_ShowDebug(sql_handle);
- StringBuf_Destroy(&buf);
- }
+ int count, aid, cid;
+
+ aid = RFIFOL(fd, 4);
+ cid = RFIFOL(fd, 8);
+ count = RFIFOW(fd, 12);
+
+ if( count > 0 )
+ {
+ struct status_change_data data;
+ StringBuf buf;
+ int i;
+
+ StringBuf_Init(&buf);
+ StringBuf_Printf(&buf, "INSERT INTO `%s` (`account_id`, `char_id`, `type`, `tick`, `val1`, `val2`, `val3`, `val4`) VALUES ", scdata_db);
+ for( i = 0; i < count; ++i )
+ {
+ memcpy (&data, RFIFOP(fd, 14+i*sizeof(struct status_change_data)), sizeof(struct status_change_data));
+ if( i > 0 )
+ StringBuf_AppendStr(&buf, ", ");
+ StringBuf_Printf(&buf, "('%d','%d','%hu','%d','%d','%d','%d','%d')", aid, cid,
+ data.type, data.tick, data.val1, data.val2, data.val3, data.val4);
+ }
+ if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) )
+ Sql_ShowDebug(sql_handle);
+ StringBuf_Destroy(&buf);
+ }
#endif
- RFIFOSKIP(fd, RFIFOW(fd, 2));
- }
- break;
-
- case 0x2b23: // map-server alive packet
- WFIFOHEAD(fd,2);
- WFIFOW(fd,0) = 0x2b24;
- WFIFOSET(fd,2);
- RFIFOSKIP(fd,2);
- break;
-
- case 0x2b26: // auth request from map-server
- if (RFIFOREST(fd) < 19)
- return 0;
-
- {
- int account_id;
- int char_id;
- int login_id1;
- char sex;
- uint32 ip;
- struct auth_node *node;
- struct mmo_charstatus *cd;
- struct mmo_charstatus char_dat;
-
- account_id = RFIFOL(fd,2);
- char_id = RFIFOL(fd,6);
- login_id1 = RFIFOL(fd,10);
- sex = RFIFOB(fd,14);
- ip = ntohl(RFIFOL(fd,15));
- RFIFOSKIP(fd,19);
-
- node = (struct auth_node *)idb_get(auth_db, account_id);
- cd = (struct mmo_charstatus *)uidb_get(char_db_,char_id);
- if (cd == NULL) {
- //Really shouldn't happen.
- mmo_char_fromsql(char_id, &char_dat, true);
- cd = (struct mmo_charstatus *)uidb_get(char_db_,char_id);
- }
- if (runflag == CHARSERVER_ST_RUNNING &&
- cd != NULL &&
- node != NULL &&
- node->account_id == account_id &&
- node->char_id == char_id &&
- node->login_id1 == login_id1 &&
- node->sex == sex /*&&
- node->ip == ip*/) {
- // auth ok
- cd->sex = sex;
-
- WFIFOHEAD(fd,25 + sizeof(struct mmo_charstatus));
- WFIFOW(fd,0) = 0x2afd;
- WFIFOW(fd,2) = 25 + sizeof(struct mmo_charstatus);
- WFIFOL(fd,4) = account_id;
- WFIFOL(fd,8) = node->login_id1;
- WFIFOL(fd,12) = node->login_id2;
- WFIFOL(fd,16) = (uint32)node->expiration_time; // FIXME: will wrap to negative after "19-Jan-2038, 03:14:07 AM GMT"
- WFIFOL(fd,20) = node->group_id;
- WFIFOB(fd,24) = node->changing_mapservers;
- memcpy(WFIFOP(fd,25), cd, sizeof(struct mmo_charstatus));
- WFIFOSET(fd, WFIFOW(fd,2));
-
- // only use the auth once and mark user online
- idb_remove(auth_db, account_id);
- set_char_online(id, char_id, account_id);
- } else {
- // auth failed
- WFIFOHEAD(fd,19);
- WFIFOW(fd,0) = 0x2b27;
- WFIFOL(fd,2) = account_id;
- WFIFOL(fd,6) = char_id;
- WFIFOL(fd,10) = login_id1;
- WFIFOB(fd,14) = sex;
- WFIFOL(fd,15) = htonl(ip);
- WFIFOSET(fd,19);
- }
- }
- break;
-
- case 0x2736: // ip address update
- if (RFIFOREST(fd) < 6) return 0;
- server[id].ip = ntohl(RFIFOL(fd, 2));
- ShowInfo("Updated IP address of map-server #%d to %d.%d.%d.%d.\n", id, CONVIP(server[id].ip));
- RFIFOSKIP(fd,6);
- break;
-
- case 0x3008:
- if (RFIFOREST(fd) < RFIFOW(fd,4))
- return 0;/* packet wasn't fully received yet (still fragmented) */
- else {
- int sfd;/* stat server fd */
- RFIFOSKIP(fd, 2);/* we skip first 2 bytes which are the 0x3008, so we end up with a buffer equal to the one we send */
-
- if ((sfd = make_connection(host2ip("stats.rathena.org"),(uint16)25421,true)) == -1) {
- RFIFOSKIP(fd, RFIFOW(fd,2)); /* skip this packet */
- break;/* connection not possible, we drop the report */
- }
-
- session[sfd]->flag.server = 1;/* to ensure we won't drop our own packet */
-
- WFIFOHEAD(sfd, RFIFOW(fd,2));
-
- memcpy((char *)WFIFOP(sfd,0), (char *)RFIFOP(fd, 0), RFIFOW(fd,2));
-
- WFIFOSET(sfd, RFIFOW(fd,2));
-
- flush_fifo(sfd);
-
- do_close(sfd);
-
- RFIFOSKIP(fd, RFIFOW(fd,2)); /* skip this packet */
- }
- break;
-
-
- default: {
- // inter server - packet
- int r = inter_parse_frommap(fd);
- if (r == 1) break; // processed
- if (r == 2) return 0; // need more packet
-
- // no inter server packet. no char server packet -> disconnect
- ShowError("Unknown packet 0x%04x from map server, disconnecting.\n", RFIFOW(fd,0));
- set_eof(fd);
- return 0;
- }
- } // switch
- } // while
-
- return 0;
+ RFIFOSKIP(fd, RFIFOW(fd, 2));
+ }
+ break;
+
+ case 0x2b23: // map-server alive packet
+ WFIFOHEAD(fd,2);
+ WFIFOW(fd,0) = 0x2b24;
+ WFIFOSET(fd,2);
+ RFIFOSKIP(fd,2);
+ break;
+
+ case 0x2b26: // auth request from map-server
+ if (RFIFOREST(fd) < 19)
+ return 0;
+
+ {
+ int account_id;
+ int char_id;
+ int login_id1;
+ char sex;
+ uint32 ip;
+ struct auth_node* node;
+ struct mmo_charstatus* cd;
+ struct mmo_charstatus char_dat;
+
+ account_id = RFIFOL(fd,2);
+ char_id = RFIFOL(fd,6);
+ login_id1 = RFIFOL(fd,10);
+ sex = RFIFOB(fd,14);
+ ip = ntohl(RFIFOL(fd,15));
+ RFIFOSKIP(fd,19);
+
+ node = (struct auth_node*)idb_get(auth_db, account_id);
+ cd = (struct mmo_charstatus*)uidb_get(char_db_,char_id);
+ if( cd == NULL )
+ { //Really shouldn't happen.
+ mmo_char_fromsql(char_id, &char_dat, true);
+ cd = (struct mmo_charstatus*)uidb_get(char_db_,char_id);
+ }
+ if( runflag == CHARSERVER_ST_RUNNING &&
+ cd != NULL &&
+ node != NULL &&
+ node->account_id == account_id &&
+ node->char_id == char_id &&
+ node->login_id1 == login_id1 &&
+ node->sex == sex /*&&
+ node->ip == ip*/ )
+ {// auth ok
+ cd->sex = sex;
+
+ WFIFOHEAD(fd,25 + sizeof(struct mmo_charstatus));
+ WFIFOW(fd,0) = 0x2afd;
+ WFIFOW(fd,2) = 25 + sizeof(struct mmo_charstatus);
+ WFIFOL(fd,4) = account_id;
+ WFIFOL(fd,8) = node->login_id1;
+ WFIFOL(fd,12) = node->login_id2;
+ WFIFOL(fd,16) = (uint32)node->expiration_time; // FIXME: will wrap to negative after "19-Jan-2038, 03:14:07 AM GMT"
+ WFIFOL(fd,20) = node->group_id;
+ WFIFOB(fd,24) = node->changing_mapservers;
+ memcpy(WFIFOP(fd,25), cd, sizeof(struct mmo_charstatus));
+ WFIFOSET(fd, WFIFOW(fd,2));
+
+ // only use the auth once and mark user online
+ idb_remove(auth_db, account_id);
+ set_char_online(id, char_id, account_id);
+ }
+ else
+ {// auth failed
+ WFIFOHEAD(fd,19);
+ WFIFOW(fd,0) = 0x2b27;
+ WFIFOL(fd,2) = account_id;
+ WFIFOL(fd,6) = char_id;
+ WFIFOL(fd,10) = login_id1;
+ WFIFOB(fd,14) = sex;
+ WFIFOL(fd,15) = htonl(ip);
+ WFIFOSET(fd,19);
+ }
+ }
+ break;
+
+ case 0x2736: // ip address update
+ if (RFIFOREST(fd) < 6) return 0;
+ server[id].ip = ntohl(RFIFOL(fd, 2));
+ ShowInfo("Updated IP address of map-server #%d to %d.%d.%d.%d.\n", id, CONVIP(server[id].ip));
+ RFIFOSKIP(fd,6);
+ break;
+
+ case 0x3008:
+ if( RFIFOREST(fd) < RFIFOW(fd,4) )
+ return 0;/* packet wasn't fully received yet (still fragmented) */
+ else {
+ int sfd;/* stat server fd */
+ RFIFOSKIP(fd, 2);/* we skip first 2 bytes which are the 0x3008, so we end up with a buffer equal to the one we send */
+
+ if( (sfd = make_connection(host2ip("stats.rathena.org"),(uint16)25421,true) ) == -1 ) {
+ RFIFOSKIP(fd, RFIFOW(fd,2) );/* skip this packet */
+ break;/* connection not possible, we drop the report */
+ }
+
+ session[sfd]->flag.server = 1;/* to ensure we won't drop our own packet */
+
+ WFIFOHEAD(sfd, RFIFOW(fd,2) );
+
+ memcpy((char*)WFIFOP(sfd,0), (char*)RFIFOP(fd, 0), RFIFOW(fd,2));
+
+ WFIFOSET(sfd, RFIFOW(fd,2) );
+
+ flush_fifo(sfd);
+
+ do_close(sfd);
+
+ RFIFOSKIP(fd, RFIFOW(fd,2) );/* skip this packet */
+ }
+ break;
+
+
+ default:
+ {
+ // inter server - packet
+ int r = inter_parse_frommap(fd);
+ if (r == 1) break; // processed
+ if (r == 2) return 0; // need more packet
+
+ // no inter server packet. no char server packet -> disconnect
+ ShowError("Unknown packet 0x%04x from map server, disconnecting.\n", RFIFOW(fd,0));
+ set_eof(fd);
+ return 0;
+ }
+ } // switch
+ } // while
+
+ return 0;
}
void do_init_mapif(void)
{
- int i;
- for (i = 0; i < ARRAYLENGTH(server); ++i)
- mapif_server_init(i);
+ int i;
+ for( i = 0; i < ARRAYLENGTH(server); ++i )
+ mapif_server_init(i);
}
void do_final_mapif(void)
{
- int i;
- for (i = 0; i < ARRAYLENGTH(server); ++i)
- mapif_server_destroy(i);
+ int i;
+ for( i = 0; i < ARRAYLENGTH(server); ++i )
+ mapif_server_destroy(i);
}
// Searches for the mapserver that has a given map (and optionally ip/port, if not -1).
// If found, returns the server's index in the 'server' array (otherwise returns -1).
int search_mapserver(unsigned short map, uint32 ip, uint16 port)
{
- int i, j;
-
- for (i = 0; i < ARRAYLENGTH(server); i++) {
- if (server[i].fd > 0
- && (ip == (uint32)-1 || server[i].ip == ip)
- && (port == (uint16)-1 || server[i].port == port)) {
- for (j = 0; server[i].map[j]; j++)
- if (server[i].map[j] == map)
- return i;
- }
- }
-
- return -1;
+ int i, j;
+
+ for(i = 0; i < ARRAYLENGTH(server); i++)
+ {
+ if (server[i].fd > 0
+ && (ip == (uint32)-1 || server[i].ip == ip)
+ && (port == (uint16)-1 || server[i].port == port))
+ {
+ for (j = 0; server[i].map[j]; j++)
+ if (server[i].map[j] == map)
+ return i;
+ }
+ }
+
+ return -1;
}
// Initialization process (currently only initialization inter_mapif)
static int char_mapif_init(int fd)
{
- return inter_mapif_init(fd);
+ return inter_mapif_init(fd);
}
//--------------------------------------------
@@ -3329,15 +3377,15 @@ static int char_mapif_init(int fd)
//--------------------------------------------
int lan_subnetcheck(uint32 ip)
{
- int i;
- ARR_FIND(0, subnet_count, i, (subnet[i].char_ip & subnet[i].mask) == (ip & subnet[i].mask));
- if (i < subnet_count) {
- ShowInfo("Subnet check [%u.%u.%u.%u]: Matches "CL_CYAN"%u.%u.%u.%u/%u.%u.%u.%u"CL_RESET"\n", CONVIP(ip), CONVIP(subnet[i].char_ip & subnet[i].mask), CONVIP(subnet[i].mask));
- return subnet[i].map_ip;
- } else {
- ShowInfo("Subnet check [%u.%u.%u.%u]: "CL_CYAN"WAN"CL_RESET"\n", CONVIP(ip));
- return 0;
- }
+ int i;
+ ARR_FIND( 0, subnet_count, i, (subnet[i].char_ip & subnet[i].mask) == (ip & subnet[i].mask) );
+ if( i < subnet_count ) {
+ ShowInfo("Subnet check [%u.%u.%u.%u]: Matches "CL_CYAN"%u.%u.%u.%u/%u.%u.%u.%u"CL_RESET"\n", CONVIP(ip), CONVIP(subnet[i].char_ip & subnet[i].mask), CONVIP(subnet[i].mask));
+ return subnet[i].map_ip;
+ } else {
+ ShowInfo("Subnet check [%u.%u.%u.%u]: "CL_CYAN"WAN"CL_RESET"\n", CONVIP(ip));
+ return 0;
+ }
}
@@ -3349,14 +3397,13 @@ int lan_subnetcheck(uint32 ip)
/// 5 (0x71b): To delete a character you must withdraw from the party.
/// Any (0x718): An unknown error has occurred.
void char_delete2_ack(int fd, int char_id, uint32 result, time_t delete_date)
-{
- // HC: <0828>.W <char id>.L <Msg:0-5>.L <deleteDate>.L
- WFIFOHEAD(fd,14);
- WFIFOW(fd,0) = 0x828;
- WFIFOL(fd,2) = char_id;
- WFIFOL(fd,6) = result;
- WFIFOL(fd,10) = TOL(delete_date);
- WFIFOSET(fd,14);
+{// HC: <0828>.W <char id>.L <Msg:0-5>.L <deleteDate>.L
+ WFIFOHEAD(fd,14);
+ WFIFOW(fd,0) = 0x828;
+ WFIFOL(fd,2) = char_id;
+ WFIFOL(fd,6) = result;
+ WFIFOL(fd,10) = TOL(delete_date);
+ WFIFOSET(fd,14);
}
@@ -3369,13 +3416,12 @@ void char_delete2_ack(int fd, int char_id, uint32 result, time_t delete_date)
/// 5 (0x71e): Date of birth do not match.
/// Any (0x718): An unknown error has occurred.
void char_delete2_accept_ack(int fd, int char_id, uint32 result)
-{
- // HC: <082a>.W <char id>.L <Msg:0-5>.L
- WFIFOHEAD(fd,10);
- WFIFOW(fd,0) = 0x82a;
- WFIFOL(fd,2) = char_id;
- WFIFOL(fd,6) = result;
- WFIFOSET(fd,10);
+{// HC: <082a>.W <char id>.L <Msg:0-5>.L
+ WFIFOHEAD(fd,10);
+ WFIFOW(fd,0) = 0x82a;
+ WFIFOL(fd,2) = char_id;
+ WFIFOL(fd,6) = result;
+ WFIFOSET(fd,10);
}
@@ -3384,797 +3430,804 @@ void char_delete2_accept_ack(int fd, int char_id, uint32 result)
/// 2 (0x719): A database error occurred.
/// Any (0x718): An unknown error has occurred.
void char_delete2_cancel_ack(int fd, int char_id, uint32 result)
-{
- // HC: <082c>.W <char id>.L <Msg:1-2>.L
- WFIFOHEAD(fd,10);
- WFIFOW(fd,0) = 0x82c;
- WFIFOL(fd,2) = char_id;
- WFIFOL(fd,6) = result;
- WFIFOSET(fd,10);
+{// HC: <082c>.W <char id>.L <Msg:1-2>.L
+ WFIFOHEAD(fd,10);
+ WFIFOW(fd,0) = 0x82c;
+ WFIFOL(fd,2) = char_id;
+ WFIFOL(fd,6) = result;
+ WFIFOSET(fd,10);
}
-static void char_delete2_req(int fd, struct char_session_data *sd)
-{
- // CH: <0827>.W <char id>.L
- int char_id, i;
- char *data;
- time_t delete_date;
-
- char_id = RFIFOL(fd,2);
-
- ARR_FIND(0, MAX_CHARS, i, sd->found_char[i] == char_id);
- if (i == MAX_CHARS) {
- // character not found
- char_delete2_ack(fd, char_id, 3, 0);
- return;
- }
-
- if (SQL_SUCCESS != Sql_Query(sql_handle, "SELECT `delete_date` FROM `%s` WHERE `char_id`='%d'", char_db, char_id) || SQL_SUCCESS != Sql_NextRow(sql_handle)) {
- Sql_ShowDebug(sql_handle);
- char_delete2_ack(fd, char_id, 3, 0);
- return;
- }
-
- Sql_GetData(sql_handle, 0, &data, NULL);
- delete_date = strtoul(data, NULL, 10);
-
- if (delete_date) { // character already queued for deletion
- char_delete2_ack(fd, char_id, 0, 0);
- return;
- }
-
- /*
- // Aegis imposes these checks probably to avoid dead member
- // entries in guilds/parties, otherwise they are not required.
- // TODO: Figure out how these are enforced during waiting.
- if( guild_id )
- {// character in guild
- char_delete2_ack(fd, char_id, 4, 0);
- return;
- }
-
- if( party_id )
- {// character in party
- char_delete2_ack(fd, char_id, 5, 0);
- return;
- }
- */
-
- // success
- delete_date = time(NULL)+char_del_delay;
-
- if (SQL_SUCCESS != Sql_Query(sql_handle, "UPDATE `%s` SET `delete_date`='%lu' WHERE `char_id`='%d'", char_db, (unsigned long)delete_date, char_id)) {
- Sql_ShowDebug(sql_handle);
- char_delete2_ack(fd, char_id, 3, 0);
- return;
- }
-
- char_delete2_ack(fd, char_id, 1, delete_date);
+static void char_delete2_req(int fd, struct char_session_data* sd)
+{// CH: <0827>.W <char id>.L
+ int char_id, i;
+ char* data;
+ time_t delete_date;
+
+ char_id = RFIFOL(fd,2);
+
+ ARR_FIND( 0, MAX_CHARS, i, sd->found_char[i] == char_id );
+ if( i == MAX_CHARS )
+ {// character not found
+ char_delete2_ack(fd, char_id, 3, 0);
+ return;
+ }
+
+ if( SQL_SUCCESS != Sql_Query(sql_handle, "SELECT `delete_date` FROM `%s` WHERE `char_id`='%d'", char_db, char_id) || SQL_SUCCESS != Sql_NextRow(sql_handle) )
+ {
+ Sql_ShowDebug(sql_handle);
+ char_delete2_ack(fd, char_id, 3, 0);
+ return;
+ }
+
+ Sql_GetData(sql_handle, 0, &data, NULL); delete_date = strtoul(data, NULL, 10);
+
+ if( delete_date ) {// character already queued for deletion
+ char_delete2_ack(fd, char_id, 0, 0);
+ return;
+ }
+
+/*
+ // Aegis imposes these checks probably to avoid dead member
+ // entries in guilds/parties, otherwise they are not required.
+ // TODO: Figure out how these are enforced during waiting.
+ if( guild_id )
+ {// character in guild
+ char_delete2_ack(fd, char_id, 4, 0);
+ return;
+ }
+
+ if( party_id )
+ {// character in party
+ char_delete2_ack(fd, char_id, 5, 0);
+ return;
+ }
+*/
+
+ // success
+ delete_date = time(NULL)+char_del_delay;
+
+ if( SQL_SUCCESS != Sql_Query(sql_handle, "UPDATE `%s` SET `delete_date`='%lu' WHERE `char_id`='%d'", char_db, (unsigned long)delete_date, char_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ char_delete2_ack(fd, char_id, 3, 0);
+ return;
+ }
+
+ char_delete2_ack(fd, char_id, 1, delete_date);
}
-static void char_delete2_accept(int fd, struct char_session_data *sd)
-{
- // CH: <0829>.W <char id>.L <birth date:YYMMDD>.6B
- char birthdate[8+1];
- int char_id, i, k;
- unsigned int base_level;
- char *data;
- time_t delete_date;
-
- char_id = RFIFOL(fd,2);
-
- ShowInfo(CL_RED"Request Char Deletion: "CL_GREEN"%d (%d)"CL_RESET"\n", sd->account_id, char_id);
-
- // construct "YY-MM-DD"
- birthdate[0] = RFIFOB(fd,6);
- birthdate[1] = RFIFOB(fd,7);
- birthdate[2] = '-';
- birthdate[3] = RFIFOB(fd,8);
- birthdate[4] = RFIFOB(fd,9);
- birthdate[5] = '-';
- birthdate[6] = RFIFOB(fd,10);
- birthdate[7] = RFIFOB(fd,11);
- birthdate[8] = 0;
-
- ARR_FIND(0, MAX_CHARS, i, sd->found_char[i] == char_id);
- if (i == MAX_CHARS) {
- // character not found
- char_delete2_accept_ack(fd, char_id, 3);
- return;
- }
-
- if (SQL_SUCCESS != Sql_Query(sql_handle, "SELECT `base_level`,`delete_date` FROM `%s` WHERE `char_id`='%d'", char_db, char_id) || SQL_SUCCESS != Sql_NextRow(sql_handle)) {
- // data error
- Sql_ShowDebug(sql_handle);
- char_delete2_accept_ack(fd, char_id, 3);
- return;
- }
-
- Sql_GetData(sql_handle, 0, &data, NULL);
- base_level = (unsigned int)strtoul(data, NULL, 10);
- Sql_GetData(sql_handle, 1, &data, NULL);
- delete_date = strtoul(data, NULL, 10);
-
- if (!delete_date || delete_date>time(NULL)) {
- // not queued or delay not yet passed
- char_delete2_accept_ack(fd, char_id, 4);
- return;
- }
-
- if (strcmp(sd->birthdate+2, birthdate)) { // +2 to cut off the century
- // birth date is wrong
- char_delete2_accept_ack(fd, char_id, 5);
- return;
- }
-
- if ((char_del_level > 0 && base_level >= (unsigned int)char_del_level) || (char_del_level < 0 && base_level <= (unsigned int)(-char_del_level))) {
- // character level config restriction
- char_delete2_accept_ack(fd, char_id, 2);
- return;
- }
-
- // success
- if (delete_char_sql(char_id) < 0) {
- char_delete2_accept_ack(fd, char_id, 3);
- return;
- }
-
- // refresh character list cache
- for (k = i; k < MAX_CHARS-1; k++) {
- sd->found_char[k] = sd->found_char[k+1];
- }
- sd->found_char[MAX_CHARS-1] = -1;
-
- char_delete2_accept_ack(fd, char_id, 1);
+static void char_delete2_accept(int fd, struct char_session_data* sd)
+{// CH: <0829>.W <char id>.L <birth date:YYMMDD>.6B
+ char birthdate[8+1];
+ int char_id, i, k;
+ unsigned int base_level;
+ char* data;
+ time_t delete_date;
+
+ char_id = RFIFOL(fd,2);
+
+ ShowInfo(CL_RED"Request Char Deletion: "CL_GREEN"%d (%d)"CL_RESET"\n", sd->account_id, char_id);
+
+ // construct "YY-MM-DD"
+ birthdate[0] = RFIFOB(fd,6);
+ birthdate[1] = RFIFOB(fd,7);
+ birthdate[2] = '-';
+ birthdate[3] = RFIFOB(fd,8);
+ birthdate[4] = RFIFOB(fd,9);
+ birthdate[5] = '-';
+ birthdate[6] = RFIFOB(fd,10);
+ birthdate[7] = RFIFOB(fd,11);
+ birthdate[8] = 0;
+
+ ARR_FIND( 0, MAX_CHARS, i, sd->found_char[i] == char_id );
+ if( i == MAX_CHARS )
+ {// character not found
+ char_delete2_accept_ack(fd, char_id, 3);
+ return;
+ }
+
+ if( SQL_SUCCESS != Sql_Query(sql_handle, "SELECT `base_level`,`delete_date` FROM `%s` WHERE `char_id`='%d'", char_db, char_id) || SQL_SUCCESS != Sql_NextRow(sql_handle) )
+ {// data error
+ Sql_ShowDebug(sql_handle);
+ char_delete2_accept_ack(fd, char_id, 3);
+ return;
+ }
+
+ Sql_GetData(sql_handle, 0, &data, NULL); base_level = (unsigned int)strtoul(data, NULL, 10);
+ Sql_GetData(sql_handle, 1, &data, NULL); delete_date = strtoul(data, NULL, 10);
+
+ if( !delete_date || delete_date>time(NULL) )
+ {// not queued or delay not yet passed
+ char_delete2_accept_ack(fd, char_id, 4);
+ return;
+ }
+
+ if( strcmp(sd->birthdate+2, birthdate) ) // +2 to cut off the century
+ {// birth date is wrong
+ char_delete2_accept_ack(fd, char_id, 5);
+ return;
+ }
+
+ if( ( char_del_level > 0 && base_level >= (unsigned int)char_del_level ) || ( char_del_level < 0 && base_level <= (unsigned int)(-char_del_level) ) )
+ {// character level config restriction
+ char_delete2_accept_ack(fd, char_id, 2);
+ return;
+ }
+
+ // success
+ if( delete_char_sql(char_id) < 0 )
+ {
+ char_delete2_accept_ack(fd, char_id, 3);
+ return;
+ }
+
+ // refresh character list cache
+ for(k = i; k < MAX_CHARS-1; k++)
+ {
+ sd->found_char[k] = sd->found_char[k+1];
+ }
+ sd->found_char[MAX_CHARS-1] = -1;
+
+ char_delete2_accept_ack(fd, char_id, 1);
}
-static void char_delete2_cancel(int fd, struct char_session_data *sd)
-{
- // CH: <082b>.W <char id>.L
- int char_id, i;
-
- char_id = RFIFOL(fd,2);
-
- ARR_FIND(0, MAX_CHARS, i, sd->found_char[i] == char_id);
- if (i == MAX_CHARS) {
- // character not found
- char_delete2_cancel_ack(fd, char_id, 2);
- return;
- }
-
- // there is no need to check, whether or not the character was
- // queued for deletion, as the client prints an error message by
- // itself, if it was not the case (@see char_delete2_cancel_ack)
- if (SQL_SUCCESS != Sql_Query(sql_handle, "UPDATE `%s` SET `delete_date`='0' WHERE `char_id`='%d'", char_db, char_id)) {
- Sql_ShowDebug(sql_handle);
- char_delete2_cancel_ack(fd, char_id, 2);
- return;
- }
-
- char_delete2_cancel_ack(fd, char_id, 1);
+static void char_delete2_cancel(int fd, struct char_session_data* sd)
+{// CH: <082b>.W <char id>.L
+ int char_id, i;
+
+ char_id = RFIFOL(fd,2);
+
+ ARR_FIND( 0, MAX_CHARS, i, sd->found_char[i] == char_id );
+ if( i == MAX_CHARS )
+ {// character not found
+ char_delete2_cancel_ack(fd, char_id, 2);
+ return;
+ }
+
+ // there is no need to check, whether or not the character was
+ // queued for deletion, as the client prints an error message by
+ // itself, if it was not the case (@see char_delete2_cancel_ack)
+ if( SQL_SUCCESS != Sql_Query(sql_handle, "UPDATE `%s` SET `delete_date`='0' WHERE `char_id`='%d'", char_db, char_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ char_delete2_cancel_ack(fd, char_id, 2);
+ return;
+ }
+
+ char_delete2_cancel_ack(fd, char_id, 1);
}
int parse_char(int fd)
{
- int i, ch;
- char email[40];
- unsigned short cmd;
- int map_fd;
- struct char_session_data *sd;
- uint32 ipl = session[fd]->client_addr;
-
- sd = (struct char_session_data *)session[fd]->session_data;
-
- // disconnect any player if no login-server.
- if (login_fd < 0)
- set_eof(fd);
-
- if (session[fd]->flag.eof) {
- if (sd != NULL && sd->auth) {
- // already authed client
- struct online_char_data *data = (struct online_char_data *)idb_get(online_char_db, sd->account_id);
- if (data != NULL && data->fd == fd)
- data->fd = -1;
- if (data == NULL || data->server == -1) //If it is not in any server, send it offline. [Skotlex]
- set_char_offline(-1,sd->account_id);
- }
- do_close(fd);
- return 0;
- }
-
- while (RFIFOREST(fd) >= 2) {
- //For use in packets that depend on an sd being present [Skotlex]
-#define FIFOSD_CHECK(rest) { if(RFIFOREST(fd) < rest) return 0; if (sd==NULL || !sd->auth) { RFIFOSKIP(fd,rest); return 0; } }
-
- cmd = RFIFOW(fd,0);
- switch (cmd) {
-
- // request to connect
- // 0065 <account id>.L <login id1>.L <login id2>.L <???>.W <sex>.B
- case 0x65:
- if (RFIFOREST(fd) < 17)
- return 0;
- {
- struct auth_node *node;
-
- int account_id = RFIFOL(fd,2);
- uint32 login_id1 = RFIFOL(fd,6);
- uint32 login_id2 = RFIFOL(fd,10);
- int sex = RFIFOB(fd,16);
- RFIFOSKIP(fd,17);
-
- ShowInfo("request connect - account_id:%d/login_id1:%d/login_id2:%d\n", account_id, login_id1, login_id2);
-
- if (sd) {
- //Received again auth packet for already authentified account?? Discard it.
- //TODO: Perhaps log this as a hack attempt?
- //TODO: and perhaps send back a reply?
- break;
- }
-
- CREATE(session[fd]->session_data, struct char_session_data, 1);
- sd = (struct char_session_data *)session[fd]->session_data;
- sd->account_id = account_id;
- sd->login_id1 = login_id1;
- sd->login_id2 = login_id2;
- sd->sex = sex;
- sd->auth = false; // not authed yet
-
- // send back account_id
- WFIFOHEAD(fd,4);
- WFIFOL(fd,0) = account_id;
- WFIFOSET(fd,4);
-
- if (runflag != CHARSERVER_ST_RUNNING) {
- WFIFOHEAD(fd,3);
- WFIFOW(fd,0) = 0x6c;
- WFIFOB(fd,2) = 0;// rejected from server
- WFIFOSET(fd,3);
- break;
- }
-
- // search authentification
- node = (struct auth_node *)idb_get(auth_db, account_id);
- if (node != NULL &&
- node->account_id == account_id &&
- node->login_id1 == login_id1 &&
- node->login_id2 == login_id2 /*&&
- node->ip == ipl*/) {
- // authentication found (coming from map server)
- idb_remove(auth_db, account_id);
- char_auth_ok(fd, sd);
- } else {
- // authentication not found (coming from login server)
- if (login_fd > 0) { // don't send request if no login-server
- WFIFOHEAD(login_fd,23);
- 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) = htonl(ipl);
- WFIFOL(login_fd,19) = fd;
- WFIFOSET(login_fd,23);
- } else { // if no login-server, we must refuse connection
- WFIFOHEAD(fd,3);
- WFIFOW(fd,0) = 0x6c;
- WFIFOB(fd,2) = 0;
- WFIFOSET(fd,3);
- }
- }
- }
- break;
-
- // char select
- case 0x66:
- FIFOSD_CHECK(3);
- {
- struct mmo_charstatus char_dat;
- struct mmo_charstatus *cd;
- char *data;
- int char_id;
- uint32 subnet_map_ip;
- struct auth_node *node;
-
- int slot = RFIFOB(fd,2);
- RFIFOSKIP(fd,3);
-
- if (SQL_SUCCESS != Sql_Query(sql_handle, "SELECT `char_id` FROM `%s` WHERE `account_id`='%d' AND `char_num`='%d'", char_db, sd->account_id, slot)
- || SQL_SUCCESS != Sql_NextRow(sql_handle)
- || SQL_SUCCESS != Sql_GetData(sql_handle, 0, &data, NULL)) {
- //Not found?? May be forged packet.
- Sql_ShowDebug(sql_handle);
- Sql_FreeResult(sql_handle);
- WFIFOHEAD(fd,3);
- WFIFOW(fd,0) = 0x6c;
- WFIFOB(fd,2) = 0; // rejected from server
- WFIFOSET(fd,3);
- break;
- }
-
- char_id = atoi(data);
- Sql_FreeResult(sql_handle);
- mmo_char_fromsql(char_id, &char_dat, true);
-
- //Have to switch over to the DB instance otherwise data won't propagate [Kevin]
- cd = (struct mmo_charstatus *)idb_get(char_db_, char_id);
- cd->sex = sd->sex;
-
- if (log_char) {
- char esc_name[NAME_LENGTH*2+1];
-
- Sql_EscapeStringLen(sql_handle, esc_name, char_dat.name, strnlen(char_dat.name, NAME_LENGTH));
- if (SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s`(`time`, `account_id`,`char_num`,`name`) VALUES (NOW(), '%d', '%d', '%s')",
- charlog_db, sd->account_id, slot, esc_name))
- Sql_ShowDebug(sql_handle);
- }
- ShowInfo("Selected char: (Account %d: %d - %s)\n", sd->account_id, slot, char_dat.name);
-
- // searching map server
- i = search_mapserver(cd->last_point.map, -1, -1);
-
- // if map is not found, we check major cities
- if (i < 0 || !cd->last_point.map) {
- unsigned short j;
- //First check that there's actually a map server online.
- ARR_FIND(0, ARRAYLENGTH(server), j, server[j].fd >= 0 && server[j].map[0]);
- if (j == ARRAYLENGTH(server)) {
- ShowInfo("Connection Closed. No map servers available.\n");
- WFIFOHEAD(fd,3);
- WFIFOW(fd,0) = 0x81;
- WFIFOB(fd,2) = 1; // 01 = Server closed
- WFIFOSET(fd,3);
- break;
- }
- if ((i = search_mapserver((j=mapindex_name2id(MAP_PRONTERA)),-1,-1)) >= 0) {
- cd->last_point.x = 273;
- cd->last_point.y = 354;
- } else if ((i = search_mapserver((j=mapindex_name2id(MAP_GEFFEN)),-1,-1)) >= 0) {
- cd->last_point.x = 120;
- cd->last_point.y = 100;
- } else if ((i = search_mapserver((j=mapindex_name2id(MAP_MORROC)),-1,-1)) >= 0) {
- cd->last_point.x = 160;
- cd->last_point.y = 94;
- } else if ((i = search_mapserver((j=mapindex_name2id(MAP_ALBERTA)),-1,-1)) >= 0) {
- cd->last_point.x = 116;
- cd->last_point.y = 57;
- } else if ((i = search_mapserver((j=mapindex_name2id(MAP_PAYON)),-1,-1)) >= 0) {
- cd->last_point.x = 87;
- cd->last_point.y = 117;
- } else if ((i = search_mapserver((j=mapindex_name2id(MAP_IZLUDE)),-1,-1)) >= 0) {
- cd->last_point.x = 94;
- cd->last_point.y = 103;
- } else {
- ShowInfo("Connection Closed. No map server available that has a major city, and unable to find map-server for '%s'.\n", mapindex_id2name(cd->last_point.map));
- WFIFOHEAD(fd,3);
- WFIFOW(fd,0) = 0x81;
- WFIFOB(fd,2) = 1; // 01 = Server closed
- WFIFOSET(fd,3);
- break;
- }
- ShowWarning("Unable to find map-server for '%s', sending to major city '%s'.\n", mapindex_id2name(cd->last_point.map), mapindex_id2name(j));
- cd->last_point.map = j;
- }
-
- //Send NEW auth packet [Kevin]
- //FIXME: is this case even possible? [ultramage]
- if ((map_fd = server[i].fd) < 1 || session[map_fd] == NULL) {
- ShowError("parse_char: Attempting to write to invalid session %d! Map Server #%d disconnected.\n", map_fd, i);
- server[i].fd = -1;
- memset(&server[i], 0, sizeof(struct mmo_map_server));
- //Send server closed.
- WFIFOHEAD(fd,3);
- WFIFOW(fd,0) = 0x81;
- WFIFOB(fd,2) = 1; // 01 = Server closed
- WFIFOSET(fd,3);
- break;
- }
-
- //Send player to map
- WFIFOHEAD(fd,28);
- WFIFOW(fd,0) = 0x71;
- WFIFOL(fd,2) = cd->char_id;
- mapindex_getmapname_ext(mapindex_id2name(cd->last_point.map), (char *)WFIFOP(fd,6));
- subnet_map_ip = lan_subnetcheck(ipl); // Advanced subnet check [LuzZza]
- WFIFOL(fd,22) = htonl((subnet_map_ip) ? subnet_map_ip : server[i].ip);
- WFIFOW(fd,26) = ntows(htons(server[i].port)); // [!] LE byte order here [!]
- WFIFOSET(fd,28);
-
- // create temporary auth entry
- CREATE(node, struct auth_node, 1);
- node->account_id = sd->account_id;
- node->char_id = cd->char_id;
- node->login_id1 = sd->login_id1;
- node->login_id2 = sd->login_id2;
- node->sex = sd->sex;
- node->expiration_time = sd->expiration_time;
- node->group_id = sd->group_id;
- node->ip = ipl;
- idb_put(auth_db, sd->account_id, node);
-
- set_char_online(-2,node->char_id,sd->account_id);
-
- }
- break;
-
- // create new char
+ int i, ch;
+ char email[40];
+ unsigned short cmd;
+ int map_fd;
+ struct char_session_data* sd;
+ uint32 ipl = session[fd]->client_addr;
+
+ sd = (struct char_session_data*)session[fd]->session_data;
+
+ // disconnect any player if no login-server.
+ if(login_fd < 0)
+ set_eof(fd);
+
+ if(session[fd]->flag.eof)
+ {
+ if( sd != NULL && sd->auth )
+ { // already authed client
+ struct online_char_data* data = (struct online_char_data*)idb_get(online_char_db, sd->account_id);
+ if( data != NULL && data->fd == fd)
+ data->fd = -1;
+ if( data == NULL || data->server == -1) //If it is not in any server, send it offline. [Skotlex]
+ set_char_offline(-1,sd->account_id);
+ }
+ do_close(fd);
+ return 0;
+ }
+
+ while( RFIFOREST(fd) >= 2 )
+ {
+ //For use in packets that depend on an sd being present [Skotlex]
+ #define FIFOSD_CHECK(rest) { if(RFIFOREST(fd) < rest) return 0; if (sd==NULL || !sd->auth) { RFIFOSKIP(fd,rest); return 0; } }
+
+ cmd = RFIFOW(fd,0);
+ switch( cmd )
+ {
+
+ // request to connect
+ // 0065 <account id>.L <login id1>.L <login id2>.L <???>.W <sex>.B
+ case 0x65:
+ if( RFIFOREST(fd) < 17 )
+ return 0;
+ {
+ struct auth_node* node;
+
+ int account_id = RFIFOL(fd,2);
+ uint32 login_id1 = RFIFOL(fd,6);
+ uint32 login_id2 = RFIFOL(fd,10);
+ int sex = RFIFOB(fd,16);
+ RFIFOSKIP(fd,17);
+
+ ShowInfo("request connect - account_id:%d/login_id1:%d/login_id2:%d\n", account_id, login_id1, login_id2);
+
+ if (sd) {
+ //Received again auth packet for already authentified account?? Discard it.
+ //TODO: Perhaps log this as a hack attempt?
+ //TODO: and perhaps send back a reply?
+ break;
+ }
+
+ CREATE(session[fd]->session_data, struct char_session_data, 1);
+ sd = (struct char_session_data*)session[fd]->session_data;
+ sd->account_id = account_id;
+ sd->login_id1 = login_id1;
+ sd->login_id2 = login_id2;
+ sd->sex = sex;
+ sd->auth = false; // not authed yet
+
+ // send back account_id
+ WFIFOHEAD(fd,4);
+ WFIFOL(fd,0) = account_id;
+ WFIFOSET(fd,4);
+
+ if( runflag != CHARSERVER_ST_RUNNING )
+ {
+ WFIFOHEAD(fd,3);
+ WFIFOW(fd,0) = 0x6c;
+ WFIFOB(fd,2) = 0;// rejected from server
+ WFIFOSET(fd,3);
+ break;
+ }
+
+ // search authentification
+ node = (struct auth_node*)idb_get(auth_db, account_id);
+ if( node != NULL &&
+ node->account_id == account_id &&
+ node->login_id1 == login_id1 &&
+ node->login_id2 == login_id2 /*&&
+ node->ip == ipl*/ )
+ {// authentication found (coming from map server)
+ idb_remove(auth_db, account_id);
+ char_auth_ok(fd, sd);
+ }
+ else
+ {// authentication not found (coming from login server)
+ if (login_fd > 0) { // don't send request if no login-server
+ WFIFOHEAD(login_fd,23);
+ 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) = htonl(ipl);
+ WFIFOL(login_fd,19) = fd;
+ WFIFOSET(login_fd,23);
+ } else { // if no login-server, we must refuse connection
+ WFIFOHEAD(fd,3);
+ WFIFOW(fd,0) = 0x6c;
+ WFIFOB(fd,2) = 0;
+ WFIFOSET(fd,3);
+ }
+ }
+ }
+ break;
+
+ // char select
+ case 0x66:
+ FIFOSD_CHECK(3);
+ {
+ struct mmo_charstatus char_dat;
+ struct mmo_charstatus *cd;
+ char* data;
+ int char_id;
+ uint32 subnet_map_ip;
+ struct auth_node* node;
+
+ int slot = RFIFOB(fd,2);
+ RFIFOSKIP(fd,3);
+
+ if ( SQL_SUCCESS != Sql_Query(sql_handle, "SELECT `char_id` FROM `%s` WHERE `account_id`='%d' AND `char_num`='%d'", char_db, sd->account_id, slot)
+ || SQL_SUCCESS != Sql_NextRow(sql_handle)
+ || SQL_SUCCESS != Sql_GetData(sql_handle, 0, &data, NULL) )
+ { //Not found?? May be forged packet.
+ Sql_ShowDebug(sql_handle);
+ Sql_FreeResult(sql_handle);
+ WFIFOHEAD(fd,3);
+ WFIFOW(fd,0) = 0x6c;
+ WFIFOB(fd,2) = 0; // rejected from server
+ WFIFOSET(fd,3);
+ break;
+ }
+
+ char_id = atoi(data);
+ Sql_FreeResult(sql_handle);
+ mmo_char_fromsql(char_id, &char_dat, true);
+
+ //Have to switch over to the DB instance otherwise data won't propagate [Kevin]
+ cd = (struct mmo_charstatus *)idb_get(char_db_, char_id);
+ cd->sex = sd->sex;
+
+ if (log_char) {
+ char esc_name[NAME_LENGTH*2+1];
+
+ Sql_EscapeStringLen(sql_handle, esc_name, char_dat.name, strnlen(char_dat.name, NAME_LENGTH));
+ if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s`(`time`, `account_id`,`char_num`,`name`) VALUES (NOW(), '%d', '%d', '%s')",
+ charlog_db, sd->account_id, slot, esc_name) )
+ Sql_ShowDebug(sql_handle);
+ }
+ ShowInfo("Selected char: (Account %d: %d - %s)\n", sd->account_id, slot, char_dat.name);
+
+ // searching map server
+ i = search_mapserver(cd->last_point.map, -1, -1);
+
+ // if map is not found, we check major cities
+ if (i < 0 || !cd->last_point.map) {
+ unsigned short j;
+ //First check that there's actually a map server online.
+ ARR_FIND( 0, ARRAYLENGTH(server), j, server[j].fd >= 0 && server[j].map[0] );
+ if (j == ARRAYLENGTH(server)) {
+ ShowInfo("Connection Closed. No map servers available.\n");
+ WFIFOHEAD(fd,3);
+ WFIFOW(fd,0) = 0x81;
+ WFIFOB(fd,2) = 1; // 01 = Server closed
+ WFIFOSET(fd,3);
+ break;
+ }
+ if ((i = search_mapserver((j=mapindex_name2id(MAP_PRONTERA)),-1,-1)) >= 0) {
+ cd->last_point.x = 273;
+ cd->last_point.y = 354;
+ } else if ((i = search_mapserver((j=mapindex_name2id(MAP_GEFFEN)),-1,-1)) >= 0) {
+ cd->last_point.x = 120;
+ cd->last_point.y = 100;
+ } else if ((i = search_mapserver((j=mapindex_name2id(MAP_MORROC)),-1,-1)) >= 0) {
+ cd->last_point.x = 160;
+ cd->last_point.y = 94;
+ } else if ((i = search_mapserver((j=mapindex_name2id(MAP_ALBERTA)),-1,-1)) >= 0) {
+ cd->last_point.x = 116;
+ cd->last_point.y = 57;
+ } else if ((i = search_mapserver((j=mapindex_name2id(MAP_PAYON)),-1,-1)) >= 0) {
+ cd->last_point.x = 87;
+ cd->last_point.y = 117;
+ } else if ((i = search_mapserver((j=mapindex_name2id(MAP_IZLUDE)),-1,-1)) >= 0) {
+ cd->last_point.x = 94;
+ cd->last_point.y = 103;
+ } else {
+ ShowInfo("Connection Closed. No map server available that has a major city, and unable to find map-server for '%s'.\n", mapindex_id2name(cd->last_point.map));
+ WFIFOHEAD(fd,3);
+ WFIFOW(fd,0) = 0x81;
+ WFIFOB(fd,2) = 1; // 01 = Server closed
+ WFIFOSET(fd,3);
+ break;
+ }
+ ShowWarning("Unable to find map-server for '%s', sending to major city '%s'.\n", mapindex_id2name(cd->last_point.map), mapindex_id2name(j));
+ cd->last_point.map = j;
+ }
+
+ //Send NEW auth packet [Kevin]
+ //FIXME: is this case even possible? [ultramage]
+ if ((map_fd = server[i].fd) < 1 || session[map_fd] == NULL)
+ {
+ ShowError("parse_char: Attempting to write to invalid session %d! Map Server #%d disconnected.\n", map_fd, i);
+ server[i].fd = -1;
+ memset(&server[i], 0, sizeof(struct mmo_map_server));
+ //Send server closed.
+ WFIFOHEAD(fd,3);
+ WFIFOW(fd,0) = 0x81;
+ WFIFOB(fd,2) = 1; // 01 = Server closed
+ WFIFOSET(fd,3);
+ break;
+ }
+
+ //Send player to map
+ WFIFOHEAD(fd,28);
+ WFIFOW(fd,0) = 0x71;
+ WFIFOL(fd,2) = cd->char_id;
+ mapindex_getmapname_ext(mapindex_id2name(cd->last_point.map), (char*)WFIFOP(fd,6));
+ subnet_map_ip = lan_subnetcheck(ipl); // Advanced subnet check [LuzZza]
+ WFIFOL(fd,22) = htonl((subnet_map_ip) ? subnet_map_ip : server[i].ip);
+ WFIFOW(fd,26) = ntows(htons(server[i].port)); // [!] LE byte order here [!]
+ WFIFOSET(fd,28);
+
+ // create temporary auth entry
+ CREATE(node, struct auth_node, 1);
+ node->account_id = sd->account_id;
+ node->char_id = cd->char_id;
+ node->login_id1 = sd->login_id1;
+ node->login_id2 = sd->login_id2;
+ node->sex = sd->sex;
+ node->expiration_time = sd->expiration_time;
+ node->group_id = sd->group_id;
+ node->ip = ipl;
+ idb_put(auth_db, sd->account_id, node);
+
+ set_char_online(-2,node->char_id,sd->account_id);
+
+ }
+ break;
+
+ // create new char
#if PACKETVER >= 20120307
- // S 0970 <name>.24B <slot>.B <hair color>.W <hair style>.W
- case 0x970:
- FIFOSD_CHECK(31);
+ // S 0970 <name>.24B <slot>.B <hair color>.W <hair style>.W
+ case 0x970:
+ FIFOSD_CHECK(31);
#else
- // S 0067 <name>.24B <str>.B <agi>.B <vit>.B <int>.B <dex>.B <luk>.B <slot>.B <hair color>.W <hair style>.W
- case 0x67:
- FIFOSD_CHECK(37);
+ // S 0067 <name>.24B <str>.B <agi>.B <vit>.B <int>.B <dex>.B <luk>.B <slot>.B <hair color>.W <hair style>.W
+ case 0x67:
+ FIFOSD_CHECK(37);
#endif
- if (!char_new) //turn character creation on/off [Kevin]
- i = -2;
- else
+ if( !char_new ) //turn character creation on/off [Kevin]
+ i = -2;
+ else
#if PACKETVER >= 20120307
- i = make_new_char_sql(sd, (char *)RFIFOP(fd,2),RFIFOB(fd,26),RFIFOW(fd,27),RFIFOW(fd,29));
+ i = make_new_char_sql(sd, (char*)RFIFOP(fd,2),RFIFOB(fd,26),RFIFOW(fd,27),RFIFOW(fd,29));
#else
- i = make_new_char_sql(sd, (char *)RFIFOP(fd,2),RFIFOB(fd,26),RFIFOB(fd,27),RFIFOB(fd,28),RFIFOB(fd,29),RFIFOB(fd,30),RFIFOB(fd,31),RFIFOB(fd,32),RFIFOW(fd,33),RFIFOW(fd,35));
+ i = make_new_char_sql(sd, (char*)RFIFOP(fd,2),RFIFOB(fd,26),RFIFOB(fd,27),RFIFOB(fd,28),RFIFOB(fd,29),RFIFOB(fd,30),RFIFOB(fd,31),RFIFOB(fd,32),RFIFOW(fd,33),RFIFOW(fd,35));
#endif
- //'Charname already exists' (-1), 'Char creation denied' (-2) and 'You are underaged' (-3)
- if (i < 0) {
- WFIFOHEAD(fd,3);
- WFIFOW(fd,0) = 0x6e;
- switch (i) {
- case -1:
- WFIFOB(fd,2) = 0x00;
- break;
- case -2:
- WFIFOB(fd,2) = 0xFF;
- break;
- case -3:
- WFIFOB(fd,2) = 0x01;
- break;
- }
- WFIFOSET(fd,3);
- } else {
- int len;
- // retrieve data
- struct mmo_charstatus char_dat;
- mmo_char_fromsql(i, &char_dat, false); //Only the short data is needed.
-
- // send to player
- WFIFOHEAD(fd,2+MAX_CHAR_BUF);
- WFIFOW(fd,0) = 0x6d;
- len = 2 + mmo_char_tobuf(WFIFOP(fd,2), &char_dat);
- WFIFOSET(fd,len);
-
- // add new entry to the chars list
- ARR_FIND(0, MAX_CHARS, ch, sd->found_char[ch] == -1);
- if (ch < MAX_CHARS)
- sd->found_char[ch] = i; // the char_id of the new char
- }
+ //'Charname already exists' (-1), 'Char creation denied' (-2) and 'You are underaged' (-3)
+ if (i < 0)
+ {
+ WFIFOHEAD(fd,3);
+ WFIFOW(fd,0) = 0x6e;
+ switch (i) {
+ case -1: WFIFOB(fd,2) = 0x00; break;
+ case -2: WFIFOB(fd,2) = 0xFF; break;
+ case -3: WFIFOB(fd,2) = 0x01; break;
+ }
+ WFIFOSET(fd,3);
+ }
+ else
+ {
+ int len;
+ // retrieve data
+ struct mmo_charstatus char_dat;
+ mmo_char_fromsql(i, &char_dat, false); //Only the short data is needed.
+
+ // send to player
+ WFIFOHEAD(fd,2+MAX_CHAR_BUF);
+ WFIFOW(fd,0) = 0x6d;
+ len = 2 + mmo_char_tobuf(WFIFOP(fd,2), &char_dat);
+ WFIFOSET(fd,len);
+
+ // add new entry to the chars list
+ ARR_FIND( 0, MAX_CHARS, ch, sd->found_char[ch] == -1 );
+ if( ch < MAX_CHARS )
+ sd->found_char[ch] = i; // the char_id of the new char
+ }
#if PACKETVER >= 20120307
- RFIFOSKIP(fd,31);
+ RFIFOSKIP(fd,31);
#else
- RFIFOSKIP(fd,37);
+ RFIFOSKIP(fd,37);
#endif
- break;
-
- // delete char
- case 0x68:
- // 2004-04-19aSakexe+ langtype 12 char deletion packet
- case 0x1fb:
- if (cmd == 0x68) FIFOSD_CHECK(46);
- if (cmd == 0x1fb) FIFOSD_CHECK(56);
- {
- int cid = RFIFOL(fd,2);
-
- ShowInfo(CL_RED"Request Char Deletion: "CL_GREEN"%d (%d)"CL_RESET"\n", sd->account_id, cid);
- memcpy(email, RFIFOP(fd,6), 40);
- RFIFOSKIP(fd,(cmd == 0x68) ? 46 : 56);
-
- // Check if e-mail is correct
- if (strcmpi(email, sd->email) && //email does not matches and
- (
- strcmp("a@a.com", sd->email) || //it is not default email, or
- (strcmp("a@a.com", email) && strcmp("", email)) //email sent does not matches default
- )) { //Fail
- WFIFOHEAD(fd,3);
- WFIFOW(fd,0) = 0x70;
- WFIFOB(fd,2) = 0; // 00 = Incorrect Email address
- WFIFOSET(fd,3);
- break;
- }
-
- // check if this char exists
- ARR_FIND(0, MAX_CHARS, i, sd->found_char[i] == cid);
- if (i == MAX_CHARS) {
- // Such a character does not exist in the account
- WFIFOHEAD(fd,3);
- WFIFOW(fd,0) = 0x70;
- WFIFOB(fd,2) = 0;
- WFIFOSET(fd,3);
- break;
- }
-
- // remove char from list and compact it
- for (ch = i; ch < MAX_CHARS-1; ch++)
- sd->found_char[ch] = sd->found_char[ch+1];
- sd->found_char[MAX_CHARS-1] = -1;
-
- /* Delete character */
- if (delete_char_sql(cid)<0) {
- //can't delete the char
- //either SQL error or can't delete by some CONFIG conditions
- //del fail
- WFIFOHEAD(fd,3);
- WFIFOW(fd, 0) = 0x70;
- WFIFOB(fd, 2) = 0;
- WFIFOSET(fd, 3);
- break;
- }
- /* Char successfully deleted.*/
- WFIFOHEAD(fd,2);
- WFIFOW(fd,0) = 0x6f;
- WFIFOSET(fd,2);
- }
- break;
-
- // client keep-alive packet (every 12 seconds)
- // R 0187 <account ID>.l
- case 0x187:
- if (RFIFOREST(fd) < 6)
- return 0;
- RFIFOSKIP(fd,6);
- break;
-
- // char rename request
- // R 028d <account ID>.l <char ID>.l <new name>.24B
- case 0x28d:
- FIFOSD_CHECK(34);
- {
- int i, aid = RFIFOL(fd,2), cid =RFIFOL(fd,6);
- char name[NAME_LENGTH];
- char esc_name[NAME_LENGTH*2+1];
- safestrncpy(name, (char *)RFIFOP(fd,10), NAME_LENGTH);
- RFIFOSKIP(fd,34);
-
- if (aid != sd->account_id)
- break;
- ARR_FIND(0, MAX_CHARS, i, sd->found_char[i] == cid);
- if (i == MAX_CHARS)
- break;
-
- normalize_name(name,TRIM_CHARS);
- Sql_EscapeStringLen(sql_handle, esc_name, name, strnlen(name, NAME_LENGTH));
- if (!check_char_name(name,esc_name)) {
- i = 1;
- safestrncpy(sd->new_name, name, NAME_LENGTH);
- } else
- i = 0;
-
- WFIFOHEAD(fd, 4);
- WFIFOW(fd,0) = 0x28e;
- WFIFOW(fd,2) = i;
- WFIFOSET(fd,4);
- }
- break;
- //Confirm change name.
- // 0x28f <char_id>.L
- case 0x28f:
- // 0: Sucessfull
- // 1: This character's name has already been changed. You cannot change a character's name more than once.
- // 2: User information is not correct.
- // 3: You have failed to change this character's name.
- // 4: Another user is using this character name, so please select another one.
- FIFOSD_CHECK(6);
- {
- int i;
- int cid = RFIFOL(fd,2);
- RFIFOSKIP(fd,6);
-
- ARR_FIND(0, MAX_CHARS, i, sd->found_char[i] == cid);
- if (i == MAX_CHARS)
- break;
- i = rename_char_sql(sd, cid);
-
- WFIFOHEAD(fd, 4);
- WFIFOW(fd,0) = 0x290;
- WFIFOW(fd,2) = i;
- WFIFOSET(fd,4);
- }
- break;
-
- // captcha code request (not implemented)
- // R 07e5 <?>.w <aid>.l
- case 0x7e5:
- WFIFOHEAD(fd,5);
- WFIFOW(fd,0) = 0x7e9;
- WFIFOW(fd,2) = 5;
- WFIFOB(fd,4) = 1;
- WFIFOSET(fd,5);
- RFIFOSKIP(fd,8);
- break;
-
- // captcha code check (not implemented)
- // R 07e7 <len>.w <aid>.l <code>.b10 <?>.b14
- case 0x7e7:
- WFIFOHEAD(fd,5);
- WFIFOW(fd,0) = 0x7e9;
- WFIFOW(fd,2) = 5;
- WFIFOB(fd,4) = 1;
- WFIFOSET(fd,5);
- RFIFOSKIP(fd,32);
- break;
-
- // deletion timer request
- case 0x827:
- FIFOSD_CHECK(6);
- char_delete2_req(fd, sd);
- RFIFOSKIP(fd,6);
- break;
-
- // deletion accept request
- case 0x829:
- FIFOSD_CHECK(12);
- char_delete2_accept(fd, sd);
- RFIFOSKIP(fd,12);
- break;
-
- // deletion cancel request
- case 0x82b:
- FIFOSD_CHECK(6);
- char_delete2_cancel(fd, sd);
- RFIFOSKIP(fd,6);
- break;
-
- // login as map-server
- case 0x2af8:
- if (RFIFOREST(fd) < 60)
- return 0;
- {
- char *l_user = (char *)RFIFOP(fd,2);
- char *l_pass = (char *)RFIFOP(fd,26);
- l_user[23] = '\0';
- l_pass[23] = '\0';
- ARR_FIND(0, ARRAYLENGTH(server), i, server[i].fd <= 0);
- if (runflag != CHARSERVER_ST_RUNNING ||
- i == ARRAYLENGTH(server) ||
- strcmp(l_user, userid) != 0 ||
- strcmp(l_pass, passwd) != 0) {
- WFIFOHEAD(fd,3);
- WFIFOW(fd,0) = 0x2af9;
- WFIFOB(fd,2) = 3;
- WFIFOSET(fd,3);
- } else {
- WFIFOHEAD(fd,3);
- WFIFOW(fd,0) = 0x2af9;
- WFIFOB(fd,2) = 0;
- WFIFOSET(fd,3);
-
- server[i].fd = fd;
- server[i].ip = ntohl(RFIFOL(fd,54));
- server[i].port = ntohs(RFIFOW(fd,58));
- server[i].users = 0;
- memset(server[i].map, 0, sizeof(server[i].map));
- session[fd]->func_parse = parse_frommap;
- session[fd]->flag.server = 1;
- realloc_fifo(fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
- char_mapif_init(fd);
- }
-
- RFIFOSKIP(fd,60);
- }
- return 0; // avoid processing of followup packets here
-
- // unknown packet received
- default:
- ShowError("parse_char: Received unknown packet "CL_WHITE"0x%x"CL_RESET" from ip '"CL_WHITE"%s"CL_RESET"'! Disconnecting!\n", RFIFOW(fd,0), ip2str(ipl, NULL));
- set_eof(fd);
- return 0;
- }
- }
-
- RFIFOFLUSH(fd);
- return 0;
+ break;
+
+ // delete char
+ case 0x68:
+ // 2004-04-19aSakexe+ langtype 12 char deletion packet
+ case 0x1fb:
+ if (cmd == 0x68) FIFOSD_CHECK(46);
+ if (cmd == 0x1fb) FIFOSD_CHECK(56);
+ {
+ int cid = RFIFOL(fd,2);
+
+ ShowInfo(CL_RED"Request Char Deletion: "CL_GREEN"%d (%d)"CL_RESET"\n", sd->account_id, cid);
+ memcpy(email, RFIFOP(fd,6), 40);
+ RFIFOSKIP(fd,( cmd == 0x68) ? 46 : 56);
+
+ // Check if e-mail is correct
+ if(strcmpi(email, sd->email) && //email does not matches and
+ (
+ strcmp("a@a.com", sd->email) || //it is not default email, or
+ (strcmp("a@a.com", email) && strcmp("", email)) //email sent does not matches default
+ )) { //Fail
+ WFIFOHEAD(fd,3);
+ WFIFOW(fd,0) = 0x70;
+ WFIFOB(fd,2) = 0; // 00 = Incorrect Email address
+ WFIFOSET(fd,3);
+ break;
+ }
+
+ // check if this char exists
+ ARR_FIND( 0, MAX_CHARS, i, sd->found_char[i] == cid );
+ if( i == MAX_CHARS )
+ { // Such a character does not exist in the account
+ WFIFOHEAD(fd,3);
+ WFIFOW(fd,0) = 0x70;
+ WFIFOB(fd,2) = 0;
+ WFIFOSET(fd,3);
+ break;
+ }
+
+ // remove char from list and compact it
+ for(ch = i; ch < MAX_CHARS-1; ch++)
+ sd->found_char[ch] = sd->found_char[ch+1];
+ sd->found_char[MAX_CHARS-1] = -1;
+
+ /* Delete character */
+ if(delete_char_sql(cid)<0){
+ //can't delete the char
+ //either SQL error or can't delete by some CONFIG conditions
+ //del fail
+ WFIFOHEAD(fd,3);
+ WFIFOW(fd, 0) = 0x70;
+ WFIFOB(fd, 2) = 0;
+ WFIFOSET(fd, 3);
+ break;
+ }
+ /* Char successfully deleted.*/
+ WFIFOHEAD(fd,2);
+ WFIFOW(fd,0) = 0x6f;
+ WFIFOSET(fd,2);
+ }
+ break;
+
+ // client keep-alive packet (every 12 seconds)
+ // R 0187 <account ID>.l
+ case 0x187:
+ if (RFIFOREST(fd) < 6)
+ return 0;
+ RFIFOSKIP(fd,6);
+ break;
+
+ // char rename request
+ // R 028d <account ID>.l <char ID>.l <new name>.24B
+ case 0x28d:
+ FIFOSD_CHECK(34);
+ {
+ int i, aid = RFIFOL(fd,2), cid =RFIFOL(fd,6);
+ char name[NAME_LENGTH];
+ char esc_name[NAME_LENGTH*2+1];
+ safestrncpy(name, (char *)RFIFOP(fd,10), NAME_LENGTH);
+ RFIFOSKIP(fd,34);
+
+ if( aid != sd->account_id )
+ break;
+ ARR_FIND( 0, MAX_CHARS, i, sd->found_char[i] == cid );
+ if( i == MAX_CHARS )
+ break;
+
+ normalize_name(name,TRIM_CHARS);
+ Sql_EscapeStringLen(sql_handle, esc_name, name, strnlen(name, NAME_LENGTH));
+ if( !check_char_name(name,esc_name) )
+ {
+ i = 1;
+ safestrncpy(sd->new_name, name, NAME_LENGTH);
+ }
+ else
+ i = 0;
+
+ WFIFOHEAD(fd, 4);
+ WFIFOW(fd,0) = 0x28e;
+ WFIFOW(fd,2) = i;
+ WFIFOSET(fd,4);
+ }
+ break;
+ //Confirm change name.
+ // 0x28f <char_id>.L
+ case 0x28f:
+ // 0: Sucessfull
+ // 1: This character's name has already been changed. You cannot change a character's name more than once.
+ // 2: User information is not correct.
+ // 3: You have failed to change this character's name.
+ // 4: Another user is using this character name, so please select another one.
+ FIFOSD_CHECK(6);
+ {
+ int i;
+ int cid = RFIFOL(fd,2);
+ RFIFOSKIP(fd,6);
+
+ ARR_FIND( 0, MAX_CHARS, i, sd->found_char[i] == cid );
+ if( i == MAX_CHARS )
+ break;
+ i = rename_char_sql(sd, cid);
+
+ WFIFOHEAD(fd, 4);
+ WFIFOW(fd,0) = 0x290;
+ WFIFOW(fd,2) = i;
+ WFIFOSET(fd,4);
+ }
+ break;
+
+ // captcha code request (not implemented)
+ // R 07e5 <?>.w <aid>.l
+ case 0x7e5:
+ WFIFOHEAD(fd,5);
+ WFIFOW(fd,0) = 0x7e9;
+ WFIFOW(fd,2) = 5;
+ WFIFOB(fd,4) = 1;
+ WFIFOSET(fd,5);
+ RFIFOSKIP(fd,8);
+ break;
+
+ // captcha code check (not implemented)
+ // R 07e7 <len>.w <aid>.l <code>.b10 <?>.b14
+ case 0x7e7:
+ WFIFOHEAD(fd,5);
+ WFIFOW(fd,0) = 0x7e9;
+ WFIFOW(fd,2) = 5;
+ WFIFOB(fd,4) = 1;
+ WFIFOSET(fd,5);
+ RFIFOSKIP(fd,32);
+ break;
+
+ // deletion timer request
+ case 0x827:
+ FIFOSD_CHECK(6);
+ char_delete2_req(fd, sd);
+ RFIFOSKIP(fd,6);
+ break;
+
+ // deletion accept request
+ case 0x829:
+ FIFOSD_CHECK(12);
+ char_delete2_accept(fd, sd);
+ RFIFOSKIP(fd,12);
+ break;
+
+ // deletion cancel request
+ case 0x82b:
+ FIFOSD_CHECK(6);
+ char_delete2_cancel(fd, sd);
+ RFIFOSKIP(fd,6);
+ break;
+
+ // login as map-server
+ case 0x2af8:
+ if (RFIFOREST(fd) < 60)
+ return 0;
+ {
+ char* l_user = (char*)RFIFOP(fd,2);
+ char* l_pass = (char*)RFIFOP(fd,26);
+ l_user[23] = '\0';
+ l_pass[23] = '\0';
+ ARR_FIND( 0, ARRAYLENGTH(server), i, server[i].fd <= 0 );
+ if( runflag != CHARSERVER_ST_RUNNING ||
+ i == ARRAYLENGTH(server) ||
+ strcmp(l_user, userid) != 0 ||
+ strcmp(l_pass, passwd) != 0 )
+ {
+ WFIFOHEAD(fd,3);
+ WFIFOW(fd,0) = 0x2af9;
+ WFIFOB(fd,2) = 3;
+ WFIFOSET(fd,3);
+ } else {
+ WFIFOHEAD(fd,3);
+ WFIFOW(fd,0) = 0x2af9;
+ WFIFOB(fd,2) = 0;
+ WFIFOSET(fd,3);
+
+ server[i].fd = fd;
+ server[i].ip = ntohl(RFIFOL(fd,54));
+ server[i].port = ntohs(RFIFOW(fd,58));
+ server[i].users = 0;
+ memset(server[i].map, 0, sizeof(server[i].map));
+ session[fd]->func_parse = parse_frommap;
+ session[fd]->flag.server = 1;
+ realloc_fifo(fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
+ char_mapif_init(fd);
+ }
+
+ RFIFOSKIP(fd,60);
+ }
+ return 0; // avoid processing of followup packets here
+
+ // unknown packet received
+ default:
+ ShowError("parse_char: Received unknown packet "CL_WHITE"0x%x"CL_RESET" from ip '"CL_WHITE"%s"CL_RESET"'! Disconnecting!\n", RFIFOW(fd,0), ip2str(ipl, NULL));
+ set_eof(fd);
+ return 0;
+ }
+ }
+
+ RFIFOFLUSH(fd);
+ return 0;
}
// Console Command Parser [Wizputer]
-int parse_console(const char *command)
+int parse_console(const char* command)
{
- ShowNotice("Console command: %s\n", command);
-
- if (strcmpi("shutdown", command) == 0 || strcmpi("exit", command) == 0 || strcmpi("quit", command) == 0 || strcmpi("end", command) == 0)
- runflag = 0;
- else if (strcmpi("alive", command) == 0 || strcmpi("status", command) == 0)
- ShowInfo(CL_CYAN"Console: "CL_BOLD"I'm Alive."CL_RESET"\n");
- else if (strcmpi("help", command) == 0) {
- ShowInfo("To shutdown the server:\n");
- ShowInfo(" 'shutdown|exit|quit|end'\n");
- ShowInfo("To know if server is alive:\n");
- ShowInfo(" 'alive|status'\n");
- }
-
- return 0;
+ ShowNotice("Console command: %s\n", command);
+
+ if( strcmpi("shutdown", command) == 0 || strcmpi("exit", command) == 0 || strcmpi("quit", command) == 0 || strcmpi("end", command) == 0 )
+ runflag = 0;
+ else if( strcmpi("alive", command) == 0 || strcmpi("status", command) == 0 )
+ ShowInfo(CL_CYAN"Console: "CL_BOLD"I'm Alive."CL_RESET"\n");
+ else if( strcmpi("help", command) == 0 )
+ {
+ ShowInfo("To shutdown the server:\n");
+ ShowInfo(" 'shutdown|exit|quit|end'\n");
+ ShowInfo("To know if server is alive:\n");
+ ShowInfo(" 'alive|status'\n");
+ }
+
+ return 0;
}
int mapif_sendall(unsigned char *buf, unsigned int len)
{
- int i, c;
-
- c = 0;
- for (i = 0; i < ARRAYLENGTH(server); i++) {
- int fd;
- if ((fd = server[i].fd) > 0) {
- WFIFOHEAD(fd,len);
- memcpy(WFIFOP(fd,0), buf, len);
- WFIFOSET(fd,len);
- c++;
- }
- }
-
- return c;
+ int i, c;
+
+ c = 0;
+ for(i = 0; i < ARRAYLENGTH(server); i++) {
+ int fd;
+ if ((fd = server[i].fd) > 0) {
+ WFIFOHEAD(fd,len);
+ memcpy(WFIFOP(fd,0), buf, len);
+ WFIFOSET(fd,len);
+ c++;
+ }
+ }
+
+ return c;
}
int mapif_sendallwos(int sfd, unsigned char *buf, unsigned int len)
{
- int i, c;
-
- c = 0;
- for (i = 0; i < ARRAYLENGTH(server); i++) {
- int fd;
- if ((fd = server[i].fd) > 0 && fd != sfd) {
- WFIFOHEAD(fd,len);
- memcpy(WFIFOP(fd,0), buf, len);
- WFIFOSET(fd,len);
- c++;
- }
- }
-
- return c;
+ int i, c;
+
+ c = 0;
+ for(i = 0; i < ARRAYLENGTH(server); i++) {
+ int fd;
+ if ((fd = server[i].fd) > 0 && fd != sfd) {
+ WFIFOHEAD(fd,len);
+ memcpy(WFIFOP(fd,0), buf, len);
+ WFIFOSET(fd,len);
+ c++;
+ }
+ }
+
+ return c;
}
int mapif_send(int fd, unsigned char *buf, unsigned int len)
{
- if (fd >= 0) {
- int i;
- ARR_FIND(0, ARRAYLENGTH(server), i, fd == server[i].fd);
- if (i < ARRAYLENGTH(server)) {
- WFIFOHEAD(fd,len);
- memcpy(WFIFOP(fd,0), buf, len);
- WFIFOSET(fd,len);
- return 1;
- }
- }
- return 0;
+ if (fd >= 0) {
+ int i;
+ ARR_FIND( 0, ARRAYLENGTH(server), i, fd == server[i].fd );
+ if( i < ARRAYLENGTH(server) )
+ {
+ WFIFOHEAD(fd,len);
+ memcpy(WFIFOP(fd,0), buf, len);
+ WFIFOSET(fd,len);
+ return 1;
+ }
+ }
+ return 0;
}
int broadcast_user_count(int tid, unsigned int tick, int id, intptr_t data)
{
- uint8 buf[6];
- int users = count_users();
-
- // only send an update when needed
- static int prev_users = 0;
- if (prev_users == users)
- return 0;
- prev_users = users;
-
- if (login_fd > 0 && session[login_fd]) {
- // send number of user to login server
- WFIFOHEAD(login_fd,6);
- 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;
+ uint8 buf[6];
+ int users = count_users();
+
+ // only send an update when needed
+ static int prev_users = 0;
+ if( prev_users == users )
+ return 0;
+ prev_users = users;
+
+ if( login_fd > 0 && session[login_fd] )
+ {
+ // send number of user to login server
+ WFIFOHEAD(login_fd,6);
+ 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;
}
/**
@@ -4183,64 +4236,66 @@ int broadcast_user_count(int tid, unsigned int tick, int id, intptr_t data)
*/
static int send_accounts_tologin_sub(DBKey key, DBData *data, va_list ap)
{
- struct online_char_data *character = db_data2ptr(data);
- int *i = va_arg(ap, int *);
-
- if (character->server > -1) {
- WFIFOL(login_fd,8+(*i)*4) = character->account_id;
- (*i)++;
- return 1;
- }
- return 0;
+ struct online_char_data* character = db_data2ptr(data);
+ int* i = va_arg(ap, int*);
+
+ if(character->server > -1)
+ {
+ WFIFOL(login_fd,8+(*i)*4) = character->account_id;
+ (*i)++;
+ return 1;
+ }
+ return 0;
}
int send_accounts_tologin(int tid, unsigned int tick, int id, intptr_t data)
{
- if (login_fd > 0 && session[login_fd]) {
- // send account list to login server
- int users = online_char_db->size(online_char_db);
- int i = 0;
-
- WFIFOHEAD(login_fd,8+users*4);
- WFIFOW(login_fd,0) = 0x272d;
- online_char_db->foreach(online_char_db, send_accounts_tologin_sub, &i, users);
- WFIFOW(login_fd,2) = 8+ i*4;
- WFIFOL(login_fd,4) = i;
- WFIFOSET(login_fd,WFIFOW(login_fd,2));
- }
- return 0;
+ if (login_fd > 0 && session[login_fd])
+ {
+ // send account list to login server
+ int users = online_char_db->size(online_char_db);
+ int i = 0;
+
+ WFIFOHEAD(login_fd,8+users*4);
+ WFIFOW(login_fd,0) = 0x272d;
+ online_char_db->foreach(online_char_db, send_accounts_tologin_sub, &i, users);
+ WFIFOW(login_fd,2) = 8+ i*4;
+ WFIFOL(login_fd,4) = i;
+ WFIFOSET(login_fd,WFIFOW(login_fd,2));
+ }
+ return 0;
}
int check_connect_login_server(int tid, unsigned int tick, int id, intptr_t data)
{
- if (login_fd > 0 && session[login_fd] != NULL)
- return 0;
-
- ShowInfo("Attempt to connect to login-server...\n");
- login_fd = make_connection(login_ip, login_port, false);
- if (login_fd == -1) {
- //Try again later. [Skotlex]
- login_fd = 0;
- return 0;
- }
- session[login_fd]->func_parse = parse_fromlogin;
- session[login_fd]->flag.server = 1;
- realloc_fifo(login_fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
-
- WFIFOHEAD(login_fd,86);
- WFIFOW(login_fd,0) = 0x2710;
- memcpy(WFIFOP(login_fd,2), userid, 24);
- memcpy(WFIFOP(login_fd,26), passwd, 24);
- WFIFOL(login_fd,50) = 0;
- WFIFOL(login_fd,54) = htonl(char_ip);
- WFIFOW(login_fd,58) = htons(char_port);
- memcpy(WFIFOP(login_fd,60), server_name, 20);
- WFIFOW(login_fd,80) = 0;
- WFIFOW(login_fd,82) = char_maintenance;
- WFIFOW(login_fd,84) = char_new_display; //only display (New) if they want to [Kevin]
- WFIFOSET(login_fd,86);
-
- return 1;
+ if (login_fd > 0 && session[login_fd] != NULL)
+ return 0;
+
+ ShowInfo("Attempt to connect to login-server...\n");
+ login_fd = make_connection(login_ip, login_port, false);
+ if (login_fd == -1)
+ { //Try again later. [Skotlex]
+ login_fd = 0;
+ return 0;
+ }
+ session[login_fd]->func_parse = parse_fromlogin;
+ session[login_fd]->flag.server = 1;
+ realloc_fifo(login_fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
+
+ WFIFOHEAD(login_fd,86);
+ WFIFOW(login_fd,0) = 0x2710;
+ memcpy(WFIFOP(login_fd,2), userid, 24);
+ memcpy(WFIFOP(login_fd,26), passwd, 24);
+ WFIFOL(login_fd,50) = 0;
+ WFIFOL(login_fd,54) = htonl(char_ip);
+ WFIFOW(login_fd,58) = htons(char_port);
+ memcpy(WFIFOP(login_fd,60), server_name, 20);
+ WFIFOW(login_fd,80) = 0;
+ WFIFOW(login_fd,82) = char_maintenance;
+ WFIFOW(login_fd,84) = char_new_display; //only display (New) if they want to [Kevin]
+ WFIFOSET(login_fd,86);
+
+ return 1;
}
//------------------------------------------------
@@ -4249,13 +4304,13 @@ int check_connect_login_server(int tid, unsigned int tick, int id, intptr_t data
//------------------------------------------------
static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr_t data)
{
- struct online_char_data *character;
- if ((character = (struct online_char_data *)idb_get(online_char_db, id)) != NULL && character->waiting_disconnect == tid) {
- //Mark it offline due to timeout.
- character->waiting_disconnect = INVALID_TIMER;
- set_char_offline(character->char_id, character->account_id);
- }
- return 0;
+ struct online_char_data* character;
+ if ((character = (struct online_char_data*)idb_get(online_char_db, id)) != NULL && character->waiting_disconnect == tid)
+ { //Mark it offline due to timeout.
+ character->waiting_disconnect = INVALID_TIMER;
+ set_char_offline(character->char_id, character->account_id);
+ }
+ return 0;
}
/**
@@ -4263,21 +4318,21 @@ static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr_
*/
static int online_data_cleanup_sub(DBKey key, DBData *data, va_list ap)
{
- struct online_char_data *character= db_data2ptr(data);
- if (character->fd != -1)
- return 0; //Character still connected
- if (character->server == -2) //Unknown server.. set them offline
- set_char_offline(character->char_id, character->account_id);
- if (character->server < 0)
- //Free data from players that have not been online for a while.
- db_remove(online_char_db, key);
- return 0;
+ struct online_char_data *character= db_data2ptr(data);
+ if (character->fd != -1)
+ return 0; //Character still connected
+ if (character->server == -2) //Unknown server.. set them offline
+ set_char_offline(character->char_id, character->account_id);
+ if (character->server < 0)
+ //Free data from players that have not been online for a while.
+ db_remove(online_char_db, key);
+ return 0;
}
static int online_data_cleanup(int tid, unsigned int tick, int id, intptr_t data)
{
- online_char_db->foreach(online_char_db, online_data_cleanup_sub);
- return 0;
+ online_char_db->foreach(online_char_db, online_data_cleanup_sub);
+ return 0;
}
//----------------------------------
@@ -4286,323 +4341,327 @@ static int online_data_cleanup(int tid, unsigned int tick, int id, intptr_t data
//----------------------------------
int char_lan_config_read(const char *lancfgName)
{
- FILE *fp;
- int line_num = 0;
- char line[1024], w1[64], w2[64], w3[64], w4[64];
-
- if ((fp = fopen(lancfgName, "r")) == NULL) {
- ShowWarning("LAN Support configuration file is not found: %s\n", lancfgName);
- return 1;
- }
-
- while (fgets(line, sizeof(line), fp)) {
- line_num++;
- if ((line[0] == '/' && line[1] == '/') || line[0] == '\n' || line[1] == '\n')
- continue;
-
- if (sscanf(line,"%[^:]: %[^:]:%[^:]:%[^\r\n]", w1, w2, w3, w4) != 4) {
-
- ShowWarning("Error syntax of configuration file %s in line %d.\n", lancfgName, line_num);
- continue;
- }
-
- remove_control_chars(w1);
- remove_control_chars(w2);
- remove_control_chars(w3);
- remove_control_chars(w4);
-
- if (strcmpi(w1, "subnet") == 0) {
- subnet[subnet_count].mask = str2ip(w2);
- subnet[subnet_count].char_ip = str2ip(w3);
- subnet[subnet_count].map_ip = str2ip(w4);
-
- if ((subnet[subnet_count].char_ip & subnet[subnet_count].mask) != (subnet[subnet_count].map_ip & subnet[subnet_count].mask)) {
- ShowError("%s: Configuration Error: The char server (%s) and map server (%s) belong to different subnetworks!\n", lancfgName, w3, w4);
- continue;
- }
-
- subnet_count++;
- }
- }
-
- if (subnet_count > 1) /* only useful if there is more than 1 */
- ShowStatus("Read information about %d subnetworks.\n", subnet_count);
-
- fclose(fp);
- return 0;
+ FILE *fp;
+ int line_num = 0;
+ char line[1024], w1[64], w2[64], w3[64], w4[64];
+
+ if((fp = fopen(lancfgName, "r")) == NULL) {
+ ShowWarning("LAN Support configuration file is not found: %s\n", lancfgName);
+ return 1;
+ }
+
+ while(fgets(line, sizeof(line), fp)) {
+ line_num++;
+ if ((line[0] == '/' && line[1] == '/') || line[0] == '\n' || line[1] == '\n')
+ continue;
+
+ if(sscanf(line,"%[^:]: %[^:]:%[^:]:%[^\r\n]", w1, w2, w3, w4) != 4) {
+
+ ShowWarning("Error syntax of configuration file %s in line %d.\n", lancfgName, line_num);
+ continue;
+ }
+
+ remove_control_chars(w1);
+ remove_control_chars(w2);
+ remove_control_chars(w3);
+ remove_control_chars(w4);
+
+ if( strcmpi(w1, "subnet") == 0 )
+ {
+ subnet[subnet_count].mask = str2ip(w2);
+ subnet[subnet_count].char_ip = str2ip(w3);
+ subnet[subnet_count].map_ip = str2ip(w4);
+
+ if( (subnet[subnet_count].char_ip & subnet[subnet_count].mask) != (subnet[subnet_count].map_ip & subnet[subnet_count].mask) )
+ {
+ ShowError("%s: Configuration Error: The char server (%s) and map server (%s) belong to different subnetworks!\n", lancfgName, w3, w4);
+ continue;
+ }
+
+ subnet_count++;
+ }
+ }
+
+ if( subnet_count > 1 ) /* only useful if there is more than 1 */
+ ShowStatus("Read information about %d subnetworks.\n", subnet_count);
+
+ fclose(fp);
+ return 0;
}
-void sql_config_read(const char *cfgName)
+void sql_config_read(const char* cfgName)
{
- char line[1024], w1[1024], w2[1024];
- FILE *fp;
-
- if ((fp = fopen(cfgName, "r")) == NULL) {
- ShowError("File not found: %s\n", cfgName);
- return;
- }
-
- while (fgets(line, sizeof(line), fp)) {
- if (line[0] == '/' && line[1] == '/')
- continue;
-
- if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) != 2)
- continue;
-
- if (!strcmpi(w1,"char_db"))
- safestrncpy(char_db, w2, sizeof(char_db));
- else if (!strcmpi(w1,"scdata_db"))
- safestrncpy(scdata_db, w2, sizeof(scdata_db));
- else if (!strcmpi(w1,"cart_db"))
- safestrncpy(cart_db, w2, sizeof(cart_db));
- else if (!strcmpi(w1,"inventory_db"))
- safestrncpy(inventory_db, w2, sizeof(inventory_db));
- else if (!strcmpi(w1,"charlog_db"))
- safestrncpy(charlog_db, w2, sizeof(charlog_db));
- else if (!strcmpi(w1,"storage_db"))
- safestrncpy(storage_db, w2, sizeof(storage_db));
- else if (!strcmpi(w1,"reg_db"))
- safestrncpy(reg_db, w2, sizeof(reg_db));
- else if (!strcmpi(w1,"skill_db"))
- safestrncpy(skill_db, w2, sizeof(skill_db));
- else if (!strcmpi(w1,"interlog_db"))
- safestrncpy(interlog_db, w2, sizeof(interlog_db));
- else if (!strcmpi(w1,"memo_db"))
- safestrncpy(memo_db, w2, sizeof(memo_db));
- else if (!strcmpi(w1,"guild_db"))
- safestrncpy(guild_db, w2, sizeof(guild_db));
- else if (!strcmpi(w1,"guild_alliance_db"))
- safestrncpy(guild_alliance_db, w2, sizeof(guild_alliance_db));
- else if (!strcmpi(w1,"guild_castle_db"))
- safestrncpy(guild_castle_db, w2, sizeof(guild_castle_db));
- else if (!strcmpi(w1,"guild_expulsion_db"))
- safestrncpy(guild_expulsion_db, w2, sizeof(guild_expulsion_db));
- else if (!strcmpi(w1,"guild_member_db"))
- safestrncpy(guild_member_db, w2, sizeof(guild_member_db));
- else if (!strcmpi(w1,"guild_skill_db"))
- safestrncpy(guild_skill_db, w2, sizeof(guild_skill_db));
- else if (!strcmpi(w1,"guild_position_db"))
- safestrncpy(guild_position_db, w2, sizeof(guild_position_db));
- else if (!strcmpi(w1,"guild_storage_db"))
- safestrncpy(guild_storage_db, w2, sizeof(guild_storage_db));
- else if (!strcmpi(w1,"party_db"))
- safestrncpy(party_db, w2, sizeof(party_db));
- else if (!strcmpi(w1,"pet_db"))
- safestrncpy(pet_db, w2, sizeof(pet_db));
- else if (!strcmpi(w1,"mail_db"))
- safestrncpy(mail_db, w2, sizeof(mail_db));
- else if (!strcmpi(w1,"auction_db"))
- safestrncpy(auction_db, w2, sizeof(auction_db));
- else if (!strcmpi(w1,"friend_db"))
- safestrncpy(friend_db, w2, sizeof(friend_db));
- else if (!strcmpi(w1,"hotkey_db"))
- safestrncpy(hotkey_db, w2, sizeof(hotkey_db));
- else if (!strcmpi(w1,"quest_db"))
- safestrncpy(quest_db,w2,sizeof(quest_db));
- else if (!strcmpi(w1,"homunculus_db"))
- safestrncpy(homunculus_db,w2,sizeof(homunculus_db));
- else if (!strcmpi(w1,"skill_homunculus_db"))
- safestrncpy(skill_homunculus_db,w2,sizeof(skill_homunculus_db));
- else if (!strcmpi(w1,"mercenary_db"))
- safestrncpy(mercenary_db,w2,sizeof(mercenary_db));
- else if (!strcmpi(w1,"mercenary_owner_db"))
- safestrncpy(mercenary_owner_db,w2,sizeof(mercenary_owner_db));
- //support the import command, just like any other config
- else if (!strcmpi(w1,"import"))
- sql_config_read(w2);
- }
- fclose(fp);
- ShowInfo("Done reading %s.\n", cfgName);
+ char line[1024], w1[1024], w2[1024];
+ FILE* fp;
+
+ if ((fp = fopen(cfgName, "r")) == NULL) {
+ ShowError("File not found: %s\n", cfgName);
+ return;
+ }
+
+ while(fgets(line, sizeof(line), fp))
+ {
+ if(line[0] == '/' && line[1] == '/')
+ continue;
+
+ if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) != 2)
+ continue;
+
+ if(!strcmpi(w1,"char_db"))
+ safestrncpy(char_db, w2, sizeof(char_db));
+ else if(!strcmpi(w1,"scdata_db"))
+ safestrncpy(scdata_db, w2, sizeof(scdata_db));
+ else if(!strcmpi(w1,"cart_db"))
+ safestrncpy(cart_db, w2, sizeof(cart_db));
+ else if(!strcmpi(w1,"inventory_db"))
+ safestrncpy(inventory_db, w2, sizeof(inventory_db));
+ else if(!strcmpi(w1,"charlog_db"))
+ safestrncpy(charlog_db, w2, sizeof(charlog_db));
+ else if(!strcmpi(w1,"storage_db"))
+ safestrncpy(storage_db, w2, sizeof(storage_db));
+ else if(!strcmpi(w1,"reg_db"))
+ safestrncpy(reg_db, w2, sizeof(reg_db));
+ else if(!strcmpi(w1,"skill_db"))
+ safestrncpy(skill_db, w2, sizeof(skill_db));
+ else if(!strcmpi(w1,"interlog_db"))
+ safestrncpy(interlog_db, w2, sizeof(interlog_db));
+ else if(!strcmpi(w1,"memo_db"))
+ safestrncpy(memo_db, w2, sizeof(memo_db));
+ else if(!strcmpi(w1,"guild_db"))
+ safestrncpy(guild_db, w2, sizeof(guild_db));
+ else if(!strcmpi(w1,"guild_alliance_db"))
+ safestrncpy(guild_alliance_db, w2, sizeof(guild_alliance_db));
+ else if(!strcmpi(w1,"guild_castle_db"))
+ safestrncpy(guild_castle_db, w2, sizeof(guild_castle_db));
+ else if(!strcmpi(w1,"guild_expulsion_db"))
+ safestrncpy(guild_expulsion_db, w2, sizeof(guild_expulsion_db));
+ else if(!strcmpi(w1,"guild_member_db"))
+ safestrncpy(guild_member_db, w2, sizeof(guild_member_db));
+ else if(!strcmpi(w1,"guild_skill_db"))
+ safestrncpy(guild_skill_db, w2, sizeof(guild_skill_db));
+ else if(!strcmpi(w1,"guild_position_db"))
+ safestrncpy(guild_position_db, w2, sizeof(guild_position_db));
+ else if(!strcmpi(w1,"guild_storage_db"))
+ safestrncpy(guild_storage_db, w2, sizeof(guild_storage_db));
+ else if(!strcmpi(w1,"party_db"))
+ safestrncpy(party_db, w2, sizeof(party_db));
+ else if(!strcmpi(w1,"pet_db"))
+ safestrncpy(pet_db, w2, sizeof(pet_db));
+ else if(!strcmpi(w1,"mail_db"))
+ safestrncpy(mail_db, w2, sizeof(mail_db));
+ else if(!strcmpi(w1,"auction_db"))
+ safestrncpy(auction_db, w2, sizeof(auction_db));
+ else if(!strcmpi(w1,"friend_db"))
+ safestrncpy(friend_db, w2, sizeof(friend_db));
+ else if(!strcmpi(w1,"hotkey_db"))
+ safestrncpy(hotkey_db, w2, sizeof(hotkey_db));
+ else if(!strcmpi(w1,"quest_db"))
+ safestrncpy(quest_db,w2,sizeof(quest_db));
+ else if(!strcmpi(w1,"homunculus_db"))
+ safestrncpy(homunculus_db,w2,sizeof(homunculus_db));
+ else if(!strcmpi(w1,"skill_homunculus_db"))
+ safestrncpy(skill_homunculus_db,w2,sizeof(skill_homunculus_db));
+ else if(!strcmpi(w1,"mercenary_db"))
+ safestrncpy(mercenary_db,w2,sizeof(mercenary_db));
+ else if(!strcmpi(w1,"mercenary_owner_db"))
+ safestrncpy(mercenary_owner_db,w2,sizeof(mercenary_owner_db));
+ //support the import command, just like any other config
+ else if(!strcmpi(w1,"import"))
+ sql_config_read(w2);
+ }
+ fclose(fp);
+ ShowInfo("Done reading %s.\n", cfgName);
}
-int char_config_read(const char *cfgName)
+int char_config_read(const char* cfgName)
{
- char line[1024], w1[1024], w2[1024];
- FILE *fp = fopen(cfgName, "r");
-
- if (fp == NULL) {
- ShowError("Configuration file not found: %s.\n", cfgName);
- return 1;
- }
-
- while (fgets(line, sizeof(line), fp)) {
- if (line[0] == '/' && line[1] == '/')
- continue;
-
- if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) != 2)
- continue;
-
- remove_control_chars(w1);
- remove_control_chars(w2);
- if (strcmpi(w1,"timestamp_format") == 0) {
- safestrncpy(timestamp_format, w2, sizeof(timestamp_format));
- } else if (strcmpi(w1,"console_silent")==0) {
- msg_silent = atoi(w2);
- if (msg_silent) /* only bother if its actually enabled */
- ShowInfo("Console Silent Setting: %d\n", atoi(w2));
- } else if (strcmpi(w1,"stdout_with_ansisequence")==0) {
- stdout_with_ansisequence = config_switch(w2);
- } else if (strcmpi(w1, "userid") == 0) {
- safestrncpy(userid, w2, sizeof(userid));
- } else if (strcmpi(w1, "passwd") == 0) {
- safestrncpy(passwd, w2, sizeof(passwd));
- } else if (strcmpi(w1, "server_name") == 0) {
- safestrncpy(server_name, w2, sizeof(server_name));
- } else if (strcmpi(w1, "wisp_server_name") == 0) {
- if (strlen(w2) >= 4) {
- safestrncpy(wisp_server_name, w2, sizeof(wisp_server_name));
- }
- } else if (strcmpi(w1, "login_ip") == 0) {
- char ip_str[16];
- login_ip = host2ip(w2);
- if (login_ip) {
- safestrncpy(login_ip_str, w2, sizeof(login_ip_str));
- ShowStatus("Login server IP address : %s -> %s\n", w2, ip2str(login_ip, ip_str));
- }
- } else if (strcmpi(w1, "login_port") == 0) {
- login_port = atoi(w2);
- } else if (strcmpi(w1, "char_ip") == 0) {
- char ip_str[16];
- char_ip = host2ip(w2);
- if (char_ip) {
- safestrncpy(char_ip_str, w2, sizeof(char_ip_str));
- ShowStatus("Character server IP address : %s -> %s\n", w2, ip2str(char_ip, ip_str));
- }
- } else if (strcmpi(w1, "bind_ip") == 0) {
- char ip_str[16];
- bind_ip = host2ip(w2);
- if (bind_ip) {
- safestrncpy(bind_ip_str, w2, sizeof(bind_ip_str));
- ShowStatus("Character server binding IP address : %s -> %s\n", w2, ip2str(bind_ip, ip_str));
- }
- } else if (strcmpi(w1, "char_port") == 0) {
- char_port = atoi(w2);
- } else if (strcmpi(w1, "char_maintenance") == 0) {
- char_maintenance = atoi(w2);
- } else if (strcmpi(w1, "char_new") == 0) {
- char_new = (bool)atoi(w2);
- } else if (strcmpi(w1, "char_new_display") == 0) {
- char_new_display = atoi(w2);
- } else if (strcmpi(w1, "max_connect_user") == 0) {
- max_connect_user = atoi(w2);
- if (max_connect_user < 0)
- max_connect_user = 0; // unlimited online players
- } else if (strcmpi(w1, "gm_allow_group") == 0) {
- gm_allow_group = atoi(w2);
- } else if (strcmpi(w1, "autosave_time") == 0) {
- autosave_interval = atoi(w2)*1000;
- if (autosave_interval <= 0)
- autosave_interval = DEFAULT_AUTOSAVE_INTERVAL;
- } else if (strcmpi(w1, "save_log") == 0) {
- save_log = config_switch(w2);
- } else if (strcmpi(w1, "start_point") == 0) {
- char map[MAP_NAME_LENGTH_EXT];
- int x, y;
- if (sscanf(w2, "%15[^,],%d,%d", map, &x, &y) < 3)
- continue;
- start_point.map = mapindex_name2id(map);
- if (!start_point.map)
- ShowError("Specified start_point %s not found in map-index cache.\n", map);
- start_point.x = x;
- start_point.y = y;
- } else if (strcmpi(w1, "start_zeny") == 0) {
- start_zeny = atoi(w2);
- if (start_zeny < 0)
- start_zeny = 0;
- } else if (strcmpi(w1, "start_weapon") == 0) {
- start_weapon = atoi(w2);
- if (start_weapon < 0)
- start_weapon = 0;
- } else if (strcmpi(w1, "start_armor") == 0) {
- start_armor = atoi(w2);
- if (start_armor < 0)
- start_armor = 0;
- } else if (strcmpi(w1,"log_char")==0) { //log char or not [devil]
- log_char = atoi(w2);
- } else if (strcmpi(w1, "unknown_char_name") == 0) {
- safestrncpy(unknown_char_name, w2, sizeof(unknown_char_name));
- unknown_char_name[NAME_LENGTH-1] = '\0';
- } else if (strcmpi(w1, "name_ignoring_case") == 0) {
- name_ignoring_case = (bool)config_switch(w2);
- } else if (strcmpi(w1, "char_name_option") == 0) {
- char_name_option = atoi(w2);
- } else if (strcmpi(w1, "char_name_letters") == 0) {
- safestrncpy(char_name_letters, w2, sizeof(char_name_letters));
- } else if (strcmpi(w1, "chars_per_account") == 0) { //maxchars per account [Sirius]
- char_per_account = atoi(w2);
- if (char_per_account == 0 || char_per_account > MAX_CHARS) {
- if (char_per_account > MAX_CHARS)
- ShowWarning("Max chars per account '%d' exceeded limit. Defaulting to '%d'.\n", char_per_account, MAX_CHARS);
- char_per_account = MAX_CHARS;
- }
- } else if (strcmpi(w1, "char_del_level") == 0) { //disable/enable char deletion by its level condition [Lupus]
- char_del_level = atoi(w2);
- } else if (strcmpi(w1, "char_del_delay") == 0) {
- char_del_delay = atoi(w2);
- } else if (strcmpi(w1,"db_path")==0) {
- safestrncpy(db_path, w2, sizeof(db_path));
- } else if (strcmpi(w1, "console") == 0) {
- console = config_switch(w2);
- } else if (strcmpi(w1, "fame_list_alchemist") == 0) {
- fame_list_size_chemist = atoi(w2);
- if (fame_list_size_chemist > MAX_FAME_LIST) {
- ShowWarning("Max fame list size is %d (fame_list_alchemist)\n", MAX_FAME_LIST);
- fame_list_size_chemist = MAX_FAME_LIST;
- }
- } else if (strcmpi(w1, "fame_list_blacksmith") == 0) {
- fame_list_size_smith = atoi(w2);
- if (fame_list_size_smith > MAX_FAME_LIST) {
- ShowWarning("Max fame list size is %d (fame_list_blacksmith)\n", MAX_FAME_LIST);
- fame_list_size_smith = MAX_FAME_LIST;
- }
- } else if (strcmpi(w1, "fame_list_taekwon") == 0) {
- fame_list_size_taekwon = atoi(w2);
- if (fame_list_size_taekwon > MAX_FAME_LIST) {
- ShowWarning("Max fame list size is %d (fame_list_taekwon)\n", MAX_FAME_LIST);
- fame_list_size_taekwon = MAX_FAME_LIST;
- }
- } else if (strcmpi(w1, "guild_exp_rate") == 0) {
- guild_exp_rate = atoi(w2);
- } else if (strcmpi(w1, "import") == 0) {
- char_config_read(w2);
- }
- }
- fclose(fp);
-
- ShowInfo("Done reading %s.\n", cfgName);
- return 0;
+ char line[1024], w1[1024], w2[1024];
+ FILE* fp = fopen(cfgName, "r");
+
+ if (fp == NULL) {
+ ShowError("Configuration file not found: %s.\n", cfgName);
+ return 1;
+ }
+
+ while(fgets(line, sizeof(line), fp)) {
+ if (line[0] == '/' && line[1] == '/')
+ continue;
+
+ if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) != 2)
+ continue;
+
+ remove_control_chars(w1);
+ remove_control_chars(w2);
+ if(strcmpi(w1,"timestamp_format") == 0) {
+ safestrncpy(timestamp_format, w2, sizeof(timestamp_format));
+ } else if(strcmpi(w1,"console_silent")==0){
+ msg_silent = atoi(w2);
+ if( msg_silent ) /* only bother if its actually enabled */
+ ShowInfo("Console Silent Setting: %d\n", atoi(w2));
+ } else if(strcmpi(w1,"stdout_with_ansisequence")==0){
+ stdout_with_ansisequence = config_switch(w2);
+ } else if (strcmpi(w1, "userid") == 0) {
+ safestrncpy(userid, w2, sizeof(userid));
+ } else if (strcmpi(w1, "passwd") == 0) {
+ safestrncpy(passwd, w2, sizeof(passwd));
+ } else if (strcmpi(w1, "server_name") == 0) {
+ safestrncpy(server_name, w2, sizeof(server_name));
+ } else if (strcmpi(w1, "wisp_server_name") == 0) {
+ if (strlen(w2) >= 4) {
+ safestrncpy(wisp_server_name, w2, sizeof(wisp_server_name));
+ }
+ } else if (strcmpi(w1, "login_ip") == 0) {
+ char ip_str[16];
+ login_ip = host2ip(w2);
+ if (login_ip) {
+ safestrncpy(login_ip_str, w2, sizeof(login_ip_str));
+ ShowStatus("Login server IP address : %s -> %s\n", w2, ip2str(login_ip, ip_str));
+ }
+ } else if (strcmpi(w1, "login_port") == 0) {
+ login_port = atoi(w2);
+ } else if (strcmpi(w1, "char_ip") == 0) {
+ char ip_str[16];
+ char_ip = host2ip(w2);
+ if (char_ip){
+ safestrncpy(char_ip_str, w2, sizeof(char_ip_str));
+ ShowStatus("Character server IP address : %s -> %s\n", w2, ip2str(char_ip, ip_str));
+ }
+ } else if (strcmpi(w1, "bind_ip") == 0) {
+ char ip_str[16];
+ bind_ip = host2ip(w2);
+ if (bind_ip) {
+ safestrncpy(bind_ip_str, w2, sizeof(bind_ip_str));
+ ShowStatus("Character server binding IP address : %s -> %s\n", w2, ip2str(bind_ip, ip_str));
+ }
+ } else if (strcmpi(w1, "char_port") == 0) {
+ char_port = atoi(w2);
+ } else if (strcmpi(w1, "char_maintenance") == 0) {
+ char_maintenance = atoi(w2);
+ } else if (strcmpi(w1, "char_new") == 0) {
+ char_new = (bool)atoi(w2);
+ } else if (strcmpi(w1, "char_new_display") == 0) {
+ char_new_display = atoi(w2);
+ } else if (strcmpi(w1, "max_connect_user") == 0) {
+ max_connect_user = atoi(w2);
+ if (max_connect_user < 0)
+ max_connect_user = 0; // unlimited online players
+ } else if(strcmpi(w1, "gm_allow_group") == 0) {
+ gm_allow_group = atoi(w2);
+ } else if (strcmpi(w1, "autosave_time") == 0) {
+ autosave_interval = atoi(w2)*1000;
+ if (autosave_interval <= 0)
+ autosave_interval = DEFAULT_AUTOSAVE_INTERVAL;
+ } else if (strcmpi(w1, "save_log") == 0) {
+ save_log = config_switch(w2);
+ } else if (strcmpi(w1, "start_point") == 0) {
+ char map[MAP_NAME_LENGTH_EXT];
+ int x, y;
+ if (sscanf(w2, "%15[^,],%d,%d", map, &x, &y) < 3)
+ continue;
+ start_point.map = mapindex_name2id(map);
+ if (!start_point.map)
+ ShowError("Specified start_point %s not found in map-index cache.\n", map);
+ start_point.x = x;
+ start_point.y = y;
+ } else if (strcmpi(w1, "start_zeny") == 0) {
+ start_zeny = atoi(w2);
+ if (start_zeny < 0)
+ start_zeny = 0;
+ } else if (strcmpi(w1, "start_weapon") == 0) {
+ start_weapon = atoi(w2);
+ if (start_weapon < 0)
+ start_weapon = 0;
+ } else if (strcmpi(w1, "start_armor") == 0) {
+ start_armor = atoi(w2);
+ if (start_armor < 0)
+ start_armor = 0;
+ } else if(strcmpi(w1,"log_char")==0) { //log char or not [devil]
+ log_char = atoi(w2);
+ } else if (strcmpi(w1, "unknown_char_name") == 0) {
+ safestrncpy(unknown_char_name, w2, sizeof(unknown_char_name));
+ unknown_char_name[NAME_LENGTH-1] = '\0';
+ } else if (strcmpi(w1, "name_ignoring_case") == 0) {
+ name_ignoring_case = (bool)config_switch(w2);
+ } else if (strcmpi(w1, "char_name_option") == 0) {
+ char_name_option = atoi(w2);
+ } else if (strcmpi(w1, "char_name_letters") == 0) {
+ safestrncpy(char_name_letters, w2, sizeof(char_name_letters));
+ } else if (strcmpi(w1, "chars_per_account") == 0) { //maxchars per account [Sirius]
+ char_per_account = atoi(w2);
+ if( char_per_account == 0 || char_per_account > MAX_CHARS ) {
+ if( char_per_account > MAX_CHARS )
+ ShowWarning("Max chars per account '%d' exceeded limit. Defaulting to '%d'.\n", char_per_account, MAX_CHARS);
+ char_per_account = MAX_CHARS;
+ }
+ } else if (strcmpi(w1, "char_del_level") == 0) { //disable/enable char deletion by its level condition [Lupus]
+ char_del_level = atoi(w2);
+ } else if (strcmpi(w1, "char_del_delay") == 0) {
+ char_del_delay = atoi(w2);
+ } else if(strcmpi(w1,"db_path")==0) {
+ safestrncpy(db_path, w2, sizeof(db_path));
+ } else if (strcmpi(w1, "console") == 0) {
+ console = config_switch(w2);
+ } else if (strcmpi(w1, "fame_list_alchemist") == 0) {
+ fame_list_size_chemist = atoi(w2);
+ if (fame_list_size_chemist > MAX_FAME_LIST) {
+ ShowWarning("Max fame list size is %d (fame_list_alchemist)\n", MAX_FAME_LIST);
+ fame_list_size_chemist = MAX_FAME_LIST;
+ }
+ } else if (strcmpi(w1, "fame_list_blacksmith") == 0) {
+ fame_list_size_smith = atoi(w2);
+ if (fame_list_size_smith > MAX_FAME_LIST) {
+ ShowWarning("Max fame list size is %d (fame_list_blacksmith)\n", MAX_FAME_LIST);
+ fame_list_size_smith = MAX_FAME_LIST;
+ }
+ } else if (strcmpi(w1, "fame_list_taekwon") == 0) {
+ fame_list_size_taekwon = atoi(w2);
+ if (fame_list_size_taekwon > MAX_FAME_LIST) {
+ ShowWarning("Max fame list size is %d (fame_list_taekwon)\n", MAX_FAME_LIST);
+ fame_list_size_taekwon = MAX_FAME_LIST;
+ }
+ } else if (strcmpi(w1, "guild_exp_rate") == 0) {
+ guild_exp_rate = atoi(w2);
+ } else if (strcmpi(w1, "import") == 0) {
+ char_config_read(w2);
+ }
+ }
+ fclose(fp);
+
+ ShowInfo("Done reading %s.\n", cfgName);
+ return 0;
}
void do_final(void)
{
- ShowStatus("Terminating...\n");
-
- set_all_offline(-1);
- set_all_offline_sql();
+ ShowStatus("Terminating...\n");
- inter_final();
+ set_all_offline(-1);
+ set_all_offline_sql();
- flush_fifos();
+ inter_final();
- do_final_mapif();
- do_final_loginif();
+ flush_fifos();
+
+ do_final_mapif();
+ do_final_loginif();
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s`", ragsrvinfo_db))
- Sql_ShowDebug(sql_handle);
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s`", ragsrvinfo_db) )
+ Sql_ShowDebug(sql_handle);
- char_db_->destroy(char_db_, NULL);
- online_char_db->destroy(online_char_db, NULL);
- auth_db->destroy(auth_db, NULL);
+ char_db_->destroy(char_db_, NULL);
+ online_char_db->destroy(online_char_db, NULL);
+ auth_db->destroy(auth_db, NULL);
- if (char_fd != -1) {
- do_close(char_fd);
- char_fd = -1;
- }
+ if( char_fd != -1 )
+ {
+ do_close(char_fd);
+ char_fd = -1;
+ }
- Sql_Free(sql_handle);
- mapindex_final();
+ Sql_Free(sql_handle);
+ mapindex_final();
- ShowStatus("Finished.\n");
+ ShowStatus("Finished.\n");
}
//------------------------------
@@ -4615,107 +4674,111 @@ void do_abort(void)
void set_server_type(void)
{
- SERVER_TYPE = ATHENA_SERVER_CHAR;
+ SERVER_TYPE = ATHENA_SERVER_CHAR;
}
/// Called when a terminate signal is received.
void do_shutdown(void)
{
- if (runflag != CHARSERVER_ST_SHUTDOWN) {
- int id;
- runflag = CHARSERVER_ST_SHUTDOWN;
- ShowStatus("Shutting down...\n");
- // TODO proper shutdown procedure; wait for acks?, kick all characters, ... [FlavoJS]
- for (id = 0; id < ARRAYLENGTH(server); ++id)
- mapif_server_reset(id);
- loginif_check_shutdown();
- flush_fifos();
- runflag = CORE_ST_STOP;
- }
+ if( runflag != CHARSERVER_ST_SHUTDOWN )
+ {
+ int id;
+ runflag = CHARSERVER_ST_SHUTDOWN;
+ ShowStatus("Shutting down...\n");
+ // TODO proper shutdown procedure; wait for acks?, kick all characters, ... [FlavoJS]
+ for( id = 0; id < ARRAYLENGTH(server); ++id )
+ mapif_server_reset(id);
+ loginif_check_shutdown();
+ flush_fifos();
+ runflag = CORE_ST_STOP;
+ }
}
int do_init(int argc, char **argv)
{
- //Read map indexes
- mapindex_init();
- start_point.map = mapindex_name2id("new_zone01");
-
- char_config_read((argc < 2) ? CHAR_CONF_NAME : argv[1]);
- char_lan_config_read((argc > 3) ? argv[3] : LAN_CONF_NAME);
- sql_config_read(SQL_CONF_NAME);
-
- if (strcmp(userid, "s1")==0 && strcmp(passwd, "p1")==0) {
- ShowWarning("Using the default user/password s1/p1 is NOT RECOMMENDED.\n");
- ShowNotice("Please edit your 'login' table to create a proper inter-server user/password (gender 'S')\n");
- ShowNotice("And then change the user/password to use in conf/char_athena.conf (or conf/import/char_conf.txt)\n");
- }
-
- inter_init_sql((argc > 2) ? argv[2] : inter_cfgName); // inter server configuration
-
- auth_db = idb_alloc(DB_OPT_RELEASE_DATA);
- online_char_db = idb_alloc(DB_OPT_RELEASE_DATA);
- mmo_char_sql_init();
- char_read_fame_list(); //Read fame lists.
-
- if ((naddr_ != 0) && (!login_ip || !char_ip)) {
- char ip_str[16];
- ip2str(addr_[0], ip_str);
-
- if (naddr_ > 1)
- ShowStatus("Multiple interfaces detected.. using %s as our IP address\n", ip_str);
- else
- ShowStatus("Defaulting to %s as our IP address\n", ip_str);
- if (!login_ip) {
- safestrncpy(login_ip_str, ip_str, sizeof(login_ip_str));
- login_ip = str2ip(login_ip_str);
- }
- if (!char_ip) {
- safestrncpy(char_ip_str, ip_str, sizeof(char_ip_str));
- char_ip = str2ip(char_ip_str);
- }
- }
-
- do_init_loginif();
- do_init_mapif();
-
- // periodically update the overall user count on all mapservers + login server
- add_timer_func_list(broadcast_user_count, "broadcast_user_count");
- add_timer_interval(gettick() + 1000, broadcast_user_count, 0, 0, 5 * 1000);
-
- // Timer to clear (online_char_db)
- add_timer_func_list(chardb_waiting_disconnect, "chardb_waiting_disconnect");
-
- // Online Data timers (checking if char still connected)
- add_timer_func_list(online_data_cleanup, "online_data_cleanup");
- add_timer_interval(gettick() + 1000, online_data_cleanup, 0, 0, 600 * 1000);
-
- if (console) {
- //##TODO invoke a CONSOLE_START plugin event
- }
-
- //Cleaning the tables for NULL entrys @ startup [Sirius]
- //Chardb clean
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '0'", char_db))
- Sql_ShowDebug(sql_handle);
-
- //guilddb clean
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_lv` = '0' AND `max_member` = '0' AND `exp` = '0' AND `next_exp` = '0' AND `average_lv` = '0'", guild_db))
- Sql_ShowDebug(sql_handle);
-
- //guildmemberdb clean
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '0' AND `account_id` = '0' AND `char_id` = '0'", guild_member_db))
- Sql_ShowDebug(sql_handle);
-
- set_defaultparse(parse_char);
- char_fd = make_listen_bind(bind_ip, char_port);
- ShowStatus("The char-server is "CL_GREEN"ready"CL_RESET" (Server is listening on the port %d).\n\n", char_port);
-
- if (runflag != CORE_ST_STOP) {
- shutdown_callback = do_shutdown;
- runflag = CHARSERVER_ST_RUNNING;
- }
-
- return 0;
+ //Read map indexes
+ mapindex_init();
+ start_point.map = mapindex_name2id("new_zone01");
+
+ char_config_read((argc < 2) ? CHAR_CONF_NAME : argv[1]);
+ char_lan_config_read((argc > 3) ? argv[3] : LAN_CONF_NAME);
+ sql_config_read(SQL_CONF_NAME);
+
+ if (strcmp(userid, "s1")==0 && strcmp(passwd, "p1")==0) {
+ ShowWarning("Using the default user/password s1/p1 is NOT RECOMMENDED.\n");
+ ShowNotice("Please edit your 'login' table to create a proper inter-server user/password (gender 'S')\n");
+ ShowNotice("And then change the user/password to use in conf/char_athena.conf (or conf/import/char_conf.txt)\n");
+ }
+
+ inter_init_sql((argc > 2) ? argv[2] : inter_cfgName); // inter server configuration
+
+ auth_db = idb_alloc(DB_OPT_RELEASE_DATA);
+ online_char_db = idb_alloc(DB_OPT_RELEASE_DATA);
+ mmo_char_sql_init();
+ char_read_fame_list(); //Read fame lists.
+
+ if ((naddr_ != 0) && (!login_ip || !char_ip))
+ {
+ char ip_str[16];
+ ip2str(addr_[0], ip_str);
+
+ if (naddr_ > 1)
+ ShowStatus("Multiple interfaces detected.. using %s as our IP address\n", ip_str);
+ else
+ ShowStatus("Defaulting to %s as our IP address\n", ip_str);
+ if (!login_ip) {
+ safestrncpy(login_ip_str, ip_str, sizeof(login_ip_str));
+ login_ip = str2ip(login_ip_str);
+ }
+ if (!char_ip) {
+ safestrncpy(char_ip_str, ip_str, sizeof(char_ip_str));
+ char_ip = str2ip(char_ip_str);
+ }
+ }
+
+ do_init_loginif();
+ do_init_mapif();
+
+ // periodically update the overall user count on all mapservers + login server
+ add_timer_func_list(broadcast_user_count, "broadcast_user_count");
+ add_timer_interval(gettick() + 1000, broadcast_user_count, 0, 0, 5 * 1000);
+
+ // Timer to clear (online_char_db)
+ add_timer_func_list(chardb_waiting_disconnect, "chardb_waiting_disconnect");
+
+ // Online Data timers (checking if char still connected)
+ add_timer_func_list(online_data_cleanup, "online_data_cleanup");
+ add_timer_interval(gettick() + 1000, online_data_cleanup, 0, 0, 600 * 1000);
+
+ if( console )
+ {
+ //##TODO invoke a CONSOLE_START plugin event
+ }
+
+ //Cleaning the tables for NULL entrys @ startup [Sirius]
+ //Chardb clean
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '0'", char_db) )
+ Sql_ShowDebug(sql_handle);
+
+ //guilddb clean
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_lv` = '0' AND `max_member` = '0' AND `exp` = '0' AND `next_exp` = '0' AND `average_lv` = '0'", guild_db) )
+ Sql_ShowDebug(sql_handle);
+
+ //guildmemberdb clean
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '0' AND `account_id` = '0' AND `char_id` = '0'", guild_member_db) )
+ Sql_ShowDebug(sql_handle);
+
+ set_defaultparse(parse_char);
+ char_fd = make_listen_bind(bind_ip, char_port);
+ ShowStatus("The char-server is "CL_GREEN"ready"CL_RESET" (Server is listening on the port %d).\n\n", char_port);
+
+ if( runflag != CORE_ST_STOP )
+ {
+ shutdown_callback = do_shutdown;
+ runflag = CHARSERVER_ST_RUNNING;
+ }
+
+ return 0;
}
diff --git a/src/char/char.h b/src/char/char.h
index cdef28718..dd1c80f9d 100644
--- a/src/char/char.h
+++ b/src/char/char.h
@@ -6,10 +6,11 @@
#include "../common/core.h" // CORE_ST_LAST
-enum E_CHARSERVER_ST {
- CHARSERVER_ST_RUNNING = CORE_ST_LAST,
- CHARSERVER_ST_SHUTDOWN,
- CHARSERVER_ST_LAST
+enum E_CHARSERVER_ST
+{
+ CHARSERVER_ST_RUNNING = CORE_ST_LAST,
+ CHARSERVER_ST_SHUTDOWN,
+ CHARSERVER_ST_LAST
};
struct mmo_charstatus;
@@ -19,10 +20,10 @@ struct mmo_charstatus;
#define DEFAULT_AUTOSAVE_INTERVAL 300*1000
enum {
- TABLE_INVENTORY,
- TABLE_CART,
- TABLE_STORAGE,
- TABLE_GUILD_STORAGE,
+ TABLE_INVENTORY,
+ TABLE_CART,
+ TABLE_STORAGE,
+ TABLE_GUILD_STORAGE,
};
int memitemdata_to_sql(const struct item items[], int max, int id, int tableswitch);
@@ -36,7 +37,7 @@ int char_child(int parent_id, int child_id);
int char_family(int pl1,int pl2,int pl3);
int request_accreg2(int account_id, int char_id);
-int save_accreg2(unsigned char *buf, int len);
+int save_accreg2(unsigned char* buf, int len);
extern int char_name_option;
extern char char_name_letters[];
diff --git a/src/char/int_auction.c b/src/char/int_auction.c
index 4eadb4866..4fc9215a0 100644
--- a/src/char/int_auction.c
+++ b/src/char/int_auction.c
@@ -18,435 +18,442 @@
#include <string.h>
#include <stdlib.h>
-static DBMap *auction_db_ = NULL; // int auction_id -> struct auction_data*
+static DBMap* auction_db_ = NULL; // int auction_id -> struct auction_data*
void auction_delete(struct auction_data *auction);
static int auction_end_timer(int tid, unsigned int tick, int id, intptr_t data);
static int auction_count(int char_id, bool buy)
{
- int i = 0;
- struct auction_data *auction;
- DBIterator *iter = db_iterator(auction_db_);
-
- for (auction = dbi_first(iter); dbi_exists(iter); auction = dbi_next(iter)) {
- if ((buy && auction->buyer_id == char_id) || (!buy && auction->seller_id == char_id))
- i++;
- }
- dbi_destroy(iter);
-
- return i;
+ int i = 0;
+ struct auction_data *auction;
+ DBIterator *iter = db_iterator(auction_db_);
+
+ for( auction = dbi_first(iter); dbi_exists(iter); auction = dbi_next(iter) )
+ {
+ if( (buy && auction->buyer_id == char_id) || (!buy && auction->seller_id == char_id) )
+ i++;
+ }
+ dbi_destroy(iter);
+
+ return i;
}
void auction_save(struct auction_data *auction)
{
- int j;
- StringBuf buf;
- SqlStmt *stmt;
-
- if (!auction)
- return;
-
- StringBuf_Init(&buf);
- StringBuf_Printf(&buf, "UPDATE `%s` SET `seller_id` = '%d', `seller_name` = ?, `buyer_id` = '%d', `buyer_name` = ?, `price` = '%d', `buynow` = '%d', `hours` = '%d', `timestamp` = '%lu', `nameid` = '%d', `item_name` = ?, `type` = '%d', `refine` = '%d', `attribute` = '%d'",
- auction_db, auction->seller_id, auction->buyer_id, auction->price, auction->buynow, auction->hours, (unsigned long)auction->timestamp, auction->item.nameid, auction->type, auction->item.refine, auction->item.attribute);
- for (j = 0; j < MAX_SLOTS; j++)
- StringBuf_Printf(&buf, ", `card%d` = '%d'", j, auction->item.card[j]);
- StringBuf_Printf(&buf, " WHERE `auction_id` = '%d'", auction->auction_id);
-
- stmt = SqlStmt_Malloc(sql_handle);
- if (SQL_SUCCESS != SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, auction->seller_name, strnlen(auction->seller_name, NAME_LENGTH))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, auction->buyer_name, strnlen(auction->buyer_name, NAME_LENGTH))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 2, SQLDT_STRING, auction->item_name, strnlen(auction->item_name, ITEM_NAME_LENGTH))
- || SQL_SUCCESS != SqlStmt_Execute(stmt)) {
- SqlStmt_ShowDebug(stmt);
- }
-
- SqlStmt_Free(stmt);
- StringBuf_Destroy(&buf);
+ int j;
+ StringBuf buf;
+ SqlStmt* stmt;
+
+ if( !auction )
+ return;
+
+ StringBuf_Init(&buf);
+ StringBuf_Printf(&buf, "UPDATE `%s` SET `seller_id` = '%d', `seller_name` = ?, `buyer_id` = '%d', `buyer_name` = ?, `price` = '%d', `buynow` = '%d', `hours` = '%d', `timestamp` = '%lu', `nameid` = '%d', `item_name` = ?, `type` = '%d', `refine` = '%d', `attribute` = '%d'",
+ auction_db, auction->seller_id, auction->buyer_id, auction->price, auction->buynow, auction->hours, (unsigned long)auction->timestamp, auction->item.nameid, auction->type, auction->item.refine, auction->item.attribute);
+ for( j = 0; j < MAX_SLOTS; j++ )
+ StringBuf_Printf(&buf, ", `card%d` = '%d'", j, auction->item.card[j]);
+ StringBuf_Printf(&buf, " WHERE `auction_id` = '%d'", auction->auction_id);
+
+ stmt = SqlStmt_Malloc(sql_handle);
+ if( SQL_SUCCESS != SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, auction->seller_name, strnlen(auction->seller_name, NAME_LENGTH))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, auction->buyer_name, strnlen(auction->buyer_name, NAME_LENGTH))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 2, SQLDT_STRING, auction->item_name, strnlen(auction->item_name, ITEM_NAME_LENGTH))
+ || SQL_SUCCESS != SqlStmt_Execute(stmt) )
+ {
+ SqlStmt_ShowDebug(stmt);
+ }
+
+ SqlStmt_Free(stmt);
+ StringBuf_Destroy(&buf);
}
unsigned int auction_create(struct auction_data *auction)
{
- int j;
- StringBuf buf;
- SqlStmt *stmt;
-
- if (!auction)
- return false;
-
- auction->timestamp = time(NULL) + (auction->hours * 3600);
-
- StringBuf_Init(&buf);
- StringBuf_Printf(&buf, "INSERT INTO `%s` (`seller_id`,`seller_name`,`buyer_id`,`buyer_name`,`price`,`buynow`,`hours`,`timestamp`,`nameid`,`item_name`,`type`,`refine`,`attribute`", auction_db);
- for (j = 0; j < MAX_SLOTS; j++)
- StringBuf_Printf(&buf, ",`card%d`", j);
- StringBuf_Printf(&buf, ") VALUES ('%d',?,'%d',?,'%d','%d','%d','%lu','%d',?,'%d','%d','%d'",
- auction->seller_id, auction->buyer_id, auction->price, auction->buynow, auction->hours, (unsigned long)auction->timestamp, auction->item.nameid, auction->type, auction->item.refine, auction->item.attribute);
- for (j = 0; j < MAX_SLOTS; j++)
- StringBuf_Printf(&buf, ",'%d'", auction->item.card[j]);
- StringBuf_AppendStr(&buf, ")");
-
- stmt = SqlStmt_Malloc(sql_handle);
- if (SQL_SUCCESS != SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, auction->seller_name, strnlen(auction->seller_name, NAME_LENGTH))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, auction->buyer_name, strnlen(auction->buyer_name, NAME_LENGTH))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 2, SQLDT_STRING, auction->item_name, strnlen(auction->item_name, ITEM_NAME_LENGTH))
- || SQL_SUCCESS != SqlStmt_Execute(stmt)) {
- SqlStmt_ShowDebug(stmt);
- auction->auction_id = 0;
- } else {
- struct auction_data *auction_;
- unsigned int tick = auction->hours * 3600000;
-
- auction->item.amount = 1;
- auction->item.identify = 1;
- auction->item.expire_time = 0;
-
- auction->auction_id = (unsigned int)SqlStmt_LastInsertId(stmt);
- auction->auction_end_timer = add_timer(gettick() + tick , auction_end_timer, auction->auction_id, 0);
- ShowInfo("New Auction %u | time left %u ms | By %s.\n", auction->auction_id, tick, auction->seller_name);
-
- CREATE(auction_, struct auction_data, 1);
- memcpy(auction_, auction, sizeof(struct auction_data));
- idb_put(auction_db_, auction_->auction_id, auction_);
- }
-
- SqlStmt_Free(stmt);
- StringBuf_Destroy(&buf);
-
- return auction->auction_id;
+ int j;
+ StringBuf buf;
+ SqlStmt* stmt;
+
+ if( !auction )
+ return false;
+
+ auction->timestamp = time(NULL) + (auction->hours * 3600);
+
+ StringBuf_Init(&buf);
+ StringBuf_Printf(&buf, "INSERT INTO `%s` (`seller_id`,`seller_name`,`buyer_id`,`buyer_name`,`price`,`buynow`,`hours`,`timestamp`,`nameid`,`item_name`,`type`,`refine`,`attribute`", auction_db);
+ for( j = 0; j < MAX_SLOTS; j++ )
+ StringBuf_Printf(&buf, ",`card%d`", j);
+ StringBuf_Printf(&buf, ") VALUES ('%d',?,'%d',?,'%d','%d','%d','%lu','%d',?,'%d','%d','%d'",
+ auction->seller_id, auction->buyer_id, auction->price, auction->buynow, auction->hours, (unsigned long)auction->timestamp, auction->item.nameid, auction->type, auction->item.refine, auction->item.attribute);
+ for( j = 0; j < MAX_SLOTS; j++ )
+ StringBuf_Printf(&buf, ",'%d'", auction->item.card[j]);
+ StringBuf_AppendStr(&buf, ")");
+
+ stmt = SqlStmt_Malloc(sql_handle);
+ if( SQL_SUCCESS != SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, auction->seller_name, strnlen(auction->seller_name, NAME_LENGTH))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, auction->buyer_name, strnlen(auction->buyer_name, NAME_LENGTH))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 2, SQLDT_STRING, auction->item_name, strnlen(auction->item_name, ITEM_NAME_LENGTH))
+ || SQL_SUCCESS != SqlStmt_Execute(stmt) )
+ {
+ SqlStmt_ShowDebug(stmt);
+ auction->auction_id = 0;
+ }
+ else
+ {
+ struct auction_data *auction_;
+ unsigned int tick = auction->hours * 3600000;
+
+ auction->item.amount = 1;
+ auction->item.identify = 1;
+ auction->item.expire_time = 0;
+
+ auction->auction_id = (unsigned int)SqlStmt_LastInsertId(stmt);
+ auction->auction_end_timer = add_timer( gettick() + tick , auction_end_timer, auction->auction_id, 0);
+ ShowInfo("New Auction %u | time left %u ms | By %s.\n", auction->auction_id, tick, auction->seller_name);
+
+ CREATE(auction_, struct auction_data, 1);
+ memcpy(auction_, auction, sizeof(struct auction_data));
+ idb_put(auction_db_, auction_->auction_id, auction_);
+ }
+
+ SqlStmt_Free(stmt);
+ StringBuf_Destroy(&buf);
+
+ return auction->auction_id;
}
static void mapif_Auction_message(int char_id, unsigned char result)
{
- unsigned char buf[74];
-
- WBUFW(buf,0) = 0x3854;
- WBUFL(buf,2) = char_id;
- WBUFL(buf,6) = result;
- mapif_sendall(buf,7);
+ unsigned char buf[74];
+
+ WBUFW(buf,0) = 0x3854;
+ WBUFL(buf,2) = char_id;
+ WBUFL(buf,6) = result;
+ mapif_sendall(buf,7);
}
static int auction_end_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- struct auction_data *auction;
- if ((auction = (struct auction_data *)idb_get(auction_db_, id)) != NULL) {
- if (auction->buyer_id) {
- mail_sendmail(0, "Auction Manager", auction->buyer_id, auction->buyer_name, "Auction", "Thanks, you won the auction!.", 0, &auction->item);
- mapif_Auction_message(auction->buyer_id, 6); // You have won the auction
- mail_sendmail(0, "Auction Manager", auction->seller_id, auction->seller_name, "Auction", "Payment for your auction!.", auction->price, NULL);
- } else
- mail_sendmail(0, "Auction Manager", auction->seller_id, auction->seller_name, "Auction", "No buyers have been found for your auction.", 0, &auction->item);
-
- ShowInfo("Auction End: id %u.\n", auction->auction_id);
-
- auction->auction_end_timer = INVALID_TIMER;
- auction_delete(auction);
- }
-
- return 0;
+ struct auction_data *auction;
+ if( (auction = (struct auction_data *)idb_get(auction_db_, id)) != NULL )
+ {
+ if( auction->buyer_id )
+ {
+ mail_sendmail(0, "Auction Manager", auction->buyer_id, auction->buyer_name, "Auction", "Thanks, you won the auction!.", 0, &auction->item);
+ mapif_Auction_message(auction->buyer_id, 6); // You have won the auction
+ mail_sendmail(0, "Auction Manager", auction->seller_id, auction->seller_name, "Auction", "Payment for your auction!.", auction->price, NULL);
+ }
+ else
+ mail_sendmail(0, "Auction Manager", auction->seller_id, auction->seller_name, "Auction", "No buyers have been found for your auction.", 0, &auction->item);
+
+ ShowInfo("Auction End: id %u.\n", auction->auction_id);
+
+ auction->auction_end_timer = INVALID_TIMER;
+ auction_delete(auction);
+ }
+
+ return 0;
}
void auction_delete(struct auction_data *auction)
{
- unsigned int auction_id = auction->auction_id;
+ unsigned int auction_id = auction->auction_id;
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `auction_id` = '%d'", auction_db, auction_id))
- Sql_ShowDebug(sql_handle);
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `auction_id` = '%d'", auction_db, auction_id) )
+ Sql_ShowDebug(sql_handle);
- if (auction->auction_end_timer != INVALID_TIMER)
- delete_timer(auction->auction_end_timer, auction_end_timer);
+ if( auction->auction_end_timer != INVALID_TIMER )
+ delete_timer(auction->auction_end_timer, auction_end_timer);
- idb_remove(auction_db_, auction_id);
+ idb_remove(auction_db_, auction_id);
}
void inter_auctions_fromsql(void)
{
- int i;
- struct auction_data *auction;
- struct item *item;
- char *data;
- StringBuf buf;
- unsigned int tick = gettick(), endtick;
- time_t now = time(NULL);
-
- StringBuf_Init(&buf);
- StringBuf_AppendStr(&buf, "SELECT `auction_id`,`seller_id`,`seller_name`,`buyer_id`,`buyer_name`,"
- "`price`,`buynow`,`hours`,`timestamp`,`nameid`,`item_name`,`type`,`refine`,`attribute`");
- for (i = 0; i < MAX_SLOTS; i++)
- StringBuf_Printf(&buf, ",`card%d`", i);
- StringBuf_Printf(&buf, " FROM `%s` ORDER BY `auction_id` DESC", auction_db);
-
- if (SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf)))
- Sql_ShowDebug(sql_handle);
-
- StringBuf_Destroy(&buf);
-
- while (SQL_SUCCESS == Sql_NextRow(sql_handle)) {
- CREATE(auction, struct auction_data, 1);
- Sql_GetData(sql_handle, 0, &data, NULL);
- auction->auction_id = atoi(data);
- Sql_GetData(sql_handle, 1, &data, NULL);
- auction->seller_id = atoi(data);
- Sql_GetData(sql_handle, 2, &data, NULL);
- safestrncpy(auction->seller_name, data, NAME_LENGTH);
- Sql_GetData(sql_handle, 3, &data, NULL);
- auction->buyer_id = atoi(data);
- Sql_GetData(sql_handle, 4, &data, NULL);
- safestrncpy(auction->buyer_name, data, NAME_LENGTH);
- Sql_GetData(sql_handle, 5, &data, NULL);
- auction->price = atoi(data);
- Sql_GetData(sql_handle, 6, &data, NULL);
- auction->buynow = atoi(data);
- Sql_GetData(sql_handle, 7, &data, NULL);
- auction->hours = atoi(data);
- Sql_GetData(sql_handle, 8, &data, NULL);
- auction->timestamp = atoi(data);
-
- item = &auction->item;
- Sql_GetData(sql_handle, 9, &data, NULL);
- item->nameid = atoi(data);
- Sql_GetData(sql_handle,10, &data, NULL);
- safestrncpy(auction->item_name, data, ITEM_NAME_LENGTH);
- Sql_GetData(sql_handle,11, &data, NULL);
- auction->type = atoi(data);
-
- Sql_GetData(sql_handle,12, &data, NULL);
- item->refine = atoi(data);
- Sql_GetData(sql_handle,13, &data, NULL);
- item->attribute = atoi(data);
-
- item->identify = 1;
- item->amount = 1;
- item->expire_time = 0;
-
- for (i = 0; i < MAX_SLOTS; i++) {
- Sql_GetData(sql_handle, 14 + i, &data, NULL);
- item->card[i] = atoi(data);
- }
-
- if (auction->timestamp > now)
- endtick = ((unsigned int)(auction->timestamp - now) * 1000) + tick;
- else
- endtick = tick + 10000; // 10 Second's to process ended auctions
-
- auction->auction_end_timer = add_timer(endtick, auction_end_timer, auction->auction_id, 0);
- idb_put(auction_db_, auction->auction_id, auction);
- }
-
- Sql_FreeResult(sql_handle);
+ int i;
+ struct auction_data *auction;
+ struct item *item;
+ char *data;
+ StringBuf buf;
+ unsigned int tick = gettick(), endtick;
+ time_t now = time(NULL);
+
+ StringBuf_Init(&buf);
+ StringBuf_AppendStr(&buf, "SELECT `auction_id`,`seller_id`,`seller_name`,`buyer_id`,`buyer_name`,"
+ "`price`,`buynow`,`hours`,`timestamp`,`nameid`,`item_name`,`type`,`refine`,`attribute`");
+ for( i = 0; i < MAX_SLOTS; i++ )
+ StringBuf_Printf(&buf, ",`card%d`", i);
+ StringBuf_Printf(&buf, " FROM `%s` ORDER BY `auction_id` DESC", auction_db);
+
+ if( SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf)) )
+ Sql_ShowDebug(sql_handle);
+
+ StringBuf_Destroy(&buf);
+
+ while( SQL_SUCCESS == Sql_NextRow(sql_handle) )
+ {
+ CREATE(auction, struct auction_data, 1);
+ Sql_GetData(sql_handle, 0, &data, NULL); auction->auction_id = atoi(data);
+ Sql_GetData(sql_handle, 1, &data, NULL); auction->seller_id = atoi(data);
+ Sql_GetData(sql_handle, 2, &data, NULL); safestrncpy(auction->seller_name, data, NAME_LENGTH);
+ Sql_GetData(sql_handle, 3, &data, NULL); auction->buyer_id = atoi(data);
+ Sql_GetData(sql_handle, 4, &data, NULL); safestrncpy(auction->buyer_name, data, NAME_LENGTH);
+ Sql_GetData(sql_handle, 5, &data, NULL); auction->price = atoi(data);
+ Sql_GetData(sql_handle, 6, &data, NULL); auction->buynow = atoi(data);
+ Sql_GetData(sql_handle, 7, &data, NULL); auction->hours = atoi(data);
+ Sql_GetData(sql_handle, 8, &data, NULL); auction->timestamp = atoi(data);
+
+ item = &auction->item;
+ Sql_GetData(sql_handle, 9, &data, NULL); item->nameid = atoi(data);
+ Sql_GetData(sql_handle,10, &data, NULL); safestrncpy(auction->item_name, data, ITEM_NAME_LENGTH);
+ Sql_GetData(sql_handle,11, &data, NULL); auction->type = atoi(data);
+
+ Sql_GetData(sql_handle,12, &data, NULL); item->refine = atoi(data);
+ Sql_GetData(sql_handle,13, &data, NULL); item->attribute = atoi(data);
+
+ item->identify = 1;
+ item->amount = 1;
+ item->expire_time = 0;
+
+ for( i = 0; i < MAX_SLOTS; i++ )
+ {
+ Sql_GetData(sql_handle, 14 + i, &data, NULL);
+ item->card[i] = atoi(data);
+ }
+
+ if( auction->timestamp > now )
+ endtick = ((unsigned int)(auction->timestamp - now) * 1000) + tick;
+ else
+ endtick = tick + 10000; // 10 Second's to process ended auctions
+
+ auction->auction_end_timer = add_timer(endtick, auction_end_timer, auction->auction_id, 0);
+ idb_put(auction_db_, auction->auction_id, auction);
+ }
+
+ Sql_FreeResult(sql_handle);
}
static void mapif_Auction_sendlist(int fd, int char_id, short count, short pages, unsigned char *buf)
{
- int len = (sizeof(struct auction_data) * count) + 12;
-
- WFIFOHEAD(fd, len);
- WFIFOW(fd,0) = 0x3850;
- WFIFOW(fd,2) = len;
- WFIFOL(fd,4) = char_id;
- WFIFOW(fd,8) = count;
- WFIFOW(fd,10) = pages;
- memcpy(WFIFOP(fd,12), buf, len - 12);
- WFIFOSET(fd,len);
+ int len = (sizeof(struct auction_data) * count) + 12;
+
+ WFIFOHEAD(fd, len);
+ WFIFOW(fd,0) = 0x3850;
+ WFIFOW(fd,2) = len;
+ WFIFOL(fd,4) = char_id;
+ WFIFOW(fd,8) = count;
+ WFIFOW(fd,10) = pages;
+ memcpy(WFIFOP(fd,12), buf, len - 12);
+ WFIFOSET(fd,len);
}
static void mapif_parse_Auction_requestlist(int fd)
{
- char searchtext[NAME_LENGTH];
- int char_id = RFIFOL(fd,4), len = sizeof(struct auction_data);
- int price = RFIFOL(fd,10);
- short type = RFIFOW(fd,8), page = max(1,RFIFOW(fd,14));
- unsigned char buf[5 * sizeof(struct auction_data)];
- DBIterator *iter = db_iterator(auction_db_);
- struct auction_data *auction;
- short i = 0, j = 0, pages = 1;
-
- memcpy(searchtext, RFIFOP(fd,16), NAME_LENGTH);
-
- for (auction = dbi_first(iter); dbi_exists(iter); auction = dbi_next(iter)) {
- if ((type == 0 && auction->type != IT_ARMOR && auction->type != IT_PETARMOR) ||
- (type == 1 && auction->type != IT_WEAPON) ||
- (type == 2 && auction->type != IT_CARD) ||
- (type == 3 && auction->type != IT_ETC) ||
- (type == 4 && !strstr(auction->item_name, searchtext)) ||
- (type == 5 && auction->price > price) ||
- (type == 6 && auction->seller_id != char_id) ||
- (type == 7 && auction->buyer_id != char_id))
- continue;
-
- i++;
- if (i > 5) {
- // Counting Pages of Total Results (5 Results per Page)
- pages++;
- i = 1; // First Result of This Page
- }
-
- if (page != pages)
- continue; // This is not the requested Page
-
- memcpy(WBUFP(buf, j * len), auction, len);
- j++; // Found Results
- }
- dbi_destroy(iter);
-
- mapif_Auction_sendlist(fd, char_id, j, pages, buf);
+ char searchtext[NAME_LENGTH];
+ int char_id = RFIFOL(fd,4), len = sizeof(struct auction_data);
+ int price = RFIFOL(fd,10);
+ short type = RFIFOW(fd,8), page = max(1,RFIFOW(fd,14));
+ unsigned char buf[5 * sizeof(struct auction_data)];
+ DBIterator *iter = db_iterator(auction_db_);
+ struct auction_data *auction;
+ short i = 0, j = 0, pages = 1;
+
+ memcpy(searchtext, RFIFOP(fd,16), NAME_LENGTH);
+
+ for( auction = dbi_first(iter); dbi_exists(iter); auction = dbi_next(iter) )
+ {
+ if( (type == 0 && auction->type != IT_ARMOR && auction->type != IT_PETARMOR) ||
+ (type == 1 && auction->type != IT_WEAPON) ||
+ (type == 2 && auction->type != IT_CARD) ||
+ (type == 3 && auction->type != IT_ETC) ||
+ (type == 4 && !strstr(auction->item_name, searchtext)) ||
+ (type == 5 && auction->price > price) ||
+ (type == 6 && auction->seller_id != char_id) ||
+ (type == 7 && auction->buyer_id != char_id) )
+ continue;
+
+ i++;
+ if( i > 5 )
+ { // Counting Pages of Total Results (5 Results per Page)
+ pages++;
+ i = 1; // First Result of This Page
+ }
+
+ if( page != pages )
+ continue; // This is not the requested Page
+
+ memcpy(WBUFP(buf, j * len), auction, len);
+ j++; // Found Results
+ }
+ dbi_destroy(iter);
+
+ mapif_Auction_sendlist(fd, char_id, j, pages, buf);
}
static void mapif_Auction_register(int fd, struct auction_data *auction)
{
- int len = sizeof(struct auction_data) + 4;
+ int len = sizeof(struct auction_data) + 4;
- WFIFOHEAD(fd,len);
- WFIFOW(fd,0) = 0x3851;
- WFIFOW(fd,2) = len;
- memcpy(WFIFOP(fd,4), auction, sizeof(struct auction_data));
- WFIFOSET(fd,len);
+ WFIFOHEAD(fd,len);
+ WFIFOW(fd,0) = 0x3851;
+ WFIFOW(fd,2) = len;
+ memcpy(WFIFOP(fd,4), auction, sizeof(struct auction_data));
+ WFIFOSET(fd,len);
}
static void mapif_parse_Auction_register(int fd)
{
- struct auction_data auction;
- if (RFIFOW(fd,2) != sizeof(struct auction_data) + 4)
- return;
+ struct auction_data auction;
+ if( RFIFOW(fd,2) != sizeof(struct auction_data) + 4 )
+ return;
- memcpy(&auction, RFIFOP(fd,4), sizeof(struct auction_data));
- if (auction_count(auction.seller_id, false) < 5)
- auction.auction_id = auction_create(&auction);
+ memcpy(&auction, RFIFOP(fd,4), sizeof(struct auction_data));
+ if( auction_count(auction.seller_id, false) < 5 )
+ auction.auction_id = auction_create(&auction);
- mapif_Auction_register(fd, &auction);
+ mapif_Auction_register(fd, &auction);
}
static void mapif_Auction_cancel(int fd, int char_id, unsigned char result)
{
- WFIFOHEAD(fd,7);
- WFIFOW(fd,0) = 0x3852;
- WFIFOL(fd,2) = char_id;
- WFIFOB(fd,6) = result;
- WFIFOSET(fd,7);
+ WFIFOHEAD(fd,7);
+ WFIFOW(fd,0) = 0x3852;
+ WFIFOL(fd,2) = char_id;
+ WFIFOB(fd,6) = result;
+ WFIFOSET(fd,7);
}
static void mapif_parse_Auction_cancel(int fd)
{
- int char_id = RFIFOL(fd,2), auction_id = RFIFOL(fd,6);
- struct auction_data *auction;
-
- if ((auction = (struct auction_data *)idb_get(auction_db_, auction_id)) == NULL) {
- mapif_Auction_cancel(fd, char_id, 1); // Bid Number is Incorrect
- return;
- }
-
- if (auction->seller_id != char_id) {
- mapif_Auction_cancel(fd, char_id, 2); // You cannot end the auction
- return;
- }
-
- if (auction->buyer_id > 0) {
- mapif_Auction_cancel(fd, char_id, 3); // An auction with at least one bidder cannot be canceled
- return;
- }
-
- mail_sendmail(0, "Auction Manager", auction->seller_id, auction->seller_name, "Auction", "Auction canceled.", 0, &auction->item);
- auction_delete(auction);
-
- mapif_Auction_cancel(fd, char_id, 0); // The auction has been canceled
+ int char_id = RFIFOL(fd,2), auction_id = RFIFOL(fd,6);
+ struct auction_data *auction;
+
+ if( (auction = (struct auction_data *)idb_get(auction_db_, auction_id)) == NULL )
+ {
+ mapif_Auction_cancel(fd, char_id, 1); // Bid Number is Incorrect
+ return;
+ }
+
+ if( auction->seller_id != char_id )
+ {
+ mapif_Auction_cancel(fd, char_id, 2); // You cannot end the auction
+ return;
+ }
+
+ if( auction->buyer_id > 0 )
+ {
+ mapif_Auction_cancel(fd, char_id, 3); // An auction with at least one bidder cannot be canceled
+ return;
+ }
+
+ mail_sendmail(0, "Auction Manager", auction->seller_id, auction->seller_name, "Auction", "Auction canceled.", 0, &auction->item);
+ auction_delete(auction);
+
+ mapif_Auction_cancel(fd, char_id, 0); // The auction has been canceled
}
static void mapif_Auction_close(int fd, int char_id, unsigned char result)
{
- WFIFOHEAD(fd,7);
- WFIFOW(fd,0) = 0x3853;
- WFIFOL(fd,2) = char_id;
- WFIFOB(fd,6) = result;
- WFIFOSET(fd,7);
+ WFIFOHEAD(fd,7);
+ WFIFOW(fd,0) = 0x3853;
+ WFIFOL(fd,2) = char_id;
+ WFIFOB(fd,6) = result;
+ WFIFOSET(fd,7);
}
static void mapif_parse_Auction_close(int fd)
{
- int char_id = RFIFOL(fd,2), auction_id = RFIFOL(fd,6);
- struct auction_data *auction;
-
- if ((auction = (struct auction_data *)idb_get(auction_db_, auction_id)) == NULL) {
- mapif_Auction_close(fd, char_id, 2); // Bid Number is Incorrect
- return;
- }
-
- if (auction->seller_id != char_id) {
- mapif_Auction_close(fd, char_id, 1); // You cannot end the auction
- return;
- }
-
- if (auction->buyer_id == 0) {
- mapif_Auction_close(fd, char_id, 1); // You cannot end the auction
- return;
- }
-
- // Send Money to Seller
- mail_sendmail(0, "Auction Manager", auction->seller_id, auction->seller_name, "Auction", "Auction closed.", auction->price, NULL);
- // Send Item to Buyer
- mail_sendmail(0, "Auction Manager", auction->buyer_id, auction->buyer_name, "Auction", "Auction winner.", 0, &auction->item);
- mapif_Auction_message(auction->buyer_id, 6); // You have won the auction
- auction_delete(auction);
-
- mapif_Auction_close(fd, char_id, 0); // You have ended the auction
+ int char_id = RFIFOL(fd,2), auction_id = RFIFOL(fd,6);
+ struct auction_data *auction;
+
+ if( (auction = (struct auction_data *)idb_get(auction_db_, auction_id)) == NULL )
+ {
+ mapif_Auction_close(fd, char_id, 2); // Bid Number is Incorrect
+ return;
+ }
+
+ if( auction->seller_id != char_id )
+ {
+ mapif_Auction_close(fd, char_id, 1); // You cannot end the auction
+ return;
+ }
+
+ if( auction->buyer_id == 0 )
+ {
+ mapif_Auction_close(fd, char_id, 1); // You cannot end the auction
+ return;
+ }
+
+ // Send Money to Seller
+ mail_sendmail(0, "Auction Manager", auction->seller_id, auction->seller_name, "Auction", "Auction closed.", auction->price, NULL);
+ // Send Item to Buyer
+ mail_sendmail(0, "Auction Manager", auction->buyer_id, auction->buyer_name, "Auction", "Auction winner.", 0, &auction->item);
+ mapif_Auction_message(auction->buyer_id, 6); // You have won the auction
+ auction_delete(auction);
+
+ mapif_Auction_close(fd, char_id, 0); // You have ended the auction
}
static void mapif_Auction_bid(int fd, int char_id, int bid, unsigned char result)
{
- WFIFOHEAD(fd,11);
- WFIFOW(fd,0) = 0x3855;
- WFIFOL(fd,2) = char_id;
- WFIFOL(fd,6) = bid; // To Return Zeny
- WFIFOB(fd,10) = result;
- WFIFOSET(fd,11);
+ WFIFOHEAD(fd,11);
+ WFIFOW(fd,0) = 0x3855;
+ WFIFOL(fd,2) = char_id;
+ WFIFOL(fd,6) = bid; // To Return Zeny
+ WFIFOB(fd,10) = result;
+ WFIFOSET(fd,11);
}
static void mapif_parse_Auction_bid(int fd)
{
- int char_id = RFIFOL(fd,4), bid = RFIFOL(fd,12);
- unsigned int auction_id = RFIFOL(fd,8);
- struct auction_data *auction;
-
- if ((auction = (struct auction_data *)idb_get(auction_db_, auction_id)) == NULL || auction->price >= bid || auction->seller_id == char_id) {
- mapif_Auction_bid(fd, char_id, bid, 0); // You have failed to bid in the auction
- return;
- }
-
- if (auction_count(char_id, true) > 4 && bid < auction->buynow && auction->buyer_id != char_id) {
- mapif_Auction_bid(fd, char_id, bid, 9); // You cannot place more than 5 bids at a time
- return;
- }
-
- if (auction->buyer_id > 0) {
- // Send Money back to the previous Buyer
- if (auction->buyer_id != char_id) {
- mail_sendmail(0, "Auction Manager", auction->buyer_id, auction->buyer_name, "Auction", "Someone has placed a higher bid.", auction->price, NULL);
- mapif_Auction_message(auction->buyer_id, 7); // You have failed to win the auction
- } else
- mail_sendmail(0, "Auction Manager", auction->buyer_id, auction->buyer_name, "Auction", "You have placed a higher bid.", auction->price, NULL);
- }
-
- auction->buyer_id = char_id;
- safestrncpy(auction->buyer_name, (char *)RFIFOP(fd,16), NAME_LENGTH);
- auction->price = bid;
-
- if (bid >= auction->buynow) {
- // Automatic won the auction
- mapif_Auction_bid(fd, char_id, bid - auction->buynow, 1); // You have successfully bid in the auction
-
- mail_sendmail(0, "Auction Manager", auction->buyer_id, auction->buyer_name, "Auction", "You have won the auction.", 0, &auction->item);
- mapif_Auction_message(char_id, 6); // You have won the auction
- mail_sendmail(0, "Auction Manager", auction->seller_id, auction->seller_name, "Auction", "Payment for your auction!.", auction->buynow, NULL);
-
- auction_delete(auction);
- return;
- }
-
- auction_save(auction);
-
- mapif_Auction_bid(fd, char_id, 0, 1); // You have successfully bid in the auction
+ int char_id = RFIFOL(fd,4), bid = RFIFOL(fd,12);
+ unsigned int auction_id = RFIFOL(fd,8);
+ struct auction_data *auction;
+
+ if( (auction = (struct auction_data *)idb_get(auction_db_, auction_id)) == NULL || auction->price >= bid || auction->seller_id == char_id )
+ {
+ mapif_Auction_bid(fd, char_id, bid, 0); // You have failed to bid in the auction
+ return;
+ }
+
+ if( auction_count(char_id, true) > 4 && bid < auction->buynow && auction->buyer_id != char_id )
+ {
+ mapif_Auction_bid(fd, char_id, bid, 9); // You cannot place more than 5 bids at a time
+ return;
+ }
+
+ if( auction->buyer_id > 0 )
+ { // Send Money back to the previous Buyer
+ if( auction->buyer_id != char_id )
+ {
+ mail_sendmail(0, "Auction Manager", auction->buyer_id, auction->buyer_name, "Auction", "Someone has placed a higher bid.", auction->price, NULL);
+ mapif_Auction_message(auction->buyer_id, 7); // You have failed to win the auction
+ }
+ else
+ mail_sendmail(0, "Auction Manager", auction->buyer_id, auction->buyer_name, "Auction", "You have placed a higher bid.", auction->price, NULL);
+ }
+
+ auction->buyer_id = char_id;
+ safestrncpy(auction->buyer_name, (char*)RFIFOP(fd,16), NAME_LENGTH);
+ auction->price = bid;
+
+ if( bid >= auction->buynow )
+ { // Automatic won the auction
+ mapif_Auction_bid(fd, char_id, bid - auction->buynow, 1); // You have successfully bid in the auction
+
+ mail_sendmail(0, "Auction Manager", auction->buyer_id, auction->buyer_name, "Auction", "You have won the auction.", 0, &auction->item);
+ mapif_Auction_message(char_id, 6); // You have won the auction
+ mail_sendmail(0, "Auction Manager", auction->seller_id, auction->seller_name, "Auction", "Payment for your auction!.", auction->buynow, NULL);
+
+ auction_delete(auction);
+ return;
+ }
+
+ auction_save(auction);
+
+ mapif_Auction_bid(fd, char_id, 0, 1); // You have successfully bid in the auction
}
/*==========================================
@@ -454,39 +461,30 @@ static void mapif_parse_Auction_bid(int fd)
*------------------------------------------*/
int inter_auction_parse_frommap(int fd)
{
- switch (RFIFOW(fd,0)) {
- case 0x3050:
- mapif_parse_Auction_requestlist(fd);
- break;
- case 0x3051:
- mapif_parse_Auction_register(fd);
- break;
- case 0x3052:
- mapif_parse_Auction_cancel(fd);
- break;
- case 0x3053:
- mapif_parse_Auction_close(fd);
- break;
- case 0x3055:
- mapif_parse_Auction_bid(fd);
- break;
- default:
- return 0;
- }
- return 1;
+ switch(RFIFOW(fd,0))
+ {
+ case 0x3050: mapif_parse_Auction_requestlist(fd); break;
+ case 0x3051: mapif_parse_Auction_register(fd); break;
+ case 0x3052: mapif_parse_Auction_cancel(fd); break;
+ case 0x3053: mapif_parse_Auction_close(fd); break;
+ case 0x3055: mapif_parse_Auction_bid(fd); break;
+ default:
+ return 0;
+ }
+ return 1;
}
int inter_auction_sql_init(void)
{
- auction_db_ = idb_alloc(DB_OPT_RELEASE_DATA);
- inter_auctions_fromsql();
+ auction_db_ = idb_alloc(DB_OPT_RELEASE_DATA);
+ inter_auctions_fromsql();
- return 0;
+ return 0;
}
void inter_auction_sql_final(void)
{
- auction_db_->destroy(auction_db_,NULL);
+ auction_db_->destroy(auction_db_,NULL);
- return;
+ return;
}
diff --git a/src/char/int_elemental.c b/src/char/int_elemental.c
index aa7ef5f65..7c76c4496 100644
--- a/src/char/int_elemental.c
+++ b/src/char/int_elemental.c
@@ -15,179 +15,147 @@
#include <stdlib.h>
#include <string.h>
-bool mapif_elemental_save(struct s_elemental *ele)
-{
- bool flag = true;
-
- if (ele->elemental_id == 0) { // Create new DB entry
- if (SQL_ERROR == Sql_Query(sql_handle,
- "INSERT INTO `elemental` (`char_id`,`class`,`mode`,`hp`,`sp`,`max_hp`,`max_sp`,`str`,`agi`,`vit`,`int`,`dex`,`luk`,`life_time`)"
- "VALUES ('%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%u')",
- ele->char_id, ele->class_, ele->mode, ele->hp, ele->sp, ele->max_hp, ele->max_sp, ele->str, ele->agi, ele->vit, ele->int_, ele->dex, ele->luk, ele->life_time)) {
- Sql_ShowDebug(sql_handle);
- flag = false;
- } else
- ele->elemental_id = (int)Sql_LastInsertId(sql_handle);
- } else if (SQL_ERROR == Sql_Query(sql_handle,
- "UPDATE `elemental` SET `char_id` = '%d', `class` = '%d', `mode` = '%d', `hp` = '%d', `sp` = '%d',"
- "`max_hp` = '%d', `max_sp` = '%d', `str` = '%d', `agi` = '%d', `vit` = '%d', `int` = '%d', `dex` = '%d',"
- "`luk` = '%d', `life_time` = '%u' WHERE `ele_id` = '%d'",
- ele->char_id, ele->class_, ele->mode, ele->hp, ele->sp, ele->max_hp, ele->max_sp, ele->str, ele->agi,
- ele->vit, ele->int_, ele->dex, ele->luk, ele->life_time, ele->elemental_id)) {
- // Update DB entry
- Sql_ShowDebug(sql_handle);
- flag = false;
- }
- return flag;
+bool mapif_elemental_save(struct s_elemental* ele) {
+ bool flag = true;
+
+ if( ele->elemental_id == 0 ) { // Create new DB entry
+ if( SQL_ERROR == Sql_Query(sql_handle,
+ "INSERT INTO `elemental` (`char_id`,`class`,`mode`,`hp`,`sp`,`max_hp`,`max_sp`,`str`,`agi`,`vit`,`int`,`dex`,`luk`,`life_time`)"
+ "VALUES ('%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%u')",
+ ele->char_id, ele->class_, ele->mode, ele->hp, ele->sp, ele->max_hp, ele->max_sp, ele->str, ele->agi, ele->vit, ele->int_, ele->dex, ele->luk, ele->life_time) )
+ {
+ Sql_ShowDebug(sql_handle);
+ flag = false;
+ }
+ else
+ ele->elemental_id = (int)Sql_LastInsertId(sql_handle);
+ } else if( SQL_ERROR == Sql_Query(sql_handle,
+ "UPDATE `elemental` SET `char_id` = '%d', `class` = '%d', `mode` = '%d', `hp` = '%d', `sp` = '%d',"
+ "`max_hp` = '%d', `max_sp` = '%d', `str` = '%d', `agi` = '%d', `vit` = '%d', `int` = '%d', `dex` = '%d',"
+ "`luk` = '%d', `life_time` = '%u' WHERE `ele_id` = '%d'",
+ ele->char_id, ele->class_, ele->mode, ele->hp, ele->sp, ele->max_hp, ele->max_sp, ele->str, ele->agi,
+ ele->vit, ele->int_, ele->dex, ele->luk, ele->life_time, ele->elemental_id) )
+ { // Update DB entry
+ Sql_ShowDebug(sql_handle);
+ flag = false;
+ }
+ return flag;
}
-bool mapif_elemental_load(int ele_id, int char_id, struct s_elemental *ele)
-{
- char *data;
-
- memset(ele, 0, sizeof(struct s_elemental));
- ele->elemental_id = ele_id;
- ele->char_id = char_id;
-
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `class`, `mode`, `hp`, `sp`, `max_hp`, `max_sp`, `str`, `agi`, `vit`, `int`, `dex`,"
- "`luk`, `life_time` FROM `elemental` WHERE `ele_id` = '%d' AND `char_id` = '%d'",
- ele_id, char_id)) {
- Sql_ShowDebug(sql_handle);
- return false;
- }
-
- if (SQL_SUCCESS != Sql_NextRow(sql_handle)) {
- Sql_FreeResult(sql_handle);
- return false;
- }
-
- Sql_GetData(sql_handle, 0, &data, NULL);
- ele->class_ = atoi(data);
- Sql_GetData(sql_handle, 1, &data, NULL);
- ele->mode = atoi(data);
- Sql_GetData(sql_handle, 2, &data, NULL);
- ele->hp = atoi(data);
- Sql_GetData(sql_handle, 3, &data, NULL);
- ele->sp = atoi(data);
- Sql_GetData(sql_handle, 4, &data, NULL);
- ele->max_hp = atoi(data);
- Sql_GetData(sql_handle, 5, &data, NULL);
- ele->max_sp = atoi(data);
- Sql_GetData(sql_handle, 6, &data, NULL);
- ele->str = atoi(data);
- Sql_GetData(sql_handle, 7, &data, NULL);
- ele->agi = atoi(data);
- Sql_GetData(sql_handle, 8, &data, NULL);
- ele->vit = atoi(data);
- Sql_GetData(sql_handle, 9, &data, NULL);
- ele->int_ = atoi(data);
- Sql_GetData(sql_handle, 10, &data, NULL);
- ele->dex = atoi(data);
- Sql_GetData(sql_handle, 11, &data, NULL);
- ele->luk = atoi(data);
- Sql_GetData(sql_handle, 12, &data, NULL);
- ele->life_time = atoi(data);
- Sql_FreeResult(sql_handle);
- if (save_log)
- ShowInfo("Elemental loaded (%d - %d).\n", ele->elemental_id, ele->char_id);
-
- return true;
+bool mapif_elemental_load(int ele_id, int char_id, struct s_elemental *ele) {
+ char* data;
+
+ memset(ele, 0, sizeof(struct s_elemental));
+ ele->elemental_id = ele_id;
+ ele->char_id = char_id;
+
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `class`, `mode`, `hp`, `sp`, `max_hp`, `max_sp`, `str`, `agi`, `vit`, `int`, `dex`,"
+ "`luk`, `life_time` FROM `elemental` WHERE `ele_id` = '%d' AND `char_id` = '%d'",
+ ele_id, char_id) ) {
+ Sql_ShowDebug(sql_handle);
+ return false;
+ }
+
+ if( SQL_SUCCESS != Sql_NextRow(sql_handle) ) {
+ Sql_FreeResult(sql_handle);
+ return false;
+ }
+
+ Sql_GetData(sql_handle, 0, &data, NULL); ele->class_ = atoi(data);
+ Sql_GetData(sql_handle, 1, &data, NULL); ele->mode = atoi(data);
+ Sql_GetData(sql_handle, 2, &data, NULL); ele->hp = atoi(data);
+ Sql_GetData(sql_handle, 3, &data, NULL); ele->sp = atoi(data);
+ Sql_GetData(sql_handle, 4, &data, NULL); ele->max_hp = atoi(data);
+ Sql_GetData(sql_handle, 5, &data, NULL); ele->max_sp = atoi(data);
+ Sql_GetData(sql_handle, 6, &data, NULL); ele->str = atoi(data);
+ Sql_GetData(sql_handle, 7, &data, NULL); ele->agi = atoi(data);
+ Sql_GetData(sql_handle, 8, &data, NULL); ele->vit = atoi(data);
+ Sql_GetData(sql_handle, 9, &data, NULL); ele->int_ = atoi(data);
+ Sql_GetData(sql_handle, 10, &data, NULL); ele->dex = atoi(data);
+ Sql_GetData(sql_handle, 11, &data, NULL); ele->luk = atoi(data);
+ Sql_GetData(sql_handle, 12, &data, NULL); ele->life_time = atoi(data);
+ Sql_FreeResult(sql_handle);
+ if( save_log )
+ ShowInfo("Elemental loaded (%d - %d).\n", ele->elemental_id, ele->char_id);
+
+ return true;
}
-bool mapif_elemental_delete(int ele_id)
-{
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `elemental` WHERE `ele_id` = '%d'", ele_id)) {
- Sql_ShowDebug(sql_handle);
- return false;
- }
-
- return true;
+bool mapif_elemental_delete(int ele_id) {
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `elemental` WHERE `ele_id` = '%d'", ele_id) ) {
+ Sql_ShowDebug(sql_handle);
+ return false;
+ }
+
+ return true;
}
-static void mapif_elemental_send(int fd, struct s_elemental *ele, unsigned char flag)
-{
- int size = sizeof(struct s_elemental) + 5;
-
- WFIFOHEAD(fd,size);
- WFIFOW(fd,0) = 0x387c;
- WFIFOW(fd,2) = size;
- WFIFOB(fd,4) = flag;
- memcpy(WFIFOP(fd,5),ele,sizeof(struct s_elemental));
- WFIFOSET(fd,size);
+static void mapif_elemental_send(int fd, struct s_elemental *ele, unsigned char flag) {
+ int size = sizeof(struct s_elemental) + 5;
+
+ WFIFOHEAD(fd,size);
+ WFIFOW(fd,0) = 0x387c;
+ WFIFOW(fd,2) = size;
+ WFIFOB(fd,4) = flag;
+ memcpy(WFIFOP(fd,5),ele,sizeof(struct s_elemental));
+ WFIFOSET(fd,size);
}
-static void mapif_parse_elemental_create(int fd, struct s_elemental *ele)
-{
- bool result = mapif_elemental_save(ele);
- mapif_elemental_send(fd, ele, result);
+static void mapif_parse_elemental_create(int fd, struct s_elemental* ele) {
+ bool result = mapif_elemental_save(ele);
+ mapif_elemental_send(fd, ele, result);
}
-static void mapif_parse_elemental_load(int fd, int ele_id, int char_id)
-{
- struct s_elemental ele;
- bool result = mapif_elemental_load(ele_id, char_id, &ele);
- mapif_elemental_send(fd, &ele, result);
+static void mapif_parse_elemental_load(int fd, int ele_id, int char_id) {
+ struct s_elemental ele;
+ bool result = mapif_elemental_load(ele_id, char_id, &ele);
+ mapif_elemental_send(fd, &ele, result);
}
-static void mapif_elemental_deleted(int fd, unsigned char flag)
-{
- WFIFOHEAD(fd,3);
- WFIFOW(fd,0) = 0x387d;
- WFIFOB(fd,2) = flag;
- WFIFOSET(fd,3);
+static void mapif_elemental_deleted(int fd, unsigned char flag) {
+ WFIFOHEAD(fd,3);
+ WFIFOW(fd,0) = 0x387d;
+ WFIFOB(fd,2) = flag;
+ WFIFOSET(fd,3);
}
-static void mapif_parse_elemental_delete(int fd, int ele_id)
-{
- bool result = mapif_elemental_delete(ele_id);
- mapif_elemental_deleted(fd, result);
+static void mapif_parse_elemental_delete(int fd, int ele_id) {
+ bool result = mapif_elemental_delete(ele_id);
+ mapif_elemental_deleted(fd, result);
}
-static void mapif_elemental_saved(int fd, unsigned char flag)
-{
- WFIFOHEAD(fd,3);
- WFIFOW(fd,0) = 0x387e;
- WFIFOB(fd,2) = flag;
- WFIFOSET(fd,3);
+static void mapif_elemental_saved(int fd, unsigned char flag) {
+ WFIFOHEAD(fd,3);
+ WFIFOW(fd,0) = 0x387e;
+ WFIFOB(fd,2) = flag;
+ WFIFOSET(fd,3);
}
-static void mapif_parse_elemental_save(int fd, struct s_elemental *ele)
-{
- bool result = mapif_elemental_save(ele);
- mapif_elemental_saved(fd, result);
+static void mapif_parse_elemental_save(int fd, struct s_elemental* ele) {
+ bool result = mapif_elemental_save(ele);
+ mapif_elemental_saved(fd, result);
}
-void inter_elemental_sql_init(void)
-{
- return;
+void inter_elemental_sql_init(void) {
+ return;
}
-void inter_elemental_sql_final(void)
-{
- return;
+void inter_elemental_sql_final(void) {
+ return;
}
/*==========================================
* Inter Packets
*------------------------------------------*/
-int inter_elemental_parse_frommap(int fd)
-{
- unsigned short cmd = RFIFOW(fd,0);
-
- switch (cmd) {
- case 0x307c:
- mapif_parse_elemental_create(fd, (struct s_elemental *)RFIFOP(fd,4));
- break;
- case 0x307d:
- mapif_parse_elemental_load(fd, (int)RFIFOL(fd,2), (int)RFIFOL(fd,6));
- break;
- case 0x307e:
- mapif_parse_elemental_delete(fd, (int)RFIFOL(fd,2));
- break;
- case 0x307f:
- mapif_parse_elemental_save(fd, (struct s_elemental *)RFIFOP(fd,4));
- break;
- default:
- return 0;
- }
- return 1;
+int inter_elemental_parse_frommap(int fd) {
+ unsigned short cmd = RFIFOW(fd,0);
+
+ switch( cmd ) {
+ case 0x307c: mapif_parse_elemental_create(fd, (struct s_elemental*)RFIFOP(fd,4)); break;
+ case 0x307d: mapif_parse_elemental_load(fd, (int)RFIFOL(fd,2), (int)RFIFOL(fd,6)); break;
+ case 0x307e: mapif_parse_elemental_delete(fd, (int)RFIFOL(fd,2)); break;
+ case 0x307f: mapif_parse_elemental_save(fd, (struct s_elemental*)RFIFOP(fd,4)); break;
+ default:
+ return 0;
+ }
+ return 1;
}
diff --git a/src/char/int_guild.c b/src/char/int_guild.c
index 2b4a9f3ac..b07a1933f 100644
--- a/src/char/int_guild.c
+++ b/src/char/int_guild.c
@@ -31,7 +31,7 @@
static const char dataToHex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
//Guild cache
-static DBMap *guild_db_; // int guild_id -> struct guild*
+static DBMap* guild_db_; // int guild_id -> struct guild*
static DBMap *castle_db;
static unsigned int guild_exp[100];
@@ -47,703 +47,703 @@ int inter_guild_tosql(struct guild *g,int flag);
static int guild_save_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- static int last_id = 0; //To know in which guild we were.
- int state = 0; //0: Have not reached last guild. 1: Reached last guild, ready for save. 2: Some guild saved, don't do further saving.
- DBIterator *iter = db_iterator(guild_db_);
- DBKey key;
- struct guild *g;
-
- if (last_id == 0) //Save the first guild in the list.
- state = 1;
-
- for (g = db_data2ptr(iter->first(iter, &key)); dbi_exists(iter); g = db_data2ptr(iter->next(iter, &key))) {
- if (state == 0 && g->guild_id == last_id)
- state++; //Save next guild in the list.
- else if (state == 1 && g->save_flag&GS_MASK) {
- inter_guild_tosql(g, g->save_flag&GS_MASK);
- g->save_flag &= ~GS_MASK;
-
- //Some guild saved.
- last_id = g->guild_id;
- state++;
- }
-
- if (g->save_flag == GS_REMOVE) {
- // Nothing to save, guild is ready for removal.
- if (save_log)
- ShowInfo("Guild Unloaded (%d - %s)\n", g->guild_id, g->name);
- db_remove(guild_db_, key);
- }
- }
- dbi_destroy(iter);
-
- if (state != 2) //Reached the end of the guild db without saving.
- last_id = 0; //Reset guild saved, return to beginning.
-
- state = guild_db_->size(guild_db_);
- if (state < 1) state = 1; //Calculate the time slot for the next save.
- add_timer(tick + autosave_interval/state, guild_save_timer, 0, 0);
- return 0;
+ static int last_id = 0; //To know in which guild we were.
+ int state = 0; //0: Have not reached last guild. 1: Reached last guild, ready for save. 2: Some guild saved, don't do further saving.
+ DBIterator *iter = db_iterator(guild_db_);
+ DBKey key;
+ struct guild* g;
+
+ if( last_id == 0 ) //Save the first guild in the list.
+ state = 1;
+
+ for( g = db_data2ptr(iter->first(iter, &key)); dbi_exists(iter); g = db_data2ptr(iter->next(iter, &key)) )
+ {
+ if( state == 0 && g->guild_id == last_id )
+ state++; //Save next guild in the list.
+ else
+ if( state == 1 && g->save_flag&GS_MASK )
+ {
+ inter_guild_tosql(g, g->save_flag&GS_MASK);
+ g->save_flag &= ~GS_MASK;
+
+ //Some guild saved.
+ last_id = g->guild_id;
+ state++;
+ }
+
+ if( g->save_flag == GS_REMOVE )
+ {// Nothing to save, guild is ready for removal.
+ if (save_log)
+ ShowInfo("Guild Unloaded (%d - %s)\n", g->guild_id, g->name);
+ db_remove(guild_db_, key);
+ }
+ }
+ dbi_destroy(iter);
+
+ if( state != 2 ) //Reached the end of the guild db without saving.
+ last_id = 0; //Reset guild saved, return to beginning.
+
+ state = guild_db_->size(guild_db_);
+ if( state < 1 ) state = 1; //Calculate the time slot for the next save.
+ add_timer(tick + autosave_interval/state, guild_save_timer, 0, 0);
+ return 0;
}
int inter_guild_removemember_tosql(int account_id, int char_id)
{
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE from `%s` where `account_id` = '%d' and `char_id` = '%d'", guild_member_db, account_id, char_id))
- Sql_ShowDebug(sql_handle);
- if (SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `guild_id` = '0' WHERE `char_id` = '%d'", char_db, char_id))
- Sql_ShowDebug(sql_handle);
- return 0;
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE from `%s` where `account_id` = '%d' and `char_id` = '%d'", guild_member_db, account_id, char_id) )
+ Sql_ShowDebug(sql_handle);
+ if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `guild_id` = '0' WHERE `char_id` = '%d'", char_db, char_id) )
+ Sql_ShowDebug(sql_handle);
+ return 0;
}
// Save guild into sql
int inter_guild_tosql(struct guild *g,int flag)
{
- // Table guild (GS_BASIC_MASK)
- // GS_EMBLEM `emblem_len`,`emblem_id`,`emblem_data`
- // GS_CONNECT `connect_member`,`average_lv`
- // GS_MES `mes1`,`mes2`
- // GS_LEVEL `guild_lv`,`max_member`,`exp`,`next_exp`,`skill_point`
- // GS_BASIC `name`,`master`,`char_id`
-
- // GS_MEMBER `guild_member` (`guild_id`,`account_id`,`char_id`,`hair`,`hair_color`,`gender`,`class`,`lv`,`exp`,`exp_payper`,`online`,`position`,`name`)
- // GS_POSITION `guild_position` (`guild_id`,`position`,`name`,`mode`,`exp_mode`)
- // GS_ALLIANCE `guild_alliance` (`guild_id`,`opposition`,`alliance_id`,`name`)
- // GS_EXPULSION `guild_expulsion` (`guild_id`,`account_id`,`name`,`mes`)
- // GS_SKILL `guild_skill` (`guild_id`,`id`,`lv`)
-
- // temporary storage for str convertion. They must be twice the size of the
- // original string to ensure no overflows will occur. [Skotlex]
- char t_info[256];
- char esc_name[NAME_LENGTH*2+1];
- char esc_master[NAME_LENGTH*2+1];
- char new_guild = 0;
- int i=0;
-
- if (g->guild_id<=0 && g->guild_id != -1) return 0;
-
+ // Table guild (GS_BASIC_MASK)
+ // GS_EMBLEM `emblem_len`,`emblem_id`,`emblem_data`
+ // GS_CONNECT `connect_member`,`average_lv`
+ // GS_MES `mes1`,`mes2`
+ // GS_LEVEL `guild_lv`,`max_member`,`exp`,`next_exp`,`skill_point`
+ // GS_BASIC `name`,`master`,`char_id`
+
+ // GS_MEMBER `guild_member` (`guild_id`,`account_id`,`char_id`,`hair`,`hair_color`,`gender`,`class`,`lv`,`exp`,`exp_payper`,`online`,`position`,`name`)
+ // GS_POSITION `guild_position` (`guild_id`,`position`,`name`,`mode`,`exp_mode`)
+ // GS_ALLIANCE `guild_alliance` (`guild_id`,`opposition`,`alliance_id`,`name`)
+ // GS_EXPULSION `guild_expulsion` (`guild_id`,`account_id`,`name`,`mes`)
+ // GS_SKILL `guild_skill` (`guild_id`,`id`,`lv`)
+
+ // temporary storage for str convertion. They must be twice the size of the
+ // original string to ensure no overflows will occur. [Skotlex]
+ char t_info[256];
+ char esc_name[NAME_LENGTH*2+1];
+ char esc_master[NAME_LENGTH*2+1];
+ char new_guild = 0;
+ int i=0;
+
+ if (g->guild_id<=0 && g->guild_id != -1) return 0;
+
#ifdef NOISY
- ShowInfo("Save guild request ("CL_BOLD"%d"CL_RESET" - flag 0x%x).",g->guild_id, flag);
+ ShowInfo("Save guild request ("CL_BOLD"%d"CL_RESET" - flag 0x%x).",g->guild_id, flag);
#endif
- Sql_EscapeStringLen(sql_handle, esc_name, g->name, strnlen(g->name, NAME_LENGTH));
- Sql_EscapeStringLen(sql_handle, esc_master, g->master, strnlen(g->master, NAME_LENGTH));
- *t_info = '\0';
-
- // Insert a new guild the guild
- if (flag&GS_BASIC && g->guild_id == -1) {
- strcat(t_info, " guild_create");
-
- // Create a new guild
- if (SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` "
- "(`name`,`master`,`guild_lv`,`max_member`,`average_lv`,`char_id`) "
- "VALUES ('%s', '%s', '%d', '%d', '%d', '%d')",
- guild_db, esc_name, esc_master, g->guild_lv, g->max_member, g->average_lv, g->member[0].char_id)) {
- Sql_ShowDebug(sql_handle);
- if (g->guild_id == -1)
- return 0; //Failed to create guild!
- } else {
- g->guild_id = (int)Sql_LastInsertId(sql_handle);
- new_guild = 1;
- }
- }
-
- // If we need an update on an existing guild or more update on the new guild
- if (((flag & GS_BASIC_MASK) && !new_guild) || ((flag & (GS_BASIC_MASK & ~GS_BASIC)) && new_guild)) {
- StringBuf buf;
- bool add_comma = false;
-
- StringBuf_Init(&buf);
- StringBuf_Printf(&buf, "UPDATE `%s` SET ", guild_db);
-
- if (flag & GS_EMBLEM) {
- char emblem_data[sizeof(g->emblem_data)*2+1];
- char *pData = emblem_data;
-
- strcat(t_info, " emblem");
- // Convert emblem_data to hex
- //TODO: why not use binary directly? [ultramage]
- for (i=0; i<g->emblem_len; i++) {
- *pData++ = dataToHex[(g->emblem_data[i] >> 4) & 0x0F];
- *pData++ = dataToHex[g->emblem_data[i] & 0x0F];
- }
- *pData = 0;
- StringBuf_Printf(&buf, "`emblem_len`=%d, `emblem_id`=%d, `emblem_data`='%s'", g->emblem_len, g->emblem_id, emblem_data);
- add_comma = true;
- }
- if (flag & GS_BASIC) {
- strcat(t_info, " basic");
- if (add_comma)
- StringBuf_AppendStr(&buf, ", ");
- else
- add_comma = true;
- StringBuf_Printf(&buf, "`name`='%s', `master`='%s', `char_id`=%d", esc_name, esc_master, g->member[0].char_id);
- }
- if (flag & GS_CONNECT) {
- strcat(t_info, " connect");
- if (add_comma)
- StringBuf_AppendStr(&buf, ", ");
- else
- add_comma = true;
- StringBuf_Printf(&buf, "`connect_member`=%d, `average_lv`=%d", g->connect_member, g->average_lv);
- }
- if (flag & GS_MES) {
- char esc_mes1[sizeof(g->mes1)*2+1];
- char esc_mes2[sizeof(g->mes2)*2+1];
-
- strcat(t_info, " mes");
- if (add_comma)
- StringBuf_AppendStr(&buf, ", ");
- else
- add_comma = true;
- Sql_EscapeStringLen(sql_handle, esc_mes1, g->mes1, strnlen(g->mes1, sizeof(g->mes1)));
- Sql_EscapeStringLen(sql_handle, esc_mes2, g->mes2, strnlen(g->mes2, sizeof(g->mes2)));
- StringBuf_Printf(&buf, "`mes1`='%s', `mes2`='%s'", esc_mes1, esc_mes2);
- }
- if (flag & GS_LEVEL) {
- strcat(t_info, " level");
- if (add_comma)
- StringBuf_AppendStr(&buf, ", ");
- else
- add_comma = true;
- StringBuf_Printf(&buf, "`guild_lv`=%d, `skill_point`=%d, `exp`=%"PRIu64", `next_exp`=%u, `max_member`=%d", g->guild_lv, g->skill_point, g->exp, g->next_exp, g->max_member);
- }
- StringBuf_Printf(&buf, " WHERE `guild_id`=%d", g->guild_id);
- if (SQL_ERROR == Sql_Query(sql_handle, "%s", StringBuf_Value(&buf)))
- Sql_ShowDebug(sql_handle);
- StringBuf_Destroy(&buf);
- }
-
- if (flag&GS_MEMBER) {
- struct guild_member *m;
-
- strcat(t_info, " members");
- // Update only needed players
- for (i=0; i<g->max_member; i++) {
- m = &g->member[i];
- if (!m->modified)
- continue;
- if (m->account_id) {
- //Since nothing references guild member table as foreign keys, it's safe to use REPLACE INTO
- Sql_EscapeStringLen(sql_handle, esc_name, m->name, strnlen(m->name, NAME_LENGTH));
- if (SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`guild_id`,`account_id`,`char_id`,`hair`,`hair_color`,`gender`,`class`,`lv`,`exp`,`exp_payper`,`online`,`position`,`name`) "
- "VALUES ('%d','%d','%d','%d','%d','%d','%d','%d','%"PRIu64"','%d','%d','%d','%s')",
- guild_member_db, 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, esc_name))
- Sql_ShowDebug(sql_handle);
- if (m->modified & GS_MEMBER_NEW) {
- if (SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `guild_id` = '%d' WHERE `char_id` = '%d'",
- char_db, g->guild_id, m->char_id))
- Sql_ShowDebug(sql_handle);
- }
- m->modified = GS_MEMBER_UNMODIFIED;
- }
- }
- }
-
- if (flag&GS_POSITION) {
- strcat(t_info, " positions");
- //printf("- Insert guild %d to guild_position\n",g->guild_id);
- for (i=0; i<MAX_GUILDPOSITION; i++) {
- struct guild_position *p = &g->position[i];
- if (!p->modified)
- continue;
- Sql_EscapeStringLen(sql_handle, esc_name, p->name, strnlen(p->name, NAME_LENGTH));
- if (SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`guild_id`,`position`,`name`,`mode`,`exp_mode`) VALUES ('%d','%d','%s','%d','%d')",
- guild_position_db, g->guild_id, i, esc_name, p->mode, p->exp_mode))
- Sql_ShowDebug(sql_handle);
- p->modified = GS_POSITION_UNMODIFIED;
- }
- }
-
- if (flag&GS_ALLIANCE) {
- // Delete current alliances
- // NOTE: no need to do it on both sides since both guilds in memory had
- // their info changed, not to mention this would also mess up oppositions!
- // [Skotlex]
- //if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id`='%d' OR `alliance_id`='%d'", guild_alliance_db, g->guild_id, g->guild_id) )
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id`='%d'", guild_alliance_db, g->guild_id)) {
- Sql_ShowDebug(sql_handle);
- } else {
- //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) {
- Sql_EscapeStringLen(sql_handle, esc_name, a->name, strnlen(a->name, NAME_LENGTH));
- if (SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`guild_id`,`opposition`,`alliance_id`,`name`) "
- "VALUES ('%d','%d','%d','%s')",
- guild_alliance_db, g->guild_id, a->opposition, a->guild_id, esc_name))
- Sql_ShowDebug(sql_handle);
- }
- }
- }
- }
-
- if (flag&GS_EXPULSION) {
- strcat(t_info, " expulsions");
- //printf("- Insert guild %d to guild_expulsion\n",g->guild_id);
- for (i=0; i<MAX_GUILDEXPULSION; i++) {
- struct guild_expulsion *e=&g->expulsion[i];
- if (e->account_id>0) {
- char esc_mes[sizeof(e->mes)*2+1];
-
- Sql_EscapeStringLen(sql_handle, esc_name, e->name, strnlen(e->name, NAME_LENGTH));
- Sql_EscapeStringLen(sql_handle, esc_mes, e->mes, strnlen(e->mes, sizeof(e->mes)));
- if (SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`guild_id`,`account_id`,`name`,`mes`) "
- "VALUES ('%d','%d','%s','%s')", guild_expulsion_db, g->guild_id, e->account_id, esc_name, esc_mes))
- Sql_ShowDebug(sql_handle);
- }
- }
- }
-
- if (flag&GS_SKILL) {
- strcat(t_info, " skills");
- //printf("- Insert guild %d to guild_skill\n",g->guild_id);
- for (i=0; i<MAX_GUILDSKILL; i++) {
- if (g->skill[i].id>0 && g->skill[i].lv>0) {
- if (SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`guild_id`,`id`,`lv`) VALUES ('%d','%d','%d')",
- guild_skill_db, g->guild_id, g->skill[i].id, g->skill[i].lv))
- Sql_ShowDebug(sql_handle);
- }
- }
- }
-
- if (save_log)
- ShowInfo("Saved guild (%d - %s):%s\n",g->guild_id,g->name,t_info);
- return 1;
+ Sql_EscapeStringLen(sql_handle, esc_name, g->name, strnlen(g->name, NAME_LENGTH));
+ Sql_EscapeStringLen(sql_handle, esc_master, g->master, strnlen(g->master, NAME_LENGTH));
+ *t_info = '\0';
+
+ // Insert a new guild the guild
+ if (flag&GS_BASIC && g->guild_id == -1)
+ {
+ strcat(t_info, " guild_create");
+
+ // Create a new guild
+ if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` "
+ "(`name`,`master`,`guild_lv`,`max_member`,`average_lv`,`char_id`) "
+ "VALUES ('%s', '%s', '%d', '%d', '%d', '%d')",
+ guild_db, esc_name, esc_master, g->guild_lv, g->max_member, g->average_lv, g->member[0].char_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ if (g->guild_id == -1)
+ return 0; //Failed to create guild!
+ }
+ else
+ {
+ g->guild_id = (int)Sql_LastInsertId(sql_handle);
+ new_guild = 1;
+ }
+ }
+
+ // If we need an update on an existing guild or more update on the new guild
+ if (((flag & GS_BASIC_MASK) && !new_guild) || ((flag & (GS_BASIC_MASK & ~GS_BASIC)) && new_guild))
+ {
+ StringBuf buf;
+ bool add_comma = false;
+
+ StringBuf_Init(&buf);
+ StringBuf_Printf(&buf, "UPDATE `%s` SET ", guild_db);
+
+ if (flag & GS_EMBLEM)
+ {
+ char emblem_data[sizeof(g->emblem_data)*2+1];
+ char* pData = emblem_data;
+
+ strcat(t_info, " emblem");
+ // Convert emblem_data to hex
+ //TODO: why not use binary directly? [ultramage]
+ for(i=0; i<g->emblem_len; i++){
+ *pData++ = dataToHex[(g->emblem_data[i] >> 4) & 0x0F];
+ *pData++ = dataToHex[g->emblem_data[i] & 0x0F];
+ }
+ *pData = 0;
+ StringBuf_Printf(&buf, "`emblem_len`=%d, `emblem_id`=%d, `emblem_data`='%s'", g->emblem_len, g->emblem_id, emblem_data);
+ add_comma = true;
+ }
+ if (flag & GS_BASIC)
+ {
+ strcat(t_info, " basic");
+ if( add_comma )
+ StringBuf_AppendStr(&buf, ", ");
+ else
+ add_comma = true;
+ StringBuf_Printf(&buf, "`name`='%s', `master`='%s', `char_id`=%d", esc_name, esc_master, g->member[0].char_id);
+ }
+ if (flag & GS_CONNECT)
+ {
+ strcat(t_info, " connect");
+ if( add_comma )
+ StringBuf_AppendStr(&buf, ", ");
+ else
+ add_comma = true;
+ StringBuf_Printf(&buf, "`connect_member`=%d, `average_lv`=%d", g->connect_member, g->average_lv);
+ }
+ if (flag & GS_MES)
+ {
+ char esc_mes1[sizeof(g->mes1)*2+1];
+ char esc_mes2[sizeof(g->mes2)*2+1];
+
+ strcat(t_info, " mes");
+ if( add_comma )
+ StringBuf_AppendStr(&buf, ", ");
+ else
+ add_comma = true;
+ Sql_EscapeStringLen(sql_handle, esc_mes1, g->mes1, strnlen(g->mes1, sizeof(g->mes1)));
+ Sql_EscapeStringLen(sql_handle, esc_mes2, g->mes2, strnlen(g->mes2, sizeof(g->mes2)));
+ StringBuf_Printf(&buf, "`mes1`='%s', `mes2`='%s'", esc_mes1, esc_mes2);
+ }
+ if (flag & GS_LEVEL)
+ {
+ strcat(t_info, " level");
+ if( add_comma )
+ StringBuf_AppendStr(&buf, ", ");
+ else
+ add_comma = true;
+ StringBuf_Printf(&buf, "`guild_lv`=%d, `skill_point`=%d, `exp`=%"PRIu64", `next_exp`=%u, `max_member`=%d", g->guild_lv, g->skill_point, g->exp, g->next_exp, g->max_member);
+ }
+ StringBuf_Printf(&buf, " WHERE `guild_id`=%d", g->guild_id);
+ if( SQL_ERROR == Sql_Query(sql_handle, "%s", StringBuf_Value(&buf)) )
+ Sql_ShowDebug(sql_handle);
+ StringBuf_Destroy(&buf);
+ }
+
+ if (flag&GS_MEMBER)
+ {
+ struct guild_member *m;
+
+ strcat(t_info, " members");
+ // Update only needed players
+ for(i=0;i<g->max_member;i++){
+ m = &g->member[i];
+ if (!m->modified)
+ continue;
+ if(m->account_id) {
+ //Since nothing references guild member table as foreign keys, it's safe to use REPLACE INTO
+ Sql_EscapeStringLen(sql_handle, esc_name, m->name, strnlen(m->name, NAME_LENGTH));
+ if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`guild_id`,`account_id`,`char_id`,`hair`,`hair_color`,`gender`,`class`,`lv`,`exp`,`exp_payper`,`online`,`position`,`name`) "
+ "VALUES ('%d','%d','%d','%d','%d','%d','%d','%d','%"PRIu64"','%d','%d','%d','%s')",
+ guild_member_db, 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, esc_name) )
+ Sql_ShowDebug(sql_handle);
+ if (m->modified & GS_MEMBER_NEW)
+ {
+ if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `guild_id` = '%d' WHERE `char_id` = '%d'",
+ char_db, g->guild_id, m->char_id) )
+ Sql_ShowDebug(sql_handle);
+ }
+ m->modified = GS_MEMBER_UNMODIFIED;
+ }
+ }
+ }
+
+ if (flag&GS_POSITION){
+ strcat(t_info, " positions");
+ //printf("- Insert guild %d to guild_position\n",g->guild_id);
+ for(i=0;i<MAX_GUILDPOSITION;i++){
+ struct guild_position *p = &g->position[i];
+ if (!p->modified)
+ continue;
+ Sql_EscapeStringLen(sql_handle, esc_name, p->name, strnlen(p->name, NAME_LENGTH));
+ if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`guild_id`,`position`,`name`,`mode`,`exp_mode`) VALUES ('%d','%d','%s','%d','%d')",
+ guild_position_db, g->guild_id, i, esc_name, p->mode, p->exp_mode) )
+ Sql_ShowDebug(sql_handle);
+ p->modified = GS_POSITION_UNMODIFIED;
+ }
+ }
+
+ if (flag&GS_ALLIANCE)
+ {
+ // Delete current alliances
+ // NOTE: no need to do it on both sides since both guilds in memory had
+ // their info changed, not to mention this would also mess up oppositions!
+ // [Skotlex]
+ //if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id`='%d' OR `alliance_id`='%d'", guild_alliance_db, g->guild_id, g->guild_id) )
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id`='%d'", guild_alliance_db, g->guild_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ }
+ else
+ {
+ //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)
+ {
+ Sql_EscapeStringLen(sql_handle, esc_name, a->name, strnlen(a->name, NAME_LENGTH));
+ if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`guild_id`,`opposition`,`alliance_id`,`name`) "
+ "VALUES ('%d','%d','%d','%s')",
+ guild_alliance_db, g->guild_id, a->opposition, a->guild_id, esc_name) )
+ Sql_ShowDebug(sql_handle);
+ }
+ }
+ }
+ }
+
+ if (flag&GS_EXPULSION){
+ strcat(t_info, " expulsions");
+ //printf("- Insert guild %d to guild_expulsion\n",g->guild_id);
+ for(i=0;i<MAX_GUILDEXPULSION;i++){
+ struct guild_expulsion *e=&g->expulsion[i];
+ if(e->account_id>0){
+ char esc_mes[sizeof(e->mes)*2+1];
+
+ Sql_EscapeStringLen(sql_handle, esc_name, e->name, strnlen(e->name, NAME_LENGTH));
+ Sql_EscapeStringLen(sql_handle, esc_mes, e->mes, strnlen(e->mes, sizeof(e->mes)));
+ if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`guild_id`,`account_id`,`name`,`mes`) "
+ "VALUES ('%d','%d','%s','%s')", guild_expulsion_db, g->guild_id, e->account_id, esc_name, esc_mes) )
+ Sql_ShowDebug(sql_handle);
+ }
+ }
+ }
+
+ if (flag&GS_SKILL){
+ strcat(t_info, " skills");
+ //printf("- Insert guild %d to guild_skill\n",g->guild_id);
+ for(i=0;i<MAX_GUILDSKILL;i++){
+ if (g->skill[i].id>0 && g->skill[i].lv>0){
+ if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`guild_id`,`id`,`lv`) VALUES ('%d','%d','%d')",
+ guild_skill_db, g->guild_id, g->skill[i].id, g->skill[i].lv) )
+ Sql_ShowDebug(sql_handle);
+ }
+ }
+ }
+
+ if (save_log)
+ ShowInfo("Saved guild (%d - %s):%s\n",g->guild_id,g->name,t_info);
+ return 1;
}
// Read guild from sql
-struct guild *inter_guild_fromsql(int guild_id) {
- struct guild *g;
- char *data;
- size_t len;
- char *p;
- int i;
+struct guild * inter_guild_fromsql(int guild_id)
+{
+ struct guild *g;
+ char* data;
+ size_t len;
+ char* p;
+ int i;
- if (guild_id <= 0)
- return NULL;
+ if( guild_id <= 0 )
+ return NULL;
- g = (struct guild *)idb_get(guild_db_, guild_id);
- if (g)
- return g;
+ g = (struct guild*)idb_get(guild_db_, guild_id);
+ if( g )
+ return g;
#ifdef NOISY
- ShowInfo("Guild load request (%d)...\n", guild_id);
+ ShowInfo("Guild load request (%d)...\n", guild_id);
#endif
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT g.`name`,c.`name`,g.`guild_lv`,g.`connect_member`,g.`max_member`,g.`average_lv`,g.`exp`,g.`next_exp`,g.`skill_point`,g.`mes1`,g.`mes2`,g.`emblem_len`,g.`emblem_id`,g.`emblem_data` "
- "FROM `%s` g LEFT JOIN `%s` c ON c.`char_id` = g.`char_id` WHERE g.`guild_id`='%d'", guild_db, char_db, guild_id)) {
- Sql_ShowDebug(sql_handle);
- return NULL;
- }
-
- if (SQL_SUCCESS != Sql_NextRow(sql_handle))
- return NULL;// Guild does not exists.
-
- CREATE(g, struct guild, 1);
-
- g->guild_id = guild_id;
- Sql_GetData(sql_handle, 0, &data, &len);
- memcpy(g->name, data, min(len, NAME_LENGTH));
- Sql_GetData(sql_handle, 1, &data, &len);
- memcpy(g->master, data, min(len, NAME_LENGTH));
- Sql_GetData(sql_handle, 2, &data, NULL);
- g->guild_lv = atoi(data);
- Sql_GetData(sql_handle, 3, &data, NULL);
- g->connect_member = atoi(data);
- Sql_GetData(sql_handle, 4, &data, NULL);
- g->max_member = atoi(data);
- if (g->max_member > MAX_GUILD) {
- // Fix reduction of MAX_GUILD [PoW]
- ShowWarning("Guild %d:%s specifies higher capacity (%d) than MAX_GUILD (%d)\n", guild_id, g->name, g->max_member, MAX_GUILD);
- g->max_member = MAX_GUILD;
- }
- Sql_GetData(sql_handle, 5, &data, NULL);
- g->average_lv = atoi(data);
- Sql_GetData(sql_handle, 6, &data, NULL);
- g->exp = strtoull(data, NULL, 10);
- Sql_GetData(sql_handle, 7, &data, NULL);
- g->next_exp = (unsigned int)strtoul(data, NULL, 10);
- Sql_GetData(sql_handle, 8, &data, NULL);
- g->skill_point = atoi(data);
- Sql_GetData(sql_handle, 9, &data, &len);
- memcpy(g->mes1, data, min(len, sizeof(g->mes1)));
- Sql_GetData(sql_handle, 10, &data, &len);
- memcpy(g->mes2, data, min(len, sizeof(g->mes2)));
- Sql_GetData(sql_handle, 11, &data, &len);
- g->emblem_len = atoi(data);
- Sql_GetData(sql_handle, 12, &data, &len);
- g->emblem_id = atoi(data);
- Sql_GetData(sql_handle, 13, &data, &len);
- // convert emblem data from hexadecimal to binary
- //TODO: why not store it in the db as binary directly? [ultramage]
- for (i = 0, p = g->emblem_data; i < g->emblem_len; ++i, ++p) {
- if (*data >= '0' && *data <= '9')
- *p = *data - '0';
- else if (*data >= 'a' && *data <= 'f')
- *p = *data - 'a' + 10;
- else if (*data >= 'A' && *data <= 'F')
- *p = *data - 'A' + 10;
- *p <<= 4;
- ++data;
-
- if (*data >= '0' && *data <= '9')
- *p |= *data - '0';
- else if (*data >= 'a' && *data <= 'f')
- *p |= *data - 'a' + 10;
- else if (*data >= 'A' && *data <= 'F')
- *p |= *data - 'A' + 10;
- ++data;
- }
-
- // load guild member info
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`char_id`,`hair`,`hair_color`,`gender`,`class`,`lv`,`exp`,`exp_payper`,`online`,`position`,`name` "
- "FROM `%s` WHERE `guild_id`='%d' ORDER BY `position`", guild_member_db, guild_id)) {
- Sql_ShowDebug(sql_handle);
- aFree(g);
- return NULL;
- }
- for (i = 0; i < g->max_member && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i) {
- struct guild_member *m = &g->member[i];
-
- Sql_GetData(sql_handle, 0, &data, NULL);
- m->account_id = atoi(data);
- Sql_GetData(sql_handle, 1, &data, NULL);
- m->char_id = atoi(data);
- Sql_GetData(sql_handle, 2, &data, NULL);
- m->hair = atoi(data);
- Sql_GetData(sql_handle, 3, &data, NULL);
- m->hair_color = atoi(data);
- Sql_GetData(sql_handle, 4, &data, NULL);
- m->gender = atoi(data);
- Sql_GetData(sql_handle, 5, &data, NULL);
- m->class_ = atoi(data);
- Sql_GetData(sql_handle, 6, &data, NULL);
- m->lv = atoi(data);
- Sql_GetData(sql_handle, 7, &data, NULL);
- m->exp = strtoull(data, NULL, 10);
- Sql_GetData(sql_handle, 8, &data, NULL);
- m->exp_payper = (unsigned int)atoi(data);
- Sql_GetData(sql_handle, 9, &data, NULL);
- m->online = atoi(data);
- Sql_GetData(sql_handle, 10, &data, NULL);
- m->position = atoi(data);
- if (m->position >= MAX_GUILDPOSITION) // Fix reduction of MAX_GUILDPOSITION [PoW]
- m->position = MAX_GUILDPOSITION - 1;
- Sql_GetData(sql_handle, 11, &data, &len);
- memcpy(m->name, data, min(len, NAME_LENGTH));
- m->modified = GS_MEMBER_UNMODIFIED;
- }
-
- //printf("- Read guild_position %d from sql \n",guild_id);
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `position`,`name`,`mode`,`exp_mode` FROM `%s` WHERE `guild_id`='%d'", guild_position_db, guild_id)) {
- Sql_ShowDebug(sql_handle);
- aFree(g);
- return NULL;
- }
- while (SQL_SUCCESS == Sql_NextRow(sql_handle)) {
- int position;
- struct guild_position *p;
-
- Sql_GetData(sql_handle, 0, &data, NULL);
- position = atoi(data);
- if (position < 0 || position >= MAX_GUILDPOSITION)
- continue;// invalid position
- p = &g->position[position];
- Sql_GetData(sql_handle, 1, &data, &len);
- memcpy(p->name, data, min(len, NAME_LENGTH));
- Sql_GetData(sql_handle, 2, &data, NULL);
- p->mode = atoi(data);
- Sql_GetData(sql_handle, 3, &data, NULL);
- p->exp_mode = atoi(data);
- p->modified = GS_POSITION_UNMODIFIED;
- }
-
- //printf("- Read guild_alliance %d from sql \n",guild_id);
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `opposition`,`alliance_id`,`name` FROM `%s` WHERE `guild_id`='%d'", guild_alliance_db, guild_id)) {
- Sql_ShowDebug(sql_handle);
- aFree(g);
- return NULL;
- }
- for (i = 0; i < MAX_GUILDALLIANCE && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i) {
- struct guild_alliance *a = &g->alliance[i];
-
- Sql_GetData(sql_handle, 0, &data, NULL);
- a->opposition = atoi(data);
- Sql_GetData(sql_handle, 1, &data, NULL);
- a->guild_id = atoi(data);
- Sql_GetData(sql_handle, 2, &data, &len);
- memcpy(a->name, data, min(len, NAME_LENGTH));
- }
-
- //printf("- Read guild_expulsion %d from sql \n",guild_id);
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`name`,`mes` FROM `%s` WHERE `guild_id`='%d'", guild_expulsion_db, guild_id)) {
- Sql_ShowDebug(sql_handle);
- aFree(g);
- return NULL;
- }
- for (i = 0; i < MAX_GUILDEXPULSION && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i) {
- struct guild_expulsion *e = &g->expulsion[i];
-
- Sql_GetData(sql_handle, 0, &data, NULL);
- e->account_id = atoi(data);
- Sql_GetData(sql_handle, 1, &data, &len);
- memcpy(e->name, data, min(len, NAME_LENGTH));
- Sql_GetData(sql_handle, 2, &data, &len);
- memcpy(e->mes, data, min(len, sizeof(e->mes)));
- }
-
- //printf("- Read guild_skill %d from sql \n",guild_id);
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `id`,`lv` FROM `%s` WHERE `guild_id`='%d' ORDER BY `id`", guild_skill_db, guild_id)) {
- Sql_ShowDebug(sql_handle);
- aFree(g);
- return NULL;
- }
-
- for (i = 0; i < MAX_GUILDSKILL; i++) {
- //Skill IDs must always be initialized. [Skotlex]
- g->skill[i].id = i + GD_SKILLBASE;
- }
-
- while (SQL_SUCCESS == Sql_NextRow(sql_handle)) {
- int id;
- Sql_GetData(sql_handle, 0, &data, NULL);
- id = atoi(data) - GD_SKILLBASE;
- if (id < 0 && id >= MAX_GUILDSKILL)
- continue;// invalid guild skill
- Sql_GetData(sql_handle, 1, &data, NULL);
- g->skill[id].lv = atoi(data);
- }
- Sql_FreeResult(sql_handle);
-
- idb_put(guild_db_, guild_id, g); //Add to cache
- g->save_flag |= GS_REMOVE; //But set it to be removed, in case it is not needed for long.
-
- if (save_log)
- ShowInfo("Guild loaded (%d - %s)\n", guild_id, g->name);
-
- return g;
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT g.`name`,c.`name`,g.`guild_lv`,g.`connect_member`,g.`max_member`,g.`average_lv`,g.`exp`,g.`next_exp`,g.`skill_point`,g.`mes1`,g.`mes2`,g.`emblem_len`,g.`emblem_id`,g.`emblem_data` "
+ "FROM `%s` g LEFT JOIN `%s` c ON c.`char_id` = g.`char_id` WHERE g.`guild_id`='%d'", guild_db, char_db, guild_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ return NULL;
+ }
+
+ if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
+ return NULL;// Guild does not exists.
+
+ CREATE(g, struct guild, 1);
+
+ g->guild_id = guild_id;
+ Sql_GetData(sql_handle, 0, &data, &len); memcpy(g->name, data, min(len, NAME_LENGTH));
+ Sql_GetData(sql_handle, 1, &data, &len); memcpy(g->master, data, min(len, NAME_LENGTH));
+ Sql_GetData(sql_handle, 2, &data, NULL); g->guild_lv = atoi(data);
+ Sql_GetData(sql_handle, 3, &data, NULL); g->connect_member = atoi(data);
+ Sql_GetData(sql_handle, 4, &data, NULL); g->max_member = atoi(data);
+ if( g->max_member > MAX_GUILD )
+ { // Fix reduction of MAX_GUILD [PoW]
+ ShowWarning("Guild %d:%s specifies higher capacity (%d) than MAX_GUILD (%d)\n", guild_id, g->name, g->max_member, MAX_GUILD);
+ g->max_member = MAX_GUILD;
+ }
+ Sql_GetData(sql_handle, 5, &data, NULL); g->average_lv = atoi(data);
+ Sql_GetData(sql_handle, 6, &data, NULL); g->exp = strtoull(data, NULL, 10);
+ Sql_GetData(sql_handle, 7, &data, NULL); g->next_exp = (unsigned int)strtoul(data, NULL, 10);
+ Sql_GetData(sql_handle, 8, &data, NULL); g->skill_point = atoi(data);
+ Sql_GetData(sql_handle, 9, &data, &len); memcpy(g->mes1, data, min(len, sizeof(g->mes1)));
+ Sql_GetData(sql_handle, 10, &data, &len); memcpy(g->mes2, data, min(len, sizeof(g->mes2)));
+ Sql_GetData(sql_handle, 11, &data, &len); g->emblem_len = atoi(data);
+ Sql_GetData(sql_handle, 12, &data, &len); g->emblem_id = atoi(data);
+ Sql_GetData(sql_handle, 13, &data, &len);
+ // convert emblem data from hexadecimal to binary
+ //TODO: why not store it in the db as binary directly? [ultramage]
+ for( i = 0, p = g->emblem_data; i < g->emblem_len; ++i, ++p )
+ {
+ if( *data >= '0' && *data <= '9' )
+ *p = *data - '0';
+ else if( *data >= 'a' && *data <= 'f' )
+ *p = *data - 'a' + 10;
+ else if( *data >= 'A' && *data <= 'F' )
+ *p = *data - 'A' + 10;
+ *p <<= 4;
+ ++data;
+
+ if( *data >= '0' && *data <= '9' )
+ *p |= *data - '0';
+ else if( *data >= 'a' && *data <= 'f' )
+ *p |= *data - 'a' + 10;
+ else if( *data >= 'A' && *data <= 'F' )
+ *p |= *data - 'A' + 10;
+ ++data;
+ }
+
+ // load guild member info
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`char_id`,`hair`,`hair_color`,`gender`,`class`,`lv`,`exp`,`exp_payper`,`online`,`position`,`name` "
+ "FROM `%s` WHERE `guild_id`='%d' ORDER BY `position`", guild_member_db, guild_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ aFree(g);
+ return NULL;
+ }
+ for( i = 0; i < g->max_member && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
+ {
+ struct guild_member* m = &g->member[i];
+
+ Sql_GetData(sql_handle, 0, &data, NULL); m->account_id = atoi(data);
+ Sql_GetData(sql_handle, 1, &data, NULL); m->char_id = atoi(data);
+ Sql_GetData(sql_handle, 2, &data, NULL); m->hair = atoi(data);
+ Sql_GetData(sql_handle, 3, &data, NULL); m->hair_color = atoi(data);
+ Sql_GetData(sql_handle, 4, &data, NULL); m->gender = atoi(data);
+ Sql_GetData(sql_handle, 5, &data, NULL); m->class_ = atoi(data);
+ Sql_GetData(sql_handle, 6, &data, NULL); m->lv = atoi(data);
+ Sql_GetData(sql_handle, 7, &data, NULL); m->exp = strtoull(data, NULL, 10);
+ Sql_GetData(sql_handle, 8, &data, NULL); m->exp_payper = (unsigned int)atoi(data);
+ Sql_GetData(sql_handle, 9, &data, NULL); m->online = atoi(data);
+ Sql_GetData(sql_handle, 10, &data, NULL); m->position = atoi(data);
+ if( m->position >= MAX_GUILDPOSITION ) // Fix reduction of MAX_GUILDPOSITION [PoW]
+ m->position = MAX_GUILDPOSITION - 1;
+ Sql_GetData(sql_handle, 11, &data, &len); memcpy(m->name, data, min(len, NAME_LENGTH));
+ m->modified = GS_MEMBER_UNMODIFIED;
+ }
+
+ //printf("- Read guild_position %d from sql \n",guild_id);
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `position`,`name`,`mode`,`exp_mode` FROM `%s` WHERE `guild_id`='%d'", guild_position_db, guild_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ aFree(g);
+ return NULL;
+ }
+ while( SQL_SUCCESS == Sql_NextRow(sql_handle) )
+ {
+ int position;
+ struct guild_position* p;
+
+ Sql_GetData(sql_handle, 0, &data, NULL); position = atoi(data);
+ if( position < 0 || position >= MAX_GUILDPOSITION )
+ continue;// invalid position
+ p = &g->position[position];
+ Sql_GetData(sql_handle, 1, &data, &len); memcpy(p->name, data, min(len, NAME_LENGTH));
+ Sql_GetData(sql_handle, 2, &data, NULL); p->mode = atoi(data);
+ Sql_GetData(sql_handle, 3, &data, NULL); p->exp_mode = atoi(data);
+ p->modified = GS_POSITION_UNMODIFIED;
+ }
+
+ //printf("- Read guild_alliance %d from sql \n",guild_id);
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `opposition`,`alliance_id`,`name` FROM `%s` WHERE `guild_id`='%d'", guild_alliance_db, guild_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ aFree(g);
+ return NULL;
+ }
+ for( i = 0; i < MAX_GUILDALLIANCE && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
+ {
+ struct guild_alliance* a = &g->alliance[i];
+
+ Sql_GetData(sql_handle, 0, &data, NULL); a->opposition = atoi(data);
+ Sql_GetData(sql_handle, 1, &data, NULL); a->guild_id = atoi(data);
+ Sql_GetData(sql_handle, 2, &data, &len); memcpy(a->name, data, min(len, NAME_LENGTH));
+ }
+
+ //printf("- Read guild_expulsion %d from sql \n",guild_id);
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`name`,`mes` FROM `%s` WHERE `guild_id`='%d'", guild_expulsion_db, guild_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ aFree(g);
+ return NULL;
+ }
+ for( i = 0; i < MAX_GUILDEXPULSION && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
+ {
+ struct guild_expulsion *e = &g->expulsion[i];
+
+ Sql_GetData(sql_handle, 0, &data, NULL); e->account_id = atoi(data);
+ Sql_GetData(sql_handle, 1, &data, &len); memcpy(e->name, data, min(len, NAME_LENGTH));
+ Sql_GetData(sql_handle, 2, &data, &len); memcpy(e->mes, data, min(len, sizeof(e->mes)));
+ }
+
+ //printf("- Read guild_skill %d from sql \n",guild_id);
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `id`,`lv` FROM `%s` WHERE `guild_id`='%d' ORDER BY `id`", guild_skill_db, guild_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ aFree(g);
+ return NULL;
+ }
+
+ for(i = 0; i < MAX_GUILDSKILL; i++)
+ { //Skill IDs must always be initialized. [Skotlex]
+ g->skill[i].id = i + GD_SKILLBASE;
+ }
+
+ while( SQL_SUCCESS == Sql_NextRow(sql_handle) )
+ {
+ int id;
+ Sql_GetData(sql_handle, 0, &data, NULL); id = atoi(data) - GD_SKILLBASE;
+ if( id < 0 && id >= MAX_GUILDSKILL )
+ continue;// invalid guild skill
+ Sql_GetData(sql_handle, 1, &data, NULL); g->skill[id].lv = atoi(data);
+ }
+ Sql_FreeResult(sql_handle);
+
+ idb_put(guild_db_, guild_id, g); //Add to cache
+ g->save_flag |= GS_REMOVE; //But set it to be removed, in case it is not needed for long.
+
+ if (save_log)
+ ShowInfo("Guild loaded (%d - %s)\n", guild_id, g->name);
+
+ return g;
}
// `guild_castle` (`castle_id`, `guild_id`, `economy`, `defense`, `triggerE`, `triggerD`, `nextTime`, `payTime`, `createTime`, `visibleC`, `visibleG0`, `visibleG1`, `visibleG2`, `visibleG3`, `visibleG4`, `visibleG5`, `visibleG6`, `visibleG7`)
int inter_guildcastle_tosql(struct guild_castle *gc)
{
- StringBuf buf;
- int i;
-
- StringBuf_Init(&buf);
- StringBuf_Printf(&buf, "REPLACE INTO `%s` SET `castle_id`='%d', `guild_id`='%d', `economy`='%d', `defense`='%d', "
- "`triggerE`='%d', `triggerD`='%d', `nextTime`='%d', `payTime`='%d', `createTime`='%d', `visibleC`='%d'",
- 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);
- for (i = 0; i < MAX_GUARDIANS; ++i)
- StringBuf_Printf(&buf, ", `visibleG%d`='%d'", i, gc->guardian[i].visible);
-
- if (SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf)))
- Sql_ShowDebug(sql_handle);
- else if (save_log)
- ShowInfo("Saved guild castle (%d)\n", gc->castle_id);
-
- StringBuf_Destroy(&buf);
- return 0;
+ StringBuf buf;
+ int i;
+
+ StringBuf_Init(&buf);
+ StringBuf_Printf(&buf, "REPLACE INTO `%s` SET `castle_id`='%d', `guild_id`='%d', `economy`='%d', `defense`='%d', "
+ "`triggerE`='%d', `triggerD`='%d', `nextTime`='%d', `payTime`='%d', `createTime`='%d', `visibleC`='%d'",
+ 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);
+ for (i = 0; i < MAX_GUARDIANS; ++i)
+ StringBuf_Printf(&buf, ", `visibleG%d`='%d'", i, gc->guardian[i].visible);
+
+ if (SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf)))
+ Sql_ShowDebug(sql_handle);
+ else if(save_log)
+ ShowInfo("Saved guild castle (%d)\n", gc->castle_id);
+
+ StringBuf_Destroy(&buf);
+ return 0;
}
// Read guild_castle from SQL
-static struct guild_castle *inter_guildcastle_fromsql(int castle_id) {
- char *data;
- int i;
- StringBuf buf;
- struct guild_castle *gc = idb_get(castle_db, castle_id);
-
- if (gc != NULL)
- return gc;
-
- StringBuf_Init(&buf);
- StringBuf_AppendStr(&buf, "SELECT `castle_id`, `guild_id`, `economy`, `defense`, `triggerE`, "
- "`triggerD`, `nextTime`, `payTime`, `createTime`, `visibleC`");
- for (i = 0; i < MAX_GUARDIANS; ++i)
- StringBuf_Printf(&buf, ", `visibleG%d`", i);
- StringBuf_Printf(&buf, " FROM `%s` WHERE `castle_id`='%d'", guild_castle_db, castle_id);
- if (SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf))) {
- Sql_ShowDebug(sql_handle);
- StringBuf_Destroy(&buf);
- return NULL;
- }
- StringBuf_Destroy(&buf);
-
- CREATE(gc, struct guild_castle, 1);
- gc->castle_id = castle_id;
-
- if (SQL_SUCCESS == Sql_NextRow(sql_handle)) {
- Sql_GetData(sql_handle, 1, &data, NULL);
- gc->guild_id = atoi(data);
- Sql_GetData(sql_handle, 2, &data, NULL);
- gc->economy = atoi(data);
- Sql_GetData(sql_handle, 3, &data, NULL);
- gc->defense = atoi(data);
- Sql_GetData(sql_handle, 4, &data, NULL);
- gc->triggerE = atoi(data);
- Sql_GetData(sql_handle, 5, &data, NULL);
- gc->triggerD = atoi(data);
- Sql_GetData(sql_handle, 6, &data, NULL);
- gc->nextTime = atoi(data);
- Sql_GetData(sql_handle, 7, &data, NULL);
- gc->payTime = atoi(data);
- Sql_GetData(sql_handle, 8, &data, NULL);
- gc->createTime = atoi(data);
- Sql_GetData(sql_handle, 9, &data, NULL);
- gc->visibleC = atoi(data);
- for (i = 10; i < 10+MAX_GUARDIANS; i++) {
- Sql_GetData(sql_handle, i, &data, NULL);
- gc->guardian[i-10].visible = atoi(data);
- }
- }
- Sql_FreeResult(sql_handle);
-
- idb_put(castle_db, castle_id, gc);
-
- if (save_log)
- ShowInfo("Loaded guild castle (%d - guild %d)\n", castle_id, gc->guild_id);
-
- return gc;
+static struct guild_castle* inter_guildcastle_fromsql(int castle_id)
+{
+ char *data;
+ int i;
+ StringBuf buf;
+ struct guild_castle *gc = idb_get(castle_db, castle_id);
+
+ if (gc != NULL)
+ return gc;
+
+ StringBuf_Init(&buf);
+ StringBuf_AppendStr(&buf, "SELECT `castle_id`, `guild_id`, `economy`, `defense`, `triggerE`, "
+ "`triggerD`, `nextTime`, `payTime`, `createTime`, `visibleC`");
+ for (i = 0; i < MAX_GUARDIANS; ++i)
+ StringBuf_Printf(&buf, ", `visibleG%d`", i);
+ StringBuf_Printf(&buf, " FROM `%s` WHERE `castle_id`='%d'", guild_castle_db, castle_id);
+ if (SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf))) {
+ Sql_ShowDebug(sql_handle);
+ StringBuf_Destroy(&buf);
+ return NULL;
+ }
+ StringBuf_Destroy(&buf);
+
+ CREATE(gc, struct guild_castle, 1);
+ gc->castle_id = castle_id;
+
+ if (SQL_SUCCESS == Sql_NextRow(sql_handle)) {
+ Sql_GetData(sql_handle, 1, &data, NULL); gc->guild_id = atoi(data);
+ Sql_GetData(sql_handle, 2, &data, NULL); gc->economy = atoi(data);
+ Sql_GetData(sql_handle, 3, &data, NULL); gc->defense = atoi(data);
+ Sql_GetData(sql_handle, 4, &data, NULL); gc->triggerE = atoi(data);
+ Sql_GetData(sql_handle, 5, &data, NULL); gc->triggerD = atoi(data);
+ Sql_GetData(sql_handle, 6, &data, NULL); gc->nextTime = atoi(data);
+ Sql_GetData(sql_handle, 7, &data, NULL); gc->payTime = atoi(data);
+ Sql_GetData(sql_handle, 8, &data, NULL); gc->createTime = atoi(data);
+ Sql_GetData(sql_handle, 9, &data, NULL); gc->visibleC = atoi(data);
+ for (i = 10; i < 10+MAX_GUARDIANS; i++) {
+ Sql_GetData(sql_handle, i, &data, NULL); gc->guardian[i-10].visible = atoi(data);
+ }
+ }
+ Sql_FreeResult(sql_handle);
+
+ idb_put(castle_db, castle_id, gc);
+
+ if (save_log)
+ ShowInfo("Loaded guild castle (%d - guild %d)\n", castle_id, gc->guild_id);
+
+ return gc;
}
// Read exp_guild.txt
int inter_guild_ReadEXP(void)
{
- int i;
- FILE *fp;
- char line[1024];
- for (i=0; i<100; i++) guild_exp[i]=0;
- //this is going to be discussed, temp fix
- sprintf(line, "%s/pre-re/exp_guild.txt", db_path);
- fp=fopen(line,"r");
- if (fp==NULL) {
- ShowError("can't read %s\n", line);
- return 1;
- }
- i=0;
- while (fgets(line, sizeof(line), fp) && i < 100) {
- if (line[0]=='/' && line[1]=='/')
- continue;
- guild_exp[i]=(unsigned int)atof(line);
- i++;
- }
- fclose(fp);
-
- return 0;
+ int i;
+ FILE *fp;
+ char line[1024];
+ for (i=0;i<100;i++) guild_exp[i]=0;
+ //this is going to be discussed, temp fix
+ sprintf(line, "%s/pre-re/exp_guild.txt", db_path);
+ fp=fopen(line,"r");
+ if(fp==NULL){
+ ShowError("can't read %s\n", line);
+ return 1;
+ }
+ i=0;
+ while(fgets(line, sizeof(line), fp) && i < 100)
+ {
+ if(line[0]=='/' && line[1]=='/')
+ continue;
+ guild_exp[i]=(unsigned int)atof(line);
+ i++;
+ }
+ fclose(fp);
+
+ return 0;
}
int inter_guild_CharOnline(int char_id, int guild_id)
{
- struct guild *g;
- int i;
-
- if (guild_id == -1) {
- //Get guild_id from the database
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT guild_id FROM `%s` WHERE char_id='%d'", char_db, char_id)) {
- Sql_ShowDebug(sql_handle);
- return 0;
- }
-
- if (SQL_SUCCESS == Sql_NextRow(sql_handle)) {
- char *data;
-
- Sql_GetData(sql_handle, 0, &data, NULL);
- guild_id = atoi(data);
- } else {
- guild_id = 0;
- }
- Sql_FreeResult(sql_handle);
- }
- if (guild_id == 0)
- return 0; //No guild...
-
- g = inter_guild_fromsql(guild_id);
- if (!g) {
- ShowError("Character %d's guild %d not found!\n", char_id, guild_id);
- return 0;
- }
-
- //Member has logged in before saving, tell saver not to delete
- if (g->save_flag & GS_REMOVE)
- g->save_flag &= ~GS_REMOVE;
-
- //Set member online
- ARR_FIND(0, g->max_member, i, g->member[i].char_id == char_id);
- if (i < g->max_member) {
- g->member[i].online = 1;
- g->member[i].modified = GS_MEMBER_MODIFIED;
- }
-
- return 1;
+ struct guild *g;
+ int i;
+
+ if (guild_id == -1) {
+ //Get guild_id from the database
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT guild_id FROM `%s` WHERE char_id='%d'", char_db, char_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ return 0;
+ }
+
+ if( SQL_SUCCESS == Sql_NextRow(sql_handle) )
+ {
+ char* data;
+
+ Sql_GetData(sql_handle, 0, &data, NULL);
+ guild_id = atoi(data);
+ }
+ else
+ {
+ guild_id = 0;
+ }
+ Sql_FreeResult(sql_handle);
+ }
+ if (guild_id == 0)
+ return 0; //No guild...
+
+ g = inter_guild_fromsql(guild_id);
+ if(!g) {
+ ShowError("Character %d's guild %d not found!\n", char_id, guild_id);
+ return 0;
+ }
+
+ //Member has logged in before saving, tell saver not to delete
+ if(g->save_flag & GS_REMOVE)
+ g->save_flag &= ~GS_REMOVE;
+
+ //Set member online
+ ARR_FIND( 0, g->max_member, i, g->member[i].char_id == char_id );
+ if( i < g->max_member )
+ {
+ g->member[i].online = 1;
+ g->member[i].modified = GS_MEMBER_MODIFIED;
+ }
+
+ return 1;
}
int inter_guild_CharOffline(int char_id, int guild_id)
{
- struct guild *g=NULL;
- int online_count, i;
-
- if (guild_id == -1) {
- //Get guild_id from the database
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT guild_id FROM `%s` WHERE char_id='%d'", char_db, char_id)) {
- Sql_ShowDebug(sql_handle);
- return 0;
- }
-
- if (SQL_SUCCESS == Sql_NextRow(sql_handle)) {
- char *data;
-
- Sql_GetData(sql_handle, 0, &data, NULL);
- guild_id = atoi(data);
- } else {
- guild_id = 0;
- }
- Sql_FreeResult(sql_handle);
- }
- if (guild_id == 0)
- return 0; //No guild...
-
- //Character has a guild, set character offline and check if they were the only member online
- g = inter_guild_fromsql(guild_id);
- if (g == NULL) //Guild not found?
- return 0;
-
- //Set member offline
- ARR_FIND(0, g->max_member, i, g->member[i].char_id == char_id);
- if (i < g->max_member) {
- g->member[i].online = 0;
- g->member[i].modified = GS_MEMBER_MODIFIED;
- }
-
- online_count = 0;
- for (i = 0; i < g->max_member; i++)
- if (g->member[i].online)
- online_count++;
-
- // Remove guild from memory if no players online
- if (online_count == 0)
- g->save_flag |= GS_REMOVE;
-
- return 1;
+ struct guild *g=NULL;
+ int online_count, i;
+
+ if (guild_id == -1)
+ {
+ //Get guild_id from the database
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT guild_id FROM `%s` WHERE char_id='%d'", char_db, char_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ return 0;
+ }
+
+ if( SQL_SUCCESS == Sql_NextRow(sql_handle) )
+ {
+ char* data;
+
+ Sql_GetData(sql_handle, 0, &data, NULL);
+ guild_id = atoi(data);
+ }
+ else
+ {
+ guild_id = 0;
+ }
+ Sql_FreeResult(sql_handle);
+ }
+ if (guild_id == 0)
+ return 0; //No guild...
+
+ //Character has a guild, set character offline and check if they were the only member online
+ g = inter_guild_fromsql(guild_id);
+ if (g == NULL) //Guild not found?
+ return 0;
+
+ //Set member offline
+ ARR_FIND( 0, g->max_member, i, g->member[i].char_id == char_id );
+ if( i < g->max_member )
+ {
+ g->member[i].online = 0;
+ g->member[i].modified = GS_MEMBER_MODIFIED;
+ }
+
+ online_count = 0;
+ for( i = 0; i < g->max_member; i++ )
+ if( g->member[i].online )
+ online_count++;
+
+ // Remove guild from memory if no players online
+ if( online_count == 0 )
+ g->save_flag |= GS_REMOVE;
+
+ return 1;
}
// Initialize guild sql
int inter_guild_sql_init(void)
{
- //Initialize the guild cache
- guild_db_= idb_alloc(DB_OPT_RELEASE_DATA);
- castle_db = idb_alloc(DB_OPT_RELEASE_DATA);
-
- //Read exp file
- inter_guild_ReadEXP();
-
- add_timer_func_list(guild_save_timer, "guild_save_timer");
- add_timer(gettick() + 10000, guild_save_timer, 0, 0);
- return 0;
+ //Initialize the guild cache
+ guild_db_= idb_alloc(DB_OPT_RELEASE_DATA);
+ castle_db = idb_alloc(DB_OPT_RELEASE_DATA);
+
+ //Read exp file
+ inter_guild_ReadEXP();
+
+ add_timer_func_list(guild_save_timer, "guild_save_timer");
+ add_timer(gettick() + 10000, guild_save_timer, 0, 0);
+ return 0;
}
/**
@@ -751,134 +751,145 @@ int inter_guild_sql_init(void)
*/
static int guild_db_final(DBKey key, DBData *data, va_list ap)
{
- struct guild *g = db_data2ptr(data);
- if (g->save_flag&GS_MASK) {
- inter_guild_tosql(g, g->save_flag&GS_MASK);
- return 1;
- }
- return 0;
+ struct guild *g = db_data2ptr(data);
+ if (g->save_flag&GS_MASK) {
+ inter_guild_tosql(g, g->save_flag&GS_MASK);
+ return 1;
+ }
+ return 0;
}
void inter_guild_sql_final(void)
{
- guild_db_->destroy(guild_db_, guild_db_final);
- db_destroy(castle_db);
- return;
+ guild_db_->destroy(guild_db_, guild_db_final);
+ db_destroy(castle_db);
+ return;
}
// Get guild_id by its name. Returns 0 if not found, -1 on error.
int search_guildname(char *str)
{
- int guild_id;
- char esc_name[NAME_LENGTH*2+1];
-
- Sql_EscapeStringLen(sql_handle, esc_name, str, safestrnlen(str, NAME_LENGTH));
- //Lookup guilds with the same name
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT guild_id FROM `%s` WHERE name='%s'", guild_db, esc_name)) {
- Sql_ShowDebug(sql_handle);
- return -1;
- }
-
- if (SQL_SUCCESS == Sql_NextRow(sql_handle)) {
- char *data;
-
- Sql_GetData(sql_handle, 0, &data, NULL);
- guild_id = atoi(data);
- } else {
- guild_id = 0;
- }
- Sql_FreeResult(sql_handle);
- return guild_id;
+ int guild_id;
+ char esc_name[NAME_LENGTH*2+1];
+
+ Sql_EscapeStringLen(sql_handle, esc_name, str, safestrnlen(str, NAME_LENGTH));
+ //Lookup guilds with the same name
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT guild_id FROM `%s` WHERE name='%s'", guild_db, esc_name) )
+ {
+ Sql_ShowDebug(sql_handle);
+ return -1;
+ }
+
+ if( SQL_SUCCESS == Sql_NextRow(sql_handle) )
+ {
+ char* data;
+
+ Sql_GetData(sql_handle, 0, &data, NULL);
+ guild_id = atoi(data);
+ }
+ else
+ {
+ guild_id = 0;
+ }
+ Sql_FreeResult(sql_handle);
+ return guild_id;
}
// Check if guild is empty
static bool guild_check_empty(struct guild *g)
{
- int i;
- ARR_FIND(0, g->max_member, i, g->member[i].account_id > 0);
- if (i < g->max_member)
- return false; // not empty
-
- //Let the calling function handle the guild removal in case they need
- //to do something else with it before freeing the data. [Skotlex]
- return true;
+ int i;
+ ARR_FIND( 0, g->max_member, i, g->member[i].account_id > 0 );
+ if( i < g->max_member)
+ return false; // not empty
+
+ //Let the calling function handle the guild removal in case they need
+ //to do something else with it before freeing the data. [Skotlex]
+ return true;
}
unsigned int guild_nextexp(int level)
{
- if (level == 0)
- return 1;
- if (level < 100 && level > 0) // Change by hack
- return guild_exp[level-1];
+ if (level == 0)
+ return 1;
+ if (level < 100 && level > 0) // Change by hack
+ return guild_exp[level-1];
- return 0;
+ return 0;
}
int guild_checkskill(struct guild *g,int id)
{
- int idx = id - GD_SKILLBASE;
+ int idx = id - GD_SKILLBASE;
- if (idx < 0 || idx >= MAX_GUILDSKILL)
- return 0;
+ if(idx < 0 || idx >= MAX_GUILDSKILL)
+ return 0;
- return g->skill[idx].lv;
+ return g->skill[idx].lv;
}
int guild_calcinfo(struct guild *g)
{
- int i,c;
- unsigned int nextexp;
- struct guild before = *g; // Save guild current values
-
- if (g->guild_lv<=0)
- g->guild_lv = 1;
- nextexp = guild_nextexp(g->guild_lv);
-
- // Consume guild exp and increase guild level
- while (g->exp >= nextexp && nextexp > 0) { //fixed guild exp overflow [Kevin]
- g->exp-=nextexp;
- g->guild_lv++;
- g->skill_point++;
- nextexp = guild_nextexp(g->guild_lv);
- }
-
- // Save next exp step
- g->next_exp = nextexp;
-
- // Set the max number of members, Guild Extention skill - currently adds 6 to max per skill lv.
- g->max_member = 16 + guild_checkskill(g, GD_EXTENSION) * 6;
- if (g->max_member > MAX_GUILD) {
- ShowError("Guild %d:%s has capacity for too many guild members (%d), max supported is %d\n", g->guild_id, g->name, g->max_member, MAX_GUILD);
- g->max_member = MAX_GUILD;
- }
-
- // Compute the guild average level level
- g->average_lv=0;
- g->connect_member=0;
- for (i=c=0; i<g->max_member; i++) {
- if (g->member[i].account_id>0) {
- if (g->member[i].lv >= 0) {
- g->average_lv+=g->member[i].lv;
- c++;
- } else {
- ShowWarning("Guild %d:%s, member %d:%s has an invalid level %d\n", g->guild_id, g->name, g->member[i].char_id, g->member[i].name, g->member[i].lv);
- }
-
- if (g->member[i].online)
- g->connect_member++;
- }
- }
- if (c)
- g->average_lv /= c;
-
- // Check if guild stats has change
- if (g->max_member != before.max_member || g->guild_lv != before.guild_lv || g->skill_point != before.skill_point) {
- g->save_flag |= GS_LEVEL;
- mapif_guild_info(-1,g);
- return 1;
- }
-
- return 0;
+ int i,c;
+ unsigned int nextexp;
+ struct guild before = *g; // Save guild current values
+
+ if(g->guild_lv<=0)
+ g->guild_lv = 1;
+ nextexp = guild_nextexp(g->guild_lv);
+
+ // Consume guild exp and increase guild level
+ while(g->exp >= nextexp && nextexp > 0){ //fixed guild exp overflow [Kevin]
+ g->exp-=nextexp;
+ g->guild_lv++;
+ g->skill_point++;
+ nextexp = guild_nextexp(g->guild_lv);
+ }
+
+ // Save next exp step
+ g->next_exp = nextexp;
+
+ // Set the max number of members, Guild Extention skill - currently adds 6 to max per skill lv.
+ g->max_member = 16 + guild_checkskill(g, GD_EXTENSION) * 6;
+ if(g->max_member > MAX_GUILD)
+ {
+ ShowError("Guild %d:%s has capacity for too many guild members (%d), max supported is %d\n", g->guild_id, g->name, g->max_member, MAX_GUILD);
+ g->max_member = MAX_GUILD;
+ }
+
+ // Compute the guild average level level
+ g->average_lv=0;
+ g->connect_member=0;
+ for(i=c=0;i<g->max_member;i++)
+ {
+ if(g->member[i].account_id>0)
+ {
+ if (g->member[i].lv >= 0)
+ {
+ g->average_lv+=g->member[i].lv;
+ c++;
+ }
+ else
+ {
+ ShowWarning("Guild %d:%s, member %d:%s has an invalid level %d\n", g->guild_id, g->name, g->member[i].char_id, g->member[i].name, g->member[i].lv);
+ }
+
+ if(g->member[i].online)
+ g->connect_member++;
+ }
+ }
+ if(c)
+ g->average_lv /= c;
+
+ // Check if guild stats has change
+ if(g->max_member != before.max_member || g->guild_lv != before.guild_lv || g->skill_point != before.skill_point )
+ {
+ g->save_flag |= GS_LEVEL;
+ mapif_guild_info(-1,g);
+ return 1;
+ }
+
+ return 0;
}
//-------------------------------------------------------------------
@@ -886,244 +897,245 @@ int guild_calcinfo(struct guild *g)
int mapif_guild_created(int fd,int account_id,struct guild *g)
{
- WFIFOHEAD(fd, 10);
- WFIFOW(fd,0)=0x3830;
- WFIFOL(fd,2)=account_id;
- if (g != NULL) {
- WFIFOL(fd,6)=g->guild_id;
- ShowInfo("int_guild: Guild created (%d - %s)\n",g->guild_id,g->name);
- } else
- WFIFOL(fd,6)=0;
-
- WFIFOSET(fd,10);
- return 0;
+ WFIFOHEAD(fd, 10);
+ WFIFOW(fd,0)=0x3830;
+ WFIFOL(fd,2)=account_id;
+ if(g != NULL)
+ {
+ WFIFOL(fd,6)=g->guild_id;
+ ShowInfo("int_guild: Guild created (%d - %s)\n",g->guild_id,g->name);
+ } else
+ WFIFOL(fd,6)=0;
+
+ WFIFOSET(fd,10);
+ return 0;
}
// Guild not found
int mapif_guild_noinfo(int fd,int guild_id)
{
- unsigned char buf[12];
- WBUFW(buf,0)=0x3831;
- WBUFW(buf,2)=8;
- WBUFL(buf,4)=guild_id;
- ShowWarning("int_guild: info not found %d\n",guild_id);
- if (fd<0)
- mapif_sendall(buf,8);
- else
- mapif_send(fd,buf,8);
- return 0;
+ unsigned char buf[12];
+ WBUFW(buf,0)=0x3831;
+ WBUFW(buf,2)=8;
+ WBUFL(buf,4)=guild_id;
+ ShowWarning("int_guild: info not found %d\n",guild_id);
+ if(fd<0)
+ mapif_sendall(buf,8);
+ else
+ mapif_send(fd,buf,8);
+ return 0;
}
// Send guild info
int mapif_guild_info(int fd,struct guild *g)
{
- unsigned char buf[8+sizeof(struct guild)];
- WBUFW(buf,0)=0x3831;
- WBUFW(buf,2)=4+sizeof(struct guild);
- memcpy(buf+4,g,sizeof(struct guild));
- if (fd<0)
- mapif_sendall(buf,WBUFW(buf,2));
- else
- mapif_send(fd,buf,WBUFW(buf,2));
- return 0;
+ unsigned char buf[8+sizeof(struct guild)];
+ WBUFW(buf,0)=0x3831;
+ WBUFW(buf,2)=4+sizeof(struct guild);
+ memcpy(buf+4,g,sizeof(struct guild));
+ if(fd<0)
+ mapif_sendall(buf,WBUFW(buf,2));
+ else
+ mapif_send(fd,buf,WBUFW(buf,2));
+ return 0;
}
// ACK member add
int mapif_guild_memberadded(int fd,int guild_id,int account_id,int char_id,int flag)
{
- WFIFOHEAD(fd, 15);
- WFIFOW(fd,0)=0x3832;
- WFIFOL(fd,2)=guild_id;
- WFIFOL(fd,6)=account_id;
- WFIFOL(fd,10)=char_id;
- WFIFOB(fd,14)=flag;
- WFIFOSET(fd,15);
- return 0;
+ WFIFOHEAD(fd, 15);
+ WFIFOW(fd,0)=0x3832;
+ WFIFOL(fd,2)=guild_id;
+ WFIFOL(fd,6)=account_id;
+ WFIFOL(fd,10)=char_id;
+ WFIFOB(fd,14)=flag;
+ WFIFOSET(fd,15);
+ return 0;
}
// ACK member leave
int mapif_guild_withdraw(int guild_id,int account_id,int char_id,int flag, const char *name, const char *mes)
{
- unsigned char buf[55+NAME_LENGTH];
- WBUFW(buf, 0)=0x3834;
- WBUFL(buf, 2)=guild_id;
- WBUFL(buf, 6)=account_id;
- WBUFL(buf,10)=char_id;
- WBUFB(buf,14)=flag;
- memcpy(WBUFP(buf,15),mes,40);
- memcpy(WBUFP(buf,55),name,NAME_LENGTH);
- mapif_sendall(buf,55+NAME_LENGTH);
- ShowInfo("int_guild: guild withdraw (%d - %d: %s - %s)\n",guild_id,account_id,name,mes);
- return 0;
+ unsigned char buf[55+NAME_LENGTH];
+ WBUFW(buf, 0)=0x3834;
+ WBUFL(buf, 2)=guild_id;
+ WBUFL(buf, 6)=account_id;
+ WBUFL(buf,10)=char_id;
+ WBUFB(buf,14)=flag;
+ memcpy(WBUFP(buf,15),mes,40);
+ memcpy(WBUFP(buf,55),name,NAME_LENGTH);
+ mapif_sendall(buf,55+NAME_LENGTH);
+ ShowInfo("int_guild: guild withdraw (%d - %d: %s - %s)\n",guild_id,account_id,name,mes);
+ return 0;
}
// Send short member's info
int mapif_guild_memberinfoshort(struct guild *g,int idx)
{
- unsigned char buf[19];
- WBUFW(buf, 0)=0x3835;
- 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)=(unsigned char)g->member[idx].online;
- WBUFW(buf,15)=g->member[idx].lv;
- WBUFW(buf,17)=g->member[idx].class_;
- mapif_sendall(buf,19);
- return 0;
+ unsigned char buf[19];
+ WBUFW(buf, 0)=0x3835;
+ 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)=(unsigned char)g->member[idx].online;
+ WBUFW(buf,15)=g->member[idx].lv;
+ WBUFW(buf,17)=g->member[idx].class_;
+ mapif_sendall(buf,19);
+ return 0;
}
// Send guild broken
int mapif_guild_broken(int guild_id,int flag)
{
- unsigned char buf[7];
- WBUFW(buf,0)=0x3836;
- WBUFL(buf,2)=guild_id;
- WBUFB(buf,6)=flag;
- mapif_sendall(buf,7);
- ShowInfo("int_guild: Guild broken (%d)\n",guild_id);
- return 0;
+ unsigned char buf[7];
+ WBUFW(buf,0)=0x3836;
+ WBUFL(buf,2)=guild_id;
+ WBUFB(buf,6)=flag;
+ mapif_sendall(buf,7);
+ ShowInfo("int_guild: Guild broken (%d)\n",guild_id);
+ return 0;
}
// Send guild message
int mapif_guild_message(int guild_id,int account_id,char *mes,int len, int sfd)
{
- unsigned char buf[512];
- if (len > 500)
- len = 500;
- 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_sendallwos(sfd, buf,len+12);
- return 0;
+ unsigned char buf[512];
+ if (len > 500)
+ len = 500;
+ 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_sendallwos(sfd, buf,len+12);
+ return 0;
}
// Send basic info
int mapif_guild_basicinfochanged(int guild_id,int type,const void *data,int len)
{
- unsigned char buf[2048];
- if (len > 2038)
- len = 2038;
- WBUFW(buf, 0)=0x3839;
- WBUFW(buf, 2)=len+10;
- WBUFL(buf, 4)=guild_id;
- WBUFW(buf, 8)=type;
- memcpy(WBUFP(buf,10),data,len);
- mapif_sendall(buf,len+10);
- return 0;
+ unsigned char buf[2048];
+ if (len > 2038)
+ len = 2038;
+ WBUFW(buf, 0)=0x3839;
+ WBUFW(buf, 2)=len+10;
+ WBUFL(buf, 4)=guild_id;
+ WBUFW(buf, 8)=type;
+ memcpy(WBUFP(buf,10),data,len);
+ mapif_sendall(buf,len+10);
+ return 0;
}
// Send member info
int mapif_guild_memberinfochanged(int guild_id,int account_id,int char_id, int type,const void *data,int len)
{
- unsigned char buf[2048];
- if (len > 2030)
- len = 2030;
- WBUFW(buf, 0)=0x383a;
- WBUFW(buf, 2)=len+18;
- WBUFL(buf, 4)=guild_id;
- WBUFL(buf, 8)=account_id;
- WBUFL(buf,12)=char_id;
- WBUFW(buf,16)=type;
- memcpy(WBUFP(buf,18),data,len);
- mapif_sendall(buf,len+18);
- return 0;
+ unsigned char buf[2048];
+ if (len > 2030)
+ len = 2030;
+ WBUFW(buf, 0)=0x383a;
+ WBUFW(buf, 2)=len+18;
+ WBUFL(buf, 4)=guild_id;
+ WBUFL(buf, 8)=account_id;
+ WBUFL(buf,12)=char_id;
+ WBUFW(buf,16)=type;
+ memcpy(WBUFP(buf,18),data,len);
+ mapif_sendall(buf,len+18);
+ return 0;
}
// ACK guild skill up
int mapif_guild_skillupack(int guild_id,int skill_num,int account_id)
{
- unsigned char buf[14];
- WBUFW(buf, 0)=0x383c;
- WBUFL(buf, 2)=guild_id;
- WBUFL(buf, 6)=skill_num;
- WBUFL(buf,10)=account_id;
- mapif_sendall(buf,14);
- return 0;
+ unsigned char buf[14];
+ WBUFW(buf, 0)=0x383c;
+ WBUFL(buf, 2)=guild_id;
+ WBUFL(buf, 6)=skill_num;
+ WBUFL(buf,10)=account_id;
+ mapif_sendall(buf,14);
+ return 0;
}
// ACK guild alliance
int mapif_guild_alliance(int guild_id1,int guild_id2,int account_id1,int account_id2,int flag,const char *name1,const char *name2)
{
- unsigned char buf[19+2*NAME_LENGTH];
- WBUFW(buf, 0)=0x383d;
- WBUFL(buf, 2)=guild_id1;
- WBUFL(buf, 6)=guild_id2;
- WBUFL(buf,10)=account_id1;
- WBUFL(buf,14)=account_id2;
- WBUFB(buf,18)=flag;
- memcpy(WBUFP(buf,19),name1,NAME_LENGTH);
- memcpy(WBUFP(buf,19+NAME_LENGTH),name2,NAME_LENGTH);
- mapif_sendall(buf,19+2*NAME_LENGTH);
- return 0;
+ unsigned char buf[19+2*NAME_LENGTH];
+ WBUFW(buf, 0)=0x383d;
+ WBUFL(buf, 2)=guild_id1;
+ WBUFL(buf, 6)=guild_id2;
+ WBUFL(buf,10)=account_id1;
+ WBUFL(buf,14)=account_id2;
+ WBUFB(buf,18)=flag;
+ memcpy(WBUFP(buf,19),name1,NAME_LENGTH);
+ memcpy(WBUFP(buf,19+NAME_LENGTH),name2,NAME_LENGTH);
+ mapif_sendall(buf,19+2*NAME_LENGTH);
+ return 0;
}
// Send a guild position desc
int mapif_guild_position(struct guild *g,int idx)
{
- unsigned char buf[12 + sizeof(struct guild_position)];
- WBUFW(buf,0)=0x383b;
- WBUFW(buf,2)=sizeof(struct guild_position)+12;
- WBUFL(buf,4)=g->guild_id;
- WBUFL(buf,8)=idx;
- memcpy(WBUFP(buf,12),&g->position[idx],sizeof(struct guild_position));
- mapif_sendall(buf,WBUFW(buf,2));
- return 0;
+ unsigned char buf[12 + sizeof(struct guild_position)];
+ WBUFW(buf,0)=0x383b;
+ WBUFW(buf,2)=sizeof(struct guild_position)+12;
+ WBUFL(buf,4)=g->guild_id;
+ WBUFL(buf,8)=idx;
+ memcpy(WBUFP(buf,12),&g->position[idx],sizeof(struct guild_position));
+ mapif_sendall(buf,WBUFW(buf,2));
+ return 0;
}
// Send the guild notice
int mapif_guild_notice(struct guild *g)
{
- unsigned char buf[256];
- WBUFW(buf,0)=0x383e;
- WBUFL(buf,2)=g->guild_id;
- memcpy(WBUFP(buf,6),g->mes1,MAX_GUILDMES1);
- memcpy(WBUFP(buf,66),g->mes2,MAX_GUILDMES2);
- mapif_sendall(buf,186);
- return 0;
+ unsigned char buf[256];
+ WBUFW(buf,0)=0x383e;
+ WBUFL(buf,2)=g->guild_id;
+ memcpy(WBUFP(buf,6),g->mes1,MAX_GUILDMES1);
+ memcpy(WBUFP(buf,66),g->mes2,MAX_GUILDMES2);
+ mapif_sendall(buf,186);
+ return 0;
}
// Send emblem data
int mapif_guild_emblem(struct guild *g)
{
- unsigned char buf[12 + sizeof(g->emblem_data)];
- WBUFW(buf,0)=0x383f;
- WBUFW(buf,2)=g->emblem_len+12;
- WBUFL(buf,4)=g->guild_id;
- WBUFL(buf,8)=g->emblem_id;
- memcpy(WBUFP(buf,12),g->emblem_data,g->emblem_len);
- mapif_sendall(buf,WBUFW(buf,2));
- return 0;
+ unsigned char buf[12 + sizeof(g->emblem_data)];
+ WBUFW(buf,0)=0x383f;
+ WBUFW(buf,2)=g->emblem_len+12;
+ WBUFL(buf,4)=g->guild_id;
+ WBUFL(buf,8)=g->emblem_id;
+ memcpy(WBUFP(buf,12),g->emblem_data,g->emblem_len);
+ mapif_sendall(buf,WBUFW(buf,2));
+ return 0;
}
int mapif_guild_master_changed(struct guild *g, int aid, int cid)
{
- unsigned char buf[14];
- WBUFW(buf,0)=0x3843;
- WBUFL(buf,2)=g->guild_id;
- WBUFL(buf,6)=aid;
- WBUFL(buf,10)=cid;
- mapif_sendall(buf,14);
- return 0;
+ unsigned char buf[14];
+ WBUFW(buf,0)=0x3843;
+ WBUFL(buf,2)=g->guild_id;
+ WBUFL(buf,6)=aid;
+ WBUFL(buf,10)=cid;
+ mapif_sendall(buf,14);
+ return 0;
}
int mapif_guild_castle_dataload(int fd, int sz, int *castle_ids)
{
- struct guild_castle *gc = NULL;
- int num = (sz - 4) / sizeof(int);
- int len = 4 + num * sizeof(*gc);
- int i;
-
- WFIFOHEAD(fd, len);
- WFIFOW(fd, 0) = 0x3840;
- WFIFOW(fd, 2) = len;
- for (i = 0; i < num; i++) {
- gc = inter_guildcastle_fromsql(*(castle_ids++));
- memcpy(WFIFOP(fd, 4 + i * sizeof(*gc)), gc, sizeof(*gc));
- }
- WFIFOSET(fd, len);
- return 0;
+ struct guild_castle *gc = NULL;
+ int num = (sz - 4) / sizeof(int);
+ int len = 4 + num * sizeof(*gc);
+ int i;
+
+ WFIFOHEAD(fd, len);
+ WFIFOW(fd, 0) = 0x3840;
+ WFIFOW(fd, 2) = len;
+ for (i = 0; i < num; i++) {
+ gc = inter_guildcastle_fromsql(*(castle_ids++));
+ memcpy(WFIFOP(fd, 4 + i * sizeof(*gc)), gc, sizeof(*gc));
+ }
+ WFIFOSET(fd, len);
+ return 0;
}
//-------------------------------------------------------------------
@@ -1133,680 +1145,696 @@ int mapif_guild_castle_dataload(int fd, int sz, int *castle_ids)
// Guild creation request
int mapif_parse_CreateGuild(int fd,int account_id,char *name,struct guild_member *master)
{
- struct guild *g;
- int i=0;
+ struct guild *g;
+ int i=0;
#ifdef NOISY
- ShowInfo("Creating Guild (%s)\n", name);
+ ShowInfo("Creating Guild (%s)\n", name);
#endif
- if (search_guildname(name) != 0) {
- ShowInfo("int_guild: guild with same name exists [%s]\n",name);
- mapif_guild_created(fd,account_id,NULL);
- return 0;
- }
- // 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 < NAME_LENGTH && name[i]; i++)
- if (strchr(char_name_letters, name[i]) == NULL) {
- mapif_guild_created(fd,account_id,NULL);
- return 0;
- }
- } else if (char_name_option == 2) { // letters/symbols in char_name_letters are forbidden
- for (i = 0; i < NAME_LENGTH && name[i]; i++)
- if (strchr(char_name_letters, name[i]) != NULL) {
- mapif_guild_created(fd,account_id,NULL);
- return 0;
- }
- }
-
- g = (struct guild *)aMalloc(sizeof(struct guild));
- memset(g,0,sizeof(struct guild));
-
- memcpy(g->name,name,NAME_LENGTH);
- memcpy(g->master,master->name,NAME_LENGTH);
- memcpy(&g->member[0],master,sizeof(struct guild_member));
- g->member[0].modified = GS_MEMBER_MODIFIED;
-
- // Set default positions
- g->position[0].mode=0x11;
- strcpy(g->position[0].name,"GuildMaster");
- strcpy(g->position[MAX_GUILDPOSITION-1].name,"Newbie");
- g->position[0].modified = g->position[MAX_GUILDPOSITION-1].modified = GS_POSITION_MODIFIED;
- for (i=1; i<MAX_GUILDPOSITION-1; i++) {
- sprintf(g->position[i].name,"Position %d",i+1);
- g->position[i].modified = GS_POSITION_MODIFIED;
- }
-
- // Initialize guild property
- g->max_member=16;
- g->average_lv=master->lv;
- g->connect_member=1;
-
- for (i=0; i<MAX_GUILDSKILL; i++)
- g->skill[i].id=i + GD_SKILLBASE;
- g->guild_id= -1; //Request to create guild.
-
- // Create the guild
- if (!inter_guild_tosql(g,GS_BASIC|GS_POSITION|GS_SKILL)) {
- //Failed to Create guild....
- ShowError("Failed to create Guild %s (Guild Master: %s)\n", g->name, g->master);
- mapif_guild_created(fd,account_id,NULL);
- aFree(g);
- return 0;
- }
- ShowInfo("Created Guild %d - %s (Guild Master: %s)\n", g->guild_id, g->name, g->master);
-
- //Add to cache
- idb_put(guild_db_, g->guild_id, g);
-
- // 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)\n",
- name, g->guild_id, master->name, master->account_id);
-
- return 0;
+ if(search_guildname(name) != 0){
+ ShowInfo("int_guild: guild with same name exists [%s]\n",name);
+ mapif_guild_created(fd,account_id,NULL);
+ return 0;
+ }
+ // 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 < NAME_LENGTH && name[i]; i++)
+ if (strchr(char_name_letters, name[i]) == NULL) {
+ mapif_guild_created(fd,account_id,NULL);
+ return 0;
+ }
+ } else if (char_name_option == 2) { // letters/symbols in char_name_letters are forbidden
+ for (i = 0; i < NAME_LENGTH && name[i]; i++)
+ if (strchr(char_name_letters, name[i]) != NULL) {
+ mapif_guild_created(fd,account_id,NULL);
+ return 0;
+ }
+ }
+
+ g = (struct guild *)aMalloc(sizeof(struct guild));
+ memset(g,0,sizeof(struct guild));
+
+ memcpy(g->name,name,NAME_LENGTH);
+ memcpy(g->master,master->name,NAME_LENGTH);
+ memcpy(&g->member[0],master,sizeof(struct guild_member));
+ g->member[0].modified = GS_MEMBER_MODIFIED;
+
+ // Set default positions
+ g->position[0].mode=0x11;
+ strcpy(g->position[0].name,"GuildMaster");
+ strcpy(g->position[MAX_GUILDPOSITION-1].name,"Newbie");
+ g->position[0].modified = g->position[MAX_GUILDPOSITION-1].modified = GS_POSITION_MODIFIED;
+ for(i=1;i<MAX_GUILDPOSITION-1;i++) {
+ sprintf(g->position[i].name,"Position %d",i+1);
+ g->position[i].modified = GS_POSITION_MODIFIED;
+ }
+
+ // Initialize guild property
+ g->max_member=16;
+ g->average_lv=master->lv;
+ g->connect_member=1;
+
+ for(i=0;i<MAX_GUILDSKILL;i++)
+ g->skill[i].id=i + GD_SKILLBASE;
+ g->guild_id= -1; //Request to create guild.
+
+ // Create the guild
+ if (!inter_guild_tosql(g,GS_BASIC|GS_POSITION|GS_SKILL)) {
+ //Failed to Create guild....
+ ShowError("Failed to create Guild %s (Guild Master: %s)\n", g->name, g->master);
+ mapif_guild_created(fd,account_id,NULL);
+ aFree(g);
+ return 0;
+ }
+ ShowInfo("Created Guild %d - %s (Guild Master: %s)\n", g->guild_id, g->name, g->master);
+
+ //Add to cache
+ idb_put(guild_db_, g->guild_id, g);
+
+ // 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)\n",
+ name, g->guild_id, master->name, master->account_id );
+
+ return 0;
}
// Return guild info to client
int mapif_parse_GuildInfo(int fd,int guild_id)
{
- struct guild *g = inter_guild_fromsql(guild_id); //We use this because on start-up the info of castle-owned guilds is requied. [Skotlex]
- if (g) {
- if (!guild_calcinfo(g))
- mapif_guild_info(fd,g);
- } else
- mapif_guild_noinfo(fd,guild_id); // Failed to load info
- return 0;
+ struct guild * g = inter_guild_fromsql(guild_id); //We use this because on start-up the info of castle-owned guilds is requied. [Skotlex]
+ if(g)
+ {
+ if (!guild_calcinfo(g))
+ mapif_guild_info(fd,g);
+ }
+ else
+ mapif_guild_noinfo(fd,guild_id); // Failed to load info
+ return 0;
}
// Add member to guild
int mapif_parse_GuildAddMember(int fd,int guild_id,struct guild_member *m)
{
- struct guild *g;
- int i;
-
- g = inter_guild_fromsql(guild_id);
- if (g==NULL) {
- // Failed to add
- mapif_guild_memberadded(fd,guild_id,m->account_id,m->char_id,1);
- return 0;
- }
-
- // Find an empty slot
- for (i=0; i<g->max_member; i++) {
- if (g->member[i].account_id==0) {
- memcpy(&g->member[i],m,sizeof(struct guild_member));
- g->member[i].modified = (GS_MEMBER_NEW | GS_MEMBER_MODIFIED);
- mapif_guild_memberadded(fd,guild_id,m->account_id,m->char_id,0);
- if (!guild_calcinfo(g)) //Send members if it was not invoked.
- mapif_guild_info(-1,g);
-
- g->save_flag |= GS_MEMBER;
- if (g->save_flag&GS_REMOVE)
- g->save_flag&=~GS_REMOVE;
- return 0;
- }
- }
-
- // Failed to add
- mapif_guild_memberadded(fd,guild_id,m->account_id,m->char_id,1);
- return 0;
+ struct guild * g;
+ int i;
+
+ g = inter_guild_fromsql(guild_id);
+ if(g==NULL){
+ // Failed to add
+ mapif_guild_memberadded(fd,guild_id,m->account_id,m->char_id,1);
+ return 0;
+ }
+
+ // Find an empty slot
+ for(i=0;i<g->max_member;i++)
+ {
+ if(g->member[i].account_id==0)
+ {
+ memcpy(&g->member[i],m,sizeof(struct guild_member));
+ g->member[i].modified = (GS_MEMBER_NEW | GS_MEMBER_MODIFIED);
+ mapif_guild_memberadded(fd,guild_id,m->account_id,m->char_id,0);
+ if (!guild_calcinfo(g)) //Send members if it was not invoked.
+ mapif_guild_info(-1,g);
+
+ g->save_flag |= GS_MEMBER;
+ if (g->save_flag&GS_REMOVE)
+ g->save_flag&=~GS_REMOVE;
+ return 0;
+ }
+ }
+
+ // Failed to add
+ mapif_guild_memberadded(fd,guild_id,m->account_id,m->char_id,1);
+ return 0;
}
// Delete member from guild
int mapif_parse_GuildLeave(int fd, int guild_id, int account_id, int char_id, int flag, const char *mes)
{
- int i, j;
-
- struct guild *g = inter_guild_fromsql(guild_id);
- if (g == NULL) {
- // Unknown guild, just update the player
- if (SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `guild_id`='0' WHERE `account_id`='%d' AND `char_id`='%d'", char_db, account_id, char_id))
- Sql_ShowDebug(sql_handle);
- // mapif_guild_withdraw(guild_id,account_id,char_id,flag,g->member[i].name,mes);
- return 0;
- }
-
- // Find the member
- ARR_FIND(0, g->max_member, i, g->member[i].account_id == account_id && g->member[i].char_id == char_id);
- if (i == g->max_member) {
- //TODO
- return 0;
- }
-
- if (flag) {
- // Write expulsion reason
- // Find an empty slot
- ARR_FIND(0, MAX_GUILDEXPULSION, j, g->expulsion[j].account_id == 0);
- if (j == MAX_GUILDEXPULSION) {
- // Expulsion list is full, flush the oldest one
- for (j = 0; j < MAX_GUILDEXPULSION - 1; j++)
- g->expulsion[j] = g->expulsion[j+1];
- j = MAX_GUILDEXPULSION-1;
- }
- // Save the expulsion entry
- g->expulsion[j].account_id = account_id;
- safestrncpy(g->expulsion[j].name, g->member[i].name, NAME_LENGTH);
- safestrncpy(g->expulsion[j].mes, mes, 40);
- }
-
- mapif_guild_withdraw(guild_id,account_id,char_id,flag,g->member[i].name,mes);
- inter_guild_removemember_tosql(g->member[i].account_id,g->member[i].char_id);
-
- memset(&g->member[i],0,sizeof(struct guild_member));
-
- if (guild_check_empty(g))
- mapif_parse_BreakGuild(-1,guild_id); //Break the guild.
- else {
- //Update member info.
- if (!guild_calcinfo(g))
- mapif_guild_info(fd,g);
- g->save_flag |= GS_EXPULSION;
- }
-
- return 0;
+ int i, j;
+
+ struct guild* g = inter_guild_fromsql(guild_id);
+ if( g == NULL )
+ {
+ // Unknown guild, just update the player
+ if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `guild_id`='0' WHERE `account_id`='%d' AND `char_id`='%d'", char_db, account_id, char_id) )
+ Sql_ShowDebug(sql_handle);
+ // mapif_guild_withdraw(guild_id,account_id,char_id,flag,g->member[i].name,mes);
+ return 0;
+ }
+
+ // Find the member
+ ARR_FIND( 0, g->max_member, i, g->member[i].account_id == account_id && g->member[i].char_id == char_id );
+ if( i == g->max_member )
+ {
+ //TODO
+ return 0;
+ }
+
+ if( flag )
+ { // Write expulsion reason
+ // Find an empty slot
+ ARR_FIND( 0, MAX_GUILDEXPULSION, j, g->expulsion[j].account_id == 0 );
+ if( j == MAX_GUILDEXPULSION )
+ {
+ // Expulsion list is full, flush the oldest one
+ for( j = 0; j < MAX_GUILDEXPULSION - 1; j++ )
+ g->expulsion[j] = g->expulsion[j+1];
+ j = MAX_GUILDEXPULSION-1;
+ }
+ // Save the expulsion entry
+ g->expulsion[j].account_id = account_id;
+ safestrncpy(g->expulsion[j].name, g->member[i].name, NAME_LENGTH);
+ safestrncpy(g->expulsion[j].mes, mes, 40);
+ }
+
+ mapif_guild_withdraw(guild_id,account_id,char_id,flag,g->member[i].name,mes);
+ inter_guild_removemember_tosql(g->member[i].account_id,g->member[i].char_id);
+
+ memset(&g->member[i],0,sizeof(struct guild_member));
+
+ if( guild_check_empty(g) )
+ mapif_parse_BreakGuild(-1,guild_id); //Break the guild.
+ else {
+ //Update member info.
+ if (!guild_calcinfo(g))
+ mapif_guild_info(fd,g);
+ g->save_flag |= GS_EXPULSION;
+ }
+
+ 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_)
{
- // Could speed up by manipulating only guild_member
- struct guild *g;
- int i,sum,c;
- int prev_count, prev_alv;
-
- g = inter_guild_fromsql(guild_id);
- if (g==NULL)
- return 0;
-
- ARR_FIND(0, g->max_member, i, g->member[i].account_id == account_id && g->member[i].char_id == char_id);
- if (i < g->max_member) {
- g->member[i].online = online;
- g->member[i].lv = lv;
- g->member[i].class_ = class_;
- g->member[i].modified = GS_MEMBER_MODIFIED;
- mapif_guild_memberinfoshort(g,i);
- }
-
- prev_count = g->connect_member;
- prev_alv = g->average_lv;
-
- g->average_lv = 0;
- g->connect_member = 0;
- c = 0;
- sum = 0;
-
- for (i = 0; i < g->max_member; i++) {
- if (g->member[i].account_id > 0) {
- sum += g->member[i].lv;
- c++;
- }
- if (g->member[i].online)
- g->connect_member++;
- }
-
- if (c) { // this check should always succeed...
- g->average_lv = sum / c;
- if (g->connect_member != prev_count || g->average_lv != prev_alv)
- g->save_flag |= GS_CONNECT;
- if (g->save_flag & GS_REMOVE)
- g->save_flag &= ~GS_REMOVE;
- }
- g->save_flag |= GS_MEMBER; //Update guild member data
- return 0;
+ // Could speed up by manipulating only guild_member
+ struct guild * g;
+ int i,sum,c;
+ int prev_count, prev_alv;
+
+ g = inter_guild_fromsql(guild_id);
+ if(g==NULL)
+ return 0;
+
+ ARR_FIND( 0, g->max_member, i, g->member[i].account_id == account_id && g->member[i].char_id == char_id );
+ if( i < g->max_member )
+ {
+ g->member[i].online = online;
+ g->member[i].lv = lv;
+ g->member[i].class_ = class_;
+ g->member[i].modified = GS_MEMBER_MODIFIED;
+ mapif_guild_memberinfoshort(g,i);
+ }
+
+ prev_count = g->connect_member;
+ prev_alv = g->average_lv;
+
+ g->average_lv = 0;
+ g->connect_member = 0;
+ c = 0;
+ sum = 0;
+
+ for( i = 0; i < g->max_member; i++ )
+ {
+ if( g->member[i].account_id > 0 )
+ {
+ sum += g->member[i].lv;
+ c++;
+ }
+ if( g->member[i].online )
+ g->connect_member++;
+ }
+
+ if( c ) // this check should always succeed...
+ {
+ g->average_lv = sum / c;
+ if( g->connect_member != prev_count || g->average_lv != prev_alv )
+ g->save_flag |= GS_CONNECT;
+ if( g->save_flag & GS_REMOVE )
+ g->save_flag &= ~GS_REMOVE;
+ }
+ g->save_flag |= GS_MEMBER; //Update guild member data
+ return 0;
}
// BreakGuild
int mapif_parse_BreakGuild(int fd,int guild_id)
{
- struct guild *g;
+ struct guild * g;
+
+ g = inter_guild_fromsql(guild_id);
+ if(g==NULL)
+ return 0;
- g = inter_guild_fromsql(guild_id);
- if (g==NULL)
- return 0;
+ // Delete guild from sql
+ //printf("- Delete guild %d from guild\n",guild_id);
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_db, guild_id) )
+ Sql_ShowDebug(sql_handle);
- // Delete guild from sql
- //printf("- Delete guild %d from guild\n",guild_id);
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_db, guild_id))
- Sql_ShowDebug(sql_handle);
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_member_db, guild_id) )
+ Sql_ShowDebug(sql_handle);
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_member_db, guild_id))
- Sql_ShowDebug(sql_handle);
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_castle_db, guild_id) )
+ Sql_ShowDebug(sql_handle);
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_castle_db, guild_id))
- Sql_ShowDebug(sql_handle);
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_storage_db, guild_id) )
+ Sql_ShowDebug(sql_handle);
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_storage_db, guild_id))
- Sql_ShowDebug(sql_handle);
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d' OR `alliance_id` = '%d'", guild_alliance_db, guild_id, guild_id) )
+ Sql_ShowDebug(sql_handle);
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d' OR `alliance_id` = '%d'", guild_alliance_db, guild_id, guild_id))
- Sql_ShowDebug(sql_handle);
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_position_db, guild_id) )
+ Sql_ShowDebug(sql_handle);
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_position_db, guild_id))
- Sql_ShowDebug(sql_handle);
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_skill_db, guild_id) )
+ Sql_ShowDebug(sql_handle);
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_skill_db, guild_id))
- Sql_ShowDebug(sql_handle);
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_expulsion_db, guild_id) )
+ Sql_ShowDebug(sql_handle);
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_expulsion_db, guild_id))
- Sql_ShowDebug(sql_handle);
+ //printf("- Update guild %d of char\n",guild_id);
+ if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `guild_id`='0' WHERE `guild_id`='%d'", char_db, guild_id) )
+ Sql_ShowDebug(sql_handle);
- //printf("- Update guild %d of char\n",guild_id);
- if (SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `guild_id`='0' WHERE `guild_id`='%d'", char_db, guild_id))
- Sql_ShowDebug(sql_handle);
+ mapif_guild_broken(guild_id,0);
- mapif_guild_broken(guild_id,0);
+ if(log_inter)
+ inter_log("guild %s (id=%d) broken\n",g->name,guild_id);
- if (log_inter)
- inter_log("guild %s (id=%d) broken\n",g->name,guild_id);
-
- //Remove the guild from memory. [Skotlex]
- idb_remove(guild_db_, guild_id);
- return 0;
+ //Remove the guild from memory. [Skotlex]
+ idb_remove(guild_db_, guild_id);
+ return 0;
}
// Forward Guild message to others map servers
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, fd);
+ return mapif_guild_message(guild_id,account_id,mes,len, fd);
}
-// Modification of the guild
+// Modification of the guild
int mapif_parse_GuildBasicInfoChange(int fd,int guild_id,int type,const char *data,int len)
{
- struct guild *g;
- short dw=*((short *)data);
- g = inter_guild_fromsql(guild_id);
- if (g==NULL)
- return 0;
-
- switch (type) {
- case GBI_GUILDLV:
- if (dw>0 && g->guild_lv+dw<=50) {
- g->guild_lv+=dw;
- g->skill_point+=dw;
- } else if (dw<0 && g->guild_lv+dw>=1)
- g->guild_lv+=dw;
- mapif_guild_info(-1,g);
- g->save_flag |= GS_LEVEL;
- return 0;
- default:
- ShowError("int_guild: GuildBasicInfoChange: Unknown type %d\n",type);
- break;
- }
- mapif_guild_basicinfochanged(guild_id,type,data,len);
- return 0;
+ struct guild * g;
+ short dw=*((short *)data);
+ g = inter_guild_fromsql(guild_id);
+ if(g==NULL)
+ return 0;
+
+ switch(type)
+ {
+ case GBI_GUILDLV:
+ if(dw>0 && g->guild_lv+dw<=50)
+ {
+ g->guild_lv+=dw;
+ g->skill_point+=dw;
+ }
+ else if(dw<0 && g->guild_lv+dw>=1)
+ g->guild_lv+=dw;
+ mapif_guild_info(-1,g);
+ g->save_flag |= GS_LEVEL;
+ return 0;
+ default:
+ ShowError("int_guild: GuildBasicInfoChange: Unknown type %d\n",type);
+ break;
+ }
+ mapif_guild_basicinfochanged(guild_id,type,data,len);
+ return 0;
}
-// Modification of the guild
+// Modification of the guild
int mapif_parse_GuildMemberInfoChange(int fd,int guild_id,int account_id,int char_id,int type,const char *data,int len)
{
- // Could make some improvement in speed, because only change guild_member
- int i;
- struct guild *g;
-
- g = inter_guild_fromsql(guild_id);
- if (g==NULL)
- return 0;
-
- // Search the member
- for (i=0; i<g->max_member; i++)
- if (g->member[i].account_id==account_id &&
- g->member[i].char_id==char_id)
- break;
-
- // Not Found
- if (i==g->max_member) {
- ShowWarning("int_guild: GuildMemberChange: Not found %d,%d in guild (%d - %s)\n",
- account_id,char_id,guild_id,g->name);
- return 0;
- }
-
- switch (type) {
- case GMI_POSITION: {
- g->member[i].position=*((short *)data);
- g->member[i].modified = GS_MEMBER_MODIFIED;
- mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len);
- g->save_flag |= GS_MEMBER;
- break;
- }
- case GMI_EXP: {
- // EXP
- uint64 exp, old_exp=g->member[i].exp;
- g->member[i].exp=*((uint64 *)data);
- g->member[i].modified = GS_MEMBER_MODIFIED;
- if (g->member[i].exp > old_exp) {
- exp = g->member[i].exp - old_exp;
-
- // Compute gained exp
- if (guild_exp_rate != 100)
- exp = exp*guild_exp_rate/100;
-
- // Update guild exp
- if (exp > UINT64_MAX - g->exp)
- g->exp = UINT64_MAX;
- else
- g->exp+=exp;
-
- guild_calcinfo(g);
- mapif_guild_basicinfochanged(guild_id,GBI_EXP,&g->exp,sizeof(g->exp));
- g->save_flag |= GS_LEVEL;
- }
- mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len);
- g->save_flag |= GS_MEMBER;
- break;
- }
- case GMI_HAIR: {
- g->member[i].hair=*((short *)data);
- g->member[i].modified = GS_MEMBER_MODIFIED;
- mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len);
- g->save_flag |= GS_MEMBER; //Save new data.
- break;
- }
- case GMI_HAIR_COLOR: {
- g->member[i].hair_color=*((short *)data);
- g->member[i].modified = GS_MEMBER_MODIFIED;
- mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len);
- g->save_flag |= GS_MEMBER; //Save new data.
- break;
- }
- case GMI_GENDER: {
- g->member[i].gender=*((short *)data);
- g->member[i].modified = GS_MEMBER_MODIFIED;
- mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len);
- g->save_flag |= GS_MEMBER; //Save new data.
- break;
- }
- case GMI_CLASS: {
- g->member[i].class_=*((short *)data);
- g->member[i].modified = GS_MEMBER_MODIFIED;
- mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len);
- g->save_flag |= GS_MEMBER; //Save new data.
- break;
- }
- case GMI_LEVEL: {
- g->member[i].lv=*((short *)data);
- g->member[i].modified = GS_MEMBER_MODIFIED;
- mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len);
- g->save_flag |= GS_MEMBER; //Save new data.
- break;
- }
- default:
- ShowError("int_guild: GuildMemberInfoChange: Unknown type %d\n",type);
- break;
- }
- return 0;
+ // Could make some improvement in speed, because only change guild_member
+ int i;
+ struct guild * g;
+
+ g = inter_guild_fromsql(guild_id);
+ if(g==NULL)
+ return 0;
+
+ // Search the member
+ for(i=0;i<g->max_member;i++)
+ if( g->member[i].account_id==account_id &&
+ g->member[i].char_id==char_id )
+ break;
+
+ // Not Found
+ if(i==g->max_member){
+ ShowWarning("int_guild: GuildMemberChange: Not found %d,%d in guild (%d - %s)\n",
+ account_id,char_id,guild_id,g->name);
+ return 0;
+ }
+
+ switch(type)
+ {
+ case GMI_POSITION:
+ {
+ g->member[i].position=*((short *)data);
+ g->member[i].modified = GS_MEMBER_MODIFIED;
+ mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len);
+ g->save_flag |= GS_MEMBER;
+ break;
+ }
+ case GMI_EXP:
+ { // EXP
+ uint64 exp, old_exp=g->member[i].exp;
+ g->member[i].exp=*((uint64 *)data);
+ g->member[i].modified = GS_MEMBER_MODIFIED;
+ if (g->member[i].exp > old_exp)
+ {
+ exp = g->member[i].exp - old_exp;
+
+ // Compute gained exp
+ if (guild_exp_rate != 100)
+ exp = exp*guild_exp_rate/100;
+
+ // Update guild exp
+ if (exp > UINT64_MAX - g->exp)
+ g->exp = UINT64_MAX;
+ else
+ g->exp+=exp;
+
+ guild_calcinfo(g);
+ mapif_guild_basicinfochanged(guild_id,GBI_EXP,&g->exp,sizeof(g->exp));
+ g->save_flag |= GS_LEVEL;
+ }
+ mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len);
+ g->save_flag |= GS_MEMBER;
+ break;
+ }
+ case GMI_HAIR:
+ {
+ g->member[i].hair=*((short *)data);
+ g->member[i].modified = GS_MEMBER_MODIFIED;
+ mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len);
+ g->save_flag |= GS_MEMBER; //Save new data.
+ break;
+ }
+ case GMI_HAIR_COLOR:
+ {
+ g->member[i].hair_color=*((short *)data);
+ g->member[i].modified = GS_MEMBER_MODIFIED;
+ mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len);
+ g->save_flag |= GS_MEMBER; //Save new data.
+ break;
+ }
+ case GMI_GENDER:
+ {
+ g->member[i].gender=*((short *)data);
+ g->member[i].modified = GS_MEMBER_MODIFIED;
+ mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len);
+ g->save_flag |= GS_MEMBER; //Save new data.
+ break;
+ }
+ case GMI_CLASS:
+ {
+ g->member[i].class_=*((short *)data);
+ g->member[i].modified = GS_MEMBER_MODIFIED;
+ mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len);
+ g->save_flag |= GS_MEMBER; //Save new data.
+ break;
+ }
+ case GMI_LEVEL:
+ {
+ g->member[i].lv=*((short *)data);
+ g->member[i].modified = GS_MEMBER_MODIFIED;
+ mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len);
+ g->save_flag |= GS_MEMBER; //Save new data.
+ break;
+ }
+ default:
+ ShowError("int_guild: GuildMemberInfoChange: Unknown type %d\n",type);
+ break;
+ }
+ return 0;
}
int inter_guild_sex_changed(int guild_id,int account_id,int char_id, short gender)
{
- return mapif_parse_GuildMemberInfoChange(0, guild_id, account_id, char_id, GMI_GENDER, (const char *)&gender, sizeof(gender));
+ return mapif_parse_GuildMemberInfoChange(0, guild_id, account_id, char_id, GMI_GENDER, (const char*)&gender, sizeof(gender));
}
int inter_guild_charname_changed(int guild_id,int account_id, int char_id, char *name)
{
- struct guild *g;
- int i, flag = 0;
-
- g = inter_guild_fromsql(guild_id);
- if (g == NULL) {
- ShowError("inter_guild_charrenamed: Can't find guild %d.\n", guild_id);
- return 0;
- }
-
- ARR_FIND(0, g->max_member, i, g->member[i].char_id == char_id);
- if (i == g->max_member) {
- ShowError("inter_guild_charrenamed: Can't find character %d in the guild\n", char_id);
- return 0;
- }
-
- if (!strcmp(g->member[i].name, g->master)) {
- safestrncpy(g->master, name, NAME_LENGTH);
- flag |= GS_BASIC;
- }
- safestrncpy(g->member[i].name, name, NAME_LENGTH);
- g->member[i].modified = GS_MEMBER_MODIFIED;
- flag |= GS_MEMBER;
-
- if (!inter_guild_tosql(g, flag))
- return 0;
-
- mapif_guild_info(-1,g);
-
- return 0;
+ struct guild *g;
+ int i, flag = 0;
+
+ g = inter_guild_fromsql(guild_id);
+ if( g == NULL )
+ {
+ ShowError("inter_guild_charrenamed: Can't find guild %d.\n", guild_id);
+ return 0;
+ }
+
+ ARR_FIND(0, g->max_member, i, g->member[i].char_id == char_id);
+ if( i == g->max_member )
+ {
+ ShowError("inter_guild_charrenamed: Can't find character %d in the guild\n", char_id);
+ return 0;
+ }
+
+ if( !strcmp(g->member[i].name, g->master) )
+ {
+ safestrncpy(g->master, name, NAME_LENGTH);
+ flag |= GS_BASIC;
+ }
+ safestrncpy(g->member[i].name, name, NAME_LENGTH);
+ g->member[i].modified = GS_MEMBER_MODIFIED;
+ flag |= GS_MEMBER;
+
+ if( !inter_guild_tosql(g, flag) )
+ return 0;
+
+ mapif_guild_info(-1,g);
+
+ return 0;
}
// Change a position desc
int mapif_parse_GuildPosition(int fd,int guild_id,int idx,struct guild_position *p)
{
- // Could make some improvement in speed, because only change guild_position
- struct guild *g;
-
- g = inter_guild_fromsql(guild_id);
- if (g==NULL || idx<0 || idx>=MAX_GUILDPOSITION)
- return 0;
-
- memcpy(&g->position[idx],p,sizeof(struct guild_position));
- mapif_guild_position(g,idx);
- g->position[idx].modified = GS_POSITION_MODIFIED;
- g->save_flag |= GS_POSITION; // Change guild_position
- return 0;
+ // Could make some improvement in speed, because only change guild_position
+ struct guild * g;
+
+ g = inter_guild_fromsql(guild_id);
+ if(g==NULL || idx<0 || idx>=MAX_GUILDPOSITION)
+ return 0;
+
+ memcpy(&g->position[idx],p,sizeof(struct guild_position));
+ mapif_guild_position(g,idx);
+ g->position[idx].modified = GS_POSITION_MODIFIED;
+ g->save_flag |= GS_POSITION; // Change guild_position
+ return 0;
}
// Guild Skill UP
int mapif_parse_GuildSkillUp(int fd,int guild_id,int skill_num,int account_id,int max)
{
- struct guild *g;
- int idx = skill_num - GD_SKILLBASE;
-
- g = inter_guild_fromsql(guild_id);
- if (g == NULL || idx < 0 || idx >= MAX_GUILDSKILL)
- return 0;
-
- if (g->skill_point>0 && g->skill[idx].id>0 && g->skill[idx].lv<max) {
- g->skill[idx].lv++;
- g->skill_point--;
- if (!guild_calcinfo(g))
- mapif_guild_info(-1,g);
- mapif_guild_skillupack(guild_id,skill_num,account_id);
- g->save_flag |= (GS_LEVEL|GS_SKILL); // Change guild & guild_skill
- }
- return 0;
+ struct guild * g;
+ int idx = skill_num - GD_SKILLBASE;
+
+ g = inter_guild_fromsql(guild_id);
+ if(g == NULL || idx < 0 || idx >= MAX_GUILDSKILL)
+ return 0;
+
+ if(g->skill_point>0 && g->skill[idx].id>0 && g->skill[idx].lv<max )
+ {
+ g->skill[idx].lv++;
+ g->skill_point--;
+ if (!guild_calcinfo(g))
+ mapif_guild_info(-1,g);
+ mapif_guild_skillupack(guild_id,skill_num,account_id);
+ g->save_flag |= (GS_LEVEL|GS_SKILL); // Change guild & guild_skill
+ }
+ return 0;
}
//Manual deletion of an alliance when partnering guild does not exists. [Skotlex]
static int mapif_parse_GuildDeleteAlliance(struct guild *g, int guild_id, int account_id1, int account_id2, int flag)
{
- int i;
- char name[NAME_LENGTH];
-
- ARR_FIND(0, MAX_GUILDALLIANCE, i, g->alliance[i].guild_id == guild_id);
- if (i == MAX_GUILDALLIANCE)
- return -1;
-
- strcpy(name, g->alliance[i].name);
- g->alliance[i].guild_id=0;
-
- mapif_guild_alliance(g->guild_id,guild_id,account_id1,account_id2,flag,g->name,name);
- g->save_flag |= GS_ALLIANCE;
- return 0;
+ int i;
+ char name[NAME_LENGTH];
+
+ ARR_FIND( 0, MAX_GUILDALLIANCE, i, g->alliance[i].guild_id == guild_id );
+ if( i == MAX_GUILDALLIANCE )
+ return -1;
+
+ strcpy(name, g->alliance[i].name);
+ g->alliance[i].guild_id=0;
+
+ mapif_guild_alliance(g->guild_id,guild_id,account_id1,account_id2,flag,g->name,name);
+ g->save_flag |= GS_ALLIANCE;
+ return 0;
}
// Alliance modification
int mapif_parse_GuildAlliance(int fd,int guild_id1,int guild_id2,int account_id1,int account_id2,int flag)
{
- // Could speed up
- struct guild *g[2];
- int j,i;
- g[0] = inter_guild_fromsql(guild_id1);
- g[1] = inter_guild_fromsql(guild_id2);
-
- if (g[0] && g[1]==NULL && (flag & GUILD_ALLIANCE_REMOVE)) //Requested to remove an alliance with a not found guild.
- return mapif_parse_GuildDeleteAlliance(g[0], guild_id2, account_id1, account_id2, flag); //Try to do a manual removal of said guild.
-
- if (g[0]==NULL || g[1]==NULL)
- return 0;
-
- if (flag&GUILD_ALLIANCE_REMOVE) {
- // Remove alliance/opposition, in case of alliance, remove on both side
- for (i=0; i<2-(flag&GUILD_ALLIANCE_TYPE_MASK); i++) {
- ARR_FIND(0, MAX_GUILDALLIANCE, j, g[i]->alliance[j].guild_id == g[1-i]->guild_id && g[i]->alliance[j].opposition == (flag&GUILD_ALLIANCE_TYPE_MASK));
- if (j < MAX_GUILDALLIANCE)
- g[i]->alliance[j].guild_id = 0;
- }
- } else {
- // Add alliance, in case of alliance, add on both side
- for (i=0; i<2-(flag&GUILD_ALLIANCE_TYPE_MASK); i++) {
- // Search an empty slot
- ARR_FIND(0, MAX_GUILDALLIANCE, j, g[i]->alliance[j].guild_id == 0);
- if (j < MAX_GUILDALLIANCE) {
- g[i]->alliance[j].guild_id=g[1-i]->guild_id;
- memcpy(g[i]->alliance[j].name,g[1-i]->name,NAME_LENGTH);
- // Set alliance type
- g[i]->alliance[j].opposition = flag&GUILD_ALLIANCE_TYPE_MASK;
- }
- }
- }
-
- // Send on all map the new alliance/opposition
- mapif_guild_alliance(guild_id1,guild_id2,account_id1,account_id2,flag,g[0]->name,g[1]->name);
-
- // Mark the two guild to be saved
- g[0]->save_flag |= GS_ALLIANCE;
- g[1]->save_flag |= GS_ALLIANCE;
- return 0;
+ // Could speed up
+ struct guild *g[2];
+ int j,i;
+ g[0] = inter_guild_fromsql(guild_id1);
+ g[1] = inter_guild_fromsql(guild_id2);
+
+ if(g[0] && g[1]==NULL && (flag & GUILD_ALLIANCE_REMOVE)) //Requested to remove an alliance with a not found guild.
+ return mapif_parse_GuildDeleteAlliance(g[0], guild_id2, account_id1, account_id2, flag); //Try to do a manual removal of said guild.
+
+ if(g[0]==NULL || g[1]==NULL)
+ return 0;
+
+ if(flag&GUILD_ALLIANCE_REMOVE)
+ {
+ // Remove alliance/opposition, in case of alliance, remove on both side
+ for(i=0;i<2-(flag&GUILD_ALLIANCE_TYPE_MASK);i++)
+ {
+ ARR_FIND( 0, MAX_GUILDALLIANCE, j, g[i]->alliance[j].guild_id == g[1-i]->guild_id && g[i]->alliance[j].opposition == (flag&GUILD_ALLIANCE_TYPE_MASK) );
+ if( j < MAX_GUILDALLIANCE )
+ g[i]->alliance[j].guild_id = 0;
+ }
+ }
+ else
+ {
+ // Add alliance, in case of alliance, add on both side
+ for(i=0;i<2-(flag&GUILD_ALLIANCE_TYPE_MASK);i++)
+ {
+ // Search an empty slot
+ ARR_FIND( 0, MAX_GUILDALLIANCE, j, g[i]->alliance[j].guild_id == 0 );
+ if( j < MAX_GUILDALLIANCE )
+ {
+ g[i]->alliance[j].guild_id=g[1-i]->guild_id;
+ memcpy(g[i]->alliance[j].name,g[1-i]->name,NAME_LENGTH);
+ // Set alliance type
+ g[i]->alliance[j].opposition = flag&GUILD_ALLIANCE_TYPE_MASK;
+ }
+ }
+ }
+
+ // Send on all map the new alliance/opposition
+ mapif_guild_alliance(guild_id1,guild_id2,account_id1,account_id2,flag,g[0]->name,g[1]->name);
+
+ // Mark the two guild to be saved
+ g[0]->save_flag |= GS_ALLIANCE;
+ g[1]->save_flag |= GS_ALLIANCE;
+ return 0;
}
// Change guild message
int mapif_parse_GuildNotice(int fd,int guild_id,const char *mes1,const char *mes2)
{
- struct guild *g;
+ struct guild *g;
- g = inter_guild_fromsql(guild_id);
- if (g==NULL)
- return 0;
+ g = inter_guild_fromsql(guild_id);
+ if(g==NULL)
+ return 0;
- memcpy(g->mes1,mes1,MAX_GUILDMES1);
- memcpy(g->mes2,mes2,MAX_GUILDMES2);
- g->save_flag |= GS_MES; //Change mes of guild
- return mapif_guild_notice(g);
+ memcpy(g->mes1,mes1,MAX_GUILDMES1);
+ memcpy(g->mes2,mes2,MAX_GUILDMES2);
+ g->save_flag |= GS_MES; //Change mes of guild
+ return mapif_guild_notice(g);
}
int mapif_parse_GuildEmblem(int fd,int len,int guild_id,int dummy,const char *data)
{
- struct guild *g;
+ struct guild * g;
- g = inter_guild_fromsql(guild_id);
- if (g==NULL)
- return 0;
+ g = inter_guild_fromsql(guild_id);
+ if(g==NULL)
+ return 0;
- if (len > sizeof(g->emblem_data))
- len = sizeof(g->emblem_data);
+ if (len > sizeof(g->emblem_data))
+ len = sizeof(g->emblem_data);
- memcpy(g->emblem_data,data,len);
- g->emblem_len=len;
- g->emblem_id++;
- g->save_flag |= GS_EMBLEM; //Change guild
- return mapif_guild_emblem(g);
+ memcpy(g->emblem_data,data,len);
+ g->emblem_len=len;
+ g->emblem_id++;
+ g->save_flag |= GS_EMBLEM; //Change guild
+ return mapif_guild_emblem(g);
}
int mapif_parse_GuildCastleDataLoad(int fd, int len, int *castle_ids)
{
- return mapif_guild_castle_dataload(fd, len, castle_ids);
+ return mapif_guild_castle_dataload(fd, len, castle_ids);
}
int mapif_parse_GuildCastleDataSave(int fd, int castle_id, int index, int value)
{
- struct guild_castle *gc = inter_guildcastle_fromsql(castle_id);
-
- if (gc == NULL) {
- ShowError("mapif_parse_GuildCastleDataSave: castle id=%d not found\n", castle_id);
- return 0;
- }
-
- switch (index) {
- case 1:
- if (log_inter && gc->guild_id != value) {
- int gid = (value) ? value : gc->guild_id;
- struct guild *g = idb_get(guild_db_, gid);
- inter_log("guild %s (id=%d) %s castle id=%d\n",
- (g) ? g->name : "??", gid, (value) ? "occupy" : "abandon", castle_id);
- }
- gc->guild_id = value;
- break;
- case 2:
- gc->economy = value;
- break;
- case 3:
- gc->defense = value;
- break;
- case 4:
- gc->triggerE = value;
- break;
- case 5:
- gc->triggerD = value;
- break;
- case 6:
- gc->nextTime = value;
- break;
- case 7:
- gc->payTime = value;
- break;
- case 8:
- gc->createTime = value;
- break;
- case 9:
- gc->visibleC = value;
- break;
- default:
- if (index > 9 && index <= 9+MAX_GUARDIANS) {
- gc->guardian[index-10].visible = value;
- break;
- }
- ShowError("mapif_parse_GuildCastleDataSave: not found index=%d\n", index);
- return 0;
- }
- inter_guildcastle_tosql(gc);
- return 0;
+ struct guild_castle *gc = inter_guildcastle_fromsql(castle_id);
+
+ if (gc == NULL) {
+ ShowError("mapif_parse_GuildCastleDataSave: castle id=%d not found\n", castle_id);
+ return 0;
+ }
+
+ switch (index) {
+ case 1:
+ if (log_inter && gc->guild_id != value) {
+ int gid = (value) ? value : gc->guild_id;
+ struct guild *g = idb_get(guild_db_, gid);
+ inter_log("guild %s (id=%d) %s castle id=%d\n",
+ (g) ? g->name : "??", gid, (value) ? "occupy" : "abandon", castle_id);
+ }
+ gc->guild_id = value;
+ break;
+ case 2: gc->economy = value; break;
+ case 3: gc->defense = value; break;
+ case 4: gc->triggerE = value; break;
+ case 5: gc->triggerD = value; break;
+ case 6: gc->nextTime = value; break;
+ case 7: gc->payTime = value; break;
+ case 8: gc->createTime = value; break;
+ case 9: gc->visibleC = value; break;
+ default:
+ if (index > 9 && index <= 9+MAX_GUARDIANS) {
+ gc->guardian[index-10].visible = value;
+ break;
+ }
+ ShowError("mapif_parse_GuildCastleDataSave: not found index=%d\n", index);
+ return 0;
+ }
+ inter_guildcastle_tosql(gc);
+ return 0;
}
-int mapif_parse_GuildMasterChange(int fd, int guild_id, const char *name, int len)
+int mapif_parse_GuildMasterChange(int fd, int guild_id, const char* name, int len)
{
- struct guild *g;
- struct guild_member gm;
- int pos;
-
- g = inter_guild_fromsql(guild_id);
-
- if (g==NULL || len > NAME_LENGTH)
- return 0;
-
- // Find member (name)
- for (pos = 0; pos < g->max_member && strncmp(g->member[pos].name, name, len); pos++);
-
- if (pos == g->max_member)
- return 0; //Character not found??
-
- // Switch current and old GM
- memcpy(&gm, &g->member[pos], sizeof(struct guild_member));
- memcpy(&g->member[pos], &g->member[0], sizeof(struct guild_member));
- memcpy(&g->member[0], &gm, sizeof(struct guild_member));
-
- // Switch positions
- g->member[pos].position = g->member[0].position;
- g->member[pos].modified = GS_MEMBER_MODIFIED;
- g->member[0].position = 0; //Position 0: guild Master.
- g->member[0].modified = GS_MEMBER_MODIFIED;
-
- strncpy(g->master, name, len);
- if (len < NAME_LENGTH)
- g->master[len] = '\0';
-
- ShowInfo("int_guild: Guildmaster Changed to %s (Guild %d - %s)\n",g->master, guild_id, g->name);
- g->save_flag |= (GS_BASIC|GS_MEMBER); //Save main data and member data.
- return mapif_guild_master_changed(g, g->member[0].account_id, g->member[0].char_id);
+ struct guild * g;
+ struct guild_member gm;
+ int pos;
+
+ g = inter_guild_fromsql(guild_id);
+
+ if(g==NULL || len > NAME_LENGTH)
+ return 0;
+
+ // Find member (name)
+ for (pos = 0; pos < g->max_member && strncmp(g->member[pos].name, name, len); pos++);
+
+ if (pos == g->max_member)
+ return 0; //Character not found??
+
+ // Switch current and old GM
+ memcpy(&gm, &g->member[pos], sizeof (struct guild_member));
+ memcpy(&g->member[pos], &g->member[0], sizeof(struct guild_member));
+ memcpy(&g->member[0], &gm, sizeof(struct guild_member));
+
+ // Switch positions
+ g->member[pos].position = g->member[0].position;
+ g->member[pos].modified = GS_MEMBER_MODIFIED;
+ g->member[0].position = 0; //Position 0: guild Master.
+ g->member[0].modified = GS_MEMBER_MODIFIED;
+
+ strncpy(g->master, name, len);
+ if (len < NAME_LENGTH)
+ g->master[len] = '\0';
+
+ ShowInfo("int_guild: Guildmaster Changed to %s (Guild %d - %s)\n",g->master, guild_id, g->name);
+ g->save_flag |= (GS_BASIC|GS_MEMBER); //Save main data and member data.
+ return mapif_guild_master_changed(g, g->member[0].account_id, g->member[0].char_id);
}
// Communication from the map server
@@ -1814,78 +1842,44 @@ int mapif_parse_GuildMasterChange(int fd, int guild_id, const char *name, int le
// Data packet length that you set to inter.c
//- Shouldn't do checking and packet length, RFIFOSKIP is done by the caller
// Must Return
-// 1 : ok
+// 1 : ok
// 0 : error
int inter_guild_parse_frommap(int fd)
{
- RFIFOHEAD(fd);
- switch (RFIFOW(fd,0)) {
- 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 0x3033:
- mapif_parse_GuildMasterChange(fd,RFIFOL(fd,4),(const char *)RFIFOP(fd,8),RFIFOW(fd,2)-8);
- 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),(char *)RFIFOP(fd,12),RFIFOW(fd,2)-12);
- 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),RFIFOL(fd,14));
- 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),(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),(int *)RFIFOP(fd,4));
- break;
- case 0x3041:
- mapif_parse_GuildCastleDataSave(fd,RFIFOW(fd,2),RFIFOB(fd,4),RFIFOL(fd,5));
- break;
-
- default:
- return 0;
- }
-
- return 1;
+ RFIFOHEAD(fd);
+ switch(RFIFOW(fd,0)) {
+ 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 0x3033: mapif_parse_GuildMasterChange(fd,RFIFOL(fd,4),(const char*)RFIFOP(fd,8),RFIFOW(fd,2)-8); 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),(char*)RFIFOP(fd,12),RFIFOW(fd,2)-12); 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),RFIFOL(fd,14)); 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),(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),(int *)RFIFOP(fd,4)); break;
+ case 0x3041: mapif_parse_GuildCastleDataSave(fd,RFIFOW(fd,2),RFIFOB(fd,4),RFIFOL(fd,5)); break;
+
+ default:
+ return 0;
+ }
+
+ return 1;
}
//Leave request from the server (for deleting character from guild)
int inter_guild_leave(int guild_id, int account_id, int char_id)
{
- return mapif_parse_GuildLeave(-1, guild_id, account_id, char_id, 0, "** Character Deleted **");
+ return mapif_parse_GuildLeave(-1, guild_id, account_id, char_id, 0, "** Character Deleted **");
}
int inter_guild_broken(int guild_id)
{
- return mapif_guild_broken(guild_id, 0);
+ return mapif_guild_broken(guild_id, 0);
}
diff --git a/src/char/int_guild.h b/src/char/int_guild.h
index 5bc3c2fe3..47c42dcc5 100644
--- a/src/char/int_guild.h
+++ b/src/char/int_guild.h
@@ -5,19 +5,19 @@
#define _INT_GUILD_SQL_H_
enum {
- GS_BASIC = 0x0001,
- GS_MEMBER = 0x0002,
- GS_POSITION = 0x0004,
- GS_ALLIANCE = 0x0008,
- GS_EXPULSION = 0x0010,
- GS_SKILL = 0x0020,
- GS_EMBLEM = 0x0040,
- GS_CONNECT = 0x0080,
- GS_LEVEL = 0x0100,
- GS_MES = 0x0200,
- GS_MASK = 0x03FF,
- GS_BASIC_MASK = (GS_BASIC | GS_EMBLEM | GS_CONNECT | GS_LEVEL | GS_MES),
- GS_REMOVE = 0x8000,
+ GS_BASIC = 0x0001,
+ GS_MEMBER = 0x0002,
+ GS_POSITION = 0x0004,
+ GS_ALLIANCE = 0x0008,
+ GS_EXPULSION = 0x0010,
+ GS_SKILL = 0x0020,
+ GS_EMBLEM = 0x0040,
+ GS_CONNECT = 0x0080,
+ GS_LEVEL = 0x0100,
+ GS_MES = 0x0200,
+ GS_MASK = 0x03FF,
+ GS_BASIC_MASK = (GS_BASIC | GS_EMBLEM | GS_CONNECT | GS_LEVEL | GS_MES),
+ GS_REMOVE = 0x8000,
};
struct guild;
diff --git a/src/char/int_homun.c b/src/char/int_homun.c
index 5676556f4..933661954 100644
--- a/src/char/int_homun.c
+++ b/src/char/int_homun.c
@@ -18,281 +18,279 @@
int inter_homunculus_sql_init(void)
{
- return 0;
+ return 0;
}
void inter_homunculus_sql_final(void)
{
- return;
+ return;
}
static void mapif_homunculus_created(int fd, int account_id, struct s_homunculus *sh, unsigned char flag)
{
- WFIFOHEAD(fd, sizeof(struct s_homunculus)+9);
- WFIFOW(fd,0) = 0x3890;
- WFIFOW(fd,2) = sizeof(struct s_homunculus)+9;
- WFIFOL(fd,4) = account_id;
- WFIFOB(fd,8)= flag;
- memcpy(WFIFOP(fd,9),sh,sizeof(struct s_homunculus));
- WFIFOSET(fd, WFIFOW(fd,2));
+ WFIFOHEAD(fd, sizeof(struct s_homunculus)+9);
+ WFIFOW(fd,0) = 0x3890;
+ WFIFOW(fd,2) = sizeof(struct s_homunculus)+9;
+ WFIFOL(fd,4) = account_id;
+ WFIFOB(fd,8)= flag;
+ memcpy(WFIFOP(fd,9),sh,sizeof(struct s_homunculus));
+ WFIFOSET(fd, WFIFOW(fd,2));
}
static void mapif_homunculus_deleted(int fd, int flag)
{
- WFIFOHEAD(fd, 3);
- WFIFOW(fd, 0) = 0x3893;
- WFIFOB(fd,2) = flag; //Flag 1 = success
- WFIFOSET(fd, 3);
+ WFIFOHEAD(fd, 3);
+ WFIFOW(fd, 0) = 0x3893;
+ WFIFOB(fd,2) = flag; //Flag 1 = success
+ WFIFOSET(fd, 3);
}
static void mapif_homunculus_loaded(int fd, int account_id, struct s_homunculus *hd)
{
- WFIFOHEAD(fd, sizeof(struct s_homunculus)+9);
- WFIFOW(fd,0) = 0x3891;
- WFIFOW(fd,2) = sizeof(struct s_homunculus)+9;
- WFIFOL(fd,4) = account_id;
- if (hd != NULL) {
- WFIFOB(fd,8) = 1; // success
- memcpy(WFIFOP(fd,9), hd, sizeof(struct s_homunculus));
- } else {
- WFIFOB(fd,8) = 0; // not found.
- memset(WFIFOP(fd,9), 0, sizeof(struct s_homunculus));
- }
- WFIFOSET(fd, sizeof(struct s_homunculus)+9);
+ WFIFOHEAD(fd, sizeof(struct s_homunculus)+9);
+ WFIFOW(fd,0) = 0x3891;
+ WFIFOW(fd,2) = sizeof(struct s_homunculus)+9;
+ WFIFOL(fd,4) = account_id;
+ if( hd != NULL )
+ {
+ WFIFOB(fd,8) = 1; // success
+ memcpy(WFIFOP(fd,9), hd, sizeof(struct s_homunculus));
+ }
+ else
+ {
+ WFIFOB(fd,8) = 0; // not found.
+ memset(WFIFOP(fd,9), 0, sizeof(struct s_homunculus));
+ }
+ WFIFOSET(fd, sizeof(struct s_homunculus)+9);
}
static void mapif_homunculus_saved(int fd, int account_id, bool flag)
{
- WFIFOHEAD(fd, 7);
- WFIFOW(fd,0) = 0x3892;
- WFIFOL(fd,2) = account_id;
- WFIFOB(fd,6) = flag; // 1:success, 0:failure
- WFIFOSET(fd, 7);
+ WFIFOHEAD(fd, 7);
+ WFIFOW(fd,0) = 0x3892;
+ WFIFOL(fd,2) = account_id;
+ WFIFOB(fd,6) = flag; // 1:success, 0:failure
+ WFIFOSET(fd, 7);
}
-static void mapif_homunculus_renamed(int fd, int account_id, int char_id, unsigned char flag, char *name)
+static void mapif_homunculus_renamed(int fd, int account_id, int char_id, unsigned char flag, char* name)
{
- WFIFOHEAD(fd, NAME_LENGTH+12);
- WFIFOW(fd, 0) = 0x3894;
- WFIFOL(fd, 2) = account_id;
- WFIFOL(fd, 6) = char_id;
- WFIFOB(fd,10) = flag;
- safestrncpy((char *)WFIFOP(fd,11), name, NAME_LENGTH);
- WFIFOSET(fd, NAME_LENGTH+12);
+ WFIFOHEAD(fd, NAME_LENGTH+12);
+ WFIFOW(fd, 0) = 0x3894;
+ WFIFOL(fd, 2) = account_id;
+ WFIFOL(fd, 6) = char_id;
+ WFIFOB(fd,10) = flag;
+ safestrncpy((char*)WFIFOP(fd,11), name, NAME_LENGTH);
+ WFIFOSET(fd, NAME_LENGTH+12);
}
-bool mapif_homunculus_save(struct s_homunculus *hd)
+bool mapif_homunculus_save(struct s_homunculus* hd)
{
- bool flag = true;
- char esc_name[NAME_LENGTH*2+1];
-
- Sql_EscapeStringLen(sql_handle, esc_name, hd->name, strnlen(hd->name, NAME_LENGTH));
-
- if (hd->hom_id == 0) {
- // new homunculus
- if (SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` "
- "(`char_id`, `class`,`prev_class`,`name`,`level`,`exp`,`intimacy`,`hunger`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hp`,`max_hp`,`sp`,`max_sp`,`skill_point`, `rename_flag`, `vaporize`) "
- "VALUES ('%d', '%d', '%d', '%s', '%d', '%u', '%u', '%d', '%d', %d, '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
- homunculus_db, hd->char_id, hd->class_, hd->prev_class, esc_name, hd->level, hd->exp, hd->intimacy, hd->hunger, hd->str, hd->agi, hd->vit, hd->int_, hd->dex, hd->luk,
- hd->hp, hd->max_hp, hd->sp, hd->max_sp, hd->skillpts, hd->rename_flag, hd->vaporize)) {
- Sql_ShowDebug(sql_handle);
- flag = false;
- } else {
- hd->hom_id = (int)Sql_LastInsertId(sql_handle);
- }
- } else {
- if (SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `char_id`='%d', `class`='%d',`prev_class`='%d',`name`='%s',`level`='%d',`exp`='%u',`intimacy`='%u',`hunger`='%d', `str`='%d', `agi`='%d', `vit`='%d', `int`='%d', `dex`='%d', `luk`='%d', `hp`='%d',`max_hp`='%d',`sp`='%d',`max_sp`='%d',`skill_point`='%d', `rename_flag`='%d', `vaporize`='%d' WHERE `homun_id`='%d'",
- homunculus_db, hd->char_id, hd->class_, hd->prev_class, esc_name, hd->level, hd->exp, hd->intimacy, hd->hunger, hd->str, hd->agi, hd->vit, hd->int_, hd->dex, hd->luk,
- hd->hp, hd->max_hp, hd->sp, hd->max_sp, hd->skillpts, hd->rename_flag, hd->vaporize, hd->hom_id)) {
- Sql_ShowDebug(sql_handle);
- flag = false;
- } else {
- SqlStmt *stmt;
- int i;
-
- stmt = SqlStmt_Malloc(sql_handle);
- if (SQL_ERROR == SqlStmt_Prepare(stmt, "REPLACE INTO `%s` (`homun_id`, `id`, `lv`) VALUES (%d, ?, ?)", skill_homunculus_db, hd->hom_id))
- SqlStmt_ShowDebug(stmt);
- for (i = 0; i < MAX_HOMUNSKILL; ++i) {
- if (hd->hskill[i].id > 0 && hd->hskill[i].lv != 0) {
- SqlStmt_BindParam(stmt, 0, SQLDT_USHORT, &hd->hskill[i].id, 0);
- SqlStmt_BindParam(stmt, 1, SQLDT_USHORT, &hd->hskill[i].lv, 0);
- if (SQL_ERROR == SqlStmt_Execute(stmt)) {
- SqlStmt_ShowDebug(stmt);
- SqlStmt_Free(stmt);
- flag = false;
- break;
- }
- }
- }
- SqlStmt_Free(stmt);
- }
- }
-
- return flag;
+ bool flag = true;
+ char esc_name[NAME_LENGTH*2+1];
+
+ Sql_EscapeStringLen(sql_handle, esc_name, hd->name, strnlen(hd->name, NAME_LENGTH));
+
+ if( hd->hom_id == 0 )
+ {// new homunculus
+ if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` "
+ "(`char_id`, `class`,`prev_class`,`name`,`level`,`exp`,`intimacy`,`hunger`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hp`,`max_hp`,`sp`,`max_sp`,`skill_point`, `rename_flag`, `vaporize`) "
+ "VALUES ('%d', '%d', '%d', '%s', '%d', '%u', '%u', '%d', '%d', %d, '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
+ homunculus_db, hd->char_id, hd->class_, hd->prev_class, esc_name, hd->level, hd->exp, hd->intimacy, hd->hunger, hd->str, hd->agi, hd->vit, hd->int_, hd->dex, hd->luk,
+ hd->hp, hd->max_hp, hd->sp, hd->max_sp, hd->skillpts, hd->rename_flag, hd->vaporize) )
+ {
+ Sql_ShowDebug(sql_handle);
+ flag = false;
+ }
+ else
+ {
+ hd->hom_id = (int)Sql_LastInsertId(sql_handle);
+ }
+ }
+ else
+ {
+ if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `char_id`='%d', `class`='%d',`prev_class`='%d',`name`='%s',`level`='%d',`exp`='%u',`intimacy`='%u',`hunger`='%d', `str`='%d', `agi`='%d', `vit`='%d', `int`='%d', `dex`='%d', `luk`='%d', `hp`='%d',`max_hp`='%d',`sp`='%d',`max_sp`='%d',`skill_point`='%d', `rename_flag`='%d', `vaporize`='%d' WHERE `homun_id`='%d'",
+ homunculus_db, hd->char_id, hd->class_, hd->prev_class, esc_name, hd->level, hd->exp, hd->intimacy, hd->hunger, hd->str, hd->agi, hd->vit, hd->int_, hd->dex, hd->luk,
+ hd->hp, hd->max_hp, hd->sp, hd->max_sp, hd->skillpts, hd->rename_flag, hd->vaporize, hd->hom_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ flag = false;
+ }
+ else
+ {
+ SqlStmt* stmt;
+ int i;
+
+ stmt = SqlStmt_Malloc(sql_handle);
+ if( SQL_ERROR == SqlStmt_Prepare(stmt, "REPLACE INTO `%s` (`homun_id`, `id`, `lv`) VALUES (%d, ?, ?)", skill_homunculus_db, hd->hom_id) )
+ SqlStmt_ShowDebug(stmt);
+ for( i = 0; i < MAX_HOMUNSKILL; ++i )
+ {
+ if( hd->hskill[i].id > 0 && hd->hskill[i].lv != 0 )
+ {
+ SqlStmt_BindParam(stmt, 0, SQLDT_USHORT, &hd->hskill[i].id, 0);
+ SqlStmt_BindParam(stmt, 1, SQLDT_USHORT, &hd->hskill[i].lv, 0);
+ if( SQL_ERROR == SqlStmt_Execute(stmt) )
+ {
+ SqlStmt_ShowDebug(stmt);
+ SqlStmt_Free(stmt);
+ flag = false;
+ break;
+ }
+ }
+ }
+ SqlStmt_Free(stmt);
+ }
+ }
+
+ return flag;
}
// Load an homunculus
-bool mapif_homunculus_load(int homun_id, struct s_homunculus *hd)
+bool mapif_homunculus_load(int homun_id, struct s_homunculus* hd)
{
- int i;
- char *data;
- size_t len;
-
- memset(hd, 0, sizeof(*hd));
-
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `homun_id`,`char_id`,`class`,`prev_class`,`name`,`level`,`exp`,`intimacy`,`hunger`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hp`,`max_hp`,`sp`,`max_sp`,`skill_point`,`rename_flag`, `vaporize` FROM `%s` WHERE `homun_id`='%u'", homunculus_db, homun_id)) {
- Sql_ShowDebug(sql_handle);
- return false;
- }
-
- if (!Sql_NumRows(sql_handle)) {
- //No homunculus found.
- Sql_FreeResult(sql_handle);
- return false;
- }
- if (SQL_SUCCESS != Sql_NextRow(sql_handle)) {
- Sql_ShowDebug(sql_handle);
- Sql_FreeResult(sql_handle);
- return false;
- }
-
- hd->hom_id = homun_id;
- Sql_GetData(sql_handle, 1, &data, NULL);
- hd->char_id = atoi(data);
- Sql_GetData(sql_handle, 2, &data, NULL);
- hd->class_ = atoi(data);
- Sql_GetData(sql_handle, 3, &data, NULL);
- hd->prev_class = atoi(data);
- Sql_GetData(sql_handle, 4, &data, &len);
- safestrncpy(hd->name, data, sizeof(hd->name));
- Sql_GetData(sql_handle, 5, &data, NULL);
- hd->level = atoi(data);
- Sql_GetData(sql_handle, 6, &data, NULL);
- hd->exp = atoi(data);
- Sql_GetData(sql_handle, 7, &data, NULL);
- hd->intimacy = (unsigned int)strtoul(data, NULL, 10);
- Sql_GetData(sql_handle, 8, &data, NULL);
- hd->hunger = atoi(data);
- Sql_GetData(sql_handle, 9, &data, NULL);
- hd->str = atoi(data);
- Sql_GetData(sql_handle, 10, &data, NULL);
- hd->agi = atoi(data);
- Sql_GetData(sql_handle, 11, &data, NULL);
- hd->vit = atoi(data);
- Sql_GetData(sql_handle, 12, &data, NULL);
- hd->int_ = atoi(data);
- Sql_GetData(sql_handle, 13, &data, NULL);
- hd->dex = atoi(data);
- Sql_GetData(sql_handle, 14, &data, NULL);
- hd->luk = atoi(data);
- Sql_GetData(sql_handle, 15, &data, NULL);
- hd->hp = atoi(data);
- Sql_GetData(sql_handle, 16, &data, NULL);
- hd->max_hp = atoi(data);
- Sql_GetData(sql_handle, 17, &data, NULL);
- hd->sp = atoi(data);
- Sql_GetData(sql_handle, 18, &data, NULL);
- hd->max_sp = atoi(data);
- Sql_GetData(sql_handle, 19, &data, NULL);
- hd->skillpts = atoi(data);
- Sql_GetData(sql_handle, 20, &data, NULL);
- hd->rename_flag = atoi(data);
- Sql_GetData(sql_handle, 21, &data, NULL);
- hd->vaporize = atoi(data);
- Sql_FreeResult(sql_handle);
-
- hd->intimacy = cap_value(hd->intimacy, 0, 100000);
- hd->hunger = cap_value(hd->hunger, 0, 100);
-
- // Load Homunculus Skill
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `id`,`lv` FROM `%s` WHERE `homun_id`=%d", skill_homunculus_db, homun_id)) {
- Sql_ShowDebug(sql_handle);
- return false;
- }
- while (SQL_SUCCESS == Sql_NextRow(sql_handle)) {
- // id
- Sql_GetData(sql_handle, 0, &data, NULL);
- i = atoi(data);
- if (i < HM_SKILLBASE || i >= HM_SKILLBASE + MAX_HOMUNSKILL)
- continue;// invalid skill id
- i = i - HM_SKILLBASE;
- hd->hskill[i].id = (unsigned short)atoi(data);
-
- // lv
- Sql_GetData(sql_handle, 1, &data, NULL);
- hd->hskill[i].lv = (unsigned char)atoi(data);
- }
- Sql_FreeResult(sql_handle);
-
- if (save_log)
- ShowInfo("Homunculus loaded (%d - %s).\n", hd->hom_id, hd->name);
-
- return true;
+ int i;
+ char* data;
+ size_t len;
+
+ memset(hd, 0, sizeof(*hd));
+
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `homun_id`,`char_id`,`class`,`prev_class`,`name`,`level`,`exp`,`intimacy`,`hunger`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hp`,`max_hp`,`sp`,`max_sp`,`skill_point`,`rename_flag`, `vaporize` FROM `%s` WHERE `homun_id`='%u'", homunculus_db, homun_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ return false;
+ }
+
+ if( !Sql_NumRows(sql_handle) )
+ { //No homunculus found.
+ Sql_FreeResult(sql_handle);
+ return false;
+ }
+ if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
+ {
+ Sql_ShowDebug(sql_handle);
+ Sql_FreeResult(sql_handle);
+ return false;
+ }
+
+ hd->hom_id = homun_id;
+ Sql_GetData(sql_handle, 1, &data, NULL); hd->char_id = atoi(data);
+ Sql_GetData(sql_handle, 2, &data, NULL); hd->class_ = atoi(data);
+ Sql_GetData(sql_handle, 3, &data, NULL); hd->prev_class = atoi(data);
+ Sql_GetData(sql_handle, 4, &data, &len); safestrncpy(hd->name, data, sizeof(hd->name));
+ Sql_GetData(sql_handle, 5, &data, NULL); hd->level = atoi(data);
+ Sql_GetData(sql_handle, 6, &data, NULL); hd->exp = atoi(data);
+ Sql_GetData(sql_handle, 7, &data, NULL); hd->intimacy = (unsigned int)strtoul(data, NULL, 10);
+ Sql_GetData(sql_handle, 8, &data, NULL); hd->hunger = atoi(data);
+ Sql_GetData(sql_handle, 9, &data, NULL); hd->str = atoi(data);
+ Sql_GetData(sql_handle, 10, &data, NULL); hd->agi = atoi(data);
+ Sql_GetData(sql_handle, 11, &data, NULL); hd->vit = atoi(data);
+ Sql_GetData(sql_handle, 12, &data, NULL); hd->int_ = atoi(data);
+ Sql_GetData(sql_handle, 13, &data, NULL); hd->dex = atoi(data);
+ Sql_GetData(sql_handle, 14, &data, NULL); hd->luk = atoi(data);
+ Sql_GetData(sql_handle, 15, &data, NULL); hd->hp = atoi(data);
+ Sql_GetData(sql_handle, 16, &data, NULL); hd->max_hp = atoi(data);
+ Sql_GetData(sql_handle, 17, &data, NULL); hd->sp = atoi(data);
+ Sql_GetData(sql_handle, 18, &data, NULL); hd->max_sp = atoi(data);
+ Sql_GetData(sql_handle, 19, &data, NULL); hd->skillpts = atoi(data);
+ Sql_GetData(sql_handle, 20, &data, NULL); hd->rename_flag = atoi(data);
+ Sql_GetData(sql_handle, 21, &data, NULL); hd->vaporize = atoi(data);
+ Sql_FreeResult(sql_handle);
+
+ hd->intimacy = cap_value(hd->intimacy, 0, 100000);
+ hd->hunger = cap_value(hd->hunger, 0, 100);
+
+ // Load Homunculus Skill
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `id`,`lv` FROM `%s` WHERE `homun_id`=%d", skill_homunculus_db, homun_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ return false;
+ }
+ while( SQL_SUCCESS == Sql_NextRow(sql_handle) )
+ {
+ // id
+ Sql_GetData(sql_handle, 0, &data, NULL);
+ i = atoi(data);
+ if( i < HM_SKILLBASE || i >= HM_SKILLBASE + MAX_HOMUNSKILL )
+ continue;// invalid skill id
+ i = i - HM_SKILLBASE;
+ hd->hskill[i].id = (unsigned short)atoi(data);
+
+ // lv
+ Sql_GetData(sql_handle, 1, &data, NULL);
+ hd->hskill[i].lv = (unsigned char)atoi(data);
+ }
+ Sql_FreeResult(sql_handle);
+
+ if( save_log )
+ ShowInfo("Homunculus loaded (%d - %s).\n", hd->hom_id, hd->name);
+
+ return true;
}
bool mapif_homunculus_delete(int homun_id)
{
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `homun_id` = '%u'", homunculus_db, homun_id)
- || SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `homun_id` = '%u'", skill_homunculus_db, homun_id)
- ) {
- Sql_ShowDebug(sql_handle);
- return false;
- }
- return true;
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `homun_id` = '%u'", homunculus_db, homun_id)
+ || SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `homun_id` = '%u'", skill_homunculus_db, homun_id)
+ ) {
+ Sql_ShowDebug(sql_handle);
+ return false;
+ }
+ return true;
}
bool mapif_homunculus_rename(char *name)
{
- int i;
-
- // Check Authorised letters/symbols in the name of the homun
- if (char_name_option == 1) {
- // only letters/symbols in char_name_letters are authorised
- for (i = 0; i < NAME_LENGTH && name[i]; i++)
- if (strchr(char_name_letters, name[i]) == NULL)
- return false;
- } else if (char_name_option == 2) {
- // letters/symbols in char_name_letters are forbidden
- for (i = 0; i < NAME_LENGTH && name[i]; i++)
- if (strchr(char_name_letters, name[i]) != NULL)
- return false;
- }
-
- return true;
+ int i;
+
+ // Check Authorised letters/symbols in the name of the homun
+ if( char_name_option == 1 )
+ {// only letters/symbols in char_name_letters are authorised
+ for( i = 0; i < NAME_LENGTH && name[i]; i++ )
+ if( strchr(char_name_letters, name[i]) == NULL )
+ return false;
+ } else
+ if( char_name_option == 2 )
+ {// letters/symbols in char_name_letters are forbidden
+ for( i = 0; i < NAME_LENGTH && name[i]; i++ )
+ if( strchr(char_name_letters, name[i]) != NULL )
+ return false;
+ }
+
+ return true;
}
-static void mapif_parse_homunculus_create(int fd, int len, int account_id, struct s_homunculus *phd)
+static void mapif_parse_homunculus_create(int fd, int len, int account_id, struct s_homunculus* phd)
{
- bool result = mapif_homunculus_save(phd);
- mapif_homunculus_created(fd, account_id, phd, result);
+ bool result = mapif_homunculus_save(phd);
+ mapif_homunculus_created(fd, account_id, phd, result);
}
static void mapif_parse_homunculus_delete(int fd, int homun_id)
{
- bool result = mapif_homunculus_delete(homun_id);
- mapif_homunculus_deleted(fd, result);
+ bool result = mapif_homunculus_delete(homun_id);
+ mapif_homunculus_deleted(fd, result);
}
static void mapif_parse_homunculus_load(int fd, int account_id, int homun_id)
{
- struct s_homunculus hd;
- bool result = mapif_homunculus_load(homun_id, &hd);
- mapif_homunculus_loaded(fd, account_id, (result ? &hd : NULL));
+ struct s_homunculus hd;
+ bool result = mapif_homunculus_load(homun_id, &hd);
+ mapif_homunculus_loaded(fd, account_id, ( result ? &hd : NULL ));
}
-static void mapif_parse_homunculus_save(int fd, int len, int account_id, struct s_homunculus *phd)
+static void mapif_parse_homunculus_save(int fd, int len, int account_id, struct s_homunculus* phd)
{
- bool result = mapif_homunculus_save(phd);
- mapif_homunculus_saved(fd, account_id, result);
+ bool result = mapif_homunculus_save(phd);
+ mapif_homunculus_saved(fd, account_id, result);
}
-static void mapif_parse_homunculus_rename(int fd, int account_id, int char_id, char *name)
+static void mapif_parse_homunculus_rename(int fd, int account_id, int char_id, char* name)
{
- bool result = mapif_homunculus_rename(name);
- mapif_homunculus_renamed(fd, account_id, char_id, result, name);
+ bool result = mapif_homunculus_rename(name);
+ mapif_homunculus_renamed(fd, account_id, char_id, result, name);
}
/*==========================================
@@ -300,26 +298,17 @@ static void mapif_parse_homunculus_rename(int fd, int account_id, int char_id, c
*------------------------------------------*/
int inter_homunculus_parse_frommap(int fd)
{
- unsigned short cmd = RFIFOW(fd,0);
-
- switch (cmd) {
- case 0x3090:
- mapif_parse_homunculus_create(fd, (int)RFIFOW(fd,2), (int)RFIFOL(fd,4), (struct s_homunculus *)RFIFOP(fd,8));
- break;
- case 0x3091:
- mapif_parse_homunculus_load(fd, (int)RFIFOL(fd,2), (int)RFIFOL(fd,6));
- break;
- case 0x3092:
- mapif_parse_homunculus_save(fd, (int)RFIFOW(fd,2), (int)RFIFOL(fd,4), (struct s_homunculus *)RFIFOP(fd,8));
- break;
- case 0x3093:
- mapif_parse_homunculus_delete(fd, (int)RFIFOL(fd,2));
- break;
- case 0x3094:
- mapif_parse_homunculus_rename(fd, (int)RFIFOL(fd,2), (int)RFIFOL(fd,6), (char *)RFIFOP(fd,10));
- break;
- default:
- return 0;
- }
- return 1;
+ unsigned short cmd = RFIFOW(fd,0);
+
+ switch( cmd )
+ {
+ case 0x3090: mapif_parse_homunculus_create(fd, (int)RFIFOW(fd,2), (int)RFIFOL(fd,4), (struct s_homunculus*)RFIFOP(fd,8)); break;
+ case 0x3091: mapif_parse_homunculus_load (fd, (int)RFIFOL(fd,2), (int)RFIFOL(fd,6)); break;
+ case 0x3092: mapif_parse_homunculus_save (fd, (int)RFIFOW(fd,2), (int)RFIFOL(fd,4), (struct s_homunculus*)RFIFOP(fd,8)); break;
+ case 0x3093: mapif_parse_homunculus_delete(fd, (int)RFIFOL(fd,2)); break;
+ case 0x3094: mapif_parse_homunculus_rename(fd, (int)RFIFOL(fd,2), (int)RFIFOL(fd,6), (char*)RFIFOP(fd,10)); break;
+ default:
+ return 0;
+ }
+ return 1;
}
diff --git a/src/char/int_homun.h b/src/char/int_homun.h
index e7976d51a..1c0d76269 100644
--- a/src/char/int_homun.h
+++ b/src/char/int_homun.h
@@ -10,8 +10,8 @@ int inter_homunculus_sql_init(void);
void inter_homunculus_sql_final(void);
int inter_homunculus_parse_frommap(int fd);
-bool mapif_homunculus_save(struct s_homunculus *hd);
-bool mapif_homunculus_load(int homun_id, struct s_homunculus *hd);
+bool mapif_homunculus_save(struct s_homunculus* hd);
+bool mapif_homunculus_load(int homun_id, struct s_homunculus* hd);
bool mapif_homunculus_delete(int homun_id);
bool mapif_homunculus_rename(char *name);
diff --git a/src/char/int_mail.c b/src/char/int_mail.c
index 2e34d9014..98da43aeb 100644
--- a/src/char/int_mail.c
+++ b/src/char/int_mail.c
@@ -15,200 +15,180 @@
#include <string.h>
#include <stdlib.h>
-static int mail_fromsql(int char_id, struct mail_data *md)
+static int mail_fromsql(int char_id, struct mail_data* md)
{
- int i, j;
- struct mail_message *msg;
- struct item *item;
- char *data;
- StringBuf buf;
-
- memset(md, 0, sizeof(struct mail_data));
- md->amount = 0;
- md->full = false;
-
- StringBuf_Init(&buf);
- StringBuf_AppendStr(&buf, "SELECT `id`,`send_name`,`send_id`,`dest_name`,`dest_id`,`title`,`message`,`time`,`status`,"
- "`zeny`,`amount`,`nameid`,`refine`,`attribute`,`identify`");
- for (i = 0; i < MAX_SLOTS; i++)
- StringBuf_Printf(&buf, ",`card%d`", i);
-
- // I keep the `status` < 3 just in case someone forget to apply the sqlfix
- StringBuf_Printf(&buf, " FROM `%s` WHERE `dest_id`='%d' AND `status` < 3 ORDER BY `id` LIMIT %d",
- mail_db, char_id, MAIL_MAX_INBOX + 1);
-
- if (SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf)))
- Sql_ShowDebug(sql_handle);
-
- StringBuf_Destroy(&buf);
-
- for (i = 0; i < MAIL_MAX_INBOX && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i) {
- msg = &md->msg[i];
- Sql_GetData(sql_handle, 0, &data, NULL);
- msg->id = atoi(data);
- Sql_GetData(sql_handle, 1, &data, NULL);
- safestrncpy(msg->send_name, data, NAME_LENGTH);
- Sql_GetData(sql_handle, 2, &data, NULL);
- msg->send_id = atoi(data);
- Sql_GetData(sql_handle, 3, &data, NULL);
- safestrncpy(msg->dest_name, data, NAME_LENGTH);
- Sql_GetData(sql_handle, 4, &data, NULL);
- msg->dest_id = atoi(data);
- Sql_GetData(sql_handle, 5, &data, NULL);
- safestrncpy(msg->title, data, MAIL_TITLE_LENGTH);
- Sql_GetData(sql_handle, 6, &data, NULL);
- safestrncpy(msg->body, data, MAIL_BODY_LENGTH);
- Sql_GetData(sql_handle, 7, &data, NULL);
- msg->timestamp = atoi(data);
- Sql_GetData(sql_handle, 8, &data, NULL);
- msg->status = (mail_status)atoi(data);
- Sql_GetData(sql_handle, 9, &data, NULL);
- msg->zeny = atoi(data);
- item = &msg->item;
- Sql_GetData(sql_handle,10, &data, NULL);
- item->amount = (short)atoi(data);
- Sql_GetData(sql_handle,11, &data, NULL);
- item->nameid = atoi(data);
- Sql_GetData(sql_handle,12, &data, NULL);
- item->refine = atoi(data);
- Sql_GetData(sql_handle,13, &data, NULL);
- item->attribute = atoi(data);
- Sql_GetData(sql_handle,14, &data, NULL);
- item->identify = atoi(data);
- item->expire_time = 0;
-
- for (j = 0; j < MAX_SLOTS; j++) {
- Sql_GetData(sql_handle, 15 + j, &data, NULL);
- item->card[j] = atoi(data);
- }
- }
-
- md->full = (Sql_NumRows(sql_handle) > MAIL_MAX_INBOX);
-
- md->amount = i;
- Sql_FreeResult(sql_handle);
-
- md->unchecked = 0;
- md->unread = 0;
- for (i = 0; i < md->amount; i++) {
- msg = &md->msg[i];
- if (msg->status == MAIL_NEW) {
- if (SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `status` = '%d' WHERE `id` = '%d'", mail_db, MAIL_UNREAD, msg->id))
- Sql_ShowDebug(sql_handle);
-
- msg->status = MAIL_UNREAD;
- md->unchecked++;
- } else if (msg->status == MAIL_UNREAD)
- md->unread++;
- }
-
- ShowInfo("mail load complete from DB - id: %d (total: %d)\n", char_id, md->amount);
- return 1;
+ int i, j;
+ struct mail_message *msg;
+ struct item *item;
+ char *data;
+ StringBuf buf;
+
+ memset(md, 0, sizeof(struct mail_data));
+ md->amount = 0;
+ md->full = false;
+
+ StringBuf_Init(&buf);
+ StringBuf_AppendStr(&buf, "SELECT `id`,`send_name`,`send_id`,`dest_name`,`dest_id`,`title`,`message`,`time`,`status`,"
+ "`zeny`,`amount`,`nameid`,`refine`,`attribute`,`identify`");
+ for (i = 0; i < MAX_SLOTS; i++)
+ StringBuf_Printf(&buf, ",`card%d`", i);
+
+ // I keep the `status` < 3 just in case someone forget to apply the sqlfix
+ StringBuf_Printf(&buf, " FROM `%s` WHERE `dest_id`='%d' AND `status` < 3 ORDER BY `id` LIMIT %d",
+ mail_db, char_id, MAIL_MAX_INBOX + 1);
+
+ if( SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf)) )
+ Sql_ShowDebug(sql_handle);
+
+ StringBuf_Destroy(&buf);
+
+ for (i = 0; i < MAIL_MAX_INBOX && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
+ {
+ msg = &md->msg[i];
+ Sql_GetData(sql_handle, 0, &data, NULL); msg->id = atoi(data);
+ Sql_GetData(sql_handle, 1, &data, NULL); safestrncpy(msg->send_name, data, NAME_LENGTH);
+ Sql_GetData(sql_handle, 2, &data, NULL); msg->send_id = atoi(data);
+ Sql_GetData(sql_handle, 3, &data, NULL); safestrncpy(msg->dest_name, data, NAME_LENGTH);
+ Sql_GetData(sql_handle, 4, &data, NULL); msg->dest_id = atoi(data);
+ Sql_GetData(sql_handle, 5, &data, NULL); safestrncpy(msg->title, data, MAIL_TITLE_LENGTH);
+ Sql_GetData(sql_handle, 6, &data, NULL); safestrncpy(msg->body, data, MAIL_BODY_LENGTH);
+ Sql_GetData(sql_handle, 7, &data, NULL); msg->timestamp = atoi(data);
+ Sql_GetData(sql_handle, 8, &data, NULL); msg->status = (mail_status)atoi(data);
+ Sql_GetData(sql_handle, 9, &data, NULL); msg->zeny = atoi(data);
+ item = &msg->item;
+ Sql_GetData(sql_handle,10, &data, NULL); item->amount = (short)atoi(data);
+ Sql_GetData(sql_handle,11, &data, NULL); item->nameid = atoi(data);
+ Sql_GetData(sql_handle,12, &data, NULL); item->refine = atoi(data);
+ Sql_GetData(sql_handle,13, &data, NULL); item->attribute = atoi(data);
+ Sql_GetData(sql_handle,14, &data, NULL); item->identify = atoi(data);
+ item->expire_time = 0;
+
+ for (j = 0; j < MAX_SLOTS; j++)
+ {
+ Sql_GetData(sql_handle, 15 + j, &data, NULL);
+ item->card[j] = atoi(data);
+ }
+ }
+
+ md->full = ( Sql_NumRows(sql_handle) > MAIL_MAX_INBOX );
+
+ md->amount = i;
+ Sql_FreeResult(sql_handle);
+
+ md->unchecked = 0;
+ md->unread = 0;
+ for (i = 0; i < md->amount; i++)
+ {
+ msg = &md->msg[i];
+ if( msg->status == MAIL_NEW )
+ {
+ if ( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `status` = '%d' WHERE `id` = '%d'", mail_db, MAIL_UNREAD, msg->id) )
+ Sql_ShowDebug(sql_handle);
+
+ msg->status = MAIL_UNREAD;
+ md->unchecked++;
+ }
+ else if ( msg->status == MAIL_UNREAD )
+ md->unread++;
+ }
+
+ ShowInfo("mail load complete from DB - id: %d (total: %d)\n", char_id, md->amount);
+ return 1;
}
/// Stores a single message in the database.
/// Returns the message's ID if successful (or 0 if it fails).
-int mail_savemessage(struct mail_message *msg)
+int mail_savemessage(struct mail_message* msg)
{
- StringBuf buf;
- SqlStmt *stmt;
- int j;
-
- // build message save query
- StringBuf_Init(&buf);
- StringBuf_Printf(&buf, "INSERT INTO `%s` (`send_name`, `send_id`, `dest_name`, `dest_id`, `title`, `message`, `time`, `status`, `zeny`, `amount`, `nameid`, `refine`, `attribute`, `identify`", mail_db);
- for (j = 0; j < MAX_SLOTS; j++)
- StringBuf_Printf(&buf, ", `card%d`", j);
- StringBuf_Printf(&buf, ") VALUES (?, '%d', ?, '%d', ?, ?, '%lu', '%d', '%d', '%d', '%d', '%d', '%d', '%d'",
- msg->send_id, msg->dest_id, (unsigned long)msg->timestamp, msg->status, msg->zeny, msg->item.amount, msg->item.nameid, msg->item.refine, msg->item.attribute, msg->item.identify);
- for (j = 0; j < MAX_SLOTS; j++)
- StringBuf_Printf(&buf, ", '%d'", msg->item.card[j]);
- StringBuf_AppendStr(&buf, ")");
-
- // prepare and execute query
- stmt = SqlStmt_Malloc(sql_handle);
- if (SQL_SUCCESS != SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, msg->send_name, strnlen(msg->send_name, NAME_LENGTH))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, msg->dest_name, strnlen(msg->dest_name, NAME_LENGTH))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 2, SQLDT_STRING, msg->title, strnlen(msg->title, MAIL_TITLE_LENGTH))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 3, SQLDT_STRING, msg->body, strnlen(msg->body, MAIL_BODY_LENGTH))
- || SQL_SUCCESS != SqlStmt_Execute(stmt)) {
- SqlStmt_ShowDebug(stmt);
- msg->id = 0;
- } else
- msg->id = (int)SqlStmt_LastInsertId(stmt);
-
- SqlStmt_Free(stmt);
- StringBuf_Destroy(&buf);
-
- return msg->id;
+ StringBuf buf;
+ SqlStmt* stmt;
+ int j;
+
+ // build message save query
+ StringBuf_Init(&buf);
+ StringBuf_Printf(&buf, "INSERT INTO `%s` (`send_name`, `send_id`, `dest_name`, `dest_id`, `title`, `message`, `time`, `status`, `zeny`, `amount`, `nameid`, `refine`, `attribute`, `identify`", mail_db);
+ for (j = 0; j < MAX_SLOTS; j++)
+ StringBuf_Printf(&buf, ", `card%d`", j);
+ StringBuf_Printf(&buf, ") VALUES (?, '%d', ?, '%d', ?, ?, '%lu', '%d', '%d', '%d', '%d', '%d', '%d', '%d'",
+ msg->send_id, msg->dest_id, (unsigned long)msg->timestamp, msg->status, msg->zeny, msg->item.amount, msg->item.nameid, msg->item.refine, msg->item.attribute, msg->item.identify);
+ for (j = 0; j < MAX_SLOTS; j++)
+ StringBuf_Printf(&buf, ", '%d'", msg->item.card[j]);
+ StringBuf_AppendStr(&buf, ")");
+
+ // prepare and execute query
+ stmt = SqlStmt_Malloc(sql_handle);
+ if( SQL_SUCCESS != SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, msg->send_name, strnlen(msg->send_name, NAME_LENGTH))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, msg->dest_name, strnlen(msg->dest_name, NAME_LENGTH))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 2, SQLDT_STRING, msg->title, strnlen(msg->title, MAIL_TITLE_LENGTH))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 3, SQLDT_STRING, msg->body, strnlen(msg->body, MAIL_BODY_LENGTH))
+ || SQL_SUCCESS != SqlStmt_Execute(stmt) )
+ {
+ SqlStmt_ShowDebug(stmt);
+ msg->id = 0;
+ } else
+ msg->id = (int)SqlStmt_LastInsertId(stmt);
+
+ SqlStmt_Free(stmt);
+ StringBuf_Destroy(&buf);
+
+ return msg->id;
}
/// Retrieves a single message from the database.
/// Returns true if the operation succeeds (or false if it fails).
-static bool mail_loadmessage(int mail_id, struct mail_message *msg)
+static bool mail_loadmessage(int mail_id, struct mail_message* msg)
{
- int j;
- StringBuf buf;
-
- StringBuf_Init(&buf);
- StringBuf_AppendStr(&buf, "SELECT `id`,`send_name`,`send_id`,`dest_name`,`dest_id`,`title`,`message`,`time`,`status`,"
- "`zeny`,`amount`,`nameid`,`refine`,`attribute`,`identify`");
- for (j = 0; j < MAX_SLOTS; j++)
- StringBuf_Printf(&buf, ",`card%d`", j);
- StringBuf_Printf(&buf, " FROM `%s` WHERE `id` = '%d'", mail_db, mail_id);
-
- if (SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf))
- || SQL_SUCCESS != Sql_NextRow(sql_handle)) {
- Sql_ShowDebug(sql_handle);
- Sql_FreeResult(sql_handle);
- StringBuf_Destroy(&buf);
- return false;
- } else {
- char *data;
-
- Sql_GetData(sql_handle, 0, &data, NULL);
- msg->id = atoi(data);
- Sql_GetData(sql_handle, 1, &data, NULL);
- safestrncpy(msg->send_name, data, NAME_LENGTH);
- Sql_GetData(sql_handle, 2, &data, NULL);
- msg->send_id = atoi(data);
- Sql_GetData(sql_handle, 3, &data, NULL);
- safestrncpy(msg->dest_name, data, NAME_LENGTH);
- Sql_GetData(sql_handle, 4, &data, NULL);
- msg->dest_id = atoi(data);
- Sql_GetData(sql_handle, 5, &data, NULL);
- safestrncpy(msg->title, data, MAIL_TITLE_LENGTH);
- Sql_GetData(sql_handle, 6, &data, NULL);
- safestrncpy(msg->body, data, MAIL_BODY_LENGTH);
- Sql_GetData(sql_handle, 7, &data, NULL);
- msg->timestamp = atoi(data);
- Sql_GetData(sql_handle, 8, &data, NULL);
- msg->status = (mail_status)atoi(data);
- Sql_GetData(sql_handle, 9, &data, NULL);
- msg->zeny = atoi(data);
- Sql_GetData(sql_handle,10, &data, NULL);
- msg->item.amount = (short)atoi(data);
- Sql_GetData(sql_handle,11, &data, NULL);
- msg->item.nameid = atoi(data);
- Sql_GetData(sql_handle,12, &data, NULL);
- msg->item.refine = atoi(data);
- Sql_GetData(sql_handle,13, &data, NULL);
- msg->item.attribute = atoi(data);
- Sql_GetData(sql_handle,14, &data, NULL);
- msg->item.identify = atoi(data);
- msg->item.expire_time = 0;
-
- for (j = 0; j < MAX_SLOTS; j++) {
- Sql_GetData(sql_handle,15 + j, &data, NULL);
- msg->item.card[j] = atoi(data);
- }
- }
-
- StringBuf_Destroy(&buf);
- Sql_FreeResult(sql_handle);
-
- return true;
+ int j;
+ StringBuf buf;
+
+ StringBuf_Init(&buf);
+ StringBuf_AppendStr(&buf, "SELECT `id`,`send_name`,`send_id`,`dest_name`,`dest_id`,`title`,`message`,`time`,`status`,"
+ "`zeny`,`amount`,`nameid`,`refine`,`attribute`,`identify`");
+ for( j = 0; j < MAX_SLOTS; j++ )
+ StringBuf_Printf(&buf, ",`card%d`", j);
+ StringBuf_Printf(&buf, " FROM `%s` WHERE `id` = '%d'", mail_db, mail_id);
+
+ if( SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf))
+ || SQL_SUCCESS != Sql_NextRow(sql_handle) )
+ {
+ Sql_ShowDebug(sql_handle);
+ Sql_FreeResult(sql_handle);
+ StringBuf_Destroy(&buf);
+ return false;
+ }
+ else
+ {
+ char* data;
+
+ Sql_GetData(sql_handle, 0, &data, NULL); msg->id = atoi(data);
+ Sql_GetData(sql_handle, 1, &data, NULL); safestrncpy(msg->send_name, data, NAME_LENGTH);
+ Sql_GetData(sql_handle, 2, &data, NULL); msg->send_id = atoi(data);
+ Sql_GetData(sql_handle, 3, &data, NULL); safestrncpy(msg->dest_name, data, NAME_LENGTH);
+ Sql_GetData(sql_handle, 4, &data, NULL); msg->dest_id = atoi(data);
+ Sql_GetData(sql_handle, 5, &data, NULL); safestrncpy(msg->title, data, MAIL_TITLE_LENGTH);
+ Sql_GetData(sql_handle, 6, &data, NULL); safestrncpy(msg->body, data, MAIL_BODY_LENGTH);
+ Sql_GetData(sql_handle, 7, &data, NULL); msg->timestamp = atoi(data);
+ Sql_GetData(sql_handle, 8, &data, NULL); msg->status = (mail_status)atoi(data);
+ Sql_GetData(sql_handle, 9, &data, NULL); msg->zeny = atoi(data);
+ Sql_GetData(sql_handle,10, &data, NULL); msg->item.amount = (short)atoi(data);
+ Sql_GetData(sql_handle,11, &data, NULL); msg->item.nameid = atoi(data);
+ Sql_GetData(sql_handle,12, &data, NULL); msg->item.refine = atoi(data);
+ Sql_GetData(sql_handle,13, &data, NULL); msg->item.attribute = atoi(data);
+ Sql_GetData(sql_handle,14, &data, NULL); msg->item.identify = atoi(data);
+ msg->item.expire_time = 0;
+
+ for( j = 0; j < MAX_SLOTS; j++ )
+ {
+ Sql_GetData(sql_handle,15 + j, &data, NULL);
+ msg->item.card[j] = atoi(data);
+ }
+ }
+
+ StringBuf_Destroy(&buf);
+ Sql_FreeResult(sql_handle);
+
+ return true;
}
/*==========================================
@@ -216,22 +196,22 @@ static bool mail_loadmessage(int mail_id, struct mail_message *msg)
*------------------------------------------*/
static void mapif_Mail_sendinbox(int fd, int char_id, unsigned char flag)
{
- struct mail_data md;
- mail_fromsql(char_id, &md);
-
- //FIXME: dumping the whole structure like this is unsafe [ultramage]
- WFIFOHEAD(fd, sizeof(md) + 9);
- WFIFOW(fd,0) = 0x3848;
- WFIFOW(fd,2) = sizeof(md) + 9;
- WFIFOL(fd,4) = char_id;
- WFIFOB(fd,8) = flag;
- memcpy(WFIFOP(fd,9),&md,sizeof(md));
- WFIFOSET(fd,WFIFOW(fd,2));
+ struct mail_data md;
+ mail_fromsql(char_id, &md);
+
+ //FIXME: dumping the whole structure like this is unsafe [ultramage]
+ WFIFOHEAD(fd, sizeof(md) + 9);
+ WFIFOW(fd,0) = 0x3848;
+ WFIFOW(fd,2) = sizeof(md) + 9;
+ WFIFOL(fd,4) = char_id;
+ WFIFOB(fd,8) = flag;
+ memcpy(WFIFOP(fd,9),&md,sizeof(md));
+ WFIFOSET(fd,WFIFOW(fd,2));
}
static void mapif_parse_Mail_requestinbox(int fd)
{
- mapif_Mail_sendinbox(fd, RFIFOL(fd,2), RFIFOB(fd,6));
+ mapif_Mail_sendinbox(fd, RFIFOL(fd,2), RFIFOB(fd,6));
}
/*==========================================
@@ -239,9 +219,9 @@ static void mapif_parse_Mail_requestinbox(int fd)
*------------------------------------------*/
static void mapif_parse_Mail_read(int fd)
{
- int mail_id = RFIFOL(fd,2);
- if (SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `status` = '%d' WHERE `id` = '%d'", mail_db, MAIL_READ, mail_id))
- Sql_ShowDebug(sql_handle);
+ int mail_id = RFIFOL(fd,2);
+ if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `status` = '%d' WHERE `id` = '%d'", mail_db, MAIL_READ, mail_id) )
+ Sql_ShowDebug(sql_handle);
}
/*==========================================
@@ -249,57 +229,58 @@ static void mapif_parse_Mail_read(int fd)
*------------------------------------------*/
static bool mail_DeleteAttach(int mail_id)
{
- StringBuf buf;
- int i;
+ StringBuf buf;
+ int i;
- StringBuf_Init(&buf);
- StringBuf_Printf(&buf, "UPDATE `%s` SET `zeny` = '0', `nameid` = '0', `amount` = '0', `refine` = '0', `attribute` = '0', `identify` = '0'", mail_db);
- for (i = 0; i < MAX_SLOTS; i++)
- StringBuf_Printf(&buf, ", `card%d` = '0'", i);
- StringBuf_Printf(&buf, " WHERE `id` = '%d'", mail_id);
+ StringBuf_Init(&buf);
+ StringBuf_Printf(&buf, "UPDATE `%s` SET `zeny` = '0', `nameid` = '0', `amount` = '0', `refine` = '0', `attribute` = '0', `identify` = '0'", mail_db);
+ for (i = 0; i < MAX_SLOTS; i++)
+ StringBuf_Printf(&buf, ", `card%d` = '0'", i);
+ StringBuf_Printf(&buf, " WHERE `id` = '%d'", mail_id);
- if (SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf))) {
- Sql_ShowDebug(sql_handle);
- StringBuf_Destroy(&buf);
+ if( SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf)) )
+ {
+ Sql_ShowDebug(sql_handle);
+ StringBuf_Destroy(&buf);
- return false;
- }
+ return false;
+ }
- StringBuf_Destroy(&buf);
- return true;
+ StringBuf_Destroy(&buf);
+ return true;
}
static void mapif_Mail_getattach(int fd, int char_id, int mail_id)
{
- struct mail_message msg;
+ struct mail_message msg;
- if (!mail_loadmessage(mail_id, &msg))
- return;
+ if( !mail_loadmessage(mail_id, &msg) )
+ return;
- if (msg.dest_id != char_id)
- return;
+ if( msg.dest_id != char_id )
+ return;
- if (msg.status != MAIL_READ)
- return;
+ if( msg.status != MAIL_READ )
+ return;
- if ((msg.item.nameid < 1 || msg.item.amount < 1) && msg.zeny < 1)
- return; // No Attachment
+ if( (msg.item.nameid < 1 || msg.item.amount < 1) && msg.zeny < 1 )
+ return; // No Attachment
- if (!mail_DeleteAttach(mail_id))
- return;
+ if( !mail_DeleteAttach(mail_id) )
+ return;
- WFIFOHEAD(fd, sizeof(struct item) + 12);
- WFIFOW(fd,0) = 0x384a;
- WFIFOW(fd,2) = sizeof(struct item) + 12;
- WFIFOL(fd,4) = char_id;
- WFIFOL(fd,8) = (msg.zeny > 0)?msg.zeny:0;
- memcpy(WFIFOP(fd,12), &msg.item, sizeof(struct item));
- WFIFOSET(fd,WFIFOW(fd,2));
+ WFIFOHEAD(fd, sizeof(struct item) + 12);
+ WFIFOW(fd,0) = 0x384a;
+ WFIFOW(fd,2) = sizeof(struct item) + 12;
+ WFIFOL(fd,4) = char_id;
+ WFIFOL(fd,8) = (msg.zeny > 0)?msg.zeny:0;
+ memcpy(WFIFOP(fd,12), &msg.item, sizeof(struct item));
+ WFIFOSET(fd,WFIFOW(fd,2));
}
static void mapif_parse_Mail_getattach(int fd)
{
- mapif_Mail_getattach(fd, RFIFOL(fd,2), RFIFOL(fd,6));
+ mapif_Mail_getattach(fd, RFIFOL(fd,2), RFIFOL(fd,6));
}
/*==========================================
@@ -307,23 +288,24 @@ static void mapif_parse_Mail_getattach(int fd)
*------------------------------------------*/
static void mapif_Mail_delete(int fd, int char_id, int mail_id)
{
- bool failed = false;
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `id` = '%d'", mail_db, mail_id)) {
- Sql_ShowDebug(sql_handle);
- failed = true;
- }
-
- WFIFOHEAD(fd,11);
- WFIFOW(fd,0) = 0x384b;
- WFIFOL(fd,2) = char_id;
- WFIFOL(fd,6) = mail_id;
- WFIFOB(fd,10) = failed;
- WFIFOSET(fd,11);
+ bool failed = false;
+ if ( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `id` = '%d'", mail_db, mail_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ failed = true;
+ }
+
+ WFIFOHEAD(fd,11);
+ WFIFOW(fd,0) = 0x384b;
+ WFIFOL(fd,2) = char_id;
+ WFIFOL(fd,6) = mail_id;
+ WFIFOB(fd,10) = failed;
+ WFIFOSET(fd,11);
}
static void mapif_parse_Mail_delete(int fd)
{
- mapif_Mail_delete(fd, RFIFOL(fd,2), RFIFOL(fd,6));
+ mapif_Mail_delete(fd, RFIFOL(fd,2), RFIFOL(fd,6));
}
/*==========================================
@@ -331,17 +313,17 @@ static void mapif_parse_Mail_delete(int fd)
*------------------------------------------*/
void mapif_Mail_new(struct mail_message *msg)
{
- unsigned char buf[74];
-
- if (!msg || !msg->id)
- return;
-
- WBUFW(buf,0) = 0x3849;
- WBUFL(buf,2) = msg->dest_id;
- WBUFL(buf,6) = msg->id;
- memcpy(WBUFP(buf,10), msg->send_name, NAME_LENGTH);
- memcpy(WBUFP(buf,34), msg->title, MAIL_TITLE_LENGTH);
- mapif_sendall(buf, 74);
+ unsigned char buf[74];
+
+ if( !msg || !msg->id )
+ return;
+
+ WBUFW(buf,0) = 0x3849;
+ WBUFL(buf,2) = msg->dest_id;
+ WBUFL(buf,6) = msg->id;
+ memcpy(WBUFP(buf,10), msg->send_name, NAME_LENGTH);
+ memcpy(WBUFP(buf,34), msg->title, MAIL_TITLE_LENGTH);
+ mapif_sendall(buf, 74);
}
/*==========================================
@@ -349,116 +331,120 @@ void mapif_Mail_new(struct mail_message *msg)
*------------------------------------------*/
static void mapif_Mail_return(int fd, int char_id, int mail_id)
{
- struct mail_message msg;
- int new_mail = 0;
-
- if (mail_loadmessage(mail_id, &msg)) {
- if (msg.dest_id != char_id)
- return;
- else if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `id` = '%d'", mail_db, mail_id))
- Sql_ShowDebug(sql_handle);
- else {
- char temp_[MAIL_TITLE_LENGTH];
-
- // swap sender and receiver
- swap(msg.send_id, msg.dest_id);
- safestrncpy(temp_, msg.send_name, NAME_LENGTH);
- safestrncpy(msg.send_name, msg.dest_name, NAME_LENGTH);
- safestrncpy(msg.dest_name, temp_, NAME_LENGTH);
-
- // set reply message title
- snprintf(temp_, MAIL_TITLE_LENGTH, "RE:%s", msg.title);
- safestrncpy(msg.title, temp_, MAIL_TITLE_LENGTH);
-
- msg.status = MAIL_NEW;
- msg.timestamp = time(NULL);
-
- new_mail = mail_savemessage(&msg);
- mapif_Mail_new(&msg);
- }
- }
-
- WFIFOHEAD(fd,11);
- WFIFOW(fd,0) = 0x384c;
- WFIFOL(fd,2) = char_id;
- WFIFOL(fd,6) = mail_id;
- WFIFOB(fd,10) = (new_mail == 0);
- WFIFOSET(fd,11);
+ struct mail_message msg;
+ int new_mail = 0;
+
+ if( mail_loadmessage(mail_id, &msg) )
+ {
+ if( msg.dest_id != char_id)
+ return;
+ else if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `id` = '%d'", mail_db, mail_id) )
+ Sql_ShowDebug(sql_handle);
+ else
+ {
+ char temp_[MAIL_TITLE_LENGTH];
+
+ // swap sender and receiver
+ swap(msg.send_id, msg.dest_id);
+ safestrncpy(temp_, msg.send_name, NAME_LENGTH);
+ safestrncpy(msg.send_name, msg.dest_name, NAME_LENGTH);
+ safestrncpy(msg.dest_name, temp_, NAME_LENGTH);
+
+ // set reply message title
+ snprintf(temp_, MAIL_TITLE_LENGTH, "RE:%s", msg.title);
+ safestrncpy(msg.title, temp_, MAIL_TITLE_LENGTH);
+
+ msg.status = MAIL_NEW;
+ msg.timestamp = time(NULL);
+
+ new_mail = mail_savemessage(&msg);
+ mapif_Mail_new(&msg);
+ }
+ }
+
+ WFIFOHEAD(fd,11);
+ WFIFOW(fd,0) = 0x384c;
+ WFIFOL(fd,2) = char_id;
+ WFIFOL(fd,6) = mail_id;
+ WFIFOB(fd,10) = (new_mail == 0);
+ WFIFOSET(fd,11);
}
static void mapif_parse_Mail_return(int fd)
{
- mapif_Mail_return(fd, RFIFOL(fd,2), RFIFOL(fd,6));
+ mapif_Mail_return(fd, RFIFOL(fd,2), RFIFOL(fd,6));
}
/*==========================================
* Send Mail
*------------------------------------------*/
-static void mapif_Mail_send(int fd, struct mail_message *msg)
+static void mapif_Mail_send(int fd, struct mail_message* msg)
{
- int len = sizeof(struct mail_message) + 4;
-
- WFIFOHEAD(fd,len);
- WFIFOW(fd,0) = 0x384d;
- WFIFOW(fd,2) = len;
- memcpy(WFIFOP(fd,4), msg, sizeof(struct mail_message));
- WFIFOSET(fd,len);
+ int len = sizeof(struct mail_message) + 4;
+
+ WFIFOHEAD(fd,len);
+ WFIFOW(fd,0) = 0x384d;
+ WFIFOW(fd,2) = len;
+ memcpy(WFIFOP(fd,4), msg, sizeof(struct mail_message));
+ WFIFOSET(fd,len);
}
static void mapif_parse_Mail_send(int fd)
{
- struct mail_message msg;
- char esc_name[NAME_LENGTH*2+1];
- int account_id = 0;
-
- if (RFIFOW(fd,2) != 8 + sizeof(struct mail_message))
- return;
-
- account_id = RFIFOL(fd,4);
- memcpy(&msg, RFIFOP(fd,8), sizeof(struct mail_message));
-
- // Try to find the Dest Char by Name
- Sql_EscapeStringLen(sql_handle, esc_name, msg.dest_name, strnlen(msg.dest_name, NAME_LENGTH));
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`, `char_id` FROM `%s` WHERE `name` = '%s'", char_db, esc_name))
- Sql_ShowDebug(sql_handle);
- else if (SQL_SUCCESS == Sql_NextRow(sql_handle)) {
- char *data;
- Sql_GetData(sql_handle, 0, &data, NULL);
- if (atoi(data) != account_id) {
- // Cannot send mail to char in the same account
- Sql_GetData(sql_handle, 1, &data, NULL);
- msg.dest_id = atoi(data);
- }
- }
- Sql_FreeResult(sql_handle);
- msg.status = MAIL_NEW;
-
- if (msg.dest_id > 0)
- msg.id = mail_savemessage(&msg);
-
- mapif_Mail_send(fd, &msg); // notify sender
- mapif_Mail_new(&msg); // notify recipient
+ struct mail_message msg;
+ char esc_name[NAME_LENGTH*2+1];
+ int account_id = 0;
+
+ if(RFIFOW(fd,2) != 8 + sizeof(struct mail_message))
+ return;
+
+ account_id = RFIFOL(fd,4);
+ memcpy(&msg, RFIFOP(fd,8), sizeof(struct mail_message));
+
+ // Try to find the Dest Char by Name
+ Sql_EscapeStringLen(sql_handle, esc_name, msg.dest_name, strnlen(msg.dest_name, NAME_LENGTH));
+ if ( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`, `char_id` FROM `%s` WHERE `name` = '%s'", char_db, esc_name) )
+ Sql_ShowDebug(sql_handle);
+ else
+ if ( SQL_SUCCESS == Sql_NextRow(sql_handle) )
+ {
+ char *data;
+ Sql_GetData(sql_handle, 0, &data, NULL);
+ if (atoi(data) != account_id)
+ { // Cannot send mail to char in the same account
+ Sql_GetData(sql_handle, 1, &data, NULL);
+ msg.dest_id = atoi(data);
+ }
+ }
+ Sql_FreeResult(sql_handle);
+ msg.status = MAIL_NEW;
+
+ if( msg.dest_id > 0 )
+ msg.id = mail_savemessage(&msg);
+
+ mapif_Mail_send(fd, &msg); // notify sender
+ mapif_Mail_new(&msg); // notify recipient
}
-void mail_sendmail(int send_id, const char *send_name, int dest_id, const char *dest_name, const char *title, const char *body, int zeny, struct item *item)
+void mail_sendmail(int send_id, const char* send_name, int dest_id, const char* dest_name, const char* title, const char* body, int zeny, struct item *item)
{
- struct mail_message msg;
- memset(&msg, 0, sizeof(struct mail_message));
-
- msg.send_id = send_id;
- safestrncpy(msg.send_name, send_name, NAME_LENGTH);
- msg.dest_id = dest_id;
- safestrncpy(msg.dest_name, dest_name, NAME_LENGTH);
- safestrncpy(msg.title, title, MAIL_TITLE_LENGTH);
- safestrncpy(msg.body, body, MAIL_BODY_LENGTH);
- msg.zeny = zeny;
- if (item != NULL)
- memcpy(&msg.item, item, sizeof(struct item));
-
- msg.timestamp = time(NULL);
-
- mail_savemessage(&msg);
- mapif_Mail_new(&msg);
+ struct mail_message msg;
+ memset(&msg, 0, sizeof(struct mail_message));
+
+ msg.send_id = send_id;
+ safestrncpy(msg.send_name, send_name, NAME_LENGTH);
+ msg.dest_id = dest_id;
+ safestrncpy(msg.dest_name, dest_name, NAME_LENGTH);
+ safestrncpy(msg.title, title, MAIL_TITLE_LENGTH);
+ safestrncpy(msg.body, body, MAIL_BODY_LENGTH);
+ msg.zeny = zeny;
+ if( item != NULL )
+ memcpy(&msg.item, item, sizeof(struct item));
+
+ msg.timestamp = time(NULL);
+
+ mail_savemessage(&msg);
+ mapif_Mail_new(&msg);
}
/*==========================================
@@ -466,37 +452,26 @@ void mail_sendmail(int send_id, const char *send_name, int dest_id, const char *
*------------------------------------------*/
int inter_mail_parse_frommap(int fd)
{
- switch (RFIFOW(fd,0)) {
- case 0x3048:
- mapif_parse_Mail_requestinbox(fd);
- break;
- case 0x3049:
- mapif_parse_Mail_read(fd);
- break;
- case 0x304a:
- mapif_parse_Mail_getattach(fd);
- break;
- case 0x304b:
- mapif_parse_Mail_delete(fd);
- break;
- case 0x304c:
- mapif_parse_Mail_return(fd);
- break;
- case 0x304d:
- mapif_parse_Mail_send(fd);
- break;
- default:
- return 0;
- }
- return 1;
+ switch(RFIFOW(fd,0))
+ {
+ case 0x3048: mapif_parse_Mail_requestinbox(fd); break;
+ case 0x3049: mapif_parse_Mail_read(fd); break;
+ case 0x304a: mapif_parse_Mail_getattach(fd); break;
+ case 0x304b: mapif_parse_Mail_delete(fd); break;
+ case 0x304c: mapif_parse_Mail_return(fd); break;
+ case 0x304d: mapif_parse_Mail_send(fd); break;
+ default:
+ return 0;
+ }
+ return 1;
}
int inter_mail_sql_init(void)
{
- return 1;
+ return 1;
}
void inter_mail_sql_final(void)
{
- return;
+ return;
}
diff --git a/src/char/int_mail.h b/src/char/int_mail.h
index 0fef3d4ab..77db51e5b 100644
--- a/src/char/int_mail.h
+++ b/src/char/int_mail.h
@@ -5,12 +5,12 @@
#define _INT_MAIL_SQL_H_
int inter_mail_parse_frommap(int fd);
-void mail_sendmail(int send_id, const char *send_name, int dest_id, const char *dest_name, const char *title, const char *body, int zeny, struct item *item);
+void mail_sendmail(int send_id, const char* send_name, int dest_id, const char* dest_name, const char* title, const char* body, int zeny, struct item *item);
int inter_mail_sql_init(void);
void inter_mail_sql_final(void);
-int mail_savemessage(struct mail_message *msg);
+int mail_savemessage(struct mail_message* msg);
void mapif_Mail_new(struct mail_message *msg);
#endif /* _INT_MAIL_SQL_H_ */
diff --git a/src/char/int_mercenary.c b/src/char/int_mercenary.c
index 528f05524..3b3714416 100644
--- a/src/char/int_mercenary.c
+++ b/src/char/int_mercenary.c
@@ -17,188 +17,185 @@
bool mercenary_owner_fromsql(int char_id, struct mmo_charstatus *status)
{
- char *data;
-
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `merc_id`, `arch_calls`, `arch_faith`, `spear_calls`, `spear_faith`, `sword_calls`, `sword_faith` FROM `%s` WHERE `char_id` = '%d'", mercenary_owner_db, char_id)) {
- Sql_ShowDebug(sql_handle);
- return false;
- }
-
- if (SQL_SUCCESS != Sql_NextRow(sql_handle)) {
- Sql_FreeResult(sql_handle);
- return false;
- }
-
- Sql_GetData(sql_handle, 0, &data, NULL);
- status->mer_id = atoi(data);
- Sql_GetData(sql_handle, 1, &data, NULL);
- status->arch_calls = atoi(data);
- Sql_GetData(sql_handle, 2, &data, NULL);
- status->arch_faith = atoi(data);
- Sql_GetData(sql_handle, 3, &data, NULL);
- status->spear_calls = atoi(data);
- Sql_GetData(sql_handle, 4, &data, NULL);
- status->spear_faith = atoi(data);
- Sql_GetData(sql_handle, 5, &data, NULL);
- status->sword_calls = atoi(data);
- Sql_GetData(sql_handle, 6, &data, NULL);
- status->sword_faith = atoi(data);
- Sql_FreeResult(sql_handle);
-
- return true;
+ char* data;
+
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `merc_id`, `arch_calls`, `arch_faith`, `spear_calls`, `spear_faith`, `sword_calls`, `sword_faith` FROM `%s` WHERE `char_id` = '%d'", mercenary_owner_db, char_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ return false;
+ }
+
+ if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
+ {
+ Sql_FreeResult(sql_handle);
+ return false;
+ }
+
+ Sql_GetData(sql_handle, 0, &data, NULL); status->mer_id = atoi(data);
+ Sql_GetData(sql_handle, 1, &data, NULL); status->arch_calls = atoi(data);
+ Sql_GetData(sql_handle, 2, &data, NULL); status->arch_faith = atoi(data);
+ Sql_GetData(sql_handle, 3, &data, NULL); status->spear_calls = atoi(data);
+ Sql_GetData(sql_handle, 4, &data, NULL); status->spear_faith = atoi(data);
+ Sql_GetData(sql_handle, 5, &data, NULL); status->sword_calls = atoi(data);
+ Sql_GetData(sql_handle, 6, &data, NULL); status->sword_faith = atoi(data);
+ Sql_FreeResult(sql_handle);
+
+ return true;
}
bool mercenary_owner_tosql(int char_id, struct mmo_charstatus *status)
{
- if (SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`char_id`, `merc_id`, `arch_calls`, `arch_faith`, `spear_calls`, `spear_faith`, `sword_calls`, `sword_faith`) VALUES ('%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
- mercenary_owner_db, char_id, status->mer_id, status->arch_calls, status->arch_faith, status->spear_calls, status->spear_faith, status->sword_calls, status->sword_faith)) {
- Sql_ShowDebug(sql_handle);
- return false;
- }
+ if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`char_id`, `merc_id`, `arch_calls`, `arch_faith`, `spear_calls`, `spear_faith`, `sword_calls`, `sword_faith`) VALUES ('%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
+ mercenary_owner_db, char_id, status->mer_id, status->arch_calls, status->arch_faith, status->spear_calls, status->spear_faith, status->sword_calls, status->sword_faith) )
+ {
+ Sql_ShowDebug(sql_handle);
+ return false;
+ }
- return true;
+ return true;
}
bool mercenary_owner_delete(int char_id)
{
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id` = '%d'", mercenary_owner_db, char_id))
- Sql_ShowDebug(sql_handle);
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id` = '%d'", mercenary_owner_db, char_id) )
+ Sql_ShowDebug(sql_handle);
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id` = '%d'", mercenary_db, char_id))
- Sql_ShowDebug(sql_handle);
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id` = '%d'", mercenary_db, char_id) )
+ Sql_ShowDebug(sql_handle);
- return true;
+ return true;
}
-bool mapif_mercenary_save(struct s_mercenary *merc)
+bool mapif_mercenary_save(struct s_mercenary* merc)
{
- bool flag = true;
+ bool flag = true;
- if (merc->mercenary_id == 0) {
- // Create new DB entry
- if (SQL_ERROR == Sql_Query(sql_handle,
- "INSERT INTO `%s` (`char_id`,`class`,`hp`,`sp`,`kill_counter`,`life_time`) VALUES ('%d','%d','%d','%d','%u','%u')",
- mercenary_db, merc->char_id, merc->class_, merc->hp, merc->sp, merc->kill_count, merc->life_time)) {
- Sql_ShowDebug(sql_handle);
- flag = false;
- } else
- merc->mercenary_id = (int)Sql_LastInsertId(sql_handle);
- } else if (SQL_ERROR == Sql_Query(sql_handle,
- "UPDATE `%s` SET `char_id` = '%d', `class` = '%d', `hp` = '%d', `sp` = '%d', `kill_counter` = '%u', `life_time` = '%u' WHERE `mer_id` = '%d'",
- mercenary_db, merc->char_id, merc->class_, merc->hp, merc->sp, merc->kill_count, merc->life_time, merc->mercenary_id)) {
- // Update DB entry
- Sql_ShowDebug(sql_handle);
- flag = false;
- }
+ if( merc->mercenary_id == 0 )
+ { // Create new DB entry
+ if( SQL_ERROR == Sql_Query(sql_handle,
+ "INSERT INTO `%s` (`char_id`,`class`,`hp`,`sp`,`kill_counter`,`life_time`) VALUES ('%d','%d','%d','%d','%u','%u')",
+ mercenary_db, merc->char_id, merc->class_, merc->hp, merc->sp, merc->kill_count, merc->life_time) )
+ {
+ Sql_ShowDebug(sql_handle);
+ flag = false;
+ }
+ else
+ merc->mercenary_id = (int)Sql_LastInsertId(sql_handle);
+ }
+ else if( SQL_ERROR == Sql_Query(sql_handle,
+ "UPDATE `%s` SET `char_id` = '%d', `class` = '%d', `hp` = '%d', `sp` = '%d', `kill_counter` = '%u', `life_time` = '%u' WHERE `mer_id` = '%d'",
+ mercenary_db, merc->char_id, merc->class_, merc->hp, merc->sp, merc->kill_count, merc->life_time, merc->mercenary_id) )
+ { // Update DB entry
+ Sql_ShowDebug(sql_handle);
+ flag = false;
+ }
- return flag;
+ return flag;
}
bool mapif_mercenary_load(int merc_id, int char_id, struct s_mercenary *merc)
{
- char *data;
-
- memset(merc, 0, sizeof(struct s_mercenary));
- merc->mercenary_id = merc_id;
- merc->char_id = char_id;
+ char* data;
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `class`, `hp`, `sp`, `kill_counter`, `life_time` FROM `%s` WHERE `mer_id` = '%d' AND `char_id` = '%d'", mercenary_db, merc_id, char_id)) {
- Sql_ShowDebug(sql_handle);
- return false;
- }
+ memset(merc, 0, sizeof(struct s_mercenary));
+ merc->mercenary_id = merc_id;
+ merc->char_id = char_id;
- if (SQL_SUCCESS != Sql_NextRow(sql_handle)) {
- Sql_FreeResult(sql_handle);
- return false;
- }
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `class`, `hp`, `sp`, `kill_counter`, `life_time` FROM `%s` WHERE `mer_id` = '%d' AND `char_id` = '%d'", mercenary_db, merc_id, char_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ return false;
+ }
- Sql_GetData(sql_handle, 0, &data, NULL);
- merc->class_ = atoi(data);
- Sql_GetData(sql_handle, 1, &data, NULL);
- merc->hp = atoi(data);
- Sql_GetData(sql_handle, 2, &data, NULL);
- merc->sp = atoi(data);
- Sql_GetData(sql_handle, 3, &data, NULL);
- merc->kill_count = atoi(data);
- Sql_GetData(sql_handle, 4, &data, NULL);
- merc->life_time = atoi(data);
- Sql_FreeResult(sql_handle);
- if (save_log)
- ShowInfo("Mercenary loaded (%d - %d).\n", merc->mercenary_id, merc->char_id);
+ if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
+ {
+ Sql_FreeResult(sql_handle);
+ return false;
+ }
- return true;
+ Sql_GetData(sql_handle, 0, &data, NULL); merc->class_ = atoi(data);
+ Sql_GetData(sql_handle, 1, &data, NULL); merc->hp = atoi(data);
+ Sql_GetData(sql_handle, 2, &data, NULL); merc->sp = atoi(data);
+ Sql_GetData(sql_handle, 3, &data, NULL); merc->kill_count = atoi(data);
+ Sql_GetData(sql_handle, 4, &data, NULL); merc->life_time = atoi(data);
+ Sql_FreeResult(sql_handle);
+ if( save_log )
+ ShowInfo("Mercenary loaded (%d - %d).\n", merc->mercenary_id, merc->char_id);
+
+ return true;
}
bool mapif_mercenary_delete(int merc_id)
{
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `mer_id` = '%d'", mercenary_db, merc_id)) {
- Sql_ShowDebug(sql_handle);
- return false;
- }
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `mer_id` = '%d'", mercenary_db, merc_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ return false;
+ }
- return true;
+ return true;
}
static void mapif_mercenary_send(int fd, struct s_mercenary *merc, unsigned char flag)
{
- int size = sizeof(struct s_mercenary) + 5;
+ int size = sizeof(struct s_mercenary) + 5;
- WFIFOHEAD(fd,size);
- WFIFOW(fd,0) = 0x3870;
- WFIFOW(fd,2) = size;
- WFIFOB(fd,4) = flag;
- memcpy(WFIFOP(fd,5),merc,sizeof(struct s_mercenary));
- WFIFOSET(fd,size);
+ WFIFOHEAD(fd,size);
+ WFIFOW(fd,0) = 0x3870;
+ WFIFOW(fd,2) = size;
+ WFIFOB(fd,4) = flag;
+ memcpy(WFIFOP(fd,5),merc,sizeof(struct s_mercenary));
+ WFIFOSET(fd,size);
}
-static void mapif_parse_mercenary_create(int fd, struct s_mercenary *merc)
+static void mapif_parse_mercenary_create(int fd, struct s_mercenary* merc)
{
- bool result = mapif_mercenary_save(merc);
- mapif_mercenary_send(fd, merc, result);
+ bool result = mapif_mercenary_save(merc);
+ mapif_mercenary_send(fd, merc, result);
}
static void mapif_parse_mercenary_load(int fd, int merc_id, int char_id)
{
- struct s_mercenary merc;
- bool result = mapif_mercenary_load(merc_id, char_id, &merc);
- mapif_mercenary_send(fd, &merc, result);
+ struct s_mercenary merc;
+ bool result = mapif_mercenary_load(merc_id, char_id, &merc);
+ mapif_mercenary_send(fd, &merc, result);
}
static void mapif_mercenary_deleted(int fd, unsigned char flag)
{
- WFIFOHEAD(fd,3);
- WFIFOW(fd,0) = 0x3871;
- WFIFOB(fd,2) = flag;
- WFIFOSET(fd,3);
+ WFIFOHEAD(fd,3);
+ WFIFOW(fd,0) = 0x3871;
+ WFIFOB(fd,2) = flag;
+ WFIFOSET(fd,3);
}
static void mapif_parse_mercenary_delete(int fd, int merc_id)
{
- bool result = mapif_mercenary_delete(merc_id);
- mapif_mercenary_deleted(fd, result);
+ bool result = mapif_mercenary_delete(merc_id);
+ mapif_mercenary_deleted(fd, result);
}
static void mapif_mercenary_saved(int fd, unsigned char flag)
{
- WFIFOHEAD(fd,3);
- WFIFOW(fd,0) = 0x3872;
- WFIFOB(fd,2) = flag;
- WFIFOSET(fd,3);
+ WFIFOHEAD(fd,3);
+ WFIFOW(fd,0) = 0x3872;
+ WFIFOB(fd,2) = flag;
+ WFIFOSET(fd,3);
}
-static void mapif_parse_mercenary_save(int fd, struct s_mercenary *merc)
+static void mapif_parse_mercenary_save(int fd, struct s_mercenary* merc)
{
- bool result = mapif_mercenary_save(merc);
- mapif_mercenary_saved(fd, result);
+ bool result = mapif_mercenary_save(merc);
+ mapif_mercenary_saved(fd, result);
}
int inter_mercenary_sql_init(void)
{
- return 0;
+ return 0;
}
void inter_mercenary_sql_final(void)
{
- return;
+ return;
}
/*==========================================
@@ -206,23 +203,16 @@ void inter_mercenary_sql_final(void)
*------------------------------------------*/
int inter_mercenary_parse_frommap(int fd)
{
- unsigned short cmd = RFIFOW(fd,0);
-
- switch (cmd) {
- case 0x3070:
- mapif_parse_mercenary_create(fd, (struct s_mercenary *)RFIFOP(fd,4));
- break;
- case 0x3071:
- mapif_parse_mercenary_load(fd, (int)RFIFOL(fd,2), (int)RFIFOL(fd,6));
- break;
- case 0x3072:
- mapif_parse_mercenary_delete(fd, (int)RFIFOL(fd,2));
- break;
- case 0x3073:
- mapif_parse_mercenary_save(fd, (struct s_mercenary *)RFIFOP(fd,4));
- break;
- default:
- return 0;
- }
- return 1;
+ unsigned short cmd = RFIFOW(fd,0);
+
+ switch( cmd )
+ {
+ case 0x3070: mapif_parse_mercenary_create(fd, (struct s_mercenary*)RFIFOP(fd,4)); break;
+ case 0x3071: mapif_parse_mercenary_load(fd, (int)RFIFOL(fd,2), (int)RFIFOL(fd,6)); break;
+ case 0x3072: mapif_parse_mercenary_delete(fd, (int)RFIFOL(fd,2)); break;
+ case 0x3073: mapif_parse_mercenary_save(fd, (struct s_mercenary*)RFIFOP(fd,4)); break;
+ default:
+ return 0;
+ }
+ return 1;
}
diff --git a/src/char/int_party.c b/src/char/int_party.c
index 862a943f1..a88e5c586 100644
--- a/src/char/int_party.c
+++ b/src/char/int_party.c
@@ -19,14 +19,14 @@
#include <string.h>
struct party_data {
- struct party party;
- unsigned int min_lv, max_lv;
- int family; //Is this party a family? if so, this holds the child id.
- unsigned char size; //Total size of party.
+ struct party party;
+ unsigned int min_lv, max_lv;
+ int family; //Is this party a family? if so, this holds the child id.
+ unsigned char size; //Total size of party.
};
static struct party_data *party_pt;
-static DBMap *party_db_; // int party_id -> struct party_data*
+static DBMap* party_db_; // int party_id -> struct party_data*
int mapif_party_broken(int party_id,int flag);
int party_check_empty(struct party_data *p);
@@ -35,297 +35,292 @@ int party_check_exp_share(struct party_data *p);
int mapif_party_optionchanged(int fd,struct party *p, int account_id, int flag);
//Updates party's level range and unsets even share if broken.
-static int int_party_check_lv(struct party_data *p)
-{
- int i;
- unsigned int lv;
- p->min_lv = UINT_MAX;
- p->max_lv = 0;
- for (i=0; i<MAX_PARTY; i++) {
- /**
- * - If not online OR if it's a family party and this is the child (doesn't affect exp range)
- **/
- if (!p->party.member[i].online || p->party.member[i].char_id == p->family)
- continue;
-
- lv=p->party.member[i].lv;
- if (lv < p->min_lv) p->min_lv = lv;
- if (lv > p->max_lv) p->max_lv = lv;
- }
-
- if (p->party.exp && !party_check_exp_share(p)) {
- p->party.exp = 0;
- mapif_party_optionchanged(0, &p->party, 0, 0);
- return 0;
- }
- return 1;
+static int int_party_check_lv(struct party_data *p) {
+ int i;
+ unsigned int lv;
+ p->min_lv = UINT_MAX;
+ p->max_lv = 0;
+ for(i=0;i<MAX_PARTY;i++){
+ /**
+ * - If not online OR if it's a family party and this is the child (doesn't affect exp range)
+ **/
+ if(!p->party.member[i].online || p->party.member[i].char_id == p->family )
+ continue;
+
+ lv=p->party.member[i].lv;
+ if (lv < p->min_lv) p->min_lv = lv;
+ if (lv > p->max_lv) p->max_lv = lv;
+ }
+
+ if (p->party.exp && !party_check_exp_share(p)) {
+ p->party.exp = 0;
+ mapif_party_optionchanged(0, &p->party, 0, 0);
+ return 0;
+ }
+ return 1;
}
//Calculates the state of a party.
static void int_party_calc_state(struct party_data *p)
{
- int i;
- unsigned int lv;
- p->min_lv = UINT_MAX;
- p->max_lv = 0;
- p->party.count =
- p->size =
- p->family = 0;
-
- //Check party size
- for (i=0; i<MAX_PARTY; i++) {
- if (!p->party.member[i].lv) continue;
- p->size++;
- if (p->party.member[i].online)
- p->party.count++;
- }
- if (p->size == 2 && (char_child(p->party.member[0].char_id,p->party.member[1].char_id) || char_child(p->party.member[1].char_id,p->party.member[0].char_id))) {
- //Child should be able to share with either of their parents [RoM]
- if (p->party.member[0].class_&0x2000) //first slot is the child?
- p->family = p->party.member[0].char_id;
- else
- p->family = p->party.member[1].char_id;
- } else if (p->size == 3) {
- //Check Family State.
- p->family = char_family(
- p->party.member[0].char_id,
- p->party.member[1].char_id,
- p->party.member[2].char_id
- );
- }
- //max/min levels.
- for (i=0; i<MAX_PARTY; i++) {
- lv=p->party.member[i].lv;
- if (!lv) continue;
- if (p->party.member[i].online &&
- //On families, the kid is not counted towards exp share rules.
- p->party.member[i].char_id != p->family) {
- if (lv < p->min_lv) p->min_lv=lv;
- if (p->max_lv < lv) p->max_lv=lv;
- }
- }
-
- if (p->party.exp && !party_check_exp_share(p)) {
- p->party.exp = 0; //Set off even share.
- mapif_party_optionchanged(0, &p->party, 0, 0);
- }
- return;
+ int i;
+ unsigned int lv;
+ p->min_lv = UINT_MAX;
+ p->max_lv = 0;
+ p->party.count =
+ p->size =
+ p->family = 0;
+
+ //Check party size
+ for(i=0;i<MAX_PARTY;i++){
+ if (!p->party.member[i].lv) continue;
+ p->size++;
+ if(p->party.member[i].online)
+ p->party.count++;
+ }
+ if( p->size == 2 && ( char_child(p->party.member[0].char_id,p->party.member[1].char_id) || char_child(p->party.member[1].char_id,p->party.member[0].char_id) ) ) {
+ //Child should be able to share with either of their parents [RoM]
+ if(p->party.member[0].class_&0x2000) //first slot is the child?
+ p->family = p->party.member[0].char_id;
+ else
+ p->family = p->party.member[1].char_id;
+ } else if( p->size == 3 ) {
+ //Check Family State.
+ p->family = char_family(
+ p->party.member[0].char_id,
+ p->party.member[1].char_id,
+ p->party.member[2].char_id
+ );
+ }
+ //max/min levels.
+ for(i=0;i<MAX_PARTY;i++){
+ lv=p->party.member[i].lv;
+ if (!lv) continue;
+ if(p->party.member[i].online &&
+ //On families, the kid is not counted towards exp share rules.
+ p->party.member[i].char_id != p->family)
+ {
+ if( lv < p->min_lv ) p->min_lv=lv;
+ if( p->max_lv < lv ) p->max_lv=lv;
+ }
+ }
+
+ if (p->party.exp && !party_check_exp_share(p)) {
+ p->party.exp = 0; //Set off even share.
+ mapif_party_optionchanged(0, &p->party, 0, 0);
+ }
+ return;
}
// Save party to mysql
int inter_party_tosql(struct party *p, int flag, int index)
{
- // 'party' ('party_id','name','exp','item','leader_id','leader_char')
- char esc_name[NAME_LENGTH*2+1];// escaped party name
- int party_id;
+ // 'party' ('party_id','name','exp','item','leader_id','leader_char')
+ char esc_name[NAME_LENGTH*2+1];// escaped party name
+ int party_id;
- if (p == NULL || p->party_id == 0)
- return 0;
- party_id = p->party_id;
+ if( p == NULL || p->party_id == 0 )
+ return 0;
+ party_id = p->party_id;
#ifdef NOISY
- ShowInfo("Save party request ("CL_BOLD"%d"CL_RESET" - %s).\n", party_id, p->name);
+ ShowInfo("Save party request ("CL_BOLD"%d"CL_RESET" - %s).\n", party_id, p->name);
#endif
- Sql_EscapeStringLen(sql_handle, esc_name, p->name, strnlen(p->name, NAME_LENGTH));
-
- if (flag & PS_BREAK) {
- // Break the party
- // we'll skip name-checking and just reset everyone with the same party id [celest]
- if (SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d'", char_db, party_id))
- Sql_ShowDebug(sql_handle);
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `party_id`='%d'", party_db, party_id))
- Sql_ShowDebug(sql_handle);
- //Remove from memory
- idb_remove(party_db_, party_id);
- return 1;
- }
-
- if (flag & PS_CREATE) {
- // Create party
- if (SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` "
- "(`name`, `exp`, `item`, `leader_id`, `leader_char`) "
- "VALUES ('%s', '%d', '%d', '%d', '%d')",
- party_db, esc_name, p->exp, p->item, p->member[index].account_id, p->member[index].char_id)) {
- Sql_ShowDebug(sql_handle);
- return 0;
- }
- party_id = p->party_id = (int)Sql_LastInsertId(sql_handle);
- }
-
- if (flag & PS_BASIC) {
- // Update party info.
- if (SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `name`='%s', `exp`='%d', `item`='%d' WHERE `party_id`='%d'",
- party_db, esc_name, p->exp, p->item, party_id))
- Sql_ShowDebug(sql_handle);
- }
-
- if (flag & PS_LEADER) {
- // Update leader
- if (SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `leader_id`='%d', `leader_char`='%d' WHERE `party_id`='%d'",
- party_db, p->member[index].account_id, p->member[index].char_id, party_id))
- Sql_ShowDebug(sql_handle);
- }
-
- if (flag & PS_ADDMEMBER) {
- // Add one party member.
- if (SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `party_id`='%d' WHERE `account_id`='%d' AND `char_id`='%d'",
- char_db, party_id, p->member[index].account_id, p->member[index].char_id))
- Sql_ShowDebug(sql_handle);
- }
-
- if (flag & PS_DELMEMBER) {
- // Remove one party member.
- if (SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d' AND `account_id`='%d' AND `char_id`='%d'",
- char_db, party_id, p->member[index].account_id, p->member[index].char_id))
- Sql_ShowDebug(sql_handle);
- }
-
- if (save_log)
- ShowInfo("Party Saved (%d - %s)\n", party_id, p->name);
- return 1;
+ Sql_EscapeStringLen(sql_handle, esc_name, p->name, strnlen(p->name, NAME_LENGTH));
+
+ if( flag & PS_BREAK )
+ {// Break the party
+ // we'll skip name-checking and just reset everyone with the same party id [celest]
+ if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d'", char_db, party_id) )
+ Sql_ShowDebug(sql_handle);
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `party_id`='%d'", party_db, party_id) )
+ Sql_ShowDebug(sql_handle);
+ //Remove from memory
+ idb_remove(party_db_, party_id);
+ return 1;
+ }
+
+ if( flag & PS_CREATE )
+ {// Create party
+ if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` "
+ "(`name`, `exp`, `item`, `leader_id`, `leader_char`) "
+ "VALUES ('%s', '%d', '%d', '%d', '%d')",
+ party_db, esc_name, p->exp, p->item, p->member[index].account_id, p->member[index].char_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ return 0;
+ }
+ party_id = p->party_id = (int)Sql_LastInsertId(sql_handle);
+ }
+
+ if( flag & PS_BASIC )
+ {// Update party info.
+ if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `name`='%s', `exp`='%d', `item`='%d' WHERE `party_id`='%d'",
+ party_db, esc_name, p->exp, p->item, party_id) )
+ Sql_ShowDebug(sql_handle);
+ }
+
+ if( flag & PS_LEADER )
+ {// Update leader
+ if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `leader_id`='%d', `leader_char`='%d' WHERE `party_id`='%d'",
+ party_db, p->member[index].account_id, p->member[index].char_id, party_id) )
+ Sql_ShowDebug(sql_handle);
+ }
+
+ if( flag & PS_ADDMEMBER )
+ {// Add one party member.
+ if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `party_id`='%d' WHERE `account_id`='%d' AND `char_id`='%d'",
+ char_db, party_id, p->member[index].account_id, p->member[index].char_id) )
+ Sql_ShowDebug(sql_handle);
+ }
+
+ if( flag & PS_DELMEMBER )
+ {// Remove one party member.
+ if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d' AND `account_id`='%d' AND `char_id`='%d'",
+ char_db, party_id, p->member[index].account_id, p->member[index].char_id) )
+ Sql_ShowDebug(sql_handle);
+ }
+
+ if( save_log )
+ ShowInfo("Party Saved (%d - %s)\n", party_id, p->name);
+ return 1;
}
// Read party from mysql
-struct party_data *inter_party_fromsql(int party_id) {
- int leader_id = 0;
- int leader_char = 0;
- struct party_data *p;
- struct party_member *m;
- char *data;
- size_t len;
- int i;
+struct party_data *inter_party_fromsql(int party_id)
+{
+ int leader_id = 0;
+ int leader_char = 0;
+ struct party_data* p;
+ struct party_member* m;
+ char* data;
+ size_t len;
+ int i;
#ifdef NOISY
- ShowInfo("Load party request ("CL_BOLD"%d"CL_RESET")\n", party_id);
+ ShowInfo("Load party request ("CL_BOLD"%d"CL_RESET")\n", party_id);
#endif
- if (party_id <= 0)
- return NULL;
-
- //Load from memory
- p = (struct party_data *)idb_get(party_db_, party_id);
- if (p != NULL)
- return p;
-
- p = party_pt;
- memset(p, 0, sizeof(struct party_data));
-
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `party_id`, `name`,`exp`,`item`, `leader_id`, `leader_char` FROM `%s` WHERE `party_id`='%d'", party_db, party_id)) {
- Sql_ShowDebug(sql_handle);
- return NULL;
- }
-
- if (SQL_SUCCESS != Sql_NextRow(sql_handle))
- return NULL;
-
- p->party.party_id = party_id;
- Sql_GetData(sql_handle, 1, &data, &len);
- memcpy(p->party.name, data, min(len, NAME_LENGTH));
- Sql_GetData(sql_handle, 2, &data, NULL);
- p->party.exp = (atoi(data) ? 1 : 0);
- Sql_GetData(sql_handle, 3, &data, NULL);
- p->party.item = atoi(data);
- Sql_GetData(sql_handle, 4, &data, NULL);
- leader_id = atoi(data);
- Sql_GetData(sql_handle, 5, &data, NULL);
- leader_char = atoi(data);
- Sql_FreeResult(sql_handle);
-
- // Load members
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`char_id`,`name`,`base_level`,`last_map`,`online`,`class` FROM `%s` WHERE `party_id`='%d'", char_db, party_id)) {
- Sql_ShowDebug(sql_handle);
- return NULL;
- }
- for (i = 0; i < MAX_PARTY && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i) {
- m = &p->party.member[i];
- Sql_GetData(sql_handle, 0, &data, NULL);
- m->account_id = atoi(data);
- Sql_GetData(sql_handle, 1, &data, NULL);
- m->char_id = atoi(data);
- Sql_GetData(sql_handle, 2, &data, &len);
- memcpy(m->name, data, min(len, NAME_LENGTH));
- Sql_GetData(sql_handle, 3, &data, NULL);
- m->lv = atoi(data);
- Sql_GetData(sql_handle, 4, &data, NULL);
- m->map = mapindex_name2id(data);
- Sql_GetData(sql_handle, 5, &data, NULL);
- m->online = (atoi(data) ? 1 : 0);
- Sql_GetData(sql_handle, 6, &data, NULL);
- m->class_ = atoi(data);
- m->leader = (m->account_id == leader_id && m->char_id == leader_char ? 1 : 0);
- }
- Sql_FreeResult(sql_handle);
-
- if (save_log)
- ShowInfo("Party loaded (%d - %s).\n", party_id, p->party.name);
- //Add party to memory.
- CREATE(p, struct party_data, 1);
- memcpy(p, party_pt, sizeof(struct party_data));
- //init state
- int_party_calc_state(p);
- idb_put(party_db_, party_id, p);
- return p;
+ if( party_id <= 0 )
+ return NULL;
+
+ //Load from memory
+ p = (struct party_data*)idb_get(party_db_, party_id);
+ if( p != NULL )
+ return p;
+
+ p = party_pt;
+ memset(p, 0, sizeof(struct party_data));
+
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `party_id`, `name`,`exp`,`item`, `leader_id`, `leader_char` FROM `%s` WHERE `party_id`='%d'", party_db, party_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ return NULL;
+ }
+
+ if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
+ return NULL;
+
+ p->party.party_id = party_id;
+ Sql_GetData(sql_handle, 1, &data, &len); memcpy(p->party.name, data, min(len, NAME_LENGTH));
+ Sql_GetData(sql_handle, 2, &data, NULL); p->party.exp = (atoi(data) ? 1 : 0);
+ Sql_GetData(sql_handle, 3, &data, NULL); p->party.item = atoi(data);
+ Sql_GetData(sql_handle, 4, &data, NULL); leader_id = atoi(data);
+ Sql_GetData(sql_handle, 5, &data, NULL); leader_char = atoi(data);
+ Sql_FreeResult(sql_handle);
+
+ // Load members
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`char_id`,`name`,`base_level`,`last_map`,`online`,`class` FROM `%s` WHERE `party_id`='%d'", char_db, party_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ return NULL;
+ }
+ for( i = 0; i < MAX_PARTY && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
+ {
+ m = &p->party.member[i];
+ Sql_GetData(sql_handle, 0, &data, NULL); m->account_id = atoi(data);
+ Sql_GetData(sql_handle, 1, &data, NULL); m->char_id = atoi(data);
+ Sql_GetData(sql_handle, 2, &data, &len); memcpy(m->name, data, min(len, NAME_LENGTH));
+ Sql_GetData(sql_handle, 3, &data, NULL); m->lv = atoi(data);
+ Sql_GetData(sql_handle, 4, &data, NULL); m->map = mapindex_name2id(data);
+ Sql_GetData(sql_handle, 5, &data, NULL); m->online = (atoi(data) ? 1 : 0);
+ Sql_GetData(sql_handle, 6, &data, NULL); m->class_ = atoi(data);
+ m->leader = (m->account_id == leader_id && m->char_id == leader_char ? 1 : 0);
+ }
+ Sql_FreeResult(sql_handle);
+
+ if( save_log )
+ ShowInfo("Party loaded (%d - %s).\n", party_id, p->party.name);
+ //Add party to memory.
+ CREATE(p, struct party_data, 1);
+ memcpy(p, party_pt, sizeof(struct party_data));
+ //init state
+ int_party_calc_state(p);
+ idb_put(party_db_, party_id, p);
+ return p;
}
int inter_party_sql_init(void)
{
- //memory alloc
- party_db_ = idb_alloc(DB_OPT_RELEASE_DATA);
- party_pt = (struct party_data *)aCalloc(sizeof(struct party_data), 1);
- if (!party_pt) {
- ShowFatalError("inter_party_sql_init: Out of Memory!\n");
- exit(EXIT_FAILURE);
- }
-
- /* Uncomment the following if you want to do a party_db cleanup (remove parties with no members) on startup.[Skotlex]
- ShowStatus("cleaning party table...\n");
- if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` USING `%s` LEFT JOIN `%s` ON `%s`.leader_id =`%s`.account_id AND `%s`.leader_char = `%s`.char_id WHERE `%s`.account_id IS NULL",
- party_db, party_db, char_db, party_db, char_db, party_db, char_db, char_db) )
- Sql_ShowDebug(sql_handle);
- */
- return 0;
+ //memory alloc
+ party_db_ = idb_alloc(DB_OPT_RELEASE_DATA);
+ party_pt = (struct party_data*)aCalloc(sizeof(struct party_data), 1);
+ if (!party_pt) {
+ ShowFatalError("inter_party_sql_init: Out of Memory!\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Uncomment the following if you want to do a party_db cleanup (remove parties with no members) on startup.[Skotlex]
+ ShowStatus("cleaning party table...\n");
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` USING `%s` LEFT JOIN `%s` ON `%s`.leader_id =`%s`.account_id AND `%s`.leader_char = `%s`.char_id WHERE `%s`.account_id IS NULL",
+ party_db, party_db, char_db, party_db, char_db, party_db, char_db, char_db) )
+ Sql_ShowDebug(sql_handle);
+ */
+ return 0;
}
void inter_party_sql_final(void)
{
- party_db_->destroy(party_db_, NULL);
- aFree(party_pt);
- return;
+ party_db_->destroy(party_db_, NULL);
+ aFree(party_pt);
+ return;
}
// Search for the party according to its name
-struct party_data *search_partyname(char *str) {
- char esc_name[NAME_LENGTH*2+1];
- char *data;
- struct party_data *p = NULL;
-
- Sql_EscapeStringLen(sql_handle, esc_name, str, safestrnlen(str, NAME_LENGTH));
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `party_id` FROM `%s` WHERE `name`='%s'", party_db, esc_name))
- Sql_ShowDebug(sql_handle);
- else if (SQL_SUCCESS == Sql_NextRow(sql_handle)) {
- Sql_GetData(sql_handle, 0, &data, NULL);
- p = inter_party_fromsql(atoi(data));
- }
- Sql_FreeResult(sql_handle);
-
- return p;
+struct party_data* search_partyname(char* str)
+{
+ char esc_name[NAME_LENGTH*2+1];
+ char* data;
+ struct party_data* p = NULL;
+
+ Sql_EscapeStringLen(sql_handle, esc_name, str, safestrnlen(str, NAME_LENGTH));
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `party_id` FROM `%s` WHERE `name`='%s'", party_db, esc_name) )
+ Sql_ShowDebug(sql_handle);
+ else if( SQL_SUCCESS == Sql_NextRow(sql_handle) )
+ {
+ Sql_GetData(sql_handle, 0, &data, NULL);
+ p = inter_party_fromsql(atoi(data));
+ }
+ Sql_FreeResult(sql_handle);
+
+ return p;
}
// Returns whether this party can keep having exp share or not.
int party_check_exp_share(struct party_data *p)
{
- return (p->party.count < 2 || p->max_lv - p->min_lv <= party_share_level);
+ return (p->party.count < 2 || p->max_lv - p->min_lv <= party_share_level);
}
// Is there any member in the party?
int party_check_empty(struct party_data *p)
{
- int i;
- if (p==NULL||p->party.party_id==0) return 1;
- for (i=0; i<MAX_PARTY && !p->party.member[i].account_id; i++);
- if (i < MAX_PARTY) return 0;
- // If there is no member, then break the party
- mapif_party_broken(p->party.party_id,0);
- inter_party_tosql(&p->party, PS_BREAK, 0);
- return 1;
+ int i;
+ if (p==NULL||p->party.party_id==0) return 1;
+ for(i=0;i<MAX_PARTY && !p->party.member[i].account_id;i++);
+ if (i < MAX_PARTY) return 0;
+ // If there is no member, then break the party
+ mapif_party_broken(p->party.party_id,0);
+ inter_party_tosql(&p->party, PS_BREAK, 0);
+ return 1;
}
//-------------------------------------------------------------------
@@ -335,135 +330,133 @@ int party_check_empty(struct party_data *p)
// Create a party whether or not
int mapif_party_created(int fd,int account_id,int char_id,struct party *p)
{
- WFIFOHEAD(fd, 39);
- WFIFOW(fd,0)=0x3820;
- WFIFOL(fd,2)=account_id;
- WFIFOL(fd,6)=char_id;
- if (p!=NULL) {
- WFIFOB(fd,10)=0;
- WFIFOL(fd,11)=p->party_id;
- memcpy(WFIFOP(fd,15),p->name,NAME_LENGTH);
- ShowInfo("int_party: Party created (%d - %s)\n",p->party_id,p->name);
- } else {
- WFIFOB(fd,10)=1;
- WFIFOL(fd,11)=0;
- memset(WFIFOP(fd,15),0,NAME_LENGTH);
- }
- WFIFOSET(fd,39);
-
- return 0;
+ WFIFOHEAD(fd, 39);
+ WFIFOW(fd,0)=0x3820;
+ WFIFOL(fd,2)=account_id;
+ WFIFOL(fd,6)=char_id;
+ if(p!=NULL){
+ WFIFOB(fd,10)=0;
+ WFIFOL(fd,11)=p->party_id;
+ memcpy(WFIFOP(fd,15),p->name,NAME_LENGTH);
+ ShowInfo("int_party: Party created (%d - %s)\n",p->party_id,p->name);
+ }else{
+ WFIFOB(fd,10)=1;
+ WFIFOL(fd,11)=0;
+ memset(WFIFOP(fd,15),0,NAME_LENGTH);
+ }
+ WFIFOSET(fd,39);
+
+ return 0;
}
//Party information not found
static void mapif_party_noinfo(int fd, int party_id, int char_id)
{
- WFIFOHEAD(fd, 12);
- WFIFOW(fd,0) = 0x3821;
- WFIFOW(fd,2) = 12;
- WFIFOL(fd,4) = char_id;
- WFIFOL(fd,8) = party_id;
- WFIFOSET(fd,12);
- ShowWarning("int_party: info not found (party_id=%d char_id=%d)\n", party_id, char_id);
+ WFIFOHEAD(fd, 12);
+ WFIFOW(fd,0) = 0x3821;
+ WFIFOW(fd,2) = 12;
+ WFIFOL(fd,4) = char_id;
+ WFIFOL(fd,8) = party_id;
+ WFIFOSET(fd,12);
+ ShowWarning("int_party: info not found (party_id=%d char_id=%d)\n", party_id, char_id);
}
//Digest party information
-static void mapif_party_info(int fd, struct party *p, int char_id)
+static void mapif_party_info(int fd, struct party* p, int char_id)
{
- unsigned char buf[8 + sizeof(struct party)];
- WBUFW(buf,0) = 0x3821;
- WBUFW(buf,2) = 8 + sizeof(struct party);
- WBUFL(buf,4) = char_id;
- memcpy(WBUFP(buf,8), p, sizeof(struct party));
-
- if (fd<0)
- mapif_sendall(buf,WBUFW(buf,2));
- else
- mapif_send(fd,buf,WBUFW(buf,2));
+ unsigned char buf[8 + sizeof(struct party)];
+ WBUFW(buf,0) = 0x3821;
+ WBUFW(buf,2) = 8 + sizeof(struct party);
+ WBUFL(buf,4) = char_id;
+ memcpy(WBUFP(buf,8), p, sizeof(struct party));
+
+ if(fd<0)
+ mapif_sendall(buf,WBUFW(buf,2));
+ else
+ mapif_send(fd,buf,WBUFW(buf,2));
}
//Whether or not additional party members
-int mapif_party_memberadded(int fd, int party_id, int account_id, int char_id, int flag)
-{
- WFIFOHEAD(fd, 15);
- WFIFOW(fd,0) = 0x3822;
- WFIFOL(fd,2) = party_id;
- WFIFOL(fd,6) = account_id;
- WFIFOL(fd,10) = char_id;
- WFIFOB(fd,14) = flag;
- WFIFOSET(fd,15);
-
- return 0;
+int mapif_party_memberadded(int fd, int party_id, int account_id, int char_id, int flag) {
+ WFIFOHEAD(fd, 15);
+ WFIFOW(fd,0) = 0x3822;
+ WFIFOL(fd,2) = party_id;
+ WFIFOL(fd,6) = account_id;
+ WFIFOL(fd,10) = char_id;
+ WFIFOB(fd,14) = flag;
+ WFIFOSET(fd,15);
+
+ return 0;
}
// Party setting change notification
int mapif_party_optionchanged(int fd,struct party *p,int account_id,int flag)
{
- unsigned char buf[16];
- WBUFW(buf,0)=0x3823;
- WBUFL(buf,2)=p->party_id;
- WBUFL(buf,6)=account_id;
- WBUFW(buf,10)=p->exp;
- WBUFW(buf,12)=p->item;
- WBUFB(buf,14)=flag;
- if (flag==0)
- mapif_sendall(buf,15);
- else
- mapif_send(fd,buf,15);
- return 0;
+ unsigned char buf[16];
+ WBUFW(buf,0)=0x3823;
+ WBUFL(buf,2)=p->party_id;
+ WBUFL(buf,6)=account_id;
+ WBUFW(buf,10)=p->exp;
+ WBUFW(buf,12)=p->item;
+ WBUFB(buf,14)=flag;
+ if(flag==0)
+ mapif_sendall(buf,15);
+ else
+ mapif_send(fd,buf,15);
+ return 0;
}
//Withdrawal notification party
-int mapif_party_withdraw(int party_id,int account_id, int char_id)
-{
- unsigned char buf[16];
-
- WBUFW(buf,0) = 0x3824;
- WBUFL(buf,2) = party_id;
- WBUFL(buf,6) = account_id;
- WBUFL(buf,10) = char_id;
- mapif_sendall(buf, 14);
- return 0;
+int mapif_party_withdraw(int party_id,int account_id, int char_id) {
+ unsigned char buf[16];
+
+ WBUFW(buf,0) = 0x3824;
+ WBUFL(buf,2) = party_id;
+ WBUFL(buf,6) = account_id;
+ WBUFL(buf,10) = char_id;
+ mapif_sendall(buf, 14);
+ return 0;
}
//Party map update notification
int mapif_party_membermoved(struct party *p,int idx)
{
- unsigned char buf[20];
-
- WBUFW(buf,0) = 0x3825;
- WBUFL(buf,2) = p->party_id;
- WBUFL(buf,6) = p->member[idx].account_id;
- WBUFL(buf,10) = p->member[idx].char_id;
- WBUFW(buf,14) = p->member[idx].map;
- WBUFB(buf,16) = p->member[idx].online;
- WBUFW(buf,17) = p->member[idx].lv;
- mapif_sendall(buf, 19);
- return 0;
+ unsigned char buf[20];
+
+ WBUFW(buf,0) = 0x3825;
+ WBUFL(buf,2) = p->party_id;
+ WBUFL(buf,6) = p->member[idx].account_id;
+ WBUFL(buf,10) = p->member[idx].char_id;
+ WBUFW(buf,14) = p->member[idx].map;
+ WBUFB(buf,16) = p->member[idx].online;
+ WBUFW(buf,17) = p->member[idx].lv;
+ mapif_sendall(buf, 19);
+ return 0;
}
//Dissolution party notification
int mapif_party_broken(int party_id,int flag)
{
- unsigned char buf[16];
- WBUFW(buf,0)=0x3826;
- WBUFL(buf,2)=party_id;
- WBUFB(buf,6)=flag;
- mapif_sendall(buf,7);
- //printf("int_party: broken %d\n",party_id);
- return 0;
+ unsigned char buf[16];
+ WBUFW(buf,0)=0x3826;
+ WBUFL(buf,2)=party_id;
+ WBUFB(buf,6)=flag;
+ mapif_sendall(buf,7);
+ //printf("int_party: broken %d\n",party_id);
+ return 0;
}
//Remarks in the party
int mapif_party_message(int party_id,int account_id,char *mes,int len, int sfd)
{
- unsigned char buf[512];
- 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_sendallwos(sfd, buf,len+12);
- return 0;
+ unsigned char buf[512];
+ 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_sendallwos(sfd, buf,len+12);
+ return 0;
}
//-------------------------------------------------------------------
@@ -473,267 +466,273 @@ int mapif_party_message(int party_id,int account_id,char *mes,int len, int sfd)
// Create Party
int mapif_parse_CreateParty(int fd, char *name, int item, int item2, struct party_member *leader)
{
- struct party_data *p;
- int i;
- if ((p=search_partyname(name))!=NULL) {
- mapif_party_created(fd,leader->account_id,leader->char_id,NULL);
- return 0;
- }
- // 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 < NAME_LENGTH && name[i]; i++)
- if (strchr(char_name_letters, name[i]) == NULL) {
- mapif_party_created(fd,leader->account_id,leader->char_id,NULL);
- return 0;
- }
- } else if (char_name_option == 2) { // letters/symbols in char_name_letters are forbidden
- for (i = 0; i < NAME_LENGTH && name[i]; i++)
- if (strchr(char_name_letters, name[i]) != NULL) {
- mapif_party_created(fd,leader->account_id,leader->char_id,NULL);
- return 0;
- }
- }
-
- p = (struct party_data *)aCalloc(1, sizeof(struct party_data));
-
- memcpy(p->party.name,name,NAME_LENGTH);
- p->party.exp=0;
- p->party.item=(item?1:0)|(item2?2:0);
-
- memcpy(&p->party.member[0], leader, sizeof(struct party_member));
- p->party.member[0].leader=1;
- p->party.member[0].online=1;
-
- p->party.party_id=-1;//New party.
- if (inter_party_tosql(&p->party,PS_CREATE|PS_ADDMEMBER,0)) {
- //Add party to db
- int_party_calc_state(p);
- idb_put(party_db_, p->party.party_id, p);
- mapif_party_info(fd, &p->party, 0);
- mapif_party_created(fd,leader->account_id,leader->char_id,&p->party);
- } else { //Failed to create party.
- aFree(p);
- mapif_party_created(fd,leader->account_id,leader->char_id,NULL);
- }
-
- return 0;
+ struct party_data *p;
+ int i;
+ if( (p=search_partyname(name))!=NULL){
+ mapif_party_created(fd,leader->account_id,leader->char_id,NULL);
+ return 0;
+ }
+ // 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 < NAME_LENGTH && name[i]; i++)
+ if (strchr(char_name_letters, name[i]) == NULL) {
+ mapif_party_created(fd,leader->account_id,leader->char_id,NULL);
+ return 0;
+ }
+ } else if (char_name_option == 2) { // letters/symbols in char_name_letters are forbidden
+ for (i = 0; i < NAME_LENGTH && name[i]; i++)
+ if (strchr(char_name_letters, name[i]) != NULL) {
+ mapif_party_created(fd,leader->account_id,leader->char_id,NULL);
+ return 0;
+ }
+ }
+
+ p = (struct party_data*)aCalloc(1, sizeof(struct party_data));
+
+ memcpy(p->party.name,name,NAME_LENGTH);
+ p->party.exp=0;
+ p->party.item=(item?1:0)|(item2?2:0);
+
+ memcpy(&p->party.member[0], leader, sizeof(struct party_member));
+ p->party.member[0].leader=1;
+ p->party.member[0].online=1;
+
+ p->party.party_id=-1;//New party.
+ if (inter_party_tosql(&p->party,PS_CREATE|PS_ADDMEMBER,0)) {
+ //Add party to db
+ int_party_calc_state(p);
+ idb_put(party_db_, p->party.party_id, p);
+ mapif_party_info(fd, &p->party, 0);
+ mapif_party_created(fd,leader->account_id,leader->char_id,&p->party);
+ } else { //Failed to create party.
+ aFree(p);
+ mapif_party_created(fd,leader->account_id,leader->char_id,NULL);
+ }
+
+ return 0;
}
// Party information request
static void mapif_parse_PartyInfo(int fd, int party_id, int char_id)
{
- struct party_data *p;
- p = inter_party_fromsql(party_id);
+ struct party_data *p;
+ p = inter_party_fromsql(party_id);
- if (p)
- mapif_party_info(fd, &p->party, char_id);
- else
- mapif_party_noinfo(fd, party_id, char_id);
+ if (p)
+ mapif_party_info(fd, &p->party, char_id);
+ else
+ mapif_party_noinfo(fd, party_id, char_id);
}
// Add a player to party request
int mapif_parse_PartyAddMember(int fd, int party_id, struct party_member *member)
{
- struct party_data *p;
- int i;
-
- p = inter_party_fromsql(party_id);
- if (p == NULL || p->size == MAX_PARTY) {
- mapif_party_memberadded(fd, party_id, member->account_id, member->char_id, 1);
- return 0;
- }
-
- ARR_FIND(0, MAX_PARTY, i, p->party.member[i].account_id == 0);
- if (i == MAX_PARTY) {
- // Party full
- mapif_party_memberadded(fd, party_id, member->account_id, member->char_id, 1);
- return 0;
- }
-
- memcpy(&p->party.member[i], member, sizeof(struct party_member));
- p->party.member[i].leader = 0;
- if (p->party.member[i].online) p->party.count++;
- p->size++;
- if (p->size == 2 || p->size == 3) // Check family state. And also accept either of their Parents. [RoM]
- int_party_calc_state(p);
- else //Check even share range.
- if (member->lv < p->min_lv || member->lv > p->max_lv || p->family) {
- if (p->family) p->family = 0; //Family state broken.
- int_party_check_lv(p);
- }
-
- mapif_party_info(-1, &p->party, 0);
- mapif_party_memberadded(fd, party_id, member->account_id, member->char_id, 0);
- inter_party_tosql(&p->party, PS_ADDMEMBER, i);
-
- return 0;
+ struct party_data *p;
+ int i;
+
+ p = inter_party_fromsql(party_id);
+ if( p == NULL || p->size == MAX_PARTY ) {
+ mapif_party_memberadded(fd, party_id, member->account_id, member->char_id, 1);
+ return 0;
+ }
+
+ ARR_FIND( 0, MAX_PARTY, i, p->party.member[i].account_id == 0 );
+ if( i == MAX_PARTY )
+ {// Party full
+ mapif_party_memberadded(fd, party_id, member->account_id, member->char_id, 1);
+ return 0;
+ }
+
+ memcpy(&p->party.member[i], member, sizeof(struct party_member));
+ p->party.member[i].leader = 0;
+ if (p->party.member[i].online) p->party.count++;
+ p->size++;
+ if (p->size == 2 || p->size == 3) // Check family state. And also accept either of their Parents. [RoM]
+ int_party_calc_state(p);
+ else //Check even share range.
+ if (member->lv < p->min_lv || member->lv > p->max_lv || p->family) {
+ if (p->family) p->family = 0; //Family state broken.
+ int_party_check_lv(p);
+ }
+
+ mapif_party_info(-1, &p->party, 0);
+ mapif_party_memberadded(fd, party_id, member->account_id, member->char_id, 0);
+ inter_party_tosql(&p->party, PS_ADDMEMBER, i);
+
+ return 0;
}
//Party setting change request
int mapif_parse_PartyChangeOption(int fd,int party_id,int account_id,int exp,int item)
{
- struct party_data *p;
- int flag = 0;
- p = inter_party_fromsql(party_id);
-
- if (!p)
- return 0;
-
- p->party.exp=exp;
- if (exp && !party_check_exp_share(p)) {
- flag|=0x01;
- p->party.exp=0;
- }
- p->party.item = item&0x3; //Filter out invalid values.
- mapif_party_optionchanged(fd,&p->party,account_id,flag);
- inter_party_tosql(&p->party, PS_BASIC, 0);
- return 0;
+ struct party_data *p;
+ int flag = 0;
+ p = inter_party_fromsql(party_id);
+
+ if(!p)
+ return 0;
+
+ p->party.exp=exp;
+ if( exp && !party_check_exp_share(p) ){
+ flag|=0x01;
+ p->party.exp=0;
+ }
+ p->party.item = item&0x3; //Filter out invalid values.
+ mapif_party_optionchanged(fd,&p->party,account_id,flag);
+ inter_party_tosql(&p->party, PS_BASIC, 0);
+ return 0;
}
//Request leave party
int mapif_parse_PartyLeave(int fd, int party_id, int account_id, int char_id)
{
- struct party_data *p;
- int i,j=-1;
-
- p = inter_party_fromsql(party_id);
- if (p == NULL) {
- // Party does not exists?
- if (SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d'", char_db, party_id))
- Sql_ShowDebug(sql_handle);
- return 0;
- }
-
- for (i = 0; i < MAX_PARTY; i++) {
- if (p->party.member[i].account_id == account_id &&
- p->party.member[i].char_id == char_id) {
- break;
- }
- }
- if (i >= MAX_PARTY)
- return 0; //Member not found?
-
- mapif_party_withdraw(party_id, account_id, char_id);
-
- if (p->party.member[i].leader) {
- p->party.member[i].account_id = 0;
- for (j = 0; j < MAX_PARTY; j++) {
- if (!p->party.member[j].account_id)
- continue;
- mapif_party_withdraw(party_id, p->party.member[j].account_id, p->party.member[j].char_id);
- p->party.member[j].account_id = 0;
- }
- //Party gets deleted on the check_empty call below.
- } else {
- inter_party_tosql(&p->party,PS_DELMEMBER,i);
- j = p->party.member[i].lv;
- if (p->party.member[i].online) p->party.count--;
- memset(&p->party.member[i], 0, sizeof(struct party_member));
- p->size--;
- if (j == p->min_lv || j == p->max_lv || p->family) {
- if (p->family) p->family = 0; //Family state broken.
- int_party_check_lv(p);
- }
- }
-
- if (party_check_empty(p) == 0)
- mapif_party_info(-1, &p->party, 0);
- return 0;
+ struct party_data *p;
+ int i,j=-1;
+
+ p = inter_party_fromsql(party_id);
+ if( p == NULL )
+ {// Party does not exists?
+ if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d'", char_db, party_id) )
+ Sql_ShowDebug(sql_handle);
+ return 0;
+ }
+
+ for (i = 0; i < MAX_PARTY; i++) {
+ if(p->party.member[i].account_id == account_id &&
+ p->party.member[i].char_id == char_id) {
+ break;
+ }
+ }
+ if (i >= MAX_PARTY)
+ return 0; //Member not found?
+
+ mapif_party_withdraw(party_id, account_id, char_id);
+
+ if (p->party.member[i].leader){
+ p->party.member[i].account_id = 0;
+ for (j = 0; j < MAX_PARTY; j++) {
+ if (!p->party.member[j].account_id)
+ continue;
+ mapif_party_withdraw(party_id, p->party.member[j].account_id, p->party.member[j].char_id);
+ p->party.member[j].account_id = 0;
+ }
+ //Party gets deleted on the check_empty call below.
+ } else {
+ inter_party_tosql(&p->party,PS_DELMEMBER,i);
+ j = p->party.member[i].lv;
+ if(p->party.member[i].online) p->party.count--;
+ memset(&p->party.member[i], 0, sizeof(struct party_member));
+ p->size--;
+ if (j == p->min_lv || j == p->max_lv || p->family)
+ {
+ if(p->family) p->family = 0; //Family state broken.
+ int_party_check_lv(p);
+ }
+ }
+
+ if (party_check_empty(p) == 0)
+ mapif_party_info(-1, &p->party, 0);
+ return 0;
}
// When member goes to other map or levels up.
int mapif_parse_PartyChangeMap(int fd, int party_id, int account_id, int char_id, unsigned short map, int online, unsigned int lv)
{
- struct party_data *p;
- int i;
-
- p = inter_party_fromsql(party_id);
- if (p == NULL)
- return 0;
-
- for (i = 0; i < MAX_PARTY &&
- (p->party.member[i].account_id != account_id ||
- p->party.member[i].char_id != char_id); i++);
-
- if (i == MAX_PARTY) return 0;
-
- if (p->party.member[i].online != online) {
- p->party.member[i].online = online;
- if (online)
- p->party.count++;
- else
- p->party.count--;
- // Even share check situations: Family state (always breaks)
- // character logging on/off is max/min level (update level range)
- // or character logging on/off has a different level (update level range using new level)
- if (p->family ||
- (p->party.member[i].lv <= p->min_lv || p->party.member[i].lv >= p->max_lv) ||
- (p->party.member[i].lv != lv && (lv <= p->min_lv || lv >= p->max_lv))
- ) {
- p->party.member[i].lv = lv;
- int_party_check_lv(p);
- }
- //Send online/offline update.
- mapif_party_membermoved(&p->party, i);
- }
-
- if (p->party.member[i].lv != lv) {
- if (p->party.member[i].lv == p->min_lv ||
- p->party.member[i].lv == p->max_lv) {
- p->party.member[i].lv = lv;
- int_party_check_lv(p);
- } else
- p->party.member[i].lv = lv;
- //There is no need to send level update to map servers
- //since they do nothing with it.
- }
-
- if (p->party.member[i].map != map) {
- p->party.member[i].map = map;
- mapif_party_membermoved(&p->party, i);
- }
- return 0;
+ struct party_data *p;
+ int i;
+
+ p = inter_party_fromsql(party_id);
+ if (p == NULL)
+ return 0;
+
+ for(i = 0; i < MAX_PARTY &&
+ (p->party.member[i].account_id != account_id ||
+ p->party.member[i].char_id != char_id); i++);
+
+ if (i == MAX_PARTY) return 0;
+
+ if (p->party.member[i].online != online)
+ {
+ p->party.member[i].online = online;
+ if (online)
+ p->party.count++;
+ else
+ p->party.count--;
+ // Even share check situations: Family state (always breaks)
+ // character logging on/off is max/min level (update level range)
+ // or character logging on/off has a different level (update level range using new level)
+ if (p->family ||
+ (p->party.member[i].lv <= p->min_lv || p->party.member[i].lv >= p->max_lv) ||
+ (p->party.member[i].lv != lv && (lv <= p->min_lv || lv >= p->max_lv))
+ )
+ {
+ p->party.member[i].lv = lv;
+ int_party_check_lv(p);
+ }
+ //Send online/offline update.
+ mapif_party_membermoved(&p->party, i);
+ }
+
+ if (p->party.member[i].lv != lv) {
+ if(p->party.member[i].lv == p->min_lv ||
+ p->party.member[i].lv == p->max_lv)
+ {
+ p->party.member[i].lv = lv;
+ int_party_check_lv(p);
+ } else
+ p->party.member[i].lv = lv;
+ //There is no need to send level update to map servers
+ //since they do nothing with it.
+ }
+
+ if (p->party.member[i].map != map) {
+ p->party.member[i].map = map;
+ mapif_party_membermoved(&p->party, i);
+ }
+ return 0;
}
//Request party dissolution
int mapif_parse_BreakParty(int fd,int party_id)
{
- struct party_data *p;
+ struct party_data *p;
- p = inter_party_fromsql(party_id);
+ p = inter_party_fromsql(party_id);
- if (!p)
- return 0;
- inter_party_tosql(&p->party,PS_BREAK,0);
- mapif_party_broken(fd,party_id);
- return 0;
+ if(!p)
+ return 0;
+ inter_party_tosql(&p->party,PS_BREAK,0);
+ mapif_party_broken(fd,party_id);
+ return 0;
}
//Party sending the message
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, fd);
+ return mapif_party_message(party_id,account_id,mes,len, fd);
}
int mapif_parse_PartyLeaderChange(int fd,int party_id,int account_id,int char_id)
{
- struct party_data *p;
- int i;
-
- p = inter_party_fromsql(party_id);
-
- if (!p)
- return 0;
-
- for (i = 0; i < MAX_PARTY; i++) {
- if (p->party.member[i].leader)
- p->party.member[i].leader = 0;
- if (p->party.member[i].account_id == account_id &&
- p->party.member[i].char_id == char_id) {
- p->party.member[i].leader = 1;
- inter_party_tosql(&p->party,PS_LEADER, i);
- }
- }
- return 1;
+ struct party_data *p;
+ int i;
+
+ p = inter_party_fromsql(party_id);
+
+ if(!p)
+ return 0;
+
+ for (i = 0; i < MAX_PARTY; i++)
+ {
+ if(p->party.member[i].leader)
+ p->party.member[i].leader = 0;
+ if(p->party.member[i].account_id == account_id &&
+ p->party.member[i].char_id == char_id)
+ {
+ p->party.member[i].leader = 1;
+ inter_party_tosql(&p->party,PS_LEADER, i);
+ }
+ }
+ return 1;
}
@@ -742,139 +741,123 @@ int mapif_parse_PartyLeaderChange(int fd,int party_id,int account_id,int char_id
// Data packet length is set to inter.c that you
// Do NOT go and check the packet length, RFIFOSKIP is done by the caller
// Return :
-// 0 : error
-// 1 : ok
+// 0 : error
+// 1 : ok
int inter_party_parse_frommap(int fd)
{
- RFIFOHEAD(fd);
- switch (RFIFOW(fd,0)) {
- case 0x3020:
- mapif_parse_CreateParty(fd, (char *)RFIFOP(fd,4), RFIFOB(fd,28), RFIFOB(fd,29), (struct party_member *)RFIFOP(fd,30));
- break;
- case 0x3021:
- mapif_parse_PartyInfo(fd, RFIFOL(fd,2), RFIFOL(fd,6));
- break;
- case 0x3022:
- mapif_parse_PartyAddMember(fd, RFIFOL(fd,4), (struct party_member *)RFIFOP(fd,8));
- 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), RFIFOL(fd,10));
- break;
- case 0x3025:
- mapif_parse_PartyChangeMap(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOW(fd,14), RFIFOB(fd,16), RFIFOW(fd,17));
- break;
- case 0x3026:
- mapif_parse_BreakParty(fd, RFIFOL(fd,2));
- break;
- case 0x3027:
- mapif_parse_PartyMessage(fd, RFIFOL(fd,4), RFIFOL(fd,8), (char *)RFIFOP(fd,12), RFIFOW(fd,2)-12);
- break;
- case 0x3029:
- mapif_parse_PartyLeaderChange(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10));
- break;
- default:
- return 0;
- }
- return 1;
+ RFIFOHEAD(fd);
+ switch(RFIFOW(fd,0)) {
+ case 0x3020: mapif_parse_CreateParty(fd, (char*)RFIFOP(fd,4), RFIFOB(fd,28), RFIFOB(fd,29), (struct party_member*)RFIFOP(fd,30)); break;
+ case 0x3021: mapif_parse_PartyInfo(fd, RFIFOL(fd,2), RFIFOL(fd,6)); break;
+ case 0x3022: mapif_parse_PartyAddMember(fd, RFIFOL(fd,4), (struct party_member*)RFIFOP(fd,8)); 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), RFIFOL(fd,10)); break;
+ case 0x3025: mapif_parse_PartyChangeMap(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOW(fd,14), RFIFOB(fd,16), RFIFOW(fd,17)); break;
+ case 0x3026: mapif_parse_BreakParty(fd, RFIFOL(fd,2)); break;
+ case 0x3027: mapif_parse_PartyMessage(fd, RFIFOL(fd,4), RFIFOL(fd,8), (char*)RFIFOP(fd,12), RFIFOW(fd,2)-12); break;
+ case 0x3029: mapif_parse_PartyLeaderChange(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10)); break;
+ default:
+ return 0;
+ }
+ return 1;
}
//Leave request from the server (for delete character)
int inter_party_leave(int party_id,int account_id, int char_id)
{
- return mapif_parse_PartyLeave(-1,party_id,account_id, char_id);
+ return mapif_parse_PartyLeave(-1,party_id,account_id, char_id);
}
int inter_party_CharOnline(int char_id, int party_id)
{
- struct party_data *p;
- int i;
-
- if (party_id == -1) {
- // Get party_id from the database
- char *data;
-
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT party_id FROM `%s` WHERE char_id='%d'", char_db, char_id)) {
- Sql_ShowDebug(sql_handle);
- return 0;
- }
-
- if (SQL_SUCCESS != Sql_NextRow(sql_handle))
- return 0; //Eh? No party?
-
- Sql_GetData(sql_handle, 0, &data, NULL);
- party_id = atoi(data);
- Sql_FreeResult(sql_handle);
- }
- if (party_id == 0)
- return 0; //No party...
-
- p = inter_party_fromsql(party_id);
- if (!p) {
- ShowError("Character %d's party %d not found!\n", char_id, party_id);
- return 0;
- }
-
- //Set member online
- for (i=0; i<MAX_PARTY; i++) {
- if (p->party.member[i].char_id == char_id) {
- if (!p->party.member[i].online) {
- p->party.member[i].online = 1;
- p->party.count++;
- if (p->party.member[i].lv < p->min_lv ||
- p->party.member[i].lv > p->max_lv)
- int_party_check_lv(p);
- }
- break;
- }
- }
- return 1;
+ struct party_data* p;
+ int i;
+
+ if( party_id == -1 )
+ {// Get party_id from the database
+ char* data;
+
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT party_id FROM `%s` WHERE char_id='%d'", char_db, char_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ return 0;
+ }
+
+ if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
+ return 0; //Eh? No party?
+
+ Sql_GetData(sql_handle, 0, &data, NULL);
+ party_id = atoi(data);
+ Sql_FreeResult(sql_handle);
+ }
+ if (party_id == 0)
+ return 0; //No party...
+
+ p = inter_party_fromsql(party_id);
+ if(!p) {
+ ShowError("Character %d's party %d not found!\n", char_id, party_id);
+ return 0;
+ }
+
+ //Set member online
+ for(i=0; i<MAX_PARTY; i++) {
+ if (p->party.member[i].char_id == char_id) {
+ if (!p->party.member[i].online) {
+ p->party.member[i].online = 1;
+ p->party.count++;
+ if (p->party.member[i].lv < p->min_lv ||
+ p->party.member[i].lv > p->max_lv)
+ int_party_check_lv(p);
+ }
+ break;
+ }
+ }
+ return 1;
}
-int inter_party_CharOffline(int char_id, int party_id)
-{
- struct party_data *p=NULL;
- int i;
-
- if (party_id == -1) {
- // Get guild_id from the database
- char *data;
-
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT party_id FROM `%s` WHERE char_id='%d'", char_db, char_id)) {
- Sql_ShowDebug(sql_handle);
- return 0;
- }
-
- if (SQL_SUCCESS != Sql_NextRow(sql_handle))
- return 0; //Eh? No party?
-
- Sql_GetData(sql_handle, 0, &data, NULL);
- party_id = atoi(data);
- Sql_FreeResult(sql_handle);
- }
- if (party_id == 0)
- return 0; //No party...
-
- //Character has a party, set character offline and check if they were the only member online
- if ((p = inter_party_fromsql(party_id)) == NULL)
- return 0;
-
- //Set member offline
- for (i=0; i< MAX_PARTY; i++) {
- if (p->party.member[i].char_id == char_id) {
- p->party.member[i].online = 0;
- p->party.count--;
- if (p->party.member[i].lv == p->min_lv ||
- p->party.member[i].lv == p->max_lv)
- int_party_check_lv(p);
- break;
- }
- }
-
- if (!p->party.count)
- //Parties don't have any data that needs be saved at this point... so just remove it from memory.
- idb_remove(party_db_, party_id);
- return 1;
+int inter_party_CharOffline(int char_id, int party_id) {
+ struct party_data *p=NULL;
+ int i;
+
+ if( party_id == -1 )
+ {// Get guild_id from the database
+ char* data;
+
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT party_id FROM `%s` WHERE char_id='%d'", char_db, char_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ return 0;
+ }
+
+ if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
+ return 0; //Eh? No party?
+
+ Sql_GetData(sql_handle, 0, &data, NULL);
+ party_id = atoi(data);
+ Sql_FreeResult(sql_handle);
+ }
+ if (party_id == 0)
+ return 0; //No party...
+
+ //Character has a party, set character offline and check if they were the only member online
+ if ((p = inter_party_fromsql(party_id)) == NULL)
+ return 0;
+
+ //Set member offline
+ for(i=0; i< MAX_PARTY; i++) {
+ if(p->party.member[i].char_id == char_id)
+ {
+ p->party.member[i].online = 0;
+ p->party.count--;
+ if(p->party.member[i].lv == p->min_lv ||
+ p->party.member[i].lv == p->max_lv)
+ int_party_check_lv(p);
+ break;
+ }
+ }
+
+ if(!p->party.count)
+ //Parties don't have any data that needs be saved at this point... so just remove it from memory.
+ idb_remove(party_db_, party_id);
+ return 1;
}
diff --git a/src/char/int_party.h b/src/char/int_party.h
index 27df25f15..d8cdcdc6a 100644
--- a/src/char/int_party.h
+++ b/src/char/int_party.h
@@ -6,12 +6,12 @@
//Party Flags on what to save/delete.
enum {
- PS_CREATE = 0x01, //Create a new party entry (index holds leader's info)
- PS_BASIC = 0x02, //Update basic party info.
- PS_LEADER = 0x04, //Update party's leader
- PS_ADDMEMBER = 0x08, //Specify new party member (index specifies which party member)
- PS_DELMEMBER = 0x10, //Specify member that left (index specifies which party member)
- PS_BREAK = 0x20, //Specify that this party must be deleted.
+ PS_CREATE = 0x01, //Create a new party entry (index holds leader's info)
+ PS_BASIC = 0x02, //Update basic party info.
+ PS_LEADER = 0x04, //Update party's leader
+ PS_ADDMEMBER = 0x08, //Specify new party member (index specifies which party member)
+ PS_DELMEMBER = 0x10, //Specify member that left (index specifies which party member)
+ PS_BREAK = 0x20, //Specify that this party must be deleted.
};
struct party;
diff --git a/src/char/int_pet.c b/src/char/int_pet.c
index e04138c0a..114398290 100644
--- a/src/char/int_pet.c
+++ b/src/char/int_pet.c
@@ -18,319 +18,292 @@
struct s_pet *pet_pt;
//---------------------------------------------------------
-int inter_pet_tosql(int pet_id, 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 esc_name[NAME_LENGTH*2+1];// escaped pet name
-
- Sql_EscapeStringLen(sql_handle, esc_name, p->name, strnlen(p->name, NAME_LENGTH));
- p->hungry = cap_value(p->hungry, 0, 100);
- p->intimate = cap_value(p->intimate, 0, 1000);
-
- if (pet_id == -1) {
- // New pet.
- if (SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` "
- "(`class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate`) "
- "VALUES ('%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
- pet_db, p->class_, esc_name, p->account_id, p->char_id, p->level, p->egg_id,
- p->equip, p->intimate, p->hungry, p->rename_flag, p->incuvate)) {
- Sql_ShowDebug(sql_handle);
- return 0;
- }
- p->pet_id = (int)Sql_LastInsertId(sql_handle);
- } else {
- // Update pet.
- if (SQL_ERROR == Sql_Query(sql_handle, "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_, esc_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)) {
- Sql_ShowDebug(sql_handle);
- return 0;
- }
- }
-
- if (save_log)
- ShowInfo("Pet saved %d - %s.\n", pet_id, p->name);
- return 1;
+ //`pet` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate`)
+ char esc_name[NAME_LENGTH*2+1];// escaped pet name
+
+ Sql_EscapeStringLen(sql_handle, esc_name, p->name, strnlen(p->name, NAME_LENGTH));
+ p->hungry = cap_value(p->hungry, 0, 100);
+ p->intimate = cap_value(p->intimate, 0, 1000);
+
+ if( pet_id == -1 )
+ {// New pet.
+ if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` "
+ "(`class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate`) "
+ "VALUES ('%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
+ pet_db, p->class_, esc_name, p->account_id, p->char_id, p->level, p->egg_id,
+ p->equip, p->intimate, p->hungry, p->rename_flag, p->incuvate) )
+ {
+ Sql_ShowDebug(sql_handle);
+ return 0;
+ }
+ p->pet_id = (int)Sql_LastInsertId(sql_handle);
+ }
+ else
+ {// Update pet.
+ if( SQL_ERROR == Sql_Query(sql_handle, "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_, esc_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) )
+ {
+ Sql_ShowDebug(sql_handle);
+ return 0;
+ }
+ }
+
+ if (save_log)
+ ShowInfo("Pet saved %d - %s.\n", pet_id, p->name);
+ return 1;
}
-int inter_pet_fromsql(int pet_id, struct s_pet *p)
+int inter_pet_fromsql(int pet_id, struct s_pet* p)
{
- char *data;
- size_t len;
+ char* data;
+ size_t len;
#ifdef NOISY
- ShowInfo("Loading pet (%d)...\n",pet_id);
+ ShowInfo("Loading pet (%d)...\n",pet_id);
#endif
- 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`)
-
- if (SQL_ERROR == Sql_Query(sql_handle, "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)) {
- Sql_ShowDebug(sql_handle);
- return 0;
- }
-
- if (SQL_SUCCESS == Sql_NextRow(sql_handle)) {
- p->pet_id = pet_id;
- Sql_GetData(sql_handle, 1, &data, NULL);
- p->class_ = atoi(data);
- Sql_GetData(sql_handle, 2, &data, &len);
- memcpy(p->name, data, min(len, NAME_LENGTH));
- Sql_GetData(sql_handle, 3, &data, NULL);
- p->account_id = atoi(data);
- Sql_GetData(sql_handle, 4, &data, NULL);
- p->char_id = atoi(data);
- Sql_GetData(sql_handle, 5, &data, NULL);
- p->level = atoi(data);
- Sql_GetData(sql_handle, 6, &data, NULL);
- p->egg_id = atoi(data);
- Sql_GetData(sql_handle, 7, &data, NULL);
- p->equip = atoi(data);
- Sql_GetData(sql_handle, 8, &data, NULL);
- p->intimate = atoi(data);
- Sql_GetData(sql_handle, 9, &data, NULL);
- p->hungry = atoi(data);
- Sql_GetData(sql_handle, 10, &data, NULL);
- p->rename_flag = atoi(data);
- Sql_GetData(sql_handle, 11, &data, NULL);
- p->incuvate = atoi(data);
-
- Sql_FreeResult(sql_handle);
-
- p->hungry = cap_value(p->hungry, 0, 100);
- p->intimate = cap_value(p->intimate, 0, 1000);
-
- if (save_log)
- ShowInfo("Pet loaded (%d - %s).\n", pet_id, p->name);
- }
- return 0;
+ 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`)
+
+ if( SQL_ERROR == Sql_Query(sql_handle, "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) )
+ {
+ Sql_ShowDebug(sql_handle);
+ return 0;
+ }
+
+ if( SQL_SUCCESS == Sql_NextRow(sql_handle) )
+ {
+ p->pet_id = pet_id;
+ Sql_GetData(sql_handle, 1, &data, NULL); p->class_ = atoi(data);
+ Sql_GetData(sql_handle, 2, &data, &len); memcpy(p->name, data, min(len, NAME_LENGTH));
+ Sql_GetData(sql_handle, 3, &data, NULL); p->account_id = atoi(data);
+ Sql_GetData(sql_handle, 4, &data, NULL); p->char_id = atoi(data);
+ Sql_GetData(sql_handle, 5, &data, NULL); p->level = atoi(data);
+ Sql_GetData(sql_handle, 6, &data, NULL); p->egg_id = atoi(data);
+ Sql_GetData(sql_handle, 7, &data, NULL); p->equip = atoi(data);
+ Sql_GetData(sql_handle, 8, &data, NULL); p->intimate = atoi(data);
+ Sql_GetData(sql_handle, 9, &data, NULL); p->hungry = atoi(data);
+ Sql_GetData(sql_handle, 10, &data, NULL); p->rename_flag = atoi(data);
+ Sql_GetData(sql_handle, 11, &data, NULL); p->incuvate = atoi(data);
+
+ Sql_FreeResult(sql_handle);
+
+ p->hungry = cap_value(p->hungry, 0, 100);
+ p->intimate = cap_value(p->intimate, 0, 1000);
+
+ if( save_log )
+ ShowInfo("Pet loaded (%d - %s).\n", pet_id, p->name);
+ }
+ return 0;
}
//----------------------------------------------
-int inter_pet_sql_init(void)
-{
- //memory alloc
- pet_pt = (struct s_pet *)aCalloc(sizeof(struct s_pet), 1);
- return 0;
+int inter_pet_sql_init(void){
+ //memory alloc
+ pet_pt = (struct s_pet*)aCalloc(sizeof(struct s_pet), 1);
+ return 0;
}
-void inter_pet_sql_final(void)
-{
- if (pet_pt) aFree(pet_pt);
- return;
+void inter_pet_sql_final(void){
+ if (pet_pt) aFree(pet_pt);
+ return;
}
//----------------------------------
-int inter_pet_delete(int pet_id)
-{
- ShowInfo("delete pet request: %d...\n",pet_id);
+int inter_pet_delete(int pet_id){
+ ShowInfo("delete pet request: %d...\n",pet_id);
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `pet_id`='%d'", pet_db, pet_id))
- Sql_ShowDebug(sql_handle);
- return 0;
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `pet_id`='%d'", pet_db, pet_id) )
+ Sql_ShowDebug(sql_handle);
+ return 0;
}
//------------------------------------------------------
int mapif_pet_created(int fd, int account_id, struct s_pet *p)
{
- WFIFOHEAD(fd, 11);
- WFIFOW(fd, 0) =0x3880;
- WFIFOL(fd, 2) =account_id;
- if (p!=NULL) {
- WFIFOB(fd, 6)=0;
- WFIFOL(fd, 7) =p->pet_id;
- ShowInfo("int_pet: created pet %d - %s\n", p->pet_id, p->name);
- } else {
- WFIFOB(fd, 6)=1;
- WFIFOL(fd, 7)=0;
- }
- WFIFOSET(fd, 11);
-
- return 0;
+ WFIFOHEAD(fd, 11);
+ WFIFOW(fd, 0) =0x3880;
+ WFIFOL(fd, 2) =account_id;
+ if(p!=NULL){
+ WFIFOB(fd, 6)=0;
+ WFIFOL(fd, 7) =p->pet_id;
+ ShowInfo("int_pet: created pet %d - %s\n", p->pet_id, p->name);
+ }else{
+ WFIFOB(fd, 6)=1;
+ WFIFOL(fd, 7)=0;
+ }
+ WFIFOSET(fd, 11);
+
+ return 0;
}
-int mapif_pet_info(int fd, int account_id, struct s_pet *p)
-{
- WFIFOHEAD(fd, sizeof(struct s_pet) + 9);
- WFIFOW(fd, 0) =0x3881;
- WFIFOW(fd, 2) =sizeof(struct s_pet) + 9;
- WFIFOL(fd, 4) =account_id;
- WFIFOB(fd, 8)=0;
- memcpy(WFIFOP(fd, 9), p, sizeof(struct s_pet));
- WFIFOSET(fd, WFIFOW(fd, 2));
-
- return 0;
+int mapif_pet_info(int fd, int account_id, struct s_pet *p){
+ WFIFOHEAD(fd, sizeof(struct s_pet) + 9);
+ WFIFOW(fd, 0) =0x3881;
+ WFIFOW(fd, 2) =sizeof(struct s_pet) + 9;
+ WFIFOL(fd, 4) =account_id;
+ WFIFOB(fd, 8)=0;
+ memcpy(WFIFOP(fd, 9), p, sizeof(struct s_pet));
+ WFIFOSET(fd, WFIFOW(fd, 2));
+
+ return 0;
}
-int mapif_pet_noinfo(int fd, int account_id)
-{
- WFIFOHEAD(fd, sizeof(struct s_pet) + 9);
- WFIFOW(fd, 0) =0x3881;
- WFIFOW(fd, 2) =sizeof(struct s_pet) + 9;
- WFIFOL(fd, 4) =account_id;
- WFIFOB(fd, 8)=1;
- memset(WFIFOP(fd, 9), 0, sizeof(struct s_pet));
- WFIFOSET(fd, WFIFOW(fd, 2));
-
- return 0;
+int mapif_pet_noinfo(int fd, int account_id){
+ WFIFOHEAD(fd, sizeof(struct s_pet) + 9);
+ WFIFOW(fd, 0) =0x3881;
+ WFIFOW(fd, 2) =sizeof(struct s_pet) + 9;
+ WFIFOL(fd, 4) =account_id;
+ WFIFOB(fd, 8)=1;
+ memset(WFIFOP(fd, 9), 0, sizeof(struct s_pet));
+ WFIFOSET(fd, WFIFOW(fd, 2));
+
+ return 0;
}
-int mapif_save_pet_ack(int fd, int account_id, int flag)
-{
- WFIFOHEAD(fd, 7);
- WFIFOW(fd, 0) =0x3882;
- WFIFOL(fd, 2) =account_id;
- WFIFOB(fd, 6) =flag;
- WFIFOSET(fd, 7);
+int mapif_save_pet_ack(int fd, int account_id, int flag){
+ WFIFOHEAD(fd, 7);
+ WFIFOW(fd, 0) =0x3882;
+ WFIFOL(fd, 2) =account_id;
+ WFIFOB(fd, 6) =flag;
+ WFIFOSET(fd, 7);
- return 0;
+ return 0;
}
-int mapif_delete_pet_ack(int fd, int flag)
-{
- WFIFOHEAD(fd, 3);
- WFIFOW(fd, 0) =0x3883;
- WFIFOB(fd, 2) =flag;
- WFIFOSET(fd, 3);
+int mapif_delete_pet_ack(int fd, int flag){
+ WFIFOHEAD(fd, 3);
+ WFIFOW(fd, 0) =0x3883;
+ WFIFOB(fd, 2) =flag;
+ WFIFOSET(fd, 3);
- return 0;
+ return 0;
}
int mapif_create_pet(int fd, 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)
+ short pet_equip, short intimate, short hungry, char rename_flag, char incuvate, char *pet_name)
{
- memset(pet_pt, 0, sizeof(struct s_pet));
- strncpy(pet_pt->name, pet_name, NAME_LENGTH);
- if (incuvate == 1)
- pet_pt->account_id = pet_pt->char_id = 0;
- else {
- pet_pt->account_id = account_id;
- pet_pt->char_id = char_id;
- }
- pet_pt->class_ = pet_class;
- pet_pt->level = pet_lv;
- pet_pt->egg_id = pet_egg_id;
- pet_pt->equip = pet_equip;
- pet_pt->intimate = intimate;
- pet_pt->hungry = hungry;
- pet_pt->rename_flag = rename_flag;
- pet_pt->incuvate = incuvate;
-
- if (pet_pt->hungry < 0)
- pet_pt->hungry = 0;
- else if (pet_pt->hungry > 100)
- pet_pt->hungry = 100;
- if (pet_pt->intimate < 0)
- pet_pt->intimate = 0;
- else if (pet_pt->intimate > 1000)
- pet_pt->intimate = 1000;
-
- pet_pt->pet_id = -1; //Signal NEW pet.
- if (inter_pet_tosql(pet_pt->pet_id,pet_pt))
- mapif_pet_created(fd, account_id, pet_pt);
- else //Failed...
- mapif_pet_created(fd, account_id, NULL);
-
- return 0;
+ memset(pet_pt, 0, sizeof(struct s_pet));
+ strncpy(pet_pt->name, pet_name, NAME_LENGTH);
+ if(incuvate == 1)
+ pet_pt->account_id = pet_pt->char_id = 0;
+ else {
+ pet_pt->account_id = account_id;
+ pet_pt->char_id = char_id;
+ }
+ pet_pt->class_ = pet_class;
+ pet_pt->level = pet_lv;
+ pet_pt->egg_id = pet_egg_id;
+ pet_pt->equip = pet_equip;
+ pet_pt->intimate = intimate;
+ pet_pt->hungry = hungry;
+ pet_pt->rename_flag = rename_flag;
+ pet_pt->incuvate = incuvate;
+
+ if(pet_pt->hungry < 0)
+ pet_pt->hungry = 0;
+ else if(pet_pt->hungry > 100)
+ pet_pt->hungry = 100;
+ if(pet_pt->intimate < 0)
+ pet_pt->intimate = 0;
+ else if(pet_pt->intimate > 1000)
+ pet_pt->intimate = 1000;
+
+ pet_pt->pet_id = -1; //Signal NEW pet.
+ if (inter_pet_tosql(pet_pt->pet_id,pet_pt))
+ mapif_pet_created(fd, account_id, pet_pt);
+ else //Failed...
+ mapif_pet_created(fd, account_id, NULL);
+
+ 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;
- mapif_pet_info(fd, account_id, pet_pt);
- } else if (account_id == pet_pt->account_id && char_id == pet_pt->char_id)
- mapif_pet_info(fd, account_id, pet_pt);
- else
- mapif_pet_noinfo(fd, account_id);
- } else
- mapif_pet_noinfo(fd, account_id);
-
- 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;
+ mapif_pet_info(fd, account_id, pet_pt);
+ }
+ else if(account_id == pet_pt->account_id && char_id == pet_pt->char_id)
+ mapif_pet_info(fd, account_id, pet_pt);
+ else
+ mapif_pet_noinfo(fd, account_id);
+ }
+ else
+ mapif_pet_noinfo(fd, account_id);
+
+ return 0;
}
-int mapif_save_pet(int fd, int account_id, struct s_pet *data)
-{
- //here process pet save request.
- int len;
- RFIFOHEAD(fd);
- len=RFIFOW(fd, 2);
- if (sizeof(struct s_pet)!=len-8) {
- ShowError("inter pet: data size error %d %d\n", sizeof(struct s_pet), len-8);
- }
-
- else {
- if (data->hungry < 0)
- data->hungry = 0;
- else if (data->hungry > 100)
- data->hungry = 100;
- if (data->intimate < 0)
- data->intimate = 0;
- else if (data->intimate > 1000)
- data->intimate = 1000;
- inter_pet_tosql(data->pet_id,data);
- mapif_save_pet_ack(fd, account_id, 0);
- }
-
- return 0;
+int mapif_save_pet(int fd, int account_id, struct s_pet *data) {
+ //here process pet save request.
+ int len;
+ RFIFOHEAD(fd);
+ len=RFIFOW(fd, 2);
+ if(sizeof(struct s_pet)!=len-8) {
+ ShowError("inter pet: data size error %d %d\n", sizeof(struct s_pet), len-8);
+ }
+
+ else{
+ if(data->hungry < 0)
+ data->hungry = 0;
+ else if(data->hungry > 100)
+ data->hungry = 100;
+ if(data->intimate < 0)
+ data->intimate = 0;
+ else if(data->intimate > 1000)
+ data->intimate = 1000;
+ inter_pet_tosql(data->pet_id,data);
+ mapif_save_pet_ack(fd, account_id, 0);
+ }
+
+ return 0;
}
-int mapif_delete_pet(int fd, int pet_id)
-{
- mapif_delete_pet_ack(fd, inter_pet_delete(pet_id));
+int mapif_delete_pet(int fd, int pet_id){
+ mapif_delete_pet_ack(fd, inter_pet_delete(pet_id));
- return 0;
+ return 0;
}
-int mapif_parse_CreatePet(int fd)
-{
- RFIFOHEAD(fd);
- mapif_create_pet(fd, RFIFOL(fd, 2), RFIFOL(fd, 6), RFIFOW(fd, 10), RFIFOW(fd, 12), RFIFOW(fd, 14), RFIFOW(fd, 16), RFIFOW(fd, 18),
- RFIFOW(fd, 20), RFIFOB(fd, 22), RFIFOB(fd, 23), (char *)RFIFOP(fd, 24));
- return 0;
+int mapif_parse_CreatePet(int fd){
+ RFIFOHEAD(fd);
+ mapif_create_pet(fd, RFIFOL(fd, 2), RFIFOL(fd, 6), RFIFOW(fd, 10), RFIFOW(fd, 12), RFIFOW(fd, 14), RFIFOW(fd, 16), RFIFOW(fd, 18),
+ RFIFOW(fd, 20), RFIFOB(fd, 22), RFIFOB(fd, 23), (char*)RFIFOP(fd, 24));
+ return 0;
}
-int mapif_parse_LoadPet(int fd)
-{
- RFIFOHEAD(fd);
- mapif_load_pet(fd, RFIFOL(fd, 2), RFIFOL(fd, 6), RFIFOL(fd, 10));
- return 0;
+int mapif_parse_LoadPet(int fd){
+ RFIFOHEAD(fd);
+ mapif_load_pet(fd, RFIFOL(fd, 2), RFIFOL(fd, 6), RFIFOL(fd, 10));
+ return 0;
}
-int mapif_parse_SavePet(int fd)
-{
- RFIFOHEAD(fd);
- mapif_save_pet(fd, RFIFOL(fd, 4), (struct s_pet *) RFIFOP(fd, 8));
- return 0;
+int mapif_parse_SavePet(int fd){
+ RFIFOHEAD(fd);
+ mapif_save_pet(fd, RFIFOL(fd, 4), (struct s_pet *) RFIFOP(fd, 8));
+ return 0;
}
-int mapif_parse_DeletePet(int fd)
-{
- RFIFOHEAD(fd);
- mapif_delete_pet(fd, RFIFOL(fd, 2));
- return 0;
+int mapif_parse_DeletePet(int fd){
+ RFIFOHEAD(fd);
+ mapif_delete_pet(fd, RFIFOL(fd, 2));
+ return 0;
}
-int inter_pet_parse_frommap(int fd)
-{
- RFIFOHEAD(fd);
- switch (RFIFOW(fd, 0)) {
- case 0x3080:
- mapif_parse_CreatePet(fd);
- break;
- case 0x3081:
- mapif_parse_LoadPet(fd);
- break;
- case 0x3082:
- mapif_parse_SavePet(fd);
- break;
- case 0x3083:
- mapif_parse_DeletePet(fd);
- break;
- default:
- return 0;
- }
- return 1;
+int inter_pet_parse_frommap(int fd){
+ RFIFOHEAD(fd);
+ switch(RFIFOW(fd, 0)){
+ case 0x3080: mapif_parse_CreatePet(fd); break;
+ case 0x3081: mapif_parse_LoadPet(fd); break;
+ case 0x3082: mapif_parse_SavePet(fd); break;
+ case 0x3083: mapif_parse_DeletePet(fd); break;
+ default:
+ return 0;
+ }
+ return 1;
}
diff --git a/src/char/int_quest.c b/src/char/int_quest.c
index 8ba6ef95a..224205412 100644
--- a/src/char/int_quest.c
+++ b/src/char/int_quest.c
@@ -21,158 +21,164 @@
//Load entire questlog for a character
int mapif_quests_fromsql(int char_id, struct quest questlog[])
{
- int i;
- struct quest tmp_quest;
- SqlStmt *stmt;
-
- stmt = SqlStmt_Malloc(sql_handle);
- if (stmt == NULL) {
- SqlStmt_ShowDebug(stmt);
- return 0;
- }
-
- memset(&tmp_quest, 0, sizeof(struct quest));
-
- if (SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `quest_id`, `state`, `time`, `count1`, `count2`, `count3` FROM `%s` WHERE `char_id`=? LIMIT %d", quest_db, MAX_QUEST_DB)
- || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
- || SQL_ERROR == SqlStmt_Execute(stmt)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &tmp_quest.quest_id, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_INT, &tmp_quest.state, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_UINT, &tmp_quest.time, 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 3, SQLDT_INT, &tmp_quest.count[0], 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 4, SQLDT_INT, &tmp_quest.count[1], 0, NULL, NULL)
- || SQL_ERROR == SqlStmt_BindColumn(stmt, 5, SQLDT_INT, &tmp_quest.count[2], 0, NULL, NULL))
- SqlStmt_ShowDebug(stmt);
-
- for (i = 0; i < MAX_QUEST_DB && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i)
- memcpy(&questlog[i], &tmp_quest, sizeof(tmp_quest));
-
- SqlStmt_Free(stmt);
- return i;
+ int i;
+ struct quest tmp_quest;
+ SqlStmt * stmt;
+
+ stmt = SqlStmt_Malloc(sql_handle);
+ if( stmt == NULL )
+ {
+ SqlStmt_ShowDebug(stmt);
+ return 0;
+ }
+
+ memset(&tmp_quest, 0, sizeof(struct quest));
+
+ if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `quest_id`, `state`, `time`, `count1`, `count2`, `count3` FROM `%s` WHERE `char_id`=? LIMIT %d", quest_db, MAX_QUEST_DB)
+ || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
+ || SQL_ERROR == SqlStmt_Execute(stmt)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &tmp_quest.quest_id, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_INT, &tmp_quest.state, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_UINT, &tmp_quest.time, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 3, SQLDT_INT, &tmp_quest.count[0], 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 4, SQLDT_INT, &tmp_quest.count[1], 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 5, SQLDT_INT, &tmp_quest.count[2], 0, NULL, NULL) )
+ SqlStmt_ShowDebug(stmt);
+
+ for( i = 0; i < MAX_QUEST_DB && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i )
+ memcpy(&questlog[i], &tmp_quest, sizeof(tmp_quest));
+
+ SqlStmt_Free(stmt);
+ return i;
}
//Delete a quest
bool mapif_quest_delete(int char_id, int quest_id)
{
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `quest_id` = '%d' AND `char_id` = '%d'", quest_db, quest_id, char_id)) {
- Sql_ShowDebug(sql_handle);
- return false;
- }
+ if ( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `quest_id` = '%d' AND `char_id` = '%d'", quest_db, quest_id, char_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ return false;
+ }
- return true;
+ return true;
}
//Add a quest to a questlog
bool mapif_quest_add(int char_id, struct quest qd)
{
- if (SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s`(`quest_id`, `char_id`, `state`, `time`, `count1`, `count2`, `count3`) VALUES ('%d', '%d', '%d','%d', '%d', '%d', '%d')", quest_db, qd.quest_id, char_id, qd.state, qd.time, qd.count[0], qd.count[1], qd.count[2])) {
- Sql_ShowDebug(sql_handle);
- return false;
- }
+ if ( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s`(`quest_id`, `char_id`, `state`, `time`, `count1`, `count2`, `count3`) VALUES ('%d', '%d', '%d','%d', '%d', '%d', '%d')", quest_db, qd.quest_id, char_id, qd.state, qd.time, qd.count[0], qd.count[1], qd.count[2]) )
+ {
+ Sql_ShowDebug(sql_handle);
+ return false;
+ }
- return true;
+ return true;
}
//Update a questlog
bool mapif_quest_update(int char_id, struct quest qd)
{
- if (SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `state`='%d', `count1`='%d', `count2`='%d', `count3`='%d' WHERE `quest_id` = '%d' AND `char_id` = '%d'", quest_db, qd.state, qd.count[0], qd.count[1], qd.count[2], qd.quest_id, char_id)) {
- Sql_ShowDebug(sql_handle);
- return false;
- }
+ if ( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `state`='%d', `count1`='%d', `count2`='%d', `count3`='%d' WHERE `quest_id` = '%d' AND `char_id` = '%d'", quest_db, qd.state, qd.count[0], qd.count[1], qd.count[2], qd.quest_id, char_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ return false;
+ }
- return true;
+ return true;
}
//Save quests
int mapif_parse_quest_save(int fd)
{
- int i, j, k, num2, num1 = (RFIFOW(fd,2)-8)/sizeof(struct quest);
- int char_id = RFIFOL(fd,4);
- struct quest qd1[MAX_QUEST_DB],qd2[MAX_QUEST_DB];
- bool success = true;
-
- memset(qd1, 0, sizeof(qd1));
- memset(qd2, 0, sizeof(qd2));
- if (num1) memcpy(&qd1, RFIFOP(fd,8), RFIFOW(fd,2)-8);
- num2 = mapif_quests_fromsql(char_id, qd2);
-
- for (i = 0; i < num1; i++) {
- ARR_FIND(0, num2, j, qd1[i].quest_id == qd2[j].quest_id);
- if (j < num2) { // Update existed quests
- // Only states and counts are changable.
- ARR_FIND(0, MAX_QUEST_OBJECTIVES, k, qd1[i].count[k] != qd2[j].count[k]);
- if (k != MAX_QUEST_OBJECTIVES || qd1[i].state != qd2[j].state)
- success &= mapif_quest_update(char_id, qd1[i]);
-
- if (j < (--num2)) {
- memmove(&qd2[j],&qd2[j+1],sizeof(struct quest)*(num2-j));
- memset(&qd2[num2], 0, sizeof(struct quest));
- }
-
- } else // Add new quests
- success &= mapif_quest_add(char_id, qd1[i]);
- }
-
- for (i = 0; i < num2; i++) // Quests not in qd1 but in qd2 are to be erased.
- success &= mapif_quest_delete(char_id, qd2[i].quest_id);
-
- WFIFOHEAD(fd,7);
- WFIFOW(fd,0) = 0x3861;
- WFIFOL(fd,2) = char_id;
- WFIFOB(fd,6) = success?1:0;
- WFIFOSET(fd,7);
-
- return 0;
+ int i, j, k, num2, num1 = (RFIFOW(fd,2)-8)/sizeof(struct quest);
+ int char_id = RFIFOL(fd,4);
+ struct quest qd1[MAX_QUEST_DB],qd2[MAX_QUEST_DB];
+ bool success = true;
+
+ memset(qd1, 0, sizeof(qd1));
+ memset(qd2, 0, sizeof(qd2));
+ if( num1 ) memcpy(&qd1, RFIFOP(fd,8), RFIFOW(fd,2)-8);
+ num2 = mapif_quests_fromsql(char_id, qd2);
+
+ for( i = 0; i < num1; i++ )
+ {
+ ARR_FIND( 0, num2, j, qd1[i].quest_id == qd2[j].quest_id );
+ if( j < num2 ) // Update existed quests
+ { // Only states and counts are changable.
+ ARR_FIND( 0, MAX_QUEST_OBJECTIVES, k, qd1[i].count[k] != qd2[j].count[k] );
+ if( k != MAX_QUEST_OBJECTIVES || qd1[i].state != qd2[j].state )
+ success &= mapif_quest_update(char_id, qd1[i]);
+
+ if( j < (--num2) )
+ {
+ memmove(&qd2[j],&qd2[j+1],sizeof(struct quest)*(num2-j));
+ memset(&qd2[num2], 0, sizeof(struct quest));
+ }
+
+ }
+ else // Add new quests
+ success &= mapif_quest_add(char_id, qd1[i]);
+ }
+
+ for( i = 0; i < num2; i++ ) // Quests not in qd1 but in qd2 are to be erased.
+ success &= mapif_quest_delete(char_id, qd2[i].quest_id);
+
+ WFIFOHEAD(fd,7);
+ WFIFOW(fd,0) = 0x3861;
+ WFIFOL(fd,2) = char_id;
+ WFIFOB(fd,6) = success?1:0;
+ WFIFOSET(fd,7);
+
+ return 0;
}
//Send questlog to map server
int mapif_parse_quest_load(int fd)
{
- int char_id = RFIFOL(fd,2);
- struct quest tmp_questlog[MAX_QUEST_DB];
- int num_quests, i, num_complete = 0;
- int complete[MAX_QUEST_DB];
-
- memset(tmp_questlog, 0, sizeof(tmp_questlog));
- memset(complete, 0, sizeof(complete));
-
- num_quests = mapif_quests_fromsql(char_id, tmp_questlog);
-
- WFIFOHEAD(fd,num_quests*sizeof(struct quest)+8);
- WFIFOW(fd,0) = 0x3860;
- WFIFOW(fd,2) = num_quests*sizeof(struct quest)+8;
- WFIFOL(fd,4) = char_id;
-
- //Active and inactive quests
- for (i = 0; i < num_quests; i++) {
- if (tmp_questlog[i].state == Q_COMPLETE) {
- complete[num_complete++] = i;
- continue;
- }
- memcpy(WFIFOP(fd,(i-num_complete)*sizeof(struct quest)+8), &tmp_questlog[i], sizeof(struct quest));
- }
-
- // Completed quests
- for (i = num_quests - num_complete; i < num_quests; i++)
- memcpy(WFIFOP(fd,i*sizeof(struct quest)+8), &tmp_questlog[complete[i-num_quests+num_complete]], sizeof(struct quest));
-
- WFIFOSET(fd,num_quests*sizeof(struct quest)+8);
-
- return 0;
+ int char_id = RFIFOL(fd,2);
+ struct quest tmp_questlog[MAX_QUEST_DB];
+ int num_quests, i, num_complete = 0;
+ int complete[MAX_QUEST_DB];
+
+ memset(tmp_questlog, 0, sizeof(tmp_questlog));
+ memset(complete, 0, sizeof(complete));
+
+ num_quests = mapif_quests_fromsql(char_id, tmp_questlog);
+
+ WFIFOHEAD(fd,num_quests*sizeof(struct quest)+8);
+ WFIFOW(fd,0) = 0x3860;
+ WFIFOW(fd,2) = num_quests*sizeof(struct quest)+8;
+ WFIFOL(fd,4) = char_id;
+
+ //Active and inactive quests
+ for( i = 0; i < num_quests; i++ )
+ {
+ if( tmp_questlog[i].state == Q_COMPLETE )
+ {
+ complete[num_complete++] = i;
+ continue;
+ }
+ memcpy(WFIFOP(fd,(i-num_complete)*sizeof(struct quest)+8), &tmp_questlog[i], sizeof(struct quest));
+ }
+
+ // Completed quests
+ for( i = num_quests - num_complete; i < num_quests; i++ )
+ memcpy(WFIFOP(fd,i*sizeof(struct quest)+8), &tmp_questlog[complete[i-num_quests+num_complete]], sizeof(struct quest));
+
+ WFIFOSET(fd,num_quests*sizeof(struct quest)+8);
+
+ return 0;
}
int inter_quest_parse_frommap(int fd)
{
- switch (RFIFOW(fd,0)) {
- case 0x3060:
- mapif_parse_quest_load(fd);
- break;
- case 0x3061:
- mapif_parse_quest_save(fd);
- break;
- default:
- return 0;
- }
- return 1;
+ switch(RFIFOW(fd,0))
+ {
+ case 0x3060: mapif_parse_quest_load(fd); break;
+ case 0x3061: mapif_parse_quest_save(fd); break;
+ default:
+ return 0;
+ }
+ return 1;
}
diff --git a/src/char/int_storage.c b/src/char/int_storage.c
index 6f94ecc32..248a4521f 100644
--- a/src/char/int_storage.c
+++ b/src/char/int_storage.c
@@ -15,155 +15,142 @@
#include <stdlib.h>
-#define STORAGE_MEMINC 16
+#define STORAGE_MEMINC 16
/// Save storage data to sql
-int storage_tosql(int account_id, struct storage_data *p)
+int storage_tosql(int account_id, struct storage_data* p)
{
- memitemdata_to_sql(p->items, MAX_STORAGE, account_id, TABLE_STORAGE);
- return 0;
+ memitemdata_to_sql(p->items, MAX_STORAGE, account_id, TABLE_STORAGE);
+ return 0;
}
/// Load storage data to mem
-int storage_fromsql(int account_id, struct storage_data *p)
+int storage_fromsql(int account_id, struct storage_data* p)
{
- StringBuf buf;
- struct item *item;
- char *data;
- int i;
- int j;
-
- memset(p, 0, sizeof(struct storage_data)); //clean up memory
- p->storage_amount = 0;
-
- // storage {`account_id`/`id`/`nameid`/`amount`/`equip`/`identify`/`refine`/`attribute`/`card0`/`card1`/`card2`/`card3`}
- StringBuf_Init(&buf);
- StringBuf_AppendStr(&buf, "SELECT `id`,`nameid`,`amount`,`equip`,`identify`,`refine`,`attribute`,`expire_time`");
- for (j = 0; j < MAX_SLOTS; ++j)
- StringBuf_Printf(&buf, ",`card%d`", j);
- StringBuf_Printf(&buf, " FROM `%s` WHERE `account_id`='%d' ORDER BY `nameid`", storage_db, account_id);
-
- if (SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf)))
- Sql_ShowDebug(sql_handle);
-
- StringBuf_Destroy(&buf);
-
- for (i = 0; i < MAX_STORAGE && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i) {
- item = &p->items[i];
- Sql_GetData(sql_handle, 0, &data, NULL);
- item->id = atoi(data);
- Sql_GetData(sql_handle, 1, &data, NULL);
- item->nameid = atoi(data);
- Sql_GetData(sql_handle, 2, &data, NULL);
- item->amount = atoi(data);
- Sql_GetData(sql_handle, 3, &data, NULL);
- item->equip = atoi(data);
- Sql_GetData(sql_handle, 4, &data, NULL);
- item->identify = atoi(data);
- Sql_GetData(sql_handle, 5, &data, NULL);
- item->refine = atoi(data);
- Sql_GetData(sql_handle, 6, &data, NULL);
- item->attribute = atoi(data);
- Sql_GetData(sql_handle, 7, &data, NULL);
- item->expire_time = (unsigned int)atoi(data);
- for (j = 0; j < MAX_SLOTS; ++j) {
- Sql_GetData(sql_handle, 8+j, &data, NULL);
- item->card[j] = atoi(data);
- }
- }
- p->storage_amount = i;
- Sql_FreeResult(sql_handle);
-
- ShowInfo("storage load complete from DB - id: %d (total: %d)\n", account_id, p->storage_amount);
- return 1;
+ StringBuf buf;
+ struct item* item;
+ char* data;
+ int i;
+ int j;
+
+ memset(p, 0, sizeof(struct storage_data)); //clean up memory
+ p->storage_amount = 0;
+
+ // storage {`account_id`/`id`/`nameid`/`amount`/`equip`/`identify`/`refine`/`attribute`/`card0`/`card1`/`card2`/`card3`}
+ StringBuf_Init(&buf);
+ StringBuf_AppendStr(&buf, "SELECT `id`,`nameid`,`amount`,`equip`,`identify`,`refine`,`attribute`,`expire_time`");
+ for( j = 0; j < MAX_SLOTS; ++j )
+ StringBuf_Printf(&buf, ",`card%d`", j);
+ StringBuf_Printf(&buf, " FROM `%s` WHERE `account_id`='%d' ORDER BY `nameid`", storage_db, account_id);
+
+ if( SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf)) )
+ Sql_ShowDebug(sql_handle);
+
+ StringBuf_Destroy(&buf);
+
+ for( i = 0; i < MAX_STORAGE && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
+ {
+ item = &p->items[i];
+ Sql_GetData(sql_handle, 0, &data, NULL); item->id = atoi(data);
+ Sql_GetData(sql_handle, 1, &data, NULL); item->nameid = atoi(data);
+ Sql_GetData(sql_handle, 2, &data, NULL); item->amount = atoi(data);
+ Sql_GetData(sql_handle, 3, &data, NULL); item->equip = atoi(data);
+ Sql_GetData(sql_handle, 4, &data, NULL); item->identify = atoi(data);
+ Sql_GetData(sql_handle, 5, &data, NULL); item->refine = atoi(data);
+ Sql_GetData(sql_handle, 6, &data, NULL); item->attribute = atoi(data);
+ Sql_GetData(sql_handle, 7, &data, NULL); item->expire_time = (unsigned int)atoi(data);
+ for( j = 0; j < MAX_SLOTS; ++j )
+ {
+ Sql_GetData(sql_handle, 8+j, &data, NULL); item->card[j] = atoi(data);
+ }
+ }
+ p->storage_amount = i;
+ Sql_FreeResult(sql_handle);
+
+ ShowInfo("storage load complete from DB - id: %d (total: %d)\n", account_id, p->storage_amount);
+ return 1;
}
/// Save guild_storage data to sql
-int guild_storage_tosql(int guild_id, struct guild_storage *p)
+int guild_storage_tosql(int guild_id, struct guild_storage* p)
{
- memitemdata_to_sql(p->items, MAX_GUILD_STORAGE, guild_id, TABLE_GUILD_STORAGE);
- ShowInfo("guild storage save to DB - guild: %d\n", guild_id);
- return 0;
+ memitemdata_to_sql(p->items, MAX_GUILD_STORAGE, guild_id, TABLE_GUILD_STORAGE);
+ ShowInfo ("guild storage save to DB - guild: %d\n", guild_id);
+ return 0;
}
/// Load guild_storage data to mem
-int guild_storage_fromsql(int guild_id, struct guild_storage *p)
+int guild_storage_fromsql(int guild_id, struct guild_storage* p)
{
- StringBuf buf;
- struct item *item;
- char *data;
- int i;
- int j;
-
- memset(p, 0, sizeof(struct guild_storage)); //clean up memory
- p->storage_amount = 0;
- p->guild_id = guild_id;
-
- // storage {`guild_id`/`id`/`nameid`/`amount`/`equip`/`identify`/`refine`/`attribute`/`card0`/`card1`/`card2`/`card3`}
- StringBuf_Init(&buf);
- StringBuf_AppendStr(&buf, "SELECT `id`,`nameid`,`amount`,`equip`,`identify`,`refine`,`attribute`");
- for (j = 0; j < MAX_SLOTS; ++j)
- StringBuf_Printf(&buf, ",`card%d`", j);
- StringBuf_Printf(&buf, " FROM `%s` WHERE `guild_id`='%d' ORDER BY `nameid`", guild_storage_db, guild_id);
-
- if (SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf)))
- Sql_ShowDebug(sql_handle);
-
- StringBuf_Destroy(&buf);
-
- for (i = 0; i < MAX_GUILD_STORAGE && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i) {
- item = &p->items[i];
- Sql_GetData(sql_handle, 0, &data, NULL);
- item->id = atoi(data);
- Sql_GetData(sql_handle, 1, &data, NULL);
- item->nameid = atoi(data);
- Sql_GetData(sql_handle, 2, &data, NULL);
- item->amount = atoi(data);
- Sql_GetData(sql_handle, 3, &data, NULL);
- item->equip = atoi(data);
- Sql_GetData(sql_handle, 4, &data, NULL);
- item->identify = atoi(data);
- Sql_GetData(sql_handle, 5, &data, NULL);
- item->refine = atoi(data);
- Sql_GetData(sql_handle, 6, &data, NULL);
- item->attribute = atoi(data);
- item->expire_time = 0;
- for (j = 0; j < MAX_SLOTS; ++j) {
- Sql_GetData(sql_handle, 7+j, &data, NULL);
- item->card[j] = atoi(data);
- }
- }
- p->storage_amount = i;
- Sql_FreeResult(sql_handle);
-
- ShowInfo("guild storage load complete from DB - id: %d (total: %d)\n", guild_id, p->storage_amount);
- return 0;
+ StringBuf buf;
+ struct item* item;
+ char* data;
+ int i;
+ int j;
+
+ memset(p, 0, sizeof(struct guild_storage)); //clean up memory
+ p->storage_amount = 0;
+ p->guild_id = guild_id;
+
+ // storage {`guild_id`/`id`/`nameid`/`amount`/`equip`/`identify`/`refine`/`attribute`/`card0`/`card1`/`card2`/`card3`}
+ StringBuf_Init(&buf);
+ StringBuf_AppendStr(&buf, "SELECT `id`,`nameid`,`amount`,`equip`,`identify`,`refine`,`attribute`");
+ for( j = 0; j < MAX_SLOTS; ++j )
+ StringBuf_Printf(&buf, ",`card%d`", j);
+ StringBuf_Printf(&buf, " FROM `%s` WHERE `guild_id`='%d' ORDER BY `nameid`", guild_storage_db, guild_id);
+
+ if( SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf)) )
+ Sql_ShowDebug(sql_handle);
+
+ StringBuf_Destroy(&buf);
+
+ for( i = 0; i < MAX_GUILD_STORAGE && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
+ {
+ item = &p->items[i];
+ Sql_GetData(sql_handle, 0, &data, NULL); item->id = atoi(data);
+ Sql_GetData(sql_handle, 1, &data, NULL); item->nameid = atoi(data);
+ Sql_GetData(sql_handle, 2, &data, NULL); item->amount = atoi(data);
+ Sql_GetData(sql_handle, 3, &data, NULL); item->equip = atoi(data);
+ Sql_GetData(sql_handle, 4, &data, NULL); item->identify = atoi(data);
+ Sql_GetData(sql_handle, 5, &data, NULL); item->refine = atoi(data);
+ Sql_GetData(sql_handle, 6, &data, NULL); item->attribute = atoi(data);
+ item->expire_time = 0;
+ for( j = 0; j < MAX_SLOTS; ++j )
+ {
+ Sql_GetData(sql_handle, 7+j, &data, NULL); item->card[j] = atoi(data);
+ }
+ }
+ p->storage_amount = i;
+ Sql_FreeResult(sql_handle);
+
+ ShowInfo("guild storage load complete from DB - id: %d (total: %d)\n", guild_id, p->storage_amount);
+ return 0;
}
//---------------------------------------------------------
// storage data initialize
int inter_storage_sql_init(void)
{
- return 1;
+ return 1;
}
// storage data finalize
void inter_storage_sql_final(void)
{
- return;
+ return;
}
// q?f[^?
int inter_storage_delete(int account_id)
{
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id`='%d'", storage_db, account_id))
- Sql_ShowDebug(sql_handle);
- return 0;
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id`='%d'", storage_db, account_id) )
+ Sql_ShowDebug(sql_handle);
+ return 0;
}
int inter_guild_storage_delete(int guild_id)
{
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id`='%d'", guild_storage_db, guild_id))
- Sql_ShowDebug(sql_handle);
- return 0;
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id`='%d'", guild_storage_db, guild_id) )
+ Sql_ShowDebug(sql_handle);
+ return 0;
}
//---------------------------------------------------------
@@ -171,38 +158,38 @@ int inter_guild_storage_delete(int guild_id)
int mapif_load_guild_storage(int fd,int account_id,int guild_id)
{
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `guild_id` FROM `%s` WHERE `guild_id`='%d'", guild_db, guild_id))
- Sql_ShowDebug(sql_handle);
- else if (Sql_NumRows(sql_handle) > 0) {
- // guild exists
- WFIFOHEAD(fd, sizeof(struct guild_storage)+12);
- WFIFOW(fd,0) = 0x3818;
- WFIFOW(fd,2) = sizeof(struct guild_storage)+12;
- WFIFOL(fd,4) = account_id;
- WFIFOL(fd,8) = guild_id;
- guild_storage_fromsql(guild_id, (struct guild_storage *)WFIFOP(fd,12));
- WFIFOSET(fd, WFIFOW(fd,2));
- return 0;
- }
- // guild does not exist
- Sql_FreeResult(sql_handle);
- WFIFOHEAD(fd, 12);
- WFIFOW(fd,0) = 0x3818;
- WFIFOW(fd,2) = 12;
- WFIFOL(fd,4) = account_id;
- WFIFOL(fd,8) = 0;
- WFIFOSET(fd, 12);
- return 0;
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `guild_id` FROM `%s` WHERE `guild_id`='%d'", guild_db, guild_id) )
+ Sql_ShowDebug(sql_handle);
+ else if( Sql_NumRows(sql_handle) > 0 )
+ {// guild exists
+ WFIFOHEAD(fd, sizeof(struct guild_storage)+12);
+ WFIFOW(fd,0) = 0x3818;
+ WFIFOW(fd,2) = sizeof(struct guild_storage)+12;
+ WFIFOL(fd,4) = account_id;
+ WFIFOL(fd,8) = guild_id;
+ guild_storage_fromsql(guild_id, (struct guild_storage*)WFIFOP(fd,12));
+ WFIFOSET(fd, WFIFOW(fd,2));
+ return 0;
+ }
+ // guild does not exist
+ Sql_FreeResult(sql_handle);
+ WFIFOHEAD(fd, 12);
+ WFIFOW(fd,0) = 0x3818;
+ WFIFOW(fd,2) = 12;
+ WFIFOL(fd,4) = account_id;
+ WFIFOL(fd,8) = 0;
+ WFIFOSET(fd, 12);
+ return 0;
}
int mapif_save_guild_storage_ack(int fd,int account_id,int guild_id,int fail)
{
- WFIFOHEAD(fd,11);
- WFIFOW(fd,0)=0x3819;
- WFIFOL(fd,2)=account_id;
- WFIFOL(fd,6)=guild_id;
- WFIFOB(fd,10)=fail;
- WFIFOSET(fd,11);
- return 0;
+ WFIFOHEAD(fd,11);
+ WFIFOW(fd,0)=0x3819;
+ WFIFOL(fd,2)=account_id;
+ WFIFOL(fd,6)=guild_id;
+ WFIFOB(fd,10)=fail;
+ WFIFOSET(fd,11);
+ return 0;
}
//---------------------------------------------------------
@@ -210,51 +197,50 @@ int mapif_save_guild_storage_ack(int fd,int account_id,int guild_id,int fail)
int mapif_parse_LoadGuildStorage(int fd)
{
- RFIFOHEAD(fd);
- mapif_load_guild_storage(fd,RFIFOL(fd,2),RFIFOL(fd,6));
- return 0;
+ RFIFOHEAD(fd);
+ mapif_load_guild_storage(fd,RFIFOL(fd,2),RFIFOL(fd,6));
+ return 0;
}
int mapif_parse_SaveGuildStorage(int fd)
{
- int guild_id;
- int len;
-
- RFIFOHEAD(fd);
- guild_id = RFIFOL(fd,8);
- len = RFIFOW(fd,2);
-
- if (sizeof(struct guild_storage) != len - 12) {
- ShowError("inter storage: data size error %d != %d\n", sizeof(struct guild_storage), len - 12);
- } else {
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `guild_id` FROM `%s` WHERE `guild_id`='%d'", guild_db, guild_id))
- Sql_ShowDebug(sql_handle);
- else if (Sql_NumRows(sql_handle) > 0) {
- // guild exists
- Sql_FreeResult(sql_handle);
- guild_storage_tosql(guild_id, (struct guild_storage *)RFIFOP(fd,12));
- mapif_save_guild_storage_ack(fd, RFIFOL(fd,4), guild_id, 0);
- return 0;
- }
- Sql_FreeResult(sql_handle);
- }
- mapif_save_guild_storage_ack(fd, RFIFOL(fd,4), guild_id, 1);
- return 0;
+ int guild_id;
+ int len;
+
+ RFIFOHEAD(fd);
+ guild_id = RFIFOL(fd,8);
+ len = RFIFOW(fd,2);
+
+ if( sizeof(struct guild_storage) != len - 12 )
+ {
+ ShowError("inter storage: data size error %d != %d\n", sizeof(struct guild_storage), len - 12);
+ }
+ else
+ {
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `guild_id` FROM `%s` WHERE `guild_id`='%d'", guild_db, guild_id) )
+ Sql_ShowDebug(sql_handle);
+ else if( Sql_NumRows(sql_handle) > 0 )
+ {// guild exists
+ Sql_FreeResult(sql_handle);
+ guild_storage_tosql(guild_id, (struct guild_storage*)RFIFOP(fd,12));
+ mapif_save_guild_storage_ack(fd, RFIFOL(fd,4), guild_id, 0);
+ return 0;
+ }
+ Sql_FreeResult(sql_handle);
+ }
+ mapif_save_guild_storage_ack(fd, RFIFOL(fd,4), guild_id, 1);
+ return 0;
}
int inter_storage_parse_frommap(int fd)
{
- RFIFOHEAD(fd);
- switch (RFIFOW(fd,0)) {
- case 0x3018:
- mapif_parse_LoadGuildStorage(fd);
- break;
- case 0x3019:
- mapif_parse_SaveGuildStorage(fd);
- break;
- default:
- return 0;
- }
- return 1;
+ RFIFOHEAD(fd);
+ switch(RFIFOW(fd,0)){
+ case 0x3018: mapif_parse_LoadGuildStorage(fd); break;
+ case 0x3019: mapif_parse_SaveGuildStorage(fd); break;
+ default:
+ return 0;
+ }
+ return 1;
}
diff --git a/src/char/int_storage.h b/src/char/int_storage.h
index 6285a8d21..811608f82 100644
--- a/src/char/int_storage.h
+++ b/src/char/int_storage.h
@@ -15,7 +15,7 @@ int inter_guild_storage_delete(int guild_id);
int inter_storage_parse_frommap(int fd);
//Exported for use in the TXT-SQL converter.
-int storage_fromsql(int account_id, struct storage_data *p);
+int storage_fromsql(int account_id, struct storage_data* p);
int storage_tosql(int account_id,struct storage_data *p);
int guild_storage_tosql(int guild_id, struct guild_storage *p);
diff --git a/src/char/inter.c b/src/char/inter.c
index 9b33d271e..8863b41d8 100644
--- a/src/char/inter.c
+++ b/src/char/inter.c
@@ -28,11 +28,11 @@
#include <sys/stat.h> // for stat/lstat/fstat - [Dekamaster/Ultimate GM Tool]
-#define WISDATA_TTL (60*1000) //Wis data Time To Live (60 seconds)
-#define WISDELLIST_MAX 256 // Number of elements in the list Delete data Wis
+#define WISDATA_TTL (60*1000) //Wis data Time To Live (60 seconds)
+#define WISDELLIST_MAX 256 // Number of elements in the list Delete data Wis
-Sql *sql_handle = NULL;
+Sql* sql_handle = NULL;
int char_server_port = 3306;
char char_server_ip[32] = "127.0.0.1";
@@ -47,800 +47,778 @@ char main_chat_nick[16] = "Main";
// recv. packet list
int inter_recv_packet_length[] = {
- -1,-1, 7,-1, -1,13,36, (2 + 4 + 4 + 4 + NAME_LENGTH), 0, 0, 0, 0, 0, 0, 0, 0, // 3000-
- 6,-1, 0, 0, 0, 0, 0, 0, 10,-1, 0, 0, 0, 0, 0, 0, // 3010-
- -1,10,-1,14, 14,19, 6,-1, 14,14, 0, 0, 0, 0, 0, 0, // 3020- Party
- -1, 6,-1,-1, 55,19, 6,-1, 14,-1,-1,-1, 18,19,186,-1, // 3030-
- -1, 9, 0, 0, 0, 0, 0, 0, 7, 6,10,10, 10,-1, 0, 0, // 3040-
- -1,-1,10,10, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3050- Auction System [Zephyrus]
- 6,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3060- Quest system [Kevin] [Inkfish]
- -1,10, 6,-1, 0, 0, 0, 0, 0, 0, 0, 0, -1,10, 6,-1, // 3070- Mercenary packets [Zephyrus], Elemental packets [pakpil]
- 48,14,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3080-
- -1,10,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3090- Homunculus packets [albator]
+ -1,-1, 7,-1, -1,13,36, (2 + 4 + 4 + 4 + NAME_LENGTH), 0, 0, 0, 0, 0, 0, 0, 0, // 3000-
+ 6,-1, 0, 0, 0, 0, 0, 0, 10,-1, 0, 0, 0, 0, 0, 0, // 3010-
+ -1,10,-1,14, 14,19, 6,-1, 14,14, 0, 0, 0, 0, 0, 0, // 3020- Party
+ -1, 6,-1,-1, 55,19, 6,-1, 14,-1,-1,-1, 18,19,186,-1, // 3030-
+ -1, 9, 0, 0, 0, 0, 0, 0, 7, 6,10,10, 10,-1, 0, 0, // 3040-
+ -1,-1,10,10, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3050- Auction System [Zephyrus]
+ 6,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3060- Quest system [Kevin] [Inkfish]
+ -1,10, 6,-1, 0, 0, 0, 0, 0, 0, 0, 0, -1,10, 6,-1, // 3070- Mercenary packets [Zephyrus], Elemental packets [pakpil]
+ 48,14,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3080-
+ -1,10,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3090- Homunculus packets [albator]
};
struct WisData {
- int id, fd, count, len;
- unsigned long tick;
- unsigned char src[24], dst[24], msg[512];
+ int id, fd, count, len;
+ unsigned long tick;
+ unsigned char src[24], dst[24], msg[512];
};
-static DBMap *wis_db = NULL; // int wis_id -> struct WisData*
+static DBMap* wis_db = NULL; // int wis_id -> struct WisData*
static int wis_dellist[WISDELLIST_MAX], wis_delnum;
#define MAX_JOB_NAMES 106
-static char *msg_table[MAX_JOB_NAMES]; // messages 550 ~ 655 are job names
+static char* msg_table[MAX_JOB_NAMES]; // messages 550 ~ 655 are job names
-const char *msg_txt(int msg_number)
-{
- msg_number -= 550;
- if (msg_number >= 0 && msg_number < MAX_JOB_NAMES &&
- msg_table[msg_number] != NULL && msg_table[msg_number][0] != '\0')
- return msg_table[msg_number];
+const char* msg_txt(int msg_number) {
+ msg_number -= 550;
+ if (msg_number >= 0 && msg_number < MAX_JOB_NAMES &&
+ msg_table[msg_number] != NULL && msg_table[msg_number][0] != '\0')
+ return msg_table[msg_number];
- return "Unknown";
+ return "Unknown";
}
/*==========================================
* Read Message Data -- at char server we only keep job names.
*------------------------------------------*/
-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) {
- ShowError("Messages file not found: %s\n", cfgName);
- return 1;
- }
-
- if ((--called) == 0)
- memset(msg_table, 0, sizeof(msg_table[0]) * MAX_JOB_NAMES);
-
- while (fgets(line, sizeof(line), fp)) {
- if (line[0] == '/' && line[1] == '/')
- continue;
- if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) != 2)
- continue;
-
- if (strcmpi(w1, "import") == 0)
- msg_config_read(w2);
- else {
- msg_number = atoi(w1);
- if (msg_number < 550 || msg_number > (550+MAX_JOB_NAMES))
- continue;
- msg_number -= 550;
- if (msg_number >= 0 && msg_number < MAX_JOB_NAMES) {
- if (msg_table[msg_number] != NULL)
- aFree(msg_table[msg_number]);
- msg_table[msg_number] = (char *)aMalloc((strlen(w2) + 1)*sizeof(char));
- strcpy(msg_table[msg_number],w2);
- }
- }
- }
-
- fclose(fp);
-
- return 0;
+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) {
+ ShowError("Messages file not found: %s\n", cfgName);
+ return 1;
+ }
+
+ if ((--called) == 0)
+ memset(msg_table, 0, sizeof(msg_table[0]) * MAX_JOB_NAMES);
+
+ while(fgets(line, sizeof(line), fp) ) {
+ if (line[0] == '/' && line[1] == '/')
+ continue;
+ if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) != 2)
+ continue;
+
+ if (strcmpi(w1, "import") == 0)
+ msg_config_read(w2);
+ else {
+ msg_number = atoi(w1);
+ if( msg_number < 550 || msg_number > (550+MAX_JOB_NAMES) )
+ continue;
+ msg_number -= 550;
+ if (msg_number >= 0 && msg_number < MAX_JOB_NAMES) {
+ if (msg_table[msg_number] != NULL)
+ aFree(msg_table[msg_number]);
+ msg_table[msg_number] = (char *)aMalloc((strlen(w2) + 1)*sizeof (char));
+ strcpy(msg_table[msg_number],w2);
+ }
+ }
+ }
+
+ fclose(fp);
+
+ return 0;
}
/*==========================================
* Cleanup Message Data
*------------------------------------------*/
-void do_final_msg(void)
-{
- int i;
- for (i = 0; i < MAX_JOB_NAMES; i++)
- aFree(msg_table[i]);
+void do_final_msg(void) {
+ int i;
+ for (i = 0; i < MAX_JOB_NAMES; i++)
+ aFree(msg_table[i]);
}
/* from pc.c due to @accinfo. any ideas to replace this crap are more than welcome. */
-const char *job_name(int class_)
-{
- switch (class_) {
- case JOB_NOVICE:
- case JOB_SWORDMAN:
- case JOB_MAGE:
- case JOB_ARCHER:
- case JOB_ACOLYTE:
- case JOB_MERCHANT:
- case JOB_THIEF:
- return msg_txt(550 - JOB_NOVICE+class_);
-
- case JOB_KNIGHT:
- case JOB_PRIEST:
- case JOB_WIZARD:
- case JOB_BLACKSMITH:
- case JOB_HUNTER:
- case JOB_ASSASSIN:
- return msg_txt(557 - JOB_KNIGHT+class_);
-
- case JOB_KNIGHT2:
- return msg_txt(557);
-
- case JOB_CRUSADER:
- case JOB_MONK:
- case JOB_SAGE:
- case JOB_ROGUE:
- case JOB_ALCHEMIST:
- case JOB_BARD:
- case JOB_DANCER:
- return msg_txt(563 - JOB_CRUSADER+class_);
-
- case JOB_CRUSADER2:
- return msg_txt(563);
-
- case JOB_WEDDING:
- case JOB_SUPER_NOVICE:
- case JOB_GUNSLINGER:
- case JOB_NINJA:
- case JOB_XMAS:
- return msg_txt(570 - JOB_WEDDING+class_);
-
- case JOB_SUMMER:
- return msg_txt(621);
-
- case JOB_NOVICE_HIGH:
- case JOB_SWORDMAN_HIGH:
- case JOB_MAGE_HIGH:
- case JOB_ARCHER_HIGH:
- case JOB_ACOLYTE_HIGH:
- case JOB_MERCHANT_HIGH:
- case JOB_THIEF_HIGH:
- return msg_txt(575 - JOB_NOVICE_HIGH+class_);
-
- case JOB_LORD_KNIGHT:
- case JOB_HIGH_PRIEST:
- case JOB_HIGH_WIZARD:
- case JOB_WHITESMITH:
- case JOB_SNIPER:
- case JOB_ASSASSIN_CROSS:
- return msg_txt(582 - JOB_LORD_KNIGHT+class_);
-
- case JOB_LORD_KNIGHT2:
- return msg_txt(582);
-
- case JOB_PALADIN:
- case JOB_CHAMPION:
- case JOB_PROFESSOR:
- case JOB_STALKER:
- case JOB_CREATOR:
- case JOB_CLOWN:
- case JOB_GYPSY:
- return msg_txt(588 - JOB_PALADIN + class_);
-
- case JOB_PALADIN2:
- return msg_txt(588);
-
- case JOB_BABY:
- case JOB_BABY_SWORDMAN:
- case JOB_BABY_MAGE:
- case JOB_BABY_ARCHER:
- case JOB_BABY_ACOLYTE:
- case JOB_BABY_MERCHANT:
- case JOB_BABY_THIEF:
- return msg_txt(595 - JOB_BABY + class_);
-
- case JOB_BABY_KNIGHT:
- case JOB_BABY_PRIEST:
- case JOB_BABY_WIZARD:
- case JOB_BABY_BLACKSMITH:
- case JOB_BABY_HUNTER:
- case JOB_BABY_ASSASSIN:
- return msg_txt(602 - JOB_BABY_KNIGHT + class_);
-
- case JOB_BABY_KNIGHT2:
- return msg_txt(602);
-
- case JOB_BABY_CRUSADER:
- case JOB_BABY_MONK:
- case JOB_BABY_SAGE:
- case JOB_BABY_ROGUE:
- case JOB_BABY_ALCHEMIST:
- case JOB_BABY_BARD:
- case JOB_BABY_DANCER:
- return msg_txt(608 - JOB_BABY_CRUSADER + class_);
-
- case JOB_BABY_CRUSADER2:
- return msg_txt(608);
-
- case JOB_SUPER_BABY:
- return msg_txt(615);
-
- case JOB_TAEKWON:
- return msg_txt(616);
- case JOB_STAR_GLADIATOR:
- case JOB_STAR_GLADIATOR2:
- return msg_txt(617);
- case JOB_SOUL_LINKER:
- return msg_txt(618);
-
- case JOB_GANGSI:
- case JOB_DEATH_KNIGHT:
- case JOB_DARK_COLLECTOR:
- return msg_txt(622 - JOB_GANGSI+class_);
-
- case JOB_RUNE_KNIGHT:
- case JOB_WARLOCK:
- case JOB_RANGER:
- case JOB_ARCH_BISHOP:
- case JOB_MECHANIC:
- case JOB_GUILLOTINE_CROSS:
- return msg_txt(625 - JOB_RUNE_KNIGHT+class_);
-
- case JOB_RUNE_KNIGHT_T:
- case JOB_WARLOCK_T:
- case JOB_RANGER_T:
- case JOB_ARCH_BISHOP_T:
- case JOB_MECHANIC_T:
- case JOB_GUILLOTINE_CROSS_T:
- return msg_txt(625 - JOB_RUNE_KNIGHT_T+class_);
-
- case JOB_ROYAL_GUARD:
- case JOB_SORCERER:
- case JOB_MINSTREL:
- case JOB_WANDERER:
- case JOB_SURA:
- case JOB_GENETIC:
- case JOB_SHADOW_CHASER:
- return msg_txt(631 - JOB_ROYAL_GUARD+class_);
-
- case JOB_ROYAL_GUARD_T:
- case JOB_SORCERER_T:
- case JOB_MINSTREL_T:
- case JOB_WANDERER_T:
- case JOB_SURA_T:
- case JOB_GENETIC_T:
- case JOB_SHADOW_CHASER_T:
- return msg_txt(631 - JOB_ROYAL_GUARD_T+class_);
-
- case JOB_RUNE_KNIGHT2:
- case JOB_RUNE_KNIGHT_T2:
- return msg_txt(625);
-
- case JOB_ROYAL_GUARD2:
- case JOB_ROYAL_GUARD_T2:
- return msg_txt(631);
-
- case JOB_RANGER2:
- case JOB_RANGER_T2:
- return msg_txt(627);
-
- case JOB_MECHANIC2:
- case JOB_MECHANIC_T2:
- return msg_txt(629);
-
- case JOB_BABY_RUNE:
- case JOB_BABY_WARLOCK:
- case JOB_BABY_RANGER:
- case JOB_BABY_BISHOP:
- case JOB_BABY_MECHANIC:
- case JOB_BABY_CROSS:
- case JOB_BABY_GUARD:
- case JOB_BABY_SORCERER:
- case JOB_BABY_MINSTREL:
- case JOB_BABY_WANDERER:
- case JOB_BABY_SURA:
- case JOB_BABY_GENETIC:
- case JOB_BABY_CHASER:
- return msg_txt(638 - JOB_BABY_RUNE+class_);
-
- case JOB_BABY_RUNE2:
- return msg_txt(638);
-
- case JOB_BABY_GUARD2:
- return msg_txt(644);
-
- case JOB_BABY_RANGER2:
- return msg_txt(640);
-
- case JOB_BABY_MECHANIC2:
- return msg_txt(642);
-
- case JOB_SUPER_NOVICE_E:
- case JOB_SUPER_BABY_E:
- return msg_txt(651 - JOB_SUPER_NOVICE_E+class_);
-
- case JOB_KAGEROU:
- case JOB_OBORO:
- return msg_txt(653 - JOB_KAGEROU+class_);
-
- default:
- return msg_txt(655);
- }
+const char* job_name(int class_) {
+ switch (class_) {
+ case JOB_NOVICE:
+ case JOB_SWORDMAN:
+ case JOB_MAGE:
+ case JOB_ARCHER:
+ case JOB_ACOLYTE:
+ case JOB_MERCHANT:
+ case JOB_THIEF:
+ return msg_txt(550 - JOB_NOVICE+class_);
+
+ case JOB_KNIGHT:
+ case JOB_PRIEST:
+ case JOB_WIZARD:
+ case JOB_BLACKSMITH:
+ case JOB_HUNTER:
+ case JOB_ASSASSIN:
+ return msg_txt(557 - JOB_KNIGHT+class_);
+
+ case JOB_KNIGHT2:
+ return msg_txt(557);
+
+ case JOB_CRUSADER:
+ case JOB_MONK:
+ case JOB_SAGE:
+ case JOB_ROGUE:
+ case JOB_ALCHEMIST:
+ case JOB_BARD:
+ case JOB_DANCER:
+ return msg_txt(563 - JOB_CRUSADER+class_);
+
+ case JOB_CRUSADER2:
+ return msg_txt(563);
+
+ case JOB_WEDDING:
+ case JOB_SUPER_NOVICE:
+ case JOB_GUNSLINGER:
+ case JOB_NINJA:
+ case JOB_XMAS:
+ return msg_txt(570 - JOB_WEDDING+class_);
+
+ case JOB_SUMMER:
+ return msg_txt(621);
+
+ case JOB_NOVICE_HIGH:
+ case JOB_SWORDMAN_HIGH:
+ case JOB_MAGE_HIGH:
+ case JOB_ARCHER_HIGH:
+ case JOB_ACOLYTE_HIGH:
+ case JOB_MERCHANT_HIGH:
+ case JOB_THIEF_HIGH:
+ return msg_txt(575 - JOB_NOVICE_HIGH+class_);
+
+ case JOB_LORD_KNIGHT:
+ case JOB_HIGH_PRIEST:
+ case JOB_HIGH_WIZARD:
+ case JOB_WHITESMITH:
+ case JOB_SNIPER:
+ case JOB_ASSASSIN_CROSS:
+ return msg_txt(582 - JOB_LORD_KNIGHT+class_);
+
+ case JOB_LORD_KNIGHT2:
+ return msg_txt(582);
+
+ case JOB_PALADIN:
+ case JOB_CHAMPION:
+ case JOB_PROFESSOR:
+ case JOB_STALKER:
+ case JOB_CREATOR:
+ case JOB_CLOWN:
+ case JOB_GYPSY:
+ return msg_txt(588 - JOB_PALADIN + class_);
+
+ case JOB_PALADIN2:
+ return msg_txt(588);
+
+ case JOB_BABY:
+ case JOB_BABY_SWORDMAN:
+ case JOB_BABY_MAGE:
+ case JOB_BABY_ARCHER:
+ case JOB_BABY_ACOLYTE:
+ case JOB_BABY_MERCHANT:
+ case JOB_BABY_THIEF:
+ return msg_txt(595 - JOB_BABY + class_);
+
+ case JOB_BABY_KNIGHT:
+ case JOB_BABY_PRIEST:
+ case JOB_BABY_WIZARD:
+ case JOB_BABY_BLACKSMITH:
+ case JOB_BABY_HUNTER:
+ case JOB_BABY_ASSASSIN:
+ return msg_txt(602 - JOB_BABY_KNIGHT + class_);
+
+ case JOB_BABY_KNIGHT2:
+ return msg_txt(602);
+
+ case JOB_BABY_CRUSADER:
+ case JOB_BABY_MONK:
+ case JOB_BABY_SAGE:
+ case JOB_BABY_ROGUE:
+ case JOB_BABY_ALCHEMIST:
+ case JOB_BABY_BARD:
+ case JOB_BABY_DANCER:
+ return msg_txt(608 - JOB_BABY_CRUSADER + class_);
+
+ case JOB_BABY_CRUSADER2:
+ return msg_txt(608);
+
+ case JOB_SUPER_BABY:
+ return msg_txt(615);
+
+ case JOB_TAEKWON:
+ return msg_txt(616);
+ case JOB_STAR_GLADIATOR:
+ case JOB_STAR_GLADIATOR2:
+ return msg_txt(617);
+ case JOB_SOUL_LINKER:
+ return msg_txt(618);
+
+ case JOB_GANGSI:
+ case JOB_DEATH_KNIGHT:
+ case JOB_DARK_COLLECTOR:
+ return msg_txt(622 - JOB_GANGSI+class_);
+
+ case JOB_RUNE_KNIGHT:
+ case JOB_WARLOCK:
+ case JOB_RANGER:
+ case JOB_ARCH_BISHOP:
+ case JOB_MECHANIC:
+ case JOB_GUILLOTINE_CROSS:
+ return msg_txt(625 - JOB_RUNE_KNIGHT+class_);
+
+ case JOB_RUNE_KNIGHT_T:
+ case JOB_WARLOCK_T:
+ case JOB_RANGER_T:
+ case JOB_ARCH_BISHOP_T:
+ case JOB_MECHANIC_T:
+ case JOB_GUILLOTINE_CROSS_T:
+ return msg_txt(625 - JOB_RUNE_KNIGHT_T+class_);
+
+ case JOB_ROYAL_GUARD:
+ case JOB_SORCERER:
+ case JOB_MINSTREL:
+ case JOB_WANDERER:
+ case JOB_SURA:
+ case JOB_GENETIC:
+ case JOB_SHADOW_CHASER:
+ return msg_txt(631 - JOB_ROYAL_GUARD+class_);
+
+ case JOB_ROYAL_GUARD_T:
+ case JOB_SORCERER_T:
+ case JOB_MINSTREL_T:
+ case JOB_WANDERER_T:
+ case JOB_SURA_T:
+ case JOB_GENETIC_T:
+ case JOB_SHADOW_CHASER_T:
+ return msg_txt(631 - JOB_ROYAL_GUARD_T+class_);
+
+ case JOB_RUNE_KNIGHT2:
+ case JOB_RUNE_KNIGHT_T2:
+ return msg_txt(625);
+
+ case JOB_ROYAL_GUARD2:
+ case JOB_ROYAL_GUARD_T2:
+ return msg_txt(631);
+
+ case JOB_RANGER2:
+ case JOB_RANGER_T2:
+ return msg_txt(627);
+
+ case JOB_MECHANIC2:
+ case JOB_MECHANIC_T2:
+ return msg_txt(629);
+
+ case JOB_BABY_RUNE:
+ case JOB_BABY_WARLOCK:
+ case JOB_BABY_RANGER:
+ case JOB_BABY_BISHOP:
+ case JOB_BABY_MECHANIC:
+ case JOB_BABY_CROSS:
+ case JOB_BABY_GUARD:
+ case JOB_BABY_SORCERER:
+ case JOB_BABY_MINSTREL:
+ case JOB_BABY_WANDERER:
+ case JOB_BABY_SURA:
+ case JOB_BABY_GENETIC:
+ case JOB_BABY_CHASER:
+ return msg_txt(638 - JOB_BABY_RUNE+class_);
+
+ case JOB_BABY_RUNE2:
+ return msg_txt(638);
+
+ case JOB_BABY_GUARD2:
+ return msg_txt(644);
+
+ case JOB_BABY_RANGER2:
+ return msg_txt(640);
+
+ case JOB_BABY_MECHANIC2:
+ return msg_txt(642);
+
+ case JOB_SUPER_NOVICE_E:
+ case JOB_SUPER_BABY_E:
+ return msg_txt(651 - JOB_SUPER_NOVICE_E+class_);
+
+ case JOB_KAGEROU:
+ case JOB_OBORO:
+ return msg_txt(653 - JOB_KAGEROU+class_);
+
+ default:
+ return msg_txt(655);
+ }
}
/**
* [Dekamaster/Nightroad]
**/
-const char *geoip_countryname[253] = {"Unknown","Asia/Pacific Region","Europe","Andorra","United Arab Emirates","Afghanistan","Antigua and Barbuda","Anguilla","Albania","Armenia","Netherlands Antilles",
- "Angola","Antarctica","Argentina","American Samoa","Austria","Australia","Aruba","Azerbaijan","Bosnia and Herzegovina","Barbados",
- "Bangladesh","Belgium","Burkina Faso","Bulgaria","Bahrain","Burundi","Benin","Bermuda","Brunei Darussalam","Bolivia",
- "Brazil","Bahamas","Bhutan","Bouvet Island","Botswana","Belarus","Belize","Canada","Cocos (Keeling) Islands","Congo, The Democratic Republic of the",
- "Central African Republic","Congo","Switzerland","Cote D'Ivoire","Cook Islands","Chile","Cameroon","China","Colombia","Costa Rica",
- "Cuba","Cape Verde","Christmas Island","Cyprus","Czech Republic","Germany","Djibouti","Denmark","Dominica","Dominican Republic",
- "Algeria","Ecuador","Estonia","Egypt","Western Sahara","Eritrea","Spain","Ethiopia","Finland","Fiji",
- "Falkland Islands (Malvinas)","Micronesia, Federated States of","Faroe Islands","France","France, Metropolitan","Gabon","United Kingdom","Grenada","Georgia","French Guiana",
- "Ghana","Gibraltar","Greenland","Gambia","Guinea","Guadeloupe","Equatorial Guinea","Greece","South Georgia and the South Sandwich Islands","Guatemala",
- "Guam","Guinea-Bissau","Guyana","Hong Kong","Heard Island and McDonald Islands","Honduras","Croatia","Haiti","Hungary","Indonesia",
- "Ireland","Israel","India","British Indian Ocean Territory","Iraq","Iran, Islamic Republic of","Iceland","Italy","Jamaica","Jordan",
- "Japan","Kenya","Kyrgyzstan","Cambodia","Kiribati","Comoros","Saint Kitts and Nevis","Korea, Democratic People's Republic of","Korea, Republic of","Kuwait",
- "Cayman Islands","Kazakhstan","Lao People's Democratic Republic","Lebanon","Saint Lucia","Liechtenstein","Sri Lanka","Liberia","Lesotho","Lithuania",
- "Luxembourg","Latvia","Libyan Arab Jamahiriya","Morocco","Monaco","Moldova, Republic of","Madagascar","Marshall Islands","Macedonia","Mali",
- "Myanmar","Mongolia","Macau","Northern Mariana Islands","Martinique","Mauritania","Montserrat","Malta","Mauritius","Maldives",
- "Malawi","Mexico","Malaysia","Mozambique","Namibia","New Caledonia","Niger","Norfolk Island","Nigeria","Nicaragua",
- "Netherlands","Norway","Nepal","Nauru","Niue","New Zealand","Oman","Panama","Peru","French Polynesia",
- "Papua New Guinea","Philippines","Pakistan","Poland","Saint Pierre and Miquelon","Pitcairn Islands","Puerto Rico","Palestinian Territory","Portugal","Palau",
- "Paraguay","Qatar","Reunion","Romania","Russian Federation","Rwanda","Saudi Arabia","Solomon Islands","Seychelles","Sudan",
- "Sweden","Singapore","Saint Helena","Slovenia","Svalbard and Jan Mayen","Slovakia","Sierra Leone","San Marino","Senegal","Somalia","Suriname",
- "Sao Tome and Principe","El Salvador","Syrian Arab Republic","Swaziland","Turks and Caicos Islands","Chad","French Southern Territories","Togo","Thailand",
- "Tajikistan","Tokelau","Turkmenistan","Tunisia","Tonga","Timor-Leste","Turkey","Trinidad and Tobago","Tuvalu","Taiwan",
- "Tanzania, United Republic of","Ukraine","Uganda","United States Minor Outlying Islands","United States","Uruguay","Uzbekistan","Holy See (Vatican City State)","Saint Vincent and the Grenadines","Venezuela",
- "Virgin Islands, British","Virgin Islands, U.S.","Vietnam","Vanuatu","Wallis and Futuna","Samoa","Yemen","Mayotte","Serbia","South Africa",
- "Zambia","Montenegro","Zimbabwe","Anonymous Proxy","Satellite Provider","Other","Aland Islands","Guernsey","Isle of Man","Jersey",
- "Saint Barthelemy","Saint Martin"
- };
+const char * geoip_countryname[253] = {"Unknown","Asia/Pacific Region","Europe","Andorra","United Arab Emirates","Afghanistan","Antigua and Barbuda","Anguilla","Albania","Armenia","Netherlands Antilles",
+ "Angola","Antarctica","Argentina","American Samoa","Austria","Australia","Aruba","Azerbaijan","Bosnia and Herzegovina","Barbados",
+ "Bangladesh","Belgium","Burkina Faso","Bulgaria","Bahrain","Burundi","Benin","Bermuda","Brunei Darussalam","Bolivia",
+ "Brazil","Bahamas","Bhutan","Bouvet Island","Botswana","Belarus","Belize","Canada","Cocos (Keeling) Islands","Congo, The Democratic Republic of the",
+ "Central African Republic","Congo","Switzerland","Cote D'Ivoire","Cook Islands","Chile","Cameroon","China","Colombia","Costa Rica",
+ "Cuba","Cape Verde","Christmas Island","Cyprus","Czech Republic","Germany","Djibouti","Denmark","Dominica","Dominican Republic",
+ "Algeria","Ecuador","Estonia","Egypt","Western Sahara","Eritrea","Spain","Ethiopia","Finland","Fiji",
+ "Falkland Islands (Malvinas)","Micronesia, Federated States of","Faroe Islands","France","France, Metropolitan","Gabon","United Kingdom","Grenada","Georgia","French Guiana",
+ "Ghana","Gibraltar","Greenland","Gambia","Guinea","Guadeloupe","Equatorial Guinea","Greece","South Georgia and the South Sandwich Islands","Guatemala",
+ "Guam","Guinea-Bissau","Guyana","Hong Kong","Heard Island and McDonald Islands","Honduras","Croatia","Haiti","Hungary","Indonesia",
+ "Ireland","Israel","India","British Indian Ocean Territory","Iraq","Iran, Islamic Republic of","Iceland","Italy","Jamaica","Jordan",
+ "Japan","Kenya","Kyrgyzstan","Cambodia","Kiribati","Comoros","Saint Kitts and Nevis","Korea, Democratic People's Republic of","Korea, Republic of","Kuwait",
+ "Cayman Islands","Kazakhstan","Lao People's Democratic Republic","Lebanon","Saint Lucia","Liechtenstein","Sri Lanka","Liberia","Lesotho","Lithuania",
+ "Luxembourg","Latvia","Libyan Arab Jamahiriya","Morocco","Monaco","Moldova, Republic of","Madagascar","Marshall Islands","Macedonia","Mali",
+ "Myanmar","Mongolia","Macau","Northern Mariana Islands","Martinique","Mauritania","Montserrat","Malta","Mauritius","Maldives",
+ "Malawi","Mexico","Malaysia","Mozambique","Namibia","New Caledonia","Niger","Norfolk Island","Nigeria","Nicaragua",
+ "Netherlands","Norway","Nepal","Nauru","Niue","New Zealand","Oman","Panama","Peru","French Polynesia",
+ "Papua New Guinea","Philippines","Pakistan","Poland","Saint Pierre and Miquelon","Pitcairn Islands","Puerto Rico","Palestinian Territory","Portugal","Palau",
+ "Paraguay","Qatar","Reunion","Romania","Russian Federation","Rwanda","Saudi Arabia","Solomon Islands","Seychelles","Sudan",
+ "Sweden","Singapore","Saint Helena","Slovenia","Svalbard and Jan Mayen","Slovakia","Sierra Leone","San Marino","Senegal","Somalia","Suriname",
+ "Sao Tome and Principe","El Salvador","Syrian Arab Republic","Swaziland","Turks and Caicos Islands","Chad","French Southern Territories","Togo","Thailand",
+ "Tajikistan","Tokelau","Turkmenistan","Tunisia","Tonga","Timor-Leste","Turkey","Trinidad and Tobago","Tuvalu","Taiwan",
+ "Tanzania, United Republic of","Ukraine","Uganda","United States Minor Outlying Islands","United States","Uruguay","Uzbekistan","Holy See (Vatican City State)","Saint Vincent and the Grenadines","Venezuela",
+ "Virgin Islands, British","Virgin Islands, U.S.","Vietnam","Vanuatu","Wallis and Futuna","Samoa","Yemen","Mayotte","Serbia","South Africa",
+ "Zambia","Montenegro","Zimbabwe","Anonymous Proxy","Satellite Provider","Other","Aland Islands","Guernsey","Isle of Man","Jersey",
+ "Saint Barthelemy","Saint Martin"};
unsigned char *geoip_cache;
-void geoip_readdb(void)
-{
- struct stat bufa;
- FILE *db=fopen("./db/GeoIP.dat","rb");
- fstat(fileno(db), &bufa);
- geoip_cache = (unsigned char *) malloc(sizeof(unsigned char) * bufa.st_size);
- if (fread(geoip_cache, sizeof(unsigned char), bufa.st_size, db) != bufa.st_size) {
- ShowError("geoip_cache reading didn't read all elements \n");
- }
- fclose(db);
- ShowStatus("Finished Reading "CL_GREEN"GeoIP"CL_RESET" Database.\n");
+void geoip_readdb(void){
+ struct stat bufa;
+ FILE *db=fopen("./db/GeoIP.dat","rb");
+ fstat(fileno(db), &bufa);
+ geoip_cache = (unsigned char *) malloc(sizeof(unsigned char) * bufa.st_size);
+ if(fread(geoip_cache, sizeof(unsigned char), bufa.st_size, db) != bufa.st_size) { ShowError("geoip_cache reading didn't read all elements \n"); }
+ fclose(db);
+ ShowStatus("Finished Reading "CL_GREEN"GeoIP"CL_RESET" Database.\n");
}
/* [Dekamaster/Nightroad] */
/* WHY NOT A DBMAP: There are millions of entries in GeoIP and it has its own algorithm to go quickly through them, a DBMap wouldn't be efficient */
-const char *geoip_getcountry(uint32 ipnum)
-{
- int depth;
- unsigned int x;
- const unsigned char *buf;
- unsigned int offset = 0;
-
- for (depth = 31; depth >= 0; depth--) {
- buf = geoip_cache + (long)6 *offset;
- if (ipnum & (1 << depth)) {
- /* Take the right-hand branch */
- x = (buf[3*1 + 0] << (0*8))
- + (buf[3*1 + 1] << (1*8))
- + (buf[3*1 + 2] << (2*8));
- } else {
- /* Take the left-hand branch */
- x = (buf[3*0 + 0] << (0*8))
- + (buf[3*0 + 1] << (1*8))
- + (buf[3*0 + 2] << (2*8));
- }
- if (x >= 16776960) {
- x=x-16776960;
- return geoip_countryname[x];
- }
- offset = x;
- }
- return geoip_countryname[0];
+const char* geoip_getcountry(uint32 ipnum){
+ int depth;
+ unsigned int x;
+ const unsigned char *buf;
+ unsigned int offset = 0;
+
+ for (depth = 31; depth >= 0; depth--) {
+ buf = geoip_cache + (long)6 *offset;
+ if (ipnum & (1 << depth)) {
+ /* Take the right-hand branch */
+ x = (buf[3*1 + 0] << (0*8))
+ + (buf[3*1 + 1] << (1*8))
+ + (buf[3*1 + 2] << (2*8));
+ } else {
+ /* Take the left-hand branch */
+ x = (buf[3*0 + 0] << (0*8))
+ + (buf[3*0 + 1] << (1*8))
+ + (buf[3*0 + 2] << (2*8));
+ }
+ if (x >= 16776960) {
+ x=x-16776960;
+ return geoip_countryname[x];
+ }
+ offset = x;
+ }
+ return geoip_countryname[0];
}
/* sends a mesasge to map server (fd) to a user (u_fd) although we use fd we keep aid for safe-check */
/* extremely handy I believe it will serve other uses in the near future */
-void inter_to_fd(int fd, int u_fd, int aid, char *msg, ...)
-{
- char msg_out[512];
- va_list ap;
- int len = 1;/* yes we start at 1 */
+void inter_to_fd(int fd, int u_fd, int aid, char* msg, ...) {
+ char msg_out[512];
+ va_list ap;
+ int len = 1;/* yes we start at 1 */
- va_start(ap,msg);
- len += vsnprintf(msg_out, 512, msg, ap);
- va_end(ap);
+ va_start(ap,msg);
+ len += vsnprintf(msg_out, 512, msg, ap);
+ va_end(ap);
- WFIFOHEAD(fd,12 + len);
+ WFIFOHEAD(fd,12 + len);
- WFIFOW(fd,0) = 0x3807;
- WFIFOW(fd,2) = 12 + (unsigned short)len;
- WFIFOL(fd,4) = u_fd;
- WFIFOL(fd,8) = aid;
- safestrncpy((char *)WFIFOP(fd,12), msg_out, len);
+ WFIFOW(fd,0) = 0x3807;
+ WFIFOW(fd,2) = 12 + (unsigned short)len;
+ WFIFOL(fd,4) = u_fd;
+ WFIFOL(fd,8) = aid;
+ safestrncpy((char*)WFIFOP(fd,12), msg_out, len);
- WFIFOSET(fd,12 + len);
+ WFIFOSET(fd,12 + len);
- return;
+ return;
}
/* [Dekamaster/Nightroad] */
-void mapif_parse_accinfo(int fd)
-{
- int u_fd = RFIFOL(fd,2), aid = RFIFOL(fd,6), castergroup = RFIFOL(fd,10);
- char query[NAME_LENGTH], query_esq[NAME_LENGTH*2+1];
- int account_id;
- char *data;
-
- safestrncpy(query, (char *) RFIFOP(fd,14), NAME_LENGTH);
-
- Sql_EscapeString(sql_handle, query_esq, query);
-
- account_id = atoi(query);
-
- if (account_id < START_ACCOUNT_NUM) { // is string
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`name`,`class`,`base_level`,`job_level`,`online` FROM `char` WHERE `name` LIKE '%s' LIMIT 10", query_esq)
- || Sql_NumRows(sql_handle) == 0) {
- if (Sql_NumRows(sql_handle) == 0) {
- inter_to_fd(fd, u_fd, aid, "No matches were found for your criteria, '%s'",query);
- } else {
- Sql_ShowDebug(sql_handle);
- inter_to_fd(fd, u_fd, aid, "An error occured, bother your admin about it.");
- }
- Sql_FreeResult(sql_handle);
- return;
- } else {
- if (Sql_NumRows(sql_handle) == 1) { //we found a perfect match
- Sql_NextRow(sql_handle);
- Sql_GetData(sql_handle, 0, &data, NULL);
- account_id = atoi(data);
- Sql_FreeResult(sql_handle);
- } else {// more than one, listing... [Dekamaster/Nightroad]
- inter_to_fd(fd, u_fd, aid, "Your query returned the following %d results, please be more specific...",(int)Sql_NumRows(sql_handle));
- while (SQL_SUCCESS == Sql_NextRow(sql_handle)) {
- int class_;
- short base_level, job_level, online;
- char name[NAME_LENGTH];
-
- Sql_GetData(sql_handle, 0, &data, NULL);
- account_id = atoi(data);
- Sql_GetData(sql_handle, 1, &data, NULL);
- safestrncpy(name, data, sizeof(name));
- Sql_GetData(sql_handle, 2, &data, NULL);
- class_ = atoi(data);
- Sql_GetData(sql_handle, 3, &data, NULL);
- base_level = atoi(data);
- Sql_GetData(sql_handle, 4, &data, NULL);
- job_level = atoi(data);
- Sql_GetData(sql_handle, 5, &data, NULL);
- online = atoi(data);
-
- inter_to_fd(fd, u_fd, aid, "[AID: %d] %s | %s | Level: %d/%d | %s", account_id, name, job_name(class_), base_level, job_level, online?"Online":"Offline");
- }
- Sql_FreeResult(sql_handle);
- return;
- }
- }
- }
-
- /* it will only get here if we have a single match */
- if (account_id) {
- char userid[NAME_LENGTH], user_pass[NAME_LENGTH], email[40], last_ip[20], lastlogin[30];
- short level = -1;
- int logincount = 0,state = 0;
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `userid`, `user_pass`, `email`, `last_ip`, `group_id`, `lastlogin`, `logincount`, `state` FROM `login` WHERE `account_id` = '%d' LIMIT 1", account_id)
- || Sql_NumRows(sql_handle) == 0) {
- if (Sql_NumRows(sql_handle) == 0) {
- inter_to_fd(fd, u_fd, aid, "No account with ID '%d' was found.", account_id);
- } else {
- inter_to_fd(fd, u_fd, aid, "An error occured, bother your admin about it.");
- Sql_ShowDebug(sql_handle);
- }
- } else {
- Sql_NextRow(sql_handle);
- Sql_GetData(sql_handle, 0, &data, NULL);
- safestrncpy(userid, data, sizeof(userid));
- Sql_GetData(sql_handle, 1, &data, NULL);
- safestrncpy(user_pass, data, sizeof(user_pass));
- Sql_GetData(sql_handle, 2, &data, NULL);
- safestrncpy(email, data, sizeof(email));
- Sql_GetData(sql_handle, 3, &data, NULL);
- safestrncpy(last_ip, data, sizeof(last_ip));
- Sql_GetData(sql_handle, 4, &data, NULL);
- level = atoi(data);
- Sql_GetData(sql_handle, 5, &data, NULL);
- safestrncpy(lastlogin, data, sizeof(lastlogin));
- Sql_GetData(sql_handle, 6, &data, NULL);
- logincount = atoi(data);
- Sql_GetData(sql_handle, 7, &data, NULL);
- state = atoi(data);
- }
-
- Sql_FreeResult(sql_handle);
-
- if (level == -1)
- return;
-
- inter_to_fd(fd, u_fd, aid, "-- Account %d --", account_id);
- inter_to_fd(fd, u_fd, aid, "User: %s | GM Group: %d | State: %d", userid, level, state);
-
- if (level < castergroup) /* only show pass if your gm level is greater than the one you're searching for */
- inter_to_fd(fd, u_fd, aid, "Password: %s", user_pass);
-
- inter_to_fd(fd, u_fd, aid, "Account e-mail: %s", email);
- inter_to_fd(fd, u_fd, aid, "Last IP: %s (%s)", last_ip, geoip_getcountry(str2ip(last_ip)));
- inter_to_fd(fd, u_fd, aid, "This user has logged %d times, the last time were at %s", logincount, lastlogin);
- inter_to_fd(fd, u_fd, aid, "-- Character Details --");
-
-
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `char_id`, `name`, `char_num`, `class`, `base_level`, `job_level`, `online` FROM `char` WHERE `account_id` = '%d' ORDER BY `char_num` LIMIT %d", account_id, MAX_CHARS)
- || Sql_NumRows(sql_handle) == 0) {
-
- if (Sql_NumRows(sql_handle) == 0)
- inter_to_fd(fd, u_fd, aid,"This account doesn't have characters.");
- else {
- inter_to_fd(fd, u_fd, aid,"An error occured, bother your admin about it.");
- Sql_ShowDebug(sql_handle);
- }
-
- } else {
- while (SQL_SUCCESS == Sql_NextRow(sql_handle)) {
- int char_id, class_;
- short char_num, base_level, job_level, online;
- char name[NAME_LENGTH];
-
- Sql_GetData(sql_handle, 0, &data, NULL);
- char_id = atoi(data);
- Sql_GetData(sql_handle, 1, &data, NULL);
- safestrncpy(name, data, sizeof(name));
- Sql_GetData(sql_handle, 2, &data, NULL);
- char_num = atoi(data);
- Sql_GetData(sql_handle, 3, &data, NULL);
- class_ = atoi(data);
- Sql_GetData(sql_handle, 4, &data, NULL);
- base_level = atoi(data);
- Sql_GetData(sql_handle, 5, &data, NULL);
- job_level = atoi(data);
- Sql_GetData(sql_handle, 6, &data, NULL);
- online = atoi(data);
-
- inter_to_fd(fd, u_fd, aid, "[Slot/CID: %d/%d] %s | %s | Level: %d/%d | %s", char_num, char_id, name, job_name(class_), base_level, job_level, online?"On":"Off");
- }
- }
- Sql_FreeResult(sql_handle);
- }
-
- return;
+void mapif_parse_accinfo(int fd) {
+ int u_fd = RFIFOL(fd,2), aid = RFIFOL(fd,6), castergroup = RFIFOL(fd,10);
+ char query[NAME_LENGTH], query_esq[NAME_LENGTH*2+1];
+ int account_id;
+ char *data;
+
+ safestrncpy(query, (char*) RFIFOP(fd,14), NAME_LENGTH);
+
+ Sql_EscapeString(sql_handle, query_esq, query);
+
+ account_id = atoi(query);
+
+ if (account_id < START_ACCOUNT_NUM) { // is string
+ if ( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`name`,`class`,`base_level`,`job_level`,`online` FROM `char` WHERE `name` LIKE '%s' LIMIT 10", query_esq)
+ || Sql_NumRows(sql_handle) == 0 ) {
+ if( Sql_NumRows(sql_handle) == 0 ) {
+ inter_to_fd(fd, u_fd, aid, "No matches were found for your criteria, '%s'",query);
+ } else {
+ Sql_ShowDebug(sql_handle);
+ inter_to_fd(fd, u_fd, aid, "An error occured, bother your admin about it.");
+ }
+ Sql_FreeResult(sql_handle);
+ return;
+ } else {
+ if( Sql_NumRows(sql_handle) == 1 ) {//we found a perfect match
+ Sql_NextRow(sql_handle);
+ Sql_GetData(sql_handle, 0, &data, NULL); account_id = atoi(data);
+ Sql_FreeResult(sql_handle);
+ } else {// more than one, listing... [Dekamaster/Nightroad]
+ inter_to_fd(fd, u_fd, aid, "Your query returned the following %d results, please be more specific...",(int)Sql_NumRows(sql_handle));
+ while ( SQL_SUCCESS == Sql_NextRow(sql_handle) ) {
+ int class_;
+ short base_level, job_level, online;
+ char name[NAME_LENGTH];
+
+ Sql_GetData(sql_handle, 0, &data, NULL); account_id = atoi(data);
+ Sql_GetData(sql_handle, 1, &data, NULL); safestrncpy(name, data, sizeof(name));
+ Sql_GetData(sql_handle, 2, &data, NULL); class_ = atoi(data);
+ Sql_GetData(sql_handle, 3, &data, NULL); base_level = atoi(data);
+ Sql_GetData(sql_handle, 4, &data, NULL); job_level = atoi(data);
+ Sql_GetData(sql_handle, 5, &data, NULL); online = atoi(data);
+
+ inter_to_fd(fd, u_fd, aid, "[AID: %d] %s | %s | Level: %d/%d | %s", account_id, name, job_name(class_), base_level, job_level, online?"Online":"Offline");
+ }
+ Sql_FreeResult(sql_handle);
+ return;
+ }
+ }
+ }
+
+ /* it will only get here if we have a single match */
+ if( account_id ) {
+ char userid[NAME_LENGTH], user_pass[NAME_LENGTH], email[40], last_ip[20], lastlogin[30];
+ short level = -1;
+ int logincount = 0,state = 0;
+ if ( SQL_ERROR == Sql_Query(sql_handle, "SELECT `userid`, `user_pass`, `email`, `last_ip`, `group_id`, `lastlogin`, `logincount`, `state` FROM `login` WHERE `account_id` = '%d' LIMIT 1", account_id)
+ || Sql_NumRows(sql_handle) == 0 ) {
+ if( Sql_NumRows(sql_handle) == 0 ) {
+ inter_to_fd(fd, u_fd, aid, "No account with ID '%d' was found.", account_id );
+ } else {
+ inter_to_fd(fd, u_fd, aid, "An error occured, bother your admin about it.");
+ Sql_ShowDebug(sql_handle);
+ }
+ } else {
+ Sql_NextRow(sql_handle);
+ Sql_GetData(sql_handle, 0, &data, NULL); safestrncpy(userid, data, sizeof(userid));
+ Sql_GetData(sql_handle, 1, &data, NULL); safestrncpy(user_pass, data, sizeof(user_pass));
+ Sql_GetData(sql_handle, 2, &data, NULL); safestrncpy(email, data, sizeof(email));
+ Sql_GetData(sql_handle, 3, &data, NULL); safestrncpy(last_ip, data, sizeof(last_ip));
+ Sql_GetData(sql_handle, 4, &data, NULL); level = atoi(data);
+ Sql_GetData(sql_handle, 5, &data, NULL); safestrncpy(lastlogin, data, sizeof(lastlogin));
+ Sql_GetData(sql_handle, 6, &data, NULL); logincount = atoi(data);
+ Sql_GetData(sql_handle, 7, &data, NULL); state = atoi(data);
+ }
+
+ Sql_FreeResult(sql_handle);
+
+ if (level == -1)
+ return;
+
+ inter_to_fd(fd, u_fd, aid, "-- Account %d --", account_id );
+ inter_to_fd(fd, u_fd, aid, "User: %s | GM Group: %d | State: %d", userid, level, state );
+
+ if (level < castergroup) /* only show pass if your gm level is greater than the one you're searching for */
+ inter_to_fd(fd, u_fd, aid, "Password: %s", user_pass );
+
+ inter_to_fd(fd, u_fd, aid, "Account e-mail: %s", email);
+ inter_to_fd(fd, u_fd, aid, "Last IP: %s (%s)", last_ip, geoip_getcountry(str2ip(last_ip)) );
+ inter_to_fd(fd, u_fd, aid, "This user has logged %d times, the last time were at %s", logincount, lastlogin );
+ inter_to_fd(fd, u_fd, aid, "-- Character Details --" );
+
+
+ if ( SQL_ERROR == Sql_Query(sql_handle, "SELECT `char_id`, `name`, `char_num`, `class`, `base_level`, `job_level`, `online` FROM `char` WHERE `account_id` = '%d' ORDER BY `char_num` LIMIT %d", account_id, MAX_CHARS)
+ || Sql_NumRows(sql_handle) == 0 ) {
+
+ if( Sql_NumRows(sql_handle) == 0 )
+ inter_to_fd(fd, u_fd, aid,"This account doesn't have characters.");
+ else {
+ inter_to_fd(fd, u_fd, aid,"An error occured, bother your admin about it.");
+ Sql_ShowDebug(sql_handle);
+ }
+
+ } else {
+ while ( SQL_SUCCESS == Sql_NextRow(sql_handle) ) {
+ int char_id, class_;
+ short char_num, base_level, job_level, online;
+ char name[NAME_LENGTH];
+
+ Sql_GetData(sql_handle, 0, &data, NULL); char_id = atoi(data);
+ Sql_GetData(sql_handle, 1, &data, NULL); safestrncpy(name, data, sizeof(name));
+ Sql_GetData(sql_handle, 2, &data, NULL); char_num = atoi(data);
+ Sql_GetData(sql_handle, 3, &data, NULL); class_ = atoi(data);
+ Sql_GetData(sql_handle, 4, &data, NULL); base_level = atoi(data);
+ Sql_GetData(sql_handle, 5, &data, NULL); job_level = atoi(data);
+ Sql_GetData(sql_handle, 6, &data, NULL); online = atoi(data);
+
+ inter_to_fd(fd, u_fd, aid, "[Slot/CID: %d/%d] %s | %s | Level: %d/%d | %s", char_num, char_id, name, job_name(class_), base_level, job_level, online?"On":"Off");
+ }
+ }
+ Sql_FreeResult(sql_handle);
+ }
+
+ return;
}
//--------------------------------------------------------
// Save registry to sql
-int inter_accreg_tosql(int account_id, int char_id, struct accreg *reg, int type)
+int inter_accreg_tosql(int account_id, int char_id, struct accreg* reg, int type)
{
- struct global_reg *r;
- StringBuf buf;
- int i;
-
- if (account_id <= 0)
- return 0;
- reg->account_id = account_id;
- reg->char_id = char_id;
-
- //`global_reg_value` (`type`, `account_id`, `char_id`, `str`, `value`)
- switch (type) {
- case 3: //Char Reg
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `type`=3 AND `char_id`='%d'", reg_db, char_id))
- Sql_ShowDebug(sql_handle);
- account_id = 0;
- break;
- case 2: //Account Reg
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `type`=2 AND `account_id`='%d'", reg_db, account_id))
- Sql_ShowDebug(sql_handle);
- char_id = 0;
- break;
- case 1: //Account2 Reg
- ShowError("inter_accreg_tosql: Char server shouldn't handle type 1 registry values (##). That is the login server's work!\n");
- return 0;
- default:
- ShowError("inter_accreg_tosql: Invalid type %d\n", type);
- return 0;
- }
-
- if (reg->reg_num <= 0)
- return 0;
-
- StringBuf_Init(&buf);
- StringBuf_Printf(&buf, "INSERT INTO `%s` (`type`,`account_id`,`char_id`,`str`,`value`) VALUES ", reg_db);
-
- for (i = 0; i < reg->reg_num; ++i) {
- r = &reg->reg[i];
- if (r->str[0] != '\0' && r->value[0] != '\0') {
- char str[32];
- char val[256];
-
- if (i > 0)
- StringBuf_AppendStr(&buf, ",");
-
- Sql_EscapeString(sql_handle, str, r->str);
- Sql_EscapeString(sql_handle, val, r->value);
-
- StringBuf_Printf(&buf, "('%d','%d','%d','%s','%s')", type, account_id, char_id, str, val);
- }
- }
-
- if (SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf))) {
- Sql_ShowDebug(sql_handle);
- }
-
- StringBuf_Destroy(&buf);
-
- return 1;
+ struct global_reg* r;
+ StringBuf buf;
+ int i;
+
+ if( account_id <= 0 )
+ return 0;
+ reg->account_id = account_id;
+ reg->char_id = char_id;
+
+ //`global_reg_value` (`type`, `account_id`, `char_id`, `str`, `value`)
+ switch( type )
+ {
+ case 3: //Char Reg
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `type`=3 AND `char_id`='%d'", reg_db, char_id) )
+ Sql_ShowDebug(sql_handle);
+ account_id = 0;
+ break;
+ case 2: //Account Reg
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `type`=2 AND `account_id`='%d'", reg_db, account_id) )
+ Sql_ShowDebug(sql_handle);
+ char_id = 0;
+ break;
+ case 1: //Account2 Reg
+ ShowError("inter_accreg_tosql: Char server shouldn't handle type 1 registry values (##). That is the login server's work!\n");
+ return 0;
+ default:
+ ShowError("inter_accreg_tosql: Invalid type %d\n", type);
+ return 0;
+ }
+
+ if( reg->reg_num <= 0 )
+ return 0;
+
+ StringBuf_Init(&buf);
+ StringBuf_Printf(&buf, "INSERT INTO `%s` (`type`,`account_id`,`char_id`,`str`,`value`) VALUES ", reg_db);
+
+ for( i = 0; i < reg->reg_num; ++i ) {
+ r = &reg->reg[i];
+ if( r->str[0] != '\0' && r->value[0] != '\0' ) {
+ char str[32];
+ char val[256];
+
+ if( i > 0 )
+ StringBuf_AppendStr(&buf, ",");
+
+ Sql_EscapeString(sql_handle, str, r->str);
+ Sql_EscapeString(sql_handle, val, r->value);
+
+ StringBuf_Printf(&buf, "('%d','%d','%d','%s','%s')", type, account_id, char_id, str, val);
+ }
+ }
+
+ if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) ) {
+ Sql_ShowDebug(sql_handle);
+ }
+
+ StringBuf_Destroy(&buf);
+
+ return 1;
}
// Load account_reg from sql (type=2)
int inter_accreg_fromsql(int account_id,int char_id, struct accreg *reg, int type)
{
- struct global_reg *r;
- char *data;
- size_t len;
- int i;
-
- if (reg == NULL)
- return 0;
-
- memset(reg, 0, sizeof(struct accreg));
- reg->account_id = account_id;
- reg->char_id = char_id;
-
- //`global_reg_value` (`type`, `account_id`, `char_id`, `str`, `value`)
- switch (type) {
- case 3: //char reg
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `str`, `value` FROM `%s` WHERE `type`=3 AND `char_id`='%d'", reg_db, char_id))
- Sql_ShowDebug(sql_handle);
- break;
- case 2: //account reg
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `str`, `value` FROM `%s` WHERE `type`=2 AND `account_id`='%d'", reg_db, account_id))
- Sql_ShowDebug(sql_handle);
- break;
- case 1: //account2 reg
- ShowError("inter_accreg_fromsql: Char server shouldn't handle type 1 registry values (##). That is the login server's work!\n");
- return 0;
- default:
- ShowError("inter_accreg_fromsql: Invalid type %d\n", type);
- return 0;
- }
- for (i = 0; i < MAX_REG_NUM && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i) {
- r = &reg->reg[i];
- // str
- Sql_GetData(sql_handle, 0, &data, &len);
- memcpy(r->str, data, min(len, sizeof(r->str)));
- // value
- Sql_GetData(sql_handle, 1, &data, &len);
- memcpy(r->value, data, min(len, sizeof(r->value)));
- }
- reg->reg_num = i;
- Sql_FreeResult(sql_handle);
- return 1;
+ struct global_reg* r;
+ char* data;
+ size_t len;
+ int i;
+
+ if( reg == NULL)
+ return 0;
+
+ memset(reg, 0, sizeof(struct accreg));
+ reg->account_id = account_id;
+ reg->char_id = char_id;
+
+ //`global_reg_value` (`type`, `account_id`, `char_id`, `str`, `value`)
+ switch( type )
+ {
+ case 3: //char reg
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `str`, `value` FROM `%s` WHERE `type`=3 AND `char_id`='%d'", reg_db, char_id) )
+ Sql_ShowDebug(sql_handle);
+ break;
+ case 2: //account reg
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `str`, `value` FROM `%s` WHERE `type`=2 AND `account_id`='%d'", reg_db, account_id) )
+ Sql_ShowDebug(sql_handle);
+ break;
+ case 1: //account2 reg
+ ShowError("inter_accreg_fromsql: Char server shouldn't handle type 1 registry values (##). That is the login server's work!\n");
+ return 0;
+ default:
+ ShowError("inter_accreg_fromsql: Invalid type %d\n", type);
+ return 0;
+ }
+ for( i = 0; i < MAX_REG_NUM && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
+ {
+ r = &reg->reg[i];
+ // str
+ Sql_GetData(sql_handle, 0, &data, &len);
+ memcpy(r->str, data, min(len, sizeof(r->str)));
+ // value
+ Sql_GetData(sql_handle, 1, &data, &len);
+ memcpy(r->value, data, min(len, sizeof(r->value)));
+ }
+ reg->reg_num = i;
+ Sql_FreeResult(sql_handle);
+ return 1;
}
// Initialize
int inter_accreg_sql_init(void)
{
- CREATE(accreg_pt, struct accreg, 1);
- return 0;
+ CREATE(accreg_pt, struct accreg, 1);
+ return 0;
}
/*==========================================
* read config file
*------------------------------------------*/
-static int inter_config_read(const char *cfgName)
+static int inter_config_read(const char* cfgName)
{
- int i;
- char line[1024], w1[1024], w2[1024];
- FILE *fp;
-
- fp = fopen(cfgName, "r");
- if (fp == NULL) {
- ShowError("File not found: %s\n", cfgName);
- return 1;
- }
-
- while (fgets(line, sizeof(line), fp)) {
- i = sscanf(line, "%[^:]: %[^\r\n]", w1, w2);
- if (i != 2)
- continue;
-
- if (!strcmpi(w1,"char_server_ip")) {
- strcpy(char_server_ip,w2);
- } else if (!strcmpi(w1,"char_server_port")) {
- char_server_port = atoi(w2);
- } else if (!strcmpi(w1,"char_server_id")) {
- strcpy(char_server_id,w2);
- } else if (!strcmpi(w1,"char_server_pw")) {
- strcpy(char_server_pw,w2);
- } else if (!strcmpi(w1,"char_server_db")) {
- strcpy(char_server_db,w2);
- } else if (!strcmpi(w1,"default_codepage")) {
- strcpy(default_codepage,w2);
- } else if (!strcmpi(w1,"party_share_level"))
- party_share_level = atoi(w2);
- else if (!strcmpi(w1,"log_inter"))
- log_inter = atoi(w2);
- else if (!strcmpi(w1,"main_chat_nick"))
- safestrncpy(main_chat_nick, w2, sizeof(main_chat_nick));
- else if (!strcmpi(w1,"import"))
- inter_config_read(w2);
- }
- fclose(fp);
-
- ShowInfo("Done reading %s.\n", cfgName);
-
- return 0;
+ int i;
+ char line[1024], w1[1024], w2[1024];
+ FILE* fp;
+
+ fp = fopen(cfgName, "r");
+ if(fp == NULL) {
+ ShowError("File not found: %s\n", cfgName);
+ return 1;
+ }
+
+ while(fgets(line, sizeof(line), fp))
+ {
+ i = sscanf(line, "%[^:]: %[^\r\n]", w1, w2);
+ if(i != 2)
+ continue;
+
+ if(!strcmpi(w1,"char_server_ip")) {
+ strcpy(char_server_ip,w2);
+ } else
+ if(!strcmpi(w1,"char_server_port")) {
+ char_server_port = atoi(w2);
+ } else
+ if(!strcmpi(w1,"char_server_id")) {
+ strcpy(char_server_id,w2);
+ } else
+ if(!strcmpi(w1,"char_server_pw")) {
+ strcpy(char_server_pw,w2);
+ } else
+ if(!strcmpi(w1,"char_server_db")) {
+ strcpy(char_server_db,w2);
+ } else
+ if(!strcmpi(w1,"default_codepage")) {
+ strcpy(default_codepage,w2);
+ }
+ else if(!strcmpi(w1,"party_share_level"))
+ party_share_level = atoi(w2);
+ else if(!strcmpi(w1,"log_inter"))
+ log_inter = atoi(w2);
+ else if(!strcmpi(w1,"main_chat_nick"))
+ safestrncpy(main_chat_nick, w2, sizeof(main_chat_nick));
+ else if(!strcmpi(w1,"import"))
+ inter_config_read(w2);
+ }
+ fclose(fp);
+
+ ShowInfo ("Done reading %s.\n", cfgName);
+
+ return 0;
}
// Save interlog into sql
-int inter_log(char *fmt, ...)
+int inter_log(char* fmt, ...)
{
- char str[255];
- char esc_str[sizeof(str)*2+1];// escaped str
- va_list ap;
+ char str[255];
+ char esc_str[sizeof(str)*2+1];// escaped str
+ va_list ap;
- va_start(ap,fmt);
- vsnprintf(str, sizeof(str), fmt, ap);
- va_end(ap);
+ va_start(ap,fmt);
+ vsnprintf(str, sizeof(str), fmt, ap);
+ va_end(ap);
- Sql_EscapeStringLen(sql_handle, esc_str, str, strnlen(str, sizeof(str)));
- if (SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`time`, `log`) VALUES (NOW(), '%s')", interlog_db, esc_str))
- Sql_ShowDebug(sql_handle);
+ Sql_EscapeStringLen(sql_handle, esc_str, str, strnlen(str, sizeof(str)));
+ if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`time`, `log`) VALUES (NOW(), '%s')", interlog_db, esc_str) )
+ Sql_ShowDebug(sql_handle);
- return 0;
+ return 0;
}
// initialize
int inter_init_sql(const char *file)
{
- //int i;
-
- inter_config_read(file);
-
- //DB connection initialized
- sql_handle = Sql_Malloc();
- ShowInfo("Connect Character DB server.... (Character Server)\n");
- if (SQL_ERROR == Sql_Connect(sql_handle, char_server_id, char_server_pw, char_server_ip, (uint16)char_server_port, char_server_db)) {
- Sql_ShowDebug(sql_handle);
- Sql_Free(sql_handle);
- exit(EXIT_FAILURE);
- }
-
- if (*default_codepage) {
- if (SQL_ERROR == Sql_SetEncoding(sql_handle, default_codepage))
- Sql_ShowDebug(sql_handle);
- }
-
- wis_db = idb_alloc(DB_OPT_RELEASE_DATA);
- inter_guild_sql_init();
- inter_storage_sql_init();
- inter_party_sql_init();
- inter_pet_sql_init();
- inter_homunculus_sql_init();
- inter_mercenary_sql_init();
- inter_elemental_sql_init();
- inter_accreg_sql_init();
- inter_mail_sql_init();
- inter_auction_sql_init();
-
- geoip_readdb();
- msg_config_read("conf/msg_athena.conf");
- return 0;
+ //int i;
+
+ inter_config_read(file);
+
+ //DB connection initialized
+ sql_handle = Sql_Malloc();
+ ShowInfo("Connect Character DB server.... (Character Server)\n");
+ if( SQL_ERROR == Sql_Connect(sql_handle, char_server_id, char_server_pw, char_server_ip, (uint16)char_server_port, char_server_db) )
+ {
+ Sql_ShowDebug(sql_handle);
+ Sql_Free(sql_handle);
+ exit(EXIT_FAILURE);
+ }
+
+ if( *default_codepage ) {
+ if( SQL_ERROR == Sql_SetEncoding(sql_handle, default_codepage) )
+ Sql_ShowDebug(sql_handle);
+ }
+
+ wis_db = idb_alloc(DB_OPT_RELEASE_DATA);
+ inter_guild_sql_init();
+ inter_storage_sql_init();
+ inter_party_sql_init();
+ inter_pet_sql_init();
+ inter_homunculus_sql_init();
+ inter_mercenary_sql_init();
+ inter_elemental_sql_init();
+ inter_accreg_sql_init();
+ inter_mail_sql_init();
+ inter_auction_sql_init();
+
+ geoip_readdb();
+ msg_config_read("conf/msg_athena.conf");
+ return 0;
}
// finalize
void inter_final(void)
{
- wis_db->destroy(wis_db, NULL);
-
- inter_guild_sql_final();
- inter_storage_sql_final();
- inter_party_sql_final();
- inter_pet_sql_final();
- inter_homunculus_sql_final();
- inter_mercenary_sql_final();
- inter_elemental_sql_final();
- inter_mail_sql_final();
- inter_auction_sql_final();
-
- if (accreg_pt) aFree(accreg_pt);
-
- do_final_msg();
- return;
+ wis_db->destroy(wis_db, NULL);
+
+ inter_guild_sql_final();
+ inter_storage_sql_final();
+ inter_party_sql_final();
+ inter_pet_sql_final();
+ inter_homunculus_sql_final();
+ inter_mercenary_sql_final();
+ inter_elemental_sql_final();
+ inter_mail_sql_final();
+ inter_auction_sql_final();
+
+ if (accreg_pt) aFree(accreg_pt);
+
+ do_final_msg();
+ return;
}
int inter_mapif_init(int fd)
{
- return 0;
+ return 0;
}
@@ -849,98 +827,99 @@ int inter_mapif_init(int fd)
// broadcast sending
int mapif_broadcast(unsigned char *mes, int len, unsigned long fontColor, short fontType, short fontSize, short fontAlign, short fontY, int sfd)
{
- unsigned char *buf = (unsigned char *)aMalloc((len)*sizeof(unsigned char));
-
- WBUFW(buf,0) = 0x3800;
- WBUFW(buf,2) = len;
- WBUFL(buf,4) = fontColor;
- WBUFW(buf,8) = fontType;
- WBUFW(buf,10) = fontSize;
- WBUFW(buf,12) = fontAlign;
- WBUFW(buf,14) = fontY;
- memcpy(WBUFP(buf,16), mes, len - 16);
- mapif_sendallwos(sfd, buf, len);
-
- if (buf)
- aFree(buf);
- return 0;
+ unsigned char *buf = (unsigned char*)aMalloc((len)*sizeof(unsigned char));
+
+ WBUFW(buf,0) = 0x3800;
+ WBUFW(buf,2) = len;
+ WBUFL(buf,4) = fontColor;
+ WBUFW(buf,8) = fontType;
+ WBUFW(buf,10) = fontSize;
+ WBUFW(buf,12) = fontAlign;
+ WBUFW(buf,14) = fontY;
+ memcpy(WBUFP(buf,16), mes, len - 16);
+ mapif_sendallwos(sfd, buf, len);
+
+ if (buf)
+ aFree(buf);
+ return 0;
}
// Wis sending
int mapif_wis_message(struct WisData *wd)
{
- unsigned char buf[2048];
- if (wd->len > 2047-56) wd->len = 2047-56; //Force it to fit to avoid crashes. [Skotlex]
-
- WBUFW(buf, 0) = 0x3801;
- WBUFW(buf, 2) = 56 +wd->len;
- WBUFL(buf, 4) = wd->id;
- memcpy(WBUFP(buf, 8), wd->src, NAME_LENGTH);
- memcpy(WBUFP(buf,32), wd->dst, NAME_LENGTH);
- memcpy(WBUFP(buf,56), wd->msg, wd->len);
- wd->count = mapif_sendall(buf,WBUFW(buf,2));
-
- return 0;
+ unsigned char buf[2048];
+ if (wd->len > 2047-56) wd->len = 2047-56; //Force it to fit to avoid crashes. [Skotlex]
+
+ WBUFW(buf, 0) = 0x3801;
+ WBUFW(buf, 2) = 56 +wd->len;
+ WBUFL(buf, 4) = wd->id;
+ memcpy(WBUFP(buf, 8), wd->src, NAME_LENGTH);
+ memcpy(WBUFP(buf,32), wd->dst, NAME_LENGTH);
+ memcpy(WBUFP(buf,56), wd->msg, wd->len);
+ wd->count = mapif_sendall(buf,WBUFW(buf,2));
+
+ return 0;
}
// Wis sending result
int mapif_wis_end(struct WisData *wd, int flag)
{
- unsigned char buf[27];
+ unsigned char buf[27];
- WBUFW(buf, 0)=0x3802;
- memcpy(WBUFP(buf, 2),wd->src,24);
- WBUFB(buf,26)=flag;
- mapif_send(wd->fd,buf,27);
- return 0;
+ WBUFW(buf, 0)=0x3802;
+ memcpy(WBUFP(buf, 2),wd->src,24);
+ WBUFB(buf,26)=flag;
+ mapif_send(wd->fd,buf,27);
+ return 0;
}
// Account registry transfer to map-server
static void mapif_account_reg(int fd, unsigned char *src)
{
- WBUFW(src,0)=0x3804; //NOTE: writing to RFIFO
- mapif_sendallwos(fd, src, WBUFW(src,2));
+ WBUFW(src,0)=0x3804; //NOTE: writing to RFIFO
+ mapif_sendallwos(fd, src, WBUFW(src,2));
}
// Send the requested account_reg
int mapif_account_reg_reply(int fd,int account_id,int char_id, int type)
{
- struct accreg *reg=accreg_pt;
- WFIFOHEAD(fd, 13 + 5000);
- inter_accreg_fromsql(account_id,char_id,reg,type);
-
- WFIFOW(fd,0)=0x3804;
- WFIFOL(fd,4)=account_id;
- WFIFOL(fd,8)=char_id;
- WFIFOB(fd,12)=type;
- if (reg->reg_num==0) {
- WFIFOW(fd,2)=13;
- } else {
- int i,p;
- for (p=13,i = 0; i < reg->reg_num && p < 5000; i++) {
- p+= sprintf((char *)WFIFOP(fd,p), "%s", reg->reg[i].str)+1; //We add 1 to consider the '\0' in place.
- p+= sprintf((char *)WFIFOP(fd,p), "%s", reg->reg[i].value)+1;
- }
- WFIFOW(fd,2)=p;
- if (p>= 5000)
- ShowWarning("Too many acc regs for %d:%d, not all values were loaded.\n", account_id, char_id);
- }
- WFIFOSET(fd,WFIFOW(fd,2));
- return 0;
+ struct accreg *reg=accreg_pt;
+ WFIFOHEAD(fd, 13 + 5000);
+ inter_accreg_fromsql(account_id,char_id,reg,type);
+
+ WFIFOW(fd,0)=0x3804;
+ WFIFOL(fd,4)=account_id;
+ WFIFOL(fd,8)=char_id;
+ WFIFOB(fd,12)=type;
+ if(reg->reg_num==0){
+ WFIFOW(fd,2)=13;
+ }else{
+ int i,p;
+ for (p=13,i = 0; i < reg->reg_num && p < 5000; i++) {
+ p+= sprintf((char*)WFIFOP(fd,p), "%s", reg->reg[i].str)+1; //We add 1 to consider the '\0' in place.
+ p+= sprintf((char*)WFIFOP(fd,p), "%s", reg->reg[i].value)+1;
+ }
+ WFIFOW(fd,2)=p;
+ if (p>= 5000)
+ ShowWarning("Too many acc regs for %d:%d, not all values were loaded.\n", account_id, char_id);
+ }
+ WFIFOSET(fd,WFIFOW(fd,2));
+ return 0;
}
//Request to kick char from a certain map server. [Skotlex]
int mapif_disconnectplayer(int fd, int account_id, int char_id, int reason)
{
- if (fd >= 0) {
- WFIFOHEAD(fd,7);
- WFIFOW(fd,0) = 0x2b1f;
- WFIFOL(fd,2) = account_id;
- WFIFOB(fd,6) = reason;
- WFIFOSET(fd,7);
- return 0;
- }
- return -1;
+ if (fd >= 0)
+ {
+ WFIFOHEAD(fd,7);
+ WFIFOW(fd,0) = 0x2b1f;
+ WFIFOL(fd,2) = account_id;
+ WFIFOB(fd,6) = reason;
+ WFIFOSET(fd,7);
+ return 0;
+ }
+ return -1;
}
//--------------------------------------------------------
@@ -951,34 +930,34 @@ int mapif_disconnectplayer(int fd, int account_id, int char_id, int reason)
*/
int check_ttl_wisdata_sub(DBKey key, DBData *data, va_list ap)
{
- unsigned long tick;
- struct WisData *wd = db_data2ptr(data);
- tick = va_arg(ap, unsigned long);
+ unsigned long tick;
+ struct WisData *wd = db_data2ptr(data);
+ tick = va_arg(ap, unsigned long);
- if (DIFF_TICK(tick, wd->tick) > WISDATA_TTL && wis_delnum < WISDELLIST_MAX)
- wis_dellist[wis_delnum++] = wd->id;
+ if (DIFF_TICK(tick, wd->tick) > WISDATA_TTL && wis_delnum < WISDELLIST_MAX)
+ wis_dellist[wis_delnum++] = wd->id;
- return 0;
+ return 0;
}
int check_ttl_wisdata(void)
{
- unsigned long tick = gettick();
- int i;
-
- do {
- wis_delnum = 0;
- wis_db->foreach(wis_db, check_ttl_wisdata_sub, tick);
- for (i = 0; i < wis_delnum; i++) {
- struct WisData *wd = (struct WisData *)idb_get(wis_db, wis_dellist[i]);
- ShowWarning("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
- idb_remove(wis_db, wd->id);
- }
- } while (wis_delnum >= WISDELLIST_MAX);
-
- return 0;
+ unsigned long tick = gettick();
+ int i;
+
+ do {
+ wis_delnum = 0;
+ wis_db->foreach(wis_db, check_ttl_wisdata_sub, tick);
+ for(i = 0; i < wis_delnum; i++) {
+ struct WisData *wd = (struct WisData*)idb_get(wis_db, wis_dellist[i]);
+ ShowWarning("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
+ idb_remove(wis_db, wd->id);
+ }
+ } while(wis_delnum >= WISDELLIST_MAX);
+
+ return 0;
}
//--------------------------------------------------------
@@ -986,206 +965,209 @@ int check_ttl_wisdata(void)
// broadcast sending
int mapif_parse_broadcast(int fd)
{
- mapif_broadcast(RFIFOP(fd,16), RFIFOW(fd,2), RFIFOL(fd,4), RFIFOW(fd,8), RFIFOW(fd,10), RFIFOW(fd,12), RFIFOW(fd,14), fd);
- return 0;
+ mapif_broadcast(RFIFOP(fd,16), RFIFOW(fd,2), RFIFOL(fd,4), RFIFOW(fd,8), RFIFOW(fd,10), RFIFOW(fd,12), RFIFOW(fd,14), fd);
+ return 0;
}
// Wisp/page request to send
int mapif_parse_WisRequest(int fd)
{
- struct WisData *wd;
- static int wisid = 0;
- char name[NAME_LENGTH];
- char esc_name[NAME_LENGTH*2+1];// escaped name
- char *data;
- size_t len;
-
-
- if (fd <= 0) {
- return 0; // check if we have a valid fd
- }
-
- if (RFIFOW(fd,2)-52 >= sizeof(wd->msg)) {
- ShowWarning("inter: Wis message size too long.\n");
- return 0;
- } else if (RFIFOW(fd,2)-52 <= 0) { // normaly, impossible, but who knows...
- ShowError("inter: Wis message doesn't exist.\n");
- return 0;
- }
-
- safestrncpy(name, (char *)RFIFOP(fd,28), NAME_LENGTH); //Received name may be too large and not contain \0! [Skotlex]
-
- Sql_EscapeStringLen(sql_handle, esc_name, name, strnlen(name, NAME_LENGTH));
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `name` FROM `%s` WHERE `name`='%s'", char_db, esc_name))
- Sql_ShowDebug(sql_handle);
-
- // search if character exists before to ask all map-servers
- if (SQL_SUCCESS != Sql_NextRow(sql_handle)) {
- unsigned char buf[27];
- WBUFW(buf, 0) = 0x3802;
- memcpy(WBUFP(buf, 2), RFIFOP(fd, 4), NAME_LENGTH);
- WBUFB(buf,26) = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
- mapif_send(fd, buf, 27);
- } else {
- // Character exists. So, ask all map-servers
- // to be sure of the correct name, rewrite it
- Sql_GetData(sql_handle, 0, &data, &len);
- memset(name, 0, NAME_LENGTH);
- memcpy(name, data, min(len, NAME_LENGTH));
- // if source is destination, don't ask other servers.
- if (strncmp((const char *)RFIFOP(fd,4), name, NAME_LENGTH) == 0) {
- uint8 buf[27];
- WBUFW(buf, 0) = 0x3802;
- memcpy(WBUFP(buf, 2), RFIFOP(fd, 4), NAME_LENGTH);
- WBUFB(buf,26) = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
- mapif_send(fd, buf, 27);
- } else {
-
- CREATE(wd, struct WisData, 1);
-
- // Whether the failure of previous wisp/page transmission (timeout)
- check_ttl_wisdata();
-
- wd->id = ++wisid;
- wd->fd = fd;
- wd->len= RFIFOW(fd,2)-52;
- memcpy(wd->src, RFIFOP(fd, 4), NAME_LENGTH);
- memcpy(wd->dst, RFIFOP(fd,28), NAME_LENGTH);
- memcpy(wd->msg, RFIFOP(fd,52), wd->len);
- wd->tick = gettick();
- idb_put(wis_db, wd->id, wd);
- mapif_wis_message(wd);
- }
- }
-
- Sql_FreeResult(sql_handle);
- return 0;
+ struct WisData* wd;
+ static int wisid = 0;
+ char name[NAME_LENGTH];
+ char esc_name[NAME_LENGTH*2+1];// escaped name
+ char* data;
+ size_t len;
+
+
+ if ( fd <= 0 ) {return 0;} // check if we have a valid fd
+
+ if (RFIFOW(fd,2)-52 >= sizeof(wd->msg)) {
+ ShowWarning("inter: Wis message size too long.\n");
+ return 0;
+ } else if (RFIFOW(fd,2)-52 <= 0) { // normaly, impossible, but who knows...
+ ShowError("inter: Wis message doesn't exist.\n");
+ return 0;
+ }
+
+ safestrncpy(name, (char*)RFIFOP(fd,28), NAME_LENGTH); //Received name may be too large and not contain \0! [Skotlex]
+
+ Sql_EscapeStringLen(sql_handle, esc_name, name, strnlen(name, NAME_LENGTH));
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `name` FROM `%s` WHERE `name`='%s'", char_db, esc_name) )
+ Sql_ShowDebug(sql_handle);
+
+ // search if character exists before to ask all map-servers
+ if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
+ {
+ unsigned char buf[27];
+ WBUFW(buf, 0) = 0x3802;
+ memcpy(WBUFP(buf, 2), RFIFOP(fd, 4), NAME_LENGTH);
+ WBUFB(buf,26) = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
+ mapif_send(fd, buf, 27);
+ }
+ else
+ {// Character exists. So, ask all map-servers
+ // to be sure of the correct name, rewrite it
+ Sql_GetData(sql_handle, 0, &data, &len);
+ memset(name, 0, NAME_LENGTH);
+ memcpy(name, data, min(len, NAME_LENGTH));
+ // if source is destination, don't ask other servers.
+ if( strncmp((const char*)RFIFOP(fd,4), name, NAME_LENGTH) == 0 )
+ {
+ uint8 buf[27];
+ WBUFW(buf, 0) = 0x3802;
+ memcpy(WBUFP(buf, 2), RFIFOP(fd, 4), NAME_LENGTH);
+ WBUFB(buf,26) = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
+ mapif_send(fd, buf, 27);
+ }
+ else
+ {
+
+ CREATE(wd, struct WisData, 1);
+
+ // Whether the failure of previous wisp/page transmission (timeout)
+ check_ttl_wisdata();
+
+ wd->id = ++wisid;
+ wd->fd = fd;
+ wd->len= RFIFOW(fd,2)-52;
+ memcpy(wd->src, RFIFOP(fd, 4), NAME_LENGTH);
+ memcpy(wd->dst, RFIFOP(fd,28), NAME_LENGTH);
+ memcpy(wd->msg, RFIFOP(fd,52), wd->len);
+ wd->tick = gettick();
+ idb_put(wis_db, wd->id, wd);
+ mapif_wis_message(wd);
+ }
+ }
+
+ Sql_FreeResult(sql_handle);
+ return 0;
}
// Wisp/page transmission result
int mapif_parse_WisReply(int fd)
{
- int id, flag;
- struct WisData *wd;
+ int id, flag;
+ struct WisData *wd;
- id = RFIFOL(fd,2);
- flag = RFIFOB(fd,6);
- wd = (struct WisData *)idb_get(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
+ id = RFIFOL(fd,2);
+ flag = RFIFOB(fd,6);
+ wd = (struct WisData*)idb_get(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
- 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
- idb_remove(wis_db, id);
- }
+ 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
+ idb_remove(wis_db, id);
+ }
- return 0;
+ return 0;
}
// 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[2048]; // 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;
- mapif_sendall(buf, RFIFOW(fd,2));
+ memcpy(WBUFP(buf,0), RFIFOP(fd,0), RFIFOW(fd,2));
+ WBUFW(buf, 0) = 0x3803;
+ mapif_sendall(buf, RFIFOW(fd,2));
- return 0;
+ return 0;
}
// Save account_reg into sql (type=2)
int mapif_parse_Registry(int fd)
{
- int j,p,len, max;
- struct accreg *reg=accreg_pt;
-
- memset(accreg_pt,0,sizeof(struct accreg));
- switch (RFIFOB(fd, 12)) {
- case 3: //Character registry
- max = GLOBAL_REG_NUM;
- break;
- case 2: //Account Registry
- max = ACCOUNT_REG_NUM;
- break;
- case 1: //Account2 registry, must be sent over to login server.
- return save_accreg2(RFIFOP(fd,4), RFIFOW(fd,2)-4);
- default:
- return 1;
- }
- for (j=0,p=13; j<max && p<RFIFOW(fd,2); j++) {
- sscanf((char *)RFIFOP(fd,p), "%31c%n",reg->reg[j].str,&len);
- reg->reg[j].str[len]='\0';
- p +=len+1; //+1 to skip the '\0' between strings.
- sscanf((char *)RFIFOP(fd,p), "%255c%n",reg->reg[j].value,&len);
- reg->reg[j].value[len]='\0';
- p +=len+1;
- }
- reg->reg_num=j;
-
- inter_accreg_tosql(RFIFOL(fd,4),RFIFOL(fd,8),reg, RFIFOB(fd,12));
- mapif_account_reg(fd,RFIFOP(fd,0)); // Send updated accounts to other map servers.
- return 0;
+ int j,p,len, max;
+ struct accreg *reg=accreg_pt;
+
+ memset(accreg_pt,0,sizeof(struct accreg));
+ switch (RFIFOB(fd, 12)) {
+ case 3: //Character registry
+ max = GLOBAL_REG_NUM;
+ break;
+ case 2: //Account Registry
+ max = ACCOUNT_REG_NUM;
+ break;
+ case 1: //Account2 registry, must be sent over to login server.
+ return save_accreg2(RFIFOP(fd,4), RFIFOW(fd,2)-4);
+ default:
+ return 1;
+ }
+ for(j=0,p=13;j<max && p<RFIFOW(fd,2);j++){
+ sscanf((char*)RFIFOP(fd,p), "%31c%n",reg->reg[j].str,&len);
+ reg->reg[j].str[len]='\0';
+ p +=len+1; //+1 to skip the '\0' between strings.
+ sscanf((char*)RFIFOP(fd,p), "%255c%n",reg->reg[j].value,&len);
+ reg->reg[j].value[len]='\0';
+ p +=len+1;
+ }
+ reg->reg_num=j;
+
+ inter_accreg_tosql(RFIFOL(fd,4),RFIFOL(fd,8),reg, RFIFOB(fd,12));
+ mapif_account_reg(fd,RFIFOP(fd,0)); // Send updated accounts to other map servers.
+ return 0;
}
// Request the value of all registries.
int mapif_parse_RegistryRequest(int fd)
{
- //Load Char Registry
- if (RFIFOB(fd,12)) mapif_account_reg_reply(fd,RFIFOL(fd,2),RFIFOL(fd,6),3);
- //Load Account Registry
- if (RFIFOB(fd,11)) mapif_account_reg_reply(fd,RFIFOL(fd,2),RFIFOL(fd,6),2);
- //Ask Login Server for Account2 values.
- if (RFIFOB(fd,10)) request_accreg2(RFIFOL(fd,2),RFIFOL(fd,6));
- return 1;
+ //Load Char Registry
+ if (RFIFOB(fd,12)) mapif_account_reg_reply(fd,RFIFOL(fd,2),RFIFOL(fd,6),3);
+ //Load Account Registry
+ if (RFIFOB(fd,11)) mapif_account_reg_reply(fd,RFIFOL(fd,2),RFIFOL(fd,6),2);
+ //Ask Login Server for Account2 values.
+ if (RFIFOB(fd,10)) request_accreg2(RFIFOL(fd,2),RFIFOL(fd,6));
+ return 1;
}
static void mapif_namechange_ack(int fd, int account_id, int char_id, int type, int flag, char *name)
{
- WFIFOHEAD(fd, NAME_LENGTH+13);
- WFIFOW(fd, 0) = 0x3806;
- WFIFOL(fd, 2) = account_id;
- WFIFOL(fd, 6) = char_id;
- WFIFOB(fd,10) = type;
- WFIFOB(fd,11) = flag;
- memcpy(WFIFOP(fd, 12), name, NAME_LENGTH);
- WFIFOSET(fd, NAME_LENGTH+13);
+ WFIFOHEAD(fd, NAME_LENGTH+13);
+ WFIFOW(fd, 0) = 0x3806;
+ WFIFOL(fd, 2) = account_id;
+ WFIFOL(fd, 6) = char_id;
+ WFIFOB(fd,10) = type;
+ WFIFOB(fd,11) = flag;
+ memcpy(WFIFOP(fd, 12), name, NAME_LENGTH);
+ WFIFOSET(fd, NAME_LENGTH+13);
}
int mapif_parse_NameChangeRequest(int fd)
{
- int account_id, char_id, type;
- char *name;
- int i;
-
- account_id = RFIFOL(fd,2);
- char_id = RFIFOL(fd,6);
- type = RFIFOB(fd,10);
- name = (char *)RFIFOP(fd,11);
-
- // Check Authorised letters/symbols in the name
- if (char_name_option == 1) { // only letters/symbols in char_name_letters are authorised
- for (i = 0; i < NAME_LENGTH && name[i]; i++)
- if (strchr(char_name_letters, name[i]) == NULL) {
- mapif_namechange_ack(fd, account_id, char_id, type, 0, name);
- return 0;
- }
- } else if (char_name_option == 2) { // letters/symbols in char_name_letters are forbidden
- for (i = 0; i < NAME_LENGTH && name[i]; i++)
- if (strchr(char_name_letters, name[i]) != NULL) {
- mapif_namechange_ack(fd, account_id, char_id, type, 0, name);
- return 0;
- }
- }
- //TODO: type holds the type of object to rename.
- //If it were a player, it needs to have the guild information and db information
- //updated here, because changing it on the map won't make it be saved [Skotlex]
-
- //name allowed.
- mapif_namechange_ack(fd, account_id, char_id, type, 1, name);
- return 0;
+ int account_id, char_id, type;
+ char* name;
+ int i;
+
+ account_id = RFIFOL(fd,2);
+ char_id = RFIFOL(fd,6);
+ type = RFIFOB(fd,10);
+ name = (char*)RFIFOP(fd,11);
+
+ // Check Authorised letters/symbols in the name
+ if (char_name_option == 1) { // only letters/symbols in char_name_letters are authorised
+ for (i = 0; i < NAME_LENGTH && name[i]; i++)
+ if (strchr(char_name_letters, name[i]) == NULL) {
+ mapif_namechange_ack(fd, account_id, char_id, type, 0, name);
+ return 0;
+ }
+ } else if (char_name_option == 2) { // letters/symbols in char_name_letters are forbidden
+ for (i = 0; i < NAME_LENGTH && name[i]; i++)
+ if (strchr(char_name_letters, name[i]) != NULL) {
+ mapif_namechange_ack(fd, account_id, char_id, type, 0, name);
+ return 0;
+ }
+ }
+ //TODO: type holds the type of object to rename.
+ //If it were a player, it needs to have the guild information and db information
+ //updated here, because changing it on the map won't make it be saved [Skotlex]
+
+ //name allowed.
+ mapif_namechange_ack(fd, account_id, char_id, type, 1, name);
+ return 0;
}
//--------------------------------------------------------
@@ -1196,75 +1178,59 @@ int mapif_parse_NameChangeRequest(int fd)
/// @param length The minimum allowed length, or -1 for dynamic lookup
int inter_check_length(int fd, int length)
{
- if (length == -1) {
- // variable-length packet
- if (RFIFOREST(fd) < 4)
- return 0;
- length = RFIFOW(fd,2);
- }
+ if( length == -1 )
+ {// variable-length packet
+ if( RFIFOREST(fd) < 4 )
+ return 0;
+ length = RFIFOW(fd,2);
+ }
- if ((int)RFIFOREST(fd) < length)
- return 0;
+ if( (int)RFIFOREST(fd) < length )
+ return 0;
- return length;
+ return length;
}
int inter_parse_frommap(int fd)
{
- int cmd;
- int len = 0;
- cmd = RFIFOW(fd,0);
- // Check is valid packet entry
- if (cmd < 0x3000 || cmd >= 0x3000 + ARRAYLENGTH(inter_recv_packet_length) || inter_recv_packet_length[cmd - 0x3000] == 0)
- return 0;
-
- // Check packet length
- if ((len = inter_check_length(fd, inter_recv_packet_length[cmd - 0x3000])) == 0)
- return 2;
-
- switch (cmd) {
- case 0x3000:
- mapif_parse_broadcast(fd);
- break;
- case 0x3001:
- mapif_parse_WisRequest(fd);
- break;
- case 0x3002:
- mapif_parse_WisReply(fd);
- break;
- case 0x3003:
- mapif_parse_WisToGM(fd);
- break;
- case 0x3004:
- mapif_parse_Registry(fd);
- break;
- case 0x3005:
- mapif_parse_RegistryRequest(fd);
- break;
- case 0x3006:
- mapif_parse_NameChangeRequest(fd);
- break;
- case 0x3007:
- mapif_parse_accinfo(fd);
- break;
- /* 0x3008 is used by the report stuff */
- default:
- if (inter_party_parse_frommap(fd)
- || inter_guild_parse_frommap(fd)
- || inter_storage_parse_frommap(fd)
- || inter_pet_parse_frommap(fd)
- || inter_homunculus_parse_frommap(fd)
- || inter_mercenary_parse_frommap(fd)
- || inter_elemental_parse_frommap(fd)
- || inter_mail_parse_frommap(fd)
- || inter_auction_parse_frommap(fd)
- || inter_quest_parse_frommap(fd)
- )
- break;
- else
- return 0;
- }
-
- RFIFOSKIP(fd, len);
- return 1;
+ int cmd;
+ int len = 0;
+ cmd = RFIFOW(fd,0);
+ // Check is valid packet entry
+ if(cmd < 0x3000 || cmd >= 0x3000 + ARRAYLENGTH(inter_recv_packet_length) || inter_recv_packet_length[cmd - 0x3000] == 0)
+ return 0;
+
+ // Check packet length
+ if((len = inter_check_length(fd, inter_recv_packet_length[cmd - 0x3000])) == 0)
+ return 2;
+
+ switch(cmd) {
+ case 0x3000: mapif_parse_broadcast(fd); break;
+ case 0x3001: mapif_parse_WisRequest(fd); break;
+ case 0x3002: mapif_parse_WisReply(fd); break;
+ case 0x3003: mapif_parse_WisToGM(fd); break;
+ case 0x3004: mapif_parse_Registry(fd); break;
+ case 0x3005: mapif_parse_RegistryRequest(fd); break;
+ case 0x3006: mapif_parse_NameChangeRequest(fd); break;
+ case 0x3007: mapif_parse_accinfo(fd); break;
+ /* 0x3008 is used by the report stuff */
+ default:
+ if( inter_party_parse_frommap(fd)
+ || inter_guild_parse_frommap(fd)
+ || inter_storage_parse_frommap(fd)
+ || inter_pet_parse_frommap(fd)
+ || inter_homunculus_parse_frommap(fd)
+ || inter_mercenary_parse_frommap(fd)
+ || inter_elemental_parse_frommap(fd)
+ || inter_mail_parse_frommap(fd)
+ || inter_auction_parse_frommap(fd)
+ || inter_quest_parse_frommap(fd)
+ )
+ break;
+ else
+ return 0;
+ }
+
+ RFIFOSKIP(fd, len);
+ return 1;
}
diff --git a/src/char/inter.h b/src/char/inter.h
index 199d70bb4..ac2e1785f 100644
--- a/src/char/inter.h
+++ b/src/char/inter.h
@@ -20,8 +20,8 @@ int inter_log(char *fmt,...);
extern unsigned int party_share_level;
-extern Sql *sql_handle;
-extern Sql *lsql_handle;
+extern Sql* sql_handle;
+extern Sql* lsql_handle;
extern char main_chat_nick[16];
diff --git a/src/common/atomic.h b/src/common/atomic.h
index a7e953db2..b1a4bda92 100644
--- a/src/common/atomic.h
+++ b/src/common/atomic.h
@@ -4,16 +4,16 @@
#ifndef _rA_ATOMIC_H_
#define _rA_ATOMIC_H_
-// Atomic Operations
+// Atomic Operations
// (Interlocked CompareExchange, Add .. and so on ..)
-//
+//
// Implementation varies / depends on:
-// - Architecture
-// - Compiler
-// - Operating System
+// - Architecture
+// - Compiler
+// - Operating System
//
// our Abstraction is fully API-Compatible to Microsofts implementation @ NT5.0+
-//
+//
#include "../common/cbasetypes.h"
#if defined(_MSC_VER)
@@ -22,65 +22,60 @@
#if !defined(_M_X64)
// When compiling for windows 32bit, the 8byte interlocked operations are not provided by microsoft
// (because they need at least i586 so its not generic enough.. ... )
-forceinline int64 InterlockedCompareExchange64(volatile int64 *dest, int64 exch, int64 _cmp)
-{
- _asm {
- lea esi,_cmp;
- lea edi,exch;
-
- mov eax,[esi];
- mov edx,4[esi];
- mov ebx,[edi];
- mov ecx,4[edi];
- mov esi,dest;
-
- lock CMPXCHG8B [esi];
- }
+forceinline int64 InterlockedCompareExchange64(volatile int64 *dest, int64 exch, int64 _cmp){
+ _asm{
+ lea esi,_cmp;
+ lea edi,exch;
+
+ mov eax,[esi];
+ mov edx,4[esi];
+ mov ebx,[edi];
+ mov ecx,4[edi];
+ mov esi,dest;
+
+ lock CMPXCHG8B [esi];
+ }
}
-forceinline volatile int64 InterlockedIncrement64(volatile int64 *addend)
-{
- __int64 old;
- do {
- old = *addend;
- } while (InterlockedCompareExchange64(addend, (old+1), old) != old);
+forceinline volatile int64 InterlockedIncrement64(volatile int64 *addend){
+ __int64 old;
+ do{
+ old = *addend;
+ }while(InterlockedCompareExchange64(addend, (old+1), old) != old);
- return (old + 1);
+ return (old + 1);
}
-forceinline volatile int64 InterlockedDecrement64(volatile int64 *addend)
-{
- __int64 old;
+forceinline volatile int64 InterlockedDecrement64(volatile int64 *addend){
+ __int64 old;
- do {
- old = *addend;
- } while (InterlockedCompareExchange64(addend, (old-1), old) != old);
+ do{
+ old = *addend;
+ }while(InterlockedCompareExchange64(addend, (old-1), old) != old);
- return (old - 1);
+ return (old - 1);
}
-forceinline volatile int64 InterlockedExchangeAdd64(volatile int64 *addend, int64 increment)
-{
- __int64 old;
+forceinline volatile int64 InterlockedExchangeAdd64(volatile int64 *addend, int64 increment){
+ __int64 old;
- do {
- old = *addend;
- } while (InterlockedCompareExchange64(addend, (old + increment), old) != old);
+ do{
+ old = *addend;
+ }while(InterlockedCompareExchange64(addend, (old + increment), old) != old);
- return old;
+ return old;
}
-forceinline volatile int64 InterlockedExchange64(volatile int64 *target, int64 val)
-{
- __int64 old;
- do {
- old = *target;
- } while (InterlockedCompareExchange64(target, val, old) != old);
+forceinline volatile int64 InterlockedExchange64(volatile int64 *target, int64 val){
+ __int64 old;
+ do{
+ old = *target;
+ }while(InterlockedCompareExchange64(target, val, old) != old);
- return old;
+ return old;
}
#endif //endif 32bit windows
@@ -91,62 +86,52 @@ forceinline volatile int64 InterlockedExchange64(volatile int64 *target, int64 v
#error Your Target Platfrom is not supported
#endif
-static forceinline int64 InterlockedExchangeAdd64(volatile int64 *addend, int64 increment)
-{
- return __sync_fetch_and_add(addend, increment);
+static forceinline int64 InterlockedExchangeAdd64(volatile int64 *addend, int64 increment){
+ return __sync_fetch_and_add(addend, increment);
}//end: InterlockedExchangeAdd64()
-static forceinline int32 InterlockedExchangeAdd(volatile int32 *addend, int32 increment)
-{
- return __sync_fetch_and_add(addend, increment);
+static forceinline int32 InterlockedExchangeAdd(volatile int32 *addend, int32 increment){
+ return __sync_fetch_and_add(addend, increment);
}//end: InterlockedExchangeAdd()
-static forceinline int64 InterlockedIncrement64(volatile int64 *addend)
-{
- return __sync_add_and_fetch(addend, 1);
+static forceinline int64 InterlockedIncrement64(volatile int64 *addend){
+ return __sync_add_and_fetch(addend, 1);
}//end: InterlockedIncrement64()
-static forceinline int32 InterlockedIncrement(volatile int32 *addend)
-{
- return __sync_add_and_fetch(addend, 1);
+static forceinline int32 InterlockedIncrement(volatile int32 *addend){
+ return __sync_add_and_fetch(addend, 1);
}//end: InterlockedIncrement()
-static forceinline int64 InterlockedDecrement64(volatile int64 *addend)
-{
- return __sync_sub_and_fetch(addend, 1);
+static forceinline int64 InterlockedDecrement64(volatile int64 *addend){
+ return __sync_sub_and_fetch(addend, 1);
}//end: InterlockedDecrement64()
-static forceinline int32 InterlockedDecrement(volatile int32 *addend)
-{
- return __sync_sub_and_fetch(addend, 1);
+static forceinline int32 InterlockedDecrement(volatile int32 *addend){
+ return __sync_sub_and_fetch(addend, 1);
}//end: InterlockedDecrement()
-static forceinline int64 InterlockedCompareExchange64(volatile int64 *dest, int64 exch, int64 cmp)
-{
- return __sync_val_compare_and_swap(dest, cmp, exch);
+static forceinline int64 InterlockedCompareExchange64(volatile int64 *dest, int64 exch, int64 cmp){
+ return __sync_val_compare_and_swap(dest, cmp, exch);
}//end: InterlockedCompareExchange64()
-static forceinline int32 InterlockedCompareExchange(volatile int32 *dest, int32 exch, int32 cmp)
-{
- return __sync_val_compare_and_swap(dest, cmp, exch);
+static forceinline int32 InterlockedCompareExchange(volatile int32 *dest, int32 exch, int32 cmp){
+ return __sync_val_compare_and_swap(dest, cmp, exch);
}//end: InterlockedCompareExchnage()
-static forceinline int64 InterlockedExchange64(volatile int64 *target, int64 val)
-{
- return __sync_lock_test_and_set(target, val);
+static forceinline int64 InterlockedExchange64(volatile int64 *target, int64 val){
+ return __sync_lock_test_and_set(target, val);
}//end: InterlockedExchange64()
-static forceinline int32 InterlockedExchange(volatile int32 *target, int32 val)
-{
+static forceinline int32 InterlockedExchange(volatile int32 *target, int32 val){
return __sync_lock_test_and_set(target, val);
}//end: InterlockedExchange()
diff --git a/src/common/cbasetypes.h b/src/common/cbasetypes.h
index a47a7434f..731a8b578 100644
--- a/src/common/cbasetypes.h
+++ b/src/common/cbasetypes.h
@@ -59,11 +59,11 @@
// debug function name
#ifndef __NETBSD__
#if __STDC_VERSION__ < 199901L
-# if __GNUC__ >= 2
-# define __func__ __FUNCTION__
-# else
-# define __func__ ""
-# endif
+# if __GNUC__ >= 2
+# define __func__ __FUNCTION__
+# else
+# define __func__ ""
+# endif
#endif
#endif
@@ -106,56 +106,56 @@
// Integers with guaranteed _exact_ size.
//////////////////////////////////////////////////////////////////////////
-typedef int8_t int8;
-typedef int16_t int16;
-typedef int32_t int32;
-typedef int64_t int64;
+typedef int8_t int8;
+typedef int16_t int16;
+typedef int32_t int32;
+typedef int64_t int64;
-typedef int8_t sint8;
-typedef int16_t sint16;
-typedef int32_t sint32;
-typedef int64_t sint64;
+typedef int8_t sint8;
+typedef int16_t sint16;
+typedef int32_t sint32;
+typedef int64_t sint64;
-typedef uint8_t uint8;
-typedef uint16_t uint16;
-typedef uint32_t uint32;
-typedef uint64_t uint64;
+typedef uint8_t uint8;
+typedef uint16_t uint16;
+typedef uint32_t uint32;
+typedef uint64_t uint64;
#undef UINT8_MIN
#undef UINT16_MIN
#undef UINT32_MIN
#undef UINT64_MIN
-#define UINT8_MIN ((uint8) UINT8_C(0x00))
-#define UINT16_MIN ((uint16)UINT16_C(0x0000))
-#define UINT32_MIN ((uint32)UINT32_C(0x00000000))
-#define UINT64_MIN ((uint64)UINT64_C(0x0000000000000000))
+#define UINT8_MIN ((uint8) UINT8_C(0x00))
+#define UINT16_MIN ((uint16)UINT16_C(0x0000))
+#define UINT32_MIN ((uint32)UINT32_C(0x00000000))
+#define UINT64_MIN ((uint64)UINT64_C(0x0000000000000000))
#undef UINT8_MAX
#undef UINT16_MAX
#undef UINT32_MAX
#undef UINT64_MAX
-#define UINT8_MAX ((uint8) UINT8_C(0xFF))
-#define UINT16_MAX ((uint16)UINT16_C(0xFFFF))
-#define UINT32_MAX ((uint32)UINT32_C(0xFFFFFFFF))
-#define UINT64_MAX ((uint64)UINT64_C(0xFFFFFFFFFFFFFFFF))
+#define UINT8_MAX ((uint8) UINT8_C(0xFF))
+#define UINT16_MAX ((uint16)UINT16_C(0xFFFF))
+#define UINT32_MAX ((uint32)UINT32_C(0xFFFFFFFF))
+#define UINT64_MAX ((uint64)UINT64_C(0xFFFFFFFFFFFFFFFF))
#undef SINT8_MIN
#undef SINT16_MIN
#undef SINT32_MIN
#undef SINT64_MIN
-#define SINT8_MIN ((sint8) INT8_C(0x80))
-#define SINT16_MIN ((sint16)INT16_C(0x8000))
-#define SINT32_MIN ((sint32)INT32_C(0x80000000))
-#define SINT64_MIN ((sint32)INT64_C(0x8000000000000000))
+#define SINT8_MIN ((sint8) INT8_C(0x80))
+#define SINT16_MIN ((sint16)INT16_C(0x8000))
+#define SINT32_MIN ((sint32)INT32_C(0x80000000))
+#define SINT64_MIN ((sint32)INT64_C(0x8000000000000000))
#undef SINT8_MAX
#undef SINT16_MAX
#undef SINT32_MAX
#undef SINT64_MAX
-#define SINT8_MAX ((sint8) INT8_C(0x7F))
-#define SINT16_MAX ((sint16)INT16_C(0x7FFF))
-#define SINT32_MAX ((sint32)INT32_C(0x7FFFFFFF))
-#define SINT64_MAX ((sint64)INT64_C(0x7FFFFFFFFFFFFFFF))
+#define SINT8_MAX ((sint8) INT8_C(0x7F))
+#define SINT16_MAX ((sint16)INT16_C(0x7FFF))
+#define SINT32_MAX ((sint32)INT32_C(0x7FFFFFFF))
+#define SINT64_MAX ((sint64)INT64_C(0x7FFFFFFFFFFFFFFF))
//////////////////////////////////////////////////////////////////////////
// Integers with guaranteed _minimum_ size.
@@ -180,10 +180,10 @@ typedef unsigned long int ppuint32;
#if defined(WIN32) && !defined(MINGW) // does not have a signed size_t
//////////////////////////////
-#if defined(_WIN64) // naive 64bit windows platform
-typedef __int64 ssize_t;
+#if defined(_WIN64) // naive 64bit windows platform
+typedef __int64 ssize_t;
#else
-typedef int ssize_t;
+typedef int ssize_t;
#endif
//////////////////////////////
#endif
@@ -201,23 +201,23 @@ typedef uintptr_t uintptr;
// Add a 'sysint' Type which has the width of the platform we're compiled for.
//////////////////////////////////////////////////////////////////////////
#if defined(__GNUC__)
-#if defined(__x86_64__)
-typedef int64 sysint;
-typedef uint64 usysint;
-#else
-typedef int32 sysint;
-typedef uint32 usysint;
-#endif
+ #if defined(__x86_64__)
+ typedef int64 sysint;
+ typedef uint64 usysint;
+ #else
+ typedef int32 sysint;
+ typedef uint32 usysint;
+ #endif
#elif defined(_MSC_VER)
-#if defined(_M_X64)
-typedef int64 sysint;
-typedef uint64 usysint;
-#else
-typedef int32 sysint;
-typedef uint32 usysint;
-#endif
+ #if defined(_M_X64)
+ typedef int64 sysint;
+ typedef uint64 usysint;
+ #else
+ typedef int32 sysint;
+ typedef uint32 usysint;
+ #endif
#else
-#error Compiler / Platform is unsupported.
+ #error Compiler / Platform is unsupported.
#endif
@@ -225,21 +225,21 @@ typedef uint32 usysint;
// some redefine of function redefines for some Compilers
//////////////////////////////////////////////////////////////////////////
#if defined(_MSC_VER) || defined(__BORLANDC__)
-#define strcasecmp stricmp
-#define strncasecmp strnicmp
-#define strncmpi strnicmp
-#define snprintf _snprintf
+#define strcasecmp stricmp
+#define strncasecmp strnicmp
+#define strncmpi strnicmp
+#define snprintf _snprintf
#if defined(_MSC_VER) && _MSC_VER < 1400
-#define vsnprintf _vsnprintf
+#define vsnprintf _vsnprintf
#endif
#else
-#define strcmpi strcasecmp
-#define stricmp strcasecmp
-#define strncmpi strncasecmp
-#define strnicmp strncasecmp
+#define strcmpi strcasecmp
+#define stricmp strcasecmp
+#define strncmpi strncasecmp
+#define strnicmp strncasecmp
#endif
#if defined(_MSC_VER) && _MSC_VER > 1200
-#define strtoull _strtoui64
+#define strtoull _strtoui64
#endif
// keyword replacement
@@ -262,8 +262,8 @@ typedef uint32 usysint;
// boolean types for C
typedef char bool;
-#define false (1==0)
-#define true (1==1)
+#define false (1==0)
+#define true (1==1)
//////////////////////////////
#endif // not __cplusplus
@@ -276,7 +276,7 @@ typedef char bool;
#undef swap
#endif
// hmm only ints?
-//#define swap(a,b) { int temp=a; a=b; b=temp;}
+//#define swap(a,b) { int temp=a; a=b; b=temp;}
// if using macros then something that is type independent
//#define swap(a,b) ((a == b) || ((a ^= b), (b ^= a), (a ^= b)))
// Avoid "value computed is not used" warning and generates the same assembly code
@@ -299,7 +299,7 @@ typedef char bool;
//////////////////////////////////////////////////////////////////////////
// number of bits in a byte
#ifndef NBBY
-#define NBBY 8
+#define NBBY 8
#endif
//////////////////////////////////////////////////////////////////////////
@@ -383,20 +383,17 @@ typedef char bool;
// Set a pointer variable to a pointer value.
#ifdef __cplusplus
template <typename T1, typename T2>
-void SET_POINTER(T1 *&var, T2 *p)
+void SET_POINTER(T1*&var, T2* p)
{
- var = static_cast<T1 *>(p);
+ var = static_cast<T1*>(p);
}
template <typename T1, typename T2>
-void SET_FUNCPOINTER(T1 &var, T2 p)
+void SET_FUNCPOINTER(T1& var, T2 p)
{
- char ASSERT_POINTERSIZE[sizeof(T1) == sizeof(void *) && sizeof(T2) == sizeof(void *)?1:-1]; // 1 if true, -1 if false
- union {
- T1 out;
- T2 in;
- } tmp;// /!\ WARNING casting a pointer to a function pointer is against the C++ standard
- tmp.in = p;
- var = tmp.out;
+ char ASSERT_POINTERSIZE[sizeof(T1) == sizeof(void*) && sizeof(T2) == sizeof(void*)?1:-1];// 1 if true, -1 if false
+ union{ T1 out; T2 in; } tmp;// /!\ WARNING casting a pointer to a function pointer is against the C++ standard
+ tmp.in = p;
+ var = tmp.out;
}
#else
#define SET_POINTER(var,p) (var) = (p)
diff --git a/src/common/conf.c b/src/common/conf.c
index 2027b4b09..3057bd4dc 100644
--- a/src/common/conf.c
+++ b/src/common/conf.c
@@ -8,14 +8,14 @@
int conf_read_file(config_t *config, const char *config_filename)
{
- config_init(config);
- if (!config_read_file(config, config_filename)) {
- ShowError("%s:%d - %s\n", config_error_file(config),
- config_error_line(config), config_error_text(config));
- config_destroy(config);
- return 1;
- }
- return 0;
+ config_init(config);
+ if (!config_read_file(config, config_filename)) {
+ ShowError("%s:%d - %s\n", config_error_file(config),
+ config_error_line(config), config_error_text(config));
+ config_destroy(config);
+ return 1;
+ }
+ return 0;
}
//
@@ -28,81 +28,82 @@ int config_setting_copy(config_setting_t *parent, const config_setting_t *src);
void config_setting_copy_simple(config_setting_t *parent, const config_setting_t *src)
{
- if (config_setting_is_aggregate(src)) {
- config_setting_copy_aggregate(parent, src);
- } else {
- config_setting_t *set = config_setting_add(parent, config_setting_name(src), config_setting_type(src));
-
- if (set == NULL)
- return;
-
- if (CONFIG_TYPE_INT == config_setting_type(src)) {
- config_setting_set_int(set, config_setting_get_int(src));
- config_setting_set_format(set, src->format);
- } else if (CONFIG_TYPE_INT64 == config_setting_type(src)) {
- config_setting_set_int64(set, config_setting_get_int64(src));
- config_setting_set_format(set, src->format);
- } else if (CONFIG_TYPE_FLOAT == config_setting_type(src)) {
- config_setting_set_float(set, config_setting_get_float(src));
- } else if (CONFIG_TYPE_STRING == config_setting_type(src)) {
- config_setting_set_string(set, config_setting_get_string(src));
- } else if (CONFIG_TYPE_BOOL == config_setting_type(src)) {
- config_setting_set_bool(set, config_setting_get_bool(src));
- }
- }
+ if (config_setting_is_aggregate(src)) {
+ config_setting_copy_aggregate(parent, src);
+ }
+ else {
+ config_setting_t *set = config_setting_add(parent, config_setting_name(src), config_setting_type(src));
+
+ if (set == NULL)
+ return;
+
+ if (CONFIG_TYPE_INT == config_setting_type(src)) {
+ config_setting_set_int(set, config_setting_get_int(src));
+ config_setting_set_format(set, src->format);
+ } else if (CONFIG_TYPE_INT64 == config_setting_type(src)) {
+ config_setting_set_int64(set, config_setting_get_int64(src));
+ config_setting_set_format(set, src->format);
+ } else if (CONFIG_TYPE_FLOAT == config_setting_type(src)) {
+ config_setting_set_float(set, config_setting_get_float(src));
+ } else if (CONFIG_TYPE_STRING == config_setting_type(src)) {
+ config_setting_set_string(set, config_setting_get_string(src));
+ } else if (CONFIG_TYPE_BOOL == config_setting_type(src)) {
+ config_setting_set_bool(set, config_setting_get_bool(src));
+ }
+ }
}
void config_setting_copy_elem(config_setting_t *parent, const config_setting_t *src)
{
- config_setting_t *set = NULL;
-
- if (config_setting_is_aggregate(src))
- config_setting_copy_aggregate(parent, src);
- else if (CONFIG_TYPE_INT == config_setting_type(src)) {
- set = config_setting_set_int_elem(parent, -1, config_setting_get_int(src));
- config_setting_set_format(set, src->format);
- } else if (CONFIG_TYPE_INT64 == config_setting_type(src)) {
- set = config_setting_set_int64_elem(parent, -1, config_setting_get_int64(src));
- config_setting_set_format(set, src->format);
- } else if (CONFIG_TYPE_FLOAT == config_setting_type(src)) {
- config_setting_set_float_elem(parent, -1, config_setting_get_float(src));
- } else if (CONFIG_TYPE_STRING == config_setting_type(src)) {
- config_setting_set_string_elem(parent, -1, config_setting_get_string(src));
- } else if (CONFIG_TYPE_BOOL == config_setting_type(src)) {
- config_setting_set_bool_elem(parent, -1, config_setting_get_bool(src));
- }
+ config_setting_t *set = NULL;
+
+ if (config_setting_is_aggregate(src))
+ config_setting_copy_aggregate(parent, src);
+ else if (CONFIG_TYPE_INT == config_setting_type(src)) {
+ set = config_setting_set_int_elem(parent, -1, config_setting_get_int(src));
+ config_setting_set_format(set, src->format);
+ } else if (CONFIG_TYPE_INT64 == config_setting_type(src)) {
+ set = config_setting_set_int64_elem(parent, -1, config_setting_get_int64(src));
+ config_setting_set_format(set, src->format);
+ } else if (CONFIG_TYPE_FLOAT == config_setting_type(src)) {
+ config_setting_set_float_elem(parent, -1, config_setting_get_float(src));
+ } else if (CONFIG_TYPE_STRING == config_setting_type(src)) {
+ config_setting_set_string_elem(parent, -1, config_setting_get_string(src));
+ } else if (CONFIG_TYPE_BOOL == config_setting_type(src)) {
+ config_setting_set_bool_elem(parent, -1, config_setting_get_bool(src));
+ }
}
void config_setting_copy_aggregate(config_setting_t *parent, const config_setting_t *src)
{
- config_setting_t *newAgg;
- int i, n;
-
- newAgg = config_setting_add(parent, config_setting_name(src), config_setting_type(src));
-
- if (newAgg == NULL)
- return;
-
- n = config_setting_length(src);
-
- for (i = 0; i < n; i++) {
- if (config_setting_is_group(src)) {
- config_setting_copy_simple(newAgg, config_setting_get_elem(src, i));
- } else {
- config_setting_copy_elem(newAgg, config_setting_get_elem(src, i));
- }
- }
+ config_setting_t *newAgg;
+ int i, n;
+
+ newAgg = config_setting_add(parent, config_setting_name(src), config_setting_type(src));
+
+ if (newAgg == NULL)
+ return;
+
+ n = config_setting_length(src);
+
+ for (i = 0; i < n; i++) {
+ if (config_setting_is_group(src)) {
+ config_setting_copy_simple(newAgg, config_setting_get_elem(src, i));
+ } else {
+ config_setting_copy_elem(newAgg, config_setting_get_elem(src, i));
+ }
+ }
}
int config_setting_copy(config_setting_t *parent, const config_setting_t *src)
{
- if (!config_setting_is_group(parent) && !config_setting_is_list(parent))
- return CONFIG_FALSE;
-
- if (config_setting_is_aggregate(src)) {
- config_setting_copy_aggregate(parent, src);
- } else {
- config_setting_copy_simple(parent, src);
- }
- return CONFIG_TRUE;
+ if (!config_setting_is_group(parent) && !config_setting_is_list(parent))
+ return CONFIG_FALSE;
+
+ if (config_setting_is_aggregate(src)) {
+ config_setting_copy_aggregate(parent, src);
+ } else {
+ config_setting_copy_simple(parent, src);
+ }
+ return CONFIG_TRUE;
}
diff --git a/src/common/core.c b/src/common/core.c
index efab15dcb..e1f99885b 100644
--- a/src/common/core.c
+++ b/src/common/core.c
@@ -28,7 +28,7 @@
void (*shutdown_callback)(void) = NULL;
#if defined(BUILDBOT)
-int buildbotflag = 0;
+ int buildbotflag = 0;
#endif
int runflag = CORE_ST_RUN;
@@ -38,14 +38,14 @@ char **arg_v = NULL;
char *SERVER_NAME = NULL;
char SERVER_TYPE = ATHENA_SERVER_NONE;
-#ifndef MINICORE // minimalist Core
+#ifndef MINICORE // minimalist Core
// 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_.
//
-#ifdef WIN32 // windows don't have SIGPIPE
+#ifdef WIN32 // windows don't have SIGPIPE
#define SIGPIPE SIGINT
#endif
@@ -54,225 +54,229 @@ char SERVER_TYPE = ATHENA_SERVER_NONE;
#else
sigfunc *compat_signal(int signo, sigfunc *func)
{
- struct sigaction sact, oact;
+ struct sigaction sact, oact;
- sact.sa_handler = func;
- sigemptyset(&sact.sa_mask);
- sact.sa_flags = 0;
+ sact.sa_handler = func;
+ sigemptyset(&sact.sa_mask);
+ sact.sa_flags = 0;
#ifdef SA_INTERRUPT
- sact.sa_flags |= SA_INTERRUPT; /* SunOS */
+ sact.sa_flags |= SA_INTERRUPT; /* SunOS */
#endif
- if (sigaction(signo, &sact, &oact) < 0)
- return (SIG_ERR);
+ if (sigaction(signo, &sact, &oact) < 0)
+ return (SIG_ERR);
- return (oact.sa_handler);
+ return (oact.sa_handler);
}
#endif
/*======================================
- * CORE : Console events for Windows
+ * CORE : Console events for Windows
*--------------------------------------*/
#ifdef _WIN32
static BOOL WINAPI console_handler(DWORD c_event)
{
- switch (c_event) {
- case CTRL_CLOSE_EVENT:
- case CTRL_LOGOFF_EVENT:
- case CTRL_SHUTDOWN_EVENT:
- if (shutdown_callback != NULL)
- shutdown_callback();
- else
- runflag = CORE_ST_STOP;// auto-shutdown
- break;
- default:
- return FALSE;
+ switch(c_event)
+ {
+ case CTRL_CLOSE_EVENT:
+ case CTRL_LOGOFF_EVENT:
+ case CTRL_SHUTDOWN_EVENT:
+ if( shutdown_callback != NULL )
+ shutdown_callback();
+ else
+ runflag = CORE_ST_STOP;// auto-shutdown
+ break;
+ default:
+ return FALSE;
}
return TRUE;
}
static void cevents_init()
{
- if (SetConsoleCtrlHandler(console_handler,TRUE)==FALSE)
- ShowWarning("Unable to install the console handler!\n");
+ if (SetConsoleCtrlHandler(console_handler,TRUE)==FALSE)
+ ShowWarning ("Unable to install the console handler!\n");
}
#endif
/*======================================
- * CORE : Signal Sub Function
+ * CORE : Signal Sub Function
*--------------------------------------*/
static void sig_proc(int sn)
{
- static int is_called = 0;
-
- switch (sn) {
- case SIGINT:
- case SIGTERM:
- if (++is_called > 3)
- exit(EXIT_SUCCESS);
- if (shutdown_callback != NULL)
- shutdown_callback();
- else
- runflag = CORE_ST_STOP;// auto-shutdown
- break;
- case SIGSEGV:
- case SIGFPE:
- do_abort();
- // Pass the signal to the system's default handler
- compat_signal(sn, SIG_DFL);
- raise(sn);
- break;
+ static int is_called = 0;
+
+ switch (sn) {
+ case SIGINT:
+ case SIGTERM:
+ if (++is_called > 3)
+ exit(EXIT_SUCCESS);
+ if( shutdown_callback != NULL )
+ shutdown_callback();
+ else
+ runflag = CORE_ST_STOP;// auto-shutdown
+ break;
+ case SIGSEGV:
+ case SIGFPE:
+ do_abort();
+ // Pass the signal to the system's default handler
+ compat_signal(sn, SIG_DFL);
+ raise(sn);
+ break;
#ifndef _WIN32
- case SIGXFSZ:
- // ignore and allow it to set errno to EFBIG
- ShowWarning("Max file size reached!\n");
- //run_flag = 0; // should we quit?
- break;
- case SIGPIPE:
- //ShowInfo ("Broken pipe found... closing socket\n"); // set to eof in socket.c
- break; // does nothing here
+ case SIGXFSZ:
+ // ignore and allow it to set errno to EFBIG
+ ShowWarning ("Max file size reached!\n");
+ //run_flag = 0; // should we quit?
+ break;
+ case SIGPIPE:
+ //ShowInfo ("Broken pipe found... closing socket\n"); // set to eof in socket.c
+ break; // does nothing here
#endif
- }
+ }
}
-void signals_init(void)
+void signals_init (void)
{
- compat_signal(SIGTERM, sig_proc);
- compat_signal(SIGINT, sig_proc);
+ compat_signal(SIGTERM, sig_proc);
+ compat_signal(SIGINT, sig_proc);
#ifndef _DEBUG // need unhandled exceptions to debug on Windows
- compat_signal(SIGSEGV, sig_proc);
- compat_signal(SIGFPE, sig_proc);
+ compat_signal(SIGSEGV, sig_proc);
+ compat_signal(SIGFPE, sig_proc);
#endif
#ifndef _WIN32
- compat_signal(SIGILL, SIG_DFL);
- compat_signal(SIGXFSZ, sig_proc);
- compat_signal(SIGPIPE, sig_proc);
- compat_signal(SIGBUS, SIG_DFL);
- compat_signal(SIGTRAP, SIG_DFL);
+ compat_signal(SIGILL, SIG_DFL);
+ compat_signal(SIGXFSZ, sig_proc);
+ compat_signal(SIGPIPE, sig_proc);
+ compat_signal(SIGBUS, SIG_DFL);
+ compat_signal(SIGTRAP, SIG_DFL);
#endif
}
#endif
#ifdef SVNVERSION
-const char *get_svn_revision(void)
-{
- return EXPAND_AND_QUOTE(SVNVERSION);
-}
+ const char *get_svn_revision(void)
+ {
+ return EXPAND_AND_QUOTE(SVNVERSION);
+ }
#else// not SVNVERSION
-const char *get_svn_revision(void)
+const char* get_svn_revision(void)
{
- static char svn_version_buffer[16] = "";
- FILE *fp;
-
- if (svn_version_buffer[0] != '\0')
- return svn_version_buffer;
-
- // subversion 1.7 uses a sqlite3 database
- // FIXME this is hackish at best...
- // - ignores database file structure
- // - assumes the data in NODES.dav_cache column ends with "!svn/ver/<revision>/<path>)"
- // - since it's a cache column, the data might not even exist
- if ((fp = fopen(".svn"PATHSEP_STR"wc.db", "rb")) != NULL || (fp = fopen(".."PATHSEP_STR".svn"PATHSEP_STR"wc.db", "rb")) != NULL) {
-#ifndef SVNNODEPATH
- //not sure how to handle branches, so i'll leave this overridable define until a better solution comes up
-#define SVNNODEPATH trunk
-#endif
- const char *prefix = "!svn/ver/";
- const char *postfix = "/"EXPAND_AND_QUOTE(SVNNODEPATH)")"; // there should exist only 1 entry like this
- size_t prefix_len = strlen(prefix);
- size_t postfix_len = strlen(postfix);
- size_t i,j,len;
- char *buffer;
-
- // read file to buffer
- fseek(fp, 0, SEEK_END);
- len = ftell(fp);
- buffer = (char *)aMalloc(len + 1);
- fseek(fp, 0, SEEK_SET);
- len = fread(buffer, 1, len, fp);
- buffer[len] = '\0';
- fclose(fp);
-
- // parse buffer
- for (i = prefix_len + 1; i + postfix_len <= len; ++i) {
- if (buffer[i] != postfix[0] || memcmp(buffer + i, postfix, postfix_len) != 0)
- continue; // postfix missmatch
- for (j = i; j > 0; --j) {
- // skip digits
- if (!ISDIGIT(buffer[j - 1]))
- break;
- }
- if (memcmp(buffer + j - prefix_len, prefix, prefix_len) != 0)
- continue; // prefix missmatch
- // done
- snprintf(svn_version_buffer, sizeof(svn_version_buffer), "%d", atoi(buffer + j));
- break;
- }
- aFree(buffer);
-
- if (svn_version_buffer[0] != '\0')
- return svn_version_buffer;
- }
-
- // subversion 1.6 and older?
- if ((fp = fopen(".svn/entries", "r")) != NULL) {
- char line[1024];
- int rev;
- // Check the version
- if (fgets(line, sizeof(line), fp)) {
- if (!ISDIGIT(line[0])) {
- // XML File format
- while (fgets(line,sizeof(line),fp))
- if (strstr(line,"revision=")) break;
- if (sscanf(line," %*[^\"]\"%d%*[^\n]", &rev) == 1) {
- snprintf(svn_version_buffer, sizeof(svn_version_buffer), "%d", rev);
- }
- } else {
- // Bin File format
- if (fgets(line, sizeof(line), fp) == NULL) {
- printf("Can't get bin name\n"); // Get the name
- }
- if (fgets(line, sizeof(line), fp) == NULL) {
- printf("Can't get entries kind\n"); // Get the entries kind
- }
- if (fgets(line, sizeof(line), fp)) { // Get the rev numver
- snprintf(svn_version_buffer, sizeof(svn_version_buffer), "%d", atoi(line));
- }
- }
- }
- fclose(fp);
-
- if (svn_version_buffer[0] != '\0')
- return svn_version_buffer;
- }
-
- // fallback
- snprintf(svn_version_buffer, sizeof(svn_version_buffer), "Unknown");
- return svn_version_buffer;
+ static char svn_version_buffer[16] = "";
+ FILE *fp;
+
+ if( svn_version_buffer[0] != '\0' )
+ return svn_version_buffer;
+
+ // subversion 1.7 uses a sqlite3 database
+ // FIXME this is hackish at best...
+ // - ignores database file structure
+ // - assumes the data in NODES.dav_cache column ends with "!svn/ver/<revision>/<path>)"
+ // - since it's a cache column, the data might not even exist
+ if( (fp = fopen(".svn"PATHSEP_STR"wc.db", "rb")) != NULL || (fp = fopen(".."PATHSEP_STR".svn"PATHSEP_STR"wc.db", "rb")) != NULL )
+ {
+ #ifndef SVNNODEPATH
+ //not sure how to handle branches, so i'll leave this overridable define until a better solution comes up
+ #define SVNNODEPATH trunk
+ #endif
+ const char* prefix = "!svn/ver/";
+ const char* postfix = "/"EXPAND_AND_QUOTE(SVNNODEPATH)")"; // there should exist only 1 entry like this
+ size_t prefix_len = strlen(prefix);
+ size_t postfix_len = strlen(postfix);
+ size_t i,j,len;
+ char* buffer;
+
+ // read file to buffer
+ fseek(fp, 0, SEEK_END);
+ len = ftell(fp);
+ buffer = (char*)aMalloc(len + 1);
+ fseek(fp, 0, SEEK_SET);
+ len = fread(buffer, 1, len, fp);
+ buffer[len] = '\0';
+ fclose(fp);
+
+ // parse buffer
+ for( i = prefix_len + 1; i + postfix_len <= len; ++i )
+ {
+ if( buffer[i] != postfix[0] || memcmp(buffer + i, postfix, postfix_len) != 0 )
+ continue; // postfix missmatch
+ for( j = i; j > 0; --j )
+ {// skip digits
+ if( !ISDIGIT(buffer[j - 1]) )
+ break;
+ }
+ if( memcmp(buffer + j - prefix_len, prefix, prefix_len) != 0 )
+ continue; // prefix missmatch
+ // done
+ snprintf(svn_version_buffer, sizeof(svn_version_buffer), "%d", atoi(buffer + j));
+ break;
+ }
+ aFree(buffer);
+
+ if( svn_version_buffer[0] != '\0' )
+ return svn_version_buffer;
+ }
+
+ // subversion 1.6 and older?
+ if ((fp = fopen(".svn/entries", "r")) != NULL)
+ {
+ char line[1024];
+ int rev;
+ // Check the version
+ if (fgets(line, sizeof(line), fp))
+ {
+ if(!ISDIGIT(line[0]))
+ {
+ // XML File format
+ while (fgets(line,sizeof(line),fp))
+ if (strstr(line,"revision=")) break;
+ if (sscanf(line," %*[^\"]\"%d%*[^\n]", &rev) == 1) {
+ snprintf(svn_version_buffer, sizeof(svn_version_buffer), "%d", rev);
+ }
+ }
+ else
+ {
+ // Bin File format
+ if ( fgets(line, sizeof(line), fp) == NULL ) { printf("Can't get bin name\n"); } // Get the name
+ if ( fgets(line, sizeof(line), fp) == NULL ) { printf("Can't get entries kind\n"); } // Get the entries kind
+ if(fgets(line, sizeof(line), fp)) // Get the rev numver
+ {
+ snprintf(svn_version_buffer, sizeof(svn_version_buffer), "%d", atoi(line));
+ }
+ }
+ }
+ fclose(fp);
+
+ if( svn_version_buffer[0] != '\0' )
+ return svn_version_buffer;
+ }
+
+ // fallback
+ snprintf(svn_version_buffer, sizeof(svn_version_buffer), "Unknown");
+ return svn_version_buffer;
}
#endif
/*======================================
- * CORE : Display title
+ * CORE : Display title
* ASCII By CalciumKid 1/12/2011
*--------------------------------------*/
-static void display_title(void)
-{
- //ClearScreen(); // clear screen and go up/left (0, 0 position in text)
-
- ShowMessage("\n");
- ShowMessage(""CL_PASS" "CL_BOLD" "CL_PASS""CL_CLL""CL_NORMAL"\n");
- ShowMessage(""CL_PASS" "CL_BT_WHITE" rAthena Development Team presents "CL_PASS""CL_CLL""CL_NORMAL"\n");
- ShowMessage(""CL_PASS" "CL_BOLD" ___ __ __ "CL_PASS""CL_CLL""CL_NORMAL"\n");
- ShowMessage(""CL_PASS" "CL_BOLD" _____/ | / /_/ /_ ___ ____ ____ _ "CL_PASS""CL_CLL""CL_NORMAL"\n");
- ShowMessage(""CL_PASS" "CL_BOLD" / ___/ /| |/ __/ __ \\/ _ \\/ __ \\/ __ `/ "CL_PASS""CL_CLL""CL_NORMAL"\n");
- ShowMessage(""CL_PASS" "CL_BOLD" / / / ___ / /_/ / / / __/ / / / /_/ / "CL_PASS""CL_CLL""CL_NORMAL"\n");
- ShowMessage(""CL_PASS" "CL_BOLD" /_/ /_/ |_\\__/_/ /_/\\___/_/ /_/\\__,_/ "CL_PASS""CL_CLL""CL_NORMAL"\n");
- ShowMessage(""CL_PASS" "CL_BOLD" "CL_PASS""CL_CLL""CL_NORMAL"\n");
- ShowMessage(""CL_PASS" "CL_GREEN" http://rathena.org/board/ "CL_PASS""CL_CLL""CL_NORMAL"\n");
- ShowMessage(""CL_PASS" "CL_BOLD" "CL_PASS""CL_CLL""CL_NORMAL"\n");
-
- ShowInfo("SVN Revision: '"CL_WHITE"%s"CL_RESET"'.\n", get_svn_revision());
+static void display_title(void) {
+ //ClearScreen(); // clear screen and go up/left (0, 0 position in text)
+
+ ShowMessage("\n");
+ ShowMessage(""CL_PASS" "CL_BOLD" "CL_PASS""CL_CLL""CL_NORMAL"\n");
+ ShowMessage(""CL_PASS" "CL_BT_WHITE" rAthena Development Team presents "CL_PASS""CL_CLL""CL_NORMAL"\n");
+ ShowMessage(""CL_PASS" "CL_BOLD" ___ __ __ "CL_PASS""CL_CLL""CL_NORMAL"\n");
+ ShowMessage(""CL_PASS" "CL_BOLD" _____/ | / /_/ /_ ___ ____ ____ _ "CL_PASS""CL_CLL""CL_NORMAL"\n");
+ ShowMessage(""CL_PASS" "CL_BOLD" / ___/ /| |/ __/ __ \\/ _ \\/ __ \\/ __ `/ "CL_PASS""CL_CLL""CL_NORMAL"\n");
+ ShowMessage(""CL_PASS" "CL_BOLD" / / / ___ / /_/ / / / __/ / / / /_/ / "CL_PASS""CL_CLL""CL_NORMAL"\n");
+ ShowMessage(""CL_PASS" "CL_BOLD" /_/ /_/ |_\\__/_/ /_/\\___/_/ /_/\\__,_/ "CL_PASS""CL_CLL""CL_NORMAL"\n");
+ ShowMessage(""CL_PASS" "CL_BOLD" "CL_PASS""CL_CLL""CL_NORMAL"\n");
+ ShowMessage(""CL_PASS" "CL_GREEN" http://rathena.org/board/ "CL_PASS""CL_CLL""CL_NORMAL"\n");
+ ShowMessage(""CL_PASS" "CL_BOLD" "CL_PASS""CL_CLL""CL_NORMAL"\n");
+
+ ShowInfo("SVN Revision: '"CL_WHITE"%s"CL_RESET"'.\n", get_svn_revision());
}
// Warning if executed as superuser (root)
@@ -280,73 +284,72 @@ void usercheck(void)
{
#ifndef _WIN32
if (geteuid() == 0) {
- ShowWarning("You are running rAthena with root privileges, it is not necessary.\n");
+ ShowWarning ("You are running rAthena with root privileges, it is not necessary.\n");
}
#endif
}
/*======================================
- * CORE : MAINROUTINE
+ * CORE : MAINROUTINE
*--------------------------------------*/
-int main(int argc, char **argv)
+int main (int argc, char **argv)
{
- {
- // initialize program arguments
- char *p1 = SERVER_NAME = argv[0];
- char *p2 = p1;
- while ((p1 = strchr(p2, '/')) != NULL || (p1 = strchr(p2, '\\')) != NULL) {
- SERVER_NAME = ++p1;
- p2 = p1;
- }
- arg_c = argc;
- arg_v = argv;
- }
-
- malloc_init();// needed for Show* in display_title() [FlavioJS]
+ {// initialize program arguments
+ char *p1 = SERVER_NAME = argv[0];
+ char *p2 = p1;
+ while ((p1 = strchr(p2, '/')) != NULL || (p1 = strchr(p2, '\\')) != NULL)
+ {
+ SERVER_NAME = ++p1;
+ p2 = p1;
+ }
+ arg_c = argc;
+ arg_v = argv;
+ }
+
+ malloc_init();// needed for Show* in display_title() [FlavioJS]
#ifdef MINICORE // minimalist Core
- display_title();
- usercheck();
- do_init(argc,argv);
- do_final();
+ display_title();
+ usercheck();
+ do_init(argc,argv);
+ do_final();
#else// not MINICORE
- set_server_type();
- display_title();
- usercheck();
+ set_server_type();
+ display_title();
+ usercheck();
- rathread_init();
- mempool_init();
- db_init();
- signals_init();
+ rathread_init();
+ mempool_init();
+ db_init();
+ signals_init();
#ifdef _WIN32
- cevents_init();
+ cevents_init();
#endif
- timer_init();
- socket_init();
+ timer_init();
+ socket_init();
- do_init(argc,argv);
+ do_init(argc,argv);
- {
- // Main runtime cycle
- int next;
- while (runflag != CORE_ST_STOP) {
- next = do_timer(gettick_nocache());
- do_sockets(next);
- }
- }
+ {// Main runtime cycle
+ int next;
+ while (runflag != CORE_ST_STOP) {
+ next = do_timer(gettick_nocache());
+ do_sockets(next);
+ }
+ }
- do_final();
+ do_final();
- timer_final();
- socket_final();
- db_final();
- mempool_final();
- rathread_final();
+ timer_final();
+ socket_final();
+ db_final();
+ mempool_final();
+ rathread_final();
#endif
- malloc_final();
+ malloc_final();
- return 0;
+ return 0;
}
diff --git a/src/common/core.h b/src/common/core.h
index d12723445..d48962c94 100644
--- a/src/common/core.h
+++ b/src/common/core.h
@@ -1,14 +1,14 @@
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder
-#ifndef _CORE_H_
-#define _CORE_H_
+#ifndef _CORE_H_
+#define _CORE_H_
extern int arg_c;
extern char **arg_v;
#if defined(BUILDBOT)
-extern int buildbotflag;
+ extern int buildbotflag;
#endif
/// @see E_CORE_ST
@@ -16,27 +16,28 @@ extern int runflag;
extern char *SERVER_NAME;
enum {
- ATHENA_SERVER_NONE = 0, // not defined
- ATHENA_SERVER_LOGIN = 1, // login server
- ATHENA_SERVER_CHAR = 2, // char server
- ATHENA_SERVER_INTER = 4, // inter server
- ATHENA_SERVER_MAP = 8, // map server
+ ATHENA_SERVER_NONE = 0, // not defined
+ ATHENA_SERVER_LOGIN = 1, // login server
+ ATHENA_SERVER_CHAR = 2, // char server
+ ATHENA_SERVER_INTER = 4, // inter server
+ ATHENA_SERVER_MAP = 8, // map server
};
extern char SERVER_TYPE;
-extern int parse_console(const char *buf);
+extern int parse_console(const char* buf);
extern const char *get_svn_revision(void);
-extern int do_init(int,char **);
+extern int do_init(int,char**);
extern void set_server_type(void);
extern void do_abort(void);
extern void do_final(void);
/// The main loop continues until runflag is CORE_ST_STOP
-enum E_CORE_ST {
- CORE_ST_STOP = 0,
- CORE_ST_RUN,
- CORE_ST_LAST
+enum E_CORE_ST
+{
+ CORE_ST_STOP = 0,
+ CORE_ST_RUN,
+ CORE_ST_LAST
};
/// Called when a terminate signal is received. (Ctrl+C pressed)
diff --git a/src/common/db.c b/src/common/db.c
index c5db21a02..204c6d2ea 100644
--- a/src/common/db.c
+++ b/src/common/db.c
@@ -88,7 +88,7 @@
\*****************************************************************************/
/**
- * If defined statistics about database nodes, database creating/destruction
+ * If defined statistics about database nodes, database creating/destruction
* and function usage are keept and displayed when finalizing the database
* system.
* WARNING: This adds overhead to every database operation (not shure how much).
@@ -112,8 +112,8 @@
* @see struct dbn
*/
typedef enum node_color {
- RED,
- BLACK
+ RED,
+ BLACK
} node_color;
/**
@@ -129,16 +129,16 @@ typedef enum node_color {
* @see DBMap_impl#ht
*/
typedef struct dbn {
- // Tree structure
- struct dbn *parent;
- struct dbn *left;
- struct dbn *right;
- // Node data
- DBKey key;
- DBData data;
- // Other
- node_color color;
- unsigned deleted : 1;
+ // Tree structure
+ struct dbn *parent;
+ struct dbn *left;
+ struct dbn *right;
+ // Node data
+ DBKey key;
+ DBData data;
+ // Other
+ node_color color;
+ unsigned deleted : 1;
} *DBNode;
/**
@@ -149,8 +149,8 @@ typedef struct dbn {
* @see DBMap_impl#free_list
*/
struct db_free {
- DBNode node;
- DBNode *root;
+ DBNode node;
+ DBNode *root;
};
/**
@@ -176,28 +176,28 @@ struct db_free {
* @see #db_alloc(const char*,int,DBType,DBOptions,unsigned short)
*/
typedef struct DBMap_impl {
- // Database interface
- struct DBMap vtable;
- // File and line of allocation
- const char *alloc_file;
- int alloc_line;
- // Lock system
- struct db_free *free_list;
- unsigned int free_count;
- unsigned int free_max;
- unsigned int free_lock;
- // Other
- ERS nodes;
- DBComparator cmp;
- DBHasher hash;
- DBReleaser release;
- DBNode ht[HASH_SIZE];
- DBNode cache;
- DBType type;
- DBOptions options;
- uint32 item_count;
- unsigned short maxlen;
- unsigned global_lock : 1;
+ // Database interface
+ struct DBMap vtable;
+ // File and line of allocation
+ const char *alloc_file;
+ int alloc_line;
+ // Lock system
+ struct db_free *free_list;
+ unsigned int free_count;
+ unsigned int free_max;
+ unsigned int free_lock;
+ // Other
+ ERS nodes;
+ DBComparator cmp;
+ DBHasher hash;
+ DBReleaser release;
+ DBNode ht[HASH_SIZE];
+ DBNode cache;
+ DBType type;
+ DBOptions options;
+ uint32 item_count;
+ unsigned short maxlen;
+ unsigned global_lock : 1;
} DBMap_impl;
/**
@@ -212,11 +212,11 @@ typedef struct DBMap_impl {
* @see #DBNode
*/
typedef struct DBIterator_impl {
- // Iterator interface
- struct DBIterator vtable;
- DBMap_impl *db;
- int ht_index;
- DBNode node;
+ // Iterator interface
+ struct DBIterator vtable;
+ DBMap_impl* db;
+ int ht_index;
+ DBNode node;
} DBIterator_impl;
#if defined(DB_ENABLE_STATS)
@@ -227,92 +227,92 @@ typedef struct DBIterator_impl {
* @see #stats
*/
static struct db_stats {
- // Node alloc/free
- uint32 db_node_alloc;
- uint32 db_node_free;
- // Database creating/destruction counters
- uint32 db_int_alloc;
- uint32 db_uint_alloc;
- uint32 db_string_alloc;
- uint32 db_istring_alloc;
- uint32 db_int_destroy;
- uint32 db_uint_destroy;
- uint32 db_string_destroy;
- uint32 db_istring_destroy;
- // Function usage counters
- uint32 db_rotate_left;
- uint32 db_rotate_right;
- uint32 db_rebalance;
- uint32 db_rebalance_erase;
- uint32 db_is_key_null;
- uint32 db_dup_key;
- uint32 db_dup_key_free;
- uint32 db_free_add;
- uint32 db_free_remove;
- uint32 db_free_lock;
- uint32 db_free_unlock;
- uint32 db_int_cmp;
- uint32 db_uint_cmp;
- uint32 db_string_cmp;
- uint32 db_istring_cmp;
- uint32 db_int_hash;
- uint32 db_uint_hash;
- uint32 db_string_hash;
- uint32 db_istring_hash;
- uint32 db_release_nothing;
- uint32 db_release_key;
- uint32 db_release_data;
- uint32 db_release_both;
- uint32 dbit_first;
- uint32 dbit_last;
- uint32 dbit_next;
- uint32 dbit_prev;
- uint32 dbit_exists;
- uint32 dbit_remove;
- uint32 dbit_destroy;
- uint32 db_iterator;
- uint32 db_exists;
- uint32 db_get;
- uint32 db_getall;
- uint32 db_vgetall;
- uint32 db_ensure;
- uint32 db_vensure;
- uint32 db_put;
- uint32 db_remove;
- uint32 db_foreach;
- uint32 db_vforeach;
- uint32 db_clear;
- uint32 db_vclear;
- uint32 db_destroy;
- uint32 db_vdestroy;
- uint32 db_size;
- uint32 db_type;
- uint32 db_options;
- uint32 db_fix_options;
- uint32 db_default_cmp;
- uint32 db_default_hash;
- uint32 db_default_release;
- uint32 db_custom_release;
- uint32 db_alloc;
- uint32 db_i2key;
- uint32 db_ui2key;
- uint32 db_str2key;
- uint32 db_i2data;
- uint32 db_ui2data;
- uint32 db_ptr2data;
- uint32 db_data2i;
- uint32 db_data2ui;
- uint32 db_data2ptr;
- uint32 db_init;
- uint32 db_final;
+ // Node alloc/free
+ uint32 db_node_alloc;
+ uint32 db_node_free;
+ // Database creating/destruction counters
+ uint32 db_int_alloc;
+ uint32 db_uint_alloc;
+ uint32 db_string_alloc;
+ uint32 db_istring_alloc;
+ uint32 db_int_destroy;
+ uint32 db_uint_destroy;
+ uint32 db_string_destroy;
+ uint32 db_istring_destroy;
+ // Function usage counters
+ uint32 db_rotate_left;
+ uint32 db_rotate_right;
+ uint32 db_rebalance;
+ uint32 db_rebalance_erase;
+ uint32 db_is_key_null;
+ uint32 db_dup_key;
+ uint32 db_dup_key_free;
+ uint32 db_free_add;
+ uint32 db_free_remove;
+ uint32 db_free_lock;
+ uint32 db_free_unlock;
+ uint32 db_int_cmp;
+ uint32 db_uint_cmp;
+ uint32 db_string_cmp;
+ uint32 db_istring_cmp;
+ uint32 db_int_hash;
+ uint32 db_uint_hash;
+ uint32 db_string_hash;
+ uint32 db_istring_hash;
+ uint32 db_release_nothing;
+ uint32 db_release_key;
+ uint32 db_release_data;
+ uint32 db_release_both;
+ uint32 dbit_first;
+ uint32 dbit_last;
+ uint32 dbit_next;
+ uint32 dbit_prev;
+ uint32 dbit_exists;
+ uint32 dbit_remove;
+ uint32 dbit_destroy;
+ uint32 db_iterator;
+ uint32 db_exists;
+ uint32 db_get;
+ uint32 db_getall;
+ uint32 db_vgetall;
+ uint32 db_ensure;
+ uint32 db_vensure;
+ uint32 db_put;
+ uint32 db_remove;
+ uint32 db_foreach;
+ uint32 db_vforeach;
+ uint32 db_clear;
+ uint32 db_vclear;
+ uint32 db_destroy;
+ uint32 db_vdestroy;
+ uint32 db_size;
+ uint32 db_type;
+ uint32 db_options;
+ uint32 db_fix_options;
+ uint32 db_default_cmp;
+ uint32 db_default_hash;
+ uint32 db_default_release;
+ uint32 db_custom_release;
+ uint32 db_alloc;
+ uint32 db_i2key;
+ uint32 db_ui2key;
+ uint32 db_str2key;
+ uint32 db_i2data;
+ uint32 db_ui2data;
+ uint32 db_ptr2data;
+ uint32 db_data2i;
+ uint32 db_data2ui;
+ uint32 db_data2ptr;
+ uint32 db_init;
+ uint32 db_final;
} stats = {
- 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, 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, 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
};
#define DB_COUNTSTAT(token) if (stats. ## token != UINT32_MAX) ++stats. ## token
#else /* !defined(DB_ENABLE_STATS) */
@@ -346,25 +346,25 @@ static struct db_stats {
*/
static void db_rotate_left(DBNode node, DBNode *root)
{
- DBNode y = node->right;
+ DBNode y = node->right;
- DB_COUNTSTAT(db_rotate_left);
- // put the left of y at the right of node
- node->right = y->left;
- if (y->left)
- y->left->parent = node;
- y->parent = node->parent;
- // link y and node's parent
- if (node == *root) {
- *root = y; // node was root
- } else if (node == node->parent->left) {
- node->parent->left = y; // node was at the left
- } else {
- node->parent->right = y; // node was at the right
- }
- // put node at the left of y
- y->left = node;
- node->parent = y;
+ DB_COUNTSTAT(db_rotate_left);
+ // put the left of y at the right of node
+ node->right = y->left;
+ if (y->left)
+ y->left->parent = node;
+ y->parent = node->parent;
+ // link y and node's parent
+ if (node == *root) {
+ *root = y; // node was root
+ } else if (node == node->parent->left) {
+ node->parent->left = y; // node was at the left
+ } else {
+ node->parent->right = y; // node was at the right
+ }
+ // put node at the left of y
+ y->left = node;
+ node->parent = y;
}
/**
@@ -377,25 +377,25 @@ static void db_rotate_left(DBNode node, DBNode *root)
*/
static void db_rotate_right(DBNode node, DBNode *root)
{
- DBNode y = node->left;
+ DBNode y = node->left;
- DB_COUNTSTAT(db_rotate_right);
- // put the right of y at the left of node
- node->left = y->right;
- if (y->right != 0)
- y->right->parent = node;
- y->parent = node->parent;
- // link y and node's parent
- if (node == *root) {
- *root = y; // node was root
- } else if (node == node->parent->right) {
- node->parent->right = y; // node was at the right
- } else {
- node->parent->left = y; // node was at the left
- }
- // put node at the right of y
- y->right = node;
- node->parent = y;
+ DB_COUNTSTAT(db_rotate_right);
+ // put the right of y at the left of node
+ node->left = y->right;
+ if (y->right != 0)
+ y->right->parent = node;
+ y->parent = node->parent;
+ // link y and node's parent
+ if (node == *root) {
+ *root = y; // node was root
+ } else if (node == node->parent->right) {
+ node->parent->right = y; // node was at the right
+ } else {
+ node->parent->left = y; // node was at the left
+ }
+ // put node at the right of y
+ y->right = node;
+ node->parent = y;
}
/**
@@ -410,55 +410,55 @@ static void db_rotate_right(DBNode node, DBNode *root)
*/
static void db_rebalance(DBNode node, DBNode *root)
{
- DBNode y;
-
- DB_COUNTSTAT(db_rebalance);
- // Restore the RED-BLACK properties
- node->color = RED;
- while (node != *root && node->parent->color == RED) {
- if (node->parent == node->parent->parent->left) {
- // If node's parent is a left, y is node's right 'uncle'
- y = node->parent->parent->right;
- if (y && y->color == RED) { // case 1
- // change the colors and move up the tree
- node->parent->color = BLACK;
- y->color = BLACK;
- node->parent->parent->color = RED;
- node = node->parent->parent;
- } else {
- if (node == node->parent->right) { // case 2
- // move up and rotate
- node = node->parent;
- db_rotate_left(node, root);
- }
- // case 3
- node->parent->color = BLACK;
- node->parent->parent->color = RED;
- db_rotate_right(node->parent->parent, root);
- }
- } else {
- // If node's parent is a right, y is node's left 'uncle'
- y = node->parent->parent->left;
- if (y && y->color == RED) { // case 1
- // change the colors and move up the tree
- node->parent->color = BLACK;
- y->color = BLACK;
- node->parent->parent->color = RED;
- node = node->parent->parent;
- } else {
- if (node == node->parent->left) { // case 2
- // move up and rotate
- node = node->parent;
- db_rotate_right(node, root);
- }
- // case 3
- node->parent->color = BLACK;
- node->parent->parent->color = RED;
- db_rotate_left(node->parent->parent, root);
- }
- }
- }
- (*root)->color = BLACK; // the root can and should always be black
+ DBNode y;
+
+ DB_COUNTSTAT(db_rebalance);
+ // Restore the RED-BLACK properties
+ node->color = RED;
+ while (node != *root && node->parent->color == RED) {
+ if (node->parent == node->parent->parent->left) {
+ // If node's parent is a left, y is node's right 'uncle'
+ y = node->parent->parent->right;
+ if (y && y->color == RED) { // case 1
+ // change the colors and move up the tree
+ node->parent->color = BLACK;
+ y->color = BLACK;
+ node->parent->parent->color = RED;
+ node = node->parent->parent;
+ } else {
+ if (node == node->parent->right) { // case 2
+ // move up and rotate
+ node = node->parent;
+ db_rotate_left(node, root);
+ }
+ // case 3
+ node->parent->color = BLACK;
+ node->parent->parent->color = RED;
+ db_rotate_right(node->parent->parent, root);
+ }
+ } else {
+ // If node's parent is a right, y is node's left 'uncle'
+ y = node->parent->parent->left;
+ if (y && y->color == RED) { // case 1
+ // change the colors and move up the tree
+ node->parent->color = BLACK;
+ y->color = BLACK;
+ node->parent->parent->color = RED;
+ node = node->parent->parent;
+ } else {
+ if (node == node->parent->left) { // case 2
+ // move up and rotate
+ node = node->parent;
+ db_rotate_right(node, root);
+ }
+ // case 3
+ node->parent->color = BLACK;
+ node->parent->parent->color = RED;
+ db_rotate_left(node->parent->parent, root);
+ }
+ }
+ }
+ (*root)->color = BLACK; // the root can and should always be black
}
/**
@@ -472,133 +472,133 @@ static void db_rebalance(DBNode node, DBNode *root)
*/
static void db_rebalance_erase(DBNode node, DBNode *root)
{
- DBNode y = node;
- DBNode x = NULL;
- DBNode x_parent = NULL;
- DBNode w;
-
- DB_COUNTSTAT(db_rebalance_erase);
- // Select where to change the tree
- if (y->left == NULL) { // no left
- x = y->right;
- } else if (y->right == NULL) { // no right
- x = y->left;
- } else { // both exist, go to the leftmost node of the right sub-tree
- y = y->right;
- while (y->left != NULL)
- y = y->left;
- x = y->right;
- }
-
- // Remove the node from the tree
- if (y != node) { // both childs existed
- // put the left of 'node' in the left of 'y'
- node->left->parent = y;
- y->left = node->left;
-
- // 'y' is not the direct child of 'node'
- if (y != node->right) {
- // put 'x' in the old position of 'y'
- x_parent = y->parent;
- if (x) x->parent = y->parent;
- y->parent->left = x;
- // put the right of 'node' in 'y'
- y->right = node->right;
- node->right->parent = y;
- // 'y' is a direct child of 'node'
- } else {
- x_parent = y;
- }
-
- // link 'y' and the parent of 'node'
- if (*root == node) {
- *root = y; // 'node' was the root
- } else if (node->parent->left == node) {
- node->parent->left = y; // 'node' was at the left
- } else {
- node->parent->right = y; // 'node' was at the right
- }
- y->parent = node->parent;
- // switch colors
- {
- node_color tmp = y->color;
- y->color = node->color;
- node->color = tmp;
- }
- y = node;
- } else { // one child did not exist
- // put x in node's position
- x_parent = y->parent;
- if (x) x->parent = y->parent;
- // link x and node's parent
- if (*root == node) {
- *root = x; // node was the root
- } else if (node->parent->left == node) {
- node->parent->left = x; // node was at the left
- } else {
- node->parent->right = x; // node was at the right
- }
- }
-
- // Restore the RED-BLACK properties
- if (y->color != RED) {
- while (x != *root && (x == NULL || x->color == BLACK)) {
- if (x == x_parent->left) {
- w = x_parent->right;
- if (w->color == RED) {
- w->color = BLACK;
- x_parent->color = RED;
- db_rotate_left(x_parent, root);
- w = x_parent->right;
- }
- if ((w->left == NULL || w->left->color == BLACK) &&
- (w->right == NULL || w->right->color == BLACK)) {
- w->color = RED;
- x = x_parent;
- x_parent = x_parent->parent;
- } else {
- if (w->right == NULL || w->right->color == BLACK) {
- if (w->left) w->left->color = BLACK;
- w->color = RED;
- db_rotate_right(w, root);
- w = x_parent->right;
- }
- w->color = x_parent->color;
- x_parent->color = BLACK;
- if (w->right) w->right->color = BLACK;
- db_rotate_left(x_parent, root);
- break;
- }
- } else {
- w = x_parent->left;
- if (w->color == RED) {
- w->color = BLACK;
- x_parent->color = RED;
- db_rotate_right(x_parent, root);
- w = x_parent->left;
- }
- if ((w->right == NULL || w->right->color == BLACK) &&
- (w->left == NULL || w->left->color == BLACK)) {
- w->color = RED;
- x = x_parent;
- x_parent = x_parent->parent;
- } else {
- if (w->left == NULL || w->left->color == BLACK) {
- if (w->right) w->right->color = BLACK;
- w->color = RED;
- db_rotate_left(w, root);
- w = x_parent->left;
- }
- w->color = x_parent->color;
- x_parent->color = BLACK;
- if (w->left) w->left->color = BLACK;
- db_rotate_right(x_parent, root);
- break;
- }
- }
- }
- if (x) x->color = BLACK;
- }
+ DBNode y = node;
+ DBNode x = NULL;
+ DBNode x_parent = NULL;
+ DBNode w;
+
+ DB_COUNTSTAT(db_rebalance_erase);
+ // Select where to change the tree
+ if (y->left == NULL) { // no left
+ x = y->right;
+ } else if (y->right == NULL) { // no right
+ x = y->left;
+ } else { // both exist, go to the leftmost node of the right sub-tree
+ y = y->right;
+ while (y->left != NULL)
+ y = y->left;
+ x = y->right;
+ }
+
+ // Remove the node from the tree
+ if (y != node) { // both childs existed
+ // put the left of 'node' in the left of 'y'
+ node->left->parent = y;
+ y->left = node->left;
+
+ // 'y' is not the direct child of 'node'
+ if (y != node->right) {
+ // put 'x' in the old position of 'y'
+ x_parent = y->parent;
+ if (x) x->parent = y->parent;
+ y->parent->left = x;
+ // put the right of 'node' in 'y'
+ y->right = node->right;
+ node->right->parent = y;
+ // 'y' is a direct child of 'node'
+ } else {
+ x_parent = y;
+ }
+
+ // link 'y' and the parent of 'node'
+ if (*root == node) {
+ *root = y; // 'node' was the root
+ } else if (node->parent->left == node) {
+ node->parent->left = y; // 'node' was at the left
+ } else {
+ node->parent->right = y; // 'node' was at the right
+ }
+ y->parent = node->parent;
+ // switch colors
+ {
+ node_color tmp = y->color;
+ y->color = node->color;
+ node->color = tmp;
+ }
+ y = node;
+ } else { // one child did not exist
+ // put x in node's position
+ x_parent = y->parent;
+ if (x) x->parent = y->parent;
+ // link x and node's parent
+ if (*root == node) {
+ *root = x; // node was the root
+ } else if (node->parent->left == node) {
+ node->parent->left = x; // node was at the left
+ } else {
+ node->parent->right = x; // node was at the right
+ }
+ }
+
+ // Restore the RED-BLACK properties
+ if (y->color != RED) {
+ while (x != *root && (x == NULL || x->color == BLACK)) {
+ if (x == x_parent->left) {
+ w = x_parent->right;
+ if (w->color == RED) {
+ w->color = BLACK;
+ x_parent->color = RED;
+ db_rotate_left(x_parent, root);
+ w = x_parent->right;
+ }
+ if ((w->left == NULL || w->left->color == BLACK) &&
+ (w->right == NULL || w->right->color == BLACK)) {
+ w->color = RED;
+ x = x_parent;
+ x_parent = x_parent->parent;
+ } else {
+ if (w->right == NULL || w->right->color == BLACK) {
+ if (w->left) w->left->color = BLACK;
+ w->color = RED;
+ db_rotate_right(w, root);
+ w = x_parent->right;
+ }
+ w->color = x_parent->color;
+ x_parent->color = BLACK;
+ if (w->right) w->right->color = BLACK;
+ db_rotate_left(x_parent, root);
+ break;
+ }
+ } else {
+ w = x_parent->left;
+ if (w->color == RED) {
+ w->color = BLACK;
+ x_parent->color = RED;
+ db_rotate_right(x_parent, root);
+ w = x_parent->left;
+ }
+ if ((w->right == NULL || w->right->color == BLACK) &&
+ (w->left == NULL || w->left->color == BLACK)) {
+ w->color = RED;
+ x = x_parent;
+ x_parent = x_parent->parent;
+ } else {
+ if (w->left == NULL || w->left->color == BLACK) {
+ if (w->right) w->right->color = BLACK;
+ w->color = RED;
+ db_rotate_left(w, root);
+ w = x_parent->left;
+ }
+ w->color = x_parent->color;
+ x_parent->color = BLACK;
+ if (w->left) w->left->color = BLACK;
+ db_rotate_right(x_parent, root);
+ break;
+ }
+ }
+ }
+ if (x) x->color = BLACK;
+ }
}
/**
@@ -613,15 +613,15 @@ static void db_rebalance_erase(DBNode node, DBNode *root)
*/
static int db_is_key_null(DBType type, DBKey key)
{
- DB_COUNTSTAT(db_is_key_null);
- switch (type) {
- case DB_STRING:
- case DB_ISTRING:
- return (key.str == NULL);
+ DB_COUNTSTAT(db_is_key_null);
+ switch (type) {
+ case DB_STRING:
+ case DB_ISTRING:
+ return (key.str == NULL);
- default: // Not a pointer
- return 0;
- }
+ default: // Not a pointer
+ return 0;
+ }
}
/**
@@ -635,25 +635,25 @@ static int db_is_key_null(DBType type, DBKey key)
* @see #db_obj_put(DBMap*,DBKey,void *)
* @see #db_dup_key_free(DBMap_impl*,DBKey)
*/
-static DBKey db_dup_key(DBMap_impl *db, DBKey key)
+static DBKey db_dup_key(DBMap_impl* db, DBKey key)
{
- char *str;
- size_t len;
+ char *str;
+ size_t len;
- DB_COUNTSTAT(db_dup_key);
- switch (db->type) {
- case DB_STRING:
- case DB_ISTRING:
- len = strnlen(key.str, db->maxlen);
- str = (char *)aMalloc(len + 1);
- memcpy(str, key.str, len);
- str[len] = '\0';
- key.str = str;
- return key;
+ DB_COUNTSTAT(db_dup_key);
+ switch (db->type) {
+ case DB_STRING:
+ case DB_ISTRING:
+ len = strnlen(key.str, db->maxlen);
+ str = (char*)aMalloc(len + 1);
+ memcpy(str, key.str, len);
+ str[len] = '\0';
+ key.str = str;
+ return key;
- default:
- return key;
- }
+ default:
+ return key;
+ }
}
/**
@@ -663,18 +663,18 @@ static DBKey db_dup_key(DBMap_impl *db, DBKey key)
* @private
* @see #db_dup_key(DBMap_impl*,DBKey)
*/
-static void db_dup_key_free(DBMap_impl *db, DBKey key)
+static void db_dup_key_free(DBMap_impl* db, DBKey key)
{
- DB_COUNTSTAT(db_dup_key_free);
- switch (db->type) {
- case DB_STRING:
- case DB_ISTRING:
- aFree((char *)key.str);
- return;
+ DB_COUNTSTAT(db_dup_key_free);
+ switch (db->type) {
+ case DB_STRING:
+ case DB_ISTRING:
+ aFree((char*)key.str);
+ return;
- default:
- return;
- }
+ default:
+ return;
+ }
}
/**
@@ -692,40 +692,40 @@ static void db_dup_key_free(DBMap_impl *db, DBKey key)
* @see #db_obj_remove(DBMap*,DBKey)
* @see #db_free_remove(DBMap_impl*,DBNode)
*/
-static void db_free_add(DBMap_impl *db, DBNode node, DBNode *root)
-{
- DBKey old_key;
-
- DB_COUNTSTAT(db_free_add);
- if (db->free_lock == (unsigned int)~0) {
- ShowFatalError("db_free_add: free_lock overflow\n"
- "Database allocated at %s:%d\n",
- db->alloc_file, db->alloc_line);
- exit(EXIT_FAILURE);
- }
- if (!(db->options&DB_OPT_DUP_KEY)) { // Make sure we have a key until the node is freed
- old_key = node->key;
- node->key = db_dup_key(db, node->key);
- db->release(old_key, node->data, DB_RELEASE_KEY);
- }
- if (db->free_count == db->free_max) { // No more space, expand free_list
- db->free_max = (db->free_max<<2) +3; // = db->free_max*4 +3
- if (db->free_max <= db->free_count) {
- if (db->free_count == (unsigned int)~0) {
- ShowFatalError("db_free_add: free_count overflow\n"
- "Database allocated at %s:%d\n",
- db->alloc_file, db->alloc_line);
- exit(EXIT_FAILURE);
- }
- db->free_max = (unsigned int)~0;
- }
- RECREATE(db->free_list, struct db_free, db->free_max);
- }
- node->deleted = 1;
- db->free_list[db->free_count].node = node;
- db->free_list[db->free_count].root = root;
- db->free_count++;
- db->item_count--;
+static void db_free_add(DBMap_impl* db, DBNode node, DBNode *root)
+{
+ DBKey old_key;
+
+ DB_COUNTSTAT(db_free_add);
+ if (db->free_lock == (unsigned int)~0) {
+ ShowFatalError("db_free_add: free_lock overflow\n"
+ "Database allocated at %s:%d\n",
+ db->alloc_file, db->alloc_line);
+ exit(EXIT_FAILURE);
+ }
+ if (!(db->options&DB_OPT_DUP_KEY)) { // Make sure we have a key until the node is freed
+ old_key = node->key;
+ node->key = db_dup_key(db, node->key);
+ db->release(old_key, node->data, DB_RELEASE_KEY);
+ }
+ if (db->free_count == db->free_max) { // No more space, expand free_list
+ db->free_max = (db->free_max<<2) +3; // = db->free_max*4 +3
+ if (db->free_max <= db->free_count) {
+ if (db->free_count == (unsigned int)~0) {
+ ShowFatalError("db_free_add: free_count overflow\n"
+ "Database allocated at %s:%d\n",
+ db->alloc_file, db->alloc_line);
+ exit(EXIT_FAILURE);
+ }
+ db->free_max = (unsigned int)~0;
+ }
+ RECREATE(db->free_list, struct db_free, db->free_max);
+ }
+ node->deleted = 1;
+ db->free_list[db->free_count].node = node;
+ db->free_list[db->free_count].root = root;
+ db->free_count++;
+ db->item_count--;
}
/**
@@ -741,26 +741,26 @@ static void db_free_add(DBMap_impl *db, DBNode node, DBNode *root)
* @see #db_obj_put(DBMap*,DBKey,DBData)
* @see #db_free_add(DBMap_impl*,DBNode*,DBNode)
*/
-static void db_free_remove(DBMap_impl *db, DBNode node)
+static void db_free_remove(DBMap_impl* db, DBNode node)
{
- unsigned int i;
+ unsigned int i;
- DB_COUNTSTAT(db_free_remove);
- for (i = 0; i < db->free_count; i++) {
- if (db->free_list[i].node == node) {
- if (i < db->free_count -1) // copy the last item to where the removed one was
- memcpy(&db->free_list[i], &db->free_list[db->free_count -1], sizeof(struct db_free));
- db_dup_key_free(db, node->key);
- break;
- }
- }
- node->deleted = 0;
- if (i == db->free_count) {
- ShowWarning("db_free_remove: node was not found - database allocated at %s:%d\n", db->alloc_file, db->alloc_line);
- } else {
- db->free_count--;
- }
- db->item_count++;
+ DB_COUNTSTAT(db_free_remove);
+ for (i = 0; i < db->free_count; i++) {
+ if (db->free_list[i].node == node) {
+ if (i < db->free_count -1) // copy the last item to where the removed one was
+ memcpy(&db->free_list[i], &db->free_list[db->free_count -1], sizeof(struct db_free));
+ db_dup_key_free(db, node->key);
+ break;
+ }
+ }
+ node->deleted = 0;
+ if (i == db->free_count) {
+ ShowWarning("db_free_remove: node was not found - database allocated at %s:%d\n", db->alloc_file, db->alloc_line);
+ } else {
+ db->free_count--;
+ }
+ db->item_count++;
}
/**
@@ -770,16 +770,16 @@ static void db_free_remove(DBMap_impl *db, DBNode node)
* @see DBMap_impl#free_lock
* @see #db_unlock(DBMap_impl*)
*/
-static void db_free_lock(DBMap_impl *db)
+static void db_free_lock(DBMap_impl* db)
{
- DB_COUNTSTAT(db_free_lock);
- if (db->free_lock == (unsigned int)~0) {
- ShowFatalError("db_free_lock: free_lock overflow\n"
- "Database allocated at %s:%d\n",
- db->alloc_file, db->alloc_line);
- exit(EXIT_FAILURE);
- }
- db->free_lock++;
+ DB_COUNTSTAT(db_free_lock);
+ if (db->free_lock == (unsigned int)~0) {
+ ShowFatalError("db_free_lock: free_lock overflow\n"
+ "Database allocated at %s:%d\n",
+ db->alloc_file, db->alloc_line);
+ exit(EXIT_FAILURE);
+ }
+ db->free_lock++;
}
/**
@@ -793,28 +793,28 @@ static void db_free_lock(DBMap_impl *db)
* @see #db_free_dbn(DBNode)
* @see #db_lock(DBMap_impl*)
*/
-static void db_free_unlock(DBMap_impl *db)
+static void db_free_unlock(DBMap_impl* db)
{
- unsigned int i;
+ unsigned int i;
- DB_COUNTSTAT(db_free_unlock);
- if (db->free_lock == 0) {
- ShowWarning("db_free_unlock: free_lock was already 0\n"
- "Database allocated at %s:%d\n",
- db->alloc_file, db->alloc_line);
- } else {
- db->free_lock--;
- }
- if (db->free_lock)
- return; // Not last lock
+ DB_COUNTSTAT(db_free_unlock);
+ if (db->free_lock == 0) {
+ ShowWarning("db_free_unlock: free_lock was already 0\n"
+ "Database allocated at %s:%d\n",
+ db->alloc_file, db->alloc_line);
+ } else {
+ db->free_lock--;
+ }
+ if (db->free_lock)
+ return; // Not last lock
- for (i = 0; i < db->free_count ; i++) {
- db_rebalance_erase(db->free_list[i].node, db->free_list[i].root);
- db_dup_key_free(db, db->free_list[i].node->key);
- DB_COUNTSTAT(db_node_free);
- ers_free(db->nodes, db->free_list[i].node);
- }
- db->free_count = 0;
+ for (i = 0; i < db->free_count ; i++) {
+ db_rebalance_erase(db->free_list[i].node, db->free_list[i].root);
+ db_dup_key_free(db, db->free_list[i].node->key);
+ DB_COUNTSTAT(db_node_free);
+ ers_free(db->nodes, db->free_list[i].node);
+ }
+ db->free_count = 0;
}
/*****************************************************************************\
@@ -850,11 +850,11 @@ static void db_free_unlock(DBMap_impl *db)
*/
static int db_int_cmp(DBKey key1, DBKey key2, unsigned short maxlen)
{
- (void)maxlen;//not used
- DB_COUNTSTAT(db_int_cmp);
- if (key1.i < key2.i) return -1;
- if (key1.i > key2.i) return 1;
- return 0;
+ (void)maxlen;//not used
+ DB_COUNTSTAT(db_int_cmp);
+ if (key1.i < key2.i) return -1;
+ if (key1.i > key2.i) return 1;
+ return 0;
}
/**
@@ -872,11 +872,11 @@ static int db_int_cmp(DBKey key1, DBKey key2, unsigned short maxlen)
*/
static int db_uint_cmp(DBKey key1, DBKey key2, unsigned short maxlen)
{
- (void)maxlen;//not used
- DB_COUNTSTAT(db_uint_cmp);
- if (key1.ui < key2.ui) return -1;
- if (key1.ui > key2.ui) return 1;
- return 0;
+ (void)maxlen;//not used
+ DB_COUNTSTAT(db_uint_cmp);
+ if (key1.ui < key2.ui) return -1;
+ if (key1.ui > key2.ui) return 1;
+ return 0;
}
/**
@@ -893,8 +893,8 @@ static int db_uint_cmp(DBKey key1, DBKey key2, unsigned short maxlen)
*/
static int db_string_cmp(DBKey key1, DBKey key2, unsigned short maxlen)
{
- DB_COUNTSTAT(db_string_cmp);
- return strncmp((const char *)key1.str, (const char *)key2.str, maxlen);
+ DB_COUNTSTAT(db_string_cmp);
+ return strncmp((const char *)key1.str, (const char *)key2.str, maxlen);
}
/**
@@ -911,8 +911,8 @@ static int db_string_cmp(DBKey key1, DBKey key2, unsigned short maxlen)
*/
static int db_istring_cmp(DBKey key1, DBKey key2, unsigned short maxlen)
{
- DB_COUNTSTAT(db_istring_cmp);
- return strncasecmp((const char *)key1.str, (const char *)key2.str, maxlen);
+ DB_COUNTSTAT(db_istring_cmp);
+ return strncasecmp((const char *)key1.str, (const char *)key2.str, maxlen);
}
/**
@@ -928,9 +928,9 @@ static int db_istring_cmp(DBKey key1, DBKey key2, unsigned short maxlen)
*/
static unsigned int db_int_hash(DBKey key, unsigned short maxlen)
{
- (void)maxlen;//not used
- DB_COUNTSTAT(db_int_hash);
- return (unsigned int)key.i;
+ (void)maxlen;//not used
+ DB_COUNTSTAT(db_int_hash);
+ return (unsigned int)key.i;
}
/**
@@ -946,9 +946,9 @@ static unsigned int db_int_hash(DBKey key, unsigned short maxlen)
*/
static unsigned int db_uint_hash(DBKey key, unsigned short maxlen)
{
- (void)maxlen;//not used
- DB_COUNTSTAT(db_uint_hash);
- return key.ui;
+ (void)maxlen;//not used
+ DB_COUNTSTAT(db_uint_hash);
+ return key.ui;
}
/**
@@ -962,20 +962,20 @@ static unsigned int db_uint_hash(DBKey key, unsigned short maxlen)
*/
static unsigned int db_string_hash(DBKey key, unsigned short maxlen)
{
- const char *k = key.str;
- unsigned int hash = 0;
- unsigned short i;
+ const char *k = key.str;
+ unsigned int hash = 0;
+ unsigned short i;
- DB_COUNTSTAT(db_string_hash);
+ DB_COUNTSTAT(db_string_hash);
- for (i = 0; *k; ++i) {
- hash = (hash*33 + ((unsigned char)*k))^(hash>>24);
- k++;
- if (i == maxlen)
- break;
- }
+ for (i = 0; *k; ++i) {
+ hash = (hash*33 + ((unsigned char)*k))^(hash>>24);
+ k++;
+ if (i == maxlen)
+ break;
+ }
- return hash;
+ return hash;
}
/**
@@ -988,20 +988,20 @@ static unsigned int db_string_hash(DBKey key, unsigned short maxlen)
*/
static unsigned int db_istring_hash(DBKey key, unsigned short maxlen)
{
- const char *k = key.str;
- unsigned int hash = 0;
- unsigned short i;
+ const char *k = key.str;
+ unsigned int hash = 0;
+ unsigned short i;
- DB_COUNTSTAT(db_istring_hash);
+ DB_COUNTSTAT(db_istring_hash);
- for (i = 0; *k; i++) {
- hash = (hash*33 + ((unsigned char)TOLOWER(*k)))^(hash>>24);
- k++;
- if (i == maxlen)
- break;
- }
+ for (i = 0; *k; i++) {
+ hash = (hash*33 + ((unsigned char)TOLOWER(*k)))^(hash>>24);
+ k++;
+ if (i == maxlen)
+ break;
+ }
- return hash;
+ return hash;
}
/**
@@ -1015,10 +1015,8 @@ static unsigned int db_istring_hash(DBKey key, unsigned short maxlen)
*/
static void db_release_nothing(DBKey key, DBData data, DBRelease which)
{
- (void)key;
- (void)data;
- (void)which;//not used
- DB_COUNTSTAT(db_release_nothing);
+ (void)key;(void)data;(void)which;//not used
+ DB_COUNTSTAT(db_release_nothing);
}
/**
@@ -1032,9 +1030,9 @@ static void db_release_nothing(DBKey key, DBData data, DBRelease which)
*/
static void db_release_key(DBKey key, DBData data, DBRelease which)
{
- (void)data;//not used
- DB_COUNTSTAT(db_release_key);
- if (which&DB_RELEASE_KEY) aFree((char *)key.str); // needs to be a pointer
+ (void)data;//not used
+ DB_COUNTSTAT(db_release_key);
+ if (which&DB_RELEASE_KEY) aFree((char*)key.str); // needs to be a pointer
}
/**
@@ -1050,9 +1048,9 @@ static void db_release_key(DBKey key, DBData data, DBRelease which)
*/
static void db_release_data(DBKey key, DBData data, DBRelease which)
{
- (void)key;//not used
- DB_COUNTSTAT(db_release_data);
- if (which&DB_RELEASE_DATA && data.type == DB_DATA_PTR) aFree(data.u.ptr);
+ (void)key;//not used
+ DB_COUNTSTAT(db_release_data);
+ if (which&DB_RELEASE_DATA && data.type == DB_DATA_PTR) aFree(data.u.ptr);
}
/**
@@ -1069,9 +1067,9 @@ static void db_release_data(DBKey key, DBData data, DBRelease which)
*/
static void db_release_both(DBKey key, DBData data, DBRelease which)
{
- DB_COUNTSTAT(db_release_both);
- if (which&DB_RELEASE_KEY) aFree((char *)key.str); // needs to be a pointer
- if (which&DB_RELEASE_DATA && data.type == DB_DATA_PTR) aFree(data.u.ptr);
+ DB_COUNTSTAT(db_release_both);
+ if (which&DB_RELEASE_KEY) aFree((char*)key.str); // needs to be a pointer
+ if (which&DB_RELEASE_DATA && data.type == DB_DATA_PTR) aFree(data.u.ptr);
}
/*****************************************************************************\
@@ -1117,16 +1115,16 @@ static void db_release_both(DBKey key, DBData data, DBRelease which)
* @protected
* @see DBIterator#first
*/
-DBData *dbit_obj_first(DBIterator *self, DBKey *out_key)
+DBData* dbit_obj_first(DBIterator* self, DBKey* out_key)
{
- DBIterator_impl *it = (DBIterator_impl *)self;
-
- DB_COUNTSTAT(dbit_first);
- // position before the first entry
- it->ht_index = -1;
- it->node = NULL;
- // get next entry
- return self->next(self, out_key);
+ DBIterator_impl* it = (DBIterator_impl*)self;
+
+ DB_COUNTSTAT(dbit_first);
+ // position before the first entry
+ it->ht_index = -1;
+ it->node = NULL;
+ // get next entry
+ return self->next(self, out_key);
}
/**
@@ -1139,16 +1137,16 @@ DBData *dbit_obj_first(DBIterator *self, DBKey *out_key)
* @protected
* @see DBIterator#last
*/
-DBData *dbit_obj_last(DBIterator *self, DBKey *out_key)
+DBData* dbit_obj_last(DBIterator* self, DBKey* out_key)
{
- DBIterator_impl *it = (DBIterator_impl *)self;
-
- DB_COUNTSTAT(dbit_last);
- // position after the last entry
- it->ht_index = HASH_SIZE;
- it->node = NULL;
- // get previous entry
- return self->prev(self, out_key);
+ DBIterator_impl* it = (DBIterator_impl*)self;
+
+ DB_COUNTSTAT(dbit_last);
+ // position after the last entry
+ it->ht_index = HASH_SIZE;
+ it->node = NULL;
+ // get previous entry
+ return self->prev(self, out_key);
}
/**
@@ -1161,67 +1159,70 @@ DBData *dbit_obj_last(DBIterator *self, DBKey *out_key)
* @protected
* @see DBIterator#next
*/
-DBData *dbit_obj_next(DBIterator *self, DBKey *out_key)
-{
- DBIterator_impl *it = (DBIterator_impl *)self;
- DBNode node;
- DBNode parent;
- struct dbn fake;
-
- DB_COUNTSTAT(dbit_next);
- if (it->ht_index < 0) {
- // get first node
- it->ht_index = 0;
- it->node = NULL;
- }
- node = it->node;
- memset(&fake, 0, sizeof(fake));
- for (; it->ht_index < HASH_SIZE; ++(it->ht_index)) {
- // Iterate in the order: left tree, current node, right tree
- if (node == NULL) {
- // prepare initial node of this hash
- node = it->db->ht[it->ht_index];
- if (node == NULL)
- continue;// next hash
- fake.right = node;
- node = &fake;
- }
-
- while (node) {
- // next node
- if (node->right) {
- // continue in the right subtree
- node = node->right;
- while (node->left)
- node = node->left;// get leftmost node
- } else {
- // continue to the next parent (recursive)
- parent = node->parent;
- while (parent) {
- if (parent->right != node)
- break;
- node = parent;
- parent = node->parent;
- }
- if (parent == NULL) {
- // next hash
- node = NULL;
- break;
- }
- node = parent;
- }
-
- if (!node->deleted) {
- // found next entry
- it->node = node;
- if (out_key)
- memcpy(out_key, &node->key, sizeof(DBKey));
- return &node->data;
- }
- }
- }
- it->node = NULL;
- return NULL;// not found
+DBData* dbit_obj_next(DBIterator* self, DBKey* out_key)
+{
+ DBIterator_impl* it = (DBIterator_impl*)self;
+ DBNode node;
+ DBNode parent;
+ struct dbn fake;
+
+ DB_COUNTSTAT(dbit_next);
+ if( it->ht_index < 0 )
+ {// get first node
+ it->ht_index = 0;
+ it->node = NULL;
+ }
+ node = it->node;
+ memset(&fake, 0, sizeof(fake));
+ for( ; it->ht_index < HASH_SIZE; ++(it->ht_index) )
+ {
+ // Iterate in the order: left tree, current node, right tree
+ if( node == NULL )
+ {// prepare initial node of this hash
+ node = it->db->ht[it->ht_index];
+ if( node == NULL )
+ continue;// next hash
+ fake.right = node;
+ node = &fake;
+ }
+
+ while( node )
+ {// next node
+ if( node->right )
+ {// continue in the right subtree
+ node = node->right;
+ while( node->left )
+ node = node->left;// get leftmost node
+ }
+ else
+ {// continue to the next parent (recursive)
+ parent = node->parent;
+ while( parent )
+ {
+ if( parent->right != node )
+ break;
+ node = parent;
+ parent = node->parent;
+ }
+ if( parent == NULL )
+ {// next hash
+ node = NULL;
+ break;
+ }
+ node = parent;
+ }
+
+ if( !node->deleted )
+ {// found next entry
+ it->node = node;
+ if( out_key )
+ memcpy(out_key, &node->key, sizeof(DBKey));
+ return &node->data;
+ }
+ }
+ }
+ it->node = NULL;
+ return NULL;// not found
}
/**
@@ -1234,90 +1235,93 @@ DBData *dbit_obj_next(DBIterator *self, DBKey *out_key)
* @protected
* @see DBIterator#prev
*/
-DBData *dbit_obj_prev(DBIterator *self, DBKey *out_key)
-{
- DBIterator_impl *it = (DBIterator_impl *)self;
- DBNode node;
- DBNode parent;
- struct dbn fake;
-
- DB_COUNTSTAT(dbit_prev);
- if (it->ht_index >= HASH_SIZE) {
- // get last node
- it->ht_index = HASH_SIZE-1;
- it->node = NULL;
- }
- node = it->node;
- memset(&fake, 0, sizeof(fake));
- for (; it->ht_index >= 0; --(it->ht_index)) {
- // Iterate in the order: right tree, current node, left tree
- if (node == NULL) {
- // prepare initial node of this hash
- node = it->db->ht[it->ht_index];
- if (node == NULL)
- continue;// next hash
- fake.left = node;
- node = &fake;
- }
-
-
- while (node) {
- // next node
- if (node->left) {
- // continue in the left subtree
- node = node->left;
- while (node->right)
- node = node->right;// get rightmost node
- } else {
- // continue to the next parent (recursive)
- parent = node->parent;
- while (parent) {
- if (parent->left != node)
- break;
- node = parent;
- parent = node->parent;
- }
- if (parent == NULL) {
- // next hash
- node = NULL;
- break;
- }
- node = parent;
- }
-
- if (!node->deleted) {
- // found previous entry
- it->node = node;
- if (out_key)
- memcpy(out_key, &node->key, sizeof(DBKey));
- return &node->data;
- }
- }
- }
- it->node = NULL;
- return NULL;// not found
+DBData* dbit_obj_prev(DBIterator* self, DBKey* out_key)
+{
+ DBIterator_impl* it = (DBIterator_impl*)self;
+ DBNode node;
+ DBNode parent;
+ struct dbn fake;
+
+ DB_COUNTSTAT(dbit_prev);
+ if( it->ht_index >= HASH_SIZE )
+ {// get last node
+ it->ht_index = HASH_SIZE-1;
+ it->node = NULL;
+ }
+ node = it->node;
+ memset(&fake, 0, sizeof(fake));
+ for( ; it->ht_index >= 0; --(it->ht_index) )
+ {
+ // Iterate in the order: right tree, current node, left tree
+ if( node == NULL )
+ {// prepare initial node of this hash
+ node = it->db->ht[it->ht_index];
+ if( node == NULL )
+ continue;// next hash
+ fake.left = node;
+ node = &fake;
+ }
+
+
+ while( node )
+ {// next node
+ if( node->left )
+ {// continue in the left subtree
+ node = node->left;
+ while( node->right )
+ node = node->right;// get rightmost node
+ }
+ else
+ {// continue to the next parent (recursive)
+ parent = node->parent;
+ while( parent )
+ {
+ if( parent->left != node )
+ break;
+ node = parent;
+ parent = node->parent;
+ }
+ if( parent == NULL )
+ {// next hash
+ node = NULL;
+ break;
+ }
+ node = parent;
+ }
+
+ if( !node->deleted )
+ {// found previous entry
+ it->node = node;
+ if( out_key )
+ memcpy(out_key, &node->key, sizeof(DBKey));
+ return &node->data;
+ }
+ }
+ }
+ it->node = NULL;
+ return NULL;// not found
}
/**
* Returns true if the fetched entry exists.
- * The databases entries might have NULL data, so use this to to test if
+ * The databases entries might have NULL data, so use this to to test if
* the iterator is done.
* @param self Iterator
* @return true if the entry exists
* @protected
* @see DBIterator#exists
*/
-bool dbit_obj_exists(DBIterator *self)
+bool dbit_obj_exists(DBIterator* self)
{
- DBIterator_impl *it = (DBIterator_impl *)self;
+ DBIterator_impl* it = (DBIterator_impl*)self;
- DB_COUNTSTAT(dbit_exists);
- return (it->node && !it->node->deleted);
+ DB_COUNTSTAT(dbit_exists);
+ return (it->node && !it->node->deleted);
}
/**
* Removes the current entry from the database.
- * NOTE: {@link DBIterator#exists} will return false until another entry
+ * NOTE: {@link DBIterator#exists} will return false until another entry
* is fetched
* Puts data of the removed entry in out_data, if out_data is not NULL.
* @param self Iterator
@@ -1327,25 +1331,26 @@ bool dbit_obj_exists(DBIterator *self)
* @see DBMap#remove
* @see DBIterator#remove
*/
-int dbit_obj_remove(DBIterator *self, DBData *out_data)
+int dbit_obj_remove(DBIterator* self, DBData *out_data)
{
- DBIterator_impl *it = (DBIterator_impl *)self;
- DBNode node;
- int retval = 0;
+ DBIterator_impl* it = (DBIterator_impl*)self;
+ DBNode node;
+ int retval = 0;
- DB_COUNTSTAT(dbit_remove);
- node = it->node;
- if (node && !node->deleted) {
- DBMap_impl *db = it->db;
- if (db->cache == node)
- db->cache = NULL;
- if (out_data)
- memcpy(out_data, &node->data, sizeof(DBData));
- retval = 1;
- db->release(node->key, node->data, DB_RELEASE_DATA);
- db_free_add(db, node, &db->ht[it->ht_index]);
- }
- return retval;
+ DB_COUNTSTAT(dbit_remove);
+ node = it->node;
+ if( node && !node->deleted )
+ {
+ DBMap_impl* db = it->db;
+ if( db->cache == node )
+ db->cache = NULL;
+ if( out_data )
+ memcpy(out_data, &node->data, sizeof(DBData));
+ retval = 1;
+ db->release(node->key, node->data, DB_RELEASE_DATA);
+ db_free_add(db, node, &db->ht[it->ht_index]);
+ }
+ return retval;
}
/**
@@ -1353,48 +1358,48 @@ int dbit_obj_remove(DBIterator *self, DBData *out_data)
* @param self Iterator
* @protected
*/
-void dbit_obj_destroy(DBIterator *self)
+void dbit_obj_destroy(DBIterator* self)
{
- DBIterator_impl *it = (DBIterator_impl *)self;
+ DBIterator_impl* it = (DBIterator_impl*)self;
- DB_COUNTSTAT(dbit_destroy);
- // unlock the database
- db_free_unlock(it->db);
- // free iterator
- aFree(self);
+ DB_COUNTSTAT(dbit_destroy);
+ // unlock the database
+ db_free_unlock(it->db);
+ // free iterator
+ aFree(self);
}
/**
* Returns a new iterator for this database.
* The iterator keeps the database locked until it is destroyed.
- * The database will keep functioning normally but will only free internal
+ * The database will keep functioning normally but will only free internal
* memory when unlocked, so destroy the iterator as soon as possible.
* @param self Database
* @return New iterator
* @protected
*/
-static DBIterator *db_obj_iterator(DBMap *self)
+static DBIterator* db_obj_iterator(DBMap* self)
{
- DBMap_impl *db = (DBMap_impl *)self;
- DBIterator_impl *it;
+ DBMap_impl* db = (DBMap_impl*)self;
+ DBIterator_impl* it;
- DB_COUNTSTAT(db_iterator);
- CREATE(it, struct DBIterator_impl, 1);
- /* Interface of the iterator **/
- it->vtable.first = dbit_obj_first;
- it->vtable.last = dbit_obj_last;
- it->vtable.next = dbit_obj_next;
- it->vtable.prev = dbit_obj_prev;
- it->vtable.exists = dbit_obj_exists;
- it->vtable.remove = dbit_obj_remove;
- it->vtable.destroy = dbit_obj_destroy;
- /* Initial state (before the first entry) */
- it->db = db;
- it->ht_index = -1;
- it->node = NULL;
- /* Lock the database */
- db_free_lock(db);
- return &it->vtable;
+ DB_COUNTSTAT(db_iterator);
+ CREATE(it, struct DBIterator_impl, 1);
+ /* Interface of the iterator **/
+ it->vtable.first = dbit_obj_first;
+ it->vtable.last = dbit_obj_last;
+ it->vtable.next = dbit_obj_next;
+ it->vtable.prev = dbit_obj_prev;
+ it->vtable.exists = dbit_obj_exists;
+ it->vtable.remove = dbit_obj_remove;
+ it->vtable.destroy = dbit_obj_destroy;
+ /* Initial state (before the first entry) */
+ it->db = db;
+ it->ht_index = -1;
+ it->node = NULL;
+ /* Lock the database */
+ db_free_lock(db);
+ return &it->vtable;
}
/**
@@ -1405,47 +1410,47 @@ static DBIterator *db_obj_iterator(DBMap *self)
* @protected
* @see DBMap#exists
*/
-static bool db_obj_exists(DBMap *self, DBKey key)
+static bool db_obj_exists(DBMap* self, DBKey key)
{
- DBMap_impl *db = (DBMap_impl *)self;
- DBNode node;
- int c;
- bool found = false;
+ DBMap_impl* db = (DBMap_impl*)self;
+ DBNode node;
+ int c;
+ bool found = false;
- DB_COUNTSTAT(db_exists);
- if (db == NULL) return false; // nullpo candidate
- if (!(db->options&DB_OPT_ALLOW_NULL_KEY) && db_is_key_null(db->type, key)) {
- return false; // nullpo candidate
- }
+ DB_COUNTSTAT(db_exists);
+ if (db == NULL) return false; // nullpo candidate
+ if (!(db->options&DB_OPT_ALLOW_NULL_KEY) && db_is_key_null(db->type, key)) {
+ return false; // nullpo candidate
+ }
- if (db->cache && db->cmp(key, db->cache->key, db->maxlen) == 0) {
+ if (db->cache && db->cmp(key, db->cache->key, db->maxlen) == 0) {
#if defined(DEBUG)
- if (db->cache->deleted) {
- ShowDebug("db_exists: Cache contains a deleted node. Please report this!!!\n");
- return false;
- }
+ if (db->cache->deleted) {
+ ShowDebug("db_exists: Cache contains a deleted node. Please report this!!!\n");
+ return false;
+ }
#endif
- return true; // cache hit
- }
-
- db_free_lock(db);
- node = db->ht[db->hash(key, db->maxlen)%HASH_SIZE];
- while (node) {
- c = db->cmp(key, node->key, db->maxlen);
- if (c == 0) {
- if (!(node->deleted)) {
- db->cache = node;
- found = true;
- }
- break;
- }
- if (c < 0)
- node = node->left;
- else
- node = node->right;
- }
- db_free_unlock(db);
- return found;
+ return true; // cache hit
+ }
+
+ db_free_lock(db);
+ node = db->ht[db->hash(key, db->maxlen)%HASH_SIZE];
+ while (node) {
+ c = db->cmp(key, node->key, db->maxlen);
+ if (c == 0) {
+ if (!(node->deleted)) {
+ db->cache = node;
+ found = true;
+ }
+ break;
+ }
+ if (c < 0)
+ node = node->left;
+ else
+ node = node->right;
+ }
+ db_free_unlock(db);
+ return found;
}
/**
@@ -1456,48 +1461,48 @@ static bool db_obj_exists(DBMap *self, DBKey key)
* @protected
* @see DBMap#get
*/
-static DBData *db_obj_get(DBMap *self, DBKey key)
+static DBData* db_obj_get(DBMap* self, DBKey key)
{
- DBMap_impl *db = (DBMap_impl *)self;
- DBNode node;
- int c;
- DBData *data = NULL;
+ DBMap_impl* db = (DBMap_impl*)self;
+ DBNode node;
+ int c;
+ DBData *data = NULL;
- DB_COUNTSTAT(db_get);
- if (db == NULL) return NULL; // nullpo candidate
- if (!(db->options&DB_OPT_ALLOW_NULL_KEY) && db_is_key_null(db->type, key)) {
- ShowError("db_get: Attempted to retrieve non-allowed NULL key for db allocated at %s:%d\n",db->alloc_file, db->alloc_line);
- return NULL; // nullpo candidate
- }
+ DB_COUNTSTAT(db_get);
+ if (db == NULL) return NULL; // nullpo candidate
+ if (!(db->options&DB_OPT_ALLOW_NULL_KEY) && db_is_key_null(db->type, key)) {
+ ShowError("db_get: Attempted to retrieve non-allowed NULL key for db allocated at %s:%d\n",db->alloc_file, db->alloc_line);
+ return NULL; // nullpo candidate
+ }
- if (db->cache && db->cmp(key, db->cache->key, db->maxlen) == 0) {
+ if (db->cache && db->cmp(key, db->cache->key, db->maxlen) == 0) {
#if defined(DEBUG)
- if (db->cache->deleted) {
- ShowDebug("db_get: Cache contains a deleted node. Please report this!!!\n");
- return NULL;
- }
+ if (db->cache->deleted) {
+ ShowDebug("db_get: Cache contains a deleted node. Please report this!!!\n");
+ return NULL;
+ }
#endif
- return &db->cache->data; // cache hit
- }
-
- db_free_lock(db);
- node = db->ht[db->hash(key, db->maxlen)%HASH_SIZE];
- while (node) {
- c = db->cmp(key, node->key, db->maxlen);
- if (c == 0) {
- if (!(node->deleted)) {
- data = &node->data;
- db->cache = node;
- }
- break;
- }
- if (c < 0)
- node = node->left;
- else
- node = node->right;
- }
- db_free_unlock(db);
- return data;
+ return &db->cache->data; // cache hit
+ }
+
+ db_free_lock(db);
+ node = db->ht[db->hash(key, db->maxlen)%HASH_SIZE];
+ while (node) {
+ c = db->cmp(key, node->key, db->maxlen);
+ if (c == 0) {
+ if (!(node->deleted)) {
+ data = &node->data;
+ db->cache = node;
+ }
+ break;
+ }
+ if (c < 0)
+ node = node->left;
+ else
+ node = node->right;
+ }
+ db_free_unlock(db);
+ return data;
}
/**
@@ -1505,7 +1510,7 @@ static DBData *db_obj_get(DBMap *self, DBKey key)
* It puts a maximum of <code>max</code> entries into <code>buf</code>.
* If <code>buf</code> is NULL, it only counts the matches.
* Returns the number of entries that matched.
- * NOTE: if the value returned is greater than <code>max</code>, only the
+ * NOTE: if the value returned is greater than <code>max</code>, only the
* first <code>max</code> entries found are put into the buffer.
* @param self Interface of the database
* @param buf Buffer to put the data of the matched entries
@@ -1516,58 +1521,58 @@ static DBData *db_obj_get(DBMap *self, DBKey key)
* @protected
* @see DBMap#vgetall
*/
-static unsigned int db_obj_vgetall(DBMap *self, DBData **buf, unsigned int max, DBMatcher match, va_list args)
-{
- DBMap_impl *db = (DBMap_impl *)self;
- unsigned int i;
- DBNode node;
- DBNode parent;
- unsigned int ret = 0;
-
- DB_COUNTSTAT(db_vgetall);
- if (db == NULL) return 0; // nullpo candidate
- if (match == NULL) return 0; // nullpo candidate
-
- db_free_lock(db);
- for (i = 0; i < HASH_SIZE; i++) {
- // Match in the order: current node, left tree, right tree
- node = db->ht[i];
- while (node) {
-
- if (!(node->deleted)) {
- va_list argscopy;
- va_copy(argscopy, args);
- if (match(node->key, node->data, argscopy) == 0) {
- if (buf && ret < max)
- buf[ret] = &node->data;
- ret++;
- }
- va_end(argscopy);
- }
-
- if (node->left) {
- node = node->left;
- continue;
- }
-
- if (node->right) {
- node = node->right;
- continue;
- }
-
- while (node) {
- parent = node->parent;
- if (parent && parent->right && parent->left == node) {
- node = parent->right;
- break;
- }
- node = parent;
- }
-
- }
- }
- db_free_unlock(db);
- return ret;
+static unsigned int db_obj_vgetall(DBMap* self, DBData **buf, unsigned int max, DBMatcher match, va_list args)
+{
+ DBMap_impl* db = (DBMap_impl*)self;
+ unsigned int i;
+ DBNode node;
+ DBNode parent;
+ unsigned int ret = 0;
+
+ DB_COUNTSTAT(db_vgetall);
+ if (db == NULL) return 0; // nullpo candidate
+ if (match == NULL) return 0; // nullpo candidate
+
+ db_free_lock(db);
+ for (i = 0; i < HASH_SIZE; i++) {
+ // Match in the order: current node, left tree, right tree
+ node = db->ht[i];
+ while (node) {
+
+ if (!(node->deleted)) {
+ va_list argscopy;
+ va_copy(argscopy, args);
+ if (match(node->key, node->data, argscopy) == 0) {
+ if (buf && ret < max)
+ buf[ret] = &node->data;
+ ret++;
+ }
+ va_end(argscopy);
+ }
+
+ if (node->left) {
+ node = node->left;
+ continue;
+ }
+
+ if (node->right) {
+ node = node->right;
+ continue;
+ }
+
+ while (node) {
+ parent = node->parent;
+ if (parent && parent->right && parent->left == node) {
+ node = parent->right;
+ break;
+ }
+ node = parent;
+ }
+
+ }
+ }
+ db_free_unlock(db);
+ return ret;
}
/**
@@ -1576,7 +1581,7 @@ static unsigned int db_obj_vgetall(DBMap *self, DBData **buf, unsigned int max,
* It puts a maximum of <code>max</code> entries into <code>buf</code>.
* If <code>buf</code> is NULL, it only counts the matches.
* Returns the number of entries that matched.
- * NOTE: if the value returned is greater than <code>max</code>, only the
+ * NOTE: if the value returned is greater than <code>max</code>, only the
* first <code>max</code> entries found are put into the buffer.
* @param self Interface of the database
* @param buf Buffer to put the data of the matched entries
@@ -1588,23 +1593,23 @@ static unsigned int db_obj_vgetall(DBMap *self, DBData **buf, unsigned int max,
* @see DBMap#vgetall
* @see DBMap#getall
*/
-static unsigned int db_obj_getall(DBMap *self, DBData **buf, unsigned int max, DBMatcher match, ...)
+static unsigned int db_obj_getall(DBMap* self, DBData **buf, unsigned int max, DBMatcher match, ...)
{
- va_list args;
- unsigned int ret;
+ va_list args;
+ unsigned int ret;
- DB_COUNTSTAT(db_getall);
- if (self == NULL) return 0; // nullpo candidate
+ DB_COUNTSTAT(db_getall);
+ if (self == NULL) return 0; // nullpo candidate
- va_start(args, match);
- ret = self->vgetall(self, buf, max, match, args);
- va_end(args);
- return ret;
+ va_start(args, match);
+ ret = self->vgetall(self, buf, max, match, args);
+ va_end(args);
+ return ret;
}
/**
* Get the data of the entry identified by the key.
- * If the entry does not exist, an entry is added with the data returned by
+ * If the entry does not exist, an entry is added with the data returned by
* <code>create</code>.
* @param self Interface of the database
* @param key Key that identifies the entry
@@ -1614,96 +1619,96 @@ static unsigned int db_obj_getall(DBMap *self, DBData **buf, unsigned int max, D
* @protected
* @see DBMap#vensure
*/
-static DBData *db_obj_vensure(DBMap *self, DBKey key, DBCreateData create, va_list args)
-{
- DBMap_impl *db = (DBMap_impl *)self;
- DBNode node;
- DBNode parent = NULL;
- unsigned int hash;
- int c = 0;
- DBData *data = NULL;
-
- DB_COUNTSTAT(db_vensure);
- if (db == NULL) return NULL; // nullpo candidate
- if (create == NULL) {
- ShowError("db_ensure: Create function is NULL for db allocated at %s:%d\n",db->alloc_file, db->alloc_line);
- return NULL; // nullpo candidate
- }
- if (!(db->options&DB_OPT_ALLOW_NULL_KEY) && db_is_key_null(db->type, key)) {
- ShowError("db_ensure: Attempted to use non-allowed NULL key for db allocated at %s:%d\n",db->alloc_file, db->alloc_line);
- return NULL; // nullpo candidate
- }
-
- if (db->cache && db->cmp(key, db->cache->key, db->maxlen) == 0)
- return &db->cache->data; // cache hit
-
- db_free_lock(db);
- hash = db->hash(key, db->maxlen)%HASH_SIZE;
- node = db->ht[hash];
- while (node) {
- c = db->cmp(key, node->key, db->maxlen);
- if (c == 0) {
- break;
- }
- parent = node;
- if (c < 0)
- node = node->left;
- else
- node = node->right;
- }
- // Create node if necessary
- if (node == NULL) {
- va_list argscopy;
- if (db->item_count == UINT32_MAX) {
- ShowError("db_vensure: item_count overflow, aborting item insertion.\n"
- "Database allocated at %s:%d",
- db->alloc_file, db->alloc_line);
- return NULL;
- }
- DB_COUNTSTAT(db_node_alloc);
- node = ers_alloc(db->nodes, struct dbn);
- node->left = NULL;
- node->right = NULL;
- node->deleted = 0;
- db->item_count++;
- if (c == 0) { // hash entry is empty
- node->color = BLACK;
- node->parent = NULL;
- db->ht[hash] = node;
- } else {
- node->color = RED;
- if (c < 0) { // put at the left
- parent->left = node;
- node->parent = parent;
- } else { // put at the right
- parent->right = node;
- node->parent = parent;
- }
- if (parent->color == RED) // two consecutive RED nodes, must rebalance
- db_rebalance(node, &db->ht[hash]);
- }
- // put key and data in the node
- if (db->options&DB_OPT_DUP_KEY) {
- node->key = db_dup_key(db, key);
- if (db->options&DB_OPT_RELEASE_KEY)
- db->release(key, *data, DB_RELEASE_KEY);
- } else {
- node->key = key;
- }
- va_copy(argscopy, args);
- node->data = create(key, argscopy);
- va_end(argscopy);
- }
- data = &node->data;
- db->cache = node;
- db_free_unlock(db);
- return data;
+static DBData* db_obj_vensure(DBMap* self, DBKey key, DBCreateData create, va_list args)
+{
+ DBMap_impl* db = (DBMap_impl*)self;
+ DBNode node;
+ DBNode parent = NULL;
+ unsigned int hash;
+ int c = 0;
+ DBData *data = NULL;
+
+ DB_COUNTSTAT(db_vensure);
+ if (db == NULL) return NULL; // nullpo candidate
+ if (create == NULL) {
+ ShowError("db_ensure: Create function is NULL for db allocated at %s:%d\n",db->alloc_file, db->alloc_line);
+ return NULL; // nullpo candidate
+ }
+ if (!(db->options&DB_OPT_ALLOW_NULL_KEY) && db_is_key_null(db->type, key)) {
+ ShowError("db_ensure: Attempted to use non-allowed NULL key for db allocated at %s:%d\n",db->alloc_file, db->alloc_line);
+ return NULL; // nullpo candidate
+ }
+
+ if (db->cache && db->cmp(key, db->cache->key, db->maxlen) == 0)
+ return &db->cache->data; // cache hit
+
+ db_free_lock(db);
+ hash = db->hash(key, db->maxlen)%HASH_SIZE;
+ node = db->ht[hash];
+ while (node) {
+ c = db->cmp(key, node->key, db->maxlen);
+ if (c == 0) {
+ break;
+ }
+ parent = node;
+ if (c < 0)
+ node = node->left;
+ else
+ node = node->right;
+ }
+ // Create node if necessary
+ if (node == NULL) {
+ va_list argscopy;
+ if (db->item_count == UINT32_MAX) {
+ ShowError("db_vensure: item_count overflow, aborting item insertion.\n"
+ "Database allocated at %s:%d",
+ db->alloc_file, db->alloc_line);
+ return NULL;
+ }
+ DB_COUNTSTAT(db_node_alloc);
+ node = ers_alloc(db->nodes, struct dbn);
+ node->left = NULL;
+ node->right = NULL;
+ node->deleted = 0;
+ db->item_count++;
+ if (c == 0) { // hash entry is empty
+ node->color = BLACK;
+ node->parent = NULL;
+ db->ht[hash] = node;
+ } else {
+ node->color = RED;
+ if (c < 0) { // put at the left
+ parent->left = node;
+ node->parent = parent;
+ } else { // put at the right
+ parent->right = node;
+ node->parent = parent;
+ }
+ if (parent->color == RED) // two consecutive RED nodes, must rebalance
+ db_rebalance(node, &db->ht[hash]);
+ }
+ // put key and data in the node
+ if (db->options&DB_OPT_DUP_KEY) {
+ node->key = db_dup_key(db, key);
+ if (db->options&DB_OPT_RELEASE_KEY)
+ db->release(key, *data, DB_RELEASE_KEY);
+ } else {
+ node->key = key;
+ }
+ va_copy(argscopy, args);
+ node->data = create(key, argscopy);
+ va_end(argscopy);
+ }
+ data = &node->data;
+ db->cache = node;
+ db_free_unlock(db);
+ return data;
}
/**
* Just calls {@link DBMap#vensure}.
* Get the data of the entry identified by the key.
- * If the entry does not exist, an entry is added with the data returned by
+ * If the entry does not exist, an entry is added with the data returned by
* <code>create</code>.
* @param self Interface of the database
* @param key Key that identifies the entry
@@ -1714,18 +1719,18 @@ static DBData *db_obj_vensure(DBMap *self, DBKey key, DBCreateData create, va_li
* @see DBMap#vensure
* @see DBMap#ensure
*/
-static DBData *db_obj_ensure(DBMap *self, DBKey key, DBCreateData create, ...)
+static DBData* db_obj_ensure(DBMap* self, DBKey key, DBCreateData create, ...)
{
- va_list args;
- DBData *ret = NULL;
+ va_list args;
+ DBData *ret = NULL;
- DB_COUNTSTAT(db_ensure);
- if (self == NULL) return NULL; // nullpo candidate
+ DB_COUNTSTAT(db_ensure);
+ if (self == NULL) return NULL; // nullpo candidate
- va_start(args, create);
- ret = self->vensure(self, key, create, args);
- va_end(args);
- return ret;
+ va_start(args, create);
+ ret = self->vensure(self, key, create, args);
+ va_end(args);
+ return ret;
}
/**
@@ -1741,97 +1746,97 @@ static DBData *db_obj_ensure(DBMap *self, DBKey key, DBCreateData create, ...)
* @see #db_malloc_dbn(void)
* @see DBMap#put
*/
-static int db_obj_put(DBMap *self, DBKey key, DBData data, DBData *out_data)
-{
- DBMap_impl *db = (DBMap_impl *)self;
- DBNode node;
- DBNode parent = NULL;
- int c = 0, retval = 0;
- unsigned int hash;
-
- DB_COUNTSTAT(db_put);
- if (db == NULL) return 0; // nullpo candidate
- if (db->global_lock) {
- ShowError("db_put: Database is being destroyed, aborting entry insertion.\n"
- "Database allocated at %s:%d\n",
- db->alloc_file, db->alloc_line);
- return 0; // nullpo candidate
- }
- if (!(db->options&DB_OPT_ALLOW_NULL_KEY) && db_is_key_null(db->type, key)) {
- ShowError("db_put: Attempted to use non-allowed NULL key for db allocated at %s:%d\n",db->alloc_file, db->alloc_line);
- return 0; // nullpo candidate
- }
- if (!(db->options&DB_OPT_ALLOW_NULL_DATA) && (data.type == DB_DATA_PTR && data.u.ptr == NULL)) {
- ShowError("db_put: Attempted to use non-allowed NULL data for db allocated at %s:%d\n",db->alloc_file, db->alloc_line);
- return 0; // nullpo candidate
- }
-
- if (db->item_count == UINT32_MAX) {
- ShowError("db_put: item_count overflow, aborting item insertion.\n"
- "Database allocated at %s:%d",
- db->alloc_file, db->alloc_line);
- return 0;
- }
- // search for an equal node
- db_free_lock(db);
- hash = db->hash(key, db->maxlen)%HASH_SIZE;
- for (node = db->ht[hash]; node;) {
- c = db->cmp(key, node->key, db->maxlen);
- if (c == 0) { // equal entry, replace
- if (node->deleted) {
- db_free_remove(db, node);
- } else {
- db->release(node->key, node->data, DB_RELEASE_BOTH);
- if (out_data)
- memcpy(out_data, &node->data, sizeof(*out_data));
- retval = 1;
- }
- break;
- }
- parent = node;
- if (c < 0) {
- node = node->left;
- } else {
- node = node->right;
- }
- }
- // allocate a new node if necessary
- if (node == NULL) {
- DB_COUNTSTAT(db_node_alloc);
- node = ers_alloc(db->nodes, struct dbn);
- node->left = NULL;
- node->right = NULL;
- node->deleted = 0;
- db->item_count++;
- if (c == 0) { // hash entry is empty
- node->color = BLACK;
- node->parent = NULL;
- db->ht[hash] = node;
- } else {
- node->color = RED;
- if (c < 0) { // put at the left
- parent->left = node;
- node->parent = parent;
- } else { // put at the right
- parent->right = node;
- node->parent = parent;
- }
- if (parent->color == RED) // two consecutive RED nodes, must rebalance
- db_rebalance(node, &db->ht[hash]);
- }
- }
- // put key and data in the node
- if (db->options&DB_OPT_DUP_KEY) {
- node->key = db_dup_key(db, key);
- if (db->options&DB_OPT_RELEASE_KEY)
- db->release(key, data, DB_RELEASE_KEY);
- } else {
- node->key = key;
- }
- node->data = data;
- db->cache = node;
- db_free_unlock(db);
- return retval;
+static int db_obj_put(DBMap* self, DBKey key, DBData data, DBData *out_data)
+{
+ DBMap_impl* db = (DBMap_impl*)self;
+ DBNode node;
+ DBNode parent = NULL;
+ int c = 0, retval = 0;
+ unsigned int hash;
+
+ DB_COUNTSTAT(db_put);
+ if (db == NULL) return 0; // nullpo candidate
+ if (db->global_lock) {
+ ShowError("db_put: Database is being destroyed, aborting entry insertion.\n"
+ "Database allocated at %s:%d\n",
+ db->alloc_file, db->alloc_line);
+ return 0; // nullpo candidate
+ }
+ if (!(db->options&DB_OPT_ALLOW_NULL_KEY) && db_is_key_null(db->type, key)) {
+ ShowError("db_put: Attempted to use non-allowed NULL key for db allocated at %s:%d\n",db->alloc_file, db->alloc_line);
+ return 0; // nullpo candidate
+ }
+ if (!(db->options&DB_OPT_ALLOW_NULL_DATA) && (data.type == DB_DATA_PTR && data.u.ptr == NULL)) {
+ ShowError("db_put: Attempted to use non-allowed NULL data for db allocated at %s:%d\n",db->alloc_file, db->alloc_line);
+ return 0; // nullpo candidate
+ }
+
+ if (db->item_count == UINT32_MAX) {
+ ShowError("db_put: item_count overflow, aborting item insertion.\n"
+ "Database allocated at %s:%d",
+ db->alloc_file, db->alloc_line);
+ return 0;
+ }
+ // search for an equal node
+ db_free_lock(db);
+ hash = db->hash(key, db->maxlen)%HASH_SIZE;
+ for (node = db->ht[hash]; node; ) {
+ c = db->cmp(key, node->key, db->maxlen);
+ if (c == 0) { // equal entry, replace
+ if (node->deleted) {
+ db_free_remove(db, node);
+ } else {
+ db->release(node->key, node->data, DB_RELEASE_BOTH);
+ if (out_data)
+ memcpy(out_data, &node->data, sizeof(*out_data));
+ retval = 1;
+ }
+ break;
+ }
+ parent = node;
+ if (c < 0) {
+ node = node->left;
+ } else {
+ node = node->right;
+ }
+ }
+ // allocate a new node if necessary
+ if (node == NULL) {
+ DB_COUNTSTAT(db_node_alloc);
+ node = ers_alloc(db->nodes, struct dbn);
+ node->left = NULL;
+ node->right = NULL;
+ node->deleted = 0;
+ db->item_count++;
+ if (c == 0) { // hash entry is empty
+ node->color = BLACK;
+ node->parent = NULL;
+ db->ht[hash] = node;
+ } else {
+ node->color = RED;
+ if (c < 0) { // put at the left
+ parent->left = node;
+ node->parent = parent;
+ } else { // put at the right
+ parent->right = node;
+ node->parent = parent;
+ }
+ if (parent->color == RED) // two consecutive RED nodes, must rebalance
+ db_rebalance(node, &db->ht[hash]);
+ }
+ }
+ // put key and data in the node
+ if (db->options&DB_OPT_DUP_KEY) {
+ node->key = db_dup_key(db, key);
+ if (db->options&DB_OPT_RELEASE_KEY)
+ db->release(key, data, DB_RELEASE_KEY);
+ } else {
+ node->key = key;
+ }
+ node->data = data;
+ db->cache = node;
+ db_free_unlock(db);
+ return retval;
}
/**
@@ -1846,49 +1851,49 @@ static int db_obj_put(DBMap *self, DBKey key, DBData data, DBData *out_data)
* @see #db_free_add(DBMap_impl*,DBNode,DBNode *)
* @see DBMap#remove
*/
-static int db_obj_remove(DBMap *self, DBKey key, DBData *out_data)
-{
- DBMap_impl *db = (DBMap_impl *)self;
- DBNode node;
- unsigned int hash;
- int c = 0, retval = 0;
-
- DB_COUNTSTAT(db_remove);
- if (db == NULL) return 0; // nullpo candidate
- if (db->global_lock) {
- ShowError("db_remove: Database is being destroyed. Aborting entry deletion.\n"
- "Database allocated at %s:%d\n",
- db->alloc_file, db->alloc_line);
- return 0; // nullpo candidate
- }
- if (!(db->options&DB_OPT_ALLOW_NULL_KEY) && db_is_key_null(db->type, key)) {
- ShowError("db_remove: Attempted to use non-allowed NULL key for db allocated at %s:%d\n",db->alloc_file, db->alloc_line);
- return 0; // nullpo candidate
- }
-
- db_free_lock(db);
- hash = db->hash(key, db->maxlen)%HASH_SIZE;
- for (node = db->ht[hash]; node;) {
- c = db->cmp(key, node->key, db->maxlen);
- if (c == 0) {
- if (!(node->deleted)) {
- if (db->cache == node)
- db->cache = NULL;
- if (out_data)
- memcpy(out_data, &node->data, sizeof(*out_data));
- retval = 1;
- db->release(node->key, node->data, DB_RELEASE_DATA);
- db_free_add(db, node, &db->ht[hash]);
- }
- break;
- }
- if (c < 0)
- node = node->left;
- else
- node = node->right;
- }
- db_free_unlock(db);
- return retval;
+static int db_obj_remove(DBMap* self, DBKey key, DBData *out_data)
+{
+ DBMap_impl* db = (DBMap_impl*)self;
+ DBNode node;
+ unsigned int hash;
+ int c = 0, retval = 0;
+
+ DB_COUNTSTAT(db_remove);
+ if (db == NULL) return 0; // nullpo candidate
+ if (db->global_lock) {
+ ShowError("db_remove: Database is being destroyed. Aborting entry deletion.\n"
+ "Database allocated at %s:%d\n",
+ db->alloc_file, db->alloc_line);
+ return 0; // nullpo candidate
+ }
+ if (!(db->options&DB_OPT_ALLOW_NULL_KEY) && db_is_key_null(db->type, key)) {
+ ShowError("db_remove: Attempted to use non-allowed NULL key for db allocated at %s:%d\n",db->alloc_file, db->alloc_line);
+ return 0; // nullpo candidate
+ }
+
+ db_free_lock(db);
+ hash = db->hash(key, db->maxlen)%HASH_SIZE;
+ for(node = db->ht[hash]; node; ){
+ c = db->cmp(key, node->key, db->maxlen);
+ if (c == 0) {
+ if (!(node->deleted)) {
+ if (db->cache == node)
+ db->cache = NULL;
+ if (out_data)
+ memcpy(out_data, &node->data, sizeof(*out_data));
+ retval = 1;
+ db->release(node->key, node->data, DB_RELEASE_DATA);
+ db_free_add(db, node, &db->ht[hash]);
+ }
+ break;
+ }
+ if (c < 0)
+ node = node->left;
+ else
+ node = node->right;
+ }
+ db_free_unlock(db);
+ return retval;
}
/**
@@ -1901,52 +1906,52 @@ static int db_obj_remove(DBMap *self, DBKey key, DBData *out_data)
* @protected
* @see DBMap#vforeach
*/
-static int db_obj_vforeach(DBMap *self, DBApply func, va_list args)
-{
- DBMap_impl *db = (DBMap_impl *)self;
- unsigned int i;
- int sum = 0;
- DBNode node;
- DBNode parent;
-
- DB_COUNTSTAT(db_vforeach);
- if (db == NULL) return 0; // nullpo candidate
- if (func == NULL) {
- ShowError("db_foreach: Passed function is NULL for db allocated at %s:%d\n",db->alloc_file, db->alloc_line);
- return 0; // nullpo candidate
- }
-
- db_free_lock(db);
- for (i = 0; i < HASH_SIZE; i++) {
- // Apply func in the order: current node, left node, right node
- node = db->ht[i];
- while (node) {
- if (!(node->deleted)) {
- va_list argscopy;
- va_copy(argscopy, args);
- sum += func(node->key, &node->data, argscopy);
- va_end(argscopy);
- }
- if (node->left) {
- node = node->left;
- continue;
- }
- if (node->right) {
- node = node->right;
- continue;
- }
- while (node) {
- parent = node->parent;
- if (parent && parent->right && parent->left == node) {
- node = parent->right;
- break;
- }
- node = parent;
- }
- }
- }
- db_free_unlock(db);
- return sum;
+static int db_obj_vforeach(DBMap* self, DBApply func, va_list args)
+{
+ DBMap_impl* db = (DBMap_impl*)self;
+ unsigned int i;
+ int sum = 0;
+ DBNode node;
+ DBNode parent;
+
+ DB_COUNTSTAT(db_vforeach);
+ if (db == NULL) return 0; // nullpo candidate
+ if (func == NULL) {
+ ShowError("db_foreach: Passed function is NULL for db allocated at %s:%d\n",db->alloc_file, db->alloc_line);
+ return 0; // nullpo candidate
+ }
+
+ db_free_lock(db);
+ for (i = 0; i < HASH_SIZE; i++) {
+ // Apply func in the order: current node, left node, right node
+ node = db->ht[i];
+ while (node) {
+ if (!(node->deleted)) {
+ va_list argscopy;
+ va_copy(argscopy, args);
+ sum += func(node->key, &node->data, argscopy);
+ va_end(argscopy);
+ }
+ if (node->left) {
+ node = node->left;
+ continue;
+ }
+ if (node->right) {
+ node = node->right;
+ continue;
+ }
+ while (node) {
+ parent = node->parent;
+ if (parent && parent->right && parent->left == node) {
+ node = parent->right;
+ break;
+ }
+ node = parent;
+ }
+ }
+ }
+ db_free_unlock(db);
+ return sum;
}
/**
@@ -1961,18 +1966,18 @@ static int db_obj_vforeach(DBMap *self, DBApply func, va_list args)
* @see DBMap#vforeach
* @see DBMap#foreach
*/
-static int db_obj_foreach(DBMap *self, DBApply func, ...)
+static int db_obj_foreach(DBMap* self, DBApply func, ...)
{
- va_list args;
- int ret;
+ va_list args;
+ int ret;
- DB_COUNTSTAT(db_foreach);
- if (self == NULL) return 0; // nullpo candidate
+ DB_COUNTSTAT(db_foreach);
+ if (self == NULL) return 0; // nullpo candidate
- va_start(args, func);
- ret = self->vforeach(self, func, args);
- va_end(args);
- return ret;
+ va_start(args, func);
+ ret = self->vforeach(self, func, args);
+ va_end(args);
+ return ret;
}
/**
@@ -1987,61 +1992,62 @@ static int db_obj_foreach(DBMap *self, DBApply func, ...)
* @protected
* @see DBMap#vclear
*/
-static int db_obj_vclear(DBMap *self, DBApply func, va_list args)
-{
- DBMap_impl *db = (DBMap_impl *)self;
- int sum = 0;
- unsigned int i;
- DBNode node;
- DBNode parent;
-
- DB_COUNTSTAT(db_vclear);
- if (db == NULL) return 0; // nullpo candidate
-
- db_free_lock(db);
- db->cache = NULL;
- for (i = 0; i < HASH_SIZE; i++) {
- // Apply the func and delete in the order: left tree, right tree, current node
- node = db->ht[i];
- db->ht[i] = NULL;
- while (node) {
- parent = node->parent;
- if (node->left) {
- node = node->left;
- continue;
- }
- if (node->right) {
- node = node->right;
- continue;
- }
- if (node->deleted) {
- db_dup_key_free(db, node->key);
- } else {
- if (func) {
- va_list argscopy;
- va_copy(argscopy, args);
- sum += func(node->key, &node->data, argscopy);
- va_end(argscopy);
- }
- db->release(node->key, node->data, DB_RELEASE_BOTH);
- node->deleted = 1;
- }
- DB_COUNTSTAT(db_node_free);
- if (parent) {
- if (parent->left == node)
- parent->left = NULL;
- else
- parent->right = NULL;
- }
- ers_free(db->nodes, node);
- node = parent;
- }
- db->ht[i] = NULL;
- }
- db->free_count = 0;
- db->item_count = 0;
- db_free_unlock(db);
- return sum;
+static int db_obj_vclear(DBMap* self, DBApply func, va_list args)
+{
+ DBMap_impl* db = (DBMap_impl*)self;
+ int sum = 0;
+ unsigned int i;
+ DBNode node;
+ DBNode parent;
+
+ DB_COUNTSTAT(db_vclear);
+ if (db == NULL) return 0; // nullpo candidate
+
+ db_free_lock(db);
+ db->cache = NULL;
+ for (i = 0; i < HASH_SIZE; i++) {
+ // Apply the func and delete in the order: left tree, right tree, current node
+ node = db->ht[i];
+ db->ht[i] = NULL;
+ while (node) {
+ parent = node->parent;
+ if (node->left) {
+ node = node->left;
+ continue;
+ }
+ if (node->right) {
+ node = node->right;
+ continue;
+ }
+ if (node->deleted) {
+ db_dup_key_free(db, node->key);
+ } else {
+ if (func)
+ {
+ va_list argscopy;
+ va_copy(argscopy, args);
+ sum += func(node->key, &node->data, argscopy);
+ va_end(argscopy);
+ }
+ db->release(node->key, node->data, DB_RELEASE_BOTH);
+ node->deleted = 1;
+ }
+ DB_COUNTSTAT(db_node_free);
+ if (parent) {
+ if (parent->left == node)
+ parent->left = NULL;
+ else
+ parent->right = NULL;
+ }
+ ers_free(db->nodes, node);
+ node = parent;
+ }
+ db->ht[i] = NULL;
+ }
+ db->free_count = 0;
+ db->item_count = 0;
+ db_free_unlock(db);
+ return sum;
}
/**
@@ -2050,7 +2056,7 @@ static int db_obj_vclear(DBMap *self, DBApply func, va_list args)
* Before deleting an entry, func is applied to it.
* Releases the key and the data.
* Returns the sum of values returned by func, if it exists.
- * NOTE: This locks the database globally. Any attempt to insert or remove
+ * NOTE: This locks the database globally. Any attempt to insert or remove
* a database entry will give an error and be aborted (except for clearing).
* @param self Interface of the database
* @param func Function to be applied to every entry before deleting
@@ -2060,25 +2066,25 @@ static int db_obj_vclear(DBMap *self, DBApply func, va_list args)
* @see DBMap#vclear
* @see DBMap#clear
*/
-static int db_obj_clear(DBMap *self, DBApply func, ...)
+static int db_obj_clear(DBMap* self, DBApply func, ...)
{
- va_list args;
- int ret;
+ va_list args;
+ int ret;
- DB_COUNTSTAT(db_clear);
- if (self == NULL) return 0; // nullpo candidate
+ DB_COUNTSTAT(db_clear);
+ if (self == NULL) return 0; // nullpo candidate
- va_start(args, func);
- ret = self->vclear(self, func, args);
- va_end(args);
- return ret;
+ va_start(args, func);
+ ret = self->vclear(self, func, args);
+ va_end(args);
+ return ret;
}
/**
* Finalize the database, feeing all the memory it uses.
* Before deleting an entry, func is applied to it.
* Returns the sum of values returned by func, if it exists.
- * NOTE: This locks the database globally. Any attempt to insert or remove
+ * NOTE: This locks the database globally. Any attempt to insert or remove
* a database entry will give an error and be aborted (except for clearing).
* @param self Interface of the database
* @param func Function to be applied to every entry before deleting
@@ -2087,50 +2093,42 @@ static int db_obj_clear(DBMap *self, DBApply func, ...)
* @protected
* @see DBMap#vdestroy
*/
-static int db_obj_vdestroy(DBMap *self, DBApply func, va_list args)
+static int db_obj_vdestroy(DBMap* self, DBApply func, va_list args)
{
- DBMap_impl *db = (DBMap_impl *)self;
- int sum;
+ DBMap_impl* db = (DBMap_impl*)self;
+ int sum;
- DB_COUNTSTAT(db_vdestroy);
- if (db == NULL) return 0; // nullpo candidate
- if (db->global_lock) {
- ShowError("db_vdestroy: Database is already locked for destruction. Aborting second database destruction.\n"
- "Database allocated at %s:%d\n",
- db->alloc_file, db->alloc_line);
- return 0;
- }
- if (db->free_lock)
- ShowWarning("db_vdestroy: Database is still in use, %u lock(s) left. Continuing database destruction.\n"
- "Database allocated at %s:%d\n",
- db->free_lock, db->alloc_file, db->alloc_line);
+ DB_COUNTSTAT(db_vdestroy);
+ if (db == NULL) return 0; // nullpo candidate
+ if (db->global_lock) {
+ ShowError("db_vdestroy: Database is already locked for destruction. Aborting second database destruction.\n"
+ "Database allocated at %s:%d\n",
+ db->alloc_file, db->alloc_line);
+ return 0;
+ }
+ if (db->free_lock)
+ ShowWarning("db_vdestroy: Database is still in use, %u lock(s) left. Continuing database destruction.\n"
+ "Database allocated at %s:%d\n",
+ db->free_lock, db->alloc_file, db->alloc_line);
#ifdef DB_ENABLE_STATS
- switch (db->type) {
- case DB_INT:
- DB_COUNTSTAT(db_int_destroy);
- break;
- case DB_UINT:
- DB_COUNTSTAT(db_uint_destroy);
- break;
- case DB_STRING:
- DB_COUNTSTAT(db_string_destroy);
- break;
- case DB_ISTRING:
- DB_COUNTSTAT(db_istring_destroy);
- break;
- }
+ switch (db->type) {
+ case DB_INT: DB_COUNTSTAT(db_int_destroy); break;
+ case DB_UINT: DB_COUNTSTAT(db_uint_destroy); break;
+ case DB_STRING: DB_COUNTSTAT(db_string_destroy); break;
+ case DB_ISTRING: DB_COUNTSTAT(db_istring_destroy); break;
+ }
#endif /* DB_ENABLE_STATS */
- db_free_lock(db);
- db->global_lock = 1;
- sum = self->vclear(self, func, args);
- aFree(db->free_list);
- db->free_list = NULL;
- db->free_max = 0;
- ers_destroy(db->nodes);
- db_free_unlock(db);
- aFree(db);
- return sum;
+ db_free_lock(db);
+ db->global_lock = 1;
+ sum = self->vclear(self, func, args);
+ aFree(db->free_list);
+ db->free_list = NULL;
+ db->free_max = 0;
+ ers_destroy(db->nodes);
+ db_free_unlock(db);
+ aFree(db);
+ return sum;
}
/**
@@ -2139,7 +2137,7 @@ static int db_obj_vdestroy(DBMap *self, DBApply func, va_list args)
* Before deleting an entry, func is applied to it.
* Releases the key and the data.
* Returns the sum of values returned by func, if it exists.
- * NOTE: This locks the database globally. Any attempt to insert or remove
+ * NOTE: This locks the database globally. Any attempt to insert or remove
* a database entry will give an error and be aborted.
* @param self Database
* @param func Function to be applied to every entry before deleting
@@ -2149,18 +2147,18 @@ static int db_obj_vdestroy(DBMap *self, DBApply func, va_list args)
* @see DBMap#vdestroy
* @see DBMap#destroy
*/
-static int db_obj_destroy(DBMap *self, DBApply func, ...)
+static int db_obj_destroy(DBMap* self, DBApply func, ...)
{
- va_list args;
- int ret;
+ va_list args;
+ int ret;
- DB_COUNTSTAT(db_destroy);
- if (self == NULL) return 0; // nullpo candidate
+ DB_COUNTSTAT(db_destroy);
+ if (self == NULL) return 0; // nullpo candidate
- va_start(args, func);
- ret = self->vdestroy(self, func, args);
- va_end(args);
- return ret;
+ va_start(args, func);
+ ret = self->vdestroy(self, func, args);
+ va_end(args);
+ return ret;
}
/**
@@ -2171,19 +2169,19 @@ static int db_obj_destroy(DBMap *self, DBApply func, ...)
* @see DBMap_impl#item_count
* @see DBMap#size
*/
-static unsigned int db_obj_size(DBMap *self)
+static unsigned int db_obj_size(DBMap* self)
{
- DBMap_impl *db = (DBMap_impl *)self;
- unsigned int item_count;
+ DBMap_impl* db = (DBMap_impl*)self;
+ unsigned int item_count;
- DB_COUNTSTAT(db_size);
- if (db == NULL) return 0; // nullpo candidate
+ DB_COUNTSTAT(db_size);
+ if (db == NULL) return 0; // nullpo candidate
- db_free_lock(db);
- item_count = db->item_count;
- db_free_unlock(db);
+ db_free_lock(db);
+ item_count = db->item_count;
+ db_free_unlock(db);
- return item_count;
+ return item_count;
}
/**
@@ -2194,19 +2192,19 @@ static unsigned int db_obj_size(DBMap *self)
* @see DBMap_impl#type
* @see DBMap#type
*/
-static DBType db_obj_type(DBMap *self)
+static DBType db_obj_type(DBMap* self)
{
- DBMap_impl *db = (DBMap_impl *)self;
- DBType type;
+ DBMap_impl* db = (DBMap_impl*)self;
+ DBType type;
- DB_COUNTSTAT(db_type);
- if (db == NULL) return (DBType)-1; // nullpo candidate - TODO what should this return?
+ DB_COUNTSTAT(db_type);
+ if (db == NULL) return (DBType)-1; // nullpo candidate - TODO what should this return?
- db_free_lock(db);
- type = db->type;
- db_free_unlock(db);
+ db_free_lock(db);
+ type = db->type;
+ db_free_unlock(db);
- return type;
+ return type;
}
/**
@@ -2217,19 +2215,19 @@ static DBType db_obj_type(DBMap *self)
* @see DBMap_impl#options
* @see DBMap#options
*/
-static DBOptions db_obj_options(DBMap *self)
+static DBOptions db_obj_options(DBMap* self)
{
- DBMap_impl *db = (DBMap_impl *)self;
- DBOptions options;
+ DBMap_impl* db = (DBMap_impl*)self;
+ DBOptions options;
- DB_COUNTSTAT(db_options);
- if (db == NULL) return DB_OPT_BASE; // nullpo candidate - TODO what should this return?
+ DB_COUNTSTAT(db_options);
+ if (db == NULL) return DB_OPT_BASE; // nullpo candidate - TODO what should this return?
- db_free_lock(db);
- options = db->options;
- db_free_unlock(db);
+ db_free_lock(db);
+ options = db->options;
+ db_free_unlock(db);
- return options;
+ return options;
}
/*****************************************************************************\
@@ -2266,18 +2264,18 @@ static DBOptions db_obj_options(DBMap *self)
*/
DBOptions db_fix_options(DBType type, DBOptions options)
{
- DB_COUNTSTAT(db_fix_options);
- switch (type) {
- case DB_INT:
- case DB_UINT: // Numeric database, do nothing with the keys
- return (DBOptions)(options&~(DB_OPT_DUP_KEY|DB_OPT_RELEASE_KEY));
+ DB_COUNTSTAT(db_fix_options);
+ switch (type) {
+ case DB_INT:
+ case DB_UINT: // Numeric database, do nothing with the keys
+ return (DBOptions)(options&~(DB_OPT_DUP_KEY|DB_OPT_RELEASE_KEY));
- default:
- ShowError("db_fix_options: Unknown database type %u with options %x\n", type, options);
- case DB_STRING:
- case DB_ISTRING: // String databases, no fix required
- return options;
- }
+ default:
+ ShowError("db_fix_options: Unknown database type %u with options %x\n", type, options);
+ case DB_STRING:
+ case DB_ISTRING: // String databases, no fix required
+ return options;
+ }
}
/**
@@ -2292,20 +2290,16 @@ DBOptions db_fix_options(DBType type, DBOptions options)
*/
DBComparator db_default_cmp(DBType type)
{
- DB_COUNTSTAT(db_default_cmp);
- switch (type) {
- case DB_INT:
- return &db_int_cmp;
- case DB_UINT:
- return &db_uint_cmp;
- case DB_STRING:
- return &db_string_cmp;
- case DB_ISTRING:
- return &db_istring_cmp;
- default:
- ShowError("db_default_cmp: Unknown database type %u\n", type);
- return NULL;
- }
+ DB_COUNTSTAT(db_default_cmp);
+ switch (type) {
+ case DB_INT: return &db_int_cmp;
+ case DB_UINT: return &db_uint_cmp;
+ case DB_STRING: return &db_string_cmp;
+ case DB_ISTRING: return &db_istring_cmp;
+ default:
+ ShowError("db_default_cmp: Unknown database type %u\n", type);
+ return NULL;
+ }
}
/**
@@ -2320,24 +2314,20 @@ DBComparator db_default_cmp(DBType type)
*/
DBHasher db_default_hash(DBType type)
{
- DB_COUNTSTAT(db_default_hash);
- switch (type) {
- case DB_INT:
- return &db_int_hash;
- case DB_UINT:
- return &db_uint_hash;
- case DB_STRING:
- return &db_string_hash;
- case DB_ISTRING:
- return &db_istring_hash;
- default:
- ShowError("db_default_hash: Unknown database type %u\n", type);
- return NULL;
- }
+ DB_COUNTSTAT(db_default_hash);
+ switch (type) {
+ case DB_INT: return &db_int_hash;
+ case DB_UINT: return &db_uint_hash;
+ case DB_STRING: return &db_string_hash;
+ case DB_ISTRING: return &db_istring_hash;
+ default:
+ ShowError("db_default_hash: Unknown database type %u\n", type);
+ return NULL;
+ }
}
/**
- * Returns the default releaser for the specified type of database with the
+ * Returns the default releaser for the specified type of database with the
* specified options.
* NOTE: the options are fixed with {@link #db_fix_options(DBType,DBOptions)}
* before choosing the releaser.
@@ -2353,16 +2343,16 @@ DBHasher db_default_hash(DBType type)
*/
DBReleaser db_default_release(DBType type, DBOptions options)
{
- DB_COUNTSTAT(db_default_release);
- options = db_fix_options(type, options);
- if (options&DB_OPT_RELEASE_DATA) { // Release data, what about the key?
- if (options&(DB_OPT_DUP_KEY|DB_OPT_RELEASE_KEY))
- return &db_release_both; // Release both key and data
- return &db_release_data; // Only release data
- }
- if (options&(DB_OPT_DUP_KEY|DB_OPT_RELEASE_KEY))
- return &db_release_key; // Only release key
- return &db_release_nothing; // Release nothing
+ DB_COUNTSTAT(db_default_release);
+ options = db_fix_options(type, options);
+ if (options&DB_OPT_RELEASE_DATA) { // Release data, what about the key?
+ if (options&(DB_OPT_DUP_KEY|DB_OPT_RELEASE_KEY))
+ return &db_release_both; // Release both key and data
+ return &db_release_data; // Only release data
+ }
+ if (options&(DB_OPT_DUP_KEY|DB_OPT_RELEASE_KEY))
+ return &db_release_key; // Only release key
+ return &db_release_nothing; // Release nothing
}
/**
@@ -2378,20 +2368,16 @@ DBReleaser db_default_release(DBType type, DBOptions options)
*/
DBReleaser db_custom_release(DBRelease which)
{
- DB_COUNTSTAT(db_custom_release);
- switch (which) {
- case DB_RELEASE_NOTHING:
- return &db_release_nothing;
- case DB_RELEASE_KEY:
- return &db_release_key;
- case DB_RELEASE_DATA:
- return &db_release_data;
- case DB_RELEASE_BOTH:
- return &db_release_both;
- default:
- ShowError("db_custom_release: Unknown release options %u\n", which);
- return NULL;
- }
+ DB_COUNTSTAT(db_custom_release);
+ switch (which) {
+ case DB_RELEASE_NOTHING: return &db_release_nothing;
+ case DB_RELEASE_KEY: return &db_release_key;
+ case DB_RELEASE_DATA: return &db_release_data;
+ case DB_RELEASE_BOTH: return &db_release_both;
+ default:
+ ShowError("db_custom_release: Unknown release options %u\n", which);
+ return NULL;
+ }
}
/**
@@ -2402,83 +2388,75 @@ DBReleaser db_custom_release(DBRelease which)
* @param line Line of the file where the database is being allocated
* @param type Type of database
* @param options Options of the database
- * @param maxlen Maximum length of the string to be used as key in string
+ * @param maxlen Maximum length of the string to be used as key in string
* databases. If 0, the maximum number of maxlen is used (64K).
* @return The interface of the database
* @public
* @see #DBMap_impl
* @see #db_fix_options(DBType,DBOptions)
*/
-DBMap *db_alloc(const char *file, int line, DBType type, DBOptions options, unsigned short maxlen)
+DBMap* db_alloc(const char *file, int line, DBType type, DBOptions options, unsigned short maxlen)
{
- DBMap_impl *db;
- unsigned int i;
+ DBMap_impl* db;
+ unsigned int i;
#ifdef DB_ENABLE_STATS
- DB_COUNTSTAT(db_alloc);
- switch (type) {
- case DB_INT:
- DB_COUNTSTAT(db_int_alloc);
- break;
- case DB_UINT:
- DB_COUNTSTAT(db_uint_alloc);
- break;
- case DB_STRING:
- DB_COUNTSTAT(db_string_alloc);
- break;
- case DB_ISTRING:
- DB_COUNTSTAT(db_istring_alloc);
- break;
- }
+ DB_COUNTSTAT(db_alloc);
+ switch (type) {
+ case DB_INT: DB_COUNTSTAT(db_int_alloc); break;
+ case DB_UINT: DB_COUNTSTAT(db_uint_alloc); break;
+ case DB_STRING: DB_COUNTSTAT(db_string_alloc); break;
+ case DB_ISTRING: DB_COUNTSTAT(db_istring_alloc); break;
+ }
#endif /* DB_ENABLE_STATS */
- CREATE(db, struct DBMap_impl, 1);
-
- options = db_fix_options(type, options);
- /* Interface of the database */
- db->vtable.iterator = db_obj_iterator;
- db->vtable.exists = db_obj_exists;
- db->vtable.get = db_obj_get;
- db->vtable.getall = db_obj_getall;
- db->vtable.vgetall = db_obj_vgetall;
- db->vtable.ensure = db_obj_ensure;
- db->vtable.vensure = db_obj_vensure;
- db->vtable.put = db_obj_put;
- db->vtable.remove = db_obj_remove;
- db->vtable.foreach = db_obj_foreach;
- db->vtable.vforeach = db_obj_vforeach;
- db->vtable.clear = db_obj_clear;
- db->vtable.vclear = db_obj_vclear;
- db->vtable.destroy = db_obj_destroy;
- db->vtable.vdestroy = db_obj_vdestroy;
- db->vtable.size = db_obj_size;
- db->vtable.type = db_obj_type;
- db->vtable.options = db_obj_options;
- /* File and line of allocation */
- db->alloc_file = file;
- db->alloc_line = line;
- /* Lock system */
- db->free_list = NULL;
- db->free_count = 0;
- db->free_max = 0;
- db->free_lock = 0;
- /* Other */
- db->nodes = ers_new(sizeof(struct dbn),"db.c::db_alloc",ERS_OPT_NONE);
- db->cmp = db_default_cmp(type);
- db->hash = db_default_hash(type);
- db->release = db_default_release(type, options);
- for (i = 0; i < HASH_SIZE; i++)
- db->ht[i] = NULL;
- db->cache = NULL;
- db->type = type;
- db->options = options;
- db->item_count = 0;
- db->maxlen = maxlen;
- db->global_lock = 0;
-
- if (db->maxlen == 0 && (type == DB_STRING || type == DB_ISTRING))
- db->maxlen = UINT16_MAX;
-
- return &db->vtable;
+ CREATE(db, struct DBMap_impl, 1);
+
+ options = db_fix_options(type, options);
+ /* Interface of the database */
+ db->vtable.iterator = db_obj_iterator;
+ db->vtable.exists = db_obj_exists;
+ db->vtable.get = db_obj_get;
+ db->vtable.getall = db_obj_getall;
+ db->vtable.vgetall = db_obj_vgetall;
+ db->vtable.ensure = db_obj_ensure;
+ db->vtable.vensure = db_obj_vensure;
+ db->vtable.put = db_obj_put;
+ db->vtable.remove = db_obj_remove;
+ db->vtable.foreach = db_obj_foreach;
+ db->vtable.vforeach = db_obj_vforeach;
+ db->vtable.clear = db_obj_clear;
+ db->vtable.vclear = db_obj_vclear;
+ db->vtable.destroy = db_obj_destroy;
+ db->vtable.vdestroy = db_obj_vdestroy;
+ db->vtable.size = db_obj_size;
+ db->vtable.type = db_obj_type;
+ db->vtable.options = db_obj_options;
+ /* File and line of allocation */
+ db->alloc_file = file;
+ db->alloc_line = line;
+ /* Lock system */
+ db->free_list = NULL;
+ db->free_count = 0;
+ db->free_max = 0;
+ db->free_lock = 0;
+ /* Other */
+ db->nodes = ers_new(sizeof(struct dbn),"db.c::db_alloc",ERS_OPT_NONE);
+ db->cmp = db_default_cmp(type);
+ db->hash = db_default_hash(type);
+ db->release = db_default_release(type, options);
+ for (i = 0; i < HASH_SIZE; i++)
+ db->ht[i] = NULL;
+ db->cache = NULL;
+ db->type = type;
+ db->options = options;
+ db->item_count = 0;
+ db->maxlen = maxlen;
+ db->global_lock = 0;
+
+ if( db->maxlen == 0 && (type == DB_STRING || type == DB_ISTRING) )
+ db->maxlen = UINT16_MAX;
+
+ return &db->vtable;
}
/**
@@ -2489,11 +2467,11 @@ DBMap *db_alloc(const char *file, int line, DBType type, DBOptions options, unsi
*/
DBKey db_i2key(int key)
{
- DBKey ret;
+ DBKey ret;
- DB_COUNTSTAT(db_i2key);
- ret.i = key;
- return ret;
+ DB_COUNTSTAT(db_i2key);
+ ret.i = key;
+ return ret;
}
/**
@@ -2504,11 +2482,11 @@ DBKey db_i2key(int key)
*/
DBKey db_ui2key(unsigned int key)
{
- DBKey ret;
+ DBKey ret;
- DB_COUNTSTAT(db_ui2key);
- ret.ui = key;
- return ret;
+ DB_COUNTSTAT(db_ui2key);
+ ret.ui = key;
+ return ret;
}
/**
@@ -2519,11 +2497,11 @@ DBKey db_ui2key(unsigned int key)
*/
DBKey db_str2key(const char *key)
{
- DBKey ret;
+ DBKey ret;
- DB_COUNTSTAT(db_str2key);
- ret.str = key;
- return ret;
+ DB_COUNTSTAT(db_str2key);
+ ret.str = key;
+ return ret;
}
/**
@@ -2534,12 +2512,12 @@ DBKey db_str2key(const char *key)
*/
DBData db_i2data(int data)
{
- DBData ret;
+ DBData ret;
- DB_COUNTSTAT(db_i2data);
- ret.type = DB_DATA_INT;
- ret.u.i = data;
- return ret;
+ DB_COUNTSTAT(db_i2data);
+ ret.type = DB_DATA_INT;
+ ret.u.i = data;
+ return ret;
}
/**
@@ -2550,12 +2528,12 @@ DBData db_i2data(int data)
*/
DBData db_ui2data(unsigned int data)
{
- DBData ret;
+ DBData ret;
- DB_COUNTSTAT(db_ui2data);
- ret.type = DB_DATA_UINT;
- ret.u.ui = data;
- return ret;
+ DB_COUNTSTAT(db_ui2data);
+ ret.type = DB_DATA_UINT;
+ ret.u.ui = data;
+ return ret;
}
/**
@@ -2566,12 +2544,12 @@ DBData db_ui2data(unsigned int data)
*/
DBData db_ptr2data(void *data)
{
- DBData ret;
+ DBData ret;
- DB_COUNTSTAT(db_ptr2data);
- ret.type = DB_DATA_PTR;
- ret.u.ptr = data;
- return ret;
+ DB_COUNTSTAT(db_ptr2data);
+ ret.type = DB_DATA_PTR;
+ ret.u.ptr = data;
+ return ret;
}
/**
@@ -2583,10 +2561,10 @@ DBData db_ptr2data(void *data)
*/
int db_data2i(DBData *data)
{
- DB_COUNTSTAT(db_data2i);
- if (data && DB_DATA_INT == data->type)
- return data->u.i;
- return 0;
+ DB_COUNTSTAT(db_data2i);
+ if (data && DB_DATA_INT == data->type)
+ return data->u.i;
+ return 0;
}
/**
@@ -2598,10 +2576,10 @@ int db_data2i(DBData *data)
*/
unsigned int db_data2ui(DBData *data)
{
- DB_COUNTSTAT(db_data2ui);
- if (data && DB_DATA_UINT == data->type)
- return data->u.ui;
- return 0;
+ DB_COUNTSTAT(db_data2ui);
+ if (data && DB_DATA_UINT == data->type)
+ return data->u.ui;
+ return 0;
}
/**
@@ -2611,12 +2589,12 @@ unsigned int db_data2ui(DBData *data)
* @return Void* value of the data.
* @public
*/
-void *db_data2ptr(DBData *data)
+void* db_data2ptr(DBData *data)
{
- DB_COUNTSTAT(db_data2ptr);
- if (data && DB_DATA_PTR == data->type)
- return data->u.ptr;
- return NULL;
+ DB_COUNTSTAT(db_data2ptr);
+ if (data && DB_DATA_PTR == data->type)
+ return data->u.ptr;
+ return NULL;
}
/**
@@ -2626,7 +2604,7 @@ void *db_data2ptr(DBData *data)
*/
void db_init(void)
{
- DB_COUNTSTAT(db_init);
+ DB_COUNTSTAT(db_init);
}
/**
@@ -2637,208 +2615,208 @@ void db_init(void)
void db_final(void)
{
#ifdef DB_ENABLE_STATS
- DB_COUNTSTAT(db_final);
- ShowInfo(CL_WHITE"Database nodes"CL_RESET":\n"
- "allocated %u, freed %u\n",
- stats.db_node_alloc, stats.db_node_free);
- ShowInfo(CL_WHITE"Database types"CL_RESET":\n"
- "DB_INT : allocated %10u, destroyed %10u\n"
- "DB_UINT : allocated %10u, destroyed %10u\n"
- "DB_STRING : allocated %10u, destroyed %10u\n"
- "DB_ISTRING : allocated %10u, destroyed %10u\n",
- stats.db_int_alloc, stats.db_int_destroy,
- stats.db_uint_alloc, stats.db_uint_destroy,
- stats.db_string_alloc, stats.db_string_destroy,
- stats.db_istring_alloc, stats.db_istring_destroy);
- ShowInfo(CL_WHITE"Database function counters"CL_RESET":\n"
- "db_rotate_left %10u, db_rotate_right %10u,\n"
- "db_rebalance %10u, db_rebalance_erase %10u,\n"
- "db_is_key_null %10u,\n"
- "db_dup_key %10u, db_dup_key_free %10u,\n"
- "db_free_add %10u, db_free_remove %10u,\n"
- "db_free_lock %10u, db_free_unlock %10u,\n"
- "db_int_cmp %10u, db_uint_cmp %10u,\n"
- "db_string_cmp %10u, db_istring_cmp %10u,\n"
- "db_int_hash %10u, db_uint_hash %10u,\n"
- "db_string_hash %10u, db_istring_hash %10u,\n"
- "db_release_nothing %10u, db_release_key %10u,\n"
- "db_release_data %10u, db_release_both %10u,\n"
- "dbit_first %10u, dbit_last %10u,\n"
- "dbit_next %10u, dbit_prev %10u,\n"
- "dbit_exists %10u, dbit_remove %10u,\n"
- "dbit_destroy %10u, db_iterator %10u,\n"
- "db_exits %10u, db_get %10u,\n"
- "db_getall %10u, db_vgetall %10u,\n"
- "db_ensure %10u, db_vensure %10u,\n"
- "db_put %10u, db_remove %10u,\n"
- "db_foreach %10u, db_vforeach %10u,\n"
- "db_clear %10u, db_vclear %10u,\n"
- "db_destroy %10u, db_vdestroy %10u,\n"
- "db_size %10u, db_type %10u,\n"
- "db_options %10u, db_fix_options %10u,\n"
- "db_default_cmp %10u, db_default_hash %10u,\n"
- "db_default_release %10u, db_custom_release %10u,\n"
- "db_alloc %10u, db_i2key %10u,\n"
- "db_ui2key %10u, db_str2key %10u,\n"
- "db_i2data %10u, db_ui2data %10u,\n"
- "db_ptr2data %10u, db_data2i %10u,\n"
- "db_data2ui %10u, db_data2ptr %10u,\n"
- "db_init %10u, db_final %10u\n",
- stats.db_rotate_left, stats.db_rotate_right,
- stats.db_rebalance, stats.db_rebalance_erase,
- stats.db_is_key_null,
- stats.db_dup_key, stats.db_dup_key_free,
- stats.db_free_add, stats.db_free_remove,
- stats.db_free_lock, stats.db_free_unlock,
- stats.db_int_cmp, stats.db_uint_cmp,
- stats.db_string_cmp, stats.db_istring_cmp,
- stats.db_int_hash, stats.db_uint_hash,
- stats.db_string_hash, stats.db_istring_hash,
- stats.db_release_nothing, stats.db_release_key,
- stats.db_release_data, stats.db_release_both,
- stats.dbit_first, stats.dbit_last,
- stats.dbit_next, stats.dbit_prev,
- stats.dbit_exists, stats.dbit_remove,
- stats.dbit_destroy, stats.db_iterator,
- stats.db_exists, stats.db_get,
- stats.db_getall, stats.db_vgetall,
- stats.db_ensure, stats.db_vensure,
- stats.db_put, stats.db_remove,
- stats.db_foreach, stats.db_vforeach,
- stats.db_clear, stats.db_vclear,
- stats.db_destroy, stats.db_vdestroy,
- stats.db_size, stats.db_type,
- stats.db_options, stats.db_fix_options,
- stats.db_default_cmp, stats.db_default_hash,
- stats.db_default_release, stats.db_custom_release,
- stats.db_alloc, stats.db_i2key,
- stats.db_ui2key, stats.db_str2key,
- stats.db_i2data, stats.db_ui2data,
- stats.db_ptr2data, stats.db_data2i,
- stats.db_data2ui, stats.db_data2ptr,
- stats.db_init, stats.db_final);
+ DB_COUNTSTAT(db_final);
+ ShowInfo(CL_WHITE"Database nodes"CL_RESET":\n"
+ "allocated %u, freed %u\n",
+ stats.db_node_alloc, stats.db_node_free);
+ ShowInfo(CL_WHITE"Database types"CL_RESET":\n"
+ "DB_INT : allocated %10u, destroyed %10u\n"
+ "DB_UINT : allocated %10u, destroyed %10u\n"
+ "DB_STRING : allocated %10u, destroyed %10u\n"
+ "DB_ISTRING : allocated %10u, destroyed %10u\n",
+ stats.db_int_alloc, stats.db_int_destroy,
+ stats.db_uint_alloc, stats.db_uint_destroy,
+ stats.db_string_alloc, stats.db_string_destroy,
+ stats.db_istring_alloc, stats.db_istring_destroy);
+ ShowInfo(CL_WHITE"Database function counters"CL_RESET":\n"
+ "db_rotate_left %10u, db_rotate_right %10u,\n"
+ "db_rebalance %10u, db_rebalance_erase %10u,\n"
+ "db_is_key_null %10u,\n"
+ "db_dup_key %10u, db_dup_key_free %10u,\n"
+ "db_free_add %10u, db_free_remove %10u,\n"
+ "db_free_lock %10u, db_free_unlock %10u,\n"
+ "db_int_cmp %10u, db_uint_cmp %10u,\n"
+ "db_string_cmp %10u, db_istring_cmp %10u,\n"
+ "db_int_hash %10u, db_uint_hash %10u,\n"
+ "db_string_hash %10u, db_istring_hash %10u,\n"
+ "db_release_nothing %10u, db_release_key %10u,\n"
+ "db_release_data %10u, db_release_both %10u,\n"
+ "dbit_first %10u, dbit_last %10u,\n"
+ "dbit_next %10u, dbit_prev %10u,\n"
+ "dbit_exists %10u, dbit_remove %10u,\n"
+ "dbit_destroy %10u, db_iterator %10u,\n"
+ "db_exits %10u, db_get %10u,\n"
+ "db_getall %10u, db_vgetall %10u,\n"
+ "db_ensure %10u, db_vensure %10u,\n"
+ "db_put %10u, db_remove %10u,\n"
+ "db_foreach %10u, db_vforeach %10u,\n"
+ "db_clear %10u, db_vclear %10u,\n"
+ "db_destroy %10u, db_vdestroy %10u,\n"
+ "db_size %10u, db_type %10u,\n"
+ "db_options %10u, db_fix_options %10u,\n"
+ "db_default_cmp %10u, db_default_hash %10u,\n"
+ "db_default_release %10u, db_custom_release %10u,\n"
+ "db_alloc %10u, db_i2key %10u,\n"
+ "db_ui2key %10u, db_str2key %10u,\n"
+ "db_i2data %10u, db_ui2data %10u,\n"
+ "db_ptr2data %10u, db_data2i %10u,\n"
+ "db_data2ui %10u, db_data2ptr %10u,\n"
+ "db_init %10u, db_final %10u\n",
+ stats.db_rotate_left, stats.db_rotate_right,
+ stats.db_rebalance, stats.db_rebalance_erase,
+ stats.db_is_key_null,
+ stats.db_dup_key, stats.db_dup_key_free,
+ stats.db_free_add, stats.db_free_remove,
+ stats.db_free_lock, stats.db_free_unlock,
+ stats.db_int_cmp, stats.db_uint_cmp,
+ stats.db_string_cmp, stats.db_istring_cmp,
+ stats.db_int_hash, stats.db_uint_hash,
+ stats.db_string_hash, stats.db_istring_hash,
+ stats.db_release_nothing, stats.db_release_key,
+ stats.db_release_data, stats.db_release_both,
+ stats.dbit_first, stats.dbit_last,
+ stats.dbit_next, stats.dbit_prev,
+ stats.dbit_exists, stats.dbit_remove,
+ stats.dbit_destroy, stats.db_iterator,
+ stats.db_exists, stats.db_get,
+ stats.db_getall, stats.db_vgetall,
+ stats.db_ensure, stats.db_vensure,
+ stats.db_put, stats.db_remove,
+ stats.db_foreach, stats.db_vforeach,
+ stats.db_clear, stats.db_vclear,
+ stats.db_destroy, stats.db_vdestroy,
+ stats.db_size, stats.db_type,
+ stats.db_options, stats.db_fix_options,
+ stats.db_default_cmp, stats.db_default_hash,
+ stats.db_default_release, stats.db_custom_release,
+ stats.db_alloc, stats.db_i2key,
+ stats.db_ui2key, stats.db_str2key,
+ stats.db_i2data, stats.db_ui2data,
+ stats.db_ptr2data, stats.db_data2i,
+ stats.db_data2ui, stats.db_data2ptr,
+ stats.db_init, stats.db_final);
#endif /* DB_ENABLE_STATS */
}
// Link DB System - jAthena
-void linkdb_insert(struct linkdb_node **head, void *key, void *data)
-{
- struct linkdb_node *node;
- if (head == NULL) return ;
- node = (struct linkdb_node *)aMalloc(sizeof(struct linkdb_node));
- if (*head == NULL) {
- // first node
- *head = node;
- node->prev = NULL;
- node->next = NULL;
- } else {
- // link nodes
- node->next = *head;
- node->prev = (*head)->prev;
- (*head)->prev = node;
- (*head) = node;
- }
- node->key = key;
- node->data = data;
-}
-
-void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...)
-{
- struct linkdb_node *node;
- if (head == NULL) return;
- node = *head;
- while (node) {
- va_list args;
- va_start(args, func);
- func(node->key, node->data, args);
- va_end(args);
- node = node->next;
- }
-}
-
-void *linkdb_search(struct linkdb_node **head, void *key)
-{
- int n = 0;
- struct linkdb_node *node;
- if (head == NULL) return NULL;
- node = *head;
- while (node) {
- if (node->key == key) {
- if (node->prev && n > 5) {
- //Moving the head in order to improve processing efficiency
- if (node->prev) node->prev->next = node->next;
- if (node->next) node->next->prev = node->prev;
- node->next = *head;
- node->prev = (*head)->prev;
- (*head)->prev = node;
- (*head) = node;
- }
- return node->data;
- }
- node = node->next;
- n++;
- }
- return NULL;
-}
-
-void *linkdb_erase(struct linkdb_node **head, void *key)
-{
- struct linkdb_node *node;
- if (head == NULL) return NULL;
- node = *head;
- while (node) {
- if (node->key == key) {
- void *data = node->data;
- if (node->prev == NULL)
- *head = node->next;
- else
- node->prev->next = node->next;
- if (node->next)
- node->next->prev = node->prev;
- aFree(node);
- return data;
- }
- node = node->next;
- }
- return NULL;
-}
-
-void linkdb_replace(struct linkdb_node **head, void *key, void *data)
-{
- int n = 0;
- struct linkdb_node *node;
- if (head == NULL) return ;
- node = *head;
- while (node) {
- if (node->key == key) {
- if (node->prev && n > 5) {
- //Moving the head in order to improve processing efficiency
- if (node->prev) node->prev->next = node->next;
- if (node->next) node->next->prev = node->prev;
- node->next = *head;
- node->prev = (*head)->prev;
- (*head)->prev = node;
- (*head) = node;
- }
- node->data = data;
- return ;
- }
- node = node->next;
- n++;
- }
- //Insert because it can not find
- linkdb_insert(head, key, data);
-}
-
-void linkdb_final(struct linkdb_node **head)
-{
- struct linkdb_node *node, *node2;
- if (head == NULL) return ;
- node = *head;
- while (node) {
- node2 = node->next;
- aFree(node);
- node = node2;
- }
- *head = NULL;
+void linkdb_insert( struct linkdb_node** head, void *key, void* data)
+{
+ struct linkdb_node *node;
+ if( head == NULL ) return ;
+ node = (struct linkdb_node*)aMalloc( sizeof(struct linkdb_node) );
+ if( *head == NULL ) {
+ // first node
+ *head = node;
+ node->prev = NULL;
+ node->next = NULL;
+ } else {
+ // link nodes
+ node->next = *head;
+ node->prev = (*head)->prev;
+ (*head)->prev = node;
+ (*head) = node;
+ }
+ node->key = key;
+ node->data = data;
+}
+
+void linkdb_foreach( struct linkdb_node** head, LinkDBFunc func, ... )
+{
+ struct linkdb_node *node;
+ if( head == NULL ) return;
+ node = *head;
+ while ( node ) {
+ va_list args;
+ va_start(args, func);
+ func( node->key, node->data, args );
+ va_end(args);
+ node = node->next;
+ }
+}
+
+void* linkdb_search( struct linkdb_node** head, void *key)
+{
+ int n = 0;
+ struct linkdb_node *node;
+ if( head == NULL ) return NULL;
+ node = *head;
+ while( node ) {
+ if( node->key == key ) {
+ if( node->prev && n > 5 ) {
+ //Moving the head in order to improve processing efficiency
+ if(node->prev) node->prev->next = node->next;
+ if(node->next) node->next->prev = node->prev;
+ node->next = *head;
+ node->prev = (*head)->prev;
+ (*head)->prev = node;
+ (*head) = node;
+ }
+ return node->data;
+ }
+ node = node->next;
+ n++;
+ }
+ return NULL;
+}
+
+void* linkdb_erase( struct linkdb_node** head, void *key)
+{
+ struct linkdb_node *node;
+ if( head == NULL ) return NULL;
+ node = *head;
+ while( node ) {
+ if( node->key == key ) {
+ void *data = node->data;
+ if( node->prev == NULL )
+ *head = node->next;
+ else
+ node->prev->next = node->next;
+ if( node->next )
+ node->next->prev = node->prev;
+ aFree( node );
+ return data;
+ }
+ node = node->next;
+ }
+ return NULL;
+}
+
+void linkdb_replace( struct linkdb_node** head, void *key, void *data )
+{
+ int n = 0;
+ struct linkdb_node *node;
+ if( head == NULL ) return ;
+ node = *head;
+ while( node ) {
+ if( node->key == key ) {
+ if( node->prev && n > 5 ) {
+ //Moving the head in order to improve processing efficiency
+ if(node->prev) node->prev->next = node->next;
+ if(node->next) node->next->prev = node->prev;
+ node->next = *head;
+ node->prev = (*head)->prev;
+ (*head)->prev = node;
+ (*head) = node;
+ }
+ node->data = data;
+ return ;
+ }
+ node = node->next;
+ n++;
+ }
+ //Insert because it can not find
+ linkdb_insert( head, key, data );
+}
+
+void linkdb_final( struct linkdb_node** head )
+{
+ struct linkdb_node *node, *node2;
+ if( head == NULL ) return ;
+ node = *head;
+ while( node ) {
+ node2 = node->next;
+ aFree( node );
+ node = node2;
+ }
+ *head = NULL;
}
diff --git a/src/common/db.h b/src/common/db.h
index eff3b775e..4fe6a93d6 100644
--- a/src/common/db.h
+++ b/src/common/db.h
@@ -69,15 +69,15 @@
* @see #db_custom_release(DBRelease)
*/
typedef enum DBRelease {
- DB_RELEASE_NOTHING = 0,
- DB_RELEASE_KEY = 1,
- DB_RELEASE_DATA = 2,
- DB_RELEASE_BOTH = 3
+ DB_RELEASE_NOTHING = 0,
+ DB_RELEASE_KEY = 1,
+ DB_RELEASE_DATA = 2,
+ DB_RELEASE_BOTH = 3
} DBRelease;
/**
* Supported types of database.
- * See {@link #db_fix_options(DBType,DBOptions)} for restrictions of the
+ * See {@link #db_fix_options(DBType,DBOptions)} for restrictions of the
* types of databases.
* @param DB_INT Uses int's for keys
* @param DB_UINT Uses unsigned int's for keys
@@ -93,22 +93,22 @@ typedef enum DBRelease {
* @see #db_alloc(const char *,int,DBType,DBOptions,unsigned short)
*/
typedef enum DBType {
- DB_INT,
- DB_UINT,
- DB_STRING,
- DB_ISTRING
+ DB_INT,
+ DB_UINT,
+ DB_STRING,
+ DB_ISTRING
} DBType;
/**
* Bitfield of options that define the behaviour of the database.
- * See {@link #db_fix_options(DBType,DBOptions)} for restrictions of the
+ * See {@link #db_fix_options(DBType,DBOptions)} for restrictions of the
* types of databases.
* @param DB_OPT_BASE Base options: does not duplicate keys, releases nothing
* and does not allow NULL keys or NULL data.
- * @param DB_OPT_DUP_KEY Duplicates the keys internally. If DB_OPT_RELEASE_KEY
+ * @param DB_OPT_DUP_KEY Duplicates the keys internally. If DB_OPT_RELEASE_KEY
* is defined, the real key is freed as soon as the entry is added.
* @param DB_OPT_RELEASE_KEY Releases the key.
- * @param DB_OPT_RELEASE_DATA Releases the data whenever an entry is removed
+ * @param DB_OPT_RELEASE_DATA Releases the data whenever an entry is removed
* from the database.
* WARNING: for funtions that return the data (like DBMap::remove),
* a dangling pointer will be returned.
@@ -121,13 +121,13 @@ typedef enum DBType {
* @see #db_alloc(const char *,int,DBType,DBOptions,unsigned short)
*/
typedef enum DBOptions {
- DB_OPT_BASE = 0,
- DB_OPT_DUP_KEY = 1,
- DB_OPT_RELEASE_KEY = 2,
- DB_OPT_RELEASE_DATA = 4,
- DB_OPT_RELEASE_BOTH = 6,
- DB_OPT_ALLOW_NULL_KEY = 8,
- DB_OPT_ALLOW_NULL_DATA = 16,
+ DB_OPT_BASE = 0,
+ DB_OPT_DUP_KEY = 1,
+ DB_OPT_RELEASE_KEY = 2,
+ DB_OPT_RELEASE_DATA = 4,
+ DB_OPT_RELEASE_BOTH = 6,
+ DB_OPT_ALLOW_NULL_KEY = 8,
+ DB_OPT_ALLOW_NULL_DATA = 16,
} DBOptions;
/**
@@ -142,9 +142,9 @@ typedef enum DBOptions {
* @see DBMap#remove
*/
typedef union DBKey {
- int i;
- unsigned int ui;
- const char *str;
+ int i;
+ unsigned int ui;
+ const char *str;
} DBKey;
/**
@@ -156,9 +156,9 @@ typedef union DBKey {
* @see #DBData
*/
typedef enum DBDataType {
- DB_DATA_INT,
- DB_DATA_UINT,
- DB_DATA_PTR
+ DB_DATA_INT,
+ DB_DATA_UINT,
+ DB_DATA_PTR
} DBDataType;
/**
@@ -171,16 +171,16 @@ typedef enum DBDataType {
* @public
*/
typedef struct DBData {
- DBDataType type;
- union {
- int i;
- unsigned int ui;
- void *ptr;
- } u;
+ DBDataType type;
+ union {
+ int i;
+ unsigned int ui;
+ void *ptr;
+ } u;
} DBData;
/**
- * Format of functions that create the data for the key when the entry doesn't
+ * Format of functions that create the data for the key when the entry doesn't
* exist in the database yet.
* @param key Key of the database entry
* @param args Extra arguments of the function
@@ -189,12 +189,12 @@ typedef struct DBData {
* @see DBMap#vensure
* @see DBMap#ensure
*/
-typedef DBData(*DBCreateData)(DBKey key, va_list args);
+typedef DBData (*DBCreateData)(DBKey key, va_list args);
/**
- * Format of functions to be applied to an unspecified quantity of entries of
+ * Format of functions to be applied to an unspecified quantity of entries of
* a database.
- * Any function that applies this function to the database will return the sum
+ * Any function that applies this function to the database will return the sum
* of values returned by this function.
* @param key Key of the database entry
* @param data Data of the database entry
@@ -272,86 +272,87 @@ typedef struct DBMap DBMap;
* Database iterator.
* Supports forward iteration, backward iteration and removing entries from the database.
* The iterator is initially positioned before the first entry of the database.
- * While the iterator exists the database is locked internally, so invoke
+ * While the iterator exists the database is locked internally, so invoke
* {@link DBIterator#destroy} as soon as possible.
* @public
* @see #DBMap
*/
-struct DBIterator {
-
- /**
- * Fetches the first entry in the database.
- * Returns the data of the entry.
- * Puts the key in out_key, if out_key is not NULL.
- * @param self Iterator
- * @param out_key Key of the entry
- * @return Data of the entry
- * @protected
- */
- DBData *(*first)(DBIterator *self, DBKey *out_key);
-
- /**
- * Fetches the last entry in the database.
- * Returns the data of the entry.
- * Puts the key in out_key, if out_key is not NULL.
- * @param self Iterator
- * @param out_key Key of the entry
- * @return Data of the entry
- * @protected
- */
- DBData *(*last)(DBIterator *self, DBKey *out_key);
-
- /**
- * Fetches the next entry in the database.
- * Returns the data of the entry.
- * Puts the key in out_key, if out_key is not NULL.
- * @param self Iterator
- * @param out_key Key of the entry
- * @return Data of the entry
- * @protected
- */
- DBData *(*next)(DBIterator *self, DBKey *out_key);
-
- /**
- * Fetches the previous entry in the database.
- * Returns the data of the entry.
- * Puts the key in out_key, if out_key is not NULL.
- * @param self Iterator
- * @param out_key Key of the entry
- * @return Data of the entry
- * @protected
- */
- DBData *(*prev)(DBIterator *self, DBKey *out_key);
-
- /**
- * Returns true if the fetched entry exists.
- * The databases entries might have NULL data, so use this to to test if
- * the iterator is done.
- * @param self Iterator
- * @return true is the entry exists
- * @protected
- */
- bool (*exists)(DBIterator *self);
-
- /**
- * Removes the current entry from the database.
- * NOTE: {@link DBIterator#exists} will return false until another entry
- * is fetched
- * Puts data of the removed entry in out_data, if out_data is not NULL.
- * @param self Iterator
- * @param out_data Data of the removed entry.
- * @return 1 if entry was removed, 0 otherwise
- * @protected
- * @see DBMap#remove
- */
- int (*remove)(DBIterator *self, DBData *out_data);
-
- /**
- * Destroys this iterator and unlocks the database.
- * @param self Iterator
- * @protected
- */
- void (*destroy)(DBIterator *self);
+struct DBIterator
+{
+
+ /**
+ * Fetches the first entry in the database.
+ * Returns the data of the entry.
+ * Puts the key in out_key, if out_key is not NULL.
+ * @param self Iterator
+ * @param out_key Key of the entry
+ * @return Data of the entry
+ * @protected
+ */
+ DBData* (*first)(DBIterator* self, DBKey* out_key);
+
+ /**
+ * Fetches the last entry in the database.
+ * Returns the data of the entry.
+ * Puts the key in out_key, if out_key is not NULL.
+ * @param self Iterator
+ * @param out_key Key of the entry
+ * @return Data of the entry
+ * @protected
+ */
+ DBData* (*last)(DBIterator* self, DBKey* out_key);
+
+ /**
+ * Fetches the next entry in the database.
+ * Returns the data of the entry.
+ * Puts the key in out_key, if out_key is not NULL.
+ * @param self Iterator
+ * @param out_key Key of the entry
+ * @return Data of the entry
+ * @protected
+ */
+ DBData* (*next)(DBIterator* self, DBKey* out_key);
+
+ /**
+ * Fetches the previous entry in the database.
+ * Returns the data of the entry.
+ * Puts the key in out_key, if out_key is not NULL.
+ * @param self Iterator
+ * @param out_key Key of the entry
+ * @return Data of the entry
+ * @protected
+ */
+ DBData* (*prev)(DBIterator* self, DBKey* out_key);
+
+ /**
+ * Returns true if the fetched entry exists.
+ * The databases entries might have NULL data, so use this to to test if
+ * the iterator is done.
+ * @param self Iterator
+ * @return true is the entry exists
+ * @protected
+ */
+ bool (*exists)(DBIterator* self);
+
+ /**
+ * Removes the current entry from the database.
+ * NOTE: {@link DBIterator#exists} will return false until another entry
+ * is fetched
+ * Puts data of the removed entry in out_data, if out_data is not NULL.
+ * @param self Iterator
+ * @param out_data Data of the removed entry.
+ * @return 1 if entry was removed, 0 otherwise
+ * @protected
+ * @see DBMap#remove
+ */
+ int (*remove)(DBIterator* self, DBData *out_data);
+
+ /**
+ * Destroys this iterator and unlocks the database.
+ * @param self Iterator
+ * @protected
+ */
+ void (*destroy)(DBIterator* self);
};
@@ -363,235 +364,235 @@ struct DBIterator {
*/
struct DBMap {
- /**
- * Returns a new iterator for this database.
- * The iterator keeps the database locked until it is destroyed.
- * The database will keep functioning normally but will only free internal
- * memory when unlocked, so destroy the iterator as soon as possible.
- * @param self Database
- * @return New iterator
- * @protected
- */
- DBIterator *(*iterator)(DBMap *self);
-
- /**
- * Returns true if the entry exists.
- * @param self Database
- * @param key Key that identifies the entry
- * @return true is the entry exists
- * @protected
- */
- bool (*exists)(DBMap *self, DBKey key);
-
- /**
- * Get the data of the entry identified by the key.
- * @param self Database
- * @param key Key that identifies the entry
- * @return Data of the entry or NULL if not found
- * @protected
- */
- DBData *(*get)(DBMap *self, DBKey key);
-
- /**
- * Just calls {@link DBMap#vgetall}.
- * Get the data of the entries matched by <code>match</code>.
- * It puts a maximum of <code>max</code> entries into <code>buf</code>.
- * If <code>buf</code> is NULL, it only counts the matches.
- * Returns the number of entries that matched.
- * NOTE: if the value returned is greater than <code>max</code>, only the
- * first <code>max</code> entries found are put into the buffer.
- * @param self Database
- * @param buf Buffer to put the data of the matched entries
- * @param max Maximum number of data entries to be put into buf
- * @param match Function that matches the database entries
- * @param ... Extra arguments for match
- * @return The number of entries that matched
- * @protected
- * @see DBMap#vgetall(DBMap*,void **,unsigned int,DBMatcher,va_list)
- */
- unsigned int (*getall)(DBMap *self, DBData **buf, unsigned int max, DBMatcher match, ...);
-
- /**
- * Get the data of the entries matched by <code>match</code>.
- * It puts a maximum of <code>max</code> entries into <code>buf</code>.
- * If <code>buf</code> is NULL, it only counts the matches.
- * Returns the number of entries that matched.
- * NOTE: if the value returned is greater than <code>max</code>, only the
- * first <code>max</code> entries found are put into the buffer.
- * @param self Database
- * @param buf Buffer to put the data of the matched entries
- * @param max Maximum number of data entries to be put into buf
- * @param match Function that matches the database entries
- * @param ... Extra arguments for match
- * @return The number of entries that matched
- * @protected
- * @see DBMap#getall(DBMap*,void **,unsigned int,DBMatcher,...)
- */
- unsigned int (*vgetall)(DBMap *self, DBData **buf, unsigned int max, DBMatcher match, va_list args);
-
- /**
- * Just calls {@link DBMap#vensure}.
- * Get the data of the entry identified by the key.
- * If the entry does not exist, an entry is added with the data returned by
- * <code>create</code>.
- * @param self Database
- * @param key Key that identifies the entry
- * @param create Function used to create the data if the entry doesn't exist
- * @param ... Extra arguments for create
- * @return Data of the entry
- * @protected
- * @see DBMap#vensure(DBMap*,DBKey,DBCreateData,va_list)
- */
- DBData *(*ensure)(DBMap *self, DBKey key, DBCreateData create, ...);
-
- /**
- * Get the data of the entry identified by the key.
- * If the entry does not exist, an entry is added with the data returned by
- * <code>create</code>.
- * @param self Database
- * @param key Key that identifies the entry
- * @param create Function used to create the data if the entry doesn't exist
- * @param args Extra arguments for create
- * @return Data of the entry
- * @protected
- * @see DBMap#ensure(DBMap*,DBKey,DBCreateData,...)
- */
- DBData *(*vensure)(DBMap *self, DBKey key, DBCreateData create, va_list args);
-
- /**
- * Put the data identified by the key in the database.
- * Puts the previous data in out_data, if out_data is not NULL.
- * NOTE: Uses the new key, the old one is released.
- * @param self Database
- * @param key Key that identifies the data
- * @param data Data to be put in the database
- * @param out_data Previous data if the entry exists
- * @return 1 if if the entry already exists, 0 otherwise
- * @protected
- */
- int (*put)(DBMap *self, DBKey key, DBData data, DBData *out_data);
-
- /**
- * Remove an entry from the database.
- * Puts the previous data in out_data, if out_data is not NULL.
- * NOTE: The key (of the database) is released.
- * @param self Database
- * @param key Key that identifies the entry
- * @param out_data Previous data if the entry exists
- * @return 1 if if the entry already exists, 0 otherwise
- * @protected
- */
- int (*remove)(DBMap *self, DBKey key, DBData *out_data);
-
- /**
- * Just calls {@link DBMap#vforeach}.
- * Apply <code>func</code> to every entry in the database.
- * Returns the sum of values returned by func.
- * @param self Database
- * @param func Function to be applied
- * @param ... Extra arguments for func
- * @return Sum of the values returned by func
- * @protected
- * @see DBMap#vforeach(DBMap*,DBApply,va_list)
- */
- int (*foreach)(DBMap *self, DBApply func, ...);
-
- /**
- * Apply <code>func</code> to every entry in the database.
- * Returns the sum of values returned by func.
- * @param self Database
- * @param func Function to be applied
- * @param args Extra arguments for func
- * @return Sum of the values returned by func
- * @protected
- * @see DBMap#foreach(DBMap*,DBApply,...)
- */
- int (*vforeach)(DBMap *self, DBApply func, va_list args);
-
- /**
- * Just calls {@link DBMap#vclear}.
- * Removes all entries from the database.
- * Before deleting an entry, func is applied to it.
- * Releases the key and the data.
- * Returns the sum of values returned by func, if it exists.
- * @param self Database
- * @param func Function to be applied to every entry before deleting
- * @param ... Extra arguments for func
- * @return Sum of values returned by func
- * @protected
- * @see DBMap#vclear(DBMap*,DBApply,va_list)
- */
- int (*clear)(DBMap *self, DBApply func, ...);
-
- /**
- * Removes all entries from the database.
- * Before deleting an entry, func is applied to it.
- * Releases the key and the data.
- * Returns the sum of values returned by func, if it exists.
- * @param self Database
- * @param func Function to be applied to every entry before deleting
- * @param args Extra arguments for func
- * @return Sum of values returned by func
- * @protected
- * @see DBMap#clear(DBMap*,DBApply,...)
- */
- int (*vclear)(DBMap *self, DBApply func, va_list args);
-
- /**
- * Just calls {@link DBMap#vdestroy}.
- * Finalize the database, feeing all the memory it uses.
- * Before deleting an entry, func is applied to it.
- * Releases the key and the data.
- * Returns the sum of values returned by func, if it exists.
- * NOTE: This locks the database globally. Any attempt to insert or remove
- * a database entry will give an error and be aborted (except for clearing).
- * @param self Database
- * @param func Function to be applied to every entry before deleting
- * @param ... Extra arguments for func
- * @return Sum of values returned by func
- * @protected
- * @see DBMap#vdestroy(DBMap*,DBApply,va_list)
- */
- int (*destroy)(DBMap *self, DBApply func, ...);
-
- /**
- * Finalize the database, feeing all the memory it uses.
- * Before deleting an entry, func is applied to it.
- * Returns the sum of values returned by func, if it exists.
- * NOTE: This locks the database globally. Any attempt to insert or remove
- * a database entry will give an error and be aborted (except for clearing).
- * @param self Database
- * @param func Function to be applied to every entry before deleting
- * @param args Extra arguments for func
- * @return Sum of values returned by func
- * @protected
- * @see DBMap#destroy(DBMap*,DBApply,...)
- */
- int (*vdestroy)(DBMap *self, DBApply func, va_list args);
-
- /**
- * Return the size of the database (number of items in the database).
- * @param self Database
- * @return Size of the database
- * @protected
- */
- unsigned int (*size)(DBMap *self);
-
- /**
- * Return the type of the database.
- * @param self Database
- * @return Type of the database
- * @protected
- */
- DBType(*type)(DBMap *self);
-
- /**
- * Return the options of the database.
- * @param self Database
- * @return Options of the database
- * @protected
- */
- DBOptions(*options)(DBMap *self);
+ /**
+ * Returns a new iterator for this database.
+ * The iterator keeps the database locked until it is destroyed.
+ * The database will keep functioning normally but will only free internal
+ * memory when unlocked, so destroy the iterator as soon as possible.
+ * @param self Database
+ * @return New iterator
+ * @protected
+ */
+ DBIterator* (*iterator)(DBMap* self);
+
+ /**
+ * Returns true if the entry exists.
+ * @param self Database
+ * @param key Key that identifies the entry
+ * @return true is the entry exists
+ * @protected
+ */
+ bool (*exists)(DBMap* self, DBKey key);
+
+ /**
+ * Get the data of the entry identified by the key.
+ * @param self Database
+ * @param key Key that identifies the entry
+ * @return Data of the entry or NULL if not found
+ * @protected
+ */
+ DBData* (*get)(DBMap* self, DBKey key);
+
+ /**
+ * Just calls {@link DBMap#vgetall}.
+ * Get the data of the entries matched by <code>match</code>.
+ * It puts a maximum of <code>max</code> entries into <code>buf</code>.
+ * If <code>buf</code> is NULL, it only counts the matches.
+ * Returns the number of entries that matched.
+ * NOTE: if the value returned is greater than <code>max</code>, only the
+ * first <code>max</code> entries found are put into the buffer.
+ * @param self Database
+ * @param buf Buffer to put the data of the matched entries
+ * @param max Maximum number of data entries to be put into buf
+ * @param match Function that matches the database entries
+ * @param ... Extra arguments for match
+ * @return The number of entries that matched
+ * @protected
+ * @see DBMap#vgetall(DBMap*,void **,unsigned int,DBMatcher,va_list)
+ */
+ unsigned int (*getall)(DBMap* self, DBData** buf, unsigned int max, DBMatcher match, ...);
+
+ /**
+ * Get the data of the entries matched by <code>match</code>.
+ * It puts a maximum of <code>max</code> entries into <code>buf</code>.
+ * If <code>buf</code> is NULL, it only counts the matches.
+ * Returns the number of entries that matched.
+ * NOTE: if the value returned is greater than <code>max</code>, only the
+ * first <code>max</code> entries found are put into the buffer.
+ * @param self Database
+ * @param buf Buffer to put the data of the matched entries
+ * @param max Maximum number of data entries to be put into buf
+ * @param match Function that matches the database entries
+ * @param ... Extra arguments for match
+ * @return The number of entries that matched
+ * @protected
+ * @see DBMap#getall(DBMap*,void **,unsigned int,DBMatcher,...)
+ */
+ unsigned int (*vgetall)(DBMap* self, DBData** buf, unsigned int max, DBMatcher match, va_list args);
+
+ /**
+ * Just calls {@link DBMap#vensure}.
+ * Get the data of the entry identified by the key.
+ * If the entry does not exist, an entry is added with the data returned by
+ * <code>create</code>.
+ * @param self Database
+ * @param key Key that identifies the entry
+ * @param create Function used to create the data if the entry doesn't exist
+ * @param ... Extra arguments for create
+ * @return Data of the entry
+ * @protected
+ * @see DBMap#vensure(DBMap*,DBKey,DBCreateData,va_list)
+ */
+ DBData* (*ensure)(DBMap* self, DBKey key, DBCreateData create, ...);
+
+ /**
+ * Get the data of the entry identified by the key.
+ * If the entry does not exist, an entry is added with the data returned by
+ * <code>create</code>.
+ * @param self Database
+ * @param key Key that identifies the entry
+ * @param create Function used to create the data if the entry doesn't exist
+ * @param args Extra arguments for create
+ * @return Data of the entry
+ * @protected
+ * @see DBMap#ensure(DBMap*,DBKey,DBCreateData,...)
+ */
+ DBData* (*vensure)(DBMap* self, DBKey key, DBCreateData create, va_list args);
+
+ /**
+ * Put the data identified by the key in the database.
+ * Puts the previous data in out_data, if out_data is not NULL.
+ * NOTE: Uses the new key, the old one is released.
+ * @param self Database
+ * @param key Key that identifies the data
+ * @param data Data to be put in the database
+ * @param out_data Previous data if the entry exists
+ * @return 1 if if the entry already exists, 0 otherwise
+ * @protected
+ */
+ int (*put)(DBMap* self, DBKey key, DBData data, DBData *out_data);
+
+ /**
+ * Remove an entry from the database.
+ * Puts the previous data in out_data, if out_data is not NULL.
+ * NOTE: The key (of the database) is released.
+ * @param self Database
+ * @param key Key that identifies the entry
+ * @param out_data Previous data if the entry exists
+ * @return 1 if if the entry already exists, 0 otherwise
+ * @protected
+ */
+ int (*remove)(DBMap* self, DBKey key, DBData *out_data);
+
+ /**
+ * Just calls {@link DBMap#vforeach}.
+ * Apply <code>func</code> to every entry in the database.
+ * Returns the sum of values returned by func.
+ * @param self Database
+ * @param func Function to be applied
+ * @param ... Extra arguments for func
+ * @return Sum of the values returned by func
+ * @protected
+ * @see DBMap#vforeach(DBMap*,DBApply,va_list)
+ */
+ int (*foreach)(DBMap* self, DBApply func, ...);
+
+ /**
+ * Apply <code>func</code> to every entry in the database.
+ * Returns the sum of values returned by func.
+ * @param self Database
+ * @param func Function to be applied
+ * @param args Extra arguments for func
+ * @return Sum of the values returned by func
+ * @protected
+ * @see DBMap#foreach(DBMap*,DBApply,...)
+ */
+ int (*vforeach)(DBMap* self, DBApply func, va_list args);
+
+ /**
+ * Just calls {@link DBMap#vclear}.
+ * Removes all entries from the database.
+ * Before deleting an entry, func is applied to it.
+ * Releases the key and the data.
+ * Returns the sum of values returned by func, if it exists.
+ * @param self Database
+ * @param func Function to be applied to every entry before deleting
+ * @param ... Extra arguments for func
+ * @return Sum of values returned by func
+ * @protected
+ * @see DBMap#vclear(DBMap*,DBApply,va_list)
+ */
+ int (*clear)(DBMap* self, DBApply func, ...);
+
+ /**
+ * Removes all entries from the database.
+ * Before deleting an entry, func is applied to it.
+ * Releases the key and the data.
+ * Returns the sum of values returned by func, if it exists.
+ * @param self Database
+ * @param func Function to be applied to every entry before deleting
+ * @param args Extra arguments for func
+ * @return Sum of values returned by func
+ * @protected
+ * @see DBMap#clear(DBMap*,DBApply,...)
+ */
+ int (*vclear)(DBMap* self, DBApply func, va_list args);
+
+ /**
+ * Just calls {@link DBMap#vdestroy}.
+ * Finalize the database, feeing all the memory it uses.
+ * Before deleting an entry, func is applied to it.
+ * Releases the key and the data.
+ * Returns the sum of values returned by func, if it exists.
+ * NOTE: This locks the database globally. Any attempt to insert or remove
+ * a database entry will give an error and be aborted (except for clearing).
+ * @param self Database
+ * @param func Function to be applied to every entry before deleting
+ * @param ... Extra arguments for func
+ * @return Sum of values returned by func
+ * @protected
+ * @see DBMap#vdestroy(DBMap*,DBApply,va_list)
+ */
+ int (*destroy)(DBMap* self, DBApply func, ...);
+
+ /**
+ * Finalize the database, feeing all the memory it uses.
+ * Before deleting an entry, func is applied to it.
+ * Returns the sum of values returned by func, if it exists.
+ * NOTE: This locks the database globally. Any attempt to insert or remove
+ * a database entry will give an error and be aborted (except for clearing).
+ * @param self Database
+ * @param func Function to be applied to every entry before deleting
+ * @param args Extra arguments for func
+ * @return Sum of values returned by func
+ * @protected
+ * @see DBMap#destroy(DBMap*,DBApply,...)
+ */
+ int (*vdestroy)(DBMap* self, DBApply func, va_list args);
+
+ /**
+ * Return the size of the database (number of items in the database).
+ * @param self Database
+ * @return Size of the database
+ * @protected
+ */
+ unsigned int (*size)(DBMap* self);
+
+ /**
+ * Return the type of the database.
+ * @param self Database
+ * @return Type of the database
+ * @protected
+ */
+ DBType (*type)(DBMap* self);
+
+ /**
+ * Return the options of the database.
+ * @param self Database
+ * @return Options of the database
+ * @protected
+ */
+ DBOptions (*options)(DBMap* self);
};
@@ -726,7 +727,7 @@ DBComparator db_default_cmp(DBType type);
DBHasher db_default_hash(DBType type);
/**
- * Returns the default releaser for the specified type of database with the
+ * Returns the default releaser for the specified type of database with the
* specified options.
* NOTE: the options are fixed by {@link #db_fix_options(DBType,DBOptions)}
* before choosing the releaser
@@ -755,7 +756,7 @@ DBReleaser db_custom_release(DBRelease which);
/**
* Allocate a new database of the specified type.
- * It uses the default comparator, hasher and releaser of the specified
+ * It uses the default comparator, hasher and releaser of the specified
* database type and fixed options.
* NOTE: the options are fixed by {@link #db_fix_options(DBType,DBOptions)}
* before creating the database.
@@ -763,7 +764,7 @@ DBReleaser db_custom_release(DBRelease which);
* @param line Line of the file where the database is being allocated
* @param type Type of database
* @param options Options of the database
- * @param maxlen Maximum length of the string to be used as key in string
+ * @param maxlen Maximum length of the string to be used as key in string
* databases. If 0, the maximum number of maxlen is used (64K).
* @return The interface of the database
* @public
@@ -774,7 +775,7 @@ DBReleaser db_custom_release(DBRelease which);
* @see #db_default_release(DBType,DBOptions)
* @see #db_fix_options(DBType,DBOptions)
*/
-DBMap *db_alloc(const char *file, int line, DBType type, DBOptions options, unsigned short maxlen);
+DBMap* db_alloc(const char *file, int line, DBType type, DBOptions options, unsigned short maxlen);
/**
* Manual cast from 'int' to the union DBKey.
@@ -849,7 +850,7 @@ unsigned int db_data2ui(DBData *data);
* @return Void* value of the data.
* @public
*/
-void *db_data2ptr(DBData *data);
+void* db_data2ptr(DBData *data);
/**
* Initialize the database system.
@@ -868,20 +869,20 @@ void db_final(void);
// Link DB System - From jAthena
struct linkdb_node {
- struct linkdb_node *next;
- struct linkdb_node *prev;
- void *key;
- void *data;
+ struct linkdb_node *next;
+ struct linkdb_node *prev;
+ void *key;
+ void *data;
};
-typedef void (*LinkDBFunc)(void *key, void *data, va_list args);
+typedef void (*LinkDBFunc)(void* key, void* data, va_list args);
-void linkdb_insert(struct linkdb_node **head, void *key, void *data); // d•¡‚ðl—¶‚µ‚È‚¢
-void linkdb_replace(struct linkdb_node **head, void *key, void *data); // d•¡‚ðl—¶‚·‚é
-void *linkdb_search(struct linkdb_node **head, void *key);
-void *linkdb_erase(struct linkdb_node **head, void *key);
-void linkdb_final(struct linkdb_node **head);
-void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
+void linkdb_insert ( struct linkdb_node** head, void *key, void* data); // d•¡‚ðl—¶‚µ‚È‚¢
+void linkdb_replace( struct linkdb_node** head, void *key, void* data); // d•¡‚ðl—¶‚·‚é
+void* linkdb_search ( struct linkdb_node** head, void *key);
+void* linkdb_erase ( struct linkdb_node** head, void *key);
+void linkdb_final ( struct linkdb_node** head );
+void linkdb_foreach( struct linkdb_node** head, LinkDBFunc func, ... );
@@ -893,11 +894,11 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
/// @param __var Index variable
/// @param __cmp Expression that returns true when the target entry is found
#define ARR_FIND(__start, __end, __var, __cmp) \
- do{ \
- for( (__var) = (__start); (__var) < (__end); ++(__var) ) \
- if( __cmp ) \
- break; \
- }while(0)
+ do{ \
+ for( (__var) = (__start); (__var) < (__end); ++(__var) ) \
+ if( __cmp ) \
+ break; \
+ }while(0)
@@ -911,18 +912,18 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
/// @param __arr Array
/// @param __type Type of entry
#define ARR_MOVE(__from, __to, __arr, __type) \
- do{ \
- if( (__from) != (__to) ) \
- { \
- __type __backup__; \
- memmove(&__backup__, (__arr)+(__from), sizeof(__type)); \
- if( (__from) < (__to) ) \
- memmove((__arr)+(__from), (__arr)+(__from)+1, ((__to)-(__from))*sizeof(__type)); \
- else if( (__from) > (__to) ) \
- memmove((__arr)+(__to)+1, (__arr)+(__to), ((__from)-(__to))*sizeof(__type)); \
- memmove((__arr)+(__to), &__backup__, sizeof(__type)); \
- } \
- }while(0)
+ do{ \
+ if( (__from) != (__to) ) \
+ { \
+ __type __backup__; \
+ memmove(&__backup__, (__arr)+(__from), sizeof(__type)); \
+ if( (__from) < (__to) ) \
+ memmove((__arr)+(__from), (__arr)+(__from)+1, ((__to)-(__from))*sizeof(__type)); \
+ else if( (__from) > (__to) ) \
+ memmove((__arr)+(__to)+1, (__arr)+(__to), ((__from)-(__to))*sizeof(__type)); \
+ memmove((__arr)+(__to), &__backup__, sizeof(__type)); \
+ } \
+ }while(0)
@@ -934,12 +935,12 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
/// @param __arr Array
/// @param __type Type of entry
#define ARR_MOVERIGHT(__from, __to, __arr, __type) \
- do{ \
- __type __backup__; \
- memmove(&__backup__, (__arr)+(__from), sizeof(__type)); \
- memmove((__arr)+(__from), (__arr)+(__from)+1, ((__to)-(__from))*sizeof(__type)); \
- memmove((__arr)+(__to), &__backup__, sizeof(__type)); \
- }while(0)
+ do{ \
+ __type __backup__; \
+ memmove(&__backup__, (__arr)+(__from), sizeof(__type)); \
+ memmove((__arr)+(__from), (__arr)+(__from)+1, ((__to)-(__from))*sizeof(__type)); \
+ memmove((__arr)+(__to), &__backup__, sizeof(__type)); \
+ }while(0)
@@ -951,12 +952,12 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
/// @param __arr Array
/// @param __type Type of entry
#define ARR_MOVELEFT(__from, __to, __arr, __type) \
- do{ \
- __type __backup__; \
- memmove(&__backup__, (__arr)+(__from), sizeof(__type)); \
- memmove((__arr)+(__to)+1, (__arr)+(__to), ((__from)-(__to))*sizeof(__type)); \
- memmove((__arr)+(__to), &__backup__, sizeof(__type)); \
- }while(0)
+ do{ \
+ __type __backup__; \
+ memmove(&__backup__, (__arr)+(__from), sizeof(__type)); \
+ memmove((__arr)+(__to)+1, (__arr)+(__to), ((__from)-(__to))*sizeof(__type)); \
+ memmove((__arr)+(__to), &__backup__, sizeof(__type)); \
+ }while(0)
@@ -970,11 +971,11 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
///
/// @param __type Type of data
#define VECTOR_DECL(__type) \
- struct { \
- size_t _max_; \
- size_t _len_; \
- __type* _data_; \
- }
+ struct { \
+ size_t _max_; \
+ size_t _len_; \
+ __type* _data_; \
+ }
@@ -983,11 +984,11 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
/// @param __name Structure name
/// @param __type Type of data
#define VECTOR_STRUCT_DECL(__name,__type) \
- struct __name { \
- size_t _max_; \
- size_t _len_; \
- __type* _data_; \
- }
+ struct __name { \
+ size_t _max_; \
+ size_t _len_; \
+ __type* _data_; \
+ }
@@ -996,7 +997,7 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
/// @param __type Type of data
/// @param __var Variable name
#define VECTOR_VAR(__type,__var) \
- VECTOR_DECL(__type) __var = {0,0,NULL}
+ VECTOR_DECL(__type) __var = {0,0,NULL}
@@ -1005,7 +1006,7 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
/// @param __name Structure name
/// @param __var Variable name
#define VECTOR_STRUCT_VAR(__name,__var) \
- struct __name __var = {0,0,NULL}
+ struct __name __var = {0,0,NULL}
@@ -1013,7 +1014,7 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
///
/// @param __vec Vector
#define VECTOR_INIT(__vec) \
- memset(&(__vec), 0, sizeof(__vec))
+ memset(&(__vec), 0, sizeof(__vec))
@@ -1022,7 +1023,7 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
/// @param __vec Vector
/// @return Array of values
#define VECTOR_DATA(__vec) \
- ( (__vec)._data_ )
+ ( (__vec)._data_ )
@@ -1031,7 +1032,7 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
/// @param __vec Vector
/// @return Length
#define VECTOR_LENGTH(__vec) \
- ( (__vec)._len_ )
+ ( (__vec)._len_ )
@@ -1040,7 +1041,7 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
/// @param __vec Vector
/// @return Capacity
#define VECTOR_CAPACITY(__vec) \
- ( (__vec)._max_ )
+ ( (__vec)._max_ )
@@ -1051,7 +1052,7 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
/// @param __idx Index
/// @return Value
#define VECTOR_INDEX(__vec,__idx) \
- ( VECTOR_DATA(__vec)[__idx] )
+ ( VECTOR_DATA(__vec)[__idx] )
@@ -1061,7 +1062,7 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
/// @param __vec Vector
/// @return First value
#define VECTOR_FIRST(__vec) \
- ( VECTOR_INDEX(__vec,0) )
+ ( VECTOR_INDEX(__vec,0) )
@@ -1071,7 +1072,7 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
/// @param __vec Vector
/// @return Last value
#define VECTOR_LAST(__vec) \
- ( VECTOR_INDEX(__vec,VECTOR_LENGTH(__vec)-1) )
+ ( VECTOR_INDEX(__vec,VECTOR_LENGTH(__vec)-1) )
@@ -1081,27 +1082,27 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
/// @param __vec Vector
/// @param __n Size
#define VECTOR_RESIZE(__vec,__n) \
- do{ \
- if( (__n) > VECTOR_CAPACITY(__vec) ) \
- { /* increase size */ \
- if( VECTOR_CAPACITY(__vec) == 0 ) SET_POINTER(VECTOR_DATA(__vec), aMalloc((__n)*sizeof(VECTOR_FIRST(__vec)))); /* allocate new */ \
- else SET_POINTER(VECTOR_DATA(__vec), aRealloc(VECTOR_DATA(__vec),(__n)*sizeof(VECTOR_FIRST(__vec)))); /* reallocate */ \
- memset(VECTOR_DATA(__vec)+VECTOR_LENGTH(__vec), 0, (VECTOR_CAPACITY(__vec)-VECTOR_LENGTH(__vec))*sizeof(VECTOR_FIRST(__vec))); /* clear new data */ \
- VECTOR_CAPACITY(__vec) = (__n); /* update capacity */ \
- } \
- else if( (__n) == 0 && VECTOR_CAPACITY(__vec) ) \
- { /* clear vector */ \
- aFree(VECTOR_DATA(__vec)); VECTOR_DATA(__vec) = NULL; /* free data */ \
- VECTOR_CAPACITY(__vec) = 0; /* clear capacity */ \
- VECTOR_LENGTH(__vec) = 0; /* clear length */ \
- } \
- else if( (__n) < VECTOR_CAPACITY(__vec) ) \
- { /* reduce size */ \
- SET_POINTER(VECTOR_DATA(__vec), aRealloc(VECTOR_DATA(__vec),(__n)*sizeof(VECTOR_FIRST(__vec)))); /* reallocate */ \
- VECTOR_CAPACITY(__vec) = (__n); /* update capacity */ \
- if( VECTOR_LENGTH(__vec) > (__n) ) VECTOR_LENGTH(__vec) = (__n); /* update length */ \
- } \
- }while(0)
+ do{ \
+ if( (__n) > VECTOR_CAPACITY(__vec) ) \
+ { /* increase size */ \
+ if( VECTOR_CAPACITY(__vec) == 0 ) SET_POINTER(VECTOR_DATA(__vec), aMalloc((__n)*sizeof(VECTOR_FIRST(__vec)))); /* allocate new */ \
+ else SET_POINTER(VECTOR_DATA(__vec), aRealloc(VECTOR_DATA(__vec),(__n)*sizeof(VECTOR_FIRST(__vec)))); /* reallocate */ \
+ memset(VECTOR_DATA(__vec)+VECTOR_LENGTH(__vec), 0, (VECTOR_CAPACITY(__vec)-VECTOR_LENGTH(__vec))*sizeof(VECTOR_FIRST(__vec))); /* clear new data */ \
+ VECTOR_CAPACITY(__vec) = (__n); /* update capacity */ \
+ } \
+ else if( (__n) == 0 && VECTOR_CAPACITY(__vec) ) \
+ { /* clear vector */ \
+ aFree(VECTOR_DATA(__vec)); VECTOR_DATA(__vec) = NULL; /* free data */ \
+ VECTOR_CAPACITY(__vec) = 0; /* clear capacity */ \
+ VECTOR_LENGTH(__vec) = 0; /* clear length */ \
+ } \
+ else if( (__n) < VECTOR_CAPACITY(__vec) ) \
+ { /* reduce size */ \
+ SET_POINTER(VECTOR_DATA(__vec), aRealloc(VECTOR_DATA(__vec),(__n)*sizeof(VECTOR_FIRST(__vec)))); /* reallocate */ \
+ VECTOR_CAPACITY(__vec) = (__n); /* update capacity */ \
+ if( VECTOR_LENGTH(__vec) > (__n) ) VECTOR_LENGTH(__vec) = (__n); /* update length */ \
+ } \
+ }while(0)
@@ -1112,11 +1113,11 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
/// @param __n Empty positions
/// @param __step Increase
#define VECTOR_ENSURE(__vec,__n,__step) \
- do{ \
- size_t _empty_ = VECTOR_CAPACITY(__vec)-VECTOR_LENGTH(__vec); \
- while( (__n) > _empty_ ) _empty_ += (__step); \
- if( _empty_ != VECTOR_CAPACITY(__vec)-VECTOR_LENGTH(__vec) ) VECTOR_RESIZE(__vec,_empty_+VECTOR_LENGTH(__vec)); \
- }while(0)
+ do{ \
+ size_t _empty_ = VECTOR_CAPACITY(__vec)-VECTOR_LENGTH(__vec); \
+ while( (__n) > _empty_ ) _empty_ += (__step); \
+ if( _empty_ != VECTOR_CAPACITY(__vec)-VECTOR_LENGTH(__vec) ) VECTOR_RESIZE(__vec,_empty_+VECTOR_LENGTH(__vec)); \
+ }while(0)
@@ -1126,12 +1127,12 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
/// @param __vec Vector
/// @param __idx Index
#define VECTOR_INSERTZEROED(__vec,__idx) \
- do{ \
- if( (__idx) < VECTOR_LENGTH(__vec) ) /* move data */ \
- memmove(&VECTOR_INDEX(__vec,(__idx)+1),&VECTOR_INDEX(__vec,__idx),(VECTOR_LENGTH(__vec)-(__idx))*sizeof(VECTOR_FIRST(__vec))); \
- memset(&VECTOR_INDEX(__vec,__idx), 0, sizeof(VECTOR_INDEX(__vec,__idx))); /* set zeroed value */ \
- ++VECTOR_LENGTH(__vec); /* increase length */ \
- }while(0)
+ do{ \
+ if( (__idx) < VECTOR_LENGTH(__vec) ) /* move data */ \
+ memmove(&VECTOR_INDEX(__vec,(__idx)+1),&VECTOR_INDEX(__vec,__idx),(VECTOR_LENGTH(__vec)-(__idx))*sizeof(VECTOR_FIRST(__vec))); \
+ memset(&VECTOR_INDEX(__vec,__idx), 0, sizeof(VECTOR_INDEX(__vec,__idx))); /* set zeroed value */ \
+ ++VECTOR_LENGTH(__vec); /* increase length */ \
+ }while(0)
@@ -1142,12 +1143,12 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
/// @param __idx Index
/// @param __val Value
#define VECTOR_INSERT(__vec,__idx,__val) \
- do{ \
- if( (__idx) < VECTOR_LENGTH(__vec) ) /* move data */ \
- memmove(&VECTOR_INDEX(__vec,(__idx)+1),&VECTOR_INDEX(__vec,__idx),(VECTOR_LENGTH(__vec)-(__idx))*sizeof(VECTOR_FIRST(__vec))); \
- VECTOR_INDEX(__vec,__idx) = (__val); /* set value */ \
- ++VECTOR_LENGTH(__vec); /* increase length */ \
- }while(0)
+ do{ \
+ if( (__idx) < VECTOR_LENGTH(__vec) ) /* move data */ \
+ memmove(&VECTOR_INDEX(__vec,(__idx)+1),&VECTOR_INDEX(__vec,__idx),(VECTOR_LENGTH(__vec)-(__idx))*sizeof(VECTOR_FIRST(__vec))); \
+ VECTOR_INDEX(__vec,__idx) = (__val); /* set value */ \
+ ++VECTOR_LENGTH(__vec); /* increase length */ \
+ }while(0)
@@ -1158,7 +1159,7 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
/// @param __idx Index
/// @param __val Value
#define VECTOR_INSERTCOPY(__vec,__idx,__val) \
- VECTOR_INSERTARRAY(__vec,__idx,&(__val),1)
+ VECTOR_INSERTARRAY(__vec,__idx,&(__val),1)
@@ -1170,12 +1171,12 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
/// @param __pval Array of values
/// @param __n Number of values
#define VECTOR_INSERTARRAY(__vec,__idx,__pval,__n) \
- do{ \
- if( (__idx) < VECTOR_LENGTH(__vec) ) /* move data */ \
- memmove(&VECTOR_INDEX(__vec,(__idx)+(__n)),&VECTOR_INDEX(__vec,__idx),(VECTOR_LENGTH(__vec)-(__idx))*sizeof(VECTOR_FIRST(__vec))); \
- memcpy(&VECTOR_INDEX(__vec,__idx), (__pval), (__n)*sizeof(VECTOR_FIRST(__vec))); /* set values */ \
- VECTOR_LENGTH(__vec) += (__n); /* increase length */ \
- }while(0)
+ do{ \
+ if( (__idx) < VECTOR_LENGTH(__vec) ) /* move data */ \
+ memmove(&VECTOR_INDEX(__vec,(__idx)+(__n)),&VECTOR_INDEX(__vec,__idx),(VECTOR_LENGTH(__vec)-(__idx))*sizeof(VECTOR_FIRST(__vec))); \
+ memcpy(&VECTOR_INDEX(__vec,__idx), (__pval), (__n)*sizeof(VECTOR_FIRST(__vec))); /* set values */ \
+ VECTOR_LENGTH(__vec) += (__n); /* increase length */ \
+ }while(0)
@@ -1184,10 +1185,10 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
///
/// @param __vec Vector
#define VECTOR_PUSHZEROED(__vec) \
- do{ \
- memset(&VECTOR_INDEX(__vec,VECTOR_LENGTH(__vec)), 0, sizeof(VECTOR_INDEX(__vec,VECTOR_LENGTH(__vec)))); /* set zeroed value */ \
- ++VECTOR_LENGTH(__vec); /* increase length */ \
- }while(0)
+ do{ \
+ memset(&VECTOR_INDEX(__vec,VECTOR_LENGTH(__vec)), 0, sizeof(VECTOR_INDEX(__vec,VECTOR_LENGTH(__vec)))); /* set zeroed value */ \
+ ++VECTOR_LENGTH(__vec); /* increase length */ \
+ }while(0)
/// Inserts a value in the end of the vector. (using the '=' operator)
@@ -1196,10 +1197,10 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
/// @param __vec Vector
/// @param __val Value
#define VECTOR_PUSH(__vec,__val) \
- do{ \
- VECTOR_INDEX(__vec,VECTOR_LENGTH(__vec)) = (__val); /* set value */ \
- ++VECTOR_LENGTH(__vec); /* increase length */ \
- }while(0)
+ do{ \
+ VECTOR_INDEX(__vec,VECTOR_LENGTH(__vec)) = (__val); /* set value */ \
+ ++VECTOR_LENGTH(__vec); /* increase length */ \
+ }while(0)
@@ -1209,7 +1210,7 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
/// @param __vec Vector
/// @param __val Value
#define VECTOR_PUSHCOPY(__vec,__val) \
- VECTOR_PUSHARRAY(__vec,&(__val),1)
+ VECTOR_PUSHARRAY(__vec,&(__val),1)
@@ -1220,10 +1221,10 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
/// @param __pval Array of values
/// @param __n Number of values
#define VECTOR_PUSHARRAY(__vec,__pval,__n) \
- do{ \
- memcpy(&VECTOR_INDEX(__vec,VECTOR_LENGTH(__vec)), (__pval), (__n)*sizeof(VECTOR_FIRST(__vec))); /* set values */ \
- VECTOR_LENGTH(__vec) += (__n); /* increase length */ \
- }while(0)
+ do{ \
+ memcpy(&VECTOR_INDEX(__vec,VECTOR_LENGTH(__vec)), (__pval), (__n)*sizeof(VECTOR_FIRST(__vec))); /* set values */ \
+ VECTOR_LENGTH(__vec) += (__n); /* increase length */ \
+ }while(0)
@@ -1233,7 +1234,7 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
/// @param __vec Vector
/// @return Removed value
#define VECTOR_POP(__vec) \
- ( VECTOR_INDEX(__vec,--VECTOR_LENGTH(__vec)) )
+ ( VECTOR_INDEX(__vec,--VECTOR_LENGTH(__vec)) )
@@ -1244,7 +1245,7 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
/// @param __n Number of pops
/// @return Last removed value
#define VECTOR_POPN(__vec,__n) \
- ( VECTOR_INDEX(__vec,(VECTOR_LENGTH(__vec)-=(__n))) )
+ ( VECTOR_INDEX(__vec,(VECTOR_LENGTH(__vec)-=(__n))) )
@@ -1254,7 +1255,7 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
/// @param __vec Vector
/// @param __idx Index
#define VECTOR_ERASE(__vec,__idx) \
- VECTOR_ERASEN(__vec,__idx,1)
+ VECTOR_ERASEN(__vec,__idx,1)
@@ -1265,11 +1266,11 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
/// @param __idx Index
/// @param __n Number of values
#define VECTOR_ERASEN(__vec,__idx,__n) \
- do{ \
- if( (__idx) < VECTOR_LENGTH(__vec)-(__n) ) /* move data */ \
- memmove(&VECTOR_INDEX(__vec,__idx),&VECTOR_INDEX(__vec,(__idx)+(__n)),(VECTOR_LENGTH(__vec)-((__idx)+(__n)))*sizeof(VECTOR_FIRST(__vec))); \
- VECTOR_LENGTH(__vec) -= (__n); /* decrease length */ \
- }while(0)
+ do{ \
+ if( (__idx) < VECTOR_LENGTH(__vec)-(__n) ) /* move data */ \
+ memmove(&VECTOR_INDEX(__vec,__idx),&VECTOR_INDEX(__vec,(__idx)+(__n)),(VECTOR_LENGTH(__vec)-((__idx)+(__n)))*sizeof(VECTOR_FIRST(__vec))); \
+ VECTOR_LENGTH(__vec) -= (__n); /* decrease length */ \
+ }while(0)
@@ -1277,14 +1278,14 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
///
/// @param __vec Vector
#define VECTOR_CLEAR(__vec) \
- do{ \
- if( VECTOR_CAPACITY(__vec) ) \
- { \
- aFree(VECTOR_DATA(__vec)); VECTOR_DATA(__vec) = NULL; /* clear allocated array */ \
- VECTOR_CAPACITY(__vec) = 0; /* clear capacity */ \
- VECTOR_LENGTH(__vec) = 0; /* clear length */ \
- } \
- }while(0)
+ do{ \
+ if( VECTOR_CAPACITY(__vec) ) \
+ { \
+ aFree(VECTOR_DATA(__vec)); VECTOR_DATA(__vec) = NULL; /* clear allocated array */ \
+ VECTOR_CAPACITY(__vec) = 0; /* clear capacity */ \
+ VECTOR_LENGTH(__vec) = 0; /* clear length */ \
+ } \
+ }while(0)
@@ -1387,18 +1388,18 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
/// @param __val Value
/// @param __topcmp Comparator
#define BHEAP_PUSH(__heap,__val,__topcmp) \
- do{ \
- size_t _i_ = VECTOR_LENGTH(__heap); \
- VECTOR_PUSH(__heap,__val); /* insert at end */ \
- while( _i_ ) \
- { /* restore heap property in parents */ \
- size_t _parent_ = (_i_-1)/2; \
- if( __topcmp(VECTOR_INDEX(__heap,_parent_),VECTOR_INDEX(__heap,_i_)) < 0 ) \
- break; /* done */ \
- swap(VECTOR_INDEX(__heap,_parent_),VECTOR_INDEX(__heap,_i_)); \
- _i_ = _parent_; \
- } \
- }while(0)
+ do{ \
+ size_t _i_ = VECTOR_LENGTH(__heap); \
+ VECTOR_PUSH(__heap,__val); /* insert at end */ \
+ while( _i_ ) \
+ { /* restore heap property in parents */ \
+ size_t _parent_ = (_i_-1)/2; \
+ if( __topcmp(VECTOR_INDEX(__heap,_parent_),VECTOR_INDEX(__heap,_i_)) < 0 ) \
+ break; /* done */ \
+ swap(VECTOR_INDEX(__heap,_parent_),VECTOR_INDEX(__heap,_i_)); \
+ _i_ = _parent_; \
+ } \
+ }while(0)
@@ -1428,36 +1429,36 @@ void linkdb_foreach(struct linkdb_node **head, LinkDBFunc func, ...);
/// @param __idx Index
/// @param __topcmp Comparator
#define BHEAP_POPINDEX(__heap,__idx,__topcmp) \
- do{ \
- size_t _i_ = __idx; \
- VECTOR_INDEX(__heap,__idx) = VECTOR_POP(__heap); /* put last at index */ \
- while( _i_ ) \
- { /* restore heap property in parents */ \
- size_t _parent_ = (_i_-1)/2; \
- if( __topcmp(VECTOR_INDEX(__heap,_parent_),VECTOR_INDEX(__heap,_i_)) < 0 ) \
- break; /* done */ \
- swap(VECTOR_INDEX(__heap,_parent_),VECTOR_INDEX(__heap,_i_)); \
- _i_ = _parent_; \
- } \
- while( _i_ < VECTOR_LENGTH(__heap) ) \
- { /* restore heap property in childs */ \
- size_t _lchild_ = _i_*2 + 1; \
- size_t _rchild_ = _i_*2 + 2; \
- if( (_lchild_ >= VECTOR_LENGTH(__heap) || __topcmp(VECTOR_INDEX(__heap,_i_),VECTOR_INDEX(__heap,_lchild_)) <= 0) && \
- (_rchild_ >= VECTOR_LENGTH(__heap) || __topcmp(VECTOR_INDEX(__heap,_i_),VECTOR_INDEX(__heap,_rchild_)) <= 0) ) \
- break; /* done */ \
- else if( _rchild_ >= VECTOR_LENGTH(__heap) || __topcmp(VECTOR_INDEX(__heap,_lchild_),VECTOR_INDEX(__heap,_rchild_)) <= 0 ) \
- { /* left child */ \
- swap(VECTOR_INDEX(__heap,_i_),VECTOR_INDEX(__heap,_lchild_)); \
- _i_ = _lchild_; \
- } \
- else \
- { /* right child */ \
- swap(VECTOR_INDEX(__heap,_i_),VECTOR_INDEX(__heap,_rchild_)); \
- _i_ = _rchild_; \
- } \
- } \
- }while(0)
+ do{ \
+ size_t _i_ = __idx; \
+ VECTOR_INDEX(__heap,__idx) = VECTOR_POP(__heap); /* put last at index */ \
+ while( _i_ ) \
+ { /* restore heap property in parents */ \
+ size_t _parent_ = (_i_-1)/2; \
+ if( __topcmp(VECTOR_INDEX(__heap,_parent_),VECTOR_INDEX(__heap,_i_)) < 0 ) \
+ break; /* done */ \
+ swap(VECTOR_INDEX(__heap,_parent_),VECTOR_INDEX(__heap,_i_)); \
+ _i_ = _parent_; \
+ } \
+ while( _i_ < VECTOR_LENGTH(__heap) ) \
+ { /* restore heap property in childs */ \
+ size_t _lchild_ = _i_*2 + 1; \
+ size_t _rchild_ = _i_*2 + 2; \
+ if( (_lchild_ >= VECTOR_LENGTH(__heap) || __topcmp(VECTOR_INDEX(__heap,_i_),VECTOR_INDEX(__heap,_lchild_)) <= 0) && \
+ (_rchild_ >= VECTOR_LENGTH(__heap) || __topcmp(VECTOR_INDEX(__heap,_i_),VECTOR_INDEX(__heap,_rchild_)) <= 0) ) \
+ break; /* done */ \
+ else if( _rchild_ >= VECTOR_LENGTH(__heap) || __topcmp(VECTOR_INDEX(__heap,_lchild_),VECTOR_INDEX(__heap,_rchild_)) <= 0 ) \
+ { /* left child */ \
+ swap(VECTOR_INDEX(__heap,_i_),VECTOR_INDEX(__heap,_lchild_)); \
+ _i_ = _lchild_; \
+ } \
+ else \
+ { /* right child */ \
+ swap(VECTOR_INDEX(__heap,_i_),VECTOR_INDEX(__heap,_rchild_)); \
+ _i_ = _rchild_; \
+ } \
+ } \
+ }while(0)
diff --git a/src/common/des.c b/src/common/des.c
index f2347f3c4..917fc33e0 100644
--- a/src/common/des.c
+++ b/src/common/des.c
@@ -12,201 +12,207 @@
/// Bitmask for accessing individual bits of a byte.
static const uint8_t mask[8] = {
- 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
+ 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
};
/// Initial permutation (IP).
-static void IP(BIT64 *src)
+static void IP(BIT64* src)
{
- BIT64 tmp = {{0}};
-
- static const uint8_t ip_table[64] = {
- 58, 50, 42, 34, 26, 18, 10, 2,
- 60, 52, 44, 36, 28, 20, 12, 4,
- 62, 54, 46, 38, 30, 22, 14, 6,
- 64, 56, 48, 40, 32, 24, 16, 8,
- 57, 49, 41, 33, 25, 17, 9, 1,
- 59, 51, 43, 35, 27, 19, 11, 3,
- 61, 53, 45, 37, 29, 21, 13, 5,
- 63, 55, 47, 39, 31, 23, 15, 7,
- };
-
- size_t i;
- for (i = 0; i < ARRAYLENGTH(ip_table); ++i) {
- uint8_t j = ip_table[i] - 1;
- if (src->b[(j >> 3) & 7] & mask[j & 7])
- tmp .b[(i >> 3) & 7] |= mask[i & 7];
- }
-
- *src = tmp;
+ BIT64 tmp = {{0}};
+
+ static const uint8_t ip_table[64] = {
+ 58, 50, 42, 34, 26, 18, 10, 2,
+ 60, 52, 44, 36, 28, 20, 12, 4,
+ 62, 54, 46, 38, 30, 22, 14, 6,
+ 64, 56, 48, 40, 32, 24, 16, 8,
+ 57, 49, 41, 33, 25, 17, 9, 1,
+ 59, 51, 43, 35, 27, 19, 11, 3,
+ 61, 53, 45, 37, 29, 21, 13, 5,
+ 63, 55, 47, 39, 31, 23, 15, 7,
+ };
+
+ size_t i;
+ for( i = 0; i < ARRAYLENGTH(ip_table); ++i )
+ {
+ uint8_t j = ip_table[i] - 1;
+ if( src->b[(j >> 3) & 7] & mask[j & 7] )
+ tmp .b[(i >> 3) & 7] |= mask[i & 7];
+ }
+
+ *src = tmp;
}
/// Final permutation (IP^-1).
-static void FP(BIT64 *src)
+static void FP(BIT64* src)
{
- BIT64 tmp = {{0}};
-
- static const uint8_t fp_table[64] = {
- 40, 8, 48, 16, 56, 24, 64, 32,
- 39, 7, 47, 15, 55, 23, 63, 31,
- 38, 6, 46, 14, 54, 22, 62, 30,
- 37, 5, 45, 13, 53, 21, 61, 29,
- 36, 4, 44, 12, 52, 20, 60, 28,
- 35, 3, 43, 11, 51, 19, 59, 27,
- 34, 2, 42, 10, 50, 18, 58, 26,
- 33, 1, 41, 9, 49, 17, 57, 25,
- };
-
- size_t i;
- for (i = 0; i < ARRAYLENGTH(fp_table); ++i) {
- uint8_t j = fp_table[i] - 1;
- if (src->b[(j >> 3) & 7] & mask[j & 7])
- tmp .b[(i >> 3) & 7] |= mask[i & 7];
- }
-
- *src = tmp;
+ BIT64 tmp = {{0}};
+
+ static const uint8_t fp_table[64] = {
+ 40, 8, 48, 16, 56, 24, 64, 32,
+ 39, 7, 47, 15, 55, 23, 63, 31,
+ 38, 6, 46, 14, 54, 22, 62, 30,
+ 37, 5, 45, 13, 53, 21, 61, 29,
+ 36, 4, 44, 12, 52, 20, 60, 28,
+ 35, 3, 43, 11, 51, 19, 59, 27,
+ 34, 2, 42, 10, 50, 18, 58, 26,
+ 33, 1, 41, 9, 49, 17, 57, 25,
+ };
+
+ size_t i;
+ for( i = 0; i < ARRAYLENGTH(fp_table); ++i )
+ {
+ uint8_t j = fp_table[i] - 1;
+ if( src->b[(j >> 3) & 7] & mask[j & 7] )
+ tmp .b[(i >> 3) & 7] |= mask[i & 7];
+ }
+
+ *src = tmp;
}
/// Expansion (E).
/// Expands upper four 8-bits (32b) into eight 6-bits (48b).
-static void E(BIT64 *src)
+static void E(BIT64* src)
{
- BIT64 tmp = {{0}};
-
- if (false) {
- // original
- static const uint8_t expand_table[48] = {
- 32, 1, 2, 3, 4, 5,
- 4, 5, 6, 7, 8, 9,
- 8, 9, 10, 11, 12, 13,
- 12, 13, 14, 15, 16, 17,
- 16, 17, 18, 19, 20, 21,
- 20, 21, 22, 23, 24, 25,
- 24, 25, 26, 27, 28, 29,
- 28, 29, 30, 31, 32, 1,
- };
-
- size_t i;
- for (i = 0; i < ARRAYLENGTH(expand_table); ++i) {
- uint8_t j = expand_table[i] - 1;
- if (src->b[j / 8 + 4] & mask[j % 8])
- tmp .b[i / 6 + 0] |= mask[i % 6];
- }
- } else {
- // optimized
- tmp.b[0] = ((src->b[7]<<5) | (src->b[4]>>3)) & 0x3f; // ..0 vutsr
- tmp.b[1] = ((src->b[4]<<1) | (src->b[5]>>7)) & 0x3f; // ..srqpo n
- tmp.b[2] = ((src->b[4]<<5) | (src->b[5]>>3)) & 0x3f; // ..o nmlkj
- tmp.b[3] = ((src->b[5]<<1) | (src->b[6]>>7)) & 0x3f; // ..kjihg f
- tmp.b[4] = ((src->b[5]<<5) | (src->b[6]>>3)) & 0x3f; // ..g fedcb
- tmp.b[5] = ((src->b[6]<<1) | (src->b[7]>>7)) & 0x3f; // ..cba98 7
- tmp.b[6] = ((src->b[6]<<5) | (src->b[7]>>3)) & 0x3f; // ..8 76543
- tmp.b[7] = ((src->b[7]<<1) | (src->b[4]>>7)) & 0x3f; // ..43210 v
- }
-
- *src = tmp;
+ BIT64 tmp = {{0}};
+
+if( false )
+{// original
+ static const uint8_t expand_table[48] = {
+ 32, 1, 2, 3, 4, 5,
+ 4, 5, 6, 7, 8, 9,
+ 8, 9, 10, 11, 12, 13,
+ 12, 13, 14, 15, 16, 17,
+ 16, 17, 18, 19, 20, 21,
+ 20, 21, 22, 23, 24, 25,
+ 24, 25, 26, 27, 28, 29,
+ 28, 29, 30, 31, 32, 1,
+ };
+
+ size_t i;
+ for( i = 0; i < ARRAYLENGTH(expand_table); ++i )
+ {
+ uint8_t j = expand_table[i] - 1;
+ if( src->b[j / 8 + 4] & mask[j % 8] )
+ tmp .b[i / 6 + 0] |= mask[i % 6];
+ }
+}
+else
+{// optimized
+ tmp.b[0] = ((src->b[7]<<5) | (src->b[4]>>3)) & 0x3f; // ..0 vutsr
+ tmp.b[1] = ((src->b[4]<<1) | (src->b[5]>>7)) & 0x3f; // ..srqpo n
+ tmp.b[2] = ((src->b[4]<<5) | (src->b[5]>>3)) & 0x3f; // ..o nmlkj
+ tmp.b[3] = ((src->b[5]<<1) | (src->b[6]>>7)) & 0x3f; // ..kjihg f
+ tmp.b[4] = ((src->b[5]<<5) | (src->b[6]>>3)) & 0x3f; // ..g fedcb
+ tmp.b[5] = ((src->b[6]<<1) | (src->b[7]>>7)) & 0x3f; // ..cba98 7
+ tmp.b[6] = ((src->b[6]<<5) | (src->b[7]>>3)) & 0x3f; // ..8 76543
+ tmp.b[7] = ((src->b[7]<<1) | (src->b[4]>>7)) & 0x3f; // ..43210 v
+}
+
+ *src = tmp;
}
/// Transposition (P-BOX).
-static void TP(BIT64 *src)
+static void TP(BIT64* src)
{
- BIT64 tmp = {{0}};
-
- static const uint8_t tp_table[32] = {
- 16, 7, 20, 21,
- 29, 12, 28, 17,
- 1, 15, 23, 26,
- 5, 18, 31, 10,
- 2, 8, 24, 14,
- 32, 27, 3, 9,
- 19, 13, 30, 6,
- 22, 11, 4, 25,
- };
-
- size_t i;
- for (i = 0; i < ARRAYLENGTH(tp_table); ++i) {
- uint8_t j = tp_table[i] - 1;
- if (src->b[(j >> 3) + 0] & mask[j & 7])
- tmp .b[(i >> 3) + 4] |= mask[i & 7];
- }
-
- *src = tmp;
+ BIT64 tmp = {{0}};
+
+ static const uint8_t tp_table[32] = {
+ 16, 7, 20, 21,
+ 29, 12, 28, 17,
+ 1, 15, 23, 26,
+ 5, 18, 31, 10,
+ 2, 8, 24, 14,
+ 32, 27, 3, 9,
+ 19, 13, 30, 6,
+ 22, 11, 4, 25,
+ };
+
+ size_t i;
+ for( i = 0; i < ARRAYLENGTH(tp_table); ++i )
+ {
+ uint8_t j = tp_table[i] - 1;
+ if( src->b[(j >> 3) + 0] & mask[j & 7] )
+ tmp .b[(i >> 3) + 4] |= mask[i & 7];
+ }
+
+ *src = tmp;
}
/// Substitution boxes (S-boxes).
/// NOTE: This implementation was optimized to process two nibbles in one step (twice as fast).
-static void SBOX(BIT64 *src)
+static void SBOX(BIT64* src)
{
- BIT64 tmp = {{0}};
-
- static const uint8_t s_table[4][64] = {
- {
- 0xef, 0x03, 0x41, 0xfd, 0xd8, 0x74, 0x1e, 0x47, 0x26, 0xef, 0xfb, 0x22, 0xb3, 0xd8, 0x84, 0x1e,
- 0x39, 0xac, 0xa7, 0x60, 0x62, 0xc1, 0xcd, 0xba, 0x5c, 0x96, 0x90, 0x59, 0x05, 0x3b, 0x7a, 0x85,
- 0x40, 0xfd, 0x1e, 0xc8, 0xe7, 0x8a, 0x8b, 0x21, 0xda, 0x43, 0x64, 0x9f, 0x2d, 0x14, 0xb1, 0x72,
- 0xf5, 0x5b, 0xc8, 0xb6, 0x9c, 0x37, 0x76, 0xec, 0x39, 0xa0, 0xa3, 0x05, 0x52, 0x6e, 0x0f, 0xd9,
- },{
- 0xa7, 0xdd, 0x0d, 0x78, 0x9e, 0x0b, 0xe3, 0x95, 0x60, 0x36, 0x36, 0x4f, 0xf9, 0x60, 0x5a, 0xa3,
- 0x11, 0x24, 0xd2, 0x87, 0xc8, 0x52, 0x75, 0xec, 0xbb, 0xc1, 0x4c, 0xba, 0x24, 0xfe, 0x8f, 0x19,
- 0xda, 0x13, 0x66, 0xaf, 0x49, 0xd0, 0x90, 0x06, 0x8c, 0x6a, 0xfb, 0x91, 0x37, 0x8d, 0x0d, 0x78,
- 0xbf, 0x49, 0x11, 0xf4, 0x23, 0xe5, 0xce, 0x3b, 0x55, 0xbc, 0xa2, 0x57, 0xe8, 0x22, 0x74, 0xce,
- },{
- 0x2c, 0xea, 0xc1, 0xbf, 0x4a, 0x24, 0x1f, 0xc2, 0x79, 0x47, 0xa2, 0x7c, 0xb6, 0xd9, 0x68, 0x15,
- 0x80, 0x56, 0x5d, 0x01, 0x33, 0xfd, 0xf4, 0xae, 0xde, 0x30, 0x07, 0x9b, 0xe5, 0x83, 0x9b, 0x68,
- 0x49, 0xb4, 0x2e, 0x83, 0x1f, 0xc2, 0xb5, 0x7c, 0xa2, 0x19, 0xd8, 0xe5, 0x7c, 0x2f, 0x83, 0xda,
- 0xf7, 0x6b, 0x90, 0xfe, 0xc4, 0x01, 0x5a, 0x97, 0x61, 0xa6, 0x3d, 0x40, 0x0b, 0x58, 0xe6, 0x3d,
- },{
- 0x4d, 0xd1, 0xb2, 0x0f, 0x28, 0xbd, 0xe4, 0x78, 0xf6, 0x4a, 0x0f, 0x93, 0x8b, 0x17, 0xd1, 0xa4,
- 0x3a, 0xec, 0xc9, 0x35, 0x93, 0x56, 0x7e, 0xcb, 0x55, 0x20, 0xa0, 0xfe, 0x6c, 0x89, 0x17, 0x62,
- 0x17, 0x62, 0x4b, 0xb1, 0xb4, 0xde, 0xd1, 0x87, 0xc9, 0x14, 0x3c, 0x4a, 0x7e, 0xa8, 0xe2, 0x7d,
- 0xa0, 0x9f, 0xf6, 0x5c, 0x6a, 0x09, 0x8d, 0xf0, 0x0f, 0xe3, 0x53, 0x25, 0x95, 0x36, 0x28, 0xcb,
- }
- };
-
- size_t i;
- for (i = 0; i < ARRAYLENGTH(s_table); ++i) {
- tmp.b[i] = (s_table[i][src->b[i*2+0]] & 0xf0)
- | (s_table[i][src->b[i*2+1]] & 0x0f);
- }
-
- *src = tmp;
+ BIT64 tmp = {{0}};
+
+ static const uint8_t s_table[4][64] = {
+ {
+ 0xef, 0x03, 0x41, 0xfd, 0xd8, 0x74, 0x1e, 0x47, 0x26, 0xef, 0xfb, 0x22, 0xb3, 0xd8, 0x84, 0x1e,
+ 0x39, 0xac, 0xa7, 0x60, 0x62, 0xc1, 0xcd, 0xba, 0x5c, 0x96, 0x90, 0x59, 0x05, 0x3b, 0x7a, 0x85,
+ 0x40, 0xfd, 0x1e, 0xc8, 0xe7, 0x8a, 0x8b, 0x21, 0xda, 0x43, 0x64, 0x9f, 0x2d, 0x14, 0xb1, 0x72,
+ 0xf5, 0x5b, 0xc8, 0xb6, 0x9c, 0x37, 0x76, 0xec, 0x39, 0xa0, 0xa3, 0x05, 0x52, 0x6e, 0x0f, 0xd9,
+ },{
+ 0xa7, 0xdd, 0x0d, 0x78, 0x9e, 0x0b, 0xe3, 0x95, 0x60, 0x36, 0x36, 0x4f, 0xf9, 0x60, 0x5a, 0xa3,
+ 0x11, 0x24, 0xd2, 0x87, 0xc8, 0x52, 0x75, 0xec, 0xbb, 0xc1, 0x4c, 0xba, 0x24, 0xfe, 0x8f, 0x19,
+ 0xda, 0x13, 0x66, 0xaf, 0x49, 0xd0, 0x90, 0x06, 0x8c, 0x6a, 0xfb, 0x91, 0x37, 0x8d, 0x0d, 0x78,
+ 0xbf, 0x49, 0x11, 0xf4, 0x23, 0xe5, 0xce, 0x3b, 0x55, 0xbc, 0xa2, 0x57, 0xe8, 0x22, 0x74, 0xce,
+ },{
+ 0x2c, 0xea, 0xc1, 0xbf, 0x4a, 0x24, 0x1f, 0xc2, 0x79, 0x47, 0xa2, 0x7c, 0xb6, 0xd9, 0x68, 0x15,
+ 0x80, 0x56, 0x5d, 0x01, 0x33, 0xfd, 0xf4, 0xae, 0xde, 0x30, 0x07, 0x9b, 0xe5, 0x83, 0x9b, 0x68,
+ 0x49, 0xb4, 0x2e, 0x83, 0x1f, 0xc2, 0xb5, 0x7c, 0xa2, 0x19, 0xd8, 0xe5, 0x7c, 0x2f, 0x83, 0xda,
+ 0xf7, 0x6b, 0x90, 0xfe, 0xc4, 0x01, 0x5a, 0x97, 0x61, 0xa6, 0x3d, 0x40, 0x0b, 0x58, 0xe6, 0x3d,
+ },{
+ 0x4d, 0xd1, 0xb2, 0x0f, 0x28, 0xbd, 0xe4, 0x78, 0xf6, 0x4a, 0x0f, 0x93, 0x8b, 0x17, 0xd1, 0xa4,
+ 0x3a, 0xec, 0xc9, 0x35, 0x93, 0x56, 0x7e, 0xcb, 0x55, 0x20, 0xa0, 0xfe, 0x6c, 0x89, 0x17, 0x62,
+ 0x17, 0x62, 0x4b, 0xb1, 0xb4, 0xde, 0xd1, 0x87, 0xc9, 0x14, 0x3c, 0x4a, 0x7e, 0xa8, 0xe2, 0x7d,
+ 0xa0, 0x9f, 0xf6, 0x5c, 0x6a, 0x09, 0x8d, 0xf0, 0x0f, 0xe3, 0x53, 0x25, 0x95, 0x36, 0x28, 0xcb,
+ }
+ };
+
+ size_t i;
+ for( i = 0; i < ARRAYLENGTH(s_table); ++i )
+ {
+ tmp.b[i] = (s_table[i][src->b[i*2+0]] & 0xf0)
+ | (s_table[i][src->b[i*2+1]] & 0x0f);
+ }
+
+ *src = tmp;
}
/// DES round function.
/// XORs src[0..3] with TP(SBOX(E(src[4..7]))).
-static void RoundFunction(BIT64 *src)
+static void RoundFunction(BIT64* src)
{
- BIT64 tmp = *src;
- E(&tmp);
- SBOX(&tmp);
- TP(&tmp);
-
- src->b[0] ^= tmp.b[4];
- src->b[1] ^= tmp.b[5];
- src->b[2] ^= tmp.b[6];
- src->b[3] ^= tmp.b[7];
+ BIT64 tmp = *src;
+ E(&tmp);
+ SBOX(&tmp);
+ TP(&tmp);
+
+ src->b[0] ^= tmp.b[4];
+ src->b[1] ^= tmp.b[5];
+ src->b[2] ^= tmp.b[6];
+ src->b[3] ^= tmp.b[7];
}
-void des_decrypt_block(BIT64 *block)
+void des_decrypt_block(BIT64* block)
{
- IP(block);
- RoundFunction(block);
- FP(block);
+ IP(block);
+ RoundFunction(block);
+ FP(block);
}
-void des_decrypt(unsigned char *data, size_t size)
+void des_decrypt(unsigned char* data, size_t size)
{
- BIT64 *p = (BIT64 *)data;
- size_t i;
+ BIT64* p = (BIT64*)data;
+ size_t i;
- for (i = 0; i*8 < size; i += 8)
- des_decrypt_block(p);
+ for( i = 0; i*8 < size; i += 8 )
+ des_decrypt_block(p);
}
diff --git a/src/common/des.h b/src/common/des.h
index a13a17165..e42136436 100644
--- a/src/common/des.h
+++ b/src/common/des.h
@@ -1,17 +1,15 @@
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder
-#ifndef _DES_H_
-#define _DES_H_
+#ifndef _DES_H_
+#define _DES_H_
/// One 64-bit block.
-typedef struct BIT64 {
- uint8_t b[8];
-} BIT64;
+typedef struct BIT64 { uint8_t b[8]; } BIT64;
-void des_decrypt_block(BIT64 *block);
-void des_decrypt(unsigned char *data, size_t size);
+void des_decrypt_block(BIT64* block);
+void des_decrypt(unsigned char* data, size_t size);
#endif // _DES_H_
diff --git a/src/common/ers.c b/src/common/ers.c
index d75f23f6f..b94b0888d 100644
--- a/src/common/ers.c
+++ b/src/common/ers.c
@@ -51,51 +51,54 @@
#define ERS_ROOT_SIZE 256
#define ERS_BLOCK_ENTRIES 4096
-struct ers_list {
- struct ers_list *Next;
+struct ers_list
+{
+ struct ers_list *Next;
};
-typedef struct ers_cache {
- // Allocated object size, including ers_list size
- unsigned int ObjectSize;
-
- // Number of ers_instances referencing this
- int ReferenceCount;
+typedef struct ers_cache
+{
+ // Allocated object size, including ers_list size
+ unsigned int ObjectSize;
- // Reuse linked list
- struct ers_list *ReuseList;
+ // Number of ers_instances referencing this
+ int ReferenceCount;
- // Memory blocks array
- unsigned char **Blocks;
+ // Reuse linked list
+ struct ers_list *ReuseList;
- // Max number of blocks
- unsigned int Max;
+ // Memory blocks array
+ unsigned char **Blocks;
- // Free objects count
- unsigned int Free;
+ // Max number of blocks
+ unsigned int Max;
- // Used objects count
- unsigned int Used;
+ // Free objects count
+ unsigned int Free;
+
+ // Used objects count
+ unsigned int Used;
- // Linked list
- struct ers_cache *Next, *Prev;
+ // Linked list
+ struct ers_cache *Next, *Prev;
} ers_cache_t;
-typedef struct {
- // Interface to ERS
- struct eri VTable;
-
- // Name, used for debbuging purpouses
- char *Name;
+typedef struct
+{
+ // Interface to ERS
+ struct eri VTable;
+
+ // Name, used for debbuging purpouses
+ char *Name;
- // Misc options
- enum ERSOptions Options;
+ // Misc options
+ enum ERSOptions Options;
- // Our cache
- ers_cache_t *Cache;
+ // Our cache
+ ers_cache_t *Cache;
- // Count of objects in use, used for detecting memory leaks
- unsigned int Count;
+ // Count of objects in use, used for detecting memory leaks
+ unsigned int Count;
} ers_instance_t;
@@ -104,171 +107,186 @@ static ers_cache_t *CacheList;
static ers_cache_t *ers_find_cache(unsigned int size)
{
- ers_cache_t *cache;
-
- for (cache = CacheList; cache; cache = cache->Next)
- if (cache->ObjectSize == size)
- return cache;
-
- CREATE(cache, ers_cache_t, 1);
- cache->ObjectSize = size;
- cache->ReferenceCount = 0;
- cache->ReuseList = NULL;
- cache->Blocks = NULL;
- cache->Free = 0;
- cache->Used = 0;
- cache->Max = 0;
-
- if (CacheList == NULL) {
- CacheList = cache;
- } else {
- cache->Next = CacheList;
- cache->Next->Prev = cache;
- CacheList = cache;
- CacheList->Prev = NULL;
- }
-
- return cache;
+ ers_cache_t *cache;
+
+ for (cache = CacheList; cache; cache = cache->Next)
+ if (cache->ObjectSize == size)
+ return cache;
+
+ CREATE(cache, ers_cache_t, 1);
+ cache->ObjectSize = size;
+ cache->ReferenceCount = 0;
+ cache->ReuseList = NULL;
+ cache->Blocks = NULL;
+ cache->Free = 0;
+ cache->Used = 0;
+ cache->Max = 0;
+
+ if (CacheList == NULL)
+ {
+ CacheList = cache;
+ }
+ else
+ {
+ cache->Next = CacheList;
+ cache->Next->Prev = cache;
+ CacheList = cache;
+ CacheList->Prev = NULL;
+ }
+
+ return cache;
}
static void ers_free_cache(ers_cache_t *cache, bool remove)
{
- unsigned int i;
+ unsigned int i;
- for (i = 0; i < cache->Used; i++)
- aFree(cache->Blocks[i]);
+ for (i = 0; i < cache->Used; i++)
+ aFree(cache->Blocks[i]);
- if (cache->Next)
- cache->Next->Prev = cache->Prev;
+ if (cache->Next)
+ cache->Next->Prev = cache->Prev;
- if (cache->Prev)
- cache->Prev->Next = cache->Next;
- else
- CacheList = cache->Next;
+ if (cache->Prev)
+ cache->Prev->Next = cache->Next;
+ else
+ CacheList = cache->Next;
- aFree(cache->Blocks);
- aFree(cache);
+ aFree(cache->Blocks);
+ aFree(cache);
}
static void *ers_obj_alloc_entry(ERS self)
{
- ers_instance_t *instance = (ers_instance_t *)self;
- void *ret;
-
- if (instance == NULL) {
- ShowError("ers_obj_alloc_entry: NULL object, aborting entry freeing.\n");
- return NULL;
- }
-
- if (instance->Cache->ReuseList != NULL) {
- ret = (void *)((unsigned char *)instance->Cache->ReuseList + sizeof(struct ers_list));
- instance->Cache->ReuseList = instance->Cache->ReuseList->Next;
- } else if (instance->Cache->Free > 0) {
- instance->Cache->Free--;
- ret = &instance->Cache->Blocks[instance->Cache->Used - 1][instance->Cache->Free * instance->Cache->ObjectSize + sizeof(struct ers_list)];
- } else {
- if (instance->Cache->Used == instance->Cache->Max) {
- instance->Cache->Max = (instance->Cache->Max * 4) + 3;
- RECREATE(instance->Cache->Blocks, unsigned char *, instance->Cache->Max);
- }
-
- CREATE(instance->Cache->Blocks[instance->Cache->Used], unsigned char, instance->Cache->ObjectSize * ERS_BLOCK_ENTRIES);
- instance->Cache->Used++;
-
- instance->Cache->Free = ERS_BLOCK_ENTRIES -1;
- ret = &instance->Cache->Blocks[instance->Cache->Used - 1][instance->Cache->Free * instance->Cache->ObjectSize + sizeof(struct ers_list)];
- }
-
- instance->Count++;
-
- return ret;
+ ers_instance_t *instance = (ers_instance_t *)self;
+ void *ret;
+
+ if (instance == NULL)
+ {
+ ShowError("ers_obj_alloc_entry: NULL object, aborting entry freeing.\n");
+ return NULL;
+ }
+
+ if (instance->Cache->ReuseList != NULL)
+ {
+ ret = (void *)((unsigned char *)instance->Cache->ReuseList + sizeof(struct ers_list));
+ instance->Cache->ReuseList = instance->Cache->ReuseList->Next;
+ }
+ else if (instance->Cache->Free > 0)
+ {
+ instance->Cache->Free--;
+ ret = &instance->Cache->Blocks[instance->Cache->Used - 1][instance->Cache->Free * instance->Cache->ObjectSize + sizeof(struct ers_list)];
+ }
+ else
+ {
+ if (instance->Cache->Used == instance->Cache->Max)
+ {
+ instance->Cache->Max = (instance->Cache->Max * 4) + 3;
+ RECREATE(instance->Cache->Blocks, unsigned char *, instance->Cache->Max);
+ }
+
+ CREATE(instance->Cache->Blocks[instance->Cache->Used], unsigned char, instance->Cache->ObjectSize * ERS_BLOCK_ENTRIES);
+ instance->Cache->Used++;
+
+ instance->Cache->Free = ERS_BLOCK_ENTRIES -1;
+ ret = &instance->Cache->Blocks[instance->Cache->Used - 1][instance->Cache->Free * instance->Cache->ObjectSize + sizeof(struct ers_list)];
+ }
+
+ instance->Count++;
+
+ return ret;
}
static void ers_obj_free_entry(ERS self, void *entry)
{
- ers_instance_t *instance = (ers_instance_t *)self;
- struct ers_list *reuse = (struct ers_list *)((unsigned char *)entry - sizeof(struct ers_list));
-
- if (instance == NULL) {
- ShowError("ers_obj_free_entry: NULL object, aborting entry freeing.\n");
- return;
- } else if (entry == NULL) {
- ShowError("ers_obj_free_entry: NULL entry, nothing to free.\n");
- return;
- }
-
- reuse->Next = instance->Cache->ReuseList;
- instance->Cache->ReuseList = reuse;
- instance->Count--;
+ ers_instance_t *instance = (ers_instance_t *)self;
+ struct ers_list *reuse = (struct ers_list *)((unsigned char *)entry - sizeof(struct ers_list));
+
+ if (instance == NULL)
+ {
+ ShowError("ers_obj_free_entry: NULL object, aborting entry freeing.\n");
+ return;
+ }
+ else if (entry == NULL)
+ {
+ ShowError("ers_obj_free_entry: NULL entry, nothing to free.\n");
+ return;
+ }
+
+ reuse->Next = instance->Cache->ReuseList;
+ instance->Cache->ReuseList = reuse;
+ instance->Count--;
}
static size_t ers_obj_entry_size(ERS self)
{
- ers_instance_t *instance = (ers_instance_t *)self;
+ ers_instance_t *instance = (ers_instance_t *)self;
- if (instance == NULL) {
- ShowError("ers_obj_entry_size: NULL object, aborting entry freeing.\n");
- return 0;
- }
+ if (instance == NULL)
+ {
+ ShowError("ers_obj_entry_size: NULL object, aborting entry freeing.\n");
+ return 0;
+ }
- return instance->Cache->ObjectSize;
+ return instance->Cache->ObjectSize;
}
static void ers_obj_destroy(ERS self)
{
- ers_instance_t *instance = (ers_instance_t *)self;
+ ers_instance_t *instance = (ers_instance_t *)self;
- if (instance == NULL) {
- ShowError("ers_obj_destroy: NULL object, aborting entry freeing.\n");
- return;
- }
+ if (instance == NULL)
+ {
+ ShowError("ers_obj_destroy: NULL object, aborting entry freeing.\n");
+ return;
+ }
- if (instance->Count > 0)
- if (!(instance->Options & ERS_OPT_CLEAR))
- ShowWarning("Memory leak detected at ERS '%s', %d objects not freed.\n", instance->Name, instance->Count);
+ if (instance->Count > 0)
+ if (!(instance->Options & ERS_OPT_CLEAR))
+ ShowWarning("Memory leak detected at ERS '%s', %d objects not freed.\n", instance->Name, instance->Count);
- if (--instance->Cache->ReferenceCount <= 0)
- ers_free_cache(instance->Cache, true);
+ if (--instance->Cache->ReferenceCount <= 0)
+ ers_free_cache(instance->Cache, true);
- aFree(instance);
+ aFree(instance);
}
ERS ers_new(uint32 size, char *name, enum ERSOptions options)
{
- ers_instance_t *instance;
- CREATE(instance, ers_instance_t, 1);
+ ers_instance_t *instance;
+ CREATE(instance, ers_instance_t, 1);
- size += sizeof(struct ers_list);
- if (size % ERS_ALIGNED)
- size += ERS_ALIGNED - size % ERS_ALIGNED;
+ size += sizeof(struct ers_list);
+ if (size % ERS_ALIGNED)
+ size += ERS_ALIGNED - size % ERS_ALIGNED;
- instance->VTable.alloc = ers_obj_alloc_entry;
- instance->VTable.free = ers_obj_free_entry;
- instance->VTable.entry_size = ers_obj_entry_size;
- instance->VTable.destroy = ers_obj_destroy;
+ instance->VTable.alloc = ers_obj_alloc_entry;
+ instance->VTable.free = ers_obj_free_entry;
+ instance->VTable.entry_size = ers_obj_entry_size;
+ instance->VTable.destroy = ers_obj_destroy;
- instance->Name = name;
- instance->Options = options;
+ instance->Name = name;
+ instance->Options = options;
- instance->Cache = ers_find_cache(size);
- instance->Cache->ReferenceCount++;
+ instance->Cache = ers_find_cache(size);
+ instance->Cache->ReferenceCount++;
- instance->Count = 0;
+ instance->Count = 0;
- return &instance->VTable;
+ return &instance->VTable;
}
void ers_report(void)
{
- // FIXME: Someone use this? Is it really needed?
+ // FIXME: Someone use this? Is it really needed?
}
void ers_force_destroy_all(void)
{
- ers_cache_t *cache;
-
- for (cache = CacheList; cache; cache = cache->Next)
- ers_free_cache(cache, false);
+ ers_cache_t *cache;
+
+ for (cache = CacheList; cache; cache = cache->Next)
+ ers_free_cache(cache, false);
}
#endif
diff --git a/src/common/ers.h b/src/common/ers.h
index c8fe2b4af..dc66af5ef 100644
--- a/src/common/ers.h
+++ b/src/common/ers.h
@@ -55,7 +55,7 @@
/**
* Define this to disable the Entry Reusage System.
* All code except the typedef of ERInterface will be disabled.
- * To allow a smooth transition,
+ * To allow a smooth transition,
*/
//#define DISABLE_ERS
@@ -63,16 +63,16 @@
* Entries are aligned to ERS_ALIGNED bytes in the blocks of entries.
* By default it aligns to one byte, using the "natural order" of the entries.
* This should NEVER be set to zero or less.
- * If greater than one, some memory can be wasted. This should never be needed
+ * If greater than one, some memory can be wasted. This should never be needed
* but is here just in case some aligment issues arise.
*/
#ifndef ERS_ALIGNED
-# define ERS_ALIGNED 1
+# define ERS_ALIGNED 1
#endif /* not ERS_ALIGN_ENTRY */
enum ERSOptions {
- ERS_OPT_NONE = 0,
- ERS_OPT_CLEAR = 1,/* silently clears any entries left in the manager upon destruction */
+ ERS_OPT_NONE = 0,
+ ERS_OPT_CLEAR = 1,/* silently clears any entries left in the manager upon destruction */
};
/**
@@ -84,65 +84,65 @@ enum ERSOptions {
*/
typedef struct eri {
- /**
- * Allocate an entry from this entry manager.
- * If there are reusable entries available, it reuses one instead.
- * @param self Interface of the entry manager
- * @return An entry
- */
- void *(*alloc)(struct eri *self);
-
- /**
- * Free an entry allocated from this manager.
- * WARNING: Does not check if the entry was allocated by this manager.
- * Freeing such an entry can lead to unexpected behaviour.
- * @param self Interface of the entry manager
- * @param entry Entry to be freed
- */
- void (*free)(struct eri *self, void *entry);
-
- /**
- * Return the size of the entries allocated from this manager.
- * @param self Interface of the entry manager
- * @return Size of the entries of this manager in bytes
- */
- size_t (*entry_size)(struct eri *self);
-
- /**
- * Destroy this instance of the manager.
- * The manager is actually only destroyed when all the instances are destroyed.
- * When destroying the manager a warning is shown if the manager has
- * missing/extra entries.
- * @param self Interface of the entry manager
- */
- void (*destroy)(struct eri *self);
+ /**
+ * Allocate an entry from this entry manager.
+ * If there are reusable entries available, it reuses one instead.
+ * @param self Interface of the entry manager
+ * @return An entry
+ */
+ void *(*alloc)(struct eri *self);
+
+ /**
+ * Free an entry allocated from this manager.
+ * WARNING: Does not check if the entry was allocated by this manager.
+ * Freeing such an entry can lead to unexpected behaviour.
+ * @param self Interface of the entry manager
+ * @param entry Entry to be freed
+ */
+ void (*free)(struct eri *self, void *entry);
+
+ /**
+ * Return the size of the entries allocated from this manager.
+ * @param self Interface of the entry manager
+ * @return Size of the entries of this manager in bytes
+ */
+ size_t (*entry_size)(struct eri *self);
+
+ /**
+ * Destroy this instance of the manager.
+ * The manager is actually only destroyed when all the instances are destroyed.
+ * When destroying the manager a warning is shown if the manager has
+ * missing/extra entries.
+ * @param self Interface of the entry manager
+ */
+ void (*destroy)(struct eri *self);
} *ERS;
#ifdef DISABLE_ERS
// Use memory manager to allocate/free and disable other interface functions
-# define ers_alloc(obj,type) (type *)aMalloc(sizeof(type))
-# define ers_free(obj,entry) aFree(entry)
-# define ers_entry_size(obj) (size_t)0
-# define ers_destroy(obj)
+# define ers_alloc(obj,type) (type *)aMalloc(sizeof(type))
+# define ers_free(obj,entry) aFree(entry)
+# define ers_entry_size(obj) (size_t)0
+# define ers_destroy(obj)
// Disable the public functions
-# define ers_new(size,name,options) NULL
-# define ers_report()
-# define ers_force_destroy_all()
+# define ers_new(size,name,options) NULL
+# define ers_report()
+# define ers_force_destroy_all()
#else /* not DISABLE_ERS */
-// These defines should be used to allow the code to keep working whenever
+// These defines should be used to allow the code to keep working whenever
// the system is disabled
-# define ers_alloc(obj,type) (type *)(obj)->alloc(obj)
-# define ers_free(obj,entry) (obj)->free((obj),(entry))
-# define ers_entry_size(obj) (obj)->entry_size(obj)
-# define ers_destroy(obj) (obj)->destroy(obj)
+# define ers_alloc(obj,type) (type *)(obj)->alloc(obj)
+# define ers_free(obj,entry) (obj)->free((obj),(entry))
+# define ers_entry_size(obj) (obj)->entry_size(obj)
+# define ers_destroy(obj) (obj)->destroy(obj)
/**
* Get a new instance of the manager that handles the specified entry size.
* Size has to greater than 0.
- * If the specified size is smaller than a pointer, the size of a pointer is
+ * If the specified size is smaller than a pointer, the size of a pointer is
* used instead.
- * It's also aligned to ERS_ALIGNED bytes, so the smallest multiple of
+ * It's also aligned to ERS_ALIGNED bytes, so the smallest multiple of
* ERS_ALIGNED that is greater or equal to size is what's actually used.
* @param The requested size of the entry in bytes
* @return Interface of the object
@@ -152,7 +152,7 @@ ERS ers_new(uint32 size, char *name, enum ERSOptions options);
/**
* Print a report about the current state of the Entry Reusage System.
* Shows information about the global system and each entry manager.
- * The number of entries are checked and a warning is shown if extra reusable
+ * The number of entries are checked and a warning is shown if extra reusable
* entries are found.
* The extra entries are included in the count of reusable entries.
*/
@@ -163,7 +163,7 @@ void ers_report(void);
* The system is left as if no instances or entries had ever been allocated.
* All previous entries and instances of the managers become invalid.
* The use of this is NOT recommended.
- * It should only be used in extreme situations to make shure all the memory
+ * It should only be used in extreme situations to make shure all the memory
* allocated by this system is released.
*/
void ers_force_destroy_all(void);
diff --git a/src/common/evdp.h b/src/common/evdp.h
index c9cff9e2b..bc3454686 100644
--- a/src/common/evdp.h
+++ b/src/common/evdp.h
@@ -8,27 +8,27 @@ typedef struct EVDP_DATA EVDP_DATA;
//#idef EVDP_EPOLL
#include <sys/epoll.h>
-struct EVDP_DATA {
- struct epoll_event ev_data;
- bool ev_added;
+struct EVDP_DATA{
+ struct epoll_event ev_data;
+ bool ev_added;
};
//#endif
-enum EVDP_EVENTFLAGS {
- EVDP_EVENT_IN = 1, // Incomming data
- EVDP_EVENT_OUT = 2, // Connection accepts writing.
- EVDP_EVENT_HUP = 4 // Connection Closed.
+enum EVDP_EVENTFLAGS{
+ EVDP_EVENT_IN = 1, // Incomming data
+ EVDP_EVENT_OUT = 2, // Connection accepts writing.
+ EVDP_EVENT_HUP = 4 // Connection Closed.
};
-typedef struct EVDP_EVENT {
- int32 events; // due to performance reasons, this should be the first member.
- int32 fd; // Connection Identifier
+typedef struct EVDP_EVENT{
+ int32 events; // due to performance reasons, this should be the first member.
+ int32 fd; // Connection Identifier
} EVDP_EVENT;
-/**
+/**
* Network Event Dispatcher Initialization / Finalization routines
*/
void evdp_init();
@@ -38,56 +38,56 @@ void evdp_final();
/**
* Will Wait for events.
*
- * @param *out_ev pointer to array in size at least of max_events.
- * @param max_events max no of events to report with this call (coalesc)
- * @param timeout_ticks max time to wait in ticks (milliseconds)
+ * @param *out_ev pointer to array in size at least of max_events.
+ * @param max_events max no of events to report with this call (coalesc)
+ * @param timeout_ticks max time to wait in ticks (milliseconds)
*
* @Note:
- * The function will block until an event has occured on one of the monitored connections
- * or the timeout of timeout_ticks has passed by.
- * Upon successfull call (changed connections) this function will write the connection
- * Identifier & event to the out_fds array.
+ * The function will block until an event has occured on one of the monitored connections
+ * or the timeout of timeout_ticks has passed by.
+ * Upon successfull call (changed connections) this function will write the connection
+ * Identifier & event to the out_fds array.
*
- * @return 0 -> Timeout, > 0 no of changed connections.
+ * @return 0 -> Timeout, > 0 no of changed connections.
*/
-int32 evdp_wait(EVDP_EVENT *out_fds, int32 max_events, int32 timeout_ticks);
+int32 evdp_wait(EVDP_EVENT *out_fds, int32 max_events, int32 timeout_ticks);
-/**
+/**
* Applys the given mask on the given connection.
- *
- * @param fd connection identifier
- * @param *ep event data pointer for the connection
- * @param mask new event mask we're monitoring for.
+ *
+ * @param fd connection identifier
+ * @param *ep event data pointer for the connection
+ * @param mask new event mask we're monitoring for.
*/
-//void evdp_apply(int32 fd, EVDP_DATA *ep, int32 mask);
+//void evdp_apply(int32 fd, EVDP_DATA *ep, int32 mask);
-/**
+/**
* Adds a connection (listner) to the event notification system.
*
- * @param fd connection identifier
- * @param *ep event data pointer for the connection
+ * @param fd connection identifier
+ * @param *ep event data pointer for the connection
*
- * @note:
- * Listener type sockets are edge triggered, (see epoll manual for more information)
+ * @note:
+ * Listener type sockets are edge triggered, (see epoll manual for more information)
* - This basicaly means that youll receive one event, adn you have to accept until accept returns an error (nothing to accept)
*
* MONITORS by default: IN
- *
+ *
* @return success indicator.
- */
+ */
bool evdp_addlistener(int32 fd, EVDP_DATA *ep);
/**
* Adds a connection (client connectioN) to the event notification system
*
- * @param fd connection identifier
- * @param *ep event data pointr for the connection
- *
+ * @param fd connection identifier
+ * @param *ep event data pointr for the connection
+ *
* @note:
- *
- * MONITORS by default: IN, HUP
+ *
+ * MONITORS by default: IN, HUP
*
* @return success indicator.
*/
@@ -96,17 +96,17 @@ bool evdp_addclient(int32 fd, EVDP_DATA *ep);
/**
* Adds a connection (pending / outgoing connection!) to the event notification system.
*
- * @param fd connection identifier
- * @param *ep event data pointer for the conneciton.
+ * @param fd connection identifier
+ * @param *ep event data pointer for the conneciton.
*
* @note:
- * Outgoing connection type sockets are getting monitored for connection established
- * successfull
- * - if the connection has been established - we're generitng a writable notification .. (send)
- * this is typical for BSD / posix conform network stacks.
- * - Additinionally its edge triggered.
+ * Outgoing connection type sockets are getting monitored for connection established
+ * successfull
+ * - if the connection has been established - we're generitng a writable notification .. (send)
+ * this is typical for BSD / posix conform network stacks.
+ * - Additinionally its edge triggered.
*
- * @see evdp_outgoingconnection_established
+ * @see evdp_outgoingconnection_established
*
*
* @return success indicator
@@ -114,14 +114,14 @@ bool evdp_addclient(int32 fd, EVDP_DATA *ep);
bool evdp_addconnecting(int32 fd, EVDP_DATA *ep);
/**
- * Adds an outgoing connection to the normal event notification system after it has been successfully established.
- *
- * @param fd connection identifier
- * @param *ep event data pointer for the conneciton.
-
- * @note
- * after this call, its handled like a normal "client" connection (incomming)
- *
+ * Adds an outgoing connection to the normal event notification system after it has been successfully established.
+ *
+ * @param fd connection identifier
+ * @param *ep event data pointer for the conneciton.
+
+ * @note
+ * after this call, its handled like a normal "client" connection (incomming)
+ *
* @rturn success indicator
*/
bool evdp_outgoingconnection_established(int32 fd, EVDP_DATA *ep);
@@ -129,24 +129,24 @@ bool evdp_outgoingconnection_established(int32 fd, EVDP_DATA *ep);
/**
* Marks a connection to be monitored for writable.
*
- * @param fd connection identifier
- * @param *ep event data pointer for the connection
+ * @param fd connection identifier
+ * @param *ep event data pointer for the connection
*
* @note:
- * the connection must be already added (as client or listener)
- *
+ * the connection must be already added (as client or listener)
+ *
*
* @return sucess indicator
*/
bool evdp_writable_add(int32 fd, EVDP_DATA *ep);
-/**
+/**
* Removes the connection from writable notification monitoring
*
- * @param fd connection identifier
- * @param *ep event data pointr for the connection
+ * @param fd connection identifier
+ * @param *ep event data pointr for the connection
*
- */
+ */
void evdp_writable_remove(int32 fd, EVDP_DATA *ep);
/**
@@ -157,11 +157,11 @@ void evdp_writable_remove(int32 fd, EVDP_DATA *ep);
*
*
* @note:
- * this will also clear the given EVENT_DATA block
- * so the connection slot is in an "initial" blank status / ready to get reused.
+ * this will also clear the given EVENT_DATA block
+ * so the connection slot is in an "initial" blank status / ready to get reused.
*
*/
-void evdp_remove(int32 fd, EVDP_DATA *ep);
+void evdp_remove(int32 fd, EVDP_DATA *ep);
diff --git a/src/common/evdp_epoll.c b/src/common/evdp_epoll.c
index 9f7c3d8ea..0357dfc66 100644
--- a/src/common/evdp_epoll.c
+++ b/src/common/evdp_epoll.c
@@ -1,5 +1,5 @@
//
-// Event Dispatcher Abstraction for EPOLL
+// Event Dispatcher Abstraction for EPOLL
//
// Author: Florian Wilkemeyer <fw@f-ws.de>
//
@@ -23,220 +23,210 @@
#include "../common/evdp.h"
-#define EPOLL_MAX_PER_CYCLE 10 // Max Events to coalesc. per cycle.
+#define EPOLL_MAX_PER_CYCLE 10 // Max Events to coalesc. per cycle.
static int epoll_fd = -1;
-void evdp_init()
-{
-
- epoll_fd = epoll_create(EPOLL_MAX_PER_CYCLE);
- if (epoll_fd == -1) {
- ShowFatalError("evdp [EPOLL]: Cannot create event dispatcher (errno: %u / %s)\n", errno, strerror(errno));
- exit(1);
- }
-
+void evdp_init(){
+
+ epoll_fd = epoll_create( EPOLL_MAX_PER_CYCLE );
+ if(epoll_fd == -1){
+ ShowFatalError("evdp [EPOLL]: Cannot create event dispatcher (errno: %u / %s)\n", errno, strerror(errno) );
+ exit(1);
+ }
+
}//end: evdp_init()
-void evdp_final()
-{
-
- if (epoll_fd != -1) {
- close(epoll_fd);
- epoll_fd = -1;
- }
-
+void evdp_final(){
+
+ if(epoll_fd != -1){
+ close(epoll_fd);
+ epoll_fd = -1;
+ }
+
}//end: evdp_final()
-int32 evdp_wait(EVDP_EVENT *out_fds, int32 max_events, int32 timeout_ticks)
-{
- struct epoll_event l_events[EPOLL_MAX_PER_CYCLE];
- register struct epoll_event *ev;
- register int nfds, n;
-
- if (max_events > EPOLL_MAX_PER_CYCLE)
- max_events = EPOLL_MAX_PER_CYCLE;
-
- nfds = epoll_wait(epoll_fd, l_events, max_events, timeout_ticks);
- if (nfds == -1) {
- // @TODO: check if core is in shutdown mode. if - ignroe error.
-
- ShowFatalError("evdp [EPOLL]: epoll_wait returned bad / unexpected status (errno: %u / %s)\n", errno, strerror(errno));
- exit(1); //..
- }
-
- // Loop thru all events and copy it to the local ra evdp_event.. struct.
- for (n = 0; n < nfds; n++) {
- ev = &l_events[n];
-
- out_fds->fd = ev->data.fd;
- out_fds->events = 0; // clear
-
- if (ev->events & EPOLLHUP)
- out_fds->events |= EVDP_EVENT_HUP;
-
- if (ev->events & EPOLLIN)
- out_fds->events |= EVDP_EVENT_IN;
-
- if (ev->events & EPOLLOUT)
- out_fds->events |= EVDP_EVENT_OUT;
-
- out_fds++;
- }
-
- return nfds; // 0 on timeout or > 0 ..
+int32 evdp_wait(EVDP_EVENT *out_fds, int32 max_events, int32 timeout_ticks){
+ struct epoll_event l_events[EPOLL_MAX_PER_CYCLE];
+ register struct epoll_event *ev;
+ register int nfds, n;
+
+ if(max_events > EPOLL_MAX_PER_CYCLE)
+ max_events = EPOLL_MAX_PER_CYCLE;
+
+ nfds = epoll_wait( epoll_fd, l_events, max_events, timeout_ticks);
+ if(nfds == -1){
+ // @TODO: check if core is in shutdown mode. if - ignroe error.
+
+ ShowFatalError("evdp [EPOLL]: epoll_wait returned bad / unexpected status (errno: %u / %s)\n", errno, strerror(errno));
+ exit(1); //..
+ }
+
+ // Loop thru all events and copy it to the local ra evdp_event.. struct.
+ for(n = 0; n < nfds; n++){
+ ev = &l_events[n];
+
+ out_fds->fd = ev->data.fd;
+ out_fds->events = 0; // clear
+
+ if(ev->events & EPOLLHUP)
+ out_fds->events |= EVDP_EVENT_HUP;
+
+ if(ev->events & EPOLLIN)
+ out_fds->events |= EVDP_EVENT_IN;
+
+ if(ev->events & EPOLLOUT)
+ out_fds->events |= EVDP_EVENT_OUT;
+
+ out_fds++;
+ }
+
+ return nfds; // 0 on timeout or > 0 ..
}//end: evdp_wait()
-void evdp_remove(int32 fd, EVDP_DATA *ep)
-{
-
- if (ep->ev_added == true) {
-
- if (epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, &ep->ev_data) != 0) {
- ShowError("evdp [EPOLL]: evdp_remove - epoll_ctl (EPOLL_CTL_DEL) failed! fd #%u (errno %u / %s)\n", fd, errno, strerror(errno));
- }
-
- ep->ev_data.events = 0; // clear struct.
- ep->ev_data.data.fd = -1; // .. clear struct ..
-
- ep->ev_added = false; // not added!
- }
+void evdp_remove(int32 fd, EVDP_DATA *ep){
+
+ if(ep->ev_added == true){
+
+ if( epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, &ep->ev_data) != 0){
+ ShowError("evdp [EPOLL]: evdp_remove - epoll_ctl (EPOLL_CTL_DEL) failed! fd #%u (errno %u / %s)\n", fd, errno, strerror(errno));
+ }
+
+ ep->ev_data.events = 0; // clear struct.
+ ep->ev_data.data.fd = -1; // .. clear struct ..
+ ep->ev_added = false; // not added!
+ }
+
}//end: evdp_remove()
-bool evdp_addlistener(int32 fd, EVDP_DATA *ep)
-{
-
- ep->ev_data.events = EPOLLET|EPOLLIN;
- ep->ev_data.data.fd = fd;
-
- // No check here for 'added ?'
- // listeners cannot be added twice.
- //
- if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ep->ev_data) != 0) {
- ShowError("evdp [EPOLL]: evdp_addlistener - epoll_ctl (EPOLL_CTL_ADD) faield! fd #%u (errno %u / %s)\n", fd, errno, strerror(errno));
- ep->ev_data.events = 0;
- ep->ev_data.data.fd = -1;
- return false;
- }
-
- ep->ev_added = true;
-
- return true;
+bool evdp_addlistener(int32 fd, EVDP_DATA *ep){
+
+ ep->ev_data.events = EPOLLET|EPOLLIN;
+ ep->ev_data.data.fd = fd;
+
+ // No check here for 'added ?'
+ // listeners cannot be added twice.
+ //
+ if( epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ep->ev_data) != 0 ){
+ ShowError("evdp [EPOLL]: evdp_addlistener - epoll_ctl (EPOLL_CTL_ADD) faield! fd #%u (errno %u / %s)\n", fd, errno, strerror(errno));
+ ep->ev_data.events = 0;
+ ep->ev_data.data.fd = -1;
+ return false;
+ }
+
+ ep->ev_added = true;
+
+ return true;
}//end: evdp_addlistener()
-bool evdp_addclient(int32 fd, EVDP_DATA *ep)
-{
-
- ep->ev_data.events = EPOLLIN | EPOLLHUP;
- ep->ev_data.data.fd = fd;
-
- // No check for "added?" here,
- // this function only gets called upon accpept.
- //
-
- if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ep->ev_data) != 0) {
- ShowError("evdp [EPOLL]: evdp_addclient - epoll_ctl (EPOLL_CTL_ADD) failed! fd #%u (errno %u / %s)\n", fd, errno, strerror(errno));
- ep->ev_data.events = 0;
- ep->ev_data.data.fd = -1;
- return false;
- }
-
- ep->ev_added = true;
-
- return true;
+bool evdp_addclient(int32 fd, EVDP_DATA *ep){
+
+ ep->ev_data.events = EPOLLIN | EPOLLHUP;
+ ep->ev_data.data.fd = fd;
+
+ // No check for "added?" here,
+ // this function only gets called upon accpept.
+ //
+
+ if( epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ep->ev_data) != 0){
+ ShowError("evdp [EPOLL]: evdp_addclient - epoll_ctl (EPOLL_CTL_ADD) failed! fd #%u (errno %u / %s)\n", fd, errno, strerror(errno));
+ ep->ev_data.events = 0;
+ ep->ev_data.data.fd = -1;
+ return false;
+ }
+
+ ep->ev_added = true;
+
+ return true;
}//end: evdp_addclient()
-bool evdp_addconnecting(int32 fd, EVDP_DATA *ep)
-{
-
- ep->ev_data.events = EPOLLET | EPOLLOUT | EPOLLHUP;
- ep->ev_data.data.fd = fd;
-
- if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ep->ev_data) != 0) {
- ShowError("evdp [EPOLL]: evdp_addconnecting - epoll_ctl (EPOLL_CTL_ADD) failed! fd #%u (errno %u / %s)\n", fd, errno, strerror(errno));
- ep->ev_data.events = 0;
- ep->ev_data.data.fd = -1;
- }
-
- ep->ev_added = true;
-
- return true;
+bool evdp_addconnecting(int32 fd, EVDP_DATA *ep){
+
+ ep->ev_data.events = EPOLLET | EPOLLOUT | EPOLLHUP;
+ ep->ev_data.data.fd = fd;
+
+ if( epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ep->ev_data) != 0){
+ ShowError("evdp [EPOLL]: evdp_addconnecting - epoll_ctl (EPOLL_CTL_ADD) failed! fd #%u (errno %u / %s)\n", fd, errno, strerror(errno));
+ ep->ev_data.events = 0;
+ ep->ev_data.data.fd = -1;
+ }
+
+ ep->ev_added = true;
+
+ return true;
}//end: evdp_addconnecting()
-bool evdp_outgoingconnection_established(int32 fd, EVDP_DATA *ep)
-{
- int32 saved_mask;
-
- if (ep->ev_added != true) {
- // !
- ShowError("evdp [EPOLL]: evdp_outgoingconnection_established fd #%u is not added to event dispatcher! invalid call.\n", fd);
- return false;
- }
-
- saved_mask = ep->ev_data.events;
-
- ep->ev_data.events = EPOLLIN | EPOLLHUP;
-
- if (epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fd, &ep->ev_data) != 0) {
- ep->ev_data.events = saved_mask; // restore old mask.
- ShowError("evdp [EPOLL]: evdp_outgoingconnection_established - epoll_ctl (EPOLL_CTL_MOD) failed! fd #%u (errno %u / %s)\n", fd, errno, strerror(errno));
- return false;
- }
-
- return true;
+bool evdp_outgoingconnection_established(int32 fd, EVDP_DATA *ep){
+ int32 saved_mask;
+
+ if(ep->ev_added != true){
+ // !
+ ShowError("evdp [EPOLL]: evdp_outgoingconnection_established fd #%u is not added to event dispatcher! invalid call.\n", fd);
+ return false;
+ }
+
+ saved_mask = ep->ev_data.events;
+
+ ep->ev_data.events = EPOLLIN | EPOLLHUP;
+
+ if( epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fd, &ep->ev_data) != 0){
+ ep->ev_data.events = saved_mask; // restore old mask.
+ ShowError("evdp [EPOLL]: evdp_outgoingconnection_established - epoll_ctl (EPOLL_CTL_MOD) failed! fd #%u (errno %u / %s)\n", fd, errno, strerror(errno));
+ return false;
+ }
+
+ return true;
}//end: evdp_outgoingconnection_established()
-bool evdp_writable_add(int32 fd, EVDP_DATA *ep)
-{
-
- if (ep->ev_added != true) {
- ShowError("evdp [EPOLL]: evdp_writable_add - tried to add not added fd #%u\n",fd);
- return false;
- }
-
- if (!(ep->ev_data.events & EPOLLOUT)) { //
-
- ep->ev_data.events |= EPOLLOUT;
- if (epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fd, &ep->ev_data) != 0) {
- ShowError("evdp [EPOLL]: evdp_writable_add - epoll_ctl (EPOLL_CTL_MOD) failed! fd #%u (errno: %u / %s)\n", fd, errno, strerror(errno));
- ep->ev_data.events &= ~EPOLLOUT; // remove from local flagmask due to failed syscall.
- return false;
- }
- }
-
- return true;
+bool evdp_writable_add(int32 fd, EVDP_DATA *ep){
+
+ if(ep->ev_added != true){
+ ShowError("evdp [EPOLL]: evdp_writable_add - tried to add not added fd #%u\n",fd);
+ return false;
+ }
+
+ if(! (ep->ev_data.events & EPOLLOUT) ){ //
+
+ ep->ev_data.events |= EPOLLOUT;
+ if( epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fd, &ep->ev_data) != 0 ){
+ ShowError("evdp [EPOLL]: evdp_writable_add - epoll_ctl (EPOLL_CTL_MOD) failed! fd #%u (errno: %u / %s)\n", fd, errno, strerror(errno));
+ ep->ev_data.events &= ~EPOLLOUT; // remove from local flagmask due to failed syscall.
+ return false;
+ }
+ }
+
+ return true;
}//end: evdp_writable_add()
-void evdp_writable_remove(int32 fd, EVDP_DATA *ep)
-{
-
- if (ep->ev_added != true) {
- ShowError("evdp [EPOLL]: evdp_writable_remove - tried to remove not added fd #%u\n", fd);
- return;
- }
-
- if (ep->ev_data.events & EPOLLOUT) {
-
- ep->ev_data.events &= ~EPOLLOUT;
- if (epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fd, &ep->ev_data) != 0) {
- ShowError("evdp [EPOLL]: evdp_writable_remove - epoll_ctl (EPOLL_CTL_MOD) failed! fd #%u (errno %u / %s)\n", fd, errno, strerror(errno));
- ep->ev_data.events |= EPOLLOUT; // add back to local flagmask because of failed syscall.
- return;
- }
- }
-
- return;
+void evdp_writable_remove(int32 fd, EVDP_DATA *ep){
+
+ if(ep->ev_added != true){
+ ShowError("evdp [EPOLL]: evdp_writable_remove - tried to remove not added fd #%u\n", fd);
+ return;
+ }
+
+ if( ep->ev_data.events & EPOLLOUT ){
+
+ ep->ev_data.events &= ~EPOLLOUT;
+ if( epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fd, &ep->ev_data) != 0){
+ ShowError("evdp [EPOLL]: evdp_writable_remove - epoll_ctl (EPOLL_CTL_MOD) failed! fd #%u (errno %u / %s)\n", fd, errno, strerror(errno));
+ ep->ev_data.events |= EPOLLOUT; // add back to local flagmask because of failed syscall.
+ return;
+ }
+ }
+
+ return;
}//end: evdp_writable_remove()
diff --git a/src/common/grfio.c b/src/common/grfio.c
index f86f9c1cb..8f430cfb9 100644
--- a/src/common/grfio.c
+++ b/src/common/grfio.c
@@ -16,18 +16,18 @@
#include <zlib.h>
//----------------------------
-// file entry table struct
+// file entry table struct
//----------------------------
typedef struct _FILELIST {
- int srclen; // compressed size
- int srclen_aligned;
- int declen; // original size
- int srcpos; // position of entry in grf
- int next; // index of next filelist entry with same hash (-1: end of entry chain)
- char type;
- char fn[128-4*5]; // file name
- char *fnd; // if the file was cloned, contains name of original file
- char gentry; // read grf file select
+ int srclen; // compressed size
+ int srclen_aligned;
+ int declen; // original size
+ int srcpos; // position of entry in grf
+ int next; // index of next filelist entry with same hash (-1: end of entry chain)
+ char type;
+ char fn[128-4*5]; // file name
+ char* fnd; // if the file was cloned, contains name of original file
+ char gentry; // read grf file select
} FILELIST;
#define FILELIST_TYPE_FILE 0x01 // entry is a file
@@ -45,33 +45,34 @@ typedef struct _FILELIST {
// stores info about every loaded file
-FILELIST *filelist = NULL;
-int filelist_entrys = 0;
-int filelist_maxentry = 0;
+FILELIST* filelist = NULL;
+int filelist_entrys = 0;
+int filelist_maxentry = 0;
// stores grf file names
-char **gentry_table = NULL;
-int gentry_entrys = 0;
-int gentry_maxentry = 0;
+char** gentry_table = NULL;
+int gentry_entrys = 0;
+int gentry_maxentry = 0;
// the path to the data directory
char data_dir[1024] = "";
// little endian char array to uint conversion
-static unsigned int getlong(unsigned char *p)
+static unsigned int getlong(unsigned char* p)
{
- return (p[0] << 0 | p[1] << 8 | p[2] << 16 | p[3] << 24);
+ return (p[0] << 0 | p[1] << 8 | p[2] << 16 | p[3] << 24);
}
-static void NibbleSwap(unsigned char *src, int len)
+static void NibbleSwap(unsigned char* src, int len)
{
- while (len > 0) {
- *src = (*src >> 4) | (*src << 4);
- ++src;
- --len;
- }
+ while( len > 0 )
+ {
+ *src = (*src >> 4) | (*src << 4);
+ ++src;
+ --len;
+ }
}
@@ -79,142 +80,114 @@ static void NibbleSwap(unsigned char *src, int len)
/// NOTE: Operation is symmetric (calling it twice gives back the original input).
static uint8_t grf_substitution(uint8_t in)
{
- uint8_t out;
-
- switch (in) {
- case 0x00:
- out = 0x2B;
- break;
- case 0x2B:
- out = 0x00;
- break;
- case 0x6C:
- out = 0x80;
- break;
- case 0x01:
- out = 0x68;
- break;
- case 0x68:
- out = 0x01;
- break;
- case 0x48:
- out = 0x77;
- break;
- case 0x60:
- out = 0xFF;
- break;
- case 0x77:
- out = 0x48;
- break;
- case 0xB9:
- out = 0xC0;
- break;
- case 0xC0:
- out = 0xB9;
- break;
- case 0xFE:
- out = 0xEB;
- break;
- case 0xEB:
- out = 0xFE;
- break;
- case 0x80:
- out = 0x6C;
- break;
- case 0xFF:
- out = 0x60;
- break;
- default:
- out = in;
- break;
- }
-
- return out;
+ uint8_t out;
+
+ switch( in )
+ {
+ case 0x00: out = 0x2B; break;
+ case 0x2B: out = 0x00; break;
+ case 0x6C: out = 0x80; break;
+ case 0x01: out = 0x68; break;
+ case 0x68: out = 0x01; break;
+ case 0x48: out = 0x77; break;
+ case 0x60: out = 0xFF; break;
+ case 0x77: out = 0x48; break;
+ case 0xB9: out = 0xC0; break;
+ case 0xC0: out = 0xB9; break;
+ case 0xFE: out = 0xEB; break;
+ case 0xEB: out = 0xFE; break;
+ case 0x80: out = 0x6C; break;
+ case 0xFF: out = 0x60; break;
+ default: out = in; break;
+ }
+
+ return out;
}
/* this is not used anywhere, is it ok to delete? */
//static void grf_shuffle_enc(BIT64* src) {
-// BIT64 out;
+// BIT64 out;
//
-// out.b[0] = src->b[3];
-// out.b[1] = src->b[4];
-// out.b[2] = src->b[5];
-// out.b[3] = src->b[0];
-// out.b[4] = src->b[1];
-// out.b[5] = src->b[6];
-// out.b[6] = src->b[2];
-// out.b[7] = grf_substitution(src->b[7]);
+// out.b[0] = src->b[3];
+// out.b[1] = src->b[4];
+// out.b[2] = src->b[5];
+// out.b[3] = src->b[0];
+// out.b[4] = src->b[1];
+// out.b[5] = src->b[6];
+// out.b[6] = src->b[2];
+// out.b[7] = grf_substitution(src->b[7]);
//
-// *src = out;
+// *src = out;
//}
-static void grf_shuffle_dec(BIT64 *src)
+static void grf_shuffle_dec(BIT64* src)
{
- BIT64 out;
-
- out.b[0] = src->b[3];
- out.b[1] = src->b[4];
- out.b[2] = src->b[6];
- out.b[3] = src->b[0];
- out.b[4] = src->b[1];
- out.b[5] = src->b[2];
- out.b[6] = src->b[5];
- out.b[7] = grf_substitution(src->b[7]);
-
- *src = out;
+ BIT64 out;
+
+ out.b[0] = src->b[3];
+ out.b[1] = src->b[4];
+ out.b[2] = src->b[6];
+ out.b[3] = src->b[0];
+ out.b[4] = src->b[1];
+ out.b[5] = src->b[2];
+ out.b[6] = src->b[5];
+ out.b[7] = grf_substitution(src->b[7]);
+
+ *src = out;
}
-static void grf_decode_header(unsigned char *buf, size_t len)
+static void grf_decode_header(unsigned char* buf, size_t len)
{
- BIT64 *p = (BIT64 *)buf;
- size_t nblocks = len / sizeof(BIT64);
- size_t i;
+ BIT64* p = (BIT64*)buf;
+ size_t nblocks = len / sizeof(BIT64);
+ size_t i;
- // first 20 blocks are all des-encrypted
- for (i = 0; i < 20 && i < nblocks; ++i)
- des_decrypt_block(&p[i]);
+ // first 20 blocks are all des-encrypted
+ for( i = 0; i < 20 && i < nblocks; ++i )
+ des_decrypt_block(&p[i]);
- // the rest is plaintext, done.
+ // the rest is plaintext, done.
}
-static void grf_decode_full(unsigned char *buf, size_t len, int cycle)
+static void grf_decode_full(unsigned char* buf, size_t len, int cycle)
{
- BIT64 *p = (BIT64 *)buf;
- size_t nblocks = len / sizeof(BIT64);
- int dcycle, scycle;
- size_t i, j;
-
- // first 20 blocks are all des-encrypted
- for (i = 0; i < 20 && i < nblocks; ++i)
- des_decrypt_block(&p[i]);
-
- // after that only one of every 'dcycle' blocks is des-encrypted
- dcycle = cycle;
-
- // and one of every 'scycle' plaintext blocks is shuffled (starting from the 0th but skipping the 0th)
- scycle = 7;
-
- // so decrypt/de-shuffle periodically
- j = -1; // 0, adjusted to fit the ++j step
- for (i = 20; i < nblocks; ++i) {
- if (i % dcycle == 0) {
- // decrypt block
- des_decrypt_block(&p[i]);
- continue;
- }
-
- ++j;
- if (j % scycle == 0 && j != 0) {
- // de-shuffle block
- grf_shuffle_dec(&p[i]);
- continue;
- }
-
- // plaintext, do nothing.
- }
+ BIT64* p = (BIT64*)buf;
+ size_t nblocks = len / sizeof(BIT64);
+ int dcycle, scycle;
+ size_t i, j;
+
+ // first 20 blocks are all des-encrypted
+ for( i = 0; i < 20 && i < nblocks; ++i )
+ des_decrypt_block(&p[i]);
+
+ // after that only one of every 'dcycle' blocks is des-encrypted
+ dcycle = cycle;
+
+ // and one of every 'scycle' plaintext blocks is shuffled (starting from the 0th but skipping the 0th)
+ scycle = 7;
+
+ // so decrypt/de-shuffle periodically
+ j = -1; // 0, adjusted to fit the ++j step
+ for( i = 20; i < nblocks; ++i )
+ {
+ if( i % dcycle == 0 )
+ {// decrypt block
+ des_decrypt_block(&p[i]);
+ continue;
+ }
+
+ ++j;
+ if( j % scycle == 0 && j != 0 )
+ {// de-shuffle block
+ grf_shuffle_dec(&p[i]);
+ continue;
+ }
+
+ // plaintext, do nothing.
+ }
}
@@ -223,35 +196,38 @@ static void grf_decode_full(unsigned char *buf, size_t len, int cycle)
/// @param len length of the data
/// @param entry_type flags associated with the data
/// @param entry_len true (unaligned) length of the data
-static void grf_decode(unsigned char *buf, size_t len, char entry_type, int entry_len)
+static void grf_decode(unsigned char* buf, size_t len, char entry_type, int entry_len)
{
- if (entry_type & FILELIST_TYPE_ENCRYPT_MIXED) {
- // fully encrypted
- int digits;
- int cycle;
- int i;
-
- // compute number of digits of the entry length
- digits = 1;
- for (i = 10; i <= entry_len; i *= 10)
- ++digits;
-
- // choose size of gap between two encrypted blocks
- // digits: 0 1 2 3 4 5 6 7 8 9 ...
- // cycle: 1 1 1 4 5 14 15 22 23 24 ...
- cycle = (digits < 3) ? 1
- : (digits < 5) ? digits + 1
- : (digits < 7) ? digits + 9
- : digits + 15;
-
- grf_decode_full(buf, len, cycle);
- } else if (entry_type & FILELIST_TYPE_ENCRYPT_HEADER) {
- // header encrypted
- grf_decode_header(buf, len);
- } else {
- // plaintext
- ;
- }
+ if( entry_type & FILELIST_TYPE_ENCRYPT_MIXED )
+ {// fully encrypted
+ int digits;
+ int cycle;
+ int i;
+
+ // compute number of digits of the entry length
+ digits = 1;
+ for( i = 10; i <= entry_len; i *= 10 )
+ ++digits;
+
+ // choose size of gap between two encrypted blocks
+ // digits: 0 1 2 3 4 5 6 7 8 9 ...
+ // cycle: 1 1 1 4 5 14 15 22 23 24 ...
+ cycle = ( digits < 3 ) ? 1
+ : ( digits < 5 ) ? digits + 1
+ : ( digits < 7 ) ? digits + 9
+ : digits + 15;
+
+ grf_decode_full(buf, len, cycle);
+ }
+ else
+ if( entry_type & FILELIST_TYPE_ENCRYPT_HEADER )
+ {// header encrypted
+ grf_decode_header(buf, len);
+ }
+ else
+ {// plaintext
+ ;
+ }
}
@@ -260,23 +236,23 @@ static void grf_decode(unsigned char *buf, size_t len, char entry_type, int entr
******************************************************/
/// zlib crc32
-unsigned long grfio_crc32(const unsigned char *buf, unsigned int len)
+unsigned long grfio_crc32(const unsigned char* buf, unsigned int len)
{
- return crc32(crc32(0L, Z_NULL, 0), buf, len);
+ return crc32(crc32(0L, Z_NULL, 0), buf, len);
}
/// zlib uncompress
-int decode_zip(void *dest, unsigned long *destLen, const void *source, unsigned long sourceLen)
+int decode_zip(void* dest, unsigned long* destLen, const void* source, unsigned long sourceLen)
{
- return uncompress((Bytef *)dest, destLen, (const Bytef *)source, sourceLen);
+ return uncompress((Bytef*)dest, destLen, (const Bytef*)source, sourceLen);
}
/// zlib compress
-int encode_zip(void *dest, unsigned long *destLen, const void *source, unsigned long sourceLen)
+int encode_zip(void* dest, unsigned long* destLen, const void* source, unsigned long sourceLen)
{
- return compress((Bytef *)dest, destLen, (const Bytef *)source, sourceLen);
+ return compress((Bytef*)dest, destLen, (const Bytef*)source, sourceLen);
}
@@ -289,94 +265,94 @@ int filelist_hash[256];
// initializes the table that holds the first elements of all hash chains
static void hashinit(void)
{
- int i;
- for (i = 0; i < 256; i++)
- filelist_hash[i] = -1;
+ int i;
+ for (i = 0; i < 256; i++)
+ filelist_hash[i] = -1;
}
// hashes a filename string into a number from {0..255}
-static int filehash(const char *fname)
+static int filehash(const char* fname)
{
- unsigned int hash = 0;
- while (*fname) {
- hash = (hash<<1) + (hash>>7)*9 + TOLOWER(*fname);
- fname++;
- }
- return hash & 255;
+ unsigned int hash = 0;
+ while(*fname) {
+ hash = (hash<<1) + (hash>>7)*9 + TOLOWER(*fname);
+ fname++;
+ }
+ return hash & 255;
}
// finds a FILELIST entry with the specified file name
-static FILELIST *filelist_find(const char *fname)
+static FILELIST* filelist_find(const char* fname)
{
- int hash, index;
+ int hash, index;
- if (!filelist)
- return NULL;
+ if (!filelist)
+ return NULL;
- hash = filelist_hash[filehash(fname)];
- for (index = hash; index != -1; index = filelist[index].next)
- if (!strcmpi(filelist[index].fn, fname))
- break;
+ hash = filelist_hash[filehash(fname)];
+ for (index = hash; index != -1; index = filelist[index].next)
+ if(!strcmpi(filelist[index].fn, fname))
+ break;
- return (index >= 0) ? &filelist[index] : NULL;
+ return (index >= 0) ? &filelist[index] : NULL;
}
// returns the original file name
-char *grfio_find_file(const char *fname)
+char* grfio_find_file(const char* fname)
{
- FILELIST *filelist = filelist_find(fname);
- if (!filelist) return NULL;
- return (!filelist->fnd ? filelist->fn : filelist->fnd);
+ FILELIST *filelist = filelist_find(fname);
+ if (!filelist) return NULL;
+ return (!filelist->fnd ? filelist->fn : filelist->fnd);
}
// adds a FILELIST entry into the list of loaded files
-static FILELIST *filelist_add(FILELIST *entry)
+static FILELIST* filelist_add(FILELIST* entry)
{
- int hash;
+ int hash;
-#define FILELIST_ADDS 1024 // number increment of file lists `
+ #define FILELIST_ADDS 1024 // number increment of file lists `
- if (filelist_entrys >= filelist_maxentry) {
- filelist = (FILELIST *)aRealloc(filelist, (filelist_maxentry + FILELIST_ADDS) * sizeof(FILELIST));
- memset(filelist + filelist_maxentry, '\0', FILELIST_ADDS * sizeof(FILELIST));
- filelist_maxentry += FILELIST_ADDS;
- }
+ if (filelist_entrys >= filelist_maxentry) {
+ filelist = (FILELIST *)aRealloc(filelist, (filelist_maxentry + FILELIST_ADDS) * sizeof(FILELIST));
+ memset(filelist + filelist_maxentry, '\0', FILELIST_ADDS * sizeof(FILELIST));
+ filelist_maxentry += FILELIST_ADDS;
+ }
- memcpy(&filelist[filelist_entrys], entry, sizeof(FILELIST));
+ memcpy (&filelist[filelist_entrys], entry, sizeof(FILELIST));
- hash = filehash(entry->fn);
- filelist[filelist_entrys].next = filelist_hash[hash];
- filelist_hash[hash] = filelist_entrys;
+ hash = filehash(entry->fn);
+ filelist[filelist_entrys].next = filelist_hash[hash];
+ filelist_hash[hash] = filelist_entrys;
- filelist_entrys++;
+ filelist_entrys++;
- return &filelist[filelist_entrys - 1];
+ return &filelist[filelist_entrys - 1];
}
// adds a new FILELIST entry or overwrites an existing one
-static FILELIST *filelist_modify(FILELIST *entry)
+static FILELIST* filelist_modify(FILELIST* entry)
{
- FILELIST *fentry = filelist_find(entry->fn);
- if (fentry != NULL) {
- int tmp = fentry->next;
- memcpy(fentry, entry, sizeof(FILELIST));
- fentry->next = tmp;
- } else {
- fentry = filelist_add(entry);
- }
- return fentry;
+ FILELIST* fentry = filelist_find(entry->fn);
+ if (fentry != NULL) {
+ int tmp = fentry->next;
+ memcpy(fentry, entry, sizeof(FILELIST));
+ fentry->next = tmp;
+ } else {
+ fentry = filelist_add(entry);
+ }
+ return fentry;
}
// shrinks the file list array if too long
static void filelist_compact(void)
{
- if (filelist == NULL)
- return;
+ if (filelist == NULL)
+ return;
- if (filelist_entrys < filelist_maxentry) {
- filelist = (FILELIST *)aRealloc(filelist, filelist_entrys * sizeof(FILELIST));
- filelist_maxentry = filelist_entrys;
- }
+ if (filelist_entrys < filelist_maxentry) {
+ filelist = (FILELIST *)aRealloc(filelist, filelist_entrys * sizeof(FILELIST));
+ filelist_maxentry = filelist_entrys;
+ }
}
@@ -386,448 +362,457 @@ static void filelist_compact(void)
/// Combines are resource path with the data folder location to create local resource path.
-static void grfio_localpath_create(char *buffer, size_t size, const char *filename)
+static void grfio_localpath_create(char* buffer, size_t size, const char* filename)
{
- unsigned int i;
- size_t len;
-
- len = strlen(data_dir);
-
- if (data_dir[0] == '\0' || data_dir[len-1] == '/' || data_dir[len-1] == '\\') {
- safesnprintf(buffer, size, "%s%s", data_dir, filename);
- } else {
- safesnprintf(buffer, size, "%s/%s", data_dir, filename);
- }
-
- // normalize path
- for (i = 0; buffer[i] != '\0'; ++i)
- if (buffer[i] == '\\')
- buffer[i] = '/';
+ unsigned int i;
+ size_t len;
+
+ len = strlen(data_dir);
+
+ if( data_dir[0] == '\0' || data_dir[len-1] == '/' || data_dir[len-1] == '\\' )
+ {
+ safesnprintf(buffer, size, "%s%s", data_dir, filename);
+ }
+ else
+ {
+ safesnprintf(buffer, size, "%s/%s", data_dir, filename);
+ }
+
+ // normalize path
+ for( i = 0; buffer[i] != '\0'; ++i )
+ if( buffer[i] == '\\' )
+ buffer[i] = '/';
}
/// Reads a file into a newly allocated buffer (from grf or data directory).
-void *grfio_reads(const char *fname, int *size)
+void* grfio_reads(const char* fname, int* size)
{
- unsigned char *buf2 = NULL;
-
- FILELIST *entry = filelist_find(fname);
- if (entry == NULL || entry->gentry <= 0) { // LocalFileCheck
- char lfname[256];
- int declen;
- FILE *in;
- grfio_localpath_create(lfname, sizeof(lfname), (entry && entry->fnd) ? entry->fnd : fname);
-
- in = fopen(lfname, "rb");
- if (in != NULL) {
- fseek(in,0,SEEK_END);
- declen = ftell(in);
- fseek(in,0,SEEK_SET);
- buf2 = (unsigned char *)aMalloc(declen+1); // +1 for resnametable zero-termination
- if (fread(buf2, 1, declen, in) != declen) ShowError("An error occured in fread grfio_reads, fname=%s \n",fname);
- fclose(in);
-
- if (size)
- *size = declen;
- } else {
- if (entry != NULL && entry->gentry < 0) {
- entry->gentry = -entry->gentry; // local file checked
- } else {
- ShowError("grfio_reads: %s not found (local file: %s)\n", fname, lfname);
- return NULL;
- }
- }
- }
-
- if (entry != NULL && entry->gentry > 0) { // Archive[GRF] File Read
- char *grfname = gentry_table[entry->gentry - 1];
- FILE *in = fopen(grfname, "rb");
- if (in != NULL) {
- int fsize = entry->srclen_aligned;
- unsigned char *buf = (unsigned char *)aMalloc(fsize);
- fseek(in, entry->srcpos, 0);
- if (fread(buf, 1, fsize, in) != fsize) ShowError("An error occured in fread in grfio_reads, grfname=%s\n",grfname);
- fclose(in);
-
- buf2 = (unsigned char *)aMalloc(entry->declen+1); // +1 for resnametable zero-termination
- if (entry->type & FILELIST_TYPE_FILE) {
- // file
- uLongf len;
- grf_decode(buf, fsize, entry->type, entry->srclen);
- len = entry->declen;
- decode_zip(buf2, &len, buf, entry->srclen);
- if (len != (uLong)entry->declen) {
- ShowError("decode_zip size mismatch err: %d != %d\n", (int)len, entry->declen);
- aFree(buf);
- aFree(buf2);
- return NULL;
- }
- } else {// directory?
- memcpy(buf2, buf, entry->declen);
- }
-
- if (size)
- *size = entry->declen;
-
- aFree(buf);
- } else {
- ShowError("grfio_reads: %s not found (GRF file: %s)\n", fname, grfname);
- return NULL;
- }
- }
-
- return buf2;
+ unsigned char* buf2 = NULL;
+
+ FILELIST* entry = filelist_find(fname);
+ if( entry == NULL || entry->gentry <= 0 ) {// LocalFileCheck
+ char lfname[256];
+ int declen;
+ FILE* in;
+ grfio_localpath_create(lfname, sizeof(lfname), ( entry && entry->fnd ) ? entry->fnd : fname);
+
+ in = fopen(lfname, "rb");
+ if( in != NULL ) {
+ fseek(in,0,SEEK_END);
+ declen = ftell(in);
+ fseek(in,0,SEEK_SET);
+ buf2 = (unsigned char *)aMalloc(declen+1); // +1 for resnametable zero-termination
+ if(fread(buf2, 1, declen, in) != declen) ShowError("An error occured in fread grfio_reads, fname=%s \n",fname);
+ fclose(in);
+
+ if( size )
+ *size = declen;
+ } else {
+ if (entry != NULL && entry->gentry < 0) {
+ entry->gentry = -entry->gentry; // local file checked
+ } else {
+ ShowError("grfio_reads: %s not found (local file: %s)\n", fname, lfname);
+ return NULL;
+ }
+ }
+ }
+
+ if( entry != NULL && entry->gentry > 0 ) {// Archive[GRF] File Read
+ char* grfname = gentry_table[entry->gentry - 1];
+ FILE* in = fopen(grfname, "rb");
+ if( in != NULL ) {
+ int fsize = entry->srclen_aligned;
+ unsigned char *buf = (unsigned char *)aMalloc(fsize);
+ fseek(in, entry->srcpos, 0);
+ if(fread(buf, 1, fsize, in) != fsize) ShowError("An error occured in fread in grfio_reads, grfname=%s\n",grfname);
+ fclose(in);
+
+ buf2 = (unsigned char *)aMalloc(entry->declen+1); // +1 for resnametable zero-termination
+ if( entry->type & FILELIST_TYPE_FILE )
+ {// file
+ uLongf len;
+ grf_decode(buf, fsize, entry->type, entry->srclen);
+ len = entry->declen;
+ decode_zip(buf2, &len, buf, entry->srclen);
+ if (len != (uLong)entry->declen) {
+ ShowError("decode_zip size mismatch err: %d != %d\n", (int)len, entry->declen);
+ aFree(buf);
+ aFree(buf2);
+ return NULL;
+ }
+ } else {// directory?
+ memcpy(buf2, buf, entry->declen);
+ }
+
+ if( size )
+ *size = entry->declen;
+
+ aFree(buf);
+ } else {
+ ShowError("grfio_reads: %s not found (GRF file: %s)\n", fname, grfname);
+ return NULL;
+ }
+ }
+
+ return buf2;
}
/// Decodes encrypted filename from a version 01xx grf index.
-static 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) {
- NibbleSwap(&buf[lop],8);
- des_decrypt(&buf[lop],8);
- }
- return (char *)buf;
+ int lop;
+ for(lop=0;lop<len;lop+=8) {
+ NibbleSwap(&buf[lop],8);
+ des_decrypt(&buf[lop],8);
+ }
+ return (char*)buf;
}
/// Compares file extension against known large file types.
/// @return true if the file should undergo full mode 0 decryption, and true otherwise.
-static bool isFullEncrypt(const char *fname)
+static bool isFullEncrypt(const char* fname)
{
- static const char extensions[4][5] = { ".gnd", ".gat", ".act", ".str" };
- size_t i;
+ static const char extensions[4][5] = { ".gnd", ".gat", ".act", ".str" };
+ size_t i;
- const char *ext = strrchr(fname, '.');
- if (ext != NULL)
- for (i = 0; i < ARRAYLENGTH(extensions); ++i)
- if (strcmpi(ext, extensions[i]) == 0)
- return false;
+ const char* ext = strrchr(fname, '.');
+ if( ext != NULL )
+ for( i = 0; i < ARRAYLENGTH(extensions); ++i )
+ if( strcmpi(ext, extensions[i]) == 0 )
+ return false;
- return true;
+ return true;
}
/// Loads all entries in the specified grf file into the filelist.
/// @param gentry index of the grf file name in the gentry_table
-static int grfio_entryread(const char *grfname, int gentry)
+static int grfio_entryread(const char* grfname, int gentry)
{
- long grf_size,list_size;
- unsigned char grf_header[0x2e];
- int entry,entrys,ofs,grf_version;
- unsigned char *grf_filelist;
-
- FILE *fp = fopen(grfname, "rb");
- if (fp == NULL) {
- ShowWarning("GRF data file not found: '%s'\n",grfname);
- return 1; // 1:not found error
- } else
- ShowInfo("GRF data file found: '%s'\n",grfname);
-
- fseek(fp,0,SEEK_END);
- grf_size = ftell(fp);
- fseek(fp,0,SEEK_SET);
-
- if (fread(grf_header,1,0x2e,fp) != 0x2e) {
- ShowError("Couldn't read all grf_header element of %s \n", grfname);
- }
- if (strcmp((const char *)grf_header,"Master of Magic") != 0 || fseek(fp,getlong(grf_header+0x1e),SEEK_CUR) != 0) {
- fclose(fp);
- ShowError("GRF %s read error\n", grfname);
- return 2; // 2:file format error
- }
-
- grf_version = getlong(grf_header+0x2a) >> 8;
-
- if (grf_version == 0x01) { // ****** Grf version 01xx ******
- list_size = grf_size - ftell(fp);
- grf_filelist = (unsigned char *) aMalloc(list_size);
- if (fread(grf_filelist,1,list_size,fp) != list_size) {
- ShowError("Couldn't read all grf_filelist element of %s \n", grfname);
- }
- fclose(fp);
-
- entrys = getlong(grf_header+0x26) - getlong(grf_header+0x22) - 7;
-
- // Get an entry
- for (entry = 0, ofs = 0; entry < entrys; ++entry) {
- FILELIST aentry;
-
- int ofs2 = ofs+getlong(grf_filelist+ofs)+4;
- unsigned char type = grf_filelist[ofs2+12];
- if (type & FILELIST_TYPE_FILE) {
- char *fname = decode_filename(grf_filelist+ofs+6, grf_filelist[ofs]-6);
- int srclen = getlong(grf_filelist+ofs2+0) - getlong(grf_filelist+ofs2+8) - 715;
-
- if (strlen(fname) > sizeof(aentry.fn) - 1) {
- ShowFatalError("GRF file name %s is too long\n", fname);
- aFree(grf_filelist);
- exit(EXIT_FAILURE);
- }
-
- type |= (isFullEncrypt(fname)) ? FILELIST_TYPE_ENCRYPT_MIXED : FILELIST_TYPE_ENCRYPT_HEADER;
-
- aentry.srclen = srclen;
- aentry.srclen_aligned = getlong(grf_filelist+ofs2+4)-37579;
- aentry.declen = getlong(grf_filelist+ofs2+8);
- aentry.srcpos = getlong(grf_filelist+ofs2+13)+0x2e;
- aentry.type = type;
- safestrncpy(aentry.fn, fname, sizeof(aentry.fn));
- aentry.fnd = NULL;
-#ifdef GRFIO_LOCAL
- aentry.gentry = -(gentry+1); // As Flag for making it a negative number carrying out the first time LocalFileCheck
+ long grf_size,list_size;
+ unsigned char grf_header[0x2e];
+ int entry,entrys,ofs,grf_version;
+ unsigned char *grf_filelist;
+
+ FILE* fp = fopen(grfname, "rb");
+ if( fp == NULL ) {
+ ShowWarning("GRF data file not found: '%s'\n",grfname);
+ return 1; // 1:not found error
+ } else
+ ShowInfo("GRF data file found: '%s'\n",grfname);
+
+ fseek(fp,0,SEEK_END);
+ grf_size = ftell(fp);
+ fseek(fp,0,SEEK_SET);
+
+ if(fread(grf_header,1,0x2e,fp) != 0x2e) { ShowError("Couldn't read all grf_header element of %s \n", grfname); }
+ if( strcmp((const char*)grf_header,"Master of Magic") != 0 || fseek(fp,getlong(grf_header+0x1e),SEEK_CUR) != 0 ) {
+ fclose(fp);
+ ShowError("GRF %s read error\n", grfname);
+ return 2; // 2:file format error
+ }
+
+ grf_version = getlong(grf_header+0x2a) >> 8;
+
+ if( grf_version == 0x01 ) {// ****** Grf version 01xx ******
+ list_size = grf_size - ftell(fp);
+ grf_filelist = (unsigned char *) aMalloc(list_size);
+ if(fread(grf_filelist,1,list_size,fp) != list_size) { ShowError("Couldn't read all grf_filelist element of %s \n", grfname); }
+ fclose(fp);
+
+ entrys = getlong(grf_header+0x26) - getlong(grf_header+0x22) - 7;
+
+ // Get an entry
+ for( entry = 0, ofs = 0; entry < entrys; ++entry ) {
+ FILELIST aentry;
+
+ int ofs2 = ofs+getlong(grf_filelist+ofs)+4;
+ unsigned char type = grf_filelist[ofs2+12];
+ if( type & FILELIST_TYPE_FILE ) {
+ char* fname = decode_filename(grf_filelist+ofs+6, grf_filelist[ofs]-6);
+ int srclen = getlong(grf_filelist+ofs2+0) - getlong(grf_filelist+ofs2+8) - 715;
+
+ if( strlen(fname) > sizeof(aentry.fn) - 1 ) {
+ ShowFatalError("GRF file name %s is too long\n", fname);
+ aFree(grf_filelist);
+ exit(EXIT_FAILURE);
+ }
+
+ type |= ( isFullEncrypt(fname) ) ? FILELIST_TYPE_ENCRYPT_MIXED : FILELIST_TYPE_ENCRYPT_HEADER;
+
+ aentry.srclen = srclen;
+ aentry.srclen_aligned = getlong(grf_filelist+ofs2+4)-37579;
+ aentry.declen = getlong(grf_filelist+ofs2+8);
+ aentry.srcpos = getlong(grf_filelist+ofs2+13)+0x2e;
+ aentry.type = type;
+ safestrncpy(aentry.fn, fname, sizeof(aentry.fn));
+ aentry.fnd = NULL;
+#ifdef GRFIO_LOCAL
+ aentry.gentry = -(gentry+1); // As Flag for making it a negative number carrying out the first time LocalFileCheck
#else
- aentry.gentry = gentry+1; // With no first time LocalFileCheck
+ aentry.gentry = gentry+1; // With no first time LocalFileCheck
#endif
- filelist_modify(&aentry);
- }
-
- ofs = ofs2 + 17;
- }
-
- aFree(grf_filelist);
- } else if (grf_version == 0x02) { // ****** Grf version 02xx ******
- unsigned char eheader[8];
- unsigned char *rBuf;
- uLongf rSize, eSize;
-
- if (fread(eheader,1,8,fp) != 8) ShowError("An error occured in fread while reading eheader buffer\n");
- rSize = getlong(eheader); // Read Size
- eSize = getlong(eheader+4); // Extend Size
-
- if ((long)rSize > grf_size-ftell(fp)) {
- fclose(fp);
- ShowError("Illegal data format: GRF compress entry size\n");
- return 4;
- }
-
- rBuf = (unsigned char *)aMalloc(rSize); // Get a Read Size
- grf_filelist = (unsigned char *)aMalloc(eSize); // Get a Extend Size
- if (fread(rBuf,1,rSize,fp) != rSize) ShowError("An error occured in fread \n");
- fclose(fp);
- decode_zip(grf_filelist, &eSize, rBuf, rSize); // Decode function
- aFree(rBuf);
-
- entrys = getlong(grf_header+0x26) - 7;
-
- // Get an entry
- for (entry = 0, ofs = 0; entry < entrys; ++entry) {
- FILELIST aentry;
-
- char *fname = (char *)(grf_filelist+ofs);
- int ofs2 = ofs + (int)strlen(fname)+1;
- int type = grf_filelist[ofs2+12];
-
- if (strlen(fname) > sizeof(aentry.fn)-1) {
- ShowFatalError("GRF file name %s is too long\n", fname);
- aFree(grf_filelist);
- exit(EXIT_FAILURE);
- }
-
- if (type & FILELIST_TYPE_FILE) { // file
- aentry.srclen = getlong(grf_filelist+ofs2+0);
- aentry.srclen_aligned = getlong(grf_filelist+ofs2+4);
- aentry.declen = getlong(grf_filelist+ofs2+8);
- aentry.srcpos = getlong(grf_filelist+ofs2+13)+0x2e;
- aentry.type = type;
- safestrncpy(aentry.fn, fname, sizeof(aentry.fn));
- aentry.fnd = NULL;
-#ifdef GRFIO_LOCAL
- aentry.gentry = -(gentry+1); // As Flag for making it a negative number carrying out the first time LocalFileCheck
+ filelist_modify(&aentry);
+ }
+
+ ofs = ofs2 + 17;
+ }
+
+ aFree(grf_filelist);
+ } else if( grf_version == 0x02 ) {// ****** Grf version 02xx ******
+ unsigned char eheader[8];
+ unsigned char *rBuf;
+ uLongf rSize, eSize;
+
+ if(fread(eheader,1,8,fp) != 8) ShowError("An error occured in fread while reading eheader buffer\n");
+ rSize = getlong(eheader); // Read Size
+ eSize = getlong(eheader+4); // Extend Size
+
+ if( (long)rSize > grf_size-ftell(fp) ) {
+ fclose(fp);
+ ShowError("Illegal data format: GRF compress entry size\n");
+ return 4;
+ }
+
+ rBuf = (unsigned char *)aMalloc(rSize); // Get a Read Size
+ grf_filelist = (unsigned char *)aMalloc(eSize); // Get a Extend Size
+ if(fread(rBuf,1,rSize,fp) != rSize) ShowError("An error occured in fread \n");
+ fclose(fp);
+ decode_zip(grf_filelist, &eSize, rBuf, rSize); // Decode function
+ aFree(rBuf);
+
+ entrys = getlong(grf_header+0x26) - 7;
+
+ // Get an entry
+ for( entry = 0, ofs = 0; entry < entrys; ++entry ) {
+ FILELIST aentry;
+
+ char* fname = (char*)(grf_filelist+ofs);
+ int ofs2 = ofs + (int)strlen(fname)+1;
+ int type = grf_filelist[ofs2+12];
+
+ if( strlen(fname) > sizeof(aentry.fn)-1 ) {
+ ShowFatalError("GRF file name %s is too long\n", fname);
+ aFree(grf_filelist);
+ exit(EXIT_FAILURE);
+ }
+
+ if( type & FILELIST_TYPE_FILE ) {// file
+ aentry.srclen = getlong(grf_filelist+ofs2+0);
+ aentry.srclen_aligned = getlong(grf_filelist+ofs2+4);
+ aentry.declen = getlong(grf_filelist+ofs2+8);
+ aentry.srcpos = getlong(grf_filelist+ofs2+13)+0x2e;
+ aentry.type = type;
+ safestrncpy(aentry.fn, fname, sizeof(aentry.fn));
+ aentry.fnd = NULL;
+#ifdef GRFIO_LOCAL
+ aentry.gentry = -(gentry+1); // As Flag for making it a negative number carrying out the first time LocalFileCheck
#else
- aentry.gentry = gentry+1; // With no first time LocalFileCheck
+ aentry.gentry = gentry+1; // With no first time LocalFileCheck
#endif
- filelist_modify(&aentry);
- }
+ filelist_modify(&aentry);
+ }
- ofs = ofs2 + 17;
- }
+ ofs = ofs2 + 17;
+ }
- aFree(grf_filelist);
- } else {// ****** Grf Other version ******
- fclose(fp);
- ShowError("GRF version %04x not supported\n",getlong(grf_header+0x2a));
- return 4;
- }
+ aFree(grf_filelist);
+ } else {// ****** Grf Other version ******
+ fclose(fp);
+ ShowError("GRF version %04x not supported\n",getlong(grf_header+0x2a));
+ return 4;
+ }
- filelist_compact(); // Unnecessary area release of filelist
+ filelist_compact(); // Unnecessary area release of filelist
- return 0; // 0:no error
+ return 0; // 0:no error
}
-static bool grfio_parse_restable_row(const char *row)
+static bool grfio_parse_restable_row(const char* row)
{
- char w1[256], w2[256];
- char src[256], dst[256];
- char local[256];
- FILELIST *entry;
-
- if (sscanf(row, "%[^#\r\n]#%[^#\r\n]#", w1, w2) != 2)
- return false;
-
- if (strstr(w2, ".gat") == NULL && strstr(w2, ".rsw") == NULL)
- return false; // we only need the maps' GAT and RSW files
-
- sprintf(src, "data\\%s", w1);
- sprintf(dst, "data\\%s", w2);
-
- entry = filelist_find(dst);
- if (entry != NULL) {
- // alias for GRF resource
- FILELIST fentry;
- memcpy(&fentry, entry, sizeof(FILELIST));
- safestrncpy(fentry.fn, src, sizeof(fentry.fn));
- fentry.fnd = aStrdup(dst);
- filelist_modify(&fentry);
- return true;
- }
-
- grfio_localpath_create(local, sizeof(local), dst);
- if (exists(local)) {
- // alias for local resource
- FILELIST fentry;
- memset(&fentry, 0, sizeof(fentry));
- safestrncpy(fentry.fn, src, sizeof(fentry.fn));
- fentry.fnd = aStrdup(dst);
- filelist_modify(&fentry);
- return true;
- }
-
- return false;
+ char w1[256], w2[256];
+ char src[256], dst[256];
+ char local[256];
+ FILELIST* entry;
+
+ if( sscanf(row, "%[^#\r\n]#%[^#\r\n]#", w1, w2) != 2 )
+ return false;
+
+ if( strstr(w2, ".gat") == NULL && strstr(w2, ".rsw") == NULL )
+ return false; // we only need the maps' GAT and RSW files
+
+ sprintf(src, "data\\%s", w1);
+ sprintf(dst, "data\\%s", w2);
+
+ entry = filelist_find(dst);
+ if( entry != NULL )
+ {// alias for GRF resource
+ FILELIST fentry;
+ memcpy(&fentry, entry, sizeof(FILELIST));
+ safestrncpy(fentry.fn, src, sizeof(fentry.fn));
+ fentry.fnd = aStrdup(dst);
+ filelist_modify(&fentry);
+ return true;
+ }
+
+ grfio_localpath_create(local, sizeof(local), dst);
+ if( exists(local) )
+ {// alias for local resource
+ FILELIST fentry;
+ memset(&fentry, 0, sizeof(fentry));
+ safestrncpy(fentry.fn, src, sizeof(fentry.fn));
+ fentry.fnd = aStrdup(dst);
+ filelist_modify(&fentry);
+ return true;
+ }
+
+ return false;
}
/// Grfio Resource file check.
static void grfio_resourcecheck(void)
{
- char restable[256];
- char *ptr, *buf;
- int size;
- FILE *fp;
- int i = 0;
-
- // read resnametable from data directory and return if successful
- grfio_localpath_create(restable, sizeof(restable), "data\\resnametable.txt");
-
- fp = fopen(restable, "rb");
- if (fp != NULL) {
- char line[256];
- while (fgets(line, sizeof(line), fp)) {
- if (grfio_parse_restable_row(line))
- ++i;
- }
-
- fclose(fp);
- ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", i, "resnametable.txt");
- return; // we're done here!
- }
-
- // read resnametable from loaded GRF's, only if it cannot be loaded from the data directory
- buf = (char *)grfio_reads("data\\resnametable.txt", &size);
- if (buf != NULL) {
- buf[size] = '\0';
-
- ptr = buf;
- while (ptr - buf < size) {
- if (grfio_parse_restable_row(ptr))
- ++i;
-
- ptr = strchr(ptr, '\n');
- if (ptr == NULL) break;
- ptr++;
- }
-
- aFree(buf);
- ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", i, "data\\resnametable.txt");
- return;
- }
+ char restable[256];
+ char *ptr, *buf;
+ int size;
+ FILE* fp;
+ int i = 0;
+
+ // read resnametable from data directory and return if successful
+ grfio_localpath_create(restable, sizeof(restable), "data\\resnametable.txt");
+
+ fp = fopen(restable, "rb");
+ if( fp != NULL )
+ {
+ char line[256];
+ while( fgets(line, sizeof(line), fp) )
+ {
+ if( grfio_parse_restable_row(line) )
+ ++i;
+ }
+
+ fclose(fp);
+ ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", i, "resnametable.txt");
+ return; // we're done here!
+ }
+
+ // read resnametable from loaded GRF's, only if it cannot be loaded from the data directory
+ buf = (char *)grfio_reads("data\\resnametable.txt", &size);
+ if( buf != NULL )
+ {
+ buf[size] = '\0';
+
+ ptr = buf;
+ while( ptr - buf < size )
+ {
+ if( grfio_parse_restable_row(ptr) )
+ ++i;
+
+ ptr = strchr(ptr, '\n');
+ if( ptr == NULL ) break;
+ ptr++;
+ }
+
+ aFree(buf);
+ ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", i, "data\\resnametable.txt");
+ return;
+ }
}
/// Reads a grf file and adds it to the list.
-static int grfio_add(const char *fname)
+static int grfio_add(const char* fname)
{
- if (gentry_entrys >= gentry_maxentry) {
-#define GENTRY_ADDS 4 // The number increment of gentry_table entries
- gentry_maxentry += GENTRY_ADDS;
- gentry_table = (char **)aRealloc(gentry_table, gentry_maxentry * sizeof(char *));
- memset(gentry_table + (gentry_maxentry - GENTRY_ADDS), 0, sizeof(char *) * GENTRY_ADDS);
- }
+ if( gentry_entrys >= gentry_maxentry )
+ {
+ #define GENTRY_ADDS 4 // The number increment of gentry_table entries
+ gentry_maxentry += GENTRY_ADDS;
+ gentry_table = (char**)aRealloc(gentry_table, gentry_maxentry * sizeof(char*));
+ memset(gentry_table + (gentry_maxentry - GENTRY_ADDS), 0, sizeof(char*) * GENTRY_ADDS);
+ }
- gentry_table[gentry_entrys++] = aStrdup(fname);
+ gentry_table[gentry_entrys++] = aStrdup(fname);
- return grfio_entryread(fname, gentry_entrys - 1);
+ return grfio_entryread(fname, gentry_entrys - 1);
}
/// Finalizes grfio.
void grfio_final(void)
{
- if (filelist != NULL) {
- int i;
- for (i = 0; i < filelist_entrys; i++)
- if (filelist[i].fnd != NULL)
- aFree(filelist[i].fnd);
-
- aFree(filelist);
- filelist = NULL;
- }
- filelist_entrys = filelist_maxentry = 0;
-
- if (gentry_table != NULL) {
- int i;
- for (i = 0; i < gentry_entrys; i++)
- if (gentry_table[i] != NULL)
- aFree(gentry_table[i]);
-
- aFree(gentry_table);
- gentry_table = NULL;
- }
- gentry_entrys = gentry_maxentry = 0;
+ if (filelist != NULL) {
+ int i;
+ for (i = 0; i < filelist_entrys; i++)
+ if (filelist[i].fnd != NULL)
+ aFree(filelist[i].fnd);
+
+ aFree(filelist);
+ filelist = NULL;
+ }
+ filelist_entrys = filelist_maxentry = 0;
+
+ if (gentry_table != NULL) {
+ int i;
+ for (i = 0; i < gentry_entrys; i++)
+ if (gentry_table[i] != NULL)
+ aFree(gentry_table[i]);
+
+ aFree(gentry_table);
+ gentry_table = NULL;
+ }
+ gentry_entrys = gentry_maxentry = 0;
}
/// Initializes grfio.
-void grfio_init(const char *fname)
+void grfio_init(const char* fname)
{
- FILE *data_conf;
- int grf_num = 0;
-
- hashinit(); // hash table initialization
-
- data_conf = fopen(fname, "r");
- if (data_conf != NULL) {
- char line[1024];
- while (fgets(line, sizeof(line), data_conf)) {
- char w1[1024], w2[1024];
-
- if (line[0] == '/' && line[1] == '/')
- continue; // skip comments
-
- if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) != 2)
- continue; // skip unrecognized lines
-
- // Entry table reading
- if (strcmp(w1, "grf") == 0) { // GRF file
- if (grfio_add(w2) == 0)
- ++grf_num;
- } else if (strcmp(w1,"data_dir") == 0) { // Data directory
- safestrncpy(data_dir, w2, sizeof(data_dir));
- }
- }
-
- fclose(data_conf);
- ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n", fname);
- }
-
- if (grf_num == 0)
- ShowInfo("No GRF loaded, using default data directory\n");
-
- // Unneccessary area release of filelist
- filelist_compact();
-
- // Resource check
- grfio_resourcecheck();
+ FILE* data_conf;
+ int grf_num = 0;
+
+ hashinit(); // hash table initialization
+
+ data_conf = fopen(fname, "r");
+ if( data_conf != NULL )
+ {
+ char line[1024];
+ while( fgets(line, sizeof(line), data_conf) )
+ {
+ char w1[1024], w2[1024];
+
+ if( line[0] == '/' && line[1] == '/' )
+ continue; // skip comments
+
+ if( sscanf(line, "%[^:]: %[^\r\n]", w1, w2) != 2 )
+ continue; // skip unrecognized lines
+
+ // Entry table reading
+ if( strcmp(w1, "grf") == 0 ) // GRF file
+ {
+ if( grfio_add(w2) == 0 )
+ ++grf_num;
+ }
+ else if( strcmp(w1,"data_dir") == 0 ) // Data directory
+ {
+ safestrncpy(data_dir, w2, sizeof(data_dir));
+ }
+ }
+
+ fclose(data_conf);
+ ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n", fname);
+ }
+
+ if( grf_num == 0 )
+ ShowInfo("No GRF loaded, using default data directory\n");
+
+ // Unneccessary area release of filelist
+ filelist_compact();
+
+ // Resource check
+ grfio_resourcecheck();
}
diff --git a/src/common/grfio.h b/src/common/grfio.h
index ae2fbd67c..c5a56a14e 100644
--- a/src/common/grfio.h
+++ b/src/common/grfio.h
@@ -1,17 +1,17 @@
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder
-#ifndef _GRFIO_H_
-#define _GRFIO_H_
+#ifndef _GRFIO_H_
+#define _GRFIO_H_
-void grfio_init(const char *fname);
+void grfio_init(const char* fname);
void grfio_final(void);
-void *grfio_reads(const char *fname, int *size);
-char *grfio_find_file(const char *fname);
+void* grfio_reads(const char* fname, int* size);
+char* grfio_find_file(const char* fname);
#define grfio_read(fn) grfio_reads(fn, NULL)
unsigned long grfio_crc32(const unsigned char *buf, unsigned int len);
-int decode_zip(void *dest, unsigned long *destLen, const void *source, unsigned long sourceLen);
-int encode_zip(void *dest, unsigned long *destLen, const void *source, unsigned long sourceLen);
+int decode_zip(void* dest, unsigned long* destLen, const void* source, unsigned long sourceLen);
+int encode_zip(void* dest, unsigned long* destLen, const void* source, unsigned long sourceLen);
#endif /* _GRFIO_H_ */
diff --git a/src/common/malloc.c b/src/common/malloc.c
index 396ec33cb..9976a28d5 100644
--- a/src/common/malloc.c
+++ b/src/common/malloc.c
@@ -14,109 +14,109 @@
#if defined(MEMWATCH)
-# include <string.h>
-# include "memwatch.h"
-# define MALLOC(n,file,line,func) mwMalloc((n),(file),(line))
-# define CALLOC(m,n,file,line,func) mwCalloc((m),(n),(file),(line))
-# define REALLOC(p,n,file,line,func) mwRealloc((p),(n),(file),(line))
-# define STRDUP(p,file,line,func) mwStrdup((p),(file),(line))
-# define FREE(p,file,line,func) mwFree((p),(file),(line))
-# define MEMORY_USAGE() 0
-# define MEMORY_VERIFY(ptr) mwIsSafeAddr(ptr, 1)
-# define MEMORY_CHECK() CHECK()
+# include <string.h>
+# include "memwatch.h"
+# define MALLOC(n,file,line,func) mwMalloc((n),(file),(line))
+# define CALLOC(m,n,file,line,func) mwCalloc((m),(n),(file),(line))
+# define REALLOC(p,n,file,line,func) mwRealloc((p),(n),(file),(line))
+# define STRDUP(p,file,line,func) mwStrdup((p),(file),(line))
+# define FREE(p,file,line,func) mwFree((p),(file),(line))
+# define MEMORY_USAGE() 0
+# define MEMORY_VERIFY(ptr) mwIsSafeAddr(ptr, 1)
+# define MEMORY_CHECK() CHECK()
#elif defined(DMALLOC)
-# include <string.h>
-# include <stdlib.h>
-# include "dmalloc.h"
-# define MALLOC(n,file,line,func) dmalloc_malloc((file),(line),(n),DMALLOC_FUNC_MALLOC,0,0)
-# define CALLOC(m,n,file,line,func) dmalloc_malloc((file),(line),(m)*(n),DMALLOC_FUNC_CALLOC,0,0)
-# define REALLOC(p,n,file,line,func) dmalloc_realloc((file),(line),(p),(n),DMALLOC_FUNC_REALLOC,0)
-# define STRDUP(p,file,line,func) strdup(p)
-# define FREE(p,file,line,func) free(p)
-# define MEMORY_USAGE() dmalloc_memory_allocated()
-# define MEMORY_VERIFY(ptr) (dmalloc_verify(ptr) == DMALLOC_VERIFY_NOERROR)
-# define MEMORY_CHECK() dmalloc_log_stats(); dmalloc_log_unfreed()
+# include <string.h>
+# include <stdlib.h>
+# include "dmalloc.h"
+# define MALLOC(n,file,line,func) dmalloc_malloc((file),(line),(n),DMALLOC_FUNC_MALLOC,0,0)
+# define CALLOC(m,n,file,line,func) dmalloc_malloc((file),(line),(m)*(n),DMALLOC_FUNC_CALLOC,0,0)
+# define REALLOC(p,n,file,line,func) dmalloc_realloc((file),(line),(p),(n),DMALLOC_FUNC_REALLOC,0)
+# define STRDUP(p,file,line,func) strdup(p)
+# define FREE(p,file,line,func) free(p)
+# define MEMORY_USAGE() dmalloc_memory_allocated()
+# define MEMORY_VERIFY(ptr) (dmalloc_verify(ptr) == DMALLOC_VERIFY_NOERROR)
+# define MEMORY_CHECK() dmalloc_log_stats(); dmalloc_log_unfreed()
#elif defined(GCOLLECT)
-# include "gc.h"
-# ifdef GC_ADD_CALLER
-# define RETURN_ADDR 0,
-# else
-# define RETURN_ADDR
-# endif
-# define MALLOC(n,file,line,func) GC_debug_malloc((n), RETURN_ADDR (file),(line))
-# define CALLOC(m,n,file,line,func) GC_debug_malloc((m)*(n), RETURN_ADDR (file),(line))
-# define REALLOC(p,n,file,line,func) GC_debug_realloc((p),(n), RETURN_ADDR (file),(line))
-# define STRDUP(p,file,line,func) GC_debug_strdup((p), RETURN_ADDR (file),(line))
-# define FREE(p,file,line,func) GC_debug_free(p)
-# define MEMORY_USAGE() GC_get_heap_size()
-# define MEMORY_VERIFY(ptr) (GC_base(ptr) != NULL)
-# define MEMORY_CHECK() GC_gcollect()
+# include "gc.h"
+# ifdef GC_ADD_CALLER
+# define RETURN_ADDR 0,
+# else
+# define RETURN_ADDR
+# endif
+# define MALLOC(n,file,line,func) GC_debug_malloc((n), RETURN_ADDR (file),(line))
+# define CALLOC(m,n,file,line,func) GC_debug_malloc((m)*(n), RETURN_ADDR (file),(line))
+# define REALLOC(p,n,file,line,func) GC_debug_realloc((p),(n), RETURN_ADDR (file),(line))
+# define STRDUP(p,file,line,func) GC_debug_strdup((p), RETURN_ADDR (file),(line))
+# define FREE(p,file,line,func) GC_debug_free(p)
+# define MEMORY_USAGE() GC_get_heap_size()
+# define MEMORY_VERIFY(ptr) (GC_base(ptr) != NULL)
+# define MEMORY_CHECK() GC_gcollect()
#else
-# define MALLOC(n,file,line,func) malloc(n)
-# define CALLOC(m,n,file,line,func) calloc((m),(n))
-# define REALLOC(p,n,file,line,func) realloc((p),(n))
-# define STRDUP(p,file,line,func) strdup(p)
-# define FREE(p,file,line,func) free(p)
-# define MEMORY_USAGE() 0
-# define MEMORY_VERIFY(ptr) true
-# define MEMORY_CHECK()
+# define MALLOC(n,file,line,func) malloc(n)
+# define CALLOC(m,n,file,line,func) calloc((m),(n))
+# define REALLOC(p,n,file,line,func) realloc((p),(n))
+# define STRDUP(p,file,line,func) strdup(p)
+# define FREE(p,file,line,func) free(p)
+# define MEMORY_USAGE() 0
+# define MEMORY_VERIFY(ptr) true
+# define MEMORY_CHECK()
#endif
-void *aMalloc_(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 *ret = MALLOC(size, file, line, func);
- // ShowMessage("%s:%d: in func %s: aMalloc %d\n",file,line,func,size);
- if (ret == NULL) {
- ShowFatalError("%s:%d: in func %s: aMalloc error out of memory!\n",file,line,func);
- exit(EXIT_FAILURE);
- }
-
- return ret;
+ void *ret = MALLOC(size, file, line, func);
+ // ShowMessage("%s:%d: in func %s: aMalloc %d\n",file,line,func,size);
+ if (ret == NULL){
+ ShowFatalError("%s:%d: in func %s: aMalloc error out of memory!\n",file,line,func);
+ exit(EXIT_FAILURE);
+ }
+
+ return ret;
}
-void *aCalloc_(size_t num, 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 = CALLOC(num, size, file, line, func);
- // ShowMessage("%s:%d: in func %s: aCalloc %d %d\n",file,line,func,num,size);
- if (ret == NULL) {
- ShowFatalError("%s:%d: in func %s: aCalloc error out of memory!\n", file, line, func);
- exit(EXIT_FAILURE);
- }
- return ret;
+ void *ret = CALLOC(num, size, file, line, func);
+ // ShowMessage("%s:%d: in func %s: aCalloc %d %d\n",file,line,func,num,size);
+ if (ret == NULL){
+ ShowFatalError("%s:%d: in func %s: aCalloc error out of memory!\n", file, line, func);
+ exit(EXIT_FAILURE);
+ }
+ return ret;
}
-void *aRealloc_(void *p, 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 *ret = REALLOC(p, size, file, line, func);
- // ShowMessage("%s:%d: in func %s: aRealloc %p %d\n",file,line,func,p,size);
- if (ret == NULL) {
- ShowFatalError("%s:%d: in func %s: aRealloc error out of memory!\n",file,line,func);
- exit(EXIT_FAILURE);
- }
- return ret;
+ void *ret = REALLOC(p, size, file, line, func);
+ // ShowMessage("%s:%d: in func %s: aRealloc %p %d\n",file,line,func,p,size);
+ if (ret == NULL){
+ ShowFatalError("%s:%d: in func %s: aRealloc error out of memory!\n",file,line,func);
+ exit(EXIT_FAILURE);
+ }
+ return ret;
}
-char *aStrdup_(const char *p, const char *file, int line, const char *func)
+char* aStrdup_(const char *p, const char *file, int line, const char *func)
{
- char *ret = STRDUP(p, file, line, func);
- // ShowMessage("%s:%d: in func %s: aStrdup %p\n",file,line,func,p);
- if (ret == NULL) {
- ShowFatalError("%s:%d: in func %s: aStrdup error out of memory!\n", file, line, func);
- exit(EXIT_FAILURE);
- }
- return ret;
+ char *ret = STRDUP(p, file, line, func);
+ // ShowMessage("%s:%d: in func %s: aStrdup %p\n",file,line,func,p);
+ if (ret == NULL){
+ ShowFatalError("%s:%d: in func %s: aStrdup error out of memory!\n", file, line, func);
+ exit(EXIT_FAILURE);
+ }
+ return ret;
}
void aFree_(void *p, const char *file, int line, const char *func)
{
- // ShowMessage("%s:%d: in func %s: aFree %p\n",file,line,func,p);
- if (p)
- FREE(p, file, line, func);
+ // ShowMessage("%s:%d: in func %s: aFree %p\n",file,line,func,p);
+ if (p)
+ FREE(p, file, line, func);
- p = NULL;
+ p = NULL;
}
@@ -146,397 +146,405 @@ void aFree_(void *p, const char *file, int line, const char *func)
*/
/* ƒuƒƒbƒN‚̃Aƒ‰ƒCƒƒ“ƒg */
-#define BLOCK_ALIGNMENT1 16
-#define BLOCK_ALIGNMENT2 64
+#define BLOCK_ALIGNMENT1 16
+#define BLOCK_ALIGNMENT2 64
/* ƒuƒƒbƒN‚É“ü‚éƒf[ƒ^—Ê */
-#define BLOCK_DATA_COUNT1 128
-#define BLOCK_DATA_COUNT2 608
+#define BLOCK_DATA_COUNT1 128
+#define BLOCK_DATA_COUNT2 608
/* ƒuƒƒbƒN‚Ì‘å‚«‚³: 16*128 + 64*576 = 40KB */
-#define BLOCK_DATA_SIZE1 ( BLOCK_ALIGNMENT1 * BLOCK_DATA_COUNT1 )
-#define BLOCK_DATA_SIZE2 ( BLOCK_ALIGNMENT2 * BLOCK_DATA_COUNT2 )
-#define BLOCK_DATA_SIZE ( BLOCK_DATA_SIZE1 + BLOCK_DATA_SIZE2 )
+#define BLOCK_DATA_SIZE1 ( BLOCK_ALIGNMENT1 * BLOCK_DATA_COUNT1 )
+#define BLOCK_DATA_SIZE2 ( BLOCK_ALIGNMENT2 * BLOCK_DATA_COUNT2 )
+#define BLOCK_DATA_SIZE ( BLOCK_DATA_SIZE1 + BLOCK_DATA_SIZE2 )
/* ˆê“x‚ÉŠm•Û‚·‚éƒuƒƒbƒN‚Ì”B */
-#define BLOCK_ALLOC 104
+#define BLOCK_ALLOC 104
/* ƒuƒƒbƒN */
struct block {
- struct block *block_next; /* ŽŸ‚ÉŠm•Û‚µ‚½—̈æ */
- struct block *unfill_prev; /* ŽŸ‚Ì–„‚Ü‚Á‚Ä‚¢‚È‚¢—̈æ */
- struct block *unfill_next; /* ŽŸ‚Ì–„‚Ü‚Á‚Ä‚¢‚È‚¢—̈æ */
- unsigned short unit_size; /* ƒ†ƒjƒbƒg‚Ì‘å‚«‚³ */
- unsigned short unit_hash; /* ƒ†ƒjƒbƒg‚̃nƒbƒVƒ… */
- unsigned short unit_count; /* ƒ†ƒjƒbƒg‚̌” */
- unsigned short unit_used; /* Žg—pƒ†ƒjƒbƒg” */
- unsigned short unit_unfill; /* –¢Žg—pƒ†ƒjƒbƒg‚ÌêŠ */
- unsigned short unit_maxused; /* Žg—pƒ†ƒjƒbƒg‚ÌÅ‘å’l */
- char data[ BLOCK_DATA_SIZE ];
+ struct block* block_next; /* ŽŸ‚ÉŠm•Û‚µ‚½—̈æ */
+ struct block* unfill_prev; /* ŽŸ‚Ì–„‚Ü‚Á‚Ä‚¢‚È‚¢—̈æ */
+ struct block* unfill_next; /* ŽŸ‚Ì–„‚Ü‚Á‚Ä‚¢‚È‚¢—̈æ */
+ unsigned short unit_size; /* ƒ†ƒjƒbƒg‚Ì‘å‚«‚³ */
+ unsigned short unit_hash; /* ƒ†ƒjƒbƒg‚̃nƒbƒVƒ… */
+ unsigned short unit_count; /* ƒ†ƒjƒbƒg‚̌” */
+ unsigned short unit_used; /* Žg—pƒ†ƒjƒbƒg” */
+ unsigned short unit_unfill; /* –¢Žg—pƒ†ƒjƒbƒg‚ÌêŠ */
+ unsigned short unit_maxused; /* Žg—pƒ†ƒjƒbƒg‚ÌÅ‘å’l */
+ char data[ BLOCK_DATA_SIZE ];
};
struct unit_head {
- struct block *block;
- const char *file;
- unsigned short line;
- unsigned short size;
- long checksum;
+ struct block *block;
+ const char* file;
+ unsigned short line;
+ unsigned short size;
+ long checksum;
};
-static struct block *hash_unfill[BLOCK_DATA_COUNT1 + BLOCK_DATA_COUNT2 + 1];
-static struct block *block_first, *block_last, block_head;
+static struct block* hash_unfill[BLOCK_DATA_COUNT1 + BLOCK_DATA_COUNT2 + 1];
+static struct block* block_first, *block_last, block_head;
/* ƒƒ‚ƒŠ‚ðŽg‚¢‰ñ‚¹‚È‚¢—̈æ—p‚̃f[ƒ^ */
struct unit_head_large {
- size_t size;
- struct unit_head_large *prev;
- struct unit_head_large *next;
- struct unit_head unit_head;
+ size_t size;
+ 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(unsigned short hash);
-static void block_free(struct block *p);
+static struct block* block_malloc(unsigned short hash);
+static void block_free(struct block* p);
static size_t memmgr_usage_bytes;
#define block2unit(p, n) ((struct unit_head*)(&(p)->data[ p->unit_size * (n) ]))
#define memmgr_assert(v) do { if(!(v)) { ShowError("Memory manager: assertion '" #v "' failed!\n"); } } while(0)
-static unsigned short size2hash(size_t size)
+static unsigned short size2hash( size_t size )
{
- if (size <= BLOCK_DATA_SIZE1) {
- return (unsigned short)(size + BLOCK_ALIGNMENT1 - 1) / BLOCK_ALIGNMENT1;
- } else if (size <= BLOCK_DATA_SIZE) {
- return (unsigned short)(size - BLOCK_DATA_SIZE1 + BLOCK_ALIGNMENT2 - 1) / BLOCK_ALIGNMENT2
- + BLOCK_DATA_COUNT1;
- } else {
- return 0xffff; // ƒuƒƒbƒN’·‚ð’´‚¦‚éê‡‚Í hash ‚É‚µ‚È‚¢
- }
+ if( size <= BLOCK_DATA_SIZE1 ) {
+ return (unsigned short)(size + BLOCK_ALIGNMENT1 - 1) / BLOCK_ALIGNMENT1;
+ } else if( size <= BLOCK_DATA_SIZE ){
+ return (unsigned short)(size - BLOCK_DATA_SIZE1 + BLOCK_ALIGNMENT2 - 1) / BLOCK_ALIGNMENT2
+ + BLOCK_DATA_COUNT1;
+ } else {
+ return 0xffff; // ƒuƒƒbƒN’·‚ð’´‚¦‚éê‡‚Í hash ‚É‚µ‚È‚¢
+ }
}
-static size_t hash2size(unsigned short hash)
+static size_t hash2size( unsigned short hash )
{
- if (hash <= BLOCK_DATA_COUNT1) {
- return hash * BLOCK_ALIGNMENT1;
- } else {
- return (hash - BLOCK_DATA_COUNT1) * BLOCK_ALIGNMENT2 + BLOCK_DATA_SIZE1;
- }
+ if( hash <= BLOCK_DATA_COUNT1) {
+ return hash * BLOCK_ALIGNMENT1;
+ } else {
+ return (hash - BLOCK_DATA_COUNT1) * BLOCK_ALIGNMENT2 + BLOCK_DATA_SIZE1;
+ }
}
-void *_mmalloc(size_t size, const char *file, int line, const char *func)
+void* _mmalloc(size_t size, const char *file, int line, const char *func )
{
- struct block *block;
- short size_hash = size2hash(size);
- struct unit_head *head;
-
- if (((long) size) < 0) {
- ShowError("_mmalloc: %d\n", size);
- return NULL;
- }
-
- if (size == 0) {
- return NULL;
- }
- memmgr_usage_bytes += size;
-
- /* ƒuƒƒbƒN’·‚ð’´‚¦‚é—̈æ‚ÌŠm•Û‚É‚ÍAmalloc() ‚ð—p‚¢‚é */
- /* ‚»‚ÌÛAunit_head.block ‚É NULL ‚ð‘ã“ü‚µ‚Ä‹æ•Ê‚·‚é */
- if (hash2size(size_hash) > BLOCK_DATA_SIZE - sizeof(struct unit_head)) {
- struct unit_head_large *p = (struct unit_head_large *)MALLOC(sizeof(struct unit_head_large)+size,file,line,func);
- if (p != NULL) {
- p->size = size;
- p->unit_head.block = NULL;
- p->unit_head.size = 0;
- p->unit_head.file = file;
- p->unit_head.line = line;
- p->prev = NULL;
- if (unit_head_large_first == NULL)
- p->next = NULL;
- else {
- unit_head_large_first->prev = p;
- p->next = unit_head_large_first;
- }
- unit_head_large_first = p;
- *(long *)((char *)p + sizeof(struct unit_head_large) - sizeof(long) + size) = 0xdeadbeaf;
- return (char *)p + sizeof(struct unit_head_large) - sizeof(long);
- } else {
- ShowFatalError("Memory manager::memmgr_alloc failed (allocating %d+%d bytes at %s:%d).\n", sizeof(struct unit_head_large), size, file, line);
- exit(EXIT_FAILURE);
- }
- }
-
- /* “¯ˆêƒTƒCƒY‚̃uƒƒbƒN‚ªŠm•Û‚³‚ê‚Ä‚¢‚È‚¢ŽžAV‚½‚ÉŠm•Û‚·‚é */
- if (hash_unfill[size_hash]) {
- block = hash_unfill[size_hash];
- } else {
- block = block_malloc(size_hash);
- }
-
- if (block->unit_unfill == 0xFFFF) {
- // freeςݗ̈悪Žc‚Á‚Ä‚¢‚È‚¢
- memmgr_assert(block->unit_used < block->unit_count);
- memmgr_assert(block->unit_used == block->unit_maxused);
- head = block2unit(block, block->unit_maxused);
- block->unit_used++;
- block->unit_maxused++;
- } else {
- head = block2unit(block, block->unit_unfill);
- block->unit_unfill = head->size;
- block->unit_used++;
- }
-
- if (block->unit_unfill == 0xFFFF && block->unit_maxused >= block->unit_count) {
- // ƒ†ƒjƒbƒg‚ðŽg‚¢‰Ê‚½‚µ‚½‚Ì‚ÅAunfillƒŠƒXƒg‚©‚çíœ
- if (block->unfill_prev == &block_head) {
- hash_unfill[ size_hash ] = block->unfill_next;
- } else {
- block->unfill_prev->unfill_next = block->unfill_next;
- }
- if (block->unfill_next) {
- block->unfill_next->unfill_prev = block->unfill_prev;
- }
- block->unfill_prev = NULL;
- }
+ struct block *block;
+ short size_hash = size2hash( size );
+ struct unit_head *head;
+
+ if (((long) size) < 0) {
+ ShowError("_mmalloc: %d\n", size);
+ return NULL;
+ }
+
+ if(size == 0) {
+ return NULL;
+ }
+ memmgr_usage_bytes += size;
+
+ /* ƒuƒƒbƒN’·‚ð’´‚¦‚é—̈æ‚ÌŠm•Û‚É‚ÍAmalloc() ‚ð—p‚¢‚é */
+ /* ‚»‚ÌÛAunit_head.block ‚É NULL ‚ð‘ã“ü‚µ‚Ä‹æ•Ê‚·‚é */
+ if(hash2size(size_hash) > BLOCK_DATA_SIZE - sizeof(struct unit_head)) {
+ struct unit_head_large* p = (struct unit_head_large*)MALLOC(sizeof(struct unit_head_large)+size,file,line,func);
+ if(p != NULL) {
+ p->size = size;
+ p->unit_head.block = NULL;
+ p->unit_head.size = 0;
+ p->unit_head.file = file;
+ p->unit_head.line = line;
+ p->prev = NULL;
+ if (unit_head_large_first == NULL)
+ p->next = NULL;
+ else {
+ unit_head_large_first->prev = p;
+ p->next = unit_head_large_first;
+ }
+ unit_head_large_first = p;
+ *(long*)((char*)p + sizeof(struct unit_head_large) - sizeof(long) + size) = 0xdeadbeaf;
+ return (char *)p + sizeof(struct unit_head_large) - sizeof(long);
+ } else {
+ ShowFatalError("Memory manager::memmgr_alloc failed (allocating %d+%d bytes at %s:%d).\n", sizeof(struct unit_head_large), size, file, line);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ /* “¯ˆêƒTƒCƒY‚̃uƒƒbƒN‚ªŠm•Û‚³‚ê‚Ä‚¢‚È‚¢ŽžAV‚½‚ÉŠm•Û‚·‚é */
+ if(hash_unfill[size_hash]) {
+ block = hash_unfill[size_hash];
+ } else {
+ block = block_malloc(size_hash);
+ }
+
+ if( block->unit_unfill == 0xFFFF ) {
+ // freeςݗ̈悪Žc‚Á‚Ä‚¢‚È‚¢
+ memmgr_assert(block->unit_used < block->unit_count);
+ memmgr_assert(block->unit_used == block->unit_maxused);
+ head = block2unit(block, block->unit_maxused);
+ block->unit_used++;
+ block->unit_maxused++;
+ } else {
+ head = block2unit(block, block->unit_unfill);
+ block->unit_unfill = head->size;
+ block->unit_used++;
+ }
+
+ if( block->unit_unfill == 0xFFFF && block->unit_maxused >= block->unit_count) {
+ // ƒ†ƒjƒbƒg‚ðŽg‚¢‰Ê‚½‚µ‚½‚Ì‚ÅAunfillƒŠƒXƒg‚©‚çíœ
+ if( block->unfill_prev == &block_head) {
+ hash_unfill[ size_hash ] = block->unfill_next;
+ } else {
+ block->unfill_prev->unfill_next = block->unfill_next;
+ }
+ if( block->unfill_next ) {
+ block->unfill_next->unfill_prev = block->unfill_prev;
+ }
+ block->unfill_prev = NULL;
+ }
#ifdef DEBUG_MEMMGR
- {
- size_t i, sz = hash2size(size_hash);
- for (i=0; i<sz; i++) {
- if (((unsigned char *)head)[ sizeof(struct unit_head) - sizeof(long) + i] != 0xfd) {
- if (head->line != 0xfdfd) {
- ShowError("Memory manager: freed-data is changed. (freed in %s line %d)\n", head->file,head->line);
- } else {
- ShowError("Memory manager: not-allocated-data is changed.\n");
- }
- break;
- }
- }
- memset((char *)head + sizeof(struct unit_head) - sizeof(long), 0xcd, sz);
- }
+ {
+ size_t i, sz = hash2size( size_hash );
+ for( i=0; i<sz; i++ )
+ {
+ if( ((unsigned char*)head)[ sizeof(struct unit_head) - sizeof(long) + i] != 0xfd )
+ {
+ if( head->line != 0xfdfd )
+ {
+ ShowError("Memory manager: freed-data is changed. (freed in %s line %d)\n", head->file,head->line);
+ }
+ else
+ {
+ ShowError("Memory manager: not-allocated-data is changed.\n");
+ }
+ break;
+ }
+ }
+ memset( (char *)head + sizeof(struct unit_head) - sizeof(long), 0xcd, sz );
+ }
#endif
- head->block = block;
- head->file = file;
- head->line = line;
- head->size = (unsigned short)size;
- *(long *)((char *)head + sizeof(struct unit_head) - sizeof(long) + size) = 0xdeadbeaf;
- return (char *)head + sizeof(struct unit_head) - sizeof(long);
+ head->block = block;
+ head->file = file;
+ head->line = line;
+ head->size = (unsigned short)size;
+ *(long*)((char*)head + sizeof(struct unit_head) - sizeof(long) + size) = 0xdeadbeaf;
+ return (char *)head + sizeof(struct unit_head) - sizeof(long);
}
-void *_mcalloc(size_t num, size_t size, const char *file, int line, const char *func)
+void* _mcalloc(size_t num, size_t size, const char *file, int line, const char *func )
{
- void *p = _mmalloc(num * size,file,line,func);
- memset(p,0,num * size);
- return p;
+ void *p = _mmalloc(num * size,file,line,func);
+ memset(p,0,num * size);
+ return p;
}
-void *_mrealloc(void *memblock, size_t size, const char *file, int line, const char *func)
+void* _mrealloc(void *memblock, size_t size, const char *file, int line, const char *func )
{
- size_t old_size;
- if (memblock == NULL) {
- return _mmalloc(size,file,line,func);
- }
-
- old_size = ((struct unit_head *)((char *)memblock - sizeof(struct unit_head) + sizeof(long)))->size;
- if (old_size == 0) {
- old_size = ((struct unit_head_large *)((char *)memblock - sizeof(struct unit_head_large) + sizeof(long)))->size;
- }
- if (old_size > size) {
- // ƒTƒCƒYk¬ -> ‚»‚Ì‚Ü‚Ü•Ô‚·iŽè”²‚«j
- return memblock;
- } else {
- // ƒTƒCƒYŠg‘å
- void *p = _mmalloc(size,file,line,func);
- if (p != NULL) {
- memcpy(p,memblock,old_size);
- }
- _mfree(memblock,file,line,func);
- return p;
- }
+ size_t old_size;
+ if(memblock == NULL) {
+ return _mmalloc(size,file,line,func);
+ }
+
+ old_size = ((struct unit_head *)((char *)memblock - sizeof(struct unit_head) + sizeof(long)))->size;
+ if( old_size == 0 ) {
+ old_size = ((struct unit_head_large *)((char *)memblock - sizeof(struct unit_head_large) + sizeof(long)))->size;
+ }
+ if(old_size > size) {
+ // ƒTƒCƒYk¬ -> ‚»‚Ì‚Ü‚Ü•Ô‚·iŽè”²‚«j
+ return memblock;
+ } else {
+ // ƒTƒCƒYŠg‘å
+ void *p = _mmalloc(size,file,line,func);
+ if(p != NULL) {
+ memcpy(p,memblock,old_size);
+ }
+ _mfree(memblock,file,line,func);
+ return p;
+ }
}
-char *_mstrdup(const char *p, const char *file, int line, const char *func)
+char* _mstrdup(const char *p, const char *file, int line, const char *func )
{
- if (p == NULL) {
- return NULL;
- } else {
- size_t len = strlen(p);
- char *string = (char *)_mmalloc(len + 1,file,line,func);
- memcpy(string,p,len+1);
- return string;
- }
+ if(p == NULL) {
+ return NULL;
+ } else {
+ size_t len = strlen(p);
+ char *string = (char *)_mmalloc(len + 1,file,line,func);
+ memcpy(string,p,len+1);
+ return string;
+ }
}
-void _mfree(void *ptr, const char *file, int line, const char *func)
+void _mfree(void *ptr, const char *file, int line, const char *func )
{
- struct unit_head *head;
-
- if (ptr == NULL)
- return;
-
- head = (struct unit_head *)((char *)ptr - sizeof(struct unit_head) + sizeof(long));
- if (head->size == 0) {
- /* malloc() ‚Å’¼‚ÉŠm•Û‚³‚ꂽ—̈æ */
- struct unit_head_large *head_large = (struct unit_head_large *)((char *)ptr - sizeof(struct unit_head_large) + sizeof(long));
- if (
- *(long *)((char *)head_large + sizeof(struct unit_head_large) - sizeof(long) + head_large->size)
- != 0xdeadbeaf) {
- ShowError("Memory manager: args of aFree 0x%p is overflowed pointer %s line %d\n", ptr, file, line);
- } else {
- head->size = 0xFFFF;
- 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;
- }
- memmgr_usage_bytes -= head_large->size;
+ struct unit_head *head;
+
+ if (ptr == NULL)
+ return;
+
+ head = (struct unit_head *)((char *)ptr - sizeof(struct unit_head) + sizeof(long));
+ if(head->size == 0) {
+ /* malloc() ‚Å’¼‚ÉŠm•Û‚³‚ꂽ—̈æ */
+ struct unit_head_large *head_large = (struct unit_head_large *)((char *)ptr - sizeof(struct unit_head_large) + sizeof(long));
+ if(
+ *(long*)((char*)head_large + sizeof(struct unit_head_large) - sizeof(long) + head_large->size)
+ != 0xdeadbeaf)
+ {
+ ShowError("Memory manager: args of aFree 0x%p is overflowed pointer %s line %d\n", ptr, file, line);
+ } else {
+ head->size = 0xFFFF;
+ 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;
+ }
+ memmgr_usage_bytes -= head_large->size;
#ifdef DEBUG_MEMMGR
- // set freed memory to 0xfd
- memset(ptr, 0xfd, head_large->size);
+ // set freed memory to 0xfd
+ memset(ptr, 0xfd, head_large->size);
#endif
- FREE(head_large,file,line,func);
- }
- } else {
- /* ƒ†ƒjƒbƒg‰ð•ú */
- struct block *block = head->block;
- if ((char *)head - (char *)block > sizeof(struct block)) {
- ShowError("Memory manager: args of aFree 0x%p is invalid pointer %s line %d\n", ptr, file, line);
- } else if (head->block == NULL) {
- ShowError("Memory manager: args of aFree 0x%p is freed pointer %s:%d@%s\n", ptr, file, line, func);
- } else if (*(long *)((char *)head + sizeof(struct unit_head) - sizeof(long) + head->size) != 0xdeadbeaf) {
- ShowError("Memory manager: args of aFree 0x%p is overflowed pointer %s line %d\n", ptr, file, line);
- } else {
- memmgr_usage_bytes -= head->size;
- head->block = NULL;
+ FREE(head_large,file,line,func);
+ }
+ } else {
+ /* ƒ†ƒjƒbƒg‰ð•ú */
+ struct block *block = head->block;
+ if( (char*)head - (char*)block > sizeof(struct block) ) {
+ ShowError("Memory manager: args of aFree 0x%p is invalid pointer %s line %d\n", ptr, file, line);
+ } else if(head->block == NULL) {
+ ShowError("Memory manager: args of aFree 0x%p is freed pointer %s:%d@%s\n", ptr, file, line, func);
+ } else if(*(long*)((char*)head + sizeof(struct unit_head) - sizeof(long) + head->size) != 0xdeadbeaf) {
+ ShowError("Memory manager: args of aFree 0x%p is overflowed pointer %s line %d\n", ptr, file, line);
+ } else {
+ memmgr_usage_bytes -= head->size;
+ head->block = NULL;
#ifdef DEBUG_MEMMGR
- memset(ptr, 0xfd, block->unit_size - sizeof(struct unit_head) + sizeof(long));
- head->file = file;
- head->line = line;
+ memset(ptr, 0xfd, block->unit_size - sizeof(struct unit_head) + sizeof(long) );
+ head->file = file;
+ head->line = line;
#endif
- memmgr_assert(block->unit_used > 0);
- if (--block->unit_used == 0) {
- /* ƒuƒƒbƒN‚̉ð•ú */
- block_free(block);
- } else {
- if (block->unfill_prev == NULL) {
- // unfill ƒŠƒXƒg‚ɒljÁ
- if (hash_unfill[ block->unit_hash ]) {
- hash_unfill[ block->unit_hash ]->unfill_prev = block;
- }
- block->unfill_prev = &block_head;
- block->unfill_next = hash_unfill[ block->unit_hash ];
- hash_unfill[ block->unit_hash ] = block;
- }
- head->size = block->unit_unfill;
- block->unit_unfill = (unsigned short)(((uintptr_t)head - (uintptr_t)block->data) / block->unit_size);
- }
- }
- }
+ memmgr_assert( block->unit_used > 0 );
+ if(--block->unit_used == 0) {
+ /* ƒuƒƒbƒN‚̉ð•ú */
+ block_free(block);
+ } else {
+ if( block->unfill_prev == NULL) {
+ // unfill ƒŠƒXƒg‚ɒljÁ
+ if( hash_unfill[ block->unit_hash ] ) {
+ hash_unfill[ block->unit_hash ]->unfill_prev = block;
+ }
+ block->unfill_prev = &block_head;
+ block->unfill_next = hash_unfill[ block->unit_hash ];
+ hash_unfill[ block->unit_hash ] = block;
+ }
+ head->size = block->unit_unfill;
+ block->unit_unfill = (unsigned short)(((uintptr_t)head - (uintptr_t)block->data) / block->unit_size);
+ }
+ }
+ }
}
/* ƒuƒƒbƒN‚ðŠm•Û‚·‚é */
-static struct block *block_malloc(unsigned short hash) {
- int i;
- struct block *p;
- if (hash_unfill[0] != NULL) {
- /* ƒuƒƒbƒN—p‚̗̈æ‚ÍŠm•ÛÏ‚Ý */
- p = hash_unfill[0];
- hash_unfill[0] = hash_unfill[0]->unfill_next;
- } else {
- /* ƒuƒƒbƒN—p‚̗̈æ‚ðV‚½‚ÉŠm•Û‚·‚é */
- p = (struct block *)MALLOC(sizeof(struct block) * (BLOCK_ALLOC), __FILE__, __LINE__, __func__);
- if (p == NULL) {
- ShowFatalError("Memory manager::block_alloc failed.\n");
- exit(EXIT_FAILURE);
- }
-
- if (block_first == NULL) {
- /* ‰‰ñŠm•Û */
- block_first = p;
- } else {
- block_last->block_next = p;
- }
- block_last = &p[BLOCK_ALLOC - 1];
- block_last->block_next = NULL;
- /* ƒuƒƒbƒN‚ð˜AŒ‹‚³‚¹‚é */
- for (i=0; i<BLOCK_ALLOC; i++) {
- if (i != 0) {
- // p[0] ‚Í‚±‚ê‚©‚çŽg‚¤‚̂ŃŠƒ“ƒN‚ɂ͉Á‚¦‚È‚¢
- p[i].unfill_next = hash_unfill[0];
- hash_unfill[0] = &p[i];
- p[i].unfill_prev = NULL;
- p[i].unit_used = 0;
- }
- if (i != BLOCK_ALLOC -1) {
- p[i].block_next = &p[i+1];
- }
- }
- }
-
- // unfill ‚ɒljÁ
- memmgr_assert(hash_unfill[ hash ] == NULL);
- hash_unfill[ hash ] = p;
- p->unfill_prev = &block_head;
- p->unfill_next = NULL;
- p->unit_size = (unsigned short)(hash2size(hash) + sizeof(struct unit_head));
- p->unit_hash = hash;
- p->unit_count = BLOCK_DATA_SIZE / p->unit_size;
- p->unit_used = 0;
- p->unit_unfill = 0xFFFF;
- p->unit_maxused = 0;
+static struct block* block_malloc(unsigned short hash)
+{
+ int i;
+ struct block *p;
+ if(hash_unfill[0] != NULL) {
+ /* ƒuƒƒbƒN—p‚̗̈æ‚ÍŠm•ÛÏ‚Ý */
+ p = hash_unfill[0];
+ hash_unfill[0] = hash_unfill[0]->unfill_next;
+ } else {
+ /* ƒuƒƒbƒN—p‚̗̈æ‚ðV‚½‚ÉŠm•Û‚·‚é */
+ p = (struct block*)MALLOC(sizeof(struct block) * (BLOCK_ALLOC), __FILE__, __LINE__, __func__ );
+ if(p == NULL) {
+ ShowFatalError("Memory manager::block_alloc failed.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if(block_first == NULL) {
+ /* ‰‰ñŠm•Û */
+ block_first = p;
+ } else {
+ block_last->block_next = p;
+ }
+ block_last = &p[BLOCK_ALLOC - 1];
+ block_last->block_next = NULL;
+ /* ƒuƒƒbƒN‚ð˜AŒ‹‚³‚¹‚é */
+ for(i=0;i<BLOCK_ALLOC;i++) {
+ if(i != 0) {
+ // p[0] ‚Í‚±‚ê‚©‚çŽg‚¤‚̂ŃŠƒ“ƒN‚ɂ͉Á‚¦‚È‚¢
+ p[i].unfill_next = hash_unfill[0];
+ hash_unfill[0] = &p[i];
+ p[i].unfill_prev = NULL;
+ p[i].unit_used = 0;
+ }
+ if(i != BLOCK_ALLOC -1) {
+ p[i].block_next = &p[i+1];
+ }
+ }
+ }
+
+ // unfill ‚ɒljÁ
+ memmgr_assert(hash_unfill[ hash ] == NULL);
+ hash_unfill[ hash ] = p;
+ p->unfill_prev = &block_head;
+ p->unfill_next = NULL;
+ p->unit_size = (unsigned short)(hash2size( hash ) + sizeof(struct unit_head));
+ p->unit_hash = hash;
+ p->unit_count = BLOCK_DATA_SIZE / p->unit_size;
+ p->unit_used = 0;
+ p->unit_unfill = 0xFFFF;
+ p->unit_maxused = 0;
#ifdef DEBUG_MEMMGR
- memset(p->data, 0xfd, sizeof(p->data));
+ memset( p->data, 0xfd, sizeof(p->data) );
#endif
- return p;
+ return p;
}
-static void block_free(struct block *p)
+static void block_free(struct block* p)
{
- if (p->unfill_prev) {
- if (p->unfill_prev == &block_head) {
- hash_unfill[ p->unit_hash ] = p->unfill_next;
- } else {
- p->unfill_prev->unfill_next = p->unfill_next;
- }
- if (p->unfill_next) {
- p->unfill_next->unfill_prev = p->unfill_prev;
- }
- p->unfill_prev = NULL;
- }
-
- p->unfill_next = hash_unfill[0];
- hash_unfill[0] = p;
+ if( p->unfill_prev ) {
+ if( p->unfill_prev == &block_head) {
+ hash_unfill[ p->unit_hash ] = p->unfill_next;
+ } else {
+ p->unfill_prev->unfill_next = p->unfill_next;
+ }
+ if( p->unfill_next ) {
+ p->unfill_next->unfill_prev = p->unfill_prev;
+ }
+ p->unfill_prev = NULL;
+ }
+
+ p->unfill_next = hash_unfill[0];
+ hash_unfill[0] = p;
}
-size_t memmgr_usage(void)
+size_t memmgr_usage (void)
{
- return memmgr_usage_bytes / 1024;
+ return memmgr_usage_bytes / 1024;
}
#ifdef LOG_MEMMGR
static char memmer_logfile[128];
static FILE *log_fp;
-static void memmgr_log(char *buf)
+static void memmgr_log (char *buf)
{
- if (!log_fp) {
- time_t raw;
- struct tm *t;
-
- log_fp = fopen(memmer_logfile,"at");
- if (!log_fp) log_fp = stdout;
-
- time(&raw);
- t = localtime(&raw);
- fprintf(log_fp, "\nMemory manager: Memory leaks found at %d/%02d/%02d %02dh%02dm%02ds (Revision %s).\n",
- (t->tm_year+1900), (t->tm_mon+1), t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, get_svn_revision());
- }
- fprintf(log_fp, "%s", buf);
- return;
+ if( !log_fp )
+ {
+ time_t raw;
+ struct tm* t;
+
+ log_fp = fopen(memmer_logfile,"at");
+ if (!log_fp) log_fp = stdout;
+
+ time(&raw);
+ t = localtime(&raw);
+ fprintf(log_fp, "\nMemory manager: Memory leaks found at %d/%02d/%02d %02dh%02dm%02ds (Revision %s).\n",
+ (t->tm_year+1900), (t->tm_mon+1), t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, get_svn_revision());
+ }
+ fprintf(log_fp, "%s", buf);
+ return;
}
#endif /* LOG_MEMMGR */
@@ -545,105 +553,107 @@ static void memmgr_log(char *buf)
///
/// @param ptr Pointer to the memory
/// @return true if the memory is active
-bool memmgr_verify(void *ptr)
+bool memmgr_verify(void* ptr)
{
- struct block *block = block_first;
- struct unit_head_large *large = unit_head_large_first;
-
- if (ptr == NULL)
- return false;// never valid
-
- // search small blocks
- while (block) {
- if ((char *)ptr >= (char *)block && (char *)ptr < ((char *)block) + sizeof(struct block)) {
- // found memory block
- if (block->unit_used && (char *)ptr >= block->data) {
- // memory block is being used and ptr points to a sub-unit
- size_t i = (size_t)((char *)ptr - block->data)/block->unit_size;
- struct unit_head *head = block2unit(block, i);
- if (i < block->unit_maxused && head->block != NULL) {
- // memory unit is allocated, check if ptr points to the usable part
- return ((char *)ptr >= ((char *)head) + sizeof(struct unit_head) - sizeof(long)
- && (char *)ptr < ((char *)head) + sizeof(struct unit_head) - sizeof(long) + head->size);
- }
- }
- return false;
- }
- block = block->block_next;
- }
-
- // search large blocks
- while (large) {
- if ((char *)ptr >= (char *)large && (char *)ptr < ((char *)large) + large->size) {
- // found memory block, check if ptr points to the usable part
- return ((char *)ptr >= ((char *)large) + sizeof(struct unit_head_large) - sizeof(long)
- && (char *)ptr < ((char *)large) + sizeof(struct unit_head_large) - sizeof(long) + large->size);
- }
- large = large->next;
- }
- return false;
+ struct block* block = block_first;
+ struct unit_head_large* large = unit_head_large_first;
+
+ if( ptr == NULL )
+ return false;// never valid
+
+ // search small blocks
+ while( block )
+ {
+ if( (char*)ptr >= (char*)block && (char*)ptr < ((char*)block) + sizeof(struct block) )
+ {// found memory block
+ if( block->unit_used && (char*)ptr >= block->data )
+ {// memory block is being used and ptr points to a sub-unit
+ size_t i = (size_t)((char*)ptr - block->data)/block->unit_size;
+ struct unit_head* head = block2unit(block, i);
+ if( i < block->unit_maxused && head->block != NULL )
+ {// memory unit is allocated, check if ptr points to the usable part
+ return ( (char*)ptr >= ((char*)head) + sizeof(struct unit_head) - sizeof(long)
+ && (char*)ptr < ((char*)head) + sizeof(struct unit_head) - sizeof(long) + head->size );
+ }
+ }
+ return false;
+ }
+ block = block->block_next;
+ }
+
+ // search large blocks
+ while( large )
+ {
+ if( (char*)ptr >= (char*)large && (char*)ptr < ((char*)large) + large->size )
+ {// found memory block, check if ptr points to the usable part
+ return ( (char*)ptr >= ((char*)large) + sizeof(struct unit_head_large) - sizeof(long)
+ && (char*)ptr < ((char*)large) + sizeof(struct unit_head_large) - sizeof(long) + large->size );
+ }
+ large = large->next;
+ }
+ return false;
}
-static void memmgr_final(void)
+static void memmgr_final (void)
{
- struct block *block = block_first;
- struct unit_head_large *large = unit_head_large_first;
+ struct block *block = block_first;
+ struct unit_head_large *large = unit_head_large_first;
#ifdef LOG_MEMMGR
- int count = 0;
+ int count = 0;
#endif /* LOG_MEMMGR */
- while (block) {
- if (block->unit_used) {
- int i;
- for (i = 0; i < block->unit_maxused; i++) {
- struct unit_head *head = block2unit(block, i);
- if (head->block != NULL) {
- char *ptr = (char *)head + sizeof(struct unit_head) - sizeof(long);
+ while (block) {
+ if (block->unit_used) {
+ int i;
+ for (i = 0; i < block->unit_maxused; i++) {
+ struct unit_head *head = block2unit(block, i);
+ if(head->block != NULL) {
+ char* ptr = (char *)head + sizeof(struct unit_head) - sizeof(long);
#ifdef LOG_MEMMGR
- char buf[1024];
- sprintf(buf,
- "%04d : %s line %d size %lu address 0x%p\n", ++count,
- head->file, head->line, (unsigned long)head->size, ptr);
- memmgr_log(buf);
+ char buf[1024];
+ sprintf (buf,
+ "%04d : %s line %d size %lu address 0x%p\n", ++count,
+ head->file, head->line, (unsigned long)head->size, ptr);
+ memmgr_log (buf);
#endif /* LOG_MEMMGR */
- // get block pointer and free it [celest]
- _mfree(ptr, ALC_MARK);
- }
- }
- }
- block = block->block_next;
- }
-
- while (large) {
- struct unit_head_large *large2;
+ // get block pointer and free it [celest]
+ _mfree(ptr, ALC_MARK);
+ }
+ }
+ }
+ block = block->block_next;
+ }
+
+ while(large) {
+ struct unit_head_large *large2;
#ifdef LOG_MEMMGR
- char buf[1024];
- sprintf(buf,
- "%04d : %s line %d size %lu address 0x%p\n", ++count,
- large->unit_head.file, large->unit_head.line, (unsigned long)large->size, &large->unit_head.checksum);
- memmgr_log(buf);
+ char buf[1024];
+ sprintf (buf,
+ "%04d : %s line %d size %lu address 0x%p\n", ++count,
+ large->unit_head.file, large->unit_head.line, (unsigned long)large->size, &large->unit_head.checksum);
+ memmgr_log (buf);
#endif /* LOG_MEMMGR */
- large2 = large->next;
- FREE(large,file,line,func);
- large = large2;
- }
+ large2 = large->next;
+ FREE(large,file,line,func);
+ large = large2;
+ }
#ifdef LOG_MEMMGR
- if (count == 0) {
- ShowInfo("Memory manager: No memory leaks found.\n");
- } else {
- ShowWarning("Memory manager: Memory leaks found and fixed.\n");
- fclose(log_fp);
- }
+ if(count == 0) {
+ ShowInfo("Memory manager: No memory leaks found.\n");
+ } else {
+ ShowWarning("Memory manager: Memory leaks found and fixed.\n");
+ fclose(log_fp);
+ }
#endif /* LOG_MEMMGR */
}
-static void memmgr_init(void)
+static void memmgr_init (void)
{
#ifdef LOG_MEMMGR
- sprintf(memmer_logfile, "log/%s.leaks", SERVER_NAME);
- ShowStatus("Memory manager initialised: "CL_WHITE"%s"CL_RESET"\n", memmer_logfile);
- memset(hash_unfill, 0, sizeof(hash_unfill));
+ sprintf(memmer_logfile, "log/%s.leaks", SERVER_NAME);
+ ShowStatus("Memory manager initialised: "CL_WHITE"%s"CL_RESET"\n", memmer_logfile);
+ memset(hash_unfill, 0, sizeof(hash_unfill));
#endif /* LOG_MEMMGR */
}
#endif /* USE_MEMMGR */
@@ -658,51 +668,51 @@ static void memmgr_init(void)
/// Tests the memory for errors and memory leaks.
void malloc_memory_check(void)
{
- MEMORY_CHECK();
+ MEMORY_CHECK();
}
/// Returns true if a pointer is valid.
/// The check is best-effort, false positives are possible.
-bool malloc_verify_ptr(void *ptr)
+bool malloc_verify_ptr(void* ptr)
{
#ifdef USE_MEMMGR
- return memmgr_verify(ptr) && MEMORY_VERIFY(ptr);
+ return memmgr_verify(ptr) && MEMORY_VERIFY(ptr);
#else
- return MEMORY_VERIFY(ptr);
+ return MEMORY_VERIFY(ptr);
#endif
}
-size_t malloc_usage(void)
+size_t malloc_usage (void)
{
#ifdef USE_MEMMGR
- return memmgr_usage();
+ return memmgr_usage ();
#else
- return MEMORY_USAGE();
+ return MEMORY_USAGE();
#endif
}
-void malloc_final(void)
+void malloc_final (void)
{
#ifdef USE_MEMMGR
- memmgr_final();
+ memmgr_final ();
#endif
- MEMORY_CHECK();
+ MEMORY_CHECK();
}
-void malloc_init(void)
+void malloc_init (void)
{
#if defined(DMALLOC) && defined(CYGWIN)
- // http://dmalloc.com/docs/latest/online/dmalloc_19.html
- dmalloc_debug_setup(getenv("DMALLOC_OPTIONS"));
+ // http://dmalloc.com/docs/latest/online/dmalloc_19.html
+ dmalloc_debug_setup(getenv("DMALLOC_OPTIONS"));
#endif
#ifdef GCOLLECT
- // don't garbage collect, only report inaccessible memory that was not deallocated
- GC_find_leak = 1;
- GC_INIT();
+ // don't garbage collect, only report inaccessible memory that was not deallocated
+ GC_find_leak = 1;
+ GC_INIT();
#endif
#ifdef USE_MEMMGR
- memmgr_init();
+ memmgr_init ();
#endif
}
diff --git a/src/common/malloc.h b/src/common/malloc.h
index 58dcee6d7..6b4e8e5c4 100644
--- a/src/common/malloc.h
+++ b/src/common/malloc.h
@@ -33,31 +33,31 @@
#undef LOG_MEMMGR
#endif
-# define aMalloc(n) _mmalloc(n,ALC_MARK)
-# define aCalloc(m,n) _mcalloc(m,n,ALC_MARK)
-# define aRealloc(p,n) _mrealloc(p,n,ALC_MARK)
-# define aStrdup(p) _mstrdup(p,ALC_MARK)
-# define aFree(p) _mfree(p,ALC_MARK)
-
-void *_mmalloc(size_t size, const char *file, int line, const char *func);
-void *_mcalloc(size_t num, size_t size, const char *file, int line, const char *func);
-void *_mrealloc(void *p, size_t size, const char *file, int line, const char *func);
-char *_mstrdup(const char *p, const char *file, int line, const char *func);
-void _mfree(void *p, const char *file, int line, const char *func);
+# define aMalloc(n) _mmalloc(n,ALC_MARK)
+# define aCalloc(m,n) _mcalloc(m,n,ALC_MARK)
+# define aRealloc(p,n) _mrealloc(p,n,ALC_MARK)
+# define aStrdup(p) _mstrdup(p,ALC_MARK)
+# define aFree(p) _mfree(p,ALC_MARK)
+
+ void* _mmalloc (size_t size, const char *file, int line, const char *func);
+ void* _mcalloc (size_t num, size_t size, const char *file, int line, const char *func);
+ void* _mrealloc (void *p, size_t size, const char *file, int line, const char *func);
+ char* _mstrdup (const char *p, const char *file, int line, const char *func);
+ void _mfree (void *p, const char *file, int line, const char *func);
#else
-# 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 aStrdup(p) aStrdup_(p,ALC_MARK)
-# define aFree(p) aFree_(p,ALC_MARK)
+# 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 aStrdup(p) aStrdup_(p,ALC_MARK)
+# define aFree(p) aFree_(p,ALC_MARK)
-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);
-char *aStrdup_(const char *p, const char *file, int line, const char *func);
-void aFree_(void *p, 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);
+ char* aStrdup_ (const char *p, const char *file, int line, const char *func);
+ void aFree_ (void *p, const char *file, int line, const char *func);
#endif
@@ -66,13 +66,13 @@ void aFree_(void *p, const char *file, int line, const char *func);
#ifdef __GNUC__ // GCC has variable length arrays
-#define CREATE_BUFFER(name, type, size) type name[size]
-#define DELETE_BUFFER(name)
+ #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)
+ #define CREATE_BUFFER(name, type, size) type *name = (type *) aCalloc (size, sizeof(type))
+ #define DELETE_BUFFER(name) aFree(name)
#endif
@@ -84,9 +84,9 @@ void aFree_(void *p, const char *file, int line, const char *func);
////////////////////////////////////////////////
void malloc_memory_check(void);
-bool malloc_verify_ptr(void *ptr);
-size_t malloc_usage(void);
-void malloc_init(void);
-void malloc_final(void);
+bool malloc_verify_ptr(void* ptr);
+size_t malloc_usage (void);
+void malloc_init (void);
+void malloc_final (void);
#endif /* _MALLOC_H_ */
diff --git a/src/common/mapindex.c b/src/common/mapindex.c
index 62d14590e..d46047833 100644
--- a/src/common/mapindex.c
+++ b/src/common/mapindex.c
@@ -12,7 +12,7 @@
#include <stdlib.h>
struct _indexes {
- char name[MAP_NAME_LENGTH]; //Stores map name
+ char name[MAP_NAME_LENGTH]; //Stores map name
} indexes[MAX_MAPINDEX];
int max_index = 0;
@@ -23,158 +23,161 @@ char mapindex_cfgfile[80] = "db/map_index.txt";
/// Retrieves the map name from 'string' (removing .gat extension if present).
/// Result gets placed either into 'buf' or in a static local buffer.
-const char *mapindex_getmapname(const char *string, char *output)
+const char* mapindex_getmapname(const char* string, char* output)
{
- static char buf[MAP_NAME_LENGTH];
- char *dest = (output != NULL) ? output : buf;
-
- size_t len = strnlen(string, MAP_NAME_LENGTH_EXT);
- if (len == MAP_NAME_LENGTH_EXT) {
- ShowWarning("(mapindex_normalize_name) Map name '%*s' is too long!\n", 2*MAP_NAME_LENGTH_EXT, string);
- len--;
- }
- if (len >= 4 && stricmp(&string[len-4], ".gat") == 0)
- len -= 4; // strip .gat extension
-
- len = min(len, MAP_NAME_LENGTH-1);
- strncpy(dest, string, len+1);
- memset(&dest[len], '\0', MAP_NAME_LENGTH-len);
-
- return dest;
+ static char buf[MAP_NAME_LENGTH];
+ char* dest = (output != NULL) ? output : buf;
+
+ size_t len = strnlen(string, MAP_NAME_LENGTH_EXT);
+ if (len == MAP_NAME_LENGTH_EXT) {
+ ShowWarning("(mapindex_normalize_name) Map name '%*s' is too long!\n", 2*MAP_NAME_LENGTH_EXT, string);
+ len--;
+ }
+ if (len >= 4 && stricmp(&string[len-4], ".gat") == 0)
+ len -= 4; // strip .gat extension
+
+ len = min(len, MAP_NAME_LENGTH-1);
+ strncpy(dest, string, len+1);
+ memset(&dest[len], '\0', MAP_NAME_LENGTH-len);
+
+ return dest;
}
/// Retrieves the map name from 'string' (adding .gat extension if not already present).
/// Result gets placed either into 'buf' or in a static local buffer.
-const char *mapindex_getmapname_ext(const char *string, char *output)
+const char* mapindex_getmapname_ext(const char* string, char* output)
{
- static char buf[MAP_NAME_LENGTH_EXT];
- char *dest = (output != NULL) ? output : buf;
+ static char buf[MAP_NAME_LENGTH_EXT];
+ char* dest = (output != NULL) ? output : buf;
- size_t len;
+ size_t len;
- strcpy(buf,string);
- sscanf(string,"%*[^#]%*[#]%s",buf);
+ strcpy(buf,string);
+ sscanf(string,"%*[^#]%*[#]%s",buf);
- len = safestrnlen(buf, MAP_NAME_LENGTH);
+ len = safestrnlen(buf, MAP_NAME_LENGTH);
- if (len == MAP_NAME_LENGTH) {
- ShowWarning("(mapindex_normalize_name) Map name '%*s' is too long!\n", 2*MAP_NAME_LENGTH, buf);
- len--;
- }
- strncpy(dest, buf, len+1);
+ if (len == MAP_NAME_LENGTH) {
+ ShowWarning("(mapindex_normalize_name) Map name '%*s' is too long!\n", 2*MAP_NAME_LENGTH, buf);
+ len--;
+ }
+ strncpy(dest, buf, len+1);
- if (len < 4 || stricmp(&dest[len-4], ".gat") != 0) {
- strcpy(&dest[len], ".gat");
- len += 4; // add .gat extension
- }
+ if (len < 4 || stricmp(&dest[len-4], ".gat") != 0) {
+ strcpy(&dest[len], ".gat");
+ len += 4; // add .gat extension
+ }
- memset(&dest[len], '\0', MAP_NAME_LENGTH_EXT-len);
-
- return dest;
+ memset(&dest[len], '\0', MAP_NAME_LENGTH_EXT-len);
+
+ return dest;
}
/// Adds a map to the specified index
/// Returns 1 if successful, 0 oherwise
-int mapindex_addmap(int index, const char *name)
+int mapindex_addmap(int index, const char* name)
{
- char map_name[MAP_NAME_LENGTH];
-
- if (index == -1) {
- for (index = 1; index < max_index; index++) {
- //if (strcmp(indexes[index].name,"#CLEARED#")==0)
- if (indexes[index].name[0] == '\0')
- break;
- }
- }
-
- if (index < 0 || index >= MAX_MAPINDEX) {
- ShowError("(mapindex_add) Map index (%d) for \"%s\" out of range (max is %d)\n", index, name, MAX_MAPINDEX);
- return 0;
- }
-
- mapindex_getmapname(name, map_name);
-
- if (map_name[0] == '\0') {
- ShowError("(mapindex_add) Cannot add maps with no name.\n");
- return 0;
- }
-
- if (strlen(map_name) >= MAP_NAME_LENGTH) {
- ShowError("(mapindex_add) Map name %s is too long. Maps are limited to %d characters.\n", map_name, MAP_NAME_LENGTH);
- return 0;
- }
-
- if (mapindex_exists(index))
- ShowWarning("(mapindex_add) Overriding index %d: map \"%s\" -> \"%s\"\n", index, indexes[index].name, map_name);
-
- safestrncpy(indexes[index].name, map_name, MAP_NAME_LENGTH);
- if (max_index <= index)
- max_index = index+1;
-
- return index;
+ char map_name[MAP_NAME_LENGTH];
+
+ if (index == -1){
+ for (index = 1; index < max_index; index++)
+ {
+ //if (strcmp(indexes[index].name,"#CLEARED#")==0)
+ if (indexes[index].name[0] == '\0')
+ break;
+ }
+ }
+
+ if (index < 0 || index >= MAX_MAPINDEX) {
+ ShowError("(mapindex_add) Map index (%d) for \"%s\" out of range (max is %d)\n", index, name, MAX_MAPINDEX);
+ return 0;
+ }
+
+ mapindex_getmapname(name, map_name);
+
+ if (map_name[0] == '\0') {
+ ShowError("(mapindex_add) Cannot add maps with no name.\n");
+ return 0;
+ }
+
+ if (strlen(map_name) >= MAP_NAME_LENGTH) {
+ ShowError("(mapindex_add) Map name %s is too long. Maps are limited to %d characters.\n", map_name, MAP_NAME_LENGTH);
+ return 0;
+ }
+
+ if (mapindex_exists(index))
+ ShowWarning("(mapindex_add) Overriding index %d: map \"%s\" -> \"%s\"\n", index, indexes[index].name, map_name);
+
+ safestrncpy(indexes[index].name, map_name, MAP_NAME_LENGTH);
+ if (max_index <= index)
+ max_index = index+1;
+
+ return index;
}
-unsigned short mapindex_name2id(const char *name)
+unsigned short mapindex_name2id(const char* name)
{
- //TODO: Perhaps use a db to speed this up? [Skotlex]
- int i;
-
- char map_name[MAP_NAME_LENGTH];
- mapindex_getmapname(name, map_name);
-
- for (i = 1; i < max_index; i++) {
- if (strcmpi(indexes[i].name,map_name)==0)
- return i;
- }
- ShowDebug("mapindex_name2id: Map \"%s\" not found in index list!\n", map_name);
- return 0;
+ //TODO: Perhaps use a db to speed this up? [Skotlex]
+ int i;
+
+ char map_name[MAP_NAME_LENGTH];
+ mapindex_getmapname(name, map_name);
+
+ for (i = 1; i < max_index; i++)
+ {
+ if (strcmpi(indexes[i].name,map_name)==0)
+ return i;
+ }
+ ShowDebug("mapindex_name2id: Map \"%s\" not found in index list!\n", map_name);
+ return 0;
}
-const char *mapindex_id2name(unsigned short id)
+const char* mapindex_id2name(unsigned short id)
{
- if (id > MAX_MAPINDEX || !mapindex_exists(id)) {
- ShowDebug("mapindex_id2name: Requested name for non-existant map index [%d] in cache.\n", id);
- return indexes[0].name; // dummy empty string so that the callee doesn't crash
- }
- return indexes[id].name;
+ if (id > MAX_MAPINDEX || !mapindex_exists(id)) {
+ ShowDebug("mapindex_id2name: Requested name for non-existant map index [%d] in cache.\n", id);
+ return indexes[0].name; // dummy empty string so that the callee doesn't crash
+ }
+ return indexes[id].name;
}
void mapindex_init(void)
{
- FILE *fp;
- char line[1024];
- int last_index = -1;
- int index;
- char map_name[1024];
-
- memset(&indexes, 0, sizeof(indexes));
- fp=fopen(mapindex_cfgfile,"r");
- if (fp==NULL) {
- ShowFatalError("Unable to read mapindex config file %s!\n", mapindex_cfgfile);
- exit(EXIT_FAILURE); //Server can't really run without this file.
- }
- while (fgets(line, sizeof(line), fp)) {
- if (line[0] == '/' && line[1] == '/')
- continue;
-
- switch (sscanf(line, "%1023s\t%d", map_name, &index)) {
- case 1: //Map with no ID given, auto-assign
- index = last_index+1;
- case 2: //Map with ID given
- mapindex_addmap(index,map_name);
- break;
- default:
- continue;
- }
- last_index = index;
- }
- fclose(fp);
+ FILE *fp;
+ char line[1024];
+ int last_index = -1;
+ int index;
+ char map_name[1024];
+
+ memset (&indexes, 0, sizeof (indexes));
+ fp=fopen(mapindex_cfgfile,"r");
+ if(fp==NULL){
+ ShowFatalError("Unable to read mapindex config file %s!\n", mapindex_cfgfile);
+ exit(EXIT_FAILURE); //Server can't really run without this file.
+ }
+ while(fgets(line, sizeof(line), fp))
+ {
+ if(line[0] == '/' && line[1] == '/')
+ continue;
+
+ switch (sscanf(line, "%1023s\t%d", map_name, &index))
+ {
+ case 1: //Map with no ID given, auto-assign
+ index = last_index+1;
+ case 2: //Map with ID given
+ mapindex_addmap(index,map_name);
+ break;
+ default:
+ continue;
+ }
+ last_index = index;
+ }
+ fclose(fp);
}
-int mapindex_removemap(int index)
-{
- indexes[index].name[0] = '\0';
- return 0;
+int mapindex_removemap(int index){
+ indexes[index].name[0] = '\0';
+ return 0;
}
void mapindex_final(void)
diff --git a/src/common/mapindex.h b/src/common/mapindex.h
index 4889d20f1..75cb254c0 100644
--- a/src/common/mapindex.h
+++ b/src/common/mapindex.h
@@ -47,14 +47,14 @@ extern char mapindex_cfgfile[80];
#define MAP_MALAYA "malaya"
#define MAP_ECLAGE "eclage"
-const char *mapindex_getmapname(const char *string, char *output);
-const char *mapindex_getmapname_ext(const char *string, char *output);
-unsigned short mapindex_name2id(const char *);
-const char *mapindex_id2name(unsigned short);
+const char* mapindex_getmapname(const char* string, char* output);
+const char* mapindex_getmapname_ext(const char* string, char* output);
+unsigned short mapindex_name2id(const char*);
+const char* mapindex_id2name(unsigned short);
void mapindex_init(void);
void mapindex_final(void);
-int mapindex_addmap(int index, const char *name);
+int mapindex_addmap(int index, const char* name);
int mapindex_removemap(int index);
#endif /* _MAPINDEX_H_ */
diff --git a/src/common/md5calc.c b/src/common/md5calc.c
index bd4b59ad0..05fde42cc 100644
--- a/src/common/md5calc.c
+++ b/src/common/md5calc.c
@@ -21,22 +21,22 @@ static unsigned int *pX;
// String Table
static const unsigned int T[] = {
- 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, //0
- 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, //4
- 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, //8
- 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, //12
- 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, //16
- 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8, //20
- 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, //24
- 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, //28
- 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, //32
- 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, //36
- 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05, //40
- 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, //44
- 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, //48
- 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, //52
- 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, //56
- 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 //60
+ 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, //0
+ 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, //4
+ 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, //8
+ 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, //12
+ 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, //16
+ 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8, //20
+ 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, //24
+ 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, //28
+ 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, //32
+ 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, //36
+ 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05, //40
+ 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, //44
+ 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, //48
+ 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, //52
+ 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, //56
+ 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 //60
};
// ROTATE_LEFT The left is made to rotate x [ n-bit ]. This is diverted as it is from RFC.
@@ -45,244 +45,196 @@ static const unsigned int T[] = {
// The function used for other calculation
static unsigned int F(unsigned int X, unsigned int Y, unsigned int Z)
{
- return (X & Y) | (~X & Z);
+ return (X & Y) | (~X & Z);
}
static unsigned int G(unsigned int X, unsigned int Y, unsigned int Z)
{
- return (X & Z) | (Y & ~Z);
+ return (X & Z) | (Y & ~Z);
}
static unsigned int H(unsigned int X, unsigned int Y, unsigned int Z)
{
- return X ^ Y ^ Z;
+ return X ^ Y ^ Z;
}
static unsigned int I(unsigned int X, unsigned int Y, unsigned int Z)
{
- return Y ^ (X | ~Z);
+ return Y ^ (X | ~Z);
}
static unsigned int Round(unsigned int a, unsigned int b, unsigned int FGHI,
- unsigned int k, unsigned int s, unsigned int i)
+ unsigned int k, unsigned int s, unsigned int i)
{
- return b + ROTATE_LEFT(a + FGHI + pX[k] + T[i], s);
+ return b + ROTATE_LEFT(a + FGHI + pX[k] + T[i], s);
}
static void Round1(unsigned int *a, unsigned int b, unsigned int c,
- unsigned int d,unsigned int k, unsigned int s, unsigned int i)
+ unsigned int d,unsigned int k, unsigned int s, unsigned int i)
{
- *a = Round(*a, b, F(b,c,d), k, s, i);
+ *a = Round(*a, b, F(b,c,d), k, s, i);
}
static void Round2(unsigned int *a, unsigned int b, unsigned int c,
- unsigned int d,unsigned int k, unsigned int s, unsigned int i)
+ unsigned int d,unsigned int k, unsigned int s, unsigned int i)
{
- *a = Round(*a, b, G(b,c,d), k, s, i);
+ *a = Round(*a, b, G(b,c,d), k, s, i);
}
static void Round3(unsigned int *a, unsigned int b, unsigned int c,
- unsigned int d,unsigned int k, unsigned int s, unsigned int i)
+ unsigned int d,unsigned int k, unsigned int s, unsigned int i)
{
- *a = Round(*a, b, H(b,c,d), k, s, i);
+ *a = Round(*a, b, H(b,c,d), k, s, i);
}
static void Round4(unsigned int *a, unsigned int b, unsigned int c,
- unsigned int d,unsigned int k, unsigned int s, unsigned int i)
+ unsigned int d,unsigned int k, unsigned int s, unsigned int i)
{
- *a = Round(*a, b, I(b,c,d), k, s, i);
+ *a = Round(*a, b, I(b,c,d), k, s, i);
}
static void MD5_Round_Calculate(const unsigned char *block,
- unsigned int *A2, unsigned int *B2, unsigned int *C2, unsigned int *D2)
+ unsigned int *A2, unsigned int *B2, unsigned int *C2, unsigned int *D2)
{
- //create X It is since it is required.
- unsigned int X[16]; //512bit 64byte
- int j,k;
-
- //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;
-
- //Copy block(padding_message) i into X
- for (j=0,k=0; j<64; j+=4,k++)
- X[k] = ((unsigned int)block[j]) // 8byte*4 -> 32byte conversion
- | (((unsigned int)block[j+1]) << 8) // A function called Decode as used in the field of RFC
- | (((unsigned int)block[j+2]) << 16)
- | (((unsigned int)block[j+3]) << 24);
-
-
- //Round 1
- Round1(&A,B,C,D, 0, 7, 0);
- Round1(&D,A,B,C, 1, 12, 1);
- Round1(&C,D,A,B, 2, 17, 2);
- Round1(&B,C,D,A, 3, 22, 3);
- Round1(&A,B,C,D, 4, 7, 4);
- Round1(&D,A,B,C, 5, 12, 5);
- Round1(&C,D,A,B, 6, 17, 6);
- Round1(&B,C,D,A, 7, 22, 7);
- Round1(&A,B,C,D, 8, 7, 8);
- Round1(&D,A,B,C, 9, 12, 9);
- Round1(&C,D,A,B, 10, 17, 10);
- Round1(&B,C,D,A, 11, 22, 11);
- Round1(&A,B,C,D, 12, 7, 12);
- Round1(&D,A,B,C, 13, 12, 13);
- Round1(&C,D,A,B, 14, 17, 14);
- Round1(&B,C,D,A, 15, 22, 15);
-
- //Round 2
- Round2(&A,B,C,D, 1, 5, 16);
- Round2(&D,A,B,C, 6, 9, 17);
- Round2(&C,D,A,B, 11, 14, 18);
- Round2(&B,C,D,A, 0, 20, 19);
- Round2(&A,B,C,D, 5, 5, 20);
- Round2(&D,A,B,C, 10, 9, 21);
- Round2(&C,D,A,B, 15, 14, 22);
- Round2(&B,C,D,A, 4, 20, 23);
- Round2(&A,B,C,D, 9, 5, 24);
- Round2(&D,A,B,C, 14, 9, 25);
- Round2(&C,D,A,B, 3, 14, 26);
- Round2(&B,C,D,A, 8, 20, 27);
- Round2(&A,B,C,D, 13, 5, 28);
- Round2(&D,A,B,C, 2, 9, 29);
- Round2(&C,D,A,B, 7, 14, 30);
- Round2(&B,C,D,A, 12, 20, 31);
-
- //Round 3
- Round3(&A,B,C,D, 5, 4, 32);
- Round3(&D,A,B,C, 8, 11, 33);
- Round3(&C,D,A,B, 11, 16, 34);
- Round3(&B,C,D,A, 14, 23, 35);
- Round3(&A,B,C,D, 1, 4, 36);
- Round3(&D,A,B,C, 4, 11, 37);
- Round3(&C,D,A,B, 7, 16, 38);
- Round3(&B,C,D,A, 10, 23, 39);
- Round3(&A,B,C,D, 13, 4, 40);
- Round3(&D,A,B,C, 0, 11, 41);
- Round3(&C,D,A,B, 3, 16, 42);
- Round3(&B,C,D,A, 6, 23, 43);
- Round3(&A,B,C,D, 9, 4, 44);
- Round3(&D,A,B,C, 12, 11, 45);
- Round3(&C,D,A,B, 15, 16, 46);
- Round3(&B,C,D,A, 2, 23, 47);
-
- //Round 4
- Round4(&A,B,C,D, 0, 6, 48);
- Round4(&D,A,B,C, 7, 10, 49);
- Round4(&C,D,A,B, 14, 15, 50);
- Round4(&B,C,D,A, 5, 21, 51);
- Round4(&A,B,C,D, 12, 6, 52);
- Round4(&D,A,B,C, 3, 10, 53);
- Round4(&C,D,A,B, 10, 15, 54);
- Round4(&B,C,D,A, 1, 21, 55);
- Round4(&A,B,C,D, 8, 6, 56);
- Round4(&D,A,B,C, 15, 10, 57);
- Round4(&C,D,A,B, 6, 15, 58);
- Round4(&B,C,D,A, 13, 21, 59);
- Round4(&A,B,C,D, 4, 6, 60);
- Round4(&D,A,B,C, 11, 10, 61);
- Round4(&C,D,A,B, 2, 15, 62);
- Round4(&B,C,D,A, 9, 21, 63);
-
- // Then perform the following additions. (let's add)
- *A2 = A + AA;
- *B2 = B + BB;
- *C2 = C + CC;
- *D2 = D + DD;
-
- //The clearance of confidential information
- memset(pX, 0, sizeof(X));
+ //create X It is since it is required.
+ unsigned int X[16]; //512bit 64byte
+ int j,k;
+
+ //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;
+
+ //Copy block(padding_message) i into X
+ for (j=0,k=0; j<64; j+=4,k++)
+ X[k] = ( (unsigned int )block[j] ) // 8byte*4 -> 32byte conversion
+ | ( ((unsigned int )block[j+1]) << 8 ) // A function called Decode as used in the field of RFC
+ | ( ((unsigned int )block[j+2]) << 16 )
+ | ( ((unsigned int )block[j+3]) << 24 );
+
+
+ //Round 1
+ Round1(&A,B,C,D, 0, 7, 0); Round1(&D,A,B,C, 1, 12, 1); Round1(&C,D,A,B, 2, 17, 2); Round1(&B,C,D,A, 3, 22, 3);
+ Round1(&A,B,C,D, 4, 7, 4); Round1(&D,A,B,C, 5, 12, 5); Round1(&C,D,A,B, 6, 17, 6); Round1(&B,C,D,A, 7, 22, 7);
+ Round1(&A,B,C,D, 8, 7, 8); Round1(&D,A,B,C, 9, 12, 9); Round1(&C,D,A,B, 10, 17, 10); Round1(&B,C,D,A, 11, 22, 11);
+ Round1(&A,B,C,D, 12, 7, 12); Round1(&D,A,B,C, 13, 12, 13); Round1(&C,D,A,B, 14, 17, 14); Round1(&B,C,D,A, 15, 22, 15);
+
+ //Round 2
+ Round2(&A,B,C,D, 1, 5, 16); Round2(&D,A,B,C, 6, 9, 17); Round2(&C,D,A,B, 11, 14, 18); Round2(&B,C,D,A, 0, 20, 19);
+ Round2(&A,B,C,D, 5, 5, 20); Round2(&D,A,B,C, 10, 9, 21); Round2(&C,D,A,B, 15, 14, 22); Round2(&B,C,D,A, 4, 20, 23);
+ Round2(&A,B,C,D, 9, 5, 24); Round2(&D,A,B,C, 14, 9, 25); Round2(&C,D,A,B, 3, 14, 26); Round2(&B,C,D,A, 8, 20, 27);
+ Round2(&A,B,C,D, 13, 5, 28); Round2(&D,A,B,C, 2, 9, 29); Round2(&C,D,A,B, 7, 14, 30); Round2(&B,C,D,A, 12, 20, 31);
+
+ //Round 3
+ Round3(&A,B,C,D, 5, 4, 32); Round3(&D,A,B,C, 8, 11, 33); Round3(&C,D,A,B, 11, 16, 34); Round3(&B,C,D,A, 14, 23, 35);
+ Round3(&A,B,C,D, 1, 4, 36); Round3(&D,A,B,C, 4, 11, 37); Round3(&C,D,A,B, 7, 16, 38); Round3(&B,C,D,A, 10, 23, 39);
+ Round3(&A,B,C,D, 13, 4, 40); Round3(&D,A,B,C, 0, 11, 41); Round3(&C,D,A,B, 3, 16, 42); Round3(&B,C,D,A, 6, 23, 43);
+ Round3(&A,B,C,D, 9, 4, 44); Round3(&D,A,B,C, 12, 11, 45); Round3(&C,D,A,B, 15, 16, 46); Round3(&B,C,D,A, 2, 23, 47);
+
+ //Round 4
+ Round4(&A,B,C,D, 0, 6, 48); Round4(&D,A,B,C, 7, 10, 49); Round4(&C,D,A,B, 14, 15, 50); Round4(&B,C,D,A, 5, 21, 51);
+ Round4(&A,B,C,D, 12, 6, 52); Round4(&D,A,B,C, 3, 10, 53); Round4(&C,D,A,B, 10, 15, 54); Round4(&B,C,D,A, 1, 21, 55);
+ Round4(&A,B,C,D, 8, 6, 56); Round4(&D,A,B,C, 15, 10, 57); Round4(&C,D,A,B, 6, 15, 58); Round4(&B,C,D,A, 13, 21, 59);
+ Round4(&A,B,C,D, 4, 6, 60); Round4(&D,A,B,C, 11, 10, 61); Round4(&C,D,A,B, 2, 15, 62); Round4(&B,C,D,A, 9, 21, 63);
+
+ // Then perform the following additions. (let's add)
+ *A2 = A + AA;
+ *B2 = B + BB;
+ *C2 = C + CC;
+ *D2 = D + DD;
+
+ //The clearance of confidential information
+ memset(pX, 0, sizeof(X));
}
-static void MD5_String2binary(const char *string, unsigned char *output)
+static void MD5_String2binary(const char * string, unsigned char * output)
{
- //var
- /*8bit*/
- unsigned char padding_message[64]; //Extended message 512bit 64byte
- unsigned char *pstring; //The position of string in the present scanning notes is held.
-
- /*32bit*/
- unsigned int string_byte_len, //The byte chief of string is held.
- string_bit_len, //The bit length of string is held.
- copy_len, //The number of bytes which is used by 1-3 and which remained
- msg_digest[4]; //Message digest 128bit 4byte
- unsigned int *A = &msg_digest[0], //The message digest in accordance with RFC (reference)
- *B = &msg_digest[1],
- *C = &msg_digest[2],
- *D = &msg_digest[3];
- int i;
-
- //prog
- //Step 3.Initialize MD Buffer (although it is the initialization; step 3 of A, B, C, and D -- unavoidable -- a head)
- *A = 0x67452301;
- *B = 0xefcdab89;
- *C = 0x98badcfe;
- *D = 0x10325476;
-
- //Step 1.Append Padding Bits (extension of a mark bit)
- //1-1
- string_byte_len = (unsigned int)strlen(string); //The byte chief of a character sequence is acquired.
- pstring = (unsigned char *)string; //The position of the present character sequence is set.
-
- //1-2 Repeat calculation until length becomes less than 64 bytes.
- for (i=string_byte_len; 64<=i; i-=64,pstring+=64)
+//var
+ /*8bit*/
+ unsigned char padding_message[64]; //Extended message 512bit 64byte
+ unsigned char *pstring; //The position of string in the present scanning notes is held.
+
+ /*32bit*/
+ unsigned int string_byte_len, //The byte chief of string is held.
+ string_bit_len, //The bit length of string is held.
+ copy_len, //The number of bytes which is used by 1-3 and which remained
+ msg_digest[4]; //Message digest 128bit 4byte
+ unsigned int *A = &msg_digest[0], //The message digest in accordance with RFC (reference)
+ *B = &msg_digest[1],
+ *C = &msg_digest[2],
+ *D = &msg_digest[3];
+ int i;
+
+//prog
+ //Step 3.Initialize MD Buffer (although it is the initialization; step 3 of A, B, C, and D -- unavoidable -- a head)
+ *A = 0x67452301;
+ *B = 0xefcdab89;
+ *C = 0x98badcfe;
+ *D = 0x10325476;
+
+ //Step 1.Append Padding Bits (extension of a mark bit)
+ //1-1
+ string_byte_len = (unsigned int)strlen(string); //The byte chief of a character sequence is acquired.
+ pstring = (unsigned char *)string; //The position of the present character sequence is set.
+
+ //1-2 Repeat calculation until length becomes less than 64 bytes.
+ for (i=string_byte_len; 64<=i; i-=64,pstring+=64)
MD5_Round_Calculate(pstring, A,B,C,D);
- //1-3
- copy_len = string_byte_len % 64; //The number of bytes which remained is computed.
- strncpy((char *)padding_message, (char *)pstring, copy_len); //A message is copied to an extended bit sequence.
- 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
- //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);
- memset(padding_message, 0, 56); //56 bytes is newly fill uped with 0.
- }
-
- //Step 2.Append Length (the information on length is added)
- string_bit_len = string_byte_len * 8; //From the byte chief to bit length (32 bytes of low rank)
- memcpy(&padding_message[56], &string_bit_len, 4); //32 bytes of low rank is set.
-
- //When bit length cannot be expressed in 32 bytes of low rank, it is a beam raising to a higher rank.
- if (UINT_MAX / 8 < string_byte_len) {
- unsigned int high = (string_byte_len - UINT_MAX / 8) * 8;
- memcpy(&padding_message[60], &high, 4);
- } else
- memset(&padding_message[60], 0, 4); //In this case, it is good for a higher rank at 0.
-
- //Step 4.Process Message in 16-Word Blocks (calculation of MD5)
- MD5_Round_Calculate(padding_message, A,B,C,D);
-
- //Step 5.Output (output)
- memcpy(output,msg_digest,16);
+ //1-3
+ copy_len = string_byte_len % 64; //The number of bytes which remained is computed.
+ strncpy((char *)padding_message, (char *)pstring, copy_len); //A message is copied to an extended bit sequence.
+ 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
+ //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);
+ memset(padding_message, 0, 56); //56 bytes is newly fill uped with 0.
+ }
+
+ //Step 2.Append Length (the information on length is added)
+ string_bit_len = string_byte_len * 8; //From the byte chief to bit length (32 bytes of low rank)
+ memcpy(&padding_message[56], &string_bit_len, 4); //32 bytes of low rank is set.
+
+ //When bit length cannot be expressed in 32 bytes of low rank, it is a beam raising to a higher rank.
+ if (UINT_MAX / 8 < string_byte_len) {
+ unsigned int high = (string_byte_len - UINT_MAX / 8) * 8;
+ memcpy(&padding_message[60], &high, 4);
+ } else
+ memset(&padding_message[60], 0, 4); //In this case, it is good for a higher rank at 0.
+
+ //Step 4.Process Message in 16-Word Blocks (calculation of MD5)
+ MD5_Round_Calculate(padding_message, A,B,C,D);
+
+ //Step 5.Output (output)
+ memcpy(output,msg_digest,16);
}
//-------------------------------------------------------------------
// The function for the exteriors
/** output is the coded binary in the character sequence which wants to code string. */
-void MD5_Binary(const char *string, unsigned char *output)
+void MD5_Binary(const char * string, unsigned char * output)
{
- MD5_String2binary(string,output);
+ MD5_String2binary(string,output);
}
/** output is the coded character sequence in the character sequence which wants to code string. */
-void MD5_String(const char *string, char *output)
+void MD5_String(const char * string, char * output)
{
- unsigned char digest[16];
-
- MD5_String2binary(string,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],
- digest[ 4], digest[ 5], digest[ 6], digest[ 7],
- digest[ 8], digest[ 9], digest[10], digest[11],
- digest[12], digest[13], digest[14], digest[15]);
+ unsigned char digest[16];
+
+ MD5_String2binary(string,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],
+ digest[ 4], digest[ 5], digest[ 6], digest[ 7],
+ digest[ 8], digest[ 9], digest[10], digest[11],
+ digest[12], digest[13], digest[14], digest[15]);
}
/** output is a sequence of non-zero characters to be used as password salt. */
-void MD5_Salt(unsigned int len, char *output)
+void MD5_Salt(unsigned int len, char * output)
{
- unsigned int i;
- for (i = 0; i < len; ++i)
- output[i] = (char)(1 + rnd() % 255);
+ unsigned int i;
+ for( i = 0; i < len; ++i )
+ output[i] = (char)(1 + rnd() % 255);
}
diff --git a/src/common/md5calc.h b/src/common/md5calc.h
index 4a112a660..323affa2c 100644
--- a/src/common/md5calc.h
+++ b/src/common/md5calc.h
@@ -1,8 +1,8 @@
#ifndef _MD5CALC_H_
#define _MD5CALC_H_
-void MD5_String(const char *string, char *output);
-void MD5_Binary(const char *string, unsigned char *output);
-void MD5_Salt(unsigned int len, char *output);
+void MD5_String(const char * string, char * output);
+void MD5_Binary(const char * string, unsigned char * output);
+void MD5_Salt(unsigned int len, char * output);
#endif /* _MD5CALC_H_ */
diff --git a/src/common/mempool.c b/src/common/mempool.c
index 62db7b9e3..35b03034d 100644
--- a/src/common/mempool.c
+++ b/src/common/mempool.c
@@ -30,9 +30,9 @@
#include "../common/malloc.h"
#include "../common/mutex.h"
-#define ALIGN16 ra_align(16)
+#define ALIGN16 ra_align(16)
#define ALIGN_TO(x, a) (x + ( a - ( x % a) ) )
-#define ALIGN_TO_16(x) ALIGN_TO(x, 16)
+#define ALIGN_TO_16(x) ALIGN_TO(x, 16)
#undef MEMPOOL_DEBUG
#define MEMPOOLASSERT
@@ -40,532 +40,523 @@
#define NODE_TO_DATA(x) ( ((char*)x) + sizeof(struct node) )
#define DATA_TO_NODE(x) ( (struct node*)(((char*)x) - sizeof(struct node)) )
-struct ra_align(16) node {
- void *next;
- void *segment;
+struct ra_align(16) node{
+ void *next;
+ void *segment;
#ifdef MEMPOOLASSERT
- bool used;
- uint64 magic;
-#define NODE_MAGIC 0xBEEF00EAEACAFE07ll
+ bool used;
+ uint64 magic;
+ #define NODE_MAGIC 0xBEEF00EAEACAFE07ll
#endif
};
// The Pointer to this struct is the base address of the segment itself.
-struct pool_segment {
- mempool pool; // pool, this segment belongs to
- struct pool_segment *next;
- int64 num_nodes_total;
- int64 num_bytes;
+struct pool_segment{
+ mempool pool; // pool, this segment belongs to
+ struct pool_segment *next;
+ int64 num_nodes_total;
+ int64 num_bytes;
};
-struct mempool {
- // Settings
- char *name;
- uint64 elem_size;
- uint64 elem_realloc_step;
- int64 elem_realloc_thresh;
-
- // Callbacks that get called for every node that gets allocated
- // Example usage: initialization of mutex/lock for each node.
- memPoolOnNodeAllocationProc onalloc;
- memPoolOnNodeDeallocationProc ondealloc;
-
- // Locks
- SPIN_LOCK segmentLock;
- SPIN_LOCK nodeLock;
-
-
- // Internal
- struct pool_segment *segments;
- struct node *free_list;
-
- volatile int64 num_nodes_total;
- volatile int64 num_nodes_free;
-
- volatile int64 num_segments;
- volatile int64 num_bytes_total;
-
- volatile int64 peak_nodes_used; // Peak Node Usage
- volatile int64 num_realloc_events; // Number of reallocations done. (allocate additional nodes)
-
- // list (used for global management such as allocator..)
- struct mempool *next;
+struct mempool{
+ // Settings
+ char *name;
+ uint64 elem_size;
+ uint64 elem_realloc_step;
+ int64 elem_realloc_thresh;
+
+ // Callbacks that get called for every node that gets allocated
+ // Example usage: initialization of mutex/lock for each node.
+ memPoolOnNodeAllocationProc onalloc;
+ memPoolOnNodeDeallocationProc ondealloc;
+
+ // Locks
+ SPIN_LOCK segmentLock;
+ SPIN_LOCK nodeLock;
+
+
+ // Internal
+ struct pool_segment *segments;
+ struct node *free_list;
+
+ volatile int64 num_nodes_total;
+ volatile int64 num_nodes_free;
+
+ volatile int64 num_segments;
+ volatile int64 num_bytes_total;
+
+ volatile int64 peak_nodes_used; // Peak Node Usage
+ volatile int64 num_realloc_events; // Number of reallocations done. (allocate additional nodes)
+
+ // list (used for global management such as allocator..)
+ struct mempool *next;
} ra_align(8); // Dont touch the alignment, otherwise interlocked functions are broken ..
-///
+///
// Implementation:
//
static void segment_allocate_add(mempool p, uint64 count);
static SPIN_LOCK l_mempoolListLock;
-static mempool l_mempoolList = NULL;
+static mempool l_mempoolList = NULL;
static rAthread l_async_thread = NULL;
-static ramutex l_async_lock = NULL;
-static racond l_async_cond = NULL;
+static ramutex l_async_lock = NULL;
+static racond l_async_cond = NULL;
static volatile int32 l_async_terminate = 0;
-static void *mempool_async_allocator(void *x)
-{
- mempool p;
-
-
- while (1) {
- if (l_async_terminate > 0)
- break;
-
- EnterSpinLock(&l_mempoolListLock);
-
- for (p = l_mempoolList; p != NULL; p = p->next) {
-
- if (p->num_nodes_free < p->elem_realloc_thresh) {
- // add new segment.
- segment_allocate_add(p, p->elem_realloc_step);
- // increase stats counter
- InterlockedIncrement64(&p->num_realloc_events);
- }
-
- }
-
- LeaveSpinLock(&l_mempoolListLock);
-
- ramutex_lock(l_async_lock);
- racond_wait(l_async_cond, l_async_lock, -1);
- ramutex_unlock(l_async_lock);
- }
-
-
- return NULL;
+static void *mempool_async_allocator(void *x){
+ mempool p;
+
+
+ while(1){
+ if(l_async_terminate > 0)
+ break;
+
+ EnterSpinLock(&l_mempoolListLock);
+
+ for(p = l_mempoolList; p != NULL; p = p->next){
+
+ if(p->num_nodes_free < p->elem_realloc_thresh){
+ // add new segment.
+ segment_allocate_add(p, p->elem_realloc_step);
+ // increase stats counter
+ InterlockedIncrement64(&p->num_realloc_events);
+ }
+
+ }
+
+ LeaveSpinLock(&l_mempoolListLock);
+
+ ramutex_lock( l_async_lock );
+ racond_wait( l_async_cond, l_async_lock, -1 );
+ ramutex_unlock( l_async_lock );
+ }
+
+
+ return NULL;
}//end: mempool_async_allocator()
-void mempool_init()
-{
-
- if (sizeof(struct node)%16 != 0) {
- ShowFatalError("mempool_init: struct node alignment failure. %u != multiple of 16\n", sizeof(struct node));
- exit(EXIT_FAILURE);
- }
-
- // Global List start
- InitializeSpinLock(&l_mempoolListLock);
- l_mempoolList = NULL;
-
- // Initialize mutex + stuff needed for async allocator worker.
- l_async_terminate = 0;
- l_async_lock = ramutex_create();
- l_async_cond = racond_create();
-
- l_async_thread = rathread_createEx(mempool_async_allocator, NULL, 1024*1024, RAT_PRIO_NORMAL);
- if (l_async_thread == NULL) {
- ShowFatalError("mempool_init: cannot spawn Async Allocator Thread.\n");
- exit(EXIT_FAILURE);
- }
+void mempool_init(){
+
+ if(sizeof(struct node)%16 != 0 ){
+ ShowFatalError("mempool_init: struct node alignment failure. %u != multiple of 16\n", sizeof(struct node));
+ exit(EXIT_FAILURE);
+ }
+
+ // Global List start
+ InitializeSpinLock(&l_mempoolListLock);
+ l_mempoolList = NULL;
+
+ // Initialize mutex + stuff needed for async allocator worker.
+ l_async_terminate = 0;
+ l_async_lock = ramutex_create();
+ l_async_cond = racond_create();
+
+ l_async_thread = rathread_createEx(mempool_async_allocator, NULL, 1024*1024, RAT_PRIO_NORMAL);
+ if(l_async_thread == NULL){
+ ShowFatalError("mempool_init: cannot spawn Async Allocator Thread.\n");
+ exit(EXIT_FAILURE);
+ }
}//end: mempool_init()
-void mempool_final()
-{
- mempool p, pn;
-
- ShowStatus("Mempool: Terminating async. allocation worker and remaining pools.\n");
-
- // Terminate worker / wait until its terminated.
- InterlockedIncrement(&l_async_terminate);
- racond_signal(l_async_cond);
- rathread_wait(l_async_thread, NULL);
-
- // Destroy cond var and mutex.
- racond_destroy(l_async_cond);
- ramutex_destroy(l_async_lock);
-
- // Free remaining mempools
- // ((bugged code! this should halppen, every mempool should
- // be freed by the subsystem that has allocated it.)
- //
- EnterSpinLock(&l_mempoolListLock);
- p = l_mempoolList;
- while (1) {
- if (p == NULL)
- break;
-
- pn = p->next;
-
- ShowWarning("Mempool [%s] was not properly destroyed - forcing destroy.\n", p->name);
- mempool_destroy(p);
-
- p = pn;
- }
- LeaveSpinLock(&l_mempoolListLock);
-
+void mempool_final(){
+ mempool p, pn;
+
+ ShowStatus("Mempool: Terminating async. allocation worker and remaining pools.\n");
+
+ // Terminate worker / wait until its terminated.
+ InterlockedIncrement(&l_async_terminate);
+ racond_signal(l_async_cond);
+ rathread_wait(l_async_thread, NULL);
+
+ // Destroy cond var and mutex.
+ racond_destroy( l_async_cond );
+ ramutex_destroy( l_async_lock );
+
+ // Free remaining mempools
+ // ((bugged code! this should halppen, every mempool should
+ // be freed by the subsystem that has allocated it.)
+ //
+ EnterSpinLock(&l_mempoolListLock);
+ p = l_mempoolList;
+ while(1){
+ if(p == NULL)
+ break;
+
+ pn = p->next;
+
+ ShowWarning("Mempool [%s] was not properly destroyed - forcing destroy.\n", p->name);
+ mempool_destroy(p);
+
+ p = pn;
+ }
+ LeaveSpinLock(&l_mempoolListLock);
+
}//end: mempool_final()
-static void segment_allocate_add(mempool p, uint64 count)
-{
-
- // Required Memory:
- // sz( segment )
- // count * sz( real_node_size )
- //
- // where real node size is:
- // ALIGN_TO_16( sz( node ) ) + p->elem_size
- // so the nodes usable address is nodebase + ALIGN_TO_16(sz(node))
- //
- size_t total_sz;
- struct pool_segment *seg = NULL;
- struct node *nodeList = NULL;
- struct node *node = NULL;
- char *ptr = NULL;
- uint64 i;
-
- total_sz = ALIGN_TO_16(sizeof(struct pool_segment))
- + ((size_t)count * (sizeof(struct node) + (size_t)p->elem_size)) ;
+static void segment_allocate_add(mempool p, uint64 count){
+
+ // Required Memory:
+ // sz( segment )
+ // count * sz( real_node_size )
+ //
+ // where real node size is:
+ // ALIGN_TO_16( sz( node ) ) + p->elem_size
+ // so the nodes usable address is nodebase + ALIGN_TO_16(sz(node))
+ //
+ size_t total_sz;
+ struct pool_segment *seg = NULL;
+ struct node *nodeList = NULL;
+ struct node *node = NULL;
+ char *ptr = NULL;
+ uint64 i;
+
+ total_sz = ALIGN_TO_16( sizeof(struct pool_segment) )
+ + ( (size_t)count * (sizeof(struct node) + (size_t)p->elem_size) ) ;
#ifdef MEMPOOL_DEBUG
- ShowDebug("Mempool [%s] Segment AllocateAdd (num: %u, total size: %0.2fMiB)\n", p->name, count, (float)total_sz/1024.f/1024.f);
+ ShowDebug("Mempool [%s] Segment AllocateAdd (num: %u, total size: %0.2fMiB)\n", p->name, count, (float)total_sz/1024.f/1024.f);
#endif
- // allocate! (spin forever until weve got the memory.)
- i=0;
- while (1) {
- ptr = (char *)aMalloc(total_sz);
- if (ptr != NULL) break;
-
- i++; // increase failcount.
- if (!(i & 7)) {
- ShowWarning("Mempool [%s] Segment AllocateAdd => System seems to be Out of Memory (%0.2f MiB). Try #%u\n", (float)total_sz/1024.f/1024.f, i);
+ // allocate! (spin forever until weve got the memory.)
+ i=0;
+ while(1){
+ ptr = (char*)aMalloc(total_sz);
+ if(ptr != NULL) break;
+
+ i++; // increase failcount.
+ if(!(i & 7)){
+ ShowWarning("Mempool [%s] Segment AllocateAdd => System seems to be Out of Memory (%0.2f MiB). Try #%u\n", (float)total_sz/1024.f/1024.f, i);
#ifdef WIN32
- Sleep(1000);
+ Sleep(1000);
#else
- sleep(1);
+ sleep(1);
#endif
- } else {
- rathread_yield(); /// allow/force vuln. ctxswitch
- }
- }//endwhile: allocation spinloop.
-
- // Clear Memory.
- memset(ptr, 0x00, total_sz);
-
- // Initialize segment struct.
- seg = (struct pool_segment *)ptr;
- ptr += ALIGN_TO_16(sizeof(struct pool_segment));
-
- seg->pool = p;
- seg->num_nodes_total = count;
- seg->num_bytes = total_sz;
-
-
- // Initialze nodes!
- nodeList = NULL;
- for (i = 0; i < count; i++) {
- node = (struct node *)ptr;
- ptr += sizeof(struct node);
- ptr += p->elem_size;
-
- node->segment = seg;
+ }else{
+ rathread_yield(); /// allow/force vuln. ctxswitch
+ }
+ }//endwhile: allocation spinloop.
+
+ // Clear Memory.
+ memset(ptr, 0x00, total_sz);
+
+ // Initialize segment struct.
+ seg = (struct pool_segment*)ptr;
+ ptr += ALIGN_TO_16(sizeof(struct pool_segment));
+
+ seg->pool = p;
+ seg->num_nodes_total = count;
+ seg->num_bytes = total_sz;
+
+
+ // Initialze nodes!
+ nodeList = NULL;
+ for(i = 0; i < count; i++){
+ node = (struct node*)ptr;
+ ptr += sizeof(struct node);
+ ptr += p->elem_size;
+
+ node->segment = seg;
#ifdef MEMPOOLASSERT
- node->used = false;
- node->magic = NODE_MAGIC;
+ node->used = false;
+ node->magic = NODE_MAGIC;
#endif
- if (p->onalloc != NULL) p->onalloc(NODE_TO_DATA(node));
-
- node->next = nodeList;
- nodeList = node;
- }
-
-
-
- // Link in Segment.
- EnterSpinLock(&p->segmentLock);
- seg->next = p->segments;
- p->segments = seg;
- LeaveSpinLock(&p->segmentLock);
-
- // Link in Nodes
- EnterSpinLock(&p->nodeLock);
- nodeList->next = p->free_list;
- p->free_list = nodeList;
- LeaveSpinLock(&p->nodeLock);
-
-
- // Increase Stats:
- InterlockedExchangeAdd64(&p->num_nodes_total, count);
- InterlockedExchangeAdd64(&p->num_nodes_free, count);
- InterlockedIncrement64(&p->num_segments);
- InterlockedExchangeAdd64(&p->num_bytes_total, total_sz);
-
+ if(p->onalloc != NULL) p->onalloc( NODE_TO_DATA(node) );
+
+ node->next = nodeList;
+ nodeList = node;
+ }
+
+
+
+ // Link in Segment.
+ EnterSpinLock(&p->segmentLock);
+ seg->next = p->segments;
+ p->segments = seg;
+ LeaveSpinLock(&p->segmentLock);
+
+ // Link in Nodes
+ EnterSpinLock(&p->nodeLock);
+ nodeList->next = p->free_list;
+ p->free_list = nodeList;
+ LeaveSpinLock(&p->nodeLock);
+
+
+ // Increase Stats:
+ InterlockedExchangeAdd64(&p->num_nodes_total, count);
+ InterlockedExchangeAdd64(&p->num_nodes_free, count);
+ InterlockedIncrement64(&p->num_segments);
+ InterlockedExchangeAdd64(&p->num_bytes_total, total_sz);
+
}//end: segment_allocate_add()
mempool mempool_create(const char *name,
- uint64 elem_size,
- uint64 initial_count,
- uint64 realloc_count,
- memPoolOnNodeAllocationProc onNodeAlloc,
- memPoolOnNodeDeallocationProc onNodeDealloc)
-{
- //..
- uint64 realloc_thresh;
- mempool pool;
- pool = (mempool)aCalloc(1, sizeof(struct mempool));
-
- if (pool == NULL) {
- ShowFatalError("mempool_create: Failed to allocate %u bytes memory.\n", sizeof(struct mempool));
- exit(EXIT_FAILURE);
- }
-
- // Check minimum initial count / realloc count requirements.
- if (initial_count < 50)
- initial_count = 50;
- if (realloc_count < 50)
- realloc_count = 50;
-
- // Set Reallocation threshold to 5% of realloc_count, at least 10.
- realloc_thresh = (realloc_count/100)*5; //
- if (realloc_thresh < 10)
- realloc_thresh = 10;
-
- // Initialize members..
- pool->name = aStrdup(name);
- pool->elem_size = ALIGN_TO_16(elem_size);
- pool->elem_realloc_step = realloc_count;
- pool->elem_realloc_thresh = realloc_thresh;
- pool->onalloc = onNodeAlloc;
- pool->ondealloc = onNodeDealloc;
-
- InitializeSpinLock(&pool->segmentLock);
- InitializeSpinLock(&pool->nodeLock);
-
- // Initial Statistic values:
- pool->num_nodes_total = 0;
- pool->num_nodes_free = 0;
- pool->num_segments = 0;
- pool->num_bytes_total = 0;
- pool->peak_nodes_used = 0;
- pool->num_realloc_events = 0;
-
- //
+ uint64 elem_size,
+ uint64 initial_count,
+ uint64 realloc_count,
+ memPoolOnNodeAllocationProc onNodeAlloc,
+ memPoolOnNodeDeallocationProc onNodeDealloc){
+ //..
+ uint64 realloc_thresh;
+ mempool pool;
+ pool = (mempool)aCalloc( 1, sizeof(struct mempool) );
+
+ if(pool == NULL){
+ ShowFatalError("mempool_create: Failed to allocate %u bytes memory.\n", sizeof(struct mempool) );
+ exit(EXIT_FAILURE);
+ }
+
+ // Check minimum initial count / realloc count requirements.
+ if(initial_count < 50)
+ initial_count = 50;
+ if(realloc_count < 50)
+ realloc_count = 50;
+
+ // Set Reallocation threshold to 5% of realloc_count, at least 10.
+ realloc_thresh = (realloc_count/100)*5; //
+ if(realloc_thresh < 10)
+ realloc_thresh = 10;
+
+ // Initialize members..
+ pool->name = aStrdup(name);
+ pool->elem_size = ALIGN_TO_16(elem_size);
+ pool->elem_realloc_step = realloc_count;
+ pool->elem_realloc_thresh = realloc_thresh;
+ pool->onalloc = onNodeAlloc;
+ pool->ondealloc = onNodeDealloc;
+
+ InitializeSpinLock(&pool->segmentLock);
+ InitializeSpinLock(&pool->nodeLock);
+
+ // Initial Statistic values:
+ pool->num_nodes_total = 0;
+ pool->num_nodes_free = 0;
+ pool->num_segments = 0;
+ pool->num_bytes_total = 0;
+ pool->peak_nodes_used = 0;
+ pool->num_realloc_events = 0;
+
+ //
#ifdef MEMPOOL_DEBUG
- ShowDebug("Mempool [%s] Init (ElemSize: %u, Initial Count: %u, Realloc Count: %u)\n", pool->name, pool->elem_size, initial_count, pool->elem_realloc_step);
+ ShowDebug("Mempool [%s] Init (ElemSize: %u, Initial Count: %u, Realloc Count: %u)\n", pool->name, pool->elem_size, initial_count, pool->elem_realloc_step);
#endif
- // Allocate first segment directly :)
- segment_allocate_add(pool, initial_count);
-
-
- // Add Pool to the global pool list
- EnterSpinLock(&l_mempoolListLock);
- pool->next = l_mempoolList;
- l_mempoolList = pool;
- LeaveSpinLock(&l_mempoolListLock);
+ // Allocate first segment directly :)
+ segment_allocate_add(pool, initial_count);
+
+ // Add Pool to the global pool list
+ EnterSpinLock(&l_mempoolListLock);
+ pool->next = l_mempoolList;
+ l_mempoolList = pool;
+ LeaveSpinLock(&l_mempoolListLock);
- return pool;
+
+ return pool;
}//end: mempool_create()
-void mempool_destroy(mempool p)
-{
- struct pool_segment *seg, *segnext;
- struct node *niter;
- mempool piter, pprev;
- char *ptr;
- int64 i;
+void mempool_destroy(mempool p){
+ struct pool_segment *seg, *segnext;
+ struct node *niter;
+ mempool piter, pprev;
+ char *ptr;
+ int64 i;
#ifdef MEMPOOL_DEBUG
ShowDebug("Mempool [%s] Destroy\n", p->name);
#endif
-
- // Unlink from global list.
- EnterSpinLock(&l_mempoolListLock);
- piter = l_mempoolList;
- pprev = l_mempoolList;
- while (1) {
- if (piter == NULL)
- break;
-
-
- if (piter == p) {
- // unlink from list,
- //
- if (pprev == l_mempoolList) {
- // this (p) is list begin. so set next as head.
- l_mempoolList = p->next;
- } else {
- // replace prevs next wuth our next.
- pprev->next = p->next;
- }
- break;
- }
-
- pprev = piter;
- piter = piter->next;
- }
-
- p->next = NULL;
- LeaveSpinLock(&l_mempoolListLock);
-
-
- // Get both locks.
- EnterSpinLock(&p->segmentLock);
- EnterSpinLock(&p->nodeLock);
-
-
- if (p->num_nodes_free != p->num_nodes_total)
- ShowWarning("Mempool [%s] Destroy - %u nodes are not freed properly!\n", p->name, (p->num_nodes_total - p->num_nodes_free));
-
- // Free All Segments (this will also free all nodes)
- // The segment pointer is the base pointer to the whole segment.
- seg = p->segments;
- while (1) {
- if (seg == NULL)
- break;
-
- segnext = seg->next;
-
- // ..
- if (p->ondealloc != NULL) {
- // walk over the segment, and call dealloc callback!
- ptr = (char *)seg;
- ptr += ALIGN_TO_16(sizeof(struct pool_segment));
- for (i = 0; i < seg->num_nodes_total; i++) {
- niter = (struct node *)ptr;
- ptr += sizeof(struct node);
- ptr += p->elem_size;
+
+ // Unlink from global list.
+ EnterSpinLock(&l_mempoolListLock);
+ piter = l_mempoolList;
+ pprev = l_mempoolList;
+ while(1){
+ if(piter == NULL)
+ break;
+
+
+ if(piter == p){
+ // unlink from list,
+ //
+ if(pprev == l_mempoolList){
+ // this (p) is list begin. so set next as head.
+ l_mempoolList = p->next;
+ }else{
+ // replace prevs next wuth our next.
+ pprev->next = p->next;
+ }
+ break;
+ }
+
+ pprev = piter;
+ piter = piter->next;
+ }
+
+ p->next = NULL;
+ LeaveSpinLock(&l_mempoolListLock);
+
+
+ // Get both locks.
+ EnterSpinLock(&p->segmentLock);
+ EnterSpinLock(&p->nodeLock);
+
+
+ if(p->num_nodes_free != p->num_nodes_total)
+ ShowWarning("Mempool [%s] Destroy - %u nodes are not freed properly!\n", p->name, (p->num_nodes_total - p->num_nodes_free) );
+
+ // Free All Segments (this will also free all nodes)
+ // The segment pointer is the base pointer to the whole segment.
+ seg = p->segments;
+ while(1){
+ if(seg == NULL)
+ break;
+
+ segnext = seg->next;
+
+ // ..
+ if(p->ondealloc != NULL){
+ // walk over the segment, and call dealloc callback!
+ ptr = (char*)seg;
+ ptr += ALIGN_TO_16(sizeof(struct pool_segment));
+ for(i = 0; i < seg->num_nodes_total; i++){
+ niter = (struct node*)ptr;
+ ptr += sizeof(struct node);
+ ptr += p->elem_size;
#ifdef MEMPOOLASSERT
- if (niter->magic != NODE_MAGIC) {
- ShowError("Mempool [%s] Destroy - walk over segment - node %p invalid magic!\n", p->name, niter);
- continue;
- }
+ if(niter->magic != NODE_MAGIC){
+ ShowError("Mempool [%s] Destroy - walk over segment - node %p invalid magic!\n", p->name, niter);
+ continue;
+ }
#endif
-
- p->ondealloc(NODE_TO_DATA(niter));
-
-
- }
- }//endif: ondealloc callback?
-
- // simple ..
- aFree(seg);
-
- seg = segnext;
- }
-
- // Clear node ptr
- p->free_list = NULL;
- InterlockedExchange64(&p->num_nodes_free, 0);
- InterlockedExchange64(&p->num_nodes_total, 0);
- InterlockedExchange64(&p->num_segments, 0);
- InterlockedExchange64(&p->num_bytes_total, 0);
-
- LeaveSpinLock(&p->nodeLock);
- LeaveSpinLock(&p->segmentLock);
-
- // Free pool itself :D
- aFree(p->name);
- aFree(p);
+
+ p->ondealloc( NODE_TO_DATA(niter) );
+
+
+ }
+ }//endif: ondealloc callback?
+
+ // simple ..
+ aFree(seg);
+
+ seg = segnext;
+ }
+
+ // Clear node ptr
+ p->free_list = NULL;
+ InterlockedExchange64(&p->num_nodes_free, 0);
+ InterlockedExchange64(&p->num_nodes_total, 0);
+ InterlockedExchange64(&p->num_segments, 0);
+ InterlockedExchange64(&p->num_bytes_total, 0);
+
+ LeaveSpinLock(&p->nodeLock);
+ LeaveSpinLock(&p->segmentLock);
+
+ // Free pool itself :D
+ aFree(p->name);
+ aFree(p);
}//end: mempool_destroy()
-void *mempool_node_get(mempool p)
-{
- struct node *node;
- int64 num_used;
-
- if (p->num_nodes_free < p->elem_realloc_thresh)
- racond_signal(l_async_cond);
-
- while (1) {
-
- EnterSpinLock(&p->nodeLock);
-
- node = p->free_list;
- if (node != NULL)
- p->free_list = node->next;
-
- LeaveSpinLock(&p->nodeLock);
-
- if (node != NULL)
- break;
-
- rathread_yield();
- }
-
- InterlockedDecrement64(&p->num_nodes_free);
-
- // Update peak value
- num_used = (p->num_nodes_total - p->num_nodes_free);
- if (num_used > p->peak_nodes_used) {
- InterlockedExchange64(&p->peak_nodes_used, num_used);
- }
-
+void *mempool_node_get(mempool p){
+ struct node *node;
+ int64 num_used;
+
+ if(p->num_nodes_free < p->elem_realloc_thresh)
+ racond_signal(l_async_cond);
+
+ while(1){
+
+ EnterSpinLock(&p->nodeLock);
+
+ node = p->free_list;
+ if(node != NULL)
+ p->free_list = node->next;
+
+ LeaveSpinLock(&p->nodeLock);
+
+ if(node != NULL)
+ break;
+
+ rathread_yield();
+ }
+
+ InterlockedDecrement64(&p->num_nodes_free);
+
+ // Update peak value
+ num_used = (p->num_nodes_total - p->num_nodes_free);
+ if(num_used > p->peak_nodes_used){
+ InterlockedExchange64(&p->peak_nodes_used, num_used);
+ }
+
#ifdef MEMPOOLASSERT
- node->used = true;
+ node->used = true;
#endif
- return NODE_TO_DATA(node);
+ return NODE_TO_DATA(node);
}//end: mempool_node_get()
-void mempool_node_put(mempool p, void *data)
-{
- struct node *node;
-
- node = DATA_TO_NODE(data);
+void mempool_node_put(mempool p, void *data){
+ struct node *node;
+
+ node = DATA_TO_NODE(data);
#ifdef MEMPOOLASSERT
- if (node->magic != NODE_MAGIC) {
- ShowError("Mempool [%s] node_put failed, given address (%p) has invalid magic.\n", p->name, data);
- return; // lost,
- }
-
- {
- struct pool_segment *node_seg = node->segment;
- if (node_seg->pool != p) {
- ShowError("Mempool [%s] node_put faild, given node (data address %p) doesnt belongs to this pool. ( Node Origin is [%s] )\n", p->name, data, node_seg->pool);
- return;
- }
- }
-
- // reset used flag.
- node->used = false;
+ if(node->magic != NODE_MAGIC){
+ ShowError("Mempool [%s] node_put failed, given address (%p) has invalid magic.\n", p->name, data);
+ return; // lost,
+ }
+
+ {
+ struct pool_segment *node_seg = node->segment;
+ if(node_seg->pool != p){
+ ShowError("Mempool [%s] node_put faild, given node (data address %p) doesnt belongs to this pool. ( Node Origin is [%s] )\n", p->name, data, node_seg->pool);
+ return;
+ }
+ }
+
+ // reset used flag.
+ node->used = false;
#endif
- //
- EnterSpinLock(&p->nodeLock);
- node->next = p->free_list;
- p->free_list = node;
- LeaveSpinLock(&p->nodeLock);
-
- InterlockedIncrement64(&p->num_nodes_free);
+ //
+ EnterSpinLock(&p->nodeLock);
+ node->next = p->free_list;
+ p->free_list = node;
+ LeaveSpinLock(&p->nodeLock);
+
+ InterlockedIncrement64(&p->num_nodes_free);
}//end: mempool_node_put()
-mempool_stats mempool_get_stats(mempool pool)
-{
- mempool_stats stats;
-
- // initialize all with zeros
- memset(&stats, 0x00, sizeof(mempool_stats));
-
- stats.num_nodes_total = pool->num_nodes_total;
- stats.num_nodes_free = pool->num_nodes_free;
- stats.num_nodes_used = (stats.num_nodes_total - stats.num_nodes_free);
- stats.num_segments = pool->num_segments;
- stats.num_realloc_events= pool->num_realloc_events;
- stats.peak_nodes_used = pool->peak_nodes_used;
- stats.num_bytes_total = pool->num_bytes_total;
-
- // Pushing such a large block over the stack as return value isnt nice
- // but lazy :) and should be okay in this case (Stats / Debug..)
- // if you dont like it - feel free and refactor it.
- return stats;
+mempool_stats mempool_get_stats(mempool pool){
+ mempool_stats stats;
+
+ // initialize all with zeros
+ memset(&stats, 0x00, sizeof(mempool_stats));
+
+ stats.num_nodes_total = pool->num_nodes_total;
+ stats.num_nodes_free = pool->num_nodes_free;
+ stats.num_nodes_used = (stats.num_nodes_total - stats.num_nodes_free);
+ stats.num_segments = pool->num_segments;
+ stats.num_realloc_events= pool->num_realloc_events;
+ stats.peak_nodes_used = pool->peak_nodes_used;
+ stats.num_bytes_total = pool->num_bytes_total;
+
+ // Pushing such a large block over the stack as return value isnt nice
+ // but lazy :) and should be okay in this case (Stats / Debug..)
+ // if you dont like it - feel free and refactor it.
+ return stats;
}//end: mempool_get_stats()
diff --git a/src/common/mempool.h b/src/common/mempool.h
index 9c4f1563e..aeaebe7fe 100644
--- a/src/common/mempool.h
+++ b/src/common/mempool.h
@@ -8,67 +8,67 @@ typedef struct mempool *mempool;
typedef void (*memPoolOnNodeAllocationProc)(void *ptr);
typedef void (*memPoolOnNodeDeallocationProc)(void *ptr);
-typedef struct mempool_stats {
- int64 num_nodes_total;
- int64 num_nodes_free;
- int64 num_nodes_used;
-
- int64 num_segments;
- int64 num_realloc_events;
-
- int64 peak_nodes_used;
-
- int64 num_bytes_total;
+typedef struct mempool_stats{
+ int64 num_nodes_total;
+ int64 num_nodes_free;
+ int64 num_nodes_used;
+
+ int64 num_segments;
+ int64 num_realloc_events;
+
+ int64 peak_nodes_used;
+
+ int64 num_bytes_total;
} mempool_stats;
-//
+//
void mempool_init();
void mempool_final();
-/**
+/**
* Creates a new Mempool
*
* @param name - Name of the pool (used for debug / error messages)
* @param elem_size - size of each element
- * @param initial_count - preallocation count
+ * @param initial_count - preallocation count
* @param realloc_count - #no of nodes being allocated when pool is running empty.
* @param onNodeAlloc - Node Allocation callback (see @note!)
* @param onNodeDealloc - Node Deallocation callback (see @note!)
*
* @note:
- * The onNode(De)alloc callbacks are only called once during segment allocation
- * (pool initialization / rallocation )
+ * The onNode(De)alloc callbacks are only called once during segment allocation
+ * (pool initialization / rallocation )
* you can use this callbacks for example to initlaize a mutex or somethingelse
- * you definitly need during runtime
+ * you definitly need during runtime
*
* @return not NULL
*/
mempool mempool_create(const char *name,
- uint64 elem_size,
- uint64 initial_count,
- uint64 realloc_count,
-
- memPoolOnNodeAllocationProc onNodeAlloc,
- memPoolOnNodeDeallocationProc onNodeDealloc);
-
-
+ uint64 elem_size,
+ uint64 initial_count,
+ uint64 realloc_count,
+
+ memPoolOnNodeAllocationProc onNodeAlloc,
+ memPoolOnNodeDeallocationProc onNodeDealloc);
+
+
/**
* Destroys a Mempool
- *
+ *
* @param pool - the mempool to destroy
*
* @note:
- * Everything gets deallocated, regardless if everything was freed properly!
- * So you have to ensure that all references are cleared properly!
+ * Everything gets deallocated, regardless if everything was freed properly!
+ * So you have to ensure that all references are cleared properly!
*/
void mempool_destroy(mempool pool);
/**
* Gets a new / empty node from the given mempool.
- *
+ *
* @param pool - the pool to get an empty node from.
*
* @return Address of empty Node
@@ -80,12 +80,12 @@ void *mempool_node_get(mempool pool);
* Returns the given node to the given mempool
*
* @param pool - the pool to put the node, to
- * @param node - the node to return
+ * @param node - the node to return
*/
void mempool_node_put(mempool pool, void *node);
-/**
+/**
* Returns Statistics for the given mempool
*
* @param pool - the pool to get thats for
diff --git a/src/common/mmo.h b/src/common/mmo.h
index 4236eb4c6..5f6108b33 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -1,8 +1,8 @@
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder
-#ifndef _MMO_H_
-#define _MMO_H_
+#ifndef _MMO_H_
+#define _MMO_H_
#include "cbasetypes.h"
#include <time.h>
@@ -46,25 +46,25 @@
// 20120307 - 2012-03-07aRagexeRE+ - 0x970
#ifndef PACKETVER
-#define PACKETVER 20120410
-//#define PACKETVER 20111116
+ #define PACKETVER 20120410
+ //#define PACKETVER 20111116
#endif
//Remove/Comment this line to disable sc_data saving. [Skotlex]
-#define ENABLE_SC_SAVING
+#define ENABLE_SC_SAVING
//Remove/Comment this line to disable server-side hot-key saving support [Skotlex]
//Note that newer clients no longer save hotkeys in the registry!
#define HOTKEY_SAVING
#if PACKETVER < 20090603
-// (27 = 9 skills x 3 bars) (0x02b9,191)
-#define MAX_HOTKEYS 27
+ // (27 = 9 skills x 3 bars) (0x02b9,191)
+ #define MAX_HOTKEYS 27
#elif PACKETVER < 20090617
-// (36 = 9 skills x 4 bars) (0x07d9,254)
-#define MAX_HOTKEYS 36
+ // (36 = 9 skills x 4 bars) (0x07d9,254)
+ #define MAX_HOTKEYS 36
#else
-// (38 = 9 skills x 4 bars & 2 Quickslots)(0x07d9,268)
-#define MAX_HOTKEYS 38
+ // (38 = 9 skills x 4 bars & 2 Quickslots)(0x07d9,268)
+ #define MAX_HOTKEYS 38
#endif
#define MAX_MAP_PER_SERVER 1500 // Increased to allow creation of Instance Maps
@@ -91,13 +91,13 @@
#define MAX_STORAGE 600
#define MAX_GUILD_STORAGE 600
#define MAX_PARTY 12
-#define MAX_GUILD 16+10*6 // increased max guild members +6 per 1 extension levels [Lupus]
-#define MAX_GUILDPOSITION 20 // increased max guild positions to accomodate for all members [Valaris] (removed) [PoW]
+#define MAX_GUILD 16+10*6 // increased max guild members +6 per 1 extension levels [Lupus]
+#define MAX_GUILDPOSITION 20 // increased max guild positions to accomodate for all members [Valaris] (removed) [PoW]
#define MAX_GUILDEXPULSION 32
#define MAX_GUILDALLIANCE 16
-#define MAX_GUILDSKILL 15 // increased max guild skills because of new skills [Sara-chan]
+#define MAX_GUILDSKILL 15 // increased max guild skills because of new skills [Sara-chan]
#define MAX_GUILDLEVEL 50
-#define MAX_GUARDIANS 8 //Local max per castle. [Skotlex]
+#define MAX_GUARDIANS 8 //Local max per castle. [Skotlex]
#define MAX_QUEST_DB 2000 //Max quests that the server will load
#define MAX_QUEST_OBJECTIVES 3 //Max quest objectives for a quest
@@ -140,7 +140,7 @@
//Base Homun skill.
#define HM_SKILLBASE 8001
#define MAX_HOMUNSKILL 43
-#define MAX_HOMUNCULUS_CLASS 52 //[orn], Increased to 60 from 16 to allow new Homun-S.
+#define MAX_HOMUNCULUS_CLASS 52 //[orn], Increased to 60 from 16 to allow new Homun-S.
#define HM_CLASS_BASE 6001
#define HM_CLASS_MAX (HM_CLASS_BASE+MAX_HOMUNCULUS_CLASS-1)
@@ -163,20 +163,20 @@
#define EL_CLASS_MAX (EL_CLASS_BASE+MAX_ELEMENTAL_CLASS-1)
enum item_types {
- IT_HEALING = 0,
- IT_UNKNOWN, //1
- IT_USABLE, //2
- IT_ETC, //3
- IT_WEAPON, //4
- IT_ARMOR, //5
- IT_CARD, //6
- IT_PETEGG, //7
- IT_PETARMOR,//8
- IT_UNKNOWN2,//9
- IT_AMMO, //10
- IT_DELAYCONSUME,//11
- IT_CASH = 18,
- IT_MAX
+ IT_HEALING = 0,
+ IT_UNKNOWN, //1
+ IT_USABLE, //2
+ IT_ETC, //3
+ IT_WEAPON, //4
+ IT_ARMOR, //5
+ IT_CARD, //6
+ IT_PETEGG, //7
+ IT_PETARMOR,//8
+ IT_UNKNOWN2,//9
+ IT_AMMO, //10
+ IT_DELAYCONSUME,//11
+ IT_CASH = 18,
+ IT_MAX
};
@@ -184,555 +184,556 @@ enum item_types {
typedef enum quest_state { Q_INACTIVE, Q_ACTIVE, Q_COMPLETE } quest_state;
struct quest {
- int quest_id;
- unsigned int time;
- int count[MAX_QUEST_OBJECTIVES];
- quest_state state;
+ int quest_id;
+ unsigned int time;
+ int count[MAX_QUEST_OBJECTIVES];
+ quest_state state;
};
struct item {
- int id;
- short nameid;
- short amount;
- unsigned short equip; // location(s) where item is equipped (using enum equip_pos for bitmasking)
- char identify;
- char refine;
- char attribute;
- short card[MAX_SLOTS];
- unsigned int expire_time;
- char favorite;
+ int id;
+ short nameid;
+ short amount;
+ unsigned short equip; // location(s) where item is equipped (using enum equip_pos for bitmasking)
+ char identify;
+ char refine;
+ char attribute;
+ short card[MAX_SLOTS];
+ unsigned int expire_time;
+ char favorite;
};
struct point {
- unsigned short map;
- short x,y;
+ unsigned short map;
+ short x,y;
};
-enum e_skill_flag {
- SKILL_FLAG_PERMANENT,
- SKILL_FLAG_TEMPORARY,
- SKILL_FLAG_PLAGIARIZED,
- SKILL_FLAG_REPLACED_LV_0, // temporary skill overshadowing permanent skill of level 'N - SKILL_FLAG_REPLACED_LV_0'
- //...
+enum e_skill_flag
+{
+ SKILL_FLAG_PERMANENT,
+ SKILL_FLAG_TEMPORARY,
+ SKILL_FLAG_PLAGIARIZED,
+ SKILL_FLAG_REPLACED_LV_0, // temporary skill overshadowing permanent skill of level 'N - SKILL_FLAG_REPLACED_LV_0'
+ //...
};
struct s_skill {
- unsigned short id;
- unsigned char lv;
- unsigned char flag; // see enum e_skill_flag
+ unsigned short id;
+ unsigned char lv;
+ unsigned char flag; // see enum e_skill_flag
};
struct global_reg {
- char str[32];
- char value[256];
+ char str[32];
+ char value[256];
};
//Holds array of global registries, used by the char server and converter.
struct accreg {
- int account_id, char_id;
- int reg_num;
- struct global_reg reg[MAX_REG_NUM];
+ int account_id, char_id;
+ int reg_num;
+ struct global_reg reg[MAX_REG_NUM];
};
//For saving status changes across sessions. [Skotlex]
struct status_change_data {
- unsigned short type; //SC_type
- long val1, val2, val3, val4, tick; //Remaining duration.
+ unsigned short type; //SC_type
+ long val1, val2, val3, val4, tick; //Remaining duration.
};
struct storage_data {
- int storage_amount;
- struct item items[MAX_STORAGE];
+ int storage_amount;
+ struct item items[MAX_STORAGE];
};
struct guild_storage {
- int dirty;
- int guild_id;
- short storage_status;
- short storage_amount;
- struct item items[MAX_GUILD_STORAGE];
+ int dirty;
+ int guild_id;
+ short storage_status;
+ short storage_amount;
+ struct item items[MAX_GUILD_STORAGE];
};
struct s_pet {
- int account_id;
- int char_id;
- int pet_id;
- short class_;
- short level;
- short egg_id;//pet egg id
- short equip;//pet equip name_id
- short intimate;//pet friendly
- short hungry;//pet hungry
- char name[NAME_LENGTH];
- char rename_flag;
- char incuvate;
-};
-
-struct s_homunculus { //[orn]
- char name[NAME_LENGTH];
- int hom_id;
- int char_id;
- short class_;
- short prev_class;
- int hp,max_hp,sp,max_sp;
- unsigned int intimacy; //[orn]
- short hunger;
- struct s_skill hskill[MAX_HOMUNSKILL]; //albator
- short skillpts;
- short level;
- unsigned int exp;
- short rename_flag;
- short vaporize; //albator
- int str ;
- int agi ;
- int vit ;
- int int_ ;
- int dex ;
- int luk ;
+ int account_id;
+ int char_id;
+ int pet_id;
+ short class_;
+ short level;
+ short egg_id;//pet egg id
+ short equip;//pet equip name_id
+ short intimate;//pet friendly
+ short hungry;//pet hungry
+ char name[NAME_LENGTH];
+ char rename_flag;
+ char incuvate;
+};
+
+struct s_homunculus { //[orn]
+ char name[NAME_LENGTH];
+ int hom_id;
+ int char_id;
+ short class_;
+ short prev_class;
+ int hp,max_hp,sp,max_sp;
+ unsigned int intimacy; //[orn]
+ short hunger;
+ struct s_skill hskill[MAX_HOMUNSKILL]; //albator
+ short skillpts;
+ short level;
+ unsigned int exp;
+ short rename_flag;
+ short vaporize; //albator
+ int str ;
+ int agi ;
+ int vit ;
+ int int_ ;
+ int dex ;
+ int luk ;
};
struct s_mercenary {
- int mercenary_id;
- int char_id;
- short class_;
- int hp, sp;
- unsigned int kill_count;
- unsigned int life_time;
+ int mercenary_id;
+ int char_id;
+ short class_;
+ int hp, sp;
+ unsigned int kill_count;
+ unsigned int life_time;
};
struct s_elemental {
- int elemental_id;
- int char_id;
- short class_;
- int mode;
- int hp, sp, max_hp, max_sp, str, agi, vit, int_, dex, luk;
- int life_time;
+ int elemental_id;
+ int char_id;
+ short class_;
+ int mode;
+ int hp, sp, max_hp, max_sp, str, agi, vit, int_, dex, luk;
+ int life_time;
};
struct s_friend {
- int account_id;
- int char_id;
- char name[NAME_LENGTH];
+ int account_id;
+ int char_id;
+ char name[NAME_LENGTH];
};
#ifdef HOTKEY_SAVING
struct hotkey {
- unsigned int id;
- unsigned short lv;
- unsigned char type; // 0: item, 1: skill
+ unsigned int id;
+ unsigned short lv;
+ unsigned char type; // 0: item, 1: skill
};
#endif
struct mmo_charstatus {
- int char_id;
- int account_id;
- int partner_id;
- int father;
- int mother;
- int child;
-
- unsigned int base_exp,job_exp;
- int zeny;
-
- short class_;
- unsigned int status_point,skill_point;
- int hp,max_hp,sp,max_sp;
- unsigned int option;
- short manner;
- unsigned char karma;
- short hair,hair_color,clothes_color;
- int party_id,guild_id,pet_id,hom_id,mer_id,ele_id;
- int fame;
-
- // Mercenary Guilds Rank
- int arch_faith, arch_calls;
- int spear_faith, spear_calls;
- int sword_faith, sword_calls;
-
- short weapon; // enum weapon_type
- short shield; // view-id
- short head_top,head_mid,head_bottom;
- short robe;
-
- char name[NAME_LENGTH];
- unsigned int base_level,job_level;
- short str,agi,vit,int_,dex,luk;
- unsigned char slot,sex;
-
- uint32 mapip;
- uint16 mapport;
-
- struct point last_point,save_point,memo_point[MAX_MEMOPOINTS];
- struct item inventory[MAX_INVENTORY],cart[MAX_CART];
- struct storage_data storage;
- struct s_skill skill[MAX_SKILL];
-
- struct s_friend friends[MAX_FRIENDS]; //New friend system [Skotlex]
+ int char_id;
+ int account_id;
+ int partner_id;
+ int father;
+ int mother;
+ int child;
+
+ unsigned int base_exp,job_exp;
+ int zeny;
+
+ short class_;
+ unsigned int status_point,skill_point;
+ int hp,max_hp,sp,max_sp;
+ unsigned int option;
+ short manner;
+ unsigned char karma;
+ short hair,hair_color,clothes_color;
+ int party_id,guild_id,pet_id,hom_id,mer_id,ele_id;
+ int fame;
+
+ // Mercenary Guilds Rank
+ int arch_faith, arch_calls;
+ int spear_faith, spear_calls;
+ int sword_faith, sword_calls;
+
+ short weapon; // enum weapon_type
+ short shield; // view-id
+ short head_top,head_mid,head_bottom;
+ short robe;
+
+ char name[NAME_LENGTH];
+ unsigned int base_level,job_level;
+ short str,agi,vit,int_,dex,luk;
+ unsigned char slot,sex;
+
+ uint32 mapip;
+ uint16 mapport;
+
+ struct point last_point,save_point,memo_point[MAX_MEMOPOINTS];
+ struct item inventory[MAX_INVENTORY],cart[MAX_CART];
+ struct storage_data storage;
+ struct s_skill skill[MAX_SKILL];
+
+ struct s_friend friends[MAX_FRIENDS]; //New friend system [Skotlex]
#ifdef HOTKEY_SAVING
- struct hotkey hotkeys[MAX_HOTKEYS];
+ struct hotkey hotkeys[MAX_HOTKEYS];
#endif
- bool show_equip;
- short rename;
+ bool show_equip;
+ short rename;
- time_t delete_date;
+ time_t delete_date;
};
typedef enum mail_status {
- MAIL_NEW,
- MAIL_UNREAD,
- MAIL_READ,
+ MAIL_NEW,
+ MAIL_UNREAD,
+ MAIL_READ,
} mail_status;
struct mail_message {
- int id;
- int send_id;
- char send_name[NAME_LENGTH];
- int dest_id;
- char dest_name[NAME_LENGTH];
- char title[MAIL_TITLE_LENGTH];
- char body[MAIL_BODY_LENGTH];
+ int id;
+ int send_id;
+ char send_name[NAME_LENGTH];
+ int dest_id;
+ char dest_name[NAME_LENGTH];
+ char title[MAIL_TITLE_LENGTH];
+ char body[MAIL_BODY_LENGTH];
- mail_status status;
- time_t timestamp; // marks when the message was sent
+ mail_status status;
+ time_t timestamp; // marks when the message was sent
- int zeny;
- struct item item;
+ int zeny;
+ struct item item;
};
struct mail_data {
- short amount;
- bool full;
- short unchecked, unread;
- struct mail_message msg[MAIL_MAX_INBOX];
+ short amount;
+ bool full;
+ short unchecked, unread;
+ struct mail_message msg[MAIL_MAX_INBOX];
};
struct auction_data {
- unsigned int auction_id;
- int seller_id;
- char seller_name[NAME_LENGTH];
- int buyer_id;
- char buyer_name[NAME_LENGTH];
-
- struct item item;
- // This data is required for searching, as itemdb is not read by char server
- char item_name[ITEM_NAME_LENGTH];
- short type;
-
- unsigned short hours;
- int price, buynow;
- time_t timestamp; // auction's end time
- int auction_end_timer;
+ unsigned int auction_id;
+ int seller_id;
+ char seller_name[NAME_LENGTH];
+ int buyer_id;
+ char buyer_name[NAME_LENGTH];
+
+ struct item item;
+ // This data is required for searching, as itemdb is not read by char server
+ char item_name[ITEM_NAME_LENGTH];
+ short type;
+
+ unsigned short hours;
+ int price, buynow;
+ time_t timestamp; // auction's end time
+ int auction_end_timer;
};
struct registry {
- int global_num;
- struct global_reg global[GLOBAL_REG_NUM];
- int account_num;
- struct global_reg account[ACCOUNT_REG_NUM];
- int account2_num;
- struct global_reg account2[ACCOUNT_REG2_NUM];
+ int global_num;
+ struct global_reg global[GLOBAL_REG_NUM];
+ int account_num;
+ struct global_reg account[ACCOUNT_REG_NUM];
+ int account2_num;
+ struct global_reg account2[ACCOUNT_REG2_NUM];
};
struct party_member {
- int account_id;
- int char_id;
- char name[NAME_LENGTH];
- unsigned short class_;
- unsigned short map;
- unsigned short lv;
- unsigned leader : 1,
- online : 1;
+ int account_id;
+ int char_id;
+ char name[NAME_LENGTH];
+ unsigned short class_;
+ unsigned short map;
+ unsigned short lv;
+ unsigned leader : 1,
+ online : 1;
};
struct party {
- int party_id;
- char name[NAME_LENGTH];
- unsigned char count; //Count of online characters.
- unsigned exp : 1,
- item : 2; //&1: Party-Share (round-robin), &2: pickup style: shared.
- struct party_member member[MAX_PARTY];
+ int party_id;
+ char name[NAME_LENGTH];
+ unsigned char count; //Count of online characters.
+ unsigned exp : 1,
+ item : 2; //&1: Party-Share (round-robin), &2: pickup style: shared.
+ struct party_member member[MAX_PARTY];
};
struct map_session_data;
struct guild_member {
- int account_id, char_id;
- short hair,hair_color,gender,class_,lv;
- uint64 exp;
- int exp_payper;
- short online,position;
- char name[NAME_LENGTH];
- struct map_session_data *sd;
- unsigned char modified;
+ int account_id, char_id;
+ short hair,hair_color,gender,class_,lv;
+ uint64 exp;
+ int exp_payper;
+ short online,position;
+ char name[NAME_LENGTH];
+ struct map_session_data *sd;
+ unsigned char modified;
};
struct guild_position {
- char name[NAME_LENGTH];
- int mode;
- int exp_mode;
- unsigned char modified;
+ char name[NAME_LENGTH];
+ int mode;
+ int exp_mode;
+ unsigned char modified;
};
struct guild_alliance {
- int opposition;
- int guild_id;
- char name[NAME_LENGTH];
+ int opposition;
+ int guild_id;
+ char name[NAME_LENGTH];
};
struct guild_expulsion {
- char name[NAME_LENGTH];
- char mes[40];
- int account_id;
+ char name[NAME_LENGTH];
+ char mes[40];
+ int account_id;
};
struct guild_skill {
- int id,lv;
+ int id,lv;
};
struct guild {
- int guild_id;
- short guild_lv, connect_member, max_member, average_lv;
- uint64 exp;
- unsigned int next_exp;
- int skill_point;
- char name[NAME_LENGTH],master[NAME_LENGTH];
- struct guild_member member[MAX_GUILD];
- struct guild_position position[MAX_GUILDPOSITION];
- char mes1[MAX_GUILDMES1],mes2[MAX_GUILDMES2];
- int emblem_len,emblem_id;
- char emblem_data[2048];
- struct guild_alliance alliance[MAX_GUILDALLIANCE];
- struct guild_expulsion expulsion[MAX_GUILDEXPULSION];
- struct guild_skill skill[MAX_GUILDSKILL];
-
- unsigned short save_flag; // for TXT saving
+ int guild_id;
+ short guild_lv, connect_member, max_member, average_lv;
+ uint64 exp;
+ unsigned int next_exp;
+ int skill_point;
+ char name[NAME_LENGTH],master[NAME_LENGTH];
+ struct guild_member member[MAX_GUILD];
+ struct guild_position position[MAX_GUILDPOSITION];
+ char mes1[MAX_GUILDMES1],mes2[MAX_GUILDMES2];
+ int emblem_len,emblem_id;
+ char emblem_data[2048];
+ struct guild_alliance alliance[MAX_GUILDALLIANCE];
+ struct guild_expulsion expulsion[MAX_GUILDEXPULSION];
+ struct guild_skill skill[MAX_GUILDSKILL];
+
+ unsigned short save_flag; // for TXT saving
};
struct guild_castle {
- int castle_id;
- int mapindex;
- char castle_name[NAME_LENGTH];
- char castle_event[NAME_LENGTH];
- int guild_id;
- int economy;
- int defense;
- int triggerE;
- int triggerD;
- int nextTime;
- int payTime;
- int createTime;
- int visibleC;
- struct {
- unsigned visible : 1;
- int id; // object id
- } guardian[MAX_GUARDIANS];
- int *temp_guardians; // ids of temporary guardians (mobs)
- int temp_guardians_max;
+ int castle_id;
+ int mapindex;
+ char castle_name[NAME_LENGTH];
+ char castle_event[NAME_LENGTH];
+ int guild_id;
+ int economy;
+ int defense;
+ int triggerE;
+ int triggerD;
+ int nextTime;
+ int payTime;
+ int createTime;
+ int visibleC;
+ struct {
+ unsigned visible : 1;
+ int id; // object id
+ } guardian[MAX_GUARDIANS];
+ int* temp_guardians; // ids of temporary guardians (mobs)
+ int temp_guardians_max;
};
struct fame_list {
- int id;
- int fame;
- char name[NAME_LENGTH];
+ int id;
+ int fame;
+ char name[NAME_LENGTH];
};
-enum { //Change Guild Infos
- GBI_EXP =1, // Guild Experience (EXP)
- GBI_GUILDLV, // Guild level
- GBI_SKILLPOINT, // Guild skillpoints
- GBI_SKILLLV, // Guild skilllv ?? seem unused
+enum { //Change Guild Infos
+ GBI_EXP =1, // Guild Experience (EXP)
+ GBI_GUILDLV, // Guild level
+ GBI_SKILLPOINT, // Guild skillpoints
+ GBI_SKILLLV, // Guild skilllv ?? seem unused
};
enum { //Change Member Infos
- GMI_POSITION =0,
- GMI_EXP,
- GMI_HAIR,
- GMI_HAIR_COLOR,
- GMI_GENDER,
- GMI_CLASS,
- GMI_LEVEL,
+ GMI_POSITION =0,
+ GMI_EXP,
+ GMI_HAIR,
+ GMI_HAIR_COLOR,
+ GMI_GENDER,
+ GMI_CLASS,
+ GMI_LEVEL,
};
enum {
- GD_SKILLBASE=10000,
- GD_APPROVAL=10000,
- GD_KAFRACONTRACT=10001,
- GD_GUARDRESEARCH=10002,
- GD_GUARDUP=10003,
- GD_EXTENSION=10004,
- GD_GLORYGUILD=10005,
- GD_LEADERSHIP=10006,
- GD_GLORYWOUNDS=10007,
- GD_SOULCOLD=10008,
- GD_HAWKEYES=10009,
- GD_BATTLEORDER=10010,
- GD_REGENERATION=10011,
- GD_RESTORE=10012,
- GD_EMERGENCYCALL=10013,
- GD_DEVELOPMENT=10014,
- GD_MAX,
+ GD_SKILLBASE=10000,
+ GD_APPROVAL=10000,
+ GD_KAFRACONTRACT=10001,
+ GD_GUARDRESEARCH=10002,
+ GD_GUARDUP=10003,
+ GD_EXTENSION=10004,
+ GD_GLORYGUILD=10005,
+ GD_LEADERSHIP=10006,
+ GD_GLORYWOUNDS=10007,
+ GD_SOULCOLD=10008,
+ GD_HAWKEYES=10009,
+ GD_BATTLEORDER=10010,
+ GD_REGENERATION=10011,
+ GD_RESTORE=10012,
+ GD_EMERGENCYCALL=10013,
+ GD_DEVELOPMENT=10014,
+ GD_MAX,
};
//These mark the ID of the jobs, as expected by the client. [Skotlex]
enum {
- JOB_NOVICE,
- JOB_SWORDMAN,
- JOB_MAGE,
- JOB_ARCHER,
- JOB_ACOLYTE,
- JOB_MERCHANT,
- JOB_THIEF,
- JOB_KNIGHT,
- JOB_PRIEST,
- JOB_WIZARD,
- JOB_BLACKSMITH,
- JOB_HUNTER,
- JOB_ASSASSIN,
- JOB_KNIGHT2,
- JOB_CRUSADER,
- JOB_MONK,
- JOB_SAGE,
- JOB_ROGUE,
- JOB_ALCHEMIST,
- JOB_BARD,
- JOB_DANCER,
- JOB_CRUSADER2,
- JOB_WEDDING,
- JOB_SUPER_NOVICE,
- JOB_GUNSLINGER,
- JOB_NINJA,
- JOB_XMAS,
- JOB_SUMMER,
- JOB_MAX_BASIC,
-
- JOB_NOVICE_HIGH = 4001,
- JOB_SWORDMAN_HIGH,
- JOB_MAGE_HIGH,
- JOB_ARCHER_HIGH,
- JOB_ACOLYTE_HIGH,
- JOB_MERCHANT_HIGH,
- JOB_THIEF_HIGH,
- JOB_LORD_KNIGHT,
- JOB_HIGH_PRIEST,
- JOB_HIGH_WIZARD,
- JOB_WHITESMITH,
- JOB_SNIPER,
- JOB_ASSASSIN_CROSS,
- JOB_LORD_KNIGHT2,
- JOB_PALADIN,
- JOB_CHAMPION,
- JOB_PROFESSOR,
- JOB_STALKER,
- JOB_CREATOR,
- JOB_CLOWN,
- JOB_GYPSY,
- JOB_PALADIN2,
-
- JOB_BABY,
- JOB_BABY_SWORDMAN,
- JOB_BABY_MAGE,
- JOB_BABY_ARCHER,
- JOB_BABY_ACOLYTE,
- JOB_BABY_MERCHANT,
- JOB_BABY_THIEF,
- JOB_BABY_KNIGHT,
- JOB_BABY_PRIEST,
- JOB_BABY_WIZARD,
- JOB_BABY_BLACKSMITH,
- JOB_BABY_HUNTER,
- JOB_BABY_ASSASSIN,
- JOB_BABY_KNIGHT2,
- JOB_BABY_CRUSADER,
- JOB_BABY_MONK,
- JOB_BABY_SAGE,
- JOB_BABY_ROGUE,
- JOB_BABY_ALCHEMIST,
- JOB_BABY_BARD,
- JOB_BABY_DANCER,
- JOB_BABY_CRUSADER2,
- JOB_SUPER_BABY,
-
- JOB_TAEKWON,
- JOB_STAR_GLADIATOR,
- JOB_STAR_GLADIATOR2,
- JOB_SOUL_LINKER,
-
- JOB_GANGSI,
- JOB_DEATH_KNIGHT,
- JOB_DARK_COLLECTOR,
-
- JOB_RUNE_KNIGHT = 4054,
- JOB_WARLOCK,
- JOB_RANGER,
- JOB_ARCH_BISHOP,
- JOB_MECHANIC,
- JOB_GUILLOTINE_CROSS,
-
- JOB_RUNE_KNIGHT_T,
- JOB_WARLOCK_T,
- JOB_RANGER_T,
- JOB_ARCH_BISHOP_T,
- JOB_MECHANIC_T,
- JOB_GUILLOTINE_CROSS_T,
-
- JOB_ROYAL_GUARD,
- JOB_SORCERER,
- JOB_MINSTREL,
- JOB_WANDERER,
- JOB_SURA,
- JOB_GENETIC,
- JOB_SHADOW_CHASER,
-
- JOB_ROYAL_GUARD_T,
- JOB_SORCERER_T,
- JOB_MINSTREL_T,
- JOB_WANDERER_T,
- JOB_SURA_T,
- JOB_GENETIC_T,
- JOB_SHADOW_CHASER_T,
-
- JOB_RUNE_KNIGHT2,
- JOB_RUNE_KNIGHT_T2,
- JOB_ROYAL_GUARD2,
- JOB_ROYAL_GUARD_T2,
- JOB_RANGER2,
- JOB_RANGER_T2,
- JOB_MECHANIC2,
- JOB_MECHANIC_T2,
-
- JOB_BABY_RUNE = 4096,
- JOB_BABY_WARLOCK,
- JOB_BABY_RANGER,
- JOB_BABY_BISHOP,
- JOB_BABY_MECHANIC,
- JOB_BABY_CROSS,
-
- JOB_BABY_GUARD,
- JOB_BABY_SORCERER,
- JOB_BABY_MINSTREL,
- JOB_BABY_WANDERER,
- JOB_BABY_SURA,
- JOB_BABY_GENETIC,
- JOB_BABY_CHASER,
-
- JOB_BABY_RUNE2,
- JOB_BABY_GUARD2,
- JOB_BABY_RANGER2,
- JOB_BABY_MECHANIC2,
-
- JOB_SUPER_NOVICE_E = 4190,
- JOB_SUPER_BABY_E,
-
- JOB_KAGEROU = 4211,
- JOB_OBORO,
-
- JOB_MAX,
+ JOB_NOVICE,
+ JOB_SWORDMAN,
+ JOB_MAGE,
+ JOB_ARCHER,
+ JOB_ACOLYTE,
+ JOB_MERCHANT,
+ JOB_THIEF,
+ JOB_KNIGHT,
+ JOB_PRIEST,
+ JOB_WIZARD,
+ JOB_BLACKSMITH,
+ JOB_HUNTER,
+ JOB_ASSASSIN,
+ JOB_KNIGHT2,
+ JOB_CRUSADER,
+ JOB_MONK,
+ JOB_SAGE,
+ JOB_ROGUE,
+ JOB_ALCHEMIST,
+ JOB_BARD,
+ JOB_DANCER,
+ JOB_CRUSADER2,
+ JOB_WEDDING,
+ JOB_SUPER_NOVICE,
+ JOB_GUNSLINGER,
+ JOB_NINJA,
+ JOB_XMAS,
+ JOB_SUMMER,
+ JOB_MAX_BASIC,
+
+ JOB_NOVICE_HIGH = 4001,
+ JOB_SWORDMAN_HIGH,
+ JOB_MAGE_HIGH,
+ JOB_ARCHER_HIGH,
+ JOB_ACOLYTE_HIGH,
+ JOB_MERCHANT_HIGH,
+ JOB_THIEF_HIGH,
+ JOB_LORD_KNIGHT,
+ JOB_HIGH_PRIEST,
+ JOB_HIGH_WIZARD,
+ JOB_WHITESMITH,
+ JOB_SNIPER,
+ JOB_ASSASSIN_CROSS,
+ JOB_LORD_KNIGHT2,
+ JOB_PALADIN,
+ JOB_CHAMPION,
+ JOB_PROFESSOR,
+ JOB_STALKER,
+ JOB_CREATOR,
+ JOB_CLOWN,
+ JOB_GYPSY,
+ JOB_PALADIN2,
+
+ JOB_BABY,
+ JOB_BABY_SWORDMAN,
+ JOB_BABY_MAGE,
+ JOB_BABY_ARCHER,
+ JOB_BABY_ACOLYTE,
+ JOB_BABY_MERCHANT,
+ JOB_BABY_THIEF,
+ JOB_BABY_KNIGHT,
+ JOB_BABY_PRIEST,
+ JOB_BABY_WIZARD,
+ JOB_BABY_BLACKSMITH,
+ JOB_BABY_HUNTER,
+ JOB_BABY_ASSASSIN,
+ JOB_BABY_KNIGHT2,
+ JOB_BABY_CRUSADER,
+ JOB_BABY_MONK,
+ JOB_BABY_SAGE,
+ JOB_BABY_ROGUE,
+ JOB_BABY_ALCHEMIST,
+ JOB_BABY_BARD,
+ JOB_BABY_DANCER,
+ JOB_BABY_CRUSADER2,
+ JOB_SUPER_BABY,
+
+ JOB_TAEKWON,
+ JOB_STAR_GLADIATOR,
+ JOB_STAR_GLADIATOR2,
+ JOB_SOUL_LINKER,
+
+ JOB_GANGSI,
+ JOB_DEATH_KNIGHT,
+ JOB_DARK_COLLECTOR,
+
+ JOB_RUNE_KNIGHT = 4054,
+ JOB_WARLOCK,
+ JOB_RANGER,
+ JOB_ARCH_BISHOP,
+ JOB_MECHANIC,
+ JOB_GUILLOTINE_CROSS,
+
+ JOB_RUNE_KNIGHT_T,
+ JOB_WARLOCK_T,
+ JOB_RANGER_T,
+ JOB_ARCH_BISHOP_T,
+ JOB_MECHANIC_T,
+ JOB_GUILLOTINE_CROSS_T,
+
+ JOB_ROYAL_GUARD,
+ JOB_SORCERER,
+ JOB_MINSTREL,
+ JOB_WANDERER,
+ JOB_SURA,
+ JOB_GENETIC,
+ JOB_SHADOW_CHASER,
+
+ JOB_ROYAL_GUARD_T,
+ JOB_SORCERER_T,
+ JOB_MINSTREL_T,
+ JOB_WANDERER_T,
+ JOB_SURA_T,
+ JOB_GENETIC_T,
+ JOB_SHADOW_CHASER_T,
+
+ JOB_RUNE_KNIGHT2,
+ JOB_RUNE_KNIGHT_T2,
+ JOB_ROYAL_GUARD2,
+ JOB_ROYAL_GUARD_T2,
+ JOB_RANGER2,
+ JOB_RANGER_T2,
+ JOB_MECHANIC2,
+ JOB_MECHANIC_T2,
+
+ JOB_BABY_RUNE = 4096,
+ JOB_BABY_WARLOCK,
+ JOB_BABY_RANGER,
+ JOB_BABY_BISHOP,
+ JOB_BABY_MECHANIC,
+ JOB_BABY_CROSS,
+
+ JOB_BABY_GUARD,
+ JOB_BABY_SORCERER,
+ JOB_BABY_MINSTREL,
+ JOB_BABY_WANDERER,
+ JOB_BABY_SURA,
+ JOB_BABY_GENETIC,
+ JOB_BABY_CHASER,
+
+ JOB_BABY_RUNE2,
+ JOB_BABY_GUARD2,
+ JOB_BABY_RANGER2,
+ JOB_BABY_MECHANIC2,
+
+ JOB_SUPER_NOVICE_E = 4190,
+ JOB_SUPER_BABY_E,
+
+ JOB_KAGEROU = 4211,
+ JOB_OBORO,
+
+ JOB_MAX,
};
enum {
- SEX_FEMALE = 0,
- SEX_MALE,
- SEX_SERVER
+ SEX_FEMALE = 0,
+ SEX_MALE,
+ SEX_SERVER
};
// sanity checks...
diff --git a/src/common/mutex.c b/src/common/mutex.c
index 813bef31b..6b4f55119 100644
--- a/src/common/mutex.c
+++ b/src/common/mutex.c
@@ -15,26 +15,26 @@
#include "../common/timer.h"
#include "../common/mutex.h"
-struct ramutex {
+struct ramutex{
#ifdef WIN32
- CRITICAL_SECTION hMutex;
+ CRITICAL_SECTION hMutex;
#else
- pthread_mutex_t hMutex;
+ pthread_mutex_t hMutex;
#endif
};
-struct racond {
+struct racond{
#ifdef WIN32
- HANDLE events[2];
- ra_align(8) volatile LONG nWaiters;
- CRITICAL_SECTION waiters_lock;
+ HANDLE events[2];
+ ra_align(8) volatile LONG nWaiters;
+ CRITICAL_SECTION waiters_lock;
#define EVENT_COND_SIGNAL 0
#define EVENT_COND_BROADCAST 1
#else
- pthread_cond_t hCond;
+ pthread_cond_t hCond;
#endif
};
@@ -46,73 +46,68 @@ struct racond {
//
-ramutex ramutex_create()
-{
- struct ramutex *m;
-
- m = (struct ramutex *)aMalloc(sizeof(struct ramutex));
- if (m == NULL) {
- ShowFatalError("ramutex_create: OOM while allocating %u bytes.\n", sizeof(struct ramutex));
- return NULL;
- }
-
+ramutex ramutex_create(){
+ struct ramutex *m;
+
+ m = (struct ramutex*)aMalloc( sizeof(struct ramutex) );
+ if(m == NULL){
+ ShowFatalError("ramutex_create: OOM while allocating %u bytes.\n", sizeof(struct ramutex));
+ return NULL;
+ }
+
#ifdef WIN32
- InitializeCriticalSection(&m->hMutex);
+ InitializeCriticalSection(&m->hMutex);
#else
- pthread_mutex_init(&m->hMutex, NULL);
+ pthread_mutex_init(&m->hMutex, NULL);
#endif
-
- return m;
+
+ return m;
}//end: ramutex_create()
-void ramutex_destroy(ramutex m)
-{
+void ramutex_destroy( ramutex m ){
#ifdef WIN32
- DeleteCriticalSection(&m->hMutex);
+ DeleteCriticalSection(&m->hMutex);
#else
- pthread_mutex_destroy(&m->hMutex);
+ pthread_mutex_destroy(&m->hMutex);
#endif
- aFree(m);
+ aFree(m);
}//end: ramutex_destroy()
-void ramutex_lock(ramutex m)
-{
+void ramutex_lock( ramutex m ){
#ifdef WIN32
- EnterCriticalSection(&m->hMutex);
+ EnterCriticalSection(&m->hMutex);
#else
- pthread_mutex_lock(&m->hMutex);
+ pthread_mutex_lock(&m->hMutex);
#endif
}//end: ramutex_lock
-bool ramutex_trylock(ramutex m)
-{
+bool ramutex_trylock( ramutex m ){
#ifdef WIN32
- if (TryEnterCriticalSection(&m->hMutex) == TRUE)
- return true;
+ if(TryEnterCriticalSection(&m->hMutex) == TRUE)
+ return true;
- return false;
+ return false;
#else
- if (pthread_mutex_trylock(&m->hMutex) == 0)
- return true;
-
- return false;
+ if(pthread_mutex_trylock(&m->hMutex) == 0)
+ return true;
+
+ return false;
#endif
}//end: ramutex_trylock()
-void ramutex_unlock(ramutex m)
-{
+void ramutex_unlock( ramutex m ){
#ifdef WIN32
- LeaveCriticalSection(&m->hMutex);
+ LeaveCriticalSection(&m->hMutex);
#else
- pthread_mutex_unlock(&m->hMutex);
+ pthread_mutex_unlock(&m->hMutex);
#endif
}//end: ramutex_unlock()
@@ -121,136 +116,131 @@ void ramutex_unlock(ramutex m)
///////////////
// Condition Variables
-//
+//
// Implementation:
//
-racond racond_create()
-{
- struct racond *c;
-
- c = (struct racond *)aMalloc(sizeof(struct racond));
- if (c == NULL) {
- ShowFatalError("racond_create: OOM while allocating %u bytes\n", sizeof(struct racond));
- return NULL;
- }
+racond racond_create(){
+ struct racond *c;
+
+ c = (struct racond*)aMalloc( sizeof(struct racond) );
+ if(c == NULL){
+ ShowFatalError("racond_create: OOM while allocating %u bytes\n", sizeof(struct racond));
+ return NULL;
+ }
#ifdef WIN32
- c->nWaiters = 0;
- c->events[ EVENT_COND_SIGNAL ] = CreateEvent(NULL, FALSE, FALSE, NULL);
- c->events[ EVENT_COND_BROADCAST ] = CreateEvent(NULL, TRUE, FALSE, NULL);
- InitializeCriticalSection(&c->waiters_lock);
+ c->nWaiters = 0;
+ c->events[ EVENT_COND_SIGNAL ] = CreateEvent( NULL, FALSE, FALSE, NULL );
+ c->events[ EVENT_COND_BROADCAST ] = CreateEvent( NULL, TRUE, FALSE, NULL );
+ InitializeCriticalSection( &c->waiters_lock );
#else
- pthread_cond_init(&c->hCond, NULL);
+ pthread_cond_init(&c->hCond, NULL);
#endif
-
- return c;
+
+ return c;
}//end: racond_create()
-void racond_destroy(racond c)
-{
+void racond_destroy( racond c ){
#ifdef WIN32
- CloseHandle(c->events[ EVENT_COND_SIGNAL ]);
- CloseHandle(c->events[ EVENT_COND_BROADCAST ]);
- DeleteCriticalSection(&c->waiters_lock);
+ CloseHandle( c->events[ EVENT_COND_SIGNAL ] );
+ CloseHandle( c->events[ EVENT_COND_BROADCAST ] );
+ DeleteCriticalSection( &c->waiters_lock );
#else
- pthread_cond_destroy(&c->hCond);
+ pthread_cond_destroy(&c->hCond);
#endif
- aFree(c);
+ aFree(c);
}//end: racond_destroy()
-void racond_wait(racond c, ramutex m, sysint timeout_ticks)
-{
+void racond_wait( racond c, ramutex m, sysint timeout_ticks){
#ifdef WIN32
- register DWORD ms;
- int result;
- bool is_last = false;
+ register DWORD ms;
+ int result;
+ bool is_last = false;
- EnterCriticalSection(&c->waiters_lock);
- c->nWaiters++;
- LeaveCriticalSection(&c->waiters_lock);
+ EnterCriticalSection(&c->waiters_lock);
+ c->nWaiters++;
+ LeaveCriticalSection(&c->waiters_lock);
- if (timeout_ticks < 0)
- ms = INFINITE;
- else
- ms = (timeout_ticks > MAXDWORD) ? (MAXDWORD - 1) : (DWORD)timeout_ticks;
+ if(timeout_ticks < 0)
+ ms = INFINITE;
+ else
+ ms = (timeout_ticks > MAXDWORD) ? (MAXDWORD - 1) : (DWORD)timeout_ticks;
+
+
+ // we can release the mutex (m) here, cause win's
+ // manual reset events maintain state when used with
+ // SetEvent()
+ ramutex_unlock(m);
+ result = WaitForMultipleObjects(2, c->events, FALSE, ms);
+
+
+ EnterCriticalSection(&c->waiters_lock);
+ c->nWaiters--;
+ if( (result == WAIT_OBJECT_0 + EVENT_COND_BROADCAST) && (c->nWaiters == 0) )
+ is_last = true; // Broadcast called!
+ LeaveCriticalSection(&c->waiters_lock);
- // we can release the mutex (m) here, cause win's
- // manual reset events maintain state when used with
- // SetEvent()
- ramutex_unlock(m);
+
- result = WaitForMultipleObjects(2, c->events, FALSE, ms);
+ // we are the last waiter that has to be notified, or to stop waiting
+ // so we have to do a manual reset
+ if(is_last == true)
+ ResetEvent( c->events[EVENT_COND_BROADCAST] );
- EnterCriticalSection(&c->waiters_lock);
- c->nWaiters--;
- if ((result == WAIT_OBJECT_0 + EVENT_COND_BROADCAST) && (c->nWaiters == 0))
- is_last = true; // Broadcast called!
- LeaveCriticalSection(&c->waiters_lock);
-
-
-
- // we are the last waiter that has to be notified, or to stop waiting
- // so we have to do a manual reset
- if (is_last == true)
- ResetEvent(c->events[EVENT_COND_BROADCAST]);
-
-
- ramutex_lock(m);
+ ramutex_lock(m);
#else
- if (timeout_ticks < 0) {
- pthread_cond_wait(&c->hCond, &m->hMutex);
- } else {
- struct timespec wtime;
- int64 exact_timeout = gettick() + timeout_ticks;
-
- wtime.tv_sec = exact_timeout/1000;
- wtime.tv_nsec = (exact_timeout%1000)*1000000;
-
- pthread_cond_timedwait(&c->hCond, &m->hMutex, &wtime);
- }
+ if(timeout_ticks < 0){
+ pthread_cond_wait( &c->hCond, &m->hMutex );
+ }else{
+ struct timespec wtime;
+ int64 exact_timeout = gettick() + timeout_ticks;
+
+ wtime.tv_sec = exact_timeout/1000;
+ wtime.tv_nsec = (exact_timeout%1000)*1000000;
+
+ pthread_cond_timedwait( &c->hCond, &m->hMutex, &wtime);
+ }
#endif
}//end: racond_wait()
-void racond_signal(racond c)
-{
+void racond_signal( racond c ){
#ifdef WIN32
- // bool has_waiters = false;
- // EnterCriticalSection(&c->waiters_lock);
- // if(c->nWaiters > 0)
- // has_waiters = true;
- // LeaveCriticalSection(&c->waiters_lock);
-
- // if(has_waiters == true)
- SetEvent(c->events[ EVENT_COND_SIGNAL ]);
+// bool has_waiters = false;
+// EnterCriticalSection(&c->waiters_lock);
+// if(c->nWaiters > 0)
+// has_waiters = true;
+// LeaveCriticalSection(&c->waiters_lock);
+
+// if(has_waiters == true)
+ SetEvent( c->events[ EVENT_COND_SIGNAL ] );
#else
- pthread_cond_signal(&c->hCond);
+ pthread_cond_signal(&c->hCond);
#endif
}//end: racond_signal()
-void racond_broadcast(racond c)
-{
+void racond_broadcast( racond c ){
#ifdef WIN32
- // bool has_waiters = false;
- // EnterCriticalSection(&c->waiters_lock);
- // if(c->nWaiters > 0)
- // has_waiters = true;
- // LeaveCriticalSection(&c->waiters_lock);
-
- // if(has_waiters == true)
- SetEvent(c->events[ EVENT_COND_BROADCAST ]);
+// bool has_waiters = false;
+// EnterCriticalSection(&c->waiters_lock);
+// if(c->nWaiters > 0)
+// has_waiters = true;
+// LeaveCriticalSection(&c->waiters_lock);
+
+// if(has_waiters == true)
+ SetEvent( c->events[ EVENT_COND_BROADCAST ] );
#else
- pthread_cond_broadcast(&c->hCond);
+ pthread_cond_broadcast(&c->hCond);
#endif
}//end: racond_broadcast()
diff --git a/src/common/mutex.h b/src/common/mutex.h
index abef731f4..1999627cd 100644
--- a/src/common/mutex.h
+++ b/src/common/mutex.h
@@ -1,5 +1,5 @@
// Copyright (c) rAthena Project (www.rathena.org) - Licensed under GNU GPL
-// For more information, see LICENCE in the main folder
+// For more information, see LICENCE in the main folder
#ifndef _rA_MUTEX_H_
#define _rA_MUTEX_H_
@@ -9,67 +9,67 @@ typedef struct ramutex *ramutex; // Mutex
typedef struct racond *racond; // Condition Var
/**
- * Creates a Mutex
+ * Creates a Mutex
*
* @return not NULL
*/
ramutex ramutex_create();
-/**
+/**
* Destroys a Mutex
- *
+ *
* @param m - the mutex to destroy
*/
-void ramutex_destroy(ramutex m);
+void ramutex_destroy( ramutex m );
-/**
+/**
* Gets a lock
*
* @param m - the mutex to lock
*/
-void ramutex_lock(ramutex m);
+void ramutex_lock( ramutex m);
-/**
+/**
* Trys to get the Lock
- *
+ *
* @param m - the mutex try to lock
- *
+ *
* @return boolean (true = got the lock)
*/
-bool ramutex_trylock(ramutex m);
+bool ramutex_trylock( ramutex m );
-/**
+/**
* Unlocks a mutex
*
* @param m - the mutex to unlock
*/
-void ramutex_unlock(ramutex m);
+void ramutex_unlock( ramutex m);
-/**
+/**
* Creates a Condition variable
*
* @return not NULL
*/
racond racond_create();
-/**
+/**
* Destroy a Condition variable
*
* @param c - the condition varaible to destroy
*/
-void racond_destroy(racond c);
+void racond_destroy( racond c );
/**
* Waits Until state is signalled
- *
- * @param c - the condition var to wait for signalled state
+ *
+ * @param c - the condition var to wait for signalled state
* @param m - the mutex used for syncronization
* @param timeout_ticks - timeout in ticks ( -1 = INFINITE )
*/
-void racond_wait(racond c, ramutex m, sysint timeout_ticks);
+void racond_wait( racond c, ramutex m, sysint timeout_ticks);
-/**
+/**
* Sets the given condition var to signalled state
*
* @param c - condition var to set in signalled state.
@@ -77,16 +77,16 @@ void racond_wait(racond c, ramutex m, sysint timeout_ticks);
* @note:
* Only one waiter gets notified.
*/
-void racond_signal(racond c);
+void racond_signal( racond c );
-/**
+/**
* Sets notifys all waiting threads thats signalled.
* @param c - condition var to set in signalled state
- *
+ *
* @note:
* All Waiters getting notified.
- */
-void racond_broadcast(racond c);
+ */
+void racond_broadcast( racond c );
#endif
diff --git a/src/common/netbuffer.c b/src/common/netbuffer.c
index 9ce13ffc3..57742d612 100644
--- a/src/common/netbuffer.c
+++ b/src/common/netbuffer.c
@@ -26,10 +26,10 @@
#include "../common/netbuffer.h"
-//
+//
// Buffers are available in the following sizes:
-// 48, 192, 2048, 8192
-// 65536 (inter server connects may use it for charstatus struct..)
+// 48, 192, 2048, 8192
+// 65536 (inter server connects may use it for charstatus struct..)
//
@@ -42,197 +42,180 @@ static sysint *l_poolElemSize = NULL;
static mempool *l_pool = NULL;
-void netbuffer_init()
-{
- char localsection[32];
- raconf conf;
- sysint i;
-
- // Initialize Statistic counters:
- l_nEmergencyAllocations = 0;
-
- // Set localsection name according to running serverype.
- switch (SERVER_TYPE) {
- case ATHENA_SERVER_LOGIN:
- strcpy(localsection, "login-netbuffer");
- break;
- case ATHENA_SERVER_CHAR:
- strcpy(localsection, "char-netbuffer");
- break;
- case ATHENA_SERVER_INTER:
- strcpy(localsection, "inter-netbuffer");
- break;
- case ATHENA_SERVER_MAP:
- strcpy(localsection, "map-netbuffer");
- break;
- default:
- strcpy(localsection, "unsupported_type");
- break;
- }
-
-
- conf = raconf_parse("conf/network.conf");
- if (conf == NULL) {
- ShowFatalError("Failed to Parse required Configuration (conf/network.conf)");
- exit(EXIT_FAILURE);
- }
-
- // Get Values from config file
- l_nPools = (sysint)raconf_getintEx(conf, localsection, "netbuffer", "num", 0);
- if (l_nPools == 0) {
- ShowFatalError("Netbuffer (network.conf) failure - requires at least 1 Pool.\n");
- exit(EXIT_FAILURE);
- }
-
- // Allocate arrays.
- l_poolElemSize = (sysint *)aCalloc(l_nPools, sizeof(sysint));
- l_pool = (mempool *)aCalloc(l_nPools, sizeof(mempool));
-
-
- for (i = 0; i < l_nPools; i++) {
- int64 num_prealloc, num_realloc;
- char key[32];
-
- sprintf(key, "pool_%u_size", (uint32)i+1);
- l_poolElemSize[i] = (sysint)raconf_getintEx(conf, localsection, "netbuffer", key, 4096);
- if (l_poolElemSize[i] < 32) {
- ShowWarning("Netbuffer (network.conf) failure - minimum allowed buffer size is 32 byte) - fixed.\n");
- l_poolElemSize[i] = 32;
- }
-
- sprintf(key, "pool_%u_prealloc", (uint32)i+1);
- num_prealloc = raconf_getintEx(conf, localsection, "netbuffer", key, 150);
-
- sprintf(key, "pool_%u_realloc_step", (uint32)i+1);
- num_realloc = raconf_getintEx(conf, localsection, "netbuffer", key, 100);
-
- // Create Pool!
- sprintf(key, "Netbuffer %u", (uint32)l_poolElemSize[i]); // name.
-
- // Info
- ShowInfo("NetBuffer: Creating Pool %u (Prealloc: %u, Realloc Step: %u) - %0.2f MiB\n", l_poolElemSize[i], num_prealloc, num_realloc, (float)((sizeof(struct netbuf) + l_poolElemSize[i] - 32)* num_prealloc)/1024.0f/1024.0f);
-
- //
- // Size Calculation:
- // struct netbuf + requested buffer size - 32 (because the struct already contains 32 byte buffer space at the end of struct)
- l_pool[i] = mempool_create(key, (sizeof(struct netbuf) + l_poolElemSize[i] - 32), num_prealloc, num_realloc, NULL, NULL);
- if (l_pool[i] == NULL) {
- ShowFatalError("Netbuffer: cannot create Pool for %u byte buffers.\n", l_poolElemSize[i]);
- // @leak: clean everything :D
- exit(EXIT_FAILURE);
- }
-
- }//
-
-
- raconf_destroy(conf);
+void netbuffer_init(){
+ char localsection[32];
+ raconf conf;
+ sysint i;
+
+ // Initialize Statistic counters:
+ l_nEmergencyAllocations = 0;
+
+ // Set localsection name according to running serverype.
+ switch(SERVER_TYPE){
+ case ATHENA_SERVER_LOGIN: strcpy(localsection, "login-netbuffer"); break;
+ case ATHENA_SERVER_CHAR: strcpy(localsection, "char-netbuffer"); break;
+ case ATHENA_SERVER_INTER: strcpy(localsection, "inter-netbuffer"); break;
+ case ATHENA_SERVER_MAP: strcpy(localsection, "map-netbuffer"); break;
+ default: strcpy(localsection, "unsupported_type"); break;
+ }
+
+
+ conf = raconf_parse("conf/network.conf");
+ if(conf == NULL){
+ ShowFatalError("Failed to Parse required Configuration (conf/network.conf)");
+ exit(EXIT_FAILURE);
+ }
+
+ // Get Values from config file
+ l_nPools = (sysint)raconf_getintEx(conf, localsection, "netbuffer", "num", 0);
+ if(l_nPools == 0){
+ ShowFatalError("Netbuffer (network.conf) failure - requires at least 1 Pool.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ // Allocate arrays.
+ l_poolElemSize = (sysint*)aCalloc( l_nPools, sizeof(sysint) );
+ l_pool = (mempool*)aCalloc( l_nPools, sizeof(mempool) );
+
+
+ for(i = 0; i < l_nPools; i++){
+ int64 num_prealloc, num_realloc;
+ char key[32];
+
+ sprintf(key, "pool_%u_size", (uint32)i+1);
+ l_poolElemSize[i] = (sysint)raconf_getintEx(conf, localsection, "netbuffer", key, 4096);
+ if(l_poolElemSize[i] < 32){
+ ShowWarning("Netbuffer (network.conf) failure - minimum allowed buffer size is 32 byte) - fixed.\n");
+ l_poolElemSize[i] = 32;
+ }
+
+ sprintf(key, "pool_%u_prealloc", (uint32)i+1);
+ num_prealloc = raconf_getintEx(conf, localsection, "netbuffer", key, 150);
+
+ sprintf(key, "pool_%u_realloc_step", (uint32)i+1);
+ num_realloc = raconf_getintEx(conf, localsection, "netbuffer", key, 100);
+
+ // Create Pool!
+ sprintf(key, "Netbuffer %u", (uint32)l_poolElemSize[i]); // name.
+
+ // Info
+ ShowInfo("NetBuffer: Creating Pool %u (Prealloc: %u, Realloc Step: %u) - %0.2f MiB\n", l_poolElemSize[i], num_prealloc, num_realloc, (float)((sizeof(struct netbuf) + l_poolElemSize[i] - 32)* num_prealloc)/1024.0f/1024.0f);
+
+ //
+ // Size Calculation:
+ // struct netbuf + requested buffer size - 32 (because the struct already contains 32 byte buffer space at the end of struct)
+ l_pool[i] = mempool_create(key, (sizeof(struct netbuf) + l_poolElemSize[i] - 32), num_prealloc, num_realloc, NULL, NULL);
+ if(l_pool[i] == NULL){
+ ShowFatalError("Netbuffer: cannot create Pool for %u byte buffers.\n", l_poolElemSize[i]);
+ // @leak: clean everything :D
+ exit(EXIT_FAILURE);
+ }
+
+ }//
+
+
+ raconf_destroy(conf);
}//end: netbuffer_init()
-void netbuffer_final()
-{
- sysint i;
-
- if (l_nPools > 0) {
- /// .. finalize mempools
- for (i = 0; i < l_nPools; i++) {
- mempool_stats stats = mempool_get_stats(l_pool[i]);
-
- ShowInfo("Netbuffer: Freeing Pool %u (Peak Usage: %u, Realloc Events: %u)\n", l_poolElemSize[i], stats.peak_nodes_used, stats.num_realloc_events);
-
- mempool_destroy(l_pool[i]);
- }
-
- if (l_nEmergencyAllocations > 0) {
- ShowWarning("Netbuffer: did %u Emergency Allocations, please tune your network.conf!\n", l_nEmergencyAllocations);
- l_nEmergencyAllocations = 0;
- }
-
- aFree(l_poolElemSize);
- l_poolElemSize = NULL;
- aFree(l_pool);
- l_pool = NULL;
- l_nPools = 0;
- }
-
-
+void netbuffer_final(){
+ sysint i;
+
+ if(l_nPools > 0){
+ /// .. finalize mempools
+ for(i = 0; i < l_nPools; i++){
+ mempool_stats stats = mempool_get_stats(l_pool[i]);
+
+ ShowInfo("Netbuffer: Freeing Pool %u (Peak Usage: %u, Realloc Events: %u)\n", l_poolElemSize[i], stats.peak_nodes_used, stats.num_realloc_events);
+
+ mempool_destroy(l_pool[i]);
+ }
+
+ if(l_nEmergencyAllocations > 0){
+ ShowWarning("Netbuffer: did %u Emergency Allocations, please tune your network.conf!\n", l_nEmergencyAllocations);
+ l_nEmergencyAllocations = 0;
+ }
+
+ aFree(l_poolElemSize); l_poolElemSize = NULL;
+ aFree(l_pool); l_pool = NULL;
+ l_nPools = 0;
+ }
+
+
}//end: netbuffer_final()
-netbuf netbuffer_get(sysint sz)
-{
- sysint i;
- netbuf nb = NULL;
-
- // Search an appropriate pool
- for (i = 0; i < l_nPools; i++) {
- if (sz <= l_poolElemSize[i]) {
- // match
-
- nb = (netbuf)mempool_node_get(l_pool[i]);
- nb->pool = i;
-
- break;
- }
- }
-
- // No Bufferpool found that mets there quirements?.. (thats bad..)
- if (nb == NULL) {
- ShowWarning("Netbuffer: get(%u): => no appropriate pool found - emergency allocation required.\n", sz);
- ShowWarning("Please reconfigure your network.conf!");
-
- InterlockedIncrement(&l_nEmergencyAllocations);
-
- // .. better to check (netbuf struct provides 32 byte bufferspace itself.
- if (sz < 32) sz = 32;
-
- // allocate memory using malloc ..
- while (1) {
- nb = (netbuf) aMalloc((sizeof(struct netbuf) + sz - 32));
- if (nb != NULL) {
- memset(nb, 0x00, (sizeof(struct netbuf) + sz - 32)); // zero memory! (to enforce commit @ os.)
- nb->pool = -1; // emergency alloc.
- break;
- }
-
- rathread_yield();
- }// spin allocation.
-
- }
-
-
- nb->refcnt = 1; // Initial refcount is 1
-
- return nb;
+netbuf netbuffer_get( sysint sz ){
+ sysint i;
+ netbuf nb = NULL;
+
+ // Search an appropriate pool
+ for(i = 0; i < l_nPools; i++){
+ if(sz <= l_poolElemSize[i]){
+ // match
+
+ nb = (netbuf)mempool_node_get(l_pool[i]);
+ nb->pool = i;
+
+ break;
+ }
+ }
+
+ // No Bufferpool found that mets there quirements?.. (thats bad..)
+ if(nb == NULL){
+ ShowWarning("Netbuffer: get(%u): => no appropriate pool found - emergency allocation required.\n", sz);
+ ShowWarning("Please reconfigure your network.conf!");
+
+ InterlockedIncrement(&l_nEmergencyAllocations);
+
+ // .. better to check (netbuf struct provides 32 byte bufferspace itself.
+ if(sz < 32) sz = 32;
+
+ // allocate memory using malloc ..
+ while(1){
+ nb = (netbuf) aMalloc( (sizeof(struct netbuf) + sz - 32) );
+ if(nb != NULL){
+ memset(nb, 0x00, (sizeof(struct netbuf) + sz - 32) ); // zero memory! (to enforce commit @ os.)
+ nb->pool = -1; // emergency alloc.
+ break;
+ }
+
+ rathread_yield();
+ }// spin allocation.
+
+ }
+
+
+ nb->refcnt = 1; // Initial refcount is 1
+
+ return nb;
}//end: netbuffer_get()
-void netbuffer_put(netbuf nb)
-{
-
- // Decrement reference counter, if > 0 do nothing :)
- if (InterlockedDecrement(&nb->refcnt) > 0)
- return;
-
- // Is this buffer an emergency allocated buffer?
- if (nb->pool == -1) {
- aFree(nb);
- return;
- }
-
-
- // Otherwise its a normal mempool based buffer
- // return it to the according mempool:
- mempool_node_put(l_pool[nb->pool], nb);
-
-
+void netbuffer_put( netbuf nb ){
+
+ // Decrement reference counter, if > 0 do nothing :)
+ if( InterlockedDecrement(&nb->refcnt) > 0 )
+ return;
+
+ // Is this buffer an emergency allocated buffer?
+ if(nb->pool == -1){
+ aFree(nb);
+ return;
+ }
+
+
+ // Otherwise its a normal mempool based buffer
+ // return it to the according mempool:
+ mempool_node_put( l_pool[nb->pool], nb);
+
+
}//end: netbuffer_put()
-void netbuffer_incref(netbuf nb)
-{
-
- InterlockedIncrement(&nb->refcnt);
-
+void netbuffer_incref( netbuf nb ){
+
+ InterlockedIncrement(&nb->refcnt);
+
}//end: netbuf_incref()
diff --git a/src/common/netbuffer.h b/src/common/netbuffer.h
index a4feb7287..844241226 100644
--- a/src/common/netbuffer.h
+++ b/src/common/netbuffer.h
@@ -6,37 +6,37 @@
#include "../common/cbasetypes.h"
-typedef struct netbuf {
- sysint pool; // The pool ID this buffer belongs to,
- // is set to -1 if its an emergency allocated buffer
-
- struct netbuf *next; // Used by Network system.
-
- volatile int32 refcnt; // Internal Refcount, it gets lowered every call to netbuffer_put,
- // if its getting zero, the buffer will returned back to the pool
- // and can be reused.
-
- int32 dataPos; // Current Offset
- // Used only for Reading (recv job)
- // write cases are using the sessions local datapos member due to
- // shared write buffer support.
-
- int32 dataLen; // read buffer case:
- // The length expected to read to.
- // when this->dataPos == dateLen, read job has been completed.
- // write buffer case:
- // The lngth of data in te buffer
- // when s->dataPos == dataLen, write job has been completed
- //
- // Note:
- // leftBytes = (dateLen - dataPos)
- //
- // Due to shared buffer support
- // dataPos gets not used in write case (each connection has its local offset)
- //
-
- // The Bufferspace itself.
- char buf[32];
+typedef struct netbuf{
+ sysint pool; // The pool ID this buffer belongs to,
+ // is set to -1 if its an emergency allocated buffer
+
+ struct netbuf *next; // Used by Network system.
+
+ volatile int32 refcnt; // Internal Refcount, it gets lowered every call to netbuffer_put,
+ // if its getting zero, the buffer will returned back to the pool
+ // and can be reused.
+
+ int32 dataPos; // Current Offset
+ // Used only for Reading (recv job)
+ // write cases are using the sessions local datapos member due to
+ // shared write buffer support.
+
+ int32 dataLen; // read buffer case:
+ // The length expected to read to.
+ // when this->dataPos == dateLen, read job has been completed.
+ // write buffer case:
+ // The lngth of data in te buffer
+ // when s->dataPos == dataLen, write job has been completed
+ //
+ // Note:
+ // leftBytes = (dateLen - dataPos)
+ //
+ // Due to shared buffer support
+ // dataPos gets not used in write case (each connection has its local offset)
+ //
+
+ // The Bufferspace itself.
+ char buf[32];
} *netbuf;
@@ -47,29 +47,29 @@ void netbuffer_final();
* Gets a netbuffer that has atleast (sz) byes space.
*
* @note: The netbuffer system guarantees that youll always recevie a buffer.
- * no check for null is required!
+ * no check for null is required!
*
* @param sz - minimum size needed.
*
* @return pointer to netbuf struct
*/
-netbuf netbuffer_get(sysint sz);
+netbuf netbuffer_get( sysint sz );
-/**
+/**
* Returns the given netbuffer (decreases refcount, if its 0 - the buffer will get returned to the pool)
*
- * @param buf - the buffer to return
+ * @param buf - the buffer to return
*/
-void netbuffer_put(netbuf buf);
+void netbuffer_put( netbuf buf );
-/**
- * Increases the Refcount on the given buffer
+/**
+ * Increases the Refcount on the given buffer
* (used for areasends .. etc)
*
*/
-void netbuffer_incref(netbuf buf);
+void netbuffer_incref( netbuf buf );
// Some Useful macros
diff --git a/src/common/network.c b/src/common/network.c
index 1c968200d..1f1621363 100644
--- a/src/common/network.c
+++ b/src/common/network.c
@@ -51,1020 +51,1011 @@ static bool onSend(int32 fd);
#define _network_free_netbuf_async( buf ) add_timer( 0, _network_async_free_netbuf_proc, 0, (intptr_t) buf)
-static int _network_async_free_netbuf_proc(int tid, unsigned int tick, int id, intptr_t data)
-{
- // netbuf is in data
- netbuffer_put((netbuf)data);
+static int _network_async_free_netbuf_proc(int tid, unsigned int tick, int id, intptr_t data){
+ // netbuf is in data
+ netbuffer_put( (netbuf)data );
- return 0;
+ return 0;
}//end: _network_async_free_netbuf_proc()
-void network_init()
-{
- SESSION *s;
- int32 i;
-
- memset(g_Session, 0x00, (sizeof(SESSION) * MAXCONN));
-
- for (i = 0; i < MAXCONN; i++) {
- s = &g_Session[i];
-
- s->type = NST_FREE;
- s->disconnect_in_progress = false;
-
- }
-
- // Initialize the correspondig event dispatcher
- evdp_init();
-
- //
- add_timer_func_list(_network_async_free_netbuf_proc, "_network_async_free_netbuf_proc");
-
+void network_init(){
+ SESSION *s;
+ int32 i;
+
+ memset(g_Session, 0x00, (sizeof(SESSION) * MAXCONN) );
+
+ for(i = 0; i < MAXCONN; i++){
+ s = &g_Session[i];
+
+ s->type = NST_FREE;
+ s->disconnect_in_progress = false;
+
+ }
+
+ // Initialize the correspondig event dispatcher
+ evdp_init();
+
+ //
+ add_timer_func_list(_network_async_free_netbuf_proc, "_network_async_free_netbuf_proc");
+
}//end: network_init()
-void network_final()
-{
-
- // @TODO:
- // .. disconnect and cleanup everything!
+void network_final(){
- evdp_final();
+ // @TODO:
+ // .. disconnect and cleanup everything!
+
+ evdp_final();
}//end: network_final()
-void network_do()
-{
- struct EVDP_EVENT l_events[EVENTS_PER_CYCLE];
- register struct EVDP_EVENT *ev;
- register int n, nfds;
- register SESSION *s;
-
- nfds = evdp_wait(l_events, EVENTS_PER_CYCLE, 1000); // @TODO: timer_getnext()
-
- for (n = 0; n < nfds; n++) {
- ev = &l_events[n];
- s = &g_Session[ ev->fd ];
-
- if (ev->events & EVDP_EVENT_HUP) {
- network_disconnect(ev->fd);
- continue; // no further event processing.
- }// endif vent is HUP (disconnect)
-
-
- if (ev->events & EVDP_EVENT_IN) {
-
- if (s->onRecv != NULL) {
- if (false == s->onRecv(ev->fd)) {
- network_disconnect(ev->fd);
- continue; // ..
- }
- } else {
- ShowError("network_do: fd #%u has no onRecv proc set. - disconnecting\n", ev->fd);
- network_disconnect(ev->fd);
- continue;
- }
-
- }// endif event is IN (recv)
-
-
- if (ev->events & EVDP_EVENT_OUT) {
- if (s->onSend != NULL) {
- if (false == s->onSend(ev->fd)) {
- network_disconnect(ev->fd);
- continue;
- }
- } else {
- ShowError("network_do: fd #%u has no onSend proc set. - disconnecting\n", ev->fd);
- network_disconnect(ev->fd);
- continue;
- }
- }// endif event is OUT (send)
-
- }//endfor
-
+void network_do(){
+ struct EVDP_EVENT l_events[EVENTS_PER_CYCLE];
+ register struct EVDP_EVENT *ev;
+ register int n, nfds;
+ register SESSION *s;
+
+ nfds = evdp_wait( l_events, EVENTS_PER_CYCLE, 1000); // @TODO: timer_getnext()
+
+ for(n = 0; n < nfds; n++){
+ ev = &l_events[n];
+ s = &g_Session[ ev->fd ];
+
+ if(ev->events & EVDP_EVENT_HUP){
+ network_disconnect( ev->fd );
+ continue; // no further event processing.
+ }// endif vent is HUP (disconnect)
+
+
+ if(ev->events & EVDP_EVENT_IN){
+
+ if(s->onRecv != NULL){
+ if( false == s->onRecv(ev->fd) ){
+ network_disconnect(ev->fd);
+ continue; // ..
+ }
+ }else{
+ ShowError("network_do: fd #%u has no onRecv proc set. - disconnecting\n", ev->fd);
+ network_disconnect(ev->fd);
+ continue;
+ }
+
+ }// endif event is IN (recv)
+
+
+ if(ev->events & EVDP_EVENT_OUT){
+ if(s->onSend != NULL){
+ if( false == s->onSend(ev->fd) ){
+ network_disconnect(ev->fd);
+ continue;
+ }
+ }else{
+ ShowError("network_do: fd #%u has no onSend proc set. - disconnecting\n", ev->fd);
+ network_disconnect(ev->fd);
+ continue;
+ }
+ }// endif event is OUT (send)
+
+ }//endfor
+
}//end: network_do()
-static bool _setnonblock(int32 fd)
-{
- int flags = fcntl(fd, F_GETFL, 0);
- if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) != 0)
- return false;
+static bool _setnonblock(int32 fd){
+ int flags = fcntl(fd, F_GETFL, 0);
+ if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) != 0)
+ return false;
- return true;
+ return true;
}//end: _setnonblock()
-static bool _network_accept(int32 fd)
-{
- SESSION *listener = &g_Session[fd];
- SESSION *s;
- union {
- struct sockaddr_in v4;
+static bool _network_accept(int32 fd){
+ SESSION *listener = &g_Session[fd];
+ SESSION *s;
+ union{
+ struct sockaddr_in v4;
#ifdef ENABLE_IPV6
- struct sockaddr_in6 v6;
+ struct sockaddr_in6 v6;
#endif
- } _addr;
- int newfd;
- socklen_t addrlen;
- struct sockaddr *addr;
-
- // Accept until OS returns - nothing to accept anymore
- // - this is required due to our EVDP abstraction. (which handles on listening sockets similar to epoll's EPOLLET flag.)
- while (1) {
+ } _addr;
+ int newfd;
+ socklen_t addrlen;
+ struct sockaddr *addr;
+
+ // Accept until OS returns - nothing to accept anymore
+ // - this is required due to our EVDP abstraction. (which handles on listening sockets similar to epoll's EPOLLET flag.)
+ while(1){
#ifdef ENABLE_IPV6
- if (listener->v6 == true) {
- addrlen = sizeof(_addr.v6);
- addr = (struct sockaddr *)&_addr.v6;
- } else {
+ if(listener->v6 == true){
+ addrlen = sizeof(_addr.v6);
+ addr = (struct sockaddr*)&_addr.v6;
+ }else{
#endif
- addrlen = sizeof(_addr.v4);
- addr = (struct sockaddr *)&_addr.v4;
+ addrlen = sizeof(_addr.v4);
+ addr = (struct sockaddr*)&_addr.v4;
#ifdef ENABLE_IPV6
- }
+ }
#endif
#ifdef HAVE_ACCEPT4
- newfd = accept4(fd, addr, &addrlen, SOCK_NONBLOCK);
+ newfd = accept4(fd, addr, &addrlen, SOCK_NONBLOCK);
#else
- newfd = accept(fd, addr, &addrlen);
+ newfd = accept(fd, addr, &addrlen);
#endif
- if (newfd == -1) {
- if (errno == EAGAIN || errno == EWOULDBLOCK)
- break; // this is fully valid & whished., se explaination on top of while(1)
-
- // Otherwis .. we have serious problems :( seems tahat our listner has gone away..
- // @TODO handle this ..
- ShowError("_network_accept: accept() returned error. closing listener. (errno: %u / %s)\n", errno, strerror(errno));
+ if(newfd == -1){
+ if(errno == EAGAIN || errno == EWOULDBLOCK)
+ break; // this is fully valid & whished., se explaination on top of while(1)
+
+ // Otherwis .. we have serious problems :( seems tahat our listner has gone away..
+ // @TODO handle this ..
+ ShowError("_network_accept: accept() returned error. closing listener. (errno: %u / %s)\n", errno, strerror(errno));
- return false; // will call disconnect after return.
- //break;
- }
+ return false; // will call disconnect after return.
+ //break;
+ }
#ifndef HAVE_ACCEPT4 // no accept4 means, we have to set nonblock by ourself. ..
- if (_setnonblock(newfd) == false) {
- ShowError("_network_accept: failed to set newly accepted connection nonblocking (errno: %u / %s). - disconnecting.\n", errno, strerror(errno));
- close(newfd);
- continue;
- }
+ if(_setnonblock(newfd) == false){
+ ShowError("_network_accept: failed to set newly accepted connection nonblocking (errno: %u / %s). - disconnecting.\n", errno, strerror(errno));
+ close(newfd);
+ continue;
+ }
#endif
- // Check connection limits.
- if (newfd >= MAXCONN) {
- ShowError("_network_accept: failed to accept connection - MAXCONN (%u) exceeded.\n", MAXCONN);
- close(newfd);
- continue; // we have to loop over the events (and disconnect them too ..) but otherwise we would leak event notifications.
- }
-
-
- // Create new Session.
- s = &g_Session[newfd];
- s->type = NST_CLIENT;
-
- // The new connection inherits listenr's handlers.
- s->onDisconnect = listener->onDisconnect;
- s->onConnect = listener->onConnect; // maybe useless but .. fear the future .. :~
-
- // Register the new connection @ EVDP
- if (evdp_addclient(newfd, &s->evdp_data) == false) {
- ShowError("_network_accept: failed to accept connection - event subsystem returned an error.\n");
- close(newfd);
- s->type = NST_FREE;
- }
-
- // Call the onConnect handler on the listener.
- if (listener->onConnect(newfd) == false) {
- // Resfused by onConnect handler..
- evdp_remove(newfd, &s->evdp_data);
-
- close(newfd);
- s->type = NST_FREE;
-
- s->data = NULL; // be on the safe side ~ !
- continue;
- }
-
-
- }
-
- return true;
+ // Check connection limits.
+ if(newfd >= MAXCONN){
+ ShowError("_network_accept: failed to accept connection - MAXCONN (%u) exceeded.\n", MAXCONN);
+ close(newfd);
+ continue; // we have to loop over the events (and disconnect them too ..) but otherwise we would leak event notifications.
+ }
+
+
+ // Create new Session.
+ s = &g_Session[newfd];
+ s->type = NST_CLIENT;
+
+ // The new connection inherits listenr's handlers.
+ s->onDisconnect = listener->onDisconnect;
+ s->onConnect = listener->onConnect; // maybe useless but .. fear the future .. :~
+
+ // Register the new connection @ EVDP
+ if( evdp_addclient(newfd, &s->evdp_data) == false){
+ ShowError("_network_accept: failed to accept connection - event subsystem returned an error.\n");
+ close(newfd);
+ s->type = NST_FREE;
+ }
+
+ // Call the onConnect handler on the listener.
+ if( listener->onConnect(newfd) == false ){
+ // Resfused by onConnect handler..
+ evdp_remove(newfd, &s->evdp_data);
+
+ close(newfd);
+ s->type = NST_FREE;
+
+ s->data = NULL; // be on the safe side ~ !
+ continue;
+ }
+
+
+ }
+
+ return true;
}//end: _network_accept()
-void network_disconnect(int32 fd)
-{
- SESSION *s = &g_Session[fd];
- netbuf b, bn;
-
- // Prevent recursive calls
- // by wrong implemented on disconnect handlers.. and such..
- if (s->disconnect_in_progress == true)
- return;
-
- s->disconnect_in_progress = true;
-
-
- // Disconnect Todo:
- // - Call onDisconnect Handler
- // - Release all Assigned buffers.
- // - remove from event system (notifications)
- // - cleanup session structure
- // - close connection.
- //
-
- if (s->onDisconnect != NULL &&
- s->type != NST_LISTENER) {
-
- s->onDisconnect(fd);
- }
-
- // Read Buffer
- if (s->read.buf != NULL) {
- netbuffer_put(s->read.buf);
- s->read.buf = NULL;
- }
-
- // Write Buffer(s)
- b = s->write.buf;
- while (1) {
- if (b == NULL) break;
-
- bn = b->next;
-
- netbuffer_put(b);
-
- b = bn;
- }
- s->write.buf = NULL;
- s->write.buf_last = NULL;
-
- s->write.n_outstanding = 0;
- s->write.max_outstanding = 0;
-
-
- // Remove from event system.
- evdp_remove(fd, &s->evdp_data);
-
- // Cleanup Session Structure.
- s->type = NST_FREE;
- s->data = NULL; // no application level data assigned
- s->disconnect_in_progress = false;
-
-
- // Close connection
- close(fd);
-
+void network_disconnect(int32 fd){
+ SESSION *s = &g_Session[fd];
+ netbuf b, bn;
+
+ // Prevent recursive calls
+ // by wrong implemented on disconnect handlers.. and such..
+ if(s->disconnect_in_progress == true)
+ return;
+
+ s->disconnect_in_progress = true;
+
+
+ // Disconnect Todo:
+ // - Call onDisconnect Handler
+ // - Release all Assigned buffers.
+ // - remove from event system (notifications)
+ // - cleanup session structure
+ // - close connection.
+ //
+
+ if(s->onDisconnect != NULL &&
+ s->type != NST_LISTENER){
+
+ s->onDisconnect( fd );
+ }
+
+ // Read Buffer
+ if(s->read.buf != NULL){
+ netbuffer_put(s->read.buf);
+ s->read.buf = NULL;
+ }
+
+ // Write Buffer(s)
+ b = s->write.buf;
+ while(1){
+ if(b == NULL) break;
+
+ bn = b->next;
+
+ netbuffer_put(b);
+
+ b = bn;
+ }
+ s->write.buf = NULL;
+ s->write.buf_last = NULL;
+
+ s->write.n_outstanding = 0;
+ s->write.max_outstanding = 0;
+
+
+ // Remove from event system.
+ evdp_remove(fd, &s->evdp_data);
+
+ // Cleanup Session Structure.
+ s->type = NST_FREE;
+ s->data = NULL; // no application level data assigned
+ s->disconnect_in_progress = false;
+
+
+ // Close connection
+ close(fd);
+
}//end: network_disconnect()
-int32 network_addlistener(bool v6, const char *addr, uint16 port)
-{
- SESSION *s;
- int optval, fd;
+int32 network_addlistener(bool v6, const char *addr, uint16 port){
+ SESSION *s;
+ int optval, fd;
#if !defined(ENABLE_IPV6)
- if (v6 == true) {
- ShowError("network_addlistener(%c, '%s', %u): this release has no IPV6 support.\n", (v6==true?'t':'f'), addr, port);
- return -1;
- }
+ if(v6 == true){
+ ShowError("network_addlistener(%c, '%s', %u): this release has no IPV6 support.\n", (v6==true?'t':'f'), addr, port);
+ return -1;
+ }
#endif
#ifdef ENABLE_IPV6
- if (v6 == true)
- fd = socket(AF_INET6, SOCK_STREAM, 0);
- else
+ if(v6 == true)
+ fd = socket(AF_INET6, SOCK_STREAM, 0);
+ else
#endif
- fd = socket(AF_INET, SOCK_STREAM, 0);
-
- // Error?
- if (fd == -1) {
- ShowError("network_addlistener(%c, '%s', %u): socket() failed (errno: %u / %s)\n", (v6==true?'t':'f'), addr, port, errno, strerror(errno));
- return -1;
- }
-
- // Too many connections?
- if (fd >= MAXCONN) {
- ShowError("network_addlistener(%c, '%s', %u): cannot create listener, exceeds more than supported connections (%u).\n", (v6==true?'t':'f'), addr, port, MAXCONN);
- close(fd);
- return -1;
- }
-
-
- s = &g_Session[fd];
- if (s->type != NST_FREE) { // additional checks.. :)
- ShowError("network_addlistener(%c, '%s', %u): failed, got fd #%u which is already in use in local session table?!\n", (v6==true?'t':'f'), addr, port, fd);
- close(fd);
- return -1;
- }
-
-
- // Fill ip addr structs
+ fd = socket(AF_INET, SOCK_STREAM, 0);
+
+ // Error?
+ if(fd == -1){
+ ShowError("network_addlistener(%c, '%s', %u): socket() failed (errno: %u / %s)\n", (v6==true?'t':'f'), addr, port, errno, strerror(errno));
+ return -1;
+ }
+
+ // Too many connections?
+ if(fd >= MAXCONN){
+ ShowError("network_addlistener(%c, '%s', %u): cannot create listener, exceeds more than supported connections (%u).\n", (v6==true?'t':'f'), addr, port, MAXCONN);
+ close(fd);
+ return -1;
+ }
+
+
+ s = &g_Session[fd];
+ if(s->type != NST_FREE){ // additional checks.. :)
+ ShowError("network_addlistener(%c, '%s', %u): failed, got fd #%u which is already in use in local session table?!\n", (v6==true?'t':'f'), addr, port, fd);
+ close(fd);
+ return -1;
+ }
+
+
+ // Fill ip addr structs
#ifdef ENABLE_IPV6
- if (v6 == true) {
- memset(&s->addr.v6, 0x00, sizeof(s->addr.v6));
- s->addr.v6.sin6_family = AF_INET6;
- s->addr.v6.sin6_port = htons(port);
- if (inet_pton(AF_INET6, addr, &s->addr.v6.sin6_addr) != 1) {
- ShowError("network_addlistener(%c, '%s', %u): failed to parse the given IPV6 address.\n", (v6==true?'t':'f'), addr, port);
- close(fd);
- return -1;
- }
-
- } else {
+ if(v6 == true){
+ memset(&s->addr.v6, 0x00, sizeof(s->addr.v6));
+ s->addr.v6.sin6_family = AF_INET6;
+ s->addr.v6.sin6_port = htons(port);
+ if(inet_pton(AF_INET6, addr, &s->addr.v6.sin6_addr) != 1){
+ ShowError("network_addlistener(%c, '%s', %u): failed to parse the given IPV6 address.\n", (v6==true?'t':'f'), addr, port);
+ close(fd);
+ return -1;
+ }
+
+ }else{
#endif
- memset(&s->addr.v4, 0x00, sizeof(s->addr.v4));
- s->addr.v4.sin_family = AF_INET;
- s->addr.v4.sin_port = htons(port);
- s->addr.v4.sin_addr.s_addr = inet_addr(addr);
+ memset(&s->addr.v4, 0x00, sizeof(s->addr.v4));
+ s->addr.v4.sin_family = AF_INET;
+ s->addr.v4.sin_port = htons(port);
+ s->addr.v4.sin_addr.s_addr = inet_addr(addr);
#ifdef ENABLE_IPV6
- }
+ }
#endif
+
-
- // if OS has support for SO_REUSEADDR, apply the flag
- // so the address could be used when there're still time_wait sockets outstanding from previous application run.
+ // if OS has support for SO_REUSEADDR, apply the flag
+ // so the address could be used when there're still time_wait sockets outstanding from previous application run.
#ifdef SO_REUSEADDR
- optval=1;
- setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
+ optval=1;
+ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
#endif
- // Bind
+ // Bind
#ifdef ENABLE_IPV6
- if (v6 == true) {
- if (bind(fd, (struct sockaddr *)&s->addr.v6, sizeof(s->addr.v6)) == -1) {
- ShowError("network_addlistener(%c, '%s', %u): bind failed (errno: %u / %s)\n", (v6==true?'t':'f'), addr, port, errno, strerror(errno));
- close(fd);
- return -1;
- }
- } else {
+ if(v6 == true){
+ if( bind(fd, (struct sockaddr*)&s->addr.v6, sizeof(s->addr.v6)) == -1) {
+ ShowError("network_addlistener(%c, '%s', %u): bind failed (errno: %u / %s)\n", (v6==true?'t':'f'), addr, port, errno, strerror(errno));
+ close(fd);
+ return -1;
+ }
+ }else{
#endif
- if (bind(fd, (struct sockaddr *)&s->addr.v4, sizeof(s->addr.v4)) == -1) {
- ShowError("network_addlistener(%c, '%s', %u): bind failed (errno: %u / %s)\n", (v6==true?'t':'f'), addr, port, errno, strerror(errno));
- close(fd);
- return -1;
- }
+ if( bind(fd, (struct sockaddr*)&s->addr.v4, sizeof(s->addr.v4)) == -1) {
+ ShowError("network_addlistener(%c, '%s', %u): bind failed (errno: %u / %s)\n", (v6==true?'t':'f'), addr, port, errno, strerror(errno));
+ close(fd);
+ return -1;
+ }
#ifdef ENABLE_IPV6
- }
+ }
#endif
- if (listen(fd, l_ListenBacklog) == -1) {
- ShowError("network_addlistener(%c, '%s', %u): listen failed (errno: %u / %s)\n", (v6==true?'t':'f'), addr, port, errno, strerror(errno));
- close(fd);
- return -1;
- }
-
-
- // Set to nonblock!
- if (_setnonblock(fd) == false) {
- ShowError("network_addlistener(%c, '%s', %u): cannot set to nonblock (errno: %u / %s)\n", (v6==true?'t':'f'), addr, port, errno, strerror(errno));
- close(fd);
- return -1;
- }
-
-
- // Rgister @ evdp.
- if (evdp_addlistener(fd, &s->evdp_data) != true) {
- ShowError("network_addlistener(%c, '%s', %u): eventdispatcher subsystem returned an error.\n", (v6==true?'t':'f'), addr, port);
- close(fd);
- return -1;
- }
-
-
- // Apply flags on Session array for this conneciton.
- if (v6 == true) s->v6 = true;
- else s->v6 = false;
-
- s->type = NST_LISTENER;
- s->onRecv = _network_accept;
-
- ShowStatus("Added Listener on '%s':%u\n", addr, port, (v6==true ? "(ipv6)":"(ipv4)"));
-
- return fd;
+ if( listen(fd, l_ListenBacklog) == -1){
+ ShowError("network_addlistener(%c, '%s', %u): listen failed (errno: %u / %s)\n", (v6==true?'t':'f'), addr, port, errno, strerror(errno));
+ close(fd);
+ return -1;
+ }
+
+
+ // Set to nonblock!
+ if(_setnonblock(fd) == false){
+ ShowError("network_addlistener(%c, '%s', %u): cannot set to nonblock (errno: %u / %s)\n", (v6==true?'t':'f'), addr, port, errno, strerror(errno));
+ close(fd);
+ return -1;
+ }
+
+
+ // Rgister @ evdp.
+ if( evdp_addlistener(fd, &s->evdp_data) != true){
+ ShowError("network_addlistener(%c, '%s', %u): eventdispatcher subsystem returned an error.\n", (v6==true?'t':'f'), addr, port);
+ close(fd);
+ return -1;
+ }
+
+
+ // Apply flags on Session array for this conneciton.
+ if(v6 == true) s->v6 = true;
+ else s->v6 = false;
+
+ s->type = NST_LISTENER;
+ s->onRecv = _network_accept;
+
+ ShowStatus("Added Listener on '%s':%u\n", addr, port, (v6==true ? "(ipv6)":"(ipv4)") );
+
+ return fd;
}//end: network_addlistener()
-static bool _network_connect_establishedHandler(int32 fd)
-{
- register SESSION *s = &g_Session[fd];
- int val;
- socklen_t val_len;
-
- if (s->type == NST_FREE)
- return true; // due to multiple non coalesced event notifications
- // this can happen .. when a previous handled event has already disconnected the connection
- // within the same cycle..
-
- val = -1;
- val_len = sizeof(val);
- getsockopt(fd, SOL_SOCKET, SO_ERROR, &val, &val_len);
-
- if (val != 0) {
- // :( .. cleanup session..
- s->type = NST_FREE;
- s->onSend = NULL;
- s->onConnect = NULL;
- s->onDisconnect = NULL;
-
- evdp_remove(fd, &s->evdp_data);
- close(fd);
-
- return true; // we CANT return false,
- // becuase the normal disconnect procedure would execute the ondisconnect handler, which we dont want .. in this case.
- } else {
- // ok
- if (s->onConnect(fd) == false) {
- // onConnect handler has refused the connection ..
- // cleanup .. and ok
- s->type = NST_FREE;
- s->onSend = NULL;
- s->onConnect = NULL;
- s->onDisconnect = NULL;
-
- evdp_remove(fd, &s->evdp_data);
- close(fd);
-
- return true; // we dnot want the ondisconnect handler to be executed, so its okay to handle this by ourself.
- }
-
- // connection established !
- //
- if (evdp_outgoingconnection_established(fd, &s->evdp_data) == false) {
- return false; // we want the normal disconnect procedure.. with call to ondisconnect handler.
- }
-
- s->onSend = NULL;
-
- ShowStatus("#%u connection successfull!\n", fd);
- }
-
- return true;
+static bool _network_connect_establishedHandler(int32 fd){
+ register SESSION *s = &g_Session[fd];
+ int val;
+ socklen_t val_len;
+
+ if(s->type == NST_FREE)
+ return true; // due to multiple non coalesced event notifications
+ // this can happen .. when a previous handled event has already disconnected the connection
+ // within the same cycle..
+
+ val = -1;
+ val_len = sizeof(val);
+ getsockopt(fd, SOL_SOCKET, SO_ERROR, &val, &val_len);
+
+ if(val != 0){
+ // :( .. cleanup session..
+ s->type = NST_FREE;
+ s->onSend = NULL;
+ s->onConnect = NULL;
+ s->onDisconnect = NULL;
+
+ evdp_remove(fd, &s->evdp_data);
+ close(fd);
+
+ return true; // we CANT return false,
+ // becuase the normal disconnect procedure would execute the ondisconnect handler, which we dont want .. in this case.
+ }else{
+ // ok
+ if(s->onConnect(fd) == false) {
+ // onConnect handler has refused the connection ..
+ // cleanup .. and ok
+ s->type = NST_FREE;
+ s->onSend = NULL;
+ s->onConnect = NULL;
+ s->onDisconnect = NULL;
+
+ evdp_remove(fd, &s->evdp_data);
+ close(fd);
+
+ return true; // we dnot want the ondisconnect handler to be executed, so its okay to handle this by ourself.
+ }
+
+ // connection established !
+ //
+ if( evdp_outgoingconnection_established(fd, &s->evdp_data) == false ){
+ return false; // we want the normal disconnect procedure.. with call to ondisconnect handler.
+ }
+
+ s->onSend = NULL;
+
+ ShowStatus("#%u connection successfull!\n", fd);
+ }
+
+ return true;
}//end: _network_connect_establishedHandler()
int32 network_connect(bool v6,
- const char *addr,
- uint16 port,
- const char *from_addr,
- uint16 from_port,
- bool (*onConnectionEstablishedHandler)(int32 fd),
- void (*onConnectionLooseHandler)(int32 fd)
- )
-{
- register SESSION *s;
- int32 fd, optval, ret;
- struct sockaddr_in ip4;
+ const char *addr,
+ uint16 port,
+ const char *from_addr,
+ uint16 from_port,
+ bool (*onConnectionEstablishedHandler)(int32 fd),
+ void (*onConnectionLooseHandler)(int32 fd)
+){
+ register SESSION *s;
+ int32 fd, optval, ret;
+ struct sockaddr_in ip4;
#ifdef ENABLE_IPV6
- struct sockaddr_in6 ip6;
+ struct sockaddr_in6 ip6;
#endif
#ifdef ENABLE_IPV6
- if (v6 == true)
- fd = socket(AF_INET6, SOCK_STREAM, 0);
- else
+ if(v6 == true)
+ fd = socket(AF_INET6, SOCK_STREAM, 0);
+ else
#endif
- fd = socket(AF_INET, SOCK_STREAM, 0);
+ fd = socket(AF_INET, SOCK_STREAM, 0);
#ifndef ENABLE_IPV6
- // check..
- if (v6 == true) {
- ShowError("network_connect(%c, '%s', %u...): tried to create an ipv6 connection, IPV6 is not supported in this release.\n", (v6==true?'t':'f'), addr, port);
- return -1;
- }
+ // check..
+ if(v6 == true){
+ ShowError("network_connect(%c, '%s', %u...): tried to create an ipv6 connection, IPV6 is not supported in this release.\n", (v6==true?'t':'f'), addr, port);
+ return -1;
+ }
#endif
- // check connection limits.
- if (fd >= MAXCONN) {
- ShowError("network_connect(%c, '%s', %u...): cannot create new connection, exceeeds more than supported connections (%u)\n", (v6==true?'t':'f'), addr, port);
- close(fd);
- return -1;
- }
-
-
- // Originating IP/Port pair given ?
- if (from_addr != NULL && *from_addr != 0) {
- //..
-#ifdef SO_REUSEADDR
- optval=1;
- setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
-#endif
-
-#ifdef ENABLE_IPV6
- if (v6 == true) {
- memset(&ip6, 0x00, sizeof(ip6));
- ip6.sin6_family = AF_INET6;
- ip6.sin6_port = htons(from_port);
-
- if (inet_pton(AF_INET6, from_addr, &ip6.sin6_addr) != 1) {
- ShowError("network_connect(%c, '%s', %u...): cannot parse originating (from) IPV6 address (errno: %u / %s)\n", (v6==true?'t':'f'), addr, port, errno, strerror(errno));
- close(fd);
- return -1;
- }
-
- ret = bind(fd, (struct sockaddr *)&ip6, sizeof(ip6));
- } else {
-#endif
- memset(&ip4, 0x00, sizeof(ip4));
-
- ip4.sin_family = AF_INET;
- ip4.sin_port = htons(from_port);
- ip4.sin_addr.s_addr = inet_addr(from_addr);
- ret = bind(fd, (struct sockaddr *)&ip4, sizeof(ip4));
+ // check connection limits.
+ if(fd >= MAXCONN){
+ ShowError("network_connect(%c, '%s', %u...): cannot create new connection, exceeeds more than supported connections (%u)\n", (v6==true?'t':'f'), addr, port );
+ close(fd);
+ return -1;
+ }
+
+
+ // Originating IP/Port pair given ?
+ if(from_addr != NULL && *from_addr != 0){
+ //..
+ #ifdef SO_REUSEADDR
+ optval=1;
+ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
+ #endif
+
+ #ifdef ENABLE_IPV6
+ if(v6 == true){
+ memset(&ip6, 0x00, sizeof(ip6));
+ ip6.sin6_family = AF_INET6;
+ ip6.sin6_port = htons(from_port);
+
+ if(inet_pton(AF_INET6, from_addr, &ip6.sin6_addr) != 1){
+ ShowError("network_connect(%c, '%s', %u...): cannot parse originating (from) IPV6 address (errno: %u / %s)\n", (v6==true?'t':'f'), addr, port, errno, strerror(errno));
+ close(fd);
+ return -1;
+ }
+
+ ret = bind(fd, (struct sockaddr*)&ip6, sizeof(ip6));
+ }else{
+ #endif
+ memset(&ip4, 0x00, sizeof(ip4));
+
+ ip4.sin_family = AF_INET;
+ ip4.sin_port = htons(from_port);
+ ip4.sin_addr.s_addr = inet_addr(from_addr);
+ ret = bind(fd, (struct sockaddr*)&ip4, sizeof(ip4));
+ #ifdef ENABLE_IPV6
+ }
+ #endif
+
+ }
+
+
+ // Set non block
+ if(_setnonblock(fd) == false){
+ ShowError("network_connect(%c, '%s', %u...): cannot set socket to nonblocking (errno: %u / %s)\n", (v6==true?'t':'f'), addr, port, errno, strerror(errno));
+ close(fd);
+ return -1;
+ }
+
+
+ // Create ip addr block to connect to ..
#ifdef ENABLE_IPV6
- }
+ if(v6 == true){
+ memset(&ip6, 0x00, sizeof(ip6));
+ ip6.sin6_family = AF_INET6;
+ ip6.sin6_port = htons(port);
+
+ if(inet_pton(AF_INET6, addr, &ip6.sin6_addr) != 1){
+ ShowError("network_connect(%c, '%s', %u...): cannot parse destination IPV6 address (errno: %u / %s)\n", (v6==true?'t':'f'), addr, port, errno, strerror(errno));
+ close(fd);
+ return -1;
+ }
+
+ }else{
#endif
-
- }
-
-
- // Set non block
- if (_setnonblock(fd) == false) {
- ShowError("network_connect(%c, '%s', %u...): cannot set socket to nonblocking (errno: %u / %s)\n", (v6==true?'t':'f'), addr, port, errno, strerror(errno));
- close(fd);
- return -1;
- }
-
-
- // Create ip addr block to connect to ..
-#ifdef ENABLE_IPV6
- if (v6 == true) {
- memset(&ip6, 0x00, sizeof(ip6));
- ip6.sin6_family = AF_INET6;
- ip6.sin6_port = htons(port);
-
- if (inet_pton(AF_INET6, addr, &ip6.sin6_addr) != 1) {
- ShowError("network_connect(%c, '%s', %u...): cannot parse destination IPV6 address (errno: %u / %s)\n", (v6==true?'t':'f'), addr, port, errno, strerror(errno));
- close(fd);
- return -1;
- }
-
- } else {
-#endif
- memset(&ip4, 0x00, sizeof(ip4));
-
- ip4.sin_family = AF_INET;
- ip4.sin_port = htons(port);
- ip4.sin_addr.s_addr = inet_addr(addr);
+ memset(&ip4, 0x00, sizeof(ip4));
+
+ ip4.sin_family = AF_INET;
+ ip4.sin_port = htons(port);
+ ip4.sin_addr.s_addr = inet_addr(addr);
#ifdef ENABLE_IPV6
- }
+ }
#endif
- // Assign Session..
- s = &g_Session[fd];
- s->type = NST_OUTGOING;
- s->v6 = v6;
- s->onConnect = onConnectionEstablishedHandler;
- s->onDisconnect = onConnectionLooseHandler;
- s->onRecv = NULL;
- s->onSend = _network_connect_establishedHandler;
+ // Assign Session..
+ s = &g_Session[fd];
+ s->type = NST_OUTGOING;
+ s->v6 = v6;
+ s->onConnect = onConnectionEstablishedHandler;
+ s->onDisconnect = onConnectionLooseHandler;
+ s->onRecv = NULL;
+ s->onSend = _network_connect_establishedHandler;
#ifdef ENABLE_IPV6
- if (v6 == true)
- memcpy(&s->addr.v6, &ip6, sizeof(ip6));
- else
+ if(v6 == true)
+ memcpy(&s->addr.v6, &ip6, sizeof(ip6));
+ else
#endif
- memcpy(&s->addr.v4, &ip4, sizeof(ip4));
-
- // Register @ EVDP. as outgoing (see doc of the function)
- if (evdp_addconnecting(fd, &s->evdp_data) == false) {
- ShowError("network_connect(%c, '%s', %u...): eventdispatcher subsystem returned an error.\n", (v6==true?'t':'f'), addr, port);
-
- // cleanup session x.x..
- s->type = NST_FREE;
- s->onConnect = NULL;
- s->onDisconnect = NULL;
- s->onSend = NULL;
-
- // close, return error code.
- close(fd);
- return -1;
- }
+ memcpy(&s->addr.v4, &ip4, sizeof(ip4));
+
+ // Register @ EVDP. as outgoing (see doc of the function)
+ if(evdp_addconnecting(fd, &s->evdp_data) == false){
+ ShowError("network_connect(%c, '%s', %u...): eventdispatcher subsystem returned an error.\n", (v6==true?'t':'f'), addr, port);
+
+ // cleanup session x.x..
+ s->type = NST_FREE;
+ s->onConnect = NULL;
+ s->onDisconnect = NULL;
+ s->onSend = NULL;
+
+ // close, return error code.
+ close(fd);
+ return -1;
+ }
#ifdef ENABLE_IPV6
- if (v6 == true)
- ret = connect(fd, (struct sockaddr *)&ip6, sizeof(ip6));
- else
+ if(v6 == true)
+ ret = connect(fd, (struct sockaddr*)&ip6, sizeof(ip6));
+ else
#endif
- ret = connect(fd, (struct sockaddr *)&ip4, sizeof(ip4));
-
-
- //
- if (ret != 0 && errno != EINPROGRESS) {
- ShowWarning("network_connect(%c, '%s', %u...): connection failed (errno: %u / %s)\n", (v6==true?'t':'f'), addr, port, errno, strerror(errno));
-
- // Cleanup session ..
- s->type = NST_FREE;
- s->onConnect = NULL;
- s->onDisconnect = NULL;
- s->onSend = NULL;
-
- // .. remove from evdp and close fd.
- evdp_remove(fd, &s->evdp_data);
- close(fd);
- return -1;
- }
-
-
- // ! The Info Message :~D
- ShowStatus("network_connect fd#%u (%s:%u) in progress.. \n", fd, addr, port);
-
- return fd;
+ ret = connect(fd, (struct sockaddr*)&ip4, sizeof(ip4));
+
+
+ //
+ if(ret != 0 && errno != EINPROGRESS){
+ ShowWarning("network_connect(%c, '%s', %u...): connection failed (errno: %u / %s)\n", (v6==true?'t':'f'), addr, port, errno, strerror(errno));
+
+ // Cleanup session ..
+ s->type = NST_FREE;
+ s->onConnect = NULL;
+ s->onDisconnect = NULL;
+ s->onSend = NULL;
+
+ // .. remove from evdp and close fd.
+ evdp_remove(fd, &s->evdp_data);
+ close(fd);
+ return -1;
+ }
+
+
+ // ! The Info Message :~D
+ ShowStatus("network_connect fd#%u (%s:%u) in progress.. \n", fd, addr, port);
+
+return fd;
}//end: network_connect()
-static bool _onSend(int32 fd)
-{
- register SESSION *s = &g_Session[fd];
- register netbuf buf, buf_next;
- register uint32 szNeeded;
- register int wLen;
-
- if (s->type == NST_FREE)
- return true; // Possible due to multipl non coalsced event notifications
- // so onSend gets called after disconnect caused by an previous vent.
- // we can ignore the call to onSend, then.
-
- buf = s->write.buf;
- while (1) {
- if (buf == NULL)
- break;
-
- buf_next = buf->next;
-
-
- szNeeded = (buf->dataLen - s->write.dataPos); // using th session-local .dataPos member, due to shared write buffer support.
-
- // try to write.
- wLen = write(fd, &buf->buf[s->write.dataPos], szNeeded);
- if (wLen == 0) {
- return false; // eof.
- } else if (wLen == -1) {
- if (errno == EAGAIN || errno == EWOULDBLOCK)
- return true; // dont disconnect / try again later.
-
- // all other errors. .
- return false;
- }
-
- // Wrote data.. =>
- szNeeded -= wLen;
- if (szNeeded > 0) {
- // still data left ..
- //
- s->write.dataPos += wLen; // fix offset.
- return true;
- } else {
- // this buffer has been written successfully
- // could be returned to pool.
- netbuffer_put(buf);
- s->write.n_outstanding--; // When threadsafe -> Interlocked here.
- s->write.dataPos = 0;
- }
-
-
- buf = buf_next;
- }
-
- // okay,
- // reaching this part means:
- // while interrupted by break -
- // which means all buffers are written, nothing left
- //
-
- s->write.buf_last = NULL;
- s->write.buf = NULL;
- s->write.n_outstanding = 0;
- s->write.dataPos = 0;
-
- // Remove from event dispatcher (write notification)
- //
- evdp_writable_remove(fd, &s->evdp_data);
-
- return true;
+static bool _onSend(int32 fd){
+ register SESSION *s = &g_Session[fd];
+ register netbuf buf, buf_next;
+ register uint32 szNeeded;
+ register int wLen;
+
+ if(s->type == NST_FREE)
+ return true; // Possible due to multipl non coalsced event notifications
+ // so onSend gets called after disconnect caused by an previous vent.
+ // we can ignore the call to onSend, then.
+
+ buf = s->write.buf;
+ while(1){
+ if(buf == NULL)
+ break;
+
+ buf_next = buf->next;
+
+
+ szNeeded = (buf->dataLen - s->write.dataPos); // using th session-local .dataPos member, due to shared write buffer support.
+
+ // try to write.
+ wLen = write(fd, &buf->buf[s->write.dataPos], szNeeded);
+ if(wLen == 0){
+ return false; // eof.
+ }else if(wLen == -1){
+ if(errno == EAGAIN || errno == EWOULDBLOCK)
+ return true; // dont disconnect / try again later.
+
+ // all other errors. .
+ return false;
+ }
+
+ // Wrote data.. =>
+ szNeeded -= wLen;
+ if(szNeeded > 0){
+ // still data left ..
+ //
+ s->write.dataPos += wLen; // fix offset.
+ return true;
+ }else{
+ // this buffer has been written successfully
+ // could be returned to pool.
+ netbuffer_put(buf);
+ s->write.n_outstanding--; // When threadsafe -> Interlocked here.
+ s->write.dataPos = 0;
+ }
+
+
+ buf = buf_next;
+ }
+
+ // okay,
+ // reaching this part means:
+ // while interrupted by break -
+ // which means all buffers are written, nothing left
+ //
+
+ s->write.buf_last = NULL;
+ s->write.buf = NULL;
+ s->write.n_outstanding = 0;
+ s->write.dataPos = 0;
+
+ // Remove from event dispatcher (write notification)
+ //
+ evdp_writable_remove(fd, &s->evdp_data);
+
+ return true;
}//end: _onSend()
-static bool _onRORecv(int32 fd)
-{
- register SESSION *s = &g_Session[fd];
- register uint32 szNeeded;
- register char *p;
- register int rLen;
-
- if (s->type == NST_FREE)
- return true; // Possible due to multiple non coalesced events by evdp.
- // simply ignore this call returning positive result.
-
- // Initialize p and szNeeded depending on change
- //
- switch (s->read.state) {
- case NRS_WAITOP:
- szNeeded = s->read.head_left;
- p = ((char *)&s->read.head[0]) + (2-szNeeded);
- break;
-
- case NRS_WAITLEN:
- szNeeded = s->read.head_left;
- p = ((char *)&s->read.head[1]) + (2-szNeeded);
- break;
-
- case NRS_WAITDATA: {
- register netbuf buf = s->read.buf;
-
- szNeeded = (buf->dataLen - buf->dataPos);
- p = (char *)&buf->buf[ buf->dataPos ];
- }
- break;
-
- default:
- // .. the impossible gets possible ..
- ShowError("_onRORecv: fd #%u has unknown read.state (%d) - disconnecting\n", fd, s->read.state);
- return false;
- break;
- }
-
-
- //
-
- rLen = read(fd, p, szNeeded);
- if (rLen == 0) {
- // eof..
- return false;
- } else if (rLen == -1) {
-
- if (errno == EAGAIN || errno == EWOULDBLOCK) {
- // try again later .. (this case shouldnt happen, because we're event trigered.. but .. sometimes it happens :)
- return true;
- }
-
- // an additional interesting case would be
- // EINTR, this 'could' be handled .. but:
- // posix says that its possible that data gets currupted during irq
- // or data gor read and not reported.., so we'd have a data loss..
- // (which shouldnt happen with stream based protocols such as tcp)
- // its better to disonnect the client in that case.
-
- return false;
- }
-
- //
- // Got Data:
- // next action also depends on current state ..
- //
- szNeeded -= rLen;
- switch (s->read.state) {
- case NRS_WAITOP:
-
- if (szNeeded > 0) {
- // still data missing ..
- s->read.head_left = szNeeded;
- return true; // wait for completion.
- } else {
- // complete ..
- // next state depends on packet type.
-
- s->read.head[1] = ((uint16 *)s->netparser_data)[ s->read.head[0] ]; // store lenght of packet by opcode head[0] to head[1]
-
- if (s->read.head[1] == ROPACKET_UNKNOWN) {
- // unknown packet - disconnect
- ShowWarning("_onRORecv: fd #%u got unlnown packet 0x%04x - disconnecting.\n", fd, s->read.head[0]);
- return false;
- } else if (s->read.head[1] == ROPACKET_DYNLEN) {
- // dynamic length
- // next state: requrie len.
- s->read.state = NRS_WAITLEN;
- s->read.head_left = 2;
- return true; //
- } else if (s->read.head[1] == 2) {
- // packet has no data (only opcode)
- register netbuf buf = netbuffer_get(2); // :D whoohoo its giant!
-
- NBUFW(buf, 0) = s->read.head[0]; // store opcode @ packet begin.
- buf->dataPos = 2;
- buf->dataLen = 2;
- buf->next = NULL;
-
- // Back to initial state -> Need opcode.
- s->read.state = NRS_WAITOP;
- s->read.head_left = 2;
- s->read.buf = NULL;
-
- // Call completion routine here.
- s->onPacketComplete(fd, s->read.head[0], 2, buf);
-
- return true; // done :)
- } else {
- // paket needs .. data ..
- register netbuf buf = netbuffer_get(s->read.head[1]);
-
- NBUFW(buf, 0) = s->read.head[0]; // store opcode @ packet begin.
- buf->dataPos = 2;
- buf->dataLen = s->read.head[1];
- buf->next = NULL;
-
- // attach buffer.
- s->read.buf = buf;
-
- // set state:
- s->read.state = NRS_WAITDATA;
-
- return true;
- }
-
- }//endif: szNeeded > 0 (opcode read completed?)
-
- break;
-
-
- case NRS_WAITLEN:
-
- if (szNeeded > 0) {
- // incomplete ..
- s->read.head_left = szNeeded;
- return true;
- } else {
-
- if (s->read.head[1] == 4) {
- // packet has no data (only opcode + length)
- register netbuf buf = netbuffer_get(4);
-
- NBUFL(buf, 0) = *((uint32 *)&s->read.head[0]); // copy Opcode + length to netbuffer using MOVL
- buf->dataPos = 4;
- buf->dataLen = 4;
- buf->next = NULL;
-
- // set initial state (need opcode)
- s->read.state = NRS_WAITOP;
- s->read.head_left = 2;
- s->read.buf = NULL;
-
- // call completion routine.
- s->onPacketComplete(fd, s->read.head[0], 4, buf);
-
- return true;
- } else if (s->read.head[1] < 4) {
- // invalid header.
- ShowWarning("_onRORecv: fd #%u invalid header - got packet 0x%04x, reported length < 4 - INVALID - disconnecting\n", fd, s->read.head[0]);
- return false;
- } else {
- // Data needed
- // next state -> waitdata!
- register netbuf buf = netbuffer_get(s->read.head[1]);
-
- NBUFL(buf, 0) = *((uint32 *)&s->read.head[0]); // copy Opcode + length to netbuffer using MOVL
- buf->dataPos = 4;
- buf->dataLen = s->read.head[1];
- buf->next = NULL;
-
- // attach to session:
- s->read.buf = buf;
- s->read.state = NRS_WAITDATA;
-
- return true;
- }
-
- }//endif: szNeeded > 0 (length read complete?)
-
- break;
-
-
- case NRS_WAITDATA:
-
- if (szNeeded == 0) {
- // Packet finished!
- // compltion.
- register netbuf buf = s->read.buf;
-
- // set initial state.
- s->read.state = NRS_WAITOP;
- s->read.head_left = 2;
- s->read.buf = NULL;
-
- // Call completion routine.
- s->onPacketComplete(fd, NBUFW(buf, 0), buf->dataLen, buf);
-
- return true;
- } else {
- // still data needed
- s->read.buf->dataPos += rLen;
-
- return true;
- }
- break;
-
-
- //
- default:
- ShowError("_onRORecv: fd #%u has unknown read.state (%d) [2] - disconnecting\n", fd, s->read.state);
- return false;
- break;
- }
-
-
- return false;
+static bool _onRORecv(int32 fd){
+ register SESSION *s = &g_Session[fd];
+ register uint32 szNeeded;
+ register char *p;
+ register int rLen;
+
+ if(s->type == NST_FREE)
+ return true; // Possible due to multiple non coalesced events by evdp.
+ // simply ignore this call returning positive result.
+
+ // Initialize p and szNeeded depending on change
+ //
+ switch(s->read.state){
+ case NRS_WAITOP:
+ szNeeded = s->read.head_left;
+ p = ((char*)&s->read.head[0]) + (2-szNeeded);
+ break;
+
+ case NRS_WAITLEN:
+ szNeeded = s->read.head_left;
+ p = ((char*)&s->read.head[1]) + (2-szNeeded);
+ break;
+
+ case NRS_WAITDATA:{
+ register netbuf buf = s->read.buf;
+
+ szNeeded = (buf->dataLen - buf->dataPos);
+ p = (char*)&buf->buf[ buf->dataPos ];
+ }
+ break;
+
+ default:
+ // .. the impossible gets possible ..
+ ShowError("_onRORecv: fd #%u has unknown read.state (%d) - disconnecting\n", fd, s->read.state);
+ return false;
+ break;
+ }
+
+
+ //
+
+ rLen = read(fd, p, szNeeded);
+ if(rLen == 0){
+ // eof..
+ return false;
+ }else if(rLen == -1){
+
+ if(errno == EAGAIN || errno == EWOULDBLOCK){
+ // try again later .. (this case shouldnt happen, because we're event trigered.. but .. sometimes it happens :)
+ return true;
+ }
+
+ // an additional interesting case would be
+ // EINTR, this 'could' be handled .. but:
+ // posix says that its possible that data gets currupted during irq
+ // or data gor read and not reported.., so we'd have a data loss..
+ // (which shouldnt happen with stream based protocols such as tcp)
+ // its better to disonnect the client in that case.
+
+ return false;
+ }
+
+ //
+ // Got Data:
+ // next action also depends on current state ..
+ //
+ szNeeded -= rLen;
+ switch(s->read.state){
+ case NRS_WAITOP:
+
+ if(szNeeded > 0){
+ // still data missing ..
+ s->read.head_left = szNeeded;
+ return true; // wait for completion.
+ }else{
+ // complete ..
+ // next state depends on packet type.
+
+ s->read.head[1] = ((uint16*)s->netparser_data)[ s->read.head[0] ]; // store lenght of packet by opcode head[0] to head[1]
+
+ if(s->read.head[1] == ROPACKET_UNKNOWN){
+ // unknown packet - disconnect
+ ShowWarning("_onRORecv: fd #%u got unlnown packet 0x%04x - disconnecting.\n", fd, s->read.head[0]);
+ return false;
+ }
+ else if(s->read.head[1] == ROPACKET_DYNLEN){
+ // dynamic length
+ // next state: requrie len.
+ s->read.state = NRS_WAITLEN;
+ s->read.head_left = 2;
+ return true; //
+ }
+ else if(s->read.head[1] == 2){
+ // packet has no data (only opcode)
+ register netbuf buf = netbuffer_get(2); // :D whoohoo its giant!
+
+ NBUFW(buf, 0) = s->read.head[0]; // store opcode @ packet begin.
+ buf->dataPos = 2;
+ buf->dataLen = 2;
+ buf->next = NULL;
+
+ // Back to initial state -> Need opcode.
+ s->read.state = NRS_WAITOP;
+ s->read.head_left = 2;
+ s->read.buf = NULL;
+
+ // Call completion routine here.
+ s->onPacketComplete(fd, s->read.head[0], 2, buf);
+
+ return true; // done :)
+ }
+ else{
+ // paket needs .. data ..
+ register netbuf buf = netbuffer_get( s->read.head[1] );
+
+ NBUFW(buf, 0) = s->read.head[0]; // store opcode @ packet begin.
+ buf->dataPos = 2;
+ buf->dataLen = s->read.head[1];
+ buf->next = NULL;
+
+ // attach buffer.
+ s->read.buf = buf;
+
+ // set state:
+ s->read.state = NRS_WAITDATA;
+
+ return true;
+ }
+
+ }//endif: szNeeded > 0 (opcode read completed?)
+
+ break;
+
+
+ case NRS_WAITLEN:
+
+ if(szNeeded > 0){
+ // incomplete ..
+ s->read.head_left = szNeeded;
+ return true;
+ }else{
+
+ if(s->read.head[1] == 4){
+ // packet has no data (only opcode + length)
+ register netbuf buf = netbuffer_get( 4 );
+
+ NBUFL(buf, 0) = *((uint32*)&s->read.head[0]); // copy Opcode + length to netbuffer using MOVL
+ buf->dataPos = 4;
+ buf->dataLen = 4;
+ buf->next = NULL;
+
+ // set initial state (need opcode)
+ s->read.state = NRS_WAITOP;
+ s->read.head_left = 2;
+ s->read.buf = NULL;
+
+ // call completion routine.
+ s->onPacketComplete(fd, s->read.head[0], 4, buf);
+
+ return true;
+ }
+ else if(s->read.head[1] < 4){
+ // invalid header.
+ ShowWarning("_onRORecv: fd #%u invalid header - got packet 0x%04x, reported length < 4 - INVALID - disconnecting\n", fd, s->read.head[0]);
+ return false;
+ }
+ else{
+ // Data needed
+ // next state -> waitdata!
+ register netbuf buf = netbuffer_get( s->read.head[1] );
+
+ NBUFL(buf, 0) = *((uint32*)&s->read.head[0]); // copy Opcode + length to netbuffer using MOVL
+ buf->dataPos = 4;
+ buf->dataLen = s->read.head[1];
+ buf->next = NULL;
+
+ // attach to session:
+ s->read.buf = buf;
+ s->read.state = NRS_WAITDATA;
+
+ return true;
+ }
+
+ }//endif: szNeeded > 0 (length read complete?)
+
+ break;
+
+
+ case NRS_WAITDATA:
+
+ if(szNeeded == 0){
+ // Packet finished!
+ // compltion.
+ register netbuf buf = s->read.buf;
+
+ // set initial state.
+ s->read.state = NRS_WAITOP;
+ s->read.head_left = 2;
+ s->read.buf = NULL;
+
+ // Call completion routine.
+ s->onPacketComplete(fd, NBUFW(buf, 0), buf->dataLen, buf);
+
+ return true;
+ }else{
+ // still data needed
+ s->read.buf->dataPos += rLen;
+
+ return true;
+ }
+ break;
+
+
+ //
+ default:
+ ShowError("_onRORecv: fd #%u has unknown read.state (%d) [2] - disconnecting\n", fd, s->read.state);
+ return false;
+ break;
+ }
+
+
+ return false;
}//end: _onRORecv()
-void network_send(int32 fd, netbuf buf)
-{
- register SESSION *s = &g_Session[fd];
-
+void network_send(int32 fd, netbuf buf){
+ register SESSION *s = &g_Session[fd];
+
#ifdef PARANOID_CHECKS
- if (fd >= MAXCONN) {
- ShowError("network_send: tried to attach buffer to connection idientifer #%u which is out of bounds.\n", fd);
- _network_free_netbuf_async(buf);
- return;
- }
+ if(fd >= MAXCONN){
+ ShowError("network_send: tried to attach buffer to connection idientifer #%u which is out of bounds.\n", fd);
+ _network_free_netbuf_async(buf);
+ return;
+ }
#endif
- if (s->type == NST_FREE)
- return;
-
- // Check Max Outstanding buffers limit.
- if ((s->write.max_outstanding > 0) &&
- (s->write.n_outstanding >= s->write.max_outstanding)) {
-
- ShowWarning("network_send: fd #%u max Outstanding buffers exceeded. - disconnecting.\n", fd);
- network_disconnect(fd);
- //
- _network_free_netbuf_async(buf);
- return;
- }
-
-
- // Attach to the end:
- buf->next = NULL;
- if (s->write.buf_last != NULL) {
- s->write.buf_last->next = buf;
- s->write.buf_last = buf;
-
- } else {
- // currently no buffer attached.
- s->write.buf = s->write.buf_last = buf;
-
- // register @ evdp for writable notification.
- evdp_writable_add(fd, &s->evdp_data); //
- }
-
-
- //
- s->write.n_outstanding++;
-
+ if(s->type == NST_FREE)
+ return;
+
+ // Check Max Outstanding buffers limit.
+ if( (s->write.max_outstanding > 0) &&
+ (s->write.n_outstanding >= s->write.max_outstanding) ){
+
+ ShowWarning("network_send: fd #%u max Outstanding buffers exceeded. - disconnecting.\n", fd);
+ network_disconnect(fd);
+ //
+ _network_free_netbuf_async(buf);
+ return;
+ }
+
+
+ // Attach to the end:
+ buf->next = NULL;
+ if(s->write.buf_last != NULL){
+ s->write.buf_last->next = buf;
+ s->write.buf_last = buf;
+
+ }else{
+ // currently no buffer attached.
+ s->write.buf = s->write.buf_last = buf;
+
+ // register @ evdp for writable notification.
+ evdp_writable_add(fd, &s->evdp_data); //
+ }
+
+
+ //
+ s->write.n_outstanding++;
+
}//end: network_send()
void network_parser_set_ro(int32 fd,
- int16 *packetlentable,
- void (*onPacketCompleteProc)(int32 fd, uint16 op, uint16 len, netbuf buf)
- )
-{
- register SESSION *s = &g_Session[fd];
- register netbuf b, nb; // used for potential free attached buffers.
-
- if (s->type == NST_FREE)
- return;
-
- s->onPacketComplete = onPacketCompleteProc;
-
- s->onRecv = _onRORecv; // ..
- s->onSend = _onSend; // Using the normal generic netbuf based send function.
-
- s->netparser_data = packetlentable;
-
- // Initial State -> Need Packet OPCode.
- s->read.state = NRS_WAITOP;
- s->read.head_left = 2;
-
-
- // Detach (if..) all buffers.
- if (s->read.buf != NULL) {
- _network_free_netbuf_async(s->read.buf); //
- s->read.buf = NULL;
- }
-
- if (s->write.buf != NULL) {
- b = s->write.buf;
- while (1) {
- nb = b->next;
-
- _network_free_netbuf_async(b);
-
- b = nb;
- }
-
- s->write.buf = NULL;
- s->write.buf_last = NULL;
- s->write.n_outstanding = 0;
- }
-
- // not changing any limits on outstanding ..
- //
-
+ int16 *packetlentable,
+ void (*onPacketCompleteProc)(int32 fd, uint16 op, uint16 len, netbuf buf)
+ ){
+ register SESSION *s = &g_Session[fd];
+ register netbuf b, nb; // used for potential free attached buffers.
+
+ if(s->type == NST_FREE)
+ return;
+
+ s->onPacketComplete = onPacketCompleteProc;
+
+ s->onRecv = _onRORecv; // ..
+ s->onSend = _onSend; // Using the normal generic netbuf based send function.
+
+ s->netparser_data = packetlentable;
+
+ // Initial State -> Need Packet OPCode.
+ s->read.state = NRS_WAITOP;
+ s->read.head_left = 2;
+
+
+ // Detach (if..) all buffers.
+ if(s->read.buf != NULL){
+ _network_free_netbuf_async(s->read.buf); //
+ s->read.buf = NULL;
+ }
+
+ if(s->write.buf != NULL){
+ b = s->write.buf;
+ while(1){
+ nb = b->next;
+
+ _network_free_netbuf_async(b);
+
+ b = nb;
+ }
+
+ s->write.buf = NULL;
+ s->write.buf_last = NULL;
+ s->write.n_outstanding = 0;
+ }
+
+ // not changing any limits on outstanding ..
+ //
+
}//end: network_parser_set_ro()
diff --git a/src/common/network.h b/src/common/network.h
index b883b41e6..d7b463a2f 100644
--- a/src/common/network.h
+++ b/src/common/network.h
@@ -3,7 +3,7 @@
#include <netinet/in.h>
#include "../common/cbasetypes.h"
-#include "../common/netbuffer.h"
+#include "../common/netbuffer.h"
#include "../common/evdp.h"
#ifndef MAXCONN
@@ -11,79 +11,79 @@
#endif
-typedef struct SESSION {
- EVDP_DATA evdp_data; // Must be always the frist member! (some evdp's may rely on this fact)
-
- // Connection Type
- enum { NST_FREE=0, NST_LISTENER = 1, NST_CLIENT=2, NST_OUTGOING=3} type;
-
- // Flags / Settings.
- bool v6; // is v6?
- bool disconnect_in_progress; // To prevent stack overflows / recursive calls.
-
-
- union { // union to save memory.
- struct sockaddr_in v4;
- struct sockaddr_in6 v6;
- } addr;
-
-
- // "lowlevel" Handlers
- // (Implemented by the protocol specific parser)
- //
- bool (*onRecv)(int32 fd); // return false = disconnect
- bool (*onSend)(int32 fd); // return false = disconnect
-
- // Event Handlers for LISTENER type sockets
- //
- // onConnect gets Called when a connection has been
- // successfully accepted.
- // Session entry is available in this Handler!
- // A returncode of false will reejct the connection (disconnect)
- // Note: When rejecting a connection in onConnect by returning false
- // The onDisconnect handler wont get called!
- // Note: the onConnect Handler is also responsible for setting
- // the appropriate netparser (which implements onRecv/onSend..) [protocol specific]
- //
- // onDisconnect gets called when a connection gets disconnected
- // (by peer as well as by core)
- //
- bool (*onConnect)(int32 fd); // return false = disconnect (wont accept)
- void (*onDisconnect)(int32 fd);
-
-
- //
- // Parser specific data
- //
- void *netparser_data; // incase of RO Packet Parser, pointer to packet len table (uint16array)
- void (*onPacketComplete)(int32 fd, uint16 op, uint16 len, netbuf buf);
-
-
- //
- // Buffers
- //
- struct {
- enum NETREADSTATE { NRS_WAITOP = 0, NRS_WAITLEN = 1, NRS_WAITDATA = 2} state;
-
- uint32 head_left;
- uint16 head[2];
-
- netbuf buf;
- } read;
-
- struct {
- uint32 max_outstanding;
- uint32 n_outstanding;
-
- uint32 dataPos;
-
- netbuf buf, buf_last;
- } write;
-
- // Application Level data Pointer
- // (required for backward compatibility with previous athena socket system.)
- void *data;
-
+typedef struct SESSION{
+ EVDP_DATA evdp_data; // Must be always the frist member! (some evdp's may rely on this fact)
+
+ // Connection Type
+ enum{ NST_FREE=0, NST_LISTENER = 1, NST_CLIENT=2, NST_OUTGOING=3} type;
+
+ // Flags / Settings.
+ bool v6; // is v6?
+ bool disconnect_in_progress; // To prevent stack overflows / recursive calls.
+
+
+ union{ // union to save memory.
+ struct sockaddr_in v4;
+ struct sockaddr_in6 v6;
+ }addr;
+
+
+ // "lowlevel" Handlers
+ // (Implemented by the protocol specific parser)
+ //
+ bool (*onRecv)(int32 fd); // return false = disconnect
+ bool (*onSend)(int32 fd); // return false = disconnect
+
+ // Event Handlers for LISTENER type sockets
+ //
+ // onConnect gets Called when a connection has been
+ // successfully accepted.
+ // Session entry is available in this Handler!
+ // A returncode of false will reejct the connection (disconnect)
+ // Note: When rejecting a connection in onConnect by returning false
+ // The onDisconnect handler wont get called!
+ // Note: the onConnect Handler is also responsible for setting
+ // the appropriate netparser (which implements onRecv/onSend..) [protocol specific]
+ //
+ // onDisconnect gets called when a connection gets disconnected
+ // (by peer as well as by core)
+ //
+ bool (*onConnect)(int32 fd); // return false = disconnect (wont accept)
+ void (*onDisconnect)(int32 fd);
+
+
+ //
+ // Parser specific data
+ //
+ void *netparser_data; // incase of RO Packet Parser, pointer to packet len table (uint16array)
+ void (*onPacketComplete)(int32 fd, uint16 op, uint16 len, netbuf buf);
+
+
+ //
+ // Buffers
+ //
+ struct{
+ enum NETREADSTATE { NRS_WAITOP = 0, NRS_WAITLEN = 1, NRS_WAITDATA = 2} state;
+
+ uint32 head_left;
+ uint16 head[2];
+
+ netbuf buf;
+ } read;
+
+ struct{
+ uint32 max_outstanding;
+ uint32 n_outstanding;
+
+ uint32 dataPos;
+
+ netbuf buf, buf_last;
+ } write;
+
+ // Application Level data Pointer
+ // (required for backward compatibility with previous athena socket system.)
+ void *data;
+
} SESSION;
@@ -101,12 +101,12 @@ void network_final();
void network_do();
-/**
+/**
* Adds a new listner.
*
- * @param v6 v6 listner?
- * @param *addr the address to listen on.
- * @param port port to listen on
+ * @param v6 v6 listner?
+ * @param *addr the address to listen on.
+ * @param port port to listen on
*
* @return -1 on error otherwise the identifier of the new listener.
*/
@@ -116,26 +116,26 @@ int32 network_addlistener(bool v6, const char *addr, uint16 port);
/**
* Tries to establish an outgoing connection.
*
- * @param v6 operate with IPv6 addresses?
- * @param addr the address to connect to
- * @param port the port to connect to
- * @param from_addr the address to connect from (local source / optional if auto -> NULL)
+ * @param v6 operate with IPv6 addresses?
+ * @param addr the address to connect to
+ * @param port the port to connect to
+ * @param from_addr the address to connect from (local source / optional if auto -> NULL)
* @param from_port the port to connect from (local source / optional if auto -> 0)
- * @param onConnectionEstablishedHandler callback that gets called when the connection is established.
- * @param onConnectionLooseHandler callback that gets called when the connection gets disconnected (or the connection couldnt be established)
+ * @param onConnectionEstablishedHandler callback that gets called when the connection is established.
+ * @param onConnectionLooseHandler callback that gets called when the connection gets disconnected (or the connection couldnt be established)
*
* @return -1 on error otherwise the identifier of the new connection
*/
int32 network_connect(bool v6,
- const char *addr,
- uint16 port,
- const char *from_addr,
- uint16 from_port,
- bool (*onConnectionEstablishedHandler)(int32 fd),
- void (*onConnectionLooseHandler)(int32 fd)
- );
-
+ const char *addr,
+ uint16 port,
+ const char *from_addr,
+ uint16 from_port,
+ bool (*onConnectionEstablishedHandler)(int32 fd),
+ void (*onConnectionLooseHandler)(int32 fd)
+);
+
/**
* Disconnects the given connection
@@ -143,43 +143,43 @@ int32 network_connect(bool v6,
* @param fd connection identifier.
*
* @Note:
- * - onDisconnect callback gets called!
- * - cleares (returns) all assigned buffers
+ * - onDisconnect callback gets called!
+ * - cleares (returns) all assigned buffers
*
*/
void network_disconnect(int32 fd);
-/**
+/**
* Attach's a netbuffer at the end of sending queue to the given connection
*
- * @param fd connection identifier
- * @param buf netbuffer to attach.
+ * @param fd connection identifier
+ * @param buf netbuffer to attach.
*/
void network_send(int32 fd, netbuf buf);
/**
* Sets the parser to RO Protocol like Packet Parser.
- *
- * @param fd connection identifier
- * @param *packetlentable pointer to array of uint16 in size of UINT16_MAX,
- * @param onComplteProc callback for packet completion.
+ *
+ * @param fd connection identifier
+ * @param *packetlentable pointer to array of uint16 in size of UINT16_MAX,
+ * @param onComplteProc callback for packet completion.
*
* @note:
- * PacketLen Table Fromat:
- * each element's offsets represents th ro opcode.
- * value is length.
- * a length of 0 means the packet is dynamic.
- * a length of UINT16_MAX means the packet is unknown.
+ * PacketLen Table Fromat:
+ * each element's offsets represents th ro opcode.
+ * value is length.
+ * a length of 0 means the packet is dynamic.
+ * a length of UINT16_MAX means the packet is unknown.
*
- * Static Packets must contain their hader in len so (0x64 == 55 ..)
+ * Static Packets must contain their hader in len so (0x64 == 55 ..)
*
*/
void network_parser_set_ro(int32 fd,
- int16 *packetlentable,
- void (*onPacketCompleteProc)(int32 fd, uint16 op, uint16 len, netbuf buf)
- );
+ int16 *packetlentable,
+ void (*onPacketCompleteProc)(int32 fd, uint16 op, uint16 len, netbuf buf)
+ );
#define ROPACKET_UNKNOWN UINT16_MAX
#define ROPACKET_DYNLEN 0
diff --git a/src/common/nullpo.c b/src/common/nullpo.c
index ef2f3cd66..4383109a7 100644
--- a/src/common/nullpo.c
+++ b/src/common/nullpo.c
@@ -8,7 +8,7 @@
#include "../common/showmsg.h"
// #include "logs.h" // •z΂µ‚Ä‚Ý‚é
-static void nullpo_info_core(const char *file, int line, const char *func,
+static void nullpo_info_core(const char *file, int line, const char *func,
const char *fmt, va_list ap);
/*======================================
@@ -17,73 +17,75 @@ static void nullpo_info_core(const char *file, int line, const char *func,
int nullpo_chk_f(const char *file, int line, const char *func, const void *target,
const char *fmt, ...)
{
- va_list ap;
-
- if (target != NULL)
- return 0;
-
- va_start(ap, fmt);
- nullpo_info_core(file, line, func, fmt, ap);
- va_end(ap);
- return 1;
+ va_list ap;
+
+ if (target != NULL)
+ return 0;
+
+ va_start(ap, fmt);
+ nullpo_info_core(file, line, func, fmt, ap);
+ va_end(ap);
+ return 1;
}
int nullpo_chk(const char *file, int line, const char *func, const void *target)
{
- if (target != NULL)
- return 0;
-
- nullpo_info_core(file, line, func, NULL, NULL);
- return 1;
+ if (target != NULL)
+ return 0;
+
+ nullpo_info_core(file, line, func, NULL, NULL);
+ return 1;
}
/*======================================
* nullpoî•ño—Í(ŠO•”ŒÄo‚µŒü‚¯ƒ‰ƒbƒp)
*--------------------------------------*/
-void nullpo_info_f(const char *file, int line, const char *func,
- const char *fmt, ...)
+void nullpo_info_f(const char *file, int line, const char *func,
+ const char *fmt, ...)
{
- va_list ap;
-
- va_start(ap, fmt);
- nullpo_info_core(file, line, func, fmt, ap);
- va_end(ap);
+ va_list ap;
+
+ va_start(ap, fmt);
+ nullpo_info_core(file, line, func, fmt, ap);
+ va_end(ap);
}
void nullpo_info(const char *file, int line, const char *func)
{
- nullpo_info_core(file, line, func, NULL, NULL);
+ nullpo_info_core(file, line, func, NULL, NULL);
}
/*======================================
* nullpoî•ño—Í(Main)
*--------------------------------------*/
-static void nullpo_info_core(const char *file, int line, const char *func,
+static void nullpo_info_core(const char *file, int line, const char *func,
const char *fmt, va_list ap)
{
- if (file == NULL)
- file = "??";
-
- func =
- func == NULL ? "unknown":
- func[0] == '\0' ? "unknown":
- func;
-
- ShowMessage("--- nullpo info --------------------------------------------\n");
- ShowMessage("%s:%d: in func `%s'\n", file, line, func);
- if (fmt != NULL) {
- if (fmt[0] != '\0') {
- vprintf(fmt, ap);
-
- // ÅŒã‚ɉüs‚µ‚½‚©Šm”F
- if (fmt[strlen(fmt)-1] != '\n')
- ShowMessage("\n");
- }
- }
- ShowMessage("--- end nullpo info ----------------------------------------\n");
-
- // ‚±‚±‚ç‚ÅnullpoƒƒO‚ðƒtƒ@ƒCƒ‹‚É‘‚«o‚¹‚½‚ç
- // ‚Ü‚Æ‚ß‚Ä’ño‚Å‚«‚é‚È‚ÆŽv‚Á‚Ä‚¢‚½‚èB
+ if (file == NULL)
+ file = "??";
+
+ func =
+ func == NULL ? "unknown":
+ func[0] == '\0' ? "unknown":
+ func;
+
+ ShowMessage("--- nullpo info --------------------------------------------\n");
+ ShowMessage("%s:%d: in func `%s'\n", file, line, func);
+ if (fmt != NULL)
+ {
+ if (fmt[0] != '\0')
+ {
+ vprintf(fmt, ap);
+
+ // ÅŒã‚ɉüs‚µ‚½‚©Šm”F
+ if (fmt[strlen(fmt)-1] != '\n')
+ ShowMessage("\n");
+ }
+ }
+ ShowMessage("--- end nullpo info ----------------------------------------\n");
+
+ // ‚±‚±‚ç‚ÅnullpoƒƒO‚ðƒtƒ@ƒCƒ‹‚É‘‚«o‚¹‚½‚ç
+ // ‚Ü‚Æ‚ß‚Ä’ño‚Å‚«‚é‚È‚ÆŽv‚Á‚Ä‚¢‚½‚èB
}
diff --git a/src/common/nullpo.h b/src/common/nullpo.h
index 67679432f..8ee86a782 100644
--- a/src/common/nullpo.h
+++ b/src/common/nullpo.h
@@ -71,45 +71,45 @@
#if defined(NULLPO_CHECK)
#define nullpo_ret(t) \
- if (nullpo_chk(NLP_MARK, (void *)(t))) {return(0);}
+ if (nullpo_chk(NLP_MARK, (void *)(t))) {return(0);}
#define nullpo_retv(t) \
- if (nullpo_chk(NLP_MARK, (void *)(t))) {return;}
+ if (nullpo_chk(NLP_MARK, (void *)(t))) {return;}
#define nullpo_retr(ret, t) \
- if (nullpo_chk(NLP_MARK, (void *)(t))) {return(ret);}
+ if (nullpo_chk(NLP_MARK, (void *)(t))) {return(ret);}
#define nullpo_retb(t) \
- if (nullpo_chk(NLP_MARK, (void *)(t))) {break;}
+ if (nullpo_chk(NLP_MARK, (void *)(t))) {break;}
// ‰Â•Ïˆø”ƒ}ƒNƒ‚ÉŠÖ‚·‚éðŒƒRƒ“ƒpƒCƒ‹
#if __STDC_VERSION__ >= 199901L
/* C99‚ɑΉž */
#define nullpo_ret_f(t, fmt, ...) \
- if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), __VA_ARGS__)) {return(0);}
+ if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), __VA_ARGS__)) {return(0);}
#define nullpo_retv_f(t, fmt, ...) \
- if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), __VA_ARGS__)) {return;}
+ if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), __VA_ARGS__)) {return;}
#define nullpo_retr_f(ret, t, fmt, ...) \
- if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), __VA_ARGS__)) {return(ret);}
+ 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;}
+ if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), __VA_ARGS__)) {break;}
#elif __GNUC__ >= 2
/* GCC—p */
#define nullpo_ret_f(t, fmt, args...) \
- if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), ## args)) {return(0);}
+ if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), ## args)) {return(0);}
#define nullpo_retv_f(t, fmt, args...) \
- if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), ## args)) {return;}
+ if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), ## args)) {return;}
#define nullpo_retr_f(ret, t, fmt, args...) \
- if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), ## args)) {return(ret);}
+ 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;}
+ if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), ## args)) {break;}
#else
@@ -189,7 +189,7 @@ int nullpo_chk(const char *file, int line, const char *func, const void *target)
*/
int nullpo_chk_f(const char *file, int line, const char *func, const void *target,
const char *fmt, ...)
-__attribute__((format(printf,5,6)));
+ __attribute__((format(printf,5,6)));
/*======================================
@@ -217,9 +217,9 @@ void nullpo_info(const char *file, int line, const char *func);
* ”õl‚âŠÖŒW•Ï”‚Ì‘‚«o‚µ‚È‚Ç‚É
*--------------------------------------
*/
-void nullpo_info_f(const char *file, int line, const char *func,
+void nullpo_info_f(const char *file, int line, const char *func,
const char *fmt, ...)
-__attribute__((format(printf,4,5)));
+ __attribute__((format(printf,4,5)));
#endif /* _NULLPO_H_ */
diff --git a/src/common/raconf.c b/src/common/raconf.c
index e73154f50..2703560ff 100644
--- a/src/common/raconf.c
+++ b/src/common/raconf.c
@@ -1,7 +1,7 @@
-//
+//
// Athena style config parser
-// (would be better to have "one" implementation instead of .. 4 :)
-//
+// (would be better to have "one" implementation instead of .. 4 :)
+//
//
// Author: Florian Wilkemeyer <fw@f-ws.de>
//
@@ -25,571 +25,560 @@
#define VARNAME_LEN 64
struct raconf {
- DBMap *db;
+ DBMap *db;
};
-struct conf_value {
- int64 intval;
- bool bval;
- double floatval;
- size_t strval_len; // not includung \0
- char strval[16];
+struct conf_value{
+ int64 intval;
+ bool bval;
+ double floatval;
+ size_t strval_len; // not includung \0
+ char strval[16];
};
-static struct conf_value *makeValue(const char *key, char *val, size_t val_len) {
- struct conf_value *v;
- char *p;
- size_t sz;
-
- sz = sizeof(struct conf_value);
- if (val_len >= sizeof(v->strval))
- sz += (val_len - sizeof(v->strval) + 1);
-
- v = (struct conf_value *)aCalloc(1, sizeof(struct conf_value));
- if (v == NULL) {
- ShowFatalError("raconf: makeValue => Out of Memory while allocating new node.\n");
- return NULL;
- }
-
- memcpy(v->strval, val, val_len);
- v->strval[val_len+1] = '\0';
- v->strval_len = val_len;
-
-
- // Parse boolean value:
- if ((val_len == 4) && (strncmpi("true", val, 4) == 0))
- v->bval = true;
- else if ((val_len == 3) && (strncmpi("yes", val, 3) == 0))
- v->bval = true;
- else if ((val_len == 3) && (strncmpi("oui", val, 3) == 0))
- v->bval = true;
- else if ((val_len == 2) && (strncmpi("si", val, 2) == 0))
- v->bval = true;
- else if ((val_len == 2) && (strncmpi("ja", val, 2) == 0))
- v->bval = true;
- else if ((val_len == 1) && (*val == '1'))
- v->bval = true;
- else if ((val_len == 5) && (strncmpi("false", val, 5) == 0))
- v->bval = false;
- else if ((val_len == 2) && (strncmpi("no", val, 2) == 0))
- v->bval = false;
- else if ((val_len == 3) && (strncmpi("non", val, 3) == 0))
- v->bval = false;
- else if ((val_len == 2) && (strncmpi("no", val, 2) == 0))
- v->bval = false;
- else if ((val_len == 4) && (strncmpi("nein", val, 4) == 0))
- v->bval = false;
- else if ((val_len == 1) && (*val == '0'))
- v->bval = false;
- else
- v->bval = false; // assume false.
-
- // Parse number
- // Supported formats:
- // prefix: 0x hex .
- // postix: h for hex
- // b for bin (dual)
- if ((val_len >= 1 && (val[val_len] == 'h')) || (val_len >= 2 && (val[0] == '0' && val[1] == 'x'))) {//HEX!
- if (val[val_len] == 'h') {
- val[val_len]= '\0';
- v->intval = strtoull(val, NULL, 16);
- val[val_len] = 'h';
- } else
- v->intval = strtoull(&val[2], NULL, 16);
- } else if (val_len >= 1 && (val[val_len] == 'b')) { //BIN
- val[val_len] = '\0';
- v->intval = strtoull(val, NULL, 2);
- val[val_len] = 'b';
- } else if (*val >='0' && *val <= '9') { // begins with normal digit, so assume its dec.
- // is it float?
- bool is_float = false;
-
- for (p = val; *p != '\0'; p++) {
- if (*p == '.') {
- v->floatval = strtod(val, NULL);
- v->intval = (int64) v->floatval;
- is_float = true;
- break;
- }
- }
-
- if (is_float == false) {
- v->intval = strtoull(val, NULL, 10);
- v->floatval = (double) v->intval;
- }
- } else {
- // Everything else: lets use boolean for fallback
- if (v->bval == true)
- v->intval = 1;
- else
- v->intval = 0;
- }
-
- return v;
+static struct conf_value *makeValue(const char *key, char *val, size_t val_len){
+ struct conf_value *v;
+ char *p;
+ size_t sz;
+
+ sz = sizeof(struct conf_value);
+ if(val_len >= sizeof(v->strval))
+ sz += (val_len - sizeof(v->strval) + 1);
+
+ v = (struct conf_value*)aCalloc(1, sizeof(struct conf_value));
+ if(v == NULL){
+ ShowFatalError("raconf: makeValue => Out of Memory while allocating new node.\n");
+ return NULL;
+ }
+
+ memcpy(v->strval, val, val_len);
+ v->strval[val_len+1] = '\0';
+ v->strval_len = val_len;
+
+
+ // Parse boolean value:
+ if((val_len == 4) && (strncmpi("true", val, 4) == 0))
+ v->bval = true;
+ else if((val_len == 3) && (strncmpi("yes", val, 3) == 0))
+ v->bval = true;
+ else if((val_len == 3) && (strncmpi("oui", val, 3) == 0))
+ v->bval = true;
+ else if((val_len == 2) && (strncmpi("si", val, 2) == 0))
+ v->bval = true;
+ else if((val_len == 2) && (strncmpi("ja", val, 2) == 0))
+ v->bval = true;
+ else if((val_len == 1) && (*val == '1'))
+ v->bval = true;
+ else if((val_len == 5) && (strncmpi("false", val, 5) == 0))
+ v->bval = false;
+ else if((val_len == 2) && (strncmpi("no", val, 2) == 0))
+ v->bval = false;
+ else if((val_len == 3) && (strncmpi("non", val, 3) == 0))
+ v->bval = false;
+ else if((val_len == 2) && (strncmpi("no", val, 2) == 0))
+ v->bval = false;
+ else if((val_len == 4) && (strncmpi("nein", val, 4) == 0))
+ v->bval = false;
+ else if((val_len == 1) && (*val == '0'))
+ v->bval = false;
+ else
+ v->bval = false; // assume false.
+
+ // Parse number
+ // Supported formats:
+ // prefix: 0x hex .
+ // postix: h for hex
+ // b for bin (dual)
+ if( (val_len >= 1 && (val[val_len] == 'h')) || (val_len >= 2 && (val[0] == '0' && val[1] == 'x')) ){//HEX!
+ if(val[val_len] == 'h'){
+ val[val_len]= '\0';
+ v->intval = strtoull(val, NULL, 16);
+ val[val_len] = 'h';
+ }else
+ v->intval = strtoull(&val[2], NULL, 16);
+ }else if( val_len >= 1 && (val[val_len] == 'b') ){ //BIN
+ val[val_len] = '\0';
+ v->intval = strtoull(val, NULL, 2);
+ val[val_len] = 'b';
+ }else if( *val >='0' && *val <= '9'){ // begins with normal digit, so assume its dec.
+ // is it float?
+ bool is_float = false;
+
+ for(p = val; *p != '\0'; p++){
+ if(*p == '.'){
+ v->floatval = strtod(val, NULL);
+ v->intval = (int64) v->floatval;
+ is_float = true;
+ break;
+ }
+ }
+
+ if(is_float == false){
+ v->intval = strtoull(val, NULL, 10);
+ v->floatval = (double) v->intval;
+ }
+ }else{
+ // Everything else: lets use boolean for fallback
+ if(v->bval == true)
+ v->intval = 1;
+ else
+ v->intval = 0;
+ }
+
+ return v;
}//end: makeValue()
-static bool configParse(raconf inst, const char *fileName)
-{
- FILE *fp;
- char line[4096];
- char currentSection[SECTION_LEN];
- char *p;
- char c;
- int linecnt;
- size_t linelen;
- size_t currentSection_len;
-
- fp = fopen(fileName, "r");
- if (fp == NULL) {
- ShowError("configParse: cannot open '%s' for reading.\n", fileName);
- return false;
- }
-
-
- // Start with empty section:
- currentSection[0] = '\0';
- currentSection_len = 0;
-
- //
- linecnt = 0;
- while (1) {
- linecnt++;
-
- if (fgets(line, sizeof(line), fp) != line)
- break;
-
- linelen = strlen(line);
- p = line;
-
- // Skip whitespaces from beginning (space and tab)
- _line_begin_skip_whities:
- c = *p;
- if (c == ' ' || c == '\t') {
- p++;
- linelen--;
- goto _line_begin_skip_whities;
- }
-
- // Remove linebreaks as (cr or lf) and whitespaces from line end!
- _line_end_skip_whities_and_breaks:
- c = p[linelen-1];
- if (c == '\r' || c == '\n' || c == ' ' || c == '\t') {
- p[--linelen] = '\0';
- goto _line_end_skip_whities_and_breaks;
- }
-
- // Empty line?
- // or line starts with comment (commented out)?
- if (linelen == 0 || (p[0] == '/' && p[1] == '/') || p[0] == ';')
- continue;
-
- // Variable names can contain:
- // A-Za-z-_.0-9
- //
- // Sections start with [ .. ] (INI Style)
- //
- c = *p;
-
- // check what we have.. :)
- if (c == '[') { // got section!
- // Got Section!
- // Search for ]
- char *start = (p+1);
-
- while (1) {
- ++p;
- c = *p;
-
- if (c == '\0') {
- ShowError("Syntax Error: unterminated Section name in %s:%u (expected ']')\n", fileName, linecnt);
- fclose(fp);
- return false;
- } else if (c == ']') { // closing backet (section name termination)
- if ((p - start + 1) > (sizeof(currentSection))) {
- ShowError("Syntax Error: Section name in %s:%u is too large (max Supported length: %u chars)\n", fileName, linecnt, sizeof(currentSection)-1);
- fclose(fp);
- return false;
- }
-
- // Set section!
- *p = '\0'; // add termination here.
- memcpy(currentSection, start, (p-start)+1); // we'll copy \0, too! (we replaced the ] backet with \0.)
- currentSection_len = (p-start);
-
- break;
-
- } else if ((c >= '0' && c <= '9') || (c == '-') || (c == ' ') || (c == '_') || (c == '.') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
- // skip .. (allowed char / specifier)
- continue;
- } else {
- ShowError("Syntax Error: Invalid Character '%c' in %s:%u (offset %u) for Section name.\n", c, fileName, linecnt, (p-line));
- fclose(fp);
- return false;
- }
-
- }//endwhile: parse section name
-
-
- } else if ((c >= '0' && c <= '9') || (c == '-') || (c == '_') || (c == '.') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
- // Got variable!
- // Search for '=' or ':' wich termiantes the name
- char *start = p;
- char *valuestart = NULL;
- size_t start_len;
-
- while (1) {
- ++p;
- c = *p;
-
- if (c == '\0') {
- ShowError("Syntax Error: unterminated Variable name in %s:%u\n", fileName, linecnt);
- fclose(fp);
- return false;
- } else if ((c == '=') || (c == ':')) {
- // got name termination
-
- *p = '\0'; // Terminate it so (start) will hold the pointer to the name.
-
- break;
-
- } else if ((c >= '0' && c <= '9') || (c == '-') || (c == '_') || (c == '.') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
- // skip .. allowed char
- continue;
- } else {
- ShowError("Syntax Error: Invalid Character '%c' in %s:%u (offset %u) for Variable name.\n", c, fileName, linecnt, (p-line));
- fclose(fp);
- return false;
- }
-
- }//endwhile: parse var name
-
- start_len = (p-start);
- if (start_len >= VARNAME_LEN) {
- ShowError("%s:%u Variable length exceeds limit of %u Characters.\n", fileName, linecnt, VARNAME_LEN-1);
- fclose(fp);
- return false;
- } else if (start_len == 0) {
- ShowError("%s:%u Empty Variable name is not allowed.\n", fileName, linecnt);
- fclose(fp);
- return false;
- }
-
-
- valuestart = (p+1);
-
-
- // Skip whitespace from begin of value (tab and space)
- _skip_value_begin_whities:
- c = *valuestart;
- if (c == ' ' || c == '\t') {
- valuestart++;
- goto _skip_value_begin_whities;
- }
-
- // Scan for value termination,
- // wich can be \0 or comment start (// or ; (INI) )
- //
- p = valuestart;
- while (1) {
- c = *p;
- if (c == '\0') {
- // Terminated by line end.
- break;
- } else if (c == '/' && p[1] == '/') {
- // terminated by c++ style comment.
- *p = '\0';
- break;
- } else if (c == ';') {
- // terminated by ini style comment.
- *p = '\0';
- break;
- }
-
- p++;
- }//endwhile: search var value end.
-
-
- // Strip whitespaces from end of value.
- if (valuestart != p) { // not empty!
- p--;
- _strip_value_end_whities:
- c = *p;
- if (c == ' ' || c == '\t') {
- *p = '\0';
- p--;
- goto _strip_value_end_whities;
- }
- p++;
- }
-
-
- // Buildin Hook:
- if (stricmp(start, "import") == 0) {
- if (configParse(inst, valuestart) != true) {
- ShowError("%s:%u - Import of '%s' failed!\n", fileName, linecnt, valuestart);
- }
- } else {
- // put it to db.
- struct conf_value *v, *o;
- char key[(SECTION_LEN+VARNAME_LEN+1+1) ]; //+1 for delimiter, +1 for termination.
- size_t section_len;
-
- if (*currentSection == '\0') { // empty / none
- strncpy(key, "<unnamed>",9);
- section_len = 9;
- } else {
- strncpy(key, currentSection, currentSection_len);
- section_len = currentSection_len;
- }
-
- key[section_len] = '.'; // Delim
-
- strncpy(&key[section_len+1], start, start_len);
-
- key[section_len + start_len + 1] = '\0';
-
-
- v = makeValue(key, valuestart, (p-valuestart));
-
- // Try to get the old one before
- o = strdb_get(inst->db, key);
- if (o != NULL) {
- strdb_remove(inst->db, key);
- aFree(o); //
- }
-
- strdb_put(inst->db, key, v);
- }
-
-
- } else {
- ShowError("Syntax Error: unexpected Character '%c' in %s:%u (offset %u)\n", c, fileName, linecnt, (p-line));
- fclose(fp);
- return false;
- }
-
-
-
- }
-
-
-
- fclose(fp);
- return true;
+static bool configParse(raconf inst, const char *fileName){
+ FILE *fp;
+ char line[4096];
+ char currentSection[SECTION_LEN];
+ char *p;
+ char c;
+ int linecnt;
+ size_t linelen;
+ size_t currentSection_len;
+
+ fp = fopen(fileName, "r");
+ if(fp == NULL){
+ ShowError("configParse: cannot open '%s' for reading.\n", fileName);
+ return false;
+ }
+
+
+ // Start with empty section:
+ currentSection[0] = '\0';
+ currentSection_len = 0;
+
+ //
+ linecnt = 0;
+ while(1){
+ linecnt++;
+
+ if(fgets(line, sizeof(line), fp) != line)
+ break;
+
+ linelen = strlen(line);
+ p = line;
+
+ // Skip whitespaces from beginning (space and tab)
+ _line_begin_skip_whities:
+ c = *p;
+ if(c == ' ' || c == '\t'){
+ p++;
+ linelen--;
+ goto _line_begin_skip_whities;
+ }
+
+ // Remove linebreaks as (cr or lf) and whitespaces from line end!
+ _line_end_skip_whities_and_breaks:
+ c = p[linelen-1];
+ if(c == '\r' || c == '\n' || c == ' ' || c == '\t'){
+ p[--linelen] = '\0';
+ goto _line_end_skip_whities_and_breaks;
+ }
+
+ // Empty line?
+ // or line starts with comment (commented out)?
+ if(linelen == 0 || (p[0] == '/' && p[1] == '/') || p[0] == ';')
+ continue;
+
+ // Variable names can contain:
+ // A-Za-z-_.0-9
+ //
+ // Sections start with [ .. ] (INI Style)
+ //
+ c = *p;
+
+ // check what we have.. :)
+ if(c == '['){ // got section!
+ // Got Section!
+ // Search for ]
+ char *start = (p+1);
+
+ while(1){
+ ++p;
+ c = *p;
+
+ if(c == '\0'){
+ ShowError("Syntax Error: unterminated Section name in %s:%u (expected ']')\n", fileName, linecnt);
+ fclose(fp);
+ return false;
+ }else if(c == ']'){ // closing backet (section name termination)
+ if( (p - start + 1) > (sizeof(currentSection) ) ){
+ ShowError("Syntax Error: Section name in %s:%u is too large (max Supported length: %u chars)\n", fileName, linecnt, sizeof(currentSection)-1);
+ fclose(fp);
+ return false;
+ }
+
+ // Set section!
+ *p = '\0'; // add termination here.
+ memcpy(currentSection, start, (p-start)+1 ); // we'll copy \0, too! (we replaced the ] backet with \0.)
+ currentSection_len = (p-start);
+
+ break;
+
+ }else if( (c >= '0' && c <= '9') || (c == '-') || (c == ' ') || (c == '_') || (c == '.') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ){
+ // skip .. (allowed char / specifier)
+ continue;
+ }else{
+ ShowError("Syntax Error: Invalid Character '%c' in %s:%u (offset %u) for Section name.\n", c, fileName, linecnt, (p-line));
+ fclose(fp);
+ return false;
+ }
+
+ }//endwhile: parse section name
+
+
+ }else if( (c >= '0' && c <= '9') || (c == '-') || (c == '_') || (c == '.') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ){
+ // Got variable!
+ // Search for '=' or ':' wich termiantes the name
+ char *start = p;
+ char *valuestart = NULL;
+ size_t start_len;
+
+ while(1){
+ ++p;
+ c = *p;
+
+ if(c == '\0'){
+ ShowError("Syntax Error: unterminated Variable name in %s:%u\n", fileName, linecnt);
+ fclose(fp);
+ return false;
+ }else if( (c == '=') || (c == ':') ){
+ // got name termination
+
+ *p = '\0'; // Terminate it so (start) will hold the pointer to the name.
+
+ break;
+
+ }else if( (c >= '0' && c <= '9') || (c == '-') || (c == '_') || (c == '.') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ){
+ // skip .. allowed char
+ continue;
+ }else{
+ ShowError("Syntax Error: Invalid Character '%c' in %s:%u (offset %u) for Variable name.\n", c, fileName, linecnt, (p-line));
+ fclose(fp);
+ return false;
+ }
+
+ }//endwhile: parse var name
+
+ start_len = (p-start);
+ if(start_len >= VARNAME_LEN){
+ ShowError("%s:%u Variable length exceeds limit of %u Characters.\n", fileName, linecnt, VARNAME_LEN-1);
+ fclose(fp);
+ return false;
+ }else if(start_len == 0){
+ ShowError("%s:%u Empty Variable name is not allowed.\n", fileName, linecnt);
+ fclose(fp);
+ return false;
+ }
+
+
+ valuestart = (p+1);
+
+
+ // Skip whitespace from begin of value (tab and space)
+ _skip_value_begin_whities:
+ c = *valuestart;
+ if(c == ' ' || c == '\t'){
+ valuestart++;
+ goto _skip_value_begin_whities;
+ }
+
+ // Scan for value termination,
+ // wich can be \0 or comment start (// or ; (INI) )
+ //
+ p = valuestart;
+ while(1){
+ c = *p;
+ if(c == '\0'){
+ // Terminated by line end.
+ break;
+ }else if(c == '/' && p[1] == '/'){
+ // terminated by c++ style comment.
+ *p = '\0';
+ break;
+ }else if(c == ';'){
+ // terminated by ini style comment.
+ *p = '\0';
+ break;
+ }
+
+ p++;
+ }//endwhile: search var value end.
+
+
+ // Strip whitespaces from end of value.
+ if(valuestart != p){ // not empty!
+ p--;
+ _strip_value_end_whities:
+ c = *p;
+ if(c == ' ' || c == '\t'){
+ *p = '\0';
+ p--;
+ goto _strip_value_end_whities;
+ }
+ p++;
+ }
+
+
+ // Buildin Hook:
+ if( stricmp(start, "import") == 0){
+ if( configParse(inst, valuestart) != true){
+ ShowError("%s:%u - Import of '%s' failed!\n", fileName, linecnt, valuestart);
+ }
+ }else{
+ // put it to db.
+ struct conf_value *v, *o;
+ char key[ (SECTION_LEN+VARNAME_LEN+1+1) ]; //+1 for delimiter, +1 for termination.
+ size_t section_len;
+
+ if(*currentSection == '\0'){ // empty / none
+ strncpy(key, "<unnamed>",9);
+ section_len = 9;
+ }else{
+ strncpy(key, currentSection, currentSection_len);
+ section_len = currentSection_len;
+ }
+
+ key[section_len] = '.'; // Delim
+
+ strncpy(&key[section_len+1], start, start_len);
+
+ key[section_len + start_len + 1] = '\0';
+
+
+ v = makeValue(key, valuestart, (p-valuestart) );
+
+ // Try to get the old one before
+ o = strdb_get(inst->db, key);
+ if(o != NULL){
+ strdb_remove(inst->db, key);
+ aFree(o); //
+ }
+
+ strdb_put( inst->db, key, v);
+ }
+
+
+ }else{
+ ShowError("Syntax Error: unexpected Character '%c' in %s:%u (offset %u)\n", c, fileName, linecnt, (p-line) );
+ fclose(fp);
+ return false;
+ }
+
+
+
+ }
+
+
+
+ fclose(fp);
+ return true;
}//end: configParse()
#define MAKEKEY(dest, section, key) { size_t section_len, key_len; \
- if(section == NULL || *section == '\0'){ \
- strncpy(dest, "<unnamed>", 9); \
- section_len = 9; \
- }else{ \
- section_len = strlen(section); \
- strncpy(dest, section, section_len); \
- } \
- \
- dest[section_len] = '.'; \
- \
- key_len = strlen(key); \
- strncpy(&dest[section_len+1], key, key_len); \
- dest[section_len + key_len + 1] = '\0'; \
- }
-
-
-raconf raconf_parse(const char *file_name)
-{
- struct raconf *rc;
-
- rc = aCalloc(1, sizeof(struct raconf));
- if (rc == NULL) {
- ShowFatalError("raconf_parse: failed to allocate memory for new handle\n");
- return NULL;
- }
-
- rc->db = strdb_alloc(DB_OPT_BASE | DB_OPT_DUP_KEY, 98);
- //
-
- if (configParse(rc, file_name) != true) {
- ShowError("Failed to Parse Configuration file '%s'\n", file_name);
- }
-
- return rc;
+ if(section == NULL || *section == '\0'){ \
+ strncpy(dest, "<unnamed>", 9); \
+ section_len = 9; \
+ }else{ \
+ section_len = strlen(section); \
+ strncpy(dest, section, section_len); \
+ } \
+ \
+ dest[section_len] = '.'; \
+ \
+ key_len = strlen(key); \
+ strncpy(&dest[section_len+1], key, key_len); \
+ dest[section_len + key_len + 1] = '\0'; \
+ }
+
+
+raconf raconf_parse(const char *file_name){
+ struct raconf *rc;
+
+ rc = aCalloc(1, sizeof(struct raconf) );
+ if(rc == NULL){
+ ShowFatalError("raconf_parse: failed to allocate memory for new handle\n");
+ return NULL;
+ }
+
+ rc->db = strdb_alloc(DB_OPT_BASE | DB_OPT_DUP_KEY, 98);
+ //
+
+ if(configParse(rc, file_name) != true){
+ ShowError("Failed to Parse Configuration file '%s'\n", file_name);
+ }
+
+ return rc;
}//end: raconf_parse()
-void raconf_destroy(raconf rc)
-{
- DBIterator *iter;
- struct conf_value *v;
-
- // Clear all entrys in db.
- iter = db_iterator(rc->db);
- for (v = (struct conf_value *)dbi_first(iter); dbi_exists(iter); v = (struct conf_value *)dbi_next(iter)) {
- aFree(v);
- }
- dbi_destroy(iter);
-
- db_destroy(rc->db);
-
- aFree(rc);
-
+void raconf_destroy(raconf rc){
+ DBIterator *iter;
+ struct conf_value *v;
+
+ // Clear all entrys in db.
+ iter = db_iterator(rc->db);
+ for( v = (struct conf_value*)dbi_first(iter); dbi_exists(iter); v = (struct conf_value*)dbi_next(iter) ){
+ aFree(v);
+ }
+ dbi_destroy(iter);
+
+ db_destroy(rc->db);
+
+ aFree(rc);
+
}//end: raconf_destroy()
-bool raconf_getbool(raconf rc, const char *section, const char *key, bool _default)
-{
- char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1];
- struct conf_value *v;
-
- MAKEKEY(keystr, section, key);
-
- v = strdb_get(rc->db, keystr);
- if (v == NULL)
- return _default;
- else
- return v->bval;
+bool raconf_getbool(raconf rc, const char *section, const char *key, bool _default){
+ char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1];
+ struct conf_value *v;
+
+ MAKEKEY(keystr, section, key);
+
+ v = strdb_get(rc->db, keystr);
+ if(v == NULL)
+ return _default;
+ else
+ return v->bval;
}//end: raconf_getbool()
-float raconf_getfloat(raconf rc,const char *section, const char *key, float _default)
-{
- char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1];
- struct conf_value *v;
-
- MAKEKEY(keystr, section, key);
+float raconf_getfloat(raconf rc,const char *section, const char *key, float _default){
+ char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1];
+ struct conf_value *v;
+
+ MAKEKEY(keystr, section, key);
- v = strdb_get(rc->db, keystr);
- if (v == NULL)
- return _default;
- else
- return (float)v->floatval;
+ v = strdb_get(rc->db, keystr);
+ if(v == NULL)
+ return _default;
+ else
+ return (float)v->floatval;
}//end: raconf_getfloat()
-int64 raconf_getint(raconf rc, const char *section, const char *key, int64 _default)
-{
- char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1];
- struct conf_value *v;
-
- MAKEKEY(keystr, section, key);
-
- v = strdb_get(rc->db, keystr);
- if (v == NULL)
- return _default;
- else
- return v->intval;
+int64 raconf_getint(raconf rc, const char *section, const char *key, int64 _default){
+ char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1];
+ struct conf_value *v;
+
+ MAKEKEY(keystr, section, key);
+
+ v = strdb_get(rc->db, keystr);
+ if(v == NULL)
+ return _default;
+ else
+ return v->intval;
}//end: raconf_getint()
-const char *raconf_getstr(raconf rc, const char *section, const char *key, const char *_default)
-{
- char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1];
- struct conf_value *v;
+const char* raconf_getstr(raconf rc, const char *section, const char *key, const char *_default){
+ char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1];
+ struct conf_value *v;
- MAKEKEY(keystr, section, key);
+ MAKEKEY(keystr, section, key);
- v = strdb_get(rc->db, keystr);
- if (v == NULL)
- return _default;
- else
- return v->strval;
+ v = strdb_get(rc->db, keystr);
+ if(v == NULL)
+ return _default;
+ else
+ return v->strval;
}//end: raconf_getstr()
-bool raconf_getboolEx(raconf rc, const char *section, const char *fallback_section, const char *key, bool _default)
-{
- char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1];
- struct conf_value *v;
-
- MAKEKEY(keystr, section, key);
- v = strdb_get(rc->db, keystr);
- if (v == NULL) {
-
- MAKEKEY(keystr, fallback_section, key);
- v = strdb_get(rc->db, keystr);
- if (v == NULL) {
- return _default;
- } else {
- return v->bval;
- }
-
- } else {
- return v->bval;
- }
+bool raconf_getboolEx(raconf rc, const char *section, const char *fallback_section, const char *key, bool _default){
+ char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1];
+ struct conf_value *v;
+
+ MAKEKEY(keystr, section, key);
+ v = strdb_get(rc->db, keystr);
+ if(v == NULL){
+
+ MAKEKEY(keystr, fallback_section, key);
+ v = strdb_get(rc->db, keystr);
+ if(v == NULL){
+ return _default;
+ }else{
+ return v->bval;
+ }
+
+ }else{
+ return v->bval;
+ }
}//end: raconf_getboolEx()
-float raconf_getfloatEx(raconf rc,const char *section, const char *fallback_section, const char *key, float _default)
-{
- char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1];
- struct conf_value *v;
-
- MAKEKEY(keystr, section, key);
- v = strdb_get(rc->db, keystr);
- if (v == NULL) {
-
- MAKEKEY(keystr, fallback_section, key);
- v = strdb_get(rc->db, keystr);
- if (v == NULL) {
- return _default;
- } else {
- return (float)v->floatval;
- }
-
- } else {
- return (float)v->floatval;
- }
-
+float raconf_getfloatEx(raconf rc,const char *section, const char *fallback_section, const char *key, float _default){
+ char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1];
+ struct conf_value *v;
+
+ MAKEKEY(keystr, section, key);
+ v = strdb_get(rc->db, keystr);
+ if(v == NULL){
+
+ MAKEKEY(keystr, fallback_section, key);
+ v = strdb_get(rc->db, keystr);
+ if(v == NULL){
+ return _default;
+ }else{
+ return (float)v->floatval;
+ }
+
+ }else{
+ return (float)v->floatval;
+ }
+
}//end: raconf_getfloatEx()
-int64 raconf_getintEx(raconf rc, const char *section, const char *fallback_section, const char *key, int64 _default)
-{
- char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1];
- struct conf_value *v;
-
- MAKEKEY(keystr, section, key);
- v = strdb_get(rc->db, keystr);
- if (v == NULL) {
-
- MAKEKEY(keystr, fallback_section, key);
- v = strdb_get(rc->db, keystr);
- if (v == NULL) {
- return _default;
- } else {
- return v->intval;
- }
-
- } else {
- return v->intval;
- }
+int64 raconf_getintEx(raconf rc, const char *section, const char *fallback_section, const char *key, int64 _default){
+ char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1];
+ struct conf_value *v;
+
+ MAKEKEY(keystr, section, key);
+ v = strdb_get(rc->db, keystr);
+ if(v == NULL){
+
+ MAKEKEY(keystr, fallback_section, key);
+ v = strdb_get(rc->db, keystr);
+ if(v == NULL){
+ return _default;
+ }else{
+ return v->intval;
+ }
+
+ }else{
+ return v->intval;
+ }
}//end: raconf_getintEx()
-const char *raconf_getstrEx(raconf rc, const char *section, const char *fallback_section, const char *key, const char *_default)
-{
- char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1];
- struct conf_value *v;
-
- MAKEKEY(keystr, section, key);
- v = strdb_get(rc->db, keystr);
- if (v == NULL) {
-
- MAKEKEY(keystr, fallback_section, key);
- v = strdb_get(rc->db, keystr);
- if (v == NULL) {
- return _default;
- } else {
- return v->strval;
- }
-
- } else {
- return v->strval;
- }
+const char* raconf_getstrEx(raconf rc, const char *section, const char *fallback_section, const char *key, const char *_default){
+ char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1];
+ struct conf_value *v;
+
+ MAKEKEY(keystr, section, key);
+ v = strdb_get(rc->db, keystr);
+ if(v == NULL){
+
+ MAKEKEY(keystr, fallback_section, key);
+ v = strdb_get(rc->db, keystr);
+ if(v == NULL){
+ return _default;
+ }else{
+ return v->strval;
+ }
+
+ }else{
+ return v->strval;
+ }
}//end: raconf_getstrEx()
diff --git a/src/common/raconf.h b/src/common/raconf.h
index 242c585bb..68a2b51b2 100644
--- a/src/common/raconf.h
+++ b/src/common/raconf.h
@@ -7,52 +7,52 @@
#include "../common/cbasetypes.h"
// rAthena generic configuration file parser
+//
+// Config file Syntax is athena style
+// extended with ini style support (including sections)
//
-// Config file Syntax is athena style
-// extended with ini style support (including sections)
-//
-// Comments are started with // or ; (ini style)
+// Comments are started with // or ; (ini style)
//
typedef struct raconf *raconf;
-/**
+/**
* Parses a rAthna Configuration file
- *
+ *
* @param file_name path to the file to parse
*
* @returns not NULL incase of success
*/
-raconf raconf_parse(const char *file_name);
+raconf raconf_parse(const char *file_name);
-/**
+/**
* Frees a Handle received from raconf_parse
*
* @param rc - the handle to free
*/
-void raconf_destroy(raconf rc);
+void raconf_destroy(raconf rc);
-/**
- * Gets the value for Section / Key pair, if key not exists returns _default!
+/**
+ * Gets the value for Section / Key pair, if key not exists returns _default!
*
*/
-bool raconf_getbool(raconf rc, const char *section, const char *key, bool _default);
-float raconf_getfloat(raconf rc,const char *section, const char *key, float _default);
-int64 raconf_getint(raconf rc, const char *section, const char *key, int64 _default);
-const char *raconf_getstr(raconf rc, const char *section, const char *key, const char *_default);
+bool raconf_getbool(raconf rc, const char *section, const char *key, bool _default);
+float raconf_getfloat(raconf rc,const char *section, const char *key, float _default);
+int64 raconf_getint(raconf rc, const char *section, const char *key, int64 _default);
+const char* raconf_getstr(raconf rc, const char *section, const char *key, const char *_default);
/**
- * Gets the value for Section / Key pair, but has fallback section option if not found in section,
+ * Gets the value for Section / Key pair, but has fallback section option if not found in section,
* if not found in both - default gets returned.
*
*/
bool raconf_getboolEx(raconf rc, const char *section, const char *fallback_section, const char *key, bool _default);
float raconf_getfloatEx(raconf rc,const char *section, const char *fallback_section, const char *key, float _default);
int64 raconf_getintEx(raconf rc, const char *section, const char *fallback_section, const char *key, int64 _default);
-const char *raconf_getstrEx(raconf rc, const char *section, const char *fallback_section, const char *key, const char *_default);
+const char* raconf_getstrEx(raconf rc, const char *section, const char *fallback_section, const char *key, const char *_default);
diff --git a/src/common/random.c b/src/common/random.c
index ab9b0052f..5c048c7eb 100644
--- a/src/common/random.c
+++ b/src/common/random.c
@@ -5,10 +5,10 @@
#include "../common/timer.h" // gettick
#include "random.h"
#if defined(WIN32)
-#include "../common/winapi.h"
+ #include "../common/winapi.h"
#elif defined(HAVE_GETPID) || defined(HAVE_GETTID)
-#include <sys/types.h>
-#include <unistd.h>
+ #include <sys/types.h>
+ #include <unistd.h>
#endif
#include <time.h> // time
#include <mt19937ar.h> // init_genrand, genrand_int32, genrand_res53
@@ -17,34 +17,34 @@
/// Initializes the random number generator with an appropriate seed.
void rnd_init(void)
{
- uint32 seed = gettick();
- seed += (uint32)time(NULL);
+ uint32 seed = gettick();
+ seed += (uint32)time(NULL);
#if defined(WIN32)
- seed += GetCurrentProcessId();
- seed += GetCurrentThreadId();
+ seed += GetCurrentProcessId();
+ seed += GetCurrentThreadId();
#else
#if defined(HAVE_GETPID)
- seed += (uint32)getpid();
+ seed += (uint32)getpid();
#endif // HAVE_GETPID
#if defined(HAVE_GETTID)
- seed += (uint32)gettid();
+ seed += (uint32)gettid();
#endif // HAVE_GETTID
#endif
- init_genrand(seed);
+ init_genrand(seed);
}
/// Initializes the random number generator.
void rnd_seed(uint32 seed)
{
- init_genrand(seed);
+ init_genrand(seed);
}
/// Generates a random number in the interval [0, SINT32_MAX]
int32 rnd(void)
{
- return (int32)genrand_int31();
+ return (int32)genrand_int31();
}
@@ -52,7 +52,7 @@ int32 rnd(void)
/// NOTE: interval is open ended, so dice_faces is excluded (unless it's 0)
uint32 rnd_roll(uint32 dice_faces)
{
- return (uint32)(rnd_uniform()*dice_faces);
+ return (uint32)(rnd_uniform()*dice_faces);
}
@@ -60,9 +60,9 @@ uint32 rnd_roll(uint32 dice_faces)
/// Returns min if range is invalid.
int32 rnd_value(int32 min, int32 max)
{
- if (min >= max)
- return min;
- return min + (int32)(rnd_uniform()*(max-min+1));
+ if( min >= max )
+ return min;
+ return min + (int32)(rnd_uniform()*(max-min+1));
}
@@ -70,7 +70,7 @@ int32 rnd_value(int32 min, int32 max)
/// NOTE: interval is open ended, so 1.0 is excluded
double rnd_uniform(void)
{
- return ((uint32)genrand_int32())*(1.0/4294967296.0);// divided by 2^32
+ return ((uint32)genrand_int32())*(1.0/4294967296.0);// divided by 2^32
}
@@ -79,5 +79,5 @@ double rnd_uniform(void)
/// NOTE: 53 bits is the maximum precision of a double
double rnd_uniform53(void)
{
- return genrand_res53();
+ return genrand_res53();
}
diff --git a/src/common/showmsg.c b/src/common/showmsg.c
index cfa1587e5..609ae3c50 100644
--- a/src/common/showmsg.c
+++ b/src/common/showmsg.c
@@ -15,33 +15,33 @@
#include "libconfig.h"
#ifdef WIN32
-#include "../common/winapi.h"
-
-#ifdef DEBUGLOGMAP
-#define DEBUGLOGPATH "log\\map-server.log"
-#else
-#ifdef DEBUGLOGCHAR
-#define DEBUGLOGPATH "log\\char-server.log"
-#else
-#ifdef DEBUGLOGLOGIN
-#define DEBUGLOGPATH "log\\login-server.log"
-#endif
-#endif
-#endif
+ #include "../common/winapi.h"
+
+ #ifdef DEBUGLOGMAP
+ #define DEBUGLOGPATH "log\\map-server.log"
+ #else
+ #ifdef DEBUGLOGCHAR
+ #define DEBUGLOGPATH "log\\char-server.log"
+ #else
+ #ifdef DEBUGLOGLOGIN
+ #define DEBUGLOGPATH "log\\login-server.log"
+ #endif
+ #endif
+ #endif
#else
-#include <unistd.h>
-
-#ifdef DEBUGLOGMAP
-#define DEBUGLOGPATH "log/map-server.log"
-#else
-#ifdef DEBUGLOGCHAR
-#define DEBUGLOGPATH "log/char-server.log"
-#else
-#ifdef DEBUGLOGLOGIN
-#define DEBUGLOGPATH "log/login-server.log"
-#endif
-#endif
-#endif
+ #include <unistd.h>
+
+ #ifdef DEBUGLOGMAP
+ #define DEBUGLOGPATH "log/map-server.log"
+ #else
+ #ifdef DEBUGLOGCHAR
+ #define DEBUGLOGPATH "log/char-server.log"
+ #else
+ #ifdef DEBUGLOGLOGIN
+ #define DEBUGLOGPATH "log/login-server.log"
+ #endif
+ #endif
+ #endif
#endif
///////////////////////////////////////////////////////////////////////////////
@@ -60,41 +60,41 @@ int console_msg_log = 0;//[Ind] msg error logging
#define SBUF_SIZE 2054 // never put less that what's required for the debug message
-#define NEWBUF(buf) \
- struct { \
- char s_[SBUF_SIZE]; \
- StringBuf *d_; \
- char *v_; \
- int l_; \
- } buf ={"",NULL,NULL,0}; \
- //define NEWBUF
-
-#define BUFVPRINTF(buf,fmt,args) \
- buf.l_ = vsnprintf(buf.s_, SBUF_SIZE, fmt, args); \
- if( buf.l_ >= 0 && buf.l_ < SBUF_SIZE ) \
- {/* static buffer */ \
- buf.v_ = buf.s_; \
- } \
- else \
- {/* dynamic buffer */ \
- buf.d_ = StringBuf_Malloc(); \
- buf.l_ = StringBuf_Vprintf(buf.d_, fmt, args); \
- buf.v_ = StringBuf_Value(buf.d_); \
- ShowDebug("showmsg: dynamic buffer used, increase the static buffer size to %d or more.\n", buf.l_+1);\
- } \
- //define BUFVPRINTF
+#define NEWBUF(buf) \
+ struct { \
+ char s_[SBUF_SIZE]; \
+ StringBuf *d_; \
+ char *v_; \
+ int l_; \
+ } buf ={"",NULL,NULL,0}; \
+//define NEWBUF
+
+#define BUFVPRINTF(buf,fmt,args) \
+ buf.l_ = vsnprintf(buf.s_, SBUF_SIZE, fmt, args); \
+ if( buf.l_ >= 0 && buf.l_ < SBUF_SIZE ) \
+ {/* static buffer */ \
+ buf.v_ = buf.s_; \
+ } \
+ else \
+ {/* dynamic buffer */ \
+ buf.d_ = StringBuf_Malloc(); \
+ buf.l_ = StringBuf_Vprintf(buf.d_, fmt, args); \
+ buf.v_ = StringBuf_Value(buf.d_); \
+ ShowDebug("showmsg: dynamic buffer used, increase the static buffer size to %d or more.\n", buf.l_+1);\
+ } \
+//define BUFVPRINTF
#define BUFVAL(buf) buf.v_
#define BUFLEN(buf) buf.l_
-#define FREEBUF(buf) \
- if( buf.d_ ) \
- { \
- StringBuf_Free(buf.d_); \
- buf.d_ = NULL; \
- } \
- buf.v_ = NULL; \
- //define FREEBUF
+#define FREEBUF(buf) \
+ if( buf.d_ ) \
+ { \
+ StringBuf_Free(buf.d_); \
+ buf.d_ = NULL; \
+ } \
+ buf.v_ = NULL; \
+//define FREEBUF
///////////////////////////////////////////////////////////////////////////////
#ifdef _WIN32
@@ -104,38 +104,38 @@ int console_msg_log = 0;//[Ind] msg error logging
// ansi compatible printf with control sequence parser for windows
// fast hack, handle with care, not everything implemented
//
-// \033[#;...;#m - Set Graphics Rendition (SGR)
+// \033[#;...;#m - Set Graphics Rendition (SGR)
//
-// printf("\x1b[1;31;40m"); // Bright red on black
-// printf("\x1b[3;33;45m"); // Blinking yellow on magenta (blink not implemented)
-// printf("\x1b[1;30;47m"); // Bright black (grey) on dim white
+// printf("\x1b[1;31;40m"); // Bright red on black
+// printf("\x1b[3;33;45m"); // Blinking yellow on magenta (blink not implemented)
+// printf("\x1b[1;30;47m"); // Bright black (grey) on dim white
//
// Style Foreground Background
-// 1st Digit 2nd Digit 3rd Digit RGB
-// 0 - Reset 30 - Black 40 - Black 000
-// 1 - FG Bright 31 - Red 41 - Red 100
-// 2 - Unknown 32 - Green 42 - Green 010
-// 3 - Blink 33 - Yellow 43 - Yellow 110
-// 4 - Underline 34 - Blue 44 - Blue 001
-// 5 - BG Bright 35 - Magenta 45 - Magenta 101
-// 6 - Unknown 36 - Cyan 46 - Cyan 011
-// 7 - Reverse 37 - White 47 - White 111
+// 1st Digit 2nd Digit 3rd Digit RGB
+// 0 - Reset 30 - Black 40 - Black 000
+// 1 - FG Bright 31 - Red 41 - Red 100
+// 2 - Unknown 32 - Green 42 - Green 010
+// 3 - Blink 33 - Yellow 43 - Yellow 110
+// 4 - Underline 34 - Blue 44 - Blue 001
+// 5 - BG Bright 35 - Magenta 45 - Magenta 101
+// 6 - Unknown 36 - Cyan 46 - Cyan 011
+// 7 - Reverse 37 - White 47 - White 111
// 8 - Concealed (invisible)
//
// \033[#A - Cursor Up (CUU)
-// Moves the cursor up by the specified number of lines without changing columns.
+// Moves the cursor up by the specified number of lines without changing columns.
// If the cursor is already on the top line, this sequence is ignored. \e[A is equivalent to \e[1A.
//
// \033[#B - Cursor Down (CUD)
-// Moves the cursor down by the specified number of lines without changing columns.
+// Moves the cursor down by the specified number of lines without changing columns.
// If the cursor is already on the bottom line, this sequence is ignored. \e[B is equivalent to \e[1B.
//
// \033[#C - Cursor Forward (CUF)
-// Moves the cursor forward by the specified number of columns without changing lines.
+// Moves the cursor forward by the specified number of columns without changing lines.
// If the cursor is already in the rightmost column, this sequence is ignored. \e[C is equivalent to \e[1C.
//
// \033[#D - Cursor Backward (CUB)
-// Moves the cursor back by the specified number of columns without changing lines.
+// Moves the cursor back by the specified number of columns without changing lines.
// If the cursor is already in the leftmost column, this sequence is ignored. \e[D is equivalent to \e[1D.
//
// \033[#E - Cursor Next Line (CNL)
@@ -148,15 +148,15 @@ int console_msg_log = 0;//[Ind] msg error logging
// Moves the cursor to indicated column in current row. \e[G is equivalent to \e[1G.
//
// \033[#;#H - Cursor Position (CUP)
-// Moves the cursor to the specified position. The first # specifies the line number,
-// the second # specifies the column. If you do not specify a position, the cursor moves to the home position:
+// Moves the cursor to the specified position. The first # specifies the line number,
+// the second # specifies the column. If you do not specify a position, the cursor moves to the home position:
// the upper-left corner of the screen (line 1, column 1).
//
// \033[#;#f - Horizontal & Vertical Position
// (same as \033[#;#H)
//
// \033[s - Save Cursor Position (SCP)
-// The current cursor position is saved.
+// The current cursor position is saved.
//
// \033[u - Restore cursor position (RCP)
// Restores the cursor position saved with the (SCP) sequence \033[s.
@@ -194,295 +194,331 @@ Escape sequences for Select Character Set
#define is_console(handle) (FILE_TYPE_CHAR==GetFileType(handle))
///////////////////////////////////////////////////////////////////////////////
-int VFPRINTF(HANDLE handle, const char *fmt, va_list argptr)
+int VFPRINTF(HANDLE handle, const char *fmt, va_list argptr)
{
- /////////////////////////////////////////////////////////////////
- /* XXX Two streams are being used. Disabled to avoid inconsistency [flaviojs]
- static COORD saveposition = {0,0};
- */
-
- /////////////////////////////////////////////////////////////////
- DWORD written;
- char *p, *q;
- NEWBUF(tempbuf); // temporary buffer
-
- if (!fmt || !*fmt)
- return 0;
-
- // Print everything to the buffer
- BUFVPRINTF(tempbuf,fmt,argptr);
-
- if (!is_console(handle) && stdout_with_ansisequence) {
- WriteFile(handle, BUFVAL(tempbuf), BUFLEN(tempbuf), &written, 0);
- return 0;
- }
-
- // start with processing
- p = BUFVAL(tempbuf);
- while ((q = strchr(p, 0x1b)) != NULL) {
- // find the escape character
- if (0==WriteConsole(handle, p, (DWORD)(q-p), &written, 0)) // write up to the escape
- WriteFile(handle, p, (DWORD)(q-p), &written, 0);
-
- if (q[1]!='[') {
- // write the escape char (whatever purpose it has)
- if (0==WriteConsole(handle, q, 1, &written, 0))
- WriteFile(handle,q, 1, &written, 0);
- p=q+1; //and start searching again
- } else {
- // from here, we will skip the '\033['
- // we break at the first unprocessible position
- // assuming regular text is starting there
- uint8 numbers[16], numpoint=0;
- CONSOLE_SCREEN_BUFFER_INFO info;
-
- // initialize
- GetConsoleScreenBufferInfo(handle, &info);
- memset(numbers,0,sizeof(numbers));
-
- // skip escape and bracket
- q=q+2;
- for (;;) {
- if (ISDIGIT(*q)) {
- // add number to number array, only accept 2digits, shift out the rest
- // so // \033[123456789m will become \033[89m
- numbers[numpoint] = (numbers[numpoint]<<4) | (*q-'0');
- ++q;
- // and next character
- continue;
- } else if (*q == ';') {
- // delimiter
- if (numpoint<sizeof(numbers)/sizeof(*numbers)) {
- // go to next array position
- numpoint++;
- } else {
- // array is full, so we 'forget' the first value
- memmove(numbers,numbers+1,sizeof(numbers)/sizeof(*numbers)-1);
- numbers[sizeof(numbers)/sizeof(*numbers)-1]=0;
- }
- ++q;
- // and next number
- continue;
- } else if (*q == 'm') {
- // \033[#;...;#m - Set Graphics Rendition (SGR)
- uint8 i;
- for (i=0; i<= numpoint; ++i) {
- if (0x00 == (0xF0 & numbers[i])) {
- // upper nibble 0
- if (0 == numbers[i]) {
- // reset
- info.wAttributes = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
- } else if (1==numbers[i]) {
- // set foreground intensity
- info.wAttributes |= FOREGROUND_INTENSITY;
- } else if (5==numbers[i]) {
- // set background intensity
- info.wAttributes |= BACKGROUND_INTENSITY;
- } else if (7==numbers[i]) {
- // reverse colors (just xor them)
- info.wAttributes ^= FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE |
- BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE;
- }
- //case '2': // not existing
- //case '3': // blinking (not implemented)
- //case '4': // unterline (not implemented)
- //case '6': // not existing
- //case '8': // concealed (not implemented)
- //case '9': // not existing
- } else if (0x20 == (0xF0 & numbers[i])) {
- // off
-
- if (1==numbers[i]) {
- // set foreground intensity off
- info.wAttributes &= ~FOREGROUND_INTENSITY;
- } else if (5==numbers[i]) {
- // set background intensity off
- info.wAttributes &= ~BACKGROUND_INTENSITY;
- } else if (7==numbers[i]) {
- // reverse colors (just xor them)
- info.wAttributes ^= FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE |
- BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE;
- }
- } else if (0x30 == (0xF0 & numbers[i])) {
- // foreground
- uint8 num = numbers[i]&0x0F;
- if (num==9) info.wAttributes |= FOREGROUND_INTENSITY;
- if (num>7) num=7; // set white for 37, 38 and 39
- info.wAttributes &= ~(FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
- if ((num & 0x01)>0) // lowest bit set = red
- info.wAttributes |= FOREGROUND_RED;
- if ((num & 0x02)>0) // second bit set = green
- info.wAttributes |= FOREGROUND_GREEN;
- if ((num & 0x04)>0) // third bit set = blue
- info.wAttributes |= FOREGROUND_BLUE;
- } else if (0x40 == (0xF0 & numbers[i])) {
- // background
- uint8 num = numbers[i]&0x0F;
- if (num==9) info.wAttributes |= BACKGROUND_INTENSITY;
- if (num>7) num=7; // set white for 47, 48 and 49
- info.wAttributes &= ~(BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE);
- if ((num & 0x01)>0) // lowest bit set = red
- info.wAttributes |= BACKGROUND_RED;
- if ((num & 0x02)>0) // second bit set = green
- info.wAttributes |= BACKGROUND_GREEN;
- if ((num & 0x04)>0) // third bit set = blue
- info.wAttributes |= BACKGROUND_BLUE;
- }
- }
- // set the attributes
- SetConsoleTextAttribute(handle, info.wAttributes);
- } else if (*q=='J') {
- // \033[#J - Erase Display (ED)
- // \033[0J - Clears the screen from cursor to end of display. The cursor position is unchanged.
- // \033[1J - Clears the screen from start to cursor. The cursor position is unchanged.
- // \033[2J - Clears the screen and moves the cursor to the home position (line 1, column 1).
- uint8 num = (numbers[numpoint]>>4)*10+(numbers[numpoint]&0x0F);
- int cnt;
- DWORD tmp;
- COORD origin = {0,0};
- if (num==1) {
- // chars from start up to and including cursor
- cnt = info.dwSize.X * info.dwCursorPosition.Y + info.dwCursorPosition.X + 1;
- } else if (num==2) {
- // Number of chars on screen.
- cnt = info.dwSize.X * info.dwSize.Y;
- SetConsoleCursorPosition(handle, origin);
- } else { // 0 and default
- // number of chars from cursor to end
- origin = info.dwCursorPosition;
- cnt = info.dwSize.X * (info.dwSize.Y - info.dwCursorPosition.Y) - info.dwCursorPosition.X;
- }
- FillConsoleOutputAttribute(handle, info.wAttributes, cnt, origin, &tmp);
- FillConsoleOutputCharacter(handle, ' ', cnt, origin, &tmp);
- } else if (*q=='K') {
- // \033[K : clear line from actual position to end of the line
- // \033[0K - Clears all characters from the cursor position to the end of the line.
- // \033[1K - Clears all characters from start of line to the cursor position.
- // \033[2K - Clears all characters of the whole line.
-
- uint8 num = (numbers[numpoint]>>4)*10+(numbers[numpoint]&0x0F);
- COORD origin = {0,info.dwCursorPosition.Y}; //warning C4204
- SHORT cnt;
- DWORD tmp;
- if (num==1) {
- cnt = info.dwCursorPosition.X + 1;
- } else if (num==2) {
- cnt = info.dwSize.X;
- } else { // 0 and default
- origin = info.dwCursorPosition;
- cnt = info.dwSize.X - info.dwCursorPosition.X; // how many spaces until line is full
- }
- FillConsoleOutputAttribute(handle, info.wAttributes, cnt, origin, &tmp);
- FillConsoleOutputCharacter(handle, ' ', cnt, origin, &tmp);
- } else if (*q == 'H' || *q == 'f') {
- // \033[#;#H - Cursor Position (CUP)
- // \033[#;#f - Horizontal & Vertical Position
- // The first # specifies the line number, the second # specifies the column.
- // The default for both is 1
- info.dwCursorPosition.X = (numbers[numpoint])?(numbers[numpoint]>>4)*10+((numbers[numpoint]&0x0F)-1):0;
- info.dwCursorPosition.Y = (numpoint && numbers[numpoint-1])?(numbers[numpoint-1]>>4)*10+((numbers[numpoint-1]&0x0F)-1):0;
-
- if (info.dwCursorPosition.X >= info.dwSize.X) info.dwCursorPosition.Y = info.dwSize.X-1;
- if (info.dwCursorPosition.Y >= info.dwSize.Y) info.dwCursorPosition.Y = info.dwSize.Y-1;
- SetConsoleCursorPosition(handle, info.dwCursorPosition);
- } else if (*q=='s') {
- // \033[s - Save Cursor Position (SCP)
- /* XXX Two streams are being used. Disabled to avoid inconsistency [flaviojs]
- CONSOLE_SCREEN_BUFFER_INFO info;
- GetConsoleScreenBufferInfo(handle, &info);
- saveposition = info.dwCursorPosition;
- */
- } else if (*q=='u') {
- // \033[u - Restore cursor position (RCP)
- /* XXX Two streams are being used. Disabled to avoid inconsistency [flaviojs]
- SetConsoleCursorPosition(handle, saveposition);
- */
- } else if (*q == 'A') {
- // \033[#A - Cursor Up (CUU)
- // Moves the cursor UP # number of lines
- info.dwCursorPosition.Y -= (numbers[numpoint])?(numbers[numpoint]>>4)*10+(numbers[numpoint]&0x0F):1;
-
- if (info.dwCursorPosition.Y < 0)
- info.dwCursorPosition.Y = 0;
- SetConsoleCursorPosition(handle, info.dwCursorPosition);
- } else if (*q == 'B') {
- // \033[#B - Cursor Down (CUD)
- // Moves the cursor DOWN # number of lines
- info.dwCursorPosition.Y += (numbers[numpoint])?(numbers[numpoint]>>4)*10+(numbers[numpoint]&0x0F):1;
-
- if (info.dwCursorPosition.Y >= info.dwSize.Y)
- info.dwCursorPosition.Y = info.dwSize.Y-1;
- SetConsoleCursorPosition(handle, info.dwCursorPosition);
- } else if (*q == 'C') {
- // \033[#C - Cursor Forward (CUF)
- // Moves the cursor RIGHT # number of columns
- info.dwCursorPosition.X += (numbers[numpoint])?(numbers[numpoint]>>4)*10+(numbers[numpoint]&0x0F):1;
-
- if (info.dwCursorPosition.X >= info.dwSize.X)
- info.dwCursorPosition.X = info.dwSize.X-1;
- SetConsoleCursorPosition(handle, info.dwCursorPosition);
- } else if (*q == 'D') {
- // \033[#D - Cursor Backward (CUB)
- // Moves the cursor LEFT # number of columns
- info.dwCursorPosition.X -= (numbers[numpoint])?(numbers[numpoint]>>4)*10+(numbers[numpoint]&0x0F):1;
-
- if (info.dwCursorPosition.X < 0)
- info.dwCursorPosition.X = 0;
- SetConsoleCursorPosition(handle, info.dwCursorPosition);
- } else if (*q == 'E') {
- // \033[#E - Cursor Next Line (CNL)
- // Moves the cursor down the indicated # of rows, to column 1
- info.dwCursorPosition.Y += (numbers[numpoint])?(numbers[numpoint]>>4)*10+(numbers[numpoint]&0x0F):1;
- info.dwCursorPosition.X = 0;
-
- if (info.dwCursorPosition.Y >= info.dwSize.Y)
- info.dwCursorPosition.Y = info.dwSize.Y-1;
- SetConsoleCursorPosition(handle, info.dwCursorPosition);
- } else if (*q == 'F') {
- // \033[#F - Cursor Preceding Line (CPL)
- // Moves the cursor up the indicated # of rows, to column 1.
- info.dwCursorPosition.Y -= (numbers[numpoint])?(numbers[numpoint]>>4)*10+(numbers[numpoint]&0x0F):1;
- info.dwCursorPosition.X = 0;
-
- if (info.dwCursorPosition.Y < 0)
- info.dwCursorPosition.Y = 0;
- SetConsoleCursorPosition(handle, info.dwCursorPosition);
- } else if (*q == 'G') {
- // \033[#G - Cursor Horizontal Absolute (CHA)
- // Moves the cursor to indicated column in current row.
- info.dwCursorPosition.X = (numbers[numpoint])?(numbers[numpoint]>>4)*10+((numbers[numpoint]&0x0F)-1):0;
-
- if (info.dwCursorPosition.X >= info.dwSize.X)
- info.dwCursorPosition.X = info.dwSize.X-1;
- SetConsoleCursorPosition(handle, info.dwCursorPosition);
- } else if (*q == 'L' || *q == 'M' || *q == '@' || *q == 'P') {
- // not implemented, just skip
- } else {
- // no number nor valid sequencer
- // something is fishy, we break and give the current char free
- --q;
- }
- // skip the sequencer and search again
- p = q+1;
- break;
- }// end while
- }
- }
- if (*p) // write the rest of the buffer
- if (0==WriteConsole(handle, p, (DWORD)strlen(p), &written, 0))
- WriteFile(handle, p, (DWORD)strlen(p), &written, 0);
- FREEBUF(tempbuf);
- return 0;
+ /////////////////////////////////////////////////////////////////
+ /* XXX Two streams are being used. Disabled to avoid inconsistency [flaviojs]
+ static COORD saveposition = {0,0};
+ */
+
+ /////////////////////////////////////////////////////////////////
+ DWORD written;
+ char *p, *q;
+ NEWBUF(tempbuf); // temporary buffer
+
+ if(!fmt || !*fmt)
+ return 0;
+
+ // Print everything to the buffer
+ BUFVPRINTF(tempbuf,fmt,argptr);
+
+ if( !is_console(handle) && stdout_with_ansisequence )
+ {
+ WriteFile(handle, BUFVAL(tempbuf), BUFLEN(tempbuf), &written, 0);
+ return 0;
+ }
+
+ // start with processing
+ p = BUFVAL(tempbuf);
+ while ((q = strchr(p, 0x1b)) != NULL)
+ { // find the escape character
+ if( 0==WriteConsole(handle, p, (DWORD)(q-p), &written, 0) ) // write up to the escape
+ WriteFile(handle, p, (DWORD)(q-p), &written, 0);
+
+ if( q[1]!='[' )
+ { // write the escape char (whatever purpose it has)
+ if(0==WriteConsole(handle, q, 1, &written, 0) )
+ WriteFile(handle,q, 1, &written, 0);
+ p=q+1; //and start searching again
+ }
+ else
+ { // from here, we will skip the '\033['
+ // we break at the first unprocessible position
+ // assuming regular text is starting there
+ uint8 numbers[16], numpoint=0;
+ CONSOLE_SCREEN_BUFFER_INFO info;
+
+ // initialize
+ GetConsoleScreenBufferInfo(handle, &info);
+ memset(numbers,0,sizeof(numbers));
+
+ // skip escape and bracket
+ q=q+2;
+ for(;;)
+ {
+ if( ISDIGIT(*q) )
+ { // add number to number array, only accept 2digits, shift out the rest
+ // so // \033[123456789m will become \033[89m
+ numbers[numpoint] = (numbers[numpoint]<<4) | (*q-'0');
+ ++q;
+ // and next character
+ continue;
+ }
+ else if( *q == ';' )
+ { // delimiter
+ if(numpoint<sizeof(numbers)/sizeof(*numbers))
+ { // go to next array position
+ numpoint++;
+ }
+ else
+ { // array is full, so we 'forget' the first value
+ memmove(numbers,numbers+1,sizeof(numbers)/sizeof(*numbers)-1);
+ numbers[sizeof(numbers)/sizeof(*numbers)-1]=0;
+ }
+ ++q;
+ // and next number
+ continue;
+ }
+ else if( *q == 'm' )
+ { // \033[#;...;#m - Set Graphics Rendition (SGR)
+ uint8 i;
+ for(i=0; i<= numpoint; ++i)
+ {
+ if( 0x00 == (0xF0 & numbers[i]) )
+ { // upper nibble 0
+ if( 0 == numbers[i] )
+ { // reset
+ info.wAttributes = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
+ }
+ else if( 1==numbers[i] )
+ { // set foreground intensity
+ info.wAttributes |= FOREGROUND_INTENSITY;
+ }
+ else if( 5==numbers[i] )
+ { // set background intensity
+ info.wAttributes |= BACKGROUND_INTENSITY;
+ }
+ else if( 7==numbers[i] )
+ { // reverse colors (just xor them)
+ info.wAttributes ^= FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE |
+ BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE;
+ }
+ //case '2': // not existing
+ //case '3': // blinking (not implemented)
+ //case '4': // unterline (not implemented)
+ //case '6': // not existing
+ //case '8': // concealed (not implemented)
+ //case '9': // not existing
+ }
+ else if( 0x20 == (0xF0 & numbers[i]) )
+ { // off
+
+ if( 1==numbers[i] )
+ { // set foreground intensity off
+ info.wAttributes &= ~FOREGROUND_INTENSITY;
+ }
+ else if( 5==numbers[i] )
+ { // set background intensity off
+ info.wAttributes &= ~BACKGROUND_INTENSITY;
+ }
+ else if( 7==numbers[i] )
+ { // reverse colors (just xor them)
+ info.wAttributes ^= FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE |
+ BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE;
+ }
+ }
+ else if( 0x30 == (0xF0 & numbers[i]) )
+ { // foreground
+ uint8 num = numbers[i]&0x0F;
+ if(num==9) info.wAttributes |= FOREGROUND_INTENSITY;
+ if(num>7) num=7; // set white for 37, 38 and 39
+ info.wAttributes &= ~(FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
+ if( (num & 0x01)>0 ) // lowest bit set = red
+ info.wAttributes |= FOREGROUND_RED;
+ if( (num & 0x02)>0 ) // second bit set = green
+ info.wAttributes |= FOREGROUND_GREEN;
+ if( (num & 0x04)>0 ) // third bit set = blue
+ info.wAttributes |= FOREGROUND_BLUE;
+ }
+ else if( 0x40 == (0xF0 & numbers[i]) )
+ { // background
+ uint8 num = numbers[i]&0x0F;
+ if(num==9) info.wAttributes |= BACKGROUND_INTENSITY;
+ if(num>7) num=7; // set white for 47, 48 and 49
+ info.wAttributes &= ~(BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE);
+ if( (num & 0x01)>0 ) // lowest bit set = red
+ info.wAttributes |= BACKGROUND_RED;
+ if( (num & 0x02)>0 ) // second bit set = green
+ info.wAttributes |= BACKGROUND_GREEN;
+ if( (num & 0x04)>0 ) // third bit set = blue
+ info.wAttributes |= BACKGROUND_BLUE;
+ }
+ }
+ // set the attributes
+ SetConsoleTextAttribute(handle, info.wAttributes);
+ }
+ else if( *q=='J' )
+ { // \033[#J - Erase Display (ED)
+ // \033[0J - Clears the screen from cursor to end of display. The cursor position is unchanged.
+ // \033[1J - Clears the screen from start to cursor. The cursor position is unchanged.
+ // \033[2J - Clears the screen and moves the cursor to the home position (line 1, column 1).
+ uint8 num = (numbers[numpoint]>>4)*10+(numbers[numpoint]&0x0F);
+ int cnt;
+ DWORD tmp;
+ COORD origin = {0,0};
+ if(num==1)
+ { // chars from start up to and including cursor
+ cnt = info.dwSize.X * info.dwCursorPosition.Y + info.dwCursorPosition.X + 1;
+ }
+ else if(num==2)
+ { // Number of chars on screen.
+ cnt = info.dwSize.X * info.dwSize.Y;
+ SetConsoleCursorPosition(handle, origin);
+ }
+ else// 0 and default
+ { // number of chars from cursor to end
+ origin = info.dwCursorPosition;
+ cnt = info.dwSize.X * (info.dwSize.Y - info.dwCursorPosition.Y) - info.dwCursorPosition.X;
+ }
+ FillConsoleOutputAttribute(handle, info.wAttributes, cnt, origin, &tmp);
+ FillConsoleOutputCharacter(handle, ' ', cnt, origin, &tmp);
+ }
+ else if( *q=='K' )
+ { // \033[K : clear line from actual position to end of the line
+ // \033[0K - Clears all characters from the cursor position to the end of the line.
+ // \033[1K - Clears all characters from start of line to the cursor position.
+ // \033[2K - Clears all characters of the whole line.
+
+ uint8 num = (numbers[numpoint]>>4)*10+(numbers[numpoint]&0x0F);
+ COORD origin = {0,info.dwCursorPosition.Y}; //warning C4204
+ SHORT cnt;
+ DWORD tmp;
+ if(num==1)
+ {
+ cnt = info.dwCursorPosition.X + 1;
+ }
+ else if(num==2)
+ {
+ cnt = info.dwSize.X;
+ }
+ else// 0 and default
+ {
+ origin = info.dwCursorPosition;
+ cnt = info.dwSize.X - info.dwCursorPosition.X; // how many spaces until line is full
+ }
+ FillConsoleOutputAttribute(handle, info.wAttributes, cnt, origin, &tmp);
+ FillConsoleOutputCharacter(handle, ' ', cnt, origin, &tmp);
+ }
+ else if( *q == 'H' || *q == 'f' )
+ { // \033[#;#H - Cursor Position (CUP)
+ // \033[#;#f - Horizontal & Vertical Position
+ // The first # specifies the line number, the second # specifies the column.
+ // The default for both is 1
+ info.dwCursorPosition.X = (numbers[numpoint])?(numbers[numpoint]>>4)*10+((numbers[numpoint]&0x0F)-1):0;
+ info.dwCursorPosition.Y = (numpoint && numbers[numpoint-1])?(numbers[numpoint-1]>>4)*10+((numbers[numpoint-1]&0x0F)-1):0;
+
+ if( info.dwCursorPosition.X >= info.dwSize.X ) info.dwCursorPosition.Y = info.dwSize.X-1;
+ if( info.dwCursorPosition.Y >= info.dwSize.Y ) info.dwCursorPosition.Y = info.dwSize.Y-1;
+ SetConsoleCursorPosition(handle, info.dwCursorPosition);
+ }
+ else if( *q=='s' )
+ { // \033[s - Save Cursor Position (SCP)
+ /* XXX Two streams are being used. Disabled to avoid inconsistency [flaviojs]
+ CONSOLE_SCREEN_BUFFER_INFO info;
+ GetConsoleScreenBufferInfo(handle, &info);
+ saveposition = info.dwCursorPosition;
+ */
+ }
+ else if( *q=='u' )
+ { // \033[u - Restore cursor position (RCP)
+ /* XXX Two streams are being used. Disabled to avoid inconsistency [flaviojs]
+ SetConsoleCursorPosition(handle, saveposition);
+ */
+ }
+ else if( *q == 'A' )
+ { // \033[#A - Cursor Up (CUU)
+ // Moves the cursor UP # number of lines
+ info.dwCursorPosition.Y -= (numbers[numpoint])?(numbers[numpoint]>>4)*10+(numbers[numpoint]&0x0F):1;
+
+ if( info.dwCursorPosition.Y < 0 )
+ info.dwCursorPosition.Y = 0;
+ SetConsoleCursorPosition(handle, info.dwCursorPosition);
+ }
+ else if( *q == 'B' )
+ { // \033[#B - Cursor Down (CUD)
+ // Moves the cursor DOWN # number of lines
+ info.dwCursorPosition.Y += (numbers[numpoint])?(numbers[numpoint]>>4)*10+(numbers[numpoint]&0x0F):1;
+
+ if( info.dwCursorPosition.Y >= info.dwSize.Y )
+ info.dwCursorPosition.Y = info.dwSize.Y-1;
+ SetConsoleCursorPosition(handle, info.dwCursorPosition);
+ }
+ else if( *q == 'C' )
+ { // \033[#C - Cursor Forward (CUF)
+ // Moves the cursor RIGHT # number of columns
+ info.dwCursorPosition.X += (numbers[numpoint])?(numbers[numpoint]>>4)*10+(numbers[numpoint]&0x0F):1;
+
+ if( info.dwCursorPosition.X >= info.dwSize.X )
+ info.dwCursorPosition.X = info.dwSize.X-1;
+ SetConsoleCursorPosition(handle, info.dwCursorPosition);
+ }
+ else if( *q == 'D' )
+ { // \033[#D - Cursor Backward (CUB)
+ // Moves the cursor LEFT # number of columns
+ info.dwCursorPosition.X -= (numbers[numpoint])?(numbers[numpoint]>>4)*10+(numbers[numpoint]&0x0F):1;
+
+ if( info.dwCursorPosition.X < 0 )
+ info.dwCursorPosition.X = 0;
+ SetConsoleCursorPosition(handle, info.dwCursorPosition);
+ }
+ else if( *q == 'E' )
+ { // \033[#E - Cursor Next Line (CNL)
+ // Moves the cursor down the indicated # of rows, to column 1
+ info.dwCursorPosition.Y += (numbers[numpoint])?(numbers[numpoint]>>4)*10+(numbers[numpoint]&0x0F):1;
+ info.dwCursorPosition.X = 0;
+
+ if( info.dwCursorPosition.Y >= info.dwSize.Y )
+ info.dwCursorPosition.Y = info.dwSize.Y-1;
+ SetConsoleCursorPosition(handle, info.dwCursorPosition);
+ }
+ else if( *q == 'F' )
+ { // \033[#F - Cursor Preceding Line (CPL)
+ // Moves the cursor up the indicated # of rows, to column 1.
+ info.dwCursorPosition.Y -= (numbers[numpoint])?(numbers[numpoint]>>4)*10+(numbers[numpoint]&0x0F):1;
+ info.dwCursorPosition.X = 0;
+
+ if( info.dwCursorPosition.Y < 0 )
+ info.dwCursorPosition.Y = 0;
+ SetConsoleCursorPosition(handle, info.dwCursorPosition);
+ }
+ else if( *q == 'G' )
+ { // \033[#G - Cursor Horizontal Absolute (CHA)
+ // Moves the cursor to indicated column in current row.
+ info.dwCursorPosition.X = (numbers[numpoint])?(numbers[numpoint]>>4)*10+((numbers[numpoint]&0x0F)-1):0;
+
+ if( info.dwCursorPosition.X >= info.dwSize.X )
+ info.dwCursorPosition.X = info.dwSize.X-1;
+ SetConsoleCursorPosition(handle, info.dwCursorPosition);
+ }
+ else if( *q == 'L' || *q == 'M' || *q == '@' || *q == 'P')
+ { // not implemented, just skip
+ }
+ else
+ { // no number nor valid sequencer
+ // something is fishy, we break and give the current char free
+ --q;
+ }
+ // skip the sequencer and search again
+ p = q+1;
+ break;
+ }// end while
+ }
+ }
+ if (*p) // write the rest of the buffer
+ if( 0==WriteConsole(handle, p, (DWORD)strlen(p), &written, 0) )
+ WriteFile(handle, p, (DWORD)strlen(p), &written, 0);
+ FREEBUF(tempbuf);
+ return 0;
}
-int FPRINTF(HANDLE handle, const char *fmt, ...)
+int FPRINTF(HANDLE handle, const char *fmt, ...)
{
- int ret;
- va_list argptr;
- va_start(argptr, fmt);
- ret = VFPRINTF(handle,fmt,argptr);
- va_end(argptr);
- return ret;
+ int ret;
+ va_list argptr;
+ va_start(argptr, fmt);
+ ret = VFPRINTF(handle,fmt,argptr);
+ va_end(argptr);
+ return ret;
}
#define FFLUSH(handle)
@@ -496,109 +532,129 @@ int FPRINTF(HANDLE handle, const char *fmt, ...)
#define is_console(file) (0!=isatty(fileno(file)))
//vprintf_without_ansiformats
-int VFPRINTF(FILE *file, const char *fmt, va_list argptr)
+int VFPRINTF(FILE *file, const char *fmt, va_list argptr)
{
- char *p, *q;
- NEWBUF(tempbuf); // temporary buffer
-
- if (!fmt || !*fmt)
- return 0;
-
- if (is_console(file) || stdout_with_ansisequence) {
- vfprintf(file, fmt, argptr);
- return 0;
- }
-
- // Print everything to the buffer
- BUFVPRINTF(tempbuf,fmt,argptr);
-
- // start with processing
- p = BUFVAL(tempbuf);
- while ((q = strchr(p, 0x1b)) != NULL) {
- // find the escape character
- fprintf(file, "%.*s", (int)(q-p), p); // write up to the escape
- if (q[1]!='[') {
- // write the escape char (whatever purpose it has)
- fprintf(file, "%.*s", 1, q);
- p=q+1; //and start searching again
- } else {
- // from here, we will skip the '\033['
- // we break at the first unprocessible position
- // assuming regular text is starting there
-
- // skip escape and bracket
- q=q+2;
- while (1) {
- if (ISDIGIT(*q)) {
- ++q;
- // and next character
- continue;
- } else if (*q == ';') {
- // delimiter
- ++q;
- // and next number
- continue;
- } else if (*q == 'm') {
- // \033[#;...;#m - Set Graphics Rendition (SGR)
- // set the attributes
- } else if (*q=='J') {
- // \033[#J - Erase Display (ED)
- } else if (*q=='K') {
- // \033[K : clear line from actual position to end of the line
- } else if (*q == 'H' || *q == 'f') {
- // \033[#;#H - Cursor Position (CUP)
- // \033[#;#f - Horizontal & Vertical Position
- } else if (*q=='s') {
- // \033[s - Save Cursor Position (SCP)
- } else if (*q=='u') {
- // \033[u - Restore cursor position (RCP)
- } else if (*q == 'A') {
- // \033[#A - Cursor Up (CUU)
- // Moves the cursor UP # number of lines
- } else if (*q == 'B') {
- // \033[#B - Cursor Down (CUD)
- // Moves the cursor DOWN # number of lines
- } else if (*q == 'C') {
- // \033[#C - Cursor Forward (CUF)
- // Moves the cursor RIGHT # number of columns
- } else if (*q == 'D') {
- // \033[#D - Cursor Backward (CUB)
- // Moves the cursor LEFT # number of columns
- } else if (*q == 'E') {
- // \033[#E - Cursor Next Line (CNL)
- // Moves the cursor down the indicated # of rows, to column 1
- } else if (*q == 'F') {
- // \033[#F - Cursor Preceding Line (CPL)
- // Moves the cursor up the indicated # of rows, to column 1.
- } else if (*q == 'G') {
- // \033[#G - Cursor Horizontal Absolute (CHA)
- // Moves the cursor to indicated column in current row.
- } else if (*q == 'L' || *q == 'M' || *q == '@' || *q == 'P') {
- // not implemented, just skip
- } else {
- // no number nor valid sequencer
- // something is fishy, we break and give the current char free
- --q;
- }
- // skip the sequencer and search again
- p = q+1;
- break;
- }// end while
- }
- }
- if (*p) // write the rest of the buffer
- fprintf(file, "%s", p);
- FREEBUF(tempbuf);
- return 0;
+ char *p, *q;
+ NEWBUF(tempbuf); // temporary buffer
+
+ if(!fmt || !*fmt)
+ return 0;
+
+ if( is_console(file) || stdout_with_ansisequence )
+ {
+ vfprintf(file, fmt, argptr);
+ return 0;
+ }
+
+ // Print everything to the buffer
+ BUFVPRINTF(tempbuf,fmt,argptr);
+
+ // start with processing
+ p = BUFVAL(tempbuf);
+ while ((q = strchr(p, 0x1b)) != NULL)
+ { // find the escape character
+ fprintf(file, "%.*s", (int)(q-p), p); // write up to the escape
+ if( q[1]!='[' )
+ { // write the escape char (whatever purpose it has)
+ fprintf(file, "%.*s", 1, q);
+ p=q+1; //and start searching again
+ }
+ else
+ { // from here, we will skip the '\033['
+ // we break at the first unprocessible position
+ // assuming regular text is starting there
+
+ // skip escape and bracket
+ q=q+2;
+ while(1)
+ {
+ if( ISDIGIT(*q) )
+ {
+ ++q;
+ // and next character
+ continue;
+ }
+ else if( *q == ';' )
+ { // delimiter
+ ++q;
+ // and next number
+ continue;
+ }
+ else if( *q == 'm' )
+ { // \033[#;...;#m - Set Graphics Rendition (SGR)
+ // set the attributes
+ }
+ else if( *q=='J' )
+ { // \033[#J - Erase Display (ED)
+ }
+ else if( *q=='K' )
+ { // \033[K : clear line from actual position to end of the line
+ }
+ else if( *q == 'H' || *q == 'f' )
+ { // \033[#;#H - Cursor Position (CUP)
+ // \033[#;#f - Horizontal & Vertical Position
+ }
+ else if( *q=='s' )
+ { // \033[s - Save Cursor Position (SCP)
+ }
+ else if( *q=='u' )
+ { // \033[u - Restore cursor position (RCP)
+ }
+ else if( *q == 'A' )
+ { // \033[#A - Cursor Up (CUU)
+ // Moves the cursor UP # number of lines
+ }
+ else if( *q == 'B' )
+ { // \033[#B - Cursor Down (CUD)
+ // Moves the cursor DOWN # number of lines
+ }
+ else if( *q == 'C' )
+ { // \033[#C - Cursor Forward (CUF)
+ // Moves the cursor RIGHT # number of columns
+ }
+ else if( *q == 'D' )
+ { // \033[#D - Cursor Backward (CUB)
+ // Moves the cursor LEFT # number of columns
+ }
+ else if( *q == 'E' )
+ { // \033[#E - Cursor Next Line (CNL)
+ // Moves the cursor down the indicated # of rows, to column 1
+ }
+ else if( *q == 'F' )
+ { // \033[#F - Cursor Preceding Line (CPL)
+ // Moves the cursor up the indicated # of rows, to column 1.
+ }
+ else if( *q == 'G' )
+ { // \033[#G - Cursor Horizontal Absolute (CHA)
+ // Moves the cursor to indicated column in current row.
+ }
+ else if( *q == 'L' || *q == 'M' || *q == '@' || *q == 'P')
+ { // not implemented, just skip
+ }
+ else
+ { // no number nor valid sequencer
+ // something is fishy, we break and give the current char free
+ --q;
+ }
+ // skip the sequencer and search again
+ p = q+1;
+ break;
+ }// end while
+ }
+ }
+ if (*p) // write the rest of the buffer
+ fprintf(file, "%s", p);
+ FREEBUF(tempbuf);
+ return 0;
}
-int FPRINTF(FILE *file, const char *fmt, ...)
+int FPRINTF(FILE *file, const char *fmt, ...)
{
- int ret;
- va_list argptr;
- va_start(argptr, fmt);
- ret = VFPRINTF(file,fmt,argptr);
- va_end(argptr);
- return ret;
+ int ret;
+ va_list argptr;
+ va_start(argptr, fmt);
+ ret = VFPRINTF(file,fmt,argptr);
+ va_end(argptr);
+ return ret;
}
#define FFLUSH fflush
@@ -621,225 +677,216 @@ char timestamp_format[20] = ""; //For displaying Timestamps
int _vShowMessage(enum msg_type flag, const char *string, va_list ap)
{
- va_list apcopy;
- char prefix[100];
+ va_list apcopy;
+ char prefix[100];
#if defined(DEBUGLOGMAP) || defined(DEBUGLOGCHAR) || defined(DEBUGLOGLOGIN)
- FILE *fp;
+ FILE *fp;
#endif
-
- if (!string || *string == '\0') {
- ShowError("Empty string passed to _vShowMessage().\n");
- return 1;
- }
- /**
- * For the buildbot, these result in a EXIT_FAILURE from core.c when done reading the params.
- **/
+
+ if (!string || *string == '\0') {
+ ShowError("Empty string passed to _vShowMessage().\n");
+ return 1;
+ }
+ /**
+ * For the buildbot, these result in a EXIT_FAILURE from core.c when done reading the params.
+ **/
#if defined(BUILDBOT)
- if (flag == MSG_WARNING ||
- flag == MSG_ERROR ||
- flag == MSG_SQL) {
- buildbotflag = 1;
- }
+ if( flag == MSG_WARNING ||
+ flag == MSG_ERROR ||
+ flag == MSG_SQL ) {
+ buildbotflag = 1;
+ }
#endif
- if (
- (flag == MSG_WARNING && console_msg_log&1) ||
- ((flag == MSG_ERROR || flag == MSG_SQL) && console_msg_log&2) ||
- (flag == MSG_DEBUG && console_msg_log&4)) { //[Ind]
- FILE *log = NULL;
- if ((log = fopen(SERVER_TYPE == ATHENA_SERVER_MAP ? "./log/map-msg_log.log" : "./log/unknown.log","a+"))) {
- char timestring[255];
- time_t curtime;
- time(&curtime);
- strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
- fprintf(log,"(%s) [ %s ] : ",
- timestring,
- flag == MSG_WARNING ? "Warning" :
- flag == MSG_ERROR ? "Error" :
- flag == MSG_SQL ? "SQL Error" :
- flag == MSG_DEBUG ? "Debug" :
- "Unknown");
- va_copy(apcopy, ap);
- vfprintf(log,string,apcopy);
- va_end(apcopy);
- fclose(log);
- }
- }
- if (
- (flag == MSG_INFORMATION && msg_silent&1) ||
- (flag == MSG_STATUS && msg_silent&2) ||
- (flag == MSG_NOTICE && msg_silent&4) ||
- (flag == MSG_WARNING && msg_silent&8) ||
- (flag == MSG_ERROR && msg_silent&16) ||
- (flag == MSG_SQL && msg_silent&16) ||
- (flag == MSG_DEBUG && msg_silent&32)
- )
- return 0; //Do not print it.
-
- if (timestamp_format[0] && flag != MSG_NONE) {
- //Display time format. [Skotlex]
- time_t t = time(NULL);
- strftime(prefix, 80, timestamp_format, localtime(&t));
- } else prefix[0]='\0';
-
- switch (flag) {
- case MSG_NONE: // direct printf replacement
- break;
- case MSG_STATUS: //Bright Green (To inform about good things)
- strcat(prefix,CL_GREEN"[Status]"CL_RESET":");
- break;
- case MSG_SQL: //Bright Violet (For dumping out anything related with SQL) <- Actually, this is mostly used for SQL errors with the database, as successes can as well just be anything else... [Skotlex]
- strcat(prefix,CL_MAGENTA"[SQL]"CL_RESET":");
- break;
- case MSG_INFORMATION: //Bright White (Variable information)
- strcat(prefix,CL_WHITE"[Info]"CL_RESET":");
- break;
- case MSG_NOTICE: //Bright White (Less than a warning)
- strcat(prefix,CL_WHITE"[Notice]"CL_RESET":");
- break;
- case MSG_WARNING: //Bright Yellow
- strcat(prefix,CL_YELLOW"[Warning]"CL_RESET":");
- break;
- case MSG_DEBUG: //Bright Cyan, important stuff!
- strcat(prefix,CL_CYAN"[Debug]"CL_RESET":");
- break;
- case MSG_ERROR: //Bright Red (Regular errors)
- strcat(prefix,CL_RED"[Error]"CL_RESET":");
- break;
- case MSG_FATALERROR: //Bright Red (Fatal errors, abort(); if possible)
- strcat(prefix,CL_RED"[Fatal Error]"CL_RESET":");
- break;
- default:
- ShowError("In function _vShowMessage() -> Invalid flag passed.\n");
- return 1;
- }
-
- if (flag == MSG_ERROR || flag == MSG_FATALERROR || flag == MSG_SQL) {
- //Send Errors to StdErr [Skotlex]
- FPRINTF(STDERR, "%s ", prefix);
- va_copy(apcopy, ap);
- VFPRINTF(STDERR, string, apcopy);
- va_end(apcopy);
- FFLUSH(STDERR);
- } else {
- if (flag != MSG_NONE)
- FPRINTF(STDOUT, "%s ", prefix);
- va_copy(apcopy, ap);
- VFPRINTF(STDOUT, string, apcopy);
- va_end(apcopy);
- FFLUSH(STDOUT);
- }
+ if(
+ ( flag == MSG_WARNING && console_msg_log&1 ) ||
+ ( ( flag == MSG_ERROR || flag == MSG_SQL ) && console_msg_log&2 ) ||
+ ( flag == MSG_DEBUG && console_msg_log&4 ) ) {//[Ind]
+ FILE *log = NULL;
+ if( (log = fopen(SERVER_TYPE == ATHENA_SERVER_MAP ? "./log/map-msg_log.log" : "./log/unknown.log","a+")) ) {
+ char timestring[255];
+ time_t curtime;
+ time(&curtime);
+ strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
+ fprintf(log,"(%s) [ %s ] : ",
+ timestring,
+ flag == MSG_WARNING ? "Warning" :
+ flag == MSG_ERROR ? "Error" :
+ flag == MSG_SQL ? "SQL Error" :
+ flag == MSG_DEBUG ? "Debug" :
+ "Unknown");
+ va_copy(apcopy, ap);
+ vfprintf(log,string,apcopy);
+ va_end(apcopy);
+ fclose(log);
+ }
+ }
+ if(
+ (flag == MSG_INFORMATION && msg_silent&1) ||
+ (flag == MSG_STATUS && msg_silent&2) ||
+ (flag == MSG_NOTICE && msg_silent&4) ||
+ (flag == MSG_WARNING && msg_silent&8) ||
+ (flag == MSG_ERROR && msg_silent&16) ||
+ (flag == MSG_SQL && msg_silent&16) ||
+ (flag == MSG_DEBUG && msg_silent&32)
+ )
+ return 0; //Do not print it.
+
+ if (timestamp_format[0] && flag != MSG_NONE)
+ { //Display time format. [Skotlex]
+ time_t t = time(NULL);
+ strftime(prefix, 80, timestamp_format, localtime(&t));
+ } else prefix[0]='\0';
+
+ switch (flag) {
+ case MSG_NONE: // direct printf replacement
+ break;
+ case MSG_STATUS: //Bright Green (To inform about good things)
+ strcat(prefix,CL_GREEN"[Status]"CL_RESET":");
+ break;
+ case MSG_SQL: //Bright Violet (For dumping out anything related with SQL) <- Actually, this is mostly used for SQL errors with the database, as successes can as well just be anything else... [Skotlex]
+ strcat(prefix,CL_MAGENTA"[SQL]"CL_RESET":");
+ break;
+ case MSG_INFORMATION: //Bright White (Variable information)
+ strcat(prefix,CL_WHITE"[Info]"CL_RESET":");
+ break;
+ case MSG_NOTICE: //Bright White (Less than a warning)
+ strcat(prefix,CL_WHITE"[Notice]"CL_RESET":");
+ break;
+ case MSG_WARNING: //Bright Yellow
+ strcat(prefix,CL_YELLOW"[Warning]"CL_RESET":");
+ break;
+ case MSG_DEBUG: //Bright Cyan, important stuff!
+ strcat(prefix,CL_CYAN"[Debug]"CL_RESET":");
+ break;
+ case MSG_ERROR: //Bright Red (Regular errors)
+ strcat(prefix,CL_RED"[Error]"CL_RESET":");
+ break;
+ case MSG_FATALERROR: //Bright Red (Fatal errors, abort(); if possible)
+ strcat(prefix,CL_RED"[Fatal Error]"CL_RESET":");
+ break;
+ default:
+ ShowError("In function _vShowMessage() -> Invalid flag passed.\n");
+ return 1;
+ }
+
+ if (flag == MSG_ERROR || flag == MSG_FATALERROR || flag == MSG_SQL)
+ { //Send Errors to StdErr [Skotlex]
+ FPRINTF(STDERR, "%s ", prefix);
+ va_copy(apcopy, ap);
+ VFPRINTF(STDERR, string, apcopy);
+ va_end(apcopy);
+ FFLUSH(STDERR);
+ } else {
+ if (flag != MSG_NONE)
+ FPRINTF(STDOUT, "%s ", prefix);
+ va_copy(apcopy, ap);
+ VFPRINTF(STDOUT, string, apcopy);
+ va_end(apcopy);
+ FFLUSH(STDOUT);
+ }
#if defined(DEBUGLOGMAP) || defined(DEBUGLOGCHAR) || defined(DEBUGLOGLOGIN)
- if (strlen(DEBUGLOGPATH) > 0) {
- fp=fopen(DEBUGLOGPATH,"a");
- if (fp == NULL) {
- FPRINTF(STDERR, CL_RED"[ERROR]"CL_RESET": Could not open '"CL_WHITE"%s"CL_RESET"', access denied.\n", DEBUGLOGPATH);
- FFLUSH(STDERR);
- } else {
- fprintf(fp,"%s ", prefix);
- va_copy(apcopy, ap);
- vfprintf(fp,string,apcopy);
- va_end(apcopy);
- fclose(fp);
- }
- } else {
- FPRINTF(STDERR, CL_RED"[ERROR]"CL_RESET": DEBUGLOGPATH not defined!\n");
- FFLUSH(STDERR);
- }
+ if(strlen(DEBUGLOGPATH) > 0) {
+ fp=fopen(DEBUGLOGPATH,"a");
+ if (fp == NULL) {
+ FPRINTF(STDERR, CL_RED"[ERROR]"CL_RESET": Could not open '"CL_WHITE"%s"CL_RESET"', access denied.\n", DEBUGLOGPATH);
+ FFLUSH(STDERR);
+ } else {
+ fprintf(fp,"%s ", prefix);
+ va_copy(apcopy, ap);
+ vfprintf(fp,string,apcopy);
+ va_end(apcopy);
+ fclose(fp);
+ }
+ } else {
+ FPRINTF(STDERR, CL_RED"[ERROR]"CL_RESET": DEBUGLOGPATH not defined!\n");
+ FFLUSH(STDERR);
+ }
#endif
- return 0;
+ return 0;
}
void ClearScreen(void)
{
#ifndef _WIN32
- ShowMessage(CL_CLS); // to prevent empty string passed messages
+ ShowMessage(CL_CLS); // to prevent empty string passed messages
#endif
}
int _ShowMessage(enum msg_type flag, const char *string, ...)
{
- int ret;
- va_list ap;
- va_start(ap, string);
- ret = _vShowMessage(flag, string, ap);
- va_end(ap);
- return ret;
+ int ret;
+ va_list ap;
+ va_start(ap, string);
+ ret = _vShowMessage(flag, string, ap);
+ va_end(ap);
+ return ret;
}
// direct printf replacement
-void ShowMessage(const char *string, ...)
-{
- va_list ap;
- va_start(ap, string);
- _vShowMessage(MSG_NONE, string, ap);
- va_end(ap);
+void ShowMessage(const char *string, ...) {
+ va_list ap;
+ va_start(ap, string);
+ _vShowMessage(MSG_NONE, string, ap);
+ va_end(ap);
}
-void ShowStatus(const char *string, ...)
-{
- va_list ap;
- va_start(ap, string);
- _vShowMessage(MSG_STATUS, string, ap);
- va_end(ap);
+void ShowStatus(const char *string, ...) {
+ va_list ap;
+ va_start(ap, string);
+ _vShowMessage(MSG_STATUS, string, ap);
+ va_end(ap);
}
-void ShowSQL(const char *string, ...)
-{
- va_list ap;
- va_start(ap, string);
- _vShowMessage(MSG_SQL, string, ap);
- va_end(ap);
+void ShowSQL(const char *string, ...) {
+ va_list ap;
+ va_start(ap, string);
+ _vShowMessage(MSG_SQL, string, ap);
+ va_end(ap);
}
-void ShowInfo(const char *string, ...)
-{
- va_list ap;
- va_start(ap, string);
- _vShowMessage(MSG_INFORMATION, string, ap);
- va_end(ap);
+void ShowInfo(const char *string, ...) {
+ va_list ap;
+ va_start(ap, string);
+ _vShowMessage(MSG_INFORMATION, string, ap);
+ va_end(ap);
}
-void ShowNotice(const char *string, ...)
-{
- va_list ap;
- va_start(ap, string);
- _vShowMessage(MSG_NOTICE, string, ap);
- va_end(ap);
+void ShowNotice(const char *string, ...) {
+ va_list ap;
+ va_start(ap, string);
+ _vShowMessage(MSG_NOTICE, string, ap);
+ va_end(ap);
}
-void ShowWarning(const char *string, ...)
-{
- va_list ap;
- va_start(ap, string);
- _vShowMessage(MSG_WARNING, string, ap);
- va_end(ap);
+void ShowWarning(const char *string, ...) {
+ va_list ap;
+ va_start(ap, string);
+ _vShowMessage(MSG_WARNING, string, ap);
+ va_end(ap);
}
void ShowConfigWarning(config_setting_t *config, const char *string, ...)
{
- StringBuf buf;
- va_list ap;
- StringBuf_Init(&buf);
- StringBuf_AppendStr(&buf, string);
- StringBuf_Printf(&buf, " (%s:%d)\n", config_setting_source_file(config), config_setting_source_line(config));
- va_start(ap, string);
- _vShowMessage(MSG_WARNING, StringBuf_Value(&buf), ap);
- va_end(ap);
- StringBuf_Destroy(&buf);
+ StringBuf buf;
+ va_list ap;
+ StringBuf_Init(&buf);
+ StringBuf_AppendStr(&buf, string);
+ StringBuf_Printf(&buf, " (%s:%d)\n", config_setting_source_file(config), config_setting_source_line(config));
+ va_start(ap, string);
+ _vShowMessage(MSG_WARNING, StringBuf_Value(&buf), ap);
+ va_end(ap);
+ StringBuf_Destroy(&buf);
}
-void ShowDebug(const char *string, ...)
-{
- va_list ap;
- va_start(ap, string);
- _vShowMessage(MSG_DEBUG, string, ap);
- va_end(ap);
+void ShowDebug(const char *string, ...) {
+ va_list ap;
+ va_start(ap, string);
+ _vShowMessage(MSG_DEBUG, string, ap);
+ va_end(ap);
}
-void ShowError(const char *string, ...)
-{
- va_list ap;
- va_start(ap, string);
- _vShowMessage(MSG_ERROR, string, ap);
- va_end(ap);
+void ShowError(const char *string, ...) {
+ va_list ap;
+ va_start(ap, string);
+ _vShowMessage(MSG_ERROR, string, ap);
+ va_end(ap);
}
-void ShowFatalError(const char *string, ...)
-{
- va_list ap;
- va_start(ap, string);
- _vShowMessage(MSG_FATALERROR, string, ap);
- va_end(ap);
+void ShowFatalError(const char *string, ...) {
+ va_list ap;
+ va_start(ap, string);
+ _vShowMessage(MSG_FATALERROR, string, ap);
+ va_end(ap);
}
diff --git a/src/common/showmsg.h b/src/common/showmsg.h
index 8c2b5bd42..0d6cb5c9f 100644
--- a/src/common/showmsg.h
+++ b/src/common/showmsg.h
@@ -14,58 +14,58 @@
// \033[0m : reset color parameter
// \033[1m : use bold for font
-#define CL_RESET "\033[0m"
-#define CL_CLS "\033[2J"
-#define CL_CLL "\033[K"
+#define CL_RESET "\033[0m"
+#define CL_CLS "\033[2J"
+#define CL_CLL "\033[K"
// font settings
-#define CL_BOLD "\033[1m"
-#define CL_NORM CL_RESET
-#define CL_NORMAL CL_RESET
-#define CL_NONE CL_RESET
+#define CL_BOLD "\033[1m"
+#define CL_NORM CL_RESET
+#define CL_NORMAL CL_RESET
+#define CL_NONE CL_RESET
// foreground color and bold font (bright color on windows)
-#define CL_WHITE "\033[1;37m"
-#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"
+#define CL_WHITE "\033[1;37m"
+#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"
// background color
-#define CL_BG_BLACK "\033[40m"
-#define CL_BG_RED "\033[41m"
-#define CL_BG_GREEN "\033[42m"
-#define CL_BG_YELLOW "\033[43m"
-#define CL_BG_BLUE "\033[44m"
-#define CL_BG_MAGENTA "\033[45m"
-#define CL_BG_CYAN "\033[46m"
-#define CL_BG_WHITE "\033[47m"
+#define CL_BG_BLACK "\033[40m"
+#define CL_BG_RED "\033[41m"
+#define CL_BG_GREEN "\033[42m"
+#define CL_BG_YELLOW "\033[43m"
+#define CL_BG_BLUE "\033[44m"
+#define CL_BG_MAGENTA "\033[45m"
+#define CL_BG_CYAN "\033[46m"
+#define CL_BG_WHITE "\033[47m"
// foreground color and normal font (normal color on windows)
-#define CL_LT_BLACK "\033[0;30m"
-#define CL_LT_RED "\033[0;31m"
-#define CL_LT_GREEN "\033[0;32m"
-#define CL_LT_YELLOW "\033[0;33m"
-#define CL_LT_BLUE "\033[0;34m"
-#define CL_LT_MAGENTA "\033[0;35m"
-#define CL_LT_CYAN "\033[0;36m"
-#define CL_LT_WHITE "\033[0;37m"
+#define CL_LT_BLACK "\033[0;30m"
+#define CL_LT_RED "\033[0;31m"
+#define CL_LT_GREEN "\033[0;32m"
+#define CL_LT_YELLOW "\033[0;33m"
+#define CL_LT_BLUE "\033[0;34m"
+#define CL_LT_MAGENTA "\033[0;35m"
+#define CL_LT_CYAN "\033[0;36m"
+#define CL_LT_WHITE "\033[0;37m"
// foreground color and bold font (bright color on windows)
-#define CL_BT_BLACK "\033[1;30m"
-#define CL_BT_RED "\033[1;31m"
-#define CL_BT_GREEN "\033[1;32m"
-#define CL_BT_YELLOW "\033[1;33m"
-#define CL_BT_BLUE "\033[1;34m"
-#define CL_BT_MAGENTA "\033[1;35m"
-#define CL_BT_CYAN "\033[1;36m"
-#define CL_BT_WHITE "\033[1;37m"
+#define CL_BT_BLACK "\033[1;30m"
+#define CL_BT_RED "\033[1;31m"
+#define CL_BT_GREEN "\033[1;32m"
+#define CL_BT_YELLOW "\033[1;33m"
+#define CL_BT_BLUE "\033[1;34m"
+#define CL_BT_MAGENTA "\033[1;35m"
+#define CL_BT_CYAN "\033[1;36m"
+#define CL_BT_WHITE "\033[1;37m"
-#define CL_WTBL "\033[37;44m" // white on blue
-#define CL_XXBL "\033[0;44m" // default on blue
-#define CL_PASS "\033[0;32;42m" // green on green
+#define CL_WTBL "\033[37;44m" // white on blue
+#define CL_XXBL "\033[0;44m" // default on blue
+#define CL_PASS "\033[0;32;42m" // green on green
-#define CL_SPACE " " // space aquivalent of the print messages
+#define CL_SPACE " " // space aquivalent of the print messages
extern int stdout_with_ansisequence; //If the color ansi sequences are to be used. [flaviojs]
extern int msg_silent; //Specifies how silent the console is. [Skotlex]
@@ -73,15 +73,15 @@ extern int console_msg_log; //Specifies what error messages to log. [Ind]
extern char timestamp_format[20]; //For displaying Timestamps [Skotlex]
enum msg_type {
- MSG_NONE,
- MSG_STATUS,
- MSG_SQL,
- MSG_INFORMATION,
- MSG_NOTICE,
- MSG_WARNING,
- MSG_DEBUG,
- MSG_ERROR,
- MSG_FATALERROR
+ MSG_NONE,
+ MSG_STATUS,
+ MSG_SQL,
+ MSG_INFORMATION,
+ MSG_NOTICE,
+ MSG_WARNING,
+ MSG_DEBUG,
+ MSG_ERROR,
+ MSG_FATALERROR
};
extern void ClearScreen(void);
diff --git a/src/common/socket.c b/src/common/socket.c
index 4a6e01459..d24a9c1d8 100644
--- a/src/common/socket.c
+++ b/src/common/socket.c
@@ -15,35 +15,35 @@
#include <sys/types.h>
#ifdef WIN32
-#include "../common/winapi.h"
+ #include "../common/winapi.h"
#else
-#include <errno.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <net/if.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include <sys/ioctl.h>
-#include <netdb.h>
-#include <arpa/inet.h>
-
-#ifndef SIOCGIFCONF
-#include <sys/sockio.h> // SIOCGIFCONF on Solaris, maybe others? [Shinomori]
-#endif
-#ifndef FIONBIO
-#include <sys/filio.h> // FIONBIO on Solaris [FlavioJS]
-#endif
-
-#ifdef HAVE_SETRLIMIT
-#include <sys/resource.h>
-#endif
+ #include <errno.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <netinet/tcp.h>
+ #include <net/if.h>
+ #include <unistd.h>
+ #include <sys/time.h>
+ #include <sys/ioctl.h>
+ #include <netdb.h>
+ #include <arpa/inet.h>
+
+ #ifndef SIOCGIFCONF
+ #include <sys/sockio.h> // SIOCGIFCONF on Solaris, maybe others? [Shinomori]
+ #endif
+ #ifndef FIONBIO
+ #include <sys/filio.h> // FIONBIO on Solaris [FlavioJS]
+ #endif
+
+ #ifdef HAVE_SETRLIMIT
+ #include <sys/resource.h>
+ #endif
#endif
/////////////////////////////////////////////////////////////////////
#if defined(WIN32)
/////////////////////////////////////////////////////////////////////
-// windows portability layer
+// windows portability layer
typedef int socklen_t;
@@ -75,21 +75,21 @@ static int sock_arr_len = 0;
/// @return Fd or -1
int sock2fd(SOCKET s)
{
- int fd;
-
- // search for the socket
- for (fd = 1; fd < sock_arr_len; ++fd)
- if (sock_arr[fd] == s)
- break;// found the socket
- if (fd == sock_arr_len)
- return -1;// not found
- return fd;
+ int fd;
+
+ // search for the socket
+ for( fd = 1; fd < sock_arr_len; ++fd )
+ if( sock_arr[fd] == s )
+ break;// found the socket
+ if( fd == sock_arr_len )
+ return -1;// not found
+ return fd;
}
/// Inserts the socket into the global array of sockets.
/// Returns a new fd associated with the socket.
-/// If there are too many sockets it closes the socket, sets an error and
+/// If there are too many sockets it closes the socket, sets an error and
// returns -1 instead.
/// Since fd 0 is reserved, it returns values in the range [1,FD_SETSIZE[.
///
@@ -97,61 +97,61 @@ int sock2fd(SOCKET s)
/// @return New fd or -1
int sock2newfd(SOCKET s)
{
- int fd;
-
- // find an empty position
- for (fd = 1; fd < sock_arr_len; ++fd)
- if (sock_arr[fd] == INVALID_SOCKET)
- break;// empty position
- if (fd == ARRAYLENGTH(sock_arr)) {
- // too many sockets
- closesocket(s);
- WSASetLastError(WSAEMFILE);
- return -1;
- }
- sock_arr[fd] = s;
- if (sock_arr_len <= fd)
- sock_arr_len = fd+1;
- return fd;
+ int fd;
+
+ // find an empty position
+ for( fd = 1; fd < sock_arr_len; ++fd )
+ if( sock_arr[fd] == INVALID_SOCKET )
+ break;// empty position
+ if( fd == ARRAYLENGTH(sock_arr) )
+ {// too many sockets
+ closesocket(s);
+ WSASetLastError(WSAEMFILE);
+ return -1;
+ }
+ sock_arr[fd] = s;
+ if( sock_arr_len <= fd )
+ sock_arr_len = fd+1;
+ return fd;
}
-int sAccept(int fd, struct sockaddr *addr, int *addrlen)
+int sAccept(int fd, struct sockaddr* addr, int* addrlen)
{
- SOCKET s;
+ SOCKET s;
- // accept connection
- s = accept(fd2sock(fd), addr, addrlen);
- if (s == INVALID_SOCKET)
- return -1;// error
- return sock2newfd(s);
+ // accept connection
+ s = accept(fd2sock(fd), addr, addrlen);
+ if( s == INVALID_SOCKET )
+ return -1;// error
+ return sock2newfd(s);
}
int sClose(int fd)
{
- int ret = closesocket(fd2sock(fd));
- fd2sock(fd) = INVALID_SOCKET;
- return ret;
+ int ret = closesocket(fd2sock(fd));
+ fd2sock(fd) = INVALID_SOCKET;
+ return ret;
}
int sSocket(int af, int type, int protocol)
{
- SOCKET s;
+ SOCKET s;
- // create socket
- s = socket(af,type,protocol);
- if (s == INVALID_SOCKET)
- return -1;// error
- return sock2newfd(s);
+ // create socket
+ s = socket(af,type,protocol);
+ if( s == INVALID_SOCKET )
+ return -1;// error
+ return sock2newfd(s);
}
-char *sErr(int code)
+char* sErr(int code)
{
- static char sbuf[512];
- // strerror does not handle socket codes
- if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
- code, MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), (LPTSTR)&sbuf, sizeof(sbuf), NULL) == 0)
- snprintf(sbuf, sizeof(sbuf), "unknown error");
- return sbuf;
+ static char sbuf[512];
+ // strerror does not handle socket codes
+ if( FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
+ code, MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), (LPTSTR)&sbuf, sizeof(sbuf), NULL) == 0 )
+ snprintf(sbuf, sizeof(sbuf), "unknown error");
+ return sbuf;
}
#define sBind(fd,name,namelen) bind(fd2sock(fd),name,namelen)
@@ -205,7 +205,7 @@ char *sErr(int code)
/////////////////////////////////////////////////////////////////////
#ifndef MSG_NOSIGNAL
-#define MSG_NOSIGNAL 0
+ #define MSG_NOSIGNAL 0
#endif
fd_set readfds;
@@ -230,7 +230,7 @@ static size_t socket_max_client_packet = 24576;
// The connection is closed if it goes over the limit.
#define WFIFO_MAX (1*1024*1024)
-struct socket_data *session[FD_SETSIZE];
+struct socket_data* session[FD_SETSIZE];
#ifdef SEND_SHORTLIST
int send_shortlist_array[FD_SETSIZE];// we only support FD_SETSIZE sockets, limit the array to that
@@ -241,390 +241,387 @@ uint32 send_shortlist_set[(FD_SETSIZE+31)/32];// to know if specific fd's are al
static int create_session(int fd, RecvFunc func_recv, SendFunc func_send, ParseFunc func_parse);
#ifndef MINICORE
-int ip_rules = 1;
-static int connect_check(uint32 ip);
+ int ip_rules = 1;
+ static int connect_check(uint32 ip);
#endif
-const char *error_msg(void)
+const char* error_msg(void)
{
- static char buf[512];
- int code = sErrno;
- snprintf(buf, sizeof(buf), "error %d: %s", code, sErr(code));
- return buf;
+ static char buf[512];
+ int code = sErrno;
+ snprintf(buf, sizeof(buf), "error %d: %s", code, sErr(code));
+ return buf;
}
/*======================================
- * CORE : Default processing functions
+ * CORE : Default processing functions
*--------------------------------------*/
-int null_recv(int fd)
-{
- return 0;
-}
-int null_send(int fd)
-{
- return 0;
-}
-int null_parse(int fd)
-{
- return 0;
-}
+int null_recv(int fd) { return 0; }
+int null_send(int fd) { return 0; }
+int null_parse(int fd) { return 0; }
ParseFunc default_func_parse = null_parse;
void set_defaultparse(ParseFunc defaultparse)
{
- default_func_parse = defaultparse;
+ default_func_parse = defaultparse;
}
/*======================================
- * CORE : Socket options
+ * CORE : Socket options
*--------------------------------------*/
void set_nonblocking(int fd, unsigned long yes)
{
- // FIONBIO Use with a nonzero argp parameter to enable the nonblocking mode of socket s.
- // The argp parameter is zero if nonblocking is to be disabled.
- if (sIoctl(fd, FIONBIO, &yes) != 0)
- ShowError("set_nonblocking: Failed to set socket #%d to non-blocking mode (%s) - Please report this!!!\n", fd, error_msg());
+ // FIONBIO Use with a nonzero argp parameter to enable the nonblocking mode of socket s.
+ // The argp parameter is zero if nonblocking is to be disabled.
+ if( sIoctl(fd, FIONBIO, &yes) != 0 )
+ ShowError("set_nonblocking: Failed to set socket #%d to non-blocking mode (%s) - Please report this!!!\n", fd, error_msg());
}
void setsocketopts(int fd)
{
- int yes = 1; // reuse fix
+ int yes = 1; // reuse fix
#if !defined(WIN32)
- // set SO_REAUSEADDR to true, unix only. on windows this option causes
- // the previous owner of the socket to give up, which is not desirable
- // in most cases, neither compatible with unix.
- sSetsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(char *)&yes,sizeof(yes));
+ // set SO_REAUSEADDR to true, unix only. on windows this option causes
+ // the previous owner of the socket to give up, which is not desirable
+ // in most cases, neither compatible with unix.
+ sSetsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(char *)&yes,sizeof(yes));
#ifdef SO_REUSEPORT
- sSetsockopt(fd,SOL_SOCKET,SO_REUSEPORT,(char *)&yes,sizeof(yes));
+ sSetsockopt(fd,SOL_SOCKET,SO_REUSEPORT,(char *)&yes,sizeof(yes));
#endif
#endif
- // Set the socket into no-delay mode; otherwise packets get delayed for up to 200ms, likely creating server-side lag.
- // The RO protocol is mainly single-packet request/response, plus the FIFO model already does packet grouping anyway.
- sSetsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&yes, sizeof(yes));
-
- // force the socket into no-wait, graceful-close mode (should be the default, but better make sure)
- //(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/closesocket_2.asp)
- {
- struct linger opt;
- opt.l_onoff = 0; // SO_DONTLINGER
- opt.l_linger = 0; // Do not care
- if (sSetsockopt(fd, SOL_SOCKET, SO_LINGER, (char *)&opt, sizeof(opt)))
- ShowWarning("setsocketopts: Unable to set SO_LINGER mode for connection #%d!\n", fd);
- }
+ // Set the socket into no-delay mode; otherwise packets get delayed for up to 200ms, likely creating server-side lag.
+ // The RO protocol is mainly single-packet request/response, plus the FIFO model already does packet grouping anyway.
+ sSetsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&yes, sizeof(yes));
+
+ // force the socket into no-wait, graceful-close mode (should be the default, but better make sure)
+ //(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/closesocket_2.asp)
+ {
+ struct linger opt;
+ opt.l_onoff = 0; // SO_DONTLINGER
+ opt.l_linger = 0; // Do not care
+ if( sSetsockopt(fd, SOL_SOCKET, SO_LINGER, (char*)&opt, sizeof(opt)) )
+ ShowWarning("setsocketopts: Unable to set SO_LINGER mode for connection #%d!\n", fd);
+ }
}
/*======================================
- * CORE : Socket Sub Function
+ * CORE : Socket Sub Function
*--------------------------------------*/
void set_eof(int fd)
{
- if (session_isActive(fd)) {
+ if( session_isActive(fd) )
+ {
#ifdef SEND_SHORTLIST
- // Add this socket to the shortlist for eof handling.
- send_shortlist_add_fd(fd);
+ // Add this socket to the shortlist for eof handling.
+ send_shortlist_add_fd(fd);
#endif
- session[fd]->flag.eof = 1;
- }
+ session[fd]->flag.eof = 1;
+ }
}
int recv_to_fifo(int fd)
{
- int len;
-
- if (!session_isActive(fd))
- return -1;
-
- len = sRecv(fd, (char *) session[fd]->rdata + session[fd]->rdata_size, (int)RFIFOSPACE(fd), 0);
-
- if (len == SOCKET_ERROR) {
- //An exception has occured
- if (sErrno != S_EWOULDBLOCK) {
- //ShowDebug("recv_to_fifo: %s, closing connection #%d\n", error_msg(), fd);
- set_eof(fd);
- }
- return 0;
- }
-
- if (len == 0) {
- //Normal connection end.
- set_eof(fd);
- return 0;
- }
-
- session[fd]->rdata_size += len;
- session[fd]->rdata_tick = last_tick;
- return 0;
+ int len;
+
+ if( !session_isActive(fd) )
+ return -1;
+
+ len = sRecv(fd, (char *) session[fd]->rdata + session[fd]->rdata_size, (int)RFIFOSPACE(fd), 0);
+
+ if( len == SOCKET_ERROR )
+ {//An exception has occured
+ if( sErrno != S_EWOULDBLOCK ) {
+ //ShowDebug("recv_to_fifo: %s, closing connection #%d\n", error_msg(), fd);
+ set_eof(fd);
+ }
+ return 0;
+ }
+
+ if( len == 0 )
+ {//Normal connection end.
+ set_eof(fd);
+ return 0;
+ }
+
+ session[fd]->rdata_size += len;
+ session[fd]->rdata_tick = last_tick;
+ return 0;
}
int send_from_fifo(int fd)
{
- int len;
+ int len;
- if (!session_isValid(fd))
- return -1;
+ if( !session_isValid(fd) )
+ return -1;
- if (session[fd]->wdata_size == 0)
- return 0; // nothing to send
+ if( session[fd]->wdata_size == 0 )
+ return 0; // nothing to send
- len = sSend(fd, (const char *) session[fd]->wdata, (int)session[fd]->wdata_size, MSG_NOSIGNAL);
+ len = sSend(fd, (const char *) session[fd]->wdata, (int)session[fd]->wdata_size, MSG_NOSIGNAL);
- if (len == SOCKET_ERROR) {
- //An exception has occured
- if (sErrno != S_EWOULDBLOCK) {
- //ShowDebug("send_from_fifo: %s, ending connection #%d\n", error_msg(), fd);
- session[fd]->wdata_size = 0; //Clear the send queue as we can't send anymore. [Skotlex]
- set_eof(fd);
- }
- return 0;
- }
+ if( len == SOCKET_ERROR )
+ {//An exception has occured
+ if( sErrno != S_EWOULDBLOCK ) {
+ //ShowDebug("send_from_fifo: %s, ending connection #%d\n", error_msg(), fd);
+ session[fd]->wdata_size = 0; //Clear the send queue as we can't send anymore. [Skotlex]
+ set_eof(fd);
+ }
+ return 0;
+ }
- if (len > 0) {
- // some data could not be transferred?
- // shift unsent data to the beginning of the queue
- if ((size_t)len < session[fd]->wdata_size)
- memmove(session[fd]->wdata, session[fd]->wdata + len, session[fd]->wdata_size - len);
+ if( len > 0 )
+ {
+ // some data could not be transferred?
+ // shift unsent data to the beginning of the queue
+ if( (size_t)len < session[fd]->wdata_size )
+ memmove(session[fd]->wdata, session[fd]->wdata + len, session[fd]->wdata_size - len);
- session[fd]->wdata_size -= len;
- }
+ session[fd]->wdata_size -= len;
+ }
- return 0;
+ return 0;
}
/// Best effort - there's no warranty that the data will be sent.
void flush_fifo(int fd)
{
- if (session[fd] != NULL)
- session[fd]->func_send(fd);
+ if(session[fd] != NULL)
+ session[fd]->func_send(fd);
}
void flush_fifos(void)
{
- int i;
- for (i = 1; i < fd_max; i++)
- flush_fifo(i);
+ int i;
+ for(i = 1; i < fd_max; i++)
+ flush_fifo(i);
}
/*======================================
- * CORE : Connection functions
+ * CORE : Connection functions
*--------------------------------------*/
int connect_client(int listen_fd)
{
- int fd;
- struct sockaddr_in client_address;
- socklen_t len;
-
- len = sizeof(client_address);
-
- fd = sAccept(listen_fd, (struct sockaddr *)&client_address, &len);
- if (fd == -1) {
- ShowError("connect_client: accept failed (%s)!\n", error_msg());
- return -1;
- }
- if (fd == 0) {
- // reserved
- ShowError("connect_client: Socket #0 is reserved - Please report this!!!\n");
- sClose(fd);
- return -1;
- }
- if (fd >= FD_SETSIZE) {
- // socket number too big
- ShowError("connect_client: New socket #%d is greater than can we handle! Increase the value of FD_SETSIZE (currently %d) for your OS to fix this!\n", fd, FD_SETSIZE);
- sClose(fd);
- return -1;
- }
-
- setsocketopts(fd);
- set_nonblocking(fd, 1);
+ int fd;
+ struct sockaddr_in client_address;
+ socklen_t len;
+
+ len = sizeof(client_address);
+
+ fd = sAccept(listen_fd, (struct sockaddr*)&client_address, &len);
+ if ( fd == -1 ) {
+ ShowError("connect_client: accept failed (%s)!\n", error_msg());
+ return -1;
+ }
+ if( fd == 0 )
+ {// reserved
+ ShowError("connect_client: Socket #0 is reserved - Please report this!!!\n");
+ sClose(fd);
+ return -1;
+ }
+ if( fd >= FD_SETSIZE )
+ {// socket number too big
+ ShowError("connect_client: New socket #%d is greater than can we handle! Increase the value of FD_SETSIZE (currently %d) for your OS to fix this!\n", fd, FD_SETSIZE);
+ sClose(fd);
+ return -1;
+ }
+
+ setsocketopts(fd);
+ set_nonblocking(fd, 1);
#ifndef MINICORE
- if (ip_rules && !connect_check(ntohl(client_address.sin_addr.s_addr))) {
- do_close(fd);
- return -1;
- }
+ if( ip_rules && !connect_check(ntohl(client_address.sin_addr.s_addr)) ) {
+ do_close(fd);
+ return -1;
+ }
#endif
- if (fd_max <= fd) fd_max = fd + 1;
- sFD_SET(fd,&readfds);
+ if( fd_max <= fd ) fd_max = fd + 1;
+ sFD_SET(fd,&readfds);
- create_session(fd, recv_to_fifo, send_from_fifo, default_func_parse);
- session[fd]->client_addr = ntohl(client_address.sin_addr.s_addr);
+ create_session(fd, recv_to_fifo, send_from_fifo, default_func_parse);
+ session[fd]->client_addr = ntohl(client_address.sin_addr.s_addr);
- return fd;
+ return fd;
}
int make_listen_bind(uint32 ip, uint16 port)
{
- struct sockaddr_in server_address;
- int fd;
- int result;
-
- fd = sSocket(AF_INET, SOCK_STREAM, 0);
-
- if (fd == -1) {
- ShowError("make_listen_bind: socket creation failed (%s)!\n", error_msg());
- exit(EXIT_FAILURE);
- }
- if (fd == 0) {
- // reserved
- ShowError("make_listen_bind: Socket #0 is reserved - Please report this!!!\n");
- sClose(fd);
- return -1;
- }
- if (fd >= FD_SETSIZE) {
- // socket number too big
- ShowError("make_listen_bind: New socket #%d is greater than can we handle! Increase the value of FD_SETSIZE (currently %d) for your OS to fix this!\n", fd, FD_SETSIZE);
- sClose(fd);
- return -1;
- }
-
- setsocketopts(fd);
- set_nonblocking(fd, 1);
-
- server_address.sin_family = AF_INET;
- server_address.sin_addr.s_addr = htonl(ip);
- server_address.sin_port = htons(port);
-
- result = sBind(fd, (struct sockaddr *)&server_address, sizeof(server_address));
- if (result == SOCKET_ERROR) {
- ShowError("make_listen_bind: bind failed (socket #%d, %s)!\n", fd, error_msg());
- exit(EXIT_FAILURE);
- }
- result = sListen(fd,5);
- if (result == SOCKET_ERROR) {
- ShowError("make_listen_bind: listen failed (socket #%d, %s)!\n", fd, error_msg());
- exit(EXIT_FAILURE);
- }
-
- if (fd_max <= fd) fd_max = fd + 1;
- sFD_SET(fd, &readfds);
-
- create_session(fd, connect_client, null_send, null_parse);
- session[fd]->client_addr = 0; // just listens
- session[fd]->rdata_tick = 0; // disable timeouts on this socket
-
- return fd;
+ struct sockaddr_in server_address;
+ int fd;
+ int result;
+
+ fd = sSocket(AF_INET, SOCK_STREAM, 0);
+
+ if( fd == -1 )
+ {
+ ShowError("make_listen_bind: socket creation failed (%s)!\n", error_msg());
+ exit(EXIT_FAILURE);
+ }
+ if( fd == 0 )
+ {// reserved
+ ShowError("make_listen_bind: Socket #0 is reserved - Please report this!!!\n");
+ sClose(fd);
+ return -1;
+ }
+ if( fd >= FD_SETSIZE )
+ {// socket number too big
+ ShowError("make_listen_bind: New socket #%d is greater than can we handle! Increase the value of FD_SETSIZE (currently %d) for your OS to fix this!\n", fd, FD_SETSIZE);
+ sClose(fd);
+ return -1;
+ }
+
+ setsocketopts(fd);
+ set_nonblocking(fd, 1);
+
+ server_address.sin_family = AF_INET;
+ server_address.sin_addr.s_addr = htonl(ip);
+ server_address.sin_port = htons(port);
+
+ result = sBind(fd, (struct sockaddr*)&server_address, sizeof(server_address));
+ if( result == SOCKET_ERROR ) {
+ ShowError("make_listen_bind: bind failed (socket #%d, %s)!\n", fd, error_msg());
+ exit(EXIT_FAILURE);
+ }
+ result = sListen(fd,5);
+ if( result == SOCKET_ERROR ) {
+ ShowError("make_listen_bind: listen failed (socket #%d, %s)!\n", fd, error_msg());
+ exit(EXIT_FAILURE);
+ }
+
+ if(fd_max <= fd) fd_max = fd + 1;
+ sFD_SET(fd, &readfds);
+
+ create_session(fd, connect_client, null_send, null_parse);
+ session[fd]->client_addr = 0; // just listens
+ session[fd]->rdata_tick = 0; // disable timeouts on this socket
+
+ return fd;
}
-int make_connection(uint32 ip, uint16 port, bool silent)
-{
- struct sockaddr_in remote_address;
- int fd;
- int result;
-
- fd = sSocket(AF_INET, SOCK_STREAM, 0);
-
- if (fd == -1) {
- ShowError("make_connection: socket creation failed (%s)!\n", error_msg());
- return -1;
- }
- if (fd == 0) {
- // reserved
- ShowError("make_connection: Socket #0 is reserved - Please report this!!!\n");
- sClose(fd);
- return -1;
- }
- if (fd >= FD_SETSIZE) {
- // socket number too big
- ShowError("make_connection: New socket #%d is greater than can we handle! Increase the value of FD_SETSIZE (currently %d) for your OS to fix this!\n", fd, FD_SETSIZE);
- sClose(fd);
- return -1;
- }
-
- setsocketopts(fd);
-
- remote_address.sin_family = AF_INET;
- remote_address.sin_addr.s_addr = htonl(ip);
- remote_address.sin_port = htons(port);
-
- if (!silent)
- ShowStatus("Connecting to %d.%d.%d.%d:%i\n", CONVIP(ip), port);
-
- result = sConnect(fd, (struct sockaddr *)(&remote_address), sizeof(struct sockaddr_in));
- if (result == SOCKET_ERROR) {
- if (!silent)
- ShowError("make_connection: connect failed (socket #%d, %s)!\n", fd, error_msg());
- do_close(fd);
- return -1;
- }
- //Now the socket can be made non-blocking. [Skotlex]
- set_nonblocking(fd, 1);
-
- if (fd_max <= fd) fd_max = fd + 1;
- sFD_SET(fd,&readfds);
-
- create_session(fd, recv_to_fifo, send_from_fifo, default_func_parse);
- session[fd]->client_addr = ntohl(remote_address.sin_addr.s_addr);
-
- return fd;
+int make_connection(uint32 ip, uint16 port, bool silent) {
+ struct sockaddr_in remote_address;
+ int fd;
+ int result;
+
+ fd = sSocket(AF_INET, SOCK_STREAM, 0);
+
+ if (fd == -1) {
+ ShowError("make_connection: socket creation failed (%s)!\n", error_msg());
+ return -1;
+ }
+ if( fd == 0 )
+ {// reserved
+ ShowError("make_connection: Socket #0 is reserved - Please report this!!!\n");
+ sClose(fd);
+ return -1;
+ }
+ if( fd >= FD_SETSIZE )
+ {// socket number too big
+ ShowError("make_connection: New socket #%d is greater than can we handle! Increase the value of FD_SETSIZE (currently %d) for your OS to fix this!\n", fd, FD_SETSIZE);
+ sClose(fd);
+ return -1;
+ }
+
+ setsocketopts(fd);
+
+ remote_address.sin_family = AF_INET;
+ remote_address.sin_addr.s_addr = htonl(ip);
+ remote_address.sin_port = htons(port);
+
+ if( !silent )
+ ShowStatus("Connecting to %d.%d.%d.%d:%i\n", CONVIP(ip), port);
+
+ result = sConnect(fd, (struct sockaddr *)(&remote_address), sizeof(struct sockaddr_in));
+ if( result == SOCKET_ERROR ) {
+ if( !silent )
+ ShowError("make_connection: connect failed (socket #%d, %s)!\n", fd, error_msg());
+ do_close(fd);
+ return -1;
+ }
+ //Now the socket can be made non-blocking. [Skotlex]
+ set_nonblocking(fd, 1);
+
+ if (fd_max <= fd) fd_max = fd + 1;
+ sFD_SET(fd,&readfds);
+
+ create_session(fd, recv_to_fifo, send_from_fifo, default_func_parse);
+ session[fd]->client_addr = ntohl(remote_address.sin_addr.s_addr);
+
+ return fd;
}
static int create_session(int fd, RecvFunc func_recv, SendFunc func_send, ParseFunc func_parse)
{
- CREATE(session[fd], struct socket_data, 1);
- CREATE(session[fd]->rdata, unsigned char, RFIFO_SIZE);
- CREATE(session[fd]->wdata, unsigned char, WFIFO_SIZE);
- session[fd]->max_rdata = RFIFO_SIZE;
- session[fd]->max_wdata = WFIFO_SIZE;
- session[fd]->func_recv = func_recv;
- session[fd]->func_send = func_send;
- session[fd]->func_parse = func_parse;
- session[fd]->rdata_tick = last_tick;
- return 0;
+ CREATE(session[fd], struct socket_data, 1);
+ CREATE(session[fd]->rdata, unsigned char, RFIFO_SIZE);
+ CREATE(session[fd]->wdata, unsigned char, WFIFO_SIZE);
+ session[fd]->max_rdata = RFIFO_SIZE;
+ session[fd]->max_wdata = WFIFO_SIZE;
+ session[fd]->func_recv = func_recv;
+ session[fd]->func_send = func_send;
+ session[fd]->func_parse = func_parse;
+ session[fd]->rdata_tick = last_tick;
+ return 0;
}
static void delete_session(int fd)
{
- if (session_isValid(fd)) {
- aFree(session[fd]->rdata);
- aFree(session[fd]->wdata);
- aFree(session[fd]->session_data);
- aFree(session[fd]);
- session[fd] = NULL;
- }
+ if( session_isValid(fd) )
+ {
+ aFree(session[fd]->rdata);
+ aFree(session[fd]->wdata);
+ aFree(session[fd]->session_data);
+ aFree(session[fd]);
+ session[fd] = NULL;
+ }
}
int realloc_fifo(int fd, unsigned int rfifo_size, unsigned int wfifo_size)
{
- if (!session_isValid(fd))
- return 0;
-
- if (session[fd]->max_rdata != rfifo_size && session[fd]->rdata_size < rfifo_size) {
- RECREATE(session[fd]->rdata, unsigned char, rfifo_size);
- session[fd]->max_rdata = rfifo_size;
- }
-
- if (session[fd]->max_wdata != wfifo_size && session[fd]->wdata_size < wfifo_size) {
- RECREATE(session[fd]->wdata, unsigned char, wfifo_size);
- session[fd]->max_wdata = wfifo_size;
- }
- return 0;
+ if( !session_isValid(fd) )
+ return 0;
+
+ if( session[fd]->max_rdata != rfifo_size && session[fd]->rdata_size < rfifo_size) {
+ RECREATE(session[fd]->rdata, unsigned char, rfifo_size);
+ session[fd]->max_rdata = rfifo_size;
+ }
+
+ if( session[fd]->max_wdata != wfifo_size && session[fd]->wdata_size < wfifo_size) {
+ RECREATE(session[fd]->wdata, unsigned char, wfifo_size);
+ session[fd]->max_wdata = wfifo_size;
+ }
+ return 0;
}
int realloc_writefifo(int fd, size_t addition)
{
- size_t newsize;
-
- if (!session_isValid(fd)) // might not happen
- return 0;
-
- if (session[fd]->wdata_size + addition > session[fd]->max_wdata) {
- // grow rule; grow in multiples of WFIFO_SIZE
- newsize = WFIFO_SIZE;
- while (session[fd]->wdata_size + addition > newsize) newsize += WFIFO_SIZE;
- } else if (session[fd]->max_wdata >= (size_t)2*(session[fd]->flag.server?FIFOSIZE_SERVERLINK:WFIFO_SIZE)
- && (session[fd]->wdata_size+addition)*4 < session[fd]->max_wdata) {
- // shrink rule, shrink by 2 when only a quarter of the fifo is used, don't shrink below nominal size.
- newsize = session[fd]->max_wdata / 2;
- } else // no change
- return 0;
-
- RECREATE(session[fd]->wdata, unsigned char, newsize);
- session[fd]->max_wdata = newsize;
-
- return 0;
+ size_t newsize;
+
+ if( !session_isValid(fd) ) // might not happen
+ return 0;
+
+ if( session[fd]->wdata_size + addition > session[fd]->max_wdata )
+ { // grow rule; grow in multiples of WFIFO_SIZE
+ newsize = WFIFO_SIZE;
+ while( session[fd]->wdata_size + addition > newsize ) newsize += WFIFO_SIZE;
+ }
+ else
+ if( session[fd]->max_wdata >= (size_t)2*(session[fd]->flag.server?FIFOSIZE_SERVERLINK:WFIFO_SIZE)
+ && (session[fd]->wdata_size+addition)*4 < session[fd]->max_wdata )
+ { // shrink rule, shrink by 2 when only a quarter of the fifo is used, don't shrink below nominal size.
+ newsize = session[fd]->max_wdata / 2;
+ }
+ else // no change
+ return 0;
+
+ RECREATE(session[fd]->wdata, unsigned char, newsize);
+ session[fd]->max_wdata = newsize;
+
+ return 0;
}
/// advance the RFIFO cursor (marking 'len' bytes as processed)
@@ -632,186 +629,197 @@ int RFIFOSKIP(int fd, size_t len)
{
struct socket_data *s;
- if (!session_isActive(fd))
- return 0;
+ if ( !session_isActive(fd) )
+ return 0;
- s = session[fd];
+ s = session[fd];
- if (s->rdata_size < s->rdata_pos + len) {
- ShowError("RFIFOSKIP: skipped past end of read buffer! Adjusting from %d to %d (session #%d)\n", len, RFIFOREST(fd), fd);
- len = RFIFOREST(fd);
- }
+ if ( s->rdata_size < s->rdata_pos + len ) {
+ ShowError("RFIFOSKIP: skipped past end of read buffer! Adjusting from %d to %d (session #%d)\n", len, RFIFOREST(fd), fd);
+ len = RFIFOREST(fd);
+ }
- s->rdata_pos = s->rdata_pos + len;
- return 0;
+ s->rdata_pos = s->rdata_pos + len;
+ return 0;
}
/// advance the WFIFO cursor (marking 'len' bytes for sending)
int WFIFOSET(int fd, size_t len)
{
- size_t newreserve;
- struct socket_data *s = session[fd];
-
- if (!session_isValid(fd) || s->wdata == NULL)
- return 0;
-
- // we have written len bytes to the buffer already before calling WFIFOSET
- if (s->wdata_size+len > s->max_wdata) {
- // actually there was a buffer overflow already
- uint32 ip = s->client_addr;
- ShowFatalError("WFIFOSET: Write Buffer Overflow. Connection %d (%d.%d.%d.%d) has written %u bytes on a %u/%u bytes buffer.\n", fd, CONVIP(ip), (unsigned int)len, (unsigned int)s->wdata_size, (unsigned int)s->max_wdata);
- ShowDebug("Likely command that caused it: 0x%x\n", (*(uint16 *)(s->wdata + s->wdata_size)));
- // no other chance, make a better fifo model
- exit(EXIT_FAILURE);
- }
-
- if (len > 0xFFFF) {
- // dynamic packets allow up to UINT16_MAX bytes (<packet_id>.W <packet_len>.W ...)
- // all known fixed-size packets are within this limit, so use the same limit
- ShowFatalError("WFIFOSET: Packet 0x%x is too big. (len=%u, max=%u)\n", (*(uint16 *)(s->wdata + s->wdata_size)), (unsigned int)len, 0xFFFF);
- exit(EXIT_FAILURE);
- } else if (len == 0) {
- // abuses the fact, that the code that did WFIFOHEAD(fd,0), already wrote
- // the packet type into memory, even if it could have overwritten vital data
- // this can happen when a new packet was added on map-server, but packet len table was not updated
- ShowWarning("WFIFOSET: Attempted to send zero-length packet, most likely 0x%04x (please report this).\n", WFIFOW(fd,0));
- return 0;
- }
-
- if (!s->flag.server) {
-
- if (len > socket_max_client_packet) { // see declaration of socket_max_client_packet for details
- ShowError("WFIFOSET: Dropped too large client packet 0x%04x (length=%u, max=%u).\n", WFIFOW(fd,0), len, socket_max_client_packet);
- return 0;
- }
-
- if (s->wdata_size+len > WFIFO_MAX) { // reached maximum write fifo size
- ShowError("WFIFOSET: Maximum write buffer size for client connection %d exceeded, most likely caused by packet 0x%04x (len=%u, ip=%lu.%lu.%lu.%lu).\n", fd, WFIFOW(fd,0), len, CONVIP(s->client_addr));
- set_eof(fd);
- return 0;
- }
-
- }
- s->wdata_size += len;
- //If the interserver has 200% of its normal size full, flush the data.
- if (s->flag.server && s->wdata_size >= 2*FIFOSIZE_SERVERLINK)
- flush_fifo(fd);
-
- // always keep a WFIFO_SIZE reserve in the buffer
- // For inter-server connections, let the reserve be 1/4th of the link size.
- newreserve = s->flag.server ? FIFOSIZE_SERVERLINK / 4 : WFIFO_SIZE;
-
- // readjust the buffer to include the chosen reserve
- realloc_writefifo(fd, newreserve);
+ size_t newreserve;
+ struct socket_data* s = session[fd];
+
+ if( !session_isValid(fd) || s->wdata == NULL )
+ return 0;
+
+ // we have written len bytes to the buffer already before calling WFIFOSET
+ if(s->wdata_size+len > s->max_wdata)
+ { // actually there was a buffer overflow already
+ uint32 ip = s->client_addr;
+ ShowFatalError("WFIFOSET: Write Buffer Overflow. Connection %d (%d.%d.%d.%d) has written %u bytes on a %u/%u bytes buffer.\n", fd, CONVIP(ip), (unsigned int)len, (unsigned int)s->wdata_size, (unsigned int)s->max_wdata);
+ ShowDebug("Likely command that caused it: 0x%x\n", (*(uint16*)(s->wdata + s->wdata_size)));
+ // no other chance, make a better fifo model
+ exit(EXIT_FAILURE);
+ }
+
+ if( len > 0xFFFF )
+ {
+ // dynamic packets allow up to UINT16_MAX bytes (<packet_id>.W <packet_len>.W ...)
+ // all known fixed-size packets are within this limit, so use the same limit
+ ShowFatalError("WFIFOSET: Packet 0x%x is too big. (len=%u, max=%u)\n", (*(uint16*)(s->wdata + s->wdata_size)), (unsigned int)len, 0xFFFF);
+ exit(EXIT_FAILURE);
+ }
+ else if( len == 0 )
+ {
+ // abuses the fact, that the code that did WFIFOHEAD(fd,0), already wrote
+ // the packet type into memory, even if it could have overwritten vital data
+ // this can happen when a new packet was added on map-server, but packet len table was not updated
+ ShowWarning("WFIFOSET: Attempted to send zero-length packet, most likely 0x%04x (please report this).\n", WFIFOW(fd,0));
+ return 0;
+ }
+
+ if( !s->flag.server ) {
+
+ if( len > socket_max_client_packet ) {// see declaration of socket_max_client_packet for details
+ ShowError("WFIFOSET: Dropped too large client packet 0x%04x (length=%u, max=%u).\n", WFIFOW(fd,0), len, socket_max_client_packet);
+ return 0;
+ }
+
+ if( s->wdata_size+len > WFIFO_MAX ) {// reached maximum write fifo size
+ ShowError("WFIFOSET: Maximum write buffer size for client connection %d exceeded, most likely caused by packet 0x%04x (len=%u, ip=%lu.%lu.%lu.%lu).\n", fd, WFIFOW(fd,0), len, CONVIP(s->client_addr));
+ set_eof(fd);
+ return 0;
+ }
+
+ }
+ s->wdata_size += len;
+ //If the interserver has 200% of its normal size full, flush the data.
+ if( s->flag.server && s->wdata_size >= 2*FIFOSIZE_SERVERLINK )
+ flush_fifo(fd);
+
+ // always keep a WFIFO_SIZE reserve in the buffer
+ // For inter-server connections, let the reserve be 1/4th of the link size.
+ newreserve = s->flag.server ? FIFOSIZE_SERVERLINK / 4 : WFIFO_SIZE;
+
+ // readjust the buffer to include the chosen reserve
+ realloc_writefifo(fd, newreserve);
#ifdef SEND_SHORTLIST
- send_shortlist_add_fd(fd);
+ send_shortlist_add_fd(fd);
#endif
- return 0;
+ return 0;
}
int do_sockets(int next)
{
- fd_set rfd;
- struct timeval timeout;
- int ret,i;
+ fd_set rfd;
+ struct timeval timeout;
+ int ret,i;
- // PRESEND Timers are executed before do_sendrecv and can send packets and/or set sessions to eof.
- // Send remaining data and process client-side disconnects here.
+ // PRESEND Timers are executed before do_sendrecv and can send packets and/or set sessions to eof.
+ // Send remaining data and process client-side disconnects here.
#ifdef SEND_SHORTLIST
- send_shortlist_do_sends();
+ send_shortlist_do_sends();
#else
- for (i = 1; i < fd_max; i++) {
- if (!session[i])
- continue;
-
- if (session[i]->wdata_size)
- session[i]->func_send(i);
- }
+ for (i = 1; i < fd_max; i++)
+ {
+ if(!session[i])
+ continue;
+
+ if(session[i]->wdata_size)
+ session[i]->func_send(i);
+ }
#endif
- // can timeout until the next tick
- timeout.tv_sec = next/1000;
- timeout.tv_usec = next%1000*1000;
+ // can timeout until the next tick
+ timeout.tv_sec = next/1000;
+ timeout.tv_usec = next%1000*1000;
- memcpy(&rfd, &readfds, sizeof(rfd));
- ret = sSelect(fd_max, &rfd, NULL, NULL, &timeout);
+ memcpy(&rfd, &readfds, sizeof(rfd));
+ ret = sSelect(fd_max, &rfd, NULL, NULL, &timeout);
- if (ret == SOCKET_ERROR) {
- if (sErrno != S_EINTR) {
- ShowFatalError("do_sockets: select() failed, %s!\n", error_msg());
- exit(EXIT_FAILURE);
- }
- return 0; // interrupted by a signal, just loop and try again
- }
+ if( ret == SOCKET_ERROR )
+ {
+ if( sErrno != S_EINTR )
+ {
+ ShowFatalError("do_sockets: select() failed, %s!\n", error_msg());
+ exit(EXIT_FAILURE);
+ }
+ return 0; // interrupted by a signal, just loop and try again
+ }
- last_tick = time(NULL);
+ last_tick = time(NULL);
#if defined(WIN32)
- // on windows, enumerating all members of the fd_set is way faster if we access the internals
- for (i = 0; i < (int)rfd.fd_count; ++i) {
- int fd = sock2fd(rfd.fd_array[i]);
- if (session[fd])
- session[fd]->func_recv(fd);
- }
+ // on windows, enumerating all members of the fd_set is way faster if we access the internals
+ for( i = 0; i < (int)rfd.fd_count; ++i )
+ {
+ int fd = sock2fd(rfd.fd_array[i]);
+ if( session[fd] )
+ session[fd]->func_recv(fd);
+ }
#else
- // otherwise assume that the fd_set is a bit-array and enumerate it in a standard way
- for (i = 1; ret && i < fd_max; ++i) {
- if (sFD_ISSET(i,&rfd) && session[i]) {
- session[i]->func_recv(i);
- --ret;
- }
- }
+ // otherwise assume that the fd_set is a bit-array and enumerate it in a standard way
+ for( i = 1; ret && i < fd_max; ++i )
+ {
+ if(sFD_ISSET(i,&rfd) && session[i])
+ {
+ session[i]->func_recv(i);
+ --ret;
+ }
+ }
#endif
- // POSTSEND Send remaining data and handle eof sessions.
+ // POSTSEND Send remaining data and handle eof sessions.
#ifdef SEND_SHORTLIST
- send_shortlist_do_sends();
+ send_shortlist_do_sends();
#else
- for (i = 1; i < fd_max; i++) {
- if (!session[i])
- continue;
-
- if (session[i]->wdata_size)
- session[i]->func_send(i);
-
- if (session[i]->flag.eof) { //func_send can't free a session, this is safe.
- //Finally, even if there is no data to parse, connections signalled eof should be closed, so we call parse_func [Skotlex]
- session[i]->func_parse(i); //This should close the session immediately.
- }
- }
+ for (i = 1; i < fd_max; i++)
+ {
+ if(!session[i])
+ continue;
+
+ if(session[i]->wdata_size)
+ session[i]->func_send(i);
+
+ if(session[i]->flag.eof) //func_send can't free a session, this is safe.
+ { //Finally, even if there is no data to parse, connections signalled eof should be closed, so we call parse_func [Skotlex]
+ session[i]->func_parse(i); //This should close the session immediately.
+ }
+ }
#endif
- // parse input data on each socket
- for (i = 1; i < fd_max; i++) {
- if (!session[i])
- continue;
-
- if (session[i]->rdata_tick && DIFF_TICK(last_tick, session[i]->rdata_tick) > stall_time) {
- if (session[i]->flag.server) { /* server is special */
- if (session[i]->flag.ping != 2) /* only update if necessary otherwise it'd resend the ping unnecessarily */
- session[i]->flag.ping = 1;
- } else {
- ShowInfo("Session #%d timed out\n", i);
- set_eof(i);
- }
- }
-
- session[i]->func_parse(i);
-
- if (!session[i])
- continue;
-
- // after parse, check client's RFIFO size to know if there is an invalid packet (too big and not parsed)
- if (session[i]->rdata_size == RFIFO_SIZE && session[i]->max_rdata == RFIFO_SIZE) {
- set_eof(i);
- continue;
- }
- RFIFOFLUSH(i);
- }
-
- return 0;
+ // parse input data on each socket
+ for(i = 1; i < fd_max; i++)
+ {
+ if(!session[i])
+ continue;
+
+ if (session[i]->rdata_tick && DIFF_TICK(last_tick, session[i]->rdata_tick) > stall_time) {
+ if( session[i]->flag.server ) {/* server is special */
+ if( session[i]->flag.ping != 2 )/* only update if necessary otherwise it'd resend the ping unnecessarily */
+ session[i]->flag.ping = 1;
+ } else {
+ ShowInfo("Session #%d timed out\n", i);
+ set_eof(i);
+ }
+ }
+
+ session[i]->func_parse(i);
+
+ if(!session[i])
+ continue;
+
+ // after parse, check client's RFIFO size to know if there is an invalid packet (too big and not parsed)
+ if (session[i]->rdata_size == RFIFO_SIZE && session[i]->max_rdata == RFIFO_SIZE) {
+ set_eof(i);
+ continue;
+ }
+ RFIFOFLUSH(i);
+ }
+
+ return 0;
}
//////////////////////////////
@@ -820,26 +828,26 @@ int do_sockets(int next)
// IP rules and DDoS protection
typedef struct _connect_history {
- struct _connect_history *next;
- uint32 ip;
- uint32 tick;
- int count;
- unsigned ddos : 1;
+ struct _connect_history* next;
+ uint32 ip;
+ uint32 tick;
+ int count;
+ unsigned ddos : 1;
} ConnectHistory;
typedef struct _access_control {
- uint32 ip;
- uint32 mask;
+ uint32 ip;
+ uint32 mask;
} AccessControl;
enum _aco {
- ACO_DENY_ALLOW,
- ACO_ALLOW_DENY,
- ACO_MUTUAL_FAILURE
+ ACO_DENY_ALLOW,
+ ACO_ALLOW_DENY,
+ ACO_MUTUAL_FAILURE
};
-static AccessControl *access_allow = NULL;
-static AccessControl *access_deny = NULL;
+static AccessControl* access_allow = NULL;
+static AccessControl* access_deny = NULL;
static int access_order = ACO_DENY_ALLOW;
static int access_allownum = 0;
static int access_denynum = 0;
@@ -849,7 +857,7 @@ static int ddos_interval = 3*1000;
static int ddos_autoreset = 10*60*1000;
/// Connection history, an array of linked lists.
/// The array's index for any ip is ip&0xFFFF
-static ConnectHistory *connect_history[0x10000];
+static ConnectHistory* connect_history[0x10000];
static int connect_check_(uint32 ip);
@@ -857,11 +865,11 @@ static int connect_check_(uint32 ip);
/// @see connect_check_()
static int connect_check(uint32 ip)
{
- int result = connect_check_(ip);
- if (access_debug) {
- ShowInfo("connect_check: Connection from %d.%d.%d.%d %s\n", CONVIP(ip),result ? "allowed." : "denied!");
- }
- return result;
+ int result = connect_check_(ip);
+ if( access_debug ) {
+ ShowInfo("connect_check: Connection from %d.%d.%d.%d %s\n", CONVIP(ip),result ? "allowed." : "denied!");
+ }
+ return result;
}
/// Verifies if the IP can connect.
@@ -869,494 +877,504 @@ static int connect_check(uint32 ip)
/// 1 or 2 : Connection Accepted
static int connect_check_(uint32 ip)
{
- ConnectHistory *hist = connect_history[ip&0xFFFF];
- int i;
- int is_allowip = 0;
- int is_denyip = 0;
- int connect_ok = 0;
-
- // Search the allow list
- for (i=0; i < access_allownum; ++i) {
- if ((ip & access_allow[i].mask) == (access_allow[i].ip & access_allow[i].mask)) {
- if (access_debug) {
- ShowInfo("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;
- }
- }
- // Search the deny list
- for (i=0; i < access_denynum; ++i) {
- if ((ip & access_deny[i].mask) == (access_deny[i].ip & access_deny[i].mask)) {
- if (access_debug) {
- ShowInfo("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;
- }
- }
- // Decide connection status
- // 0 : Reject
- // 1 : Accept
- // 2 : Unconditional Accept (accepts even if flagged as DDoS)
- switch (access_order) {
- case ACO_DENY_ALLOW:
- default:
- if (is_denyip)
- connect_ok = 0; // Reject
- else if (is_allowip)
- connect_ok = 2; // Unconditional Accept
- else
- connect_ok = 1; // Accept
- break;
- case ACO_ALLOW_DENY:
- if (is_allowip)
- connect_ok = 2; // Unconditional Accept
- else if (is_denyip)
- connect_ok = 0; // Reject
- else
- connect_ok = 1; // Accept
- break;
- case ACO_MUTUAL_FAILURE:
- if (is_allowip && !is_denyip)
- connect_ok = 2; // Unconditional Accept
- else
- connect_ok = 0; // Reject
- break;
- }
-
- // Inspect connection history
- while (hist) {
- if (ip == hist->ip) {
- // IP found
- if (hist->ddos) {
- // flagged as DDoS
- return (connect_ok == 2 ? 1 : 0);
- } else if (DIFF_TICK(gettick(),hist->tick) < ddos_interval) {
- // connection within ddos_interval
- hist->tick = gettick();
- if (hist->count++ >= ddos_count) {
- // DDoS attack detected
- hist->ddos = 1;
- ShowWarning("connect_check: DDoS Attack detected from %d.%d.%d.%d!\n", CONVIP(ip));
- return (connect_ok == 2 ? 1 : 0);
- }
- return connect_ok;
- } else {
- // not within ddos_interval, clear data
- hist->tick = gettick();
- hist->count = 0;
- return connect_ok;
- }
- }
- hist = hist->next;
- }
- // IP not found, add to history
- CREATE(hist, ConnectHistory, 1);
- memset(hist, 0, sizeof(ConnectHistory));
- hist->ip = ip;
- hist->tick = gettick();
- hist->next = connect_history[ip&0xFFFF];
- connect_history[ip&0xFFFF] = hist;
- return connect_ok;
+ ConnectHistory* hist = connect_history[ip&0xFFFF];
+ int i;
+ int is_allowip = 0;
+ int is_denyip = 0;
+ int connect_ok = 0;
+
+ // Search the allow list
+ for( i=0; i < access_allownum; ++i ){
+ if( (ip & access_allow[i].mask) == (access_allow[i].ip & access_allow[i].mask) ){
+ if( access_debug ){
+ ShowInfo("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;
+ }
+ }
+ // Search the deny list
+ for( i=0; i < access_denynum; ++i ){
+ if( (ip & access_deny[i].mask) == (access_deny[i].ip & access_deny[i].mask) ){
+ if( access_debug ){
+ ShowInfo("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;
+ }
+ }
+ // Decide connection status
+ // 0 : Reject
+ // 1 : Accept
+ // 2 : Unconditional Accept (accepts even if flagged as DDoS)
+ switch(access_order) {
+ case ACO_DENY_ALLOW:
+ default:
+ if( is_denyip )
+ connect_ok = 0; // Reject
+ else if( is_allowip )
+ connect_ok = 2; // Unconditional Accept
+ else
+ connect_ok = 1; // Accept
+ break;
+ case ACO_ALLOW_DENY:
+ if( is_allowip )
+ connect_ok = 2; // Unconditional Accept
+ else if( is_denyip )
+ connect_ok = 0; // Reject
+ else
+ connect_ok = 1; // Accept
+ break;
+ case ACO_MUTUAL_FAILURE:
+ if( is_allowip && !is_denyip )
+ connect_ok = 2; // Unconditional Accept
+ else
+ connect_ok = 0; // Reject
+ break;
+ }
+
+ // Inspect connection history
+ while( hist ) {
+ if( ip == hist->ip )
+ {// IP found
+ if( hist->ddos )
+ {// flagged as DDoS
+ return (connect_ok == 2 ? 1 : 0);
+ } else if( DIFF_TICK(gettick(),hist->tick) < ddos_interval )
+ {// connection within ddos_interval
+ hist->tick = gettick();
+ if( hist->count++ >= ddos_count )
+ {// DDoS attack detected
+ hist->ddos = 1;
+ ShowWarning("connect_check: DDoS Attack detected from %d.%d.%d.%d!\n", CONVIP(ip));
+ return (connect_ok == 2 ? 1 : 0);
+ }
+ return connect_ok;
+ } else
+ {// not within ddos_interval, clear data
+ hist->tick = gettick();
+ hist->count = 0;
+ return connect_ok;
+ }
+ }
+ hist = hist->next;
+ }
+ // IP not found, add to history
+ CREATE(hist, ConnectHistory, 1);
+ memset(hist, 0, sizeof(ConnectHistory));
+ hist->ip = ip;
+ hist->tick = gettick();
+ hist->next = connect_history[ip&0xFFFF];
+ connect_history[ip&0xFFFF] = hist;
+ return connect_ok;
}
/// Timer function.
/// Deletes old connection history records.
static int connect_check_clear(int tid, unsigned int tick, int id, intptr_t data)
{
- int i;
- int clear = 0;
- int list = 0;
- ConnectHistory root;
- ConnectHistory *prev_hist;
- ConnectHistory *hist;
-
- for (i=0; i < 0x10000 ; ++i) {
- prev_hist = &root;
- root.next = hist = connect_history[i];
- while (hist) {
- if ((!hist->ddos && DIFF_TICK(tick,hist->tick) > ddos_interval*3) ||
- (hist->ddos && DIFF_TICK(tick,hist->tick) > ddos_autoreset)) {
- // Remove connection history
- prev_hist->next = hist->next;
- aFree(hist);
- hist = prev_hist->next;
- clear++;
- } else {
- prev_hist = hist;
- hist = hist->next;
- }
- list++;
- }
- connect_history[i] = root.next;
- }
- if (access_debug) {
- ShowInfo("connect_check_clear: Cleared %d of %d from IP list.\n", clear, list);
- }
- return list;
+ int i;
+ int clear = 0;
+ int list = 0;
+ ConnectHistory root;
+ ConnectHistory* prev_hist;
+ ConnectHistory* hist;
+
+ for( i=0; i < 0x10000 ; ++i ){
+ prev_hist = &root;
+ root.next = hist = connect_history[i];
+ while( hist ){
+ if( (!hist->ddos && DIFF_TICK(tick,hist->tick) > ddos_interval*3) ||
+ (hist->ddos && DIFF_TICK(tick,hist->tick) > ddos_autoreset) )
+ {// Remove connection history
+ prev_hist->next = hist->next;
+ aFree(hist);
+ hist = prev_hist->next;
+ clear++;
+ } else {
+ prev_hist = hist;
+ hist = hist->next;
+ }
+ list++;
+ }
+ connect_history[i] = root.next;
+ }
+ if( access_debug ){
+ ShowInfo("connect_check_clear: Cleared %d of %d from IP list.\n", clear, list);
+ }
+ return list;
}
/// Parses the ip address and mask and puts it into acc.
/// Returns 1 is successful, 0 otherwise.
-int access_ipmask(const char *str, AccessControl *acc)
+int access_ipmask(const char* str, AccessControl* acc)
{
- uint32 ip;
- uint32 mask;
- unsigned int a[4];
- unsigned int m[4];
- int n;
-
- if (strcmp(str,"all") == 0) {
- ip = 0;
- mask = 0;
- } else {
- if (((n=sscanf(str,"%u.%u.%u.%u/%u.%u.%u.%u",a,a+1,a+2,a+3,m,m+1,m+2,m+3)) != 8 && // not an ip + standard mask
- (n=sscanf(str,"%u.%u.%u.%u/%u",a,a+1,a+2,a+3,m)) != 5 && // not an ip + bit mask
- (n=sscanf(str,"%u.%u.%u.%u",a,a+1,a+2,a+3)) != 4) || // not an ip
- a[0] > 255 || a[1] > 255 || a[2] > 255 || a[3] > 255 || // invalid ip
- (n == 8 && (m[0] > 255 || m[1] > 255 || m[2] > 255 || m[3] > 255)) || // invalid standard mask
- (n == 5 && m[0] > 32)) { // invalid bit mask
- return 0;
- }
- ip = MAKEIP(a[0],a[1],a[2],a[3]);
- if (n == 8) {
- // standard mask
- mask = MAKEIP(m[0],m[1],m[2],m[3]);
- } else if (n == 5) {
- // bit mask
- mask = 0;
- while (m[0]) {
- mask = (mask >> 1) | 0x80000000;
- --m[0];
- }
- } else {
- // just this ip
- mask = 0xFFFFFFFF;
- }
- }
- if (access_debug) {
- ShowInfo("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;
+ uint32 ip;
+ uint32 mask;
+ unsigned int a[4];
+ unsigned int m[4];
+ int n;
+
+ if( strcmp(str,"all") == 0 ) {
+ ip = 0;
+ mask = 0;
+ } else {
+ if( ((n=sscanf(str,"%u.%u.%u.%u/%u.%u.%u.%u",a,a+1,a+2,a+3,m,m+1,m+2,m+3)) != 8 && // not an ip + standard mask
+ (n=sscanf(str,"%u.%u.%u.%u/%u",a,a+1,a+2,a+3,m)) != 5 && // not an ip + bit mask
+ (n=sscanf(str,"%u.%u.%u.%u",a,a+1,a+2,a+3)) != 4 ) || // not an ip
+ a[0] > 255 || a[1] > 255 || a[2] > 255 || a[3] > 255 || // invalid ip
+ (n == 8 && (m[0] > 255 || m[1] > 255 || m[2] > 255 || m[3] > 255)) || // invalid standard mask
+ (n == 5 && m[0] > 32) ){ // invalid bit mask
+ return 0;
+ }
+ ip = MAKEIP(a[0],a[1],a[2],a[3]);
+ if( n == 8 )
+ {// standard mask
+ mask = MAKEIP(m[0],m[1],m[2],m[3]);
+ } else if( n == 5 )
+ {// bit mask
+ mask = 0;
+ while( m[0] ){
+ mask = (mask >> 1) | 0x80000000;
+ --m[0];
+ }
+ } else
+ {// just this ip
+ mask = 0xFFFFFFFF;
+ }
+ }
+ if( access_debug ){
+ ShowInfo("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;
}
//////////////////////////////
#endif
//////////////////////////////
-int socket_config_read(const char *cfgName)
+int socket_config_read(const char* cfgName)
{
- char line[1024],w1[1024],w2[1024];
- FILE *fp;
-
- fp = fopen(cfgName, "r");
- if (fp == NULL) {
- ShowError("File not found: %s\n", cfgName);
- return 1;
- }
-
- while (fgets(line, sizeof(line), fp)) {
- if (line[0] == '/' && line[1] == '/')
- continue;
- if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) != 2)
- continue;
-
- if (!strcmpi(w1, "stall_time")) {
- stall_time = atoi(w2);
- if (stall_time < 3)
- stall_time = 3;/* a minimum is required to refrain it from killing itself */
- }
+ char line[1024],w1[1024],w2[1024];
+ FILE *fp;
+
+ fp = fopen(cfgName, "r");
+ if(fp == NULL) {
+ ShowError("File not found: %s\n", cfgName);
+ return 1;
+ }
+
+ while(fgets(line, sizeof(line), fp))
+ {
+ if(line[0] == '/' && line[1] == '/')
+ continue;
+ if(sscanf(line, "%[^:]: %[^\r\n]", w1, w2) != 2)
+ continue;
+
+ if (!strcmpi(w1, "stall_time")) {
+ stall_time = atoi(w2);
+ if( stall_time < 3 )
+ stall_time = 3;/* a minimum is required to refrain it from killing itself */
+ }
#ifndef MINICORE
- else if (!strcmpi(w1, "enable_ip_rules")) {
- ip_rules = config_switch(w2);
- } else if (!strcmpi(w1, "order")) {
- if (!strcmpi(w2, "deny,allow"))
- access_order = ACO_DENY_ALLOW;
- else if (!strcmpi(w2, "allow,deny"))
- access_order = ACO_ALLOW_DENY;
- else if (!strcmpi(w2, "mutual-failure"))
- access_order = ACO_MUTUAL_FAILURE;
- } else if (!strcmpi(w1, "allow")) {
- RECREATE(access_allow, AccessControl, access_allownum+1);
- if (access_ipmask(w2, &access_allow[access_allownum]))
- ++access_allownum;
- else
- ShowError("socket_config_read: Invalid ip or ip range '%s'!\n", line);
- } else if (!strcmpi(w1, "deny")) {
- RECREATE(access_deny, AccessControl, access_denynum+1);
- if (access_ipmask(w2, &access_deny[access_denynum]))
- ++access_denynum;
- else
- ShowError("socket_config_read: Invalid ip or ip range '%s'!\n", line);
- } 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"))
- access_debug = config_switch(w2);
- else if (!strcmpi(w1,"socket_max_client_packet"))
- socket_max_client_packet = strtoul(w2, NULL, 0);
+ else if (!strcmpi(w1, "enable_ip_rules")) {
+ ip_rules = config_switch(w2);
+ } else if (!strcmpi(w1, "order")) {
+ if (!strcmpi(w2, "deny,allow"))
+ access_order = ACO_DENY_ALLOW;
+ else if (!strcmpi(w2, "allow,deny"))
+ access_order = ACO_ALLOW_DENY;
+ else if (!strcmpi(w2, "mutual-failure"))
+ access_order = ACO_MUTUAL_FAILURE;
+ } else if (!strcmpi(w1, "allow")) {
+ RECREATE(access_allow, AccessControl, access_allownum+1);
+ if (access_ipmask(w2, &access_allow[access_allownum]))
+ ++access_allownum;
+ else
+ ShowError("socket_config_read: Invalid ip or ip range '%s'!\n", line);
+ } else if (!strcmpi(w1, "deny")) {
+ RECREATE(access_deny, AccessControl, access_denynum+1);
+ if (access_ipmask(w2, &access_deny[access_denynum]))
+ ++access_denynum;
+ else
+ ShowError("socket_config_read: Invalid ip or ip range '%s'!\n", line);
+ }
+ 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"))
+ access_debug = config_switch(w2);
+ else if (!strcmpi(w1,"socket_max_client_packet"))
+ socket_max_client_packet = strtoul(w2, NULL, 0);
#endif
- else if (!strcmpi(w1, "import"))
- socket_config_read(w2);
- else
- ShowWarning("Unknown setting '%s' in file %s\n", w1, cfgName);
- }
-
- fclose(fp);
- return 0;
+ else if (!strcmpi(w1, "import"))
+ socket_config_read(w2);
+ else
+ ShowWarning("Unknown setting '%s' in file %s\n", w1, cfgName);
+ }
+
+ fclose(fp);
+ return 0;
}
void socket_final(void)
{
- int i;
+ int i;
#ifndef MINICORE
- ConnectHistory *hist;
- ConnectHistory *next_hist;
-
- for (i=0; i < 0x10000; ++i) {
- hist = connect_history[i];
- while (hist) {
- next_hist = hist->next;
- aFree(hist);
- hist = next_hist;
- }
- }
- if (access_allow)
- aFree(access_allow);
- if (access_deny)
- aFree(access_deny);
+ ConnectHistory* hist;
+ ConnectHistory* next_hist;
+
+ for( i=0; i < 0x10000; ++i ){
+ hist = connect_history[i];
+ while( hist ){
+ next_hist = hist->next;
+ aFree(hist);
+ hist = next_hist;
+ }
+ }
+ if( access_allow )
+ aFree(access_allow);
+ if( access_deny )
+ aFree(access_deny);
#endif
- for (i = 1; i < fd_max; i++)
- if (session[i])
- do_close(i);
+ for( i = 1; i < fd_max; i++ )
+ if(session[i])
+ do_close(i);
- // session[0] ‚̃_ƒ~[ƒf[ƒ^‚ðíœ
- aFree(session[0]->rdata);
- aFree(session[0]->wdata);
- aFree(session[0]);
+ // session[0] ‚̃_ƒ~[ƒf[ƒ^‚ðíœ
+ aFree(session[0]->rdata);
+ aFree(session[0]->wdata);
+ aFree(session[0]);
}
/// Closes a socket.
void do_close(int fd)
{
- if (fd <= 0 ||fd >= FD_SETSIZE)
- return;// invalid
-
- flush_fifo(fd); // Try to send what's left (although it might not succeed since it's a nonblocking socket)
- sFD_CLR(fd, &readfds);// this needs to be done before closing the socket
- sShutdown(fd, SHUT_RDWR); // Disallow further reads/writes
- sClose(fd); // We don't really care if these closing functions return an error, we are just shutting down and not reusing this socket.
- if (session[fd]) delete_session(fd);
+ if( fd <= 0 ||fd >= FD_SETSIZE )
+ return;// invalid
+
+ flush_fifo(fd); // Try to send what's left (although it might not succeed since it's a nonblocking socket)
+ sFD_CLR(fd, &readfds);// this needs to be done before closing the socket
+ sShutdown(fd, SHUT_RDWR); // Disallow further reads/writes
+ sClose(fd); // We don't really care if these closing functions return an error, we are just shutting down and not reusing this socket.
+ if (session[fd]) delete_session(fd);
}
/// Retrieve local ips in host byte order.
/// Uses loopback is no address is found.
-int socket_getips(uint32 *ips, int max)
+int socket_getips(uint32* ips, int max)
{
- int num = 0;
+ int num = 0;
- if (ips == NULL || max <= 0)
- return 0;
+ if( ips == NULL || max <= 0 )
+ return 0;
#ifdef WIN32
- {
- char fullhost[255];
- u_long **a;
- struct hostent *hent;
-
- // XXX This should look up the local IP addresses in the registry
- // instead of calling gethostbyname. However, the way IP addresses
- // are stored in the registry is annoyingly complex, so I'll leave
- // this as T.B.D. [Meruru]
- if (gethostname(fullhost, sizeof(fullhost)) == SOCKET_ERROR) {
- ShowError("socket_getips: No hostname defined!\n");
- return 0;
- } else {
- hent = gethostbyname(fullhost);
- if (hent == NULL) {
- ShowError("socket_getips: Cannot resolve our own hostname to an IP address\n");
- return 0;
- }
- a = (u_long **)hent->h_addr_list;
- for (; a[num] != NULL && num < max; ++num)
- ips[num] = (uint32)ntohl(*a[num]);
- }
- }
+ {
+ char fullhost[255];
+ u_long** a;
+ struct hostent* hent;
+
+ // XXX This should look up the local IP addresses in the registry
+ // instead of calling gethostbyname. However, the way IP addresses
+ // are stored in the registry is annoyingly complex, so I'll leave
+ // this as T.B.D. [Meruru]
+ if( gethostname(fullhost, sizeof(fullhost)) == SOCKET_ERROR )
+ {
+ ShowError("socket_getips: No hostname defined!\n");
+ return 0;
+ }
+ else
+ {
+ hent = gethostbyname(fullhost);
+ if( hent == NULL ){
+ ShowError("socket_getips: Cannot resolve our own hostname to an IP address\n");
+ return 0;
+ }
+ a = (u_long**)hent->h_addr_list;
+ for( ; a[num] != NULL && num < max; ++num)
+ ips[num] = (uint32)ntohl(*a[num]);
+ }
+ }
#else // not WIN32
- {
- int pos;
- int fd;
- char buf[2*16*sizeof(struct ifreq)];
- struct ifconf ic;
- struct ifreq *ir;
- struct sockaddr_in *a;
- u_long ad;
-
- fd = sSocket(AF_INET, SOCK_STREAM, 0);
-
- memset(buf, 0x00, sizeof(buf));
-
- // The ioctl call will fail with Invalid Argument if there are more
- // interfaces than will fit in the buffer
- ic.ifc_len = sizeof(buf);
- ic.ifc_buf = buf;
- if (sIoctl(fd, SIOCGIFCONF, &ic) == -1) {
- ShowError("socket_getips: SIOCGIFCONF failed!\n");
- return 0;
- } else {
- for (pos=0; pos < ic.ifc_len && num < max;) {
- ir = (struct ifreq *)(buf+pos);
- a = (struct sockaddr_in *) &(ir->ifr_addr);
- if (a->sin_family == AF_INET) {
- ad = ntohl(a->sin_addr.s_addr);
- if (ad != INADDR_LOOPBACK && ad != INADDR_ANY)
- ips[num++] = (uint32)ad;
- }
-#if (defined(BSD) && BSD >= 199103) || defined(_AIX) || defined(__APPLE__)
- pos += ir->ifr_addr.sa_len + sizeof(ir->ifr_name);
-#else// not AIX or APPLE
- pos += sizeof(struct ifreq);
-#endif//not AIX or APPLE
- }
- }
- sClose(fd);
- }
+ {
+ int pos;
+ int fd;
+ char buf[2*16*sizeof(struct ifreq)];
+ struct ifconf ic;
+ struct ifreq* ir;
+ struct sockaddr_in* a;
+ u_long ad;
+
+ fd = sSocket(AF_INET, SOCK_STREAM, 0);
+
+ memset(buf, 0x00, sizeof(buf));
+
+ // The ioctl call will fail with Invalid Argument if there are more
+ // interfaces than will fit in the buffer
+ ic.ifc_len = sizeof(buf);
+ ic.ifc_buf = buf;
+ if( sIoctl(fd, SIOCGIFCONF, &ic) == -1 )
+ {
+ ShowError("socket_getips: SIOCGIFCONF failed!\n");
+ return 0;
+ }
+ else
+ {
+ for( pos=0; pos < ic.ifc_len && num < max; )
+ {
+ ir = (struct ifreq*)(buf+pos);
+ a = (struct sockaddr_in*) &(ir->ifr_addr);
+ if( a->sin_family == AF_INET ){
+ ad = ntohl(a->sin_addr.s_addr);
+ if( ad != INADDR_LOOPBACK && ad != INADDR_ANY )
+ ips[num++] = (uint32)ad;
+ }
+ #if (defined(BSD) && BSD >= 199103) || defined(_AIX) || defined(__APPLE__)
+ pos += ir->ifr_addr.sa_len + sizeof(ir->ifr_name);
+ #else// not AIX or APPLE
+ pos += sizeof(struct ifreq);
+ #endif//not AIX or APPLE
+ }
+ }
+ sClose(fd);
+ }
#endif // not W32
- // Use loopback if no ips are found
- if (num == 0)
- ips[num++] = (uint32)INADDR_LOOPBACK;
+ // Use loopback if no ips are found
+ if( num == 0 )
+ ips[num++] = (uint32)INADDR_LOOPBACK;
- return num;
+ return num;
}
void socket_init(void)
{
- char *SOCKET_CONF_FILENAME = "conf/packet_athena.conf";
- unsigned int rlim_cur = FD_SETSIZE;
+ char *SOCKET_CONF_FILENAME = "conf/packet_athena.conf";
+ unsigned int rlim_cur = FD_SETSIZE;
#ifdef WIN32
- {
- // Start up windows networking
- WSADATA wsaData;
- WORD wVersionRequested = MAKEWORD(2, 0);
- if (WSAStartup(wVersionRequested, &wsaData) != 0) {
- ShowError("socket_init: WinSock not available!\n");
- return;
- }
- if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0) {
- ShowError("socket_init: WinSock version mismatch (2.0 or compatible required)!\n");
- return;
- }
- }
+ {// Start up windows networking
+ WSADATA wsaData;
+ WORD wVersionRequested = MAKEWORD(2, 0);
+ if( WSAStartup(wVersionRequested, &wsaData) != 0 )
+ {
+ ShowError("socket_init: WinSock not available!\n");
+ return;
+ }
+ if( LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0 )
+ {
+ ShowError("socket_init: WinSock version mismatch (2.0 or compatible required)!\n");
+ return;
+ }
+ }
#elif defined(HAVE_SETRLIMIT) && !defined(CYGWIN)
- // NOTE: getrlimit and setrlimit have bogus behaviour in cygwin.
- // "Number of fds is virtually unlimited in cygwin" (sys/param.h)
- {
- // set socket limit to FD_SETSIZE
- struct rlimit rlp;
- if (0 == getrlimit(RLIMIT_NOFILE, &rlp)) {
- rlp.rlim_cur = FD_SETSIZE;
- if (0 != setrlimit(RLIMIT_NOFILE, &rlp)) {
- // failed, try setting the maximum too (permission to change system limits is required)
- rlp.rlim_max = FD_SETSIZE;
- if (0 != setrlimit(RLIMIT_NOFILE, &rlp)) {
- // failed
- const char *errmsg = error_msg();
- int rlim_ori;
- // set to maximum allowed
- getrlimit(RLIMIT_NOFILE, &rlp);
- rlim_ori = (int)rlp.rlim_cur;
- rlp.rlim_cur = rlp.rlim_max;
- setrlimit(RLIMIT_NOFILE, &rlp);
- // report limit
- getrlimit(RLIMIT_NOFILE, &rlp);
- rlim_cur = rlp.rlim_cur;
- ShowWarning("socket_init: failed to set socket limit to %d, setting to maximum allowed (original limit=%d, current limit=%d, maximum allowed=%d, %s).\n", FD_SETSIZE, rlim_ori, (int)rlp.rlim_cur, (int)rlp.rlim_max, errmsg);
- }
- }
- }
- }
+ // NOTE: getrlimit and setrlimit have bogus behaviour in cygwin.
+ // "Number of fds is virtually unlimited in cygwin" (sys/param.h)
+ {// set socket limit to FD_SETSIZE
+ struct rlimit rlp;
+ if( 0 == getrlimit(RLIMIT_NOFILE, &rlp) )
+ {
+ rlp.rlim_cur = FD_SETSIZE;
+ if( 0 != setrlimit(RLIMIT_NOFILE, &rlp) )
+ {// failed, try setting the maximum too (permission to change system limits is required)
+ rlp.rlim_max = FD_SETSIZE;
+ if( 0 != setrlimit(RLIMIT_NOFILE, &rlp) )
+ {// failed
+ const char *errmsg = error_msg();
+ int rlim_ori;
+ // set to maximum allowed
+ getrlimit(RLIMIT_NOFILE, &rlp);
+ rlim_ori = (int)rlp.rlim_cur;
+ rlp.rlim_cur = rlp.rlim_max;
+ setrlimit(RLIMIT_NOFILE, &rlp);
+ // report limit
+ getrlimit(RLIMIT_NOFILE, &rlp);
+ rlim_cur = rlp.rlim_cur;
+ ShowWarning("socket_init: failed to set socket limit to %d, setting to maximum allowed (original limit=%d, current limit=%d, maximum allowed=%d, %s).\n", FD_SETSIZE, rlim_ori, (int)rlp.rlim_cur, (int)rlp.rlim_max, errmsg);
+ }
+ }
+ }
+ }
#endif
- // Get initial local ips
- naddr_ = socket_getips(addr_,16);
+ // Get initial local ips
+ naddr_ = socket_getips(addr_,16);
- sFD_ZERO(&readfds);
+ sFD_ZERO(&readfds);
#if defined(SEND_SHORTLIST)
- memset(send_shortlist_set, 0, sizeof(send_shortlist_set));
+ memset(send_shortlist_set, 0, sizeof(send_shortlist_set));
#endif
- socket_config_read(SOCKET_CONF_FILENAME);
+ socket_config_read(SOCKET_CONF_FILENAME);
- // initialise last send-receive tick
- last_tick = time(NULL);
+ // initialise last send-receive tick
+ last_tick = time(NULL);
- // session[0] is now currently used for disconnected sessions of the map server, and as such,
- // should hold enough buffer (it is a vacuum so to speak) as it is never flushed. [Skotlex]
- create_session(0, null_recv, null_send, null_parse);
+ // session[0] is now currently used for disconnected sessions of the map server, and as such,
+ // should hold enough buffer (it is a vacuum so to speak) as it is never flushed. [Skotlex]
+ create_session(0, null_recv, null_send, null_parse);
#ifndef MINICORE
- // Delete old connection history every 5 minutes
- memset(connect_history, 0, sizeof(connect_history));
- add_timer_func_list(connect_check_clear, "connect_check_clear");
- add_timer_interval(gettick()+1000, connect_check_clear, 0, 0, 5*60*1000);
+ // Delete old connection history every 5 minutes
+ memset(connect_history, 0, sizeof(connect_history));
+ add_timer_func_list(connect_check_clear, "connect_check_clear");
+ add_timer_interval(gettick()+1000, connect_check_clear, 0, 0, 5*60*1000);
#endif
- ShowInfo("Server supports up to '"CL_WHITE"%u"CL_RESET"' concurrent connections.\n", rlim_cur);
+ ShowInfo("Server supports up to '"CL_WHITE"%u"CL_RESET"' concurrent connections.\n", rlim_cur);
}
bool session_isValid(int fd)
{
- return (fd > 0 && fd < FD_SETSIZE && session[fd] != NULL);
+ return ( fd > 0 && fd < FD_SETSIZE && session[fd] != NULL );
}
bool session_isActive(int fd)
{
- return (session_isValid(fd) && !session[fd]->flag.eof);
+ return ( session_isValid(fd) && !session[fd]->flag.eof );
}
// Resolves hostname into a numeric ip.
-uint32 host2ip(const char *hostname)
+uint32 host2ip(const char* hostname)
{
- struct hostent *h = gethostbyname(hostname);
- return (h != NULL) ? ntohl(*(uint32 *)h->h_addr) : 0;
+ struct hostent* h = gethostbyname(hostname);
+ return (h != NULL) ? ntohl(*(uint32*)h->h_addr) : 0;
}
// Converts a numeric ip into a dot-formatted string.
// Result is placed either into a user-provided buffer or a static system buffer.
-const char *ip2str(uint32 ip, char ip_str[16])
+const char* ip2str(uint32 ip, char ip_str[16])
{
- struct in_addr addr;
- addr.s_addr = htonl(ip);
- return (ip_str == NULL) ? inet_ntoa(addr) : strncpy(ip_str, inet_ntoa(addr), 16);
+ struct in_addr addr;
+ addr.s_addr = htonl(ip);
+ return (ip_str == NULL) ? inet_ntoa(addr) : strncpy(ip_str, inet_ntoa(addr), 16);
}
// Converts a dot-formatted ip string into a numeric ip.
-uint32 str2ip(const char *ip_str)
+uint32 str2ip(const char* ip_str)
{
- return ntohl(inet_addr(ip_str));
+ return ntohl(inet_addr(ip_str));
}
// Reorders bytes from network to little endian (Windows).
// Neccessary for sending port numbers to the RO client until Gravity notices that they forgot ntohs() calls.
uint16 ntows(uint16 netshort)
{
- return ((netshort & 0xFF) << 8) | ((netshort & 0xFF00) >> 8);
+ return ((netshort & 0xFF) << 8) | ((netshort & 0xFF00) >> 8);
}
#ifdef SEND_SHORTLIST
@@ -1364,70 +1382,75 @@ uint16 ntows(uint16 netshort)
// sending or eof handling.
void send_shortlist_add_fd(int fd)
{
- int i;
- int bit;
+ int i;
+ int bit;
- if (!session_isValid(fd))
- return;// out of range
+ if( !session_isValid(fd) )
+ return;// out of range
- i = fd/32;
- bit = fd%32;
+ i = fd/32;
+ bit = fd%32;
- if ((send_shortlist_set[i]>>bit)&1)
- return;// already in the list
+ if( (send_shortlist_set[i]>>bit)&1 )
+ return;// already in the list
- if (send_shortlist_count >= ARRAYLENGTH(send_shortlist_array)) {
- ShowDebug("send_shortlist_add_fd: shortlist is full, ignoring... (fd=%d shortlist.count=%d shortlist.length=%d)\n", fd, send_shortlist_count, ARRAYLENGTH(send_shortlist_array));
- return;
- }
+ if( send_shortlist_count >= ARRAYLENGTH(send_shortlist_array) )
+ {
+ ShowDebug("send_shortlist_add_fd: shortlist is full, ignoring... (fd=%d shortlist.count=%d shortlist.length=%d)\n", fd, send_shortlist_count, ARRAYLENGTH(send_shortlist_array));
+ return;
+ }
- // set the bit
- send_shortlist_set[i] |= 1<<bit;
- // Add to the end of the shortlist array.
- send_shortlist_array[send_shortlist_count++] = fd;
+ // set the bit
+ send_shortlist_set[i] |= 1<<bit;
+ // Add to the end of the shortlist array.
+ send_shortlist_array[send_shortlist_count++] = fd;
}
// Do pending network sends and eof handling from the shortlist.
void send_shortlist_do_sends()
{
- int i;
-
- for (i = send_shortlist_count-1; i >= 0; --i) {
- int fd = send_shortlist_array[i];
- int idx = fd/32;
- int bit = fd%32;
-
- // Remove fd from shortlist, move the last fd to the current position
- --send_shortlist_count;
- send_shortlist_array[i] = send_shortlist_array[send_shortlist_count];
- send_shortlist_array[send_shortlist_count] = 0;
-
- if (fd <= 0 || fd >= FD_SETSIZE) {
- ShowDebug("send_shortlist_do_sends: fd is out of range, corrupted memory? (fd=%d)\n", fd);
- continue;
- }
- if (((send_shortlist_set[idx]>>bit)&1) == 0) {
- ShowDebug("send_shortlist_do_sends: fd is not set, why is it in the shortlist? (fd=%d)\n", fd);
- continue;
- }
- send_shortlist_set[idx]&=~(1<<bit);// unset fd
- // If this session still exists, perform send operations on it and
- // check for the eof state.
- if (session[fd]) {
- // Send data
- if (session[fd]->wdata_size)
- session[fd]->func_send(fd);
-
- // If it's been marked as eof, call the parse func on it so that
- // the socket will be immediately closed.
- if (session[fd]->flag.eof)
- session[fd]->func_parse(fd);
-
- // If the session still exists, is not eof and has things left to
- // be sent from it we'll re-add it to the shortlist.
- if (session[fd] && !session[fd]->flag.eof && session[fd]->wdata_size)
- send_shortlist_add_fd(fd);
- }
- }
+ int i;
+
+ for( i = send_shortlist_count-1; i >= 0; --i )
+ {
+ int fd = send_shortlist_array[i];
+ int idx = fd/32;
+ int bit = fd%32;
+
+ // Remove fd from shortlist, move the last fd to the current position
+ --send_shortlist_count;
+ send_shortlist_array[i] = send_shortlist_array[send_shortlist_count];
+ send_shortlist_array[send_shortlist_count] = 0;
+
+ if( fd <= 0 || fd >= FD_SETSIZE )
+ {
+ ShowDebug("send_shortlist_do_sends: fd is out of range, corrupted memory? (fd=%d)\n", fd);
+ continue;
+ }
+ if( ((send_shortlist_set[idx]>>bit)&1) == 0 )
+ {
+ ShowDebug("send_shortlist_do_sends: fd is not set, why is it in the shortlist? (fd=%d)\n", fd);
+ continue;
+ }
+ send_shortlist_set[idx]&=~(1<<bit);// unset fd
+ // If this session still exists, perform send operations on it and
+ // check for the eof state.
+ if( session[fd] )
+ {
+ // Send data
+ if( session[fd]->wdata_size )
+ session[fd]->func_send(fd);
+
+ // If it's been marked as eof, call the parse func on it so that
+ // the socket will be immediately closed.
+ if( session[fd]->flag.eof )
+ session[fd]->func_parse(fd);
+
+ // If the session still exists, is not eof and has things left to
+ // be sent from it we'll re-add it to the shortlist.
+ if( session[fd] && !session[fd]->flag.eof && session[fd]->wdata_size )
+ send_shortlist_add_fd(fd);
+ }
+ }
}
#endif
diff --git a/src/common/socket.h b/src/common/socket.h
index 5c4008d62..7c0e02f5d 100644
--- a/src/common/socket.h
+++ b/src/common/socket.h
@@ -1,18 +1,18 @@
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder
-#ifndef _SOCKET_H_
+#ifndef _SOCKET_H_
#define _SOCKET_H_
#include "../common/cbasetypes.h"
#ifdef WIN32
-#include "../common/winapi.h"
-typedef long in_addr_t;
+ #include "../common/winapi.h"
+ typedef long in_addr_t;
#else
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
#endif
#include <time.h>
@@ -38,15 +38,15 @@ typedef long in_addr_t;
#define RFIFOREST(fd) (session[fd]->flag.eof ? 0 : session[fd]->rdata_size - session[fd]->rdata_pos)
#define RFIFOFLUSH(fd) \
- do { \
- if(session[fd]->rdata_size == session[fd]->rdata_pos){ \
- session[fd]->rdata_size = session[fd]->rdata_pos = 0; \
- } else { \
- session[fd]->rdata_size -= session[fd]->rdata_pos; \
- memmove(session[fd]->rdata, session[fd]->rdata+session[fd]->rdata_pos, session[fd]->rdata_size); \
- session[fd]->rdata_pos = 0; \
- } \
- } while(0)
+ do { \
+ if(session[fd]->rdata_size == session[fd]->rdata_pos){ \
+ session[fd]->rdata_size = session[fd]->rdata_pos = 0; \
+ } else { \
+ session[fd]->rdata_size -= session[fd]->rdata_pos; \
+ memmove(session[fd]->rdata, session[fd]->rdata+session[fd]->rdata_pos, session[fd]->rdata_size); \
+ session[fd]->rdata_pos = 0; \
+ } \
+ } while(0)
// buffer I/O macros
#define RBUFP(p,pos) (((uint8*)(p)) + (pos))
@@ -71,32 +71,33 @@ typedef int (*RecvFunc)(int fd);
typedef int (*SendFunc)(int fd);
typedef int (*ParseFunc)(int fd);
-struct socket_data {
- struct {
- unsigned char eof : 1;
- unsigned char server : 1;
- unsigned char ping : 2;
- } flag;
+struct socket_data
+{
+ struct {
+ unsigned char eof : 1;
+ unsigned char server : 1;
+ unsigned char ping : 2;
+ } flag;
- uint32 client_addr; // remote client address
+ uint32 client_addr; // remote client address
- uint8 *rdata, *wdata;
- size_t max_rdata, max_wdata;
- size_t rdata_size, wdata_size;
- size_t rdata_pos;
- time_t rdata_tick; // time of last recv (for detecting timeouts); zero when timeout is disabled
+ uint8 *rdata, *wdata;
+ size_t max_rdata, max_wdata;
+ size_t rdata_size, wdata_size;
+ size_t rdata_pos;
+ time_t rdata_tick; // time of last recv (for detecting timeouts); zero when timeout is disabled
- RecvFunc func_recv;
- SendFunc func_send;
- ParseFunc func_parse;
+ RecvFunc func_recv;
+ SendFunc func_send;
+ ParseFunc func_parse;
- void *session_data; // stores application-specific data related to the session
+ void* session_data; // stores application-specific data related to the session
};
// Data prototype declaration
-extern struct socket_data *session[FD_SETSIZE];
+extern struct socket_data* session[FD_SETSIZE];
extern int fd_max;
@@ -130,21 +131,21 @@ extern void set_nonblocking(int fd, unsigned long yes);
void set_defaultparse(ParseFunc defaultparse);
// hostname/ip conversion functions
-uint32 host2ip(const char *hostname);
-const char *ip2str(uint32 ip, char ip_str[16]);
-uint32 str2ip(const char *ip_str);
+uint32 host2ip(const char* hostname);
+const char* ip2str(uint32 ip, char ip_str[16]);
+uint32 str2ip(const char* ip_str);
#define CONVIP(ip) ((ip)>>24)&0xFF,((ip)>>16)&0xFF,((ip)>>8)&0xFF,((ip)>>0)&0xFF
#define MAKEIP(a,b,c,d) (uint32)( ( ( (a)&0xFF ) << 24 ) | ( ( (b)&0xFF ) << 16 ) | ( ( (c)&0xFF ) << 8 ) | ( ( (d)&0xFF ) << 0 ) )
uint16 ntows(uint16 netshort);
-int socket_getips(uint32 *ips, int max);
+int socket_getips(uint32* ips, int max);
extern uint32 addr_[16]; // ip addresses of local host (host byte order)
extern int naddr_; // # of ip addresses
void set_eof(int fd);
-/// Use a shortlist of sockets instead of iterating all sessions for sockets
+/// Use a shortlist of sockets instead of iterating all sessions for sockets
/// that have data to send or need eof handling.
/// Adapted to use a static array instead of a linked list.
///
diff --git a/src/common/spinlock.h b/src/common/spinlock.h
index 8d1624b33..3419bfdd5 100644
--- a/src/common/spinlock.h
+++ b/src/common/spinlock.h
@@ -14,7 +14,7 @@
// For more information, see LICENCE in the main folder
//
//
-
+
#ifdef WIN32
#include "../common/winapi.h"
#endif
@@ -25,81 +25,77 @@
#ifdef WIN32
-typedef struct __declspec(align(64)) SPIN_LOCK {
- volatile LONG lock;
- volatile LONG nest;
- volatile LONG sync_lock;
+typedef struct __declspec( align(64) ) SPIN_LOCK{
+ volatile LONG lock;
+ volatile LONG nest;
+ volatile LONG sync_lock;
} SPIN_LOCK, *PSPIN_LOCK;
#else
-typedef struct SPIN_LOCK {
- volatile int32 lock;
- volatile int32 nest; // nesting level.
-
- volatile int32 sync_lock;
+typedef struct SPIN_LOCK{
+ volatile int32 lock;
+ volatile int32 nest; // nesting level.
+
+ volatile int32 sync_lock;
} __attribute__((aligned(64))) SPIN_LOCK, *PSPIN_LOCK;
#endif
-static forceinline void InitializeSpinLock(PSPIN_LOCK lck)
-{
- lck->lock = 0;
- lck->nest = 0;
- lck->sync_lock = 0;
+static forceinline void InitializeSpinLock(PSPIN_LOCK lck){
+ lck->lock = 0;
+ lck->nest = 0;
+ lck->sync_lock = 0;
}
-static forceinline void FinalizeSpinLock(PSPIN_LOCK lck)
-{
- return;
+static forceinline void FinalizeSpinLock(PSPIN_LOCK lck){
+ return;
}
#define getsynclock(l) { while(1){ if(InterlockedCompareExchange(l, 1, 0) == 0) break; rathread_yield(); } }
#define dropsynclock(l) { InterlockedExchange(l, 0); }
-static forceinline void EnterSpinLock(PSPIN_LOCK lck)
-{
- int tid = rathread_get_tid();
-
- // Get Sync Lock && Check if the requester thread already owns the lock.
- // if it owns, increase nesting level
- getsynclock(&lck->sync_lock);
- if (InterlockedCompareExchange(&lck->lock, tid, tid) == tid) {
- InterlockedIncrement(&lck->nest);
- dropsynclock(&lck->sync_lock);
- return; // Got Lock
- }
- // drop sync lock
- dropsynclock(&lck->sync_lock);
-
-
- // Spin until we've got it !
- while (1) {
-
- if (InterlockedCompareExchange(&lck->lock, tid, 0) == 0) {
-
- InterlockedIncrement(&lck->nest);
- return; // Got Lock
- }
-
- rathread_yield(); // Force ctxswitch to another thread.
- }
+static forceinline void EnterSpinLock(PSPIN_LOCK lck){
+ int tid = rathread_get_tid();
+
+ // Get Sync Lock && Check if the requester thread already owns the lock.
+ // if it owns, increase nesting level
+ getsynclock(&lck->sync_lock);
+ if(InterlockedCompareExchange(&lck->lock, tid, tid) == tid){
+ InterlockedIncrement(&lck->nest);
+ dropsynclock(&lck->sync_lock);
+ return; // Got Lock
+ }
+ // drop sync lock
+ dropsynclock(&lck->sync_lock);
+
+
+ // Spin until we've got it !
+ while(1){
+
+ if(InterlockedCompareExchange(&lck->lock, tid, 0) == 0){
+
+ InterlockedIncrement(&lck->nest);
+ return; // Got Lock
+ }
+
+ rathread_yield(); // Force ctxswitch to another thread.
+ }
}
-static forceinline void LeaveSpinLock(PSPIN_LOCK lck)
-{
- int tid = rathread_get_tid();
-
- getsynclock(&lck->sync_lock);
-
- if (InterlockedCompareExchange(&lck->lock, tid, tid) == tid) { // this thread owns the lock.
- if (InterlockedDecrement(&lck->nest) == 0)
- InterlockedExchange(&lck->lock, 0); // Unlock!
- }
+static forceinline void LeaveSpinLock(PSPIN_LOCK lck){
+ int tid = rathread_get_tid();
- dropsynclock(&lck->sync_lock);
+ getsynclock(&lck->sync_lock);
+
+ if(InterlockedCompareExchange(&lck->lock, tid, tid) == tid){ // this thread owns the lock.
+ if(InterlockedDecrement(&lck->nest) == 0)
+ InterlockedExchange(&lck->lock, 0); // Unlock!
+ }
+
+ dropsynclock(&lck->sync_lock);
}
diff --git a/src/common/sql.c b/src/common/sql.c
index 740da476d..800aa89b0 100644
--- a/src/common/sql.c
+++ b/src/common/sql.c
@@ -18,38 +18,41 @@
/// Sql handle
-struct Sql {
- StringBuf buf;
- MYSQL handle;
- MYSQL_RES *result;
- MYSQL_ROW row;
- unsigned long *lengths;
- int keepalive;
+struct Sql
+{
+ StringBuf buf;
+ MYSQL handle;
+ MYSQL_RES* result;
+ MYSQL_ROW row;
+ unsigned long* lengths;
+ int keepalive;
};
// Column length receiver.
// Takes care of the possible size missmatch between uint32 and unsigned long.
-struct s_column_length {
- uint32 *out_length;
- unsigned long length;
+struct s_column_length
+{
+ uint32* out_length;
+ unsigned long length;
};
typedef struct s_column_length s_column_length;
/// Sql statement
-struct SqlStmt {
- StringBuf buf;
- MYSQL_STMT *stmt;
- MYSQL_BIND *params;
- MYSQL_BIND *columns;
- s_column_length *column_lengths;
- size_t max_params;
- size_t max_columns;
- bool bind_params;
- bool bind_columns;
+struct SqlStmt
+{
+ StringBuf buf;
+ MYSQL_STMT* stmt;
+ MYSQL_BIND* params;
+ MYSQL_BIND* columns;
+ s_column_length* column_lengths;
+ size_t max_params;
+ size_t max_columns;
+ bool bind_params;
+ bool bind_columns;
};
@@ -61,111 +64,117 @@ struct SqlStmt {
/// Allocates and initializes a new Sql handle.
-Sql *Sql_Malloc(void)
+Sql* Sql_Malloc(void)
{
- Sql *self;
+ Sql* self;
- CREATE(self, Sql, 1);
- mysql_init(&self->handle);
- StringBuf_Init(&self->buf);
- self->lengths = NULL;
- self->result = NULL;
- self->keepalive = INVALID_TIMER;
+ CREATE(self, Sql, 1);
+ mysql_init(&self->handle);
+ StringBuf_Init(&self->buf);
+ self->lengths = NULL;
+ self->result = NULL;
+ self->keepalive = INVALID_TIMER;
- return self;
+ return self;
}
-static int Sql_P_Keepalive(Sql *self);
+static int Sql_P_Keepalive(Sql* self);
/// Establishes a connection.
-int Sql_Connect(Sql *self, const char *user, const char *passwd, const char *host, uint16 port, const char *db)
+int Sql_Connect(Sql* self, const char* user, const char* passwd, const char* host, uint16 port, const char* db)
{
- if (self == NULL)
- return SQL_ERROR;
+ if( self == NULL )
+ return SQL_ERROR;
- StringBuf_Clear(&self->buf);
- if (!mysql_real_connect(&self->handle, host, user, passwd, db, (unsigned int)port, NULL/*unix_socket*/, 0/*clientflag*/)) {
- ShowSQL("%s\n", mysql_error(&self->handle));
- return SQL_ERROR;
- }
+ StringBuf_Clear(&self->buf);
+ if( !mysql_real_connect(&self->handle, host, user, passwd, db, (unsigned int)port, NULL/*unix_socket*/, 0/*clientflag*/) )
+ {
+ ShowSQL("%s\n", mysql_error(&self->handle));
+ return SQL_ERROR;
+ }
- self->keepalive = Sql_P_Keepalive(self);
- if (self->keepalive == INVALID_TIMER) {
- ShowSQL("Failed to establish keepalive for DB connection!\n");
- return SQL_ERROR;
- }
+ self->keepalive = Sql_P_Keepalive(self);
+ if( self->keepalive == INVALID_TIMER )
+ {
+ ShowSQL("Failed to establish keepalive for DB connection!\n");
+ return SQL_ERROR;
+ }
- return SQL_SUCCESS;
+ return SQL_SUCCESS;
}
/// Retrieves the timeout of the connection.
-int Sql_GetTimeout(Sql *self, uint32 *out_timeout)
+int Sql_GetTimeout(Sql* self, uint32* out_timeout)
{
- if (self && out_timeout && SQL_SUCCESS == Sql_Query(self, "SHOW VARIABLES LIKE 'wait_timeout'")) {
- char *data;
- size_t len;
- if (SQL_SUCCESS == Sql_NextRow(self) &&
- SQL_SUCCESS == Sql_GetData(self, 1, &data, &len)) {
- *out_timeout = (uint32)strtoul(data, NULL, 10);
- Sql_FreeResult(self);
- return SQL_SUCCESS;
- }
- Sql_FreeResult(self);
- }
- return SQL_ERROR;
+ if( self && out_timeout && SQL_SUCCESS == Sql_Query(self, "SHOW VARIABLES LIKE 'wait_timeout'") )
+ {
+ char* data;
+ size_t len;
+ if( SQL_SUCCESS == Sql_NextRow(self) &&
+ SQL_SUCCESS == Sql_GetData(self, 1, &data, &len) )
+ {
+ *out_timeout = (uint32)strtoul(data, NULL, 10);
+ Sql_FreeResult(self);
+ return SQL_SUCCESS;
+ }
+ Sql_FreeResult(self);
+ }
+ return SQL_ERROR;
}
/// Retrieves the name of the columns of a table into out_buf, with the separator after each name.
-int Sql_GetColumnNames(Sql *self, const char *table, char *out_buf, size_t buf_len, char sep)
+int Sql_GetColumnNames(Sql* self, const char* table, char* out_buf, size_t buf_len, char sep)
{
- char *data;
- size_t len;
- size_t off = 0;
+ char* data;
+ size_t len;
+ size_t off = 0;
- if (self == NULL || SQL_ERROR == Sql_Query(self, "EXPLAIN `%s`", table))
- return SQL_ERROR;
+ if( self == NULL || SQL_ERROR == Sql_Query(self, "EXPLAIN `%s`", table) )
+ return SQL_ERROR;
- out_buf[off] = '\0';
- while (SQL_SUCCESS == Sql_NextRow(self) && SQL_SUCCESS == Sql_GetData(self, 0, &data, &len)) {
- len = strnlen(data, len);
- if (off + len + 2 > buf_len) {
- ShowDebug("Sql_GetColumns: output buffer is too small\n");
- *out_buf = '\0';
- return SQL_ERROR;
- }
- memcpy(out_buf+off, data, len);
- off += len;
- out_buf[off++] = sep;
- }
- out_buf[off] = '\0';
- Sql_FreeResult(self);
- return SQL_SUCCESS;
+ out_buf[off] = '\0';
+ while( SQL_SUCCESS == Sql_NextRow(self) && SQL_SUCCESS == Sql_GetData(self, 0, &data, &len) )
+ {
+ len = strnlen(data, len);
+ if( off + len + 2 > buf_len )
+ {
+ ShowDebug("Sql_GetColumns: output buffer is too small\n");
+ *out_buf = '\0';
+ return SQL_ERROR;
+ }
+ memcpy(out_buf+off, data, len);
+ off += len;
+ out_buf[off++] = sep;
+ }
+ out_buf[off] = '\0';
+ Sql_FreeResult(self);
+ return SQL_SUCCESS;
}
/// Changes the encoding of the connection.
-int Sql_SetEncoding(Sql *self, const char *encoding)
+int Sql_SetEncoding(Sql* self, const char* encoding)
{
- if (self && mysql_set_character_set(&self->handle, encoding) == 0)
- return SQL_SUCCESS;
- return SQL_ERROR;
+ if( self && mysql_set_character_set(&self->handle, encoding) == 0 )
+ return SQL_SUCCESS;
+ return SQL_ERROR;
}
/// Pings the connection.
-int Sql_Ping(Sql *self)
+int Sql_Ping(Sql* self)
{
- if (self && mysql_ping(&self->handle) == 0)
- return SQL_SUCCESS;
- return SQL_ERROR;
+ if( self && mysql_ping(&self->handle) == 0 )
+ return SQL_SUCCESS;
+ return SQL_ERROR;
}
@@ -175,10 +184,10 @@ int Sql_Ping(Sql *self)
/// @private
static int Sql_P_KeepaliveTimer(int tid, unsigned int tick, int id, intptr_t data)
{
- Sql *self = (Sql *)data;
- ShowInfo("Pinging SQL server to keep connection alive...\n");
- Sql_Ping(self);
- return 0;
+ Sql* self = (Sql*)data;
+ ShowInfo("Pinging SQL server to keep connection alive...\n");
+ Sql_Ping(self);
+ return 0;
}
@@ -187,213 +196,224 @@ static int Sql_P_KeepaliveTimer(int tid, unsigned int tick, int id, intptr_t dat
///
/// @return the keepalive timer id, or INVALID_TIMER
/// @private
-static int Sql_P_Keepalive(Sql *self)
+static int Sql_P_Keepalive(Sql* self)
{
- uint32 timeout, ping_interval;
+ uint32 timeout, ping_interval;
- // set a default value first
- timeout = 28800; // 8 hours
+ // set a default value first
+ timeout = 28800; // 8 hours
- // request the timeout value from the mysql server
- Sql_GetTimeout(self, &timeout);
+ // request the timeout value from the mysql server
+ Sql_GetTimeout(self, &timeout);
- if (timeout < 60)
- timeout = 60;
+ if( timeout < 60 )
+ timeout = 60;
- // establish keepalive
- ping_interval = timeout - 30; // 30-second reserve
- //add_timer_func_list(Sql_P_KeepaliveTimer, "Sql_P_KeepaliveTimer");
- return add_timer_interval(gettick() + ping_interval*1000, Sql_P_KeepaliveTimer, 0, (intptr_t)self, ping_interval*1000);
+ // establish keepalive
+ ping_interval = timeout - 30; // 30-second reserve
+ //add_timer_func_list(Sql_P_KeepaliveTimer, "Sql_P_KeepaliveTimer");
+ return add_timer_interval(gettick() + ping_interval*1000, Sql_P_KeepaliveTimer, 0, (intptr_t)self, ping_interval*1000);
}
/// Escapes a string.
-size_t Sql_EscapeString(Sql *self, char *out_to, const char *from)
+size_t Sql_EscapeString(Sql* self, char *out_to, const char *from)
{
- if (self)
- return (size_t)mysql_real_escape_string(&self->handle, out_to, from, (unsigned long)strlen(from));
- else
- return (size_t)mysql_escape_string(out_to, from, (unsigned long)strlen(from));
+ if( self )
+ return (size_t)mysql_real_escape_string(&self->handle, out_to, from, (unsigned long)strlen(from));
+ else
+ return (size_t)mysql_escape_string(out_to, from, (unsigned long)strlen(from));
}
/// Escapes a string.
-size_t Sql_EscapeStringLen(Sql *self, char *out_to, const char *from, size_t from_len)
+size_t Sql_EscapeStringLen(Sql* self, char *out_to, const char *from, size_t from_len)
{
- if (self)
- return (size_t)mysql_real_escape_string(&self->handle, out_to, from, (unsigned long)from_len);
- else
- return (size_t)mysql_escape_string(out_to, from, (unsigned long)from_len);
+ if( self )
+ return (size_t)mysql_real_escape_string(&self->handle, out_to, from, (unsigned long)from_len);
+ else
+ return (size_t)mysql_escape_string(out_to, from, (unsigned long)from_len);
}
/// Executes a query.
-int Sql_Query(Sql *self, const char *query, ...)
+int Sql_Query(Sql* self, const char* query, ...)
{
- int res;
- va_list args;
+ int res;
+ va_list args;
- va_start(args, query);
- res = Sql_QueryV(self, query, args);
- va_end(args);
+ va_start(args, query);
+ res = Sql_QueryV(self, query, args);
+ va_end(args);
- return res;
+ return res;
}
/// Executes a query.
-int Sql_QueryV(Sql *self, const char *query, va_list args)
+int Sql_QueryV(Sql* self, const char* query, va_list args)
{
- if (self == NULL)
- return SQL_ERROR;
+ if( self == NULL )
+ return SQL_ERROR;
- Sql_FreeResult(self);
- StringBuf_Clear(&self->buf);
- StringBuf_Vprintf(&self->buf, query, args);
- if (mysql_real_query(&self->handle, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf))) {
- ShowSQL("DB error - %s\n", mysql_error(&self->handle));
- return SQL_ERROR;
- }
- self->result = mysql_store_result(&self->handle);
- if (mysql_errno(&self->handle) != 0) {
- ShowSQL("DB error - %s\n", mysql_error(&self->handle));
- return SQL_ERROR;
- }
- return SQL_SUCCESS;
+ Sql_FreeResult(self);
+ StringBuf_Clear(&self->buf);
+ StringBuf_Vprintf(&self->buf, query, args);
+ if( mysql_real_query(&self->handle, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf)) )
+ {
+ ShowSQL("DB error - %s\n", mysql_error(&self->handle));
+ return SQL_ERROR;
+ }
+ self->result = mysql_store_result(&self->handle);
+ if( mysql_errno(&self->handle) != 0 )
+ {
+ ShowSQL("DB error - %s\n", mysql_error(&self->handle));
+ return SQL_ERROR;
+ }
+ return SQL_SUCCESS;
}
/// Executes a query.
-int Sql_QueryStr(Sql *self, const char *query)
+int Sql_QueryStr(Sql* self, const char* query)
{
- if (self == NULL)
- return SQL_ERROR;
+ if( self == NULL )
+ return SQL_ERROR;
- Sql_FreeResult(self);
- StringBuf_Clear(&self->buf);
- StringBuf_AppendStr(&self->buf, query);
- if (mysql_real_query(&self->handle, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf))) {
- ShowSQL("DB error - %s\n", mysql_error(&self->handle));
- return SQL_ERROR;
- }
- self->result = mysql_store_result(&self->handle);
- if (mysql_errno(&self->handle) != 0) {
- ShowSQL("DB error - %s\n", mysql_error(&self->handle));
- return SQL_ERROR;
- }
- return SQL_SUCCESS;
+ Sql_FreeResult(self);
+ StringBuf_Clear(&self->buf);
+ StringBuf_AppendStr(&self->buf, query);
+ if( mysql_real_query(&self->handle, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf)) )
+ {
+ ShowSQL("DB error - %s\n", mysql_error(&self->handle));
+ return SQL_ERROR;
+ }
+ self->result = mysql_store_result(&self->handle);
+ if( mysql_errno(&self->handle) != 0 )
+ {
+ ShowSQL("DB error - %s\n", mysql_error(&self->handle));
+ return SQL_ERROR;
+ }
+ return SQL_SUCCESS;
}
/// Returns the number of the AUTO_INCREMENT column of the last INSERT/UPDATE query.
-uint64 Sql_LastInsertId(Sql *self)
+uint64 Sql_LastInsertId(Sql* self)
{
- if (self)
- return (uint64)mysql_insert_id(&self->handle);
- else
- return 0;
+ if( self )
+ return (uint64)mysql_insert_id(&self->handle);
+ else
+ return 0;
}
/// Returns the number of columns in each row of the result.
-uint32 Sql_NumColumns(Sql *self)
+uint32 Sql_NumColumns(Sql* self)
{
- if (self && self->result)
- return (uint32)mysql_num_fields(self->result);
- return 0;
+ if( self && self->result )
+ return (uint32)mysql_num_fields(self->result);
+ return 0;
}
/// Returns the number of rows in the result.
-uint64 Sql_NumRows(Sql *self)
+uint64 Sql_NumRows(Sql* self)
{
- if (self && self->result)
- return (uint64)mysql_num_rows(self->result);
- return 0;
+ if( self && self->result )
+ return (uint64)mysql_num_rows(self->result);
+ return 0;
}
/// Fetches the next row.
-int Sql_NextRow(Sql *self)
+int Sql_NextRow(Sql* self)
{
- if (self && self->result) {
- self->row = mysql_fetch_row(self->result);
- if (self->row) {
- self->lengths = mysql_fetch_lengths(self->result);
- return SQL_SUCCESS;
- }
- self->lengths = NULL;
- if (mysql_errno(&self->handle) == 0)
- return SQL_NO_DATA;
- }
- return SQL_ERROR;
+ if( self && self->result )
+ {
+ self->row = mysql_fetch_row(self->result);
+ if( self->row )
+ {
+ self->lengths = mysql_fetch_lengths(self->result);
+ return SQL_SUCCESS;
+ }
+ self->lengths = NULL;
+ if( mysql_errno(&self->handle) == 0 )
+ return SQL_NO_DATA;
+ }
+ return SQL_ERROR;
}
/// Gets the data of a column.
-int Sql_GetData(Sql *self, size_t col, char **out_buf, size_t *out_len)
+int Sql_GetData(Sql* self, size_t col, char** out_buf, size_t* out_len)
{
- if (self && self->row) {
- if (col < Sql_NumColumns(self)) {
- if (out_buf) *out_buf = self->row[col];
- if (out_len) *out_len = (size_t)self->lengths[col];
- } else {
- // out of range - ignore
- if (out_buf) *out_buf = NULL;
- if (out_len) *out_len = 0;
- }
- return SQL_SUCCESS;
- }
- return SQL_ERROR;
+ if( self && self->row )
+ {
+ if( col < Sql_NumColumns(self) )
+ {
+ if( out_buf ) *out_buf = self->row[col];
+ if( out_len ) *out_len = (size_t)self->lengths[col];
+ }
+ else
+ {// out of range - ignore
+ if( out_buf ) *out_buf = NULL;
+ if( out_len ) *out_len = 0;
+ }
+ return SQL_SUCCESS;
+ }
+ return SQL_ERROR;
}
/// Frees the result of the query.
-void Sql_FreeResult(Sql *self)
+void Sql_FreeResult(Sql* self)
{
- if (self && self->result) {
- mysql_free_result(self->result);
- self->result = NULL;
- self->row = NULL;
- self->lengths = NULL;
- }
+ if( self && self->result )
+ {
+ mysql_free_result(self->result);
+ self->result = NULL;
+ self->row = NULL;
+ self->lengths = NULL;
+ }
}
/// Shows debug information (last query).
-void Sql_ShowDebug_(Sql *self, const char *debug_file, const unsigned long debug_line)
+void Sql_ShowDebug_(Sql* self, const char* debug_file, const unsigned long debug_line)
{
- if (self == NULL)
- ShowDebug("at %s:%lu - self is NULL\n", debug_file, debug_line);
- else if (StringBuf_Length(&self->buf) > 0)
- ShowDebug("at %s:%lu - %s\n", debug_file, debug_line, StringBuf_Value(&self->buf));
- else
- ShowDebug("at %s:%lu\n", debug_file, debug_line);
+ if( self == NULL )
+ ShowDebug("at %s:%lu - self is NULL\n", debug_file, debug_line);
+ else if( StringBuf_Length(&self->buf) > 0 )
+ ShowDebug("at %s:%lu - %s\n", debug_file, debug_line, StringBuf_Value(&self->buf));
+ else
+ ShowDebug("at %s:%lu\n", debug_file, debug_line);
}
/// Frees a Sql handle returned by Sql_Malloc.
-void Sql_Free(Sql *self)
+void Sql_Free(Sql* self)
{
- if (self) {
- Sql_FreeResult(self);
- StringBuf_Destroy(&self->buf);
- if (self->keepalive != INVALID_TIMER) delete_timer(self->keepalive, Sql_P_KeepaliveTimer);
- aFree(self);
- }
+ if( self )
+ {
+ Sql_FreeResult(self);
+ StringBuf_Destroy(&self->buf);
+ if( self->keepalive != INVALID_TIMER ) delete_timer(self->keepalive, Sql_P_KeepaliveTimer);
+ aFree(self);
+ }
}
@@ -409,19 +429,16 @@ void Sql_Free(Sql *self)
/// @private
static enum enum_field_types Sql_P_SizeToMysqlIntType(int sz)
{
- switch (sz) {
- case 1:
- return MYSQL_TYPE_TINY;
- case 2:
- return MYSQL_TYPE_SHORT;
- case 4:
- return MYSQL_TYPE_LONG;
- case 8:
- return MYSQL_TYPE_LONGLONG;
- default:
- ShowDebug("SizeToMysqlIntType: unsupported size (%d)\n", sz);
- return MYSQL_TYPE_NULL;
- }
+ switch( sz )
+ {
+ case 1: return MYSQL_TYPE_TINY;
+ case 2: return MYSQL_TYPE_SHORT;
+ case 4: return MYSQL_TYPE_LONG;
+ case 8: return MYSQL_TYPE_LONGLONG;
+ default:
+ ShowDebug("SizeToMysqlIntType: unsupported size (%d)\n", sz);
+ return MYSQL_TYPE_NULL;
+ }
}
@@ -429,96 +446,74 @@ static enum enum_field_types Sql_P_SizeToMysqlIntType(int sz)
/// Binds a parameter/result.
///
/// @private
-static int Sql_P_BindSqlDataType(MYSQL_BIND *bind, enum SqlDataType buffer_type, void *buffer, size_t buffer_len, unsigned long *out_length, int8 *out_is_null)
-{
- memset(bind, 0, sizeof(MYSQL_BIND));
- switch (buffer_type) {
- case SQLDT_NULL:
- bind->buffer_type = MYSQL_TYPE_NULL;
- buffer_len = 0;// FIXME length = ? [FlavioJS]
- break;
- // fixed size
- case SQLDT_UINT8:
- bind->is_unsigned = 1;
- case SQLDT_INT8:
- bind->buffer_type = MYSQL_TYPE_TINY;
- buffer_len = 1;
- break;
- case SQLDT_UINT16:
- bind->is_unsigned = 1;
- case SQLDT_INT16:
- bind->buffer_type = MYSQL_TYPE_SHORT;
- buffer_len = 2;
- break;
- case SQLDT_UINT32:
- bind->is_unsigned = 1;
- case SQLDT_INT32:
- bind->buffer_type = MYSQL_TYPE_LONG;
- buffer_len = 4;
- break;
- case SQLDT_UINT64:
- bind->is_unsigned = 1;
- case SQLDT_INT64:
- bind->buffer_type = MYSQL_TYPE_LONGLONG;
- buffer_len = 8;
- break;
- // platform dependent size
- case SQLDT_UCHAR:
- bind->is_unsigned = 1;
- case SQLDT_CHAR:
- bind->buffer_type = Sql_P_SizeToMysqlIntType(sizeof(char));
- buffer_len = sizeof(char);
- break;
- case SQLDT_USHORT:
- bind->is_unsigned = 1;
- case SQLDT_SHORT:
- bind->buffer_type = Sql_P_SizeToMysqlIntType(sizeof(short));
- buffer_len = sizeof(short);
- break;
- case SQLDT_UINT:
- bind->is_unsigned = 1;
- case SQLDT_INT:
- bind->buffer_type = Sql_P_SizeToMysqlIntType(sizeof(int));
- buffer_len = sizeof(int);
- break;
- case SQLDT_ULONG:
- bind->is_unsigned = 1;
- case SQLDT_LONG:
- bind->buffer_type = Sql_P_SizeToMysqlIntType(sizeof(long));
- buffer_len = sizeof(long);
- break;
- case SQLDT_ULONGLONG:
- bind->is_unsigned = 1;
- case SQLDT_LONGLONG:
- bind->buffer_type = Sql_P_SizeToMysqlIntType(sizeof(int64));
- buffer_len = sizeof(int64);
- break;
- // floating point
- case SQLDT_FLOAT:
- bind->buffer_type = MYSQL_TYPE_FLOAT;
- buffer_len = 4;
- break;
- case SQLDT_DOUBLE:
- bind->buffer_type = MYSQL_TYPE_DOUBLE;
- buffer_len = 8;
- break;
- // other
- case SQLDT_STRING:
- case SQLDT_ENUM:
- bind->buffer_type = MYSQL_TYPE_STRING;
- break;
- case SQLDT_BLOB:
- bind->buffer_type = MYSQL_TYPE_BLOB;
- break;
- default:
- ShowDebug("Sql_P_BindSqlDataType: unsupported buffer type (%d)\n", buffer_type);
- return SQL_ERROR;
- }
- bind->buffer = buffer;
- bind->buffer_length = (unsigned long)buffer_len;
- bind->length = out_length;
- bind->is_null = (my_bool *)out_is_null;
- return SQL_SUCCESS;
+static int Sql_P_BindSqlDataType(MYSQL_BIND* bind, enum SqlDataType buffer_type, void* buffer, size_t buffer_len, unsigned long* out_length, int8* out_is_null)
+{
+ memset(bind, 0, sizeof(MYSQL_BIND));
+ switch( buffer_type )
+ {
+ case SQLDT_NULL: bind->buffer_type = MYSQL_TYPE_NULL;
+ buffer_len = 0;// FIXME length = ? [FlavioJS]
+ break;
+ // fixed size
+ case SQLDT_UINT8: bind->is_unsigned = 1;
+ case SQLDT_INT8: bind->buffer_type = MYSQL_TYPE_TINY;
+ buffer_len = 1;
+ break;
+ case SQLDT_UINT16: bind->is_unsigned = 1;
+ case SQLDT_INT16: bind->buffer_type = MYSQL_TYPE_SHORT;
+ buffer_len = 2;
+ break;
+ case SQLDT_UINT32: bind->is_unsigned = 1;
+ case SQLDT_INT32: bind->buffer_type = MYSQL_TYPE_LONG;
+ buffer_len = 4;
+ break;
+ case SQLDT_UINT64: bind->is_unsigned = 1;
+ case SQLDT_INT64: bind->buffer_type = MYSQL_TYPE_LONGLONG;
+ buffer_len = 8;
+ break;
+ // platform dependent size
+ case SQLDT_UCHAR: bind->is_unsigned = 1;
+ case SQLDT_CHAR: bind->buffer_type = Sql_P_SizeToMysqlIntType(sizeof(char));
+ buffer_len = sizeof(char);
+ break;
+ case SQLDT_USHORT: bind->is_unsigned = 1;
+ case SQLDT_SHORT: bind->buffer_type = Sql_P_SizeToMysqlIntType(sizeof(short));
+ buffer_len = sizeof(short);
+ break;
+ case SQLDT_UINT: bind->is_unsigned = 1;
+ case SQLDT_INT: bind->buffer_type = Sql_P_SizeToMysqlIntType(sizeof(int));
+ buffer_len = sizeof(int);
+ break;
+ case SQLDT_ULONG: bind->is_unsigned = 1;
+ case SQLDT_LONG: bind->buffer_type = Sql_P_SizeToMysqlIntType(sizeof(long));
+ buffer_len = sizeof(long);
+ break;
+ case SQLDT_ULONGLONG: bind->is_unsigned = 1;
+ case SQLDT_LONGLONG: bind->buffer_type = Sql_P_SizeToMysqlIntType(sizeof(int64));
+ buffer_len = sizeof(int64);
+ break;
+ // floating point
+ case SQLDT_FLOAT: bind->buffer_type = MYSQL_TYPE_FLOAT;
+ buffer_len = 4;
+ break;
+ case SQLDT_DOUBLE: bind->buffer_type = MYSQL_TYPE_DOUBLE;
+ buffer_len = 8;
+ break;
+ // other
+ case SQLDT_STRING:
+ case SQLDT_ENUM: bind->buffer_type = MYSQL_TYPE_STRING;
+ break;
+ case SQLDT_BLOB: bind->buffer_type = MYSQL_TYPE_BLOB;
+ break;
+ default:
+ ShowDebug("Sql_P_BindSqlDataType: unsupported buffer type (%d)\n", buffer_type);
+ return SQL_ERROR;
+ }
+ bind->buffer = buffer;
+ bind->buffer_length = (unsigned long)buffer_len;
+ bind->length = out_length;
+ bind->is_null = (my_bool*)out_is_null;
+ return SQL_SUCCESS;
}
@@ -526,37 +521,38 @@ static int Sql_P_BindSqlDataType(MYSQL_BIND *bind, enum SqlDataType buffer_type,
/// Prints debug information about a field (type and length).
///
/// @private
-static void Sql_P_ShowDebugMysqlFieldInfo(const char *prefix, enum enum_field_types type, int is_unsigned, unsigned long length, const char *length_postfix)
-{
- const char *sign = (is_unsigned ? "UNSIGNED " : "");
- const char *type_string;
- switch (type) {
- default:
- ShowDebug("%stype=%s%u, length=%d\n", prefix, sign, type, length);
- return;
+static void Sql_P_ShowDebugMysqlFieldInfo(const char* prefix, enum enum_field_types type, int is_unsigned, unsigned long length, const char* length_postfix)
+{
+ const char* sign = (is_unsigned ? "UNSIGNED " : "");
+ const char* type_string;
+ switch( type )
+ {
+ default:
+ ShowDebug("%stype=%s%u, length=%d\n", prefix, sign, type, length);
+ return;
#define SHOW_DEBUG_OF(x) case x: type_string = #x; break
- SHOW_DEBUG_OF(MYSQL_TYPE_TINY);
- SHOW_DEBUG_OF(MYSQL_TYPE_SHORT);
- SHOW_DEBUG_OF(MYSQL_TYPE_LONG);
- SHOW_DEBUG_OF(MYSQL_TYPE_INT24);
- SHOW_DEBUG_OF(MYSQL_TYPE_LONGLONG);
- SHOW_DEBUG_OF(MYSQL_TYPE_DECIMAL);
- SHOW_DEBUG_OF(MYSQL_TYPE_FLOAT);
- SHOW_DEBUG_OF(MYSQL_TYPE_DOUBLE);
- SHOW_DEBUG_OF(MYSQL_TYPE_TIMESTAMP);
- SHOW_DEBUG_OF(MYSQL_TYPE_DATE);
- SHOW_DEBUG_OF(MYSQL_TYPE_TIME);
- SHOW_DEBUG_OF(MYSQL_TYPE_DATETIME);
- SHOW_DEBUG_OF(MYSQL_TYPE_YEAR);
- SHOW_DEBUG_OF(MYSQL_TYPE_STRING);
- SHOW_DEBUG_OF(MYSQL_TYPE_VAR_STRING);
- SHOW_DEBUG_OF(MYSQL_TYPE_BLOB);
- SHOW_DEBUG_OF(MYSQL_TYPE_SET);
- SHOW_DEBUG_OF(MYSQL_TYPE_ENUM);
- SHOW_DEBUG_OF(MYSQL_TYPE_NULL);
+ SHOW_DEBUG_OF(MYSQL_TYPE_TINY);
+ SHOW_DEBUG_OF(MYSQL_TYPE_SHORT);
+ SHOW_DEBUG_OF(MYSQL_TYPE_LONG);
+ SHOW_DEBUG_OF(MYSQL_TYPE_INT24);
+ SHOW_DEBUG_OF(MYSQL_TYPE_LONGLONG);
+ SHOW_DEBUG_OF(MYSQL_TYPE_DECIMAL);
+ SHOW_DEBUG_OF(MYSQL_TYPE_FLOAT);
+ SHOW_DEBUG_OF(MYSQL_TYPE_DOUBLE);
+ SHOW_DEBUG_OF(MYSQL_TYPE_TIMESTAMP);
+ SHOW_DEBUG_OF(MYSQL_TYPE_DATE);
+ SHOW_DEBUG_OF(MYSQL_TYPE_TIME);
+ SHOW_DEBUG_OF(MYSQL_TYPE_DATETIME);
+ SHOW_DEBUG_OF(MYSQL_TYPE_YEAR);
+ SHOW_DEBUG_OF(MYSQL_TYPE_STRING);
+ SHOW_DEBUG_OF(MYSQL_TYPE_VAR_STRING);
+ SHOW_DEBUG_OF(MYSQL_TYPE_BLOB);
+ SHOW_DEBUG_OF(MYSQL_TYPE_SET);
+ SHOW_DEBUG_OF(MYSQL_TYPE_ENUM);
+ SHOW_DEBUG_OF(MYSQL_TYPE_NULL);
#undef SHOW_DEBUG_TYPE_OF
- }
- ShowDebug("%stype=%s%s, length=%d%s\n", prefix, sign, type_string, length, length_postfix);
+ }
+ ShowDebug("%stype=%s%s, length=%d%s\n", prefix, sign, type_string, length, length_postfix);
}
@@ -564,369 +560,389 @@ static void Sql_P_ShowDebugMysqlFieldInfo(const char *prefix, enum enum_field_ty
/// Reports debug information about a truncated column.
///
/// @private
-static void SqlStmt_P_ShowDebugTruncatedColumn(SqlStmt *self, size_t i)
+static void SqlStmt_P_ShowDebugTruncatedColumn(SqlStmt* self, size_t i)
{
- MYSQL_RES *meta;
- MYSQL_FIELD *field;
- MYSQL_BIND *column;
+ MYSQL_RES* meta;
+ MYSQL_FIELD* field;
+ MYSQL_BIND* column;
- meta = mysql_stmt_result_metadata(self->stmt);
- field = mysql_fetch_field_direct(meta, (unsigned int)i);
- ShowSQL("DB error - data of field '%s' was truncated.\n", field->name);
- ShowDebug("column - %lu\n", (unsigned long)i);
- Sql_P_ShowDebugMysqlFieldInfo("data - ", field->type, field->flags&UNSIGNED_FLAG, self->column_lengths[i].length, "");
- column = &self->columns[i];
- if (column->buffer_type == MYSQL_TYPE_STRING)
- Sql_P_ShowDebugMysqlFieldInfo("buffer - ", column->buffer_type, column->is_unsigned, column->buffer_length, "+1(nul-terminator)");
- else
- Sql_P_ShowDebugMysqlFieldInfo("buffer - ", column->buffer_type, column->is_unsigned, column->buffer_length, "");
- mysql_free_result(meta);
+ meta = mysql_stmt_result_metadata(self->stmt);
+ field = mysql_fetch_field_direct(meta, (unsigned int)i);
+ ShowSQL("DB error - data of field '%s' was truncated.\n", field->name);
+ ShowDebug("column - %lu\n", (unsigned long)i);
+ Sql_P_ShowDebugMysqlFieldInfo("data - ", field->type, field->flags&UNSIGNED_FLAG, self->column_lengths[i].length, "");
+ column = &self->columns[i];
+ if( column->buffer_type == MYSQL_TYPE_STRING )
+ Sql_P_ShowDebugMysqlFieldInfo("buffer - ", column->buffer_type, column->is_unsigned, column->buffer_length, "+1(nul-terminator)");
+ else
+ Sql_P_ShowDebugMysqlFieldInfo("buffer - ", column->buffer_type, column->is_unsigned, column->buffer_length, "");
+ mysql_free_result(meta);
}
/// Allocates and initializes a new SqlStmt handle.
-SqlStmt *SqlStmt_Malloc(Sql *sql)
+SqlStmt* SqlStmt_Malloc(Sql* sql)
{
- SqlStmt *self;
- MYSQL_STMT *stmt;
+ SqlStmt* self;
+ MYSQL_STMT* stmt;
- if (sql == NULL)
- return NULL;
+ if( sql == NULL )
+ return NULL;
- stmt = mysql_stmt_init(&sql->handle);
- if (stmt == NULL) {
- ShowSQL("DB error - %s\n", mysql_error(&sql->handle));
- return NULL;
- }
- CREATE(self, SqlStmt, 1);
- StringBuf_Init(&self->buf);
- self->stmt = stmt;
- self->params = NULL;
- self->columns = NULL;
- self->column_lengths = NULL;
- self->max_params = 0;
- self->max_columns = 0;
- self->bind_params = false;
- self->bind_columns = false;
+ stmt = mysql_stmt_init(&sql->handle);
+ if( stmt == NULL )
+ {
+ ShowSQL("DB error - %s\n", mysql_error(&sql->handle));
+ return NULL;
+ }
+ CREATE(self, SqlStmt, 1);
+ StringBuf_Init(&self->buf);
+ self->stmt = stmt;
+ self->params = NULL;
+ self->columns = NULL;
+ self->column_lengths = NULL;
+ self->max_params = 0;
+ self->max_columns = 0;
+ self->bind_params = false;
+ self->bind_columns = false;
- return self;
+ return self;
}
/// Prepares the statement.
-int SqlStmt_Prepare(SqlStmt *self, const char *query, ...)
+int SqlStmt_Prepare(SqlStmt* self, const char* query, ...)
{
- int res;
- va_list args;
+ int res;
+ va_list args;
- va_start(args, query);
- res = SqlStmt_PrepareV(self, query, args);
- va_end(args);
+ va_start(args, query);
+ res = SqlStmt_PrepareV(self, query, args);
+ va_end(args);
- return res;
+ return res;
}
/// Prepares the statement.
-int SqlStmt_PrepareV(SqlStmt *self, const char *query, va_list args)
+int SqlStmt_PrepareV(SqlStmt* self, const char* query, va_list args)
{
- if (self == NULL)
- return SQL_ERROR;
+ if( self == NULL )
+ return SQL_ERROR;
- SqlStmt_FreeResult(self);
- StringBuf_Clear(&self->buf);
- StringBuf_Vprintf(&self->buf, query, args);
- if (mysql_stmt_prepare(self->stmt, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf))) {
- ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt));
- return SQL_ERROR;
- }
- self->bind_params = false;
+ SqlStmt_FreeResult(self);
+ StringBuf_Clear(&self->buf);
+ StringBuf_Vprintf(&self->buf, query, args);
+ if( mysql_stmt_prepare(self->stmt, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf)) )
+ {
+ ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt));
+ return SQL_ERROR;
+ }
+ self->bind_params = false;
- return SQL_SUCCESS;
+ return SQL_SUCCESS;
}
/// Prepares the statement.
-int SqlStmt_PrepareStr(SqlStmt *self, const char *query)
+int SqlStmt_PrepareStr(SqlStmt* self, const char* query)
{
- if (self == NULL)
- return SQL_ERROR;
+ if( self == NULL )
+ return SQL_ERROR;
- SqlStmt_FreeResult(self);
- StringBuf_Clear(&self->buf);
- StringBuf_AppendStr(&self->buf, query);
- if (mysql_stmt_prepare(self->stmt, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf))) {
- ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt));
- return SQL_ERROR;
- }
- self->bind_params = false;
+ SqlStmt_FreeResult(self);
+ StringBuf_Clear(&self->buf);
+ StringBuf_AppendStr(&self->buf, query);
+ if( mysql_stmt_prepare(self->stmt, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf)) )
+ {
+ ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt));
+ return SQL_ERROR;
+ }
+ self->bind_params = false;
- return SQL_SUCCESS;
+ return SQL_SUCCESS;
}
/// Returns the number of parameters in the prepared statement.
-size_t SqlStmt_NumParams(SqlStmt *self)
+size_t SqlStmt_NumParams(SqlStmt* self)
{
- if (self)
- return (size_t)mysql_stmt_param_count(self->stmt);
- else
- return 0;
+ if( self )
+ return (size_t)mysql_stmt_param_count(self->stmt);
+ else
+ return 0;
}
/// Binds a parameter to a buffer.
-int SqlStmt_BindParam(SqlStmt *self, size_t idx, enum SqlDataType buffer_type, void *buffer, size_t buffer_len)
+int SqlStmt_BindParam(SqlStmt* self, size_t idx, enum SqlDataType buffer_type, void* buffer, size_t buffer_len)
{
- if (self == NULL)
- return SQL_ERROR;
+ if( self == NULL )
+ return SQL_ERROR;
- if (!self->bind_params) {
- // initialize the bindings
- size_t i;
- size_t count;
+ if( !self->bind_params )
+ {// initialize the bindings
+ size_t i;
+ size_t count;
- count = SqlStmt_NumParams(self);
- if (self->max_params < count) {
- self->max_params = count;
- RECREATE(self->params, MYSQL_BIND, count);
- }
- memset(self->params, 0, count*sizeof(MYSQL_BIND));
- for (i = 0; i < count; ++i)
- self->params[i].buffer_type = MYSQL_TYPE_NULL;
- self->bind_params = true;
- }
- if (idx < self->max_params)
- return Sql_P_BindSqlDataType(self->params+idx, buffer_type, buffer, buffer_len, NULL, NULL);
- else
- return SQL_SUCCESS;// out of range - ignore
+ count = SqlStmt_NumParams(self);
+ if( self->max_params < count )
+ {
+ self->max_params = count;
+ RECREATE(self->params, MYSQL_BIND, count);
+ }
+ memset(self->params, 0, count*sizeof(MYSQL_BIND));
+ for( i = 0; i < count; ++i )
+ self->params[i].buffer_type = MYSQL_TYPE_NULL;
+ self->bind_params = true;
+ }
+ if( idx < self->max_params )
+ return Sql_P_BindSqlDataType(self->params+idx, buffer_type, buffer, buffer_len, NULL, NULL);
+ else
+ return SQL_SUCCESS;// out of range - ignore
}
/// Executes the prepared statement.
-int SqlStmt_Execute(SqlStmt *self)
+int SqlStmt_Execute(SqlStmt* self)
{
- if (self == NULL)
- return SQL_ERROR;
+ if( self == NULL )
+ return SQL_ERROR;
- SqlStmt_FreeResult(self);
- if ((self->bind_params && mysql_stmt_bind_param(self->stmt, self->params)) ||
- mysql_stmt_execute(self->stmt)) {
- ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt));
- return SQL_ERROR;
- }
- self->bind_columns = false;
- if (mysql_stmt_store_result(self->stmt)) { // store all the data
- ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt));
- return SQL_ERROR;
- }
+ SqlStmt_FreeResult(self);
+ if( (self->bind_params && mysql_stmt_bind_param(self->stmt, self->params)) ||
+ mysql_stmt_execute(self->stmt) )
+ {
+ ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt));
+ return SQL_ERROR;
+ }
+ self->bind_columns = false;
+ if( mysql_stmt_store_result(self->stmt) )// store all the data
+ {
+ ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt));
+ return SQL_ERROR;
+ }
- return SQL_SUCCESS;
+ return SQL_SUCCESS;
}
/// Returns the number of the AUTO_INCREMENT column of the last INSERT/UPDATE statement.
-uint64 SqlStmt_LastInsertId(SqlStmt *self)
+uint64 SqlStmt_LastInsertId(SqlStmt* self)
{
- if (self)
- return (uint64)mysql_stmt_insert_id(self->stmt);
- else
- return 0;
+ if( self )
+ return (uint64)mysql_stmt_insert_id(self->stmt);
+ else
+ return 0;
}
/// Returns the number of columns in each row of the result.
-size_t SqlStmt_NumColumns(SqlStmt *self)
+size_t SqlStmt_NumColumns(SqlStmt* self)
{
- if (self)
- return (size_t)mysql_stmt_field_count(self->stmt);
- else
- return 0;
+ if( self )
+ return (size_t)mysql_stmt_field_count(self->stmt);
+ else
+ return 0;
}
/// Binds the result of a column to a buffer.
-int SqlStmt_BindColumn(SqlStmt *self, size_t idx, enum SqlDataType buffer_type, void *buffer, size_t buffer_len, uint32 *out_length, int8 *out_is_null)
-{
- if (self == NULL)
- return SQL_ERROR;
-
- if (buffer_type == SQLDT_STRING || buffer_type == SQLDT_ENUM) {
- if (buffer_len < 1) {
- ShowDebug("SqlStmt_BindColumn: buffer_len(%d) is too small, no room for the nul-terminator\n", buffer_len);
- return SQL_ERROR;
- }
- --buffer_len;// nul-terminator
- }
- if (!self->bind_columns) {
- // initialize the bindings
- size_t i;
- size_t cols;
-
- cols = SqlStmt_NumColumns(self);
- if (self->max_columns < cols) {
- self->max_columns = cols;
- RECREATE(self->columns, MYSQL_BIND, cols);
- RECREATE(self->column_lengths, s_column_length, cols);
- }
- memset(self->columns, 0, cols*sizeof(MYSQL_BIND));
- memset(self->column_lengths, 0, cols*sizeof(s_column_length));
- for (i = 0; i < cols; ++i)
- self->columns[i].buffer_type = MYSQL_TYPE_NULL;
- self->bind_columns = true;
- }
- if (idx < self->max_columns) {
- self->column_lengths[idx].out_length = out_length;
- return Sql_P_BindSqlDataType(self->columns+idx, buffer_type, buffer, buffer_len, &self->column_lengths[idx].length, out_is_null);
- } else {
- return SQL_SUCCESS;// out of range - ignore
- }
+int SqlStmt_BindColumn(SqlStmt* self, size_t idx, enum SqlDataType buffer_type, void* buffer, size_t buffer_len, uint32* out_length, int8* out_is_null)
+{
+ if( self == NULL )
+ return SQL_ERROR;
+
+ if( buffer_type == SQLDT_STRING || buffer_type == SQLDT_ENUM )
+ {
+ if( buffer_len < 1 )
+ {
+ ShowDebug("SqlStmt_BindColumn: buffer_len(%d) is too small, no room for the nul-terminator\n", buffer_len);
+ return SQL_ERROR;
+ }
+ --buffer_len;// nul-terminator
+ }
+ if( !self->bind_columns )
+ {// initialize the bindings
+ size_t i;
+ size_t cols;
+
+ cols = SqlStmt_NumColumns(self);
+ if( self->max_columns < cols )
+ {
+ self->max_columns = cols;
+ RECREATE(self->columns, MYSQL_BIND, cols);
+ RECREATE(self->column_lengths, s_column_length, cols);
+ }
+ memset(self->columns, 0, cols*sizeof(MYSQL_BIND));
+ memset(self->column_lengths, 0, cols*sizeof(s_column_length));
+ for( i = 0; i < cols; ++i )
+ self->columns[i].buffer_type = MYSQL_TYPE_NULL;
+ self->bind_columns = true;
+ }
+ if( idx < self->max_columns )
+ {
+ self->column_lengths[idx].out_length = out_length;
+ return Sql_P_BindSqlDataType(self->columns+idx, buffer_type, buffer, buffer_len, &self->column_lengths[idx].length, out_is_null);
+ }
+ else
+ {
+ return SQL_SUCCESS;// out of range - ignore
+ }
}
/// Returns the number of rows in the result.
-uint64 SqlStmt_NumRows(SqlStmt *self)
+uint64 SqlStmt_NumRows(SqlStmt* self)
{
- if (self)
- return (uint64)mysql_stmt_num_rows(self->stmt);
- else
- return 0;
+ if( self )
+ return (uint64)mysql_stmt_num_rows(self->stmt);
+ else
+ return 0;
}
/// Fetches the next row.
-int SqlStmt_NextRow(SqlStmt *self)
-{
- int err;
- size_t i;
- size_t cols;
- MYSQL_BIND *column;
- unsigned long length;
-
- if (self == NULL)
- return SQL_ERROR;
-
- // bind columns
- if (self->bind_columns && mysql_stmt_bind_result(self->stmt, self->columns))
- err = 1;// error binding columns
- else
- err = mysql_stmt_fetch(self->stmt);// fetch row
-
- // check for errors
- if (err == MYSQL_NO_DATA)
- return SQL_NO_DATA;
+int SqlStmt_NextRow(SqlStmt* self)
+{
+ int err;
+ size_t i;
+ size_t cols;
+ MYSQL_BIND* column;
+ unsigned long length;
+
+ if( self == NULL )
+ return SQL_ERROR;
+
+ // bind columns
+ if( self->bind_columns && mysql_stmt_bind_result(self->stmt, self->columns) )
+ err = 1;// error binding columns
+ else
+ err = mysql_stmt_fetch(self->stmt);// fetch row
+
+ // check for errors
+ if( err == MYSQL_NO_DATA )
+ return SQL_NO_DATA;
#if defined(MYSQL_DATA_TRUNCATED)
- // MySQL 5.0/5.1 defines and returns MYSQL_DATA_TRUNCATED [FlavioJS]
- if (err == MYSQL_DATA_TRUNCATED) {
- my_bool truncated;
-
- if (!self->bind_columns) {
- ShowSQL("DB error - data truncated (unknown source, columns are not bound)\n");
- return SQL_ERROR;
- }
-
- // find truncated column
- cols = SqlStmt_NumColumns(self);
- for (i = 0; i < cols; ++i) {
- column = &self->columns[i];
- column->error = &truncated;
- mysql_stmt_fetch_column(self->stmt, column, (unsigned int)i, 0);
- column->error = NULL;
- if (truncated) {
- // report truncated column
- SqlStmt_P_ShowDebugTruncatedColumn(self, i);
- return SQL_ERROR;
- }
- }
- ShowSQL("DB error - data truncated (unknown source)\n");
- return SQL_ERROR;
- }
+ // MySQL 5.0/5.1 defines and returns MYSQL_DATA_TRUNCATED [FlavioJS]
+ if( err == MYSQL_DATA_TRUNCATED )
+ {
+ my_bool truncated;
+
+ if( !self->bind_columns )
+ {
+ ShowSQL("DB error - data truncated (unknown source, columns are not bound)\n");
+ return SQL_ERROR;
+ }
+
+ // find truncated column
+ cols = SqlStmt_NumColumns(self);
+ for( i = 0; i < cols; ++i )
+ {
+ column = &self->columns[i];
+ column->error = &truncated;
+ mysql_stmt_fetch_column(self->stmt, column, (unsigned int)i, 0);
+ column->error = NULL;
+ if( truncated )
+ {// report truncated column
+ SqlStmt_P_ShowDebugTruncatedColumn(self, i);
+ return SQL_ERROR;
+ }
+ }
+ ShowSQL("DB error - data truncated (unknown source)\n");
+ return SQL_ERROR;
+ }
#endif
- if (err) {
- ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt));
- return SQL_ERROR;
- }
-
- // propagate column lengths and clear unused parts of string/enum/blob buffers
- cols = SqlStmt_NumColumns(self);
- for (i = 0; i < cols; ++i) {
- length = self->column_lengths[i].length;
- column = &self->columns[i];
+ if( err )
+ {
+ ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt));
+ return SQL_ERROR;
+ }
+
+ // propagate column lengths and clear unused parts of string/enum/blob buffers
+ cols = SqlStmt_NumColumns(self);
+ for( i = 0; i < cols; ++i )
+ {
+ length = self->column_lengths[i].length;
+ column = &self->columns[i];
#if !defined(MYSQL_DATA_TRUNCATED)
- // MySQL 4.1/(below?) returns success even if data is truncated, so we test truncation manually [FlavioJS]
- if (column->buffer_length < length) {
- // report truncated column
- if (column->buffer_type == MYSQL_TYPE_STRING || column->buffer_type == MYSQL_TYPE_BLOB) {
- // string/enum/blob column
- SqlStmt_P_ShowDebugTruncatedColumn(self, i);
- return SQL_ERROR;
- }
- // FIXME numeric types and null [FlavioJS]
- }
+ // MySQL 4.1/(below?) returns success even if data is truncated, so we test truncation manually [FlavioJS]
+ if( column->buffer_length < length )
+ {// report truncated column
+ if( column->buffer_type == MYSQL_TYPE_STRING || column->buffer_type == MYSQL_TYPE_BLOB )
+ {// string/enum/blob column
+ SqlStmt_P_ShowDebugTruncatedColumn(self, i);
+ return SQL_ERROR;
+ }
+ // FIXME numeric types and null [FlavioJS]
+ }
#endif
- if (self->column_lengths[i].out_length)
- *self->column_lengths[i].out_length = (uint32)length;
- if (column->buffer_type == MYSQL_TYPE_STRING) {
- // clear unused part of the string/enum buffer (and nul-terminate)
- memset((char *)column->buffer + length, 0, column->buffer_length - length + 1);
- } else if (column->buffer_type == MYSQL_TYPE_BLOB && length < column->buffer_length) {
- // clear unused part of the blob buffer
- memset((char *)column->buffer + length, 0, column->buffer_length - length);
- }
- }
+ if( self->column_lengths[i].out_length )
+ *self->column_lengths[i].out_length = (uint32)length;
+ if( column->buffer_type == MYSQL_TYPE_STRING )
+ {// clear unused part of the string/enum buffer (and nul-terminate)
+ memset((char*)column->buffer + length, 0, column->buffer_length - length + 1);
+ }
+ else if( column->buffer_type == MYSQL_TYPE_BLOB && length < column->buffer_length )
+ {// clear unused part of the blob buffer
+ memset((char*)column->buffer + length, 0, column->buffer_length - length);
+ }
+ }
- return SQL_SUCCESS;
+ return SQL_SUCCESS;
}
/// Frees the result of the statement execution.
-void SqlStmt_FreeResult(SqlStmt *self)
+void SqlStmt_FreeResult(SqlStmt* self)
{
- if (self)
- mysql_stmt_free_result(self->stmt);
+ if( self )
+ mysql_stmt_free_result(self->stmt);
}
/// Shows debug information (with statement).
-void SqlStmt_ShowDebug_(SqlStmt *self, const char *debug_file, const unsigned long debug_line)
+void SqlStmt_ShowDebug_(SqlStmt* self, const char* debug_file, const unsigned long debug_line)
{
- if (self == NULL)
- ShowDebug("at %s:%lu - self is NULL\n", debug_file, debug_line);
- else if (StringBuf_Length(&self->buf) > 0)
- ShowDebug("at %s:%lu - %s\n", debug_file, debug_line, StringBuf_Value(&self->buf));
- else
- ShowDebug("at %s:%lu\n", debug_file, debug_line);
+ if( self == NULL )
+ ShowDebug("at %s:%lu - self is NULL\n", debug_file, debug_line);
+ else if( StringBuf_Length(&self->buf) > 0 )
+ ShowDebug("at %s:%lu - %s\n", debug_file, debug_line, StringBuf_Value(&self->buf));
+ else
+ ShowDebug("at %s:%lu\n", debug_file, debug_line);
}
/// Frees a SqlStmt returned by SqlStmt_Malloc.
-void SqlStmt_Free(SqlStmt *self)
-{
- if (self) {
- SqlStmt_FreeResult(self);
- StringBuf_Destroy(&self->buf);
- mysql_stmt_close(self->stmt);
- if (self->params)
- aFree(self->params);
- if (self->columns) {
- aFree(self->columns);
- aFree(self->column_lengths);
- }
- aFree(self);
- }
+void SqlStmt_Free(SqlStmt* self)
+{
+ if( self )
+ {
+ SqlStmt_FreeResult(self);
+ StringBuf_Destroy(&self->buf);
+ mysql_stmt_close(self->stmt);
+ if( self->params )
+ aFree(self->params);
+ if( self->columns )
+ {
+ aFree(self->columns);
+ aFree(self->column_lengths);
+ }
+ aFree(self);
+ }
}
diff --git a/src/common/sql.h b/src/common/sql.h
index 4534061e0..898e2c778 100644
--- a/src/common/sql.h
+++ b/src/common/sql.h
@@ -21,38 +21,39 @@
/// Data type identifier.
/// String, enum and blob data types need the buffer length specified.
-enum SqlDataType {
- SQLDT_NULL,
- // fixed size
- SQLDT_INT8,
- SQLDT_INT16,
- SQLDT_INT32,
- SQLDT_INT64,
- SQLDT_UINT8,
- SQLDT_UINT16,
- SQLDT_UINT32,
- SQLDT_UINT64,
- // platform dependent size
- SQLDT_CHAR,
- SQLDT_SHORT,
- SQLDT_INT,
- SQLDT_LONG,
- SQLDT_LONGLONG,
- SQLDT_UCHAR,
- SQLDT_USHORT,
- SQLDT_UINT,
- SQLDT_ULONG,
- SQLDT_ULONGLONG,
- // floating point
- SQLDT_FLOAT,
- SQLDT_DOUBLE,
- // other
- SQLDT_STRING,
- SQLDT_ENUM,
- // Note: An ENUM is a string with restricted values. When an invalid value
- // is inserted, it is saved as an empty string (numerical value 0).
- SQLDT_BLOB,
- SQLDT_LASTID
+enum SqlDataType
+{
+ SQLDT_NULL,
+ // fixed size
+ SQLDT_INT8,
+ SQLDT_INT16,
+ SQLDT_INT32,
+ SQLDT_INT64,
+ SQLDT_UINT8,
+ SQLDT_UINT16,
+ SQLDT_UINT32,
+ SQLDT_UINT64,
+ // platform dependent size
+ SQLDT_CHAR,
+ SQLDT_SHORT,
+ SQLDT_INT,
+ SQLDT_LONG,
+ SQLDT_LONGLONG,
+ SQLDT_UCHAR,
+ SQLDT_USHORT,
+ SQLDT_UINT,
+ SQLDT_ULONG,
+ SQLDT_ULONGLONG,
+ // floating point
+ SQLDT_FLOAT,
+ SQLDT_DOUBLE,
+ // other
+ SQLDT_STRING,
+ SQLDT_ENUM,
+ // Note: An ENUM is a string with restricted values. When an invalid value
+ // is inserted, it is saved as an empty string (numerical value 0).
+ SQLDT_BLOB,
+ SQLDT_LASTID
};
struct Sql;// Sql handle (private access)
@@ -64,14 +65,14 @@ typedef struct SqlStmt SqlStmt;
/// Allocates and initializes a new Sql handle.
-struct Sql *Sql_Malloc(void);
+struct Sql* Sql_Malloc(void);
/// Establishes a connection.
///
/// @return SQL_SUCCESS or SQL_ERROR
-int Sql_Connect(Sql *self, const char *user, const char *passwd, const char *host, uint16 port, const char *db);
+int Sql_Connect(Sql* self, const char* user, const char* passwd, const char* host, uint16 port, const char* db);
@@ -79,7 +80,7 @@ int Sql_Connect(Sql *self, const char *user, const char *passwd, const char *hos
/// Retrieves the timeout of the connection.
///
/// @return SQL_SUCCESS or SQL_ERROR
-int Sql_GetTimeout(Sql *self, uint32 *out_timeout);
+int Sql_GetTimeout(Sql* self, uint32* out_timeout);
@@ -87,7 +88,7 @@ int Sql_GetTimeout(Sql *self, uint32 *out_timeout);
/// Retrieves the name of the columns of a table into out_buf, with the separator after each name.
///
/// @return SQL_SUCCESS or SQL_ERROR
-int Sql_GetColumnNames(Sql *self, const char *table, char *out_buf, size_t buf_len, char sep);
+int Sql_GetColumnNames(Sql* self, const char* table, char* out_buf, size_t buf_len, char sep);
@@ -95,14 +96,14 @@ int Sql_GetColumnNames(Sql *self, const char *table, char *out_buf, size_t buf_l
/// Changes the encoding of the connection.
///
/// @return SQL_SUCCESS or SQL_ERROR
-int Sql_SetEncoding(Sql *self, const char *encoding);
+int Sql_SetEncoding(Sql* self, const char* encoding);
/// Pings the connection.
///
/// @return SQL_SUCCESS or SQL_ERROR
-int Sql_Ping(Sql *self);
+int Sql_Ping(Sql* self);
@@ -110,7 +111,7 @@ int Sql_Ping(Sql *self);
/// The output buffer must be at least strlen(from)*2+1 in size.
///
/// @return The size of the escaped string
-size_t Sql_EscapeString(Sql *self, char *out_to, const char *from);
+size_t Sql_EscapeString(Sql* self, char* out_to, const char* from);
@@ -118,7 +119,7 @@ size_t Sql_EscapeString(Sql *self, char *out_to, const char *from);
/// The output buffer must be at least from_len*2+1 in size.
///
/// @return The size of the escaped string
-size_t Sql_EscapeStringLen(Sql *self, char *out_to, const char *from, size_t from_len);
+size_t Sql_EscapeStringLen(Sql* self, char* out_to, const char* from, size_t from_len);
@@ -127,7 +128,7 @@ size_t Sql_EscapeStringLen(Sql *self, char *out_to, const char *from, size_t fro
/// The query is constructed as if it was sprintf.
///
/// @return SQL_SUCCESS or SQL_ERROR
-int Sql_Query(Sql *self, const char *query, ...);
+int Sql_Query(Sql* self, const char* query, ...);
@@ -136,7 +137,7 @@ int Sql_Query(Sql *self, const char *query, ...);
/// The query is constructed as if it was svprintf.
///
/// @return SQL_SUCCESS or SQL_ERROR
-int Sql_QueryV(Sql *self, const char *query, va_list args);
+int Sql_QueryV(Sql* self, const char* query, va_list args);
@@ -145,28 +146,28 @@ int Sql_QueryV(Sql *self, const char *query, va_list args);
/// The query is used directly.
///
/// @return SQL_SUCCESS or SQL_ERROR
-int Sql_QueryStr(Sql *self, const char *query);
+int Sql_QueryStr(Sql* self, const char* query);
/// Returns the number of the AUTO_INCREMENT column of the last INSERT/UPDATE query.
///
/// @return Value of the auto-increment column
-uint64 Sql_LastInsertId(Sql *self);
+uint64 Sql_LastInsertId(Sql* self);
/// Returns the number of columns in each row of the result.
///
/// @return Number of columns
-uint32 Sql_NumColumns(Sql *self);
+uint32 Sql_NumColumns(Sql* self);
/// Returns the number of rows in the result.
///
/// @return Number of rows
-uint64 Sql_NumRows(Sql *self);
+uint64 Sql_NumRows(Sql* self);
@@ -174,7 +175,7 @@ uint64 Sql_NumRows(Sql *self);
/// The data of the previous row is no longer valid.
///
/// @return SQL_SUCCESS, SQL_ERROR or SQL_NO_DATA
-int Sql_NextRow(Sql *self);
+int Sql_NextRow(Sql* self);
@@ -182,12 +183,12 @@ int Sql_NextRow(Sql *self);
/// The data remains valid until the next row is fetched or the result is freed.
///
/// @return SQL_SUCCESS or SQL_ERROR
-int Sql_GetData(Sql *self, size_t col, char **out_buf, size_t *out_len);
+int Sql_GetData(Sql* self, size_t col, char** out_buf, size_t* out_len);
/// Frees the result of the query.
-void Sql_FreeResult(Sql *self);
+void Sql_FreeResult(Sql* self);
@@ -197,22 +198,22 @@ void Sql_FreeResult(Sql *self);
#define Sql_ShowDebug(self) Sql_ShowDebug_(self, __FILE__, __LINE__)
#endif
/// Shows debug information (last query).
-void Sql_ShowDebug_(Sql *self, const char *debug_file, const unsigned long debug_line);
+void Sql_ShowDebug_(Sql* self, const char* debug_file, const unsigned long debug_line);
/// Frees a Sql handle returned by Sql_Malloc.
-void Sql_Free(Sql *self);
+void Sql_Free(Sql* self);
///////////////////////////////////////////////////////////////////////////////
// Prepared Statements
///////////////////////////////////////////////////////////////////////////////
-// Parameters are placed in the statement by embedding question mark ('?')
+// Parameters are placed in the statement by embedding question mark ('?')
// characters into the query at the appropriate positions.
// The markers are legal only in places where they represent data.
-// The markers cannot be inside quotes. Quotes will be added automatically
+// The markers cannot be inside quotes. Quotes will be added automatically
// when they are required.
//
// example queries with parameters:
@@ -226,7 +227,7 @@ void Sql_Free(Sql *self);
/// Queries in Sql and SqlStmt are independent and don't affect each other.
///
/// @return SqlStmt handle or NULL if an error occured
-struct SqlStmt *SqlStmt_Malloc(Sql *sql);
+struct SqlStmt* SqlStmt_Malloc(Sql* sql);
@@ -235,7 +236,7 @@ struct SqlStmt *SqlStmt_Malloc(Sql *sql);
/// The query is constructed as if it was sprintf.
///
/// @return SQL_SUCCESS or SQL_ERROR
-int SqlStmt_Prepare(SqlStmt *self, const char *query, ...);
+int SqlStmt_Prepare(SqlStmt* self, const char* query, ...);
@@ -244,7 +245,7 @@ int SqlStmt_Prepare(SqlStmt *self, const char *query, ...);
/// The query is constructed as if it was svprintf.
///
/// @return SQL_SUCCESS or SQL_ERROR
-int SqlStmt_PrepareV(SqlStmt *self, const char *query, va_list args);
+int SqlStmt_PrepareV(SqlStmt* self, const char* query, va_list args);
@@ -253,14 +254,14 @@ int SqlStmt_PrepareV(SqlStmt *self, const char *query, va_list args);
/// The query is used directly.
///
/// @return SQL_SUCCESS or SQL_ERROR
-int SqlStmt_PrepareStr(SqlStmt *self, const char *query);
+int SqlStmt_PrepareStr(SqlStmt* self, const char* query);
/// Returns the number of parameters in the prepared statement.
///
/// @return Number or paramenters
-size_t SqlStmt_NumParams(SqlStmt *self);
+size_t SqlStmt_NumParams(SqlStmt* self);
@@ -269,7 +270,7 @@ size_t SqlStmt_NumParams(SqlStmt *self);
/// All parameters should have bindings.
///
/// @return SQL_SUCCESS or SQL_ERROR
-int SqlStmt_BindParam(SqlStmt *self, size_t idx, SqlDataType buffer_type, void *buffer, size_t buffer_len);
+int SqlStmt_BindParam(SqlStmt* self, size_t idx, SqlDataType buffer_type, void* buffer, size_t buffer_len);
@@ -277,38 +278,38 @@ int SqlStmt_BindParam(SqlStmt *self, size_t idx, SqlDataType buffer_type, void *
/// Any previous result is freed and all column bindings are removed.
///
/// @return SQL_SUCCESS or SQL_ERROR
-int SqlStmt_Execute(SqlStmt *self);
+int SqlStmt_Execute(SqlStmt* self);
/// Returns the number of the AUTO_INCREMENT column of the last INSERT/UPDATE statement.
///
/// @return Value of the auto-increment column
-uint64 SqlStmt_LastInsertId(SqlStmt *self);
+uint64 SqlStmt_LastInsertId(SqlStmt* self);
/// Returns the number of columns in each row of the result.
///
/// @return Number of columns
-size_t SqlStmt_NumColumns(SqlStmt *self);
+size_t SqlStmt_NumColumns(SqlStmt* self);
/// Binds the result of a column to a buffer.
/// The buffer will be filled with data when the next row is fetched.
-/// For string/enum buffer types there has to be enough space for the data
+/// For string/enum buffer types there has to be enough space for the data
/// and the nul-terminator (an extra byte).
///
/// @return SQL_SUCCESS or SQL_ERROR
-int SqlStmt_BindColumn(SqlStmt *self, size_t idx, SqlDataType buffer_type, void *buffer, size_t buffer_len, uint32 *out_length, int8 *out_is_null);
+int SqlStmt_BindColumn(SqlStmt* self, size_t idx, SqlDataType buffer_type, void* buffer, size_t buffer_len, uint32* out_length, int8* out_is_null);
/// Returns the number of rows in the result.
///
/// @return Number of rows
-uint64 SqlStmt_NumRows(SqlStmt *self);
+uint64 SqlStmt_NumRows(SqlStmt* self);
@@ -316,12 +317,12 @@ uint64 SqlStmt_NumRows(SqlStmt *self);
/// All column bindings will be filled with data.
///
/// @return SQL_SUCCESS, SQL_ERROR or SQL_NO_DATA
-int SqlStmt_NextRow(SqlStmt *self);
+int SqlStmt_NextRow(SqlStmt* self);
/// Frees the result of the statement execution.
-void SqlStmt_FreeResult(SqlStmt *self);
+void SqlStmt_FreeResult(SqlStmt* self);
@@ -331,12 +332,12 @@ void SqlStmt_FreeResult(SqlStmt *self);
#define SqlStmt_ShowDebug(self) SqlStmt_ShowDebug_(self, __FILE__, __LINE__)
#endif
/// Shows debug information (with statement).
-void SqlStmt_ShowDebug_(SqlStmt *self, const char *debug_file, const unsigned long debug_line);
+void SqlStmt_ShowDebug_(SqlStmt* self, const char* debug_file, const unsigned long debug_line);
/// Frees a SqlStmt returned by SqlStmt_Malloc.
-void SqlStmt_Free(SqlStmt *self);
+void SqlStmt_Free(SqlStmt* self);
diff --git a/src/common/strlib.c b/src/common/strlib.c
index 89aac3b40..dfacbf136 100644
--- a/src/common/strlib.c
+++ b/src/common/strlib.c
@@ -14,348 +14,360 @@
#define J_MAX_MALLOC_SIZE 65535
// escapes a string in-place (' -> \' , \ -> \\ , % -> _)
-char *jstrescape(char *pt)
+char* jstrescape (char* pt)
{
- //copy from here
- 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;
- case '%':
- pt[j++] = '_';
- i++;
- break;
- default:
- pt[j++] = ptr[i++];
- }
- }
- pt[j++] = '\0';
- aFree(ptr);
- return pt;
+ //copy from here
+ 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;
+ case '%':
+ pt[j++] = '_'; i++;
+ break;
+ default:
+ pt[j++] = ptr[i++];
+ }
+ }
+ pt[j++] = '\0';
+ aFree(ptr);
+ return pt;
}
// escapes a string into a provided buffer
-char *jstrescapecpy(char *pt, const char *spt)
+char* jstrescapecpy (char* pt, const char* spt)
{
- //copy from here
- //WARNING: Target string pt should be able to hold strlen(spt)*2, as each time
- //a escape character is found, the target's final length increases! [Skotlex]
- int i =0, j=0;
-
- if (!spt) { //Return an empty string [Skotlex]
- pt[0] = '\0';
- return &pt[0];
- }
-
- while (spt[i] != '\0') {
- switch (spt[i]) {
- case '\'':
- pt[j++] = '\\';
- pt[j++] = spt[i++];
- break;
- case '\\':
- pt[j++] = '\\';
- pt[j++] = spt[i++];
- break;
- case '%':
- pt[j++] = '_';
- i++;
- break;
- default:
- pt[j++] = spt[i++];
- }
- }
- pt[j++] = '\0';
- return &pt[0];
+ //copy from here
+ //WARNING: Target string pt should be able to hold strlen(spt)*2, as each time
+ //a escape character is found, the target's final length increases! [Skotlex]
+ int i =0, j=0;
+
+ if (!spt) { //Return an empty string [Skotlex]
+ pt[0] = '\0';
+ return &pt[0];
+ }
+
+ while (spt[i] != '\0') {
+ switch (spt[i]) {
+ case '\'':
+ pt[j++] = '\\';
+ pt[j++] = spt[i++];
+ break;
+ case '\\':
+ pt[j++] = '\\';
+ pt[j++] = spt[i++];
+ break;
+ case '%':
+ pt[j++] = '_'; i++;
+ break;
+ default:
+ pt[j++] = spt[i++];
+ }
+ }
+ pt[j++] = '\0';
+ return &pt[0];
}
// escapes exactly 'size' bytes of a string into a provided buffer
-int jmemescapecpy(char *pt, const char *spt, int size)
+int jmemescapecpy (char* pt, const 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;
- case '\\':
- pt[j++] = '\\';
- pt[j++] = spt[i++];
- break;
- case '%':
- pt[j++] = '_';
- i++;
- break;
- default:
- pt[j++] = spt[i++];
- }
- }
- // copy size is 0 ~ (j-1)
- return j;
+ //copy from here
+ int i =0, j=0;
+
+ while (i < size) {
+ switch (spt[i]) {
+ case '\'':
+ pt[j++] = '\\';
+ pt[j++] = spt[i++];
+ break;
+ case '\\':
+ pt[j++] = '\\';
+ pt[j++] = spt[i++];
+ break;
+ case '%':
+ pt[j++] = '_'; i++;
+ break;
+ default:
+ pt[j++] = spt[i++];
+ }
+ }
+ // 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(char* str)
{
- int i;
- int change = 0;
+ int i;
+ int change = 0;
- for (i = 0; str[i]; i++) {
- if (ISCNTRL(str[i])) {
- str[i] = '_';
- change = 1;
- }
- }
+ for(i = 0; str[i]; i++) {
+ if (ISCNTRL(str[i])) {
+ str[i] = '_';
+ change = 1;
+ }
+ }
- return change;
+ return change;
}
// Removes characters identified by ISSPACE from the start and end of the string
// NOTE: make sure the string is not const!!
-char *trim(char *str)
+char* trim(char* str)
{
- size_t start;
- size_t end;
-
- if (str == NULL)
- return str;
-
- // get start position
- for (start = 0; str[start] && ISSPACE(str[start]); ++start)
- ;
- // get end position
- for (end = strlen(str); start < end && str[end-1] && ISSPACE(str[end-1]); --end)
- ;
- // trim
- if (start == end)
- *str = '\0';// empty string
- else {
- // move string with nul terminator
- str[end] = '\0';
- memmove(str,str+start,end-start+1);
- }
- return str;
+ size_t start;
+ size_t end;
+
+ if( str == NULL )
+ return str;
+
+ // get start position
+ for( start = 0; str[start] && ISSPACE(str[start]); ++start )
+ ;
+ // get end position
+ for( end = strlen(str); start < end && str[end-1] && ISSPACE(str[end-1]); --end )
+ ;
+ // trim
+ if( start == end )
+ *str = '\0';// empty string
+ else
+ {// move string with nul terminator
+ str[end] = '\0';
+ memmove(str,str+start,end-start+1);
+ }
+ return str;
}
// Converts one or more consecutive occurences of the delimiters into a single space
// and removes such occurences from the beginning and end of string
// NOTE: make sure the string is not const!!
-char *normalize_name(char *str,const char *delims)
+char* normalize_name(char* str,const char* delims)
{
- char *in = str;
- char *out = str;
- int put_space = 0;
-
- if (str == NULL || delims == NULL)
- return str;
-
- // trim start of string
- while (*in && strchr(delims,*in))
- ++in;
- while (*in) {
- if (put_space) {
- // replace trim characters with a single space
- *out = ' ';
- ++out;
- }
- // copy non trim characters
- while (*in && !strchr(delims,*in)) {
- *out = *in;
- ++out;
- ++in;
- }
- // skip trim characters
- while (*in && strchr(delims,*in))
- ++in;
- put_space = 1;
- }
- *out = '\0';
- return str;
+ char* in = str;
+ char* out = str;
+ int put_space = 0;
+
+ if( str == NULL || delims == NULL )
+ return str;
+
+ // trim start of string
+ while( *in && strchr(delims,*in) )
+ ++in;
+ while( *in )
+ {
+ if( put_space )
+ {// replace trim characters with a single space
+ *out = ' ';
+ ++out;
+ }
+ // copy non trim characters
+ while( *in && !strchr(delims,*in) )
+ {
+ *out = *in;
+ ++out;
+ ++in;
+ }
+ // skip trim characters
+ while( *in && strchr(delims,*in) )
+ ++in;
+ put_space = 1;
+ }
+ *out = '\0';
+ return str;
}
-//stristr: Case insensitive version of strstr, code taken from
+//stristr: Case insensitive version of strstr, code taken from
//http://www.daniweb.com/code/snippet313.html, Dave Sinkula
//
-const char *stristr(const char *haystack, const char *needle)
+const char* stristr(const char* haystack, const char* needle)
{
- if (!*needle) {
- return haystack;
- }
- for (; *haystack; ++haystack) {
- if (TOUPPER(*haystack) == TOUPPER(*needle)) {
- // matched starting char -- loop through remaining chars
- const char *h, *n;
- for (h = haystack, n = needle; *h && *n; ++h, ++n) {
- if (TOUPPER(*h) != TOUPPER(*n)) {
- break;
- }
- }
- if (!*n) { // matched all of 'needle' to null termination
- return haystack; // return the start of the match
- }
- }
- }
- return 0;
+ if ( !*needle )
+ {
+ return haystack;
+ }
+ for ( ; *haystack; ++haystack )
+ {
+ if ( TOUPPER(*haystack) == TOUPPER(*needle) )
+ {
+ // matched starting char -- loop through remaining chars
+ const char *h, *n;
+ for ( h = haystack, n = needle; *h && *n; ++h, ++n )
+ {
+ if ( TOUPPER(*h) != TOUPPER(*n) )
+ {
+ break;
+ }
+ }
+ if ( !*n ) // matched all of 'needle' to null termination
+ {
+ return haystack; // return the start of the match
+ }
+ }
+ }
+ return 0;
}
#ifdef __WIN32
-char *_strtok_r(char *s1, const char *s2, char **lasts)
+char* _strtok_r(char *s1, const char *s2, char **lasts)
{
- char *ret;
-
- if (s1 == NULL)
- s1 = *lasts;
- while (*s1 && strchr(s2, *s1))
- ++s1;
- if (*s1 == '\0')
- return NULL;
- ret = s1;
- while (*s1 && !strchr(s2, *s1))
- ++s1;
- if (*s1)
- *s1++ = '\0';
- *lasts = s1;
- return ret;
+ char *ret;
+
+ if (s1 == NULL)
+ s1 = *lasts;
+ while(*s1 && strchr(s2, *s1))
+ ++s1;
+ if(*s1 == '\0')
+ return NULL;
+ ret = s1;
+ while(*s1 && !strchr(s2, *s1))
+ ++s1;
+ if(*s1)
+ *s1++ = '\0';
+ *lasts = s1;
+ return ret;
}
#endif
#if !(defined(WIN32) && defined(_MSC_VER) && _MSC_VER >= 1400) && !defined(HAVE_STRNLEN)
/* Find the length of STRING, but scan at most MAXLEN characters.
If no '\0' terminator is found in that many characters, return MAXLEN. */
-size_t strnlen(const char *string, size_t maxlen)
+size_t strnlen (const char* string, size_t maxlen)
{
- const char *end = (const char *)memchr(string, '\0', maxlen);
- return end ? (size_t)(end - string) : maxlen;
+ const char* end = (const char*)memchr(string, '\0', maxlen);
+ return end ? (size_t) (end - string) : maxlen;
}
#endif
#if defined(WIN32) && defined(_MSC_VER) && _MSC_VER <= 1200
-uint64 strtoull(const char *str, char **endptr, int base)
+uint64 strtoull(const char* str, char** endptr, int base)
{
- uint64 result;
- int count;
- int n;
-
- if (base == 0) {
- if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
- base = 16;
- else if (str[0] == '0')
- base = 8;
- else
- base = 10;
- }
-
- if (base == 8)
- count = sscanf(str, "%I64o%n", &result, &n);
- else if (base == 10)
- count = sscanf(str, "%I64u%n", &result, &n);
- else if (base == 16)
- count = sscanf(str, "%I64x%n", &result, &n);
- else
- count = 0; // fail
-
- if (count < 1) {
- errno = EINVAL;
- result = 0;
- n = 0;
- }
-
- if (endptr)
- *endptr = (char *)str + n;
-
- return result;
+ uint64 result;
+ int count;
+ int n;
+
+ if( base == 0 )
+ {
+ if( str[0] == '0' && (str[1] == 'x' || str[1] == 'X') )
+ base = 16;
+ else
+ if( str[0] == '0' )
+ base = 8;
+ else
+ base = 10;
+ }
+
+ if( base == 8 )
+ count = sscanf(str, "%I64o%n", &result, &n);
+ else
+ if( base == 10 )
+ count = sscanf(str, "%I64u%n", &result, &n);
+ else
+ if( base == 16 )
+ count = sscanf(str, "%I64x%n", &result, &n);
+ else
+ count = 0; // fail
+
+ if( count < 1 )
+ {
+ errno = EINVAL;
+ result = 0;
+ n = 0;
+ }
+
+ if( endptr )
+ *endptr = (char*)str + n;
+
+ return result;
}
#endif
//----------------------------------------------------
// E-mail check: return 0 (not correct) or 1 (valid).
//----------------------------------------------------
-int e_mail_check(char *email)
+int e_mail_check(char* email)
{
- char ch;
- char *last_arobas;
- size_t len = strlen(email);
+ char ch;
+ char* last_arobas;
+ size_t len = strlen(email);
- // athena limits
- if (len < 3 || len > 39)
- return 0;
+ // athena limits
+ if (len < 3 || len > 39)
+ return 0;
- // part of RFC limits (official reference of e-mail description)
- if (strchr(email, '@') == NULL || email[len-1] == '@')
- return 0;
+ // part of RFC limits (official reference of e-mail description)
+ if (strchr(email, '@') == NULL || email[len-1] == '@')
+ return 0;
- if (email[len-1] == '.')
- return 0;
+ if (email[len-1] == '.')
+ return 0;
- last_arobas = strrchr(email, '@');
+ last_arobas = strrchr(email, '@');
- if (strstr(last_arobas, "@.") != NULL || strstr(last_arobas, "..") != NULL)
- return 0;
+ if (strstr(last_arobas, "@.") != NULL || strstr(last_arobas, "..") != NULL)
+ return 0;
- for (ch = 1; ch < 32; ch++)
- if (strchr(last_arobas, ch) != NULL)
- return 0;
+ for(ch = 1; ch < 32; ch++)
+ if (strchr(last_arobas, ch) != NULL)
+ return 0;
- if (strchr(last_arobas, ' ') != NULL || strchr(last_arobas, ';') != NULL)
- return 0;
+ if (strchr(last_arobas, ' ') != NULL || strchr(last_arobas, ';') != NULL)
+ return 0;
- // all correct
- return 1;
+ // all correct
+ return 1;
}
//--------------------------------------------------
// Return numerical value of a switch configuration
// on/off, english, français, deutsch, español
//--------------------------------------------------
-int config_switch(const char *str)
+int config_switch(const char* str)
{
- if (strcmpi(str, "on") == 0 || strcmpi(str, "yes") == 0 || strcmpi(str, "oui") == 0 || strcmpi(str, "ja") == 0 || strcmpi(str, "si") == 0)
- return 1;
- if (strcmpi(str, "off") == 0 || strcmpi(str, "no") == 0 || strcmpi(str, "non") == 0 || strcmpi(str, "nein") == 0)
- return 0;
+ if (strcmpi(str, "on") == 0 || strcmpi(str, "yes") == 0 || strcmpi(str, "oui") == 0 || strcmpi(str, "ja") == 0 || strcmpi(str, "si") == 0)
+ return 1;
+ if (strcmpi(str, "off") == 0 || strcmpi(str, "no") == 0 || strcmpi(str, "non") == 0 || strcmpi(str, "nein") == 0)
+ return 0;
- return (int)strtol(str, NULL, 0);
+ return (int)strtol(str, NULL, 0);
}
/// strncpy that always nul-terminates the string
-char *safestrncpy(char *dst, const char *src, size_t n)
+char* safestrncpy(char* dst, const char* src, size_t n)
{
- if (n > 0) {
- char *d = dst;
- const char *s = src;
- d[--n] = '\0';/* nul-terminate string */
- for (; n > 0; --n) {
- if ((*d++ = *s++) == '\0') {
- /* nul-pad remaining bytes */
- while (--n > 0)
- *d++ = '\0';
- break;
- }
- }
- }
- return dst;
+ if( n > 0 )
+ {
+ char* d = dst;
+ const char* s = src;
+ d[--n] = '\0';/* nul-terminate string */
+ for( ; n > 0; --n )
+ {
+ if( (*d++ = *s++) == '\0' )
+ {/* nul-pad remaining bytes */
+ while( --n > 0 )
+ *d++ = '\0';
+ break;
+ }
+ }
+ }
+ return dst;
}
/// doesn't crash on null pointer
-size_t safestrnlen(const char *string, size_t maxlen)
+size_t safestrnlen(const char* string, size_t maxlen)
{
- return (string != NULL) ? strnlen(string, maxlen) : 0;
+ return ( string != NULL ) ? strnlen(string, maxlen) : 0;
}
/// Works like snprintf, but always nul-terminates the buffer.
@@ -367,40 +379,41 @@ size_t safestrnlen(const char *string, size_t maxlen)
/// @param fmt Format string
/// @param ... Format arguments
/// @return The size of the string or -1 if the buffer is too small
-int safesnprintf(char *buf, size_t sz, const char *fmt, ...)
+int safesnprintf(char* buf, size_t sz, const char* fmt, ...)
{
- va_list ap;
- int ret;
-
- va_start(ap,fmt);
- ret = vsnprintf(buf, sz, fmt, ap);
- va_end(ap);
- if (ret < 0 || (size_t)ret >= sz) {
- // overflow
- buf[sz-1] = '\0';// always nul-terminate
- return -1;
- }
- return ret;
+ va_list ap;
+ int ret;
+
+ va_start(ap,fmt);
+ ret = vsnprintf(buf, sz, fmt, ap);
+ va_end(ap);
+ if( ret < 0 || (size_t)ret >= sz )
+ {// overflow
+ buf[sz-1] = '\0';// always nul-terminate
+ return -1;
+ }
+ return ret;
}
/// Returns the line of the target position in the string.
/// Lines start at 1.
-int strline(const char *str, size_t pos)
+int strline(const char* str, size_t pos)
{
- const char *target;
- int line;
-
- if (str == NULL || pos == 0)
- return 1;
-
- target = str+pos;
- for (line = 1; ; ++line) {
- str = strchr(str, '\n');
- if (str == NULL || target <= str)
- break;// found target line
- ++str;// skip newline
- }
- return line;
+ const char* target;
+ int line;
+
+ if( str == NULL || pos == 0 )
+ return 1;
+
+ target = str+pos;
+ for( line = 1; ; ++line )
+ {
+ str = strchr(str, '\n');
+ if( str == NULL || target <= str )
+ break;// found target line
+ ++str;// skip newline
+ }
+ return line;
}
/// Produces the hexadecimal representation of the given input.
@@ -410,18 +423,19 @@ int strline(const char *str, size_t pos)
/// @param output Output string
/// @param input Binary input buffer
/// @param count Number of bytes to convert
-bool bin2hex(char *output, unsigned char *input, size_t count)
+bool bin2hex(char* output, unsigned char* input, size_t count)
{
- char toHex[] = "0123456789abcdef";
- size_t i;
-
- for (i = 0; i < count; ++i) {
- *output++ = toHex[(*input & 0xF0) >> 4];
- *output++ = toHex[(*input & 0x0F) >> 0];
- ++input;
- }
- *output = '\0';
- return true;
+ char toHex[] = "0123456789abcdef";
+ size_t i;
+
+ for( i = 0; i < count; ++i )
+ {
+ *output++ = toHex[(*input & 0xF0) >> 4];
+ *output++ = toHex[(*input & 0x0F) >> 0];
+ ++input;
+ }
+ *output = '\0';
+ return true;
}
@@ -432,134 +446,146 @@ bool bin2hex(char *output, unsigned char *input, size_t count)
///
/// @param sv Parse state
/// @return 1 if a field was parsed, 0 if already done, -1 on error.
-int sv_parse_next(struct s_svstate *sv)
+int sv_parse_next(struct s_svstate* sv)
{
- enum {
- START_OF_FIELD,
- PARSING_FIELD,
- PARSING_C_ESCAPE,
- END_OF_FIELD,
- TERMINATE,
- END
- } state;
- const char *str;
- int len;
- enum e_svopt opt;
- char delim;
- int i;
-
- if (sv == NULL)
- return -1;// error
-
- str = sv->str;
- len = sv->len;
- opt = sv->opt;
- delim = sv->delim;
-
- // check opt
- if (delim == '\n' && (opt&(SV_TERMINATE_CRLF|SV_TERMINATE_LF))) {
- ShowError("sv_parse_next: delimiter '\\n' is not compatible with options SV_TERMINATE_LF or SV_TERMINATE_CRLF.\n");
- return -1;// error
- }
- if (delim == '\r' && (opt&(SV_TERMINATE_CRLF|SV_TERMINATE_CR))) {
- ShowError("sv_parse_next: delimiter '\\r' is not compatible with options SV_TERMINATE_CR or SV_TERMINATE_CRLF.\n");
- return -1;// error
- }
-
- if (sv->done || str == NULL) {
- sv->done = true;
- return 0;// nothing to parse
- }
+ enum {
+ START_OF_FIELD,
+ PARSING_FIELD,
+ PARSING_C_ESCAPE,
+ END_OF_FIELD,
+ TERMINATE,
+ END
+ } state;
+ const char* str;
+ int len;
+ enum e_svopt opt;
+ char delim;
+ int i;
+
+ if( sv == NULL )
+ return -1;// error
+
+ str = sv->str;
+ len = sv->len;
+ opt = sv->opt;
+ delim = sv->delim;
+
+ // check opt
+ if( delim == '\n' && (opt&(SV_TERMINATE_CRLF|SV_TERMINATE_LF)) )
+ {
+ ShowError("sv_parse_next: delimiter '\\n' is not compatible with options SV_TERMINATE_LF or SV_TERMINATE_CRLF.\n");
+ return -1;// error
+ }
+ if( delim == '\r' && (opt&(SV_TERMINATE_CRLF|SV_TERMINATE_CR)) )
+ {
+ ShowError("sv_parse_next: delimiter '\\r' is not compatible with options SV_TERMINATE_CR or SV_TERMINATE_CRLF.\n");
+ return -1;// error
+ }
+
+ if( sv->done || str == NULL )
+ {
+ sv->done = true;
+ return 0;// nothing to parse
+ }
#define IS_END() ( i >= len )
#define IS_DELIM() ( str[i] == delim )
#define IS_TERMINATOR() ( \
- ((opt&SV_TERMINATE_LF) && str[i] == '\n') || \
- ((opt&SV_TERMINATE_CR) && str[i] == '\r') || \
- ((opt&SV_TERMINATE_CRLF) && i+1 < len && str[i] == '\r' && str[i+1] == '\n') )
+ ((opt&SV_TERMINATE_LF) && str[i] == '\n') || \
+ ((opt&SV_TERMINATE_CR) && str[i] == '\r') || \
+ ((opt&SV_TERMINATE_CRLF) && i+1 < len && str[i] == '\r' && str[i+1] == '\n') )
#define IS_C_ESCAPE() ( (opt&SV_ESCAPE_C) && str[i] == '\\' )
#define SET_FIELD_START() sv->start = i
#define SET_FIELD_END() sv->end = i
- i = sv->off;
- state = START_OF_FIELD;
- while (state != END) {
- switch (state) {
- case START_OF_FIELD:// record start of field and start parsing it
- SET_FIELD_START();
- state = PARSING_FIELD;
- break;
-
- case PARSING_FIELD:// skip field character
- if (IS_END() || IS_DELIM() || IS_TERMINATOR())
- state = END_OF_FIELD;
- else if (IS_C_ESCAPE())
- state = PARSING_C_ESCAPE;
- else
- ++i;// normal character
- break;
-
- case PARSING_C_ESCAPE: { // skip escape sequence (validates it too)
- ++i;// '\\'
- if (IS_END()) {
- ShowError("sv_parse_next: empty escape sequence\n");
- return -1;
- }
- if (str[i] == 'x') {
- // hex escape
- ++i;// 'x'
- if (IS_END() || !ISXDIGIT(str[i])) {
- ShowError("sv_parse_next: \\x with no following hex digits\n");
- return -1;
- }
- do {
- ++i;// hex digit
- } while (!IS_END() && ISXDIGIT(str[i]));
- } else if (str[i] == '0' || str[i] == '1' || str[i] == '2') {
- // octal escape
- ++i;// octal digit
- if (!IS_END() && str[i] >= '0' && str[i] <= '7')
- ++i;// octal digit
- if (!IS_END() && str[i] >= '0' && str[i] <= '7')
- ++i;// octal digit
- } else if (strchr(SV_ESCAPE_C_SUPPORTED, str[i])) {
- // supported escape character
- ++i;
- } else {
- ShowError("sv_parse_next: unknown escape sequence \\%c\n", str[i]);
- return -1;
- }
- state = PARSING_FIELD;
- break;
- }
-
- case END_OF_FIELD:// record end of field and stop
- SET_FIELD_END();
- state = END;
- if (IS_END())
- ;// nothing else
- else if (IS_DELIM())
- ++i;// delim
- else if (IS_TERMINATOR())
- state = TERMINATE;
- break;
-
- case TERMINATE:
+ i = sv->off;
+ state = START_OF_FIELD;
+ while( state != END )
+ {
+ switch( state )
+ {
+ case START_OF_FIELD:// record start of field and start parsing it
+ SET_FIELD_START();
+ state = PARSING_FIELD;
+ break;
+
+ case PARSING_FIELD:// skip field character
+ if( IS_END() || IS_DELIM() || IS_TERMINATOR() )
+ state = END_OF_FIELD;
+ else if( IS_C_ESCAPE() )
+ state = PARSING_C_ESCAPE;
+ else
+ ++i;// normal character
+ break;
+
+ case PARSING_C_ESCAPE:// skip escape sequence (validates it too)
+ {
+ ++i;// '\\'
+ if( IS_END() )
+ {
+ ShowError("sv_parse_next: empty escape sequence\n");
+ return -1;
+ }
+ if( str[i] == 'x' )
+ {// hex escape
+ ++i;// 'x'
+ if( IS_END() || !ISXDIGIT(str[i]) )
+ {
+ ShowError("sv_parse_next: \\x with no following hex digits\n");
+ return -1;
+ }
+ do{
+ ++i;// hex digit
+ }while( !IS_END() && ISXDIGIT(str[i]));
+ }
+ else if( str[i] == '0' || str[i] == '1' || str[i] == '2' )
+ {// octal escape
+ ++i;// octal digit
+ if( !IS_END() && str[i] >= '0' && str[i] <= '7' )
+ ++i;// octal digit
+ if( !IS_END() && str[i] >= '0' && str[i] <= '7' )
+ ++i;// octal digit
+ }
+ else if( strchr(SV_ESCAPE_C_SUPPORTED, str[i]) )
+ {// supported escape character
+ ++i;
+ }
+ else
+ {
+ ShowError("sv_parse_next: unknown escape sequence \\%c\n", str[i]);
+ return -1;
+ }
+ state = PARSING_FIELD;
+ break;
+ }
+
+ case END_OF_FIELD:// record end of field and stop
+ SET_FIELD_END();
+ state = END;
+ if( IS_END() )
+ ;// nothing else
+ else if( IS_DELIM() )
+ ++i;// delim
+ else if( IS_TERMINATOR() )
+ state = TERMINATE;
+ break;
+
+ case TERMINATE:
#if 0
- // skip line terminator
- if ((opt&SV_TERMINATE_CRLF) && i+1 < len && str[i] == '\r' && str[i+1] == '\n')
- i += 2;// CRLF
- else
- ++i;// CR or LF
+ // skip line terminator
+ if( (opt&SV_TERMINATE_CRLF) && i+1 < len && str[i] == '\r' && str[i+1] == '\n' )
+ i += 2;// CRLF
+ else
+ ++i;// CR or LF
#endif
- sv->done = true;
- state = END;
- break;
- }
- }
- if (IS_END())
- sv->done = true;
- sv->off = i;
+ sv->done = true;
+ state = END;
+ break;
+ }
+ }
+ if( IS_END() )
+ sv->done = true;
+ sv->off = i;
#undef IS_END
#undef IS_DELIM
@@ -568,7 +594,7 @@ int sv_parse_next(struct s_svstate *sv)
#undef SET_FIELD_START
#undef SET_FIELD_END
- return 1;
+ return 1;
}
@@ -577,13 +603,13 @@ int sv_parse_next(struct s_svstate *sv)
/// out_pos[0] and out_pos[1] are the start and end of line.
/// Other position pairs are the start and end of fields.
/// Returns the number of fields found or -1 if an error occurs.
-///
+///
/// out_pos can be NULL.
/// If a line terminator is found, the end position is placed there.
-/// out_pos[2] and out_pos[3] for the first field, out_pos[4] and out_pos[5]
+/// out_pos[2] and out_pos[3] for the first field, out_pos[4] and out_pos[5]
/// for the seconds field and so on.
/// Unfilled positions are set to -1.
-///
+///
/// @param str String to parse
/// @param len Length of the string
/// @param startoff Where to start parsing
@@ -592,34 +618,35 @@ int sv_parse_next(struct s_svstate *sv)
/// @param npos Size of the pos array
/// @param opt Options that determine the parsing behaviour
/// @return Number of fields found in the string or -1 if an error occured
-int sv_parse(const char *str, int len, int startoff, char delim, int *out_pos, int npos, enum e_svopt opt)
+int sv_parse(const char* str, int len, int startoff, char delim, int* out_pos, int npos, enum e_svopt opt)
{
- struct s_svstate sv;
- int count;
-
- // initialize
- if (out_pos == NULL) npos = 0;
- for (count = 0; count < npos; ++count)
- out_pos[count] = -1;
- sv.str = str;
- sv.len = len;
- sv.off = startoff;
- sv.opt = opt;
- sv.delim = delim;
- sv.done = false;
-
- // parse
- count = 0;
- if (npos > 0) out_pos[0] = startoff;
- while (!sv.done) {
- ++count;
- if (sv_parse_next(&sv) <= 0)
- return -1;// error
- if (npos > count*2) out_pos[count*2] = sv.start;
- if (npos > count*2+1) out_pos[count*2+1] = sv.end;
- }
- if (npos > 1) out_pos[1] = sv.off;
- return count;
+ struct s_svstate sv;
+ int count;
+
+ // initialize
+ if( out_pos == NULL ) npos = 0;
+ for( count = 0; count < npos; ++count )
+ out_pos[count] = -1;
+ sv.str = str;
+ sv.len = len;
+ sv.off = startoff;
+ sv.opt = opt;
+ sv.delim = delim;
+ sv.done = false;
+
+ // parse
+ count = 0;
+ if( npos > 0 ) out_pos[0] = startoff;
+ while( !sv.done )
+ {
+ ++count;
+ if( sv_parse_next(&sv) <= 0 )
+ return -1;// error
+ if( npos > count*2 ) out_pos[count*2] = sv.start;
+ if( npos > count*2+1 ) out_pos[count*2+1] = sv.end;
+ }
+ if( npos > 1 ) out_pos[1] = sv.off;
+ return count;
}
/// Splits a delim-separated string.
@@ -628,11 +655,11 @@ int sv_parse(const char *str, int len, int startoff, char delim, int *out_pos, i
/// out_fields[0] is the start of the next line.
/// Other entries are the start of fields (nul-teminated).
/// Returns the number of fields found or -1 if an error occurs.
-///
+///
/// out_fields can be NULL.
/// Fields that don't fit in out_fields are not nul-terminated.
/// Extra entries in out_fields are filled with the end of the last field (empty string).
-///
+///
/// @param str String to parse
/// @param len Length of the string
/// @param startoff Where to start parsing
@@ -641,64 +668,75 @@ int sv_parse(const char *str, int len, int startoff, char delim, int *out_pos, i
/// @param nfields Size of the field array
/// @param opt Options that determine the parsing behaviour
/// @return Number of fields found in the string or -1 if an error occured
-int sv_split(char *str, int len, int startoff, char delim, char **out_fields, int nfields, enum e_svopt opt)
+int sv_split(char* str, int len, int startoff, char delim, char** out_fields, int nfields, enum e_svopt opt)
{
- int pos[1024];
- int i;
- int done;
- char *end;
- int ret = sv_parse(str, len, startoff, delim, pos, ARRAYLENGTH(pos), opt);
-
- if (ret == -1 || out_fields == NULL || nfields <= 0)
- return ret; // nothing to do
-
- // next line
- end = str + pos[1];
- if (end[0] == '\0') {
- *out_fields = end;
- } else if ((opt&SV_TERMINATE_LF) && end[0] == '\n') {
- if (!(opt&SV_KEEP_TERMINATOR))
- end[0] = '\0';
- *out_fields = end + 1;
- } else if ((opt&SV_TERMINATE_CRLF) && end[0] == '\r' && end[1] == '\n') {
- if (!(opt&SV_KEEP_TERMINATOR))
- end[0] = end[1] = '\0';
- *out_fields = end + 2;
- } else if ((opt&SV_TERMINATE_CR) && end[0] == '\r') {
- if (!(opt&SV_KEEP_TERMINATOR))
- end[0] = '\0';
- *out_fields = end + 1;
- } else {
- ShowError("sv_split: unknown line delimiter 0x02%x.\n", (unsigned char)end[0]);
- return -1;// error
- }
- ++out_fields;
- --nfields;
-
- // fields
- i = 2;
- done = 0;
- while (done < ret && nfields > 0) {
- if (i < ARRAYLENGTH(pos)) {
- // split field
- *out_fields = str + pos[i];
- end = str + pos[i+1];
- *end = '\0';
- // next field
- i += 2;
- ++done;
- ++out_fields;
- --nfields;
- } else {
- // get more fields
- sv_parse(str, len, pos[i-1] + 1, delim, pos, ARRAYLENGTH(pos), opt);
- i = 2;
- }
- }
- // remaining fields
- for (i = 0; i < nfields; ++i)
- out_fields[i] = end;
- return ret;
+ int pos[1024];
+ int i;
+ int done;
+ char* end;
+ int ret = sv_parse(str, len, startoff, delim, pos, ARRAYLENGTH(pos), opt);
+
+ if( ret == -1 || out_fields == NULL || nfields <= 0 )
+ return ret; // nothing to do
+
+ // next line
+ end = str + pos[1];
+ if( end[0] == '\0' )
+ {
+ *out_fields = end;
+ }
+ else if( (opt&SV_TERMINATE_LF) && end[0] == '\n' )
+ {
+ if( !(opt&SV_KEEP_TERMINATOR) )
+ end[0] = '\0';
+ *out_fields = end + 1;
+ }
+ else if( (opt&SV_TERMINATE_CRLF) && end[0] == '\r' && end[1] == '\n' )
+ {
+ if( !(opt&SV_KEEP_TERMINATOR) )
+ end[0] = end[1] = '\0';
+ *out_fields = end + 2;
+ }
+ else if( (opt&SV_TERMINATE_CR) && end[0] == '\r' )
+ {
+ if( !(opt&SV_KEEP_TERMINATOR) )
+ end[0] = '\0';
+ *out_fields = end + 1;
+ }
+ else
+ {
+ ShowError("sv_split: unknown line delimiter 0x02%x.\n", (unsigned char)end[0]);
+ return -1;// error
+ }
+ ++out_fields;
+ --nfields;
+
+ // fields
+ i = 2;
+ done = 0;
+ while( done < ret && nfields > 0 )
+ {
+ if( i < ARRAYLENGTH(pos) )
+ {// split field
+ *out_fields = str + pos[i];
+ end = str + pos[i+1];
+ *end = '\0';
+ // next field
+ i += 2;
+ ++done;
+ ++out_fields;
+ --nfields;
+ }
+ else
+ {// get more fields
+ sv_parse(str, len, pos[i-1] + 1, delim, pos, ARRAYLENGTH(pos), opt);
+ i = 2;
+ }
+ }
+ // remaining fields
+ for( i = 0; i < nfields; ++i )
+ out_fields[i] = end;
+ return ret;
}
/// Escapes src to out_dest according to the format of the C compiler.
@@ -710,77 +748,69 @@ int sv_split(char *str, int len, int startoff, char delim, char **out_fields, in
/// @param len Length of the source string
/// @param escapes Extra characters to be escaped
/// @return Length of the escaped string
-size_t sv_escape_c(char *out_dest, const char *src, size_t len, const char *escapes)
+size_t sv_escape_c(char* out_dest, const char* src, size_t len, const char* escapes)
{
- size_t i;
- size_t j;
-
- if (out_dest == NULL)
- return 0;// nothing to do
- if (src == NULL) {
- // nothing to escape
- *out_dest = 0;
- return 0;
- }
- if (escapes == NULL)
- escapes = "";
-
- for (i = 0, j = 0; i < len; ++i) {
- switch (src[i]) {
- case '\0':// octal 0
- out_dest[j++] = '\\';
- out_dest[j++] = '0';
- out_dest[j++] = '0';
- out_dest[j++] = '0';
- break;
- case '\r':// carriage return
- out_dest[j++] = '\\';
- out_dest[j++] = 'r';
- break;
- case '\n':// line feed
- out_dest[j++] = '\\';
- out_dest[j++] = 'n';
- break;
- case '\\':// escape character
- out_dest[j++] = '\\';
- out_dest[j++] = '\\';
- break;
- default:
- if (strchr(escapes,src[i])) {
- // escape
- out_dest[j++] = '\\';
- switch (src[i]) {
- case '\a':
- out_dest[j++] = 'a';
- break;
- case '\b':
- out_dest[j++] = 'b';
- break;
- case '\t':
- out_dest[j++] = 't';
- break;
- case '\v':
- out_dest[j++] = 'v';
- break;
- case '\f':
- out_dest[j++] = 'f';
- break;
- case '\?':
- out_dest[j++] = '?';
- break;
- default:// to octal
- out_dest[j++] = '0'+((char)(((unsigned char)src[i]&0700)>>6));
- out_dest[j++] = '0'+((char)(((unsigned char)src[i]&0070)>>3));
- out_dest[j++] = '0'+((char)(((unsigned char)src[i]&0007)));
- break;
- }
- } else
- out_dest[j++] = src[i];
- break;
- }
- }
- out_dest[j] = 0;
- return j;
+ size_t i;
+ size_t j;
+
+ if( out_dest == NULL )
+ return 0;// nothing to do
+ if( src == NULL )
+ {// nothing to escape
+ *out_dest = 0;
+ return 0;
+ }
+ if( escapes == NULL )
+ escapes = "";
+
+ for( i = 0, j = 0; i < len; ++i )
+ {
+ switch( src[i] )
+ {
+ case '\0':// octal 0
+ out_dest[j++] = '\\';
+ out_dest[j++] = '0';
+ out_dest[j++] = '0';
+ out_dest[j++] = '0';
+ break;
+ case '\r':// carriage return
+ out_dest[j++] = '\\';
+ out_dest[j++] = 'r';
+ break;
+ case '\n':// line feed
+ out_dest[j++] = '\\';
+ out_dest[j++] = 'n';
+ break;
+ case '\\':// escape character
+ out_dest[j++] = '\\';
+ out_dest[j++] = '\\';
+ break;
+ default:
+ if( strchr(escapes,src[i]) )
+ {// escape
+ out_dest[j++] = '\\';
+ switch( src[i] )
+ {
+ case '\a': out_dest[j++] = 'a'; break;
+ case '\b': out_dest[j++] = 'b'; break;
+ case '\t': out_dest[j++] = 't'; break;
+ case '\v': out_dest[j++] = 'v'; break;
+ case '\f': out_dest[j++] = 'f'; break;
+ case '\?': out_dest[j++] = '?'; break;
+ default:// to octal
+ out_dest[j++] = '0'+((char)(((unsigned char)src[i]&0700)>>6));
+ out_dest[j++] = '0'+((char)(((unsigned char)src[i]&0070)>>3));
+ out_dest[j++] = '0'+((char)(((unsigned char)src[i]&0007) ));
+ break;
+ }
+ }
+ else
+ out_dest[j++] = src[i];
+ break;
+ }
+ }
+ out_dest[j] = 0;
+ return j;
}
/// Unescapes src to out_dest according to the format of the C compiler.
@@ -791,135 +821,129 @@ size_t sv_escape_c(char *out_dest, const char *src, size_t len, const char *esca
/// @param src Source string
/// @param len Length of the source string
/// @return Length of the escaped string
-size_t sv_unescape_c(char *out_dest, const char *src, size_t len)
+size_t sv_unescape_c(char* out_dest, const char* src, size_t len)
{
- static unsigned char low2hex[256] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0x0?
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0x1?
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0x2?
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,// 0x3?
- 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0x4?
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0x5?
- 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0x6?
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0x7?
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0x8?
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0x9?
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0xA?
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0xB?
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0xC?
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0xD?
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0xE?
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 0xF?
- };
- size_t i;
- size_t j;
-
- for (i = 0, j = 0; i < len;) {
- if (src[i] == '\\') {
- ++i;// '\\'
- if (i >= len)
- ShowWarning("sv_unescape_c: empty escape sequence\n");
- else if (src[i] == 'x') {
- // hex escape sequence
- unsigned char c = 0;
- unsigned char inrange = 1;
-
- ++i;// 'x'
- if (i >= len || !ISXDIGIT(src[i])) {
- ShowWarning("sv_unescape_c: \\x with no following hex digits\n");
- continue;
- }
- do {
- if (c > 0x0F && inrange) {
- ShowWarning("sv_unescape_c: hex escape sequence out of range\n");
- inrange = 0;
- }
- c = (c<<4)|low2hex[(unsigned char)src[i]];// hex digit
- ++i;
- } while (i < len && ISXDIGIT(src[i]));
- out_dest[j++] = (char)c;
- } else if (src[i] == '0' || src[i] == '1' || src[i] == '2' || src[i] == '3') {
- // octal escape sequence (255=0377)
- unsigned char c = src[i]-'0';
- ++i;// '0', '1', '2' or '3'
- if (i < len && src[i] >= '0' && src[i] <= '7') {
- c = (c<<3)|(src[i]-'0');
- ++i;// octal digit
- }
- if (i < len && src[i] >= '0' && src[i] <= '7') {
- c = (c<<3)|(src[i]-'0');
- ++i;// octal digit
- }
- out_dest[j++] = (char)c;
- } else {
- // other escape sequence
- if (strchr(SV_ESCAPE_C_SUPPORTED, src[i]) == NULL)
- ShowWarning("sv_unescape_c: unknown escape sequence \\%c\n", src[i]);
- switch (src[i]) {
- case 'a':
- out_dest[j++] = '\a';
- break;
- case 'b':
- out_dest[j++] = '\b';
- break;
- case 't':
- out_dest[j++] = '\t';
- break;
- case 'n':
- out_dest[j++] = '\n';
- break;
- case 'v':
- out_dest[j++] = '\v';
- break;
- case 'f':
- out_dest[j++] = '\f';
- break;
- case 'r':
- out_dest[j++] = '\r';
- break;
- case '?':
- out_dest[j++] = '\?';
- break;
- default:
- out_dest[j++] = src[i];
- break;
- }
- ++i;// escaped character
- }
- } else
- out_dest[j++] = src[i++];// normal character
- }
- out_dest[j] = 0;
- return j;
+ static unsigned char low2hex[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0x0?
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0x1?
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0x2?
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,// 0x3?
+ 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0x4?
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0x5?
+ 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0x6?
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0x7?
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0x8?
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0x9?
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0xA?
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0xB?
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0xC?
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0xD?
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0xE?
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 0xF?
+ };
+ size_t i;
+ size_t j;
+
+ for( i = 0, j = 0; i < len; )
+ {
+ if( src[i] == '\\' )
+ {
+ ++i;// '\\'
+ if( i >= len )
+ ShowWarning("sv_unescape_c: empty escape sequence\n");
+ else if( src[i] == 'x' )
+ {// hex escape sequence
+ unsigned char c = 0;
+ unsigned char inrange = 1;
+
+ ++i;// 'x'
+ if( i >= len || !ISXDIGIT(src[i]) )
+ {
+ ShowWarning("sv_unescape_c: \\x with no following hex digits\n");
+ continue;
+ }
+ do{
+ if( c > 0x0F && inrange )
+ {
+ ShowWarning("sv_unescape_c: hex escape sequence out of range\n");
+ inrange = 0;
+ }
+ c = (c<<4)|low2hex[(unsigned char)src[i]];// hex digit
+ ++i;
+ }while( i < len && ISXDIGIT(src[i]) );
+ out_dest[j++] = (char)c;
+ }
+ else if( src[i] == '0' || src[i] == '1' || src[i] == '2' || src[i] == '3' )
+ {// octal escape sequence (255=0377)
+ unsigned char c = src[i]-'0';
+ ++i;// '0', '1', '2' or '3'
+ if( i < len && src[i] >= '0' && src[i] <= '7' )
+ {
+ c = (c<<3)|(src[i]-'0');
+ ++i;// octal digit
+ }
+ if( i < len && src[i] >= '0' && src[i] <= '7' )
+ {
+ c = (c<<3)|(src[i]-'0');
+ ++i;// octal digit
+ }
+ out_dest[j++] = (char)c;
+ }
+ else
+ {// other escape sequence
+ if( strchr(SV_ESCAPE_C_SUPPORTED, src[i]) == NULL )
+ ShowWarning("sv_unescape_c: unknown escape sequence \\%c\n", src[i]);
+ switch( src[i] )
+ {
+ case 'a': out_dest[j++] = '\a'; break;
+ case 'b': out_dest[j++] = '\b'; break;
+ case 't': out_dest[j++] = '\t'; break;
+ case 'n': out_dest[j++] = '\n'; break;
+ case 'v': out_dest[j++] = '\v'; break;
+ case 'f': out_dest[j++] = '\f'; break;
+ case 'r': out_dest[j++] = '\r'; break;
+ case '?': out_dest[j++] = '\?'; break;
+ default: out_dest[j++] = src[i]; break;
+ }
+ ++i;// escaped character
+ }
+ }
+ else
+ out_dest[j++] = src[i++];// normal character
+ }
+ out_dest[j] = 0;
+ return j;
}
/// Skips a C escape sequence (starting with '\\').
-const char *skip_escaped_c(const char *p)
+const char* skip_escaped_c(const char* p)
{
- if (p && *p == '\\') {
- ++p;
- switch (*p) {
- case 'x':// hexadecimal
- ++p;
- while (ISXDIGIT(*p))
- ++p;
- break;
- case '0':
- case '1':
- case '2':
- case '3':// octal
- ++p;
- if (*p >= '0' && *p <= '7')
- ++p;
- if (*p >= '0' && *p <= '7')
- ++p;
- break;
- default:
- if (*p && strchr(SV_ESCAPE_C_SUPPORTED, *p))
- ++p;
- }
- }
- return p;
+ if( p && *p == '\\' )
+ {
+ ++p;
+ switch( *p )
+ {
+ case 'x':// hexadecimal
+ ++p;
+ while( ISXDIGIT(*p) )
+ ++p;
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':// octal
+ ++p;
+ if( *p >= '0' && *p <= '7' )
+ ++p;
+ if( *p >= '0' && *p <= '7' )
+ ++p;
+ break;
+ default:
+ if( *p && strchr(SV_ESCAPE_C_SUPPORTED, *p) )
+ ++p;
+ }
+ }
+ return p;
}
@@ -934,72 +958,78 @@ const char *skip_escaped_c(const char *p)
/// @param maxcols Maximum number of columns of a valid row
/// @param parseproc User-supplied row processing function
/// @return true on success, false if file could not be opened
-bool sv_readdb(const char *directory, const char *filename, char delim, int mincols, int maxcols, int maxrows, bool (*parseproc)(char *fields[], int columns, int current))
+bool sv_readdb(const char* directory, const char* filename, char delim, int mincols, int maxcols, int maxrows, bool (*parseproc)(char* fields[], int columns, int current))
{
- FILE *fp;
- int lines = 0;
- int entries = 0;
- char **fields; // buffer for fields ([0] is reserved)
- int columns, fields_length;
- char path[1024], line[1024];
- char *match;
-
- snprintf(path, sizeof(path), "%s/%s", directory, filename);
-
- // open file
- fp = fopen(path, "r");
- if (fp == NULL) {
- ShowError("sv_readdb: can't read %s\n", path);
- return false;
- }
-
- // allocate enough memory for the maximum requested amount of columns plus the reserved one
- fields_length = maxcols+1;
- fields = (char **)aMalloc(fields_length*sizeof(char *));
-
- // process rows one by one
- while (fgets(line, sizeof(line), fp)) {
- lines++;
-
- if ((match = strstr(line, "//")) != NULL) {
- // strip comments
- match[0] = 0;
- }
-
- //TODO: strip trailing whitespace
- if (line[0] == '\0' || line[0] == '\n' || line[0] == '\r')
- continue;
-
- columns = sv_split(line, strlen(line), 0, delim, fields, fields_length, (e_svopt)(SV_TERMINATE_LF|SV_TERMINATE_CRLF));
-
- if (columns < mincols) {
- ShowError("sv_readdb: Insufficient columns in line %d of \"%s\" (found %d, need at least %d).\n", lines, path, columns, mincols);
- continue; // not enough columns
- }
- if (columns > maxcols) {
- ShowError("sv_readdb: Too many columns in line %d of \"%s\" (found %d, maximum is %d).\n", lines, path, columns, maxcols);
- continue; // too many columns
- }
- if (entries == maxrows) {
- ShowError("sv_readdb: Reached the maximum allowed number of entries (%d) when parsing file \"%s\".\n", maxrows, path);
- break;
- }
-
- // parse this row
- if (!parseproc(fields+1, columns, entries)) {
- ShowError("sv_readdb: Could not process contents of line %d of \"%s\".\n", lines, path);
- continue; // invalid row contents
- }
-
- // success!
- entries++;
- }
-
- aFree(fields);
- fclose(fp);
- ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", entries, path);
-
- return true;
+ FILE* fp;
+ int lines = 0;
+ int entries = 0;
+ char** fields; // buffer for fields ([0] is reserved)
+ int columns, fields_length;
+ char path[1024], line[1024];
+ char* match;
+
+ snprintf(path, sizeof(path), "%s/%s", directory, filename);
+
+ // open file
+ fp = fopen(path, "r");
+ if( fp == NULL )
+ {
+ ShowError("sv_readdb: can't read %s\n", path);
+ return false;
+ }
+
+ // allocate enough memory for the maximum requested amount of columns plus the reserved one
+ fields_length = maxcols+1;
+ fields = (char**)aMalloc(fields_length*sizeof(char*));
+
+ // process rows one by one
+ while( fgets(line, sizeof(line), fp) )
+ {
+ lines++;
+
+ if( ( match = strstr(line, "//") ) != NULL )
+ {// strip comments
+ match[0] = 0;
+ }
+
+ //TODO: strip trailing whitespace
+ if( line[0] == '\0' || line[0] == '\n' || line[0] == '\r')
+ continue;
+
+ columns = sv_split(line, strlen(line), 0, delim, fields, fields_length, (e_svopt)(SV_TERMINATE_LF|SV_TERMINATE_CRLF));
+
+ if( columns < mincols )
+ {
+ ShowError("sv_readdb: Insufficient columns in line %d of \"%s\" (found %d, need at least %d).\n", lines, path, columns, mincols);
+ continue; // not enough columns
+ }
+ if( columns > maxcols )
+ {
+ ShowError("sv_readdb: Too many columns in line %d of \"%s\" (found %d, maximum is %d).\n", lines, path, columns, maxcols );
+ continue; // too many columns
+ }
+ if( entries == maxrows )
+ {
+ ShowError("sv_readdb: Reached the maximum allowed number of entries (%d) when parsing file \"%s\".\n", maxrows, path);
+ break;
+ }
+
+ // parse this row
+ if( !parseproc(fields+1, columns, entries) )
+ {
+ ShowError("sv_readdb: Could not process contents of line %d of \"%s\".\n", lines, path);
+ continue; // invalid row contents
+ }
+
+ // success!
+ entries++;
+ }
+
+ aFree(fields);
+ fclose(fp);
+ ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", entries, path);
+
+ return true;
}
@@ -1009,126 +1039,129 @@ bool sv_readdb(const char *directory, const char *filename, char delim, int minc
// @author MouseJstr (original)
/// Allocates a StringBuf
-StringBuf *StringBuf_Malloc()
+StringBuf* StringBuf_Malloc()
{
- StringBuf *self;
- CREATE(self, StringBuf, 1);
- StringBuf_Init(self);
- return self;
+ StringBuf* self;
+ CREATE(self, StringBuf, 1);
+ StringBuf_Init(self);
+ return self;
}
/// Initializes a previously allocated StringBuf
-void StringBuf_Init(StringBuf *self)
+void StringBuf_Init(StringBuf* self)
{
- self->max_ = 1024;
- self->ptr_ = self->buf_ = (char *)aMalloc(self->max_ + 1);
+ self->max_ = 1024;
+ self->ptr_ = self->buf_ = (char*)aMalloc(self->max_ + 1);
}
/// Appends the result of printf to the StringBuf
-int StringBuf_Printf(StringBuf *self, const char *fmt, ...)
+int StringBuf_Printf(StringBuf* self, const char* fmt, ...)
{
- int len;
- va_list ap;
+ int len;
+ va_list ap;
- va_start(ap, fmt);
- len = StringBuf_Vprintf(self, fmt, ap);
- va_end(ap);
+ va_start(ap, fmt);
+ len = StringBuf_Vprintf(self, fmt, ap);
+ va_end(ap);
- return len;
+ return len;
}
/// Appends the result of vprintf to the StringBuf
-int StringBuf_Vprintf(StringBuf *self, const char *fmt, va_list ap)
+int StringBuf_Vprintf(StringBuf* self, const char* fmt, va_list ap)
{
- int n, size, off;
-
- for (;;) {
- va_list apcopy;
- /* Try to print in the allocated space. */
- size = self->max_ - (self->ptr_ - self->buf_);
- va_copy(apcopy, ap);
- n = vsnprintf(self->ptr_, size, fmt, apcopy);
- va_end(apcopy);
- /* If that worked, return the length. */
- if (n > -1 && n < size) {
- self->ptr_ += n;
- return (int)(self->ptr_ - self->buf_);
- }
- /* Else try again with more space. */
- self->max_ *= 2; // twice the old size
- off = (int)(self->ptr_ - self->buf_);
- self->buf_ = (char *)aRealloc(self->buf_, self->max_ + 1);
- self->ptr_ = self->buf_ + off;
- }
+ int n, size, off;
+
+ for(;;)
+ {
+ va_list apcopy;
+ /* Try to print in the allocated space. */
+ size = self->max_ - (self->ptr_ - self->buf_);
+ va_copy(apcopy, ap);
+ n = vsnprintf(self->ptr_, size, fmt, apcopy);
+ va_end(apcopy);
+ /* If that worked, return the length. */
+ if( n > -1 && n < size )
+ {
+ self->ptr_ += n;
+ return (int)(self->ptr_ - self->buf_);
+ }
+ /* Else try again with more space. */
+ self->max_ *= 2; // twice the old size
+ off = (int)(self->ptr_ - self->buf_);
+ self->buf_ = (char*)aRealloc(self->buf_, self->max_ + 1);
+ self->ptr_ = self->buf_ + off;
+ }
}
/// Appends the contents of another StringBuf to the StringBuf
-int StringBuf_Append(StringBuf *self, const StringBuf *sbuf)
+int StringBuf_Append(StringBuf* self, const StringBuf* sbuf)
{
- int available = self->max_ - (self->ptr_ - self->buf_);
- int needed = (int)(sbuf->ptr_ - sbuf->buf_);
-
- if (needed >= available) {
- int off = (int)(self->ptr_ - self->buf_);
- self->max_ += needed;
- self->buf_ = (char *)aRealloc(self->buf_, self->max_ + 1);
- self->ptr_ = self->buf_ + off;
- }
-
- memcpy(self->ptr_, sbuf->buf_, needed);
- self->ptr_ += needed;
- return (int)(self->ptr_ - self->buf_);
+ int available = self->max_ - (self->ptr_ - self->buf_);
+ int needed = (int)(sbuf->ptr_ - sbuf->buf_);
+
+ if( needed >= available )
+ {
+ int off = (int)(self->ptr_ - self->buf_);
+ self->max_ += needed;
+ self->buf_ = (char*)aRealloc(self->buf_, self->max_ + 1);
+ self->ptr_ = self->buf_ + off;
+ }
+
+ memcpy(self->ptr_, sbuf->buf_, needed);
+ self->ptr_ += needed;
+ return (int)(self->ptr_ - self->buf_);
}
// Appends str to the StringBuf
-int StringBuf_AppendStr(StringBuf *self, const char *str)
+int StringBuf_AppendStr(StringBuf* self, const char* str)
{
- int available = self->max_ - (self->ptr_ - self->buf_);
- int needed = (int)strlen(str);
-
- if (needed >= available) {
- // not enough space, expand the buffer (minimum expansion = 1024)
- int off = (int)(self->ptr_ - self->buf_);
- self->max_ += max(needed, 1024);
- self->buf_ = (char *)aRealloc(self->buf_, self->max_ + 1);
- self->ptr_ = self->buf_ + off;
- }
-
- memcpy(self->ptr_, str, needed);
- self->ptr_ += needed;
- return (int)(self->ptr_ - self->buf_);
+ int available = self->max_ - (self->ptr_ - self->buf_);
+ int needed = (int)strlen(str);
+
+ if( needed >= available )
+ {// not enough space, expand the buffer (minimum expansion = 1024)
+ int off = (int)(self->ptr_ - self->buf_);
+ self->max_ += max(needed, 1024);
+ self->buf_ = (char*)aRealloc(self->buf_, self->max_ + 1);
+ self->ptr_ = self->buf_ + off;
+ }
+
+ memcpy(self->ptr_, str, needed);
+ self->ptr_ += needed;
+ return (int)(self->ptr_ - self->buf_);
}
// Returns the length of the data in the Stringbuf
-int StringBuf_Length(StringBuf *self)
+int StringBuf_Length(StringBuf* self)
{
- return (int)(self->ptr_ - self->buf_);
+ return (int)(self->ptr_ - self->buf_);
}
/// Returns the data in the StringBuf
-char *StringBuf_Value(StringBuf *self)
+char* StringBuf_Value(StringBuf* self)
{
- *self->ptr_ = '\0';
- return self->buf_;
+ *self->ptr_ = '\0';
+ return self->buf_;
}
/// Clears the contents of the StringBuf
-void StringBuf_Clear(StringBuf *self)
+void StringBuf_Clear(StringBuf* self)
{
- self->ptr_ = self->buf_;
+ self->ptr_ = self->buf_;
}
/// Destroys the StringBuf
-void StringBuf_Destroy(StringBuf *self)
+void StringBuf_Destroy(StringBuf* self)
{
- aFree(self->buf_);
- self->ptr_ = self->buf_ = 0;
- self->max_ = 0;
+ aFree(self->buf_);
+ self->ptr_ = self->buf_ = 0;
+ self->max_ = 0;
}
// Frees a StringBuf returned by StringBuf_Malloc
-void StringBuf_Free(StringBuf *self)
+void StringBuf_Free(StringBuf* self)
{
- StringBuf_Destroy(self);
- aFree(self);
+ StringBuf_Destroy(self);
+ aFree(self);
}
diff --git a/src/common/strlib.h b/src/common/strlib.h
index ae4f688c2..bbc2c6105 100644
--- a/src/common/strlib.h
+++ b/src/common/strlib.h
@@ -11,65 +11,66 @@
#include <string.h>
#undef __USE_GNU
-char *jstrescape(char *pt);
-char *jstrescapecpy(char *pt, const char *spt);
-int jmemescapecpy(char *pt, const char *spt, int size);
+char* jstrescape (char* pt);
+char* jstrescapecpy (char* pt, const char* spt);
+int jmemescapecpy (char* pt, const char* spt, int size);
-int remove_control_chars(char *str);
-char *trim(char *str);
-char *normalize_name(char *str,const char *delims);
+int remove_control_chars(char* str);
+char* trim(char* str);
+char* normalize_name(char* str,const char* delims);
const char *stristr(const char *haystack, const char *needle);
#ifdef WIN32
#define HAVE_STRTOK_R
#define strtok_r(s,delim,save_ptr) _strtok_r((s),(delim),(save_ptr))
-char *_strtok_r(char *s1, const char *s2, char **lasts);
+char* _strtok_r(char* s1, const char* s2, char** lasts);
#endif
#if !(defined(WIN32) && defined(_MSC_VER) && _MSC_VER >= 1400) && !defined(HAVE_STRNLEN)
-size_t strnlen(const char *string, size_t maxlen);
+size_t strnlen (const char* string, size_t maxlen);
#endif
#if defined(WIN32) && defined(_MSC_VER) && _MSC_VER <= 1200
-uint64 strtoull(const char *str, char **endptr, int base);
+uint64 strtoull(const char* str, char** endptr, int base);
#endif
-int e_mail_check(char *email);
-int config_switch(const char *str);
+int e_mail_check(char* email);
+int config_switch(const char* str);
/// strncpy that always nul-terminates the string
-char *safestrncpy(char *dst, const char *src, size_t n);
+char* safestrncpy(char* dst, const char* src, size_t n);
/// doesn't crash on null pointer
-size_t safestrnlen(const char *string, size_t maxlen);
+size_t safestrnlen(const char* string, size_t maxlen);
/// Works like snprintf, but always nul-terminates the buffer.
/// Returns the size of the string (without nul-terminator)
/// or -1 if the buffer is too small.
-int safesnprintf(char *buf, size_t sz, const char *fmt, ...);
+int safesnprintf(char* buf, size_t sz, const char* fmt, ...);
/// Returns the line of the target position in the string.
/// Lines start at 1.
-int strline(const char *str, size_t pos);
+int strline(const char* str, size_t pos);
/// Produces the hexadecimal representation of the given input.
/// The output buffer must be at least count*2+1 in size.
/// Returns true on success, false on failure.
-bool bin2hex(char *output, unsigned char *input, size_t count);
+bool bin2hex(char* output, unsigned char* input, size_t count);
/// Bitfield determining the behaviour of sv_parse and sv_split.
-typedef enum e_svopt {
- // default: no escapes and no line terminator
- SV_NOESCAPE_NOTERMINATE = 0,
- // Escapes according to the C compiler.
- SV_ESCAPE_C = 1,
- // Line terminators
- SV_TERMINATE_LF = 2,
- SV_TERMINATE_CRLF = 4,
- SV_TERMINATE_CR = 8,
- // If sv_split keeps the end of line terminator, instead of replacing with '\0'
- SV_KEEP_TERMINATOR = 16
+typedef enum e_svopt
+{
+ // default: no escapes and no line terminator
+ SV_NOESCAPE_NOTERMINATE = 0,
+ // Escapes according to the C compiler.
+ SV_ESCAPE_C = 1,
+ // Line terminators
+ SV_TERMINATE_LF = 2,
+ SV_TERMINATE_CRLF = 4,
+ SV_TERMINATE_CR = 8,
+ // If sv_split keeps the end of line terminator, instead of replacing with '\0'
+ SV_KEEP_TERMINATOR = 16
} e_svopt;
/// Other escape sequences supported by the C compiler.
@@ -77,15 +78,16 @@ typedef enum e_svopt {
/// Parse state.
/// The field is [start,end[
-struct s_svstate {
- const char *str; //< string to parse
- int len; //< string length
- int off; //< current offset in the string
- int start; //< where the field starts
- int end; //< where the field ends
- enum e_svopt opt; //< parse options
- char delim; //< field delimiter
- bool done; //< if all the text has been parsed
+struct s_svstate
+{
+ const char* str; //< string to parse
+ int len; //< string length
+ int off; //< current offset in the string
+ int start; //< where the field starts
+ int end; //< where the field ends
+ enum e_svopt opt; //< parse options
+ char delim; //< field delimiter
+ bool done; //< if all the text has been parsed
};
/// Parses a single field in a delim-separated string.
@@ -93,14 +95,14 @@ struct s_svstate {
///
/// @param sv Parse state
/// @return 1 if a field was parsed, 0 if done, -1 on error.
-int sv_parse_next(struct s_svstate *sv);
+int sv_parse_next(struct s_svstate* sv);
/// Parses a delim-separated string.
/// Starts parsing at startoff and fills the pos array with position pairs.
/// out_pos[0] and out_pos[1] are the start and end of line.
/// Other position pairs are the start and end of fields.
/// Returns the number of fields found or -1 if an error occurs.
-int sv_parse(const char *str, int len, int startoff, char delim, int *out_pos, int npos, enum e_svopt opt);
+int sv_parse(const char* str, int len, int startoff, char delim, int* out_pos, int npos, enum e_svopt opt);
/// Splits a delim-separated string.
/// WARNING: this function modifies the input string
@@ -108,45 +110,46 @@ int sv_parse(const char *str, int len, int startoff, char delim, int *out_pos, i
/// out_fields[0] is the start of the next line.
/// Other entries are the start of fields (nul-teminated).
/// Returns the number of fields found or -1 if an error occurs.
-int sv_split(char *str, int len, int startoff, char delim, char **out_fields, int nfields, enum e_svopt opt);
+int sv_split(char* str, int len, int startoff, char delim, char** out_fields, int nfields, enum e_svopt opt);
/// Escapes src to out_dest according to the format of the C compiler.
/// Returns the length of the escaped string.
/// out_dest should be len*4+1 in size.
-size_t sv_escape_c(char *out_dest, const char *src, size_t len, const char *escapes);
+size_t sv_escape_c(char* out_dest, const char* src, size_t len, const char* escapes);
/// Unescapes src to out_dest according to the format of the C compiler.
/// Returns the length of the unescaped string.
/// out_dest should be len+1 in size and can be the same buffer as src.
-size_t sv_unescape_c(char *out_dest, const char *src, size_t len);
+size_t sv_unescape_c(char* out_dest, const char* src, size_t len);
/// Skips a C escape sequence (starting with '\\').
-const char *skip_escaped_c(const char *p);
+const char* skip_escaped_c(const char* p);
/// Opens and parses a file containing delim-separated columns, feeding them to the specified callback function row by row.
/// Tracks the progress of the operation (current line number, number of successfully processed rows).
/// Returns 'true' if it was able to process the specified file, or 'false' if it could not be read.
-bool sv_readdb(const char *directory, const char *filename, char delim, int mincols, int maxcols, int maxrows, bool (*parseproc)(char *fields[], int columns, int current));
+bool sv_readdb(const char* directory, const char* filename, char delim, int mincols, int maxcols, int maxrows, bool (*parseproc)(char* fields[], int columns, int current));
/// StringBuf - dynamic string
-struct StringBuf {
- char *buf_;
- char *ptr_;
- unsigned int max_;
+struct StringBuf
+{
+ char *buf_;
+ char *ptr_;
+ unsigned int max_;
};
typedef struct StringBuf StringBuf;
-StringBuf *StringBuf_Malloc(void);
-void StringBuf_Init(StringBuf *self);
-int StringBuf_Printf(StringBuf *self, const char *fmt, ...);
-int StringBuf_Vprintf(StringBuf *self, const char *fmt, va_list args);
-int StringBuf_Append(StringBuf *self, const StringBuf *sbuf);
-int StringBuf_AppendStr(StringBuf *self, const char *str);
-int StringBuf_Length(StringBuf *self);
-char *StringBuf_Value(StringBuf *self);
-void StringBuf_Clear(StringBuf *self);
-void StringBuf_Destroy(StringBuf *self);
-void StringBuf_Free(StringBuf *self);
+StringBuf* StringBuf_Malloc(void);
+void StringBuf_Init(StringBuf* self);
+int StringBuf_Printf(StringBuf* self, const char* fmt, ...);
+int StringBuf_Vprintf(StringBuf* self, const char* fmt, va_list args);
+int StringBuf_Append(StringBuf* self, const StringBuf *sbuf);
+int StringBuf_AppendStr(StringBuf* self, const char* str);
+int StringBuf_Length(StringBuf* self);
+char* StringBuf_Value(StringBuf* self);
+void StringBuf_Clear(StringBuf* self);
+void StringBuf_Destroy(StringBuf* self);
+void StringBuf_Free(StringBuf* self);
#endif /* _STRLIB_H_ */
diff --git a/src/common/thread.c b/src/common/thread.c
index 610ee394c..315b310b2 100644
--- a/src/common/thread.c
+++ b/src/common/thread.c
@@ -9,7 +9,7 @@
#ifdef WIN32
#include "../common/winapi.h"
#define getpagesize() 4096 // @TODO: implement this properly (GetSystemInfo .. dwPageSize..). (Atm as on all supported win platforms its 4k its static.)
-#define __thread __declspec( thread )
+#define __thread __declspec( thread )
#else
#include <stdlib.h>
#include <unistd.h>
@@ -25,25 +25,25 @@
#include "thread.h"
// When Compiling using MSC (on win32..) we know we have support in any case!
-#ifdef _MSC_VER
-#define HAS_TLS
+#ifdef _MSC_VER
+#define HAS_TLS
#endif
#define RA_THREADS_MAX 64
struct rAthread {
- unsigned int myID;
-
- RATHREAD_PRIO prio;
- rAthreadProc proc;
- void *param;
-
-#ifdef WIN32
- HANDLE hThread;
-#else
- pthread_t hThread;
-#endif
+ unsigned int myID;
+
+ RATHREAD_PRIO prio;
+ rAthreadProc proc;
+ void *param;
+
+ #ifdef WIN32
+ HANDLE hThread;
+ #else
+ pthread_t hThread;
+ #endif
};
@@ -57,100 +57,95 @@ __thread int g_rathread_ID = -1;
///
static struct rAthread l_threads[RA_THREADS_MAX];
-void rathread_init()
-{
- register unsigned int i;
- memset(&l_threads, 0x00, RA_THREADS_MAX * sizeof(struct rAthread));
-
- for (i = 0; i < RA_THREADS_MAX; i++) {
- l_threads[i].myID = i;
- }
+void rathread_init(){
+ register unsigned int i;
+ memset(&l_threads, 0x00, RA_THREADS_MAX * sizeof(struct rAthread) );
+
+ for(i = 0; i < RA_THREADS_MAX; i++){
+ l_threads[i].myID = i;
+ }
- // now lets init thread id 0, which represnts the main thread
+ // now lets init thread id 0, which represnts the main thread
#ifdef HAS_TLS
- g_rathread_ID = 0;
+ g_rathread_ID = 0;
#endif
- l_threads[0].prio = RAT_PRIO_NORMAL;
- l_threads[0].proc = (rAthreadProc)0xDEADCAFE;
+ l_threads[0].prio = RAT_PRIO_NORMAL;
+ l_threads[0].proc = (rAthreadProc)0xDEADCAFE;
}//end: rathread_init()
-void rathread_final()
-{
- register unsigned int i;
-
- // Unterminated Threads Left?
- // Should'nt happen ..
- // Kill 'em all!
- //
- for (i = 1; i < RA_THREADS_MAX; i++) {
- if (l_threads[i].proc != NULL) {
- ShowWarning("rAthread_final: unterminated Thread (tid %u entryPoint %p) - forcing to terminate (kill)\n", i, l_threads[i].proc);
- rathread_destroy(&l_threads[i]);
- }
- }
-
-
+void rathread_final(){
+ register unsigned int i;
+
+ // Unterminated Threads Left?
+ // Should'nt happen ..
+ // Kill 'em all!
+ //
+ for(i = 1; i < RA_THREADS_MAX; i++){
+ if(l_threads[i].proc != NULL){
+ ShowWarning("rAthread_final: unterminated Thread (tid %u entryPoint %p) - forcing to terminate (kill)\n", i, l_threads[i].proc);
+ rathread_destroy(&l_threads[i]);
+ }
+ }
+
+
}//end: rathread_final()
// gets called whenever a thread terminated ..
-static void rat_thread_terminated(rAthread handle)
-{
+static void rat_thread_terminated( rAthread handle ){
- int id_backup = handle->myID;
+ int id_backup = handle->myID;
- // Simply set all members to 0 (except the id)
- memset(handle, 0x00, sizeof(struct rAthread));
-
- handle->myID = id_backup; // done ;)
+ // Simply set all members to 0 (except the id)
+ memset(handle, 0x00, sizeof(struct rAthread));
+
+ handle->myID = id_backup; // done ;)
}//end: rat_thread_terminated()
#ifdef WIN32
-DWORD WINAPI _raThreadMainRedirector(LPVOID p)
-{
+DWORD WINAPI _raThreadMainRedirector(LPVOID p){
#else
-static void *_raThreadMainRedirector(void *p)
-{
- sigset_t set; // on Posix Thread platforms
+static void *_raThreadMainRedirector( void *p ){
+ sigset_t set; // on Posix Thread platforms
#endif
- void *ret;
-
- // Update myID @ TLS to right id.
+ void *ret;
+
+ // Update myID @ TLS to right id.
#ifdef HAS_TLS
- g_rathread_ID = ((rAthread)p)->myID;
+ g_rathread_ID = ((rAthread)p)->myID;
#endif
#ifndef WIN32
- // When using posix threads
- // the threads inherits the Signal mask from the thread which's spawned
- // this thread
- // so we've to block everything we dont care about.
- sigemptyset(&set);
- sigaddset(&set, SIGINT);
- sigaddset(&set, SIGTERM);
- sigaddset(&set, SIGPIPE);
-
- pthread_sigmask(SIG_BLOCK, &set, NULL);
-
+ // When using posix threads
+ // the threads inherits the Signal mask from the thread which's spawned
+ // this thread
+ // so we've to block everything we dont care about.
+ sigemptyset(&set);
+ sigaddset(&set, SIGINT);
+ sigaddset(&set, SIGTERM);
+ sigaddset(&set, SIGPIPE);
+
+ pthread_sigmask(SIG_BLOCK, &set, NULL);
+
#endif
- ret = ((rAthread)p)->proc(((rAthread)p)->param) ;
+ ret = ((rAthread)p)->proc( ((rAthread)p)->param ) ;
-#ifdef WIN32
- CloseHandle(((rAthread)p)->hThread);
+#ifdef WIN32
+ CloseHandle( ((rAthread)p)->hThread );
#endif
- rat_thread_terminated((rAthread)p);
+ rat_thread_terminated( (rAthread)p );
#ifdef WIN32
- return (DWORD)ret;
+ return (DWORD)ret;
#else
- return ret;
+ return ret;
#endif
}//end: _raThreadMainRedirector()
@@ -160,172 +155,163 @@ static void *_raThreadMainRedirector(void *p)
///
/// API Level
-///
-rAthread rathread_create(rAthreadProc entryPoint, void *param)
-{
- return rathread_createEx(entryPoint, param, (1<<23) /*8MB*/, RAT_PRIO_NORMAL);
+///
+rAthread rathread_create( rAthreadProc entryPoint, void *param ){
+ return rathread_createEx( entryPoint, param, (1<<23) /*8MB*/, RAT_PRIO_NORMAL );
}//end: rathread_create()
-rAthread rathread_createEx(rAthreadProc entryPoint, void *param, size_t szStack, RATHREAD_PRIO prio)
-{
+rAthread rathread_createEx( rAthreadProc entryPoint, void *param, size_t szStack, RATHREAD_PRIO prio ){
#ifndef WIN32
- pthread_attr_t attr;
+ pthread_attr_t attr;
#endif
- size_t tmp;
- unsigned int i;
- rAthread handle = NULL;
-
-
- // given stacksize aligned to systems pagesize?
- tmp = szStack % getpagesize();
- if (tmp != 0)
- szStack += tmp;
-
-
- // Get a free Thread Slot.
- for (i = 0; i < RA_THREADS_MAX; i++) {
- if (l_threads[i].proc == NULL) {
- handle = &l_threads[i];
- break;
- }
- }
-
- if (handle == NULL) {
- ShowError("rAthread: cannot create new thread (entryPoint: %p) - no free thread slot found!", entryPoint);
- return NULL;
- }
-
-
-
- handle->proc = entryPoint;
- handle->param = param;
+ size_t tmp;
+ unsigned int i;
+ rAthread handle = NULL;
+
+
+ // given stacksize aligned to systems pagesize?
+ tmp = szStack % getpagesize();
+ if(tmp != 0)
+ szStack += tmp;
+
+
+ // Get a free Thread Slot.
+ for(i = 0; i < RA_THREADS_MAX; i++){
+ if(l_threads[i].proc == NULL){
+ handle = &l_threads[i];
+ break;
+ }
+ }
+
+ if(handle == NULL){
+ ShowError("rAthread: cannot create new thread (entryPoint: %p) - no free thread slot found!", entryPoint);
+ return NULL;
+ }
+
+
+
+ handle->proc = entryPoint;
+ handle->param = param;
#ifdef WIN32
- handle->hThread = CreateThread(NULL, szStack, _raThreadMainRedirector, (void *)handle, 0, NULL);
+ handle->hThread = CreateThread(NULL, szStack, _raThreadMainRedirector, (void*)handle, 0, NULL);
#else
- pthread_attr_init(&attr);
- pthread_attr_setstacksize(&attr, szStack);
-
- if (pthread_create(&handle->hThread, &attr, _raThreadMainRedirector, (void *)handle) != 0) {
- handle->proc = NULL;
- handle->param = NULL;
- return NULL;
- }
- pthread_attr_destroy(&attr);
+ pthread_attr_init(&attr);
+ pthread_attr_setstacksize(&attr, szStack);
+
+ if(pthread_create(&handle->hThread, &attr, _raThreadMainRedirector, (void*)handle) != 0){
+ handle->proc = NULL;
+ handle->param = NULL;
+ return NULL;
+ }
+ pthread_attr_destroy(&attr);
#endif
- rathread_prio_set(handle, prio);
-
- return handle;
+ rathread_prio_set( handle, prio );
+
+ return handle;
}//end: rathread_createEx
-void rathread_destroy(rAthread handle)
-{
+void rathread_destroy ( rAthread handle ){
#ifdef WIN32
- if (TerminateThread(handle->hThread, 0) != FALSE) {
- CloseHandle(handle->hThread);
- rat_thread_terminated(handle);
- }
+ if( TerminateThread(handle->hThread, 0) != FALSE){
+ CloseHandle(handle->hThread);
+ rat_thread_terminated(handle);
+ }
#else
- if (pthread_cancel(handle->hThread) == 0) {
-
- // We have to join it, otherwise pthread wont re-cycle its internal ressources assoc. with this thread.
- //
- pthread_join(handle->hThread, NULL);
-
- // Tell our manager to release ressources ;)
- rat_thread_terminated(handle);
- }
+ if( pthread_cancel( handle->hThread ) == 0){
+
+ // We have to join it, otherwise pthread wont re-cycle its internal ressources assoc. with this thread.
+ //
+ pthread_join( handle->hThread, NULL );
+
+ // Tell our manager to release ressources ;)
+ rat_thread_terminated(handle);
+ }
#endif
}//end: rathread_destroy()
-rAthread rathread_self()
-{
+rAthread rathread_self( ){
#ifdef HAS_TLS
- rAthread handle = &l_threads[g_rathread_ID];
-
- if (handle->proc != NULL) // entry point set, so its used!
- return handle;
+ rAthread handle = &l_threads[g_rathread_ID];
+
+ if(handle->proc != NULL) // entry point set, so its used!
+ return handle;
#else
- // .. so no tls means we have to search the thread by its api-handle ..
- int i;
-
-#ifdef WIN32
- HANDLE hSelf;
- hSelf = GetCurrent = GetCurrentThread();
-#else
- pthread_t hSelf;
- hSelf = pthread_self();
-#endif
-
- for (i = 0; i < RA_THREADS_MAX; i++) {
- if (l_threads[i].hThread == hSelf && l_threads[i].proc != NULL)
- return &l_threads[i];
- }
-
+ // .. so no tls means we have to search the thread by its api-handle ..
+ int i;
+
+ #ifdef WIN32
+ HANDLE hSelf;
+ hSelf = GetCurrent = GetCurrentThread();
+ #else
+ pthread_t hSelf;
+ hSelf = pthread_self();
+ #endif
+
+ for(i = 0; i < RA_THREADS_MAX; i++){
+ if(l_threads[i].hThread == hSelf && l_threads[i].proc != NULL)
+ return &l_threads[i];
+ }
+
#endif
-
- return NULL;
+
+ return NULL;
}//end: rathread_self()
-int rathread_get_tid()
-{
+int rathread_get_tid(){
-#ifdef HAS_TLS
- return g_rathread_ID;
+#ifdef HAS_TLS
+ return g_rathread_ID;
#else
- // todo
-#ifdef WIN32
- return (int)GetCurrentThreadId();
-#else
- return (intptr_t)pthread_self();
-#endif
-
+ // todo
+ #ifdef WIN32
+ return (int)GetCurrentThreadId();
+ #else
+ return (intptr_t)pthread_self();
+ #endif
+
#endif
-
+
}//end: rathread_get_tid()
-bool rathread_wait(rAthread handle, void* *out_exitCode)
-{
-
- // Hint:
- // no thread data cleanup routine call here!
- // its managed by the callProxy itself..
- //
+bool rathread_wait( rAthread handle, void* *out_exitCode ){
+
+ // Hint:
+ // no thread data cleanup routine call here!
+ // its managed by the callProxy itself..
+ //
#ifdef WIN32
- WaitForSingleObject(handle->hThread, INFINITE);
- return true;
+ WaitForSingleObject(handle->hThread, INFINITE);
+ return true;
#else
- if (pthread_join(handle->hThread, out_exitCode) == 0)
- return true;
- return false;
+ if(pthread_join(handle->hThread, out_exitCode) == 0)
+ return true;
+ return false;
#endif
}//end: rathread_wait()
-void rathread_prio_set(rAthread handle, RATHREAD_PRIO prio)
-{
- handle->prio = RAT_PRIO_NORMAL;
- //@TODO
+void rathread_prio_set( rAthread handle, RATHREAD_PRIO prio ){
+ handle->prio = RAT_PRIO_NORMAL;
+ //@TODO
}//end: rathread_prio_set()
-RATHREAD_PRIO rathread_prio_get(rAthread handle)
-{
- return handle->prio;
+RATHREAD_PRIO rathread_prio_get( rAthread handle){
+ return handle->prio;
}//end: rathread_prio_get()
-void rathread_yield()
-{
-#ifdef WIN32
- SwitchToThread();
+void rathread_yield(){
+#ifdef WIN32
+ SwitchToThread();
#else
- sched_yield();
-#endif
+ sched_yield();
+#endif
}//end: rathread_yield()
diff --git a/src/common/thread.h b/src/common/thread.h
index cfbfe689f..a5a66e954 100644
--- a/src/common/thread.h
+++ b/src/common/thread.h
@@ -1,19 +1,19 @@
// Copyright (c) rAthena Project (www.rathena.org) - Licensed under GNU GPL
// For more information, see LICENCE in the main folder
-#pragma once
+#pragma once
#ifndef _rA_THREAD_H_
#define _rA_THREAD_H_
#include "../common/cbasetypes.h"
typedef struct rAthread *rAthread;
-typedef void *(*rAthreadProc)(void *);
+typedef void* (*rAthreadProc)(void*);
typedef enum RATHREAD_PRIO {
- RAT_PRIO_LOW = 0,
- RAT_PRIO_NORMAL,
- RAT_PRIO_HIGH
+ RAT_PRIO_LOW = 0,
+ RAT_PRIO_NORMAL,
+ RAT_PRIO_HIGH
} RATHREAD_PRIO;
@@ -22,51 +22,51 @@ typedef enum RATHREAD_PRIO {
*
* @param entyPoint - entryProc,
* @param param - general purpose parameter, would be given as parameter to the thread's entrypoint.
- *
+ *
* @return not NULL if success
*/
-rAthread rathread_create(rAthreadProc entryPoint, void *param);
+rAthread rathread_create( rAthreadProc entryPoint, void *param );
-/**
+/**
* Creates a new Thread (with more creation options)
*
* @param entyPoint - entryProc,
* @param param - general purpose parameter, would be given as parameter to the thread's entrypoint
- * @param szStack - stack Size in bytes
+ * @param szStack - stack Size in bytes
* @param prio - Priority of the Thread @ OS Scheduler..
*
* @return not NULL if success
*/
-rAthread rathread_createEx(rAthreadProc entryPoint, void *param, size_t szStack, RATHREAD_PRIO prio);
+rAthread rathread_createEx( rAthreadProc entryPoint, void *param, size_t szStack, RATHREAD_PRIO prio );
/**
* Destroys the given Thread immediatly
*
- * @note The Handle gets invalid after call! dont use it afterwards.
+ * @note The Handle gets invalid after call! dont use it afterwards.
*
* @param handle - thread to destroy.
*/
-void rathread_destroy(rAthread handle);
+void rathread_destroy ( rAthread handle );
-/**
+/**
* Returns the thread handle of the thread calling this function
- *
+ *
* @note this wont work @ programms main thread
- * @note the underlying implementation might not perform very well, cache the value received!
- *
+ * @note the underlying implementation might not perform very well, cache the value received!
+ *
* @return not NULL if success
*/
-rAthread rathread_self();
+rAthread rathread_self( );
/**
- * Returns own thrad id (TID)
+ * Returns own thrad id (TID)
*
- * @note this is an unique identifier for the calling thread, and
- * depends on platfrom / compiler, and may not be the systems Thread ID!
+ * @note this is an unique identifier for the calling thread, and
+ * depends on platfrom / compiler, and may not be the systems Thread ID!
*
* @return -1 when fails, otherwise >= 0
*/
@@ -74,39 +74,39 @@ int rathread_get_tid();
/**
- * Waits for the given thread to terminate
+ * Waits for the given thread to terminate
*
* @param handle - thread to wait (join) for
* @param out_Exitcode - [OPTIONAL] - if given => Exitcode (value) of the given thread - if it's terminated
- *
+ *
* @return true - if the given thread has been terminated.
*/
-bool rathread_wait(rAthread handle, void* *out_exitCode);
+bool rathread_wait( rAthread handle, void* *out_exitCode );
-/**
+/**
* Sets the given PRIORITY @ OS Task Scheduler
- *
+ *
* @param handle - thread to set prio for
* @param rio - the priority (RAT_PRIO_LOW ... )
*/
-void rathread_prio_set(rAthread handle, RATHREAD_PRIO prio);
+void rathread_prio_set( rAthread handle, RATHREAD_PRIO prio );
-/**
+/**
* Gets the current Prio of the given trhead
*
* @param handle - the thread to get the prio for.
*/
-RATHREAD_PRIO rathread_prio_get(rAthread handle);
+RATHREAD_PRIO rathread_prio_get( rAthread handle);
/**
* Tells the OS scheduler to yield the execution of the calling thread
- *
+ *
* @note: this will not "pause" the thread,
- * it just allows the OS to spent the remaining time
- * of the slice to another thread.
+ * it just allows the OS to spent the remaining time
+ * of the slice to another thread.
*/
void rathread_yield();
diff --git a/src/common/timer.c b/src/common/timer.c
index bb2458233..c239a9d70 100644
--- a/src/common/timer.c
+++ b/src/common/timer.c
@@ -26,12 +26,12 @@
#define TIMER_MAX_INTERVAL 1000
// timers (array)
-static struct TimerData *timer_data = NULL;
+static struct TimerData* timer_data = NULL;
static int timer_data_max = 0;
static int timer_data_num = 0;
// free timers (array)
-static int *free_timer_list = NULL;
+static int* free_timer_list = NULL;
static int free_timer_list_max = 0;
static int free_timer_list_pos = 0;
@@ -53,87 +53,85 @@ time_t start_time;
/*----------------------------
- * Timer debugging
+ * Timer debugging
*----------------------------*/
struct timer_func_list {
- struct timer_func_list *next;
- TimerFunc func;
- char *name;
+ struct timer_func_list* next;
+ TimerFunc func;
+ char* name;
} *tfl_root = NULL;
/// Sets the name of a timer function.
-int add_timer_func_list(TimerFunc func, char *name)
+int add_timer_func_list(TimerFunc func, char* name)
{
- struct timer_func_list *tfl;
-
- if (name) {
- for (tfl=tfl_root; tfl != NULL; tfl=tfl->next) {
- // check suspicious cases
- if (func == tfl->func)
- ShowWarning("add_timer_func_list: duplicating function %p(%s) as %s.\n",tfl->func,tfl->name,name);
- else if (strcmp(name,tfl->name) == 0)
- ShowWarning("add_timer_func_list: function %p has the same name as %p(%s)\n",func,tfl->func,tfl->name);
- }
- CREATE(tfl,struct timer_func_list,1);
- tfl->next = tfl_root;
- tfl->func = func;
- tfl->name = aStrdup(name);
- tfl_root = tfl;
- }
- return 0;
+ struct timer_func_list* tfl;
+
+ if (name) {
+ for( tfl=tfl_root; tfl != NULL; tfl=tfl->next )
+ {// check suspicious cases
+ if( func == tfl->func )
+ ShowWarning("add_timer_func_list: duplicating function %p(%s) as %s.\n",tfl->func,tfl->name,name);
+ else if( strcmp(name,tfl->name) == 0 )
+ ShowWarning("add_timer_func_list: function %p has the same name as %p(%s)\n",func,tfl->func,tfl->name);
+ }
+ CREATE(tfl,struct timer_func_list,1);
+ tfl->next = tfl_root;
+ tfl->func = func;
+ tfl->name = aStrdup(name);
+ tfl_root = tfl;
+ }
+ return 0;
}
/// Returns the name of the timer function.
-char *search_timer_func_list(TimerFunc func)
+char* search_timer_func_list(TimerFunc func)
{
- struct timer_func_list *tfl;
+ struct timer_func_list* tfl;
- for (tfl=tfl_root; tfl != NULL; tfl=tfl->next)
- if (func == tfl->func)
- return tfl->name;
+ for( tfl=tfl_root; tfl != NULL; tfl=tfl->next )
+ if (func == tfl->func)
+ return tfl->name;
- return "unknown timer function";
+ return "unknown timer function";
}
/*----------------------------
- * Get tick time
+ * Get tick time
*----------------------------*/
#if defined(ENABLE_RDTSC)
static uint64 RDTSC_BEGINTICK = 0, RDTSC_CLOCK = 0;
-static __inline uint64 _rdtsc()
-{
- register union {
- uint64 qw;
- uint32 dw[2];
- } t;
-
- asm volatile("rdtsc":"=a"(t.dw[0]), "=d"(t.dw[1]));
+static __inline uint64 _rdtsc(){
+ register union{
+ uint64 qw;
+ uint32 dw[2];
+ } t;
- return t.qw;
+ asm volatile("rdtsc":"=a"(t.dw[0]), "=d"(t.dw[1]) );
+
+ return t.qw;
}
-static void rdtsc_calibrate()
-{
- uint64 t1, t2;
- int32 i;
-
- ShowStatus("Calibrating Timer Source, please wait... ");
-
- RDTSC_CLOCK = 0;
-
- for (i = 0; i < 5; i++) {
- t1 = _rdtsc();
- usleep(1000000); //1000 MS
- t2 = _rdtsc();
- RDTSC_CLOCK += (t2 - t1) / 1000;
- }
- RDTSC_CLOCK /= 5;
-
- RDTSC_BEGINTICK = _rdtsc();
-
- ShowMessage(" done. (Frequency: %u Mhz)\n", (uint32)(RDTSC_CLOCK/1000));
+static void rdtsc_calibrate(){
+ uint64 t1, t2;
+ int32 i;
+
+ ShowStatus("Calibrating Timer Source, please wait... ");
+
+ RDTSC_CLOCK = 0;
+
+ for(i = 0; i < 5; i++){
+ t1 = _rdtsc();
+ usleep(1000000); //1000 MS
+ t2 = _rdtsc();
+ RDTSC_CLOCK += (t2 - t1) / 1000;
+ }
+ RDTSC_CLOCK /= 5;
+
+ RDTSC_BEGINTICK = _rdtsc();
+
+ ShowMessage(" done. (Frequency: %u Mhz)\n", (uint32)(RDTSC_CLOCK/1000) );
}
#endif
@@ -142,19 +140,19 @@ static void rdtsc_calibrate()
static unsigned int tick(void)
{
#if defined(WIN32)
- return GetTickCount();
+ return GetTickCount();
#elif defined(ENABLE_RDTSC)
- //
- return (unsigned int)((_rdtsc() - RDTSC_BEGINTICK) / RDTSC_CLOCK);
- //
+ //
+ return (unsigned int)((_rdtsc() - RDTSC_BEGINTICK) / RDTSC_CLOCK);
+ //
#elif defined(HAVE_MONOTONIC_CLOCK)
- struct timespec tval;
- clock_gettime(CLOCK_MONOTONIC, &tval);
- return tval.tv_sec * 1000 + tval.tv_nsec / 1000000;
+ struct timespec tval;
+ clock_gettime(CLOCK_MONOTONIC, &tval);
+ return tval.tv_sec * 1000 + tval.tv_nsec / 1000000;
#else
- struct timeval tval;
- gettimeofday(&tval, NULL);
- return tval.tv_sec * 1000 + tval.tv_usec / 1000;
+ struct timeval tval;
+ gettimeofday(&tval, NULL);
+ return tval.tv_sec * 1000 + tval.tv_usec / 1000;
#endif
}
@@ -167,14 +165,14 @@ static int gettick_count = 1;
unsigned int gettick_nocache(void)
{
- gettick_count = TICK_CACHE;
- gettick_cache = tick();
- return gettick_cache;
+ gettick_count = TICK_CACHE;
+ gettick_cache = tick();
+ return gettick_cache;
}
unsigned int gettick(void)
{
- return (--gettick_count == 0) ? gettick_nocache() : gettick_cache;
+ return ( --gettick_count == 0 ) ? gettick_nocache() : gettick_cache;
}
//////////////////////////////
#else
@@ -182,108 +180,110 @@ unsigned int gettick(void)
// tick doesn't get cached
unsigned int gettick_nocache(void)
{
- return tick();
+ return tick();
}
unsigned int gettick(void)
{
- return tick();
+ return tick();
}
//////////////////////////////////////////////////////////////////////////
#endif
//////////////////////////////////////////////////////////////////////////
/*======================================
- * CORE : Timer Heap
+ * CORE : Timer Heap
*--------------------------------------*/
/// Adds a timer to the timer_heap
static void push_timer_heap(int tid)
{
- BHEAP_ENSURE(timer_heap, 1, 256);
- BHEAP_PUSH(timer_heap, tid, DIFFTICK_MINTOPCMP);
+ BHEAP_ENSURE(timer_heap, 1, 256);
+ BHEAP_PUSH(timer_heap, tid, DIFFTICK_MINTOPCMP);
}
/*==========================
- * Timer Management
+ * Timer Management
*--------------------------*/
/// Returns a free timer id.
static int acquire_timer(void)
{
- int tid;
-
- // select a free timer
- if (free_timer_list_pos) {
- do {
- tid = free_timer_list[--free_timer_list_pos];
- } while (tid >= timer_data_num && free_timer_list_pos > 0);
- } else
- tid = timer_data_num;
-
- // check available space
- if (tid >= timer_data_num)
- for (tid = timer_data_num; tid < timer_data_max && timer_data[tid].type; tid++);
- if (tid >= timer_data_num && tid >= timer_data_max) {
- // expand timer array
- timer_data_max += 256;
- if (timer_data)
- RECREATE(timer_data, struct TimerData, timer_data_max);
- else
- CREATE(timer_data, struct TimerData, timer_data_max);
- memset(timer_data + (timer_data_max - 256), 0, sizeof(struct TimerData)*256);
- }
-
- if (tid >= timer_data_num)
- timer_data_num = tid + 1;
-
- return tid;
+ int tid;
+
+ // select a free timer
+ if (free_timer_list_pos) {
+ do {
+ tid = free_timer_list[--free_timer_list_pos];
+ } while(tid >= timer_data_num && free_timer_list_pos > 0);
+ } else
+ tid = timer_data_num;
+
+ // check available space
+ if( tid >= timer_data_num )
+ for (tid = timer_data_num; tid < timer_data_max && timer_data[tid].type; tid++);
+ if (tid >= timer_data_num && tid >= timer_data_max)
+ {// expand timer array
+ timer_data_max += 256;
+ if( timer_data )
+ RECREATE(timer_data, struct TimerData, timer_data_max);
+ else
+ CREATE(timer_data, struct TimerData, timer_data_max);
+ memset(timer_data + (timer_data_max - 256), 0, sizeof(struct TimerData)*256);
+ }
+
+ if( tid >= timer_data_num )
+ timer_data_num = tid + 1;
+
+ return tid;
}
/// Starts a new timer that is deleted once it expires (single-use).
/// Returns the timer's id.
int add_timer(unsigned int tick, TimerFunc func, int id, intptr_t data)
{
- int tid;
-
- tid = acquire_timer();
- timer_data[tid].tick = tick;
- timer_data[tid].func = func;
- timer_data[tid].id = id;
- timer_data[tid].data = data;
- timer_data[tid].type = TIMER_ONCE_AUTODEL;
- timer_data[tid].interval = 1000;
- push_timer_heap(tid);
-
- return tid;
+ int tid;
+
+ tid = acquire_timer();
+ timer_data[tid].tick = tick;
+ timer_data[tid].func = func;
+ timer_data[tid].id = id;
+ timer_data[tid].data = data;
+ timer_data[tid].type = TIMER_ONCE_AUTODEL;
+ timer_data[tid].interval = 1000;
+ push_timer_heap(tid);
+
+ return tid;
}
/// Starts a new timer that automatically restarts itself (infinite loop until manually removed).
/// Returns the timer's id, or INVALID_TIMER if it fails.
int add_timer_interval(unsigned int tick, TimerFunc func, int id, intptr_t data, int interval)
{
- int tid;
-
- if (interval < 1) {
- ShowError("add_timer_interval: invalid interval (tick=%u %p[%s] id=%d data=%d diff_tick=%d)\n", tick, func, search_timer_func_list(func), id, data, DIFF_TICK(tick, gettick()));
- return INVALID_TIMER;
- }
-
- tid = acquire_timer();
- timer_data[tid].tick = tick;
- timer_data[tid].func = func;
- timer_data[tid].id = id;
- timer_data[tid].data = data;
- timer_data[tid].type = TIMER_INTERVAL;
- timer_data[tid].interval = interval;
- push_timer_heap(tid);
-
- return tid;
+ int tid;
+
+ if( interval < 1 )
+ {
+ ShowError("add_timer_interval: invalid interval (tick=%u %p[%s] id=%d data=%d diff_tick=%d)\n", tick, func, search_timer_func_list(func), id, data, DIFF_TICK(tick, gettick()));
+ return INVALID_TIMER;
+ }
+
+ tid = acquire_timer();
+ timer_data[tid].tick = tick;
+ timer_data[tid].func = func;
+ timer_data[tid].id = id;
+ timer_data[tid].data = data;
+ timer_data[tid].type = TIMER_INTERVAL;
+ timer_data[tid].interval = interval;
+ push_timer_heap(tid);
+
+ return tid;
}
/// Retrieves internal timer data
-const struct TimerData *get_timer(int tid) {
- return (tid >= 0 && tid < timer_data_num) ? &timer_data[tid] : NULL;
+const struct TimerData* get_timer(int tid)
+{
+ return ( tid >= 0 && tid < timer_data_num ) ? &timer_data[tid] : NULL;
}
/// Marks a timer specified by 'id' for immediate deletion once it expires.
@@ -291,135 +291,142 @@ const struct TimerData *get_timer(int tid) {
/// Returns 0 on success, < 0 on failure.
int delete_timer(int tid, TimerFunc func)
{
- if (tid < 0 || tid >= timer_data_num) {
- ShowError("delete_timer error : no such timer %d (%p(%s))\n", tid, func, search_timer_func_list(func));
- return -1;
- }
- if (timer_data[tid].func != func) {
- ShowError("delete_timer error : function mismatch %p(%s) != %p(%s)\n", timer_data[tid].func, search_timer_func_list(timer_data[tid].func), func, search_timer_func_list(func));
- return -2;
- }
-
- timer_data[tid].func = NULL;
- timer_data[tid].type = TIMER_ONCE_AUTODEL;
-
- return 0;
+ if( tid < 0 || tid >= timer_data_num )
+ {
+ ShowError("delete_timer error : no such timer %d (%p(%s))\n", tid, func, search_timer_func_list(func));
+ return -1;
+ }
+ if( timer_data[tid].func != func )
+ {
+ ShowError("delete_timer error : function mismatch %p(%s) != %p(%s)\n", timer_data[tid].func, search_timer_func_list(timer_data[tid].func), func, search_timer_func_list(func));
+ return -2;
+ }
+
+ timer_data[tid].func = NULL;
+ timer_data[tid].type = TIMER_ONCE_AUTODEL;
+
+ return 0;
}
/// Adjusts a timer's expiration time.
/// Returns the new tick value, or -1 if it fails.
int addtick_timer(int tid, unsigned int tick)
{
- return settick_timer(tid, timer_data[tid].tick+tick);
+ return settick_timer(tid, timer_data[tid].tick+tick);
}
/// Modifies a timer's expiration time (an alternative to deleting a timer and starting a new one).
/// Returns the new tick value, or -1 if it fails.
int settick_timer(int tid, unsigned int tick)
{
- size_t i;
-
- // search timer position
- ARR_FIND(0, BHEAP_LENGTH(timer_heap), i, BHEAP_DATA(timer_heap)[i] == tid);
- if (i == BHEAP_LENGTH(timer_heap)) {
- ShowError("settick_timer: no such timer %d (%p(%s))\n", tid, timer_data[tid].func, search_timer_func_list(timer_data[tid].func));
- return -1;
- }
-
- if ((int)tick == -1)
- tick = 0;// add 1ms to avoid the error value -1
-
- if (timer_data[tid].tick == tick)
- return (int)tick;// nothing to do, already in propper position
-
- // pop and push adjusted timer
- BHEAP_POPINDEX(timer_heap, i, DIFFTICK_MINTOPCMP);
- timer_data[tid].tick = tick;
- BHEAP_PUSH(timer_heap, tid, DIFFTICK_MINTOPCMP);
- return (int)tick;
+ size_t i;
+
+ // search timer position
+ ARR_FIND(0, BHEAP_LENGTH(timer_heap), i, BHEAP_DATA(timer_heap)[i] == tid);
+ if( i == BHEAP_LENGTH(timer_heap) )
+ {
+ ShowError("settick_timer: no such timer %d (%p(%s))\n", tid, timer_data[tid].func, search_timer_func_list(timer_data[tid].func));
+ return -1;
+ }
+
+ if( (int)tick == -1 )
+ tick = 0;// add 1ms to avoid the error value -1
+
+ if( timer_data[tid].tick == tick )
+ return (int)tick;// nothing to do, already in propper position
+
+ // pop and push adjusted timer
+ BHEAP_POPINDEX(timer_heap, i, DIFFTICK_MINTOPCMP);
+ timer_data[tid].tick = tick;
+ BHEAP_PUSH(timer_heap, tid, DIFFTICK_MINTOPCMP);
+ return (int)tick;
}
/// Executes all expired timers.
/// Returns the value of the smallest non-expired timer (or 1 second if there aren't any).
int do_timer(unsigned int tick)
{
- int diff = TIMER_MAX_INTERVAL; // return value
-
- // process all timers one by one
- while (BHEAP_LENGTH(timer_heap)) {
- int tid = BHEAP_PEEK(timer_heap);// top element in heap (smallest tick)
-
- diff = DIFF_TICK(timer_data[tid].tick, tick);
- if (diff > 0)
- break; // no more expired timers to process
-
- // remove timer
- BHEAP_POP(timer_heap, DIFFTICK_MINTOPCMP);
- timer_data[tid].type |= TIMER_REMOVE_HEAP;
-
- if (timer_data[tid].func) {
- if (diff < -1000)
- // timer was delayed for more than 1 second, use current tick instead
- timer_data[tid].func(tid, tick, timer_data[tid].id, timer_data[tid].data);
- else
- timer_data[tid].func(tid, timer_data[tid].tick, timer_data[tid].id, timer_data[tid].data);
- }
-
- // in the case the function didn't change anything...
- if (timer_data[tid].type & TIMER_REMOVE_HEAP) {
- timer_data[tid].type &= ~TIMER_REMOVE_HEAP;
-
- switch (timer_data[tid].type) {
- default:
- case TIMER_ONCE_AUTODEL:
- timer_data[tid].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(int));
- }
- free_timer_list[free_timer_list_pos++] = tid;
- break;
- case TIMER_INTERVAL:
- if (DIFF_TICK(timer_data[tid].tick, tick) < -1000)
- timer_data[tid].tick = tick + timer_data[tid].interval;
- else
- timer_data[tid].tick += timer_data[tid].interval;
- push_timer_heap(tid);
- break;
- }
- }
- }
-
- return cap_value(diff, TIMER_MIN_INTERVAL, TIMER_MAX_INTERVAL);
+ int diff = TIMER_MAX_INTERVAL; // return value
+
+ // process all timers one by one
+ while( BHEAP_LENGTH(timer_heap) )
+ {
+ int tid = BHEAP_PEEK(timer_heap);// top element in heap (smallest tick)
+
+ diff = DIFF_TICK(timer_data[tid].tick, tick);
+ if( diff > 0 )
+ break; // no more expired timers to process
+
+ // remove timer
+ BHEAP_POP(timer_heap, DIFFTICK_MINTOPCMP);
+ timer_data[tid].type |= TIMER_REMOVE_HEAP;
+
+ if( timer_data[tid].func )
+ {
+ if( diff < -1000 )
+ // timer was delayed for more than 1 second, use current tick instead
+ timer_data[tid].func(tid, tick, timer_data[tid].id, timer_data[tid].data);
+ else
+ timer_data[tid].func(tid, timer_data[tid].tick, timer_data[tid].id, timer_data[tid].data);
+ }
+
+ // in the case the function didn't change anything...
+ if( timer_data[tid].type & TIMER_REMOVE_HEAP )
+ {
+ timer_data[tid].type &= ~TIMER_REMOVE_HEAP;
+
+ switch( timer_data[tid].type )
+ {
+ default:
+ case TIMER_ONCE_AUTODEL:
+ timer_data[tid].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(int));
+ }
+ free_timer_list[free_timer_list_pos++] = tid;
+ break;
+ case TIMER_INTERVAL:
+ if( DIFF_TICK(timer_data[tid].tick, tick) < -1000 )
+ timer_data[tid].tick = tick + timer_data[tid].interval;
+ else
+ timer_data[tid].tick += timer_data[tid].interval;
+ push_timer_heap(tid);
+ break;
+ }
+ }
+ }
+
+ return cap_value(diff, TIMER_MIN_INTERVAL, TIMER_MAX_INTERVAL);
}
unsigned long get_uptime(void)
{
- return (unsigned long)difftime(time(NULL), start_time);
+ return (unsigned long)difftime(time(NULL), start_time);
}
void timer_init(void)
{
#if defined(ENABLE_RDTSC)
- rdtsc_calibrate();
+ rdtsc_calibrate();
#endif
- time(&start_time);
+ time(&start_time);
}
void timer_final(void)
{
- struct timer_func_list *tfl;
- struct timer_func_list *next;
-
- for (tfl=tfl_root; tfl != NULL; tfl = next) {
- next = tfl->next; // copy next pointer
- aFree(tfl->name); // free structures
- aFree(tfl);
- }
-
- if (timer_data) aFree(timer_data);
- BHEAP_CLEAR(timer_heap);
- if (free_timer_list) aFree(free_timer_list);
+ struct timer_func_list *tfl;
+ struct timer_func_list *next;
+
+ for( tfl=tfl_root; tfl != NULL; tfl = next ) {
+ next = tfl->next; // copy next pointer
+ aFree(tfl->name); // free structures
+ aFree(tfl);
+ }
+
+ if (timer_data) aFree(timer_data);
+ BHEAP_CLEAR(timer_heap);
+ if (free_timer_list) aFree(free_timer_list);
}
diff --git a/src/common/timer.h b/src/common/timer.h
index 9b46927d8..d45c73d12 100644
--- a/src/common/timer.h
+++ b/src/common/timer.h
@@ -1,8 +1,8 @@
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder
-#ifndef _TIMER_H_
-#define _TIMER_H_
+#ifndef _TIMER_H_
+#define _TIMER_H_
#include "../common/cbasetypes.h"
@@ -12,9 +12,9 @@
// timer flags
enum {
- TIMER_ONCE_AUTODEL = 0x01,
- TIMER_INTERVAL = 0x02,
- TIMER_REMOVE_HEAP = 0x10,
+ TIMER_ONCE_AUTODEL = 0x01,
+ TIMER_INTERVAL = 0x02,
+ TIMER_REMOVE_HEAP = 0x10,
};
// Struct declaration
@@ -22,15 +22,15 @@ enum {
typedef int (*TimerFunc)(int tid, unsigned int tick, int id, intptr_t data);
struct TimerData {
- unsigned int tick;
- TimerFunc func;
- int type;
- int interval;
- int heap_pos;
-
- // general-purpose storage
- int id;
- intptr_t data;
+ unsigned int tick;
+ TimerFunc func;
+ int type;
+ int interval;
+ int heap_pos;
+
+ // general-purpose storage
+ int id;
+ intptr_t data;
};
// Function prototype declaration
@@ -40,13 +40,13 @@ unsigned int gettick_nocache(void);
int add_timer(unsigned int tick, TimerFunc func, int id, intptr_t data);
int add_timer_interval(unsigned int tick, TimerFunc func, int id, intptr_t data, int interval);
-const struct TimerData *get_timer(int tid);
+const struct TimerData* get_timer(int tid);
int delete_timer(int tid, TimerFunc func);
int addtick_timer(int tid, unsigned int tick);
int settick_timer(int tid, unsigned int tick);
-int add_timer_func_list(TimerFunc func, char *name);
+int add_timer_func_list(TimerFunc func, char* name);
unsigned long get_uptime(void);
diff --git a/src/common/utils.c b/src/common/utils.c
index 9d090f594..296df7e70 100644
--- a/src/common/utils.c
+++ b/src/common/utils.c
@@ -15,262 +15,269 @@
#include <math.h> // floor()
#ifdef WIN32
-#include "../common/winapi.h"
-#ifndef F_OK
-#define F_OK 0x0
-#endif /* F_OK */
+ #include "../common/winapi.h"
+ #ifndef F_OK
+ #define F_OK 0x0
+ #endif /* F_OK */
#else
-#include <unistd.h>
-#include <dirent.h>
-#include <sys/stat.h>
+ #include <unistd.h>
+ #include <dirent.h>
+ #include <sys/stat.h>
#endif
/// Dumps given buffer into file pointed to by a handle.
-void WriteDump(FILE *fp, const void *buffer, size_t length)
+void WriteDump(FILE* fp, const void* buffer, size_t length)
{
- size_t i;
- char hex[48+1], ascii[16+1];
-
- fprintf(fp, "--- 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F 0123456789ABCDEF\n");
- ascii[16] = 0;
-
- for (i = 0; i < length; i++) {
- char c = RBUFB(buffer,i);
-
- ascii[i%16] = ISCNTRL(c) ? '.' : c;
- sprintf(hex+(i%16)*3, "%02X ", RBUFB(buffer,i));
-
- if ((i%16) == 15) {
- fprintf(fp, "%03X %s %s\n", (unsigned int)(i/16), hex, ascii);
- }
- }
-
- if ((i%16) != 0) {
- ascii[i%16] = 0;
- fprintf(fp, "%03X %-48s %-16s\n", (unsigned int)(i/16), hex, ascii);
- }
+ size_t i;
+ char hex[48+1], ascii[16+1];
+
+ fprintf(fp, "--- 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F 0123456789ABCDEF\n");
+ ascii[16] = 0;
+
+ for( i = 0; i < length; i++ )
+ {
+ char c = RBUFB(buffer,i);
+
+ ascii[i%16] = ISCNTRL(c) ? '.' : c;
+ sprintf(hex+(i%16)*3, "%02X ", RBUFB(buffer,i));
+
+ if( (i%16) == 15 )
+ {
+ fprintf(fp, "%03X %s %s\n", (unsigned int)(i/16), hex, ascii);
+ }
+ }
+
+ if( (i%16) != 0 )
+ {
+ ascii[i%16] = 0;
+ fprintf(fp, "%03X %-48s %-16s\n", (unsigned int)(i/16), hex, ascii);
+ }
}
/// Dumps given buffer on the console.
-void ShowDump(const void *buffer, size_t length)
+void ShowDump(const void* buffer, size_t length)
{
- size_t i;
- char hex[48+1], ascii[16+1];
-
- ShowDebug("--- 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F 0123456789ABCDEF\n");
- ascii[16] = 0;
-
- for (i = 0; i < length; i++) {
- char c = RBUFB(buffer,i);
-
- ascii[i%16] = ISCNTRL(c) ? '.' : c;
- sprintf(hex+(i%16)*3, "%02X ", RBUFB(buffer,i));
-
- if ((i%16) == 15) {
- ShowDebug("%03X %s %s\n", i/16, hex, ascii);
- }
- }
-
- if ((i%16) != 0) {
- ascii[i%16] = 0;
- ShowDebug("%03X %-48s %-16s\n", i/16, hex, ascii);
- }
+ size_t i;
+ char hex[48+1], ascii[16+1];
+
+ ShowDebug("--- 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F 0123456789ABCDEF\n");
+ ascii[16] = 0;
+
+ for( i = 0; i < length; i++ )
+ {
+ char c = RBUFB(buffer,i);
+
+ ascii[i%16] = ISCNTRL(c) ? '.' : c;
+ sprintf(hex+(i%16)*3, "%02X ", RBUFB(buffer,i));
+
+ if( (i%16) == 15 )
+ {
+ ShowDebug("%03X %s %s\n", i/16, hex, ascii);
+ }
+ }
+
+ if( (i%16) != 0 )
+ {
+ ascii[i%16] = 0;
+ ShowDebug("%03X %-48s %-16s\n", i/16, hex, ascii);
+ }
}
#ifdef WIN32
-static char *checkpath(char *path, const char *srcpath)
-{
- // just make sure the char*path is not const
- char *p=path;
- if (NULL!=path && NULL!=srcpath)
- while (*srcpath) {
- if (*srcpath=='/') {
- *p++ = '\\';
- srcpath++;
- } else
- *p++ = *srcpath++;
- }
- *p = *srcpath; //EOS
- return path;
+static char* checkpath(char *path, const char *srcpath)
+{ // just make sure the char*path is not const
+ char *p=path;
+ if(NULL!=path && NULL!=srcpath)
+ while(*srcpath) {
+ if (*srcpath=='/') {
+ *p++ = '\\';
+ srcpath++;
+ }
+ else
+ *p++ = *srcpath++;
+ }
+ *p = *srcpath; //EOS
+ return path;
}
-void findfile(const char *p, const char *pat, void (func)(const char *))
+void findfile(const char *p, const char *pat, void (func)(const char*))
{
- WIN32_FIND_DATAA FindFileData;
- HANDLE hFind;
- char tmppath[MAX_PATH+1];
-
- const char *path = (p ==NULL)? "." : p;
- const char *pattern = (pat==NULL)? "" : pat;
-
- checkpath(tmppath,path);
- if (PATHSEP != tmppath[strlen(tmppath)-1])
- strcat(tmppath, "\\*");
- else
- strcat(tmppath, "*");
-
- hFind = FindFirstFileA(tmppath, &FindFileData);
- if (hFind != INVALID_HANDLE_VALUE) {
- do {
- if (strcmp(FindFileData.cFileName, ".") == 0)
- continue;
- if (strcmp(FindFileData.cFileName, "..") == 0)
- continue;
-
- sprintf(tmppath,"%s%c%s",path,PATHSEP,FindFileData.cFileName);
-
- if (FindFileData.cFileName && strstr(FindFileData.cFileName, pattern)) {
- func(tmppath);
- }
-
-
- if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
- findfile(tmppath, pat, func);
- }
- } while (FindNextFileA(hFind, &FindFileData) != 0);
- FindClose(hFind);
- }
- return;
+ WIN32_FIND_DATAA FindFileData;
+ HANDLE hFind;
+ char tmppath[MAX_PATH+1];
+
+ const char *path = (p ==NULL)? "." : p;
+ const char *pattern = (pat==NULL)? "" : pat;
+
+ checkpath(tmppath,path);
+ if( PATHSEP != tmppath[strlen(tmppath)-1])
+ strcat(tmppath, "\\*");
+ else
+ strcat(tmppath, "*");
+
+ hFind = FindFirstFileA(tmppath, &FindFileData);
+ if (hFind != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ if (strcmp(FindFileData.cFileName, ".") == 0)
+ continue;
+ if (strcmp(FindFileData.cFileName, "..") == 0)
+ continue;
+
+ sprintf(tmppath,"%s%c%s",path,PATHSEP,FindFileData.cFileName);
+
+ if (FindFileData.cFileName && strstr(FindFileData.cFileName, pattern)) {
+ func( tmppath );
+ }
+
+
+ if( FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
+ {
+ findfile(tmppath, pat, func);
+ }
+ }while (FindNextFileA(hFind, &FindFileData) != 0);
+ FindClose(hFind);
+ }
+ return;
}
#else
#define MAX_DIR_PATH 2048
-static char *checkpath(char *path, const char *srcpath)
-{
- // just make sure the char*path is not const
- char *p=path;
- if (NULL!=path && NULL!=srcpath)
- while (*srcpath) {
- if (*srcpath=='\\') {
- *p++ = '/';
- srcpath++;
- } else
- *p++ = *srcpath++;
- }
- *p = *srcpath; //EOS
- return path;
+static char* checkpath(char *path, const char*srcpath)
+{ // just make sure the char*path is not const
+ char *p=path;
+ if(NULL!=path && NULL!=srcpath)
+ while(*srcpath) {
+ if (*srcpath=='\\') {
+ *p++ = '/';
+ srcpath++;
+ }
+ else
+ *p++ = *srcpath++;
+ }
+ *p = *srcpath; //EOS
+ return path;
}
-void findfile(const char *p, const char *pat, void (func)(const char *))
+void findfile(const char *p, const char *pat, void (func)(const char*))
{
- DIR *dir; // pointer to the scanned directory.
- struct dirent *entry; // pointer to one directory entry.
- struct stat dir_stat; // used by stat().
- char tmppath[MAX_DIR_PATH+1];
- char path[MAX_DIR_PATH+1]= ".";
- const char *pattern = (pat==NULL)? "" : pat;
- if (p!=NULL) strcpy(path,p);
-
- // open the directory for reading
- dir = opendir(checkpath(path, path));
- if (!dir) {
- ShowError("Cannot read directory '%s'\n", path);
- return;
- }
-
- // scan the directory, traversing each sub-directory
- // matching the pattern for each file name.
- while ((entry = readdir(dir))) {
- // skip the "." and ".." entries.
- if (strcmp(entry->d_name, ".") == 0)
- continue;
- if (strcmp(entry->d_name, "..") == 0)
- continue;
-
- sprintf(tmppath,"%s%c%s",path, PATHSEP, entry->d_name);
-
- // check if the pattern matchs.
- if (entry->d_name && strstr(entry->d_name, pattern)) {
- func(tmppath);
- }
- // check if it is a directory.
- if (stat(tmppath, &dir_stat) == -1) {
- ShowError("stat error %s\n': ", tmppath);
- continue;
- }
- // is this a directory?
- if (S_ISDIR(dir_stat.st_mode)) {
- // decent recursivly
- findfile(tmppath, pat, func);
- }
- }//end while
-
- closedir(dir);
+ DIR* dir; // pointer to the scanned directory.
+ struct dirent* entry; // pointer to one directory entry.
+ struct stat dir_stat; // used by stat().
+ char tmppath[MAX_DIR_PATH+1];
+ char path[MAX_DIR_PATH+1]= ".";
+ const char *pattern = (pat==NULL)? "" : pat;
+ if(p!=NULL) strcpy(path,p);
+
+ // open the directory for reading
+ dir = opendir( checkpath(path, path) );
+ if (!dir) {
+ ShowError("Cannot read directory '%s'\n", path);
+ return;
+ }
+
+ // scan the directory, traversing each sub-directory
+ // matching the pattern for each file name.
+ while ((entry = readdir(dir))) {
+ // skip the "." and ".." entries.
+ if (strcmp(entry->d_name, ".") == 0)
+ continue;
+ if (strcmp(entry->d_name, "..") == 0)
+ continue;
+
+ sprintf(tmppath,"%s%c%s",path, PATHSEP, entry->d_name);
+
+ // check if the pattern matchs.
+ if (entry->d_name && strstr(entry->d_name, pattern)) {
+ func( tmppath );
+ }
+ // check if it is a directory.
+ if (stat(tmppath, &dir_stat) == -1) {
+ ShowError("stat error %s\n': ", tmppath);
+ continue;
+ }
+ // is this a directory?
+ if (S_ISDIR(dir_stat.st_mode)) {
+ // decent recursivly
+ findfile(tmppath, pat, func);
+ }
+ }//end while
+
+ closedir(dir);
}
#endif
-bool exists(const char *filename)
+bool exists(const char* filename)
{
- return !access(filename, F_OK);
+ return !access(filename, F_OK);
}
uint8 GetByte(uint32 val, int idx)
{
- switch (idx) {
- case 0:
- return (uint8)((val & 0x000000FF));
- case 1:
- return (uint8)((val & 0x0000FF00) >> 0x08);
- case 2:
- return (uint8)((val & 0x00FF0000) >> 0x10);
- case 3:
- return (uint8)((val & 0xFF000000) >> 0x18);
- default:
+ switch( idx )
+ {
+ case 0: return (uint8)( (val & 0x000000FF) );
+ case 1: return (uint8)( (val & 0x0000FF00) >> 0x08 );
+ case 2: return (uint8)( (val & 0x00FF0000) >> 0x10 );
+ case 3: return (uint8)( (val & 0xFF000000) >> 0x18 );
+ default:
#if defined(DEBUG)
- ShowDebug("GetByte: invalid index (idx=%d)\n", idx);
+ ShowDebug("GetByte: invalid index (idx=%d)\n", idx);
#endif
- return 0;
- }
+ return 0;
+ }
}
uint16 GetWord(uint32 val, int idx)
{
- switch (idx) {
- case 0:
- return (uint16)((val & 0x0000FFFF));
- case 1:
- return (uint16)((val & 0xFFFF0000) >> 0x10);
- default:
+ switch( idx )
+ {
+ case 0: return (uint16)( (val & 0x0000FFFF) );
+ case 1: return (uint16)( (val & 0xFFFF0000) >> 0x10 );
+ default:
#if defined(DEBUG)
- ShowDebug("GetWord: invalid index (idx=%d)\n", idx);
+ ShowDebug("GetWord: invalid index (idx=%d)\n", idx);
#endif
- return 0;
- }
+ return 0;
+ }
}
uint16 MakeWord(uint8 byte0, uint8 byte1)
{
- return byte0 | (byte1 << 0x08);
+ return byte0 | (byte1 << 0x08);
}
uint32 MakeDWord(uint16 word0, uint16 word1)
{
- return
- ((uint32)(word0))|
- ((uint32)(word1 << 0x10));
+ return
+ ( (uint32)(word0 ) )|
+ ( (uint32)(word1 << 0x10) );
}
/// calculates the value of A / B, in percent (rounded down)
unsigned int get_percentage(const unsigned int A, const unsigned int B)
{
- double result;
+ double result;
- if (B == 0) {
- ShowError("get_percentage(): divison by zero! (A=%u,B=%u)\n", A, B);
- return ~0U;
- }
+ if( B == 0 )
+ {
+ ShowError("get_percentage(): divison by zero! (A=%u,B=%u)\n", A, B);
+ return ~0U;
+ }
- result = 100 * ((double)A / (double)B);
+ result = 100 * ((double)A / (double)B);
- if (result > UINT_MAX) {
- ShowError("get_percentage(): result percentage too high! (A=%u,B=%u,result=%g)\n", A, B, result);
- return UINT_MAX;
- }
+ if( result > UINT_MAX )
+ {
+ ShowError("get_percentage(): result percentage too high! (A=%u,B=%u,result=%g)\n", A, B, result);
+ return UINT_MAX;
+ }
- return (unsigned int)floor(result);
+ return (unsigned int)floor(result);
}
diff --git a/src/common/utils.h b/src/common/utils.h
index 7f68e484e..8e39f2655 100644
--- a/src/common/utils.h
+++ b/src/common/utils.h
@@ -8,11 +8,11 @@
#include <stdio.h> // FILE*
// generate a hex dump of the first 'length' bytes of 'buffer'
-void WriteDump(FILE *fp, const void *buffer, size_t length);
-void ShowDump(const void *buffer, size_t length);
+void WriteDump(FILE* fp, const void* buffer, size_t length);
+void ShowDump(const void* buffer, size_t length);
-void findfile(const char *p, const char *pat, void (func)(const char *));
-bool exists(const char *filename);
+void findfile(const char *p, const char *pat, void (func)(const char*));
+bool exists(const char* filename);
//Caps values to min/max
#define cap_value(a, min, max) ((a >= max) ? max : (a <= min) ? min : a)
diff --git a/src/common/winapi.h b/src/common/winapi.h
index dfb7d4588..7ce555049 100644
--- a/src/common/winapi.h
+++ b/src/common/winapi.h
@@ -2,12 +2,12 @@
#define STRICT
-#define NTDDI_VERSION NTDDI_WIN2K
+#define NTDDI_VERSION NTDDI_WIN2K
#define _WIN32_WINNT 0x0500
#define WINVER 0x0500
-#define _WIN32_IE 0x0600
+#define _WIN32_IE 0x0600
#define WIN32_LEAN_AND_MEAN
-#define NOCOMM
+#define NOCOMM
#define NOKANJI
#define NOHELP
#define NOMCX
diff --git a/src/config/const.h b/src/config/const.h
index 11477e75f..5fb74e22e 100644
--- a/src/config/const.h
+++ b/src/config/const.h
@@ -13,85 +13,85 @@
*/
/**
- * "Sane Checks" to save you from compiling with cool bugs
+ * "Sane Checks" to save you from compiling with cool bugs
**/
#if SECURE_NPCTIMEOUT_INTERVAL <= 0
-#error SECURE_NPCTIMEOUT_INTERVAL should be at least 1 (1s)
+ #error SECURE_NPCTIMEOUT_INTERVAL should be at least 1 (1s)
#endif
#if SECURE_NPCTIMEOUT < 0
-#error SECURE_NPCTIMEOUT cannot be lower than 0
+ #error SECURE_NPCTIMEOUT cannot be lower than 0
#endif
/**
* Path within the /db folder to (non-)renewal specific db files
**/
#ifdef RENEWAL
-#define DBPATH "re/"
+ #define DBPATH "re/"
#else
-#define DBPATH "pre-re/"
+ #define DBPATH "pre-re/"
#endif
/**
* DefType
**/
#ifdef RENEWAL
-typedef short defType;
-#define DEFTYPE_MIN SHRT_MIN
-#define DEFTYPE_MAX SHRT_MAX
+ typedef short defType;
+ #define DEFTYPE_MIN SHRT_MIN
+ #define DEFTYPE_MAX SHRT_MAX
#else
-typedef signed char defType;
-#define DEFTYPE_MIN CHAR_MIN
-#define DEFTYPE_MAX CHAR_MAX
+ typedef signed char defType;
+ #define DEFTYPE_MIN CHAR_MIN
+ #define DEFTYPE_MAX CHAR_MAX
#endif
/* pointer size fix which fixes several gcc warnings */
#ifdef __64BIT__
-#define __64BPRTSIZE(y) (intptr)y
+ #define __64BPRTSIZE(y) (intptr)y
#else
-#define __64BPRTSIZE(y) y
+ #define __64BPRTSIZE(y) y
#endif
/* ATCMD_FUNC(mobinfo) HIT and FLEE calculations */
#ifdef RENEWAL
-#define MOB_FLEE(mob) ( mob->lv + mob->status.agi + mob->status.luk/5 + 100 )
-#define MOB_HIT(mob) ( mob->lv + mob->status.dex + mob->status.luk/3 + 175 )
+ #define MOB_FLEE(mob) ( mob->lv + mob->status.agi + mob->status.luk/5 + 100 )
+ #define MOB_HIT(mob) ( mob->lv + mob->status.dex + mob->status.luk/3 + 175 )
#else
-#define MOB_FLEE(mob) ( mob->lv + mob->status.agi )
-#define MOB_HIT(mob) ( mob->lv + mob->status.dex )
+ #define MOB_FLEE(mob) ( mob->lv + mob->status.agi )
+ #define MOB_HIT(mob) ( mob->lv + mob->status.dex )
#endif
/* Renewal's dmg level modifier, used as a macro for a easy way to turn off. */
#ifdef RENEWAL_LVDMG
-#define RE_LVL_DMOD(val) \
- if( status_get_lv(src) > 100 && val > 0 ) \
- skillratio = skillratio * status_get_lv(src) / val;
-#define RE_LVL_MDMOD(val) \
- if( status_get_lv(src) > 100 && val > 0) \
- md.damage = md.damage * status_get_lv(src) / val;
-/* ranger traps special */
-#define RE_LVL_TMDMOD() \
- if( status_get_lv(src) > 100 ) \
- md.damage = md.damage * 150 / 100 + md.damage * status_get_lv(src) / 100;
+ #define RE_LVL_DMOD(val) \
+ if( status_get_lv(src) > 100 && val > 0 ) \
+ skillratio = skillratio * status_get_lv(src) / val;
+ #define RE_LVL_MDMOD(val) \
+ if( status_get_lv(src) > 100 && val > 0) \
+ md.damage = md.damage * status_get_lv(src) / val;
+ /* ranger traps special */
+ #define RE_LVL_TMDMOD() \
+ if( status_get_lv(src) > 100 ) \
+ md.damage = md.damage * 150 / 100 + md.damage * status_get_lv(src) / 100;
#else
-#define RE_LVL_DMOD(val)
-#define RE_LVL_MDMOD(val)
-#define RE_LVL_TMDMOD()
+ #define RE_LVL_DMOD(val)
+ #define RE_LVL_MDMOD(val)
+ #define RE_LVL_TMDMOD()
#endif
/* Feb 1st 2012 */
#if PACKETVER >= 20120201
-#define NEW_CARTS
-#define MAX_CARTS 9
+ #define NEW_CARTS
+ #define MAX_CARTS 9
#else
-#define MAX_CARTS 5
+ #define MAX_CARTS 5
#endif
// Renewal variable cast time reduction
#ifdef RENEWAL_CAST
-#define VARCAST_REDUCTION(val){ \
- if( (varcast_r += val) != 0 && varcast_r >= 0 ) \
- time = time * (1 - (float)min(val, 100) / 100); \
- }
+ #define VARCAST_REDUCTION(val){ \
+ if( (varcast_r += val) != 0 && varcast_r >= 0 ) \
+ time = time * (1 - (float)min(val, 100) / 100); \
+ }
#endif
/**
* End of File
diff --git a/src/login/account.h b/src/login/account.h
index 22e31d799..1b567be70 100644
--- a/src/login/account.h
+++ b/src/login/account.h
@@ -12,141 +12,144 @@ typedef struct AccountDBIterator AccountDBIterator;
// standard engines
-AccountDB *account_db_sql(void);
+AccountDB* account_db_sql(void);
// extra engines (will probably use the other txt functions)
#define ACCOUNTDB_CONSTRUCTOR_(engine) account_db_##engine
#define ACCOUNTDB_CONSTRUCTOR(engine) ACCOUNTDB_CONSTRUCTOR_(engine)
#ifdef ACCOUNTDB_ENGINE_0
-AccountDB *ACCOUNTDB_CONSTRUCTOR(ACCOUNTDB_ENGINE_0)(void);
+AccountDB* ACCOUNTDB_CONSTRUCTOR(ACCOUNTDB_ENGINE_0)(void);
#endif
#ifdef ACCOUNTDB_ENGINE_1
-AccountDB *ACCOUNTDB_CONSTRUCTOR(ACCOUNTDB_ENGINE_1)(void);
+AccountDB* ACCOUNTDB_CONSTRUCTOR(ACCOUNTDB_ENGINE_1)(void);
#endif
#ifdef ACCOUNTDB_ENGINE_2
-AccountDB *ACCOUNTDB_CONSTRUCTOR(ACCOUNTDB_ENGINE_2)(void);
+AccountDB* ACCOUNTDB_CONSTRUCTOR(ACCOUNTDB_ENGINE_2)(void);
#endif
#ifdef ACCOUNTDB_ENGINE_3
-AccountDB *ACCOUNTDB_CONSTRUCTOR(ACCOUNTDB_ENGINE_3)(void);
+AccountDB* ACCOUNTDB_CONSTRUCTOR(ACCOUNTDB_ENGINE_3)(void);
#endif
#ifdef ACCOUNTDB_ENGINE_4
-AccountDB *ACCOUNTDB_CONSTRUCTOR(ACCOUNTDB_ENGINE_4)(void);
+AccountDB* ACCOUNTDB_CONSTRUCTOR(ACCOUNTDB_ENGINE_4)(void);
#endif
-struct mmo_account {
- int account_id;
- char userid[NAME_LENGTH];
- char pass[32+1]; // 23+1 for plaintext, 32+1 for md5-ed passwords
- char sex; // gender (M/F/S)
- char email[40]; // e-mail (by default: a@a.com)
- int group_id; // player group id
- unsigned int state; // packet 0x006a value + 1 (0: compte OK)
- time_t unban_time; // (timestamp): ban time limit of the account (0 = no ban)
- time_t expiration_time; // (timestamp): validity limit of the account (0 = unlimited)
- unsigned int logincount;// number of successful auth attempts
- char lastlogin[24]; // date+time of last successful login
- char last_ip[16]; // save of last IP of connection
- char birthdate[10+1]; // assigned birth date (format: YYYY-MM-DD, default: 0000-00-00)
- int account_reg2_num;
- struct global_reg account_reg2[ACCOUNT_REG2_NUM]; // account script variables (stored on login server)
+struct mmo_account
+{
+ int account_id;
+ char userid[NAME_LENGTH];
+ char pass[32+1]; // 23+1 for plaintext, 32+1 for md5-ed passwords
+ char sex; // gender (M/F/S)
+ char email[40]; // e-mail (by default: a@a.com)
+ int group_id; // player group id
+ unsigned int state; // packet 0x006a value + 1 (0: compte OK)
+ time_t unban_time; // (timestamp): ban time limit of the account (0 = no ban)
+ time_t expiration_time; // (timestamp): validity limit of the account (0 = unlimited)
+ unsigned int logincount;// number of successful auth attempts
+ char lastlogin[24]; // date+time of last successful login
+ char last_ip[16]; // save of last IP of connection
+ char birthdate[10+1]; // assigned birth date (format: YYYY-MM-DD, default: 0000-00-00)
+ int account_reg2_num;
+ struct global_reg account_reg2[ACCOUNT_REG2_NUM]; // account script variables (stored on login server)
};
-struct AccountDBIterator {
- /// Destroys this iterator, releasing all allocated memory (including itself).
- ///
- /// @param self Iterator
- void (*destroy)(AccountDBIterator *self);
+struct AccountDBIterator
+{
+ /// Destroys this iterator, releasing all allocated memory (including itself).
+ ///
+ /// @param self Iterator
+ void (*destroy)(AccountDBIterator* self);
- /// Fetches the next account in the database.
- /// Fills acc with the account data.
- /// @param self Iterator
- /// @param acc Account data
- /// @return true if successful
- bool (*next)(AccountDBIterator *self, struct mmo_account *acc);
+ /// Fetches the next account in the database.
+ /// Fills acc with the account data.
+ /// @param self Iterator
+ /// @param acc Account data
+ /// @return true if successful
+ bool (*next)(AccountDBIterator* self, struct mmo_account* acc);
};
-struct AccountDB {
- /// Initializes this database, making it ready for use.
- /// Call this after setting the properties.
- ///
- /// @param self Database
- /// @return true if successful
- bool (*init)(AccountDB *self);
-
- /// Destroys this database, releasing all allocated memory (including itself).
- ///
- /// @param self Database
- void (*destroy)(AccountDB *self);
-
- /// Gets a property from this database.
- /// These read-only properties must be implemented:
- /// "engine.name" -> "txt", "sql", ...
- /// "engine.version" -> internal version
- /// "engine.comment" -> anything (suggestion: description or specs of the engine)
- ///
- /// @param self Database
- /// @param key Property name
- /// @param buf Buffer for the value
- /// @param buflen Buffer length
- /// @return true if successful
- bool (*get_property)(AccountDB *self, const char *key, char *buf, size_t buflen);
-
- /// Sets a property in this database.
- ///
- /// @param self Database
- /// @param key Property name
- /// @param value Property value
- /// @return true if successful
- bool (*set_property)(AccountDB *self, const char *key, const char *value);
-
- /// Creates a new account in this database.
- /// If acc->account_id is not -1, the provided value will be used.
- /// Otherwise the account_id will be auto-generated and written to acc->account_id.
- ///
- /// @param self Database
- /// @param acc Account data
- /// @return true if successful
- bool (*create)(AccountDB *self, struct mmo_account *acc);
-
- /// Removes an account from this database.
- ///
- /// @param self Database
- /// @param account_id Account id
- /// @return true if successful
- bool (*remove)(AccountDB *self, const int account_id);
-
- /// Modifies the data of an existing account.
- /// Uses acc->account_id to identify the account.
- ///
- /// @param self Database
- /// @param acc Account data
- /// @return true if successful
- bool (*save)(AccountDB *self, const struct mmo_account *acc);
-
- /// Finds an account with account_id and copies it to acc.
- ///
- /// @param self Database
- /// @param acc Pointer that receives the account data
- /// @param account_id Target account id
- /// @return true if successful
- bool (*load_num)(AccountDB *self, struct mmo_account *acc, const int account_id);
-
- /// Finds an account with userid and copies it to acc.
- ///
- /// @param self Database
- /// @param acc Pointer that receives the account data
- /// @param userid Target username
- /// @return true if successful
- bool (*load_str)(AccountDB *self, struct mmo_account *acc, const char *userid);
-
- /// Returns a new forward iterator.
- ///
- /// @param self Database
- /// @return Iterator
- AccountDBIterator *(*iterator)(AccountDB *self);
+struct AccountDB
+{
+ /// Initializes this database, making it ready for use.
+ /// Call this after setting the properties.
+ ///
+ /// @param self Database
+ /// @return true if successful
+ bool (*init)(AccountDB* self);
+
+ /// Destroys this database, releasing all allocated memory (including itself).
+ ///
+ /// @param self Database
+ void (*destroy)(AccountDB* self);
+
+ /// Gets a property from this database.
+ /// These read-only properties must be implemented:
+ /// "engine.name" -> "txt", "sql", ...
+ /// "engine.version" -> internal version
+ /// "engine.comment" -> anything (suggestion: description or specs of the engine)
+ ///
+ /// @param self Database
+ /// @param key Property name
+ /// @param buf Buffer for the value
+ /// @param buflen Buffer length
+ /// @return true if successful
+ bool (*get_property)(AccountDB* self, const char* key, char* buf, size_t buflen);
+
+ /// Sets a property in this database.
+ ///
+ /// @param self Database
+ /// @param key Property name
+ /// @param value Property value
+ /// @return true if successful
+ bool (*set_property)(AccountDB* self, const char* key, const char* value);
+
+ /// Creates a new account in this database.
+ /// If acc->account_id is not -1, the provided value will be used.
+ /// Otherwise the account_id will be auto-generated and written to acc->account_id.
+ ///
+ /// @param self Database
+ /// @param acc Account data
+ /// @return true if successful
+ bool (*create)(AccountDB* self, struct mmo_account* acc);
+
+ /// Removes an account from this database.
+ ///
+ /// @param self Database
+ /// @param account_id Account id
+ /// @return true if successful
+ bool (*remove)(AccountDB* self, const int account_id);
+
+ /// Modifies the data of an existing account.
+ /// Uses acc->account_id to identify the account.
+ ///
+ /// @param self Database
+ /// @param acc Account data
+ /// @return true if successful
+ bool (*save)(AccountDB* self, const struct mmo_account* acc);
+
+ /// Finds an account with account_id and copies it to acc.
+ ///
+ /// @param self Database
+ /// @param acc Pointer that receives the account data
+ /// @param account_id Target account id
+ /// @return true if successful
+ bool (*load_num)(AccountDB* self, struct mmo_account* acc, const int account_id);
+
+ /// Finds an account with userid and copies it to acc.
+ ///
+ /// @param self Database
+ /// @param acc Pointer that receives the account data
+ /// @param userid Target username
+ /// @return true if successful
+ bool (*load_str)(AccountDB* self, struct mmo_account* acc, const char* userid);
+
+ /// Returns a new forward iterator.
+ ///
+ /// @param self Database
+ /// @return Iterator
+ AccountDBIterator* (*iterator)(AccountDB* self);
};
diff --git a/src/login/account_sql.c b/src/login/account_sql.c
index 6e56d4688..5073941e2 100644
--- a/src/login/account_sql.c
+++ b/src/login/account_sql.c
@@ -15,96 +15,98 @@
#define ACCOUNT_SQL_DB_VERSION 20110114
/// internal structure
-typedef struct AccountDB_SQL {
- AccountDB vtable; // public interface
-
- Sql *accounts; // SQL accounts storage
-
- // global sql settings
- char global_db_hostname[32];
- uint16 global_db_port;
- char global_db_username[32];
- char global_db_password[32];
- char global_db_database[32];
- char global_codepage[32];
- // local sql settings
- char db_hostname[32];
- uint16 db_port;
- char db_username[32];
- char db_password[32];
- char db_database[32];
- char codepage[32];
- // other settings
- bool case_sensitive;
- char account_db[32];
- char accreg_db[32];
+typedef struct AccountDB_SQL
+{
+ AccountDB vtable; // public interface
+
+ Sql* accounts; // SQL accounts storage
+
+ // global sql settings
+ char global_db_hostname[32];
+ uint16 global_db_port;
+ char global_db_username[32];
+ char global_db_password[32];
+ char global_db_database[32];
+ char global_codepage[32];
+ // local sql settings
+ char db_hostname[32];
+ uint16 db_port;
+ char db_username[32];
+ char db_password[32];
+ char db_database[32];
+ char codepage[32];
+ // other settings
+ bool case_sensitive;
+ char account_db[32];
+ char accreg_db[32];
} AccountDB_SQL;
/// internal structure
-typedef struct AccountDBIterator_SQL {
- AccountDBIterator vtable; // public interface
+typedef struct AccountDBIterator_SQL
+{
+ AccountDBIterator vtable; // public interface
- AccountDB_SQL *db;
- int last_account_id;
+ AccountDB_SQL* db;
+ int last_account_id;
} AccountDBIterator_SQL;
/// internal functions
-static bool account_db_sql_init(AccountDB *self);
-static void account_db_sql_destroy(AccountDB *self);
-static bool account_db_sql_get_property(AccountDB *self, const char *key, char *buf, size_t buflen);
-static bool account_db_sql_set_property(AccountDB *self, const char *option, const char *value);
-static bool account_db_sql_create(AccountDB *self, struct mmo_account *acc);
-static bool account_db_sql_remove(AccountDB *self, const int account_id);
-static bool account_db_sql_save(AccountDB *self, const struct mmo_account *acc);
-static bool account_db_sql_load_num(AccountDB *self, struct mmo_account *acc, const int account_id);
-static bool account_db_sql_load_str(AccountDB *self, struct mmo_account *acc, const char *userid);
-static AccountDBIterator *account_db_sql_iterator(AccountDB *self);
-static void account_db_sql_iter_destroy(AccountDBIterator *self);
-static bool account_db_sql_iter_next(AccountDBIterator *self, struct mmo_account *acc);
-
-static bool mmo_auth_fromsql(AccountDB_SQL *db, struct mmo_account *acc, int account_id);
-static bool mmo_auth_tosql(AccountDB_SQL *db, const struct mmo_account *acc, bool is_new);
+static bool account_db_sql_init(AccountDB* self);
+static void account_db_sql_destroy(AccountDB* self);
+static bool account_db_sql_get_property(AccountDB* self, const char* key, char* buf, size_t buflen);
+static bool account_db_sql_set_property(AccountDB* self, const char* option, const char* value);
+static bool account_db_sql_create(AccountDB* self, struct mmo_account* acc);
+static bool account_db_sql_remove(AccountDB* self, const int account_id);
+static bool account_db_sql_save(AccountDB* self, const struct mmo_account* acc);
+static bool account_db_sql_load_num(AccountDB* self, struct mmo_account* acc, const int account_id);
+static bool account_db_sql_load_str(AccountDB* self, struct mmo_account* acc, const char* userid);
+static AccountDBIterator* account_db_sql_iterator(AccountDB* self);
+static void account_db_sql_iter_destroy(AccountDBIterator* self);
+static bool account_db_sql_iter_next(AccountDBIterator* self, struct mmo_account* acc);
+
+static bool mmo_auth_fromsql(AccountDB_SQL* db, struct mmo_account* acc, int account_id);
+static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, bool is_new);
/// public constructor
-AccountDB *account_db_sql(void)
+AccountDB* account_db_sql(void)
{
- AccountDB_SQL *db = (AccountDB_SQL *)aCalloc(1, sizeof(AccountDB_SQL));
-
- // set up the vtable
- db->vtable.init = &account_db_sql_init;
- db->vtable.destroy = &account_db_sql_destroy;
- db->vtable.get_property = &account_db_sql_get_property;
- db->vtable.set_property = &account_db_sql_set_property;
- db->vtable.save = &account_db_sql_save;
- db->vtable.create = &account_db_sql_create;
- db->vtable.remove = &account_db_sql_remove;
- db->vtable.load_num = &account_db_sql_load_num;
- db->vtable.load_str = &account_db_sql_load_str;
- db->vtable.iterator = &account_db_sql_iterator;
-
- // initialize to default values
- db->accounts = NULL;
- // global sql settings
- safestrncpy(db->global_db_hostname, "127.0.0.1", sizeof(db->global_db_hostname));
- db->global_db_port = 3306;
- safestrncpy(db->global_db_username, "ragnarok", sizeof(db->global_db_username));
- safestrncpy(db->global_db_password, "ragnarok", sizeof(db->global_db_password));
- safestrncpy(db->global_db_database, "ragnarok", sizeof(db->global_db_database));
- safestrncpy(db->global_codepage, "", sizeof(db->global_codepage));
- // local sql settings
- safestrncpy(db->db_hostname, "", sizeof(db->db_hostname));
- db->db_port = 3306;
- safestrncpy(db->db_username, "", sizeof(db->db_username));
- safestrncpy(db->db_password, "", sizeof(db->db_password));
- safestrncpy(db->db_database, "", sizeof(db->db_database));
- safestrncpy(db->codepage, "", sizeof(db->codepage));
- // other settings
- db->case_sensitive = false;
- safestrncpy(db->account_db, "login", sizeof(db->account_db));
- safestrncpy(db->accreg_db, "global_reg_value", sizeof(db->accreg_db));
-
- return &db->vtable;
+ AccountDB_SQL* db = (AccountDB_SQL*)aCalloc(1, sizeof(AccountDB_SQL));
+
+ // set up the vtable
+ db->vtable.init = &account_db_sql_init;
+ db->vtable.destroy = &account_db_sql_destroy;
+ db->vtable.get_property = &account_db_sql_get_property;
+ db->vtable.set_property = &account_db_sql_set_property;
+ db->vtable.save = &account_db_sql_save;
+ db->vtable.create = &account_db_sql_create;
+ db->vtable.remove = &account_db_sql_remove;
+ db->vtable.load_num = &account_db_sql_load_num;
+ db->vtable.load_str = &account_db_sql_load_str;
+ db->vtable.iterator = &account_db_sql_iterator;
+
+ // initialize to default values
+ db->accounts = NULL;
+ // global sql settings
+ safestrncpy(db->global_db_hostname, "127.0.0.1", sizeof(db->global_db_hostname));
+ db->global_db_port = 3306;
+ safestrncpy(db->global_db_username, "ragnarok", sizeof(db->global_db_username));
+ safestrncpy(db->global_db_password, "ragnarok", sizeof(db->global_db_password));
+ safestrncpy(db->global_db_database, "ragnarok", sizeof(db->global_db_database));
+ safestrncpy(db->global_codepage, "", sizeof(db->global_codepage));
+ // local sql settings
+ safestrncpy(db->db_hostname, "", sizeof(db->db_hostname));
+ db->db_port = 3306;
+ safestrncpy(db->db_username, "", sizeof(db->db_username));
+ safestrncpy(db->db_password, "", sizeof(db->db_password));
+ safestrncpy(db->db_database, "", sizeof(db->db_database));
+ safestrncpy(db->codepage, "", sizeof(db->codepage));
+ // other settings
+ db->case_sensitive = false;
+ safestrncpy(db->account_db, "login", sizeof(db->account_db));
+ safestrncpy(db->accreg_db, "global_reg_value", sizeof(db->accreg_db));
+
+ return &db->vtable;
}
@@ -112,532 +114,567 @@ AccountDB *account_db_sql(void)
/// establishes database connection
-static bool account_db_sql_init(AccountDB *self)
+static bool account_db_sql_init(AccountDB* self)
{
- AccountDB_SQL *db = (AccountDB_SQL *)self;
- Sql *sql_handle;
- const char *username;
- const char *password;
- const char *hostname;
- uint16 port;
- const char *database;
- const char *codepage;
-
- db->accounts = Sql_Malloc();
- sql_handle = db->accounts;
-
- if (db->db_hostname[0] != '\0') {
- // local settings
- username = db->db_username;
- password = db->db_password;
- hostname = db->db_hostname;
- port = db->db_port;
- database = db->db_database;
- codepage = db->codepage;
- } else {
- // global settings
- username = db->global_db_username;
- password = db->global_db_password;
- hostname = db->global_db_hostname;
- port = db->global_db_port;
- database = db->global_db_database;
- codepage = db->global_codepage;
- }
-
- if (SQL_ERROR == Sql_Connect(sql_handle, username, password, hostname, port, database)) {
- Sql_ShowDebug(sql_handle);
- Sql_Free(db->accounts);
- db->accounts = NULL;
- return false;
- }
-
- if (codepage[0] != '\0' && SQL_ERROR == Sql_SetEncoding(sql_handle, codepage))
- Sql_ShowDebug(sql_handle);
-
- return true;
+ AccountDB_SQL* db = (AccountDB_SQL*)self;
+ Sql* sql_handle;
+ const char* username;
+ const char* password;
+ const char* hostname;
+ uint16 port;
+ const char* database;
+ const char* codepage;
+
+ db->accounts = Sql_Malloc();
+ sql_handle = db->accounts;
+
+ if( db->db_hostname[0] != '\0' )
+ {// local settings
+ username = db->db_username;
+ password = db->db_password;
+ hostname = db->db_hostname;
+ port = db->db_port;
+ database = db->db_database;
+ codepage = db->codepage;
+ }
+ else
+ {// global settings
+ username = db->global_db_username;
+ password = db->global_db_password;
+ hostname = db->global_db_hostname;
+ port = db->global_db_port;
+ database = db->global_db_database;
+ codepage = db->global_codepage;
+ }
+
+ if( SQL_ERROR == Sql_Connect(sql_handle, username, password, hostname, port, database) )
+ {
+ Sql_ShowDebug(sql_handle);
+ Sql_Free(db->accounts);
+ db->accounts = NULL;
+ return false;
+ }
+
+ if( codepage[0] != '\0' && SQL_ERROR == Sql_SetEncoding(sql_handle, codepage) )
+ Sql_ShowDebug(sql_handle);
+
+ return true;
}
/// disconnects from database
-static void account_db_sql_destroy(AccountDB *self)
+static void account_db_sql_destroy(AccountDB* self)
{
- AccountDB_SQL *db = (AccountDB_SQL *)self;
+ AccountDB_SQL* db = (AccountDB_SQL*)self;
- Sql_Free(db->accounts);
- db->accounts = NULL;
- aFree(db);
+ Sql_Free(db->accounts);
+ db->accounts = NULL;
+ aFree(db);
}
/// Gets a property from this database.
-static bool account_db_sql_get_property(AccountDB *self, const char *key, char *buf, size_t buflen)
+static bool account_db_sql_get_property(AccountDB* self, const char* key, char* buf, size_t buflen)
{
- AccountDB_SQL *db = (AccountDB_SQL *)self;
- const char *signature;
-
- signature = "engine.";
- if (strncmpi(key, signature, strlen(signature)) == 0) {
- key += strlen(signature);
- if (strcmpi(key, "name") == 0)
- safesnprintf(buf, buflen, "sql");
- else if (strcmpi(key, "version") == 0)
- safesnprintf(buf, buflen, "%d", ACCOUNT_SQL_DB_VERSION);
- else if (strcmpi(key, "comment") == 0)
- safesnprintf(buf, buflen, "SQL Account Database");
- else
- return false;// not found
- return true;
- }
-
- signature = "sql.";
- if (strncmpi(key, signature, strlen(signature)) == 0) {
- key += strlen(signature);
- if (strcmpi(key, "db_hostname") == 0)
- safesnprintf(buf, buflen, "%s", db->global_db_hostname);
- else if (strcmpi(key, "db_port") == 0)
- safesnprintf(buf, buflen, "%d", db->global_db_port);
- else if (strcmpi(key, "db_username") == 0)
- safesnprintf(buf, buflen, "%s", db->global_db_username);
- else if (strcmpi(key, "db_password") == 0)
- safesnprintf(buf, buflen, "%s", db->global_db_password);
- else if (strcmpi(key, "db_database") == 0)
- safesnprintf(buf, buflen, "%s", db->global_db_database);
- else if (strcmpi(key, "codepage") == 0)
- safesnprintf(buf, buflen, "%s", db->global_codepage);
- else
- return false;// not found
- return true;
- }
-
- signature = "account.sql.";
- if (strncmpi(key, signature, strlen(signature)) == 0) {
- key += strlen(signature);
- if (strcmpi(key, "db_hostname") == 0)
- safesnprintf(buf, buflen, "%s", db->db_hostname);
- else if (strcmpi(key, "db_port") == 0)
- safesnprintf(buf, buflen, "%d", db->db_port);
- else if (strcmpi(key, "db_username") == 0)
- safesnprintf(buf, buflen, "%s", db->db_username);
- else if (strcmpi(key, "db_password") == 0)
- safesnprintf(buf, buflen, "%s", db->db_password);
- else if (strcmpi(key, "db_database") == 0)
- safesnprintf(buf, buflen, "%s", db->db_database);
- else if (strcmpi(key, "codepage") == 0)
- safesnprintf(buf, buflen, "%s", db->codepage);
- else if (strcmpi(key, "case_sensitive") == 0)
- safesnprintf(buf, buflen, "%d", (db->case_sensitive ? 1 : 0));
- else if (strcmpi(key, "account_db") == 0)
- safesnprintf(buf, buflen, "%s", db->account_db);
- else if (strcmpi(key, "accreg_db") == 0)
- safesnprintf(buf, buflen, "%s", db->accreg_db);
- else
- return false;// not found
- return true;
- }
-
- return false;// not found
+ AccountDB_SQL* db = (AccountDB_SQL*)self;
+ const char* signature;
+
+ signature = "engine.";
+ if( strncmpi(key, signature, strlen(signature)) == 0 )
+ {
+ key += strlen(signature);
+ if( strcmpi(key, "name") == 0 )
+ safesnprintf(buf, buflen, "sql");
+ else
+ if( strcmpi(key, "version") == 0 )
+ safesnprintf(buf, buflen, "%d", ACCOUNT_SQL_DB_VERSION);
+ else
+ if( strcmpi(key, "comment") == 0 )
+ safesnprintf(buf, buflen, "SQL Account Database");
+ else
+ return false;// not found
+ return true;
+ }
+
+ signature = "sql.";
+ if( strncmpi(key, signature, strlen(signature)) == 0 )
+ {
+ key += strlen(signature);
+ if( strcmpi(key, "db_hostname") == 0 )
+ safesnprintf(buf, buflen, "%s", db->global_db_hostname);
+ else
+ if( strcmpi(key, "db_port") == 0 )
+ safesnprintf(buf, buflen, "%d", db->global_db_port);
+ else
+ if( strcmpi(key, "db_username") == 0 )
+ safesnprintf(buf, buflen, "%s", db->global_db_username);
+ else
+ if( strcmpi(key, "db_password") == 0 )
+ safesnprintf(buf, buflen, "%s", db->global_db_password);
+ else
+ if( strcmpi(key, "db_database") == 0 )
+ safesnprintf(buf, buflen, "%s", db->global_db_database);
+ else
+ if( strcmpi(key, "codepage") == 0 )
+ safesnprintf(buf, buflen, "%s", db->global_codepage);
+ else
+ return false;// not found
+ return true;
+ }
+
+ signature = "account.sql.";
+ if( strncmpi(key, signature, strlen(signature)) == 0 )
+ {
+ key += strlen(signature);
+ if( strcmpi(key, "db_hostname") == 0 )
+ safesnprintf(buf, buflen, "%s", db->db_hostname);
+ else
+ if( strcmpi(key, "db_port") == 0 )
+ safesnprintf(buf, buflen, "%d", db->db_port);
+ else
+ if( strcmpi(key, "db_username") == 0 )
+ safesnprintf(buf, buflen, "%s", db->db_username);
+ else
+ if( strcmpi(key, "db_password") == 0 )
+ safesnprintf(buf, buflen, "%s", db->db_password);
+ else
+ if( strcmpi(key, "db_database") == 0 )
+ safesnprintf(buf, buflen, "%s", db->db_database);
+ else
+ if( strcmpi(key, "codepage") == 0 )
+ safesnprintf(buf, buflen, "%s", db->codepage);
+ else
+ if( strcmpi(key, "case_sensitive") == 0 )
+ safesnprintf(buf, buflen, "%d", (db->case_sensitive ? 1 : 0));
+ else
+ if( strcmpi(key, "account_db") == 0 )
+ safesnprintf(buf, buflen, "%s", db->account_db);
+ else
+ if( strcmpi(key, "accreg_db") == 0 )
+ safesnprintf(buf, buflen, "%s", db->accreg_db);
+ else
+ return false;// not found
+ return true;
+ }
+
+ return false;// not found
}
/// if the option is supported, adjusts the internal state
-static bool account_db_sql_set_property(AccountDB *self, const char *key, const char *value)
+static bool account_db_sql_set_property(AccountDB* self, const char* key, const char* value)
{
- AccountDB_SQL *db = (AccountDB_SQL *)self;
- const char *signature;
-
-
- signature = "sql.";
- if (strncmp(key, signature, strlen(signature)) == 0) {
- key += strlen(signature);
- if (strcmpi(key, "db_hostname") == 0)
- safestrncpy(db->global_db_hostname, value, sizeof(db->global_db_hostname));
- else if (strcmpi(key, "db_port") == 0)
- db->global_db_port = (uint16)strtoul(value, NULL, 10);
- else if (strcmpi(key, "db_username") == 0)
- safestrncpy(db->global_db_username, value, sizeof(db->global_db_username));
- else if (strcmpi(key, "db_password") == 0)
- safestrncpy(db->global_db_password, value, sizeof(db->global_db_password));
- else if (strcmpi(key, "db_database") == 0)
- safestrncpy(db->global_db_database, value, sizeof(db->global_db_database));
- else if (strcmpi(key, "codepage") == 0)
- safestrncpy(db->global_codepage, value, sizeof(db->global_codepage));
- else
- return false;// not found
- return true;
- }
-
- signature = "account.sql.";
- if (strncmp(key, signature, strlen(signature)) == 0) {
- key += strlen(signature);
- if (strcmpi(key, "db_hostname") == 0)
- safestrncpy(db->db_hostname, value, sizeof(db->db_hostname));
- else if (strcmpi(key, "db_port") == 0)
- db->db_port = (uint16)strtoul(value, NULL, 10);
- else if (strcmpi(key, "db_username") == 0)
- safestrncpy(db->db_username, value, sizeof(db->db_username));
- else if (strcmpi(key, "db_password") == 0)
- safestrncpy(db->db_password, value, sizeof(db->db_password));
- else if (strcmpi(key, "db_database") == 0)
- safestrncpy(db->db_database, value, sizeof(db->db_database));
- else if (strcmpi(key, "codepage") == 0)
- safestrncpy(db->codepage, value, sizeof(db->codepage));
- else if (strcmpi(key, "case_sensitive") == 0)
- db->case_sensitive = config_switch(value);
- else if (strcmpi(key, "account_db") == 0)
- safestrncpy(db->account_db, value, sizeof(db->account_db));
- else if (strcmpi(key, "accreg_db") == 0)
- safestrncpy(db->accreg_db, value, sizeof(db->accreg_db));
- else
- return false;// not found
- return true;
- }
-
- return false;// not found
+ AccountDB_SQL* db = (AccountDB_SQL*)self;
+ const char* signature;
+
+
+ signature = "sql.";
+ if( strncmp(key, signature, strlen(signature)) == 0 )
+ {
+ key += strlen(signature);
+ if( strcmpi(key, "db_hostname") == 0 )
+ safestrncpy(db->global_db_hostname, value, sizeof(db->global_db_hostname));
+ else
+ if( strcmpi(key, "db_port") == 0 )
+ db->global_db_port = (uint16)strtoul(value, NULL, 10);
+ else
+ if( strcmpi(key, "db_username") == 0 )
+ safestrncpy(db->global_db_username, value, sizeof(db->global_db_username));
+ else
+ if( strcmpi(key, "db_password") == 0 )
+ safestrncpy(db->global_db_password, value, sizeof(db->global_db_password));
+ else
+ if( strcmpi(key, "db_database") == 0 )
+ safestrncpy(db->global_db_database, value, sizeof(db->global_db_database));
+ else
+ if( strcmpi(key, "codepage") == 0 )
+ safestrncpy(db->global_codepage, value, sizeof(db->global_codepage));
+ else
+ return false;// not found
+ return true;
+ }
+
+ signature = "account.sql.";
+ if( strncmp(key, signature, strlen(signature)) == 0 )
+ {
+ key += strlen(signature);
+ if( strcmpi(key, "db_hostname") == 0 )
+ safestrncpy(db->db_hostname, value, sizeof(db->db_hostname));
+ else
+ if( strcmpi(key, "db_port") == 0 )
+ db->db_port = (uint16)strtoul(value, NULL, 10);
+ else
+ if( strcmpi(key, "db_username") == 0 )
+ safestrncpy(db->db_username, value, sizeof(db->db_username));
+ else
+ if( strcmpi(key, "db_password") == 0 )
+ safestrncpy(db->db_password, value, sizeof(db->db_password));
+ else
+ if( strcmpi(key, "db_database") == 0 )
+ safestrncpy(db->db_database, value, sizeof(db->db_database));
+ else
+ if( strcmpi(key, "codepage") == 0 )
+ safestrncpy(db->codepage, value, sizeof(db->codepage));
+ else
+ if( strcmpi(key, "case_sensitive") == 0 )
+ db->case_sensitive = config_switch(value);
+ else
+ if( strcmpi(key, "account_db") == 0 )
+ safestrncpy(db->account_db, value, sizeof(db->account_db));
+ else
+ if( strcmpi(key, "accreg_db") == 0 )
+ safestrncpy(db->accreg_db, value, sizeof(db->accreg_db));
+ else
+ return false;// not found
+ return true;
+ }
+
+ return false;// not found
}
/// create a new account entry
/// If acc->account_id is -1, the account id will be auto-generated,
/// and its value will be written to acc->account_id if everything succeeds.
-static bool account_db_sql_create(AccountDB *self, struct mmo_account *acc)
+static bool account_db_sql_create(AccountDB* self, struct mmo_account* acc)
{
- AccountDB_SQL *db = (AccountDB_SQL *)self;
- Sql *sql_handle = db->accounts;
-
- // decide on the account id to assign
- int account_id;
- if (acc->account_id != -1) {
- // caller specifies it manually
- account_id = acc->account_id;
- } else {
- // ask the database
- char *data;
- size_t len;
-
- if (SQL_SUCCESS != Sql_Query(sql_handle, "SELECT MAX(`account_id`)+1 FROM `%s`", db->account_db)) {
- Sql_ShowDebug(sql_handle);
- return false;
- }
- if (SQL_SUCCESS != Sql_NextRow(sql_handle)) {
- Sql_ShowDebug(sql_handle);
- Sql_FreeResult(sql_handle);
- return false;
- }
-
- Sql_GetData(sql_handle, 0, &data, &len);
- account_id = (data != NULL) ? atoi(data) : 0;
- Sql_FreeResult(sql_handle);
-
- if (account_id < START_ACCOUNT_NUM)
- account_id = START_ACCOUNT_NUM;
-
- }
-
- // zero value is prohibited
- if (account_id == 0)
- return false;
-
- // absolute maximum
- if (account_id > END_ACCOUNT_NUM)
- return false;
-
- // insert the data into the database
- acc->account_id = account_id;
- return mmo_auth_tosql(db, acc, true);
+ AccountDB_SQL* db = (AccountDB_SQL*)self;
+ Sql* sql_handle = db->accounts;
+
+ // decide on the account id to assign
+ int account_id;
+ if( acc->account_id != -1 )
+ {// caller specifies it manually
+ account_id = acc->account_id;
+ }
+ else
+ {// ask the database
+ char* data;
+ size_t len;
+
+ if( SQL_SUCCESS != Sql_Query(sql_handle, "SELECT MAX(`account_id`)+1 FROM `%s`", db->account_db) )
+ {
+ Sql_ShowDebug(sql_handle);
+ return false;
+ }
+ if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
+ {
+ Sql_ShowDebug(sql_handle);
+ Sql_FreeResult(sql_handle);
+ return false;
+ }
+
+ Sql_GetData(sql_handle, 0, &data, &len);
+ account_id = ( data != NULL ) ? atoi(data) : 0;
+ Sql_FreeResult(sql_handle);
+
+ if( account_id < START_ACCOUNT_NUM )
+ account_id = START_ACCOUNT_NUM;
+
+ }
+
+ // zero value is prohibited
+ if( account_id == 0 )
+ return false;
+
+ // absolute maximum
+ if( account_id > END_ACCOUNT_NUM )
+ return false;
+
+ // insert the data into the database
+ acc->account_id = account_id;
+ return mmo_auth_tosql(db, acc, true);
}
/// delete an existing account entry + its regs
-static bool account_db_sql_remove(AccountDB *self, const int account_id)
+static bool account_db_sql_remove(AccountDB* self, const int account_id)
{
- AccountDB_SQL *db = (AccountDB_SQL *)self;
- Sql *sql_handle = db->accounts;
- bool result = false;
+ AccountDB_SQL* db = (AccountDB_SQL*)self;
+ Sql* sql_handle = db->accounts;
+ bool result = false;
- if (SQL_SUCCESS != Sql_QueryStr(sql_handle, "START TRANSACTION")
- || SQL_SUCCESS != Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = %d", db->account_db, account_id)
- || SQL_SUCCESS != Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = %d", db->accreg_db, account_id))
- Sql_ShowDebug(sql_handle);
- else
- result = true;
+ if( SQL_SUCCESS != Sql_QueryStr(sql_handle, "START TRANSACTION")
+ || SQL_SUCCESS != Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = %d", db->account_db, account_id)
+ || SQL_SUCCESS != Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = %d", db->accreg_db, account_id) )
+ Sql_ShowDebug(sql_handle);
+ else
+ result = true;
- result &= (SQL_SUCCESS == Sql_QueryStr(sql_handle, (result == true) ? "COMMIT" : "ROLLBACK"));
+ result &= ( SQL_SUCCESS == Sql_QueryStr(sql_handle, (result == true) ? "COMMIT" : "ROLLBACK") );
- return result;
+ return result;
}
/// update an existing account with the provided new data (both account and regs)
-static bool account_db_sql_save(AccountDB *self, const struct mmo_account *acc)
+static bool account_db_sql_save(AccountDB* self, const struct mmo_account* acc)
{
- AccountDB_SQL *db = (AccountDB_SQL *)self;
- return mmo_auth_tosql(db, acc, false);
+ AccountDB_SQL* db = (AccountDB_SQL*)self;
+ return mmo_auth_tosql(db, acc, false);
}
/// retrieve data from db and store it in the provided data structure
-static bool account_db_sql_load_num(AccountDB *self, struct mmo_account *acc, const int account_id)
+static bool account_db_sql_load_num(AccountDB* self, struct mmo_account* acc, const int account_id)
{
- AccountDB_SQL *db = (AccountDB_SQL *)self;
- return mmo_auth_fromsql(db, acc, account_id);
+ AccountDB_SQL* db = (AccountDB_SQL*)self;
+ return mmo_auth_fromsql(db, acc, account_id);
}
/// retrieve data from db and store it in the provided data structure
-static bool account_db_sql_load_str(AccountDB *self, struct mmo_account *acc, const char *userid)
+static bool account_db_sql_load_str(AccountDB* self, struct mmo_account* acc, const char* userid)
{
- AccountDB_SQL *db = (AccountDB_SQL *)self;
- Sql *sql_handle = db->accounts;
- char esc_userid[2*NAME_LENGTH+1];
- int account_id;
- char *data;
-
- Sql_EscapeString(sql_handle, esc_userid, userid);
-
- // get the list of account IDs for this user ID
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id` FROM `%s` WHERE `userid`= %s '%s'",
- db->account_db, (db->case_sensitive ? "BINARY" : ""), esc_userid)) {
- Sql_ShowDebug(sql_handle);
- return false;
- }
-
- if (Sql_NumRows(sql_handle) > 1) {
- // serious problem - duplicit account
- ShowError("account_db_sql_load_str: multiple accounts found when retrieving data for account '%s'!\n", userid);
- Sql_FreeResult(sql_handle);
- return false;
- }
-
- if (SQL_SUCCESS != Sql_NextRow(sql_handle)) {
- // no such entry
- Sql_FreeResult(sql_handle);
- return false;
- }
-
- Sql_GetData(sql_handle, 0, &data, NULL);
- account_id = atoi(data);
-
- return account_db_sql_load_num(self, acc, account_id);
+ AccountDB_SQL* db = (AccountDB_SQL*)self;
+ Sql* sql_handle = db->accounts;
+ char esc_userid[2*NAME_LENGTH+1];
+ int account_id;
+ char* data;
+
+ Sql_EscapeString(sql_handle, esc_userid, userid);
+
+ // get the list of account IDs for this user ID
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id` FROM `%s` WHERE `userid`= %s '%s'",
+ db->account_db, (db->case_sensitive ? "BINARY" : ""), esc_userid) )
+ {
+ Sql_ShowDebug(sql_handle);
+ return false;
+ }
+
+ if( Sql_NumRows(sql_handle) > 1 )
+ {// serious problem - duplicit account
+ ShowError("account_db_sql_load_str: multiple accounts found when retrieving data for account '%s'!\n", userid);
+ Sql_FreeResult(sql_handle);
+ return false;
+ }
+
+ if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
+ {// no such entry
+ Sql_FreeResult(sql_handle);
+ return false;
+ }
+
+ Sql_GetData(sql_handle, 0, &data, NULL);
+ account_id = atoi(data);
+
+ return account_db_sql_load_num(self, acc, account_id);
}
/// Returns a new forward iterator.
-static AccountDBIterator *account_db_sql_iterator(AccountDB *self)
+static AccountDBIterator* account_db_sql_iterator(AccountDB* self)
{
- AccountDB_SQL *db = (AccountDB_SQL *)self;
- AccountDBIterator_SQL *iter = (AccountDBIterator_SQL *)aCalloc(1, sizeof(AccountDBIterator_SQL));
+ AccountDB_SQL* db = (AccountDB_SQL*)self;
+ AccountDBIterator_SQL* iter = (AccountDBIterator_SQL*)aCalloc(1, sizeof(AccountDBIterator_SQL));
- // set up the vtable
- iter->vtable.destroy = &account_db_sql_iter_destroy;
- iter->vtable.next = &account_db_sql_iter_next;
+ // set up the vtable
+ iter->vtable.destroy = &account_db_sql_iter_destroy;
+ iter->vtable.next = &account_db_sql_iter_next;
- // fill data
- iter->db = db;
- iter->last_account_id = -1;
+ // fill data
+ iter->db = db;
+ iter->last_account_id = -1;
- return &iter->vtable;
+ return &iter->vtable;
}
/// Destroys this iterator, releasing all allocated memory (including itself).
-static void account_db_sql_iter_destroy(AccountDBIterator *self)
+static void account_db_sql_iter_destroy(AccountDBIterator* self)
{
- AccountDBIterator_SQL *iter = (AccountDBIterator_SQL *)self;
- aFree(iter);
+ AccountDBIterator_SQL* iter = (AccountDBIterator_SQL*)self;
+ aFree(iter);
}
/// Fetches the next account in the database.
-static bool account_db_sql_iter_next(AccountDBIterator *self, struct mmo_account *acc)
+static bool account_db_sql_iter_next(AccountDBIterator* self, struct mmo_account* acc)
{
- AccountDBIterator_SQL *iter = (AccountDBIterator_SQL *)self;
- AccountDB_SQL *db = (AccountDB_SQL *)iter->db;
- Sql *sql_handle = db->accounts;
- int account_id;
- char *data;
-
- // get next account ID
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id` FROM `%s` WHERE `account_id` > '%d' ORDER BY `account_id` ASC LIMIT 1",
- db->account_db, iter->last_account_id)) {
- Sql_ShowDebug(sql_handle);
- return false;
- }
-
- if (SQL_SUCCESS == Sql_NextRow(sql_handle) &&
- SQL_SUCCESS == Sql_GetData(sql_handle, 0, &data, NULL) &&
- data != NULL) {
- // get account data
- account_id = atoi(data);
- if (mmo_auth_fromsql(db, acc, account_id)) {
- iter->last_account_id = account_id;
- Sql_FreeResult(sql_handle);
- return true;
- }
- }
- Sql_FreeResult(sql_handle);
- return false;
+ AccountDBIterator_SQL* iter = (AccountDBIterator_SQL*)self;
+ AccountDB_SQL* db = (AccountDB_SQL*)iter->db;
+ Sql* sql_handle = db->accounts;
+ int account_id;
+ char* data;
+
+ // get next account ID
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id` FROM `%s` WHERE `account_id` > '%d' ORDER BY `account_id` ASC LIMIT 1",
+ db->account_db, iter->last_account_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ return false;
+ }
+
+ if( SQL_SUCCESS == Sql_NextRow(sql_handle) &&
+ SQL_SUCCESS == Sql_GetData(sql_handle, 0, &data, NULL) &&
+ data != NULL )
+ {// get account data
+ account_id = atoi(data);
+ if( mmo_auth_fromsql(db, acc, account_id) )
+ {
+ iter->last_account_id = account_id;
+ Sql_FreeResult(sql_handle);
+ return true;
+ }
+ }
+ Sql_FreeResult(sql_handle);
+ return false;
}
-static bool mmo_auth_fromsql(AccountDB_SQL *db, struct mmo_account *acc, int account_id)
+static bool mmo_auth_fromsql(AccountDB_SQL* db, struct mmo_account* acc, int account_id)
{
- Sql *sql_handle = db->accounts;
- char *data;
- int i = 0;
-
- // retrieve login entry for the specified account
- if (SQL_ERROR == Sql_Query(sql_handle,
- "SELECT `account_id`,`userid`,`user_pass`,`sex`,`email`,`group_id`,`state`,`unban_time`,`expiration_time`,`logincount`,`lastlogin`,`last_ip`,`birthdate` FROM `%s` WHERE `account_id` = %d",
- db->account_db, account_id)
- ) {
- Sql_ShowDebug(sql_handle);
- return false;
- }
-
- if (SQL_SUCCESS != Sql_NextRow(sql_handle)) {
- // no such entry
- Sql_FreeResult(sql_handle);
- return false;
- }
-
- Sql_GetData(sql_handle, 0, &data, NULL);
- acc->account_id = atoi(data);
- Sql_GetData(sql_handle, 1, &data, NULL);
- safestrncpy(acc->userid, data, sizeof(acc->userid));
- Sql_GetData(sql_handle, 2, &data, NULL);
- safestrncpy(acc->pass, data, sizeof(acc->pass));
- Sql_GetData(sql_handle, 3, &data, NULL);
- acc->sex = data[0];
- Sql_GetData(sql_handle, 4, &data, NULL);
- safestrncpy(acc->email, data, sizeof(acc->email));
- Sql_GetData(sql_handle, 5, &data, NULL);
- acc->group_id = atoi(data);
- Sql_GetData(sql_handle, 6, &data, NULL);
- acc->state = strtoul(data, NULL, 10);
- Sql_GetData(sql_handle, 7, &data, NULL);
- acc->unban_time = atol(data);
- Sql_GetData(sql_handle, 8, &data, NULL);
- acc->expiration_time = atol(data);
- Sql_GetData(sql_handle, 9, &data, NULL);
- acc->logincount = strtoul(data, NULL, 10);
- Sql_GetData(sql_handle, 10, &data, NULL);
- safestrncpy(acc->lastlogin, data, sizeof(acc->lastlogin));
- Sql_GetData(sql_handle, 11, &data, NULL);
- safestrncpy(acc->last_ip, data, sizeof(acc->last_ip));
- Sql_GetData(sql_handle, 12, &data, NULL);
- safestrncpy(acc->birthdate, data, sizeof(acc->birthdate));
-
- Sql_FreeResult(sql_handle);
-
-
- // retrieve account regs for the specified user
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `str`,`value` FROM `%s` WHERE `type`='1' AND `account_id`='%d'", db->accreg_db, acc->account_id)) {
- Sql_ShowDebug(sql_handle);
- return false;
- }
-
- acc->account_reg2_num = (int)Sql_NumRows(sql_handle);
-
- while (SQL_SUCCESS == Sql_NextRow(sql_handle)) {
- char *data;
- Sql_GetData(sql_handle, 0, &data, NULL);
- safestrncpy(acc->account_reg2[i].str, data, sizeof(acc->account_reg2[i].str));
- Sql_GetData(sql_handle, 1, &data, NULL);
- safestrncpy(acc->account_reg2[i].value, data, sizeof(acc->account_reg2[i].value));
- ++i;
- }
- Sql_FreeResult(sql_handle);
-
- if (i != acc->account_reg2_num)
- return false;
-
- return true;
+ Sql* sql_handle = db->accounts;
+ char* data;
+ int i = 0;
+
+ // retrieve login entry for the specified account
+ if( SQL_ERROR == Sql_Query(sql_handle,
+ "SELECT `account_id`,`userid`,`user_pass`,`sex`,`email`,`group_id`,`state`,`unban_time`,`expiration_time`,`logincount`,`lastlogin`,`last_ip`,`birthdate` FROM `%s` WHERE `account_id` = %d",
+ db->account_db, account_id )
+ ) {
+ Sql_ShowDebug(sql_handle);
+ return false;
+ }
+
+ if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
+ {// no such entry
+ Sql_FreeResult(sql_handle);
+ return false;
+ }
+
+ Sql_GetData(sql_handle, 0, &data, NULL); acc->account_id = atoi(data);
+ Sql_GetData(sql_handle, 1, &data, NULL); safestrncpy(acc->userid, data, sizeof(acc->userid));
+ Sql_GetData(sql_handle, 2, &data, NULL); safestrncpy(acc->pass, data, sizeof(acc->pass));
+ Sql_GetData(sql_handle, 3, &data, NULL); acc->sex = data[0];
+ Sql_GetData(sql_handle, 4, &data, NULL); safestrncpy(acc->email, data, sizeof(acc->email));
+ Sql_GetData(sql_handle, 5, &data, NULL); acc->group_id = atoi(data);
+ Sql_GetData(sql_handle, 6, &data, NULL); acc->state = strtoul(data, NULL, 10);
+ Sql_GetData(sql_handle, 7, &data, NULL); acc->unban_time = atol(data);
+ Sql_GetData(sql_handle, 8, &data, NULL); acc->expiration_time = atol(data);
+ Sql_GetData(sql_handle, 9, &data, NULL); acc->logincount = strtoul(data, NULL, 10);
+ Sql_GetData(sql_handle, 10, &data, NULL); safestrncpy(acc->lastlogin, data, sizeof(acc->lastlogin));
+ Sql_GetData(sql_handle, 11, &data, NULL); safestrncpy(acc->last_ip, data, sizeof(acc->last_ip));
+ Sql_GetData(sql_handle, 12, &data, NULL); safestrncpy(acc->birthdate, data, sizeof(acc->birthdate));
+
+ Sql_FreeResult(sql_handle);
+
+
+ // retrieve account regs for the specified user
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `str`,`value` FROM `%s` WHERE `type`='1' AND `account_id`='%d'", db->accreg_db, acc->account_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ return false;
+ }
+
+ acc->account_reg2_num = (int)Sql_NumRows(sql_handle);
+
+ while( SQL_SUCCESS == Sql_NextRow(sql_handle) )
+ {
+ char* data;
+ Sql_GetData(sql_handle, 0, &data, NULL); safestrncpy(acc->account_reg2[i].str, data, sizeof(acc->account_reg2[i].str));
+ Sql_GetData(sql_handle, 1, &data, NULL); safestrncpy(acc->account_reg2[i].value, data, sizeof(acc->account_reg2[i].value));
+ ++i;
+ }
+ Sql_FreeResult(sql_handle);
+
+ if( i != acc->account_reg2_num )
+ return false;
+
+ return true;
}
-static bool mmo_auth_tosql(AccountDB_SQL *db, const struct mmo_account *acc, bool is_new)
+static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, bool is_new)
{
- Sql *sql_handle = db->accounts;
- SqlStmt *stmt = SqlStmt_Malloc(sql_handle);
- bool result = false;
- int i;
-
- // try
- do {
-
- if (SQL_SUCCESS != Sql_QueryStr(sql_handle, "START TRANSACTION")) {
- Sql_ShowDebug(sql_handle);
- break;
- }
-
- if (is_new) {
- // insert into account table
- if (SQL_SUCCESS != SqlStmt_Prepare(stmt,
- "INSERT INTO `%s` (`account_id`, `userid`, `user_pass`, `sex`, `email`, `group_id`, `state`, `unban_time`, `expiration_time`, `logincount`, `lastlogin`, `last_ip`, `birthdate`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
- db->account_db)
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_INT, (void *)&acc->account_id, sizeof(acc->account_id))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (void *)acc->userid, strlen(acc->userid))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 2, SQLDT_STRING, (void *)acc->pass, strlen(acc->pass))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 3, SQLDT_ENUM, (void *)&acc->sex, sizeof(acc->sex))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 4, SQLDT_STRING, (void *)&acc->email, strlen(acc->email))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 5, SQLDT_INT, (void *)&acc->group_id, sizeof(acc->group_id))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 6, SQLDT_UINT, (void *)&acc->state, sizeof(acc->state))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 7, SQLDT_LONG, (void *)&acc->unban_time, sizeof(acc->unban_time))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 8, SQLDT_INT, (void *)&acc->expiration_time, sizeof(acc->expiration_time))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 9, SQLDT_UINT, (void *)&acc->logincount, sizeof(acc->logincount))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 10, SQLDT_STRING, (void *)&acc->lastlogin, strlen(acc->lastlogin))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 11, SQLDT_STRING, (void *)&acc->last_ip, strlen(acc->last_ip))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 12, SQLDT_STRING, (void *)&acc->birthdate, strlen(acc->birthdate))
- || SQL_SUCCESS != SqlStmt_Execute(stmt)
- ) {
- SqlStmt_ShowDebug(stmt);
- break;
- }
- } else {
- // update account table
- if (SQL_SUCCESS != SqlStmt_Prepare(stmt, "UPDATE `%s` SET `userid`=?,`user_pass`=?,`sex`=?,`email`=?,`group_id`=?,`state`=?,`unban_time`=?,`expiration_time`=?,`logincount`=?,`lastlogin`=?,`last_ip`=?,`birthdate`=? WHERE `account_id` = '%d'", db->account_db, acc->account_id)
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, (void *)acc->userid, strlen(acc->userid))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (void *)acc->pass, strlen(acc->pass))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 2, SQLDT_ENUM, (void *)&acc->sex, sizeof(acc->sex))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 3, SQLDT_STRING, (void *)acc->email, strlen(acc->email))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 4, SQLDT_INT, (void *)&acc->group_id, sizeof(acc->group_id))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 5, SQLDT_UINT, (void *)&acc->state, sizeof(acc->state))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 6, SQLDT_LONG, (void *)&acc->unban_time, sizeof(acc->unban_time))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 7, SQLDT_LONG, (void *)&acc->expiration_time, sizeof(acc->expiration_time))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 8, SQLDT_UINT, (void *)&acc->logincount, sizeof(acc->logincount))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 9, SQLDT_STRING, (void *)&acc->lastlogin, strlen(acc->lastlogin))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 10, SQLDT_STRING, (void *)&acc->last_ip, strlen(acc->last_ip))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 11, SQLDT_STRING, (void *)&acc->birthdate, strlen(acc->birthdate))
- || SQL_SUCCESS != SqlStmt_Execute(stmt)
- ) {
- SqlStmt_ShowDebug(stmt);
- break;
- }
- }
-
- // remove old account regs
- if (SQL_SUCCESS != Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `type`='1' AND `account_id`='%d'", db->accreg_db, acc->account_id)) {
- Sql_ShowDebug(sql_handle);
- break;
- }
- // insert new account regs
- if (SQL_SUCCESS != SqlStmt_Prepare(stmt, "INSERT INTO `%s` (`type`, `account_id`, `str`, `value`) VALUES ( 1 , '%d' , ? , ? );", db->accreg_db, acc->account_id)) {
- SqlStmt_ShowDebug(stmt);
- break;
- }
- for (i = 0; i < acc->account_reg2_num; ++i) {
- if (SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, (void *)acc->account_reg2[i].str, strlen(acc->account_reg2[i].str))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (void *)acc->account_reg2[i].value, strlen(acc->account_reg2[i].value))
- || SQL_SUCCESS != SqlStmt_Execute(stmt)
- ) {
- SqlStmt_ShowDebug(stmt);
- break;
- }
- }
- if (i < acc->account_reg2_num) {
- result = false;
- break;
- }
-
- // if we got this far, everything was successful
- result = true;
-
- } while (0);
- // finally
-
- result &= (SQL_SUCCESS == Sql_QueryStr(sql_handle, (result == true) ? "COMMIT" : "ROLLBACK"));
- SqlStmt_Free(stmt);
-
- return result;
+ Sql* sql_handle = db->accounts;
+ SqlStmt* stmt = SqlStmt_Malloc(sql_handle);
+ bool result = false;
+ int i;
+
+ // try
+ do
+ {
+
+ if( SQL_SUCCESS != Sql_QueryStr(sql_handle, "START TRANSACTION") )
+ {
+ Sql_ShowDebug(sql_handle);
+ break;
+ }
+
+ if( is_new )
+ {// insert into account table
+ if( SQL_SUCCESS != SqlStmt_Prepare(stmt,
+ "INSERT INTO `%s` (`account_id`, `userid`, `user_pass`, `sex`, `email`, `group_id`, `state`, `unban_time`, `expiration_time`, `logincount`, `lastlogin`, `last_ip`, `birthdate`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+ db->account_db)
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_INT, (void*)&acc->account_id, sizeof(acc->account_id))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (void*)acc->userid, strlen(acc->userid))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 2, SQLDT_STRING, (void*)acc->pass, strlen(acc->pass))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 3, SQLDT_ENUM, (void*)&acc->sex, sizeof(acc->sex))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 4, SQLDT_STRING, (void*)&acc->email, strlen(acc->email))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 5, SQLDT_INT, (void*)&acc->group_id, sizeof(acc->group_id))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 6, SQLDT_UINT, (void*)&acc->state, sizeof(acc->state))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 7, SQLDT_LONG, (void*)&acc->unban_time, sizeof(acc->unban_time))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 8, SQLDT_INT, (void*)&acc->expiration_time, sizeof(acc->expiration_time))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 9, SQLDT_UINT, (void*)&acc->logincount, sizeof(acc->logincount))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 10, SQLDT_STRING, (void*)&acc->lastlogin, strlen(acc->lastlogin))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 11, SQLDT_STRING, (void*)&acc->last_ip, strlen(acc->last_ip))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 12, SQLDT_STRING, (void*)&acc->birthdate, strlen(acc->birthdate))
+ || SQL_SUCCESS != SqlStmt_Execute(stmt)
+ ) {
+ SqlStmt_ShowDebug(stmt);
+ break;
+ }
+ }
+ else
+ {// update account table
+ if( SQL_SUCCESS != SqlStmt_Prepare(stmt, "UPDATE `%s` SET `userid`=?,`user_pass`=?,`sex`=?,`email`=?,`group_id`=?,`state`=?,`unban_time`=?,`expiration_time`=?,`logincount`=?,`lastlogin`=?,`last_ip`=?,`birthdate`=? WHERE `account_id` = '%d'", db->account_db, acc->account_id)
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, (void*)acc->userid, strlen(acc->userid))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (void*)acc->pass, strlen(acc->pass))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 2, SQLDT_ENUM, (void*)&acc->sex, sizeof(acc->sex))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 3, SQLDT_STRING, (void*)acc->email, strlen(acc->email))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 4, SQLDT_INT, (void*)&acc->group_id, sizeof(acc->group_id))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 5, SQLDT_UINT, (void*)&acc->state, sizeof(acc->state))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 6, SQLDT_LONG, (void*)&acc->unban_time, sizeof(acc->unban_time))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 7, SQLDT_LONG, (void*)&acc->expiration_time, sizeof(acc->expiration_time))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 8, SQLDT_UINT, (void*)&acc->logincount, sizeof(acc->logincount))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 9, SQLDT_STRING, (void*)&acc->lastlogin, strlen(acc->lastlogin))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 10, SQLDT_STRING, (void*)&acc->last_ip, strlen(acc->last_ip))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 11, SQLDT_STRING, (void*)&acc->birthdate, strlen(acc->birthdate))
+ || SQL_SUCCESS != SqlStmt_Execute(stmt)
+ ) {
+ SqlStmt_ShowDebug(stmt);
+ break;
+ }
+ }
+
+ // remove old account regs
+ if( SQL_SUCCESS != Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `type`='1' AND `account_id`='%d'", db->accreg_db, acc->account_id) )
+ {
+ Sql_ShowDebug(sql_handle);
+ break;
+ }
+ // insert new account regs
+ if( SQL_SUCCESS != SqlStmt_Prepare(stmt, "INSERT INTO `%s` (`type`, `account_id`, `str`, `value`) VALUES ( 1 , '%d' , ? , ? );", db->accreg_db, acc->account_id) )
+ {
+ SqlStmt_ShowDebug(stmt);
+ break;
+ }
+ for( i = 0; i < acc->account_reg2_num; ++i )
+ {
+ if( SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, (void*)acc->account_reg2[i].str, strlen(acc->account_reg2[i].str))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (void*)acc->account_reg2[i].value, strlen(acc->account_reg2[i].value))
+ || SQL_SUCCESS != SqlStmt_Execute(stmt)
+ ) {
+ SqlStmt_ShowDebug(stmt);
+ break;
+ }
+ }
+ if( i < acc->account_reg2_num )
+ {
+ result = false;
+ break;
+ }
+
+ // if we got this far, everything was successful
+ result = true;
+
+ } while(0);
+ // finally
+
+ result &= ( SQL_SUCCESS == Sql_QueryStr(sql_handle, (result == true) ? "COMMIT" : "ROLLBACK") );
+ SqlStmt_Free(stmt);
+
+ return result;
}
diff --git a/src/login/ipban.h b/src/login/ipban.h
index 6adc40483..b2a1a7d9e 100644
--- a/src/login/ipban.h
+++ b/src/login/ipban.h
@@ -19,7 +19,7 @@ bool ipban_check(uint32 ip);
void ipban_log(uint32 ip);
// parses configuration option
-bool ipban_config_read(const char *key, const char *value);
+bool ipban_config_read(const char* key, const char* value);
#endif // __IPBAN_H_INCLUDED__
diff --git a/src/login/ipban_sql.c b/src/login/ipban_sql.c
index eec9a98be..c75a1f956 100644
--- a/src/login/ipban_sql.c
+++ b/src/login/ipban_sql.c
@@ -31,7 +31,7 @@ static char ipban_codepage[32] = "";
static char ipban_table[32] = "ipbanlist";
// globals
-static Sql *sql_handle = NULL;
+static Sql* sql_handle = NULL;
static int cleanup_timer_id = INVALID_TIMER;
static bool ipban_inited = false;
@@ -41,196 +41,218 @@ int ipban_cleanup(int tid, unsigned int tick, int id, intptr_t data);
// initialize
void ipban_init(void)
{
- const char *username;
- const char *password;
- const char *hostname;
- uint16 port;
- const char *database;
- const char *codepage;
-
- ipban_inited = true;
-
- if (!login_config.ipban)
- return;// ipban disabled
-
- if (ipban_db_hostname[0] != '\0') {
- // local settings
- username = ipban_db_username;
- password = ipban_db_password;
- hostname = ipban_db_hostname;
- port = ipban_db_port;
- database = ipban_db_database;
- codepage = ipban_codepage;
- } else {
- // global settings
- username = global_db_username;
- password = global_db_password;
- hostname = global_db_hostname;
- port = global_db_port;
- database = global_db_database;
- codepage = global_codepage;
- }
-
- // establish connections
- sql_handle = Sql_Malloc();
- if (SQL_ERROR == Sql_Connect(sql_handle, username, password, hostname, port, database)) {
- Sql_ShowDebug(sql_handle);
- Sql_Free(sql_handle);
- exit(EXIT_FAILURE);
- }
- if (codepage[0] != '\0' && SQL_ERROR == Sql_SetEncoding(sql_handle, codepage))
- Sql_ShowDebug(sql_handle);
-
- if (login_config.ipban_cleanup_interval > 0) {
- // set up periodic cleanup of connection history and active bans
- add_timer_func_list(ipban_cleanup, "ipban_cleanup");
- cleanup_timer_id = add_timer_interval(gettick()+10, ipban_cleanup, 0, 0, login_config.ipban_cleanup_interval*1000);
- } else // make sure it gets cleaned up on login-server start regardless of interval-based cleanups
- ipban_cleanup(0,0,0,0);
+ const char* username;
+ const char* password;
+ const char* hostname;
+ uint16 port;
+ const char* database;
+ const char* codepage;
+
+ ipban_inited = true;
+
+ if( !login_config.ipban )
+ return;// ipban disabled
+
+ if( ipban_db_hostname[0] != '\0' )
+ {// local settings
+ username = ipban_db_username;
+ password = ipban_db_password;
+ hostname = ipban_db_hostname;
+ port = ipban_db_port;
+ database = ipban_db_database;
+ codepage = ipban_codepage;
+ }
+ else
+ {// global settings
+ username = global_db_username;
+ password = global_db_password;
+ hostname = global_db_hostname;
+ port = global_db_port;
+ database = global_db_database;
+ codepage = global_codepage;
+ }
+
+ // establish connections
+ sql_handle = Sql_Malloc();
+ if( SQL_ERROR == Sql_Connect(sql_handle, username, password, hostname, port, database) )
+ {
+ Sql_ShowDebug(sql_handle);
+ Sql_Free(sql_handle);
+ exit(EXIT_FAILURE);
+ }
+ if( codepage[0] != '\0' && SQL_ERROR == Sql_SetEncoding(sql_handle, codepage) )
+ Sql_ShowDebug(sql_handle);
+
+ if( login_config.ipban_cleanup_interval > 0 )
+ { // set up periodic cleanup of connection history and active bans
+ add_timer_func_list(ipban_cleanup, "ipban_cleanup");
+ cleanup_timer_id = add_timer_interval(gettick()+10, ipban_cleanup, 0, 0, login_config.ipban_cleanup_interval*1000);
+ } else // make sure it gets cleaned up on login-server start regardless of interval-based cleanups
+ ipban_cleanup(0,0,0,0);
}
// finalize
void ipban_final(void)
{
- if (!login_config.ipban)
- return;// ipban disabled
-
- if (login_config.ipban_cleanup_interval > 0)
- // release data
- delete_timer(cleanup_timer_id, ipban_cleanup);
-
- ipban_cleanup(0,0,0,0); // always clean up on login-server stop
-
- // close connections
- Sql_Free(sql_handle);
- sql_handle = NULL;
+ if( !login_config.ipban )
+ return;// ipban disabled
+
+ if( login_config.ipban_cleanup_interval > 0 )
+ // release data
+ delete_timer(cleanup_timer_id, ipban_cleanup);
+
+ ipban_cleanup(0,0,0,0); // always clean up on login-server stop
+
+ // close connections
+ Sql_Free(sql_handle);
+ sql_handle = NULL;
}
// load configuration options
-bool ipban_config_read(const char *key, const char *value)
+bool ipban_config_read(const char* key, const char* value)
{
- const char *signature;
-
- if (ipban_inited)
- return false;// settings can only be changed before init
-
- signature = "sql.";
- if (strncmpi(key, signature, strlen(signature)) == 0) {
- key += strlen(signature);
- if (strcmpi(key, "db_hostname") == 0)
- safestrncpy(global_db_hostname, value, sizeof(global_db_hostname));
- else if (strcmpi(key, "db_port") == 0)
- global_db_port = (uint16)strtoul(value, NULL, 10);
- else if (strcmpi(key, "db_username") == 0)
- safestrncpy(global_db_username, value, sizeof(global_db_username));
- else if (strcmpi(key, "db_password") == 0)
- safestrncpy(global_db_password, value, sizeof(global_db_password));
- else if (strcmpi(key, "db_database") == 0)
- safestrncpy(global_db_database, value, sizeof(global_db_database));
- else if (strcmpi(key, "codepage") == 0)
- safestrncpy(global_codepage, value, sizeof(global_codepage));
- else
- return false;// not found
- return true;
- }
-
- signature = "ipban.sql.";
- if (strncmpi(key, signature, strlen(signature)) == 0) {
- key += strlen(signature);
- if (strcmpi(key, "db_hostname") == 0)
- safestrncpy(ipban_db_hostname, value, sizeof(ipban_db_hostname));
- else if (strcmpi(key, "db_port") == 0)
- ipban_db_port = (uint16)strtoul(value, NULL, 10);
- else if (strcmpi(key, "db_username") == 0)
- safestrncpy(ipban_db_username, value, sizeof(ipban_db_username));
- else if (strcmpi(key, "db_password") == 0)
- safestrncpy(ipban_db_password, value, sizeof(ipban_db_password));
- else if (strcmpi(key, "db_database") == 0)
- safestrncpy(ipban_db_database, value, sizeof(ipban_db_database));
- else if (strcmpi(key, "codepage") == 0)
- safestrncpy(ipban_codepage, value, sizeof(ipban_codepage));
- else if (strcmpi(key, "ipban_table") == 0)
- safestrncpy(ipban_table, value, sizeof(ipban_table));
- else
- return false;// not found
- return true;
- }
-
- signature = "ipban.";
- if (strncmpi(key, signature, strlen(signature)) == 0) {
- key += strlen(signature);
- if (strcmpi(key, "enable") == 0)
- login_config.ipban = (bool)config_switch(value);
- else if (strcmpi(key, "dynamic_pass_failure_ban") == 0)
- login_config.dynamic_pass_failure_ban = (bool)config_switch(value);
- else if (strcmpi(key, "dynamic_pass_failure_ban_interval") == 0)
- login_config.dynamic_pass_failure_ban_interval = atoi(value);
- else if (strcmpi(key, "dynamic_pass_failure_ban_limit") == 0)
- login_config.dynamic_pass_failure_ban_limit = atoi(value);
- else if (strcmpi(key, "dynamic_pass_failure_ban_duration") == 0)
- login_config.dynamic_pass_failure_ban_duration = atoi(value);
- else
- return false;// not found
- return true;
- }
-
- return false;// not found
+ const char* signature;
+
+ if( ipban_inited )
+ return false;// settings can only be changed before init
+
+ signature = "sql.";
+ if( strncmpi(key, signature, strlen(signature)) == 0 )
+ {
+ key += strlen(signature);
+ if( strcmpi(key, "db_hostname") == 0 )
+ safestrncpy(global_db_hostname, value, sizeof(global_db_hostname));
+ else
+ if( strcmpi(key, "db_port") == 0 )
+ global_db_port = (uint16)strtoul(value, NULL, 10);
+ else
+ if( strcmpi(key, "db_username") == 0 )
+ safestrncpy(global_db_username, value, sizeof(global_db_username));
+ else
+ if( strcmpi(key, "db_password") == 0 )
+ safestrncpy(global_db_password, value, sizeof(global_db_password));
+ else
+ if( strcmpi(key, "db_database") == 0 )
+ safestrncpy(global_db_database, value, sizeof(global_db_database));
+ else
+ if( strcmpi(key, "codepage") == 0 )
+ safestrncpy(global_codepage, value, sizeof(global_codepage));
+ else
+ return false;// not found
+ return true;
+ }
+
+ signature = "ipban.sql.";
+ if( strncmpi(key, signature, strlen(signature)) == 0 )
+ {
+ key += strlen(signature);
+ if( strcmpi(key, "db_hostname") == 0 )
+ safestrncpy(ipban_db_hostname, value, sizeof(ipban_db_hostname));
+ else
+ if( strcmpi(key, "db_port") == 0 )
+ ipban_db_port = (uint16)strtoul(value, NULL, 10);
+ else
+ if( strcmpi(key, "db_username") == 0 )
+ safestrncpy(ipban_db_username, value, sizeof(ipban_db_username));
+ else
+ if( strcmpi(key, "db_password") == 0 )
+ safestrncpy(ipban_db_password, value, sizeof(ipban_db_password));
+ else
+ if( strcmpi(key, "db_database") == 0 )
+ safestrncpy(ipban_db_database, value, sizeof(ipban_db_database));
+ else
+ if( strcmpi(key, "codepage") == 0 )
+ safestrncpy(ipban_codepage, value, sizeof(ipban_codepage));
+ else
+ if( strcmpi(key, "ipban_table") == 0 )
+ safestrncpy(ipban_table, value, sizeof(ipban_table));
+ else
+ return false;// not found
+ return true;
+ }
+
+ signature = "ipban.";
+ if( strncmpi(key, signature, strlen(signature)) == 0 )
+ {
+ key += strlen(signature);
+ if( strcmpi(key, "enable") == 0 )
+ login_config.ipban = (bool)config_switch(value);
+ else
+ if( strcmpi(key, "dynamic_pass_failure_ban") == 0 )
+ login_config.dynamic_pass_failure_ban = (bool)config_switch(value);
+ else
+ if( strcmpi(key, "dynamic_pass_failure_ban_interval") == 0 )
+ login_config.dynamic_pass_failure_ban_interval = atoi(value);
+ else
+ if( strcmpi(key, "dynamic_pass_failure_ban_limit") == 0 )
+ login_config.dynamic_pass_failure_ban_limit = atoi(value);
+ else
+ if( strcmpi(key, "dynamic_pass_failure_ban_duration") == 0 )
+ login_config.dynamic_pass_failure_ban_duration = atoi(value);
+ else
+ return false;// not found
+ return true;
+ }
+
+ return false;// not found
}
// check ip against active bans list
bool ipban_check(uint32 ip)
{
- uint8 *p = (uint8 *)&ip;
- char *data = NULL;
- int matches;
+ uint8* p = (uint8*)&ip;
+ char* data = NULL;
+ int matches;
- if (!login_config.ipban)
- return false;// ipban disabled
+ if( !login_config.ipban )
+ return false;// ipban disabled
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT count(*) FROM `%s` WHERE `rtime` > NOW() AND (`list` = '%u.*.*.*' OR `list` = '%u.%u.*.*' OR `list` = '%u.%u.%u.*' OR `list` = '%u.%u.%u.%u')",
- ipban_table, p[3], p[3], p[2], p[3], p[2], p[1], p[3], p[2], p[1], p[0])) {
- Sql_ShowDebug(sql_handle);
- // close connection because we can't verify their connectivity.
- return true;
- }
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT count(*) FROM `%s` WHERE `rtime` > NOW() AND (`list` = '%u.*.*.*' OR `list` = '%u.%u.*.*' OR `list` = '%u.%u.%u.*' OR `list` = '%u.%u.%u.%u')",
+ ipban_table, p[3], p[3], p[2], p[3], p[2], p[1], p[3], p[2], p[1], p[0]) )
+ {
+ Sql_ShowDebug(sql_handle);
+ // close connection because we can't verify their connectivity.
+ return true;
+ }
- if (SQL_ERROR == Sql_NextRow(sql_handle))
- return true;// Shouldn't happen, but just in case...
+ if( SQL_ERROR == Sql_NextRow(sql_handle) )
+ return true;// Shouldn't happen, but just in case...
- Sql_GetData(sql_handle, 0, &data, NULL);
- matches = atoi(data);
- Sql_FreeResult(sql_handle);
+ Sql_GetData(sql_handle, 0, &data, NULL);
+ matches = atoi(data);
+ Sql_FreeResult(sql_handle);
- return(matches > 0);
+ return( matches > 0 );
}
// log failed attempt
void ipban_log(uint32 ip)
{
- unsigned long failures;
+ unsigned long failures;
- if (!login_config.ipban)
- return;// ipban disabled
+ if( !login_config.ipban )
+ return;// ipban disabled
- failures = loginlog_failedattempts(ip, login_config.dynamic_pass_failure_ban_interval);// how many times failed account? in one ip.
+ failures = loginlog_failedattempts(ip, login_config.dynamic_pass_failure_ban_interval);// how many times failed account? in one ip.
- // if over the limit, add a temporary ban entry
- if (failures >= login_config.dynamic_pass_failure_ban_limit) {
- uint8 *p = (uint8 *)&ip;
- if (SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s`(`list`,`btime`,`rtime`,`reason`) VALUES ('%u.%u.%u.*', NOW() , NOW() + INTERVAL %d MINUTE ,'Password error ban')",
- ipban_table, p[3], p[2], p[1], login_config.dynamic_pass_failure_ban_duration))
- Sql_ShowDebug(sql_handle);
- }
+ // if over the limit, add a temporary ban entry
+ if( failures >= login_config.dynamic_pass_failure_ban_limit )
+ {
+ uint8* p = (uint8*)&ip;
+ if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s`(`list`,`btime`,`rtime`,`reason`) VALUES ('%u.%u.%u.*', NOW() , NOW() + INTERVAL %d MINUTE ,'Password error ban')",
+ ipban_table, p[3], p[2], p[1], login_config.dynamic_pass_failure_ban_duration) )
+ Sql_ShowDebug(sql_handle);
+ }
}
// remove expired bans
int ipban_cleanup(int tid, unsigned int tick, int id, intptr_t data)
{
- if (!login_config.ipban)
- return 0;// ipban disabled
+ if( !login_config.ipban )
+ return 0;// ipban disabled
- if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `ipbanlist` WHERE `rtime` <= NOW()"))
- Sql_ShowDebug(sql_handle);
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `ipbanlist` WHERE `rtime` <= NOW()") )
+ Sql_ShowDebug(sql_handle);
- return 0;
+ return 0;
}
diff --git a/src/login/login.c b/src/login/login.c
index 1f63463d5..e079dbaf2 100644
--- a/src/login/login.c
+++ b/src/login/login.c
@@ -25,31 +25,31 @@ int login_fd; // login server socket
struct mmo_char_server server[MAX_SERVERS]; // char server data
// Account engines available
-static struct {
- AccountDB *(*constructor)(void);
- AccountDB *db;
+static struct{
+ AccountDB* (*constructor)(void);
+ AccountDB* db;
} account_engines[] = {
- {account_db_sql, NULL},
+ {account_db_sql, NULL},
#ifdef ACCOUNTDB_ENGINE_0
- {ACCOUNTDB_CONSTRUCTOR(ACCOUNTDB_ENGINE_0), NULL},
+ {ACCOUNTDB_CONSTRUCTOR(ACCOUNTDB_ENGINE_0), NULL},
#endif
#ifdef ACCOUNTDB_ENGINE_1
- {ACCOUNTDB_CONSTRUCTOR(ACCOUNTDB_ENGINE_1), NULL},
+ {ACCOUNTDB_CONSTRUCTOR(ACCOUNTDB_ENGINE_1), NULL},
#endif
#ifdef ACCOUNTDB_ENGINE_2
- {ACCOUNTDB_CONSTRUCTOR(ACCOUNTDB_ENGINE_2), NULL},
+ {ACCOUNTDB_CONSTRUCTOR(ACCOUNTDB_ENGINE_2), NULL},
#endif
#ifdef ACCOUNTDB_ENGINE_3
- {ACCOUNTDB_CONSTRUCTOR(ACCOUNTDB_ENGINE_3), NULL},
+ {ACCOUNTDB_CONSTRUCTOR(ACCOUNTDB_ENGINE_3), NULL},
#endif
#ifdef ACCOUNTDB_ENGINE_4
- {ACCOUNTDB_CONSTRUCTOR(ACCOUNTDB_ENGINE_4), NULL},
+ {ACCOUNTDB_CONSTRUCTOR(ACCOUNTDB_ENGINE_4), NULL},
#endif
- // end of structure
- {NULL, NULL}
+ // end of structure
+ {NULL, NULL}
};
// account database
-AccountDB *accounts = NULL;
+AccountDB* accounts = NULL;
//Account registration flood protection [Kevin]
int allowed_regs = 1;
@@ -57,14 +57,14 @@ int time_allowed = 10; //in seconds
// Advanced subnet check [LuzZza]
struct s_subnet {
- uint32 mask;
- uint32 char_ip;
- uint32 map_ip;
+ uint32 mask;
+ uint32 char_ip;
+ uint32 map_ip;
} subnet[16];
int subnet_count = 0;
-int mmo_auth_new(const char *userid, const char *pass, const char sex, const char *last_ip);
+int mmo_auth_new(const char* userid, const char* pass, const char sex, const char* last_ip);
//-----------------------------------------------------
// Auth database
@@ -73,16 +73,16 @@ int mmo_auth_new(const char *userid, const char *pass, const char sex, const cha
struct auth_node {
- int account_id;
- uint32 login_id1;
- uint32 login_id2;
- uint32 ip;
- char sex;
- uint32 version;
- uint8 clienttype;
+ int account_id;
+ uint32 login_id1;
+ uint32 login_id2;
+ uint32 ip;
+ char sex;
+ uint32 version;
+ uint8 clienttype;
};
-static DBMap *auth_db; // int account_id -> struct auth_node*
+static DBMap* auth_db; // int account_id -> struct auth_node*
//-----------------------------------------------------
@@ -90,12 +90,12 @@ static DBMap *auth_db; // int account_id -> struct auth_node*
//-----------------------------------------------------
struct online_login_data {
- int account_id;
- int waiting_disconnect;
- int char_server;
+ int account_id;
+ int waiting_disconnect;
+ int char_server;
};
-static DBMap *online_db; // int account_id -> struct online_login_data*
+static DBMap* online_db; // int account_id -> struct online_login_data*
static int waiting_disconnect_timer(int tid, unsigned int tick, int id, intptr_t data);
/**
@@ -103,46 +103,49 @@ static int waiting_disconnect_timer(int tid, unsigned int tick, int id, intptr_t
*/
static DBData create_online_user(DBKey key, va_list args)
{
- struct online_login_data *p;
- CREATE(p, struct online_login_data, 1);
- p->account_id = key.i;
- p->char_server = -1;
- p->waiting_disconnect = INVALID_TIMER;
- return db_ptr2data(p);
+ struct online_login_data* p;
+ CREATE(p, struct online_login_data, 1);
+ p->account_id = key.i;
+ p->char_server = -1;
+ p->waiting_disconnect = INVALID_TIMER;
+ return db_ptr2data(p);
}
-struct online_login_data *add_online_user(int char_server, int account_id) {
- struct online_login_data *p;
- p = idb_ensure(online_db, account_id, create_online_user);
- p->char_server = char_server;
- if (p->waiting_disconnect != INVALID_TIMER) {
- delete_timer(p->waiting_disconnect, waiting_disconnect_timer);
- p->waiting_disconnect = INVALID_TIMER;
- }
- return p;
+struct online_login_data* add_online_user(int char_server, int account_id)
+{
+ struct online_login_data* p;
+ p = idb_ensure(online_db, account_id, create_online_user);
+ p->char_server = char_server;
+ if( p->waiting_disconnect != INVALID_TIMER )
+ {
+ delete_timer(p->waiting_disconnect, waiting_disconnect_timer);
+ p->waiting_disconnect = INVALID_TIMER;
+ }
+ return p;
}
void remove_online_user(int account_id)
{
- struct online_login_data *p;
- p = (struct online_login_data *)idb_get(online_db, account_id);
- if (p == NULL)
- return;
- if (p->waiting_disconnect != INVALID_TIMER)
- delete_timer(p->waiting_disconnect, waiting_disconnect_timer);
-
- idb_remove(online_db, account_id);
+ struct online_login_data* p;
+ p = (struct online_login_data*)idb_get(online_db, account_id);
+ if( p == NULL )
+ return;
+ if( p->waiting_disconnect != INVALID_TIMER )
+ delete_timer(p->waiting_disconnect, waiting_disconnect_timer);
+
+ idb_remove(online_db, account_id);
}
static int waiting_disconnect_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- struct online_login_data *p = (struct online_login_data *)idb_get(online_db, id);
- if (p != NULL && p->waiting_disconnect == tid && p->account_id == id) {
- p->waiting_disconnect = INVALID_TIMER;
- remove_online_user(id);
- idb_remove(auth_db, id);
- }
- return 0;
+ struct online_login_data* p = (struct online_login_data*)idb_get(online_db, id);
+ if( p != NULL && p->waiting_disconnect == tid && p->account_id == id )
+ {
+ p->waiting_disconnect = INVALID_TIMER;
+ remove_online_user(id);
+ idb_remove(auth_db, id);
+ }
+ return 0;
}
/**
@@ -150,17 +153,20 @@ static int waiting_disconnect_timer(int tid, unsigned int tick, int id, intptr_t
*/
static int online_db_setoffline(DBKey key, DBData *data, va_list ap)
{
- struct online_login_data *p = db_data2ptr(data);
- int server = va_arg(ap, int);
- if (server == -1) {
- p->char_server = -1;
- if (p->waiting_disconnect != INVALID_TIMER) {
- delete_timer(p->waiting_disconnect, waiting_disconnect_timer);
- p->waiting_disconnect = INVALID_TIMER;
- }
- } else if (p->char_server == server)
- p->char_server = -2; //Char server disconnected.
- return 0;
+ struct online_login_data* p = db_data2ptr(data);
+ int server = va_arg(ap, int);
+ if( server == -1 )
+ {
+ p->char_server = -1;
+ if( p->waiting_disconnect != INVALID_TIMER )
+ {
+ delete_timer(p->waiting_disconnect, waiting_disconnect_timer);
+ p->waiting_disconnect = INVALID_TIMER;
+ }
+ }
+ else if( p->char_server == server )
+ p->char_server = -2; //Char server disconnected.
+ return 0;
}
/**
@@ -168,72 +174,75 @@ static int online_db_setoffline(DBKey key, DBData *data, va_list ap)
*/
static int online_data_cleanup_sub(DBKey key, DBData *data, va_list ap)
{
- struct online_login_data *character= db_data2ptr(data);
- if (character->char_server == -2) //Unknown server.. set them offline
- remove_online_user(character->account_id);
- return 0;
+ struct online_login_data *character= db_data2ptr(data);
+ if (character->char_server == -2) //Unknown server.. set them offline
+ remove_online_user(character->account_id);
+ return 0;
}
static int online_data_cleanup(int tid, unsigned int tick, int id, intptr_t data)
{
- online_db->foreach(online_db, online_data_cleanup_sub);
- return 0;
-}
+ online_db->foreach(online_db, online_data_cleanup_sub);
+ return 0;
+}
//--------------------------------------------------------------------
// Packet send to all char-servers, except one (wos: without our self)
//--------------------------------------------------------------------
-int charif_sendallwos(int sfd, uint8 *buf, size_t len)
+int charif_sendallwos(int sfd, uint8* buf, size_t len)
{
- int i, c;
-
- for (i = 0, c = 0; i < ARRAYLENGTH(server); ++i) {
- int fd = server[i].fd;
- if (session_isValid(fd) && fd != sfd) {
- WFIFOHEAD(fd,len);
- memcpy(WFIFOP(fd,0), buf, len);
- WFIFOSET(fd,len);
- ++c;
- }
- }
-
- return c;
+ int i, c;
+
+ for( i = 0, c = 0; i < ARRAYLENGTH(server); ++i )
+ {
+ int fd = server[i].fd;
+ if( session_isValid(fd) && fd != sfd )
+ {
+ WFIFOHEAD(fd,len);
+ memcpy(WFIFOP(fd,0), buf, len);
+ WFIFOSET(fd,len);
+ ++c;
+ }
+ }
+
+ return c;
}
/// Initializes a server structure.
void chrif_server_init(int id)
{
- memset(&server[id], 0, sizeof(server[id]));
- server[id].fd = -1;
+ memset(&server[id], 0, sizeof(server[id]));
+ server[id].fd = -1;
}
/// Destroys a server structure.
void chrif_server_destroy(int id)
{
- if (server[id].fd != -1) {
- do_close(server[id].fd);
- server[id].fd = -1;
- }
+ if( server[id].fd != -1 )
+ {
+ do_close(server[id].fd);
+ server[id].fd = -1;
+ }
}
/// Resets all the data related to a server.
void chrif_server_reset(int id)
{
- online_db->foreach(online_db, online_db_setoffline, id); //Set all chars from this char server to offline.
- chrif_server_destroy(id);
- chrif_server_init(id);
+ online_db->foreach(online_db, online_db_setoffline, id); //Set all chars from this char server to offline.
+ chrif_server_destroy(id);
+ chrif_server_init(id);
}
/// Called when the connection to Char Server is disconnected.
void chrif_on_disconnect(int id)
{
- ShowStatus("Char-server '%s' has disconnected.\n", server[id].name);
- chrif_server_reset(id);
+ ShowStatus("Char-server '%s' has disconnected.\n", server[id].name);
+ chrif_server_reset(id);
}
@@ -242,49 +251,52 @@ void chrif_on_disconnect(int id)
//-----------------------------------------------------
static int sync_ip_addresses(int tid, unsigned int tick, int id, intptr_t data)
{
- uint8 buf[2];
- ShowInfo("IP Sync in progress...\n");
- WBUFW(buf,0) = 0x2735;
- charif_sendallwos(-1, buf, 2);
- return 0;
+ uint8 buf[2];
+ ShowInfo("IP Sync in progress...\n");
+ WBUFW(buf,0) = 0x2735;
+ charif_sendallwos(-1, buf, 2);
+ return 0;
}
//-----------------------------------------------------
// encrypted/unencrypted password check (from eApp)
//-----------------------------------------------------
-bool check_encrypted(const char *str1, const char *str2, const char *passwd)
+bool check_encrypted(const char* str1, const char* str2, const char* passwd)
{
- char tmpstr[64+1], md5str[32+1];
+ char tmpstr[64+1], md5str[32+1];
- safesnprintf(tmpstr, sizeof(tmpstr), "%s%s", str1, str2);
- MD5_String(tmpstr, md5str);
+ safesnprintf(tmpstr, sizeof(tmpstr), "%s%s", str1, str2);
+ MD5_String(tmpstr, md5str);
- return (0==strcmp(passwd, md5str));
+ return (0==strcmp(passwd, md5str));
}
-bool check_password(const char *md5key, int passwdenc, const char *passwd, const char *refpass)
+bool check_password(const char* md5key, int passwdenc, const char* passwd, const char* refpass)
{
- if (passwdenc == 0) {
- return (0==strcmp(passwd, refpass));
- } else {
- // password mode set to 1 -> md5(md5key, refpass) enable with <passwordencrypt></passwordencrypt>
- // password mode set to 2 -> md5(refpass, md5key) enable with <passwordencrypt2></passwordencrypt2>
-
- return ((passwdenc&0x01) && check_encrypted(md5key, refpass, passwd)) ||
- ((passwdenc&0x02) && check_encrypted(refpass, md5key, passwd));
- }
+ if(passwdenc == 0)
+ {
+ return (0==strcmp(passwd, refpass));
+ }
+ else
+ {
+ // password mode set to 1 -> md5(md5key, refpass) enable with <passwordencrypt></passwordencrypt>
+ // password mode set to 2 -> md5(refpass, md5key) enable with <passwordencrypt2></passwordencrypt2>
+
+ return ((passwdenc&0x01) && check_encrypted(md5key, refpass, passwd)) ||
+ ((passwdenc&0x02) && check_encrypted(refpass, md5key, passwd));
+ }
}
//-----------------------------------------------------
// custom timestamp formatting (from eApp)
//-----------------------------------------------------
-const char *timestamp2string(char *str, size_t size, time_t timestamp, const char *format)
+const char* timestamp2string(char* str, size_t size, time_t timestamp, const char* format)
{
- size_t len = strftime(str, size, format, localtime(&timestamp));
- memset(str + len, '\0', size - len);
- return str;
+ size_t len = strftime(str, size, format, localtime(&timestamp));
+ memset(str + len, '\0', size - len);
+ return str;
}
@@ -293,9 +305,9 @@ const char *timestamp2string(char *str, size_t size, time_t timestamp, const cha
//--------------------------------------------
int lan_subnetcheck(uint32 ip)
{
- int i;
- ARR_FIND(0, subnet_count, i, (subnet[i].char_ip & subnet[i].mask) == (ip & subnet[i].mask));
- return (i < subnet_count) ? subnet[i].char_ip : 0;
+ int i;
+ ARR_FIND( 0, subnet_count, i, (subnet[i].char_ip & subnet[i].mask) == (ip & subnet[i].mask) );
+ return ( i < subnet_count ) ? subnet[i].char_ip : 0;
}
//----------------------------------
@@ -303,89 +315,99 @@ int lan_subnetcheck(uint32 ip)
//----------------------------------
int login_lan_config_read(const char *lancfgName)
{
- FILE *fp;
- int line_num = 0;
- char line[1024], w1[64], w2[64], w3[64], w4[64];
-
- if ((fp = fopen(lancfgName, "r")) == NULL) {
- ShowWarning("LAN Support configuration file is not found: %s\n", lancfgName);
- return 1;
- }
-
- while (fgets(line, sizeof(line), fp)) {
- line_num++;
- if ((line[0] == '/' && line[1] == '/') || line[0] == '\n' || line[1] == '\n')
- continue;
-
- if (sscanf(line,"%[^:]: %[^:]:%[^:]:%[^\r\n]", w1, w2, w3, w4) != 4) {
- ShowWarning("Error syntax of configuration file %s in line %d.\n", lancfgName, line_num);
- continue;
- }
-
- if (strcmpi(w1, "subnet") == 0) {
- subnet[subnet_count].mask = str2ip(w2);
- subnet[subnet_count].char_ip = str2ip(w3);
- subnet[subnet_count].map_ip = str2ip(w4);
-
- if ((subnet[subnet_count].char_ip & subnet[subnet_count].mask) != (subnet[subnet_count].map_ip & subnet[subnet_count].mask)) {
- ShowError("%s: Configuration Error: The char server (%s) and map server (%s) belong to different subnetworks!\n", lancfgName, w3, w4);
- continue;
- }
-
- subnet_count++;
- }
- }
-
- if (subnet_count > 1) /* only useful if there is more than 1 available */
- ShowStatus("Read information about %d subnetworks.\n", subnet_count);
-
- fclose(fp);
- return 0;
+ FILE *fp;
+ int line_num = 0;
+ char line[1024], w1[64], w2[64], w3[64], w4[64];
+
+ if((fp = fopen(lancfgName, "r")) == NULL) {
+ ShowWarning("LAN Support configuration file is not found: %s\n", lancfgName);
+ return 1;
+ }
+
+ while(fgets(line, sizeof(line), fp))
+ {
+ line_num++;
+ if ((line[0] == '/' && line[1] == '/') || line[0] == '\n' || line[1] == '\n')
+ continue;
+
+ if(sscanf(line,"%[^:]: %[^:]:%[^:]:%[^\r\n]", w1, w2, w3, w4) != 4)
+ {
+ ShowWarning("Error syntax of configuration file %s in line %d.\n", lancfgName, line_num);
+ continue;
+ }
+
+ if( strcmpi(w1, "subnet") == 0 )
+ {
+ subnet[subnet_count].mask = str2ip(w2);
+ subnet[subnet_count].char_ip = str2ip(w3);
+ subnet[subnet_count].map_ip = str2ip(w4);
+
+ if( (subnet[subnet_count].char_ip & subnet[subnet_count].mask) != (subnet[subnet_count].map_ip & subnet[subnet_count].mask) )
+ {
+ ShowError("%s: Configuration Error: The char server (%s) and map server (%s) belong to different subnetworks!\n", lancfgName, w3, w4);
+ continue;
+ }
+
+ subnet_count++;
+ }
+ }
+
+ if( subnet_count > 1 ) /* only useful if there is more than 1 available */
+ ShowStatus("Read information about %d subnetworks.\n", subnet_count);
+
+ fclose(fp);
+ return 0;
}
//-----------------------
// Console Command Parser [Wizputer]
//-----------------------
-int parse_console(const char *command)
+int parse_console(const char* command)
{
- ShowNotice("Console command: %s\n", command);
-
- if (strcmpi("shutdown", command) == 0 || strcmpi("exit", command) == 0 || strcmpi("quit", command) == 0 || strcmpi("end", command) == 0)
- runflag = 0;
- else if (strcmpi("alive", command) == 0 || strcmpi("status", command) == 0)
- ShowInfo(CL_CYAN"Console: "CL_BOLD"I'm Alive."CL_RESET"\n");
- else if (strcmpi("help", command) == 0) {
- ShowInfo("To shutdown the server:\n");
- ShowInfo(" 'shutdown|exit|quit|end'\n");
- ShowInfo("To know if server is alive:\n");
- ShowInfo(" 'alive|status'\n");
- ShowInfo("To create a new account:\n");
- ShowInfo(" 'create'\n");
- } else {
- // commands with parameters
- char cmd[128], params[256];
-
- if (sscanf(command, "%127s %255[^\r\n]", cmd, params) < 2) {
- return 0;
- }
-
- if (strcmpi(cmd, "create") == 0) {
- char username[NAME_LENGTH], password[NAME_LENGTH], sex;
-
- if (sscanf(params, "%23s %23s %c", username, password, &sex) < 3 || strnlen(username, sizeof(username)) < 4 || strnlen(password, sizeof(password)) < 1) {
- ShowWarning("Console: Invalid parameters for '%s'. Usage: %s <username> <password> <sex:F/M>\n", cmd, cmd);
- return 0;
- }
-
- if (mmo_auth_new(username, password, TOUPPER(sex), "0.0.0.0") != -1) {
- ShowError("Console: Account creation failed.\n");
- return 0;
- }
- ShowStatus("Console: Account '%s' created successfully.\n", username);
- }
- }
-
- return 0;
+ ShowNotice("Console command: %s\n", command);
+
+ if( strcmpi("shutdown", command) == 0 || strcmpi("exit", command) == 0 || strcmpi("quit", command) == 0 || strcmpi("end", command) == 0 )
+ runflag = 0;
+ else if( strcmpi("alive", command) == 0 || strcmpi("status", command) == 0 )
+ ShowInfo(CL_CYAN"Console: "CL_BOLD"I'm Alive."CL_RESET"\n");
+ else if( strcmpi("help", command) == 0 )
+ {
+ ShowInfo("To shutdown the server:\n");
+ ShowInfo(" 'shutdown|exit|quit|end'\n");
+ ShowInfo("To know if server is alive:\n");
+ ShowInfo(" 'alive|status'\n");
+ ShowInfo("To create a new account:\n");
+ ShowInfo(" 'create'\n");
+ }
+ else
+ {// commands with parameters
+ char cmd[128], params[256];
+
+ if( sscanf(command, "%127s %255[^\r\n]", cmd, params) < 2 )
+ {
+ return 0;
+ }
+
+ if( strcmpi(cmd, "create") == 0 )
+ {
+ char username[NAME_LENGTH], password[NAME_LENGTH], sex;
+
+ if( sscanf(params, "%23s %23s %c", username, password, &sex) < 3 || strnlen(username, sizeof(username)) < 4 || strnlen(password, sizeof(password)) < 1 )
+ {
+ ShowWarning("Console: Invalid parameters for '%s'. Usage: %s <username> <password> <sex:F/M>\n", cmd, cmd);
+ return 0;
+ }
+
+ if( mmo_auth_new(username, password, TOUPPER(sex), "0.0.0.0") != -1 )
+ {
+ ShowError("Console: Account creation failed.\n");
+ return 0;
+ }
+ ShowStatus("Console: Account '%s' created successfully.\n", username);
+ }
+ }
+
+ return 0;
}
@@ -394,898 +416,880 @@ int parse_console(const char *command)
//--------------------------------
int parse_fromchar(int fd)
{
- int j, id;
- uint32 ipl;
- char ip[16];
-
- ARR_FIND(0, ARRAYLENGTH(server), id, server[id].fd == fd);
- if (id == ARRAYLENGTH(server)) {
- // not a char server
- ShowDebug("parse_fromchar: Disconnecting invalid session #%d (is not a char-server)\n", fd);
- set_eof(fd);
- do_close(fd);
- return 0;
- }
-
- if (session[fd]->flag.eof) {
- do_close(fd);
- server[id].fd = -1;
- chrif_on_disconnect(id);
- return 0;
- }
-
- ipl = server[id].ip;
- ip2str(ipl, ip);
-
- while (RFIFOREST(fd) >= 2) {
- uint16 command = RFIFOW(fd,0);
-
- switch (command) {
-
- case 0x2712: // request from char-server to authenticate an account
- if (RFIFOREST(fd) < 23)
- return 0;
- {
- struct auth_node *node;
-
- int account_id = RFIFOL(fd,2);
- uint32 login_id1 = RFIFOL(fd,6);
- uint32 login_id2 = RFIFOL(fd,10);
- uint8 sex = RFIFOB(fd,14);
- //uint32 ip_ = ntohl(RFIFOL(fd,15));
- int request_id = RFIFOL(fd,19);
- RFIFOSKIP(fd,23);
-
- node = (struct auth_node *)idb_get(auth_db, account_id);
- if (runflag == LOGINSERVER_ST_RUNNING &&
- node != NULL &&
- node->account_id == account_id &&
- node->login_id1 == login_id1 &&
- node->login_id2 == login_id2 &&
- node->sex == sex_num2str(sex) /*&&
- node->ip == ip_*/) {
- // found
- //ShowStatus("Char-server '%s': authentication of the account %d accepted (ip: %s).\n", server[id].name, account_id, ip);
-
- // send ack
- WFIFOHEAD(fd,25);
- WFIFOW(fd,0) = 0x2713;
- WFIFOL(fd,2) = account_id;
- WFIFOL(fd,6) = login_id1;
- WFIFOL(fd,10) = login_id2;
- WFIFOB(fd,14) = sex;
- WFIFOB(fd,15) = 0;// ok
- WFIFOL(fd,16) = request_id;
- WFIFOL(fd,20) = node->version;
- WFIFOB(fd,24) = node->clienttype;
- WFIFOSET(fd,25);
-
- // each auth entry can only be used once
- idb_remove(auth_db, account_id);
- } else {
- // authentication not found
- ShowStatus("Char-server '%s': authentication of the account %d REFUSED (ip: %s).\n", server[id].name, account_id, ip);
- WFIFOHEAD(fd,25);
- WFIFOW(fd,0) = 0x2713;
- WFIFOL(fd,2) = account_id;
- WFIFOL(fd,6) = login_id1;
- WFIFOL(fd,10) = login_id2;
- WFIFOB(fd,14) = sex;
- WFIFOB(fd,15) = 1;// auth failed
- WFIFOL(fd,16) = request_id;
- WFIFOL(fd,20) = 0;
- WFIFOB(fd,24) = 0;
- WFIFOSET(fd,25);
- }
- }
- break;
-
- case 0x2714:
- if (RFIFOREST(fd) < 6)
- return 0;
- {
- int users = RFIFOL(fd,2);
- RFIFOSKIP(fd,6);
-
- // how many users on world? (update)
- if (server[id].users != users) {
- ShowStatus("set users %s : %d\n", server[id].name, users);
-
- server[id].users = users;
- }
- }
- break;
-
- case 0x2715: // request from char server to change e-email from default "a@a.com"
- if (RFIFOREST(fd) < 46)
- return 0;
- {
- struct mmo_account acc;
- char email[40];
-
- int account_id = RFIFOL(fd,2);
- safestrncpy(email, (char *)RFIFOP(fd,6), 40);
- remove_control_chars(email);
- RFIFOSKIP(fd,46);
-
- if (e_mail_check(email) == 0)
- ShowNotice("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)\n", server[id].name, account_id, ip);
- else if (!accounts->load_num(accounts, &acc, account_id) || strcmp(acc.email, "a@a.com") == 0 || acc.email[0] == '\0')
- ShowNotice("Char-server '%s': Attempt to create an e-mail on an account with a default e-mail REFUSED - account doesn't exist or e-mail of account isn't default e-mail (account: %d, ip: %s).\n", server[id].name, account_id, ip);
- else {
- memcpy(acc.email, email, 40);
- ShowNotice("Char-server '%s': Create an e-mail on an account with a default e-mail (account: %d, new e-mail: %s, ip: %s).\n", server[id].name, account_id, email, ip);
- // Save
- accounts->save(accounts, &acc);
- }
- }
- break;
-
- case 0x2716: // request account data
- if (RFIFOREST(fd) < 6)
- return 0;
- {
- struct mmo_account acc;
- time_t expiration_time = 0;
- char email[40] = "";
- int group_id = 0;
- char birthdate[10+1] = "";
-
- int account_id = RFIFOL(fd,2);
- RFIFOSKIP(fd,6);
-
- if (!accounts->load_num(accounts, &acc, account_id))
- ShowNotice("Char-server '%s': account %d NOT found (ip: %s).\n", server[id].name, account_id, ip);
- else {
- safestrncpy(email, acc.email, sizeof(email));
- expiration_time = acc.expiration_time;
- group_id = acc.group_id;
- safestrncpy(birthdate, acc.birthdate, sizeof(birthdate));
- }
-
- WFIFOHEAD(fd,62);
- WFIFOW(fd,0) = 0x2717;
- WFIFOL(fd,2) = account_id;
- safestrncpy((char *)WFIFOP(fd,6), email, 40);
- WFIFOL(fd,46) = (uint32)expiration_time;
- WFIFOB(fd,50) = group_id;
- safestrncpy((char *)WFIFOP(fd,51), birthdate, 10+1);
- WFIFOSET(fd,62);
- }
- break;
-
- case 0x2719: // ping request from charserver
- RFIFOSKIP(fd,2);
-
- WFIFOHEAD(fd,2);
- WFIFOW(fd,0) = 0x2718;
- WFIFOSET(fd,2);
- break;
-
- // 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;
- {
- struct mmo_account acc;
- char actual_email[40];
- char new_email[40];
-
- int account_id = RFIFOL(fd,2);
- safestrncpy(actual_email, (char *)RFIFOP(fd,6), 40);
- safestrncpy(new_email, (char *)RFIFOP(fd,46), 40);
- RFIFOSKIP(fd, 86);
-
- if (e_mail_check(actual_email) == 0)
- ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual email is invalid (account: %d, ip: %s)\n", server[id].name, account_id, ip);
- else if (e_mail_check(new_email) == 0)
- ShowNotice("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)\n", server[id].name, account_id, ip);
- else if (strcmpi(new_email, "a@a.com") == 0)
- ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a default e-mail (account: %d, ip: %s)\n", server[id].name, account_id, ip);
- else if (!accounts->load_num(accounts, &acc, account_id))
- ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but account doesn't exist (account: %d, ip: %s).\n", server[id].name, account_id, ip);
- else if (strcmpi(acc.email, actual_email) != 0)
- ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual e-mail is incorrect (account: %d (%s), actual e-mail: %s, proposed e-mail: %s, ip: %s).\n", server[id].name, account_id, acc.userid, acc.email, actual_email, ip);
- else {
- safestrncpy(acc.email, new_email, 40);
- ShowNotice("Char-server '%s': Modify an e-mail on an account (@email GM command) (account: %d (%s), new e-mail: %s, ip: %s).\n", server[id].name, account_id, acc.userid, new_email, ip);
- // Save
- accounts->save(accounts, &acc);
- }
- }
- break;
-
- case 0x2724: // Receiving an account state update request from a map-server (relayed via char-server)
- if (RFIFOREST(fd) < 10)
- return 0;
- {
- struct mmo_account acc;
-
- int account_id = RFIFOL(fd,2);
- unsigned int state = RFIFOL(fd,6);
- RFIFOSKIP(fd,10);
-
- if (!accounts->load_num(accounts, &acc, account_id))
- ShowNotice("Char-server '%s': Error of Status change (account: %d not found, suggested status %d, ip: %s).\n", server[id].name, account_id, state, ip);
- else if (acc.state == state)
- ShowNotice("Char-server '%s': Error of Status change - actual status is already the good status (account: %d, status %d, ip: %s).\n", server[id].name, account_id, state, ip);
- else {
- ShowNotice("Char-server '%s': Status change (account: %d, new status %d, ip: %s).\n", server[id].name, account_id, state, ip);
-
- acc.state = state;
- // Save
- accounts->save(accounts, &acc);
-
- // notify other servers
- if (state != 0) {
- uint8 buf[11];
- WBUFW(buf,0) = 0x2731;
- WBUFL(buf,2) = account_id;
- WBUFB(buf,6) = 0; // 0: change of state, 1: ban
- WBUFL(buf,7) = state; // status or final date of a banishment
- charif_sendallwos(-1, buf, 11);
- }
- }
- }
- break;
-
- case 0x2725: // Receiving of map-server via char-server a ban request
- if (RFIFOREST(fd) < 18)
- return 0;
- {
- struct mmo_account acc;
-
- int account_id = RFIFOL(fd,2);
- int year = (short)RFIFOW(fd,6);
- int month = (short)RFIFOW(fd,8);
- int mday = (short)RFIFOW(fd,10);
- int hour = (short)RFIFOW(fd,12);
- int min = (short)RFIFOW(fd,14);
- int sec = (short)RFIFOW(fd,16);
- RFIFOSKIP(fd,18);
-
- if (!accounts->load_num(accounts, &acc, account_id))
- ShowNotice("Char-server '%s': Error of ban request (account: %d not found, ip: %s).\n", server[id].name, account_id, ip);
- else {
- time_t timestamp;
- struct tm *tmtime;
- if (acc.unban_time == 0 || acc.unban_time < time(NULL))
- timestamp = time(NULL); // new ban
- else
- timestamp = acc.unban_time; // add to existing ban
- tmtime = localtime(&timestamp);
- tmtime->tm_year = tmtime->tm_year + year;
- tmtime->tm_mon = tmtime->tm_mon + month;
- tmtime->tm_mday = tmtime->tm_mday + mday;
- tmtime->tm_hour = tmtime->tm_hour + hour;
- tmtime->tm_min = tmtime->tm_min + min;
- tmtime->tm_sec = tmtime->tm_sec + sec;
- timestamp = mktime(tmtime);
- if (timestamp == -1)
- ShowNotice("Char-server '%s': Error of ban request (account: %d, invalid date, ip: %s).\n", server[id].name, account_id, ip);
- else if (timestamp <= time(NULL) || timestamp == 0)
- ShowNotice("Char-server '%s': Error of ban request (account: %d, new date unbans the account, ip: %s).\n", server[id].name, account_id, ip);
- else {
- uint8 buf[11];
- char tmpstr[24];
- timestamp2string(tmpstr, sizeof(tmpstr), timestamp, login_config.date_format);
- ShowNotice("Char-server '%s': Ban request (account: %d, new final date of banishment: %d (%s), ip: %s).\n", server[id].name, account_id, timestamp, tmpstr, ip);
-
- acc.unban_time = timestamp;
-
- // Save
- accounts->save(accounts, &acc);
-
- WBUFW(buf,0) = 0x2731;
- WBUFL(buf,2) = account_id;
- WBUFB(buf,6) = 1; // 0: change of status, 1: ban
- WBUFL(buf,7) = (uint32)timestamp; // status or final date of a banishment
- charif_sendallwos(-1, buf, 11);
- }
- }
- }
- break;
-
- case 0x2727: // Change of sex (sex is reversed)
- if (RFIFOREST(fd) < 6)
- return 0;
- {
- struct mmo_account acc;
-
- int account_id = RFIFOL(fd,2);
- RFIFOSKIP(fd,6);
-
- if (!accounts->load_num(accounts, &acc, account_id))
- ShowNotice("Char-server '%s': Error of sex change (account: %d not found, ip: %s).\n", server[id].name, account_id, ip);
- else if (acc.sex == 'S')
- ShowNotice("Char-server '%s': Error of sex change - account to change is a Server account (account: %d, ip: %s).\n", server[id].name, account_id, ip);
- else {
- unsigned char buf[7];
- char sex = (acc.sex == 'M') ? 'F' : 'M'; //Change gender
-
- ShowNotice("Char-server '%s': Sex change (account: %d, new sex %c, ip: %s).\n", server[id].name, account_id, sex, ip);
-
- acc.sex = sex;
- // Save
- accounts->save(accounts, &acc);
-
- // announce to other servers
- WBUFW(buf,0) = 0x2723;
- WBUFL(buf,2) = account_id;
- WBUFB(buf,6) = sex_str2num(sex);
- charif_sendallwos(-1, buf, 7);
- }
- }
- break;
-
- case 0x2728: // We receive account_reg2 from a char-server, and we send them to other map-servers.
- if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
- return 0;
- {
- struct mmo_account acc;
-
- int account_id = RFIFOL(fd,4);
-
- if (!accounts->load_num(accounts, &acc, account_id))
- ShowStatus("Char-server '%s': receiving (from the char-server) of account_reg2 (account: %d not found, ip: %s).\n", server[id].name, account_id, ip);
- else {
- int len;
- int p;
- ShowNotice("char-server '%s': receiving (from the char-server) of account_reg2 (account: %d, ip: %s).\n", server[id].name, account_id, ip);
- for (j = 0, p = 13; j < ACCOUNT_REG2_NUM && p < RFIFOW(fd,2); ++j) {
- sscanf((char *)RFIFOP(fd,p), "%31c%n", acc.account_reg2[j].str, &len);
- acc.account_reg2[j].str[len]='\0';
- p +=len+1; //+1 to skip the '\0' between strings.
- sscanf((char *)RFIFOP(fd,p), "%255c%n", acc.account_reg2[j].value, &len);
- acc.account_reg2[j].value[len]='\0';
- p +=len+1;
- remove_control_chars(acc.account_reg2[j].str);
- remove_control_chars(acc.account_reg2[j].value);
- }
- acc.account_reg2_num = j;
-
- // Save
- accounts->save(accounts, &acc);
-
- // Sending information towards the other char-servers.
- RFIFOW(fd,0) = 0x2729;// reusing read buffer
- charif_sendallwos(fd, RFIFOP(fd,0), RFIFOW(fd,2));
- }
- RFIFOSKIP(fd,RFIFOW(fd,2));
- }
- break;
-
- case 0x272a: // Receiving of map-server via char-server an unban request
- if (RFIFOREST(fd) < 6)
- return 0;
- {
- struct mmo_account acc;
-
- int account_id = RFIFOL(fd,2);
- RFIFOSKIP(fd,6);
-
- if (!accounts->load_num(accounts, &acc, account_id))
- ShowNotice("Char-server '%s': Error of UnBan request (account: %d not found, ip: %s).\n", server[id].name, account_id, ip);
- else if (acc.unban_time == 0)
- ShowNotice("Char-server '%s': Error of UnBan request (account: %d, no change for unban date, ip: %s).\n", server[id].name, account_id, ip);
- else {
- ShowNotice("Char-server '%s': UnBan request (account: %d, ip: %s).\n", server[id].name, account_id, ip);
- acc.unban_time = 0;
- accounts->save(accounts, &acc);
- }
- }
- break;
-
- case 0x272b: // Set account_id to online [Wizputer]
- if (RFIFOREST(fd) < 6)
- return 0;
- add_online_user(id, 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 0x272d: // Receive list of all online accounts. [Skotlex]
- if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
- return 0;
- {
- struct online_login_data *p;
- int aid;
- uint32 i, users;
- online_db->foreach(online_db, online_db_setoffline, id); //Set all chars from this char-server offline first
- users = RFIFOW(fd,4);
- for (i = 0; i < users; i++) {
- aid = RFIFOL(fd,6+i*4);
- p = idb_ensure(online_db, aid, create_online_user);
- p->char_server = id;
- if (p->waiting_disconnect != INVALID_TIMER) {
- delete_timer(p->waiting_disconnect, waiting_disconnect_timer);
- p->waiting_disconnect = INVALID_TIMER;
- }
- }
- }
- RFIFOSKIP(fd,RFIFOW(fd,2));
- break;
-
- case 0x272e: //Request account_reg2 for a character.
- if (RFIFOREST(fd) < 10)
- return 0;
- {
- struct mmo_account acc;
- size_t off;
-
- int account_id = RFIFOL(fd,2);
- int char_id = RFIFOL(fd,6);
- RFIFOSKIP(fd,10);
-
- WFIFOHEAD(fd,ACCOUNT_REG2_NUM*sizeof(struct global_reg));
- WFIFOW(fd,0) = 0x2729;
- WFIFOL(fd,4) = account_id;
- WFIFOL(fd,8) = char_id;
- WFIFOB(fd,12) = 1; //Type 1 for Account2 registry
-
- off = 13;
- if (accounts->load_num(accounts, &acc, account_id)) {
- for (j = 0; j < acc.account_reg2_num; j++) {
- if (acc.account_reg2[j].str[0] != '\0') {
- off += sprintf((char *)WFIFOP(fd,off), "%s", acc.account_reg2[j].str)+1; //We add 1 to consider the '\0' in place.
- off += sprintf((char *)WFIFOP(fd,off), "%s", acc.account_reg2[j].value)+1;
- }
- }
- }
-
- WFIFOW(fd,2) = (uint16)off;
- WFIFOSET(fd,WFIFOW(fd,2));
- }
- break;
-
- case 0x2736: // WAN IP update from char-server
- if (RFIFOREST(fd) < 6)
- return 0;
- server[id].ip = ntohl(RFIFOL(fd,2));
- ShowInfo("Updated IP of Server #%d to %d.%d.%d.%d.\n",id, CONVIP(server[id].ip));
- RFIFOSKIP(fd,6);
- break;
-
- case 0x2737: //Request to set all offline.
- ShowInfo("Setting accounts from char-server %d offline.\n", id);
- online_db->foreach(online_db, online_db_setoffline, id);
- RFIFOSKIP(fd,2);
- break;
-
- default:
- ShowError("parse_fromchar: Unknown packet 0x%x from a char-server! Disconnecting!\n", command);
- set_eof(fd);
- return 0;
- } // switch
- } // while
-
- return 0;
+ int j, id;
+ uint32 ipl;
+ char ip[16];
+
+ ARR_FIND( 0, ARRAYLENGTH(server), id, server[id].fd == fd );
+ if( id == ARRAYLENGTH(server) )
+ {// not a char server
+ ShowDebug("parse_fromchar: Disconnecting invalid session #%d (is not a char-server)\n", fd);
+ set_eof(fd);
+ do_close(fd);
+ return 0;
+ }
+
+ if( session[fd]->flag.eof )
+ {
+ do_close(fd);
+ server[id].fd = -1;
+ chrif_on_disconnect(id);
+ return 0;
+ }
+
+ ipl = server[id].ip;
+ ip2str(ipl, ip);
+
+ while( RFIFOREST(fd) >= 2 )
+ {
+ uint16 command = RFIFOW(fd,0);
+
+ switch( command )
+ {
+
+ case 0x2712: // request from char-server to authenticate an account
+ if( RFIFOREST(fd) < 23 )
+ return 0;
+ {
+ struct auth_node* node;
+
+ int account_id = RFIFOL(fd,2);
+ uint32 login_id1 = RFIFOL(fd,6);
+ uint32 login_id2 = RFIFOL(fd,10);
+ uint8 sex = RFIFOB(fd,14);
+ //uint32 ip_ = ntohl(RFIFOL(fd,15));
+ int request_id = RFIFOL(fd,19);
+ RFIFOSKIP(fd,23);
+
+ node = (struct auth_node*)idb_get(auth_db, account_id);
+ if( runflag == LOGINSERVER_ST_RUNNING &&
+ node != NULL &&
+ node->account_id == account_id &&
+ node->login_id1 == login_id1 &&
+ node->login_id2 == login_id2 &&
+ node->sex == sex_num2str(sex) /*&&
+ node->ip == ip_*/ )
+ {// found
+ //ShowStatus("Char-server '%s': authentication of the account %d accepted (ip: %s).\n", server[id].name, account_id, ip);
+
+ // send ack
+ WFIFOHEAD(fd,25);
+ WFIFOW(fd,0) = 0x2713;
+ WFIFOL(fd,2) = account_id;
+ WFIFOL(fd,6) = login_id1;
+ WFIFOL(fd,10) = login_id2;
+ WFIFOB(fd,14) = sex;
+ WFIFOB(fd,15) = 0;// ok
+ WFIFOL(fd,16) = request_id;
+ WFIFOL(fd,20) = node->version;
+ WFIFOB(fd,24) = node->clienttype;
+ WFIFOSET(fd,25);
+
+ // each auth entry can only be used once
+ idb_remove(auth_db, account_id);
+ }
+ else
+ {// authentication not found
+ ShowStatus("Char-server '%s': authentication of the account %d REFUSED (ip: %s).\n", server[id].name, account_id, ip);
+ WFIFOHEAD(fd,25);
+ WFIFOW(fd,0) = 0x2713;
+ WFIFOL(fd,2) = account_id;
+ WFIFOL(fd,6) = login_id1;
+ WFIFOL(fd,10) = login_id2;
+ WFIFOB(fd,14) = sex;
+ WFIFOB(fd,15) = 1;// auth failed
+ WFIFOL(fd,16) = request_id;
+ WFIFOL(fd,20) = 0;
+ WFIFOB(fd,24) = 0;
+ WFIFOSET(fd,25);
+ }
+ }
+ break;
+
+ case 0x2714:
+ if( RFIFOREST(fd) < 6 )
+ return 0;
+ {
+ int users = RFIFOL(fd,2);
+ RFIFOSKIP(fd,6);
+
+ // how many users on world? (update)
+ if( server[id].users != users )
+ {
+ ShowStatus("set users %s : %d\n", server[id].name, users);
+
+ server[id].users = users;
+ }
+ }
+ break;
+
+ case 0x2715: // request from char server to change e-email from default "a@a.com"
+ if (RFIFOREST(fd) < 46)
+ return 0;
+ {
+ struct mmo_account acc;
+ char email[40];
+
+ int account_id = RFIFOL(fd,2);
+ safestrncpy(email, (char*)RFIFOP(fd,6), 40); remove_control_chars(email);
+ RFIFOSKIP(fd,46);
+
+ if( e_mail_check(email) == 0 )
+ ShowNotice("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)\n", server[id].name, account_id, ip);
+ else
+ if( !accounts->load_num(accounts, &acc, account_id) || strcmp(acc.email, "a@a.com") == 0 || acc.email[0] == '\0' )
+ ShowNotice("Char-server '%s': Attempt to create an e-mail on an account with a default e-mail REFUSED - account doesn't exist or e-mail of account isn't default e-mail (account: %d, ip: %s).\n", server[id].name, account_id, ip);
+ else {
+ memcpy(acc.email, email, 40);
+ ShowNotice("Char-server '%s': Create an e-mail on an account with a default e-mail (account: %d, new e-mail: %s, ip: %s).\n", server[id].name, account_id, email, ip);
+ // Save
+ accounts->save(accounts, &acc);
+ }
+ }
+ break;
+
+ case 0x2716: // request account data
+ if( RFIFOREST(fd) < 6 )
+ return 0;
+ {
+ struct mmo_account acc;
+ time_t expiration_time = 0;
+ char email[40] = "";
+ int group_id = 0;
+ char birthdate[10+1] = "";
+
+ int account_id = RFIFOL(fd,2);
+ RFIFOSKIP(fd,6);
+
+ if( !accounts->load_num(accounts, &acc, account_id) )
+ ShowNotice("Char-server '%s': account %d NOT found (ip: %s).\n", server[id].name, account_id, ip);
+ else
+ {
+ safestrncpy(email, acc.email, sizeof(email));
+ expiration_time = acc.expiration_time;
+ group_id = acc.group_id;
+ safestrncpy(birthdate, acc.birthdate, sizeof(birthdate));
+ }
+
+ WFIFOHEAD(fd,62);
+ WFIFOW(fd,0) = 0x2717;
+ WFIFOL(fd,2) = account_id;
+ safestrncpy((char*)WFIFOP(fd,6), email, 40);
+ WFIFOL(fd,46) = (uint32)expiration_time;
+ WFIFOB(fd,50) = group_id;
+ safestrncpy((char*)WFIFOP(fd,51), birthdate, 10+1);
+ WFIFOSET(fd,62);
+ }
+ break;
+
+ case 0x2719: // ping request from charserver
+ RFIFOSKIP(fd,2);
+
+ WFIFOHEAD(fd,2);
+ WFIFOW(fd,0) = 0x2718;
+ WFIFOSET(fd,2);
+ break;
+
+ // 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;
+ {
+ struct mmo_account acc;
+ char actual_email[40];
+ char new_email[40];
+
+ int account_id = RFIFOL(fd,2);
+ safestrncpy(actual_email, (char*)RFIFOP(fd,6), 40);
+ safestrncpy(new_email, (char*)RFIFOP(fd,46), 40);
+ RFIFOSKIP(fd, 86);
+
+ if( e_mail_check(actual_email) == 0 )
+ ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual email is invalid (account: %d, ip: %s)\n", server[id].name, account_id, ip);
+ else
+ if( e_mail_check(new_email) == 0 )
+ ShowNotice("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)\n", server[id].name, account_id, ip);
+ else
+ if( strcmpi(new_email, "a@a.com") == 0 )
+ ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a default e-mail (account: %d, ip: %s)\n", server[id].name, account_id, ip);
+ else
+ if( !accounts->load_num(accounts, &acc, account_id) )
+ ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but account doesn't exist (account: %d, ip: %s).\n", server[id].name, account_id, ip);
+ else
+ if( strcmpi(acc.email, actual_email) != 0 )
+ ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual e-mail is incorrect (account: %d (%s), actual e-mail: %s, proposed e-mail: %s, ip: %s).\n", server[id].name, account_id, acc.userid, acc.email, actual_email, ip);
+ else {
+ safestrncpy(acc.email, new_email, 40);
+ ShowNotice("Char-server '%s': Modify an e-mail on an account (@email GM command) (account: %d (%s), new e-mail: %s, ip: %s).\n", server[id].name, account_id, acc.userid, new_email, ip);
+ // Save
+ accounts->save(accounts, &acc);
+ }
+ }
+ break;
+
+ case 0x2724: // Receiving an account state update request from a map-server (relayed via char-server)
+ if (RFIFOREST(fd) < 10)
+ return 0;
+ {
+ struct mmo_account acc;
+
+ int account_id = RFIFOL(fd,2);
+ unsigned int state = RFIFOL(fd,6);
+ RFIFOSKIP(fd,10);
+
+ if( !accounts->load_num(accounts, &acc, account_id) )
+ ShowNotice("Char-server '%s': Error of Status change (account: %d not found, suggested status %d, ip: %s).\n", server[id].name, account_id, state, ip);
+ else
+ if( acc.state == state )
+ ShowNotice("Char-server '%s': Error of Status change - actual status is already the good status (account: %d, status %d, ip: %s).\n", server[id].name, account_id, state, ip);
+ else {
+ ShowNotice("Char-server '%s': Status change (account: %d, new status %d, ip: %s).\n", server[id].name, account_id, state, ip);
+
+ acc.state = state;
+ // Save
+ accounts->save(accounts, &acc);
+
+ // notify other servers
+ if (state != 0) {
+ uint8 buf[11];
+ WBUFW(buf,0) = 0x2731;
+ WBUFL(buf,2) = account_id;
+ WBUFB(buf,6) = 0; // 0: change of state, 1: ban
+ WBUFL(buf,7) = state; // status or final date of a banishment
+ charif_sendallwos(-1, buf, 11);
+ }
+ }
+ }
+ break;
+
+ case 0x2725: // Receiving of map-server via char-server a ban request
+ if (RFIFOREST(fd) < 18)
+ return 0;
+ {
+ struct mmo_account acc;
+
+ int account_id = RFIFOL(fd,2);
+ int year = (short)RFIFOW(fd,6);
+ int month = (short)RFIFOW(fd,8);
+ int mday = (short)RFIFOW(fd,10);
+ int hour = (short)RFIFOW(fd,12);
+ int min = (short)RFIFOW(fd,14);
+ int sec = (short)RFIFOW(fd,16);
+ RFIFOSKIP(fd,18);
+
+ if( !accounts->load_num(accounts, &acc, account_id) )
+ ShowNotice("Char-server '%s': Error of ban request (account: %d not found, ip: %s).\n", server[id].name, account_id, ip);
+ else
+ {
+ time_t timestamp;
+ struct tm *tmtime;
+ if (acc.unban_time == 0 || acc.unban_time < time(NULL))
+ timestamp = time(NULL); // new ban
+ else
+ timestamp = acc.unban_time; // add to existing ban
+ tmtime = localtime(&timestamp);
+ tmtime->tm_year = tmtime->tm_year + year;
+ tmtime->tm_mon = tmtime->tm_mon + month;
+ tmtime->tm_mday = tmtime->tm_mday + mday;
+ tmtime->tm_hour = tmtime->tm_hour + hour;
+ tmtime->tm_min = tmtime->tm_min + min;
+ tmtime->tm_sec = tmtime->tm_sec + sec;
+ timestamp = mktime(tmtime);
+ if (timestamp == -1)
+ ShowNotice("Char-server '%s': Error of ban request (account: %d, invalid date, ip: %s).\n", server[id].name, account_id, ip);
+ else
+ if( timestamp <= time(NULL) || timestamp == 0 )
+ ShowNotice("Char-server '%s': Error of ban request (account: %d, new date unbans the account, ip: %s).\n", server[id].name, account_id, ip);
+ else
+ {
+ uint8 buf[11];
+ char tmpstr[24];
+ timestamp2string(tmpstr, sizeof(tmpstr), timestamp, login_config.date_format);
+ ShowNotice("Char-server '%s': Ban request (account: %d, new final date of banishment: %d (%s), ip: %s).\n", server[id].name, account_id, timestamp, tmpstr, ip);
+
+ acc.unban_time = timestamp;
+
+ // Save
+ accounts->save(accounts, &acc);
+
+ WBUFW(buf,0) = 0x2731;
+ WBUFL(buf,2) = account_id;
+ WBUFB(buf,6) = 1; // 0: change of status, 1: ban
+ WBUFL(buf,7) = (uint32)timestamp; // status or final date of a banishment
+ charif_sendallwos(-1, buf, 11);
+ }
+ }
+ }
+ break;
+
+ case 0x2727: // Change of sex (sex is reversed)
+ if( RFIFOREST(fd) < 6 )
+ return 0;
+ {
+ struct mmo_account acc;
+
+ int account_id = RFIFOL(fd,2);
+ RFIFOSKIP(fd,6);
+
+ if( !accounts->load_num(accounts, &acc, account_id) )
+ ShowNotice("Char-server '%s': Error of sex change (account: %d not found, ip: %s).\n", server[id].name, account_id, ip);
+ else
+ if( acc.sex == 'S' )
+ ShowNotice("Char-server '%s': Error of sex change - account to change is a Server account (account: %d, ip: %s).\n", server[id].name, account_id, ip);
+ else
+ {
+ unsigned char buf[7];
+ char sex = ( acc.sex == 'M' ) ? 'F' : 'M'; //Change gender
+
+ ShowNotice("Char-server '%s': Sex change (account: %d, new sex %c, ip: %s).\n", server[id].name, account_id, sex, ip);
+
+ acc.sex = sex;
+ // Save
+ accounts->save(accounts, &acc);
+
+ // announce to other servers
+ WBUFW(buf,0) = 0x2723;
+ WBUFL(buf,2) = account_id;
+ WBUFB(buf,6) = sex_str2num(sex);
+ charif_sendallwos(-1, buf, 7);
+ }
+ }
+ break;
+
+ case 0x2728: // We receive account_reg2 from a char-server, and we send them to other map-servers.
+ if( RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2) )
+ return 0;
+ {
+ struct mmo_account acc;
+
+ int account_id = RFIFOL(fd,4);
+
+ if( !accounts->load_num(accounts, &acc, account_id) )
+ ShowStatus("Char-server '%s': receiving (from the char-server) of account_reg2 (account: %d not found, ip: %s).\n", server[id].name, account_id, ip);
+ else
+ {
+ int len;
+ int p;
+ ShowNotice("char-server '%s': receiving (from the char-server) of account_reg2 (account: %d, ip: %s).\n", server[id].name, account_id, ip);
+ for( j = 0, p = 13; j < ACCOUNT_REG2_NUM && p < RFIFOW(fd,2); ++j )
+ {
+ sscanf((char*)RFIFOP(fd,p), "%31c%n", acc.account_reg2[j].str, &len);
+ acc.account_reg2[j].str[len]='\0';
+ p +=len+1; //+1 to skip the '\0' between strings.
+ sscanf((char*)RFIFOP(fd,p), "%255c%n", acc.account_reg2[j].value, &len);
+ acc.account_reg2[j].value[len]='\0';
+ p +=len+1;
+ remove_control_chars(acc.account_reg2[j].str);
+ remove_control_chars(acc.account_reg2[j].value);
+ }
+ acc.account_reg2_num = j;
+
+ // Save
+ accounts->save(accounts, &acc);
+
+ // Sending information towards the other char-servers.
+ RFIFOW(fd,0) = 0x2729;// reusing read buffer
+ charif_sendallwos(fd, RFIFOP(fd,0), RFIFOW(fd,2));
+ }
+ RFIFOSKIP(fd,RFIFOW(fd,2));
+ }
+ break;
+
+ case 0x272a: // Receiving of map-server via char-server an unban request
+ if( RFIFOREST(fd) < 6 )
+ return 0;
+ {
+ struct mmo_account acc;
+
+ int account_id = RFIFOL(fd,2);
+ RFIFOSKIP(fd,6);
+
+ if( !accounts->load_num(accounts, &acc, account_id) )
+ ShowNotice("Char-server '%s': Error of UnBan request (account: %d not found, ip: %s).\n", server[id].name, account_id, ip);
+ else
+ if( acc.unban_time == 0 )
+ ShowNotice("Char-server '%s': Error of UnBan request (account: %d, no change for unban date, ip: %s).\n", server[id].name, account_id, ip);
+ else
+ {
+ ShowNotice("Char-server '%s': UnBan request (account: %d, ip: %s).\n", server[id].name, account_id, ip);
+ acc.unban_time = 0;
+ accounts->save(accounts, &acc);
+ }
+ }
+ break;
+
+ case 0x272b: // Set account_id to online [Wizputer]
+ if( RFIFOREST(fd) < 6 )
+ return 0;
+ add_online_user(id, 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 0x272d: // Receive list of all online accounts. [Skotlex]
+ if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
+ return 0;
+ {
+ struct online_login_data *p;
+ int aid;
+ uint32 i, users;
+ online_db->foreach(online_db, online_db_setoffline, id); //Set all chars from this char-server offline first
+ users = RFIFOW(fd,4);
+ for (i = 0; i < users; i++) {
+ aid = RFIFOL(fd,6+i*4);
+ p = idb_ensure(online_db, aid, create_online_user);
+ p->char_server = id;
+ if (p->waiting_disconnect != INVALID_TIMER)
+ {
+ delete_timer(p->waiting_disconnect, waiting_disconnect_timer);
+ p->waiting_disconnect = INVALID_TIMER;
+ }
+ }
+ }
+ RFIFOSKIP(fd,RFIFOW(fd,2));
+ break;
+
+ case 0x272e: //Request account_reg2 for a character.
+ if (RFIFOREST(fd) < 10)
+ return 0;
+ {
+ struct mmo_account acc;
+ size_t off;
+
+ int account_id = RFIFOL(fd,2);
+ int char_id = RFIFOL(fd,6);
+ RFIFOSKIP(fd,10);
+
+ WFIFOHEAD(fd,ACCOUNT_REG2_NUM*sizeof(struct global_reg));
+ WFIFOW(fd,0) = 0x2729;
+ WFIFOL(fd,4) = account_id;
+ WFIFOL(fd,8) = char_id;
+ WFIFOB(fd,12) = 1; //Type 1 for Account2 registry
+
+ off = 13;
+ if( accounts->load_num(accounts, &acc, account_id) )
+ {
+ for( j = 0; j < acc.account_reg2_num; j++ )
+ {
+ if( acc.account_reg2[j].str[0] != '\0' )
+ {
+ off += sprintf((char*)WFIFOP(fd,off), "%s", acc.account_reg2[j].str)+1; //We add 1 to consider the '\0' in place.
+ off += sprintf((char*)WFIFOP(fd,off), "%s", acc.account_reg2[j].value)+1;
+ }
+ }
+ }
+
+ WFIFOW(fd,2) = (uint16)off;
+ WFIFOSET(fd,WFIFOW(fd,2));
+ }
+ break;
+
+ case 0x2736: // WAN IP update from char-server
+ if( RFIFOREST(fd) < 6 )
+ return 0;
+ server[id].ip = ntohl(RFIFOL(fd,2));
+ ShowInfo("Updated IP of Server #%d to %d.%d.%d.%d.\n",id, CONVIP(server[id].ip));
+ RFIFOSKIP(fd,6);
+ break;
+
+ case 0x2737: //Request to set all offline.
+ ShowInfo("Setting accounts from char-server %d offline.\n", id);
+ online_db->foreach(online_db, online_db_setoffline, id);
+ RFIFOSKIP(fd,2);
+ break;
+
+ default:
+ ShowError("parse_fromchar: Unknown packet 0x%x from a char-server! Disconnecting!\n", command);
+ set_eof(fd);
+ return 0;
+ } // switch
+ } // while
+
+ return 0;
}
//-------------------------------------
// Make new account
//-------------------------------------
-int mmo_auth_new(const char *userid, const char *pass, const char sex, const char *last_ip)
-{
- static int num_regs = 0; // registration counter
- static unsigned int new_reg_tick = 0;
- unsigned int tick = gettick();
- struct mmo_account acc;
-
- //Account Registration Flood Protection by [Kevin]
- if (new_reg_tick == 0)
- new_reg_tick = gettick();
- if (DIFF_TICK(tick, new_reg_tick) < 0 && num_regs >= allowed_regs) {
- ShowNotice("Account registration denied (registration limit exceeded)\n");
- return 3;
- }
-
- if (login_config.new_acc_length_limit && (strlen(userid) < 4 || strlen(pass) < 4))
- return 1;
-
- // check for invalid inputs
- if (sex != 'M' && sex != 'F')
- return 0; // 0 = Unregistered ID
-
- // check if the account doesn't exist already
- if (accounts->load_str(accounts, &acc, userid)) {
- ShowNotice("Attempt of creation of an already existant account (account: %s_%c, pass: %s, received pass: %s)\n", userid, sex, acc.pass, pass);
- return 1; // 1 = Incorrect Password
- }
-
- memset(&acc, '\0', sizeof(acc));
- acc.account_id = -1; // assigned by account db
- safestrncpy(acc.userid, userid, sizeof(acc.userid));
- safestrncpy(acc.pass, pass, sizeof(acc.pass));
- acc.sex = sex;
- safestrncpy(acc.email, "a@a.com", sizeof(acc.email));
- acc.expiration_time = (login_config.start_limited_time != -1) ? time(NULL) + login_config.start_limited_time : 0;
- safestrncpy(acc.lastlogin, "0000-00-00 00:00:00", sizeof(acc.lastlogin));
- safestrncpy(acc.last_ip, last_ip, sizeof(acc.last_ip));
- safestrncpy(acc.birthdate, "0000-00-00", sizeof(acc.birthdate));
-
- if (!accounts->create(accounts, &acc))
- return 0;
-
- ShowNotice("Account creation (account %s, id: %d, pass: %s, sex: %c)\n", acc.userid, acc.account_id, acc.pass, acc.sex);
-
- if (DIFF_TICK(tick, new_reg_tick) > 0) { // Update the registration check.
- num_regs = 0;
- new_reg_tick = tick + time_allowed*1000;
- }
- ++num_regs;
-
- return -1;
+int mmo_auth_new(const char* userid, const char* pass, const char sex, const char* last_ip) {
+ static int num_regs = 0; // registration counter
+ static unsigned int new_reg_tick = 0;
+ unsigned int tick = gettick();
+ struct mmo_account acc;
+
+ //Account Registration Flood Protection by [Kevin]
+ if( new_reg_tick == 0 )
+ new_reg_tick = gettick();
+ if( DIFF_TICK(tick, new_reg_tick) < 0 && num_regs >= allowed_regs ) {
+ ShowNotice("Account registration denied (registration limit exceeded)\n");
+ return 3;
+ }
+
+ if( login_config.new_acc_length_limit && ( strlen(userid) < 4 || strlen(pass) < 4 ) )
+ return 1;
+
+ // check for invalid inputs
+ if( sex != 'M' && sex != 'F' )
+ return 0; // 0 = Unregistered ID
+
+ // check if the account doesn't exist already
+ if( accounts->load_str(accounts, &acc, userid) ) {
+ ShowNotice("Attempt of creation of an already existant account (account: %s_%c, pass: %s, received pass: %s)\n", userid, sex, acc.pass, pass);
+ return 1; // 1 = Incorrect Password
+ }
+
+ memset(&acc, '\0', sizeof(acc));
+ acc.account_id = -1; // assigned by account db
+ safestrncpy(acc.userid, userid, sizeof(acc.userid));
+ safestrncpy(acc.pass, pass, sizeof(acc.pass));
+ acc.sex = sex;
+ safestrncpy(acc.email, "a@a.com", sizeof(acc.email));
+ acc.expiration_time = ( login_config.start_limited_time != -1 ) ? time(NULL) + login_config.start_limited_time : 0;
+ safestrncpy(acc.lastlogin, "0000-00-00 00:00:00", sizeof(acc.lastlogin));
+ safestrncpy(acc.last_ip, last_ip, sizeof(acc.last_ip));
+ safestrncpy(acc.birthdate, "0000-00-00", sizeof(acc.birthdate));
+
+ if( !accounts->create(accounts, &acc) )
+ return 0;
+
+ ShowNotice("Account creation (account %s, id: %d, pass: %s, sex: %c)\n", acc.userid, acc.account_id, acc.pass, acc.sex);
+
+ if( DIFF_TICK(tick, new_reg_tick) > 0 ) {// Update the registration check.
+ num_regs = 0;
+ new_reg_tick = tick + time_allowed*1000;
+ }
+ ++num_regs;
+
+ return -1;
}
//-----------------------------------------------------
// Check/authentication of a connection
//-----------------------------------------------------
-int mmo_auth(struct login_session_data *sd, bool isServer)
-{
- struct mmo_account acc;
- int len;
-
- char ip[16];
- ip2str(session[sd->fd]->client_addr, ip);
-
- // DNS Blacklist check
- if (login_config.use_dnsbl) {
- char r_ip[16];
- char ip_dnsbl[256];
- char *dnsbl_serv;
- uint8 *sin_addr = (uint8 *)&session[sd->fd]->client_addr;
-
- sprintf(r_ip, "%u.%u.%u.%u", sin_addr[0], sin_addr[1], sin_addr[2], sin_addr[3]);
-
- for (dnsbl_serv = strtok(login_config.dnsbl_servs,","); dnsbl_serv != NULL; dnsbl_serv = strtok(NULL,",")) {
- sprintf(ip_dnsbl, "%s.%s", r_ip, trim(dnsbl_serv));
- if (host2ip(ip_dnsbl)) {
- ShowInfo("DNSBL: (%s) Blacklisted. User Kicked.\n", r_ip);
- return 3;
- }
- }
-
- }
-
- //Client Version check
- if (login_config.check_client_version && sd->version != login_config.client_version_to_connect)
- return 5;
-
- len = strnlen(sd->userid, NAME_LENGTH);
-
- // Account creation with _M/_F
- if (login_config.new_account_flag) {
- if (len > 2 && strnlen(sd->passwd, NAME_LENGTH) > 0 && // valid user and password lengths
- sd->passwdenc == 0 && // unencoded password
- sd->userid[len-2] == '_' && memchr("FfMm", sd->userid[len-1], 4)) { // _M/_F suffix
- int result;
-
- // remove the _M/_F suffix
- len -= 2;
- sd->userid[len] = '\0';
-
- result = mmo_auth_new(sd->userid, sd->passwd, TOUPPER(sd->userid[len+1]), ip);
- if (result != -1)
- return result;// Failed to make account. [Skotlex].
- }
- }
-
- if (!accounts->load_str(accounts, &acc, sd->userid)) {
- ShowNotice("Unknown account (account: %s, received pass: %s, ip: %s)\n", sd->userid, sd->passwd, ip);
- return 0; // 0 = Unregistered ID
- }
-
- if (!check_password(sd->md5key, sd->passwdenc, sd->passwd, acc.pass)) {
- ShowNotice("Invalid password (account: '%s', pass: '%s', received pass: '%s', ip: %s)\n", sd->userid, acc.pass, sd->passwd, ip);
- return 1; // 1 = Incorrect Password
- }
-
- if (acc.expiration_time != 0 && acc.expiration_time < time(NULL)) {
- ShowNotice("Connection refused (account: %s, pass: %s, expired ID, ip: %s)\n", sd->userid, sd->passwd, ip);
- return 2; // 2 = This ID is expired
- }
-
- if (acc.unban_time != 0 && acc.unban_time > time(NULL)) {
- char tmpstr[24];
- timestamp2string(tmpstr, sizeof(tmpstr), acc.unban_time, login_config.date_format);
- ShowNotice("Connection refused (account: %s, pass: %s, banned until %s, ip: %s)\n", sd->userid, sd->passwd, tmpstr, ip);
- return 6; // 6 = Your are Prohibited to log in until %s
- }
-
- if (acc.state != 0) {
- ShowNotice("Connection refused (account: %s, pass: %s, state: %d, ip: %s)\n", sd->userid, sd->passwd, acc.state, ip);
- return acc.state - 1;
- }
-
- if (login_config.client_hash_check && !isServer) {
- struct client_hash_node *node = login_config.client_hash_nodes;
- bool match = false;
-
- if (!sd->has_client_hash) {
- ShowNotice("Client doesn't sent client hash (account: %s, pass: %s, ip: %s)\n", sd->userid, sd->passwd, acc.state, ip);
- return 5;
- }
-
- while (node) {
- if (node->group_id <= acc.group_id && memcmp(node->hash, sd->client_hash, 16) == 0) {
- match = true;
- break;
- }
-
- node = node->next;
- }
-
- if (!match) {
- char smd5[33];
- int i;
-
- for (i = 0; i < 16; i++)
- sprintf(&smd5[i * 2], "%02x", sd->client_hash[i]);
-
- ShowNotice("Invalid client hash (account: %s, pass: %s, sent md5: %d, ip: %s)\n", sd->userid, sd->passwd, smd5, ip);
- return 5;
- }
- }
-
- ShowNotice("Authentication accepted (account: %s, id: %d, ip: %s)\n", sd->userid, acc.account_id, ip);
-
- // update session data
- sd->account_id = acc.account_id;
- sd->login_id1 = rnd();
- sd->login_id2 = rnd();
- safestrncpy(sd->lastlogin, acc.lastlogin, sizeof(sd->lastlogin));
- sd->sex = acc.sex;
- sd->group_id = acc.group_id;
-
- // update account data
- timestamp2string(acc.lastlogin, sizeof(acc.lastlogin), time(NULL), "%Y-%m-%d %H:%M:%S");
- safestrncpy(acc.last_ip, ip, sizeof(acc.last_ip));
- acc.unban_time = 0;
- acc.logincount++;
-
- accounts->save(accounts, &acc);
-
- if (sd->sex != 'S' && sd->account_id < START_ACCOUNT_NUM)
- ShowWarning("Account %s has account id %d! Account IDs must be over %d to work properly!\n", sd->userid, sd->account_id, START_ACCOUNT_NUM);
-
- return -1; // account OK
+int mmo_auth(struct login_session_data* sd, bool isServer) {
+ struct mmo_account acc;
+ int len;
+
+ char ip[16];
+ ip2str(session[sd->fd]->client_addr, ip);
+
+ // DNS Blacklist check
+ if( login_config.use_dnsbl ) {
+ char r_ip[16];
+ char ip_dnsbl[256];
+ char* dnsbl_serv;
+ uint8* sin_addr = (uint8*)&session[sd->fd]->client_addr;
+
+ sprintf(r_ip, "%u.%u.%u.%u", sin_addr[0], sin_addr[1], sin_addr[2], sin_addr[3]);
+
+ for( dnsbl_serv = strtok(login_config.dnsbl_servs,","); dnsbl_serv != NULL; dnsbl_serv = strtok(NULL,",") ) {
+ sprintf(ip_dnsbl, "%s.%s", r_ip, trim(dnsbl_serv));
+ if( host2ip(ip_dnsbl) ) {
+ ShowInfo("DNSBL: (%s) Blacklisted. User Kicked.\n", r_ip);
+ return 3;
+ }
+ }
+
+ }
+
+ //Client Version check
+ if( login_config.check_client_version && sd->version != login_config.client_version_to_connect )
+ return 5;
+
+ len = strnlen(sd->userid, NAME_LENGTH);
+
+ // Account creation with _M/_F
+ if( login_config.new_account_flag ) {
+ if( len > 2 && strnlen(sd->passwd, NAME_LENGTH) > 0 && // valid user and password lengths
+ sd->passwdenc == 0 && // unencoded password
+ sd->userid[len-2] == '_' && memchr("FfMm", sd->userid[len-1], 4) ) // _M/_F suffix
+ {
+ int result;
+
+ // remove the _M/_F suffix
+ len -= 2;
+ sd->userid[len] = '\0';
+
+ result = mmo_auth_new(sd->userid, sd->passwd, TOUPPER(sd->userid[len+1]), ip);
+ if( result != -1 )
+ return result;// Failed to make account. [Skotlex].
+ }
+ }
+
+ if( !accounts->load_str(accounts, &acc, sd->userid) ) {
+ ShowNotice("Unknown account (account: %s, received pass: %s, ip: %s)\n", sd->userid, sd->passwd, ip);
+ return 0; // 0 = Unregistered ID
+ }
+
+ if( !check_password(sd->md5key, sd->passwdenc, sd->passwd, acc.pass) ) {
+ ShowNotice("Invalid password (account: '%s', pass: '%s', received pass: '%s', ip: %s)\n", sd->userid, acc.pass, sd->passwd, ip);
+ return 1; // 1 = Incorrect Password
+ }
+
+ if( acc.expiration_time != 0 && acc.expiration_time < time(NULL) ) {
+ ShowNotice("Connection refused (account: %s, pass: %s, expired ID, ip: %s)\n", sd->userid, sd->passwd, ip);
+ return 2; // 2 = This ID is expired
+ }
+
+ if( acc.unban_time != 0 && acc.unban_time > time(NULL) ) {
+ char tmpstr[24];
+ timestamp2string(tmpstr, sizeof(tmpstr), acc.unban_time, login_config.date_format);
+ ShowNotice("Connection refused (account: %s, pass: %s, banned until %s, ip: %s)\n", sd->userid, sd->passwd, tmpstr, ip);
+ return 6; // 6 = Your are Prohibited to log in until %s
+ }
+
+ if( acc.state != 0 ) {
+ ShowNotice("Connection refused (account: %s, pass: %s, state: %d, ip: %s)\n", sd->userid, sd->passwd, acc.state, ip);
+ return acc.state - 1;
+ }
+
+ if( login_config.client_hash_check && !isServer ) {
+ struct client_hash_node *node = login_config.client_hash_nodes;
+ bool match = false;
+
+ if( !sd->has_client_hash ) {
+ ShowNotice("Client doesn't sent client hash (account: %s, pass: %s, ip: %s)\n", sd->userid, sd->passwd, acc.state, ip);
+ return 5;
+ }
+
+ while( node ) {
+ if( node->group_id <= acc.group_id && memcmp(node->hash, sd->client_hash, 16) == 0 ) {
+ match = true;
+ break;
+ }
+
+ node = node->next;
+ }
+
+ if( !match ) {
+ char smd5[33];
+ int i;
+
+ for( i = 0; i < 16; i++ )
+ sprintf(&smd5[i * 2], "%02x", sd->client_hash[i]);
+
+ ShowNotice("Invalid client hash (account: %s, pass: %s, sent md5: %d, ip: %s)\n", sd->userid, sd->passwd, smd5, ip);
+ return 5;
+ }
+ }
+
+ ShowNotice("Authentication accepted (account: %s, id: %d, ip: %s)\n", sd->userid, acc.account_id, ip);
+
+ // update session data
+ sd->account_id = acc.account_id;
+ sd->login_id1 = rnd();
+ sd->login_id2 = rnd();
+ safestrncpy(sd->lastlogin, acc.lastlogin, sizeof(sd->lastlogin));
+ sd->sex = acc.sex;
+ sd->group_id = acc.group_id;
+
+ // update account data
+ timestamp2string(acc.lastlogin, sizeof(acc.lastlogin), time(NULL), "%Y-%m-%d %H:%M:%S");
+ safestrncpy(acc.last_ip, ip, sizeof(acc.last_ip));
+ acc.unban_time = 0;
+ acc.logincount++;
+
+ accounts->save(accounts, &acc);
+
+ if( sd->sex != 'S' && sd->account_id < START_ACCOUNT_NUM )
+ ShowWarning("Account %s has account id %d! Account IDs must be over %d to work properly!\n", sd->userid, sd->account_id, START_ACCOUNT_NUM);
+
+ return -1; // account OK
}
-void login_auth_ok(struct login_session_data *sd)
+void login_auth_ok(struct login_session_data* sd)
{
- int fd = sd->fd;
- uint32 ip = session[fd]->client_addr;
-
- uint8 server_num, n;
- uint32 subnet_char_ip;
- struct auth_node *node;
- int i;
-
- if (runflag != LOGINSERVER_ST_RUNNING) {
- // players can only login while running
- WFIFOHEAD(fd,3);
- WFIFOW(fd,0) = 0x81;
- WFIFOB(fd,2) = 1;// server closed
- WFIFOSET(fd,3);
- return;
- }
-
- if (login_config.group_id_to_connect >= 0 && sd->group_id != login_config.group_id_to_connect) {
- ShowStatus("Connection refused: the required group id for connection is %d (account: %s, group: %d).\n", login_config.group_id_to_connect, sd->userid, sd->group_id);
- WFIFOHEAD(fd,3);
- WFIFOW(fd,0) = 0x81;
- WFIFOB(fd,2) = 1; // 01 = Server closed
- WFIFOSET(fd,3);
- return;
- } else if (login_config.min_group_id_to_connect >= 0 && login_config.group_id_to_connect == -1 && sd->group_id < login_config.min_group_id_to_connect) {
- ShowStatus("Connection refused: the minium group id required for connection is %d (account: %s, group: %d).\n", login_config.min_group_id_to_connect, sd->userid, sd->group_id);
- WFIFOHEAD(fd,3);
- WFIFOW(fd,0) = 0x81;
- WFIFOB(fd,2) = 1; // 01 = Server closed
- WFIFOSET(fd,3);
- return;
- }
-
- server_num = 0;
- for (i = 0; i < ARRAYLENGTH(server); ++i)
- if (session_isActive(server[i].fd))
- server_num++;
-
- if (server_num == 0) {
- // if no char-server, don't send void list of servers, just disconnect the player with proper message
- ShowStatus("Connection refused: there is no char-server online (account: %s).\n", sd->userid);
- WFIFOHEAD(fd,3);
- WFIFOW(fd,0) = 0x81;
- WFIFOB(fd,2) = 1; // 01 = Server closed
- WFIFOSET(fd,3);
- return;
- }
-
- {
- struct online_login_data *data = (struct online_login_data *)idb_get(online_db, sd->account_id);
- if (data) {
- // account is already marked as online!
- if (data->char_server > -1) {
- // Request char servers to kick this account out. [Skotlex]
- uint8 buf[6];
- ShowNotice("User '%s' is already online - Rejected.\n", sd->userid);
- WBUFW(buf,0) = 0x2734;
- WBUFL(buf,2) = sd->account_id;
- charif_sendallwos(-1, buf, 6);
- if (data->waiting_disconnect == INVALID_TIMER)
- data->waiting_disconnect = add_timer(gettick()+AUTH_TIMEOUT, waiting_disconnect_timer, sd->account_id, 0);
-
- WFIFOHEAD(fd,3);
- WFIFOW(fd,0) = 0x81;
- WFIFOB(fd,2) = 8; // 08 = Server still recognizes your last login
- WFIFOSET(fd,3);
- return;
- } else if (data->char_server == -1) {
- // client has authed but did not access char-server yet
- // wipe previous session
- idb_remove(auth_db, sd->account_id);
- remove_online_user(sd->account_id);
- data = NULL;
- }
- }
- }
-
- login_log(ip, sd->userid, 100, "login ok");
- ShowStatus("Connection of the account '%s' accepted.\n", sd->userid);
-
- WFIFOHEAD(fd,47+32*server_num);
- WFIFOW(fd,0) = 0x69;
- WFIFOW(fd,2) = 47+32*server_num;
- WFIFOL(fd,4) = sd->login_id1;
- WFIFOL(fd,8) = sd->account_id;
- WFIFOL(fd,12) = sd->login_id2;
- WFIFOL(fd,16) = 0; // in old version, that was for ip (not more used)
- //memcpy(WFIFOP(fd,20), sd->lastlogin, 24); // in old version, that was for name (not more used)
- memset(WFIFOP(fd,20), 0, 24);
- WFIFOW(fd,44) = 0; // unknown
- WFIFOB(fd,46) = sex_str2num(sd->sex);
- for (i = 0, n = 0; i < ARRAYLENGTH(server); ++i) {
- if (!session_isValid(server[i].fd))
- continue;
-
- subnet_char_ip = lan_subnetcheck(ip); // Advanced subnet check [LuzZza]
- WFIFOL(fd,47+n*32) = htonl((subnet_char_ip) ? subnet_char_ip : server[i].ip);
- WFIFOW(fd,47+n*32+4) = ntows(htons(server[i].port)); // [!] LE byte order here [!]
- memcpy(WFIFOP(fd,47+n*32+6), server[i].name, 20);
- WFIFOW(fd,47+n*32+26) = server[i].users;
- WFIFOW(fd,47+n*32+28) = server[i].type;
- WFIFOW(fd,47+n*32+30) = server[i].new_;
- n++;
- }
- WFIFOSET(fd,47+32*server_num);
-
- // create temporary auth entry
- CREATE(node, struct auth_node, 1);
- node->account_id = sd->account_id;
- node->login_id1 = sd->login_id1;
- node->login_id2 = sd->login_id2;
- node->sex = sd->sex;
- node->ip = ip;
- node->version = sd->version;
- node->clienttype = sd->clienttype;
- idb_put(auth_db, sd->account_id, node);
-
- {
- struct online_login_data *data;
-
- // mark client as 'online'
- data = add_online_user(-1, sd->account_id);
-
- // schedule deletion of this node
- data->waiting_disconnect = add_timer(gettick()+AUTH_TIMEOUT, waiting_disconnect_timer, sd->account_id, 0);
- }
+ int fd = sd->fd;
+ uint32 ip = session[fd]->client_addr;
+
+ uint8 server_num, n;
+ uint32 subnet_char_ip;
+ struct auth_node* node;
+ int i;
+
+ if( runflag != LOGINSERVER_ST_RUNNING )
+ {
+ // players can only login while running
+ WFIFOHEAD(fd,3);
+ WFIFOW(fd,0) = 0x81;
+ WFIFOB(fd,2) = 1;// server closed
+ WFIFOSET(fd,3);
+ return;
+ }
+
+ if( login_config.group_id_to_connect >= 0 && sd->group_id != login_config.group_id_to_connect ) {
+ ShowStatus("Connection refused: the required group id for connection is %d (account: %s, group: %d).\n", login_config.group_id_to_connect, sd->userid, sd->group_id);
+ WFIFOHEAD(fd,3);
+ WFIFOW(fd,0) = 0x81;
+ WFIFOB(fd,2) = 1; // 01 = Server closed
+ WFIFOSET(fd,3);
+ return;
+ } else if( login_config.min_group_id_to_connect >= 0 && login_config.group_id_to_connect == -1 && sd->group_id < login_config.min_group_id_to_connect ) {
+ ShowStatus("Connection refused: the minium group id required for connection is %d (account: %s, group: %d).\n", login_config.min_group_id_to_connect, sd->userid, sd->group_id);
+ WFIFOHEAD(fd,3);
+ WFIFOW(fd,0) = 0x81;
+ WFIFOB(fd,2) = 1; // 01 = Server closed
+ WFIFOSET(fd,3);
+ return;
+ }
+
+ server_num = 0;
+ for( i = 0; i < ARRAYLENGTH(server); ++i )
+ if( session_isActive(server[i].fd) )
+ server_num++;
+
+ if( server_num == 0 )
+ {// if no char-server, don't send void list of servers, just disconnect the player with proper message
+ ShowStatus("Connection refused: there is no char-server online (account: %s).\n", sd->userid);
+ WFIFOHEAD(fd,3);
+ WFIFOW(fd,0) = 0x81;
+ WFIFOB(fd,2) = 1; // 01 = Server closed
+ WFIFOSET(fd,3);
+ return;
+ }
+
+ {
+ struct online_login_data* data = (struct online_login_data*)idb_get(online_db, sd->account_id);
+ if( data )
+ {// account is already marked as online!
+ if( data->char_server > -1 )
+ {// Request char servers to kick this account out. [Skotlex]
+ uint8 buf[6];
+ ShowNotice("User '%s' is already online - Rejected.\n", sd->userid);
+ WBUFW(buf,0) = 0x2734;
+ WBUFL(buf,2) = sd->account_id;
+ charif_sendallwos(-1, buf, 6);
+ if( data->waiting_disconnect == INVALID_TIMER )
+ data->waiting_disconnect = add_timer(gettick()+AUTH_TIMEOUT, waiting_disconnect_timer, sd->account_id, 0);
+
+ WFIFOHEAD(fd,3);
+ WFIFOW(fd,0) = 0x81;
+ WFIFOB(fd,2) = 8; // 08 = Server still recognizes your last login
+ WFIFOSET(fd,3);
+ return;
+ }
+ else
+ if( data->char_server == -1 )
+ {// client has authed but did not access char-server yet
+ // wipe previous session
+ idb_remove(auth_db, sd->account_id);
+ remove_online_user(sd->account_id);
+ data = NULL;
+ }
+ }
+ }
+
+ login_log(ip, sd->userid, 100, "login ok");
+ ShowStatus("Connection of the account '%s' accepted.\n", sd->userid);
+
+ WFIFOHEAD(fd,47+32*server_num);
+ WFIFOW(fd,0) = 0x69;
+ WFIFOW(fd,2) = 47+32*server_num;
+ WFIFOL(fd,4) = sd->login_id1;
+ WFIFOL(fd,8) = sd->account_id;
+ WFIFOL(fd,12) = sd->login_id2;
+ WFIFOL(fd,16) = 0; // in old version, that was for ip (not more used)
+ //memcpy(WFIFOP(fd,20), sd->lastlogin, 24); // in old version, that was for name (not more used)
+ memset(WFIFOP(fd,20), 0, 24);
+ WFIFOW(fd,44) = 0; // unknown
+ WFIFOB(fd,46) = sex_str2num(sd->sex);
+ for( i = 0, n = 0; i < ARRAYLENGTH(server); ++i )
+ {
+ if( !session_isValid(server[i].fd) )
+ continue;
+
+ subnet_char_ip = lan_subnetcheck(ip); // Advanced subnet check [LuzZza]
+ WFIFOL(fd,47+n*32) = htonl((subnet_char_ip) ? subnet_char_ip : server[i].ip);
+ WFIFOW(fd,47+n*32+4) = ntows(htons(server[i].port)); // [!] LE byte order here [!]
+ memcpy(WFIFOP(fd,47+n*32+6), server[i].name, 20);
+ WFIFOW(fd,47+n*32+26) = server[i].users;
+ WFIFOW(fd,47+n*32+28) = server[i].type;
+ WFIFOW(fd,47+n*32+30) = server[i].new_;
+ n++;
+ }
+ WFIFOSET(fd,47+32*server_num);
+
+ // create temporary auth entry
+ CREATE(node, struct auth_node, 1);
+ node->account_id = sd->account_id;
+ node->login_id1 = sd->login_id1;
+ node->login_id2 = sd->login_id2;
+ node->sex = sd->sex;
+ node->ip = ip;
+ node->version = sd->version;
+ node->clienttype = sd->clienttype;
+ idb_put(auth_db, sd->account_id, node);
+
+ {
+ struct online_login_data* data;
+
+ // mark client as 'online'
+ data = add_online_user(-1, sd->account_id);
+
+ // schedule deletion of this node
+ data->waiting_disconnect = add_timer(gettick()+AUTH_TIMEOUT, waiting_disconnect_timer, sd->account_id, 0);
+ }
}
-void login_auth_failed(struct login_session_data *sd, int result)
+void login_auth_failed(struct login_session_data* sd, int result)
{
- int fd = sd->fd;
- uint32 ip = session[fd]->client_addr;
-
- if (login_config.log_login) {
- const char *error;
- switch (result) {
- case 0:
- error = "Unregistered ID.";
- break; // 0 = Unregistered ID
- case 1:
- error = "Incorrect Password.";
- break; // 1 = Incorrect Password
- case 2:
- error = "Account Expired.";
- break; // 2 = This ID is expired
- case 3:
- error = "Rejected from server.";
- break; // 3 = Rejected from Server
- case 4:
- error = "Blocked by GM.";
- break; // 4 = You have been blocked by the GM Team
- case 5:
- error = "Not latest game EXE.";
- break; // 5 = Your Game's EXE file is not the latest version
- case 6:
- error = "Banned.";
- break; // 6 = Your are Prohibited to log in until %s
- case 7:
- error = "Server Over-population.";
- break; // 7 = Server is jammed due to over populated
- case 8:
- error = "Account limit from company";
- break; // 8 = No more accounts may be connected from this company
- case 9:
- error = "Ban by DBA";
- break; // 9 = MSI_REFUSE_BAN_BY_DBA
- case 10:
- error = "Email not confirmed";
- break; // 10 = MSI_REFUSE_EMAIL_NOT_CONFIRMED
- case 11:
- error = "Ban by GM";
- break; // 11 = MSI_REFUSE_BAN_BY_GM
- case 12:
- error = "Working in DB";
- break; // 12 = MSI_REFUSE_TEMP_BAN_FOR_DBWORK
- case 13:
- error = "Self Lock";
- break; // 13 = MSI_REFUSE_SELF_LOCK
- case 14:
- error = "Not Permitted Group";
- break; // 14 = MSI_REFUSE_NOT_PERMITTED_GROUP
- case 15:
- error = "Not Permitted Group";
- break; // 15 = MSI_REFUSE_NOT_PERMITTED_GROUP
- case 99:
- error = "Account gone.";
- break; // 99 = This ID has been totally erased
- case 100:
- error = "Login info remains.";
- break; // 100 = Login information remains at %s
- case 101:
- error = "Hacking investigation.";
- break; // 101 = Account has been locked for a hacking investigation. Please contact the GM Team for more information
- case 102:
- error = "Bug investigation.";
- break; // 102 = This account has been temporarily prohibited from login due to a bug-related investigation
- case 103:
- error = "Deleting char.";
- break; // 103 = This character is being deleted. Login is temporarily unavailable for the time being
- case 104:
- error = "Deleting spouse char.";
- break; // 104 = This character is being deleted. Login is temporarily unavailable for the time being
- default :
- error = "Unknown Error.";
- break;
- }
-
- login_log(ip, sd->userid, result, error);
- }
-
- if (result == 1 && login_config.dynamic_pass_failure_ban)
- ipban_log(ip); // log failed password attempt
-
- WFIFOHEAD(fd,23);
- WFIFOW(fd,0) = 0x6a;
- WFIFOB(fd,2) = (uint8)result;
- if (result != 6)
- memset(WFIFOP(fd,3), '\0', 20);
- else {
- // 6 = Your are Prohibited to log in until %s
- struct mmo_account acc;
- time_t unban_time = (accounts->load_str(accounts, &acc, sd->userid)) ? acc.unban_time : 0;
- timestamp2string((char *)WFIFOP(fd,3), 20, unban_time, login_config.date_format);
- }
- WFIFOSET(fd,23);
+ int fd = sd->fd;
+ uint32 ip = session[fd]->client_addr;
+
+ if (login_config.log_login)
+ {
+ const char* error;
+ switch( result ) {
+ case 0: error = "Unregistered ID."; break; // 0 = Unregistered ID
+ case 1: error = "Incorrect Password."; break; // 1 = Incorrect Password
+ case 2: error = "Account Expired."; break; // 2 = This ID is expired
+ case 3: error = "Rejected from server."; break; // 3 = Rejected from Server
+ case 4: error = "Blocked by GM."; break; // 4 = You have been blocked by the GM Team
+ case 5: error = "Not latest game EXE."; break; // 5 = Your Game's EXE file is not the latest version
+ case 6: error = "Banned."; break; // 6 = Your are Prohibited to log in until %s
+ case 7: error = "Server Over-population."; break; // 7 = Server is jammed due to over populated
+ case 8: error = "Account limit from company"; break; // 8 = No more accounts may be connected from this company
+ case 9: error = "Ban by DBA"; break; // 9 = MSI_REFUSE_BAN_BY_DBA
+ case 10: error = "Email not confirmed"; break; // 10 = MSI_REFUSE_EMAIL_NOT_CONFIRMED
+ case 11: error = "Ban by GM"; break; // 11 = MSI_REFUSE_BAN_BY_GM
+ case 12: error = "Working in DB"; break; // 12 = MSI_REFUSE_TEMP_BAN_FOR_DBWORK
+ case 13: error = "Self Lock"; break; // 13 = MSI_REFUSE_SELF_LOCK
+ case 14: error = "Not Permitted Group"; break; // 14 = MSI_REFUSE_NOT_PERMITTED_GROUP
+ case 15: error = "Not Permitted Group"; break; // 15 = MSI_REFUSE_NOT_PERMITTED_GROUP
+ case 99: error = "Account gone."; break; // 99 = This ID has been totally erased
+ case 100: error = "Login info remains."; break; // 100 = Login information remains at %s
+ case 101: error = "Hacking investigation."; break; // 101 = Account has been locked for a hacking investigation. Please contact the GM Team for more information
+ case 102: error = "Bug investigation."; break; // 102 = This account has been temporarily prohibited from login due to a bug-related investigation
+ case 103: error = "Deleting char."; break; // 103 = This character is being deleted. Login is temporarily unavailable for the time being
+ case 104: error = "Deleting spouse char."; break; // 104 = This character is being deleted. Login is temporarily unavailable for the time being
+ default : error = "Unknown Error."; break;
+ }
+
+ login_log(ip, sd->userid, result, error);
+ }
+
+ if( result == 1 && login_config.dynamic_pass_failure_ban )
+ ipban_log(ip); // log failed password attempt
+
+ WFIFOHEAD(fd,23);
+ WFIFOW(fd,0) = 0x6a;
+ WFIFOB(fd,2) = (uint8)result;
+ if( result != 6 )
+ memset(WFIFOP(fd,3), '\0', 20);
+ else
+ {// 6 = Your are Prohibited to log in until %s
+ struct mmo_account acc;
+ time_t unban_time = ( accounts->load_str(accounts, &acc, sd->userid) ) ? acc.unban_time : 0;
+ timestamp2string((char*)WFIFOP(fd,3), 20, unban_time, login_config.date_format);
+ }
+ WFIFOSET(fd,23);
}
@@ -1294,400 +1298,428 @@ void login_auth_failed(struct login_session_data *sd, int result)
//----------------------------------------------------------------------------------------
int parse_login(int fd)
{
- struct login_session_data *sd = (struct login_session_data *)session[fd]->session_data;
- int result;
-
- char ip[16];
- uint32 ipl = session[fd]->client_addr;
- ip2str(ipl, ip);
-
- if (session[fd]->flag.eof) {
- ShowInfo("Closed connection from '"CL_WHITE"%s"CL_RESET"'.\n", ip);
- do_close(fd);
- return 0;
- }
-
- if (sd == NULL) {
- // Perform ip-ban check
- if (login_config.ipban && ipban_check(ipl)) {
- ShowStatus("Connection refused: IP isn't authorised (deny/allow, ip: %s).\n", ip);
- login_log(ipl, "unknown", -3, "ip banned");
- WFIFOHEAD(fd,23);
- WFIFOW(fd,0) = 0x6a;
- WFIFOB(fd,2) = 3; // 3 = Rejected from Server
- WFIFOSET(fd,23);
- set_eof(fd);
- return 0;
- }
-
- // create a session for this new connection
- CREATE(session[fd]->session_data, struct login_session_data, 1);
- sd = (struct login_session_data *)session[fd]->session_data;
- sd->fd = fd;
- }
-
- while (RFIFOREST(fd) >= 2) {
- uint16 command = RFIFOW(fd,0);
-
- switch (command) {
-
- case 0x0200: // 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;
-
- // client md5 hash (binary)
- case 0x0204: // S 0204 <md5 hash>.16B (kRO 2004-05-31aSakexe langtype 0 and 6)
- if (RFIFOREST(fd) < 18)
- return 0;
-
- sd->has_client_hash = 1;
- memcpy(sd->client_hash, RFIFOP(fd, 2), 16);
-
- RFIFOSKIP(fd,18);
- break;
-
- // request client login (raw password)
- case 0x0064: // S 0064 <version>.L <username>.24B <password>.24B <clienttype>.B
- case 0x0277: // S 0277 <version>.L <username>.24B <password>.24B <clienttype>.B <ip address>.16B <adapter address>.13B
- case 0x02b0: // S 02b0 <version>.L <username>.24B <password>.24B <clienttype>.B <ip address>.16B <adapter address>.13B <g_isGravityID>.B
- // request client login (md5-hashed password)
- case 0x01dd: // S 01dd <version>.L <username>.24B <password hash>.16B <clienttype>.B
- case 0x01fa: // S 01fa <version>.L <username>.24B <password hash>.16B <clienttype>.B <?>.B(index of the connection in the clientinfo file (+10 if the command-line contains "pc"))
- case 0x027c: // S 027c <version>.L <username>.24B <password hash>.16B <clienttype>.B <?>.13B(junk)
- case 0x0825: { // S 0825 <packetsize>.W <version>.L <clienttype>.B <userid>.24B <password>.27B <mac>.17B <ip>.15B <token>.(packetsize - 0x5C)B
- size_t packet_len = RFIFOREST(fd);
-
- if ((command == 0x0064 && packet_len < 55)
- || (command == 0x0277 && packet_len < 84)
- || (command == 0x02b0 && packet_len < 85)
- || (command == 0x01dd && packet_len < 47)
- || (command == 0x01fa && packet_len < 48)
- || (command == 0x027c && packet_len < 60)
- || (command == 0x0825 && (packet_len < 4 || packet_len < RFIFOW(fd, 2))))
- return 0;
- }
- {
- uint32 version;
- char username[NAME_LENGTH];
- char password[NAME_LENGTH];
- unsigned char passhash[16];
- uint8 clienttype;
- bool israwpass = (command==0x0064 || command==0x0277 || command==0x02b0 || command == 0x0825);
-
- // Shinryo: For the time being, just use token as password.
- if (command == 0x0825) {
- char *accname = (char *)RFIFOP(fd, 9);
- char *token = (char *)RFIFOP(fd, 0x5C);
- size_t uAccLen = strlen(accname);
- size_t uTokenLen = RFIFOREST(fd) - 0x5C;
-
- version = RFIFOL(fd,4);
-
- if (uAccLen > NAME_LENGTH - 1 || uAccLen <= 0 || uTokenLen > NAME_LENGTH - 1 || uTokenLen <= 0) {
- login_auth_failed(sd, 3);
- return 0;
- }
-
- safestrncpy(username, accname, uAccLen + 1);
- safestrncpy(password, token, uTokenLen + 1);
- clienttype = RFIFOB(fd, 8);
- } else {
- version = RFIFOL(fd,2);
- safestrncpy(username, (const char *)RFIFOP(fd,6), NAME_LENGTH);
- if (israwpass) {
- safestrncpy(password, (const char *)RFIFOP(fd,30), NAME_LENGTH);
- clienttype = RFIFOB(fd,54);
- } else {
- memcpy(passhash, RFIFOP(fd,30), 16);
- clienttype = RFIFOB(fd,46);
- }
- }
- RFIFOSKIP(fd,RFIFOREST(fd)); // assume no other packet was sent
-
- sd->clienttype = clienttype;
- sd->version = version;
- safestrncpy(sd->userid, username, NAME_LENGTH);
- if (israwpass) {
- ShowStatus("Request for connection of %s (ip: %s).\n", sd->userid, ip);
- safestrncpy(sd->passwd, password, NAME_LENGTH);
- if (login_config.use_md5_passwds)
- MD5_String(sd->passwd, sd->passwd);
- sd->passwdenc = 0;
- } else {
- ShowStatus("Request for connection (passwdenc mode) of %s (ip: %s).\n", sd->userid, ip);
- bin2hex(sd->passwd, passhash, 16); // raw binary data here!
- sd->passwdenc = PASSWORDENC;
- }
-
- if (sd->passwdenc != 0 && login_config.use_md5_passwds) {
- login_auth_failed(sd, 3); // send "rejected from server"
- return 0;
- }
-
- result = mmo_auth(sd, false);
-
- if (result == -1)
- login_auth_ok(sd);
- else
- login_auth_failed(sd, result);
- }
- break;
-
- case 0x01db: // Sending request of the coding key
- RFIFOSKIP(fd,2);
- {
- memset(sd->md5key, '\0', sizeof(sd->md5key));
- sd->md5keylen = (uint16)(12 + rnd() % 4);
- MD5_Salt(sd->md5keylen, sd->md5key);
-
- WFIFOHEAD(fd,4 + sd->md5keylen);
- WFIFOW(fd,0) = 0x01dc;
- WFIFOW(fd,2) = 4 + sd->md5keylen;
- memcpy(WFIFOP(fd,4), sd->md5key, sd->md5keylen);
- WFIFOSET(fd,WFIFOW(fd,2));
- }
- break;
-
- case 0x2710: // Connection request of a char-server
- if (RFIFOREST(fd) < 86)
- return 0;
- {
- char server_name[20];
- char message[256];
- uint32 server_ip;
- uint16 server_port;
- uint16 type;
- uint16 new_;
-
- safestrncpy(sd->userid, (char *)RFIFOP(fd,2), NAME_LENGTH);
- safestrncpy(sd->passwd, (char *)RFIFOP(fd,26), NAME_LENGTH);
- if (login_config.use_md5_passwds)
- MD5_String(sd->passwd, sd->passwd);
- sd->passwdenc = 0;
- sd->version = login_config.client_version_to_connect; // hack to skip version check
- server_ip = ntohl(RFIFOL(fd,54));
- server_port = ntohs(RFIFOW(fd,58));
- safestrncpy(server_name, (char *)RFIFOP(fd,60), 20);
- type = RFIFOW(fd,82);
- new_ = RFIFOW(fd,84);
- RFIFOSKIP(fd,86);
-
- ShowInfo("Connection request of the char-server '%s' @ %u.%u.%u.%u:%u (account: '%s', pass: '%s', ip: '%s')\n", server_name, CONVIP(server_ip), server_port, sd->userid, sd->passwd, ip);
- sprintf(message, "charserver - %s@%u.%u.%u.%u:%u", server_name, CONVIP(server_ip), server_port);
- login_log(session[fd]->client_addr, sd->userid, 100, message);
-
- result = mmo_auth(sd, true);
- if (runflag == LOGINSERVER_ST_RUNNING &&
- result == -1 &&
- sd->sex == 'S' &&
- sd->account_id >= 0 && sd->account_id < ARRAYLENGTH(server) &&
- !session_isValid(server[sd->account_id].fd)) {
- ShowStatus("Connection of the char-server '%s' accepted.\n", server_name);
- safestrncpy(server[sd->account_id].name, server_name, sizeof(server[sd->account_id].name));
- server[sd->account_id].fd = fd;
- server[sd->account_id].ip = server_ip;
- server[sd->account_id].port = server_port;
- server[sd->account_id].users = 0;
- server[sd->account_id].type = type;
- server[sd->account_id].new_ = new_;
-
- session[fd]->func_parse = parse_fromchar;
- session[fd]->flag.server = 1;
- realloc_fifo(fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
-
- // send connection success
- WFIFOHEAD(fd,3);
- WFIFOW(fd,0) = 0x2711;
- WFIFOB(fd,2) = 0;
- WFIFOSET(fd,3);
- } else {
- ShowNotice("Connection of the char-server '%s' REFUSED.\n", server_name);
- WFIFOHEAD(fd,3);
- WFIFOW(fd,0) = 0x2711;
- WFIFOB(fd,2) = 3;
- WFIFOSET(fd,3);
- }
- }
- return 0; // processing will continue elsewhere
-
- default:
- ShowNotice("Abnormal end of connection (ip: %s): Unknown packet 0x%x\n", ip, command);
- set_eof(fd);
- return 0;
- }
- }
-
- return 0;
+ struct login_session_data* sd = (struct login_session_data*)session[fd]->session_data;
+ int result;
+
+ char ip[16];
+ uint32 ipl = session[fd]->client_addr;
+ ip2str(ipl, ip);
+
+ if( session[fd]->flag.eof )
+ {
+ ShowInfo("Closed connection from '"CL_WHITE"%s"CL_RESET"'.\n", ip);
+ do_close(fd);
+ return 0;
+ }
+
+ if( sd == NULL )
+ {
+ // Perform ip-ban check
+ if( login_config.ipban && ipban_check(ipl) )
+ {
+ ShowStatus("Connection refused: IP isn't authorised (deny/allow, ip: %s).\n", ip);
+ login_log(ipl, "unknown", -3, "ip banned");
+ WFIFOHEAD(fd,23);
+ WFIFOW(fd,0) = 0x6a;
+ WFIFOB(fd,2) = 3; // 3 = Rejected from Server
+ WFIFOSET(fd,23);
+ set_eof(fd);
+ return 0;
+ }
+
+ // create a session for this new connection
+ CREATE(session[fd]->session_data, struct login_session_data, 1);
+ sd = (struct login_session_data*)session[fd]->session_data;
+ sd->fd = fd;
+ }
+
+ while( RFIFOREST(fd) >= 2 )
+ {
+ uint16 command = RFIFOW(fd,0);
+
+ switch( command )
+ {
+
+ case 0x0200: // 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;
+
+ // client md5 hash (binary)
+ case 0x0204: // S 0204 <md5 hash>.16B (kRO 2004-05-31aSakexe langtype 0 and 6)
+ if (RFIFOREST(fd) < 18)
+ return 0;
+
+ sd->has_client_hash = 1;
+ memcpy(sd->client_hash, RFIFOP(fd, 2), 16);
+
+ RFIFOSKIP(fd,18);
+ break;
+
+ // request client login (raw password)
+ case 0x0064: // S 0064 <version>.L <username>.24B <password>.24B <clienttype>.B
+ case 0x0277: // S 0277 <version>.L <username>.24B <password>.24B <clienttype>.B <ip address>.16B <adapter address>.13B
+ case 0x02b0: // S 02b0 <version>.L <username>.24B <password>.24B <clienttype>.B <ip address>.16B <adapter address>.13B <g_isGravityID>.B
+ // request client login (md5-hashed password)
+ case 0x01dd: // S 01dd <version>.L <username>.24B <password hash>.16B <clienttype>.B
+ case 0x01fa: // S 01fa <version>.L <username>.24B <password hash>.16B <clienttype>.B <?>.B(index of the connection in the clientinfo file (+10 if the command-line contains "pc"))
+ case 0x027c: // S 027c <version>.L <username>.24B <password hash>.16B <clienttype>.B <?>.13B(junk)
+ case 0x0825: // S 0825 <packetsize>.W <version>.L <clienttype>.B <userid>.24B <password>.27B <mac>.17B <ip>.15B <token>.(packetsize - 0x5C)B
+ {
+ size_t packet_len = RFIFOREST(fd);
+
+ if( (command == 0x0064 && packet_len < 55)
+ || (command == 0x0277 && packet_len < 84)
+ || (command == 0x02b0 && packet_len < 85)
+ || (command == 0x01dd && packet_len < 47)
+ || (command == 0x01fa && packet_len < 48)
+ || (command == 0x027c && packet_len < 60)
+ || (command == 0x0825 && (packet_len < 4 || packet_len < RFIFOW(fd, 2))) )
+ return 0;
+ }
+ {
+ uint32 version;
+ char username[NAME_LENGTH];
+ char password[NAME_LENGTH];
+ unsigned char passhash[16];
+ uint8 clienttype;
+ bool israwpass = (command==0x0064 || command==0x0277 || command==0x02b0 || command == 0x0825);
+
+ // Shinryo: For the time being, just use token as password.
+ if(command == 0x0825)
+ {
+ char *accname = (char *)RFIFOP(fd, 9);
+ char *token = (char *)RFIFOP(fd, 0x5C);
+ size_t uAccLen = strlen(accname);
+ size_t uTokenLen = RFIFOREST(fd) - 0x5C;
+
+ version = RFIFOL(fd,4);
+
+ if(uAccLen > NAME_LENGTH - 1 || uAccLen <= 0 || uTokenLen > NAME_LENGTH - 1 || uTokenLen <= 0)
+ {
+ login_auth_failed(sd, 3);
+ return 0;
+ }
+
+ safestrncpy(username, accname, uAccLen + 1);
+ safestrncpy(password, token, uTokenLen + 1);
+ clienttype = RFIFOB(fd, 8);
+ }
+ else
+ {
+ version = RFIFOL(fd,2);
+ safestrncpy(username, (const char*)RFIFOP(fd,6), NAME_LENGTH);
+ if( israwpass )
+ {
+ safestrncpy(password, (const char*)RFIFOP(fd,30), NAME_LENGTH);
+ clienttype = RFIFOB(fd,54);
+ }
+ else
+ {
+ memcpy(passhash, RFIFOP(fd,30), 16);
+ clienttype = RFIFOB(fd,46);
+ }
+ }
+ RFIFOSKIP(fd,RFIFOREST(fd)); // assume no other packet was sent
+
+ sd->clienttype = clienttype;
+ sd->version = version;
+ safestrncpy(sd->userid, username, NAME_LENGTH);
+ if( israwpass )
+ {
+ ShowStatus("Request for connection of %s (ip: %s).\n", sd->userid, ip);
+ safestrncpy(sd->passwd, password, NAME_LENGTH);
+ if( login_config.use_md5_passwds )
+ MD5_String(sd->passwd, sd->passwd);
+ sd->passwdenc = 0;
+ }
+ else
+ {
+ ShowStatus("Request for connection (passwdenc mode) of %s (ip: %s).\n", sd->userid, ip);
+ bin2hex(sd->passwd, passhash, 16); // raw binary data here!
+ sd->passwdenc = PASSWORDENC;
+ }
+
+ if( sd->passwdenc != 0 && login_config.use_md5_passwds )
+ {
+ login_auth_failed(sd, 3); // send "rejected from server"
+ return 0;
+ }
+
+ result = mmo_auth(sd, false);
+
+ if( result == -1 )
+ login_auth_ok(sd);
+ else
+ login_auth_failed(sd, result);
+ }
+ break;
+
+ case 0x01db: // Sending request of the coding key
+ RFIFOSKIP(fd,2);
+ {
+ memset(sd->md5key, '\0', sizeof(sd->md5key));
+ sd->md5keylen = (uint16)(12 + rnd() % 4);
+ MD5_Salt(sd->md5keylen, sd->md5key);
+
+ WFIFOHEAD(fd,4 + sd->md5keylen);
+ WFIFOW(fd,0) = 0x01dc;
+ WFIFOW(fd,2) = 4 + sd->md5keylen;
+ memcpy(WFIFOP(fd,4), sd->md5key, sd->md5keylen);
+ WFIFOSET(fd,WFIFOW(fd,2));
+ }
+ break;
+
+ case 0x2710: // Connection request of a char-server
+ if (RFIFOREST(fd) < 86)
+ return 0;
+ {
+ char server_name[20];
+ char message[256];
+ uint32 server_ip;
+ uint16 server_port;
+ uint16 type;
+ uint16 new_;
+
+ safestrncpy(sd->userid, (char*)RFIFOP(fd,2), NAME_LENGTH);
+ safestrncpy(sd->passwd, (char*)RFIFOP(fd,26), NAME_LENGTH);
+ if( login_config.use_md5_passwds )
+ MD5_String(sd->passwd, sd->passwd);
+ sd->passwdenc = 0;
+ sd->version = login_config.client_version_to_connect; // hack to skip version check
+ server_ip = ntohl(RFIFOL(fd,54));
+ server_port = ntohs(RFIFOW(fd,58));
+ safestrncpy(server_name, (char*)RFIFOP(fd,60), 20);
+ type = RFIFOW(fd,82);
+ new_ = RFIFOW(fd,84);
+ RFIFOSKIP(fd,86);
+
+ ShowInfo("Connection request of the char-server '%s' @ %u.%u.%u.%u:%u (account: '%s', pass: '%s', ip: '%s')\n", server_name, CONVIP(server_ip), server_port, sd->userid, sd->passwd, ip);
+ sprintf(message, "charserver - %s@%u.%u.%u.%u:%u", server_name, CONVIP(server_ip), server_port);
+ login_log(session[fd]->client_addr, sd->userid, 100, message);
+
+ result = mmo_auth(sd, true);
+ if( runflag == LOGINSERVER_ST_RUNNING &&
+ result == -1 &&
+ sd->sex == 'S' &&
+ sd->account_id >= 0 && sd->account_id < ARRAYLENGTH(server) &&
+ !session_isValid(server[sd->account_id].fd) )
+ {
+ ShowStatus("Connection of the char-server '%s' accepted.\n", server_name);
+ safestrncpy(server[sd->account_id].name, server_name, sizeof(server[sd->account_id].name));
+ server[sd->account_id].fd = fd;
+ server[sd->account_id].ip = server_ip;
+ server[sd->account_id].port = server_port;
+ server[sd->account_id].users = 0;
+ server[sd->account_id].type = type;
+ server[sd->account_id].new_ = new_;
+
+ session[fd]->func_parse = parse_fromchar;
+ session[fd]->flag.server = 1;
+ realloc_fifo(fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
+
+ // send connection success
+ WFIFOHEAD(fd,3);
+ WFIFOW(fd,0) = 0x2711;
+ WFIFOB(fd,2) = 0;
+ WFIFOSET(fd,3);
+ }
+ else
+ {
+ ShowNotice("Connection of the char-server '%s' REFUSED.\n", server_name);
+ WFIFOHEAD(fd,3);
+ WFIFOW(fd,0) = 0x2711;
+ WFIFOB(fd,2) = 3;
+ WFIFOSET(fd,3);
+ }
+ }
+ return 0; // processing will continue elsewhere
+
+ default:
+ ShowNotice("Abnormal end of connection (ip: %s): Unknown packet 0x%x\n", ip, command);
+ set_eof(fd);
+ return 0;
+ }
+ }
+
+ return 0;
}
void login_set_defaults()
{
- login_config.login_ip = INADDR_ANY;
- login_config.login_port = 6900;
- login_config.ipban_cleanup_interval = 60;
- login_config.ip_sync_interval = 0;
- login_config.log_login = true;
- safestrncpy(login_config.date_format, "%Y-%m-%d %H:%M:%S", sizeof(login_config.date_format));
- login_config.console = false;
- login_config.new_account_flag = true;
- login_config.new_acc_length_limit = true;
- login_config.use_md5_passwds = false;
- login_config.group_id_to_connect = -1;
- login_config.min_group_id_to_connect = -1;
- login_config.check_client_version = false;
- login_config.client_version_to_connect = 20;
-
- login_config.ipban = true;
- login_config.dynamic_pass_failure_ban = true;
- login_config.dynamic_pass_failure_ban_interval = 5;
- login_config.dynamic_pass_failure_ban_limit = 7;
- login_config.dynamic_pass_failure_ban_duration = 5;
- login_config.use_dnsbl = false;
- safestrncpy(login_config.dnsbl_servs, "", sizeof(login_config.dnsbl_servs));
- safestrncpy(login_config.account_engine, "auto", sizeof(login_config.account_engine));
-
- login_config.client_hash_check = 0;
- login_config.client_hash_nodes = NULL;
+ login_config.login_ip = INADDR_ANY;
+ login_config.login_port = 6900;
+ login_config.ipban_cleanup_interval = 60;
+ login_config.ip_sync_interval = 0;
+ login_config.log_login = true;
+ safestrncpy(login_config.date_format, "%Y-%m-%d %H:%M:%S", sizeof(login_config.date_format));
+ login_config.console = false;
+ login_config.new_account_flag = true;
+ login_config.new_acc_length_limit = true;
+ login_config.use_md5_passwds = false;
+ login_config.group_id_to_connect = -1;
+ login_config.min_group_id_to_connect = -1;
+ login_config.check_client_version = false;
+ login_config.client_version_to_connect = 20;
+
+ login_config.ipban = true;
+ login_config.dynamic_pass_failure_ban = true;
+ login_config.dynamic_pass_failure_ban_interval = 5;
+ login_config.dynamic_pass_failure_ban_limit = 7;
+ login_config.dynamic_pass_failure_ban_duration = 5;
+ login_config.use_dnsbl = false;
+ safestrncpy(login_config.dnsbl_servs, "", sizeof(login_config.dnsbl_servs));
+ safestrncpy(login_config.account_engine, "auto", sizeof(login_config.account_engine));
+
+ login_config.client_hash_check = 0;
+ login_config.client_hash_nodes = NULL;
}
//-----------------------------------
// Reading main configuration file
//-----------------------------------
-int login_config_read(const char *cfgName)
+int login_config_read(const char* cfgName)
{
- char line[1024], w1[1024], w2[1024];
- FILE *fp = fopen(cfgName, "r");
- if (fp == NULL) {
- ShowError("Configuration file (%s) not found.\n", cfgName);
- return 1;
- }
- while (fgets(line, sizeof(line), fp)) {
- if (line[0] == '/' && line[1] == '/')
- continue;
-
- if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) < 2)
- continue;
-
- if (!strcmpi(w1,"timestamp_format"))
- strncpy(timestamp_format, w2, 20);
- else if (!strcmpi(w1,"stdout_with_ansisequence"))
- stdout_with_ansisequence = config_switch(w2);
- else if (!strcmpi(w1,"console_silent")) {
- msg_silent = atoi(w2);
- if (msg_silent) /* only bother if we actually have this enabled */
- ShowInfo("Console Silent Setting: %d\n", atoi(w2));
- } else if (!strcmpi(w1, "bind_ip")) {
- char ip_str[16];
- login_config.login_ip = host2ip(w2);
- if (login_config.login_ip)
- ShowStatus("Login server binding IP address : %s -> %s\n", w2, ip2str(login_config.login_ip, ip_str));
- } else if (!strcmpi(w1, "login_port")) {
- login_config.login_port = (uint16)atoi(w2);
- } else if (!strcmpi(w1, "log_login"))
- login_config.log_login = (bool)config_switch(w2);
-
- else if (!strcmpi(w1, "new_account"))
- login_config.new_account_flag = (bool)config_switch(w2);
- else if (!strcmpi(w1, "new_acc_length_limit"))
- login_config.new_acc_length_limit = (bool)config_switch(w2);
- else if (!strcmpi(w1, "start_limited_time"))
- login_config.start_limited_time = atoi(w2);
- else if (!strcmpi(w1, "check_client_version"))
- login_config.check_client_version = (bool)config_switch(w2);
- else if (!strcmpi(w1, "client_version_to_connect"))
- login_config.client_version_to_connect = strtoul(w2, NULL, 10);
- else if (!strcmpi(w1, "use_MD5_passwords"))
- login_config.use_md5_passwds = (bool)config_switch(w2);
- else if (!strcmpi(w1, "group_id_to_connect"))
- login_config.group_id_to_connect = atoi(w2);
- else if (!strcmpi(w1, "min_group_id_to_connect"))
- login_config.min_group_id_to_connect = atoi(w2);
- else if (!strcmpi(w1, "date_format"))
- safestrncpy(login_config.date_format, w2, sizeof(login_config.date_format));
- else if (!strcmpi(w1, "console"))
- login_config.console = (bool)config_switch(w2);
- else if (!strcmpi(w1, "allowed_regs")) //account flood protection system
- allowed_regs = atoi(w2);
- else if (!strcmpi(w1, "time_allowed"))
- time_allowed = atoi(w2);
- else if (!strcmpi(w1, "use_dnsbl"))
- login_config.use_dnsbl = (bool)config_switch(w2);
- else if (!strcmpi(w1, "dnsbl_servers"))
- safestrncpy(login_config.dnsbl_servs, w2, sizeof(login_config.dnsbl_servs));
- else if (!strcmpi(w1, "ipban_cleanup_interval"))
- login_config.ipban_cleanup_interval = (unsigned int)atoi(w2);
- else if (!strcmpi(w1, "ip_sync_interval"))
- login_config.ip_sync_interval = (unsigned int)1000*60*atoi(w2); //w2 comes in minutes.
- else if (!strcmpi(w1, "client_hash_check"))
- login_config.client_hash_check = config_switch(w2);
- else if (!strcmpi(w1, "client_hash")) {
- int group = 0;
- char md5[33];
- int i;
-
- if (sscanf(w2, "%d, %32s", &group, md5) == 2) {
- struct client_hash_node *nnode;
- CREATE(nnode, struct client_hash_node, 1);
-
- for (i = 0; i < 32; i += 2) {
- char buf[3];
- unsigned int byte;
-
- memcpy(buf, &md5[i], 2);
- buf[2] = 0;
-
- sscanf(buf, "%x", &byte);
- nnode->hash[i / 2] = (uint8)(byte & 0xFF);
- }
-
- nnode->group_id = group;
- nnode->next = login_config.client_hash_nodes;
-
- login_config.client_hash_nodes = nnode;
- }
- } else if (!strcmpi(w1, "import"))
- login_config_read(w2);
- else if (!strcmpi(w1, "account.engine"))
- safestrncpy(login_config.account_engine, w2, sizeof(login_config.account_engine));
- else {
- // try the account engines
- int i;
- for (i = 0; account_engines[i].constructor; ++i) {
- AccountDB *db = account_engines[i].db;
- if (db && db->set_property(db, w1, w2))
- break;
- }
- // try others
- ipban_config_read(w1, w2);
- loginlog_config_read(w1, w2);
- }
- }
- fclose(fp);
- ShowInfo("Finished reading %s.\n", cfgName);
- return 0;
+ char line[1024], w1[1024], w2[1024];
+ FILE* fp = fopen(cfgName, "r");
+ if (fp == NULL) {
+ ShowError("Configuration file (%s) not found.\n", cfgName);
+ return 1;
+ }
+ while(fgets(line, sizeof(line), fp)) {
+ if (line[0] == '/' && line[1] == '/')
+ continue;
+
+ if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) < 2)
+ continue;
+
+ if(!strcmpi(w1,"timestamp_format"))
+ strncpy(timestamp_format, w2, 20);
+ else if(!strcmpi(w1,"stdout_with_ansisequence"))
+ stdout_with_ansisequence = config_switch(w2);
+ else if(!strcmpi(w1,"console_silent")) {
+ msg_silent = atoi(w2);
+ if( msg_silent ) /* only bother if we actually have this enabled */
+ ShowInfo("Console Silent Setting: %d\n", atoi(w2));
+ }
+ else if( !strcmpi(w1, "bind_ip") ) {
+ char ip_str[16];
+ login_config.login_ip = host2ip(w2);
+ if( login_config.login_ip )
+ ShowStatus("Login server binding IP address : %s -> %s\n", w2, ip2str(login_config.login_ip, ip_str));
+ }
+ else if( !strcmpi(w1, "login_port") ) {
+ login_config.login_port = (uint16)atoi(w2);
+ }
+ else if(!strcmpi(w1, "log_login"))
+ login_config.log_login = (bool)config_switch(w2);
+
+ else if(!strcmpi(w1, "new_account"))
+ login_config.new_account_flag = (bool)config_switch(w2);
+ else if(!strcmpi(w1, "new_acc_length_limit"))
+ login_config.new_acc_length_limit = (bool)config_switch(w2);
+ else if(!strcmpi(w1, "start_limited_time"))
+ login_config.start_limited_time = atoi(w2);
+ else if(!strcmpi(w1, "check_client_version"))
+ login_config.check_client_version = (bool)config_switch(w2);
+ else if(!strcmpi(w1, "client_version_to_connect"))
+ login_config.client_version_to_connect = strtoul(w2, NULL, 10);
+ else if(!strcmpi(w1, "use_MD5_passwords"))
+ login_config.use_md5_passwds = (bool)config_switch(w2);
+ else if(!strcmpi(w1, "group_id_to_connect"))
+ login_config.group_id_to_connect = atoi(w2);
+ else if(!strcmpi(w1, "min_group_id_to_connect"))
+ login_config.min_group_id_to_connect = atoi(w2);
+ else if(!strcmpi(w1, "date_format"))
+ safestrncpy(login_config.date_format, w2, sizeof(login_config.date_format));
+ else if(!strcmpi(w1, "console"))
+ login_config.console = (bool)config_switch(w2);
+ else if(!strcmpi(w1, "allowed_regs")) //account flood protection system
+ allowed_regs = atoi(w2);
+ else if(!strcmpi(w1, "time_allowed"))
+ time_allowed = atoi(w2);
+ else if(!strcmpi(w1, "use_dnsbl"))
+ login_config.use_dnsbl = (bool)config_switch(w2);
+ else if(!strcmpi(w1, "dnsbl_servers"))
+ safestrncpy(login_config.dnsbl_servs, w2, sizeof(login_config.dnsbl_servs));
+ else if(!strcmpi(w1, "ipban_cleanup_interval"))
+ login_config.ipban_cleanup_interval = (unsigned int)atoi(w2);
+ else if(!strcmpi(w1, "ip_sync_interval"))
+ login_config.ip_sync_interval = (unsigned int)1000*60*atoi(w2); //w2 comes in minutes.
+ else if(!strcmpi(w1, "client_hash_check"))
+ login_config.client_hash_check = config_switch(w2);
+ else if(!strcmpi(w1, "client_hash")) {
+ int group = 0;
+ char md5[33];
+ int i;
+
+ if (sscanf(w2, "%d, %32s", &group, md5) == 2) {
+ struct client_hash_node *nnode;
+ CREATE(nnode, struct client_hash_node, 1);
+
+ for (i = 0; i < 32; i += 2) {
+ char buf[3];
+ unsigned int byte;
+
+ memcpy(buf, &md5[i], 2);
+ buf[2] = 0;
+
+ sscanf(buf, "%x", &byte);
+ nnode->hash[i / 2] = (uint8)(byte & 0xFF);
+ }
+
+ nnode->group_id = group;
+ nnode->next = login_config.client_hash_nodes;
+
+ login_config.client_hash_nodes = nnode;
+ }
+ }
+ else if(!strcmpi(w1, "import"))
+ login_config_read(w2);
+ else
+ if(!strcmpi(w1, "account.engine"))
+ safestrncpy(login_config.account_engine, w2, sizeof(login_config.account_engine));
+ else
+ {// try the account engines
+ int i;
+ for( i = 0; account_engines[i].constructor; ++i )
+ {
+ AccountDB* db = account_engines[i].db;
+ if( db && db->set_property(db, w1, w2) )
+ break;
+ }
+ // try others
+ ipban_config_read(w1, w2);
+ loginlog_config_read(w1, w2);
+ }
+ }
+ fclose(fp);
+ ShowInfo("Finished reading %s.\n", cfgName);
+ return 0;
}
/// Get the engine selected in the config settings.
/// Updates the config setting with the selected engine if 'auto'.
-static AccountDB *get_account_engine(void)
+static AccountDB* get_account_engine(void)
{
- int i;
- bool get_first = (strcmp(login_config.account_engine,"auto") == 0);
-
- for (i = 0; account_engines[i].constructor; ++i) {
- char name[sizeof(login_config.account_engine)];
- AccountDB *db = account_engines[i].db;
- if (db && db->get_property(db, "engine.name", name, sizeof(name)) &&
- (get_first || strcmp(name, login_config.account_engine) == 0)) {
- if (get_first)
- safestrncpy(login_config.account_engine, name, sizeof(login_config.account_engine));
- return db;
- }
- }
- return NULL;
+ int i;
+ bool get_first = (strcmp(login_config.account_engine,"auto") == 0);
+
+ for( i = 0; account_engines[i].constructor; ++i )
+ {
+ char name[sizeof(login_config.account_engine)];
+ AccountDB* db = account_engines[i].db;
+ if( db && db->get_property(db, "engine.name", name, sizeof(name)) &&
+ (get_first || strcmp(name, login_config.account_engine) == 0) )
+ {
+ if( get_first )
+ safestrncpy(login_config.account_engine, name, sizeof(login_config.account_engine));
+ return db;
+ }
+ }
+ return NULL;
}
//--------------------------------------
@@ -1695,44 +1727,47 @@ static AccountDB *get_account_engine(void)
//--------------------------------------
void do_final(void)
{
- int i;
- struct client_hash_node *hn = login_config.client_hash_nodes;
-
- while (hn) {
- struct client_hash_node *tmp = hn;
- hn = hn->next;
- aFree(tmp);
- }
-
- login_log(0, "login server", 100, "login server shutdown");
- ShowStatus("Terminating...\n");
-
- if (login_config.log_login)
- loginlog_final();
-
- ipban_final();
-
- for (i = 0; account_engines[i].constructor; ++i) {
- // destroy all account engines
- AccountDB *db = account_engines[i].db;
- if (db) {
- db->destroy(db);
- account_engines[i].db = NULL;
- }
- }
- accounts = NULL; // destroyed in account_engines
- online_db->destroy(online_db, NULL);
- auth_db->destroy(auth_db, NULL);
-
- for (i = 0; i < ARRAYLENGTH(server); ++i)
- chrif_server_destroy(i);
-
- if (login_fd != -1) {
- do_close(login_fd);
- login_fd = -1;
- }
-
- ShowStatus("Finished.\n");
+ int i;
+ struct client_hash_node *hn = login_config.client_hash_nodes;
+
+ while (hn)
+ {
+ struct client_hash_node *tmp = hn;
+ hn = hn->next;
+ aFree(tmp);
+ }
+
+ login_log(0, "login server", 100, "login server shutdown");
+ ShowStatus("Terminating...\n");
+
+ if( login_config.log_login )
+ loginlog_final();
+
+ ipban_final();
+
+ for( i = 0; account_engines[i].constructor; ++i )
+ {// destroy all account engines
+ AccountDB* db = account_engines[i].db;
+ if( db )
+ {
+ db->destroy(db);
+ account_engines[i].db = NULL;
+ }
+ }
+ accounts = NULL; // destroyed in account_engines
+ online_db->destroy(online_db, NULL);
+ auth_db->destroy(auth_db, NULL);
+
+ for( i = 0; i < ARRAYLENGTH(server); ++i )
+ chrif_server_destroy(i);
+
+ if( login_fd != -1 )
+ {
+ do_close(login_fd);
+ login_fd = -1;
+ }
+
+ ShowStatus("Finished.\n");
}
//------------------------------
@@ -1745,101 +1780,104 @@ void do_abort(void)
void set_server_type(void)
{
- SERVER_TYPE = ATHENA_SERVER_LOGIN;
+ SERVER_TYPE = ATHENA_SERVER_LOGIN;
}
/// Called when a terminate signal is received.
void do_shutdown(void)
{
- if (runflag != LOGINSERVER_ST_SHUTDOWN) {
- int id;
- runflag = LOGINSERVER_ST_SHUTDOWN;
- ShowStatus("Shutting down...\n");
- // TODO proper shutdown procedure; kick all characters, wait for acks, ... [FlavioJS]
- for (id = 0; id < ARRAYLENGTH(server); ++id)
- chrif_server_reset(id);
- flush_fifos();
- runflag = CORE_ST_STOP;
- }
+ if( runflag != LOGINSERVER_ST_SHUTDOWN )
+ {
+ int id;
+ runflag = LOGINSERVER_ST_SHUTDOWN;
+ ShowStatus("Shutting down...\n");
+ // TODO proper shutdown procedure; kick all characters, wait for acks, ... [FlavioJS]
+ for( id = 0; id < ARRAYLENGTH(server); ++id )
+ chrif_server_reset(id);
+ flush_fifos();
+ runflag = CORE_ST_STOP;
+ }
}
//------------------------------
// Login server initialization
//------------------------------
-int do_init(int argc, char **argv)
+int do_init(int argc, char** argv)
{
- int i;
-
- // intialize engines (to accept config settings)
- for (i = 0; account_engines[i].constructor; ++i)
- account_engines[i].db = account_engines[i].constructor();
-
- // read login-server configuration
- login_set_defaults();
- login_config_read((argc > 1) ? argv[1] : LOGIN_CONF_NAME);
- login_lan_config_read((argc > 2) ? argv[2] : LAN_CONF_NAME);
-
- rnd_init();
-
- for (i = 0; i < ARRAYLENGTH(server); ++i)
- chrif_server_init(i);
-
- // initialize logging
- if (login_config.log_login)
- loginlog_init();
-
- // initialize static and dynamic ipban system
- ipban_init();
-
- // Online user database init
- online_db = idb_alloc(DB_OPT_RELEASE_DATA);
- add_timer_func_list(waiting_disconnect_timer, "waiting_disconnect_timer");
-
- // Interserver auth init
- auth_db = idb_alloc(DB_OPT_RELEASE_DATA);
-
- // set default parser as parse_login function
- set_defaultparse(parse_login);
-
- // every 10 minutes cleanup online account db.
- add_timer_func_list(online_data_cleanup, "online_data_cleanup");
- add_timer_interval(gettick() + 600*1000, online_data_cleanup, 0, 0, 600*1000);
-
- // add timer to detect ip address change and perform update
- if (login_config.ip_sync_interval) {
- add_timer_func_list(sync_ip_addresses, "sync_ip_addresses");
- add_timer_interval(gettick() + login_config.ip_sync_interval, sync_ip_addresses, 0, 0, login_config.ip_sync_interval);
- }
-
- // Account database init
- accounts = get_account_engine();
- if (accounts == NULL) {
- ShowFatalError("do_init: account engine '%s' not found.\n", login_config.account_engine);
- exit(EXIT_FAILURE);
- } else {
-
- if (!accounts->init(accounts)) {
- ShowFatalError("do_init: Failed to initialize account engine '%s'.\n", login_config.account_engine);
- exit(EXIT_FAILURE);
- }
- }
-
- if (login_config.console) {
- //##TODO invoke a CONSOLE_START plugin event
- }
-
- // server port open & binding
- login_fd = make_listen_bind(login_config.login_ip, login_config.login_port);
-
- if (runflag != CORE_ST_STOP) {
- shutdown_callback = do_shutdown;
- runflag = LOGINSERVER_ST_RUNNING;
- }
-
- ShowStatus("The login-server is "CL_GREEN"ready"CL_RESET" (Server is listening on the port %u).\n\n", login_config.login_port);
- login_log(0, "login server", 100, "login server started");
-
- return 0;
+ int i;
+
+ // intialize engines (to accept config settings)
+ for( i = 0; account_engines[i].constructor; ++i )
+ account_engines[i].db = account_engines[i].constructor();
+
+ // read login-server configuration
+ login_set_defaults();
+ login_config_read((argc > 1) ? argv[1] : LOGIN_CONF_NAME);
+ login_lan_config_read((argc > 2) ? argv[2] : LAN_CONF_NAME);
+
+ rnd_init();
+
+ for( i = 0; i < ARRAYLENGTH(server); ++i )
+ chrif_server_init(i);
+
+ // initialize logging
+ if( login_config.log_login )
+ loginlog_init();
+
+ // initialize static and dynamic ipban system
+ ipban_init();
+
+ // Online user database init
+ online_db = idb_alloc(DB_OPT_RELEASE_DATA);
+ add_timer_func_list(waiting_disconnect_timer, "waiting_disconnect_timer");
+
+ // Interserver auth init
+ auth_db = idb_alloc(DB_OPT_RELEASE_DATA);
+
+ // set default parser as parse_login function
+ set_defaultparse(parse_login);
+
+ // every 10 minutes cleanup online account db.
+ add_timer_func_list(online_data_cleanup, "online_data_cleanup");
+ add_timer_interval(gettick() + 600*1000, online_data_cleanup, 0, 0, 600*1000);
+
+ // add timer to detect ip address change and perform update
+ if (login_config.ip_sync_interval) {
+ add_timer_func_list(sync_ip_addresses, "sync_ip_addresses");
+ add_timer_interval(gettick() + login_config.ip_sync_interval, sync_ip_addresses, 0, 0, login_config.ip_sync_interval);
+ }
+
+ // Account database init
+ accounts = get_account_engine();
+ if( accounts == NULL ) {
+ ShowFatalError("do_init: account engine '%s' not found.\n", login_config.account_engine);
+ exit(EXIT_FAILURE);
+ } else {
+
+ if(!accounts->init(accounts)) {
+ ShowFatalError("do_init: Failed to initialize account engine '%s'.\n", login_config.account_engine);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if( login_config.console )
+ {
+ //##TODO invoke a CONSOLE_START plugin event
+ }
+
+ // server port open & binding
+ login_fd = make_listen_bind(login_config.login_ip, login_config.login_port);
+
+ if( runflag != CORE_ST_STOP )
+ {
+ shutdown_callback = do_shutdown;
+ runflag = LOGINSERVER_ST_RUNNING;
+ }
+
+ ShowStatus("The login-server is "CL_GREEN"ready"CL_RESET" (Server is listening on the port %u).\n\n", login_config.login_port);
+ login_log(0, "login server", 100, "login server started");
+
+ return 0;
}
diff --git a/src/login/login.h b/src/login/login.h
index 97335aa89..bedf5e179 100644
--- a/src/login/login.h
+++ b/src/login/login.h
@@ -7,10 +7,11 @@
#include "../common/mmo.h" // NAME_LENGTH,SEX_*
#include "../common/core.h" // CORE_ST_LAST
-enum E_LOGINSERVER_ST {
- LOGINSERVER_ST_RUNNING = CORE_ST_LAST,
- LOGINSERVER_ST_SHUTDOWN,
- LOGINSERVER_ST_LAST
+enum E_LOGINSERVER_ST
+{
+ LOGINSERVER_ST_RUNNING = CORE_ST_LAST,
+ LOGINSERVER_ST_SHUTDOWN,
+ LOGINSERVER_ST_LAST
};
#define LOGIN_CONF_NAME "conf/login_athena.conf"
@@ -20,74 +21,74 @@ enum E_LOGINSERVER_ST {
#define PASSWORDENC 3
struct login_session_data {
- int account_id;
- long login_id1;
- long login_id2;
- char sex;// 'F','M','S'
-
- char userid[NAME_LENGTH];
- char passwd[32+1]; // 23+1 for plaintext, 32+1 for md5-ed passwords
- int passwdenc;
- char md5key[20];
- uint16 md5keylen;
-
- char lastlogin[24];
- uint8 group_id;
- uint8 clienttype;
- uint32 version;
-
- uint8 client_hash[16];
- int has_client_hash;
-
- int fd;
+ int account_id;
+ long login_id1;
+ long login_id2;
+ char sex;// 'F','M','S'
+
+ char userid[NAME_LENGTH];
+ char passwd[32+1]; // 23+1 for plaintext, 32+1 for md5-ed passwords
+ int passwdenc;
+ char md5key[20];
+ uint16 md5keylen;
+
+ char lastlogin[24];
+ uint8 group_id;
+ uint8 clienttype;
+ uint32 version;
+
+ uint8 client_hash[16];
+ int has_client_hash;
+
+ int fd;
};
struct mmo_char_server {
- char name[20];
- int fd;
- uint32 ip;
- uint16 port;
- uint16 users; // user count on this server
- uint16 type; // 0=normal, 1=maintenance, 2=over 18, 3=paying, 4=P2P
- uint16 new_; // should display as 'new'?
+ char name[20];
+ int fd;
+ uint32 ip;
+ uint16 port;
+ uint16 users; // user count on this server
+ uint16 type; // 0=normal, 1=maintenance, 2=over 18, 3=paying, 4=P2P
+ uint16 new_; // should display as 'new'?
};
struct client_hash_node {
- int group_id;
- uint8 hash[16];
- struct client_hash_node *next;
+ int group_id;
+ uint8 hash[16];
+ struct client_hash_node *next;
};
struct Login_Config {
- uint32 login_ip; // the address to bind to
- uint16 login_port; // the port to bind to
- unsigned int ipban_cleanup_interval; // interval (in seconds) to clean up expired IP bans
- unsigned int ip_sync_interval; // interval (in minutes) to execute a DNS/IP update (for dynamic IPs)
- bool log_login; // whether to log login server actions or not
- char date_format[32]; // date format used in messages
- bool console; // console input system enabled?
- bool new_account_flag,new_acc_length_limit; // autoregistration via _M/_F ? / if yes minimum length is 4?
- int start_limited_time; // new account expiration time (-1: unlimited)
- bool use_md5_passwds; // work with password hashes instead of plaintext passwords?
- int group_id_to_connect; // required group id to connect
- int min_group_id_to_connect; // minimum group id to connect
- bool check_client_version; // check the clientversion set in the clientinfo ?
- uint32 client_version_to_connect; // the client version needed to connect (if checking is enabled)
-
- bool ipban; // perform IP blocking (via contents of `ipbanlist`) ?
- bool dynamic_pass_failure_ban; // automatic IP blocking due to failed login attemps ?
- unsigned int dynamic_pass_failure_ban_interval; // how far to scan the loginlog for password failures
- unsigned int dynamic_pass_failure_ban_limit; // number of failures needed to trigger the ipban
- unsigned int dynamic_pass_failure_ban_duration; // duration of the ipban
- bool use_dnsbl; // dns blacklist blocking ?
- char dnsbl_servs[1024]; // comma-separated list of dnsbl servers
-
- char account_engine[256]; // name of the engine to use (defaults to auto, for the first available engine)
-
- int client_hash_check; // flags for checking client md5
- struct client_hash_node *client_hash_nodes; // linked list containg md5 hash for each gm group
+ uint32 login_ip; // the address to bind to
+ uint16 login_port; // the port to bind to
+ unsigned int ipban_cleanup_interval; // interval (in seconds) to clean up expired IP bans
+ unsigned int ip_sync_interval; // interval (in minutes) to execute a DNS/IP update (for dynamic IPs)
+ bool log_login; // whether to log login server actions or not
+ char date_format[32]; // date format used in messages
+ bool console; // console input system enabled?
+ bool new_account_flag,new_acc_length_limit; // autoregistration via _M/_F ? / if yes minimum length is 4?
+ int start_limited_time; // new account expiration time (-1: unlimited)
+ bool use_md5_passwds; // work with password hashes instead of plaintext passwords?
+ int group_id_to_connect; // required group id to connect
+ int min_group_id_to_connect; // minimum group id to connect
+ bool check_client_version; // check the clientversion set in the clientinfo ?
+ uint32 client_version_to_connect; // the client version needed to connect (if checking is enabled)
+
+ bool ipban; // perform IP blocking (via contents of `ipbanlist`) ?
+ bool dynamic_pass_failure_ban; // automatic IP blocking due to failed login attemps ?
+ unsigned int dynamic_pass_failure_ban_interval; // how far to scan the loginlog for password failures
+ unsigned int dynamic_pass_failure_ban_limit; // number of failures needed to trigger the ipban
+ unsigned int dynamic_pass_failure_ban_duration; // duration of the ipban
+ bool use_dnsbl; // dns blacklist blocking ?
+ char dnsbl_servs[1024]; // comma-separated list of dnsbl servers
+
+ char account_engine[256]; // name of the engine to use (defaults to auto, for the first available engine)
+
+ int client_hash_check; // flags for checking client md5
+ struct client_hash_node *client_hash_nodes; // linked list containg md5 hash for each gm group
};
#define sex_num2str(num) ( (num == SEX_FEMALE ) ? 'F' : (num == SEX_MALE ) ? 'M' : 'S' )
diff --git a/src/login/loginlog.h b/src/login/loginlog.h
index 63621c50a..a1ffaae85 100644
--- a/src/login/loginlog.h
+++ b/src/login/loginlog.h
@@ -6,10 +6,10 @@
unsigned long loginlog_failedattempts(uint32 ip, unsigned int minutes);
-void login_log(uint32 ip, const char *username, int rcode, const char *message);
+void login_log(uint32 ip, const char* username, int rcode, const char* message);
bool loginlog_init(void);
bool loginlog_final(void);
-bool loginlog_config_read(const char *w1, const char *w2);
+bool loginlog_config_read(const char* w1, const char* w2);
#endif // __LOGINLOG_H_INCLUDED__
diff --git a/src/login/loginlog_sql.c b/src/login/loginlog_sql.c
index 2d8a17528..d61172697 100644
--- a/src/login/loginlog_sql.c
+++ b/src/login/loginlog_sql.c
@@ -25,145 +25,160 @@ static char log_db_database[32] = "";
static char log_codepage[32] = "";
static char log_login_db[256] = "loginlog";
-static Sql *sql_handle = NULL;
+static Sql* sql_handle = NULL;
static bool enabled = false;
// Returns the number of failed login attemps by the ip in the last minutes.
unsigned long loginlog_failedattempts(uint32 ip, unsigned int minutes)
{
- unsigned long failures = 0;
-
- if (!enabled)
- return 0;
-
- if (SQL_ERROR == Sql_Query(sql_handle, "SELECT count(*) FROM `%s` WHERE `ip` = '%s' AND `rcode` = '1' AND `time` > NOW() - INTERVAL %d MINUTE",
- log_login_db, ip2str(ip,NULL), minutes)) // how many times failed account? in one ip.
- Sql_ShowDebug(sql_handle);
-
- if (SQL_SUCCESS == Sql_NextRow(sql_handle)) {
- char *data;
- Sql_GetData(sql_handle, 0, &data, NULL);
- failures = strtoul(data, NULL, 10);
- Sql_FreeResult(sql_handle);
- }
- return failures;
+ unsigned long failures = 0;
+
+ if( !enabled )
+ return 0;
+
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT count(*) FROM `%s` WHERE `ip` = '%s' AND `rcode` = '1' AND `time` > NOW() - INTERVAL %d MINUTE",
+ log_login_db, ip2str(ip,NULL), minutes) )// how many times failed account? in one ip.
+ Sql_ShowDebug(sql_handle);
+
+ if( SQL_SUCCESS == Sql_NextRow(sql_handle) )
+ {
+ char* data;
+ Sql_GetData(sql_handle, 0, &data, NULL);
+ failures = strtoul(data, NULL, 10);
+ Sql_FreeResult(sql_handle);
+ }
+ return failures;
}
/*=============================================
* Records an event in the login log
*---------------------------------------------*/
-void login_log(uint32 ip, const char *username, int rcode, const char *message)
+void login_log(uint32 ip, const char* username, int rcode, const char* message)
{
- char esc_username[NAME_LENGTH*2+1];
- char esc_message[255*2+1];
- int retcode;
+ char esc_username[NAME_LENGTH*2+1];
+ char esc_message[255*2+1];
+ int retcode;
- if (!enabled)
- return;
+ if( !enabled )
+ return;
- Sql_EscapeStringLen(sql_handle, esc_username, username, strnlen(username, NAME_LENGTH));
- Sql_EscapeStringLen(sql_handle, esc_message, message, strnlen(message, 255));
+ Sql_EscapeStringLen(sql_handle, esc_username, username, strnlen(username, NAME_LENGTH));
+ Sql_EscapeStringLen(sql_handle, esc_message, message, strnlen(message, 255));
- retcode = Sql_Query(sql_handle,
- "INSERT INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%s', '%s', '%d', '%s')",
- log_login_db, ip2str(ip,NULL), esc_username, rcode, esc_message);
+ retcode = Sql_Query(sql_handle,
+ "INSERT INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%s', '%s', '%d', '%s')",
+ log_login_db, ip2str(ip,NULL), esc_username, rcode, esc_message);
- if (retcode != SQL_SUCCESS)
- Sql_ShowDebug(sql_handle);
+ if( retcode != SQL_SUCCESS )
+ Sql_ShowDebug(sql_handle);
}
bool loginlog_init(void)
{
- const char *username;
- const char *password;
- const char *hostname;
- uint16 port;
- const char *database;
- const char *codepage;
-
- if (log_db_hostname[0] != '\0') {
- // local settings
- username = log_db_username;
- password = log_db_password;
- hostname = log_db_hostname;
- port = log_db_port;
- database = log_db_database;
- codepage = log_codepage;
- } else {
- // global settings
- username = global_db_username;
- password = global_db_password;
- hostname = global_db_hostname;
- port = global_db_port;
- database = global_db_database;
- codepage = global_codepage;
- }
-
- sql_handle = Sql_Malloc();
-
- if (SQL_ERROR == Sql_Connect(sql_handle, username, password, hostname, port, database)) {
- Sql_ShowDebug(sql_handle);
- Sql_Free(sql_handle);
- exit(EXIT_FAILURE);
- }
-
- if (codepage[0] != '\0' && SQL_ERROR == Sql_SetEncoding(sql_handle, codepage))
- Sql_ShowDebug(sql_handle);
-
- enabled = true;
-
- return true;
+ const char* username;
+ const char* password;
+ const char* hostname;
+ uint16 port;
+ const char* database;
+ const char* codepage;
+
+ if( log_db_hostname[0] != '\0' )
+ {// local settings
+ username = log_db_username;
+ password = log_db_password;
+ hostname = log_db_hostname;
+ port = log_db_port;
+ database = log_db_database;
+ codepage = log_codepage;
+ }
+ else
+ {// global settings
+ username = global_db_username;
+ password = global_db_password;
+ hostname = global_db_hostname;
+ port = global_db_port;
+ database = global_db_database;
+ codepage = global_codepage;
+ }
+
+ sql_handle = Sql_Malloc();
+
+ if( SQL_ERROR == Sql_Connect(sql_handle, username, password, hostname, port, database) )
+ {
+ Sql_ShowDebug(sql_handle);
+ Sql_Free(sql_handle);
+ exit(EXIT_FAILURE);
+ }
+
+ if( codepage[0] != '\0' && SQL_ERROR == Sql_SetEncoding(sql_handle, codepage) )
+ Sql_ShowDebug(sql_handle);
+
+ enabled = true;
+
+ return true;
}
bool loginlog_final(void)
{
- Sql_Free(sql_handle);
- sql_handle = NULL;
- return true;
+ Sql_Free(sql_handle);
+ sql_handle = NULL;
+ return true;
}
-bool loginlog_config_read(const char *key, const char *value)
+bool loginlog_config_read(const char* key, const char* value)
{
- const char *signature;
-
- signature = "sql.";
- if (strncmpi(key, signature, strlen(signature)) == 0) {
- key += strlen(signature);
- if (strcmpi(key, "db_hostname") == 0)
- safestrncpy(global_db_hostname, value, sizeof(global_db_hostname));
- else if (strcmpi(key, "db_port") == 0)
- global_db_port = (uint16)strtoul(value, NULL, 10);
- else if (strcmpi(key, "db_username") == 0)
- safestrncpy(global_db_username, value, sizeof(global_db_username));
- else if (strcmpi(key, "db_password") == 0)
- safestrncpy(global_db_password, value, sizeof(global_db_password));
- else if (strcmpi(key, "db_database") == 0)
- safestrncpy(global_db_database, value, sizeof(global_db_database));
- else if (strcmpi(key, "codepage") == 0)
- safestrncpy(global_codepage, value, sizeof(global_codepage));
- else
- return false;// not found
- return true;
- }
-
- if (strcmpi(key, "log_db_ip") == 0)
- safestrncpy(log_db_hostname, value, sizeof(log_db_hostname));
- else if (strcmpi(key, "log_db_port") == 0)
- log_db_port = (uint16)strtoul(value, NULL, 10);
- else if (strcmpi(key, "log_db_id") == 0)
- safestrncpy(log_db_username, value, sizeof(log_db_username));
- else if (strcmpi(key, "log_db_pw") == 0)
- safestrncpy(log_db_password, value, sizeof(log_db_password));
- else if (strcmpi(key, "log_db_db") == 0)
- safestrncpy(log_db_database, value, sizeof(log_db_database));
- else if (strcmpi(key, "log_codepage") == 0)
- safestrncpy(log_codepage, value, sizeof(log_codepage));
- else if (strcmpi(key, "log_login_db") == 0)
- safestrncpy(log_login_db, value, sizeof(log_login_db));
- else
- return false;
-
- return true;
+ const char* signature;
+
+ signature = "sql.";
+ if( strncmpi(key, signature, strlen(signature)) == 0 )
+ {
+ key += strlen(signature);
+ if( strcmpi(key, "db_hostname") == 0 )
+ safestrncpy(global_db_hostname, value, sizeof(global_db_hostname));
+ else
+ if( strcmpi(key, "db_port") == 0 )
+ global_db_port = (uint16)strtoul(value, NULL, 10);
+ else
+ if( strcmpi(key, "db_username") == 0 )
+ safestrncpy(global_db_username, value, sizeof(global_db_username));
+ else
+ if( strcmpi(key, "db_password") == 0 )
+ safestrncpy(global_db_password, value, sizeof(global_db_password));
+ else
+ if( strcmpi(key, "db_database") == 0 )
+ safestrncpy(global_db_database, value, sizeof(global_db_database));
+ else
+ if( strcmpi(key, "codepage") == 0 )
+ safestrncpy(global_codepage, value, sizeof(global_codepage));
+ else
+ return false;// not found
+ return true;
+ }
+
+ if( strcmpi(key, "log_db_ip") == 0 )
+ safestrncpy(log_db_hostname, value, sizeof(log_db_hostname));
+ else
+ if( strcmpi(key, "log_db_port") == 0 )
+ log_db_port = (uint16)strtoul(value, NULL, 10);
+ else
+ if( strcmpi(key, "log_db_id") == 0 )
+ safestrncpy(log_db_username, value, sizeof(log_db_username));
+ else
+ if( strcmpi(key, "log_db_pw") == 0 )
+ safestrncpy(log_db_password, value, sizeof(log_db_password));
+ else
+ if( strcmpi(key, "log_db_db") == 0 )
+ safestrncpy(log_db_database, value, sizeof(log_db_database));
+ else
+ if( strcmpi(key, "log_codepage") == 0 )
+ safestrncpy(log_codepage, value, sizeof(log_codepage));
+ else
+ if( strcmpi(key, "log_login_db") == 0 )
+ safestrncpy(log_login_db, value, sizeof(log_login_db));
+ else
+ return false;
+
+ return true;
}
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index a67c67108..394f4fb11 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -61,97 +61,100 @@ typedef struct AliasInfo AliasInfo;
int atcmd_binding_count = 0;
struct AtCommandInfo {
- char command[ATCOMMAND_LENGTH];
- AtCommandFunc func;
- char *at_groups;/* quick @commands "can-use" lookup */
- char *char_groups;/* quick @charcommands "can-use" lookup */
+ char command[ATCOMMAND_LENGTH];
+ AtCommandFunc func;
+ char* at_groups;/* quick @commands "can-use" lookup */
+ char* char_groups;/* quick @charcommands "can-use" lookup */
};
struct AliasInfo {
- AtCommandInfo *command;
- char alias[ATCOMMAND_LENGTH];
+ AtCommandInfo *command;
+ char alias[ATCOMMAND_LENGTH];
};
char atcommand_symbol = '@'; // first char of the commands
char charcommand_symbol = '#';
-static char *msg_table[MAX_MSG]; // Server messages (0-499 reserved for GM commands, 500-999 reserved for others)
-static DBMap *atcommand_db = NULL; //name -> AtCommandInfo
-static DBMap *atcommand_alias_db = NULL; //alias -> AtCommandInfo
+static char* msg_table[MAX_MSG]; // Server messages (0-499 reserved for GM commands, 500-999 reserved for others)
+static DBMap* atcommand_db = NULL; //name -> AtCommandInfo
+static DBMap* atcommand_alias_db = NULL; //alias -> AtCommandInfo
static config_t atcommand_config;
static char atcmd_output[CHAT_SIZE_MAX];
static char atcmd_player_name[NAME_LENGTH];
-static AtCommandInfo *get_atcommandinfo_byname(const char *name); // @help
-static const char *atcommand_checkalias(const char *aliasname); // @help
-static void atcommand_get_suggestions(struct map_session_data *sd, const char *name, bool atcommand); // @help
+static AtCommandInfo* get_atcommandinfo_byname(const char *name); // @help
+static const char* atcommand_checkalias(const char *aliasname); // @help
+static void atcommand_get_suggestions(struct map_session_data* sd, const char *name, bool atcommand); // @help
// @commands (script-based)
-struct atcmd_binding_data *get_atcommandbind_byname(const char *name) {
- int i = 0;
+struct atcmd_binding_data* get_atcommandbind_byname(const char* name) {
+ int i = 0;
- if (*name == atcommand_symbol || *name == charcommand_symbol)
- name++; // for backwards compatibility
+ if( *name == atcommand_symbol || *name == charcommand_symbol )
+ name++; // for backwards compatibility
- ARR_FIND(0, atcmd_binding_count, i, strcmp(atcmd_binding[i]->command, name) == 0);
+ ARR_FIND( 0, atcmd_binding_count, i, strcmp(atcmd_binding[i]->command, name) == 0 );
- return (i < atcmd_binding_count) ? atcmd_binding[i] : NULL;
+ return ( i < atcmd_binding_count ) ? atcmd_binding[i] : NULL;
}
//-----------------------------------------------------------
// Return the message string of the specified number by [Yor]
//-----------------------------------------------------------
-const char *msg_txt(int msg_number)
+const char* msg_txt(int msg_number)
{
- if (msg_number >= 0 && msg_number < MAX_MSG &&
- msg_table[msg_number] != NULL && msg_table[msg_number][0] != '\0')
- return msg_table[msg_number];
+ if (msg_number >= 0 && msg_number < MAX_MSG &&
+ msg_table[msg_number] != NULL && msg_table[msg_number][0] != '\0')
+ return msg_table[msg_number];
- return "??";
+ return "??";
}
/*==========================================
* Read Message Data
*------------------------------------------*/
-int msg_config_read(const char *cfgName)
+int msg_config_read(const char* cfgName)
{
- int msg_number;
- char line[1024], w1[1024], w2[1024];
- FILE *fp;
- static int called = 1;
+ int msg_number;
+ char line[1024], w1[1024], w2[1024];
+ FILE *fp;
+ static int called = 1;
- if ((fp = fopen(cfgName, "r")) == NULL) {
- ShowError("Messages file not found: %s\n", cfgName);
- return 1;
- }
+ if ((fp = fopen(cfgName, "r")) == NULL) {
+ ShowError("Messages file not found: %s\n", cfgName);
+ return 1;
+ }
- if ((--called) == 0)
- memset(msg_table, 0, sizeof(msg_table[0]) * MAX_MSG);
+ if ((--called) == 0)
+ memset(msg_table, 0, sizeof(msg_table[0]) * MAX_MSG);
- while (fgets(line, sizeof(line), fp)) {
- if (line[0] == '/' && line[1] == '/')
- continue;
- if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) != 2)
- continue;
+ while(fgets(line, sizeof(line), fp))
+ {
+ if (line[0] == '/' && line[1] == '/')
+ continue;
+ if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) != 2)
+ continue;
- if (strcmpi(w1, "import") == 0)
- msg_config_read(w2);
- else {
- msg_number = atoi(w1);
- if (msg_number >= 0 && msg_number < MAX_MSG) {
- if (msg_table[msg_number] != NULL)
- aFree(msg_table[msg_number]);
- msg_table[msg_number] = (char *)aMalloc((strlen(w2) + 1)*sizeof(char));
- strcpy(msg_table[msg_number],w2);
- }
- }
- }
+ if (strcmpi(w1, "import") == 0)
+ msg_config_read(w2);
+ else
+ {
+ msg_number = atoi(w1);
+ if (msg_number >= 0 && msg_number < MAX_MSG)
+ {
+ if (msg_table[msg_number] != NULL)
+ aFree(msg_table[msg_number]);
+ msg_table[msg_number] = (char *)aMalloc((strlen(w2) + 1)*sizeof (char));
+ strcpy(msg_table[msg_number],w2);
+ }
+ }
+ }
- fclose(fp);
+ fclose(fp);
- return 0;
+ return 0;
}
/*==========================================
@@ -159,9 +162,9 @@ int msg_config_read(const char *cfgName)
*------------------------------------------*/
void do_final_msg(void)
{
- int i;
- for (i = 0; i < MAX_MSG; i++)
- aFree(msg_table[i]);
+ int i;
+ for (i = 0; i < MAX_MSG; i++)
+ aFree(msg_table[i]);
}
/**
@@ -170,34 +173,34 @@ void do_final_msg(void)
* @param name the name of the command to retrieve help information for
* @return the string associated with the command, or NULL
*/
-static const char *atcommand_help_string(const char *command)
+static const char* atcommand_help_string(const char* command)
{
- const char *str = NULL;
- config_setting_t *info;
+ const char* str = NULL;
+ config_setting_t* info;
- if (*command == atcommand_symbol || *command == charcommand_symbol) {
- // remove the prefix symbol for the raw name of the command
- command ++;
- }
+ if( *command == atcommand_symbol || *command == charcommand_symbol )
+ {// remove the prefix symbol for the raw name of the command
+ command ++;
+ }
- // convert alias to the real command name
- command = atcommand_checkalias(command);
+ // convert alias to the real command name
+ command = atcommand_checkalias(command);
- // attept to find the first default help command
- info = config_lookup(&atcommand_config, "help");
+ // attept to find the first default help command
+ info = config_lookup(&atcommand_config, "help");
- if (info == NULL) {
- // failed to find the help property in the configuration file
- return NULL;
- }
+ if( info == NULL )
+ {// failed to find the help property in the configuration file
+ return NULL;
+ }
- if (!config_setting_lookup_string(info, command, &str)) {
- // failed to find the matching help string
- return NULL;
- }
+ if( !config_setting_lookup_string( info, command, &str ) )
+ {// failed to find the matching help string
+ return NULL;
+ }
- // push the result from the method
- return str;
+ // push the result from the method
+ return str;
}
@@ -206,243 +209,228 @@ static const char *atcommand_help_string(const char *command)
*------------------------------------------*/
ACMD_FUNC(send)
{
- int len=0,off,end,type;
- long num;
+ int len=0,off,end,type;
+ long num;
- // read message type as hex number (without the 0x)
- if (!message || !*message ||
- !((sscanf(message, "len %x", &type)==1 && (len=1))
- || sscanf(message, "%x", &type)==1)) {
- int i;
- for (i = 900; i <= 903; ++i)
- clif_displaymessage(fd, msg_txt(i));
- return -1;
- }
+ // read message type as hex number (without the 0x)
+ if(!message || !*message ||
+ !((sscanf(message, "len %x", &type)==1 && (len=1))
+ || sscanf(message, "%x", &type)==1) )
+ {
+ int i;
+ for (i = 900; i <= 903; ++i)
+ clif_displaymessage(fd, msg_txt(i));
+ return -1;
+ }
#define PARSE_ERROR(error,p) \
- {\
- clif_displaymessage(fd, (error));\
- sprintf(atcmd_output, ">%s", (p));\
- clif_displaymessage(fd, atcmd_output);\
- }
- //define PARSE_ERROR
+ {\
+ clif_displaymessage(fd, (error));\
+ sprintf(atcmd_output, ">%s", (p));\
+ clif_displaymessage(fd, atcmd_output);\
+ }
+//define PARSE_ERROR
#define CHECK_EOS(p) \
- if(*(p) == 0){\
- clif_displaymessage(fd, "Unexpected end of string");\
- return -1;\
- }
- //define CHECK_EOS
+ if(*(p) == 0){\
+ clif_displaymessage(fd, "Unexpected end of string");\
+ return -1;\
+ }
+//define CHECK_EOS
#define SKIP_VALUE(p) \
- {\
- while(*(p) && !ISSPACE(*(p))) ++(p); /* non-space */\
- while(*(p) && ISSPACE(*(p))) ++(p); /* space */\
- }
- //define SKIP_VALUE
+ {\
+ while(*(p) && !ISSPACE(*(p))) ++(p); /* non-space */\
+ while(*(p) && ISSPACE(*(p))) ++(p); /* space */\
+ }
+//define SKIP_VALUE
#define GET_VALUE(p,num) \
- {\
- if(sscanf((p), "x%lx", &(num)) < 1 && sscanf((p), "%ld ", &(num)) < 1){\
- PARSE_ERROR("Invalid number in:",(p));\
- return -1;\
- }\
- }
- //define GET_VALUE
-
- if (type > 0 && type < MAX_PACKET_DB) {
-
- if (len) {
- // show packet length
- sprintf(atcmd_output, msg_txt(904), type, packet_db[sd->packet_ver][type].len); // Packet 0x%x length: %d
- clif_displaymessage(fd, atcmd_output);
- return 0;
- }
-
- len=packet_db[sd->packet_ver][type].len;
- off=2;
- if (len == 0) {
- // unknown packet - ERROR
- sprintf(atcmd_output, msg_txt(905), type); // Unknown packet: 0x%x
- clif_displaymessage(fd, atcmd_output);
- return -1;
- } else if (len == -1) {
- // dynamic packet
- len=SHRT_MAX-4; // maximum length
- off=4;
- }
- WFIFOHEAD(fd, len);
- WFIFOW(fd,0)=TOW(type);
-
- // parse packet contents
- SKIP_VALUE(message);
- while (*message != 0 && off < len) {
- if (ISDIGIT(*message) || *message == '-' || *message == '+') {
- // default (byte)
- GET_VALUE(message,num);
- WFIFOB(fd,off)=TOB(num);
- ++off;
- } else if (TOUPPER(*message) == 'B') {
- // byte
- ++message;
- GET_VALUE(message,num);
- WFIFOB(fd,off)=TOB(num);
- ++off;
- } else if (TOUPPER(*message) == 'W') {
- // word (2 bytes)
- ++message;
- GET_VALUE(message,num);
- WFIFOW(fd,off)=TOW(num);
- off+=2;
- } else if (TOUPPER(*message) == 'L') {
- // long word (4 bytes)
- ++message;
- GET_VALUE(message,num);
- WFIFOL(fd,off)=TOL(num);
- off+=4;
- } else if (TOUPPER(*message) == 'S') {
- // string - escapes are valid
- // get string length - num <= 0 means not fixed length (default)
- ++message;
- if (*message == '"') {
- num=0;
- } else {
- GET_VALUE(message,num);
- while (*message != '"') {
- // find start of string
- if (*message == 0 || ISSPACE(*message)) {
- PARSE_ERROR(msg_txt(906),message); // Not a string:
- return -1;
- }
- ++message;
- }
- }
-
- // parse string
- ++message;
- CHECK_EOS(message);
- end=(num<=0? 0: min(off+((int)num),len));
- for (; *message != '"' && (off < end || end == 0); ++off) {
- if (*message == '\\') {
- ++message;
- CHECK_EOS(message);
- switch (*message) {
- case 'a':
- num=0x07;
- break; // Bell
- case 'b':
- num=0x08;
- break; // Backspace
- case 't':
- num=0x09;
- break; // Horizontal tab
- case 'n':
- num=0x0A;
- break; // Line feed
- case 'v':
- num=0x0B;
- break; // Vertical tab
- case 'f':
- num=0x0C;
- break; // Form feed
- case 'r':
- num=0x0D;
- break; // Carriage return
- case 'e':
- num=0x1B;
- break; // Escape
- default:
- num=*message;
- break;
- case 'x': { // Hexadecimal
- ++message;
- CHECK_EOS(message);
- if (!ISXDIGIT(*message)) {
- PARSE_ERROR(msg_txt(907),message); // Not a hexadecimal digit:
- return -1;
- }
- num=(ISDIGIT(*message)?*message-'0':TOLOWER(*message)-'a'+10);
- if (ISXDIGIT(*message)) {
- ++message;
- CHECK_EOS(message);
- num<<=8;
- num+=(ISDIGIT(*message)?*message-'0':TOLOWER(*message)-'a'+10);
- }
- WFIFOB(fd,off)=TOB(num);
- ++message;
- CHECK_EOS(message);
- continue;
- }
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7': { // Octal
- num=*message-'0'; // 1st octal digit
- ++message;
- CHECK_EOS(message);
- if (ISDIGIT(*message) && *message < '8') {
- num<<=3;
- num+=*message-'0'; // 2nd octal digit
- ++message;
- CHECK_EOS(message);
- if (ISDIGIT(*message) && *message < '8') {
- num<<=3;
- num+=*message-'0'; // 3rd octal digit
- ++message;
- CHECK_EOS(message);
- }
- }
- WFIFOB(fd,off)=TOB(num);
- continue;
- }
- }
- } else
- num=*message;
- WFIFOB(fd,off)=TOB(num);
- ++message;
- CHECK_EOS(message);
- }//for
- while (*message != '"') {
- // ignore extra characters
- ++message;
- CHECK_EOS(message);
- }
-
- // terminate the string
- if (off < end) {
- // fill the rest with 0's
- memset(WFIFOP(fd,off),0,end-off);
- off=end;
- }
- } else {
- // unknown
- PARSE_ERROR(msg_txt(908),message); // Unknown type of value in:
- return -1;
- }
- SKIP_VALUE(message);
- }
-
- if (packet_db[sd->packet_ver][type].len == -1) {
- // send dynamic packet
- WFIFOW(fd,2)=TOW(off);
- WFIFOSET(fd,off);
- } else {
- // send static packet
- if (off < len)
- memset(WFIFOP(fd,off),0,len-off);
- WFIFOSET(fd,len);
- }
- } else {
- clif_displaymessage(fd, msg_txt(259)); // Invalid packet
- return -1;
- }
- sprintf(atcmd_output, msg_txt(258), type, type); // Sent packet 0x%x (%d)
- clif_displaymessage(fd, atcmd_output);
- return 0;
+ {\
+ if(sscanf((p), "x%lx", &(num)) < 1 && sscanf((p), "%ld ", &(num)) < 1){\
+ PARSE_ERROR("Invalid number in:",(p));\
+ return -1;\
+ }\
+ }
+//define GET_VALUE
+
+ if (type > 0 && type < MAX_PACKET_DB) {
+
+ if(len)
+ {// show packet length
+ sprintf(atcmd_output, msg_txt(904), type, packet_db[sd->packet_ver][type].len); // Packet 0x%x length: %d
+ clif_displaymessage(fd, atcmd_output);
+ return 0;
+ }
+
+ len=packet_db[sd->packet_ver][type].len;
+ off=2;
+ if(len == 0)
+ {// unknown packet - ERROR
+ sprintf(atcmd_output, msg_txt(905), type); // Unknown packet: 0x%x
+ clif_displaymessage(fd, atcmd_output);
+ return -1;
+ } else if(len == -1)
+ {// dynamic packet
+ len=SHRT_MAX-4; // maximum length
+ off=4;
+ }
+ WFIFOHEAD(fd, len);
+ WFIFOW(fd,0)=TOW(type);
+
+ // parse packet contents
+ SKIP_VALUE(message);
+ while(*message != 0 && off < len){
+ if(ISDIGIT(*message) || *message == '-' || *message == '+')
+ {// default (byte)
+ GET_VALUE(message,num);
+ WFIFOB(fd,off)=TOB(num);
+ ++off;
+ } else if(TOUPPER(*message) == 'B')
+ {// byte
+ ++message;
+ GET_VALUE(message,num);
+ WFIFOB(fd,off)=TOB(num);
+ ++off;
+ } else if(TOUPPER(*message) == 'W')
+ {// word (2 bytes)
+ ++message;
+ GET_VALUE(message,num);
+ WFIFOW(fd,off)=TOW(num);
+ off+=2;
+ } else if(TOUPPER(*message) == 'L')
+ {// long word (4 bytes)
+ ++message;
+ GET_VALUE(message,num);
+ WFIFOL(fd,off)=TOL(num);
+ off+=4;
+ } else if(TOUPPER(*message) == 'S')
+ {// string - escapes are valid
+ // get string length - num <= 0 means not fixed length (default)
+ ++message;
+ if(*message == '"'){
+ num=0;
+ } else {
+ GET_VALUE(message,num);
+ while(*message != '"')
+ {// find start of string
+ if(*message == 0 || ISSPACE(*message)){
+ PARSE_ERROR(msg_txt(906),message); // Not a string:
+ return -1;
+ }
+ ++message;
+ }
+ }
+
+ // parse string
+ ++message;
+ CHECK_EOS(message);
+ end=(num<=0? 0: min(off+((int)num),len));
+ for(; *message != '"' && (off < end || end == 0); ++off){
+ if(*message == '\\'){
+ ++message;
+ CHECK_EOS(message);
+ switch(*message){
+ case 'a': num=0x07; break; // Bell
+ case 'b': num=0x08; break; // Backspace
+ case 't': num=0x09; break; // Horizontal tab
+ case 'n': num=0x0A; break; // Line feed
+ case 'v': num=0x0B; break; // Vertical tab
+ case 'f': num=0x0C; break; // Form feed
+ case 'r': num=0x0D; break; // Carriage return
+ case 'e': num=0x1B; break; // Escape
+ default: num=*message; break;
+ case 'x': // Hexadecimal
+ {
+ ++message;
+ CHECK_EOS(message);
+ if(!ISXDIGIT(*message)){
+ PARSE_ERROR(msg_txt(907),message); // Not a hexadecimal digit:
+ return -1;
+ }
+ num=(ISDIGIT(*message)?*message-'0':TOLOWER(*message)-'a'+10);
+ if(ISXDIGIT(*message)){
+ ++message;
+ CHECK_EOS(message);
+ num<<=8;
+ num+=(ISDIGIT(*message)?*message-'0':TOLOWER(*message)-'a'+10);
+ }
+ WFIFOB(fd,off)=TOB(num);
+ ++message;
+ CHECK_EOS(message);
+ continue;
+ }
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7': // Octal
+ {
+ num=*message-'0'; // 1st octal digit
+ ++message;
+ CHECK_EOS(message);
+ if(ISDIGIT(*message) && *message < '8'){
+ num<<=3;
+ num+=*message-'0'; // 2nd octal digit
+ ++message;
+ CHECK_EOS(message);
+ if(ISDIGIT(*message) && *message < '8'){
+ num<<=3;
+ num+=*message-'0'; // 3rd octal digit
+ ++message;
+ CHECK_EOS(message);
+ }
+ }
+ WFIFOB(fd,off)=TOB(num);
+ continue;
+ }
+ }
+ } else
+ num=*message;
+ WFIFOB(fd,off)=TOB(num);
+ ++message;
+ CHECK_EOS(message);
+ }//for
+ while(*message != '"')
+ {// ignore extra characters
+ ++message;
+ CHECK_EOS(message);
+ }
+
+ // terminate the string
+ if(off < end)
+ {// fill the rest with 0's
+ memset(WFIFOP(fd,off),0,end-off);
+ off=end;
+ }
+ } else
+ {// unknown
+ PARSE_ERROR(msg_txt(908),message); // Unknown type of value in:
+ return -1;
+ }
+ SKIP_VALUE(message);
+ }
+
+ if(packet_db[sd->packet_ver][type].len == -1)
+ {// send dynamic packet
+ WFIFOW(fd,2)=TOW(off);
+ WFIFOSET(fd,off);
+ } else
+ {// send static packet
+ if(off < len)
+ memset(WFIFOP(fd,off),0,len-off);
+ WFIFOSET(fd,len);
+ }
+ } else {
+ clif_displaymessage(fd, msg_txt(259)); // Invalid packet
+ return -1;
+ }
+ sprintf (atcmd_output, msg_txt(258), type, type); // Sent packet 0x%x (%d)
+ clif_displaymessage(fd, atcmd_output);
+ return 0;
#undef PARSE_ERROR
#undef CHECK_EOS
#undef SKIP_VALUE
@@ -454,53 +442,53 @@ ACMD_FUNC(send)
*------------------------------------------*/
ACMD_FUNC(mapmove)
{
- char map_name[MAP_NAME_LENGTH_EXT];
- unsigned short mapindex;
- short x = 0, y = 0;
- int m = -1;
+ char map_name[MAP_NAME_LENGTH_EXT];
+ unsigned short mapindex;
+ short x = 0, y = 0;
+ int m = -1;
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- memset(map_name, '\0', sizeof(map_name));
+ memset(map_name, '\0', sizeof(map_name));
- if (!message || !*message ||
- (sscanf(message, "%15s %hd %hd", map_name, &x, &y) < 3 &&
- sscanf(message, "%15[^,],%hd,%hd", map_name, &x, &y) < 1)) {
+ if (!message || !*message ||
+ (sscanf(message, "%15s %hd %hd", map_name, &x, &y) < 3 &&
+ sscanf(message, "%15[^,],%hd,%hd", map_name, &x, &y) < 1)) {
- clif_displaymessage(fd, msg_txt(909)); // Please enter a map (usage: @warp/@rura/@mapmove <mapname> <x> <y>).
- return -1;
- }
+ clif_displaymessage(fd, msg_txt(909)); // Please enter a map (usage: @warp/@rura/@mapmove <mapname> <x> <y>).
+ return -1;
+ }
- mapindex = mapindex_name2id(map_name);
- if (mapindex)
- m = map_mapindex2mapid(mapindex);
+ mapindex = mapindex_name2id(map_name);
+ if (mapindex)
+ m = map_mapindex2mapid(mapindex);
- if (!mapindex) { // m < 0 means on different server! [Kevin]
- clif_displaymessage(fd, msg_txt(1)); // Map not found.
- return -1;
- }
+ if (!mapindex) { // m < 0 means on different server! [Kevin]
+ clif_displaymessage(fd, msg_txt(1)); // Map not found.
+ return -1;
+ }
- if ((x || y) && map_getcell(m, x, y, CELL_CHKNOPASS)) {
- //This is to prevent the pc_setpos call from printing an error.
- clif_displaymessage(fd, msg_txt(2));
- if (!map_search_freecell(NULL, m, &x, &y, 10, 10, 1))
- x = y = 0; //Invalid cell, use random spot.
- }
- if (map[m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
- clif_displaymessage(fd, msg_txt(247));
- return -1;
- }
- if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
- clif_displaymessage(fd, msg_txt(248));
- return -1;
- }
- if (pc_setpos(sd, mapindex, x, y, CLR_TELEPORT) != 0) {
- clif_displaymessage(fd, msg_txt(1)); // Map not found.
- return -1;
- }
+ if ((x || y) && map_getcell(m, x, y, CELL_CHKNOPASS))
+ { //This is to prevent the pc_setpos call from printing an error.
+ clif_displaymessage(fd, msg_txt(2));
+ if (!map_search_freecell(NULL, m, &x, &y, 10, 10, 1))
+ x = y = 0; //Invalid cell, use random spot.
+ }
+ if (map[m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
+ clif_displaymessage(fd, msg_txt(247));
+ return -1;
+ }
+ if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
+ clif_displaymessage(fd, msg_txt(248));
+ return -1;
+ }
+ if (pc_setpos(sd, mapindex, x, y, CLR_TELEPORT) != 0) {
+ clif_displaymessage(fd, msg_txt(1)); // Map not found.
+ return -1;
+ }
- clif_displaymessage(fd, msg_txt(0)); // Warped.
- return 0;
+ clif_displaymessage(fd, msg_txt(0)); // Warped.
+ return 0;
}
/*==========================================
@@ -508,29 +496,29 @@ ACMD_FUNC(mapmove)
*------------------------------------------*/
ACMD_FUNC(where)
{
- struct map_session_data *pl_sd;
+ struct map_session_data* pl_sd;
- nullpo_retr(-1, sd);
- memset(atcmd_player_name, '\0', sizeof atcmd_player_name);
+ nullpo_retr(-1, sd);
+ memset(atcmd_player_name, '\0', sizeof atcmd_player_name);
- if (!message || !*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) {
- clif_displaymessage(fd, msg_txt(910)); // Please enter a player name (usage: @where <char name>).
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) {
+ clif_displaymessage(fd, msg_txt(910)); // Please enter a player name (usage: @where <char name>).
+ return -1;
+ }
- pl_sd = map_nick2sd(atcmd_player_name);
- if (pl_sd == NULL ||
- strncmp(pl_sd->status.name, atcmd_player_name, NAME_LENGTH) != 0 ||
- (pc_has_permission(pl_sd, PC_PERM_HIDE_SESSION) && pc_get_group_level(pl_sd) > pc_get_group_level(sd) && !pc_has_permission(sd, PC_PERM_WHO_DISPLAY_AID))
- ) {
- clif_displaymessage(fd, msg_txt(3)); // Character not found.
- return -1;
- }
+ pl_sd = map_nick2sd(atcmd_player_name);
+ if (pl_sd == NULL ||
+ strncmp(pl_sd->status.name, atcmd_player_name, NAME_LENGTH) != 0 ||
+ (pc_has_permission(pl_sd, PC_PERM_HIDE_SESSION) && pc_get_group_level(pl_sd) > pc_get_group_level(sd) && !pc_has_permission(sd, PC_PERM_WHO_DISPLAY_AID))
+ ) {
+ clif_displaymessage(fd, msg_txt(3)); // Character not found.
+ return -1;
+ }
- snprintf(atcmd_output, sizeof atcmd_output, "%s %s %d %d", pl_sd->status.name, mapindex_id2name(pl_sd->mapindex), pl_sd->bl.x, pl_sd->bl.y);
- clif_displaymessage(fd, atcmd_output);
+ snprintf(atcmd_output, sizeof atcmd_output, "%s %s %d %d", pl_sd->status.name, mapindex_id2name(pl_sd->mapindex), pl_sd->bl.x, pl_sd->bl.y);
+ clif_displaymessage(fd, atcmd_output);
- return 0;
+ return 0;
}
/*==========================================
@@ -538,40 +526,44 @@ ACMD_FUNC(where)
*------------------------------------------*/
ACMD_FUNC(jumpto)
{
- struct map_session_data *pl_sd = NULL;
+ struct map_session_data *pl_sd = NULL;
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- if (!message || !*message) {
- clif_displaymessage(fd, msg_txt(911)); // Please enter a player name (usage: @jumpto/@warpto/@goto <char name/ID>).
- return -1;
- }
+ if (!message || !*message) {
+ clif_displaymessage(fd, msg_txt(911)); // Please enter a player name (usage: @jumpto/@warpto/@goto <char name/ID>).
+ return -1;
+ }
- if ((pl_sd=map_nick2sd((char *)message)) == NULL && (pl_sd=map_charid2sd(atoi(message))) == NULL) {
- clif_displaymessage(fd, msg_txt(3)); // Character not found.
- return -1;
- }
+ if((pl_sd=map_nick2sd((char *)message)) == NULL && (pl_sd=map_charid2sd(atoi(message))) == NULL)
+ {
+ clif_displaymessage(fd, msg_txt(3)); // Character not found.
+ return -1;
+ }
- if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
- clif_displaymessage(fd, msg_txt(247)); // You are not authorized to warp to this map.
- return -1;
- }
+ if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE))
+ {
+ clif_displaymessage(fd, msg_txt(247)); // You are not authorized to warp to this map.
+ return -1;
+ }
- if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
- clif_displaymessage(fd, msg_txt(248)); // You are not authorized to warp from your current map.
- return -1;
- }
+ if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE))
+ {
+ clif_displaymessage(fd, msg_txt(248)); // You are not authorized to warp from your current map.
+ return -1;
+ }
- if (pc_isdead(sd)) {
- clif_displaymessage(fd, msg_txt(664));
- return -1;
- }
+ if( pc_isdead(sd) )
+ {
+ clif_displaymessage(fd, msg_txt(664));
+ return -1;
+ }
- pc_setpos(sd, pl_sd->mapindex, pl_sd->bl.x, pl_sd->bl.y, CLR_TELEPORT);
- sprintf(atcmd_output, msg_txt(4), pl_sd->status.name); // Jumped to %s
- clif_displaymessage(fd, atcmd_output);
+ pc_setpos(sd, pl_sd->mapindex, pl_sd->bl.x, pl_sd->bl.y, CLR_TELEPORT);
+ sprintf(atcmd_output, msg_txt(4), pl_sd->status.name); // Jumped to %s
+ clif_displaymessage(fd, atcmd_output);
- return 0;
+ return 0;
}
/*==========================================
@@ -579,35 +571,36 @@ ACMD_FUNC(jumpto)
*------------------------------------------*/
ACMD_FUNC(jump)
{
- short x = 0, y = 0;
+ short x = 0, y = 0;
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- memset(atcmd_output, '\0', sizeof(atcmd_output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
- sscanf(message, "%hd %hd", &x, &y);
+ sscanf(message, "%hd %hd", &x, &y);
- if (map[sd->bl.m].flag.noteleport && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
- clif_displaymessage(fd, msg_txt(248)); // You are not authorized to warp from your current map.
- return -1;
- }
+ if (map[sd->bl.m].flag.noteleport && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
+ clif_displaymessage(fd, msg_txt(248)); // You are not authorized to warp from your current map.
+ return -1;
+ }
- if (pc_isdead(sd)) {
- clif_displaymessage(fd, msg_txt(664));
- return -1;
- }
+ if( pc_isdead(sd) )
+ {
+ clif_displaymessage(fd, msg_txt(664));
+ return -1;
+ }
- if ((x || y) && map_getcell(sd->bl.m, x, y, CELL_CHKNOPASS)) {
- //This is to prevent the pc_setpos call from printing an error.
- clif_displaymessage(fd, msg_txt(2));
- if (!map_search_freecell(NULL, sd->bl.m, &x, &y, 10, 10, 1))
- x = y = 0; //Invalid cell, use random spot.
- }
+ if ((x || y) && map_getcell(sd->bl.m, x, y, CELL_CHKNOPASS))
+ { //This is to prevent the pc_setpos call from printing an error.
+ clif_displaymessage(fd, msg_txt(2));
+ if (!map_search_freecell(NULL, sd->bl.m, &x, &y, 10, 10, 1))
+ x = y = 0; //Invalid cell, use random spot.
+ }
- pc_setpos(sd, sd->mapindex, x, y, CLR_TELEPORT);
- sprintf(atcmd_output, msg_txt(5), sd->bl.x, sd->bl.y); // Jumped to %d %d
- clif_displaymessage(fd, atcmd_output);
- return 0;
+ pc_setpos(sd, sd->mapindex, x, y, CLR_TELEPORT);
+ sprintf(atcmd_output, msg_txt(5), sd->bl.x, sd->bl.y); // Jumped to %d %d
+ clif_displaymessage(fd, atcmd_output);
+ return 0;
}
/*==========================================
@@ -616,101 +609,101 @@ ACMD_FUNC(jump)
*------------------------------------------*/
ACMD_FUNC(who)
{
- struct map_session_data *pl_sd = NULL;
- struct s_mapiterator *iter = NULL;
- char map_name[MAP_NAME_LENGTH_EXT] = "";
- char player_name[NAME_LENGTH] = "";
- int count = 0;
- int level = 0;
- StringBuf buf;
- /**
- * 1 = @who : Player name, [Title], [Party name], [Guild name]
- * 2 = @who2 : Player name, [Title], BLvl, JLvl, Job
- * 3 = @who3 : [CID/AID] Player name [Title], Map, X, Y
- */
- int display_type = 1;
- int map_id = -1;
-
- nullpo_retr(-1, sd);
-
- if (strstr(command, "map") != NULL) {
- if (sscanf(message, "%15s %23s", map_name, player_name) < 1 || (map_id = map_mapname2mapid(map_name)) < 0)
- map_id = sd->bl.m;
- } else {
- sscanf(message, "%23s", player_name);
- }
-
- if (strstr(command, "2") != NULL)
- display_type = 2;
- else if (strstr(command, "3") != NULL)
- display_type = 3;
-
- level = pc_get_group_level(sd);
- StringBuf_Init(&buf);
-
- iter = mapit_getallusers();
- for (pl_sd = (TBL_PC *)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC *)mapit_next(iter)) {
- if (!((pc_has_permission(pl_sd, PC_PERM_HIDE_SESSION) || (pl_sd->sc.option & OPTION_INVISIBLE)) && pc_get_group_level(pl_sd) > level)) { // you can look only lower or same level
- if (stristr(pl_sd->status.name, player_name) == NULL // search with no case sensitive
- || (map_id >= 0 && pl_sd->bl.m != map_id))
- continue;
- switch (display_type) {
- case 2: {
- StringBuf_Printf(&buf, msg_txt(343), pl_sd->status.name); // "Name: %s "
- if (pc_get_group_id(pl_sd) > 0) // Player title, if exists
- StringBuf_Printf(&buf, msg_txt(344), pc_group_id2name(pc_get_group_id(pl_sd))); // "(%s) "
- StringBuf_Printf(&buf, msg_txt(347), pl_sd->status.base_level, pl_sd->status.job_level,
- job_name(pl_sd->status.class_)); // "| Lv:%d/%d | Job: %s"
- break;
- }
- case 3: {
- if (pc_has_permission(sd, PC_PERM_WHO_DISPLAY_AID))
- StringBuf_Printf(&buf, msg_txt(912), pl_sd->status.char_id, pl_sd->status.account_id); // "(CID:%d/AID:%d) "
- StringBuf_Printf(&buf, msg_txt(343), pl_sd->status.name); // "Name: %s "
- if (pc_get_group_id(pl_sd) > 0) // Player title, if exists
- StringBuf_Printf(&buf, msg_txt(344), pc_group_id2name(pc_get_group_id(pl_sd))); // "(%s) "
- StringBuf_Printf(&buf, msg_txt(348), mapindex_id2name(pl_sd->mapindex), pl_sd->bl.x, pl_sd->bl.y); // "| Location: %s %d %d"
- break;
- }
- default: {
- struct party_data *p = party_search(pl_sd->status.party_id);
- struct guild *g = guild_search(pl_sd->status.guild_id);
-
- StringBuf_Printf(&buf, msg_txt(343), pl_sd->status.name); // "Name: %s "
- if (pc_get_group_id(pl_sd) > 0) // Player title, if exists
- StringBuf_Printf(&buf, msg_txt(344), pc_group_id2name(pc_get_group_id(pl_sd))); // "(%s) "
- if (p != NULL)
- StringBuf_Printf(&buf, msg_txt(345), p->party.name); // " | Party: '%s'"
- if (g != NULL)
- StringBuf_Printf(&buf, msg_txt(346), g->name); // " | Guild: '%s'"
- break;
- }
- }
- clif_displaymessage(fd, StringBuf_Value(&buf));
- StringBuf_Clear(&buf);
- count++;
- }
- }
- mapit_free(iter);
-
- if (map_id < 0) {
- if (count == 0)
- StringBuf_Printf(&buf, msg_txt(28)); // No player found.
- else if (count == 1)
- StringBuf_Printf(&buf, msg_txt(29)); // 1 player found.
- else
- StringBuf_Printf(&buf, msg_txt(30), count); // %d players found.
- } else {
- if (count == 0)
- StringBuf_Printf(&buf, msg_txt(54), map[map_id].name); // No player found in map '%s'.
- else if (count == 1)
- StringBuf_Printf(&buf, msg_txt(55), map[map_id].name); // 1 player found in map '%s'.
- else
- StringBuf_Printf(&buf, msg_txt(56), count, map[map_id].name); // %d players found in map '%s'.
- }
- clif_displaymessage(fd, StringBuf_Value(&buf));
- StringBuf_Destroy(&buf);
- return 0;
+ struct map_session_data *pl_sd = NULL;
+ struct s_mapiterator *iter = NULL;
+ char map_name[MAP_NAME_LENGTH_EXT] = "";
+ char player_name[NAME_LENGTH] = "";
+ int count = 0;
+ int level = 0;
+ StringBuf buf;
+ /**
+ * 1 = @who : Player name, [Title], [Party name], [Guild name]
+ * 2 = @who2 : Player name, [Title], BLvl, JLvl, Job
+ * 3 = @who3 : [CID/AID] Player name [Title], Map, X, Y
+ */
+ int display_type = 1;
+ int map_id = -1;
+
+ nullpo_retr(-1, sd);
+
+ if (strstr(command, "map") != NULL) {
+ if (sscanf(message, "%15s %23s", map_name, player_name) < 1 || (map_id = map_mapname2mapid(map_name)) < 0)
+ map_id = sd->bl.m;
+ } else {
+ sscanf(message, "%23s", player_name);
+ }
+
+ if (strstr(command, "2") != NULL)
+ display_type = 2;
+ else if (strstr(command, "3") != NULL)
+ display_type = 3;
+
+ level = pc_get_group_level(sd);
+ StringBuf_Init(&buf);
+
+ iter = mapit_getallusers();
+ for (pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter)) {
+ if (!((pc_has_permission(pl_sd, PC_PERM_HIDE_SESSION) || (pl_sd->sc.option & OPTION_INVISIBLE)) && pc_get_group_level(pl_sd) > level)) { // you can look only lower or same level
+ if (stristr(pl_sd->status.name, player_name) == NULL // search with no case sensitive
+ || (map_id >= 0 && pl_sd->bl.m != map_id))
+ continue;
+ switch (display_type) {
+ case 2: {
+ StringBuf_Printf(&buf, msg_txt(343), pl_sd->status.name); // "Name: %s "
+ if (pc_get_group_id(pl_sd) > 0) // Player title, if exists
+ StringBuf_Printf(&buf, msg_txt(344), pc_group_id2name(pc_get_group_id(pl_sd))); // "(%s) "
+ StringBuf_Printf(&buf, msg_txt(347), pl_sd->status.base_level, pl_sd->status.job_level,
+ job_name(pl_sd->status.class_)); // "| Lv:%d/%d | Job: %s"
+ break;
+ }
+ case 3: {
+ if (pc_has_permission(sd, PC_PERM_WHO_DISPLAY_AID))
+ StringBuf_Printf(&buf, msg_txt(912), pl_sd->status.char_id, pl_sd->status.account_id); // "(CID:%d/AID:%d) "
+ StringBuf_Printf(&buf, msg_txt(343), pl_sd->status.name); // "Name: %s "
+ if (pc_get_group_id(pl_sd) > 0) // Player title, if exists
+ StringBuf_Printf(&buf, msg_txt(344), pc_group_id2name(pc_get_group_id(pl_sd))); // "(%s) "
+ StringBuf_Printf(&buf, msg_txt(348), mapindex_id2name(pl_sd->mapindex), pl_sd->bl.x, pl_sd->bl.y); // "| Location: %s %d %d"
+ break;
+ }
+ default: {
+ struct party_data *p = party_search(pl_sd->status.party_id);
+ struct guild *g = guild_search(pl_sd->status.guild_id);
+
+ StringBuf_Printf(&buf, msg_txt(343), pl_sd->status.name); // "Name: %s "
+ if (pc_get_group_id(pl_sd) > 0) // Player title, if exists
+ StringBuf_Printf(&buf, msg_txt(344), pc_group_id2name(pc_get_group_id(pl_sd))); // "(%s) "
+ if (p != NULL)
+ StringBuf_Printf(&buf, msg_txt(345), p->party.name); // " | Party: '%s'"
+ if (g != NULL)
+ StringBuf_Printf(&buf, msg_txt(346), g->name); // " | Guild: '%s'"
+ break;
+ }
+ }
+ clif_displaymessage(fd, StringBuf_Value(&buf));
+ StringBuf_Clear(&buf);
+ count++;
+ }
+ }
+ mapit_free(iter);
+
+ if (map_id < 0) {
+ if (count == 0)
+ StringBuf_Printf(&buf, msg_txt(28)); // No player found.
+ else if (count == 1)
+ StringBuf_Printf(&buf, msg_txt(29)); // 1 player found.
+ else
+ StringBuf_Printf(&buf, msg_txt(30), count); // %d players found.
+ } else {
+ if (count == 0)
+ StringBuf_Printf(&buf, msg_txt(54), map[map_id].name); // No player found in map '%s'.
+ else if (count == 1)
+ StringBuf_Printf(&buf, msg_txt(55), map[map_id].name); // 1 player found in map '%s'.
+ else
+ StringBuf_Printf(&buf, msg_txt(56), count, map[map_id].name); // %d players found in map '%s'.
+ }
+ clif_displaymessage(fd, StringBuf_Value(&buf));
+ StringBuf_Destroy(&buf);
+ return 0;
}
/*==========================================
@@ -718,83 +711,85 @@ ACMD_FUNC(who)
*------------------------------------------*/
ACMD_FUNC(whogm)
{
- struct map_session_data *pl_sd;
- struct s_mapiterator *iter;
- int j, count;
- int pl_level, level;
- char match_text[CHAT_SIZE_MAX];
- char player_name[NAME_LENGTH];
- struct guild *g;
- struct party_data *p;
-
- 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));
-
- if (sscanf(message, "%199[^\n]", match_text) < 1)
- strcpy(match_text, "");
- for (j = 0; match_text[j]; j++)
- match_text[j] = TOLOWER(match_text[j]);
-
- count = 0;
- level = pc_get_group_level(sd);
-
- iter = mapit_getallusers();
- for (pl_sd = (TBL_PC *)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC *)mapit_next(iter)) {
- pl_level = pc_get_group_level(pl_sd);
- if (!pl_level)
- continue;
-
- if (match_text[0]) {
- memcpy(player_name, pl_sd->status.name, NAME_LENGTH);
- for (j = 0; player_name[j]; j++)
- player_name[j] = TOLOWER(player_name[j]);
- // search with no case sensitive
- if (strstr(player_name, match_text) == NULL)
- continue;
- }
- if (pl_level > level) {
- if (pl_sd->sc.option & OPTION_INVISIBLE)
- continue;
- sprintf(atcmd_output, msg_txt(913), pl_sd->status.name); // Name: %s (GM)
- clif_displaymessage(fd, atcmd_output);
- count++;
- continue;
- }
-
- sprintf(atcmd_output, msg_txt(914), // Name: %s (GM:%d) | Location: %s %d %d
- pl_sd->status.name, pl_level,
- mapindex_id2name(pl_sd->mapindex), pl_sd->bl.x, pl_sd->bl.y);
- clif_displaymessage(fd, atcmd_output);
-
- sprintf(atcmd_output, msg_txt(915), // 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);
-
- p = party_search(pl_sd->status.party_id);
- g = guild_search(pl_sd->status.guild_id);
-
- sprintf(atcmd_output,msg_txt(916), // Party: '%s' | Guild: '%s'
- p?p->party.name:msg_txt(917), g?g->name:msg_txt(917)); // None.
-
- clif_displaymessage(fd, atcmd_output);
- count++;
- }
- mapit_free(iter);
-
- if (count == 0)
- clif_displaymessage(fd, msg_txt(150)); // No GM found.
- else if (count == 1)
- clif_displaymessage(fd, msg_txt(151)); // 1 GM found.
- else {
- sprintf(atcmd_output, msg_txt(152), count); // %d GMs found.
- clif_displaymessage(fd, atcmd_output);
- }
-
- return 0;
+ struct map_session_data* pl_sd;
+ struct s_mapiterator* iter;
+ int j, count;
+ int pl_level, level;
+ char match_text[CHAT_SIZE_MAX];
+ char player_name[NAME_LENGTH];
+ struct guild *g;
+ struct party_data *p;
+
+ 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));
+
+ if (sscanf(message, "%199[^\n]", match_text) < 1)
+ strcpy(match_text, "");
+ for (j = 0; match_text[j]; j++)
+ match_text[j] = TOLOWER(match_text[j]);
+
+ count = 0;
+ level = pc_get_group_level(sd);
+
+ iter = mapit_getallusers();
+ for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
+ {
+ pl_level = pc_get_group_level(pl_sd);
+ if (!pl_level)
+ continue;
+
+ if (match_text[0])
+ {
+ memcpy(player_name, pl_sd->status.name, NAME_LENGTH);
+ for (j = 0; player_name[j]; j++)
+ player_name[j] = TOLOWER(player_name[j]);
+ // search with no case sensitive
+ if (strstr(player_name, match_text) == NULL)
+ continue;
+ }
+ if (pl_level > level) {
+ if (pl_sd->sc.option & OPTION_INVISIBLE)
+ continue;
+ sprintf(atcmd_output, msg_txt(913), pl_sd->status.name); // Name: %s (GM)
+ clif_displaymessage(fd, atcmd_output);
+ count++;
+ continue;
+ }
+
+ sprintf(atcmd_output, msg_txt(914), // Name: %s (GM:%d) | Location: %s %d %d
+ pl_sd->status.name, pl_level,
+ mapindex_id2name(pl_sd->mapindex), pl_sd->bl.x, pl_sd->bl.y);
+ clif_displaymessage(fd, atcmd_output);
+
+ sprintf(atcmd_output, msg_txt(915), // 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);
+
+ p = party_search(pl_sd->status.party_id);
+ g = guild_search(pl_sd->status.guild_id);
+
+ sprintf(atcmd_output,msg_txt(916), // Party: '%s' | Guild: '%s'
+ p?p->party.name:msg_txt(917), g?g->name:msg_txt(917)); // None.
+
+ clif_displaymessage(fd, atcmd_output);
+ count++;
+ }
+ mapit_free(iter);
+
+ if (count == 0)
+ clif_displaymessage(fd, msg_txt(150)); // No GM found.
+ else if (count == 1)
+ clif_displaymessage(fd, msg_txt(151)); // 1 GM found.
+ else {
+ sprintf(atcmd_output, msg_txt(152), count); // %d GMs found.
+ clif_displaymessage(fd, atcmd_output);
+ }
+
+ return 0;
}
/*==========================================
@@ -802,17 +797,17 @@ ACMD_FUNC(whogm)
*------------------------------------------*/
ACMD_FUNC(save)
{
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- pc_setsavepoint(sd, sd->mapindex, sd->bl.x, sd->bl.y);
- if (sd->status.pet_id > 0 && sd->pd)
- intif_save_petdata(sd->status.account_id, &sd->pd->pet);
+ pc_setsavepoint(sd, sd->mapindex, sd->bl.x, sd->bl.y);
+ if (sd->status.pet_id > 0 && sd->pd)
+ intif_save_petdata(sd->status.account_id, &sd->pd->pet);
- chrif_save(sd,0);
+ chrif_save(sd,0);
- clif_displaymessage(fd, msg_txt(6)); // Your save point has been changed.
+ clif_displaymessage(fd, msg_txt(6)); // Your save point has been changed.
- return 0;
+ return 0;
}
/*==========================================
@@ -820,24 +815,24 @@ ACMD_FUNC(save)
*------------------------------------------*/
ACMD_FUNC(load)
{
- int m;
+ int m;
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- m = map_mapindex2mapid(sd->status.save_point.map);
- if (m >= 0 && map[m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
- clif_displaymessage(fd, msg_txt(249)); // You are not authorized to warp to your save map.
- return -1;
- }
- if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
- clif_displaymessage(fd, msg_txt(248)); // You are not authorized to warp from your current map.
- return -1;
- }
+ m = map_mapindex2mapid(sd->status.save_point.map);
+ if (m >= 0 && map[m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
+ clif_displaymessage(fd, msg_txt(249)); // You are not authorized to warp to your save map.
+ return -1;
+ }
+ if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
+ clif_displaymessage(fd, msg_txt(248)); // You are not authorized to warp from your current map.
+ return -1;
+ }
- pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_OUTSIGHT);
- clif_displaymessage(fd, msg_txt(7)); // Warping to save point..
+ pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_OUTSIGHT);
+ clif_displaymessage(fd, msg_txt(7)); // Warping to save point..
- return 0;
+ return 0;
}
/*==========================================
@@ -845,22 +840,22 @@ ACMD_FUNC(load)
*------------------------------------------*/
ACMD_FUNC(speed)
{
- int speed;
+ int speed;
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- memset(atcmd_output, '\0', sizeof(atcmd_output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
- if (!message || !*message || sscanf(message, "%d", &speed) < 1) {
- sprintf(atcmd_output, msg_txt(918), MIN_WALK_SPEED, MAX_WALK_SPEED); // Please enter a speed value (usage: @speed <%d-%d>).
- clif_displaymessage(fd, atcmd_output);
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%d", &speed) < 1) {
+ sprintf(atcmd_output, msg_txt(918), MIN_WALK_SPEED, MAX_WALK_SPEED); // Please enter a speed value (usage: @speed <%d-%d>).
+ clif_displaymessage(fd, atcmd_output);
+ return -1;
+ }
- sd->base_status.speed = cap_value(speed, MIN_WALK_SPEED, MAX_WALK_SPEED);
- status_calc_bl(&sd->bl, SCB_SPEED);
- clif_displaymessage(fd, msg_txt(8)); // Speed changed.
- return 0;
+ sd->base_status.speed = cap_value(speed, MIN_WALK_SPEED, MAX_WALK_SPEED);
+ status_calc_bl(&sd->bl, SCB_SPEED);
+ clif_displaymessage(fd, msg_txt(8)); // Speed changed.
+ return 0;
}
/*==========================================
@@ -868,20 +863,20 @@ ACMD_FUNC(speed)
*------------------------------------------*/
ACMD_FUNC(storage)
{
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- if (sd->npc_id || sd->state.vending || sd->state.buyingstore || sd->state.trading || sd->state.storage_flag)
- return -1;
+ if (sd->npc_id || sd->state.vending || sd->state.buyingstore || sd->state.trading || sd->state.storage_flag)
+ return -1;
- if (storage_storageopen(sd) == 1) {
- //Already open.
- clif_displaymessage(fd, msg_txt(250));
- return -1;
- }
+ if (storage_storageopen(sd) == 1)
+ { //Already open.
+ clif_displaymessage(fd, msg_txt(250));
+ return -1;
+ }
- clif_displaymessage(fd, msg_txt(919)); // Storage opened.
+ clif_displaymessage(fd, msg_txt(919)); // Storage opened.
- return 0;
+ return 0;
}
@@ -890,29 +885,29 @@ ACMD_FUNC(storage)
*------------------------------------------*/
ACMD_FUNC(guildstorage)
{
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- if (!sd->status.guild_id) {
- clif_displaymessage(fd, msg_txt(252));
- return -1;
- }
+ if (!sd->status.guild_id) {
+ clif_displaymessage(fd, msg_txt(252));
+ return -1;
+ }
- if (sd->npc_id || sd->state.vending || sd->state.buyingstore || sd->state.trading)
- return -1;
+ if (sd->npc_id || sd->state.vending || sd->state.buyingstore || sd->state.trading)
+ return -1;
- if (sd->state.storage_flag == 1) {
- clif_displaymessage(fd, msg_txt(250));
- return -1;
- }
+ if (sd->state.storage_flag == 1) {
+ clif_displaymessage(fd, msg_txt(250));
+ return -1;
+ }
- if (sd->state.storage_flag == 2) {
- clif_displaymessage(fd, msg_txt(251));
- return -1;
- }
+ if (sd->state.storage_flag == 2) {
+ clif_displaymessage(fd, msg_txt(251));
+ return -1;
+ }
- storage_guild_storageopen(sd);
- clif_displaymessage(fd, msg_txt(920)); // Guild storage opened.
- return 0;
+ storage_guild_storageopen(sd);
+ clif_displaymessage(fd, msg_txt(920)); // Guild storage opened.
+ return 0;
}
/*==========================================
@@ -920,34 +915,34 @@ ACMD_FUNC(guildstorage)
*------------------------------------------*/
ACMD_FUNC(option)
{
- int param1 = 0, param2 = 0, param3 = 0;
- nullpo_retr(-1, sd);
+ 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) {
- // failed to match the parameters so inform the user of the options
- const char *text = NULL;
+ if (!message || !*message || sscanf(message, "%d %d %d", &param1, &param2, &param3) < 1 || param1 < 0 || param2 < 0 || param3 < 0)
+ {// failed to match the parameters so inform the user of the options
+ const char* text = NULL;
- // attempt to find the setting information for this command
- text = atcommand_help_string(command);
+ // attempt to find the setting information for this command
+ text = atcommand_help_string( command );
- // notify the user of the requirement to enter an option
- clif_displaymessage(fd, msg_txt(921)); // Please enter at least one option.
+ // notify the user of the requirement to enter an option
+ clif_displaymessage(fd, msg_txt(921)); // Please enter at least one option.
- if (text) {
- // send the help text associated with this command
- clif_displaymessage(fd, text);
- }
+ if( text )
+ {// send the help text associated with this command
+ clif_displaymessage( fd, text );
+ }
- return -1;
- }
+ return -1;
+ }
- sd->sc.opt1 = param1;
- sd->sc.opt2 = param2;
- pc_setoption(sd, param3);
+ sd->sc.opt1 = param1;
+ sd->sc.opt2 = param2;
+ pc_setoption(sd, param3);
- clif_displaymessage(fd, msg_txt(9)); // Options changed.
+ clif_displaymessage(fd, msg_txt(9)); // Options changed.
- return 0;
+ return 0;
}
/*==========================================
@@ -955,41 +950,41 @@ ACMD_FUNC(option)
*------------------------------------------*/
ACMD_FUNC(hide)
{
- nullpo_retr(-1, sd);
- if (sd->sc.option & OPTION_INVISIBLE) {
- sd->sc.option &= ~OPTION_INVISIBLE;
- if (sd->disguise)
- status_set_viewdata(&sd->bl, sd->disguise);
- else
- status_set_viewdata(&sd->bl, sd->status.class_);
- clif_displaymessage(fd, msg_txt(10)); // Invisible: Off
+ nullpo_retr(-1, sd);
+ if (sd->sc.option & OPTION_INVISIBLE) {
+ sd->sc.option &= ~OPTION_INVISIBLE;
+ if (sd->disguise)
+ status_set_viewdata(&sd->bl, sd->disguise);
+ else
+ status_set_viewdata(&sd->bl, sd->status.class_);
+ clif_displaymessage(fd, msg_txt(10)); // Invisible: Off
- // increment the number of pvp players on the map
- map[sd->bl.m].users_pvp++;
+ // increment the number of pvp players on the map
+ map[sd->bl.m].users_pvp++;
- if (map[sd->bl.m].flag.pvp && !map[sd->bl.m].flag.pvp_nocalcrank) {
- // register the player for ranking calculations
- sd->pvp_timer = add_timer(gettick() + 200, pc_calc_pvprank_timer, sd->bl.id, 0);
- }
- //bugreport:2266
- map_foreachinmovearea(clif_insight, &sd->bl, AREA_SIZE, sd->bl.x, sd->bl.y, BL_ALL, &sd->bl);
- } else {
- sd->sc.option |= OPTION_INVISIBLE;
- sd->vd.class_ = INVISIBLE_CLASS;
- clif_displaymessage(fd, msg_txt(11)); // Invisible: On
+ if( map[sd->bl.m].flag.pvp && !map[sd->bl.m].flag.pvp_nocalcrank )
+ {// register the player for ranking calculations
+ sd->pvp_timer = add_timer( gettick() + 200, pc_calc_pvprank_timer, sd->bl.id, 0 );
+ }
+ //bugreport:2266
+ map_foreachinmovearea(clif_insight, &sd->bl, AREA_SIZE, sd->bl.x, sd->bl.y, BL_ALL, &sd->bl);
+ } else {
+ sd->sc.option |= OPTION_INVISIBLE;
+ sd->vd.class_ = INVISIBLE_CLASS;
+ clif_displaymessage(fd, msg_txt(11)); // Invisible: On
- // decrement the number of pvp players on the map
- map[sd->bl.m].users_pvp--;
+ // decrement the number of pvp players on the map
+ map[sd->bl.m].users_pvp--;
- if (map[sd->bl.m].flag.pvp && !map[sd->bl.m].flag.pvp_nocalcrank && sd->pvp_timer != INVALID_TIMER) {
- // unregister the player for ranking
- delete_timer(sd->pvp_timer, pc_calc_pvprank_timer);
- sd->pvp_timer = INVALID_TIMER;
- }
- }
- clif_changeoption(&sd->bl);
+ if( map[sd->bl.m].flag.pvp && !map[sd->bl.m].flag.pvp_nocalcrank && sd->pvp_timer != INVALID_TIMER )
+ {// unregister the player for ranking
+ delete_timer( sd->pvp_timer, pc_calc_pvprank_timer );
+ sd->pvp_timer = INVALID_TIMER;
+ }
+ }
+ clif_changeoption(&sd->bl);
- return 0;
+ return 0;
}
/*==========================================
@@ -997,53 +992,183 @@ ACMD_FUNC(hide)
*------------------------------------------*/
ACMD_FUNC(jobchange)
{
- int job = 0, upper = 0;
- const char *text;
- nullpo_retr(-1, sd);
-
- if (!message || !*message || sscanf(message, "%d %d", &job, &upper) < 1) {
- int i, found = 0;
-
- for (i = JOB_NOVICE; i < JOB_MAX; ++i) {
- if (strncmpi(message, job_name(i), 16) == 0) {
- job = i;
- upper = 0;
- found = 1;
- break;
- }
- }
-
- if (!found) {
- text = atcommand_help_string(command);
- if (text)
- clif_displaymessage(fd, text);
- return -1;
- }
- }
-
- if (job == JOB_KNIGHT2 || job == JOB_CRUSADER2 || job == JOB_WEDDING || job == JOB_XMAS || job == JOB_SUMMER
- || job == JOB_LORD_KNIGHT2 || job == JOB_PALADIN2 || job == JOB_BABY_KNIGHT2 || job == JOB_BABY_CRUSADER2 || job == JOB_STAR_GLADIATOR2
- || (job >= JOB_RUNE_KNIGHT2 && job <= JOB_MECHANIC_T2) || (job >= JOB_BABY_RUNE2 && job <= JOB_BABY_MECHANIC2)
- ) { // Deny direct transformation into dummy jobs
- clif_displaymessage(fd, msg_txt(923)); //"You can not change to this job by command."
- return 0;
- }
-
- if (pcdb_checkid(job)) {
- if (pc_jobchange(sd, job, upper) == 0)
- clif_displaymessage(fd, msg_txt(12)); // Your job has been changed.
- else {
- clif_displaymessage(fd, msg_txt(155)); // You are unable to change your job.
- return -1;
- }
- } else {
- text = atcommand_help_string(command);
- if (text)
- clif_displaymessage(fd, text);
- return -1;
- }
-
- return 0;
+ //FIXME: redundancy, potentially wrong code, should use job_name() or similar instead of hardcoding the table [ultramage]
+ int job = 0, upper = 0;
+ const char* text;
+ nullpo_retr(-1, sd);
+
+ if (!message || !*message || sscanf(message, "%d %d", &job, &upper) < 1)
+ {
+ int i, found = 0;
+ const struct { char name[24]; int id; } jobs[] = {
+ { "novice", 0 },
+ { "swordman", 1 },
+ { "swordsman", 1 },
+ { "magician", 2 },
+ { "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 },
+ { "gunslinger", 24 },
+ { "gunner", 24 },
+ { "ninja", 25 },
+ { "novice high", 4001 },
+ { "high novice", 4001 },
+ { "swordman high", 4002 },
+ { "swordsman high", 4002 },
+ { "magician high", 4003 },
+ { "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 swordman", 4024 },
+ { "baby swordsman", 4024 },
+ { "baby magician", 4025 },
+ { "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 },
+ { "taekwon", 4046 },
+ { "taekwon boy", 4046 },
+ { "taekwon girl", 4046 },
+ { "star gladiator", 4047 },
+ { "soul linker", 4049 },
+ { "gangsi", 4050 },
+ { "bongun", 4050 },
+ { "munak", 4050 },
+ { "death knight", 4051 },
+ { "dark collector", 4052 },
+ { "rune knight", 4054 },
+ { "warlock", 4055 },
+ { "ranger", 4056 },
+ { "arch bishop", 4057 },
+ { "mechanic", 4058 },
+ { "guillotine", 4059 },
+ { "rune knight2", 4060 },
+ { "warlock2", 4061 },
+ { "ranger2", 4062 },
+ { "arch bishop2", 4063 },
+ { "mechanic2", 4064 },
+ { "guillotine2", 4065 },
+ { "royal guard", 4066 },
+ { "sorcerer", 4067 },
+ { "minstrel", 4068 },
+ { "wanderer", 4069 },
+ { "sura", 4070 },
+ { "genetic", 4071 },
+ { "shadow chaser", 4072 },
+ { "royal guard2", 4073 },
+ { "sorcerer2", 4074 },
+ { "minstrel2", 4075 },
+ { "wanderer2", 4076 },
+ { "sura2", 4077 },
+ { "genetic2", 4078 },
+ { "shadow chaser2", 4079 },
+ { "baby rune", 4096 },
+ { "baby warlock", 4097 },
+ { "baby ranger", 4098 },
+ { "baby bishop", 4099 },
+ { "baby mechanic", 4100 },
+ { "baby cross", 4101 },
+ { "baby guard", 4102 },
+ { "baby sorcerer", 4103 },
+ { "baby minstrel", 4104 },
+ { "baby wanderer", 4105 },
+ { "baby sura", 4106 },
+ { "baby genetic", 4107 },
+ { "baby chaser", 4108 },
+ { "super novice e", 4190 },
+ { "super baby e", 4191 },
+ { "kagerou", 4211 },
+ { "oboro", 4212 },
+ };
+
+ for (i=0; i < ARRAYLENGTH(jobs); i++) {
+ if (strncmpi(message, jobs[i].name, 16) == 0) {
+ job = jobs[i].id;
+ upper = 0;
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ text = atcommand_help_string(command);
+ if (text) clif_displaymessage(fd, text);
+ return -1;
+ }
+ }
+
+ if (job == 13 || job == 21 || job == 22 || job == 26 || job == 27 || job == 4014 || job == 4022 || job == 4036 || job == 4044 || job == 4048
+ || (job >= JOB_RUNE_KNIGHT2 && job <= JOB_MECHANIC_T2) || (job >= JOB_BABY_RUNE2 && job <= JOB_BABY_MECHANIC2)
+ ) // Deny direct transformation into dummy jobs
+ {clif_displaymessage(fd, msg_txt(923)); //"You can not change to this job by command."
+ return 0;}
+
+ if (pcdb_checkid(job))
+ {
+ if (pc_jobchange(sd, job, upper) == 0)
+ clif_displaymessage(fd, msg_txt(12)); // Your job has been changed.
+ else {
+ clif_displaymessage(fd, msg_txt(155)); // You are unable to change your job.
+ return -1;
+ }
+ } else {
+ text = atcommand_help_string(command);
+ if (text) clif_displaymessage(fd, text);
+ return -1;
+ }
+
+ return 0;
}
/*==========================================
@@ -1051,12 +1176,12 @@ ACMD_FUNC(jobchange)
*------------------------------------------*/
ACMD_FUNC(kill)
{
- nullpo_retr(-1, sd);
- status_kill(&sd->bl);
- clif_displaymessage(sd->fd, msg_txt(13)); // A pity! You've died.
- if (fd != sd->fd)
- clif_displaymessage(fd, msg_txt(14)); // Character killed.
- return 0;
+ nullpo_retr(-1, sd);
+ status_kill(&sd->bl);
+ clif_displaymessage(sd->fd, msg_txt(13)); // A pity! You've died.
+ if (fd != sd->fd)
+ clif_displaymessage(fd, msg_txt(14)); // Character killed.
+ return 0;
}
/*==========================================
@@ -1064,14 +1189,15 @@ ACMD_FUNC(kill)
*------------------------------------------*/
ACMD_FUNC(alive)
{
- nullpo_retr(-1, sd);
- if (!status_revive(&sd->bl, 100, 100)) {
- clif_displaymessage(fd, msg_txt(667));
- return -1;
- }
- clif_skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION,4,1);
- clif_displaymessage(fd, msg_txt(16)); // You've been revived! It's a miracle!
- return 0;
+ nullpo_retr(-1, sd);
+ if (!status_revive(&sd->bl, 100, 100))
+ {
+ clif_displaymessage(fd, msg_txt(667));
+ return -1;
+ }
+ clif_skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION,4,1);
+ clif_displaymessage(fd, msg_txt(16)); // You've been revived! It's a miracle!
+ return 0;
}
/*==========================================
@@ -1079,35 +1205,35 @@ ACMD_FUNC(alive)
*------------------------------------------*/
ACMD_FUNC(kami)
{
- unsigned long color=0;
- nullpo_retr(-1, sd);
+ unsigned long color=0;
+ nullpo_retr(-1, sd);
- memset(atcmd_output, '\0', sizeof(atcmd_output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
- if (*(command + 5) != 'c' && *(command + 5) != 'C') {
- if (!message || !*message) {
- clif_displaymessage(fd, msg_txt(980)); // Please enter a message (usage: @kami <message>).
- return -1;
- }
+ if(*(command + 5) != 'c' && *(command + 5) != 'C') {
+ if (!message || !*message) {
+ clif_displaymessage(fd, msg_txt(980)); // Please enter a message (usage: @kami <message>).
+ return -1;
+ }
- sscanf(message, "%199[^\n]", atcmd_output);
- if (strstr(command, "l") != NULL)
- clif_broadcast(&sd->bl, atcmd_output, strlen(atcmd_output) + 1, 0, ALL_SAMEMAP);
- else
- intif_broadcast(atcmd_output, strlen(atcmd_output) + 1, (*(command + 5) == 'b' || *(command + 5) == 'B') ? 0x10 : 0);
- } else {
- if (!message || !*message || (sscanf(message, "%lx %199[^\n]", &color, atcmd_output) < 2)) {
- clif_displaymessage(fd, msg_txt(981)); // Please enter color and message (usage: @kamic <color> <message>).
- return -1;
- }
+ sscanf(message, "%199[^\n]", atcmd_output);
+ if (strstr(command, "l") != NULL)
+ clif_broadcast(&sd->bl, atcmd_output, strlen(atcmd_output) + 1, 0, ALL_SAMEMAP);
+ else
+ intif_broadcast(atcmd_output, strlen(atcmd_output) + 1, (*(command + 5) == 'b' || *(command + 5) == 'B') ? 0x10 : 0);
+ } else {
+ if(!message || !*message || (sscanf(message, "%lx %199[^\n]", &color, atcmd_output) < 2)) {
+ clif_displaymessage(fd, msg_txt(981)); // Please enter color and message (usage: @kamic <color> <message>).
+ return -1;
+ }
- if (color > 0xFFFFFF) {
- clif_displaymessage(fd, msg_txt(982)); // Invalid color.
- return -1;
- }
- intif_broadcast2(atcmd_output, strlen(atcmd_output) + 1, color, 0x190, 12, 0, 0);
- }
- return 0;
+ if(color > 0xFFFFFF) {
+ clif_displaymessage(fd, msg_txt(982)); // Invalid color.
+ return -1;
+ }
+ intif_broadcast2(atcmd_output, strlen(atcmd_output) + 1, color, 0x190, 12, 0, 0);
+ }
+ return 0;
}
/*==========================================
@@ -1115,57 +1241,57 @@ ACMD_FUNC(kami)
*------------------------------------------*/
ACMD_FUNC(heal)
{
- int hp = 0, sp = 0; // [Valaris] thanks to fov
- nullpo_retr(-1, sd);
-
- sscanf(message, "%d %d", &hp, &sp);
-
- // some overflow checks
- if (hp == INT_MIN) hp++;
- if (sp == INT_MIN) sp++;
-
- if (hp == 0 && sp == 0) {
- if (!status_percent_heal(&sd->bl, 100, 100))
- clif_displaymessage(fd, msg_txt(157)); // HP and SP have already been recovered.
- else
- clif_displaymessage(fd, msg_txt(17)); // HP, SP recovered.
- return 0;
- }
-
- if (hp > 0 && sp >= 0) {
- if (!status_heal(&sd->bl, hp, sp, 0))
- clif_displaymessage(fd, msg_txt(157)); // HP and SP are already with the good value.
- else
- clif_displaymessage(fd, msg_txt(17)); // HP, SP recovered.
- return 0;
- }
-
- if (hp < 0 && sp <= 0) {
- status_damage(NULL, &sd->bl, -hp, -sp, 0, 0);
- clif_damage(&sd->bl,&sd->bl, gettick(), 0, 0, -hp, 0, 4, 0);
- clif_displaymessage(fd, msg_txt(156)); // HP or/and SP modified.
- return 0;
- }
-
- //Opposing signs.
- if (hp) {
- if (hp > 0)
- status_heal(&sd->bl, hp, 0, 0);
- else {
- status_damage(NULL, &sd->bl, -hp, 0, 0, 0);
- clif_damage(&sd->bl,&sd->bl, gettick(), 0, 0, -hp, 0, 4, 0);
- }
- }
-
- if (sp) {
- if (sp > 0)
- status_heal(&sd->bl, 0, sp, 0);
- else
- status_damage(NULL, &sd->bl, 0, -sp, 0, 0);
- }
-
- clif_displaymessage(fd, msg_txt(156)); // HP or/and SP modified.
- return 0;
+ int hp = 0, sp = 0; // [Valaris] thanks to fov
+ nullpo_retr(-1, sd);
+
+ sscanf(message, "%d %d", &hp, &sp);
+
+ // some overflow checks
+ if( hp == INT_MIN ) hp++;
+ if( sp == INT_MIN ) sp++;
+
+ if ( hp == 0 && sp == 0 ) {
+ if (!status_percent_heal(&sd->bl, 100, 100))
+ clif_displaymessage(fd, msg_txt(157)); // HP and SP have already been recovered.
+ else
+ clif_displaymessage(fd, msg_txt(17)); // HP, SP recovered.
+ return 0;
+ }
+
+ if ( hp > 0 && sp >= 0 ) {
+ if(!status_heal(&sd->bl, hp, sp, 0))
+ clif_displaymessage(fd, msg_txt(157)); // HP and SP are already with the good value.
+ else
+ clif_displaymessage(fd, msg_txt(17)); // HP, SP recovered.
+ return 0;
+ }
+
+ if ( hp < 0 && sp <= 0 ) {
+ status_damage(NULL, &sd->bl, -hp, -sp, 0, 0);
+ clif_damage(&sd->bl,&sd->bl, gettick(), 0, 0, -hp, 0, 4, 0);
+ clif_displaymessage(fd, msg_txt(156)); // HP or/and SP modified.
+ return 0;
+ }
+
+ //Opposing signs.
+ if ( hp ) {
+ if (hp > 0)
+ status_heal(&sd->bl, hp, 0, 0);
+ else {
+ status_damage(NULL, &sd->bl, -hp, 0, 0, 0);
+ clif_damage(&sd->bl,&sd->bl, gettick(), 0, 0, -hp, 0, 4, 0);
+ }
+ }
+
+ if ( sp ) {
+ if (sp > 0)
+ status_heal(&sd->bl, 0, sp, 0);
+ else
+ status_damage(NULL, &sd->bl, 0, -sp, 0, 0);
+ }
+
+ clif_displaymessage(fd, msg_txt(156)); // HP or/and SP modified.
+ return 0;
}
/*==========================================
@@ -1173,53 +1299,54 @@ ACMD_FUNC(heal)
*------------------------------------------*/
ACMD_FUNC(item)
{
- char item_name[100];
- int number = 0, item_id, flag = 0;
- struct item item_tmp;
- struct item_data *item_data;
- int get_count, i;
- nullpo_retr(-1, sd);
-
- memset(item_name, '\0', sizeof(item_name));
-
- if (!message || !*message || (
- sscanf(message, "\"%99[^\"]\" %d", item_name, &number) < 1 &&
- sscanf(message, "%99s %d", item_name, &number) < 1
- )) {
- clif_displaymessage(fd, msg_txt(983)); // Please enter an item name or ID (usage: @item <item name/ID> <quantity>).
- return -1;
- }
-
- if (number <= 0)
- number = 1;
-
- if ((item_data = itemdb_searchname(item_name)) == NULL &&
- (item_data = itemdb_exists(atoi(item_name))) == NULL) {
- clif_displaymessage(fd, msg_txt(19)); // Invalid item ID or name.
- return -1;
- }
-
- item_id = item_data->nameid;
- get_count = number;
- //Check if it's stackable.
- if (!itemdb_isstackable2(item_data))
- get_count = 1;
-
- for (i = 0; i < number; i += get_count) {
- // if not pet egg
- if (!pet_create_egg(sd, item_id)) {
- memset(&item_tmp, 0, sizeof(item_tmp));
- item_tmp.nameid = item_id;
- item_tmp.identify = 1;
-
- if ((flag = pc_additem(sd, &item_tmp, get_count, LOG_TYPE_COMMAND)))
- clif_additem(sd, 0, 0, flag);
- }
- }
-
- if (flag == 0)
- clif_displaymessage(fd, msg_txt(18)); // Item created.
- return 0;
+ char item_name[100];
+ int number = 0, item_id, flag = 0;
+ struct item item_tmp;
+ struct item_data *item_data;
+ int get_count, i;
+ nullpo_retr(-1, sd);
+
+ memset(item_name, '\0', sizeof(item_name));
+
+ if (!message || !*message || (
+ sscanf(message, "\"%99[^\"]\" %d", item_name, &number) < 1 &&
+ sscanf(message, "%99s %d", item_name, &number) < 1
+ )) {
+ clif_displaymessage(fd, msg_txt(983)); // Please enter an item name or ID (usage: @item <item name/ID> <quantity>).
+ return -1;
+ }
+
+ if (number <= 0)
+ number = 1;
+
+ if ((item_data = itemdb_searchname(item_name)) == NULL &&
+ (item_data = itemdb_exists(atoi(item_name))) == NULL)
+ {
+ clif_displaymessage(fd, msg_txt(19)); // Invalid item ID or name.
+ return -1;
+ }
+
+ item_id = item_data->nameid;
+ get_count = number;
+ //Check if it's stackable.
+ if (!itemdb_isstackable2(item_data))
+ get_count = 1;
+
+ for (i = 0; i < number; i += get_count) {
+ // if not pet egg
+ if (!pet_create_egg(sd, item_id)) {
+ memset(&item_tmp, 0, sizeof(item_tmp));
+ item_tmp.nameid = item_id;
+ item_tmp.identify = 1;
+
+ if ((flag = pc_additem(sd, &item_tmp, get_count, LOG_TYPE_COMMAND)))
+ clif_additem(sd, 0, 0, flag);
+ }
+ }
+
+ if (flag == 0)
+ clif_displaymessage(fd, msg_txt(18)); // Item created.
+ return 0;
}
/*==========================================
@@ -1227,76 +1354,76 @@ ACMD_FUNC(item)
*------------------------------------------*/
ACMD_FUNC(item2)
{
- struct item item_tmp;
- struct item_data *item_data;
- char item_name[100];
- int item_id, number = 0;
- int identify = 0, refine = 0, attr = 0;
- int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
- int flag = 0;
- int loop, get_count, i;
- nullpo_retr(-1, sd);
-
- memset(item_name, '\0', sizeof(item_name));
-
- if (!message || !*message || (
- sscanf(message, "\"%99[^\"]\" %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4) < 9 &&
- sscanf(message, "%99s %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4) < 9
- )) {
- clif_displaymessage(fd, msg_txt(984)); // Please enter all parameters (usage: @item2 <item name/ID> <quantity>
- clif_displaymessage(fd, msg_txt(985)); // <identify_flag> <refine> <attribute> <card1> <card2> <card3> <card4>).
- 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) {
- loop = 1;
- get_count = number;
- if (item_data->type == IT_WEAPON || item_data->type == IT_ARMOR ||
- item_data->type == IT_PETEGG || item_data->type == IT_PETARMOR) {
- loop = number;
- get_count = 1;
- if (item_data->type == IT_PETEGG) {
- identify = 1;
- refine = 0;
- }
- if (item_data->type == IT_PETARMOR)
- refine = 0;
- if (refine > MAX_REFINE)
- refine = MAX_REFINE;
- } else {
- identify = 1;
- refine = attr = 0;
- }
- for (i = 0; i < loop; i++) {
- memset(&item_tmp, 0, sizeof(item_tmp));
- item_tmp.nameid = item_id;
- item_tmp.identify = identify;
- item_tmp.refine = refine;
- item_tmp.attribute = attr;
- item_tmp.card[0] = c1;
- item_tmp.card[1] = c2;
- item_tmp.card[2] = c3;
- item_tmp.card[3] = c4;
- if ((flag = pc_additem(sd, &item_tmp, get_count, LOG_TYPE_COMMAND)))
- clif_additem(sd, 0, 0, flag);
- }
-
- if (flag == 0)
- clif_displaymessage(fd, msg_txt(18)); // Item created.
- } else {
- clif_displaymessage(fd, msg_txt(19)); // Invalid item ID or name.
- return -1;
- }
-
- return 0;
+ struct item item_tmp;
+ struct item_data *item_data;
+ char item_name[100];
+ int item_id, number = 0;
+ int identify = 0, refine = 0, attr = 0;
+ int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
+ int flag = 0;
+ int loop, get_count, i;
+ nullpo_retr(-1, sd);
+
+ memset(item_name, '\0', sizeof(item_name));
+
+ if (!message || !*message || (
+ sscanf(message, "\"%99[^\"]\" %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4) < 9 &&
+ sscanf(message, "%99s %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4) < 9
+ )) {
+ clif_displaymessage(fd, msg_txt(984)); // Please enter all parameters (usage: @item2 <item name/ID> <quantity>
+ clif_displaymessage(fd, msg_txt(985)); // <identify_flag> <refine> <attribute> <card1> <card2> <card3> <card4>).
+ 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) {
+ loop = 1;
+ get_count = number;
+ if (item_data->type == IT_WEAPON || item_data->type == IT_ARMOR ||
+ item_data->type == IT_PETEGG || item_data->type == IT_PETARMOR) {
+ loop = number;
+ get_count = 1;
+ if (item_data->type == IT_PETEGG) {
+ identify = 1;
+ refine = 0;
+ }
+ if (item_data->type == IT_PETARMOR)
+ refine = 0;
+ if (refine > MAX_REFINE)
+ refine = MAX_REFINE;
+ } else {
+ identify = 1;
+ refine = attr = 0;
+ }
+ for (i = 0; i < loop; i++) {
+ memset(&item_tmp, 0, sizeof(item_tmp));
+ item_tmp.nameid = item_id;
+ item_tmp.identify = identify;
+ item_tmp.refine = refine;
+ item_tmp.attribute = attr;
+ item_tmp.card[0] = c1;
+ item_tmp.card[1] = c2;
+ item_tmp.card[2] = c3;
+ item_tmp.card[3] = c4;
+ if ((flag = pc_additem(sd, &item_tmp, get_count, LOG_TYPE_COMMAND)))
+ clif_additem(sd, 0, 0, flag);
+ }
+
+ if (flag == 0)
+ clif_displaymessage(fd, msg_txt(18)); // Item created.
+ } else {
+ clif_displaymessage(fd, msg_txt(19)); // Invalid item ID or name.
+ return -1;
+ }
+
+ return 0;
}
/*==========================================
@@ -1304,17 +1431,17 @@ ACMD_FUNC(item2)
*------------------------------------------*/
ACMD_FUNC(itemreset)
{
- int i;
- nullpo_retr(-1, sd);
+ 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) {
- pc_delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_COMMAND);
- }
- }
- clif_displaymessage(fd, msg_txt(20)); // All of your items have been removed.
+ for (i = 0; i < MAX_INVENTORY; i++) {
+ if (sd->status.inventory[i].amount && sd->status.inventory[i].equip == 0) {
+ pc_delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_COMMAND);
+ }
+ }
+ clif_displaymessage(fd, msg_txt(20)); // All of your items have been removed.
- return 0;
+ return 0;
}
/*==========================================
@@ -1322,59 +1449,59 @@ ACMD_FUNC(itemreset)
*------------------------------------------*/
ACMD_FUNC(baselevelup)
{
- int level=0, i=0, status_point=0;
- nullpo_retr(-1, sd);
- level = atoi(message);
-
- if (!message || !*message || !level) {
- clif_displaymessage(fd, msg_txt(986)); // Please enter a level adjustment (usage: @lvup/@blevel/@baselvlup <number of levels>).
- return -1;
- }
-
- if (level > 0) {
- if (sd->status.base_level >= pc_maxbaselv(sd)) { // check for max level by Valaris
- clif_displaymessage(fd, msg_txt(47)); // Base level can't go any higher.
- return -1;
- } // End Addition
- if ((unsigned int)level > pc_maxbaselv(sd) || (unsigned int)level > pc_maxbaselv(sd) - sd->status.base_level) // fix positiv overflow
- level = pc_maxbaselv(sd) - sd->status.base_level;
- for (i = 0; i < level; i++)
- status_point += pc_gets_status_point(sd->status.base_level + i);
-
- sd->status.status_point += status_point;
- sd->status.base_level += (unsigned int)level;
- status_percent_heal(&sd->bl, 100, 100);
- clif_misceffect(&sd->bl, 0);
- clif_displaymessage(fd, msg_txt(21)); // Base level raised.
- } else {
- if (sd->status.base_level == 1) {
- clif_displaymessage(fd, msg_txt(158)); // Base level can't go any lower.
- return -1;
- }
- level*=-1;
- if ((unsigned int)level >= sd->status.base_level)
- level = sd->status.base_level-1;
- for (i = 0; i > -level; i--)
- status_point += pc_gets_status_point(sd->status.base_level + i - 1);
- if (sd->status.status_point < status_point)
- pc_resetstate(sd);
- if (sd->status.status_point < status_point)
- sd->status.status_point = 0;
- else
- sd->status.status_point -= status_point;
- sd->status.base_level -= (unsigned int)level;
- clif_displaymessage(fd, msg_txt(22)); // Base level lowered.
- }
- sd->status.base_exp = 0;
- clif_updatestatus(sd, SP_STATUSPOINT);
- clif_updatestatus(sd, SP_BASELEVEL);
- clif_updatestatus(sd, SP_BASEEXP);
- clif_updatestatus(sd, SP_NEXTBASEEXP);
- status_calc_pc(sd, 0);
- pc_baselevelchanged(sd);
- if (sd->status.party_id)
- party_send_levelup(sd);
- return 0;
+ int level=0, i=0, status_point=0;
+ nullpo_retr(-1, sd);
+ level = atoi(message);
+
+ if (!message || !*message || !level) {
+ clif_displaymessage(fd, msg_txt(986)); // Please enter a level adjustment (usage: @lvup/@blevel/@baselvlup <number of levels>).
+ return -1;
+ }
+
+ if (level > 0) {
+ if (sd->status.base_level >= pc_maxbaselv(sd)) { // check for max level by Valaris
+ clif_displaymessage(fd, msg_txt(47)); // Base level can't go any higher.
+ return -1;
+ } // End Addition
+ if ((unsigned int)level > pc_maxbaselv(sd) || (unsigned int)level > pc_maxbaselv(sd) - sd->status.base_level) // fix positiv overflow
+ level = pc_maxbaselv(sd) - sd->status.base_level;
+ for (i = 0; i < level; i++)
+ status_point += pc_gets_status_point(sd->status.base_level + i);
+
+ sd->status.status_point += status_point;
+ sd->status.base_level += (unsigned int)level;
+ status_percent_heal(&sd->bl, 100, 100);
+ clif_misceffect(&sd->bl, 0);
+ clif_displaymessage(fd, msg_txt(21)); // Base level raised.
+ } else {
+ if (sd->status.base_level == 1) {
+ clif_displaymessage(fd, msg_txt(158)); // Base level can't go any lower.
+ return -1;
+ }
+ level*=-1;
+ if ((unsigned int)level >= sd->status.base_level)
+ level = sd->status.base_level-1;
+ for (i = 0; i > -level; i--)
+ status_point += pc_gets_status_point(sd->status.base_level + i - 1);
+ if (sd->status.status_point < status_point)
+ pc_resetstate(sd);
+ if (sd->status.status_point < status_point)
+ sd->status.status_point = 0;
+ else
+ sd->status.status_point -= status_point;
+ sd->status.base_level -= (unsigned int)level;
+ clif_displaymessage(fd, msg_txt(22)); // Base level lowered.
+ }
+ sd->status.base_exp = 0;
+ clif_updatestatus(sd, SP_STATUSPOINT);
+ clif_updatestatus(sd, SP_BASELEVEL);
+ clif_updatestatus(sd, SP_BASEEXP);
+ clif_updatestatus(sd, SP_NEXTBASEEXP);
+ status_calc_pc(sd, 0);
+ pc_baselevelchanged(sd);
+ if(sd->status.party_id)
+ party_send_levelup(sd);
+ return 0;
}
/*==========================================
@@ -1382,51 +1509,51 @@ ACMD_FUNC(baselevelup)
*------------------------------------------*/
ACMD_FUNC(joblevelup)
{
- int level=0;
- nullpo_retr(-1, sd);
-
- level = atoi(message);
-
- if (!message || !*message || !level) {
- clif_displaymessage(fd, msg_txt(987)); // Please enter a level adjustment (usage: @joblvup/@jlevel/@joblvlup <number of levels>).
- return -1;
- }
- if (level > 0) {
- if (sd->status.job_level >= pc_maxjoblv(sd)) {
- clif_displaymessage(fd, msg_txt(23)); // Job level can't go any higher.
- return -1;
- }
- if ((unsigned int)level > pc_maxjoblv(sd) || (unsigned int)level > pc_maxjoblv(sd) - sd->status.job_level) // fix positiv overflow
- level = pc_maxjoblv(sd) - sd->status.job_level;
- sd->status.job_level += (unsigned int)level;
- sd->status.skill_point += level;
- clif_misceffect(&sd->bl, 1);
- clif_displaymessage(fd, msg_txt(24)); // Job level raised.
- } else {
- if (sd->status.job_level == 1) {
- clif_displaymessage(fd, msg_txt(159)); // Job level can't go any lower.
- return -1;
- }
- level *=-1;
- if ((unsigned int)level >= sd->status.job_level) // fix negativ overflow
- level = sd->status.job_level-1;
- sd->status.job_level -= (unsigned int)level;
- if (sd->status.skill_point < level)
- pc_resetskill(sd,0); //Reset skills since we need to substract more points.
- if (sd->status.skill_point < level)
- sd->status.skill_point = 0;
- else
- sd->status.skill_point -= level;
- clif_displaymessage(fd, msg_txt(25)); // Job level lowered.
- }
- sd->status.job_exp = 0;
- clif_updatestatus(sd, SP_JOBLEVEL);
- clif_updatestatus(sd, SP_JOBEXP);
- clif_updatestatus(sd, SP_NEXTJOBEXP);
- clif_updatestatus(sd, SP_SKILLPOINT);
- status_calc_pc(sd, 0);
-
- return 0;
+ int level=0;
+ nullpo_retr(-1, sd);
+
+ level = atoi(message);
+
+ if (!message || !*message || !level) {
+ clif_displaymessage(fd, msg_txt(987)); // Please enter a level adjustment (usage: @joblvup/@jlevel/@joblvlup <number of levels>).
+ return -1;
+ }
+ if (level > 0) {
+ if (sd->status.job_level >= pc_maxjoblv(sd)) {
+ clif_displaymessage(fd, msg_txt(23)); // Job level can't go any higher.
+ return -1;
+ }
+ if ((unsigned int)level > pc_maxjoblv(sd) || (unsigned int)level > pc_maxjoblv(sd) - sd->status.job_level) // fix positiv overflow
+ level = pc_maxjoblv(sd) - sd->status.job_level;
+ sd->status.job_level += (unsigned int)level;
+ sd->status.skill_point += level;
+ clif_misceffect(&sd->bl, 1);
+ clif_displaymessage(fd, msg_txt(24)); // Job level raised.
+ } else {
+ if (sd->status.job_level == 1) {
+ clif_displaymessage(fd, msg_txt(159)); // Job level can't go any lower.
+ return -1;
+ }
+ level *=-1;
+ if ((unsigned int)level >= sd->status.job_level) // fix negativ overflow
+ level = sd->status.job_level-1;
+ sd->status.job_level -= (unsigned int)level;
+ if (sd->status.skill_point < level)
+ pc_resetskill(sd,0); //Reset skills since we need to substract more points.
+ if (sd->status.skill_point < level)
+ sd->status.skill_point = 0;
+ else
+ sd->status.skill_point -= level;
+ clif_displaymessage(fd, msg_txt(25)); // Job level lowered.
+ }
+ sd->status.job_exp = 0;
+ clif_updatestatus(sd, SP_JOBLEVEL);
+ clif_updatestatus(sd, SP_JOBEXP);
+ clif_updatestatus(sd, SP_NEXTJOBEXP);
+ clif_updatestatus(sd, SP_SKILLPOINT);
+ status_calc_pc(sd, 0);
+
+ return 0;
}
/*==========================================
@@ -1434,116 +1561,116 @@ ACMD_FUNC(joblevelup)
*------------------------------------------*/
ACMD_FUNC(help)
{
- config_setting_t *help;
- const char *text = NULL;
- const char *command_name = NULL;
- char *default_command = "help";
-
- nullpo_retr(-1, sd);
-
- help = config_lookup(&atcommand_config, "help");
- if (help == NULL) {
- clif_displaymessage(fd, msg_txt(27)); // "Commands help is not available."
- return -1;
- }
-
- if (!message || !*message) {
- command_name = default_command; // If no command_name specified, display help for @help.
- } else {
- if (*message == atcommand_symbol || *message == charcommand_symbol)
- ++message;
- command_name = atcommand_checkalias(message);
- }
-
- if (!pc_can_use_command(sd, command_name, COMMAND_ATCOMMAND)) {
- sprintf(atcmd_output, msg_txt(153), message); // "%s is Unknown Command"
- clif_displaymessage(fd, atcmd_output);
- atcommand_get_suggestions(sd, command_name, true);
- return -1;
- }
-
- if (!config_setting_lookup_string(help, command_name, &text)) {
- sprintf(atcmd_output, msg_txt(988), atcommand_symbol, command_name); // There is no help for %c%s.
- clif_displaymessage(fd, atcmd_output);
- atcommand_get_suggestions(sd, command_name, true);
- return -1;
- }
-
- sprintf(atcmd_output, msg_txt(989), atcommand_symbol, command_name); // Help for command %c%s:
- clif_displaymessage(fd, atcmd_output);
-
- {
- // Display aliases
- DBIterator *iter;
- AtCommandInfo *command_info;
- AliasInfo *alias_info = NULL;
- StringBuf buf;
- bool has_aliases = false;
-
- StringBuf_Init(&buf);
- StringBuf_AppendStr(&buf, msg_txt(990)); // Available aliases:
- command_info = get_atcommandinfo_byname(command_name);
- iter = db_iterator(atcommand_alias_db);
- for (alias_info = dbi_first(iter); dbi_exists(iter); alias_info = dbi_next(iter)) {
- if (alias_info->command == command_info) {
- StringBuf_Printf(&buf, " %s", alias_info->alias);
- has_aliases = true;
- }
- }
- dbi_destroy(iter);
- if (has_aliases)
- clif_displaymessage(fd, StringBuf_Value(&buf));
- StringBuf_Destroy(&buf);
- }
-
- // Display help contents
- clif_displaymessage(fd, text);
- return 0;
+ config_setting_t *help;
+ const char *text = NULL;
+ const char *command_name = NULL;
+ char *default_command = "help";
+
+ nullpo_retr(-1, sd);
+
+ help = config_lookup(&atcommand_config, "help");
+ if (help == NULL) {
+ clif_displaymessage(fd, msg_txt(27)); // "Commands help is not available."
+ return -1;
+ }
+
+ if (!message || !*message) {
+ command_name = default_command; // If no command_name specified, display help for @help.
+ } else {
+ if (*message == atcommand_symbol || *message == charcommand_symbol)
+ ++message;
+ command_name = atcommand_checkalias(message);
+ }
+
+ if (!pc_can_use_command(sd, command_name, COMMAND_ATCOMMAND)) {
+ sprintf(atcmd_output, msg_txt(153), message); // "%s is Unknown Command"
+ clif_displaymessage(fd, atcmd_output);
+ atcommand_get_suggestions(sd, command_name, true);
+ return -1;
+ }
+
+ if (!config_setting_lookup_string(help, command_name, &text)) {
+ sprintf(atcmd_output, msg_txt(988), atcommand_symbol, command_name); // There is no help for %c%s.
+ clif_displaymessage(fd, atcmd_output);
+ atcommand_get_suggestions(sd, command_name, true);
+ return -1;
+ }
+
+ sprintf(atcmd_output, msg_txt(989), atcommand_symbol, command_name); // Help for command %c%s:
+ clif_displaymessage(fd, atcmd_output);
+
+ { // Display aliases
+ DBIterator* iter;
+ AtCommandInfo *command_info;
+ AliasInfo *alias_info = NULL;
+ StringBuf buf;
+ bool has_aliases = false;
+
+ StringBuf_Init(&buf);
+ StringBuf_AppendStr(&buf, msg_txt(990)); // Available aliases:
+ command_info = get_atcommandinfo_byname(command_name);
+ iter = db_iterator(atcommand_alias_db);
+ for (alias_info = dbi_first(iter); dbi_exists(iter); alias_info = dbi_next(iter)) {
+ if (alias_info->command == command_info) {
+ StringBuf_Printf(&buf, " %s", alias_info->alias);
+ has_aliases = true;
+ }
+ }
+ dbi_destroy(iter);
+ if (has_aliases)
+ clif_displaymessage(fd, StringBuf_Value(&buf));
+ StringBuf_Destroy(&buf);
+ }
+
+ // Display help contents
+ clif_displaymessage(fd, text);
+ return 0;
}
// helper function, used in foreach calls to stop auto-attack timers
// parameter: '0' - everyone, 'id' - only those attacking someone with that id
static int atcommand_stopattack(struct block_list *bl,va_list ap)
{
- struct unit_data *ud = unit_bl2ud(bl);
- int id = va_arg(ap, int);
- if (ud && ud->attacktimer != INVALID_TIMER && (!id || id == ud->target)) {
- unit_stop_attack(bl);
- return 1;
- }
- return 0;
+ struct unit_data *ud = unit_bl2ud(bl);
+ int id = va_arg(ap, int);
+ if (ud && ud->attacktimer != INVALID_TIMER && (!id || id == ud->target))
+ {
+ unit_stop_attack(bl);
+ return 1;
+ }
+ return 0;
}
/*==========================================
*
*------------------------------------------*/
static int atcommand_pvpoff_sub(struct block_list *bl,va_list ap)
{
- TBL_PC *sd = (TBL_PC *)bl;
- clif_pvpset(sd, 0, 0, 2);
- if (sd->pvp_timer != INVALID_TIMER) {
- delete_timer(sd->pvp_timer, pc_calc_pvprank_timer);
- sd->pvp_timer = INVALID_TIMER;
- }
- return 0;
+ TBL_PC* sd = (TBL_PC*)bl;
+ clif_pvpset(sd, 0, 0, 2);
+ if (sd->pvp_timer != INVALID_TIMER) {
+ delete_timer(sd->pvp_timer, pc_calc_pvprank_timer);
+ sd->pvp_timer = INVALID_TIMER;
+ }
+ return 0;
}
ACMD_FUNC(pvpoff)
{
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- if (!map[sd->bl.m].flag.pvp) {
- clif_displaymessage(fd, msg_txt(160)); // PvP is already Off.
- return -1;
- }
+ if (!map[sd->bl.m].flag.pvp) {
+ clif_displaymessage(fd, msg_txt(160)); // PvP is already Off.
+ return -1;
+ }
- map[sd->bl.m].flag.pvp = 0;
+ map[sd->bl.m].flag.pvp = 0;
- if (!battle_config.pk_mode)
- clif_map_property_mapall(sd->bl.m, MAPPROPERTY_NOTHING);
- map_foreachinmap(atcommand_pvpoff_sub,sd->bl.m, BL_PC);
- map_foreachinmap(atcommand_stopattack,sd->bl.m, BL_CHAR, 0);
- clif_displaymessage(fd, msg_txt(31)); // PvP: Off.
- return 0;
+ if (!battle_config.pk_mode)
+ clif_map_property_mapall(sd->bl.m, MAPPROPERTY_NOTHING);
+ map_foreachinmap(atcommand_pvpoff_sub,sd->bl.m, BL_PC);
+ map_foreachinmap(atcommand_stopattack,sd->bl.m, BL_CHAR, 0);
+ clif_displaymessage(fd, msg_txt(31)); // PvP: Off.
+ return 0;
}
/*==========================================
@@ -1551,38 +1678,38 @@ ACMD_FUNC(pvpoff)
*------------------------------------------*/
static int atcommand_pvpon_sub(struct block_list *bl,va_list ap)
{
- TBL_PC *sd = (TBL_PC *)bl;
- if (sd->pvp_timer == INVALID_TIMER) {
- sd->pvp_timer = add_timer(gettick() + 200, pc_calc_pvprank_timer, sd->bl.id, 0);
- sd->pvp_rank = 0;
- sd->pvp_lastusers = 0;
- sd->pvp_point = 5;
- sd->pvp_won = 0;
- sd->pvp_lost = 0;
- }
- return 0;
+ TBL_PC* sd = (TBL_PC*)bl;
+ if (sd->pvp_timer == INVALID_TIMER) {
+ sd->pvp_timer = add_timer(gettick() + 200, pc_calc_pvprank_timer, sd->bl.id, 0);
+ sd->pvp_rank = 0;
+ sd->pvp_lastusers = 0;
+ sd->pvp_point = 5;
+ sd->pvp_won = 0;
+ sd->pvp_lost = 0;
+ }
+ return 0;
}
ACMD_FUNC(pvpon)
{
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- if (map[sd->bl.m].flag.pvp) {
- clif_displaymessage(fd, msg_txt(161)); // PvP is already On.
- return -1;
- }
+ if (map[sd->bl.m].flag.pvp) {
+ clif_displaymessage(fd, msg_txt(161)); // PvP is already On.
+ return -1;
+ }
- map[sd->bl.m].flag.pvp = 1;
+ map[sd->bl.m].flag.pvp = 1;
- if (!battle_config.pk_mode) {
- // display pvp circle and rank
- clif_map_property_mapall(sd->bl.m, MAPPROPERTY_FREEPVPZONE);
- map_foreachinmap(atcommand_pvpon_sub,sd->bl.m, BL_PC);
- }
+ if (!battle_config.pk_mode)
+ {// display pvp circle and rank
+ clif_map_property_mapall(sd->bl.m, MAPPROPERTY_FREEPVPZONE);
+ map_foreachinmap(atcommand_pvpon_sub,sd->bl.m, BL_PC);
+ }
- clif_displaymessage(fd, msg_txt(32)); // PvP: On.
+ clif_displaymessage(fd, msg_txt(32)); // PvP: On.
- return 0;
+ return 0;
}
/*==========================================
@@ -1590,19 +1717,19 @@ ACMD_FUNC(pvpon)
*------------------------------------------*/
ACMD_FUNC(gvgoff)
{
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- if (!map[sd->bl.m].flag.gvg) {
- clif_displaymessage(fd, msg_txt(162)); // GvG is already Off.
- return -1;
- }
+ if (!map[sd->bl.m].flag.gvg) {
+ clif_displaymessage(fd, msg_txt(162)); // GvG is already Off.
+ return -1;
+ }
- map[sd->bl.m].flag.gvg = 0;
- clif_map_property_mapall(sd->bl.m, MAPPROPERTY_NOTHING);
- map_foreachinmap(atcommand_stopattack,sd->bl.m, BL_CHAR, 0);
- clif_displaymessage(fd, msg_txt(33)); // GvG: Off.
+ map[sd->bl.m].flag.gvg = 0;
+ clif_map_property_mapall(sd->bl.m, MAPPROPERTY_NOTHING);
+ map_foreachinmap(atcommand_stopattack,sd->bl.m, BL_CHAR, 0);
+ clif_displaymessage(fd, msg_txt(33)); // GvG: Off.
- return 0;
+ return 0;
}
/*==========================================
@@ -1610,18 +1737,18 @@ ACMD_FUNC(gvgoff)
*------------------------------------------*/
ACMD_FUNC(gvgon)
{
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- if (map[sd->bl.m].flag.gvg) {
- clif_displaymessage(fd, msg_txt(163)); // GvG is already On.
- return -1;
- }
+ if (map[sd->bl.m].flag.gvg) {
+ clif_displaymessage(fd, msg_txt(163)); // GvG is already On.
+ return -1;
+ }
- map[sd->bl.m].flag.gvg = 1;
- clif_map_property_mapall(sd->bl.m, MAPPROPERTY_AGITZONE);
- clif_displaymessage(fd, msg_txt(34)); // GvG: On.
+ map[sd->bl.m].flag.gvg = 1;
+ clif_map_property_mapall(sd->bl.m, MAPPROPERTY_AGITZONE);
+ clif_displaymessage(fd, msg_txt(34)); // GvG: On.
- return 0;
+ return 0;
}
/*==========================================
@@ -1629,31 +1756,31 @@ ACMD_FUNC(gvgon)
*------------------------------------------*/
ACMD_FUNC(model)
{
- int hair_style = 0, hair_color = 0, cloth_color = 0;
- nullpo_retr(-1, sd);
+ int hair_style = 0, hair_color = 0, cloth_color = 0;
+ nullpo_retr(-1, sd);
- memset(atcmd_output, '\0', sizeof(atcmd_output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
- if (!message || !*message || sscanf(message, "%d %d %d", &hair_style, &hair_color, &cloth_color) < 1) {
- sprintf(atcmd_output, msg_txt(991), // Please enter at least one 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, atcmd_output);
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%d %d %d", &hair_style, &hair_color, &cloth_color) < 1) {
+ sprintf(atcmd_output, msg_txt(991), // Please enter at least one 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, atcmd_output);
+ return -1;
+ }
- 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) {
- pc_changelook(sd, LOOK_HAIR, hair_style);
- pc_changelook(sd, LOOK_HAIR_COLOR, hair_color);
- pc_changelook(sd, LOOK_CLOTHES_COLOR, cloth_color);
- clif_displaymessage(fd, msg_txt(36)); // Appearence changed.
- } else {
- clif_displaymessage(fd, msg_txt(37)); // An invalid number was specified.
- return -1;
- }
+ 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) {
+ pc_changelook(sd, LOOK_HAIR, hair_style);
+ pc_changelook(sd, LOOK_HAIR_COLOR, hair_color);
+ pc_changelook(sd, LOOK_CLOTHES_COLOR, cloth_color);
+ clif_displaymessage(fd, msg_txt(36)); // Appearence changed.
+ } else {
+ clif_displaymessage(fd, msg_txt(37)); // An invalid number was specified.
+ return -1;
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -1661,26 +1788,26 @@ ACMD_FUNC(model)
*------------------------------------------*/
ACMD_FUNC(dye)
{
- int cloth_color = 0;
- nullpo_retr(-1, sd);
+ int cloth_color = 0;
+ nullpo_retr(-1, sd);
- memset(atcmd_output, '\0', sizeof(atcmd_output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
- if (!message || !*message || sscanf(message, "%d", &cloth_color) < 1) {
- sprintf(atcmd_output, msg_txt(992), MIN_CLOTH_COLOR, MAX_CLOTH_COLOR); // Please enter a clothes color (usage: @dye/@ccolor <clothes color: %d-%d>).
- clif_displaymessage(fd, atcmd_output);
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%d", &cloth_color) < 1) {
+ sprintf(atcmd_output, msg_txt(992), MIN_CLOTH_COLOR, MAX_CLOTH_COLOR); // Please enter a clothes color (usage: @dye/@ccolor <clothes color: %d-%d>).
+ clif_displaymessage(fd, atcmd_output);
+ return -1;
+ }
- if (cloth_color >= MIN_CLOTH_COLOR && cloth_color <= MAX_CLOTH_COLOR) {
- pc_changelook(sd, LOOK_CLOTHES_COLOR, cloth_color);
- clif_displaymessage(fd, msg_txt(36)); // Appearence changed.
- } else {
- clif_displaymessage(fd, msg_txt(37)); // An invalid number was specified.
- return -1;
- }
+ if (cloth_color >= MIN_CLOTH_COLOR && cloth_color <= MAX_CLOTH_COLOR) {
+ pc_changelook(sd, LOOK_CLOTHES_COLOR, cloth_color);
+ clif_displaymessage(fd, msg_txt(36)); // Appearence changed.
+ } else {
+ clif_displaymessage(fd, msg_txt(37)); // An invalid number was specified.
+ return -1;
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -1688,26 +1815,26 @@ ACMD_FUNC(dye)
*------------------------------------------*/
ACMD_FUNC(hair_style)
{
- int hair_style = 0;
- nullpo_retr(-1, sd);
+ int hair_style = 0;
+ nullpo_retr(-1, sd);
- memset(atcmd_output, '\0', sizeof(atcmd_output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
- if (!message || !*message || sscanf(message, "%d", &hair_style) < 1) {
- sprintf(atcmd_output, msg_txt(993), MIN_HAIR_STYLE, MAX_HAIR_STYLE); // Please enter a hair style (usage: @hairstyle/@hstyle <hair ID: %d-%d>).
- clif_displaymessage(fd, atcmd_output);
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%d", &hair_style) < 1) {
+ sprintf(atcmd_output, msg_txt(993), MIN_HAIR_STYLE, MAX_HAIR_STYLE); // Please enter a hair style (usage: @hairstyle/@hstyle <hair ID: %d-%d>).
+ clif_displaymessage(fd, atcmd_output);
+ return -1;
+ }
- if (hair_style >= MIN_HAIR_STYLE && hair_style <= MAX_HAIR_STYLE) {
- pc_changelook(sd, LOOK_HAIR, hair_style);
- clif_displaymessage(fd, msg_txt(36)); // Appearence changed.
- } else {
- clif_displaymessage(fd, msg_txt(37)); // An invalid number was specified.
- return -1;
- }
+ if (hair_style >= MIN_HAIR_STYLE && hair_style <= MAX_HAIR_STYLE) {
+ pc_changelook(sd, LOOK_HAIR, hair_style);
+ clif_displaymessage(fd, msg_txt(36)); // Appearence changed.
+ } else {
+ clif_displaymessage(fd, msg_txt(37)); // An invalid number was specified.
+ return -1;
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -1715,26 +1842,26 @@ ACMD_FUNC(hair_style)
*------------------------------------------*/
ACMD_FUNC(hair_color)
{
- int hair_color = 0;
- nullpo_retr(-1, sd);
+ int hair_color = 0;
+ nullpo_retr(-1, sd);
- memset(atcmd_output, '\0', sizeof(atcmd_output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
- if (!message || !*message || sscanf(message, "%d", &hair_color) < 1) {
- sprintf(atcmd_output, msg_txt(994), MIN_HAIR_COLOR, MAX_HAIR_COLOR); // Please enter a hair color (usage: @haircolor/@hcolor <hair color: %d-%d>).
- clif_displaymessage(fd, atcmd_output);
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%d", &hair_color) < 1) {
+ sprintf(atcmd_output, msg_txt(994), MIN_HAIR_COLOR, MAX_HAIR_COLOR); // Please enter a hair color (usage: @haircolor/@hcolor <hair color: %d-%d>).
+ clif_displaymessage(fd, atcmd_output);
+ return -1;
+ }
- if (hair_color >= MIN_HAIR_COLOR && hair_color <= MAX_HAIR_COLOR) {
- pc_changelook(sd, LOOK_HAIR_COLOR, hair_color);
- clif_displaymessage(fd, msg_txt(36)); // Appearence changed.
- } else {
- clif_displaymessage(fd, msg_txt(37)); // An invalid number was specified.
- return -1;
- }
+ if (hair_color >= MIN_HAIR_COLOR && hair_color <= MAX_HAIR_COLOR) {
+ pc_changelook(sd, LOOK_HAIR_COLOR, hair_color);
+ clif_displaymessage(fd, msg_txt(36)); // Appearence changed.
+ } else {
+ clif_displaymessage(fd, msg_txt(37)); // An invalid number was specified.
+ return -1;
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -1742,198 +1869,199 @@ ACMD_FUNC(hair_color)
*------------------------------------------*/
ACMD_FUNC(go)
{
- int i;
- int town;
- char map_name[MAP_NAME_LENGTH];
- int m;
-
- const struct {
- char map[MAP_NAME_LENGTH];
- int x, y;
- } data[] = {
- { MAP_PRONTERA, 156, 191 }, // 0=Prontera
- { MAP_MORROC, 156, 93 }, // 1=Morroc
- { MAP_GEFFEN, 119, 59 }, // 2=Geffen
- { MAP_PAYON, 162, 233 }, // 3=Payon
- { MAP_ALBERTA, 192, 147 }, // 4=Alberta
+ int i;
+ int town;
+ char map_name[MAP_NAME_LENGTH];
+ int m;
+
+ const struct {
+ char map[MAP_NAME_LENGTH];
+ int x, y;
+ } data[] = {
+ { MAP_PRONTERA, 156, 191 }, // 0=Prontera
+ { MAP_MORROC, 156, 93 }, // 1=Morroc
+ { MAP_GEFFEN, 119, 59 }, // 2=Geffen
+ { MAP_PAYON, 162, 233 }, // 3=Payon
+ { MAP_ALBERTA, 192, 147 }, // 4=Alberta
#ifdef RENEWAL
- { MAP_IZLUDE, 128, 146 }, // 5=Izlude (Renewal)
+ { MAP_IZLUDE, 128, 146 }, // 5=Izlude (Renewal)
#else
- { MAP_IZLUDE, 128, 114 }, // 5=Izlude
+ { MAP_IZLUDE, 128, 114 }, // 5=Izlude
#endif
- { MAP_ALDEBARAN, 140, 131 }, // 6=Al de Baran
- { MAP_LUTIE, 147, 134 }, // 7=Lutie
- { MAP_COMODO, 209, 143 }, // 8=Comodo
- { MAP_YUNO, 157, 51 }, // 9=Yuno
- { MAP_AMATSU, 198, 84 }, // 10=Amatsu
- { MAP_GONRYUN, 160, 120 }, // 11=Gonryun
- { MAP_UMBALA, 89, 157 }, // 12=Umbala
- { MAP_NIFLHEIM, 21, 153 }, // 13=Niflheim
- { MAP_LOUYANG, 217, 40 }, // 14=Louyang
- { MAP_NOVICE, 53, 111 }, // 15=Training Grounds
- { MAP_JAIL, 23, 61 }, // 16=Prison
- { MAP_JAWAII, 249, 127 }, // 17=Jawaii
- { MAP_AYOTHAYA, 151, 117 }, // 18=Ayothaya
- { MAP_EINBROCH, 64, 200 }, // 19=Einbroch
- { MAP_LIGHTHALZEN, 158, 92 }, // 20=Lighthalzen
- { MAP_EINBECH, 70, 95 }, // 21=Einbech
- { MAP_HUGEL, 96, 145 }, // 22=Hugel
- { MAP_RACHEL, 130, 110 }, // 23=Rachel
- { MAP_VEINS, 216, 123 }, // 24=Veins
- { MAP_MOSCOVIA, 223, 184 }, // 25=Moscovia
- { MAP_MIDCAMP, 180, 240 }, // 26=Midgard Camp
- { MAP_MANUK, 282, 138 }, // 27=Manuk
- { MAP_SPLENDIDE, 197, 176 }, // 28=Splendide
- { MAP_BRASILIS, 182, 239 }, // 29=Brasilis
- { MAP_DICASTES, 198, 187 }, // 30=El Dicastes
- { MAP_MORA, 44, 151 }, // 31=Mora
- { MAP_DEWATA, 200, 180 }, // 32=Dewata
- { MAP_MALANGDO, 140, 114 }, // 33=Malangdo Island
- { MAP_MALAYA, 242, 211 }, // 34=Malaya Port
- { MAP_ECLAGE, 110, 39 }, // 35=Eclage
- };
-
- nullpo_retr(-1, sd);
-
- if (map[sd->bl.m].flag.nogo && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
- clif_displaymessage(sd->fd,msg_txt(995)); // You cannot use @go on this map.
- return 0;
- }
-
- memset(map_name, '\0', sizeof(map_name));
- memset(atcmd_output, '\0', sizeof(atcmd_output));
-
- // get the number
- town = atoi(message);
-
- if (!message || !*message || sscanf(message, "%11s", map_name) < 1 || town < 0 || town >= ARRAYLENGTH(data)) {
- // no value matched so send the list of locations
- const char *text;
-
- // attempt to find the text help string
- text = atcommand_help_string(command);
-
- clif_displaymessage(fd, msg_txt(38)); // Invalid location number, or name.
-
- if (text) {
- // send the text to the client
- clif_displaymessage(fd, text);
- }
-
- return -1;
- }
-
- // get possible name of the city
- map_name[MAP_NAME_LENGTH-1] = '\0';
- for (i = 0; map_name[i]; i++)
- map_name[i] = TOLOWER(map_name[i]);
- // try to identify the map name
- if (strncmp(map_name, "prontera", 3) == 0) {
- town = 0;
- } else if (strncmp(map_name, "morocc", 4) == 0 ||
- strncmp(map_name, "morroc", 4) == 0) {
- town = 1;
- } else if (strncmp(map_name, "geffen", 3) == 0) {
- town = 2;
- } else if (strncmp(map_name, "payon", 3) == 0) {
- town = 3;
- } else if (strncmp(map_name, "alberta", 3) == 0) {
- town = 4;
- } else if (strncmp(map_name, "izlude", 3) == 0) {
- town = 5;
- } else if (strncmp(map_name, "aldebaran", 3) == 0) {
- town = 6;
- } else if (strncmp(map_name, "lutie", 3) == 0 ||
- strcmp(map_name, "christmas") == 0 ||
- strncmp(map_name, "xmas", 3) == 0 ||
- strncmp(map_name, "x-mas", 3) == 0) {
- town = 7;
- } else if (strncmp(map_name, "comodo", 3) == 0) {
- town = 8;
- } else if (strncmp(map_name, "juno", 3) == 0 ||
- strncmp(map_name, "yuno", 3) == 0) {
- town = 9;
- } else if (strncmp(map_name, "amatsu", 3) == 0) {
- town = 10;
- } else if (strncmp(map_name, "kunlun", 3) == 0 ||
- strncmp(map_name, "gonryun", 3) == 0) {
- town = 11;
- } else if (strncmp(map_name, "umbala", 3) == 0) {
- town = 12;
- } else if (strncmp(map_name, "niflheim", 3) == 0) {
- town = 13;
- } else if (strncmp(map_name, "louyang", 3) == 0) {
- town = 14;
- } else if (strncmp(map_name, "new_1-1", 3) == 0 ||
- strncmp(map_name, "startpoint", 3) == 0 ||
- strncmp(map_name, "beginning", 3) == 0) {
- town = 15;
- } else if (strncmp(map_name, "sec_pri", 3) == 0 ||
- strncmp(map_name, "prison", 3) == 0 ||
- strncmp(map_name, "jail", 3) == 0) {
- town = 16;
- } else if (strncmp(map_name, "jawaii", 3) == 0) {
- town = 17;
- } else if (strncmp(map_name, "ayothaya", 3) == 0) {
- town = 18;
- } else if (strncmp(map_name, "einbroch", 5) == 0) {
- town = 19;
- } else if (strncmp(map_name, "lighthalzen", 3) == 0) {
- town = 20;
- } else if (strncmp(map_name, "einbech", 5) == 0) {
- town = 21;
- } else if (strncmp(map_name, "hugel", 3) == 0) {
- town = 22;
- } else if (strncmp(map_name, "rachel", 3) == 0) {
- town = 23;
- } else if (strncmp(map_name, "veins", 3) == 0) {
- town = 24;
- } else if (strncmp(map_name, "moscovia", 3) == 0) {
- town = 25;
- } else if (strncmp(map_name, "mid_camp", 3) == 0) {
- town = 26;
- } else if (strncmp(map_name, "manuk", 3) == 0) {
- town = 27;
- } else if (strncmp(map_name, "splendide", 3) == 0) {
- town = 28;
- } else if (strncmp(map_name, "brasilis", 3) == 0) {
- town = 29;
- } else if (strncmp(map_name, "dicastes01", 3) == 0) {
- town = 30;
- } else if (strcmp(map_name, "mora") == 0) {
- town = 31;
- } else if (strncmp(map_name, "dewata", 3) == 0) {
- town = 32;
- } else if (strncmp(map_name, "malangdo", 5) == 0) {
- town = 33;
- } else if (strncmp(map_name, "malaya", 5) == 0) {
- town = 34;
- } else if (strncmp(map_name, "eclage", 3) == 0) {
- town = 35;
- }
-
- if (town >= 0 && town < ARRAYLENGTH(data)) {
- m = map_mapname2mapid(data[town].map);
- if (m >= 0 && map[m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
- clif_displaymessage(fd, msg_txt(247));
- return -1;
- }
- if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
- clif_displaymessage(fd, msg_txt(248));
- return -1;
- }
- if (pc_setpos(sd, mapindex_name2id(data[town].map), data[town].x, data[town].y, CLR_TELEPORT) == 0) {
- clif_displaymessage(fd, msg_txt(0)); // Warped.
- } else {
- clif_displaymessage(fd, msg_txt(1)); // Map not found.
- return -1;
- }
- } else { // if you arrive here, you have an error in town variable when reading of names
- clif_displaymessage(fd, msg_txt(38)); // Invalid location number or name.
- return -1;
- }
-
- return 0;
+ { MAP_ALDEBARAN, 140, 131 }, // 6=Al de Baran
+ { MAP_LUTIE, 147, 134 }, // 7=Lutie
+ { MAP_COMODO, 209, 143 }, // 8=Comodo
+ { MAP_YUNO, 157, 51 }, // 9=Yuno
+ { MAP_AMATSU, 198, 84 }, // 10=Amatsu
+ { MAP_GONRYUN, 160, 120 }, // 11=Gonryun
+ { MAP_UMBALA, 89, 157 }, // 12=Umbala
+ { MAP_NIFLHEIM, 21, 153 }, // 13=Niflheim
+ { MAP_LOUYANG, 217, 40 }, // 14=Louyang
+ { MAP_NOVICE, 53, 111 }, // 15=Training Grounds
+ { MAP_JAIL, 23, 61 }, // 16=Prison
+ { MAP_JAWAII, 249, 127 }, // 17=Jawaii
+ { MAP_AYOTHAYA, 151, 117 }, // 18=Ayothaya
+ { MAP_EINBROCH, 64, 200 }, // 19=Einbroch
+ { MAP_LIGHTHALZEN, 158, 92 }, // 20=Lighthalzen
+ { MAP_EINBECH, 70, 95 }, // 21=Einbech
+ { MAP_HUGEL, 96, 145 }, // 22=Hugel
+ { MAP_RACHEL, 130, 110 }, // 23=Rachel
+ { MAP_VEINS, 216, 123 }, // 24=Veins
+ { MAP_MOSCOVIA, 223, 184 }, // 25=Moscovia
+ { MAP_MIDCAMP, 180, 240 }, // 26=Midgard Camp
+ { MAP_MANUK, 282, 138 }, // 27=Manuk
+ { MAP_SPLENDIDE, 197, 176 }, // 28=Splendide
+ { MAP_BRASILIS, 182, 239 }, // 29=Brasilis
+ { MAP_DICASTES, 198, 187 }, // 30=El Dicastes
+ { MAP_MORA, 44, 151 }, // 31=Mora
+ { MAP_DEWATA, 200, 180 }, // 32=Dewata
+ { MAP_MALANGDO, 140, 114 }, // 33=Malangdo Island
+ { MAP_MALAYA, 242, 211 }, // 34=Malaya Port
+ { MAP_ECLAGE, 110, 39 }, // 35=Eclage
+ };
+
+ nullpo_retr(-1, sd);
+
+ if( map[sd->bl.m].flag.nogo && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE) ) {
+ clif_displaymessage(sd->fd,msg_txt(995)); // You cannot use @go on this map.
+ return 0;
+ }
+
+ memset(map_name, '\0', sizeof(map_name));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
+
+ // get the number
+ town = atoi(message);
+
+ if (!message || !*message || sscanf(message, "%11s", map_name) < 1 || town < 0 || town >= ARRAYLENGTH(data))
+ {// no value matched so send the list of locations
+ const char* text;
+
+ // attempt to find the text help string
+ text = atcommand_help_string( command );
+
+ clif_displaymessage(fd, msg_txt(38)); // Invalid location number, or name.
+
+ if( text )
+ {// send the text to the client
+ clif_displaymessage( fd, text );
+ }
+
+ return -1;
+ }
+
+ // get possible name of the city
+ map_name[MAP_NAME_LENGTH-1] = '\0';
+ for (i = 0; map_name[i]; i++)
+ map_name[i] = TOLOWER(map_name[i]);
+ // try to identify the map name
+ if (strncmp(map_name, "prontera", 3) == 0) {
+ town = 0;
+ } else if (strncmp(map_name, "morocc", 4) == 0 ||
+ strncmp(map_name, "morroc", 4) == 0) {
+ town = 1;
+ } else if (strncmp(map_name, "geffen", 3) == 0) {
+ town = 2;
+ } else if (strncmp(map_name, "payon", 3) == 0) {
+ town = 3;
+ } else if (strncmp(map_name, "alberta", 3) == 0) {
+ town = 4;
+ } else if (strncmp(map_name, "izlude", 3) == 0) {
+ town = 5;
+ } else if (strncmp(map_name, "aldebaran", 3) == 0) {
+ town = 6;
+ } else if (strncmp(map_name, "lutie", 3) == 0 ||
+ strcmp(map_name, "christmas") == 0 ||
+ strncmp(map_name, "xmas", 3) == 0 ||
+ strncmp(map_name, "x-mas", 3) == 0) {
+ town = 7;
+ } else if (strncmp(map_name, "comodo", 3) == 0) {
+ town = 8;
+ } else if (strncmp(map_name, "juno", 3) == 0 ||
+ strncmp(map_name, "yuno", 3) == 0) {
+ town = 9;
+ } else if (strncmp(map_name, "amatsu", 3) == 0) {
+ town = 10;
+ } else if (strncmp(map_name, "kunlun", 3) == 0 ||
+ strncmp(map_name, "gonryun", 3) == 0) {
+ town = 11;
+ } else if (strncmp(map_name, "umbala", 3) == 0) {
+ town = 12;
+ } else if (strncmp(map_name, "niflheim", 3) == 0) {
+ town = 13;
+ } else if (strncmp(map_name, "louyang", 3) == 0) {
+ town = 14;
+ } else if (strncmp(map_name, "new_1-1", 3) == 0 ||
+ strncmp(map_name, "startpoint", 3) == 0 ||
+ strncmp(map_name, "beginning", 3) == 0) {
+ town = 15;
+ } else if (strncmp(map_name, "sec_pri", 3) == 0 ||
+ strncmp(map_name, "prison", 3) == 0 ||
+ strncmp(map_name, "jail", 3) == 0) {
+ town = 16;
+ } else if (strncmp(map_name, "jawaii", 3) == 0) {
+ town = 17;
+ } else if (strncmp(map_name, "ayothaya", 3) == 0) {
+ town = 18;
+ } else if (strncmp(map_name, "einbroch", 5) == 0) {
+ town = 19;
+ } else if (strncmp(map_name, "lighthalzen", 3) == 0) {
+ town = 20;
+ } else if (strncmp(map_name, "einbech", 5) == 0) {
+ town = 21;
+ } else if (strncmp(map_name, "hugel", 3) == 0) {
+ town = 22;
+ } else if (strncmp(map_name, "rachel", 3) == 0) {
+ town = 23;
+ } else if (strncmp(map_name, "veins", 3) == 0) {
+ town = 24;
+ } else if (strncmp(map_name, "moscovia", 3) == 0) {
+ town = 25;
+ } else if (strncmp(map_name, "mid_camp", 3) == 0) {
+ town = 26;
+ } else if (strncmp(map_name, "manuk", 3) == 0) {
+ town = 27;
+ } else if (strncmp(map_name, "splendide", 3) == 0) {
+ town = 28;
+ } else if (strncmp(map_name, "brasilis", 3) == 0) {
+ town = 29;
+ } else if (strncmp(map_name, "dicastes01", 3) == 0) {
+ town = 30;
+ } else if (strcmp(map_name, "mora") == 0) {
+ town = 31;
+ } else if (strncmp(map_name, "dewata", 3) == 0) {
+ town = 32;
+ } else if (strncmp(map_name, "malangdo", 5) == 0) {
+ town = 33;
+ } else if (strncmp(map_name, "malaya", 5) == 0) {
+ town = 34;
+ } else if (strncmp(map_name, "eclage", 3) == 0) {
+ town = 35;
+ }
+
+ if (town >= 0 && town < ARRAYLENGTH(data))
+ {
+ m = map_mapname2mapid(data[town].map);
+ if (m >= 0 && map[m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
+ clif_displaymessage(fd, msg_txt(247));
+ return -1;
+ }
+ if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
+ clif_displaymessage(fd, msg_txt(248));
+ return -1;
+ }
+ if (pc_setpos(sd, mapindex_name2id(data[town].map), data[town].x, data[town].y, CLR_TELEPORT) == 0) {
+ clif_displaymessage(fd, msg_txt(0)); // Warped.
+ } else {
+ clif_displaymessage(fd, msg_txt(1)); // Map not found.
+ return -1;
+ }
+ } else { // if you arrive here, you have an error in town variable when reading of names
+ clif_displaymessage(fd, msg_txt(38)); // Invalid location number or name.
+ return -1;
+ }
+
+ return 0;
}
/*==========================================
@@ -1941,96 +2069,96 @@ ACMD_FUNC(go)
*------------------------------------------*/
ACMD_FUNC(monster)
{
- char name[NAME_LENGTH];
- char monster[NAME_LENGTH];
- char eventname[EVENT_NAME_LENGTH] = "";
- int mob_id;
- int number = 0;
- int count;
- int i, k, range;
- short mx, my;
- unsigned int size;
- nullpo_retr(-1, sd);
-
- memset(name, '\0', sizeof(name));
- memset(monster, '\0', sizeof(monster));
- memset(atcmd_output, '\0', sizeof(atcmd_output));
-
- if (!message || !*message) {
- clif_displaymessage(fd, msg_txt(80)); // Give the display name or monster name/id please.
- return -1;
- }
- if (sscanf(message, "\"%23[^\"]\" %23s %d", name, monster, &number) > 1 ||
- sscanf(message, "%23s \"%23[^\"]\" %d", monster, name, &number) > 1) {
- //All data can be left as it is.
- } else if ((count=sscanf(message, "%23s %d %23s", monster, &number, name)) > 1) {
- //Here, it is possible name was not given and we are using monster for it.
- if (count < 3) //Blank mob's name.
- name[0] = '\0';
- } else if (sscanf(message, "%23s %23s %d", name, monster, &number) > 1) {
- //All data can be left as it is.
- } else if (sscanf(message, "%23s", monster) > 0) {
- //As before, name may be already filled.
- name[0] = '\0';
- } else {
- clif_displaymessage(fd, msg_txt(80)); // Give a display name and monster name/id please.
- return -1;
- }
-
- if ((mob_id = mobdb_searchname(monster)) == 0) // check name first (to avoid possible name begining by a number)
- mob_id = mobdb_checkid(atoi(monster));
-
- if (mob_id == 0) {
- clif_displaymessage(fd, msg_txt(40)); // Invalid monster ID or name.
- return -1;
- }
-
- if (mob_id == MOBID_EMPERIUM) {
- clif_displaymessage(fd, msg_txt(83)); // Monster 'Emperium' cannot be spawned.
- return -1;
- }
-
- if (number <= 0)
- number = 1;
-
- if (!name[0])
- strcpy(name, "--ja--");
-
- // If value of atcommand_spawn_quantity_limit directive is greater than or equal to 1 and quantity of monsters is greater than value of the directive
- if (battle_config.atc_spawn_quantity_limit && number > battle_config.atc_spawn_quantity_limit)
- number = battle_config.atc_spawn_quantity_limit;
-
- if (strcmp(command+1, "monstersmall") == 0)
- size = SZ_MEDIUM; // This is just gorgeous [mkbu95]
- else if (strcmp(command+1, "monsterbig") == 0)
- size = SZ_BIG;
- else
- size = SZ_SMALL;
-
- if (battle_config.etc_log)
- ShowInfo("%s monster='%s' name='%s' id=%d count=%d (%d,%d)\n", command, monster, name, mob_id, number, sd->bl.x, sd->bl.y);
-
- count = 0;
- range = (int)sqrt((float)number) +2; // calculation of an odd number (+ 4 area around)
- for (i = 0; i < number; i++) {
- map_search_freecell(&sd->bl, 0, &mx, &my, range, range, 0);
- k = mob_once_spawn(sd, sd->bl.m, mx, my, name, mob_id, 1, eventname, size, AI_NONE);
- count += (k != 0) ? 1 : 0;
- }
-
- if (count != 0)
- if (number == count)
- clif_displaymessage(fd, msg_txt(39)); // All monster summoned!
- else {
- sprintf(atcmd_output, msg_txt(240), count); // %d monster(s) summoned!
- clif_displaymessage(fd, atcmd_output);
- }
- else {
- clif_displaymessage(fd, msg_txt(40)); // Invalid monster ID or name.
- return -1;
- }
-
- return 0;
+ char name[NAME_LENGTH];
+ char monster[NAME_LENGTH];
+ char eventname[EVENT_NAME_LENGTH] = "";
+ int mob_id;
+ int number = 0;
+ int count;
+ int i, k, range;
+ short mx, my;
+ unsigned int size;
+ nullpo_retr(-1, sd);
+
+ memset(name, '\0', sizeof(name));
+ memset(monster, '\0', sizeof(monster));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
+
+ if (!message || !*message) {
+ clif_displaymessage(fd, msg_txt(80)); // Give the display name or monster name/id please.
+ return -1;
+ }
+ if (sscanf(message, "\"%23[^\"]\" %23s %d", name, monster, &number) > 1 ||
+ sscanf(message, "%23s \"%23[^\"]\" %d", monster, name, &number) > 1) {
+ //All data can be left as it is.
+ } else if ((count=sscanf(message, "%23s %d %23s", monster, &number, name)) > 1) {
+ //Here, it is possible name was not given and we are using monster for it.
+ if (count < 3) //Blank mob's name.
+ name[0] = '\0';
+ } else if (sscanf(message, "%23s %23s %d", name, monster, &number) > 1) {
+ //All data can be left as it is.
+ } else if (sscanf(message, "%23s", monster) > 0) {
+ //As before, name may be already filled.
+ name[0] = '\0';
+ } else {
+ clif_displaymessage(fd, msg_txt(80)); // Give a display name and monster name/id please.
+ return -1;
+ }
+
+ if ((mob_id = mobdb_searchname(monster)) == 0) // check name first (to avoid possible name begining by a number)
+ mob_id = mobdb_checkid(atoi(monster));
+
+ if (mob_id == 0) {
+ clif_displaymessage(fd, msg_txt(40)); // Invalid monster ID or name.
+ return -1;
+ }
+
+ if (mob_id == MOBID_EMPERIUM) {
+ clif_displaymessage(fd, msg_txt(83)); // Monster 'Emperium' cannot be spawned.
+ return -1;
+ }
+
+ if (number <= 0)
+ number = 1;
+
+ if( !name[0] )
+ strcpy(name, "--ja--");
+
+ // If value of atcommand_spawn_quantity_limit directive is greater than or equal to 1 and quantity of monsters is greater than value of the directive
+ if (battle_config.atc_spawn_quantity_limit && number > battle_config.atc_spawn_quantity_limit)
+ number = battle_config.atc_spawn_quantity_limit;
+
+ if (strcmp(command+1, "monstersmall") == 0)
+ size = SZ_MEDIUM; // This is just gorgeous [mkbu95]
+ else if (strcmp(command+1, "monsterbig") == 0)
+ size = SZ_BIG;
+ else
+ size = SZ_SMALL;
+
+ if (battle_config.etc_log)
+ ShowInfo("%s monster='%s' name='%s' id=%d count=%d (%d,%d)\n", command, monster, name, mob_id, number, sd->bl.x, sd->bl.y);
+
+ count = 0;
+ range = (int)sqrt((float)number) +2; // calculation of an odd number (+ 4 area around)
+ for (i = 0; i < number; i++) {
+ map_search_freecell(&sd->bl, 0, &mx, &my, range, range, 0);
+ k = mob_once_spawn(sd, sd->bl.m, mx, my, name, mob_id, 1, eventname, size, AI_NONE);
+ count += (k != 0) ? 1 : 0;
+ }
+
+ if (count != 0)
+ if (number == count)
+ clif_displaymessage(fd, msg_txt(39)); // All monster summoned!
+ else {
+ sprintf(atcmd_output, msg_txt(240), count); // %d monster(s) summoned!
+ clif_displaymessage(fd, atcmd_output);
+ }
+ else {
+ clif_displaymessage(fd, msg_txt(40)); // Invalid monster ID or name.
+ return -1;
+ }
+
+ return 0;
}
/*==========================================
@@ -2038,44 +2166,44 @@ ACMD_FUNC(monster)
*------------------------------------------*/
static int atkillmonster_sub(struct block_list *bl, va_list ap)
{
- struct mob_data *md;
- int flag;
+ struct mob_data *md;
+ int flag;
- nullpo_ret(md=(struct mob_data *)bl);
- flag = va_arg(ap, int);
+ nullpo_ret(md=(struct mob_data *)bl);
+ flag = va_arg(ap, int);
- if (md->guardian_data)
- return 0; //Do not touch WoE mobs!
+ if (md->guardian_data)
+ return 0; //Do not touch WoE mobs!
- if (flag)
- status_zap(bl,md->status.hp, 0);
- else
- status_kill(bl);
- return 1;
+ if (flag)
+ status_zap(bl,md->status.hp, 0);
+ else
+ status_kill(bl);
+ return 1;
}
ACMD_FUNC(killmonster)
{
- int map_id, drop_flag;
- char map_name[MAP_NAME_LENGTH_EXT];
- nullpo_retr(-1, sd);
+ int map_id, drop_flag;
+ char map_name[MAP_NAME_LENGTH_EXT];
+ nullpo_retr(-1, sd);
- memset(map_name, '\0', sizeof(map_name));
+ memset(map_name, '\0', sizeof(map_name));
- if (!message || !*message || sscanf(message, "%15s", map_name) < 1)
- map_id = sd->bl.m;
- else {
- if ((map_id = map_mapname2mapid(map_name)) < 0)
- map_id = sd->bl.m;
- }
+ if (!message || !*message || sscanf(message, "%15s", map_name) < 1)
+ map_id = sd->bl.m;
+ else {
+ if ((map_id = map_mapname2mapid(map_name)) < 0)
+ map_id = sd->bl.m;
+ }
- drop_flag = strcmp(command+1, "killmonster2");
+ drop_flag = strcmp(command+1, "killmonster2");
- map_foreachinmap(atkillmonster_sub, map_id, BL_MOB, -drop_flag);
+ map_foreachinmap(atkillmonster_sub, map_id, BL_MOB, -drop_flag);
- clif_displaymessage(fd, msg_txt(165)); // All monsters killed!
+ clif_displaymessage(fd, msg_txt(165)); // All monsters killed!
- return 0;
+ return 0;
}
/*==========================================
@@ -2083,77 +2211,77 @@ ACMD_FUNC(killmonster)
*------------------------------------------*/
ACMD_FUNC(refine)
{
- int i,j, position = 0, refine = 0, current_position, final_refine;
- int count;
- nullpo_retr(-1, sd);
-
- memset(atcmd_output, '\0', sizeof(atcmd_output));
-
- if (!message || !*message || sscanf(message, "%d %d", &position, &refine) < 2) {
- clif_displaymessage(fd, msg_txt(996)); // Please enter a position and an amount (usage: @refine <equip position> <+/- amount>).
- sprintf(atcmd_output, msg_txt(997), EQP_HEAD_LOW); // %d: Lower Headgear
- clif_displaymessage(fd, atcmd_output);
- sprintf(atcmd_output, msg_txt(998), EQP_HAND_R); // %d: Right Hand
- clif_displaymessage(fd, atcmd_output);
- sprintf(atcmd_output, msg_txt(999), EQP_GARMENT); // %d: Garment
- clif_displaymessage(fd, atcmd_output);
- sprintf(atcmd_output, msg_txt(1000), EQP_ACC_L); // %d: Left Accessory
- clif_displaymessage(fd, atcmd_output);
- sprintf(atcmd_output, msg_txt(1001), EQP_ARMOR); // %d: Body Armor
- clif_displaymessage(fd, atcmd_output);
- sprintf(atcmd_output, msg_txt(1002), EQP_HAND_L); // %d: Left Hand
- clif_displaymessage(fd, atcmd_output);
- sprintf(atcmd_output, msg_txt(1003), EQP_SHOES); // %d: Shoes
- clif_displaymessage(fd, atcmd_output);
- sprintf(atcmd_output, msg_txt(1004), EQP_ACC_R); // %d: Right Accessory
- clif_displaymessage(fd, atcmd_output);
- sprintf(atcmd_output, msg_txt(1005), EQP_HEAD_TOP); // %d: Top Headgear
- clif_displaymessage(fd, atcmd_output);
- sprintf(atcmd_output, msg_txt(1006), EQP_HEAD_MID); // %d: Mid Headgear
- clif_displaymessage(fd, atcmd_output);
- return -1;
- }
-
- refine = cap_value(refine, -MAX_REFINE, MAX_REFINE);
-
- count = 0;
- for (j = 0; j < EQI_MAX-1; j++) {
- if ((i = sd->equip_index[j]) < 0)
- continue;
- if (j == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == i)
- continue;
- if (j == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == i)
- continue;
- if (j == EQI_HEAD_TOP && (sd->equip_index[EQI_HEAD_MID] == i || sd->equip_index[EQI_HEAD_LOW] == i))
- continue;
-
- if (position && !(sd->status.inventory[i].equip & position))
- continue;
-
- final_refine = cap_value(sd->status.inventory[i].refine + refine, 0, MAX_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, 3);
- clif_refine(fd, 0, i, sd->status.inventory[i].refine);
- clif_delitem(sd, i, 1, 3);
- clif_additem(sd, i, 1, 0);
- pc_equipitem(sd, i, current_position);
- clif_misceffect(&sd->bl, 3);
- count++;
- }
- }
-
- if (count == 0)
- clif_displaymessage(fd, msg_txt(166)); // No item has been refined.
- else if (count == 1)
- clif_displaymessage(fd, msg_txt(167)); // 1 item has been refined.
- else {
- sprintf(atcmd_output, msg_txt(168), count); // %d items have been refined.
- clif_displaymessage(fd, atcmd_output);
- }
-
- return 0;
+ int i,j, position = 0, refine = 0, current_position, final_refine;
+ int count;
+ nullpo_retr(-1, sd);
+
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
+
+ if (!message || !*message || sscanf(message, "%d %d", &position, &refine) < 2) {
+ clif_displaymessage(fd, msg_txt(996)); // Please enter a position and an amount (usage: @refine <equip position> <+/- amount>).
+ sprintf(atcmd_output, msg_txt(997), EQP_HEAD_LOW); // %d: Lower Headgear
+ clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output, msg_txt(998), EQP_HAND_R); // %d: Right Hand
+ clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output, msg_txt(999), EQP_GARMENT); // %d: Garment
+ clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output, msg_txt(1000), EQP_ACC_L); // %d: Left Accessory
+ clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output, msg_txt(1001), EQP_ARMOR); // %d: Body Armor
+ clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output, msg_txt(1002), EQP_HAND_L); // %d: Left Hand
+ clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output, msg_txt(1003), EQP_SHOES); // %d: Shoes
+ clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output, msg_txt(1004), EQP_ACC_R); // %d: Right Accessory
+ clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output, msg_txt(1005), EQP_HEAD_TOP); // %d: Top Headgear
+ clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output, msg_txt(1006), EQP_HEAD_MID); // %d: Mid Headgear
+ clif_displaymessage(fd, atcmd_output);
+ return -1;
+ }
+
+ refine = cap_value(refine, -MAX_REFINE, MAX_REFINE);
+
+ count = 0;
+ for (j = 0; j < EQI_MAX-1; j++) {
+ if ((i = sd->equip_index[j]) < 0)
+ continue;
+ if(j == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == i)
+ continue;
+ if(j == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == i)
+ continue;
+ if(j == EQI_HEAD_TOP && (sd->equip_index[EQI_HEAD_MID] == i || sd->equip_index[EQI_HEAD_LOW] == i))
+ continue;
+
+ if(position && !(sd->status.inventory[i].equip & position))
+ continue;
+
+ final_refine = cap_value(sd->status.inventory[i].refine + refine, 0, MAX_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, 3);
+ clif_refine(fd, 0, i, sd->status.inventory[i].refine);
+ clif_delitem(sd, i, 1, 3);
+ clif_additem(sd, i, 1, 0);
+ pc_equipitem(sd, i, current_position);
+ clif_misceffect(&sd->bl, 3);
+ count++;
+ }
+ }
+
+ if (count == 0)
+ clif_displaymessage(fd, msg_txt(166)); // No item has been refined.
+ else if (count == 1)
+ clif_displaymessage(fd, msg_txt(167)); // 1 item has been refined.
+ else {
+ sprintf(atcmd_output, msg_txt(168), count); // %d items have been refined.
+ clif_displaymessage(fd, atcmd_output);
+ }
+
+ return 0;
}
/*==========================================
@@ -2161,58 +2289,58 @@ ACMD_FUNC(refine)
*------------------------------------------*/
ACMD_FUNC(produce)
{
- char item_name[100];
- int item_id, attribute = 0, star = 0;
- int flag = 0;
- struct item_data *item_data;
- struct item tmp_item;
- nullpo_retr(-1, sd);
-
- memset(atcmd_output, '\0', sizeof(atcmd_output));
- memset(item_name, '\0', sizeof(item_name));
-
- if (!message || !*message || (
- sscanf(message, "\"%99[^\"]\" %d %d", item_name, &attribute, &star) < 1 &&
- sscanf(message, "%99s %d %d", item_name, &attribute, &star) < 1
- )) {
- clif_displaymessage(fd, msg_txt(1007)); // Please enter at least one item name/ID (usage: @produce <equip name/ID> <element> <# of very's>).
- return -1;
- }
-
- if ((item_data = itemdb_searchname(item_name)) == NULL &&
- (item_data = itemdb_exists(atoi(item_name))) == NULL) {
- clif_displaymessage(fd, msg_txt(170)); //This item is not an equipment.
- return -1;
- }
-
- item_id = item_data->nameid;
-
- if (itemdb_isequip2(item_data)) {
- if (attribute < MIN_ATTRIBUTE || attribute > MAX_ATTRIBUTE)
- attribute = ATTRIBUTE_NORMAL;
- if (star < MIN_STAR || star > MAX_STAR)
- star = 0;
- memset(&tmp_item, 0, sizeof tmp_item);
- tmp_item.nameid = item_id;
- tmp_item.amount = 1;
- tmp_item.identify = 1;
- tmp_item.card[0] = CARD0_FORGE;
- tmp_item.card[1] = item_data->type==IT_WEAPON?
- ((star*5) << 8) + attribute:0;
- tmp_item.card[2] = GetWord(sd->status.char_id, 0);
- tmp_item.card[3] = GetWord(sd->status.char_id, 1);
- clif_produceeffect(sd, 0, item_id);
- clif_misceffect(&sd->bl, 3);
-
- if ((flag = pc_additem(sd, &tmp_item, 1, LOG_TYPE_COMMAND)))
- clif_additem(sd, 0, 0, flag);
- } else {
- sprintf(atcmd_output, msg_txt(169), item_id, item_data->name); // The item (%d: '%s') is not equipable.
- clif_displaymessage(fd, atcmd_output);
- return -1;
- }
-
- return 0;
+ char item_name[100];
+ int item_id, attribute = 0, star = 0;
+ int flag = 0;
+ struct item_data *item_data;
+ struct item tmp_item;
+ nullpo_retr(-1, sd);
+
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
+ memset(item_name, '\0', sizeof(item_name));
+
+ if (!message || !*message || (
+ sscanf(message, "\"%99[^\"]\" %d %d", item_name, &attribute, &star) < 1 &&
+ sscanf(message, "%99s %d %d", item_name, &attribute, &star) < 1
+ )) {
+ clif_displaymessage(fd, msg_txt(1007)); // Please enter at least one item name/ID (usage: @produce <equip name/ID> <element> <# of very's>).
+ return -1;
+ }
+
+ if ( (item_data = itemdb_searchname(item_name)) == NULL &&
+ (item_data = itemdb_exists(atoi(item_name))) == NULL ) {
+ clif_displaymessage(fd, msg_txt(170)); //This item is not an equipment.
+ return -1;
+ }
+
+ item_id = item_data->nameid;
+
+ if (itemdb_isequip2(item_data)) {
+ if (attribute < MIN_ATTRIBUTE || attribute > MAX_ATTRIBUTE)
+ attribute = ATTRIBUTE_NORMAL;
+ if (star < MIN_STAR || star > MAX_STAR)
+ star = 0;
+ memset(&tmp_item, 0, sizeof tmp_item);
+ tmp_item.nameid = item_id;
+ tmp_item.amount = 1;
+ tmp_item.identify = 1;
+ tmp_item.card[0] = CARD0_FORGE;
+ tmp_item.card[1] = item_data->type==IT_WEAPON?
+ ((star*5) << 8) + attribute:0;
+ tmp_item.card[2] = GetWord(sd->status.char_id, 0);
+ tmp_item.card[3] = GetWord(sd->status.char_id, 1);
+ clif_produceeffect(sd, 0, item_id);
+ clif_misceffect(&sd->bl, 3);
+
+ if ((flag = pc_additem(sd, &tmp_item, 1, LOG_TYPE_COMMAND)))
+ clif_additem(sd, 0, 0, flag);
+ } else {
+ sprintf(atcmd_output, msg_txt(169), item_id, item_data->name); // The item (%d: '%s') is not equipable.
+ clif_displaymessage(fd, atcmd_output);
+ return -1;
+ }
+
+ return 0;
}
/*==========================================
@@ -2220,32 +2348,35 @@ ACMD_FUNC(produce)
*------------------------------------------*/
ACMD_FUNC(memo)
{
- int position = 0;
- nullpo_retr(-1, sd);
+ int position = 0;
+ nullpo_retr(-1, sd);
- memset(atcmd_output, '\0', sizeof(atcmd_output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
- if (!message || !*message || sscanf(message, "%d", &position) < 1) {
- int i;
- clif_displaymessage(sd->fd, msg_txt(668));
- for (i = 0; i < MAX_MEMOPOINTS; i++) {
- if (sd->status.memo_point[i].map)
- sprintf(atcmd_output, "%d - %s (%d,%d)", i, mapindex_id2name(sd->status.memo_point[i].map), sd->status.memo_point[i].x, sd->status.memo_point[i].y);
- else
- sprintf(atcmd_output, msg_txt(171), i); // %d - void
- clif_displaymessage(sd->fd, atcmd_output);
- }
- return 0;
- }
+ if( !message || !*message || sscanf(message, "%d", &position) < 1 )
+ {
+ int i;
+ clif_displaymessage(sd->fd, msg_txt(668));
+ for( i = 0; i < MAX_MEMOPOINTS; i++ )
+ {
+ if( sd->status.memo_point[i].map )
+ sprintf(atcmd_output, "%d - %s (%d,%d)", i, mapindex_id2name(sd->status.memo_point[i].map), sd->status.memo_point[i].x, sd->status.memo_point[i].y);
+ else
+ sprintf(atcmd_output, msg_txt(171), i); // %d - void
+ clif_displaymessage(sd->fd, atcmd_output);
+ }
+ return 0;
+ }
- if (position < 0 || position >= MAX_MEMOPOINTS) {
- sprintf(atcmd_output, msg_txt(1008), 0, MAX_MEMOPOINTS-1); // Please enter a valid position (usage: @memo <memo_position:%d-%d>).
- clif_displaymessage(fd, atcmd_output);
- return -1;
- }
+ if( position < 0 || position >= MAX_MEMOPOINTS )
+ {
+ sprintf(atcmd_output, msg_txt(1008), 0, MAX_MEMOPOINTS-1); // Please enter a valid position (usage: @memo <memo_position:%d-%d>).
+ clif_displaymessage(fd, atcmd_output);
+ return -1;
+ }
- pc_memo(sd, position);
- return 0;
+ pc_memo(sd, position);
+ return 0;
}
/*==========================================
@@ -2253,24 +2384,24 @@ ACMD_FUNC(memo)
*------------------------------------------*/
ACMD_FUNC(gat)
{
- int y;
- nullpo_retr(-1, sd);
+ int y;
+ nullpo_retr(-1, sd);
- memset(atcmd_output, '\0', sizeof(atcmd_output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
- for (y = 2; y >= -2; y--) {
- 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));
+ for (y = 2; y >= -2; y--) {
+ 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);
- }
+ clif_displaymessage(fd, atcmd_output);
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -2278,19 +2409,19 @@ ACMD_FUNC(gat)
*------------------------------------------*/
ACMD_FUNC(displaystatus)
{
- int i, type, flag, tick, val1 = 0, val2 = 0, val3 = 0;
- nullpo_retr(-1, sd);
+ int i, type, flag, tick, val1 = 0, val2 = 0, val3 = 0;
+ nullpo_retr(-1, sd);
- if (!message || !*message || (i = sscanf(message, "%d %d %d %d %d %d", &type, &flag, &tick, &val1, &val2, &val3)) < 1) {
- clif_displaymessage(fd, msg_txt(1009)); // Please enter a status type/flag (usage: @displaystatus <status type> <flag> <tick> {<val1> {<val2> {<val3>}}}).
- return -1;
- }
- if (i < 2) flag = 1;
- if (i < 3) tick = 0;
+ if (!message || !*message || (i = sscanf(message, "%d %d %d %d %d %d", &type, &flag, &tick, &val1, &val2, &val3)) < 1) {
+ clif_displaymessage(fd, msg_txt(1009)); // Please enter a status type/flag (usage: @displaystatus <status type> <flag> <tick> {<val1> {<val2> {<val3>}}}).
+ return -1;
+ }
+ if (i < 2) flag = 1;
+ if (i < 3) tick = 0;
- clif_status_change(&sd->bl, type, flag, tick, val1, val2, val3);
+ clif_status_change(&sd->bl, type, flag, tick, val1, val2, val3);
- return 0;
+ return 0;
}
/*==========================================
@@ -2298,39 +2429,47 @@ ACMD_FUNC(displaystatus)
*------------------------------------------*/
ACMD_FUNC(statuspoint)
{
- int point;
- unsigned int new_status_point;
-
- if (!message || !*message || (point = atoi(message)) == 0) {
- clif_displaymessage(fd, msg_txt(1010)); // Please enter a number (usage: @stpoint <number of points>).
- return -1;
- }
-
- if (point < 0) {
- if (sd->status.status_point < (unsigned int)(-point)) {
- new_status_point = 0;
- } else {
- new_status_point = sd->status.status_point + point;
- }
- } else if (UINT_MAX - sd->status.status_point < (unsigned int)point) {
- new_status_point = UINT_MAX;
- } else {
- new_status_point = sd->status.status_point + point;
- }
-
- if (new_status_point != sd->status.status_point) {
- sd->status.status_point = new_status_point;
- clif_updatestatus(sd, SP_STATUSPOINT);
- clif_displaymessage(fd, msg_txt(174)); // Number of status points changed.
- } else {
- if (point < 0)
- clif_displaymessage(fd, msg_txt(41)); // Unable to decrease the number/value.
- else
- clif_displaymessage(fd, msg_txt(149)); // Unable to increase the number/value.
- return -1;
- }
-
- return 0;
+ int point;
+ unsigned int new_status_point;
+
+ if (!message || !*message || (point = atoi(message)) == 0) {
+ clif_displaymessage(fd, msg_txt(1010)); // Please enter a number (usage: @stpoint <number of points>).
+ return -1;
+ }
+
+ if(point < 0)
+ {
+ if(sd->status.status_point < (unsigned int)(-point))
+ {
+ new_status_point = 0;
+ }
+ else
+ {
+ new_status_point = sd->status.status_point + point;
+ }
+ }
+ else if(UINT_MAX - sd->status.status_point < (unsigned int)point)
+ {
+ new_status_point = UINT_MAX;
+ }
+ else
+ {
+ new_status_point = sd->status.status_point + point;
+ }
+
+ if (new_status_point != sd->status.status_point) {
+ sd->status.status_point = new_status_point;
+ clif_updatestatus(sd, SP_STATUSPOINT);
+ clif_displaymessage(fd, msg_txt(174)); // Number of status points changed.
+ } else {
+ if (point < 0)
+ clif_displaymessage(fd, msg_txt(41)); // Unable to decrease the number/value.
+ else
+ clif_displaymessage(fd, msg_txt(149)); // Unable to increase the number/value.
+ return -1;
+ }
+
+ return 0;
}
/*==========================================
@@ -2338,40 +2477,48 @@ ACMD_FUNC(statuspoint)
*------------------------------------------*/
ACMD_FUNC(skillpoint)
{
- int point;
- unsigned int new_skill_point;
- nullpo_retr(-1, sd);
-
- if (!message || !*message || (point = atoi(message)) == 0) {
- clif_displaymessage(fd, msg_txt(1011)); // Please enter a number (usage: @skpoint <number of points>).
- return -1;
- }
-
- if (point < 0) {
- if (sd->status.skill_point < (unsigned int)(-point)) {
- new_skill_point = 0;
- } else {
- new_skill_point = sd->status.skill_point + point;
- }
- } else if (UINT_MAX - sd->status.skill_point < (unsigned int)point) {
- new_skill_point = UINT_MAX;
- } else {
- new_skill_point = sd->status.skill_point + point;
- }
-
- if (new_skill_point != sd->status.skill_point) {
- sd->status.skill_point = new_skill_point;
- clif_updatestatus(sd, SP_SKILLPOINT);
- clif_displaymessage(fd, msg_txt(175)); // Number of skill points changed.
- } else {
- if (point < 0)
- clif_displaymessage(fd, msg_txt(41)); // Unable to decrease the number/value.
- else
- clif_displaymessage(fd, msg_txt(149)); // Unable to increase the number/value.
- return -1;
- }
-
- return 0;
+ int point;
+ unsigned int new_skill_point;
+ nullpo_retr(-1, sd);
+
+ if (!message || !*message || (point = atoi(message)) == 0) {
+ clif_displaymessage(fd, msg_txt(1011)); // Please enter a number (usage: @skpoint <number of points>).
+ return -1;
+ }
+
+ if(point < 0)
+ {
+ if(sd->status.skill_point < (unsigned int)(-point))
+ {
+ new_skill_point = 0;
+ }
+ else
+ {
+ new_skill_point = sd->status.skill_point + point;
+ }
+ }
+ else if(UINT_MAX - sd->status.skill_point < (unsigned int)point)
+ {
+ new_skill_point = UINT_MAX;
+ }
+ else
+ {
+ new_skill_point = sd->status.skill_point + point;
+ }
+
+ if (new_skill_point != sd->status.skill_point) {
+ sd->status.skill_point = new_skill_point;
+ clif_updatestatus(sd, SP_SKILLPOINT);
+ clif_displaymessage(fd, msg_txt(175)); // Number of skill points changed.
+ } else {
+ if (point < 0)
+ clif_displaymessage(fd, msg_txt(41)); // Unable to decrease the number/value.
+ else
+ clif_displaymessage(fd, msg_txt(149)); // Unable to increase the number/value.
+ return -1;
+ }
+
+ return 0;
}
/*==========================================
@@ -2379,24 +2526,25 @@ ACMD_FUNC(skillpoint)
*------------------------------------------*/
ACMD_FUNC(zeny)
{
- int zeny=0, ret=-1;
- nullpo_retr(-1, sd);
+ int zeny=0, ret=-1;
+ nullpo_retr(-1, sd);
- if (!message || !*message || (zeny = atoi(message)) == 0) {
- clif_displaymessage(fd, msg_txt(1012)); // Please enter an amount (usage: @zeny <amount>).
- return -1;
- }
+ if (!message || !*message || (zeny = atoi(message)) == 0) {
+ clif_displaymessage(fd, msg_txt(1012)); // Please enter an amount (usage: @zeny <amount>).
+ return -1;
+ }
- if (zeny > 0) {
- if ((ret=pc_getzeny(sd,zeny,LOG_TYPE_COMMAND,NULL)) == 1)
- clif_displaymessage(fd, msg_txt(149)); // Unable to increase the number/value.
- } else {
- if (sd->status.zeny < -zeny) zeny = -sd->status.zeny;
- if ((ret=pc_payzeny(sd,-zeny,LOG_TYPE_COMMAND,NULL)) == 1)
- clif_displaymessage(fd, msg_txt(41)); // Unable to decrease the number/value.
- }
- if (!ret) clif_displaymessage(fd, msg_txt(176)); //ret=0 mean cmd success
- return 0;
+ if(zeny > 0){
+ if((ret=pc_getzeny(sd,zeny,LOG_TYPE_COMMAND,NULL)) == 1)
+ clif_displaymessage(fd, msg_txt(149)); // Unable to increase the number/value.
+ }
+ else {
+ if( sd->status.zeny < -zeny ) zeny = -sd->status.zeny;
+ if((ret=pc_payzeny(sd,-zeny,LOG_TYPE_COMMAND,NULL)) == 1)
+ clif_displaymessage(fd, msg_txt(41)); // Unable to decrease the number/value.
+ }
+ if(!ret) clif_displaymessage(fd, msg_txt(176)); //ret=0 mean cmd success
+ return 0;
}
/*==========================================
@@ -2404,61 +2552,61 @@ ACMD_FUNC(zeny)
*------------------------------------------*/
ACMD_FUNC(param)
{
- int i, value = 0, new_value, max;
- const char *param[] = { "str", "agi", "vit", "int", "dex", "luk" };
- short *status[6];
- //we don't use direct initialization because it isn't part of the c standard.
- nullpo_retr(-1, sd);
-
- memset(atcmd_output, '\0', sizeof(atcmd_output));
-
- if (!message || !*message || sscanf(message, "%d", &value) < 1 || value == 0) {
- clif_displaymessage(fd, msg_txt(1013)); // Please enter a valid value (usage: @str/@agi/@vit/@int/@dex/@luk <+/-adjustment>).
- return -1;
- }
-
- ARR_FIND(0, ARRAYLENGTH(param), i, strcmpi(command+1, param[i]) == 0);
-
- if (i == ARRAYLENGTH(param) || i > MAX_STATUS_TYPE) { // normally impossible...
- clif_displaymessage(fd, msg_txt(1013)); // Please enter a valid value (usage: @str/@agi/@vit/@int/@dex/@luk <+/-adjustment>).
- return -1;
- }
-
- status[0] = &sd->status.str;
- status[1] = &sd->status.agi;
- status[2] = &sd->status.vit;
- status[3] = &sd->status.int_;
- status[4] = &sd->status.dex;
- status[5] = &sd->status.luk;
-
- if (battle_config.atcommand_max_stat_bypass)
- max = SHRT_MAX;
- else
- max = pc_maxparameter(sd);
-
- if (value < 0 && *status[i] <= -value) {
- new_value = 1;
- } else if (max - *status[i] < value) {
- new_value = max;
- } else {
- new_value = *status[i] + value;
- }
-
- if (new_value != *status[i]) {
- *status[i] = new_value;
- clif_updatestatus(sd, SP_STR + i);
- clif_updatestatus(sd, SP_USTR + i);
- status_calc_pc(sd, 0);
- clif_displaymessage(fd, msg_txt(42)); // Stat changed.
- } else {
- if (value < 0)
- clif_displaymessage(fd, msg_txt(41)); // Unable to decrease the number/value.
- else
- clif_displaymessage(fd, msg_txt(149)); // Unable to increase the number/value.
- return -1;
- }
-
- return 0;
+ int i, value = 0, new_value, max;
+ const char* param[] = { "str", "agi", "vit", "int", "dex", "luk" };
+ short* status[6];
+ //we don't use direct initialization because it isn't part of the c standard.
+ nullpo_retr(-1, sd);
+
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
+
+ if (!message || !*message || sscanf(message, "%d", &value) < 1 || value == 0) {
+ clif_displaymessage(fd, msg_txt(1013)); // Please enter a valid value (usage: @str/@agi/@vit/@int/@dex/@luk <+/-adjustment>).
+ return -1;
+ }
+
+ ARR_FIND( 0, ARRAYLENGTH(param), i, strcmpi(command+1, param[i]) == 0 );
+
+ if( i == ARRAYLENGTH(param) || i > MAX_STATUS_TYPE) { // normally impossible...
+ clif_displaymessage(fd, msg_txt(1013)); // Please enter a valid value (usage: @str/@agi/@vit/@int/@dex/@luk <+/-adjustment>).
+ return -1;
+ }
+
+ status[0] = &sd->status.str;
+ status[1] = &sd->status.agi;
+ status[2] = &sd->status.vit;
+ status[3] = &sd->status.int_;
+ status[4] = &sd->status.dex;
+ status[5] = &sd->status.luk;
+
+ if( battle_config.atcommand_max_stat_bypass )
+ max = SHRT_MAX;
+ else
+ max = pc_maxparameter(sd);
+
+ if(value < 0 && *status[i] <= -value) {
+ new_value = 1;
+ } else if(max - *status[i] < value) {
+ new_value = max;
+ } else {
+ new_value = *status[i] + value;
+ }
+
+ if (new_value != *status[i]) {
+ *status[i] = new_value;
+ clif_updatestatus(sd, SP_STR + i);
+ clif_updatestatus(sd, SP_USTR + i);
+ status_calc_pc(sd, 0);
+ clif_displaymessage(fd, msg_txt(42)); // Stat changed.
+ } else {
+ if (value < 0)
+ clif_displaymessage(fd, msg_txt(41)); // Unable to decrease the number/value.
+ else
+ clif_displaymessage(fd, msg_txt(149)); // Unable to increase the number/value.
+ return -1;
+ }
+
+ return 0;
}
/*==========================================
@@ -2466,58 +2614,58 @@ ACMD_FUNC(param)
*------------------------------------------*/
ACMD_FUNC(stat_all)
{
- int index, count, value, max, new_value;
- short *status[6];
- //we don't use direct initialization because it isn't part of the c standard.
- nullpo_retr(-1, sd);
-
- status[0] = &sd->status.str;
- status[1] = &sd->status.agi;
- status[2] = &sd->status.vit;
- status[3] = &sd->status.int_;
- status[4] = &sd->status.dex;
- status[5] = &sd->status.luk;
-
- if (!message || !*message || sscanf(message, "%d", &value) < 1 || value == 0) {
- value = pc_maxparameter(sd);
- max = pc_maxparameter(sd);
- } else {
- if (battle_config.atcommand_max_stat_bypass)
- max = SHRT_MAX;
- else
- max = pc_maxparameter(sd);
- }
-
- count = 0;
- for (index = 0; index < ARRAYLENGTH(status); index++) {
-
- if (value > 0 && *status[index] > max - value)
- new_value = max;
- else if (value < 0 && *status[index] <= -value)
- new_value = 1;
- else
- new_value = *status[index] +value;
-
- if (new_value != (int)*status[index]) {
- *status[index] = new_value;
- clif_updatestatus(sd, SP_STR + index);
- clif_updatestatus(sd, SP_USTR + index);
- count++;
- }
- }
-
- if (count > 0) { // if at least 1 stat modified
- status_calc_pc(sd, 0);
- clif_displaymessage(fd, msg_txt(84)); // All stats changed!
- } else {
- if (value < 0)
- clif_displaymessage(fd, msg_txt(177)); // You cannot decrease that stat anymore.
- else
- clif_displaymessage(fd, msg_txt(178)); // You cannot increase that stat anymore.
- return -1;
- }
-
- return 0;
+ int index, count, value, max, new_value;
+ short* status[6];
+ //we don't use direct initialization because it isn't part of the c standard.
+ nullpo_retr(-1, sd);
+
+ status[0] = &sd->status.str;
+ status[1] = &sd->status.agi;
+ status[2] = &sd->status.vit;
+ status[3] = &sd->status.int_;
+ status[4] = &sd->status.dex;
+ status[5] = &sd->status.luk;
+
+ if (!message || !*message || sscanf(message, "%d", &value) < 1 || value == 0) {
+ value = pc_maxparameter(sd);
+ max = pc_maxparameter(sd);
+ } else {
+ if( battle_config.atcommand_max_stat_bypass )
+ max = SHRT_MAX;
+ else
+ max = pc_maxparameter(sd);
+ }
+
+ count = 0;
+ for (index = 0; index < ARRAYLENGTH(status); index++) {
+
+ if (value > 0 && *status[index] > max - value)
+ new_value = max;
+ else if (value < 0 && *status[index] <= -value)
+ new_value = 1;
+ else
+ new_value = *status[index] +value;
+
+ if (new_value != (int)*status[index]) {
+ *status[index] = new_value;
+ clif_updatestatus(sd, SP_STR + index);
+ clif_updatestatus(sd, SP_USTR + index);
+ count++;
+ }
+ }
+
+ if (count > 0) { // if at least 1 stat modified
+ status_calc_pc(sd, 0);
+ clif_displaymessage(fd, msg_txt(84)); // All stats changed!
+ } else {
+ if (value < 0)
+ clif_displaymessage(fd, msg_txt(177)); // You cannot decrease that stat anymore.
+ else
+ clif_displaymessage(fd, msg_txt(178)); // You cannot increase that stat anymore.
+ return -1;
+ }
+
+ return 0;
}
/*==========================================
@@ -2525,40 +2673,40 @@ ACMD_FUNC(stat_all)
*------------------------------------------*/
ACMD_FUNC(guildlevelup)
{
- int level = 0;
- short added_level;
- struct guild *guild_info;
- nullpo_retr(-1, sd);
+ 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, msg_txt(1014)); // Please enter a valid level (usage: @guildlvup/@guildlvlup <# of levels>).
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%d", &level) < 1 || level == 0) {
+ clif_displaymessage(fd, msg_txt(1014)); // Please enter a valid level (usage: @guildlvup/@guildlvlup <# of levels>).
+ return -1;
+ }
- if (sd->status.guild_id <= 0 || (guild_info = guild_search(sd->status.guild_id)) == NULL) {
- clif_displaymessage(fd, msg_txt(43)); // You're not in a guild.
- return -1;
- }
- //if (strcmp(sd->status.name, guild_info->master) != 0) {
- // clif_displaymessage(fd, msg_txt(44)); // You're not the master of your guild.
- // return -1;
- //}
+ if (sd->status.guild_id <= 0 || (guild_info = guild_search(sd->status.guild_id)) == NULL) {
+ clif_displaymessage(fd, msg_txt(43)); // You're not in a guild.
+ return -1;
+ }
+ //if (strcmp(sd->status.name, guild_info->master) != 0) {
+ // clif_displaymessage(fd, msg_txt(44)); // You're not the master of your guild.
+ // return -1;
+ //}
- added_level = (short)level;
- if (level > 0 && (level > MAX_GUILDLEVEL || added_level > ((short)MAX_GUILDLEVEL - guild_info->guild_lv))) // fix positiv overflow
- added_level = (short)MAX_GUILDLEVEL - guild_info->guild_lv;
- else if (level < 0 && (level < -MAX_GUILDLEVEL || added_level < (1 - guild_info->guild_lv))) // fix negativ overflow
- added_level = 1 - guild_info->guild_lv;
+ added_level = (short)level;
+ if (level > 0 && (level > MAX_GUILDLEVEL || added_level > ((short)MAX_GUILDLEVEL - guild_info->guild_lv))) // fix positiv overflow
+ added_level = (short)MAX_GUILDLEVEL - guild_info->guild_lv;
+ else if (level < 0 && (level < -MAX_GUILDLEVEL || added_level < (1 - guild_info->guild_lv))) // fix negativ overflow
+ added_level = 1 - guild_info->guild_lv;
- if (added_level != 0) {
- intif_guild_change_basicinfo(guild_info->guild_id, GBI_GUILDLV, &added_level, sizeof(added_level));
- clif_displaymessage(fd, msg_txt(179)); // Guild level changed.
- } else {
- clif_displaymessage(fd, msg_txt(45)); // Guild level change failed.
- return -1;
- }
+ if (added_level != 0) {
+ intif_guild_change_basicinfo(guild_info->guild_id, GBI_GUILDLV, &added_level, sizeof(added_level));
+ clif_displaymessage(fd, msg_txt(179)); // Guild level changed.
+ } else {
+ clif_displaymessage(fd, msg_txt(45)); // Guild level change failed.
+ return -1;
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -2566,38 +2714,39 @@ ACMD_FUNC(guildlevelup)
*------------------------------------------*/
ACMD_FUNC(makeegg)
{
- struct item_data *item_data;
- int id, pet_id;
- nullpo_retr(-1, sd);
-
- if (!message || !*message) {
- clif_displaymessage(fd, msg_txt(1015)); // Please enter a monster/egg name/ID (usage: @makeegg <pet>).
- return -1;
- }
-
- if ((item_data = itemdb_searchname(message)) != NULL) // for egg name
- id = item_data->nameid;
- else if ((id = mobdb_searchname(message)) != 0) // for monster name
- ;
- else
- id = atoi(message);
-
- pet_id = search_petDB_index(id, PET_CLASS);
- 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_;
- intif_create_pet(
- sd->status.account_id, 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);
- } else {
- clif_displaymessage(fd, msg_txt(180)); // The monster/egg name/id doesn't exist.
- return -1;
- }
-
- return 0;
+ struct item_data *item_data;
+ int id, pet_id;
+ nullpo_retr(-1, sd);
+
+ if (!message || !*message) {
+ clif_displaymessage(fd, msg_txt(1015)); // Please enter a monster/egg name/ID (usage: @makeegg <pet>).
+ return -1;
+ }
+
+ if ((item_data = itemdb_searchname(message)) != NULL) // for egg name
+ id = item_data->nameid;
+ else
+ if ((id = mobdb_searchname(message)) != 0) // for monster name
+ ;
+ else
+ id = atoi(message);
+
+ pet_id = search_petDB_index(id, PET_CLASS);
+ 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_;
+ intif_create_pet(
+ sd->status.account_id, 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);
+ } else {
+ clif_displaymessage(fd, msg_txt(180)); // The monster/egg name/id doesn't exist.
+ return -1;
+ }
+
+ return 0;
}
/*==========================================
@@ -2605,15 +2754,15 @@ ACMD_FUNC(makeegg)
*------------------------------------------*/
ACMD_FUNC(hatch)
{
- nullpo_retr(-1, sd);
- if (sd->status.pet_id <= 0)
- clif_sendegg(sd);
- else {
- clif_displaymessage(fd, msg_txt(181)); // You already have a pet.
- return -1;
- }
+ nullpo_retr(-1, sd);
+ if (sd->status.pet_id <= 0)
+ clif_sendegg(sd);
+ else {
+ clif_displaymessage(fd, msg_txt(181)); // You already have a pet.
+ return -1;
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -2621,35 +2770,36 @@ ACMD_FUNC(hatch)
*------------------------------------------*/
ACMD_FUNC(petfriendly)
{
- int friendly;
- struct pet_data *pd;
- nullpo_retr(-1, sd);
+ int friendly;
+ struct pet_data *pd;
+ nullpo_retr(-1, sd);
- if (!message || !*message || (friendly = atoi(message)) < 0) {
- clif_displaymessage(fd, msg_txt(1016)); // Please enter a valid value (usage: @petfriendly <0-1000>).
- return -1;
- }
+ if (!message || !*message || (friendly = atoi(message)) < 0) {
+ clif_displaymessage(fd, msg_txt(1016)); // Please enter a valid value (usage: @petfriendly <0-1000>).
+ return -1;
+ }
- pd = sd->pd;
- if (!pd) {
- clif_displaymessage(fd, msg_txt(184)); // Sorry, but you have no pet.
- return -1;
- }
+ pd = sd->pd;
+ if (!pd) {
+ clif_displaymessage(fd, msg_txt(184)); // Sorry, but you have no pet.
+ return -1;
+ }
- if (friendly < 0 || friendly > 1000) {
- clif_displaymessage(fd, msg_txt(37)); // An invalid number was specified.
- return -1;
- }
+ if (friendly < 0 || friendly > 1000)
+ {
+ clif_displaymessage(fd, msg_txt(37)); // An invalid number was specified.
+ return -1;
+ }
- if (friendly == pd->pet.intimate) {
- clif_displaymessage(fd, msg_txt(183)); // Pet intimacy is already at maximum.
- return -1;
- }
+ if (friendly == pd->pet.intimate) {
+ clif_displaymessage(fd, msg_txt(183)); // Pet intimacy is already at maximum.
+ return -1;
+ }
- pet_set_intimate(pd, friendly);
- clif_send_petstatus(sd);
- clif_displaymessage(fd, msg_txt(182)); // Pet intimacy changed.
- return 0;
+ pet_set_intimate(pd, friendly);
+ clif_send_petstatus(sd);
+ clif_displaymessage(fd, msg_txt(182)); // Pet intimacy changed.
+ return 0;
}
/*==========================================
@@ -2657,34 +2807,34 @@ ACMD_FUNC(petfriendly)
*------------------------------------------*/
ACMD_FUNC(pethungry)
{
- int hungry;
- struct pet_data *pd;
- nullpo_retr(-1, sd);
+ int hungry;
+ struct pet_data *pd;
+ nullpo_retr(-1, sd);
- if (!message || !*message || (hungry = atoi(message)) < 0) {
- clif_displaymessage(fd, msg_txt(1017)); // Please enter a valid number (usage: @pethungry <0-100>).
- return -1;
- }
+ if (!message || !*message || (hungry = atoi(message)) < 0) {
+ clif_displaymessage(fd, msg_txt(1017)); // Please enter a valid number (usage: @pethungry <0-100>).
+ return -1;
+ }
- pd = sd->pd;
- if (!sd->status.pet_id || !pd) {
- clif_displaymessage(fd, msg_txt(184)); // Sorry, but you have no pet.
- return -1;
- }
- if (hungry < 0 || hungry > 100) {
- clif_displaymessage(fd, msg_txt(37)); // An invalid number was specified.
- return -1;
- }
- if (hungry == pd->pet.hungry) {
- clif_displaymessage(fd, msg_txt(186)); // Pet hunger is already at maximum.
- return -1;
- }
+ pd = sd->pd;
+ if (!sd->status.pet_id || !pd) {
+ clif_displaymessage(fd, msg_txt(184)); // Sorry, but you have no pet.
+ return -1;
+ }
+ if (hungry < 0 || hungry > 100) {
+ clif_displaymessage(fd, msg_txt(37)); // An invalid number was specified.
+ return -1;
+ }
+ if (hungry == pd->pet.hungry) {
+ clif_displaymessage(fd, msg_txt(186)); // Pet hunger is already at maximum.
+ return -1;
+ }
- pd->pet.hungry = hungry;
- clif_send_petstatus(sd);
- clif_displaymessage(fd, msg_txt(185)); // Pet hunger changed.
+ pd->pet.hungry = hungry;
+ clif_send_petstatus(sd);
+ clif_displaymessage(fd, msg_txt(185)); // Pet hunger changed.
- return 0;
+ return 0;
}
/*==========================================
@@ -2692,66 +2842,64 @@ ACMD_FUNC(pethungry)
*------------------------------------------*/
ACMD_FUNC(petrename)
{
- struct pet_data *pd;
- nullpo_retr(-1, sd);
- if (!sd->status.pet_id || !sd->pd) {
- clif_displaymessage(fd, msg_txt(184)); // Sorry, but you have no pet.
- return -1;
- }
- pd = sd->pd;
- if (!pd->pet.rename_flag) {
- clif_displaymessage(fd, msg_txt(188)); // You can already rename your pet.
- return -1;
- }
+ struct pet_data *pd;
+ nullpo_retr(-1, sd);
+ if (!sd->status.pet_id || !sd->pd) {
+ clif_displaymessage(fd, msg_txt(184)); // Sorry, but you have no pet.
+ return -1;
+ }
+ pd = sd->pd;
+ if (!pd->pet.rename_flag) {
+ clif_displaymessage(fd, msg_txt(188)); // You can already rename your pet.
+ return -1;
+ }
- pd->pet.rename_flag = 0;
- intif_save_petdata(sd->status.account_id, &pd->pet);
- clif_send_petstatus(sd);
- clif_displaymessage(fd, msg_txt(187)); // You can now rename your pet.
+ pd->pet.rename_flag = 0;
+ intif_save_petdata(sd->status.account_id, &pd->pet);
+ clif_send_petstatus(sd);
+ clif_displaymessage(fd, msg_txt(187)); // You can now rename your pet.
- return 0;
+ return 0;
}
/*==========================================
*
*------------------------------------------*/
-ACMD_FUNC(recall)
-{
- struct map_session_data *pl_sd = NULL;
+ACMD_FUNC(recall) {
+ struct map_session_data *pl_sd = NULL;
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- if (!message || !*message) {
- clif_displaymessage(fd, msg_txt(1018)); // Please enter a player name (usage: @recall <char name/ID>).
- return -1;
- }
+ if (!message || !*message) {
+ clif_displaymessage(fd, msg_txt(1018)); // Please enter a player name (usage: @recall <char name/ID>).
+ return -1;
+ }
- if ((pl_sd=map_nick2sd((char *)message)) == NULL && (pl_sd=map_charid2sd(atoi(message))) == NULL) {
- clif_displaymessage(fd, msg_txt(3)); // Character not found.
- return -1;
- }
+ if((pl_sd=map_nick2sd((char *)message)) == NULL && (pl_sd=map_charid2sd(atoi(message))) == NULL)
+ {
+ clif_displaymessage(fd, msg_txt(3)); // Character not found.
+ return -1;
+ }
- if (pc_get_group_level(sd) < pc_get_group_level(pl_sd)) {
- clif_displaymessage(fd, msg_txt(81)); // Your GM level doesn't authorize you to preform this action on the specified player.
- return -1;
- }
+ if ( pc_get_group_level(sd) < pc_get_group_level(pl_sd) )
+ {
+ clif_displaymessage(fd, msg_txt(81)); // Your GM level doesn't authorize you to preform this action on the specified player.
+ return -1;
+ }
- if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
- clif_displaymessage(fd, msg_txt(1019)); // You are not authorized to warp someone to this map.
- return -1;
- }
- if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
- clif_displaymessage(fd, msg_txt(1020)); // You are not authorized to warp this player from their map.
- return -1;
- }
- if (pl_sd->bl.m == sd->bl.m && pl_sd->bl.x == sd->bl.x && pl_sd->bl.y == sd->bl.y) {
- return -1;
- }
- pc_setpos(pl_sd, sd->mapindex, sd->bl.x, sd->bl.y, CLR_RESPAWN);
- sprintf(atcmd_output, msg_txt(46), pl_sd->status.name); // %s recalled!
- clif_displaymessage(fd, atcmd_output);
+ if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
+ clif_displaymessage(fd, msg_txt(1019)); // You are not authorized to warp someone to this map.
+ return -1;
+ }
+ if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
+ clif_displaymessage(fd, msg_txt(1020)); // You are not authorized to warp this player from their map.
+ return -1;
+ }
+ pc_setpos(pl_sd, sd->mapindex, sd->bl.x, sd->bl.y, CLR_RESPAWN);
+ sprintf(atcmd_output, msg_txt(46), pl_sd->status.name); // %s recalled!
+ clif_displaymessage(fd, atcmd_output);
- return 0;
+ return 0;
}
/*==========================================
@@ -2760,19 +2908,19 @@ ACMD_FUNC(recall)
*------------------------------------------*/
ACMD_FUNC(char_block)
{
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
- if (!message || !*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) {
- clif_displaymessage(fd, msg_txt(1021)); // Please enter a player name (usage: @charblock/@block <char name>).
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) {
+ clif_displaymessage(fd, msg_txt(1021)); // Please enter a player name (usage: @charblock/@block <char name>).
+ return -1;
+ }
- 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_txt(88)); // Character name sent to char-server to ask it.
+ 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_txt(88)); // Character name sent to char-server to ask it.
- return 0;
+ return 0;
}
/*==========================================
@@ -2792,84 +2940,84 @@ ACMD_FUNC(char_block)
*------------------------------------------*/
ACMD_FUNC(char_ban)
{
- char *modif_p;
- int year, month, day, hour, minute, second, value;
- time_t timestamp;
- struct tm *tmtime;
- nullpo_retr(-1, sd);
-
- memset(atcmd_output, '\0', sizeof(atcmd_output));
- memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
-
- if (!message || !*message || sscanf(message, "%s %23[^\n]", atcmd_output, atcmd_player_name) < 2) {
- clif_displaymessage(fd, msg_txt(1022)); // Please enter ban time and a player name (usage: @charban/@ban/@banish/@charbanish <time> <char name>).
- return -1;
- }
-
- atcmd_output[sizeof(atcmd_output)-1] = '\0';
-
- modif_p = atcmd_output;
- year = month = day = hour = minute = second = 0;
- while (modif_p[0] != '\0') {
- value = atoi(modif_p);
- if (value == 0)
- modif_p++;
- else {
- if (modif_p[0] == '-' || modif_p[0] == '+')
- modif_p++;
- while (modif_p[0] >= '0' && modif_p[0] <= '9')
- modif_p++;
- if (modif_p[0] == 's') {
- second = value;
- modif_p++;
- } else if (modif_p[0] == 'n') {
- minute = value;
- modif_p++;
- } else if (modif_p[0] == 'm' && modif_p[1] == 'n') {
- minute = value;
- modif_p = modif_p + 2;
- } else if (modif_p[0] == 'h') {
- hour = value;
- modif_p++;
- } else if (modif_p[0] == 'd' || modif_p[0] == 'j') {
- day = value;
- modif_p++;
- } else if (modif_p[0] == 'm') {
- month = value;
- modif_p++;
- } else if (modif_p[0] == 'y' || modif_p[0] == 'a') {
- year = value;
- modif_p++;
- } else if (modif_p[0] != '\0') {
- modif_p++;
- }
- }
- }
- if (year == 0 && month == 0 && day == 0 && hour == 0 && minute == 0 && second == 0) {
- clif_displaymessage(fd, msg_txt(85)); // Invalid time for ban command.
- return -1;
- }
- /**
- * We now check if you can adjust the ban to negative (and if this is the case)
- **/
- timestamp = time(NULL);
- tmtime = localtime(&timestamp);
- tmtime->tm_year = tmtime->tm_year + year;
- tmtime->tm_mon = tmtime->tm_mon + month;
- tmtime->tm_mday = tmtime->tm_mday + day;
- tmtime->tm_hour = tmtime->tm_hour + hour;
- tmtime->tm_min = tmtime->tm_min + minute;
- tmtime->tm_sec = tmtime->tm_sec + second;
- timestamp = mktime(tmtime);
- if (timestamp <= time(NULL) && !pc_can_use_command(sd, "unban", COMMAND_ATCOMMAND)) {
- clif_displaymessage(fd,msg_txt(1023)); // You are not allowed to reduce the length of a ban.
- return -1;
- }
-
- 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_txt(88)); // Character name sent to char-server to ask it.
-
- return 0;
+ char * modif_p;
+ int year, month, day, hour, minute, second, value;
+ time_t timestamp;
+ struct tm *tmtime;
+ nullpo_retr(-1, sd);
+
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
+
+ if (!message || !*message || sscanf(message, "%s %23[^\n]", atcmd_output, atcmd_player_name) < 2) {
+ clif_displaymessage(fd, msg_txt(1022)); // Please enter ban time and a player name (usage: @charban/@ban/@banish/@charbanish <time> <char name>).
+ return -1;
+ }
+
+ atcmd_output[sizeof(atcmd_output)-1] = '\0';
+
+ modif_p = atcmd_output;
+ year = month = day = hour = minute = second = 0;
+ while (modif_p[0] != '\0') {
+ value = atoi(modif_p);
+ if (value == 0)
+ modif_p++;
+ else {
+ if (modif_p[0] == '-' || modif_p[0] == '+')
+ modif_p++;
+ while (modif_p[0] >= '0' && modif_p[0] <= '9')
+ modif_p++;
+ if (modif_p[0] == 's') {
+ second = value;
+ modif_p++;
+ } else if (modif_p[0] == 'n') {
+ minute = value;
+ modif_p++;
+ } else if (modif_p[0] == 'm' && modif_p[1] == 'n') {
+ minute = value;
+ modif_p = modif_p + 2;
+ } else if (modif_p[0] == 'h') {
+ hour = value;
+ modif_p++;
+ } else if (modif_p[0] == 'd' || modif_p[0] == 'j') {
+ day = value;
+ modif_p++;
+ } else if (modif_p[0] == 'm') {
+ month = value;
+ modif_p++;
+ } else if (modif_p[0] == 'y' || modif_p[0] == 'a') {
+ year = value;
+ modif_p++;
+ } else if (modif_p[0] != '\0') {
+ modif_p++;
+ }
+ }
+ }
+ if (year == 0 && month == 0 && day == 0 && hour == 0 && minute == 0 && second == 0) {
+ clif_displaymessage(fd, msg_txt(85)); // Invalid time for ban command.
+ return -1;
+ }
+ /**
+ * We now check if you can adjust the ban to negative (and if this is the case)
+ **/
+ timestamp = time(NULL);
+ tmtime = localtime(&timestamp);
+ tmtime->tm_year = tmtime->tm_year + year;
+ tmtime->tm_mon = tmtime->tm_mon + month;
+ tmtime->tm_mday = tmtime->tm_mday + day;
+ tmtime->tm_hour = tmtime->tm_hour + hour;
+ tmtime->tm_min = tmtime->tm_min + minute;
+ tmtime->tm_sec = tmtime->tm_sec + second;
+ timestamp = mktime(tmtime);
+ if( timestamp <= time(NULL) && !pc_can_use_command(sd, "unban", COMMAND_ATCOMMAND) ) {
+ clif_displaymessage(fd,msg_txt(1023)); // You are not allowed to reduce the length of a ban.
+ return -1;
+ }
+
+ 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_txt(88)); // Character name sent to char-server to ask it.
+
+ return 0;
}
/*==========================================
@@ -2877,20 +3025,20 @@ ACMD_FUNC(char_ban)
*------------------------------------------*/
ACMD_FUNC(char_unblock)
{
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
- if (!message || !*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) {
- clif_displaymessage(fd, msg_txt(1024)); // Please enter a player name (usage: @charunblock <char name>).
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) {
+ clif_displaymessage(fd, msg_txt(1024)); // Please enter a player name (usage: @charunblock <char name>).
+ return -1;
+ }
- // send answer to login server via char-server
- 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_txt(88)); // Character name sent to char-server to ask it.
+ // send answer to login server via char-server
+ 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_txt(88)); // Character name sent to char-server to ask it.
- return 0;
+ return 0;
}
/*==========================================
@@ -2898,20 +3046,20 @@ ACMD_FUNC(char_unblock)
*------------------------------------------*/
ACMD_FUNC(char_unban)
{
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
- if (!message || !*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) {
- clif_displaymessage(fd, msg_txt(1025)); // Please enter a player name (usage: @charunban <char name>).
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) {
+ clif_displaymessage(fd, msg_txt(1025)); // Please enter a player name (usage: @charunban <char name>).
+ return -1;
+ }
- // send answer to login server via char-server
- 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_txt(88)); // Character name sent to char-server to ask it.
+ // send answer to login server via char-server
+ 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_txt(88)); // Character name sent to char-server to ask it.
- return 0;
+ return 0;
}
/*==========================================
@@ -2919,16 +3067,16 @@ ACMD_FUNC(char_unban)
*------------------------------------------*/
ACMD_FUNC(night)
{
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- if (night_flag != 1) {
- map_night_timer(night_timer_tid, 0, 0, 1);
- } else {
- clif_displaymessage(fd, msg_txt(89)); // Night mode is already enabled.
- return -1;
- }
+ if (night_flag != 1) {
+ map_night_timer(night_timer_tid, 0, 0, 1);
+ } else {
+ clif_displaymessage(fd, msg_txt(89)); // Night mode is already enabled.
+ return -1;
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -2936,16 +3084,16 @@ ACMD_FUNC(night)
*------------------------------------------*/
ACMD_FUNC(day)
{
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- if (night_flag != 0) {
- map_day_timer(day_timer_tid, 0, 0, 1);
- } else {
- clif_displaymessage(fd, msg_txt(90)); // Day mode is already enabled.
- return -1;
- }
+ if (night_flag != 0) {
+ map_day_timer(day_timer_tid, 0, 0, 1);
+ } else {
+ clif_displaymessage(fd, msg_txt(90)); // Day mode is already enabled.
+ return -1;
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -2953,24 +3101,26 @@ ACMD_FUNC(day)
*------------------------------------------*/
ACMD_FUNC(doom)
{
- struct map_session_data *pl_sd;
- struct s_mapiterator *iter;
+ struct map_session_data* pl_sd;
+ struct s_mapiterator* iter;
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- iter = mapit_getallusers();
- for (pl_sd = (TBL_PC *)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC *)mapit_next(iter)) {
- if (pl_sd->fd != fd && pc_get_group_level(sd) >= pc_get_group_level(pl_sd)) {
- status_kill(&pl_sd->bl);
- clif_specialeffect(&pl_sd->bl,450,AREA);
- clif_displaymessage(pl_sd->fd, msg_txt(61)); // The holy messenger has given judgement.
- }
- }
- mapit_free(iter);
+ iter = mapit_getallusers();
+ for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
+ {
+ if (pl_sd->fd != fd && pc_get_group_level(sd) >= pc_get_group_level(pl_sd))
+ {
+ status_kill(&pl_sd->bl);
+ clif_specialeffect(&pl_sd->bl,450,AREA);
+ clif_displaymessage(pl_sd->fd, msg_txt(61)); // The holy messenger has given judgement.
+ }
+ }
+ mapit_free(iter);
- clif_displaymessage(fd, msg_txt(62)); // Judgement was made.
+ clif_displaymessage(fd, msg_txt(62)); // Judgement was made.
- return 0;
+ return 0;
}
/*==========================================
@@ -2978,36 +3128,37 @@ ACMD_FUNC(doom)
*------------------------------------------*/
ACMD_FUNC(doommap)
{
- struct map_session_data *pl_sd;
- struct s_mapiterator *iter;
+ struct map_session_data* pl_sd;
+ struct s_mapiterator* iter;
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- iter = mapit_getallusers();
- for (pl_sd = (TBL_PC *)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC *)mapit_next(iter)) {
- if (pl_sd->fd != fd && sd->bl.m == pl_sd->bl.m && pc_get_group_level(sd) >= pc_get_group_level(pl_sd)) {
- status_kill(&pl_sd->bl);
- clif_specialeffect(&pl_sd->bl,450,AREA);
- clif_displaymessage(pl_sd->fd, msg_txt(61)); // The holy messenger has given judgement.
- }
- }
- mapit_free(iter);
+ iter = mapit_getallusers();
+ for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
+ {
+ if (pl_sd->fd != fd && sd->bl.m == pl_sd->bl.m && pc_get_group_level(sd) >= pc_get_group_level(pl_sd))
+ {
+ status_kill(&pl_sd->bl);
+ clif_specialeffect(&pl_sd->bl,450,AREA);
+ clif_displaymessage(pl_sd->fd, msg_txt(61)); // The holy messenger has given judgement.
+ }
+ }
+ mapit_free(iter);
- clif_displaymessage(fd, msg_txt(62)); // Judgement was made.
+ clif_displaymessage(fd, msg_txt(62)); // Judgement was made.
- return 0;
+ return 0;
}
/*==========================================
*
*------------------------------------------*/
-static void atcommand_raise_sub(struct map_session_data *sd)
-{
+static void atcommand_raise_sub(struct map_session_data* sd) {
- status_revive(&sd->bl, 100, 100);
+ status_revive(&sd->bl, 100, 100);
- clif_skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION,4,1);
- clif_displaymessage(sd->fd, msg_txt(63)); // Mercy has been shown.
+ clif_skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION,4,1);
+ clif_displaymessage(sd->fd, msg_txt(63)); // Mercy has been shown.
}
/*==========================================
@@ -3015,20 +3166,20 @@ static void atcommand_raise_sub(struct map_session_data *sd)
*------------------------------------------*/
ACMD_FUNC(raise)
{
- struct map_session_data *pl_sd;
- struct s_mapiterator *iter;
+ struct map_session_data* pl_sd;
+ struct s_mapiterator* iter;
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- iter = mapit_getallusers();
- for (pl_sd = (TBL_PC *)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC *)mapit_next(iter))
- if (pc_isdead(pl_sd))
- atcommand_raise_sub(pl_sd);
- mapit_free(iter);
+ iter = mapit_getallusers();
+ for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
+ if( pc_isdead(pl_sd) )
+ atcommand_raise_sub(pl_sd);
+ mapit_free(iter);
- clif_displaymessage(fd, msg_txt(64)); // Mercy has been granted.
+ clif_displaymessage(fd, msg_txt(64)); // Mercy has been granted.
- return 0;
+ return 0;
}
/*==========================================
@@ -3036,20 +3187,20 @@ ACMD_FUNC(raise)
*------------------------------------------*/
ACMD_FUNC(raisemap)
{
- struct map_session_data *pl_sd;
- struct s_mapiterator *iter;
+ struct map_session_data* pl_sd;
+ struct s_mapiterator* iter;
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- iter = mapit_getallusers();
- for (pl_sd = (TBL_PC *)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC *)mapit_next(iter))
- if (sd->bl.m == pl_sd->bl.m && pc_isdead(pl_sd))
- atcommand_raise_sub(pl_sd);
- mapit_free(iter);
+ iter = mapit_getallusers();
+ for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
+ if (sd->bl.m == pl_sd->bl.m && pc_isdead(pl_sd) )
+ atcommand_raise_sub(pl_sd);
+ mapit_free(iter);
- clif_displaymessage(fd, msg_txt(64)); // Mercy has been granted.
+ clif_displaymessage(fd, msg_txt(64)); // Mercy has been granted.
- return 0;
+ return 0;
}
/*==========================================
@@ -3057,29 +3208,31 @@ ACMD_FUNC(raisemap)
*------------------------------------------*/
ACMD_FUNC(kick)
{
- struct map_session_data *pl_sd;
- nullpo_retr(-1, sd);
+ struct map_session_data *pl_sd;
+ nullpo_retr(-1, sd);
- memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
- if (!message || !*message) {
- clif_displaymessage(fd, msg_txt(1026)); // Please enter a player name (usage: @kick <char name/ID>).
- return -1;
- }
+ if (!message || !*message) {
+ clif_displaymessage(fd, msg_txt(1026)); // Please enter a player name (usage: @kick <char name/ID>).
+ return -1;
+ }
- if ((pl_sd=map_nick2sd((char *)message)) == NULL && (pl_sd=map_charid2sd(atoi(message))) == NULL) {
- clif_displaymessage(fd, msg_txt(3)); // Character not found.
- return -1;
- }
+ if((pl_sd=map_nick2sd((char *)message)) == NULL && (pl_sd=map_charid2sd(atoi(message))) == NULL)
+ {
+ clif_displaymessage(fd, msg_txt(3)); // Character not found.
+ return -1;
+ }
- if (pc_get_group_level(sd) < pc_get_group_level(pl_sd)) {
- clif_displaymessage(fd, msg_txt(81)); // Your GM level don't authorise you to do this action on this player.
- return -1;
- }
+ if ( pc_get_group_level(sd) < pc_get_group_level(pl_sd) )
+ {
+ clif_displaymessage(fd, msg_txt(81)); // Your GM level don't authorise you to do this action on this player.
+ return -1;
+ }
- clif_GM_kick(sd, pl_sd);
+ clif_GM_kick(sd, pl_sd);
- return 0;
+ return 0;
}
/*==========================================
@@ -3087,22 +3240,23 @@ ACMD_FUNC(kick)
*------------------------------------------*/
ACMD_FUNC(kickall)
{
- struct map_session_data *pl_sd;
- struct s_mapiterator *iter;
- nullpo_retr(-1, sd);
+ struct map_session_data* pl_sd;
+ struct s_mapiterator* iter;
+ nullpo_retr(-1, sd);
- iter = mapit_getallusers();
- for (pl_sd = (TBL_PC *)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC *)mapit_next(iter)) {
- if (pc_get_group_level(sd) >= pc_get_group_level(pl_sd)) { // you can kick only lower or same gm level
- if (sd->status.account_id != pl_sd->status.account_id)
- clif_GM_kick(NULL, pl_sd);
- }
- }
- mapit_free(iter);
+ iter = mapit_getallusers();
+ for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
+ {
+ if (pc_get_group_level(sd) >= pc_get_group_level(pl_sd)) { // you can kick only lower or same gm level
+ if (sd->status.account_id != pl_sd->status.account_id)
+ clif_GM_kick(NULL, pl_sd);
+ }
+ }
+ mapit_free(iter);
- clif_displaymessage(fd, msg_txt(195)); // All players have been kicked!
+ clif_displaymessage(fd, msg_txt(195)); // All players have been kicked!
- return 0;
+ return 0;
}
/*==========================================
@@ -3110,13 +3264,13 @@ ACMD_FUNC(kickall)
*------------------------------------------*/
ACMD_FUNC(allskill)
{
- nullpo_retr(-1, sd);
- pc_allskillup(sd); // all skills
- sd->status.skill_point = 0; // 0 skill points
- clif_updatestatus(sd, SP_SKILLPOINT); // update
- clif_displaymessage(fd, msg_txt(76)); // All skills have been added to your skill tree.
+ nullpo_retr(-1, sd);
+ pc_allskillup(sd); // all skills
+ sd->status.skill_point = 0; // 0 skill points
+ clif_updatestatus(sd, SP_SKILLPOINT); // update
+ clif_displaymessage(fd, msg_txt(76)); // All skills have been added to your skill tree.
- return 0;
+ return 0;
}
/*==========================================
@@ -3124,43 +3278,43 @@ ACMD_FUNC(allskill)
*------------------------------------------*/
ACMD_FUNC(questskill)
{
- int skill_id;
- nullpo_retr(-1, sd);
+ int skill_id;
+ nullpo_retr(-1, sd);
- if (!message || !*message || (skill_id = atoi(message)) < 0) {
- // also send a list of skills applicable to this command
- const char *text;
+ if (!message || !*message || (skill_id = atoi(message)) < 0)
+ {// also send a list of skills applicable to this command
+ const char* text;
- // attempt to find the text corresponding to this command
- text = atcommand_help_string(command);
+ // attempt to find the text corresponding to this command
+ text = atcommand_help_string( command );
- // send the error message as always
- clif_displaymessage(fd, msg_txt(1027)); // Please enter a quest skill number.
+ // send the error message as always
+ clif_displaymessage(fd, msg_txt(1027)); // Please enter a quest skill number.
- if (text) {
- // send the skill ID list associated with this command
- clif_displaymessage(fd, text);
- }
+ if( text )
+ {// send the skill ID list associated with this command
+ clif_displaymessage( fd, text );
+ }
- return -1;
- }
- if (skill_id < 0 && skill_id >= MAX_SKILL_DB) {
- clif_displaymessage(fd, msg_txt(198)); // This skill number doesn't exist.
- return -1;
- }
- if (!(skill_get_inf2(skill_id) & INF2_QUEST_SKILL)) {
- clif_displaymessage(fd, msg_txt(197)); // This skill number doesn't exist or isn't a quest skill.
- return -1;
- }
- if (pc_checkskill(sd, skill_id) > 0) {
- clif_displaymessage(fd, msg_txt(196)); // You already have this quest skill.
- return -1;
- }
+ return -1;
+ }
+ if (skill_id < 0 && skill_id >= MAX_SKILL_DB) {
+ clif_displaymessage(fd, msg_txt(198)); // This skill number doesn't exist.
+ return -1;
+ }
+ if (!(skill_get_inf2(skill_id) & INF2_QUEST_SKILL)) {
+ clif_displaymessage(fd, msg_txt(197)); // This skill number doesn't exist or isn't a quest skill.
+ return -1;
+ }
+ if (pc_checkskill(sd, skill_id) > 0) {
+ clif_displaymessage(fd, msg_txt(196)); // You already have this quest skill.
+ return -1;
+ }
- pc_skill(sd, skill_id, 1, 0);
- clif_displaymessage(fd, msg_txt(70)); // You have learned the skill.
+ pc_skill(sd, skill_id, 1, 0);
+ clif_displaymessage(fd, msg_txt(70)); // You have learned the skill.
- return 0;
+ return 0;
}
/*==========================================
@@ -3168,45 +3322,45 @@ ACMD_FUNC(questskill)
*------------------------------------------*/
ACMD_FUNC(lostskill)
{
- int skill_id;
- nullpo_retr(-1, sd);
+ int skill_id;
+ nullpo_retr(-1, sd);
- if (!message || !*message || (skill_id = atoi(message)) < 0) {
- // also send a list of skills applicable to this command
- const char *text;
+ if (!message || !*message || (skill_id = atoi(message)) < 0)
+ {// also send a list of skills applicable to this command
+ const char* text;
- // attempt to find the text corresponding to this command
- text = atcommand_help_string(command);
+ // attempt to find the text corresponding to this command
+ text = atcommand_help_string( command );
- // send the error message as always
- clif_displaymessage(fd, msg_txt(1027)); // Please enter a quest skill number.
+ // send the error message as always
+ clif_displaymessage(fd, msg_txt(1027)); // Please enter a quest skill number.
- if (text) {
- // send the skill ID list associated with this command
- clif_displaymessage(fd, text);
- }
+ if( text )
+ {// send the skill ID list associated with this command
+ clif_displaymessage( fd, text );
+ }
- return -1;
- }
- if (skill_id < 0 && skill_id >= MAX_SKILL) {
- clif_displaymessage(fd, msg_txt(198)); // This skill number doesn't exist.
- return -1;
- }
- if (!(skill_get_inf2(skill_id) & INF2_QUEST_SKILL)) {
- clif_displaymessage(fd, msg_txt(197)); // This skill number doesn't exist or isn't a quest skill.
- return -1;
- }
- if (pc_checkskill(sd, skill_id) == 0) {
- clif_displaymessage(fd, msg_txt(201)); // You don't have this quest skill.
- return -1;
- }
+ return -1;
+ }
+ if (skill_id < 0 && skill_id >= MAX_SKILL) {
+ clif_displaymessage(fd, msg_txt(198)); // This skill number doesn't exist.
+ return -1;
+ }
+ if (!(skill_get_inf2(skill_id) & INF2_QUEST_SKILL)) {
+ clif_displaymessage(fd, msg_txt(197)); // This skill number doesn't exist or isn't a quest skill.
+ return -1;
+ }
+ if (pc_checkskill(sd, skill_id) == 0) {
+ clif_displaymessage(fd, msg_txt(201)); // You don't have this quest skill.
+ return -1;
+ }
- sd->status.skill[skill_id].lv = 0;
- sd->status.skill[skill_id].flag = 0;
- clif_deleteskill(sd,skill_id);
- clif_displaymessage(fd, msg_txt(71)); // You have forgotten the skill.
+ sd->status.skill[skill_id].lv = 0;
+ sd->status.skill[skill_id].flag = 0;
+ clif_deleteskill(sd,skill_id);
+ clif_displaymessage(fd, msg_txt(71)); // You have forgotten the skill.
- return 0;
+ return 0;
}
/*==========================================
@@ -3214,26 +3368,27 @@ ACMD_FUNC(lostskill)
*------------------------------------------*/
ACMD_FUNC(spiritball)
{
- int max_spiritballs;
- int number;
- nullpo_retr(-1, sd);
+ int max_spiritballs;
+ int number;
+ nullpo_retr(-1, sd);
- max_spiritballs = min(ARRAYLENGTH(sd->spirit_timer), 0x7FFF);
+ max_spiritballs = min(ARRAYLENGTH(sd->spirit_timer), 0x7FFF);
- if (!message || !*message || (number = atoi(message)) < 0 || number > max_spiritballs) {
- char msg[CHAT_SIZE_MAX];
- safesnprintf(msg, sizeof(msg), msg_txt(1028), max_spiritballs); // Please enter a party name (usage: @party <party_name>).
- clif_displaymessage(fd, msg);
- return -1;
- }
+ if( !message || !*message || (number = atoi(message)) < 0 || number > max_spiritballs )
+ {
+ char msg[CHAT_SIZE_MAX];
+ safesnprintf(msg, sizeof(msg), msg_txt(1028), max_spiritballs); // Please enter a party name (usage: @party <party_name>).
+ clif_displaymessage(fd, msg);
+ return -1;
+ }
- if (sd->spiritball > 0)
- pc_delspiritball(sd, sd->spiritball, 1);
- sd->spiritball = number;
- clif_spiritball(&sd->bl);
- // no message, player can look the difference
+ if( sd->spiritball > 0 )
+ pc_delspiritball(sd, sd->spiritball, 1);
+ sd->spiritball = number;
+ clif_spiritball(&sd->bl);
+ // no message, player can look the difference
- return 0;
+ return 0;
}
/*==========================================
@@ -3241,19 +3396,19 @@ ACMD_FUNC(spiritball)
*------------------------------------------*/
ACMD_FUNC(party)
{
- char party[NAME_LENGTH];
- nullpo_retr(-1, sd);
+ char party[NAME_LENGTH];
+ nullpo_retr(-1, sd);
- memset(party, '\0', sizeof(party));
+ memset(party, '\0', sizeof(party));
- if (!message || !*message || sscanf(message, "%23[^\n]", party) < 1) {
- clif_displaymessage(fd, msg_txt(1029)); // Please enter a party name (usage: @party <party_name>).
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%23[^\n]", party) < 1) {
+ clif_displaymessage(fd, msg_txt(1029)); // Please enter a party name (usage: @party <party_name>).
+ return -1;
+ }
- party_create(sd, party, 0, 0);
+ party_create(sd, party, 0, 0);
- return 0;
+ return 0;
}
/*==========================================
@@ -3261,23 +3416,23 @@ ACMD_FUNC(party)
*------------------------------------------*/
ACMD_FUNC(guild)
{
- char guild[NAME_LENGTH];
- int prev;
- nullpo_retr(-1, sd);
+ char guild[NAME_LENGTH];
+ int prev;
+ nullpo_retr(-1, sd);
- memset(guild, '\0', sizeof(guild));
+ memset(guild, '\0', sizeof(guild));
- if (!message || !*message || sscanf(message, "%23[^\n]", guild) < 1) {
- clif_displaymessage(fd, msg_txt(1030)); // Please enter a guild name (usage: @guild <guild_name>).
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%23[^\n]", guild) < 1) {
+ clif_displaymessage(fd, msg_txt(1030)); // Please enter a guild name (usage: @guild <guild_name>).
+ return -1;
+ }
- prev = battle_config.guild_emperium_check;
- battle_config.guild_emperium_check = 0;
- guild_create(sd, guild);
- battle_config.guild_emperium_check = prev;
+ prev = battle_config.guild_emperium_check;
+ battle_config.guild_emperium_check = 0;
+ guild_create(sd, guild);
+ battle_config.guild_emperium_check = prev;
- return 0;
+ return 0;
}
/*==========================================
@@ -3285,17 +3440,17 @@ ACMD_FUNC(guild)
*------------------------------------------*/
ACMD_FUNC(agitstart)
{
- nullpo_retr(-1, sd);
- if (agit_flag == 1) {
- clif_displaymessage(fd, msg_txt(73)); // War of Emperium is currently in progress.
- return -1;
- }
+ nullpo_retr(-1, sd);
+ if (agit_flag == 1) {
+ clif_displaymessage(fd, msg_txt(73)); // War of Emperium is currently in progress.
+ return -1;
+ }
- agit_flag = 1;
- guild_agit_start();
- clif_displaymessage(fd, msg_txt(72)); // War of Emperium has been initiated.
+ agit_flag = 1;
+ guild_agit_start();
+ clif_displaymessage(fd, msg_txt(72)); // War of Emperium has been initiated.
- return 0;
+ return 0;
}
/*==========================================
@@ -3303,17 +3458,17 @@ ACMD_FUNC(agitstart)
*------------------------------------------*/
ACMD_FUNC(agitstart2)
{
- nullpo_retr(-1, sd);
- if (agit2_flag == 1) {
- clif_displaymessage(fd, msg_txt(404)); // "War of Emperium SE is currently in progress."
- return -1;
- }
+ nullpo_retr(-1, sd);
+ if (agit2_flag == 1) {
+ clif_displaymessage(fd, msg_txt(404)); // "War of Emperium SE is currently in progress."
+ return -1;
+ }
- agit2_flag = 1;
- guild_agit2_start();
- clif_displaymessage(fd, msg_txt(403)); // "War of Emperium SE has been initiated."
+ agit2_flag = 1;
+ guild_agit2_start();
+ clif_displaymessage(fd, msg_txt(403)); // "War of Emperium SE has been initiated."
- return 0;
+ return 0;
}
/*==========================================
@@ -3321,17 +3476,17 @@ ACMD_FUNC(agitstart2)
*------------------------------------------*/
ACMD_FUNC(agitend)
{
- nullpo_retr(-1, sd);
- if (agit_flag == 0) {
- clif_displaymessage(fd, msg_txt(75)); // War of Emperium is currently not in progress.
- return -1;
- }
+ nullpo_retr(-1, sd);
+ if (agit_flag == 0) {
+ clif_displaymessage(fd, msg_txt(75)); // War of Emperium is currently not in progress.
+ return -1;
+ }
- agit_flag = 0;
- guild_agit_end();
- clif_displaymessage(fd, msg_txt(74)); // War of Emperium has been ended.
+ agit_flag = 0;
+ guild_agit_end();
+ clif_displaymessage(fd, msg_txt(74)); // War of Emperium has been ended.
- return 0;
+ return 0;
}
/*==========================================
@@ -3339,17 +3494,17 @@ ACMD_FUNC(agitend)
*------------------------------------------*/
ACMD_FUNC(agitend2)
{
- nullpo_retr(-1, sd);
- if (agit2_flag == 0) {
- clif_displaymessage(fd, msg_txt(406)); // "War of Emperium SE is currently not in progress."
- return -1;
- }
+ nullpo_retr(-1, sd);
+ if (agit2_flag == 0) {
+ clif_displaymessage(fd, msg_txt(406)); // "War of Emperium SE is currently not in progress."
+ return -1;
+ }
- agit2_flag = 0;
- guild_agit2_end();
- clif_displaymessage(fd, msg_txt(405)); // "War of Emperium SE has been ended."
+ agit2_flag = 0;
+ guild_agit2_end();
+ clif_displaymessage(fd, msg_txt(405)); // "War of Emperium SE has been ended."
- return 0;
+ return 0;
}
/*==========================================
@@ -3357,10 +3512,10 @@ ACMD_FUNC(agitend2)
*------------------------------------------*/
ACMD_FUNC(mapexit)
{
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- do_shutdown();
- return 0;
+ do_shutdown();
+ return 0;
}
/*==========================================
@@ -3368,35 +3523,35 @@ ACMD_FUNC(mapexit)
*------------------------------------------*/
ACMD_FUNC(idsearch)
{
- char item_name[100];
- unsigned int i, match;
- struct item_data *item_array[MAX_SEARCH];
- nullpo_retr(-1, sd);
+ char item_name[100];
+ unsigned int i, match;
+ struct item_data *item_array[MAX_SEARCH];
+ nullpo_retr(-1, sd);
- memset(item_name, '\0', sizeof(item_name));
- memset(atcmd_output, '\0', sizeof(atcmd_output));
+ memset(item_name, '\0', sizeof(item_name));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
- if (!message || !*message || sscanf(message, "%99s", item_name) < 0) {
- clif_displaymessage(fd, msg_txt(1031)); // Please enter part of an item name (usage: @idsearch <part_of_item_name>).
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%99s", item_name) < 0) {
+ clif_displaymessage(fd, msg_txt(1031)); // Please enter part of an item name (usage: @idsearch <part_of_item_name>).
+ return -1;
+ }
- sprintf(atcmd_output, msg_txt(77), item_name); // The reference result of '%s' (name: id):
- clif_displaymessage(fd, atcmd_output);
- match = itemdb_searchname_array(item_array, MAX_SEARCH, item_name);
- if (match > MAX_SEARCH) {
- sprintf(atcmd_output, msg_txt(269), MAX_SEARCH, match);
- clif_displaymessage(fd, atcmd_output);
- match = MAX_SEARCH;
- }
- for (i = 0; i < match; i++) {
- sprintf(atcmd_output, msg_txt(78), item_array[i]->jname, item_array[i]->nameid); // %s: %d
- clif_displaymessage(fd, atcmd_output);
- }
- sprintf(atcmd_output, msg_txt(79), match); // It is %d affair above.
- clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output, msg_txt(77), item_name); // The reference result of '%s' (name: id):
+ clif_displaymessage(fd, atcmd_output);
+ match = itemdb_searchname_array(item_array, MAX_SEARCH, item_name);
+ if (match > MAX_SEARCH) {
+ sprintf(atcmd_output, msg_txt(269), MAX_SEARCH, match);
+ clif_displaymessage(fd, atcmd_output);
+ match = MAX_SEARCH;
+ }
+ for(i = 0; i < match; i++) {
+ sprintf(atcmd_output, msg_txt(78), item_array[i]->jname, item_array[i]->nameid); // %s: %d
+ clif_displaymessage(fd, atcmd_output);
+ }
+ sprintf(atcmd_output, msg_txt(79), match); // It is %d affair above.
+ clif_displaymessage(fd, atcmd_output);
- return 0;
+ return 0;
}
/*==========================================
@@ -3404,44 +3559,44 @@ ACMD_FUNC(idsearch)
*------------------------------------------*/
ACMD_FUNC(recallall)
{
- struct map_session_data *pl_sd;
- struct s_mapiterator *iter;
- int count;
- nullpo_retr(-1, sd);
-
- memset(atcmd_output, '\0', sizeof(atcmd_output));
-
- if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
- clif_displaymessage(fd, msg_txt(1032)); // You are not authorized to warp somenone to your current map.
- return -1;
- }
-
- count = 0;
- iter = mapit_getallusers();
- for (pl_sd = (TBL_PC *)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC *)mapit_next(iter)) {
- if (sd->status.account_id != pl_sd->status.account_id && pc_get_group_level(sd) >= pc_get_group_level(pl_sd)) {
- if (pl_sd->bl.m == sd->bl.m && pl_sd->bl.x == sd->bl.x && pl_sd->bl.y == sd->bl.y)
- continue; // Don't waste time warping the character to the same place.
- if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE))
- count++;
- else {
- if (pc_isdead(pl_sd)) { //Wake them up
- pc_setstand(pl_sd);
- pc_setrestartvalue(pl_sd,1);
- }
- pc_setpos(pl_sd, sd->mapindex, sd->bl.x, sd->bl.y, CLR_RESPAWN);
- }
- }
- }
- mapit_free(iter);
-
- clif_displaymessage(fd, msg_txt(92)); // All characters recalled!
- if (count) {
- sprintf(atcmd_output, msg_txt(1033), count); // Because you are not authorized to warp from some maps, %d player(s) have not been recalled.
- clif_displaymessage(fd, atcmd_output);
- }
-
- return 0;
+ struct map_session_data* pl_sd;
+ struct s_mapiterator* iter;
+ int count;
+ nullpo_retr(-1, sd);
+
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
+
+ if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
+ clif_displaymessage(fd, msg_txt(1032)); // You are not authorized to warp somenone to your current map.
+ return -1;
+ }
+
+ count = 0;
+ iter = mapit_getallusers();
+ for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
+ {
+ if (sd->status.account_id != pl_sd->status.account_id && pc_get_group_level(sd) >= pc_get_group_level(pl_sd))
+ {
+ if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE))
+ count++;
+ else {
+ if (pc_isdead(pl_sd)) { //Wake them up
+ pc_setstand(pl_sd);
+ pc_setrestartvalue(pl_sd,1);
+ }
+ pc_setpos(pl_sd, sd->mapindex, sd->bl.x, sd->bl.y, CLR_RESPAWN);
+ }
+ }
+ }
+ mapit_free(iter);
+
+ clif_displaymessage(fd, msg_txt(92)); // All characters recalled!
+ if (count) {
+ sprintf(atcmd_output, msg_txt(1033), count); // Because you are not authorized to warp from some maps, %d player(s) have not been recalled.
+ clif_displaymessage(fd, atcmd_output);
+ }
+
+ return 0;
}
/*==========================================
@@ -3449,55 +3604,58 @@ ACMD_FUNC(recallall)
*------------------------------------------*/
ACMD_FUNC(guildrecall)
{
- struct map_session_data *pl_sd;
- struct s_mapiterator *iter;
- int count;
- char guild_name[NAME_LENGTH];
- struct guild *g;
- nullpo_retr(-1, sd);
-
- memset(guild_name, '\0', sizeof(guild_name));
- memset(atcmd_output, '\0', sizeof(atcmd_output));
-
- if (!message || !*message || sscanf(message, "%23[^\n]", guild_name) < 1) {
- clif_displaymessage(fd, msg_txt(1034)); // Please enter a guild name/ID (usage: @guildrecall <guild_name/ID>).
- return -1;
- }
-
- if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
- clif_displaymessage(fd, msg_txt(1032)); // You are not authorized to warp somenone to your current map.
- return -1;
- }
-
- if ((g = guild_searchname(guild_name)) == NULL && // name first to avoid error when name begin with a number
- (g = guild_search(atoi(message))) == NULL) {
- clif_displaymessage(fd, msg_txt(94)); // Incorrect name/ID, or no one from the guild is online.
- return -1;
- }
-
- count = 0;
-
- iter = mapit_getallusers();
- for (pl_sd = (TBL_PC *)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC *)mapit_next(iter)) {
- if (sd->status.account_id != pl_sd->status.account_id && pl_sd->status.guild_id == g->guild_id) {
- if (pc_get_group_level(pl_sd) > pc_get_group_level(sd) || (pl_sd->bl.m == sd->bl.m && pl_sd->bl.x == sd->bl.x && pl_sd->bl.y == sd->bl.y))
- continue; //Skip GMs greater than you.
- if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE))
- count++;
- else
- pc_setpos(pl_sd, sd->mapindex, sd->bl.x, sd->bl.y, CLR_RESPAWN);
- }
- }
- mapit_free(iter);
-
- sprintf(atcmd_output, msg_txt(93), g->name); // All online characters of the %s guild have been recalled to your position.
- clif_displaymessage(fd, atcmd_output);
- if (count) {
- sprintf(atcmd_output, msg_txt(1033), count); // Because you are not authorized to warp from some maps, %d player(s) have not been recalled.
- clif_displaymessage(fd, atcmd_output);
- }
-
- return 0;
+ struct map_session_data* pl_sd;
+ struct s_mapiterator* iter;
+ int count;
+ char guild_name[NAME_LENGTH];
+ struct guild *g;
+ nullpo_retr(-1, sd);
+
+ memset(guild_name, '\0', sizeof(guild_name));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
+
+ if (!message || !*message || sscanf(message, "%23[^\n]", guild_name) < 1) {
+ clif_displaymessage(fd, msg_txt(1034)); // Please enter a guild name/ID (usage: @guildrecall <guild_name/ID>).
+ return -1;
+ }
+
+ if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
+ clif_displaymessage(fd, msg_txt(1032)); // You are not authorized to warp somenone to your current map.
+ return -1;
+ }
+
+ if ((g = guild_searchname(guild_name)) == NULL && // name first to avoid error when name begin with a number
+ (g = guild_search(atoi(message))) == NULL)
+ {
+ clif_displaymessage(fd, msg_txt(94)); // Incorrect name/ID, or no one from the guild is online.
+ return -1;
+ }
+
+ count = 0;
+
+ iter = mapit_getallusers();
+ for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
+ {
+ if (sd->status.account_id != pl_sd->status.account_id && pl_sd->status.guild_id == g->guild_id)
+ {
+ if (pc_get_group_level(pl_sd) > pc_get_group_level(sd))
+ continue; //Skip GMs greater than you.
+ if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE))
+ count++;
+ else
+ pc_setpos(pl_sd, sd->mapindex, sd->bl.x, sd->bl.y, CLR_RESPAWN);
+ }
+ }
+ mapit_free(iter);
+
+ sprintf(atcmd_output, msg_txt(93), g->name); // All online characters of the %s guild have been recalled to your position.
+ clif_displaymessage(fd, atcmd_output);
+ if (count) {
+ sprintf(atcmd_output, msg_txt(1033), count); // Because you are not authorized to warp from some maps, %d player(s) have not been recalled.
+ clif_displaymessage(fd, atcmd_output);
+ }
+
+ return 0;
}
/*==========================================
@@ -3505,55 +3663,58 @@ ACMD_FUNC(guildrecall)
*------------------------------------------*/
ACMD_FUNC(partyrecall)
{
- struct map_session_data *pl_sd;
- struct s_mapiterator *iter;
- char party_name[NAME_LENGTH];
- struct party_data *p;
- int count;
- nullpo_retr(-1, sd);
-
- memset(party_name, '\0', sizeof(party_name));
- memset(atcmd_output, '\0', sizeof(atcmd_output));
-
- if (!message || !*message || sscanf(message, "%23[^\n]", party_name) < 1) {
- clif_displaymessage(fd, msg_txt(1035)); // Please enter a party name/ID (usage: @partyrecall <party_name/ID>).
- return -1;
- }
-
- if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
- clif_displaymessage(fd, msg_txt(1032)); // You are not authorized to warp somenone to your current map.
- return -1;
- }
-
- if ((p = party_searchname(party_name)) == NULL && // name first to avoid error when name begin with a number
- (p = party_search(atoi(message))) == NULL) {
- clif_displaymessage(fd, msg_txt(96)); // Incorrect name or ID, or no one from the party is online.
- return -1;
- }
-
- count = 0;
-
- iter = mapit_getallusers();
- for (pl_sd = (TBL_PC *)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC *)mapit_next(iter)) {
- if (sd->status.account_id != pl_sd->status.account_id && pl_sd->status.party_id == p->party.party_id) {
- if (pc_get_group_level(pl_sd) > pc_get_group_level(sd) || (pl_sd->bl.m == sd->bl.m && pl_sd->bl.x == sd->bl.x && pl_sd->bl.y == sd->bl.y))
- continue; //Skip GMs greater than you.
- if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE))
- count++;
- else
- pc_setpos(pl_sd, sd->mapindex, sd->bl.x, sd->bl.y, CLR_RESPAWN);
- }
- }
- mapit_free(iter);
-
- sprintf(atcmd_output, msg_txt(95), p->party.name); // All online characters of the %s party have been recalled to your position.
- clif_displaymessage(fd, atcmd_output);
- if (count) {
- sprintf(atcmd_output, msg_txt(1033), count); // Because you are not authorized to warp from some maps, %d player(s) have not been recalled.
- clif_displaymessage(fd, atcmd_output);
- }
-
- return 0;
+ struct map_session_data* pl_sd;
+ struct s_mapiterator* iter;
+ char party_name[NAME_LENGTH];
+ struct party_data *p;
+ int count;
+ nullpo_retr(-1, sd);
+
+ memset(party_name, '\0', sizeof(party_name));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
+
+ if (!message || !*message || sscanf(message, "%23[^\n]", party_name) < 1) {
+ clif_displaymessage(fd, msg_txt(1035)); // Please enter a party name/ID (usage: @partyrecall <party_name/ID>).
+ return -1;
+ }
+
+ if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
+ clif_displaymessage(fd, msg_txt(1032)); // You are not authorized to warp somenone to your current map.
+ return -1;
+ }
+
+ if ((p = party_searchname(party_name)) == NULL && // name first to avoid error when name begin with a number
+ (p = party_search(atoi(message))) == NULL)
+ {
+ clif_displaymessage(fd, msg_txt(96)); // Incorrect name or ID, or no one from the party is online.
+ return -1;
+ }
+
+ count = 0;
+
+ iter = mapit_getallusers();
+ for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
+ {
+ if (sd->status.account_id != pl_sd->status.account_id && pl_sd->status.party_id == p->party.party_id)
+ {
+ if (pc_get_group_level(pl_sd) > pc_get_group_level(sd))
+ continue; //Skip GMs greater than you.
+ if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE))
+ count++;
+ else
+ pc_setpos(pl_sd, sd->mapindex, sd->bl.x, sd->bl.y, CLR_RESPAWN);
+ }
+ }
+ mapit_free(iter);
+
+ sprintf(atcmd_output, msg_txt(95), p->party.name); // All online characters of the %s party have been recalled to your position.
+ clif_displaymessage(fd, atcmd_output);
+ if (count) {
+ sprintf(atcmd_output, msg_txt(1033), count); // Because you are not authorized to warp from some maps, %d player(s) have not been recalled.
+ clif_displaymessage(fd, atcmd_output);
+ }
+
+ return 0;
}
/*==========================================
@@ -3561,11 +3722,11 @@ ACMD_FUNC(partyrecall)
*------------------------------------------*/
ACMD_FUNC(reloaditemdb)
{
- nullpo_retr(-1, sd);
- itemdb_reload();
- clif_displaymessage(fd, msg_txt(97)); // Item database has been reloaded.
+ nullpo_retr(-1, sd);
+ itemdb_reload();
+ clif_displaymessage(fd, msg_txt(97)); // Item database has been reloaded.
- return 0;
+ return 0;
}
/*==========================================
@@ -3573,16 +3734,16 @@ ACMD_FUNC(reloaditemdb)
*------------------------------------------*/
ACMD_FUNC(reloadmobdb)
{
- nullpo_retr(-1, sd);
- mob_reload();
- read_petdb();
- merc_reload();
- read_mercenarydb();
- read_mercenary_skilldb();
- reload_elementaldb();
- clif_displaymessage(fd, msg_txt(98)); // Monster database has been reloaded.
+ nullpo_retr(-1, sd);
+ mob_reload();
+ read_petdb();
+ merc_reload();
+ read_mercenarydb();
+ read_mercenary_skilldb();
+ reload_elementaldb();
+ clif_displaymessage(fd, msg_txt(98)); // Monster database has been reloaded.
- return 0;
+ return 0;
}
/*==========================================
@@ -3590,108 +3751,107 @@ ACMD_FUNC(reloadmobdb)
*------------------------------------------*/
ACMD_FUNC(reloadskilldb)
{
- nullpo_retr(-1, sd);
- skill_reload();
- merc_skill_reload();
- reload_elemental_skilldb();
- read_mercenary_skilldb();
- clif_displaymessage(fd, msg_txt(99)); // Skill database has been reloaded.
+ nullpo_retr(-1, sd);
+ skill_reload();
+ merc_skill_reload();
+ reload_elemental_skilldb();
+ read_mercenary_skilldb();
+ clif_displaymessage(fd, msg_txt(99)); // Skill database has been reloaded.
- return 0;
+ return 0;
}
/*==========================================
* @reloadatcommand - reloads atcommand_athena.conf groups.conf
*------------------------------------------*/
void atcommand_doload();
-ACMD_FUNC(reloadatcommand)
-{
- config_t run_test;
+ACMD_FUNC(reloadatcommand) {
+ config_t run_test;
- if (conf_read_file(&run_test, "conf/groups.conf")) {
- clif_displaymessage(fd, msg_txt(1036)); // Error reading groups.conf, reload failed.
- return -1;
- }
+ if (conf_read_file(&run_test, "conf/groups.conf")) {
+ clif_displaymessage(fd, msg_txt(1036)); // Error reading groups.conf, reload failed.
+ return -1;
+ }
- config_destroy(&run_test);
+ config_destroy(&run_test);
- if (conf_read_file(&run_test, ATCOMMAND_CONF_FILENAME)) {
- clif_displaymessage(fd, msg_txt(1037)); // Error reading atcommand_athena.conf, reload failed.
- return -1;
- }
+ if (conf_read_file(&run_test, ATCOMMAND_CONF_FILENAME)) {
+ clif_displaymessage(fd, msg_txt(1037)); // Error reading atcommand_athena.conf, reload failed.
+ return -1;
+ }
- config_destroy(&run_test);
+ config_destroy(&run_test);
- atcommand_doload();
- pc_groups_reload();
- clif_displaymessage(fd, msg_txt(254));
- return 0;
+ atcommand_doload();
+ pc_groups_reload();
+ clif_displaymessage(fd, msg_txt(254));
+ return 0;
}
/*==========================================
* @reloadbattleconf - reloads battle_athena.conf
*------------------------------------------*/
ACMD_FUNC(reloadbattleconf)
{
- struct Battle_Config prev_config;
- memcpy(&prev_config, &battle_config, sizeof(prev_config));
-
- battle_config_read(BATTLE_CONF_FILENAME);
-
- if (prev_config.item_rate_mvp != battle_config.item_rate_mvp
- || prev_config.item_rate_common != battle_config.item_rate_common
- || prev_config.item_rate_common_boss != battle_config.item_rate_common_boss
- || prev_config.item_rate_card != battle_config.item_rate_card
- || prev_config.item_rate_card_boss != battle_config.item_rate_card_boss
- || prev_config.item_rate_equip != battle_config.item_rate_equip
- || prev_config.item_rate_equip_boss != battle_config.item_rate_equip_boss
- || prev_config.item_rate_heal != battle_config.item_rate_heal
- || prev_config.item_rate_heal_boss != battle_config.item_rate_heal_boss
- || prev_config.item_rate_use != battle_config.item_rate_use
- || prev_config.item_rate_use_boss != battle_config.item_rate_use_boss
- || prev_config.item_rate_treasure != battle_config.item_rate_treasure
- || prev_config.item_rate_adddrop != battle_config.item_rate_adddrop
- || prev_config.logarithmic_drops != battle_config.logarithmic_drops
- || prev_config.item_drop_common_min != battle_config.item_drop_common_min
- || prev_config.item_drop_common_max != battle_config.item_drop_common_max
- || prev_config.item_drop_card_min != battle_config.item_drop_card_min
- || prev_config.item_drop_card_max != battle_config.item_drop_card_max
- || prev_config.item_drop_equip_min != battle_config.item_drop_equip_min
- || prev_config.item_drop_equip_max != battle_config.item_drop_equip_max
- || prev_config.item_drop_mvp_min != battle_config.item_drop_mvp_min
- || prev_config.item_drop_mvp_max != battle_config.item_drop_mvp_max
- || prev_config.item_drop_heal_min != battle_config.item_drop_heal_min
- || prev_config.item_drop_heal_max != battle_config.item_drop_heal_max
- || prev_config.item_drop_use_min != battle_config.item_drop_use_min
- || prev_config.item_drop_use_max != battle_config.item_drop_use_max
- || prev_config.item_drop_treasure_min != battle_config.item_drop_treasure_min
- || prev_config.item_drop_treasure_max != battle_config.item_drop_treasure_max
- || prev_config.base_exp_rate != battle_config.base_exp_rate
- || prev_config.job_exp_rate != battle_config.job_exp_rate
- ) {
- // Exp or Drop rates changed.
- mob_reload(); //Needed as well so rate changes take effect.
- chrif_ragsrvinfo(battle_config.base_exp_rate, battle_config.job_exp_rate, battle_config.item_rate_common);
- }
- clif_displaymessage(fd, msg_txt(255));
- return 0;
+ struct Battle_Config prev_config;
+ memcpy(&prev_config, &battle_config, sizeof(prev_config));
+
+ battle_config_read(BATTLE_CONF_FILENAME);
+
+ if( prev_config.item_rate_mvp != battle_config.item_rate_mvp
+ || prev_config.item_rate_common != battle_config.item_rate_common
+ || prev_config.item_rate_common_boss != battle_config.item_rate_common_boss
+ || prev_config.item_rate_card != battle_config.item_rate_card
+ || prev_config.item_rate_card_boss != battle_config.item_rate_card_boss
+ || prev_config.item_rate_equip != battle_config.item_rate_equip
+ || prev_config.item_rate_equip_boss != battle_config.item_rate_equip_boss
+ || prev_config.item_rate_heal != battle_config.item_rate_heal
+ || prev_config.item_rate_heal_boss != battle_config.item_rate_heal_boss
+ || prev_config.item_rate_use != battle_config.item_rate_use
+ || prev_config.item_rate_use_boss != battle_config.item_rate_use_boss
+ || prev_config.item_rate_treasure != battle_config.item_rate_treasure
+ || prev_config.item_rate_adddrop != battle_config.item_rate_adddrop
+ || prev_config.logarithmic_drops != battle_config.logarithmic_drops
+ || prev_config.item_drop_common_min != battle_config.item_drop_common_min
+ || prev_config.item_drop_common_max != battle_config.item_drop_common_max
+ || prev_config.item_drop_card_min != battle_config.item_drop_card_min
+ || prev_config.item_drop_card_max != battle_config.item_drop_card_max
+ || prev_config.item_drop_equip_min != battle_config.item_drop_equip_min
+ || prev_config.item_drop_equip_max != battle_config.item_drop_equip_max
+ || prev_config.item_drop_mvp_min != battle_config.item_drop_mvp_min
+ || prev_config.item_drop_mvp_max != battle_config.item_drop_mvp_max
+ || prev_config.item_drop_heal_min != battle_config.item_drop_heal_min
+ || prev_config.item_drop_heal_max != battle_config.item_drop_heal_max
+ || prev_config.item_drop_use_min != battle_config.item_drop_use_min
+ || prev_config.item_drop_use_max != battle_config.item_drop_use_max
+ || prev_config.item_drop_treasure_min != battle_config.item_drop_treasure_min
+ || prev_config.item_drop_treasure_max != battle_config.item_drop_treasure_max
+ || prev_config.base_exp_rate != battle_config.base_exp_rate
+ || prev_config.job_exp_rate != battle_config.job_exp_rate
+ )
+ { // Exp or Drop rates changed.
+ mob_reload(); //Needed as well so rate changes take effect.
+ chrif_ragsrvinfo(battle_config.base_exp_rate, battle_config.job_exp_rate, battle_config.item_rate_common);
+ }
+ clif_displaymessage(fd, msg_txt(255));
+ return 0;
}
/*==========================================
* @reloadstatusdb - reloads job_db1.txt job_db2.txt job_db2-2.txt refine_db.txt size_fix.txt
*------------------------------------------*/
ACMD_FUNC(reloadstatusdb)
{
- status_readdb();
- clif_displaymessage(fd, msg_txt(256));
- return 0;
+ status_readdb();
+ clif_displaymessage(fd, msg_txt(256));
+ return 0;
}
/*==========================================
* @reloadpcdb - reloads exp.txt skill_tree.txt attr_fix.txt statpoint.txt
*------------------------------------------*/
ACMD_FUNC(reloadpcdb)
{
- pc_readdb();
- clif_displaymessage(fd, msg_txt(257));
- return 0;
+ pc_readdb();
+ clif_displaymessage(fd, msg_txt(257));
+ return 0;
}
/*==========================================
@@ -3699,9 +3859,9 @@ ACMD_FUNC(reloadpcdb)
*------------------------------------------*/
ACMD_FUNC(reloadmotd)
{
- pc_read_motd();
- clif_displaymessage(fd, msg_txt(268));
- return 0;
+ pc_read_motd();
+ clif_displaymessage(fd, msg_txt(268));
+ return 0;
}
/*==========================================
@@ -3709,18 +3869,18 @@ ACMD_FUNC(reloadmotd)
*------------------------------------------*/
ACMD_FUNC(reloadscript)
{
- nullpo_retr(-1, sd);
- //atcommand_broadcast( fd, sd, "@broadcast", "Server is reloading scripts..." );
- //atcommand_broadcast( fd, sd, "@broadcast", "You will feel a bit of lag at this point !" );
+ nullpo_retr(-1, sd);
+ //atcommand_broadcast( fd, sd, "@broadcast", "Server is reloading scripts..." );
+ //atcommand_broadcast( fd, sd, "@broadcast", "You will feel a bit of lag at this point !" );
- flush_fifos();
- map_reloadnpc(true); // reload config files seeking for npcs
- script_reload();
- npc_reload();
+ flush_fifos();
+ map_reloadnpc(true); // reload config files seeking for npcs
+ script_reload();
+ npc_reload();
- clif_displaymessage(fd, msg_txt(100)); // Scripts have been reloaded.
+ clif_displaymessage(fd, msg_txt(100)); // Scripts have been reloaded.
- return 0;
+ return 0;
}
/*==========================================
@@ -3733,268 +3893,253 @@ ACMD_FUNC(reloadscript)
*------------------------------------------*/
ACMD_FUNC(mapinfo)
{
- struct map_session_data *pl_sd;
- struct s_mapiterator *iter;
- struct npc_data *nd = NULL;
- struct chat_data *cd = NULL;
- char direction[12];
- int i, m_id, chat_num, list = 0;
- unsigned short m_index;
- char mapname[24];
-
- nullpo_retr(-1, sd);
-
- memset(atcmd_output, '\0', sizeof(atcmd_output));
- memset(mapname, '\0', sizeof(mapname));
- memset(direction, '\0', sizeof(direction));
-
- sscanf(message, "%d %23[^\n]", &list, mapname);
-
- if (list < 0 || list > 3) {
- clif_displaymessage(fd, msg_txt(1038)); // Please enter at least one valid list number (usage: @mapinfo <0-3> <map>).
- return -1;
- }
-
- if (mapname[0] == '\0') {
- safestrncpy(mapname, mapindex_id2name(sd->mapindex), MAP_NAME_LENGTH);
- m_id = map_mapindex2mapid(sd->mapindex);
- } else {
- m_id = map_mapname2mapid(mapname);
- }
-
- if (m_id < 0) {
- clif_displaymessage(fd, msg_txt(1)); // Map not found.
- return -1;
- }
- m_index = mapindex_name2id(mapname); //This one shouldn't fail since the previous seek did not.
-
- clif_displaymessage(fd, msg_txt(1039)); // ------ Map Info ------
-
- // count chats (for initial message)
- chat_num = 0;
- iter = mapit_getallusers();
- for (pl_sd = (TBL_PC *)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC *)mapit_next(iter))
- if ((cd = (struct chat_data *)map_id2bl(pl_sd->chatID)) != NULL && pl_sd->mapindex == m_index && cd->usersd[0] == pl_sd)
- chat_num++;
- mapit_free(iter);
-
- sprintf(atcmd_output, msg_txt(1040), mapname, map[m_id].users, map[m_id].npc_num, chat_num); // Map Name: %s | Players In Map: %d | NPCs In Map: %d | Chats In Map: %d
- clif_displaymessage(fd, atcmd_output);
- clif_displaymessage(fd, msg_txt(1041)); // ------ Map Flags ------
- if (map[m_id].flag.town)
- clif_displaymessage(fd, msg_txt(1042)); // Town Map
-
- if (battle_config.autotrade_mapflag == map[m_id].flag.autotrade)
- clif_displaymessage(fd, msg_txt(1043)); // Autotrade Enabled
- else
- clif_displaymessage(fd, msg_txt(1044)); // Autotrade Disabled
-
- if (map[m_id].flag.battleground)
- clif_displaymessage(fd, msg_txt(1045)); // Battlegrounds ON
-
- strcpy(atcmd_output,msg_txt(1046)); // PvP Flags:
- if (map[m_id].flag.pvp)
- strcat(atcmd_output, msg_txt(1047)); // Pvp ON |
- if (map[m_id].flag.pvp_noguild)
- strcat(atcmd_output, msg_txt(1048)); // NoGuild |
- if (map[m_id].flag.pvp_noparty)
- strcat(atcmd_output, msg_txt(1049)); // NoParty |
- if (map[m_id].flag.pvp_nightmaredrop)
- strcat(atcmd_output, msg_txt(1050)); // NightmareDrop |
- if (map[m_id].flag.pvp_nocalcrank)
- strcat(atcmd_output, msg_txt(1051)); // NoCalcRank |
- clif_displaymessage(fd, atcmd_output);
-
- strcpy(atcmd_output,msg_txt(1052)); // GvG Flags:
- if (map[m_id].flag.gvg)
- strcat(atcmd_output, msg_txt(1053)); // GvG ON |
- if (map[m_id].flag.gvg_dungeon)
- strcat(atcmd_output, msg_txt(1054)); // GvG Dungeon |
- if (map[m_id].flag.gvg_castle)
- strcat(atcmd_output, msg_txt(1055)); // GvG Castle |
- if (map[m_id].flag.gvg_noparty)
- strcat(atcmd_output, msg_txt(1056)); // NoParty |
- clif_displaymessage(fd, atcmd_output);
-
- strcpy(atcmd_output,msg_txt(1057)); // Teleport Flags:
- if (map[m_id].flag.noteleport)
- strcat(atcmd_output, msg_txt(1058)); // NoTeleport |
- if (map[m_id].flag.monster_noteleport)
- strcat(atcmd_output, msg_txt(1059)); // Monster NoTeleport |
- if (map[m_id].flag.nowarp)
- strcat(atcmd_output, msg_txt(1060)); // NoWarp |
- if (map[m_id].flag.nowarpto)
- strcat(atcmd_output, msg_txt(1061)); // NoWarpTo |
- if (map[m_id].flag.noreturn)
- strcat(atcmd_output, msg_txt(1062)); // NoReturn |
- if (map[m_id].flag.nogo)
- strcat(atcmd_output, msg_txt(1063)); // NoGo |
- if (map[m_id].flag.nomemo)
- strcat(atcmd_output, msg_txt(1064)); // NoMemo |
- clif_displaymessage(fd, atcmd_output);
-
- sprintf(atcmd_output, msg_txt(1065), // No Exp Penalty: %s | No Zeny Penalty: %s
- (map[m_id].flag.noexppenalty) ? msg_txt(1066) : msg_txt(1067), (map[m_id].flag.nozenypenalty) ? msg_txt(1066) : msg_txt(1067)); // On / Off
- clif_displaymessage(fd, atcmd_output);
-
- if (map[m_id].flag.nosave) {
- if (!map[m_id].save.map)
- clif_displaymessage(fd, msg_txt(1068)); // No Save (Return to last Save Point)
- else if (map[m_id].save.x == -1 || map[m_id].save.y == -1) {
- sprintf(atcmd_output, msg_txt(1069), mapindex_id2name(map[m_id].save.map)); // No Save, Save Point: %s,Random
- clif_displaymessage(fd, atcmd_output);
- } else {
- sprintf(atcmd_output, msg_txt(1070), // No Save, Save Point: %s,%d,%d
- mapindex_id2name(map[m_id].save.map),map[m_id].save.x,map[m_id].save.y);
- clif_displaymessage(fd, atcmd_output);
- }
- }
-
- strcpy(atcmd_output,msg_txt(1071)); // Weather Flags:
- if (map[m_id].flag.snow)
- strcat(atcmd_output, msg_txt(1072)); // Snow |
- if (map[m_id].flag.fog)
- strcat(atcmd_output, msg_txt(1073)); // Fog |
- if (map[m_id].flag.sakura)
- strcat(atcmd_output, msg_txt(1074)); // Sakura |
- if (map[m_id].flag.clouds)
- strcat(atcmd_output, msg_txt(1075)); // Clouds |
- if (map[m_id].flag.clouds2)
- strcat(atcmd_output, msg_txt(1076)); // Clouds2 |
- if (map[m_id].flag.fireworks)
- strcat(atcmd_output, msg_txt(1077)); // Fireworks |
- if (map[m_id].flag.leaves)
- strcat(atcmd_output, msg_txt(1078)); // Leaves |
- /**
- * No longer available, keeping here just in case it's back someday. [Ind]
- **/
- //if (map[m_id].flag.rain)
- // strcat(atcmd_output, msg_txt(1079)); // Rain |
- if (map[m_id].flag.nightenabled)
- strcat(atcmd_output, msg_txt(1080)); // Displays Night |
- clif_displaymessage(fd, atcmd_output);
-
- strcpy(atcmd_output,msg_txt(1081)); // Other Flags:
- if (map[m_id].flag.nobranch)
- strcat(atcmd_output, msg_txt(1082)); // NoBranch |
- if (map[m_id].flag.notrade)
- strcat(atcmd_output, msg_txt(1083)); // NoTrade |
- if (map[m_id].flag.novending)
- strcat(atcmd_output, msg_txt(1084)); // NoVending |
- if (map[m_id].flag.nodrop)
- strcat(atcmd_output, msg_txt(1085)); // NoDrop |
- if (map[m_id].flag.noskill)
- strcat(atcmd_output, msg_txt(1086)); // NoSkill |
- if (map[m_id].flag.noicewall)
- strcat(atcmd_output, msg_txt(1087)); // NoIcewall |
- if (map[m_id].flag.allowks)
- strcat(atcmd_output, msg_txt(1088)); // AllowKS |
- if (map[m_id].flag.reset)
- strcat(atcmd_output, msg_txt(1089)); // Reset |
- clif_displaymessage(fd, atcmd_output);
-
- strcpy(atcmd_output,msg_txt(1090)); // Other Flags:
- if (map[m_id].nocommand)
- strcat(atcmd_output, msg_txt(1091)); // NoCommand |
- if (map[m_id].flag.nobaseexp)
- strcat(atcmd_output, msg_txt(1092)); // NoBaseEXP |
- if (map[m_id].flag.nojobexp)
- strcat(atcmd_output, msg_txt(1093)); // NoJobEXP |
- if (map[m_id].flag.nomobloot)
- strcat(atcmd_output, msg_txt(1094)); // NoMobLoot |
- if (map[m_id].flag.nomvploot)
- strcat(atcmd_output, msg_txt(1095)); // NoMVPLoot |
- if (map[m_id].flag.partylock)
- strcat(atcmd_output, msg_txt(1096)); // PartyLock |
- if (map[m_id].flag.guildlock)
- strcat(atcmd_output, msg_txt(1097)); // GuildLock |
- clif_displaymessage(fd, atcmd_output);
-
- switch (list) {
- case 0:
- // Do nothing. It's list 0, no additional display.
- break;
- case 1:
- clif_displaymessage(fd, msg_txt(1098)); // ----- Players in Map -----
- iter = mapit_getallusers();
- for (pl_sd = (TBL_PC *)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC *)mapit_next(iter)) {
- if (pl_sd->mapindex == m_index) {
- sprintf(atcmd_output, msg_txt(1099), // Player '%s' (session #%d) | Location: %d,%d
- pl_sd->status.name, pl_sd->fd, pl_sd->bl.x, pl_sd->bl.y);
- clif_displaymessage(fd, atcmd_output);
- }
- }
- mapit_free(iter);
- break;
- case 2:
- clif_displaymessage(fd, msg_txt(1100)); // ----- NPCs in Map -----
- for (i = 0; i < map[m_id].npc_num;) {
- nd = map[m_id].npc[i];
- switch (nd->ud.dir) {
- case 0:
- strcpy(direction, msg_txt(1101));
- break; // North
- case 1:
- strcpy(direction, msg_txt(1102));
- break; // North West
- case 2:
- strcpy(direction, msg_txt(1103));
- break; // West
- case 3:
- strcpy(direction, msg_txt(1104));
- break; // South West
- case 4:
- strcpy(direction, msg_txt(1105));
- break; // South
- case 5:
- strcpy(direction, msg_txt(1106));
- break; // South East
- case 6:
- strcpy(direction, msg_txt(1107));
- break; // East
- case 7:
- strcpy(direction, msg_txt(1108));
- break; // North East
- case 9:
- strcpy(direction, msg_txt(1109));
- break; // North
- default:
- strcpy(direction, msg_txt(1110));
- break; // Unknown
- }
- if (strcmp(nd->name,nd->exname) == 0)
- sprintf(atcmd_output, msg_txt(1111), // NPC %d: %s | Direction: %s | Sprite: %d | Location: %d %d
- ++i, nd->name, direction, nd->class_, nd->bl.x, nd->bl.y);
- else
- sprintf(atcmd_output, msg_txt(1112), // NPC %d: %s::%s | Direction: %s | Sprite: %d | Location: %d %d
- ++i, nd->name, nd->exname, direction, nd->class_, nd->bl.x, nd->bl.y);
- clif_displaymessage(fd, atcmd_output);
- }
- break;
- case 3:
- clif_displaymessage(fd, msg_txt(1113)); // ----- Chats in Map -----
- iter = mapit_getallusers();
- for (pl_sd = (TBL_PC *)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC *)mapit_next(iter)) {
- if ((cd = (struct chat_data *)map_id2bl(pl_sd->chatID)) != NULL &&
- pl_sd->mapindex == m_index &&
- cd->usersd[0] == pl_sd) {
- sprintf(atcmd_output, msg_txt(1114), // Chat: %s | Player: %s | Location: %d %d
- cd->title, pl_sd->status.name, cd->bl.x, cd->bl.y);
- clif_displaymessage(fd, atcmd_output);
- sprintf(atcmd_output, msg_txt(1115), // Users: %d/%d | Password: %s | Public: %s
- cd->users, cd->limit, cd->pass, (cd->pub) ? msg_txt(1116) : msg_txt(1117)); // Yes / No
- clif_displaymessage(fd, atcmd_output);
- }
- }
- mapit_free(iter);
- break;
- default: // normally impossible to arrive here
- clif_displaymessage(fd, msg_txt(1118)); // Please enter at least one valid list number (usage: @mapinfo <0-3> <map>).
- return -1;
- break;
- }
-
- return 0;
+ struct map_session_data* pl_sd;
+ struct s_mapiterator* iter;
+ struct npc_data *nd = NULL;
+ struct chat_data *cd = NULL;
+ char direction[12];
+ int i, m_id, chat_num, list = 0;
+ unsigned short m_index;
+ char mapname[24];
+
+ nullpo_retr(-1, sd);
+
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
+ memset(mapname, '\0', sizeof(mapname));
+ memset(direction, '\0', sizeof(direction));
+
+ sscanf(message, "%d %23[^\n]", &list, mapname);
+
+ if (list < 0 || list > 3) {
+ clif_displaymessage(fd, msg_txt(1038)); // Please enter at least one valid list number (usage: @mapinfo <0-3> <map>).
+ return -1;
+ }
+
+ if (mapname[0] == '\0') {
+ safestrncpy(mapname, mapindex_id2name(sd->mapindex), MAP_NAME_LENGTH);
+ m_id = map_mapindex2mapid(sd->mapindex);
+ } else {
+ m_id = map_mapname2mapid(mapname);
+ }
+
+ if (m_id < 0) {
+ clif_displaymessage(fd, msg_txt(1)); // Map not found.
+ return -1;
+ }
+ m_index = mapindex_name2id(mapname); //This one shouldn't fail since the previous seek did not.
+
+ clif_displaymessage(fd, msg_txt(1039)); // ------ Map Info ------
+
+ // count chats (for initial message)
+ chat_num = 0;
+ iter = mapit_getallusers();
+ for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
+ if( (cd = (struct chat_data*)map_id2bl(pl_sd->chatID)) != NULL && pl_sd->mapindex == m_index && cd->usersd[0] == pl_sd )
+ chat_num++;
+ mapit_free(iter);
+
+ sprintf(atcmd_output, msg_txt(1040), mapname, map[m_id].users, map[m_id].npc_num, chat_num); // Map Name: %s | Players In Map: %d | NPCs In Map: %d | Chats In Map: %d
+ clif_displaymessage(fd, atcmd_output);
+ clif_displaymessage(fd, msg_txt(1041)); // ------ Map Flags ------
+ if (map[m_id].flag.town)
+ clif_displaymessage(fd, msg_txt(1042)); // Town Map
+
+ if (battle_config.autotrade_mapflag == map[m_id].flag.autotrade)
+ clif_displaymessage(fd, msg_txt(1043)); // Autotrade Enabled
+ else
+ clif_displaymessage(fd, msg_txt(1044)); // Autotrade Disabled
+
+ if (map[m_id].flag.battleground)
+ clif_displaymessage(fd, msg_txt(1045)); // Battlegrounds ON
+
+ strcpy(atcmd_output,msg_txt(1046)); // PvP Flags:
+ if (map[m_id].flag.pvp)
+ strcat(atcmd_output, msg_txt(1047)); // Pvp ON |
+ if (map[m_id].flag.pvp_noguild)
+ strcat(atcmd_output, msg_txt(1048)); // NoGuild |
+ if (map[m_id].flag.pvp_noparty)
+ strcat(atcmd_output, msg_txt(1049)); // NoParty |
+ if (map[m_id].flag.pvp_nightmaredrop)
+ strcat(atcmd_output, msg_txt(1050)); // NightmareDrop |
+ if (map[m_id].flag.pvp_nocalcrank)
+ strcat(atcmd_output, msg_txt(1051)); // NoCalcRank |
+ clif_displaymessage(fd, atcmd_output);
+
+ strcpy(atcmd_output,msg_txt(1052)); // GvG Flags:
+ if (map[m_id].flag.gvg)
+ strcat(atcmd_output, msg_txt(1053)); // GvG ON |
+ if (map[m_id].flag.gvg_dungeon)
+ strcat(atcmd_output, msg_txt(1054)); // GvG Dungeon |
+ if (map[m_id].flag.gvg_castle)
+ strcat(atcmd_output, msg_txt(1055)); // GvG Castle |
+ if (map[m_id].flag.gvg_noparty)
+ strcat(atcmd_output, msg_txt(1056)); // NoParty |
+ clif_displaymessage(fd, atcmd_output);
+
+ strcpy(atcmd_output,msg_txt(1057)); // Teleport Flags:
+ if (map[m_id].flag.noteleport)
+ strcat(atcmd_output, msg_txt(1058)); // NoTeleport |
+ if (map[m_id].flag.monster_noteleport)
+ strcat(atcmd_output, msg_txt(1059)); // Monster NoTeleport |
+ if (map[m_id].flag.nowarp)
+ strcat(atcmd_output, msg_txt(1060)); // NoWarp |
+ if (map[m_id].flag.nowarpto)
+ strcat(atcmd_output, msg_txt(1061)); // NoWarpTo |
+ if (map[m_id].flag.noreturn)
+ strcat(atcmd_output, msg_txt(1062)); // NoReturn |
+ if (map[m_id].flag.nogo)
+ strcat(atcmd_output, msg_txt(1063)); // NoGo |
+ if (map[m_id].flag.nomemo)
+ strcat(atcmd_output, msg_txt(1064)); // NoMemo |
+ clif_displaymessage(fd, atcmd_output);
+
+ sprintf(atcmd_output, msg_txt(1065), // No Exp Penalty: %s | No Zeny Penalty: %s
+ (map[m_id].flag.noexppenalty) ? msg_txt(1066) : msg_txt(1067), (map[m_id].flag.nozenypenalty) ? msg_txt(1066) : msg_txt(1067)); // On / Off
+ clif_displaymessage(fd, atcmd_output);
+
+ if (map[m_id].flag.nosave) {
+ if (!map[m_id].save.map)
+ clif_displaymessage(fd, msg_txt(1068)); // No Save (Return to last Save Point)
+ else if (map[m_id].save.x == -1 || map[m_id].save.y == -1 ) {
+ sprintf(atcmd_output, msg_txt(1069), mapindex_id2name(map[m_id].save.map)); // No Save, Save Point: %s,Random
+ clif_displaymessage(fd, atcmd_output);
+ }
+ else {
+ sprintf(atcmd_output, msg_txt(1070), // No Save, Save Point: %s,%d,%d
+ mapindex_id2name(map[m_id].save.map),map[m_id].save.x,map[m_id].save.y);
+ clif_displaymessage(fd, atcmd_output);
+ }
+ }
+
+ strcpy(atcmd_output,msg_txt(1071)); // Weather Flags:
+ if (map[m_id].flag.snow)
+ strcat(atcmd_output, msg_txt(1072)); // Snow |
+ if (map[m_id].flag.fog)
+ strcat(atcmd_output, msg_txt(1073)); // Fog |
+ if (map[m_id].flag.sakura)
+ strcat(atcmd_output, msg_txt(1074)); // Sakura |
+ if (map[m_id].flag.clouds)
+ strcat(atcmd_output, msg_txt(1075)); // Clouds |
+ if (map[m_id].flag.clouds2)
+ strcat(atcmd_output, msg_txt(1076)); // Clouds2 |
+ if (map[m_id].flag.fireworks)
+ strcat(atcmd_output, msg_txt(1077)); // Fireworks |
+ if (map[m_id].flag.leaves)
+ strcat(atcmd_output, msg_txt(1078)); // Leaves |
+ /**
+ * No longer available, keeping here just in case it's back someday. [Ind]
+ **/
+ //if (map[m_id].flag.rain)
+ // strcat(atcmd_output, msg_txt(1079)); // Rain |
+ if (map[m_id].flag.nightenabled)
+ strcat(atcmd_output, msg_txt(1080)); // Displays Night |
+ clif_displaymessage(fd, atcmd_output);
+
+ strcpy(atcmd_output,msg_txt(1081)); // Other Flags:
+ if (map[m_id].flag.nobranch)
+ strcat(atcmd_output, msg_txt(1082)); // NoBranch |
+ if (map[m_id].flag.notrade)
+ strcat(atcmd_output, msg_txt(1083)); // NoTrade |
+ if (map[m_id].flag.novending)
+ strcat(atcmd_output, msg_txt(1084)); // NoVending |
+ if (map[m_id].flag.nodrop)
+ strcat(atcmd_output, msg_txt(1085)); // NoDrop |
+ if (map[m_id].flag.noskill)
+ strcat(atcmd_output, msg_txt(1086)); // NoSkill |
+ if (map[m_id].flag.noicewall)
+ strcat(atcmd_output, msg_txt(1087)); // NoIcewall |
+ if (map[m_id].flag.allowks)
+ strcat(atcmd_output, msg_txt(1088)); // AllowKS |
+ if (map[m_id].flag.reset)
+ strcat(atcmd_output, msg_txt(1089)); // Reset |
+ clif_displaymessage(fd, atcmd_output);
+
+ strcpy(atcmd_output,msg_txt(1090)); // Other Flags:
+ if (map[m_id].nocommand)
+ strcat(atcmd_output, msg_txt(1091)); // NoCommand |
+ if (map[m_id].flag.nobaseexp)
+ strcat(atcmd_output, msg_txt(1092)); // NoBaseEXP |
+ if (map[m_id].flag.nojobexp)
+ strcat(atcmd_output, msg_txt(1093)); // NoJobEXP |
+ if (map[m_id].flag.nomobloot)
+ strcat(atcmd_output, msg_txt(1094)); // NoMobLoot |
+ if (map[m_id].flag.nomvploot)
+ strcat(atcmd_output, msg_txt(1095)); // NoMVPLoot |
+ if (map[m_id].flag.partylock)
+ strcat(atcmd_output, msg_txt(1096)); // PartyLock |
+ if (map[m_id].flag.guildlock)
+ strcat(atcmd_output, msg_txt(1097)); // GuildLock |
+ clif_displaymessage(fd, atcmd_output);
+
+ switch (list) {
+ case 0:
+ // Do nothing. It's list 0, no additional display.
+ break;
+ case 1:
+ clif_displaymessage(fd, msg_txt(1098)); // ----- Players in Map -----
+ iter = mapit_getallusers();
+ for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
+ {
+ if (pl_sd->mapindex == m_index) {
+ sprintf(atcmd_output, msg_txt(1099), // Player '%s' (session #%d) | Location: %d,%d
+ pl_sd->status.name, pl_sd->fd, pl_sd->bl.x, pl_sd->bl.y);
+ clif_displaymessage(fd, atcmd_output);
+ }
+ }
+ mapit_free(iter);
+ break;
+ case 2:
+ clif_displaymessage(fd, msg_txt(1100)); // ----- NPCs in Map -----
+ for (i = 0; i < map[m_id].npc_num;)
+ {
+ nd = map[m_id].npc[i];
+ switch(nd->ud.dir) {
+ case 0: strcpy(direction, msg_txt(1101)); break; // North
+ case 1: strcpy(direction, msg_txt(1102)); break; // North West
+ case 2: strcpy(direction, msg_txt(1103)); break; // West
+ case 3: strcpy(direction, msg_txt(1104)); break; // South West
+ case 4: strcpy(direction, msg_txt(1105)); break; // South
+ case 5: strcpy(direction, msg_txt(1106)); break; // South East
+ case 6: strcpy(direction, msg_txt(1107)); break; // East
+ case 7: strcpy(direction, msg_txt(1108)); break; // North East
+ case 9: strcpy(direction, msg_txt(1109)); break; // North
+ default: strcpy(direction, msg_txt(1110)); break; // Unknown
+ }
+ if(strcmp(nd->name,nd->exname) == 0)
+ sprintf(atcmd_output, msg_txt(1111), // NPC %d: %s | Direction: %s | Sprite: %d | Location: %d %d
+ ++i, nd->name, direction, nd->class_, nd->bl.x, nd->bl.y);
+ else
+ sprintf(atcmd_output, msg_txt(1112), // NPC %d: %s::%s | Direction: %s | Sprite: %d | Location: %d %d
+ ++i, nd->name, nd->exname, direction, nd->class_, nd->bl.x, nd->bl.y);
+ clif_displaymessage(fd, atcmd_output);
+ }
+ break;
+ case 3:
+ clif_displaymessage(fd, msg_txt(1113)); // ----- Chats in Map -----
+ iter = mapit_getallusers();
+ for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
+ {
+ if ((cd = (struct chat_data*)map_id2bl(pl_sd->chatID)) != NULL &&
+ pl_sd->mapindex == m_index &&
+ cd->usersd[0] == pl_sd)
+ {
+ sprintf(atcmd_output, msg_txt(1114), // Chat: %s | Player: %s | Location: %d %d
+ cd->title, pl_sd->status.name, cd->bl.x, cd->bl.y);
+ clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output, msg_txt(1115), // Users: %d/%d | Password: %s | Public: %s
+ cd->users, cd->limit, cd->pass, (cd->pub) ? msg_txt(1116) : msg_txt(1117)); // Yes / No
+ clif_displaymessage(fd, atcmd_output);
+ }
+ }
+ mapit_free(iter);
+ break;
+ default: // normally impossible to arrive here
+ clif_displaymessage(fd, msg_txt(1118)); // Please enter at least one valid list number (usage: @mapinfo <0-3> <map>).
+ return -1;
+ break;
+ }
+
+ return 0;
}
/*==========================================
@@ -4002,58 +4147,58 @@ ACMD_FUNC(mapinfo)
*------------------------------------------*/
ACMD_FUNC(mount_peco)
{
- nullpo_retr(-1, sd);
-
- if (sd->disguise) {
- clif_displaymessage(fd, msg_txt(212)); // Cannot mount while in disguise.
- return -1;
- }
-
- if ((sd->class_&MAPID_THIRDMASK) == MAPID_RUNE_KNIGHT && pc_checkskill(sd,RK_DRAGONTRAINING) > 0) {
- if (!(sd->sc.option&OPTION_DRAGON1)) {
- clif_displaymessage(sd->fd,msg_txt(1119)); // You have mounted your Dragon.
- pc_setoption(sd, sd->sc.option|OPTION_DRAGON1);
- } else {
- clif_displaymessage(sd->fd,msg_txt(1120)); // You have released your Dragon.
- pc_setoption(sd, sd->sc.option&~OPTION_DRAGON1);
- }
- return 0;
- }
- if ((sd->class_&MAPID_THIRDMASK) == MAPID_RANGER && pc_checkskill(sd,RA_WUGRIDER) > 0) {
- if (!pc_isridingwug(sd)) {
- clif_displaymessage(sd->fd,msg_txt(1121)); // You have mounted your Warg.
- pc_setoption(sd, sd->sc.option|OPTION_WUGRIDER);
- } else {
- clif_displaymessage(sd->fd,msg_txt(1122)); // You have released your Warg.
- pc_setoption(sd, sd->sc.option&~OPTION_WUGRIDER);
- }
- return 0;
- }
- if ((sd->class_&MAPID_THIRDMASK) == MAPID_MECHANIC) {
- if (!pc_ismadogear(sd)) {
- clif_displaymessage(sd->fd,msg_txt(1123)); // You have mounted your Mado Gear.
- pc_setoption(sd, sd->sc.option|OPTION_MADOGEAR);
- } else {
- clif_displaymessage(sd->fd,msg_txt(1124)); // You have released your Mado Gear.
- pc_setoption(sd, sd->sc.option&~OPTION_MADOGEAR);
- }
- return 0;
- }
- if (!pc_isriding(sd)) { // if actually no peco
-
- if (!pc_checkskill(sd, KN_RIDING)) {
- clif_displaymessage(fd, msg_txt(213)); // You can not mount a Peco Peco with your current job.
- return -1;
- }
-
- pc_setoption(sd, sd->sc.option | OPTION_RIDING);
- clif_displaymessage(fd, msg_txt(102)); // You have mounted a Peco Peco.
- } else {//Dismount
- pc_setoption(sd, sd->sc.option & ~OPTION_RIDING);
- clif_displaymessage(fd, msg_txt(214)); // You have released your Peco Peco.
- }
-
- return 0;
+ nullpo_retr(-1, sd);
+
+ if (sd->disguise) {
+ clif_displaymessage(fd, msg_txt(212)); // Cannot mount while in disguise.
+ return -1;
+ }
+
+ if( (sd->class_&MAPID_THIRDMASK) == MAPID_RUNE_KNIGHT && pc_checkskill(sd,RK_DRAGONTRAINING) > 0 ) {
+ if( !(sd->sc.option&OPTION_DRAGON1) ) {
+ clif_displaymessage(sd->fd,msg_txt(1119)); // You have mounted your Dragon.
+ pc_setoption(sd, sd->sc.option|OPTION_DRAGON1);
+ } else {
+ clif_displaymessage(sd->fd,msg_txt(1120)); // You have released your Dragon.
+ pc_setoption(sd, sd->sc.option&~OPTION_DRAGON1);
+ }
+ return 0;
+ }
+ if( (sd->class_&MAPID_THIRDMASK) == MAPID_RANGER && pc_checkskill(sd,RA_WUGRIDER) > 0 ) {
+ if( !pc_isridingwug(sd) ) {
+ clif_displaymessage(sd->fd,msg_txt(1121)); // You have mounted your Warg.
+ pc_setoption(sd, sd->sc.option|OPTION_WUGRIDER);
+ } else {
+ clif_displaymessage(sd->fd,msg_txt(1122)); // You have released your Warg.
+ pc_setoption(sd, sd->sc.option&~OPTION_WUGRIDER);
+ }
+ return 0;
+ }
+ if( (sd->class_&MAPID_THIRDMASK) == MAPID_MECHANIC ) {
+ if( !pc_ismadogear(sd) ) {
+ clif_displaymessage(sd->fd,msg_txt(1123)); // You have mounted your Mado Gear.
+ pc_setoption(sd, sd->sc.option|OPTION_MADOGEAR);
+ } else {
+ clif_displaymessage(sd->fd,msg_txt(1124)); // You have released your Mado Gear.
+ pc_setoption(sd, sd->sc.option&~OPTION_MADOGEAR);
+ }
+ return 0;
+ }
+ if (!pc_isriding(sd)) { // if actually no peco
+
+ if (!pc_checkskill(sd, KN_RIDING)) {
+ clif_displaymessage(fd, msg_txt(213)); // You can not mount a Peco Peco with your current job.
+ return -1;
+ }
+
+ pc_setoption(sd, sd->sc.option | OPTION_RIDING);
+ clif_displaymessage(fd, msg_txt(102)); // You have mounted a Peco Peco.
+ } else {//Dismount
+ pc_setoption(sd, sd->sc.option & ~OPTION_RIDING);
+ clif_displaymessage(fd, msg_txt(214)); // You have released your Peco Peco.
+ }
+
+ return 0;
}
/*==========================================
@@ -4061,39 +4206,40 @@ ACMD_FUNC(mount_peco)
*------------------------------------------*/
ACMD_FUNC(guildspy)
{
- char guild_name[NAME_LENGTH];
- struct guild *g;
- nullpo_retr(-1, sd);
-
- memset(guild_name, '\0', sizeof(guild_name));
- memset(atcmd_output, '\0', sizeof(atcmd_output));
-
- if (!enable_spy) {
- clif_displaymessage(fd, msg_txt(1125)); // The mapserver has spy command support disabled.
- return -1;
- }
- if (!message || !*message || sscanf(message, "%23[^\n]", guild_name) < 1) {
- clif_displaymessage(fd, msg_txt(1126)); // Please enter a guild name/ID (usage: @guildspy <guild_name/ID>).
- return -1;
- }
-
- if ((g = guild_searchname(guild_name)) != NULL || // name first to avoid error when name begin with a number
- (g = guild_search(atoi(message))) != NULL) {
- if (sd->guildspy == g->guild_id) {
- sd->guildspy = 0;
- sprintf(atcmd_output, msg_txt(103), g->name); // No longer spying on the %s guild.
- clif_displaymessage(fd, atcmd_output);
- } else {
- sd->guildspy = g->guild_id;
- sprintf(atcmd_output, msg_txt(104), g->name); // Spying on the %s guild.
- clif_displaymessage(fd, atcmd_output);
- }
- } else {
- clif_displaymessage(fd, msg_txt(94)); // Incorrect name/ID, or no one from the specified guild is online.
- return -1;
- }
-
- return 0;
+ char guild_name[NAME_LENGTH];
+ struct guild *g;
+ nullpo_retr(-1, sd);
+
+ memset(guild_name, '\0', sizeof(guild_name));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
+
+ if (!enable_spy)
+ {
+ clif_displaymessage(fd, msg_txt(1125)); // The mapserver has spy command support disabled.
+ return -1;
+ }
+ if (!message || !*message || sscanf(message, "%23[^\n]", guild_name) < 1) {
+ clif_displaymessage(fd, msg_txt(1126)); // Please enter a guild name/ID (usage: @guildspy <guild_name/ID>).
+ return -1;
+ }
+
+ if ((g = guild_searchname(guild_name)) != NULL || // name first to avoid error when name begin with a number
+ (g = guild_search(atoi(message))) != NULL) {
+ if (sd->guildspy == g->guild_id) {
+ sd->guildspy = 0;
+ sprintf(atcmd_output, msg_txt(103), g->name); // No longer spying on the %s guild.
+ clif_displaymessage(fd, atcmd_output);
+ } else {
+ sd->guildspy = g->guild_id;
+ sprintf(atcmd_output, msg_txt(104), g->name); // Spying on the %s guild.
+ clif_displaymessage(fd, atcmd_output);
+ }
+ } else {
+ clif_displaymessage(fd, msg_txt(94)); // Incorrect name/ID, or no one from the specified guild is online.
+ return -1;
+ }
+
+ return 0;
}
/*==========================================
@@ -4101,40 +4247,41 @@ ACMD_FUNC(guildspy)
*------------------------------------------*/
ACMD_FUNC(partyspy)
{
- char party_name[NAME_LENGTH];
- struct party_data *p;
- nullpo_retr(-1, sd);
+ char party_name[NAME_LENGTH];
+ struct party_data *p;
+ nullpo_retr(-1, sd);
- memset(party_name, '\0', sizeof(party_name));
- memset(atcmd_output, '\0', sizeof(atcmd_output));
+ memset(party_name, '\0', sizeof(party_name));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
- if (!enable_spy) {
- clif_displaymessage(fd, msg_txt(1125)); // The mapserver has spy command support disabled.
- return -1;
- }
+ if (!enable_spy)
+ {
+ clif_displaymessage(fd, msg_txt(1125)); // The mapserver has spy command support disabled.
+ return -1;
+ }
- if (!message || !*message || sscanf(message, "%23[^\n]", party_name) < 1) {
- clif_displaymessage(fd, msg_txt(1127)); // Please enter a party name/ID (usage: @partyspy <party_name/ID>).
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%23[^\n]", party_name) < 1) {
+ clif_displaymessage(fd, msg_txt(1127)); // Please enter a party name/ID (usage: @partyspy <party_name/ID>).
+ return -1;
+ }
- if ((p = party_searchname(party_name)) != NULL || // name first to avoid error when name begin with a number
- (p = party_search(atoi(message))) != NULL) {
- if (sd->partyspy == p->party.party_id) {
- sd->partyspy = 0;
- sprintf(atcmd_output, msg_txt(105), p->party.name); // No longer spying on the %s party.
- clif_displaymessage(fd, atcmd_output);
- } else {
- sd->partyspy = p->party.party_id;
- sprintf(atcmd_output, msg_txt(106), p->party.name); // Spying on the %s party.
- clif_displaymessage(fd, atcmd_output);
- }
- } else {
- clif_displaymessage(fd, msg_txt(96)); // Incorrect name/ID, or no one from the specified party is online.
- return -1;
- }
+ if ((p = party_searchname(party_name)) != NULL || // name first to avoid error when name begin with a number
+ (p = party_search(atoi(message))) != NULL) {
+ if (sd->partyspy == p->party.party_id) {
+ sd->partyspy = 0;
+ sprintf(atcmd_output, msg_txt(105), p->party.name); // No longer spying on the %s party.
+ clif_displaymessage(fd, atcmd_output);
+ } else {
+ sd->partyspy = p->party.party_id;
+ sprintf(atcmd_output, msg_txt(106), p->party.name); // Spying on the %s party.
+ clif_displaymessage(fd, atcmd_output);
+ }
+ } else {
+ clif_displaymessage(fd, msg_txt(96)); // Incorrect name/ID, or no one from the specified party is online.
+ return -1;
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -4142,28 +4289,28 @@ ACMD_FUNC(partyspy)
*------------------------------------------*/
ACMD_FUNC(repairall)
{
- int count, i;
- nullpo_retr(-1, sd);
+ int count, i;
+ nullpo_retr(-1, sd);
- count = 0;
- for (i = 0; i < MAX_INVENTORY; i++) {
- if (sd->status.inventory[i].nameid && sd->status.inventory[i].attribute == 1) {
- sd->status.inventory[i].attribute = 0;
- clif_produceeffect(sd, 0, sd->status.inventory[i].nameid);
- count++;
- }
- }
+ count = 0;
+ for (i = 0; i < MAX_INVENTORY; i++) {
+ if (sd->status.inventory[i].nameid && sd->status.inventory[i].attribute == 1) {
+ sd->status.inventory[i].attribute = 0;
+ clif_produceeffect(sd, 0, sd->status.inventory[i].nameid);
+ count++;
+ }
+ }
- if (count > 0) {
- clif_misceffect(&sd->bl, 3);
- clif_equiplist(sd);
- clif_displaymessage(fd, msg_txt(107)); // All items have been repaired.
- } else {
- clif_displaymessage(fd, msg_txt(108)); // No item need to be repaired.
- return -1;
- }
+ if (count > 0) {
+ clif_misceffect(&sd->bl, 3);
+ clif_equiplist(sd);
+ clif_displaymessage(fd, msg_txt(107)); // All items have been repaired.
+ } else {
+ clif_displaymessage(fd, msg_txt(108)); // No item need to be repaired.
+ return -1;
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -4171,30 +4318,30 @@ ACMD_FUNC(repairall)
*------------------------------------------*/
ACMD_FUNC(nuke)
{
- struct map_session_data *pl_sd;
- nullpo_retr(-1, sd);
+ struct map_session_data *pl_sd;
+ nullpo_retr(-1, sd);
- memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
- if (!message || !*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) {
- clif_displaymessage(fd, msg_txt(1128)); // Please enter a player name (usage: @nuke <char name>).
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) {
+ clif_displaymessage(fd, msg_txt(1128)); // Please enter a player name (usage: @nuke <char name>).
+ return -1;
+ }
- if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) {
- if (pc_get_group_level(sd) >= pc_get_group_level(pl_sd)) { // you can kill only lower or same GM level
- skill_castend_nodamage_id(&pl_sd->bl, &pl_sd->bl, NPC_SELFDESTRUCTION, 99, gettick(), 0);
- clif_displaymessage(fd, msg_txt(109)); // Player has been nuked!
- } else {
- clif_displaymessage(fd, msg_txt(81)); // Your GM level don't authorise you to do this action on this player.
- return -1;
- }
- } else {
- clif_displaymessage(fd, msg_txt(3)); // Character not found.
- return -1;
- }
+ if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) {
+ if (pc_get_group_level(sd) >= pc_get_group_level(pl_sd)) { // you can kill only lower or same GM level
+ skill_castend_nodamage_id(&pl_sd->bl, &pl_sd->bl, NPC_SELFDESTRUCTION, 99, gettick(), 0);
+ clif_displaymessage(fd, msg_txt(109)); // Player has been nuked!
+ } else {
+ clif_displaymessage(fd, msg_txt(81)); // Your GM level don't authorise you to do this action on this player.
+ return -1;
+ }
+ } else {
+ clif_displaymessage(fd, msg_txt(3)); // Character not found.
+ return -1;
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -4202,29 +4349,29 @@ ACMD_FUNC(nuke)
*------------------------------------------*/
ACMD_FUNC(tonpc)
{
- char npcname[NAME_LENGTH+1];
- struct npc_data *nd;
+ char npcname[NAME_LENGTH+1];
+ struct npc_data *nd;
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- memset(npcname, 0, sizeof(npcname));
+ memset(npcname, 0, sizeof(npcname));
- if (!message || !*message || sscanf(message, "%23[^\n]", npcname) < 1) {
- clif_displaymessage(fd, msg_txt(1129)); // Please enter a NPC name (usage: @tonpc <NPC_name>).
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%23[^\n]", npcname) < 1) {
+ clif_displaymessage(fd, msg_txt(1129)); // Please enter a NPC name (usage: @tonpc <NPC_name>).
+ return -1;
+ }
- if ((nd = npc_name2id(npcname)) != NULL) {
- if (pc_setpos(sd, map_id2index(nd->bl.m), nd->bl.x, nd->bl.y, CLR_TELEPORT) == 0)
- clif_displaymessage(fd, msg_txt(0)); // Warped.
- else
- return -1;
- } else {
- clif_displaymessage(fd, msg_txt(111)); // This NPC doesn't exist.
- return -1;
- }
+ if ((nd = npc_name2id(npcname)) != NULL) {
+ if (pc_setpos(sd, map_id2index(nd->bl.m), nd->bl.x, nd->bl.y, CLR_TELEPORT) == 0)
+ clif_displaymessage(fd, msg_txt(0)); // Warped.
+ else
+ return -1;
+ } else {
+ clif_displaymessage(fd, msg_txt(111)); // This NPC doesn't exist.
+ return -1;
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -4232,25 +4379,25 @@ ACMD_FUNC(tonpc)
*------------------------------------------*/
ACMD_FUNC(shownpc)
{
- char NPCname[NAME_LENGTH+1];
- nullpo_retr(-1, sd);
+ char NPCname[NAME_LENGTH+1];
+ nullpo_retr(-1, sd);
- memset(NPCname, '\0', sizeof(NPCname));
+ memset(NPCname, '\0', sizeof(NPCname));
- if (!message || !*message || sscanf(message, "%23[^\n]", NPCname) < 1) {
- clif_displaymessage(fd, msg_txt(1130)); // Please enter a NPC name (usage: @enablenpc <NPC_name>).
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%23[^\n]", NPCname) < 1) {
+ clif_displaymessage(fd, msg_txt(1130)); // Please enter a NPC name (usage: @enablenpc <NPC_name>).
+ return -1;
+ }
- if (npc_name2id(NPCname) != NULL) {
- npc_enable(NPCname, 1);
- clif_displaymessage(fd, msg_txt(110)); // Npc Enabled.
- } else {
- clif_displaymessage(fd, msg_txt(111)); // This NPC doesn't exist.
- return -1;
- }
+ if (npc_name2id(NPCname) != NULL) {
+ npc_enable(NPCname, 1);
+ clif_displaymessage(fd, msg_txt(110)); // Npc Enabled.
+ } else {
+ clif_displaymessage(fd, msg_txt(111)); // This NPC doesn't exist.
+ return -1;
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -4258,114 +4405,114 @@ ACMD_FUNC(shownpc)
*------------------------------------------*/
ACMD_FUNC(hidenpc)
{
- char NPCname[NAME_LENGTH+1];
- nullpo_retr(-1, sd);
+ char NPCname[NAME_LENGTH+1];
+ nullpo_retr(-1, sd);
- memset(NPCname, '\0', sizeof(NPCname));
+ memset(NPCname, '\0', sizeof(NPCname));
- if (!message || !*message || sscanf(message, "%23[^\n]", NPCname) < 1) {
- clif_displaymessage(fd, msg_txt(1131)); // Please enter a NPC name (usage: @hidenpc <NPC_name>).
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%23[^\n]", NPCname) < 1) {
+ clif_displaymessage(fd, msg_txt(1131)); // Please enter a NPC name (usage: @hidenpc <NPC_name>).
+ return -1;
+ }
- if (npc_name2id(NPCname) == NULL) {
- clif_displaymessage(fd, msg_txt(111)); // This NPC doesn't exist.
- return -1;
- }
+ if (npc_name2id(NPCname) == NULL) {
+ clif_displaymessage(fd, msg_txt(111)); // This NPC doesn't exist.
+ return -1;
+ }
- npc_enable(NPCname, 0);
- clif_displaymessage(fd, msg_txt(112)); // Npc Disabled.
- return 0;
+ npc_enable(NPCname, 0);
+ clif_displaymessage(fd, msg_txt(112)); // Npc Disabled.
+ return 0;
}
ACMD_FUNC(loadnpc)
{
- FILE *fp;
+ FILE *fp;
- if (!message || !*message) {
- clif_displaymessage(fd, msg_txt(1132)); // Please enter a script file name (usage: @loadnpc <file name>).
- return -1;
- }
+ if (!message || !*message) {
+ clif_displaymessage(fd, msg_txt(1132)); // Please enter a script file name (usage: @loadnpc <file name>).
+ return -1;
+ }
- // check if script file exists
- if ((fp = fopen(message, "r")) == NULL) {
- clif_displaymessage(fd, msg_txt(261));
- return -1;
- }
- fclose(fp);
+ // check if script file exists
+ if ((fp = fopen(message, "r")) == NULL) {
+ clif_displaymessage(fd, msg_txt(261));
+ return -1;
+ }
+ fclose(fp);
- // add to list of script sources and run it
- npc_addsrcfile(message);
- npc_parsesrcfile(message,true);
- npc_read_event_script();
+ // add to list of script sources and run it
+ npc_addsrcfile(message);
+ npc_parsesrcfile(message,true);
+ npc_read_event_script();
- clif_displaymessage(fd, msg_txt(262));
+ clif_displaymessage(fd, msg_txt(262));
- return 0;
+ return 0;
}
ACMD_FUNC(unloadnpc)
{
- struct npc_data *nd;
- char NPCname[NAME_LENGTH+1];
- nullpo_retr(-1, sd);
+ struct npc_data *nd;
+ char NPCname[NAME_LENGTH+1];
+ nullpo_retr(-1, sd);
- memset(NPCname, '\0', sizeof(NPCname));
+ memset(NPCname, '\0', sizeof(NPCname));
- if (!message || !*message || sscanf(message, "%24[^\n]", NPCname) < 1) {
- clif_displaymessage(fd, msg_txt(1133)); // Please enter a NPC name (usage: @npcoff <NPC_name>).
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%24[^\n]", NPCname) < 1) {
+ clif_displaymessage(fd, msg_txt(1133)); // Please enter a NPC name (usage: @npcoff <NPC_name>).
+ return -1;
+ }
- if ((nd = npc_name2id(NPCname)) == NULL) {
- clif_displaymessage(fd, msg_txt(111)); // This NPC doesn't exist.
- return -1;
- }
+ if ((nd = npc_name2id(NPCname)) == NULL) {
+ clif_displaymessage(fd, msg_txt(111)); // This NPC doesn't exist.
+ return -1;
+ }
- npc_unload_duplicates(nd);
- npc_unload(nd,true);
- npc_read_event_script();
- clif_displaymessage(fd, msg_txt(112)); // Npc Disabled.
- return 0;
+ npc_unload_duplicates(nd);
+ npc_unload(nd,true);
+ npc_read_event_script();
+ clif_displaymessage(fd, msg_txt(112)); // Npc Disabled.
+ return 0;
}
/*==========================================
* time in txt for time command (by [Yor])
*------------------------------------------*/
-char *txt_time(unsigned int duration)
+char* txt_time(unsigned int duration)
{
- int days, hours, minutes, seconds;
- char temp[CHAT_SIZE_MAX];
- static char temp1[CHAT_SIZE_MAX];
+ int days, hours, minutes, seconds;
+ char temp[CHAT_SIZE_MAX];
+ static char temp1[CHAT_SIZE_MAX];
- memset(temp, '\0', sizeof(temp));
- memset(temp1, '\0', sizeof(temp1));
+ memset(temp, '\0', sizeof(temp));
+ memset(temp1, '\0', sizeof(temp1));
- days = duration / (60 * 60 * 24);
- duration = duration - (60 * 60 * 24 * days);
- hours = duration / (60 * 60);
- duration = duration - (60 * 60 * hours);
- minutes = duration / 60;
- seconds = duration - (60 * minutes);
+ days = duration / (60 * 60 * 24);
+ duration = duration - (60 * 60 * 24 * days);
+ hours = duration / (60 * 60);
+ duration = duration - (60 * 60 * hours);
+ minutes = duration / 60;
+ seconds = duration - (60 * minutes);
- if (days == 1)
- sprintf(temp, msg_txt(219), days); // %d day
- else if (days > 1)
- sprintf(temp, msg_txt(220), days); // %d days
- if (hours == 1)
- sprintf(temp1, msg_txt(221), temp, hours); // %s %d hour
- else if (hours > 1)
- sprintf(temp1, msg_txt(222), temp, hours); // %s %d hours
- if (minutes < 2)
- sprintf(temp, msg_txt(223), temp1, minutes); // %s %d minute
- else
- sprintf(temp, msg_txt(224), temp1, minutes); // %s %d minutes
- if (seconds == 1)
- sprintf(temp1, msg_txt(225), temp, seconds); // %s and %d second
- else if (seconds > 1)
- sprintf(temp1, msg_txt(226), temp, seconds); // %s and %d seconds
+ if (days == 1)
+ sprintf(temp, msg_txt(219), days); // %d day
+ else if (days > 1)
+ sprintf(temp, msg_txt(220), days); // %d days
+ if (hours == 1)
+ sprintf(temp1, msg_txt(221), temp, hours); // %s %d hour
+ else if (hours > 1)
+ sprintf(temp1, msg_txt(222), temp, hours); // %s %d hours
+ if (minutes < 2)
+ sprintf(temp, msg_txt(223), temp1, minutes); // %s %d minute
+ else
+ sprintf(temp, msg_txt(224), temp1, minutes); // %s %d minutes
+ if (seconds == 1)
+ sprintf(temp1, msg_txt(225), temp, seconds); // %s and %d second
+ else if (seconds > 1)
+ sprintf(temp1, msg_txt(226), temp, seconds); // %s and %d seconds
- return temp1;
+ return temp1;
}
/*==========================================
@@ -4374,99 +4521,99 @@ char *txt_time(unsigned int duration)
*------------------------------------------*/
ACMD_FUNC(servertime)
{
- const struct TimerData *timer_data;
- const struct TimerData *timer_data2;
- 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[CHAT_SIZE_MAX];
- nullpo_retr(-1, sd);
-
- memset(temp, '\0', sizeof(temp));
-
- time(&time_server); // get time in seconds since 1/1/1970
- datetime = localtime(&time_server); // convert seconds in structure
- // like sprintf, but only for date/time (Sunday, November 02 2003 15:12:52)
- strftime(temp, sizeof(temp)-1, msg_txt(230), datetime); // Server time (normal time): %A, %B %d %Y %X.
- clif_displaymessage(fd, temp);
-
- if (battle_config.night_duration == 0 && battle_config.day_duration == 0) {
- if (night_flag == 0)
- clif_displaymessage(fd, msg_txt(231)); // Game time: The game is in permanent daylight.
- else
- clif_displaymessage(fd, msg_txt(232)); // Game time: The game is in permanent night.
- } else if (battle_config.night_duration == 0)
- if (night_flag == 1) { // we start with night
- timer_data = get_timer(day_timer_tid);
- sprintf(temp, msg_txt(233), txt_time(DIFF_TICK(timer_data->tick,gettick())/1000)); // Game time: The game is actualy in night for %s.
- clif_displaymessage(fd, temp);
- clif_displaymessage(fd, msg_txt(234)); // Game time: After, the game will be in permanent daylight.
- } else
- clif_displaymessage(fd, msg_txt(231)); // Game time: The game is in permanent daylight.
- else if (battle_config.day_duration == 0)
- if (night_flag == 0) { // we start with day
- timer_data = get_timer(night_timer_tid);
- sprintf(temp, msg_txt(235), txt_time(DIFF_TICK(timer_data->tick,gettick())/1000)); // Game time: The game is actualy in daylight for %s.
- clif_displaymessage(fd, temp);
- clif_displaymessage(fd, msg_txt(236)); // Game time: After, the game will be in permanent night.
- } else
- clif_displaymessage(fd, msg_txt(232)); // Game time: The game is in permanent night.
- else {
- if (night_flag == 0) {
- timer_data = get_timer(night_timer_tid);
- timer_data2 = get_timer(day_timer_tid);
- sprintf(temp, msg_txt(235), txt_time(DIFF_TICK(timer_data->tick,gettick())/1000)); // Game time: The game is actualy in daylight for %s.
- clif_displaymessage(fd, temp);
- if (DIFF_TICK(timer_data->tick, timer_data2->tick) > 0)
- sprintf(temp, msg_txt(237), txt_time(DIFF_TICK(timer_data->interval,DIFF_TICK(timer_data->tick,timer_data2->tick)) / 1000)); // Game time: After, the game will be in night for %s.
- else
- sprintf(temp, msg_txt(237), txt_time(DIFF_TICK(timer_data2->tick,timer_data->tick)/1000)); // Game time: After, the game will be in night for %s.
- clif_displaymessage(fd, temp);
- sprintf(temp, msg_txt(238), txt_time(timer_data->interval / 1000)); // Game time: A day cycle has a normal duration of %s.
- clif_displaymessage(fd, temp);
- } else {
- timer_data = get_timer(day_timer_tid);
- timer_data2 = get_timer(night_timer_tid);
- sprintf(temp, msg_txt(233), txt_time(DIFF_TICK(timer_data->tick,gettick()) / 1000)); // Game time: The game is actualy in night for %s.
- clif_displaymessage(fd, temp);
- if (DIFF_TICK(timer_data->tick,timer_data2->tick) > 0)
- sprintf(temp, msg_txt(239), txt_time((timer_data->interval - DIFF_TICK(timer_data->tick, timer_data2->tick)) / 1000)); // Game time: After, the game will be in daylight for %s.
- else
- sprintf(temp, msg_txt(239), txt_time(DIFF_TICK(timer_data2->tick, timer_data->tick) / 1000)); // Game time: After, the game will be in daylight for %s.
- clif_displaymessage(fd, temp);
- sprintf(temp, msg_txt(238), txt_time(timer_data->interval / 1000)); // Game time: A day cycle has a normal duration of %s.
- clif_displaymessage(fd, temp);
- }
- }
-
- return 0;
+ const struct TimerData * timer_data;
+ const struct TimerData * timer_data2;
+ 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[CHAT_SIZE_MAX];
+ nullpo_retr(-1, sd);
+
+ memset(temp, '\0', sizeof(temp));
+
+ time(&time_server); // get time in seconds since 1/1/1970
+ datetime = localtime(&time_server); // convert seconds in structure
+ // like sprintf, but only for date/time (Sunday, November 02 2003 15:12:52)
+ strftime(temp, sizeof(temp)-1, msg_txt(230), datetime); // Server time (normal time): %A, %B %d %Y %X.
+ clif_displaymessage(fd, temp);
+
+ if (battle_config.night_duration == 0 && battle_config.day_duration == 0) {
+ if (night_flag == 0)
+ clif_displaymessage(fd, msg_txt(231)); // Game time: The game is in permanent daylight.
+ else
+ clif_displaymessage(fd, msg_txt(232)); // Game time: The game is in permanent night.
+ } else if (battle_config.night_duration == 0)
+ if (night_flag == 1) { // we start with night
+ timer_data = get_timer(day_timer_tid);
+ sprintf(temp, msg_txt(233), txt_time(DIFF_TICK(timer_data->tick,gettick())/1000)); // Game time: The game is actualy in night for %s.
+ clif_displaymessage(fd, temp);
+ clif_displaymessage(fd, msg_txt(234)); // Game time: After, the game will be in permanent daylight.
+ } else
+ clif_displaymessage(fd, msg_txt(231)); // Game time: The game is in permanent daylight.
+ else if (battle_config.day_duration == 0)
+ if (night_flag == 0) { // we start with day
+ timer_data = get_timer(night_timer_tid);
+ sprintf(temp, msg_txt(235), txt_time(DIFF_TICK(timer_data->tick,gettick())/1000)); // Game time: The game is actualy in daylight for %s.
+ clif_displaymessage(fd, temp);
+ clif_displaymessage(fd, msg_txt(236)); // Game time: After, the game will be in permanent night.
+ } else
+ clif_displaymessage(fd, msg_txt(232)); // Game time: The game is in permanent night.
+ else {
+ if (night_flag == 0) {
+ timer_data = get_timer(night_timer_tid);
+ timer_data2 = get_timer(day_timer_tid);
+ sprintf(temp, msg_txt(235), txt_time(DIFF_TICK(timer_data->tick,gettick())/1000)); // Game time: The game is actualy in daylight for %s.
+ clif_displaymessage(fd, temp);
+ if (DIFF_TICK(timer_data->tick, timer_data2->tick) > 0)
+ sprintf(temp, msg_txt(237), txt_time(DIFF_TICK(timer_data->interval,DIFF_TICK(timer_data->tick,timer_data2->tick)) / 1000)); // Game time: After, the game will be in night for %s.
+ else
+ sprintf(temp, msg_txt(237), txt_time(DIFF_TICK(timer_data2->tick,timer_data->tick)/1000)); // Game time: After, the game will be in night for %s.
+ clif_displaymessage(fd, temp);
+ sprintf(temp, msg_txt(238), txt_time(timer_data->interval / 1000)); // Game time: A day cycle has a normal duration of %s.
+ clif_displaymessage(fd, temp);
+ } else {
+ timer_data = get_timer(day_timer_tid);
+ timer_data2 = get_timer(night_timer_tid);
+ sprintf(temp, msg_txt(233), txt_time(DIFF_TICK(timer_data->tick,gettick()) / 1000)); // Game time: The game is actualy in night for %s.
+ clif_displaymessage(fd, temp);
+ if (DIFF_TICK(timer_data->tick,timer_data2->tick) > 0)
+ sprintf(temp, msg_txt(239), txt_time((timer_data->interval - DIFF_TICK(timer_data->tick, timer_data2->tick)) / 1000)); // Game time: After, the game will be in daylight for %s.
+ else
+ sprintf(temp, msg_txt(239), txt_time(DIFF_TICK(timer_data2->tick, timer_data->tick) / 1000)); // Game time: After, the game will be in daylight for %s.
+ clif_displaymessage(fd, temp);
+ sprintf(temp, msg_txt(238), txt_time(timer_data->interval / 1000)); // Game time: A day cycle has a normal duration of %s.
+ clif_displaymessage(fd, temp);
+ }
+ }
+
+ return 0;
}
//Added by Coltaro
//We're using this function here instead of using time_t so that it only counts player's jail time when he/she's online (and since the idea is to reduce the amount of minutes one by one in status_change_timer...).
//Well, using time_t could still work but for some reason that looks like more coding x_x
-static void get_jail_time(int jailtime, int *year, int *month, int *day, int *hour, int *minute)
+static void get_jail_time(int jailtime, int* year, int* month, int* day, int* hour, int* minute)
{
- const int factor_year = 518400; //12*30*24*60 = 518400
- const int factor_month = 43200; //30*24*60 = 43200
- const int factor_day = 1440; //24*60 = 1440
- const int factor_hour = 60;
+ const int factor_year = 518400; //12*30*24*60 = 518400
+ const int factor_month = 43200; //30*24*60 = 43200
+ const int factor_day = 1440; //24*60 = 1440
+ const int factor_hour = 60;
- *year = jailtime/factor_year;
- jailtime -= *year*factor_year;
- *month = jailtime/factor_month;
- jailtime -= *month*factor_month;
- *day = jailtime/factor_day;
- jailtime -= *day*factor_day;
- *hour = jailtime/factor_hour;
- jailtime -= *hour*factor_hour;
- *minute = jailtime;
+ *year = jailtime/factor_year;
+ jailtime -= *year*factor_year;
+ *month = jailtime/factor_month;
+ jailtime -= *month*factor_month;
+ *day = jailtime/factor_day;
+ jailtime -= *day*factor_day;
+ *hour = jailtime/factor_hour;
+ jailtime -= *hour*factor_hour;
+ *minute = jailtime;
- *year = *year > 0? *year : 0;
- *month = *month > 0? *month : 0;
- *day = *day > 0? *day : 0;
- *hour = *hour > 0? *hour : 0;
- *minute = *minute > 0? *minute : 0;
- return;
+ *year = *year > 0? *year : 0;
+ *month = *month > 0? *month : 0;
+ *day = *day > 0? *day : 0;
+ *hour = *hour > 0? *hour : 0;
+ *minute = *minute > 0? *minute : 0;
+ return;
}
/*==========================================
@@ -4475,52 +4622,53 @@ static void get_jail_time(int jailtime, int *year, int *month, int *day, int *ho
*------------------------------------------*/
ACMD_FUNC(jail)
{
- struct map_session_data *pl_sd;
- int x, y;
- unsigned short m_index;
- nullpo_retr(-1, sd);
-
- memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
-
- if (!message || !*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) {
- clif_displaymessage(fd, msg_txt(1134)); // Please enter a player name (usage: @jail <char_name>).
- return -1;
- }
-
- if ((pl_sd = map_nick2sd(atcmd_player_name)) == NULL) {
- clif_displaymessage(fd, msg_txt(3)); // Character not found.
- return -1;
- }
-
- if (pc_get_group_level(sd) < pc_get_group_level(pl_sd)) {
- // you can jail only lower or same GM
- clif_displaymessage(fd, msg_txt(81)); // Your GM level don't authorise you to do this action on this player.
- return -1;
- }
-
- if (pl_sd->sc.data[SC_JAILED]) {
- clif_displaymessage(fd, msg_txt(118)); // Player warped in jails.
- return -1;
- }
-
- switch (rnd() % 2) { //Jail Locations
- case 0:
- m_index = mapindex_name2id(MAP_JAIL);
- x = 24;
- y = 75;
- break;
- default:
- m_index = mapindex_name2id(MAP_JAIL);
- x = 49;
- y = 75;
- break;
- }
-
- //Duration of INT_MAX to specify infinity.
- sc_start4(&pl_sd->bl,SC_JAILED,100,INT_MAX,m_index,x,y,1000);
- clif_displaymessage(pl_sd->fd, msg_txt(117)); // GM has send you in jails.
- clif_displaymessage(fd, msg_txt(118)); // Player warped in jails.
- return 0;
+ struct map_session_data *pl_sd;
+ int x, y;
+ unsigned short m_index;
+ nullpo_retr(-1, sd);
+
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
+
+ if (!message || !*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) {
+ clif_displaymessage(fd, msg_txt(1134)); // Please enter a player name (usage: @jail <char_name>).
+ return -1;
+ }
+
+ if ((pl_sd = map_nick2sd(atcmd_player_name)) == NULL) {
+ clif_displaymessage(fd, msg_txt(3)); // Character not found.
+ return -1;
+ }
+
+ if (pc_get_group_level(sd) < pc_get_group_level(pl_sd))
+ { // you can jail only lower or same GM
+ clif_displaymessage(fd, msg_txt(81)); // Your GM level don't authorise you to do this action on this player.
+ return -1;
+ }
+
+ if (pl_sd->sc.data[SC_JAILED])
+ {
+ clif_displaymessage(fd, msg_txt(118)); // Player warped in jails.
+ return -1;
+ }
+
+ switch(rnd() % 2) { //Jail Locations
+ case 0:
+ m_index = mapindex_name2id(MAP_JAIL);
+ x = 24;
+ y = 75;
+ break;
+ default:
+ m_index = mapindex_name2id(MAP_JAIL);
+ x = 49;
+ y = 75;
+ break;
+ }
+
+ //Duration of INT_MAX to specify infinity.
+ sc_start4(&pl_sd->bl,SC_JAILED,100,INT_MAX,m_index,x,y,1000);
+ clif_displaymessage(pl_sd->fd, msg_txt(117)); // GM has send you in jails.
+ clif_displaymessage(fd, msg_txt(118)); // Player warped in jails.
+ return 0;
}
/*==========================================
@@ -4529,180 +4677,180 @@ ACMD_FUNC(jail)
*------------------------------------------*/
ACMD_FUNC(unjail)
{
- struct map_session_data *pl_sd;
+ struct map_session_data *pl_sd;
- memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
- if (!message || !*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) {
- clif_displaymessage(fd, msg_txt(1135)); // Please enter a player name (usage: @unjail/@discharge <char_name>).
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) {
+ clif_displaymessage(fd, msg_txt(1135)); // Please enter a player name (usage: @unjail/@discharge <char_name>).
+ return -1;
+ }
- if ((pl_sd = map_nick2sd(atcmd_player_name)) == NULL) {
- clif_displaymessage(fd, msg_txt(3)); // Character not found.
- return -1;
- }
+ if ((pl_sd = map_nick2sd(atcmd_player_name)) == NULL) {
+ clif_displaymessage(fd, msg_txt(3)); // Character not found.
+ return -1;
+ }
- if (pc_get_group_level(sd) < pc_get_group_level(pl_sd)) { // you can jail only lower or same GM
+ if (pc_get_group_level(sd) < pc_get_group_level(pl_sd)) { // you can jail only lower or same GM
- clif_displaymessage(fd, msg_txt(81)); // Your GM level don't authorise you to do this action on this player.
- return -1;
- }
+ clif_displaymessage(fd, msg_txt(81)); // Your GM level don't authorise you to do this action on this player.
+ return -1;
+ }
- if (!pl_sd->sc.data[SC_JAILED]) {
- clif_displaymessage(fd, msg_txt(119)); // This player is not in jails.
- return -1;
- }
+ if (!pl_sd->sc.data[SC_JAILED])
+ {
+ clif_displaymessage(fd, msg_txt(119)); // This player is not in jails.
+ return -1;
+ }
- //Reset jail time to 1 sec.
- sc_start(&pl_sd->bl,SC_JAILED,100,1,1000);
- clif_displaymessage(pl_sd->fd, msg_txt(120)); // A GM has discharged you from jail.
- clif_displaymessage(fd, msg_txt(121)); // Player unjailed.
- return 0;
+ //Reset jail time to 1 sec.
+ sc_start(&pl_sd->bl,SC_JAILED,100,1,1000);
+ clif_displaymessage(pl_sd->fd, msg_txt(120)); // A GM has discharged you from jail.
+ clif_displaymessage(fd, msg_txt(121)); // Player unjailed.
+ return 0;
}
ACMD_FUNC(jailfor)
{
- struct map_session_data *pl_sd = NULL;
- int year, month, day, hour, minute, value;
- char *modif_p;
- int jailtime = 0,x,y;
- short m_index = 0;
- nullpo_retr(-1, sd);
-
- if (!message || !*message || sscanf(message, "%s %23[^\n]",atcmd_output,atcmd_player_name) < 2) {
- clif_displaymessage(fd, msg_txt(400)); //Usage: @jailfor <time> <character name>
- return -1;
- }
-
- atcmd_output[sizeof(atcmd_output)-1] = '\0';
-
- modif_p = atcmd_output;
- year = month = day = hour = minute = 0;
- while (modif_p[0] != '\0') {
- value = atoi(modif_p);
- if (value == 0)
- modif_p++;
- else {
- if (modif_p[0] == '-' || modif_p[0] == '+')
- modif_p++;
- while (modif_p[0] >= '0' && modif_p[0] <= '9')
- modif_p++;
- if (modif_p[0] == 'n') {
- minute = value;
- modif_p++;
- } else if (modif_p[0] == 'm' && modif_p[1] == 'n') {
- minute = value;
- modif_p = modif_p + 2;
- } else if (modif_p[0] == 'h') {
- hour = value;
- modif_p++;
- } else if (modif_p[0] == 'd' || modif_p[0] == 'j') {
- day = value;
- modif_p++;
- } else if (modif_p[0] == 'm') {
- month = value;
- modif_p++;
- } else if (modif_p[0] == 'y' || modif_p[0] == 'a') {
- year = value;
- modif_p++;
- } else if (modif_p[0] != '\0') {
- modif_p++;
- }
- }
- }
-
- if (year == 0 && month == 0 && day == 0 && hour == 0 && minute == 0) {
- clif_displaymessage(fd, msg_txt(1136)); // Invalid time for jail command.
- return -1;
- }
-
- if ((pl_sd = map_nick2sd(atcmd_player_name)) == NULL) {
- clif_displaymessage(fd, msg_txt(3)); // Character not found.
- return -1;
- }
-
- if (pc_get_group_level(pl_sd) > pc_get_group_level(sd)) {
- clif_displaymessage(fd, msg_txt(81)); // Your GM level don't authorise you to do this action on this player.
- return -1;
- }
-
- jailtime = year*12*30*24*60 + month*30*24*60 + day*24*60 + hour*60 + minute; //In minutes
-
- if (jailtime==0) {
- clif_displaymessage(fd, msg_txt(1136)); // Invalid time for jail command.
- return -1;
- }
-
- //Added by Coltaro
- if (pl_sd->sc.data[SC_JAILED] &&
- pl_sd->sc.data[SC_JAILED]->val1 != INT_MAX) {
- //Update the player's jail time
- jailtime += pl_sd->sc.data[SC_JAILED]->val1;
- if (jailtime <= 0) {
- jailtime = 0;
- clif_displaymessage(pl_sd->fd, msg_txt(120)); // GM has discharge you.
- clif_displaymessage(fd, msg_txt(121)); // Player unjailed
- } else {
- get_jail_time(jailtime,&year,&month,&day,&hour,&minute);
- sprintf(atcmd_output,msg_txt(402),msg_txt(1137),year,month,day,hour,minute); //%s in jail for %d years, %d months, %d days, %d hours and %d minutes
- clif_displaymessage(pl_sd->fd, atcmd_output);
- sprintf(atcmd_output,msg_txt(402),msg_txt(1138),year,month,day,hour,minute); //This player is now in jail for %d years, %d months, %d days, %d hours and %d minutes
- clif_displaymessage(fd, atcmd_output);
- }
- } else if (jailtime < 0) {
- clif_displaymessage(fd, msg_txt(1136));
- return -1;
- }
-
- //Jail locations, add more as you wish.
- switch (rnd()%2) {
- case 1: //Jail #1
- m_index = mapindex_name2id(MAP_JAIL);
- x = 49;
- y = 75;
- break;
- default: //Default Jail
- m_index = mapindex_name2id(MAP_JAIL);
- x = 24;
- y = 75;
- break;
- }
-
- sc_start4(&pl_sd->bl,SC_JAILED,100,jailtime,m_index,x,y,jailtime?60000:1000); //jailtime = 0: Time was reset to 0. Wait 1 second to warp player out (since it's done in status_change_timer).
- return 0;
+ struct map_session_data *pl_sd = NULL;
+ int year, month, day, hour, minute, value;
+ char * modif_p;
+ int jailtime = 0,x,y;
+ short m_index = 0;
+ nullpo_retr(-1, sd);
+
+ if (!message || !*message || sscanf(message, "%s %23[^\n]",atcmd_output,atcmd_player_name) < 2) {
+ clif_displaymessage(fd, msg_txt(400)); //Usage: @jailfor <time> <character name>
+ return -1;
+ }
+
+ atcmd_output[sizeof(atcmd_output)-1] = '\0';
+
+ modif_p = atcmd_output;
+ year = month = day = hour = minute = 0;
+ while (modif_p[0] != '\0') {
+ value = atoi(modif_p);
+ if (value == 0)
+ modif_p++;
+ else {
+ if (modif_p[0] == '-' || modif_p[0] == '+')
+ modif_p++;
+ while (modif_p[0] >= '0' && modif_p[0] <= '9')
+ modif_p++;
+ if (modif_p[0] == 'n') {
+ minute = value;
+ modif_p++;
+ } else if (modif_p[0] == 'm' && modif_p[1] == 'n') {
+ minute = value;
+ modif_p = modif_p + 2;
+ } else if (modif_p[0] == 'h') {
+ hour = value;
+ modif_p++;
+ } else if (modif_p[0] == 'd' || modif_p[0] == 'j') {
+ day = value;
+ modif_p++;
+ } else if (modif_p[0] == 'm') {
+ month = value;
+ modif_p++;
+ } else if (modif_p[0] == 'y' || modif_p[0] == 'a') {
+ year = value;
+ modif_p++;
+ } else if (modif_p[0] != '\0') {
+ modif_p++;
+ }
+ }
+ }
+
+ if (year == 0 && month == 0 && day == 0 && hour == 0 && minute == 0) {
+ clif_displaymessage(fd, msg_txt(1136)); // Invalid time for jail command.
+ return -1;
+ }
+
+ if ((pl_sd = map_nick2sd(atcmd_player_name)) == NULL) {
+ clif_displaymessage(fd, msg_txt(3)); // Character not found.
+ return -1;
+ }
+
+ if (pc_get_group_level(pl_sd) > pc_get_group_level(sd)) {
+ clif_displaymessage(fd, msg_txt(81)); // Your GM level don't authorise you to do this action on this player.
+ return -1;
+ }
+
+ jailtime = year*12*30*24*60 + month*30*24*60 + day*24*60 + hour*60 + minute; //In minutes
+
+ if(jailtime==0) {
+ clif_displaymessage(fd, msg_txt(1136)); // Invalid time for jail command.
+ return -1;
+ }
+
+ //Added by Coltaro
+ if(pl_sd->sc.data[SC_JAILED] &&
+ pl_sd->sc.data[SC_JAILED]->val1 != INT_MAX)
+ { //Update the player's jail time
+ jailtime += pl_sd->sc.data[SC_JAILED]->val1;
+ if (jailtime <= 0) {
+ jailtime = 0;
+ clif_displaymessage(pl_sd->fd, msg_txt(120)); // GM has discharge you.
+ clif_displaymessage(fd, msg_txt(121)); // Player unjailed
+ } else {
+ get_jail_time(jailtime,&year,&month,&day,&hour,&minute);
+ sprintf(atcmd_output,msg_txt(402),msg_txt(1137),year,month,day,hour,minute); //%s in jail for %d years, %d months, %d days, %d hours and %d minutes
+ clif_displaymessage(pl_sd->fd, atcmd_output);
+ sprintf(atcmd_output,msg_txt(402),msg_txt(1138),year,month,day,hour,minute); //This player is now in jail for %d years, %d months, %d days, %d hours and %d minutes
+ clif_displaymessage(fd, atcmd_output);
+ }
+ } else if (jailtime < 0) {
+ clif_displaymessage(fd, msg_txt(1136));
+ return -1;
+ }
+
+ //Jail locations, add more as you wish.
+ switch(rnd()%2)
+ {
+ case 1: //Jail #1
+ m_index = mapindex_name2id(MAP_JAIL);
+ x = 49; y = 75;
+ break;
+ default: //Default Jail
+ m_index = mapindex_name2id(MAP_JAIL);
+ x = 24; y = 75;
+ break;
+ }
+
+ sc_start4(&pl_sd->bl,SC_JAILED,100,jailtime,m_index,x,y,jailtime?60000:1000); //jailtime = 0: Time was reset to 0. Wait 1 second to warp player out (since it's done in status_change_timer).
+ return 0;
}
//By Coltaro
ACMD_FUNC(jailtime)
{
- int year, month, day, hour, minute;
+ int year, month, day, hour, minute;
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- if (!sd->sc.data[SC_JAILED]) {
- clif_displaymessage(fd, msg_txt(1139)); // You are not in jail.
- return -1;
- }
+ if (!sd->sc.data[SC_JAILED]) {
+ clif_displaymessage(fd, msg_txt(1139)); // You are not in jail.
+ return -1;
+ }
- if (sd->sc.data[SC_JAILED]->val1 == INT_MAX) {
- clif_displaymessage(fd, msg_txt(1140)); // You have been jailed indefinitely.
- return 0;
- }
+ if (sd->sc.data[SC_JAILED]->val1 == INT_MAX) {
+ clif_displaymessage(fd, msg_txt(1140)); // You have been jailed indefinitely.
+ return 0;
+ }
- if (sd->sc.data[SC_JAILED]->val1 <= 0) { // Was not jailed with @jailfor (maybe @jail? or warped there? or got recalled?)
- clif_displaymessage(fd, msg_txt(1141)); // You have been jailed for an unknown amount of time.
- return -1;
- }
+ if (sd->sc.data[SC_JAILED]->val1 <= 0) { // Was not jailed with @jailfor (maybe @jail? or warped there? or got recalled?)
+ clif_displaymessage(fd, msg_txt(1141)); // You have been jailed for an unknown amount of time.
+ return -1;
+ }
- //Get remaining jail time
- get_jail_time(sd->sc.data[SC_JAILED]->val1,&year,&month,&day,&hour,&minute);
- sprintf(atcmd_output,msg_txt(402),msg_txt(1142),year,month,day,hour,minute); // You will remain in jail for %d years, %d months, %d days, %d hours and %d minutes
+ //Get remaining jail time
+ get_jail_time(sd->sc.data[SC_JAILED]->val1,&year,&month,&day,&hour,&minute);
+ sprintf(atcmd_output,msg_txt(402),msg_txt(1142),year,month,day,hour,minute); // You will remain in jail for %d years, %d months, %d days, %d hours and %d minutes
- clif_displaymessage(fd, atcmd_output);
+ clif_displaymessage(fd, atcmd_output);
- return 0;
+ return 0;
}
/*==========================================
@@ -4710,40 +4858,43 @@ ACMD_FUNC(jailtime)
*------------------------------------------*/
ACMD_FUNC(disguise)
{
- int id = 0;
- nullpo_retr(-1, sd);
+ int id = 0;
+ nullpo_retr(-1, sd);
- if (!message || !*message) {
- clif_displaymessage(fd, msg_txt(1143)); // Please enter a Monster/NPC name/ID (usage: @disguise <name/ID>).
- return -1;
- }
+ if (!message || !*message) {
+ clif_displaymessage(fd, msg_txt(1143)); // Please enter a Monster/NPC name/ID (usage: @disguise <name/ID>).
+ return -1;
+ }
- if ((id = atoi(message)) > 0) {
- //Acquired an ID
- if (!mobdb_checkid(id) && !npcdb_checkid(id))
- id = 0; //Invalid id for either mobs or npcs.
- } else { //Acquired a Name
- if ((id = mobdb_searchname(message)) == 0) {
- struct npc_data *nd = npc_name2id(message);
- if (nd != NULL)
- id = nd->class_;
- }
- }
+ if ((id = atoi(message)) > 0)
+ { //Acquired an ID
+ if (!mobdb_checkid(id) && !npcdb_checkid(id))
+ id = 0; //Invalid id for either mobs or npcs.
+ } else { //Acquired a Name
+ if ((id = mobdb_searchname(message)) == 0)
+ {
+ struct npc_data* nd = npc_name2id(message);
+ if (nd != NULL)
+ id = nd->class_;
+ }
+ }
- if (id == 0) {
- clif_displaymessage(fd, msg_txt(123)); // Invalid Monster/NPC name/ID specified.
- return -1;
- }
+ if (id == 0)
+ {
+ clif_displaymessage(fd, msg_txt(123)); // Invalid Monster/NPC name/ID specified.
+ return -1;
+ }
- if (pc_isriding(sd)) {
- clif_displaymessage(fd, msg_txt(1144)); // Character cannot be disguised while mounted.
- return -1;
- }
+ if(pc_isriding(sd))
+ {
+ clif_displaymessage(fd, msg_txt(1144)); // Character cannot be disguised while mounted.
+ return -1;
+ }
- pc_disguise(sd, id);
- clif_displaymessage(fd, msg_txt(122)); // Disguise applied.
+ pc_disguise(sd, id);
+ clif_displaymessage(fd, msg_txt(122)); // Disguise applied.
- return 0;
+ return 0;
}
/*==========================================
@@ -4751,31 +4902,31 @@ ACMD_FUNC(disguise)
*------------------------------------------*/
ACMD_FUNC(disguiseall)
{
- int mob_id=0;
- struct map_session_data *pl_sd;
- struct s_mapiterator *iter;
- nullpo_retr(-1, sd);
+ int mob_id=0;
+ struct map_session_data *pl_sd;
+ struct s_mapiterator* iter;
+ nullpo_retr(-1, sd);
- if (!message || !*message) {
- clif_displaymessage(fd, msg_txt(1145)); // Please enter a Monster/NPC name/ID (usage: @disguiseall <name/ID>).
- return -1;
- }
+ if (!message || !*message) {
+ clif_displaymessage(fd, msg_txt(1145)); // Please enter a Monster/NPC name/ID (usage: @disguiseall <name/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 = mobdb_searchname(message)) == 0) // check name first (to avoid possible name begining by a number)
+ mob_id = atoi(message);
- if (!mobdb_checkid(mob_id) && !npcdb_checkid(mob_id)) { //if mob or npc...
- clif_displaymessage(fd, msg_txt(123)); // Monster/NPC name/id not found.
- return -1;
- }
+ if (!mobdb_checkid(mob_id) && !npcdb_checkid(mob_id)) { //if mob or npc...
+ clif_displaymessage(fd, msg_txt(123)); // Monster/NPC name/id not found.
+ return -1;
+ }
- iter = mapit_getallusers();
- for (pl_sd = (TBL_PC *)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC *)mapit_next(iter))
- pc_disguise(pl_sd, mob_id);
- mapit_free(iter);
+ iter = mapit_getallusers();
+ for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
+ pc_disguise(pl_sd, mob_id);
+ mapit_free(iter);
- clif_displaymessage(fd, msg_txt(122)); // Disguise applied.
- return 0;
+ clif_displaymessage(fd, msg_txt(122)); // Disguise applied.
+ return 0;
}
/*==========================================
@@ -4783,46 +4934,46 @@ ACMD_FUNC(disguiseall)
*------------------------------------------*/
ACMD_FUNC(disguiseguild)
{
- int id = 0, i;
- char monster[NAME_LENGTH], guild[NAME_LENGTH];
- struct map_session_data *pl_sd;
- struct guild *g;
+ int id = 0, i;
+ char monster[NAME_LENGTH], guild[NAME_LENGTH];
+ struct map_session_data *pl_sd;
+ struct guild *g;
- memset(monster, '\0', sizeof(monster));
- memset(guild, '\0', sizeof(guild));
+ memset(monster, '\0', sizeof(monster));
+ memset(guild, '\0', sizeof(guild));
- if (!message || !*message || sscanf(message, "%23[^,], %23[^\r\n]", monster, guild) < 2) {
- clif_displaymessage(fd, msg_txt(1146)); // Please enter a mob name/ID and guild name/ID (usage: @disguiseguild <mob name/ID>, <guild name/ID>).
- return -1;
- }
+ if( !message || !*message || sscanf(message, "%23[^,], %23[^\r\n]", monster, guild) < 2 ) {
+ clif_displaymessage(fd, msg_txt(1146)); // Please enter a mob name/ID and guild name/ID (usage: @disguiseguild <mob name/ID>, <guild name/ID>).
+ return -1;
+ }
- if ((id = atoi(monster)) > 0) {
- if (!mobdb_checkid(id) && !npcdb_checkid(id))
- id = 0;
- } else {
- if ((id = mobdb_searchname(monster)) == 0) {
- struct npc_data *nd = npc_name2id(monster);
- if (nd != NULL)
- id = nd->class_;
- }
- }
+ if( (id = atoi(monster)) > 0 ) {
+ if( !mobdb_checkid(id) && !npcdb_checkid(id) )
+ id = 0;
+ } else {
+ if( (id = mobdb_searchname(monster)) == 0 ) {
+ struct npc_data* nd = npc_name2id(monster);
+ if( nd != NULL )
+ id = nd->class_;
+ }
+ }
- if (id == 0) {
- clif_displaymessage(fd, msg_txt(123)); // Monster/NPC name/id hasn't been found.
- return -1;
- }
+ if( id == 0 ) {
+ clif_displaymessage(fd, msg_txt(123)); // Monster/NPC name/id hasn't been found.
+ return -1;
+ }
- if ((g = guild_searchname(guild)) == NULL && (g = guild_search(atoi(guild))) == NULL) {
- clif_displaymessage(fd, msg_txt(94)); // Incorrect name/ID, or no one from the guild is online.
- return -1;
- }
+ if( (g = guild_searchname(guild)) == NULL && (g = guild_search(atoi(guild))) == NULL ) {
+ clif_displaymessage(fd, msg_txt(94)); // Incorrect name/ID, or no one from the guild is online.
+ return -1;
+ }
- for (i = 0; i < g->max_member; i++)
- if ((pl_sd = g->member[i].sd) && !pc_isriding(pl_sd))
- pc_disguise(pl_sd, id);
+ for( i = 0; i < g->max_member; i++ )
+ if( (pl_sd = g->member[i].sd) && !pc_isriding(pl_sd) )
+ pc_disguise(pl_sd, id);
- clif_displaymessage(fd, msg_txt(122)); // Disguise applied.
- return 0;
+ clif_displaymessage(fd, msg_txt(122)); // Disguise applied.
+ return 0;
}
@@ -4831,16 +4982,16 @@ ACMD_FUNC(disguiseguild)
*------------------------------------------*/
ACMD_FUNC(undisguise)
{
- nullpo_retr(-1, sd);
- if (sd->disguise) {
- pc_disguise(sd, 0);
- clif_displaymessage(fd, msg_txt(124)); // Undisguise applied.
- } else {
- clif_displaymessage(fd, msg_txt(125)); // You're not disguised.
- return -1;
- }
+ nullpo_retr(-1, sd);
+ if (sd->disguise) {
+ pc_disguise(sd, 0);
+ clif_displaymessage(fd, msg_txt(124)); // Undisguise applied.
+ } else {
+ clif_displaymessage(fd, msg_txt(125)); // You're not disguised.
+ return -1;
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -4848,19 +4999,19 @@ ACMD_FUNC(undisguise)
*------------------------------------------*/
ACMD_FUNC(undisguiseall)
{
- struct map_session_data *pl_sd;
- struct s_mapiterator *iter;
- nullpo_retr(-1, sd);
+ struct map_session_data *pl_sd;
+ struct s_mapiterator* iter;
+ nullpo_retr(-1, sd);
- iter = mapit_getallusers();
- for (pl_sd = (TBL_PC *)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC *)mapit_next(iter))
- if (pl_sd->disguise)
- pc_disguise(pl_sd, 0);
- mapit_free(iter);
+ iter = mapit_getallusers();
+ for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
+ if( pl_sd->disguise )
+ pc_disguise(pl_sd, 0);
+ mapit_free(iter);
- clif_displaymessage(fd, msg_txt(124)); // Undisguise applied.
+ clif_displaymessage(fd, msg_txt(124)); // Undisguise applied.
- return 0;
+ return 0;
}
/*==========================================
@@ -4868,31 +5019,31 @@ ACMD_FUNC(undisguiseall)
*------------------------------------------*/
ACMD_FUNC(undisguiseguild)
{
- char guild_name[NAME_LENGTH];
- struct map_session_data *pl_sd;
- struct guild *g;
- int i;
- nullpo_retr(-1, sd);
+ char guild_name[NAME_LENGTH];
+ struct map_session_data *pl_sd;
+ struct guild *g;
+ int i;
+ nullpo_retr(-1, sd);
- memset(guild_name, '\0', sizeof(guild_name));
+ memset(guild_name, '\0', sizeof(guild_name));
- if (!message || !*message || sscanf(message, "%23[^\n]", guild_name) < 1) {
- clif_displaymessage(fd, msg_txt(1147)); // Please enter guild name/ID (usage: @undisguiseguild <guild name/ID>).
- return -1;
- }
+ if(!message || !*message || sscanf(message, "%23[^\n]", guild_name) < 1) {
+ clif_displaymessage(fd, msg_txt(1147)); // Please enter guild name/ID (usage: @undisguiseguild <guild name/ID>).
+ return -1;
+ }
- if ((g = guild_searchname(guild_name)) == NULL && (g = guild_search(atoi(message))) == NULL) {
- clif_displaymessage(fd, msg_txt(94)); // Incorrect name/ID, or no one from the guild is online.
- return -1;
- }
+ if( (g = guild_searchname(guild_name)) == NULL && (g = guild_search(atoi(message))) == NULL ) {
+ clif_displaymessage(fd, msg_txt(94)); // Incorrect name/ID, or no one from the guild is online.
+ return -1;
+ }
- for (i = 0; i < g->max_member; i++)
- if ((pl_sd = g->member[i].sd) && pl_sd->disguise)
- pc_disguise(pl_sd, 0);
+ for(i = 0; i < g->max_member; i++)
+ if( (pl_sd = g->member[i].sd) && pl_sd->disguise )
+ pc_disguise(pl_sd, 0);
- clif_displaymessage(fd, msg_txt(124)); // Undisguise applied.
+ clif_displaymessage(fd, msg_txt(124)); // Undisguise applied.
- return 0;
+ return 0;
}
/*==========================================
@@ -4900,22 +5051,22 @@ ACMD_FUNC(undisguiseguild)
*------------------------------------------*/
ACMD_FUNC(exp)
{
- char output[CHAT_SIZE_MAX];
- double nextb, nextj;
- nullpo_retr(-1, sd);
- memset(output, '\0', sizeof(output));
+ char output[CHAT_SIZE_MAX];
+ double nextb, nextj;
+ nullpo_retr(-1, sd);
+ memset(output, '\0', sizeof(output));
- nextb = pc_nextbaseexp(sd);
- if (nextb)
- nextb = sd->status.base_exp*100.0/nextb;
+ nextb = pc_nextbaseexp(sd);
+ if (nextb)
+ nextb = sd->status.base_exp*100.0/nextb;
- nextj = pc_nextjobexp(sd);
- if (nextj)
- nextj = sd->status.job_exp*100.0/nextj;
+ nextj = pc_nextjobexp(sd);
+ if (nextj)
+ nextj = sd->status.job_exp*100.0/nextj;
- sprintf(output, msg_txt(1148), sd->status.base_level, nextb, sd->status.job_level, nextj); // Base Level: %d (%.3f%%) | Job Level: %d (%.3f%%)
- clif_displaymessage(fd, output);
- return 0;
+ sprintf(output, msg_txt(1148), sd->status.base_level, nextb, sd->status.job_level, nextj); // Base Level: %d (%.3f%%) | Job Level: %d (%.3f%%)
+ clif_displaymessage(fd, output);
+ return 0;
}
@@ -4924,19 +5075,19 @@ ACMD_FUNC(exp)
*------------------------------------------*/
ACMD_FUNC(broadcast)
{
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- memset(atcmd_output, '\0', sizeof(atcmd_output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
- if (!message || !*message) {
- clif_displaymessage(fd, msg_txt(1149)); // Please enter a message (usage: @broadcast <message>).
- return -1;
- }
+ if (!message || !*message) {
+ clif_displaymessage(fd, msg_txt(1149)); // Please enter a message (usage: @broadcast <message>).
+ return -1;
+ }
- sprintf(atcmd_output, "%s: %s", sd->status.name, message);
- intif_broadcast(atcmd_output, strlen(atcmd_output) + 1, 0);
+ sprintf(atcmd_output, "%s: %s", sd->status.name, message);
+ intif_broadcast(atcmd_output, strlen(atcmd_output) + 1, 0);
- return 0;
+ return 0;
}
/*==========================================
@@ -4944,20 +5095,20 @@ ACMD_FUNC(broadcast)
*------------------------------------------*/
ACMD_FUNC(localbroadcast)
{
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- memset(atcmd_output, '\0', sizeof(atcmd_output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
- if (!message || !*message) {
- clif_displaymessage(fd, msg_txt(1150)); // Please enter a message (usage: @localbroadcast <message>).
- return -1;
- }
+ if (!message || !*message) {
+ clif_displaymessage(fd, msg_txt(1150)); // Please enter a message (usage: @localbroadcast <message>).
+ return -1;
+ }
- sprintf(atcmd_output, "%s: %s", sd->status.name, message);
+ sprintf(atcmd_output, "%s: %s", sd->status.name, message);
- clif_broadcast(&sd->bl, atcmd_output, strlen(atcmd_output) + 1, 0, ALL_SAMEMAP);
+ clif_broadcast(&sd->bl, atcmd_output, strlen(atcmd_output) + 1, 0, ALL_SAMEMAP);
- return 0;
+ return 0;
}
/*==========================================
@@ -4965,35 +5116,35 @@ ACMD_FUNC(localbroadcast)
*------------------------------------------*/
ACMD_FUNC(email)
{
- char actual_email[100];
- char new_email[100];
- nullpo_retr(-1, sd);
+ 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));
+ memset(actual_email, '\0', sizeof(actual_email));
+ memset(new_email, '\0', sizeof(new_email));
- if (!message || !*message || sscanf(message, "%99s %99s", actual_email, new_email) < 2) {
- clif_displaymessage(fd, msg_txt(1151)); // Please enter 2 emails (usage: @email <actual@email> <new@email>).
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%99s %99s", actual_email, new_email) < 2) {
+ clif_displaymessage(fd, msg_txt(1151)); // Please enter 2 emails (usage: @email <actual@email> <new@email>).
+ return -1;
+ }
- if (e_mail_check(actual_email) == 0) {
- clif_displaymessage(fd, msg_txt(144)); // Invalid actual email. If you have default e-mail, give a@a.com.
- return -1;
- } else if (e_mail_check(new_email) == 0) {
- clif_displaymessage(fd, msg_txt(145)); // Invalid new email. Please enter a real e-mail.
- return -1;
- } else if (strcmpi(new_email, "a@a.com") == 0) {
- clif_displaymessage(fd, msg_txt(146)); // New email must be a real e-mail.
- return -1;
- } else if (strcmpi(actual_email, new_email) == 0) {
- clif_displaymessage(fd, msg_txt(147)); // New email must be different of the actual e-mail.
- return -1;
- }
+ if (e_mail_check(actual_email) == 0) {
+ clif_displaymessage(fd, msg_txt(144)); // Invalid actual email. If you have default e-mail, give a@a.com.
+ return -1;
+ } else if (e_mail_check(new_email) == 0) {
+ clif_displaymessage(fd, msg_txt(145)); // Invalid new email. Please enter a real e-mail.
+ return -1;
+ } else if (strcmpi(new_email, "a@a.com") == 0) {
+ clif_displaymessage(fd, msg_txt(146)); // New email must be a real e-mail.
+ return -1;
+ } else if (strcmpi(actual_email, new_email) == 0) {
+ clif_displaymessage(fd, msg_txt(147)); // New email must be different of the actual e-mail.
+ return -1;
+ }
- chrif_changeemail(sd->status.account_id, actual_email, new_email);
- clif_displaymessage(fd, msg_txt(148)); // Information sended to login-server via char-server.
- return 0;
+ chrif_changeemail(sd->status.account_id, actual_email, new_email);
+ clif_displaymessage(fd, msg_txt(148)); // Information sended to login-server via char-server.
+ return 0;
}
/*==========================================
@@ -5001,17 +5152,17 @@ ACMD_FUNC(email)
*------------------------------------------*/
ACMD_FUNC(effect)
{
- int type = 0, flag = 0;
- nullpo_retr(-1, sd);
+ int type = 0, flag = 0;
+ nullpo_retr(-1, sd);
- if (!message || !*message || sscanf(message, "%d", &type) < 1) {
- clif_displaymessage(fd, msg_txt(1152)); // Please enter an effect number (usage: @effect <effect number>).
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%d", &type) < 1) {
+ clif_displaymessage(fd, msg_txt(1152)); // Please enter an effect number (usage: @effect <effect number>).
+ return -1;
+ }
- clif_specialeffect(&sd->bl, type, (send_target)flag);
- clif_displaymessage(fd, msg_txt(229)); // Your effect has changed.
- return 0;
+ clif_specialeffect(&sd->bl, type, (send_target)flag);
+ clif_displaymessage(fd, msg_txt(229)); // Your effect has changed.
+ return 0;
}
/*==========================================
@@ -5020,16 +5171,16 @@ ACMD_FUNC(effect)
*------------------------------------------*/
ACMD_FUNC(killer)
{
- nullpo_retr(-1, sd);
- sd->state.killer = !sd->state.killer;
+ nullpo_retr(-1, sd);
+ sd->state.killer = !sd->state.killer;
- if (sd->state.killer)
- clif_displaymessage(fd, msg_txt(241));
- else {
- clif_displaymessage(fd, msg_txt(292));
- pc_stop_attack(sd);
- }
- return 0;
+ if(sd->state.killer)
+ clif_displaymessage(fd, msg_txt(241));
+ else {
+ clif_displaymessage(fd, msg_txt(292));
+ pc_stop_attack(sd);
+ }
+ return 0;
}
/*==========================================
@@ -5038,16 +5189,16 @@ ACMD_FUNC(killer)
*------------------------------------------*/
ACMD_FUNC(killable)
{
- nullpo_retr(-1, sd);
- sd->state.killable = !sd->state.killable;
+ nullpo_retr(-1, sd);
+ sd->state.killable = !sd->state.killable;
- if (sd->state.killable)
- clif_displaymessage(fd, msg_txt(242));
- else {
- clif_displaymessage(fd, msg_txt(288));
- map_foreachinrange(atcommand_stopattack,&sd->bl, AREA_SIZE, BL_CHAR, sd->bl.id);
- }
- return 0;
+ if(sd->state.killable)
+ clif_displaymessage(fd, msg_txt(242));
+ else {
+ clif_displaymessage(fd, msg_txt(288));
+ map_foreachinrange(atcommand_stopattack,&sd->bl, AREA_SIZE, BL_CHAR, sd->bl.id);
+ }
+ return 0;
}
/*==========================================
@@ -5056,10 +5207,10 @@ ACMD_FUNC(killable)
*------------------------------------------*/
ACMD_FUNC(skillon)
{
- nullpo_retr(-1, sd);
- map[sd->bl.m].flag.noskill = 0;
- clif_displaymessage(fd, msg_txt(244));
- return 0;
+ nullpo_retr(-1, sd);
+ map[sd->bl.m].flag.noskill = 0;
+ clif_displaymessage(fd, msg_txt(244));
+ return 0;
}
/*==========================================
@@ -5068,10 +5219,10 @@ ACMD_FUNC(skillon)
*------------------------------------------*/
ACMD_FUNC(skilloff)
{
- nullpo_retr(-1, sd);
- map[sd->bl.m].flag.noskill = 1;
- clif_displaymessage(fd, msg_txt(243));
- return 0;
+ nullpo_retr(-1, sd);
+ map[sd->bl.m].flag.noskill = 1;
+ clif_displaymessage(fd, msg_txt(243));
+ return 0;
}
/*==========================================
@@ -5080,34 +5231,36 @@ ACMD_FUNC(skilloff)
*------------------------------------------*/
ACMD_FUNC(npcmove)
{
- int x = 0, y = 0, m;
- struct npc_data *nd = 0;
- nullpo_retr(-1, sd);
- memset(atcmd_player_name, '\0', sizeof atcmd_player_name);
+ int x = 0, y = 0, m;
+ struct npc_data *nd = 0;
+ nullpo_retr(-1, sd);
+ memset(atcmd_player_name, '\0', sizeof atcmd_player_name);
- if (!message || !*message || sscanf(message, "%d %d %23[^\n]", &x, &y, atcmd_player_name) < 3) {
- clif_displaymessage(fd, msg_txt(1153)); // Usage: @npcmove <X> <Y> <npc_name>
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%d %d %23[^\n]", &x, &y, atcmd_player_name) < 3) {
+ clif_displaymessage(fd, msg_txt(1153)); // Usage: @npcmove <X> <Y> <npc_name>
+ return -1;
+ }
- if ((nd = npc_name2id(atcmd_player_name)) == NULL) {
- clif_displaymessage(fd, msg_txt(111)); // This NPC doesn't exist.
- return -1;
- }
+ if ((nd = npc_name2id(atcmd_player_name)) == NULL)
+ {
+ clif_displaymessage(fd, msg_txt(111)); // This NPC doesn't exist.
+ return -1;
+ }
- if ((m=nd->bl.m) < 0 || nd->bl.prev == NULL) {
- clif_displaymessage(fd, msg_txt(1154)); // NPC is not on this map.
- return -1; //Not on a map.
- }
+ if ((m=nd->bl.m) < 0 || nd->bl.prev == NULL)
+ {
+ clif_displaymessage(fd, msg_txt(1154)); // NPC is not on this map.
+ return -1; //Not on a map.
+ }
- x = cap_value(x, 0, map[m].xs-1);
- y = cap_value(y, 0, map[m].ys-1);
- map_foreachinrange(clif_outsight, &nd->bl, AREA_SIZE, BL_PC, &nd->bl);
- map_moveblock(&nd->bl, x, y, gettick());
- map_foreachinrange(clif_insight, &nd->bl, AREA_SIZE, BL_PC, &nd->bl);
- clif_displaymessage(fd, msg_txt(1155)); // NPC moved.
+ x = cap_value(x, 0, map[m].xs-1);
+ y = cap_value(y, 0, map[m].ys-1);
+ map_foreachinrange(clif_outsight, &nd->bl, AREA_SIZE, BL_PC, &nd->bl);
+ map_moveblock(&nd->bl, x, y, gettick());
+ map_foreachinrange(clif_insight, &nd->bl, AREA_SIZE, BL_PC, &nd->bl);
+ clif_displaymessage(fd, msg_txt(1155)); // NPC moved.
- return 0;
+ return 0;
}
/*==========================================
@@ -5116,33 +5269,34 @@ ACMD_FUNC(npcmove)
*------------------------------------------*/
ACMD_FUNC(addwarp)
{
- char mapname[32], warpname[NAME_LENGTH+1];
- int x,y;
- unsigned short m;
- struct npc_data *nd;
+ char mapname[32], warpname[NAME_LENGTH+1];
+ int x,y;
+ unsigned short m;
+ struct npc_data* nd;
- nullpo_retr(-1, sd);
- memset(warpname, '\0', sizeof(warpname));
+ nullpo_retr(-1, sd);
+ memset(warpname, '\0', sizeof(warpname));
- if (!message || !*message || sscanf(message, "%31s %d %d %23[^\n]", mapname, &x, &y, warpname) < 4) {
- clif_displaymessage(fd, msg_txt(1156)); // Usage: @addwarp <mapname> <X> <Y> <npc name>
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%31s %d %d %23[^\n]", mapname, &x, &y, warpname) < 4) {
+ clif_displaymessage(fd, msg_txt(1156)); // Usage: @addwarp <mapname> <X> <Y> <npc name>
+ return -1;
+ }
- m = mapindex_name2id(mapname);
- if (m == 0) {
- sprintf(atcmd_output, msg_txt(1157), mapname); // Unknown map '%s'.
- clif_displaymessage(fd, atcmd_output);
- return -1;
- }
+ m = mapindex_name2id(mapname);
+ if( m == 0 )
+ {
+ sprintf(atcmd_output, msg_txt(1157), mapname); // Unknown map '%s'.
+ clif_displaymessage(fd, atcmd_output);
+ return -1;
+ }
- nd = npc_add_warp(warpname, sd->bl.m, sd->bl.x, sd->bl.y, 2, 2, m, x, y);
- if (nd == NULL)
- return -1;
+ nd = npc_add_warp(warpname, sd->bl.m, sd->bl.x, sd->bl.y, 2, 2, m, x, y);
+ if( nd == NULL )
+ return -1;
- sprintf(atcmd_output, msg_txt(1158), nd->exname); // New warp NPC '%s' created.
- clif_displaymessage(fd, atcmd_output);
- return 0;
+ sprintf(atcmd_output, msg_txt(1158), nd->exname); // New warp NPC '%s' created.
+ clif_displaymessage(fd, atcmd_output);
+ return 0;
}
/*==========================================
@@ -5151,32 +5305,33 @@ ACMD_FUNC(addwarp)
*------------------------------------------*/
ACMD_FUNC(follow)
{
- struct map_session_data *pl_sd = NULL;
- nullpo_retr(-1, sd);
+ struct map_session_data *pl_sd = NULL;
+ nullpo_retr(-1, sd);
- if (!message || !*message) {
- if (sd->followtarget == -1)
- return -1;
+ if (!message || !*message) {
+ if (sd->followtarget == -1)
+ return -1;
- pc_stop_following(sd);
- clif_displaymessage(fd, msg_txt(1159)); // Follow mode OFF.
- return 0;
- }
+ pc_stop_following (sd);
+ clif_displaymessage(fd, msg_txt(1159)); // Follow mode OFF.
+ return 0;
+ }
- if ((pl_sd = map_nick2sd((char *)message)) == NULL) {
- clif_displaymessage(fd, msg_txt(3)); // Character not found.
- return -1;
- }
+ if ( (pl_sd = map_nick2sd((char *)message)) == NULL )
+ {
+ clif_displaymessage(fd, msg_txt(3)); // Character not found.
+ return -1;
+ }
- if (sd->followtarget == pl_sd->bl.id) {
- pc_stop_following(sd);
- clif_displaymessage(fd, msg_txt(1159)); // Follow mode OFF.
- } else {
- pc_follow(sd, pl_sd->bl.id);
- clif_displaymessage(fd, msg_txt(1160)); // Follow mode ON.
- }
+ if (sd->followtarget == pl_sd->bl.id) {
+ pc_stop_following (sd);
+ clif_displaymessage(fd, msg_txt(1159)); // Follow mode OFF.
+ } else {
+ pc_follow(sd, pl_sd->bl.id);
+ clif_displaymessage(fd, msg_txt(1160)); // Follow mode ON.
+ }
- return 0;
+ return 0;
}
@@ -5186,16 +5341,16 @@ ACMD_FUNC(follow)
*------------------------------------------*/
ACMD_FUNC(dropall)
{
- 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, 3);
- pc_dropitem(sd, i, sd->status.inventory[i].amount);
- }
- }
- return 0;
+ 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, 3);
+ pc_dropitem(sd, i, sd->status.inventory[i].amount);
+ }
+ }
+ return 0;
}
/*==========================================
@@ -5204,28 +5359,28 @@ ACMD_FUNC(dropall)
*------------------------------------------*/
ACMD_FUNC(storeall)
{
- int i;
- nullpo_retr(-1, sd);
+ int i;
+ nullpo_retr(-1, sd);
- if (sd->state.storage_flag != 1) {
- //Open storage.
- if (storage_storageopen(sd) == 1) {
- clif_displaymessage(fd, msg_txt(1161)); // You currently cannot open your storage.
- return -1;
- }
- }
+ if (sd->state.storage_flag != 1)
+ { //Open storage.
+ if( storage_storageopen(sd) == 1 ) {
+ clif_displaymessage(fd, msg_txt(1161)); // You currently cannot open your storage.
+ return -1;
+ }
+ }
- for (i = 0; i < MAX_INVENTORY; i++) {
- if (sd->status.inventory[i].amount) {
- if (sd->status.inventory[i].equip != 0)
- pc_unequipitem(sd, i, 3);
- storage_storageadd(sd, i, sd->status.inventory[i].amount);
- }
- }
- storage_storageclose(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, 3);
+ storage_storageadd(sd, i, sd->status.inventory[i].amount);
+ }
+ }
+ storage_storageclose(sd);
- clif_displaymessage(fd, msg_txt(1162)); // All items stored.
- return 0;
+ clif_displaymessage(fd, msg_txt(1162)); // All items stored.
+ return 0;
}
/*==========================================
@@ -5234,24 +5389,26 @@ ACMD_FUNC(storeall)
*------------------------------------------*/
ACMD_FUNC(skillid)
{
- int skillen, idx;
- nullpo_retr(-1, sd);
+ int skillen, idx;
+ nullpo_retr(-1, sd);
- if (!message || !*message) {
- clif_displaymessage(fd, msg_txt(1163)); // Please enter a skill name to look up (usage: @skillid <skill name>).
- return -1;
- }
+ if (!message || !*message)
+ {
+ clif_displaymessage(fd, msg_txt(1163)); // Please enter a skill name to look up (usage: @skillid <skill name>).
+ return -1;
+ }
- skillen = strlen(message);
+ skillen = strlen(message);
- for (idx = 0; idx < MAX_SKILL_DB; idx++) {
- if (strnicmp(skill_db[idx].name, message, skillen) == 0 || strnicmp(skill_db[idx].desc, message, skillen) == 0) {
- sprintf(atcmd_output, msg_txt(1164), idx, skill_db[idx].desc); // skill %d: %s
- clif_displaymessage(fd, atcmd_output);
- }
- }
+ for (idx = 0; idx < MAX_SKILL_DB; idx++) {
+ if (strnicmp(skill_db[idx].name, message, skillen) == 0 || strnicmp(skill_db[idx].desc, message, skillen) == 0)
+ {
+ sprintf(atcmd_output, msg_txt(1164), idx, skill_db[idx].desc); // skill %d: %s
+ clif_displaymessage(fd, atcmd_output);
+ }
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -5260,40 +5417,42 @@ ACMD_FUNC(skillid)
*------------------------------------------*/
ACMD_FUNC(useskill)
{
- struct map_session_data *pl_sd = NULL;
- struct block_list *bl;
- int skillnum;
- int skilllv;
- char target[100];
- nullpo_retr(-1, sd);
+ struct map_session_data *pl_sd = NULL;
+ struct block_list *bl;
+ int skillnum;
+ int skilllv;
+ char target[100];
+ nullpo_retr(-1, sd);
- if (!message || !*message || sscanf(message, "%d %d %23[^\n]", &skillnum, &skilllv, target) != 3) {
- clif_displaymessage(fd, msg_txt(1165)); // Usage: @useskill <skill ID> <skill level> <target>
- return -1;
- }
+ if(!message || !*message || sscanf(message, "%d %d %23[^\n]", &skillnum, &skilllv, target) != 3) {
+ clif_displaymessage(fd, msg_txt(1165)); // Usage: @useskill <skill ID> <skill level> <target>
+ return -1;
+ }
- if ((pl_sd = map_nick2sd(target)) == NULL) {
- clif_displaymessage(fd, msg_txt(3)); // Character not found.
- return -1;
- }
+ if ( (pl_sd = map_nick2sd(target)) == NULL )
+ {
+ clif_displaymessage(fd, msg_txt(3)); // Character not found.
+ return -1;
+ }
- if (pc_get_group_level(sd) < pc_get_group_level(pl_sd)) {
- clif_displaymessage(fd, msg_txt(81)); // Your GM level don't authorise you to do this action on this player.
- return -1;
- }
+ if ( pc_get_group_level(sd) < pc_get_group_level(pl_sd) )
+ {
+ clif_displaymessage(fd, msg_txt(81)); // Your GM level don't authorise you to do this action on this player.
+ return -1;
+ }
- if (skillnum >= HM_SKILLBASE && skillnum < HM_SKILLBASE+MAX_HOMUNSKILL
- && sd->hd && merc_is_hom_active(sd->hd)) // (If used with @useskill, put the homunc as dest)
- bl = &sd->hd->bl;
- else
- bl = &sd->bl;
+ if (skillnum >= HM_SKILLBASE && skillnum < HM_SKILLBASE+MAX_HOMUNSKILL
+ && sd->hd && merc_is_hom_active(sd->hd)) // (If used with @useskill, put the homunc as dest)
+ bl = &sd->hd->bl;
+ else
+ bl = &sd->bl;
- if (skill_get_inf(skillnum)&INF_GROUND_SKILL)
- unit_skilluse_pos(bl, pl_sd->bl.x, pl_sd->bl.y, skillnum, skilllv);
- else
- unit_skilluse_id(bl, pl_sd->bl.id, skillnum, skilllv);
+ if (skill_get_inf(skillnum)&INF_GROUND_SKILL)
+ unit_skilluse_pos(bl, pl_sd->bl.x, pl_sd->bl.y, skillnum, skilllv);
+ else
+ unit_skilluse_id(bl, pl_sd->bl.id, skillnum, skilllv);
- return 0;
+ return 0;
}
/*==========================================
@@ -5303,22 +5462,23 @@ ACMD_FUNC(useskill)
*------------------------------------------*/
ACMD_FUNC(displayskill)
{
- struct status_data *status;
- unsigned int tick;
- int skillnum;
- int skilllv = 1;
- nullpo_retr(-1, sd);
+ struct status_data * status;
+ unsigned int tick;
+ int skillnum;
+ int skilllv = 1;
+ nullpo_retr(-1, sd);
- if (!message || !*message || sscanf(message, "%d %d", &skillnum, &skilllv) < 1) {
- clif_displaymessage(fd, msg_txt(1166)); // Usage: @displayskill <skill ID> {<skill level>}
- return -1;
- }
- status = status_get_status_data(&sd->bl);
- tick = gettick();
- clif_skill_damage(&sd->bl,&sd->bl, tick, status->amotion, status->dmotion, 1, 1, skillnum, skilllv, 5);
- clif_skill_nodamage(&sd->bl, &sd->bl, skillnum, skilllv, 1);
- clif_skill_poseffect(&sd->bl, skillnum, skilllv, sd->bl.x, sd->bl.y, tick);
- return 0;
+ if (!message || !*message || sscanf(message, "%d %d", &skillnum, &skilllv) < 1)
+ {
+ clif_displaymessage(fd, msg_txt(1166)); // Usage: @displayskill <skill ID> {<skill level>}
+ return -1;
+ }
+ status = status_get_status_data(&sd->bl);
+ tick = gettick();
+ clif_skill_damage(&sd->bl,&sd->bl, tick, status->amotion, status->dmotion, 1, 1, skillnum, skilllv, 5);
+ clif_skill_nodamage(&sd->bl, &sd->bl, skillnum, skilllv, 1);
+ clif_skill_poseffect(&sd->bl, skillnum, skilllv, sd->bl.x, sd->bl.y, tick);
+ return 0;
}
/*==========================================
@@ -5327,70 +5487,74 @@ ACMD_FUNC(displayskill)
*------------------------------------------*/
ACMD_FUNC(skilltree)
{
- struct map_session_data *pl_sd = NULL;
- int skillnum;
- int meets, j, c=0;
- char target[NAME_LENGTH];
- struct skill_tree_entry *ent;
- nullpo_retr(-1, sd);
-
- if (!message || !*message || sscanf(message, "%d %23[^\r\n]", &skillnum, target) != 2) {
- clif_displaymessage(fd, msg_txt(1167)); // Usage: @skilltree <skill ID> <target>
- return -1;
- }
-
- if ((pl_sd = map_nick2sd(target)) == NULL) {
- clif_displaymessage(fd, msg_txt(3)); // Character not found.
- return -1;
- }
-
- c = pc_calc_skilltree_normalize_job(pl_sd);
- c = pc_mapid2jobid(c, pl_sd->status.sex);
-
- sprintf(atcmd_output, msg_txt(1168), job_name(c), pc_checkskill(pl_sd, NV_BASIC)); // Player is using %s skill tree (%d basic points).
- clif_displaymessage(fd, atcmd_output);
-
- ARR_FIND(0, MAX_SKILL_TREE, j, skill_tree[c][j].id == 0 || skill_tree[c][j].id == skillnum);
- if (j == MAX_SKILL_TREE || skill_tree[c][j].id == 0) {
- clif_displaymessage(fd, msg_txt(1169)); // The player cannot use that skill.
- return 0;
- }
-
- ent = &skill_tree[c][j];
-
- meets = 1;
- for (j=0; j<MAX_PC_SKILL_REQUIRE; j++) {
- if (ent->need[j].id && pc_checkskill(sd,ent->need[j].id) < ent->need[j].lv) {
- sprintf(atcmd_output, msg_txt(1170), ent->need[j].lv, skill_db[ent->need[j].id].desc); // Player requires level %d of skill %s.
- clif_displaymessage(fd, atcmd_output);
- meets = 0;
- }
- }
- if (meets == 1) {
- clif_displaymessage(fd, msg_txt(1171)); // The player meets all the requirements for that skill.
- }
-
- return 0;
+ struct map_session_data *pl_sd = NULL;
+ int skillnum;
+ int meets, j, c=0;
+ char target[NAME_LENGTH];
+ struct skill_tree_entry *ent;
+ nullpo_retr(-1, sd);
+
+ if(!message || !*message || sscanf(message, "%d %23[^\r\n]", &skillnum, target) != 2) {
+ clif_displaymessage(fd, msg_txt(1167)); // Usage: @skilltree <skill ID> <target>
+ return -1;
+ }
+
+ if ( (pl_sd = map_nick2sd(target)) == NULL )
+ {
+ clif_displaymessage(fd, msg_txt(3)); // Character not found.
+ return -1;
+ }
+
+ c = pc_calc_skilltree_normalize_job(pl_sd);
+ c = pc_mapid2jobid(c, pl_sd->status.sex);
+
+ sprintf(atcmd_output, msg_txt(1168), job_name(c), pc_checkskill(pl_sd, NV_BASIC)); // Player is using %s skill tree (%d basic points).
+ clif_displaymessage(fd, atcmd_output);
+
+ ARR_FIND( 0, MAX_SKILL_TREE, j, skill_tree[c][j].id == 0 || skill_tree[c][j].id == skillnum );
+ if( j == MAX_SKILL_TREE || skill_tree[c][j].id == 0 )
+ {
+ clif_displaymessage(fd, msg_txt(1169)); // The player cannot use that skill.
+ return 0;
+ }
+
+ ent = &skill_tree[c][j];
+
+ meets = 1;
+ for(j=0;j<MAX_PC_SKILL_REQUIRE;j++)
+ {
+ if( ent->need[j].id && pc_checkskill(sd,ent->need[j].id) < ent->need[j].lv)
+ {
+ sprintf(atcmd_output, msg_txt(1170), ent->need[j].lv, skill_db[ent->need[j].id].desc); // Player requires level %d of skill %s.
+ clif_displaymessage(fd, atcmd_output);
+ meets = 0;
+ }
+ }
+ if (meets == 1) {
+ clif_displaymessage(fd, msg_txt(1171)); // The player meets all the requirements for that skill.
+ }
+
+ return 0;
}
// Hand a ring with partners name on it to this char
-void getring(struct map_session_data *sd)
+void getring (struct map_session_data* sd)
{
- int flag, item_id;
- struct item item_tmp;
- item_id = (sd->status.sex) ? WEDDING_RING_M : WEDDING_RING_F;
+ int flag, item_id;
+ struct item item_tmp;
+ item_id = (sd->status.sex) ? WEDDING_RING_M : WEDDING_RING_F;
- memset(&item_tmp, 0, sizeof(item_tmp));
- item_tmp.nameid = item_id;
- item_tmp.identify = 1;
- item_tmp.card[0] = 255;
- item_tmp.card[2] = sd->status.partner_id;
- item_tmp.card[3] = sd->status.partner_id >> 16;
+ memset(&item_tmp, 0, sizeof(item_tmp));
+ item_tmp.nameid = item_id;
+ item_tmp.identify = 1;
+ item_tmp.card[0] = 255;
+ item_tmp.card[2] = sd->status.partner_id;
+ item_tmp.card[3] = sd->status.partner_id >> 16;
- if ((flag = pc_additem(sd,&item_tmp,1,LOG_TYPE_COMMAND))) {
- clif_additem(sd,0,0,flag);
- map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
- }
+ if((flag = pc_additem(sd,&item_tmp,1,LOG_TYPE_COMMAND))) {
+ clif_additem(sd,0,0,flag);
+ map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ }
}
/*==========================================
@@ -5399,31 +5563,31 @@ void getring(struct map_session_data *sd)
*------------------------------------------*/
ACMD_FUNC(marry)
{
- struct map_session_data *pl_sd = NULL;
- char player_name[NAME_LENGTH] = "";
+ struct map_session_data *pl_sd = NULL;
+ char player_name[NAME_LENGTH] = "";
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- if (!message || !*message || sscanf(message, "%23s", player_name) != 1) {
- clif_displaymessage(fd, msg_txt(1172)); // Usage: @marry <char name>
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%23s", player_name) != 1) {
+ clif_displaymessage(fd, msg_txt(1172)); // Usage: @marry <char name>
+ return -1;
+ }
- if ((pl_sd = map_nick2sd(player_name)) == NULL) {
- clif_displaymessage(fd, msg_txt(3));
- return -1;
- }
+ if ((pl_sd = map_nick2sd(player_name)) == NULL) {
+ clif_displaymessage(fd, msg_txt(3));
+ return -1;
+ }
- if (pc_marriage(sd, pl_sd) == 0) {
- clif_displaymessage(fd, msg_txt(1173)); // They are married... wish them well.
- clif_wedding_effect(&pl_sd->bl); //wedding effect and music [Lupus]
- getring(sd); // Auto-give named rings (Aru)
- getring(pl_sd);
- return 0;
- }
+ if (pc_marriage(sd, pl_sd) == 0) {
+ clif_displaymessage(fd, msg_txt(1173)); // They are married... wish them well.
+ clif_wedding_effect(&pl_sd->bl); //wedding effect and music [Lupus]
+ getring(sd); // Auto-give named rings (Aru)
+ getring(pl_sd);
+ return 0;
+ }
- clif_displaymessage(fd, msg_txt(1174)); // The two cannot wed because one is either a baby or already married.
- return -1;
+ clif_displaymessage(fd, msg_txt(1174)); // The two cannot wed because one is either a baby or already married.
+ return -1;
}
/*==========================================
@@ -5432,17 +5596,17 @@ ACMD_FUNC(marry)
*------------------------------------------*/
ACMD_FUNC(divorce)
{
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- if (pc_divorce(sd) != 0) {
- sprintf(atcmd_output, msg_txt(1175), sd->status.name); // '%s' is not married.
- clif_displaymessage(fd, atcmd_output);
- return -1;
- }
+ if (pc_divorce(sd) != 0) {
+ sprintf(atcmd_output, msg_txt(1175), sd->status.name); // '%s' is not married.
+ clif_displaymessage(fd, atcmd_output);
+ return -1;
+ }
- sprintf(atcmd_output, msg_txt(1176), sd->status.name); // '%s' and his/her partner are now divorced.
- clif_displaymessage(fd, atcmd_output);
- return 0;
+ sprintf(atcmd_output, msg_txt(1176), sd->status.name); // '%s' and his/her partner are now divorced.
+ clif_displaymessage(fd, atcmd_output);
+ return 0;
}
/*==========================================
@@ -5450,25 +5614,25 @@ ACMD_FUNC(divorce)
*------------------------------------------*/
ACMD_FUNC(changelook)
{
- int i, j = 0, k = 0;
- int pos[7] = { LOOK_HEAD_TOP,LOOK_HEAD_MID,LOOK_HEAD_BOTTOM,LOOK_WEAPON,LOOK_SHIELD,LOOK_SHOES,LOOK_ROBE };
+ int i, j = 0, k = 0;
+ int pos[7] = { LOOK_HEAD_TOP,LOOK_HEAD_MID,LOOK_HEAD_BOTTOM,LOOK_WEAPON,LOOK_SHIELD,LOOK_SHOES,LOOK_ROBE };
- if ((i = sscanf(message, "%d %d", &j, &k)) < 1) {
- clif_displaymessage(fd, msg_txt(1177)); // Usage: @changelook {<position>} <view id>
- clif_displaymessage(fd, msg_txt(1178)); // Position: 1-Top 2-Middle 3-Bottom 4-Weapon 5-Shield 6-Shoes 7-Robe
- return -1;
- } else if (i == 2) {
- if (j < 1 || j > 7)
- j = 1;
- j = pos[j - 1];
- } else if (i == 1) { // position not defined, use HEAD_TOP as default
- k = j; // swap
- j = LOOK_HEAD_TOP;
- }
+ if((i = sscanf(message, "%d %d", &j, &k)) < 1) {
+ clif_displaymessage(fd, msg_txt(1177)); // Usage: @changelook {<position>} <view id>
+ clif_displaymessage(fd, msg_txt(1178)); // Position: 1-Top 2-Middle 3-Bottom 4-Weapon 5-Shield 6-Shoes 7-Robe
+ return -1;
+ } else if ( i == 2 ) {
+ if (j < 1 || j > 7)
+ j = 1;
+ 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);
+ clif_changelook(&sd->bl,j,k);
- return 0;
+ return 0;
}
/*==========================================
@@ -5477,31 +5641,32 @@ ACMD_FUNC(changelook)
*------------------------------------------*/
ACMD_FUNC(autotrade)
{
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- if (map[sd->bl.m].flag.autotrade != battle_config.autotrade_mapflag) {
- clif_displaymessage(fd, msg_txt(1179)); // Autotrade is not allowed on this map.
- return -1;
- }
+ if( map[sd->bl.m].flag.autotrade != battle_config.autotrade_mapflag ) {
+ clif_displaymessage(fd, msg_txt(1179)); // Autotrade is not allowed on this map.
+ return -1;
+ }
- if (pc_isdead(sd)) {
- clif_displaymessage(fd, msg_txt(1180)); // You cannot autotrade when dead.
- return -1;
- }
+ if( pc_isdead(sd) ) {
+ clif_displaymessage(fd, msg_txt(1180)); // You cannot autotrade when dead.
+ return -1;
+ }
- if (!sd->state.vending && !sd->state.buyingstore) { //check if player is vending or buying
- clif_displaymessage(fd, msg_txt(549)); // "You should have a shop open to use @autotrade."
- return -1;
- }
+ if( !sd->state.vending && !sd->state.buyingstore ) { //check if player is vending or buying
+ clif_displaymessage(fd, msg_txt(549)); // "You should have a shop open to use @autotrade."
+ return -1;
+ }
- sd->state.autotrade = 1;
- if (battle_config.at_timeout) {
- int timeout = atoi(message);
- status_change_start(&sd->bl, SC_AUTOTRADE, 10000, 0, 0, 0, 0, ((timeout > 0) ? min(timeout,battle_config.at_timeout) : battle_config.at_timeout) * 60000, 0);
- }
- clif_authfail_fd(fd, 15);
+ sd->state.autotrade = 1;
+ if( battle_config.at_timeout )
+ {
+ int timeout = atoi(message);
+ status_change_start(&sd->bl, SC_AUTOTRADE, 10000, 0, 0, 0, 0, ((timeout > 0) ? min(timeout,battle_config.at_timeout) : battle_config.at_timeout) * 60000, 0);
+ }
+ clif_authfail_fd(fd, 15);
- return 0;
+ return 0;
}
/*==========================================
@@ -5510,32 +5675,32 @@ ACMD_FUNC(autotrade)
*------------------------------------------*/
ACMD_FUNC(changegm)
{
- struct guild *g;
- struct map_session_data *pl_sd;
- nullpo_retr(-1, sd);
+ struct guild *g;
+ struct map_session_data *pl_sd;
+ nullpo_retr(-1, sd);
- if (sd->status.guild_id == 0 || (g = guild_search(sd->status.guild_id)) == NULL || strcmp(g->master,sd->status.name)) {
- clif_displaymessage(fd, msg_txt(1181)); // You need to be a Guild Master to use this command.
- return -1;
- }
+ if (sd->status.guild_id == 0 || (g = guild_search(sd->status.guild_id)) == NULL || strcmp(g->master,sd->status.name)) {
+ clif_displaymessage(fd, msg_txt(1181)); // You need to be a Guild Master to use this command.
+ return -1;
+ }
- if (map[sd->bl.m].flag.guildlock || map[sd->bl.m].flag.gvg_castle) {
- clif_displaymessage(fd, msg_txt(1182)); // You cannot change guild leaders on this map.
- return -1;
- }
+ if( map[sd->bl.m].flag.guildlock || map[sd->bl.m].flag.gvg_castle ) {
+ clif_displaymessage(fd, msg_txt(1182)); // You cannot change guild leaders on this map.
+ return -1;
+ }
- if (!message[0]) {
- clif_displaymessage(fd, msg_txt(1183)); // Usage: @changegm <guild_member_name>
- return -1;
- }
+ if( !message[0] ) {
+ clif_displaymessage(fd, msg_txt(1183)); // Usage: @changegm <guild_member_name>
+ return -1;
+ }
- if ((pl_sd=map_nick2sd((char *) message)) == NULL || pl_sd->status.guild_id != sd->status.guild_id) {
- clif_displaymessage(fd, msg_txt(1184)); // Target character must be online and be a guild member.
- return -1;
- }
+ if((pl_sd=map_nick2sd((char *) message)) == NULL || pl_sd->status.guild_id != sd->status.guild_id) {
+ clif_displaymessage(fd, msg_txt(1184)); // Target character must be online and be a guild member.
+ return -1;
+ }
- guild_gm_change(sd->status.guild_id, pl_sd);
- return 0;
+ guild_gm_change(sd->status.guild_id, pl_sd);
+ return 0;
}
/*==========================================
@@ -5544,16 +5709,17 @@ ACMD_FUNC(changegm)
*------------------------------------------*/
ACMD_FUNC(changeleader)
{
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- if (!message[0]) {
- clif_displaymessage(fd, msg_txt(1185)); // Usage: @changeleader <party_member_name>
- return -1;
- }
+ if( !message[0] )
+ {
+ clif_displaymessage(fd, msg_txt(1185)); // Usage: @changeleader <party_member_name>
+ return -1;
+ }
- if (party_changeleader(sd, map_nick2sd((char *) message)))
- return 0;
- return -1;
+ if (party_changeleader(sd, map_nick2sd((char *) message)))
+ return 0;
+ return -1;
}
/*==========================================
@@ -5562,39 +5728,42 @@ ACMD_FUNC(changeleader)
*------------------------------------------*/
ACMD_FUNC(partyoption)
{
- struct party_data *p;
- int mi, option;
- char w1[16], w2[16];
- nullpo_retr(-1, sd);
+ struct party_data *p;
+ int mi, option;
+ char w1[16], w2[16];
+ nullpo_retr(-1, sd);
- if (sd->status.party_id == 0 || (p = party_search(sd->status.party_id)) == NULL) {
- clif_displaymessage(fd, msg_txt(282));
- return -1;
- }
+ if (sd->status.party_id == 0 || (p = party_search(sd->status.party_id)) == NULL)
+ {
+ clif_displaymessage(fd, msg_txt(282));
+ return -1;
+ }
- ARR_FIND(0, MAX_PARTY, mi, p->data[mi].sd == sd);
- if (mi == MAX_PARTY)
- return -1; //Shouldn't happen
+ ARR_FIND( 0, MAX_PARTY, mi, p->data[mi].sd == sd );
+ if (mi == MAX_PARTY)
+ return -1; //Shouldn't happen
- if (!p->party.member[mi].leader) {
- clif_displaymessage(fd, msg_txt(282));
- return -1;
- }
+ if (!p->party.member[mi].leader)
+ {
+ clif_displaymessage(fd, msg_txt(282));
+ return -1;
+ }
- if (!message || !*message || sscanf(message, "%15s %15s", w1, w2) < 2) {
- clif_displaymessage(fd, msg_txt(1186)); // Usage: @partyoption <pickup share: yes/no> <item distribution: yes/no>
- return -1;
- }
+ if(!message || !*message || sscanf(message, "%15s %15s", w1, w2) < 2)
+ {
+ clif_displaymessage(fd, msg_txt(1186)); // Usage: @partyoption <pickup share: yes/no> <item distribution: yes/no>
+ return -1;
+ }
- option = (config_switch(w1)?1:0)|(config_switch(w2)?2:0);
+ option = (config_switch(w1)?1:0)|(config_switch(w2)?2:0);
- //Change item share type.
- if (option != p->party.item)
- party_changeoption(sd, p->party.exp, option);
- else
- clif_displaymessage(fd, msg_txt(286));
+ //Change item share type.
+ if (option != p->party.item)
+ party_changeoption(sd, p->party.exp, option);
+ else
+ clif_displaymessage(fd, msg_txt(286));
- return 0;
+ return 0;
}
/*==========================================
@@ -5603,30 +5772,31 @@ ACMD_FUNC(partyoption)
*------------------------------------------*/
ACMD_FUNC(autoloot)
{
- int rate;
- double drate;
- nullpo_retr(-1, sd);
- // autoloot command without value
- if (!message || !*message) {
- if (sd->state.autoloot)
- rate = 0;
- else
- rate = 10000;
- } else {
- drate = atof(message);
- rate = (int)(drate*100);
- }
- if (rate < 0) rate = 0;
- if (rate > 10000) rate = 10000;
-
- sd->state.autoloot = rate;
- if (sd->state.autoloot) {
- snprintf(atcmd_output, sizeof atcmd_output, msg_txt(1187),((double)sd->state.autoloot)/100.); // Autolooting items with drop rates of %0.02f%% and below.
- clif_displaymessage(fd, atcmd_output);
- } else
- clif_displaymessage(fd, msg_txt(1188)); // Autoloot is now off.
-
- return 0;
+ int rate;
+ double drate;
+ nullpo_retr(-1, sd);
+ // autoloot command without value
+ if(!message || !*message)
+ {
+ if (sd->state.autoloot)
+ rate = 0;
+ else
+ rate = 10000;
+ } else {
+ drate = atof(message);
+ rate = (int)(drate*100);
+ }
+ if (rate < 0) rate = 0;
+ if (rate > 10000) rate = 10000;
+
+ sd->state.autoloot = rate;
+ if (sd->state.autoloot) {
+ snprintf(atcmd_output, sizeof atcmd_output, msg_txt(1187),((double)sd->state.autoloot)/100.); // Autolooting items with drop rates of %0.02f%% and below.
+ clif_displaymessage(fd, atcmd_output);
+ }else
+ clif_displaymessage(fd, msg_txt(1188)); // Autoloot is now off.
+
+ return 0;
}
/*==========================================
@@ -5634,91 +5804,95 @@ ACMD_FUNC(autoloot)
*------------------------------------------*/
ACMD_FUNC(autolootitem)
{
- struct item_data *item_data = NULL;
- int i;
- int action = 3; // 1=add, 2=remove, 3=help+list (default), 4=reset
-
- if (message && *message) {
- if (message[0] == '+') {
- message++;
- action = 1;
- } else if (message[0] == '-') {
- message++;
- action = 2;
- } else if (!strcmp(message,"reset"))
- action = 4;
- }
-
- if (action < 3) { // add or remove
- if ((item_data = itemdb_exists(atoi(message))) == NULL)
- item_data = itemdb_searchname(message);
- if (!item_data) {
- // No items founds in the DB with Id or Name
- clif_displaymessage(fd, msg_txt(1189)); // Item not found.
- return -1;
- }
- }
-
- switch (action) {
- case 1:
- ARR_FIND(0, AUTOLOOTITEM_SIZE, i, sd->state.autolootid[i] == item_data->nameid);
- if (i != AUTOLOOTITEM_SIZE) {
- clif_displaymessage(fd, msg_txt(1190)); // You're already autolooting this item.
- return -1;
- }
- ARR_FIND(0, AUTOLOOTITEM_SIZE, i, sd->state.autolootid[i] == 0);
- if (i == AUTOLOOTITEM_SIZE) {
- clif_displaymessage(fd, msg_txt(1191)); // Your autolootitem list is full. Remove some items first with @autolootid -<item name or ID>.
- return -1;
- }
- sd->state.autolootid[i] = item_data->nameid; // Autoloot Activated
- sprintf(atcmd_output, msg_txt(1192), item_data->name, item_data->jname, item_data->nameid); // Autolooting item: '%s'/'%s' {%d}
- clif_displaymessage(fd, atcmd_output);
- sd->state.autolooting = 1;
- break;
- case 2:
- ARR_FIND(0, AUTOLOOTITEM_SIZE, i, sd->state.autolootid[i] == item_data->nameid);
- if (i == AUTOLOOTITEM_SIZE) {
- clif_displaymessage(fd, msg_txt(1193)); // You're currently not autolooting this item.
- return -1;
- }
- sd->state.autolootid[i] = 0;
- sprintf(atcmd_output, msg_txt(1194), item_data->name, item_data->jname, item_data->nameid); // Removed item: '%s'/'%s' {%d} from your autolootitem list.
- clif_displaymessage(fd, atcmd_output);
- ARR_FIND(0, AUTOLOOTITEM_SIZE, i, sd->state.autolootid[i] != 0);
- if (i == AUTOLOOTITEM_SIZE) {
- sd->state.autolooting = 0;
- }
- break;
- case 3:
- sprintf(atcmd_output, msg_txt(1195), AUTOLOOTITEM_SIZE); // You can have %d items on your autolootitem list.
- clif_displaymessage(fd, atcmd_output);
- clif_displaymessage(fd, msg_txt(1196)); // To add an item to the list, use "@alootid +<item name or ID>". To remove an item, use "@alootid -<item name or ID>".
- clif_displaymessage(fd, msg_txt(1197)); // "@alootid reset" will clear your autolootitem list.
- ARR_FIND(0, AUTOLOOTITEM_SIZE, i, sd->state.autolootid[i] != 0);
- if (i == AUTOLOOTITEM_SIZE) {
- clif_displaymessage(fd, msg_txt(1198)); // Your autolootitem list is empty.
- } else {
- clif_displaymessage(fd, msg_txt(1199)); // Items on your autolootitem list:
- for (i = 0; i < AUTOLOOTITEM_SIZE; i++) {
- if (sd->state.autolootid[i] == 0)
- continue;
- if (!(item_data = itemdb_exists(sd->state.autolootid[i]))) {
- ShowDebug("Non-existant item %d on autolootitem list (account_id: %d, char_id: %d)", sd->state.autolootid[i], sd->status.account_id, sd->status.char_id);
- continue;
- }
- sprintf(atcmd_output, "'%s'/'%s' {%d}", item_data->name, item_data->jname, item_data->nameid);
- clif_displaymessage(fd, atcmd_output);
- }
- }
- break;
- case 4:
- memset(sd->state.autolootid, 0, sizeof(sd->state.autolootid));
- clif_displaymessage(fd, msg_txt(1200)); // Your autolootitem list has been reset.
- sd->state.autolooting = 0;
- break;
- }
- return 0;
+ struct item_data *item_data = NULL;
+ int i;
+ int action = 3; // 1=add, 2=remove, 3=help+list (default), 4=reset
+
+ if (message && *message) {
+ if (message[0] == '+') {
+ message++;
+ action = 1;
+ }
+ else if (message[0] == '-') {
+ message++;
+ action = 2;
+ }
+ else if (!strcmp(message,"reset"))
+ action = 4;
+ }
+
+ if (action < 3) // add or remove
+ {
+ if ((item_data = itemdb_exists(atoi(message))) == NULL)
+ item_data = itemdb_searchname(message);
+ if (!item_data) {
+ // No items founds in the DB with Id or Name
+ clif_displaymessage(fd, msg_txt(1189)); // Item not found.
+ return -1;
+ }
+ }
+
+ switch(action) {
+ case 1:
+ ARR_FIND(0, AUTOLOOTITEM_SIZE, i, sd->state.autolootid[i] == item_data->nameid);
+ if (i != AUTOLOOTITEM_SIZE) {
+ clif_displaymessage(fd, msg_txt(1190)); // You're already autolooting this item.
+ return -1;
+ }
+ ARR_FIND(0, AUTOLOOTITEM_SIZE, i, sd->state.autolootid[i] == 0);
+ if (i == AUTOLOOTITEM_SIZE) {
+ clif_displaymessage(fd, msg_txt(1191)); // Your autolootitem list is full. Remove some items first with @autolootid -<item name or ID>.
+ return -1;
+ }
+ sd->state.autolootid[i] = item_data->nameid; // Autoloot Activated
+ sprintf(atcmd_output, msg_txt(1192), item_data->name, item_data->jname, item_data->nameid); // Autolooting item: '%s'/'%s' {%d}
+ clif_displaymessage(fd, atcmd_output);
+ sd->state.autolooting = 1;
+ break;
+ case 2:
+ ARR_FIND(0, AUTOLOOTITEM_SIZE, i, sd->state.autolootid[i] == item_data->nameid);
+ if (i == AUTOLOOTITEM_SIZE) {
+ clif_displaymessage(fd, msg_txt(1193)); // You're currently not autolooting this item.
+ return -1;
+ }
+ sd->state.autolootid[i] = 0;
+ sprintf(atcmd_output, msg_txt(1194), item_data->name, item_data->jname, item_data->nameid); // Removed item: '%s'/'%s' {%d} from your autolootitem list.
+ clif_displaymessage(fd, atcmd_output);
+ ARR_FIND(0, AUTOLOOTITEM_SIZE, i, sd->state.autolootid[i] != 0);
+ if (i == AUTOLOOTITEM_SIZE) {
+ sd->state.autolooting = 0;
+ }
+ break;
+ case 3:
+ sprintf(atcmd_output, msg_txt(1195), AUTOLOOTITEM_SIZE); // You can have %d items on your autolootitem list.
+ clif_displaymessage(fd, atcmd_output);
+ clif_displaymessage(fd, msg_txt(1196)); // To add an item to the list, use "@alootid +<item name or ID>". To remove an item, use "@alootid -<item name or ID>".
+ clif_displaymessage(fd, msg_txt(1197)); // "@alootid reset" will clear your autolootitem list.
+ ARR_FIND(0, AUTOLOOTITEM_SIZE, i, sd->state.autolootid[i] != 0);
+ if (i == AUTOLOOTITEM_SIZE) {
+ clif_displaymessage(fd, msg_txt(1198)); // Your autolootitem list is empty.
+ } else {
+ clif_displaymessage(fd, msg_txt(1199)); // Items on your autolootitem list:
+ for(i = 0; i < AUTOLOOTITEM_SIZE; i++)
+ {
+ if (sd->state.autolootid[i] == 0)
+ continue;
+ if (!(item_data = itemdb_exists(sd->state.autolootid[i]))) {
+ ShowDebug("Non-existant item %d on autolootitem list (account_id: %d, char_id: %d)", sd->state.autolootid[i], sd->status.account_id, sd->status.char_id);
+ continue;
+ }
+ sprintf(atcmd_output, "'%s'/'%s' {%d}", item_data->name, item_data->jname, item_data->nameid);
+ clif_displaymessage(fd, atcmd_output);
+ }
+ }
+ break;
+ case 4:
+ memset(sd->state.autolootid, 0, sizeof(sd->state.autolootid));
+ clif_displaymessage(fd, msg_txt(1200)); // Your autolootitem list has been reset.
+ sd->state.autolooting = 0;
+ break;
+ }
+ return 0;
}
/**
* No longer available, keeping here just in case it's back someday. [Ind]
@@ -5728,17 +5902,17 @@ ACMD_FUNC(autolootitem)
*------------------------------------------*/
//ACMD_FUNC(rain)
//{
-// nullpo_retr(-1, sd);
-// if (map[sd->bl.m].flag.rain) {
-// map[sd->bl.m].flag.rain=0;
-// clif_weather(sd->bl.m);
-// clif_displaymessage(fd, msg_txt(1201)); // The rain has stopped.
-// } else {
-// map[sd->bl.m].flag.rain=1;
-// clif_weather(sd->bl.m);
-// clif_displaymessage(fd, msg_txt(1202)); // It has started to rain.
-// }
-// return 0;
+// nullpo_retr(-1, sd);
+// if (map[sd->bl.m].flag.rain) {
+// map[sd->bl.m].flag.rain=0;
+// clif_weather(sd->bl.m);
+// clif_displaymessage(fd, msg_txt(1201)); // The rain has stopped.
+// } else {
+// map[sd->bl.m].flag.rain=1;
+// clif_weather(sd->bl.m);
+// clif_displaymessage(fd, msg_txt(1202)); // It has started to rain.
+// }
+// return 0;
//}
/*==========================================
@@ -5746,18 +5920,18 @@ ACMD_FUNC(autolootitem)
*------------------------------------------*/
ACMD_FUNC(snow)
{
- nullpo_retr(-1, sd);
- if (map[sd->bl.m].flag.snow) {
- map[sd->bl.m].flag.snow=0;
- clif_weather(sd->bl.m);
- clif_displaymessage(fd, msg_txt(1203)); // Snow has stopped falling.
- } else {
- map[sd->bl.m].flag.snow=1;
- clif_weather(sd->bl.m);
- clif_displaymessage(fd, msg_txt(1204)); // It has started to snow.
- }
+ nullpo_retr(-1, sd);
+ if (map[sd->bl.m].flag.snow) {
+ map[sd->bl.m].flag.snow=0;
+ clif_weather(sd->bl.m);
+ clif_displaymessage(fd, msg_txt(1203)); // Snow has stopped falling.
+ } else {
+ map[sd->bl.m].flag.snow=1;
+ clif_weather(sd->bl.m);
+ clif_displaymessage(fd, msg_txt(1204)); // It has started to snow.
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -5765,17 +5939,17 @@ ACMD_FUNC(snow)
*------------------------------------------*/
ACMD_FUNC(sakura)
{
- nullpo_retr(-1, sd);
- if (map[sd->bl.m].flag.sakura) {
- map[sd->bl.m].flag.sakura=0;
- clif_weather(sd->bl.m);
- clif_displaymessage(fd, msg_txt(1205)); // Cherry tree leaves no longer fall.
- } else {
- map[sd->bl.m].flag.sakura=1;
- clif_weather(sd->bl.m);
- clif_displaymessage(fd, msg_txt(1206)); // Cherry tree leaves have begun to fall.
- }
- return 0;
+ nullpo_retr(-1, sd);
+ if (map[sd->bl.m].flag.sakura) {
+ map[sd->bl.m].flag.sakura=0;
+ clif_weather(sd->bl.m);
+ clif_displaymessage(fd, msg_txt(1205)); // Cherry tree leaves no longer fall.
+ } else {
+ map[sd->bl.m].flag.sakura=1;
+ clif_weather(sd->bl.m);
+ clif_displaymessage(fd, msg_txt(1206)); // Cherry tree leaves have begun to fall.
+ }
+ return 0;
}
/*==========================================
@@ -5783,18 +5957,18 @@ ACMD_FUNC(sakura)
*------------------------------------------*/
ACMD_FUNC(clouds)
{
- nullpo_retr(-1, sd);
- if (map[sd->bl.m].flag.clouds) {
- map[sd->bl.m].flag.clouds=0;
- clif_weather(sd->bl.m);
- clif_displaymessage(fd, msg_txt(1207)); // The clouds has disappear.
- } else {
- map[sd->bl.m].flag.clouds=1;
- clif_weather(sd->bl.m);
- clif_displaymessage(fd, msg_txt(1208)); // Clouds appear.
- }
+ nullpo_retr(-1, sd);
+ if (map[sd->bl.m].flag.clouds) {
+ map[sd->bl.m].flag.clouds=0;
+ clif_weather(sd->bl.m);
+ clif_displaymessage(fd, msg_txt(1207)); // The clouds has disappear.
+ } else {
+ map[sd->bl.m].flag.clouds=1;
+ clif_weather(sd->bl.m);
+ clif_displaymessage(fd, msg_txt(1208)); // Clouds appear.
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -5802,18 +5976,18 @@ ACMD_FUNC(clouds)
*------------------------------------------*/
ACMD_FUNC(clouds2)
{
- nullpo_retr(-1, sd);
- if (map[sd->bl.m].flag.clouds2) {
- map[sd->bl.m].flag.clouds2=0;
- clif_weather(sd->bl.m);
- clif_displaymessage(fd, msg_txt(1209)); // The alternative clouds disappear.
- } else {
- map[sd->bl.m].flag.clouds2=1;
- clif_weather(sd->bl.m);
- clif_displaymessage(fd, msg_txt(1210)); // Alternative clouds appear.
- }
+ nullpo_retr(-1, sd);
+ if (map[sd->bl.m].flag.clouds2) {
+ map[sd->bl.m].flag.clouds2=0;
+ clif_weather(sd->bl.m);
+ clif_displaymessage(fd, msg_txt(1209)); // The alternative clouds disappear.
+ } else {
+ map[sd->bl.m].flag.clouds2=1;
+ clif_weather(sd->bl.m);
+ clif_displaymessage(fd, msg_txt(1210)); // Alternative clouds appear.
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -5821,17 +5995,17 @@ ACMD_FUNC(clouds2)
*------------------------------------------*/
ACMD_FUNC(fog)
{
- nullpo_retr(-1, sd);
- if (map[sd->bl.m].flag.fog) {
- map[sd->bl.m].flag.fog=0;
- clif_weather(sd->bl.m);
- clif_displaymessage(fd, msg_txt(1211)); // The fog has gone.
- } else {
- map[sd->bl.m].flag.fog=1;
- clif_weather(sd->bl.m);
- clif_displaymessage(fd, msg_txt(1212)); // Fog hangs over.
- }
- return 0;
+ nullpo_retr(-1, sd);
+ if (map[sd->bl.m].flag.fog) {
+ map[sd->bl.m].flag.fog=0;
+ clif_weather(sd->bl.m);
+ clif_displaymessage(fd, msg_txt(1211)); // The fog has gone.
+ } else {
+ map[sd->bl.m].flag.fog=1;
+ clif_weather(sd->bl.m);
+ clif_displaymessage(fd, msg_txt(1212)); // Fog hangs over.
+ }
+ return 0;
}
/*==========================================
@@ -5839,18 +6013,18 @@ ACMD_FUNC(fog)
*------------------------------------------*/
ACMD_FUNC(leaves)
{
- nullpo_retr(-1, sd);
- if (map[sd->bl.m].flag.leaves) {
- map[sd->bl.m].flag.leaves=0;
- clif_weather(sd->bl.m);
- clif_displaymessage(fd, msg_txt(1213)); // Leaves no longer fall.
- } else {
- map[sd->bl.m].flag.leaves=1;
- clif_weather(sd->bl.m);
- clif_displaymessage(fd, msg_txt(1214)); // Fallen leaves fall.
- }
+ nullpo_retr(-1, sd);
+ if (map[sd->bl.m].flag.leaves) {
+ map[sd->bl.m].flag.leaves=0;
+ clif_weather(sd->bl.m);
+ clif_displaymessage(fd, msg_txt(1213)); // Leaves no longer fall.
+ } else {
+ map[sd->bl.m].flag.leaves=1;
+ clif_weather(sd->bl.m);
+ clif_displaymessage(fd, msg_txt(1214)); // Fallen leaves fall.
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -5858,18 +6032,18 @@ ACMD_FUNC(leaves)
*------------------------------------------*/
ACMD_FUNC(fireworks)
{
- nullpo_retr(-1, sd);
- if (map[sd->bl.m].flag.fireworks) {
- map[sd->bl.m].flag.fireworks=0;
- clif_weather(sd->bl.m);
- clif_displaymessage(fd, msg_txt(1215)); // Fireworks have ended.
- } else {
- map[sd->bl.m].flag.fireworks=1;
- clif_weather(sd->bl.m);
- clif_displaymessage(fd, msg_txt(1216)); // Fireworks have launched.
- }
+ nullpo_retr(-1, sd);
+ if (map[sd->bl.m].flag.fireworks) {
+ map[sd->bl.m].flag.fireworks=0;
+ clif_weather(sd->bl.m);
+ clif_displaymessage(fd, msg_txt(1215)); // Fireworks have ended.
+ } else {
+ map[sd->bl.m].flag.fireworks=1;
+ clif_weather(sd->bl.m);
+ clif_displaymessage(fd, msg_txt(1216)); // Fireworks have launched.
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -5877,22 +6051,22 @@ ACMD_FUNC(fireworks)
*------------------------------------------*/
ACMD_FUNC(clearweather)
{
- nullpo_retr(-1, sd);
- /**
- * No longer available, keeping here just in case it's back someday. [Ind]
- **/
- //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.clouds=0;
- map[sd->bl.m].flag.clouds2=0;
- map[sd->bl.m].flag.fog=0;
- map[sd->bl.m].flag.fireworks=0;
- map[sd->bl.m].flag.leaves=0;
- clif_weather(sd->bl.m);
- clif_displaymessage(fd, msg_txt(291));
+ nullpo_retr(-1, sd);
+ /**
+ * No longer available, keeping here just in case it's back someday. [Ind]
+ **/
+ //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.clouds=0;
+ map[sd->bl.m].flag.clouds2=0;
+ map[sd->bl.m].flag.fog=0;
+ map[sd->bl.m].flag.fireworks=0;
+ map[sd->bl.m].flag.leaves=0;
+ clif_weather(sd->bl.m);
+ clif_displaymessage(fd, msg_txt(291));
- return 0;
+ return 0;
}
/*===============================================================
@@ -5900,112 +6074,97 @@ ACMD_FUNC(clearweather)
*---------------------------------------------------------------*/
ACMD_FUNC(sound)
{
- char sound_file[100];
+ char sound_file[100];
- memset(sound_file, '\0', sizeof(sound_file));
+ memset(sound_file, '\0', sizeof(sound_file));
- if (!message || !*message || sscanf(message, "%99[^\n]", sound_file) < 1) {
- clif_displaymessage(fd, msg_txt(1217)); // Please enter a sound filename (usage: @sound <filename>).
- return -1;
- }
+ if(!message || !*message || sscanf(message, "%99[^\n]", sound_file) < 1) {
+ clif_displaymessage(fd, msg_txt(1217)); // Please enter a sound filename (usage: @sound <filename>).
+ return -1;
+ }
- if (strstr(sound_file, ".wav") == NULL)
- strcat(sound_file, ".wav");
+ if(strstr(sound_file, ".wav") == NULL)
+ strcat(sound_file, ".wav");
- clif_soundeffectall(&sd->bl, sound_file, 0, AREA);
+ clif_soundeffectall(&sd->bl, sound_file, 0, AREA);
- return 0;
+ return 0;
}
/*==========================================
- * MOB Search
+ * MOB Search
*------------------------------------------*/
ACMD_FUNC(mobsearch)
{
- char mob_name[100];
- int mob_id;
- int number = 0;
- struct s_mapiterator *it;
-
- nullpo_retr(-1, sd);
-
- if (!message || !*message || sscanf(message, "%99[^\n]", mob_name) < 1) {
- clif_displaymessage(fd, msg_txt(1218)); // Please enter a monster name (usage: @mobsearch <monster name>).
- return -1;
- }
-
- if ((mob_id = atoi(mob_name)) == 0)
- mob_id = mobdb_searchname(mob_name);
- if (mob_id > 0 && mobdb_checkid(mob_id) == 0) {
- snprintf(atcmd_output, sizeof atcmd_output, msg_txt(1219),mob_name); // Invalid mob ID %s!
- clif_displaymessage(fd, atcmd_output);
- return -1;
- }
- 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--
-
- snprintf(atcmd_output, sizeof atcmd_output, msg_txt(1220), mob_name, mapindex_id2name(sd->mapindex)); // Mob Search... %s %s
- clif_displaymessage(fd, atcmd_output);
-
- it = mapit_geteachmob();
- for (;;) {
- TBL_MOB *md = (TBL_MOB *)mapit_next(it);
- if (md == NULL)
- break;// no more mobs
-
- if (md->bl.m != sd->bl.m)
- continue;
- if (mob_id != -1 && md->class_ != mob_id)
- continue;
-
- ++number;
- if (md->spawn_timer == INVALID_TIMER)
- snprintf(atcmd_output, sizeof(atcmd_output), "%2d[%3d:%3d] %s", number, md->bl.x, md->bl.y, md->name);
- else
- snprintf(atcmd_output, sizeof(atcmd_output), "%2d[%s] %s", number, "dead", md->name);
- clif_displaymessage(fd, atcmd_output);
- }
- mapit_free(it);
-
- return 0;
+ char mob_name[100];
+ int mob_id;
+ int number = 0;
+ struct s_mapiterator* it;
+
+ nullpo_retr(-1, sd);
+
+ if (!message || !*message || sscanf(message, "%99[^\n]", mob_name) < 1) {
+ clif_displaymessage(fd, msg_txt(1218)); // Please enter a monster name (usage: @mobsearch <monster name>).
+ return -1;
+ }
+
+ if ((mob_id = atoi(mob_name)) == 0)
+ mob_id = mobdb_searchname(mob_name);
+ if(mob_id > 0 && mobdb_checkid(mob_id) == 0){
+ snprintf(atcmd_output, sizeof atcmd_output, msg_txt(1219),mob_name); // Invalid mob ID %s!
+ clif_displaymessage(fd, atcmd_output);
+ return -1;
+ }
+ 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--
+
+ snprintf(atcmd_output, sizeof atcmd_output, msg_txt(1220), mob_name, mapindex_id2name(sd->mapindex)); // Mob Search... %s %s
+ clif_displaymessage(fd, atcmd_output);
+
+ it = mapit_geteachmob();
+ for(;;)
+ {
+ TBL_MOB* md = (TBL_MOB*)mapit_next(it);
+ if( md == NULL )
+ break;// no more mobs
+
+ if( md->bl.m != sd->bl.m )
+ continue;
+ if( mob_id != -1 && md->class_ != mob_id )
+ continue;
+
+ ++number;
+ if( md->spawn_timer == INVALID_TIMER )
+ snprintf(atcmd_output, sizeof(atcmd_output), "%2d[%3d:%3d] %s", number, md->bl.x, md->bl.y, md->name);
+ else
+ snprintf(atcmd_output, sizeof(atcmd_output), "%2d[%s] %s", number, "dead", md->name);
+ clif_displaymessage(fd, atcmd_output);
+ }
+ mapit_free(it);
+
+ return 0;
}
/*==========================================
* @cleanmap - cleans items on the ground
- * @cleanarea - cleans items on the ground within an specified area
*------------------------------------------*/
-static int atcommand_cleanfloor_sub(struct block_list *bl, va_list ap)
+static int atcommand_cleanmap_sub(struct block_list *bl, va_list ap)
{
- nullpo_ret(bl);
- map_clearflooritem(bl);
+ nullpo_ret(bl);
+ map_clearflooritem(bl);
- return 0;
+ return 0;
}
ACMD_FUNC(cleanmap)
{
- map_foreachinmap(atcommand_cleanfloor_sub, sd->bl.m, BL_ITEM);
- clif_displaymessage(fd, msg_txt(1221)); // All dropped items have been cleaned up.
- return 0;
-}
-
-ACMD_FUNC(cleanarea)
-{
- int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
-
- if (!message || !*message || sscanf(message, "%d %d %d %d", &x0, &y0, &x1, &y1) < 1) {
- map_foreachinarea(atcommand_cleanfloor_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);
- }
- else if (sscanf(message, "%d %d %d %d", &x0, &y0, &x1, &y1) == 1) {
- map_foreachinarea(atcommand_cleanfloor_sub, sd->bl.m, sd->bl.x - x0, sd->bl.y - x0, sd->bl.x + x0, sd->bl.y + x0, BL_ITEM);
- }
- else if (sscanf(message, "%d %d %d %d", &x0, &y0, &x1, &y1) == 4) {
- map_foreachinarea(atcommand_cleanfloor_sub, sd->bl.m, x0, y0, x1, y1, BL_ITEM);
- }
-
- clif_displaymessage(fd, msg_txt(1221)); // All dropped items have been cleaned up.
- return 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);
+ clif_displaymessage(fd, msg_txt(1221)); // All dropped items have been cleaned up.
+ return 0;
}
/*==========================================
@@ -6014,146 +6173,151 @@ ACMD_FUNC(cleanarea)
*------------------------------------------*/
ACMD_FUNC(npctalk)
{
- char name[NAME_LENGTH],mes[100],temp[100];
- struct npc_data *nd;
- bool ifcolor=(*(command + 8) != 'c' && *(command + 8) != 'C')?0:1;
- unsigned long color=0;
+ char name[NAME_LENGTH],mes[100],temp[100];
+ struct npc_data *nd;
+ bool ifcolor=(*(command + 8) != 'c' && *(command + 8) != 'C')?0:1;
+ unsigned long color=0;
- if (sd->sc.count && //no "chatting" while muted.
- (sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] ||
- (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT)))
- return -1;
+ if (sd->sc.count && //no "chatting" while muted.
+ (sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] ||
+ (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT)))
+ return -1;
- if (!ifcolor) {
- if (!message || !*message || sscanf(message, "%23[^,], %99[^\n]", name, mes) < 2) {
- clif_displaymessage(fd, msg_txt(1222)); // Please enter the correct parameters (usage: @npctalk <npc name>, <message>).
- return -1;
- }
- } else {
- if (!message || !*message || sscanf(message, "%lx %23[^,], %99[^\n]", &color, name, mes) < 3) {
- clif_displaymessage(fd, msg_txt(1223)); // Please enter the correct parameters (usage: @npctalkc <color> <npc name>, <message>).
- return -1;
- }
- }
+ if(!ifcolor) {
+ if (!message || !*message || sscanf(message, "%23[^,], %99[^\n]", name, mes) < 2) {
+ clif_displaymessage(fd, msg_txt(1222)); // Please enter the correct parameters (usage: @npctalk <npc name>, <message>).
+ return -1;
+ }
+ }
+ else {
+ if (!message || !*message || sscanf(message, "%lx %23[^,], %99[^\n]", &color, name, mes) < 3) {
+ clif_displaymessage(fd, msg_txt(1223)); // Please enter the correct parameters (usage: @npctalkc <color> <npc name>, <message>).
+ return -1;
+ }
+ }
- if (!(nd = npc_name2id(name))) {
- clif_displaymessage(fd, msg_txt(111)); // This NPC doesn't exist
- return -1;
- }
+ if (!(nd = npc_name2id(name))) {
+ clif_displaymessage(fd, msg_txt(111)); // This NPC doesn't exist
+ return -1;
+ }
- strtok(name, "#"); // discard extra name identifier if present
- snprintf(temp, sizeof(temp), "%s : %s", name, mes);
+ strtok(name, "#"); // discard extra name identifier if present
+ snprintf(temp, sizeof(temp), "%s : %s", name, mes);
- if (ifcolor) clif_messagecolor(&nd->bl,color,temp);
- else clif_message(&nd->bl, temp);
+ if(ifcolor) clif_messagecolor(&nd->bl,color,temp);
+ else clif_message(&nd->bl, temp);
- return 0;
+ return 0;
}
ACMD_FUNC(pettalk)
{
- char mes[100],temp[100];
- struct pet_data *pd;
-
- nullpo_retr(-1, sd);
-
- if (battle_config.min_chat_delay) {
- if (DIFF_TICK(sd->cantalk_tick, gettick()) > 0)
- return 0;
- sd->cantalk_tick = gettick() + battle_config.min_chat_delay;
- }
-
- if (!sd->status.pet_id || !(pd=sd->pd)) {
- clif_displaymessage(fd, msg_txt(184));
- return -1;
- }
-
- if (sd->sc.count && //no "chatting" while muted.
- (sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] ||
- (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT)))
- return -1;
-
- if (!message || !*message || sscanf(message, "%99[^\n]", mes) < 1) {
- clif_displaymessage(fd, msg_txt(1224)); // Please enter a message (usage: @pettalk <message>).
- return -1;
- }
-
- if (message[0] == '/') {
- // pet emotion processing
- const char *emo[] = {
- "/!", "/?", "/ho", "/lv", "/swt", "/ic", "/an", "/ag", "/$", "/...",
- "/scissors", "/rock", "/paper", "/korea", "/lv2", "/thx", "/wah", "/sry", "/heh", "/swt2",
- "/hmm", "/no1", "/??", "/omg", "/O", "/X", "/hlp", "/go", "/sob", "/gg",
- "/kis", "/kis2", "/pif", "/ok", "-?-", "/indonesia", "/bzz", "/rice", "/awsm", "/meh",
- "/shy", "/pat", "/mp", "/slur", "/com", "/yawn", "/grat", "/hp", "/philippines", "/malaysia",
- "/singapore", "/brazil", "/fsh", "/spin", "/sigh", "/dum", "/crwd", "/desp", "/dice", "-dice2",
- "-dice3", "-dice4", "-dice5", "-dice6", "/india", "/love", "/russia", "-?-", "/mobile", "/mail",
- "/chinese", "/antenna1", "/antenna2", "/antenna3", "/hum", "/abs", "/oops", "/spit", "/ene", "/panic",
- "/whisp"
- };
- int i;
- ARR_FIND(0, ARRAYLENGTH(emo), i, stricmp(message, emo[i]) == 0);
- if (i == E_DICE1) i = rnd()%6 + E_DICE1; // randomize /dice
- if (i < ARRAYLENGTH(emo)) {
- if (sd->emotionlasttime + 1 >= time(NULL)) { // not more than 1 per second
- sd->emotionlasttime = time(NULL);
- return 0;
- }
- sd->emotionlasttime = time(NULL);
-
- clif_emotion(&pd->bl, i);
- return 0;
- }
- }
-
- snprintf(temp, sizeof temp ,"%s : %s", pd->pet.name, mes);
- clif_message(&pd->bl, temp);
-
- return 0;
+ char mes[100],temp[100];
+ struct pet_data *pd;
+
+ nullpo_retr(-1, sd);
+
+ if ( battle_config.min_chat_delay ) {
+ if( DIFF_TICK(sd->cantalk_tick, gettick()) > 0 )
+ return 0;
+ sd->cantalk_tick = gettick() + battle_config.min_chat_delay;
+ }
+
+ if(!sd->status.pet_id || !(pd=sd->pd))
+ {
+ clif_displaymessage(fd, msg_txt(184));
+ return -1;
+ }
+
+ if (sd->sc.count && //no "chatting" while muted.
+ (sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] ||
+ (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT)))
+ return -1;
+
+ if (!message || !*message || sscanf(message, "%99[^\n]", mes) < 1) {
+ clif_displaymessage(fd, msg_txt(1224)); // Please enter a message (usage: @pettalk <message>).
+ return -1;
+ }
+
+ if (message[0] == '/')
+ {// pet emotion processing
+ const char* emo[] = {
+ "/!", "/?", "/ho", "/lv", "/swt", "/ic", "/an", "/ag", "/$", "/...",
+ "/scissors", "/rock", "/paper", "/korea", "/lv2", "/thx", "/wah", "/sry", "/heh", "/swt2",
+ "/hmm", "/no1", "/??", "/omg", "/O", "/X", "/hlp", "/go", "/sob", "/gg",
+ "/kis", "/kis2", "/pif", "/ok", "-?-", "/indonesia", "/bzz", "/rice", "/awsm", "/meh",
+ "/shy", "/pat", "/mp", "/slur", "/com", "/yawn", "/grat", "/hp", "/philippines", "/malaysia",
+ "/singapore", "/brazil", "/fsh", "/spin", "/sigh", "/dum", "/crwd", "/desp", "/dice", "-dice2",
+ "-dice3", "-dice4", "-dice5", "-dice6", "/india", "/love", "/russia", "-?-", "/mobile", "/mail",
+ "/chinese", "/antenna1", "/antenna2", "/antenna3", "/hum", "/abs", "/oops", "/spit", "/ene", "/panic",
+ "/whisp"
+ };
+ int i;
+ ARR_FIND( 0, ARRAYLENGTH(emo), i, stricmp(message, emo[i]) == 0 );
+ if( i == E_DICE1 ) i = rnd()%6 + E_DICE1; // randomize /dice
+ if( i < ARRAYLENGTH(emo) )
+ {
+ if (sd->emotionlasttime + 1 >= time(NULL)) { // not more than 1 per second
+ sd->emotionlasttime = time(NULL);
+ return 0;
+ }
+ sd->emotionlasttime = time(NULL);
+
+ clif_emotion(&pd->bl, i);
+ return 0;
+ }
+ }
+
+ snprintf(temp, sizeof temp ,"%s : %s", pd->pet.name, mes);
+ clif_message(&pd->bl, temp);
+
+ return 0;
}
/// @users - displays the number of players present on each map (and percentage)
/// #users displays on the target user instead of self
ACMD_FUNC(users)
{
- char buf[CHAT_SIZE_MAX];
- int i;
- int users[MAX_MAPINDEX];
- int users_all;
- struct s_mapiterator *iter;
+ char buf[CHAT_SIZE_MAX];
+ int i;
+ int users[MAX_MAPINDEX];
+ int users_all;
+ struct s_mapiterator* iter;
- memset(users, 0, sizeof(users));
- users_all = 0;
+ memset(users, 0, sizeof(users));
+ users_all = 0;
- // count users on each map
- iter = mapit_getallusers();
- for (;;) {
- struct map_session_data *sd2 = (struct map_session_data *)mapit_next(iter);
- if (sd2 == NULL)
- break;// no more users
+ // count users on each map
+ iter = mapit_getallusers();
+ for(;;)
+ {
+ struct map_session_data* sd2 = (struct map_session_data*)mapit_next(iter);
+ if( sd2 == NULL )
+ break;// no more users
- if (sd2->mapindex >= MAX_MAPINDEX)
- continue;// invalid mapindex
+ if( sd2->mapindex >= MAX_MAPINDEX )
+ continue;// invalid mapindex
- if (users[sd2->mapindex] < INT_MAX) ++users[sd2->mapindex];
- if (users_all < INT_MAX) ++users_all;
- }
- mapit_free(iter);
+ if( users[sd2->mapindex] < INT_MAX ) ++users[sd2->mapindex];
+ if( users_all < INT_MAX ) ++users_all;
+ }
+ mapit_free(iter);
- // display results for each map
- for (i = 0; i < MAX_MAPINDEX; ++i) {
- if (users[i] == 0)
- continue;// empty
+ // display results for each map
+ for( i = 0; i < MAX_MAPINDEX; ++i )
+ {
+ if( users[i] == 0 )
+ continue;// empty
- safesnprintf(buf, sizeof(buf), "%s: %d (%.2f%%)", mapindex_id2name(i), users[i], (float)(100.0f*users[i]/users_all));
- clif_displaymessage(sd->fd, buf);
- }
+ safesnprintf(buf, sizeof(buf), "%s: %d (%.2f%%)", mapindex_id2name(i), users[i], (float)(100.0f*users[i]/users_all));
+ clif_displaymessage(sd->fd, buf);
+ }
- // display overall count
- safesnprintf(buf, sizeof(buf), "all: %d", users_all);
- clif_displaymessage(sd->fd, buf);
+ // display overall count
+ safesnprintf(buf, sizeof(buf), "all: %d", users_all);
+ clif_displaymessage(sd->fd, buf);
- return 0;
+ return 0;
}
/*==========================================
@@ -6161,11 +6325,11 @@ ACMD_FUNC(users)
*------------------------------------------*/
ACMD_FUNC(reset)
{
- pc_resetstate(sd);
- pc_resetskill(sd,1);
- sprintf(atcmd_output, msg_txt(208), sd->status.name); // '%s' skill and stats points reseted!
- clif_displaymessage(fd, atcmd_output);
- return 0;
+ pc_resetstate(sd);
+ pc_resetskill(sd,1);
+ sprintf(atcmd_output, msg_txt(208), sd->status.name); // '%s' skill and stats points reseted!
+ clif_displaymessage(fd, atcmd_output);
+ return 0;
}
/*==========================================
@@ -6173,46 +6337,48 @@ ACMD_FUNC(reset)
*------------------------------------------*/
ACMD_FUNC(summon)
{
- char name[NAME_LENGTH];
- int mob_id = 0;
- int duration = 0;
- struct mob_data *md;
- unsigned int tick=gettick();
+ char name[NAME_LENGTH];
+ int mob_id = 0;
+ int duration = 0;
+ struct mob_data *md;
+ unsigned int tick=gettick();
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- if (!message || !*message || sscanf(message, "%23s %d", name, &duration) < 1) {
- clif_displaymessage(fd, msg_txt(1225)); // Please enter a monster name (usage: @summon <monster name> {duration}).
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%23s %d", name, &duration) < 1)
+ {
+ clif_displaymessage(fd, msg_txt(1225)); // Please enter a monster name (usage: @summon <monster name> {duration}).
+ return -1;
+ }
- if (duration < 1)
- duration =1;
- else if (duration > 60)
- duration =60;
+ if (duration < 1)
+ duration =1;
+ else if (duration > 60)
+ duration =60;
- if ((mob_id = atoi(name)) == 0)
- mob_id = mobdb_searchname(name);
- if (mob_id == 0 || mobdb_checkid(mob_id) == 0) {
- clif_displaymessage(fd, msg_txt(40)); // Invalid monster ID or name.
- return -1;
- }
+ if ((mob_id = atoi(name)) == 0)
+ mob_id = mobdb_searchname(name);
+ if(mob_id == 0 || mobdb_checkid(mob_id) == 0)
+ {
+ clif_displaymessage(fd, msg_txt(40)); // Invalid monster ID or name.
+ return -1;
+ }
- md = mob_once_spawn_sub(&sd->bl, sd->bl.m, -1, -1, "--ja--", mob_id, "", SZ_SMALL, AI_NONE);
+ md = mob_once_spawn_sub(&sd->bl, sd->bl.m, -1, -1, "--ja--", mob_id, "", SZ_SMALL, AI_NONE);
- if (!md)
- return -1;
+ if(!md)
+ return -1;
- md->master_id=sd->bl.id;
- md->special_state.ai=1;
- md->deletetimer=add_timer(tick+(duration*60000),mob_timer_delete,md->bl.id,0);
- clif_specialeffect(&md->bl,344,AREA);
- mob_spawn(md);
- sc_start4(&md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE, 0, 60000);
- clif_skill_poseffect(&sd->bl,AM_CALLHOMUN,1,md->bl.x,md->bl.y,tick);
- clif_displaymessage(fd, msg_txt(39)); // All monster summoned!
+ md->master_id=sd->bl.id;
+ md->special_state.ai=1;
+ md->deletetimer=add_timer(tick+(duration*60000),mob_timer_delete,md->bl.id,0);
+ clif_specialeffect(&md->bl,344,AREA);
+ mob_spawn(md);
+ sc_start4(&md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE, 0, 60000);
+ clif_skill_poseffect(&sd->bl,AM_CALLHOMUN,1,md->bl.x,md->bl.y,tick);
+ clif_displaymessage(fd, msg_txt(39)); // All monster summoned!
- return 0;
+ return 0;
}
/*==========================================
@@ -6222,24 +6388,24 @@ ACMD_FUNC(summon)
*------------------------------------------*/
ACMD_FUNC(adjgroup)
{
- int new_group = 0;
- nullpo_retr(-1, sd);
+ int new_group = 0;
+ nullpo_retr(-1, sd);
- if (!message || !*message || sscanf(message, "%d", &new_group) != 1) {
- clif_displaymessage(fd, msg_txt(1226)); // Usage: @adjgroup <group_id>
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%d", &new_group) != 1) {
+ clif_displaymessage(fd, msg_txt(1226)); // Usage: @adjgroup <group_id>
+ return -1;
+ }
- if (!pc_group_exists(new_group)) {
- clif_displaymessage(fd, msg_txt(1227)); // Specified group does not exist.
- return -1;
- }
+ if (!pc_group_exists(new_group)) {
+ clif_displaymessage(fd, msg_txt(1227)); // Specified group does not exist.
+ return -1;
+ }
- sd->group_id = new_group;
- pc_group_pc_load(sd);/* update cache */
- clif_displaymessage(fd, msg_txt(1228)); // Group changed successfully.
- clif_displaymessage(sd->fd, msg_txt(1229)); // Your group has changed.
- return 0;
+ sd->group_id = new_group;
+ pc_group_pc_load(sd);/* update cache */
+ clif_displaymessage(fd, msg_txt(1228)); // Group changed successfully.
+ clif_displaymessage(sd->fd, msg_txt(1229)); // Your group has changed.
+ return 0;
}
/*==========================================
@@ -6249,20 +6415,21 @@ ACMD_FUNC(adjgroup)
ACMD_FUNC(trade)
{
struct map_session_data *pl_sd = NULL;
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- if (!message || !*message) {
- clif_displaymessage(fd, msg_txt(1230)); // Please enter a player name (usage: @trade <char name>).
- return -1;
- }
+ if (!message || !*message) {
+ clif_displaymessage(fd, msg_txt(1230)); // Please enter a player name (usage: @trade <char name>).
+ return -1;
+ }
- if ((pl_sd = map_nick2sd((char *)message)) == NULL) {
- clif_displaymessage(fd, msg_txt(3)); // Character not found.
- return -1;
- }
+ if ( (pl_sd = map_nick2sd((char *)message)) == NULL )
+ {
+ clif_displaymessage(fd, msg_txt(3)); // Character not found.
+ return -1;
+ }
- trade_traderequest(sd, pl_sd);
- return 0;
+ trade_traderequest(sd, pl_sd);
+ return 0;
}
/*==========================================
@@ -6271,22 +6438,23 @@ ACMD_FUNC(trade)
*------------------------------------------*/
ACMD_FUNC(setbattleflag)
{
- char flag[128], value[128];
- nullpo_retr(-1, sd);
+ char flag[128], value[128];
+ nullpo_retr(-1, sd);
- if (!message || !*message || sscanf(message, "%127s %127s", flag, value) != 2) {
- clif_displaymessage(fd, msg_txt(1231)); // Usage: @setbattleflag <flag> <value>
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%127s %127s", flag, value) != 2) {
+ clif_displaymessage(fd, msg_txt(1231)); // Usage: @setbattleflag <flag> <value>
+ return -1;
+ }
- if (battle_set_value(flag, value) == 0) {
- clif_displaymessage(fd, msg_txt(1232)); // Unknown battle_config flag.
- return -1;
- }
+ if (battle_set_value(flag, value) == 0)
+ {
+ clif_displaymessage(fd, msg_txt(1232)); // Unknown battle_config flag.
+ return -1;
+ }
- clif_displaymessage(fd, msg_txt(1233)); // Set battle_config as requested.
+ clif_displaymessage(fd, msg_txt(1233)); // Set battle_config as requested.
- return 0;
+ return 0;
}
/*==========================================
@@ -6294,29 +6462,30 @@ ACMD_FUNC(setbattleflag)
*------------------------------------------*/
ACMD_FUNC(unmute)
{
- struct map_session_data *pl_sd = NULL;
- nullpo_retr(-1, sd);
+ struct map_session_data *pl_sd = NULL;
+ nullpo_retr(-1, sd);
- if (!message || !*message) {
- clif_displaymessage(fd, msg_txt(1234)); // Please enter a player name (usage: @unmute <char name>).
- return -1;
- }
+ if (!message || !*message) {
+ clif_displaymessage(fd, msg_txt(1234)); // Please enter a player name (usage: @unmute <char name>).
+ return -1;
+ }
- if ((pl_sd = map_nick2sd((char *)message)) == NULL) {
- clif_displaymessage(fd, msg_txt(3)); // Character not found.
- return -1;
- }
+ if ( (pl_sd = map_nick2sd((char *)message)) == NULL )
+ {
+ clif_displaymessage(fd, msg_txt(3)); // Character not found.
+ return -1;
+ }
- if (!pl_sd->sc.data[SC_NOCHAT]) {
- clif_displaymessage(sd->fd,msg_txt(1235)); // Player is not muted.
- return -1;
- }
+ if(!pl_sd->sc.data[SC_NOCHAT]) {
+ clif_displaymessage(sd->fd,msg_txt(1235)); // Player is not muted.
+ return -1;
+ }
- pl_sd->status.manner = 0;
- status_change_end(&pl_sd->bl, SC_NOCHAT, INVALID_TIMER);
- clif_displaymessage(sd->fd,msg_txt(1236)); // Player unmuted.
+ pl_sd->status.manner = 0;
+ status_change_end(&pl_sd->bl, SC_NOCHAT, INVALID_TIMER);
+ clif_displaymessage(sd->fd,msg_txt(1236)); // Player unmuted.
- return 0;
+ return 0;
}
/*==========================================
@@ -6324,22 +6493,22 @@ ACMD_FUNC(unmute)
*------------------------------------------*/
ACMD_FUNC(uptime)
{
- unsigned long seconds = 0, day = 24*60*60, hour = 60*60,
- minute = 60, days = 0, hours = 0, minutes = 0;
- nullpo_retr(-1, sd);
+ unsigned long seconds = 0, day = 24*60*60, hour = 60*60,
+ minute = 60, days = 0, hours = 0, minutes = 0;
+ nullpo_retr(-1, sd);
- seconds = get_uptime();
- 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;
+ seconds = get_uptime();
+ 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;
- snprintf(atcmd_output, sizeof(atcmd_output), msg_txt(245), days, hours, minutes, seconds);
- clif_displaymessage(fd, atcmd_output);
+ snprintf(atcmd_output, sizeof(atcmd_output), msg_txt(245), days, hours, minutes, seconds);
+ clif_displaymessage(fd, atcmd_output);
- return 0;
+ return 0;
}
/*==========================================
@@ -6348,14 +6517,14 @@ ACMD_FUNC(uptime)
*------------------------------------------*/
ACMD_FUNC(changesex)
{
- int i;
- nullpo_retr(-1, sd);
- pc_resetskill(sd,4);
- // to avoid any problem with equipment and invalid sex, equipment is unequiped.
- for (i=0; i<EQI_MAX; i++)
- if (sd->equip_index[i] >= 0) pc_unequipitem(sd, sd->equip_index[i], 3);
- chrif_changesex(sd);
- return 0;
+ int i;
+ nullpo_retr(-1, sd);
+ pc_resetskill(sd,4);
+ // to avoid any problem with equipment and invalid sex, equipment is unequiped.
+ for( i=0; i<EQI_MAX; i++ )
+ if( sd->equip_index[i] >= 0 ) pc_unequipitem(sd, sd->equip_index[i], 3);
+ chrif_changesex(sd);
+ return 0;
}
/*================================================
@@ -6363,39 +6532,41 @@ ACMD_FUNC(changesex)
*------------------------------------------------*/
ACMD_FUNC(mute)
{
- struct map_session_data *pl_sd = NULL;
- int manner;
- nullpo_retr(-1, sd);
+ struct map_session_data *pl_sd = NULL;
+ int manner;
+ nullpo_retr(-1, sd);
- if (!message || !*message || sscanf(message, "%d %23[^\n]", &manner, atcmd_player_name) < 1) {
- clif_displaymessage(fd, msg_txt(1237)); // Usage: @mute <time> <char name>
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%d %23[^\n]", &manner, atcmd_player_name) < 1) {
+ clif_displaymessage(fd, msg_txt(1237)); // Usage: @mute <time> <char name>
+ return -1;
+ }
- if ((pl_sd = map_nick2sd(atcmd_player_name)) == NULL) {
- clif_displaymessage(fd, msg_txt(3)); // Character not found.
- return -1;
- }
+ if ( (pl_sd = map_nick2sd(atcmd_player_name)) == NULL )
+ {
+ clif_displaymessage(fd, msg_txt(3)); // Character not found.
+ return -1;
+ }
- if (pc_get_group_level(sd) < pc_get_group_level(pl_sd)) {
- clif_displaymessage(fd, msg_txt(81)); // Your GM level don't authorise you to do this action on this player.
- return -1;
- }
+ if ( pc_get_group_level(sd) < pc_get_group_level(pl_sd) )
+ {
+ clif_displaymessage(fd, msg_txt(81)); // Your GM level don't authorise you to do this action on this player.
+ return -1;
+ }
- clif_manner_message(sd, 0);
- clif_manner_message(pl_sd, 5);
+ clif_manner_message(sd, 0);
+ clif_manner_message(pl_sd, 5);
- if (pl_sd->status.manner < manner) {
- pl_sd->status.manner -= manner;
- sc_start(&pl_sd->bl,SC_NOCHAT,100,0,0);
- } else {
- pl_sd->status.manner = 0;
- status_change_end(&pl_sd->bl, SC_NOCHAT, INVALID_TIMER);
- }
+ if( pl_sd->status.manner < manner ) {
+ pl_sd->status.manner -= manner;
+ sc_start(&pl_sd->bl,SC_NOCHAT,100,0,0);
+ } else {
+ pl_sd->status.manner = 0;
+ status_change_end(&pl_sd->bl, SC_NOCHAT, INVALID_TIMER);
+ }
- clif_GM_silence(sd, pl_sd, (manner > 0 ? 1 : 0));
+ clif_GM_silence(sd, pl_sd, (manner > 0 ? 1 : 0));
- return 0;
+ return 0;
}
/*==========================================
@@ -6403,9 +6574,9 @@ ACMD_FUNC(mute)
*------------------------------------------*/
ACMD_FUNC(refresh)
{
- nullpo_retr(-1, sd);
- clif_refresh(sd);
- return 0;
+ nullpo_retr(-1, sd);
+ clif_refresh(sd);
+ return 0;
}
/*==========================================
@@ -6414,21 +6585,21 @@ ACMD_FUNC(refresh)
*------------------------------------------*/
ACMD_FUNC(identify)
{
- int i,num;
+ int i,num;
- nullpo_retr(-1, sd);
+ 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);
- } else {
- clif_displaymessage(fd,msg_txt(1238)); // There are no items to appraise.
- }
- return 0;
+ 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);
+ } else {
+ clif_displaymessage(fd,msg_txt(1238)); // There are no items to appraise.
+ }
+ return 0;
}
/*==========================================
@@ -6437,45 +6608,49 @@ ACMD_FUNC(identify)
*------------------------------------------*/
ACMD_FUNC(gmotd)
{
- char buf[CHAT_SIZE_MAX];
- size_t len;
- FILE *fp;
+ char buf[CHAT_SIZE_MAX];
+ size_t len;
+ FILE* fp;
- if ((fp = fopen(motd_txt, "r")) != NULL) {
- while (fgets(buf, sizeof(buf), fp)) {
- if (buf[0] == '/' && buf[1] == '/') {
- continue;
- }
+ if( ( fp = fopen(motd_txt, "r") ) != NULL )
+ {
+ while( fgets(buf, sizeof(buf), fp) )
+ {
+ if( buf[0] == '/' && buf[1] == '/' )
+ {
+ continue;
+ }
- len = strlen(buf);
+ len = strlen(buf);
- while (len && (buf[len-1] == '\r' || buf[len-1] == '\n')) {
- // strip trailing EOL characters
- len--;
- }
+ while( len && ( buf[len-1] == '\r' || buf[len-1] == '\n' ) )
+ {// strip trailing EOL characters
+ len--;
+ }
- if (len) {
- buf[len] = 0;
+ if( len )
+ {
+ buf[len] = 0;
- intif_broadcast(buf, len+1, 0);
- }
- }
- fclose(fp);
- }
- return 0;
+ intif_broadcast(buf, len+1, 0);
+ }
+ }
+ fclose(fp);
+ }
+ return 0;
}
ACMD_FUNC(misceffect)
{
- int effect = 0;
- nullpo_retr(-1, sd);
- if (!message || !*message)
- return -1;
- if (sscanf(message, "%d", &effect) < 1)
- return -1;
- clif_misceffect(&sd->bl,effect);
+ int effect = 0;
+ nullpo_retr(-1, sd);
+ if (!message || !*message)
+ return -1;
+ if (sscanf(message, "%d", &effect) < 1)
+ return -1;
+ clif_misceffect(&sd->bl,effect);
- return 0;
+ return 0;
}
/*==========================================
@@ -6483,9 +6658,9 @@ ACMD_FUNC(misceffect)
*------------------------------------------*/
ACMD_FUNC(mail)
{
- nullpo_ret(sd);
- mail_openmail(sd);
- return 0;
+ nullpo_ret(sd);
+ mail_openmail(sd);
+ return 0;
}
/*==========================================
@@ -6494,110 +6669,111 @@ ACMD_FUNC(mail)
*------------------------------------------*/
ACMD_FUNC(mobinfo)
{
- 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[10][8] = {"Neutral", "Water", "Earth", "Fire", "Wind", "Poison", "Holy", "Dark", "Ghost", "Undead"};
- char atcmd_output2[CHAT_SIZE_MAX];
- struct item_data *item_data;
- struct mob_db *mob, *mob_array[MAX_SEARCH];
- int count;
- int i, j, k;
-
- memset(atcmd_output, '\0', sizeof(atcmd_output));
- memset(atcmd_output2, '\0', sizeof(atcmd_output2));
-
- if (!message || !*message) {
- clif_displaymessage(fd, msg_txt(1239)); // Please enter a monster name/ID (usage: @mobinfo <monster_name_or_monster_ID>).
- return -1;
- }
-
- // If monster identifier/name argument is a name
- if ((i = mobdb_checkid(atoi(message)))) {
- mob_array[0] = mob_db(i);
- count = 1;
- } else
- count = mobdb_searchname_array(mob_array, MAX_SEARCH, message);
-
- if (!count) {
- clif_displaymessage(fd, msg_txt(40)); // Invalid monster ID or name.
- return -1;
- }
-
- if (count > MAX_SEARCH) {
- sprintf(atcmd_output, msg_txt(269), MAX_SEARCH, count);
- clif_displaymessage(fd, atcmd_output);
- count = MAX_SEARCH;
- }
- for (k = 0; k < count; k++) {
- mob = mob_array[k];
-
- // stats
- if (mob->mexp)
- sprintf(atcmd_output, msg_txt(1240), mob->name, mob->jname, mob->sprite, mob->vd.class_); // MVP Monster: '%s'/'%s'/'%s' (%d)
- else
- sprintf(atcmd_output, msg_txt(1241), mob->name, mob->jname, mob->sprite, mob->vd.class_); // Monster: '%s'/'%s'/'%s' (%d)
- clif_displaymessage(fd, atcmd_output);
- sprintf(atcmd_output, msg_txt(1242), mob->lv, mob->status.max_hp, mob->base_exp, mob->job_exp,MOB_HIT(mob), MOB_FLEE(mob)); // Lv:%d HP:%d Base EXP:%u Job EXP:%u HIT:%d FLEE:%d
- clif_displaymessage(fd, atcmd_output);
- sprintf(atcmd_output, msg_txt(1243), // DEF:%d MDEF:%d STR:%d AGI:%d VIT:%d INT:%d DEX:%d LUK:%d
- mob->status.def, mob->status.mdef,mob->status.str, mob->status.agi,
- mob->status.vit, mob->status.int_, mob->status.dex, mob->status.luk);
- clif_displaymessage(fd, atcmd_output);
-
- sprintf(atcmd_output, msg_txt(1244), // ATK:%d~%d Range:%d~%d~%d Size:%s Race: %s Element: %s (Lv:%d)
- mob->status.rhw.atk, mob->status.rhw.atk2, mob->status.rhw.range,
- mob->range2 , mob->range3, msize[mob->status.size],
- mrace[mob->status.race], melement[mob->status.def_ele], mob->status.ele_lv);
- clif_displaymessage(fd, atcmd_output);
- // drops
- clif_displaymessage(fd, msg_txt(1245)); // Drops:
- strcpy(atcmd_output, " ");
- j = 0;
- for (i = 0; i < MAX_MOB_DROP; i++) {
- int droprate;
- if (mob->dropitem[i].nameid <= 0 || mob->dropitem[i].p < 1 || (item_data = itemdb_exists(mob->dropitem[i].nameid)) == NULL)
- continue;
- droprate = mob->dropitem[i].p;
-
- if (item_data->slot)
- sprintf(atcmd_output2, " - %s[%d] %02.02f%%", item_data->jname, item_data->slot, (float)droprate / 100);
- else
- sprintf(atcmd_output2, " - %s %02.02f%%", item_data->jname, (float)droprate / 100);
- strcat(atcmd_output, atcmd_output2);
- if (++j % 3 == 0) {
- clif_displaymessage(fd, atcmd_output);
- strcpy(atcmd_output, " ");
- }
- }
- if (j == 0)
- clif_displaymessage(fd, msg_txt(1246)); // This monster has no drops.
- else if (j % 3 != 0)
- clif_displaymessage(fd, atcmd_output);
- // mvp
- if (mob->mexp) {
- sprintf(atcmd_output, msg_txt(1247), mob->mexp); // MVP Bonus EXP:%u
- clif_displaymessage(fd, atcmd_output);
- strcpy(atcmd_output, msg_txt(1248)); // MVP Items:
- j = 0;
- for (i = 0; i < MAX_MVP_DROP; i++) {
- if (mob->mvpitem[i].nameid <= 0 || (item_data = itemdb_exists(mob->mvpitem[i].nameid)) == NULL)
- continue;
- if (mob->mvpitem[i].p > 0) {
- j++;
- if (j == 1)
- sprintf(atcmd_output2, " %s %02.02f%%", item_data->jname, (float)mob->mvpitem[i].p / 100);
- else
- sprintf(atcmd_output2, " - %s %02.02f%%", item_data->jname, (float)mob->mvpitem[i].p / 100);
- strcat(atcmd_output, atcmd_output2);
- }
- }
- if (j == 0)
- clif_displaymessage(fd, msg_txt(1249)); // This monster has no MVP prizes.
- else
- clif_displaymessage(fd, atcmd_output);
- }
- }
- return 0;
+ 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[10][8] = {"Neutral", "Water", "Earth", "Fire", "Wind", "Poison", "Holy", "Dark", "Ghost", "Undead"};
+ char atcmd_output2[CHAT_SIZE_MAX];
+ struct item_data *item_data;
+ struct mob_db *mob, *mob_array[MAX_SEARCH];
+ int count;
+ int i, j, k;
+
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
+ memset(atcmd_output2, '\0', sizeof(atcmd_output2));
+
+ if (!message || !*message) {
+ clif_displaymessage(fd, msg_txt(1239)); // Please enter a monster name/ID (usage: @mobinfo <monster_name_or_monster_ID>).
+ return -1;
+ }
+
+ // If monster identifier/name argument is a name
+ if ((i = mobdb_checkid(atoi(message))))
+ {
+ mob_array[0] = mob_db(i);
+ count = 1;
+ } else
+ count = mobdb_searchname_array(mob_array, MAX_SEARCH, message);
+
+ if (!count) {
+ clif_displaymessage(fd, msg_txt(40)); // Invalid monster ID or name.
+ return -1;
+ }
+
+ if (count > MAX_SEARCH) {
+ sprintf(atcmd_output, msg_txt(269), MAX_SEARCH, count);
+ clif_displaymessage(fd, atcmd_output);
+ count = MAX_SEARCH;
+ }
+ for (k = 0; k < count; k++) {
+ mob = mob_array[k];
+
+ // stats
+ if (mob->mexp)
+ sprintf(atcmd_output, msg_txt(1240), mob->name, mob->jname, mob->sprite, mob->vd.class_); // MVP Monster: '%s'/'%s'/'%s' (%d)
+ else
+ sprintf(atcmd_output, msg_txt(1241), mob->name, mob->jname, mob->sprite, mob->vd.class_); // Monster: '%s'/'%s'/'%s' (%d)
+ clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output, msg_txt(1242), mob->lv, mob->status.max_hp, mob->base_exp, mob->job_exp,MOB_HIT(mob), MOB_FLEE(mob)); // Lv:%d HP:%d Base EXP:%u Job EXP:%u HIT:%d FLEE:%d
+ clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output, msg_txt(1243), // DEF:%d MDEF:%d STR:%d AGI:%d VIT:%d INT:%d DEX:%d LUK:%d
+ mob->status.def, mob->status.mdef,mob->status.str, mob->status.agi,
+ mob->status.vit, mob->status.int_, mob->status.dex, mob->status.luk);
+ clif_displaymessage(fd, atcmd_output);
+
+ sprintf(atcmd_output, msg_txt(1244), // ATK:%d~%d Range:%d~%d~%d Size:%s Race: %s Element: %s (Lv:%d)
+ mob->status.rhw.atk, mob->status.rhw.atk2, mob->status.rhw.range,
+ mob->range2 , mob->range3, msize[mob->status.size],
+ mrace[mob->status.race], melement[mob->status.def_ele], mob->status.ele_lv);
+ clif_displaymessage(fd, atcmd_output);
+ // drops
+ clif_displaymessage(fd, msg_txt(1245)); // Drops:
+ strcpy(atcmd_output, " ");
+ j = 0;
+ for (i = 0; i < MAX_MOB_DROP; i++) {
+ int droprate;
+ if (mob->dropitem[i].nameid <= 0 || mob->dropitem[i].p < 1 || (item_data = itemdb_exists(mob->dropitem[i].nameid)) == NULL)
+ continue;
+ droprate = mob->dropitem[i].p;
+
+ if (item_data->slot)
+ sprintf(atcmd_output2, " - %s[%d] %02.02f%%", item_data->jname, item_data->slot, (float)droprate / 100);
+ else
+ sprintf(atcmd_output2, " - %s %02.02f%%", item_data->jname, (float)droprate / 100);
+ strcat(atcmd_output, atcmd_output2);
+ if (++j % 3 == 0) {
+ clif_displaymessage(fd, atcmd_output);
+ strcpy(atcmd_output, " ");
+ }
+ }
+ if (j == 0)
+ clif_displaymessage(fd, msg_txt(1246)); // This monster has no drops.
+ else if (j % 3 != 0)
+ clif_displaymessage(fd, atcmd_output);
+ // mvp
+ if (mob->mexp) {
+ sprintf(atcmd_output, msg_txt(1247), mob->mexp); // MVP Bonus EXP:%u
+ clif_displaymessage(fd, atcmd_output);
+ strcpy(atcmd_output, msg_txt(1248)); // MVP Items:
+ j = 0;
+ for (i = 0; i < MAX_MVP_DROP; i++) {
+ if (mob->mvpitem[i].nameid <= 0 || (item_data = itemdb_exists(mob->mvpitem[i].nameid)) == NULL)
+ continue;
+ if (mob->mvpitem[i].p > 0) {
+ j++;
+ if (j == 1)
+ sprintf(atcmd_output2, " %s %02.02f%%", item_data->jname, (float)mob->mvpitem[i].p / 100);
+ else
+ sprintf(atcmd_output2, " - %s %02.02f%%", item_data->jname, (float)mob->mvpitem[i].p / 100);
+ strcat(atcmd_output, atcmd_output2);
+ }
+ }
+ if (j == 0)
+ clif_displaymessage(fd, msg_txt(1249)); // This monster has no MVP prizes.
+ else
+ clif_displaymessage(fd, atcmd_output);
+ }
+ }
+ return 0;
}
/*=========================================
@@ -6606,58 +6782,59 @@ ACMD_FUNC(mobinfo)
*------------------------------------------*/
ACMD_FUNC(showmobs)
{
- char mob_name[100];
- int mob_id;
- int number = 0;
- struct s_mapiterator *it;
+ char mob_name[100];
+ int mob_id;
+ int number = 0;
+ struct s_mapiterator* it;
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- if (sscanf(message, "%99[^\n]", mob_name) < 0)
- return -1;
+ 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 > 0 && mobdb_checkid(mob_id) == 0) {
- snprintf(atcmd_output, sizeof atcmd_output, msg_txt(1250),mob_name); // Invalid mob id %s!
- clif_displaymessage(fd, atcmd_output);
- return 0;
- }
+ if((mob_id = atoi(mob_name)) == 0)
+ mob_id = mobdb_searchname(mob_name);
+ if(mob_id > 0 && mobdb_checkid(mob_id) == 0){
+ snprintf(atcmd_output, sizeof atcmd_output, msg_txt(1250),mob_name); // Invalid mob id %s!
+ clif_displaymessage(fd, atcmd_output);
+ return 0;
+ }
- if (mob_db(mob_id)->status.mode&MD_BOSS && !pc_has_permission(sd, PC_PERM_SHOW_BOSS)) { // If player group does not have access to boss mobs.
- clif_displaymessage(fd, msg_txt(1251)); // Can't show boss mobs!
- return 0;
- }
+ if(mob_db(mob_id)->status.mode&MD_BOSS && !pc_has_permission(sd, PC_PERM_SHOW_BOSS)){ // If player group does not have access to boss mobs.
+ clif_displaymessage(fd, msg_txt(1251)); // Can't show boss mobs!
+ 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--
+ 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--
- snprintf(atcmd_output, sizeof atcmd_output, msg_txt(1252), // Mob Search... %s %s
- mob_name, mapindex_id2name(sd->mapindex));
- clif_displaymessage(fd, atcmd_output);
+ snprintf(atcmd_output, sizeof atcmd_output, msg_txt(1252), // Mob Search... %s %s
+ mob_name, mapindex_id2name(sd->mapindex));
+ clif_displaymessage(fd, atcmd_output);
- it = mapit_geteachmob();
- for (;;) {
- TBL_MOB *md = (TBL_MOB *)mapit_next(it);
- if (md == NULL)
- break;// no more mobs
+ it = mapit_geteachmob();
+ for(;;)
+ {
+ TBL_MOB* md = (TBL_MOB*)mapit_next(it);
+ if( md == NULL )
+ break;// no more mobs
- if (md->bl.m != sd->bl.m)
- continue;
- if (mob_id != -1 && md->class_ != mob_id)
- continue;
- if (md->special_state.ai || md->master_id)
- continue; // hide slaves and player summoned mobs
- if (md->spawn_timer != INVALID_TIMER)
- continue; // hide mobs waiting for respawn
+ if( md->bl.m != sd->bl.m )
+ continue;
+ if( mob_id != -1 && md->class_ != mob_id )
+ continue;
+ if( md->special_state.ai || md->master_id )
+ continue; // hide slaves and player summoned mobs
+ if( md->spawn_timer != INVALID_TIMER )
+ continue; // hide mobs waiting for respawn
- ++number;
- clif_viewpoint(sd, 1, 0, md->bl.x, md->bl.y, number, 0xFFFFFF);
- }
- mapit_free(it);
+ ++number;
+ clif_viewpoint(sd, 1, 0, md->bl.x, md->bl.y, number, 0xFFFFFF);
+ }
+ mapit_free(it);
- return 0;
+ return 0;
}
/*==========================================
@@ -6665,31 +6842,31 @@ ACMD_FUNC(showmobs)
*------------------------------------------*/
ACMD_FUNC(homlevel)
{
- TBL_HOM *hd;
- int level = 0, i = 0;
+ TBL_HOM * hd;
+ int level = 0, i = 0;
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- if (!message || !*message || (level = atoi(message)) < 1) {
- clif_displaymessage(fd, msg_txt(1253)); // Please enter a level adjustment (usage: @homlevel <number of levels>).
- return -1;
- }
+ if ( !message || !*message || ( level = atoi(message) ) < 1 ) {
+ clif_displaymessage(fd, msg_txt(1253)); // Please enter a level adjustment (usage: @homlevel <number of levels>).
+ return -1;
+ }
- if (!merc_is_hom_active(sd->hd)) {
- clif_displaymessage(fd, msg_txt(1254)); // You do not have a homunculus.
- return -1;
- }
+ if ( !merc_is_hom_active(sd->hd) ) {
+ clif_displaymessage(fd, msg_txt(1254)); // You do not have a homunculus.
+ return -1;
+ }
- hd = sd->hd;
+ hd = sd->hd;
- for (i = 1; i <= level && hd->exp_next; i++) {
- hd->homunculus.exp += hd->exp_next;
- merc_hom_levelup(hd);
- }
- status_calc_homunculus(hd,0);
- status_percent_heal(&hd->bl, 100, 100);
- clif_specialeffect(&hd->bl,568,AREA);
- return 0;
+ for (i = 1; i <= level && hd->exp_next; i++){
+ hd->homunculus.exp += hd->exp_next;
+ merc_hom_levelup(hd);
+ }
+ status_calc_homunculus(hd,0);
+ status_percent_heal(&hd->bl, 100, 100);
+ clif_specialeffect(&hd->bl,568,AREA);
+ return 0;
}
/*==========================================
@@ -6697,19 +6874,19 @@ ACMD_FUNC(homlevel)
*------------------------------------------*/
ACMD_FUNC(homevolution)
{
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- if (!merc_is_hom_active(sd->hd)) {
- clif_displaymessage(fd, msg_txt(1254)); // You do not have a homunculus.
- return -1;
- }
+ if ( !merc_is_hom_active(sd->hd) ) {
+ clif_displaymessage(fd, msg_txt(1254)); // You do not have a homunculus.
+ return -1;
+ }
- if (!merc_hom_evolution(sd->hd)) {
- clif_displaymessage(fd, msg_txt(1255)); // Your homunculus doesn't evolve.
- return -1;
- }
- clif_homskillinfoblock(sd);
- return 0;
+ if ( !merc_hom_evolution(sd->hd) ) {
+ clif_displaymessage(fd, msg_txt(1255)); // Your homunculus doesn't evolve.
+ return -1;
+ }
+ clif_homskillinfoblock(sd);
+ return 0;
}
/*==========================================
@@ -6717,27 +6894,28 @@ ACMD_FUNC(homevolution)
*------------------------------------------*/
ACMD_FUNC(makehomun)
{
- int homunid;
- nullpo_retr(-1, sd);
+ int homunid;
+ nullpo_retr(-1, sd);
- if (sd->status.hom_id) {
- clif_displaymessage(fd, msg_txt(450));
- return -1;
- }
+ if ( sd->status.hom_id ) {
+ clif_displaymessage(fd, msg_txt(450));
+ return -1;
+ }
- if (!message || !*message) {
- clif_displaymessage(fd, msg_txt(1256)); // Please enter a homunculus ID (usage: @makehomun <homunculus id>).
- return -1;
- }
+ if (!message || !*message) {
+ clif_displaymessage(fd, msg_txt(1256)); // Please enter a homunculus ID (usage: @makehomun <homunculus id>).
+ return -1;
+ }
- homunid = atoi(message);
- if (homunid < HM_CLASS_BASE || homunid > HM_CLASS_BASE + MAX_HOMUNCULUS_CLASS - 1) {
- clif_displaymessage(fd, msg_txt(1257)); // Invalid Homunculus ID.
- return -1;
- }
+ homunid = atoi(message);
+ if( homunid < HM_CLASS_BASE || homunid > HM_CLASS_BASE + MAX_HOMUNCULUS_CLASS - 1 )
+ {
+ clif_displaymessage(fd, msg_txt(1257)); // Invalid Homunculus ID.
+ return -1;
+ }
- merc_create_homunculus_request(sd,homunid);
- return 0;
+ merc_create_homunculus_request(sd,homunid);
+ return 0;
}
/*==========================================
@@ -6745,26 +6923,26 @@ ACMD_FUNC(makehomun)
*------------------------------------------*/
ACMD_FUNC(homfriendly)
{
- int friendly = 0;
+ int friendly = 0;
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- if (!merc_is_hom_active(sd->hd)) {
- clif_displaymessage(fd, msg_txt(1254)); // You do not have a homunculus.
- return -1;
- }
+ if ( !merc_is_hom_active(sd->hd) ) {
+ clif_displaymessage(fd, msg_txt(1254)); // You do not have a homunculus.
+ return -1;
+ }
- if (!message || !*message) {
- clif_displaymessage(fd, msg_txt(1258)); // Please enter a friendly value (usage: @homfriendly <friendly value [0-1000]>).
- return -1;
- }
+ if (!message || !*message) {
+ clif_displaymessage(fd, msg_txt(1258)); // Please enter a friendly value (usage: @homfriendly <friendly value [0-1000]>).
+ return -1;
+ }
- friendly = atoi(message);
- friendly = cap_value(friendly, 0, 1000);
+ friendly = atoi(message);
+ friendly = cap_value(friendly, 0, 1000);
- sd->hd->homunculus.intimacy = friendly * 100 ;
- clif_send_homdata(sd,SP_INTIMATE,friendly);
- return 0;
+ sd->hd->homunculus.intimacy = friendly * 100 ;
+ clif_send_homdata(sd,SP_INTIMATE,friendly);
+ return 0;
}
/*==========================================
@@ -6772,26 +6950,26 @@ ACMD_FUNC(homfriendly)
*------------------------------------------*/
ACMD_FUNC(homhungry)
{
- int hungry = 0;
+ int hungry = 0;
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- if (!merc_is_hom_active(sd->hd)) {
- clif_displaymessage(fd, msg_txt(1254)); // You do not have a homunculus.
- return -1;
- }
+ if ( !merc_is_hom_active(sd->hd) ) {
+ clif_displaymessage(fd, msg_txt(1254)); // You do not have a homunculus.
+ return -1;
+ }
- if (!message || !*message) {
- clif_displaymessage(fd, msg_txt(1259)); // Please enter a hunger value (usage: @homhungry <hunger value [0-100]>).
- return -1;
- }
+ if (!message || !*message) {
+ clif_displaymessage(fd, msg_txt(1259)); // Please enter a hunger value (usage: @homhungry <hunger value [0-100]>).
+ return -1;
+ }
- hungry = atoi(message);
- hungry = cap_value(hungry, 0, 100);
+ hungry = atoi(message);
+ hungry = cap_value(hungry, 0, 100);
- sd->hd->homunculus.hunger = hungry;
- clif_send_homdata(sd,SP_HUNGRY,hungry);
- return 0;
+ sd->hd->homunculus.hunger = hungry;
+ clif_send_homdata(sd,SP_HUNGRY,hungry);
+ return 0;
}
/*==========================================
@@ -6799,35 +6977,35 @@ ACMD_FUNC(homhungry)
*------------------------------------------*/
ACMD_FUNC(homtalk)
{
- char mes[100],temp[100];
+ char mes[100],temp[100];
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- if (battle_config.min_chat_delay) {
- if (DIFF_TICK(sd->cantalk_tick, gettick()) > 0)
- return 0;
- sd->cantalk_tick = gettick() + battle_config.min_chat_delay;
- }
+ if ( battle_config.min_chat_delay ) {
+ if( DIFF_TICK(sd->cantalk_tick, gettick()) > 0 )
+ return 0;
+ sd->cantalk_tick = gettick() + battle_config.min_chat_delay;
+ }
- if (sd->sc.count && //no "chatting" while muted.
- (sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] ||
- (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT)))
- return -1;
+ if (sd->sc.count && //no "chatting" while muted.
+ (sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] ||
+ (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT)))
+ return -1;
- if (!merc_is_hom_active(sd->hd)) {
- clif_displaymessage(fd, msg_txt(1254)); // You do not have a homunculus.
- return -1;
- }
+ if ( !merc_is_hom_active(sd->hd) ) {
+ clif_displaymessage(fd, msg_txt(1254)); // You do not have a homunculus.
+ return -1;
+ }
- if (!message || !*message || sscanf(message, "%99[^\n]", mes) < 1) {
- clif_displaymessage(fd, msg_txt(1260)); // Please enter a message (usage: @homtalk <message>).
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%99[^\n]", mes) < 1) {
+ clif_displaymessage(fd, msg_txt(1260)); // Please enter a message (usage: @homtalk <message>).
+ return -1;
+ }
- snprintf(temp, sizeof temp ,"%s : %s", sd->hd->homunculus.name, mes);
- clif_message(&sd->hd->bl, temp);
+ snprintf(temp, sizeof temp ,"%s : %s", sd->hd->homunculus.name, mes);
+ clif_message(&sd->hd->bl, temp);
- return 0;
+ return 0;
}
/*==========================================
@@ -6835,122 +7013,122 @@ ACMD_FUNC(homtalk)
*------------------------------------------*/
ACMD_FUNC(hominfo)
{
- struct homun_data *hd;
- struct status_data *status;
- nullpo_retr(-1, sd);
+ struct homun_data *hd;
+ struct status_data *status;
+ nullpo_retr(-1, sd);
- if (!merc_is_hom_active(sd->hd)) {
- clif_displaymessage(fd, msg_txt(1254)); // You do not have a homunculus.
- return -1;
- }
+ if ( !merc_is_hom_active(sd->hd) ) {
+ clif_displaymessage(fd, msg_txt(1254)); // You do not have a homunculus.
+ return -1;
+ }
- hd = sd->hd;
- status = status_get_status_data(&hd->bl);
- clif_displaymessage(fd, msg_txt(1261)); // Homunculus stats:
+ hd = sd->hd;
+ status = status_get_status_data(&hd->bl);
+ clif_displaymessage(fd, msg_txt(1261)); // Homunculus stats:
- snprintf(atcmd_output, sizeof(atcmd_output) ,msg_txt(1262), // HP: %d/%d - SP: %d/%d
- status->hp, status->max_hp, status->sp, status->max_sp);
- clif_displaymessage(fd, atcmd_output);
+ snprintf(atcmd_output, sizeof(atcmd_output) ,msg_txt(1262), // HP: %d/%d - SP: %d/%d
+ status->hp, status->max_hp, status->sp, status->max_sp);
+ clif_displaymessage(fd, atcmd_output);
- snprintf(atcmd_output, sizeof(atcmd_output) ,msg_txt(1263), // ATK: %d - MATK: %d~%d
- status->rhw.atk2 +status->batk, status->matk_min, status->matk_max);
- clif_displaymessage(fd, atcmd_output);
+ snprintf(atcmd_output, sizeof(atcmd_output) ,msg_txt(1263), // ATK: %d - MATK: %d~%d
+ status->rhw.atk2 +status->batk, status->matk_min, status->matk_max);
+ clif_displaymessage(fd, atcmd_output);
- snprintf(atcmd_output, sizeof(atcmd_output) ,msg_txt(1264), // Hungry: %d - Intimacy: %u
- hd->homunculus.hunger, hd->homunculus.intimacy/100);
- clif_displaymessage(fd, atcmd_output);
+ snprintf(atcmd_output, sizeof(atcmd_output) ,msg_txt(1264), // Hungry: %d - Intimacy: %u
+ hd->homunculus.hunger, hd->homunculus.intimacy/100);
+ clif_displaymessage(fd, atcmd_output);
- snprintf(atcmd_output, sizeof(atcmd_output) ,
- msg_txt(1265), // Stats: Str %d / Agi %d / Vit %d / Int %d / Dex %d / Luk %d
- status->str, status->agi, status->vit,
- status->int_, status->dex, status->luk);
- clif_displaymessage(fd, atcmd_output);
+ snprintf(atcmd_output, sizeof(atcmd_output) ,
+ msg_txt(1265), // Stats: Str %d / Agi %d / Vit %d / Int %d / Dex %d / Luk %d
+ status->str, status->agi, status->vit,
+ status->int_, status->dex, status->luk);
+ clif_displaymessage(fd, atcmd_output);
- return 0;
+ return 0;
}
ACMD_FUNC(homstats)
{
- struct homun_data *hd;
- struct s_homunculus_db *db;
- struct s_homunculus *hom;
- int lv, min, max, evo;
+ struct homun_data *hd;
+ struct s_homunculus_db *db;
+ struct s_homunculus *hom;
+ int lv, min, max, evo;
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- if (!merc_is_hom_active(sd->hd)) {
- clif_displaymessage(fd, msg_txt(1254)); // You do not have a homunculus.
- return -1;
- }
+ if ( !merc_is_hom_active(sd->hd) ) {
+ clif_displaymessage(fd, msg_txt(1254)); // You do not have a homunculus.
+ return -1;
+ }
- hd = sd->hd;
+ hd = sd->hd;
- hom = &hd->homunculus;
- db = hd->homunculusDB;
- lv = hom->level;
+ hom = &hd->homunculus;
+ db = hd->homunculusDB;
+ lv = hom->level;
- snprintf(atcmd_output, sizeof(atcmd_output) ,
- msg_txt(1266), lv, db->name); // Homunculus growth stats (Lv %d %s):
- clif_displaymessage(fd, atcmd_output);
- lv--; //Since the first increase is at level 2.
+ snprintf(atcmd_output, sizeof(atcmd_output) ,
+ msg_txt(1266), lv, db->name); // Homunculus growth stats (Lv %d %s):
+ clif_displaymessage(fd, atcmd_output);
+ lv--; //Since the first increase is at level 2.
- evo = (hom->class_ == db->evo_class);
- min = db->base.HP +lv*db->gmin.HP +(evo?db->emin.HP:0);
- max = db->base.HP +lv*db->gmax.HP +(evo?db->emax.HP:0);;
- snprintf(atcmd_output, sizeof(atcmd_output) ,msg_txt(1267), hom->max_hp, min, max); // Max HP: %d (%d~%d)
- clif_displaymessage(fd, atcmd_output);
+ evo = (hom->class_ == db->evo_class);
+ min = db->base.HP +lv*db->gmin.HP +(evo?db->emin.HP:0);
+ max = db->base.HP +lv*db->gmax.HP +(evo?db->emax.HP:0);;
+ snprintf(atcmd_output, sizeof(atcmd_output) ,msg_txt(1267), hom->max_hp, min, max); // Max HP: %d (%d~%d)
+ clif_displaymessage(fd, atcmd_output);
- min = db->base.SP +lv*db->gmin.SP +(evo?db->emin.SP:0);
- max = db->base.SP +lv*db->gmax.SP +(evo?db->emax.SP:0);;
- snprintf(atcmd_output, sizeof(atcmd_output) ,msg_txt(1268), hom->max_sp, min, max); // Max SP: %d (%d~%d)
- clif_displaymessage(fd, atcmd_output);
+ min = db->base.SP +lv*db->gmin.SP +(evo?db->emin.SP:0);
+ max = db->base.SP +lv*db->gmax.SP +(evo?db->emax.SP:0);;
+ snprintf(atcmd_output, sizeof(atcmd_output) ,msg_txt(1268), hom->max_sp, min, max); // Max SP: %d (%d~%d)
+ clif_displaymessage(fd, atcmd_output);
- min = db->base.str +lv*(db->gmin.str/10) +(evo?db->emin.str:0);
- max = db->base.str +lv*(db->gmax.str/10) +(evo?db->emax.str:0);;
- snprintf(atcmd_output, sizeof(atcmd_output) ,msg_txt(1269), hom->str/10, min, max); // Str: %d (%d~%d)
- clif_displaymessage(fd, atcmd_output);
+ min = db->base.str +lv*(db->gmin.str/10) +(evo?db->emin.str:0);
+ max = db->base.str +lv*(db->gmax.str/10) +(evo?db->emax.str:0);;
+ snprintf(atcmd_output, sizeof(atcmd_output) ,msg_txt(1269), hom->str/10, min, max); // Str: %d (%d~%d)
+ clif_displaymessage(fd, atcmd_output);
- min = db->base.agi +lv*(db->gmin.agi/10) +(evo?db->emin.agi:0);
- max = db->base.agi +lv*(db->gmax.agi/10) +(evo?db->emax.agi:0);;
- snprintf(atcmd_output, sizeof(atcmd_output) ,msg_txt(1270), hom->agi/10, min, max); // Agi: %d (%d~%d)
- clif_displaymessage(fd, atcmd_output);
+ min = db->base.agi +lv*(db->gmin.agi/10) +(evo?db->emin.agi:0);
+ max = db->base.agi +lv*(db->gmax.agi/10) +(evo?db->emax.agi:0);;
+ snprintf(atcmd_output, sizeof(atcmd_output) ,msg_txt(1270), hom->agi/10, min, max); // Agi: %d (%d~%d)
+ clif_displaymessage(fd, atcmd_output);
- min = db->base.vit +lv*(db->gmin.vit/10) +(evo?db->emin.vit:0);
- max = db->base.vit +lv*(db->gmax.vit/10) +(evo?db->emax.vit:0);;
- snprintf(atcmd_output, sizeof(atcmd_output) ,msg_txt(1271), hom->vit/10, min, max); // Vit: %d (%d~%d)
- clif_displaymessage(fd, atcmd_output);
+ min = db->base.vit +lv*(db->gmin.vit/10) +(evo?db->emin.vit:0);
+ max = db->base.vit +lv*(db->gmax.vit/10) +(evo?db->emax.vit:0);;
+ snprintf(atcmd_output, sizeof(atcmd_output) ,msg_txt(1271), hom->vit/10, min, max); // Vit: %d (%d~%d)
+ clif_displaymessage(fd, atcmd_output);
- min = db->base.int_ +lv*(db->gmin.int_/10) +(evo?db->emin.int_:0);
- max = db->base.int_ +lv*(db->gmax.int_/10) +(evo?db->emax.int_:0);;
- snprintf(atcmd_output, sizeof(atcmd_output) ,msg_txt(1272), hom->int_/10, min, max); // Int: %d (%d~%d)
- clif_displaymessage(fd, atcmd_output);
+ min = db->base.int_ +lv*(db->gmin.int_/10) +(evo?db->emin.int_:0);
+ max = db->base.int_ +lv*(db->gmax.int_/10) +(evo?db->emax.int_:0);;
+ snprintf(atcmd_output, sizeof(atcmd_output) ,msg_txt(1272), hom->int_/10, min, max); // Int: %d (%d~%d)
+ clif_displaymessage(fd, atcmd_output);
- min = db->base.dex +lv*(db->gmin.dex/10) +(evo?db->emin.dex:0);
- max = db->base.dex +lv*(db->gmax.dex/10) +(evo?db->emax.dex:0);;
- snprintf(atcmd_output, sizeof(atcmd_output) ,msg_txt(1273), hom->dex/10, min, max); // Dex: %d (%d~%d)
- clif_displaymessage(fd, atcmd_output);
+ min = db->base.dex +lv*(db->gmin.dex/10) +(evo?db->emin.dex:0);
+ max = db->base.dex +lv*(db->gmax.dex/10) +(evo?db->emax.dex:0);;
+ snprintf(atcmd_output, sizeof(atcmd_output) ,msg_txt(1273), hom->dex/10, min, max); // Dex: %d (%d~%d)
+ clif_displaymessage(fd, atcmd_output);
- min = db->base.luk +lv*(db->gmin.luk/10) +(evo?db->emin.luk:0);
- max = db->base.luk +lv*(db->gmax.luk/10) +(evo?db->emax.luk:0);;
- snprintf(atcmd_output, sizeof(atcmd_output) ,msg_txt(1274), hom->luk/10, min, max); // Luk: %d (%d~%d)
- clif_displaymessage(fd, atcmd_output);
+ min = db->base.luk +lv*(db->gmin.luk/10) +(evo?db->emin.luk:0);
+ max = db->base.luk +lv*(db->gmax.luk/10) +(evo?db->emax.luk:0);;
+ snprintf(atcmd_output, sizeof(atcmd_output) ,msg_txt(1274), hom->luk/10, min, max); // Luk: %d (%d~%d)
+ clif_displaymessage(fd, atcmd_output);
- return 0;
+ return 0;
}
ACMD_FUNC(homshuffle)
{
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- if (!sd->hd)
- return -1; // nothing to do
+ if(!sd->hd)
+ return -1; // nothing to do
- if (!merc_hom_shuffle(sd->hd))
- return -1;
+ if(!merc_hom_shuffle(sd->hd))
+ return -1;
- clif_displaymessage(sd->fd, msg_txt(1275)); // Homunculus stats altered.
- atcommand_homstats(fd, sd, command, message); //Print out the new stats
- return 0;
+ clif_displaymessage(sd->fd, msg_txt(1275)); // Homunculus stats altered.
+ atcommand_homstats(fd, sd, command, message); //Print out the new stats
+ return 0;
}
/*==========================================
@@ -6959,48 +7137,48 @@ ACMD_FUNC(homshuffle)
*------------------------------------------*/
ACMD_FUNC(iteminfo)
{
- struct item_data *item_data, *item_array[MAX_SEARCH];
- int i, count = 1;
-
- if (!message || !*message) {
- clif_displaymessage(fd, msg_txt(1276)); // Please enter an item name/ID (usage: @ii/@iteminfo <item name/ID>).
- return -1;
- }
- if ((item_array[0] = itemdb_exists(atoi(message))) == NULL)
- count = itemdb_searchname_array(item_array, MAX_SEARCH, message);
-
- if (!count) {
- clif_displaymessage(fd, msg_txt(19)); // Invalid item ID or name.
- return -1;
- }
-
- if (count > MAX_SEARCH) {
- sprintf(atcmd_output, msg_txt(269), MAX_SEARCH, count); // Displaying first %d out of %d matches
- clif_displaymessage(fd, atcmd_output);
- count = MAX_SEARCH;
- }
- for (i = 0; i < count; i++) {
- item_data = item_array[i];
- sprintf(atcmd_output, msg_txt(1277), // Item: '%s'/'%s'[%d] (%d) Type: %s | Extra Effect: %s
- item_data->name,item_data->jname,item_data->slot,item_data->nameid,
- itemdb_typename(item_data->type),
- (item_data->script==NULL)? msg_txt(1278) : msg_txt(1279) // None / With script
- );
- clif_displaymessage(fd, atcmd_output);
-
- sprintf(atcmd_output, msg_txt(1280), item_data->value_buy, item_data->value_sell, item_data->weight/10.); // NPC Buy:%dz, Sell:%dz | Weight: %.1f
- clif_displaymessage(fd, atcmd_output);
-
- if (item_data->maxchance == -1)
- strcpy(atcmd_output, msg_txt(1281)); // - Available in the shops only.
- else if (!battle_config.atcommand_mobinfo_type && item_data->maxchance)
- sprintf(atcmd_output, msg_txt(1282), (float)item_data->maxchance / 100); // - Maximal monsters drop chance: %02.02f%%
- else
- strcpy(atcmd_output, msg_txt(1283)); // - Monsters don't drop this item.
- clif_displaymessage(fd, atcmd_output);
-
- }
- return 0;
+ struct item_data *item_data, *item_array[MAX_SEARCH];
+ int i, count = 1;
+
+ if (!message || !*message) {
+ clif_displaymessage(fd, msg_txt(1276)); // Please enter an item name/ID (usage: @ii/@iteminfo <item name/ID>).
+ return -1;
+ }
+ if ((item_array[0] = itemdb_exists(atoi(message))) == NULL)
+ count = itemdb_searchname_array(item_array, MAX_SEARCH, message);
+
+ if (!count) {
+ clif_displaymessage(fd, msg_txt(19)); // Invalid item ID or name.
+ return -1;
+ }
+
+ if (count > MAX_SEARCH) {
+ sprintf(atcmd_output, msg_txt(269), MAX_SEARCH, count); // Displaying first %d out of %d matches
+ clif_displaymessage(fd, atcmd_output);
+ count = MAX_SEARCH;
+ }
+ for (i = 0; i < count; i++) {
+ item_data = item_array[i];
+ sprintf(atcmd_output, msg_txt(1277), // Item: '%s'/'%s'[%d] (%d) Type: %s | Extra Effect: %s
+ item_data->name,item_data->jname,item_data->slot,item_data->nameid,
+ itemdb_typename(item_data->type),
+ (item_data->script==NULL)? msg_txt(1278) : msg_txt(1279) // None / With script
+ );
+ clif_displaymessage(fd, atcmd_output);
+
+ sprintf(atcmd_output, msg_txt(1280), item_data->value_buy, item_data->value_sell, item_data->weight/10. ); // NPC Buy:%dz, Sell:%dz | Weight: %.1f
+ clif_displaymessage(fd, atcmd_output);
+
+ if (item_data->maxchance == -1)
+ strcpy(atcmd_output, msg_txt(1281)); // - Available in the shops only.
+ else if (!battle_config.atcommand_mobinfo_type && item_data->maxchance)
+ sprintf(atcmd_output, msg_txt(1282), (float)item_data->maxchance / 100 ); // - Maximal monsters drop chance: %02.02f%%
+ else
+ strcpy(atcmd_output, msg_txt(1283)); // - Monsters don't drop this item.
+ clif_displaymessage(fd, atcmd_output);
+
+ }
+ return 0;
}
/*==========================================
@@ -7008,91 +7186,94 @@ ACMD_FUNC(iteminfo)
*------------------------------------------*/
ACMD_FUNC(whodrops)
{
- struct item_data *item_data, *item_array[MAX_SEARCH];
- int i,j, count = 1;
-
- if (!message || !*message) {
- clif_displaymessage(fd, msg_txt(1284)); // Please enter item name/ID (usage: @whodrops <item name/ID>).
- return -1;
- }
- if ((item_array[0] = itemdb_exists(atoi(message))) == NULL)
- count = itemdb_searchname_array(item_array, MAX_SEARCH, message);
-
- if (!count) {
- clif_displaymessage(fd, msg_txt(19)); // Invalid item ID or name.
- return -1;
- }
-
- if (count > MAX_SEARCH) {
- sprintf(atcmd_output, msg_txt(269), MAX_SEARCH, count); // Displaying first %d out of %d matches
- clif_displaymessage(fd, atcmd_output);
- count = MAX_SEARCH;
- }
- for (i = 0; i < count; i++) {
- item_data = item_array[i];
- sprintf(atcmd_output, msg_txt(1285), item_data->jname,item_data->slot); // Item: '%s'[%d]
- clif_displaymessage(fd, atcmd_output);
-
- if (item_data->mob[0].chance == 0) {
- strcpy(atcmd_output, msg_txt(1286)); // - Item is not dropped by mobs.
- clif_displaymessage(fd, atcmd_output);
- } else {
- sprintf(atcmd_output, msg_txt(1287), MAX_SEARCH); // - Common mobs with highest drop chance (only max %d are listed):
- clif_displaymessage(fd, atcmd_output);
-
- for (j=0; j < MAX_SEARCH && item_data->mob[j].chance > 0; j++) {
- sprintf(atcmd_output, "- %s (%02.02f%%)", mob_db(item_data->mob[j].id)->jname, item_data->mob[j].chance/100.);
- clif_displaymessage(fd, atcmd_output);
- }
- }
- }
- return 0;
+ struct item_data *item_data, *item_array[MAX_SEARCH];
+ int i,j, count = 1;
+
+ if (!message || !*message) {
+ clif_displaymessage(fd, msg_txt(1284)); // Please enter item name/ID (usage: @whodrops <item name/ID>).
+ return -1;
+ }
+ if ((item_array[0] = itemdb_exists(atoi(message))) == NULL)
+ count = itemdb_searchname_array(item_array, MAX_SEARCH, message);
+
+ if (!count) {
+ clif_displaymessage(fd, msg_txt(19)); // Invalid item ID or name.
+ return -1;
+ }
+
+ if (count > MAX_SEARCH) {
+ sprintf(atcmd_output, msg_txt(269), MAX_SEARCH, count); // Displaying first %d out of %d matches
+ clif_displaymessage(fd, atcmd_output);
+ count = MAX_SEARCH;
+ }
+ for (i = 0; i < count; i++) {
+ item_data = item_array[i];
+ sprintf(atcmd_output, msg_txt(1285), item_data->jname,item_data->slot); // Item: '%s'[%d]
+ clif_displaymessage(fd, atcmd_output);
+
+ if (item_data->mob[0].chance == 0) {
+ strcpy(atcmd_output, msg_txt(1286)); // - Item is not dropped by mobs.
+ clif_displaymessage(fd, atcmd_output);
+ } else {
+ sprintf(atcmd_output, msg_txt(1287), MAX_SEARCH); // - Common mobs with highest drop chance (only max %d are listed):
+ clif_displaymessage(fd, atcmd_output);
+
+ for (j=0; j < MAX_SEARCH && item_data->mob[j].chance > 0; j++)
+ {
+ sprintf(atcmd_output, "- %s (%02.02f%%)", mob_db(item_data->mob[j].id)->jname, item_data->mob[j].chance/100.);
+ clif_displaymessage(fd, atcmd_output);
+ }
+ }
+ }
+ return 0;
}
ACMD_FUNC(whereis)
{
- struct mob_db *mob, *mob_array[MAX_SEARCH];
- int count;
- int i, j, k;
-
- if (!message || !*message) {
- clif_displaymessage(fd, msg_txt(1288)); // Please enter a monster name/ID (usage: @whereis <monster_name_or_monster_ID>).
- return -1;
- }
-
- // If monster identifier/name argument is a name
- if ((i = mobdb_checkid(atoi(message)))) {
- mob_array[0] = mob_db(i);
- count = 1;
- } else
- count = mobdb_searchname_array(mob_array, MAX_SEARCH, message);
-
- if (!count) {
- clif_displaymessage(fd, msg_txt(40)); // Invalid monster ID or name.
- return -1;
- }
-
- if (count > MAX_SEARCH) {
- sprintf(atcmd_output, msg_txt(269), MAX_SEARCH, count);
- clif_displaymessage(fd, atcmd_output);
- count = MAX_SEARCH;
- }
- for (k = 0; k < count; k++) {
- mob = mob_array[k];
- snprintf(atcmd_output, sizeof atcmd_output, msg_txt(1289), mob->jname); // %s spawns in:
- clif_displaymessage(fd, atcmd_output);
-
- for (i = 0; i < ARRAYLENGTH(mob->spawn) && mob->spawn[i].qty; i++) {
- j = map_mapindex2mapid(mob->spawn[i].mapindex);
- if (j < 0) continue;
- snprintf(atcmd_output, sizeof atcmd_output, "%s (%d)", map[j].name, mob->spawn[i].qty);
- clif_displaymessage(fd, atcmd_output);
- }
- if (i == 0)
- clif_displaymessage(fd, msg_txt(1290)); // This monster does not spawn normally.
- }
-
- return 0;
+ struct mob_db *mob, *mob_array[MAX_SEARCH];
+ int count;
+ int i, j, k;
+
+ if (!message || !*message) {
+ clif_displaymessage(fd, msg_txt(1288)); // Please enter a monster name/ID (usage: @whereis <monster_name_or_monster_ID>).
+ return -1;
+ }
+
+ // If monster identifier/name argument is a name
+ if ((i = mobdb_checkid(atoi(message))))
+ {
+ mob_array[0] = mob_db(i);
+ count = 1;
+ } else
+ count = mobdb_searchname_array(mob_array, MAX_SEARCH, message);
+
+ if (!count) {
+ clif_displaymessage(fd, msg_txt(40)); // Invalid monster ID or name.
+ return -1;
+ }
+
+ if (count > MAX_SEARCH) {
+ sprintf(atcmd_output, msg_txt(269), MAX_SEARCH, count);
+ clif_displaymessage(fd, atcmd_output);
+ count = MAX_SEARCH;
+ }
+ for (k = 0; k < count; k++) {
+ mob = mob_array[k];
+ snprintf(atcmd_output, sizeof atcmd_output, msg_txt(1289), mob->jname); // %s spawns in:
+ clif_displaymessage(fd, atcmd_output);
+
+ for (i = 0; i < ARRAYLENGTH(mob->spawn) && mob->spawn[i].qty; i++)
+ {
+ j = map_mapindex2mapid(mob->spawn[i].mapindex);
+ if (j < 0) continue;
+ snprintf(atcmd_output, sizeof atcmd_output, "%s (%d)", map[j].name, mob->spawn[i].qty);
+ clif_displaymessage(fd, atcmd_output);
+ }
+ if (i == 0)
+ clif_displaymessage(fd, msg_txt(1290)); // This monster does not spawn normally.
+ }
+
+ return 0;
}
/*==========================================
@@ -7101,57 +7282,57 @@ ACMD_FUNC(whereis)
*------------------------------------------*/
ACMD_FUNC(adopt)
{
- struct map_session_data *pl_sd1, *pl_sd2, *pl_sd3;
- char player1[NAME_LENGTH], player2[NAME_LENGTH], player3[NAME_LENGTH];
- char output[CHAT_SIZE_MAX];
+ struct map_session_data *pl_sd1, *pl_sd2, *pl_sd3;
+ char player1[NAME_LENGTH], player2[NAME_LENGTH], player3[NAME_LENGTH];
+ char output[CHAT_SIZE_MAX];
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- if (!message || !*message || sscanf(message, "%23[^,],%23[^,],%23[^\r\n]", player1, player2, player3) < 3) {
- clif_displaymessage(fd, msg_txt(1291)); // Usage: @adopt <father>,<mother>,<child>
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%23[^,],%23[^,],%23[^\r\n]", player1, player2, player3) < 3) {
+ clif_displaymessage(fd, msg_txt(1291)); // Usage: @adopt <father>,<mother>,<child>
+ return -1;
+ }
- if (battle_config.etc_log)
- ShowInfo(msg_txt(1292),player1,player2,player3); // Adopting: --%s--%s--%s--\n
+ if (battle_config.etc_log)
+ ShowInfo(msg_txt(1292),player1,player2,player3); // Adopting: --%s--%s--%s--\n
- if ((pl_sd1=map_nick2sd((char *) player1)) == NULL) {
- sprintf(output, msg_txt(1293), player1); // Cannot find player %s online.
- clif_displaymessage(fd, output);
- return -1;
- }
+ if((pl_sd1=map_nick2sd((char *) player1)) == NULL) {
+ sprintf(output, msg_txt(1293), player1); // Cannot find player %s online.
+ clif_displaymessage(fd, output);
+ return -1;
+ }
- if ((pl_sd2=map_nick2sd((char *) player2)) == NULL) {
- sprintf(output, msg_txt(1293), player2); // Cannot find player %s online.
- clif_displaymessage(fd, output);
- return -1;
- }
+ if((pl_sd2=map_nick2sd((char *) player2)) == NULL) {
+ sprintf(output, msg_txt(1293), player2); // Cannot find player %s online.
+ clif_displaymessage(fd, output);
+ return -1;
+ }
- if ((pl_sd3=map_nick2sd((char *) player3)) == NULL) {
- sprintf(output, msg_txt(1293), player3); // Cannot find player %s online.
- clif_displaymessage(fd, output);
- return -1;
- }
+ if((pl_sd3=map_nick2sd((char *) player3)) == NULL) {
+ sprintf(output, msg_txt(1293), player3); // Cannot find player %s online.
+ clif_displaymessage(fd, output);
+ return -1;
+ }
- if (!pc_adoption(pl_sd1, pl_sd2, pl_sd3)) {
- return -1;
- }
+ if( !pc_adoption(pl_sd1, pl_sd2, pl_sd3) ) {
+ return -1;
+ }
- clif_displaymessage(fd, msg_txt(1294)); // They are family... wish them luck.
- return 0;
+ clif_displaymessage(fd, msg_txt(1294)); // They are family... wish them luck.
+ return 0;
}
ACMD_FUNC(version)
{
- const char *revision;
+ const char * revision;
- if ((revision = get_svn_revision()) != 0) {
- sprintf(atcmd_output,msg_txt(1295),revision); // rAthena Version SVN r%s
- clif_displaymessage(fd,atcmd_output);
- } else
- clif_displaymessage(fd,msg_txt(1296)); // Cannot determine SVN revision.
+ if ((revision = get_svn_revision()) != 0) {
+ sprintf(atcmd_output,msg_txt(1295),revision); // rAthena Version SVN r%s
+ clif_displaymessage(fd,atcmd_output);
+ } else
+ clif_displaymessage(fd,msg_txt(1296)); // Cannot determine SVN revision.
- return 0;
+ return 0;
}
/*==========================================
@@ -7160,65 +7341,65 @@ ACMD_FUNC(version)
static int atcommand_mutearea_sub(struct block_list *bl,va_list ap)
{
- int time, id;
- struct map_session_data *pl_sd = (struct map_session_data *)bl;
- if (pl_sd == NULL)
- return 0;
+ int time, id;
+ struct map_session_data *pl_sd = (struct map_session_data *)bl;
+ if (pl_sd == NULL)
+ return 0;
- id = va_arg(ap, int);
- time = va_arg(ap, int);
+ id = va_arg(ap, int);
+ time = va_arg(ap, int);
- if (id != bl->id && !pc_get_group_level(pl_sd)) {
- pl_sd->status.manner -= time;
- if (pl_sd->status.manner < 0)
- sc_start(&pl_sd->bl,SC_NOCHAT,100,0,0);
- else
- status_change_end(&pl_sd->bl, SC_NOCHAT, INVALID_TIMER);
- }
- return 0;
+ if (id != bl->id && !pc_get_group_level(pl_sd)) {
+ pl_sd->status.manner -= time;
+ if (pl_sd->status.manner < 0)
+ sc_start(&pl_sd->bl,SC_NOCHAT,100,0,0);
+ else
+ status_change_end(&pl_sd->bl, SC_NOCHAT, INVALID_TIMER);
+ }
+ return 0;
}
ACMD_FUNC(mutearea)
{
- int time;
- nullpo_ret(sd);
+ int time;
+ nullpo_ret(sd);
- if (!message || !*message) {
- clif_displaymessage(fd, msg_txt(1297)); // Please enter a time in minutes (usage: @mutearea/@stfu <time in minutes>).
- return -1;
- }
+ if (!message || !*message) {
+ clif_displaymessage(fd, msg_txt(1297)); // Please enter a time in minutes (usage: @mutearea/@stfu <time in minutes>).
+ return -1;
+ }
- time = atoi(message);
+ time = atoi(message);
- map_foreachinarea(atcommand_mutearea_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_PC, sd->bl.id, time);
+ map_foreachinarea(atcommand_mutearea_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_PC, sd->bl.id, time);
- return 0;
+ return 0;
}
ACMD_FUNC(rates)
{
- char buf[CHAT_SIZE_MAX];
+ char buf[CHAT_SIZE_MAX];
- nullpo_ret(sd);
- memset(buf, '\0', sizeof(buf));
+ nullpo_ret(sd);
+ memset(buf, '\0', sizeof(buf));
- snprintf(buf, CHAT_SIZE_MAX, msg_txt(1298), // Experience rates: Base %.2fx / Job %.2fx
- battle_config.base_exp_rate/100., battle_config.job_exp_rate/100.);
- clif_displaymessage(fd, buf);
- snprintf(buf, CHAT_SIZE_MAX, msg_txt(1299), // Normal Drop Rates: Common %.2fx / Healing %.2fx / Usable %.2fx / Equipment %.2fx / Card %.2fx
- battle_config.item_rate_common/100., battle_config.item_rate_heal/100., battle_config.item_rate_use/100., battle_config.item_rate_equip/100., battle_config.item_rate_card/100.);
- clif_displaymessage(fd, buf);
- snprintf(buf, CHAT_SIZE_MAX, msg_txt(1300), // Boss Drop Rates: Common %.2fx / Healing %.2fx / Usable %.2fx / Equipment %.2fx / Card %.2fx
- battle_config.item_rate_common_boss/100., battle_config.item_rate_heal_boss/100., battle_config.item_rate_use_boss/100., battle_config.item_rate_equip_boss/100., battle_config.item_rate_card_boss/100.);
- clif_displaymessage(fd, buf);
- snprintf(buf, CHAT_SIZE_MAX, msg_txt(1301), // Other Drop Rates: MvP %.2fx / Card-Based %.2fx / Treasure %.2fx
- battle_config.item_rate_mvp/100., battle_config.item_rate_adddrop/100., battle_config.item_rate_treasure/100.);
- clif_displaymessage(fd, buf);
+ snprintf(buf, CHAT_SIZE_MAX, msg_txt(1298), // Experience rates: Base %.2fx / Job %.2fx
+ battle_config.base_exp_rate/100., battle_config.job_exp_rate/100.);
+ clif_displaymessage(fd, buf);
+ snprintf(buf, CHAT_SIZE_MAX, msg_txt(1299), // Normal Drop Rates: Common %.2fx / Healing %.2fx / Usable %.2fx / Equipment %.2fx / Card %.2fx
+ battle_config.item_rate_common/100., battle_config.item_rate_heal/100., battle_config.item_rate_use/100., battle_config.item_rate_equip/100., battle_config.item_rate_card/100.);
+ clif_displaymessage(fd, buf);
+ snprintf(buf, CHAT_SIZE_MAX, msg_txt(1300), // Boss Drop Rates: Common %.2fx / Healing %.2fx / Usable %.2fx / Equipment %.2fx / Card %.2fx
+ battle_config.item_rate_common_boss/100., battle_config.item_rate_heal_boss/100., battle_config.item_rate_use_boss/100., battle_config.item_rate_equip_boss/100., battle_config.item_rate_card_boss/100.);
+ clif_displaymessage(fd, buf);
+ snprintf(buf, CHAT_SIZE_MAX, msg_txt(1301), // Other Drop Rates: MvP %.2fx / Card-Based %.2fx / Treasure %.2fx
+ battle_config.item_rate_mvp/100., battle_config.item_rate_adddrop/100., battle_config.item_rate_treasure/100.);
+ clif_displaymessage(fd, buf);
- return 0;
+ return 0;
}
/*==========================================
@@ -7227,26 +7408,26 @@ ACMD_FUNC(rates)
*------------------------------------------*/
ACMD_FUNC(me)
{
- char tempmes[CHAT_SIZE_MAX];
- nullpo_retr(-1, sd);
+ char tempmes[CHAT_SIZE_MAX];
+ nullpo_retr(-1, sd);
- memset(tempmes, '\0', sizeof(tempmes));
- memset(atcmd_output, '\0', sizeof(atcmd_output));
+ memset(tempmes, '\0', sizeof(tempmes));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
- if (sd->sc.count && //no "chatting" while muted.
- (sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] ||
- (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT)))
- return -1;
+ if (sd->sc.count && //no "chatting" while muted.
+ (sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] ||
+ (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT)))
+ return -1;
- if (!message || !*message || sscanf(message, "%199[^\n]", tempmes) < 0) {
- clif_displaymessage(fd, msg_txt(1302)); // Please enter a message (usage: @me <message>).
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%199[^\n]", tempmes) < 0) {
+ clif_displaymessage(fd, msg_txt(1302)); // Please enter a message (usage: @me <message>).
+ return -1;
+ }
- sprintf(atcmd_output, msg_txt(270), sd->status.name, tempmes); // *%s %s*
- clif_disp_overhead(sd, atcmd_output);
+ sprintf(atcmd_output, msg_txt(270), sd->status.name, tempmes); // *%s %s*
+ clif_disp_overhead(sd, atcmd_output);
- return 0;
+ return 0;
}
@@ -7256,95 +7437,95 @@ ACMD_FUNC(me)
*------------------------------------------*/
ACMD_FUNC(size)
{
- int size = 0;
- nullpo_retr(-1, sd);
+ int size = 0;
+ nullpo_retr(-1, sd);
- size = cap_value(atoi(message),SZ_SMALL,SZ_BIG);
+ size = cap_value(atoi(message),SZ_SMALL,SZ_BIG);
- if (sd->state.size) {
- sd->state.size = SZ_SMALL;
- pc_setpos(sd, sd->mapindex, sd->bl.x, sd->bl.y, CLR_TELEPORT);
- }
+ if(sd->state.size) {
+ sd->state.size = SZ_SMALL;
+ pc_setpos(sd, sd->mapindex, sd->bl.x, sd->bl.y, CLR_TELEPORT);
+ }
- sd->state.size = size;
- if (size == SZ_MEDIUM)
- clif_specialeffect(&sd->bl,420,AREA);
- else if (size == SZ_BIG)
- clif_specialeffect(&sd->bl,422,AREA);
+ sd->state.size = size;
+ if( size == SZ_MEDIUM )
+ clif_specialeffect(&sd->bl,420,AREA);
+ else if( size == SZ_BIG )
+ clif_specialeffect(&sd->bl,422,AREA);
- clif_displaymessage(fd, msg_txt(1303)); // Size change applied.
- return 0;
+ clif_displaymessage(fd, msg_txt(1303)); // Size change applied.
+ return 0;
}
ACMD_FUNC(sizeall)
{
- int size;
- struct map_session_data *pl_sd;
- struct s_mapiterator *iter;
+ int size;
+ struct map_session_data *pl_sd;
+ struct s_mapiterator* iter;
- size = atoi(message);
- size = cap_value(size,0,2);
+ size = atoi(message);
+ size = cap_value(size,0,2);
- iter = mapit_getallusers();
- for (pl_sd = (TBL_PC *)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC *)mapit_next(iter)) {
- if (pl_sd->state.size != size) {
- if (pl_sd->state.size) {
- pl_sd->state.size = SZ_SMALL;
- pc_setpos(pl_sd, pl_sd->mapindex, pl_sd->bl.x, pl_sd->bl.y, CLR_TELEPORT);
- }
+ iter = mapit_getallusers();
+ for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) ) {
+ if( pl_sd->state.size != size ) {
+ if( pl_sd->state.size ) {
+ pl_sd->state.size = SZ_SMALL;
+ pc_setpos(pl_sd, pl_sd->mapindex, pl_sd->bl.x, pl_sd->bl.y, CLR_TELEPORT);
+ }
- pl_sd->state.size = size;
- if (size == SZ_MEDIUM)
- clif_specialeffect(&pl_sd->bl,420,AREA);
- else if (size == SZ_BIG)
- clif_specialeffect(&pl_sd->bl,422,AREA);
- }
- }
- mapit_free(iter);
+ pl_sd->state.size = size;
+ if( size == SZ_MEDIUM )
+ clif_specialeffect(&pl_sd->bl,420,AREA);
+ else if( size == SZ_BIG )
+ clif_specialeffect(&pl_sd->bl,422,AREA);
+ }
+ }
+ mapit_free(iter);
- clif_displaymessage(fd, msg_txt(1303)); // Size change applied.
- return 0;
+ clif_displaymessage(fd, msg_txt(1303)); // Size change applied.
+ return 0;
}
ACMD_FUNC(sizeguild)
{
- int size = 0, i;
- char guild[NAME_LENGTH];
- struct map_session_data *pl_sd;
- struct guild *g;
- nullpo_retr(-1, sd);
+ int size = 0, i;
+ char guild[NAME_LENGTH];
+ struct map_session_data *pl_sd;
+ struct guild *g;
+ nullpo_retr(-1, sd);
- memset(guild, '\0', sizeof(guild));
+ memset(guild, '\0', sizeof(guild));
- if (!message || !*message || sscanf(message, "%d %23[^\n]", &size, guild) < 2) {
- clif_displaymessage(fd, msg_txt(1304)); // Please enter guild name/ID (usage: @sizeguild <size> <guild name/ID>).
- return -1;
- }
+ if( !message || !*message || sscanf(message, "%d %23[^\n]", &size, guild) < 2 ) {
+ clif_displaymessage(fd, msg_txt(1304)); // Please enter guild name/ID (usage: @sizeguild <size> <guild name/ID>).
+ return -1;
+ }
- if ((g = guild_searchname(guild)) == NULL && (g = guild_search(atoi(guild))) == NULL) {
- clif_displaymessage(fd, msg_txt(94)); // Incorrect name/ID, or no one from the guild is online.
- return -1;
- }
+ if( (g = guild_searchname(guild)) == NULL && (g = guild_search(atoi(guild))) == NULL ) {
+ clif_displaymessage(fd, msg_txt(94)); // Incorrect name/ID, or no one from the guild is online.
+ return -1;
+ }
- size = cap_value(size,SZ_SMALL,SZ_BIG);
+ size = cap_value(size,SZ_SMALL,SZ_BIG);
- for (i = 0; i < g->max_member; i++) {
- if ((pl_sd = g->member[i].sd) && pl_sd->state.size != size) {
- if (pl_sd->state.size) {
- pl_sd->state.size = SZ_SMALL;
- pc_setpos(pl_sd, pl_sd->mapindex, pl_sd->bl.x, pl_sd->bl.y, CLR_TELEPORT);
- }
+ for( i = 0; i < g->max_member; i++ ) {
+ if( (pl_sd = g->member[i].sd) && pl_sd->state.size != size ) {
+ if( pl_sd->state.size ) {
+ pl_sd->state.size = SZ_SMALL;
+ pc_setpos(pl_sd, pl_sd->mapindex, pl_sd->bl.x, pl_sd->bl.y, CLR_TELEPORT);
+ }
- pl_sd->state.size = size;
- if (size == SZ_MEDIUM)
- clif_specialeffect(&pl_sd->bl,420,AREA);
- else if (size == SZ_BIG)
- clif_specialeffect(&pl_sd->bl,422,AREA);
- }
- }
+ pl_sd->state.size = size;
+ if( size == SZ_MEDIUM )
+ clif_specialeffect(&pl_sd->bl,420,AREA);
+ else if( size == SZ_BIG )
+ clif_specialeffect(&pl_sd->bl,422,AREA);
+ }
+ }
- clif_displaymessage(fd, msg_txt(1303)); // Size change applied.
- return 0;
+ clif_displaymessage(fd, msg_txt(1303)); // Size change applied.
+ return 0;
}
/*==========================================
@@ -7353,17 +7534,17 @@ ACMD_FUNC(sizeguild)
*------------------------------------------*/
ACMD_FUNC(monsterignore)
{
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- if (!sd->state.monster_ignore) {
- sd->state.monster_ignore = 1;
- clif_displaymessage(sd->fd, msg_txt(1305)); // You are now immune to attacks.
- } else {
- sd->state.monster_ignore = 0;
- clif_displaymessage(sd->fd, msg_txt(1306)); // Returned to normal state.
- }
+ if (!sd->state.monster_ignore) {
+ sd->state.monster_ignore = 1;
+ clif_displaymessage(sd->fd, msg_txt(1305)); // You are now immune to attacks.
+ } else {
+ sd->state.monster_ignore = 0;
+ clif_displaymessage(sd->fd, msg_txt(1306)); // Returned to normal state.
+ }
- return 0;
+ return 0;
}
/*==========================================
* @fakename
@@ -7371,169 +7552,103 @@ ACMD_FUNC(monsterignore)
*------------------------------------------*/
ACMD_FUNC(fakename)
{
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- if (!message || !*message) {
- if (sd->fakename[0]) {
- sd->fakename[0] = '\0';
- clif_charnameack(0, &sd->bl);
- clif_displaymessage(sd->fd, msg_txt(1307)); // Returned to real name.
- return 0;
- }
+ if( !message || !*message )
+ {
+ if( sd->fakename[0] )
+ {
+ sd->fakename[0] = '\0';
+ clif_charnameack(0, &sd->bl);
+ clif_displaymessage(sd->fd, msg_txt(1307)); // Returned to real name.
+ return 0;
+ }
- clif_displaymessage(sd->fd, msg_txt(1308)); // You must enter a name.
- return -1;
- }
+ clif_displaymessage(sd->fd, msg_txt(1308)); // You must enter a name.
+ return -1;
+ }
- if (strlen(message) < 2) {
- clif_displaymessage(sd->fd, msg_txt(1309)); // Fake name must be at least two characters.
- return -1;
- }
+ if( strlen(message) < 2 )
+ {
+ clif_displaymessage(sd->fd, msg_txt(1309)); // Fake name must be at least two characters.
+ return -1;
+ }
- safestrncpy(sd->fakename, message, sizeof(sd->fakename));
- clif_charnameack(0, &sd->bl);
- clif_displaymessage(sd->fd, msg_txt(1310)); // Fake name enabled.
+ safestrncpy(sd->fakename, message, sizeof(sd->fakename));
+ clif_charnameack(0, &sd->bl);
+ clif_displaymessage(sd->fd, msg_txt(1310)); // Fake name enabled.
- return 0;
+ return 0;
}
/*==========================================
* Ragnarok Resources
*------------------------------------------*/
-ACMD_FUNC(mapflag)
-{
+ACMD_FUNC(mapflag) {
#define checkflag( cmd ) if ( map[ sd->bl.m ].flag.cmd ) clif_displaymessage(sd->fd,#cmd)
#define setflag( cmd ) \
- if ( strcmp( flag_name , #cmd ) == 0 ){\
- map[ sd->bl.m ].flag.cmd = flag;\
- sprintf(atcmd_output,"[ @mapflag ] %s flag has been set to %s",#cmd,flag?"On":"Off");\
- clif_displaymessage(sd->fd,atcmd_output);\
- return 0;\
- }
- char flag_name[100];
- int flag=0,i;
- nullpo_retr(-1, sd);
- memset(flag_name, '\0', sizeof(flag_name));
-
- if (!message || !*message || (sscanf(message, "%99s %d", flag_name, &flag) < 1)) {
- clif_displaymessage(sd->fd,msg_txt(1311)); // Enabled Mapflags in this map:
- clif_displaymessage(sd->fd,"----------------------------------");
- checkflag(autotrade);
- checkflag(allowks);
- checkflag(nomemo);
- checkflag(noteleport);
- checkflag(noreturn);
- checkflag(monster_noteleport);
- checkflag(nosave);
- checkflag(nobranch);
- checkflag(noexppenalty);
- checkflag(pvp);
- checkflag(pvp_noparty);
- checkflag(pvp_noguild);
- checkflag(pvp_nightmaredrop);
- checkflag(pvp_nocalcrank);
- checkflag(gvg_castle);
- checkflag(gvg);
- checkflag(gvg_dungeon);
- checkflag(gvg_noparty);
- checkflag(battleground);
- checkflag(nozenypenalty);
- checkflag(notrade);
- checkflag(noskill);
- checkflag(nowarp);
- checkflag(nowarpto);
- checkflag(noicewall);
- checkflag(snow);
- checkflag(clouds);
- checkflag(clouds2);
- checkflag(fog);
- checkflag(fireworks);
- checkflag(sakura);
- checkflag(leaves);
- checkflag(nogo);
- checkflag(nobaseexp);
- checkflag(nojobexp);
- checkflag(nomobloot);
- checkflag(nomvploot);
- checkflag(nightenabled);
- checkflag(restricted);
- checkflag(nodrop);
- checkflag(novending);
- checkflag(loadevent);
- checkflag(nochat);
- checkflag(partylock);
- checkflag(guildlock);
- checkflag(src4instance);
- clif_displaymessage(sd->fd," ");
- clif_displaymessage(sd->fd,msg_txt(1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On)
- clif_displaymessage(sd->fd,msg_txt(1313)); // Type "@mapflag available" to list the available mapflags.
- return 1;
- }
- for (i = 0; flag_name[i]; i++) flag_name[i] = tolower(flag_name[i]); //lowercase
-
- setflag(autotrade);
- setflag(allowks);
- setflag(nomemo);
- setflag(noteleport);
- setflag(noreturn);
- setflag(monster_noteleport);
- setflag(nosave);
- setflag(nobranch);
- setflag(noexppenalty);
- setflag(pvp);
- setflag(pvp_noparty);
- setflag(pvp_noguild);
- setflag(pvp_nightmaredrop);
- setflag(pvp_nocalcrank);
- setflag(gvg_castle);
- setflag(gvg);
- setflag(gvg_dungeon);
- setflag(gvg_noparty);
- setflag(battleground);
- setflag(nozenypenalty);
- setflag(notrade);
- setflag(noskill);
- setflag(nowarp);
- setflag(nowarpto);
- setflag(noicewall);
- setflag(snow);
- setflag(clouds);
- setflag(clouds2);
- setflag(fog);
- setflag(fireworks);
- setflag(sakura);
- setflag(leaves);
- setflag(nogo);
- setflag(nobaseexp);
- setflag(nojobexp);
- setflag(nomobloot);
- setflag(nomvploot);
- setflag(nightenabled);
- setflag(restricted);
- setflag(nodrop);
- setflag(novending);
- setflag(loadevent);
- setflag(nochat);
- setflag(partylock);
- setflag(guildlock);
- setflag(src4instance);
-
- clif_displaymessage(sd->fd,msg_txt(1314)); // Invalid flag name or flag.
- clif_displaymessage(sd->fd,msg_txt(1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On)
- clif_displaymessage(sd->fd,msg_txt(1315)); // Available Flags:
- clif_displaymessage(sd->fd,"----------------------------------");
- clif_displaymessage(sd->fd,"town, autotrade, allowks, nomemo, noteleport, noreturn, monster_noteleport, nosave,");
- clif_displaymessage(sd->fd,"nobranch, noexppenalty, pvp, pvp_noparty, pvp_noguild, pvp_nightmaredrop,");
- clif_displaymessage(sd->fd,"pvp_nocalcrank, gvg_castle, gvg, gvg_dungeon, gvg_noparty, battleground,");
- clif_displaymessage(sd->fd,"nozenypenalty, notrade, noskill, nowarp, nowarpto, noicewall, snow, clouds, clouds2,");
- clif_displaymessage(sd->fd,"fog, fireworks, sakura, leaves, nogo, nobaseexp, nojobexp, nomobloot,");
- clif_displaymessage(sd->fd,"nomvploot, nightenabled, restricted, nodrop, novending, loadevent, nochat, partylock,");
- clif_displaymessage(sd->fd,"guildlock, src4instance");
+ if ( strcmp( flag_name , #cmd ) == 0 ){\
+ map[ sd->bl.m ].flag.cmd = flag;\
+ sprintf(atcmd_output,"[ @mapflag ] %s flag has been set to %s",#cmd,flag?"On":"Off");\
+ clif_displaymessage(sd->fd,atcmd_output);\
+ return 0;\
+ }
+ unsigned char flag_name[100];
+ int flag=0,i;
+ nullpo_retr(-1, sd);
+ memset(flag_name, '\0', sizeof(flag_name));
+
+ if (!message || !*message || (sscanf(message, "%99s %d", flag_name, &flag) < 1)) {
+ clif_displaymessage(sd->fd,msg_txt(1311)); // Enabled Mapflags in this map:
+ clif_displaymessage(sd->fd,"----------------------------------");
+ checkflag(autotrade); checkflag(allowks); checkflag(nomemo); checkflag(noteleport);
+ checkflag(noreturn); checkflag(monster_noteleport); checkflag(nosave); checkflag(nobranch);
+ checkflag(noexppenalty); checkflag(pvp); checkflag(pvp_noparty); checkflag(pvp_noguild);
+ checkflag(pvp_nightmaredrop); checkflag(pvp_nocalcrank); checkflag(gvg_castle); checkflag(gvg);
+ checkflag(gvg_dungeon); checkflag(gvg_noparty); checkflag(battleground);checkflag(nozenypenalty);
+ checkflag(notrade); checkflag(noskill); checkflag(nowarp); checkflag(nowarpto);
+ checkflag(noicewall); checkflag(snow); checkflag(clouds); checkflag(clouds2);
+ checkflag(fog); checkflag(fireworks); checkflag(sakura); checkflag(leaves);
+ checkflag(nogo); checkflag(nobaseexp);
+ checkflag(nojobexp); checkflag(nomobloot); checkflag(nomvploot); checkflag(nightenabled);
+ checkflag(restricted); checkflag(nodrop); checkflag(novending); checkflag(loadevent);
+ checkflag(nochat); checkflag(partylock); checkflag(guildlock); checkflag(src4instance);
+ clif_displaymessage(sd->fd," ");
+ clif_displaymessage(sd->fd,msg_txt(1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On)
+ clif_displaymessage(sd->fd,msg_txt(1313)); // Type "@mapflag available" to list the available mapflags.
+ return 1;
+ }
+ for (i = 0; flag_name[i]; i++) flag_name[i] = tolower(flag_name[i]); //lowercase
+
+ setflag(autotrade); setflag(allowks); setflag(nomemo); setflag(noteleport);
+ setflag(noreturn); setflag(monster_noteleport);setflag(nosave); setflag(nobranch);
+ setflag(noexppenalty); setflag(pvp); setflag(pvp_noparty); setflag(pvp_noguild);
+ setflag(pvp_nightmaredrop); setflag(pvp_nocalcrank); setflag(gvg_castle); setflag(gvg);
+ setflag(gvg_dungeon); setflag(gvg_noparty); setflag(battleground); setflag(nozenypenalty);
+ setflag(notrade); setflag(noskill); setflag(nowarp); setflag(nowarpto);
+ setflag(noicewall); setflag(snow); setflag(clouds); setflag(clouds2);
+ setflag(fog); setflag(fireworks); setflag(sakura); setflag(leaves);
+ setflag(nogo); setflag(nobaseexp);
+ setflag(nojobexp); setflag(nomobloot); setflag(nomvploot); setflag(nightenabled);
+ setflag(restricted); setflag(nodrop); setflag(novending); setflag(loadevent);
+ setflag(nochat); setflag(partylock); setflag(guildlock); setflag(src4instance);
+
+ clif_displaymessage(sd->fd,msg_txt(1314)); // Invalid flag name or flag.
+ clif_displaymessage(sd->fd,msg_txt(1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On)
+ clif_displaymessage(sd->fd,msg_txt(1315)); // Available Flags:
+ clif_displaymessage(sd->fd,"----------------------------------");
+ clif_displaymessage(sd->fd,"town, autotrade, allowks, nomemo, noteleport, noreturn, monster_noteleport, nosave,");
+ clif_displaymessage(sd->fd,"nobranch, noexppenalty, pvp, pvp_noparty, pvp_noguild, pvp_nightmaredrop,");
+ clif_displaymessage(sd->fd,"pvp_nocalcrank, gvg_castle, gvg, gvg_dungeon, gvg_noparty, battleground,");
+ clif_displaymessage(sd->fd,"nozenypenalty, notrade, noskill, nowarp, nowarpto, noicewall, snow, clouds, clouds2,");
+ clif_displaymessage(sd->fd,"fog, fireworks, sakura, leaves, nogo, nobaseexp, nojobexp, nomobloot,");
+ clif_displaymessage(sd->fd,"nomvploot, nightenabled, restricted, nodrop, novending, loadevent, nochat, partylock,");
+ clif_displaymessage(sd->fd,"guildlock, src4instance");
#undef checkflag
#undef setflag
- return 0;
+ return 0;
}
/*===================================
@@ -7541,41 +7656,41 @@ ACMD_FUNC(mapflag)
*-----------------------------------*/
ACMD_FUNC(showexp)
{
- if (sd->state.showexp) {
- sd->state.showexp = 0;
- clif_displaymessage(fd, msg_txt(1316)); // Gained exp will not be shown.
- return 0;
- }
+ if (sd->state.showexp) {
+ sd->state.showexp = 0;
+ clif_displaymessage(fd, msg_txt(1316)); // Gained exp will not be shown.
+ return 0;
+ }
- sd->state.showexp = 1;
- clif_displaymessage(fd, msg_txt(1317)); // Gained exp is now shown.
- return 0;
+ sd->state.showexp = 1;
+ clif_displaymessage(fd, msg_txt(1317)); // Gained exp is now shown.
+ return 0;
}
ACMD_FUNC(showzeny)
{
- if (sd->state.showzeny) {
- sd->state.showzeny = 0;
- clif_displaymessage(fd, msg_txt(1318)); // Gained zeny will not be shown.
- return 0;
- }
+ if (sd->state.showzeny) {
+ sd->state.showzeny = 0;
+ clif_displaymessage(fd, msg_txt(1318)); // Gained zeny will not be shown.
+ return 0;
+ }
- sd->state.showzeny = 1;
- clif_displaymessage(fd, msg_txt(1319)); // Gained zeny is now shown.
- return 0;
+ sd->state.showzeny = 1;
+ clif_displaymessage(fd, msg_txt(1319)); // Gained zeny is now shown.
+ return 0;
}
ACMD_FUNC(showdelay)
{
- if (sd->state.showdelay) {
- sd->state.showdelay = 0;
- clif_displaymessage(fd, msg_txt(1320)); // Skill delay failures will not be shown.
- return 0;
- }
+ if (sd->state.showdelay) {
+ sd->state.showdelay = 0;
+ clif_displaymessage(fd, msg_txt(1320)); // Skill delay failures will not be shown.
+ return 0;
+ }
- sd->state.showdelay = 1;
- clif_displaymessage(fd, msg_txt(1321)); // Skill delay failures are now shown.
- return 0;
+ sd->state.showdelay = 1;
+ clif_displaymessage(fd, msg_txt(1321)); // Skill delay failures are now shown.
+ return 0;
}
/*==========================================
@@ -7589,156 +7704,158 @@ ACMD_FUNC(showdelay)
*------------------------------------------*/
ACMD_FUNC(invite)
{
- unsigned int did = sd->duel_group;
- struct map_session_data *target_sd = map_nick2sd((char *)message);
+ unsigned int did = sd->duel_group;
+ struct map_session_data *target_sd = map_nick2sd((char *)message);
- if (did <= 0) {
- // "Duel: @invite without @duel."
- clif_displaymessage(fd, msg_txt(350));
- return 0;
- }
+ if(did <= 0) {
+ // "Duel: @invite without @duel."
+ clif_displaymessage(fd, msg_txt(350));
+ return 0;
+ }
- if (duel_list[did].max_players_limit > 0 &&
- duel_list[did].members_count >= duel_list[did].max_players_limit) {
+ if(duel_list[did].max_players_limit > 0 &&
+ duel_list[did].members_count >= duel_list[did].max_players_limit) {
- // "Duel: Limit of players is reached."
- clif_displaymessage(fd, msg_txt(351));
- return 0;
- }
+ // "Duel: Limit of players is reached."
+ clif_displaymessage(fd, msg_txt(351));
+ return 0;
+ }
- if (target_sd == NULL) {
- // "Duel: Player not found."
- clif_displaymessage(fd, msg_txt(352));
- return 0;
- }
+ if(target_sd == NULL) {
+ // "Duel: Player not found."
+ clif_displaymessage(fd, msg_txt(352));
+ return 0;
+ }
- if (target_sd->duel_group > 0 || target_sd->duel_invite > 0) {
- // "Duel: Player already in duel."
- clif_displaymessage(fd, msg_txt(353));
- return 0;
- }
+ if(target_sd->duel_group > 0 || target_sd->duel_invite > 0) {
+ // "Duel: Player already in duel."
+ clif_displaymessage(fd, msg_txt(353));
+ return 0;
+ }
- if (battle_config.duel_only_on_same_map && target_sd->bl.m != sd->bl.m) {
- sprintf(atcmd_output, msg_txt(364), message);
- clif_displaymessage(fd, atcmd_output);
- return 0;
- }
+ if(battle_config.duel_only_on_same_map && target_sd->bl.m != sd->bl.m)
+ {
+ sprintf(atcmd_output, msg_txt(364), message);
+ clif_displaymessage(fd, atcmd_output);
+ return 0;
+ }
- duel_invite(did, sd, target_sd);
- // "Duel: Invitation has been sent."
- clif_displaymessage(fd, msg_txt(354));
- return 0;
+ duel_invite(did, sd, target_sd);
+ // "Duel: Invitation has been sent."
+ clif_displaymessage(fd, msg_txt(354));
+ return 0;
}
ACMD_FUNC(duel)
{
- char output[CHAT_SIZE_MAX];
- unsigned int maxpl=0, newduel;
- struct map_session_data *target_sd;
-
- if (sd->duel_group > 0) {
- duel_showinfo(sd->duel_group, sd);
- return 0;
- }
-
- if (sd->duel_invite > 0) {
- // "Duel: @duel without @reject."
- clif_displaymessage(fd, msg_txt(355));
- return 0;
- }
-
- if (!duel_checktime(sd)) {
- // "Duel: You can take part in duel only one time per %d minutes."
- sprintf(output, msg_txt(356), battle_config.duel_time_interval);
- clif_displaymessage(fd, output);
- return 0;
- }
-
- if (message[0]) {
- if (sscanf(message, "%d", &maxpl) >= 1) {
- if (maxpl < 2 || maxpl > 65535) {
- clif_displaymessage(fd, msg_txt(357)); // "Duel: Invalid value."
- return 0;
- }
- duel_create(sd, maxpl);
- } else {
- target_sd = map_nick2sd((char *)message);
- if (target_sd != NULL) {
- if ((newduel = duel_create(sd, 2)) != -1) {
- if (target_sd->duel_group > 0 || target_sd->duel_invite > 0) {
- clif_displaymessage(fd, msg_txt(353)); // "Duel: Player already in duel."
- return 0;
- }
- duel_invite(newduel, sd, target_sd);
- clif_displaymessage(fd, msg_txt(354)); // "Duel: Invitation has been sent."
- }
- } else {
- // "Duel: Player not found."
- clif_displaymessage(fd, msg_txt(352));
- return 0;
- }
- }
- } else
- duel_create(sd, 0);
-
- return 0;
+ char output[CHAT_SIZE_MAX];
+ unsigned int maxpl=0, newduel;
+ struct map_session_data *target_sd;
+
+ if(sd->duel_group > 0) {
+ duel_showinfo(sd->duel_group, sd);
+ return 0;
+ }
+
+ if(sd->duel_invite > 0) {
+ // "Duel: @duel without @reject."
+ clif_displaymessage(fd, msg_txt(355));
+ return 0;
+ }
+
+ if(!duel_checktime(sd)) {
+ // "Duel: You can take part in duel only one time per %d minutes."
+ sprintf(output, msg_txt(356), battle_config.duel_time_interval);
+ clif_displaymessage(fd, output);
+ return 0;
+ }
+
+ if( message[0] ) {
+ if(sscanf(message, "%d", &maxpl) >= 1) {
+ if(maxpl < 2 || maxpl > 65535) {
+ clif_displaymessage(fd, msg_txt(357)); // "Duel: Invalid value."
+ return 0;
+ }
+ duel_create(sd, maxpl);
+ } else {
+ target_sd = map_nick2sd((char *)message);
+ if(target_sd != NULL) {
+ if((newduel = duel_create(sd, 2)) != -1) {
+ if(target_sd->duel_group > 0 || target_sd->duel_invite > 0) {
+ clif_displaymessage(fd, msg_txt(353)); // "Duel: Player already in duel."
+ return 0;
+ }
+ duel_invite(newduel, sd, target_sd);
+ clif_displaymessage(fd, msg_txt(354)); // "Duel: Invitation has been sent."
+ }
+ } else {
+ // "Duel: Player not found."
+ clif_displaymessage(fd, msg_txt(352));
+ return 0;
+ }
+ }
+ } else
+ duel_create(sd, 0);
+
+ return 0;
}
ACMD_FUNC(leave)
{
- if (sd->duel_group <= 0) {
- // "Duel: @leave without @duel."
- clif_displaymessage(fd, msg_txt(358));
- return 0;
- }
+ if(sd->duel_group <= 0) {
+ // "Duel: @leave without @duel."
+ clif_displaymessage(fd, msg_txt(358));
+ return 0;
+ }
- duel_leave(sd->duel_group, sd);
- clif_displaymessage(fd, msg_txt(359)); // "Duel: You left the duel."
- return 0;
+ duel_leave(sd->duel_group, sd);
+ clif_displaymessage(fd, msg_txt(359)); // "Duel: You left the duel."
+ return 0;
}
ACMD_FUNC(accept)
{
- char output[CHAT_SIZE_MAX];
+ char output[CHAT_SIZE_MAX];
- if (!duel_checktime(sd)) {
- // "Duel: You can take part in duel only one time per %d minutes."
- sprintf(output, msg_txt(356), battle_config.duel_time_interval);
- clif_displaymessage(fd, output);
- return 0;
- }
+ if(!duel_checktime(sd)) {
+ // "Duel: You can take part in duel only one time per %d minutes."
+ sprintf(output, msg_txt(356), battle_config.duel_time_interval);
+ clif_displaymessage(fd, output);
+ return 0;
+ }
- if (sd->duel_invite <= 0) {
- // "Duel: @accept without invititation."
- clif_displaymessage(fd, msg_txt(360));
- return 0;
- }
+ if(sd->duel_invite <= 0) {
+ // "Duel: @accept without invititation."
+ clif_displaymessage(fd, msg_txt(360));
+ return 0;
+ }
- if (duel_list[sd->duel_invite].max_players_limit > 0 && duel_list[sd->duel_invite].members_count >= duel_list[sd->duel_invite].max_players_limit) {
- // "Duel: Limit of players is reached."
- clif_displaymessage(fd, msg_txt(351));
- return 0;
- }
+ if( duel_list[sd->duel_invite].max_players_limit > 0 && duel_list[sd->duel_invite].members_count >= duel_list[sd->duel_invite].max_players_limit )
+ {
+ // "Duel: Limit of players is reached."
+ clif_displaymessage(fd, msg_txt(351));
+ return 0;
+ }
- duel_accept(sd->duel_invite, sd);
- // "Duel: Invitation has been accepted."
- clif_displaymessage(fd, msg_txt(361));
- return 0;
+ duel_accept(sd->duel_invite, sd);
+ // "Duel: Invitation has been accepted."
+ clif_displaymessage(fd, msg_txt(361));
+ return 0;
}
ACMD_FUNC(reject)
{
- if (sd->duel_invite <= 0) {
- // "Duel: @reject without invititation."
- clif_displaymessage(fd, msg_txt(362));
- return 0;
- }
+ if(sd->duel_invite <= 0) {
+ // "Duel: @reject without invititation."
+ clif_displaymessage(fd, msg_txt(362));
+ return 0;
+ }
- duel_reject(sd->duel_invite, sd);
- // "Duel: Invitation has been rejected."
- clif_displaymessage(fd, msg_txt(363));
- return 0;
+ duel_reject(sd->duel_invite, sd);
+ // "Duel: Invitation has been rejected."
+ clif_displaymessage(fd, msg_txt(363));
+ return 0;
}
/*===================================
@@ -7746,99 +7863,105 @@ ACMD_FUNC(reject)
*-----------------------------------*/
ACMD_FUNC(cash)
{
- char output[128];
- int value;
- int ret=0;
- nullpo_retr(-1, sd);
-
- if (!message || !*message || (value = atoi(message)) == 0) {
- clif_displaymessage(fd, msg_txt(1322)); // Please enter an amount.
- return -1;
- }
-
- if (!strcmpi(command+1,"cash")) {
- if (value > 0) {
- if ((ret=pc_getcash(sd, value, 0)) >= 0) {
- sprintf(output, msg_txt(505), ret, sd->cashPoints);
- clif_disp_onlyself(sd, output, strlen(output));
- } else clif_displaymessage(fd, msg_txt(149)); // Unable to decrease the number/value.
- } else {
- if ((ret=pc_paycash(sd, -value, 0)) >= 0) {
- sprintf(output, msg_txt(410), ret, sd->cashPoints);
- clif_disp_onlyself(sd, output, strlen(output));
- } else clif_displaymessage(fd, msg_txt(41)); // Unable to decrease the number/value.
- }
- } else {
- // @points
- if (value > 0) {
- if ((ret=pc_getcash(sd, 0, value)) >= 0) {
- sprintf(output, msg_txt(506), ret, sd->kafraPoints);
- clif_disp_onlyself(sd, output, strlen(output));
- } else clif_displaymessage(fd, msg_txt(149)); // Unable to decrease the number/value.
- } else {
- if ((ret=pc_paycash(sd, -value, -value)) >= 0) {
- sprintf(output, msg_txt(411), ret, sd->kafraPoints);
- clif_disp_onlyself(sd, output, strlen(output));
- } else clif_displaymessage(fd, msg_txt(41)); // Unable to decrease the number/value.
- }
- }
-
- return 0;
+ char output[128];
+ int value;
+ int ret=0;
+ nullpo_retr(-1, sd);
+
+ if( !message || !*message || (value = atoi(message)) == 0 ) {
+ clif_displaymessage(fd, msg_txt(1322)); // Please enter an amount.
+ return -1;
+ }
+
+ if( !strcmpi(command+1,"cash") )
+ {
+ if( value > 0 ) {
+ if( (ret=pc_getcash(sd, value, 0)) >= 0){
+ sprintf(output, msg_txt(505), ret, sd->cashPoints);
+ clif_disp_onlyself(sd, output, strlen(output));
+ }
+ else clif_displaymessage(fd, msg_txt(149)); // Unable to decrease the number/value.
+ } else {
+ if( (ret=pc_paycash(sd, -value, 0)) >= 0){
+ sprintf(output, msg_txt(410), ret, sd->cashPoints);
+ clif_disp_onlyself(sd, output, strlen(output));
+ }
+ else clif_displaymessage(fd, msg_txt(41)); // Unable to decrease the number/value.
+ }
+ }
+ else
+ { // @points
+ if( value > 0 ) {
+ if( (ret=pc_getcash(sd, 0, value)) >= 0){
+ sprintf(output, msg_txt(506), ret, sd->kafraPoints);
+ clif_disp_onlyself(sd, output, strlen(output));
+ }
+ else clif_displaymessage(fd, msg_txt(149)); // Unable to decrease the number/value.
+ } else {
+ if( (ret=pc_paycash(sd, -value, -value)) >= 0){
+ sprintf(output, msg_txt(411), ret, sd->kafraPoints);
+ clif_disp_onlyself(sd, output, strlen(output));
+ }
+ else clif_displaymessage(fd, msg_txt(41)); // Unable to decrease the number/value.
+ }
+ }
+
+ return 0;
}
// @clone/@slaveclone/@evilclone <playername> [Valaris]
ACMD_FUNC(clone)
{
- int x=0,y=0,flag=0,master=0,i=0;
- struct map_session_data *pl_sd=NULL;
-
- if (!message || !*message) {
- clif_displaymessage(sd->fd,msg_txt(1323)); // You must enter a player name or ID.
- return 0;
- }
-
- if ((pl_sd=map_nick2sd((char *)message)) == NULL && (pl_sd=map_charid2sd(atoi(message))) == NULL) {
- clif_displaymessage(fd, msg_txt(3)); // Character not found.
- return 0;
- }
-
- if (pc_get_group_level(pl_sd) > pc_get_group_level(sd)) {
- clif_displaymessage(fd, msg_txt(126)); // Cannot clone a player of higher GM level than yourself.
- return 0;
- }
-
- if (strcmpi(command+1, "clone") == 0)
- flag = 1;
- else if (strcmpi(command+1, "slaveclone") == 0) {
- flag = 2;
- if (pc_isdead(sd)) {
- clif_displaymessage(fd, msg_txt(129+flag*2));
- return 0;
- }
- master = sd->bl.id;
- if (battle_config.atc_slave_clone_limit
- && mob_countslave(&sd->bl) >= battle_config.atc_slave_clone_limit) {
- clif_displaymessage(fd, msg_txt(127)); // You've reached your slave clones limit.
- return 0;
- }
- }
-
- do {
- x = sd->bl.x + (rnd() % 10 - 5);
- y = sd->bl.y + (rnd() % 10 - 5);
- } while (map_getcell(sd->bl.m,x,y,CELL_CHKNOPASS) && i++ < 10);
-
- if (i >= 10) {
- x = sd->bl.x;
- y = sd->bl.y;
- }
-
- if ((x = mob_clone_spawn(pl_sd, sd->bl.m, x, y, "", master, 0, flag?1:0, 0)) > 0) {
- clif_displaymessage(fd, msg_txt(128+flag*2)); // Evil Clone spawned. Clone spawned. Slave clone spawned.
- return 0;
- }
- clif_displaymessage(fd, msg_txt(129+flag*2)); // Unable to spawn evil clone. Unable to spawn clone. Unable to spawn slave clone.
- return 0;
+ int x=0,y=0,flag=0,master=0,i=0;
+ struct map_session_data *pl_sd=NULL;
+
+ if (!message || !*message) {
+ clif_displaymessage(sd->fd,msg_txt(1323)); // You must enter a player name or ID.
+ return 0;
+ }
+
+ if((pl_sd=map_nick2sd((char *)message)) == NULL && (pl_sd=map_charid2sd(atoi(message))) == NULL) {
+ clif_displaymessage(fd, msg_txt(3)); // Character not found.
+ return 0;
+ }
+
+ if(pc_get_group_level(pl_sd) > pc_get_group_level(sd)) {
+ clif_displaymessage(fd, msg_txt(126)); // Cannot clone a player of higher GM level than yourself.
+ return 0;
+ }
+
+ if (strcmpi(command+1, "clone") == 0)
+ flag = 1;
+ else if (strcmpi(command+1, "slaveclone") == 0) {
+ flag = 2;
+ if(pc_isdead(sd)){
+ clif_displaymessage(fd, msg_txt(129+flag*2));
+ return 0;
+ }
+ master = sd->bl.id;
+ if (battle_config.atc_slave_clone_limit
+ && mob_countslave(&sd->bl) >= battle_config.atc_slave_clone_limit) {
+ clif_displaymessage(fd, msg_txt(127)); // You've reached your slave clones limit.
+ return 0;
+ }
+ }
+
+ do {
+ x = sd->bl.x + (rnd() % 10 - 5);
+ y = sd->bl.y + (rnd() % 10 - 5);
+ } while (map_getcell(sd->bl.m,x,y,CELL_CHKNOPASS) && i++ < 10);
+
+ if (i >= 10) {
+ x = sd->bl.x;
+ y = sd->bl.y;
+ }
+
+ if((x = mob_clone_spawn(pl_sd, sd->bl.m, x, y, "", master, 0, flag?1:0, 0)) > 0) {
+ clif_displaymessage(fd, msg_txt(128+flag*2)); // Evil Clone spawned. Clone spawned. Slave clone spawned.
+ return 0;
+ }
+ clif_displaymessage(fd, msg_txt(129+flag*2)); // Unable to spawn evil clone. Unable to spawn clone. Unable to spawn slave clone.
+ return 0;
}
/*===================================
@@ -7847,50 +7970,50 @@ ACMD_FUNC(clone)
*-----------------------------------*/
ACMD_FUNC(main)
{
- if (message[0]) {
-
- if (strcmpi(message, "on") == 0) {
- if (!sd->state.mainchat) {
- sd->state.mainchat = 1;
- clif_displaymessage(fd, msg_txt(380)); // Main chat has been activated.
- } else {
- clif_displaymessage(fd, msg_txt(381)); // Main chat already activated.
- }
- } else if (strcmpi(message, "off") == 0) {
- if (sd->state.mainchat) {
- sd->state.mainchat = 0;
- clif_displaymessage(fd, msg_txt(382)); // Main chat has been disabled.
- } else {
- clif_displaymessage(fd, msg_txt(383)); // Main chat already disabled.
- }
- } else {
- if (!sd->state.mainchat) {
- sd->state.mainchat = 1;
- clif_displaymessage(fd, msg_txt(380)); // Main chat has been activated.
- }
- if (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) {
- clif_displaymessage(fd, msg_txt(387));
- return -1;
- }
-
- if (battle_config.min_chat_delay) {
- if (DIFF_TICK(sd->cantalk_tick, gettick()) > 0)
- return 0;
- sd->cantalk_tick = gettick() + battle_config.min_chat_delay;
- }
-
- // send the message using inter-server system
- intif_main_message(sd, message);
- }
-
- } else {
-
- if (sd->state.mainchat)
- clif_displaymessage(fd, msg_txt(384)); // Main chat currently enabled. Usage: @main <on|off>, @main <message>.
- else
- clif_displaymessage(fd, msg_txt(385)); // Main chat currently disabled. Usage: @main <on|off>, @main <message>.
- }
- return 0;
+ if( message[0] ) {
+
+ if(strcmpi(message, "on") == 0) {
+ if(!sd->state.mainchat) {
+ sd->state.mainchat = 1;
+ clif_displaymessage(fd, msg_txt(380)); // Main chat has been activated.
+ } else {
+ clif_displaymessage(fd, msg_txt(381)); // Main chat already activated.
+ }
+ } else if(strcmpi(message, "off") == 0) {
+ if(sd->state.mainchat) {
+ sd->state.mainchat = 0;
+ clif_displaymessage(fd, msg_txt(382)); // Main chat has been disabled.
+ } else {
+ clif_displaymessage(fd, msg_txt(383)); // Main chat already disabled.
+ }
+ } else {
+ if(!sd->state.mainchat) {
+ sd->state.mainchat = 1;
+ clif_displaymessage(fd, msg_txt(380)); // Main chat has been activated.
+ }
+ if (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) {
+ clif_displaymessage(fd, msg_txt(387));
+ return -1;
+ }
+
+ if ( battle_config.min_chat_delay ) {
+ if( DIFF_TICK(sd->cantalk_tick, gettick()) > 0 )
+ return 0;
+ sd->cantalk_tick = gettick() + battle_config.min_chat_delay;
+ }
+
+ // send the message using inter-server system
+ intif_main_message( sd, message );
+ }
+
+ } else {
+
+ if(sd->state.mainchat)
+ clif_displaymessage(fd, msg_txt(384)); // Main chat currently enabled. Usage: @main <on|off>, @main <message>.
+ else
+ clif_displaymessage(fd, msg_txt(385)); // Main chat currently disabled. Usage: @main <on|off>, @main <message>.
+ }
+ return 0;
}
/*=====================================
@@ -7899,15 +8022,15 @@ ACMD_FUNC(main)
*-------------------------------------*/
ACMD_FUNC(noask)
{
- if (sd->state.noask) {
- clif_displaymessage(fd, msg_txt(391)); // Autorejecting is deactivated.
- sd->state.noask = 0;
- } else {
- clif_displaymessage(fd, msg_txt(390)); // Autorejecting is activated.
- sd->state.noask = 1;
- }
+ if(sd->state.noask) {
+ clif_displaymessage(fd, msg_txt(391)); // Autorejecting is deactivated.
+ sd->state.noask = 0;
+ } else {
+ clif_displaymessage(fd, msg_txt(390)); // Autorejecting is activated.
+ sd->state.noask = 1;
+ }
- return 0;
+ return 0;
}
/*=====================================
@@ -7916,16 +8039,16 @@ ACMD_FUNC(noask)
*-------------------------------------*/
ACMD_FUNC(request)
{
- if (!message || !*message) {
- clif_displaymessage(sd->fd,msg_txt(277)); // Usage: @request <petition/message to online GMs>.
- return -1;
- }
+ if (!message || !*message) {
+ clif_displaymessage(sd->fd,msg_txt(277)); // Usage: @request <petition/message to online GMs>.
+ return -1;
+ }
- sprintf(atcmd_output, msg_txt(278), message); // (@request): %s
- intif_wis_message_to_gm(sd->status.name, PC_PERM_RECEIVE_REQUESTS, atcmd_output);
- clif_disp_onlyself(sd, atcmd_output, strlen(atcmd_output));
- clif_displaymessage(sd->fd,msg_txt(279)); // @request sent.
- return 0;
+ sprintf(atcmd_output, msg_txt(278), message); // (@request): %s
+ intif_wis_message_to_gm(sd->status.name, PC_PERM_RECEIVE_REQUESTS, atcmd_output);
+ clif_disp_onlyself(sd, atcmd_output, strlen(atcmd_output));
+ clif_displaymessage(sd->fd,msg_txt(279)); // @request sent.
+ return 0;
}
/*==========================================
@@ -7933,10 +8056,10 @@ ACMD_FUNC(request)
*------------------------------------------*/
ACMD_FUNC(feelreset)
{
- pc_resetfeel(sd);
- clif_displaymessage(fd, msg_txt(1324)); // Reset 'Feeling' maps.
+ pc_resetfeel(sd);
+ clif_displaymessage(fd, msg_txt(1324)); // Reset 'Feeling' maps.
- return 0;
+ return 0;
}
/*==========================================
@@ -7944,11 +8067,11 @@ ACMD_FUNC(feelreset)
*------------------------------------------*/
ACMD_FUNC(auction)
{
- nullpo_ret(sd);
+ nullpo_ret(sd);
- clif_Auction_openwindow(sd);
+ clif_Auction_openwindow(sd);
- return 0;
+ return 0;
}
/*==========================================
@@ -7956,62 +8079,69 @@ ACMD_FUNC(auction)
*------------------------------------------*/
ACMD_FUNC(ksprotection)
{
- nullpo_retr(-1,sd);
-
- if (sd->state.noks) {
- sd->state.noks = 0;
- clif_displaymessage(fd, msg_txt(1325)); // [ K.S Protection Inactive ]
- } else {
- if (!message || !*message || !strcmpi(message, "party")) {
- // Default is Party
- sd->state.noks = 2;
- clif_displaymessage(fd, msg_txt(1326)); // [ K.S Protection Active - Option: Party ]
- } else if (!strcmpi(message, "self")) {
- sd->state.noks = 1;
- clif_displaymessage(fd, msg_txt(1327)); // [ K.S Protection Active - Option: Self ]
- } else if (!strcmpi(message, "guild")) {
- sd->state.noks = 3;
- clif_displaymessage(fd, msg_txt(1328)); // [ K.S Protection Active - Option: Guild ]
- } else
- clif_displaymessage(fd, msg_txt(1329)); // Usage: @noks <self|party|guild>
- }
- return 0;
+ nullpo_retr(-1,sd);
+
+ if( sd->state.noks ) {
+ sd->state.noks = 0;
+ clif_displaymessage(fd, msg_txt(1325)); // [ K.S Protection Inactive ]
+ }
+ else
+ {
+ if( !message || !*message || !strcmpi(message, "party") )
+ { // Default is Party
+ sd->state.noks = 2;
+ clif_displaymessage(fd, msg_txt(1326)); // [ K.S Protection Active - Option: Party ]
+ }
+ else if( !strcmpi(message, "self") )
+ {
+ sd->state.noks = 1;
+ clif_displaymessage(fd, msg_txt(1327)); // [ K.S Protection Active - Option: Self ]
+ }
+ else if( !strcmpi(message, "guild") )
+ {
+ sd->state.noks = 3;
+ clif_displaymessage(fd, msg_txt(1328)); // [ K.S Protection Active - Option: Guild ]
+ }
+ else
+ clif_displaymessage(fd, msg_txt(1329)); // Usage: @noks <self|party|guild>
+ }
+ return 0;
}
/*==========================================
* Map Kill Steal Protection Setting
*------------------------------------------*/
ACMD_FUNC(allowks)
{
- nullpo_retr(-1,sd);
+ nullpo_retr(-1,sd);
- if (map[sd->bl.m].flag.allowks) {
- map[sd->bl.m].flag.allowks = 0;
- clif_displaymessage(fd, msg_txt(1330)); // [ Map K.S Protection Active ]
- } else {
- map[sd->bl.m].flag.allowks = 1;
- clif_displaymessage(fd, msg_txt(1331)); // [ Map K.S Protection Inactive ]
- }
- return 0;
+ if( map[sd->bl.m].flag.allowks ) {
+ map[sd->bl.m].flag.allowks = 0;
+ clif_displaymessage(fd, msg_txt(1330)); // [ Map K.S Protection Active ]
+ } else {
+ map[sd->bl.m].flag.allowks = 1;
+ clif_displaymessage(fd, msg_txt(1331)); // [ Map K.S Protection Inactive ]
+ }
+ return 0;
}
ACMD_FUNC(resetstat)
{
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- pc_resetstate(sd);
- sprintf(atcmd_output, msg_txt(207), sd->status.name);
- clif_displaymessage(fd, atcmd_output);
- return 0;
+ pc_resetstate(sd);
+ sprintf(atcmd_output, msg_txt(207), sd->status.name);
+ clif_displaymessage(fd, atcmd_output);
+ return 0;
}
ACMD_FUNC(resetskill)
{
- nullpo_retr(-1,sd);
+ nullpo_retr(-1,sd);
- pc_resetskill(sd,1);
- sprintf(atcmd_output, msg_txt(206), sd->status.name);
- clif_displaymessage(fd, atcmd_output);
- return 0;
+ pc_resetskill(sd,1);
+ sprintf(atcmd_output, msg_txt(206), sd->status.name);
+ clif_displaymessage(fd, atcmd_output);
+ return 0;
}
/*==========================================
@@ -8021,262 +8151,289 @@ ACMD_FUNC(resetskill)
*------------------------------------------*/
ACMD_FUNC(itemlist)
{
- int i, j, count, counter;
- const char *location;
- const struct item *items;
- int size;
- StringBuf buf;
-
- nullpo_retr(-1, sd);
-
- if (strcmp(command+1, "storagelist") == 0) {
- location = "storage";
- items = sd->status.storage.items;
- size = MAX_STORAGE;
- } else if (strcmp(command+1, "cartlist") == 0) {
- location = "cart";
- items = sd->status.cart;
- size = MAX_CART;
- } else if (strcmp(command+1, "itemlist") == 0) {
- location = "inventory";
- items = sd->status.inventory;
- size = MAX_INVENTORY;
- } else
- return 1;
-
- StringBuf_Init(&buf);
-
- count = 0; // total slots occupied
- counter = 0; // total items found
- for (i = 0; i < size; ++i) {
- const struct item *it = &items[i];
- struct item_data *itd;
-
- if (it->nameid == 0 || (itd = itemdb_exists(it->nameid)) == NULL)
- continue;
-
- counter += it->amount;
- count++;
-
- if (count == 1) {
- StringBuf_Printf(&buf, msg_txt(1332), location, sd->status.name); // ------ %s items list of '%s' ------
- clif_displaymessage(fd, StringBuf_Value(&buf));
- StringBuf_Clear(&buf);
- }
-
- if (it->refine)
- StringBuf_Printf(&buf, "%d %s %+d (%s, id: %d)", it->amount, itd->jname, it->refine, itd->name, it->nameid);
- else
- StringBuf_Printf(&buf, "%d %s (%s, id: %d)", it->amount, itd->jname, itd->name, it->nameid);
-
- if (it->equip) {
- char equipstr[CHAT_SIZE_MAX];
- strcpy(equipstr, msg_txt(1333)); // | equipped:
- if (it->equip & EQP_GARMENT)
- strcat(equipstr, msg_txt(1334)); // garment,
- if (it->equip & EQP_ACC_L)
- strcat(equipstr, msg_txt(1335)); // left accessory,
- if (it->equip & EQP_ARMOR)
- strcat(equipstr, msg_txt(1336)); // body/armor,
- if ((it->equip & EQP_ARMS) == EQP_HAND_R)
- strcat(equipstr, msg_txt(1337)); // right hand,
- if ((it->equip & EQP_ARMS) == EQP_HAND_L)
- strcat(equipstr, msg_txt(1338)); // left hand,
- if ((it->equip & EQP_ARMS) == EQP_ARMS)
- strcat(equipstr, msg_txt(1339)); // both hands,
- if (it->equip & EQP_SHOES)
- strcat(equipstr, msg_txt(1340)); // feet,
- if (it->equip & EQP_ACC_R)
- strcat(equipstr, msg_txt(1341)); // right accessory,
- if ((it->equip & EQP_HELM) == EQP_HEAD_LOW)
- strcat(equipstr, msg_txt(1342)); // lower head,
- if ((it->equip & EQP_HELM) == EQP_HEAD_TOP)
- strcat(equipstr, msg_txt(1343)); // top head,
- if ((it->equip & EQP_HELM) == (EQP_HEAD_LOW|EQP_HEAD_TOP))
- strcat(equipstr, msg_txt(1344)); // lower/top head,
- if ((it->equip & EQP_HELM) == EQP_HEAD_MID)
- strcat(equipstr, msg_txt(1345)); // mid head,
- if ((it->equip & EQP_HELM) == (EQP_HEAD_LOW|EQP_HEAD_MID))
- strcat(equipstr, msg_txt(1346)); // lower/mid head,
- if ((it->equip & EQP_HELM) == EQP_HELM)
- strcat(equipstr, msg_txt(1347)); // lower/mid/top head,
- // remove final ', '
- equipstr[strlen(equipstr) - 2] = '\0';
- StringBuf_AppendStr(&buf, equipstr);
- }
-
- clif_displaymessage(fd, StringBuf_Value(&buf));
- StringBuf_Clear(&buf);
-
- if (it->card[0] == CARD0_PET) {
- // pet egg
- if (it->card[3])
- StringBuf_Printf(&buf, msg_txt(1348), (unsigned int)MakeDWord(it->card[1], it->card[2])); // -> (pet egg, pet id: %u, named)
- else
- StringBuf_Printf(&buf, msg_txt(1349), (unsigned int)MakeDWord(it->card[1], it->card[2])); // -> (pet egg, pet id: %u, unnamed)
- } else if (it->card[0] == CARD0_FORGE) {
- // forged item
- StringBuf_Printf(&buf, msg_txt(1350), (unsigned int)MakeDWord(it->card[2], it->card[3]), it->card[1]>>8, it->card[1]&0x0f); // -> (crafted item, creator id: %u, star crumbs %d, element %d)
- } else if (it->card[0] == CARD0_CREATE) {
- // created item
- StringBuf_Printf(&buf, msg_txt(1351), (unsigned int)MakeDWord(it->card[2], it->card[3])); // -> (produced item, creator id: %u)
- } else {
- // normal item
- int counter2 = 0;
-
- for (j = 0; j < itd->slot; ++j) {
- struct item_data *card;
-
- if (it->card[j] == 0 || (card = itemdb_exists(it->card[j])) == NULL)
- continue;
-
- counter2++;
-
- if (counter2 == 1)
- StringBuf_AppendStr(&buf, msg_txt(1352)); // -> (card(s):
-
- if (counter2 != 1)
- StringBuf_AppendStr(&buf, ", ");
-
- StringBuf_Printf(&buf, "#%d %s (id: %d)", counter2, card->jname, card->nameid);
- }
-
- if (counter2 > 0)
- StringBuf_AppendStr(&buf, ")");
- }
-
- if (StringBuf_Length(&buf) > 0)
- clif_displaymessage(fd, StringBuf_Value(&buf));
-
- StringBuf_Clear(&buf);
- }
-
- if (count == 0)
- StringBuf_Printf(&buf, msg_txt(1353), location); // No item found in this player's %s.
- else
- StringBuf_Printf(&buf, msg_txt(1354), counter, count, location); // %d item(s) found in %d %s slots.
-
- clif_displaymessage(fd, StringBuf_Value(&buf));
-
- StringBuf_Destroy(&buf);
-
- return 0;
+ int i, j, count, counter;
+ const char* location;
+ const struct item* items;
+ int size;
+ StringBuf buf;
+
+ nullpo_retr(-1, sd);
+
+ if( strcmp(command+1, "storagelist") == 0 )
+ {
+ location = "storage";
+ items = sd->status.storage.items;
+ size = MAX_STORAGE;
+ }
+ else
+ if( strcmp(command+1, "cartlist") == 0 )
+ {
+ location = "cart";
+ items = sd->status.cart;
+ size = MAX_CART;
+ }
+ else
+ if( strcmp(command+1, "itemlist") == 0 )
+ {
+ location = "inventory";
+ items = sd->status.inventory;
+ size = MAX_INVENTORY;
+ }
+ else
+ return 1;
+
+ StringBuf_Init(&buf);
+
+ count = 0; // total slots occupied
+ counter = 0; // total items found
+ for( i = 0; i < size; ++i )
+ {
+ const struct item* it = &items[i];
+ struct item_data* itd;
+
+ if( it->nameid == 0 || (itd = itemdb_exists(it->nameid)) == NULL )
+ continue;
+
+ counter += it->amount;
+ count++;
+
+ if( count == 1 )
+ {
+ StringBuf_Printf(&buf, msg_txt(1332), location, sd->status.name); // ------ %s items list of '%s' ------
+ clif_displaymessage(fd, StringBuf_Value(&buf));
+ StringBuf_Clear(&buf);
+ }
+
+ if( it->refine )
+ StringBuf_Printf(&buf, "%d %s %+d (%s, id: %d)", it->amount, itd->jname, it->refine, itd->name, it->nameid);
+ else
+ StringBuf_Printf(&buf, "%d %s (%s, id: %d)", it->amount, itd->jname, itd->name, it->nameid);
+
+ if( it->equip )
+ {
+ char equipstr[CHAT_SIZE_MAX];
+ strcpy(equipstr, msg_txt(1333)); // | equipped:
+ if( it->equip & EQP_GARMENT )
+ strcat(equipstr, msg_txt(1334)); // garment,
+ if( it->equip & EQP_ACC_L )
+ strcat(equipstr, msg_txt(1335)); // left accessory,
+ if( it->equip & EQP_ARMOR )
+ strcat(equipstr, msg_txt(1336)); // body/armor,
+ if( (it->equip & EQP_ARMS) == EQP_HAND_R )
+ strcat(equipstr, msg_txt(1337)); // right hand,
+ if( (it->equip & EQP_ARMS) == EQP_HAND_L )
+ strcat(equipstr, msg_txt(1338)); // left hand,
+ if( (it->equip & EQP_ARMS) == EQP_ARMS )
+ strcat(equipstr, msg_txt(1339)); // both hands,
+ if( it->equip & EQP_SHOES )
+ strcat(equipstr, msg_txt(1340)); // feet,
+ if( it->equip & EQP_ACC_R )
+ strcat(equipstr, msg_txt(1341)); // right accessory,
+ if( (it->equip & EQP_HELM) == EQP_HEAD_LOW )
+ strcat(equipstr, msg_txt(1342)); // lower head,
+ if( (it->equip & EQP_HELM) == EQP_HEAD_TOP )
+ strcat(equipstr, msg_txt(1343)); // top head,
+ if( (it->equip & EQP_HELM) == (EQP_HEAD_LOW|EQP_HEAD_TOP) )
+ strcat(equipstr, msg_txt(1344)); // lower/top head,
+ if( (it->equip & EQP_HELM) == EQP_HEAD_MID )
+ strcat(equipstr, msg_txt(1345)); // mid head,
+ if( (it->equip & EQP_HELM) == (EQP_HEAD_LOW|EQP_HEAD_MID) )
+ strcat(equipstr, msg_txt(1346)); // lower/mid head,
+ if( (it->equip & EQP_HELM) == EQP_HELM )
+ strcat(equipstr, msg_txt(1347)); // lower/mid/top head,
+ // remove final ', '
+ equipstr[strlen(equipstr) - 2] = '\0';
+ StringBuf_AppendStr(&buf, equipstr);
+ }
+
+ clif_displaymessage(fd, StringBuf_Value(&buf));
+ StringBuf_Clear(&buf);
+
+ if( it->card[0] == CARD0_PET )
+ {// pet egg
+ if (it->card[3])
+ StringBuf_Printf(&buf, msg_txt(1348), (unsigned int)MakeDWord(it->card[1], it->card[2])); // -> (pet egg, pet id: %u, named)
+ else
+ StringBuf_Printf(&buf, msg_txt(1349), (unsigned int)MakeDWord(it->card[1], it->card[2])); // -> (pet egg, pet id: %u, unnamed)
+ }
+ else
+ if(it->card[0] == CARD0_FORGE)
+ {// forged item
+ StringBuf_Printf(&buf, msg_txt(1350), (unsigned int)MakeDWord(it->card[2], it->card[3]), it->card[1]>>8, it->card[1]&0x0f); // -> (crafted item, creator id: %u, star crumbs %d, element %d)
+ }
+ else
+ if(it->card[0] == CARD0_CREATE)
+ {// created item
+ StringBuf_Printf(&buf, msg_txt(1351), (unsigned int)MakeDWord(it->card[2], it->card[3])); // -> (produced item, creator id: %u)
+ }
+ else
+ {// normal item
+ int counter2 = 0;
+
+ for( j = 0; j < itd->slot; ++j )
+ {
+ struct item_data* card;
+
+ if( it->card[j] == 0 || (card = itemdb_exists(it->card[j])) == NULL )
+ continue;
+
+ counter2++;
+
+ if( counter2 == 1 )
+ StringBuf_AppendStr(&buf, msg_txt(1352)); // -> (card(s):
+
+ if( counter2 != 1 )
+ StringBuf_AppendStr(&buf, ", ");
+
+ StringBuf_Printf(&buf, "#%d %s (id: %d)", counter2, card->jname, card->nameid);
+ }
+
+ if( counter2 > 0 )
+ StringBuf_AppendStr(&buf, ")");
+ }
+
+ if( StringBuf_Length(&buf) > 0 )
+ clif_displaymessage(fd, StringBuf_Value(&buf));
+
+ StringBuf_Clear(&buf);
+ }
+
+ if( count == 0 )
+ StringBuf_Printf(&buf, msg_txt(1353), location); // No item found in this player's %s.
+ else
+ StringBuf_Printf(&buf, msg_txt(1354), counter, count, location); // %d item(s) found in %d %s slots.
+
+ clif_displaymessage(fd, StringBuf_Value(&buf));
+
+ StringBuf_Destroy(&buf);
+
+ return 0;
}
ACMD_FUNC(stats)
{
- char job_jobname[100];
- char output[CHAT_SIZE_MAX];
- int i;
- struct {
- const char *format;
- int value;
- } output_table[] = {
- { "Base Level - %d", 0 },
- { NULL, 0 },
- { "Hp - %d", 0 },
- { "MaxHp - %d", 0 },
- { "Sp - %d", 0 },
- { "MaxSp - %d", 0 },
- { "Str - %3d", 0 },
- { "Agi - %3d", 0 },
- { "Vit - %3d", 0 },
- { "Int - %3d", 0 },
- { "Dex - %3d", 0 },
- { "Luk - %3d", 0 },
- { "Zeny - %d", 0 },
- { "Free SK Points - %d", 0 },
- { "JobChangeLvl (2nd) - %d", 0 },
- { "JobChangeLvl (3rd) - %d", 0 },
- { NULL, 0 }
- };
-
- memset(job_jobname, '\0', sizeof(job_jobname));
- memset(output, '\0', sizeof(output));
-
- //direct array initialization with variables is not standard C compliant.
- output_table[0].value = sd->status.base_level;
- output_table[1].format = job_jobname;
- output_table[1].value = sd->status.job_level;
- output_table[2].value = sd->status.hp;
- output_table[3].value = sd->status.max_hp;
- output_table[4].value = sd->status.sp;
- output_table[5].value = sd->status.max_sp;
- output_table[6].value = sd->status.str;
- output_table[7].value = sd->status.agi;
- output_table[8].value = sd->status.vit;
- output_table[9].value = sd->status.int_;
- output_table[10].value = sd->status.dex;
- output_table[11].value = sd->status.luk;
- output_table[12].value = sd->status.zeny;
- output_table[13].value = sd->status.skill_point;
- output_table[14].value = sd->change_level_2nd;
- output_table[15].value = sd->change_level_3rd;
-
- sprintf(job_jobname, "Job - %s %s", job_name(sd->status.class_), "(level %d)");
- sprintf(output, msg_txt(53), sd->status.name); // '%s' stats:
-
- clif_displaymessage(fd, output);
-
- for (i = 0; output_table[i].format != NULL; i++) {
- sprintf(output, output_table[i].format, output_table[i].value);
- clif_displaymessage(fd, output);
- }
-
- return 0;
+ char job_jobname[100];
+ char output[CHAT_SIZE_MAX];
+ int i;
+ struct {
+ const char* format;
+ int value;
+ } output_table[] = {
+ { "Base Level - %d", 0 },
+ { NULL, 0 },
+ { "Hp - %d", 0 },
+ { "MaxHp - %d", 0 },
+ { "Sp - %d", 0 },
+ { "MaxSp - %d", 0 },
+ { "Str - %3d", 0 },
+ { "Agi - %3d", 0 },
+ { "Vit - %3d", 0 },
+ { "Int - %3d", 0 },
+ { "Dex - %3d", 0 },
+ { "Luk - %3d", 0 },
+ { "Zeny - %d", 0 },
+ { "Free SK Points - %d", 0 },
+ { "JobChangeLvl (2nd) - %d", 0 },
+ { "JobChangeLvl (3rd) - %d", 0 },
+ { NULL, 0 }
+ };
+
+ memset(job_jobname, '\0', sizeof(job_jobname));
+ memset(output, '\0', sizeof(output));
+
+ //direct array initialization with variables is not standard C compliant.
+ output_table[0].value = sd->status.base_level;
+ output_table[1].format = job_jobname;
+ output_table[1].value = sd->status.job_level;
+ output_table[2].value = sd->status.hp;
+ output_table[3].value = sd->status.max_hp;
+ output_table[4].value = sd->status.sp;
+ output_table[5].value = sd->status.max_sp;
+ output_table[6].value = sd->status.str;
+ output_table[7].value = sd->status.agi;
+ output_table[8].value = sd->status.vit;
+ output_table[9].value = sd->status.int_;
+ output_table[10].value = sd->status.dex;
+ output_table[11].value = sd->status.luk;
+ output_table[12].value = sd->status.zeny;
+ output_table[13].value = sd->status.skill_point;
+ output_table[14].value = sd->change_level_2nd;
+ output_table[15].value = sd->change_level_3rd;
+
+ sprintf(job_jobname, "Job - %s %s", job_name(sd->status.class_), "(level %d)");
+ sprintf(output, msg_txt(53), sd->status.name); // '%s' stats:
+
+ clif_displaymessage(fd, output);
+
+ for (i = 0; output_table[i].format != NULL; i++) {
+ sprintf(output, output_table[i].format, output_table[i].value);
+ clif_displaymessage(fd, output);
+ }
+
+ return 0;
}
ACMD_FUNC(delitem)
{
- char item_name[100];
- int nameid, amount = 0, total, idx;
- struct item_data *id;
-
- nullpo_retr(-1, sd);
-
- if (!message || !*message || (sscanf(message, "\"%99[^\"]\" %d", item_name, &amount) < 2 && sscanf(message, "%99s %d", item_name, &amount) < 2) || amount < 1) {
- clif_displaymessage(fd, msg_txt(1355)); // Please enter an item name/ID, a quantity, and a player name (usage: #delitem <player> <item_name_or_ID> <quantity>).
- return -1;
- }
-
- if ((id = itemdb_searchname(item_name)) != NULL || (id = itemdb_exists(atoi(item_name))) != NULL) {
- nameid = id->nameid;
- } else {
- clif_displaymessage(fd, msg_txt(19)); // Invalid item ID or name.
- return -1;
- }
-
- total = amount;
-
- // delete items
- while (amount && (idx = pc_search_inventory(sd, nameid)) != -1) {
- int delamount = (amount < sd->status.inventory[idx].amount) ? amount : sd->status.inventory[idx].amount;
-
- if (sd->inventory_data[idx]->type == IT_PETEGG && sd->status.inventory[idx].card[0] == CARD0_PET) {
- // delete pet
- intif_delete_petdata(MakeDWord(sd->status.inventory[idx].card[1], sd->status.inventory[idx].card[2]));
- }
- pc_delitem(sd, idx, delamount, 0, 0, LOG_TYPE_COMMAND);
-
- amount-= delamount;
- }
-
- // notify target
- sprintf(atcmd_output, msg_txt(113), total-amount); // %d item(s) removed by a GM.
- clif_displaymessage(sd->fd, atcmd_output);
-
- // notify source
- if (amount == total) {
- clif_displaymessage(fd, msg_txt(116)); // Character does not have the item.
- } else if (amount) {
- sprintf(atcmd_output, msg_txt(115), total-amount, total-amount, total); // %d item(s) removed. Player had only %d on %d items.
- clif_displaymessage(fd, atcmd_output);
- } else {
- sprintf(atcmd_output, msg_txt(114), total); // %d item(s) removed from the player.
- clif_displaymessage(fd, atcmd_output);
- }
-
- return 0;
+ char item_name[100];
+ int nameid, amount = 0, total, idx;
+ struct item_data* id;
+
+ nullpo_retr(-1, sd);
+
+ if( !message || !*message || ( sscanf(message, "\"%99[^\"]\" %d", item_name, &amount) < 2 && sscanf(message, "%99s %d", item_name, &amount) < 2 ) || amount < 1 )
+ {
+ clif_displaymessage(fd, msg_txt(1355)); // Please enter an item name/ID, a quantity, and a player name (usage: #delitem <player> <item_name_or_ID> <quantity>).
+ return -1;
+ }
+
+ if( ( id = itemdb_searchname(item_name) ) != NULL || ( id = itemdb_exists(atoi(item_name)) ) != NULL )
+ {
+ nameid = id->nameid;
+ }
+ else
+ {
+ clif_displaymessage(fd, msg_txt(19)); // Invalid item ID or name.
+ return -1;
+ }
+
+ total = amount;
+
+ // delete items
+ while( amount && ( idx = pc_search_inventory(sd, nameid) ) != -1 )
+ {
+ int delamount = ( amount < sd->status.inventory[idx].amount ) ? amount : sd->status.inventory[idx].amount;
+
+ if( sd->inventory_data[idx]->type == IT_PETEGG && sd->status.inventory[idx].card[0] == CARD0_PET )
+ {// delete pet
+ intif_delete_petdata(MakeDWord(sd->status.inventory[idx].card[1], sd->status.inventory[idx].card[2]));
+ }
+ pc_delitem(sd, idx, delamount, 0, 0, LOG_TYPE_COMMAND);
+
+ amount-= delamount;
+ }
+
+ // notify target
+ sprintf(atcmd_output, msg_txt(113), total-amount); // %d item(s) removed by a GM.
+ clif_displaymessage(sd->fd, atcmd_output);
+
+ // notify source
+ if( amount == total )
+ {
+ clif_displaymessage(fd, msg_txt(116)); // Character does not have the item.
+ }
+ else if( amount )
+ {
+ sprintf(atcmd_output, msg_txt(115), total-amount, total-amount, total); // %d item(s) removed. Player had only %d on %d items.
+ clif_displaymessage(fd, atcmd_output);
+ }
+ else
+ {
+ sprintf(atcmd_output, msg_txt(114), total); // %d item(s) removed from the player.
+ clif_displaymessage(fd, atcmd_output);
+ }
+
+ return 0;
}
/*==========================================
@@ -8284,86 +8441,94 @@ ACMD_FUNC(delitem)
*------------------------------------------*/
ACMD_FUNC(font)
{
- int font_id;
- nullpo_retr(-1,sd);
-
- font_id = atoi(message);
- if (font_id == 0) {
- if (sd->user_font) {
- sd->user_font = 0;
- clif_displaymessage(fd, msg_txt(1356)); // Returning to normal font.
- clif_font(sd);
- } else {
- clif_displaymessage(fd, msg_txt(1357)); // Use @font <1-9> to change your message font.
- clif_displaymessage(fd, msg_txt(1358)); // Use 0 or no parameter to return to normal font.
- }
- } else if (font_id < 0 || font_id > 9)
- clif_displaymessage(fd, msg_txt(1359)); // Invalid font. Use a value from 0 to 9.
- else if (font_id != sd->user_font) {
- sd->user_font = font_id;
- clif_font(sd);
- clif_displaymessage(fd, msg_txt(1360)); // Font changed.
- } else
- clif_displaymessage(fd, msg_txt(1361)); // Already using this font.
-
- return 0;
+ int font_id;
+ nullpo_retr(-1,sd);
+
+ font_id = atoi(message);
+ if( font_id == 0 )
+ {
+ if( sd->user_font )
+ {
+ sd->user_font = 0;
+ clif_displaymessage(fd, msg_txt(1356)); // Returning to normal font.
+ clif_font(sd);
+ }
+ else
+ {
+ clif_displaymessage(fd, msg_txt(1357)); // Use @font <1-9> to change your message font.
+ clif_displaymessage(fd, msg_txt(1358)); // Use 0 or no parameter to return to normal font.
+ }
+ }
+ else if( font_id < 0 || font_id > 9 )
+ clif_displaymessage(fd, msg_txt(1359)); // Invalid font. Use a value from 0 to 9.
+ else if( font_id != sd->user_font )
+ {
+ sd->user_font = font_id;
+ clif_font(sd);
+ clif_displaymessage(fd, msg_txt(1360)); // Font changed.
+ }
+ else
+ clif_displaymessage(fd, msg_txt(1361)); // Already using this font.
+
+ return 0;
}
/*==========================================
* type: 1 = commands (@), 2 = charcommands (#)
*------------------------------------------*/
-static void atcommand_commands_sub(struct map_session_data *sd, const int fd, AtCommandType type)
+static void atcommand_commands_sub(struct map_session_data* sd, const int fd, AtCommandType type)
{
- char line_buff[CHATBOX_SIZE];
- char *cur = line_buff;
- AtCommandInfo *cmd;
- DBIterator *iter = db_iterator(atcommand_db);
- int count = 0;
+ char line_buff[CHATBOX_SIZE];
+ char* cur = line_buff;
+ AtCommandInfo* cmd;
+ DBIterator *iter = db_iterator(atcommand_db);
+ int count = 0;
- memset(line_buff,' ',CHATBOX_SIZE);
- line_buff[CHATBOX_SIZE-1] = 0;
+ memset(line_buff,' ',CHATBOX_SIZE);
+ line_buff[CHATBOX_SIZE-1] = 0;
- clif_displaymessage(fd, msg_txt(273)); // "Commands available:"
+ clif_displaymessage(fd, msg_txt(273)); // "Commands available:"
- for (cmd = dbi_first(iter); dbi_exists(iter); cmd = dbi_next(iter)) {
- unsigned int slen = 0;
+ for (cmd = dbi_first(iter); dbi_exists(iter); cmd = dbi_next(iter)) {
+ unsigned int slen = 0;
- switch (type) {
- case COMMAND_CHARCOMMAND:
- if (cmd->char_groups[sd->group_pos] == 0)
- continue;
- break;
- case COMMAND_ATCOMMAND:
- if (cmd->at_groups[sd->group_pos] == 0)
- continue;
- break;
- default:
- continue;
- }
+ switch( type ) {
+ case COMMAND_CHARCOMMAND:
+ if( cmd->char_groups[sd->group_pos] == 0 )
+ continue;
+ break;
+ case COMMAND_ATCOMMAND:
+ if( cmd->at_groups[sd->group_pos] == 0 )
+ continue;
+ break;
+ default:
+ continue;
+ }
- slen = strlen(cmd->command);
+ slen = strlen(cmd->command);
- // flush the text buffer if this command won't fit into it
- if (slen + cur - line_buff >= CHATBOX_SIZE) {
- clif_displaymessage(fd,line_buff);
- cur = line_buff;
- memset(line_buff,' ',CHATBOX_SIZE);
- line_buff[CHATBOX_SIZE-1] = 0;
- }
+ // flush the text buffer if this command won't fit into it
+ if ( slen + cur - line_buff >= CHATBOX_SIZE )
+ {
+ clif_displaymessage(fd,line_buff);
+ cur = line_buff;
+ memset(line_buff,' ',CHATBOX_SIZE);
+ line_buff[CHATBOX_SIZE-1] = 0;
+ }
- memcpy(cur,cmd->command,slen);
- cur += slen+(10-slen%10);
+ memcpy(cur,cmd->command,slen);
+ cur += slen+(10-slen%10);
- count++;
- }
- dbi_destroy(iter);
- clif_displaymessage(fd,line_buff);
+ count++;
+ }
+ dbi_destroy(iter);
+ clif_displaymessage(fd,line_buff);
- sprintf(atcmd_output, msg_txt(274), count); // "%d commands found."
- clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output, msg_txt(274), count); // "%d commands found."
+ clif_displaymessage(fd, atcmd_output);
- return;
+ return;
}
/*==========================================
@@ -8371,8 +8536,8 @@ static void atcommand_commands_sub(struct map_session_data *sd, const int fd, At
*------------------------------------------*/
ACMD_FUNC(commands)
{
- atcommand_commands_sub(sd, fd, COMMAND_ATCOMMAND);
- return 0;
+ atcommand_commands_sub(sd, fd, COMMAND_ATCOMMAND);
+ return 0;
}
/*==========================================
@@ -8380,275 +8545,268 @@ ACMD_FUNC(commands)
*------------------------------------------*/
ACMD_FUNC(charcommands)
{
- atcommand_commands_sub(sd, fd, COMMAND_CHARCOMMAND);
- return 0;
+ atcommand_commands_sub(sd, fd, COMMAND_CHARCOMMAND);
+ return 0;
}
/* for new mounts */
-ACMD_FUNC(mount2)
-{
+ACMD_FUNC(mount2) {
- clif_displaymessage(sd->fd,msg_txt(1362)); // NOTICE: If you crash with mount your LUA is outdated.
- if (!(sd->sc.option&OPTION_MOUNTING)) {
- clif_displaymessage(sd->fd,msg_txt(1363)); // You have mounted.
- pc_setoption(sd, sd->sc.option|OPTION_MOUNTING);
- } else {
- clif_displaymessage(sd->fd,msg_txt(1364)); // You have released your mount.
- pc_setoption(sd, sd->sc.option&~OPTION_MOUNTING);
- }
- return 0;
+ clif_displaymessage(sd->fd,msg_txt(1362)); // NOTICE: If you crash with mount your LUA is outdated.
+ if( !(sd->sc.option&OPTION_MOUNTING) ) {
+ clif_displaymessage(sd->fd,msg_txt(1363)); // You have mounted.
+ pc_setoption(sd, sd->sc.option|OPTION_MOUNTING);
+ } else {
+ clif_displaymessage(sd->fd,msg_txt(1364)); // You have released your mount.
+ pc_setoption(sd, sd->sc.option&~OPTION_MOUNTING);
+ }
+ return 0;
}
-ACMD_FUNC(accinfo)
-{
- char query[NAME_LENGTH];
+ACMD_FUNC(accinfo) {
+ char query[NAME_LENGTH];
- if (!message || !*message || strlen(message) > NAME_LENGTH) {
- clif_displaymessage(fd, msg_txt(1365)); // Usage: @accinfo/@accountinfo <account_id/char name>
- clif_displaymessage(fd, msg_txt(1366)); // You may search partial name by making use of '%' in the search, ex. "@accinfo %Mario%" lists all characters whose name contains "Mario".
- return -1;
- }
+ if (!message || !*message || strlen(message) > NAME_LENGTH ) {
+ clif_displaymessage(fd, msg_txt(1365)); // Usage: @accinfo/@accountinfo <account_id/char name>
+ clif_displaymessage(fd, msg_txt(1366)); // You may search partial name by making use of '%' in the search, ex. "@accinfo %Mario%" lists all characters whose name contains "Mario".
+ return -1;
+ }
- //remove const type
- safestrncpy(query, message, NAME_LENGTH);
+ //remove const type
+ safestrncpy(query, message, NAME_LENGTH);
- intif_request_accinfo(sd->fd, sd->bl.id, sd->group_id, query);
+ intif_request_accinfo( sd->fd, sd->bl.id, sd->group_id, query );
- return 0;
+ return 0;
}
/* [Ind] */
-ACMD_FUNC(set)
-{
- char reg[32], val[128];
- struct script_data *data;
- int toset = 0;
- bool is_str = false;
-
- if (!message || !*message || (toset = sscanf(message, "%32s %128[^\n]s", reg, val)) < 1) {
- clif_displaymessage(fd, msg_txt(1367)); // Usage: @set <variable name> <value>
- clif_displaymessage(fd, msg_txt(1368)); // Usage: ex. "@set PoringCharVar 50"
- clif_displaymessage(fd, msg_txt(1369)); // Usage: ex. "@set PoringCharVarSTR$ Super Duper String"
- clif_displaymessage(fd, msg_txt(1370)); // Usage: ex. "@set PoringCharVarSTR$" outputs its value, Super Duper String.
- return -1;
- }
-
- /* disabled variable types (they require a proper script state to function, so allowing them would crash the server) */
- if (reg[0] == '.') {
- clif_displaymessage(fd, msg_txt(1371)); // NPC variables may not be used with @set.
- return -1;
- } else if (reg[0] == '\'') {
- clif_displaymessage(fd, msg_txt(1372)); // Instance variables may not be used with @set.
- return -1;
- }
-
- is_str = (reg[strlen(reg) - 1] == '$') ? true : false;
-
- if (toset >= 2) { /* we only set the var if there is an val, otherwise we only output the value */
- if (is_str)
- set_var(sd, reg, (void *) val);
- else
- set_var(sd, reg, (void *)__64BPRTSIZE((int)(atoi(val))));
-
- }
-
- CREATE(data, struct script_data,1);
-
-
- if (is_str) { // string variable
-
- switch (reg[0]) {
- case '@':
- data->u.str = pc_readregstr(sd, add_str(reg));
- break;
- case '$':
- data->u.str = mapreg_readregstr(add_str(reg));
- break;
- case '#':
- if (reg[1] == '#')
- data->u.str = pc_readaccountreg2str(sd, reg);// global
- else
- data->u.str = pc_readaccountregstr(sd, reg);// local
- break;
- default:
- data->u.str = pc_readglobalreg_str(sd, reg);
- break;
- }
-
- if (data->u.str == NULL || data->u.str[0] == '\0') { // empty string
- data->type = C_CONSTSTR;
- data->u.str = "";
- } else {// duplicate string
- data->type = C_STR;
- data->u.str = aStrdup(data->u.str);
- }
-
- } else {// integer variable
-
- data->type = C_INT;
- switch (reg[0]) {
- case '@':
- data->u.num = pc_readreg(sd, add_str(reg));
- break;
- case '$':
- data->u.num = mapreg_readreg(add_str(reg));
- break;
- case '#':
- if (reg[1] == '#')
- data->u.num = pc_readaccountreg2(sd, reg);// global
- else
- data->u.num = pc_readaccountreg(sd, reg);// local
- break;
- default:
- data->u.num = pc_readglobalreg(sd, reg);
- break;
- }
-
- }
-
-
- switch (data->type) {
- case C_INT:
- sprintf(atcmd_output,msg_txt(1373),reg,data->u.num); // %s value is now :%d
- break;
- case C_STR:
- sprintf(atcmd_output,msg_txt(1374),reg,data->u.str); // %s value is now :%s
- break;
- case C_CONSTSTR:
- sprintf(atcmd_output,msg_txt(1375),reg); // %s is empty
- break;
- default:
- sprintf(atcmd_output,msg_txt(1376),reg,data->type); // %s data type is not supported :%u
- break;
- }
-
- clif_displaymessage(fd, atcmd_output);
-
- aFree(data);
-
- return 0;
-}
-ACMD_FUNC(reloadquestdb)
-{
- do_reload_quest();
- clif_displaymessage(fd, msg_txt(1377)); // Quest database has been reloaded.
- return 0;
-}
-ACMD_FUNC(addperm)
-{
- int perm_size = ARRAYLENGTH(pc_g_permission_name);
- bool add = (strcmpi(command+1, "addperm") == 0) ? true : false;
- int i;
-
- if (!message || !*message) {
- sprintf(atcmd_output, msg_txt(1378),command); // Usage: %s <permission_name>
- clif_displaymessage(fd, atcmd_output);
- clif_displaymessage(fd, msg_txt(1379)); // -- Permission List
- for (i = 0; i < perm_size; i++) {
- sprintf(atcmd_output,"- %s",pc_g_permission_name[i].name);
- clif_displaymessage(fd, atcmd_output);
- }
- return -1;
- }
-
- ARR_FIND(0, perm_size, i, strcmpi(pc_g_permission_name[i].name, message) == 0);
-
- if (i == perm_size) {
- sprintf(atcmd_output,msg_txt(1380),message); // '%s' is not a known permission.
- clif_displaymessage(fd, atcmd_output);
- clif_displaymessage(fd, msg_txt(1379)); // -- Permission List
- for (i = 0; i < perm_size; i++) {
- sprintf(atcmd_output,"- %s",pc_g_permission_name[i].name);
- clif_displaymessage(fd, atcmd_output);
- }
- return -1;
- }
-
- if (add && (sd->permissions&pc_g_permission_name[i].permission)) {
- sprintf(atcmd_output, msg_txt(1381),sd->status.name,pc_g_permission_name[i].name); // User '%s' already possesses the '%s' permission.
- clif_displaymessage(fd, atcmd_output);
- return -1;
- } else if (!add && !(sd->permissions&pc_g_permission_name[i].permission)) {
- sprintf(atcmd_output, msg_txt(1382),sd->status.name,pc_g_permission_name[i].name); // User '%s' doesn't possess the '%s' permission.
- clif_displaymessage(fd, atcmd_output);
- sprintf(atcmd_output,msg_txt(1383),sd->status.name); // -- User '%s' Permissions
- clif_displaymessage(fd, atcmd_output);
- for (i = 0; i < perm_size; i++) {
- if (sd->permissions&pc_g_permission_name[i].permission) {
- sprintf(atcmd_output,"- %s",pc_g_permission_name[i].name);
- clif_displaymessage(fd, atcmd_output);
- }
- }
-
- return -1;
- }
-
- if (add)
- sd->permissions |= pc_g_permission_name[i].permission;
- else
- sd->permissions &=~ pc_g_permission_name[i].permission;
-
-
- sprintf(atcmd_output, msg_txt(1384),sd->status.name); // User '%s' permissions updated successfully. The changes are temporary.
- clif_displaymessage(fd, atcmd_output);
-
- return 0;
-}
-ACMD_FUNC(unloadnpcfile)
-{
-
- if (!message || !*message) {
- clif_displaymessage(fd, msg_txt(1385)); // Usage: @unloadnpcfile <file name>
- return -1;
- }
-
- if (npc_unloadfile(message))
- clif_displaymessage(fd, msg_txt(1386)); // File unloaded. Be aware that mapflags and monsters spawned directly are not removed.
- else {
- clif_displaymessage(fd, msg_txt(1387)); // File not found.
- return -1;
- }
- return 0;
-}
-ACMD_FUNC(cart)
-{
+ACMD_FUNC(set) {
+ char reg[32], val[128];
+ struct script_data* data;
+ int toset = 0;
+ bool is_str = false;
+
+ if( !message || !*message || (toset = sscanf(message, "%32s %128[^\n]s", reg, val)) < 1 ) {
+ clif_displaymessage(fd, msg_txt(1367)); // Usage: @set <variable name> <value>
+ clif_displaymessage(fd, msg_txt(1368)); // Usage: ex. "@set PoringCharVar 50"
+ clif_displaymessage(fd, msg_txt(1369)); // Usage: ex. "@set PoringCharVarSTR$ Super Duper String"
+ clif_displaymessage(fd, msg_txt(1370)); // Usage: ex. "@set PoringCharVarSTR$" outputs its value, Super Duper String.
+ return -1;
+ }
+
+ /* disabled variable types (they require a proper script state to function, so allowing them would crash the server) */
+ if( reg[0] == '.' ) {
+ clif_displaymessage(fd, msg_txt(1371)); // NPC variables may not be used with @set.
+ return -1;
+ } else if( reg[0] == '\'' ) {
+ clif_displaymessage(fd, msg_txt(1372)); // Instance variables may not be used with @set.
+ return -1;
+ }
+
+ is_str = ( reg[strlen(reg) - 1] == '$' ) ? true : false;
+
+ if( toset >= 2 ) {/* we only set the var if there is an val, otherwise we only output the value */
+ if( is_str )
+ set_var(sd, reg, (void*) val);
+ else
+ set_var(sd, reg, (void*)__64BPRTSIZE((int)(atoi(val))));
+
+ }
+
+ CREATE(data, struct script_data,1);
+
+
+ if( is_str ) {// string variable
+
+ switch( reg[0] ) {
+ case '@':
+ data->u.str = pc_readregstr(sd, add_str(reg));
+ break;
+ case '$':
+ data->u.str = mapreg_readregstr(add_str(reg));
+ break;
+ case '#':
+ if( reg[1] == '#' )
+ data->u.str = pc_readaccountreg2str(sd, reg);// global
+ else
+ data->u.str = pc_readaccountregstr(sd, reg);// local
+ break;
+ default:
+ data->u.str = pc_readglobalreg_str(sd, reg);
+ break;
+ }
+
+ if( data->u.str == NULL || data->u.str[0] == '\0' ) {// empty string
+ data->type = C_CONSTSTR;
+ data->u.str = "";
+ } else {// duplicate string
+ data->type = C_STR;
+ data->u.str = aStrdup(data->u.str);
+ }
+
+ } else {// integer variable
+
+ data->type = C_INT;
+ switch( reg[0] ) {
+ case '@':
+ data->u.num = pc_readreg(sd, add_str(reg));
+ break;
+ case '$':
+ data->u.num = mapreg_readreg(add_str(reg));
+ break;
+ case '#':
+ if( reg[1] == '#' )
+ data->u.num = pc_readaccountreg2(sd, reg);// global
+ else
+ data->u.num = pc_readaccountreg(sd, reg);// local
+ break;
+ default:
+ data->u.num = pc_readglobalreg(sd, reg);
+ break;
+ }
+
+ }
+
+
+ switch( data->type ) {
+ case C_INT:
+ sprintf(atcmd_output,msg_txt(1373),reg,data->u.num); // %s value is now :%d
+ break;
+ case C_STR:
+ sprintf(atcmd_output,msg_txt(1374),reg,data->u.str); // %s value is now :%s
+ break;
+ case C_CONSTSTR:
+ sprintf(atcmd_output,msg_txt(1375),reg); // %s is empty
+ break;
+ default:
+ sprintf(atcmd_output,msg_txt(1376),reg,data->type); // %s data type is not supported :%u
+ break;
+ }
+
+ clif_displaymessage(fd, atcmd_output);
+
+ aFree(data);
+
+ return 0;
+}
+ACMD_FUNC(reloadquestdb) {
+ do_reload_quest();
+ clif_displaymessage(fd, msg_txt(1377)); // Quest database has been reloaded.
+ return 0;
+}
+ACMD_FUNC(addperm) {
+ int perm_size = ARRAYLENGTH(pc_g_permission_name);
+ bool add = (strcmpi(command+1, "addperm") == 0) ? true : false;
+ int i;
+
+ if( !message || !*message ) {
+ sprintf(atcmd_output, msg_txt(1378),command); // Usage: %s <permission_name>
+ clif_displaymessage(fd, atcmd_output);
+ clif_displaymessage(fd, msg_txt(1379)); // -- Permission List
+ for( i = 0; i < perm_size; i++ ) {
+ sprintf(atcmd_output,"- %s",pc_g_permission_name[i].name);
+ clif_displaymessage(fd, atcmd_output);
+ }
+ return -1;
+ }
+
+ ARR_FIND(0, perm_size, i, strcmpi(pc_g_permission_name[i].name, message) == 0);
+
+ if( i == perm_size ) {
+ sprintf(atcmd_output,msg_txt(1380),message); // '%s' is not a known permission.
+ clif_displaymessage(fd, atcmd_output);
+ clif_displaymessage(fd, msg_txt(1379)); // -- Permission List
+ for( i = 0; i < perm_size; i++ ) {
+ sprintf(atcmd_output,"- %s",pc_g_permission_name[i].name);
+ clif_displaymessage(fd, atcmd_output);
+ }
+ return -1;
+ }
+
+ if( add && (sd->permissions&pc_g_permission_name[i].permission) ) {
+ sprintf(atcmd_output, msg_txt(1381),sd->status.name,pc_g_permission_name[i].name); // User '%s' already possesses the '%s' permission.
+ clif_displaymessage(fd, atcmd_output);
+ return -1;
+ } else if ( !add && !(sd->permissions&pc_g_permission_name[i].permission) ) {
+ sprintf(atcmd_output, msg_txt(1382),sd->status.name,pc_g_permission_name[i].name); // User '%s' doesn't possess the '%s' permission.
+ clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output,msg_txt(1383),sd->status.name); // -- User '%s' Permissions
+ clif_displaymessage(fd, atcmd_output);
+ for( i = 0; i < perm_size; i++ ) {
+ if( sd->permissions&pc_g_permission_name[i].permission ) {
+ sprintf(atcmd_output,"- %s",pc_g_permission_name[i].name);
+ clif_displaymessage(fd, atcmd_output);
+ }
+ }
+
+ return -1;
+ }
+
+ if( add )
+ sd->permissions |= pc_g_permission_name[i].permission;
+ else
+ sd->permissions &=~ pc_g_permission_name[i].permission;
+
+
+ sprintf(atcmd_output, msg_txt(1384),sd->status.name); // User '%s' permissions updated successfully. The changes are temporary.
+ clif_displaymessage(fd, atcmd_output);
+
+ return 0;
+}
+ACMD_FUNC(unloadnpcfile) {
+
+ if( !message || !*message ) {
+ clif_displaymessage(fd, msg_txt(1385)); // Usage: @unloadnpcfile <file name>
+ return -1;
+ }
+
+ if( npc_unloadfile(message) )
+ clif_displaymessage(fd, msg_txt(1386)); // File unloaded. Be aware that mapflags and monsters spawned directly are not removed.
+ else {
+ clif_displaymessage(fd, msg_txt(1387)); // File not found.
+ return -1;
+ }
+ return 0;
+}
+ACMD_FUNC(cart) {
#define MC_CART_MDFY(x) \
- sd->status.skill[MC_PUSHCART].id = x?MC_PUSHCART:0; \
- sd->status.skill[MC_PUSHCART].lv = x?1:0; \
- sd->status.skill[MC_PUSHCART].flag = x?1:0;
+ sd->status.skill[MC_PUSHCART].id = x?MC_PUSHCART:0; \
+ sd->status.skill[MC_PUSHCART].lv = x?1:0; \
+ sd->status.skill[MC_PUSHCART].flag = x?1:0;
- int val = atoi(message);
- bool need_skill = pc_checkskill(sd, MC_PUSHCART) ? false : true;
+ int val = atoi(message);
+ bool need_skill = pc_checkskill(sd, MC_PUSHCART) ? false : true;
- if (!message || !*message || val < 0 || val > MAX_CARTS) {
- sprintf(atcmd_output, msg_txt(1390),command,MAX_CARTS); // Unknown Cart (usage: %s <0-%d>).
- clif_displaymessage(fd, atcmd_output);
- return -1;
- }
+ if( !message || !*message || val < 0 || val > MAX_CARTS ) {
+ sprintf(atcmd_output, msg_txt(1390),command,MAX_CARTS); // Unknown Cart (usage: %s <0-%d>).
+ clif_displaymessage(fd, atcmd_output);
+ return -1;
+ }
- if (val == 0 && !pc_iscarton(sd)) {
- clif_displaymessage(fd, msg_txt(1391)); // You do not possess a cart to be removed
- return -1;
- }
+ if( val == 0 && !pc_iscarton(sd) ) {
+ clif_displaymessage(fd, msg_txt(1391)); // You do not possess a cart to be removed
+ return -1;
+ }
- if (need_skill) {
- MC_CART_MDFY(1);
- }
+ if( need_skill ) {
+ MC_CART_MDFY(1);
+ }
- if (pc_setcart(sd, val)) {
- if (need_skill) {
- MC_CART_MDFY(0);
- }
- return -1;/* @cart failed */
- }
+ if( pc_setcart(sd, val) ) {
+ if( need_skill ) {
+ MC_CART_MDFY(0);
+ }
+ return -1;/* @cart failed */
+ }
- if (need_skill) {
- MC_CART_MDFY(0);
- }
+ if( need_skill ) {
+ MC_CART_MDFY(0);
+ }
- clif_displaymessage(fd, msg_txt(1392)); // Cart Added
+ clif_displaymessage(fd, msg_txt(1392)); // Cart Added
- return 0;
-#undef MC_CART_MDFY
+ return 0;
+ #undef MC_CART_MDFY
}
/**
@@ -8656,697 +8814,693 @@ ACMD_FUNC(cart)
**/
#define ACMD_DEF(x) { #x, atcommand_ ## x, NULL, NULL }
#define ACMD_DEF2(x2, x) { x2, atcommand_ ## x, NULL, NULL }
-void atcommand_basecommands(void)
-{
- /**
- * Command reference list, place the base of your commands here
- **/
- AtCommandInfo atcommand_base[] = {
- ACMD_DEF2("warp", mapmove),
- ACMD_DEF(where),
- ACMD_DEF(jumpto),
- ACMD_DEF(jump),
- ACMD_DEF(who),
- ACMD_DEF2("who2", who),
- ACMD_DEF2("who3", who),
- ACMD_DEF2("whomap", who),
- ACMD_DEF2("whomap2", who),
- ACMD_DEF2("whomap3", who),
- ACMD_DEF(whogm),
- ACMD_DEF(save),
- ACMD_DEF(load),
- ACMD_DEF(speed),
- ACMD_DEF(storage),
- ACMD_DEF(guildstorage),
- ACMD_DEF(option),
- ACMD_DEF(hide), // + /hide
- ACMD_DEF(jobchange),
- ACMD_DEF(kill),
- ACMD_DEF(alive),
- ACMD_DEF(kami),
- ACMD_DEF2("kamib", kami),
- ACMD_DEF2("kamic", kami),
- ACMD_DEF2("lkami", kami),
- ACMD_DEF(heal),
- ACMD_DEF(item),
- ACMD_DEF(item2),
- ACMD_DEF(itemreset),
- ACMD_DEF2("blvl", baselevelup),
- ACMD_DEF2("jlvl", joblevelup),
- ACMD_DEF(help),
- ACMD_DEF(pvpoff),
- ACMD_DEF(pvpon),
- ACMD_DEF(gvgoff),
- ACMD_DEF(gvgon),
- ACMD_DEF(model),
- ACMD_DEF(go),
- ACMD_DEF(monster),
- ACMD_DEF2("monstersmall", monster),
- ACMD_DEF2("monsterbig", monster),
- ACMD_DEF(killmonster),
- ACMD_DEF2("killmonster2", killmonster),
- ACMD_DEF(refine),
- ACMD_DEF(produce),
- ACMD_DEF(memo),
- ACMD_DEF(gat),
- ACMD_DEF(displaystatus),
- ACMD_DEF2("stpoint", statuspoint),
- ACMD_DEF2("skpoint", skillpoint),
- ACMD_DEF(zeny),
- ACMD_DEF2("str", param),
- ACMD_DEF2("agi", param),
- ACMD_DEF2("vit", param),
- ACMD_DEF2("int", param),
- ACMD_DEF2("dex", param),
- ACMD_DEF2("luk", param),
- ACMD_DEF2("glvl", guildlevelup),
- ACMD_DEF(makeegg),
- ACMD_DEF(hatch),
- ACMD_DEF(petfriendly),
- ACMD_DEF(pethungry),
- ACMD_DEF(petrename),
- ACMD_DEF(recall), // + /recall
- ACMD_DEF(night),
- ACMD_DEF(day),
- ACMD_DEF(doom),
- ACMD_DEF(doommap),
- ACMD_DEF(raise),
- ACMD_DEF(raisemap),
- ACMD_DEF(kick), // + right click menu for GM "(name) force to quit"
- ACMD_DEF(kickall),
- ACMD_DEF(allskill),
- ACMD_DEF(questskill),
- ACMD_DEF(lostskill),
- ACMD_DEF(spiritball),
- ACMD_DEF(party),
- ACMD_DEF(guild),
- ACMD_DEF(agitstart),
- ACMD_DEF(agitend),
- ACMD_DEF(mapexit),
- ACMD_DEF(idsearch),
- ACMD_DEF(broadcast), // + /b and /nb
- ACMD_DEF(localbroadcast), // + /lb and /nlb
- ACMD_DEF(recallall),
- ACMD_DEF(reloaditemdb),
- ACMD_DEF(reloadmobdb),
- ACMD_DEF(reloadskilldb),
- ACMD_DEF(reloadscript),
- ACMD_DEF(reloadatcommand),
- ACMD_DEF(reloadbattleconf),
- ACMD_DEF(reloadstatusdb),
- ACMD_DEF(reloadpcdb),
- ACMD_DEF(reloadmotd),
- ACMD_DEF(mapinfo),
- ACMD_DEF(dye),
- ACMD_DEF2("hairstyle", hair_style),
- ACMD_DEF2("haircolor", hair_color),
- ACMD_DEF2("allstats", stat_all),
- ACMD_DEF2("block", char_block),
- ACMD_DEF2("ban", char_ban),
- ACMD_DEF2("unblock", char_unblock),
- ACMD_DEF2("unban", char_unban),
- ACMD_DEF2("mount", mount_peco),
- ACMD_DEF(guildspy),
- ACMD_DEF(partyspy),
- ACMD_DEF(repairall),
- ACMD_DEF(guildrecall),
- ACMD_DEF(partyrecall),
- ACMD_DEF(nuke),
- ACMD_DEF(shownpc),
- ACMD_DEF(hidenpc),
- ACMD_DEF(loadnpc),
- ACMD_DEF(unloadnpc),
- ACMD_DEF2("time", servertime),
- ACMD_DEF(jail),
- ACMD_DEF(unjail),
- ACMD_DEF(jailfor),
- ACMD_DEF(jailtime),
- ACMD_DEF(disguise),
- ACMD_DEF(undisguise),
- ACMD_DEF(email),
- ACMD_DEF(effect),
- ACMD_DEF(follow),
- ACMD_DEF(addwarp),
- ACMD_DEF(skillon),
- ACMD_DEF(skilloff),
- ACMD_DEF(killer),
- ACMD_DEF(npcmove),
- ACMD_DEF(killable),
- ACMD_DEF(dropall),
- ACMD_DEF(storeall),
- ACMD_DEF(skillid),
- ACMD_DEF(useskill),
- ACMD_DEF(displayskill),
- ACMD_DEF(snow),
- ACMD_DEF(sakura),
- ACMD_DEF(clouds),
- ACMD_DEF(clouds2),
- ACMD_DEF(fog),
- ACMD_DEF(fireworks),
- ACMD_DEF(leaves),
- ACMD_DEF(summon),
- ACMD_DEF(adjgroup),
- ACMD_DEF(trade),
- ACMD_DEF(send),
- ACMD_DEF(setbattleflag),
- ACMD_DEF(unmute),
- ACMD_DEF(clearweather),
- ACMD_DEF(uptime),
- ACMD_DEF(changesex),
- ACMD_DEF(mute),
- ACMD_DEF(refresh),
- ACMD_DEF(identify),
- ACMD_DEF(gmotd),
- ACMD_DEF(misceffect),
- ACMD_DEF(mobsearch),
- ACMD_DEF(cleanmap),
- ACMD_DEF(cleanarea),
- ACMD_DEF(npctalk),
- ACMD_DEF(pettalk),
- ACMD_DEF(users),
- ACMD_DEF(reset),
- ACMD_DEF(skilltree),
- ACMD_DEF(marry),
- ACMD_DEF(divorce),
- ACMD_DEF(sound),
- ACMD_DEF(undisguiseall),
- ACMD_DEF(disguiseall),
- ACMD_DEF(changelook),
- ACMD_DEF(autoloot),
- ACMD_DEF2("alootid", autolootitem),
- ACMD_DEF(mobinfo),
- ACMD_DEF(exp),
- ACMD_DEF(adopt),
- ACMD_DEF(version),
- ACMD_DEF(mutearea),
- ACMD_DEF(rates),
- ACMD_DEF(iteminfo),
- ACMD_DEF(whodrops),
- ACMD_DEF(whereis),
- ACMD_DEF(mapflag),
- ACMD_DEF(me),
- ACMD_DEF(monsterignore),
- ACMD_DEF(fakename),
- ACMD_DEF(size),
- ACMD_DEF(showexp),
- ACMD_DEF(showzeny),
- ACMD_DEF(showdelay),
- ACMD_DEF(autotrade),
- ACMD_DEF(changegm),
- ACMD_DEF(changeleader),
- ACMD_DEF(partyoption),
- ACMD_DEF(invite),
- ACMD_DEF(duel),
- ACMD_DEF(leave),
- ACMD_DEF(accept),
- ACMD_DEF(reject),
- ACMD_DEF(main),
- ACMD_DEF(clone),
- ACMD_DEF2("slaveclone", clone),
- ACMD_DEF2("evilclone", clone),
- ACMD_DEF(tonpc),
- ACMD_DEF(commands),
- ACMD_DEF(noask),
- ACMD_DEF(request),
- ACMD_DEF(homlevel),
- ACMD_DEF(homevolution),
- ACMD_DEF(makehomun),
- ACMD_DEF(homfriendly),
- ACMD_DEF(homhungry),
- ACMD_DEF(homtalk),
- ACMD_DEF(hominfo),
- ACMD_DEF(homstats),
- ACMD_DEF(homshuffle),
- ACMD_DEF(showmobs),
- ACMD_DEF(feelreset),
- ACMD_DEF(auction),
- ACMD_DEF(mail),
- ACMD_DEF2("noks", ksprotection),
- ACMD_DEF(allowks),
- ACMD_DEF(cash),
- ACMD_DEF2("points", cash),
- ACMD_DEF(agitstart2),
- ACMD_DEF(agitend2),
- ACMD_DEF2("skreset", resetskill),
- ACMD_DEF2("streset", resetstat),
- ACMD_DEF2("storagelist", itemlist),
- ACMD_DEF2("cartlist", itemlist),
- ACMD_DEF2("itemlist", itemlist),
- ACMD_DEF(stats),
- ACMD_DEF(delitem),
- ACMD_DEF(charcommands),
- ACMD_DEF(font),
- ACMD_DEF(accinfo),
- ACMD_DEF(set),
- ACMD_DEF(reloadquestdb),
- ACMD_DEF(undisguiseguild),
- ACMD_DEF(disguiseguild),
- ACMD_DEF(sizeall),
- ACMD_DEF(sizeguild),
- ACMD_DEF(addperm),
- ACMD_DEF2("rmvperm", addperm),
- ACMD_DEF(unloadnpcfile),
- ACMD_DEF(cart),
- ACMD_DEF(mount2)
- };
- AtCommandInfo *atcommand;
- int i;
-
- for (i = 0; i < ARRAYLENGTH(atcommand_base); i++) {
- if (atcommand_exists(atcommand_base[i].command)) { // Should not happen if atcommand_base[] array is OK
- ShowDebug("atcommand_basecommands: duplicate ACMD_DEF for '%s'.\n", atcommand_base[i].command);
- continue;
- }
- CREATE(atcommand, AtCommandInfo, 1);
- safestrncpy(atcommand->command, atcommand_base[i].command, sizeof(atcommand->command));
- atcommand->func = atcommand_base[i].func;
- strdb_put(atcommand_db, atcommand->command, atcommand);
- }
- return;
+void atcommand_basecommands(void) {
+ /**
+ * Command reference list, place the base of your commands here
+ **/
+ AtCommandInfo atcommand_base[] = {
+ ACMD_DEF2("warp", mapmove),
+ ACMD_DEF(where),
+ ACMD_DEF(jumpto),
+ ACMD_DEF(jump),
+ ACMD_DEF(who),
+ ACMD_DEF2("who2", who),
+ ACMD_DEF2("who3", who),
+ ACMD_DEF2("whomap", who),
+ ACMD_DEF2("whomap2", who),
+ ACMD_DEF2("whomap3", who),
+ ACMD_DEF(whogm),
+ ACMD_DEF(save),
+ ACMD_DEF(load),
+ ACMD_DEF(speed),
+ ACMD_DEF(storage),
+ ACMD_DEF(guildstorage),
+ ACMD_DEF(option),
+ ACMD_DEF(hide), // + /hide
+ ACMD_DEF(jobchange),
+ ACMD_DEF(kill),
+ ACMD_DEF(alive),
+ ACMD_DEF(kami),
+ ACMD_DEF2("kamib", kami),
+ ACMD_DEF2("kamic", kami),
+ ACMD_DEF2("lkami", kami),
+ ACMD_DEF(heal),
+ ACMD_DEF(item),
+ ACMD_DEF(item2),
+ ACMD_DEF(itemreset),
+ ACMD_DEF2("blvl", baselevelup),
+ ACMD_DEF2("jlvl", joblevelup),
+ ACMD_DEF(help),
+ ACMD_DEF(pvpoff),
+ ACMD_DEF(pvpon),
+ ACMD_DEF(gvgoff),
+ ACMD_DEF(gvgon),
+ ACMD_DEF(model),
+ ACMD_DEF(go),
+ ACMD_DEF(monster),
+ ACMD_DEF2("monstersmall", monster),
+ ACMD_DEF2("monsterbig", monster),
+ ACMD_DEF(killmonster),
+ ACMD_DEF2("killmonster2", killmonster),
+ ACMD_DEF(refine),
+ ACMD_DEF(produce),
+ ACMD_DEF(memo),
+ ACMD_DEF(gat),
+ ACMD_DEF(displaystatus),
+ ACMD_DEF2("stpoint", statuspoint),
+ ACMD_DEF2("skpoint", skillpoint),
+ ACMD_DEF(zeny),
+ ACMD_DEF2("str", param),
+ ACMD_DEF2("agi", param),
+ ACMD_DEF2("vit", param),
+ ACMD_DEF2("int", param),
+ ACMD_DEF2("dex", param),
+ ACMD_DEF2("luk", param),
+ ACMD_DEF2("glvl", guildlevelup),
+ ACMD_DEF(makeegg),
+ ACMD_DEF(hatch),
+ ACMD_DEF(petfriendly),
+ ACMD_DEF(pethungry),
+ ACMD_DEF(petrename),
+ ACMD_DEF(recall), // + /recall
+ ACMD_DEF(night),
+ ACMD_DEF(day),
+ ACMD_DEF(doom),
+ ACMD_DEF(doommap),
+ ACMD_DEF(raise),
+ ACMD_DEF(raisemap),
+ ACMD_DEF(kick), // + right click menu for GM "(name) force to quit"
+ ACMD_DEF(kickall),
+ ACMD_DEF(allskill),
+ ACMD_DEF(questskill),
+ ACMD_DEF(lostskill),
+ ACMD_DEF(spiritball),
+ ACMD_DEF(party),
+ ACMD_DEF(guild),
+ ACMD_DEF(agitstart),
+ ACMD_DEF(agitend),
+ ACMD_DEF(mapexit),
+ ACMD_DEF(idsearch),
+ ACMD_DEF(broadcast), // + /b and /nb
+ ACMD_DEF(localbroadcast), // + /lb and /nlb
+ ACMD_DEF(recallall),
+ ACMD_DEF(reloaditemdb),
+ ACMD_DEF(reloadmobdb),
+ ACMD_DEF(reloadskilldb),
+ ACMD_DEF(reloadscript),
+ ACMD_DEF(reloadatcommand),
+ ACMD_DEF(reloadbattleconf),
+ ACMD_DEF(reloadstatusdb),
+ ACMD_DEF(reloadpcdb),
+ ACMD_DEF(reloadmotd),
+ ACMD_DEF(mapinfo),
+ ACMD_DEF(dye),
+ ACMD_DEF2("hairstyle", hair_style),
+ ACMD_DEF2("haircolor", hair_color),
+ ACMD_DEF2("allstats", stat_all),
+ ACMD_DEF2("block", char_block),
+ ACMD_DEF2("ban", char_ban),
+ ACMD_DEF2("unblock", char_unblock),
+ ACMD_DEF2("unban", char_unban),
+ ACMD_DEF2("mount", mount_peco),
+ ACMD_DEF(guildspy),
+ ACMD_DEF(partyspy),
+ ACMD_DEF(repairall),
+ ACMD_DEF(guildrecall),
+ ACMD_DEF(partyrecall),
+ ACMD_DEF(nuke),
+ ACMD_DEF(shownpc),
+ ACMD_DEF(hidenpc),
+ ACMD_DEF(loadnpc),
+ ACMD_DEF(unloadnpc),
+ ACMD_DEF2("time", servertime),
+ ACMD_DEF(jail),
+ ACMD_DEF(unjail),
+ ACMD_DEF(jailfor),
+ ACMD_DEF(jailtime),
+ ACMD_DEF(disguise),
+ ACMD_DEF(undisguise),
+ ACMD_DEF(email),
+ ACMD_DEF(effect),
+ ACMD_DEF(follow),
+ ACMD_DEF(addwarp),
+ ACMD_DEF(skillon),
+ ACMD_DEF(skilloff),
+ ACMD_DEF(killer),
+ ACMD_DEF(npcmove),
+ ACMD_DEF(killable),
+ ACMD_DEF(dropall),
+ ACMD_DEF(storeall),
+ ACMD_DEF(skillid),
+ ACMD_DEF(useskill),
+ ACMD_DEF(displayskill),
+ ACMD_DEF(snow),
+ ACMD_DEF(sakura),
+ ACMD_DEF(clouds),
+ ACMD_DEF(clouds2),
+ ACMD_DEF(fog),
+ ACMD_DEF(fireworks),
+ ACMD_DEF(leaves),
+ ACMD_DEF(summon),
+ ACMD_DEF(adjgroup),
+ ACMD_DEF(trade),
+ ACMD_DEF(send),
+ ACMD_DEF(setbattleflag),
+ ACMD_DEF(unmute),
+ ACMD_DEF(clearweather),
+ ACMD_DEF(uptime),
+ ACMD_DEF(changesex),
+ ACMD_DEF(mute),
+ ACMD_DEF(refresh),
+ ACMD_DEF(identify),
+ ACMD_DEF(gmotd),
+ ACMD_DEF(misceffect),
+ ACMD_DEF(mobsearch),
+ ACMD_DEF(cleanmap),
+ ACMD_DEF(npctalk),
+ ACMD_DEF(pettalk),
+ ACMD_DEF(users),
+ ACMD_DEF(reset),
+ ACMD_DEF(skilltree),
+ ACMD_DEF(marry),
+ ACMD_DEF(divorce),
+ ACMD_DEF(sound),
+ ACMD_DEF(undisguiseall),
+ ACMD_DEF(disguiseall),
+ ACMD_DEF(changelook),
+ ACMD_DEF(autoloot),
+ ACMD_DEF2("alootid", autolootitem),
+ ACMD_DEF(mobinfo),
+ ACMD_DEF(exp),
+ ACMD_DEF(adopt),
+ ACMD_DEF(version),
+ ACMD_DEF(mutearea),
+ ACMD_DEF(rates),
+ ACMD_DEF(iteminfo),
+ ACMD_DEF(whodrops),
+ ACMD_DEF(whereis),
+ ACMD_DEF(mapflag),
+ ACMD_DEF(me),
+ ACMD_DEF(monsterignore),
+ ACMD_DEF(fakename),
+ ACMD_DEF(size),
+ ACMD_DEF(showexp),
+ ACMD_DEF(showzeny),
+ ACMD_DEF(showdelay),
+ ACMD_DEF(autotrade),
+ ACMD_DEF(changegm),
+ ACMD_DEF(changeleader),
+ ACMD_DEF(partyoption),
+ ACMD_DEF(invite),
+ ACMD_DEF(duel),
+ ACMD_DEF(leave),
+ ACMD_DEF(accept),
+ ACMD_DEF(reject),
+ ACMD_DEF(main),
+ ACMD_DEF(clone),
+ ACMD_DEF2("slaveclone", clone),
+ ACMD_DEF2("evilclone", clone),
+ ACMD_DEF(tonpc),
+ ACMD_DEF(commands),
+ ACMD_DEF(noask),
+ ACMD_DEF(request),
+ ACMD_DEF(homlevel),
+ ACMD_DEF(homevolution),
+ ACMD_DEF(makehomun),
+ ACMD_DEF(homfriendly),
+ ACMD_DEF(homhungry),
+ ACMD_DEF(homtalk),
+ ACMD_DEF(hominfo),
+ ACMD_DEF(homstats),
+ ACMD_DEF(homshuffle),
+ ACMD_DEF(showmobs),
+ ACMD_DEF(feelreset),
+ ACMD_DEF(auction),
+ ACMD_DEF(mail),
+ ACMD_DEF2("noks", ksprotection),
+ ACMD_DEF(allowks),
+ ACMD_DEF(cash),
+ ACMD_DEF2("points", cash),
+ ACMD_DEF(agitstart2),
+ ACMD_DEF(agitend2),
+ ACMD_DEF2("skreset", resetskill),
+ ACMD_DEF2("streset", resetstat),
+ ACMD_DEF2("storagelist", itemlist),
+ ACMD_DEF2("cartlist", itemlist),
+ ACMD_DEF2("itemlist", itemlist),
+ ACMD_DEF(stats),
+ ACMD_DEF(delitem),
+ ACMD_DEF(charcommands),
+ ACMD_DEF(font),
+ ACMD_DEF(accinfo),
+ ACMD_DEF(set),
+ ACMD_DEF(reloadquestdb),
+ ACMD_DEF(undisguiseguild),
+ ACMD_DEF(disguiseguild),
+ ACMD_DEF(sizeall),
+ ACMD_DEF(sizeguild),
+ ACMD_DEF(addperm),
+ ACMD_DEF2("rmvperm", addperm),
+ ACMD_DEF(unloadnpcfile),
+ ACMD_DEF(cart),
+ ACMD_DEF(mount2)
+ };
+ AtCommandInfo* atcommand;
+ int i;
+
+ for( i = 0; i < ARRAYLENGTH(atcommand_base); i++ ) {
+ if(atcommand_exists(atcommand_base[i].command)) { // Should not happen if atcommand_base[] array is OK
+ ShowDebug("atcommand_basecommands: duplicate ACMD_DEF for '%s'.\n", atcommand_base[i].command);
+ continue;
+ }
+ CREATE(atcommand, AtCommandInfo, 1);
+ safestrncpy(atcommand->command, atcommand_base[i].command, sizeof(atcommand->command));
+ atcommand->func = atcommand_base[i].func;
+ strdb_put(atcommand_db, atcommand->command, atcommand);
+ }
+ return;
}
/*==========================================
* Command lookup functions
*------------------------------------------*/
-bool atcommand_exists(const char *name)
+bool atcommand_exists(const char* name)
{
- return strdb_exists(atcommand_db, name);
+ return strdb_exists(atcommand_db, name);
}
-static AtCommandInfo *get_atcommandinfo_byname(const char *name)
+static AtCommandInfo* get_atcommandinfo_byname(const char *name)
{
- if (strdb_exists(atcommand_db, name))
- return (AtCommandInfo *)strdb_get(atcommand_db, name);
- return NULL;
+ if (strdb_exists(atcommand_db, name))
+ return (AtCommandInfo*)strdb_get(atcommand_db, name);
+ return NULL;
}
-static const char *atcommand_checkalias(const char *aliasname)
+static const char* atcommand_checkalias(const char *aliasname)
{
- AliasInfo *alias_info = NULL;
- if ((alias_info = (AliasInfo *)strdb_get(atcommand_alias_db, aliasname)) != NULL)
- return alias_info->command->command;
- return aliasname;
+ AliasInfo *alias_info = NULL;
+ if ((alias_info = (AliasInfo*)strdb_get(atcommand_alias_db, aliasname)) != NULL)
+ return alias_info->command->command;
+ return aliasname;
}
/// AtCommand suggestion
-static void atcommand_get_suggestions(struct map_session_data *sd, const char *name, bool atcommand)
-{
- DBIterator *atcommand_iter;
- DBIterator *alias_iter;
- AtCommandInfo *command_info = NULL;
- AliasInfo *alias_info = NULL;
- AtCommandType type = atcommand ? COMMAND_ATCOMMAND : COMMAND_CHARCOMMAND;
- char *full_match[MAX_SUGGESTIONS];
- char *suggestions[MAX_SUGGESTIONS];
- char *match;
- int prefix_count = 0, full_count = 0;
- bool can_use;
-
- if (!battle_config.atcommand_suggestions_enabled)
- return;
-
- atcommand_iter = db_iterator(atcommand_db);
- alias_iter = db_iterator(atcommand_alias_db);
-
- // Build the matches
- for (command_info = dbi_first(atcommand_iter); dbi_exists(atcommand_iter); command_info = dbi_next(atcommand_iter)) {
- match = strstr(command_info->command, name);
- can_use = pc_can_use_command(sd, command_info->command, type);
- if (prefix_count < MAX_SUGGESTIONS && match == command_info->command && can_use) {
- suggestions[prefix_count] = command_info->command;
- ++prefix_count;
- }
- if (full_count < MAX_SUGGESTIONS && match != NULL && match != command_info->command && can_use) {
- full_match[full_count] = command_info->command;
- ++full_count;
- }
- }
-
- for (alias_info = dbi_first(alias_iter); dbi_exists(alias_iter); alias_info = dbi_next(alias_iter)) {
- match = strstr(alias_info->alias, name);
- can_use = pc_can_use_command(sd, alias_info->command->command, type);
- if (prefix_count < MAX_SUGGESTIONS && match == alias_info->alias && can_use) {
- suggestions[prefix_count] = alias_info->alias;
- ++prefix_count;
- }
- if (full_count < MAX_SUGGESTIONS && match != NULL && match != alias_info->alias && can_use) {
- full_match[full_count] = alias_info->alias;
- ++full_count;
- }
- }
-
- if ((full_count+prefix_count) > 0) {
- char buffer[512];
- int i;
-
- // Merge full match and prefix match results
- if (prefix_count < MAX_SUGGESTIONS) {
- memmove(&suggestions[prefix_count], full_match, sizeof(char *) * (MAX_SUGGESTIONS-prefix_count));
- prefix_count = min(prefix_count+full_count, MAX_SUGGESTIONS);
- }
-
- // Build the suggestion string
- strcpy(buffer, msg_txt(205));
- strcat(buffer,"\n");
-
- for (i=0; i < prefix_count; ++i) {
- strcat(buffer,suggestions[i]);
- strcat(buffer," ");
- }
-
- clif_displaymessage(sd->fd, buffer);
- }
-
- dbi_destroy(atcommand_iter);
- dbi_destroy(alias_iter);
+static void atcommand_get_suggestions(struct map_session_data* sd, const char *name, bool atcommand) {
+ DBIterator* atcommand_iter;
+ DBIterator* alias_iter;
+ AtCommandInfo* command_info = NULL;
+ AliasInfo* alias_info = NULL;
+ AtCommandType type = atcommand ? COMMAND_ATCOMMAND : COMMAND_CHARCOMMAND;
+ char* full_match[MAX_SUGGESTIONS];
+ char* suggestions[MAX_SUGGESTIONS];
+ char* match;
+ int prefix_count = 0, full_count = 0;
+ bool can_use;
+
+ if (!battle_config.atcommand_suggestions_enabled)
+ return;
+
+ atcommand_iter = db_iterator(atcommand_db);
+ alias_iter = db_iterator(atcommand_alias_db);
+
+ // Build the matches
+ for (command_info = dbi_first(atcommand_iter); dbi_exists(atcommand_iter); command_info = dbi_next(atcommand_iter)) {
+ match = strstr(command_info->command, name);
+ can_use = pc_can_use_command(sd, command_info->command, type);
+ if ( prefix_count < MAX_SUGGESTIONS && match == command_info->command && can_use ) {
+ suggestions[prefix_count] = command_info->command;
+ ++prefix_count;
+ }
+ if ( full_count < MAX_SUGGESTIONS && match != NULL && match != command_info->command && can_use ) {
+ full_match[full_count] = command_info->command;
+ ++full_count;
+ }
+ }
+
+ for (alias_info = dbi_first(alias_iter); dbi_exists(alias_iter); alias_info = dbi_next(alias_iter)) {
+ match = strstr(alias_info->alias, name);
+ can_use = pc_can_use_command(sd, alias_info->command->command, type);
+ if ( prefix_count < MAX_SUGGESTIONS && match == alias_info->alias && can_use) {
+ suggestions[prefix_count] = alias_info->alias;
+ ++prefix_count;
+ }
+ if ( full_count < MAX_SUGGESTIONS && match != NULL && match != alias_info->alias && can_use ) {
+ full_match[full_count] = alias_info->alias;
+ ++full_count;
+ }
+ }
+
+ if ((full_count+prefix_count) > 0) {
+ char buffer[512];
+ int i;
+
+ // Merge full match and prefix match results
+ if (prefix_count < MAX_SUGGESTIONS) {
+ memmove(&suggestions[prefix_count], full_match, sizeof(char*) * (MAX_SUGGESTIONS-prefix_count));
+ prefix_count = min(prefix_count+full_count, MAX_SUGGESTIONS);
+ }
+
+ // Build the suggestion string
+ strcpy(buffer, msg_txt(205));
+ strcat(buffer,"\n");
+
+ for(i=0; i < prefix_count; ++i) {
+ strcat(buffer,suggestions[i]);
+ strcat(buffer," ");
+ }
+
+ clif_displaymessage(sd->fd, buffer);
+ }
+
+ dbi_destroy(atcommand_iter);
+ dbi_destroy(alias_iter);
}
/// Executes an at-command.
-bool is_atcommand(const int fd, struct map_session_data *sd, const char *message, int type)
-{
- char charname[NAME_LENGTH], params[100];
- char charname2[NAME_LENGTH], params2[100];
- char command[100];
- char output[CHAT_SIZE_MAX];
-
- //Reconstructed message
- char atcmd_msg[CHAT_SIZE_MAX];
-
- TBL_PC *ssd = NULL; //sd for target
- AtCommandInfo *info;
-
- nullpo_retr(false, sd);
-
- //Shouldn't happen
- if (!message || !*message)
- return false;
-
- //Block NOCHAT but do not display it as a normal message
- if (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCOMMAND)
- return true;
-
- // skip 10/11-langtype's codepage indicator, if detected
- if (message[0] == '|' && strlen(message) >= 4 && (message[3] == atcommand_symbol || message[3] == charcommand_symbol))
- message += 3;
-
- //Should display as a normal message
- if (*message != atcommand_symbol && *message != charcommand_symbol)
- return false;
-
- // type value 0 = server invoked: bypass restrictions
- // 1 = player invoked
- if (type == 1) {
- //Commands are disabled on maps flagged as 'nocommand'
- if (map[sd->bl.m].nocommand && pc_get_group_level(sd) < map[sd->bl.m].nocommand) {
- clif_displaymessage(fd, msg_txt(143));
- return false;
- }
- }
-
- if (*message == charcommand_symbol) {
- do {
- int x, y, z;
-
- //Checks to see if #command has a name or a name + parameters.
- x = sscanf(message, "%99s \"%23[^\"]\" %99[^\n]", command, charname, params);
- y = sscanf(message, "%99s %23s %99[^\n]", command, charname2, params2);
-
- //z always has the value of the scan that was successful
- z = (x > 1) ? x : y;
-
- //#command + name means the sufficient target was used and anything else after
- //can be looked at by the actual command function since most scan to see if the
- //right parameters are used.
- if (x > 2) {
- sprintf(atcmd_msg, "%s %s", command, params);
- break;
- } else if (y > 2) {
- sprintf(atcmd_msg, "%s %s", command, params2);
- break;
- }
- //Regardless of what style the #command is used, if it's correct, it will always have
- //this value if there is no parameter. Send it as just the #command
- else if (z == 2) {
- sprintf(atcmd_msg, "%s", command);
- break;
- }
-
- if (!pc_get_group_level(sd)) {
- if (x >= 1 || y >= 1) { /* we have command */
- info = get_atcommandinfo_byname(atcommand_checkalias(command + 1));
- if (!info || info->char_groups[sd->group_pos] == 0) /* if we can't use or doesn't exist: don't even display the command failed message */
- return false;
- } else
- return false;/* display as normal message */
- }
-
- sprintf(output, msg_txt(1388), charcommand_symbol); // Charcommand failed (usage: %c<command> <char name> <parameters>).
- clif_displaymessage(fd, output);
- return true;
- } while (0);
- } else if (*message == atcommand_symbol) {
- //atcmd_msg is constructed above differently for charcommands
- //it's copied from message if not a charcommand so it can
- //pass through the rest of the code compatible with both symbols
- sprintf(atcmd_msg, "%s", message);
- }
-
- //Clearing these to be used once more.
- memset(command, '\0', sizeof(command));
- memset(params, '\0', sizeof(params));
-
- //check to see if any params exist within this command
- if (sscanf(atcmd_msg, "%99s %99[^\n]", command, params) < 2)
- params[0] = '\0';
-
- // @commands (script based)
- if (type == 1 && atcmd_binding_count > 0) {
- struct atcmd_binding_data *binding;
-
- // Check if the command initiated is a character command
- if (*message == charcommand_symbol &&
- (ssd = map_nick2sd(charname)) == NULL && (ssd = map_nick2sd(charname2)) == NULL) {
- sprintf(output, msg_txt(1389), command); // %s failed. Player not found.
- clif_displaymessage(fd, output);
- return true;
- }
-
- // Get atcommand binding
- binding = get_atcommandbind_byname(command);
-
- // Check if the binding isn't NULL and there is a NPC event, level of usage met, et cetera
- if (binding != NULL && binding->npc_event[0] &&
- ((*atcmd_msg == atcommand_symbol && pc_get_group_level(sd) >= binding->level) ||
- (*atcmd_msg == charcommand_symbol && pc_get_group_level(sd) >= binding->level2))) {
- // Check if self or character invoking; if self == character invoked, then self invoke.
- bool invokeFlag = ((*atcmd_msg == atcommand_symbol) ? 1 : 0);
- npc_do_atcmd_event((invokeFlag ? sd : ssd), command, params, binding->npc_event);
- return true;
- }
- }
-
- //Grab the command information and check for the proper GM level required to use it or if the command exists
- info = get_atcommandinfo_byname(atcommand_checkalias(command + 1));
- if (info == NULL) {
- if (pc_get_group_level(sd)) { // TODO: remove or replace with proper permission
- sprintf(output, msg_txt(153), command); // "%s is Unknown Command."
- clif_displaymessage(fd, output);
- atcommand_get_suggestions(sd, command + 1, *message == atcommand_symbol);
- return true;
- } else
- return false;
- }
-
- // type == 1 : player invoked
- if (type == 1) {
- if ((*command == atcommand_symbol && info->at_groups[sd->group_pos] == 0) ||
- (*command == charcommand_symbol && info->char_groups[sd->group_pos] == 0)) {
- return false;
- }
- if (pc_isdead(sd) && pc_has_permission(sd,PC_PERM_DISABLE_CMD_DEAD)) {
- clif_displaymessage(fd, msg_txt(1393)); // You can't use commands while dead
- return true;
- }
- }
-
- // Check if target is valid only if confirmed that player can use command.
- if (*message == charcommand_symbol &&
- (ssd = map_nick2sd(charname)) == NULL && (ssd = map_nick2sd(charname2)) == NULL) {
- sprintf(output, msg_txt(1389), command); // %s failed. Player not found.
- clif_displaymessage(fd, output);
- return true;
- }
-
- //Attempt to use the command
- if ((info->func(fd, (*atcmd_msg == atcommand_symbol) ? sd : ssd, command, params) != 0)) {
- sprintf(output,msg_txt(154), command); // %s failed.
- clif_displaymessage(fd, output);
- return true;
- }
-
- //Log only if successful.
- if (*atcmd_msg == atcommand_symbol)
- log_atcommand(sd, atcmd_msg);
- else if (*atcmd_msg == charcommand_symbol)
- log_atcommand(sd, message);
-
- return true;
+bool is_atcommand(const int fd, struct map_session_data* sd, const char* message, int type)
+{
+ char charname[NAME_LENGTH], params[100];
+ char charname2[NAME_LENGTH], params2[100];
+ char command[100];
+ char output[CHAT_SIZE_MAX];
+
+ //Reconstructed message
+ char atcmd_msg[CHAT_SIZE_MAX];
+
+ TBL_PC * ssd = NULL; //sd for target
+ AtCommandInfo * info;
+
+ nullpo_retr(false, sd);
+
+ //Shouldn't happen
+ if ( !message || !*message )
+ return false;
+
+ //Block NOCHAT but do not display it as a normal message
+ if ( sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCOMMAND )
+ return true;
+
+ // skip 10/11-langtype's codepage indicator, if detected
+ if ( message[0] == '|' && strlen(message) >= 4 && (message[3] == atcommand_symbol || message[3] == charcommand_symbol) )
+ message += 3;
+
+ //Should display as a normal message
+ if ( *message != atcommand_symbol && *message != charcommand_symbol )
+ return false;
+
+ // type value 0 = server invoked: bypass restrictions
+ // 1 = player invoked
+ if ( type == 1) {
+ //Commands are disabled on maps flagged as 'nocommand'
+ if ( map[sd->bl.m].nocommand && pc_get_group_level(sd) < map[sd->bl.m].nocommand ) {
+ clif_displaymessage(fd, msg_txt(143));
+ return false;
+ }
+ }
+
+ if (*message == charcommand_symbol) {
+ do {
+ int x, y, z;
+
+ //Checks to see if #command has a name or a name + parameters.
+ x = sscanf(message, "%99s \"%23[^\"]\" %99[^\n]", command, charname, params);
+ y = sscanf(message, "%99s %23s %99[^\n]", command, charname2, params2);
+
+ //z always has the value of the scan that was successful
+ z = ( x > 1 ) ? x : y;
+
+ //#command + name means the sufficient target was used and anything else after
+ //can be looked at by the actual command function since most scan to see if the
+ //right parameters are used.
+ if ( x > 2 ) {
+ sprintf(atcmd_msg, "%s %s", command, params);
+ break;
+ }
+ else if ( y > 2 ) {
+ sprintf(atcmd_msg, "%s %s", command, params2);
+ break;
+ }
+ //Regardless of what style the #command is used, if it's correct, it will always have
+ //this value if there is no parameter. Send it as just the #command
+ else if ( z == 2 ) {
+ sprintf(atcmd_msg, "%s", command);
+ break;
+ }
+
+ if( !pc_get_group_level(sd) ) {
+ if( x >= 1 || y >= 1 ) { /* we have command */
+ info = get_atcommandinfo_byname(atcommand_checkalias(command + 1));
+ if( !info || info->char_groups[sd->group_pos] == 0 ) /* if we can't use or doesn't exist: don't even display the command failed message */
+ return false;
+ } else
+ return false;/* display as normal message */
+ }
+
+ sprintf(output, msg_txt(1388), charcommand_symbol); // Charcommand failed (usage: %c<command> <char name> <parameters>).
+ clif_displaymessage(fd, output);
+ return true;
+ } while(0);
+ }
+ else if (*message == atcommand_symbol) {
+ //atcmd_msg is constructed above differently for charcommands
+ //it's copied from message if not a charcommand so it can
+ //pass through the rest of the code compatible with both symbols
+ sprintf(atcmd_msg, "%s", message);
+ }
+
+ //Clearing these to be used once more.
+ memset(command, '\0', sizeof(command));
+ memset(params, '\0', sizeof(params));
+
+ //check to see if any params exist within this command
+ if( sscanf(atcmd_msg, "%99s %99[^\n]", command, params) < 2 )
+ params[0] = '\0';
+
+ // @commands (script based)
+ if(type == 1 && atcmd_binding_count > 0) {
+ struct atcmd_binding_data * binding;
+
+ // Check if the command initiated is a character command
+ if (*message == charcommand_symbol &&
+ (ssd = map_nick2sd(charname)) == NULL && (ssd = map_nick2sd(charname2)) == NULL ) {
+ sprintf(output, msg_txt(1389), command); // %s failed. Player not found.
+ clif_displaymessage(fd, output);
+ return true;
+ }
+
+ // Get atcommand binding
+ binding = get_atcommandbind_byname(command);
+
+ // Check if the binding isn't NULL and there is a NPC event, level of usage met, et cetera
+ if( binding != NULL && binding->npc_event[0] &&
+ ((*atcmd_msg == atcommand_symbol && pc_get_group_level(sd) >= binding->level) ||
+ (*atcmd_msg == charcommand_symbol && pc_get_group_level(sd) >= binding->level2)))
+ {
+ // Check if self or character invoking; if self == character invoked, then self invoke.
+ bool invokeFlag = ((*atcmd_msg == atcommand_symbol) ? 1 : 0);
+ npc_do_atcmd_event((invokeFlag ? sd : ssd), command, params, binding->npc_event);
+ return true;
+ }
+ }
+
+ //Grab the command information and check for the proper GM level required to use it or if the command exists
+ info = get_atcommandinfo_byname(atcommand_checkalias(command + 1));
+ if (info == NULL) {
+ if( pc_get_group_level(sd) ) { // TODO: remove or replace with proper permission
+ sprintf(output, msg_txt(153), command); // "%s is Unknown Command."
+ clif_displaymessage(fd, output);
+ atcommand_get_suggestions(sd, command + 1, *message == atcommand_symbol);
+ return true;
+ } else
+ return false;
+ }
+
+ // type == 1 : player invoked
+ if (type == 1) {
+ if ((*command == atcommand_symbol && info->at_groups[sd->group_pos] == 0) ||
+ (*command == charcommand_symbol && info->char_groups[sd->group_pos] == 0) ) {
+ return false;
+ }
+ if( pc_isdead(sd) && pc_has_permission(sd,PC_PERM_DISABLE_CMD_DEAD) ) {
+ clif_displaymessage(fd, msg_txt(1393)); // You can't use commands while dead
+ return true;
+ }
+ }
+
+ // Check if target is valid only if confirmed that player can use command.
+ if (*message == charcommand_symbol &&
+ (ssd = map_nick2sd(charname)) == NULL && (ssd = map_nick2sd(charname2)) == NULL ) {
+ sprintf(output, msg_txt(1389), command); // %s failed. Player not found.
+ clif_displaymessage(fd, output);
+ return true;
+ }
+
+ //Attempt to use the command
+ if ( (info->func(fd, (*atcmd_msg == atcommand_symbol) ? sd : ssd, command, params) != 0) )
+ {
+ sprintf(output,msg_txt(154), command); // %s failed.
+ clif_displaymessage(fd, output);
+ return true;
+ }
+
+ //Log only if successful.
+ if ( *atcmd_msg == atcommand_symbol )
+ log_atcommand(sd, atcmd_msg);
+ else if ( *atcmd_msg == charcommand_symbol )
+ log_atcommand(sd, message);
+
+ return true;
}
/*==========================================
*
*------------------------------------------*/
-static void atcommand_config_read(const char *config_filename)
-{
- config_setting_t *aliases = NULL, *help = NULL;
- const char *symbol = NULL;
- int num_aliases = 0;
-
- if (conf_read_file(&atcommand_config, config_filename))
- return;
-
- // Command symbols
- if (config_lookup_string(&atcommand_config, "atcommand_symbol", &symbol)) {
- if (ISPRINT(*symbol) && // no control characters
- *symbol != '/' && // symbol of client commands
- *symbol != '%' && // symbol of party chat
- *symbol != '$' && // symbol of guild chat
- *symbol != charcommand_symbol)
- atcommand_symbol = *symbol;
- }
-
- if (config_lookup_string(&atcommand_config, "charcommand_symbol", &symbol)) {
- if (ISPRINT(*symbol) && // no control characters
- *symbol != '/' && // symbol of client commands
- *symbol != '%' && // symbol of party chat
- *symbol != '$' && // symbol of guild chat
- *symbol != atcommand_symbol)
- charcommand_symbol = *symbol;
- }
-
- // Command aliases
- aliases = config_lookup(&atcommand_config, "aliases");
- if (aliases != NULL) {
- int i = 0;
- int count = config_setting_length(aliases);
-
- for (i = 0; i < count; ++i) {
- config_setting_t *command = NULL;
- const char *commandname = NULL;
- int j = 0, alias_count = 0;
- AtCommandInfo *commandinfo = NULL;
-
- command = config_setting_get_elem(aliases, i);
- if (config_setting_type(command) != CONFIG_TYPE_ARRAY)
- continue;
- commandname = config_setting_name(command);
- if (!atcommand_exists(commandname)) {
- ShowConfigWarning(command, "atcommand_config_read: can not set alias for non-existent command %s", commandname);
- continue;
- }
- commandinfo = get_atcommandinfo_byname(commandname);
- alias_count = config_setting_length(command);
- for (j = 0; j < alias_count; ++j) {
- const char *alias = config_setting_get_string_elem(command, j);
- if (alias != NULL) {
- AliasInfo *alias_info;
- if (strdb_exists(atcommand_alias_db, alias)) {
- ShowConfigWarning(command, "atcommand_config_read: alias %s already exists", alias);
- continue;
- }
- CREATE(alias_info, AliasInfo, 1);
- alias_info->command = commandinfo;
- safestrncpy(alias_info->alias, alias, sizeof(alias_info->alias));
- strdb_put(atcommand_alias_db, alias, alias_info);
- ++num_aliases;
- }
- }
- }
- }
-
- // Commands help
- // We only check if all commands exist
- help = config_lookup(&atcommand_config, "help");
- if (help != NULL) {
- int count = config_setting_length(help);
- int i;
-
- for (i = 0; i < count; ++i) {
- config_setting_t *command = NULL;
- const char *commandname = NULL;
-
- command = config_setting_get_elem(help, i);
- commandname = config_setting_name(command);
- if (!atcommand_exists(commandname))
- ShowConfigWarning(command, "atcommand_config_read: command %s does not exist", commandname);
- }
- }
-
- ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' command aliases in '"CL_WHITE"%s"CL_RESET"'.\n", num_aliases, config_filename);
- return;
-}
-void atcommand_db_load_groups(int *group_ids)
-{
- DBIterator *iter = db_iterator(atcommand_db);
- AtCommandInfo *cmd;
- int i;
-
- for (cmd = dbi_first(iter); dbi_exists(iter); cmd = dbi_next(iter)) {
- cmd->at_groups = aMalloc(pc_group_max * sizeof(char));
- cmd->char_groups = aMalloc(pc_group_max * sizeof(char));
- for (i = 0; i < pc_group_max; i++) {
- if (pc_group_can_use_command(group_ids[i], cmd->command, COMMAND_ATCOMMAND))
- cmd->at_groups[i] = 1;
- else
- cmd->at_groups[i] = 0;
- if (pc_group_can_use_command(group_ids[i], cmd->command, COMMAND_CHARCOMMAND))
- cmd->char_groups[i] = 1;
- else
- cmd->char_groups[i] = 0;
- }
- }
-
- dbi_destroy(iter);
-
- return;
-}
-void atcommand_db_clear(void)
-{
-
- if (atcommand_db != NULL) {
- DBIterator *iter = db_iterator(atcommand_db);
- AtCommandInfo *cmd;
-
- for (cmd = dbi_first(iter); dbi_exists(iter); cmd = dbi_next(iter)) {
- aFree(cmd->at_groups);
- aFree(cmd->char_groups);
- }
-
- dbi_destroy(iter);
-
- db_destroy(atcommand_db);
- }
- if (atcommand_alias_db != NULL)
- db_destroy(atcommand_alias_db);
-
- config_destroy(&atcommand_config);
-}
-
-void atcommand_doload(void)
-{
- atcommand_db_clear();
- atcommand_db = stridb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, ATCOMMAND_LENGTH);
- atcommand_alias_db = stridb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, ATCOMMAND_LENGTH);
- atcommand_basecommands(); //fills initial atcommand_db with known commands
- atcommand_config_read(ATCOMMAND_CONF_FILENAME);
-}
-
-void do_init_atcommand(void)
-{
- atcommand_doload();
-}
-
-void do_final_atcommand(void)
-{
- atcommand_db_clear();
+static void atcommand_config_read(const char* config_filename)
+{
+ config_setting_t *aliases = NULL, *help = NULL;
+ const char *symbol = NULL;
+ int num_aliases = 0;
+
+ if (conf_read_file(&atcommand_config, config_filename))
+ return;
+
+ // Command symbols
+ if (config_lookup_string(&atcommand_config, "atcommand_symbol", &symbol)) {
+ if (ISPRINT(*symbol) && // no control characters
+ *symbol != '/' && // symbol of client commands
+ *symbol != '%' && // symbol of party chat
+ *symbol != '$' && // symbol of guild chat
+ *symbol != charcommand_symbol)
+ atcommand_symbol = *symbol;
+ }
+
+ if (config_lookup_string(&atcommand_config, "charcommand_symbol", &symbol)) {
+ if (ISPRINT(*symbol) && // no control characters
+ *symbol != '/' && // symbol of client commands
+ *symbol != '%' && // symbol of party chat
+ *symbol != '$' && // symbol of guild chat
+ *symbol != atcommand_symbol)
+ charcommand_symbol = *symbol;
+ }
+
+ // Command aliases
+ aliases = config_lookup(&atcommand_config, "aliases");
+ if (aliases != NULL) {
+ int i = 0;
+ int count = config_setting_length(aliases);
+
+ for (i = 0; i < count; ++i) {
+ config_setting_t *command = NULL;
+ const char *commandname = NULL;
+ int j = 0, alias_count = 0;
+ AtCommandInfo *commandinfo = NULL;
+
+ command = config_setting_get_elem(aliases, i);
+ if (config_setting_type(command) != CONFIG_TYPE_ARRAY)
+ continue;
+ commandname = config_setting_name(command);
+ if (!atcommand_exists(commandname)) {
+ ShowConfigWarning(command, "atcommand_config_read: can not set alias for non-existent command %s", commandname);
+ continue;
+ }
+ commandinfo = get_atcommandinfo_byname(commandname);
+ alias_count = config_setting_length(command);
+ for (j = 0; j < alias_count; ++j) {
+ const char *alias = config_setting_get_string_elem(command, j);
+ if (alias != NULL) {
+ AliasInfo *alias_info;
+ if (strdb_exists(atcommand_alias_db, alias)) {
+ ShowConfigWarning(command, "atcommand_config_read: alias %s already exists", alias);
+ continue;
+ }
+ CREATE(alias_info, AliasInfo, 1);
+ alias_info->command = commandinfo;
+ safestrncpy(alias_info->alias, alias, sizeof(alias_info->alias));
+ strdb_put(atcommand_alias_db, alias, alias_info);
+ ++num_aliases;
+ }
+ }
+ }
+ }
+
+ // Commands help
+ // We only check if all commands exist
+ help = config_lookup(&atcommand_config, "help");
+ if (help != NULL) {
+ int count = config_setting_length(help);
+ int i;
+
+ for (i = 0; i < count; ++i) {
+ config_setting_t *command = NULL;
+ const char *commandname = NULL;
+
+ command = config_setting_get_elem(help, i);
+ commandname = config_setting_name(command);
+ if (!atcommand_exists(commandname))
+ ShowConfigWarning(command, "atcommand_config_read: command %s does not exist", commandname);
+ }
+ }
+
+ ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' command aliases in '"CL_WHITE"%s"CL_RESET"'.\n", num_aliases, config_filename);
+ return;
+}
+void atcommand_db_load_groups(int* group_ids) {
+ DBIterator *iter = db_iterator(atcommand_db);
+ AtCommandInfo* cmd;
+ int i;
+
+ for (cmd = dbi_first(iter); dbi_exists(iter); cmd = dbi_next(iter)) {
+ cmd->at_groups = aMalloc( pc_group_max * sizeof(char) );
+ cmd->char_groups = aMalloc( pc_group_max * sizeof(char) );
+ for(i = 0; i < pc_group_max; i++) {
+ if( pc_group_can_use_command(group_ids[i], cmd->command, COMMAND_ATCOMMAND ) )
+ cmd->at_groups[i] = 1;
+ else
+ cmd->at_groups[i] = 0;
+ if( pc_group_can_use_command(group_ids[i], cmd->command, COMMAND_CHARCOMMAND ) )
+ cmd->char_groups[i] = 1;
+ else
+ cmd->char_groups[i] = 0;
+ }
+ }
+
+ dbi_destroy(iter);
+
+ return;
+}
+void atcommand_db_clear(void) {
+
+ if (atcommand_db != NULL) {
+ DBIterator *iter = db_iterator(atcommand_db);
+ AtCommandInfo* cmd;
+
+ for (cmd = dbi_first(iter); dbi_exists(iter); cmd = dbi_next(iter)) {
+ aFree(cmd->at_groups);
+ aFree(cmd->char_groups);
+ }
+
+ dbi_destroy(iter);
+
+ db_destroy(atcommand_db);
+ }
+ if (atcommand_alias_db != NULL)
+ db_destroy(atcommand_alias_db);
+
+ config_destroy(&atcommand_config);
+}
+
+void atcommand_doload(void) {
+ atcommand_db_clear();
+ atcommand_db = stridb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, ATCOMMAND_LENGTH);
+ atcommand_alias_db = stridb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, ATCOMMAND_LENGTH);
+ atcommand_basecommands(); //fills initial atcommand_db with known commands
+ atcommand_config_read(ATCOMMAND_CONF_FILENAME);
+}
+
+void do_init_atcommand(void) {
+ atcommand_doload();
+}
+
+void do_final_atcommand(void) {
+ atcommand_db_clear();
}
diff --git a/src/map/atcommand.h b/src/map/atcommand.h
index b3c7e4867..8affa4c26 100644
--- a/src/map/atcommand.h
+++ b/src/map/atcommand.h
@@ -16,36 +16,36 @@ extern char atcommand_symbol;
extern char charcommand_symbol;
typedef enum {
- COMMAND_ATCOMMAND = 1,
- COMMAND_CHARCOMMAND = 2,
+ COMMAND_ATCOMMAND = 1,
+ COMMAND_CHARCOMMAND = 2,
} AtCommandType;
-typedef int (*AtCommandFunc)(const int fd, struct map_session_data *sd, const char *command, const char *message);
+typedef int (*AtCommandFunc)(const int fd, struct map_session_data* sd, const char* command, const char* message);
-bool is_atcommand(const int fd, struct map_session_data *sd, const char *message, int type);
+bool is_atcommand(const int fd, struct map_session_data* sd, const char* message, int type);
void do_init_atcommand(void);
void do_final_atcommand(void);
-void atcommand_db_load_groups(int *group_ids);
+void atcommand_db_load_groups(int* group_ids);
-bool atcommand_exists(const char *name);
+bool atcommand_exists(const char* name);
-const char *msg_txt(int msg_number);
-int msg_config_read(const char *cfgName);
+const char* msg_txt(int msg_number);
+int msg_config_read(const char* cfgName);
void do_final_msg(void);
extern int atcmd_binding_count;
// @commands (script based)
struct atcmd_binding_data {
- char command[50];
- char npc_event[50];
- int level;
- int level2;
+ char command[50];
+ char npc_event[50];
+ int level;
+ int level2;
};
-struct atcmd_binding_data **atcmd_binding;
+struct atcmd_binding_data** atcmd_binding;
-struct atcmd_binding_data *get_atcommandbind_byname(const char *name);
+struct atcmd_binding_data* get_atcommandbind_byname(const char* name);
#endif /* _ATCOMMAND_H_ */
diff --git a/src/map/battle.c b/src/map/battle.c
index 3bbdcc210..36d8051ef 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -40,274 +40,263 @@ int attr_fix_table[4][ELE_MAX][ELE_MAX];
struct Battle_Config battle_config;
static struct eri *delay_damage_ers; //For battle delay damage structures.
-int battle_getcurrentskill(struct block_list *bl) //Returns the current/last skill in use by this bl.
-{
- struct unit_data *ud;
+int battle_getcurrentskill(struct block_list *bl) { //Returns the current/last skill in use by this bl.
+ struct unit_data *ud;
- if (bl->type == BL_SKILL) {
- struct skill_unit *su = (struct skill_unit *)bl;
- return su->group?su->group->skill_id:0;
- }
+ if( bl->type == BL_SKILL ) {
+ struct skill_unit * su = (struct skill_unit*)bl;
+ return su->group?su->group->skill_id:0;
+ }
- ud = unit_bl2ud(bl);
+ ud = unit_bl2ud(bl);
- return ud?ud->skillid:0;
+ return ud?ud->skillid:0;
}
/*==========================================
* Get random targetting enemy
*------------------------------------------*/
-static int battle_gettargeted_sub(struct block_list *bl, va_list ap)
-{
- struct block_list **bl_list;
- struct unit_data *ud;
- int target_id;
- int *c;
+static int battle_gettargeted_sub(struct block_list *bl, va_list ap) {
+ struct block_list **bl_list;
+ struct unit_data *ud;
+ int target_id;
+ int *c;
- bl_list = va_arg(ap, struct block_list **);
- c = va_arg(ap, int *);
- target_id = va_arg(ap, int);
+ bl_list = va_arg(ap, struct block_list **);
+ c = va_arg(ap, int *);
+ target_id = va_arg(ap, int);
- if (bl->id == target_id)
- return 0;
+ if (bl->id == target_id)
+ return 0;
- if (*c >= 24)
- return 0;
+ if (*c >= 24)
+ return 0;
- if (!(ud = unit_bl2ud(bl)))
- return 0;
+ if ( !(ud = unit_bl2ud(bl)) )
+ return 0;
- if (ud->target == target_id || ud->skilltarget == target_id) {
- bl_list[(*c)++] = bl;
- return 1;
- }
+ if (ud->target == target_id || ud->skilltarget == target_id) {
+ bl_list[(*c)++] = bl;
+ return 1;
+ }
- return 0;
+ return 0;
}
-struct block_list *battle_gettargeted(struct block_list *target) {
- struct block_list *bl_list[24];
- int c = 0;
- nullpo_retr(NULL, target);
-
- memset(bl_list, 0, sizeof(bl_list));
- map_foreachinrange(battle_gettargeted_sub, target, AREA_SIZE, BL_CHAR, bl_list, &c, target->id);
- if (c == 0)
- return NULL;
- if (c > 24)
- c = 24;
- return bl_list[rnd()%c];
+struct block_list* battle_gettargeted(struct block_list *target) {
+ struct block_list *bl_list[24];
+ int c = 0;
+ nullpo_retr(NULL, target);
+
+ memset(bl_list, 0, sizeof(bl_list));
+ map_foreachinrange(battle_gettargeted_sub, target, AREA_SIZE, BL_CHAR, bl_list, &c, target->id);
+ if ( c == 0 )
+ return NULL;
+ if( c > 24 )
+ c = 24;
+ return bl_list[rnd()%c];
}
//Returns the id of the current targetted character of the passed bl. [Skotlex]
-int battle_gettarget(struct block_list *bl)
-{
-
- switch (bl->type) {
- case BL_PC:
- return ((struct map_session_data *)bl)->ud.target;
- case BL_MOB:
- return ((struct mob_data *)bl)->target_id;
- case BL_PET:
- return ((struct pet_data *)bl)->target_id;
- case BL_HOM:
- return ((struct homun_data *)bl)->ud.target;
- case BL_MER:
- return ((struct mercenary_data *)bl)->ud.target;
- case BL_ELEM:
- return ((struct elemental_data *)bl)->ud.target;
- }
+int battle_gettarget(struct block_list* bl) {
+
+ switch (bl->type) {
+ case BL_PC: return ((struct map_session_data*)bl)->ud.target;
+ case BL_MOB: return ((struct mob_data*)bl)->target_id;
+ case BL_PET: return ((struct pet_data*)bl)->target_id;
+ case BL_HOM: return ((struct homun_data*)bl)->ud.target;
+ case BL_MER: return ((struct mercenary_data*)bl)->ud.target;
+ case BL_ELEM: return ((struct elemental_data*)bl)->ud.target;
+ }
- return 0;
+ return 0;
}
-static int battle_getenemy_sub(struct block_list *bl, va_list ap)
-{
- struct block_list **bl_list;
- struct block_list *target;
- int *c;
+static int battle_getenemy_sub(struct block_list *bl, va_list ap) {
+ struct block_list **bl_list;
+ struct block_list *target;
+ int *c;
- bl_list = va_arg(ap, struct block_list **);
- c = va_arg(ap, int *);
- target = va_arg(ap, struct block_list *);
+ bl_list = va_arg(ap, struct block_list **);
+ c = va_arg(ap, int *);
+ target = va_arg(ap, struct block_list *);
- if (bl->id == target->id)
- return 0;
+ if (bl->id == target->id)
+ return 0;
- if (*c >= 24)
- return 0;
+ if (*c >= 24)
+ return 0;
- if (status_isdead(bl))
- return 0;
+ if (status_isdead(bl))
+ return 0;
- if (battle_check_target(target, bl, BCT_ENEMY) > 0) {
- bl_list[(*c)++] = bl;
- return 1;
- }
+ if (battle_check_target(target, bl, BCT_ENEMY) > 0) {
+ bl_list[(*c)++] = bl;
+ return 1;
+ }
- return 0;
+ return 0;
}
// Picks a random enemy of the given type (BL_PC, BL_CHAR, etc) within the range given. [Skotlex]
-struct block_list *battle_getenemy(struct block_list *target, int type, int range) {
- struct block_list *bl_list[24];
- int c = 0;
+struct block_list* battle_getenemy(struct block_list *target, int type, int range) {
+ struct block_list *bl_list[24];
+ int c = 0;
- memset(bl_list, 0, sizeof(bl_list));
- map_foreachinrange(battle_getenemy_sub, target, range, type, bl_list, &c, target);
+ memset(bl_list, 0, sizeof(bl_list));
+ map_foreachinrange(battle_getenemy_sub, target, range, type, bl_list, &c, target);
- if (c == 0)
- return NULL;
+ if ( c == 0 )
+ return NULL;
- if (c > 24)
- c = 24;
+ if( c > 24 )
+ c = 24;
- return bl_list[rnd()%c];
+ return bl_list[rnd()%c];
}
-static int battle_getenemyarea_sub(struct block_list *bl, va_list ap)
-{
- struct block_list **bl_list, *src;
- int *c, ignore_id;
+static int battle_getenemyarea_sub(struct block_list *bl, va_list ap) {
+ struct block_list **bl_list, *src;
+ int *c, ignore_id;
- bl_list = va_arg(ap, struct block_list **);
- c = va_arg(ap, int *);
- src = va_arg(ap, struct block_list *);
- ignore_id = va_arg(ap, int);
+ bl_list = va_arg(ap, struct block_list **);
+ c = va_arg(ap, int *);
+ src = va_arg(ap, struct block_list *);
+ ignore_id = va_arg(ap, int);
- if (bl->id == src->id || bl->id == ignore_id)
- return 0; // Ignores Caster and a possible pre-target
+ if( bl->id == src->id || bl->id == ignore_id )
+ return 0; // Ignores Caster and a possible pre-target
- if (*c >= 23)
- return 0;
+ if( *c >= 23 )
+ return 0;
- if (status_isdead(bl))
- return 0;
+ if( status_isdead(bl) )
+ return 0;
- if (battle_check_target(src, bl, BCT_ENEMY) > 0) { // Is Enemy!...
- bl_list[(*c)++] = bl;
- return 1;
- }
+ if( battle_check_target(src, bl, BCT_ENEMY) > 0 ) {// Is Enemy!...
+ bl_list[(*c)++] = bl;
+ return 1;
+ }
- return 0;
+ return 0;
}
// Pick a random enemy
-struct block_list *battle_getenemyarea(struct block_list *src, int x, int y, int range, int type, int ignore_id) {
- struct block_list *bl_list[24];
- int c = 0;
+struct block_list* battle_getenemyarea(struct block_list *src, int x, int y, int range, int type, int ignore_id) {
+ struct block_list *bl_list[24];
+ int c = 0;
- memset(bl_list, 0, sizeof(bl_list));
- map_foreachinarea(battle_getenemyarea_sub, src->m, x - range, y - range, x + range, y + range, type, bl_list, &c, src, ignore_id);
+ memset(bl_list, 0, sizeof(bl_list));
+ map_foreachinarea(battle_getenemyarea_sub, src->m, x - range, y - range, x + range, y + range, type, bl_list, &c, src, ignore_id);
- if (c == 0)
- return NULL;
- if (c >= 24)
- c = 23;
+ if( c == 0 )
+ return NULL;
+ if( c >= 24 )
+ c = 23;
- return bl_list[rnd()%c];
+ return bl_list[rnd()%c];
}
// Dammage delayed info
struct delay_damage {
- int src_id;
- int target_id;
- int damage;
- int delay;
- unsigned short distance;
- unsigned short skill_lv;
- unsigned short skill_id;
- enum damage_lv dmg_lv;
- unsigned short attack_type;
+ int src_id;
+ int target_id;
+ int damage;
+ int delay;
+ unsigned short distance;
+ unsigned short skill_lv;
+ unsigned short skill_id;
+ enum damage_lv dmg_lv;
+ unsigned short attack_type;
};
-int battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr_t data)
-{
- struct delay_damage *dat = (struct delay_damage *)data;
+int battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr_t data) {
+ struct delay_damage *dat = (struct delay_damage *)data;
- if (dat) {
- struct block_list *src;
- struct block_list *target = map_id2bl(dat->target_id);
+ if ( dat ) {
+ struct block_list* src;
+ struct block_list* target = map_id2bl(dat->target_id);
- if (!target || status_isdead(target)) { /* nothing we can do */
- ers_free(delay_damage_ers, dat);
- return 0;
- }
+ if( !target || status_isdead(target) ) {/* nothing we can do */
+ ers_free(delay_damage_ers, dat);
+ return 0;
+ }
- src = map_id2bl(dat->src_id);
-
- if (src && target->m == src->m &&
- (target->type != BL_PC || ((TBL_PC *)target)->invincible_timer == INVALID_TIMER) &&
- check_distance_bl(src, target, dat->distance)) { //Check to see if you haven't teleported. [Skotlex]
- map_freeblock_lock();
- status_fix_damage(src, target, dat->damage, dat->delay);
- if (dat->attack_type && !status_isdead(target))
- skill_additional_effect(src,target,dat->skill_id,dat->skill_lv,dat->attack_type,dat->dmg_lv,tick);
- if (dat->dmg_lv > ATK_BLOCK && dat->attack_type)
- skill_counter_additional_effect(src,target,dat->skill_id,dat->skill_lv,dat->attack_type,tick);
- map_freeblock_unlock();
- } else if (!src && dat->skill_id == CR_REFLECTSHIELD) {
- /**
- * it was monster reflected damage, and the monster died, we pass the damage to the character as expected
- **/
- map_freeblock_lock();
- status_fix_damage(target, target, dat->damage, dat->delay);
- map_freeblock_unlock();
- }
- }
- ers_free(delay_damage_ers, dat);
- return 0;
+ src = map_id2bl(dat->src_id);
+
+ if( src && target->m == src->m &&
+ (target->type != BL_PC || ((TBL_PC*)target)->invincible_timer == INVALID_TIMER) &&
+ check_distance_bl(src, target, dat->distance) ) //Check to see if you haven't teleported. [Skotlex]
+ {
+ map_freeblock_lock();
+ status_fix_damage(src, target, dat->damage, dat->delay);
+ if( dat->attack_type && !status_isdead(target) )
+ skill_additional_effect(src,target,dat->skill_id,dat->skill_lv,dat->attack_type,dat->dmg_lv,tick);
+ if( dat->dmg_lv > ATK_BLOCK && dat->attack_type )
+ skill_counter_additional_effect(src,target,dat->skill_id,dat->skill_lv,dat->attack_type,tick);
+ map_freeblock_unlock();
+ } else if( !src && dat->skill_id == CR_REFLECTSHIELD ) {
+ /**
+ * it was monster reflected damage, and the monster died, we pass the damage to the character as expected
+ **/
+ map_freeblock_lock();
+ status_fix_damage(target, target, dat->damage, dat->delay);
+ map_freeblock_unlock();
+ }
+ }
+ ers_free(delay_damage_ers, dat);
+ return 0;
}
-int battle_delay_damage(unsigned int tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, int skill_id, int skill_lv, int damage, enum damage_lv dmg_lv, int ddelay)
+int battle_delay_damage (unsigned int tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, int skill_id, int skill_lv, int damage, enum damage_lv dmg_lv, int ddelay)
{
- struct delay_damage *dat;
- struct status_change *sc;
- nullpo_ret(src);
- nullpo_ret(target);
-
- sc = status_get_sc(target);
-
- if (sc && sc->data[SC_DEVOTION] && damage > 0 && skill_id != PA_PRESSURE && skill_id != CR_REFLECTSHIELD)
- damage = 0;
-
- if (!battle_config.delay_battle_damage || amotion <= 1) {
- map_freeblock_lock();
- status_fix_damage(src, target, damage, ddelay); // We have to seperate here between reflect damage and others [icescope]
- if (attack_type && !status_isdead(target))
- skill_additional_effect(src, target, skill_id, skill_lv, attack_type, dmg_lv, gettick());
- if (dmg_lv > ATK_BLOCK && attack_type)
- skill_counter_additional_effect(src, target, skill_id, skill_lv, attack_type, gettick());
- map_freeblock_unlock();
- return 0;
- }
- dat = ers_alloc(delay_damage_ers, struct delay_damage);
- dat->src_id = src->id;
- dat->target_id = target->id;
- dat->skill_id = skill_id;
- dat->skill_lv = skill_lv;
- dat->attack_type = attack_type;
- dat->damage = damage;
- dat->dmg_lv = dmg_lv;
- dat->delay = ddelay;
- dat->distance = distance_bl(src, target)+10; //Attack should connect regardless unless you teleported.
- if (src->type != BL_PC && amotion > 1000)
- amotion = 1000; //Aegis places a damage-delay cap of 1 sec to non player attacks. [Skotlex]
-
- add_timer(tick+amotion, battle_delay_damage_sub, 0, (intptr_t)dat);
-
- return 0;
+ struct delay_damage *dat;
+ struct status_change *sc;
+ nullpo_ret(src);
+ nullpo_ret(target);
+
+ sc = status_get_sc(target);
+
+ if( sc && sc->data[SC_DEVOTION] && damage > 0 && skill_id != PA_PRESSURE && skill_id != CR_REFLECTSHIELD )
+ damage = 0;
+
+ if ( !battle_config.delay_battle_damage || amotion <= 1 ) {
+ map_freeblock_lock();
+ status_fix_damage(src, target, damage, ddelay); // We have to seperate here between reflect damage and others [icescope]
+ if( attack_type && !status_isdead(target) )
+ skill_additional_effect(src, target, skill_id, skill_lv, attack_type, dmg_lv, gettick());
+ if( dmg_lv > ATK_BLOCK && attack_type )
+ skill_counter_additional_effect(src, target, skill_id, skill_lv, attack_type, gettick());
+ map_freeblock_unlock();
+ return 0;
+ }
+ dat = ers_alloc(delay_damage_ers, struct delay_damage);
+ dat->src_id = src->id;
+ dat->target_id = target->id;
+ dat->skill_id = skill_id;
+ dat->skill_lv = skill_lv;
+ dat->attack_type = attack_type;
+ dat->damage = damage;
+ dat->dmg_lv = dmg_lv;
+ dat->delay = ddelay;
+ dat->distance = distance_bl(src, target)+10; //Attack should connect regardless unless you teleported.
+ if (src->type != BL_PC && amotion > 1000)
+ amotion = 1000; //Aegis places a damage-delay cap of 1 sec to non player attacks. [Skotlex]
+
+ add_timer(tick+amotion, battle_delay_damage_sub, 0, (intptr_t)dat);
+
+ return 0;
}
int battle_attr_ratio(int atk_elem,int def_type, int def_lv)
{
- if (atk_elem < 0 || atk_elem >= ELE_MAX)
- return 100;
+ if (atk_elem < 0 || atk_elem >= ELE_MAX)
+ return 100;
- if (def_type < 0 || def_type > ELE_MAX || def_lv < 1 || def_lv > 4)
- return 100;
+ if (def_type < 0 || def_type > ELE_MAX || def_lv < 1 || def_lv > 4)
+ return 100;
- return attr_fix_table[def_lv-1][atk_elem][def_type];
+ return attr_fix_table[def_lv-1][atk_elem][def_type];
}
/*==========================================
@@ -317,416 +306,106 @@ int battle_attr_ratio(int atk_elem,int def_type, int def_lv)
*------------------------------------------*/
int battle_attr_fix(struct block_list *src, struct block_list *target, int damage,int atk_elem,int def_type, int def_lv)
{
- struct status_change *sc=NULL, *tsc=NULL;
- int ratio;
-
- if (src) sc = status_get_sc(src);
- if (target) tsc = status_get_sc(target);
-
- if (atk_elem < 0 || atk_elem >= ELE_MAX)
- atk_elem = rnd()%ELE_MAX;
+ struct status_change *sc=NULL, *tsc=NULL;
+ int ratio;
- if (def_type < 0 || def_type > ELE_MAX ||
- def_lv < 1 || def_lv > 4) {
- ShowError("battle_attr_fix: unknown attr type: atk=%d def_type=%d def_lv=%d\n",atk_elem,def_type,def_lv);
- return damage;
- }
-
- ratio = attr_fix_table[def_lv-1][atk_elem][def_type];
- if (sc && sc->count) {
- if (sc->data[SC_VOLCANO] && atk_elem == ELE_FIRE)
- ratio += enchant_eff[sc->data[SC_VOLCANO]->val1-1];
- if (sc->data[SC_VIOLENTGALE] && atk_elem == ELE_WIND)
- ratio += enchant_eff[sc->data[SC_VIOLENTGALE]->val1-1];
- if (sc->data[SC_DELUGE] && atk_elem == ELE_WATER)
- ratio += enchant_eff[sc->data[SC_DELUGE]->val1-1];
- }
- if (target && target->type == BL_SKILL) {
- if (atk_elem == ELE_FIRE && battle_getcurrentskill(target) == GN_WALLOFTHORN) {
- struct skill_unit *su = (struct skill_unit *)target;
- struct skill_unit_group *sg;
- struct block_list *src;
- int x,y;
-
- if (!su || !su->alive || (sg = su->group) == NULL || !sg || sg->val3 == -1 ||
- (src = map_id2bl(sg->src_id)) == NULL || status_isdead(src))
- return 0;
-
- if (sg->unit_id != UNT_FIREWALL) {
- x = sg->val3 >> 16;
- y = sg->val3 & 0xffff;
- skill_unitsetting(src,su->group->skill_id,su->group->skill_lv,x,y,1);
- sg->val3 = -1;
- sg->limit = DIFF_TICK(gettick(),sg->tick)+300;
- }
- }
- }
- if (tsc && tsc->count) { //since an atk can only have one type let's optimise this a bit
- switch (atk_elem) {
- case ELE_FIRE:
- if (tsc->data[SC_SPIDERWEB]) {
- tsc->data[SC_SPIDERWEB]->val1 = 0; // free to move now
- if (tsc->data[SC_SPIDERWEB]->val2-- > 0)
- damage <<= 1; // double damage
- if (tsc->data[SC_SPIDERWEB]->val2 == 0)
- status_change_end(target, SC_SPIDERWEB, INVALID_TIMER);
- }
- if (tsc->data[SC_THORNSTRAP])
- status_change_end(target, SC_THORNSTRAP, INVALID_TIMER);
- if (tsc->data[SC_FIRE_CLOAK_OPTION])
- damage -= damage * tsc->data[SC_FIRE_CLOAK_OPTION]->val2 / 100;
- if (tsc->data[SC_CRYSTALIZE] && target->type != BL_MOB)
- status_change_end(target, SC_CRYSTALIZE, INVALID_TIMER);
- if (tsc->data[SC_EARTH_INSIGNIA]) damage += damage/2;
- if (tsc->data[SC_ASH]) damage += damage/2; //150%
- break;
- case ELE_HOLY:
- if (tsc->data[SC_ORATIO]) ratio += tsc->data[SC_ORATIO]->val1 * 2;
- break;
- case ELE_POISON:
- if (tsc->data[SC_VENOMIMPRESS]) ratio += tsc->data[SC_VENOMIMPRESS]->val2;
- break;
- case ELE_WIND:
- if (tsc->data[SC_CRYSTALIZE] && target->type != BL_MOB) damage += damage/2;
- if (tsc->data[SC_WATER_INSIGNIA]) damage += damage/2;
- break;
- case ELE_WATER:
- if (tsc->data[SC_FIRE_INSIGNIA]) damage += damage/2;
- break;
- case ELE_EARTH:
- if (tsc->data[SC_WIND_INSIGNIA]) damage += damage/2;
- break;
- }
- } //end tsc check
- if (src && src->type == BL_PC) {
- struct map_session_data *sd = BL_CAST(BL_PC, src);
- int s;
+ if (src) sc = status_get_sc(src);
+ if (target) tsc = status_get_sc(target);
- ARR_FIND(1, 6, s, sd->talisman[s] > 0);
+ if (atk_elem < 0 || atk_elem >= ELE_MAX)
+ atk_elem = rnd()%ELE_MAX;
- if (s < 5 && atk_elem == s)
- ratio += sd->talisman[s] * 2; // +2% custom value
- }
- if (target && target->type == BL_PC) {
- struct map_session_data *tsd = BL_CAST(BL_PC, target);
- int t;
-
- ARR_FIND(1, 6, t, tsd->talisman[t] > 0);
-
- if (t < 5 && atk_elem == t)
- damage -= damage * tsd->talisman[t] * 3 / 100; // -3% custom value
- }
- return damage*ratio/100;
-}
-/*==========================================
- * Calculates card bonuses damage adjustments.
- *------------------------------------------*/
-int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_list *target, int nk, int s_ele, int s_ele_, int damage, int left, int flag){
- struct map_session_data *sd, *tsd;
- short cardfix = 1000, t_class, s_class, s_race2, t_race2;
- struct status_data *sstatus, *tstatus;
- int i;
-
- sd = BL_CAST(BL_PC, src);
- tsd = BL_CAST(BL_PC, target);
- t_class = status_get_class(target);
- s_class = status_get_class(src);
- sstatus = status_get_status_data(src);
- tstatus = status_get_status_data(target);
- s_race2 = status_get_race2(src);
- t_race2 = status_get_race2(target);
-
- if( !damage )
- return 0;
-
- switch(attack_type){
- case BF_MAGIC:
- if ( sd && !(nk&NK_NO_CARDFIX_ATK) ) {
- cardfix=cardfix*(100+sd->magic_addrace[tstatus->race])/100;
- if (!(nk&NK_NO_ELEFIX))
- cardfix=cardfix*(100+sd->magic_addele[tstatus->def_ele])/100;
- cardfix=cardfix*(100+sd->magic_addsize[tstatus->size])/100;
- cardfix=cardfix*(100+sd->magic_addrace[is_boss(target)?RC_BOSS:RC_NONBOSS])/100;
- for(i=0; i< ARRAYLENGTH(sd->add_mdmg) && sd->add_mdmg[i].rate;i++) {
- if(sd->add_mdmg[i].class_ == t_class) {
- cardfix=cardfix*(100+sd->add_mdmg[i].rate)/100;
- continue;
- }
- }
- if (cardfix != 1000)
- damage = damage * cardfix / 1000;
- }
-
- if( tsd && !(nk&NK_NO_CARDFIX_DEF) )
- { // Target cards.
- if (!(nk&NK_NO_ELEFIX))
- {
- int ele_fix = tsd->subele[s_ele];
- for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++)
- {
- if(tsd->subele2[i].ele != s_ele) continue;
- if(!(tsd->subele2[i].flag&flag&BF_WEAPONMASK &&
- tsd->subele2[i].flag&flag&BF_RANGEMASK &&
- tsd->subele2[i].flag&flag&BF_SKILLMASK))
- continue;
- ele_fix += tsd->subele2[i].rate;
- }
- cardfix=cardfix*(100-ele_fix)/100;
- }
- cardfix=cardfix*(100-tsd->subsize[sstatus->size])/100;
- cardfix=cardfix*(100-tsd->subrace2[s_race2])/100;
- cardfix=cardfix*(100-tsd->subrace[sstatus->race])/100;
- cardfix=cardfix*(100-tsd->subrace[is_boss(src)?RC_BOSS:RC_NONBOSS])/100;
- if( sstatus->race != RC_DEMIHUMAN )
- cardfix=cardfix*(100-tsd->subrace[RC_NONDEMIHUMAN])/100;
-
- for(i=0; i < ARRAYLENGTH(tsd->add_mdef) && tsd->add_mdef[i].rate;i++) {
- if(tsd->add_mdef[i].class_ == s_class) {
- cardfix=cardfix*(100-tsd->add_mdef[i].rate)/100;
- break;
- }
- }
- //It was discovered that ranged defense also counts vs magic! [Skotlex]
- if ( flag&BF_SHORT )
- cardfix = cardfix * ( 100 - tsd->bonus.near_attack_def_rate ) / 100;
- else
- cardfix = cardfix * ( 100 - tsd->bonus.long_attack_def_rate ) / 100;
-
- cardfix = cardfix * ( 100 - tsd->bonus.magic_def_rate ) / 100;
-
- if( tsd->sc.data[SC_MDEF_RATE] )
- cardfix = cardfix * ( 100 - tsd->sc.data[SC_MDEF_RATE]->val1 ) / 100;
-
- if (cardfix != 1000)
- damage = damage * cardfix / 1000;
- }
- break;
- case BF_WEAPON:
- if( sd && !(nk&NK_NO_CARDFIX_ATK) && (left&2) )
- {
- short cardfix_ = 1000;
- if(sd->state.arrow_atk)
- {
- cardfix=cardfix*(100+sd->right_weapon.addrace[tstatus->race]+sd->arrow_addrace[tstatus->race])/100;
- if (!(nk&NK_NO_ELEFIX))
- {
- int ele_fix = sd->right_weapon.addele[tstatus->def_ele] + sd->arrow_addele[tstatus->def_ele];
- for (i = 0; ARRAYLENGTH(sd->right_weapon.addele2) > i && sd->right_weapon.addele2[i].rate != 0; i++) {
- if (sd->right_weapon.addele2[i].ele != tstatus->def_ele) continue;
- if(!(sd->right_weapon.addele2[i].flag&flag&BF_WEAPONMASK &&
- sd->right_weapon.addele2[i].flag&flag&BF_RANGEMASK &&
- sd->right_weapon.addele2[i].flag&flag&BF_SKILLMASK))
- continue;
- ele_fix += sd->right_weapon.addele2[i].rate;
- }
- cardfix=cardfix*(100+ele_fix)/100;
- }
- cardfix=cardfix*(100+sd->right_weapon.addsize[tstatus->size]+sd->arrow_addsize[tstatus->size])/100;
- cardfix=cardfix*(100+sd->right_weapon.addrace2[t_race2])/100;
- cardfix=cardfix*(100+sd->right_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS]+sd->arrow_addrace[is_boss(target)?RC_BOSS:RC_NONBOSS])/100;
- if( tstatus->race != RC_DEMIHUMAN )
- cardfix=cardfix*(100+sd->right_weapon.addrace[RC_NONDEMIHUMAN]+sd->arrow_addrace[RC_NONDEMIHUMAN])/100;
- }
- else
- { // Melee attack
- if( !battle_config.left_cardfix_to_right )
- {
- cardfix=cardfix*(100+sd->right_weapon.addrace[tstatus->race])/100;
- if (!(nk&NK_NO_ELEFIX)) {
- int ele_fix = sd->right_weapon.addele[tstatus->def_ele];
- for (i = 0; ARRAYLENGTH(sd->right_weapon.addele2) > i && sd->right_weapon.addele2[i].rate != 0; i++) {
- if (sd->right_weapon.addele2[i].ele != tstatus->def_ele) continue;
- if(!(sd->right_weapon.addele2[i].flag&flag&BF_WEAPONMASK &&
- sd->right_weapon.addele2[i].flag&flag&BF_RANGEMASK &&
- sd->right_weapon.addele2[i].flag&flag&BF_SKILLMASK))
- continue;
- ele_fix += sd->right_weapon.addele2[i].rate;
- }
- cardfix=cardfix*(100+ele_fix)/100;
- }
- cardfix=cardfix*(100+sd->right_weapon.addsize[tstatus->size])/100;
- cardfix=cardfix*(100+sd->right_weapon.addrace2[t_race2])/100;
- cardfix=cardfix*(100+sd->right_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS])/100;
- if( tstatus->race != RC_DEMIHUMAN )
- cardfix=cardfix*(100+sd->right_weapon.addrace[RC_NONDEMIHUMAN])/100;
-
- if( left&1 )
- {
- cardfix_=cardfix_*(100+sd->left_weapon.addrace[tstatus->race])/100;
- if (!(nk&NK_NO_ELEFIX)) {
- int ele_fix_lh = sd->left_weapon.addele[tstatus->def_ele];
- for (i = 0; ARRAYLENGTH(sd->left_weapon.addele2) > i && sd->left_weapon.addele2[i].rate != 0; i++) {
- if (sd->left_weapon.addele2[i].ele != tstatus->def_ele) continue;
- if(!(sd->left_weapon.addele2[i].flag&flag&BF_WEAPONMASK &&
- sd->left_weapon.addele2[i].flag&flag&BF_RANGEMASK &&
- sd->left_weapon.addele2[i].flag&flag&BF_SKILLMASK))
- continue;
- ele_fix_lh += sd->left_weapon.addele2[i].rate;
- }
- cardfix=cardfix*(100+ele_fix_lh)/100;
- }
- cardfix_=cardfix_*(100+sd->left_weapon.addsize[tstatus->size])/100;
- cardfix_=cardfix_*(100+sd->left_weapon.addrace2[t_race2])/100;
- cardfix_=cardfix_*(100+sd->left_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS])/100;
- if( tstatus->race != RC_DEMIHUMAN )
- cardfix_=cardfix_*(100+sd->left_weapon.addrace[RC_NONDEMIHUMAN])/100;
- }
- }
- else
- {
- int ele_fix = sd->right_weapon.addele[tstatus->def_ele] + sd->left_weapon.addele[tstatus->def_ele];
- for (i = 0; ARRAYLENGTH(sd->right_weapon.addele2) > i && sd->right_weapon.addele2[i].rate != 0; i++) {
- if (sd->right_weapon.addele2[i].ele != tstatus->def_ele) continue;
- if(!(sd->right_weapon.addele2[i].flag&flag&BF_WEAPONMASK &&
- sd->right_weapon.addele2[i].flag&flag&BF_RANGEMASK &&
- sd->right_weapon.addele2[i].flag&flag&BF_SKILLMASK))
- continue;
- ele_fix += sd->right_weapon.addele2[i].rate;
- }
- for (i = 0; ARRAYLENGTH(sd->left_weapon.addele2) > i && sd->left_weapon.addele2[i].rate != 0; i++) {
- if (sd->left_weapon.addele2[i].ele != tstatus->def_ele) continue;
- if(!(sd->left_weapon.addele2[i].flag&flag&BF_WEAPONMASK &&
- sd->left_weapon.addele2[i].flag&flag&BF_RANGEMASK &&
- sd->left_weapon.addele2[i].flag&flag&BF_SKILLMASK))
- continue;
- ele_fix += sd->left_weapon.addele2[i].rate;
- }
-
- cardfix=cardfix*(100+sd->right_weapon.addrace[tstatus->race]+sd->left_weapon.addrace[tstatus->race])/100;
- cardfix=cardfix*(100+ele_fix)/100;
- cardfix=cardfix*(100+sd->right_weapon.addsize[tstatus->size]+sd->left_weapon.addsize[tstatus->size])/100;
- cardfix=cardfix*(100+sd->right_weapon.addrace2[t_race2]+sd->left_weapon.addrace2[t_race2])/100;
- cardfix=cardfix*(100+sd->right_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS]+sd->left_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS])/100;
- if( tstatus->race != RC_DEMIHUMAN )
- cardfix=cardfix*(100+sd->right_weapon.addrace[RC_NONDEMIHUMAN]+sd->left_weapon.addrace[RC_NONDEMIHUMAN])/100;
- }
- }
- for( i = 0; i < ARRAYLENGTH(sd->right_weapon.add_dmg) && sd->right_weapon.add_dmg[i].rate; i++ )
- {
- if( sd->right_weapon.add_dmg[i].class_ == t_class )
- {
- cardfix=cardfix*(100+sd->right_weapon.add_dmg[i].rate)/100;
- break;
- }
- }
-
- if( left&1 )
- {
- for( i = 0; i < ARRAYLENGTH(sd->left_weapon.add_dmg) && sd->left_weapon.add_dmg[i].rate; i++ )
- {
- if( sd->left_weapon.add_dmg[i].class_ == t_class )
- {
- cardfix_=cardfix_*(100+sd->left_weapon.add_dmg[i].rate)/100;
- break;
- }
- }
- }
-
- if( flag&BF_LONG )
- cardfix = cardfix * ( 100 + sd->bonus.long_attack_atk_rate ) / 100;
-#ifdef RENEWAL_EDP
- if( sd->sc.data[SC_EDP] ){
- cardfix = cardfix * (100 + sd->sc.data[SC_EDP]->val1 * 60 ) / 100;
- cardfix_ = cardfix_ * (100 + sd->sc.data[SC_EDP]->val1 * 60 ) / 100;
- }
-#endif
- if( (left&1) && cardfix_ != 1000 )
- damage = damage * cardfix_ / 1000;
- else if( cardfix != 1000 )
- damage = damage * cardfix / 1000;
-
- }else if( tsd && !(nk&NK_NO_CARDFIX_DEF) ){
- if( !(nk&NK_NO_ELEFIX) )
- {
- int ele_fix = tsd->subele[s_ele];
- for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++)
- {
- if(tsd->subele2[i].ele != s_ele) continue;
- if(!(tsd->subele2[i].flag&flag&BF_WEAPONMASK &&
- tsd->subele2[i].flag&flag&BF_RANGEMASK &&
- tsd->subele2[i].flag&flag&BF_SKILLMASK))
- continue;
- ele_fix += tsd->subele2[i].rate;
- }
- cardfix=cardfix*(100-ele_fix)/100;
- if( left&1 && s_ele_ != s_ele )
- {
- int ele_fix_lh = tsd->subele[s_ele_];
- for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++)
- {
- if(tsd->subele2[i].ele != s_ele_) continue;
- if(!(tsd->subele2[i].flag&flag&BF_WEAPONMASK &&
- tsd->subele2[i].flag&flag&BF_RANGEMASK &&
- tsd->subele2[i].flag&flag&BF_SKILLMASK))
- continue;
- ele_fix_lh += tsd->subele2[i].rate;
- }
- cardfix=cardfix*(100-ele_fix_lh)/100;
- }
- }
- cardfix=cardfix*(100-tsd->subsize[sstatus->size])/100;
- cardfix=cardfix*(100-tsd->subrace2[s_race2])/100;
- cardfix=cardfix*(100-tsd->subrace[sstatus->race])/100;
- cardfix=cardfix*(100-tsd->subrace[is_boss(src)?RC_BOSS:RC_NONBOSS])/100;
- if( sstatus->race != RC_DEMIHUMAN )
- cardfix=cardfix*(100-tsd->subrace[RC_NONDEMIHUMAN])/100;
+ if (def_type < 0 || def_type > ELE_MAX ||
+ def_lv < 1 || def_lv > 4) {
+ ShowError("battle_attr_fix: unknown attr type: atk=%d def_type=%d def_lv=%d\n",atk_elem,def_type,def_lv);
+ return damage;
+ }
- for( i = 0; i < ARRAYLENGTH(tsd->add_def) && tsd->add_def[i].rate;i++ ) {
- if( tsd->add_def[i].class_ == s_class ) {
- cardfix=cardfix*(100-tsd->add_def[i].rate)/100;
- break;
- }
+ ratio = attr_fix_table[def_lv-1][atk_elem][def_type];
+ if (sc && sc->count) {
+ if(sc->data[SC_VOLCANO] && atk_elem == ELE_FIRE)
+ ratio += enchant_eff[sc->data[SC_VOLCANO]->val1-1];
+ if(sc->data[SC_VIOLENTGALE] && atk_elem == ELE_WIND)
+ ratio += enchant_eff[sc->data[SC_VIOLENTGALE]->val1-1];
+ if(sc->data[SC_DELUGE] && atk_elem == ELE_WATER)
+ ratio += enchant_eff[sc->data[SC_DELUGE]->val1-1];
+ }
+ if( target && target->type == BL_SKILL ) {
+ if( atk_elem == ELE_FIRE && battle_getcurrentskill(target) == GN_WALLOFTHORN ) {
+ struct skill_unit *su = (struct skill_unit*)target;
+ struct skill_unit_group *sg;
+ struct block_list *src;
+ int x,y;
+
+ if( !su || !su->alive || (sg = su->group) == NULL || !sg || sg->val3 == -1 ||
+ (src = map_id2bl(sg->src_id)) == NULL || status_isdead(src) )
+ return 0;
+
+ if( sg->unit_id != UNT_FIREWALL ) {
+ x = sg->val3 >> 16;
+ y = sg->val3 & 0xffff;
+ skill_unitsetting(src,su->group->skill_id,su->group->skill_lv,x,y,1);
+ sg->val3 = -1;
+ sg->limit = DIFF_TICK(gettick(),sg->tick)+300;
}
+ }
+ }
+ if( tsc && tsc->count ) { //since an atk can only have one type let's optimise this a bit
+ switch(atk_elem){
+ case ELE_FIRE:
+ if( tsc->data[SC_SPIDERWEB]) {
+ tsc->data[SC_SPIDERWEB]->val1 = 0; // free to move now
+ if( tsc->data[SC_SPIDERWEB]->val2-- > 0 )
+ damage <<= 1; // double damage
+ if( tsc->data[SC_SPIDERWEB]->val2 == 0 )
+ status_change_end(target, SC_SPIDERWEB, INVALID_TIMER);
+ }
+ if( tsc->data[SC_THORNSTRAP])
+ status_change_end(target, SC_THORNSTRAP, INVALID_TIMER);
+ if( tsc->data[SC_FIRE_CLOAK_OPTION])
+ damage -= damage * tsc->data[SC_FIRE_CLOAK_OPTION]->val2 / 100;
+ if( tsc->data[SC_CRYSTALIZE] && target->type != BL_MOB)
+ status_change_end(target, SC_CRYSTALIZE, INVALID_TIMER);
+ if( tsc->data[SC_EARTH_INSIGNIA]) damage += damage/2;
+ if( tsc->data[SC_ASH]) damage += damage/2; //150%
+ break;
+ case ELE_HOLY:
+ if( tsc->data[SC_ORATIO]) ratio += tsc->data[SC_ORATIO]->val1 * 2;
+ break;
+ case ELE_POISON:
+ if( tsc->data[SC_VENOMIMPRESS]) ratio += tsc->data[SC_VENOMIMPRESS]->val2;
+ break;
+ case ELE_WIND:
+ if( tsc->data[SC_CRYSTALIZE] && target->type != BL_MOB) damage += damage/2;
+ if( tsc->data[SC_WATER_INSIGNIA]) damage += damage/2;
+ break;
+ case ELE_WATER:
+ if( tsc->data[SC_FIRE_INSIGNIA]) damage += damage/2;
+ break;
+ case ELE_EARTH:
+ if( tsc->data[SC_WIND_INSIGNIA]) damage += damage/2;
+ break;
+ }
+ } //end tsc check
+ if( src && src->type == BL_PC ){
+ struct map_session_data *sd = BL_CAST(BL_PC, src);
+ int s;
- if( flag&BF_SHORT )
- cardfix = cardfix * ( 100 - tsd->bonus.near_attack_def_rate ) / 100;
- else // BF_LONG (there's no other choice)
- cardfix = cardfix * ( 100 - tsd->bonus.long_attack_def_rate ) / 100;
+ ARR_FIND(1, 6, s, sd->talisman[s] > 0);
- if( tsd->sc.data[SC_DEF_RATE] )
- cardfix = cardfix * ( 100 - tsd->sc.data[SC_DEF_RATE]->val1 ) / 100;
+ if( s < 5 && atk_elem == s )
+ ratio += sd->talisman[s] * 2; // +2% custom value
+ }
+ if( target && target->type == BL_PC ) {
+ struct map_session_data *tsd = BL_CAST(BL_PC, target);
+ int t;
- if( cardfix != 1000 )
- damage = damage * cardfix / 1000;
- }
- break;
- case BF_MISC:
- if( tsd && !(nk&NK_NO_CARDFIX_DEF) ){
- // misc damage reduction from equipment
- if (!(nk&NK_NO_ELEFIX))
- {
- int ele_fix = tsd->subele[s_ele];
- for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++)
- {
- if(tsd->subele2[i].ele != s_ele) continue;
- if(!(tsd->subele2[i].flag&flag&BF_WEAPONMASK &&
- tsd->subele2[i].flag&flag&BF_RANGEMASK &&
- tsd->subele2[i].flag&flag&BF_SKILLMASK))
- continue;
- ele_fix += tsd->subele2[i].rate;
- }
- cardfix=cardfix*(100-ele_fix)/100;
- }
- cardfix=cardfix*(100-tsd->subsize[sstatus->size])/100;
- cardfix=cardfix*(100-tsd->subrace2[s_race2])/100;
- cardfix=cardfix*(100-tsd->subrace[sstatus->race])/100;
- cardfix=cardfix*(100-tsd->subrace[is_boss(src)?RC_BOSS:RC_NONBOSS])/100;
- if( sstatus->race != RC_DEMIHUMAN )
- cardfix=cardfix*(100-tsd->subrace[RC_NONDEMIHUMAN])/100;
-
- cardfix = cardfix * ( 100 - tsd->bonus.misc_def_rate ) / 100;
- if( flag&BF_SHORT )
- cardfix = cardfix * ( 100 - tsd->bonus.near_attack_def_rate ) / 100;
- else // BF_LONG (there's no other choice)
- cardfix = cardfix * ( 100 - tsd->bonus.long_attack_def_rate ) / 100;
+ ARR_FIND(1, 6, t, tsd->talisman[t] > 0);
- if (cardfix != 10000)
- damage = (int)( (int64)damage * cardfix / 1000);
- }
- break;
+ if( t < 5 && atk_elem == t )
+ damage -= damage * tsd->talisman[t] * 3 / 100; // -3% custom value
}
-
- return damage;
+ return damage*ratio/100;
}
/*==========================================
@@ -736,506 +415,519 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
*------------------------------------------*/
int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damage *d,int damage,int skill_num,int skill_lv)
{
- struct map_session_data *sd = NULL;
- struct status_change *sc;
- struct status_change_entry *sce;
- int div_ = d->div_, flag = d->flag;
+ struct map_session_data *sd = NULL;
+ struct status_change *sc;
+ struct status_change_entry *sce;
+ int div_ = d->div_, flag = d->flag;
- nullpo_ret(bl);
+ nullpo_ret(bl);
- if (!damage)
- return 0;
- if (battle_config.ksprotection && mob_ksprotected(src, bl))
- return 0;
+ if( !damage )
+ return 0;
+ if( battle_config.ksprotection && mob_ksprotected(src, bl) )
+ return 0;
- if (bl->type == BL_PC) {
- sd=(struct map_session_data *)bl;
- //Special no damage states
- if (flag&BF_WEAPON && sd->special_state.no_weapon_damage)
- damage -= damage*sd->special_state.no_weapon_damage/100;
+ if (bl->type == BL_PC) {
+ sd=(struct map_session_data *)bl;
+ //Special no damage states
+ if(flag&BF_WEAPON && sd->special_state.no_weapon_damage)
+ damage -= damage*sd->special_state.no_weapon_damage/100;
- if (flag&BF_MAGIC && sd->special_state.no_magic_damage)
- damage -= damage*sd->special_state.no_magic_damage/100;
+ if(flag&BF_MAGIC && sd->special_state.no_magic_damage)
+ damage -= damage*sd->special_state.no_magic_damage/100;
- if (flag&BF_MISC && sd->special_state.no_misc_damage)
- damage -= damage*sd->special_state.no_misc_damage/100;
+ if(flag&BF_MISC && sd->special_state.no_misc_damage)
+ damage -= damage*sd->special_state.no_misc_damage/100;
- if (!damage) return 0;
- }
+ if(!damage) return 0;
+ }
- sc = status_get_sc(bl);
+ sc = status_get_sc(bl);
- if (sc && sc->data[SC_INVINCIBLE] && !sc->data[SC_INVINCIBLEOFF])
- return 1;
+ if( sc && sc->data[SC_INVINCIBLE] && !sc->data[SC_INVINCIBLEOFF] )
+ return 1;
- if (skill_num == PA_PRESSURE)
- return damage; //This skill bypass everything else.
+ if (skill_num == PA_PRESSURE)
+ return damage; //This skill bypass everything else.
- if (sc && sc->count) {
- //First, sc_*'s that reduce damage to 0.
- if (sc->data[SC_BASILICA] && !(status_get_mode(src)&MD_BOSS)) {
- d->dmg_lv = ATK_BLOCK;
- return 0;
- }
- if (sc->data[SC_WHITEIMPRISON] && skill_num != HW_GRAVITATION) { // Gravitation and Pressure do damage without removing the effect
- if (skill_num == MG_NAPALMBEAT ||
- skill_num == MG_SOULSTRIKE ||
- skill_num == WL_SOULEXPANSION ||
- (skill_num && skill_get_ele(skill_num, skill_lv) == ELE_GHOST) ||
- (!skill_num && (status_get_status_data(src))->rhw.ele == ELE_GHOST)
- ) {
- if (skill_num == WL_SOULEXPANSION)
- damage <<= 1; // If used against a player in White Imprison, the skill deals double damage.
- status_change_end(bl,SC_WHITEIMPRISON,INVALID_TIMER); // Those skills do damage and removes effect
- } else {
- d->dmg_lv = ATK_BLOCK;
- return 0;
- }
- }
+ if( sc && sc->count )
+ {
+ //First, sc_*'s that reduce damage to 0.
+ if( sc->data[SC_BASILICA] && !(status_get_mode(src)&MD_BOSS) )
+ {
+ d->dmg_lv = ATK_BLOCK;
+ return 0;
+ }
+ if( sc->data[SC_WHITEIMPRISON] && skill_num != HW_GRAVITATION ) { // Gravitation and Pressure do damage without removing the effect
+ if( skill_num == MG_NAPALMBEAT ||
+ skill_num == MG_SOULSTRIKE ||
+ skill_num == WL_SOULEXPANSION ||
+ (skill_num && skill_get_ele(skill_num, skill_lv) == ELE_GHOST) ||
+ (!skill_num && (status_get_status_data(src))->rhw.ele == ELE_GHOST)
+ ){
+ if( skill_num == WL_SOULEXPANSION )
+ damage <<= 1; // If used against a player in White Imprison, the skill deals double damage.
+ status_change_end(bl,SC_WHITEIMPRISON,INVALID_TIMER); // Those skills do damage and removes effect
+ }else{
+ d->dmg_lv = ATK_BLOCK;
+ return 0;
+ }
+ }
- if (sc->data[SC_ZEPHYR] &&
- flag&(BF_LONG|BF_SHORT)) {
- d->dmg_lv = ATK_BLOCK;
- return 0;
- }
+ if(sc->data[SC_ZEPHYR] &&
+ flag&(BF_LONG|BF_SHORT)){
+ d->dmg_lv = ATK_BLOCK;
+ return 0;
+ }
- if (sc->data[SC_SAFETYWALL] && (flag&(BF_SHORT|BF_MAGIC))==BF_SHORT) {
- struct skill_unit_group *group = skill_id2group(sc->data[SC_SAFETYWALL]->val3);
- int skill_id = sc->data[SC_SAFETYWALL]->val2;
- if (group) {
- if (skill_id == MH_STEINWAND) {
- if (--group->val2<=0)
- skill_delunitgroup(group);
- d->dmg_lv = ATK_BLOCK;
- return 0;
- }
- /**
- * in RE, SW possesses a lifetime equal to 3 times the caster's health
- **/
-#ifdef RENEWAL
- if ((group->val2 - damage) > 0) {
- group->val2 -= damage;
- d->dmg_lv = ATK_BLOCK;
- return 0;
- } else
- damage -= group->val2;
- skill_delunitgroup(group);
-#else
- if (--group->val2<=0)
- skill_delunitgroup(group);
- d->dmg_lv = ATK_BLOCK;
- return 0;
-#endif
- }
- status_change_end(bl, SC_SAFETYWALL, INVALID_TIMER);
- }
+ if( sc->data[SC_SAFETYWALL] && (flag&(BF_SHORT|BF_MAGIC))==BF_SHORT )
+ {
+ struct skill_unit_group* group = skill_id2group(sc->data[SC_SAFETYWALL]->val3);
+ int skill_id = sc->data[SC_SAFETYWALL]->val2;
+ if (group) {
+ if(skill_id == MH_STEINWAND){
+ if (--group->val2<=0)
+ skill_delunitgroup(group);
+ d->dmg_lv = ATK_BLOCK;
+ return 0;
+ }
+ /**
+ * in RE, SW possesses a lifetime equal to 3 times the caster's health
+ **/
+ #ifdef RENEWAL
+ if ( ( group->val2 - damage) > 0 ) {
+ group->val2 -= damage;
+ d->dmg_lv = ATK_BLOCK;
+ return 0;
+ } else
+ damage -= group->val2;
+ skill_delunitgroup(group);
+ #else
+ if (--group->val2<=0)
+ skill_delunitgroup(group);
+ d->dmg_lv = ATK_BLOCK;
+ return 0;
+ #endif
+ }
+ status_change_end(bl, SC_SAFETYWALL, INVALID_TIMER);
+ }
- if ((sc->data[SC_PNEUMA] && (flag&(BF_MAGIC|BF_LONG)) == BF_LONG) || sc->data[SC__MANHOLE]) {
- d->dmg_lv = ATK_BLOCK;
- return 0;
- }
- if (sc->data[SC_WEAPONBLOCKING] && flag&(BF_SHORT|BF_WEAPON) && rnd()%100 < sc->data[SC_WEAPONBLOCKING]->val2) {
- clif_skill_nodamage(bl,src,GC_WEAPONBLOCKING,1,1);
- d->dmg_lv = ATK_BLOCK;
- sc_start2(bl,SC_COMBO,100,GC_WEAPONBLOCKING,src->id,2000);
- return 0;
- }
- if ((sce=sc->data[SC_AUTOGUARD]) && flag&BF_WEAPON && !(skill_get_nk(skill_num)&NK_NO_CARDFIX_ATK) && rnd()%100 < sce->val2) {
- int delay;
- clif_skill_nodamage(bl,bl,CR_AUTOGUARD,sce->val1,1);
- // different delay depending on skill level [celest]
- if (sce->val1 <= 5)
- delay = 300;
- else if (sce->val1 > 5 && sce->val1 <= 9)
- delay = 200;
- else
- delay = 100;
- unit_set_walkdelay(bl, gettick(), delay, 1);
-
- if (sc->data[SC_SHRINK] && rnd()%100<5*sce->val1)
- skill_blown(bl,src,skill_get_blewcount(CR_SHRINK,1),-1,0);
- return 0;
- }
+ if( ( sc->data[SC_PNEUMA] && (flag&(BF_MAGIC|BF_LONG)) == BF_LONG ) || sc->data[SC__MANHOLE] ) {
+ d->dmg_lv = ATK_BLOCK;
+ return 0;
+ }
+ if( sc->data[SC_WEAPONBLOCKING] && flag&(BF_SHORT|BF_WEAPON) && rnd()%100 < sc->data[SC_WEAPONBLOCKING]->val2 )
+ {
+ clif_skill_nodamage(bl,src,GC_WEAPONBLOCKING,1,1);
+ d->dmg_lv = ATK_BLOCK;
+ sc_start2(bl,SC_COMBO,100,GC_WEAPONBLOCKING,src->id,2000);
+ return 0;
+ }
+ if( (sce=sc->data[SC_AUTOGUARD]) && flag&BF_WEAPON && !(skill_get_nk(skill_num)&NK_NO_CARDFIX_ATK) && rnd()%100 < sce->val2 )
+ {
+ int delay;
+ clif_skill_nodamage(bl,bl,CR_AUTOGUARD,sce->val1,1);
+ // different delay depending on skill level [celest]
+ if (sce->val1 <= 5)
+ delay = 300;
+ else if (sce->val1 > 5 && sce->val1 <= 9)
+ delay = 200;
+ else
+ delay = 100;
+ unit_set_walkdelay(bl, gettick(), delay, 1);
+
+ if(sc->data[SC_SHRINK] && rnd()%100<5*sce->val1)
+ skill_blown(bl,src,skill_get_blewcount(CR_SHRINK,1),-1,0);
+ return 0;
+ }
- if ((sce = sc->data[SC_MILLENNIUMSHIELD]) && sce->val2 > 0 && damage > 0) {
- clif_skill_nodamage(bl, bl, RK_MILLENNIUMSHIELD, 1, 1);
- sce->val3 -= damage; // absorb damage
- d->dmg_lv = ATK_BLOCK;
- sc_start(bl,SC_STUN,15,0,skill_get_time2(RK_MILLENNIUMSHIELD,sce->val1)); // There is a chance to be stuned when one shield is broken.
- if (sce->val3 <= 0) { // Shield Down
- sce->val2--;
- if (sce->val2 > 0) {
- if (sd)
- clif_millenniumshield(sd,sce->val2);
- sce->val3 = 1000; // Next Shield
- } else
- status_change_end(bl,SC_MILLENNIUMSHIELD,INVALID_TIMER); // All shields down
- }
- return 0;
- }
+ if( (sce = sc->data[SC_MILLENNIUMSHIELD]) && sce->val2 > 0 && damage > 0 ) {
+ clif_skill_nodamage(bl, bl, RK_MILLENNIUMSHIELD, 1, 1);
+ sce->val3 -= damage; // absorb damage
+ d->dmg_lv = ATK_BLOCK;
+ sc_start(bl,SC_STUN,15,0,skill_get_time2(RK_MILLENNIUMSHIELD,sce->val1)); // There is a chance to be stuned when one shield is broken.
+ if( sce->val3 <= 0 ) { // Shield Down
+ sce->val2--;
+ if( sce->val2 > 0 ) {
+ if( sd )
+ clif_millenniumshield(sd,sce->val2);
+ sce->val3 = 1000; // Next Shield
+ } else
+ status_change_end(bl,SC_MILLENNIUMSHIELD,INVALID_TIMER); // All shields down
+ }
+ return 0;
+ }
- if ((sce=sc->data[SC_PARRYING]) && flag&BF_WEAPON && skill_num != WS_CARTTERMINATION && rnd()%100 < sce->val2) {
- // attack blocked by Parrying
- clif_skill_nodamage(bl, bl, LK_PARRYING, sce->val1,1);
- return 0;
- }
+ if( (sce=sc->data[SC_PARRYING]) && flag&BF_WEAPON && skill_num != WS_CARTTERMINATION && rnd()%100 < sce->val2 )
+ { // attack blocked by Parrying
+ clif_skill_nodamage(bl, bl, LK_PARRYING, sce->val1,1);
+ return 0;
+ }
- if (sc->data[SC_DODGE] && (!sc->opt1 || sc->opt1 == OPT1_BURNING) &&
- (flag&BF_LONG || sc->data[SC_SPURT])
- && rnd()%100 < 20) {
- if (sd && pc_issit(sd)) pc_setstand(sd); //Stand it to dodge.
- clif_skill_nodamage(bl,bl,TK_DODGE,1,1);
- if (!sc->data[SC_COMBO])
- sc_start4(bl, SC_COMBO, 100, TK_JUMPKICK, src->id, 1, 0, 2000);
- return 0;
- }
+ if(sc->data[SC_DODGE] && ( !sc->opt1 || sc->opt1 == OPT1_BURNING ) &&
+ (flag&BF_LONG || sc->data[SC_SPURT])
+ && rnd()%100 < 20) {
+ if (sd && pc_issit(sd)) pc_setstand(sd); //Stand it to dodge.
+ clif_skill_nodamage(bl,bl,TK_DODGE,1,1);
+ if (!sc->data[SC_COMBO])
+ sc_start4(bl, SC_COMBO, 100, TK_JUMPKICK, src->id, 1, 0, 2000);
+ return 0;
+ }
- if (sc->data[SC_HERMODE] && flag&BF_MAGIC)
- return 0;
+ if(sc->data[SC_HERMODE] && flag&BF_MAGIC)
+ return 0;
- if (sc->data[SC_TATAMIGAESHI] && (flag&(BF_MAGIC|BF_LONG)) == BF_LONG)
- return 0;
+ if(sc->data[SC_TATAMIGAESHI] && (flag&(BF_MAGIC|BF_LONG)) == BF_LONG)
+ return 0;
- if (sc->data[SC_NEUTRALBARRIER] && (flag&(BF_MAGIC|BF_LONG)) == (BF_MAGIC|BF_LONG)) {
- d->dmg_lv = ATK_MISS;
- return 0;
- }
+ if( sc->data[SC_NEUTRALBARRIER] && (flag&(BF_MAGIC|BF_LONG)) == (BF_MAGIC|BF_LONG) ) {
+ d->dmg_lv = ATK_MISS;
+ return 0;
+ }
- if ((sce=sc->data[SC_KAUPE]) && rnd()%100 < sce->val2) {
- //Kaupe blocks damage (skill or otherwise) from players, mobs, homuns, mercenaries.
- clif_specialeffect(bl, 462, AREA);
- //Shouldn't end until Breaker's non-weapon part connects.
- if (skill_num != ASC_BREAKER || !(flag&BF_WEAPON))
- if (--(sce->val3) <= 0) //We make it work like Safety Wall, even though it only blocks 1 time.
- status_change_end(bl, SC_KAUPE, INVALID_TIMER);
- return 0;
- }
+ if((sce=sc->data[SC_KAUPE]) && rnd()%100 < sce->val2)
+ { //Kaupe blocks damage (skill or otherwise) from players, mobs, homuns, mercenaries.
+ clif_specialeffect(bl, 462, AREA);
+ //Shouldn't end until Breaker's non-weapon part connects.
+ if (skill_num != ASC_BREAKER || !(flag&BF_WEAPON))
+ if (--(sce->val3) <= 0) //We make it work like Safety Wall, even though it only blocks 1 time.
+ status_change_end(bl, SC_KAUPE, INVALID_TIMER);
+ return 0;
+ }
- if (flag&BF_MAGIC && (sce=sc->data[SC_PRESTIGE]) && rnd()%100 < sce->val2) {
- clif_specialeffect(bl, 462, AREA); // Still need confirm it.
- return 0;
- }
+ if( flag&BF_MAGIC && (sce=sc->data[SC_PRESTIGE]) && rnd()%100 < sce->val2) {
+ clif_specialeffect(bl, 462, AREA); // Still need confirm it.
+ return 0;
+ }
- if (((sce=sc->data[SC_UTSUSEMI]) || sc->data[SC_BUNSINJYUTSU])
- && flag&BF_WEAPON && !(skill_get_nk(skill_num)&NK_NO_CARDFIX_ATK)) {
+ if (((sce=sc->data[SC_UTSUSEMI]) || sc->data[SC_BUNSINJYUTSU])
+ && flag&BF_WEAPON && !(skill_get_nk(skill_num)&NK_NO_CARDFIX_ATK)) {
- skill_additional_effect(src, bl, skill_num, skill_lv, flag, ATK_BLOCK, gettick());
- if (!status_isdead(src))
- skill_counter_additional_effect(src, bl, skill_num, skill_lv, flag, gettick());
- if (sce) {
- clif_specialeffect(bl, 462, AREA);
- skill_blown(src,bl,sce->val3,-1,0);
- }
- //Both need to be consumed if they are active.
- if (sce && --(sce->val2) <= 0)
- status_change_end(bl, SC_UTSUSEMI, INVALID_TIMER);
- if ((sce=sc->data[SC_BUNSINJYUTSU]) && --(sce->val2) <= 0)
- status_change_end(bl, SC_BUNSINJYUTSU, INVALID_TIMER);
+ skill_additional_effect (src, bl, skill_num, skill_lv, flag, ATK_BLOCK, gettick() );
+ if( !status_isdead(src) )
+ skill_counter_additional_effect( src, bl, skill_num, skill_lv, flag, gettick() );
+ if (sce) {
+ clif_specialeffect(bl, 462, AREA);
+ skill_blown(src,bl,sce->val3,-1,0);
+ }
+ //Both need to be consumed if they are active.
+ if (sce && --(sce->val2) <= 0)
+ status_change_end(bl, SC_UTSUSEMI, INVALID_TIMER);
+ if ((sce=sc->data[SC_BUNSINJYUTSU]) && --(sce->val2) <= 0)
+ status_change_end(bl, SC_BUNSINJYUTSU, INVALID_TIMER);
- return 0;
- }
+ return 0;
+ }
- //Now damage increasing effects
- if (sc->data[SC_AETERNA] && skill_num != PF_SOULBURN) {
- if (src->type != BL_MER || skill_num == 0)
- damage <<= 1; // Lex Aeterna only doubles damage of regular attacks from mercenaries
+ //Now damage increasing effects
+ if( sc->data[SC_AETERNA] && skill_num != PF_SOULBURN )
+ {
+ if( src->type != BL_MER || skill_num == 0 )
+ damage <<= 1; // Lex Aeterna only doubles damage of regular attacks from mercenaries
- if (skill_num != ASC_BREAKER || !(flag&BF_WEAPON))
- status_change_end(bl, SC_AETERNA, INVALID_TIMER); //Shouldn't end until Breaker's non-weapon part connects.
- }
+ if( skill_num != ASC_BREAKER || !(flag&BF_WEAPON) )
+ status_change_end(bl, SC_AETERNA, INVALID_TIMER); //Shouldn't end until Breaker's non-weapon part connects.
+ }
#ifdef RENEWAL
- if (sc->data[SC_RAID]) {
- damage += 20*damage/100;
+ if( sc->data[SC_RAID] )
+ {
+ damage += 20*damage/100;
- if (--sc->data[SC_RAID]->val1 == 0)
- status_change_end(bl, SC_RAID, INVALID_TIMER);
- }
+ if (--sc->data[SC_RAID]->val1 == 0)
+ status_change_end(bl, SC_RAID, INVALID_TIMER);
+ }
#endif
- if (damage) {
- struct map_session_data *tsd = BL_CAST(BL_PC, src);
- if (sc->data[SC_DEEPSLEEP]) {
- damage += damage / 2; // 1.5 times more damage while in Deep Sleep.
- status_change_end(bl,SC_DEEPSLEEP,INVALID_TIMER);
- }
- if (tsd && sd && sc->data[SC_CRYSTALIZE] && flag&BF_WEAPON) {
- switch (tsd->status.weapon) {
- case W_MACE:
- case W_2HMACE:
- case W_1HAXE:
- case W_2HAXE:
- damage = damage * 150 / 100;
- break;
- case W_MUSICAL:
- case W_WHIP:
- if (!sd->state.arrow_atk)
- break;
- case W_BOW:
- case W_REVOLVER:
- case W_RIFLE:
- case W_GATLING:
- case W_SHOTGUN:
- case W_GRENADE:
- case W_DAGGER:
- case W_1HSWORD:
- case W_2HSWORD:
- damage = damage * 50 / 100;
- break;
- }
- }
- if (sc->data[SC_VOICEOFSIREN])
- status_change_end(bl,SC_VOICEOFSIREN,INVALID_TIMER);
- }
+ if( damage ) {
+ struct map_session_data *tsd = BL_CAST(BL_PC, src);
+ if( sc->data[SC_DEEPSLEEP] ) {
+ damage += damage / 2; // 1.5 times more damage while in Deep Sleep.
+ status_change_end(bl,SC_DEEPSLEEP,INVALID_TIMER);
+ }
+ if( tsd && sd && sc->data[SC_CRYSTALIZE] && flag&BF_WEAPON ){
+ switch(tsd->status.weapon){
+ case W_MACE:
+ case W_2HMACE:
+ case W_1HAXE:
+ case W_2HAXE:
+ damage = damage * 150 / 100;
+ break;
+ case W_MUSICAL:
+ case W_WHIP:
+ if(!sd->state.arrow_atk)
+ break;
+ case W_BOW:
+ case W_REVOLVER:
+ case W_RIFLE:
+ case W_GATLING:
+ case W_SHOTGUN:
+ case W_GRENADE:
+ case W_DAGGER:
+ case W_1HSWORD:
+ case W_2HSWORD:
+ damage = damage * 50 / 100;
+ break;
+ }
+ }
+ if( sc->data[SC_VOICEOFSIREN] )
+ status_change_end(bl,SC_VOICEOFSIREN,INVALID_TIMER);
+ }
- //Finally damage reductions....
- // Assumptio doubles the def & mdef on RE mode, otherwise gives a reduction on the final damage. [Igniz]
+ //Finally damage reductions....
+ // Assumptio doubles the def & mdef on RE mode, otherwise gives a reduction on the final damage. [Igniz]
#ifndef RENEWAL
- if (sc->data[SC_ASSUMPTIO]) {
- if (map_flag_vs(bl->m))
- damage = damage*2/3; //Receive 66% damage
- else
- damage >>= 1; //Receive 50% damage
- }
+ if( sc->data[SC_ASSUMPTIO] ) {
+ if( map_flag_vs(bl->m) )
+ damage = damage*2/3; //Receive 66% damage
+ else
+ damage >>= 1; //Receive 50% damage
+ }
#endif
- if (sc->data[SC_DEFENDER] &&
- (flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON))
- damage=damage*(100-sc->data[SC_DEFENDER]->val2)/100;
+ if(sc->data[SC_DEFENDER] &&
+ (flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON))
+ damage=damage*(100-sc->data[SC_DEFENDER]->val2)/100;
- if (sc->data[SC_ADJUSTMENT] &&
- (flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON))
- damage -= 20*damage/100;
+ if(sc->data[SC_ADJUSTMENT] &&
+ (flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON))
+ damage -= 20*damage/100;
- if (sc->data[SC_FOGWALL] && skill_num != RK_DRAGONBREATH) {
- if (flag&BF_SKILL) //25% reduction
- damage -= 25*damage/100;
- else if ((flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON))
- damage >>= 2; //75% reduction
- }
+ if(sc->data[SC_FOGWALL] && skill_num != RK_DRAGONBREATH) {
+ if(flag&BF_SKILL) //25% reduction
+ damage -= 25*damage/100;
+ else if ((flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON))
+ damage >>= 2; //75% reduction
+ }
- // Compressed code, fixed by map.h [Epoque]
- if (src->type == BL_MOB) {
- int i;
- if (sc->data[SC_MANU_DEF])
- for (i=0; ARRAYLENGTH(mob_manuk)>i; i++)
- if (mob_manuk[i]==((TBL_MOB *)src)->class_) {
- damage -= sc->data[SC_MANU_DEF]->val1*damage/100;
- break;
- }
- if (sc->data[SC_SPL_DEF])
- for (i=0; ARRAYLENGTH(mob_splendide)>i; i++)
- if (mob_splendide[i]==((TBL_MOB *)src)->class_) {
- damage -= sc->data[SC_SPL_DEF]->val1*damage/100;
- break;
- }
- }
+ // Compressed code, fixed by map.h [Epoque]
+ if (src->type == BL_MOB) {
+ int i;
+ if (sc->data[SC_MANU_DEF])
+ for (i=0;ARRAYLENGTH(mob_manuk)>i;i++)
+ if (mob_manuk[i]==((TBL_MOB*)src)->class_) {
+ damage -= sc->data[SC_MANU_DEF]->val1*damage/100;
+ break;
+ }
+ if (sc->data[SC_SPL_DEF])
+ for (i=0;ARRAYLENGTH(mob_splendide)>i;i++)
+ if (mob_splendide[i]==((TBL_MOB*)src)->class_) {
+ damage -= sc->data[SC_SPL_DEF]->val1*damage/100;
+ break;
+ }
+ }
- if ((sce=sc->data[SC_ARMOR]) && //NPC_DEFENDER
- sce->val3&flag && sce->val4&flag)
- damage -= damage*sc->data[SC_ARMOR]->val2/100;
+ if((sce=sc->data[SC_ARMOR]) && //NPC_DEFENDER
+ sce->val3&flag && sce->val4&flag)
+ damage -= damage*sc->data[SC_ARMOR]->val2/100;
#ifdef RENEWAL
- if (sc->data[SC_ENERGYCOAT] && (flag&BF_WEAPON || flag&BF_MAGIC) && skill_num != WS_CARTTERMINATION)
+ if(sc->data[SC_ENERGYCOAT] && (flag&BF_WEAPON || flag&BF_MAGIC) && skill_num != WS_CARTTERMINATION)
#else
- if (sc->data[SC_ENERGYCOAT] && flag&BF_WEAPON && skill_num != WS_CARTTERMINATION)
+ if(sc->data[SC_ENERGYCOAT] && flag&BF_WEAPON && skill_num != WS_CARTTERMINATION)
#endif
- {
- struct status_data *status = status_get_status_data(bl);
- int per = 100*status->sp / status->max_sp -1; //100% should be counted as the 80~99% interval
- per /=20; //Uses 20% SP intervals.
- //SP Cost: 1% + 0.5% per every 20% SP
- if (!status_charge(bl, 0, (10+5*per)*status->max_sp/1000))
- status_change_end(bl, SC_ENERGYCOAT, INVALID_TIMER);
- //Reduction: 6% + 6% every 20%
- damage -= damage * 6 * (1+per) / 100;
- }
- if (sc->data[SC_GRANITIC_ARMOR]) {
- damage -= damage * sc->data[SC_GRANITIC_ARMOR]->val2/100;
- }
- if (sc->data[SC_PAIN_KILLER]) {
- damage -= damage * sc->data[SC_PAIN_KILLER]->val3/100;
- }
- if ((sce=sc->data[SC_MAGMA_FLOW]) && (rnd()%100 <= sce->val2)) {
- skill_castend_damage_id(bl,src,MH_MAGMA_FLOW,sce->val1,gettick(),0);
- }
+ {
+ struct status_data *status = status_get_status_data(bl);
+ int per = 100*status->sp / status->max_sp -1; //100% should be counted as the 80~99% interval
+ per /=20; //Uses 20% SP intervals.
+ //SP Cost: 1% + 0.5% per every 20% SP
+ if (!status_charge(bl, 0, (10+5*per)*status->max_sp/1000))
+ status_change_end(bl, SC_ENERGYCOAT, INVALID_TIMER);
+ //Reduction: 6% + 6% every 20%
+ damage -= damage * 6 * (1+per) / 100;
+ }
+ if(sc->data[SC_GRANITIC_ARMOR]){
+ damage -= damage * sc->data[SC_GRANITIC_ARMOR]->val2/100;
+ }
+ if(sc->data[SC_PAIN_KILLER]){
+ damage -= damage * sc->data[SC_PAIN_KILLER]->val3/100;
+ }
+ if((sce=sc->data[SC_MAGMA_FLOW]) && (rnd()%100 <= sce->val2) ){
+ skill_castend_damage_id(bl,src,MH_MAGMA_FLOW,sce->val1,gettick(),0);
+ }
- /**
- * In renewal steel body reduces all incoming damage by 1/10
- **/
+/**
+ * In renewal steel body reduces all incoming damage by 1/10
+ **/
#ifdef RENEWAL
- if (sc->data[SC_STEELBODY]) {
- damage = damage > 10 ? damage / 10 : 1;
- }
+ if( sc->data[SC_STEELBODY] ) {
+ damage = damage > 10 ? damage / 10 : 1;
+ }
#endif
- //Finally added to remove the status of immobile when aimedbolt is used. [Jobbie]
- if (skill_num == RA_AIMEDBOLT && (sc->data[SC_BITE] || sc->data[SC_ANKLE] || sc->data[SC_ELECTRICSHOCKER])) {
- status_change_end(bl, SC_BITE, INVALID_TIMER);
- status_change_end(bl, SC_ANKLE, INVALID_TIMER);
- status_change_end(bl, SC_ELECTRICSHOCKER, INVALID_TIMER);
- }
+ //Finally added to remove the status of immobile when aimedbolt is used. [Jobbie]
+ if( skill_num == RA_AIMEDBOLT && (sc->data[SC_BITE] || sc->data[SC_ANKLE] || sc->data[SC_ELECTRICSHOCKER]) )
+ {
+ status_change_end(bl, SC_BITE, INVALID_TIMER);
+ status_change_end(bl, SC_ANKLE, INVALID_TIMER);
+ status_change_end(bl, SC_ELECTRICSHOCKER, INVALID_TIMER);
+ }
- //Finally Kyrie because it may, or not, reduce damage to 0.
- if ((sce = sc->data[SC_KYRIE]) && damage > 0) {
- sce->val2-=damage;
- if (flag&BF_WEAPON || skill_num == TF_THROWSTONE) {
- if (sce->val2>=0)
- damage=0;
- else
- damage=-sce->val2;
- }
- if ((--sce->val3)<=0 || (sce->val2<=0) || skill_num == AL_HOLYLIGHT)
- status_change_end(bl, SC_KYRIE, INVALID_TIMER);
- }
+ //Finally Kyrie because it may, or not, reduce damage to 0.
+ if((sce = sc->data[SC_KYRIE]) && damage > 0){
+ sce->val2-=damage;
+ if(flag&BF_WEAPON || skill_num == TF_THROWSTONE){
+ if(sce->val2>=0)
+ damage=0;
+ else
+ damage=-sce->val2;
+ }
+ if((--sce->val3)<=0 || (sce->val2<=0) || skill_num == AL_HOLYLIGHT)
+ status_change_end(bl, SC_KYRIE, INVALID_TIMER);
+ }
- if (sc->data[SC_MEIKYOUSISUI] && rand()%100 < 40) // custom value
- damage = 0;
+ if( sc->data[SC_MEIKYOUSISUI] && rand()%100 < 40 ) // custom value
+ damage = 0;
- if (!damage) return 0;
+ if (!damage) return 0;
- if ((sce = sc->data[SC_LIGHTNINGWALK]) && flag&BF_LONG && rnd()%100 < sce->val1) {
- int dx[8]= {0,-1,-1,-1,0,1,1,1};
- int dy[8]= {1,1,0,-1,-1,-1,0,1};
- int dir = map_calc_dir(bl, src->x, src->y);
- if (unit_movepos(bl, src->x-dx[dir], src->y-dy[dir], 1, 1)) {
- clif_slide(bl,src->x-dx[dir],src->y-dy[dir]);
- unit_setdir(bl, dir);
- }
- d->dmg_lv = ATK_DEF;
- status_change_end(bl, SC_LIGHTNINGWALK, INVALID_TIMER);
- return 0;
- }
+ if( (sce = sc->data[SC_LIGHTNINGWALK]) && flag&BF_LONG && rnd()%100 < sce->val1 ) {
+ int dx[8]={0,-1,-1,-1,0,1,1,1};
+ int dy[8]={1,1,0,-1,-1,-1,0,1};
+ int dir = map_calc_dir(bl, src->x, src->y);
+ if( unit_movepos(bl, src->x-dx[dir], src->y-dy[dir], 1, 1) ) {
+ clif_slide(bl,src->x-dx[dir],src->y-dy[dir]);
+ unit_setdir(bl, dir);
+ }
+ d->dmg_lv = ATK_DEF;
+ status_change_end(bl, SC_LIGHTNINGWALK, INVALID_TIMER);
+ return 0;
+ }
- //Probably not the most correct place, but it'll do here
- //(since battle_drain is strictly for players currently)
- if ((sce=sc->data[SC_BLOODLUST]) && flag&BF_WEAPON && damage > 0 &&
- rnd()%100 < sce->val3)
- status_heal(src, damage*sce->val4/100, 0, 3);
+ //Probably not the most correct place, but it'll do here
+ //(since battle_drain is strictly for players currently)
+ if ((sce=sc->data[SC_BLOODLUST]) && flag&BF_WEAPON && damage > 0 &&
+ rnd()%100 < sce->val3)
+ status_heal(src, damage*sce->val4/100, 0, 3);
- if (sd && (sce = sc->data[SC_FORCEOFVANGUARD]) && flag&BF_WEAPON && rnd()%100 < sce->val2)
- pc_addspiritball(sd,skill_get_time(LG_FORCEOFVANGUARD,sce->val1),sce->val3);
- if (sc->data[SC_STYLE_CHANGE] && rnd() % 100 < 50) {
+ if( sd && (sce = sc->data[SC_FORCEOFVANGUARD]) && flag&BF_WEAPON && rnd()%100 < sce->val2 )
+ pc_addspiritball(sd,skill_get_time(LG_FORCEOFVANGUARD,sce->val1),sce->val3);
+ if (sc->data[SC_STYLE_CHANGE] && rnd() % 100 < 50) {
TBL_HOM *hd = BL_CAST(BL_HOM,bl);
if (hd) hom_addspiritball(hd, 10); //add a sphere
}
- if (sc->data[SC__DEADLYINFECT] && damage > 0 && rnd()%100 < 65 + 5 * sc->data[SC__DEADLYINFECT]->val1)
- status_change_spread(bl, src); // Deadly infect attacked side
-
- if (sc && sc->data[SC__SHADOWFORM]) {
- struct block_list *s_bl = map_id2bl(sc->data[SC__SHADOWFORM]->val2);
- if (!s_bl) { // If the shadow form target is not present remove the sc.
- status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
- } else if (status_isdead(s_bl) || !battle_check_target(src,s_bl,BCT_ENEMY)) { // If the shadow form target is dead or not your enemy remove the sc in both.
- status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
- if (s_bl->type == BL_PC)
- ((TBL_PC *)s_bl)->shadowform_id = 0;
- } else {
- if ((--sc->data[SC__SHADOWFORM]->val3) < 0) { // If you have exceded max hits supported, remove the sc in both.
- status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
- if (s_bl->type == BL_PC)
- ((TBL_PC *)s_bl)->shadowform_id = 0;
- } else {
- status_damage(src, s_bl, damage, 0, clif_damage(s_bl, s_bl, gettick(), 500, 500, damage, -1, 0, 0), 0);
- return ATK_NONE;
- }
- }
- }
-
- }
+ if( sc->data[SC__DEADLYINFECT] && damage > 0 && rnd()%100 < 65 + 5 * sc->data[SC__DEADLYINFECT]->val1 )
+ status_change_spread(bl, src); // Deadly infect attacked side
+
+ if( sc && sc->data[SC__SHADOWFORM] ) {
+ struct block_list *s_bl = map_id2bl(sc->data[SC__SHADOWFORM]->val2);
+ if( !s_bl ) { // If the shadow form target is not present remove the sc.
+ status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
+ } else if( status_isdead(s_bl) || !battle_check_target(src,s_bl,BCT_ENEMY)) { // If the shadow form target is dead or not your enemy remove the sc in both.
+ status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
+ if( s_bl->type == BL_PC )
+ ((TBL_PC*)s_bl)->shadowform_id = 0;
+ } else {
+ if( (--sc->data[SC__SHADOWFORM]->val3) < 0 ) { // If you have exceded max hits supported, remove the sc in both.
+ status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
+ if( s_bl->type == BL_PC )
+ ((TBL_PC*)s_bl)->shadowform_id = 0;
+ } else {
+ status_damage(src, s_bl, damage, 0, clif_damage(s_bl, s_bl, gettick(), 500, 500, damage, -1, 0, 0), 0);
+ return ATK_NONE;
+ }
+ }
+ }
- //SC effects from caster side.
- sc = status_get_sc(src);
+ }
- if (sc && sc->count) {
- if (sc->data[SC_INVINCIBLE] && !sc->data[SC_INVINCIBLEOFF])
- damage += damage * 75 / 100;
- // [Epoque]
- if (bl->type == BL_MOB) {
- int i;
-
- if (((sce=sc->data[SC_MANU_ATK]) && (flag&BF_WEAPON)) ||
- ((sce=sc->data[SC_MANU_MATK]) && (flag&BF_MAGIC))
- )
- for (i=0; ARRAYLENGTH(mob_manuk)>i; i++)
- if (((TBL_MOB *)bl)->class_==mob_manuk[i]) {
- damage += damage*sce->val1/100;
- break;
- }
- if (((sce=sc->data[SC_SPL_ATK]) && (flag&BF_WEAPON)) ||
- ((sce=sc->data[SC_SPL_MATK]) && (flag&BF_MAGIC))
- )
- for (i=0; ARRAYLENGTH(mob_splendide)>i; i++)
- if (((TBL_MOB *)bl)->class_==mob_splendide[i]) {
- damage += damage*sce->val1/100;
- break;
- }
- }
- if (sc->data[SC_POISONINGWEAPON] && skill_num != GC_VENOMPRESSURE && (flag&BF_WEAPON) && damage > 0 && rnd()%100 < sc->data[SC_POISONINGWEAPON]->val3)
- sc_start(bl,sc->data[SC_POISONINGWEAPON]->val2,100,sc->data[SC_POISONINGWEAPON]->val1,skill_get_time2(GC_POISONINGWEAPON, 1));
- if (sc->data[SC__DEADLYINFECT] && damage > 0 && rnd()%100 < 65 + 5 * sc->data[SC__DEADLYINFECT]->val1)
- status_change_spread(src, bl);
+ //SC effects from caster side.
+ sc = status_get_sc(src);
+
+ if (sc && sc->count)
+ {
+ if( sc->data[SC_INVINCIBLE] && !sc->data[SC_INVINCIBLEOFF] )
+ damage += damage * 75 / 100;
+ // [Epoque]
+ if (bl->type == BL_MOB)
+ {
+ int i;
+
+ if ( ((sce=sc->data[SC_MANU_ATK]) && (flag&BF_WEAPON)) ||
+ ((sce=sc->data[SC_MANU_MATK]) && (flag&BF_MAGIC))
+ )
+ for (i=0;ARRAYLENGTH(mob_manuk)>i;i++)
+ if (((TBL_MOB*)bl)->class_==mob_manuk[i]) {
+ damage += damage*sce->val1/100;
+ break;
+ }
+ if ( ((sce=sc->data[SC_SPL_ATK]) && (flag&BF_WEAPON)) ||
+ ((sce=sc->data[SC_SPL_MATK]) && (flag&BF_MAGIC))
+ )
+ for (i=0;ARRAYLENGTH(mob_splendide)>i;i++)
+ if (((TBL_MOB*)bl)->class_==mob_splendide[i]) {
+ damage += damage*sce->val1/100;
+ break;
+ }
+ }
+ if( sc->data[SC_POISONINGWEAPON] && skill_num != GC_VENOMPRESSURE && (flag&BF_WEAPON) && damage > 0 && rnd()%100 < sc->data[SC_POISONINGWEAPON]->val3 )
+ sc_start(bl,sc->data[SC_POISONINGWEAPON]->val2,100,sc->data[SC_POISONINGWEAPON]->val1,skill_get_time2(GC_POISONINGWEAPON, 1));
+ if( sc->data[SC__DEADLYINFECT] && damage > 0 && rnd()%100 < 65 + 5 * sc->data[SC__DEADLYINFECT]->val1 )
+ status_change_spread(src, bl);
if (sc->data[SC_STYLE_CHANGE] && rnd() % 100 < 50) {
TBL_HOM *hd = BL_CAST(BL_HOM,bl);
if (hd) hom_addspiritball(hd, 10);
}
- }
+ }
- if (battle_config.pk_mode && sd && bl->type == BL_PC && damage && map[bl->m].flag.pvp) {
- if (flag & BF_SKILL) { //Skills get a different reduction than non-skills. [Skotlex]
- if (flag&BF_WEAPON)
- damage = damage * battle_config.pk_weapon_damage_rate/100;
- if (flag&BF_MAGIC)
- damage = damage * battle_config.pk_magic_damage_rate/100;
- if (flag&BF_MISC)
- damage = damage * battle_config.pk_misc_damage_rate/100;
- } else { //Normal attacks get reductions based on range.
- if (flag & BF_SHORT)
- damage = damage * battle_config.pk_short_damage_rate/100;
- if (flag & BF_LONG)
- damage = damage * battle_config.pk_long_damage_rate/100;
- }
- if (!damage) damage = 1;
- }
+ if (battle_config.pk_mode && sd && bl->type == BL_PC && damage && map[bl->m].flag.pvp)
+ {
+ if (flag & BF_SKILL) { //Skills get a different reduction than non-skills. [Skotlex]
+ if (flag&BF_WEAPON)
+ damage = damage * battle_config.pk_weapon_damage_rate/100;
+ if (flag&BF_MAGIC)
+ damage = damage * battle_config.pk_magic_damage_rate/100;
+ if (flag&BF_MISC)
+ damage = damage * battle_config.pk_misc_damage_rate/100;
+ } else { //Normal attacks get reductions based on range.
+ if (flag & BF_SHORT)
+ damage = damage * battle_config.pk_short_damage_rate/100;
+ if (flag & BF_LONG)
+ damage = damage * battle_config.pk_long_damage_rate/100;
+ }
+ if(!damage) damage = 1;
+ }
- if (battle_config.skill_min_damage && damage > 0 && damage < div_) {
- if ((flag&BF_WEAPON && battle_config.skill_min_damage&1)
- || (flag&BF_MAGIC && battle_config.skill_min_damage&2)
- || (flag&BF_MISC && battle_config.skill_min_damage&4)
- )
- damage = div_;
- }
+ if(battle_config.skill_min_damage && damage > 0 && damage < div_)
+ {
+ if ((flag&BF_WEAPON && battle_config.skill_min_damage&1)
+ || (flag&BF_MAGIC && battle_config.skill_min_damage&2)
+ || (flag&BF_MISC && battle_config.skill_min_damage&4)
+ )
+ damage = div_;
+ }
- if (bl->type == BL_MOB && !status_isdead(bl) && src != bl) {
- if (damage > 0)
- mobskill_event((TBL_MOB *)bl,src,gettick(),flag);
- if (skill_num)
- mobskill_event((TBL_MOB *)bl,src,gettick(),MSC_SKILLUSED|(skill_num<<16));
- }
- if (sd) {
- if (pc_ismadogear(sd) && rnd()%100 < 50) {
- short element = skill_get_ele(skill_num, skill_lv);
- if (!skill_num || element == -1) { //Take weapon's element
- struct status_data *sstatus = NULL;
- if (src->type == BL_PC && ((TBL_PC *)src)->bonus.arrow_ele)
- element = ((TBL_PC *)src)->bonus.arrow_ele;
- else if ((sstatus = status_get_status_data(src))) {
- element = sstatus->rhw.ele;
- }
- } else if (element == -2) //Use enchantment's element
- element = status_get_attack_sc_element(src,status_get_sc(src));
- else if (element == -3) //Use random element
- element = rnd()%ELE_MAX;
- if (element == ELE_FIRE || element == ELE_WATER)
- pc_overheat(sd,element == ELE_FIRE ? 1 : -1);
- }
- }
+ if( bl->type == BL_MOB && !status_isdead(bl) && src != bl) {
+ if (damage > 0 )
+ mobskill_event((TBL_MOB*)bl,src,gettick(),flag);
+ if (skill_num)
+ mobskill_event((TBL_MOB*)bl,src,gettick(),MSC_SKILLUSED|(skill_num<<16));
+ }
+ if( sd ) {
+ if( pc_ismadogear(sd) && rnd()%100 < 50 ) {
+ short element = skill_get_ele(skill_num, skill_lv);
+ if( !skill_num || element == -1 ) { //Take weapon's element
+ struct status_data *sstatus = NULL;
+ if( src->type == BL_PC && ((TBL_PC*)src)->bonus.arrow_ele )
+ element = ((TBL_PC*)src)->bonus.arrow_ele;
+ else if( (sstatus = status_get_status_data(src)) ) {
+ element = sstatus->rhw.ele;
+ }
+ }
+ else if( element == -2 ) //Use enchantment's element
+ element = status_get_attack_sc_element(src,status_get_sc(src));
+ else if( element == -3 ) //Use random element
+ element = rnd()%ELE_MAX;
+ if( element == ELE_FIRE || element == ELE_WATER )
+ pc_overheat(sd,element == ELE_FIRE ? 1 : -1);
+ }
+ }
- return damage;
+ return damage;
}
/*==========================================
@@ -1243,42 +935,45 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
*------------------------------------------*/
int battle_calc_bg_damage(struct block_list *src, struct block_list *bl, int damage, int div_, int skill_num, int skill_lv, int flag)
{
- if (!damage)
- return 0;
+ if( !damage )
+ return 0;
- if (bl->type == BL_MOB) {
- struct mob_data *md = BL_CAST(BL_MOB, bl);
- if (map[bl->m].flag.battleground && (md->class_ == MOBID_BLUE_CRYST || md->class_ == MOBID_PINK_CRYST) && flag&BF_SKILL)
- return 0; // Crystal cannot receive skill damage on battlegrounds
- }
+ if( bl->type == BL_MOB )
+ {
+ struct mob_data* md = BL_CAST(BL_MOB, bl);
+ if( map[bl->m].flag.battleground && (md->class_ == MOBID_BLUE_CRYST || md->class_ == MOBID_PINK_CRYST) && flag&BF_SKILL )
+ return 0; // Crystal cannot receive skill damage on battlegrounds
+ }
- switch (skill_num) {
- case PA_PRESSURE:
- case HW_GRAVITATION:
- case NJ_ZENYNAGE:
- case KO_MUCHANAGE:
- break;
- default:
- if (flag&BF_SKILL) {
- //Skills get a different reduction than non-skills. [Skotlex]
- if (flag&BF_WEAPON)
- damage = damage * battle_config.bg_weapon_damage_rate/100;
- if (flag&BF_MAGIC)
- damage = damage * battle_config.bg_magic_damage_rate/100;
- if (flag&BF_MISC)
- damage = damage * battle_config.bg_misc_damage_rate/100;
- } else {
- //Normal attacks get reductions based on range.
- if (flag&BF_SHORT)
- damage = damage * battle_config.bg_short_damage_rate/100;
- if (flag&BF_LONG)
- damage = damage * battle_config.bg_long_damage_rate/100;
- }
+ switch( skill_num )
+ {
+ case PA_PRESSURE:
+ case HW_GRAVITATION:
+ case NJ_ZENYNAGE:
+ case KO_MUCHANAGE:
+ break;
+ default:
+ if( flag&BF_SKILL )
+ { //Skills get a different reduction than non-skills. [Skotlex]
+ if( flag&BF_WEAPON )
+ damage = damage * battle_config.bg_weapon_damage_rate/100;
+ if( flag&BF_MAGIC )
+ damage = damage * battle_config.bg_magic_damage_rate/100;
+ if( flag&BF_MISC )
+ damage = damage * battle_config.bg_misc_damage_rate/100;
+ }
+ else
+ { //Normal attacks get reductions based on range.
+ if( flag&BF_SHORT )
+ damage = damage * battle_config.bg_short_damage_rate/100;
+ if( flag&BF_LONG )
+ damage = damage * battle_config.bg_long_damage_rate/100;
+ }
- if (!damage) damage = 1;
- }
+ if( !damage ) damage = 1;
+ }
- return damage;
+ return damage;
}
/*==========================================
@@ -1286,65 +981,65 @@ int battle_calc_bg_damage(struct block_list *src, struct block_list *bl, int dam
*------------------------------------------*/
int battle_calc_gvg_damage(struct block_list *src,struct block_list *bl,int damage,int div_,int skill_num,int skill_lv,int flag)
{
- struct mob_data *md = BL_CAST(BL_MOB, bl);
- int class_ = status_get_class(bl);
+ struct mob_data* md = BL_CAST(BL_MOB, bl);
+ int class_ = status_get_class(bl);
- if (!damage) //No reductions to make.
- return 0;
+ if (!damage) //No reductions to make.
+ return 0;
- if (md && md->guardian_data) {
- if (class_ == MOBID_EMPERIUM && flag&BF_SKILL) {
- //Skill immunity.
- switch (skill_num) {
+ if(md && md->guardian_data) {
+ if(class_ == MOBID_EMPERIUM && flag&BF_SKILL) {
+ //Skill immunity.
+ switch (skill_num) {
#ifndef RENEWAL
- case MO_TRIPLEATTACK:
+ case MO_TRIPLEATTACK:
#endif
- case HW_GRAVITATION:
- break;
- default:
- return 0;
- }
- }
- if (src->type != BL_MOB) {
- struct guild *g = guild_search(status_get_guild_id(src));
+ case HW_GRAVITATION:
+ break;
+ default:
+ return 0;
+ }
+ }
+ if(src->type != BL_MOB) {
+ struct guild *g = guild_search(status_get_guild_id(src));
- if (class_ == MOBID_EMPERIUM && (!g || guild_checkskill(g,GD_APPROVAL) <= 0))
- return 0;
+ if (class_ == MOBID_EMPERIUM && (!g || guild_checkskill(g,GD_APPROVAL) <= 0 ))
+ return 0;
- if (g && battle_config.guild_max_castles && guild_checkcastles(g)>=battle_config.guild_max_castles)
- return 0; // [MouseJstr]
- }
- }
+ if (g && battle_config.guild_max_castles && guild_checkcastles(g)>=battle_config.guild_max_castles)
+ return 0; // [MouseJstr]
+ }
+ }
- switch (skill_num) {
- //Skills with no damage reduction.
- case PA_PRESSURE:
- case HW_GRAVITATION:
- case NJ_ZENYNAGE:
- case KO_MUCHANAGE:
- break;
- default:
- /* Uncomment if you want god-mode Emperiums at 100 defense. [Kisuka]
- if (md && md->guardian_data) {
- damage -= damage * (md->guardian_data->castle->defense/100) * battle_config.castle_defense_rate/100;
- }
- */
- if (flag & BF_SKILL) { //Skills get a different reduction than non-skills. [Skotlex]
- if (flag&BF_WEAPON)
- damage = damage * battle_config.gvg_weapon_damage_rate/100;
- if (flag&BF_MAGIC)
- damage = damage * battle_config.gvg_magic_damage_rate/100;
- if (flag&BF_MISC)
- damage = damage * battle_config.gvg_misc_damage_rate/100;
- } else { //Normal attacks get reductions based on range.
- if (flag & BF_SHORT)
- damage = damage * battle_config.gvg_short_damage_rate/100;
- if (flag & BF_LONG)
- damage = damage * battle_config.gvg_long_damage_rate/100;
- }
- if (!damage) damage = 1;
- }
- return damage;
+ switch (skill_num) {
+ //Skills with no damage reduction.
+ case PA_PRESSURE:
+ case HW_GRAVITATION:
+ case NJ_ZENYNAGE:
+ case KO_MUCHANAGE:
+ break;
+ default:
+ /* Uncomment if you want god-mode Emperiums at 100 defense. [Kisuka]
+ if (md && md->guardian_data) {
+ damage -= damage * (md->guardian_data->castle->defense/100) * battle_config.castle_defense_rate/100;
+ }
+ */
+ if (flag & BF_SKILL) { //Skills get a different reduction than non-skills. [Skotlex]
+ if (flag&BF_WEAPON)
+ damage = damage * battle_config.gvg_weapon_damage_rate/100;
+ if (flag&BF_MAGIC)
+ damage = damage * battle_config.gvg_magic_damage_rate/100;
+ if (flag&BF_MISC)
+ damage = damage * battle_config.gvg_misc_damage_rate/100;
+ } else { //Normal attacks get reductions based on range.
+ if (flag & BF_SHORT)
+ damage = damage * battle_config.gvg_short_damage_rate/100;
+ if (flag & BF_LONG)
+ damage = damage * battle_config.gvg_long_damage_rate/100;
+ }
+ if(!damage) damage = 1;
+ }
+ return damage;
}
/*==========================================
@@ -1352,18 +1047,18 @@ int battle_calc_gvg_damage(struct block_list *src,struct block_list *bl,int dama
*------------------------------------------*/
static int battle_calc_drain(int damage, int rate, int per)
{
- int diff = 0;
-
- if (per && rnd()%1000 < rate) {
- diff = (damage * per) / 100;
- if (diff == 0) {
- if (per > 0)
- diff = 1;
- else
- diff = -1;
- }
- }
- return diff;
+ int diff = 0;
+
+ if (per && rnd()%1000 < rate) {
+ diff = (damage * per) / 100;
+ if (diff == 0) {
+ if (per > 0)
+ diff = 1;
+ else
+ diff = -1;
+ }
+ }
+ return diff;
}
/*==========================================
@@ -1371,105 +1066,106 @@ static int battle_calc_drain(int damage, int rate, int per)
*------------------------------------------*/
int battle_addmastery(struct map_session_data *sd,struct block_list *target,int dmg,int type)
{
- int damage,skill;
- struct status_data *status = status_get_status_data(target);
- int weapon;
- damage = dmg;
-
- nullpo_ret(sd);
-
- if ((skill = pc_checkskill(sd,AL_DEMONBANE)) > 0 &&
- target->type == BL_MOB && //This bonus doesnt work against players.
- (battle_check_undead(status->race,status->def_ele) || status->race==RC_DEMON))
- damage += (skill*(int)(3+(sd->status.base_level+1)*0.05)); // submitted by orn
- //damage += (skill * 3);
- if ((skill = pc_checkskill(sd, RA_RANGERMAIN)) > 0 && (status->race == RC_BRUTE || status->race == RC_PLANT || status->race == RC_FISH))
- damage += (skill * 5);
- if ((skill = pc_checkskill(sd,NC_RESEARCHFE)) > 0 && (status->def_ele == ELE_FIRE || status->def_ele == ELE_EARTH))
- damage += (skill * 10);
- if (pc_ismadogear(sd))
- damage += 20 + 20 * pc_checkskill(sd, NC_MADOLICENCE);
-
- if ((skill = pc_checkskill(sd,HT_BEASTBANE)) > 0 && (status->race==RC_BRUTE || status->race==RC_INSECT)) {
- damage += (skill * 4);
- if (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_HUNTER)
- damage += sd->status.str;
- }
+ int damage,skill;
+ struct status_data *status = status_get_status_data(target);
+ int weapon;
+ damage = dmg;
+
+ nullpo_ret(sd);
+
+ if((skill = pc_checkskill(sd,AL_DEMONBANE)) > 0 &&
+ target->type == BL_MOB && //This bonus doesnt work against players.
+ (battle_check_undead(status->race,status->def_ele) || status->race==RC_DEMON) )
+ damage += (skill*(int)(3+(sd->status.base_level+1)*0.05)); // submitted by orn
+ //damage += (skill * 3);
+ if( (skill = pc_checkskill(sd, RA_RANGERMAIN)) > 0 && (status->race == RC_BRUTE || status->race == RC_PLANT || status->race == RC_FISH) )
+ damage += (skill * 5);
+ if( (skill = pc_checkskill(sd,NC_RESEARCHFE)) > 0 && (status->def_ele == ELE_FIRE || status->def_ele == ELE_EARTH) )
+ damage += (skill * 10);
+ if( pc_ismadogear(sd) )
+ damage += 20 + 20 * pc_checkskill(sd, NC_MADOLICENCE);
+
+ if((skill = pc_checkskill(sd,HT_BEASTBANE)) > 0 && (status->race==RC_BRUTE || status->race==RC_INSECT) ) {
+ damage += (skill * 4);
+ if (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_HUNTER)
+ damage += sd->status.str;
+ }
- if (type == 0)
- weapon = sd->weapontype1;
- else
- weapon = sd->weapontype2;
- switch (weapon) {
- case W_1HSWORD:
-#ifdef RENEWAL
- if ((skill = pc_checkskill(sd,AM_AXEMASTERY)) > 0)
- damage += (skill * 3);
-#endif
- case W_DAGGER:
- if ((skill = pc_checkskill(sd,SM_SWORD)) > 0)
- damage += (skill * 4);
- if ((skill = pc_checkskill(sd,GN_TRAINING_SWORD)) > 0)
- damage += skill * 10;
- break;
- case W_2HSWORD:
-#ifdef RENEWAL
- if ((skill = pc_checkskill(sd,AM_AXEMASTERY)) > 0)
- damage += (skill * 3);
-#endif
- if ((skill = pc_checkskill(sd,SM_TWOHAND)) > 0)
- damage += (skill * 4);
- break;
- case W_1HSPEAR:
- case W_2HSPEAR:
- if ((skill = pc_checkskill(sd,KN_SPEARMASTERY)) > 0) {
- if (!pc_isriding(sd))
- damage += (skill * 4);
- else
- damage += (skill * 5);
- }
- break;
- case W_1HAXE:
- case W_2HAXE:
- if ((skill = pc_checkskill(sd,AM_AXEMASTERY)) > 0)
- damage += (skill * 3);
- if ((skill = pc_checkskill(sd,NC_TRAININGAXE)) > 0)
- damage += (skill * 5);
- break;
- case W_MACE:
- case W_2HMACE:
- if ((skill = pc_checkskill(sd,PR_MACEMASTERY)) > 0)
- damage += (skill * 3);
- if ((skill = pc_checkskill(sd,NC_TRAININGAXE)) > 0)
- damage += (skill * 5);
- break;
- case W_FIST:
- if ((skill = pc_checkskill(sd,TK_RUN)) > 0)
- damage += (skill * 10);
- // No break, fallthrough to Knuckles
- case W_KNUCKLE:
- if ((skill = pc_checkskill(sd,MO_IRONHAND)) > 0)
- damage += (skill * 3);
- break;
- case W_MUSICAL:
- if ((skill = pc_checkskill(sd,BA_MUSICALLESSON)) > 0)
- damage += (skill * 3);
- break;
- case W_WHIP:
- if ((skill = pc_checkskill(sd,DC_DANCINGLESSON)) > 0)
- damage += (skill * 3);
- break;
- case W_BOOK:
- if ((skill = pc_checkskill(sd,SA_ADVANCEDBOOK)) > 0)
- damage += (skill * 3);
- break;
- case W_KATAR:
- if ((skill = pc_checkskill(sd,AS_KATAR)) > 0)
- damage += (skill * 3);
- break;
- }
+ if(type == 0)
+ weapon = sd->weapontype1;
+ else
+ weapon = sd->weapontype2;
+ switch(weapon)
+ {
+ case W_1HSWORD:
+ #ifdef RENEWAL
+ if((skill = pc_checkskill(sd,AM_AXEMASTERY)) > 0)
+ damage += (skill * 3);
+ #endif
+ case W_DAGGER:
+ if((skill = pc_checkskill(sd,SM_SWORD)) > 0)
+ damage += (skill * 4);
+ if((skill = pc_checkskill(sd,GN_TRAINING_SWORD)) > 0)
+ damage += skill * 10;
+ break;
+ case W_2HSWORD:
+ #ifdef RENEWAL
+ if((skill = pc_checkskill(sd,AM_AXEMASTERY)) > 0)
+ damage += (skill * 3);
+ #endif
+ if((skill = pc_checkskill(sd,SM_TWOHAND)) > 0)
+ damage += (skill * 4);
+ break;
+ case W_1HSPEAR:
+ case W_2HSPEAR:
+ if((skill = pc_checkskill(sd,KN_SPEARMASTERY)) > 0) {
+ if(!pc_isriding(sd))
+ damage += (skill * 4);
+ else
+ damage += (skill * 5);
+ }
+ break;
+ case W_1HAXE:
+ case W_2HAXE:
+ if((skill = pc_checkskill(sd,AM_AXEMASTERY)) > 0)
+ damage += (skill * 3);
+ if((skill = pc_checkskill(sd,NC_TRAININGAXE)) > 0)
+ damage += (skill * 5);
+ break;
+ case W_MACE:
+ case W_2HMACE:
+ if((skill = pc_checkskill(sd,PR_MACEMASTERY)) > 0)
+ damage += (skill * 3);
+ if((skill = pc_checkskill(sd,NC_TRAININGAXE)) > 0)
+ damage += (skill * 5);
+ break;
+ case W_FIST:
+ if((skill = pc_checkskill(sd,TK_RUN)) > 0)
+ damage += (skill * 10);
+ // No break, fallthrough to Knuckles
+ case W_KNUCKLE:
+ if((skill = pc_checkskill(sd,MO_IRONHAND)) > 0)
+ damage += (skill * 3);
+ break;
+ case W_MUSICAL:
+ if((skill = pc_checkskill(sd,BA_MUSICALLESSON)) > 0)
+ damage += (skill * 3);
+ break;
+ case W_WHIP:
+ if((skill = pc_checkskill(sd,DC_DANCINGLESSON)) > 0)
+ damage += (skill * 3);
+ break;
+ case W_BOOK:
+ if((skill = pc_checkskill(sd,SA_ADVANCEDBOOK)) > 0)
+ damage += (skill * 3);
+ break;
+ case W_KATAR:
+ if((skill = pc_checkskill(sd,AS_KATAR)) > 0)
+ damage += (skill * 3);
+ break;
+ }
- return damage;
+ return damage;
}
/*==========================================
* Calculates the standard damage of a normal attack assuming it hits,
@@ -1485,138 +1181,139 @@ int battle_addmastery(struct map_session_data *sd,struct block_list *target,int
*/
static int battle_calc_base_damage(struct status_data *status, struct weapon_atk *wa, struct status_change *sc, unsigned short t_size, struct map_session_data *sd, int flag)
{
- unsigned short atkmin=0, atkmax=0;
- short type = 0;
- int damage = 0;
-
- if (!sd) {
- //Mobs/Pets
- if (flag&4) {
- atkmin = status->matk_min;
- atkmax = status->matk_max;
- } else {
- atkmin = wa->atk;
- atkmax = wa->atk2;
- }
- if (atkmin > atkmax)
- atkmin = atkmax;
- } else { //PCs
- atkmax = wa->atk;
- type = (wa == &status->lhw)?EQI_HAND_L:EQI_HAND_R;
-
- if (!(flag&1) || (flag&2)) {
- //Normal attacks
- atkmin = status->dex;
-
- if (sd->equip_index[type] >= 0 && sd->inventory_data[sd->equip_index[type]])
- atkmin = atkmin*(80 + sd->inventory_data[sd->equip_index[type]]->wlv*20)/100;
-
- if (atkmin > atkmax)
- atkmin = atkmax;
-
- if (flag&2 && !(flag&16)) {
- //Bows
- atkmin = atkmin*atkmax/100;
- if (atkmin > atkmax)
- atkmax = atkmin;
- }
- }
- }
+ unsigned short atkmin=0, atkmax=0;
+ short type = 0;
+ int damage = 0;
+
+ if (!sd)
+ { //Mobs/Pets
+ if(flag&4)
+ {
+ atkmin = status->matk_min;
+ atkmax = status->matk_max;
+ } else {
+ atkmin = wa->atk;
+ atkmax = wa->atk2;
+ }
+ if (atkmin > atkmax)
+ atkmin = atkmax;
+ } else { //PCs
+ atkmax = wa->atk;
+ type = (wa == &status->lhw)?EQI_HAND_L:EQI_HAND_R;
+
+ if (!(flag&1) || (flag&2))
+ { //Normal attacks
+ atkmin = status->dex;
+
+ if (sd->equip_index[type] >= 0 && sd->inventory_data[sd->equip_index[type]])
+ atkmin = atkmin*(80 + sd->inventory_data[sd->equip_index[type]]->wlv*20)/100;
+
+ if (atkmin > atkmax)
+ atkmin = atkmax;
+
+ if(flag&2 && !(flag&16))
+ { //Bows
+ atkmin = atkmin*atkmax/100;
+ if (atkmin > atkmax)
+ atkmax = atkmin;
+ }
+ }
+ }
- if (sc && sc->data[SC_MAXIMIZEPOWER])
- atkmin = atkmax;
-
- //Weapon Damage calculation
- if (!(flag&1))
- damage = (atkmax>atkmin? rnd()%(atkmax-atkmin):0)+atkmin;
- else
- damage = atkmax;
-
- if (sd) {
- //rodatazone says the range is 0~arrow_atk-1 for non crit
- if (flag&2 && sd->bonus.arrow_atk)
- damage += ((flag&1) ? sd->bonus.arrow_atk : rnd()%sd->bonus.arrow_atk);
-
- //SizeFix only for players
- if (!(sd->special_state.no_sizefix || (flag&8)))
- damage = damage*(type==EQI_HAND_L?
- sd->left_weapon.atkmods[t_size]:
- sd->right_weapon.atkmods[t_size])/100;
- }
+ if (sc && sc->data[SC_MAXIMIZEPOWER])
+ atkmin = atkmax;
+
+ //Weapon Damage calculation
+ if (!(flag&1))
+ damage = (atkmax>atkmin? rnd()%(atkmax-atkmin):0)+atkmin;
+ else
+ damage = atkmax;
+
+ if (sd)
+ {
+ //rodatazone says the range is 0~arrow_atk-1 for non crit
+ if (flag&2 && sd->bonus.arrow_atk)
+ damage += ( (flag&1) ? sd->bonus.arrow_atk : rnd()%sd->bonus.arrow_atk );
+
+ //SizeFix only for players
+ if (!(sd->special_state.no_sizefix || (flag&8)))
+ damage = damage*(type==EQI_HAND_L?
+ sd->left_weapon.atkmods[t_size]:
+ sd->right_weapon.atkmods[t_size])/100;
+ }
- //Finally, add baseatk
- if (flag&4)
- damage += status->matk_min;
- else
- damage += status->batk;
-
- //rodatazone says that Overrefine bonuses are part of baseatk
- //Here we also apply the weapon_atk_rate bonus so it is correctly applied on left/right hands.
- if (sd) {
- if (type == EQI_HAND_L) {
- if (sd->left_weapon.overrefine)
- damage += rnd()%sd->left_weapon.overrefine+1;
- if (sd->weapon_atk_rate[sd->weapontype2])
- damage += damage*sd->weapon_atk_rate[sd->weapontype2]/100;;
- } else { //Right hand
- if (sd->right_weapon.overrefine)
- damage += rnd()%sd->right_weapon.overrefine+1;
- if (sd->weapon_atk_rate[sd->weapontype1])
- damage += damage*sd->weapon_atk_rate[sd->weapontype1]/100;;
- }
- }
- return damage;
+ //Finally, add baseatk
+ if(flag&4)
+ damage += status->matk_min;
+ else
+ damage += status->batk;
+
+ //rodatazone says that Overrefine bonuses are part of baseatk
+ //Here we also apply the weapon_atk_rate bonus so it is correctly applied on left/right hands.
+ if(sd) {
+ if (type == EQI_HAND_L) {
+ if(sd->left_weapon.overrefine)
+ damage += rnd()%sd->left_weapon.overrefine+1;
+ if (sd->weapon_atk_rate[sd->weapontype2])
+ damage += damage*sd->weapon_atk_rate[sd->weapontype2]/100;;
+ } else { //Right hand
+ if(sd->right_weapon.overrefine)
+ damage += rnd()%sd->right_weapon.overrefine+1;
+ if (sd->weapon_atk_rate[sd->weapontype1])
+ damage += damage*sd->weapon_atk_rate[sd->weapontype1]/100;;
+ }
+ }
+ return damage;
}
/*==========================================
* Consumes ammo for the given skill.
*------------------------------------------*/
-void battle_consume_ammo(TBL_PC *sd, int skill, int lv)
+void battle_consume_ammo(TBL_PC*sd, int skill, int lv)
{
- int qty=1;
- if (!battle_config.arrow_decrement)
- return;
+ int qty=1;
+ if (!battle_config.arrow_decrement)
+ return;
- if (skill) {
- qty = skill_get_ammo_qty(skill, lv);
- if (!qty) qty = 1;
- }
+ if (skill) {
+ qty = skill_get_ammo_qty(skill, lv);
+ if (!qty) qty = 1;
+ }
- if (sd->equip_index[EQI_AMMO]>=0) //Qty check should have been done in skill_check_condition
- pc_delitem(sd,sd->equip_index[EQI_AMMO],qty,0,1,LOG_TYPE_CONSUME);
+ if(sd->equip_index[EQI_AMMO]>=0) //Qty check should have been done in skill_check_condition
+ pc_delitem(sd,sd->equip_index[EQI_AMMO],qty,0,1,LOG_TYPE_CONSUME);
- sd->state.arrow_atk = 0;
+ sd->state.arrow_atk = 0;
}
static int battle_range_type(
- struct block_list *src, struct block_list *target,
- int skill_num, int skill_lv)
-{
- //Skill Range Criteria
- if (battle_config.skillrange_by_distance &&
- (src->type&battle_config.skillrange_by_distance)
- ) { //based on distance between src/target [Skotlex]
- if (check_distance_bl(src, target, 5))
- return BF_SHORT;
- return BF_LONG;
- }
- //based on used skill's range
- if (skill_get_range2(src, skill_num, skill_lv) < 5)
- return BF_SHORT;
- return BF_LONG;
+ struct block_list *src, struct block_list *target,
+ int skill_num, int skill_lv)
+{ //Skill Range Criteria
+ if (battle_config.skillrange_by_distance &&
+ (src->type&battle_config.skillrange_by_distance)
+ ) { //based on distance between src/target [Skotlex]
+ if (check_distance_bl(src, target, 5))
+ return BF_SHORT;
+ return BF_LONG;
+ }
+ //based on used skill's range
+ if (skill_get_range2(src, skill_num, skill_lv) < 5)
+ return BF_SHORT;
+ return BF_LONG;
}
static int battle_blewcount_bonus(struct map_session_data *sd, int skill_num)
{
- int i;
- if (!sd->skillblown[0].id)
- return 0;
- //Apply the bonus blewcount. [Skotlex]
- for (i = 0; i < ARRAYLENGTH(sd->skillblown) && sd->skillblown[i].id; i++) {
- if (sd->skillblown[i].id == skill_num)
- return sd->skillblown[i].val;
- }
- return 0;
+ int i;
+ if (!sd->skillblown[0].id)
+ return 0;
+ //Apply the bonus blewcount. [Skotlex]
+ for (i = 0; i < ARRAYLENGTH(sd->skillblown) && sd->skillblown[i].id; i++) {
+ if (sd->skillblown[i].id == skill_num)
+ return sd->skillblown[i].val;
+ }
+ return 0;
}
struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list *target,int skill_num,int skill_lv,int mflag);
@@ -1627,3411 +1324,3741 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
/*==========================================
* battle_calc_weapon_attack (by Skotlex)
*------------------------------------------*/
-static struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list *target,int skill_num,int skill_lv,int wflag) {
- unsigned int skillratio = 100; //Skill dmg modifiers.
- short skill=0;
- short s_ele, s_ele_, t_class;
- int i, nk;
- bool n_ele = false; // non-elemental
-
- struct map_session_data *sd, *tsd;
- struct Damage wd;
- struct status_change *sc = status_get_sc(src);
- struct status_change *tsc = status_get_sc(target);
- struct status_data *sstatus = status_get_status_data(src);
- struct status_data *tstatus = status_get_status_data(target);
- struct {
- unsigned hit : 1; //the attack Hit? (not a miss)
- unsigned cri : 1; //Critical hit
- unsigned idef : 1; //Ignore defense
- unsigned idef2 : 1; //Ignore defense (left weapon)
- unsigned pdef : 2; //Pierces defense (Investigate/Ice Pick)
- unsigned pdef2 : 2; //1: Use def+def2/100, 2: Use def+def2/50
- unsigned infdef : 1; //Infinite defense (plants)
- unsigned arrow : 1; //Attack is arrow-based
- unsigned rh : 1; //Attack considers right hand (wd.damage)
- unsigned lh : 1; //Attack considers left hand (wd.damage2)
- unsigned weapon : 1; //It's a weapon attack (consider VVS, and all that)
- } flag;
-
- memset(&wd,0,sizeof(wd));
- memset(&flag,0,sizeof(flag));
-
- if (src==NULL || target==NULL) {
- nullpo_info(NLP_MARK);
- return wd;
- }
- //Initial flag
- flag.rh=1;
- flag.weapon=1;
- flag.infdef=(tstatus->mode&MD_PLANT && skill_num != RA_CLUSTERBOMB
+static struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list *target,int skill_num,int skill_lv,int wflag)
+{
+ unsigned int skillratio = 100; //Skill dmg modifiers.
+ short skill=0;
+ short s_ele, s_ele_, t_class;
+ int i, nk;
+ bool n_ele = false; // non-elemental
+
+ struct map_session_data *sd, *tsd;
+ struct Damage wd;
+ struct status_change *sc = status_get_sc(src);
+ struct status_change *tsc = status_get_sc(target);
+ struct status_data *sstatus = status_get_status_data(src);
+ struct status_data *tstatus = status_get_status_data(target);
+ struct {
+ unsigned hit : 1; //the attack Hit? (not a miss)
+ unsigned cri : 1; //Critical hit
+ unsigned idef : 1; //Ignore defense
+ unsigned idef2 : 1; //Ignore defense (left weapon)
+ unsigned pdef : 2; //Pierces defense (Investigate/Ice Pick)
+ unsigned pdef2 : 2; //1: Use def+def2/100, 2: Use def+def2/50
+ unsigned infdef : 1; //Infinite defense (plants)
+ unsigned arrow : 1; //Attack is arrow-based
+ unsigned rh : 1; //Attack considers right hand (wd.damage)
+ unsigned lh : 1; //Attack considers left hand (wd.damage2)
+ unsigned weapon : 1; //It's a weapon attack (consider VVS, and all that)
+ } flag;
+
+ memset(&wd,0,sizeof(wd));
+ memset(&flag,0,sizeof(flag));
+
+ if(src==NULL || target==NULL)
+ {
+ nullpo_info(NLP_MARK);
+ return wd;
+ }
+ //Initial flag
+ flag.rh=1;
+ flag.weapon=1;
+ flag.infdef=(tstatus->mode&MD_PLANT && skill_num != RA_CLUSTERBOMB
#ifdef RENEWAL
- && skill_num != HT_FREEZINGTRAP
+ && skill_num != HT_FREEZINGTRAP
#endif
- ?1:0);
- if (target->type == BL_SKILL) {
- TBL_SKILL *su = (TBL_SKILL *)target;
- if (su->group && (su->group->skill_id == WM_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD))
- flag.infdef = 1;
- }
+ ?1:0);
+ if( target->type == BL_SKILL){
+ TBL_SKILL *su = (TBL_SKILL*)target;
+ if( su->group && (su->group->skill_id == WM_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD) )
+ flag.infdef = 1;
+ }
+
+ //Initial Values
+ wd.type=0; //Normal attack
+ wd.div_=skill_num?skill_get_num(skill_num,skill_lv):1;
+ wd.amotion=(skill_num && skill_get_inf(skill_num)&INF_GROUND_SKILL)?0:sstatus->amotion; //Amotion should be 0 for ground skills.
+ if(skill_num == KN_AUTOCOUNTER)
+ wd.amotion >>= 1;
+ wd.dmotion=tstatus->dmotion;
+ wd.blewcount=skill_get_blewcount(skill_num,skill_lv);
+ wd.flag = BF_WEAPON; //Initial Flag
+ wd.flag |= (skill_num||wflag)?BF_SKILL:BF_NORMAL; // Baphomet card's splash damage is counted as a skill. [Inkfish]
+ wd.dmg_lv=ATK_DEF; //This assumption simplifies the assignation later
+ nk = skill_get_nk(skill_num);
+ if( !skill_num && wflag ) //If flag, this is splash damage from Baphomet Card and it always hits.
+ nk |= NK_NO_CARDFIX_ATK|NK_IGNORE_FLEE;
+ flag.hit = nk&NK_IGNORE_FLEE?1:0;
+ flag.idef = flag.idef2 = nk&NK_IGNORE_DEF?1:0;
+
+ if (sc && !sc->count)
+ sc = NULL; //Skip checking as there are no status changes active.
+ if (tsc && !tsc->count)
+ tsc = NULL; //Skip checking as there are no status changes active.
+
+ sd = BL_CAST(BL_PC, src);
+ tsd = BL_CAST(BL_PC, target);
- //Initial Values
- wd.type=0; //Normal attack
- wd.div_=skill_num?skill_get_num(skill_num,skill_lv):1;
- wd.amotion=(skill_num && skill_get_inf(skill_num)&INF_GROUND_SKILL)?0:sstatus->amotion; //Amotion should be 0 for ground skills.
- if (skill_num == KN_AUTOCOUNTER)
- wd.amotion >>= 1;
- wd.dmotion=tstatus->dmotion;
- wd.blewcount=skill_get_blewcount(skill_num,skill_lv);
- wd.flag = BF_WEAPON; //Initial Flag
- wd.flag |= (skill_num||wflag)?BF_SKILL:BF_NORMAL; // Baphomet card's splash damage is counted as a skill. [Inkfish]
- wd.dmg_lv=ATK_DEF; //This assumption simplifies the assignation later
- nk = skill_get_nk(skill_num);
- if (!skill_num && wflag) //If flag, this is splash damage from Baphomet Card and it always hits.
- nk |= NK_NO_CARDFIX_ATK|NK_IGNORE_FLEE;
- flag.hit = nk &NK_IGNORE_FLEE?1:0;
- flag.idef = flag.idef2 = nk &NK_IGNORE_DEF?1:0;
-
- if (sc && !sc->count)
- sc = NULL; //Skip checking as there are no status changes active.
- if (tsc && !tsc->count)
- tsc = NULL; //Skip checking as there are no status changes active.
-
- sd = BL_CAST(BL_PC, src);
- tsd = BL_CAST(BL_PC, target);
-
- if (sd)
- wd.blewcount += battle_blewcount_bonus(sd, skill_num);
-
- //Set miscellaneous data that needs be filled regardless of hit/miss
- if (
- (sd && sd->state.arrow_atk) ||
- (!sd && ((skill_num && skill_get_ammotype(skill_num)) || sstatus->rhw.range>3))
- )
- flag.arrow = 1;
-
- if (skill_num) {
- wd.flag |= battle_range_type(src, target, skill_num, skill_lv);
- switch (skill_num) {
- case MO_FINGEROFFENSIVE:
- if (sd) {
- if (battle_config.finger_offensive_type)
- wd.div_ = 1;
- else
- wd.div_ = sd->spiritball_old;
- }
- break;
- case HT_PHANTASMIC:
- //Since these do not consume ammo, they need to be explicitly set as arrow attacks.
- flag.arrow = 1;
- break;
+ if(sd)
+ wd.blewcount += battle_blewcount_bonus(sd, skill_num);
+
+ //Set miscellaneous data that needs be filled regardless of hit/miss
+ if(
+ (sd && sd->state.arrow_atk) ||
+ (!sd && ((skill_num && skill_get_ammotype(skill_num)) || sstatus->rhw.range>3))
+ )
+ flag.arrow = 1;
+
+ if(skill_num){
+ wd.flag |= battle_range_type(src, target, skill_num, skill_lv);
+ switch(skill_num)
+ {
+ case MO_FINGEROFFENSIVE:
+ if(sd) {
+ if (battle_config.finger_offensive_type)
+ wd.div_ = 1;
+ else
+ wd.div_ = sd->spiritball_old;
+ }
+ break;
+ case HT_PHANTASMIC:
+ //Since these do not consume ammo, they need to be explicitly set as arrow attacks.
+ flag.arrow = 1;
+ break;
#ifndef RENEWAL
- case PA_SHIELDCHAIN:
- case CR_SHIELDBOOMERANG:
+ case PA_SHIELDCHAIN:
+ case CR_SHIELDBOOMERANG:
#endif
- case LG_SHIELDPRESS:
- case LG_EARTHDRIVE:
- flag.weapon = 0;
- break;
-
- case KN_PIERCE:
- case ML_PIERCE:
- wd.div_= (wd.div_>0?tstatus->size+1:-(tstatus->size+1));
- break;
-
- case TF_DOUBLE: //For NPC used skill.
- case GS_CHAINACTION:
- wd.type = 0x08;
- break;
-
- case GS_GROUNDDRIFT:
- case KN_SPEARSTAB:
- case KN_BOWLINGBASH:
- case MS_BOWLINGBASH:
- case MO_BALKYOUNG:
- case TK_TURNKICK:
- wd.blewcount=0;
- break;
-
- case KN_AUTOCOUNTER:
- wd.flag=(wd.flag&~BF_SKILLMASK)|BF_NORMAL;
- break;
-
- case NPC_CRITICALSLASH:
- case LG_PINPOINTATTACK:
- flag.cri = 1; //Always critical skill.
- break;
-
- case LK_SPIRALPIERCE:
- if (!sd) wd.flag=(wd.flag&~(BF_RANGEMASK|BF_WEAPONMASK))|BF_LONG|BF_MISC;
- break;
- }
- } else //Range for normal attacks.
- wd.flag |= flag.arrow?BF_LONG:BF_SHORT;
-
- if ((!skill_num || skill_num == PA_SACRIFICE) && tstatus->flee2 && rnd()%1000 < tstatus->flee2) {
- //Check for Lucky Dodge
- wd.type=0x0b;
- wd.dmg_lv=ATK_LUCKY;
- if (wd.div_ < 0) wd.div_*=-1;
- return wd;
- }
+ case LG_SHIELDPRESS:
+ case LG_EARTHDRIVE:
+ flag.weapon = 0;
+ break;
+
+ case KN_PIERCE:
+ case ML_PIERCE:
+ wd.div_= (wd.div_>0?tstatus->size+1:-(tstatus->size+1));
+ break;
+
+ case TF_DOUBLE: //For NPC used skill.
+ case GS_CHAINACTION:
+ wd.type = 0x08;
+ break;
+
+ case GS_GROUNDDRIFT:
+ case KN_SPEARSTAB:
+ case KN_BOWLINGBASH:
+ case MS_BOWLINGBASH:
+ case MO_BALKYOUNG:
+ case TK_TURNKICK:
+ wd.blewcount=0;
+ break;
+
+ case KN_AUTOCOUNTER:
+ wd.flag=(wd.flag&~BF_SKILLMASK)|BF_NORMAL;
+ break;
+
+ case NPC_CRITICALSLASH:
+ case LG_PINPOINTATTACK:
+ flag.cri = 1; //Always critical skill.
+ break;
+
+ case LK_SPIRALPIERCE:
+ if (!sd) wd.flag=(wd.flag&~(BF_RANGEMASK|BF_WEAPONMASK))|BF_LONG|BF_MISC;
+ break;
+ }
+ } else //Range for normal attacks.
+ wd.flag |= flag.arrow?BF_LONG:BF_SHORT;
+
+ if ( (!skill_num || skill_num == PA_SACRIFICE) && tstatus->flee2 && rnd()%1000 < tstatus->flee2 )
+ { //Check for Lucky Dodge
+ wd.type=0x0b;
+ wd.dmg_lv=ATK_LUCKY;
+ if (wd.div_ < 0) wd.div_*=-1;
+ return wd;
+ }
- t_class = status_get_class(target);
- s_ele = s_ele_ = skill_get_ele(skill_num, skill_lv);
- if (!skill_num || s_ele == -1) {
- //Take weapon's element
- s_ele = sstatus->rhw.ele;
- s_ele_ = sstatus->lhw.ele;
- if (sd) { //Summoning 10 talisman will endow your weapon.
- ARR_FIND(1, 6, i, sd->talisman[i] >= 10);
- if (i < 5) s_ele = s_ele_ = i;
- }
- if (flag.arrow && sd && sd->bonus.arrow_ele)
- s_ele = sd->bonus.arrow_ele;
- if (battle_config.attack_attr_none&src->type)
- n_ele = true; //Weapon's element is "not elemental"
- } else if (s_ele == -2) //Use enchantment's element
- s_ele = s_ele_ = status_get_attack_sc_element(src,sc);
- else if (s_ele == -3) //Use random element
- s_ele = s_ele_ = rnd()%ELE_MAX;
- switch (skill_num) {
- case GS_GROUNDDRIFT:
- s_ele = s_ele_ = wflag; //element comes in flag.
- break;
- case LK_SPIRALPIERCE:
- if (!sd) n_ele = false; //forced neutral for monsters
- break;
- }
+ t_class = status_get_class(target);
+ s_ele = s_ele_ = skill_get_ele(skill_num, skill_lv);
+ if( !skill_num || s_ele == -1 )
+ { //Take weapon's element
+ s_ele = sstatus->rhw.ele;
+ s_ele_ = sstatus->lhw.ele;
+ if( sd ){ //Summoning 10 talisman will endow your weapon.
+ ARR_FIND(1, 6, i, sd->talisman[i] >= 10);
+ if( i < 5 ) s_ele = s_ele_ = i;
+ }
+ if( flag.arrow && sd && sd->bonus.arrow_ele )
+ s_ele = sd->bonus.arrow_ele;
+ if( battle_config.attack_attr_none&src->type )
+ n_ele = true; //Weapon's element is "not elemental"
+ }
+ else if( s_ele == -2 ) //Use enchantment's element
+ s_ele = s_ele_ = status_get_attack_sc_element(src,sc);
+ else if( s_ele == -3 ) //Use random element
+ s_ele = s_ele_ = rnd()%ELE_MAX;
+ switch( skill_num )
+ {
+ case GS_GROUNDDRIFT:
+ s_ele = s_ele_ = wflag; //element comes in flag.
+ break;
+ case LK_SPIRALPIERCE:
+ if (!sd) n_ele = false; //forced neutral for monsters
+ break;
+ }
- if (!(nk &NK_NO_ELEFIX) && !n_ele)
- if (src->type == BL_HOM)
- n_ele = true; //skill is "not elemental"
- if (sc && sc->data[SC_GOLDENE_FERSE] && ((!skill_num && (rnd() % 100 < sc->data[SC_GOLDENE_FERSE]->val4)) || skill_num == MH_STAHL_HORN)) {
- s_ele = s_ele_ = ELE_HOLY;
- n_ele = false;
- }
+ if (!(nk & NK_NO_ELEFIX) && !n_ele)
+ if (src->type == BL_HOM)
+ n_ele = true; //skill is "not elemental"
+ if (sc && sc->data[SC_GOLDENE_FERSE] && ((!skill_num && (rnd() % 100 < sc->data[SC_GOLDENE_FERSE]->val4)) || skill_num == MH_STAHL_HORN)) {
+ s_ele = s_ele_ = ELE_HOLY;
+ n_ele = false;
+ }
- if (!skill_num) {
- //Skills ALWAYS use ONLY your right-hand weapon (tested on Aegis 10.2)
- if (sd && sd->weapontype1 == 0 && sd->weapontype2 > 0) {
- flag.rh=0;
- flag.lh=1;
- }
- if (sstatus->lhw.atk)
- flag.lh=1;
- }
+ if(!skill_num)
+ { //Skills ALWAYS use ONLY your right-hand weapon (tested on Aegis 10.2)
+ if (sd && sd->weapontype1 == 0 && sd->weapontype2 > 0)
+ {
+ flag.rh=0;
+ flag.lh=1;
+ }
+ if (sstatus->lhw.atk)
+ flag.lh=1;
+ }
- if (sd && !skill_num) { //Check for double attack.
- if (((skill_lv = pc_checkskill(sd,TF_DOUBLE)) > 0 && sd->weapontype1 == W_DAGGER)
- || (sd->bonus.double_rate > 0 && sd->weapontype1 != W_FIST) //Will fail bare-handed
- || (sc && sc->data[SC_KAGEMUSYA] && sd->weapontype1 != W_FIST)) { // Need confirmation
- //Success chance is not added, the higher one is used [Skotlex]
- if (rnd()%100 < (5*skill_lv > sd->bonus.double_rate ? 5*skill_lv : sc && sc->data[SC_KAGEMUSYA]?sc->data[SC_KAGEMUSYA]->val1*3:sd->bonus.double_rate)) {
- wd.div_ = skill_get_num(TF_DOUBLE,skill_lv?skill_lv:1);
- wd.type = 0x08;
- }
- } else if (sd->weapontype1 == W_REVOLVER && (skill_lv = pc_checkskill(sd,GS_CHAINACTION)) > 0 && rnd()%100 < 5*skill_lv) {
- wd.div_ = skill_get_num(GS_CHAINACTION,skill_lv);
- wd.type = 0x08;
- } else if (sc && sc->data[SC_FEARBREEZE] && sd->weapontype1==W_BOW && (i = sd->equip_index[EQI_AMMO]) >= 0 && sd->inventory_data[i] && sd->status.inventory[i].amount > 1) {
- short rate[] = { 4, 4, 7, 9, 10 };
- if (sc->data[SC_FEARBREEZE]->val1 > 0 && sc->data[SC_FEARBREEZE]->val1 < 6 && rand()%100 < rate[sc->data[SC_FEARBREEZE]->val1-1]) {
- wd.type = 0x08;
- wd.div_ = 2;
- if (sc->data[SC_FEARBREEZE]->val1 > 2) {
- int chance = rand()%100;
- wd.div_ += (chance >= 40) + (chance >= 70) + (chance >= 90);
- wd.div_ = min(wd.div_,sc->data[SC_FEARBREEZE]->val1);
- }
- wd.div_ = min(wd.div_,sd->status.inventory[i].amount);
- sc->data[SC_FEARBREEZE]->val4 = wd.div_-1;
- }
- }
- }
+ if( sd && !skill_num ) { //Check for double attack.
+ if( ( ( skill_lv = pc_checkskill(sd,TF_DOUBLE) ) > 0 && sd->weapontype1 == W_DAGGER )
+ || ( sd->bonus.double_rate > 0 && sd->weapontype1 != W_FIST ) //Will fail bare-handed
+ || ( sc && sc->data[SC_KAGEMUSYA] && sd->weapontype1 != W_FIST )) // Need confirmation
+ { //Success chance is not added, the higher one is used [Skotlex]
+ if( rnd()%100 < ( 5*skill_lv > sd->bonus.double_rate ? 5*skill_lv : sc && sc->data[SC_KAGEMUSYA]?sc->data[SC_KAGEMUSYA]->val1*3:sd->bonus.double_rate ) )
+ {
+ wd.div_ = skill_get_num(TF_DOUBLE,skill_lv?skill_lv:1);
+ wd.type = 0x08;
+ }
+ }
+ else if( sd->weapontype1 == W_REVOLVER && (skill_lv = pc_checkskill(sd,GS_CHAINACTION)) > 0 && rnd()%100 < 5*skill_lv )
+ {
+ wd.div_ = skill_get_num(GS_CHAINACTION,skill_lv);
+ wd.type = 0x08;
+ }
+ else if(sc && sc->data[SC_FEARBREEZE] && sd->weapontype1==W_BOW && (i = sd->equip_index[EQI_AMMO]) >= 0 && sd->inventory_data[i] && sd->status.inventory[i].amount > 1){
+ short rate[] = { 4, 4, 7, 9, 10 };
+ if(sc->data[SC_FEARBREEZE]->val1 > 0 && sc->data[SC_FEARBREEZE]->val1 < 6 && rand()%100 < rate[sc->data[SC_FEARBREEZE]->val1-1]) {
+ wd.type = 0x08;
+ wd.div_ = 2;
+ if(sc->data[SC_FEARBREEZE]->val1 > 2){
+ int chance = rand()%100;
+ wd.div_ += (chance >= 40) + (chance >= 70) + (chance >= 90);
+ wd.div_ = min(wd.div_,sc->data[SC_FEARBREEZE]->val1);
+ }
+ wd.div_ = min(wd.div_,sd->status.inventory[i].amount);
+ sc->data[SC_FEARBREEZE]->val4 = wd.div_-1;
+ }
+ }
+ }
- //Check for critical
- if (!flag.cri && !(wd.type&0x08) && sstatus->cri &&
- (!skill_num ||
- skill_num == KN_AUTOCOUNTER ||
- skill_num == SN_SHARPSHOOTING || skill_num == MA_SHARPSHOOTING ||
- skill_num == NJ_KIRIKAGE)) {
- short cri = sstatus->cri;
- if (sd) {
- cri+= sd->critaddrace[tstatus->race];
- if (flag.arrow)
- cri += sd->bonus.arrow_cri;
- }
- if (sc && sc->data[SC_CAMOUFLAGE])
- cri += 10 * (10-sc->data[SC_CAMOUFLAGE]->val4);
- //The official equation is *2, but that only applies when sd's do critical.
- //Therefore, we use the old value 3 on cases when an sd gets attacked by a mob
- cri -= tstatus->luk*(!sd&&tsd?3:2);
-
- if (tsc && tsc->data[SC_SLEEP]) {
- cri <<= 1;
- }
- switch (skill_num) {
- case KN_AUTOCOUNTER:
- if (battle_config.auto_counter_type &&
- (battle_config.auto_counter_type&src->type))
- flag.cri = 1;
- else
- cri <<= 1;
- break;
- case SN_SHARPSHOOTING:
- case MA_SHARPSHOOTING:
- cri += 200;
- break;
- case NJ_KIRIKAGE:
- cri += 250 + 50*skill_lv;
- break;
- }
- if (tsd && tsd->bonus.critical_def)
- cri = cri * (100 - tsd->bonus.critical_def) / 100;
- if (rnd()%1000 < cri)
- flag.cri = 1;
- }
- if (flag.cri) {
- wd.type = 0x0a;
- flag.idef = flag.idef2 = flag.hit = 1;
- } else { //Check for Perfect Hit
- if (sd && sd->bonus.perfect_hit > 0 && rnd()%100 < sd->bonus.perfect_hit)
- flag.hit = 1;
- if (sc && sc->data[SC_FUSION]) {
- flag.hit = 1; //SG_FUSION always hit [Komurka]
- flag.idef = flag.idef2 = 1; //def ignore [Komurka]
- }
- if (!flag.hit)
- switch (skill_num) {
- case AS_SPLASHER:
- if (!wflag) // Always hits the one exploding.
- flag.hit = 1;
- break;
- case CR_SHIELDBOOMERANG:
- if (sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_CRUSADER)
- flag.hit = 1;
- break;
- }
- if (tsc && !flag.hit && tsc->opt1 && tsc->opt1 != OPT1_STONEWAIT && tsc->opt1 != OPT1_BURNING)
- flag.hit = 1;
- }
+ //Check for critical
+ if( !flag.cri && !(wd.type&0x08) && sstatus->cri &&
+ (!skill_num ||
+ skill_num == KN_AUTOCOUNTER ||
+ skill_num == SN_SHARPSHOOTING || skill_num == MA_SHARPSHOOTING ||
+ skill_num == NJ_KIRIKAGE))
+ {
+ short cri = sstatus->cri;
+ if (sd)
+ {
+ cri+= sd->critaddrace[tstatus->race];
+ if(flag.arrow)
+ cri += sd->bonus.arrow_cri;
+ }
+ if( sc && sc->data[SC_CAMOUFLAGE] )
+ cri += 10 * (10-sc->data[SC_CAMOUFLAGE]->val4);
+ //The official equation is *2, but that only applies when sd's do critical.
+ //Therefore, we use the old value 3 on cases when an sd gets attacked by a mob
+ cri -= tstatus->luk*(!sd&&tsd?3:2);
+
+ if( tsc && tsc->data[SC_SLEEP] ) {
+ cri <<= 1;
+ }
+ switch (skill_num) {
+ case KN_AUTOCOUNTER:
+ if(battle_config.auto_counter_type &&
+ (battle_config.auto_counter_type&src->type))
+ flag.cri = 1;
+ else
+ cri <<= 1;
+ break;
+ case SN_SHARPSHOOTING:
+ case MA_SHARPSHOOTING:
+ cri += 200;
+ break;
+ case NJ_KIRIKAGE:
+ cri += 250 + 50*skill_lv;
+ break;
+ }
+ if(tsd && tsd->bonus.critical_def)
+ cri = cri * ( 100 - tsd->bonus.critical_def ) / 100;
+ if (rnd()%1000 < cri)
+ flag.cri = 1;
+ }
+ if (flag.cri)
+ {
+ wd.type = 0x0a;
+ flag.idef = flag.idef2 = flag.hit = 1;
+ } else { //Check for Perfect Hit
+ if(sd && sd->bonus.perfect_hit > 0 && rnd()%100 < sd->bonus.perfect_hit)
+ flag.hit = 1;
+ if (sc && sc->data[SC_FUSION]) {
+ flag.hit = 1; //SG_FUSION always hit [Komurka]
+ flag.idef = flag.idef2 = 1; //def ignore [Komurka]
+ }
+ if( !flag.hit )
+ switch(skill_num)
+ {
+ case AS_SPLASHER:
+ if( !wflag ) // Always hits the one exploding.
+ flag.hit = 1;
+ break;
+ case CR_SHIELDBOOMERANG:
+ if( sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_CRUSADER )
+ flag.hit = 1;
+ break;
+ }
+ if (tsc && !flag.hit && tsc->opt1 && tsc->opt1 != OPT1_STONEWAIT && tsc->opt1 != OPT1_BURNING)
+ flag.hit = 1;
+ }
- if (!flag.hit) {
- //Hit/Flee calculation
- short
- flee = tstatus->flee,
+ if (!flag.hit)
+ { //Hit/Flee calculation
+ short
+ flee = tstatus->flee,
#ifdef RENEWAL
- hitrate = 0; //Default hitrate
+ hitrate = 0; //Default hitrate
#else
- hitrate = 80; //Default hitrate
+ hitrate = 80; //Default hitrate
#endif
- if (battle_config.agi_penalty_type && battle_config.agi_penalty_target&target->type) {
- unsigned char attacker_count; //256 max targets should be a sane max
- attacker_count = unit_counttargeted(target);
- if (attacker_count >= battle_config.agi_penalty_count) {
- if (battle_config.agi_penalty_type == 1)
- flee = (flee * (100 - (attacker_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num))/100;
- else //asume type 2: absolute reduction
- flee -= (attacker_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num;
- if (flee < 1) flee = 1;
- }
- }
+ if(battle_config.agi_penalty_type && battle_config.agi_penalty_target&target->type) {
+ unsigned char attacker_count; //256 max targets should be a sane max
+ attacker_count = unit_counttargeted(target);
+ if(attacker_count >= battle_config.agi_penalty_count) {
+ if (battle_config.agi_penalty_type == 1)
+ flee = (flee * (100 - (attacker_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num))/100;
+ else //asume type 2: absolute reduction
+ flee -= (attacker_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num;
+ if(flee < 1) flee = 1;
+ }
+ }
- hitrate+= sstatus->hit - flee;
+ hitrate+= sstatus->hit - flee;
- if (wd.flag&BF_LONG && !skill_num && //Fogwall's hit penalty is only for normal ranged attacks.
- tsc && tsc->data[SC_FOGWALL])
- hitrate -= 50;
+ if(wd.flag&BF_LONG && !skill_num && //Fogwall's hit penalty is only for normal ranged attacks.
+ tsc && tsc->data[SC_FOGWALL])
+ hitrate -= 50;
- if (sd && flag.arrow)
- hitrate += sd->bonus.arrow_hit;
+ if(sd && flag.arrow)
+ hitrate += sd->bonus.arrow_hit;
#ifdef RENEWAL
- if (sd) //in Renewal hit bonus from Vultures Eye is not anymore shown in status window
- hitrate += pc_checkskill(sd,AC_VULTURE);
+ if( sd ) //in Renewal hit bonus from Vultures Eye is not anymore shown in status window
+ hitrate += pc_checkskill(sd,AC_VULTURE);
#endif
- if (skill_num)
- switch (skill_num) {
- //Hit skill modifiers
- //It is proven that bonus is applied on final hitrate, not hit.
- case SM_BASH:
- case MS_BASH:
- hitrate += hitrate * 5 * skill_lv / 100;
- break;
- case MS_MAGNUM:
- case SM_MAGNUM:
- hitrate += hitrate * 10 * skill_lv / 100;
- break;
- case KN_AUTOCOUNTER:
- case PA_SHIELDCHAIN:
- case NPC_WATERATTACK:
- case NPC_GROUNDATTACK:
- case NPC_FIREATTACK:
- case NPC_WINDATTACK:
- case NPC_POISONATTACK:
- case NPC_HOLYATTACK:
- case NPC_DARKNESSATTACK:
- case NPC_UNDEADATTACK:
- case NPC_TELEKINESISATTACK:
- case NPC_BLEEDING:
- hitrate += hitrate * 20 / 100;
- break;
- case KN_PIERCE:
- case ML_PIERCE:
- hitrate += hitrate * 5 * skill_lv / 100;
- break;
- case AS_SONICBLOW:
- if (sd && pc_checkskill(sd,AS_SONICACCEL)>0)
- hitrate += hitrate * 50 / 100;
- break;
- case MC_CARTREVOLUTION:
- case GN_CART_TORNADO:
- case GN_CARTCANNON:
- if (sd && pc_checkskill(sd, GN_REMODELING_CART))
- hitrate += pc_checkskill(sd, GN_REMODELING_CART) * 4;
- break;
- case GC_VENOMPRESSURE:
- hitrate += 10 + 4 * skill_lv;
- break;
- }
+ if(skill_num)
+ switch(skill_num)
+ { //Hit skill modifiers
+ //It is proven that bonus is applied on final hitrate, not hit.
+ case SM_BASH:
+ case MS_BASH:
+ hitrate += hitrate * 5 * skill_lv / 100;
+ break;
+ case MS_MAGNUM:
+ case SM_MAGNUM:
+ hitrate += hitrate * 10 * skill_lv / 100;
+ break;
+ case KN_AUTOCOUNTER:
+ case PA_SHIELDCHAIN:
+ case NPC_WATERATTACK:
+ case NPC_GROUNDATTACK:
+ case NPC_FIREATTACK:
+ case NPC_WINDATTACK:
+ case NPC_POISONATTACK:
+ case NPC_HOLYATTACK:
+ case NPC_DARKNESSATTACK:
+ case NPC_UNDEADATTACK:
+ case NPC_TELEKINESISATTACK:
+ case NPC_BLEEDING:
+ hitrate += hitrate * 20 / 100;
+ break;
+ case KN_PIERCE:
+ case ML_PIERCE:
+ hitrate += hitrate * 5 * skill_lv / 100;
+ break;
+ case AS_SONICBLOW:
+ if(sd && pc_checkskill(sd,AS_SONICACCEL)>0)
+ hitrate += hitrate * 50 / 100;
+ break;
+ case MC_CARTREVOLUTION:
+ case GN_CART_TORNADO:
+ case GN_CARTCANNON:
+ if( sd && pc_checkskill(sd, GN_REMODELING_CART) )
+ hitrate += pc_checkskill(sd, GN_REMODELING_CART) * 4;
+ break;
+ case GC_VENOMPRESSURE:
+ hitrate += 10 + 4 * skill_lv;
+ break;
+ }
- if (sd) {
- // Weaponry Research hidden bonus
- if ((skill = pc_checkskill(sd,BS_WEAPONRESEARCH)) > 0)
- hitrate += hitrate * (2 * skill) / 100;
+ if( sd ) {
+ // Weaponry Research hidden bonus
+ if ((skill = pc_checkskill(sd,BS_WEAPONRESEARCH)) > 0)
+ hitrate += hitrate * ( 2 * skill ) / 100;
- if ((sd->status.weapon == W_1HSWORD || sd->status.weapon == W_DAGGER) &&
- (skill = pc_checkskill(sd, GN_TRAINING_SWORD))>0)
- hitrate += 3 * skill;
- }
+ if( (sd->status.weapon == W_1HSWORD || sd->status.weapon == W_DAGGER) &&
+ (skill = pc_checkskill(sd, GN_TRAINING_SWORD))>0 )
+ hitrate += 3 * skill;
+ }
- hitrate = cap_value(hitrate, battle_config.min_hitrate, battle_config.max_hitrate);
+ hitrate = cap_value(hitrate, battle_config.min_hitrate, battle_config.max_hitrate);
- if (rnd()%100 >= hitrate)
- wd.dmg_lv = ATK_FLEE;
- else
- flag.hit = 1;
- } //End hit/miss calculation
+ if(rnd()%100 >= hitrate)
+ wd.dmg_lv = ATK_FLEE;
+ else
+ flag.hit = 1;
+ } //End hit/miss calculation
- if (flag.hit && !flag.infdef) { //No need to do the math for plants
- //Hitting attack
+ if (flag.hit && !flag.infdef) //No need to do the math for plants
+ { //Hitting attack
- //Assuming that 99% of the cases we will not need to check for the flag.rh... we don't.
- //ATK_RATE scales the damage. 100 = no change. 50 is halved, 200 is doubled, etc
+//Assuming that 99% of the cases we will not need to check for the flag.rh... we don't.
+//ATK_RATE scales the damage. 100 = no change. 50 is halved, 200 is doubled, etc
#define ATK_RATE( a ) { wd.damage= wd.damage*(a)/100 ; if(flag.lh) wd.damage2= wd.damage2*(a)/100; }
#define ATK_RATE2( a , b ) { wd.damage= wd.damage*(a)/100 ; if(flag.lh) wd.damage2= wd.damage2*(b)/100; }
- //Adds dmg%. 100 = +100% (double) damage. 10 = +10% damage
+//Adds dmg%. 100 = +100% (double) damage. 10 = +10% damage
#define ATK_ADDRATE( a ) { wd.damage+= wd.damage*(a)/100 ; if(flag.lh) wd.damage2+= wd.damage2*(a)/100; }
#define ATK_ADDRATE2( a , b ) { wd.damage+= wd.damage*(a)/100 ; if(flag.lh) wd.damage2+= wd.damage2*(b)/100; }
- //Adds an absolute value to damage. 100 = +100 damage
+//Adds an absolute value to damage. 100 = +100 damage
#define ATK_ADD( a ) { wd.damage+= a; if (flag.lh) wd.damage2+= a; }
#define ATK_ADD2( a , b ) { wd.damage+= a; if (flag.lh) wd.damage2+= b; }
- switch (skill_num) {
- //Calc base damage according to skill
- case NJ_ISSEN:
- wd.damage = 40*sstatus->str +skill_lv*(sstatus->hp/10 + 35);
- wd.damage2 = 0;
- status_set_hp(src, 1, 0);
- break;
- case PA_SACRIFICE:
- wd.damage = sstatus->max_hp* 9/100;
- wd.damage2 = 0;
- break;
+ switch (skill_num)
+ { //Calc base damage according to skill
+ case NJ_ISSEN:
+ wd.damage = 40*sstatus->str +skill_lv*(sstatus->hp/10 + 35);
+ wd.damage2 = 0;
+ status_set_hp(src, 1, 0);
+ break;
+ case PA_SACRIFICE:
+ wd.damage = sstatus->max_hp* 9/100;
+ wd.damage2 = 0;
+ break;
#ifndef RENEWAL
- case LK_SPIRALPIERCE:
- case ML_SPIRALPIERCE:
- if (sd) {
- short index = sd->equip_index[EQI_HAND_R];
-
- if (index >= 0 &&
- sd->inventory_data[index] &&
- sd->inventory_data[index]->type == IT_WEAPON)
- wd.damage = sd->inventory_data[index]->weight*8/100; //80% of weight
- } else
- wd.damage = sstatus->rhw.atk2*8/10; //Else use Atk2
-
- ATK_ADDRATE(50*skill_lv); //Skill modifier applies to weight only.
- i = sstatus->str/10;
- i*=i;
- ATK_ADD(i); //Add str bonus.
- switch (tstatus->size) { //Size-fix. Is this modified by weapon perfection?
- case SZ_SMALL: //Small: 125%
- ATK_RATE(125);
- break;
- //case SZ_MEDIUM: //Medium: 100%
- case SZ_BIG: //Large: 75%
- ATK_RATE(75);
- break;
- }
- break;
-#endif
- case CR_SHIELDBOOMERANG:
- case PA_SHIELDCHAIN:
- case LG_SHIELDPRESS:
- case LG_EARTHDRIVE:
- wd.damage = sstatus->batk;
- if (sd) {
- short index = sd->equip_index[EQI_HAND_L];
-
- if (index >= 0 &&
- sd->inventory_data[index] &&
- sd->inventory_data[index]->type == IT_ARMOR)
- ATK_ADD(sd->inventory_data[index]->weight/10);
- } else
- ATK_ADD(sstatus->rhw.atk2); //Else use Atk2
- break;
- case HFLI_SBR44: //[orn]
- if (src->type == BL_HOM) {
- wd.damage = ((TBL_HOM *)src)->homunculus.intimacy ;
- break;
- }
- default: {
- i = (flag.cri?1:0)|
- (flag.arrow?2:0)|
- (skill_num == HW_MAGICCRASHER?4:0)|
- (!skill_num && sc && sc->data[SC_CHANGE]?4:0)|
- (skill_num == MO_EXTREMITYFIST?8:0)|
- (sc && sc->data[SC_WEAPONPERFECTION]?8:0);
- if (flag.arrow && sd)
- switch (sd->status.weapon) {
- case W_BOW:
- case W_REVOLVER:
- case W_GATLING:
- case W_SHOTGUN:
- case W_GRENADE:
- break;
- default:
- i |= 16; // for ex. shuriken must not be influenced by DEX
- }
- wd.damage = battle_calc_base_damage(sstatus, &sstatus->rhw, sc, tstatus->size, sd, i);
- if (flag.lh)
- wd.damage2 = battle_calc_base_damage(sstatus, &sstatus->lhw, sc, tstatus->size, sd, i);
-
- if (nk&NK_SPLASHSPLIT) { // Divide ATK among targets
- if (wflag>0)
- wd.damage/= wflag;
- else
- ShowError("0 enemies targeted by %d:%s, divide per 0 avoided!\n", skill_num, skill_get_name(skill_num));
- }
-
- //Add any bonuses that modify the base baseatk+watk (pre-skills)
- if (sd) {
- if (sd->bonus.atk_rate)
- ATK_ADDRATE(sd->bonus.atk_rate);
-
- if (flag.cri && sd->bonus.crit_atk_rate)
- ATK_ADDRATE(sd->bonus.crit_atk_rate);
-
- if (sd->status.party_id && (skill=pc_checkskill(sd,TK_POWER)) > 0) {
- if ((i = party_foreachsamemap(party_sub_count, sd, 0)) > 1) // exclude the player himself [Inkfish]
- ATK_ADDRATE(2*skill*i);
- }
- }
- break;
- } //End default case
- } //End switch(skill_num)
-
- //Skill damage modifiers that stack linearly
- if (sc && skill_num != PA_SACRIFICE) {
- if (sc->data[SC_OVERTHRUST])
- skillratio += sc->data[SC_OVERTHRUST]->val3;
- if (sc->data[SC_MAXOVERTHRUST])
- skillratio += sc->data[SC_MAXOVERTHRUST]->val2;
- if (sc->data[SC_BERSERK] || sc->data[SC_SATURDAYNIGHTFEVER] || sc->data[SC__BLOODYLUST])
- skillratio += 100;
- if (sc->data[SC_ZENKAI] && sstatus->rhw.ele == sc->data[SC_ZENKAI]->val2)
- skillratio += sc->data[SC_ZENKAI]->val1 * 2;
- }
- if (!skill_num) {
- ATK_RATE(skillratio);
- } else {
- switch (skill_num) {
- case SM_BASH:
- case MS_BASH:
- skillratio += 30*skill_lv;
- break;
- case SM_MAGNUM:
- case MS_MAGNUM:
- skillratio += 20*skill_lv;
- break;
- case MC_MAMMONITE:
- skillratio += 50*skill_lv;
- break;
- case HT_POWER:
- skillratio += -50+8*sstatus->str;
- break;
- case AC_DOUBLE:
- case MA_DOUBLE:
- skillratio += 10*(skill_lv-1);
- break;
- case AC_SHOWER:
- case MA_SHOWER:
-#ifdef RENEWAL
- skillratio += 50+10*skill_lv;
-#else
- skillratio += -25+5*skill_lv;
+ case LK_SPIRALPIERCE:
+ case ML_SPIRALPIERCE:
+ if (sd) {
+ short index = sd->equip_index[EQI_HAND_R];
+
+ if (index >= 0 &&
+ sd->inventory_data[index] &&
+ sd->inventory_data[index]->type == IT_WEAPON)
+ wd.damage = sd->inventory_data[index]->weight*8/100; //80% of weight
+ } else
+ wd.damage = sstatus->rhw.atk2*8/10; //Else use Atk2
+
+ ATK_ADDRATE(50*skill_lv); //Skill modifier applies to weight only.
+ i = sstatus->str/10;
+ i*=i;
+ ATK_ADD(i); //Add str bonus.
+ switch (tstatus->size) { //Size-fix. Is this modified by weapon perfection?
+ case SZ_SMALL: //Small: 125%
+ ATK_RATE(125);
+ break;
+ //case SZ_MEDIUM: //Medium: 100%
+ case SZ_BIG: //Large: 75%
+ ATK_RATE(75);
+ break;
+ }
+ break;
#endif
- break;
- case AC_CHARGEARROW:
- case MA_CHARGEARROW:
- skillratio += 50;
- break;
+ case CR_SHIELDBOOMERANG:
+ case PA_SHIELDCHAIN:
+ case LG_SHIELDPRESS:
+ case LG_EARTHDRIVE:
+ wd.damage = sstatus->batk;
+ if (sd) {
+ short index = sd->equip_index[EQI_HAND_L];
+
+ if (index >= 0 &&
+ sd->inventory_data[index] &&
+ sd->inventory_data[index]->type == IT_ARMOR)
+ ATK_ADD(sd->inventory_data[index]->weight/10);
+ } else
+ ATK_ADD(sstatus->rhw.atk2); //Else use Atk2
+ break;
+ case HFLI_SBR44: //[orn]
+ if(src->type == BL_HOM) {
+ wd.damage = ((TBL_HOM*)src)->homunculus.intimacy ;
+ break;
+ }
+ default:
+ {
+ i = (flag.cri?1:0)|
+ (flag.arrow?2:0)|
+ (skill_num == HW_MAGICCRASHER?4:0)|
+ (!skill_num && sc && sc->data[SC_CHANGE]?4:0)|
+ (skill_num == MO_EXTREMITYFIST?8:0)|
+ (sc && sc->data[SC_WEAPONPERFECTION]?8:0);
+ if (flag.arrow && sd)
+ switch(sd->status.weapon) {
+ case W_BOW:
+ case W_REVOLVER:
+ case W_GATLING:
+ case W_SHOTGUN:
+ case W_GRENADE:
+ break;
+ default:
+ i |= 16; // for ex. shuriken must not be influenced by DEX
+ }
+ wd.damage = battle_calc_base_damage(sstatus, &sstatus->rhw, sc, tstatus->size, sd, i);
+ if (flag.lh)
+ wd.damage2 = battle_calc_base_damage(sstatus, &sstatus->lhw, sc, tstatus->size, sd, i);
+
+ if (nk&NK_SPLASHSPLIT){ // Divide ATK among targets
+ if(wflag>0)
+ wd.damage/= wflag;
+ else
+ ShowError("0 enemies targeted by %d:%s, divide per 0 avoided!\n", skill_num, skill_get_name(skill_num));
+ }
+
+ //Add any bonuses that modify the base baseatk+watk (pre-skills)
+ if(sd) {
+ if (sd->bonus.atk_rate)
+ ATK_ADDRATE(sd->bonus.atk_rate);
+
+ if(flag.cri && sd->bonus.crit_atk_rate)
+ ATK_ADDRATE(sd->bonus.crit_atk_rate);
+
+ if(sd->status.party_id && (skill=pc_checkskill(sd,TK_POWER)) > 0){
+ if( (i = party_foreachsamemap(party_sub_count, sd, 0)) > 1 ) // exclude the player himself [Inkfish]
+ ATK_ADDRATE(2*skill*i);
+ }
+ }
+ break;
+ } //End default case
+ } //End switch(skill_num)
+
+ //Skill damage modifiers that stack linearly
+ if(sc && skill_num != PA_SACRIFICE)
+ {
+ if(sc->data[SC_OVERTHRUST])
+ skillratio += sc->data[SC_OVERTHRUST]->val3;
+ if(sc->data[SC_MAXOVERTHRUST])
+ skillratio += sc->data[SC_MAXOVERTHRUST]->val2;
+ if (sc->data[SC_BERSERK] || sc->data[SC_SATURDAYNIGHTFEVER] || sc->data[SC__BLOODYLUST])
+ skillratio += 100;
+ if(sc->data[SC_ZENKAI] && sstatus->rhw.ele == sc->data[SC_ZENKAI]->val2 )
+ skillratio += sc->data[SC_ZENKAI]->val1 * 2;
+ }
+ if( !skill_num )
+ {
+ ATK_RATE(skillratio);
+ }
+ else
+ {
+ switch( skill_num )
+ {
+ case SM_BASH:
+ case MS_BASH:
+ skillratio += 30*skill_lv;
+ break;
+ case SM_MAGNUM:
+ case MS_MAGNUM:
+ skillratio += 20*skill_lv;
+ break;
+ case MC_MAMMONITE:
+ skillratio += 50*skill_lv;
+ break;
+ case HT_POWER:
+ skillratio += -50+8*sstatus->str;
+ break;
+ case AC_DOUBLE:
+ case MA_DOUBLE:
+ skillratio += 10*(skill_lv-1);
+ break;
+ case AC_SHOWER:
+ case MA_SHOWER:
+ #ifdef RENEWAL
+ skillratio += 50+10*skill_lv;
+ #else
+ skillratio += -25+5*skill_lv;
+ #endif
+ break;
+ case AC_CHARGEARROW:
+ case MA_CHARGEARROW:
+ skillratio += 50;
+ break;
#ifndef RENEWAL
- case HT_FREEZINGTRAP:
- case MA_FREEZINGTRAP:
- skillratio += -50+10*skill_lv;
- break;
-#endif
- case KN_PIERCE:
- case ML_PIERCE:
- skillratio += 10*skill_lv;
- break;
- case MER_CRASH:
- skillratio += 10*skill_lv;
- break;
- case KN_SPEARSTAB:
- skillratio += 15*skill_lv;
- break;
- case KN_SPEARBOOMERANG:
- skillratio += 50*skill_lv;
- break;
- case KN_BRANDISHSPEAR:
- case ML_BRANDISH: {
- int ratio = 100+20*skill_lv;
- skillratio += ratio-100;
- if (skill_lv>3 && wflag==1) skillratio += ratio/2;
- if (skill_lv>6 && wflag==1) skillratio += ratio/4;
- if (skill_lv>9 && wflag==1) skillratio += ratio/8;
- if (skill_lv>6 && wflag==2) skillratio += ratio/2;
- if (skill_lv>9 && wflag==2) skillratio += ratio/4;
- if (skill_lv>9 && wflag==3) skillratio += ratio/2;
- break;
- }
- case KN_BOWLINGBASH:
- case MS_BOWLINGBASH:
- skillratio+= 40*skill_lv;
- break;
- case AS_GRIMTOOTH:
- skillratio += 20*skill_lv;
- break;
- case AS_POISONREACT:
- skillratio += 30*skill_lv;
- break;
- case AS_SONICBLOW:
- skillratio += -50+5*skill_lv;
- break;
- case TF_SPRINKLESAND:
- skillratio += 30;
- break;
- case MC_CARTREVOLUTION:
- skillratio += 50;
- if (sd && sd->cart_weight)
- skillratio += 100*sd->cart_weight/sd->cart_weight_max; // +1% every 1% weight
- else if (!sd)
- skillratio += 100; //Max damage for non players.
- break;
- case NPC_RANDOMATTACK:
- skillratio += 100*skill_lv;
- break;
- case NPC_WATERATTACK:
- case NPC_GROUNDATTACK:
- case NPC_FIREATTACK:
- case NPC_WINDATTACK:
- case NPC_POISONATTACK:
- case NPC_HOLYATTACK:
- case NPC_DARKNESSATTACK:
- case NPC_UNDEADATTACK:
- case NPC_TELEKINESISATTACK:
- case NPC_BLOODDRAIN:
- case NPC_ACIDBREATH:
- case NPC_DARKNESSBREATH:
- case NPC_FIREBREATH:
- case NPC_ICEBREATH:
- case NPC_THUNDERBREATH:
- case NPC_HELLJUDGEMENT:
- case NPC_PULSESTRIKE:
- skillratio += 100*(skill_lv-1);
- break;
- case RG_BACKSTAP:
- if (sd && sd->status.weapon == W_BOW && battle_config.backstab_bow_penalty)
- skillratio += (200+40*skill_lv)/2;
- else
- skillratio += 200+40*skill_lv;
- break;
- case RG_RAID:
- skillratio += 40*skill_lv;
- break;
- case RG_INTIMIDATE:
- skillratio += 30*skill_lv;
- break;
- case CR_SHIELDCHARGE:
- skillratio += 20*skill_lv;
- break;
- case CR_SHIELDBOOMERANG:
- skillratio += 30*skill_lv;
- break;
- case NPC_DARKCROSS:
- case CR_HOLYCROSS: {
- int ratio = 35*skill_lv;
-#ifdef RENEWAL
- if (sd && sd->status.weapon == W_2HSPEAR)
- ratio *= 2;
-#endif
- skillratio += ratio;
- break;
- }
- case AM_DEMONSTRATION:
- skillratio += 20*skill_lv;
- break;
- case AM_ACIDTERROR:
- skillratio += 40*skill_lv;
- break;
- case MO_FINGEROFFENSIVE:
- skillratio+= 50 * skill_lv;
- break;
- case MO_INVESTIGATE:
- skillratio += 75*skill_lv;
- flag.pdef = flag.pdef2 = 2;
- break;
- case MO_EXTREMITYFIST: {
- //Overflow check. [Skotlex]
- unsigned int ratio = skillratio + 100*(8 + sstatus->sp/10);
- //You'd need something like 6K SP to reach this max, so should be fine for most purposes.
- if (ratio > 60000) ratio = 60000; //We leave some room here in case skillratio gets further increased.
- skillratio = (unsigned short)ratio;
- status_set_sp(src, 0, 0);
- }
- break;
- case MO_TRIPLEATTACK:
- skillratio += 20*skill_lv;
- break;
- case MO_CHAINCOMBO:
- skillratio += 50+50*skill_lv;
- break;
- case MO_COMBOFINISH:
- skillratio += 140+60*skill_lv;
- break;
- case BA_MUSICALSTRIKE:
- case DC_THROWARROW:
- skillratio += 25+25*skill_lv;
- break;
- case CH_TIGERFIST:
- skillratio += 100*skill_lv-60;
- break;
- case CH_CHAINCRUSH:
- skillratio += 300+100*skill_lv;
- break;
- case CH_PALMSTRIKE:
- skillratio += 100+100*skill_lv;
- break;
- case LK_HEADCRUSH:
- skillratio += 40*skill_lv;
- break;
- case LK_JOINTBEAT:
- i = 10*skill_lv-50;
- // Although not clear, it's being assumed that the 2x damage is only for the break neck ailment.
- if (wflag&BREAK_NECK) i*=2;
- skillratio += i;
- break;
-#ifdef RENEWAL
- case LK_SPIRALPIERCE:
- case ML_SPIRALPIERCE: {
- // Formula: Floor[Floor(Weapon Weight/2)*skill level + ATK ]*(100%+50%*s.lvl) * 5 multi-hits
- short index = sd?sd->equip_index[EQI_HAND_R]:0;
- int weight = 0;
-
- if (sd && index >= 0 &&
- sd->inventory_data[index] &&
- sd->inventory_data[index]->type == IT_WEAPON)
- weight = sd->inventory_data[index]->weight/20;
- ATK_ADD(weight * skill_lv)
- skillratio += 50*skill_lv;
- }
- break;
+ case HT_FREEZINGTRAP:
+ case MA_FREEZINGTRAP:
+ skillratio += -50+10*skill_lv;
+ break;
#endif
- case ASC_METEORASSAULT:
- skillratio += 40*skill_lv-60;
- break;
- case SN_SHARPSHOOTING:
- case MA_SHARPSHOOTING:
- skillratio += 100+50*skill_lv;
- break;
- case CG_ARROWVULCAN:
- skillratio += 100+100*skill_lv;
- break;
- case AS_SPLASHER:
- skillratio += 400+50*skill_lv;
- if (sd)
- skillratio += 20 * pc_checkskill(sd,AS_POISONREACT);
- break;
- case ASC_BREAKER:
- skillratio += 100*skill_lv-100;
- break;
- case PA_SACRIFICE:
- skillratio += 10*skill_lv-10;
- break;
- case PA_SHIELDCHAIN:
- skillratio += 30*skill_lv;
- break;
- case WS_CARTTERMINATION:
- i = 10 * (16 - skill_lv);
- if (i < 1) i = 1;
- //Preserve damage ratio when max cart weight is changed.
- if (sd && sd->cart_weight)
- skillratio += sd->cart_weight/i * 80000/battle_config.max_cart_weight - 100;
- else if (!sd)
- skillratio += 80000 / i - 100;
- break;
- case TK_DOWNKICK:
- skillratio += 60 + 20*skill_lv;
- break;
- case TK_STORMKICK:
- skillratio += 60 + 20*skill_lv;
- break;
- case TK_TURNKICK:
- skillratio += 90 + 30*skill_lv;
- break;
- case TK_COUNTER:
- skillratio += 90 + 30*skill_lv;
- break;
- case TK_JUMPKICK:
- skillratio += -70 + 10*skill_lv;
- if (sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == skill_num)
- skillratio += 10*status_get_lv(src)/3; //Tumble bonus
- if (wflag) {
- skillratio += 10*status_get_lv(src)/3; //Running bonus (TODO: What is the real bonus?)
- if (sc && sc->data[SC_SPURT]) // Spurt bonus
- skillratio *= 2;
- }
- break;
- case GS_TRIPLEACTION:
- skillratio += 50*skill_lv;
- break;
- case GS_BULLSEYE:
- //Only works well against brute/demihumans non bosses.
- if ((tstatus->race == RC_BRUTE || tstatus->race == RC_DEMIHUMAN)
- && !(tstatus->mode&MD_BOSS))
- skillratio += 400;
- break;
- case GS_TRACKING:
- skillratio += 100 *(skill_lv+1);
- break;
- case GS_PIERCINGSHOT:
- skillratio += 20*skill_lv;
- break;
- case GS_RAPIDSHOWER:
- skillratio += 10*skill_lv;
- break;
- case GS_DESPERADO:
- skillratio += 50*(skill_lv-1);
- break;
- case GS_DUST:
- skillratio += 50*skill_lv;
- break;
- case GS_FULLBUSTER:
- skillratio += 100*(skill_lv+2);
- break;
- case GS_SPREADATTACK:
+ case KN_PIERCE:
+ case ML_PIERCE:
+ skillratio += 10*skill_lv;
+ break;
+ case MER_CRASH:
+ skillratio += 10*skill_lv;
+ break;
+ case KN_SPEARSTAB:
+ skillratio += 15*skill_lv;
+ break;
+ case KN_SPEARBOOMERANG:
+ skillratio += 50*skill_lv;
+ break;
+ case KN_BRANDISHSPEAR:
+ case ML_BRANDISH:
+ {
+ int ratio = 100+20*skill_lv;
+ skillratio += ratio-100;
+ if(skill_lv>3 && wflag==1) skillratio += ratio/2;
+ if(skill_lv>6 && wflag==1) skillratio += ratio/4;
+ if(skill_lv>9 && wflag==1) skillratio += ratio/8;
+ if(skill_lv>6 && wflag==2) skillratio += ratio/2;
+ if(skill_lv>9 && wflag==2) skillratio += ratio/4;
+ if(skill_lv>9 && wflag==3) skillratio += ratio/2;
+ break;
+ }
+ case KN_BOWLINGBASH:
+ case MS_BOWLINGBASH:
+ skillratio+= 40*skill_lv;
+ break;
+ case AS_GRIMTOOTH:
+ skillratio += 20*skill_lv;
+ break;
+ case AS_POISONREACT:
+ skillratio += 30*skill_lv;
+ break;
+ case AS_SONICBLOW:
+ skillratio += -50+5*skill_lv;
+ break;
+ case TF_SPRINKLESAND:
+ skillratio += 30;
+ break;
+ case MC_CARTREVOLUTION:
+ skillratio += 50;
+ if(sd && sd->cart_weight)
+ skillratio += 100*sd->cart_weight/sd->cart_weight_max; // +1% every 1% weight
+ else if (!sd)
+ skillratio += 100; //Max damage for non players.
+ break;
+ case NPC_RANDOMATTACK:
+ skillratio += 100*skill_lv;
+ break;
+ case NPC_WATERATTACK:
+ case NPC_GROUNDATTACK:
+ case NPC_FIREATTACK:
+ case NPC_WINDATTACK:
+ case NPC_POISONATTACK:
+ case NPC_HOLYATTACK:
+ case NPC_DARKNESSATTACK:
+ case NPC_UNDEADATTACK:
+ case NPC_TELEKINESISATTACK:
+ case NPC_BLOODDRAIN:
+ case NPC_ACIDBREATH:
+ case NPC_DARKNESSBREATH:
+ case NPC_FIREBREATH:
+ case NPC_ICEBREATH:
+ case NPC_THUNDERBREATH:
+ case NPC_HELLJUDGEMENT:
+ case NPC_PULSESTRIKE:
+ skillratio += 100*(skill_lv-1);
+ break;
+ case RG_BACKSTAP:
+ if(sd && sd->status.weapon == W_BOW && battle_config.backstab_bow_penalty)
+ skillratio += (200+40*skill_lv)/2;
+ else
+ skillratio += 200+40*skill_lv;
+ break;
+ case RG_RAID:
+ skillratio += 40*skill_lv;
+ break;
+ case RG_INTIMIDATE:
+ skillratio += 30*skill_lv;
+ break;
+ case CR_SHIELDCHARGE:
+ skillratio += 20*skill_lv;
+ break;
+ case CR_SHIELDBOOMERANG:
+ skillratio += 30*skill_lv;
+ break;
+ case NPC_DARKCROSS:
+ case CR_HOLYCROSS:
+ {
+ int ratio = 35*skill_lv;
+ #ifdef RENEWAL
+ if(sd && sd->status.weapon == W_2HSPEAR)
+ ratio *= 2;
+ #endif
+ skillratio += ratio;
+ break;
+ }
+ case AM_DEMONSTRATION:
+ skillratio += 20*skill_lv;
+ break;
+ case AM_ACIDTERROR:
+ skillratio += 40*skill_lv;
+ break;
+ case MO_FINGEROFFENSIVE:
+ skillratio+= 50 * skill_lv;
+ break;
+ case MO_INVESTIGATE:
+ skillratio += 75*skill_lv;
+ flag.pdef = flag.pdef2 = 2;
+ break;
+ case MO_EXTREMITYFIST:
+ { //Overflow check. [Skotlex]
+ unsigned int ratio = skillratio + 100*(8 + sstatus->sp/10);
+ //You'd need something like 6K SP to reach this max, so should be fine for most purposes.
+ if (ratio > 60000) ratio = 60000; //We leave some room here in case skillratio gets further increased.
+ skillratio = (unsigned short)ratio;
+ status_set_sp(src, 0, 0);
+ }
+ break;
+ case MO_TRIPLEATTACK:
+ skillratio += 20*skill_lv;
+ break;
+ case MO_CHAINCOMBO:
+ skillratio += 50+50*skill_lv;
+ break;
+ case MO_COMBOFINISH:
+ skillratio += 140+60*skill_lv;
+ break;
+ case BA_MUSICALSTRIKE:
+ case DC_THROWARROW:
+ skillratio += 25+25*skill_lv;
+ break;
+ case CH_TIGERFIST:
+ skillratio += 100*skill_lv-60;
+ break;
+ case CH_CHAINCRUSH:
+ skillratio += 300+100*skill_lv;
+ break;
+ case CH_PALMSTRIKE:
+ skillratio += 100+100*skill_lv;
+ break;
+ case LK_HEADCRUSH:
+ skillratio += 40*skill_lv;
+ break;
+ case LK_JOINTBEAT:
+ i = 10*skill_lv-50;
+ // Although not clear, it's being assumed that the 2x damage is only for the break neck ailment.
+ if (wflag&BREAK_NECK) i*=2;
+ skillratio += i;
+ break;
#ifdef RENEWAL
- skillratio += 20*(skill_lv);
-#else
- skillratio += 20*(skill_lv-1);
+ case LK_SPIRALPIERCE:
+ case ML_SPIRALPIERCE:
+ {// Formula: Floor[Floor(Weapon Weight/2)*skill level + ATK ]*(100%+50%*s.lvl) * 5 multi-hits
+ short index = sd?sd->equip_index[EQI_HAND_R]:0;
+ int weight = 0;
+
+ if (sd && index >= 0 &&
+ sd->inventory_data[index] &&
+ sd->inventory_data[index]->type == IT_WEAPON)
+ weight = sd->inventory_data[index]->weight/20;
+ ATK_ADD(weight * skill_lv)
+ skillratio += 50*skill_lv;
+ }
+ break;
#endif
- break;
- case NJ_HUUMA:
- skillratio += 50 + 150*skill_lv;
- break;
- case NJ_TATAMIGAESHI:
- skillratio += 10*skill_lv;
- break;
- case NJ_KASUMIKIRI:
- skillratio += 10*skill_lv;
- break;
- case NJ_KIRIKAGE:
- skillratio += 100*(skill_lv-1);
- break;
- case KN_CHARGEATK: {
- int k = (wflag-1)/3; //+100% every 3 cells of distance
- if (k > 2) k = 2; // ...but hard-limited to 300%.
- skillratio += 100 * k;
- }
- break;
- case HT_PHANTASMIC:
- skillratio += 50;
- break;
- case MO_BALKYOUNG:
- skillratio += 200;
- break;
- case HFLI_MOON: //[orn]
- skillratio += 10+110*skill_lv;
- break;
- case HFLI_SBR44: //[orn]
- skillratio += 100 *(skill_lv-1);
- break;
- case NPC_VAMPIRE_GIFT:
- skillratio += ((skill_lv-1)%5+1)*100;
- break;
- case RK_SONICWAVE:
- skillratio += 400 + 100 * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case RK_HUNDREDSPEAR:
- skillratio += 500 + (80 * skill_lv);
- if (sd) {
- short index = sd->equip_index[EQI_HAND_R];
- if (index >= 0 && sd->inventory_data[index]
- && sd->inventory_data[index]->type == IT_WEAPON)
- skillratio += max(10000 - sd->inventory_data[index]->weight, 0) / 10;
- skillratio += 50 * pc_checkskill(sd,LK_SPIRALPIERCE);
- } // (1 + [(Casters Base Level - 100) / 200])
- skillratio = skillratio * (100 + (status_get_lv(src)-100) / 2) / 100;
- break;
- case RK_WINDCUTTER:
- skillratio += 50 * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case RK_IGNITIONBREAK:
- i = distance_bl(src,target);
- if (i < 2)
- skillratio = 200 + 200 * skill_lv;
- else if (i < 4)
- skillratio = 100 + 200 * skill_lv;
- else
- skillratio = 100 + 100 * skill_lv;
- RE_LVL_DMOD(100);
- if (sstatus->rhw.ele == ELE_FIRE)
- skillratio += skillratio / 2;
- break;
- case RK_CRUSHSTRIKE:
- if (sd) {
- //ATK [{Weapon Level * (Weapon Upgrade Level + 6) * 100} + (Weapon ATK) + (Weapon Weight)]%
- short index = sd->equip_index[EQI_HAND_R];
- if (index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_WEAPON)
- skillratio = sd->inventory_data[index]->weight/10 + sstatus->rhw.atk +
- 100 * sd->inventory_data[index]->wlv * (sd->status.inventory[index].refine + 6);
- }
- break;
- case RK_STORMBLAST:
- skillratio = 100 * (sd ? pc_checkskill(sd,RK_RUNEMASTERY) : 1) + 100 * (sstatus->int_ / 4);
- break;
- case RK_PHANTOMTHRUST:
- skillratio = 50 * skill_lv + 10 * (sd ? pc_checkskill(sd,KN_SPEARMASTERY) : 10);
- //if( s_level > 100 ) skillratio += skillratio * s_level / 150; // Base level bonus. This is official, but is disabled until I can confirm something with was changed or not. [Rytech]
- //if( s_level > 100 ) skillratio += skillratio * (s_level - 100) / 200; // Base level bonus.
- break;
- /**
- * GC Guilotine Cross
- **/
- case GC_CROSSIMPACT:
- skillratio += 900 + 100 * skill_lv;
- RE_LVL_DMOD(120);
- break;
- case GC_PHANTOMMENACE:
- skillratio += 200;
- break;
- case GC_COUNTERSLASH:
- //ATK [{(Skill Level x 100) + 300} x Caster's Base Level / 120]% + ATK [(AGI x 2) + (Caster's Job Level x 4)]%
- skillratio += 200 + (100 * skill_lv);
- RE_LVL_DMOD(120);
- skillratio += sstatus->agi + (sd?sd->status.job_level:0) * 4;
- break;
- case GC_ROLLINGCUTTER:
- skillratio += -50 + 50 * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case GC_CROSSRIPPERSLASHER:
- skillratio += 300 + 80 * skill_lv;
- RE_LVL_DMOD(100);
- if (sc && sc->data[SC_ROLLINGCUTTER])
- skillratio += sc->data[SC_ROLLINGCUTTER]->val1 * sstatus->agi;
- break;
- /**
- * Arch Bishop
- **/
- case AB_DUPLELIGHT_MELEE:
- skillratio += 10 * skill_lv;
- break;
- /**
- * Ranger
- **/
- case RA_ARROWSTORM:
- skillratio += 900 + 80 * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case RA_AIMEDBOLT:
- skillratio += 400 + 50 * skill_lv;
- RE_LVL_DMOD(100);
- if (tsc && (tsc->data[SC_BITE] || tsc->data[SC_ANKLE] || tsc->data[SC_ELECTRICSHOCKER]))
- wd.div_ = tstatus->size + 2 + ((rnd()%100 < 50-tstatus->size*10) ? 1 : 0);
- break;
- case RA_CLUSTERBOMB:
- skillratio += 100 + 100 * skill_lv;
- break;
- case RA_WUGDASH:// ATK 300%
- skillratio += 200;
- break;
- case RA_WUGSTRIKE:
- skillratio = 200 * skill_lv;
- break;
- case RA_WUGBITE:
- skillratio += 300 + 200 * skill_lv;
- if (skill_lv == 5) skillratio += 100;
- break;
- case RA_SENSITIVEKEEN:
- skillratio += 50 * skill_lv;
- break;
- /**
- * Mechanic
- **/
- case NC_BOOSTKNUCKLE:
- skillratio += 100 + 100 * skill_lv + sstatus->dex;
- RE_LVL_DMOD(100);
- break;
- case NC_PILEBUNKER:
- skillratio += 200 + 100 * skill_lv + sstatus->str;
- RE_LVL_DMOD(100);
- break;
- case NC_VULCANARM:
- skillratio = 70 * skill_lv + sstatus->dex;
- RE_LVL_DMOD(100);
- break;
- case NC_FLAMELAUNCHER:
- case NC_COLDSLOWER:
- skillratio += 200 + 300 * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case NC_ARMSCANNON:
- switch (tstatus->size) {
- case SZ_SMALL:
- skillratio += 100 + 500 * skill_lv;
- break;// Small
- case SZ_MEDIUM:
- skillratio += 100 + 400 * skill_lv;
- break;// Medium
- case SZ_BIG:
- skillratio += 100 + 300 * skill_lv;
- break;// Large
- }
- RE_LVL_DMOD(100);
- //NOTE: Their's some other factors that affects damage, but not sure how exactly. Will recheck one day. [Rytech]
- break;
- case NC_AXEBOOMERANG:
- skillratio += 60 + 40 * skill_lv;
- if (sd) {
- short index = sd->equip_index[EQI_HAND_R];
- if (index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_WEAPON)
- skillratio += sd->inventory_data[index]->weight / 10;// Weight is divided by 10 since 10 weight in coding make 1 whole actural weight. [Rytech]
- }
- RE_LVL_DMOD(100);
- break;
- case NC_POWERSWING:
- skillratio += 80 + 20 * skill_lv + sstatus->str + sstatus->dex;
- RE_LVL_DMOD(100);
- break;
- case NC_AXETORNADO:
- skillratio += 100 + 100 * skill_lv + sstatus->vit;
- RE_LVL_DMOD(100);
- break;
- case SC_FATALMENACE:
- skillratio += 100 * skill_lv;
- break;
- case SC_TRIANGLESHOT:
- skillratio += 270 + 30 * skill_lv;
- break;
- case SC_FEINTBOMB:
- skillratio += 100 + 100 * skill_lv;
- break;
- case LG_CANNONSPEAR:// Stimated formula. Still need confirm it.
- skillratio += -100 + (50 + sstatus->str) * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case LG_BANISHINGPOINT:
- skillratio += -100 + ((50 * skill_lv) + (30 * ((sd)?pc_checkskill(sd,SM_BASH):1)));
- RE_LVL_DMOD(100);
- break;
- case LG_SHIELDPRESS:
- skillratio += 60 + 43 * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case LG_PINPOINTATTACK:
- skillratio = ((100 * skill_lv) + (10 * status_get_agi(src)));
- RE_LVL_DMOD(100);
- break;
- case LG_RAGEBURST:
- if (sd && sd->spiritball_old)
- skillratio += -100 + (sd->spiritball_old * 200);
- else
- skillratio += -100 + 15 * 200;
- RE_LVL_DMOD(100);
- break;
- case LG_SHIELDSPELL:// [(Casters Base Level x 4) + (Shield DEF x 10) + (Casters VIT x 2)] %
- if (sd) {
- struct item_data *shield_data = sd->inventory_data[sd->equip_index[EQI_HAND_L]];
- skillratio = status_get_lv(src) * 4 + status_get_vit(src) * 2;
- if (shield_data)
- skillratio += shield_data->def * 10;
- } else
- skillratio += 2400; //2500%
- break;
- case LG_MOONSLASHER:
- skillratio += -100 + (120 * skill_lv + ((sd) ? pc_checkskill(sd,LG_OVERBRAND) : 5) * 80);
- RE_LVL_DMOD(100);
- break;
- case LG_OVERBRAND:
- skillratio = 400 * skill_lv + (pc_checkskill(sd,CR_SPEARQUICKEN) * 30);
- RE_LVL_DMOD(100);
- break;
- case LG_OVERBRAND_BRANDISH:
- skillratio = 300 * skill_lv + (2 * (sstatus->str + sstatus->dex) / 3);
- RE_LVL_DMOD(100);
- break;
- case LG_OVERBRAND_PLUSATK:
- skillratio = 150 * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case LG_RAYOFGENESIS:
- skillratio = skillratio + 200 + 300 * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case LG_EARTHDRIVE:
- skillratio = (skillratio + 100) * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case LG_HESPERUSLIT:
- skillratio += 120 * skill_lv - 100;
- break;
- case SR_DRAGONCOMBO:
- skillratio += 40 * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case SR_SKYNETBLOW:
- //ATK [{(Skill Level x 80) + (Caster AGI)} x Caster Base Level / 100] %
- skillratio = 80 * skill_lv + sstatus->agi;
- if (sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_DRAGONCOMBO) //ATK [{(Skill Level x 100) + (Caster AGI) + 150} x Caster Base Level / 100] %
- skillratio = 100 * skill_lv + sstatus->agi + 150;
- RE_LVL_DMOD(100);
- break;
- case SR_EARTHSHAKER:
- if (tsc && (tsc->data[SC_HIDING] || tsc->data[SC_CLOAKING] || // [(Skill Level x 150) x (Caster Base Level / 100) + (Caster INT x 3)] %
- tsc->data[SC_CHASEWALK] || tsc->data[SC_CLOAKINGEXCEED] || tsc->data[SC__INVISIBILITY])) {
- skillratio = 150 * skill_lv;
- RE_LVL_DMOD(100);
- skillratio += sstatus->int_ * 3;
- } else { //[(Skill Level x 50) x (Caster Base Level / 100) + (Caster INT x 2)] %
- skillratio += 50 * (skill_lv-2);
- RE_LVL_DMOD(100);
- skillratio += sstatus->int_ * 2;
- }
- break;
- case SR_FALLENEMPIRE:// ATK [(Skill Level x 150 + 100) x Caster Base Level / 150] %
- skillratio += 150 *skill_lv;
- RE_LVL_DMOD(150);
- break;
- case SR_TIGERCANNON: { // ATK [((Caster consumed HP + SP) / 4) x Caster Base Level / 100] %
- int hp = sstatus->max_hp * (10 + 2 * skill_lv) / 100,
- sp = sstatus->max_sp * (6 + skill_lv) / 100;
- skillratio = (hp+sp) / 4;
- if (sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE) // ATK [((Caster consumed HP + SP) / 2) x Caster Base Level / 100] %
- skillratio = (hp+sp) / 2;
- RE_LVL_DMOD(100);
- }
- break;
- case SR_RAMPAGEBLASTER:
- skillratio += 20 * skill_lv * (sd?sd->spiritball_old:5) - 100;
- if (sc && sc->data[SC_EXPLOSIONSPIRITS]) {
- skillratio += sc->data[SC_EXPLOSIONSPIRITS]->val1 * 20;
- RE_LVL_DMOD(120);
- } else
- RE_LVL_DMOD(150);
- break;
- case SR_KNUCKLEARROW:
- if (wflag&4) { // ATK [(Skill Level x 150) + (1000 x Target current weight / Maximum weight) + (Target Base Level x 5) x (Caster Base Level / 150)] %
- skillratio = 150 * skill_lv + status_get_lv(target) * 5 * (status_get_lv(src) / 100) ;
- if (tsd && tsd->weight)
- skillratio += 100 * (tsd->weight / tsd->max_weight);
- } else // ATK [(Skill Level x 100 + 500) x Caster Base Level / 100] %
- skillratio += 400 + (100 * skill_lv);
- RE_LVL_DMOD(100);
- break;
- case SR_WINDMILL: // ATK [(Caster Base Level + Caster DEX) x Caster Base Level / 100] %
- skillratio = status_get_lv(src) + sstatus->dex;
- RE_LVL_DMOD(100);
- break;
- case SR_GATEOFHELL:
- if (sc && sc->data[SC_COMBO]
- && sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE)
- skillratio += 800 * skill_lv -100;
- else
- skillratio += 500 * skill_lv -100;
- RE_LVL_DMOD(100);
- break;
- case SR_GENTLETOUCH_QUIET:
- skillratio += 100 * skill_lv - 100 + sstatus->dex;
- RE_LVL_DMOD(100);
- break;
- case SR_HOWLINGOFLION:
- skillratio += 300 * skill_lv - 100;
- RE_LVL_DMOD(150);
- break;
- case SR_RIDEINLIGHTNING: // ATK [{(Skill Level x 200) + Additional Damage} x Caster Base Level / 100] %
- if ((sstatus->rhw.ele) == ELE_WIND || (sstatus->lhw.ele) == ELE_WIND)
- skillratio += skill_lv * 50;
- skillratio += -100 + 200 * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case WM_REVERBERATION_MELEE:
- // ATK [{(Skill Level x 100) + 300} x Caster Base Level / 100]
- skillratio += 200 + 100 * pc_checkskill(sd, WM_REVERBERATION);
- RE_LVL_DMOD(100);
- break;
- case WM_SEVERE_RAINSTORM_MELEE:
- skillratio = 50 + 50 * skill_lv;
- break;
- case WM_GREAT_ECHO:
- skillratio += 800 + 100 * skill_lv;
- if (sd) { // Still need official value [pakpil]
- short lv = (short)skill_lv;
- skillratio += 100 * skill_check_pc_partner(sd,skill_num,&lv,skill_get_splash(skill_num,skill_lv),0);
- }
- break;
- case WM_SOUND_OF_DESTRUCTION:
- skillratio += 400;
- break;
- case GN_CART_TORNADO:
- // ATK [( Skill Level x 50 ) + ( Cart Weight / ( 150 - Caster Base STR ))] + ( Cart Remodeling Skill Level x 50 )] %
- skillratio = 50 * skill_lv;
- if (sd && sd->cart_weight)
- skillratio += sd->cart_weight/10 / max(150-sstatus->str,1) + pc_checkskill(sd, GN_REMODELING_CART) * 50;
- break;
- case GN_CARTCANNON:
- // ATK [{( Cart Remodeling Skill Level x 50 ) x ( INT / 40 )} + ( Cart Cannon Skill Level x 60 )] %
- skillratio = 60 * skill_lv;
- if (sd) skillratio += pc_checkskill(sd, GN_REMODELING_CART) * 50 * (sstatus->int_ / 40);
- break;
- case GN_SPORE_EXPLOSION:
- skillratio += 200 + 100 * skill_lv;
- break;
- case GN_CRAZYWEED_ATK:
- skillratio += 400 + 100 * skill_lv;
- break;
- case GN_SLINGITEM_RANGEMELEEATK:
- if (sd) {
- switch (sd->itemid) {
- case 13260: // Apple Bomob
- case 13261: // Coconut Bomb
- case 13262: // Melon Bomb
- case 13263: // Pinapple Bomb
- skillratio += 400; // Unconfirded
- break;
- case 13264: // Banana Bomb 2000%
- skillratio += 1900;
- break;
- case 13265:
- skillratio -= 75;
- break; // Black Lump 25%
- case 13266:
- skillratio -= 25;
- break; // Hard Black Lump 75%
- case 13267:
- skillratio += 100;
- break; // Extremely Hard Black Lump 200%
- }
- } else
- skillratio += 300; // Bombs
- break;
- case SO_VARETYR_SPEAR: //Assumed Formula.
- skillratio += -100 + 200 * (sd ? pc_checkskill(sd, SA_LIGHTNINGLOADER) : 1);
- if (sc && sc->data[SC_BLAST_OPTION])
- skillratio += skillratio * sc->data[SC_BLAST_OPTION]->val2 / 100;
- break;
- // Physical Elemantal Spirits Attack Skills
- case EL_CIRCLE_OF_FIRE:
- case EL_FIRE_BOMB_ATK:
- case EL_STONE_RAIN:
- skillratio += 200;
- break;
- case EL_FIRE_WAVE_ATK:
- skillratio += 500;
- break;
- case EL_TIDAL_WEAPON:
- skillratio += 1400;
- break;
- case EL_WIND_SLASH:
- skillratio += 100;
- break;
- case EL_HURRICANE:
- skillratio += 600;
- break;
- case EL_TYPOON_MIS:
- case EL_WATER_SCREW_ATK:
- skillratio += 900;
- break;
- case EL_STONE_HAMMER:
- skillratio += 400;
- break;
- case EL_ROCK_CRUSHER:
- skillratio += 700;
- break;
- case KO_JYUMONJIKIRI:
- if (tsc && tsc->data[SC_JYUMONJIKIRI])
- wd.div_ = wd.div_ * -1;// needs more info
- skillratio += -100 + 150 * skill_lv;
- case KO_HUUMARANKA:
- skillratio += -100 + 150 * skill_lv + sstatus->dex/2 + sstatus->agi/2; // needs more info
- break;
- case KO_SETSUDAN:
- skillratio += 100 * (skill_lv-1);
- break;
- case KO_BAKURETSU:
- skillratio = 50 * skill_lv * (sd?pc_checkskill(sd,NJ_TOBIDOUGU):10);
- break;
- case MH_NEEDLE_OF_PARALYZE:
- skillratio += 600 + 100 * skill_lv;
- break;
- case MH_STAHL_HORN:
- skillratio += 400 + 100 * skill_lv;
- break;
- case MH_LAVA_SLIDE:
- skillratio = 70 * skill_lv;
- break;
- case MH_MAGMA_FLOW:
- skillratio += -100 + 100 * skill_lv;
- break;
- }
+ case ASC_METEORASSAULT:
+ skillratio += 40*skill_lv-60;
+ break;
+ case SN_SHARPSHOOTING:
+ case MA_SHARPSHOOTING:
+ skillratio += 100+50*skill_lv;
+ break;
+ case CG_ARROWVULCAN:
+ skillratio += 100+100*skill_lv;
+ break;
+ case AS_SPLASHER:
+ skillratio += 400+50*skill_lv;
+ if(sd)
+ skillratio += 20 * pc_checkskill(sd,AS_POISONREACT);
+ break;
+ case ASC_BREAKER:
+ skillratio += 100*skill_lv-100;
+ break;
+ case PA_SACRIFICE:
+ skillratio += 10*skill_lv-10;
+ break;
+ case PA_SHIELDCHAIN:
+ skillratio += 30*skill_lv;
+ break;
+ case WS_CARTTERMINATION:
+ i = 10 * (16 - skill_lv);
+ if (i < 1) i = 1;
+ //Preserve damage ratio when max cart weight is changed.
+ if(sd && sd->cart_weight)
+ skillratio += sd->cart_weight/i * 80000/battle_config.max_cart_weight - 100;
+ else if (!sd)
+ skillratio += 80000 / i - 100;
+ break;
+ case TK_DOWNKICK:
+ skillratio += 60 + 20*skill_lv;
+ break;
+ case TK_STORMKICK:
+ skillratio += 60 + 20*skill_lv;
+ break;
+ case TK_TURNKICK:
+ skillratio += 90 + 30*skill_lv;
+ break;
+ case TK_COUNTER:
+ skillratio += 90 + 30*skill_lv;
+ break;
+ case TK_JUMPKICK:
+ skillratio += -70 + 10*skill_lv;
+ if (sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == skill_num)
+ skillratio += 10*status_get_lv(src)/3; //Tumble bonus
+ if (wflag)
+ {
+ skillratio += 10*status_get_lv(src)/3; //Running bonus (TODO: What is the real bonus?)
+ if( sc && sc->data[SC_SPURT] ) // Spurt bonus
+ skillratio *= 2;
+ }
+ break;
+ case GS_TRIPLEACTION:
+ skillratio += 50*skill_lv;
+ break;
+ case GS_BULLSEYE:
+ //Only works well against brute/demihumans non bosses.
+ if((tstatus->race == RC_BRUTE || tstatus->race == RC_DEMIHUMAN)
+ && !(tstatus->mode&MD_BOSS))
+ skillratio += 400;
+ break;
+ case GS_TRACKING:
+ skillratio += 100 *(skill_lv+1);
+ break;
+ case GS_PIERCINGSHOT:
+ skillratio += 20*skill_lv;
+ break;
+ case GS_RAPIDSHOWER:
+ skillratio += 10*skill_lv;
+ break;
+ case GS_DESPERADO:
+ skillratio += 50*(skill_lv-1);
+ break;
+ case GS_DUST:
+ skillratio += 50*skill_lv;
+ break;
+ case GS_FULLBUSTER:
+ skillratio += 100*(skill_lv+2);
+ break;
+ case GS_SPREADATTACK:
+ #ifdef RENEWAL
+ skillratio += 20*(skill_lv);
+ #else
+ skillratio += 20*(skill_lv-1);
+ #endif
+ break;
+ case NJ_HUUMA:
+ skillratio += 50 + 150*skill_lv;
+ break;
+ case NJ_TATAMIGAESHI:
+ skillratio += 10*skill_lv;
+ break;
+ case NJ_KASUMIKIRI:
+ skillratio += 10*skill_lv;
+ break;
+ case NJ_KIRIKAGE:
+ skillratio += 100*(skill_lv-1);
+ break;
+ case KN_CHARGEATK:
+ {
+ int k = (wflag-1)/3; //+100% every 3 cells of distance
+ if( k > 2 ) k = 2; // ...but hard-limited to 300%.
+ skillratio += 100 * k;
+ }
+ break;
+ case HT_PHANTASMIC:
+ skillratio += 50;
+ break;
+ case MO_BALKYOUNG:
+ skillratio += 200;
+ break;
+ case HFLI_MOON: //[orn]
+ skillratio += 10+110*skill_lv;
+ break;
+ case HFLI_SBR44: //[orn]
+ skillratio += 100 *(skill_lv-1);
+ break;
+ case NPC_VAMPIRE_GIFT:
+ skillratio += ((skill_lv-1)%5+1)*100;
+ break;
+ case RK_SONICWAVE:
+ skillratio += 400 + 100 * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case RK_HUNDREDSPEAR:
+ skillratio += 500 + (80 * skill_lv);
+ if( sd )
+ {
+ short index = sd->equip_index[EQI_HAND_R];
+ if( index >= 0 && sd->inventory_data[index]
+ && sd->inventory_data[index]->type == IT_WEAPON )
+ skillratio += max(10000 - sd->inventory_data[index]->weight, 0) / 10;
+ skillratio += 50 * pc_checkskill(sd,LK_SPIRALPIERCE);
+ } // (1 + [(Casters Base Level - 100) / 200])
+ skillratio = skillratio * (100 + (status_get_lv(src)-100) / 2) / 100;
+ break;
+ case RK_WINDCUTTER:
+ skillratio += 50 * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case RK_IGNITIONBREAK:
+ i = distance_bl(src,target);
+ if( i < 2 )
+ skillratio = 200 + 200 * skill_lv;
+ else if( i < 4 )
+ skillratio = 100 + 200 * skill_lv;
+ else
+ skillratio = 100 + 100 * skill_lv;
+ RE_LVL_DMOD(100);
+ if( sstatus->rhw.ele == ELE_FIRE )
+ skillratio += skillratio / 2;
+ break;
+ case RK_CRUSHSTRIKE:
+ if( sd )
+ {//ATK [{Weapon Level * (Weapon Upgrade Level + 6) * 100} + (Weapon ATK) + (Weapon Weight)]%
+ short index = sd->equip_index[EQI_HAND_R];
+ if( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_WEAPON )
+ skillratio = sd->inventory_data[index]->weight/10 + sstatus->rhw.atk +
+ 100 * sd->inventory_data[index]->wlv * (sd->status.inventory[index].refine + 6);
+ }
+ break;
+ case RK_STORMBLAST:
+ skillratio = 100 * (sd ? pc_checkskill(sd,RK_RUNEMASTERY) : 1) + 100 * (sstatus->int_ / 4);
+ break;
+ case RK_PHANTOMTHRUST:
+ skillratio = 50 * skill_lv + 10 * ( sd ? pc_checkskill(sd,KN_SPEARMASTERY) : 10);
+ //if( s_level > 100 ) skillratio += skillratio * s_level / 150; // Base level bonus. This is official, but is disabled until I can confirm something with was changed or not. [Rytech]
+ //if( s_level > 100 ) skillratio += skillratio * (s_level - 100) / 200; // Base level bonus.
+ break;
+ /**
+ * GC Guilotine Cross
+ **/
+ case GC_CROSSIMPACT:
+ skillratio += 900 + 100 * skill_lv;
+ RE_LVL_DMOD(120);
+ break;
+ case GC_PHANTOMMENACE:
+ skillratio += 200;
+ break;
+ case GC_COUNTERSLASH:
+ //ATK [{(Skill Level x 100) + 300} x Caster's Base Level / 120]% + ATK [(AGI x 2) + (Caster's Job Level x 4)]%
+ skillratio += 200 + (100 * skill_lv);
+ RE_LVL_DMOD(120);
+ skillratio += sstatus->agi + (sd?sd->status.job_level:0) * 4;
+ break;
+ case GC_ROLLINGCUTTER:
+ skillratio += -50 + 50 * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case GC_CROSSRIPPERSLASHER:
+ skillratio += 300 + 80 * skill_lv;
+ RE_LVL_DMOD(100);
+ if( sc && sc->data[SC_ROLLINGCUTTER] )
+ skillratio += sc->data[SC_ROLLINGCUTTER]->val1 * sstatus->agi;
+ break;
+ /**
+ * Arch Bishop
+ **/
+ case AB_DUPLELIGHT_MELEE:
+ skillratio += 10 * skill_lv;
+ break;
+ /**
+ * Ranger
+ **/
+ case RA_ARROWSTORM:
+ skillratio += 900 + 80 * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case RA_AIMEDBOLT:
+ skillratio += 400 + 50 * skill_lv;
+ RE_LVL_DMOD(100);
+ if( tsc && (tsc->data[SC_BITE] || tsc->data[SC_ANKLE] || tsc->data[SC_ELECTRICSHOCKER]) )
+ wd.div_ = tstatus->size + 2 + ( (rnd()%100 < 50-tstatus->size*10) ? 1 : 0 );
+ break;
+ case RA_CLUSTERBOMB:
+ skillratio += 100 + 100 * skill_lv;
+ break;
+ case RA_WUGDASH:// ATK 300%
+ skillratio += 200;
+ break;
+ case RA_WUGSTRIKE:
+ skillratio = 200 * skill_lv;
+ break;
+ case RA_WUGBITE:
+ skillratio += 300 + 200 * skill_lv;
+ if ( skill_lv == 5 ) skillratio += 100;
+ break;
+ case RA_SENSITIVEKEEN:
+ skillratio += 50 * skill_lv;
+ break;
+ /**
+ * Mechanic
+ **/
+ case NC_BOOSTKNUCKLE:
+ skillratio += 100 + 100 * skill_lv + sstatus->dex;
+ RE_LVL_DMOD(100);
+ break;
+ case NC_PILEBUNKER:
+ skillratio += 200 + 100 * skill_lv + sstatus->str;
+ RE_LVL_DMOD(100);
+ break;
+ case NC_VULCANARM:
+ skillratio = 70 * skill_lv + sstatus->dex;
+ RE_LVL_DMOD(100);
+ break;
+ case NC_FLAMELAUNCHER:
+ case NC_COLDSLOWER:
+ skillratio += 200 + 300 * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case NC_ARMSCANNON:
+ switch( tstatus->size ) {
+ case SZ_SMALL: skillratio += 100 + 500 * skill_lv; break;// Small
+ case SZ_MEDIUM: skillratio += 100 + 400 * skill_lv; break;// Medium
+ case SZ_BIG: skillratio += 100 + 300 * skill_lv; break;// Large
+ }
+ RE_LVL_DMOD(100);
+ //NOTE: Their's some other factors that affects damage, but not sure how exactly. Will recheck one day. [Rytech]
+ break;
+ case NC_AXEBOOMERANG:
+ skillratio += 60 + 40 * skill_lv;
+ if( sd ) {
+ short index = sd->equip_index[EQI_HAND_R];
+ if( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_WEAPON )
+ skillratio += sd->inventory_data[index]->weight / 10;// Weight is divided by 10 since 10 weight in coding make 1 whole actural weight. [Rytech]
+ }
+ RE_LVL_DMOD(100);
+ break;
+ case NC_POWERSWING:
+ skillratio += 80 + 20 * skill_lv + sstatus->str + sstatus->dex;
+ RE_LVL_DMOD(100);
+ break;
+ case NC_AXETORNADO:
+ skillratio += 100 + 100 * skill_lv + sstatus->vit;
+ RE_LVL_DMOD(100);
+ break;
+ case SC_FATALMENACE:
+ skillratio += 100 * skill_lv;
+ break;
+ case SC_TRIANGLESHOT:
+ skillratio += 270 + 30 * skill_lv;
+ break;
+ case SC_FEINTBOMB:
+ skillratio += 100 + 100 * skill_lv;
+ break;
+ case LG_CANNONSPEAR:// Stimated formula. Still need confirm it.
+ skillratio += -100 + (50 + sstatus->str) * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case LG_BANISHINGPOINT:
+ skillratio += -100 + ((50 * skill_lv) + (30 * ((sd)?pc_checkskill(sd,SM_BASH):1)));
+ RE_LVL_DMOD(100);
+ break;
+ case LG_SHIELDPRESS:
+ skillratio += 60 + 43 * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case LG_PINPOINTATTACK:
+ skillratio = ((100 * skill_lv) + (10 * status_get_agi(src)) );
+ RE_LVL_DMOD(100);
+ break;
+ case LG_RAGEBURST:
+ if( sd && sd->spiritball_old )
+ skillratio += -100 + (sd->spiritball_old * 200);
+ else
+ skillratio += -100 + 15 * 200;
+ RE_LVL_DMOD(100);
+ break;
+ case LG_SHIELDSPELL:// [(Casters Base Level x 4) + (Shield DEF x 10) + (Casters VIT x 2)] %
+ if( sd ) {
+ struct item_data *shield_data = sd->inventory_data[sd->equip_index[EQI_HAND_L]];
+ skillratio = status_get_lv(src) * 4 + status_get_vit(src) * 2;
+ if( shield_data )
+ skillratio += shield_data->def * 10;
+ } else
+ skillratio += 2400; //2500%
+ break;
+ case LG_MOONSLASHER:
+ skillratio += -100 + (120 * skill_lv + ((sd) ? pc_checkskill(sd,LG_OVERBRAND) : 5) * 80);
+ RE_LVL_DMOD(100);
+ break;
+ case LG_OVERBRAND:
+ skillratio = 400 * skill_lv + (pc_checkskill(sd,CR_SPEARQUICKEN) * 30);
+ RE_LVL_DMOD(100);
+ break;
+ case LG_OVERBRAND_BRANDISH:
+ skillratio = 300 * skill_lv + (2 * (sstatus->str + sstatus->dex) / 3);
+ RE_LVL_DMOD(100);
+ break;
+ case LG_OVERBRAND_PLUSATK:
+ skillratio = 150 * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case LG_RAYOFGENESIS:
+ skillratio = skillratio + 200 + 300 * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case LG_EARTHDRIVE:
+ skillratio = (skillratio + 100) * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case LG_HESPERUSLIT:
+ skillratio += 120 * skill_lv - 100;
+ break;
+ case SR_DRAGONCOMBO:
+ skillratio += 40 * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case SR_SKYNETBLOW:
+ //ATK [{(Skill Level x 80) + (Caster AGI)} x Caster Base Level / 100] %
+ skillratio = 80 * skill_lv + sstatus->agi;
+ if( sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_DRAGONCOMBO )//ATK [{(Skill Level x 100) + (Caster AGI) + 150} x Caster Base Level / 100] %
+ skillratio = 100 * skill_lv + sstatus->agi + 150;
+ RE_LVL_DMOD(100);
+ break;
+ case SR_EARTHSHAKER:
+ if( tsc && (tsc->data[SC_HIDING] || tsc->data[SC_CLOAKING] || // [(Skill Level x 150) x (Caster Base Level / 100) + (Caster INT x 3)] %
+ tsc->data[SC_CHASEWALK] || tsc->data[SC_CLOAKINGEXCEED] || tsc->data[SC__INVISIBILITY]) ){
+ skillratio = 150 * skill_lv;
+ RE_LVL_DMOD(100);
+ skillratio += sstatus->int_ * 3;
+ }else{ //[(Skill Level x 50) x (Caster Base Level / 100) + (Caster INT x 2)] %
+ skillratio += 50 * (skill_lv-2);
+ RE_LVL_DMOD(100);
+ skillratio += sstatus->int_ * 2;
+ }
+ break;
+ case SR_FALLENEMPIRE:// ATK [(Skill Level x 150 + 100) x Caster Base Level / 150] %
+ skillratio += 150 *skill_lv;
+ RE_LVL_DMOD(150);
+ break;
+ case SR_TIGERCANNON:// ATK [((Caster consumed HP + SP) / 4) x Caster Base Level / 100] %
+ {
+ int hp = sstatus->max_hp * (10 + 2 * skill_lv) / 100,
+ sp = sstatus->max_sp * (6 + skill_lv) / 100;
+ skillratio = (hp+sp) / 4;
+ if( sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE ) // ATK [((Caster consumed HP + SP) / 2) x Caster Base Level / 100] %
+ skillratio = (hp+sp) / 2;
+ RE_LVL_DMOD(100);
+ }
+ break;
+ case SR_RAMPAGEBLASTER:
+ skillratio += 20 * skill_lv * (sd?sd->spiritball_old:5) - 100;
+ if( sc && sc->data[SC_EXPLOSIONSPIRITS] ){
+ skillratio += sc->data[SC_EXPLOSIONSPIRITS]->val1 * 20;
+ RE_LVL_DMOD(120);
+ }else
+ RE_LVL_DMOD(150);
+ break;
+ case SR_KNUCKLEARROW:
+ if( wflag&4 ){ // ATK [(Skill Level x 150) + (1000 x Target current weight / Maximum weight) + (Target Base Level x 5) x (Caster Base Level / 150)] %
+ skillratio = 150 * skill_lv + status_get_lv(target) * 5 * (status_get_lv(src) / 100) ;
+ if( tsd && tsd->weight )
+ skillratio += 100 * (tsd->weight / tsd->max_weight);
+ }else // ATK [(Skill Level x 100 + 500) x Caster Base Level / 100] %
+ skillratio += 400 + (100 * skill_lv);
+ RE_LVL_DMOD(100);
+ break;
+ case SR_WINDMILL: // ATK [(Caster Base Level + Caster DEX) x Caster Base Level / 100] %
+ skillratio = status_get_lv(src) + sstatus->dex;
+ RE_LVL_DMOD(100);
+ break;
+ case SR_GATEOFHELL:
+ if( sc && sc->data[SC_COMBO]
+ && sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE )
+ skillratio += 800 * skill_lv -100;
+ else
+ skillratio += 500 * skill_lv -100;
+ RE_LVL_DMOD(100);
+ break;
+ case SR_GENTLETOUCH_QUIET:
+ skillratio += 100 * skill_lv - 100 + sstatus->dex;
+ RE_LVL_DMOD(100);
+ break;
+ case SR_HOWLINGOFLION:
+ skillratio += 300 * skill_lv - 100;
+ RE_LVL_DMOD(150);
+ break;
+ case SR_RIDEINLIGHTNING: // ATK [{(Skill Level x 200) + Additional Damage} x Caster Base Level / 100] %
+ if( (sstatus->rhw.ele) == ELE_WIND || (sstatus->lhw.ele) == ELE_WIND )
+ skillratio += skill_lv * 50;
+ skillratio += -100 + 200 * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case WM_REVERBERATION_MELEE:
+ // ATK [{(Skill Level x 100) + 300} x Caster Base Level / 100]
+ skillratio += 200 + 100 * pc_checkskill(sd, WM_REVERBERATION);
+ RE_LVL_DMOD(100);
+ break;
+ case WM_SEVERE_RAINSTORM_MELEE:
+ skillratio = 50 + 50 * skill_lv;
+ break;
+ case WM_GREAT_ECHO:
+ skillratio += 800 + 100 * skill_lv;
+ if( sd ) { // Still need official value [pakpil]
+ short lv = (short)skill_lv;
+ skillratio += 100 * skill_check_pc_partner(sd,skill_num,&lv,skill_get_splash(skill_num,skill_lv),0);
+ }
+ break;
+ case WM_SOUND_OF_DESTRUCTION:
+ skillratio += 400;
+ break;
+ case GN_CART_TORNADO:
+ // ATK [( Skill Level x 50 ) + ( Cart Weight / ( 150 - Caster Base STR ))] + ( Cart Remodeling Skill Level x 50 )] %
+ skillratio = 50 * skill_lv;
+ if( sd && sd->cart_weight)
+ skillratio += sd->cart_weight/10 / max(150-sstatus->str,1) + pc_checkskill(sd, GN_REMODELING_CART) * 50;
+ break;
+ case GN_CARTCANNON:
+ // ATK [{( Cart Remodeling Skill Level x 50 ) x ( INT / 40 )} + ( Cart Cannon Skill Level x 60 )] %
+ skillratio = 60 * skill_lv;
+ if( sd ) skillratio += pc_checkskill(sd, GN_REMODELING_CART) * 50 * (sstatus->int_ / 40);
+ break;
+ case GN_SPORE_EXPLOSION:
+ skillratio += 200 + 100 * skill_lv;
+ break;
+ case GN_CRAZYWEED_ATK:
+ skillratio += 400 + 100 * skill_lv;
+ break;
+ case GN_SLINGITEM_RANGEMELEEATK:
+ if( sd ) {
+ switch( sd->itemid ) {
+ case 13260: // Apple Bomob
+ case 13261: // Coconut Bomb
+ case 13262: // Melon Bomb
+ case 13263: // Pinapple Bomb
+ skillratio += 400; // Unconfirded
+ break;
+ case 13264: // Banana Bomb 2000%
+ skillratio += 1900;
+ break;
+ case 13265: skillratio -= 75; break; // Black Lump 25%
+ case 13266: skillratio -= 25; break; // Hard Black Lump 75%
+ case 13267: skillratio += 100; break; // Extremely Hard Black Lump 200%
+ }
+ } else
+ skillratio += 300; // Bombs
+ break;
+ case SO_VARETYR_SPEAR: //Assumed Formula.
+ skillratio += -100 + 200 * ( sd ? pc_checkskill(sd, SA_LIGHTNINGLOADER) : 1 );
+ if( sc && sc->data[SC_BLAST_OPTION] )
+ skillratio += skillratio * sc->data[SC_BLAST_OPTION]->val2 / 100;
+ break;
+ // Physical Elemantal Spirits Attack Skills
+ case EL_CIRCLE_OF_FIRE:
+ case EL_FIRE_BOMB_ATK:
+ case EL_STONE_RAIN:
+ skillratio += 200;
+ break;
+ case EL_FIRE_WAVE_ATK:
+ skillratio += 500;
+ break;
+ case EL_TIDAL_WEAPON:
+ skillratio += 1400;
+ break;
+ case EL_WIND_SLASH:
+ skillratio += 100;
+ break;
+ case EL_HURRICANE:
+ skillratio += 600;
+ break;
+ case EL_TYPOON_MIS:
+ case EL_WATER_SCREW_ATK:
+ skillratio += 900;
+ break;
+ case EL_STONE_HAMMER:
+ skillratio += 400;
+ break;
+ case EL_ROCK_CRUSHER:
+ skillratio += 700;
+ break;
+ case KO_JYUMONJIKIRI:
+ if( tsc && tsc->data[SC_JYUMONJIKIRI] )
+ wd.div_ = wd.div_ * -1;// needs more info
+ skillratio += -100 + 150 * skill_lv;
+ case KO_HUUMARANKA:
+ skillratio += -100 + 150 * skill_lv + sstatus->dex/2 + sstatus->agi/2; // needs more info
+ break;
+ case KO_SETSUDAN:
+ skillratio += 100 * (skill_lv-1);
+ break;
+ case KO_BAKURETSU:
+ skillratio = 50 * skill_lv * (sd?pc_checkskill(sd,NJ_TOBIDOUGU):10);
+ break;
+ case MH_NEEDLE_OF_PARALYZE:
+ skillratio += 600 + 100 * skill_lv;
+ break;
+ case MH_STAHL_HORN:
+ skillratio += 400 + 100 * skill_lv;
+ break;
+ case MH_LAVA_SLIDE:
+ skillratio = 70 * skill_lv;
+ break;
+ case MH_MAGMA_FLOW:
+ skillratio += -100 + 100 * skill_lv;
+ break;
+ }
- ATK_RATE(skillratio);
-
- //Constant/misc additions from skills
- switch (skill_num) {
- case MO_EXTREMITYFIST:
- ATK_ADD(250 + 150*skill_lv);
- break;
- case TK_DOWNKICK:
- case TK_STORMKICK:
- case TK_TURNKICK:
- case TK_COUNTER:
- case TK_JUMPKICK:
- //TK_RUN kick damage bonus.
- if (sd && sd->weapontype1 == W_FIST && sd->weapontype2 == W_FIST)
- ATK_ADD(10*pc_checkskill(sd, TK_RUN));
- break;
- case GS_MAGICALBULLET:
- if (sstatus->matk_max>sstatus->matk_min) {
- ATK_ADD(sstatus->matk_min+rnd()%(sstatus->matk_max-sstatus->matk_min));
- } else {
- ATK_ADD(sstatus->matk_min);
- }
- break;
- case NJ_SYURIKEN:
- ATK_ADD(4*skill_lv);
- break;
- case HT_FREEZINGTRAP:
- if (sd)
- ATK_ADD(40 * pc_checkskill(sd, RA_RESEARCHTRAP));
- break;
- case RA_WUGDASH ://(Caster Current Weight x 10 / 8)
- if (sd && sd->weight)
- ATK_ADD(sd->weight / 8);
- case RA_WUGSTRIKE:
- case RA_WUGBITE:
- if (sd)
- ATK_ADD(30*pc_checkskill(sd, RA_TOOTHOFWUG));
- break;
- case LG_RAYOFGENESIS:
- if (sc && sc->data[SC_BANDING]) { // Increase only if the RG is under Banding.
- short lv = (short)skill_lv;
- ATK_ADDRATE(190 * ((sd) ? skill_check_pc_partner(sd,(short)skill_num,&lv,skill_get_splash(skill_num,skill_lv),0) : 1));
- }
- break;
- case SR_GATEOFHELL:
- ATK_ADD(sstatus->max_hp - status_get_hp(src));
- if (sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE) {
- ATK_ADD((sstatus->sp * (1 + skill_lv * 2 / 10)) + 10 * status_get_lv(src));
- } else {
- ATK_ADD((sstatus->max_sp * (1 + skill_lv * 2 / 10)) + 40 * status_get_lv(src));
- }
- break;
- case SR_TIGERCANNON: // (Tiger Cannon skill level x 240) + (Target Base Level x 40)
- ATK_ADD(skill_lv * 240 + status_get_lv(target) * 40);
- if (sc && sc->data[SC_COMBO]
- && sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE) // (Tiger Cannon skill level x 500) + (Target Base Level x 40)
- ATK_ADD(skill_lv * 500 + status_get_lv(target) * 40);
- break;
- case SR_FALLENEMPIRE:// [(Target Size value + Skill Level - 1) x Caster STR] + [(Target current weight x Caster DEX / 120)]
- ATK_ADD(((tstatus->size+1)*2 + skill_lv - 1) * sstatus->str);
- if (tsd && tsd->weight) {
- ATK_ADD((tsd->weight/10) * sstatus->dex / 120);
- } else {
- ATK_ADD(status_get_lv(target) * 50); //mobs
- }
- break;
- case KO_SETSUDAN:
- if (tsc && tsc->data[SC_SPIRIT]) {
- ATK_ADDRATE(10*tsc->data[SC_SPIRIT]->val1);// +10% custom value.
- status_change_end(target,SC_SPIRIT,INVALID_TIMER);
- }
- break;
- case KO_KAIHOU:
- if (sd) {
- ARR_FIND(1, 6, i, sd->talisman[i] > 0);
- if (i < 5) {
- s_ele = i;
- ATK_ADDRATE(100 * sd->talisman[i]);// +100% custom value.
- pc_del_talisman(sd, sd->talisman[i], i);
- }
- }
- break;
- }
- }
- //Div fix.
- damage_div_fix(wd.damage, wd.div_);
-
- //The following are applied on top of current damage and are stackable.
- if (sc) {
- if (sc->data[SC_TRUESIGHT])
- ATK_ADDRATE(2*sc->data[SC_TRUESIGHT]->val1);
- if (sc->data[SC_GLOOMYDAY_SK] &&
- (skill_num == LK_SPIRALPIERCE || skill_num == KN_BRANDISHSPEAR ||
- skill_num == CR_SHIELDBOOMERANG || skill_num == PA_SHIELDCHAIN ||
- skill_num == LG_SHIELDPRESS))
- ATK_ADDRATE(sc->data[SC_GLOOMYDAY_SK]->val2);
- if (sc->data[SC_EDP]) {
- switch (skill_num) {
- case AS_SPLASHER:
- case AS_VENOMKNIFE:
- case AS_GRIMTOOTH:
- break;
+ ATK_RATE(skillratio);
+
+ //Constant/misc additions from skills
+ switch (skill_num) {
+ case MO_EXTREMITYFIST:
+ ATK_ADD(250 + 150*skill_lv);
+ break;
+ case TK_DOWNKICK:
+ case TK_STORMKICK:
+ case TK_TURNKICK:
+ case TK_COUNTER:
+ case TK_JUMPKICK:
+ //TK_RUN kick damage bonus.
+ if(sd && sd->weapontype1 == W_FIST && sd->weapontype2 == W_FIST)
+ ATK_ADD(10*pc_checkskill(sd, TK_RUN));
+ break;
+ case GS_MAGICALBULLET:
+ if(sstatus->matk_max>sstatus->matk_min) {
+ ATK_ADD(sstatus->matk_min+rnd()%(sstatus->matk_max-sstatus->matk_min));
+ } else {
+ ATK_ADD(sstatus->matk_min);
+ }
+ break;
+ case NJ_SYURIKEN:
+ ATK_ADD(4*skill_lv);
+ break;
+ case HT_FREEZINGTRAP:
+ if(sd)
+ ATK_ADD( 40 * pc_checkskill(sd, RA_RESEARCHTRAP) );
+ break;
+ case RA_WUGDASH ://(Caster Current Weight x 10 / 8)
+ if( sd && sd->weight )
+ ATK_ADD( sd->weight / 8 );
+ case RA_WUGSTRIKE:
+ case RA_WUGBITE:
+ if(sd)
+ ATK_ADD(30*pc_checkskill(sd, RA_TOOTHOFWUG));
+ break;
+ case LG_RAYOFGENESIS:
+ if( sc && sc->data[SC_BANDING] ) {// Increase only if the RG is under Banding.
+ short lv = (short)skill_lv;
+ ATK_ADDRATE( 190 * ((sd) ? skill_check_pc_partner(sd,(short)skill_num,&lv,skill_get_splash(skill_num,skill_lv),0) : 1));
+ }
+ break;
+ case SR_GATEOFHELL:
+ ATK_ADD (sstatus->max_hp - status_get_hp(src));
+ if(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE){
+ ATK_ADD ( (sstatus->sp * (1 + skill_lv * 2 / 10)) + 10 * status_get_lv(src) );
+ }else{
+ ATK_ADD ( (sstatus->max_sp * (1 + skill_lv * 2 / 10)) + 40 * status_get_lv(src) );
+ }
+ break;
+ case SR_TIGERCANNON: // (Tiger Cannon skill level x 240) + (Target Base Level x 40)
+ ATK_ADD( skill_lv * 240 + status_get_lv(target) * 40 );
+ if( sc && sc->data[SC_COMBO]
+ && sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE ) // (Tiger Cannon skill level x 500) + (Target Base Level x 40)
+ ATK_ADD( skill_lv * 500 + status_get_lv(target) * 40 );
+ break;
+ case SR_FALLENEMPIRE:// [(Target Size value + Skill Level - 1) x Caster STR] + [(Target current weight x Caster DEX / 120)]
+ ATK_ADD( ((tstatus->size+1)*2 + skill_lv - 1) * sstatus->str);
+ if( tsd && tsd->weight ){
+ ATK_ADD( (tsd->weight/10) * sstatus->dex / 120 );
+ }else{
+ ATK_ADD( status_get_lv(target) * 50 ); //mobs
+ }
+ break;
+ case KO_SETSUDAN:
+ if( tsc && tsc->data[SC_SPIRIT] ){
+ ATK_ADDRATE(10*tsc->data[SC_SPIRIT]->val1);// +10% custom value.
+ status_change_end(target,SC_SPIRIT,INVALID_TIMER);
+ }
+ break;
+ case KO_KAIHOU:
+ if( sd ){
+ ARR_FIND(1, 6, i, sd->talisman[i] > 0);
+ if( i < 5 ){
+ s_ele = i;
+ ATK_ADDRATE(100 * sd->talisman[i]);// +100% custom value.
+ pc_del_talisman(sd, sd->talisman[i], i);
+ }
+ }
+ break;
+ }
+ }
+ //Div fix.
+ damage_div_fix(wd.damage, wd.div_);
+
+ //The following are applied on top of current damage and are stackable.
+ if ( sc ) {
+ if( sc->data[SC_TRUESIGHT] )
+ ATK_ADDRATE(2*sc->data[SC_TRUESIGHT]->val1);
+ if( sc->data[SC_GLOOMYDAY_SK] &&
+ ( skill_num == LK_SPIRALPIERCE || skill_num == KN_BRANDISHSPEAR ||
+ skill_num == CR_SHIELDBOOMERANG || skill_num == PA_SHIELDCHAIN ||
+ skill_num == LG_SHIELDPRESS ) )
+ ATK_ADDRATE(sc->data[SC_GLOOMYDAY_SK]->val2);
+ if( sc->data[SC_EDP] ){
+ switch(skill_num){
+ case AS_SPLASHER: case AS_VENOMKNIFE:
+ case AS_GRIMTOOTH:
+ break;
#ifndef RENEWAL_EDP
- case ASC_BREAKER:
- case ASC_METEORASSAULT:
- break;
+ case ASC_BREAKER: case ASC_METEORASSAULT: break;
#else
- case AS_SONICBLOW:
- case ASC_BREAKER:
- case GC_COUNTERSLASH:
- case GC_CROSSIMPACT:
- ATK_RATE(50); // only modifier is halved but still benefit with the damage bonus
+ case AS_SONICBLOW:
+ case ASC_BREAKER:
+ case GC_COUNTERSLASH:
+ case GC_CROSSIMPACT:
+ ATK_RATE(50); // only modifier is halved but still benefit with the damage bonus
#endif
- default:
- ATK_ADDRATE(sc->data[SC_EDP]->val3);
- }
- }
- if (sc->data[SC_STYLE_CHANGE]) {
+ default:
+ ATK_ADDRATE(sc->data[SC_EDP]->val3);
+ }
+ }
+ if(sc->data[SC_STYLE_CHANGE]){
TBL_HOM *hd = BL_CAST(BL_HOM,src);
if (hd) ATK_ADD(hd->spiritball * 3);
}
- }
+ }
- switch (skill_num) {
- case AS_SONICBLOW:
- if (sc && sc->data[SC_SPIRIT] &&
- sc->data[SC_SPIRIT]->val2 == SL_ASSASIN)
- ATK_ADDRATE(map_flag_gvg(src->m)?25:100); //+25% dmg on woe/+100% dmg on nonwoe
-
- if (sd && pc_checkskill(sd,AS_SONICACCEL)>0)
- ATK_ADDRATE(10);
- break;
- case CR_SHIELDBOOMERANG:
- if (sc && sc->data[SC_SPIRIT] &&
- sc->data[SC_SPIRIT]->val2 == SL_CRUSADER)
- ATK_ADDRATE(100);
- break;
- case NC_AXETORNADO:
- if ((sstatus->rhw.ele) == ELE_WIND || (sstatus->lhw.ele) == ELE_WIND)
- ATK_ADDRATE(50);
- break;
- }
+ switch (skill_num) {
+ case AS_SONICBLOW:
+ if (sc && sc->data[SC_SPIRIT] &&
+ sc->data[SC_SPIRIT]->val2 == SL_ASSASIN)
+ ATK_ADDRATE(map_flag_gvg(src->m)?25:100); //+25% dmg on woe/+100% dmg on nonwoe
- if (sd) {
- if (skill_num && (i = pc_skillatk_bonus(sd, skill_num)))
- ATK_ADDRATE(i);
-
- if (skill_num != PA_SACRIFICE && skill_num != MO_INVESTIGATE && skill_num != CR_GRANDCROSS && skill_num != NPC_GRANDDARKNESS && skill_num != PA_SHIELDCHAIN && !flag.cri) {
- //Elemental/Racial adjustments
- if (sd->right_weapon.def_ratio_atk_ele & (1<<tstatus->def_ele) ||
- sd->right_weapon.def_ratio_atk_race & (1<<tstatus->race) ||
- sd->right_weapon.def_ratio_atk_race & (1<<(is_boss(target)?RC_BOSS:RC_NONBOSS))
- )
- flag.pdef = 1;
-
- if (sd->left_weapon.def_ratio_atk_ele & (1<<tstatus->def_ele) ||
- sd->left_weapon.def_ratio_atk_race & (1<<tstatus->race) ||
- sd->left_weapon.def_ratio_atk_race & (1<<(is_boss(target)?RC_BOSS:RC_NONBOSS))
- ) {
- //Pass effect onto right hand if configured so. [Skotlex]
- if (battle_config.left_cardfix_to_right && flag.rh)
- flag.pdef = 1;
- else
- flag.pdef2 = 1;
- }
- }
+ if(sd && pc_checkskill(sd,AS_SONICACCEL)>0)
+ ATK_ADDRATE(10);
+ break;
+ case CR_SHIELDBOOMERANG:
+ if(sc && sc->data[SC_SPIRIT] &&
+ sc->data[SC_SPIRIT]->val2 == SL_CRUSADER)
+ ATK_ADDRATE(100);
+ break;
+ case NC_AXETORNADO:
+ if( (sstatus->rhw.ele) == ELE_WIND || (sstatus->lhw.ele) == ELE_WIND )
+ ATK_ADDRATE(50);
+ break;
+ }
- if (skill_num != CR_GRANDCROSS && skill_num != NPC_GRANDDARKNESS) {
- //Ignore Defense?
- if (!flag.idef && (
- sd->right_weapon.ignore_def_ele & (1<<tstatus->def_ele) ||
- sd->right_weapon.ignore_def_race & (1<<tstatus->race) ||
- sd->right_weapon.ignore_def_race & (is_boss(target)?1<<RC_BOSS:1<<RC_NONBOSS)
- ))
- flag.idef = 1;
-
- if (!flag.idef2 && (
- sd->left_weapon.ignore_def_ele & (1<<tstatus->def_ele) ||
- sd->left_weapon.ignore_def_race & (1<<tstatus->race) ||
- sd->left_weapon.ignore_def_race & (is_boss(target)?1<<RC_BOSS:1<<RC_NONBOSS)
- )) {
- if (battle_config.left_cardfix_to_right && flag.rh) //Move effect to right hand. [Skotlex]
- flag.idef = 1;
- else
- flag.idef2 = 1;
- }
- }
- }
+ if( sd )
+ {
+ if (skill_num && (i = pc_skillatk_bonus(sd, skill_num)))
+ ATK_ADDRATE(i);
+
+ if( skill_num != PA_SACRIFICE && skill_num != MO_INVESTIGATE && skill_num != CR_GRANDCROSS && skill_num != NPC_GRANDDARKNESS && skill_num != PA_SHIELDCHAIN && !flag.cri )
+ { //Elemental/Racial adjustments
+ if( sd->right_weapon.def_ratio_atk_ele & (1<<tstatus->def_ele) ||
+ sd->right_weapon.def_ratio_atk_race & (1<<tstatus->race) ||
+ sd->right_weapon.def_ratio_atk_race & (1<<(is_boss(target)?RC_BOSS:RC_NONBOSS))
+ )
+ flag.pdef = 1;
+
+ if( sd->left_weapon.def_ratio_atk_ele & (1<<tstatus->def_ele) ||
+ sd->left_weapon.def_ratio_atk_race & (1<<tstatus->race) ||
+ sd->left_weapon.def_ratio_atk_race & (1<<(is_boss(target)?RC_BOSS:RC_NONBOSS))
+ )
+ { //Pass effect onto right hand if configured so. [Skotlex]
+ if (battle_config.left_cardfix_to_right && flag.rh)
+ flag.pdef = 1;
+ else
+ flag.pdef2 = 1;
+ }
+ }
- if (!flag.idef || !flag.idef2) {
- //Defense reduction
- short vit_def;
- defType def1 = status_get_def(target); //Don't use tstatus->def1 due to skill timer reductions.
- short def2 = (short)tstatus->def2;
-
- if (sd) {
- i = sd->ignore_def[is_boss(target)?RC_BOSS:RC_NONBOSS];
- i += sd->ignore_def[tstatus->race];
- if (i) {
- if (i > 100) i = 100;
- def1 -= def1 * i / 100;
- def2 -= def2 * i / 100;
- }
- }
+ if (skill_num != CR_GRANDCROSS && skill_num != NPC_GRANDDARKNESS)
+ { //Ignore Defense?
+ if (!flag.idef && (
+ sd->right_weapon.ignore_def_ele & (1<<tstatus->def_ele) ||
+ sd->right_weapon.ignore_def_race & (1<<tstatus->race) ||
+ sd->right_weapon.ignore_def_race & (is_boss(target)?1<<RC_BOSS:1<<RC_NONBOSS)
+ ))
+ flag.idef = 1;
+
+ if (!flag.idef2 && (
+ sd->left_weapon.ignore_def_ele & (1<<tstatus->def_ele) ||
+ sd->left_weapon.ignore_def_race & (1<<tstatus->race) ||
+ sd->left_weapon.ignore_def_race & (is_boss(target)?1<<RC_BOSS:1<<RC_NONBOSS)
+ )) {
+ if(battle_config.left_cardfix_to_right && flag.rh) //Move effect to right hand. [Skotlex]
+ flag.idef = 1;
+ else
+ flag.idef2 = 1;
+ }
+ }
+ }
- if (sc && sc->data[SC_EXPIATIO]) {
- i = 5 * sc->data[SC_EXPIATIO]->val1; // 5% per level
- def1 -= def1 * i / 100;
- def2 -= def2 * i / 100;
- }
+ if (!flag.idef || !flag.idef2)
+ { //Defense reduction
+ short vit_def;
+ defType def1 = status_get_def(target); //Don't use tstatus->def1 due to skill timer reductions.
+ short def2 = (short)tstatus->def2;
- if (tsc && tsc->data[SC_GT_REVITALIZE] && tsc->data[SC_GT_REVITALIZE]->val4)
- def2 += 2 * tsc->data[SC_GT_REVITALIZE]->val4;
+ if( sd )
+ {
+ i = sd->ignore_def[is_boss(target)?RC_BOSS:RC_NONBOSS];
+ i += sd->ignore_def[tstatus->race];
+ if( i )
+ {
+ if( i > 100 ) i = 100;
+ def1 -= def1 * i / 100;
+ def2 -= def2 * i / 100;
+ }
+ }
- if (tsc && tsc->data[SC_CAMOUFLAGE]) {
- i = 5 * (10-tsc->data[SC_CAMOUFLAGE]->val4);
- def1 -= def1 * i / 100;
- def2 -= def2 * i / 100;
- }
+ if( sc && sc->data[SC_EXPIATIO] ){
+ i = 5 * sc->data[SC_EXPIATIO]->val1; // 5% per level
+ def1 -= def1 * i / 100;
+ def2 -= def2 * i / 100;
+ }
- if (battle_config.vit_penalty_type && battle_config.vit_penalty_target&target->type) {
- unsigned char target_count; //256 max targets should be a sane max
- target_count = unit_counttargeted(target);
- if (target_count >= battle_config.vit_penalty_count) {
- if (battle_config.vit_penalty_type == 1) {
- if (!tsc || !tsc->data[SC_STEELBODY])
- 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;
- } else { //Assume type 2
- if (!tsc || !tsc->data[SC_STEELBODY])
- 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;
- }
- }
- if (skill_num == AM_ACIDTERROR) def1 = 0; //Acid Terror ignores only armor defense. [Skotlex]
- if (def2 < 1) def2 = 1;
- }
- //Vitality reduction from rodatazone: http://rodatazone.simgaming.net/mechanics/substats.php#def
- if (tsd) { //Sd vit-eq
- //[VIT*0.5] + rnd([VIT*0.3], max([VIT*0.3],[VIT^2/150]-1))
- vit_def = def2*(def2-15)/150;
- vit_def = def2/2 + (vit_def>0?rnd()%vit_def:0);
-
- if ((battle_check_undead(sstatus->race,sstatus->def_ele) || sstatus->race==RC_DEMON) && //This bonus already doesnt work vs players
- src->type == BL_MOB && (skill=pc_checkskill(tsd,AL_DP)) > 0)
- vit_def += skill*(int)(3 +(tsd->status.base_level+1)*0.04); // submitted by orn
- if (src->type == BL_MOB && (skill=pc_checkskill(tsd,RA_RANGERMAIN))>0 &&
- (sstatus->race == RC_BRUTE || sstatus->race == RC_FISH || sstatus->race == RC_PLANT))
- vit_def += skill*5;
- } else { //Mob-Pet vit-eq
- //VIT + rnd(0,[VIT/20]^2-1)
- vit_def = (def2/20)*(def2/20);
- vit_def = def2 + (vit_def>0?rnd()%vit_def:0);
- }
+ if( tsc && tsc->data[SC_GT_REVITALIZE] && tsc->data[SC_GT_REVITALIZE]->val4 )
+ def2 += 2 * tsc->data[SC_GT_REVITALIZE]->val4;
- if (battle_config.weapon_defense_type) {
- vit_def += def1*battle_config.weapon_defense_type;
- def1 = 0;
- }
-#ifdef RENEWAL
- /**
- * In Renewal 100% damage reduction is 900 DEF
- * Formula: (1+(900-def1)/9)%
- **/
- if (def1 > 900) def1 = 900;
- ATK_RATE2(
- flag.idef ?100:(flag.pdef ?(int)(flag.pdef *(def1+vit_def)):(1+(900-def1)/9)),
- flag.idef2?100:(flag.pdef2?(int)(flag.pdef2*(def1+vit_def)):(1+(900-def1)/9))
- );
-#else
- if (def1 > 100) def1 = 100;
- ATK_RATE2(
- flag.idef ?100:(flag.pdef ?(int)(flag.pdef *(def1+vit_def)):(100-def1)),
- flag.idef2?100:(flag.pdef2?(int)(flag.pdef2*(def1+vit_def)):(100-def1))
- );
-#endif
- ATK_ADD2(
- flag.idef ||flag.pdef ?0:-vit_def,
- flag.idef2||flag.pdef2?0:-vit_def
- );
- }
+ if( tsc && tsc->data[SC_CAMOUFLAGE] ){
+ i = 5 * (10-tsc->data[SC_CAMOUFLAGE]->val4);
+ def1 -= def1 * i / 100;
+ def2 -= def2 * i / 100;
+ }
+
+ if( battle_config.vit_penalty_type && battle_config.vit_penalty_target&target->type ) {
+ unsigned char target_count; //256 max targets should be a sane max
+ target_count = unit_counttargeted(target);
+ if(target_count >= battle_config.vit_penalty_count) {
+ if(battle_config.vit_penalty_type == 1) {
+ if( !tsc || !tsc->data[SC_STEELBODY] )
+ 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;
+ } else { //Assume type 2
+ if( !tsc || !tsc->data[SC_STEELBODY] )
+ 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;
+ }
+ }
+ if(skill_num == AM_ACIDTERROR) def1 = 0; //Acid Terror ignores only armor defense. [Skotlex]
+ if(def2 < 1) def2 = 1;
+ }
+ //Vitality reduction from rodatazone: http://rodatazone.simgaming.net/mechanics/substats.php#def
+ if (tsd) //Sd vit-eq
+ { //[VIT*0.5] + rnd([VIT*0.3], max([VIT*0.3],[VIT^2/150]-1))
+ vit_def = def2*(def2-15)/150;
+ vit_def = def2/2 + (vit_def>0?rnd()%vit_def:0);
+
+ if((battle_check_undead(sstatus->race,sstatus->def_ele) || sstatus->race==RC_DEMON) && //This bonus already doesnt work vs players
+ src->type == BL_MOB && (skill=pc_checkskill(tsd,AL_DP)) > 0)
+ vit_def += skill*(int)(3 +(tsd->status.base_level+1)*0.04); // submitted by orn
+ if( src->type == BL_MOB && (skill=pc_checkskill(tsd,RA_RANGERMAIN))>0 &&
+ (sstatus->race == RC_BRUTE || sstatus->race == RC_FISH || sstatus->race == RC_PLANT) )
+ vit_def += skill*5;
+ } else { //Mob-Pet vit-eq
+ //VIT + rnd(0,[VIT/20]^2-1)
+ vit_def = (def2/20)*(def2/20);
+ vit_def = def2 + (vit_def>0?rnd()%vit_def:0);
+ }
+
+ if (battle_config.weapon_defense_type) {
+ vit_def += def1*battle_config.weapon_defense_type;
+ def1 = 0;
+ }
+ #ifdef RENEWAL
+ /**
+ * In Renewal 100% damage reduction is 900 DEF
+ * Formula: (1+(900-def1)/9)%
+ **/
+ if (def1 > 900) def1 = 900;
+ ATK_RATE2(
+ flag.idef ?100:(flag.pdef ?(int)(flag.pdef *(def1+vit_def)):(1+(900-def1)/9)),
+ flag.idef2?100:(flag.pdef2?(int)(flag.pdef2*(def1+vit_def)):(1+(900-def1)/9))
+ );
+ #else
+ if (def1 > 100) def1 = 100;
+ ATK_RATE2(
+ flag.idef ?100:(flag.pdef ?(int)(flag.pdef *(def1+vit_def)):(100-def1)),
+ flag.idef2?100:(flag.pdef2?(int)(flag.pdef2*(def1+vit_def)):(100-def1))
+ );
+ #endif
+ ATK_ADD2(
+ flag.idef ||flag.pdef ?0:-vit_def,
+ flag.idef2||flag.pdef2?0:-vit_def
+ );
+ }
- //Post skill/vit reduction damage increases
- if (sc) {
- //SC skill damages
- if (sc->data[SC_AURABLADE]
+ //Post skill/vit reduction damage increases
+ if( sc )
+ { //SC skill damages
+ if(sc->data[SC_AURABLADE]
#ifndef RENEWAL
- && skill_num != LK_SPIRALPIERCE && skill_num != ML_SPIRALPIERCE
+ && skill_num != LK_SPIRALPIERCE && skill_num != ML_SPIRALPIERCE
#endif
- ) {
- int lv = sc->data[SC_AURABLADE]->val1;
+ ){
+ int lv = sc->data[SC_AURABLADE]->val1;
#ifdef RENEWAL
- lv *= ((skill_num == LK_SPIRALPIERCE || skill_num == ML_SPIRALPIERCE)?wd.div_:1); // +100 per hit in lv 5
+ lv *= ((skill_num == LK_SPIRALPIERCE || skill_num == ML_SPIRALPIERCE)?wd.div_:1); // +100 per hit in lv 5
#endif
- ATK_ADD(20*lv);
- }
+ ATK_ADD(20*lv);
+ }
- if (sc->data[SC_GN_CARTBOOST])
- ATK_ADD(10*sc->data[SC_GN_CARTBOOST]->val1);
+ if(sc->data[SC_GN_CARTBOOST])
+ ATK_ADD(10*sc->data[SC_GN_CARTBOOST]->val1);
- if (sc->data[SC_GT_CHANGE] && sc->data[SC_GT_CHANGE]->val2) {
- struct block_list *bl; // ATK increase: ATK [{(Caster DEX / 4) + (Caster STR / 2)} x Skill Level / 5]
- if ((bl = map_id2bl(sc->data[SC_GT_CHANGE]->val2)))
- ATK_ADD((status_get_dex(bl)/4 + status_get_str(bl)/2) * sc->data[SC_GT_CHANGE]->val1 / 5);
- }
+ if(sc->data[SC_GT_CHANGE] && sc->data[SC_GT_CHANGE]->val2){
+ struct block_list *bl; // ATK increase: ATK [{(Caster DEX / 4) + (Caster STR / 2)} x Skill Level / 5]
+ if( (bl = map_id2bl(sc->data[SC_GT_CHANGE]->val2)) )
+ ATK_ADD( ( status_get_dex(bl)/4 + status_get_str(bl)/2 ) * sc->data[SC_GT_CHANGE]->val1 / 5 );
+ }
- if (sc->data[SC_CAMOUFLAGE])
- ATK_ADD(30 * (10-sc->data[SC_CAMOUFLAGE]->val4));
- }
+ if(sc->data[SC_CAMOUFLAGE])
+ ATK_ADD(30 * (10-sc->data[SC_CAMOUFLAGE]->val4) );
+ }
- //Refine bonus
- if (sd && flag.weapon && skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST) {
- // Counts refine bonus multiple times
- if (skill_num == MO_FINGEROFFENSIVE) {
- ATK_ADD2(wd.div_*sstatus->rhw.atk2, wd.div_*sstatus->lhw.atk2);
- } else {
- ATK_ADD2(sstatus->rhw.atk2, sstatus->lhw.atk2);
- }
- }
+ //Refine bonus
+ if( sd && flag.weapon && skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST )
+ { // Counts refine bonus multiple times
+ if( skill_num == MO_FINGEROFFENSIVE )
+ {
+ ATK_ADD2(wd.div_*sstatus->rhw.atk2, wd.div_*sstatus->lhw.atk2);
+ } else {
+ ATK_ADD2(sstatus->rhw.atk2, sstatus->lhw.atk2);
+ }
+ }
- //Set to min of 1
- if (flag.rh && wd.damage < 1) wd.damage = 1;
- if (flag.lh && wd.damage2 < 1) wd.damage2 = 1;
-
- if (sd && flag.weapon &&
- skill_num != MO_INVESTIGATE &&
- skill_num != MO_EXTREMITYFIST &&
- skill_num != CR_GRANDCROSS) {
- //Add mastery damage
- if (skill_num != ASC_BREAKER && sd->status.weapon == W_KATAR &&
- (skill=pc_checkskill(sd,ASC_KATAR)) > 0) {
- //Adv Katar Mastery is does not applies to ASC_BREAKER,
- // but other masteries DO apply >_>
- ATK_ADDRATE(10+ 2*skill);
- }
+ //Set to min of 1
+ if (flag.rh && wd.damage < 1) wd.damage = 1;
+ if (flag.lh && wd.damage2 < 1) wd.damage2 = 1;
+
+ if (sd && flag.weapon &&
+ skill_num != MO_INVESTIGATE &&
+ skill_num != MO_EXTREMITYFIST &&
+ skill_num != CR_GRANDCROSS)
+ { //Add mastery damage
+ if(skill_num != ASC_BREAKER && sd->status.weapon == W_KATAR &&
+ (skill=pc_checkskill(sd,ASC_KATAR)) > 0)
+ { //Adv Katar Mastery is does not applies to ASC_BREAKER,
+ // but other masteries DO apply >_>
+ ATK_ADDRATE(10+ 2*skill);
+ }
- wd.damage = battle_addmastery(sd,target,wd.damage,0);
- if (flag.lh)
- wd.damage2 = battle_addmastery(sd,target,wd.damage2,1);
-
- if (sc && sc->data[SC_MIRACLE]) i = 2; //Star anger
- else
- ARR_FIND(0, MAX_PC_FEELHATE, i, t_class == sd->hate_mob[i]);
- if (i < MAX_PC_FEELHATE && (skill=pc_checkskill(sd,sg_info[i].anger_id))) {
- skillratio = sd->status.base_level + sstatus->dex + sstatus->luk;
- if (i == 2) skillratio += sstatus->str; //Star Anger
- if (skill<4)
- skillratio /= 12-3*skill;
- ATK_ADDRATE(skillratio);
- }
- if (skill_num == NJ_SYURIKEN && (skill = pc_checkskill(sd,NJ_TOBIDOUGU)) > 0)
- ATK_ADD(3*skill);
- if (skill_num == NJ_KUNAI)
- ATK_ADD(60);
- }
- } //Here ends flag.hit section, the rest of the function applies to both hitting and missing attacks
- else if (wd.div_ < 0) //Since the attack missed...
- wd.div_ *= -1;
-
- if (sd && (skill=pc_checkskill(sd,BS_WEAPONRESEARCH)) > 0)
- ATK_ADD(skill*2);
-
- if (skill_num==TF_POISON)
- ATK_ADD(15*skill_lv);
-
- if (!(nk &NK_NO_ELEFIX) && !n_ele) {
- //Elemental attribute fix
- if (wd.damage > 0) {
- wd.damage=battle_attr_fix(src,target,wd.damage,s_ele,tstatus->def_ele, tstatus->ele_lv);
- if (skill_num == MC_CARTREVOLUTION) //Cart Revolution applies the element fix once more with neutral element
- wd.damage = battle_attr_fix(src,target,wd.damage,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv);
- if (skill_num== GS_GROUNDDRIFT) //Additional 50*lv Neutral damage.
- wd.damage += battle_attr_fix(src,target,50*skill_lv,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv);
- }
- if (flag.lh && wd.damage2 > 0)
- wd.damage2 = battle_attr_fix(src,target,wd.damage2,s_ele_,tstatus->def_ele, tstatus->ele_lv);
- if (sc && sc->data[SC_WATK_ELEMENT]) {
- // Descriptions indicate this means adding a percent of a normal attack in another element. [Skotlex]
- int damage = battle_calc_base_damage(sstatus, &sstatus->rhw, sc, tstatus->size, sd, (flag.arrow?2:0)) * sc->data[SC_WATK_ELEMENT]->val2 / 100;
- wd.damage += battle_attr_fix(src, target, damage, sc->data[SC_WATK_ELEMENT]->val1, tstatus->def_ele, tstatus->ele_lv);
-
- if (flag.lh) {
- damage = battle_calc_base_damage(sstatus, &sstatus->lhw, sc, tstatus->size, sd, (flag.arrow?2:0)) * sc->data[SC_WATK_ELEMENT]->val2 / 100;
- wd.damage2 += battle_attr_fix(src, target, damage, sc->data[SC_WATK_ELEMENT]->val1, tstatus->def_ele, tstatus->ele_lv);
- }
- }
-#ifdef RENEWAL
- /**
- * In RE Shield Bommerang takes weapon element only for damage calculation,
- * - resist calculation is always against neutral
- **/
- if (skill_num == CR_SHIELDBOOMERANG)
- s_ele = s_ele_ = ELE_NEUTRAL;
+ wd.damage = battle_addmastery(sd,target,wd.damage,0);
+ if (flag.lh)
+ wd.damage2 = battle_addmastery(sd,target,wd.damage2,1);
+
+ if (sc && sc->data[SC_MIRACLE]) i = 2; //Star anger
+ else
+ ARR_FIND(0, MAX_PC_FEELHATE, i, t_class == sd->hate_mob[i]);
+ if (i < MAX_PC_FEELHATE && (skill=pc_checkskill(sd,sg_info[i].anger_id)))
+ {
+ skillratio = sd->status.base_level + sstatus->dex + sstatus->luk;
+ if (i == 2) skillratio += sstatus->str; //Star Anger
+ if (skill<4)
+ skillratio /= 12-3*skill;
+ ATK_ADDRATE(skillratio);
+ }
+ if (skill_num == NJ_SYURIKEN && (skill = pc_checkskill(sd,NJ_TOBIDOUGU)) > 0)
+ ATK_ADD(3*skill);
+ if (skill_num == NJ_KUNAI)
+ ATK_ADD(60);
+ }
+ } //Here ends flag.hit section, the rest of the function applies to both hitting and missing attacks
+ else if(wd.div_ < 0) //Since the attack missed...
+ wd.div_ *= -1;
+
+ if(sd && (skill=pc_checkskill(sd,BS_WEAPONRESEARCH)) > 0)
+ ATK_ADD(skill*2);
+
+ if(skill_num==TF_POISON)
+ ATK_ADD(15*skill_lv);
+
+ if( !(nk&NK_NO_ELEFIX) && !n_ele )
+ { //Elemental attribute fix
+ if( wd.damage > 0 )
+ {
+ wd.damage=battle_attr_fix(src,target,wd.damage,s_ele,tstatus->def_ele, tstatus->ele_lv);
+ if( skill_num == MC_CARTREVOLUTION ) //Cart Revolution applies the element fix once more with neutral element
+ wd.damage = battle_attr_fix(src,target,wd.damage,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv);
+ if( skill_num== GS_GROUNDDRIFT ) //Additional 50*lv Neutral damage.
+ wd.damage += battle_attr_fix(src,target,50*skill_lv,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv);
+ }
+ if( flag.lh && wd.damage2 > 0 )
+ wd.damage2 = battle_attr_fix(src,target,wd.damage2,s_ele_,tstatus->def_ele, tstatus->ele_lv);
+ if( sc && sc->data[SC_WATK_ELEMENT] )
+ { // Descriptions indicate this means adding a percent of a normal attack in another element. [Skotlex]
+ int damage = battle_calc_base_damage(sstatus, &sstatus->rhw, sc, tstatus->size, sd, (flag.arrow?2:0)) * sc->data[SC_WATK_ELEMENT]->val2 / 100;
+ wd.damage += battle_attr_fix(src, target, damage, sc->data[SC_WATK_ELEMENT]->val1, tstatus->def_ele, tstatus->ele_lv);
+
+ if( flag.lh )
+ {
+ damage = battle_calc_base_damage(sstatus, &sstatus->lhw, sc, tstatus->size, sd, (flag.arrow?2:0)) * sc->data[SC_WATK_ELEMENT]->val2 / 100;
+ wd.damage2 += battle_attr_fix(src, target, damage, sc->data[SC_WATK_ELEMENT]->val1, tstatus->def_ele, tstatus->ele_lv);
+ }
+ }
+ #ifdef RENEWAL
+ /**
+ * In RE Shield Bommerang takes weapon element only for damage calculation,
+ * - resist calculation is always against neutral
+ **/
+ if ( skill_num == CR_SHIELDBOOMERANG )
+ s_ele = s_ele_ = ELE_NEUTRAL;
+ #endif
+ }
+
+ if(skill_num == CR_GRANDCROSS || skill_num == NPC_GRANDDARKNESS)
+ return wd; //Enough, rest is not needed.
+
+ if (sd)
+ {
+ if (skill_num != CR_SHIELDBOOMERANG) //Only Shield boomerang doesn't takes the Star Crumbs bonus.
+ ATK_ADD2(wd.div_*sd->right_weapon.star, wd.div_*sd->left_weapon.star);
+ if (skill_num==MO_FINGEROFFENSIVE) { //The finger offensive spheres on moment of attack do count. [Skotlex]
+ ATK_ADD(wd.div_*sd->spiritball_old*3);
+ } else {
+ ATK_ADD(wd.div_*sd->spiritball*3);
+ }
+
+ //Card Fix, sd side
+ if( (wd.damage || wd.damage2) && !(nk&NK_NO_CARDFIX_ATK) )
+ {
+ int cardfix = 1000, cardfix_ = 1000;
+ int t_race2 = status_get_race2(target);
+ if(sd->state.arrow_atk)
+ {
+ cardfix=cardfix*(100+sd->right_weapon.addrace[tstatus->race]+sd->arrow_addrace[tstatus->race])/100;
+ if (!(nk&NK_NO_ELEFIX))
+ {
+ int ele_fix = sd->right_weapon.addele[tstatus->def_ele] + sd->arrow_addele[tstatus->def_ele];
+ for (i = 0; ARRAYLENGTH(sd->right_weapon.addele2) > i && sd->right_weapon.addele2[i].rate != 0; i++) {
+ if (sd->right_weapon.addele2[i].ele != tstatus->def_ele) continue;
+ if(!(sd->right_weapon.addele2[i].flag&wd.flag&BF_WEAPONMASK &&
+ sd->right_weapon.addele2[i].flag&wd.flag&BF_RANGEMASK &&
+ sd->right_weapon.addele2[i].flag&wd.flag&BF_SKILLMASK))
+ continue;
+ ele_fix += sd->right_weapon.addele2[i].rate;
+ }
+ cardfix=cardfix*(100+ele_fix)/100;
+ }
+ cardfix=cardfix*(100+sd->right_weapon.addsize[tstatus->size]+sd->arrow_addsize[tstatus->size])/100;
+ cardfix=cardfix*(100+sd->right_weapon.addrace2[t_race2])/100;
+ cardfix=cardfix*(100+sd->right_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS]+sd->arrow_addrace[is_boss(target)?RC_BOSS:RC_NONBOSS])/100;
+ if( tstatus->race != RC_DEMIHUMAN )
+ cardfix=cardfix*(100+sd->right_weapon.addrace[RC_NONDEMIHUMAN]+sd->arrow_addrace[RC_NONDEMIHUMAN])/100;
+ }
+ else
+ { // Melee attack
+ if( !battle_config.left_cardfix_to_right )
+ {
+ cardfix=cardfix*(100+sd->right_weapon.addrace[tstatus->race])/100;
+ if (!(nk&NK_NO_ELEFIX)) {
+ int ele_fix = sd->right_weapon.addele[tstatus->def_ele];
+ for (i = 0; ARRAYLENGTH(sd->right_weapon.addele2) > i && sd->right_weapon.addele2[i].rate != 0; i++) {
+ if (sd->right_weapon.addele2[i].ele != tstatus->def_ele) continue;
+ if(!(sd->right_weapon.addele2[i].flag&wd.flag&BF_WEAPONMASK &&
+ sd->right_weapon.addele2[i].flag&wd.flag&BF_RANGEMASK &&
+ sd->right_weapon.addele2[i].flag&wd.flag&BF_SKILLMASK))
+ continue;
+ ele_fix += sd->right_weapon.addele2[i].rate;
+ }
+ cardfix=cardfix*(100+ele_fix)/100;
+ }
+ cardfix=cardfix*(100+sd->right_weapon.addsize[tstatus->size])/100;
+ cardfix=cardfix*(100+sd->right_weapon.addrace2[t_race2])/100;
+ cardfix=cardfix*(100+sd->right_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS])/100;
+ if( tstatus->race != RC_DEMIHUMAN )
+ cardfix=cardfix*(100+sd->right_weapon.addrace[RC_NONDEMIHUMAN])/100;
+
+ if( flag.lh )
+ {
+ cardfix_=cardfix_*(100+sd->left_weapon.addrace[tstatus->race])/100;
+ if (!(nk&NK_NO_ELEFIX)) {
+ int ele_fix_lh = sd->left_weapon.addele[tstatus->def_ele];
+ for (i = 0; ARRAYLENGTH(sd->left_weapon.addele2) > i && sd->left_weapon.addele2[i].rate != 0; i++) {
+ if (sd->left_weapon.addele2[i].ele != tstatus->def_ele) continue;
+ if(!(sd->left_weapon.addele2[i].flag&wd.flag&BF_WEAPONMASK &&
+ sd->left_weapon.addele2[i].flag&wd.flag&BF_RANGEMASK &&
+ sd->left_weapon.addele2[i].flag&wd.flag&BF_SKILLMASK))
+ continue;
+ ele_fix_lh += sd->left_weapon.addele2[i].rate;
+ }
+ cardfix=cardfix*(100+ele_fix_lh)/100;
+ }
+ cardfix_=cardfix_*(100+sd->left_weapon.addsize[tstatus->size])/100;
+ cardfix_=cardfix_*(100+sd->left_weapon.addrace2[t_race2])/100;
+ cardfix_=cardfix_*(100+sd->left_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS])/100;
+ if( tstatus->race != RC_DEMIHUMAN )
+ cardfix_=cardfix_*(100+sd->left_weapon.addrace[RC_NONDEMIHUMAN])/100;
+ }
+ }
+ else
+ {
+ int ele_fix = sd->right_weapon.addele[tstatus->def_ele] + sd->left_weapon.addele[tstatus->def_ele];
+ for (i = 0; ARRAYLENGTH(sd->right_weapon.addele2) > i && sd->right_weapon.addele2[i].rate != 0; i++) {
+ if (sd->right_weapon.addele2[i].ele != tstatus->def_ele) continue;
+ if(!(sd->right_weapon.addele2[i].flag&wd.flag&BF_WEAPONMASK &&
+ sd->right_weapon.addele2[i].flag&wd.flag&BF_RANGEMASK &&
+ sd->right_weapon.addele2[i].flag&wd.flag&BF_SKILLMASK))
+ continue;
+ ele_fix += sd->right_weapon.addele2[i].rate;
+ }
+ for (i = 0; ARRAYLENGTH(sd->left_weapon.addele2) > i && sd->left_weapon.addele2[i].rate != 0; i++) {
+ if (sd->left_weapon.addele2[i].ele != tstatus->def_ele) continue;
+ if(!(sd->left_weapon.addele2[i].flag&wd.flag&BF_WEAPONMASK &&
+ sd->left_weapon.addele2[i].flag&wd.flag&BF_RANGEMASK &&
+ sd->left_weapon.addele2[i].flag&wd.flag&BF_SKILLMASK))
+ continue;
+ ele_fix += sd->left_weapon.addele2[i].rate;
+ }
+
+ cardfix=cardfix*(100+sd->right_weapon.addrace[tstatus->race]+sd->left_weapon.addrace[tstatus->race])/100;
+ cardfix=cardfix*(100+ele_fix)/100;
+ cardfix=cardfix*(100+sd->right_weapon.addsize[tstatus->size]+sd->left_weapon.addsize[tstatus->size])/100;
+ cardfix=cardfix*(100+sd->right_weapon.addrace2[t_race2]+sd->left_weapon.addrace2[t_race2])/100;
+ cardfix=cardfix*(100+sd->right_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS]+sd->left_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS])/100;
+ if( tstatus->race != RC_DEMIHUMAN )
+ cardfix=cardfix*(100+sd->right_weapon.addrace[RC_NONDEMIHUMAN]+sd->left_weapon.addrace[RC_NONDEMIHUMAN])/100;
+ }
+ }
+
+ for( i = 0; i < ARRAYLENGTH(sd->right_weapon.add_dmg) && sd->right_weapon.add_dmg[i].rate; i++ )
+ {
+ if( sd->right_weapon.add_dmg[i].class_ == t_class )
+ {
+ cardfix=cardfix*(100+sd->right_weapon.add_dmg[i].rate)/100;
+ break;
+ }
+ }
+
+ if( flag.lh )
+ {
+ for( i = 0; i < ARRAYLENGTH(sd->left_weapon.add_dmg) && sd->left_weapon.add_dmg[i].rate; i++ )
+ {
+ if( sd->left_weapon.add_dmg[i].class_ == t_class )
+ {
+ cardfix_=cardfix_*(100+sd->left_weapon.add_dmg[i].rate)/100;
+ break;
+ }
+ }
+ }
+
+ if( wd.flag&BF_LONG )
+ cardfix = cardfix * ( 100 + sd->bonus.long_attack_atk_rate ) / 100;
+#ifdef RENEWAL_EDP
+ if( sc && sc->data[SC_EDP] ){
+ cardfix = cardfix * (100 + sc->data[SC_EDP]->val1 * 60 ) / 100;
+ cardfix_ = cardfix_ * (100 + sc->data[SC_EDP]->val1 * 60 ) / 100;
+ }
#endif
- }
+ if( cardfix != 1000 || cardfix_ != 1000 )
+ ATK_RATE2(cardfix/10, cardfix_/10); //What happens if you use right-to-left and there's no right weapon, only left?
+ }
- if (skill_num == CR_GRANDCROSS || skill_num == NPC_GRANDDARKNESS)
- return wd; //Enough, rest is not needed.
+ if( skill_num == CR_SHIELDBOOMERANG || skill_num == PA_SHIELDCHAIN )
+ { //Refine bonus applies after cards and elements.
+ short index= sd->equip_index[EQI_HAND_L];
+ if( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_ARMOR )
+ ATK_ADD(10*sd->status.inventory[index].refine);
+ }
+ } //if (sd)
- if (sd) {
- if (skill_num != CR_SHIELDBOOMERANG) //Only Shield boomerang doesn't takes the Star Crumbs bonus.
- ATK_ADD2(wd.div_*sd->right_weapon.star, wd.div_*sd->left_weapon.star);
- if (skill_num==MO_FINGEROFFENSIVE) { //The finger offensive spheres on moment of attack do count. [Skotlex]
- ATK_ADD(wd.div_*sd->spiritball_old*3);
- } else {
- ATK_ADD(wd.div_*sd->spiritball*3);
- }
+ //Card Fix, tsd sid
+ if( tsd && !(nk&NK_NO_CARDFIX_DEF) )
+ {
+ short s_race2,s_class;
+ short cardfix=1000;
- //Card Fix, sd side
- wd.damage = battle_calc_cardfix(BF_WEAPON, src, target, nk, s_ele, s_ele_, wd.damage, 2, wd.flag);
- if( flag.lh )
- wd.damage2 = battle_calc_cardfix(BF_WEAPON, src, target, nk, s_ele, s_ele_, wd.damage2, 3, wd.flag);
+ s_race2 = status_get_race2(src);
+ s_class = status_get_class(src);
- if (skill_num == CR_SHIELDBOOMERANG || skill_num == PA_SHIELDCHAIN) {
- //Refine bonus applies after cards and elements.
- short index= sd->equip_index[EQI_HAND_L];
- if (index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_ARMOR)
- ATK_ADD(10*sd->status.inventory[index].refine);
- }
- } //if (sd)
-
- //Card Fix, tsd side
- if(tsd)
- wd.damage = battle_calc_cardfix(BF_WEAPON, src, target, nk, s_ele, s_ele_, wd.damage, flag.lh, wd.flag);
-
- if (flag.infdef) {
- //Plants receive 1 damage when hit
- short class_ = status_get_class(target);
- if (flag.hit || wd.damage > 0)
- wd.damage = wd.div_; // In some cases, right hand no need to have a weapon to increase damage
- if (flag.lh && (flag.hit || wd.damage2 > 0))
- wd.damage2 = wd.div_;
- if (flag.hit && class_ == MOBID_EMPERIUM) {
- if (wd.damage2 > 0) {
- wd.damage2 = battle_attr_fix(src,target,wd.damage2,s_ele_,tstatus->def_ele, tstatus->ele_lv);
- wd.damage2 = battle_calc_gvg_damage(src,target,wd.damage2,wd.div_,skill_num,skill_lv,wd.flag);
- } else if (wd.damage > 0) {
- wd.damage = battle_attr_fix(src,target,wd.damage,s_ele_,tstatus->def_ele, tstatus->ele_lv);
- wd.damage = battle_calc_gvg_damage(src,target,wd.damage,wd.div_,skill_num,skill_lv,wd.flag);
- }
- return wd;
- }
- if (!(battle_config.skill_min_damage&1))
- //Do not return if you are supposed to deal greater damage to plants than 1. [Skotlex]
- return wd;
- }
+ if( !(nk&NK_NO_ELEFIX) )
+ {
+ int ele_fix = tsd->subele[s_ele];
+ for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++)
+ {
+ if(tsd->subele2[i].ele != s_ele) continue;
+ if(!(tsd->subele2[i].flag&wd.flag&BF_WEAPONMASK &&
+ tsd->subele2[i].flag&wd.flag&BF_RANGEMASK &&
+ tsd->subele2[i].flag&wd.flag&BF_SKILLMASK))
+ continue;
+ ele_fix += tsd->subele2[i].rate;
+ }
+ cardfix=cardfix*(100-ele_fix)/100;
+ if( flag.lh && s_ele_ != s_ele )
+ {
+ int ele_fix_lh = tsd->subele[s_ele_];
+ for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++)
+ {
+ if(tsd->subele2[i].ele != s_ele_) continue;
+ if(!(tsd->subele2[i].flag&wd.flag&BF_WEAPONMASK &&
+ tsd->subele2[i].flag&wd.flag&BF_RANGEMASK &&
+ tsd->subele2[i].flag&wd.flag&BF_SKILLMASK))
+ continue;
+ ele_fix_lh += tsd->subele2[i].rate;
+ }
+ cardfix=cardfix*(100-ele_fix_lh)/100;
+ }
+ }
+ cardfix=cardfix*(100-tsd->subsize[sstatus->size])/100;
+ cardfix=cardfix*(100-tsd->subrace2[s_race2])/100;
+ cardfix=cardfix*(100-tsd->subrace[sstatus->race])/100;
+ cardfix=cardfix*(100-tsd->subrace[is_boss(src)?RC_BOSS:RC_NONBOSS])/100;
+ if( sstatus->race != RC_DEMIHUMAN )
+ cardfix=cardfix*(100-tsd->subrace[RC_NONDEMIHUMAN])/100;
+
+ for( i = 0; i < ARRAYLENGTH(tsd->add_def) && tsd->add_def[i].rate;i++ ) {
+ if( tsd->add_def[i].class_ == s_class ) {
+ cardfix=cardfix*(100-tsd->add_def[i].rate)/100;
+ break;
+ }
+ }
- if (sd) {
- if (!flag.rh && flag.lh) { //Move lh damage to the rh
- wd.damage = wd.damage2;
- wd.damage2 = 0;
- flag.rh=1;
- flag.lh=0;
- } else if (flag.rh && flag.lh) { //Dual-wield
- if (wd.damage) {
- if ((skill = pc_checkskill(sd,AS_RIGHT)))
- wd.damage = wd.damage * (50 + (skill * 10))/100;
- else if ((skill = pc_checkskill(sd,KO_RIGHT)))
- wd.damage = wd.damage * (70 + (skill * 10))/100;
- if (wd.damage < 1) wd.damage = 1;
- }
- if (wd.damage2) {
- if ((skill = pc_checkskill(sd,AS_LEFT)))
- wd.damage2 = wd.damage2 * (30 + (skill * 10))/100;
- else if ((skill = pc_checkskill(sd,KO_LEFT)))
- wd.damage2 = wd.damage2 * (50 + (skill * 10))/100;
- if (wd.damage2 < 1) wd.damage2 = 1;
- }
- } else if (sd->status.weapon == W_KATAR && !skill_num) { //Katars (offhand damage only applies to normal attacks, tested on Aegis 10.2)
- skill = pc_checkskill(sd,TF_DOUBLE);
- wd.damage2 = wd.damage * (1 + (skill * 2))/100;
+ if( wd.flag&BF_SHORT )
+ cardfix = cardfix * ( 100 - tsd->bonus.near_attack_def_rate ) / 100;
+ else // BF_LONG (there's no other choice)
+ cardfix = cardfix * ( 100 - tsd->bonus.long_attack_def_rate ) / 100;
- if (wd.damage && !wd.damage2) wd.damage2 = 1;
- flag.lh = 1;
- }
- }
+ if( tsd->sc.data[SC_DEF_RATE] )
+ cardfix = cardfix * ( 100 - tsd->sc.data[SC_DEF_RATE]->val1 ) / 100;
- if (!flag.rh && wd.damage)
- wd.damage=0;
-
- if (!flag.lh && wd.damage2)
- wd.damage2=0;
-
- if (wd.damage + wd.damage2) {
- //There is a total damage value
- if (!wd.damage2) {
- wd.damage = battle_calc_damage(src,target,&wd,wd.damage,skill_num,skill_lv);
- if (map_flag_gvg2(target->m))
- wd.damage=battle_calc_gvg_damage(src,target,wd.damage,wd.div_,skill_num,skill_lv,wd.flag);
- else if (map[target->m].flag.battleground)
- wd.damage=battle_calc_bg_damage(src,target,wd.damage,wd.div_,skill_num,skill_lv,wd.flag);
- } else if (!wd.damage) {
- wd.damage2 = battle_calc_damage(src,target,&wd,wd.damage2,skill_num,skill_lv);
- if (map_flag_gvg2(target->m))
- wd.damage2 = battle_calc_gvg_damage(src,target,wd.damage2,wd.div_,skill_num,skill_lv,wd.flag);
- else if (map[target->m].flag.battleground)
- wd.damage = battle_calc_bg_damage(src,target,wd.damage2,wd.div_,skill_num,skill_lv,wd.flag);
- } else {
- int d1 = wd.damage + wd.damage2,d2 = wd.damage2;
- wd.damage = battle_calc_damage(src,target,&wd,d1,skill_num,skill_lv);
- if (map_flag_gvg2(target->m))
- wd.damage = battle_calc_gvg_damage(src,target,wd.damage,wd.div_,skill_num,skill_lv,wd.flag);
- else if (map[target->m].flag.battleground)
- wd.damage = battle_calc_bg_damage(src,target,wd.damage,wd.div_,skill_num,skill_lv,wd.flag);
- wd.damage2 = (d2*100/d1)*wd.damage/100;
- if (wd.damage > 1 && wd.damage2 < 1) wd.damage2 = 1;
- wd.damage-=wd.damage2;
- }
- }
- //Reject Sword bugreport:4493 by Daegaladh
- if (wd.damage && tsc && tsc->data[SC_REJECTSWORD] &&
- (src->type!=BL_PC || (
- ((TBL_PC *)src)->weapontype1 == W_DAGGER ||
- ((TBL_PC *)src)->weapontype1 == W_1HSWORD ||
- ((TBL_PC *)src)->status.weapon == W_2HSWORD
- )) &&
- rnd()%100 < tsc->data[SC_REJECTSWORD]->val2
- ) {
- wd.damage = wd.damage * 50 / 100;
- status_fix_damage(target,src,wd.damage,clif_damage(target,src,gettick(),0,0,wd.damage,0,0,0));
- clif_skill_nodamage(target,target,ST_REJECTSWORD,tsc->data[SC_REJECTSWORD]->val1,1);
- if (--(tsc->data[SC_REJECTSWORD]->val3) <= 0)
- status_change_end(target, SC_REJECTSWORD, INVALID_TIMER);
- }
- if (skill_num == ASC_BREAKER) { //Breaker's int-based damage (a misc attack?)
- struct Damage md = battle_calc_misc_attack(src, target, skill_num, skill_lv, wflag);
- wd.damage += md.damage;
- }
- if (sc) {
- //SG_FUSION hp penalty [Komurka]
- if (sc->data[SC_FUSION]) {
- int hp= sstatus->max_hp;
- if (sd && tsd) {
- hp = 8*hp/100;
- if (100*sstatus->hp <= 20*sstatus->max_hp)
- hp = sstatus->hp;
- } else
- hp = 2*hp/100; //2% hp loss per hit
- status_zap(src, hp, 0);
- }
- /**
- * affecting non-skills
- **/
- if (!skill_num) {
- /**
- * RK Enchant Blade
- **/
- if (sc->data[SC_ENCHANTBLADE] && sd && ((flag.rh && sd->weapontype1) || (flag.lh && sd->weapontype2))) {
- //[( ( Skill Lv x 20 ) + 100 ) x ( casterBaseLevel / 150 )] + casterInt
- ATK_ADD((sc->data[SC_ENCHANTBLADE]->val1*20+100) * status_get_lv(src) / 150 + status_get_int(src));
- }
- }
- status_change_end(src,SC_CAMOUFLAGE, INVALID_TIMER);
- }
- if (skill_num == LG_RAYOFGENESIS) {
- struct Damage md = battle_calc_magic_attack(src, target, skill_num, skill_lv, wflag);
- wd.damage += md.damage;
- }
+ if( cardfix != 1000 )
+ ATK_RATE( cardfix / 10 );
+ }
+
+ if( flag.infdef )
+ { //Plants receive 1 damage when hit
+ short class_ = status_get_class(target);
+ if( flag.hit || wd.damage > 0 )
+ wd.damage = wd.div_; // In some cases, right hand no need to have a weapon to increase damage
+ if( flag.lh && (flag.hit || wd.damage2 > 0) )
+ wd.damage2 = wd.div_;
+ if( flag.hit && class_ == MOBID_EMPERIUM ) {
+ if(wd.damage2 > 0) {
+ wd.damage2 = battle_attr_fix(src,target,wd.damage2,s_ele_,tstatus->def_ele, tstatus->ele_lv);
+ wd.damage2 = battle_calc_gvg_damage(src,target,wd.damage2,wd.div_,skill_num,skill_lv,wd.flag);
+ }
+ else if(wd.damage > 0) {
+ wd.damage = battle_attr_fix(src,target,wd.damage,s_ele_,tstatus->def_ele, tstatus->ele_lv);
+ wd.damage = battle_calc_gvg_damage(src,target,wd.damage,wd.div_,skill_num,skill_lv,wd.flag);
+ }
+ return wd;
+ }
+ if( !(battle_config.skill_min_damage&1) )
+ //Do not return if you are supposed to deal greater damage to plants than 1. [Skotlex]
+ return wd;
+ }
+
+ if (sd) {
+ if (!flag.rh && flag.lh) { //Move lh damage to the rh
+ wd.damage = wd.damage2;
+ wd.damage2 = 0;
+ flag.rh=1;
+ flag.lh=0;
+ } else if(flag.rh && flag.lh) { //Dual-wield
+ if (wd.damage) {
+ if( (skill = pc_checkskill(sd,AS_RIGHT)) )
+ wd.damage = wd.damage * (50 + (skill * 10))/100;
+ else if( (skill = pc_checkskill(sd,KO_RIGHT)) )
+ wd.damage = wd.damage * (70 + (skill * 10))/100;
+ if(wd.damage < 1) wd.damage = 1;
+ }
+ if (wd.damage2) {
+ if( (skill = pc_checkskill(sd,AS_LEFT)) )
+ wd.damage2 = wd.damage2 * (30 + (skill * 10))/100;
+ else if( (skill = pc_checkskill(sd,KO_LEFT)) )
+ wd.damage2 = wd.damage2 * (50 + (skill * 10))/100;
+ if(wd.damage2 < 1) wd.damage2 = 1;
+ }
+ } else if(sd->status.weapon == W_KATAR && !skill_num) { //Katars (offhand damage only applies to normal attacks, tested on Aegis 10.2)
+ skill = pc_checkskill(sd,TF_DOUBLE);
+ wd.damage2 = wd.damage * (1 + (skill * 2))/100;
+
+ if(wd.damage && !wd.damage2) wd.damage2 = 1;
+ flag.lh = 1;
+ }
+ }
+
+ if(!flag.rh && wd.damage)
+ wd.damage=0;
+
+ if(!flag.lh && wd.damage2)
+ wd.damage2=0;
+
+ if( wd.damage + wd.damage2 )
+ { //There is a total damage value
+ if(!wd.damage2)
+ {
+ wd.damage = battle_calc_damage(src,target,&wd,wd.damage,skill_num,skill_lv);
+ if( map_flag_gvg2(target->m) )
+ wd.damage=battle_calc_gvg_damage(src,target,wd.damage,wd.div_,skill_num,skill_lv,wd.flag);
+ else if( map[target->m].flag.battleground )
+ wd.damage=battle_calc_bg_damage(src,target,wd.damage,wd.div_,skill_num,skill_lv,wd.flag);
+ }
+ else if(!wd.damage)
+ {
+ wd.damage2 = battle_calc_damage(src,target,&wd,wd.damage2,skill_num,skill_lv);
+ if( map_flag_gvg2(target->m) )
+ wd.damage2 = battle_calc_gvg_damage(src,target,wd.damage2,wd.div_,skill_num,skill_lv,wd.flag);
+ else if( map[target->m].flag.battleground )
+ wd.damage = battle_calc_bg_damage(src,target,wd.damage2,wd.div_,skill_num,skill_lv,wd.flag);
+ }
+ else
+ {
+ int d1 = wd.damage + wd.damage2,d2 = wd.damage2;
+ wd.damage = battle_calc_damage(src,target,&wd,d1,skill_num,skill_lv);
+ if( map_flag_gvg2(target->m) )
+ wd.damage = battle_calc_gvg_damage(src,target,wd.damage,wd.div_,skill_num,skill_lv,wd.flag);
+ else if( map[target->m].flag.battleground )
+ wd.damage = battle_calc_bg_damage(src,target,wd.damage,wd.div_,skill_num,skill_lv,wd.flag);
+ wd.damage2 = (d2*100/d1)*wd.damage/100;
+ if(wd.damage > 1 && wd.damage2 < 1) wd.damage2 = 1;
+ wd.damage-=wd.damage2;
+ }
+ }
+ //Reject Sword bugreport:4493 by Daegaladh
+ if(wd.damage && tsc && tsc->data[SC_REJECTSWORD] &&
+ (src->type!=BL_PC || (
+ ((TBL_PC *)src)->weapontype1 == W_DAGGER ||
+ ((TBL_PC *)src)->weapontype1 == W_1HSWORD ||
+ ((TBL_PC *)src)->status.weapon == W_2HSWORD
+ )) &&
+ rnd()%100 < tsc->data[SC_REJECTSWORD]->val2
+ ) {
+ wd.damage = wd.damage * 50 / 100;
+ status_fix_damage(target,src,wd.damage,clif_damage(target,src,gettick(),0,0,wd.damage,0,0,0));
+ clif_skill_nodamage(target,target,ST_REJECTSWORD,tsc->data[SC_REJECTSWORD]->val1,1);
+ if( --(tsc->data[SC_REJECTSWORD]->val3) <= 0 )
+ status_change_end(target, SC_REJECTSWORD, INVALID_TIMER);
+ }
+ if(skill_num == ASC_BREAKER) { //Breaker's int-based damage (a misc attack?)
+ struct Damage md = battle_calc_misc_attack(src, target, skill_num, skill_lv, wflag);
+ wd.damage += md.damage;
+ }
+ if( sc ) {
+ //SG_FUSION hp penalty [Komurka]
+ if (sc->data[SC_FUSION]) {
+ int hp= sstatus->max_hp;
+ if (sd && tsd) {
+ hp = 8*hp/100;
+ if (100*sstatus->hp <= 20*sstatus->max_hp)
+ hp = sstatus->hp;
+ } else
+ hp = 2*hp/100; //2% hp loss per hit
+ status_zap(src, hp, 0);
+ }
+ /**
+ * affecting non-skills
+ **/
+ if( !skill_num ) {
+ /**
+ * RK Enchant Blade
+ **/
+ if( sc->data[SC_ENCHANTBLADE] && sd && ( (flag.rh && sd->weapontype1) || (flag.lh && sd->weapontype2) ) ) {
+ //[( ( Skill Lv x 20 ) + 100 ) x ( casterBaseLevel / 150 )] + casterInt
+ ATK_ADD( ( sc->data[SC_ENCHANTBLADE]->val1*20+100 ) * status_get_lv(src) / 150 + status_get_int(src) );
+ }
+ }
+ status_change_end(src,SC_CAMOUFLAGE, INVALID_TIMER);
+ }
+ if( skill_num == LG_RAYOFGENESIS ) {
+ struct Damage md = battle_calc_magic_attack(src, target, skill_num, skill_lv, wflag);
+ wd.damage += md.damage;
+ }
- return wd;
+ return wd;
}
/*==========================================
* battle_calc_magic_attack [DracoRPG]
*------------------------------------------*/
-struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list *target,int skill_num,int skill_lv,int mflag) {
- int i, nk;
- short s_ele = 0;
- unsigned int skillratio = 100; //Skill dmg modifiers.
-
- TBL_PC *sd;
-// TBL_PC *tsd;
- struct Damage ad;
- struct status_data *sstatus = status_get_status_data(src);
- struct status_data *tstatus = status_get_status_data(target);
- struct {
- unsigned imdef : 1;
- unsigned infdef : 1;
- } flag;
-
- memset(&ad,0,sizeof(ad));
- memset(&flag,0,sizeof(flag));
-
- if (src==NULL || target==NULL) {
- nullpo_info(NLP_MARK);
- return ad;
- }
- //Initial Values
- ad.div_=skill_get_num(skill_num,skill_lv);
- ad.amotion=skill_get_inf(skill_num) &INF_GROUND_SKILL?0:sstatus->amotion; //Amotion should be 0 for ground skills.
- ad.dmotion=tstatus->dmotion;
- ad.blewcount = skill_get_blewcount(skill_num,skill_lv);
- ad.flag=BF_MAGIC|BF_SKILL;
- ad.dmg_lv=ATK_DEF;
- nk = skill_get_nk(skill_num);
- flag.imdef = nk &NK_IGNORE_DEF?1:0;
-
- sd = BL_CAST(BL_PC, src);
-// tsd = BL_CAST(BL_PC, target);
-
- if (skill_num == SO_PSYCHIC_WAVE) {
- struct status_change *sc = status_get_sc(src);
- if (sc && sc->count && (sc->data[SC_HEATER_OPTION] || sc->data[SC_COOLER_OPTION] ||
- sc->data[SC_BLAST_OPTION] || sc->data[SC_CURSED_SOIL_OPTION])) {
- if (sc->data[SC_HEATER_OPTION]) s_ele = sc->data[SC_HEATER_OPTION]->val4;
- else if (sc->data[SC_COOLER_OPTION]) s_ele = sc->data[SC_COOLER_OPTION]->val4;
- else if (sc->data[SC_BLAST_OPTION]) s_ele = sc->data[SC_BLAST_OPTION]->val3;
- else if (sc->data[SC_CURSED_SOIL_OPTION]) s_ele = sc->data[SC_CURSED_SOIL_OPTION]->val4;
- } else {
- //#HALP# I didn't get a clue on how to do this without unnecessary adding a overhead of status_change on every call while this is a per-skill case.
- //, - so i duplicated this code. make yourself comfortable to fix if you have any better ideas.
- //Initialize variables that will be used afterwards
- s_ele = skill_get_ele(skill_num, skill_lv);
-
- if (s_ele == -1) // pl=-1 : the skill takes the weapon's element
- s_ele = sstatus->rhw.ele;
- else if (s_ele == -2) //Use status element
- s_ele = status_get_attack_sc_element(src,status_get_sc(src));
- else if (s_ele == -3) //Use random element
- s_ele = rnd()%ELE_MAX;
- }
- } else {
- //Initialize variables that will be used afterwards
- s_ele = skill_get_ele(skill_num, skill_lv);
-
- if (s_ele == -1) { // pl=-1 : the skill takes the weapon's element
- s_ele = sstatus->rhw.ele;
- if (sd) { //Summoning 10 talisman will endow your weapon
- ARR_FIND(1, 6, i, sd->talisman[i] >= 10);
- if (i < 5) s_ele = i;
- }
- } else if (s_ele == -2) //Use status element
- s_ele = status_get_attack_sc_element(src,status_get_sc(src));
- else if (s_ele == -3) //Use random element
- s_ele = rnd()%ELE_MAX;
- }
- //Set miscellaneous data that needs be filled
- if (sd) {
- sd->state.arrow_atk = 0;
- ad.blewcount += battle_blewcount_bonus(sd, skill_num);
- }
+struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list *target,int skill_num,int skill_lv,int mflag)
+{
+ int i, nk;
+ short s_ele = 0;
+ unsigned int skillratio = 100; //Skill dmg modifiers.
- //Skill Range Criteria
- ad.flag |= battle_range_type(src, target, skill_num, skill_lv);
- flag.infdef=(tstatus->mode&MD_PLANT?1:0);
- if (target->type == BL_SKILL) {
- TBL_SKILL *su = (TBL_SKILL *)target;
- if (su->group && (su->group->skill_id == WM_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD))
- flag.infdef = 1;
- }
+ struct map_session_data *sd, *tsd;
+ struct Damage ad;
+ struct status_data *sstatus = status_get_status_data(src);
+ struct status_data *tstatus = status_get_status_data(target);
+ struct {
+ unsigned imdef : 1;
+ unsigned infdef : 1;
+ } flag;
+
+ memset(&ad,0,sizeof(ad));
+ memset(&flag,0,sizeof(flag));
+
+ if(src==NULL || target==NULL)
+ {
+ nullpo_info(NLP_MARK);
+ return ad;
+ }
+ //Initial Values
+ ad.damage = 1;
+ ad.div_=skill_get_num(skill_num,skill_lv);
+ ad.amotion=skill_get_inf(skill_num)&INF_GROUND_SKILL?0:sstatus->amotion; //Amotion should be 0 for ground skills.
+ ad.dmotion=tstatus->dmotion;
+ ad.blewcount = skill_get_blewcount(skill_num,skill_lv);
+ ad.flag=BF_MAGIC|BF_SKILL;
+ ad.dmg_lv=ATK_DEF;
+ nk = skill_get_nk(skill_num);
+ flag.imdef = nk&NK_IGNORE_DEF?1:0;
- switch (skill_num) {
- case MG_FIREWALL:
- case NJ_KAENSIN:
- ad.dmotion = 0; //No flinch animation.
- if (tstatus->def_ele == ELE_FIRE || battle_check_undead(tstatus->race, tstatus->def_ele))
- ad.blewcount = 0; //No knockback
- break;
- case PR_SANCTUARY:
- ad.dmotion = 0; //No flinch animation.
- break;
- }
+ sd = BL_CAST(BL_PC, src);
+ tsd = BL_CAST(BL_PC, target);
- if (!flag.infdef) { //No need to do the math for plants
+ if( skill_num == SO_PSYCHIC_WAVE ) {
+ struct status_change *sc = status_get_sc(src);
+ if( sc && sc->count && ( sc->data[SC_HEATER_OPTION] || sc->data[SC_COOLER_OPTION] ||
+ sc->data[SC_BLAST_OPTION] || sc->data[SC_CURSED_SOIL_OPTION] ) ) {
+ if( sc->data[SC_HEATER_OPTION] ) s_ele = sc->data[SC_HEATER_OPTION]->val4;
+ else if( sc->data[SC_COOLER_OPTION] ) s_ele = sc->data[SC_COOLER_OPTION]->val4;
+ else if( sc->data[SC_BLAST_OPTION] ) s_ele = sc->data[SC_BLAST_OPTION]->val3;
+ else if( sc->data[SC_CURSED_SOIL_OPTION] ) s_ele = sc->data[SC_CURSED_SOIL_OPTION]->val4;
+ } else {
+ //#HALP# I didn't get a clue on how to do this without unnecessary adding a overhead of status_change on every call while this is a per-skill case.
+ //, - so i duplicated this code. make yourself comfortable to fix if you have any better ideas.
+ //Initialize variables that will be used afterwards
+ s_ele = skill_get_ele(skill_num, skill_lv);
+
+ if (s_ele == -1) // pl=-1 : the skill takes the weapon's element
+ s_ele = sstatus->rhw.ele;
+ else if (s_ele == -2) //Use status element
+ s_ele = status_get_attack_sc_element(src,status_get_sc(src));
+ else if( s_ele == -3 ) //Use random element
+ s_ele = rnd()%ELE_MAX;
+ }
+ } else {
+ //Initialize variables that will be used afterwards
+ s_ele = skill_get_ele(skill_num, skill_lv);
+
+ if (s_ele == -1){ // pl=-1 : the skill takes the weapon's element
+ s_ele = sstatus->rhw.ele;
+ if( sd ){ //Summoning 10 talisman will endow your weapon
+ ARR_FIND(1, 6, i, sd->talisman[i] >= 10);
+ if( i < 5 ) s_ele = i;
+ }
+ }else if (s_ele == -2) //Use status element
+ s_ele = status_get_attack_sc_element(src,status_get_sc(src));
+ else if( s_ele == -3 ) //Use random element
+ s_ele = rnd()%ELE_MAX;
+ }
+ //Set miscellaneous data that needs be filled
+ if(sd) {
+ sd->state.arrow_atk = 0;
+ ad.blewcount += battle_blewcount_bonus(sd, skill_num);
+ }
+
+ //Skill Range Criteria
+ ad.flag |= battle_range_type(src, target, skill_num, skill_lv);
+ flag.infdef=(tstatus->mode&MD_PLANT?1:0);
+ if( target->type == BL_SKILL){
+ TBL_SKILL *su = (TBL_SKILL*)target;
+ if( su->group && (su->group->skill_id == WM_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD) )
+ flag.infdef = 1;
+ }
- //MATK_RATE scales the damage. 100 = no change. 50 is halved, 200 is doubled, etc
+ switch(skill_num)
+ {
+ case MG_FIREWALL:
+ case NJ_KAENSIN:
+ ad.dmotion = 0; //No flinch animation.
+ if ( tstatus->def_ele == ELE_FIRE || battle_check_undead(tstatus->race, tstatus->def_ele) )
+ ad.blewcount = 0; //No knockback
+ break;
+ case PR_SANCTUARY:
+ ad.dmotion = 0; //No flinch animation.
+ break;
+ }
+
+ if (!flag.infdef) //No need to do the math for plants
+ {
+
+//MATK_RATE scales the damage. 100 = no change. 50 is halved, 200 is doubled, etc
#define MATK_RATE( a ) { ad.damage= ad.damage*(a)/100; }
- //Adds dmg%. 100 = +100% (double) damage. 10 = +10% damage
+//Adds dmg%. 100 = +100% (double) damage. 10 = +10% damage
#define MATK_ADDRATE( a ) { ad.damage+= ad.damage*(a)/100; }
- //Adds an absolute value to damage. 100 = +100 damage
+//Adds an absolute value to damage. 100 = +100 damage
#define MATK_ADD( a ) { ad.damage+= a; }
- switch (skill_num) {
- //Calc base damage according to skill
- case AL_HEAL:
- case PR_BENEDICTIO:
- case PR_SANCTUARY:
- /**
- * Arch Bishop
- **/
- case AB_HIGHNESSHEAL:
- ad.damage = skill_calc_heal(src, target, skill_num, skill_lv, false);
- break;
- case PR_ASPERSIO:
- ad.damage = 40;
- break;
- case ALL_RESURRECTION:
- case PR_TURNUNDEAD:
- //Undead check is on skill_castend_damageid code.
-#ifdef RENEWAL
- i = 10*skill_lv + sstatus->luk + sstatus->int_ + status_get_lv(src)
- + 300 - 300*tstatus->hp/tstatus->max_hp;
-#else
- i = 20*skill_lv + sstatus->luk + sstatus->int_ + status_get_lv(src)
- + 200 - 200*tstatus->hp/tstatus->max_hp;
-#endif
- if (i > 700) i = 700;
- if (rnd()%1000 < i && !(tstatus->mode&MD_BOSS))
- ad.damage = tstatus->hp;
- else {
-#ifdef RENEWAL
- if (sstatus->matk_max > sstatus->matk_min) {
- MATK_ADD(sstatus->matk_min+rnd()%(sstatus->matk_max-sstatus->matk_min));
- } else {
- MATK_ADD(sstatus->matk_min);
- }
- MATK_RATE(skill_lv);
-#else
- ad.damage = status_get_lv(src) + sstatus->int_ + skill_lv * 10;
-#endif
- }
- break;
- case PF_SOULBURN:
- ad.damage = tstatus->sp * 2;
- break;
- /**
- * Arch Bishop
- **/
- case AB_RENOVATIO:
- //Damage calculation from iRO wiki. [Jobbie]
- ad.damage = (int)((15 * status_get_lv(src)) + (1.5 * sstatus->int_));
- break;
- default: {
- if (sstatus->matk_max > sstatus->matk_min) {
- MATK_ADD(sstatus->matk_min+rnd()%(sstatus->matk_max-sstatus->matk_min));
- } else {
- MATK_ADD(sstatus->matk_min);
- }
-
- if (nk&NK_SPLASHSPLIT) { // Divide MATK in case of multiple targets skill
- if (mflag>0)
- ad.damage/= mflag;
- else
- ShowError("0 enemies targeted by %d:%s, divide per 0 avoided!\n", skill_num, skill_get_name(skill_num));
- }
-
- switch (skill_num) {
- case MG_NAPALMBEAT:
- skillratio += skill_lv*10-30;
- break;
- case MG_FIREBALL:
-#ifdef RENEWAL
- skillratio += 20*skill_lv;
-#else
- skillratio += skill_lv*10-30;
-#endif
- break;
- case MG_SOULSTRIKE:
- if (battle_check_undead(tstatus->race,tstatus->def_ele))
- skillratio += 5*skill_lv;
- break;
- case MG_FIREWALL: {
- struct status_change *sc = status_get_sc(src);
- skillratio -= 50;
- if (sc && sc->data[SC_PYROTECHNIC_OPTION])
- skillratio += skillratio * sc->data[SC_PYROTECHNIC_OPTION]->val3 / 100;
- }
- break;
- case MG_COLDBOLT: {
- struct status_change *sc = status_get_sc(src);
- if (sc && sc->count) {
- if (sc->data[SC_SPELLFIST] && mflag&BF_SHORT) {
- skillratio += (sc->data[SC_SPELLFIST]->val4 * 100) + (sc->data[SC_SPELLFIST]->val2 * 100) - 100;// val4 = used bolt level, val2 = used spellfist level. [Rytech]
- ad.div_ = 1;// ad mods, to make it work similar to regular hits [Xazax]
- ad.flag = BF_WEAPON|BF_SHORT;
- ad.type = 0;
- }
- if (sc->data[SC_AQUAPLAY_OPTION])
- skillratio += skillratio * sc->data[SC_AQUAPLAY_OPTION]->val3 / 100;
- }
- }
- break;
- case MG_FIREBOLT: {
- struct status_change *sc = status_get_sc(src);
- if (sc && sc->count) {
- if (sc->data[SC_SPELLFIST] && mflag&BF_SHORT) {
- skillratio += (sc->data[SC_SPELLFIST]->val4 * 100) + (sc->data[SC_SPELLFIST]->val2 * 100) - 100;
- ad.div_ = 1;
- ad.flag = BF_WEAPON|BF_SHORT;
- ad.type = 0;
- }
- if (sc->data[SC_PYROTECHNIC_OPTION])
- skillratio += skillratio * sc->data[SC_PYROTECHNIC_OPTION]->val3 / 100;
- }
- }
- break;
- case MG_LIGHTNINGBOLT: {
- struct status_change *sc = status_get_sc(src);
- if (sc && sc->count) {
- if (sc->data[SC_SPELLFIST] && mflag&BF_SHORT) {
- skillratio += (sc->data[SC_SPELLFIST]->val4 * 100) + (sc->data[SC_SPELLFIST]->val2 * 100) - 100;
- ad.div_ = 1;
- ad.flag = BF_WEAPON|BF_SHORT;
- ad.type = 0;
- }
- if (sc->data[SC_GUST_OPTION])
- skillratio += skillratio * sc->data[SC_GUST_OPTION]->val2 / 100;
- }
- }
- break;
- case MG_THUNDERSTORM: {
- struct status_change *sc = status_get_sc(src);
- /**
- * in Renewal Thunder Storm boost is 100% (in pre-re, 80%)
- **/
-#ifndef RENEWAL
- skillratio -= 20;
-#endif
- if (sc && sc->data[SC_GUST_OPTION])
- skillratio += skillratio * sc->data[SC_GUST_OPTION]->val2 / 100;
- }
- break;
- case MG_FROSTDIVER:
- skillratio += 10*skill_lv;
- break;
- case AL_HOLYLIGHT:
- skillratio += 25;
- if (sd && sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_PRIEST)
- skillratio *= 5; //Does 5x damage include bonuses from other skills?
- break;
- case AL_RUWACH:
- skillratio += 45;
- break;
- case WZ_FROSTNOVA:
- skillratio += (100+skill_lv*10)*2/3-100;
- break;
- case WZ_FIREPILLAR:
- if (skill_lv > 10)
- skillratio += 100;
- else
- skillratio -= 80;
- break;
- case WZ_SIGHTRASHER:
- skillratio += 20*skill_lv;
- break;
- case WZ_WATERBALL:
- skillratio += 30*skill_lv;
- break;
- case WZ_STORMGUST:
- skillratio += 40*skill_lv;
- break;
- case HW_NAPALMVULCAN:
- skillratio += 10*skill_lv-30;
- break;
- case SL_STIN:
- skillratio += (tstatus->size!=SZ_SMALL?-99:10*skill_lv); //target size must be small (0) for full damage.
- break;
- case SL_STUN:
- skillratio += (tstatus->size!=SZ_BIG?5*skill_lv:-99); //Full damage is dealt on small/medium targets
- break;
- case SL_SMA:
- skillratio += -60 + status_get_lv(src); //Base damage is 40% + lv%
- break;
- case NJ_KOUENKA:
- skillratio -= 10;
- break;
- case NJ_KAENSIN:
- skillratio -= 50;
- break;
- case NJ_BAKUENRYU:
- skillratio += 50*(skill_lv-1);
- break;
- case NJ_HYOUSYOURAKU:
- skillratio += 50*skill_lv;
- break;
- case NJ_RAIGEKISAI:
- skillratio += 60 + 40*skill_lv;
- break;
- case NJ_KAMAITACHI:
- case NPC_ENERGYDRAIN:
- skillratio += 100*skill_lv;
- break;
- case NPC_EARTHQUAKE:
- skillratio += 100 +100*skill_lv +100*(skill_lv/2);
- break;
-#ifdef RENEWAL
- case WZ_HEAVENDRIVE:
- case WZ_METEOR:
- skillratio += 25;
- break;
- case WZ_VERMILION: {
- int interval = 0, per = interval , ratio = per;
- while ((per++) < skill_lv) {
- ratio += interval;
- if (per%3==0) interval += 20;
- }
- if (skill_lv > 9)
- ratio -= 10;
- skillratio += ratio;
- }
- break;
- case NJ_HUUJIN:
- skillratio += 50;
- break;
-#else
- case WZ_VERMILION:
- skillratio += 20*skill_lv-20;
- break;
-#endif
- /**
- * Arch Bishop
- **/
- case AB_JUDEX:
- skillratio += 180 + 20 * skill_lv;
- if (skill_lv > 4) skillratio += 20;
- RE_LVL_DMOD(100);
- break;
- case AB_ADORAMUS:
- skillratio += 400 + 100 * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case AB_DUPLELIGHT_MAGIC:
- skillratio += 100 + 20 * skill_lv;
- break;
- /**
- * Warlock
- **/
- case WL_SOULEXPANSION:
- skillratio += 300 + 100 * skill_lv + sstatus->int_;
- RE_LVL_DMOD(100);
- break;
- case WL_FROSTMISTY:
- skillratio += 100 + 100 * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case WL_JACKFROST: {
- struct status_change *tsc = status_get_sc(target);
- if (tsc && tsc->data[SC_FREEZING]) {
- skillratio += 900 + 300 * skill_lv;
- RE_LVL_DMOD(100);
- } else {
- skillratio += 400 + 100 * skill_lv;
- RE_LVL_DMOD(150);
- }
- }
- break;
- case WL_DRAINLIFE:
- skillratio = 200 * skill_lv + sstatus->int_;
- RE_LVL_DMOD(100);
- break;
- case WL_CRIMSONROCK:
- skillratio += 1200 + 300 * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case WL_HELLINFERNO:
- skillratio = 300 * skill_lv;
- RE_LVL_DMOD(100);
- // Shadow: MATK [{( Skill Level x 300 ) x ( Caster Base Level / 100 ) x 4/5 }] %
- // Fire : MATK [{( Skill Level x 300 ) x ( Caster Base Level / 100 ) /5 }] %
- if (mflag&ELE_DARK) {
- skillratio *= 4;
- s_ele = ELE_DARK;
- }
- skillratio /= 5;
- break;
- case WL_COMET: {
- struct status_change *sc = status_get_sc(src);
- if (sc)
- i = distance_xy(target->x, target->y, sc->comet_x, sc->comet_y);
- else
- i = 8;
- if (i < 2) skillratio = 2500 + 500 * skill_lv;
- else if (i < 4) skillratio = 1600 + 400 * skill_lv;
- else if (i < 6) skillratio = 1200 + 300 * skill_lv;
- else
- skillratio = 800 + 200 * skill_lv;
- }
- break;
- case WL_CHAINLIGHTNING_ATK:
- skillratio += 100 + 300 * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case WL_EARTHSTRAIN:
- skillratio += 1900 + 100 * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case WL_TETRAVORTEX_FIRE:
- case WL_TETRAVORTEX_WATER:
- case WL_TETRAVORTEX_WIND:
- case WL_TETRAVORTEX_GROUND:
- skillratio += 400 + 500 * skill_lv;
- break;
- case WL_SUMMON_ATK_FIRE:
- case WL_SUMMON_ATK_WATER:
- case WL_SUMMON_ATK_WIND:
- case WL_SUMMON_ATK_GROUND:
- skillratio = skill_lv * (status_get_lv(src) + (sd ? sd->status.job_level : 50)); // This is close to official, but lacking a little info to finalize. [Rytech]
- RE_LVL_DMOD(100);
- break;
- case LG_RAYOFGENESIS:
- skillratio = (skillratio + 200) * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case LG_SHIELDSPELL:// [(Casters Base Level x 4) + (Shield MDEF x 100) + (Casters INT x 2)] %
- if (sd) {
- skillratio = status_get_lv(src) * 4 + sd->bonus.shieldmdef * 100 + status_get_int(src) * 2;
- } else
- skillratio += 1900; //2000%
- break;
- case WM_METALICSOUND:
- skillratio += 120 * skill_lv + 60 * (sd? pc_checkskill(sd, WM_LESSON) : 10) - 100;
- break;
- case WM_SEVERE_RAINSTORM:
- skillratio += 50 * skill_lv;
- break;
- case WM_REVERBERATION_MAGIC:
- // MATK [{(Skill Level x 100) + 100} x Casters Base Level / 100] %
- skillratio += 100 * (sd ? pc_checkskill(sd, WM_REVERBERATION) : 1);
- RE_LVL_DMOD(100);
- break;
- case SO_FIREWALK: {
- struct status_change *sc = status_get_sc(src);
- skillratio = 300;
- RE_LVL_DMOD(100);
- if (sc && sc->data[SC_HEATER_OPTION])
- skillratio += skillratio * sc->data[SC_HEATER_OPTION]->val3 / 100;
- }
- break;
- case SO_ELECTRICWALK: {
- struct status_change *sc = status_get_sc(src);
- skillratio = 300;
- RE_LVL_DMOD(100);
- if (sc && sc->data[SC_BLAST_OPTION])
- skillratio += skillratio * sc->data[SC_BLAST_OPTION]->val2 / 100;
- }
- break;
- case SO_EARTHGRAVE: {
- struct status_change *sc = status_get_sc(src);
- skillratio = (200 * (sd ? pc_checkskill(sd, SA_SEISMICWEAPON) : 10) + sstatus->int_ * skill_lv);
- RE_LVL_DMOD(100);
- if (sc && sc->data[SC_CURSED_SOIL_OPTION])
- skillratio += skillratio * sc->data[SC_CURSED_SOIL_OPTION]->val2 / 100;
- }
- break;
- case SO_DIAMONDDUST: {
- struct status_change *sc = status_get_sc(src);
- skillratio = (200 * (sd ? pc_checkskill(sd, SA_FROSTWEAPON) : 10) + sstatus->int_ * skill_lv);
- RE_LVL_DMOD(100);
- if (sc && sc->data[SC_COOLER_OPTION])
- skillratio += skillratio * sc->data[SC_COOLER_OPTION]->val3 / 100;
- }
- break;
- case SO_POISON_BUSTER: {
- struct status_change *sc = status_get_sc(src);
- skillratio += 1100 + 300 * skill_lv;
- if (sc && sc->data[SC_CURSED_SOIL_OPTION])
- skillratio += skillratio * sc->data[SC_CURSED_SOIL_OPTION]->val2 / 100;
- }
- break;
- case SO_PSYCHIC_WAVE: {
- struct status_change *sc = status_get_sc(src);
- skillratio += -100 + skill_lv * 70 + (sstatus->int_ * 3);
- RE_LVL_DMOD(100);
- if (sc) {
- if (sc->data[SC_HEATER_OPTION])
- skillratio += skillratio * sc->data[SC_HEATER_OPTION]->val3 / 100;
- else if (sc->data[SC_COOLER_OPTION])
- skillratio += skillratio * sc->data[SC_COOLER_OPTION]->val3 / 100;
- else if (sc->data[SC_BLAST_OPTION])
- skillratio += skillratio * sc->data[SC_BLAST_OPTION]->val2 / 100;
- else if (sc->data[SC_CURSED_SOIL_OPTION])
- skillratio += skillratio * sc->data[SC_CURSED_SOIL_OPTION]->val3 / 100;
- }
- }
- break;
- case SO_VARETYR_SPEAR: {
- struct status_change *sc = status_get_sc(src);
- skillratio += -100 + (100 * (sd ? pc_checkskill(sd, SA_LIGHTNINGLOADER) : 10) + sstatus->int_ * skill_lv);
- RE_LVL_DMOD(100);
- if (sc && sc->data[SC_BLAST_OPTION])
- skillratio += skillratio * sc->data[SC_BLAST_OPTION]->val2 / 100;
- }
- break;
- case SO_CLOUD_KILL: {
- struct status_change *sc = status_get_sc(src);
- skillratio += -100 + skill_lv * 40;
- RE_LVL_DMOD(100);
- if (sc && sc->data[SC_CURSED_SOIL_OPTION])
- skillratio += skillratio * sc->data[SC_CURSED_SOIL_OPTION]->val2 / 100;
- }
- break;
- case GN_DEMONIC_FIRE:
- if (skill_lv > 20) {
- // Fire expansion Lv.2
- skillratio += 110 + 20 * (skill_lv - 20) + status_get_int(src) * 3; // Need official INT bonus. [LimitLine]
- } else if (skill_lv > 10) {
- // Fire expansion Lv.1
- skillratio += 110 + 20 * (skill_lv - 10) / 2;
- } else
- skillratio += 110 + 20 * skill_lv;
- break;
- // Magical Elemental Spirits Attack Skills
- case EL_FIRE_MANTLE:
- case EL_WATER_SCREW:
- skillratio += 900;
- break;
- case EL_FIRE_ARROW:
- case EL_ROCK_CRUSHER_ATK:
- skillratio += 200;
- break;
- case EL_FIRE_BOMB:
- case EL_ICE_NEEDLE:
- case EL_HURRICANE_ATK:
- skillratio += 400;
- break;
- case EL_FIRE_WAVE:
- case EL_TYPOON_MIS_ATK:
- skillratio += 1100;
- break;
- case MH_ERASER_CUTTER:
- if (skill_lv%2) skillratio += 400; //600:800:1000
- else skillratio += 700; //1000:1200
- skillratio += 100 * skill_lv;
- break;
- case MH_XENO_SLASHER:
- if (skill_lv%2) skillratio += 350 + 50 * skill_lv; //500:600:700
- else skillratio += 400 + 100 * skill_lv; //700:900
- break;
- case MH_HEILIGE_STANGE:
- skillratio += 400 + 250 * skill_lv;
- break;
- case MH_POISON_MIST:
- skillratio += 100 * skill_lv;
- break;
- }
-
- MATK_RATE(skillratio);
-
- //Constant/misc additions from skills
- if (skill_num == WZ_FIREPILLAR)
- MATK_ADD(50);
- }
- }
-#ifdef RENEWAL
- ad.damage = battle_calc_cardfix(BF_MAGIC, src, target, nk, s_ele, 0, ad.damage, 0, ad.flag);
-#endif
- if (sd) {
- //Damage bonuses
- if ((i = pc_skillatk_bonus(sd, skill_num)))
- ad.damage += ad.damage*i/100;
-
- //Ignore Defense?
- if (!flag.imdef && (
- sd->bonus.ignore_mdef_ele & (1 << tstatus->def_ele) ||
- sd->bonus.ignore_mdef_race & (1 << tstatus->race) ||
- sd->bonus.ignore_mdef_race & (is_boss(target) ? 1 << RC_BOSS : 1 << RC_NONBOSS)
- ))
- flag.imdef = 1;
- }
+ switch (skill_num)
+ { //Calc base damage according to skill
+ case AL_HEAL:
+ case PR_BENEDICTIO:
+ case PR_SANCTUARY:
+ /**
+ * Arch Bishop
+ **/
+ case AB_HIGHNESSHEAL:
+ ad.damage = skill_calc_heal(src, target, skill_num, skill_lv, false);
+ break;
+ case PR_ASPERSIO:
+ ad.damage = 40;
+ break;
+ case ALL_RESURRECTION:
+ case PR_TURNUNDEAD:
+ //Undead check is on skill_castend_damageid code.
+ #ifdef RENEWAL
+ i = 10*skill_lv + sstatus->luk + sstatus->int_ + status_get_lv(src)
+ + 300 - 300*tstatus->hp/tstatus->max_hp;
+ #else
+ i = 20*skill_lv + sstatus->luk + sstatus->int_ + status_get_lv(src)
+ + 200 - 200*tstatus->hp/tstatus->max_hp;
+ #endif
+ if(i > 700) i = 700;
+ if(rnd()%1000 < i && !(tstatus->mode&MD_BOSS))
+ ad.damage = tstatus->hp;
+ else {
+ #ifdef RENEWAL
+ ad.damage = skill_lv * (sstatus->matk_min + sstatus->matk_max);
+ #else
+ ad.damage = status_get_lv(src) + sstatus->int_ + skill_lv * 10;
+ #endif
+ }
+ break;
+ case PF_SOULBURN:
+ ad.damage = tstatus->sp * 2;
+ break;
+ /**
+ * Arch Bishop
+ **/
+ case AB_RENOVATIO:
+ //Damage calculation from iRO wiki. [Jobbie]
+ ad.damage = (int)((15 * status_get_lv(src)) + (1.5 * sstatus->int_));
+ break;
+ default:
+ {
+ #ifdef RENEWAL //Renewal MATK Appliance according to doddler (?title=Renewal_Changes#Upgrade_MATK)
+ /**
+ * min: (weaponMATK+upgradeMATK) * 2 + 1.5 * statusMATK
+ * max: [weaponMATK+upgradeMATK+(wMatk*wLvl)/10] * 2 + 1.5 * statusMATK
+ * yes this formula MATCHES their site: matk_max already holds weaponmatk+upgradematk, and
+ * -> statusMATK holds the %Matk modifier stuff from earlier and lastly:
+ * -> the mdef part is not applied at this point, but later.
+ **/ //1:bugreport:5101 //1:bugreport:5101
+ MATK_ADD((1+sstatus->matk_max) * 2 + 15/10 * sstatus->matk_min + rnd()% ( sstatus->matk_max + (1 + (sstatus->matk_max*sstatus->wlv) / 10 * 2 + 10/15 * sstatus->matk_min ) ));
+ #else //Ancient MATK Appliance
+ if (sstatus->matk_max > sstatus->matk_min) {
+ MATK_ADD(sstatus->matk_min+rnd()%(1+sstatus->matk_max-sstatus->matk_min));
+ } else {
+ MATK_ADD(sstatus->matk_min);
+ }
+ #endif
+ if(nk&NK_SPLASHSPLIT){ // Divide MATK in case of multiple targets skill
+ if(mflag>0)
+ ad.damage/= mflag;
+ else
+ ShowError("0 enemies targeted by %d:%s, divide per 0 avoided!\n", skill_num, skill_get_name(skill_num));
+ }
- if (!flag.imdef) {
- defType mdef = tstatus->mdef;
- int mdef2= tstatus->mdef2;
- if (sd) {
- i = sd->ignore_mdef[is_boss(target)?RC_BOSS:RC_NONBOSS];
- i+= sd->ignore_mdef[tstatus->race];
- if (i) {
- if (i > 100) i = 100;
- mdef -= mdef * i/100;
- //mdef2-= mdef2* i/100;
- }
- }
-#ifdef RENEWAL
- /**
- * RE MDEF Reduction (from doddler:?title=Renewal_Changes#MDEF)
- * Damage from magic = Magic Attack * 111.5/(111.5+eMDEF)
- * Damage = Magic Attack * 111.5/(111.5+eMDEF) - sMDEF
- **/
- if (mdef < -111) mdef = -111; // value smaller -111 brings back the damage to origin up to -223.
- ad.damage = ad.damage * 1115 / (1115 + mdef * 10) - mdef2;
-#else
- if (battle_config.magic_defense_type)
- ad.damage = ad.damage - mdef*battle_config.magic_defense_type - mdef2;
- else
- ad.damage = ad.damage * (100-mdef)/100 - mdef2;
-#endif
- }
+ switch(skill_num){
+ case MG_NAPALMBEAT:
+ skillratio += skill_lv*10-30;
+ break;
+ case MG_FIREBALL:
+ #ifdef RENEWAL
+ skillratio += 20*skill_lv;
+ #else
+ skillratio += skill_lv*10-30;
+ #endif
+ break;
+ case MG_SOULSTRIKE:
+ if (battle_check_undead(tstatus->race,tstatus->def_ele))
+ skillratio += 5*skill_lv;
+ break;
+ case MG_FIREWALL: {
+ struct status_change *sc = status_get_sc(src);
+ skillratio -= 50;
+ if( sc && sc->data[SC_PYROTECHNIC_OPTION] )
+ skillratio += skillratio * sc->data[SC_PYROTECHNIC_OPTION]->val3 / 100;
+ }
+ break;
+ case MG_COLDBOLT: {
+ struct status_change *sc = status_get_sc(src);
+ if ( sc && sc->count ) {
+ if ( sc->data[SC_SPELLFIST] && mflag&BF_SHORT ) {
+ skillratio += (sc->data[SC_SPELLFIST]->val4 * 100) + (sc->data[SC_SPELLFIST]->val2 * 100) - 100;// val4 = used bolt level, val2 = used spellfist level. [Rytech]
+ ad.div_ = 1;// ad mods, to make it work similar to regular hits [Xazax]
+ ad.flag = BF_WEAPON|BF_SHORT;
+ ad.type = 0;
+ }
+ if( sc->data[SC_AQUAPLAY_OPTION] )
+ skillratio += skillratio * sc->data[SC_AQUAPLAY_OPTION]->val3 / 100;
+ }
+ }
+ break;
+ case MG_FIREBOLT: {
+ struct status_change *sc = status_get_sc(src);
+ if ( sc && sc->count ) {
+ if ( sc->data[SC_SPELLFIST] && mflag&BF_SHORT ) {
+ skillratio += (sc->data[SC_SPELLFIST]->val4 * 100) + (sc->data[SC_SPELLFIST]->val2 * 100) - 100;
+ ad.div_ = 1;
+ ad.flag = BF_WEAPON|BF_SHORT;
+ ad.type = 0;
+ }
+ if( sc->data[SC_PYROTECHNIC_OPTION] )
+ skillratio += skillratio * sc->data[SC_PYROTECHNIC_OPTION]->val3 / 100;
+ }
+ }
+ break;
+ case MG_LIGHTNINGBOLT: {
+ struct status_change *sc = status_get_sc(src);
+ if ( sc && sc->count ) {
+ if ( sc->data[SC_SPELLFIST] && mflag&BF_SHORT ) {
+ skillratio += (sc->data[SC_SPELLFIST]->val4 * 100) + (sc->data[SC_SPELLFIST]->val2 * 100) - 100;
+ ad.div_ = 1;
+ ad.flag = BF_WEAPON|BF_SHORT;
+ ad.type = 0;
+ }
+ if( sc->data[SC_GUST_OPTION] )
+ skillratio += skillratio * sc->data[SC_GUST_OPTION]->val2 / 100;
+ }
+ }
+ break;
+ case MG_THUNDERSTORM: {
+ struct status_change *sc = status_get_sc(src);
+ /**
+ * in Renewal Thunder Storm boost is 100% (in pre-re, 80%)
+ **/
+ #ifndef RENEWAL
+ skillratio -= 20;
+ #endif
+ if( sc && sc->data[SC_GUST_OPTION] )
+ skillratio += skillratio * sc->data[SC_GUST_OPTION]->val2 / 100;
+ }
+ break;
+ case MG_FROSTDIVER:
+ skillratio += 10*skill_lv;
+ break;
+ case AL_HOLYLIGHT:
+ skillratio += 25;
+ if (sd && sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_PRIEST)
+ skillratio *= 5; //Does 5x damage include bonuses from other skills?
+ break;
+ case AL_RUWACH:
+ skillratio += 45;
+ break;
+ case WZ_FROSTNOVA:
+ skillratio += (100+skill_lv*10)*2/3-100;
+ break;
+ case WZ_FIREPILLAR:
+ if (skill_lv > 10)
+ skillratio += 100;
+ else
+ skillratio -= 80;
+ break;
+ case WZ_SIGHTRASHER:
+ skillratio += 20*skill_lv;
+ break;
+ case WZ_WATERBALL:
+ skillratio += 30*skill_lv;
+ break;
+ case WZ_STORMGUST:
+ skillratio += 40*skill_lv;
+ break;
+ case HW_NAPALMVULCAN:
+ skillratio += 10*skill_lv-30;
+ break;
+ case SL_STIN:
+ skillratio += (tstatus->size!=SZ_SMALL?-99:10*skill_lv); //target size must be small (0) for full damage.
+ break;
+ case SL_STUN:
+ skillratio += (tstatus->size!=SZ_BIG?5*skill_lv:-99); //Full damage is dealt on small/medium targets
+ break;
+ case SL_SMA:
+ skillratio += -60 + status_get_lv(src); //Base damage is 40% + lv%
+ break;
+ case NJ_KOUENKA:
+ skillratio -= 10;
+ break;
+ case NJ_KAENSIN:
+ skillratio -= 50;
+ break;
+ case NJ_BAKUENRYU:
+ skillratio += 50*(skill_lv-1);
+ break;
+ case NJ_HYOUSYOURAKU:
+ skillratio += 50*skill_lv;
+ break;
+ case NJ_RAIGEKISAI:
+ skillratio += 60 + 40*skill_lv;
+ break;
+ case NJ_KAMAITACHI:
+ case NPC_ENERGYDRAIN:
+ skillratio += 100*skill_lv;
+ break;
+ case NPC_EARTHQUAKE:
+ skillratio += 100 +100*skill_lv +100*(skill_lv/2);
+ break;
+ #ifdef RENEWAL
+ case WZ_HEAVENDRIVE:
+ case WZ_METEOR:
+ skillratio += 25;
+ break;
+ case WZ_VERMILION:
+ {
+ int interval = 0, per = interval , ratio = per;
+ while( (per++) < skill_lv ){
+ ratio += interval;
+ if(per%3==0) interval += 20;
+ }
+ if( skill_lv > 9 )
+ ratio -= 10;
+ skillratio += ratio;
+ }
+ break;
+ case NJ_HUUJIN:
+ skillratio += 50;
+ break;
+ #else
+ case WZ_VERMILION:
+ skillratio += 20*skill_lv-20;
+ break;
+ #endif
+ /**
+ * Arch Bishop
+ **/
+ case AB_JUDEX:
+ skillratio += 180 + 20 * skill_lv;
+ if (skill_lv > 4) skillratio += 20;
+ RE_LVL_DMOD(100);
+ break;
+ case AB_ADORAMUS:
+ skillratio += 400 + 100 * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case AB_DUPLELIGHT_MAGIC:
+ skillratio += 100 + 20 * skill_lv;
+ break;
+ /**
+ * Warlock
+ **/
+ case WL_SOULEXPANSION:
+ skillratio += 300 + 100 * skill_lv + sstatus->int_;
+ RE_LVL_DMOD(100);
+ break;
+ case WL_FROSTMISTY:
+ skillratio += 100 + 100 * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case WL_JACKFROST: {
+ struct status_change *tsc = status_get_sc(target);
+ if( tsc && tsc->data[SC_FREEZING] ){
+ skillratio += 900 + 300 * skill_lv;
+ RE_LVL_DMOD(100);
+ }else{
+ skillratio += 400 + 100 * skill_lv;
+ RE_LVL_DMOD(150);
+ }
+ }
+ break;
+ case WL_DRAINLIFE:
+ skillratio = 200 * skill_lv + sstatus->int_;
+ RE_LVL_DMOD(100);
+ break;
+ case WL_CRIMSONROCK:
+ skillratio += 1200 + 300 * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case WL_HELLINFERNO:
+ skillratio = 300 * skill_lv;
+ RE_LVL_DMOD(100);
+ // Shadow: MATK [{( Skill Level x 300 ) x ( Caster Base Level / 100 ) x 4/5 }] %
+ // Fire : MATK [{( Skill Level x 300 ) x ( Caster Base Level / 100 ) /5 }] %
+ if( mflag&ELE_DARK ){ skillratio *= 4; s_ele = ELE_DARK; }
+ skillratio /= 5;
+ break;
+ case WL_COMET: {
+ struct status_change * sc = status_get_sc(src);
+ if( sc )
+ i = distance_xy(target->x, target->y, sc->comet_x, sc->comet_y);
+ else
+ i = 8;
+ if( i < 2 ) skillratio = 2500 + 500 * skill_lv;
+ else
+ if( i < 4 ) skillratio = 1600 + 400 * skill_lv;
+ else
+ if( i < 6 ) skillratio = 1200 + 300 * skill_lv;
+ else
+ skillratio = 800 + 200 * skill_lv;
+ }
+ break;
+ case WL_CHAINLIGHTNING_ATK:
+ skillratio += 100 + 300 * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case WL_EARTHSTRAIN:
+ skillratio += 1900 + 100 * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case WL_TETRAVORTEX_FIRE:
+ case WL_TETRAVORTEX_WATER:
+ case WL_TETRAVORTEX_WIND:
+ case WL_TETRAVORTEX_GROUND:
+ skillratio += 400 + 500 * skill_lv;
+ break;
+ case WL_SUMMON_ATK_FIRE:
+ case WL_SUMMON_ATK_WATER:
+ case WL_SUMMON_ATK_WIND:
+ case WL_SUMMON_ATK_GROUND:
+ skillratio = skill_lv * (status_get_lv(src) + ( sd ? sd->status.job_level : 50 ));// This is close to official, but lacking a little info to finalize. [Rytech]
+ RE_LVL_DMOD(100);
+ break;
+ case LG_RAYOFGENESIS:
+ skillratio = (skillratio + 200) * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case LG_SHIELDSPELL:// [(Casters Base Level x 4) + (Shield MDEF x 100) + (Casters INT x 2)] %
+ if( sd ) {
+ skillratio = status_get_lv(src) * 4 + sd->bonus.shieldmdef * 100 + status_get_int(src) * 2;
+ } else
+ skillratio += 1900; //2000%
+ break;
+ case WM_METALICSOUND:
+ skillratio += 120 * skill_lv + 60 * ( sd? pc_checkskill(sd, WM_LESSON) : 10 ) - 100;
+ break;
+ case WM_SEVERE_RAINSTORM:
+ skillratio += 50 * skill_lv;
+ break;
+ case WM_REVERBERATION_MAGIC:
+ // MATK [{(Skill Level x 100) + 100} x Casters Base Level / 100] %
+ skillratio += 100 * (sd ? pc_checkskill(sd, WM_REVERBERATION) : 1);
+ RE_LVL_DMOD(100);
+ break;
+ case SO_FIREWALK: {
+ struct status_change * sc = status_get_sc(src);
+ skillratio = 300;
+ RE_LVL_DMOD(100);
+ if( sc && sc->data[SC_HEATER_OPTION] )
+ skillratio += skillratio * sc->data[SC_HEATER_OPTION]->val3 / 100;
+ }
+ break;
+ case SO_ELECTRICWALK: {
+ struct status_change * sc = status_get_sc(src);
+ skillratio = 300;
+ RE_LVL_DMOD(100);
+ if( sc && sc->data[SC_BLAST_OPTION] )
+ skillratio += skillratio * sc->data[SC_BLAST_OPTION]->val2 / 100;
+ }
+ break;
+ case SO_EARTHGRAVE: {
+ struct status_change * sc = status_get_sc(src);
+ skillratio = ( 200 * ( sd ? pc_checkskill(sd, SA_SEISMICWEAPON) : 10 ) + sstatus->int_ * skill_lv );
+ RE_LVL_DMOD(100);
+ if( sc && sc->data[SC_CURSED_SOIL_OPTION] )
+ skillratio += skillratio * sc->data[SC_CURSED_SOIL_OPTION]->val2 / 100;
+ }
+ break;
+ case SO_DIAMONDDUST: {
+ struct status_change * sc = status_get_sc(src);
+ skillratio = ( 200 * ( sd ? pc_checkskill(sd, SA_FROSTWEAPON) : 10 ) + sstatus->int_ * skill_lv );
+ RE_LVL_DMOD(100);
+ if( sc && sc->data[SC_COOLER_OPTION] )
+ skillratio += skillratio * sc->data[SC_COOLER_OPTION]->val3 / 100;
+ }
+ break;
+ case SO_POISON_BUSTER: {
+ struct status_change * sc = status_get_sc(src);
+ skillratio += 1100 + 300 * skill_lv;
+ if( sc && sc->data[SC_CURSED_SOIL_OPTION] )
+ skillratio += skillratio * sc->data[SC_CURSED_SOIL_OPTION]->val2 / 100;
+ }
+ break;
+ case SO_PSYCHIC_WAVE: {
+ struct status_change * sc = status_get_sc(src);
+ skillratio += -100 + skill_lv * 70 + (sstatus->int_ * 3);
+ RE_LVL_DMOD(100);
+ if( sc ){
+ if( sc->data[SC_HEATER_OPTION] )
+ skillratio += skillratio * sc->data[SC_HEATER_OPTION]->val3 / 100;
+ else if(sc->data[SC_COOLER_OPTION] )
+ skillratio += skillratio * sc->data[SC_COOLER_OPTION]->val3 / 100;
+ else if(sc->data[SC_BLAST_OPTION] )
+ skillratio += skillratio * sc->data[SC_BLAST_OPTION]->val2 / 100;
+ else if(sc->data[SC_CURSED_SOIL_OPTION] )
+ skillratio += skillratio * sc->data[SC_CURSED_SOIL_OPTION]->val3 / 100;
+ }
+ }
+ break;
+ case SO_VARETYR_SPEAR: {
+ struct status_change * sc = status_get_sc(src);
+ skillratio += -100 + ( 100 * ( sd ? pc_checkskill(sd, SA_LIGHTNINGLOADER) : 10 ) + sstatus->int_ * skill_lv );
+ RE_LVL_DMOD(100);
+ if( sc && sc->data[SC_BLAST_OPTION] )
+ skillratio += skillratio * sc->data[SC_BLAST_OPTION]->val2 / 100;
+ }
+ break;
+ case SO_CLOUD_KILL: {
+ struct status_change * sc = status_get_sc(src);
+ skillratio += -100 + skill_lv * 40;
+ RE_LVL_DMOD(100);
+ if( sc && sc->data[SC_CURSED_SOIL_OPTION] )
+ skillratio += skillratio * sc->data[SC_CURSED_SOIL_OPTION]->val2 / 100;
+ }
+ break;
+ case GN_DEMONIC_FIRE:
+ if( skill_lv > 20)
+ { // Fire expansion Lv.2
+ skillratio += 110 + 20 * (skill_lv - 20) + status_get_int(src) * 3; // Need official INT bonus. [LimitLine]
+ }
+ else if( skill_lv > 10 )
+ { // Fire expansion Lv.1
+ skillratio += 110 + 20 * (skill_lv - 10) / 2;
+ }
+ else
+ skillratio += 110 + 20 * skill_lv;
+ break;
+ // Magical Elemental Spirits Attack Skills
+ case EL_FIRE_MANTLE:
+ case EL_WATER_SCREW:
+ skillratio += 900;
+ break;
+ case EL_FIRE_ARROW:
+ case EL_ROCK_CRUSHER_ATK:
+ skillratio += 200;
+ break;
+ case EL_FIRE_BOMB:
+ case EL_ICE_NEEDLE:
+ case EL_HURRICANE_ATK:
+ skillratio += 400;
+ break;
+ case EL_FIRE_WAVE:
+ case EL_TYPOON_MIS_ATK:
+ skillratio += 1100;
+ break;
+ case MH_ERASER_CUTTER:
+ if(skill_lv%2) skillratio += 400; //600:800:1000
+ else skillratio += 700; //1000:1200
+ skillratio += 100 * skill_lv;
+ break;
+ case MH_XENO_SLASHER:
+ if(skill_lv%2) skillratio += 350 + 50 * skill_lv; //500:600:700
+ else skillratio += 400 + 100 * skill_lv; //700:900
+ break;
+ case MH_HEILIGE_STANGE:
+ skillratio += 400 + 250 * skill_lv;
+ break;
+ case MH_POISON_MIST:
+ skillratio += 100 * skill_lv;
+ break;
+ }
- if (skill_num == NPC_EARTHQUAKE) {
- //Adds atk2 to the damage, should be influenced by number of hits and skill-ratio, but not mdef reductions. [Skotlex]
- //Also divide the extra bonuses from atk2 based on the number in range [Kevin]
- if (mflag>0)
- ad.damage+= (sstatus->rhw.atk2*skillratio/100)/mflag;
- else
- ShowError("Zero range by %d:%s, divide per 0 avoided!\n", skill_num, skill_get_name(skill_num));
- }
+ MATK_RATE(skillratio);
- if (ad.damage<1)
- ad.damage=1;
-
- if (!(nk&NK_NO_ELEFIX))
- ad.damage=battle_attr_fix(src, target, ad.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
-
- if (skill_num == CR_GRANDCROSS || skill_num == NPC_GRANDDARKNESS) {
- //Apply the physical part of the skill's damage. [Skotlex]
- struct Damage wd = battle_calc_weapon_attack(src,target,skill_num,skill_lv,mflag);
- ad.damage = battle_attr_fix(src, target, wd.damage + ad.damage, s_ele, tstatus->def_ele, tstatus->ele_lv) * (100 + 40*skill_lv)/100;
- if (src == target) {
- if (src->type == BL_PC)
- ad.damage = ad.damage/2;
- else
- ad.damage = 0;
- }
- }
+ //Constant/misc additions from skills
+ if (skill_num == WZ_FIREPILLAR)
+ MATK_ADD(50);
+ }
+ }
-#ifndef RENEWAL
- ad.damage = battle_calc_cardfix(BF_MAGIC, src, target, nk, s_ele, 0, ad.damage, 0, ad.flag);
-#endif
- }
+ if(sd) {
+ //Damage bonuses
+ if ((i = pc_skillatk_bonus(sd, skill_num)))
+ ad.damage += ad.damage*i/100;
+
+ //Ignore Defense?
+ if (!flag.imdef && (
+ sd->bonus.ignore_mdef_ele & ( 1 << tstatus->def_ele ) ||
+ sd->bonus.ignore_mdef_race & ( 1 << tstatus->race ) ||
+ sd->bonus.ignore_mdef_race & ( is_boss(target) ? 1 << RC_BOSS : 1 << RC_NONBOSS )
+ ))
+ flag.imdef = 1;
+ }
- damage_div_fix(ad.damage, ad.div_);
+ if(!flag.imdef){
+ defType mdef = tstatus->mdef;
+ int mdef2= tstatus->mdef2;
+ if(sd) {
+ i = sd->ignore_mdef[is_boss(target)?RC_BOSS:RC_NONBOSS];
+ i+= sd->ignore_mdef[tstatus->race];
+ if (i)
+ {
+ if (i > 100) i = 100;
+ mdef -= mdef * i/100;
+ //mdef2-= mdef2* i/100;
+ }
+ }
+ #ifdef RENEWAL
+ /**
+ * RE MDEF Reduction (from doddler:?title=Renewal_Changes#MDEF)
+ * Damage from magic = Magic Attack * 111.5/(111.5+eMDEF)
+ * Damage = Magic Attack * 111.5/(111.5+eMDEF) - sMDEF
+ **/
+ if(mdef < -111) mdef = -111; // value smaller -111 brings back the damage to origin up to -223.
+ ad.damage = ad.damage * 1115 / (1115 + mdef * 10) - mdef2;
+ #else
+ if(battle_config.magic_defense_type)
+ ad.damage = ad.damage - mdef*battle_config.magic_defense_type - mdef2;
+ else
+ ad.damage = ad.damage * (100-mdef)/100 - mdef2;
+ #endif
+ }
- if (flag.infdef && ad.damage)
- ad.damage = ad.damage>0?1:-1;
+ if (skill_num == NPC_EARTHQUAKE)
+ { //Adds atk2 to the damage, should be influenced by number of hits and skill-ratio, but not mdef reductions. [Skotlex]
+ //Also divide the extra bonuses from atk2 based on the number in range [Kevin]
+ if(mflag>0)
+ ad.damage+= (sstatus->rhw.atk2*skillratio/100)/mflag;
+ else
+ ShowError("Zero range by %d:%s, divide per 0 avoided!\n", skill_num, skill_get_name(skill_num));
+ }
- ad.damage=battle_calc_damage(src,target,&ad,ad.damage,skill_num,skill_lv);
- if (map_flag_gvg2(target->m))
- ad.damage=battle_calc_gvg_damage(src,target,ad.damage,ad.div_,skill_num,skill_lv,ad.flag);
- else if (map[target->m].flag.battleground)
- ad.damage=battle_calc_bg_damage(src,target,ad.damage,ad.div_,skill_num,skill_lv,ad.flag);
+ if(ad.damage<1)
+ ad.damage=1;
- switch (skill_num) { /* post-calc modifiers */
- case SO_VARETYR_SPEAR: { // Physical damage.
- struct Damage wd = battle_calc_weapon_attack(src,target,skill_num,skill_lv,mflag);
- ad.damage += wd.damage;
- break;
- }
- //case HM_ERASER_CUTTER:
- }
+ if (!(nk&NK_NO_ELEFIX))
+ ad.damage=battle_attr_fix(src, target, ad.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
+
+ if( skill_num == CR_GRANDCROSS || skill_num == NPC_GRANDDARKNESS )
+ { //Apply the physical part of the skill's damage. [Skotlex]
+ struct Damage wd = battle_calc_weapon_attack(src,target,skill_num,skill_lv,mflag);
+ ad.damage = battle_attr_fix(src, target, wd.damage + ad.damage, s_ele, tstatus->def_ele, tstatus->ele_lv) * (100 + 40*skill_lv)/100;
+ if( src == target )
+ {
+ if( src->type == BL_PC )
+ ad.damage = ad.damage/2;
+ else
+ ad.damage = 0;
+ }
+ }
+
+ if (sd && !(nk&NK_NO_CARDFIX_ATK)) {
+ short t_class = status_get_class(target);
+ short cardfix=1000;
+
+ cardfix=cardfix*(100+sd->magic_addrace[tstatus->race])/100;
+ if (!(nk&NK_NO_ELEFIX))
+ cardfix=cardfix*(100+sd->magic_addele[tstatus->def_ele])/100;
+ cardfix=cardfix*(100+sd->magic_addsize[tstatus->size])/100;
+ cardfix=cardfix*(100+sd->magic_addrace[is_boss(target)?RC_BOSS:RC_NONBOSS])/100;
+ for(i=0; i< ARRAYLENGTH(sd->add_mdmg) && sd->add_mdmg[i].rate;i++) {
+ if(sd->add_mdmg[i].class_ == t_class) {
+ cardfix=cardfix*(100+sd->add_mdmg[i].rate)/100;
+ continue;
+ }
+ }
+ if (cardfix != 1000)
+ MATK_RATE(cardfix/10);
+ }
+
+ if( tsd && !(nk&NK_NO_CARDFIX_DEF) )
+ { // Target cards.
+ short s_race2 = status_get_race2(src);
+ short s_class= status_get_class(src);
+ int cardfix=1000;
+
+ if (!(nk&NK_NO_ELEFIX))
+ {
+ int ele_fix = tsd->subele[s_ele];
+ for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++)
+ {
+ if(tsd->subele2[i].ele != s_ele) continue;
+ if(!(tsd->subele2[i].flag&ad.flag&BF_WEAPONMASK &&
+ tsd->subele2[i].flag&ad.flag&BF_RANGEMASK &&
+ tsd->subele2[i].flag&ad.flag&BF_SKILLMASK))
+ continue;
+ ele_fix += tsd->subele2[i].rate;
+ }
+ cardfix=cardfix*(100-ele_fix)/100;
+ }
+ cardfix=cardfix*(100-tsd->subsize[sstatus->size])/100;
+ cardfix=cardfix*(100-tsd->subrace2[s_race2])/100;
+ cardfix=cardfix*(100-tsd->subrace[sstatus->race])/100;
+ cardfix=cardfix*(100-tsd->subrace[is_boss(src)?RC_BOSS:RC_NONBOSS])/100;
+ if( sstatus->race != RC_DEMIHUMAN )
+ cardfix=cardfix*(100-tsd->subrace[RC_NONDEMIHUMAN])/100;
+
+ for(i=0; i < ARRAYLENGTH(tsd->add_mdef) && tsd->add_mdef[i].rate;i++) {
+ if(tsd->add_mdef[i].class_ == s_class) {
+ cardfix=cardfix*(100-tsd->add_mdef[i].rate)/100;
+ break;
+ }
+ }
+ //It was discovered that ranged defense also counts vs magic! [Skotlex]
+ if ( ad.flag&BF_SHORT )
+ cardfix = cardfix * ( 100 - tsd->bonus.near_attack_def_rate ) / 100;
+ else
+ cardfix = cardfix * ( 100 - tsd->bonus.long_attack_def_rate ) / 100;
+
+ cardfix = cardfix * ( 100 - tsd->bonus.magic_def_rate ) / 100;
- return ad;
+ if( tsd->sc.data[SC_MDEF_RATE] )
+ cardfix = cardfix * ( 100 - tsd->sc.data[SC_MDEF_RATE]->val1 ) / 100;
+
+ if (cardfix != 1000)
+ MATK_RATE( cardfix / 10 );
+ }
+ }
+
+ damage_div_fix(ad.damage, ad.div_);
+
+ if (flag.infdef && ad.damage)
+ ad.damage = ad.damage>0?1:-1;
+
+ ad.damage=battle_calc_damage(src,target,&ad,ad.damage,skill_num,skill_lv);
+ if( map_flag_gvg2(target->m) )
+ ad.damage=battle_calc_gvg_damage(src,target,ad.damage,ad.div_,skill_num,skill_lv,ad.flag);
+ else if( map[target->m].flag.battleground )
+ ad.damage=battle_calc_bg_damage(src,target,ad.damage,ad.div_,skill_num,skill_lv,ad.flag);
+
+ switch( skill_num ) { /* post-calc modifiers */
+ case SO_VARETYR_SPEAR: { // Physical damage.
+ struct Damage wd = battle_calc_weapon_attack(src,target,skill_num,skill_lv,mflag);
+ ad.damage += wd.damage;
+ break;
+ }
+ //case HM_ERASER_CUTTER:
+ }
+
+ return ad;
}
/*==========================================
* Calculate Misc dammage for skillid
*------------------------------------------*/
-struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *target,int skill_num,int skill_lv,int mflag) {
- int skill;
- short i, nk;
- short s_ele;
+struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *target,int skill_num,int skill_lv,int mflag)
+{
+ int skill;
+ short i, nk;
+ short s_ele;
- struct map_session_data *sd, *tsd;
- struct Damage md; //DO NOT CONFUSE with md of mob_data!
- struct status_data *sstatus = status_get_status_data(src);
- struct status_data *tstatus = status_get_status_data(target);
+ struct map_session_data *sd, *tsd;
+ struct Damage md; //DO NOT CONFUSE with md of mob_data!
+ struct status_data *sstatus = status_get_status_data(src);
+ struct status_data *tstatus = status_get_status_data(target);
- memset(&md,0,sizeof(md));
+ memset(&md,0,sizeof(md));
- if (src == NULL || target == NULL) {
- nullpo_info(NLP_MARK);
- return md;
- }
+ if( src == NULL || target == NULL ){
+ nullpo_info(NLP_MARK);
+ return md;
+ }
- //Some initial values
- md.amotion=skill_get_inf(skill_num) &INF_GROUND_SKILL?0:sstatus->amotion;
- md.dmotion=tstatus->dmotion;
- md.div_=skill_get_num(skill_num,skill_lv);
- md.blewcount=skill_get_blewcount(skill_num,skill_lv);
- md.dmg_lv=ATK_DEF;
- md.flag=BF_MISC|BF_SKILL;
+ //Some initial values
+ md.amotion=skill_get_inf(skill_num)&INF_GROUND_SKILL?0:sstatus->amotion;
+ md.dmotion=tstatus->dmotion;
+ md.div_=skill_get_num( skill_num,skill_lv );
+ md.blewcount=skill_get_blewcount(skill_num,skill_lv);
+ md.dmg_lv=ATK_DEF;
+ md.flag=BF_MISC|BF_SKILL;
- nk = skill_get_nk(skill_num);
+ nk = skill_get_nk(skill_num);
- sd = BL_CAST(BL_PC, src);
- tsd = BL_CAST(BL_PC, target);
+ sd = BL_CAST(BL_PC, src);
+ tsd = BL_CAST(BL_PC, target);
- if (sd) {
- sd->state.arrow_atk = 0;
- md.blewcount += battle_blewcount_bonus(sd, skill_num);
- }
+ if(sd) {
+ sd->state.arrow_atk = 0;
+ md.blewcount += battle_blewcount_bonus(sd, skill_num);
+ }
- s_ele = skill_get_ele(skill_num, skill_lv);
- if (s_ele < 0 && s_ele != -3) //Attack that takes weapon's element for misc attacks? Make it neutral [Skotlex]
- s_ele = ELE_NEUTRAL;
- else if (s_ele == -3) //Use random element
- s_ele = rnd()%ELE_MAX;
+ s_ele = skill_get_ele(skill_num, skill_lv);
+ if (s_ele < 0 && s_ele != -3) //Attack that takes weapon's element for misc attacks? Make it neutral [Skotlex]
+ s_ele = ELE_NEUTRAL;
+ else if (s_ele == -3) //Use random element
+ s_ele = rnd()%ELE_MAX;
- //Skill Range Criteria
- md.flag |= battle_range_type(src, target, skill_num, skill_lv);
+ //Skill Range Criteria
+ md.flag |= battle_range_type(src, target, skill_num, skill_lv);
- switch (skill_num) {
+ switch( skill_num )
+ {
#ifdef RENEWAL
- case HT_LANDMINE:
- case MA_LANDMINE:
- case HT_BLASTMINE:
- case HT_CLAYMORETRAP:
- md.damage = skill_lv * sstatus->dex * (3+status_get_lv(src)/100) * (1+sstatus->int_/35);
- md.damage += md.damage * (rnd()%20-10) / 100;
- md.damage += 40 * (sd?pc_checkskill(sd,RA_RESEARCHTRAP):0);
- break;
+ case HT_LANDMINE:
+ case MA_LANDMINE:
+ case HT_BLASTMINE:
+ case HT_CLAYMORETRAP:
+ md.damage = skill_lv * sstatus->dex * (3+status_get_lv(src)/100) * (1+sstatus->int_/35);
+ md.damage += md.damage * (rnd()%20-10) / 100;
+ md.damage += 40 * (sd?pc_checkskill(sd,RA_RESEARCHTRAP):0);
+ break;
#else
- case HT_LANDMINE:
- case MA_LANDMINE:
- md.damage=skill_lv*(sstatus->dex+75)*(100+sstatus->int_)/100;
- break;
- case HT_BLASTMINE:
- md.damage=skill_lv*(sstatus->dex/2+50)*(100+sstatus->int_)/100;
- break;
- case HT_CLAYMORETRAP:
- md.damage=skill_lv*(sstatus->dex/2+75)*(100+sstatus->int_)/100;
- break;
+ case HT_LANDMINE:
+ case MA_LANDMINE:
+ md.damage=skill_lv*(sstatus->dex+75)*(100+sstatus->int_)/100;
+ break;
+ case HT_BLASTMINE:
+ md.damage=skill_lv*(sstatus->dex/2+50)*(100+sstatus->int_)/100;
+ break;
+ case HT_CLAYMORETRAP:
+ md.damage=skill_lv*(sstatus->dex/2+75)*(100+sstatus->int_)/100;
+ break;
#endif
- case HT_BLITZBEAT:
- case SN_FALCONASSAULT:
- //Blitz-beat Damage.
- if (!sd || (skill = pc_checkskill(sd,HT_STEELCROW)) <= 0)
- skill=0;
- md.damage=(sstatus->dex/10+sstatus->int_/2+skill*3+40)*2;
- if (mflag > 1) //Autocasted Blitz.
- nk|=NK_SPLASHSPLIT;
-
- if (skill_num == SN_FALCONASSAULT) {
- //Div fix of Blitzbeat
- skill = skill_get_num(HT_BLITZBEAT, 5);
- damage_div_fix(md.damage, skill);
-
- //Falcon Assault Modifier
- md.damage=md.damage*(150+70*skill_lv)/100;
- }
- break;
- case TF_THROWSTONE:
- md.damage=50;
- break;
- case BA_DISSONANCE:
- md.damage=30+skill_lv*10;
- if (sd)
- md.damage+= 3*pc_checkskill(sd,BA_MUSICALLESSON);
- break;
- case NPC_SELFDESTRUCTION:
- md.damage = sstatus->hp;
- break;
- case NPC_SMOKING:
- md.damage=3;
- break;
- case NPC_DARKBREATH:
- md.damage = 500 + (skill_lv-1)*1000 + rnd()%1000;
- if (md.damage > 9999) md.damage = 9999;
- break;
- case PA_PRESSURE:
- md.damage=500+300*skill_lv;
- break;
- case PA_GOSPEL:
- md.damage = 1+rnd()%9999;
- break;
- case CR_ACIDDEMONSTRATION: // updated the formula based on a Japanese formula found to be exact [Reddozen]
- if (tstatus->vit+sstatus->int_) //crash fix
- md.damage = (int)((int64)7*tstatus->vit*sstatus->int_*sstatus->int_ / (10*(tstatus->vit+sstatus->int_)));
- else
- md.damage = 0;
- if (tsd) md.damage>>=1;
- if (md.damage < 0 || md.damage > INT_MAX>>1)
- //Overflow prevention, will anyone whine if I cap it to a few billion?
- //Not capped to INT_MAX to give some room for further damage increase.
- md.damage = INT_MAX>>1;
- break;
- case NJ_ZENYNAGE:
- case KO_MUCHANAGE:
- md.damage = skill_get_zeny(skill_num ,skill_lv);
- if (!md.damage) md.damage = 2;
- md.damage = rand()%md.damage + md.damage / (skill_num==NJ_ZENYNAGE?1:2) ;
- if (is_boss(target))
- md.damage=md.damage / (skill_num==NJ_ZENYNAGE?3:2);
- else if (tsd) // need confirmation for KO_MUCHANAGE
- md.damage=md.damage/2;
- break;
- case GS_FLING:
- md.damage = sd?sd->status.job_level:status_get_lv(src);
- break;
- case HVAN_EXPLOSION: //[orn]
- md.damage = sstatus->max_hp * (50 + 50 * skill_lv) / 100 ;
- break ;
- case ASC_BREAKER:
- md.damage = 500+rnd()%500 + 5*skill_lv * sstatus->int_;
- nk|=NK_IGNORE_FLEE|NK_NO_ELEFIX; //These two are not properties of the weapon based part.
- break;
- case HW_GRAVITATION:
- md.damage = 200+200*skill_lv;
- md.dmotion = 0; //No flinch animation.
- break;
- case NPC_EVILLAND:
- md.damage = skill_calc_heal(src,target,skill_num,skill_lv,false);
- break;
- case RK_DRAGONBREATH:
- md.damage = ((status_get_hp(src) / 50) + (status_get_max_sp(src) / 4)) * skill_lv;
- RE_LVL_MDMOD(150);
- if (sd) md.damage = md.damage * (100 + 5 * (pc_checkskill(sd,RK_DRAGONTRAINING) - 1)) / 100;
- md.flag |= BF_LONG|BF_WEAPON;
- break;
- /**
- * Ranger
- **/
- case RA_CLUSTERBOMB:
- case RA_FIRINGTRAP:
- case RA_ICEBOUNDTRAP:
- md.damage = skill_lv * sstatus->dex + sstatus->int_ * 5 ;
- RE_LVL_TMDMOD();
- md.damage = md.damage * (20 * (sd ? pc_checkskill(sd,RA_RESEARCHTRAP) : 10));
- md.damage = (md.damage?md.damage:1) / (skill_num == RA_CLUSTERBOMB?50:100);
- break;
- /**
- * Mechanic
- **/
- case NC_SELFDESTRUCTION: {
- short totaldef = tstatus->def2 + (short)status_get_def(target);
- md.damage = ((sd?pc_checkskill(sd,NC_MAINFRAME):10) + 8) * (skill_lv + 1) * (status_get_sp(src) + sstatus->vit);
- RE_LVL_MDMOD(100);
- md.damage += status_get_hp(src) - totaldef;
- }
- break;
- case GN_THORNS_TRAP:
- md.damage = 100 + 200 * skill_lv + sstatus->int_;
- break;
- case GN_HELLS_PLANT_ATK:
- //[{( Hell Plant Skill Level x Casters Base Level ) x 10 } + {( Casters INT x 7 ) / 2 } x { 18 + ( Casters Job Level / 4 )] x ( 5 / ( 10 - Summon Flora Skill Level ))
- md.damage = (skill_lv * status_get_lv(src) * 10) + (sstatus->int_ * 7 / 2) * (18 + (sd?sd->status.job_level:0) / 4) * (5 / (10 - (sd?pc_checkskill(sd,AM_CANNIBALIZE):0)));
- break;
- case KO_HAPPOKUNAI: {
- struct Damage wd = battle_calc_weapon_attack(src,target,skill_num,skill_lv,mflag);
- short totaldef = tstatus->def2 + (short)status_get_def(target);
- md.damage = wd.damage * 60 * (5 + skill_lv) / 100;
- md.damage -= totaldef;
- }
- break;
- case KO_MAKIBISHI:
- md.damage = 20 * skill_lv;
- break;
- }
-
- if (nk &NK_SPLASHSPLIT) { // Divide ATK among targets
- if (mflag>0)
- md.damage/= mflag;
- else
- ShowError("0 enemies targeted by %d:%s, divide per 0 avoided!\n", skill_num, skill_get_name(skill_num));
- }
+ case HT_BLITZBEAT:
+ case SN_FALCONASSAULT:
+ //Blitz-beat Damage.
+ if(!sd || (skill = pc_checkskill(sd,HT_STEELCROW)) <= 0)
+ skill=0;
+ md.damage=(sstatus->dex/10+sstatus->int_/2+skill*3+40)*2;
+ if(mflag > 1) //Autocasted Blitz.
+ nk|=NK_SPLASHSPLIT;
+
+ if (skill_num == SN_FALCONASSAULT)
+ {
+ //Div fix of Blitzbeat
+ skill = skill_get_num(HT_BLITZBEAT, 5);
+ damage_div_fix(md.damage, skill);
+
+ //Falcon Assault Modifier
+ md.damage=md.damage*(150+70*skill_lv)/100;
+ }
+ break;
+ case TF_THROWSTONE:
+ md.damage=50;
+ break;
+ case BA_DISSONANCE:
+ md.damage=30+skill_lv*10;
+ if (sd)
+ md.damage+= 3*pc_checkskill(sd,BA_MUSICALLESSON);
+ break;
+ case NPC_SELFDESTRUCTION:
+ md.damage = sstatus->hp;
+ break;
+ case NPC_SMOKING:
+ md.damage=3;
+ break;
+ case NPC_DARKBREATH:
+ md.damage = 500 + (skill_lv-1)*1000 + rnd()%1000;
+ if(md.damage > 9999) md.damage = 9999;
+ break;
+ case PA_PRESSURE:
+ md.damage=500+300*skill_lv;
+ break;
+ case PA_GOSPEL:
+ md.damage = 1+rnd()%9999;
+ break;
+ case CR_ACIDDEMONSTRATION: // updated the formula based on a Japanese formula found to be exact [Reddozen]
+ if(tstatus->vit+sstatus->int_) //crash fix
+ md.damage = (int)((int64)7*tstatus->vit*sstatus->int_*sstatus->int_ / (10*(tstatus->vit+sstatus->int_)));
+ else
+ md.damage = 0;
+ if (tsd) md.damage>>=1;
+ if (md.damage < 0 || md.damage > INT_MAX>>1)
+ //Overflow prevention, will anyone whine if I cap it to a few billion?
+ //Not capped to INT_MAX to give some room for further damage increase.
+ md.damage = INT_MAX>>1;
+ break;
+ case NJ_ZENYNAGE:
+ case KO_MUCHANAGE:
+ md.damage = skill_get_zeny(skill_num ,skill_lv);
+ if (!md.damage) md.damage = 2;
+ md.damage = rand()%md.damage + md.damage / (skill_num==NJ_ZENYNAGE?1:2) ;
+ if (is_boss(target))
+ md.damage=md.damage / (skill_num==NJ_ZENYNAGE?3:2);
+ else if (tsd) // need confirmation for KO_MUCHANAGE
+ md.damage=md.damage/2;
+ break;
+ case GS_FLING:
+ md.damage = sd?sd->status.job_level:status_get_lv(src);
+ break;
+ case HVAN_EXPLOSION: //[orn]
+ md.damage = sstatus->max_hp * (50 + 50 * skill_lv) / 100 ;
+ break ;
+ case ASC_BREAKER:
+ md.damage = 500+rnd()%500 + 5*skill_lv * sstatus->int_;
+ nk|=NK_IGNORE_FLEE|NK_NO_ELEFIX; //These two are not properties of the weapon based part.
+ break;
+ case HW_GRAVITATION:
+ md.damage = 200+200*skill_lv;
+ md.dmotion = 0; //No flinch animation.
+ break;
+ case NPC_EVILLAND:
+ md.damage = skill_calc_heal(src,target,skill_num,skill_lv,false);
+ break;
+ case RK_DRAGONBREATH:
+ md.damage = ((status_get_hp(src) / 50) + (status_get_max_sp(src) / 4)) * skill_lv;
+ RE_LVL_MDMOD(150);
+ if (sd) md.damage = md.damage * (100 + 5 * (pc_checkskill(sd,RK_DRAGONTRAINING) - 1)) / 100;
+ md.flag |= BF_LONG|BF_WEAPON;
+ break;
+ /**
+ * Ranger
+ **/
+ case RA_CLUSTERBOMB:
+ case RA_FIRINGTRAP:
+ case RA_ICEBOUNDTRAP:
+ md.damage = skill_lv * sstatus->dex + sstatus->int_ * 5 ;
+ RE_LVL_TMDMOD();
+ md.damage = md.damage * (20 * ( sd ? pc_checkskill(sd,RA_RESEARCHTRAP) : 10 ) );
+ md.damage = (md.damage?md.damage:1) / (skill_num == RA_CLUSTERBOMB?50:100);
+ break;
+ /**
+ * Mechanic
+ **/
+ case NC_SELFDESTRUCTION:
+ {
+ short totaldef = tstatus->def2 + (short)status_get_def(target);
+ md.damage = ( (sd?pc_checkskill(sd,NC_MAINFRAME):10) + 8 ) * ( skill_lv + 1 ) * ( status_get_sp(src) + sstatus->vit );
+ RE_LVL_MDMOD(100);
+ md.damage += status_get_hp(src) - totaldef;
+ }
+ break;
+ case GN_THORNS_TRAP:
+ md.damage = 100 + 200 * skill_lv + sstatus->int_;
+ break;
+ case GN_HELLS_PLANT_ATK:
+ //[{( Hell Plant Skill Level x Casters Base Level ) x 10 } + {( Casters INT x 7 ) / 2 } x { 18 + ( Casters Job Level / 4 )] x ( 5 / ( 10 - Summon Flora Skill Level ))
+ md.damage = ( skill_lv * status_get_lv(src) * 10 ) + ( sstatus->int_ * 7 / 2 ) * ( 18 + (sd?sd->status.job_level:0) / 4 ) * ( 5 / (10 - (sd?pc_checkskill(sd,AM_CANNIBALIZE):0)) );
+ break;
+ case KO_HAPPOKUNAI:
+ {
+ struct Damage wd = battle_calc_weapon_attack(src,target,skill_num,skill_lv,mflag);
+ short totaldef = tstatus->def2 + (short)status_get_def(target);
+ md.damage = wd.damage * 60 * (5 + skill_lv) / 100;
+ md.damage -= totaldef;
+ }
+ break;
+ case KO_MAKIBISHI:
+ md.damage = 20 * skill_lv;
+ break;
+ }
- damage_div_fix(md.damage, md.div_);
+ if (nk&NK_SPLASHSPLIT){ // Divide ATK among targets
+ if(mflag>0)
+ md.damage/= mflag;
+ else
+ ShowError("0 enemies targeted by %d:%s, divide per 0 avoided!\n", skill_num, skill_get_name(skill_num));
+ }
- if (!(nk &NK_IGNORE_FLEE)) {
- struct status_change *sc = status_get_sc(target);
- i = 0; //Temp for "hit or no hit"
- if (sc && sc->opt1 && sc->opt1 != OPT1_STONEWAIT && sc->opt1 != OPT1_BURNING)
- i = 1;
- else {
- short
- flee = tstatus->flee,
+ damage_div_fix(md.damage, md.div_);
+
+ if (!(nk&NK_IGNORE_FLEE))
+ {
+ struct status_change *sc = status_get_sc(target);
+ i = 0; //Temp for "hit or no hit"
+ if(sc && sc->opt1 && sc->opt1 != OPT1_STONEWAIT && sc->opt1 != OPT1_BURNING)
+ i = 1;
+ else {
+ short
+ flee = tstatus->flee,
#ifdef RENEWAL
- hitrate = 0; //Default hitrate
+ hitrate = 0; //Default hitrate
#else
- hitrate = 80; //Default hitrate
+ hitrate = 80; //Default hitrate
#endif
- if (battle_config.agi_penalty_type && battle_config.agi_penalty_target&target->type) {
- unsigned char attacker_count; //256 max targets should be a sane max
- attacker_count = unit_counttargeted(target);
- if (attacker_count >= battle_config.agi_penalty_count) {
- if (battle_config.agi_penalty_type == 1)
- flee = (flee * (100 - (attacker_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num))/100;
- else //asume type 2: absolute reduction
- flee -= (attacker_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num;
- if (flee < 1) flee = 1;
- }
- }
+ if(battle_config.agi_penalty_type && battle_config.agi_penalty_target&target->type) {
+ unsigned char attacker_count; //256 max targets should be a sane max
+ attacker_count = unit_counttargeted(target);
+ if(attacker_count >= battle_config.agi_penalty_count)
+ {
+ if (battle_config.agi_penalty_type == 1)
+ flee = (flee * (100 - (attacker_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num))/100;
+ else //asume type 2: absolute reduction
+ flee -= (attacker_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num;
+ if(flee < 1) flee = 1;
+ }
+ }
- hitrate+= sstatus->hit - flee;
+ hitrate+= sstatus->hit - flee;
#ifdef RENEWAL
- if (sd) //in Renewal hit bonus from Vultures Eye is not anymore shown in status window
- hitrate += pc_checkskill(sd,AC_VULTURE);
+ if( sd ) //in Renewal hit bonus from Vultures Eye is not anymore shown in status window
+ hitrate += pc_checkskill(sd,AC_VULTURE);
#endif
- hitrate = cap_value(hitrate, battle_config.min_hitrate, battle_config.max_hitrate);
-
- if (rnd()%100 < hitrate)
- i = 1;
- }
- if (!i) {
- md.damage = 0;
- md.dmg_lv=ATK_FLEE;
- }
- }
+ hitrate = cap_value(hitrate, battle_config.min_hitrate, battle_config.max_hitrate);
- md.damage = battle_calc_cardfix(BF_MISC, src, target, nk, s_ele, 0, md.damage, 0, md.flag);
+ if(rnd()%100 < hitrate)
+ i = 1;
+ }
+ if (!i) {
+ md.damage = 0;
+ md.dmg_lv=ATK_FLEE;
+ }
+ }
- if (sd && (i = pc_skillatk_bonus(sd, skill_num)))
- md.damage += md.damage *i/100;
+ if( md.damage && tsd && !(nk&NK_NO_CARDFIX_DEF) )
+ {// misc damage reduction from equipment
+ int cardfix = 10000;
+ int race2 = status_get_race2(src);
+ if (!(nk&NK_NO_ELEFIX))
+ {
+ int ele_fix = tsd->subele[s_ele];
+ for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++)
+ {
+ if(tsd->subele2[i].ele != s_ele) continue;
+ if(!(tsd->subele2[i].flag&md.flag&BF_WEAPONMASK &&
+ tsd->subele2[i].flag&md.flag&BF_RANGEMASK &&
+ tsd->subele2[i].flag&md.flag&BF_SKILLMASK))
+ continue;
+ ele_fix += tsd->subele2[i].rate;
+ }
+ cardfix=cardfix*(100-ele_fix)/100;
+ }
+ cardfix=cardfix*(100-tsd->subsize[sstatus->size])/100;
+ cardfix=cardfix*(100-tsd->subrace2[race2])/100;
+ cardfix=cardfix*(100-tsd->subrace[sstatus->race])/100;
+ cardfix=cardfix*(100-tsd->subrace[is_boss(src)?RC_BOSS:RC_NONBOSS])/100;
+ if( sstatus->race != RC_DEMIHUMAN )
+ cardfix=cardfix*(100-tsd->subrace[RC_NONDEMIHUMAN])/100;
+
+ cardfix = cardfix * ( 100 - tsd->bonus.misc_def_rate ) / 100;
+ if( md.flag&BF_SHORT )
+ cardfix = cardfix * ( 100 - tsd->bonus.near_attack_def_rate ) / 100;
+ else // BF_LONG (there's no other choice)
+ cardfix = cardfix * ( 100 - tsd->bonus.long_attack_def_rate ) / 100;
+
+ if (cardfix != 10000)
+ md.damage= (int)( (int64)md.damage * cardfix / 10000 );
+ }
- if (md.damage < 0)
- md.damage = 0;
- else if (md.damage && tstatus->mode &MD_PLANT) {
- switch (skill_num) {
- case HT_LANDMINE:
- case MA_LANDMINE:
- case HT_BLASTMINE:
- case HT_CLAYMORETRAP:
- case RA_CLUSTERBOMB:
+ if (sd && (i = pc_skillatk_bonus(sd, skill_num)))
+ md.damage += md.damage*i/100;
+
+ if(md.damage < 0)
+ md.damage = 0;
+ else if(md.damage && tstatus->mode&MD_PLANT){
+ switch(skill_num){
+ case HT_LANDMINE:
+ case MA_LANDMINE:
+ case HT_BLASTMINE:
+ case HT_CLAYMORETRAP:
+ case RA_CLUSTERBOMB:
#ifdef RENEWAL
- break;
+ break;
#endif
- default:
- md.damage = 1;
- }
- } else if (target->type == BL_SKILL) {
- TBL_SKILL *su = (TBL_SKILL *)target;
- if (su->group && (su->group->skill_id == WM_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD))
- md.damage = 1;
- }
+ default:
+ md.damage = 1;
+ }
+ }else if( target->type == BL_SKILL ){
+ TBL_SKILL *su = (TBL_SKILL*)target;
+ if( su->group && (su->group->skill_id == WM_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD) )
+ md.damage = 1;
+ }
- if (!(nk &NK_NO_ELEFIX))
- md.damage=battle_attr_fix(src, target, md.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
-
- md.damage=battle_calc_damage(src,target,&md,md.damage,skill_num,skill_lv);
- if (map_flag_gvg2(target->m))
- md.damage=battle_calc_gvg_damage(src,target,md.damage,md.div_,skill_num,skill_lv,md.flag);
- else if (map[target->m].flag.battleground)
- md.damage=battle_calc_bg_damage(src,target,md.damage,md.div_,skill_num,skill_lv,md.flag);
-
- switch (skill_num) {
- case RA_FIRINGTRAP:
- case RA_ICEBOUNDTRAP:
- if (md.damage == 1) break;
- case RA_CLUSTERBOMB: {
- struct Damage wd;
- wd = battle_calc_weapon_attack(src,target,skill_num,skill_lv,mflag);
- md.damage += wd.damage;
- }
- break;
- case NJ_ZENYNAGE:
- if (sd) {
- if (md.damage > sd->status.zeny)
- md.damage = sd->status.zeny;
- pc_payzeny(sd, md.damage,LOG_TYPE_STEAL,NULL);
- }
- break;
- }
+ if(!(nk&NK_NO_ELEFIX))
+ md.damage=battle_attr_fix(src, target, md.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
+
+ md.damage=battle_calc_damage(src,target,&md,md.damage,skill_num,skill_lv);
+ if( map_flag_gvg2(target->m) )
+ md.damage=battle_calc_gvg_damage(src,target,md.damage,md.div_,skill_num,skill_lv,md.flag);
+ else if( map[target->m].flag.battleground )
+ md.damage=battle_calc_bg_damage(src,target,md.damage,md.div_,skill_num,skill_lv,md.flag);
+
+ switch( skill_num ) {
+ case RA_FIRINGTRAP:
+ case RA_ICEBOUNDTRAP:
+ if( md.damage == 1 ) break;
+ case RA_CLUSTERBOMB:
+ {
+ struct Damage wd;
+ wd = battle_calc_weapon_attack(src,target,skill_num,skill_lv,mflag);
+ md.damage += wd.damage;
+ }
+ break;
+ case NJ_ZENYNAGE:
+ if( sd ) {
+ if ( md.damage > sd->status.zeny )
+ md.damage = sd->status.zeny;
+ pc_payzeny(sd, md.damage,LOG_TYPE_STEAL,NULL);
+ }
+ break;
+ }
- return md;
+ return md;
}
/*==========================================
* Battle main entry, from skill_attack
*------------------------------------------*/
-struct Damage battle_calc_attack(int attack_type,struct block_list *bl,struct block_list *target,int skill_num,int skill_lv,int count) {
- struct Damage d;
- switch (attack_type) {
- case BF_WEAPON:
- d = battle_calc_weapon_attack(bl,target,skill_num,skill_lv,count);
- break;
- case BF_MAGIC:
- d = battle_calc_magic_attack(bl,target,skill_num,skill_lv,count);
- break;
- case BF_MISC:
- d = battle_calc_misc_attack(bl,target,skill_num,skill_lv,count);
- break;
- default:
- ShowError("battle_calc_attack: unknown attack type! %d\n",attack_type);
- memset(&d,0,sizeof(d));
- break;
- }
- if (d.damage + d.damage2 < 1) {
- //Miss/Absorbed
- //Weapon attacks should go through to cause additional effects.
- if (d.dmg_lv == ATK_DEF /*&& attack_type&(BF_MAGIC|BF_MISC)*/) // Isn't it that additional effects don't apply if miss?
- d.dmg_lv = ATK_MISS;
- d.dmotion = 0;
- } else // Some skills like Weaponry Research will cause damage even if attack is dodged
- d.dmg_lv = ATK_DEF;
- return d;
+struct Damage battle_calc_attack(int attack_type,struct block_list *bl,struct block_list *target,int skill_num,int skill_lv,int count)
+{
+ struct Damage d;
+ switch(attack_type) {
+ case BF_WEAPON: d = battle_calc_weapon_attack(bl,target,skill_num,skill_lv,count); break;
+ case BF_MAGIC: d = battle_calc_magic_attack(bl,target,skill_num,skill_lv,count); break;
+ case BF_MISC: d = battle_calc_misc_attack(bl,target,skill_num,skill_lv,count); break;
+ default:
+ ShowError("battle_calc_attack: unknown attack type! %d\n",attack_type);
+ memset(&d,0,sizeof(d));
+ break;
+ }
+ if( d.damage + d.damage2 < 1 )
+ { //Miss/Absorbed
+ //Weapon attacks should go through to cause additional effects.
+ if (d.dmg_lv == ATK_DEF /*&& attack_type&(BF_MAGIC|BF_MISC)*/) // Isn't it that additional effects don't apply if miss?
+ d.dmg_lv = ATK_MISS;
+ d.dmotion = 0;
+ }
+ else // Some skills like Weaponry Research will cause damage even if attack is dodged
+ d.dmg_lv = ATK_DEF;
+ return d;
}
//Calculates BF_WEAPON returned damage.
-int battle_calc_return_damage(struct block_list *bl, struct block_list *src, int *dmg, int flag, int skillid)
-{
- struct map_session_data *sd = NULL;
- int rdamage = 0, damage = *dmg;
- struct status_change *sc;
-
- sd = BL_CAST(BL_PC, bl);
- sc = status_get_sc(bl);
-
- if (sc && sc->data[SC_REFLECTDAMAGE]) {
- int max_damage = status_get_max_hp(bl) * status_get_lv(bl) / 100;
- rdamage = (*dmg) * sc->data[SC_REFLECTDAMAGE]->val2 / 100;
- if (rdamage > max_damage) rdamage = max_damage;
- } else if (sc && sc->data[SC_CRESCENTELBOW] && !is_boss(src) && rnd()%100 < sc->data[SC_CRESCENTELBOW]->val2) {
- //ATK [{(Target HP / 100) x Skill Level} x Caster Base Level / 125] % + [Received damage x {1 + (Skill Level x 0.2)}]
- int ratio = (status_get_hp(src) / 100) * sc->data[SC_CRESCENTELBOW]->val1 * status_get_lv(bl) / 125;
- if (ratio > 5000) ratio = 5000; // Maximum of 5000% ATK
- rdamage = rdamage * ratio / 100 + (*dmg) * (10 + sc->data[SC_CRESCENTELBOW]->val1 * 20 / 10) / 10;
- skill_blown(bl, src, skill_get_blewcount(SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1), unit_getdir(src), 0);
- clif_skill_damage(bl, src, gettick(), status_get_amotion(src), 0, rdamage,
- 1, SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1, 6); // This is how official does
- clif_damage(src, bl, gettick(), status_get_amotion(src)+1000, 0, rdamage/10, 1, 0, 0);
- status_damage(src, bl, status_damage(bl, src, rdamage, 0, 0, 1)/10, 0, 0, 1);
- status_change_end(bl, SC_CRESCENTELBOW, INVALID_TIMER);
- return 0; // Just put here to minimize redundancy
- } else if (flag & BF_SHORT) {//Bounces back part of the damage.
- if (sd && sd->bonus.short_weapon_damage_return) {
- rdamage += damage * sd->bonus.short_weapon_damage_return / 100;
- if (rdamage < 1) rdamage = 1;
- }
- if (sc && sc->count) {
- if (sc->data[SC_REFLECTSHIELD] && skillid != WS_CARTTERMINATION) {
- rdamage += damage * sc->data[SC_REFLECTSHIELD]->val2 / 100;
- if (rdamage < 1) rdamage = 1;
- }
- if (sc->data[SC_DEATHBOUND] && skillid != WS_CARTTERMINATION && !(src->type == BL_MOB && is_boss(src))) {
- int dir = map_calc_dir(bl,src->x,src->y),
- t_dir = unit_getdir(bl), rd1 = 0;
-
- if (distance_bl(src,bl) <= 0 || !map_check_dir(dir,t_dir)) {
- rd1 = min(damage,status_get_max_hp(bl)) * sc->data[SC_DEATHBOUND]->val2 / 100; // Amplify damage.
- *dmg = rd1 * 30 / 100; // Received damge = 30% of amplifly damage.
- clif_skill_damage(src,bl,gettick(), status_get_amotion(src), 0, -30000, 1, RK_DEATHBOUND, sc->data[SC_DEATHBOUND]->val1,6);
- status_change_end(bl,SC_DEATHBOUND,INVALID_TIMER);
- rdamage += rd1;
- if (rdamage < 1) rdamage = 1;
- }
- }
- }
- } else {
- if (sd && sd->bonus.long_weapon_damage_return) {
- rdamage += damage * sd->bonus.long_weapon_damage_return / 100;
- if (rdamage < 1) rdamage = 1;
- }
- }
+int battle_calc_return_damage(struct block_list* bl, struct block_list *src, int *dmg, int flag, int skillid){
+ struct map_session_data* sd = NULL;
+ int rdamage = 0, damage = *dmg;
+ struct status_change* sc;
+
+ sd = BL_CAST(BL_PC, bl);
+ sc = status_get_sc(bl);
+
+ if( sc && sc->data[SC_REFLECTDAMAGE] ) {
+ int max_damage = status_get_max_hp(bl) * status_get_lv(bl) / 100;
+ rdamage = (*dmg) * sc->data[SC_REFLECTDAMAGE]->val2 / 100;
+ if( rdamage > max_damage ) rdamage = max_damage;
+ }else if( sc && sc->data[SC_CRESCENTELBOW] && !is_boss(src) && rnd()%100 < sc->data[SC_CRESCENTELBOW]->val2 ){
+ //ATK [{(Target HP / 100) x Skill Level} x Caster Base Level / 125] % + [Received damage x {1 + (Skill Level x 0.2)}]
+ int ratio = (status_get_hp(src) / 100) * sc->data[SC_CRESCENTELBOW]->val1 * status_get_lv(bl) / 125;
+ if (ratio > 5000) ratio = 5000; // Maximum of 5000% ATK
+ rdamage = rdamage * ratio / 100 + (*dmg) * (10 + sc->data[SC_CRESCENTELBOW]->val1 * 20 / 10) / 10;
+ skill_blown(bl, src, skill_get_blewcount(SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1), unit_getdir(src), 0);
+ clif_skill_damage(bl, src, gettick(), status_get_amotion(src), 0, rdamage,
+ 1, SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1, 6); // This is how official does
+ clif_damage(src, bl, gettick(), status_get_amotion(src)+1000, 0, rdamage/10, 1, 0, 0);
+ status_damage(src, bl, status_damage(bl, src, rdamage, 0, 0, 1)/10, 0, 0, 1);
+ status_change_end(bl, SC_CRESCENTELBOW, INVALID_TIMER);
+ return 0; // Just put here to minimize redundancy
+ }else if (flag & BF_SHORT) {//Bounces back part of the damage.
+ if ( sd && sd->bonus.short_weapon_damage_return ) {
+ rdamage += damage * sd->bonus.short_weapon_damage_return / 100;
+ if(rdamage < 1) rdamage = 1;
+ }
+ if( sc && sc->count ) {
+ if ( sc->data[SC_REFLECTSHIELD] && skillid != WS_CARTTERMINATION ) {
+ rdamage += damage * sc->data[SC_REFLECTSHIELD]->val2 / 100;
+ if (rdamage < 1) rdamage = 1;
+ }
+ if(sc->data[SC_DEATHBOUND] && skillid != WS_CARTTERMINATION && !(src->type == BL_MOB && is_boss(src)) ) {
+ int dir = map_calc_dir(bl,src->x,src->y),
+ t_dir = unit_getdir(bl), rd1 = 0;
+
+ if( distance_bl(src,bl) <= 0 || !map_check_dir(dir,t_dir) ) {
+ rd1 = min(damage,status_get_max_hp(bl)) * sc->data[SC_DEATHBOUND]->val2 / 100; // Amplify damage.
+ *dmg = rd1 * 30 / 100; // Received damge = 30% of amplifly damage.
+ clif_skill_damage(src,bl,gettick(), status_get_amotion(src), 0, -30000, 1, RK_DEATHBOUND, sc->data[SC_DEATHBOUND]->val1,6);
+ status_change_end(bl,SC_DEATHBOUND,INVALID_TIMER);
+ rdamage += rd1;
+ if (rdamage < 1) rdamage = 1;
+ }
+ }
+ }
+ } else {
+ if (sd && sd->bonus.long_weapon_damage_return) {
+ rdamage += damage * sd->bonus.long_weapon_damage_return / 100;
+ if (rdamage < 1) rdamage = 1;
+ }
+ }
- if (sc && sc->data[SC_KYOMU]) // Nullify reflecting ability
- rdamage = 0;
+ if( sc && sc->data[SC_KYOMU] ) // Nullify reflecting ability
+ rdamage = 0;
- return rdamage;
+ return rdamage;
}
void battle_drain(TBL_PC *sd, struct block_list *tbl, int rdamage, int ldamage, int race, int boss)
{
- struct weapon_data *wd;
- int type, thp = 0, tsp = 0, rhp = 0, rsp = 0, hp, sp, i, *damage;
- for (i = 0; i < 4; i++) {
- //First two iterations: Right hand
- if (i < 2) {
- wd = &sd->right_weapon;
- damage = &rdamage;
- } else {
- wd = &sd->left_weapon;
- damage = &ldamage;
- }
- if (*damage <= 0) continue;
- //First and Third iterations: race, other two boss/nonboss state
- if (i == 0 || i == 2)
- type = race;
- else
- type = boss?RC_BOSS:RC_NONBOSS;
-
- hp = wd->hp_drain[type].value;
- if (wd->hp_drain[type].rate)
- hp += battle_calc_drain(*damage, wd->hp_drain[type].rate, wd->hp_drain[type].per);
-
- sp = wd->sp_drain[type].value;
- if (wd->sp_drain[type].rate)
- sp += battle_calc_drain(*damage, wd->sp_drain[type].rate, wd->sp_drain[type].per);
-
- if (hp) {
- if (wd->hp_drain[type].type)
- rhp += hp;
- thp += hp;
- }
- if (sp) {
- if (wd->sp_drain[type].type)
- rsp += sp;
- tsp += sp;
- }
- }
+ struct weapon_data *wd;
+ int type, thp = 0, tsp = 0, rhp = 0, rsp = 0, hp, sp, i, *damage;
+ for (i = 0; i < 4; i++) {
+ //First two iterations: Right hand
+ if (i < 2) { wd = &sd->right_weapon; damage = &rdamage; }
+ else { wd = &sd->left_weapon; damage = &ldamage; }
+ if (*damage <= 0) continue;
+ //First and Third iterations: race, other two boss/nonboss state
+ if (i == 0 || i == 2)
+ type = race;
+ else
+ type = boss?RC_BOSS:RC_NONBOSS;
+
+ hp = wd->hp_drain[type].value;
+ if (wd->hp_drain[type].rate)
+ hp += battle_calc_drain(*damage, wd->hp_drain[type].rate, wd->hp_drain[type].per);
+
+ sp = wd->sp_drain[type].value;
+ if (wd->sp_drain[type].rate)
+ sp += battle_calc_drain(*damage, wd->sp_drain[type].rate, wd->sp_drain[type].per);
+
+ if (hp) {
+ if (wd->hp_drain[type].type)
+ rhp += hp;
+ thp += hp;
+ }
+ if (sp) {
+ if (wd->sp_drain[type].type)
+ rsp += sp;
+ tsp += sp;
+ }
+ }
- if (sd->bonus.sp_vanish_rate && rnd()%1000 < sd->bonus.sp_vanish_rate)
- status_percent_damage(&sd->bl, tbl, 0, (unsigned char)sd->bonus.sp_vanish_per, false);
+ if (sd->bonus.sp_vanish_rate && rnd()%1000 < sd->bonus.sp_vanish_rate)
+ status_percent_damage(&sd->bl, tbl, 0, (unsigned char)sd->bonus.sp_vanish_per, false);
- if (sd->sp_gain_race_attack[race])
- tsp += sd->sp_gain_race_attack[race];
- if (sd->hp_gain_race_attack[race])
- thp += sd->hp_gain_race_attack[race];
+ if( sd->sp_gain_race_attack[race] )
+ tsp += sd->sp_gain_race_attack[race];
+ if( sd->hp_gain_race_attack[race] )
+ thp += sd->hp_gain_race_attack[race];
- if (!thp && !tsp) return;
+ if (!thp && !tsp) return;
- status_heal(&sd->bl, thp, tsp, battle_config.show_hp_sp_drain?3:1);
+ status_heal(&sd->bl, thp, tsp, battle_config.show_hp_sp_drain?3:1);
- if (rhp || rsp)
- status_zap(tbl, rhp, rsp);
+ if (rhp || rsp)
+ status_zap(tbl, rhp, rsp);
}
// Deals the same damage to targets in area. [pakpil]
-int battle_damage_area(struct block_list *bl, va_list ap)
-{
- unsigned int tick;
- int amotion, dmotion, damage;
- struct block_list *src;
-
- nullpo_ret(bl);
-
- tick=va_arg(ap, unsigned int);
- src=va_arg(ap,struct block_list *);
- amotion=va_arg(ap,int);
- dmotion=va_arg(ap,int);
- damage=va_arg(ap,int);
- if (bl->type == BL_MOB && ((TBL_MOB *)bl)->class_ == MOBID_EMPERIUM)
- return 0;
- if (bl != src && battle_check_target(src,bl,BCT_ENEMY) > 0) {
- map_freeblock_lock();
- if (src->type == BL_PC)
- battle_drain((TBL_PC *)src, bl, damage, damage, status_get_race(bl), is_boss(bl));
- if (amotion)
- battle_delay_damage(tick, amotion,src,bl,0,CR_REFLECTSHIELD,0,damage,ATK_DEF,0);
- else
- status_fix_damage(src,bl,damage,0);
- clif_damage(bl,bl,tick,amotion,dmotion,damage,1,ATK_BLOCK,0);
- skill_additional_effect(src, bl, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick);
- map_freeblock_unlock();
- }
+int battle_damage_area( struct block_list *bl, va_list ap) {
+ unsigned int tick;
+ int amotion, dmotion, damage;
+ struct block_list *src;
+
+ nullpo_ret(bl);
+
+ tick=va_arg(ap, unsigned int);
+ src=va_arg(ap,struct block_list *);
+ amotion=va_arg(ap,int);
+ dmotion=va_arg(ap,int);
+ damage=va_arg(ap,int);
+ if( bl->type == BL_MOB && ((TBL_MOB*)bl)->class_ == MOBID_EMPERIUM )
+ return 0;
+ if( bl != src && battle_check_target(src,bl,BCT_ENEMY) > 0 ) {
+ map_freeblock_lock();
+ if( src->type == BL_PC )
+ battle_drain((TBL_PC*)src, bl, damage, damage, status_get_race(bl), is_boss(bl));
+ if( amotion )
+ battle_delay_damage(tick, amotion,src,bl,0,CR_REFLECTSHIELD,0,damage,ATK_DEF,0);
+ else
+ status_fix_damage(src,bl,damage,0);
+ clif_damage(bl,bl,tick,amotion,dmotion,damage,1,ATK_BLOCK,0);
+ skill_additional_effect(src, bl, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick);
+ map_freeblock_unlock();
+ }
- return 0;
+ return 0;
}
/*==========================================
* Do a basic physical attack (call trough unit_attack_timer)
*------------------------------------------*/
-enum damage_lv battle_weapon_attack(struct block_list *src, struct block_list *target, unsigned int tick, int flag)
-{
- struct map_session_data *sd = NULL, *tsd = NULL;
- struct status_data *sstatus, *tstatus;
- struct status_change *sc, *tsc;
- int damage,rdamage=0,rdelay=0;
- int skillv;
- struct Damage wd;
-
- nullpo_retr(ATK_NONE, src);
- nullpo_retr(ATK_NONE, target);
-
- if (src->prev == NULL || target->prev == NULL)
- return ATK_NONE;
-
- sd = BL_CAST(BL_PC, src);
- tsd = BL_CAST(BL_PC, target);
-
- sstatus = status_get_status_data(src);
- tstatus = status_get_status_data(target);
-
- sc = status_get_sc(src);
- tsc = status_get_sc(target);
-
- if (sc && !sc->count) //Avoid sc checks when there's none to check for. [Skotlex]
- sc = NULL;
- if (tsc && !tsc->count)
- tsc = NULL;
-
- if (sd) {
- sd->state.arrow_atk = (sd->status.weapon == W_BOW || (sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE));
- if (sd->state.arrow_atk) {
- int index = sd->equip_index[EQI_AMMO];
- if (index<0) {
- clif_arrow_fail(sd,0);
- return ATK_NONE;
- }
- //Ammo check by Ishizu-chan
- if (sd->inventory_data[index])
- switch (sd->status.weapon) {
- case W_BOW:
- if (sd->inventory_data[index]->look != A_ARROW) {
- clif_arrow_fail(sd,0);
- return ATK_NONE;
- }
- break;
- case W_REVOLVER:
- case W_RIFLE:
- case W_GATLING:
- case W_SHOTGUN:
- if (sd->inventory_data[index]->look != A_BULLET) {
- clif_arrow_fail(sd,0);
- return ATK_NONE;
- }
- break;
- case W_GRENADE:
- if (sd->inventory_data[index]->look != A_GRENADE) {
- clif_arrow_fail(sd,0);
- return ATK_NONE;
- }
- break;
- }
- }
- }
+enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* target, unsigned int tick, int flag) {
+ struct map_session_data *sd = NULL, *tsd = NULL;
+ struct status_data *sstatus, *tstatus;
+ struct status_change *sc, *tsc;
+ int damage,rdamage=0,rdelay=0;
+ int skillv;
+ struct Damage wd;
+
+ nullpo_retr(ATK_NONE, src);
+ nullpo_retr(ATK_NONE, target);
+
+ if (src->prev == NULL || target->prev == NULL)
+ return ATK_NONE;
+
+ sd = BL_CAST(BL_PC, src);
+ tsd = BL_CAST(BL_PC, target);
+
+ sstatus = status_get_status_data(src);
+ tstatus = status_get_status_data(target);
+
+ sc = status_get_sc(src);
+ tsc = status_get_sc(target);
+
+ if (sc && !sc->count) //Avoid sc checks when there's none to check for. [Skotlex]
+ sc = NULL;
+ if (tsc && !tsc->count)
+ tsc = NULL;
+
+ if (sd)
+ {
+ sd->state.arrow_atk = (sd->status.weapon == W_BOW || (sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE));
+ if (sd->state.arrow_atk)
+ {
+ int index = sd->equip_index[EQI_AMMO];
+ if (index<0) {
+ clif_arrow_fail(sd,0);
+ return ATK_NONE;
+ }
+ //Ammo check by Ishizu-chan
+ if (sd->inventory_data[index])
+ switch (sd->status.weapon) {
+ case W_BOW:
+ if (sd->inventory_data[index]->look != A_ARROW) {
+ clif_arrow_fail(sd,0);
+ return ATK_NONE;
+ }
+ break;
+ case W_REVOLVER:
+ case W_RIFLE:
+ case W_GATLING:
+ case W_SHOTGUN:
+ if (sd->inventory_data[index]->look != A_BULLET) {
+ clif_arrow_fail(sd,0);
+ return ATK_NONE;
+ }
+ break;
+ case W_GRENADE:
+ if (sd->inventory_data[index]->look != A_GRENADE) {
+ clif_arrow_fail(sd,0);
+ return ATK_NONE;
+ }
+ break;
+ }
+ }
+ }
if (sc && sc->count) {
if (sc->data[SC_CLOAKING] && !(sc->data[SC_CLOAKING]->val4 & 2))
status_change_end(src, SC_CLOAKING, INVALID_TIMER);
else if (sc->data[SC_CLOAKINGEXCEED] && !(sc->data[SC_CLOAKINGEXCEED]->val4 & 2))
status_change_end(src, SC_CLOAKINGEXCEED, INVALID_TIMER);
}
- if (tsc && tsc->data[SC_AUTOCOUNTER] && status_check_skilluse(target, src, KN_AUTOCOUNTER, 1)) {
- int dir = map_calc_dir(target,src->x,src->y);
- int t_dir = unit_getdir(target);
- int dist = distance_bl(src, target);
- if (dist <= 0 || (!map_check_dir(dir,t_dir) && dist <= tstatus->rhw.range+1)) {
- int skilllv = tsc->data[SC_AUTOCOUNTER]->val1;
- clif_skillcastcancel(target); //Remove the casting bar. [Skotlex]
- clif_damage(src, target, tick, sstatus->amotion, 1, 0, 1, 0, 0); //Display MISS.
- status_change_end(target, SC_AUTOCOUNTER, INVALID_TIMER);
- skill_attack(BF_WEAPON,target,target,src,KN_AUTOCOUNTER,skilllv,tick,0);
- return ATK_BLOCK;
- }
- }
+ if( tsc && tsc->data[SC_AUTOCOUNTER] && status_check_skilluse(target, src, KN_AUTOCOUNTER, 1) )
+ {
+ int dir = map_calc_dir(target,src->x,src->y);
+ int t_dir = unit_getdir(target);
+ int dist = distance_bl(src, target);
+ if(dist <= 0 || (!map_check_dir(dir,t_dir) && dist <= tstatus->rhw.range+1))
+ {
+ int skilllv = tsc->data[SC_AUTOCOUNTER]->val1;
+ clif_skillcastcancel(target); //Remove the casting bar. [Skotlex]
+ clif_damage(src, target, tick, sstatus->amotion, 1, 0, 1, 0, 0); //Display MISS.
+ status_change_end(target, SC_AUTOCOUNTER, INVALID_TIMER);
+ skill_attack(BF_WEAPON,target,target,src,KN_AUTOCOUNTER,skilllv,tick,0);
+ return ATK_BLOCK;
+ }
+ }
- if (tsc && tsc->data[SC_BLADESTOP_WAIT] && !is_boss(src) && (src->type == BL_PC || tsd == NULL || distance_bl(src, target) <= (tsd->status.weapon == W_FIST ? 1 : 2))) {
- int skilllv = tsc->data[SC_BLADESTOP_WAIT]->val1;
- int duration = skill_get_time2(MO_BLADESTOP,skilllv);
- status_change_end(target, SC_BLADESTOP_WAIT, INVALID_TIMER);
- if (sc_start4(src, SC_BLADESTOP, 100, sd?pc_checkskill(sd, MO_BLADESTOP):5, 0, 0, target->id, duration)) {
- //Target locked.
- clif_damage(src, target, tick, sstatus->amotion, 1, 0, 1, 0, 0); //Display MISS.
- clif_bladestop(target, src->id, 1);
- sc_start4(target, SC_BLADESTOP, 100, skilllv, 0, 0, src->id, duration);
- return ATK_BLOCK;
- }
- }
+ if( tsc && tsc->data[SC_BLADESTOP_WAIT] && !is_boss(src) && (src->type == BL_PC || tsd == NULL || distance_bl(src, target) <= (tsd->status.weapon == W_FIST ? 1 : 2)) )
+ {
+ int skilllv = tsc->data[SC_BLADESTOP_WAIT]->val1;
+ int duration = skill_get_time2(MO_BLADESTOP,skilllv);
+ status_change_end(target, SC_BLADESTOP_WAIT, INVALID_TIMER);
+ if(sc_start4(src, SC_BLADESTOP, 100, sd?pc_checkskill(sd, MO_BLADESTOP):5, 0, 0, target->id, duration))
+ { //Target locked.
+ clif_damage(src, target, tick, sstatus->amotion, 1, 0, 1, 0, 0); //Display MISS.
+ clif_bladestop(target, src->id, 1);
+ sc_start4(target, SC_BLADESTOP, 100, skilllv, 0, 0, src->id, duration);
+ return ATK_BLOCK;
+ }
+ }
- if (sd && (skillv = pc_checkskill(sd,MO_TRIPLEATTACK)) > 0) {
- int triple_rate= 30 - skillv; //Base Rate
- if (sc && sc->data[SC_SKILLRATE_UP] && sc->data[SC_SKILLRATE_UP]->val1 == MO_TRIPLEATTACK) {
- triple_rate+= triple_rate*(sc->data[SC_SKILLRATE_UP]->val2)/100;
- status_change_end(src, SC_SKILLRATE_UP, INVALID_TIMER);
- }
- if (rnd()%100 < triple_rate) {
- if (skill_attack(BF_WEAPON,src,src,target,MO_TRIPLEATTACK,skillv,tick,0))
- return ATK_DEF;
- return ATK_MISS;
- }
- }
+ if(sd && (skillv = pc_checkskill(sd,MO_TRIPLEATTACK)) > 0) {
+ int triple_rate= 30 - skillv; //Base Rate
+ if (sc && sc->data[SC_SKILLRATE_UP] && sc->data[SC_SKILLRATE_UP]->val1 == MO_TRIPLEATTACK) {
+ triple_rate+= triple_rate*(sc->data[SC_SKILLRATE_UP]->val2)/100;
+ status_change_end(src, SC_SKILLRATE_UP, INVALID_TIMER);
+ }
+ if (rnd()%100 < triple_rate) {
+ if( skill_attack(BF_WEAPON,src,src,target,MO_TRIPLEATTACK,skillv,tick,0) )
+ return ATK_DEF;
+ return ATK_MISS;
+ }
+ }
- if (sc) {
- if (sc->data[SC_SACRIFICE]) {
- int skilllv = sc->data[SC_SACRIFICE]->val1;
- damage_lv ret_val;
+ if (sc) {
+ if (sc->data[SC_SACRIFICE]) {
+ int skilllv = sc->data[SC_SACRIFICE]->val1;
+ damage_lv ret_val;
- if (--sc->data[SC_SACRIFICE]->val2 <= 0)
- status_change_end(src, SC_SACRIFICE, INVALID_TIMER);
+ if( --sc->data[SC_SACRIFICE]->val2 <= 0 )
+ status_change_end(src, SC_SACRIFICE, INVALID_TIMER);
- /**
- * We need to calculate the DMG before the hp reduction, because it can kill the source.
- * For futher information: bugreport:4950
- **/
- ret_val = (damage_lv)skill_attack(BF_WEAPON,src,src,target,PA_SACRIFICE,skilllv,tick,0);
+ /**
+ * We need to calculate the DMG before the hp reduction, because it can kill the source.
+ * For futher information: bugreport:4950
+ **/
+ ret_val = (damage_lv)skill_attack(BF_WEAPON,src,src,target,PA_SACRIFICE,skilllv,tick,0);
- status_zap(src, sstatus->max_hp*9/100, 0);//Damage to self is always 9%
- if (ret_val == ATK_NONE)
- return ATK_MISS;
- return ret_val;
- }
- if (sc->data[SC_MAGICALATTACK]) {
- if (skill_attack(BF_MAGIC,src,src,target,NPC_MAGICALATTACK,sc->data[SC_MAGICALATTACK]->val1,tick,0))
- return ATK_DEF;
- return ATK_MISS;
- }
- if (sc->data[SC_GT_ENERGYGAIN]) {
- if (sd && rnd()%100 < 10 + 5 * sc->data[SC_GT_ENERGYGAIN]->val1)
- pc_addspiritball(sd,
- skill_get_time(MO_CALLSPIRITS, sc->data[SC_GT_ENERGYGAIN]->val1),
- sc->data[SC_GT_ENERGYGAIN]->val1);
- }
- if (tsc && tsc->data[SC_GT_ENERGYGAIN]) {
- if (tsd && rnd()%100 < 10 + 5 * tsc->data[SC_GT_ENERGYGAIN]->val1)
- pc_addspiritball(tsd,
- skill_get_time(MO_CALLSPIRITS, tsc->data[SC_GT_ENERGYGAIN]->val1),
- tsc->data[SC_GT_ENERGYGAIN]->val1);
- }
+ status_zap(src, sstatus->max_hp*9/100, 0);//Damage to self is always 9%
+ if( ret_val == ATK_NONE )
+ return ATK_MISS;
+ return ret_val;
+ }
+ if (sc->data[SC_MAGICALATTACK]) {
+ if( skill_attack(BF_MAGIC,src,src,target,NPC_MAGICALATTACK,sc->data[SC_MAGICALATTACK]->val1,tick,0) )
+ return ATK_DEF;
+ return ATK_MISS;
+ }
+ if( sc->data[SC_GT_ENERGYGAIN] ) {
+ if( sd && rnd()%100 < 10 + 5 * sc->data[SC_GT_ENERGYGAIN]->val1)
+ pc_addspiritball(sd,
+ skill_get_time(MO_CALLSPIRITS, sc->data[SC_GT_ENERGYGAIN]->val1),
+ sc->data[SC_GT_ENERGYGAIN]->val1);
+ }
+ if( tsc && tsc->data[SC_GT_ENERGYGAIN] ) {
+ if( tsd && rnd()%100 < 10 + 5 * tsc->data[SC_GT_ENERGYGAIN]->val1)
+ pc_addspiritball(tsd,
+ skill_get_time(MO_CALLSPIRITS, tsc->data[SC_GT_ENERGYGAIN]->val1),
+ tsc->data[SC_GT_ENERGYGAIN]->val1);
+ }
- }
+ }
- if (tsc && tsc->data[SC_KAAHI] && tsc->data[SC_KAAHI]->val4 == INVALID_TIMER && tstatus->hp < tstatus->max_hp)
- tsc->data[SC_KAAHI]->val4 = add_timer(tick + skill_get_time2(SL_KAAHI,tsc->data[SC_KAAHI]->val1), kaahi_heal_timer, target->id, SC_KAAHI); //Activate heal.
+ if(tsc && tsc->data[SC_KAAHI] && tsc->data[SC_KAAHI]->val4 == INVALID_TIMER && tstatus->hp < tstatus->max_hp)
+ tsc->data[SC_KAAHI]->val4 = add_timer(tick + skill_get_time2(SL_KAAHI,tsc->data[SC_KAAHI]->val1), kaahi_heal_timer, target->id, SC_KAAHI); //Activate heal.
- wd = battle_calc_attack(BF_WEAPON, src, target, 0, 0, flag);
+ wd = battle_calc_attack(BF_WEAPON, src, target, 0, 0, flag);
- if (sc && sc->count) {
- if (sc->data[SC_EXEEDBREAK]) {
- wd.damage = wd.damage * sc->data[SC_EXEEDBREAK]->val1 / 100;
- status_change_end(src, SC_EXEEDBREAK, INVALID_TIMER);
- }
- if (sc->data[SC_SPELLFIST]) {
- if (--(sc->data[SC_SPELLFIST]->val1) >= 0) {
- struct Damage ad = battle_calc_attack(BF_MAGIC,src,target,sc->data[SC_SPELLFIST]->val3,sc->data[SC_SPELLFIST]->val4,flag|BF_SHORT);
- wd.damage = ad.damage;
- } else
- status_change_end(src,SC_SPELLFIST,INVALID_TIMER);
- }
- if (sc->data[SC_GIANTGROWTH] && (wd.flag&BF_SHORT) && rnd()%100 < sc->data[SC_GIANTGROWTH]->val2)
- wd.damage *= 3; // Triple Damage
+ if( sc && sc->count ) {
+ if (sc->data[SC_EXEEDBREAK]) {
+ wd.damage = wd.damage * sc->data[SC_EXEEDBREAK]->val1 / 100;
+ status_change_end(src, SC_EXEEDBREAK, INVALID_TIMER);
+ }
+ if( sc->data[SC_SPELLFIST] ) {
+ if( --(sc->data[SC_SPELLFIST]->val1) >= 0 ){
+ struct Damage ad = battle_calc_attack(BF_MAGIC,src,target,sc->data[SC_SPELLFIST]->val3,sc->data[SC_SPELLFIST]->val4,flag|BF_SHORT);
+ wd.damage = ad.damage;
+ }else
+ status_change_end(src,SC_SPELLFIST,INVALID_TIMER);
+ }
+ if( sc->data[SC_GIANTGROWTH] && (wd.flag&BF_SHORT) && rnd()%100 < sc->data[SC_GIANTGROWTH]->val2 )
+ wd.damage *= 3; // Triple Damage
- if (sd && sc->data[SC_FEARBREEZE] && sc->data[SC_FEARBREEZE]->val4 > 0 && sd->status.inventory[sd->equip_index[EQI_AMMO]].amount >= sc->data[SC_FEARBREEZE]->val4 && battle_config.arrow_decrement) {
- pc_delitem(sd,sd->equip_index[EQI_AMMO],sc->data[SC_FEARBREEZE]->val4,0,1,LOG_TYPE_CONSUME);
- sc->data[SC_FEARBREEZE]->val4 = 0;
- }
- }
- if (sd && sd->state.arrow_atk) //Consume arrow.
- battle_consume_ammo(sd, 0, 0);
-
- damage = wd.damage + wd.damage2;
- if (damage > 0 && src != target) {
- if (sc && sc->data[SC_DUPLELIGHT] && (wd.flag&BF_SHORT) && rnd()%100 <= 10+2*sc->data[SC_DUPLELIGHT]->val1) {
- // Activates it only from melee damage
- int skillid;
- if (rnd()%2 == 1)
- skillid = AB_DUPLELIGHT_MELEE;
- else
- skillid = AB_DUPLELIGHT_MAGIC;
- skill_attack(skill_get_type(skillid), src, src, target, skillid, sc->data[SC_DUPLELIGHT]->val1, tick, SD_LEVEL);
- }
+ if( sd && sc->data[SC_FEARBREEZE] && sc->data[SC_FEARBREEZE]->val4 > 0 && sd->status.inventory[sd->equip_index[EQI_AMMO]].amount >= sc->data[SC_FEARBREEZE]->val4 && battle_config.arrow_decrement){
+ pc_delitem(sd,sd->equip_index[EQI_AMMO],sc->data[SC_FEARBREEZE]->val4,0,1,LOG_TYPE_CONSUME);
+ sc->data[SC_FEARBREEZE]->val4 = 0;
+ }
+ }
+ if (sd && sd->state.arrow_atk) //Consume arrow.
+ battle_consume_ammo(sd, 0, 0);
+
+ damage = wd.damage + wd.damage2;
+ if( damage > 0 && src != target )
+ {
+ if( sc && sc->data[SC_DUPLELIGHT] && (wd.flag&BF_SHORT) && rnd()%100 <= 10+2*sc->data[SC_DUPLELIGHT]->val1 )
+ { // Activates it only from melee damage
+ int skillid;
+ if( rnd()%2 == 1 )
+ skillid = AB_DUPLELIGHT_MELEE;
+ else
+ skillid = AB_DUPLELIGHT_MAGIC;
+ skill_attack(skill_get_type(skillid), src, src, target, skillid, sc->data[SC_DUPLELIGHT]->val1, tick, SD_LEVEL);
+ }
- rdamage = battle_calc_return_damage(target,src, &damage, wd.flag, 0);
- if (rdamage > 0) {
- if (tsc && tsc->data[SC_REFLECTDAMAGE]) {
- if (src != target) // Don't reflect your own damage (Grand Cross)
- map_foreachinshootrange(battle_damage_area,target,skill_get_splash(LG_REFLECTDAMAGE,1),BL_CHAR,tick,target,wd.amotion,wd.dmotion,rdamage,tstatus->race,0);
- } else {
- rdelay = clif_damage(src, src, tick, wd.amotion, sstatus->dmotion, rdamage, 1, 4, 0);
- //Use Reflect Shield to signal this kind of skill trigger. [Skotlex]
- skill_additional_effect(target,src,CR_REFLECTSHIELD,1,BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick);
- }
- }
- }
+ rdamage = battle_calc_return_damage(target,src, &damage, wd.flag, 0);
+ if( rdamage > 0 ) {
+ if( tsc && tsc->data[SC_REFLECTDAMAGE] ) {
+ if( src != target )// Don't reflect your own damage (Grand Cross)
+ map_foreachinshootrange(battle_damage_area,target,skill_get_splash(LG_REFLECTDAMAGE,1),BL_CHAR,tick,target,wd.amotion,wd.dmotion,rdamage,tstatus->race,0);
+ } else {
+ rdelay = clif_damage(src, src, tick, wd.amotion, sstatus->dmotion, rdamage, 1, 4, 0);
+ //Use Reflect Shield to signal this kind of skill trigger. [Skotlex]
+ skill_additional_effect(target,src,CR_REFLECTSHIELD,1,BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick);
+ }
+ }
+ }
- wd.dmotion = clif_damage(src, target, tick, wd.amotion, wd.dmotion, wd.damage, wd.div_ , wd.type, wd.damage2);
+ wd.dmotion = clif_damage(src, target, tick, wd.amotion, wd.dmotion, wd.damage, wd.div_ , wd.type, wd.damage2);
- if (sd && sd->bonus.splash_range > 0 && damage > 0)
- skill_castend_damage_id(src, target, 0, 1, tick, 0);
- if (target->type == BL_SKILL && damage > 0) {
- TBL_SKILL *su = (TBL_SKILL *)target;
- if (su->group && su->group->skill_id == HT_BLASTMINE)
- skill_blown(src, target, 3, -1, 0);
- }
- map_freeblock_lock();
-
- battle_delay_damage(tick, wd.amotion, src, target, wd.flag, 0, 0, damage, wd.dmg_lv, wd.dmotion);
- if (tsc) {
- if (tsc->data[SC_DEVOTION]) {
- struct status_change_entry *sce = tsc->data[SC_DEVOTION];
- struct block_list *d_bl = map_id2bl(sce->val1);
-
- if (d_bl && (
- (d_bl->type == BL_MER && ((TBL_MER *)d_bl)->master && ((TBL_MER *)d_bl)->master->bl.id == target->id) ||
- (d_bl->type == BL_PC && ((TBL_PC *)d_bl)->devotion[sce->val2] == target->id)
- ) && check_distance_bl(target, d_bl, sce->val3)) {
- clif_damage(d_bl, d_bl, gettick(), 0, 0, damage, 0, 0, 0);
- status_fix_damage(NULL, d_bl, damage, 0);
- } else
- status_change_end(target, SC_DEVOTION, INVALID_TIMER);
- } else if (tsc->data[SC_CIRCLE_OF_FIRE_OPTION] && (wd.flag&BF_SHORT) && target->type == BL_PC) {
- struct elemental_data *ed = ((TBL_PC *)target)->ed;
- if (ed) {
- clif_skill_damage(&ed->bl, target, tick, status_get_amotion(src), 0, -30000, 1, EL_CIRCLE_OF_FIRE, tsc->data[SC_CIRCLE_OF_FIRE_OPTION]->val1, 6);
- skill_attack(BF_MAGIC,&ed->bl,&ed->bl,src,EL_CIRCLE_OF_FIRE,tsc->data[SC_CIRCLE_OF_FIRE_OPTION]->val1,tick,wd.flag);
- }
- } else if (tsc->data[SC_WATER_SCREEN_OPTION] && tsc->data[SC_WATER_SCREEN_OPTION]->val1) {
- struct block_list *e_bl = map_id2bl(tsc->data[SC_WATER_SCREEN_OPTION]->val1);
- if (e_bl && !status_isdead(e_bl)) {
- clif_damage(e_bl,e_bl,tick,wd.amotion,wd.dmotion,damage,wd.div_,wd.type,wd.damage2);
- status_damage(target,e_bl,damage,0,0,0);
- // Just show damage in target.
- clif_damage(src, target, tick, wd.amotion, wd.dmotion, damage, wd.div_, wd.type, wd.damage2);
- map_freeblock_unlock();
- return ATK_NONE;
- }
- }
- }
- if (sc && sc->data[SC_AUTOSPELL] && rnd()%100 < sc->data[SC_AUTOSPELL]->val4) {
- int sp = 0;
- int skillid = sc->data[SC_AUTOSPELL]->val2;
- int skilllv = sc->data[SC_AUTOSPELL]->val3;
- int i = rnd()%100;
- if (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_SAGE)
- i = 0; //Max chance, no skilllv reduction. [Skotlex]
- if (i >= 50) skilllv -= 2;
- else if (i >= 15) skilllv--;
- if (skilllv < 1) skilllv = 1;
- sp = skill_get_sp(skillid,skilllv) * 2 / 3;
-
- if (status_charge(src, 0, sp)) {
- switch (skill_get_casttype(skillid)) {
- case CAST_GROUND:
- skill_castend_pos2(src, target->x, target->y, skillid, skilllv, tick, flag);
- break;
- case CAST_NODAMAGE:
- skill_castend_nodamage_id(src, target, skillid, skilllv, tick, flag);
- break;
- case CAST_DAMAGE:
- skill_castend_damage_id(src, target, skillid, skilllv, tick, flag);
- break;
- }
- }
- }
- if (sd) {
- if (wd.flag&BF_SHORT && sc && sc->data[SC__AUTOSHADOWSPELL] && rnd()%100 < sc->data[SC__AUTOSHADOWSPELL]->val3 &&
- sd->status.skill[sc->data[SC__AUTOSHADOWSPELL]->val1].id != 0 && sd->status.skill[sc->data[SC__AUTOSHADOWSPELL]->val1].flag == SKILL_FLAG_PLAGIARIZED) {
- int r_skill = sd->status.skill[sc->data[SC__AUTOSHADOWSPELL]->val1].id,
- r_lv = sc->data[SC__AUTOSHADOWSPELL]->val2, type;
-
- if (r_skill != AL_HOLYLIGHT && r_skill != PR_MAGNUS) {
- if ((type = skill_get_casttype(r_skill)) == CAST_GROUND) {
- int maxcount = 0;
-
- if (!(BL_PC&battle_config.skill_reiteration) &&
- skill_get_unit_flag(r_skill)&UF_NOREITERATION)
- type = -1;
-
- if (BL_PC&battle_config.skill_nofootset &&
- skill_get_unit_flag(r_skill)&UF_NOFOOTSET)
- type = -1;
-
- if (BL_PC&battle_config.land_skill_limit &&
- (maxcount = skill_get_maxcount(r_skill, r_lv)) > 0
- ) {
- int v;
- for (v=0; v<MAX_SKILLUNITGROUP && sd->ud.skillunit[v] && maxcount; v++) {
- if (sd->ud.skillunit[v]->skill_id == r_skill)
- maxcount--;
- }
- if (maxcount == 0)
- type = -1;
- }
-
- if (type != CAST_GROUND) {
- clif_skill_fail(sd,r_skill,USESKILL_FAIL_LEVEL,0);
- map_freeblock_unlock();
- return wd.dmg_lv;
- }
- }
-
- sd->state.autocast = 1;
- skill_consume_requirement(sd,r_skill,r_lv,3);
- switch (type) {
- case CAST_GROUND:
- skill_castend_pos2(src, target->x, target->y, r_skill, r_lv, tick, flag);
- break;
- case CAST_NODAMAGE:
- skill_castend_nodamage_id(src, target, r_skill, r_lv, tick, flag);
- break;
- case CAST_DAMAGE:
- skill_castend_damage_id(src, target, r_skill, r_lv, tick, flag);
- break;
- }
- sd->state.autocast = 0;
+ if (sd && sd->bonus.splash_range > 0 && damage > 0)
+ skill_castend_damage_id(src, target, 0, 1, tick, 0);
+ if ( target->type == BL_SKILL && damage > 0 ){
+ TBL_SKILL *su = (TBL_SKILL*)target;
+ if( su->group && su->group->skill_id == HT_BLASTMINE)
+ skill_blown(src, target, 3, -1, 0);
+ }
+ map_freeblock_lock();
+
+ battle_delay_damage(tick, wd.amotion, src, target, wd.flag, 0, 0, damage, wd.dmg_lv, wd.dmotion);
+ if( tsc ) {
+ if( tsc->data[SC_DEVOTION] ) {
+ struct status_change_entry *sce = tsc->data[SC_DEVOTION];
+ struct block_list *d_bl = map_id2bl(sce->val1);
+
+ if( d_bl && (
+ (d_bl->type == BL_MER && ((TBL_MER*)d_bl)->master && ((TBL_MER*)d_bl)->master->bl.id == target->id) ||
+ (d_bl->type == BL_PC && ((TBL_PC*)d_bl)->devotion[sce->val2] == target->id)
+ ) && check_distance_bl(target, d_bl, sce->val3) )
+ {
+ clif_damage(d_bl, d_bl, gettick(), 0, 0, damage, 0, 0, 0);
+ status_fix_damage(NULL, d_bl, damage, 0);
+ }
+ else
+ status_change_end(target, SC_DEVOTION, INVALID_TIMER);
+ } else if( tsc->data[SC_CIRCLE_OF_FIRE_OPTION] && (wd.flag&BF_SHORT) && target->type == BL_PC ) {
+ struct elemental_data *ed = ((TBL_PC*)target)->ed;
+ if( ed ) {
+ clif_skill_damage(&ed->bl, target, tick, status_get_amotion(src), 0, -30000, 1, EL_CIRCLE_OF_FIRE, tsc->data[SC_CIRCLE_OF_FIRE_OPTION]->val1, 6);
+ skill_attack(BF_MAGIC,&ed->bl,&ed->bl,src,EL_CIRCLE_OF_FIRE,tsc->data[SC_CIRCLE_OF_FIRE_OPTION]->val1,tick,wd.flag);
+ }
+ } else if( tsc->data[SC_WATER_SCREEN_OPTION] && tsc->data[SC_WATER_SCREEN_OPTION]->val1 ) {
+ struct block_list *e_bl = map_id2bl(tsc->data[SC_WATER_SCREEN_OPTION]->val1);
+ if( e_bl && !status_isdead(e_bl) ) {
+ clif_damage(e_bl,e_bl,tick,wd.amotion,wd.dmotion,damage,wd.div_,wd.type,wd.damage2);
+ status_damage(target,e_bl,damage,0,0,0);
+ // Just show damage in target.
+ clif_damage(src, target, tick, wd.amotion, wd.dmotion, damage, wd.div_, wd.type, wd.damage2 );
+ map_freeblock_unlock();
+ return ATK_NONE;
+ }
+ }
+ }
+ if (sc && sc->data[SC_AUTOSPELL] && rnd()%100 < sc->data[SC_AUTOSPELL]->val4) {
+ int sp = 0;
+ int skillid = sc->data[SC_AUTOSPELL]->val2;
+ int skilllv = sc->data[SC_AUTOSPELL]->val3;
+ int i = rnd()%100;
+ if (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_SAGE)
+ i = 0; //Max chance, no skilllv reduction. [Skotlex]
+ if (i >= 50) skilllv -= 2;
+ else if (i >= 15) skilllv--;
+ if (skilllv < 1) skilllv = 1;
+ sp = skill_get_sp(skillid,skilllv) * 2 / 3;
+
+ if (status_charge(src, 0, sp)) {
+ switch (skill_get_casttype(skillid)) {
+ case CAST_GROUND:
+ skill_castend_pos2(src, target->x, target->y, skillid, skilllv, tick, flag);
+ break;
+ case CAST_NODAMAGE:
+ skill_castend_nodamage_id(src, target, skillid, skilllv, tick, flag);
+ break;
+ case CAST_DAMAGE:
+ skill_castend_damage_id(src, target, skillid, skilllv, tick, flag);
+ break;
+ }
+ }
+ }
+ if (sd) {
+ if( wd.flag&BF_SHORT && sc && sc->data[SC__AUTOSHADOWSPELL] && rnd()%100 < sc->data[SC__AUTOSHADOWSPELL]->val3 &&
+ sd->status.skill[sc->data[SC__AUTOSHADOWSPELL]->val1].id != 0 && sd->status.skill[sc->data[SC__AUTOSHADOWSPELL]->val1].flag == SKILL_FLAG_PLAGIARIZED )
+ {
+ int r_skill = sd->status.skill[sc->data[SC__AUTOSHADOWSPELL]->val1].id,
+ r_lv = sc->data[SC__AUTOSHADOWSPELL]->val2, type;
+
+ if (r_skill != AL_HOLYLIGHT && r_skill != PR_MAGNUS) {
+ if( (type = skill_get_casttype(r_skill)) == CAST_GROUND ) {
+ int maxcount = 0;
+
+ if( !(BL_PC&battle_config.skill_reiteration) &&
+ skill_get_unit_flag(r_skill)&UF_NOREITERATION )
+ type = -1;
+
+ if( BL_PC&battle_config.skill_nofootset &&
+ skill_get_unit_flag(r_skill)&UF_NOFOOTSET )
+ type = -1;
+
+ if( BL_PC&battle_config.land_skill_limit &&
+ (maxcount = skill_get_maxcount(r_skill, r_lv)) > 0
+ ) {
+ int v;
+ for(v=0;v<MAX_SKILLUNITGROUP && sd->ud.skillunit[v] && maxcount;v++) {
+ if(sd->ud.skillunit[v]->skill_id == r_skill)
+ maxcount--;
+ }
+ if( maxcount == 0 )
+ type = -1;
+ }
- sd->ud.canact_tick = tick + skill_delayfix(src, r_skill, r_lv);
- clif_status_change(src, SI_ACTIONDELAY, 1, skill_delayfix(src, r_skill, r_lv), 0, 0, 1);
- }
- }
+ if( type != CAST_GROUND ){
+ clif_skill_fail(sd,r_skill,USESKILL_FAIL_LEVEL,0);
+ map_freeblock_unlock();
+ return wd.dmg_lv;
+ }
+ }
- if (wd.flag & BF_WEAPON && src != target && damage > 0) {
- if (battle_config.left_cardfix_to_right)
- battle_drain(sd, target, wd.damage, wd.damage, tstatus->race, is_boss(target));
- else
- battle_drain(sd, target, wd.damage, wd.damage2, tstatus->race, is_boss(target));
- }
- }
- if (rdamage > 0 && !(tsc && tsc->data[SC_REFLECTDAMAGE])) { //By sending attack type "none" skill_additional_effect won't be invoked. [Skotlex]
- if (tsd && src != target)
- battle_drain(tsd, src, rdamage, rdamage, sstatus->race, is_boss(src));
- battle_delay_damage(tick, wd.amotion, target, src, 0, CR_REFLECTSHIELD, 0, rdamage, ATK_DEF, rdelay);
- }
+ sd->state.autocast = 1;
+ skill_consume_requirement(sd,r_skill,r_lv,3);
+ switch( type ) {
+ case CAST_GROUND:
+ skill_castend_pos2(src, target->x, target->y, r_skill, r_lv, tick, flag);
+ break;
+ case CAST_NODAMAGE:
+ skill_castend_nodamage_id(src, target, r_skill, r_lv, tick, flag);
+ break;
+ case CAST_DAMAGE:
+ skill_castend_damage_id(src, target, r_skill, r_lv, tick, flag);
+ break;
+ }
+ sd->state.autocast = 0;
- if (tsc) {
- if (tsc->data[SC_POISONREACT] &&
- (rnd()%100 < tsc->data[SC_POISONREACT]->val3
- || sstatus->def_ele == ELE_POISON) &&
- // check_distance_bl(src, target, tstatus->rhw.range+1) && Doesn't checks range! o.O;
- status_check_skilluse(target, src, TF_POISON, 0)
- ) { //Poison React
- struct status_change_entry *sce = tsc->data[SC_POISONREACT];
- if (sstatus->def_ele == ELE_POISON) {
- sce->val2 = 0;
- skill_attack(BF_WEAPON,target,target,src,AS_POISONREACT,sce->val1,tick,0);
- } else {
- skill_attack(BF_WEAPON,target,target,src,TF_POISON, 5, tick, 0);
- --sce->val2;
- }
- if (sce->val2 <= 0)
- status_change_end(target, SC_POISONREACT, INVALID_TIMER);
- }
- }
- map_freeblock_unlock();
- return wd.dmg_lv;
+ sd->ud.canact_tick = tick + skill_delayfix(src, r_skill, r_lv);
+ clif_status_change(src, SI_ACTIONDELAY, 1, skill_delayfix(src, r_skill, r_lv), 0, 0, 1);
+ }
+ }
+
+ if (wd.flag & BF_WEAPON && src != target && damage > 0) {
+ if (battle_config.left_cardfix_to_right)
+ battle_drain(sd, target, wd.damage, wd.damage, tstatus->race, is_boss(target));
+ else
+ battle_drain(sd, target, wd.damage, wd.damage2, tstatus->race, is_boss(target));
+ }
+ }
+ if (rdamage > 0 && !(tsc && tsc->data[SC_REFLECTDAMAGE])) { //By sending attack type "none" skill_additional_effect won't be invoked. [Skotlex]
+ if(tsd && src != target)
+ battle_drain(tsd, src, rdamage, rdamage, sstatus->race, is_boss(src));
+ battle_delay_damage(tick, wd.amotion, target, src, 0, CR_REFLECTSHIELD, 0, rdamage, ATK_DEF, rdelay);
+ }
+
+ if (tsc) {
+ if (tsc->data[SC_POISONREACT] &&
+ (rnd()%100 < tsc->data[SC_POISONREACT]->val3
+ || sstatus->def_ele == ELE_POISON) &&
+// check_distance_bl(src, target, tstatus->rhw.range+1) && Doesn't checks range! o.O;
+ status_check_skilluse(target, src, TF_POISON, 0)
+ ) { //Poison React
+ struct status_change_entry *sce = tsc->data[SC_POISONREACT];
+ if (sstatus->def_ele == ELE_POISON) {
+ sce->val2 = 0;
+ skill_attack(BF_WEAPON,target,target,src,AS_POISONREACT,sce->val1,tick,0);
+ } else {
+ skill_attack(BF_WEAPON,target,target,src,TF_POISON, 5, tick, 0);
+ --sce->val2;
+ }
+ if (sce->val2 <= 0)
+ status_change_end(target, SC_POISONREACT, INVALID_TIMER);
+ }
+ }
+ map_freeblock_unlock();
+ return wd.dmg_lv;
}
int battle_check_undead(int race,int element)
{
- if (battle_config.undead_detect_type == 0) {
- if (element == ELE_UNDEAD)
- return 1;
- } else if (battle_config.undead_detect_type == 1) {
- if (race == RC_UNDEAD)
- return 1;
- } else {
- if (element == ELE_UNDEAD || race == RC_UNDEAD)
- return 1;
- }
- return 0;
+ if(battle_config.undead_detect_type == 0) {
+ if(element == ELE_UNDEAD)
+ return 1;
+ }
+ else if(battle_config.undead_detect_type == 1) {
+ if(race == RC_UNDEAD)
+ return 1;
+ }
+ else {
+ if(element == ELE_UNDEAD || race == RC_UNDEAD)
+ return 1;
+ }
+ return 0;
}
//Returns the upmost level master starting with the given object
-struct block_list *battle_get_master(struct block_list *src) {
- struct block_list *prev; //Used for infinite loop check (master of yourself?)
- do {
- prev = src;
- switch (src->type) {
- case BL_PET:
- if (((TBL_PET *)src)->msd)
- src = (struct block_list *)((TBL_PET *)src)->msd;
- break;
- case BL_MOB:
- if (((TBL_MOB *)src)->master_id)
- src = map_id2bl(((TBL_MOB *)src)->master_id);
- break;
- case BL_HOM:
- if (((TBL_HOM *)src)->master)
- src = (struct block_list *)((TBL_HOM *)src)->master;
- break;
- case BL_MER:
- if (((TBL_MER *)src)->master)
- src = (struct block_list *)((TBL_MER *)src)->master;
- break;
- case BL_ELEM:
- if (((TBL_ELEM *)src)->master)
- src = (struct block_list *)((TBL_ELEM *)src)->master;
- break;
- case BL_SKILL:
- if (((TBL_SKILL *)src)->group && ((TBL_SKILL *)src)->group->src_id)
- src = map_id2bl(((TBL_SKILL *)src)->group->src_id);
- break;
- }
- } while (src && src != prev);
- return prev;
+struct block_list* battle_get_master(struct block_list *src)
+{
+ struct block_list *prev; //Used for infinite loop check (master of yourself?)
+ do {
+ prev = src;
+ switch (src->type) {
+ case BL_PET:
+ if (((TBL_PET*)src)->msd)
+ src = (struct block_list*)((TBL_PET*)src)->msd;
+ break;
+ case BL_MOB:
+ if (((TBL_MOB*)src)->master_id)
+ src = map_id2bl(((TBL_MOB*)src)->master_id);
+ break;
+ case BL_HOM:
+ if (((TBL_HOM*)src)->master)
+ src = (struct block_list*)((TBL_HOM*)src)->master;
+ break;
+ case BL_MER:
+ if (((TBL_MER*)src)->master)
+ src = (struct block_list*)((TBL_MER*)src)->master;
+ break;
+ case BL_ELEM:
+ if (((TBL_ELEM*)src)->master)
+ src = (struct block_list*)((TBL_ELEM*)src)->master;
+ break;
+ case BL_SKILL:
+ if (((TBL_SKILL*)src)->group && ((TBL_SKILL*)src)->group->src_id)
+ src = map_id2bl(((TBL_SKILL*)src)->group->src_id);
+ break;
+ }
+ } while (src && src != prev);
+ return prev;
}
/*==========================================
@@ -5044,309 +5071,324 @@ struct block_list *battle_get_master(struct block_list *src) {
* -1: flag fails
* 0: Invalid target (non-targetable ever)
*------------------------------------------*/
-int battle_check_target(struct block_list *src, struct block_list *target,int flag)
+int battle_check_target( struct block_list *src, struct block_list *target,int flag)
{
- int m,state = 0; //Initial state none
- int strip_enemy = 1; //Flag which marks whether to remove the BCT_ENEMY status if it's also friend/ally.
- struct block_list *s_bl = src, *t_bl = target;
-
- nullpo_ret(src);
- nullpo_ret(target);
-
- m = target->m;
-
- //t_bl/s_bl hold the 'master' of the attack, while src/target are the actual
- //objects involved.
- if ((t_bl = battle_get_master(target)) == NULL)
- t_bl = target;
-
- if ((s_bl = battle_get_master(src)) == NULL)
- s_bl = src;
-
- if (s_bl->type == BL_PC) {
- switch (t_bl->type) {
- case BL_MOB: // Source => PC, Target => MOB
- if (pc_has_permission((TBL_PC *)s_bl, PC_PERM_DISABLE_PVM))
- return 0;
- break;
- case BL_PC:
- if (pc_has_permission((TBL_PC *)s_bl, PC_PERM_DISABLE_PVP))
- return 0;
- break;
- default:/* anything else goes */
- break;
- }
- }
+ int m,state = 0; //Initial state none
+ int strip_enemy = 1; //Flag which marks whether to remove the BCT_ENEMY status if it's also friend/ally.
+ struct block_list *s_bl = src, *t_bl = target;
+
+ nullpo_ret(src);
+ nullpo_ret(target);
+
+ m = target->m;
+
+ //t_bl/s_bl hold the 'master' of the attack, while src/target are the actual
+ //objects involved.
+ if( (t_bl = battle_get_master(target)) == NULL )
+ t_bl = target;
+
+ if( (s_bl = battle_get_master(src)) == NULL )
+ s_bl = src;
+
+ if ( s_bl->type == BL_PC ) {
+ switch( t_bl->type ) {
+ case BL_MOB: // Source => PC, Target => MOB
+ if ( pc_has_permission((TBL_PC*)s_bl, PC_PERM_DISABLE_PVM) )
+ return 0;
+ break;
+ case BL_PC:
+ if (pc_has_permission((TBL_PC*)s_bl, PC_PERM_DISABLE_PVP))
+ return 0;
+ break;
+ default:/* anything else goes */
+ break;
+ }
+ }
- switch (target->type) { // Checks on actual target
- case BL_PC: {
- struct status_change *sc = status_get_sc(src);
- if (((TBL_PC *)target)->invincible_timer != INVALID_TIMER || pc_isinvisible((TBL_PC *)target))
- return -1; //Cannot be targeted yet.
- if (sc && sc->count) {
- if (sc->data[SC_VOICEOFSIREN] && sc->data[SC_VOICEOFSIREN]->val2 == target->id)
- return -1;
- }
- }
- break;
- case BL_MOB:
- if (((((TBL_MOB *)target)->special_state.ai == 2 || //Marine Spheres
- (((TBL_MOB *)target)->special_state.ai == 3 && battle_config.summon_flora&1)) && //Floras
- s_bl->type == BL_PC && src->type != BL_MOB) || ((TBL_MOB *)target)->special_state.ai == 4) { //Zanzoe
- //Targettable by players
- state |= BCT_ENEMY;
- strip_enemy = 0;
- }
- break;
- case BL_SKILL: {
- TBL_SKILL *su = (TBL_SKILL *)target;
- if (!su->group)
- return 0;
- if (skill_get_inf2(su->group->skill_id)&INF2_TRAP) { //Only a few skills can target traps...
- switch (battle_getcurrentskill(src)) {
- case RK_DRAGONBREATH:// it can only hit traps in pvp/gvg maps
- if (!map[m].flag.pvp && !map[m].flag.gvg)
- break;
- case 0://you can hit them without skills
- case MA_REMOVETRAP:
- case HT_REMOVETRAP:
- case AC_SHOWER:
- case MA_SHOWER:
- case WZ_SIGHTRASHER:
- case WZ_SIGHTBLASTER:
- case SM_MAGNUM:
- case MS_MAGNUM:
- case RA_DETONATOR:
- case RA_SENSITIVEKEEN:
- case GN_CRAZYWEED_ATK:
- case RK_STORMBLAST:
- case RK_PHANTOMTHRUST:
- case SR_RAMPAGEBLASTER:
- case NC_COLDSLOWER:
- case NC_SELFDESTRUCTION:
+ switch( target->type ) { // Checks on actual target
+ case BL_PC: {
+ struct status_change* sc = status_get_sc(src);
+ if (((TBL_PC*)target)->invincible_timer != INVALID_TIMER || pc_isinvisible((TBL_PC*)target))
+ return -1; //Cannot be targeted yet.
+ if( sc && sc->count ) {
+ if( sc->data[SC_VOICEOFSIREN] && sc->data[SC_VOICEOFSIREN]->val2 == target->id )
+ return -1;
+ }
+ }
+ break;
+ case BL_MOB:
+ if(((((TBL_MOB*)target)->special_state.ai == 2 || //Marine Spheres
+ (((TBL_MOB*)target)->special_state.ai == 3 && battle_config.summon_flora&1)) && //Floras
+ s_bl->type == BL_PC && src->type != BL_MOB) || ((TBL_MOB*)target)->special_state.ai == 4) //Zanzoe
+ { //Targettable by players
+ state |= BCT_ENEMY;
+ strip_enemy = 0;
+ }
+ break;
+ case BL_SKILL:
+ {
+ TBL_SKILL *su = (TBL_SKILL*)target;
+ if( !su->group )
+ return 0;
+ if( skill_get_inf2(su->group->skill_id)&INF2_TRAP ) { //Only a few skills can target traps...
+ switch( battle_getcurrentskill(src) ) {
+ case RK_DRAGONBREATH:// it can only hit traps in pvp/gvg maps
+ if( !map[m].flag.pvp && !map[m].flag.gvg )
+ break;
+ case 0://you can hit them without skills
+ case MA_REMOVETRAP:
+ case HT_REMOVETRAP:
+ case AC_SHOWER:
+ case MA_SHOWER:
+ case WZ_SIGHTRASHER:
+ case WZ_SIGHTBLASTER:
+ case SM_MAGNUM:
+ case MS_MAGNUM:
+ case RA_DETONATOR:
+ case RA_SENSITIVEKEEN:
+ case GN_CRAZYWEED_ATK:
+ case RK_STORMBLAST:
+ case RK_PHANTOMTHRUST:
+ case SR_RAMPAGEBLASTER:
+ case NC_COLDSLOWER:
+ case NC_SELFDESTRUCTION:
#ifdef RENEWAL
- case KN_BOWLINGBASH:
- case KN_SPEARSTAB:
- case LK_SPIRALPIERCE:
- case ML_SPIRALPIERCE:
- case MO_FINGEROFFENSIVE:
- case MO_INVESTIGATE:
- case MO_TRIPLEATTACK:
- case MO_EXTREMITYFIST:
- case CR_HOLYCROSS:
- case ASC_METEORASSAULT:
- case RG_RAID:
- case MC_CARTREVOLUTION:
+ case KN_BOWLINGBASH:
+ case KN_SPEARSTAB:
+ case LK_SPIRALPIERCE:
+ case ML_SPIRALPIERCE:
+ case MO_FINGEROFFENSIVE:
+ case MO_INVESTIGATE:
+ case MO_TRIPLEATTACK:
+ case MO_EXTREMITYFIST:
+ case CR_HOLYCROSS:
+ case ASC_METEORASSAULT:
+ case RG_RAID:
+ case MC_CARTREVOLUTION:
#endif
- state |= BCT_ENEMY;
- strip_enemy = 0;
- break;
- default:
- if (su->group->skill_id == WM_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD) {
- state |= BCT_ENEMY;
- strip_enemy = 0;
- } else
- return 0;
- }
- } else if (su->group->skill_id==WZ_ICEWALL ||
- su->group->skill_id == GN_WALLOFTHORN) {
- state |= BCT_ENEMY;
- strip_enemy = 0;
- } else //Excepting traps and icewall, you should not be able to target skills.
- return 0;
- }
- break;
- //Valid targets with no special checks here.
- case BL_MER:
- case BL_HOM:
- case BL_ELEM:
- break;
- //All else not specified is an invalid target.
- default:
- return 0;
+ state |= BCT_ENEMY;
+ strip_enemy = 0;
+ break;
+ default:
+ if(su->group->skill_id == WM_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD){
+ state |= BCT_ENEMY;
+ strip_enemy = 0;
+ }else
+ return 0;
+ }
+ } else if (su->group->skill_id==WZ_ICEWALL ||
+ su->group->skill_id == GN_WALLOFTHORN) {
+ state |= BCT_ENEMY;
+ strip_enemy = 0;
+ } else //Excepting traps and icewall, you should not be able to target skills.
+ return 0;
+ }
+ break;
+ //Valid targets with no special checks here.
+ case BL_MER:
+ case BL_HOM:
+ case BL_ELEM:
+ break;
+ //All else not specified is an invalid target.
+ default:
+ return 0;
} //end switch actual target
- switch (t_bl->type) {
- //Checks on target master
- case BL_PC: {
- struct map_session_data *sd;
- if (t_bl == s_bl) break;
- sd = BL_CAST(BL_PC, t_bl);
-
- if (sd->state.monster_ignore && flag&BCT_ENEMY)
- return 0; // Global inminuty only to Attacks
- if (sd->status.karma && s_bl->type == BL_PC && ((TBL_PC *)s_bl)->status.karma)
- state |= BCT_ENEMY; // Characters with bad karma may fight amongst them
- if (sd->state.killable) {
- state |= BCT_ENEMY; // Everything can kill it
- strip_enemy = 0;
- }
- break;
- }
- case BL_MOB: {
- struct mob_data *md = BL_CAST(BL_MOB, t_bl);
+ switch( t_bl->type )
+ { //Checks on target master
+ case BL_PC:
+ {
+ struct map_session_data *sd;
+ if( t_bl == s_bl ) break;
+ sd = BL_CAST(BL_PC, t_bl);
+
+ if( sd->state.monster_ignore && flag&BCT_ENEMY )
+ return 0; // Global inminuty only to Attacks
+ if( sd->status.karma && s_bl->type == BL_PC && ((TBL_PC*)s_bl)->status.karma )
+ state |= BCT_ENEMY; // Characters with bad karma may fight amongst them
+ if( sd->state.killable ) {
+ state |= BCT_ENEMY; // Everything can kill it
+ strip_enemy = 0;
+ }
+ break;
+ }
+ case BL_MOB:
+ {
+ struct mob_data *md = BL_CAST(BL_MOB, t_bl);
- if (!((agit_flag || agit2_flag) && map[m].flag.gvg_castle) && md->guardian_data && md->guardian_data->guild_id)
- return 0; // Disable guardians/emperiums owned by Guilds on non-woe times.
- break;
- }
- default:
- break; //other type doesn't have slave yet
+ if( !((agit_flag || agit2_flag) && map[m].flag.gvg_castle) && md->guardian_data && md->guardian_data->guild_id )
+ return 0; // Disable guardians/emperiums owned by Guilds on non-woe times.
+ break;
+ }
+ default: break; //other type doesn't have slave yet
} //end switch master target
- switch (src->type) { //Checks on actual src type
- case BL_PET:
- if (t_bl->type != BL_MOB && flag&BCT_ENEMY)
- return 0; //Pet may not attack non-mobs.
- if (t_bl->type == BL_MOB && ((TBL_MOB *)t_bl)->guardian_data && flag&BCT_ENEMY)
- return 0; //pet may not attack Guardians/Emperium
- break;
- case BL_SKILL: {
- struct skill_unit *su = (struct skill_unit *)src;
- if (!su->group)
- return 0;
-
- if (su->group->src_id == target->id) {
- int inf2 = skill_get_inf2(su->group->skill_id);
- if (inf2&INF2_NO_TARGET_SELF)
- return -1;
- if (inf2&INF2_TARGET_SELF)
- return 1;
- }
- }
- break;
- case BL_MER:
- if (t_bl->type == BL_MOB && ((TBL_MOB *)t_bl)->class_ == MOBID_EMPERIUM && flag&BCT_ENEMY)
- return 0; //mercenary may not attack Emperium
- break;
+ switch( src->type ) { //Checks on actual src type
+ case BL_PET:
+ if (t_bl->type != BL_MOB && flag&BCT_ENEMY)
+ return 0; //Pet may not attack non-mobs.
+ if (t_bl->type == BL_MOB && ((TBL_MOB*)t_bl)->guardian_data && flag&BCT_ENEMY)
+ return 0; //pet may not attack Guardians/Emperium
+ break;
+ case BL_SKILL: {
+ struct skill_unit *su = (struct skill_unit *)src;
+ if (!su->group)
+ return 0;
+
+ if (su->group->src_id == target->id) {
+ int inf2 = skill_get_inf2(su->group->skill_id);
+ if (inf2&INF2_NO_TARGET_SELF)
+ return -1;
+ if (inf2&INF2_TARGET_SELF)
+ return 1;
+ }
+ }
+ break;
+ case BL_MER:
+ if (t_bl->type == BL_MOB && ((TBL_MOB*)t_bl)->class_ == MOBID_EMPERIUM && flag&BCT_ENEMY)
+ return 0; //mercenary may not attack Emperium
+ break;
} //end switch actual src
- switch (s_bl->type) {
- //Checks on source master
- case BL_PC: {
- struct map_session_data *sd = BL_CAST(BL_PC, s_bl);
- if (s_bl != t_bl) {
- if (sd->state.killer) {
- state |= BCT_ENEMY; // Can kill anything
- strip_enemy = 0;
- } else if (sd->duel_group && !((!battle_config.duel_allow_pvp && map[m].flag.pvp) || (!battle_config.duel_allow_gvg && map_flag_gvg(m)))) {
- if (t_bl->type == BL_PC && (sd->duel_group == ((TBL_PC *)t_bl)->duel_group))
- return (BCT_ENEMY&flag)?1:-1; // Duel targets can ONLY be your enemy, nothing else.
- else
- return 0; // You can't target anything out of your duel
- }
- }
- if (map_flag_gvg(m) && !sd->status.guild_id && t_bl->type == BL_MOB && ((TBL_MOB *)t_bl)->class_ == MOBID_EMPERIUM)
- return 0; //If you don't belong to a guild, can't target emperium.
- if (t_bl->type != BL_PC)
- state |= BCT_ENEMY; //Natural enemy.
- break;
- }
- case BL_MOB: {
- struct mob_data *md = BL_CAST(BL_MOB, s_bl);
- if (!((agit_flag || agit2_flag) && map[m].flag.gvg_castle) && md->guardian_data && md->guardian_data->guild_id)
- return 0; // Disable guardians/emperium owned by Guilds on non-woe times.
-
- if (!md->special_state.ai) {
- //Normal mobs
- if (
- (target->type == BL_MOB && t_bl->type == BL_PC && (((TBL_MOB *)target)->special_state.ai != 4 && ((TBL_MOB *)target)->special_state.ai != 1)) ||
- (t_bl->type == BL_MOB && !((TBL_MOB *)t_bl)->special_state.ai)
- )
- state |= BCT_PARTY; //Normal mobs with no ai are friends.
- else
- state |= BCT_ENEMY; //However, all else are enemies.
- } else {
- if (t_bl->type == BL_MOB && !((TBL_MOB *)t_bl)->special_state.ai)
- state |= BCT_ENEMY; //Natural enemy for AI mobs are normal mobs.
- }
- break;
- }
- default:
- //Need some sort of default behaviour for unhandled types.
- if (t_bl->type != s_bl->type)
- state |= BCT_ENEMY;
- break;
+ switch( s_bl->type )
+ { //Checks on source master
+ case BL_PC:
+ {
+ struct map_session_data *sd = BL_CAST(BL_PC, s_bl);
+ if( s_bl != t_bl )
+ {
+ if( sd->state.killer )
+ {
+ state |= BCT_ENEMY; // Can kill anything
+ strip_enemy = 0;
+ }
+ else if( sd->duel_group && !((!battle_config.duel_allow_pvp && map[m].flag.pvp) || (!battle_config.duel_allow_gvg && map_flag_gvg(m))) )
+ {
+ if( t_bl->type == BL_PC && (sd->duel_group == ((TBL_PC*)t_bl)->duel_group) )
+ return (BCT_ENEMY&flag)?1:-1; // Duel targets can ONLY be your enemy, nothing else.
+ else
+ return 0; // You can't target anything out of your duel
+ }
+ }
+ if( map_flag_gvg(m) && !sd->status.guild_id && t_bl->type == BL_MOB && ((TBL_MOB*)t_bl)->class_ == MOBID_EMPERIUM )
+ return 0; //If you don't belong to a guild, can't target emperium.
+ if( t_bl->type != BL_PC )
+ state |= BCT_ENEMY; //Natural enemy.
+ break;
+ }
+ case BL_MOB:
+ {
+ struct mob_data *md = BL_CAST(BL_MOB, s_bl);
+ if( !((agit_flag || agit2_flag) && map[m].flag.gvg_castle) && md->guardian_data && md->guardian_data->guild_id )
+ return 0; // Disable guardians/emperium owned by Guilds on non-woe times.
+
+ if( !md->special_state.ai )
+ { //Normal mobs
+ if(
+ ( target->type == BL_MOB && t_bl->type == BL_PC && ( ((TBL_MOB*)target)->special_state.ai != 4 && ((TBL_MOB*)target)->special_state.ai != 1 ) ) ||
+ ( t_bl->type == BL_MOB && !((TBL_MOB*)t_bl)->special_state.ai )
+ )
+ state |= BCT_PARTY; //Normal mobs with no ai are friends.
+ else
+ state |= BCT_ENEMY; //However, all else are enemies.
+ }
+ else
+ {
+ if( t_bl->type == BL_MOB && !((TBL_MOB*)t_bl)->special_state.ai )
+ state |= BCT_ENEMY; //Natural enemy for AI mobs are normal mobs.
+ }
+ break;
+ }
+ default:
+ //Need some sort of default behaviour for unhandled types.
+ if (t_bl->type != s_bl->type)
+ state |= BCT_ENEMY;
+ break;
} //end switch on src master
- if ((flag&BCT_ALL) == BCT_ALL) {
- //All actually stands for all attackable chars
- if (target->type&BL_CHAR)
- return 1;
- else
- return -1;
- }
- if (flag == BCT_NOONE) //Why would someone use this? no clue.
- return -1;
-
- if (t_bl == s_bl) {
- //No need for further testing.
- state |= BCT_SELF|BCT_PARTY|BCT_GUILD;
- if (state&BCT_ENEMY && strip_enemy)
- state&=~BCT_ENEMY;
- return (flag&state)?1:-1;
- }
+ if( (flag&BCT_ALL) == BCT_ALL )
+ { //All actually stands for all attackable chars
+ if( target->type&BL_CHAR )
+ return 1;
+ else
+ return -1;
+ }
+ if( flag == BCT_NOONE ) //Why would someone use this? no clue.
+ return -1;
+
+ if( t_bl == s_bl )
+ { //No need for further testing.
+ state |= BCT_SELF|BCT_PARTY|BCT_GUILD;
+ if( state&BCT_ENEMY && strip_enemy )
+ state&=~BCT_ENEMY;
+ return (flag&state)?1:-1;
+ }
- if (map_flag_vs(m)) {
- //Check rivalry settings.
- int sbg_id = 0, tbg_id = 0;
- if (map[m].flag.battleground) {
- sbg_id = bg_team_get_id(s_bl);
- tbg_id = bg_team_get_id(t_bl);
- }
- if (flag&(BCT_PARTY|BCT_ENEMY)) {
- int s_party = status_get_party_id(s_bl);
- if (s_party && s_party == status_get_party_id(t_bl) && !(map[m].flag.pvp && map[m].flag.pvp_noparty) && !(map_flag_gvg(m) && map[m].flag.gvg_noparty) && (!map[m].flag.battleground || sbg_id == tbg_id))
- state |= BCT_PARTY;
- else
- state |= BCT_ENEMY;
- }
- if (flag&(BCT_GUILD|BCT_ENEMY)) {
- int s_guild = status_get_guild_id(s_bl);
- int t_guild = status_get_guild_id(t_bl);
- if (!(map[m].flag.pvp && map[m].flag.pvp_noguild) && s_guild && t_guild && (s_guild == t_guild || guild_isallied(s_guild, t_guild)) && (!map[m].flag.battleground || sbg_id == tbg_id))
- state |= BCT_GUILD;
- else
- state |= BCT_ENEMY;
- }
- if (state&BCT_ENEMY && map[m].flag.battleground && sbg_id && sbg_id == tbg_id)
- state &= ~BCT_ENEMY;
-
- if (state&BCT_ENEMY && battle_config.pk_mode && !map_flag_gvg(m) && s_bl->type == BL_PC && t_bl->type == BL_PC) {
- // Prevent novice engagement on pk_mode (feature by Valaris)
- TBL_PC *sd = (TBL_PC *)s_bl, *sd2 = (TBL_PC *)t_bl;
- if (
- (sd->class_&MAPID_UPPERMASK) == MAPID_NOVICE ||
- (sd2->class_&MAPID_UPPERMASK) == MAPID_NOVICE ||
- (int)sd->status.base_level < battle_config.pk_min_level ||
- (int)sd2->status.base_level < battle_config.pk_min_level ||
- (battle_config.pk_level_range && abs((int)sd->status.base_level - (int)sd2->status.base_level) > battle_config.pk_level_range)
- )
- state &= ~BCT_ENEMY;
- }
+ if( map_flag_vs(m) )
+ { //Check rivalry settings.
+ int sbg_id = 0, tbg_id = 0;
+ if( map[m].flag.battleground )
+ {
+ sbg_id = bg_team_get_id(s_bl);
+ tbg_id = bg_team_get_id(t_bl);
+ }
+ if( flag&(BCT_PARTY|BCT_ENEMY) )
+ {
+ int s_party = status_get_party_id(s_bl);
+ if( s_party && s_party == status_get_party_id(t_bl) && !(map[m].flag.pvp && map[m].flag.pvp_noparty) && !(map_flag_gvg(m) && map[m].flag.gvg_noparty) && (!map[m].flag.battleground || sbg_id == tbg_id) )
+ state |= BCT_PARTY;
+ else
+ state |= BCT_ENEMY;
+ }
+ if( flag&(BCT_GUILD|BCT_ENEMY) )
+ {
+ int s_guild = status_get_guild_id(s_bl);
+ int t_guild = status_get_guild_id(t_bl);
+ if( !(map[m].flag.pvp && map[m].flag.pvp_noguild) && s_guild && t_guild && (s_guild == t_guild || guild_isallied(s_guild, t_guild)) && (!map[m].flag.battleground || sbg_id == tbg_id) )
+ state |= BCT_GUILD;
+ else
+ state |= BCT_ENEMY;
+ }
+ if( state&BCT_ENEMY && map[m].flag.battleground && sbg_id && sbg_id == tbg_id )
+ state &= ~BCT_ENEMY;
+
+ if( state&BCT_ENEMY && battle_config.pk_mode && !map_flag_gvg(m) && s_bl->type == BL_PC && t_bl->type == BL_PC )
+ { // Prevent novice engagement on pk_mode (feature by Valaris)
+ TBL_PC *sd = (TBL_PC*)s_bl, *sd2 = (TBL_PC*)t_bl;
+ if (
+ (sd->class_&MAPID_UPPERMASK) == MAPID_NOVICE ||
+ (sd2->class_&MAPID_UPPERMASK) == MAPID_NOVICE ||
+ (int)sd->status.base_level < battle_config.pk_min_level ||
+ (int)sd2->status.base_level < battle_config.pk_min_level ||
+ (battle_config.pk_level_range && abs((int)sd->status.base_level - (int)sd2->status.base_level) > battle_config.pk_level_range)
+ )
+ state &= ~BCT_ENEMY;
+ }
}//end map_flag_vs chk rivality
- else {
- //Non pvp/gvg, check party/guild settings.
- if (flag&BCT_PARTY || state&BCT_ENEMY) {
- int s_party = status_get_party_id(s_bl);
- if (s_party && s_party == status_get_party_id(t_bl))
- state |= BCT_PARTY;
- }
- if (flag&BCT_GUILD || state&BCT_ENEMY) {
- int s_guild = status_get_guild_id(s_bl);
- int t_guild = status_get_guild_id(t_bl);
- if (s_guild && t_guild && (s_guild == t_guild || guild_isallied(s_guild, t_guild)))
- state |= BCT_GUILD;
- }
+ else
+ { //Non pvp/gvg, check party/guild settings.
+ if( flag&BCT_PARTY || state&BCT_ENEMY )
+ {
+ int s_party = status_get_party_id(s_bl);
+ if(s_party && s_party == status_get_party_id(t_bl))
+ state |= BCT_PARTY;
+ }
+ if( flag&BCT_GUILD || state&BCT_ENEMY )
+ {
+ int s_guild = status_get_guild_id(s_bl);
+ int t_guild = status_get_guild_id(t_bl);
+ if(s_guild && t_guild && (s_guild == t_guild || guild_isallied(s_guild, t_guild)))
+ state |= BCT_GUILD;
+ }
} //end non pvp/gvg chk rivality
- if (!state) //If not an enemy, nor a guild, nor party, nor yourself, it's neutral.
- state = BCT_NEUTRAL;
- //Alliance state takes precedence over enemy one.
- else if (state&BCT_ENEMY && strip_enemy && state&(BCT_SELF|BCT_PARTY|BCT_GUILD))
- state&=~BCT_ENEMY;
+ if( !state ) //If not an enemy, nor a guild, nor party, nor yourself, it's neutral.
+ state = BCT_NEUTRAL;
+ //Alliance state takes precedence over enemy one.
+ else if( state&BCT_ENEMY && strip_enemy && state&(BCT_SELF|BCT_PARTY|BCT_GUILD) )
+ state&=~BCT_ENEMY;
- return (flag&state)?1:-1;
+ return (flag&state)?1:-1;
}
/*==========================================
* Check if can attack from this range
@@ -5354,687 +5396,689 @@ int battle_check_target(struct block_list *src, struct block_list *target,int fl
*------------------------------------------*/
bool battle_check_range(struct block_list *src, struct block_list *bl, int range)
{
- int d;
- nullpo_retr(false, src);
- nullpo_retr(false, bl);
+ int d;
+ nullpo_retr(false, src);
+ nullpo_retr(false, bl);
- if (src->m != bl->m)
- return false;
+ if( src->m != bl->m )
+ return false;
#ifndef CIRCULAR_AREA
- if (src->type == BL_PC) { // Range for players' attacks and skills should always have a circular check. [Angezerus]
- int dx = src->x - bl->x, dy = src->y - bl->y;
- if (!check_distance(dx, dy, range))
- return false;
- } else
+ if( src->type == BL_PC ) { // Range for players' attacks and skills should always have a circular check. [Angezerus]
+ int dx = src->x - bl->x, dy = src->y - bl->y;
+ if( !check_distance(dx, dy, range) )
+ return false;
+ } else
#endif
- if (!check_distance_bl(src, bl, range))
- return false;
+ if( !check_distance_bl(src, bl, range) )
+ return false;
- if ((d = distance_bl(src, bl)) < 2)
- return true; // No need for path checking.
+ if( (d = distance_bl(src, bl)) < 2 )
+ return true; // No need for path checking.
- if (d > AREA_SIZE)
- return false; // Avoid targetting objects beyond your range of sight.
+ if( d > AREA_SIZE )
+ return false; // Avoid targetting objects beyond your range of sight.
- return path_search_long(NULL,src->m,src->x,src->y,bl->x,bl->y,CELL_CHKWALL);
+ return path_search_long(NULL,src->m,src->x,src->y,bl->x,bl->y,CELL_CHKWALL);
}
static const struct _battle_data {
- const char *str;
- int *val;
- int defval;
- int min;
- int max;
+ const char* str;
+ int* val;
+ int defval;
+ int min;
+ int max;
} battle_data[] = {
- { "warp_point_debug", &battle_config.warp_point_debug, 0, 0, 1, },
- { "enable_critical", &battle_config.enable_critical, BL_PC, BL_NUL, BL_ALL, },
- { "mob_critical_rate", &battle_config.mob_critical_rate, 100, 0, INT_MAX, },
- { "critical_rate", &battle_config.critical_rate, 100, 0, INT_MAX, },
- { "enable_baseatk", &battle_config.enable_baseatk, BL_PC|BL_HOM, BL_NUL, BL_ALL, },
- { "enable_perfect_flee", &battle_config.enable_perfect_flee, BL_PC|BL_PET, BL_NUL, BL_ALL, },
- { "casting_rate", &battle_config.cast_rate, 100, 0, INT_MAX, },
- { "delay_rate", &battle_config.delay_rate, 100, 0, INT_MAX, },
- { "delay_dependon_dex", &battle_config.delay_dependon_dex, 0, 0, 1, },
- { "delay_dependon_agi", &battle_config.delay_dependon_agi, 0, 0, 1, },
- { "skill_delay_attack_enable", &battle_config.sdelay_attack_enable, 0, 0, 1, },
- { "left_cardfix_to_right", &battle_config.left_cardfix_to_right, 0, 0, 1, },
- { "skill_add_range", &battle_config.skill_add_range, 0, 0, INT_MAX, },
- { "skill_out_range_consume", &battle_config.skill_out_range_consume, 1, 0, 1, },
- { "skillrange_by_distance", &battle_config.skillrange_by_distance, ~BL_PC, BL_NUL, BL_ALL, },
- { "skillrange_from_weapon", &battle_config.use_weapon_skill_range, ~BL_PC, BL_NUL, BL_ALL, },
- { "player_damage_delay_rate", &battle_config.pc_damage_delay_rate, 100, 0, INT_MAX, },
- { "defunit_not_enemy", &battle_config.defnotenemy, 0, 0, 1, },
- { "gvg_traps_target_all", &battle_config.vs_traps_bctall, BL_PC, BL_NUL, BL_ALL, },
- { "traps_setting", &battle_config.traps_setting, 0, 0, 1, },
- { "summon_flora_setting", &battle_config.summon_flora, 1|2, 0, 1|2, },
- { "clear_skills_on_death", &battle_config.clear_unit_ondeath, BL_NUL, BL_NUL, BL_ALL, },
- { "clear_skills_on_warp", &battle_config.clear_unit_onwarp, BL_ALL, BL_NUL, BL_ALL, },
- { "random_monster_checklv", &battle_config.random_monster_checklv, 0, 0, 1, },
- { "attribute_recover", &battle_config.attr_recover, 1, 0, 1, },
- { "flooritem_lifetime", &battle_config.flooritem_lifetime, 60000, 1000, INT_MAX, },
- { "item_auto_get", &battle_config.item_auto_get, 0, 0, 1, },
- { "item_first_get_time", &battle_config.item_first_get_time, 3000, 0, INT_MAX, },
- { "item_second_get_time", &battle_config.item_second_get_time, 1000, 0, INT_MAX, },
- { "item_third_get_time", &battle_config.item_third_get_time, 1000, 0, INT_MAX, },
- { "mvp_item_first_get_time", &battle_config.mvp_item_first_get_time, 10000, 0, INT_MAX, },
- { "mvp_item_second_get_time", &battle_config.mvp_item_second_get_time, 10000, 0, INT_MAX, },
- { "mvp_item_third_get_time", &battle_config.mvp_item_third_get_time, 2000, 0, INT_MAX, },
- { "drop_rate0item", &battle_config.drop_rate0item, 0, 0, 1, },
- { "base_exp_rate", &battle_config.base_exp_rate, 100, 0, INT_MAX, },
- { "job_exp_rate", &battle_config.job_exp_rate, 100, 0, INT_MAX, },
- { "pvp_exp", &battle_config.pvp_exp, 1, 0, 1, },
- { "death_penalty_type", &battle_config.death_penalty_type, 0, 0, 2, },
- { "death_penalty_base", &battle_config.death_penalty_base, 0, 0, INT_MAX, },
- { "death_penalty_job", &battle_config.death_penalty_job, 0, 0, INT_MAX, },
- { "zeny_penalty", &battle_config.zeny_penalty, 0, 0, INT_MAX, },
- { "hp_rate", &battle_config.hp_rate, 100, 1, INT_MAX, },
- { "sp_rate", &battle_config.sp_rate, 100, 1, INT_MAX, },
- { "restart_hp_rate", &battle_config.restart_hp_rate, 0, 0, 100, },
- { "restart_sp_rate", &battle_config.restart_sp_rate, 0, 0, 100, },
- { "guild_aura", &battle_config.guild_aura, 31, 0, 31, },
- { "mvp_hp_rate", &battle_config.mvp_hp_rate, 100, 1, INT_MAX, },
- { "mvp_exp_rate", &battle_config.mvp_exp_rate, 100, 0, INT_MAX, },
- { "monster_hp_rate", &battle_config.monster_hp_rate, 100, 1, INT_MAX, },
- { "monster_max_aspd", &battle_config.monster_max_aspd, 199, 100, 199, },
- { "view_range_rate", &battle_config.view_range_rate, 100, 0, INT_MAX, },
- { "chase_range_rate", &battle_config.chase_range_rate, 100, 0, INT_MAX, },
- { "gtb_sc_immunity", &battle_config.gtb_sc_immunity, 50, 0, INT_MAX, },
- { "guild_max_castles", &battle_config.guild_max_castles, 0, 0, INT_MAX, },
- { "guild_skill_relog_delay", &battle_config.guild_skill_relog_delay, 0, 0, 1, },
- { "emergency_call", &battle_config.emergency_call, 11, 0, 31, },
- { "atcommand_spawn_quantity_limit", &battle_config.atc_spawn_quantity_limit, 100, 0, INT_MAX, },
- { "atcommand_slave_clone_limit", &battle_config.atc_slave_clone_limit, 25, 0, INT_MAX, },
- { "partial_name_scan", &battle_config.partial_name_scan, 0, 0, 1, },
- { "player_skillfree", &battle_config.skillfree, 0, 0, 1, },
- { "player_skillup_limit", &battle_config.skillup_limit, 1, 0, 1, },
- { "weapon_produce_rate", &battle_config.wp_rate, 100, 0, INT_MAX, },
- { "potion_produce_rate", &battle_config.pp_rate, 100, 0, INT_MAX, },
- { "monster_active_enable", &battle_config.monster_active_enable, 1, 0, 1, },
- { "monster_damage_delay_rate", &battle_config.monster_damage_delay_rate, 100, 0, INT_MAX, },
- { "monster_loot_type", &battle_config.monster_loot_type, 0, 0, 1, },
- // { "mob_skill_use", &battle_config.mob_skill_use, 1, 0, 1, }, //Deprecated
- { "mob_skill_rate", &battle_config.mob_skill_rate, 100, 0, INT_MAX, },
- { "mob_skill_delay", &battle_config.mob_skill_delay, 100, 0, INT_MAX, },
- { "mob_count_rate", &battle_config.mob_count_rate, 100, 0, INT_MAX, },
- { "mob_spawn_delay", &battle_config.mob_spawn_delay, 100, 0, INT_MAX, },
- { "plant_spawn_delay", &battle_config.plant_spawn_delay, 100, 0, INT_MAX, },
- { "boss_spawn_delay", &battle_config.boss_spawn_delay, 100, 0, INT_MAX, },
- { "no_spawn_on_player", &battle_config.no_spawn_on_player, 0, 0, 100, },
- { "force_random_spawn", &battle_config.force_random_spawn, 0, 0, 1, },
- { "slaves_inherit_mode", &battle_config.slaves_inherit_mode, 2, 0, 3, },
- { "slaves_inherit_speed", &battle_config.slaves_inherit_speed, 3, 0, 3, },
- { "summons_trigger_autospells", &battle_config.summons_trigger_autospells, 1, 0, 1, },
- { "pc_damage_walk_delay_rate", &battle_config.pc_walk_delay_rate, 20, 0, INT_MAX, },
- { "damage_walk_delay_rate", &battle_config.walk_delay_rate, 100, 0, INT_MAX, },
- { "multihit_delay", &battle_config.multihit_delay, 80, 0, INT_MAX, },
- { "quest_skill_learn", &battle_config.quest_skill_learn, 0, 0, 1, },
- { "quest_skill_reset", &battle_config.quest_skill_reset, 0, 0, 1, },
- { "basic_skill_check", &battle_config.basic_skill_check, 1, 0, 1, },
- { "guild_emperium_check", &battle_config.guild_emperium_check, 1, 0, 1, },
- { "guild_exp_limit", &battle_config.guild_exp_limit, 50, 0, 99, },
- { "player_invincible_time", &battle_config.pc_invincible_time, 5000, 0, INT_MAX, },
- { "pet_catch_rate", &battle_config.pet_catch_rate, 100, 0, INT_MAX, },
- { "pet_rename", &battle_config.pet_rename, 0, 0, 1, },
- { "pet_friendly_rate", &battle_config.pet_friendly_rate, 100, 0, INT_MAX, },
- { "pet_hungry_delay_rate", &battle_config.pet_hungry_delay_rate, 100, 10, INT_MAX, },
- { "pet_hungry_friendly_decrease", &battle_config.pet_hungry_friendly_decrease, 5, 0, INT_MAX, },
- { "pet_status_support", &battle_config.pet_status_support, 0, 0, 1, },
- { "pet_attack_support", &battle_config.pet_attack_support, 0, 0, 1, },
- { "pet_damage_support", &battle_config.pet_damage_support, 0, 0, 1, },
- { "pet_support_min_friendly", &battle_config.pet_support_min_friendly, 900, 0, 950, },
- { "pet_equip_min_friendly", &battle_config.pet_equip_min_friendly, 900, 0, 950, },
- { "pet_support_rate", &battle_config.pet_support_rate, 100, 0, INT_MAX, },
- { "pet_attack_exp_to_master", &battle_config.pet_attack_exp_to_master, 0, 0, 1, },
- { "pet_attack_exp_rate", &battle_config.pet_attack_exp_rate, 100, 0, INT_MAX, },
- { "pet_lv_rate", &battle_config.pet_lv_rate, 0, 0, INT_MAX, },
- { "pet_max_stats", &battle_config.pet_max_stats, 99, 0, INT_MAX, },
- { "pet_max_atk1", &battle_config.pet_max_atk1, 750, 0, INT_MAX, },
- { "pet_max_atk2", &battle_config.pet_max_atk2, 1000, 0, INT_MAX, },
- { "pet_disable_in_gvg", &battle_config.pet_no_gvg, 0, 0, 1, },
- { "skill_min_damage", &battle_config.skill_min_damage, 2|4, 0, 1|2|4, },
- { "finger_offensive_type", &battle_config.finger_offensive_type, 0, 0, 1, },
- { "heal_exp", &battle_config.heal_exp, 0, 0, INT_MAX, },
- { "resurrection_exp", &battle_config.resurrection_exp, 0, 0, INT_MAX, },
- { "shop_exp", &battle_config.shop_exp, 0, 0, INT_MAX, },
- { "max_heal_lv", &battle_config.max_heal_lv, 11, 1, INT_MAX, },
- { "max_heal", &battle_config.max_heal, 9999, 0, INT_MAX, },
- { "combo_delay_rate", &battle_config.combo_delay_rate, 100, 0, INT_MAX, },
- { "item_check", &battle_config.item_check, 0, 0, 1, },
- { "item_use_interval", &battle_config.item_use_interval, 100, 0, INT_MAX, },
- { "cashfood_use_interval", &battle_config.cashfood_use_interval, 60000, 0, INT_MAX, },
- { "wedding_modifydisplay", &battle_config.wedding_modifydisplay, 0, 0, 1, },
- { "wedding_ignorepalette", &battle_config.wedding_ignorepalette, 0, 0, 1, },
- { "xmas_ignorepalette", &battle_config.xmas_ignorepalette, 0, 0, 1, },
- { "summer_ignorepalette", &battle_config.summer_ignorepalette, 0, 0, 1, },
- { "natural_healhp_interval", &battle_config.natural_healhp_interval, 6000, NATURAL_HEAL_INTERVAL, INT_MAX, },
- { "natural_healsp_interval", &battle_config.natural_healsp_interval, 8000, NATURAL_HEAL_INTERVAL, INT_MAX, },
- { "natural_heal_skill_interval", &battle_config.natural_heal_skill_interval, 10000, NATURAL_HEAL_INTERVAL, INT_MAX, },
- { "natural_heal_weight_rate", &battle_config.natural_heal_weight_rate, 50, 50, 101 },
- { "arrow_decrement", &battle_config.arrow_decrement, 1, 0, 2, },
- { "max_aspd", &battle_config.max_aspd, 190, 100, 199, },
- { "max_third_aspd", &battle_config.max_third_aspd, 193, 100, 199, },
- { "max_walk_speed", &battle_config.max_walk_speed, 300, 100, 100*DEFAULT_WALK_SPEED, },
- { "max_lv", &battle_config.max_lv, 99, 0, MAX_LEVEL, },
- { "aura_lv", &battle_config.aura_lv, 99, 0, INT_MAX, },
- { "max_hp", &battle_config.max_hp, 32500, 100, 1000000000, },
- { "max_sp", &battle_config.max_sp, 32500, 100, 1000000000, },
- { "max_cart_weight", &battle_config.max_cart_weight, 8000, 100, 1000000, },
- { "max_parameter", &battle_config.max_parameter, 99, 10, 10000, },
- { "max_baby_parameter", &battle_config.max_baby_parameter, 80, 10, 10000, },
- { "max_def", &battle_config.max_def, 99, 0, INT_MAX, },
- { "over_def_bonus", &battle_config.over_def_bonus, 0, 0, 1000, },
- { "skill_log", &battle_config.skill_log, BL_NUL, BL_NUL, BL_ALL, },
- { "battle_log", &battle_config.battle_log, 0, 0, 1, },
- { "etc_log", &battle_config.etc_log, 1, 0, 1, },
- { "save_clothcolor", &battle_config.save_clothcolor, 1, 0, 1, },
- { "undead_detect_type", &battle_config.undead_detect_type, 0, 0, 2, },
- { "auto_counter_type", &battle_config.auto_counter_type, BL_ALL, BL_NUL, BL_ALL, },
- { "min_hitrate", &battle_config.min_hitrate, 5, 0, 100, },
- { "max_hitrate", &battle_config.max_hitrate, 100, 0, 100, },
- { "agi_penalty_target", &battle_config.agi_penalty_target, BL_PC, BL_NUL, BL_ALL, },
- { "agi_penalty_type", &battle_config.agi_penalty_type, 1, 0, 2, },
- { "agi_penalty_count", &battle_config.agi_penalty_count, 3, 2, INT_MAX, },
- { "agi_penalty_num", &battle_config.agi_penalty_num, 10, 0, INT_MAX, },
- { "vit_penalty_target", &battle_config.vit_penalty_target, BL_PC, BL_NUL, BL_ALL, },
- { "vit_penalty_type", &battle_config.vit_penalty_type, 1, 0, 2, },
- { "vit_penalty_count", &battle_config.vit_penalty_count, 3, 2, INT_MAX, },
- { "vit_penalty_num", &battle_config.vit_penalty_num, 5, 0, INT_MAX, },
- { "weapon_defense_type", &battle_config.weapon_defense_type, 0, 0, INT_MAX, },
- { "magic_defense_type", &battle_config.magic_defense_type, 0, 0, INT_MAX, },
- { "skill_reiteration", &battle_config.skill_reiteration, BL_NUL, BL_NUL, BL_ALL, },
- { "skill_nofootset", &battle_config.skill_nofootset, BL_PC, BL_NUL, BL_ALL, },
- { "player_cloak_check_type", &battle_config.pc_cloak_check_type, 1, 0, 1|2|4, },
- { "monster_cloak_check_type", &battle_config.monster_cloak_check_type, 4, 0, 1|2|4, },
- { "sense_type", &battle_config.estimation_type, 1|2, 0, 1|2, },
- { "gvg_short_attack_damage_rate", &battle_config.gvg_short_damage_rate, 80, 0, INT_MAX, },
- { "gvg_long_attack_damage_rate", &battle_config.gvg_long_damage_rate, 80, 0, INT_MAX, },
- { "gvg_weapon_attack_damage_rate", &battle_config.gvg_weapon_damage_rate, 60, 0, INT_MAX, },
- { "gvg_magic_attack_damage_rate", &battle_config.gvg_magic_damage_rate, 60, 0, INT_MAX, },
- { "gvg_misc_attack_damage_rate", &battle_config.gvg_misc_damage_rate, 60, 0, INT_MAX, },
- { "gvg_flee_penalty", &battle_config.gvg_flee_penalty, 20, 0, INT_MAX, },
- { "pk_short_attack_damage_rate", &battle_config.pk_short_damage_rate, 80, 0, INT_MAX, },
- { "pk_long_attack_damage_rate", &battle_config.pk_long_damage_rate, 70, 0, INT_MAX, },
- { "pk_weapon_attack_damage_rate", &battle_config.pk_weapon_damage_rate, 60, 0, INT_MAX, },
- { "pk_magic_attack_damage_rate", &battle_config.pk_magic_damage_rate, 60, 0, INT_MAX, },
- { "pk_misc_attack_damage_rate", &battle_config.pk_misc_damage_rate, 60, 0, INT_MAX, },
- { "mob_changetarget_byskill", &battle_config.mob_changetarget_byskill, 0, 0, 1, },
- { "attack_direction_change", &battle_config.attack_direction_change, BL_ALL, BL_NUL, BL_ALL, },
- { "land_skill_limit", &battle_config.land_skill_limit, BL_ALL, BL_NUL, BL_ALL, },
- { "monster_class_change_full_recover", &battle_config.monster_class_change_recover, 1, 0, 1, },
- { "produce_item_name_input", &battle_config.produce_item_name_input, 0x1|0x2, 0, 0x9F, },
- { "display_skill_fail", &battle_config.display_skill_fail, 2, 0, 1|2|4|8, },
- { "chat_warpportal", &battle_config.chat_warpportal, 0, 0, 1, },
- { "mob_warp", &battle_config.mob_warp, 0, 0, 1|2|4, },
- { "dead_branch_active", &battle_config.dead_branch_active, 1, 0, 1, },
- { "vending_max_value", &battle_config.vending_max_value, 10000000, 1, MAX_ZENY, },
- { "vending_over_max", &battle_config.vending_over_max, 1, 0, 1, },
- { "show_steal_in_same_party", &battle_config.show_steal_in_same_party, 0, 0, 1, },
- { "party_hp_mode", &battle_config.party_hp_mode, 0, 0, 1, },
- { "show_party_share_picker", &battle_config.party_show_share_picker, 1, 0, 1, },
- { "show_picker.item_type", &battle_config.show_picker_item_type, 112, 0, INT_MAX, },
- { "party_update_interval", &battle_config.party_update_interval, 1000, 100, INT_MAX, },
- { "party_item_share_type", &battle_config.party_share_type, 0, 0, 1|2|3, },
- { "attack_attr_none", &battle_config.attack_attr_none, ~BL_PC, BL_NUL, BL_ALL, },
- { "gx_allhit", &battle_config.gx_allhit, 0, 0, 1, },
- { "gx_disptype", &battle_config.gx_disptype, 1, 0, 1, },
- { "devotion_level_difference", &battle_config.devotion_level_difference, 10, 0, INT_MAX, },
- { "player_skill_partner_check", &battle_config.player_skill_partner_check, 1, 0, 1, },
- { "invite_request_check", &battle_config.invite_request_check, 1, 0, 1, },
- { "skill_removetrap_type", &battle_config.skill_removetrap_type, 0, 0, 1, },
- { "disp_experience", &battle_config.disp_experience, 0, 0, 1, },
- { "disp_zeny", &battle_config.disp_zeny, 0, 0, 1, },
- { "castle_defense_rate", &battle_config.castle_defense_rate, 100, 0, 100, },
- { "bone_drop", &battle_config.bone_drop, 0, 0, 2, },
- { "buyer_name", &battle_config.buyer_name, 1, 0, 1, },
- { "skill_wall_check", &battle_config.skill_wall_check, 1, 0, 1, },
- { "cell_stack_limit", &battle_config.cell_stack_limit, 1, 1, 255, },
- { "dancing_weaponswitch_fix", &battle_config.dancing_weaponswitch_fix, 1, 0, 1, },
-
- // eAthena additions
- { "item_logarithmic_drops", &battle_config.logarithmic_drops, 0, 0, 1, },
- { "item_drop_common_min", &battle_config.item_drop_common_min, 1, 1, 10000, },
- { "item_drop_common_max", &battle_config.item_drop_common_max, 10000, 1, 10000, },
- { "item_drop_equip_min", &battle_config.item_drop_equip_min, 1, 1, 10000, },
- { "item_drop_equip_max", &battle_config.item_drop_equip_max, 10000, 1, 10000, },
- { "item_drop_card_min", &battle_config.item_drop_card_min, 1, 1, 10000, },
- { "item_drop_card_max", &battle_config.item_drop_card_max, 10000, 1, 10000, },
- { "item_drop_mvp_min", &battle_config.item_drop_mvp_min, 1, 1, 10000, },
- { "item_drop_mvp_max", &battle_config.item_drop_mvp_max, 10000, 1, 10000, },
- { "item_drop_heal_min", &battle_config.item_drop_heal_min, 1, 1, 10000, },
- { "item_drop_heal_max", &battle_config.item_drop_heal_max, 10000, 1, 10000, },
- { "item_drop_use_min", &battle_config.item_drop_use_min, 1, 1, 10000, },
- { "item_drop_use_max", &battle_config.item_drop_use_max, 10000, 1, 10000, },
- { "item_drop_add_min", &battle_config.item_drop_adddrop_min, 1, 1, 10000, },
- { "item_drop_add_max", &battle_config.item_drop_adddrop_max, 10000, 1, 10000, },
- { "item_drop_treasure_min", &battle_config.item_drop_treasure_min, 1, 1, 10000, },
- { "item_drop_treasure_max", &battle_config.item_drop_treasure_max, 10000, 1, 10000, },
- { "item_rate_mvp", &battle_config.item_rate_mvp, 100, 0, 1000000, },
- { "item_rate_common", &battle_config.item_rate_common, 100, 0, 1000000, },
- { "item_rate_common_boss", &battle_config.item_rate_common_boss, 100, 0, 1000000, },
- { "item_rate_equip", &battle_config.item_rate_equip, 100, 0, 1000000, },
- { "item_rate_equip_boss", &battle_config.item_rate_equip_boss, 100, 0, 1000000, },
- { "item_rate_card", &battle_config.item_rate_card, 100, 0, 1000000, },
- { "item_rate_card_boss", &battle_config.item_rate_card_boss, 100, 0, 1000000, },
- { "item_rate_heal", &battle_config.item_rate_heal, 100, 0, 1000000, },
- { "item_rate_heal_boss", &battle_config.item_rate_heal_boss, 100, 0, 1000000, },
- { "item_rate_use", &battle_config.item_rate_use, 100, 0, 1000000, },
- { "item_rate_use_boss", &battle_config.item_rate_use_boss, 100, 0, 1000000, },
- { "item_rate_adddrop", &battle_config.item_rate_adddrop, 100, 0, 1000000, },
- { "item_rate_treasure", &battle_config.item_rate_treasure, 100, 0, 1000000, },
- { "prevent_logout", &battle_config.prevent_logout, 10000, 0, 60000, },
- { "alchemist_summon_reward", &battle_config.alchemist_summon_reward, 1, 0, 2, },
- { "drops_by_luk", &battle_config.drops_by_luk, 0, 0, INT_MAX, },
- { "drops_by_luk2", &battle_config.drops_by_luk2, 0, 0, INT_MAX, },
- { "equip_natural_break_rate", &battle_config.equip_natural_break_rate, 0, 0, INT_MAX, },
- { "equip_self_break_rate", &battle_config.equip_self_break_rate, 100, 0, INT_MAX, },
- { "equip_skill_break_rate", &battle_config.equip_skill_break_rate, 100, 0, INT_MAX, },
- { "pk_mode", &battle_config.pk_mode, 0, 0, 2, },
- { "pk_level_range", &battle_config.pk_level_range, 0, 0, INT_MAX, },
- { "manner_system", &battle_config.manner_system, 0xFFF, 0, 0xFFF, },
- { "pet_equip_required", &battle_config.pet_equip_required, 0, 0, 1, },
- { "multi_level_up", &battle_config.multi_level_up, 0, 0, 1, },
- { "max_exp_gain_rate", &battle_config.max_exp_gain_rate, 0, 0, INT_MAX, },
- { "backstab_bow_penalty", &battle_config.backstab_bow_penalty, 0, 0, 1, },
- { "night_at_start", &battle_config.night_at_start, 0, 0, 1, },
- { "show_mob_info", &battle_config.show_mob_info, 0, 0, 1|2|4, },
- { "ban_hack_trade", &battle_config.ban_hack_trade, 0, 0, INT_MAX, },
- { "packet_ver_flag", &battle_config.packet_ver_flag, 0xFFFFFF,0x0000,INT_MAX, },
- { "min_hair_style", &battle_config.min_hair_style, 0, 0, INT_MAX, },
- { "max_hair_style", &battle_config.max_hair_style, 23, 0, INT_MAX, },
- { "min_hair_color", &battle_config.min_hair_color, 0, 0, INT_MAX, },
- { "max_hair_color", &battle_config.max_hair_color, 9, 0, INT_MAX, },
- { "min_cloth_color", &battle_config.min_cloth_color, 0, 0, INT_MAX, },
- { "max_cloth_color", &battle_config.max_cloth_color, 4, 0, INT_MAX, },
- { "pet_hair_style", &battle_config.pet_hair_style, 100, 0, INT_MAX, },
- { "castrate_dex_scale", &battle_config.castrate_dex_scale, 150, 1, INT_MAX, },
- { "vcast_stat_scale", &battle_config.vcast_stat_scale, 530, 1, INT_MAX, },
- { "area_size", &battle_config.area_size, 14, 0, INT_MAX, },
- { "zeny_from_mobs", &battle_config.zeny_from_mobs, 0, 0, 1, },
- { "mobs_level_up", &battle_config.mobs_level_up, 0, 0, 1, },
- { "mobs_level_up_exp_rate", &battle_config.mobs_level_up_exp_rate, 1, 1, INT_MAX, },
- { "pk_min_level", &battle_config.pk_min_level, 55, 1, INT_MAX, },
- { "skill_steal_max_tries", &battle_config.skill_steal_max_tries, 0, 0, UCHAR_MAX, },
- { "motd_type", &battle_config.motd_type, 0, 0, 1, },
- { "finding_ore_rate", &battle_config.finding_ore_rate, 100, 0, INT_MAX, },
- { "exp_calc_type", &battle_config.exp_calc_type, 0, 0, 1, },
- { "exp_bonus_attacker", &battle_config.exp_bonus_attacker, 25, 0, INT_MAX, },
- { "exp_bonus_max_attacker", &battle_config.exp_bonus_max_attacker, 12, 2, INT_MAX, },
- { "min_skill_delay_limit", &battle_config.min_skill_delay_limit, 100, 10, INT_MAX, },
- { "default_walk_delay", &battle_config.default_walk_delay, 300, 0, INT_MAX, },
- { "no_skill_delay", &battle_config.no_skill_delay, BL_MOB, BL_NUL, BL_ALL, },
- { "attack_walk_delay", &battle_config.attack_walk_delay, BL_ALL, BL_NUL, BL_ALL, },
- { "require_glory_guild", &battle_config.require_glory_guild, 0, 0, 1, },
- { "idle_no_share", &battle_config.idle_no_share, 0, 0, INT_MAX, },
- { "party_even_share_bonus", &battle_config.party_even_share_bonus, 0, 0, INT_MAX, },
- { "delay_battle_damage", &battle_config.delay_battle_damage, 1, 0, 1, },
- { "hide_woe_damage", &battle_config.hide_woe_damage, 0, 0, 1, },
- { "display_version", &battle_config.display_version, 1, 0, 1, },
- { "display_hallucination", &battle_config.display_hallucination, 1, 0, 1, },
- { "use_statpoint_table", &battle_config.use_statpoint_table, 1, 0, 1, },
- { "ignore_items_gender", &battle_config.ignore_items_gender, 1, 0, 1, },
- { "copyskill_restrict", &battle_config.copyskill_restrict, 2, 0, 2, },
- { "berserk_cancels_buffs", &battle_config.berserk_cancels_buffs, 0, 0, 1, },
- { "debuff_on_logout", &battle_config.debuff_on_logout, 1|2, 0, 1|2, },
- { "monster_ai", &battle_config.mob_ai, 0x000, 0x000, 0x77F, },
- { "hom_setting", &battle_config.hom_setting, 0xFFFF, 0x0000, 0xFFFF, },
- { "dynamic_mobs", &battle_config.dynamic_mobs, 1, 0, 1, },
- { "mob_remove_damaged", &battle_config.mob_remove_damaged, 1, 0, 1, },
- { "show_hp_sp_drain", &battle_config.show_hp_sp_drain, 0, 0, 1, },
- { "show_hp_sp_gain", &battle_config.show_hp_sp_gain, 1, 0, 1, },
- { "mob_npc_event_type", &battle_config.mob_npc_event_type, 1, 0, 1, },
- { "character_size", &battle_config.character_size, 1|2, 0, 1|2, },
- { "mob_max_skilllvl", &battle_config.mob_max_skilllvl, MAX_SKILL_LEVEL, 1, MAX_SKILL_LEVEL, },
- { "retaliate_to_master", &battle_config.retaliate_to_master, 1, 0, 1, },
- { "rare_drop_announce", &battle_config.rare_drop_announce, 0, 0, 10000, },
- { "duel_allow_pvp", &battle_config.duel_allow_pvp, 0, 0, 1, },
- { "duel_allow_gvg", &battle_config.duel_allow_gvg, 0, 0, 1, },
- { "duel_allow_teleport", &battle_config.duel_allow_teleport, 0, 0, 1, },
- { "duel_autoleave_when_die", &battle_config.duel_autoleave_when_die, 1, 0, 1, },
- { "duel_time_interval", &battle_config.duel_time_interval, 60, 0, INT_MAX, },
- { "duel_only_on_same_map", &battle_config.duel_only_on_same_map, 0, 0, 1, },
- { "skip_teleport_lv1_menu", &battle_config.skip_teleport_lv1_menu, 0, 0, 1, },
- { "allow_skill_without_day", &battle_config.allow_skill_without_day, 0, 0, 1, },
- { "allow_es_magic_player", &battle_config.allow_es_magic_pc, 0, 0, 1, },
- { "skill_caster_check", &battle_config.skill_caster_check, 1, 0, 1, },
- { "status_cast_cancel", &battle_config.sc_castcancel, BL_NUL, BL_NUL, BL_ALL, },
- { "pc_status_def_rate", &battle_config.pc_sc_def_rate, 100, 0, INT_MAX, },
- { "mob_status_def_rate", &battle_config.mob_sc_def_rate, 100, 0, INT_MAX, },
- { "pc_luk_status_def", &battle_config.pc_luk_sc_def, 300, 1, INT_MAX, },
- { "mob_luk_status_def", &battle_config.mob_luk_sc_def, 300, 1, INT_MAX, },
- { "pc_max_status_def", &battle_config.pc_max_sc_def, 100, 0, INT_MAX, },
- { "mob_max_status_def", &battle_config.mob_max_sc_def, 100, 0, INT_MAX, },
- { "sg_miracle_skill_ratio", &battle_config.sg_miracle_skill_ratio, 1, 0, 10000, },
- { "sg_angel_skill_ratio", &battle_config.sg_angel_skill_ratio, 10, 0, 10000, },
- { "autospell_stacking", &battle_config.autospell_stacking, 0, 0, 1, },
- { "override_mob_names", &battle_config.override_mob_names, 0, 0, 2, },
- { "min_chat_delay", &battle_config.min_chat_delay, 0, 0, INT_MAX, },
- { "friend_auto_add", &battle_config.friend_auto_add, 1, 0, 1, },
- { "hom_rename", &battle_config.hom_rename, 0, 0, 1, },
- { "homunculus_show_growth", &battle_config.homunculus_show_growth, 0, 0, 1, },
- { "homunculus_friendly_rate", &battle_config.homunculus_friendly_rate, 100, 0, INT_MAX, },
- { "vending_tax", &battle_config.vending_tax, 0, 0, 10000, },
- { "day_duration", &battle_config.day_duration, 0, 0, INT_MAX, },
- { "night_duration", &battle_config.night_duration, 0, 0, INT_MAX, },
- { "mob_remove_delay", &battle_config.mob_remove_delay, 60000, 1000, INT_MAX, },
- { "mob_active_time", &battle_config.mob_active_time, 0, 0, INT_MAX, },
- { "boss_active_time", &battle_config.boss_active_time, 0, 0, INT_MAX, },
- { "sg_miracle_skill_duration", &battle_config.sg_miracle_skill_duration, 3600000, 0, INT_MAX, },
- { "hvan_explosion_intimate", &battle_config.hvan_explosion_intimate, 45000, 0, 100000, },
- { "quest_exp_rate", &battle_config.quest_exp_rate, 100, 0, INT_MAX, },
- { "at_mapflag", &battle_config.autotrade_mapflag, 0, 0, 1, },
- { "at_timeout", &battle_config.at_timeout, 0, 0, INT_MAX, },
- { "homunculus_autoloot", &battle_config.homunculus_autoloot, 0, 0, 1, },
- { "idle_no_autoloot", &battle_config.idle_no_autoloot, 0, 0, INT_MAX, },
- { "max_guild_alliance", &battle_config.max_guild_alliance, 3, 0, 3, },
- { "ksprotection", &battle_config.ksprotection, 5000, 0, INT_MAX, },
- { "auction_feeperhour", &battle_config.auction_feeperhour, 12000, 0, INT_MAX, },
- { "auction_maximumprice", &battle_config.auction_maximumprice, 500000000, 0, MAX_ZENY, },
- { "homunculus_auto_vapor", &battle_config.homunculus_auto_vapor, 1, 0, 1, },
- { "display_status_timers", &battle_config.display_status_timers, 1, 0, 1, },
- { "skill_add_heal_rate", &battle_config.skill_add_heal_rate, 7, 0, INT_MAX, },
- { "eq_single_target_reflectable", &battle_config.eq_single_target_reflectable, 1, 0, 1, },
- { "invincible.nodamage", &battle_config.invincible_nodamage, 0, 0, 1, },
- { "mob_slave_keep_target", &battle_config.mob_slave_keep_target, 0, 0, 1, },
- { "autospell_check_range", &battle_config.autospell_check_range, 0, 0, 1, },
- { "client_reshuffle_dice", &battle_config.client_reshuffle_dice, 0, 0, 1, },
- { "client_sort_storage", &battle_config.client_sort_storage, 0, 0, 1, },
- { "feature.buying_store", &battle_config.feature_buying_store, 1, 0, 1, },
- { "feature.search_stores", &battle_config.feature_search_stores, 1, 0, 1, },
- { "searchstore_querydelay", &battle_config.searchstore_querydelay, 10, 0, INT_MAX, },
- { "searchstore_maxresults", &battle_config.searchstore_maxresults, 30, 1, INT_MAX, },
- { "display_party_name", &battle_config.display_party_name, 0, 0, 1, },
- { "cashshop_show_points", &battle_config.cashshop_show_points, 0, 0, 1, },
- { "mail_show_status", &battle_config.mail_show_status, 0, 0, 2, },
- { "client_limit_unit_lv", &battle_config.client_limit_unit_lv, 0, 0, BL_ALL, },
- // BattleGround Settings
- { "bg_update_interval", &battle_config.bg_update_interval, 1000, 100, INT_MAX, },
- { "bg_short_attack_damage_rate", &battle_config.bg_short_damage_rate, 80, 0, INT_MAX, },
- { "bg_long_attack_damage_rate", &battle_config.bg_long_damage_rate, 80, 0, INT_MAX, },
- { "bg_weapon_attack_damage_rate", &battle_config.bg_weapon_damage_rate, 60, 0, INT_MAX, },
- { "bg_magic_attack_damage_rate", &battle_config.bg_magic_damage_rate, 60, 0, INT_MAX, },
- { "bg_misc_attack_damage_rate", &battle_config.bg_misc_damage_rate, 60, 0, INT_MAX, },
- { "bg_flee_penalty", &battle_config.bg_flee_penalty, 20, 0, INT_MAX, },
- /**
- * rAthena
- **/
- { "max_third_parameter", &battle_config.max_third_parameter, 120, 10, 10000, },
- { "max_baby_third_parameter", &battle_config.max_baby_third_parameter, 108, 10, 10000, },
- { "atcommand_max_stat_bypass", &battle_config.atcommand_max_stat_bypass, 0, 0, 100, },
- { "skill_amotion_leniency", &battle_config.skill_amotion_leniency, 90, 0, 100 },
- { "mvp_tomb_enabled", &battle_config.mvp_tomb_enabled, 1, 0, 1 },
- { "feature.atcommand_suggestions", &battle_config.atcommand_suggestions_enabled, 0, 0, 1 },
- { "min_npc_vending_distance", &battle_config.min_npc_vending_distance, 3, 0, 100 },
- { "atcommand_mobinfo_type", &battle_config.atcommand_mobinfo_type, 0, 0, 1 },
- { "homunculus_max_level", &battle_config.hom_max_level, 99, 0, MAX_LEVEL, },
- { "homunculus_S_max_level", &battle_config.hom_S_max_level, 150, 0, MAX_LEVEL, },
- { "mob_size_influence", &battle_config.mob_size_influence, 0, 0, 1, },
+ { "warp_point_debug", &battle_config.warp_point_debug, 0, 0, 1, },
+ { "enable_critical", &battle_config.enable_critical, BL_PC, BL_NUL, BL_ALL, },
+ { "mob_critical_rate", &battle_config.mob_critical_rate, 100, 0, INT_MAX, },
+ { "critical_rate", &battle_config.critical_rate, 100, 0, INT_MAX, },
+ { "enable_baseatk", &battle_config.enable_baseatk, BL_PC|BL_HOM, BL_NUL, BL_ALL, },
+ { "enable_perfect_flee", &battle_config.enable_perfect_flee, BL_PC|BL_PET, BL_NUL, BL_ALL, },
+ { "casting_rate", &battle_config.cast_rate, 100, 0, INT_MAX, },
+ { "delay_rate", &battle_config.delay_rate, 100, 0, INT_MAX, },
+ { "delay_dependon_dex", &battle_config.delay_dependon_dex, 0, 0, 1, },
+ { "delay_dependon_agi", &battle_config.delay_dependon_agi, 0, 0, 1, },
+ { "skill_delay_attack_enable", &battle_config.sdelay_attack_enable, 0, 0, 1, },
+ { "left_cardfix_to_right", &battle_config.left_cardfix_to_right, 0, 0, 1, },
+ { "skill_add_range", &battle_config.skill_add_range, 0, 0, INT_MAX, },
+ { "skill_out_range_consume", &battle_config.skill_out_range_consume, 1, 0, 1, },
+ { "skillrange_by_distance", &battle_config.skillrange_by_distance, ~BL_PC, BL_NUL, BL_ALL, },
+ { "skillrange_from_weapon", &battle_config.use_weapon_skill_range, ~BL_PC, BL_NUL, BL_ALL, },
+ { "player_damage_delay_rate", &battle_config.pc_damage_delay_rate, 100, 0, INT_MAX, },
+ { "defunit_not_enemy", &battle_config.defnotenemy, 0, 0, 1, },
+ { "gvg_traps_target_all", &battle_config.vs_traps_bctall, BL_PC, BL_NUL, BL_ALL, },
+ { "traps_setting", &battle_config.traps_setting, 0, 0, 1, },
+ { "summon_flora_setting", &battle_config.summon_flora, 1|2, 0, 1|2, },
+ { "clear_skills_on_death", &battle_config.clear_unit_ondeath, BL_NUL, BL_NUL, BL_ALL, },
+ { "clear_skills_on_warp", &battle_config.clear_unit_onwarp, BL_ALL, BL_NUL, BL_ALL, },
+ { "random_monster_checklv", &battle_config.random_monster_checklv, 0, 0, 1, },
+ { "attribute_recover", &battle_config.attr_recover, 1, 0, 1, },
+ { "flooritem_lifetime", &battle_config.flooritem_lifetime, 60000, 1000, INT_MAX, },
+ { "item_auto_get", &battle_config.item_auto_get, 0, 0, 1, },
+ { "item_first_get_time", &battle_config.item_first_get_time, 3000, 0, INT_MAX, },
+ { "item_second_get_time", &battle_config.item_second_get_time, 1000, 0, INT_MAX, },
+ { "item_third_get_time", &battle_config.item_third_get_time, 1000, 0, INT_MAX, },
+ { "mvp_item_first_get_time", &battle_config.mvp_item_first_get_time, 10000, 0, INT_MAX, },
+ { "mvp_item_second_get_time", &battle_config.mvp_item_second_get_time, 10000, 0, INT_MAX, },
+ { "mvp_item_third_get_time", &battle_config.mvp_item_third_get_time, 2000, 0, INT_MAX, },
+ { "drop_rate0item", &battle_config.drop_rate0item, 0, 0, 1, },
+ { "base_exp_rate", &battle_config.base_exp_rate, 100, 0, INT_MAX, },
+ { "job_exp_rate", &battle_config.job_exp_rate, 100, 0, INT_MAX, },
+ { "pvp_exp", &battle_config.pvp_exp, 1, 0, 1, },
+ { "death_penalty_type", &battle_config.death_penalty_type, 0, 0, 2, },
+ { "death_penalty_base", &battle_config.death_penalty_base, 0, 0, INT_MAX, },
+ { "death_penalty_job", &battle_config.death_penalty_job, 0, 0, INT_MAX, },
+ { "zeny_penalty", &battle_config.zeny_penalty, 0, 0, INT_MAX, },
+ { "hp_rate", &battle_config.hp_rate, 100, 1, INT_MAX, },
+ { "sp_rate", &battle_config.sp_rate, 100, 1, INT_MAX, },
+ { "restart_hp_rate", &battle_config.restart_hp_rate, 0, 0, 100, },
+ { "restart_sp_rate", &battle_config.restart_sp_rate, 0, 0, 100, },
+ { "guild_aura", &battle_config.guild_aura, 31, 0, 31, },
+ { "mvp_hp_rate", &battle_config.mvp_hp_rate, 100, 1, INT_MAX, },
+ { "mvp_exp_rate", &battle_config.mvp_exp_rate, 100, 0, INT_MAX, },
+ { "monster_hp_rate", &battle_config.monster_hp_rate, 100, 1, INT_MAX, },
+ { "monster_max_aspd", &battle_config.monster_max_aspd, 199, 100, 199, },
+ { "view_range_rate", &battle_config.view_range_rate, 100, 0, INT_MAX, },
+ { "chase_range_rate", &battle_config.chase_range_rate, 100, 0, INT_MAX, },
+ { "gtb_sc_immunity", &battle_config.gtb_sc_immunity, 50, 0, INT_MAX, },
+ { "guild_max_castles", &battle_config.guild_max_castles, 0, 0, INT_MAX, },
+ { "guild_skill_relog_delay", &battle_config.guild_skill_relog_delay, 0, 0, 1, },
+ { "emergency_call", &battle_config.emergency_call, 11, 0, 31, },
+ { "atcommand_spawn_quantity_limit", &battle_config.atc_spawn_quantity_limit, 100, 0, INT_MAX, },
+ { "atcommand_slave_clone_limit", &battle_config.atc_slave_clone_limit, 25, 0, INT_MAX, },
+ { "partial_name_scan", &battle_config.partial_name_scan, 0, 0, 1, },
+ { "player_skillfree", &battle_config.skillfree, 0, 0, 1, },
+ { "player_skillup_limit", &battle_config.skillup_limit, 1, 0, 1, },
+ { "weapon_produce_rate", &battle_config.wp_rate, 100, 0, INT_MAX, },
+ { "potion_produce_rate", &battle_config.pp_rate, 100, 0, INT_MAX, },
+ { "monster_active_enable", &battle_config.monster_active_enable, 1, 0, 1, },
+ { "monster_damage_delay_rate", &battle_config.monster_damage_delay_rate, 100, 0, INT_MAX, },
+ { "monster_loot_type", &battle_config.monster_loot_type, 0, 0, 1, },
+// { "mob_skill_use", &battle_config.mob_skill_use, 1, 0, 1, }, //Deprecated
+ { "mob_skill_rate", &battle_config.mob_skill_rate, 100, 0, INT_MAX, },
+ { "mob_skill_delay", &battle_config.mob_skill_delay, 100, 0, INT_MAX, },
+ { "mob_count_rate", &battle_config.mob_count_rate, 100, 0, INT_MAX, },
+ { "mob_spawn_delay", &battle_config.mob_spawn_delay, 100, 0, INT_MAX, },
+ { "plant_spawn_delay", &battle_config.plant_spawn_delay, 100, 0, INT_MAX, },
+ { "boss_spawn_delay", &battle_config.boss_spawn_delay, 100, 0, INT_MAX, },
+ { "no_spawn_on_player", &battle_config.no_spawn_on_player, 0, 0, 100, },
+ { "force_random_spawn", &battle_config.force_random_spawn, 0, 0, 1, },
+ { "slaves_inherit_mode", &battle_config.slaves_inherit_mode, 2, 0, 3, },
+ { "slaves_inherit_speed", &battle_config.slaves_inherit_speed, 3, 0, 3, },
+ { "summons_trigger_autospells", &battle_config.summons_trigger_autospells, 1, 0, 1, },
+ { "pc_damage_walk_delay_rate", &battle_config.pc_walk_delay_rate, 20, 0, INT_MAX, },
+ { "damage_walk_delay_rate", &battle_config.walk_delay_rate, 100, 0, INT_MAX, },
+ { "multihit_delay", &battle_config.multihit_delay, 80, 0, INT_MAX, },
+ { "quest_skill_learn", &battle_config.quest_skill_learn, 0, 0, 1, },
+ { "quest_skill_reset", &battle_config.quest_skill_reset, 0, 0, 1, },
+ { "basic_skill_check", &battle_config.basic_skill_check, 1, 0, 1, },
+ { "guild_emperium_check", &battle_config.guild_emperium_check, 1, 0, 1, },
+ { "guild_exp_limit", &battle_config.guild_exp_limit, 50, 0, 99, },
+ { "player_invincible_time", &battle_config.pc_invincible_time, 5000, 0, INT_MAX, },
+ { "pet_catch_rate", &battle_config.pet_catch_rate, 100, 0, INT_MAX, },
+ { "pet_rename", &battle_config.pet_rename, 0, 0, 1, },
+ { "pet_friendly_rate", &battle_config.pet_friendly_rate, 100, 0, INT_MAX, },
+ { "pet_hungry_delay_rate", &battle_config.pet_hungry_delay_rate, 100, 10, INT_MAX, },
+ { "pet_hungry_friendly_decrease", &battle_config.pet_hungry_friendly_decrease, 5, 0, INT_MAX, },
+ { "pet_status_support", &battle_config.pet_status_support, 0, 0, 1, },
+ { "pet_attack_support", &battle_config.pet_attack_support, 0, 0, 1, },
+ { "pet_damage_support", &battle_config.pet_damage_support, 0, 0, 1, },
+ { "pet_support_min_friendly", &battle_config.pet_support_min_friendly, 900, 0, 950, },
+ { "pet_equip_min_friendly", &battle_config.pet_equip_min_friendly, 900, 0, 950, },
+ { "pet_support_rate", &battle_config.pet_support_rate, 100, 0, INT_MAX, },
+ { "pet_attack_exp_to_master", &battle_config.pet_attack_exp_to_master, 0, 0, 1, },
+ { "pet_attack_exp_rate", &battle_config.pet_attack_exp_rate, 100, 0, INT_MAX, },
+ { "pet_lv_rate", &battle_config.pet_lv_rate, 0, 0, INT_MAX, },
+ { "pet_max_stats", &battle_config.pet_max_stats, 99, 0, INT_MAX, },
+ { "pet_max_atk1", &battle_config.pet_max_atk1, 750, 0, INT_MAX, },
+ { "pet_max_atk2", &battle_config.pet_max_atk2, 1000, 0, INT_MAX, },
+ { "pet_disable_in_gvg", &battle_config.pet_no_gvg, 0, 0, 1, },
+ { "skill_min_damage", &battle_config.skill_min_damage, 2|4, 0, 1|2|4, },
+ { "finger_offensive_type", &battle_config.finger_offensive_type, 0, 0, 1, },
+ { "heal_exp", &battle_config.heal_exp, 0, 0, INT_MAX, },
+ { "resurrection_exp", &battle_config.resurrection_exp, 0, 0, INT_MAX, },
+ { "shop_exp", &battle_config.shop_exp, 0, 0, INT_MAX, },
+ { "max_heal_lv", &battle_config.max_heal_lv, 11, 1, INT_MAX, },
+ { "max_heal", &battle_config.max_heal, 9999, 0, INT_MAX, },
+ { "combo_delay_rate", &battle_config.combo_delay_rate, 100, 0, INT_MAX, },
+ { "item_check", &battle_config.item_check, 0, 0, 1, },
+ { "item_use_interval", &battle_config.item_use_interval, 100, 0, INT_MAX, },
+ { "cashfood_use_interval", &battle_config.cashfood_use_interval, 60000, 0, INT_MAX, },
+ { "wedding_modifydisplay", &battle_config.wedding_modifydisplay, 0, 0, 1, },
+ { "wedding_ignorepalette", &battle_config.wedding_ignorepalette, 0, 0, 1, },
+ { "xmas_ignorepalette", &battle_config.xmas_ignorepalette, 0, 0, 1, },
+ { "summer_ignorepalette", &battle_config.summer_ignorepalette, 0, 0, 1, },
+ { "natural_healhp_interval", &battle_config.natural_healhp_interval, 6000, NATURAL_HEAL_INTERVAL, INT_MAX, },
+ { "natural_healsp_interval", &battle_config.natural_healsp_interval, 8000, NATURAL_HEAL_INTERVAL, INT_MAX, },
+ { "natural_heal_skill_interval", &battle_config.natural_heal_skill_interval, 10000, NATURAL_HEAL_INTERVAL, INT_MAX, },
+ { "natural_heal_weight_rate", &battle_config.natural_heal_weight_rate, 50, 50, 101 },
+ { "arrow_decrement", &battle_config.arrow_decrement, 1, 0, 2, },
+ { "max_aspd", &battle_config.max_aspd, 190, 100, 199, },
+ { "max_third_aspd", &battle_config.max_third_aspd, 193, 100, 199, },
+ { "max_walk_speed", &battle_config.max_walk_speed, 300, 100, 100*DEFAULT_WALK_SPEED, },
+ { "max_lv", &battle_config.max_lv, 99, 0, MAX_LEVEL, },
+ { "aura_lv", &battle_config.aura_lv, 99, 0, INT_MAX, },
+ { "max_hp", &battle_config.max_hp, 32500, 100, 1000000000, },
+ { "max_sp", &battle_config.max_sp, 32500, 100, 1000000000, },
+ { "max_cart_weight", &battle_config.max_cart_weight, 8000, 100, 1000000, },
+ { "max_parameter", &battle_config.max_parameter, 99, 10, 10000, },
+ { "max_baby_parameter", &battle_config.max_baby_parameter, 80, 10, 10000, },
+ { "max_def", &battle_config.max_def, 99, 0, INT_MAX, },
+ { "over_def_bonus", &battle_config.over_def_bonus, 0, 0, 1000, },
+ { "skill_log", &battle_config.skill_log, BL_NUL, BL_NUL, BL_ALL, },
+ { "battle_log", &battle_config.battle_log, 0, 0, 1, },
+ { "etc_log", &battle_config.etc_log, 1, 0, 1, },
+ { "save_clothcolor", &battle_config.save_clothcolor, 1, 0, 1, },
+ { "undead_detect_type", &battle_config.undead_detect_type, 0, 0, 2, },
+ { "auto_counter_type", &battle_config.auto_counter_type, BL_ALL, BL_NUL, BL_ALL, },
+ { "min_hitrate", &battle_config.min_hitrate, 5, 0, 100, },
+ { "max_hitrate", &battle_config.max_hitrate, 100, 0, 100, },
+ { "agi_penalty_target", &battle_config.agi_penalty_target, BL_PC, BL_NUL, BL_ALL, },
+ { "agi_penalty_type", &battle_config.agi_penalty_type, 1, 0, 2, },
+ { "agi_penalty_count", &battle_config.agi_penalty_count, 3, 2, INT_MAX, },
+ { "agi_penalty_num", &battle_config.agi_penalty_num, 10, 0, INT_MAX, },
+ { "vit_penalty_target", &battle_config.vit_penalty_target, BL_PC, BL_NUL, BL_ALL, },
+ { "vit_penalty_type", &battle_config.vit_penalty_type, 1, 0, 2, },
+ { "vit_penalty_count", &battle_config.vit_penalty_count, 3, 2, INT_MAX, },
+ { "vit_penalty_num", &battle_config.vit_penalty_num, 5, 0, INT_MAX, },
+ { "weapon_defense_type", &battle_config.weapon_defense_type, 0, 0, INT_MAX, },
+ { "magic_defense_type", &battle_config.magic_defense_type, 0, 0, INT_MAX, },
+ { "skill_reiteration", &battle_config.skill_reiteration, BL_NUL, BL_NUL, BL_ALL, },
+ { "skill_nofootset", &battle_config.skill_nofootset, BL_PC, BL_NUL, BL_ALL, },
+ { "player_cloak_check_type", &battle_config.pc_cloak_check_type, 1, 0, 1|2|4, },
+ { "monster_cloak_check_type", &battle_config.monster_cloak_check_type, 4, 0, 1|2|4, },
+ { "sense_type", &battle_config.estimation_type, 1|2, 0, 1|2, },
+ { "gvg_short_attack_damage_rate", &battle_config.gvg_short_damage_rate, 80, 0, INT_MAX, },
+ { "gvg_long_attack_damage_rate", &battle_config.gvg_long_damage_rate, 80, 0, INT_MAX, },
+ { "gvg_weapon_attack_damage_rate", &battle_config.gvg_weapon_damage_rate, 60, 0, INT_MAX, },
+ { "gvg_magic_attack_damage_rate", &battle_config.gvg_magic_damage_rate, 60, 0, INT_MAX, },
+ { "gvg_misc_attack_damage_rate", &battle_config.gvg_misc_damage_rate, 60, 0, INT_MAX, },
+ { "gvg_flee_penalty", &battle_config.gvg_flee_penalty, 20, 0, INT_MAX, },
+ { "pk_short_attack_damage_rate", &battle_config.pk_short_damage_rate, 80, 0, INT_MAX, },
+ { "pk_long_attack_damage_rate", &battle_config.pk_long_damage_rate, 70, 0, INT_MAX, },
+ { "pk_weapon_attack_damage_rate", &battle_config.pk_weapon_damage_rate, 60, 0, INT_MAX, },
+ { "pk_magic_attack_damage_rate", &battle_config.pk_magic_damage_rate, 60, 0, INT_MAX, },
+ { "pk_misc_attack_damage_rate", &battle_config.pk_misc_damage_rate, 60, 0, INT_MAX, },
+ { "mob_changetarget_byskill", &battle_config.mob_changetarget_byskill, 0, 0, 1, },
+ { "attack_direction_change", &battle_config.attack_direction_change, BL_ALL, BL_NUL, BL_ALL, },
+ { "land_skill_limit", &battle_config.land_skill_limit, BL_ALL, BL_NUL, BL_ALL, },
+ { "monster_class_change_full_recover", &battle_config.monster_class_change_recover, 1, 0, 1, },
+ { "produce_item_name_input", &battle_config.produce_item_name_input, 0x1|0x2, 0, 0x9F, },
+ { "display_skill_fail", &battle_config.display_skill_fail, 2, 0, 1|2|4|8, },
+ { "chat_warpportal", &battle_config.chat_warpportal, 0, 0, 1, },
+ { "mob_warp", &battle_config.mob_warp, 0, 0, 1|2|4, },
+ { "dead_branch_active", &battle_config.dead_branch_active, 1, 0, 1, },
+ { "vending_max_value", &battle_config.vending_max_value, 10000000, 1, MAX_ZENY, },
+ { "vending_over_max", &battle_config.vending_over_max, 1, 0, 1, },
+ { "show_steal_in_same_party", &battle_config.show_steal_in_same_party, 0, 0, 1, },
+ { "party_hp_mode", &battle_config.party_hp_mode, 0, 0, 1, },
+ { "show_party_share_picker", &battle_config.party_show_share_picker, 1, 0, 1, },
+ { "show_picker.item_type", &battle_config.show_picker_item_type, 112, 0, INT_MAX, },
+ { "party_update_interval", &battle_config.party_update_interval, 1000, 100, INT_MAX, },
+ { "party_item_share_type", &battle_config.party_share_type, 0, 0, 1|2|3, },
+ { "attack_attr_none", &battle_config.attack_attr_none, ~BL_PC, BL_NUL, BL_ALL, },
+ { "gx_allhit", &battle_config.gx_allhit, 0, 0, 1, },
+ { "gx_disptype", &battle_config.gx_disptype, 1, 0, 1, },
+ { "devotion_level_difference", &battle_config.devotion_level_difference, 10, 0, INT_MAX, },
+ { "player_skill_partner_check", &battle_config.player_skill_partner_check, 1, 0, 1, },
+ { "invite_request_check", &battle_config.invite_request_check, 1, 0, 1, },
+ { "skill_removetrap_type", &battle_config.skill_removetrap_type, 0, 0, 1, },
+ { "disp_experience", &battle_config.disp_experience, 0, 0, 1, },
+ { "disp_zeny", &battle_config.disp_zeny, 0, 0, 1, },
+ { "castle_defense_rate", &battle_config.castle_defense_rate, 100, 0, 100, },
+ { "bone_drop", &battle_config.bone_drop, 0, 0, 2, },
+ { "buyer_name", &battle_config.buyer_name, 1, 0, 1, },
+ { "skill_wall_check", &battle_config.skill_wall_check, 1, 0, 1, },
+ { "cell_stack_limit", &battle_config.cell_stack_limit, 1, 1, 255, },
+ { "dancing_weaponswitch_fix", &battle_config.dancing_weaponswitch_fix, 1, 0, 1, },
+
+// eAthena additions
+ { "item_logarithmic_drops", &battle_config.logarithmic_drops, 0, 0, 1, },
+ { "item_drop_common_min", &battle_config.item_drop_common_min, 1, 1, 10000, },
+ { "item_drop_common_max", &battle_config.item_drop_common_max, 10000, 1, 10000, },
+ { "item_drop_equip_min", &battle_config.item_drop_equip_min, 1, 1, 10000, },
+ { "item_drop_equip_max", &battle_config.item_drop_equip_max, 10000, 1, 10000, },
+ { "item_drop_card_min", &battle_config.item_drop_card_min, 1, 1, 10000, },
+ { "item_drop_card_max", &battle_config.item_drop_card_max, 10000, 1, 10000, },
+ { "item_drop_mvp_min", &battle_config.item_drop_mvp_min, 1, 1, 10000, },
+ { "item_drop_mvp_max", &battle_config.item_drop_mvp_max, 10000, 1, 10000, },
+ { "item_drop_heal_min", &battle_config.item_drop_heal_min, 1, 1, 10000, },
+ { "item_drop_heal_max", &battle_config.item_drop_heal_max, 10000, 1, 10000, },
+ { "item_drop_use_min", &battle_config.item_drop_use_min, 1, 1, 10000, },
+ { "item_drop_use_max", &battle_config.item_drop_use_max, 10000, 1, 10000, },
+ { "item_drop_add_min", &battle_config.item_drop_adddrop_min, 1, 1, 10000, },
+ { "item_drop_add_max", &battle_config.item_drop_adddrop_max, 10000, 1, 10000, },
+ { "item_drop_treasure_min", &battle_config.item_drop_treasure_min, 1, 1, 10000, },
+ { "item_drop_treasure_max", &battle_config.item_drop_treasure_max, 10000, 1, 10000, },
+ { "item_rate_mvp", &battle_config.item_rate_mvp, 100, 0, 1000000, },
+ { "item_rate_common", &battle_config.item_rate_common, 100, 0, 1000000, },
+ { "item_rate_common_boss", &battle_config.item_rate_common_boss, 100, 0, 1000000, },
+ { "item_rate_equip", &battle_config.item_rate_equip, 100, 0, 1000000, },
+ { "item_rate_equip_boss", &battle_config.item_rate_equip_boss, 100, 0, 1000000, },
+ { "item_rate_card", &battle_config.item_rate_card, 100, 0, 1000000, },
+ { "item_rate_card_boss", &battle_config.item_rate_card_boss, 100, 0, 1000000, },
+ { "item_rate_heal", &battle_config.item_rate_heal, 100, 0, 1000000, },
+ { "item_rate_heal_boss", &battle_config.item_rate_heal_boss, 100, 0, 1000000, },
+ { "item_rate_use", &battle_config.item_rate_use, 100, 0, 1000000, },
+ { "item_rate_use_boss", &battle_config.item_rate_use_boss, 100, 0, 1000000, },
+ { "item_rate_adddrop", &battle_config.item_rate_adddrop, 100, 0, 1000000, },
+ { "item_rate_treasure", &battle_config.item_rate_treasure, 100, 0, 1000000, },
+ { "prevent_logout", &battle_config.prevent_logout, 10000, 0, 60000, },
+ { "alchemist_summon_reward", &battle_config.alchemist_summon_reward, 1, 0, 2, },
+ { "drops_by_luk", &battle_config.drops_by_luk, 0, 0, INT_MAX, },
+ { "drops_by_luk2", &battle_config.drops_by_luk2, 0, 0, INT_MAX, },
+ { "equip_natural_break_rate", &battle_config.equip_natural_break_rate, 0, 0, INT_MAX, },
+ { "equip_self_break_rate", &battle_config.equip_self_break_rate, 100, 0, INT_MAX, },
+ { "equip_skill_break_rate", &battle_config.equip_skill_break_rate, 100, 0, INT_MAX, },
+ { "pk_mode", &battle_config.pk_mode, 0, 0, 2, },
+ { "pk_level_range", &battle_config.pk_level_range, 0, 0, INT_MAX, },
+ { "manner_system", &battle_config.manner_system, 0xFFF, 0, 0xFFF, },
+ { "pet_equip_required", &battle_config.pet_equip_required, 0, 0, 1, },
+ { "multi_level_up", &battle_config.multi_level_up, 0, 0, 1, },
+ { "max_exp_gain_rate", &battle_config.max_exp_gain_rate, 0, 0, INT_MAX, },
+ { "backstab_bow_penalty", &battle_config.backstab_bow_penalty, 0, 0, 1, },
+ { "night_at_start", &battle_config.night_at_start, 0, 0, 1, },
+ { "show_mob_info", &battle_config.show_mob_info, 0, 0, 1|2|4, },
+ { "ban_hack_trade", &battle_config.ban_hack_trade, 0, 0, INT_MAX, },
+ { "packet_ver_flag", &battle_config.packet_ver_flag, 0xFFFFFF,0x0000,INT_MAX, },
+ { "min_hair_style", &battle_config.min_hair_style, 0, 0, INT_MAX, },
+ { "max_hair_style", &battle_config.max_hair_style, 23, 0, INT_MAX, },
+ { "min_hair_color", &battle_config.min_hair_color, 0, 0, INT_MAX, },
+ { "max_hair_color", &battle_config.max_hair_color, 9, 0, INT_MAX, },
+ { "min_cloth_color", &battle_config.min_cloth_color, 0, 0, INT_MAX, },
+ { "max_cloth_color", &battle_config.max_cloth_color, 4, 0, INT_MAX, },
+ { "pet_hair_style", &battle_config.pet_hair_style, 100, 0, INT_MAX, },
+ { "castrate_dex_scale", &battle_config.castrate_dex_scale, 150, 1, INT_MAX, },
+ { "vcast_stat_scale", &battle_config.vcast_stat_scale, 530, 1, INT_MAX, },
+ { "area_size", &battle_config.area_size, 14, 0, INT_MAX, },
+ { "zeny_from_mobs", &battle_config.zeny_from_mobs, 0, 0, 1, },
+ { "mobs_level_up", &battle_config.mobs_level_up, 0, 0, 1, },
+ { "mobs_level_up_exp_rate", &battle_config.mobs_level_up_exp_rate, 1, 1, INT_MAX, },
+ { "pk_min_level", &battle_config.pk_min_level, 55, 1, INT_MAX, },
+ { "skill_steal_max_tries", &battle_config.skill_steal_max_tries, 0, 0, UCHAR_MAX, },
+ { "motd_type", &battle_config.motd_type, 0, 0, 1, },
+ { "finding_ore_rate", &battle_config.finding_ore_rate, 100, 0, INT_MAX, },
+ { "exp_calc_type", &battle_config.exp_calc_type, 0, 0, 1, },
+ { "exp_bonus_attacker", &battle_config.exp_bonus_attacker, 25, 0, INT_MAX, },
+ { "exp_bonus_max_attacker", &battle_config.exp_bonus_max_attacker, 12, 2, INT_MAX, },
+ { "min_skill_delay_limit", &battle_config.min_skill_delay_limit, 100, 10, INT_MAX, },
+ { "default_walk_delay", &battle_config.default_walk_delay, 300, 0, INT_MAX, },
+ { "no_skill_delay", &battle_config.no_skill_delay, BL_MOB, BL_NUL, BL_ALL, },
+ { "attack_walk_delay", &battle_config.attack_walk_delay, BL_ALL, BL_NUL, BL_ALL, },
+ { "require_glory_guild", &battle_config.require_glory_guild, 0, 0, 1, },
+ { "idle_no_share", &battle_config.idle_no_share, 0, 0, INT_MAX, },
+ { "party_even_share_bonus", &battle_config.party_even_share_bonus, 0, 0, INT_MAX, },
+ { "delay_battle_damage", &battle_config.delay_battle_damage, 1, 0, 1, },
+ { "hide_woe_damage", &battle_config.hide_woe_damage, 0, 0, 1, },
+ { "display_version", &battle_config.display_version, 1, 0, 1, },
+ { "display_hallucination", &battle_config.display_hallucination, 1, 0, 1, },
+ { "use_statpoint_table", &battle_config.use_statpoint_table, 1, 0, 1, },
+ { "ignore_items_gender", &battle_config.ignore_items_gender, 1, 0, 1, },
+ { "copyskill_restrict", &battle_config.copyskill_restrict, 2, 0, 2, },
+ { "berserk_cancels_buffs", &battle_config.berserk_cancels_buffs, 0, 0, 1, },
+ { "debuff_on_logout", &battle_config.debuff_on_logout, 1|2, 0, 1|2, },
+ { "monster_ai", &battle_config.mob_ai, 0x000, 0x000, 0x77F, },
+ { "hom_setting", &battle_config.hom_setting, 0xFFFF, 0x0000, 0xFFFF, },
+ { "dynamic_mobs", &battle_config.dynamic_mobs, 1, 0, 1, },
+ { "mob_remove_damaged", &battle_config.mob_remove_damaged, 1, 0, 1, },
+ { "show_hp_sp_drain", &battle_config.show_hp_sp_drain, 0, 0, 1, },
+ { "show_hp_sp_gain", &battle_config.show_hp_sp_gain, 1, 0, 1, },
+ { "mob_npc_event_type", &battle_config.mob_npc_event_type, 1, 0, 1, },
+ { "character_size", &battle_config.character_size, 1|2, 0, 1|2, },
+ { "mob_max_skilllvl", &battle_config.mob_max_skilllvl, MAX_SKILL_LEVEL, 1, MAX_SKILL_LEVEL, },
+ { "retaliate_to_master", &battle_config.retaliate_to_master, 1, 0, 1, },
+ { "rare_drop_announce", &battle_config.rare_drop_announce, 0, 0, 10000, },
+ { "duel_allow_pvp", &battle_config.duel_allow_pvp, 0, 0, 1, },
+ { "duel_allow_gvg", &battle_config.duel_allow_gvg, 0, 0, 1, },
+ { "duel_allow_teleport", &battle_config.duel_allow_teleport, 0, 0, 1, },
+ { "duel_autoleave_when_die", &battle_config.duel_autoleave_when_die, 1, 0, 1, },
+ { "duel_time_interval", &battle_config.duel_time_interval, 60, 0, INT_MAX, },
+ { "duel_only_on_same_map", &battle_config.duel_only_on_same_map, 0, 0, 1, },
+ { "skip_teleport_lv1_menu", &battle_config.skip_teleport_lv1_menu, 0, 0, 1, },
+ { "allow_skill_without_day", &battle_config.allow_skill_without_day, 0, 0, 1, },
+ { "allow_es_magic_player", &battle_config.allow_es_magic_pc, 0, 0, 1, },
+ { "skill_caster_check", &battle_config.skill_caster_check, 1, 0, 1, },
+ { "status_cast_cancel", &battle_config.sc_castcancel, BL_NUL, BL_NUL, BL_ALL, },
+ { "pc_status_def_rate", &battle_config.pc_sc_def_rate, 100, 0, INT_MAX, },
+ { "mob_status_def_rate", &battle_config.mob_sc_def_rate, 100, 0, INT_MAX, },
+ { "pc_luk_status_def", &battle_config.pc_luk_sc_def, 300, 1, INT_MAX, },
+ { "mob_luk_status_def", &battle_config.mob_luk_sc_def, 300, 1, INT_MAX, },
+ { "pc_max_status_def", &battle_config.pc_max_sc_def, 100, 0, INT_MAX, },
+ { "mob_max_status_def", &battle_config.mob_max_sc_def, 100, 0, INT_MAX, },
+ { "sg_miracle_skill_ratio", &battle_config.sg_miracle_skill_ratio, 1, 0, 10000, },
+ { "sg_angel_skill_ratio", &battle_config.sg_angel_skill_ratio, 10, 0, 10000, },
+ { "autospell_stacking", &battle_config.autospell_stacking, 0, 0, 1, },
+ { "override_mob_names", &battle_config.override_mob_names, 0, 0, 2, },
+ { "min_chat_delay", &battle_config.min_chat_delay, 0, 0, INT_MAX, },
+ { "friend_auto_add", &battle_config.friend_auto_add, 1, 0, 1, },
+ { "hom_rename", &battle_config.hom_rename, 0, 0, 1, },
+ { "homunculus_show_growth", &battle_config.homunculus_show_growth, 0, 0, 1, },
+ { "homunculus_friendly_rate", &battle_config.homunculus_friendly_rate, 100, 0, INT_MAX, },
+ { "vending_tax", &battle_config.vending_tax, 0, 0, 10000, },
+ { "day_duration", &battle_config.day_duration, 0, 0, INT_MAX, },
+ { "night_duration", &battle_config.night_duration, 0, 0, INT_MAX, },
+ { "mob_remove_delay", &battle_config.mob_remove_delay, 60000, 1000, INT_MAX, },
+ { "mob_active_time", &battle_config.mob_active_time, 0, 0, INT_MAX, },
+ { "boss_active_time", &battle_config.boss_active_time, 0, 0, INT_MAX, },
+ { "sg_miracle_skill_duration", &battle_config.sg_miracle_skill_duration, 3600000, 0, INT_MAX, },
+ { "hvan_explosion_intimate", &battle_config.hvan_explosion_intimate, 45000, 0, 100000, },
+ { "quest_exp_rate", &battle_config.quest_exp_rate, 100, 0, INT_MAX, },
+ { "at_mapflag", &battle_config.autotrade_mapflag, 0, 0, 1, },
+ { "at_timeout", &battle_config.at_timeout, 0, 0, INT_MAX, },
+ { "homunculus_autoloot", &battle_config.homunculus_autoloot, 0, 0, 1, },
+ { "idle_no_autoloot", &battle_config.idle_no_autoloot, 0, 0, INT_MAX, },
+ { "max_guild_alliance", &battle_config.max_guild_alliance, 3, 0, 3, },
+ { "ksprotection", &battle_config.ksprotection, 5000, 0, INT_MAX, },
+ { "auction_feeperhour", &battle_config.auction_feeperhour, 12000, 0, INT_MAX, },
+ { "auction_maximumprice", &battle_config.auction_maximumprice, 500000000, 0, MAX_ZENY, },
+ { "homunculus_auto_vapor", &battle_config.homunculus_auto_vapor, 1, 0, 1, },
+ { "display_status_timers", &battle_config.display_status_timers, 1, 0, 1, },
+ { "skill_add_heal_rate", &battle_config.skill_add_heal_rate, 7, 0, INT_MAX, },
+ { "eq_single_target_reflectable", &battle_config.eq_single_target_reflectable, 1, 0, 1, },
+ { "invincible.nodamage", &battle_config.invincible_nodamage, 0, 0, 1, },
+ { "mob_slave_keep_target", &battle_config.mob_slave_keep_target, 0, 0, 1, },
+ { "autospell_check_range", &battle_config.autospell_check_range, 0, 0, 1, },
+ { "client_reshuffle_dice", &battle_config.client_reshuffle_dice, 0, 0, 1, },
+ { "client_sort_storage", &battle_config.client_sort_storage, 0, 0, 1, },
+ { "feature.buying_store", &battle_config.feature_buying_store, 1, 0, 1, },
+ { "feature.search_stores", &battle_config.feature_search_stores, 1, 0, 1, },
+ { "searchstore_querydelay", &battle_config.searchstore_querydelay, 10, 0, INT_MAX, },
+ { "searchstore_maxresults", &battle_config.searchstore_maxresults, 30, 1, INT_MAX, },
+ { "display_party_name", &battle_config.display_party_name, 0, 0, 1, },
+ { "cashshop_show_points", &battle_config.cashshop_show_points, 0, 0, 1, },
+ { "mail_show_status", &battle_config.mail_show_status, 0, 0, 2, },
+ { "client_limit_unit_lv", &battle_config.client_limit_unit_lv, 0, 0, BL_ALL, },
+// BattleGround Settings
+ { "bg_update_interval", &battle_config.bg_update_interval, 1000, 100, INT_MAX, },
+ { "bg_short_attack_damage_rate", &battle_config.bg_short_damage_rate, 80, 0, INT_MAX, },
+ { "bg_long_attack_damage_rate", &battle_config.bg_long_damage_rate, 80, 0, INT_MAX, },
+ { "bg_weapon_attack_damage_rate", &battle_config.bg_weapon_damage_rate, 60, 0, INT_MAX, },
+ { "bg_magic_attack_damage_rate", &battle_config.bg_magic_damage_rate, 60, 0, INT_MAX, },
+ { "bg_misc_attack_damage_rate", &battle_config.bg_misc_damage_rate, 60, 0, INT_MAX, },
+ { "bg_flee_penalty", &battle_config.bg_flee_penalty, 20, 0, INT_MAX, },
+ /**
+ * rAthena
+ **/
+ { "max_third_parameter", &battle_config.max_third_parameter, 120, 10, 10000, },
+ { "max_baby_third_parameter", &battle_config.max_baby_third_parameter, 108, 10, 10000, },
+ { "atcommand_max_stat_bypass", &battle_config.atcommand_max_stat_bypass, 0, 0, 100, },
+ { "skill_amotion_leniency", &battle_config.skill_amotion_leniency, 90, 0, 100 },
+ { "mvp_tomb_enabled", &battle_config.mvp_tomb_enabled, 1, 0, 1 },
+ { "feature.atcommand_suggestions", &battle_config.atcommand_suggestions_enabled, 0, 0, 1 },
+ { "min_npc_vending_distance", &battle_config.min_npc_vending_distance, 3, 0, 100 },
+ { "atcommand_mobinfo_type", &battle_config.atcommand_mobinfo_type, 0, 0, 1 },
+ { "homunculus_max_level", &battle_config.hom_max_level, 99, 0, MAX_LEVEL, },
+ { "homunculus_S_max_level", &battle_config.hom_S_max_level, 150, 0, MAX_LEVEL, },
+ { "mob_size_influence", &battle_config.mob_size_influence, 0, 0, 1, },
};
#ifndef STATS_OPT_OUT
/**
* rAthena anonymous statistic usage report -- packet is built here, and sent to char server to report.
**/
-void rAthena_report(char *date, char *time_c)
-{
- int i, rev = 0, bd_size = ARRAYLENGTH(battle_data);
- unsigned int config = 0;
- const char *rev_str;
- char timestring[25];
- time_t curtime;
- char *buf;
-
- enum config_table {
- C_CIRCULAR_AREA = 0x0001,
- C_CELLNOSTACK = 0x0002,
- C_BETA_THREAD_TEST = 0x0004,
- C_SCRIPT_CALLFUNC_CHECK = 0x0008,
- C_OFFICIAL_WALKPATH = 0x0010,
- C_RENEWAL = 0x0020,
- C_RENEWAL_CAST = 0x0040,
- C_RENEWAL_DROP = 0x0080,
- C_RENEWAL_EXP = 0x0100,
- C_RENEWAL_LVDMG = 0x0200,
- C_RENEWAL_EDP = 0x0400,
- C_RENEWAL_ASPD = 0x0800,
- C_SECURE_NPCTIMEOUT = 0x1000,
- C_SQL_DBS = 0x2000,
- C_SQL_LOGS = 0x4000,
- };
-
- if ((rev_str = get_svn_revision()) != 0)
- rev = atoi(rev_str);
-
- /* we get the current time */
- time(&curtime);
- strftime(timestring, 24, "%Y-%m-%d %H:%M:%S", localtime(&curtime));
+void rAthena_report(char* date, char *time_c) {
+ int i, rev = 0, bd_size = ARRAYLENGTH(battle_data);
+ unsigned int config = 0;
+ const char* rev_str;
+ char timestring[25];
+ time_t curtime;
+ char* buf;
+
+ enum config_table {
+ C_CIRCULAR_AREA = 0x0001,
+ C_CELLNOSTACK = 0x0002,
+ C_BETA_THREAD_TEST = 0x0004,
+ C_SCRIPT_CALLFUNC_CHECK = 0x0008,
+ C_OFFICIAL_WALKPATH = 0x0010,
+ C_RENEWAL = 0x0020,
+ C_RENEWAL_CAST = 0x0040,
+ C_RENEWAL_DROP = 0x0080,
+ C_RENEWAL_EXP = 0x0100,
+ C_RENEWAL_LVDMG = 0x0200,
+ C_RENEWAL_EDP = 0x0400,
+ C_RENEWAL_ASPD = 0x0800,
+ C_SECURE_NPCTIMEOUT = 0x1000,
+ C_SQL_DBS = 0x2000,
+ C_SQL_LOGS = 0x4000,
+ };
+
+ if( (rev_str = get_svn_revision()) != 0 )
+ rev = atoi(rev_str);
+
+ /* we get the current time */
+ time(&curtime);
+ strftime(timestring, 24, "%Y-%m-%d %H:%M:%S", localtime(&curtime));
#ifdef CIRCULAR_AREA
- config |= C_CIRCULAR_AREA;
+ config |= C_CIRCULAR_AREA;
#endif
#ifdef CELL_NOSTACK
- config |= C_CELLNOSTACK;
+ config |= C_CELLNOSTACK;
#endif
#ifdef BETA_THREAD_TEST
- config |= C_BETA_THREAD_TEST;
+ config |= C_BETA_THREAD_TEST;
#endif
#ifdef SCRIPT_CALLFUNC_CHECK
- config |= C_SCRIPT_CALLFUNC_CHECK;
+ config |= C_SCRIPT_CALLFUNC_CHECK;
#endif
#ifdef OFFICIAL_WALKPATH
- config |= C_OFFICIAL_WALKPATH;
+ config |= C_OFFICIAL_WALKPATH;
#endif
#ifdef RENEWAL
- config |= C_RENEWAL;
+ config |= C_RENEWAL;
#endif
#ifdef RENEWAL_CAST
- config |= C_RENEWAL_CAST;
+ config |= C_RENEWAL_CAST;
#endif
#ifdef RENEWAL_DROP
- config |= C_RENEWAL_DROP;
+ config |= C_RENEWAL_DROP;
#endif
#ifdef RENEWAL_EXP
- config |= C_RENEWAL_EXP;
+ config |= C_RENEWAL_EXP;
#endif
#ifdef RENEWAL_LVDMG
- config |= C_RENEWAL_LVDMG;
+ config |= C_RENEWAL_LVDMG;
#endif
#ifdef RENEWAL_EDP
- config |= C_RENEWAL_EDP;
+ config |= C_RENEWAL_EDP;
#endif
#ifdef RENEWAL_ASPD
- config |= C_RENEWAL_ASPD;
+ config |= C_RENEWAL_ASPD;
#endif
- /* not a ifdef because SECURE_NPCTIMEOUT is always defined, but either as 0 or higher */
+/* not a ifdef because SECURE_NPCTIMEOUT is always defined, but either as 0 or higher */
#if SECURE_NPCTIMEOUT
- config |= C_SECURE_NPCTIMEOUT;
+ config |= C_SECURE_NPCTIMEOUT;
#endif
- /* non-define part */
- if (db_use_sqldbs)
- config |= C_SQL_DBS;
+ /* non-define part */
+ if( db_use_sqldbs )
+ config |= C_SQL_DBS;
- if (log_config.sql_logs)
- config |= C_SQL_LOGS;
+ if( log_config.sql_logs )
+ config |= C_SQL_LOGS;
#define BFLAG_LENGTH 35
- CREATE(buf, char, 6 + 12 + 9 + 24 + 4 + 4 + 4 + 4 + (bd_size * (BFLAG_LENGTH + 4)) + 1);
+ CREATE(buf, char, 6 + 12 + 9 + 24 + 4 + 4 + 4 + 4 + ( bd_size * ( BFLAG_LENGTH + 4 ) ) + 1 );
- /* build packet */
+ /* build packet */
- WBUFW(buf,0) = 0x3000;
- WBUFW(buf,2) = 6 + 12 + 9 + 24 + 4 + 4 + 4 + 4 + (bd_size * (BFLAG_LENGTH + 4));
- WBUFW(buf,4) = 0x9c;
+ WBUFW(buf,0) = 0x3000;
+ WBUFW(buf,2) = 6 + 12 + 9 + 24 + 4 + 4 + 4 + 4 + ( bd_size * ( BFLAG_LENGTH + 4 ) );
+ WBUFW(buf,4) = 0x9c;
- safestrncpy((char *)WBUFP(buf,6), date, 12);
- safestrncpy((char *)WBUFP(buf,6 + 12), time_c, 9);
- safestrncpy((char *)WBUFP(buf,6 + 12 + 9), timestring, 24);
+ safestrncpy((char*)WBUFP(buf,6), date, 12);
+ safestrncpy((char*)WBUFP(buf,6 + 12), time_c, 9);
+ safestrncpy((char*)WBUFP(buf,6 + 12 + 9), timestring, 24);
- WBUFL(buf,6 + 12 + 9 + 24) = rev;
- WBUFL(buf,6 + 12 + 9 + 24 + 4) = map_getusers();
+ WBUFL(buf,6 + 12 + 9 + 24) = rev;
+ WBUFL(buf,6 + 12 + 9 + 24 + 4) = map_getusers();
- WBUFL(buf,6 + 12 + 9 + 24 + 4 + 4) = config;
- WBUFL(buf,6 + 12 + 9 + 24 + 4 + 4 + 4) = bd_size;
+ WBUFL(buf,6 + 12 + 9 + 24 + 4 + 4) = config;
+ WBUFL(buf,6 + 12 + 9 + 24 + 4 + 4 + 4) = bd_size;
- for (i = 0; i < bd_size; i++) {
- safestrncpy((char *)WBUFP(buf,6 + 12 + 9+ 24 + 4 + 4 + 4 + 4 + (i * (BFLAG_LENGTH + 4))), battle_data[i].str, 35);
- WBUFL(buf,6 + 12 + 9 + 24 + 4 + 4 + 4 + 4 + BFLAG_LENGTH + (i * (BFLAG_LENGTH + 4))) = *battle_data[i].val;
- }
+ for( i = 0; i < bd_size; i++ ) {
+ safestrncpy((char*)WBUFP(buf,6 + 12 + 9+ 24 + 4 + 4 + 4 + 4 + ( i * ( BFLAG_LENGTH + 4 ) ) ), battle_data[i].str, 35);
+ WBUFL(buf,6 + 12 + 9 + 24 + 4 + 4 + 4 + 4 + BFLAG_LENGTH + ( i * ( BFLAG_LENGTH + 4 ) ) ) = *battle_data[i].val;
+ }
- chrif_send_report(buf, 6 + 12 + 9 + 24 + 4 + 4 + 4 + 4 + (bd_size * (BFLAG_LENGTH + 4)));
+ chrif_send_report(buf, 6 + 12 + 9 + 24 + 4 + 4 + 4 + 4 + ( bd_size * ( BFLAG_LENGTH + 4 ) ) );
- aFree(buf);
+ aFree(buf);
#undef BFLAG_LENGTH
}
-static int rAthena_report_timer(int tid, unsigned int tick, int id, intptr_t data)
-{
- if (chrif_isconnected()) { /* char server relays it, so it must be online. */
- rAthena_report(__DATE__,__TIME__);
- }
- return 0;
+static int rAthena_report_timer(int tid, unsigned int tick, int id, intptr_t data) {
+ if( chrif_isconnected() ) {/* char server relays it, so it must be online. */
+ rAthena_report(__DATE__,__TIME__);
+ }
+ return 0;
}
#endif
-int battle_set_value(const char *w1, const char *w2)
+int battle_set_value(const char* w1, const char* w2)
{
- int val = config_switch(w2);
-
- int i;
- ARR_FIND(0, ARRAYLENGTH(battle_data), i, strcmpi(w1, battle_data[i].str) == 0);
- if (i == ARRAYLENGTH(battle_data))
- return 0; // not found
+ int val = config_switch(w2);
- if (val < battle_data[i].min || val > battle_data[i].max) {
- ShowWarning("Value for setting '%s': %s is invalid (min:%i max:%i)! Defaulting to %i...\n", w1, w2, battle_data[i].min, battle_data[i].max, battle_data[i].defval);
- val = battle_data[i].defval;
- }
+ int i;
+ ARR_FIND(0, ARRAYLENGTH(battle_data), i, strcmpi(w1, battle_data[i].str) == 0);
+ if (i == ARRAYLENGTH(battle_data))
+ return 0; // not found
+
+ if (val < battle_data[i].min || val > battle_data[i].max)
+ {
+ ShowWarning("Value for setting '%s': %s is invalid (min:%i max:%i)! Defaulting to %i...\n", w1, w2, battle_data[i].min, battle_data[i].max, battle_data[i].defval);
+ val = battle_data[i].defval;
+ }
- *battle_data[i].val = val;
- return 1;
+ *battle_data[i].val = val;
+ return 1;
}
-int battle_get_value(const char *w1)
+int battle_get_value(const char* w1)
{
- int i;
- ARR_FIND(0, ARRAYLENGTH(battle_data), i, strcmpi(w1, battle_data[i].str) == 0);
- if (i == ARRAYLENGTH(battle_data))
- return 0; // not found
- else
- return *battle_data[i].val;
+ int i;
+ ARR_FIND(0, ARRAYLENGTH(battle_data), i, strcmpi(w1, battle_data[i].str) == 0);
+ if (i == ARRAYLENGTH(battle_data))
+ return 0; // not found
+ else
+ return *battle_data[i].val;
}
void battle_set_defaults()
{
- int i;
- for (i = 0; i < ARRAYLENGTH(battle_data); i++)
- *battle_data[i].val = battle_data[i].defval;
+ int i;
+ for (i = 0; i < ARRAYLENGTH(battle_data); i++)
+ *battle_data[i].val = battle_data[i].defval;
}
void battle_adjust_conf()
{
- battle_config.monster_max_aspd = 2000 - battle_config.monster_max_aspd*10;
- battle_config.max_aspd = 2000 - battle_config.max_aspd*10;
- battle_config.max_third_aspd = 2000 - battle_config.max_third_aspd*10;
- battle_config.max_walk_speed = 100*DEFAULT_WALK_SPEED/battle_config.max_walk_speed;
- battle_config.max_cart_weight *= 10;
+ battle_config.monster_max_aspd = 2000 - battle_config.monster_max_aspd*10;
+ battle_config.max_aspd = 2000 - battle_config.max_aspd*10;
+ battle_config.max_third_aspd = 2000 - battle_config.max_third_aspd*10;
+ battle_config.max_walk_speed = 100*DEFAULT_WALK_SPEED/battle_config.max_walk_speed;
+ battle_config.max_cart_weight *= 10;
- if (battle_config.max_def > 100 && !battle_config.weapon_defense_type) // added by [Skotlex]
- battle_config.max_def = 100;
+ if(battle_config.max_def > 100 && !battle_config.weapon_defense_type) // added by [Skotlex]
+ battle_config.max_def = 100;
- if (battle_config.min_hitrate > battle_config.max_hitrate)
- battle_config.min_hitrate = battle_config.max_hitrate;
+ if(battle_config.min_hitrate > battle_config.max_hitrate)
+ battle_config.min_hitrate = battle_config.max_hitrate;
- if (battle_config.pet_max_atk1 > battle_config.pet_max_atk2) //Skotlex
- battle_config.pet_max_atk1 = battle_config.pet_max_atk2;
+ if(battle_config.pet_max_atk1 > battle_config.pet_max_atk2) //Skotlex
+ battle_config.pet_max_atk1 = battle_config.pet_max_atk2;
- if (battle_config.day_duration && battle_config.day_duration < 60000) // added by [Yor]
- battle_config.day_duration = 60000;
- if (battle_config.night_duration && battle_config.night_duration < 60000) // added by [Yor]
- battle_config.night_duration = 60000;
+ if (battle_config.day_duration && battle_config.day_duration < 60000) // added by [Yor]
+ battle_config.day_duration = 60000;
+ if (battle_config.night_duration && battle_config.night_duration < 60000) // added by [Yor]
+ battle_config.night_duration = 60000;
#if PACKETVER < 20100427
- if (battle_config.feature_buying_store) {
- ShowWarning("conf/battle/feature.conf buying_store is enabled but it requires PACKETVER 2010-04-27 or newer, disabling...\n");
- battle_config.feature_buying_store = 0;
- }
+ if( battle_config.feature_buying_store ) {
+ ShowWarning("conf/battle/feature.conf buying_store is enabled but it requires PACKETVER 2010-04-27 or newer, disabling...\n");
+ battle_config.feature_buying_store = 0;
+ }
#endif
#if PACKETVER < 20100803
- if (battle_config.feature_search_stores) {
- ShowWarning("conf/battle/feature.conf search_stores is enabled but it requires PACKETVER 2010-08-03 or newer, disabling...\n");
- battle_config.feature_search_stores = 0;
- }
+ if( battle_config.feature_search_stores ) {
+ ShowWarning("conf/battle/feature.conf search_stores is enabled but it requires PACKETVER 2010-08-03 or newer, disabling...\n");
+ battle_config.feature_search_stores = 0;
+ }
#endif
#ifndef CELL_NOSTACK
- if (battle_config.cell_stack_limit != 1)
- ShowWarning("Battle setting 'cell_stack_limit' takes no effect as this server was compiled without Cell Stack Limit support.\n");
+ if (battle_config.cell_stack_limit != 1)
+ ShowWarning("Battle setting 'cell_stack_limit' takes no effect as this server was compiled without Cell Stack Limit support.\n");
#endif
}
-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)
- battle_set_defaults();
-
- count++;
-
- fp = fopen(cfgName,"r");
- if (fp == NULL)
- ShowError("File not found: %s\n", cfgName);
- else {
- while (fgets(line, sizeof(line), fp)) {
- if (line[0] == '/' && line[1] == '/')
- continue;
- if (sscanf(line, "%1023[^:]:%1023s", w1, w2) != 2)
- continue;
- if (strcmpi(w1, "import") == 0)
- battle_config_read(w2);
- else if (battle_set_value(w1, w2) == 0)
- ShowWarning("Unknown setting '%s' in file %s\n", w1, cfgName);
- }
+ char line[1024], w1[1024], w2[1024];
+ FILE* fp;
+ static int count = 0;
+
+ if (count == 0)
+ battle_set_defaults();
+
+ count++;
+
+ fp = fopen(cfgName,"r");
+ if (fp == NULL)
+ ShowError("File not found: %s\n", cfgName);
+ else
+ {
+ while(fgets(line, sizeof(line), fp))
+ {
+ if (line[0] == '/' && line[1] == '/')
+ continue;
+ if (sscanf(line, "%1023[^:]:%1023s", w1, w2) != 2)
+ continue;
+ if (strcmpi(w1, "import") == 0)
+ battle_config_read(w2);
+ else
+ if (battle_set_value(w1, w2) == 0)
+ ShowWarning("Unknown setting '%s' in file %s\n", w1, cfgName);
+ }
- fclose(fp);
- }
+ fclose(fp);
+ }
- count--;
+ count--;
- if (count == 0)
- battle_adjust_conf();
+ if (count == 0)
+ battle_adjust_conf();
- return 0;
+ return 0;
}
void do_init_battle(void)
{
- delay_damage_ers = ers_new(sizeof(struct delay_damage),"battle.c::delay_damage_ers",ERS_OPT_CLEAR);
- add_timer_func_list(battle_delay_damage_sub, "battle_delay_damage_sub");
+ delay_damage_ers = ers_new(sizeof(struct delay_damage),"battle.c::delay_damage_ers",ERS_OPT_CLEAR);
+ add_timer_func_list(battle_delay_damage_sub, "battle_delay_damage_sub");
#ifndef STATS_OPT_OUT
- add_timer_func_list(rAthena_report_timer, "rAthena_report_timer");
- add_timer_interval(gettick()+30000, rAthena_report_timer, 0, 0, 60000 * 30);
+ add_timer_func_list(rAthena_report_timer, "rAthena_report_timer");
+ add_timer_interval(gettick()+30000, rAthena_report_timer, 0, 0, 60000 * 30);
#endif
}
void do_final_battle(void)
{
- ers_destroy(delay_damage_ers);
+ ers_destroy(delay_damage_ers);
}
diff --git a/src/map/battle.h b/src/map/battle.h
index 17d7bd28e..b901644de 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -6,22 +6,22 @@
// state of a single attack attempt; used in flee/def penalty calculations when mobbed
typedef enum damage_lv {
- ATK_NONE, // not an attack
- ATK_LUCKY, // attack was lucky-dodged
- ATK_FLEE, // attack was dodged
- ATK_MISS, // attack missed because of element/race modifier.
- ATK_BLOCK, // attack was blocked by some skills.
- ATK_DEF // attack connected
+ ATK_NONE, // not an attack
+ ATK_LUCKY, // attack was lucky-dodged
+ ATK_FLEE, // attack was dodged
+ ATK_MISS, // attack missed because of element/race modifier.
+ ATK_BLOCK, // attack was blocked by some skills.
+ ATK_DEF // attack connected
} damage_lv;
// dammage structure
struct Damage {
- int damage,damage2; //right, left dmg
- int type,div_; //chk clif_damage for type @TODO add an enum ? ; nb of hit
- int amotion,dmotion;
- int blewcount; //nb of knockback
- int flag; //chk BF_* flag, (enum below)
- enum damage_lv dmg_lv; //ATK_LUCKY,ATK_FLEE,ATK_DEF
+ int damage,damage2; //right, left dmg
+ int type,div_; //chk clif_damage for type @TODO add an enum ? ; nb of hit
+ int amotion,dmotion;
+ int blewcount; //nb of knockback
+ int flag; //chk BF_* flag, (enum below)
+ enum damage_lv dmg_lv; //ATK_LUCKY,ATK_FLEE,ATK_DEF
};
//(Used in read pc.c,) attribute table (battle_attr_fix)
@@ -41,59 +41,58 @@ void battle_drain(struct map_session_data *sd, struct block_list *tbl, int rdama
int battle_attr_ratio(int atk_elem,int def_type, int def_lv);
int battle_attr_fix(struct block_list *src, struct block_list *target, int damage,int atk_elem,int def_type, int def_lv);
-int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_list *target, int nk, int s_ele, int s_ele_, int damage, int left, int flag);
// Final calculation Damage
int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damage *d,int damage,int skill_num,int skill_lv);
int battle_calc_gvg_damage(struct block_list *src,struct block_list *bl,int damage,int div_,int skill_num,int skill_lv,int flag);
int battle_calc_bg_damage(struct block_list *src,struct block_list *bl,int damage,int div_,int skill_num,int skill_lv,int flag);
-enum { // Flag of the final calculation
- BF_WEAPON = 0x0001,
- BF_MAGIC = 0x0002,
- BF_MISC = 0x0004,
- BF_SHORT = 0x0010,
- BF_LONG = 0x0040,
- BF_SKILL = 0x0100,
- BF_NORMAL = 0x0200,
- BF_WEAPONMASK=0x000f,
- BF_RANGEMASK= 0x00f0,
- BF_SKILLMASK= 0x0f00,
+enum { // Flag of the final calculation
+ BF_WEAPON = 0x0001,
+ BF_MAGIC = 0x0002,
+ BF_MISC = 0x0004,
+ BF_SHORT = 0x0010,
+ BF_LONG = 0x0040,
+ BF_SKILL = 0x0100,
+ BF_NORMAL = 0x0200,
+ BF_WEAPONMASK=0x000f,
+ BF_RANGEMASK= 0x00f0,
+ BF_SKILLMASK= 0x0f00,
};
-int battle_delay_damage(unsigned int tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, int skill_id, int skill_lv, int damage, enum damage_lv dmg_lv, int ddelay);
+int battle_delay_damage (unsigned int tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, int skill_id, int skill_lv, int damage, enum damage_lv dmg_lv, int ddelay);
// Summary normal attack treatment (basic attack)
-enum damage_lv battle_weapon_attack(struct block_list *bl,struct block_list *target,unsigned int tick,int flag);
+enum damage_lv battle_weapon_attack( struct block_list *bl,struct block_list *target,unsigned int tick,int flag);
// Accessors
-struct block_list *battle_get_master(struct block_list *src);
-struct block_list *battle_gettargeted(struct block_list *target);
-struct block_list *battle_getenemy(struct block_list *target, int type, int range);
+struct block_list* battle_get_master(struct block_list *src);
+struct block_list* battle_gettargeted(struct block_list *target);
+struct block_list* battle_getenemy(struct block_list *target, int type, int range);
int battle_gettarget(struct block_list *bl);
int battle_getcurrentskill(struct block_list *bl);
-enum e_battle_check_target {
- //New definitions [Skotlex]
- BCT_ENEMY = 0x020000,
- BCT_NOENEMY = 0x1d0000, //This should be (~BCT_ENEMY&BCT_ALL)
- BCT_PARTY = 0x040000,
- BCT_NOPARTY = 0x1b0000, //This should be (~BCT_PARTY&BCT_ALL)
- BCT_GUILD = 0x080000,
- BCT_NOGUILD = 0x170000, //This should be (~BCT_GUILD&BCT_ALL)
- BCT_ALL = 0x1f0000,
- BCT_NOONE = 0x000000,
- BCT_SELF = 0x010000,
- BCT_NEUTRAL = 0x100000,
+enum e_battle_check_target
+{//New definitions [Skotlex]
+ BCT_ENEMY = 0x020000,
+ BCT_NOENEMY = 0x1d0000, //This should be (~BCT_ENEMY&BCT_ALL)
+ BCT_PARTY = 0x040000,
+ BCT_NOPARTY = 0x1b0000, //This should be (~BCT_PARTY&BCT_ALL)
+ BCT_GUILD = 0x080000,
+ BCT_NOGUILD = 0x170000, //This should be (~BCT_GUILD&BCT_ALL)
+ BCT_ALL = 0x1f0000,
+ BCT_NOONE = 0x000000,
+ BCT_SELF = 0x010000,
+ BCT_NEUTRAL = 0x100000,
};
-#define is_boss(bl) (status_get_mode(bl)&MD_BOSS) // Can refine later [Aru]
+#define is_boss(bl) (status_get_mode(bl)&MD_BOSS) // Can refine later [Aru]
int battle_check_undead(int race,int element);
int battle_check_target(struct block_list *src, struct block_list *target,int flag);
bool battle_check_range(struct block_list *src,struct block_list *bl,int range);
-void battle_consume_ammo(struct map_session_data *sd, int skill, int lv);
+void battle_consume_ammo(struct map_session_data* sd, int skill, int lv);
// Settings
#define MIN_HAIR_STYLE battle_config.min_hair_style
@@ -103,385 +102,386 @@ void battle_consume_ammo(struct map_session_data *sd, int skill, int lv);
#define MIN_CLOTH_COLOR battle_config.min_cloth_color
#define MAX_CLOTH_COLOR battle_config.max_cloth_color
-extern struct Battle_Config {
- int warp_point_debug;
- int enable_critical;
- int mob_critical_rate;
- int critical_rate;
- int enable_baseatk;
- int enable_perfect_flee;
- int cast_rate, delay_rate;
- int delay_dependon_dex, delay_dependon_agi;
- int sdelay_attack_enable;
- int left_cardfix_to_right;
- int skill_add_range;
- int skill_out_range_consume;
- int skill_amotion_leniency;
- int skillrange_by_distance; //[Skotlex]
- int use_weapon_skill_range; //[Skotlex]
- int pc_damage_delay_rate;
- int defnotenemy;
- int vs_traps_bctall;
- int traps_setting;
- int summon_flora; //[Skotlex]
- int clear_unit_ondeath; //[Skotlex]
- int clear_unit_onwarp; //[Skotlex]
- int random_monster_checklv;
- int attr_recover;
- int item_auto_get;
- int flooritem_lifetime;
- int item_first_get_time;
- int item_second_get_time;
- int item_third_get_time;
- int mvp_item_first_get_time;
- int mvp_item_second_get_time;
- int mvp_item_third_get_time;
- int base_exp_rate,job_exp_rate;
- int drop_rate0item;
- int death_penalty_type;
- int death_penalty_base,death_penalty_job;
- int pvp_exp; // [MouseJstr]
- int gtb_sc_immunity;
- int zeny_penalty;
- int restart_hp_rate;
- int restart_sp_rate;
- int mvp_exp_rate;
- int mvp_hp_rate;
- int monster_hp_rate;
- int monster_max_aspd;
- int view_range_rate;
- int chase_range_rate;
- int atc_spawn_quantity_limit;
- int atc_slave_clone_limit;
- int partial_name_scan;
- int skillfree;
- int skillup_limit;
- int wp_rate;
- int pp_rate;
- int monster_active_enable;
- int monster_damage_delay_rate;
- int monster_loot_type;
- int mob_skill_rate; //[Skotlex]
- int mob_skill_delay; //[Skotlex]
- int mob_count_rate;
- int no_spawn_on_player; //[Skotlex]
- int force_random_spawn; //[Skotlex]
- int mob_spawn_delay, plant_spawn_delay, boss_spawn_delay; // [Skotlex]
- int slaves_inherit_mode;
- int slaves_inherit_speed;
- int summons_trigger_autospells;
- int pc_walk_delay_rate; //Adjusts can't walk delay after being hit for players. [Skotlex]
- int walk_delay_rate; //Adjusts can't walk delay after being hit. [Skotlex]
- int multihit_delay; //Adjusts can't walk delay per hit on multi-hitting skills. [Skotlex]
- int quest_skill_learn;
- int quest_skill_reset;
- int basic_skill_check;
- int guild_emperium_check;
- int guild_exp_limit;
- int guild_max_castles;
- int guild_skill_relog_delay;
- int emergency_call;
- int guild_aura;
- int pc_invincible_time;
-
- int pet_catch_rate;
- int pet_rename;
- int pet_friendly_rate;
- int pet_hungry_delay_rate;
- int pet_hungry_friendly_decrease;
- int pet_status_support;
- int pet_attack_support;
- int pet_damage_support;
- int pet_support_min_friendly; //[Skotlex]
- int pet_equip_min_friendly;
- int pet_support_rate;
- int pet_attack_exp_to_master;
- int pet_attack_exp_rate;
- int pet_lv_rate; //[Skotlex]
- int pet_max_stats; //[Skotlex]
- int pet_max_atk1; //[Skotlex]
- int pet_max_atk2; //[Skotlex]
- int pet_no_gvg; //Disables pets in gvg. [Skotlex]
- int pet_equip_required;
-
- int skill_min_damage;
- int finger_offensive_type;
- int heal_exp;
- int max_heal_lv;
- int max_heal; //Mitternacht
- int resurrection_exp;
- int shop_exp;
- int combo_delay_rate;
- int item_check;
- int item_use_interval; //[Skotlex]
- int cashfood_use_interval;
- int wedding_modifydisplay;
- int wedding_ignorepalette; //[Skotlex]
- int xmas_ignorepalette; // [Valaris]
- int summer_ignorepalette; // [Zephyrus]
- int natural_healhp_interval;
- int natural_healsp_interval;
- int natural_heal_skill_interval;
- int natural_heal_weight_rate;
- int arrow_decrement;
- int max_aspd;
- int max_walk_speed; //Maximum walking speed after buffs [Skotlex]
- int max_hp;
- int max_sp;
- int max_lv, aura_lv;
- int max_parameter, max_baby_parameter;
- int max_cart_weight;
- int skill_log;
- int battle_log;
- int etc_log;
- int save_clothcolor;
- int undead_detect_type;
- int auto_counter_type;
- int min_hitrate; //[Skotlex]
- int max_hitrate; //[Skotlex]
- int agi_penalty_target;
- int agi_penalty_type;
- int agi_penalty_count;
- int agi_penalty_num;
- int vit_penalty_target;
- int vit_penalty_type;
- int vit_penalty_count;
- int vit_penalty_num;
- int weapon_defense_type;
- int magic_defense_type;
- int skill_reiteration;
- int skill_nofootset;
- int pc_cloak_check_type;
- int monster_cloak_check_type;
- int estimation_type;
- int gvg_short_damage_rate;
- int gvg_long_damage_rate;
- int gvg_weapon_damage_rate;
- int gvg_magic_damage_rate;
- int gvg_misc_damage_rate;
- int gvg_flee_penalty;
- int pk_short_damage_rate;
- int pk_long_damage_rate;
- int pk_weapon_damage_rate;
- int pk_magic_damage_rate;
- int pk_misc_damage_rate;
- int mob_changetarget_byskill;
- int attack_direction_change;
- int land_skill_limit;
- int monster_class_change_recover;
- int produce_item_name_input;
- int display_skill_fail;
- int chat_warpportal;
- int mob_warp;
- int dead_branch_active;
- int vending_max_value;
- int vending_over_max;
- int vending_tax;
- int show_steal_in_same_party;
- int party_share_type;
- int party_hp_mode;
- int party_show_share_picker;
- int show_picker_item_type;
- int attack_attr_none;
- int item_rate_mvp, item_rate_common, item_rate_common_boss, item_rate_card, item_rate_card_boss,
- item_rate_equip, item_rate_equip_boss, item_rate_heal, item_rate_heal_boss, item_rate_use,
- item_rate_use_boss, item_rate_treasure, item_rate_adddrop;
-
- int logarithmic_drops;
- int item_drop_common_min,item_drop_common_max; // Added by TyrNemesis^
- int item_drop_card_min,item_drop_card_max;
- int item_drop_equip_min,item_drop_equip_max;
- int item_drop_mvp_min,item_drop_mvp_max; // End Addition
- int item_drop_heal_min,item_drop_heal_max; // Added by Valatris
- int item_drop_use_min,item_drop_use_max; //End
- int item_drop_treasure_min,item_drop_treasure_max; //by [Skotlex]
- int item_drop_adddrop_min,item_drop_adddrop_max; //[Skotlex]
-
- int prevent_logout; // Added by RoVeRT
-
- int alchemist_summon_reward; // [Valaris]
- int drops_by_luk;
- int drops_by_luk2;
- int equip_natural_break_rate; //Base Natural break rate for attacks.
- int equip_self_break_rate; //Natural & Penalty skills break rate
- int equip_skill_break_rate; //Offensive skills break rate
- int multi_level_up;
- int max_exp_gain_rate; //Max amount of exp bar % you can get in one go.
- int pk_mode;
- int pk_level_range;
-
- int manner_system; // end additions [Valaris]
- int show_mob_info;
-
- int gx_allhit;
- int gx_disptype;
- int devotion_level_difference;
- int player_skill_partner_check;
- int invite_request_check;
- int skill_removetrap_type;
- int disp_experience;
- int disp_zeny;
- int castle_defense_rate;
- int backstab_bow_penalty;
- int hp_rate;
- int sp_rate;
- int bone_drop;
- int buyer_name;
- int dancing_weaponswitch_fix;
-
- // eAthena additions
- int night_at_start; // added by [Yor]
- int day_duration; // added by [Yor]
- int night_duration; // added by [Yor]
- int ban_hack_trade; // added by [Yor]
- int packet_ver_flag; // added by [Yor]
-
- int min_hair_style; // added by [MouseJstr]
- int max_hair_style; // added by [MouseJstr]
- int min_hair_color; // added by [MouseJstr]
- int max_hair_color; // added by [MouseJstr]
- int min_cloth_color; // added by [MouseJstr]
- int max_cloth_color; // added by [MouseJstr]
- int pet_hair_style; // added by [Skotlex]
-
- int castrate_dex_scale; // added by [MouseJstr]
- int area_size; // added by [MouseJstr]
-
- int max_def, over_def_bonus; //added by [Skotlex]
-
- int zeny_from_mobs; // [Valaris]
- int mobs_level_up; // [Valaris]
- int mobs_level_up_exp_rate; // [Valaris]
- int pk_min_level; // [celest]
- int skill_steal_max_tries; //max steal skill tries on a mob. if 0, then w/o limit [Lupus]
- int motd_type; // [celest]
- int finding_ore_rate; // orn
- int exp_calc_type;
- int exp_bonus_attacker;
- int exp_bonus_max_attacker;
- int min_skill_delay_limit;
- int default_walk_delay;
- int no_skill_delay;
- int attack_walk_delay;
- int require_glory_guild;
- int idle_no_share;
- int party_update_interval;
- int party_even_share_bonus;
- int delay_battle_damage;
- int hide_woe_damage;
- int display_version;
-
- int display_hallucination; // [Skotlex]
- int use_statpoint_table; // [Skotlex]
-
- int ignore_items_gender; //[Lupus]
-
- int copyskill_restrict; // [Aru]
- int berserk_cancels_buffs; // [Aru]
- int debuff_on_logout; // Removes a few "official" negative Scs on logout. [Skotlex]
- int mob_ai; //Configures various mob_ai settings to make them smarter or dumber(official). [Skotlex]
- int hom_setting; //Configures various homunc settings which make them behave unlike normal characters.. [Skotlex]
- int dynamic_mobs; // Dynamic Mobs [Wizputer] - battle_athena flag implemented by [random]
- int mob_remove_damaged; // Dynamic Mobs - Remove mobs even if damaged [Wizputer]
- int mob_remove_delay; // Dynamic Mobs - delay before removing mobs from a map [Skotlex]
- int mob_active_time; //Duration through which mobs execute their Hard AI after players leave their area of sight.
- int boss_active_time;
-
- int show_hp_sp_drain, show_hp_sp_gain; //[Skotlex]
-
- int mob_npc_event_type; //Determines on who the npc_event is executed. [Skotlex]
-
- int character_size; // if riders have size=2, and baby class riders size=1 [Lupus]
- int mob_max_skilllvl; // Max possible skill level [Lupus]
- int rare_drop_announce; // chance <= to show rare drops global announces
-
- int retaliate_to_master; //Whether when a mob is attacked by another mob, it will retaliate versus the mob or the mob's master. [Skotlex]
-
- int duel_allow_pvp; // [LuzZza]
- int duel_allow_gvg; // [LuzZza]
- int duel_allow_teleport; // [LuzZza]
- int duel_autoleave_when_die; // [LuzZza]
- int duel_time_interval; // [LuzZza]
- int duel_only_on_same_map; // [Toms]
-
- int skip_teleport_lv1_menu; // possibility to disable (skip) Teleport Lv1 menu, that have only two lines `Random` and `Cancel` [LuzZza]
-
- int allow_skill_without_day; // [Komurka]
- int allow_es_magic_pc; // [Skotlex]
- int skill_wall_check; // [Skotlex]
- int cell_stack_limit; // [Skotlex]
- int skill_caster_check; // [Skotlex]
- int sc_castcancel; // [Skotlex]
- int pc_sc_def_rate; // [Skotlex]
- int mob_sc_def_rate;
- int pc_luk_sc_def;
- int mob_luk_sc_def;
- int pc_max_sc_def;
- int mob_max_sc_def;
-
- int sg_angel_skill_ratio;
- int sg_miracle_skill_ratio;
- int sg_miracle_skill_duration;
- int autospell_stacking; //Enables autospell cards to stack. [Skotlex]
- int override_mob_names; //Enables overriding spawn mob names with the mob_db names. [Skotlex]
- int min_chat_delay; //Minimum time between client messages. [Skotlex]
- int friend_auto_add; //When accepting friends, both get friended. [Skotlex]
- int hvan_explosion_intimate; // fix [albator]
- int hom_rename;
- int homunculus_show_growth ; //[orn]
- int homunculus_friendly_rate;
- int quest_exp_rate;
- int autotrade_mapflag;
- int at_timeout;
- int homunculus_autoloot;
- int idle_no_autoloot;
- int max_guild_alliance;
- int ksprotection;
- int auction_feeperhour;
- int auction_maximumprice;
- int homunculus_auto_vapor; //Keep Homunculus from Vaporizing when master dies. [L0ne_W0lf]
- int display_status_timers; //Show or hide skill buff/delay timers in recent clients [Sara]
- int skill_add_heal_rate; //skills that bHealPower has effect on [Inkfish]
- int eq_single_target_reflectable;
- int invincible_nodamage;
- int mob_slave_keep_target;
- int autospell_check_range; //Enable range check for autospell bonus. [L0ne_W0lf]
- int client_reshuffle_dice; // Reshuffle /dice
- int client_sort_storage;
- int feature_buying_store;
- int feature_search_stores;
- int searchstore_querydelay;
- int searchstore_maxresults;
- int display_party_name;
- int cashshop_show_points;
- int mail_show_status;
- int client_limit_unit_lv;
- int hom_max_level;
- int hom_S_max_level;
-
- // [BattleGround Settings]
- int bg_update_interval;
- int bg_short_damage_rate;
- int bg_long_damage_rate;
- int bg_weapon_damage_rate;
- int bg_magic_damage_rate;
- int bg_misc_damage_rate;
- int bg_flee_penalty;
-
- // rAthena
- int max_third_parameter;
- int max_baby_third_parameter;
- int atcommand_max_stat_bypass;
- int max_third_aspd;
- int vcast_stat_scale;
-
- int mvp_tomb_enabled;
-
- int atcommand_suggestions_enabled;
+extern struct Battle_Config
+{
+ int warp_point_debug;
+ int enable_critical;
+ int mob_critical_rate;
+ int critical_rate;
+ int enable_baseatk;
+ int enable_perfect_flee;
+ int cast_rate, delay_rate;
+ int delay_dependon_dex, delay_dependon_agi;
+ int sdelay_attack_enable;
+ int left_cardfix_to_right;
+ int skill_add_range;
+ int skill_out_range_consume;
+ int skill_amotion_leniency;
+ int skillrange_by_distance; //[Skotlex]
+ int use_weapon_skill_range; //[Skotlex]
+ int pc_damage_delay_rate;
+ int defnotenemy;
+ int vs_traps_bctall;
+ int traps_setting;
+ int summon_flora; //[Skotlex]
+ int clear_unit_ondeath; //[Skotlex]
+ int clear_unit_onwarp; //[Skotlex]
+ int random_monster_checklv;
+ int attr_recover;
+ int item_auto_get;
+ int flooritem_lifetime;
+ int item_first_get_time;
+ int item_second_get_time;
+ int item_third_get_time;
+ int mvp_item_first_get_time;
+ int mvp_item_second_get_time;
+ int mvp_item_third_get_time;
+ int base_exp_rate,job_exp_rate;
+ int drop_rate0item;
+ int death_penalty_type;
+ int death_penalty_base,death_penalty_job;
+ int pvp_exp; // [MouseJstr]
+ int gtb_sc_immunity;
+ int zeny_penalty;
+ int restart_hp_rate;
+ int restart_sp_rate;
+ int mvp_exp_rate;
+ int mvp_hp_rate;
+ int monster_hp_rate;
+ int monster_max_aspd;
+ int view_range_rate;
+ int chase_range_rate;
+ int atc_spawn_quantity_limit;
+ int atc_slave_clone_limit;
+ int partial_name_scan;
+ int skillfree;
+ int skillup_limit;
+ int wp_rate;
+ int pp_rate;
+ int monster_active_enable;
+ int monster_damage_delay_rate;
+ int monster_loot_type;
+ int mob_skill_rate; //[Skotlex]
+ int mob_skill_delay; //[Skotlex]
+ int mob_count_rate;
+ int no_spawn_on_player; //[Skotlex]
+ int force_random_spawn; //[Skotlex]
+ int mob_spawn_delay, plant_spawn_delay, boss_spawn_delay; // [Skotlex]
+ int slaves_inherit_mode;
+ int slaves_inherit_speed;
+ int summons_trigger_autospells;
+ int pc_walk_delay_rate; //Adjusts can't walk delay after being hit for players. [Skotlex]
+ int walk_delay_rate; //Adjusts can't walk delay after being hit. [Skotlex]
+ int multihit_delay; //Adjusts can't walk delay per hit on multi-hitting skills. [Skotlex]
+ int quest_skill_learn;
+ int quest_skill_reset;
+ int basic_skill_check;
+ int guild_emperium_check;
+ int guild_exp_limit;
+ int guild_max_castles;
+ int guild_skill_relog_delay;
+ int emergency_call;
+ int guild_aura;
+ int pc_invincible_time;
+
+ int pet_catch_rate;
+ int pet_rename;
+ int pet_friendly_rate;
+ int pet_hungry_delay_rate;
+ int pet_hungry_friendly_decrease;
+ int pet_status_support;
+ int pet_attack_support;
+ int pet_damage_support;
+ int pet_support_min_friendly; //[Skotlex]
+ int pet_equip_min_friendly;
+ int pet_support_rate;
+ int pet_attack_exp_to_master;
+ int pet_attack_exp_rate;
+ int pet_lv_rate; //[Skotlex]
+ int pet_max_stats; //[Skotlex]
+ int pet_max_atk1; //[Skotlex]
+ int pet_max_atk2; //[Skotlex]
+ int pet_no_gvg; //Disables pets in gvg. [Skotlex]
+ int pet_equip_required;
+
+ int skill_min_damage;
+ int finger_offensive_type;
+ int heal_exp;
+ int max_heal_lv;
+ int max_heal; //Mitternacht
+ int resurrection_exp;
+ int shop_exp;
+ int combo_delay_rate;
+ int item_check;
+ int item_use_interval; //[Skotlex]
+ int cashfood_use_interval;
+ int wedding_modifydisplay;
+ int wedding_ignorepalette; //[Skotlex]
+ int xmas_ignorepalette; // [Valaris]
+ int summer_ignorepalette; // [Zephyrus]
+ int natural_healhp_interval;
+ int natural_healsp_interval;
+ int natural_heal_skill_interval;
+ int natural_heal_weight_rate;
+ int arrow_decrement;
+ int max_aspd;
+ int max_walk_speed; //Maximum walking speed after buffs [Skotlex]
+ int max_hp;
+ int max_sp;
+ int max_lv, aura_lv;
+ int max_parameter, max_baby_parameter;
+ int max_cart_weight;
+ int skill_log;
+ int battle_log;
+ int etc_log;
+ int save_clothcolor;
+ int undead_detect_type;
+ int auto_counter_type;
+ int min_hitrate; //[Skotlex]
+ int max_hitrate; //[Skotlex]
+ int agi_penalty_target;
+ int agi_penalty_type;
+ int agi_penalty_count;
+ int agi_penalty_num;
+ int vit_penalty_target;
+ int vit_penalty_type;
+ int vit_penalty_count;
+ int vit_penalty_num;
+ int weapon_defense_type;
+ int magic_defense_type;
+ int skill_reiteration;
+ int skill_nofootset;
+ int pc_cloak_check_type;
+ int monster_cloak_check_type;
+ int estimation_type;
+ int gvg_short_damage_rate;
+ int gvg_long_damage_rate;
+ int gvg_weapon_damage_rate;
+ int gvg_magic_damage_rate;
+ int gvg_misc_damage_rate;
+ int gvg_flee_penalty;
+ int pk_short_damage_rate;
+ int pk_long_damage_rate;
+ int pk_weapon_damage_rate;
+ int pk_magic_damage_rate;
+ int pk_misc_damage_rate;
+ int mob_changetarget_byskill;
+ int attack_direction_change;
+ int land_skill_limit;
+ int monster_class_change_recover;
+ int produce_item_name_input;
+ int display_skill_fail;
+ int chat_warpportal;
+ int mob_warp;
+ int dead_branch_active;
+ int vending_max_value;
+ int vending_over_max;
+ int vending_tax;
+ int show_steal_in_same_party;
+ int party_share_type;
+ int party_hp_mode;
+ int party_show_share_picker;
+ int show_picker_item_type;
+ int attack_attr_none;
+ int item_rate_mvp, item_rate_common, item_rate_common_boss, item_rate_card, item_rate_card_boss,
+ item_rate_equip, item_rate_equip_boss, item_rate_heal, item_rate_heal_boss, item_rate_use,
+ item_rate_use_boss, item_rate_treasure, item_rate_adddrop;
+
+ int logarithmic_drops;
+ int item_drop_common_min,item_drop_common_max; // Added by TyrNemesis^
+ int item_drop_card_min,item_drop_card_max;
+ int item_drop_equip_min,item_drop_equip_max;
+ int item_drop_mvp_min,item_drop_mvp_max; // End Addition
+ int item_drop_heal_min,item_drop_heal_max; // Added by Valatris
+ int item_drop_use_min,item_drop_use_max; //End
+ int item_drop_treasure_min,item_drop_treasure_max; //by [Skotlex]
+ int item_drop_adddrop_min,item_drop_adddrop_max; //[Skotlex]
+
+ int prevent_logout; // Added by RoVeRT
+
+ int alchemist_summon_reward; // [Valaris]
+ int drops_by_luk;
+ int drops_by_luk2;
+ int equip_natural_break_rate; //Base Natural break rate for attacks.
+ int equip_self_break_rate; //Natural & Penalty skills break rate
+ int equip_skill_break_rate; //Offensive skills break rate
+ int multi_level_up;
+ int max_exp_gain_rate; //Max amount of exp bar % you can get in one go.
+ int pk_mode;
+ int pk_level_range;
+
+ int manner_system; // end additions [Valaris]
+ int show_mob_info;
+
+ int gx_allhit;
+ int gx_disptype;
+ int devotion_level_difference;
+ int player_skill_partner_check;
+ int invite_request_check;
+ int skill_removetrap_type;
+ int disp_experience;
+ int disp_zeny;
+ int castle_defense_rate;
+ int backstab_bow_penalty;
+ int hp_rate;
+ int sp_rate;
+ int bone_drop;
+ int buyer_name;
+ int dancing_weaponswitch_fix;
+
+// eAthena additions
+ int night_at_start; // added by [Yor]
+ int day_duration; // added by [Yor]
+ int night_duration; // added by [Yor]
+ int ban_hack_trade; // added by [Yor]
+ int packet_ver_flag; // added by [Yor]
+
+ int min_hair_style; // added by [MouseJstr]
+ int max_hair_style; // added by [MouseJstr]
+ int min_hair_color; // added by [MouseJstr]
+ int max_hair_color; // added by [MouseJstr]
+ int min_cloth_color; // added by [MouseJstr]
+ int max_cloth_color; // added by [MouseJstr]
+ int pet_hair_style; // added by [Skotlex]
+
+ int castrate_dex_scale; // added by [MouseJstr]
+ int area_size; // added by [MouseJstr]
+
+ int max_def, over_def_bonus; //added by [Skotlex]
+
+ int zeny_from_mobs; // [Valaris]
+ int mobs_level_up; // [Valaris]
+ int mobs_level_up_exp_rate; // [Valaris]
+ int pk_min_level; // [celest]
+ int skill_steal_max_tries; //max steal skill tries on a mob. if 0, then w/o limit [Lupus]
+ int motd_type; // [celest]
+ int finding_ore_rate; // orn
+ int exp_calc_type;
+ int exp_bonus_attacker;
+ int exp_bonus_max_attacker;
+ int min_skill_delay_limit;
+ int default_walk_delay;
+ int no_skill_delay;
+ int attack_walk_delay;
+ int require_glory_guild;
+ int idle_no_share;
+ int party_update_interval;
+ int party_even_share_bonus;
+ int delay_battle_damage;
+ int hide_woe_damage;
+ int display_version;
+
+ int display_hallucination; // [Skotlex]
+ int use_statpoint_table; // [Skotlex]
+
+ int ignore_items_gender; //[Lupus]
+
+ int copyskill_restrict; // [Aru]
+ int berserk_cancels_buffs; // [Aru]
+ int debuff_on_logout; // Removes a few "official" negative Scs on logout. [Skotlex]
+ int mob_ai; //Configures various mob_ai settings to make them smarter or dumber(official). [Skotlex]
+ int hom_setting; //Configures various homunc settings which make them behave unlike normal characters.. [Skotlex]
+ int dynamic_mobs; // Dynamic Mobs [Wizputer] - battle_athena flag implemented by [random]
+ int mob_remove_damaged; // Dynamic Mobs - Remove mobs even if damaged [Wizputer]
+ int mob_remove_delay; // Dynamic Mobs - delay before removing mobs from a map [Skotlex]
+ int mob_active_time; //Duration through which mobs execute their Hard AI after players leave their area of sight.
+ int boss_active_time;
+
+ int show_hp_sp_drain, show_hp_sp_gain; //[Skotlex]
+
+ int mob_npc_event_type; //Determines on who the npc_event is executed. [Skotlex]
+
+ int character_size; // if riders have size=2, and baby class riders size=1 [Lupus]
+ int mob_max_skilllvl; // Max possible skill level [Lupus]
+ int rare_drop_announce; // chance <= to show rare drops global announces
+
+ int retaliate_to_master; //Whether when a mob is attacked by another mob, it will retaliate versus the mob or the mob's master. [Skotlex]
+
+ int duel_allow_pvp; // [LuzZza]
+ int duel_allow_gvg; // [LuzZza]
+ int duel_allow_teleport; // [LuzZza]
+ int duel_autoleave_when_die; // [LuzZza]
+ int duel_time_interval; // [LuzZza]
+ int duel_only_on_same_map; // [Toms]
+
+ int skip_teleport_lv1_menu; // possibility to disable (skip) Teleport Lv1 menu, that have only two lines `Random` and `Cancel` [LuzZza]
+
+ int allow_skill_without_day; // [Komurka]
+ int allow_es_magic_pc; // [Skotlex]
+ int skill_wall_check; // [Skotlex]
+ int cell_stack_limit; // [Skotlex]
+ int skill_caster_check; // [Skotlex]
+ int sc_castcancel; // [Skotlex]
+ int pc_sc_def_rate; // [Skotlex]
+ int mob_sc_def_rate;
+ int pc_luk_sc_def;
+ int mob_luk_sc_def;
+ int pc_max_sc_def;
+ int mob_max_sc_def;
+
+ int sg_angel_skill_ratio;
+ int sg_miracle_skill_ratio;
+ int sg_miracle_skill_duration;
+ int autospell_stacking; //Enables autospell cards to stack. [Skotlex]
+ int override_mob_names; //Enables overriding spawn mob names with the mob_db names. [Skotlex]
+ int min_chat_delay; //Minimum time between client messages. [Skotlex]
+ int friend_auto_add; //When accepting friends, both get friended. [Skotlex]
+ int hvan_explosion_intimate; // fix [albator]
+ int hom_rename;
+ int homunculus_show_growth ; //[orn]
+ int homunculus_friendly_rate;
+ int quest_exp_rate;
+ int autotrade_mapflag;
+ int at_timeout;
+ int homunculus_autoloot;
+ int idle_no_autoloot;
+ int max_guild_alliance;
+ int ksprotection;
+ int auction_feeperhour;
+ int auction_maximumprice;
+ int homunculus_auto_vapor; //Keep Homunculus from Vaporizing when master dies. [L0ne_W0lf]
+ int display_status_timers; //Show or hide skill buff/delay timers in recent clients [Sara]
+ int skill_add_heal_rate; //skills that bHealPower has effect on [Inkfish]
+ int eq_single_target_reflectable;
+ int invincible_nodamage;
+ int mob_slave_keep_target;
+ int autospell_check_range; //Enable range check for autospell bonus. [L0ne_W0lf]
+ int client_reshuffle_dice; // Reshuffle /dice
+ int client_sort_storage;
+ int feature_buying_store;
+ int feature_search_stores;
+ int searchstore_querydelay;
+ int searchstore_maxresults;
+ int display_party_name;
+ int cashshop_show_points;
+ int mail_show_status;
+ int client_limit_unit_lv;
+ int hom_max_level;
+ int hom_S_max_level;
+
+ // [BattleGround Settings]
+ int bg_update_interval;
+ int bg_short_damage_rate;
+ int bg_long_damage_rate;
+ int bg_weapon_damage_rate;
+ int bg_magic_damage_rate;
+ int bg_misc_damage_rate;
+ int bg_flee_penalty;
+
+ // rAthena
+ int max_third_parameter;
+ int max_baby_third_parameter;
+ int atcommand_max_stat_bypass;
+ int max_third_aspd;
+ int vcast_stat_scale;
+
+ int mvp_tomb_enabled;
+
+ int atcommand_suggestions_enabled;
int min_npc_vending_distance;
- int atcommand_mobinfo_type;
-
- int mob_size_influence; // Enable modifications on earned experience, drop rates and monster status depending on monster size. [mkbu95]
+ int atcommand_mobinfo_type;
+
+ int mob_size_influence; // Enable modifications on earned experience, drop rates and monster status depending on monster size. [mkbu95]
} battle_config;
void do_init_battle(void);
@@ -489,14 +489,14 @@ void do_final_battle(void);
extern int battle_config_read(const char *cfgName);
extern void battle_validate_conf(void);
extern void battle_set_defaults(void);
-int battle_set_value(const char *w1, const char *w2);
-int battle_get_value(const char *w1);
+int battle_set_value(const char* w1, const char* w2);
+int battle_get_value(const char* w1);
//
-struct block_list *battle_getenemyarea(struct block_list *src, int x, int y, int range, int type, int ignore_id);
+struct block_list* battle_getenemyarea(struct block_list *src, int x, int y, int range, int type, int ignore_id);
/**
* Royal Guard
**/
-int battle_damage_area(struct block_list *bl, va_list ap);
+int battle_damage_area( struct block_list *bl, va_list ap);
#endif /* _BATTLE_H_ */
diff --git a/src/map/battleground.c b/src/map/battleground.c
index fc1653e03..7b605066d 100644
--- a/src/map/battleground.c
+++ b/src/map/battleground.c
@@ -22,198 +22,198 @@
#include <string.h>
#include <stdio.h>
-static DBMap *bg_team_db; // int bg_id -> struct battleground_data*
+static DBMap* bg_team_db; // int bg_id -> struct battleground_data*
static unsigned int bg_team_counter = 0; // Next bg_id
-struct battleground_data *bg_team_search(int bg_id) {
- // Search a BG Team using bg_id
- if (!bg_id) return NULL;
- return (struct battleground_data *)idb_get(bg_team_db, bg_id);
+struct battleground_data* bg_team_search(int bg_id)
+{ // Search a BG Team using bg_id
+ if( !bg_id ) return NULL;
+ return (struct battleground_data *)idb_get(bg_team_db, bg_id);
}
-struct map_session_data *bg_getavailablesd(struct battleground_data *bg) {
- int i;
- nullpo_retr(NULL, bg);
- ARR_FIND(0, MAX_BG_MEMBERS, i, bg->members[i].sd != NULL);
- return(i < MAX_BG_MEMBERS) ? bg->members[i].sd : NULL;
+struct map_session_data* bg_getavailablesd(struct battleground_data *bg)
+{
+ int i;
+ nullpo_retr(NULL, bg);
+ ARR_FIND(0, MAX_BG_MEMBERS, i, bg->members[i].sd != NULL);
+ return( i < MAX_BG_MEMBERS ) ? bg->members[i].sd : NULL;
}
int bg_team_delete(int bg_id)
-{
- // Deletes BG Team from db
- int i;
- struct map_session_data *sd;
- struct battleground_data *bg = bg_team_search(bg_id);
-
- if (bg == NULL) return 0;
- for (i = 0; i < MAX_BG_MEMBERS; i++) {
- if ((sd = bg->members[i].sd) == NULL)
- continue;
-
- bg_send_dot_remove(sd);
- sd->bg_id = 0;
- }
- idb_remove(bg_team_db, bg_id);
- return 1;
+{ // Deletes BG Team from db
+ int i;
+ struct map_session_data *sd;
+ struct battleground_data *bg = bg_team_search(bg_id);
+
+ if( bg == NULL ) return 0;
+ for( i = 0; i < MAX_BG_MEMBERS; i++ )
+ {
+ if( (sd = bg->members[i].sd) == NULL )
+ continue;
+
+ bg_send_dot_remove(sd);
+ sd->bg_id = 0;
+ }
+ idb_remove(bg_team_db, bg_id);
+ return 1;
}
int bg_team_warp(int bg_id, unsigned short mapindex, short x, short y)
-{
- // Warps a Team
- int i;
- struct battleground_data *bg = bg_team_search(bg_id);
- if (bg == NULL) return 0;
- for (i = 0; i < MAX_BG_MEMBERS; i++)
- if (bg->members[i].sd != NULL) pc_setpos(bg->members[i].sd, mapindex, x, y, CLR_TELEPORT);
- return 1;
+{ // Warps a Team
+ int i;
+ struct battleground_data *bg = bg_team_search(bg_id);
+ if( bg == NULL ) return 0;
+ for( i = 0; i < MAX_BG_MEMBERS; i++ )
+ if( bg->members[i].sd != NULL ) pc_setpos(bg->members[i].sd, mapindex, x, y, CLR_TELEPORT);
+ return 1;
}
int bg_send_dot_remove(struct map_session_data *sd)
{
- if (sd && sd->bg_id)
- clif_bg_xy_remove(sd);
- return 0;
+ if( sd && sd->bg_id )
+ clif_bg_xy_remove(sd);
+ return 0;
}
int bg_team_join(int bg_id, struct map_session_data *sd)
-{
- // Player joins team
- int i;
- struct battleground_data *bg = bg_team_search(bg_id);
- struct map_session_data *pl_sd;
+{ // Player joins team
+ int i;
+ struct battleground_data *bg = bg_team_search(bg_id);
+ struct map_session_data *pl_sd;
- if (bg == NULL || sd == NULL || sd->bg_id) return 0;
+ if( bg == NULL || sd == NULL || sd->bg_id ) return 0;
- ARR_FIND(0, MAX_BG_MEMBERS, i, bg->members[i].sd == NULL);
- if (i == MAX_BG_MEMBERS) return 0; // No free slots
+ ARR_FIND(0, MAX_BG_MEMBERS, i, bg->members[i].sd == NULL);
+ if( i == MAX_BG_MEMBERS ) return 0; // No free slots
- sd->bg_id = bg_id;
- bg->members[i].sd = sd;
- bg->members[i].x = sd->bl.x;
- bg->members[i].y = sd->bl.y;
- bg->count++;
+ sd->bg_id = bg_id;
+ bg->members[i].sd = sd;
+ bg->members[i].x = sd->bl.x;
+ bg->members[i].y = sd->bl.y;
+ bg->count++;
- guild_send_dot_remove(sd);
+ guild_send_dot_remove(sd);
- for (i = 0; i < MAX_BG_MEMBERS; i++) {
- if ((pl_sd = bg->members[i].sd) != NULL && pl_sd != sd)
- clif_hpmeter_single(sd->fd, pl_sd->bl.id, pl_sd->battle_status.hp, pl_sd->battle_status.max_hp);
- }
+ for( i = 0; i < MAX_BG_MEMBERS; i++ )
+ {
+ if( (pl_sd = bg->members[i].sd) != NULL && pl_sd != sd )
+ clif_hpmeter_single(sd->fd, pl_sd->bl.id, pl_sd->battle_status.hp, pl_sd->battle_status.max_hp);
+ }
- clif_bg_hp(sd);
- clif_bg_xy(sd);
- return 1;
+ clif_bg_hp(sd);
+ clif_bg_xy(sd);
+ return 1;
}
int bg_team_leave(struct map_session_data *sd, int flag)
-{
- // Single Player leaves team
- int i, bg_id;
- struct battleground_data *bg;
- char output[128];
+{ // Single Player leaves team
+ int i, bg_id;
+ struct battleground_data *bg;
+ char output[128];
- if (sd == NULL || !sd->bg_id)
- return 0;
+ if( sd == NULL || !sd->bg_id )
+ return 0;
- bg_send_dot_remove(sd);
- bg_id = sd->bg_id;
- sd->bg_id = 0;
+ bg_send_dot_remove(sd);
+ bg_id = sd->bg_id;
+ sd->bg_id = 0;
- if ((bg = bg_team_search(bg_id)) == NULL)
- return 0;
+ if( (bg = bg_team_search(bg_id)) == NULL )
+ return 0;
- ARR_FIND(0, MAX_BG_MEMBERS, i, bg->members[i].sd == sd);
- if (i < MAX_BG_MEMBERS) // Removes member from BG
- memset(&bg->members[i], 0, sizeof(bg->members[0]));
- bg->count--;
+ ARR_FIND(0, MAX_BG_MEMBERS, i, bg->members[i].sd == sd);
+ if( i < MAX_BG_MEMBERS ) // Removes member from BG
+ memset(&bg->members[i], 0, sizeof(bg->members[0]));
+ bg->count--;
- if (flag)
- sprintf(output, "Server : %s has quit the game...", sd->status.name);
- else
- sprintf(output, "Server : %s is leaving the battlefield...", sd->status.name);
- clif_bg_message(bg, 0, "Server", output, strlen(output) + 1);
+ if( flag )
+ sprintf(output, "Server : %s has quit the game...", sd->status.name);
+ else
+ sprintf(output, "Server : %s is leaving the battlefield...", sd->status.name);
+ clif_bg_message(bg, 0, "Server", output, strlen(output) + 1);
- if (bg->logout_event[0] && flag)
- npc_event(sd, bg->logout_event, 0);
+ if( bg->logout_event[0] && flag )
+ npc_event(sd, bg->logout_event, 0);
- return bg->count;
+ return bg->count;
}
int bg_member_respawn(struct map_session_data *sd)
-{
- // Respawn after killed
- struct battleground_data *bg;
- if (sd == NULL || !pc_isdead(sd) || !sd->bg_id || (bg = bg_team_search(sd->bg_id)) == NULL)
- return 0;
- if (bg->mapindex == 0)
- return 0; // Respawn not handled by Core
- pc_setpos(sd, bg->mapindex, bg->x, bg->y, CLR_OUTSIGHT);
- status_revive(&sd->bl, 1, 100);
-
- return 1; // Warped
+{ // Respawn after killed
+ struct battleground_data *bg;
+ if( sd == NULL || !pc_isdead(sd) || !sd->bg_id || (bg = bg_team_search(sd->bg_id)) == NULL )
+ return 0;
+ if( bg->mapindex == 0 )
+ return 0; // Respawn not handled by Core
+ pc_setpos(sd, bg->mapindex, bg->x, bg->y, CLR_OUTSIGHT);
+ status_revive(&sd->bl, 1, 100);
+
+ return 1; // Warped
}
int bg_create(unsigned short mapindex, short rx, short ry, const char *ev, const char *dev)
{
- struct battleground_data *bg;
- bg_team_counter++;
-
- CREATE(bg, struct battleground_data, 1);
- bg->bg_id = bg_team_counter;
- bg->count = 0;
- bg->mapindex = mapindex;
- bg->x = rx;
- bg->y = ry;
- safestrncpy(bg->logout_event, ev, sizeof(bg->logout_event));
- safestrncpy(bg->die_event, dev, sizeof(bg->die_event));
-
- memset(&bg->members, 0, sizeof(bg->members));
- idb_put(bg_team_db, bg_team_counter, bg);
-
- return bg->bg_id;
+ struct battleground_data *bg;
+ bg_team_counter++;
+
+ CREATE(bg, struct battleground_data, 1);
+ bg->bg_id = bg_team_counter;
+ bg->count = 0;
+ bg->mapindex = mapindex;
+ bg->x = rx;
+ bg->y = ry;
+ safestrncpy(bg->logout_event, ev, sizeof(bg->logout_event));
+ safestrncpy(bg->die_event, dev, sizeof(bg->die_event));
+
+ memset(&bg->members, 0, sizeof(bg->members));
+ idb_put(bg_team_db, bg_team_counter, bg);
+
+ return bg->bg_id;
}
int bg_team_get_id(struct block_list *bl)
{
- nullpo_ret(bl);
- switch (bl->type) {
- case BL_PC:
- return ((TBL_PC *)bl)->bg_id;
- case BL_PET:
- if (((TBL_PET *)bl)->msd)
- return ((TBL_PET *)bl)->msd->bg_id;
- break;
- case BL_MOB: {
- struct map_session_data *msd;
- struct mob_data *md = (TBL_MOB *)bl;
- if (md->special_state.ai && (msd = map_id2sd(md->master_id)) != NULL)
- return msd->bg_id;
- return md->bg_id;
- }
- case BL_HOM:
- if (((TBL_HOM *)bl)->master)
- return ((TBL_HOM *)bl)->master->bg_id;
- break;
- case BL_MER:
- if (((TBL_MER *)bl)->master)
- return ((TBL_MER *)bl)->master->bg_id;
- break;
- case BL_SKILL:
- return ((TBL_SKILL *)bl)->group->bg_id;
- }
-
- return 0;
+ nullpo_ret(bl);
+ switch( bl->type )
+ {
+ case BL_PC:
+ return ((TBL_PC*)bl)->bg_id;
+ case BL_PET:
+ if( ((TBL_PET*)bl)->msd )
+ return ((TBL_PET*)bl)->msd->bg_id;
+ break;
+ case BL_MOB:
+ {
+ struct map_session_data *msd;
+ struct mob_data *md = (TBL_MOB*)bl;
+ if( md->special_state.ai && (msd = map_id2sd(md->master_id)) != NULL )
+ return msd->bg_id;
+ return md->bg_id;
+ }
+ case BL_HOM:
+ if( ((TBL_HOM*)bl)->master )
+ return ((TBL_HOM*)bl)->master->bg_id;
+ break;
+ case BL_MER:
+ if( ((TBL_MER*)bl)->master )
+ return ((TBL_MER*)bl)->master->bg_id;
+ break;
+ case BL_SKILL:
+ return ((TBL_SKILL*)bl)->group->bg_id;
+ }
+
+ return 0;
}
int bg_send_message(struct map_session_data *sd, const char *mes, int len)
{
- struct battleground_data *bg;
+ struct battleground_data *bg;
- nullpo_ret(sd);
- if (sd->bg_id == 0 || (bg = bg_team_search(sd->bg_id)) == NULL)
- return 0;
- clif_bg_message(bg, sd->bl.id, sd->status.name, mes, len);
- return 0;
+ nullpo_ret(sd);
+ if( sd->bg_id == 0 || (bg = bg_team_search(sd->bg_id)) == NULL )
+ return 0;
+ clif_bg_message(bg, sd->bl.id, sd->status.name, mes, len);
+ return 0;
}
/**
@@ -221,37 +221,38 @@ int bg_send_message(struct map_session_data *sd, const char *mes, int len)
*/
int bg_send_xy_timer_sub(DBKey key, DBData *data, va_list ap)
{
- struct battleground_data *bg = db_data2ptr(data);
- struct map_session_data *sd;
- int i;
- nullpo_ret(bg);
- for (i = 0; i < MAX_BG_MEMBERS; i++) {
- if ((sd = bg->members[i].sd) == NULL)
- continue;
- if (sd->bl.x != bg->members[i].x || sd->bl.y != bg->members[i].y) {
- // xy update
- bg->members[i].x = sd->bl.x;
- bg->members[i].y = sd->bl.y;
- clif_bg_xy(sd);
- }
- }
- return 0;
+ struct battleground_data *bg = db_data2ptr(data);
+ struct map_session_data *sd;
+ int i;
+ nullpo_ret(bg);
+ for( i = 0; i < MAX_BG_MEMBERS; i++ )
+ {
+ if( (sd = bg->members[i].sd) == NULL )
+ continue;
+ if( sd->bl.x != bg->members[i].x || sd->bl.y != bg->members[i].y )
+ { // xy update
+ bg->members[i].x = sd->bl.x;
+ bg->members[i].y = sd->bl.y;
+ clif_bg_xy(sd);
+ }
+ }
+ return 0;
}
int bg_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- bg_team_db->foreach(bg_team_db, bg_send_xy_timer_sub, tick);
- return 0;
+ bg_team_db->foreach(bg_team_db, bg_send_xy_timer_sub, tick);
+ return 0;
}
void do_init_battleground(void)
{
- bg_team_db = idb_alloc(DB_OPT_RELEASE_DATA);
- add_timer_func_list(bg_send_xy_timer, "bg_send_xy_timer");
- add_timer_interval(gettick() + battle_config.bg_update_interval, bg_send_xy_timer, 0, 0, battle_config.bg_update_interval);
+ bg_team_db = idb_alloc(DB_OPT_RELEASE_DATA);
+ add_timer_func_list(bg_send_xy_timer, "bg_send_xy_timer");
+ add_timer_interval(gettick() + battle_config.bg_update_interval, bg_send_xy_timer, 0, 0, battle_config.bg_update_interval);
}
void do_final_battleground(void)
{
- bg_team_db->destroy(bg_team_db, NULL);
+ bg_team_db->destroy(bg_team_db, NULL);
}
diff --git a/src/map/battleground.h b/src/map/battleground.h
index c3efc30a2..c2b74a534 100644
--- a/src/map/battleground.h
+++ b/src/map/battleground.h
@@ -10,29 +10,29 @@
#define MAX_BG_MEMBERS 30
struct battleground_member_data {
- unsigned short x, y;
- struct map_session_data *sd;
- unsigned afk : 1;
+ unsigned short x, y;
+ struct map_session_data *sd;
+ unsigned afk : 1;
};
struct battleground_data {
- unsigned int bg_id;
- unsigned char count;
- struct battleground_member_data members[MAX_BG_MEMBERS];
- // BG Cementery
- unsigned short mapindex, x, y;
- // Logout Event
- char logout_event[EVENT_NAME_LENGTH];
- char die_event[EVENT_NAME_LENGTH];
+ unsigned int bg_id;
+ unsigned char count;
+ struct battleground_member_data members[MAX_BG_MEMBERS];
+ // BG Cementery
+ unsigned short mapindex, x, y;
+ // Logout Event
+ char logout_event[EVENT_NAME_LENGTH];
+ char die_event[EVENT_NAME_LENGTH];
};
void do_init_battleground(void);
void do_final_battleground(void);
-struct battleground_data *bg_team_search(int bg_id);
+struct battleground_data* bg_team_search(int bg_id);
int bg_send_dot_remove(struct map_session_data *sd);
int bg_team_get_id(struct block_list *bl);
-struct map_session_data *bg_getavailablesd(struct battleground_data *bg);
+struct map_session_data* bg_getavailablesd(struct battleground_data *bg);
int bg_create(unsigned short mapindex, short rx, short ry, const char *ev, const char *dev);
int bg_team_join(int bg_id, struct map_session_data *sd);
diff --git a/src/map/buyingstore.c b/src/map/buyingstore.c
index 796c6cd7d..8e3c21bd4 100644
--- a/src/map/buyingstore.c
+++ b/src/map/buyingstore.c
@@ -20,15 +20,16 @@
/// failure constants for clif functions
-enum e_buyingstore_failure {
- BUYINGSTORE_CREATE = 1, // "Failed to open buying store."
- BUYINGSTORE_CREATE_OVERWEIGHT = 2, // "Total amount of then possessed items exceeds the weight limit by %d. Please re-enter."
- BUYINGSTORE_TRADE_BUYER_ZENY = 3, // "All items within the buy limit were purchased."
- BUYINGSTORE_TRADE_BUYER_NO_ITEMS = 4, // "All items were purchased."
- BUYINGSTORE_TRADE_SELLER_FAILED = 5, // "The deal has failed."
- BUYINGSTORE_TRADE_SELLER_COUNT = 6, // "The trade failed, because the entered amount of item %s is higher, than the buyer is willing to buy."
- BUYINGSTORE_TRADE_SELLER_ZENY = 7, // "The trade failed, because the buyer is lacking required balance."
- BUYINGSTORE_CREATE_NO_INFO = 8, // "No sale (purchase) information available."
+enum e_buyingstore_failure
+{
+ BUYINGSTORE_CREATE = 1, // "Failed to open buying store."
+ BUYINGSTORE_CREATE_OVERWEIGHT = 2, // "Total amount of then possessed items exceeds the weight limit by %d. Please re-enter."
+ BUYINGSTORE_TRADE_BUYER_ZENY = 3, // "All items within the buy limit were purchased."
+ BUYINGSTORE_TRADE_BUYER_NO_ITEMS = 4, // "All items were purchased."
+ BUYINGSTORE_TRADE_SELLER_FAILED = 5, // "The deal has failed."
+ BUYINGSTORE_TRADE_SELLER_COUNT = 6, // "The trade failed, because the entered amount of item %s is higher, than the buyer is willing to buy."
+ BUYINGSTORE_TRADE_SELLER_ZENY = 7, // "The trade failed, because the buyer is lacking required balance."
+ BUYINGSTORE_CREATE_NO_INFO = 8, // "No sale (purchase) information available."
};
@@ -39,427 +40,434 @@ static const short buyingstore_blankslots[MAX_SLOTS] = { 0 }; // used when chec
/// Returns unique buying store id
static unsigned int buyingstore_getuid(void)
{
- return buyingstore_nextid++;
+ return buyingstore_nextid++;
}
-bool buyingstore_setup(struct map_session_data *sd, unsigned char slots)
+bool buyingstore_setup(struct map_session_data* sd, unsigned char slots)
{
- if (!battle_config.feature_buying_store || sd->state.vending || sd->state.buyingstore || sd->state.trading || slots == 0) {
- return false;
- }
-
- if (sd->sc.data[SC_NOCHAT] && (sd->sc.data[SC_NOCHAT]->val1&MANNER_NOROOM)) {
- // custom: mute limitation
- return false;
- }
-
- if (map[sd->bl.m].flag.novending) {
- // custom: no vending maps
- clif_displaymessage(sd->fd, msg_txt(276)); // "You can't open a shop on this map"
- return false;
- }
-
- if (map_getcell(sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKNOVENDING)) {
- // custom: no vending cells
- clif_displaymessage(sd->fd, msg_txt(204)); // "You can't open a shop on this cell."
- return false;
- }
-
- if (slots > MAX_BUYINGSTORE_SLOTS) {
- ShowWarning("buyingstore_setup: Requested %d slots, but server supports only %d slots.\n", (int)slots, MAX_BUYINGSTORE_SLOTS);
- slots = MAX_BUYINGSTORE_SLOTS;
- }
-
- sd->buyingstore.slots = slots;
- clif_buyingstore_open(sd);
-
- return true;
+ if( !battle_config.feature_buying_store || sd->state.vending || sd->state.buyingstore || sd->state.trading || slots == 0 )
+ {
+ return false;
+ }
+
+ if( sd->sc.data[SC_NOCHAT] && (sd->sc.data[SC_NOCHAT]->val1&MANNER_NOROOM) )
+ {// custom: mute limitation
+ return false;
+ }
+
+ if( map[sd->bl.m].flag.novending )
+ {// custom: no vending maps
+ clif_displaymessage(sd->fd, msg_txt(276)); // "You can't open a shop on this map"
+ return false;
+ }
+
+ if( map_getcell(sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKNOVENDING) )
+ {// custom: no vending cells
+ clif_displaymessage(sd->fd, msg_txt(204)); // "You can't open a shop on this cell."
+ return false;
+ }
+
+ if( slots > MAX_BUYINGSTORE_SLOTS )
+ {
+ ShowWarning("buyingstore_setup: Requested %d slots, but server supports only %d slots.\n", (int)slots, MAX_BUYINGSTORE_SLOTS);
+ slots = MAX_BUYINGSTORE_SLOTS;
+ }
+
+ sd->buyingstore.slots = slots;
+ clif_buyingstore_open(sd);
+
+ return true;
}
-void buyingstore_create(struct map_session_data *sd, int zenylimit, unsigned char result, const char *storename, const uint8 *itemlist, unsigned int count)
+void buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned char result, const char* storename, const uint8* itemlist, unsigned int count)
{
- unsigned int i, weight, listidx;
- struct item_data *id;
-
- if (!result || count == 0) {
- // canceled, or no items
- return;
- }
-
- if (!battle_config.feature_buying_store || pc_istrading(sd) || sd->buyingstore.slots == 0 || count > sd->buyingstore.slots || zenylimit <= 0 || zenylimit > sd->status.zeny || !storename[0]) {
- // disabled or invalid input
- sd->buyingstore.slots = 0;
- clif_buyingstore_open_failed(sd, BUYINGSTORE_CREATE, 0);
- return;
- }
-
- if (!pc_can_give_items(sd)) {
- // custom: GM is not allowed to buy (give zeny)
- sd->buyingstore.slots = 0;
- clif_displaymessage(sd->fd, msg_txt(246));
- clif_buyingstore_open_failed(sd, BUYINGSTORE_CREATE, 0);
- return;
- }
-
- if (sd->sc.data[SC_NOCHAT] && (sd->sc.data[SC_NOCHAT]->val1&MANNER_NOROOM)) {
- // custom: mute limitation
- return;
- }
-
- if (map[sd->bl.m].flag.novending) {
- // custom: no vending maps
- clif_displaymessage(sd->fd, msg_txt(276)); // "You can't open a shop on this map"
- return;
- }
-
- if (map_getcell(sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKNOVENDING)) {
- // custom: no vending cells
- clif_displaymessage(sd->fd, msg_txt(204)); // "You can't open a shop on this cell."
- return;
- }
-
- weight = sd->weight;
-
- // check item list
- for (i = 0; i < count; i++) {
- // itemlist: <name id>.W <amount>.W <price>.L
- unsigned short nameid, amount;
- int price, idx;
-
- nameid = RBUFW(itemlist,i*8+0);
- amount = RBUFW(itemlist,i*8+2);
- price = RBUFL(itemlist,i*8+4);
-
- if ((id = itemdb_exists(nameid)) == NULL || amount == 0) {
- // invalid input
- break;
- }
-
- if (price <= 0 || price > BUYINGSTORE_MAX_PRICE) {
- // invalid price: unlike vending, items cannot be bought at 0 Zeny
- break;
- }
-
- if (!id->flag.buyingstore || !itemdb_cantrade_sub(id, pc_get_group_level(sd), pc_get_group_level(sd)) || (idx = pc_search_inventory(sd, nameid)) == -1) {
- // restrictions: allowed, no character-bound items and at least one must be owned
- break;
- }
-
- if (sd->status.inventory[idx].amount+amount > BUYINGSTORE_MAX_AMOUNT) {
- // too many items of same kind
- break;
- }
-
- if (i) {
- // duplicate check. as the client does this too, only malicious intent should be caught here
- ARR_FIND(0, i, listidx, sd->buyingstore.items[listidx].nameid == nameid);
- if (listidx != i) {
- // duplicate
- ShowWarning("buyingstore_create: Found duplicate item on buying list (nameid=%hu, amount=%hu, account_id=%d, char_id=%d).\n", nameid, amount, sd->status.account_id, sd->status.char_id);
- break;
- }
- }
-
- weight+= id->weight*amount;
- sd->buyingstore.items[i].nameid = nameid;
- sd->buyingstore.items[i].amount = amount;
- sd->buyingstore.items[i].price = price;
- }
-
- if (i != count) {
- // invalid item/amount/price
- sd->buyingstore.slots = 0;
- clif_buyingstore_open_failed(sd, BUYINGSTORE_CREATE, 0);
- return;
- }
-
- if ((sd->max_weight*90)/100 < weight) {
- // not able to carry all wanted items without getting overweight (90%)
- sd->buyingstore.slots = 0;
- clif_buyingstore_open_failed(sd, BUYINGSTORE_CREATE_OVERWEIGHT, weight);
- return;
- }
-
- // success
- sd->state.buyingstore = true;
- sd->buyer_id = buyingstore_getuid();
- sd->buyingstore.zenylimit = zenylimit;
- sd->buyingstore.slots = i; // store actual amount of items
- safestrncpy(sd->message, storename, sizeof(sd->message));
- clif_buyingstore_myitemlist(sd);
- clif_buyingstore_entry(sd);
+ unsigned int i, weight, listidx;
+ struct item_data* id;
+
+ if( !result || count == 0 )
+ {// canceled, or no items
+ return;
+ }
+
+ if( !battle_config.feature_buying_store || pc_istrading(sd) || sd->buyingstore.slots == 0 || count > sd->buyingstore.slots || zenylimit <= 0 || zenylimit > sd->status.zeny || !storename[0] )
+ {// disabled or invalid input
+ sd->buyingstore.slots = 0;
+ clif_buyingstore_open_failed(sd, BUYINGSTORE_CREATE, 0);
+ return;
+ }
+
+ if( !pc_can_give_items(sd) )
+ {// custom: GM is not allowed to buy (give zeny)
+ sd->buyingstore.slots = 0;
+ clif_displaymessage(sd->fd, msg_txt(246));
+ clif_buyingstore_open_failed(sd, BUYINGSTORE_CREATE, 0);
+ return;
+ }
+
+ if( sd->sc.data[SC_NOCHAT] && (sd->sc.data[SC_NOCHAT]->val1&MANNER_NOROOM) )
+ {// custom: mute limitation
+ return;
+ }
+
+ if( map[sd->bl.m].flag.novending )
+ {// custom: no vending maps
+ clif_displaymessage(sd->fd, msg_txt(276)); // "You can't open a shop on this map"
+ return;
+ }
+
+ if( map_getcell(sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKNOVENDING) )
+ {// custom: no vending cells
+ clif_displaymessage(sd->fd, msg_txt(204)); // "You can't open a shop on this cell."
+ return;
+ }
+
+ weight = sd->weight;
+
+ // check item list
+ for( i = 0; i < count; i++ )
+ {// itemlist: <name id>.W <amount>.W <price>.L
+ unsigned short nameid, amount;
+ int price, idx;
+
+ nameid = RBUFW(itemlist,i*8+0);
+ amount = RBUFW(itemlist,i*8+2);
+ price = RBUFL(itemlist,i*8+4);
+
+ if( ( id = itemdb_exists(nameid) ) == NULL || amount == 0 )
+ {// invalid input
+ break;
+ }
+
+ if( price <= 0 || price > BUYINGSTORE_MAX_PRICE )
+ {// invalid price: unlike vending, items cannot be bought at 0 Zeny
+ break;
+ }
+
+ if( !id->flag.buyingstore || !itemdb_cantrade_sub(id, pc_get_group_level(sd), pc_get_group_level(sd)) || ( idx = pc_search_inventory(sd, nameid) ) == -1 )
+ {// restrictions: allowed, no character-bound items and at least one must be owned
+ break;
+ }
+
+ if( sd->status.inventory[idx].amount+amount > BUYINGSTORE_MAX_AMOUNT )
+ {// too many items of same kind
+ break;
+ }
+
+ if( i )
+ {// duplicate check. as the client does this too, only malicious intent should be caught here
+ ARR_FIND( 0, i, listidx, sd->buyingstore.items[listidx].nameid == nameid );
+ if( listidx != i )
+ {// duplicate
+ ShowWarning("buyingstore_create: Found duplicate item on buying list (nameid=%hu, amount=%hu, account_id=%d, char_id=%d).\n", nameid, amount, sd->status.account_id, sd->status.char_id);
+ break;
+ }
+ }
+
+ weight+= id->weight*amount;
+ sd->buyingstore.items[i].nameid = nameid;
+ sd->buyingstore.items[i].amount = amount;
+ sd->buyingstore.items[i].price = price;
+ }
+
+ if( i != count )
+ {// invalid item/amount/price
+ sd->buyingstore.slots = 0;
+ clif_buyingstore_open_failed(sd, BUYINGSTORE_CREATE, 0);
+ return;
+ }
+
+ if( (sd->max_weight*90)/100 < weight )
+ {// not able to carry all wanted items without getting overweight (90%)
+ sd->buyingstore.slots = 0;
+ clif_buyingstore_open_failed(sd, BUYINGSTORE_CREATE_OVERWEIGHT, weight);
+ return;
+ }
+
+ // success
+ sd->state.buyingstore = true;
+ sd->buyer_id = buyingstore_getuid();
+ sd->buyingstore.zenylimit = zenylimit;
+ sd->buyingstore.slots = i; // store actual amount of items
+ safestrncpy(sd->message, storename, sizeof(sd->message));
+ clif_buyingstore_myitemlist(sd);
+ clif_buyingstore_entry(sd);
}
-void buyingstore_close(struct map_session_data *sd)
+void buyingstore_close(struct map_session_data* sd)
{
- if (sd->state.buyingstore) {
- // invalidate data
- sd->state.buyingstore = false;
- memset(&sd->buyingstore, 0, sizeof(sd->buyingstore));
-
- // notify other players
- clif_buyingstore_disappear_entry(sd);
- }
+ if( sd->state.buyingstore )
+ {
+ // invalidate data
+ sd->state.buyingstore = false;
+ memset(&sd->buyingstore, 0, sizeof(sd->buyingstore));
+
+ // notify other players
+ clif_buyingstore_disappear_entry(sd);
+ }
}
-void buyingstore_open(struct map_session_data *sd, int account_id)
+void buyingstore_open(struct map_session_data* sd, int account_id)
{
- struct map_session_data *pl_sd;
-
- if (!battle_config.feature_buying_store || pc_istrading(sd)) {
- // not allowed to sell
- return;
- }
-
- if (!pc_can_give_items(sd)) {
- // custom: GM is not allowed to sell
- clif_displaymessage(sd->fd, msg_txt(246));
- return;
- }
-
- if ((pl_sd = map_id2sd(account_id)) == NULL || !pl_sd->state.buyingstore) {
- // not online or not buying
- return;
- }
-
- if (!searchstore_queryremote(sd, account_id) && (sd->bl.m != pl_sd->bl.m || !check_distance_bl(&sd->bl, &pl_sd->bl, AREA_SIZE))) {
- // out of view range
- return;
- }
-
- // success
- clif_buyingstore_itemlist(sd, pl_sd);
+ struct map_session_data* pl_sd;
+
+ if( !battle_config.feature_buying_store || pc_istrading(sd) )
+ {// not allowed to sell
+ return;
+ }
+
+ if( !pc_can_give_items(sd) )
+ {// custom: GM is not allowed to sell
+ clif_displaymessage(sd->fd, msg_txt(246));
+ return;
+ }
+
+ if( ( pl_sd = map_id2sd(account_id) ) == NULL || !pl_sd->state.buyingstore )
+ {// not online or not buying
+ return;
+ }
+
+ if( !searchstore_queryremote(sd, account_id) && ( sd->bl.m != pl_sd->bl.m || !check_distance_bl(&sd->bl, &pl_sd->bl, AREA_SIZE) ) )
+ {// out of view range
+ return;
+ }
+
+ // success
+ clif_buyingstore_itemlist(sd, pl_sd);
}
-void buyingstore_trade(struct map_session_data *sd, int account_id, unsigned int buyer_id, const uint8 *itemlist, unsigned int count)
+void buyingstore_trade(struct map_session_data* sd, int account_id, unsigned int buyer_id, const uint8* itemlist, unsigned int count)
{
- int zeny = 0;
- unsigned int i, weight, listidx, k;
- struct map_session_data *pl_sd;
-
- if (count == 0) {
- // nothing to do
- return;
- }
-
- if (!battle_config.feature_buying_store || pc_istrading(sd)) {
- // not allowed to sell
- clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, 0);
- return;
- }
-
- if (!pc_can_give_items(sd)) {
- // custom: GM is not allowed to sell
- clif_displaymessage(sd->fd, msg_txt(246));
- clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, 0);
- return;
- }
-
- if ((pl_sd = map_id2sd(account_id)) == NULL || !pl_sd->state.buyingstore || pl_sd->buyer_id != buyer_id) {
- // not online, not buying or not same store
- clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, 0);
- return;
- }
-
- if (!searchstore_queryremote(sd, account_id) && (sd->bl.m != pl_sd->bl.m || !check_distance_bl(&sd->bl, &pl_sd->bl, AREA_SIZE))) {
- // out of view range
- clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, 0);
- return;
- }
-
- searchstore_clearremote(sd);
-
- if (pl_sd->status.zeny < pl_sd->buyingstore.zenylimit) {
- // buyer lost zeny in the mean time? fix the limit
- pl_sd->buyingstore.zenylimit = pl_sd->status.zeny;
- }
- weight = pl_sd->weight;
-
- // check item list
- for (i = 0; i < count; i++) {
- // itemlist: <index>.W <name id>.W <amount>.W
- unsigned short nameid, amount;
- int index;
-
- index = RBUFW(itemlist,i*6+0)-2;
- nameid = RBUFW(itemlist,i*6+2);
- amount = RBUFW(itemlist,i*6+4);
-
- if (i) {
- // duplicate check. as the client does this too, only malicious intent should be caught here
- ARR_FIND(0, i, k, RBUFW(itemlist,k*6+0)-2 == index);
- if (k != i) {
- // duplicate
- ShowWarning("buyingstore_trade: Found duplicate item on selling list (prevnameid=%hu, prevamount=%hu, nameid=%hu, amount=%hu, account_id=%d, char_id=%d).\n",
- RBUFW(itemlist,k*6+2), RBUFW(itemlist,k*6+4), nameid, amount, sd->status.account_id, sd->status.char_id);
- clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid);
- return;
- }
- }
-
- if (index < 0 || index >= ARRAYLENGTH(sd->status.inventory) || sd->inventory_data[index] == NULL || sd->status.inventory[index].nameid != nameid || sd->status.inventory[index].amount < amount) {
- // invalid input
- clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid);
- return;
- }
-
- if (sd->status.inventory[index].expire_time || !itemdb_cantrade(&sd->status.inventory[index], pc_get_group_level(sd), pc_get_group_level(pl_sd)) || memcmp(sd->status.inventory[index].card, buyingstore_blankslots, sizeof(buyingstore_blankslots))) {
- // non-tradable item
- clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid);
- return;
- }
-
- ARR_FIND(0, pl_sd->buyingstore.slots, listidx, pl_sd->buyingstore.items[listidx].nameid == nameid);
- if (listidx == pl_sd->buyingstore.slots || pl_sd->buyingstore.items[listidx].amount == 0) {
- // there is no such item or the buyer has already bought all of them
- clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid);
- return;
- }
-
- if (pl_sd->buyingstore.items[listidx].amount < amount) {
- // buyer does not need that much of the item
- clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_COUNT, nameid);
- return;
- }
-
- if (pc_checkadditem(pl_sd, nameid, amount) == ADDITEM_OVERAMOUNT) {
- // buyer does not have enough space for this item
- clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid);
- return;
- }
-
- if (amount*(unsigned int)sd->inventory_data[index]->weight > pl_sd->max_weight-weight) {
- // normally this is not supposed to happen, as the total weight is
- // checked upon creation, but the buyer could have gained items
- clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid);
- return;
- }
- weight+= amount*sd->inventory_data[index]->weight;
-
- if (amount*pl_sd->buyingstore.items[listidx].price > pl_sd->buyingstore.zenylimit-zeny) {
- // buyer does not have enough zeny
- clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_ZENY, nameid);
- return;
- }
- zeny+= amount*pl_sd->buyingstore.items[listidx].price;
- }
-
- // process item list
- for (i = 0; i < count; i++) {
- // itemlist: <index>.W <name id>.W <amount>.W
- unsigned short nameid, amount;
- int index;
-
- index = RBUFW(itemlist,i*6+0)-2;
- nameid = RBUFW(itemlist,i*6+2);
- amount = RBUFW(itemlist,i*6+4);
-
- ARR_FIND(0, pl_sd->buyingstore.slots, listidx, pl_sd->buyingstore.items[listidx].nameid == nameid);
- zeny = amount*pl_sd->buyingstore.items[listidx].price;
-
- // move item
- pc_additem(pl_sd, &sd->status.inventory[index], amount, LOG_TYPE_BUYING_STORE);
- pc_delitem(sd, index, amount, 1, 0, LOG_TYPE_BUYING_STORE);
- pl_sd->buyingstore.items[listidx].amount-= amount;
-
- // pay up
- pc_payzeny(pl_sd, zeny, LOG_TYPE_BUYING_STORE, sd);
- pc_getzeny(sd, zeny, LOG_TYPE_BUYING_STORE, pl_sd);
- pl_sd->buyingstore.zenylimit-= zeny;
-
- // notify clients
- clif_buyingstore_delete_item(sd, index, amount, pl_sd->buyingstore.items[listidx].price);
- clif_buyingstore_update_item(pl_sd, nameid, amount);
- }
-
- // check whether or not there is still something to buy
- ARR_FIND(0, pl_sd->buyingstore.slots, i, pl_sd->buyingstore.items[i].amount != 0);
- if (i == pl_sd->buyingstore.slots) {
- // everything was bought
- clif_buyingstore_trade_failed_buyer(pl_sd, BUYINGSTORE_TRADE_BUYER_NO_ITEMS);
- } else if (pl_sd->buyingstore.zenylimit == 0) {
- // zeny limit reached
- clif_buyingstore_trade_failed_buyer(pl_sd, BUYINGSTORE_TRADE_BUYER_ZENY);
- } else {
- // continue buying
- return;
- }
-
- // cannot continue buying
- buyingstore_close(pl_sd);
-
- // remove auto-trader
- if (pl_sd->state.autotrade) {
- map_quit(pl_sd);
- }
+ int zeny = 0;
+ unsigned int i, weight, listidx, k;
+ struct map_session_data* pl_sd;
+
+ if( count == 0 )
+ {// nothing to do
+ return;
+ }
+
+ if( !battle_config.feature_buying_store || pc_istrading(sd) )
+ {// not allowed to sell
+ clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, 0);
+ return;
+ }
+
+ if( !pc_can_give_items(sd) )
+ {// custom: GM is not allowed to sell
+ clif_displaymessage(sd->fd, msg_txt(246));
+ clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, 0);
+ return;
+ }
+
+ if( ( pl_sd = map_id2sd(account_id) ) == NULL || !pl_sd->state.buyingstore || pl_sd->buyer_id != buyer_id )
+ {// not online, not buying or not same store
+ clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, 0);
+ return;
+ }
+
+ if( !searchstore_queryremote(sd, account_id) && ( sd->bl.m != pl_sd->bl.m || !check_distance_bl(&sd->bl, &pl_sd->bl, AREA_SIZE) ) )
+ {// out of view range
+ clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, 0);
+ return;
+ }
+
+ searchstore_clearremote(sd);
+
+ if( pl_sd->status.zeny < pl_sd->buyingstore.zenylimit )
+ {// buyer lost zeny in the mean time? fix the limit
+ pl_sd->buyingstore.zenylimit = pl_sd->status.zeny;
+ }
+ weight = pl_sd->weight;
+
+ // check item list
+ for( i = 0; i < count; i++ )
+ {// itemlist: <index>.W <name id>.W <amount>.W
+ unsigned short nameid, amount;
+ int index;
+
+ index = RBUFW(itemlist,i*6+0)-2;
+ nameid = RBUFW(itemlist,i*6+2);
+ amount = RBUFW(itemlist,i*6+4);
+
+ if( i )
+ {// duplicate check. as the client does this too, only malicious intent should be caught here
+ ARR_FIND( 0, i, k, RBUFW(itemlist,k*6+0)-2 == index );
+ if( k != i )
+ {// duplicate
+ ShowWarning("buyingstore_trade: Found duplicate item on selling list (prevnameid=%hu, prevamount=%hu, nameid=%hu, amount=%hu, account_id=%d, char_id=%d).\n",
+ RBUFW(itemlist,k*6+2), RBUFW(itemlist,k*6+4), nameid, amount, sd->status.account_id, sd->status.char_id);
+ clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid);
+ return;
+ }
+ }
+
+ if( index < 0 || index >= ARRAYLENGTH(sd->status.inventory) || sd->inventory_data[index] == NULL || sd->status.inventory[index].nameid != nameid || sd->status.inventory[index].amount < amount )
+ {// invalid input
+ clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid);
+ return;
+ }
+
+ if( sd->status.inventory[index].expire_time || !itemdb_cantrade(&sd->status.inventory[index], pc_get_group_level(sd), pc_get_group_level(pl_sd)) || memcmp(sd->status.inventory[index].card, buyingstore_blankslots, sizeof(buyingstore_blankslots)) )
+ {// non-tradable item
+ clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid);
+ return;
+ }
+
+ ARR_FIND( 0, pl_sd->buyingstore.slots, listidx, pl_sd->buyingstore.items[listidx].nameid == nameid );
+ if( listidx == pl_sd->buyingstore.slots || pl_sd->buyingstore.items[listidx].amount == 0 )
+ {// there is no such item or the buyer has already bought all of them
+ clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid);
+ return;
+ }
+
+ if( pl_sd->buyingstore.items[listidx].amount < amount )
+ {// buyer does not need that much of the item
+ clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_COUNT, nameid);
+ return;
+ }
+
+ if( pc_checkadditem(pl_sd, nameid, amount) == ADDITEM_OVERAMOUNT )
+ {// buyer does not have enough space for this item
+ clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid);
+ return;
+ }
+
+ if( amount*(unsigned int)sd->inventory_data[index]->weight > pl_sd->max_weight-weight )
+ {// normally this is not supposed to happen, as the total weight is
+ // checked upon creation, but the buyer could have gained items
+ clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid);
+ return;
+ }
+ weight+= amount*sd->inventory_data[index]->weight;
+
+ if( amount*pl_sd->buyingstore.items[listidx].price > pl_sd->buyingstore.zenylimit-zeny )
+ {// buyer does not have enough zeny
+ clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_ZENY, nameid);
+ return;
+ }
+ zeny+= amount*pl_sd->buyingstore.items[listidx].price;
+ }
+
+ // process item list
+ for( i = 0; i < count; i++ )
+ {// itemlist: <index>.W <name id>.W <amount>.W
+ unsigned short nameid, amount;
+ int index;
+
+ index = RBUFW(itemlist,i*6+0)-2;
+ nameid = RBUFW(itemlist,i*6+2);
+ amount = RBUFW(itemlist,i*6+4);
+
+ ARR_FIND( 0, pl_sd->buyingstore.slots, listidx, pl_sd->buyingstore.items[listidx].nameid == nameid );
+ zeny = amount*pl_sd->buyingstore.items[listidx].price;
+
+ // move item
+ pc_additem(pl_sd, &sd->status.inventory[index], amount, LOG_TYPE_BUYING_STORE);
+ pc_delitem(sd, index, amount, 1, 0, LOG_TYPE_BUYING_STORE);
+ pl_sd->buyingstore.items[listidx].amount-= amount;
+
+ // pay up
+ pc_payzeny(pl_sd, zeny, LOG_TYPE_BUYING_STORE, sd);
+ pc_getzeny(sd, zeny, LOG_TYPE_BUYING_STORE, pl_sd);
+ pl_sd->buyingstore.zenylimit-= zeny;
+
+ // notify clients
+ clif_buyingstore_delete_item(sd, index, amount, pl_sd->buyingstore.items[listidx].price);
+ clif_buyingstore_update_item(pl_sd, nameid, amount);
+ }
+
+ // check whether or not there is still something to buy
+ ARR_FIND( 0, pl_sd->buyingstore.slots, i, pl_sd->buyingstore.items[i].amount != 0 );
+ if( i == pl_sd->buyingstore.slots )
+ {// everything was bought
+ clif_buyingstore_trade_failed_buyer(pl_sd, BUYINGSTORE_TRADE_BUYER_NO_ITEMS);
+ }
+ else if( pl_sd->buyingstore.zenylimit == 0 )
+ {// zeny limit reached
+ clif_buyingstore_trade_failed_buyer(pl_sd, BUYINGSTORE_TRADE_BUYER_ZENY);
+ }
+ else
+ {// continue buying
+ return;
+ }
+
+ // cannot continue buying
+ buyingstore_close(pl_sd);
+
+ // remove auto-trader
+ if( pl_sd->state.autotrade )
+ {
+ map_quit(pl_sd);
+ }
}
/// Checks if an item is being bought in given player's buying store.
-bool buyingstore_search(struct map_session_data *sd, unsigned short nameid)
+bool buyingstore_search(struct map_session_data* sd, unsigned short nameid)
{
- unsigned int i;
+ unsigned int i;
- if (!sd->state.buyingstore) {
- // not buying
- return false;
- }
+ if( !sd->state.buyingstore )
+ {// not buying
+ return false;
+ }
- ARR_FIND(0, sd->buyingstore.slots, i, sd->buyingstore.items[i].nameid == nameid && sd->buyingstore.items[i].amount);
- if (i == sd->buyingstore.slots) {
- // not found
- return false;
- }
+ ARR_FIND( 0, sd->buyingstore.slots, i, sd->buyingstore.items[i].nameid == nameid && sd->buyingstore.items[i].amount );
+ if( i == sd->buyingstore.slots )
+ {// not found
+ return false;
+ }
- return true;
+ return true;
}
/// Searches for all items in a buyingstore, that match given ids, price and possible cards.
/// @return Whether or not the search should be continued.
-bool buyingstore_searchall(struct map_session_data *sd, const struct s_search_store_search *s)
+bool buyingstore_searchall(struct map_session_data* sd, const struct s_search_store_search* s)
{
- unsigned int i, idx;
- struct s_buyingstore_item *it;
-
- if (!sd->state.buyingstore) {
- // not buying
- return true;
- }
-
- for (idx = 0; idx < s->item_count; idx++) {
- ARR_FIND(0, sd->buyingstore.slots, i, sd->buyingstore.items[i].nameid == s->itemlist[idx] && sd->buyingstore.items[i].amount);
- if (i == sd->buyingstore.slots) {
- // not found
- continue;
- }
- it = &sd->buyingstore.items[i];
-
- if (s->min_price && s->min_price > (unsigned int)it->price) {
- // too low price
- continue;
- }
-
- if (s->max_price && s->max_price < (unsigned int)it->price) {
- // too high price
- continue;
- }
-
- if (s->card_count) {
- // ignore cards, as there cannot be any
- ;
- }
-
- if (!searchstore_result(s->search_sd, sd->buyer_id, sd->status.account_id, sd->message, it->nameid, it->amount, it->price, buyingstore_blankslots, 0)) {
- // result set full
- return false;
- }
- }
-
- return true;
+ unsigned int i, idx;
+ struct s_buyingstore_item* it;
+
+ if( !sd->state.buyingstore )
+ {// not buying
+ return true;
+ }
+
+ for( idx = 0; idx < s->item_count; idx++ )
+ {
+ ARR_FIND( 0, sd->buyingstore.slots, i, sd->buyingstore.items[i].nameid == s->itemlist[idx] && sd->buyingstore.items[i].amount );
+ if( i == sd->buyingstore.slots )
+ {// not found
+ continue;
+ }
+ it = &sd->buyingstore.items[i];
+
+ if( s->min_price && s->min_price > (unsigned int)it->price )
+ {// too low price
+ continue;
+ }
+
+ if( s->max_price && s->max_price < (unsigned int)it->price )
+ {// too high price
+ continue;
+ }
+
+ if( s->card_count )
+ {// ignore cards, as there cannot be any
+ ;
+ }
+
+ if( !searchstore_result(s->search_sd, sd->buyer_id, sd->status.account_id, sd->message, it->nameid, it->amount, it->price, buyingstore_blankslots, 0) )
+ {// result set full
+ return false;
+ }
+ }
+
+ return true;
}
diff --git a/src/map/buyingstore.h b/src/map/buyingstore.h
index 52e7a664a..0ed6e5457 100644
--- a/src/map/buyingstore.h
+++ b/src/map/buyingstore.h
@@ -8,24 +8,26 @@ struct s_search_store_search;
#define MAX_BUYINGSTORE_SLOTS 5
-struct s_buyingstore_item {
- int price;
- unsigned short amount;
- unsigned short nameid;
+struct s_buyingstore_item
+{
+ int price;
+ unsigned short amount;
+ unsigned short nameid;
};
-struct s_buyingstore {
- struct s_buyingstore_item items[MAX_BUYINGSTORE_SLOTS];
- int zenylimit;
- unsigned char slots;
+struct s_buyingstore
+{
+ struct s_buyingstore_item items[MAX_BUYINGSTORE_SLOTS];
+ int zenylimit;
+ unsigned char slots;
};
-bool buyingstore_setup(struct map_session_data *sd, unsigned char slots);
-void buyingstore_create(struct map_session_data *sd, int zenylimit, unsigned char result, const char *storename, const uint8 *itemlist, unsigned int count);
-void buyingstore_close(struct map_session_data *sd);
-void buyingstore_open(struct map_session_data *sd, int account_id);
-void buyingstore_trade(struct map_session_data *sd, int account_id, unsigned int buyer_id, const uint8 *itemlist, unsigned int count);
-bool buyingstore_search(struct map_session_data *sd, unsigned short nameid);
-bool buyingstore_searchall(struct map_session_data *sd, const struct s_search_store_search *s);
+bool buyingstore_setup(struct map_session_data* sd, unsigned char slots);
+void buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned char result, const char* storename, const uint8* itemlist, unsigned int count);
+void buyingstore_close(struct map_session_data* sd);
+void buyingstore_open(struct map_session_data* sd, int account_id);
+void buyingstore_trade(struct map_session_data* sd, int account_id, unsigned int buyer_id, const uint8* itemlist, unsigned int count);
+bool buyingstore_search(struct map_session_data* sd, unsigned short nameid);
+bool buyingstore_searchall(struct map_session_data* sd, const struct s_search_store_search* s);
#endif // _BUYINGSTORE_H_
diff --git a/src/map/chat.c b/src/map/chat.c
index a65714ce1..dfeb16cad 100644
--- a/src/map/chat.c
+++ b/src/map/chat.c
@@ -24,136 +24,144 @@ int chat_triggerevent(struct chat_data *cd); // forward declaration
/// Initializes a chatroom object (common functionality for both pc and npc chatrooms).
/// Returns a chatroom object on success, or NULL on failure.
-static struct chat_data *chat_createchat(struct block_list *bl, const char *title, const char *pass, int limit, bool pub, int trigger, const char *ev, int zeny, int minLvl, int maxLvl) {
- struct chat_data *cd;
- nullpo_retr(NULL, bl);
-
- cd = (struct chat_data *) aMalloc(sizeof(struct chat_data));
-
- safestrncpy(cd->title, title, sizeof(cd->title));
- safestrncpy(cd->pass, pass, sizeof(cd->pass));
- cd->pub = pub;
- cd->users = 0;
- cd->limit = min(limit, ARRAYLENGTH(cd->usersd));
- cd->trigger = trigger;
- cd->zeny = zeny;
- cd->minLvl = minLvl;
- cd->maxLvl = maxLvl;
- memset(cd->usersd, 0, sizeof(cd->usersd));
- cd->owner = bl;
- safestrncpy(cd->npc_event, ev, sizeof(cd->npc_event));
-
- cd->bl.id = map_get_new_object_id();
- cd->bl.m = bl->m;
- cd->bl.x = bl->x;
- cd->bl.y = bl->y;
- cd->bl.type = BL_CHAT;
- cd->bl.next = cd->bl.prev = NULL;
-
- if (cd->bl.id == 0) {
- aFree(cd);
- cd = NULL;
- }
-
- map_addiddb(&cd->bl);
-
- if (bl->type != BL_NPC)
- cd->kick_list = idb_alloc(DB_OPT_BASE);
-
- return cd;
+static struct chat_data* chat_createchat(struct block_list* bl, const char* title, const char* pass, int limit, bool pub, int trigger, const char* ev, int zeny, int minLvl, int maxLvl)
+{
+ struct chat_data* cd;
+ nullpo_retr(NULL, bl);
+
+ cd = (struct chat_data *) aMalloc(sizeof(struct chat_data));
+
+ safestrncpy(cd->title, title, sizeof(cd->title));
+ safestrncpy(cd->pass, pass, sizeof(cd->pass));
+ cd->pub = pub;
+ cd->users = 0;
+ cd->limit = min(limit, ARRAYLENGTH(cd->usersd));
+ cd->trigger = trigger;
+ cd->zeny = zeny;
+ cd->minLvl = minLvl;
+ cd->maxLvl = maxLvl;
+ memset(cd->usersd, 0, sizeof(cd->usersd));
+ cd->owner = bl;
+ safestrncpy(cd->npc_event, ev, sizeof(cd->npc_event));
+
+ cd->bl.id = map_get_new_object_id();
+ cd->bl.m = bl->m;
+ cd->bl.x = bl->x;
+ cd->bl.y = bl->y;
+ cd->bl.type = BL_CHAT;
+ cd->bl.next = cd->bl.prev = NULL;
+
+ if( cd->bl.id == 0 )
+ {
+ aFree(cd);
+ cd = NULL;
+ }
+
+ map_addiddb(&cd->bl);
+
+ if( bl->type != BL_NPC )
+ cd->kick_list = idb_alloc(DB_OPT_BASE);
+
+ return cd;
}
/*==========================================
* player chatroom creation
*------------------------------------------*/
-int chat_createpcchat(struct map_session_data *sd, const char *title, const char *pass, int limit, bool pub)
+int chat_createpcchat(struct map_session_data* sd, const char* title, const char* pass, int limit, bool pub)
{
- struct chat_data *cd;
- nullpo_ret(sd);
-
- if (sd->chatID)
- return 0; //Prevent people abusing the chat system by creating multiple chats, as pointed out by End of Exam. [Skotlex]
-
- if (sd->state.vending || sd->state.buyingstore) {
- // not chat, when you already have a store open
- return 0;
- }
-
- if (map[sd->bl.m].flag.nochat) {
- clif_displaymessage(sd->fd, msg_txt(281));
- return 0; //Can't create chatrooms on this map.
- }
-
- if (map_getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKNOCHAT)) {
- clif_displaymessage(sd->fd, msg_txt(665));
- return 0;
- }
-
- pc_stop_walking(sd,1);
-
- cd = chat_createchat(&sd->bl, title, pass, limit, pub, 0, "", 0, 1, MAX_LEVEL);
- if (cd) {
- cd->users = 1;
- cd->usersd[0] = sd;
- pc_setchatid(sd,cd->bl.id);
- clif_createchat(sd,0);
- clif_dispchat(cd,0);
- } else
- clif_createchat(sd,1);
-
- return 0;
+ struct chat_data* cd;
+ nullpo_ret(sd);
+
+ if( sd->chatID )
+ return 0; //Prevent people abusing the chat system by creating multiple chats, as pointed out by End of Exam. [Skotlex]
+
+ if( sd->state.vending || sd->state.buyingstore )
+ {// not chat, when you already have a store open
+ return 0;
+ }
+
+ if( map[sd->bl.m].flag.nochat )
+ {
+ clif_displaymessage(sd->fd, msg_txt(281));
+ return 0; //Can't create chatrooms on this map.
+ }
+
+ if( map_getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKNOCHAT) )
+ {
+ clif_displaymessage (sd->fd, msg_txt(665));
+ return 0;
+ }
+
+ pc_stop_walking(sd,1);
+
+ cd = chat_createchat(&sd->bl, title, pass, limit, pub, 0, "", 0, 1, MAX_LEVEL);
+ if( cd )
+ {
+ cd->users = 1;
+ cd->usersd[0] = sd;
+ pc_setchatid(sd,cd->bl.id);
+ clif_createchat(sd,0);
+ clif_dispchat(cd,0);
+ }
+ else
+ clif_createchat(sd,1);
+
+ return 0;
}
/*==========================================
* join an existing chatroom
*------------------------------------------*/
-int chat_joinchat(struct map_session_data *sd, int chatid, const char *pass)
+int chat_joinchat(struct map_session_data* sd, int chatid, const char* pass)
{
- struct chat_data *cd;
+ struct chat_data* cd;
- nullpo_ret(sd);
- cd = (struct chat_data *)map_id2bl(chatid);
+ nullpo_ret(sd);
+ cd = (struct chat_data*)map_id2bl(chatid);
- if (cd == NULL || cd->bl.type != BL_CHAT || cd->bl.m != sd->bl.m || sd->state.vending || sd->state.buyingstore || sd->chatID || ((cd->owner->type == BL_NPC) ? cd->users+1 : cd->users) >= cd->limit) {
- clif_joinchatfail(sd,0);
- return 0;
- }
+ if( cd == NULL || cd->bl.type != BL_CHAT || cd->bl.m != sd->bl.m || sd->state.vending || sd->state.buyingstore || sd->chatID || ((cd->owner->type == BL_NPC) ? cd->users+1 : cd->users) >= cd->limit )
+ {
+ clif_joinchatfail(sd,0);
+ return 0;
+ }
- if (!cd->pub && strncmp(pass, cd->pass, sizeof(cd->pass)) != 0 && !pc_has_permission(sd, PC_PERM_JOIN_ALL_CHAT)) {
- clif_joinchatfail(sd,1);
- return 0;
- }
+ if( !cd->pub && strncmp(pass, cd->pass, sizeof(cd->pass)) != 0 && !pc_has_permission(sd, PC_PERM_JOIN_ALL_CHAT) )
+ {
+ clif_joinchatfail(sd,1);
+ return 0;
+ }
- if (sd->status.base_level < cd->minLvl || sd->status.base_level > cd->maxLvl) {
- if (sd->status.base_level < cd->minLvl)
- clif_joinchatfail(sd,5);
- else
- clif_joinchatfail(sd,6);
+ if( sd->status.base_level < cd->minLvl || sd->status.base_level > cd->maxLvl ) {
+ if(sd->status.base_level < cd->minLvl)
+ clif_joinchatfail(sd,5);
+ else
+ clif_joinchatfail(sd,6);
- return 0;
- }
+ return 0;
+ }
- if (sd->status.zeny < cd->zeny) {
- clif_joinchatfail(sd,4);
- return 0;
- }
+ if( sd->status.zeny < cd->zeny ) {
+ clif_joinchatfail(sd,4);
+ return 0;
+ }
- if (cd->owner->type != BL_NPC && idb_exists(cd->kick_list,sd->status.char_id)) {
- clif_joinchatfail(sd,2);//You have been kicked out of the room.
- return 0;
- }
+ if( cd->owner->type != BL_NPC && idb_exists(cd->kick_list,sd->status.char_id) ) {
+ clif_joinchatfail(sd,2);//You have been kicked out of the room.
+ return 0;
+ }
- pc_stop_walking(sd,1);
- cd->usersd[cd->users] = sd;
- cd->users++;
+ pc_stop_walking(sd,1);
+ cd->usersd[cd->users] = sd;
+ cd->users++;
- pc_setchatid(sd,cd->bl.id);
+ pc_setchatid(sd,cd->bl.id);
clif_joinchatok(sd, cd); //To the person who newly joined the list of all
- clif_addchat(cd, sd); //Reports To the person who already in the chat
- clif_dispchat(cd, 0); //Reported number of changes to the people around
+ clif_addchat(cd, sd); //Reports To the person who already in the chat
+ clif_dispchat(cd, 0); //Reported number of changes to the people around
- chat_triggerevent(cd); //Event
+ chat_triggerevent(cd); //Event
return 0;
}
@@ -162,213 +170,215 @@ int chat_joinchat(struct map_session_data *sd, int chatid, const char *pass)
/*==========================================
* leave a chatroom
*------------------------------------------*/
-int chat_leavechat(struct map_session_data *sd, bool kicked)
+int chat_leavechat(struct map_session_data* sd, bool kicked)
{
- struct chat_data *cd;
- int i;
- int leavechar;
-
- nullpo_retr(1, sd);
-
- cd = (struct chat_data *)map_id2bl(sd->chatID);
- if (cd == NULL) {
- pc_setchatid(sd, 0);
- return 1;
- }
-
- ARR_FIND(0, cd->users, i, cd->usersd[i] == sd);
- if (i == cd->users) {
- // Not found in the chatroom?
- pc_setchatid(sd, 0);
- return -1;
- }
-
- clif_leavechat(cd, sd, kicked);
- pc_setchatid(sd, 0);
- cd->users--;
-
- leavechar = i;
-
- for (i = leavechar; i < cd->users; i++)
- cd->usersd[i] = cd->usersd[i+1];
-
-
- if (cd->users == 0 && cd->owner->type == BL_PC) { // Delete empty chatroom
- struct skill_unit *unit = NULL;
- struct skill_unit_group *group = NULL;
-
- clif_clearchat(cd, 0);
- db_destroy(cd->kick_list);
- map_deliddb(&cd->bl);
- map_delblock(&cd->bl);
- map_freeblock(&cd->bl);
-
- unit = map_find_skill_unit_oncell(&sd->bl, sd->bl.x, sd->bl.y, AL_WARP, NULL, 0);
- group = (unit != NULL) ? unit->group : NULL;
- if (group != NULL)
- ext_skill_unit_onplace(unit, &sd->bl, group->tick);
-
- return 1;
- }
-
- if (leavechar == 0 && cd->owner->type == BL_PC) {
- // Set and announce new owner
- cd->owner = (struct block_list *) cd->usersd[0];
- clif_changechatowner(cd, cd->usersd[0]);
- clif_clearchat(cd, 0);
-
- //Adjust Chat location after owner has been changed.
- map_delblock(&cd->bl);
- cd->bl.x=cd->usersd[0]->bl.x;
- cd->bl.y=cd->usersd[0]->bl.y;
- map_addblock(&cd->bl);
-
- clif_dispchat(cd,0);
- } else
- clif_dispchat(cd,0); // refresh chatroom
-
- return 0;
+ struct chat_data* cd;
+ int i;
+ int leavechar;
+
+ nullpo_retr(1, sd);
+
+ cd = (struct chat_data*)map_id2bl(sd->chatID);
+ if( cd == NULL )
+ {
+ pc_setchatid(sd, 0);
+ return 1;
+ }
+
+ ARR_FIND( 0, cd->users, i, cd->usersd[i] == sd );
+ if ( i == cd->users )
+ { // Not found in the chatroom?
+ pc_setchatid(sd, 0);
+ return -1;
+ }
+
+ clif_leavechat(cd, sd, kicked);
+ pc_setchatid(sd, 0);
+ cd->users--;
+
+ leavechar = i;
+
+ for( i = leavechar; i < cd->users; i++ )
+ cd->usersd[i] = cd->usersd[i+1];
+
+
+ if( cd->users == 0 && cd->owner->type == BL_PC ) { // Delete empty chatroom
+ struct skill_unit* unit = NULL;
+ struct skill_unit_group* group = NULL;
+
+ clif_clearchat(cd, 0);
+ db_destroy(cd->kick_list);
+ map_deliddb(&cd->bl);
+ map_delblock(&cd->bl);
+ map_freeblock(&cd->bl);
+
+ unit = map_find_skill_unit_oncell(&sd->bl, sd->bl.x, sd->bl.y, AL_WARP, NULL, 0);
+ group = (unit != NULL) ? unit->group : NULL;
+ if (group != NULL)
+ ext_skill_unit_onplace(unit, &sd->bl, group->tick);
+
+ return 1;
+ }
+
+ if( leavechar == 0 && cd->owner->type == BL_PC )
+ { // Set and announce new owner
+ cd->owner = (struct block_list*) cd->usersd[0];
+ clif_changechatowner(cd, cd->usersd[0]);
+ clif_clearchat(cd, 0);
+
+ //Adjust Chat location after owner has been changed.
+ map_delblock( &cd->bl );
+ cd->bl.x=cd->usersd[0]->bl.x;
+ cd->bl.y=cd->usersd[0]->bl.y;
+ map_addblock( &cd->bl );
+
+ clif_dispchat(cd,0);
+ }
+ else
+ clif_dispchat(cd,0); // refresh chatroom
+
+ return 0;
}
/*==========================================
* change a chatroom's owner
*------------------------------------------*/
-int chat_changechatowner(struct map_session_data *sd, const char *nextownername)
+int chat_changechatowner(struct map_session_data* sd, const char* nextownername)
{
- struct chat_data *cd;
- struct map_session_data *tmpsd;
- int i;
+ struct chat_data* cd;
+ struct map_session_data* tmpsd;
+ int i;
- nullpo_retr(1, sd);
+ nullpo_retr(1, sd);
- cd = (struct chat_data *)map_id2bl(sd->chatID);
- if (cd == NULL || (struct block_list *) sd != cd->owner)
- return 1;
+ cd = (struct chat_data*)map_id2bl(sd->chatID);
+ if( cd == NULL || (struct block_list*) sd != cd->owner )
+ return 1;
- ARR_FIND(1, cd->users, i, strncmp(cd->usersd[i]->status.name, nextownername, NAME_LENGTH) == 0);
- if (i == cd->users)
- return -1; // name not found
+ ARR_FIND( 1, cd->users, i, strncmp(cd->usersd[i]->status.name, nextownername, NAME_LENGTH) == 0 );
+ if( i == cd->users )
+ return -1; // name not found
- // erase temporarily
- clif_clearchat(cd,0);
+ // erase temporarily
+ clif_clearchat(cd,0);
- // set new owner
- cd->owner = (struct block_list *) cd->usersd[i];
- clif_changechatowner(cd,cd->usersd[i]);
+ // set new owner
+ cd->owner = (struct block_list*) cd->usersd[i];
+ clif_changechatowner(cd,cd->usersd[i]);
- // swap the old and new owners' positions
- tmpsd = cd->usersd[i];
- cd->usersd[i] = cd->usersd[0];
- cd->usersd[0] = tmpsd;
+ // swap the old and new owners' positions
+ tmpsd = cd->usersd[i];
+ cd->usersd[i] = cd->usersd[0];
+ cd->usersd[0] = tmpsd;
- // set the new chatroom position
- map_delblock(&cd->bl);
- cd->bl.x = cd->owner->x;
- cd->bl.y = cd->owner->y;
- map_addblock(&cd->bl);
+ // set the new chatroom position
+ map_delblock( &cd->bl );
+ cd->bl.x = cd->owner->x;
+ cd->bl.y = cd->owner->y;
+ map_addblock( &cd->bl );
- // and display again
- clif_dispchat(cd,0);
+ // and display again
+ clif_dispchat(cd,0);
- return 0;
+ return 0;
}
/*==========================================
* change a chatroom's status (title, etc)
*------------------------------------------*/
-int chat_changechatstatus(struct map_session_data *sd, const char *title, const char *pass, int limit, bool pub)
+int chat_changechatstatus(struct map_session_data* sd, const char* title, const char* pass, int limit, bool pub)
{
- struct chat_data *cd;
+ struct chat_data* cd;
- nullpo_retr(1, sd);
+ nullpo_retr(1, sd);
- cd = (struct chat_data *)map_id2bl(sd->chatID);
- if (cd==NULL || (struct block_list *)sd != cd->owner)
- return 1;
+ cd = (struct chat_data*)map_id2bl(sd->chatID);
+ if( cd==NULL || (struct block_list *)sd != cd->owner )
+ return 1;
- safestrncpy(cd->title, title, CHATROOM_TITLE_SIZE);
- safestrncpy(cd->pass, pass, CHATROOM_PASS_SIZE);
- cd->limit = min(limit, ARRAYLENGTH(cd->usersd));
- cd->pub = pub;
+ safestrncpy(cd->title, title, CHATROOM_TITLE_SIZE);
+ safestrncpy(cd->pass, pass, CHATROOM_PASS_SIZE);
+ cd->limit = min(limit, ARRAYLENGTH(cd->usersd));
+ cd->pub = pub;
- clif_changechatstatus(cd);
- clif_dispchat(cd,0);
+ clif_changechatstatus(cd);
+ clif_dispchat(cd,0);
- return 0;
+ return 0;
}
/*==========================================
* kick an user from a chatroom
*------------------------------------------*/
-int chat_kickchat(struct map_session_data *sd, const char *kickusername)
+int chat_kickchat(struct map_session_data* sd, const char* kickusername)
{
- struct chat_data *cd;
- int i;
+ struct chat_data* cd;
+ int i;
- nullpo_retr(1, sd);
+ nullpo_retr(1, sd);
- cd = (struct chat_data *)map_id2bl(sd->chatID);
+ cd = (struct chat_data *)map_id2bl(sd->chatID);
+
+ if( cd==NULL || (struct block_list *)sd != cd->owner )
+ return -1;
- if (cd==NULL || (struct block_list *)sd != cd->owner)
- return -1;
+ ARR_FIND( 0, cd->users, i, strncmp(cd->usersd[i]->status.name, kickusername, NAME_LENGTH) == 0 );
+ if( i == cd->users )
+ return -1;
- ARR_FIND(0, cd->users, i, strncmp(cd->usersd[i]->status.name, kickusername, NAME_LENGTH) == 0);
- if (i == cd->users)
- return -1;
+ if (pc_has_permission(cd->usersd[i], PC_PERM_NO_CHAT_KICK))
+ return 0; //gm kick protection [Valaris]
+
+ idb_put(cd->kick_list,cd->usersd[i]->status.char_id,(void*)1);
- if (pc_has_permission(cd->usersd[i], PC_PERM_NO_CHAT_KICK))
- return 0; //gm kick protection [Valaris]
-
- idb_put(cd->kick_list,cd->usersd[i]->status.char_id,(void *)1);
-
- chat_leavechat(cd->usersd[i],1);
- return 0;
+ chat_leavechat(cd->usersd[i],1);
+ return 0;
}
/// Creates a chat room for the npc.
-int chat_createnpcchat(struct npc_data *nd, const char *title, int limit, bool pub, int trigger, const char *ev, int zeny, int minLvl, int maxLvl)
+int chat_createnpcchat(struct npc_data* nd, const char* title, int limit, bool pub, int trigger, const char* ev, int zeny, int minLvl, int maxLvl)
{
- struct chat_data *cd;
- nullpo_ret(nd);
+ struct chat_data* cd;
+ nullpo_ret(nd);
- if (nd->chat_id) {
- ShowError("chat_createnpcchat: npc '%s' already has a chatroom, cannot create new one!\n", nd->exname);
- return 0;
- }
+ if( nd->chat_id ) {
+ ShowError("chat_createnpcchat: npc '%s' already has a chatroom, cannot create new one!\n", nd->exname);
+ return 0;
+ }
- if (zeny > MAX_ZENY || maxLvl > MAX_LEVEL) {
- ShowError("chat_createnpcchat: npc '%s' has a required lvl or amount of zeny over the max limit!\n", nd->exname);
- return 0;
- }
+ if( zeny > MAX_ZENY || maxLvl > MAX_LEVEL ) {
+ ShowError("chat_createnpcchat: npc '%s' has a required lvl or amount of zeny over the max limit!\n", nd->exname);
+ return 0;
+ }
- cd = chat_createchat(&nd->bl, title, "", limit, pub, trigger, ev, zeny, minLvl, maxLvl);
+ cd = chat_createchat(&nd->bl, title, "", limit, pub, trigger, ev, zeny, minLvl, maxLvl);
- if (cd) {
- nd->chat_id = cd->bl.id;
- clif_dispchat(cd,0);
- }
+ if( cd ) {
+ nd->chat_id = cd->bl.id;
+ clif_dispchat(cd,0);
+ }
- return 0;
+ return 0;
}
/// Removes the chatroom from the npc.
-int chat_deletenpcchat(struct npc_data *nd)
+int chat_deletenpcchat(struct npc_data* nd)
{
- struct chat_data *cd;
- nullpo_ret(nd);
-
- cd = (struct chat_data *)map_id2bl(nd->chat_id);
- if (cd == NULL)
- return 0;
-
- chat_npckickall(cd);
- clif_clearchat(cd, 0);
- map_deliddb(&cd->bl);
- map_delblock(&cd->bl);
- map_freeblock(&cd->bl);
- nd->chat_id = 0;
-
- return 0;
+ struct chat_data *cd;
+ nullpo_ret(nd);
+
+ cd = (struct chat_data*)map_id2bl(nd->chat_id);
+ if( cd == NULL )
+ return 0;
+
+ chat_npckickall(cd);
+ clif_clearchat(cd, 0);
+ map_deliddb(&cd->bl);
+ map_delblock(&cd->bl);
+ map_freeblock(&cd->bl);
+ nd->chat_id = 0;
+
+ return 0;
}
/*==========================================
@@ -376,40 +386,40 @@ int chat_deletenpcchat(struct npc_data *nd)
*------------------------------------------*/
int chat_triggerevent(struct chat_data *cd)
{
- nullpo_ret(cd);
+ nullpo_ret(cd);
- if (cd->users >= cd->trigger && cd->npc_event[0])
- npc_event_do(cd->npc_event);
- return 0;
+ if( cd->users >= cd->trigger && cd->npc_event[0] )
+ npc_event_do(cd->npc_event);
+ return 0;
}
/// Enables the event of the chat room.
/// At most, 127 users are needed to trigger the event.
-int chat_enableevent(struct chat_data *cd)
+int chat_enableevent(struct chat_data* cd)
{
- nullpo_ret(cd);
+ nullpo_ret(cd);
- cd->trigger &= 0x7f;
- chat_triggerevent(cd);
- return 0;
+ cd->trigger &= 0x7f;
+ chat_triggerevent(cd);
+ return 0;
}
/// Disables the event of the chat room
-int chat_disableevent(struct chat_data *cd)
+int chat_disableevent(struct chat_data* cd)
{
- nullpo_ret(cd);
+ nullpo_ret(cd);
- cd->trigger |= 0x80;
- return 0;
+ cd->trigger |= 0x80;
+ return 0;
}
/// Kicks all the users from the chat room.
-int chat_npckickall(struct chat_data *cd)
+int chat_npckickall(struct chat_data* cd)
{
- nullpo_ret(cd);
+ nullpo_ret(cd);
- while (cd->users > 0)
- chat_leavechat(cd->usersd[cd->users-1],0);
+ while( cd->users > 0 )
+ chat_leavechat(cd->usersd[cd->users-1],0);
- return 0;
+ return 0;
}
diff --git a/src/map/chat.h b/src/map/chat.h
index 3e7d0d283..cb2e6ecd9 100644
--- a/src/map/chat.h
+++ b/src/map/chat.h
@@ -10,34 +10,34 @@ struct chat_data;
struct chat_data {
- struct block_list bl; // data for this map object
- char title[CHATROOM_TITLE_SIZE]; // room title
- char pass[CHATROOM_PASS_SIZE]; // password
- bool pub; // private/public flag
- uint8 users; // current user count
- uint8 limit; // join limit
- uint8 trigger; // number of users needed to trigger event
- uint32 zeny; // required zeny to join
- uint32 minLvl; // minimum base level to join
- uint32 maxLvl; // maximum base level allowed to join
- struct map_session_data *usersd[20];
- struct block_list *owner;
- char npc_event[EVENT_NAME_LENGTH];
- DBMap *kick_list; //DBMap of users who were kicked from this chat
+ struct block_list bl; // data for this map object
+ char title[CHATROOM_TITLE_SIZE]; // room title
+ char pass[CHATROOM_PASS_SIZE]; // password
+ bool pub; // private/public flag
+ uint8 users; // current user count
+ uint8 limit; // join limit
+ uint8 trigger; // number of users needed to trigger event
+ uint32 zeny; // required zeny to join
+ uint32 minLvl; // minimum base level to join
+ uint32 maxLvl; // maximum base level allowed to join
+ struct map_session_data* usersd[20];
+ struct block_list* owner;
+ char npc_event[EVENT_NAME_LENGTH];
+ DBMap* kick_list; //DBMap of users who were kicked from this chat
};
-int chat_createpcchat(struct map_session_data *sd, const char *title, const char *pass, int limit, bool pub);
-int chat_joinchat(struct map_session_data *sd, int chatid, const char *pass);
-int chat_leavechat(struct map_session_data *sd, bool kicked);
-int chat_changechatowner(struct map_session_data *sd, const char *nextownername);
-int chat_changechatstatus(struct map_session_data *sd, const char *title, const char *pass, int limit, bool pub);
-int chat_kickchat(struct map_session_data *sd, const char *kickusername);
+int chat_createpcchat(struct map_session_data* sd, const char* title, const char* pass, int limit, bool pub);
+int chat_joinchat(struct map_session_data* sd, int chatid, const char* pass);
+int chat_leavechat(struct map_session_data* sd, bool kicked);
+int chat_changechatowner(struct map_session_data* sd, const char* nextownername);
+int chat_changechatstatus(struct map_session_data* sd, const char* title, const char* pass, int limit, bool pub);
+int chat_kickchat(struct map_session_data* sd, const char* kickusername);
-int chat_createnpcchat(struct npc_data *nd, const char *title, int limit, bool pub, int trigger, const char *ev, int zeny, int minLvl, int maxLvl);
-int chat_deletenpcchat(struct npc_data *nd);
-int chat_enableevent(struct chat_data *cd);
-int chat_disableevent(struct chat_data *cd);
-int chat_npckickall(struct chat_data *cd);
+int chat_createnpcchat(struct npc_data* nd, const char* title, int limit, bool pub, int trigger, const char* ev, int zeny, int minLvl, int maxLvl);
+int chat_deletenpcchat(struct npc_data* nd);
+int chat_enableevent(struct chat_data* cd);
+int chat_disableevent(struct chat_data* cd);
+int chat_npckickall(struct chat_data* cd);
#endif /* _CHAT_H_ */
diff --git a/src/map/chrif.c b/src/map/chrif.c
index 8ba47a601..1575e11f4 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -36,15 +36,15 @@
static int check_connect_char_server(int tid, unsigned int tick, int id, intptr_t data);
static struct eri *auth_db_ers; //For reutilizing player login structures.
-static DBMap *auth_db; // int id -> struct auth_node*
+static DBMap* auth_db; // int id -> struct auth_node*
static const int packet_len_table[0x3d] = { // U - used, F - free
- 60, 3,-1,27,10,-1, 6,-1, // 2af8-2aff: U->2af8, U->2af9, U->2afa, U->2afb, U->2afc, U->2afd, U->2afe, U->2aff
- 6,-1,18, 7,-1,39,30, 10, // 2b00-2b07: U->2b00, U->2b01, U->2b02, U->2b03, U->2b04, U->2b05, U->2b06, U->2b07
- 6,30, 0, 0,86, 7,44,34, // 2b08-2b0f: U->2b08, U->2b09, F->2b0a, F->2b0b, U->2b0c, U->2b0d, U->2b0e, U->2b0f
- 11,10,10, 0,11, 0,266,10, // 2b10-2b17: U->2b10, U->2b11, U->2b12, F->2b13, U->2b14, F->2b15, U->2b16, U->2b17
- 2,10, 2,-1,-1,-1, 2, 7, // 2b18-2b1f: U->2b18, U->2b19, U->2b1a, U->2b1b, U->2b1c, U->2b1d, U->2b1e, U->2b1f
- -1,10, 8, 2, 2,14,19,19, // 2b20-2b27: U->2b20, U->2b21, U->2b22, U->2b23, U->2b24, U->2b25, U->2b26, U->2b27
+ 60, 3,-1,27,10,-1, 6,-1, // 2af8-2aff: U->2af8, U->2af9, U->2afa, U->2afb, U->2afc, U->2afd, U->2afe, U->2aff
+ 6,-1,18, 7,-1,39,30, 10, // 2b00-2b07: U->2b00, U->2b01, U->2b02, U->2b03, U->2b04, U->2b05, U->2b06, U->2b07
+ 6,30, 0, 0,86, 7,44,34, // 2b08-2b0f: U->2b08, U->2b09, F->2b0a, F->2b0b, U->2b0c, U->2b0d, U->2b0e, U->2b0f
+ 11,10,10, 0,11, 0,266,10, // 2b10-2b17: U->2b10, U->2b11, U->2b12, F->2b13, U->2b14, F->2b15, U->2b16, U->2b17
+ 2,10, 2,-1,-1,-1, 2, 7, // 2b18-2b1f: U->2b18, U->2b19, U->2b1a, U->2b1b, U->2b1c, U->2b1d, U->2b1e, U->2b1f
+ -1,10, 8, 2, 2,14,19,19, // 2b20-2b27: U->2b20, U->2b21, U->2b22, U->2b23, U->2b24, U->2b25, U->2b26, U->2b27
};
//Used Packets:
@@ -116,163 +116,151 @@ int other_mapserver_count=0; //Holds count of how many other map servers are onl
/// Resets all the data.
-void chrif_reset(void)
-{
- // TODO kick everyone out and reset everything [FlavioJS]
- exit(EXIT_FAILURE);
+void chrif_reset(void) {
+ // TODO kick everyone out and reset everything [FlavioJS]
+ exit(EXIT_FAILURE);
}
/// Checks the conditions for the server to stop.
/// Releases the cookie when all characters are saved.
/// If all the conditions are met, it stops the core loop.
-void chrif_check_shutdown(void)
-{
- if (runflag != MAPSERVER_ST_SHUTDOWN)
- return;
- if (auth_db->size(auth_db) > 0)
- return;
- runflag = CORE_ST_STOP;
-}
-
-struct auth_node *chrif_search(int account_id) {
- return (struct auth_node *)idb_get(auth_db, account_id);
-}
-
-struct auth_node *chrif_auth_check(int account_id, int char_id, enum sd_state state) {
- struct auth_node *node = chrif_search(account_id);
-
- return (node && node->char_id == char_id && node->state == state) ? node : NULL;
-}
-
-bool chrif_auth_delete(int account_id, int char_id, enum sd_state state)
-{
- struct auth_node *node;
-
- if ((node = chrif_auth_check(account_id, char_id, state))) {
- int fd = node->sd ? node->sd->fd : node->fd;
-
- if (session[fd] && session[fd]->session_data == node->sd)
- session[fd]->session_data = NULL;
-
- if (node->char_dat)
- aFree(node->char_dat);
-
- if (node->sd)
- aFree(node->sd);
-
- ers_free(auth_db_ers, node);
- idb_remove(auth_db,account_id);
-
- return true;
- }
- return false;
+void chrif_check_shutdown(void) {
+ if( runflag != MAPSERVER_ST_SHUTDOWN )
+ return;
+ if( auth_db->size(auth_db) > 0 )
+ return;
+ runflag = CORE_ST_STOP;
+}
+
+struct auth_node* chrif_search(int account_id) {
+ return (struct auth_node*)idb_get(auth_db, account_id);
+}
+
+struct auth_node* chrif_auth_check(int account_id, int char_id, enum sd_state state) {
+ struct auth_node *node = chrif_search(account_id);
+
+ return ( node && node->char_id == char_id && node->state == state ) ? node : NULL;
+}
+
+bool chrif_auth_delete(int account_id, int char_id, enum sd_state state) {
+ struct auth_node *node;
+
+ if ( (node = chrif_auth_check(account_id, char_id, state) ) ) {
+ int fd = node->sd ? node->sd->fd : node->fd;
+
+ if ( session[fd] && session[fd]->session_data == node->sd )
+ session[fd]->session_data = NULL;
+
+ if ( node->char_dat )
+ aFree(node->char_dat);
+
+ if ( node->sd )
+ aFree(node->sd);
+
+ ers_free(auth_db_ers, node);
+ idb_remove(auth_db,account_id);
+
+ return true;
+ }
+ return false;
}
//Moves the sd character to the auth_db structure.
-static bool chrif_sd_to_auth(TBL_PC *sd, enum sd_state state)
-{
- struct auth_node *node;
-
- if (chrif_search(sd->status.account_id))
- return false; //Already exists?
-
- node = ers_alloc(auth_db_ers, struct auth_node);
-
- memset(node, 0, sizeof(struct auth_node));
-
- node->account_id = sd->status.account_id;
- node->char_id = sd->status.char_id;
- node->login_id1 = sd->login_id1;
- node->login_id2 = sd->login_id2;
- node->sex = sd->status.sex;
- node->fd = sd->fd;
- node->sd = sd; //Data from logged on char.
- node->node_created = gettick(); //timestamp for node timeouts
- node->state = state;
-
- sd->state.active = 0;
-
- idb_put(auth_db, node->account_id, node);
-
- return true;
-}
-
-static bool chrif_auth_logout(TBL_PC *sd, enum sd_state state)
-{
-
- if (sd->fd && state == ST_LOGOUT) { //Disassociate player, and free it after saving ack returns. [Skotlex]
- //fd info must not be lost for ST_MAPCHANGE as a final packet needs to be sent to the player.
- if (session[sd->fd])
- session[sd->fd]->session_data = NULL;
- sd->fd = 0;
- }
-
- return chrif_sd_to_auth(sd, state);
-}
-
-bool chrif_auth_finished(TBL_PC *sd)
-{
- struct auth_node *node= chrif_search(sd->status.account_id);
-
- if (node && node->sd == sd && node->state == ST_LOGIN) {
- node->sd = NULL;
-
- return chrif_auth_delete(node->account_id, node->char_id, ST_LOGIN);
- }
-
- return false;
+static bool chrif_sd_to_auth(TBL_PC* sd, enum sd_state state) {
+ struct auth_node *node;
+
+ if ( chrif_search(sd->status.account_id) )
+ return false; //Already exists?
+
+ node = ers_alloc(auth_db_ers, struct auth_node);
+
+ memset(node, 0, sizeof(struct auth_node));
+
+ node->account_id = sd->status.account_id;
+ node->char_id = sd->status.char_id;
+ node->login_id1 = sd->login_id1;
+ node->login_id2 = sd->login_id2;
+ node->sex = sd->status.sex;
+ node->fd = sd->fd;
+ node->sd = sd; //Data from logged on char.
+ node->node_created = gettick(); //timestamp for node timeouts
+ node->state = state;
+
+ sd->state.active = 0;
+
+ idb_put(auth_db, node->account_id, node);
+
+ return true;
+}
+
+static bool chrif_auth_logout(TBL_PC* sd, enum sd_state state) {
+
+ if(sd->fd && state == ST_LOGOUT) { //Disassociate player, and free it after saving ack returns. [Skotlex]
+ //fd info must not be lost for ST_MAPCHANGE as a final packet needs to be sent to the player.
+ if ( session[sd->fd] )
+ session[sd->fd]->session_data = NULL;
+ sd->fd = 0;
+ }
+
+ return chrif_sd_to_auth(sd, state);
+}
+
+bool chrif_auth_finished(TBL_PC* sd) {
+ struct auth_node *node= chrif_search(sd->status.account_id);
+
+ if ( node && node->sd == sd && node->state == ST_LOGIN ) {
+ node->sd = NULL;
+
+ return chrif_auth_delete(node->account_id, node->char_id, ST_LOGIN);
+ }
+
+ return false;
}
// sets char-server's user id
-void chrif_setuserid(char *id)
-{
- memcpy(userid, id, NAME_LENGTH);
+void chrif_setuserid(char *id) {
+ memcpy(userid, id, NAME_LENGTH);
}
// sets char-server's password
-void chrif_setpasswd(char *pwd)
-{
- memcpy(passwd, pwd, NAME_LENGTH);
+void chrif_setpasswd(char *pwd) {
+ memcpy(passwd, pwd, NAME_LENGTH);
}
// security check, prints warning if using default password
-void chrif_checkdefaultlogin(void)
-{
- if (strcmp(userid, "s1")==0 && strcmp(passwd, "p1")==0) {
- ShowWarning("Using the default user/password s1/p1 is NOT RECOMMENDED.\n");
- ShowNotice("Please edit your 'login' table to create a proper inter-server user/password (gender 'S')\n");
- ShowNotice("and then edit your user/password in conf/map_athena.conf (or conf/import/map_conf.txt)\n");
- }
+void chrif_checkdefaultlogin(void) {
+ if (strcmp(userid, "s1")==0 && strcmp(passwd, "p1")==0) {
+ ShowWarning("Using the default user/password s1/p1 is NOT RECOMMENDED.\n");
+ ShowNotice("Please edit your 'login' table to create a proper inter-server user/password (gender 'S')\n");
+ ShowNotice("and then edit your user/password in conf/map_athena.conf (or conf/import/map_conf.txt)\n");
+ }
}
// sets char-server's ip address
-int chrif_setip(const char *ip)
-{
- char ip_str[16];
-
- if (!(char_ip = host2ip(ip))) {
- ShowWarning("Failed to Resolve Char Server Address! (%s)\n", ip);
-
- return 0;
- }
-
- strncpy(char_ip_str, ip, sizeof(char_ip_str));
-
- ShowInfo("Char Server IP Address : '"CL_WHITE"%s"CL_RESET"' -> '"CL_WHITE"%s"CL_RESET"'.\n", ip, ip2str(char_ip, ip_str));
-
- return 1;
+int chrif_setip(const char* ip) {
+ char ip_str[16];
+
+ if ( !( char_ip = host2ip(ip) ) ) {
+ ShowWarning("Failed to Resolve Char Server Address! (%s)\n", ip);
+
+ return 0;
+ }
+
+ strncpy(char_ip_str, ip, sizeof(char_ip_str));
+
+ ShowInfo("Char Server IP Address : '"CL_WHITE"%s"CL_RESET"' -> '"CL_WHITE"%s"CL_RESET"'.\n", ip, ip2str(char_ip, ip_str));
+
+ return 1;
}
// sets char-server's port number
-void chrif_setport(uint16 port)
-{
- char_port = port;
+void chrif_setport(uint16 port) {
+ char_port = port;
}
// says whether the char-server is connected or not
-int chrif_isconnected(void)
-{
- return (char_fd > 0 && session[char_fd] != NULL && chrif_state == 2);
+int chrif_isconnected(void) {
+ return (char_fd > 0 && session[char_fd] != NULL && chrif_state == 2);
}
/*==========================================
@@ -280,429 +268,413 @@ int chrif_isconnected(void)
* Flag = 1: Character is quitting
* Flag = 2: Character is changing map-servers
*------------------------------------------*/
-int chrif_save(struct map_session_data *sd, int flag)
-{
- nullpo_retr(-1, sd);
-
- pc_makesavestatus(sd);
-
- if (flag && sd->state.active) { //Store player data which is quitting
- //FIXME: SC are lost if there's no connection at save-time because of the way its related data is cleared immediately after this function. [Skotlex]
- if (chrif_isconnected())
- chrif_save_scdata(sd);
- if (!chrif_auth_logout(sd,flag == 1 ? ST_LOGOUT : ST_MAPCHANGE))
- ShowError("chrif_save: Failed to set up player %d:%d for proper quitting!\n", sd->status.account_id, sd->status.char_id);
- }
-
- chrif_check(-1); //Character is saved on reconnect.
-
- //For data sync
- if (sd->state.storage_flag == 2)
- storage_guild_storagesave(sd->status.account_id, sd->status.guild_id, flag);
-
- if (flag)
- sd->state.storage_flag = 0; //Force close it.
-
- //Saving of registry values.
- if (sd->state.reg_dirty&4)
- intif_saveregistry(sd, 3); //Save char regs
- if (sd->state.reg_dirty&2)
- intif_saveregistry(sd, 2); //Save account regs
- if (sd->state.reg_dirty&1)
- intif_saveregistry(sd, 1); //Save account2 regs
-
- WFIFOHEAD(char_fd, sizeof(sd->status) + 13);
- WFIFOW(char_fd,0) = 0x2b01;
- WFIFOW(char_fd,2) = sizeof(sd->status) + 13;
- WFIFOL(char_fd,4) = sd->status.account_id;
- WFIFOL(char_fd,8) = sd->status.char_id;
- WFIFOB(char_fd,12) = (flag==1)?1:0; //Flag to tell char-server this character is quitting.
- memcpy(WFIFOP(char_fd,13), &sd->status, sizeof(sd->status));
- WFIFOSET(char_fd, WFIFOW(char_fd,2));
-
- if (sd->status.pet_id > 0 && sd->pd)
- intif_save_petdata(sd->status.account_id,&sd->pd->pet);
- if (sd->hd && merc_is_hom_active(sd->hd))
- merc_save(sd->hd);
- if (sd->md && mercenary_get_lifetime(sd->md) > 0)
- mercenary_save(sd->md);
- if (sd->ed && elemental_get_lifetime(sd->ed) > 0)
- elemental_save(sd->ed);
- if (sd->save_quest)
- intif_quest_save(sd);
-
- return 0;
+int chrif_save(struct map_session_data *sd, int flag) {
+ nullpo_retr(-1, sd);
+
+ pc_makesavestatus(sd);
+
+ if (flag && sd->state.active) { //Store player data which is quitting
+ //FIXME: SC are lost if there's no connection at save-time because of the way its related data is cleared immediately after this function. [Skotlex]
+ if ( chrif_isconnected() )
+ chrif_save_scdata(sd);
+ if ( !chrif_auth_logout(sd,flag == 1 ? ST_LOGOUT : ST_MAPCHANGE) )
+ ShowError("chrif_save: Failed to set up player %d:%d for proper quitting!\n", sd->status.account_id, sd->status.char_id);
+ }
+
+ chrif_check(-1); //Character is saved on reconnect.
+
+ //For data sync
+ if (sd->state.storage_flag == 2)
+ storage_guild_storagesave(sd->status.account_id, sd->status.guild_id, flag);
+
+ if (flag)
+ sd->state.storage_flag = 0; //Force close it.
+
+ //Saving of registry values.
+ if (sd->state.reg_dirty&4)
+ intif_saveregistry(sd, 3); //Save char regs
+ if (sd->state.reg_dirty&2)
+ intif_saveregistry(sd, 2); //Save account regs
+ if (sd->state.reg_dirty&1)
+ intif_saveregistry(sd, 1); //Save account2 regs
+
+ WFIFOHEAD(char_fd, sizeof(sd->status) + 13);
+ WFIFOW(char_fd,0) = 0x2b01;
+ WFIFOW(char_fd,2) = sizeof(sd->status) + 13;
+ WFIFOL(char_fd,4) = sd->status.account_id;
+ WFIFOL(char_fd,8) = sd->status.char_id;
+ WFIFOB(char_fd,12) = (flag==1)?1:0; //Flag to tell char-server this character is quitting.
+ memcpy(WFIFOP(char_fd,13), &sd->status, sizeof(sd->status));
+ WFIFOSET(char_fd, WFIFOW(char_fd,2));
+
+ if( sd->status.pet_id > 0 && sd->pd )
+ intif_save_petdata(sd->status.account_id,&sd->pd->pet);
+ if( sd->hd && merc_is_hom_active(sd->hd) )
+ merc_save(sd->hd);
+ if( sd->md && mercenary_get_lifetime(sd->md) > 0 )
+ mercenary_save(sd->md);
+ if( sd->ed && elemental_get_lifetime(sd->ed) > 0 )
+ elemental_save(sd->ed);
+ if( sd->save_quest )
+ intif_quest_save(sd);
+
+ return 0;
}
// connects to char-server (plaintext)
-int chrif_connect(int fd)
-{
- ShowStatus("Logging in to char server...\n", char_fd);
- WFIFOHEAD(fd,60);
- WFIFOW(fd,0) = 0x2af8;
- memcpy(WFIFOP(fd,2), userid, NAME_LENGTH);
- memcpy(WFIFOP(fd,26), passwd, NAME_LENGTH);
- WFIFOL(fd,50) = 0;
- WFIFOL(fd,54) = htonl(clif_getip());
- WFIFOW(fd,58) = htons(clif_getport());
- WFIFOSET(fd,60);
+int chrif_connect(int fd) {
+ ShowStatus("Logging in to char server...\n", char_fd);
+ WFIFOHEAD(fd,60);
+ WFIFOW(fd,0) = 0x2af8;
+ memcpy(WFIFOP(fd,2), userid, NAME_LENGTH);
+ memcpy(WFIFOP(fd,26), passwd, NAME_LENGTH);
+ WFIFOL(fd,50) = 0;
+ WFIFOL(fd,54) = htonl(clif_getip());
+ WFIFOW(fd,58) = htons(clif_getport());
+ WFIFOSET(fd,60);
- return 0;
+ return 0;
}
// sends maps to char-server
-int chrif_sendmap(int fd)
-{
- int i;
-
- ShowStatus("Sending maps to char server...\n");
-
- // Sending normal maps, not instances
- WFIFOHEAD(fd, 4 + instance_start * 4);
- WFIFOW(fd,0) = 0x2afa;
- for (i = 0; i < instance_start; i++)
- WFIFOW(fd,4+i*4) = map[i].index;
- WFIFOW(fd,2) = 4 + i * 4;
- WFIFOSET(fd,WFIFOW(fd,2));
-
- return 0;
+int chrif_sendmap(int fd) {
+ int i;
+
+ ShowStatus("Sending maps to char server...\n");
+
+ // Sending normal maps, not instances
+ WFIFOHEAD(fd, 4 + instance_start * 4);
+ WFIFOW(fd,0) = 0x2afa;
+ for(i = 0; i < instance_start; i++)
+ WFIFOW(fd,4+i*4) = map[i].index;
+ WFIFOW(fd,2) = 4 + i * 4;
+ WFIFOSET(fd,WFIFOW(fd,2));
+
+ return 0;
}
// receive maps from some other map-server (relayed via char-server)
-int chrif_recvmap(int fd)
-{
- int i, j;
- uint32 ip = ntohl(RFIFOL(fd,4));
- uint16 port = ntohs(RFIFOW(fd,8));
-
- for (i = 10, j = 0; i < RFIFOW(fd,2); i += 4, j++) {
- map_setipport(RFIFOW(fd,i), ip, port);
- }
+int chrif_recvmap(int fd) {
+ int i, j;
+ uint32 ip = ntohl(RFIFOL(fd,4));
+ uint16 port = ntohs(RFIFOW(fd,8));
- if (battle_config.etc_log)
- ShowStatus("Received maps from %d.%d.%d.%d:%d (%d maps)\n", CONVIP(ip), port, j);
+ for(i = 10, j = 0; i < RFIFOW(fd,2); i += 4, j++) {
+ map_setipport(RFIFOW(fd,i), ip, port);
+ }
+
+ if (battle_config.etc_log)
+ ShowStatus("Received maps from %d.%d.%d.%d:%d (%d maps)\n", CONVIP(ip), port, j);
- other_mapserver_count++;
-
- return 0;
+ other_mapserver_count++;
+
+ return 0;
}
// remove specified maps (used when some other map-server disconnects)
-int chrif_removemap(int fd)
-{
- int i, j;
- uint32 ip = RFIFOL(fd,4);
- uint16 port = RFIFOW(fd,8);
-
- for (i = 10, j = 0; i < RFIFOW(fd, 2); i += 4, j++)
- map_eraseipport(RFIFOW(fd, i), ip, port);
+int chrif_removemap(int fd) {
+ int i, j;
+ uint32 ip = RFIFOL(fd,4);
+ uint16 port = RFIFOW(fd,8);
- other_mapserver_count--;
+ for(i = 10, j = 0; i < RFIFOW(fd, 2); i += 4, j++)
+ map_eraseipport(RFIFOW(fd, i), ip, port);
- if (battle_config.etc_log)
- ShowStatus("remove map of server %d.%d.%d.%d:%d (%d maps)\n", CONVIP(ip), port, j);
-
- return 0;
+ other_mapserver_count--;
+
+ if(battle_config.etc_log)
+ ShowStatus("remove map of server %d.%d.%d.%d:%d (%d maps)\n", CONVIP(ip), port, j);
+
+ return 0;
}
// received after a character has been "final saved" on the char-server
-static void chrif_save_ack(int fd)
-{
- chrif_auth_delete(RFIFOL(fd,2), RFIFOL(fd,6), ST_LOGOUT);
- chrif_check_shutdown();
+static void chrif_save_ack(int fd) {
+ chrif_auth_delete(RFIFOL(fd,2), RFIFOL(fd,6), ST_LOGOUT);
+ chrif_check_shutdown();
}
// request to move a character between mapservers
-int chrif_changemapserver(struct map_session_data *sd, uint32 ip, uint16 port)
-{
- nullpo_retr(-1, sd);
-
- if (other_mapserver_count < 1) {//No other map servers are online!
- clif_authfail_fd(sd->fd, 0);
- return -1;
- }
-
- chrif_check(-1);
-
- WFIFOHEAD(char_fd,35);
- WFIFOW(char_fd, 0) = 0x2b05;
- WFIFOL(char_fd, 2) = sd->bl.id;
- WFIFOL(char_fd, 6) = sd->login_id1;
- WFIFOL(char_fd,10) = sd->login_id2;
- WFIFOL(char_fd,14) = sd->status.char_id;
- WFIFOW(char_fd,18) = sd->mapindex;
- WFIFOW(char_fd,20) = sd->bl.x;
- WFIFOW(char_fd,22) = sd->bl.y;
- WFIFOL(char_fd,24) = htonl(ip);
- WFIFOW(char_fd,28) = htons(port);
- WFIFOB(char_fd,30) = sd->status.sex;
- WFIFOL(char_fd,31) = htonl(session[sd->fd]->client_addr);
- WFIFOL(char_fd,35) = sd->group_id;
- WFIFOSET(char_fd,39);
-
- return 0;
+int chrif_changemapserver(struct map_session_data* sd, uint32 ip, uint16 port) {
+ nullpo_retr(-1, sd);
+
+ if (other_mapserver_count < 1) {//No other map servers are online!
+ clif_authfail_fd(sd->fd, 0);
+ return -1;
+ }
+
+ chrif_check(-1);
+
+ WFIFOHEAD(char_fd,35);
+ WFIFOW(char_fd, 0) = 0x2b05;
+ WFIFOL(char_fd, 2) = sd->bl.id;
+ WFIFOL(char_fd, 6) = sd->login_id1;
+ WFIFOL(char_fd,10) = sd->login_id2;
+ WFIFOL(char_fd,14) = sd->status.char_id;
+ WFIFOW(char_fd,18) = sd->mapindex;
+ WFIFOW(char_fd,20) = sd->bl.x;
+ WFIFOW(char_fd,22) = sd->bl.y;
+ WFIFOL(char_fd,24) = htonl(ip);
+ WFIFOW(char_fd,28) = htons(port);
+ WFIFOB(char_fd,30) = sd->status.sex;
+ WFIFOL(char_fd,31) = htonl(session[sd->fd]->client_addr);
+ WFIFOL(char_fd,35) = sd->group_id;
+ WFIFOSET(char_fd,39);
+
+ return 0;
}
/// map-server change request acknowledgement (positive or negative)
/// R 2b06 <account_id>.L <login_id1>.L <login_id2>.L <char_id>.L <map_index>.W <x>.W <y>.W <ip>.L <port>.W
-int chrif_changemapserverack(int account_id, int login_id1, int login_id2, int char_id, short map_index, short x, short y, uint32 ip, uint16 port)
-{
- struct auth_node *node;
-
- if (!(node = chrif_auth_check(account_id, char_id, ST_MAPCHANGE)))
- return -1;
+int chrif_changemapserverack(int account_id, int login_id1, int login_id2, int char_id, short map_index, short x, short y, uint32 ip, uint16 port) {
+ struct auth_node *node;
+
+ if ( !( node = chrif_auth_check(account_id, char_id, ST_MAPCHANGE) ) )
+ return -1;
- if (!login_id1) {
- ShowError("map server change failed.\n");
- clif_authfail_fd(node->fd, 0);
- } else
- clif_changemapserver(node->sd, map_index, x, y, ntohl(ip), ntohs(port));
+ if ( !login_id1 ) {
+ ShowError("map server change failed.\n");
+ clif_authfail_fd(node->fd, 0);
+ } else
+ clif_changemapserver(node->sd, map_index, x, y, ntohl(ip), ntohs(port));
- //Player has been saved already, remove him from memory. [Skotlex]
- chrif_auth_delete(account_id, char_id, ST_MAPCHANGE);
+ //Player has been saved already, remove him from memory. [Skotlex]
+ chrif_auth_delete(account_id, char_id, ST_MAPCHANGE);
- return 0;
+ return 0;
}
/*==========================================
*
*------------------------------------------*/
-int chrif_connectack(int fd)
-{
- static bool char_init_done = false;
+int chrif_connectack(int fd) {
+ static bool char_init_done = false;
- if (RFIFOB(fd,2)) {
- ShowFatalError("Connection to char-server failed %d.\n", RFIFOB(fd,2));
- exit(EXIT_FAILURE);
- }
+ if (RFIFOB(fd,2)) {
+ ShowFatalError("Connection to char-server failed %d.\n", RFIFOB(fd,2));
+ exit(EXIT_FAILURE);
+ }
- ShowStatus("Successfully logged on to Char Server (Connection: '"CL_WHITE"%d"CL_RESET"').\n",fd);
- chrif_state = 1;
- chrif_connected = 1;
+ ShowStatus("Successfully logged on to Char Server (Connection: '"CL_WHITE"%d"CL_RESET"').\n",fd);
+ chrif_state = 1;
+ chrif_connected = 1;
- chrif_sendmap(fd);
+ chrif_sendmap(fd);
- ShowStatus("Event '"CL_WHITE"OnInterIfInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc_event_doall("OnInterIfInit"));
- if (!char_init_done) {
- char_init_done = true;
- ShowStatus("Event '"CL_WHITE"OnInterIfInitOnce"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc_event_doall("OnInterIfInitOnce"));
- guild_castle_map_init();
- }
+ ShowStatus("Event '"CL_WHITE"OnInterIfInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc_event_doall("OnInterIfInit"));
+ if( !char_init_done ) {
+ char_init_done = true;
+ ShowStatus("Event '"CL_WHITE"OnInterIfInitOnce"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc_event_doall("OnInterIfInitOnce"));
+ guild_castle_map_init();
+ }
- return 0;
+ return 0;
}
/**
* @see DBApply
*/
-static int chrif_reconnect(DBKey key, DBData *data, va_list ap)
-{
- struct auth_node *node = db_data2ptr(data);
-
- switch (node->state) {
- case ST_LOGIN:
- if (node->sd && node->char_dat == NULL) { //Since there is no way to request the char auth, make it fail.
- pc_authfail(node->sd);
- chrif_char_offline(node->sd);
- chrif_auth_delete(node->account_id, node->char_id, ST_LOGIN);
- }
- break;
- case ST_LOGOUT:
- //Re-send final save
- chrif_save(node->sd, 1);
- break;
- case ST_MAPCHANGE: { //Re-send map-change request.
- struct map_session_data *sd = node->sd;
- uint32 ip;
- uint16 port;
-
- if (map_mapname2ipport(sd->mapindex,&ip,&port) == 0)
- chrif_changemapserver(sd, ip, port);
- else //too much lag/timeout is the closest explanation for this error.
- clif_authfail_fd(sd->fd, 3);
-
- break;
- }
- }
-
- return 0;
+static int chrif_reconnect(DBKey key, DBData *data, va_list ap) {
+ struct auth_node *node = db_data2ptr(data);
+
+ switch (node->state) {
+ case ST_LOGIN:
+ if ( node->sd && node->char_dat == NULL ) {//Since there is no way to request the char auth, make it fail.
+ pc_authfail(node->sd);
+ chrif_char_offline(node->sd);
+ chrif_auth_delete(node->account_id, node->char_id, ST_LOGIN);
+ }
+ break;
+ case ST_LOGOUT:
+ //Re-send final save
+ chrif_save(node->sd, 1);
+ break;
+ case ST_MAPCHANGE: { //Re-send map-change request.
+ struct map_session_data *sd = node->sd;
+ uint32 ip;
+ uint16 port;
+
+ if( map_mapname2ipport(sd->mapindex,&ip,&port) == 0 )
+ chrif_changemapserver(sd, ip, port);
+ else //too much lag/timeout is the closest explanation for this error.
+ clif_authfail_fd(sd->fd, 3);
+
+ break;
+ }
+ }
+
+ return 0;
}
/// Called when all the connection steps are completed.
-void chrif_on_ready(void)
-{
- ShowStatus("Map Server is now online.\n");
-
- chrif_state = 2;
-
- chrif_check_shutdown();
+void chrif_on_ready(void) {
+ ShowStatus("Map Server is now online.\n");
+
+ chrif_state = 2;
+
+ chrif_check_shutdown();
- //If there are players online, send them to the char-server. [Skotlex]
- send_users_tochar();
+ //If there are players online, send them to the char-server. [Skotlex]
+ send_users_tochar();
- //Auth db reconnect handling
- auth_db->foreach(auth_db,chrif_reconnect);
+ //Auth db reconnect handling
+ auth_db->foreach(auth_db,chrif_reconnect);
- //Re-save any storages that were modified in the disconnection time. [Skotlex]
- do_reconnect_storage();
+ //Re-save any storages that were modified in the disconnection time. [Skotlex]
+ do_reconnect_storage();
- //Re-save any guild castles that were modified in the disconnection time.
- guild_castle_reconnect(-1, 0, 0);
+ //Re-save any guild castles that were modified in the disconnection time.
+ guild_castle_reconnect(-1, 0, 0);
}
/*==========================================
*
*------------------------------------------*/
-int chrif_sendmapack(int fd)
-{
+int chrif_sendmapack(int fd) {
+
+ if (RFIFOB(fd,2)) {
+ ShowFatalError("chrif : send map list to char server failed %d\n", RFIFOB(fd,2));
+ exit(EXIT_FAILURE);
+ }
- if (RFIFOB(fd,2)) {
- ShowFatalError("chrif : send map list to char server failed %d\n", RFIFOB(fd,2));
- exit(EXIT_FAILURE);
- }
-
- memcpy(wisp_server_name, RFIFOP(fd,3), NAME_LENGTH);
-
- chrif_on_ready();
-
- return 0;
+ memcpy(wisp_server_name, RFIFOP(fd,3), NAME_LENGTH);
+
+ chrif_on_ready();
+
+ return 0;
}
/*==========================================
* Request sc_data from charserver [Skotlex]
*------------------------------------------*/
-int chrif_scdata_request(int account_id, int char_id)
-{
-
+int chrif_scdata_request(int account_id, int char_id) {
+
#ifdef ENABLE_SC_SAVING
- chrif_check(-1);
+ chrif_check(-1);
- WFIFOHEAD(char_fd,10);
- WFIFOW(char_fd,0) = 0x2afc;
- WFIFOL(char_fd,2) = account_id;
- WFIFOL(char_fd,6) = char_id;
- WFIFOSET(char_fd,10);
+ WFIFOHEAD(char_fd,10);
+ WFIFOW(char_fd,0) = 0x2afc;
+ WFIFOL(char_fd,2) = account_id;
+ WFIFOL(char_fd,6) = char_id;
+ WFIFOSET(char_fd,10);
#endif
-
- return 0;
+
+ return 0;
}
/*==========================================
* Request auth confirmation
*------------------------------------------*/
-void chrif_authreq(struct map_session_data *sd)
-{
- struct auth_node *node= chrif_search(sd->bl.id);
-
- if (node != NULL || !chrif_isconnected()) {
- set_eof(sd->fd);
- return;
- }
-
- WFIFOHEAD(char_fd,19);
- WFIFOW(char_fd,0) = 0x2b26;
- WFIFOL(char_fd,2) = sd->status.account_id;
- WFIFOL(char_fd,6) = sd->status.char_id;
- WFIFOL(char_fd,10) = sd->login_id1;
- WFIFOB(char_fd,14) = sd->status.sex;
- WFIFOL(char_fd,15) = htonl(session[sd->fd]->client_addr);
- WFIFOSET(char_fd,19);
- chrif_sd_to_auth(sd, ST_LOGIN);
+void chrif_authreq(struct map_session_data *sd) {
+ struct auth_node *node= chrif_search(sd->bl.id);
+
+ if( node != NULL || !chrif_isconnected() ) {
+ set_eof(sd->fd);
+ return;
+ }
+
+ WFIFOHEAD(char_fd,19);
+ WFIFOW(char_fd,0) = 0x2b26;
+ WFIFOL(char_fd,2) = sd->status.account_id;
+ WFIFOL(char_fd,6) = sd->status.char_id;
+ WFIFOL(char_fd,10) = sd->login_id1;
+ WFIFOB(char_fd,14) = sd->status.sex;
+ WFIFOL(char_fd,15) = htonl(session[sd->fd]->client_addr);
+ WFIFOSET(char_fd,19);
+ chrif_sd_to_auth(sd, ST_LOGIN);
}
/*==========================================
* Auth confirmation ack
*------------------------------------------*/
-void chrif_authok(int fd)
-{
- int account_id, group_id, char_id;
- uint32 login_id1,login_id2;
- time_t expiration_time;
- struct mmo_charstatus *status;
- struct auth_node *node;
- bool changing_mapservers;
- TBL_PC *sd;
-
- //Check if both servers agree on the struct's size
- if (RFIFOW(fd,2) - 25 != sizeof(struct mmo_charstatus)) {
- ShowError("chrif_authok: Data size mismatch! %d != %d\n", RFIFOW(fd,2) - 25, sizeof(struct mmo_charstatus));
- return;
- }
-
- account_id = RFIFOL(fd,4);
- login_id1 = RFIFOL(fd,8);
- login_id2 = RFIFOL(fd,12);
- expiration_time = (time_t)(int32)RFIFOL(fd,16);
- group_id = RFIFOL(fd,20);
- changing_mapservers = (RFIFOB(fd,24));
- status = (struct mmo_charstatus *)RFIFOP(fd,25);
- char_id = status->char_id;
-
- //Check if we don't already have player data in our server
- //Causes problems if the currently connected player tries to quit or this data belongs to an already connected player which is trying to re-auth.
- if ((sd = map_id2sd(account_id)) != NULL)
- return;
-
- if ((node = chrif_search(account_id)) == NULL)
- return; // should not happen
-
- if (node->state != ST_LOGIN)
- return; //character in logout phase, do not touch that data.
-
- if (node->sd == NULL) {
- /*
- //When we receive double login info and the client has not connected yet,
- //discard the older one and keep the new one.
- chrif_auth_delete(node->account_id, node->char_id, ST_LOGIN);
- */
- return; // should not happen
- }
-
- sd = node->sd;
-
- if (runflag == MAPSERVER_ST_RUNNING &&
- node->char_dat == NULL &&
- node->account_id == account_id &&
- node->char_id == char_id &&
- node->login_id1 == login_id1) {
- //Auth Ok
- if (pc_authok(sd, login_id2, expiration_time, group_id, status, changing_mapservers))
- return;
- } else { //Auth Failed
- pc_authfail(sd);
- }
-
- chrif_char_offline(sd); //Set him offline, the char server likely has it set as online already.
- chrif_auth_delete(account_id, char_id, ST_LOGIN);
+void chrif_authok(int fd) {
+ int account_id, group_id, char_id;
+ uint32 login_id1,login_id2;
+ time_t expiration_time;
+ struct mmo_charstatus* status;
+ struct auth_node *node;
+ bool changing_mapservers;
+ TBL_PC* sd;
+
+ //Check if both servers agree on the struct's size
+ if( RFIFOW(fd,2) - 25 != sizeof(struct mmo_charstatus) ) {
+ ShowError("chrif_authok: Data size mismatch! %d != %d\n", RFIFOW(fd,2) - 25, sizeof(struct mmo_charstatus));
+ return;
+ }
+
+ account_id = RFIFOL(fd,4);
+ login_id1 = RFIFOL(fd,8);
+ login_id2 = RFIFOL(fd,12);
+ expiration_time = (time_t)(int32)RFIFOL(fd,16);
+ group_id = RFIFOL(fd,20);
+ changing_mapservers = (RFIFOB(fd,24));
+ status = (struct mmo_charstatus*)RFIFOP(fd,25);
+ char_id = status->char_id;
+
+ //Check if we don't already have player data in our server
+ //Causes problems if the currently connected player tries to quit or this data belongs to an already connected player which is trying to re-auth.
+ if ( ( sd = map_id2sd(account_id) ) != NULL )
+ return;
+
+ if ( ( node = chrif_search(account_id) ) == NULL )
+ return; // should not happen
+
+ if ( node->state != ST_LOGIN )
+ return; //character in logout phase, do not touch that data.
+
+ if ( node->sd == NULL ) {
+ /*
+ //When we receive double login info and the client has not connected yet,
+ //discard the older one and keep the new one.
+ chrif_auth_delete(node->account_id, node->char_id, ST_LOGIN);
+ */
+ return; // should not happen
+ }
+
+ sd = node->sd;
+
+ if( runflag == MAPSERVER_ST_RUNNING &&
+ node->char_dat == NULL &&
+ node->account_id == account_id &&
+ node->char_id == char_id &&
+ node->login_id1 == login_id1 )
+ { //Auth Ok
+ if (pc_authok(sd, login_id2, expiration_time, group_id, status, changing_mapservers))
+ return;
+ } else { //Auth Failed
+ pc_authfail(sd);
+ }
+
+ chrif_char_offline(sd); //Set him offline, the char server likely has it set as online already.
+ chrif_auth_delete(account_id, char_id, ST_LOGIN);
}
// client authentication failed
-void chrif_authfail(int fd) /* HELLO WORLD. ip in RFIFOL 15 is not being used (but is available) */
-{
- int account_id, char_id;
- uint32 login_id1;
- char sex;
- struct auth_node *node;
-
- account_id = RFIFOL(fd,2);
- char_id = RFIFOL(fd,6);
- login_id1 = RFIFOL(fd,10);
- sex = RFIFOB(fd,14);
-
- node = chrif_search(account_id);
-
- if (node != NULL &&
- node->account_id == account_id &&
- node->char_id == char_id &&
- node->login_id1 == login_id1 &&
- node->sex == sex &&
- node->state == ST_LOGIN) {
- // found a match
- clif_authfail_fd(node->fd, 0);
- chrif_auth_delete(account_id, char_id, ST_LOGIN);
- }
+void chrif_authfail(int fd) {/* HELLO WORLD. ip in RFIFOL 15 is not being used (but is available) */
+ int account_id, char_id;
+ uint32 login_id1;
+ char sex;
+ struct auth_node* node;
+
+ account_id = RFIFOL(fd,2);
+ char_id = RFIFOL(fd,6);
+ login_id1 = RFIFOL(fd,10);
+ sex = RFIFOB(fd,14);
+
+ node = chrif_search(account_id);
+
+ if( node != NULL &&
+ node->account_id == account_id &&
+ node->char_id == char_id &&
+ node->login_id1 == login_id1 &&
+ node->sex == sex &&
+ node->state == ST_LOGIN )
+ {// found a match
+ clif_authfail_fd(node->fd, 0);
+ chrif_auth_delete(account_id, char_id, ST_LOGIN);
+ }
}
@@ -710,98 +682,93 @@ void chrif_authfail(int fd) /* HELLO WORLD. ip in RFIFOL 15 is not being used (
* This can still happen (client times out while waiting for char to confirm auth data)
* @see DBApply
*/
-int auth_db_cleanup_sub(DBKey key, DBData *data, va_list ap)
-{
- struct auth_node *node = db_data2ptr(data);
- const char *states[] = { "Login", "Logout", "Map change" };
-
- if (DIFF_TICK(gettick(),node->node_created)>60000) {
- switch (node->state) {
- case ST_LOGOUT:
- //Re-save attempt (->sd should never be null here).
- node->node_created = gettick(); //Refresh tick (avoid char-server load if connection is really bad)
- chrif_save(node->sd, 1);
- break;
- default:
- //Clear data. any connected players should have timed out by now.
- ShowInfo("auth_db: Node (state %s) timed out for %d:%d\n", states[node->state], node->account_id, node->char_id);
- chrif_char_offline_nsd(node->account_id, node->char_id);
- chrif_auth_delete(node->account_id, node->char_id, node->state);
- break;
- }
- return 1;
- }
- return 0;
-}
-
-int auth_db_cleanup(int tid, unsigned int tick, int id, intptr_t data)
-{
- chrif_check(0);
- auth_db->foreach(auth_db, auth_db_cleanup_sub);
- return 0;
+int auth_db_cleanup_sub(DBKey key, DBData *data, va_list ap) {
+ struct auth_node *node = db_data2ptr(data);
+ const char* states[] = { "Login", "Logout", "Map change" };
+
+ if(DIFF_TICK(gettick(),node->node_created)>60000) {
+ switch (node->state) {
+ case ST_LOGOUT:
+ //Re-save attempt (->sd should never be null here).
+ node->node_created = gettick(); //Refresh tick (avoid char-server load if connection is really bad)
+ chrif_save(node->sd, 1);
+ break;
+ default:
+ //Clear data. any connected players should have timed out by now.
+ ShowInfo("auth_db: Node (state %s) timed out for %d:%d\n", states[node->state], node->account_id, node->char_id);
+ chrif_char_offline_nsd(node->account_id, node->char_id);
+ chrif_auth_delete(node->account_id, node->char_id, node->state);
+ break;
+ }
+ return 1;
+ }
+ return 0;
+}
+
+int auth_db_cleanup(int tid, unsigned int tick, int id, intptr_t data) {
+ chrif_check(0);
+ auth_db->foreach(auth_db, auth_db_cleanup_sub);
+ return 0;
}
/*==========================================
*
*------------------------------------------*/
-int chrif_charselectreq(struct map_session_data *sd, uint32 s_ip)
-{
- nullpo_retr(-1, sd);
-
- if (!sd || !sd->bl.id || !sd->login_id1)
- return -1;
+int chrif_charselectreq(struct map_session_data* sd, uint32 s_ip) {
+ nullpo_retr(-1, sd);
- chrif_check(-1);
+ if( !sd || !sd->bl.id || !sd->login_id1 )
+ return -1;
+
+ chrif_check(-1);
- WFIFOHEAD(char_fd,18);
- WFIFOW(char_fd, 0) = 0x2b02;
- WFIFOL(char_fd, 2) = sd->bl.id;
- WFIFOL(char_fd, 6) = sd->login_id1;
- WFIFOL(char_fd,10) = sd->login_id2;
- WFIFOL(char_fd,14) = htonl(s_ip);
- WFIFOSET(char_fd,18);
+ WFIFOHEAD(char_fd,18);
+ WFIFOW(char_fd, 0) = 0x2b02;
+ WFIFOL(char_fd, 2) = sd->bl.id;
+ WFIFOL(char_fd, 6) = sd->login_id1;
+ WFIFOL(char_fd,10) = sd->login_id2;
+ WFIFOL(char_fd,14) = htonl(s_ip);
+ WFIFOSET(char_fd,18);
- return 0;
+ return 0;
}
/*==========================================
* Search Char trough id on char serv
*------------------------------------------*/
-int chrif_searchcharid(int char_id)
-{
-
- if (!char_id)
- return -1;
-
- chrif_check(-1);
+int chrif_searchcharid(int char_id) {
+
+ if( !char_id )
+ return -1;
+
+ chrif_check(-1);
- WFIFOHEAD(char_fd,6);
- WFIFOW(char_fd,0) = 0x2b08;
- WFIFOL(char_fd,2) = char_id;
- WFIFOSET(char_fd,6);
+ WFIFOHEAD(char_fd,6);
+ WFIFOW(char_fd,0) = 0x2b08;
+ WFIFOL(char_fd,2) = char_id;
+ WFIFOSET(char_fd,6);
- return 0;
+ return 0;
}
/*==========================================
* 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)
+ ShowInfo("chrif_changeemail: account: %d, actual_email: '%s', new_email: '%s'.\n", id, actual_email, new_email);
- if (battle_config.etc_log)
- ShowInfo("chrif_changeemail: account: %d, actual_email: '%s', new_email: '%s'.\n", id, actual_email, new_email);
+ chrif_check(-1);
- chrif_check(-1);
+ WFIFOHEAD(char_fd,86);
+ WFIFOW(char_fd,0) = 0x2b0c;
+ WFIFOL(char_fd,2) = id;
+ memcpy(WFIFOP(char_fd,6), actual_email, 40);
+ memcpy(WFIFOP(char_fd,46), new_email, 40);
+ WFIFOSET(char_fd,86);
- WFIFOHEAD(char_fd,86);
- WFIFOW(char_fd,0) = 0x2b0c;
- WFIFOL(char_fd,2) = id;
- memcpy(WFIFOP(char_fd,6), actual_email, 40);
- memcpy(WFIFOP(char_fd,46), new_email, 40);
- WFIFOSET(char_fd,86);
-
- return 0;
+ return 0;
}
/*==========================================
@@ -810,48 +777,46 @@ int chrif_changeemail(int id, const char *actual_email, const char *new_email)
* type of operation:
* 1: block, 2: ban, 3: unblock, 4: unban, 5: changesex (use next function for 5)
*------------------------------------------*/
-int chrif_char_ask_name(int acc, const char *character_name, unsigned short operation_type, int year, int month, int day, int hour, int minute, int second)
-{
-
- chrif_check(-1);
-
- WFIFOHEAD(char_fd,44);
- WFIFOW(char_fd,0) = 0x2b0e;
- WFIFOL(char_fd,2) = acc;
- safestrncpy((char *)WFIFOP(char_fd,6), character_name, NAME_LENGTH);
- WFIFOW(char_fd,30) = operation_type;
-
- if (operation_type == 2) {
- WFIFOW(char_fd,32) = year;
- WFIFOW(char_fd,34) = month;
- WFIFOW(char_fd,36) = day;
- WFIFOW(char_fd,38) = hour;
- WFIFOW(char_fd,40) = minute;
- WFIFOW(char_fd,42) = second;
- }
-
- WFIFOSET(char_fd,44);
- return 0;
-}
-
-int chrif_changesex(struct map_session_data *sd)
-{
- chrif_check(-1);
-
- WFIFOHEAD(char_fd,44);
- WFIFOW(char_fd,0) = 0x2b0e;
- WFIFOL(char_fd,2) = sd->status.account_id;
- safestrncpy((char *)WFIFOP(char_fd,6), sd->status.name, NAME_LENGTH);
- WFIFOW(char_fd,30) = 5;
- WFIFOSET(char_fd,44);
-
- clif_displaymessage(sd->fd, msg_txt(408)); //"Need disconnection to perform change-sex request..."
-
- if (sd->fd)
- clif_authfail_fd(sd->fd, 15);
- else
- map_quit(sd);
- return 0;
+int chrif_char_ask_name(int acc, const char* character_name, unsigned short operation_type, int year, int month, int day, int hour, int minute, int second) {
+
+ chrif_check(-1);
+
+ WFIFOHEAD(char_fd,44);
+ WFIFOW(char_fd,0) = 0x2b0e;
+ WFIFOL(char_fd,2) = acc;
+ safestrncpy((char*)WFIFOP(char_fd,6), character_name, NAME_LENGTH);
+ WFIFOW(char_fd,30) = operation_type;
+
+ if ( operation_type == 2 ) {
+ WFIFOW(char_fd,32) = year;
+ WFIFOW(char_fd,34) = month;
+ WFIFOW(char_fd,36) = day;
+ WFIFOW(char_fd,38) = hour;
+ WFIFOW(char_fd,40) = minute;
+ WFIFOW(char_fd,42) = second;
+ }
+
+ WFIFOSET(char_fd,44);
+ return 0;
+}
+
+int chrif_changesex(struct map_session_data *sd) {
+ chrif_check(-1);
+
+ WFIFOHEAD(char_fd,44);
+ WFIFOW(char_fd,0) = 0x2b0e;
+ WFIFOL(char_fd,2) = sd->status.account_id;
+ safestrncpy((char*)WFIFOP(char_fd,6), sd->status.name, NAME_LENGTH);
+ WFIFOW(char_fd,30) = 5;
+ WFIFOSET(char_fd,44);
+
+ clif_displaymessage(sd->fd, msg_txt(408)); //"Need disconnection to perform change-sex request..."
+
+ if (sd->fd)
+ clif_authfail_fd(sd->fd, 15);
+ else
+ map_quit(sd);
+ return 0;
}
/*==========================================
@@ -865,844 +830,737 @@ int chrif_changesex(struct map_session_data *sd)
* 2: gm level too low
* 3: login-server offline
*------------------------------------------*/
-static void chrif_char_ask_name_answer(int acc, const char *player_name, uint16 type, uint16 answer)
-{
- struct map_session_data *sd;
- char action[25];
- char output[256];
-
- sd = map_id2sd(acc);
-
- if (acc < 0 || sd == NULL) {
- ShowError("chrif_char_ask_name_answer failed - player not online.\n");
- return;
- }
-
- if (type > 0 && type <= 5)
- snprintf(action,25,"%s",msg_txt(427+type)); //block|ban|unblock|unban|change the sex of
- else
- snprintf(action,25,"???");
-
- switch (answer) {
- case 0 :
- sprintf(output, msg_txt(424), action, NAME_LENGTH, player_name);
- break;
- case 1 :
- sprintf(output, msg_txt(425), NAME_LENGTH, player_name);
- break;
- case 2 :
- sprintf(output, msg_txt(426), action, NAME_LENGTH, player_name);
- break;
- case 3 :
- sprintf(output, msg_txt(427), action, NAME_LENGTH, player_name);
- break;
- default:
- output[0] = '\0';
- break;
- }
-
- clif_displaymessage(sd->fd, output);
+static void chrif_char_ask_name_answer(int acc, const char* player_name, uint16 type, uint16 answer) {
+ struct map_session_data* sd;
+ char action[25];
+ char output[256];
+
+ sd = map_id2sd(acc);
+
+ if( acc < 0 || sd == NULL ) {
+ ShowError("chrif_char_ask_name_answer failed - player not online.\n");
+ return;
+ }
+
+ if( type > 0 && type <= 5 )
+ snprintf(action,25,"%s",msg_txt(427+type)); //block|ban|unblock|unban|change the sex of
+ else
+ snprintf(action,25,"???");
+
+ switch( answer ) {
+ case 0 : sprintf(output, msg_txt(424), action, NAME_LENGTH, player_name); break;
+ case 1 : sprintf(output, msg_txt(425), NAME_LENGTH, player_name); break;
+ case 2 : sprintf(output, msg_txt(426), action, NAME_LENGTH, player_name); break;
+ case 3 : sprintf(output, msg_txt(427), action, NAME_LENGTH, player_name); break;
+ default: output[0] = '\0'; break;
+ }
+
+ clif_displaymessage(sd->fd, output);
}
/*==========================================
* Request char server to change sex of char (modified by Yor)
*------------------------------------------*/
-int chrif_changedsex(int fd)
-{
- int acc, sex, i;
- struct map_session_data *sd;
-
- acc = RFIFOL(fd,2);
- sex = RFIFOL(fd,6);
-
- if (battle_config.etc_log)
- ShowNotice("chrif_changedsex %d.\n", acc);
-
- sd = map_id2sd(acc);
- if (sd) { //Normally there should not be a char logged on right now!
- if (sd->status.sex == sex)
- return 0; //Do nothing? Likely safe.
- sd->status.sex = !sd->status.sex;
-
- // reset skill of some job
- if ((sd->class_&MAPID_UPPERMASK) == MAPID_BARDDANCER) {
- // remove specifical skills of Bard classes
- for (i = 315; i <= 322; i++) {
- if (sd->status.skill[i].id > 0 && sd->status.skill[i].flag == SKILL_FLAG_PERMANENT) {
- sd->status.skill_point += sd->status.skill[i].lv;
- sd->status.skill[i].id = 0;
- sd->status.skill[i].lv = 0;
- }
- }
- // remove specifical skills of Dancer classes
- for (i = 323; i <= 330; i++) {
- if (sd->status.skill[i].id > 0 && sd->status.skill[i].flag == SKILL_FLAG_PERMANENT) {
- sd->status.skill_point += sd->status.skill[i].lv;
- sd->status.skill[i].id = 0;
- sd->status.skill[i].lv = 0;
- }
- }
- clif_updatestatus(sd, SP_SKILLPOINT);
- // change job if necessary
- if (sd->status.sex) //Changed from Dancer
- sd->status.class_ -= 1;
- else //Changed from Bard
- sd->status.class_ += 1;
- //sd->class_ needs not be updated as both Dancer/Bard are the same.
- }
- // save character
- 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, msg_txt(409)); //"Your sex has been changed (need disconnection by the server)..."
- set_eof(sd->fd); // forced to disconnect for the change
- map_quit(sd); // Remove leftovers (e.g. autotrading) [Paradox924X]
- }
- return 0;
+int chrif_changedsex(int fd) {
+ int acc, sex, i;
+ struct map_session_data *sd;
+
+ acc = RFIFOL(fd,2);
+ sex = RFIFOL(fd,6);
+
+ if ( battle_config.etc_log )
+ ShowNotice("chrif_changedsex %d.\n", acc);
+
+ sd = map_id2sd(acc);
+ if ( sd ) { //Normally there should not be a char logged on right now!
+ if ( sd->status.sex == sex )
+ return 0; //Do nothing? Likely safe.
+ sd->status.sex = !sd->status.sex;
+
+ // reset skill of some job
+ if ((sd->class_&MAPID_UPPERMASK) == MAPID_BARDDANCER) {
+ // remove specifical skills of Bard classes
+ for(i = 315; i <= 322; i++) {
+ if (sd->status.skill[i].id > 0 && sd->status.skill[i].flag == SKILL_FLAG_PERMANENT) {
+ sd->status.skill_point += sd->status.skill[i].lv;
+ sd->status.skill[i].id = 0;
+ sd->status.skill[i].lv = 0;
+ }
+ }
+ // remove specifical skills of Dancer classes
+ for(i = 323; i <= 330; i++) {
+ if (sd->status.skill[i].id > 0 && sd->status.skill[i].flag == SKILL_FLAG_PERMANENT) {
+ sd->status.skill_point += sd->status.skill[i].lv;
+ sd->status.skill[i].id = 0;
+ sd->status.skill[i].lv = 0;
+ }
+ }
+ clif_updatestatus(sd, SP_SKILLPOINT);
+ // change job if necessary
+ if (sd->status.sex) //Changed from Dancer
+ sd->status.class_ -= 1;
+ else //Changed from Bard
+ sd->status.class_ += 1;
+ //sd->class_ needs not be updated as both Dancer/Bard are the same.
+ }
+ // save character
+ 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, msg_txt(409)); //"Your sex has been changed (need disconnection by the server)..."
+ set_eof(sd->fd); // forced to disconnect for the change
+ map_quit(sd); // Remove leftovers (e.g. autotrading) [Paradox924X]
+ }
+ return 0;
}
/*==========================================
* Request Char Server to Divorce Players
*------------------------------------------*/
-int chrif_divorce(int partner_id1, int partner_id2)
-{
- chrif_check(-1);
+int chrif_divorce(int partner_id1, int partner_id2) {
+ chrif_check(-1);
- WFIFOHEAD(char_fd,10);
- WFIFOW(char_fd,0) = 0x2b11;
- WFIFOL(char_fd,2) = partner_id1;
- WFIFOL(char_fd,6) = partner_id2;
- WFIFOSET(char_fd,10);
+ WFIFOHEAD(char_fd,10);
+ WFIFOW(char_fd,0) = 0x2b11;
+ WFIFOL(char_fd,2) = partner_id1;
+ WFIFOL(char_fd,6) = partner_id2;
+ WFIFOSET(char_fd,10);
- return 0;
+ return 0;
}
/*==========================================
* Divorce players
* only used if 'partner_id' is offline
*------------------------------------------*/
-int chrif_divorceack(int char_id, int partner_id)
-{
- struct map_session_data *sd;
- int i;
-
- if (!char_id || !partner_id)
- return 0;
-
- if ((sd = map_charid2sd(char_id)) != NULL && sd->status.partner_id == partner_id) {
- sd->status.partner_id = 0;
- for (i = 0; i < MAX_INVENTORY; i++)
- if (sd->status.inventory[i].nameid == WEDDING_RING_M || sd->status.inventory[i].nameid == WEDDING_RING_F)
- pc_delitem(sd, i, 1, 0, 0, LOG_TYPE_OTHER);
- }
-
- if ((sd = map_charid2sd(partner_id)) != NULL && sd->status.partner_id == char_id) {
- sd->status.partner_id = 0;
- for (i = 0; i < MAX_INVENTORY; i++)
- if (sd->status.inventory[i].nameid == WEDDING_RING_M || sd->status.inventory[i].nameid == WEDDING_RING_F)
- pc_delitem(sd, i, 1, 0, 0, LOG_TYPE_OTHER);
- }
-
- return 0;
+int chrif_divorceack(int char_id, int partner_id) {
+ struct map_session_data* sd;
+ int i;
+
+ if( !char_id || !partner_id )
+ return 0;
+
+ if( ( sd = map_charid2sd(char_id) ) != NULL && sd->status.partner_id == partner_id ) {
+ sd->status.partner_id = 0;
+ for(i = 0; i < MAX_INVENTORY; i++)
+ if (sd->status.inventory[i].nameid == WEDDING_RING_M || sd->status.inventory[i].nameid == WEDDING_RING_F)
+ pc_delitem(sd, i, 1, 0, 0, LOG_TYPE_OTHER);
+ }
+
+ if( ( sd = map_charid2sd(partner_id) ) != NULL && sd->status.partner_id == char_id ) {
+ sd->status.partner_id = 0;
+ for(i = 0; i < MAX_INVENTORY; i++)
+ if (sd->status.inventory[i].nameid == WEDDING_RING_M || sd->status.inventory[i].nameid == WEDDING_RING_F)
+ pc_delitem(sd, i, 1, 0, 0, LOG_TYPE_OTHER);
+ }
+
+ return 0;
}
/*==========================================
* Removes Baby from parents
*------------------------------------------*/
-int chrif_deadopt(int father_id, int mother_id, int child_id)
-{
- struct map_session_data *sd;
+int chrif_deadopt(int father_id, int mother_id, int child_id) {
+ struct map_session_data* sd;
- if (father_id && (sd = map_charid2sd(father_id)) != NULL && sd->status.child == child_id) {
- sd->status.child = 0;
- sd->status.skill[WE_CALLBABY].id = 0;
- sd->status.skill[WE_CALLBABY].lv = 0;
- sd->status.skill[WE_CALLBABY].flag = 0;
- clif_deleteskill(sd,WE_CALLBABY);
- }
+ if( father_id && ( sd = map_charid2sd(father_id) ) != NULL && sd->status.child == child_id ) {
+ sd->status.child = 0;
+ sd->status.skill[WE_CALLBABY].id = 0;
+ sd->status.skill[WE_CALLBABY].lv = 0;
+ sd->status.skill[WE_CALLBABY].flag = 0;
+ clif_deleteskill(sd,WE_CALLBABY);
+ }
- if (mother_id && (sd = map_charid2sd(mother_id)) != NULL && sd->status.child == child_id) {
- sd->status.child = 0;
- sd->status.skill[WE_CALLBABY].id = 0;
- sd->status.skill[WE_CALLBABY].lv = 0;
- sd->status.skill[WE_CALLBABY].flag = 0;
- clif_deleteskill(sd,WE_CALLBABY);
- }
+ if( mother_id && ( sd = map_charid2sd(mother_id) ) != NULL && sd->status.child == child_id ) {
+ sd->status.child = 0;
+ sd->status.skill[WE_CALLBABY].id = 0;
+ sd->status.skill[WE_CALLBABY].lv = 0;
+ sd->status.skill[WE_CALLBABY].flag = 0;
+ clif_deleteskill(sd,WE_CALLBABY);
+ }
- return 0;
+ return 0;
}
/*==========================================
* Disconnection of a player (account has been banned of has a status, from login-server) by [Yor]
*------------------------------------------*/
-int chrif_accountban(int fd)
-{
- int acc;
- struct map_session_data *sd;
-
- acc = RFIFOL(fd,2);
-
- if (battle_config.etc_log)
- ShowNotice("chrif_accountban %d.\n", acc);
-
- sd = map_id2sd(acc);
-
- if (acc < 0 || sd == NULL) {
- ShowError("chrif_accountban failed - player not online.\n");
- return 0;
- }
-
- sd->login_id1++; // change identify, because if player come back in char within the 5 seconds, he can change its characters
- if (RFIFOB(fd,6) == 0) { // 0: change of statut, 1: ban
- int ret_status = RFIFOL(fd,7); // status or final date of a banishment
- if (0<ret_status && ret_status<=9)
- clif_displaymessage(sd->fd, msg_txt(411+ret_status));
- else if (ret_status==100)
- clif_displaymessage(sd->fd, msg_txt(421));
- else
- clif_displaymessage(sd->fd, msg_txt(420)); //"Your account has not more authorised."
- } else if (RFIFOB(fd,6) == 1) { // 0: change of statut, 1: ban
- time_t timestamp;
- char tmpstr[2048];
- timestamp = (time_t)RFIFOL(fd,7); // status or final date of a banishment
- strcpy(tmpstr, msg_txt(423)); //"Your account has been banished until "
- strftime(tmpstr + strlen(tmpstr), 24, "%d-%m-%Y %H:%M:%S", localtime(&timestamp));
- clif_displaymessage(sd->fd, tmpstr);
- }
-
- set_eof(sd->fd); // forced to disconnect for the change
- map_quit(sd); // Remove leftovers (e.g. autotrading) [Paradox924X]
- return 0;
+int chrif_accountban(int fd) {
+ int acc;
+ struct map_session_data *sd;
+
+ acc = RFIFOL(fd,2);
+
+ if ( battle_config.etc_log )
+ ShowNotice("chrif_accountban %d.\n", acc);
+
+ sd = map_id2sd(acc);
+
+ if ( acc < 0 || sd == NULL ) {
+ ShowError("chrif_accountban failed - player not online.\n");
+ return 0;
+ }
+
+ sd->login_id1++; // change identify, because if player come back in char within the 5 seconds, he can change its characters
+ if (RFIFOB(fd,6) == 0) { // 0: change of statut, 1: ban
+ int ret_status = RFIFOL(fd,7); // status or final date of a banishment
+ if(0<ret_status && ret_status<=9)
+ clif_displaymessage(sd->fd, msg_txt(411+ret_status));
+ else if(ret_status==100)
+ clif_displaymessage(sd->fd, msg_txt(421));
+ else
+ clif_displaymessage(sd->fd, msg_txt(420)); //"Your account has not more authorised."
+ } else if (RFIFOB(fd,6) == 1) { // 0: change of statut, 1: ban
+ time_t timestamp;
+ char tmpstr[2048];
+ timestamp = (time_t)RFIFOL(fd,7); // status or final date of a banishment
+ strcpy(tmpstr, msg_txt(423)); //"Your account has been banished until "
+ strftime(tmpstr + strlen(tmpstr), 24, "%d-%m-%Y %H:%M:%S", localtime(&timestamp));
+ clif_displaymessage(sd->fd, tmpstr);
+ }
+
+ set_eof(sd->fd); // forced to disconnect for the change
+ map_quit(sd); // Remove leftovers (e.g. autotrading) [Paradox924X]
+ return 0;
}
//Disconnect the player out of the game, simple packet
//packet.w AID.L WHY.B 2+4+1 = 7byte
-int chrif_disconnectplayer(int fd)
-{
- struct map_session_data *sd;
- int account_id = RFIFOL(fd, 2);
-
- sd = map_id2sd(account_id);
- if (sd == NULL) {
- struct auth_node *auth = chrif_search(account_id);
-
- if (auth != NULL && chrif_auth_delete(account_id, auth->char_id, ST_LOGIN))
- return 0;
-
- return -1;
- }
-
- if (!sd->fd) { //No connection
- if (sd->state.autotrade)
- map_quit(sd); //Remove it.
- //Else we don't remove it because the char should have a timer to remove the player because it force-quit before,
- //and we don't want them kicking their previous instance before the 10 secs penalty time passes. [Skotlex]
- return 0;
- }
-
- switch (RFIFOB(fd, 6)) {
- case 1:
- clif_authfail_fd(sd->fd, 1);
- break; //server closed
- case 2:
- clif_authfail_fd(sd->fd, 2);
- break; //someone else logged in
- case 3:
- clif_authfail_fd(sd->fd, 4);
- break; //server overpopulated
- case 4:
- clif_authfail_fd(sd->fd, 10);
- break; //out of available time paid for
- case 5:
- clif_authfail_fd(sd->fd, 15);
- break; //forced to dc by gm
- }
- return 0;
+int chrif_disconnectplayer(int fd) {
+ struct map_session_data* sd;
+ int account_id = RFIFOL(fd, 2);
+
+ sd = map_id2sd(account_id);
+ if( sd == NULL ) {
+ struct auth_node* auth = chrif_search(account_id);
+
+ if( auth != NULL && chrif_auth_delete(account_id, auth->char_id, ST_LOGIN) )
+ return 0;
+
+ return -1;
+ }
+
+ if (!sd->fd) { //No connection
+ if (sd->state.autotrade)
+ map_quit(sd); //Remove it.
+ //Else we don't remove it because the char should have a timer to remove the player because it force-quit before,
+ //and we don't want them kicking their previous instance before the 10 secs penalty time passes. [Skotlex]
+ return 0;
+ }
+
+ switch(RFIFOB(fd, 6)) {
+ case 1: clif_authfail_fd(sd->fd, 1); break; //server closed
+ case 2: clif_authfail_fd(sd->fd, 2); break; //someone else logged in
+ case 3: clif_authfail_fd(sd->fd, 4); break; //server overpopulated
+ case 4: clif_authfail_fd(sd->fd, 10); break; //out of available time paid for
+ case 5: clif_authfail_fd(sd->fd, 15); break; //forced to dc by gm
+ }
+ return 0;
}
/*==========================================
* Request/Receive top 10 Fame character list
*------------------------------------------*/
-int chrif_updatefamelist(struct map_session_data *sd)
-{
- char type;
-
- chrif_check(-1);
-
- switch (sd->class_ & MAPID_UPPERMASK) {
- case MAPID_BLACKSMITH:
- type = 1;
- break;
- case MAPID_ALCHEMIST:
- type = 2;
- break;
- case MAPID_TAEKWON:
- type = 3;
- break;
- default:
- return 0;
- }
-
- WFIFOHEAD(char_fd, 11);
- WFIFOW(char_fd,0) = 0x2b10;
- WFIFOL(char_fd,2) = sd->status.char_id;
- WFIFOL(char_fd,6) = sd->status.fame;
- WFIFOB(char_fd,10) = type;
- WFIFOSET(char_fd,11);
-
- return 0;
-}
-
-int chrif_buildfamelist(void)
-{
- chrif_check(-1);
-
- WFIFOHEAD(char_fd,2);
- WFIFOW(char_fd,0) = 0x2b1a;
- WFIFOSET(char_fd,2);
-
- return 0;
-}
-
-int chrif_recvfamelist(int fd)
-{
- int num, size;
- int total = 0, len = 8;
-
- memset(smith_fame_list, 0, sizeof(smith_fame_list));
- memset(chemist_fame_list, 0, sizeof(chemist_fame_list));
- memset(taekwon_fame_list, 0, sizeof(taekwon_fame_list));
-
- size = RFIFOW(fd, 6); //Blacksmith block size
-
- for (num = 0; len < size && num < MAX_FAME_LIST; num++) {
- memcpy(&smith_fame_list[num], RFIFOP(fd,len), sizeof(struct fame_list));
- len += sizeof(struct fame_list);
- }
-
- total += num;
-
- size = RFIFOW(fd, 4); //Alchemist block size
-
- for (num = 0; len < size && num < MAX_FAME_LIST; num++) {
- memcpy(&chemist_fame_list[num], RFIFOP(fd,len), sizeof(struct fame_list));
- len += sizeof(struct fame_list);
- }
-
- total += num;
-
- size = RFIFOW(fd, 2); //Total packet length
-
- for (num = 0; len < size && num < MAX_FAME_LIST; num++) {
- memcpy(&taekwon_fame_list[num], RFIFOP(fd,len), sizeof(struct fame_list));
- len += sizeof(struct fame_list);
- }
-
- total += num;
-
- ShowInfo("Received Fame List of '"CL_WHITE"%d"CL_RESET"' characters.\n", total);
-
- return 0;
+int chrif_updatefamelist(struct map_session_data* sd) {
+ char type;
+
+ chrif_check(-1);
+
+ switch(sd->class_ & MAPID_UPPERMASK) {
+ case MAPID_BLACKSMITH: type = 1; break;
+ case MAPID_ALCHEMIST: type = 2; break;
+ case MAPID_TAEKWON: type = 3; break;
+ default:
+ return 0;
+ }
+
+ WFIFOHEAD(char_fd, 11);
+ WFIFOW(char_fd,0) = 0x2b10;
+ WFIFOL(char_fd,2) = sd->status.char_id;
+ WFIFOL(char_fd,6) = sd->status.fame;
+ WFIFOB(char_fd,10) = type;
+ WFIFOSET(char_fd,11);
+
+ return 0;
+}
+
+int chrif_buildfamelist(void) {
+ chrif_check(-1);
+
+ WFIFOHEAD(char_fd,2);
+ WFIFOW(char_fd,0) = 0x2b1a;
+ WFIFOSET(char_fd,2);
+
+ return 0;
+}
+
+int chrif_recvfamelist(int fd) {
+ int num, size;
+ int total = 0, len = 8;
+
+ memset (smith_fame_list, 0, sizeof(smith_fame_list));
+ memset (chemist_fame_list, 0, sizeof(chemist_fame_list));
+ memset (taekwon_fame_list, 0, sizeof(taekwon_fame_list));
+
+ size = RFIFOW(fd, 6); //Blacksmith block size
+
+ for (num = 0; len < size && num < MAX_FAME_LIST; num++) {
+ memcpy(&smith_fame_list[num], RFIFOP(fd,len), sizeof(struct fame_list));
+ len += sizeof(struct fame_list);
+ }
+
+ total += num;
+
+ size = RFIFOW(fd, 4); //Alchemist block size
+
+ for (num = 0; len < size && num < MAX_FAME_LIST; num++) {
+ memcpy(&chemist_fame_list[num], RFIFOP(fd,len), sizeof(struct fame_list));
+ len += sizeof(struct fame_list);
+ }
+
+ total += num;
+
+ size = RFIFOW(fd, 2); //Total packet length
+
+ for (num = 0; len < size && num < MAX_FAME_LIST; num++) {
+ memcpy(&taekwon_fame_list[num], RFIFOP(fd,len), sizeof(struct fame_list));
+ len += sizeof(struct fame_list);
+ }
+
+ total += num;
+
+ ShowInfo("Received Fame List of '"CL_WHITE"%d"CL_RESET"' characters.\n", total);
+
+ return 0;
}
/// fame ranking update confirmation
/// R 2b22 <table>.B <index>.B <value>.L
-int chrif_updatefamelist_ack(int fd)
-{
- struct fame_list *list;
- uint8 index;
-
- switch (RFIFOB(fd,2)) {
- case 1:
- list = smith_fame_list;
- break;
- case 2:
- list = chemist_fame_list;
- break;
- case 3:
- list = taekwon_fame_list;
- break;
- default:
- return 0;
- }
-
- index = RFIFOB(fd, 3);
-
- if (index >= MAX_FAME_LIST)
- return 0;
-
- list[index].fame = RFIFOL(fd,4);
-
- return 1;
-}
-
-int chrif_save_scdata(struct map_session_data *sd) //parses the sc_data of the player and sends it to the char-server for saving. [Skotlex]
-{
+int chrif_updatefamelist_ack(int fd) {
+ struct fame_list* list;
+ uint8 index;
+
+ switch (RFIFOB(fd,2)) {
+ case 1: list = smith_fame_list; break;
+ case 2: list = chemist_fame_list; break;
+ case 3: list = taekwon_fame_list; break;
+ default: return 0;
+ }
+
+ index = RFIFOB(fd, 3);
+
+ if (index >= MAX_FAME_LIST)
+ return 0;
+
+ list[index].fame = RFIFOL(fd,4);
+
+ return 1;
+}
+
+int chrif_save_scdata(struct map_session_data *sd) { //parses the sc_data of the player and sends it to the char-server for saving. [Skotlex]
#ifdef ENABLE_SC_SAVING
- int i, count=0;
- unsigned int tick;
- struct status_change_data data;
- struct status_change *sc = &sd->sc;
- const struct TimerData *timer;
-
- chrif_check(-1);
- tick = gettick();
-
- WFIFOHEAD(char_fd, 14 + SC_MAX*sizeof(struct status_change_data));
- WFIFOW(char_fd,0) = 0x2b1c;
- WFIFOL(char_fd,4) = sd->status.account_id;
- WFIFOL(char_fd,8) = sd->status.char_id;
-
- for (i = 0; i < SC_MAX; i++) {
- if (!sc->data[i])
- continue;
- if (sc->data[i]->timer != INVALID_TIMER) {
- timer = get_timer(sc->data[i]->timer);
- if (timer == NULL || timer->func != status_change_timer || DIFF_TICK(timer->tick,tick) < 0)
- continue;
- data.tick = DIFF_TICK(timer->tick,tick); //Duration that is left before ending.
- } else
- data.tick = -1; //Infinite duration
- data.type = i;
- data.val1 = sc->data[i]->val1;
- data.val2 = sc->data[i]->val2;
- data.val3 = sc->data[i]->val3;
- data.val4 = sc->data[i]->val4;
- memcpy(WFIFOP(char_fd,14 +count*sizeof(struct status_change_data)),
- &data, sizeof(struct status_change_data));
- count++;
- }
-
- if (count == 0)
- return 0; //Nothing to save.
-
- WFIFOW(char_fd,12) = count;
- WFIFOW(char_fd,2) = 14 +count*sizeof(struct status_change_data); //Total packet size
- WFIFOSET(char_fd,WFIFOW(char_fd,2));
+ int i, count=0;
+ unsigned int tick;
+ struct status_change_data data;
+ struct status_change *sc = &sd->sc;
+ const struct TimerData *timer;
+
+ chrif_check(-1);
+ tick = gettick();
+
+ WFIFOHEAD(char_fd, 14 + SC_MAX*sizeof(struct status_change_data));
+ WFIFOW(char_fd,0) = 0x2b1c;
+ WFIFOL(char_fd,4) = sd->status.account_id;
+ WFIFOL(char_fd,8) = sd->status.char_id;
+
+ for (i = 0; i < SC_MAX; i++) {
+ if (!sc->data[i])
+ continue;
+ if (sc->data[i]->timer != INVALID_TIMER) {
+ timer = get_timer(sc->data[i]->timer);
+ if (timer == NULL || timer->func != status_change_timer || DIFF_TICK(timer->tick,tick) < 0)
+ continue;
+ data.tick = DIFF_TICK(timer->tick,tick); //Duration that is left before ending.
+ } else
+ data.tick = -1; //Infinite duration
+ data.type = i;
+ data.val1 = sc->data[i]->val1;
+ data.val2 = sc->data[i]->val2;
+ data.val3 = sc->data[i]->val3;
+ data.val4 = sc->data[i]->val4;
+ memcpy(WFIFOP(char_fd,14 +count*sizeof(struct status_change_data)),
+ &data, sizeof(struct status_change_data));
+ count++;
+ }
+
+ if (count == 0)
+ return 0; //Nothing to save.
+
+ WFIFOW(char_fd,12) = count;
+ WFIFOW(char_fd,2) = 14 +count*sizeof(struct status_change_data); //Total packet size
+ WFIFOSET(char_fd,WFIFOW(char_fd,2));
#endif
-
- return 0;
+
+ return 0;
}
//Retrieve and load sc_data for a player. [Skotlex]
-int chrif_load_scdata(int fd)
-{
+int chrif_load_scdata(int fd) {
#ifdef ENABLE_SC_SAVING
- struct map_session_data *sd;
- struct status_change_data *data;
- int aid, cid, i, count;
-
- aid = RFIFOL(fd,4); //Player Account ID
- cid = RFIFOL(fd,8); //Player Char ID
-
- sd = map_id2sd(aid);
-
- if (!sd) {
- ShowError("chrif_load_scdata: Player of AID %d not found!\n", aid);
- return -1;
- }
-
- if (sd->status.char_id != cid) {
- ShowError("chrif_load_scdata: Receiving data for account %d, char id does not matches (%d != %d)!\n", aid, sd->status.char_id, cid);
- return -1;
- }
-
- count = RFIFOW(fd,12); //sc_count
-
- for (i = 0; i < count; i++) {
- data = (struct status_change_data *)RFIFOP(fd,14 + i*sizeof(struct status_change_data));
- status_change_start(&sd->bl, (sc_type)data->type, 10000, data->val1, data->val2, data->val3, data->val4, data->tick, 15);
- }
+ struct map_session_data *sd;
+ struct status_change_data *data;
+ int aid, cid, i, count;
+
+ aid = RFIFOL(fd,4); //Player Account ID
+ cid = RFIFOL(fd,8); //Player Char ID
+
+ sd = map_id2sd(aid);
+
+ if ( !sd ) {
+ ShowError("chrif_load_scdata: Player of AID %d not found!\n", aid);
+ return -1;
+ }
+
+ if ( sd->status.char_id != cid ) {
+ ShowError("chrif_load_scdata: Receiving data for account %d, char id does not matches (%d != %d)!\n", aid, sd->status.char_id, cid);
+ return -1;
+ }
+
+ count = RFIFOW(fd,12); //sc_count
+
+ for (i = 0; i < count; i++) {
+ data = (struct status_change_data*)RFIFOP(fd,14 + i*sizeof(struct status_change_data));
+ status_change_start(&sd->bl, (sc_type)data->type, 10000, data->val1, data->val2, data->val3, data->val4, data->tick, 15);
+ }
#endif
-
- return 0;
+
+ return 0;
}
/*==========================================
* Send rates and motd to char server [Wizputer]
* S 2b16 <base rate>.L <job rate>.L <drop rate>.L
*------------------------------------------*/
-int chrif_ragsrvinfo(int base_rate, int job_rate, int drop_rate)
-{
- chrif_check(-1);
-
- WFIFOHEAD(char_fd,14);
- WFIFOW(char_fd,0) = 0x2b16;
- WFIFOL(char_fd,2) = base_rate;
- WFIFOL(char_fd,6) = job_rate;
- WFIFOL(char_fd,10) = drop_rate;
- WFIFOSET(char_fd,14);
+int chrif_ragsrvinfo(int base_rate, int job_rate, int drop_rate) {
+ chrif_check(-1);
- return 0;
+ WFIFOHEAD(char_fd,14);
+ WFIFOW(char_fd,0) = 0x2b16;
+ WFIFOL(char_fd,2) = base_rate;
+ WFIFOL(char_fd,6) = job_rate;
+ WFIFOL(char_fd,10) = drop_rate;
+ WFIFOSET(char_fd,14);
+
+ return 0;
}
/*=========================================
* Tell char-server charcter disconnected [Wizputer]
*-----------------------------------------*/
-int chrif_char_offline(struct map_session_data *sd)
-{
- chrif_check(-1);
+int chrif_char_offline(struct map_session_data *sd) {
+ chrif_check(-1);
- WFIFOHEAD(char_fd,10);
- WFIFOW(char_fd,0) = 0x2b17;
- WFIFOL(char_fd,2) = sd->status.char_id;
- WFIFOL(char_fd,6) = sd->status.account_id;
- WFIFOSET(char_fd,10);
+ WFIFOHEAD(char_fd,10);
+ WFIFOW(char_fd,0) = 0x2b17;
+ WFIFOL(char_fd,2) = sd->status.char_id;
+ WFIFOL(char_fd,6) = sd->status.account_id;
+ WFIFOSET(char_fd,10);
- return 0;
+ return 0;
}
-int chrif_char_offline_nsd(int account_id, int char_id)
-{
- chrif_check(-1);
+int chrif_char_offline_nsd(int account_id, int char_id) {
+ chrif_check(-1);
- WFIFOHEAD(char_fd,10);
- WFIFOW(char_fd,0) = 0x2b17;
- WFIFOL(char_fd,2) = char_id;
- WFIFOL(char_fd,6) = account_id;
- WFIFOSET(char_fd,10);
+ WFIFOHEAD(char_fd,10);
+ WFIFOW(char_fd,0) = 0x2b17;
+ WFIFOL(char_fd,2) = char_id;
+ WFIFOL(char_fd,6) = account_id;
+ WFIFOSET(char_fd,10);
- return 0;
+ return 0;
}
/*=========================================
* Tell char-server to reset all chars offline [Wizputer]
*-----------------------------------------*/
-int chrif_flush_fifo(void)
-{
- chrif_check(-1);
+int chrif_flush_fifo(void) {
+ chrif_check(-1);
- set_nonblocking(char_fd, 0);
- flush_fifos();
- set_nonblocking(char_fd, 1);
+ set_nonblocking(char_fd, 0);
+ flush_fifos();
+ set_nonblocking(char_fd, 1);
- return 0;
+ return 0;
}
/*=========================================
* Tell char-server to reset all chars offline [Wizputer]
*-----------------------------------------*/
-int chrif_char_reset_offline(void)
-{
- chrif_check(-1);
+int chrif_char_reset_offline(void) {
+ chrif_check(-1);
- WFIFOHEAD(char_fd,2);
- WFIFOW(char_fd,0) = 0x2b18;
- WFIFOSET(char_fd,2);
+ WFIFOHEAD(char_fd,2);
+ WFIFOW(char_fd,0) = 0x2b18;
+ WFIFOSET(char_fd,2);
- return 0;
+ return 0;
}
/*=========================================
* Tell char-server charcter is online [Wizputer]
*-----------------------------------------*/
-int chrif_char_online(struct map_session_data *sd)
-{
- chrif_check(-1);
+int chrif_char_online(struct map_session_data *sd) {
+ chrif_check(-1);
- WFIFOHEAD(char_fd,10);
- 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);
+ WFIFOHEAD(char_fd,10);
+ 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;
+ return 0;
}
/// Called when the connection to Char Server is disconnected.
-void chrif_on_disconnect(void)
-{
- if (chrif_connected != 1)
- ShowWarning("Connection to Char Server lost.\n\n");
- chrif_connected = 0;
-
- other_mapserver_count = 0; //Reset counter. We receive ALL maps from all map-servers on reconnect.
- map_eraseallipport();
-
- //Attempt to reconnect in a second. [Skotlex]
- add_timer(gettick() + 1000, check_connect_char_server, 0, 0);
-}
-
-
-void chrif_update_ip(int fd)
-{
- uint32 new_ip;
-
- WFIFOHEAD(fd,6);
-
- new_ip = host2ip(char_ip_str);
-
- if (new_ip && new_ip != char_ip)
- char_ip = new_ip; //Update char_ip
-
- new_ip = clif_refresh_ip();
-
- if (!new_ip)
- return; //No change
-
- WFIFOW(fd,0) = 0x2736;
- WFIFOL(fd,2) = htonl(new_ip);
- WFIFOSET(fd,6);
+void chrif_on_disconnect(void) {
+ if( chrif_connected != 1 )
+ ShowWarning("Connection to Char Server lost.\n\n");
+ chrif_connected = 0;
+
+ other_mapserver_count = 0; //Reset counter. We receive ALL maps from all map-servers on reconnect.
+ map_eraseallipport();
+
+ //Attempt to reconnect in a second. [Skotlex]
+ add_timer(gettick() + 1000, check_connect_char_server, 0, 0);
+}
+
+
+void chrif_update_ip(int fd) {
+ uint32 new_ip;
+
+ WFIFOHEAD(fd,6);
+
+ new_ip = host2ip(char_ip_str);
+
+ if (new_ip && new_ip != char_ip)
+ char_ip = new_ip; //Update char_ip
+
+ new_ip = clif_refresh_ip();
+
+ if (!new_ip)
+ return; //No change
+
+ WFIFOW(fd,0) = 0x2736;
+ WFIFOL(fd,2) = htonl(new_ip);
+ WFIFOSET(fd,6);
}
// pings the charserver
-void chrif_keepalive(int fd)
-{
- WFIFOHEAD(fd,2);
- WFIFOW(fd,0) = 0x2b23;
- WFIFOSET(fd,2);
+void chrif_keepalive(int fd) {
+ WFIFOHEAD(fd,2);
+ WFIFOW(fd,0) = 0x2b23;
+ WFIFOSET(fd,2);
}
-void chrif_keepalive_ack(int fd)
-{
- session[fd]->flag.ping = 0;/* reset ping state, we received a packet */
+void chrif_keepalive_ack(int fd) {
+ session[fd]->flag.ping = 0;/* reset ping state, we received a packet */
}
/*==========================================
*
*------------------------------------------*/
-int chrif_parse(int fd)
-{
- int packet_len, cmd;
-
- // only process data from the char-server
- if (fd != char_fd) {
- ShowDebug("chrif_parse: Disconnecting invalid session #%d (is not the char-server)\n", fd);
- do_close(fd);
- return 0;
- }
-
- if (session[fd]->flag.eof) {
- do_close(fd);
- char_fd = -1;
- chrif_on_disconnect();
- return 0;
- } else if (session[fd]->flag.ping) { /* we've reached stall time */
- if (DIFF_TICK(last_tick, session[fd]->rdata_tick) > (stall_time * 2)) { /* we can't wait any longer */
- set_eof(fd);
- return 0;
- } else if (session[fd]->flag.ping != 2) { /* we haven't sent ping out yet */
- chrif_keepalive(fd);
- session[fd]->flag.ping = 2;
- }
- }
-
- while (RFIFOREST(fd) >= 2) {
- cmd = RFIFOW(fd,0);
- if (cmd < 0x2af8 || cmd >= 0x2af8 + ARRAYLENGTH(packet_len_table) || packet_len_table[cmd-0x2af8] == 0) {
- int r = intif_parse(fd); // Passed on to the intif
-
- if (r == 1) continue; // Treated in intif
- if (r == 2) return 0; // Didn't have enough data (len==-1)
-
- ShowWarning("chrif_parse: session #%d, intif_parse failed (unrecognized command 0x%.4x).\n", fd, cmd);
- set_eof(fd);
- return 0;
- }
-
- if ((packet_len = packet_len_table[cmd-0x2af8]) == -1) { // dynamic-length packet, second WORD holds the length
- if (RFIFOREST(fd) < 4)
- return 0;
- packet_len = RFIFOW(fd,2);
- }
-
- if ((int)RFIFOREST(fd) < packet_len)
- return 0;
-
- //ShowDebug("Received packet 0x%4x (%d bytes) from char-server (connection %d)\n", RFIFOW(fd,0), packet_len, fd);
-
- switch (cmd) {
- case 0x2af9:
- chrif_connectack(fd);
- break;
- case 0x2afb:
- chrif_sendmapack(fd);
- break;
- case 0x2afd:
- chrif_authok(fd);
- break;
- case 0x2b00:
- map_setusers(RFIFOL(fd,2));
- chrif_keepalive(fd);
- break;
- case 0x2b03:
- clif_charselectok(RFIFOL(fd,2), RFIFOB(fd,6));
- break;
- case 0x2b04:
- chrif_recvmap(fd);
- break;
- case 0x2b06:
- chrif_changemapserverack(RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14), RFIFOW(fd,18), RFIFOW(fd,20), RFIFOW(fd,22), RFIFOL(fd,24), RFIFOW(fd,28));
- break;
- case 0x2b09:
- map_addnickdb(RFIFOL(fd,2), (char *)RFIFOP(fd,6));
- break;
- case 0x2b0d:
- chrif_changedsex(fd);
- break;
- case 0x2b0f:
- chrif_char_ask_name_answer(RFIFOL(fd,2), (char *)RFIFOP(fd,6), RFIFOW(fd,30), RFIFOW(fd,32));
- break;
- case 0x2b12:
- chrif_divorceack(RFIFOL(fd,2), RFIFOL(fd,6));
- break;
- case 0x2b14:
- chrif_accountban(fd);
- break;
- case 0x2b1b:
- chrif_recvfamelist(fd);
- break;
- case 0x2b1d:
- chrif_load_scdata(fd);
- break;
- case 0x2b1e:
- chrif_update_ip(fd);
- break;
- case 0x2b1f:
- chrif_disconnectplayer(fd);
- break;
- case 0x2b20:
- chrif_removemap(fd);
- break;
- case 0x2b21:
- chrif_save_ack(fd);
- break;
- case 0x2b22:
- chrif_updatefamelist_ack(fd);
- break;
- case 0x2b24:
- chrif_keepalive_ack(fd);
- break;
- case 0x2b25:
- chrif_deadopt(RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10));
- break;
- case 0x2b27:
- chrif_authfail(fd);
- break;
- default:
- ShowError("chrif_parse : unknown packet (session #%d): 0x%x. Disconnecting.\n", fd, cmd);
- set_eof(fd);
- return 0;
- }
- if (fd == char_fd) //There's the slight chance we lost the connection during parse, in which case this would segfault if not checked [Skotlex]
- RFIFOSKIP(fd, packet_len);
- }
-
- return 0;
+int chrif_parse(int fd) {
+ int packet_len, cmd;
+
+ // only process data from the char-server
+ if ( fd != char_fd ) {
+ ShowDebug("chrif_parse: Disconnecting invalid session #%d (is not the char-server)\n", fd);
+ do_close(fd);
+ return 0;
+ }
+
+ if ( session[fd]->flag.eof ) {
+ do_close(fd);
+ char_fd = -1;
+ chrif_on_disconnect();
+ return 0;
+ } else if ( session[fd]->flag.ping ) {/* we've reached stall time */
+ if( DIFF_TICK(last_tick, session[fd]->rdata_tick) > (stall_time * 2) ) {/* we can't wait any longer */
+ set_eof(fd);
+ return 0;
+ } else if( session[fd]->flag.ping != 2 ) { /* we haven't sent ping out yet */
+ chrif_keepalive(fd);
+ session[fd]->flag.ping = 2;
+ }
+ }
+
+ while ( RFIFOREST(fd) >= 2 ) {
+ cmd = RFIFOW(fd,0);
+ if (cmd < 0x2af8 || cmd >= 0x2af8 + ARRAYLENGTH(packet_len_table) || packet_len_table[cmd-0x2af8] == 0) {
+ int r = intif_parse(fd); // Passed on to the intif
+
+ if (r == 1) continue; // Treated in intif
+ if (r == 2) return 0; // Didn't have enough data (len==-1)
+
+ ShowWarning("chrif_parse: session #%d, intif_parse failed (unrecognized command 0x%.4x).\n", fd, cmd);
+ set_eof(fd);
+ return 0;
+ }
+
+ if ( ( packet_len = packet_len_table[cmd-0x2af8] ) == -1) { // dynamic-length packet, second WORD holds the length
+ if (RFIFOREST(fd) < 4)
+ return 0;
+ packet_len = RFIFOW(fd,2);
+ }
+
+ if ((int)RFIFOREST(fd) < packet_len)
+ return 0;
+
+ //ShowDebug("Received packet 0x%4x (%d bytes) from char-server (connection %d)\n", RFIFOW(fd,0), packet_len, fd);
+
+ switch(cmd) {
+ case 0x2af9: chrif_connectack(fd); break;
+ case 0x2afb: chrif_sendmapack(fd); break;
+ case 0x2afd: chrif_authok(fd); break;
+ case 0x2b00: map_setusers(RFIFOL(fd,2)); chrif_keepalive(fd); break;
+ case 0x2b03: clif_charselectok(RFIFOL(fd,2), RFIFOB(fd,6)); break;
+ case 0x2b04: chrif_recvmap(fd); break;
+ case 0x2b06: chrif_changemapserverack(RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14), RFIFOW(fd,18), RFIFOW(fd,20), RFIFOW(fd,22), RFIFOL(fd,24), RFIFOW(fd,28)); break;
+ case 0x2b09: map_addnickdb(RFIFOL(fd,2), (char*)RFIFOP(fd,6)); break;
+ case 0x2b0d: chrif_changedsex(fd); break;
+ case 0x2b0f: chrif_char_ask_name_answer(RFIFOL(fd,2), (char*)RFIFOP(fd,6), RFIFOW(fd,30), RFIFOW(fd,32)); break;
+ case 0x2b12: chrif_divorceack(RFIFOL(fd,2), RFIFOL(fd,6)); break;
+ case 0x2b14: chrif_accountban(fd); break;
+ case 0x2b1b: chrif_recvfamelist(fd); break;
+ case 0x2b1d: chrif_load_scdata(fd); break;
+ case 0x2b1e: chrif_update_ip(fd); break;
+ case 0x2b1f: chrif_disconnectplayer(fd); break;
+ case 0x2b20: chrif_removemap(fd); break;
+ case 0x2b21: chrif_save_ack(fd); break;
+ case 0x2b22: chrif_updatefamelist_ack(fd); break;
+ case 0x2b24: chrif_keepalive_ack(fd); break;
+ case 0x2b25: chrif_deadopt(RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10)); break;
+ case 0x2b27: chrif_authfail(fd); break;
+ default:
+ ShowError("chrif_parse : unknown packet (session #%d): 0x%x. Disconnecting.\n", fd, cmd);
+ set_eof(fd);
+ return 0;
+ }
+ if ( fd == char_fd ) //There's the slight chance we lost the connection during parse, in which case this would segfault if not checked [Skotlex]
+ RFIFOSKIP(fd, packet_len);
+ }
+
+ return 0;
}
// unused
-int send_usercount_tochar(int tid, unsigned int tick, int id, intptr_t data)
-{
- chrif_check(-1);
+int send_usercount_tochar(int tid, unsigned int tick, int id, intptr_t data) {
+ chrif_check(-1);
- WFIFOHEAD(char_fd,4);
- WFIFOW(char_fd,0) = 0x2afe;
- WFIFOW(char_fd,2) = map_usercount();
- WFIFOSET(char_fd,4);
- return 0;
+ WFIFOHEAD(char_fd,4);
+ WFIFOW(char_fd,0) = 0x2afe;
+ WFIFOW(char_fd,2) = map_usercount();
+ WFIFOSET(char_fd,4);
+ return 0;
}
/*==========================================
* timerFunction
* Send to char the number of client connected to map
*------------------------------------------*/
-int send_users_tochar(void)
-{
- int users = 0, i = 0;
- struct map_session_data *sd;
- struct s_mapiterator *iter;
-
- chrif_check(-1);
-
- users = map_usercount();
-
- WFIFOHEAD(char_fd, 6+8*users);
- WFIFOW(char_fd,0) = 0x2aff;
-
- iter = mapit_getallusers();
-
- for (sd = (TBL_PC *)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC *)mapit_next(iter)) {
- WFIFOL(char_fd,6+8*i) = sd->status.account_id;
- WFIFOL(char_fd,6+8*i+4) = sd->status.char_id;
- i++;
- }
-
- mapit_free(iter);
-
- WFIFOW(char_fd,2) = 6 + 8*users;
- WFIFOW(char_fd,4) = users;
- WFIFOSET(char_fd, 6+8*users);
-
- return 0;
+int send_users_tochar(void) {
+ int users = 0, i = 0;
+ struct map_session_data* sd;
+ struct s_mapiterator* iter;
+
+ chrif_check(-1);
+
+ users = map_usercount();
+
+ WFIFOHEAD(char_fd, 6+8*users);
+ WFIFOW(char_fd,0) = 0x2aff;
+
+ iter = mapit_getallusers();
+
+ for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) ) {
+ WFIFOL(char_fd,6+8*i) = sd->status.account_id;
+ WFIFOL(char_fd,6+8*i+4) = sd->status.char_id;
+ i++;
+ }
+
+ mapit_free(iter);
+
+ WFIFOW(char_fd,2) = 6 + 8*users;
+ WFIFOW(char_fd,4) = users;
+ WFIFOSET(char_fd, 6+8*users);
+
+ return 0;
}
/*==========================================
* timerFunction
* Chk the connection to char server, (if it down)
*------------------------------------------*/
-static int check_connect_char_server(int tid, unsigned int tick, int id, intptr_t data)
-{
- static int displayed = 0;
- if (char_fd <= 0 || session[char_fd] == NULL) {
- 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,false);
-
- if (char_fd == -1)//Attempt to connect later. [Skotlex]
- return 0;
-
- session[char_fd]->func_parse = chrif_parse;
- session[char_fd]->flag.server = 1;
- realloc_fifo(char_fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
-
- chrif_connect(char_fd);
- chrif_connected = (chrif_state == 2);
- srvinfo = 0;
- } else {
- if (srvinfo == 0) {
- chrif_ragsrvinfo(battle_config.base_exp_rate, battle_config.job_exp_rate, battle_config.item_rate_common);
- srvinfo = 1;
- }
- }
- if (chrif_isconnected())
- displayed = 0;
- return 0;
+static int check_connect_char_server(int tid, unsigned int tick, int id, intptr_t data) {
+ static int displayed = 0;
+ if ( char_fd <= 0 || session[char_fd] == NULL ) {
+ 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,false);
+
+ if (char_fd == -1)//Attempt to connect later. [Skotlex]
+ return 0;
+
+ session[char_fd]->func_parse = chrif_parse;
+ session[char_fd]->flag.server = 1;
+ realloc_fifo(char_fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
+
+ chrif_connect(char_fd);
+ chrif_connected = (chrif_state == 2);
+ srvinfo = 0;
+ } else {
+ if (srvinfo == 0) {
+ chrif_ragsrvinfo(battle_config.base_exp_rate, battle_config.job_exp_rate, battle_config.item_rate_common);
+ srvinfo = 1;
+ }
+ }
+ if ( chrif_isconnected() )
+ displayed = 0;
+ return 0;
}
/*==========================================
* Asks char server to remove friend_id from the friend list of char_id
*------------------------------------------*/
-int chrif_removefriend(int char_id, int friend_id)
-{
-
- chrif_check(-1);
+int chrif_removefriend(int char_id, int friend_id) {
- WFIFOHEAD(char_fd,10);
- WFIFOW(char_fd,0) = 0x2b07;
- WFIFOL(char_fd,2) = char_id;
- WFIFOL(char_fd,6) = friend_id;
- WFIFOSET(char_fd,10);
+ chrif_check(-1);
- return 0;
+ WFIFOHEAD(char_fd,10);
+ WFIFOW(char_fd,0) = 0x2b07;
+ WFIFOL(char_fd,2) = char_id;
+ WFIFOL(char_fd,6) = friend_id;
+ WFIFOSET(char_fd,10);
+
+ return 0;
}
-void chrif_send_report(char *buf, int len)
-{
+void chrif_send_report(char* buf, int len) {
#ifndef STATS_OPT_OUT
- WFIFOHEAD(char_fd,len + 2);
-
- WFIFOW(char_fd,0) = 0x3008;
-
- memcpy(WFIFOP(char_fd,2), buf, len);
-
- WFIFOSET(char_fd,len + 2);
-
- flush_fifo(char_fd); /* ensure it's sent now. */
+ WFIFOHEAD(char_fd,len + 2);
+
+ WFIFOW(char_fd,0) = 0x3008;
+
+ memcpy(WFIFOP(char_fd,2), buf, len);
+
+ WFIFOSET(char_fd,len + 2);
+
+ flush_fifo(char_fd); /* ensure it's sent now. */
#endif
}
@@ -1710,59 +1568,56 @@ void chrif_send_report(char *buf, int len)
/**
* @see DBApply
*/
-int auth_db_final(DBKey key, DBData *data, va_list ap)
-{
- struct auth_node *node = db_data2ptr(data);
-
- if (node->char_dat)
- aFree(node->char_dat);
-
- if (node->sd)
- aFree(node->sd);
-
- ers_free(auth_db_ers, node);
-
- return 0;
+int auth_db_final(DBKey key, DBData *data, va_list ap) {
+ struct auth_node *node = db_data2ptr(data);
+
+ if (node->char_dat)
+ aFree(node->char_dat);
+
+ if (node->sd)
+ aFree(node->sd);
+
+ ers_free(auth_db_ers, node);
+
+ return 0;
}
/*==========================================
* Destructor
*------------------------------------------*/
-int do_final_chrif(void)
-{
+int do_final_chrif(void) {
+
+ if( char_fd != -1 ) {
+ do_close(char_fd);
+ char_fd = -1;
+ }
- if (char_fd != -1) {
- do_close(char_fd);
- char_fd = -1;
- }
-
- auth_db->destroy(auth_db, auth_db_final);
-
- ers_destroy(auth_db_ers);
-
- return 0;
+ auth_db->destroy(auth_db, auth_db_final);
+
+ ers_destroy(auth_db_ers);
+
+ return 0;
}
/*==========================================
*
*------------------------------------------*/
-int do_init_chrif(void)
-{
-
- auth_db = idb_alloc(DB_OPT_BASE);
- auth_db_ers = ers_new(sizeof(struct auth_node),"chrif.c::auth_db_ers",ERS_OPT_NONE);
+int do_init_chrif(void) {
+
+ auth_db = idb_alloc(DB_OPT_BASE);
+ auth_db_ers = ers_new(sizeof(struct auth_node),"chrif.c::auth_db_ers",ERS_OPT_NONE);
- add_timer_func_list(check_connect_char_server, "check_connect_char_server");
- add_timer_func_list(auth_db_cleanup, "auth_db_cleanup");
+ add_timer_func_list(check_connect_char_server, "check_connect_char_server");
+ add_timer_func_list(auth_db_cleanup, "auth_db_cleanup");
- // establish map-char connection if not present
- add_timer_interval(gettick() + 1000, check_connect_char_server, 0, 0, 10 * 1000);
+ // establish map-char connection if not present
+ add_timer_interval(gettick() + 1000, check_connect_char_server, 0, 0, 10 * 1000);
- // wipe stale data for timed-out client connection requests
- add_timer_interval(gettick() + 1000, auth_db_cleanup, 0, 0, 30 * 1000);
+ // wipe stale data for timed-out client connection requests
+ add_timer_interval(gettick() + 1000, auth_db_cleanup, 0, 0, 30 * 1000);
- // send the user count every 10 seconds, to hide the charserver's online counting problem
- add_timer_interval(gettick() + 1000, send_usercount_tochar, 0, 0, UPDATE_INTERVAL);
+ // send the user count every 10 seconds, to hide the charserver's online counting problem
+ add_timer_interval(gettick() + 1000, send_usercount_tochar, 0, 0, UPDATE_INTERVAL);
- return 0;
+ return 0;
}
diff --git a/src/map/chrif.h b/src/map/chrif.h
index f4dc98acd..0aadb1a7b 100644
--- a/src/map/chrif.h
+++ b/src/map/chrif.h
@@ -9,19 +9,19 @@
enum sd_state { ST_LOGIN, ST_LOGOUT, ST_MAPCHANGE };
struct auth_node {
- int account_id, char_id;
- int login_id1, login_id2, sex, fd;
- time_t expiration_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited)
- struct map_session_data *sd; //Data from logged on char.
- struct mmo_charstatus *char_dat; //Data from char server.
- unsigned int node_created; //timestamp for node timeouts
- enum sd_state state; //To track whether player was login in/out or changing maps.
+ int account_id, char_id;
+ int login_id1, login_id2, sex, fd;
+ time_t expiration_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited)
+ struct map_session_data *sd; //Data from logged on char.
+ struct mmo_charstatus *char_dat; //Data from char server.
+ unsigned int node_created; //timestamp for node timeouts
+ enum sd_state state; //To track whether player was login in/out or changing maps.
};
-void chrif_setuserid(char *id);
-void chrif_setpasswd(char *pwd);
+void chrif_setuserid(char* id);
+void chrif_setpasswd(char* pwd);
void chrif_checkdefaultlogin(void);
-int chrif_setip(const char *ip);
+int chrif_setip(const char* ip);
void chrif_setport(uint16 port);
int chrif_isconnected(void);
@@ -30,21 +30,21 @@ void chrif_check_shutdown(void);
extern int chrif_connected;
extern int other_mapserver_count;
-struct auth_node *chrif_search(int account_id);
-struct auth_node *chrif_auth_check(int account_id, int char_id, enum sd_state state);
+struct auth_node* chrif_search(int account_id);
+struct auth_node* chrif_auth_check(int account_id, int char_id, enum sd_state state);
bool chrif_auth_delete(int account_id, int char_id, enum sd_state state);
-bool chrif_auth_finished(struct map_session_data *sd);
+bool chrif_auth_finished(struct map_session_data* sd);
-void chrif_authreq(struct map_session_data *sd);
+void chrif_authreq(struct map_session_data* sd);
void chrif_authok(int fd);
int chrif_scdata_request(int account_id, int char_id);
-int chrif_save(struct map_session_data *sd, int flag);
-int chrif_charselectreq(struct map_session_data *sd, uint32 s_ip);
-int chrif_changemapserver(struct map_session_data *sd, uint32 ip, uint16 port);
+int chrif_save(struct map_session_data* sd, int flag);
+int chrif_charselectreq(struct map_session_data* sd, uint32 s_ip);
+int chrif_changemapserver(struct map_session_data* sd, uint32 ip, uint16 port);
int chrif_searchcharid(int char_id);
int chrif_changeemail(int id, const char *actual_email, const char *new_email);
-int chrif_char_ask_name(int acc, const char *character_name, unsigned short operation_type, int year, int month, int day, int hour, int minute, int second);
+int chrif_char_ask_name(int acc, const char* character_name, unsigned short operation_type, int year, int month, int day, int hour, int minute, int second);
int chrif_updatefamelist(struct map_session_data *sd);
int chrif_buildfamelist(void);
int chrif_save_scdata(struct map_session_data *sd);
@@ -59,7 +59,7 @@ int chrif_chardisconnect(struct map_session_data *sd);
int chrif_divorce(int partner_id1, int partner_id2);
int chrif_removefriend(int char_id, int friend_id);
-void chrif_send_report(char *buf, int len);
+void chrif_send_report(char* buf, int len);
int do_final_chrif(void);
int do_init_chrif(void);
diff --git a/src/map/clif.c b/src/map/clif.c
index 362930b84..5e7c7f9bf 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -56,8 +56,8 @@ static struct eri *delay_clearunit_ers;
//#define DUMP_INVALID_PACKET
struct Clif_Config {
- int packet_db_ver; //Preferred packet version.
- int connect_cmd[MAX_PACKET_VER + 1]; //Store the connect command for all versions. [Skotlex]
+ int packet_db_ver; //Preferred packet version.
+ int connect_cmd[MAX_PACKET_VER + 1]; //Store the connect command for all versions. [Skotlex]
} clif_config;
struct s_packet_db packet_db[MAX_PACKET_VER + 1][MAX_PACKET_DB + 1];
@@ -65,120 +65,120 @@ struct s_packet_db packet_db[MAX_PACKET_VER + 1][MAX_PACKET_DB + 1];
//Converts item type in case of pet eggs.
static inline int itemtype(int type)
{
- return (type == IT_PETEGG) ? IT_WEAPON : type;
+ return ( type == IT_PETEGG ) ? IT_WEAPON : type;
}
-static inline void WBUFPOS(uint8 *p, unsigned short pos, short x, short y, unsigned char dir)
+static inline void WBUFPOS(uint8* p, unsigned short pos, short x, short y, unsigned char dir)
{
- p += pos;
- p[0] = (uint8)(x>>2);
- p[1] = (uint8)((x<<6) | ((y>>4)&0x3f));
- p[2] = (uint8)((y<<4) | (dir&0xf));
+ p += pos;
+ p[0] = (uint8)(x>>2);
+ p[1] = (uint8)((x<<6) | ((y>>4)&0x3f));
+ p[2] = (uint8)((y<<4) | (dir&0xf));
}
// client-side: x0+=sx0*0.0625-0.5 and y0+=sy0*0.0625-0.5
-static inline void WBUFPOS2(uint8 *p, unsigned short pos, short x0, short y0, short x1, short y1, unsigned char sx0, unsigned char sy0)
+static inline void WBUFPOS2(uint8* p, unsigned short pos, short x0, short y0, short x1, short y1, unsigned char sx0, unsigned char sy0)
{
- p += pos;
- p[0] = (uint8)(x0>>2);
- p[1] = (uint8)((x0<<6) | ((y0>>4)&0x3f));
- p[2] = (uint8)((y0<<4) | ((x1>>6)&0x0f));
- p[3] = (uint8)((x1<<2) | ((y1>>8)&0x03));
- p[4] = (uint8)y1;
- p[5] = (uint8)((sx0<<4) | (sy0&0x0f));
+ p += pos;
+ p[0] = (uint8)(x0>>2);
+ p[1] = (uint8)((x0<<6) | ((y0>>4)&0x3f));
+ p[2] = (uint8)((y0<<4) | ((x1>>6)&0x0f));
+ p[3] = (uint8)((x1<<2) | ((y1>>8)&0x03));
+ p[4] = (uint8)y1;
+ p[5] = (uint8)((sx0<<4) | (sy0&0x0f));
}
static inline void WFIFOPOS(int fd, unsigned short pos, short x, short y, unsigned char dir)
{
- WBUFPOS(WFIFOP(fd,pos), 0, x, y, dir);
+ WBUFPOS(WFIFOP(fd,pos), 0, x, y, dir);
}
static inline void WFIFOPOS2(int fd, unsigned short pos, short x0, short y0, short x1, short y1, unsigned char sx0, unsigned char sy0)
{
- WBUFPOS2(WFIFOP(fd,pos), 0, x0, y0, x1, y1, sx0, sy0);
+ WBUFPOS2(WFIFOP(fd,pos), 0, x0, y0, x1, y1, sx0, sy0);
}
-static inline void RBUFPOS(const uint8 *p, unsigned short pos, short *x, short *y, unsigned char *dir)
+static inline void RBUFPOS(const uint8* p, unsigned short pos, short* x, short* y, unsigned char* dir)
{
- p += pos;
+ p += pos;
- if (x) {
- x[0] = ((p[0] & 0xff) << 2) | (p[1] >> 6);
- }
+ if( x ) {
+ x[0] = ( ( p[0] & 0xff ) << 2 ) | ( p[1] >> 6 );
+ }
- if (y) {
- y[0] = ((p[1] & 0x3f) << 4) | (p[2] >> 4);
- }
+ if( y ) {
+ y[0] = ( ( p[1] & 0x3f ) << 4 ) | ( p[2] >> 4 );
+ }
- if (dir) {
- dir[0] = (p[2] & 0x0f);
- }
+ if( dir ) {
+ dir[0] = ( p[2] & 0x0f );
+ }
}
-static inline void RBUFPOS2(const uint8 *p, unsigned short pos, short *x0, short *y0, short *x1, short *y1, unsigned char *sx0, unsigned char *sy0)
+static inline void RBUFPOS2(const uint8* p, unsigned short pos, short* x0, short* y0, short* x1, short* y1, unsigned char* sx0, unsigned char* sy0)
{
- p += pos;
+ p += pos;
- if (x0) {
- x0[0] = ((p[0] & 0xff) << 2) | (p[1] >> 6);
- }
+ if( x0 ) {
+ x0[0] = ( ( p[0] & 0xff ) << 2 ) | ( p[1] >> 6 );
+ }
- if (y0) {
- y0[0] = ((p[1] & 0x3f) << 4) | (p[2] >> 4);
- }
+ if( y0 ) {
+ y0[0] = ( ( p[1] & 0x3f ) << 4 ) | ( p[2] >> 4 );
+ }
- if (x1) {
- x1[0] = ((p[2] & 0x0f) << 6) | (p[3] >> 2);
- }
+ if( x1 ) {
+ x1[0] = ( ( p[2] & 0x0f ) << 6 ) | ( p[3] >> 2 );
+ }
- if (y1) {
- y1[0] = ((p[3] & 0x03) << 8) | (p[4] >> 0);
- }
+ if( y1 ) {
+ y1[0] = ( ( p[3] & 0x03 ) << 8 ) | ( p[4] >> 0 );
+ }
- if (sx0) {
- sx0[0] = (p[5] & 0xf0) >> 4;
- }
+ if( sx0 ) {
+ sx0[0] = ( p[5] & 0xf0 ) >> 4;
+ }
- if (sy0) {
- sy0[0] = (p[5] & 0x0f) >> 0;
- }
+ if( sy0 ) {
+ sy0[0] = ( p[5] & 0x0f ) >> 0;
+ }
}
-static inline void RFIFOPOS(int fd, unsigned short pos, short *x, short *y, unsigned char *dir)
+static inline void RFIFOPOS(int fd, unsigned short pos, short* x, short* y, unsigned char* dir)
{
- RBUFPOS(RFIFOP(fd,pos), 0, x, y, dir);
+ RBUFPOS(RFIFOP(fd,pos), 0, x, y, dir);
}
-static inline void RFIFOPOS2(int fd, unsigned short pos, short *x0, short *y0, short *x1, short *y1, unsigned char *sx0, unsigned char *sy0)
+static inline void RFIFOPOS2(int fd, unsigned short pos, short* x0, short* y0, short* x1, short* y1, unsigned char* sx0, unsigned char* sy0)
{
- RBUFPOS2(WFIFOP(fd,pos), 0, x0, y0, x1, y1, sx0, sy0);
+ RBUFPOS2(WFIFOP(fd,pos), 0, x0, y0, x1, y1, sx0, sy0);
}
//To idenfity disguised characters.
-static inline bool disguised(struct block_list *bl)
+static inline bool disguised(struct block_list* bl)
{
- return (bool)(bl->type == BL_PC && ((TBL_PC *)bl)->disguise);
+ return (bool)( bl->type == BL_PC && ((TBL_PC*)bl)->disguise );
}
//Guarantees that the given string does not exceeds the allowed size, as well as making sure it's null terminated. [Skotlex]
-static inline unsigned int mes_len_check(char *mes, unsigned int len, unsigned int max)
+static inline unsigned int mes_len_check(char* mes, unsigned int len, unsigned int max)
{
- if (len > max)
- len = max;
+ if( len > max )
+ len = max;
- mes[len-1] = '\0';
+ mes[len-1] = '\0';
- return len;
+ return len;
}
@@ -188,34 +188,34 @@ static uint32 bind_ip = INADDR_ANY;
static uint16 map_port = 5121;
int map_fd;
-static int clif_parse(int fd);
+static int clif_parse (int fd);
/*==========================================
* Ip setting of map-server
*------------------------------------------*/
-int clif_setip(const char *ip)
+int clif_setip(const char* ip)
{
- char ip_str[16];
- map_ip = host2ip(ip);
- if (!map_ip) {
- ShowWarning("Failed to Resolve Map Server Address! (%s)\n", ip);
- return 0;
- }
+ char ip_str[16];
+ map_ip = host2ip(ip);
+ if (!map_ip) {
+ ShowWarning("Failed to Resolve Map Server Address! (%s)\n", ip);
+ return 0;
+ }
- strncpy(map_ip_str, ip, sizeof(map_ip_str));
- ShowInfo("Map Server IP Address : '"CL_WHITE"%s"CL_RESET"' -> '"CL_WHITE"%s"CL_RESET"'.\n", ip, ip2str(map_ip, ip_str));
- return 1;
+ strncpy(map_ip_str, ip, sizeof(map_ip_str));
+ ShowInfo("Map Server IP Address : '"CL_WHITE"%s"CL_RESET"' -> '"CL_WHITE"%s"CL_RESET"'.\n", ip, ip2str(map_ip, ip_str));
+ return 1;
}
-void clif_setbindip(const char *ip)
+void clif_setbindip(const char* ip)
{
- char ip_str[16];
- bind_ip = host2ip(ip);
- if (bind_ip) {
- ShowInfo("Map Server Bind IP Address : '"CL_WHITE"%s"CL_RESET"' -> '"CL_WHITE"%s"CL_RESET"'.\n", ip, ip2str(bind_ip, ip_str));
- } else {
- ShowWarning("Failed to Resolve Map Server Address! (%s)\n", ip);
- }
+ char ip_str[16];
+ bind_ip = host2ip(ip);
+ if (bind_ip) {
+ ShowInfo("Map Server Bind IP Address : '"CL_WHITE"%s"CL_RESET"' -> '"CL_WHITE"%s"CL_RESET"'.\n", ip, ip2str(bind_ip, ip_str));
+ } else {
+ ShowWarning("Failed to Resolve Map Server Address! (%s)\n", ip);
+ }
}
/*==========================================
@@ -224,7 +224,7 @@ void clif_setbindip(const char *ip)
*------------------------------------------*/
void clif_setport(uint16 port)
{
- map_port = port;
+ map_port = port;
}
/*==========================================
@@ -232,21 +232,21 @@ void clif_setport(uint16 port)
*------------------------------------------*/
uint32 clif_getip(void)
{
- return map_ip;
+ return map_ip;
}
//Refreshes map_server ip, returns the new ip if the ip changed, otherwise it returns 0.
uint32 clif_refresh_ip(void)
{
- uint32 new_ip;
+ uint32 new_ip;
- new_ip = host2ip(map_ip_str);
- if (new_ip && new_ip != map_ip) {
- map_ip = new_ip;
- ShowInfo("Updating IP resolution of [%s].\n", map_ip_str);
- return map_ip;
- }
- return 0;
+ new_ip = host2ip(map_ip_str);
+ if (new_ip && new_ip != map_ip) {
+ map_ip = new_ip;
+ ShowInfo("Updating IP resolution of [%s].\n", map_ip_str);
+ return map_ip;
+ }
+ return 0;
}
/*==========================================
@@ -254,36 +254,24 @@ uint32 clif_refresh_ip(void)
*------------------------------------------*/
uint16 clif_getport(void)
{
- return map_port;
+ return map_port;
}
#if PACKETVER >= 20071106
-static inline unsigned char clif_bl_type(struct block_list *bl)
-{
- switch (bl->type) {
- case BL_PC:
- return disguised(bl)?0x1:0x0; //PC_TYPE
- case BL_ITEM:
- return 0x2; //ITEM_TYPE
- case BL_SKILL:
- return 0x3; //SKILL_TYPE
- case BL_CHAT:
- return 0x4; //UNKNOWN_TYPE
- case BL_MOB:
- return pcdb_checkid(status_get_viewdata(bl)->class_)?0x0:0x5; //NPC_MOB_TYPE
- case BL_NPC:
- return 0x6; //NPC_EVT_TYPE
- case BL_PET:
- return pcdb_checkid(status_get_viewdata(bl)->class_)?0x0:0x7; //NPC_PET_TYPE
- case BL_HOM:
- return 0x8; //NPC_HOM_TYPE
- case BL_MER:
- return 0x9; //NPC_MERSOL_TYPE
- case BL_ELEM:
- return 0xa; //NPC_ELEMENTAL_TYPE
- default:
- return 0x1; //NPC_TYPE
- }
+static inline unsigned char clif_bl_type(struct block_list *bl) {
+ switch (bl->type) {
+ case BL_PC: return disguised(bl)?0x1:0x0; //PC_TYPE
+ case BL_ITEM: return 0x2; //ITEM_TYPE
+ case BL_SKILL: return 0x3; //SKILL_TYPE
+ case BL_CHAT: return 0x4; //UNKNOWN_TYPE
+ case BL_MOB: return pcdb_checkid(status_get_viewdata(bl)->class_)?0x0:0x5; //NPC_MOB_TYPE
+ case BL_NPC: return 0x6; //NPC_EVT_TYPE
+ case BL_PET: return pcdb_checkid(status_get_viewdata(bl)->class_)?0x0:0x7; //NPC_PET_TYPE
+ case BL_HOM: return 0x8; //NPC_HOM_TYPE
+ case BL_MER: return 0x9; //NPC_MERSOL_TYPE
+ case BL_ELEM: return 0xa; //NPC_ELEMENTAL_TYPE
+ default: return 0x1; //NPC_TYPE
+ }
}
#endif
@@ -299,338 +287,352 @@ static inline unsigned char clif_bl_type(struct block_list *bl)
*------------------------------------------*/
static int clif_send_sub(struct block_list *bl, va_list ap)
{
- struct block_list *src_bl;
- struct map_session_data *sd;
- unsigned char *buf;
- int len, type, fd;
-
- nullpo_ret(bl);
- nullpo_ret(sd = (struct map_session_data *)bl);
-
- fd = sd->fd;
- if (!fd) //Don't send to disconnected clients.
- return 0;
-
- buf = va_arg(ap,unsigned char *);
- len = va_arg(ap,int);
- nullpo_ret(src_bl = va_arg(ap,struct block_list *));
- type = va_arg(ap,int);
-
- switch (type) {
- case AREA_WOS:
- if (bl == src_bl)
- return 0;
- break;
- case AREA_WOC:
- if (sd->chatID || bl == src_bl)
- return 0;
- break;
- case AREA_WOSC: {
- if (src_bl->type == BL_PC) {
- struct map_session_data *ssd = (struct map_session_data *)src_bl;
- if (ssd && sd->chatID && (sd->chatID == ssd->chatID))
- return 0;
- } else if (src_bl->type == BL_NPC) {
- struct npc_data *nd = (struct npc_data *)src_bl;
- if (nd && sd->chatID && (sd->chatID == nd->chat_id))
- return 0;
- }
- }
- break;
- }
-
- if (session[fd] == NULL)
- return 0;
-
- WFIFOHEAD(fd, len);
- if (WFIFOP(fd,0) == buf) {
- ShowError("WARNING: Invalid use of clif_send function\n");
- ShowError(" Packet x%4x use a WFIFO of a player instead of to use a buffer.\n", WBUFW(buf,0));
- ShowError(" Please correct your code.\n");
- // don't send to not move the pointer of the packet for next sessions in the loop
- //WFIFOSET(fd,0);//## TODO is this ok?
- //NO. It is not ok. There is the chance WFIFOSET actually sends the buffer data, and shifts elements around, which will corrupt the buffer.
- return 0;
- }
-
- if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
- memcpy(WFIFOP(fd,0), buf, len);
- WFIFOSET(fd,len);
- }
-
- return 0;
+ struct block_list *src_bl;
+ struct map_session_data *sd;
+ unsigned char *buf;
+ int len, type, fd;
+
+ nullpo_ret(bl);
+ nullpo_ret(sd = (struct map_session_data *)bl);
+
+ fd = sd->fd;
+ if (!fd) //Don't send to disconnected clients.
+ return 0;
+
+ buf = va_arg(ap,unsigned char*);
+ len = va_arg(ap,int);
+ nullpo_ret(src_bl = va_arg(ap,struct block_list*));
+ type = va_arg(ap,int);
+
+ switch(type)
+ {
+ case AREA_WOS:
+ if (bl == src_bl)
+ return 0;
+ break;
+ case AREA_WOC:
+ if (sd->chatID || bl == src_bl)
+ return 0;
+ break;
+ case AREA_WOSC:
+ {
+ if(src_bl->type == BL_PC){
+ struct map_session_data *ssd = (struct map_session_data *)src_bl;
+ if (ssd && sd->chatID && (sd->chatID == ssd->chatID))
+ return 0;
+ }
+ else if(src_bl->type == BL_NPC) {
+ struct npc_data *nd = (struct npc_data *)src_bl;
+ if (nd && sd->chatID && (sd->chatID == nd->chat_id))
+ return 0;
+ }
+ }
+ break;
+ }
+
+ if (session[fd] == NULL)
+ return 0;
+
+ WFIFOHEAD(fd, len);
+ if (WFIFOP(fd,0) == buf) {
+ ShowError("WARNING: Invalid use of clif_send function\n");
+ ShowError(" Packet x%4x use a WFIFO of a player instead of to use a buffer.\n", WBUFW(buf,0));
+ ShowError(" Please correct your code.\n");
+ // don't send to not move the pointer of the packet for next sessions in the loop
+ //WFIFOSET(fd,0);//## TODO is this ok?
+ //NO. It is not ok. There is the chance WFIFOSET actually sends the buffer data, and shifts elements around, which will corrupt the buffer.
+ return 0;
+ }
+
+ if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
+ memcpy(WFIFOP(fd,0), buf, len);
+ WFIFOSET(fd,len);
+ }
+
+ return 0;
}
/*==========================================
* Packet Delegation (called on all packets that require data to be sent to more than one client)
* functions that are sent solely to one use whose ID it posses use WFIFOSET
*------------------------------------------*/
-int clif_send(const uint8 *buf, int len, struct block_list *bl, enum send_target type)
-{
- int i;
- struct map_session_data *sd, *tsd;
- struct party_data *p = NULL;
- struct guild *g = NULL;
- struct battleground_data *bg = NULL;
- int x0 = 0, x1 = 0, y0 = 0, y1 = 0, fd;
- struct s_mapiterator *iter;
-
- if (type != ALL_CLIENT && type != CHAT_MAINCHAT)
- nullpo_ret(bl);
-
- sd = BL_CAST(BL_PC, bl);
-
- switch (type) {
-
- case ALL_CLIENT: //All player clients.
- iter = mapit_getallusers();
- while ((tsd = (TBL_PC *)mapit_next(iter)) != NULL) {
- if (packet_db[tsd->packet_ver][RBUFW(buf,0)].len) {
- // packet must exist for the client version
- WFIFOHEAD(tsd->fd, len);
- memcpy(WFIFOP(tsd->fd,0), buf, len);
- WFIFOSET(tsd->fd,len);
- }
- }
- mapit_free(iter);
- break;
-
- case ALL_SAMEMAP: //All players on the same map
- iter = mapit_getallusers();
- while ((tsd = (TBL_PC *)mapit_next(iter)) != NULL) {
- if (bl->m == tsd->bl.m && packet_db[tsd->packet_ver][RBUFW(buf,0)].len) {
- // packet must exist for the client version
- WFIFOHEAD(tsd->fd, len);
- memcpy(WFIFOP(tsd->fd,0), buf, len);
- WFIFOSET(tsd->fd,len);
- }
- }
- mapit_free(iter);
- break;
-
- case AREA:
- case AREA_WOSC:
- if (sd && bl->prev == NULL) //Otherwise source misses the packet.[Skotlex]
- clif_send(buf, len, bl, SELF);
- case AREA_WOC:
- case AREA_WOS:
- map_foreachinarea(clif_send_sub, bl->m, bl->x-AREA_SIZE, bl->y-AREA_SIZE, bl->x+AREA_SIZE, bl->y+AREA_SIZE,
- BL_PC, buf, len, bl, type);
- break;
- case AREA_CHAT_WOC:
- map_foreachinarea(clif_send_sub, bl->m, bl->x-(AREA_SIZE-5), bl->y-(AREA_SIZE-5),
- bl->x+(AREA_SIZE-5), bl->y+(AREA_SIZE-5), BL_PC, buf, len, bl, AREA_WOC);
- break;
-
- case CHAT:
- case CHAT_WOS: {
- 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 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 ((fd=cd->usersd[i]->fd) >0 && session[fd]) { // Added check to see if session exists [PoW]
- WFIFOHEAD(fd,len);
- memcpy(WFIFOP(fd,0), buf, len);
- WFIFOSET(fd,len);
- }
- }
- }
- }
- break;
-
- case CHAT_MAINCHAT: //[LuzZza]
- iter = mapit_getallusers();
- while ((tsd = (TBL_PC *)mapit_next(iter)) != NULL) {
- if (tsd->state.mainchat && tsd->chatID == 0 && packet_db[tsd->packet_ver][RBUFW(buf,0)].len) {
- // packet must exist for the client version
- WFIFOHEAD(tsd->fd, len);
- memcpy(WFIFOP(tsd->fd,0), buf, len);
- WFIFOSET(tsd->fd,len);
- }
- }
- mapit_free(iter);
- break;
-
- case PARTY_AREA:
- case PARTY_AREA_WOS:
- x0 = bl->x - AREA_SIZE;
- y0 = bl->y - AREA_SIZE;
- x1 = bl->x + AREA_SIZE;
- y1 = bl->y + AREA_SIZE;
- case PARTY:
- case PARTY_WOS:
- case PARTY_SAMEMAP:
- case PARTY_SAMEMAP_WOS:
- if (sd && sd->status.party_id)
- p = party_search(sd->status.party_id);
-
- if (p) {
- for (i=0; i<MAX_PARTY; i++) {
- if ((sd = p->data[i].sd) == NULL)
- continue;
-
- if (!(fd=sd->fd))
- continue;
-
- if (sd->bl.id == bl->id && (type == PARTY_WOS || type == PARTY_SAMEMAP_WOS || type == PARTY_AREA_WOS))
- continue;
-
- if (type != PARTY && type != PARTY_WOS && bl->m != sd->bl.m)
- continue;
-
- if ((type == PARTY_AREA || type == PARTY_AREA_WOS) && (sd->bl.x < x0 || sd->bl.y < y0 || sd->bl.x > x1 || sd->bl.y > y1))
- continue;
-
- if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) {
- // packet must exist for the client version
- WFIFOHEAD(fd,len);
- memcpy(WFIFOP(fd,0), buf, len);
- WFIFOSET(fd,len);
- }
- }
- if (!enable_spy) //Skip unnecessary parsing. [Skotlex]
- break;
-
- iter = mapit_getallusers();
- while ((tsd = (TBL_PC *)mapit_next(iter)) != NULL) {
- if (tsd->partyspy == p->party.party_id && packet_db[tsd->packet_ver][RBUFW(buf,0)].len) {
- // packet must exist for the client version
- WFIFOHEAD(tsd->fd, len);
- memcpy(WFIFOP(tsd->fd,0), buf, len);
- WFIFOSET(tsd->fd,len);
- }
- }
- mapit_free(iter);
- }
- break;
-
- case DUEL:
- case DUEL_WOS:
- if (!sd || !sd->duel_group) break; //Invalid usage.
-
- iter = mapit_getallusers();
- while ((tsd = (TBL_PC *)mapit_next(iter)) != NULL) {
- if (type == DUEL_WOS && bl->id == tsd->bl.id)
- continue;
- if (sd->duel_group == tsd->duel_group && packet_db[tsd->packet_ver][RBUFW(buf,0)].len) {
- // packet must exist for the client version
- WFIFOHEAD(tsd->fd, len);
- memcpy(WFIFOP(tsd->fd,0), buf, len);
- WFIFOSET(tsd->fd,len);
- }
- }
- mapit_free(iter);
- break;
-
- case SELF:
- if (sd && (fd=sd->fd) && packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
- WFIFOHEAD(fd,len);
- memcpy(WFIFOP(fd,0), buf, len);
- WFIFOSET(fd,len);
- }
- break;
-
- // New definitions for guilds [Valaris] - Cleaned up and reorganized by [Skotlex]
- case GUILD_AREA:
- case GUILD_AREA_WOS:
- x0 = bl->x - AREA_SIZE;
- y0 = bl->y - AREA_SIZE;
- x1 = bl->x + AREA_SIZE;
- y1 = bl->y + AREA_SIZE;
- case GUILD_SAMEMAP:
- case GUILD_SAMEMAP_WOS:
- case GUILD:
- case GUILD_WOS:
- case GUILD_NOBG:
- if (sd && sd->status.guild_id)
- g = guild_search(sd->status.guild_id);
-
- if (g) {
- for (i = 0; i < g->max_member; i++) {
- if ((sd = g->member[i].sd) != NULL) {
- if (!(fd=sd->fd))
- continue;
-
- if (type == GUILD_NOBG && sd->bg_id)
- continue;
-
- if (sd->bl.id == bl->id && (type == GUILD_WOS || type == GUILD_SAMEMAP_WOS || type == GUILD_AREA_WOS))
- continue;
-
- if (type != GUILD && type != GUILD_NOBG && type != GUILD_WOS && sd->bl.m != bl->m)
- continue;
-
- if ((type == GUILD_AREA || type == GUILD_AREA_WOS) && (sd->bl.x < x0 || sd->bl.y < y0 || sd->bl.x > x1 || sd->bl.y > y1))
- continue;
-
- if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) {
- // packet must exist for the client version
- WFIFOHEAD(fd,len);
- memcpy(WFIFOP(fd,0), buf, len);
- WFIFOSET(fd,len);
- }
- }
- }
- if (!enable_spy) //Skip unnecessary parsing. [Skotlex]
- break;
-
- iter = mapit_getallusers();
- while ((tsd = (TBL_PC *)mapit_next(iter)) != NULL) {
- if (tsd->guildspy == g->guild_id && packet_db[tsd->packet_ver][RBUFW(buf,0)].len) {
- // packet must exist for the client version
- WFIFOHEAD(tsd->fd, len);
- memcpy(WFIFOP(tsd->fd,0), buf, len);
- WFIFOSET(tsd->fd,len);
- }
- }
- mapit_free(iter);
- }
- break;
-
- case BG_AREA:
- case BG_AREA_WOS:
- x0 = bl->x - AREA_SIZE;
- y0 = bl->y - AREA_SIZE;
- x1 = bl->x + AREA_SIZE;
- y1 = bl->y + AREA_SIZE;
- case BG_SAMEMAP:
- case BG_SAMEMAP_WOS:
- case BG:
- case BG_WOS:
- if (sd && sd->bg_id && (bg = bg_team_search(sd->bg_id)) != NULL) {
- for (i = 0; i < MAX_BG_MEMBERS; i++) {
- if ((sd = bg->members[i].sd) == NULL || !(fd = sd->fd))
- continue;
- if (sd->bl.id == bl->id && (type == BG_WOS || type == BG_SAMEMAP_WOS || type == BG_AREA_WOS))
- continue;
- if (type != BG && type != BG_WOS && sd->bl.m != bl->m)
- continue;
- if ((type == BG_AREA || type == BG_AREA_WOS) && (sd->bl.x < x0 || sd->bl.y < y0 || sd->bl.x > x1 || sd->bl.y > y1))
- continue;
- if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) {
- // packet must exist for the client version
- WFIFOHEAD(fd,len);
- memcpy(WFIFOP(fd,0), buf, len);
- WFIFOSET(fd,len);
- }
- }
- }
- break;
-
- default:
- ShowError("clif_send: Unrecognized type %d\n",type);
- return -1;
- }
-
- return 0;
+int clif_send(const uint8* buf, int len, struct block_list* bl, enum send_target type)
+{
+ int i;
+ struct map_session_data *sd, *tsd;
+ struct party_data *p = NULL;
+ struct guild *g = NULL;
+ struct battleground_data *bg = NULL;
+ int x0 = 0, x1 = 0, y0 = 0, y1 = 0, fd;
+ struct s_mapiterator* iter;
+
+ if( type != ALL_CLIENT && type != CHAT_MAINCHAT )
+ nullpo_ret(bl);
+
+ sd = BL_CAST(BL_PC, bl);
+
+ switch(type) {
+
+ case ALL_CLIENT: //All player clients.
+ iter = mapit_getallusers();
+ while( (tsd = (TBL_PC*)mapit_next(iter)) != NULL )
+ {
+ if( packet_db[tsd->packet_ver][RBUFW(buf,0)].len )
+ { // packet must exist for the client version
+ WFIFOHEAD(tsd->fd, len);
+ memcpy(WFIFOP(tsd->fd,0), buf, len);
+ WFIFOSET(tsd->fd,len);
+ }
+ }
+ mapit_free(iter);
+ break;
+
+ case ALL_SAMEMAP: //All players on the same map
+ iter = mapit_getallusers();
+ while( (tsd = (TBL_PC*)mapit_next(iter)) != NULL )
+ {
+ if( bl->m == tsd->bl.m && packet_db[tsd->packet_ver][RBUFW(buf,0)].len )
+ { // packet must exist for the client version
+ WFIFOHEAD(tsd->fd, len);
+ memcpy(WFIFOP(tsd->fd,0), buf, len);
+ WFIFOSET(tsd->fd,len);
+ }
+ }
+ mapit_free(iter);
+ break;
+
+ case AREA:
+ case AREA_WOSC:
+ if (sd && bl->prev == NULL) //Otherwise source misses the packet.[Skotlex]
+ clif_send (buf, len, bl, SELF);
+ case AREA_WOC:
+ case AREA_WOS:
+ map_foreachinarea(clif_send_sub, bl->m, bl->x-AREA_SIZE, bl->y-AREA_SIZE, bl->x+AREA_SIZE, bl->y+AREA_SIZE,
+ BL_PC, buf, len, bl, type);
+ break;
+ case AREA_CHAT_WOC:
+ map_foreachinarea(clif_send_sub, bl->m, bl->x-(AREA_SIZE-5), bl->y-(AREA_SIZE-5),
+ bl->x+(AREA_SIZE-5), bl->y+(AREA_SIZE-5), BL_PC, buf, len, bl, AREA_WOC);
+ break;
+
+ case CHAT:
+ case CHAT_WOS:
+ {
+ 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 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 ((fd=cd->usersd[i]->fd) >0 && session[fd]) // Added check to see if session exists [PoW]
+ {
+ WFIFOHEAD(fd,len);
+ memcpy(WFIFOP(fd,0), buf, len);
+ WFIFOSET(fd,len);
+ }
+ }
+ }
+ }
+ break;
+
+ case CHAT_MAINCHAT: //[LuzZza]
+ iter = mapit_getallusers();
+ while( (tsd = (TBL_PC*)mapit_next(iter)) != NULL )
+ {
+ if( tsd->state.mainchat && tsd->chatID == 0 && packet_db[tsd->packet_ver][RBUFW(buf,0)].len )
+ { // packet must exist for the client version
+ WFIFOHEAD(tsd->fd, len);
+ memcpy(WFIFOP(tsd->fd,0), buf, len);
+ WFIFOSET(tsd->fd,len);
+ }
+ }
+ mapit_free(iter);
+ break;
+
+ case PARTY_AREA:
+ case PARTY_AREA_WOS:
+ x0 = bl->x - AREA_SIZE;
+ y0 = bl->y - AREA_SIZE;
+ x1 = bl->x + AREA_SIZE;
+ y1 = bl->y + AREA_SIZE;
+ case PARTY:
+ case PARTY_WOS:
+ case PARTY_SAMEMAP:
+ case PARTY_SAMEMAP_WOS:
+ if (sd && sd->status.party_id)
+ p = party_search(sd->status.party_id);
+
+ if (p) {
+ for(i=0;i<MAX_PARTY;i++){
+ if( (sd = p->data[i].sd) == NULL )
+ continue;
+
+ if( !(fd=sd->fd) )
+ continue;
+
+ if( sd->bl.id == bl->id && (type == PARTY_WOS || type == PARTY_SAMEMAP_WOS || type == PARTY_AREA_WOS) )
+ continue;
+
+ if( type != PARTY && type != PARTY_WOS && bl->m != sd->bl.m )
+ continue;
+
+ if( (type == PARTY_AREA || type == PARTY_AREA_WOS) && (sd->bl.x < x0 || sd->bl.y < y0 || sd->bl.x > x1 || sd->bl.y > y1) )
+ continue;
+
+ if( packet_db[sd->packet_ver][RBUFW(buf,0)].len )
+ { // packet must exist for the client version
+ WFIFOHEAD(fd,len);
+ memcpy(WFIFOP(fd,0), buf, len);
+ WFIFOSET(fd,len);
+ }
+ }
+ if (!enable_spy) //Skip unnecessary parsing. [Skotlex]
+ break;
+
+ iter = mapit_getallusers();
+ while( (tsd = (TBL_PC*)mapit_next(iter)) != NULL )
+ {
+ if( tsd->partyspy == p->party.party_id && packet_db[tsd->packet_ver][RBUFW(buf,0)].len )
+ { // packet must exist for the client version
+ WFIFOHEAD(tsd->fd, len);
+ memcpy(WFIFOP(tsd->fd,0), buf, len);
+ WFIFOSET(tsd->fd,len);
+ }
+ }
+ mapit_free(iter);
+ }
+ break;
+
+ case DUEL:
+ case DUEL_WOS:
+ if (!sd || !sd->duel_group) break; //Invalid usage.
+
+ iter = mapit_getallusers();
+ while( (tsd = (TBL_PC*)mapit_next(iter)) != NULL )
+ {
+ if( type == DUEL_WOS && bl->id == tsd->bl.id )
+ continue;
+ if( sd->duel_group == tsd->duel_group && packet_db[tsd->packet_ver][RBUFW(buf,0)].len )
+ { // packet must exist for the client version
+ WFIFOHEAD(tsd->fd, len);
+ memcpy(WFIFOP(tsd->fd,0), buf, len);
+ WFIFOSET(tsd->fd,len);
+ }
+ }
+ mapit_free(iter);
+ break;
+
+ case SELF:
+ if (sd && (fd=sd->fd) && packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
+ WFIFOHEAD(fd,len);
+ memcpy(WFIFOP(fd,0), buf, len);
+ WFIFOSET(fd,len);
+ }
+ break;
+
+ // New definitions for guilds [Valaris] - Cleaned up and reorganized by [Skotlex]
+ case GUILD_AREA:
+ case GUILD_AREA_WOS:
+ x0 = bl->x - AREA_SIZE;
+ y0 = bl->y - AREA_SIZE;
+ x1 = bl->x + AREA_SIZE;
+ y1 = bl->y + AREA_SIZE;
+ case GUILD_SAMEMAP:
+ case GUILD_SAMEMAP_WOS:
+ case GUILD:
+ case GUILD_WOS:
+ case GUILD_NOBG:
+ if (sd && sd->status.guild_id)
+ g = guild_search(sd->status.guild_id);
+
+ if (g) {
+ for(i = 0; i < g->max_member; i++) {
+ if( (sd = g->member[i].sd) != NULL )
+ {
+ if( !(fd=sd->fd) )
+ continue;
+
+ if( type == GUILD_NOBG && sd->bg_id )
+ continue;
+
+ if( sd->bl.id == bl->id && (type == GUILD_WOS || type == GUILD_SAMEMAP_WOS || type == GUILD_AREA_WOS) )
+ continue;
+
+ if( type != GUILD && type != GUILD_NOBG && type != GUILD_WOS && sd->bl.m != bl->m )
+ continue;
+
+ if( (type == GUILD_AREA || type == GUILD_AREA_WOS) && (sd->bl.x < x0 || sd->bl.y < y0 || sd->bl.x > x1 || sd->bl.y > y1) )
+ continue;
+
+ if( packet_db[sd->packet_ver][RBUFW(buf,0)].len )
+ { // packet must exist for the client version
+ WFIFOHEAD(fd,len);
+ memcpy(WFIFOP(fd,0), buf, len);
+ WFIFOSET(fd,len);
+ }
+ }
+ }
+ if (!enable_spy) //Skip unnecessary parsing. [Skotlex]
+ break;
+
+ iter = mapit_getallusers();
+ while( (tsd = (TBL_PC*)mapit_next(iter)) != NULL )
+ {
+ if( tsd->guildspy == g->guild_id && packet_db[tsd->packet_ver][RBUFW(buf,0)].len )
+ { // packet must exist for the client version
+ WFIFOHEAD(tsd->fd, len);
+ memcpy(WFIFOP(tsd->fd,0), buf, len);
+ WFIFOSET(tsd->fd,len);
+ }
+ }
+ mapit_free(iter);
+ }
+ break;
+
+ case BG_AREA:
+ case BG_AREA_WOS:
+ x0 = bl->x - AREA_SIZE;
+ y0 = bl->y - AREA_SIZE;
+ x1 = bl->x + AREA_SIZE;
+ y1 = bl->y + AREA_SIZE;
+ case BG_SAMEMAP:
+ case BG_SAMEMAP_WOS:
+ case BG:
+ case BG_WOS:
+ if( sd && sd->bg_id && (bg = bg_team_search(sd->bg_id)) != NULL )
+ {
+ for( i = 0; i < MAX_BG_MEMBERS; i++ )
+ {
+ if( (sd = bg->members[i].sd) == NULL || !(fd = sd->fd) )
+ continue;
+ if( sd->bl.id == bl->id && (type == BG_WOS || type == BG_SAMEMAP_WOS || type == BG_AREA_WOS) )
+ continue;
+ if( type != BG && type != BG_WOS && sd->bl.m != bl->m )
+ continue;
+ if( (type == BG_AREA || type == BG_AREA_WOS) && (sd->bl.x < x0 || sd->bl.y < y0 || sd->bl.x > x1 || sd->bl.y > y1) )
+ continue;
+ if( packet_db[sd->packet_ver][RBUFW(buf,0)].len )
+ { // packet must exist for the client version
+ WFIFOHEAD(fd,len);
+ memcpy(WFIFOP(fd,0), buf, len);
+ WFIFOSET(fd,len);
+ }
+ }
+ }
+ break;
+
+ default:
+ ShowError("clif_send: Unrecognized type %d\n",type);
+ return -1;
+ }
+
+ return 0;
}
@@ -640,22 +642,22 @@ int clif_send(const uint8 *buf, int len, struct block_list *bl, enum send_target
void clif_authok(struct map_session_data *sd)
{
#if PACKETVER < 20080102
- const int cmd = 0x73;
+ const int cmd = 0x73;
#else
- const int cmd = 0x2eb;
+ const int cmd = 0x2eb;
#endif
- int fd = sd->fd;
-
- WFIFOHEAD(fd,packet_len(cmd));
- WFIFOW(fd, 0) = cmd;
- WFIFOL(fd, 2) = gettick();
- WFIFOPOS(fd, 6, sd->bl.x, sd->bl.y, sd->ud.dir);
- WFIFOB(fd, 9) = 5; // ignored
- WFIFOB(fd,10) = 5; // ignored
+ int fd = sd->fd;
+
+ WFIFOHEAD(fd,packet_len(cmd));
+ WFIFOW(fd, 0) = cmd;
+ WFIFOL(fd, 2) = gettick();
+ WFIFOPOS(fd, 6, sd->bl.x, sd->bl.y, sd->ud.dir);
+ WFIFOB(fd, 9) = 5; // ignored
+ WFIFOB(fd,10) = 5; // ignored
#if PACKETVER >= 20080102
- WFIFOW(fd,11) = sd->user_font; // FIXME: Font is currently not saved.
+ WFIFOW(fd,11) = sd->user_font; // FIXME: Font is currently not saved.
#endif
- WFIFOSET(fd,packet_len(cmd));
+ WFIFOSET(fd,packet_len(cmd));
}
@@ -669,10 +671,10 @@ void clif_authok(struct map_session_data *sd)
/// 4 = mobile - waiting state
void clif_authrefuse(int fd, uint8 error_code)
{
- WFIFOHEAD(fd,packet_len(0x74));
- WFIFOW(fd,0) = 0x74;
- WFIFOB(fd,2) = error_code;
- WFIFOSET(fd,packet_len(0x74));
+ WFIFOHEAD(fd,packet_len(0x74));
+ WFIFOW(fd,0) = 0x74;
+ WFIFOB(fd,2) = error_code;
+ WFIFOSET(fd,packet_len(0x74));
}
@@ -710,14 +712,14 @@ void clif_authrefuse(int fd, uint8 error_code)
/// ? = disconnected -> MsgStringTable[3]
void clif_authfail_fd(int fd, int type)
{
- if (!fd || !session[fd] || session[fd]->func_parse != clif_parse) //clif_authfail should only be invoked on players!
- return;
+ if (!fd || !session[fd] || session[fd]->func_parse != clif_parse) //clif_authfail should only be invoked on players!
+ return;
- WFIFOHEAD(fd, packet_len(0x81));
- WFIFOW(fd,0) = 0x81;
- WFIFOB(fd,2) = type;
- WFIFOSET(fd,packet_len(0x81));
- set_eof(fd);
+ WFIFOHEAD(fd, packet_len(0x81));
+ WFIFOW(fd,0) = 0x81;
+ WFIFOB(fd,2) = type;
+ WFIFOSET(fd,packet_len(0x81));
+ set_eof(fd);
}
@@ -728,43 +730,43 @@ void clif_authfail_fd(int fd, int type)
/// ? = nothing
void clif_charselectok(int id, uint8 ok)
{
- struct map_session_data *sd;
- int fd;
+ struct map_session_data* sd;
+ int fd;
- if ((sd = map_id2sd(id)) == NULL || !sd->fd)
- return;
+ if ((sd = map_id2sd(id)) == NULL || !sd->fd)
+ return;
- fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0xb3));
- WFIFOW(fd,0) = 0xb3;
- WFIFOB(fd,2) = ok;
- WFIFOSET(fd,packet_len(0xb3));
+ fd = sd->fd;
+ WFIFOHEAD(fd,packet_len(0xb3));
+ WFIFOW(fd,0) = 0xb3;
+ WFIFOB(fd,2) = ok;
+ WFIFOSET(fd,packet_len(0xb3));
}
/// Makes an item appear on the ground.
/// 009e <id>.L <name id>.W <identified>.B <x>.W <y>.W <subX>.B <subY>.B <amount>.W (ZC_ITEM_FALL_ENTRY)
/// 084b (ZC_ITEM_FALL_ENTRY4)
-void clif_dropflooritem(struct flooritem_data *fitem)
+void clif_dropflooritem(struct flooritem_data* fitem)
{
- uint8 buf[17];
- int view;
+ uint8 buf[17];
+ int view;
- nullpo_retv(fitem);
+ nullpo_retv(fitem);
- if (fitem->item_data.nameid <= 0)
- return;
+ if (fitem->item_data.nameid <= 0)
+ return;
- WBUFW(buf, 0) = 0x9e;
- WBUFL(buf, 2) = fitem->bl.id;
- WBUFW(buf, 6) = ((view = itemdb_viewid(fitem->item_data.nameid)) > 0) ? view : fitem->item_data.nameid;
- WBUFB(buf, 8) = fitem->item_data.identify;
- WBUFW(buf, 9) = fitem->bl.x;
- WBUFW(buf,11) = fitem->bl.y;
- WBUFB(buf,13) = fitem->subx;
- WBUFB(buf,14) = fitem->suby;
- WBUFW(buf,15) = fitem->item_data.amount;
+ WBUFW(buf, 0) = 0x9e;
+ WBUFL(buf, 2) = fitem->bl.id;
+ WBUFW(buf, 6) = ((view = itemdb_viewid(fitem->item_data.nameid)) > 0) ? view : fitem->item_data.nameid;
+ WBUFB(buf, 8) = fitem->item_data.identify;
+ WBUFW(buf, 9) = fitem->bl.x;
+ WBUFW(buf,11) = fitem->bl.y;
+ WBUFB(buf,13) = fitem->subx;
+ WBUFB(buf,14) = fitem->suby;
+ WBUFW(buf,15) = fitem->item_data.amount;
- clif_send(buf, packet_len(0x9e), &fitem->bl, AREA);
+ clif_send(buf, packet_len(0x9e), &fitem->bl, AREA);
}
@@ -773,20 +775,20 @@ void clif_dropflooritem(struct flooritem_data *fitem)
/// 00a1 <id>.L (ZC_ITEM_DISAPPEAR)
void clif_clearflooritem(struct flooritem_data *fitem, int fd)
{
- unsigned char buf[16];
+ unsigned char buf[16];
- nullpo_retv(fitem);
+ nullpo_retv(fitem);
- WBUFW(buf,0) = 0xa1;
- WBUFL(buf,2) = fitem->bl.id;
+ WBUFW(buf,0) = 0xa1;
+ WBUFL(buf,2) = fitem->bl.id;
- if (fd == 0) {
- clif_send(buf, packet_len(0xa1), &fitem->bl, AREA);
- } else {
- WFIFOHEAD(fd,packet_len(0xa1));
- memcpy(WFIFOP(fd,0), buf, packet_len(0xa1));
- WFIFOSET(fd,packet_len(0xa1));
- }
+ if (fd == 0) {
+ clif_send(buf, packet_len(0xa1), &fitem->bl, AREA);
+ } else {
+ WFIFOHEAD(fd,packet_len(0xa1));
+ memcpy(WFIFOP(fd,0), buf, packet_len(0xa1));
+ WFIFOSET(fd,packet_len(0xa1));
+ }
}
@@ -800,11 +802,11 @@ void clif_clearflooritem(struct flooritem_data *fitem, int fd)
/// 4 = trickdead
void clif_clearunit_single(int id, clr_type type, int fd)
{
- WFIFOHEAD(fd, packet_len(0x80));
- WFIFOW(fd,0) = 0x80;
- WFIFOL(fd,2) = id;
- WFIFOB(fd,6) = type;
- WFIFOSET(fd, packet_len(0x80));
+ WFIFOHEAD(fd, packet_len(0x80));
+ WFIFOW(fd,0) = 0x80;
+ WFIFOL(fd,2) = id;
+ WFIFOB(fd,6) = type;
+ WFIFOSET(fd, packet_len(0x80));
}
/// Makes a unit (char, npc, mob, homun) disappear to all clients in area (ZC_NOTIFY_VANISH).
@@ -815,22 +817,22 @@ void clif_clearunit_single(int id, clr_type type, int fd)
/// 2 = logged out
/// 3 = teleport
/// 4 = trickdead
-void clif_clearunit_area(struct block_list *bl, clr_type type)
+void clif_clearunit_area(struct block_list* bl, clr_type type)
{
- unsigned char buf[8];
+ unsigned char buf[8];
- nullpo_retv(bl);
+ nullpo_retv(bl);
- WBUFW(buf,0) = 0x80;
- WBUFL(buf,2) = bl->id;
- WBUFB(buf,6) = type;
+ WBUFW(buf,0) = 0x80;
+ WBUFL(buf,2) = bl->id;
+ WBUFB(buf,6) = type;
- clif_send(buf, packet_len(0x80), bl, type == CLR_DEAD ? AREA : AREA_WOS);
+ clif_send(buf, packet_len(0x80), bl, type == CLR_DEAD ? AREA : AREA_WOS);
- if (disguised(bl)) {
- WBUFL(buf,2) = -bl->id;
- clif_send(buf, packet_len(0x80), bl, SELF);
- }
+ if(disguised(bl)) {
+ WBUFL(buf,2) = -bl->id;
+ clif_send(buf, packet_len(0x80), bl, SELF);
+ }
}
@@ -839,352 +841,361 @@ void clif_clearunit_area(struct block_list *bl, clr_type type)
/// automatically.
static int clif_clearunit_delayed_sub(int tid, unsigned int tick, int id, intptr_t data)
{
- struct block_list *bl = (struct block_list *)data;
- clif_clearunit_area(bl, (clr_type) id);
- ers_free(delay_clearunit_ers,bl);
- return 0;
+ struct block_list *bl = (struct block_list *)data;
+ clif_clearunit_area(bl, (clr_type) id);
+ ers_free(delay_clearunit_ers,bl);
+ return 0;
}
-void clif_clearunit_delayed(struct block_list *bl, clr_type type, unsigned int tick)
+void clif_clearunit_delayed(struct block_list* bl, clr_type type, unsigned int tick)
{
- struct block_list *tbl = ers_alloc(delay_clearunit_ers, struct block_list);
- memcpy(tbl, bl, sizeof(struct block_list));
- add_timer(tick, clif_clearunit_delayed_sub, (int)type, (intptr_t)tbl);
+ struct block_list *tbl = ers_alloc(delay_clearunit_ers, struct block_list);
+ memcpy (tbl, bl, sizeof (struct block_list));
+ add_timer(tick, clif_clearunit_delayed_sub, (int)type, (intptr_t)tbl);
}
-void clif_get_weapon_view(struct map_session_data *sd, unsigned short *rhand, unsigned short *lhand)
+void clif_get_weapon_view(struct map_session_data* sd, unsigned short *rhand, unsigned short *lhand)
{
- if (sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER)) {
- *rhand = *lhand = 0;
- return;
- }
+ if(sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER))
+ {
+ *rhand = *lhand = 0;
+ return;
+ }
#if PACKETVER < 4
- *rhand = sd->status.weapon;
- *lhand = sd->status.shield;
+ *rhand = sd->status.weapon;
+ *lhand = sd->status.shield;
#else
- if (sd->equip_index[EQI_HAND_R] >= 0 &&
- sd->inventory_data[sd->equip_index[EQI_HAND_R]]) {
- struct item_data *id = sd->inventory_data[sd->equip_index[EQI_HAND_R]];
- if (id->view_id > 0)
- *rhand = id->view_id;
- else
- *rhand = id->nameid;
- } else
- *rhand = 0;
-
- if (sd->equip_index[EQI_HAND_L] >= 0 &&
- sd->equip_index[EQI_HAND_L] != sd->equip_index[EQI_HAND_R] &&
- sd->inventory_data[sd->equip_index[EQI_HAND_L]]) {
- struct item_data *id = sd->inventory_data[sd->equip_index[EQI_HAND_L]];
- if (id->view_id > 0)
- *lhand = id->view_id;
- else
- *lhand = id->nameid;
- } else
- *lhand = 0;
+ if (sd->equip_index[EQI_HAND_R] >= 0 &&
+ sd->inventory_data[sd->equip_index[EQI_HAND_R]])
+ {
+ struct item_data* id = sd->inventory_data[sd->equip_index[EQI_HAND_R]];
+ if (id->view_id > 0)
+ *rhand = id->view_id;
+ else
+ *rhand = id->nameid;
+ } else
+ *rhand = 0;
+
+ if (sd->equip_index[EQI_HAND_L] >= 0 &&
+ sd->equip_index[EQI_HAND_L] != sd->equip_index[EQI_HAND_R] &&
+ sd->inventory_data[sd->equip_index[EQI_HAND_L]])
+ {
+ struct item_data* id = sd->inventory_data[sd->equip_index[EQI_HAND_L]];
+ if (id->view_id > 0)
+ *lhand = id->view_id;
+ else
+ *lhand = id->nameid;
+ } else
+ *lhand = 0;
#endif
}
//To make the assignation of the level based on limits clearer/easier. [Skotlex]
static int clif_setlevel_sub(int lv)
{
- if (lv < battle_config.max_lv) {
- ;
- } else if (lv < battle_config.aura_lv) {
- lv = battle_config.max_lv - 1;
- } else {
- lv = battle_config.max_lv;
- }
-
- return lv;
-}
-
-static int clif_setlevel(struct block_list *bl)
-{
- int lv = status_get_lv(bl);
- if (battle_config.client_limit_unit_lv&bl->type)
- return clif_setlevel_sub(lv);
- switch (bl->type) {
- case BL_NPC:
- case BL_PET:
- // npcs and pets do not have level
- return 0;
- }
- return lv;
+ if( lv < battle_config.max_lv )
+ {
+ ;
+ }
+ else if( lv < battle_config.aura_lv )
+ {
+ lv = battle_config.max_lv - 1;
+ }
+ else
+ {
+ lv = battle_config.max_lv;
+ }
+
+ return lv;
+}
+
+static int clif_setlevel(struct block_list* bl)
+{
+ int lv = status_get_lv(bl);
+ if( battle_config.client_limit_unit_lv&bl->type )
+ return clif_setlevel_sub(lv);
+ switch( bl->type )
+ {
+ case BL_NPC:
+ case BL_PET:
+ // npcs and pets do not have level
+ return 0;
+ }
+ return lv;
}
/*==========================================
* Prepares 'unit standing/spawning' packet
*------------------------------------------*/
-static int clif_set_unit_idle(struct block_list *bl, unsigned char *buffer, bool spawn)
+static int clif_set_unit_idle(struct block_list* bl, unsigned char* buffer, bool spawn)
{
- struct map_session_data *sd;
- struct status_change *sc = status_get_sc(bl);
- struct view_data *vd = status_get_viewdata(bl);
- unsigned char *buf = WBUFP(buffer,0);
+ struct map_session_data* sd;
+ struct status_change* sc = status_get_sc(bl);
+ struct view_data* vd = status_get_viewdata(bl);
+ unsigned char *buf = WBUFP(buffer,0);
#if PACKETVER < 20091103
- bool type = !pcdb_checkid(vd->class_);
+ bool type = !pcdb_checkid(vd->class_);
#endif
#if PACKETVER >= 7
- unsigned short offset = 0;
+ unsigned short offset = 0;
#endif
#if PACKETVER >= 20091103
- const char *name;
+ const char *name;
#endif
- sd = BL_CAST(BL_PC, bl);
+ sd = BL_CAST(BL_PC, bl);
#if PACKETVER < 20091103
- if (type)
- WBUFW(buf,0) = spawn?0x7c:0x78;
- else
+ if(type)
+ WBUFW(buf,0) = spawn?0x7c:0x78;
+ else
#endif
#if PACKETVER < 4
- WBUFW(buf,0) = spawn?0x79:0x78;
+ WBUFW(buf,0) = spawn?0x79:0x78;
#elif PACKETVER < 7
- WBUFW(buf,0) = spawn?0x1d9:0x1d8;
+ WBUFW(buf,0) = spawn?0x1d9:0x1d8;
#elif PACKETVER < 20080102
- WBUFW(buf,0) = spawn?0x22b:0x22a;
+ WBUFW(buf,0) = spawn?0x22b:0x22a;
#elif PACKETVER < 20091103
- WBUFW(buf,0) = spawn?0x2ed:0x2ee;
+ WBUFW(buf,0) = spawn?0x2ed:0x2ee;
#elif PACKETVER < 20101124
- WBUFW(buf,0) = spawn?0x7f8:0x7f9;
+ WBUFW(buf,0) = spawn?0x7f8:0x7f9;
#else
- WBUFW(buf,0) = spawn?0x858:0x857;
+ WBUFW(buf,0) = spawn?0x858:0x857;
#endif
#if PACKETVER >= 20091103
- name = status_get_name(bl);
+ name = status_get_name(bl);
#if PACKETVER < 20110111
- WBUFW(buf,2) = (spawn?62:63)+strlen(name);
+ WBUFW(buf,2) = (spawn?62:63)+strlen(name);
#else
- WBUFW(buf,2) = (spawn?64:65)+strlen(name);
+ WBUFW(buf,2) = (spawn?64:65)+strlen(name);
#endif
- WBUFB(buf,4) = clif_bl_type(bl);
- offset+=3;
- buf = WBUFP(buffer,offset);
+ WBUFB(buf,4) = clif_bl_type(bl);
+ offset+=3;
+ buf = WBUFP(buffer,offset);
#elif PACKETVER >= 20071106
- if (type) { //Non-player packets
- WBUFB(buf,2) = clif_bl_type(bl);
- offset++;
- buf = WBUFP(buffer,offset);
- }
+ if (type) { //Non-player packets
+ WBUFB(buf,2) = clif_bl_type(bl);
+ offset++;
+ buf = WBUFP(buffer,offset);
+ }
#endif
- WBUFL(buf, 2) = bl->id;
- WBUFW(buf, 6) = status_get_speed(bl);
- WBUFW(buf, 8) = (sc)? sc->opt1 : 0;
- WBUFW(buf,10) = (sc)? sc->opt2 : 0;
+ WBUFL(buf, 2) = bl->id;
+ WBUFW(buf, 6) = status_get_speed(bl);
+ WBUFW(buf, 8) = (sc)? sc->opt1 : 0;
+ WBUFW(buf,10) = (sc)? sc->opt2 : 0;
#if PACKETVER < 20091103
- if (type&&spawn) { //uses an older and different packet structure
- WBUFW(buf,12) = (sc)? sc->option : 0;
- WBUFW(buf,14) = vd->hair_style;
- WBUFW(buf,16) = vd->weapon;
- WBUFW(buf,18) = vd->head_bottom;
- WBUFW(buf,20) = vd->class_; //Pet armor (ignored by client)
- WBUFW(buf,22) = vd->shield;
- } else {
+ if (type&&spawn) { //uses an older and different packet structure
+ WBUFW(buf,12) = (sc)? sc->option : 0;
+ WBUFW(buf,14) = vd->hair_style;
+ WBUFW(buf,16) = vd->weapon;
+ WBUFW(buf,18) = vd->head_bottom;
+ WBUFW(buf,20) = vd->class_; //Pet armor (ignored by client)
+ WBUFW(buf,22) = vd->shield;
+ } else {
#endif
#if PACKETVER >= 20091103
- WBUFL(buf,12) = (sc)? sc->option : 0;
- offset+=2;
- buf = WBUFP(buffer,offset);
+ WBUFL(buf,12) = (sc)? sc->option : 0;
+ offset+=2;
+ buf = WBUFP(buffer,offset);
#elif PACKETVER >= 7
- if (!type) {
- WBUFL(buf,12) = (sc)? sc->option : 0;
- offset+=2;
- buf = WBUFP(buffer,offset);
- } else
- WBUFW(buf,12) = (sc)? sc->option : 0;
+ if (!type) {
+ WBUFL(buf,12) = (sc)? sc->option : 0;
+ offset+=2;
+ buf = WBUFP(buffer,offset);
+ } else
+ WBUFW(buf,12) = (sc)? sc->option : 0;
#else
- WBUFW(buf,12) = (sc)? sc->option : 0;
+ WBUFW(buf,12) = (sc)? sc->option : 0;
#endif
- WBUFW(buf,14) = vd->class_;
- WBUFW(buf,16) = vd->hair_style;
- WBUFW(buf,18) = vd->weapon;
+ WBUFW(buf,14) = vd->class_;
+ WBUFW(buf,16) = vd->hair_style;
+ WBUFW(buf,18) = vd->weapon;
#if PACKETVER < 4
- WBUFW(buf,20) = vd->head_bottom;
- WBUFW(buf,22) = vd->shield;
+ WBUFW(buf,20) = vd->head_bottom;
+ WBUFW(buf,22) = vd->shield;
#else
- WBUFW(buf,20) = vd->shield;
- WBUFW(buf,22) = vd->head_bottom;
+ WBUFW(buf,20) = vd->shield;
+ WBUFW(buf,22) = vd->head_bottom;
#endif
#if PACKETVER < 20091103
- }
+ }
#endif
- WBUFW(buf,24) = vd->head_top;
- WBUFW(buf,26) = vd->head_mid;
-
- if (bl->type == BL_NPC && vd->class_ == FLAG_CLASS) {
- //The hell, why flags work like this?
- WBUFW(buf,22) = status_get_emblem_id(bl);
- WBUFW(buf,24) = GetWord(status_get_guild_id(bl), 1);
- WBUFW(buf,26) = GetWord(status_get_guild_id(bl), 0);
- }
-
- WBUFW(buf,28) = vd->hair_color;
- WBUFW(buf,30) = vd->cloth_color;
- WBUFW(buf,32) = (sd)? sd->head_dir : 0;
+ WBUFW(buf,24) = vd->head_top;
+ WBUFW(buf,26) = vd->head_mid;
+
+ if( bl->type == BL_NPC && vd->class_ == FLAG_CLASS )
+ { //The hell, why flags work like this?
+ WBUFW(buf,22) = status_get_emblem_id(bl);
+ WBUFW(buf,24) = GetWord(status_get_guild_id(bl), 1);
+ WBUFW(buf,26) = GetWord(status_get_guild_id(bl), 0);
+ }
+
+ WBUFW(buf,28) = vd->hair_color;
+ WBUFW(buf,30) = vd->cloth_color;
+ WBUFW(buf,32) = (sd)? sd->head_dir : 0;
#if PACKETVER < 20091103
- if (type&&spawn) { //End of packet 0x7c
- WBUFB(buf,34) = (sd)?sd->status.karma:0; // karma
- WBUFB(buf,35) = vd->sex;
- WBUFPOS(buf,36,bl->x,bl->y,unit_getdir(bl));
- WBUFB(buf,39) = 0;
- WBUFB(buf,40) = 0;
- return packet_len(0x7c);
- }
+ if (type&&spawn) { //End of packet 0x7c
+ WBUFB(buf,34) = (sd)?sd->status.karma:0; // karma
+ WBUFB(buf,35) = vd->sex;
+ WBUFPOS(buf,36,bl->x,bl->y,unit_getdir(bl));
+ WBUFB(buf,39) = 0;
+ WBUFB(buf,40) = 0;
+ return packet_len(0x7c);
+ }
#endif
#if PACKETVER >= 20110111
- WBUFW(buf,34) = vd->robe;
- offset+= 2;
- buf = WBUFP(buffer,offset);
+ WBUFW(buf,34) = vd->robe;
+ offset+= 2;
+ buf = WBUFP(buffer,offset);
#endif
- WBUFL(buf,34) = status_get_guild_id(bl);
- WBUFW(buf,38) = status_get_emblem_id(bl);
- WBUFW(buf,40) = (sd)? sd->status.manner : 0;
+ WBUFL(buf,34) = status_get_guild_id(bl);
+ WBUFW(buf,38) = status_get_emblem_id(bl);
+ WBUFW(buf,40) = (sd)? sd->status.manner : 0;
#if PACKETVER >= 20091103
- WBUFL(buf,42) = (sc)? sc->opt3 : 0;
- offset+=2;
- buf = WBUFP(buffer,offset);
+ WBUFL(buf,42) = (sc)? sc->opt3 : 0;
+ offset+=2;
+ buf = WBUFP(buffer,offset);
#elif PACKETVER >= 7
- if (!type) {
- WBUFL(buf,42) = (sc)? sc->opt3 : 0;
- offset+=2;
- buf = WBUFP(buffer,offset);
- } else
- WBUFW(buf,42) = (sc)? sc->opt3 : 0;
+ if (!type) {
+ WBUFL(buf,42) = (sc)? sc->opt3 : 0;
+ offset+=2;
+ buf = WBUFP(buffer,offset);
+ } else
+ WBUFW(buf,42) = (sc)? sc->opt3 : 0;
#else
- WBUFW(buf,42) = (sc)? sc->opt3 : 0;
+ WBUFW(buf,42) = (sc)? sc->opt3 : 0;
#endif
- WBUFB(buf,44) = (sd)? sd->status.karma : 0;
- WBUFB(buf,45) = vd->sex;
- WBUFPOS(buf,46,bl->x,bl->y,unit_getdir(bl));
- WBUFB(buf,49) = (sd)? 5 : 0;
- WBUFB(buf,50) = (sd)? 5 : 0;
- if (!spawn) {
- WBUFB(buf,51) = vd->dead_sit;
- offset++;
- buf = WBUFP(buffer,offset);
- }
- WBUFW(buf,51) = clif_setlevel(bl);
+ WBUFB(buf,44) = (sd)? sd->status.karma : 0;
+ WBUFB(buf,45) = vd->sex;
+ WBUFPOS(buf,46,bl->x,bl->y,unit_getdir(bl));
+ WBUFB(buf,49) = (sd)? 5 : 0;
+ WBUFB(buf,50) = (sd)? 5 : 0;
+ if (!spawn) {
+ WBUFB(buf,51) = vd->dead_sit;
+ offset++;
+ buf = WBUFP(buffer,offset);
+ }
+ WBUFW(buf,51) = clif_setlevel(bl);
#if PACKETVER < 20091103
- if (type) //End for non-player packet
- return packet_len(WBUFW(buffer,0));
+ if (type) //End for non-player packet
+ return packet_len(WBUFW(buffer,0));
#endif
#if PACKETVER >= 20080102
- WBUFW(buf,53) = sd?sd->user_font:0;
+ WBUFW(buf,53) = sd?sd->user_font:0;
#endif
#if PACKETVER >= 20091103
- memcpy((char *)WBUFP(buf,55), name, NAME_LENGTH);
- return WBUFW(buffer,2);
+ memcpy((char*)WBUFP(buf,55), name, NAME_LENGTH);
+ return WBUFW(buffer,2);
#else
- return packet_len(WBUFW(buffer,0));
+ return packet_len(WBUFW(buffer,0));
#endif
}
/*==========================================
* Prepares 'unit walking' packet
*------------------------------------------*/
-static int clif_set_unit_walking(struct block_list *bl, struct unit_data *ud, unsigned char *buffer)
+static int clif_set_unit_walking(struct block_list* bl, struct unit_data* ud, unsigned char* buffer)
{
- struct map_session_data *sd;
- struct status_change *sc = status_get_sc(bl);
- struct view_data *vd = status_get_viewdata(bl);
- unsigned char *buf = WBUFP(buffer,0);
+ struct map_session_data* sd;
+ struct status_change* sc = status_get_sc(bl);
+ struct view_data* vd = status_get_viewdata(bl);
+ unsigned char* buf = WBUFP(buffer,0);
#if PACKETVER >= 7
- unsigned short offset = 0;
+ unsigned short offset = 0;
#endif
#if PACKETVER >= 20091103
- const char *name;
+ const char *name;
#endif
- sd = BL_CAST(BL_PC, bl);
+ sd = BL_CAST(BL_PC, bl);
#if PACKETVER < 4
- WBUFW(buf, 0) = 0x7b;
+ WBUFW(buf, 0) = 0x7b;
#elif PACKETVER < 7
- WBUFW(buf, 0) = 0x1da;
+ WBUFW(buf, 0) = 0x1da;
#elif PACKETVER < 20080102
- WBUFW(buf, 0) = 0x22c;
+ WBUFW(buf, 0) = 0x22c;
#elif PACKETVER < 20091103
- WBUFW(buf, 0) = 0x2ec;
+ WBUFW(buf, 0) = 0x2ec;
#elif PACKETVER < 20101124
- WBUFW(buf, 0) = 0x7f7;
+ WBUFW(buf, 0) = 0x7f7;
#else
- WBUFW(buf, 0) = 0x856;
+ WBUFW(buf, 0) = 0x856;
#endif
#if PACKETVER >= 20091103
- name = status_get_name(bl);
+ name = status_get_name(bl);
#if PACKETVER < 20110111
- WBUFW(buf, 2) = 69+strlen(name);
+ WBUFW(buf, 2) = 69+strlen(name);
#else
- WBUFW(buf, 2) = 71+strlen(name);
+ WBUFW(buf, 2) = 71+strlen(name);
#endif
- offset+=2;
- buf = WBUFP(buffer,offset);
+ offset+=2;
+ buf = WBUFP(buffer,offset);
#endif
#if PACKETVER >= 20071106
- WBUFB(buf, 2) = clif_bl_type(bl);
- offset++;
- buf = WBUFP(buffer,offset);
+ WBUFB(buf, 2) = clif_bl_type(bl);
+ offset++;
+ buf = WBUFP(buffer,offset);
#endif
- WBUFL(buf, 2) = bl->id;
- WBUFW(buf, 6) = status_get_speed(bl);
- WBUFW(buf, 8) = (sc)? sc->opt1 : 0;
- WBUFW(buf,10) = (sc)? sc->opt2 : 0;
+ WBUFL(buf, 2) = bl->id;
+ WBUFW(buf, 6) = status_get_speed(bl);
+ WBUFW(buf, 8) = (sc)? sc->opt1 : 0;
+ WBUFW(buf,10) = (sc)? sc->opt2 : 0;
#if PACKETVER < 7
- WBUFW(buf,12) = (sc)? sc->option : 0;
+ WBUFW(buf,12) = (sc)? sc->option : 0;
#else
- WBUFL(buf,12) = (sc)? sc->option : 0;
- offset+=2; //Shift the rest of elements by 2 bytes.
- buf = WBUFP(buffer,offset);
+ WBUFL(buf,12) = (sc)? sc->option : 0;
+ offset+=2; //Shift the rest of elements by 2 bytes.
+ buf = WBUFP(buffer,offset);
#endif
- WBUFW(buf,14) = vd->class_;
- WBUFW(buf,16) = vd->hair_style;
- WBUFW(buf,18) = vd->weapon;
+ WBUFW(buf,14) = vd->class_;
+ WBUFW(buf,16) = vd->hair_style;
+ WBUFW(buf,18) = vd->weapon;
#if PACKETVER < 4
- WBUFW(buf,20) = vd->head_bottom;
- WBUFL(buf,22) = gettick();
- WBUFW(buf,26) = vd->shield;
+ WBUFW(buf,20) = vd->head_bottom;
+ WBUFL(buf,22) = gettick();
+ WBUFW(buf,26) = vd->shield;
#else
- WBUFW(buf,20) = vd->shield;
- WBUFW(buf,22) = vd->head_bottom;
- WBUFL(buf,24) = gettick();
+ WBUFW(buf,20) = vd->shield;
+ WBUFW(buf,22) = vd->head_bottom;
+ WBUFL(buf,24) = gettick();
#endif
- WBUFW(buf,28) = vd->head_top;
- WBUFW(buf,30) = vd->head_mid;
- WBUFW(buf,32) = vd->hair_color;
- WBUFW(buf,34) = vd->cloth_color;
- WBUFW(buf,36) = (sd)? sd->head_dir : 0;
+ WBUFW(buf,28) = vd->head_top;
+ WBUFW(buf,30) = vd->head_mid;
+ WBUFW(buf,32) = vd->hair_color;
+ WBUFW(buf,34) = vd->cloth_color;
+ WBUFW(buf,36) = (sd)? sd->head_dir : 0;
#if PACKETVER >= 20110111
- WBUFW(buf,38) = vd->robe;
- offset+= 2;
- buf = WBUFP(buffer,offset);
+ WBUFW(buf,38) = vd->robe;
+ offset+= 2;
+ buf = WBUFP(buffer,offset);
#endif
- WBUFL(buf,38) = status_get_guild_id(bl);
- WBUFW(buf,42) = status_get_emblem_id(bl);
- WBUFW(buf,44) = (sd)? sd->status.manner : 0;
+ WBUFL(buf,38) = status_get_guild_id(bl);
+ WBUFW(buf,42) = status_get_emblem_id(bl);
+ WBUFW(buf,44) = (sd)? sd->status.manner : 0;
#if PACKETVER < 7
- WBUFW(buf,46) = (sc)? sc->opt3 : 0;
+ WBUFW(buf,46) = (sc)? sc->opt3 : 0;
#else
- WBUFL(buf,46) = (sc)? sc->opt3 : 0;
- offset+=2; //Shift the rest of elements by 2 bytes.
- buf = WBUFP(buffer,offset);
+ WBUFL(buf,46) = (sc)? sc->opt3 : 0;
+ offset+=2; //Shift the rest of elements by 2 bytes.
+ buf = WBUFP(buffer,offset);
#endif
- WBUFB(buf,48) = (sd)? sd->status.karma : 0;
- WBUFB(buf,49) = vd->sex;
- WBUFPOS2(buf,50,bl->x,bl->y,ud->to_x,ud->to_y,8,8);
- WBUFB(buf,56) = (sd)? 5 : 0;
- WBUFB(buf,57) = (sd)? 5 : 0;
- WBUFW(buf,58) = clif_setlevel(bl);
+ WBUFB(buf,48) = (sd)? sd->status.karma : 0;
+ WBUFB(buf,49) = vd->sex;
+ WBUFPOS2(buf,50,bl->x,bl->y,ud->to_x,ud->to_y,8,8);
+ WBUFB(buf,56) = (sd)? 5 : 0;
+ WBUFB(buf,57) = (sd)? 5 : 0;
+ WBUFW(buf,58) = clif_setlevel(bl);
#if PACKETVER >= 20080102
- WBUFW(buf,60) = sd?sd->user_font:0;
+ WBUFW(buf,60) = sd?sd->user_font:0;
#endif
#if PACKETVER >= 20091103
- memcpy((char *)WBUFP(buf,62), name, NAME_LENGTH);
- return WBUFW(buffer,2);
+ memcpy((char*)WBUFP(buf,62), name, NAME_LENGTH);
+ return WBUFW(buffer,2);
#else
- return packet_len(WBUFW(buffer,0));
+ return packet_len(WBUFW(buffer,0));
#endif
}
@@ -1193,15 +1204,15 @@ static int clif_set_unit_walking(struct block_list *bl, struct unit_data *ud, un
static void clif_setdisguise(struct block_list *bl, unsigned char *buf,int len)
{
#if PACKETVER >= 20091103
- WBUFB(buf,4)= pcdb_checkid(status_get_viewdata(bl)->class_) ? 0x0 : 0x5; //PC_TYPE : NPC_MOB_TYPE
- WBUFL(buf,5)=-bl->id;
+ WBUFB(buf,4)= pcdb_checkid(status_get_viewdata(bl)->class_) ? 0x0 : 0x5; //PC_TYPE : NPC_MOB_TYPE
+ WBUFL(buf,5)=-bl->id;
#elif PACKETVER >= 20071106
- WBUFB(buf,2)= pcdb_checkid(status_get_viewdata(bl)->class_) ? 0x0 : 0x5; //PC_TYPE : NPC_MOB_TYPE
- WBUFL(buf,3)=-bl->id;
+ WBUFB(buf,2)= pcdb_checkid(status_get_viewdata(bl)->class_) ? 0x0 : 0x5; //PC_TYPE : NPC_MOB_TYPE
+ WBUFL(buf,3)=-bl->id;
#else
- WBUFL(buf,2)=-bl->id;
+ WBUFL(buf,2)=-bl->id;
#endif
- clif_send(buf, len, bl, SELF);
+ clif_send(buf, len, bl, SELF);
}
@@ -1211,18 +1222,18 @@ static void clif_setdisguise(struct block_list *bl, unsigned char *buf,int len)
/// unused
void clif_class_change(struct block_list *bl,int class_,int type)
{
- unsigned char buf[16];
+ unsigned char buf[16];
- nullpo_retv(bl);
+ nullpo_retv(bl);
- if (!pcdb_checkid(class_)) {
- // player classes yield missing sprites
- WBUFW(buf,0)=0x1b0;
- WBUFL(buf,2)=bl->id;
- WBUFB(buf,6)=type;
- WBUFL(buf,7)=class_;
- clif_send(buf,packet_len(0x1b0),bl,AREA);
- }
+ if(!pcdb_checkid(class_))
+ {// player classes yield missing sprites
+ WBUFW(buf,0)=0x1b0;
+ WBUFL(buf,2)=bl->id;
+ WBUFB(buf,6)=type;
+ WBUFL(buf,7)=class_;
+ clif_send(buf,packet_len(0x1b0),bl,AREA);
+ }
}
@@ -1231,11 +1242,11 @@ void clif_class_change(struct block_list *bl,int class_,int type)
/// 01e1 <id>.L <amount>.W (ZC_SPIRITS2)
static void clif_spiritball_single(int fd, struct map_session_data *sd)
{
- WFIFOHEAD(fd, packet_len(0x1e1));
- WFIFOW(fd,0)=0x1e1;
- WFIFOL(fd,2)=sd->bl.id;
- WFIFOW(fd,6)=sd->spiritball;
- WFIFOSET(fd, packet_len(0x1e1));
+ WFIFOHEAD(fd, packet_len(0x1e1));
+ WFIFOW(fd,0)=0x1e1;
+ WFIFOL(fd,2)=sd->bl.id;
+ WFIFOW(fd,6)=sd->spiritball;
+ WFIFOSET(fd, packet_len(0x1e1));
}
/*==========================================
@@ -1243,12 +1254,12 @@ static void clif_spiritball_single(int fd, struct map_session_data *sd)
*------------------------------------------*/
static void clif_talisman_single(int fd, struct map_session_data *sd, short type)
{
- WFIFOHEAD(fd, packet_len(0x08cf));
- WFIFOW(fd,0)=0x08cf;
- WFIFOL(fd,2)=sd->bl.id;
- WFIFOW(fd,6)=type;
- WFIFOW(fd,8)=sd->talisman[type];
- WFIFOSET(fd, packet_len(0x08cf));
+ WFIFOHEAD(fd, packet_len(0x08cf));
+ WFIFOW(fd,0)=0x08cf;
+ WFIFOL(fd,2)=sd->bl.id;
+ WFIFOW(fd,6)=type;
+ WFIFOW(fd,8)=sd->talisman[type];
+ WFIFOSET(fd, packet_len(0x08cf));
}
/*==========================================
@@ -1257,194 +1268,200 @@ static void clif_talisman_single(int fd, struct map_session_data *sd, short type
*------------------------------------------*/
static void clif_weather_check(struct map_session_data *sd)
{
- int m = sd->bl.m, fd = sd->fd;
-
- if (map[m].flag.snow
- || map[m].flag.clouds
- || map[m].flag.fog
- || map[m].flag.fireworks
- || map[m].flag.sakura
- || map[m].flag.leaves
- /**
- * No longer available, keeping here just in case it's back someday. [Ind]
- **/
- //|| map[m].flag.rain
- || map[m].flag.clouds2) {
- if (map[m].flag.snow)
- clif_specialeffect_single(&sd->bl, 162, fd);
- if (map[m].flag.clouds)
- clif_specialeffect_single(&sd->bl, 233, fd);
- if (map[m].flag.clouds2)
- clif_specialeffect_single(&sd->bl, 516, fd);
- if (map[m].flag.fog)
- clif_specialeffect_single(&sd->bl, 515, fd);
- if (map[m].flag.fireworks) {
- clif_specialeffect_single(&sd->bl, 297, fd);
- clif_specialeffect_single(&sd->bl, 299, fd);
- clif_specialeffect_single(&sd->bl, 301, fd);
- }
- if (map[m].flag.sakura)
- clif_specialeffect_single(&sd->bl, 163, fd);
- if (map[m].flag.leaves)
- clif_specialeffect_single(&sd->bl, 333, fd);
- /**
- * No longer available, keeping here just in case it's back someday. [Ind]
- **/
- //if (map[m].flag.rain)
- // clif_specialeffect_single(&sd->bl, 161, fd);
- }
+ int m = sd->bl.m, fd = sd->fd;
+
+ if (map[m].flag.snow
+ || map[m].flag.clouds
+ || map[m].flag.fog
+ || map[m].flag.fireworks
+ || map[m].flag.sakura
+ || map[m].flag.leaves
+ /**
+ * No longer available, keeping here just in case it's back someday. [Ind]
+ **/
+ //|| map[m].flag.rain
+ || map[m].flag.clouds2)
+ {
+ if (map[m].flag.snow)
+ clif_specialeffect_single(&sd->bl, 162, fd);
+ if (map[m].flag.clouds)
+ clif_specialeffect_single(&sd->bl, 233, fd);
+ if (map[m].flag.clouds2)
+ clif_specialeffect_single(&sd->bl, 516, fd);
+ if (map[m].flag.fog)
+ clif_specialeffect_single(&sd->bl, 515, fd);
+ if (map[m].flag.fireworks) {
+ clif_specialeffect_single(&sd->bl, 297, fd);
+ clif_specialeffect_single(&sd->bl, 299, fd);
+ clif_specialeffect_single(&sd->bl, 301, fd);
+ }
+ if (map[m].flag.sakura)
+ clif_specialeffect_single(&sd->bl, 163, fd);
+ if (map[m].flag.leaves)
+ clif_specialeffect_single(&sd->bl, 333, fd);
+ /**
+ * No longer available, keeping here just in case it's back someday. [Ind]
+ **/
+ //if (map[m].flag.rain)
+ // clif_specialeffect_single(&sd->bl, 161, fd);
+ }
}
/**
* Run when the weather on a map changes, throws all players in map id 'm' to clif_weather_check function
**/
void clif_weather(int m)
{
- struct s_mapiterator *iter;
- struct map_session_data *sd=NULL;
+ struct s_mapiterator* iter;
+ struct map_session_data *sd=NULL;
- iter = mapit_getallusers();
- for (sd = (struct map_session_data *)mapit_first(iter); mapit_exists(iter); sd = (struct map_session_data *)mapit_next(iter)) {
- if (sd->bl.m == m)
- clif_weather_check(sd);
- }
- mapit_free(iter);
+ iter = mapit_getallusers();
+ for( sd = (struct map_session_data*)mapit_first(iter); mapit_exists(iter); sd = (struct map_session_data*)mapit_next(iter) )
+ {
+ if( sd->bl.m == m )
+ clif_weather_check(sd);
+ }
+ mapit_free(iter);
}
/**
* Main function to spawn a unit on the client (player/mob/pet/etc)
**/
int clif_spawn(struct block_list *bl)
{
- unsigned char buf[128];
- struct view_data *vd;
- int len;
-
- vd = status_get_viewdata(bl);
- if (!vd || vd->class_ == INVISIBLE_CLASS)
- return 0;
-
- /**
- * Hide NPC from maya purple card.
- **/
- if (bl->type == BL_NPC && !((TBL_NPC *)bl)->chat_id && (((TBL_NPC *)bl)->sc.option&OPTION_INVISIBLE))
- return 0;
-
- len = clif_set_unit_idle(bl, buf,true);
- clif_send(buf, len, bl, AREA_WOS);
- if (disguised(bl))
- clif_setdisguise(bl, buf, len);
-
- if (vd->cloth_color)
- clif_refreshlook(bl,bl->id,LOOK_CLOTHES_COLOR,vd->cloth_color,AREA_WOS);
-
- switch (bl->type) {
- case BL_PC: {
- TBL_PC *sd = ((TBL_PC *)bl);
- int i;
- if (sd->spiritball > 0)
- clif_spiritball(&sd->bl);
- if (sd->state.size==SZ_BIG) // tiny/big players [Valaris]
- clif_specialeffect(bl,423,AREA);
- else if (sd->state.size==SZ_MEDIUM)
- clif_specialeffect(bl,421,AREA);
- if (sd->bg_id && map[sd->bl.m].flag.battleground)
- clif_sendbgemblem_area(sd);
- if (sd->sc.option&OPTION_MOUNTING) {
- //New Mounts are not complaint to the original method, so we gotta tell this guy that he is mounting.
- clif_status_load_notick(&sd->bl,SI_ALL_RIDING,2,1,0,0);
- }
- for (i = 1; i < 5; i++) {
- if (sd->talisman[i] > 0)
- clif_talisman(sd, i);
- }
-#ifdef NEW_CARTS
- if (sd->sc.data[SC_PUSH_CART])
- clif_status_load_notick(&sd->bl, SI_ON_PUSH_CART, 2, sd->sc.data[SC_PUSH_CART]->val1, 0, 0);
-#endif
-#if PACKETVER <= 20120207
- if (sd->status.robe)
- clif_refreshlook(bl,bl->id,LOOK_ROBE,sd->status.robe,AREA);
-#endif
- }
- break;
- case BL_MOB: {
- TBL_MOB *md = ((TBL_MOB *)bl);
- if (md->special_state.size==SZ_BIG) // tiny/big mobs [Valaris]
- clif_specialeffect(&md->bl,423,AREA);
- else if (md->special_state.size==SZ_MEDIUM)
- clif_specialeffect(&md->bl,421,AREA);
- }
- break;
- case BL_NPC: {
- TBL_NPC *nd = ((TBL_NPC *)bl);
- if (nd->size == SZ_BIG)
- clif_specialeffect(&nd->bl,423,AREA);
- else if (nd->size == SZ_MEDIUM)
- clif_specialeffect(&nd->bl,421,AREA);
- }
- break;
- case BL_PET:
- if (vd->head_bottom)
- clif_pet_equip_area((TBL_PET *)bl); // needed to display pet equip properly
- break;
- }
- return 0;
+ unsigned char buf[128];
+ struct view_data *vd;
+ int len;
+
+ vd = status_get_viewdata(bl);
+ if( !vd || vd->class_ == INVISIBLE_CLASS )
+ return 0;
+
+ /**
+ * Hide NPC from maya purple card.
+ **/
+ if(bl->type == BL_NPC && !((TBL_NPC*)bl)->chat_id && (((TBL_NPC*)bl)->sc.option&OPTION_INVISIBLE))
+ return 0;
+
+ len = clif_set_unit_idle(bl, buf,true);
+ clif_send(buf, len, bl, AREA_WOS);
+ if (disguised(bl))
+ clif_setdisguise(bl, buf, len);
+
+ if (vd->cloth_color)
+ clif_refreshlook(bl,bl->id,LOOK_CLOTHES_COLOR,vd->cloth_color,AREA_WOS);
+
+ switch (bl->type)
+ {
+ case BL_PC:
+ {
+ TBL_PC *sd = ((TBL_PC*)bl);
+ int i;
+ if (sd->spiritball > 0)
+ clif_spiritball(&sd->bl);
+ if(sd->state.size==SZ_BIG) // tiny/big players [Valaris]
+ clif_specialeffect(bl,423,AREA);
+ else if(sd->state.size==SZ_MEDIUM)
+ clif_specialeffect(bl,421,AREA);
+ if( sd->bg_id && map[sd->bl.m].flag.battleground )
+ clif_sendbgemblem_area(sd);
+ if( sd->sc.option&OPTION_MOUNTING ) {
+ //New Mounts are not complaint to the original method, so we gotta tell this guy that he is mounting.
+ clif_status_load_notick(&sd->bl,SI_ALL_RIDING,2,1,0,0);
+ }
+ for(i = 1; i < 5; i++){
+ if( sd->talisman[i] > 0 )
+ clif_talisman(sd, i);
+ }
+ #ifdef NEW_CARTS
+ if( sd->sc.data[SC_PUSH_CART] )
+ clif_status_load_notick(&sd->bl, SI_ON_PUSH_CART, 2, sd->sc.data[SC_PUSH_CART]->val1, 0, 0);
+ #endif
+ #if PACKETVER <= 20120207
+ if (sd->status.robe)
+ clif_refreshlook(bl,bl->id,LOOK_ROBE,sd->status.robe,AREA);
+ #endif
+ }
+ break;
+ case BL_MOB:
+ {
+ TBL_MOB *md = ((TBL_MOB*)bl);
+ if(md->special_state.size==SZ_BIG) // tiny/big mobs [Valaris]
+ clif_specialeffect(&md->bl,423,AREA);
+ else if(md->special_state.size==SZ_MEDIUM)
+ clif_specialeffect(&md->bl,421,AREA);
+ }
+ break;
+ case BL_NPC:
+ {
+ TBL_NPC *nd = ((TBL_NPC*)bl);
+ if( nd->size == SZ_BIG )
+ clif_specialeffect(&nd->bl,423,AREA);
+ else if( nd->size == SZ_MEDIUM )
+ clif_specialeffect(&nd->bl,421,AREA);
+ }
+ break;
+ case BL_PET:
+ if (vd->head_bottom)
+ clif_pet_equip_area((TBL_PET*)bl); // needed to display pet equip properly
+ break;
+ }
+ return 0;
}
/// Sends information about owned homunculus to the client (ZC_PROPERTY_HOMUN). [orn]
/// 022e <name>.24B <modified>.B <level>.W <hunger>.W <intimacy>.W <equip id>.W <atk>.W <matk>.W <hit>.W <crit>.W <def>.W <mdef>.W <flee>.W <aspd>.W <hp>.W <max hp>.W <sp>.W <max sp>.W <exp>.L <max exp>.L <skill points>.W <atk range>.W
void clif_hominfo(struct map_session_data *sd, struct homun_data *hd, int flag)
{
- struct status_data *status;
- unsigned char buf[128];
- int m_class;
-
- nullpo_retv(hd);
-
- status = &hd->battle_status;
- m_class = hom_class2mapid(hd->homunculus.class_);
-
- memset(buf,0,packet_len(0x22e));
- WBUFW(buf,0)=0x22e;
- memcpy(WBUFP(buf,2),hd->homunculus.name,NAME_LENGTH);
- // Bit field, bit 0 : rename_flag (1 = already renamed), bit 1 : homunc vaporized (1 = true), bit 2 : homunc dead (1 = true)
- WBUFB(buf,26)=(battle_config.hom_rename?0:hd->homunculus.rename_flag) | (hd->homunculus.vaporize << 1) | (hd->homunculus.hp?0:4);
- WBUFW(buf,27)=hd->homunculus.level;
- WBUFW(buf,29)=hd->homunculus.hunger;
- WBUFW(buf,31)=(unsigned short)(hd->homunculus.intimacy / 100) ;
- WBUFW(buf,33)=0; // equip id
- WBUFW(buf,35)=cap_value(status->rhw.atk2+status->batk, 0, INT16_MAX);
- WBUFW(buf,37)=cap_value(status->matk_max, 0, INT16_MAX);
- WBUFW(buf,39)=status->hit;
- if (battle_config.hom_setting&0x10)
- WBUFW(buf,41)=status->luk/3 + 1; //crit is a +1 decimal value! Just display purpose.[Vicious]
- else
- WBUFW(buf,41)=status->cri/10;
- WBUFW(buf,43)=status->def + status->vit ;
- WBUFW(buf,45)=status->mdef;
- WBUFW(buf,47)=status->flee;
- WBUFW(buf,49)=(flag)?0:status->amotion;
- if (status->max_hp > INT16_MAX) {
- WBUFW(buf,51) = status->hp/(status->max_hp/100);
- WBUFW(buf,53) = 100;
- } else {
- WBUFW(buf,51)=status->hp;
- WBUFW(buf,53)=status->max_hp;
- }
- if (status->max_sp > INT16_MAX) {
- WBUFW(buf,55) = status->sp/(status->max_sp/100);
- WBUFW(buf,57) = 100;
- } else {
- WBUFW(buf,55)=status->sp;
- WBUFW(buf,57)=status->max_sp;
- }
- WBUFL(buf,59)=hd->homunculus.exp;
- if (((m_class&HOM_REG) && hd->homunculus.level >= battle_config.hom_max_level) || ((m_class&HOM_S) && hd->homunculus.level >= battle_config.hom_S_max_level))
- WBUFL(buf,63)=0;
- else
- WBUFL(buf,63)=hd->exp_next;
- WBUFW(buf,67)=hd->homunculus.skillpts;
- WBUFW(buf,69)=status_get_range(&hd->bl);
- clif_send(buf,packet_len(0x22e),&sd->bl,SELF);
+ struct status_data *status;
+ unsigned char buf[128];
+ int m_class;
+
+ nullpo_retv(hd);
+
+ status = &hd->battle_status;
+ m_class = hom_class2mapid(hd->homunculus.class_);
+
+ memset(buf,0,packet_len(0x22e));
+ WBUFW(buf,0)=0x22e;
+ memcpy(WBUFP(buf,2),hd->homunculus.name,NAME_LENGTH);
+ // Bit field, bit 0 : rename_flag (1 = already renamed), bit 1 : homunc vaporized (1 = true), bit 2 : homunc dead (1 = true)
+ WBUFB(buf,26)=(battle_config.hom_rename?0:hd->homunculus.rename_flag) | (hd->homunculus.vaporize << 1) | (hd->homunculus.hp?0:4);
+ WBUFW(buf,27)=hd->homunculus.level;
+ WBUFW(buf,29)=hd->homunculus.hunger;
+ WBUFW(buf,31)=(unsigned short) (hd->homunculus.intimacy / 100) ;
+ WBUFW(buf,33)=0; // equip id
+ WBUFW(buf,35)=cap_value(status->rhw.atk2+status->batk, 0, INT16_MAX);
+ WBUFW(buf,37)=cap_value(status->matk_max, 0, INT16_MAX);
+ WBUFW(buf,39)=status->hit;
+ if (battle_config.hom_setting&0x10)
+ WBUFW(buf,41)=status->luk/3 + 1; //crit is a +1 decimal value! Just display purpose.[Vicious]
+ else
+ WBUFW(buf,41)=status->cri/10;
+ WBUFW(buf,43)=status->def + status->vit ;
+ WBUFW(buf,45)=status->mdef;
+ WBUFW(buf,47)=status->flee;
+ WBUFW(buf,49)=(flag)?0:status->amotion;
+ if (status->max_hp > INT16_MAX) {
+ WBUFW(buf,51) = status->hp/(status->max_hp/100);
+ WBUFW(buf,53) = 100;
+ } else {
+ WBUFW(buf,51)=status->hp;
+ WBUFW(buf,53)=status->max_hp;
+ }
+ if (status->max_sp > INT16_MAX) {
+ WBUFW(buf,55) = status->sp/(status->max_sp/100);
+ WBUFW(buf,57) = 100;
+ } else {
+ WBUFW(buf,55)=status->sp;
+ WBUFW(buf,57)=status->max_sp;
+ }
+ WBUFL(buf,59)=hd->homunculus.exp;
+ if( ((m_class&HOM_REG) && hd->homunculus.level >= battle_config.hom_max_level) || ((m_class&HOM_S) && hd->homunculus.level >= battle_config.hom_S_max_level) )
+ WBUFL(buf,63)=0;
+ else
+ WBUFL(buf,63)=hd->exp_next;
+ WBUFW(buf,67)=hd->homunculus.skillpts;
+ WBUFW(buf,69)=status_get_range(&hd->bl);
+ clif_send(buf,packet_len(0x22e),&sd->bl,SELF);
}
@@ -1459,87 +1476,84 @@ void clif_hominfo(struct map_session_data *sd, struct homun_data *hd, int flag)
/// 3 = accessory?
/// ? = ignored
void clif_send_homdata(struct map_session_data *sd, int state, int param)
-{
- //[orn]
- int fd = sd->fd;
+{ //[orn]
+ int fd = sd->fd;
- if ((state == SP_INTIMATE) && (param >= 910) && (sd->hd->homunculus.class_ == sd->hd->homunculusDB->evo_class))
- merc_hom_calc_skilltree(sd->hd, 0);
+ if ( (state == SP_INTIMATE) && (param >= 910) && (sd->hd->homunculus.class_ == sd->hd->homunculusDB->evo_class) )
+ merc_hom_calc_skilltree(sd->hd, 0);
- WFIFOHEAD(fd, packet_len(0x230));
- WFIFOW(fd,0)=0x230;
- WFIFOB(fd,2)=0;
- WFIFOB(fd,3)=state;
- WFIFOL(fd,4)=sd->hd->bl.id;
- WFIFOL(fd,8)=param;
- WFIFOSET(fd,packet_len(0x230));
+ WFIFOHEAD(fd, packet_len(0x230));
+ WFIFOW(fd,0)=0x230;
+ WFIFOB(fd,2)=0;
+ WFIFOB(fd,3)=state;
+ WFIFOL(fd,4)=sd->hd->bl.id;
+ WFIFOL(fd,8)=param;
+ WFIFOSET(fd,packet_len(0x230));
}
int clif_homskillinfoblock(struct map_session_data *sd)
-{
- //[orn]
- struct homun_data *hd;
- int fd = sd->fd;
- int i,j,len=4,id;
- WFIFOHEAD(fd, 4+37*MAX_HOMUNSKILL);
-
- hd = sd->hd;
- if (!hd)
- return 0 ;
-
- WFIFOW(fd,0)=0x235;
- for (i = 0; i < MAX_HOMUNSKILL; i++) {
- if ((id = hd->homunculus.hskill[i].id) != 0) {
- j = id - HM_SKILLBASE;
- WFIFOW(fd,len) = id;
- WFIFOW(fd,len+2) = skill_get_inf(id);
- WFIFOW(fd,len+4) = 0;
- WFIFOW(fd,len+6) = hd->homunculus.hskill[j].lv;
- WFIFOW(fd,len+8) = skill_get_sp(id,hd->homunculus.hskill[j].lv);
- WFIFOW(fd,len+10)= skill_get_range2(&sd->hd->bl, id,hd->homunculus.hskill[j].lv);
- safestrncpy((char *)WFIFOP(fd,len+12), skill_get_name(id), NAME_LENGTH);
- WFIFOB(fd,len+36) = (hd->homunculus.hskill[j].lv < merc_skill_tree_get_max(id, hd->homunculus.class_))?1:0;
- len+=37;
- }
- }
- WFIFOW(fd,2)=len;
- WFIFOSET(fd,len);
-
- return 0;
+{ //[orn]
+ struct homun_data *hd;
+ int fd = sd->fd;
+ int i,j,len=4,id;
+ WFIFOHEAD(fd, 4+37*MAX_HOMUNSKILL);
+
+ hd = sd->hd;
+ if ( !hd )
+ return 0 ;
+
+ WFIFOW(fd,0)=0x235;
+ for ( i = 0; i < MAX_HOMUNSKILL; i++){
+ if( (id = hd->homunculus.hskill[i].id) != 0 ){
+ j = id - HM_SKILLBASE;
+ WFIFOW(fd,len ) = id;
+ WFIFOW(fd,len+2) = skill_get_inf(id);
+ WFIFOW(fd,len+4) = 0;
+ WFIFOW(fd,len+6) = hd->homunculus.hskill[j].lv;
+ WFIFOW(fd,len+8) = skill_get_sp(id,hd->homunculus.hskill[j].lv);
+ WFIFOW(fd,len+10)= skill_get_range2(&sd->hd->bl, id,hd->homunculus.hskill[j].lv);
+ safestrncpy((char*)WFIFOP(fd,len+12), skill_get_name(id), NAME_LENGTH);
+ WFIFOB(fd,len+36) = (hd->homunculus.hskill[j].lv < merc_skill_tree_get_max(id, hd->homunculus.class_))?1:0;
+ len+=37;
+ }
+ }
+ WFIFOW(fd,2)=len;
+ WFIFOSET(fd,len);
+
+ return 0;
}
void clif_homskillup(struct map_session_data *sd, int skill_num)
-{
- //[orn]
- struct homun_data *hd;
- int fd, skillid;
- nullpo_retv(sd);
- skillid = skill_num - HM_SKILLBASE;
+{ //[orn]
+ struct homun_data *hd;
+ int fd, skillid;
+ nullpo_retv(sd);
+ skillid = skill_num - HM_SKILLBASE;
- fd=sd->fd;
- hd=sd->hd;
+ fd=sd->fd;
+ hd=sd->hd;
- WFIFOHEAD(fd, packet_len(0x239));
- WFIFOW(fd,0) = 0x239;
- WFIFOW(fd,2) = skill_num;
- WFIFOW(fd,4) = hd->homunculus.hskill[skillid].lv;
- WFIFOW(fd,6) = skill_get_sp(skill_num,hd->homunculus.hskill[skillid].lv);
- WFIFOW(fd,8) = skill_get_range2(&hd->bl, skill_num,hd->homunculus.hskill[skillid].lv);
- WFIFOB(fd,10) = (hd->homunculus.hskill[skillid].lv < skill_get_max(hd->homunculus.hskill[skillid].id)) ? 1 : 0;
- WFIFOSET(fd,packet_len(0x239));
+ WFIFOHEAD(fd, packet_len(0x239));
+ WFIFOW(fd,0) = 0x239;
+ WFIFOW(fd,2) = skill_num;
+ WFIFOW(fd,4) = hd->homunculus.hskill[skillid].lv;
+ WFIFOW(fd,6) = skill_get_sp(skill_num,hd->homunculus.hskill[skillid].lv);
+ WFIFOW(fd,8) = skill_get_range2(&hd->bl, skill_num,hd->homunculus.hskill[skillid].lv);
+ WFIFOB(fd,10) = (hd->homunculus.hskill[skillid].lv < skill_get_max(hd->homunculus.hskill[skillid].id)) ? 1 : 0;
+ WFIFOSET(fd,packet_len(0x239));
}
-int clif_hom_food(struct map_session_data *sd,int foodid,int fail) //[orn]
+int clif_hom_food(struct map_session_data *sd,int foodid,int fail) //[orn]
{
- int fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x22f));
- WFIFOW(fd,0)=0x22f;
- WFIFOB(fd,2)=fail;
- WFIFOW(fd,3)=foodid;
- WFIFOSET(fd,packet_len(0x22f));
+ int fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0x22f));
+ WFIFOW(fd,0)=0x22f;
+ WFIFOB(fd,2)=fail;
+ WFIFOW(fd,3)=foodid;
+ WFIFOSET(fd,packet_len(0x22f));
- return 0;
+ return 0;
}
@@ -1547,54 +1561,57 @@ int clif_hom_food(struct map_session_data *sd,int foodid,int fail) //[orn]
/// 0087 <walk start time>.L <walk data>.6B
void clif_walkok(struct map_session_data *sd)
{
- int fd=sd->fd;
+ int fd=sd->fd;
- WFIFOHEAD(fd, packet_len(0x87));
- WFIFOW(fd,0)=0x87;
- WFIFOL(fd,2)=gettick();
- WFIFOPOS2(fd,6,sd->bl.x,sd->bl.y,sd->ud.to_x,sd->ud.to_y,8,8);
- WFIFOSET(fd,packet_len(0x87));
+ WFIFOHEAD(fd, packet_len(0x87));
+ WFIFOW(fd,0)=0x87;
+ WFIFOL(fd,2)=gettick();
+ WFIFOPOS2(fd,6,sd->bl.x,sd->bl.y,sd->ud.to_x,sd->ud.to_y,8,8);
+ WFIFOSET(fd,packet_len(0x87));
}
static void clif_move2(struct block_list *bl, struct view_data *vd, struct unit_data *ud)
{
- uint8 buf[128];
- int len;
-
- len = clif_set_unit_walking(bl,ud,buf);
- clif_send(buf,len,bl,AREA_WOS);
- if (disguised(bl))
- clif_setdisguise(bl, buf, len);
-
- if (vd->cloth_color)
- clif_refreshlook(bl,bl->id,LOOK_CLOTHES_COLOR,vd->cloth_color,AREA_WOS);
-
- switch (bl->type) {
- case BL_PC: {
- TBL_PC *sd = ((TBL_PC *)bl);
- // clif_movepc(sd);
- if (sd->state.size==SZ_BIG) // tiny/big players [Valaris]
- clif_specialeffect(&sd->bl,423,AREA);
- else if (sd->state.size==SZ_MEDIUM)
- clif_specialeffect(&sd->bl,421,AREA);
- }
- break;
- case BL_MOB: {
- TBL_MOB *md = ((TBL_MOB *)bl);
- if (md->special_state.size==SZ_BIG) // tiny/big mobs [Valaris]
- clif_specialeffect(&md->bl,423,AREA);
- else if (md->special_state.size==SZ_MEDIUM)
- clif_specialeffect(&md->bl,421,AREA);
- }
- break;
- case BL_PET:
- if (vd->head_bottom) {
- // needed to display pet equip properly
- clif_pet_equip_area((TBL_PET *)bl);
- }
- break;
- }
+ uint8 buf[128];
+ int len;
+
+ len = clif_set_unit_walking(bl,ud,buf);
+ clif_send(buf,len,bl,AREA_WOS);
+ if (disguised(bl))
+ clif_setdisguise(bl, buf, len);
+
+ if(vd->cloth_color)
+ clif_refreshlook(bl,bl->id,LOOK_CLOTHES_COLOR,vd->cloth_color,AREA_WOS);
+
+ switch(bl->type)
+ {
+ case BL_PC:
+ {
+ TBL_PC *sd = ((TBL_PC*)bl);
+// clif_movepc(sd);
+ if(sd->state.size==SZ_BIG) // tiny/big players [Valaris]
+ clif_specialeffect(&sd->bl,423,AREA);
+ else if(sd->state.size==SZ_MEDIUM)
+ clif_specialeffect(&sd->bl,421,AREA);
+ }
+ break;
+ case BL_MOB:
+ {
+ TBL_MOB *md = ((TBL_MOB*)bl);
+ if(md->special_state.size==SZ_BIG) // tiny/big mobs [Valaris]
+ clif_specialeffect(&md->bl,423,AREA);
+ else if(md->special_state.size==SZ_MEDIUM)
+ clif_specialeffect(&md->bl,421,AREA);
+ }
+ break;
+ case BL_PET:
+ if( vd->head_bottom )
+ {// needed to display pet equip properly
+ clif_pet_equip_area((TBL_PET*)bl);
+ }
+ break;
+ }
}
@@ -1603,37 +1620,38 @@ static void clif_move2(struct block_list *bl, struct view_data *vd, struct unit_
/// Note: unit must not be self
void clif_move(struct unit_data *ud)
{
- unsigned char buf[16];
- struct view_data *vd;
- struct block_list *bl = ud->bl;
-
- vd = status_get_viewdata(bl);
- if (!vd || vd->class_ == INVISIBLE_CLASS)
- return; //This performance check is needed to keep GM-hidden objects from being notified to bots.
-
- /**
- * Hide NPC from maya purple card.
- **/
- if (bl->type == BL_NPC && !((TBL_NPC *)bl)->chat_id && (((TBL_NPC *)bl)->sc.option&OPTION_INVISIBLE))
- return;
-
- if (ud->state.speed_changed) {
- // Since we don't know how to update the speed of other objects,
- // use the old walk packet to update the data.
- ud->state.speed_changed = 0;
- clif_move2(bl, vd, ud);
- return;
- }
-
- WBUFW(buf,0)=0x86;
- WBUFL(buf,2)=bl->id;
- WBUFPOS2(buf,6,bl->x,bl->y,ud->to_x,ud->to_y,8,8);
- WBUFL(buf,12)=gettick();
- clif_send(buf, packet_len(0x86), bl, AREA_WOS);
- if (disguised(bl)) {
- WBUFL(buf,2)=-bl->id;
- clif_send(buf, packet_len(0x86), bl, SELF);
- }
+ unsigned char buf[16];
+ struct view_data* vd;
+ struct block_list* bl = ud->bl;
+
+ vd = status_get_viewdata(bl);
+ if (!vd || vd->class_ == INVISIBLE_CLASS)
+ return; //This performance check is needed to keep GM-hidden objects from being notified to bots.
+
+ /**
+ * Hide NPC from maya purple card.
+ **/
+ if(bl->type == BL_NPC && !((TBL_NPC*)bl)->chat_id && (((TBL_NPC*)bl)->sc.option&OPTION_INVISIBLE))
+ return;
+
+ if (ud->state.speed_changed) {
+ // Since we don't know how to update the speed of other objects,
+ // use the old walk packet to update the data.
+ ud->state.speed_changed = 0;
+ clif_move2(bl, vd, ud);
+ return;
+ }
+
+ WBUFW(buf,0)=0x86;
+ WBUFL(buf,2)=bl->id;
+ WBUFPOS2(buf,6,bl->x,bl->y,ud->to_x,ud->to_y,8,8);
+ WBUFL(buf,12)=gettick();
+ clif_send(buf, packet_len(0x86), bl, AREA_WOS);
+ if (disguised(bl))
+ {
+ WBUFL(buf,2)=-bl->id;
+ clif_send(buf, packet_len(0x86), bl, SELF);
+ }
}
@@ -1642,12 +1660,12 @@ void clif_move(struct unit_data *ud)
*------------------------------------------*/
static int clif_delayquit(int tid, unsigned int tick, int id, intptr_t data)
{
- struct map_session_data *sd = NULL;
+ struct map_session_data *sd = NULL;
- //Remove player from map server
- if ((sd = map_id2sd(id)) != NULL && sd->fd == 0) //Should be a disconnected player.
- map_quit(sd);
- return 0;
+ //Remove player from map server
+ if ((sd = map_id2sd(id)) != NULL && sd->fd == 0) //Should be a disconnected player.
+ map_quit(sd);
+ return 0;
}
/*==========================================
@@ -1655,59 +1673,59 @@ static int clif_delayquit(int tid, unsigned int tick, int id, intptr_t data)
*------------------------------------------*/
void clif_quitsave(int fd,struct map_session_data *sd)
{
- if (!battle_config.prevent_logout ||
- DIFF_TICK(gettick(), sd->canlog_tick) > battle_config.prevent_logout)
- map_quit(sd);
- else if (sd->fd) {
- //Disassociate session from player (session is deleted after this function was called)
- //And set a timer to make him quit later.
- session[sd->fd]->session_data = NULL;
- sd->fd = 0;
- add_timer(gettick() + 10000, clif_delayquit, sd->bl.id, 0);
- }
+ if (!battle_config.prevent_logout ||
+ DIFF_TICK(gettick(), sd->canlog_tick) > battle_config.prevent_logout)
+ map_quit(sd);
+ else if (sd->fd)
+ { //Disassociate session from player (session is deleted after this function was called)
+ //And set a timer to make him quit later.
+ session[sd->fd]->session_data = NULL;
+ sd->fd = 0;
+ add_timer(gettick() + 10000, clif_delayquit, sd->bl.id, 0);
+ }
}
/// Notifies the client of a position change to coordinates on given map (ZC_NPCACK_MAPMOVE).
/// 0091 <map name>.16B <x>.W <y>.W
void clif_changemap(struct map_session_data *sd, short map, int x, int y)
{
- int fd;
- nullpo_retv(sd);
- fd = sd->fd;
+ int fd;
+ nullpo_retv(sd);
+ fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x91));
- WFIFOW(fd,0) = 0x91;
- mapindex_getmapname_ext(mapindex_id2name(map), (char *)WFIFOP(fd,2));
- WFIFOW(fd,18) = x;
- WFIFOW(fd,20) = y;
- WFIFOSET(fd,packet_len(0x91));
+ WFIFOHEAD(fd,packet_len(0x91));
+ WFIFOW(fd,0) = 0x91;
+ mapindex_getmapname_ext(mapindex_id2name(map), (char*)WFIFOP(fd,2));
+ WFIFOW(fd,18) = x;
+ WFIFOW(fd,20) = y;
+ WFIFOSET(fd,packet_len(0x91));
}
/// Notifies the client of a position change to coordinates on given map, which is on another map-server (ZC_NPCACK_SERVERMOVE).
/// 0092 <map name>.16B <x>.W <y>.W <ip>.L <port>.W
-void clif_changemapserver(struct map_session_data *sd, unsigned short map_index, int x, int y, uint32 ip, uint16 port)
+void clif_changemapserver(struct map_session_data* sd, unsigned short map_index, int x, int y, uint32 ip, uint16 port)
{
- int fd;
- nullpo_retv(sd);
- fd = sd->fd;
+ int fd;
+ nullpo_retv(sd);
+ fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x92));
- WFIFOW(fd,0) = 0x92;
- mapindex_getmapname_ext(mapindex_id2name(map_index), (char *)WFIFOP(fd,2));
- WFIFOW(fd,18) = x;
- WFIFOW(fd,20) = y;
- WFIFOL(fd,22) = htonl(ip);
- WFIFOW(fd,26) = ntows(htons(port)); // [!] LE byte order here [!]
- WFIFOSET(fd,packet_len(0x92));
+ WFIFOHEAD(fd,packet_len(0x92));
+ WFIFOW(fd,0) = 0x92;
+ mapindex_getmapname_ext(mapindex_id2name(map_index), (char*)WFIFOP(fd,2));
+ WFIFOW(fd,18) = x;
+ WFIFOW(fd,20) = y;
+ WFIFOL(fd,22) = htonl(ip);
+ WFIFOW(fd,26) = ntows(htons(port)); // [!] LE byte order here [!]
+ WFIFOSET(fd,packet_len(0x92));
}
void clif_blown(struct block_list *bl)
{
- //Aegis packets says fixpos, but it's unsure whether slide works better or not.
- // clif_fixpos(bl);
- clif_slide(bl, bl->x, bl->y);
+//Aegis packets says fixpos, but it's unsure whether slide works better or not.
+// clif_fixpos(bl);
+ clif_slide(bl, bl->x, bl->y);
}
@@ -1717,35 +1735,36 @@ void clif_blown(struct block_list *bl)
/// 0088 <id>.L <x>.W <y>.W
void clif_fixpos(struct block_list *bl)
{
- unsigned char buf[10];
- nullpo_retv(bl);
+ unsigned char buf[10];
+ nullpo_retv(bl);
- WBUFW(buf,0) = 0x88;
- WBUFL(buf,2) = bl->id;
- WBUFW(buf,6) = bl->x;
- WBUFW(buf,8) = bl->y;
- clif_send(buf, packet_len(0x88), bl, AREA);
+ WBUFW(buf,0) = 0x88;
+ WBUFL(buf,2) = bl->id;
+ WBUFW(buf,6) = bl->x;
+ WBUFW(buf,8) = bl->y;
+ clif_send(buf, packet_len(0x88), bl, AREA);
- if (disguised(bl)) {
- WBUFL(buf,2) = -bl->id;
- clif_send(buf, packet_len(0x88), bl, SELF);
- }
+ if( disguised(bl) )
+ {
+ WBUFL(buf,2) = -bl->id;
+ clif_send(buf, packet_len(0x88), bl, SELF);
+ }
}
/// Displays the buy/sell dialog of an NPC shop (ZC_SELECT_DEALTYPE).
/// 00c4 <shop id>.L
-void clif_npcbuysell(struct map_session_data *sd, int id)
+void clif_npcbuysell(struct map_session_data* sd, int id)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd, packet_len(0xc4));
- WFIFOW(fd,0)=0xc4;
- WFIFOL(fd,2)=id;
- WFIFOSET(fd,packet_len(0xc4));
+ fd=sd->fd;
+ WFIFOHEAD(fd, packet_len(0xc4));
+ WFIFOW(fd,0)=0xc4;
+ WFIFOL(fd,2)=id;
+ WFIFOSET(fd,packet_len(0xc4));
}
@@ -1753,30 +1772,31 @@ void clif_npcbuysell(struct map_session_data *sd, int id)
/// 00c6 <packet len>.W { <price>.L <discount price>.L <item type>.B <name id>.W }*
void clif_buylist(struct map_session_data *sd, struct npc_data *nd)
{
- int fd,i,c;
+ int fd,i,c;
- nullpo_retv(sd);
- nullpo_retv(nd);
-
- fd = sd->fd;
- WFIFOHEAD(fd, 4 + nd->u.shop.count * 11);
- WFIFOW(fd,0) = 0xc6;
-
- c = 0;
- for (i = 0; i < nd->u.shop.count; i++) {
- struct item_data *id = itemdb_exists(nd->u.shop.shop_item[i].nameid);
- int val = nd->u.shop.shop_item[i].value;
- if (id == NULL)
- continue;
- WFIFOL(fd, 4+c*11) = val;
- WFIFOL(fd, 8+c*11) = pc_modifybuyvalue(sd,val);
- WFIFOB(fd,12+c*11) = itemtype(id->type);
- WFIFOW(fd,13+c*11) = (id->view_id > 0) ? id->view_id : id->nameid;
- c++;
- }
+ nullpo_retv(sd);
+ nullpo_retv(nd);
- WFIFOW(fd,2) = 4 + c*11;
- WFIFOSET(fd,WFIFOW(fd,2));
+ fd = sd->fd;
+ WFIFOHEAD(fd, 4 + nd->u.shop.count * 11);
+ WFIFOW(fd,0) = 0xc6;
+
+ c = 0;
+ for( i = 0; i < nd->u.shop.count; i++ )
+ {
+ struct item_data* id = itemdb_exists(nd->u.shop.shop_item[i].nameid);
+ int val = nd->u.shop.shop_item[i].value;
+ if( id == NULL )
+ continue;
+ WFIFOL(fd, 4+c*11) = val;
+ WFIFOL(fd, 8+c*11) = pc_modifybuyvalue(sd,val);
+ WFIFOB(fd,12+c*11) = itemtype(id->type);
+ WFIFOW(fd,13+c*11) = ( id->view_id > 0 ) ? id->view_id : id->nameid;
+ c++;
+ }
+
+ WFIFOW(fd,2) = 4 + c*11;
+ WFIFOSET(fd,WFIFOW(fd,2));
}
@@ -1784,32 +1804,34 @@ void clif_buylist(struct map_session_data *sd, struct npc_data *nd)
/// 00c7 <packet len>.W { <index>.W <price>.L <overcharge price>.L }*
void clif_selllist(struct map_session_data *sd)
{
- int fd,i,c=0,val;
+ int fd,i,c=0,val;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd, MAX_INVENTORY * 10 + 4);
- WFIFOW(fd,0)=0xc7;
- for (i = 0; i < MAX_INVENTORY; i++) {
- if (sd->status.inventory[i].nameid > 0 && sd->inventory_data[i]) {
- if (!itemdb_cansell(&sd->status.inventory[i], pc_get_group_level(sd)))
- continue;
-
- if (sd->status.inventory[i].expire_time)
- continue; // Cannot Sell Rental Items
-
- val=sd->inventory_data[i]->value_sell;
- if (val < 0)
- continue;
- WFIFOW(fd,4+c*10)=i+2;
- WFIFOL(fd,6+c*10)=val;
- WFIFOL(fd,10+c*10)=pc_modifysellvalue(sd,val);
- c++;
- }
- }
- WFIFOW(fd,2)=c*10+4;
- WFIFOSET(fd,WFIFOW(fd,2));
+ fd=sd->fd;
+ WFIFOHEAD(fd, MAX_INVENTORY * 10 + 4);
+ WFIFOW(fd,0)=0xc7;
+ for( i = 0; i < MAX_INVENTORY; i++ )
+ {
+ if( sd->status.inventory[i].nameid > 0 && sd->inventory_data[i] )
+ {
+ if( !itemdb_cansell(&sd->status.inventory[i], pc_get_group_level(sd)) )
+ continue;
+
+ if( sd->status.inventory[i].expire_time )
+ continue; // Cannot Sell Rental Items
+
+ val=sd->inventory_data[i]->value_sell;
+ if( val < 0 )
+ continue;
+ WFIFOW(fd,4+c*10)=i+2;
+ WFIFOL(fd,6+c*10)=val;
+ WFIFOL(fd,10+c*10)=pc_modifysellvalue(sd,val);
+ c++;
+ }
+ }
+ WFIFOW(fd,2)=c*10+4;
+ WFIFOSET(fd,WFIFOW(fd,2));
}
@@ -1823,15 +1845,15 @@ void clif_selllist(struct map_session_data *sd)
/// - append this text
void clif_scriptmes(struct map_session_data *sd, int npcid, const char *mes)
{
- int fd = sd->fd;
- int slen = strlen(mes) + 9;
+ int fd = sd->fd;
+ int slen = strlen(mes) + 9;
- WFIFOHEAD(fd, slen);
- WFIFOW(fd,0)=0xb4;
- WFIFOW(fd,2)=slen;
- WFIFOL(fd,4)=npcid;
- memcpy((char *)WFIFOP(fd,8), mes, slen-8);
- WFIFOSET(fd,WFIFOW(fd,2));
+ WFIFOHEAD(fd, slen);
+ WFIFOW(fd,0)=0xb4;
+ WFIFOW(fd,2)=slen;
+ WFIFOL(fd,4)=npcid;
+ memcpy((char*)WFIFOP(fd,8), mes, slen-8);
+ WFIFOSET(fd,WFIFOW(fd,2));
}
@@ -1847,15 +1869,15 @@ void clif_scriptmes(struct map_session_data *sd, int npcid, const char *mes)
/// - remove 'next' button
void clif_scriptnext(struct map_session_data *sd,int npcid)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd, packet_len(0xb5));
- WFIFOW(fd,0)=0xb5;
- WFIFOL(fd,2)=npcid;
- WFIFOSET(fd,packet_len(0xb5));
+ fd=sd->fd;
+ WFIFOHEAD(fd, packet_len(0xb5));
+ WFIFOW(fd,0)=0xb5;
+ WFIFOL(fd,2)=npcid;
+ WFIFOSET(fd,packet_len(0xb5));
}
@@ -1876,15 +1898,15 @@ void clif_scriptnext(struct map_session_data *sd,int npcid)
/// - 0146 <npcid of dialog window>.L
void clif_scriptclose(struct map_session_data *sd, int npcid)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd, packet_len(0xb6));
- WFIFOW(fd,0)=0xb6;
- WFIFOL(fd,2)=npcid;
- WFIFOSET(fd,packet_len(0xb6));
+ fd=sd->fd;
+ WFIFOHEAD(fd, packet_len(0xb6));
+ WFIFOW(fd,0)=0xb6;
+ WFIFOL(fd,2)=npcid;
+ WFIFOSET(fd,packet_len(0xb6));
}
/*==========================================
@@ -1892,24 +1914,24 @@ void clif_scriptclose(struct map_session_data *sd, int npcid)
*------------------------------------------*/
void clif_sendfakenpc(struct map_session_data *sd, int npcid)
{
- unsigned char *buf;
- int fd = sd->fd;
- sd->state.using_fake_npc = 1;
+ unsigned char *buf;
+ int fd = sd->fd;
+ sd->state.using_fake_npc = 1;
- WFIFOHEAD(fd, packet_len(0x78));
- buf = WFIFOP(fd,0);
- memset(WBUFP(buf,0), 0, packet_len(0x78));
- WBUFW(buf,0)=0x78;
+ WFIFOHEAD(fd, packet_len(0x78));
+ buf = WFIFOP(fd,0);
+ memset(WBUFP(buf,0), 0, packet_len(0x78));
+ WBUFW(buf,0)=0x78;
#if PACKETVER >= 20071106
- WBUFB(buf,2) = 0; // object type
- buf = WFIFOP(fd,1);
+ WBUFB(buf,2) = 0; // object type
+ buf = WFIFOP(fd,1);
#endif
- WBUFL(buf,2)=npcid;
- WBUFW(buf,14)=111;
- WBUFPOS(buf,46,sd->bl.x,sd->bl.y,sd->ud.dir);
- WBUFB(buf,49)=5;
- WBUFB(buf,50)=5;
- WFIFOSET(fd, packet_len(0x78));
+ WBUFL(buf,2)=npcid;
+ WBUFW(buf,14)=111;
+ WBUFPOS(buf,46,sd->bl.x,sd->bl.y,sd->ud.dir);
+ WBUFB(buf,49)=5;
+ WBUFB(buf,50)=5;
+ WFIFOSET(fd, packet_len(0x78));
}
@@ -1933,23 +1955,23 @@ void clif_sendfakenpc(struct map_session_data *sd, int npcid)
/// WARNING: the 'cancel' button closes other windows besides the dialog window and the menu window.
/// Which suggests their have intertwined behavior. (probably the mouse targeting)
/// TODO investigate behavior of other windows [FlavioJS]
-void clif_scriptmenu(struct map_session_data *sd, int npcid, const char *mes)
+void clif_scriptmenu(struct map_session_data* sd, int npcid, const char* mes)
{
- int fd = sd->fd;
- int slen = strlen(mes) + 9;
- struct block_list *bl = NULL;
+ int fd = sd->fd;
+ int slen = strlen(mes) + 9;
+ struct block_list *bl = NULL;
- if (!sd->state.using_fake_npc && (npcid == fake_nd->bl.id || ((bl = map_id2bl(npcid)) && (bl->m!=sd->bl.m ||
- bl->x<sd->bl.x-AREA_SIZE-1 || bl->x>sd->bl.x+AREA_SIZE+1 ||
- bl->y<sd->bl.y-AREA_SIZE-1 || bl->y>sd->bl.y+AREA_SIZE+1))))
- clif_sendfakenpc(sd, npcid);
+ if (!sd->state.using_fake_npc && (npcid == fake_nd->bl.id || ((bl = map_id2bl(npcid)) && (bl->m!=sd->bl.m ||
+ bl->x<sd->bl.x-AREA_SIZE-1 || bl->x>sd->bl.x+AREA_SIZE+1 ||
+ bl->y<sd->bl.y-AREA_SIZE-1 || bl->y>sd->bl.y+AREA_SIZE+1))))
+ clif_sendfakenpc(sd, npcid);
- WFIFOHEAD(fd, slen);
- WFIFOW(fd,0)=0xb7;
- WFIFOW(fd,2)=slen;
- WFIFOL(fd,4)=npcid;
- memcpy((char *)WFIFOP(fd,8), mes, slen-8);
- WFIFOSET(fd,WFIFOW(fd,2));
+ WFIFOHEAD(fd, slen);
+ WFIFOW(fd,0)=0xb7;
+ WFIFOW(fd,2)=slen;
+ WFIFOL(fd,4)=npcid;
+ memcpy((char*)WFIFOP(fd,8), mes, slen-8);
+ WFIFOSET(fd,WFIFOW(fd,2));
}
@@ -1966,21 +1988,21 @@ void clif_scriptmenu(struct map_session_data *sd, int npcid, const char *mes)
/// - close inputnum window
void clif_scriptinput(struct map_session_data *sd, int npcid)
{
- int fd;
- struct block_list *bl = NULL;
+ int fd;
+ struct block_list *bl = NULL;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- if (!sd->state.using_fake_npc && (npcid == fake_nd->bl.id || ((bl = map_id2bl(npcid)) && (bl->m!=sd->bl.m ||
- bl->x<sd->bl.x-AREA_SIZE-1 || bl->x>sd->bl.x+AREA_SIZE+1 ||
- bl->y<sd->bl.y-AREA_SIZE-1 || bl->y>sd->bl.y+AREA_SIZE+1))))
- clif_sendfakenpc(sd, npcid);
+ if (!sd->state.using_fake_npc && (npcid == fake_nd->bl.id || ((bl = map_id2bl(npcid)) && (bl->m!=sd->bl.m ||
+ bl->x<sd->bl.x-AREA_SIZE-1 || bl->x>sd->bl.x+AREA_SIZE+1 ||
+ bl->y<sd->bl.y-AREA_SIZE-1 || bl->y>sd->bl.y+AREA_SIZE+1))))
+ clif_sendfakenpc(sd, npcid);
- fd=sd->fd;
- WFIFOHEAD(fd, packet_len(0x142));
- WFIFOW(fd,0)=0x142;
- WFIFOL(fd,2)=npcid;
- WFIFOSET(fd,packet_len(0x142));
+ fd=sd->fd;
+ WFIFOHEAD(fd, packet_len(0x142));
+ WFIFOW(fd,0)=0x142;
+ WFIFOL(fd,2)=npcid;
+ WFIFOSET(fd,packet_len(0x142));
}
@@ -1997,21 +2019,21 @@ void clif_scriptinput(struct map_session_data *sd, int npcid)
/// - close inputstr window
void clif_scriptinputstr(struct map_session_data *sd, int npcid)
{
- int fd;
- struct block_list *bl = NULL;
+ int fd;
+ struct block_list *bl = NULL;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- if (!sd->state.using_fake_npc && (npcid == fake_nd->bl.id || ((bl = map_id2bl(npcid)) && (bl->m!=sd->bl.m ||
- bl->x<sd->bl.x-AREA_SIZE-1 || bl->x>sd->bl.x+AREA_SIZE+1 ||
- bl->y<sd->bl.y-AREA_SIZE-1 || bl->y>sd->bl.y+AREA_SIZE+1))))
- clif_sendfakenpc(sd, npcid);
+ if (!sd->state.using_fake_npc && (npcid == fake_nd->bl.id || ((bl = map_id2bl(npcid)) && (bl->m!=sd->bl.m ||
+ bl->x<sd->bl.x-AREA_SIZE-1 || bl->x>sd->bl.x+AREA_SIZE+1 ||
+ bl->y<sd->bl.y-AREA_SIZE-1 || bl->y>sd->bl.y+AREA_SIZE+1))))
+ clif_sendfakenpc(sd, npcid);
- fd=sd->fd;
- WFIFOHEAD(fd, packet_len(0x1d4));
- WFIFOW(fd,0)=0x1d4;
- WFIFOL(fd,2)=npcid;
- WFIFOSET(fd,packet_len(0x1d4));
+ fd=sd->fd;
+ WFIFOHEAD(fd, packet_len(0x1d4));
+ WFIFOW(fd,0)=0x1d4;
+ WFIFOL(fd,2)=npcid;
+ WFIFOSET(fd,packet_len(0x1d4));
}
@@ -2027,20 +2049,20 @@ void clif_scriptinputstr(struct map_session_data *sd, int npcid)
/// 0x00RRGGBB
void clif_viewpoint(struct map_session_data *sd, int npc_id, int type, int x, int y, int id, int color)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd, packet_len(0x144));
- WFIFOW(fd,0)=0x144;
- WFIFOL(fd,2)=npc_id;
- WFIFOL(fd,6)=type;
- WFIFOL(fd,10)=x;
- WFIFOL(fd,14)=y;
- WFIFOB(fd,18)=id;
- WFIFOL(fd,19)=color;
- WFIFOSET(fd,packet_len(0x144));
+ fd=sd->fd;
+ WFIFOHEAD(fd, packet_len(0x144));
+ WFIFOW(fd,0)=0x144;
+ WFIFOL(fd,2)=npc_id;
+ WFIFOL(fd,6)=type;
+ WFIFOL(fd,10)=x;
+ WFIFOL(fd,14)=y;
+ WFIFOB(fd,18)=id;
+ WFIFOL(fd,19)=color;
+ WFIFOSET(fd,packet_len(0x144));
}
@@ -2053,72 +2075,72 @@ void clif_viewpoint(struct map_session_data *sd, int npc_id, int type, int x, in
/// 2 = bottom right corner
/// 3 = middle of screen, inside a movable window
/// 4 = middle of screen, movable with a close button, chrome-less
-void clif_cutin(struct map_session_data *sd, const char *image, int type)
+void clif_cutin(struct map_session_data* sd, const char* image, int type)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd, packet_len(0x1b3));
- WFIFOW(fd,0)=0x1b3;
- strncpy((char *)WFIFOP(fd,2),image,64);
- WFIFOB(fd,66)=type;
- WFIFOSET(fd,packet_len(0x1b3));
+ fd=sd->fd;
+ WFIFOHEAD(fd, packet_len(0x1b3));
+ WFIFOW(fd,0)=0x1b3;
+ strncpy((char*)WFIFOP(fd,2),image,64);
+ WFIFOB(fd,66)=type;
+ WFIFOSET(fd,packet_len(0x1b3));
}
/*==========================================
* Fills in card data from the given item and into the buffer. [Skotlex]
*------------------------------------------*/
-static void clif_addcards(unsigned char *buf, struct item *item)
-{
- int i=0,j;
- if (item == NULL) { //Blank data
- WBUFW(buf,0) = 0;
- WBUFW(buf,2) = 0;
- WBUFW(buf,4) = 0;
- WBUFW(buf,6) = 0;
- return;
- }
- if (item->card[0] == CARD0_PET) { //pet eggs
- WBUFW(buf,0) = 0;
- WBUFW(buf,2) = 0;
- WBUFW(buf,4) = 0;
- WBUFW(buf,6) = item->card[3]; //Pet renamed flag.
- return;
- }
- if (item->card[0] == CARD0_FORGE || item->card[0] == CARD0_CREATE) { //Forged/created items
- WBUFW(buf,0) = item->card[0];
- WBUFW(buf,2) = item->card[1];
- WBUFW(buf,4) = item->card[2];
- WBUFW(buf,6) = item->card[3];
- return;
- }
- //Client only receives four cards.. so randomly send them a set of cards. [Skotlex]
- if (MAX_SLOTS > 4 && (j = itemdb_slot(item->nameid)) > 4)
- i = rnd()%(j-3); //eg: 6 slots, possible i values: 0->3, 1->4, 2->5 => i = rnd()%3;
-
- //Normal items.
- if (item->card[i] > 0 && (j=itemdb_viewid(item->card[i])) > 0)
- WBUFW(buf,0) = j;
- else
- WBUFW(buf,0) = item->card[i];
-
- if (item->card[++i] > 0 && (j=itemdb_viewid(item->card[i])) > 0)
- WBUFW(buf,2) = j;
- else
- WBUFW(buf,2) = item->card[i];
-
- if (item->card[++i] > 0 && (j=itemdb_viewid(item->card[i])) > 0)
- WBUFW(buf,4) = j;
- else
- WBUFW(buf,4) = item->card[i];
-
- if (item->card[++i] > 0 && (j=itemdb_viewid(item->card[i])) > 0)
- WBUFW(buf,6) = j;
- else
- WBUFW(buf,6) = item->card[i];
+static void clif_addcards(unsigned char* buf, struct item* item)
+{
+ int i=0,j;
+ if( item == NULL ) { //Blank data
+ WBUFW(buf,0) = 0;
+ WBUFW(buf,2) = 0;
+ WBUFW(buf,4) = 0;
+ WBUFW(buf,6) = 0;
+ return;
+ }
+ if( item->card[0] == CARD0_PET ) { //pet eggs
+ WBUFW(buf,0) = 0;
+ WBUFW(buf,2) = 0;
+ WBUFW(buf,4) = 0;
+ WBUFW(buf,6) = item->card[3]; //Pet renamed flag.
+ return;
+ }
+ if( item->card[0] == CARD0_FORGE || item->card[0] == CARD0_CREATE ) { //Forged/created items
+ WBUFW(buf,0) = item->card[0];
+ WBUFW(buf,2) = item->card[1];
+ WBUFW(buf,4) = item->card[2];
+ WBUFW(buf,6) = item->card[3];
+ return;
+ }
+ //Client only receives four cards.. so randomly send them a set of cards. [Skotlex]
+ if( MAX_SLOTS > 4 && (j = itemdb_slot(item->nameid)) > 4 )
+ i = rnd()%(j-3); //eg: 6 slots, possible i values: 0->3, 1->4, 2->5 => i = rnd()%3;
+
+ //Normal items.
+ if( item->card[i] > 0 && (j=itemdb_viewid(item->card[i])) > 0 )
+ WBUFW(buf,0) = j;
+ else
+ WBUFW(buf,0) = item->card[i];
+
+ if( item->card[++i] > 0 && (j=itemdb_viewid(item->card[i])) > 0 )
+ WBUFW(buf,2) = j;
+ else
+ WBUFW(buf,2) = item->card[i];
+
+ if( item->card[++i] > 0 && (j=itemdb_viewid(item->card[i])) > 0 )
+ WBUFW(buf,4) = j;
+ else
+ WBUFW(buf,4) = item->card[i];
+
+ if( item->card[++i] > 0 && (j=itemdb_viewid(item->card[i])) > 0 )
+ WBUFW(buf,6) = j;
+ else
+ WBUFW(buf,6) = item->card[i];
}
@@ -2128,69 +2150,72 @@ static void clif_addcards(unsigned char *buf, struct item *item)
/// 02d4 <index>.W <amount>.W <name id>.W <identified>.B <damaged>.B <refine>.B <card1>.W <card2>.W <card3>.W <card4>.W <equip location>.W <item type>.B <result>.B <expire time>.L <bindOnEquipType>.W (ZC_ITEM_PICKUP_ACK3)
void clif_additem(struct map_session_data *sd, int n, int amount, int fail)
{
- int fd;
+ int fd;
#if PACKETVER < 20061218
- const int cmd = 0xa0;
+ const int cmd = 0xa0;
#elif PACKETVER < 20071002
- const int cmd = 0x29a;
+ const int cmd = 0x29a;
#else
- const int cmd = 0x2d4;
+ const int cmd = 0x2d4;
#endif
- nullpo_retv(sd);
-
- fd = sd->fd;
- if (!session_isActive(fd)) //Sasuke-
- return;
-
- WFIFOHEAD(fd,packet_len(cmd));
- if (fail) {
- WFIFOW(fd,0)=cmd;
- WFIFOW(fd,2)=n+2;
- WFIFOW(fd,4)=amount;
- WFIFOW(fd,6)=0;
- WFIFOB(fd,8)=0;
- WFIFOB(fd,9)=0;
- WFIFOB(fd,10)=0;
- WFIFOW(fd,11)=0;
- WFIFOW(fd,13)=0;
- WFIFOW(fd,15)=0;
- WFIFOW(fd,17)=0;
- WFIFOW(fd,19)=0;
- WFIFOB(fd,21)=0;
- WFIFOB(fd,22)=fail;
+ nullpo_retv(sd);
+
+ fd = sd->fd;
+ if( !session_isActive(fd) ) //Sasuke-
+ return;
+
+ WFIFOHEAD(fd,packet_len(cmd));
+ if( fail )
+ {
+ WFIFOW(fd,0)=cmd;
+ WFIFOW(fd,2)=n+2;
+ WFIFOW(fd,4)=amount;
+ WFIFOW(fd,6)=0;
+ WFIFOB(fd,8)=0;
+ WFIFOB(fd,9)=0;
+ WFIFOB(fd,10)=0;
+ WFIFOW(fd,11)=0;
+ WFIFOW(fd,13)=0;
+ WFIFOW(fd,15)=0;
+ WFIFOW(fd,17)=0;
+ WFIFOW(fd,19)=0;
+ WFIFOB(fd,21)=0;
+ WFIFOB(fd,22)=fail;
#if PACKETVER >= 20061218
- WFIFOL(fd,23)=0;
+ WFIFOL(fd,23)=0;
#endif
#if PACKETVER >= 20071002
- WFIFOW(fd,27)=0; // unknown
+ WFIFOW(fd,27)=0; // unknown
#endif
- } else {
- if (n < 0 || n >= MAX_INVENTORY || sd->status.inventory[n].nameid <=0 || sd->inventory_data[n] == NULL)
- return;
-
- WFIFOW(fd,0)=cmd;
- WFIFOW(fd,2)=n+2;
- WFIFOW(fd,4)=amount;
- if (sd->inventory_data[n]->view_id > 0)
- WFIFOW(fd,6)=sd->inventory_data[n]->view_id;
- else
- WFIFOW(fd,6)=sd->status.inventory[n].nameid;
- WFIFOB(fd,8)=sd->status.inventory[n].identify;
- WFIFOB(fd,9)=sd->status.inventory[n].attribute;
- WFIFOB(fd,10)=sd->status.inventory[n].refine;
- clif_addcards(WFIFOP(fd,11), &sd->status.inventory[n]);
- WFIFOW(fd,19)=pc_equippoint(sd,n);
- WFIFOB(fd,21)=itemtype(sd->inventory_data[n]->type);
- WFIFOB(fd,22)=fail;
+ }
+ else
+ {
+ if( n < 0 || n >= MAX_INVENTORY || sd->status.inventory[n].nameid <=0 || sd->inventory_data[n] == NULL )
+ return;
+
+ WFIFOW(fd,0)=cmd;
+ WFIFOW(fd,2)=n+2;
+ WFIFOW(fd,4)=amount;
+ if (sd->inventory_data[n]->view_id > 0)
+ WFIFOW(fd,6)=sd->inventory_data[n]->view_id;
+ else
+ WFIFOW(fd,6)=sd->status.inventory[n].nameid;
+ WFIFOB(fd,8)=sd->status.inventory[n].identify;
+ WFIFOB(fd,9)=sd->status.inventory[n].attribute;
+ WFIFOB(fd,10)=sd->status.inventory[n].refine;
+ clif_addcards(WFIFOP(fd,11), &sd->status.inventory[n]);
+ WFIFOW(fd,19)=pc_equippoint(sd,n);
+ WFIFOB(fd,21)=itemtype(sd->inventory_data[n]->type);
+ WFIFOB(fd,22)=fail;
#if PACKETVER >= 20061218
- WFIFOL(fd,23)=sd->status.inventory[n].expire_time;
+ WFIFOL(fd,23)=sd->status.inventory[n].expire_time;
#endif
#if PACKETVER >= 20071002
- WFIFOW(fd,27)=0; // unknown
+ WFIFOW(fd,27)=0; // unknown
#endif
- }
+ }
- WFIFOSET(fd,packet_len(cmd));
+ WFIFOSET(fd,packet_len(cmd));
}
@@ -2198,16 +2223,16 @@ void clif_additem(struct map_session_data *sd, int n, int amount, int fail)
/// 00af <index>.W <amount>.W
void clif_dropitem(struct map_session_data *sd,int n,int amount)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd, packet_len(0xaf));
- WFIFOW(fd,0)=0xaf;
- WFIFOW(fd,2)=n+2;
- WFIFOW(fd,4)=amount;
- WFIFOSET(fd,packet_len(0xaf));
+ fd=sd->fd;
+ WFIFOHEAD(fd, packet_len(0xaf));
+ WFIFOW(fd,0)=0xaf;
+ WFIFOW(fd,2)=n+2;
+ WFIFOW(fd,4)=amount;
+ WFIFOSET(fd,packet_len(0xaf));
}
@@ -2225,20 +2250,20 @@ void clif_dropitem(struct map_session_data *sd,int n,int amount)
void clif_delitem(struct map_session_data *sd,int n,int amount, short reason)
{
#if PACKETVER < 20091117
- clif_dropitem(sd,n,amount);
+ clif_dropitem(sd,n,amount);
#else
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
+ fd=sd->fd;
- WFIFOHEAD(fd, packet_len(0x7fa));
- WFIFOW(fd,0)=0x7fa;
- WFIFOW(fd,2)=reason;
- WFIFOW(fd,4)=n+2;
- WFIFOW(fd,6)=amount;
- WFIFOSET(fd,packet_len(0x7fa));
+ WFIFOHEAD(fd, packet_len(0x7fa));
+ WFIFOW(fd,0)=0x7fa;
+ WFIFOW(fd,2)=reason;
+ WFIFOW(fd,4)=n+2;
+ WFIFOW(fd,6)=amount;
+ WFIFOSET(fd,packet_len(0x7fa));
#endif
}
@@ -2248,323 +2273,335 @@ void clif_delitem(struct map_session_data *sd,int n,int amount, short reason)
// armor/egg) -1 for stackable items, -2 for stackable items where arrows must send in the equip-point.
void clif_item_sub(unsigned char *buf, int n, struct item *i, struct item_data *id, int equip)
{
- if (id->view_id > 0)
- WBUFW(buf,n)=id->view_id;
- else
- WBUFW(buf,n)=i->nameid;
- WBUFB(buf,n+2)=itemtype(id->type);
- WBUFB(buf,n+3)=i->identify;
- if (equip >= 0) { //Equippable item
- WBUFW(buf,n+4)=equip;
- WBUFW(buf,n+6)=i->equip;
- WBUFB(buf,n+8)=i->attribute;
- WBUFB(buf,n+9)=i->refine;
- } else { //Stackable item.
- WBUFW(buf,n+4)=i->amount;
- if (equip == -2 && id->equip == EQP_AMMO)
- WBUFW(buf,n+6)=EQP_AMMO;
- else
- WBUFW(buf,n+6)=0;
- }
-
-}
-void clif_favorite_item(struct map_session_data *sd, unsigned short index);
+ if (id->view_id > 0)
+ WBUFW(buf,n)=id->view_id;
+ else
+ WBUFW(buf,n)=i->nameid;
+ WBUFB(buf,n+2)=itemtype(id->type);
+ WBUFB(buf,n+3)=i->identify;
+ if (equip >= 0) { //Equippable item
+ WBUFW(buf,n+4)=equip;
+ WBUFW(buf,n+6)=i->equip;
+ WBUFB(buf,n+8)=i->attribute;
+ WBUFB(buf,n+9)=i->refine;
+ } else { //Stackable item.
+ WBUFW(buf,n+4)=i->amount;
+ if (equip == -2 && id->equip == EQP_AMMO)
+ WBUFW(buf,n+6)=EQP_AMMO;
+ else
+ WBUFW(buf,n+6)=0;
+ }
+
+}
+void clif_favorite_item(struct map_session_data* sd, unsigned short index);
//Unified inventory function which sends all of the inventory (requires two packets, one for equipable items and one for stackable ones. [Skotlex]
void clif_inventorylist(struct map_session_data *sd)
{
- int i,n,ne,arrow=-1;
- unsigned char *buf;
- unsigned char *bufe;
+ int i,n,ne,arrow=-1;
+ unsigned char *buf;
+ unsigned char *bufe;
#if PACKETVER < 5
- const int s = 10; //Entry size.
+ const int s = 10; //Entry size.
#elif PACKETVER < 20080102
- const int s = 18;
+ const int s = 18;
#else
- const int s = 22;
+ const int s = 22;
#endif
#if PACKETVER < 20071002
- const int se = 20;
+ const int se = 20;
#elif PACKETVER < 20100629
- const int se = 26;
+ const int se = 26;
#else
- const int se = 28;
+ const int se = 28;
#endif
- buf = (unsigned char *)aMalloc(MAX_INVENTORY * s + 4);
- bufe = (unsigned char *)aMalloc(MAX_INVENTORY * se + 4);
+ buf = (unsigned char*)aMalloc(MAX_INVENTORY * s + 4);
+ bufe = (unsigned char*)aMalloc(MAX_INVENTORY * se + 4);
- for (i = 0, n = 0, ne = 0; i < MAX_INVENTORY; i++) {
- if (sd->status.inventory[i].nameid <=0 || sd->inventory_data[i] == NULL)
- continue;
+ for( i = 0, n = 0, ne = 0; i < MAX_INVENTORY; i++ )
+ {
+ if( sd->status.inventory[i].nameid <=0 || sd->inventory_data[i] == NULL )
+ continue;
- if (!itemdb_isstackable2(sd->inventory_data[i])) {
- //Non-stackable (Equippable)
- WBUFW(bufe,ne*se+4)=i+2;
- clif_item_sub(bufe, ne*se+6, &sd->status.inventory[i], sd->inventory_data[i], pc_equippoint(sd,i));
- clif_addcards(WBUFP(bufe, ne*se+16), &sd->status.inventory[i]);
+ if( !itemdb_isstackable2(sd->inventory_data[i]) )
+ { //Non-stackable (Equippable)
+ WBUFW(bufe,ne*se+4)=i+2;
+ clif_item_sub(bufe, ne*se+6, &sd->status.inventory[i], sd->inventory_data[i], pc_equippoint(sd,i));
+ clif_addcards(WBUFP(bufe, ne*se+16), &sd->status.inventory[i]);
#if PACKETVER >= 20071002
- WBUFL(bufe,ne*se+24)=sd->status.inventory[i].expire_time;
- WBUFW(bufe,ne*se+28)=0; //Unknown
+ WBUFL(bufe,ne*se+24)=sd->status.inventory[i].expire_time;
+ WBUFW(bufe,ne*se+28)=0; //Unknown
#endif
#if PACKETVER >= 20100629
- if (sd->inventory_data[i]->equip&EQP_VISIBLE)
- WBUFW(bufe,ne*se+30)= sd->inventory_data[i]->look;
- else
- WBUFW(bufe,ne*se+30)=0;
+ if (sd->inventory_data[i]->equip&EQP_VISIBLE)
+ WBUFW(bufe,ne*se+30)= sd->inventory_data[i]->look;
+ else
+ WBUFW(bufe,ne*se+30)=0;
#endif
- ne++;
- } else {
- //Stackable.
- WBUFW(buf,n*s+4)=i+2;
- clif_item_sub(buf, n*s+6, &sd->status.inventory[i], sd->inventory_data[i], -2);
- if (sd->inventory_data[i]->equip == EQP_AMMO && sd->status.inventory[i].equip)
- arrow=i;
+ ne++;
+ }
+ else
+ { //Stackable.
+ WBUFW(buf,n*s+4)=i+2;
+ clif_item_sub(buf, n*s+6, &sd->status.inventory[i], sd->inventory_data[i], -2);
+ if( sd->inventory_data[i]->equip == EQP_AMMO && sd->status.inventory[i].equip )
+ arrow=i;
#if PACKETVER >= 5
- clif_addcards(WBUFP(buf, n*s+14), &sd->status.inventory[i]);
+ clif_addcards(WBUFP(buf, n*s+14), &sd->status.inventory[i]);
#endif
#if PACKETVER >= 20080102
- WBUFL(buf,n*s+22)=sd->status.inventory[i].expire_time;
+ WBUFL(buf,n*s+22)=sd->status.inventory[i].expire_time;
#endif
- n++;
- }
- }
- if (n) {
+ n++;
+ }
+ }
+ if( n )
+ {
#if PACKETVER < 5
- WBUFW(buf,0)=0xa3;
+ WBUFW(buf,0)=0xa3;
#elif PACKETVER < 20080102
- WBUFW(buf,0)=0x1ee;
+ WBUFW(buf,0)=0x1ee;
#else
- WBUFW(buf,0)=0x2e8;
+ WBUFW(buf,0)=0x2e8;
#endif
- WBUFW(buf,2)=4+n*s;
- clif_send(buf, WBUFW(buf,2), &sd->bl, SELF);
- }
- if (arrow >= 0)
- clif_arrowequip(sd,arrow);
-
- if (ne) {
+ WBUFW(buf,2)=4+n*s;
+ clif_send(buf, WBUFW(buf,2), &sd->bl, SELF);
+ }
+ if( arrow >= 0 )
+ clif_arrowequip(sd,arrow);
+
+ if( ne )
+ {
#if PACKETVER < 20071002
- WBUFW(bufe,0)=0xa4;
+ WBUFW(bufe,0)=0xa4;
#else
- WBUFW(bufe,0)=0x2d0;
+ WBUFW(bufe,0)=0x2d0;
#endif
- WBUFW(bufe,2)=4+ne*se;
- clif_send(bufe, WBUFW(bufe,2), &sd->bl, SELF);
- }
+ WBUFW(bufe,2)=4+ne*se;
+ clif_send(bufe, WBUFW(bufe,2), &sd->bl, SELF);
+ }
#if PACKETVER >= 20111122
- for (i = 0; i < MAX_INVENTORY; i++) {
- if (sd->status.inventory[i].nameid <= 0 || sd->inventory_data[i] == NULL)
- continue;
+ for( i = 0; i < MAX_INVENTORY; i++ ) {
+ if( sd->status.inventory[i].nameid <= 0 || sd->inventory_data[i] == NULL )
+ continue;
- if (sd->status.inventory[i].favorite)
- clif_favorite_item(sd, i);
- }
+ if ( sd->status.inventory[i].favorite )
+ clif_favorite_item(sd, i);
+ }
#endif
- if (buf) aFree(buf);
- if (bufe) aFree(bufe);
+ if( buf ) aFree(buf);
+ if( bufe ) aFree(bufe);
}
//Required when items break/get-repaired. Only sends equippable item list.
void clif_equiplist(struct map_session_data *sd)
{
- int i,n,fd = sd->fd;
- unsigned char *buf;
+ int i,n,fd = sd->fd;
+ unsigned char *buf;
#if PACKETVER < 20071002
- const int cmd = 20;
+ const int cmd = 20;
#elif PACKETVER < 20100629
- const int cmd = 26;
+ const int cmd = 26;
#else
- const int cmd = 28;
+ const int cmd = 28;
#endif
- WFIFOHEAD(fd, MAX_INVENTORY * cmd + 4);
- buf = WFIFOP(fd,0);
+ WFIFOHEAD(fd, MAX_INVENTORY * cmd + 4);
+ buf = WFIFOP(fd,0);
- for (i=0,n=0; i<MAX_INVENTORY; i++) {
- if (sd->status.inventory[i].nameid <=0 || sd->inventory_data[i] == NULL)
- continue;
+ for(i=0,n=0;i<MAX_INVENTORY;i++){
+ if (sd->status.inventory[i].nameid <=0 || sd->inventory_data[i] == NULL)
+ continue;
- if (itemdb_isstackable2(sd->inventory_data[i]))
- continue;
- //Equippable
- WBUFW(buf,n*cmd+4)=i+2;
- clif_item_sub(buf, n*cmd+6, &sd->status.inventory[i], sd->inventory_data[i], pc_equippoint(sd,i));
- clif_addcards(WBUFP(buf, n*cmd+16), &sd->status.inventory[i]);
+ if(itemdb_isstackable2(sd->inventory_data[i]))
+ continue;
+ //Equippable
+ WBUFW(buf,n*cmd+4)=i+2;
+ clif_item_sub(buf, n*cmd+6, &sd->status.inventory[i], sd->inventory_data[i], pc_equippoint(sd,i));
+ clif_addcards(WBUFP(buf, n*cmd+16), &sd->status.inventory[i]);
#if PACKETVER >= 20071002
- WBUFL(buf,n*cmd+24)=sd->status.inventory[i].expire_time;
- WBUFW(buf,n*cmd+28)=0; //Unknown
+ WBUFL(buf,n*cmd+24)=sd->status.inventory[i].expire_time;
+ WBUFW(buf,n*cmd+28)=0; //Unknown
#endif
#if PACKETVER >= 20100629
- if (sd->inventory_data[i]->equip&EQP_VISIBLE)
- WBUFW(buf,n*cmd+30)= sd->inventory_data[i]->look;
- else
- WBUFW(buf,n*cmd+30)=0;
+ if (sd->inventory_data[i]->equip&EQP_VISIBLE)
+ WBUFW(buf,n*cmd+30)= sd->inventory_data[i]->look;
+ else
+ WBUFW(buf,n*cmd+30)=0;
#endif
- n++;
- }
- if (n) {
+ n++;
+ }
+ if (n) {
#if PACKETVER < 20071002
- WBUFW(buf,0)=0xa4;
+ WBUFW(buf,0)=0xa4;
#else
- WBUFW(buf,0)=0x2d0;
+ WBUFW(buf,0)=0x2d0;
#endif
- WBUFW(buf,2)=4+n*cmd;
- WFIFOSET(fd,WFIFOW(fd,2));
- }
+ WBUFW(buf,2)=4+n*cmd;
+ WFIFOSET(fd,WFIFOW(fd,2));
+ }
}
-void clif_storagelist(struct map_session_data *sd, struct item *items, int items_length)
+void clif_storagelist(struct map_session_data* sd, struct item* items, int items_length)
{
- struct item_data *id;
- int i,n,ne;
- unsigned char *buf;
- unsigned char *bufe;
+ struct item_data *id;
+ int i,n,ne;
+ unsigned char *buf;
+ unsigned char *bufe;
#if PACKETVER < 5
- const int s = 10; //Entry size.
+ const int s = 10; //Entry size.
#elif PACKETVER < 20080102
- const int s = 18;
+ const int s = 18;
#else
- const int s = 22;
+ const int s = 22;
#endif
#if PACKETVER < 20071002
- const int cmd = 20;
+ const int cmd = 20;
#elif PACKETVER < 20100629
- const int cmd = 26;
+ const int cmd = 26;
#else
- const int cmd = 28;
+ const int cmd = 28;
#endif
- buf = (unsigned char *)aMalloc(items_length * s + 4);
- bufe = (unsigned char *)aMalloc(items_length * cmd + 4);
-
- for (i = 0, n = 0, ne = 0; i < items_length; i++) {
- if (items[i].nameid <= 0)
- continue;
- id = itemdb_search(items[i].nameid);
- if (!itemdb_isstackable2(id)) {
- //Equippable
- WBUFW(bufe,ne*cmd+4)=i+1;
- clif_item_sub(bufe, ne*cmd+6, &items[i], id, id->equip);
- clif_addcards(WBUFP(bufe, ne*cmd+16), &items[i]);
+ buf = (unsigned char*)aMalloc(items_length * s + 4);
+ bufe = (unsigned char*)aMalloc(items_length * cmd + 4);
+
+ for( i = 0, n = 0, ne = 0; i < items_length; i++ )
+ {
+ if( items[i].nameid <= 0 )
+ continue;
+ id = itemdb_search(items[i].nameid);
+ if( !itemdb_isstackable2(id) )
+ { //Equippable
+ WBUFW(bufe,ne*cmd+4)=i+1;
+ clif_item_sub(bufe, ne*cmd+6, &items[i], id, id->equip);
+ clif_addcards(WBUFP(bufe, ne*cmd+16), &items[i]);
#if PACKETVER >= 20071002
- WBUFL(bufe,ne*cmd+24)=items[i].expire_time;
- WBUFW(bufe,ne*cmd+28)=0; //Unknown
+ WBUFL(bufe,ne*cmd+24)=items[i].expire_time;
+ WBUFW(bufe,ne*cmd+28)=0; //Unknown
#endif
- ne++;
- } else {
- //Stackable
- WBUFW(buf,n*s+4)=i+1;
- clif_item_sub(buf, n*s+6, &items[i], id,-1);
+ ne++;
+ }
+ else
+ { //Stackable
+ WBUFW(buf,n*s+4)=i+1;
+ clif_item_sub(buf, n*s+6, &items[i], id,-1);
#if PACKETVER >= 5
- clif_addcards(WBUFP(buf,n*s+14), &items[i]);
+ clif_addcards(WBUFP(buf,n*s+14), &items[i]);
#endif
#if PACKETVER >= 20080102
- WBUFL(buf,n*s+22)=items[i].expire_time;
+ WBUFL(buf,n*s+22)=items[i].expire_time;
#endif
- n++;
- }
- }
- if (n) {
+ n++;
+ }
+ }
+ if( n )
+ {
#if PACKETVER < 5
- WBUFW(buf,0)=0xa5;
+ WBUFW(buf,0)=0xa5;
#elif PACKETVER < 20080102
- WBUFW(buf,0)=0x1f0;
+ WBUFW(buf,0)=0x1f0;
#else
- WBUFW(buf,0)=0x2ea;
+ WBUFW(buf,0)=0x2ea;
#endif
- WBUFW(buf,2)=4+n*s;
- clif_send(buf, WBUFW(buf,2), &sd->bl, SELF);
- }
- if (ne) {
+ WBUFW(buf,2)=4+n*s;
+ clif_send(buf, WBUFW(buf,2), &sd->bl, SELF);
+ }
+ if( ne )
+ {
#if PACKETVER < 20071002
- WBUFW(bufe,0)=0xa6;
+ WBUFW(bufe,0)=0xa6;
#else
- WBUFW(bufe,0)=0x2d1;
+ WBUFW(bufe,0)=0x2d1;
#endif
- WBUFW(bufe,2)=4+ne*cmd;
- clif_send(bufe, WBUFW(bufe,2), &sd->bl, SELF);
- }
+ WBUFW(bufe,2)=4+ne*cmd;
+ clif_send(bufe, WBUFW(bufe,2), &sd->bl, SELF);
+ }
- if (buf) aFree(buf);
- if (bufe) aFree(bufe);
+ if( buf ) aFree(buf);
+ if( bufe ) aFree(bufe);
}
void clif_cartlist(struct map_session_data *sd)
{
- struct item_data *id;
- int i,n,ne;
- unsigned char *buf;
- unsigned char *bufe;
+ struct item_data *id;
+ int i,n,ne;
+ unsigned char *buf;
+ unsigned char *bufe;
#if PACKETVER < 5
- const int s = 10; //Entry size.
+ const int s = 10; //Entry size.
#elif PACKETVER < 20080102
- const int s = 18;
+ const int s = 18;
#else
- const int s = 22;
+ const int s = 22;
#endif
#if PACKETVER < 20071002
- const int cmd = 20;
+ const int cmd = 20;
#elif PACKETVER < 20100629
- const int cmd = 26;
+ const int cmd = 26;
#else
- const int cmd = 28;
+ const int cmd = 28;
#endif
- buf = (unsigned char *)aMalloc(MAX_CART * s + 4);
- bufe = (unsigned char *)aMalloc(MAX_CART * cmd + 4);
-
- for (i = 0, n = 0, ne = 0; i < MAX_CART; i++) {
- if (sd->status.cart[i].nameid <= 0)
- continue;
- id = itemdb_search(sd->status.cart[i].nameid);
- if (!itemdb_isstackable2(id)) {
- //Equippable
- WBUFW(bufe,ne*cmd+4)=i+2;
- clif_item_sub(bufe, ne*cmd+6, &sd->status.cart[i], id, id->equip);
- clif_addcards(WBUFP(bufe, ne*cmd+16), &sd->status.cart[i]);
+ buf = (unsigned char*)aMalloc(MAX_CART * s + 4);
+ bufe = (unsigned char*)aMalloc(MAX_CART * cmd + 4);
+
+ for( i = 0, n = 0, ne = 0; i < MAX_CART; i++ )
+ {
+ if( sd->status.cart[i].nameid <= 0 )
+ continue;
+ id = itemdb_search(sd->status.cart[i].nameid);
+ if( !itemdb_isstackable2(id) )
+ { //Equippable
+ WBUFW(bufe,ne*cmd+4)=i+2;
+ clif_item_sub(bufe, ne*cmd+6, &sd->status.cart[i], id, id->equip);
+ clif_addcards(WBUFP(bufe, ne*cmd+16), &sd->status.cart[i]);
#if PACKETVER >= 20071002
- WBUFL(bufe,ne*cmd+24)=sd->status.cart[i].expire_time;
- WBUFW(bufe,ne*cmd+28)=0; //Unknown
+ WBUFL(bufe,ne*cmd+24)=sd->status.cart[i].expire_time;
+ WBUFW(bufe,ne*cmd+28)=0; //Unknown
#endif
- ne++;
- } else {
- //Stackable
- WBUFW(buf,n*s+4)=i+2;
- clif_item_sub(buf, n*s+6, &sd->status.cart[i], id,-1);
+ ne++;
+ }
+ else
+ { //Stackable
+ WBUFW(buf,n*s+4)=i+2;
+ clif_item_sub(buf, n*s+6, &sd->status.cart[i], id,-1);
#if PACKETVER >= 5
- clif_addcards(WBUFP(buf,n*s+14), &sd->status.cart[i]);
+ clif_addcards(WBUFP(buf,n*s+14), &sd->status.cart[i]);
#endif
#if PACKETVER >= 20080102
- WBUFL(buf,n*s+22)=sd->status.cart[i].expire_time;
+ WBUFL(buf,n*s+22)=sd->status.cart[i].expire_time;
#endif
- n++;
- }
- }
- if (n) {
+ n++;
+ }
+ }
+ if( n )
+ {
#if PACKETVER < 5
- WBUFW(buf,0)=0x123;
+ WBUFW(buf,0)=0x123;
#elif PACKETVER < 20080102
- WBUFW(buf,0)=0x1ef;
+ WBUFW(buf,0)=0x1ef;
#else
- WBUFW(buf,0)=0x2e9;
+ WBUFW(buf,0)=0x2e9;
#endif
- WBUFW(buf,2)=4+n*s;
- clif_send(buf, WBUFW(buf,2), &sd->bl, SELF);
- }
- if (ne) {
+ WBUFW(buf,2)=4+n*s;
+ clif_send(buf, WBUFW(buf,2), &sd->bl, SELF);
+ }
+ if( ne )
+ {
#if PACKETVER < 20071002
- WBUFW(bufe,0)=0x122;
+ WBUFW(bufe,0)=0x122;
#else
- WBUFW(bufe,0)=0x2d2;
+ WBUFW(bufe,0)=0x2d2;
#endif
- WBUFW(bufe,2)=4+ne*cmd;
- clif_send(bufe, WBUFW(bufe,2), &sd->bl, SELF);
- }
+ WBUFW(bufe,2)=4+ne*cmd;
+ clif_send(bufe, WBUFW(bufe,2), &sd->bl, SELF);
+ }
- if (buf) aFree(buf);
- if (bufe) aFree(bufe);
+ if( buf ) aFree(buf);
+ if( bufe ) aFree(bufe);
}
@@ -2575,9 +2612,9 @@ void clif_cartlist(struct map_session_data *sd)
/// The Num & Weight values of the cart are left untouched and the cart is NOT removed.
void clif_clearcart(int fd)
{
- WFIFOHEAD(fd, packet_len(0x12b));
- WFIFOW(fd,0) = 0x12b;
- WFIFOSET(fd, packet_len(0x12b));
+ WFIFOHEAD(fd, packet_len(0x12b));
+ WFIFOW(fd,0) = 0x12b;
+ WFIFOSET(fd, packet_len(0x12b));
}
@@ -2586,15 +2623,15 @@ void clif_clearcart(int fd)
/// 01eb <account id>.L <x>.W <y>.W
void clif_guild_xy(struct map_session_data *sd)
{
- unsigned char buf[10];
+ unsigned char buf[10];
- nullpo_retv(sd);
+ nullpo_retv(sd);
- WBUFW(buf,0)=0x1eb;
- WBUFL(buf,2)=sd->status.account_id;
- WBUFW(buf,6)=sd->bl.x;
- WBUFW(buf,8)=sd->bl.y;
- clif_send(buf,packet_len(0x1eb),&sd->bl,GUILD_SAMEMAP_WOS);
+ WBUFW(buf,0)=0x1eb;
+ WBUFL(buf,2)=sd->status.account_id;
+ WBUFW(buf,6)=sd->bl.x;
+ WBUFW(buf,8)=sd->bl.y;
+ clif_send(buf,packet_len(0x1eb),&sd->bl,GUILD_SAMEMAP_WOS);
}
/*==========================================
@@ -2602,29 +2639,29 @@ void clif_guild_xy(struct map_session_data *sd)
*------------------------------------------*/
void clif_guild_xy_single(int fd, struct map_session_data *sd)
{
- if (sd->bg_id)
- return;
+ if( sd->bg_id )
+ return;
- WFIFOHEAD(fd,packet_len(0x1eb));
- WFIFOW(fd,0)=0x1eb;
- WFIFOL(fd,2)=sd->status.account_id;
- WFIFOW(fd,6)=sd->bl.x;
- WFIFOW(fd,8)=sd->bl.y;
- WFIFOSET(fd,packet_len(0x1eb));
+ WFIFOHEAD(fd,packet_len(0x1eb));
+ WFIFOW(fd,0)=0x1eb;
+ WFIFOL(fd,2)=sd->status.account_id;
+ WFIFOW(fd,6)=sd->bl.x;
+ WFIFOW(fd,8)=sd->bl.y;
+ WFIFOSET(fd,packet_len(0x1eb));
}
// Guild XY locators [Valaris]
void clif_guild_xy_remove(struct map_session_data *sd)
{
- unsigned char buf[10];
+ unsigned char buf[10];
- nullpo_retv(sd);
+ nullpo_retv(sd);
- WBUFW(buf,0)=0x1eb;
- WBUFL(buf,2)=sd->status.account_id;
- WBUFW(buf,6)=-1;
- WBUFW(buf,8)=-1;
- clif_send(buf,packet_len(0x1eb),&sd->bl,GUILD_SAMEMAP_WOS);
+ WBUFW(buf,0)=0x1eb;
+ WBUFL(buf,2)=sd->status.account_id;
+ WBUFW(buf,6)=-1;
+ WBUFW(buf,8)=-1;
+ clif_send(buf,packet_len(0x1eb),&sd->bl,GUILD_SAMEMAP_WOS);
}
/*==========================================
@@ -2632,42 +2669,42 @@ void clif_guild_xy_remove(struct map_session_data *sd)
*------------------------------------------*/
static int clif_hpmeter_sub(struct block_list *bl, va_list ap)
{
- struct map_session_data *sd, *tsd;
+ struct map_session_data *sd, *tsd;
#if PACKETVER < 20100126
- const int cmd = 0x106;
+ const int cmd = 0x106;
#else
- const int cmd = 0x80e;
+ const int cmd = 0x80e;
#endif
- sd = va_arg(ap, struct map_session_data *);
- tsd = (TBL_PC *)bl;
+ sd = va_arg(ap, struct map_session_data *);
+ tsd = (TBL_PC *)bl;
- nullpo_ret(sd);
- nullpo_ret(tsd);
+ nullpo_ret(sd);
+ nullpo_ret(tsd);
- if (!tsd->fd || tsd == sd)
- return 0;
+ if( !tsd->fd || tsd == sd )
+ return 0;
- if (!pc_has_permission(tsd, PC_PERM_VIEW_HPMETER))
- return 0;
- WFIFOHEAD(tsd->fd,packet_len(cmd));
- WFIFOW(tsd->fd,0) = cmd;
- WFIFOL(tsd->fd,2) = sd->status.account_id;
+ if( !pc_has_permission(tsd, PC_PERM_VIEW_HPMETER) )
+ return 0;
+ WFIFOHEAD(tsd->fd,packet_len(cmd));
+ WFIFOW(tsd->fd,0) = cmd;
+ WFIFOL(tsd->fd,2) = sd->status.account_id;
#if PACKETVER < 20100126
- if (sd->battle_status.max_hp > INT16_MAX) {
- //To correctly display the %hp bar. [Skotlex]
- WFIFOW(tsd->fd,6) = sd->battle_status.hp/(sd->battle_status.max_hp/100);
- WFIFOW(tsd->fd,8) = 100;
- } else {
- WFIFOW(tsd->fd,6) = sd->battle_status.hp;
- WFIFOW(tsd->fd,8) = sd->battle_status.max_hp;
- }
+ if( sd->battle_status.max_hp > INT16_MAX )
+ { //To correctly display the %hp bar. [Skotlex]
+ WFIFOW(tsd->fd,6) = sd->battle_status.hp/(sd->battle_status.max_hp/100);
+ WFIFOW(tsd->fd,8) = 100;
+ } else {
+ WFIFOW(tsd->fd,6) = sd->battle_status.hp;
+ WFIFOW(tsd->fd,8) = sd->battle_status.max_hp;
+ }
#else
- WFIFOL(tsd->fd,6) = sd->battle_status.hp;
- WFIFOL(tsd->fd,10) = sd->battle_status.max_hp;
+ WFIFOL(tsd->fd,6) = sd->battle_status.hp;
+ WFIFOL(tsd->fd,10) = sd->battle_status.max_hp;
#endif
- WFIFOSET(tsd->fd,packet_len(cmd));
- return 0;
+ WFIFOSET(tsd->fd,packet_len(cmd));
+ return 0;
}
/*==========================================
@@ -2676,9 +2713,9 @@ static int clif_hpmeter_sub(struct block_list *bl, va_list ap)
*------------------------------------------*/
static int clif_hpmeter(struct map_session_data *sd)
{
- nullpo_ret(sd);
- map_foreachinarea(clif_hpmeter_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_PC, sd);
- return 0;
+ nullpo_ret(sd);
+ map_foreachinarea(clif_hpmeter_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_PC, sd);
+ return 0;
}
/// Notifies client of a character parameter change.
@@ -2692,245 +2729,246 @@ static int clif_hpmeter(struct map_session_data *sd)
/// FIXME: Packet lengths from packet_len(cmd)
void clif_updatestatus(struct map_session_data *sd,int type)
{
- int fd,len=8;
-
- nullpo_retv(sd);
-
- fd=sd->fd;
-
- if (!session_isActive(fd)) // Invalid pointer fix, by sasuke [Kevin]
- return;
-
- WFIFOHEAD(fd, 14);
- WFIFOW(fd,0)=0xb0;
- WFIFOW(fd,2)=type;
- switch (type) {
- // 00b0
- case SP_WEIGHT:
- pc_updateweightstatus(sd);
- WFIFOHEAD(fd,14);
- WFIFOW(fd,0)=0xb0; //Need to re-set as pc_updateweightstatus can alter the buffer. [Skotlex]
- WFIFOW(fd,2)=type;
- WFIFOL(fd,4)=sd->weight;
- break;
- case SP_MAXWEIGHT:
- WFIFOL(fd,4)=sd->max_weight;
- break;
- case SP_SPEED:
- WFIFOL(fd,4)=sd->battle_status.speed;
- break;
- case SP_BASELEVEL:
- WFIFOL(fd,4)=sd->status.base_level;
- break;
- case SP_JOBLEVEL:
- WFIFOL(fd,4)=sd->status.job_level;
- break;
- case SP_KARMA: // Adding this back, I wonder if the client intercepts this - [Lance]
- WFIFOL(fd,4)=sd->status.karma;
- break;
- case SP_MANNER:
- WFIFOL(fd,4)=sd->status.manner;
- break;
- case SP_STATUSPOINT:
- WFIFOL(fd,4)=sd->status.status_point;
- break;
- case SP_SKILLPOINT:
- WFIFOL(fd,4)=sd->status.skill_point;
- break;
- case SP_HIT:
- WFIFOL(fd,4)=sd->battle_status.hit;
- break;
- case SP_FLEE1:
- WFIFOL(fd,4)=sd->battle_status.flee;
- break;
- case SP_FLEE2:
- WFIFOL(fd,4)=sd->battle_status.flee2/10;
- break;
- case SP_MAXHP:
- WFIFOL(fd,4)=sd->battle_status.max_hp;
- break;
- case SP_MAXSP:
- WFIFOL(fd,4)=sd->battle_status.max_sp;
- break;
- case SP_HP:
- WFIFOL(fd,4)=sd->battle_status.hp;
- // TODO: Won't these overwrite the current packet?
- clif_hpmeter(sd);
- if (!battle_config.party_hp_mode && sd->status.party_id)
- clif_party_hp(sd);
- if (sd->bg_id)
- clif_bg_hp(sd);
- break;
- case SP_SP:
- WFIFOL(fd,4)=sd->battle_status.sp;
- break;
- case SP_ASPD:
- WFIFOL(fd,4)=sd->battle_status.amotion;
- break;
- case SP_ATK1:
- WFIFOL(fd,4)=pc_leftside_atk(sd);
- break;
- case SP_DEF1:
- WFIFOL(fd,4)=pc_leftside_def(sd);
- break;
- case SP_MDEF1:
- WFIFOL(fd,4)=pc_leftside_mdef(sd);
- break;
- case SP_ATK2:
- WFIFOL(fd,4)=pc_rightside_atk(sd);
- break;
- case SP_DEF2:
- WFIFOL(fd,4)=pc_rightside_def(sd);
- break;
- case SP_MDEF2: {
- //negative check (in case you have something like Berserk active)
- int mdef2 = pc_rightside_mdef(sd);
-
- WFIFOL(fd,4)=
+ int fd,len=8;
+
+ nullpo_retv(sd);
+
+ fd=sd->fd;
+
+ if ( !session_isActive(fd) ) // Invalid pointer fix, by sasuke [Kevin]
+ return;
+
+ WFIFOHEAD(fd, 14);
+ WFIFOW(fd,0)=0xb0;
+ WFIFOW(fd,2)=type;
+ switch(type){
+ // 00b0
+ case SP_WEIGHT:
+ pc_updateweightstatus(sd);
+ WFIFOHEAD(fd,14);
+ WFIFOW(fd,0)=0xb0; //Need to re-set as pc_updateweightstatus can alter the buffer. [Skotlex]
+ WFIFOW(fd,2)=type;
+ WFIFOL(fd,4)=sd->weight;
+ break;
+ case SP_MAXWEIGHT:
+ WFIFOL(fd,4)=sd->max_weight;
+ break;
+ case SP_SPEED:
+ WFIFOL(fd,4)=sd->battle_status.speed;
+ break;
+ case SP_BASELEVEL:
+ WFIFOL(fd,4)=sd->status.base_level;
+ break;
+ case SP_JOBLEVEL:
+ WFIFOL(fd,4)=sd->status.job_level;
+ break;
+ case SP_KARMA: // Adding this back, I wonder if the client intercepts this - [Lance]
+ WFIFOL(fd,4)=sd->status.karma;
+ break;
+ case SP_MANNER:
+ WFIFOL(fd,4)=sd->status.manner;
+ break;
+ case SP_STATUSPOINT:
+ WFIFOL(fd,4)=sd->status.status_point;
+ break;
+ case SP_SKILLPOINT:
+ WFIFOL(fd,4)=sd->status.skill_point;
+ break;
+ case SP_HIT:
+ WFIFOL(fd,4)=sd->battle_status.hit;
+ break;
+ case SP_FLEE1:
+ WFIFOL(fd,4)=sd->battle_status.flee;
+ break;
+ case SP_FLEE2:
+ WFIFOL(fd,4)=sd->battle_status.flee2/10;
+ break;
+ case SP_MAXHP:
+ WFIFOL(fd,4)=sd->battle_status.max_hp;
+ break;
+ case SP_MAXSP:
+ WFIFOL(fd,4)=sd->battle_status.max_sp;
+ break;
+ case SP_HP:
+ WFIFOL(fd,4)=sd->battle_status.hp;
+ // TODO: Won't these overwrite the current packet?
+ clif_hpmeter(sd);
+ if( !battle_config.party_hp_mode && sd->status.party_id )
+ clif_party_hp(sd);
+ if( sd->bg_id )
+ clif_bg_hp(sd);
+ break;
+ case SP_SP:
+ WFIFOL(fd,4)=sd->battle_status.sp;
+ break;
+ case SP_ASPD:
+ WFIFOL(fd,4)=sd->battle_status.amotion;
+ break;
+ case SP_ATK1:
+ WFIFOL(fd,4)=pc_leftside_atk(sd);
+ break;
+ case SP_DEF1:
+ WFIFOL(fd,4)=pc_leftside_def(sd);
+ break;
+ case SP_MDEF1:
+ WFIFOL(fd,4)=pc_leftside_mdef(sd);
+ break;
+ case SP_ATK2:
+ WFIFOL(fd,4)=pc_rightside_atk(sd);
+ break;
+ case SP_DEF2:
+ WFIFOL(fd,4)=pc_rightside_def(sd);
+ break;
+ case SP_MDEF2: {
+ //negative check (in case you have something like Berserk active)
+ int mdef2 = pc_rightside_mdef(sd);
+
+ WFIFOL(fd,4)=
#ifndef RENEWAL
- (mdef2 < 0) ? 0 :
+ ( mdef2 < 0 ) ? 0 :
#endif
- mdef2;
-
- }
- break;
- case SP_CRITICAL:
- WFIFOL(fd,4)=sd->battle_status.cri/10;
- break;
- case SP_MATK1:
- WFIFOL(fd,4)=pc_rightside_matk(sd);
- break;
- case SP_MATK2:
- WFIFOL(fd,4)=pc_leftside_matk(sd);
- break;
-
-
- case SP_ZENY:
- WFIFOW(fd,0)=0xb1;
- WFIFOL(fd,4)=sd->status.zeny;
- break;
- case SP_BASEEXP:
- WFIFOW(fd,0)=0xb1;
- WFIFOL(fd,4)=sd->status.base_exp;
- break;
- case SP_JOBEXP:
- WFIFOW(fd,0)=0xb1;
- WFIFOL(fd,4)=sd->status.job_exp;
- break;
- case SP_NEXTBASEEXP:
- WFIFOW(fd,0)=0xb1;
- WFIFOL(fd,4)=pc_nextbaseexp(sd);
- break;
- case SP_NEXTJOBEXP:
- WFIFOW(fd,0)=0xb1;
- WFIFOL(fd,4)=pc_nextjobexp(sd);
- break;
-
- /**
- * SP_U<STAT> are used to update the amount of points necessary to increase that stat
- **/
- case SP_USTR:
- case SP_UAGI:
- case SP_UVIT:
- case SP_UINT:
- case SP_UDEX:
- case SP_ULUK:
- WFIFOW(fd,0)=0xbe;
- WFIFOB(fd,4)=pc_need_status_point(sd,type-SP_USTR+SP_STR,1);
- len=5;
- break;
-
- /**
- * Tells the client how far it is allowed to attack (weapon range)
- **/
- case SP_ATTACKRANGE:
- WFIFOW(fd,0)=0x13a;
- WFIFOW(fd,2)=sd->battle_status.rhw.range;
- len=4;
- break;
-
- case SP_STR:
- WFIFOW(fd,0)=0x141;
- WFIFOL(fd,2)=type;
- WFIFOL(fd,6)=sd->status.str;
- WFIFOL(fd,10)=sd->battle_status.str - sd->status.str;
- len=14;
- break;
- case SP_AGI:
- WFIFOW(fd,0)=0x141;
- WFIFOL(fd,2)=type;
- WFIFOL(fd,6)=sd->status.agi;
- WFIFOL(fd,10)=sd->battle_status.agi - sd->status.agi;
- len=14;
- break;
- case SP_VIT:
- WFIFOW(fd,0)=0x141;
- WFIFOL(fd,2)=type;
- WFIFOL(fd,6)=sd->status.vit;
- WFIFOL(fd,10)=sd->battle_status.vit - sd->status.vit;
- len=14;
- break;
- case SP_INT:
- WFIFOW(fd,0)=0x141;
- WFIFOL(fd,2)=type;
- WFIFOL(fd,6)=sd->status.int_;
- WFIFOL(fd,10)=sd->battle_status.int_ - sd->status.int_;
- len=14;
- break;
- case SP_DEX:
- WFIFOW(fd,0)=0x141;
- WFIFOL(fd,2)=type;
- WFIFOL(fd,6)=sd->status.dex;
- WFIFOL(fd,10)=sd->battle_status.dex - sd->status.dex;
- len=14;
- break;
- case SP_LUK:
- WFIFOW(fd,0)=0x141;
- WFIFOL(fd,2)=type;
- WFIFOL(fd,6)=sd->status.luk;
- WFIFOL(fd,10)=sd->battle_status.luk - sd->status.luk;
- len=14;
- break;
-
- case SP_CARTINFO:
- WFIFOW(fd,0)=0x121;
- WFIFOW(fd,2)=sd->cart_num;
- WFIFOW(fd,4)=MAX_CART;
- WFIFOL(fd,6)=sd->cart_weight;
- WFIFOL(fd,10)=sd->cart_weight_max;
- len=14;
- break;
-
- default:
- ShowError("clif_updatestatus : unrecognized type %d\n",type);
- return;
- }
- WFIFOSET(fd,len);
+ mdef2;
+
+ }
+ break;
+ case SP_CRITICAL:
+ WFIFOL(fd,4)=sd->battle_status.cri/10;
+ break;
+ case SP_MATK1:
+ WFIFOL(fd,4)=sd->battle_status.matk_max;
+ break;
+ case SP_MATK2:
+ WFIFOL(fd,4)=sd->battle_status.matk_min;
+ break;
+
+
+ case SP_ZENY:
+ WFIFOW(fd,0)=0xb1;
+ WFIFOL(fd,4)=sd->status.zeny;
+ break;
+ case SP_BASEEXP:
+ WFIFOW(fd,0)=0xb1;
+ WFIFOL(fd,4)=sd->status.base_exp;
+ break;
+ case SP_JOBEXP:
+ WFIFOW(fd,0)=0xb1;
+ WFIFOL(fd,4)=sd->status.job_exp;
+ break;
+ case SP_NEXTBASEEXP:
+ WFIFOW(fd,0)=0xb1;
+ WFIFOL(fd,4)=pc_nextbaseexp(sd);
+ break;
+ case SP_NEXTJOBEXP:
+ WFIFOW(fd,0)=0xb1;
+ WFIFOL(fd,4)=pc_nextjobexp(sd);
+ break;
+
+ /**
+ * SP_U<STAT> are used to update the amount of points necessary to increase that stat
+ **/
+ case SP_USTR:
+ case SP_UAGI:
+ case SP_UVIT:
+ case SP_UINT:
+ case SP_UDEX:
+ case SP_ULUK:
+ WFIFOW(fd,0)=0xbe;
+ WFIFOB(fd,4)=pc_need_status_point(sd,type-SP_USTR+SP_STR,1);
+ len=5;
+ break;
+
+ /**
+ * Tells the client how far it is allowed to attack (weapon range)
+ **/
+ case SP_ATTACKRANGE:
+ WFIFOW(fd,0)=0x13a;
+ WFIFOW(fd,2)=sd->battle_status.rhw.range;
+ len=4;
+ break;
+
+ case SP_STR:
+ WFIFOW(fd,0)=0x141;
+ WFIFOL(fd,2)=type;
+ WFIFOL(fd,6)=sd->status.str;
+ WFIFOL(fd,10)=sd->battle_status.str - sd->status.str;
+ len=14;
+ break;
+ case SP_AGI:
+ WFIFOW(fd,0)=0x141;
+ WFIFOL(fd,2)=type;
+ WFIFOL(fd,6)=sd->status.agi;
+ WFIFOL(fd,10)=sd->battle_status.agi - sd->status.agi;
+ len=14;
+ break;
+ case SP_VIT:
+ WFIFOW(fd,0)=0x141;
+ WFIFOL(fd,2)=type;
+ WFIFOL(fd,6)=sd->status.vit;
+ WFIFOL(fd,10)=sd->battle_status.vit - sd->status.vit;
+ len=14;
+ break;
+ case SP_INT:
+ WFIFOW(fd,0)=0x141;
+ WFIFOL(fd,2)=type;
+ WFIFOL(fd,6)=sd->status.int_;
+ WFIFOL(fd,10)=sd->battle_status.int_ - sd->status.int_;
+ len=14;
+ break;
+ case SP_DEX:
+ WFIFOW(fd,0)=0x141;
+ WFIFOL(fd,2)=type;
+ WFIFOL(fd,6)=sd->status.dex;
+ WFIFOL(fd,10)=sd->battle_status.dex - sd->status.dex;
+ len=14;
+ break;
+ case SP_LUK:
+ WFIFOW(fd,0)=0x141;
+ WFIFOL(fd,2)=type;
+ WFIFOL(fd,6)=sd->status.luk;
+ WFIFOL(fd,10)=sd->battle_status.luk - sd->status.luk;
+ len=14;
+ break;
+
+ case SP_CARTINFO:
+ WFIFOW(fd,0)=0x121;
+ WFIFOW(fd,2)=sd->cart_num;
+ WFIFOW(fd,4)=MAX_CART;
+ WFIFOL(fd,6)=sd->cart_weight;
+ WFIFOL(fd,10)=sd->cart_weight_max;
+ len=14;
+ break;
+
+ default:
+ ShowError("clif_updatestatus : unrecognized type %d\n",type);
+ return;
+ }
+ WFIFOSET(fd,len);
}
/// Notifies client of a parameter change of an another player (ZC_PAR_CHANGE_USER).
/// 01ab <account id>.L <var id>.W <value>.L
-void clif_changestatus(struct map_session_data *sd,int type,int val)
+void clif_changestatus(struct map_session_data* sd,int type,int val)
{
- unsigned char buf[12];
+ unsigned char buf[12];
- nullpo_retv(sd);
+ nullpo_retv(sd);
- WBUFW(buf,0)=0x1ab;
- WBUFL(buf,2)=sd->bl.id;
- WBUFW(buf,6)=type;
+ WBUFW(buf,0)=0x1ab;
+ WBUFL(buf,2)=sd->bl.id;
+ WBUFW(buf,6)=type;
- switch (type) {
- case SP_MANNER:
- WBUFL(buf,8)=val;
- break;
- default:
- ShowError("clif_changestatus : unrecognized type %d.\n",type);
- return;
- }
+ switch(type)
+ {
+ case SP_MANNER:
+ WBUFL(buf,8)=val;
+ break;
+ default:
+ ShowError("clif_changestatus : unrecognized type %d.\n",type);
+ return;
+ }
- clif_send(buf,packet_len(0x1ab),&sd->bl,AREA_WOS);
+ clif_send(buf,packet_len(0x1ab),&sd->bl,AREA_WOS);
}
@@ -2939,156 +2977,161 @@ void clif_changestatus(struct map_session_data *sd,int type,int val)
/// 01d7 <id>.L <type>.B <value>.L (ZC_SPRITE_CHANGE2)
void clif_changelook(struct block_list *bl,int type,int val)
{
- unsigned char buf[16];
- struct map_session_data *sd = NULL;
- struct status_change *sc;
- struct view_data *vd;
- enum send_target target = AREA;
- nullpo_retv(bl);
-
- sd = BL_CAST(BL_PC, bl);
- sc = status_get_sc(bl);
- vd = status_get_viewdata(bl);
- //nullpo_ret(vd);
- if (vd) //temp hack to let Warp Portal change appearance
- switch (type) {
- case LOOK_WEAPON:
- if (sd) {
- clif_get_weapon_view(sd, &vd->weapon, &vd->shield);
- val = vd->weapon;
- } else vd->weapon = val;
- break;
- case LOOK_SHIELD:
- if (sd) {
- clif_get_weapon_view(sd, &vd->weapon, &vd->shield);
- val = vd->shield;
- } else vd->shield = val;
- break;
- case LOOK_BASE:
- vd->class_ = val;
- if (vd->class_ == JOB_WEDDING || vd->class_ == JOB_XMAS || vd->class_ == JOB_SUMMER)
- vd->weapon = vd->shield = 0;
- if (vd->cloth_color && (
- (vd->class_ == JOB_WEDDING && battle_config.wedding_ignorepalette) ||
- (vd->class_ == JOB_XMAS && battle_config.xmas_ignorepalette) ||
- (vd->class_ == JOB_SUMMER && battle_config.summer_ignorepalette)
- ))
- clif_changelook(bl,LOOK_CLOTHES_COLOR,0);
- break;
- case LOOK_HAIR:
- vd->hair_style = val;
- break;
- case LOOK_HEAD_BOTTOM:
- vd->head_bottom = val;
- break;
- case LOOK_HEAD_TOP:
- vd->head_top = val;
- break;
- case LOOK_HEAD_MID:
- vd->head_mid = val;
- break;
- case LOOK_HAIR_COLOR:
- vd->hair_color = val;
- break;
- case LOOK_CLOTHES_COLOR:
- if (val && (
- (vd->class_ == JOB_WEDDING && battle_config.wedding_ignorepalette) ||
- (vd->class_ == JOB_XMAS && battle_config.xmas_ignorepalette) ||
- (vd->class_ == JOB_SUMMER && battle_config.summer_ignorepalette)
- ))
- val = 0;
- vd->cloth_color = val;
- break;
- case LOOK_SHOES:
+ unsigned char buf[16];
+ struct map_session_data* sd = NULL;
+ struct status_change* sc;
+ struct view_data* vd;
+ enum send_target target = AREA;
+ nullpo_retv(bl);
+
+ sd = BL_CAST(BL_PC, bl);
+ sc = status_get_sc(bl);
+ vd = status_get_viewdata(bl);
+ //nullpo_ret(vd);
+ if( vd ) //temp hack to let Warp Portal change appearance
+ switch(type)
+ {
+ case LOOK_WEAPON:
+ if (sd)
+ {
+ clif_get_weapon_view(sd, &vd->weapon, &vd->shield);
+ val = vd->weapon;
+ }
+ else vd->weapon = val;
+ break;
+ case LOOK_SHIELD:
+ if (sd)
+ {
+ clif_get_weapon_view(sd, &vd->weapon, &vd->shield);
+ val = vd->shield;
+ }
+ else vd->shield = val;
+ break;
+ case LOOK_BASE:
+ vd->class_ = val;
+ if (vd->class_ == JOB_WEDDING || vd->class_ == JOB_XMAS || vd->class_ == JOB_SUMMER)
+ vd->weapon = vd->shield = 0;
+ if (vd->cloth_color && (
+ (vd->class_ == JOB_WEDDING && battle_config.wedding_ignorepalette) ||
+ (vd->class_ == JOB_XMAS && battle_config.xmas_ignorepalette) ||
+ (vd->class_ == JOB_SUMMER && battle_config.summer_ignorepalette)
+ ))
+ clif_changelook(bl,LOOK_CLOTHES_COLOR,0);
+ break;
+ case LOOK_HAIR:
+ vd->hair_style = val;
+ break;
+ case LOOK_HEAD_BOTTOM:
+ vd->head_bottom = val;
+ break;
+ case LOOK_HEAD_TOP:
+ vd->head_top = val;
+ break;
+ case LOOK_HEAD_MID:
+ vd->head_mid = val;
+ break;
+ case LOOK_HAIR_COLOR:
+ vd->hair_color = val;
+ break;
+ case LOOK_CLOTHES_COLOR:
+ if (val && (
+ (vd->class_ == JOB_WEDDING && battle_config.wedding_ignorepalette) ||
+ (vd->class_ == JOB_XMAS && battle_config.xmas_ignorepalette) ||
+ (vd->class_ == JOB_SUMMER && battle_config.summer_ignorepalette)
+ ))
+ val = 0;
+ vd->cloth_color = val;
+ break;
+ case LOOK_SHOES:
#if PACKETVER > 3
- if (sd) {
- int n;
- if ((n = sd->equip_index[2]) >= 0 && sd->inventory_data[n]) {
- if (sd->inventory_data[n]->view_id > 0)
- val = sd->inventory_data[n]->view_id;
- else
- val = sd->status.inventory[n].nameid;
- } else
- val = 0;
- }
+ if (sd) {
+ int n;
+ if((n = sd->equip_index[2]) >= 0 && sd->inventory_data[n]) {
+ if(sd->inventory_data[n]->view_id > 0)
+ val = sd->inventory_data[n]->view_id;
+ else
+ val = sd->status.inventory[n].nameid;
+ } else
+ val = 0;
+ }
#endif
- //Shoes? No packet uses this....
- break;
- case LOOK_BODY:
- case LOOK_FLOOR:
- // unknown purpose
- break;
- case LOOK_ROBE:
+ //Shoes? No packet uses this....
+ break;
+ case LOOK_BODY:
+ case LOOK_FLOOR:
+ // unknown purpose
+ break;
+ case LOOK_ROBE:
#if PACKETVER < 20110111
- return;
+ return;
#else
- vd->robe = val;
+ vd->robe = val;
#endif
- break;
- }
+ break;
+ }
- // prevent leaking the presence of GM-hidden objects
- if (sc && sc->option&OPTION_INVISIBLE)
- target = SELF;
+ // prevent leaking the presence of GM-hidden objects
+ if( sc && sc->option&OPTION_INVISIBLE )
+ target = SELF;
#if PACKETVER < 4
- WBUFW(buf,0)=0xc3;
- WBUFL(buf,2)=bl->id;
- WBUFB(buf,6)=type;
- WBUFB(buf,7)=val;
- clif_send(buf,packet_len(0xc3),bl,target);
+ WBUFW(buf,0)=0xc3;
+ WBUFL(buf,2)=bl->id;
+ WBUFB(buf,6)=type;
+ WBUFB(buf,7)=val;
+ clif_send(buf,packet_len(0xc3),bl,target);
#else
- WBUFW(buf,0)=0x1d7;
- WBUFL(buf,2)=bl->id;
- if (type == LOOK_WEAPON || type == LOOK_SHIELD) {
- WBUFB(buf,6)=LOOK_WEAPON;
- WBUFW(buf,7)=vd->weapon;
- WBUFW(buf,9)=vd->shield;
- } else {
- WBUFB(buf,6)=type;
- WBUFL(buf,7)=val;
- }
- clif_send(buf,packet_len(0x1d7),bl,target);
+ WBUFW(buf,0)=0x1d7;
+ WBUFL(buf,2)=bl->id;
+ if(type == LOOK_WEAPON || type == LOOK_SHIELD) {
+ WBUFB(buf,6)=LOOK_WEAPON;
+ WBUFW(buf,7)=vd->weapon;
+ WBUFW(buf,9)=vd->shield;
+ } else {
+ WBUFB(buf,6)=type;
+ WBUFL(buf,7)=val;
+ }
+ clif_send(buf,packet_len(0x1d7),bl,target);
#endif
}
//Sends a change-base-look packet required for traps as they are triggered.
void clif_changetraplook(struct block_list *bl,int val)
{
- unsigned char buf[32];
+ unsigned char buf[32];
#if PACKETVER < 4
- WBUFW(buf,0)=0xc3;
- WBUFL(buf,2)=bl->id;
- WBUFB(buf,6)=LOOK_BASE;
- WBUFB(buf,7)=val;
- clif_send(buf,packet_len(0xc3),bl,AREA);
+ WBUFW(buf,0)=0xc3;
+ WBUFL(buf,2)=bl->id;
+ WBUFB(buf,6)=LOOK_BASE;
+ WBUFB(buf,7)=val;
+ clif_send(buf,packet_len(0xc3),bl,AREA);
#else
- WBUFW(buf,0)=0x1d7;
- WBUFL(buf,2)=bl->id;
- WBUFB(buf,6)=LOOK_BASE;
- WBUFW(buf,7)=val;
- WBUFW(buf,9)=0;
- clif_send(buf,packet_len(0x1d7),bl,AREA);
+ WBUFW(buf,0)=0x1d7;
+ WBUFL(buf,2)=bl->id;
+ WBUFB(buf,6)=LOOK_BASE;
+ WBUFW(buf,7)=val;
+ WBUFW(buf,9)=0;
+ clif_send(buf,packet_len(0x1d7),bl,AREA);
#endif
}
//For the stupid cloth-dye bug. Resends the given view data to the area specified by bl.
void clif_refreshlook(struct block_list *bl,int id,int type,int val,enum send_target target)
{
- unsigned char buf[32];
+ unsigned char buf[32];
#if PACKETVER < 4
- WBUFW(buf,0)=0xc3;
- WBUFL(buf,2)=id;
- WBUFB(buf,6)=type;
- WBUFB(buf,7)=val;
- clif_send(buf,packet_len(0xc3),bl,target);
+ WBUFW(buf,0)=0xc3;
+ WBUFL(buf,2)=id;
+ WBUFB(buf,6)=type;
+ WBUFB(buf,7)=val;
+ clif_send(buf,packet_len(0xc3),bl,target);
#else
- WBUFW(buf,0)=0x1d7;
- WBUFL(buf,2)=id;
- WBUFB(buf,6)=type;
- WBUFW(buf,7)=val;
- WBUFW(buf,9)=0;
- clif_send(buf,packet_len(0x1d7),bl,target);
+ WBUFW(buf,0)=0x1d7;
+ WBUFL(buf,2)=id;
+ WBUFB(buf,6)=type;
+ WBUFW(buf,7)=val;
+ WBUFW(buf,9)=0;
+ clif_send(buf,packet_len(0x1d7),bl,target);
#endif
}
@@ -3100,61 +3143,61 @@ void clif_refreshlook(struct block_list *bl,int id,int type,int val,enum send_ta
/// <flee>.W <flee2>.W <crit>.W <aspd>.W <aspd2>.W
void clif_initialstatus(struct map_session_data *sd)
{
- int fd, mdef2;
- unsigned char *buf;
-
- nullpo_retv(sd);
-
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0xbd));
- buf=WFIFOP(fd,0);
-
- WBUFW(buf,0)=0xbd;
- WBUFW(buf,2)=min(sd->status.status_point, INT16_MAX);
- WBUFB(buf,4)=min(sd->status.str, UINT8_MAX);
- WBUFB(buf,5)=pc_need_status_point(sd,SP_STR,1);
- WBUFB(buf,6)=min(sd->status.agi, UINT8_MAX);
- WBUFB(buf,7)=pc_need_status_point(sd,SP_AGI,1);
- WBUFB(buf,8)=min(sd->status.vit, UINT8_MAX);
- WBUFB(buf,9)=pc_need_status_point(sd,SP_VIT,1);
- WBUFB(buf,10)=min(sd->status.int_, UINT8_MAX);
- WBUFB(buf,11)=pc_need_status_point(sd,SP_INT,1);
- WBUFB(buf,12)=min(sd->status.dex, UINT8_MAX);
- WBUFB(buf,13)=pc_need_status_point(sd,SP_DEX,1);
- WBUFB(buf,14)=min(sd->status.luk, UINT8_MAX);
- WBUFB(buf,15)=pc_need_status_point(sd,SP_LUK,1);
-
- WBUFW(buf,16) = pc_leftside_atk(sd);
- WBUFW(buf,18) = pc_rightside_atk(sd);
- WBUFW(buf,20) = pc_rightside_matk(sd);
- WBUFW(buf,22) = pc_leftside_matk(sd);
- WBUFW(buf,24) = pc_leftside_def(sd);
- WBUFW(buf,26) = pc_rightside_def(sd);
- WBUFW(buf,28) = pc_leftside_mdef(sd);
- mdef2 = pc_rightside_mdef(sd);
- WBUFW(buf,30) =
+ int fd, mdef2;
+ unsigned char *buf;
+
+ nullpo_retv(sd);
+
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0xbd));
+ buf=WFIFOP(fd,0);
+
+ WBUFW(buf,0)=0xbd;
+ WBUFW(buf,2)=min(sd->status.status_point, INT16_MAX);
+ WBUFB(buf,4)=min(sd->status.str, UINT8_MAX);
+ WBUFB(buf,5)=pc_need_status_point(sd,SP_STR,1);
+ WBUFB(buf,6)=min(sd->status.agi, UINT8_MAX);
+ WBUFB(buf,7)=pc_need_status_point(sd,SP_AGI,1);
+ WBUFB(buf,8)=min(sd->status.vit, UINT8_MAX);
+ WBUFB(buf,9)=pc_need_status_point(sd,SP_VIT,1);
+ WBUFB(buf,10)=min(sd->status.int_, UINT8_MAX);
+ WBUFB(buf,11)=pc_need_status_point(sd,SP_INT,1);
+ WBUFB(buf,12)=min(sd->status.dex, UINT8_MAX);
+ WBUFB(buf,13)=pc_need_status_point(sd,SP_DEX,1);
+ WBUFB(buf,14)=min(sd->status.luk, UINT8_MAX);
+ WBUFB(buf,15)=pc_need_status_point(sd,SP_LUK,1);
+
+ WBUFW(buf,16) = pc_leftside_atk(sd);
+ WBUFW(buf,18) = pc_rightside_atk(sd);
+ WBUFW(buf,20) = sd->battle_status.matk_max;
+ WBUFW(buf,22) = sd->battle_status.matk_min;
+ WBUFW(buf,24) = pc_leftside_def(sd);
+ WBUFW(buf,26) = pc_rightside_def(sd);
+ WBUFW(buf,28) = pc_leftside_mdef(sd);
+ mdef2 = pc_rightside_mdef(sd);
+ WBUFW(buf,30) =
#ifndef RENEWAL
- (mdef2 < 0) ? 0 : //Negative check for Frenzy'ed characters.
+ ( mdef2 < 0 ) ? 0 : //Negative check for Frenzy'ed characters.
#endif
- mdef2;
- WBUFW(buf,32) = sd->battle_status.hit;
- WBUFW(buf,34) = sd->battle_status.flee;
- WBUFW(buf,36) = sd->battle_status.flee2/10;
- WBUFW(buf,38) = sd->battle_status.cri/10;
- WBUFW(buf,40) = sd->battle_status.amotion; // aspd
- WBUFW(buf,42) = 0; // always 0 (plusASPD)
+ mdef2;
+ WBUFW(buf,32) = sd->battle_status.hit;
+ WBUFW(buf,34) = sd->battle_status.flee;
+ WBUFW(buf,36) = sd->battle_status.flee2/10;
+ WBUFW(buf,38) = sd->battle_status.cri/10;
+ WBUFW(buf,40) = sd->battle_status.amotion; // aspd
+ WBUFW(buf,42) = 0; // always 0 (plusASPD)
- WFIFOSET(fd,packet_len(0xbd));
+ WFIFOSET(fd,packet_len(0xbd));
- clif_updatestatus(sd,SP_STR);
- clif_updatestatus(sd,SP_AGI);
- clif_updatestatus(sd,SP_VIT);
- clif_updatestatus(sd,SP_INT);
- clif_updatestatus(sd,SP_DEX);
- clif_updatestatus(sd,SP_LUK);
+ clif_updatestatus(sd,SP_STR);
+ clif_updatestatus(sd,SP_AGI);
+ clif_updatestatus(sd,SP_VIT);
+ clif_updatestatus(sd,SP_INT);
+ clif_updatestatus(sd,SP_DEX);
+ clif_updatestatus(sd,SP_LUK);
- clif_updatestatus(sd,SP_ATTACKRANGE);
- clif_updatestatus(sd,SP_ASPD);
+ clif_updatestatus(sd,SP_ATTACKRANGE);
+ clif_updatestatus(sd,SP_ASPD);
}
@@ -3162,17 +3205,17 @@ void clif_initialstatus(struct map_session_data *sd)
/// 013c <index>.W
void clif_arrowequip(struct map_session_data *sd,int val)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- pc_stop_attack(sd); // [Valaris]
+ pc_stop_attack(sd); // [Valaris]
- fd=sd->fd;
- WFIFOHEAD(fd, packet_len(0x013c));
- WFIFOW(fd,0)=0x013c;
- WFIFOW(fd,2)=val+2; //Item ID of the arrow
- WFIFOSET(fd,packet_len(0x013c));
+ fd=sd->fd;
+ WFIFOHEAD(fd, packet_len(0x013c));
+ WFIFOW(fd,0)=0x013c;
+ WFIFOW(fd,2)=val+2; //Item ID of the arrow
+ WFIFOSET(fd,packet_len(0x013c));
}
@@ -3187,15 +3230,15 @@ void clif_arrowequip(struct map_session_data *sd,int val)
/// NOT ninja => MsgStringTable[245]="Ammunition has been equipped."
void clif_arrow_fail(struct map_session_data *sd,int type)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd, packet_len(0x013b));
- WFIFOW(fd,0)=0x013b;
- WFIFOW(fd,2)=type;
- WFIFOSET(fd,packet_len(0x013b));
+ fd=sd->fd;
+ WFIFOHEAD(fd, packet_len(0x013b));
+ WFIFOW(fd,0)=0x013b;
+ WFIFOW(fd,2)=type;
+ WFIFOSET(fd,packet_len(0x013b));
}
@@ -3203,32 +3246,33 @@ void clif_arrow_fail(struct map_session_data *sd,int type)
/// 01ad <packet len>.W { <name id>.W }*
void clif_arrow_create_list(struct map_session_data *sd)
{
- int i, c, j;
- int fd;
+ int i, c, j;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd = sd->fd;
- WFIFOHEAD(fd, MAX_SKILL_ARROW_DB*2+4);
- WFIFOW(fd,0) = 0x1ad;
-
- for (i = 0, c = 0; i < MAX_SKILL_ARROW_DB; i++) {
- if (skill_arrow_db[i].nameid > 0 &&
- (j = pc_search_inventory(sd, skill_arrow_db[i].nameid)) >= 0 &&
- !sd->status.inventory[j].equip && sd->status.inventory[j].identify) {
- if ((j = itemdb_viewid(skill_arrow_db[i].nameid)) > 0)
- WFIFOW(fd,c*2+4) = j;
- else
- WFIFOW(fd,c*2+4) = skill_arrow_db[i].nameid;
- c++;
- }
- }
- WFIFOW(fd,2) = c*2+4;
- WFIFOSET(fd, WFIFOW(fd,2));
- if (c > 0) {
- sd->menuskill_id = AC_MAKINGARROW;
- sd->menuskill_val = c;
- }
+ fd = sd->fd;
+ WFIFOHEAD(fd, MAX_SKILL_ARROW_DB*2+4);
+ WFIFOW(fd,0) = 0x1ad;
+
+ for (i = 0, c = 0; i < MAX_SKILL_ARROW_DB; i++) {
+ if (skill_arrow_db[i].nameid > 0 &&
+ (j = pc_search_inventory(sd, skill_arrow_db[i].nameid)) >= 0 &&
+ !sd->status.inventory[j].equip && sd->status.inventory[j].identify)
+ {
+ if ((j = itemdb_viewid(skill_arrow_db[i].nameid)) > 0)
+ WFIFOW(fd,c*2+4) = j;
+ else
+ WFIFOW(fd,c*2+4) = skill_arrow_db[i].nameid;
+ c++;
+ }
+ }
+ WFIFOW(fd,2) = c*2+4;
+ WFIFOSET(fd, WFIFOW(fd,2));
+ if (c > 0) {
+ sd->menuskill_id = AC_MAKINGARROW;
+ sd->menuskill_val = c;
+ }
}
@@ -3241,17 +3285,17 @@ void clif_arrow_create_list(struct map_session_data *sd)
/// 1 = success
void clif_statusupack(struct map_session_data *sd,int type,int ok,int val)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0xbc));
- WFIFOW(fd,0)=0xbc;
- WFIFOW(fd,2)=type;
- WFIFOB(fd,4)=ok;
- WFIFOB(fd,5)=cap_value(val,0,UINT8_MAX);
- WFIFOSET(fd,packet_len(0xbc));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0xbc));
+ WFIFOW(fd,0)=0xbc;
+ WFIFOW(fd,2)=type;
+ WFIFOB(fd,4)=ok;
+ WFIFOB(fd,5)=cap_value(val,0,UINT8_MAX);
+ WFIFOSET(fd,packet_len(0xbc));
}
@@ -3264,25 +3308,25 @@ void clif_statusupack(struct map_session_data *sd,int type,int ok,int val)
/// 2 = failure due to low level
void clif_equipitemack(struct map_session_data *sd,int n,int pos,int ok)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0xaa));
- WFIFOW(fd,0)=0xaa;
- WFIFOW(fd,2)=n+2;
- WFIFOW(fd,4)=pos;
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0xaa));
+ WFIFOW(fd,0)=0xaa;
+ WFIFOW(fd,2)=n+2;
+ WFIFOW(fd,4)=pos;
#if PACKETVER < 20100629
- WFIFOB(fd,6)=ok;
+ WFIFOB(fd,6)=ok;
#else
- if (ok && sd->inventory_data[n]->equip&EQP_VISIBLE)
- WFIFOW(fd,6)=sd->inventory_data[n]->look;
- else
- WFIFOW(fd,6)=0;
- WFIFOB(fd,8)=ok;
+ if (ok && sd->inventory_data[n]->equip&EQP_VISIBLE)
+ WFIFOW(fd,6)=sd->inventory_data[n]->look;
+ else
+ WFIFOW(fd,6)=0;
+ WFIFOB(fd,8)=ok;
#endif
- WFIFOSET(fd,packet_len(0xaa));
+ WFIFOSET(fd,packet_len(0xaa));
}
@@ -3293,17 +3337,17 @@ void clif_equipitemack(struct map_session_data *sd,int n,int pos,int ok)
/// 1 = success
void clif_unequipitemack(struct map_session_data *sd,int n,int pos,int ok)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0xac));
- WFIFOW(fd,0)=0xac;
- WFIFOW(fd,2)=n+2;
- WFIFOW(fd,4)=pos;
- WFIFOB(fd,6)=ok;
- WFIFOSET(fd,packet_len(0xac));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0xac));
+ WFIFOW(fd,0)=0xac;
+ WFIFOW(fd,2)=n+2;
+ WFIFOW(fd,4)=pos;
+ WFIFOB(fd,6)=ok;
+ WFIFOSET(fd,packet_len(0xac));
}
@@ -3320,94 +3364,94 @@ void clif_unequipitemack(struct map_session_data *sd,int n,int pos,int ok)
/// 7 = base level up (super novice)
/// 8 = job level up (super novice)
/// 9 = base level up (taekwon)
-void clif_misceffect(struct block_list *bl,int type)
+void clif_misceffect(struct block_list* bl,int type)
{
- unsigned char buf[32];
+ unsigned char buf[32];
- nullpo_retv(bl);
+ nullpo_retv(bl);
- WBUFW(buf,0) = 0x19b;
- WBUFL(buf,2) = bl->id;
- WBUFL(buf,6) = type;
+ WBUFW(buf,0) = 0x19b;
+ WBUFL(buf,2) = bl->id;
+ WBUFL(buf,6) = type;
- clif_send(buf,packet_len(0x19b),bl,AREA);
+ clif_send(buf,packet_len(0x19b),bl,AREA);
}
/// Notifies clients in the area of a state change.
/// 0119 <id>.L <body state>.W <health state>.W <effect state>.W <pk mode>.B (ZC_STATE_CHANGE)
/// 0229 <id>.L <body state>.W <health state>.W <effect state>.L <pk mode>.B (ZC_STATE_CHANGE3)
-void clif_changeoption(struct block_list *bl)
+void clif_changeoption(struct block_list* bl)
{
- unsigned char buf[32];
- struct status_change *sc;
- struct map_session_data *sd;
+ unsigned char buf[32];
+ struct status_change *sc;
+ struct map_session_data* sd;
- nullpo_retv(bl);
- sc = status_get_sc(bl);
- if (!sc) return; //How can an option change if there's no sc?
- sd = BL_CAST(BL_PC, bl);
+ nullpo_retv(bl);
+ sc = status_get_sc(bl);
+ if (!sc) return; //How can an option change if there's no sc?
+ sd = BL_CAST(BL_PC, bl);
#if PACKETVER >= 7
- WBUFW(buf,0) = 0x229;
- WBUFL(buf,2) = bl->id;
- WBUFW(buf,6) = sc->opt1;
- WBUFW(buf,8) = sc->opt2;
- WBUFL(buf,10) = sc->option;
- WBUFB(buf,14) = (sd)? sd->status.karma : 0;
- if (disguised(bl)) {
- clif_send(buf,packet_len(0x229),bl,AREA_WOS);
- WBUFL(buf,2) = -bl->id;
- clif_send(buf,packet_len(0x229),bl,SELF);
- WBUFL(buf,2) = bl->id;
- WBUFL(buf,10) = OPTION_INVISIBLE;
- clif_send(buf,packet_len(0x229),bl,SELF);
- } else
- clif_send(buf,packet_len(0x229),bl,AREA);
+ WBUFW(buf,0) = 0x229;
+ WBUFL(buf,2) = bl->id;
+ WBUFW(buf,6) = sc->opt1;
+ WBUFW(buf,8) = sc->opt2;
+ WBUFL(buf,10) = sc->option;
+ WBUFB(buf,14) = (sd)? sd->status.karma : 0;
+ if(disguised(bl)) {
+ clif_send(buf,packet_len(0x229),bl,AREA_WOS);
+ WBUFL(buf,2) = -bl->id;
+ clif_send(buf,packet_len(0x229),bl,SELF);
+ WBUFL(buf,2) = bl->id;
+ WBUFL(buf,10) = OPTION_INVISIBLE;
+ clif_send(buf,packet_len(0x229),bl,SELF);
+ } else
+ clif_send(buf,packet_len(0x229),bl,AREA);
#else
- WBUFW(buf,0) = 0x119;
- WBUFL(buf,2) = bl->id;
- WBUFW(buf,6) = sc->opt1;
- WBUFW(buf,8) = sc->opt2;
- WBUFW(buf,10) = sc->option;
- WBUFB(buf,12) = (sd)? sd->status.karma : 0;
- if (disguised(bl)) {
- clif_send(buf,packet_len(0x119),bl,AREA_WOS);
- WBUFL(buf,2) = -bl->id;
- clif_send(buf,packet_len(0x119),bl,SELF);
- WBUFL(buf,2) = bl->id;
- WBUFW(buf,10) = OPTION_INVISIBLE;
- clif_send(buf,packet_len(0x119),bl,SELF);
- } else
- clif_send(buf,packet_len(0x119),bl,AREA);
+ WBUFW(buf,0) = 0x119;
+ WBUFL(buf,2) = bl->id;
+ WBUFW(buf,6) = sc->opt1;
+ WBUFW(buf,8) = sc->opt2;
+ WBUFW(buf,10) = sc->option;
+ WBUFB(buf,12) = (sd)? sd->status.karma : 0;
+ if(disguised(bl)) {
+ clif_send(buf,packet_len(0x119),bl,AREA_WOS);
+ WBUFL(buf,2) = -bl->id;
+ clif_send(buf,packet_len(0x119),bl,SELF);
+ WBUFL(buf,2) = bl->id;
+ WBUFW(buf,10) = OPTION_INVISIBLE;
+ clif_send(buf,packet_len(0x119),bl,SELF);
+ } else
+ clif_send(buf,packet_len(0x119),bl,AREA);
#endif
}
/// Displays status change effects on NPCs/monsters (ZC_NPC_SHOWEFST_UPDATE).
/// 028a <id>.L <effect state>.L <level>.L <showEFST>.L
-void clif_changeoption2(struct block_list *bl)
+void clif_changeoption2(struct block_list* bl)
{
- unsigned char buf[20];
- struct status_change *sc;
+ unsigned char buf[20];
+ struct status_change *sc;
- sc = status_get_sc(bl);
- if (!sc) return; //How can an option change if there's no sc?
+ sc = status_get_sc(bl);
+ if (!sc) return; //How can an option change if there's no sc?
- WBUFW(buf,0) = 0x28a;
- WBUFL(buf,2) = bl->id;
- WBUFL(buf,6) = sc->option;
- WBUFL(buf,10) = clif_setlevel(bl);
- WBUFL(buf,14) = sc->opt3;
- if (disguised(bl)) {
- clif_send(buf,packet_len(0x28a),bl,AREA_WOS);
- WBUFL(buf,2) = -bl->id;
- clif_send(buf,packet_len(0x28a),bl,SELF);
- WBUFL(buf,2) = bl->id;
- WBUFL(buf,6) = OPTION_INVISIBLE;
- clif_send(buf,packet_len(0x28a),bl,SELF);
- } else
- clif_send(buf,packet_len(0x28a),bl,AREA);
+ WBUFW(buf,0) = 0x28a;
+ WBUFL(buf,2) = bl->id;
+ WBUFL(buf,6) = sc->option;
+ WBUFL(buf,10) = clif_setlevel(bl);
+ WBUFL(buf,14) = sc->opt3;
+ if(disguised(bl)) {
+ clif_send(buf,packet_len(0x28a),bl,AREA_WOS);
+ WBUFL(buf,2) = -bl->id;
+ clif_send(buf,packet_len(0x28a),bl,SELF);
+ WBUFL(buf,2) = bl->id;
+ WBUFL(buf,6) = OPTION_INVISIBLE;
+ clif_send(buf,packet_len(0x28a),bl,SELF);
+ } else
+ clif_send(buf,packet_len(0x28a),bl,AREA);
}
@@ -3416,40 +3460,41 @@ void clif_changeoption2(struct block_list *bl)
/// 01c8 <index>.W <name id>.W <id>.L <amount>.W <result>.B (ZC_USE_ITEM_ACK2)
void clif_useitemack(struct map_session_data *sd,int index,int amount,bool ok)
{
- nullpo_retv(sd);
-
- if (!ok) {
- int fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0xa8));
- WFIFOW(fd,0)=0xa8;
- WFIFOW(fd,2)=index+2;
- WFIFOW(fd,4)=amount;
- WFIFOB(fd,6)=ok;
- WFIFOSET(fd,packet_len(0xa8));
- } else {
+ nullpo_retv(sd);
+
+ if(!ok) {
+ int fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0xa8));
+ WFIFOW(fd,0)=0xa8;
+ WFIFOW(fd,2)=index+2;
+ WFIFOW(fd,4)=amount;
+ WFIFOB(fd,6)=ok;
+ WFIFOSET(fd,packet_len(0xa8));
+ }
+ else {
#if PACKETVER < 3
- int fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0xa8));
- WFIFOW(fd,0)=0xa8;
- WFIFOW(fd,2)=index+2;
- WFIFOW(fd,4)=amount;
- WFIFOB(fd,6)=ok;
- WFIFOSET(fd,packet_len(0xa8));
+ int fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0xa8));
+ WFIFOW(fd,0)=0xa8;
+ WFIFOW(fd,2)=index+2;
+ WFIFOW(fd,4)=amount;
+ WFIFOB(fd,6)=ok;
+ WFIFOSET(fd,packet_len(0xa8));
#else
- unsigned char buf[32];
-
- WBUFW(buf,0)=0x1c8;
- WBUFW(buf,2)=index+2;
- if (sd->inventory_data[index] && sd->inventory_data[index]->view_id > 0)
- WBUFW(buf,4)=sd->inventory_data[index]->view_id;
- else
- WBUFW(buf,4)=sd->status.inventory[index].nameid;
- WBUFL(buf,6)=sd->bl.id;
- WBUFW(buf,10)=amount;
- WBUFB(buf,12)=ok;
- clif_send(buf,packet_len(0x1c8),&sd->bl,AREA);
+ unsigned char buf[32];
+
+ WBUFW(buf,0)=0x1c8;
+ WBUFW(buf,2)=index+2;
+ if(sd->inventory_data[index] && sd->inventory_data[index]->view_id > 0)
+ WBUFW(buf,4)=sd->inventory_data[index]->view_id;
+ else
+ WBUFW(buf,4)=sd->status.inventory[index].nameid;
+ WBUFL(buf,6)=sd->bl.id;
+ WBUFW(buf,10)=amount;
+ WBUFB(buf,12)=ok;
+ clif_send(buf,packet_len(0x1c8),&sd->bl,AREA);
#endif
- }
+ }
}
@@ -3459,17 +3504,17 @@ void clif_useitemack(struct map_session_data *sd,int index,int amount,bool ok)
/// 0 = Room has been successfully created (opens chat room)
/// 1 = Room limit exceeded
/// 2 = Same room already exists
-void clif_createchat(struct map_session_data *sd, int flag)
+void clif_createchat(struct map_session_data* sd, int flag)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0xd6));
- WFIFOW(fd,0) = 0xd6;
- WFIFOB(fd,2) = flag;
- WFIFOSET(fd,packet_len(0xd6));
+ fd = sd->fd;
+ WFIFOHEAD(fd,packet_len(0xd6));
+ WFIFOW(fd,0) = 0xd6;
+ WFIFOB(fd,2) = flag;
+ WFIFOSET(fd,packet_len(0xd6));
}
@@ -3480,34 +3525,34 @@ void clif_createchat(struct map_session_data *sd, int flag)
/// 1 = public
/// 2 = arena (npc waiting room)
/// 3 = PK zone (non-clickable)
-void clif_dispchat(struct chat_data *cd, int fd)
-{
- unsigned char buf[128];
- uint8 type;
-
- if (cd == NULL || cd->owner == NULL)
- return;
-
- type = (cd->owner->type == BL_PC) ? (cd->pub) ? 1 : 0
- : (cd->owner->type == BL_NPC) ? (cd->limit) ? 2 : 3
- : 1;
-
- WBUFW(buf, 0) = 0xd7;
- WBUFW(buf, 2) = 17 + strlen(cd->title);
- WBUFL(buf, 4) = cd->owner->id;
- WBUFL(buf, 8) = cd->bl.id;
- WBUFW(buf,12) = cd->limit;
- WBUFW(buf,14) = (cd->owner->type == BL_NPC) ? cd->users+1 : cd->users;
- WBUFB(buf,16) = type;
- memcpy((char *)WBUFP(buf,17), cd->title, strlen(cd->title)); // not zero-terminated
-
- if (fd) {
- WFIFOHEAD(fd,WBUFW(buf,2));
- memcpy(WFIFOP(fd,0),buf,WBUFW(buf,2));
- WFIFOSET(fd,WBUFW(buf,2));
- } else {
- clif_send(buf,WBUFW(buf,2),cd->owner,AREA_WOSC);
- }
+void clif_dispchat(struct chat_data* cd, int fd)
+{
+ unsigned char buf[128];
+ uint8 type;
+
+ if( cd == NULL || cd->owner == NULL )
+ return;
+
+ type = (cd->owner->type == BL_PC ) ? (cd->pub) ? 1 : 0
+ : (cd->owner->type == BL_NPC) ? (cd->limit) ? 2 : 3
+ : 1;
+
+ WBUFW(buf, 0) = 0xd7;
+ WBUFW(buf, 2) = 17 + strlen(cd->title);
+ WBUFL(buf, 4) = cd->owner->id;
+ WBUFL(buf, 8) = cd->bl.id;
+ WBUFW(buf,12) = cd->limit;
+ WBUFW(buf,14) = (cd->owner->type == BL_NPC) ? cd->users+1 : cd->users;
+ WBUFB(buf,16) = type;
+ memcpy((char*)WBUFP(buf,17), cd->title, strlen(cd->title)); // not zero-terminated
+
+ if( fd ) {
+ WFIFOHEAD(fd,WBUFW(buf,2));
+ memcpy(WFIFOP(fd,0),buf,WBUFW(buf,2));
+ WFIFOSET(fd,WBUFW(buf,2));
+ } else {
+ clif_send(buf,WBUFW(buf,2),cd->owner,AREA_WOSC);
+ }
}
@@ -3518,28 +3563,28 @@ void clif_dispchat(struct chat_data *cd, int fd)
/// 1 = public
/// 2 = arena (npc waiting room)
/// 3 = PK zone (non-clickable)
-void clif_changechatstatus(struct chat_data *cd)
+void clif_changechatstatus(struct chat_data* cd)
{
- unsigned char buf[128];
- uint8 type;
+ unsigned char buf[128];
+ uint8 type;
- if (cd == NULL || cd->usersd[0] == NULL)
- return;
+ if( cd == NULL || cd->usersd[0] == NULL )
+ return;
- type = (cd->owner->type == BL_PC) ? (cd->pub) ? 1 : 0
- : (cd->owner->type == BL_NPC) ? (cd->limit) ? 2 : 3
- : 1;
+ type = (cd->owner->type == BL_PC ) ? (cd->pub) ? 1 : 0
+ : (cd->owner->type == BL_NPC) ? (cd->limit) ? 2 : 3
+ : 1;
- WBUFW(buf, 0) = 0xdf;
- WBUFW(buf, 2) = 17 + strlen(cd->title);
- WBUFL(buf, 4) = cd->owner->id;
- WBUFL(buf, 8) = cd->bl.id;
- WBUFW(buf,12) = cd->limit;
- WBUFW(buf,14) = (cd->owner->type == BL_NPC) ? cd->users+1 : cd->users;
- WBUFB(buf,16) = type;
- memcpy((char *)WBUFP(buf,17), cd->title, strlen(cd->title)); // not zero-terminated
+ WBUFW(buf, 0) = 0xdf;
+ WBUFW(buf, 2) = 17 + strlen(cd->title);
+ WBUFL(buf, 4) = cd->owner->id;
+ WBUFL(buf, 8) = cd->bl.id;
+ WBUFW(buf,12) = cd->limit;
+ WBUFW(buf,14) = (cd->owner->type == BL_NPC) ? cd->users+1 : cd->users;
+ WBUFB(buf,16) = type;
+ memcpy((char*)WBUFP(buf,17), cd->title, strlen(cd->title)); // not zero-terminated
- clif_send(buf,WBUFW(buf,2),cd->owner,CHAT);
+ clif_send(buf,WBUFW(buf,2),cd->owner,CHAT);
}
@@ -3547,19 +3592,19 @@ void clif_changechatstatus(struct chat_data *cd)
/// 00d8 <chat id>.L
void clif_clearchat(struct chat_data *cd,int fd)
{
- unsigned char buf[32];
+ unsigned char buf[32];
- nullpo_retv(cd);
+ nullpo_retv(cd);
- WBUFW(buf,0) = 0xd8;
- WBUFL(buf,2) = cd->bl.id;
- if (fd) {
- WFIFOHEAD(fd,packet_len(0xd8));
- memcpy(WFIFOP(fd,0),buf,packet_len(0xd8));
- WFIFOSET(fd,packet_len(0xd8));
- } else {
- clif_send(buf,packet_len(0xd8),cd->owner,AREA_WOSC);
- }
+ WBUFW(buf,0) = 0xd8;
+ WBUFL(buf,2) = cd->bl.id;
+ if( fd ) {
+ WFIFOHEAD(fd,packet_len(0xd8));
+ memcpy(WFIFOP(fd,0),buf,packet_len(0xd8));
+ WFIFOSET(fd,packet_len(0xd8));
+ } else {
+ clif_send(buf,packet_len(0xd8),cd->owner,AREA_WOSC);
+ }
}
@@ -3576,16 +3621,16 @@ void clif_clearchat(struct chat_data *cd,int fd)
/// 7 = unsuitable job class
void clif_joinchatfail(struct map_session_data *sd,int flag)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd = sd->fd;
+ fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0xda));
- WFIFOW(fd,0) = 0xda;
- WFIFOB(fd,2) = flag;
- WFIFOSET(fd,packet_len(0xda));
+ WFIFOHEAD(fd,packet_len(0xda));
+ WFIFOW(fd,0) = 0xda;
+ WFIFOB(fd,2) = flag;
+ WFIFOSET(fd,packet_len(0xda));
}
@@ -3594,53 +3639,53 @@ void clif_joinchatfail(struct map_session_data *sd,int flag)
/// role:
/// 0 = owner (menu)
/// 1 = normal
-void clif_joinchatok(struct map_session_data *sd,struct chat_data *cd)
-{
- int fd;
- int i,t;
-
- nullpo_retv(sd);
- nullpo_retv(cd);
-
- fd = sd->fd;
- if (!session_isActive(fd))
- return;
- t = (int)(cd->owner->type == BL_NPC);
- WFIFOHEAD(fd, 8 + (28*(cd->users+t)));
- WFIFOW(fd, 0) = 0xdb;
- WFIFOW(fd, 2) = 8 + (28*(cd->users+t));
- WFIFOL(fd, 4) = cd->bl.id;
-
- if (cd->owner->type == BL_NPC) {
- WFIFOL(fd, 30) = 1;
- WFIFOL(fd, 8) = 0;
- memcpy(WFIFOP(fd, 12), ((struct npc_data *)cd->owner)->name, NAME_LENGTH);
- for (i = 0; i < cd->users; i++) {
- WFIFOL(fd, 8+(i+1)*28) = 1;
- memcpy(WFIFOP(fd, 8+(i+t)*28+4), cd->usersd[i]->status.name, NAME_LENGTH);
- }
- } else
- for (i = 0; i < cd->users; i++) {
- WFIFOL(fd, 8+i*28) = (i != 0 || cd->owner->type == BL_NPC);
- memcpy(WFIFOP(fd, 8+(i+t)*28+4), cd->usersd[i]->status.name, NAME_LENGTH);
- }
- WFIFOSET(fd, WFIFOW(fd, 2));
+void clif_joinchatok(struct map_session_data *sd,struct chat_data* cd)
+{
+ int fd;
+ int i,t;
+
+ nullpo_retv(sd);
+ nullpo_retv(cd);
+
+ fd = sd->fd;
+ if (!session_isActive(fd))
+ return;
+ t = (int)(cd->owner->type == BL_NPC);
+ WFIFOHEAD(fd, 8 + (28*(cd->users+t)));
+ WFIFOW(fd, 0) = 0xdb;
+ WFIFOW(fd, 2) = 8 + (28*(cd->users+t));
+ WFIFOL(fd, 4) = cd->bl.id;
+
+ if(cd->owner->type == BL_NPC){
+ WFIFOL(fd, 30) = 1;
+ WFIFOL(fd, 8) = 0;
+ memcpy(WFIFOP(fd, 12), ((struct npc_data *)cd->owner)->name, NAME_LENGTH);
+ for (i = 0; i < cd->users; i++) {
+ WFIFOL(fd, 8+(i+1)*28) = 1;
+ memcpy(WFIFOP(fd, 8+(i+t)*28+4), cd->usersd[i]->status.name, NAME_LENGTH);
+ }
+ } else
+ for (i = 0; i < cd->users; i++) {
+ WFIFOL(fd, 8+i*28) = (i != 0 || cd->owner->type == BL_NPC);
+ memcpy(WFIFOP(fd, 8+(i+t)*28+4), cd->usersd[i]->status.name, NAME_LENGTH);
+ }
+ WFIFOSET(fd, WFIFOW(fd, 2));
}
/// Notifies clients in a chat about a new member (ZC_MEMBER_NEWENTRY).
/// 00dc <users>.W <name>.24B
-void clif_addchat(struct chat_data *cd,struct map_session_data *sd)
+void clif_addchat(struct chat_data* cd,struct map_session_data *sd)
{
- unsigned char buf[32];
+ unsigned char buf[32];
- nullpo_retv(sd);
- nullpo_retv(cd);
+ nullpo_retv(sd);
+ nullpo_retv(cd);
- WBUFW(buf, 0) = 0xdc;
- WBUFW(buf, 2) = cd->users;
- memcpy(WBUFP(buf, 4),sd->status.name,NAME_LENGTH);
- clif_send(buf,packet_len(0xdc),&sd->bl,CHAT_WOS);
+ WBUFW(buf, 0) = 0xdc;
+ WBUFW(buf, 2) = cd->users;
+ memcpy(WBUFP(buf, 4),sd->status.name,NAME_LENGTH);
+ clif_send(buf,packet_len(0xdc),&sd->bl,CHAT_WOS);
}
@@ -3649,22 +3694,22 @@ void clif_addchat(struct chat_data *cd,struct map_session_data *sd)
/// role:
/// 0 = owner (menu)
/// 1 = normal
-void clif_changechatowner(struct chat_data *cd, struct map_session_data *sd)
+void clif_changechatowner(struct chat_data* cd, struct map_session_data* sd)
{
- unsigned char buf[64];
+ unsigned char buf[64];
- nullpo_retv(sd);
- nullpo_retv(cd);
+ nullpo_retv(sd);
+ nullpo_retv(cd);
- WBUFW(buf, 0) = 0xe1;
- WBUFL(buf, 2) = 1;
- memcpy(WBUFP(buf,6),cd->usersd[0]->status.name,NAME_LENGTH);
+ WBUFW(buf, 0) = 0xe1;
+ WBUFL(buf, 2) = 1;
+ memcpy(WBUFP(buf,6),cd->usersd[0]->status.name,NAME_LENGTH);
- WBUFW(buf,30) = 0xe1;
- WBUFL(buf,32) = 0;
- memcpy(WBUFP(buf,36),sd->status.name,NAME_LENGTH);
+ WBUFW(buf,30) = 0xe1;
+ WBUFL(buf,32) = 0;
+ memcpy(WBUFP(buf,36),sd->status.name,NAME_LENGTH);
- clif_send(buf,packet_len(0xe1)*2,&sd->bl,CHAT);
+ clif_send(buf,packet_len(0xe1)*2,&sd->bl,CHAT);
}
@@ -3673,44 +3718,44 @@ void clif_changechatowner(struct chat_data *cd, struct map_session_data *sd)
/// flag:
/// 0 = left
/// 1 = kicked
-void clif_leavechat(struct chat_data *cd, struct map_session_data *sd, bool flag)
+void clif_leavechat(struct chat_data* cd, struct map_session_data* sd, bool flag)
{
- unsigned char buf[32];
+ unsigned char buf[32];
- nullpo_retv(sd);
- nullpo_retv(cd);
+ nullpo_retv(sd);
+ nullpo_retv(cd);
- WBUFW(buf, 0) = 0xdd;
- WBUFW(buf, 2) = cd->users-1;
- memcpy(WBUFP(buf,4),sd->status.name,NAME_LENGTH);
- WBUFB(buf,28) = flag;
+ WBUFW(buf, 0) = 0xdd;
+ WBUFW(buf, 2) = cd->users-1;
+ memcpy(WBUFP(buf,4),sd->status.name,NAME_LENGTH);
+ WBUFB(buf,28) = flag;
- clif_send(buf,packet_len(0xdd),&sd->bl,CHAT);
+ clif_send(buf,packet_len(0xdd),&sd->bl,CHAT);
}
/// Opens a trade request window from char 'name'.
/// 00e5 <nick>.24B (ZC_REQ_EXCHANGE_ITEM)
/// 01f4 <nick>.24B <charid>.L <baselvl>.W (ZC_REQ_EXCHANGE_ITEM2)
-void clif_traderequest(struct map_session_data *sd, const char *name)
+void clif_traderequest(struct map_session_data* sd, const char* name)
{
- int fd = sd->fd;
+ int fd = sd->fd;
#if PACKETVER < 6
- WFIFOHEAD(fd,packet_len(0xe5));
- WFIFOW(fd,0) = 0xe5;
- safestrncpy((char *)WFIFOP(fd,2), name, NAME_LENGTH);
- WFIFOSET(fd,packet_len(0xe5));
+ WFIFOHEAD(fd,packet_len(0xe5));
+ WFIFOW(fd,0) = 0xe5;
+ safestrncpy((char*)WFIFOP(fd,2), name, NAME_LENGTH);
+ WFIFOSET(fd,packet_len(0xe5));
#else
- struct map_session_data *tsd = map_id2sd(sd->trade_partner);
- if (!tsd) return;
-
- WFIFOHEAD(fd,packet_len(0x1f4));
- WFIFOW(fd,0) = 0x1f4;
- safestrncpy((char *)WFIFOP(fd,2), name, NAME_LENGTH);
- WFIFOL(fd,26) = tsd->status.char_id;
- WFIFOW(fd,30) = tsd->status.base_level;
- WFIFOSET(fd,packet_len(0x1f4));
+ struct map_session_data* tsd = map_id2sd(sd->trade_partner);
+ if( !tsd ) return;
+
+ WFIFOHEAD(fd,packet_len(0x1f4));
+ WFIFOW(fd,0) = 0x1f4;
+ safestrncpy((char*)WFIFOP(fd,2), name, NAME_LENGTH);
+ WFIFOL(fd,26) = tsd->status.char_id;
+ WFIFOW(fd,30) = tsd->status.base_level;
+ WFIFOSET(fd,packet_len(0x1f4));
#endif
}
@@ -3725,85 +3770,88 @@ void clif_traderequest(struct map_session_data *sd, const char *name)
/// 3 = Accept
/// 4 = Cancel
/// 5 = Busy
-void clif_tradestart(struct map_session_data *sd, uint8 type)
-{
- int fd = sd->fd;
- struct map_session_data *tsd = map_id2sd(sd->trade_partner);
- if (PACKETVER < 6 || !tsd) {
- WFIFOHEAD(fd,packet_len(0xe7));
- WFIFOW(fd,0) = 0xe7;
- WFIFOB(fd,2) = type;
- WFIFOSET(fd,packet_len(0xe7));
- } else {
- WFIFOHEAD(fd,packet_len(0x1f5));
- WFIFOW(fd,0) = 0x1f5;
- WFIFOB(fd,2) = type;
- WFIFOL(fd,3) = tsd->status.char_id;
- WFIFOW(fd,7) = tsd->status.base_level;
- WFIFOSET(fd,packet_len(0x1f5));
- }
+void clif_tradestart(struct map_session_data* sd, uint8 type)
+{
+ int fd = sd->fd;
+ struct map_session_data* tsd = map_id2sd(sd->trade_partner);
+ if( PACKETVER < 6 || !tsd ) {
+ WFIFOHEAD(fd,packet_len(0xe7));
+ WFIFOW(fd,0) = 0xe7;
+ WFIFOB(fd,2) = type;
+ WFIFOSET(fd,packet_len(0xe7));
+ } else {
+ WFIFOHEAD(fd,packet_len(0x1f5));
+ WFIFOW(fd,0) = 0x1f5;
+ WFIFOB(fd,2) = type;
+ WFIFOL(fd,3) = tsd->status.char_id;
+ WFIFOW(fd,7) = tsd->status.base_level;
+ WFIFOSET(fd,packet_len(0x1f5));
+ }
}
/// Notifies the client about an item from other player in current trade.
/// 00e9 <amount>.L <nameid>.W <identified>.B <damaged>.B <refine>.B <card1>.W <card2>.W <card3>.W <card4>.W (ZC_ADD_EXCHANGE_ITEM)
/// 080f <nameid>.W <item type>.B <amount>.L <identified>.B <damaged>.B <refine>.B <card1>.W <card2>.W <card3>.W <card4>.W (ZC_ADD_EXCHANGE_ITEM2)
-void clif_tradeadditem(struct map_session_data *sd, struct map_session_data *tsd, int index, int amount)
+void clif_tradeadditem(struct map_session_data* sd, struct map_session_data* tsd, int index, int amount)
{
- int fd;
- unsigned char *buf;
+ int fd;
+ unsigned char *buf;
#if PACKETVER < 20100223
- const int cmd = 0xe9;
+ const int cmd = 0xe9;
#else
- const int cmd = 0x80f;
+ const int cmd = 0x80f;
#endif
- nullpo_retv(sd);
- nullpo_retv(tsd);
-
- fd = tsd->fd;
- buf = WFIFOP(fd,0);
- WFIFOHEAD(fd,packet_len(cmd));
- WBUFW(buf,0) = cmd;
- if (index == 0) {
+ nullpo_retv(sd);
+ nullpo_retv(tsd);
+
+ fd = tsd->fd;
+ buf = WFIFOP(fd,0);
+ WFIFOHEAD(fd,packet_len(cmd));
+ WBUFW(buf,0) = cmd;
+ if( index == 0 )
+ {
#if PACKETVER < 20100223
- WBUFL(buf,2) = amount; //amount
- WBUFW(buf,6) = 0; // type id
+ WBUFL(buf,2) = amount; //amount
+ WBUFW(buf,6) = 0; // type id
#else
- WBUFW(buf,2) = 0; // type id
- WBUFB(buf,4) = 0; // item type
- WBUFL(buf,5) = amount; // amount
- buf = WBUFP(buf,1); //Advance 1B
+ WBUFW(buf,2) = 0; // type id
+ WBUFB(buf,4) = 0; // item type
+ WBUFL(buf,5) = amount; // amount
+ buf = WBUFP(buf,1); //Advance 1B
#endif
- WBUFB(buf,8) = 0; //identify flag
- WBUFB(buf,9) = 0; // attribute
- WBUFB(buf,10)= 0; //refine
- WBUFW(buf,11)= 0; //card (4w)
- WBUFW(buf,13)= 0; //card (4w)
- WBUFW(buf,15)= 0; //card (4w)
- WBUFW(buf,17)= 0; //card (4w)
- } else {
- index -= 2; //index fix
+ WBUFB(buf,8) = 0; //identify flag
+ WBUFB(buf,9) = 0; // attribute
+ WBUFB(buf,10)= 0; //refine
+ WBUFW(buf,11)= 0; //card (4w)
+ WBUFW(buf,13)= 0; //card (4w)
+ WBUFW(buf,15)= 0; //card (4w)
+ WBUFW(buf,17)= 0; //card (4w)
+ }
+ else
+ {
+ index -= 2; //index fix
#if PACKETVER < 20100223
- WBUFL(buf,2) = amount; //amount
- if (sd->inventory_data[index] && sd->inventory_data[index]->view_id > 0)
- WBUFW(buf,6) = sd->inventory_data[index]->view_id;
- else
- WBUFW(buf,6) = sd->status.inventory[index].nameid; // type id
+ WBUFL(buf,2) = amount; //amount
+ if(sd->inventory_data[index] && sd->inventory_data[index]->view_id > 0)
+ WBUFW(buf,6) = sd->inventory_data[index]->view_id;
+ else
+ WBUFW(buf,6) = sd->status.inventory[index].nameid; // type id
#else
- if (sd->inventory_data[index] && sd->inventory_data[index]->view_id > 0)
- WBUFW(buf,2) = sd->inventory_data[index]->view_id;
- else
- WBUFW(buf,2) = sd->status.inventory[index].nameid; // type id
- WBUFB(buf,4) = sd->inventory_data[index]->type; // item type
- WBUFL(buf,5) = amount; // amount
- buf = WBUFP(buf,1); //Advance 1B
+ if(sd->inventory_data[index] && sd->inventory_data[index]->view_id > 0)
+ WBUFW(buf,2) = sd->inventory_data[index]->view_id;
+ else
+ WBUFW(buf,2) = sd->status.inventory[index].nameid; // type id
+ WBUFB(buf,4) = sd->inventory_data[index]->type; // item type
+ WBUFL(buf,5) = amount; // amount
+ buf = WBUFP(buf,1); //Advance 1B
#endif
- WBUFB(buf,8) = sd->status.inventory[index].identify; //identify flag
- WBUFB(buf,9) = sd->status.inventory[index].attribute; // attribute
- WBUFB(buf,10)= sd->status.inventory[index].refine; //refine
- clif_addcards(WBUFP(buf, 11), &sd->status.inventory[index]);
- }
- WFIFOSET(fd,packet_len(cmd));
+ WBUFB(buf,8) = sd->status.inventory[index].identify; //identify flag
+ WBUFB(buf,9) = sd->status.inventory[index].attribute; // attribute
+ WBUFB(buf,10)= sd->status.inventory[index].refine; //refine
+ clif_addcards(WBUFP(buf, 11), &sd->status.inventory[index]);
+ }
+ WFIFOSET(fd,packet_len(cmd));
}
@@ -3813,17 +3861,17 @@ void clif_tradeadditem(struct map_session_data *sd, struct map_session_data *tsd
/// 0 = success
/// 1 = overweight
/// 2 = trade canceled
-void clif_tradeitemok(struct map_session_data *sd, int index, int fail)
+void clif_tradeitemok(struct map_session_data* sd, int index, int fail)
{
- int fd;
- nullpo_retv(sd);
+ int fd;
+ nullpo_retv(sd);
- fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0xea));
- WFIFOW(fd,0) = 0xea;
- WFIFOW(fd,2) = index;
- WFIFOB(fd,4) = fail;
- WFIFOSET(fd,packet_len(0xea));
+ fd = sd->fd;
+ WFIFOHEAD(fd,packet_len(0xea));
+ WFIFOW(fd,0) = 0xea;
+ WFIFOW(fd,2) = index;
+ WFIFOB(fd,4) = fail;
+ WFIFOSET(fd,packet_len(0xea));
}
@@ -3832,30 +3880,30 @@ void clif_tradeitemok(struct map_session_data *sd, int index, int fail)
/// who:
/// 0 = self
/// 1 = other player
-void clif_tradedeal_lock(struct map_session_data *sd, int fail)
+void clif_tradedeal_lock(struct map_session_data* sd, int fail)
{
- int fd;
- nullpo_retv(sd);
+ int fd;
+ nullpo_retv(sd);
- fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0xec));
- WFIFOW(fd,0) = 0xec;
- WFIFOB(fd,2) = fail;
- WFIFOSET(fd,packet_len(0xec));
+ fd = sd->fd;
+ WFIFOHEAD(fd,packet_len(0xec));
+ WFIFOW(fd,0) = 0xec;
+ WFIFOB(fd,2) = fail;
+ WFIFOSET(fd,packet_len(0xec));
}
/// Notifies the client about the trade being canceled (ZC_CANCEL_EXCHANGE_ITEM).
/// 00ee
-void clif_tradecancelled(struct map_session_data *sd)
+void clif_tradecancelled(struct map_session_data* sd)
{
- int fd;
- nullpo_retv(sd);
+ int fd;
+ nullpo_retv(sd);
- fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0xee));
- WFIFOW(fd,0) = 0xee;
- WFIFOSET(fd,packet_len(0xee));
+ fd = sd->fd;
+ WFIFOHEAD(fd,packet_len(0xee));
+ WFIFOW(fd,0) = 0xee;
+ WFIFOSET(fd,packet_len(0xee));
}
@@ -3864,16 +3912,16 @@ void clif_tradecancelled(struct map_session_data *sd)
/// result:
/// 0 = success
/// 1 = failure
-void clif_tradecompleted(struct map_session_data *sd, int fail)
+void clif_tradecompleted(struct map_session_data* sd, int fail)
{
- int fd;
- nullpo_retv(sd);
+ int fd;
+ nullpo_retv(sd);
- fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0xf0));
- WFIFOW(fd,0) = 0xf0;
- WFIFOB(fd,2) = fail;
- WFIFOSET(fd,packet_len(0xf0));
+ fd = sd->fd;
+ WFIFOHEAD(fd,packet_len(0xf0));
+ WFIFOW(fd,0) = 0xf0;
+ WFIFOB(fd,2) = fail;
+ WFIFOSET(fd,packet_len(0xf0));
}
@@ -3881,231 +3929,235 @@ void clif_tradecompleted(struct map_session_data *sd, int fail)
/// 00f1
/// NOTE: Unknown purpose. Items are not removed until the window is
/// refreshed (ex. by putting another item in there).
-void clif_tradeundo(struct map_session_data *sd)
+void clif_tradeundo(struct map_session_data* sd)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0xf1));
- WFIFOW(fd,0) = 0xf1;
- WFIFOSET(fd,packet_len(0xf1));
+ WFIFOHEAD(fd,packet_len(0xf1));
+ WFIFOW(fd,0) = 0xf1;
+ WFIFOSET(fd,packet_len(0xf1));
}
/// Updates storage total amount (ZC_NOTIFY_STOREITEM_COUNTINFO).
/// 00f2 <current count>.W <max count>.W
-void clif_updatestorageamount(struct map_session_data *sd, int amount, int max_amount)
+void clif_updatestorageamount(struct map_session_data* sd, int amount, int max_amount)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0xf2));
- WFIFOW(fd,0) = 0xf2;
- WFIFOW(fd,2) = amount;
- WFIFOW(fd,4) = max_amount;
- WFIFOSET(fd,packet_len(0xf2));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0xf2));
+ WFIFOW(fd,0) = 0xf2;
+ WFIFOW(fd,2) = amount;
+ WFIFOW(fd,4) = max_amount;
+ WFIFOSET(fd,packet_len(0xf2));
}
/// Notifies the client of an item being added to the storage.
/// 00f4 <index>.W <amount>.L <nameid>.W <identified>.B <damaged>.B <refine>.B <card1>.W <card2>.W <card3>.W <card4>.W (ZC_ADD_ITEM_TO_STORE)
/// 01c4 <index>.W <amount>.L <nameid>.W <type>.B <identified>.B <damaged>.B <refine>.B <card1>.W <card2>.W <card3>.W <card4>.W (ZC_ADD_ITEM_TO_STORE2)
-void clif_storageitemadded(struct map_session_data *sd, struct item *i, int index, int amount)
+void clif_storageitemadded(struct map_session_data* sd, struct item* i, int index, int amount)
{
- int view,fd;
+ int view,fd;
- nullpo_retv(sd);
- nullpo_retv(i);
- fd=sd->fd;
- view = itemdb_viewid(i->nameid);
+ nullpo_retv(sd);
+ nullpo_retv(i);
+ fd=sd->fd;
+ view = itemdb_viewid(i->nameid);
#if PACKETVER < 5
- WFIFOHEAD(fd,packet_len(0xf4));
- WFIFOW(fd, 0) = 0xf4; // Storage item added
- WFIFOW(fd, 2) = index+1; // index
- WFIFOL(fd, 4) = amount; // amount
- WFIFOW(fd, 8) = (view > 0) ? view : i->nameid; // id
- WFIFOB(fd,10) = i->identify; //identify flag
- WFIFOB(fd,11) = i->attribute; // attribute
- WFIFOB(fd,12) = i->refine; //refine
- clif_addcards(WFIFOP(fd,13), i);
- WFIFOSET(fd,packet_len(0xf4));
+ WFIFOHEAD(fd,packet_len(0xf4));
+ WFIFOW(fd, 0) = 0xf4; // Storage item added
+ WFIFOW(fd, 2) = index+1; // index
+ WFIFOL(fd, 4) = amount; // amount
+ WFIFOW(fd, 8) = ( view > 0 ) ? view : i->nameid; // id
+ WFIFOB(fd,10) = i->identify; //identify flag
+ WFIFOB(fd,11) = i->attribute; // attribute
+ WFIFOB(fd,12) = i->refine; //refine
+ clif_addcards(WFIFOP(fd,13), i);
+ WFIFOSET(fd,packet_len(0xf4));
#else
- WFIFOHEAD(fd,packet_len(0x1c4));
- WFIFOW(fd, 0) = 0x1c4; // Storage item added
- WFIFOW(fd, 2) = index+1; // index
- WFIFOL(fd, 4) = amount; // amount
- WFIFOW(fd, 8) = (view > 0) ? view : i->nameid; // id
- WFIFOB(fd,10) = itemdb_type(i->nameid); //type
- WFIFOB(fd,11) = i->identify; //identify flag
- WFIFOB(fd,12) = i->attribute; // attribute
- WFIFOB(fd,13) = i->refine; //refine
- clif_addcards(WFIFOP(fd,14), i);
- WFIFOSET(fd,packet_len(0x1c4));
+ WFIFOHEAD(fd,packet_len(0x1c4));
+ WFIFOW(fd, 0) = 0x1c4; // Storage item added
+ WFIFOW(fd, 2) = index+1; // index
+ WFIFOL(fd, 4) = amount; // amount
+ WFIFOW(fd, 8) = ( view > 0 ) ? view : i->nameid; // id
+ WFIFOB(fd,10) = itemdb_type(i->nameid); //type
+ WFIFOB(fd,11) = i->identify; //identify flag
+ WFIFOB(fd,12) = i->attribute; // attribute
+ WFIFOB(fd,13) = i->refine; //refine
+ clif_addcards(WFIFOP(fd,14), i);
+ WFIFOSET(fd,packet_len(0x1c4));
#endif
}
/// Notifies the client of an item being deleted from the storage (ZC_DELETE_ITEM_FROM_STORE).
/// 00f6 <index>.W <amount>.L
-void clif_storageitemremoved(struct map_session_data *sd, int index, int amount)
+void clif_storageitemremoved(struct map_session_data* sd, int index, int amount)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0xf6));
- WFIFOW(fd,0)=0xf6; // Storage item removed
- WFIFOW(fd,2)=index+1;
- WFIFOL(fd,4)=amount;
- WFIFOSET(fd,packet_len(0xf6));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0xf6));
+ WFIFOW(fd,0)=0xf6; // Storage item removed
+ WFIFOW(fd,2)=index+1;
+ WFIFOL(fd,4)=amount;
+ WFIFOSET(fd,packet_len(0xf6));
}
/// Closes storage (ZC_CLOSE_STORE).
/// 00f8
-void clif_storageclose(struct map_session_data *sd)
+void clif_storageclose(struct map_session_data* sd)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0xf8));
- WFIFOW(fd,0) = 0xf8; // Storage Closed
- WFIFOSET(fd,packet_len(0xf8));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0xf8));
+ WFIFOW(fd,0) = 0xf8; // Storage Closed
+ WFIFOSET(fd,packet_len(0xf8));
}
/*==========================================
* Server tells 'sd' player client the abouts of 'dstsd' player
*------------------------------------------*/
-static void clif_getareachar_pc(struct map_session_data *sd,struct map_session_data *dstsd)
-{
- struct block_list *d_bl;
- int i;
-
- if (dstsd->chatID) {
- struct chat_data *cd = NULL;
- if ((cd = (struct chat_data *)map_id2bl(dstsd->chatID)) && cd->usersd[0]==dstsd)
- clif_dispchat(cd,sd->fd);
- } else if (dstsd->state.vending)
- clif_showvendingboard(&dstsd->bl,dstsd->message,sd->fd);
- else if (dstsd->state.buyingstore)
- clif_buyingstore_entry_single(sd, dstsd);
-
- if (dstsd->spiritball > 0)
- clif_spiritball_single(sd->fd, dstsd);
- for (i = 1; i < 5; i++) {
- if (dstsd->talisman[i] > 0)
- clif_talisman_single(sd->fd, dstsd, i);
- }
- if (dstsd->sc.option&OPTION_MOUNTING) {
- //New Mounts are not complaint to the original method, so we gotta tell this guy that I'm mounting.
- clif_status_load_single(sd->fd,dstsd->bl.id,SI_ALL_RIDING,2,1,0,0);
- }
+static void clif_getareachar_pc(struct map_session_data* sd,struct map_session_data* dstsd)
+{
+ struct block_list *d_bl;
+ int i;
+
+ if( dstsd->chatID ) {
+ struct chat_data *cd = NULL;
+ if( (cd = (struct chat_data*)map_id2bl(dstsd->chatID)) && cd->usersd[0]==dstsd)
+ clif_dispchat(cd,sd->fd);
+ } else if( dstsd->state.vending )
+ clif_showvendingboard(&dstsd->bl,dstsd->message,sd->fd);
+ else if( dstsd->state.buyingstore )
+ clif_buyingstore_entry_single(sd, dstsd);
+
+ if(dstsd->spiritball > 0)
+ clif_spiritball_single(sd->fd, dstsd);
+ for(i = 1; i < 5; i++){
+ if( dstsd->talisman[i] > 0 )
+ clif_talisman_single(sd->fd, dstsd, i);
+ }
+ if( dstsd->sc.option&OPTION_MOUNTING ) {
+ //New Mounts are not complaint to the original method, so we gotta tell this guy that I'm mounting.
+ clif_status_load_single(sd->fd,dstsd->bl.id,SI_ALL_RIDING,2,1,0,0);
+ }
#ifdef NEW_CARTS
- if (dstsd->sc.data[SC_PUSH_CART])
- clif_status_load_single(sd->fd, dstsd->bl.id, SI_ON_PUSH_CART, 2, dstsd->sc.data[SC_PUSH_CART]->val1, 0, 0);
+ if( dstsd->sc.data[SC_PUSH_CART] )
+ clif_status_load_single(sd->fd, dstsd->bl.id, SI_ON_PUSH_CART, 2, dstsd->sc.data[SC_PUSH_CART]->val1, 0, 0);
#endif
- if ((sd->status.party_id && dstsd->status.party_id == sd->status.party_id) || //Party-mate, or hpdisp setting.
- (sd->bg_id && sd->bg_id == dstsd->bg_id) || //BattleGround
- pc_has_permission(sd, PC_PERM_VIEW_HPMETER)
- )
- clif_hpmeter_single(sd->fd, dstsd->bl.id, dstsd->battle_status.hp, dstsd->battle_status.max_hp);
-
- // display link (sd - dstsd) to sd
- ARR_FIND(0, 5, i, sd->devotion[i] == dstsd->bl.id);
- if (i < 5) clif_devotion(&sd->bl, sd);
- // display links (dstsd - devotees) to sd
- ARR_FIND(0, 5, i, dstsd->devotion[i] > 0);
- if (i < 5) clif_devotion(&dstsd->bl, sd);
- // display link (dstsd - crusader) to sd
- if (dstsd->sc.data[SC_DEVOTION] && (d_bl = map_id2bl(dstsd->sc.data[SC_DEVOTION]->val1)) != NULL)
- clif_devotion(d_bl, sd);
-}
-
-void clif_getareachar_unit(struct map_session_data *sd,struct block_list *bl)
-{
- uint8 buf[128];
- struct unit_data *ud;
- struct view_data *vd;
- int len;
-
- vd = status_get_viewdata(bl);
- if (!vd || vd->class_ == INVISIBLE_CLASS)
- return;
-
- /**
- * Hide NPC from maya purple card.
- **/
- if (bl->type == BL_NPC && !((TBL_NPC *)bl)->chat_id && (((TBL_NPC *)bl)->sc.option&OPTION_INVISIBLE))
- return;
-
- ud = unit_bl2ud(bl);
- len = (ud && ud->walktimer != INVALID_TIMER) ? clif_set_unit_walking(bl,ud,buf) : clif_set_unit_idle(bl,buf,false);
- clif_send(buf,len,&sd->bl,SELF);
-
- if (vd->cloth_color)
- clif_refreshlook(&sd->bl,bl->id,LOOK_CLOTHES_COLOR,vd->cloth_color,SELF);
-
- switch (bl->type) {
- case BL_PC: {
- TBL_PC *tsd = (TBL_PC *)bl;
- clif_getareachar_pc(sd, tsd);
- if (tsd->state.size==SZ_BIG) // tiny/big players [Valaris]
- clif_specialeffect_single(bl,423,sd->fd);
- else if (tsd->state.size==SZ_MEDIUM)
- clif_specialeffect_single(bl,421,sd->fd);
- if (tsd->bg_id && map[tsd->bl.m].flag.battleground)
- clif_sendbgemblem_single(sd->fd,tsd);
- if (tsd->sc.data[SC_CAMOUFLAGE])
- clif_status_load(bl,SI_CAMOUFLAGE,1);
- }
- break;
- case BL_MER: // Devotion Effects
- if (((TBL_MER *)bl)->devotion_flag)
- clif_devotion(bl, sd);
- break;
- case BL_NPC: {
- TBL_NPC *nd = (TBL_NPC *)bl;
- if (nd->chat_id)
- clif_dispchat((struct chat_data *)map_id2bl(nd->chat_id),sd->fd);
- if (nd->size == SZ_BIG)
- clif_specialeffect_single(bl,423,sd->fd);
- else if (nd->size == SZ_MEDIUM)
- clif_specialeffect_single(bl,421,sd->fd);
- }
- break;
- case BL_MOB: {
- TBL_MOB *md = (TBL_MOB *)bl;
- if (md->special_state.size==SZ_BIG) // tiny/big mobs [Valaris]
- clif_specialeffect_single(bl,423,sd->fd);
- else if (md->special_state.size==SZ_MEDIUM)
- clif_specialeffect_single(bl,421,sd->fd);
+ if( (sd->status.party_id && dstsd->status.party_id == sd->status.party_id) || //Party-mate, or hpdisp setting.
+ (sd->bg_id && sd->bg_id == dstsd->bg_id) || //BattleGround
+ pc_has_permission(sd, PC_PERM_VIEW_HPMETER)
+ )
+ clif_hpmeter_single(sd->fd, dstsd->bl.id, dstsd->battle_status.hp, dstsd->battle_status.max_hp);
+
+ // display link (sd - dstsd) to sd
+ ARR_FIND( 0, 5, i, sd->devotion[i] == dstsd->bl.id );
+ if( i < 5 ) clif_devotion(&sd->bl, sd);
+ // display links (dstsd - devotees) to sd
+ ARR_FIND( 0, 5, i, dstsd->devotion[i] > 0 );
+ if( i < 5 ) clif_devotion(&dstsd->bl, sd);
+ // display link (dstsd - crusader) to sd
+ if( dstsd->sc.data[SC_DEVOTION] && (d_bl = map_id2bl(dstsd->sc.data[SC_DEVOTION]->val1)) != NULL )
+ clif_devotion(d_bl, sd);
+}
+
+void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl)
+{
+ uint8 buf[128];
+ struct unit_data *ud;
+ struct view_data *vd;
+ int len;
+
+ vd = status_get_viewdata(bl);
+ if (!vd || vd->class_ == INVISIBLE_CLASS)
+ return;
+
+ /**
+ * Hide NPC from maya purple card.
+ **/
+ if(bl->type == BL_NPC && !((TBL_NPC*)bl)->chat_id && (((TBL_NPC*)bl)->sc.option&OPTION_INVISIBLE))
+ return;
+
+ ud = unit_bl2ud(bl);
+ len = ( ud && ud->walktimer != INVALID_TIMER ) ? clif_set_unit_walking(bl,ud,buf) : clif_set_unit_idle(bl,buf,false);
+ clif_send(buf,len,&sd->bl,SELF);
+
+ if (vd->cloth_color)
+ clif_refreshlook(&sd->bl,bl->id,LOOK_CLOTHES_COLOR,vd->cloth_color,SELF);
+
+ switch (bl->type)
+ {
+ case BL_PC:
+ {
+ TBL_PC* tsd = (TBL_PC*)bl;
+ clif_getareachar_pc(sd, tsd);
+ if(tsd->state.size==SZ_BIG) // tiny/big players [Valaris]
+ clif_specialeffect_single(bl,423,sd->fd);
+ else if(tsd->state.size==SZ_MEDIUM)
+ clif_specialeffect_single(bl,421,sd->fd);
+ if( tsd->bg_id && map[tsd->bl.m].flag.battleground )
+ clif_sendbgemblem_single(sd->fd,tsd);
+ if( tsd->sc.data[SC_CAMOUFLAGE] )
+ clif_status_load(bl,SI_CAMOUFLAGE,1);
+ }
+ break;
+ case BL_MER: // Devotion Effects
+ if( ((TBL_MER*)bl)->devotion_flag )
+ clif_devotion(bl, sd);
+ break;
+ case BL_NPC:
+ {
+ TBL_NPC* nd = (TBL_NPC*)bl;
+ if( nd->chat_id )
+ clif_dispchat((struct chat_data*)map_id2bl(nd->chat_id),sd->fd);
+ if( nd->size == SZ_BIG )
+ clif_specialeffect_single(bl,423,sd->fd);
+ else if( nd->size == SZ_MEDIUM )
+ clif_specialeffect_single(bl,421,sd->fd);
+ }
+ break;
+ case BL_MOB:
+ {
+ TBL_MOB* md = (TBL_MOB*)bl;
+ if(md->special_state.size==SZ_BIG) // tiny/big mobs [Valaris]
+ clif_specialeffect_single(bl,423,sd->fd);
+ else if(md->special_state.size==SZ_MEDIUM)
+ clif_specialeffect_single(bl,421,sd->fd);
#if PACKETVER >= 20120404
- if (!(md->status.mode&MD_BOSS)) {
- int i;
- for (i = 0; i < DAMAGELOG_SIZE; i++) // must show hp bar to all char who already hit the mob.
- if (md->dmglog[i].id == sd->status.char_id)
- clif_monster_hp_bar(md, sd->fd);
- }
+ if( !(md->status.mode&MD_BOSS) ){
+ int i;
+ for(i = 0; i < DAMAGELOG_SIZE; i++)// must show hp bar to all char who already hit the mob.
+ if( md->dmglog[i].id == sd->status.char_id )
+ clif_monster_hp_bar(md, sd->fd);
+ }
#endif
- }
- break;
- case BL_PET:
- if (vd->head_bottom)
- clif_pet_equip(sd, (TBL_PET *)bl); // needed to display pet equip properly
- break;
- }
+ }
+ break;
+ case BL_PET:
+ if (vd->head_bottom)
+ clif_pet_equip(sd, (TBL_PET*)bl); // needed to display pet equip properly
+ break;
+ }
}
//Modifies the type of damage according to status changes [Skotlex]
//Aegis data specifies that: 4 endure against single hit sources, 9 against multi-hit.
static inline int clif_calc_delay(int type, int div, int damage, int delay)
{
- return (delay == 0 && damage > 0) ? (div > 1 ? 9 : 4) : type;
+ return ( delay == 0 && damage > 0 ) ? ( div > 1 ? 9 : 4 ) : type;
}
/*==========================================
@@ -4113,19 +4165,20 @@ static inline int clif_calc_delay(int type, int div, int damage, int delay)
*------------------------------------------*/
static int clif_calc_walkdelay(struct block_list *bl,int delay, int type, int damage, int div_)
{
- if (type == 4 || type == 9 || damage <=0)
- return 0;
+ if (type == 4 || type == 9 || damage <=0)
+ return 0;
- if (bl->type == BL_PC) {
- if (battle_config.pc_walk_delay_rate != 100)
- delay = delay*battle_config.pc_walk_delay_rate/100;
- } else if (battle_config.walk_delay_rate != 100)
- delay = delay*battle_config.walk_delay_rate/100;
+ if (bl->type == BL_PC) {
+ if (battle_config.pc_walk_delay_rate != 100)
+ delay = delay*battle_config.pc_walk_delay_rate/100;
+ } else
+ if (battle_config.walk_delay_rate != 100)
+ delay = delay*battle_config.walk_delay_rate/100;
- if (div_ > 1) //Multi-hit skills mean higher delays.
- delay += battle_config.multihit_delay*(div_-1);
+ if (div_ > 1) //Multi-hit skills mean higher delays.
+ delay += battle_config.multihit_delay*(div_-1);
- return delay>0?delay:1; //Return 1 to specify there should be no noticeable delay, but you should stop walking.
+ return delay>0?delay:1; //Return 1 to specify there should be no noticeable delay, but you should stop walking.
}
@@ -4146,138 +4199,138 @@ static int clif_calc_walkdelay(struct block_list *bl,int delay, int type, int da
/// 10 = critical hit
/// 11 = lucky dodge
/// 12 = (touch skill?)
-int clif_damage(struct block_list *src, struct block_list *dst, unsigned int tick, int sdelay, int ddelay, int damage, int div, int type, int damage2)
+int clif_damage(struct block_list* src, struct block_list* dst, unsigned int tick, int sdelay, int ddelay, int damage, int div, int type, int damage2)
{
- unsigned char buf[33];
- struct status_change *sc;
+ unsigned char buf[33];
+ struct status_change *sc;
#if PACKETVER < 20071113
- const int cmd = 0x8a;
+ const int cmd = 0x8a;
#else
- const int cmd = 0x2e1;
+ const int cmd = 0x2e1;
#endif
- nullpo_ret(src);
- nullpo_ret(dst);
-
- type = clif_calc_delay(type,div,damage+damage2,ddelay);
- sc = status_get_sc(dst);
- if (sc && sc->count) {
- if (sc->data[SC_HALLUCINATION]) {
- if (damage) damage = damage*(sc->data[SC_HALLUCINATION]->val2) + rnd()%100;
- if (damage2) damage2 = damage2*(sc->data[SC_HALLUCINATION]->val2) + rnd()%100;
- }
- }
-
- WBUFW(buf,0)=cmd;
- WBUFL(buf,2)=src->id;
- WBUFL(buf,6)=dst->id;
- WBUFL(buf,10)=tick;
- WBUFL(buf,14)=sdelay;
- WBUFL(buf,18)=ddelay;
+ nullpo_ret(src);
+ nullpo_ret(dst);
+
+ type = clif_calc_delay(type,div,damage+damage2,ddelay);
+ sc = status_get_sc(dst);
+ if(sc && sc->count) {
+ if(sc->data[SC_HALLUCINATION]) {
+ if(damage) damage = damage*(sc->data[SC_HALLUCINATION]->val2) + rnd()%100;
+ if(damage2) damage2 = damage2*(sc->data[SC_HALLUCINATION]->val2) + rnd()%100;
+ }
+ }
+
+ WBUFW(buf,0)=cmd;
+ WBUFL(buf,2)=src->id;
+ WBUFL(buf,6)=dst->id;
+ WBUFL(buf,10)=tick;
+ WBUFL(buf,14)=sdelay;
+ WBUFL(buf,18)=ddelay;
#if PACKETVER < 20071113
- if (battle_config.hide_woe_damage && map_flag_gvg(src->m)) {
- WBUFW(buf,22)=damage?div:0;
- WBUFW(buf,27)=damage2?div:0;
- } else {
- WBUFW(buf,22)=min(damage, INT16_MAX);
- WBUFW(buf,27)=damage2;
- }
- WBUFW(buf,24)=div;
- WBUFB(buf,26)=type;
+ if (battle_config.hide_woe_damage && map_flag_gvg(src->m)) {
+ WBUFW(buf,22)=damage?div:0;
+ WBUFW(buf,27)=damage2?div:0;
+ } else {
+ WBUFW(buf,22)=min(damage, INT16_MAX);
+ WBUFW(buf,27)=damage2;
+ }
+ WBUFW(buf,24)=div;
+ WBUFB(buf,26)=type;
#else
- if (battle_config.hide_woe_damage && map_flag_gvg(src->m)) {
- WBUFL(buf,22)=damage?div:0;
- WBUFL(buf,29)=damage2?div:0;
- } else {
- WBUFL(buf,22)=damage;
- WBUFL(buf,29)=damage2;
- }
- WBUFW(buf,26)=div;
- WBUFB(buf,28)=type;
+ if (battle_config.hide_woe_damage && map_flag_gvg(src->m)) {
+ WBUFL(buf,22)=damage?div:0;
+ WBUFL(buf,29)=damage2?div:0;
+ } else {
+ WBUFL(buf,22)=damage;
+ WBUFL(buf,29)=damage2;
+ }
+ WBUFW(buf,26)=div;
+ WBUFB(buf,28)=type;
#endif
- if (disguised(dst)) {
- clif_send(buf,packet_len(cmd),dst,AREA_WOS);
- WBUFL(buf,6) = -dst->id;
- clif_send(buf,packet_len(cmd),dst,SELF);
- } else
- clif_send(buf,packet_len(cmd),dst,AREA);
-
- if (disguised(src)) {
- WBUFL(buf,2) = -src->id;
- if (disguised(dst))
- WBUFL(buf,6) = dst->id;
+ if(disguised(dst)) {
+ clif_send(buf,packet_len(cmd),dst,AREA_WOS);
+ WBUFL(buf,6) = -dst->id;
+ clif_send(buf,packet_len(cmd),dst,SELF);
+ } else
+ clif_send(buf,packet_len(cmd),dst,AREA);
+
+ if(disguised(src)) {
+ WBUFL(buf,2) = -src->id;
+ if (disguised(dst))
+ WBUFL(buf,6) = dst->id;
#if PACKETVER < 20071113
- if (damage > 0) WBUFW(buf,22) = -1;
- if (damage2 > 0) WBUFW(buf,27) = -1;
+ if(damage > 0) WBUFW(buf,22) = -1;
+ if(damage2 > 0) WBUFW(buf,27) = -1;
#else
- if (damage > 0) WBUFL(buf,22) = -1;
- if (damage2 > 0) WBUFL(buf,29) = -1;
+ if(damage > 0) WBUFL(buf,22) = -1;
+ if(damage2 > 0) WBUFL(buf,29) = -1;
#endif
- clif_send(buf,packet_len(cmd),src,SELF);
- }
+ clif_send(buf,packet_len(cmd),src,SELF);
+ }
- if (src == dst) {
- unit_setdir(src,unit_getdir(src));
- }
- //Return adjusted can't walk delay for further processing.
- return clif_calc_walkdelay(dst,ddelay,type,damage+damage2,div);
+ if(src == dst) {
+ unit_setdir(src,unit_getdir(src));
+ }
+ //Return adjusted can't walk delay for further processing.
+ return clif_calc_walkdelay(dst,ddelay,type,damage+damage2,div);
}
/*==========================================
* src picks up dst
*------------------------------------------*/
-void clif_takeitem(struct block_list *src, struct block_list *dst)
+void clif_takeitem(struct block_list* src, struct block_list* dst)
{
- //clif_damage(src,dst,0,0,0,0,0,1,0);
- unsigned char buf[32];
+ //clif_damage(src,dst,0,0,0,0,0,1,0);
+ unsigned char buf[32];
- nullpo_retv(src);
- nullpo_retv(dst);
+ nullpo_retv(src);
+ nullpo_retv(dst);
- WBUFW(buf, 0) = 0x8a;
- WBUFL(buf, 2) = src->id;
- WBUFL(buf, 6) = dst->id;
- WBUFB(buf,26) = 1;
- clif_send(buf, packet_len(0x8a), src, AREA);
+ WBUFW(buf, 0) = 0x8a;
+ WBUFL(buf, 2) = src->id;
+ WBUFL(buf, 6) = dst->id;
+ WBUFB(buf,26) = 1;
+ clif_send(buf, packet_len(0x8a), src, AREA);
}
/*==========================================
* inform clients in area that `bl` is sitting
*------------------------------------------*/
-void clif_sitting(struct block_list *bl)
+void clif_sitting(struct block_list* bl)
{
- unsigned char buf[32];
- nullpo_retv(bl);
+ unsigned char buf[32];
+ nullpo_retv(bl);
- WBUFW(buf, 0) = 0x8a;
- WBUFL(buf, 2) = bl->id;
- WBUFB(buf,26) = 2;
- clif_send(buf, packet_len(0x8a), bl, AREA);
+ WBUFW(buf, 0) = 0x8a;
+ WBUFL(buf, 2) = bl->id;
+ WBUFB(buf,26) = 2;
+ clif_send(buf, packet_len(0x8a), bl, AREA);
- if (disguised(bl)) {
- WBUFL(buf, 2) = - bl->id;
- clif_send(buf, packet_len(0x8a), bl, SELF);
- }
+ if(disguised(bl)) {
+ WBUFL(buf, 2) = - bl->id;
+ clif_send(buf, packet_len(0x8a), bl, SELF);
+ }
}
/*==========================================
* inform clients in area that `bl` is standing
*------------------------------------------*/
-void clif_standing(struct block_list *bl)
+void clif_standing(struct block_list* bl)
{
- unsigned char buf[32];
- nullpo_retv(bl);
+ unsigned char buf[32];
+ nullpo_retv(bl);
- WBUFW(buf, 0) = 0x8a;
- WBUFL(buf, 2) = bl->id;
- WBUFB(buf,26) = 3;
- clif_send(buf, packet_len(0x8a), bl, AREA);
+ WBUFW(buf, 0) = 0x8a;
+ WBUFL(buf, 2) = bl->id;
+ WBUFB(buf,26) = 3;
+ clif_send(buf, packet_len(0x8a), bl, AREA);
- if (disguised(bl)) {
- WBUFL(buf, 2) = - bl->id;
- clif_send(buf, packet_len(0x8a), bl, SELF);
- }
+ if(disguised(bl)) {
+ WBUFL(buf, 2) = - bl->id;
+ clif_send(buf, packet_len(0x8a), bl, SELF);
+ }
}
@@ -4285,50 +4338,53 @@ void clif_standing(struct block_list *bl)
/// 0192 <x>.W <y>.W <type>.W <map name>.16B
void clif_changemapcell(int fd, int m, int x, int y, int type, enum send_target target)
{
- unsigned char buf[32];
-
- WBUFW(buf,0) = 0x192;
- WBUFW(buf,2) = x;
- WBUFW(buf,4) = y;
- WBUFW(buf,6) = type;
- mapindex_getmapname_ext(map[m].name,(char *)WBUFP(buf,8));
-
- if (fd) {
- WFIFOHEAD(fd,packet_len(0x192));
- memcpy(WFIFOP(fd,0), buf, packet_len(0x192));
- WFIFOSET(fd,packet_len(0x192));
- } else {
- struct block_list dummy_bl;
- dummy_bl.type = BL_NUL;
- dummy_bl.x = x;
- dummy_bl.y = y;
- dummy_bl.m = m;
- clif_send(buf,packet_len(0x192),&dummy_bl,target);
- }
+ unsigned char buf[32];
+
+ WBUFW(buf,0) = 0x192;
+ WBUFW(buf,2) = x;
+ WBUFW(buf,4) = y;
+ WBUFW(buf,6) = type;
+ mapindex_getmapname_ext(map[m].name,(char*)WBUFP(buf,8));
+
+ if( fd )
+ {
+ WFIFOHEAD(fd,packet_len(0x192));
+ memcpy(WFIFOP(fd,0), buf, packet_len(0x192));
+ WFIFOSET(fd,packet_len(0x192));
+ }
+ else
+ {
+ struct block_list dummy_bl;
+ dummy_bl.type = BL_NUL;
+ dummy_bl.x = x;
+ dummy_bl.y = y;
+ dummy_bl.m = m;
+ clif_send(buf,packet_len(0x192),&dummy_bl,target);
+ }
}
/// Notifies the client about an item on floor (ZC_ITEM_ENTRY).
/// 009d <id>.L <name id>.W <identified>.B <x>.W <y>.W <amount>.W <subX>.B <subY>.B
-void clif_getareachar_item(struct map_session_data *sd,struct flooritem_data *fitem)
+void clif_getareachar_item(struct map_session_data* sd,struct flooritem_data* fitem)
{
- int view,fd;
- fd=sd->fd;
+ int view,fd;
+ fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x9d));
- WFIFOW(fd,0)=0x9d;
- WFIFOL(fd,2)=fitem->bl.id;
- if ((view = itemdb_viewid(fitem->item_data.nameid)) > 0)
- WFIFOW(fd,6)=view;
- else
- WFIFOW(fd,6)=fitem->item_data.nameid;
- WFIFOB(fd,8)=fitem->item_data.identify;
- WFIFOW(fd,9)=fitem->bl.x;
- WFIFOW(fd,11)=fitem->bl.y;
- WFIFOW(fd,13)=fitem->item_data.amount;
- WFIFOB(fd,15)=fitem->subx;
- WFIFOB(fd,16)=fitem->suby;
- WFIFOSET(fd,packet_len(0x9d));
+ WFIFOHEAD(fd,packet_len(0x9d));
+ WFIFOW(fd,0)=0x9d;
+ WFIFOL(fd,2)=fitem->bl.id;
+ if((view = itemdb_viewid(fitem->item_data.nameid)) > 0)
+ WFIFOW(fd,6)=view;
+ else
+ WFIFOW(fd,6)=fitem->item_data.nameid;
+ WFIFOB(fd,8)=fitem->item_data.identify;
+ WFIFOW(fd,9)=fitem->bl.x;
+ WFIFOW(fd,11)=fitem->bl.y;
+ WFIFOW(fd,13)=fitem->item_data.amount;
+ WFIFOB(fd,15)=fitem->subx;
+ WFIFOB(fd,16)=fitem->suby;
+ WFIFOSET(fd,packet_len(0x9d));
}
@@ -4337,44 +4393,44 @@ void clif_getareachar_item(struct map_session_data *sd,struct flooritem_data *fi
/// 01c9 <id>.L <creator id>.L <x>.W <y>.W <unit id>.B <visible>.B <has msg>.B <msg>.80B (ZC_SKILL_ENTRY2)
static void clif_getareachar_skillunit(struct map_session_data *sd, struct skill_unit *unit)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- if (unit->group->state.guildaura)
- return;
+ if( unit->group->state.guildaura )
+ return;
#if PACKETVER >= 3
- if (unit->group->unit_id==UNT_GRAFFITI) { // Graffiti [Valaris]
- WFIFOHEAD(fd,packet_len(0x1c9));
- WFIFOW(fd, 0)=0x1c9;
- WFIFOL(fd, 2)=unit->bl.id;
- WFIFOL(fd, 6)=unit->group->src_id;
- WFIFOW(fd,10)=unit->bl.x;
- WFIFOW(fd,12)=unit->bl.y;
- WFIFOB(fd,14)=unit->group->unit_id;
- WFIFOB(fd,15)=1;
- WFIFOB(fd,16)=1;
- safestrncpy((char *)WFIFOP(fd,17),unit->group->valstr,MESSAGE_SIZE);
- WFIFOSET(fd,packet_len(0x1c9));
- return;
- }
+ if(unit->group->unit_id==UNT_GRAFFITI) { // Graffiti [Valaris]
+ WFIFOHEAD(fd,packet_len(0x1c9));
+ WFIFOW(fd, 0)=0x1c9;
+ WFIFOL(fd, 2)=unit->bl.id;
+ WFIFOL(fd, 6)=unit->group->src_id;
+ WFIFOW(fd,10)=unit->bl.x;
+ WFIFOW(fd,12)=unit->bl.y;
+ WFIFOB(fd,14)=unit->group->unit_id;
+ WFIFOB(fd,15)=1;
+ WFIFOB(fd,16)=1;
+ safestrncpy((char*)WFIFOP(fd,17),unit->group->valstr,MESSAGE_SIZE);
+ WFIFOSET(fd,packet_len(0x1c9));
+ return;
+ }
#endif
- WFIFOHEAD(fd,packet_len(0x11f));
- WFIFOW(fd, 0)=0x11f;
- WFIFOL(fd, 2)=unit->bl.id;
- WFIFOL(fd, 6)=unit->group->src_id;
- WFIFOW(fd,10)=unit->bl.x;
- WFIFOW(fd,12)=unit->bl.y;
- if (battle_config.traps_setting&1 && skill_get_inf2(unit->group->skill_id)&INF2_TRAP)
- WFIFOB(fd,14)=UNT_DUMMYSKILL; //Use invisible unit id for traps.
+ WFIFOHEAD(fd,packet_len(0x11f));
+ WFIFOW(fd, 0)=0x11f;
+ WFIFOL(fd, 2)=unit->bl.id;
+ WFIFOL(fd, 6)=unit->group->src_id;
+ WFIFOW(fd,10)=unit->bl.x;
+ WFIFOW(fd,12)=unit->bl.y;
+ if (battle_config.traps_setting&1 && skill_get_inf2(unit->group->skill_id)&INF2_TRAP)
+ WFIFOB(fd,14)=UNT_DUMMYSKILL; //Use invisible unit id for traps.
else if (skill_get_unit_flag(unit->group->skill_id) & UF_RANGEDSINGLEUNIT && !(unit->val2 & UF_RANGEDSINGLEUNIT))
- WFIFOB(fd,14)=UNT_DUMMYSKILL; //Use invisible unit id for traps.
- else
- WFIFOB(fd,14)=unit->group->unit_id;
- WFIFOB(fd,15)=1; // ignored by client (always gets set to 1)
- WFIFOSET(fd,packet_len(0x11f));
+ WFIFOB(fd,14)=UNT_DUMMYSKILL; //Use invisible unit id for traps.
+ else
+ WFIFOB(fd,14)=unit->group->unit_id;
+ WFIFOB(fd,15)=1; // ignored by client (always gets set to 1)
+ WFIFOSET(fd,packet_len(0x11f));
- if (unit->group->skill_id == WZ_ICEWALL)
- clif_changemapcell(fd,unit->bl.m,unit->bl.x,unit->bl.y,5,SELF);
+ if(unit->group->skill_id == WZ_ICEWALL)
+ clif_changemapcell(fd,unit->bl.m,unit->bl.x,unit->bl.y,5,SELF);
}
@@ -4383,15 +4439,15 @@ static void clif_getareachar_skillunit(struct map_session_data *sd, struct skill
*------------------------------------------*/
static void clif_clearchar_skillunit(struct skill_unit *unit, int fd)
{
- nullpo_retv(unit);
+ nullpo_retv(unit);
- WFIFOHEAD(fd,packet_len(0x120));
- WFIFOW(fd, 0)=0x120;
- WFIFOL(fd, 2)=unit->bl.id;
- WFIFOSET(fd,packet_len(0x120));
+ WFIFOHEAD(fd,packet_len(0x120));
+ WFIFOW(fd, 0)=0x120;
+ WFIFOL(fd, 2)=unit->bl.id;
+ WFIFOSET(fd,packet_len(0x120));
- if (unit->group && unit->group->skill_id == WZ_ICEWALL)
- clif_changemapcell(fd,unit->bl.m,unit->bl.x,unit->bl.y,unit->val2,SELF);
+ if(unit->group && unit->group->skill_id == WZ_ICEWALL)
+ clif_changemapcell(fd,unit->bl.m,unit->bl.x,unit->bl.y,unit->val2,SELF);
}
@@ -4399,59 +4455,59 @@ static void clif_clearchar_skillunit(struct skill_unit *unit, int fd)
/// 0120 <id>.L
void clif_skill_delunit(struct skill_unit *unit)
{
- unsigned char buf[16];
+ unsigned char buf[16];
- nullpo_retv(unit);
+ nullpo_retv(unit);
- WBUFW(buf, 0)=0x120;
- WBUFL(buf, 2)=unit->bl.id;
- clif_send(buf,packet_len(0x120),&unit->bl,AREA);
+ WBUFW(buf, 0)=0x120;
+ WBUFL(buf, 2)=unit->bl.id;
+ clif_send(buf,packet_len(0x120),&unit->bl,AREA);
}
/// Sent when an object gets ankle-snared (ZC_SKILL_UPDATE).
/// 01ac <id>.L
/// Only affects units with class [139,153] client-side.
-void clif_skillunit_update(struct block_list *bl)
+void clif_skillunit_update(struct block_list* bl)
{
- unsigned char buf[6];
- nullpo_retv(bl);
+ unsigned char buf[6];
+ nullpo_retv(bl);
- WBUFW(buf,0) = 0x1ac;
- WBUFL(buf,2) = bl->id;
+ WBUFW(buf,0) = 0x1ac;
+ WBUFL(buf,2) = bl->id;
- clif_send(buf,packet_len(0x1ac),bl,AREA);
+ clif_send(buf,packet_len(0x1ac),bl,AREA);
}
/*==========================================
*
*------------------------------------------*/
-static int clif_getareachar(struct block_list *bl,va_list ap)
+static int clif_getareachar(struct block_list* bl,va_list ap)
{
- struct map_session_data *sd;
+ struct map_session_data *sd;
- nullpo_ret(bl);
+ nullpo_ret(bl);
- sd=va_arg(ap,struct map_session_data *);
+ sd=va_arg(ap,struct map_session_data*);
- if (sd == NULL || !sd->fd)
- return 0;
+ if (sd == NULL || !sd->fd)
+ return 0;
- switch (bl->type) {
- case BL_ITEM:
- clif_getareachar_item(sd,(struct flooritem_data *) bl);
- break;
- case BL_SKILL:
- clif_getareachar_skillunit(sd,(TBL_SKILL *)bl);
- break;
- default:
- if (&sd->bl == bl)
- break;
- clif_getareachar_unit(sd,bl);
- break;
- }
- return 0;
+ switch(bl->type){
+ case BL_ITEM:
+ clif_getareachar_item(sd,(struct flooritem_data*) bl);
+ break;
+ case BL_SKILL:
+ clif_getareachar_skillunit(sd,(TBL_SKILL*)bl);
+ break;
+ default:
+ if(&sd->bl == bl)
+ break;
+ clif_getareachar_unit(sd,bl);
+ break;
+ }
+ return 0;
}
/*==========================================
@@ -4459,54 +4515,54 @@ static int clif_getareachar(struct block_list *bl,va_list ap)
*------------------------------------------*/
int clif_outsight(struct block_list *bl,va_list ap)
{
- struct block_list *tbl;
- struct view_data *vd;
- TBL_PC *sd, *tsd;
- tbl=va_arg(ap,struct block_list *);
- if (bl == tbl) return 0;
- sd = BL_CAST(BL_PC, bl);
- tsd = BL_CAST(BL_PC, tbl);
-
- if (tsd && tsd->fd) {
- //tsd has lost sight of the bl object.
- switch (bl->type) {
- case BL_PC:
- if (sd->vd.class_ != INVISIBLE_CLASS)
- clif_clearunit_single(bl->id,CLR_OUTSIGHT,tsd->fd);
- if (sd->chatID) {
- struct chat_data *cd;
- cd=(struct chat_data *)map_id2bl(sd->chatID);
- if (cd->usersd[0]==sd)
- clif_dispchat(cd,tsd->fd);
- }
- if (sd->state.vending)
- clif_closevendingboard(bl,tsd->fd);
- if (sd->state.buyingstore)
- clif_buyingstore_disappear_entry_single(tsd, sd);
- break;
- case BL_ITEM:
- clif_clearflooritem((struct flooritem_data *)bl,tsd->fd);
- break;
- case BL_SKILL:
- clif_clearchar_skillunit((struct skill_unit *)bl,tsd->fd);
- break;
- case BL_NPC:
- if (!(((TBL_NPC *)bl)->sc.option&OPTION_INVISIBLE))
- clif_clearunit_single(bl->id,CLR_OUTSIGHT,tsd->fd);
- break;
- default:
- if ((vd=status_get_viewdata(bl)) && vd->class_ != INVISIBLE_CLASS)
- clif_clearunit_single(bl->id,CLR_OUTSIGHT,tsd->fd);
- break;
- }
- }
- if (sd && sd->fd) {
- //sd is watching tbl go out of view.
- if (((vd=status_get_viewdata(tbl)) && vd->class_ != INVISIBLE_CLASS) &&
- !(tbl->type == BL_NPC && (((TBL_NPC *)tbl)->sc.option&OPTION_INVISIBLE)))
- clif_clearunit_single(tbl->id,CLR_OUTSIGHT,sd->fd);
- }
- return 0;
+ struct block_list *tbl;
+ struct view_data *vd;
+ TBL_PC *sd, *tsd;
+ tbl=va_arg(ap,struct block_list*);
+ if(bl == tbl) return 0;
+ sd = BL_CAST(BL_PC, bl);
+ tsd = BL_CAST(BL_PC, tbl);
+
+ if (tsd && tsd->fd)
+ { //tsd has lost sight of the bl object.
+ switch(bl->type){
+ case BL_PC:
+ if (sd->vd.class_ != INVISIBLE_CLASS)
+ clif_clearunit_single(bl->id,CLR_OUTSIGHT,tsd->fd);
+ if(sd->chatID){
+ struct chat_data *cd;
+ cd=(struct chat_data*)map_id2bl(sd->chatID);
+ if(cd->usersd[0]==sd)
+ clif_dispchat(cd,tsd->fd);
+ }
+ if( sd->state.vending )
+ clif_closevendingboard(bl,tsd->fd);
+ if( sd->state.buyingstore )
+ clif_buyingstore_disappear_entry_single(tsd, sd);
+ break;
+ case BL_ITEM:
+ clif_clearflooritem((struct flooritem_data*)bl,tsd->fd);
+ break;
+ case BL_SKILL:
+ clif_clearchar_skillunit((struct skill_unit *)bl,tsd->fd);
+ break;
+ case BL_NPC:
+ if( !(((TBL_NPC*)bl)->sc.option&OPTION_INVISIBLE) )
+ clif_clearunit_single(bl->id,CLR_OUTSIGHT,tsd->fd);
+ break;
+ default:
+ if ((vd=status_get_viewdata(bl)) && vd->class_ != INVISIBLE_CLASS)
+ clif_clearunit_single(bl->id,CLR_OUTSIGHT,tsd->fd);
+ break;
+ }
+ }
+ if (sd && sd->fd)
+ { //sd is watching tbl go out of view.
+ if (((vd=status_get_viewdata(tbl)) && vd->class_ != INVISIBLE_CLASS) &&
+ !(tbl->type == BL_NPC && (((TBL_NPC*)tbl)->sc.option&OPTION_INVISIBLE)))
+ clif_clearunit_single(tbl->id,CLR_OUTSIGHT,sd->fd);
+ }
+ return 0;
}
/*==========================================
@@ -4514,34 +4570,34 @@ int clif_outsight(struct block_list *bl,va_list ap)
*------------------------------------------*/
int clif_insight(struct block_list *bl,va_list ap)
{
- struct block_list *tbl;
- TBL_PC *sd, *tsd;
- tbl=va_arg(ap,struct block_list *);
-
- if (bl == tbl) return 0;
-
- sd = BL_CAST(BL_PC, bl);
- tsd = BL_CAST(BL_PC, tbl);
-
- if (tsd && tsd->fd) {
- //Tell tsd that bl entered into his view
- switch (bl->type) {
- case BL_ITEM:
- clif_getareachar_item(tsd,(struct flooritem_data *)bl);
- break;
- case BL_SKILL:
- clif_getareachar_skillunit(tsd,(TBL_SKILL *)bl);
- break;
- default:
- clif_getareachar_unit(tsd,bl);
- break;
- }
- }
- if (sd && sd->fd) {
- //Tell sd that tbl walked into his view
- clif_getareachar_unit(sd,tbl);
- }
- return 0;
+ struct block_list *tbl;
+ TBL_PC *sd, *tsd;
+ tbl=va_arg(ap,struct block_list*);
+
+ if (bl == tbl) return 0;
+
+ sd = BL_CAST(BL_PC, bl);
+ tsd = BL_CAST(BL_PC, tbl);
+
+ if (tsd && tsd->fd)
+ { //Tell tsd that bl entered into his view
+ switch(bl->type){
+ case BL_ITEM:
+ clif_getareachar_item(tsd,(struct flooritem_data*)bl);
+ break;
+ case BL_SKILL:
+ clif_getareachar_skillunit(tsd,(TBL_SKILL*)bl);
+ break;
+ default:
+ clif_getareachar_unit(tsd,bl);
+ break;
+ }
+ }
+ if (sd && sd->fd)
+ { //Tell sd that tbl walked into his view
+ clif_getareachar_unit(sd,tbl);
+ }
+ return 0;
}
@@ -4549,45 +4605,49 @@ int clif_insight(struct block_list *bl,va_list ap)
/// 010f <packet len>.W { <skill id>.W <type>.L <level>.W <sp cost>.W <attack range>.W <skill name>.24B <upgradable>.B }*
void clif_skillinfoblock(struct map_session_data *sd)
{
- int fd;
- int i,len,id;
-
- nullpo_retv(sd);
-
- fd=sd->fd;
- if (!fd) return;
-
- WFIFOHEAD(fd, MAX_SKILL * 37 + 4);
- WFIFOW(fd,0) = 0x10f;
- for (i = 0, len = 4; i < MAX_SKILL; i++) {
- if ((id = sd->status.skill[i].id) != 0) {
- // workaround for bugreport:5348
- if (len + 37 > 8192)
- break;
-
- WFIFOW(fd,len) = id;
- WFIFOL(fd,len+2) = skill_get_inf(id);
- WFIFOW(fd,len+6) = sd->status.skill[i].lv;
- WFIFOW(fd,len+8) = skill_get_sp(id,sd->status.skill[i].lv);
- WFIFOW(fd,len+10)= skill_get_range2(&sd->bl, id,sd->status.skill[i].lv);
- safestrncpy((char *)WFIFOP(fd,len+12), skill_get_name(id), NAME_LENGTH);
- if (sd->status.skill[i].flag == SKILL_FLAG_PERMANENT)
- WFIFOB(fd,len+36) = (sd->status.skill[i].lv < skill_tree_get_max(id, sd->status.class_))? 1:0;
- else
- WFIFOB(fd,len+36) = 0;
- len += 37;
- }
- }
- WFIFOW(fd,2)=len;
- WFIFOSET(fd,len);
-
- // workaround for bugreport:5348; send the remaining skills one by one to bypass packet size limit
- for (; i < MAX_SKILL; i++) {
- if ((id = sd->status.skill[i].id) != 0) {
- clif_addskill(sd, id);
- clif_skillinfo(sd, id, 0);
- }
- }
+ int fd;
+ int i,len,id;
+
+ nullpo_retv(sd);
+
+ fd=sd->fd;
+ if (!fd) return;
+
+ WFIFOHEAD(fd, MAX_SKILL * 37 + 4);
+ WFIFOW(fd,0) = 0x10f;
+ for ( i = 0, len = 4; i < MAX_SKILL; i++)
+ {
+ if( (id = sd->status.skill[i].id) != 0 )
+ {
+ // workaround for bugreport:5348
+ if (len + 37 > 8192)
+ break;
+
+ WFIFOW(fd,len) = id;
+ WFIFOL(fd,len+2) = skill_get_inf(id);
+ WFIFOW(fd,len+6) = sd->status.skill[i].lv;
+ WFIFOW(fd,len+8) = skill_get_sp(id,sd->status.skill[i].lv);
+ WFIFOW(fd,len+10)= skill_get_range2(&sd->bl, id,sd->status.skill[i].lv);
+ safestrncpy((char*)WFIFOP(fd,len+12), skill_get_name(id), NAME_LENGTH);
+ if(sd->status.skill[i].flag == SKILL_FLAG_PERMANENT)
+ WFIFOB(fd,len+36) = (sd->status.skill[i].lv < skill_tree_get_max(id, sd->status.class_))? 1:0;
+ else
+ WFIFOB(fd,len+36) = 0;
+ len += 37;
+ }
+ }
+ WFIFOW(fd,2)=len;
+ WFIFOSET(fd,len);
+
+ // workaround for bugreport:5348; send the remaining skills one by one to bypass packet size limit
+ for ( ; i < MAX_SKILL; i++)
+ {
+ if( (id = sd->status.skill[i].id) != 0 )
+ {
+ clif_addskill(sd, id);
+ clif_skillinfo(sd, id, 0);
+ }
+ }
}
/**
* Server tells client 'sd' to add skill of id 'id' to it's skill tree (e.g. with Ice Falcion item)
@@ -4597,29 +4657,29 @@ void clif_skillinfoblock(struct map_session_data *sd)
/// 0111 <skill id>.W <type>.L <level>.W <sp cost>.W <attack range>.W <skill name>.24B <upgradable>.B
void clif_addskill(struct map_session_data *sd, int id)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd = sd->fd;
- if (!fd) return;
-
- if (sd->status.skill[id].id <= 0)
- return;
-
- WFIFOHEAD(fd, packet_len(0x111));
- WFIFOW(fd,0) = 0x111;
- WFIFOW(fd,2) = id;
- WFIFOL(fd,4) = skill_get_inf(id);
- WFIFOW(fd,8) = sd->status.skill[id].lv;
- WFIFOW(fd,10) = skill_get_sp(id,sd->status.skill[id].lv);
- WFIFOW(fd,12)= skill_get_range2(&sd->bl, id,sd->status.skill[id].lv);
- safestrncpy((char *)WFIFOP(fd,14), skill_get_name(id), NAME_LENGTH);
- if (sd->status.skill[id].flag == SKILL_FLAG_PERMANENT)
- WFIFOB(fd,38) = (sd->status.skill[id].lv < skill_tree_get_max(id, sd->status.class_))? 1:0;
- else
- WFIFOB(fd,38) = 0;
- WFIFOSET(fd,packet_len(0x111));
+ fd = sd->fd;
+ if (!fd) return;
+
+ if( sd->status.skill[id].id <= 0 )
+ return;
+
+ WFIFOHEAD(fd, packet_len(0x111));
+ WFIFOW(fd,0) = 0x111;
+ WFIFOW(fd,2) = id;
+ WFIFOL(fd,4) = skill_get_inf(id);
+ WFIFOW(fd,8) = sd->status.skill[id].lv;
+ WFIFOW(fd,10) = skill_get_sp(id,sd->status.skill[id].lv);
+ WFIFOW(fd,12)= skill_get_range2(&sd->bl, id,sd->status.skill[id].lv);
+ safestrncpy((char*)WFIFOP(fd,14), skill_get_name(id), NAME_LENGTH);
+ if( sd->status.skill[id].flag == SKILL_FLAG_PERMANENT )
+ WFIFOB(fd,38) = (sd->status.skill[id].lv < skill_tree_get_max(id, sd->status.class_))? 1:0;
+ else
+ WFIFOB(fd,38) = 0;
+ WFIFOSET(fd,packet_len(0x111));
}
@@ -4628,18 +4688,18 @@ void clif_addskill(struct map_session_data *sd, int id)
void clif_deleteskill(struct map_session_data *sd, int id)
{
#if PACKETVER >= 20081217
- int fd;
+ int fd;
- nullpo_retv(sd);
- fd = sd->fd;
- if (!fd) return;
+ nullpo_retv(sd);
+ fd = sd->fd;
+ if( !fd ) return;
- WFIFOHEAD(fd,packet_len(0x441));
- WFIFOW(fd,0) = 0x441;
- WFIFOW(fd,2) = id;
- WFIFOSET(fd,packet_len(0x441));
+ WFIFOHEAD(fd,packet_len(0x441));
+ WFIFOW(fd,0) = 0x441;
+ WFIFOW(fd,2) = id;
+ WFIFOSET(fd,packet_len(0x441));
#else
- clif_skillinfoblock(sd);
+ clif_skillinfoblock(sd);
#endif
}
@@ -4648,19 +4708,19 @@ void clif_deleteskill(struct map_session_data *sd, int id)
/// 010e <skill id>.W <level>.W <sp cost>.W <attack range>.W <upgradable>.B
void clif_skillup(struct map_session_data *sd,int skill_num)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x10e));
- WFIFOW(fd,0) = 0x10e;
- WFIFOW(fd,2) = skill_num;
- WFIFOW(fd,4) = sd->status.skill[skill_num].lv;
- WFIFOW(fd,6) = skill_get_sp(skill_num,sd->status.skill[skill_num].lv);
- WFIFOW(fd,8) = skill_get_range2(&sd->bl,skill_num,sd->status.skill[skill_num].lv);
- 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(0x10e));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0x10e));
+ WFIFOW(fd,0) = 0x10e;
+ WFIFOW(fd,2) = skill_num;
+ WFIFOW(fd,4) = sd->status.skill[skill_num].lv;
+ WFIFOW(fd,6) = skill_get_sp(skill_num,sd->status.skill[skill_num].lv);
+ WFIFOW(fd,8) = skill_get_range2(&sd->bl,skill_num,sd->status.skill[skill_num].lv);
+ 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(0x10e));
}
@@ -4668,20 +4728,20 @@ void clif_skillup(struct map_session_data *sd,int skill_num)
/// 07e1 <skill id>.W <type>.L <level>.W <sp cost>.W <attack range>.W <upgradable>.B
void clif_skillinfo(struct map_session_data *sd,int skill, int inf)
{
- const int fd = sd->fd;
-
- WFIFOHEAD(fd,packet_len(0x7e1));
- WFIFOW(fd,0) = 0x7e1;
- WFIFOW(fd,2) = skill;
- WFIFOL(fd,4) = inf?inf:skill_get_inf(skill);
- WFIFOW(fd,8) = sd->status.skill[skill].lv;
- WFIFOW(fd,10) = skill_get_sp(skill,sd->status.skill[skill].lv);
- WFIFOW(fd,12) = skill_get_range2(&sd->bl,skill,sd->status.skill[skill].lv);
- if (sd->status.skill[skill].flag == SKILL_FLAG_PERMANENT)
- WFIFOB(fd,14) = (sd->status.skill[skill].lv < skill_tree_get_max(skill, sd->status.class_))? 1:0;
- else
- WFIFOB(fd,14) = 0;
- WFIFOSET(fd,packet_len(0x7e1));
+ const int fd = sd->fd;
+
+ WFIFOHEAD(fd,packet_len(0x7e1));
+ WFIFOW(fd,0) = 0x7e1;
+ WFIFOW(fd,2) = skill;
+ WFIFOL(fd,4) = inf?inf:skill_get_inf(skill);
+ WFIFOW(fd,8) = sd->status.skill[skill].lv;
+ WFIFOW(fd,10) = skill_get_sp(skill,sd->status.skill[skill].lv);
+ WFIFOW(fd,12) = skill_get_range2(&sd->bl,skill,sd->status.skill[skill].lv);
+ if( sd->status.skill[skill].flag == SKILL_FLAG_PERMANENT )
+ WFIFOB(fd,14) = (sd->status.skill[skill].lv < skill_tree_get_max(skill, sd->status.class_))? 1:0;
+ else
+ WFIFOB(fd,14) = 0;
+ WFIFOSET(fd,packet_len(0x7e1));
}
@@ -4700,47 +4760,47 @@ void clif_skillinfo(struct map_session_data *sd,int skill, int inf)
/// is disposable:
/// 0 = yellow chat text "[src name] will use skill [skill name]."
/// 1 = no text
-void clif_skillcasting(struct block_list *bl, int src_id, int dst_id, int dst_x, int dst_y, int skill_num, int property, int casttime)
+void clif_skillcasting(struct block_list* bl, int src_id, int dst_id, int dst_x, int dst_y, int skill_num, int property, int casttime)
{
#if PACKETVER < 20091124
- const int cmd = 0x13e;
+ const int cmd = 0x13e;
#else
- const int cmd = 0x7fb;
+ const int cmd = 0x7fb;
#endif
- unsigned char buf[32];
-
- WBUFW(buf,0) = cmd;
- WBUFL(buf,2) = src_id;
- WBUFL(buf,6) = dst_id;
- WBUFW(buf,10) = dst_x;
- WBUFW(buf,12) = dst_y;
- WBUFW(buf,14) = skill_num;
- WBUFL(buf,16) = property<0?0:property; //Avoid sending negatives as element [Skotlex]
- WBUFL(buf,20) = casttime;
+ unsigned char buf[32];
+
+ WBUFW(buf,0) = cmd;
+ WBUFL(buf,2) = src_id;
+ WBUFL(buf,6) = dst_id;
+ WBUFW(buf,10) = dst_x;
+ WBUFW(buf,12) = dst_y;
+ WBUFW(buf,14) = skill_num;
+ WBUFL(buf,16) = property<0?0:property; //Avoid sending negatives as element [Skotlex]
+ WBUFL(buf,20) = casttime;
#if PACKETVER >= 20091124
- WBUFB(buf,24) = 0; // isDisposable
+ WBUFB(buf,24) = 0; // isDisposable
#endif
- if (disguised(bl)) {
- clif_send(buf,packet_len(cmd), bl, AREA_WOS);
- WBUFL(buf,2) = -src_id;
- clif_send(buf,packet_len(cmd), bl, SELF);
- } else
- clif_send(buf,packet_len(cmd), bl, AREA);
+ if (disguised(bl)) {
+ clif_send(buf,packet_len(cmd), bl, AREA_WOS);
+ WBUFL(buf,2) = -src_id;
+ clif_send(buf,packet_len(cmd), bl, SELF);
+ } else
+ clif_send(buf,packet_len(cmd), bl, AREA);
}
/// Notifies clients in area, that an object canceled casting (ZC_DISPEL).
/// 01b9 <id>.L
-void clif_skillcastcancel(struct block_list *bl)
+void clif_skillcastcancel(struct block_list* bl)
{
- unsigned char buf[16];
+ unsigned char buf[16];
- nullpo_retv(bl);
+ nullpo_retv(bl);
- WBUFW(buf,0) = 0x1b9;
- WBUFL(buf,2) = bl->id;
- clif_send(buf,packet_len(0x1b9), bl, AREA);
+ WBUFW(buf,0) = 0x1b9;
+ WBUFL(buf,2) = bl->id;
+ clif_send(buf,packet_len(0x1b9), bl, AREA);
}
@@ -4769,35 +4829,35 @@ void clif_skillcastcancel(struct block_list *bl)
/// suggesting this is an ACK packet for the UseSkill packets and should be sent on success too [FlavioJS]
void clif_skill_fail(struct map_session_data *sd,int skill_id,enum useskill_fail_cause cause,int btype)
{
- int fd;
+ int fd;
- if (!sd) { //Since this is the most common nullpo....
- ShowDebug("clif_skill_fail: Error, received NULL sd for skill %d\n", skill_id);
- return;
- }
+ if (!sd) { //Since this is the most common nullpo....
+ ShowDebug("clif_skill_fail: Error, received NULL sd for skill %d\n", skill_id);
+ return;
+ }
- fd=sd->fd;
- if (!fd) return;
+ fd=sd->fd;
+ if (!fd) return;
- if (battle_config.display_skill_fail&1)
- return; //Disable all skill failed messages
+ if(battle_config.display_skill_fail&1)
+ return; //Disable all skill failed messages
- if (cause==USESKILL_FAIL_SKILLINTERVAL && !sd->state.showdelay)
- return; //Disable delay failed messages
+ if(cause==USESKILL_FAIL_SKILLINTERVAL && !sd->state.showdelay)
+ return; //Disable delay failed messages
- if (skill_id == RG_SNATCHER && battle_config.display_skill_fail&4)
- return;
+ if(skill_id == RG_SNATCHER && battle_config.display_skill_fail&4)
+ return;
- if (skill_id == TF_POISON && battle_config.display_skill_fail&8)
- return;
+ if(skill_id == TF_POISON && battle_config.display_skill_fail&8)
+ return;
- WFIFOHEAD(fd,packet_len(0x110));
- WFIFOW(fd,0) = 0x110;
- WFIFOW(fd,2) = skill_id;
- WFIFOL(fd,4) = btype;
- WFIFOB(fd,8) = 0;// success
- WFIFOB(fd,9) = cause;
- WFIFOSET(fd,packet_len(0x110));
+ WFIFOHEAD(fd,packet_len(0x110));
+ WFIFOW(fd,0) = 0x110;
+ WFIFOW(fd,2) = skill_id;
+ WFIFOL(fd,4) = btype;
+ WFIFOB(fd,8) = 0;// success
+ WFIFOB(fd,9) = cause;
+ WFIFOSET(fd,packet_len(0x110));
}
@@ -4806,16 +4866,16 @@ void clif_skill_fail(struct map_session_data *sd,int skill_id,enum useskill_fail
void clif_skill_cooldown(struct map_session_data *sd, int skillid, unsigned int tick)
{
#if PACKETVER>=20081112
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x43d));
- WFIFOW(fd,0) = 0x43d;
- WFIFOW(fd,2) = skillid;
- WFIFOL(fd,4) = tick;
- WFIFOSET(fd,packet_len(0x43d));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0x43d));
+ WFIFOW(fd,0) = 0x43d;
+ WFIFOW(fd,2) = skillid;
+ WFIFOL(fd,4) = tick;
+ WFIFOSET(fd,packet_len(0x43d));
#endif
}
@@ -4825,85 +4885,85 @@ void clif_skill_cooldown(struct map_session_data *sd, int skillid, unsigned int
/// 01de <skill id>.W <src id>.L <dst id>.L <tick>.L <src delay>.L <dst delay>.L <damage>.L <level>.W <div>.W <type>.B (ZC_NOTIFY_SKILL2)
int clif_skill_damage(struct block_list *src,struct block_list *dst,unsigned int tick,int sdelay,int ddelay,int damage,int div,int skill_id,int skill_lv,int type)
{
- unsigned char buf[64];
- struct status_change *sc;
+ unsigned char buf[64];
+ struct status_change *sc;
- nullpo_ret(src);
- nullpo_ret(dst);
+ nullpo_ret(src);
+ nullpo_ret(dst);
- type = clif_calc_delay(type,div,damage,ddelay);
- sc = status_get_sc(dst);
- if (sc && sc->count) {
- if (sc->data[SC_HALLUCINATION] && damage)
- damage = damage*(sc->data[SC_HALLUCINATION]->val2) + rnd()%100;
- }
+ type = clif_calc_delay(type,div,damage,ddelay);
+ sc = status_get_sc(dst);
+ if(sc && sc->count) {
+ if(sc->data[SC_HALLUCINATION] && damage)
+ damage = damage*(sc->data[SC_HALLUCINATION]->val2) + rnd()%100;
+ }
#if PACKETVER < 3
- WBUFW(buf,0)=0x114;
- WBUFW(buf,2)=skill_id;
- WBUFL(buf,4)=src->id;
- WBUFL(buf,8)=dst->id;
- WBUFL(buf,12)=tick;
- WBUFL(buf,16)=sdelay;
- WBUFL(buf,20)=ddelay;
- if (battle_config.hide_woe_damage && map_flag_gvg(src->m)) {
- WBUFW(buf,24)=damage?div:0;
- } else {
- WBUFW(buf,24)=damage;
- }
- WBUFW(buf,26)=skill_lv;
- WBUFW(buf,28)=div;
- WBUFB(buf,30)=type;
- if (disguised(dst)) {
- clif_send(buf,packet_len(0x114),dst,AREA_WOS);
- WBUFL(buf,8)=-dst->id;
- clif_send(buf,packet_len(0x114),dst,SELF);
- } else
- clif_send(buf,packet_len(0x114),dst,AREA);
-
- if (disguised(src)) {
- WBUFL(buf,4)=-src->id;
- if (disguised(dst))
- WBUFL(buf,8)=dst->id;
- if (damage > 0)
- WBUFW(buf,24)=-1;
- clif_send(buf,packet_len(0x114),src,SELF);
- }
+ WBUFW(buf,0)=0x114;
+ WBUFW(buf,2)=skill_id;
+ WBUFL(buf,4)=src->id;
+ WBUFL(buf,8)=dst->id;
+ WBUFL(buf,12)=tick;
+ WBUFL(buf,16)=sdelay;
+ WBUFL(buf,20)=ddelay;
+ if (battle_config.hide_woe_damage && map_flag_gvg(src->m)) {
+ WBUFW(buf,24)=damage?div:0;
+ } else {
+ WBUFW(buf,24)=damage;
+ }
+ WBUFW(buf,26)=skill_lv;
+ WBUFW(buf,28)=div;
+ WBUFB(buf,30)=type;
+ if (disguised(dst)) {
+ clif_send(buf,packet_len(0x114),dst,AREA_WOS);
+ WBUFL(buf,8)=-dst->id;
+ clif_send(buf,packet_len(0x114),dst,SELF);
+ } else
+ clif_send(buf,packet_len(0x114),dst,AREA);
+
+ if(disguised(src)) {
+ WBUFL(buf,4)=-src->id;
+ if (disguised(dst))
+ WBUFL(buf,8)=dst->id;
+ if(damage > 0)
+ WBUFW(buf,24)=-1;
+ clif_send(buf,packet_len(0x114),src,SELF);
+ }
#else
- WBUFW(buf,0)=0x1de;
- WBUFW(buf,2)=skill_id;
- WBUFL(buf,4)=src->id;
- WBUFL(buf,8)=dst->id;
- WBUFL(buf,12)=tick;
- WBUFL(buf,16)=sdelay;
- WBUFL(buf,20)=ddelay;
- if (battle_config.hide_woe_damage && map_flag_gvg(src->m)) {
- WBUFL(buf,24)=damage?div:0;
- } else {
- WBUFL(buf,24)=damage;
- }
- WBUFW(buf,28)=skill_lv;
- WBUFW(buf,30)=div;
- WBUFB(buf,32)=type;
- if (disguised(dst)) {
- clif_send(buf,packet_len(0x1de),dst,AREA_WOS);
- WBUFL(buf,8)=-dst->id;
- clif_send(buf,packet_len(0x1de),dst,SELF);
- } else
- clif_send(buf,packet_len(0x1de),dst,AREA);
-
- if (disguised(src)) {
- WBUFL(buf,4)=-src->id;
- if (disguised(dst))
- WBUFL(buf,8)=dst->id;
- if (damage > 0)
- WBUFL(buf,24)=-1;
- clif_send(buf,packet_len(0x1de),src,SELF);
- }
+ WBUFW(buf,0)=0x1de;
+ WBUFW(buf,2)=skill_id;
+ WBUFL(buf,4)=src->id;
+ WBUFL(buf,8)=dst->id;
+ WBUFL(buf,12)=tick;
+ WBUFL(buf,16)=sdelay;
+ WBUFL(buf,20)=ddelay;
+ if (battle_config.hide_woe_damage && map_flag_gvg(src->m)) {
+ WBUFL(buf,24)=damage?div:0;
+ } else {
+ WBUFL(buf,24)=damage;
+ }
+ WBUFW(buf,28)=skill_lv;
+ WBUFW(buf,30)=div;
+ WBUFB(buf,32)=type;
+ if (disguised(dst)) {
+ clif_send(buf,packet_len(0x1de),dst,AREA_WOS);
+ WBUFL(buf,8)=-dst->id;
+ clif_send(buf,packet_len(0x1de),dst,SELF);
+ } else
+ clif_send(buf,packet_len(0x1de),dst,AREA);
+
+ if(disguised(src)) {
+ WBUFL(buf,4)=-src->id;
+ if (disguised(dst))
+ WBUFL(buf,8)=dst->id;
+ if(damage > 0)
+ WBUFL(buf,24)=-1;
+ clif_send(buf,packet_len(0x1de),src,SELF);
+ }
#endif
- //Because the damage delay must be synced with the client, here is where the can-walk tick must be updated. [Skotlex]
- return clif_calc_walkdelay(dst,ddelay,type,damage,div);
+ //Because the damage delay must be synced with the client, here is where the can-walk tick must be updated. [Skotlex]
+ return clif_calc_walkdelay(dst,ddelay,type,damage,div);
}
@@ -4912,56 +4972,56 @@ int clif_skill_damage(struct block_list *src,struct block_list *dst,unsigned int
/*
int clif_skill_damage2(struct block_list *src,struct block_list *dst,unsigned int tick,int sdelay,int ddelay,int damage,int div,int skill_id,int skill_lv,int type)
{
- unsigned char buf[64];
- struct status_change *sc;
-
- nullpo_ret(src);
- nullpo_ret(dst);
-
- type = (type>0)?type:skill_get_hit(skill_id);
- type = clif_calc_delay(type,div,damage,ddelay);
- sc = status_get_sc(dst);
-
- if(sc && sc->count) {
- if(sc->data[SC_HALLUCINATION] && damage)
- damage = damage*(sc->data[SC_HALLUCINATION]->val2) + rnd()%100;
- }
-
- WBUFW(buf,0)=0x115;
- WBUFW(buf,2)=skill_id;
- WBUFL(buf,4)=src->id;
- WBUFL(buf,8)=dst->id;
- WBUFL(buf,12)=tick;
- WBUFL(buf,16)=sdelay;
- WBUFL(buf,20)=ddelay;
- WBUFW(buf,24)=dst->x;
- WBUFW(buf,26)=dst->y;
- if (battle_config.hide_woe_damage && map_flag_gvg(src->m)) {
- WBUFW(buf,28)=damage?div:0;
- } else {
- WBUFW(buf,28)=damage;
- }
- WBUFW(buf,30)=skill_lv;
- WBUFW(buf,32)=div;
- WBUFB(buf,34)=type;
- clif_send(buf,packet_len(0x115),src,AREA);
- if(disguised(src)) {
- WBUFL(buf,4)=-src->id;
- if(damage > 0)
- WBUFW(buf,28)=-1;
- clif_send(buf,packet_len(0x115),src,SELF);
- }
- if (disguised(dst)) {
- WBUFL(buf,8)=-dst->id;
- if (disguised(src))
- WBUFL(buf,4)=src->id;
- else if(damage > 0)
- WBUFW(buf,28)=-1;
- clif_send(buf,packet_len(0x115),dst,SELF);
- }
-
- //Because the damage delay must be synced with the client, here is where the can-walk tick must be updated. [Skotlex]
- return clif_calc_walkdelay(dst,ddelay,type,damage,div);
+ unsigned char buf[64];
+ struct status_change *sc;
+
+ nullpo_ret(src);
+ nullpo_ret(dst);
+
+ type = (type>0)?type:skill_get_hit(skill_id);
+ type = clif_calc_delay(type,div,damage,ddelay);
+ sc = status_get_sc(dst);
+
+ if(sc && sc->count) {
+ if(sc->data[SC_HALLUCINATION] && damage)
+ damage = damage*(sc->data[SC_HALLUCINATION]->val2) + rnd()%100;
+ }
+
+ WBUFW(buf,0)=0x115;
+ WBUFW(buf,2)=skill_id;
+ WBUFL(buf,4)=src->id;
+ WBUFL(buf,8)=dst->id;
+ WBUFL(buf,12)=tick;
+ WBUFL(buf,16)=sdelay;
+ WBUFL(buf,20)=ddelay;
+ WBUFW(buf,24)=dst->x;
+ WBUFW(buf,26)=dst->y;
+ if (battle_config.hide_woe_damage && map_flag_gvg(src->m)) {
+ WBUFW(buf,28)=damage?div:0;
+ } else {
+ WBUFW(buf,28)=damage;
+ }
+ WBUFW(buf,30)=skill_lv;
+ WBUFW(buf,32)=div;
+ WBUFB(buf,34)=type;
+ clif_send(buf,packet_len(0x115),src,AREA);
+ if(disguised(src)) {
+ WBUFL(buf,4)=-src->id;
+ if(damage > 0)
+ WBUFW(buf,28)=-1;
+ clif_send(buf,packet_len(0x115),src,SELF);
+ }
+ if (disguised(dst)) {
+ WBUFL(buf,8)=-dst->id;
+ if (disguised(src))
+ WBUFL(buf,4)=src->id;
+ else if(damage > 0)
+ WBUFW(buf,28)=-1;
+ clif_send(buf,packet_len(0x115),dst,SELF);
+ }
+
+ //Because the damage delay must be synced with the client, here is where the can-walk tick must be updated. [Skotlex]
+ return clif_calc_walkdelay(dst,ddelay,type,damage,div);
}
*/
@@ -4970,32 +5030,32 @@ int clif_skill_damage2(struct block_list *src,struct block_list *dst,unsigned in
/// 011a <skill id>.W <skill lv>.W <dst id>.L <src id>.L <result>.B
int clif_skill_nodamage(struct block_list *src,struct block_list *dst,int skill_id,int heal,int fail)
{
- unsigned char buf[32];
-
- nullpo_ret(dst);
-
- WBUFW(buf,0)=0x11a;
- WBUFW(buf,2)=skill_id;
- WBUFW(buf,4)=min(heal, INT16_MAX);
- WBUFL(buf,6)=dst->id;
- WBUFL(buf,10)=src?src->id:0;
- WBUFB(buf,14)=fail;
-
- if (disguised(dst)) {
- clif_send(buf,packet_len(0x11a),dst,AREA_WOS);
- WBUFL(buf,6)=-dst->id;
- clif_send(buf,packet_len(0x11a),dst,SELF);
- } else
- clif_send(buf,packet_len(0x11a),dst,AREA);
-
- if (src && disguised(src)) {
- WBUFL(buf,10)=-src->id;
- if (disguised(dst))
- WBUFL(buf,6)=dst->id;
- clif_send(buf,packet_len(0x11a),src,SELF);
- }
+ unsigned char buf[32];
+
+ nullpo_ret(dst);
- return fail;
+ WBUFW(buf,0)=0x11a;
+ WBUFW(buf,2)=skill_id;
+ WBUFW(buf,4)=min(heal, INT16_MAX);
+ WBUFL(buf,6)=dst->id;
+ WBUFL(buf,10)=src?src->id:0;
+ WBUFB(buf,14)=fail;
+
+ if (disguised(dst)) {
+ clif_send(buf,packet_len(0x11a),dst,AREA_WOS);
+ WBUFL(buf,6)=-dst->id;
+ clif_send(buf,packet_len(0x11a),dst,SELF);
+ } else
+ clif_send(buf,packet_len(0x11a),dst,AREA);
+
+ if(src && disguised(src)) {
+ WBUFL(buf,10)=-src->id;
+ if (disguised(dst))
+ WBUFL(buf,6)=dst->id;
+ clif_send(buf,packet_len(0x11a),src,SELF);
+ }
+
+ return fail;
}
@@ -5003,23 +5063,23 @@ int clif_skill_nodamage(struct block_list *src,struct block_list *dst,int skill_
/// 0117 <skill id>.W <src id>.L <level>.W <x>.W <y>.W <tick>.L
void clif_skill_poseffect(struct block_list *src,int skill_id,int val,int x,int y,int tick)
{
- unsigned char buf[32];
+ unsigned char buf[32];
- nullpo_retv(src);
+ nullpo_retv(src);
- WBUFW(buf,0)=0x117;
- WBUFW(buf,2)=skill_id;
- WBUFL(buf,4)=src->id;
- WBUFW(buf,8)=val;
- WBUFW(buf,10)=x;
- WBUFW(buf,12)=y;
- WBUFL(buf,14)=tick;
- if (disguised(src)) {
- clif_send(buf,packet_len(0x117),src,AREA_WOS);
- WBUFL(buf,4)=-src->id;
- clif_send(buf,packet_len(0x117),src,SELF);
- } else
- clif_send(buf,packet_len(0x117),src,AREA);
+ WBUFW(buf,0)=0x117;
+ WBUFW(buf,2)=skill_id;
+ WBUFL(buf,4)=src->id;
+ WBUFW(buf,8)=val;
+ WBUFW(buf,10)=x;
+ WBUFW(buf,12)=y;
+ WBUFL(buf,14)=tick;
+ if(disguised(src)) {
+ clif_send(buf,packet_len(0x117),src,AREA_WOS);
+ WBUFL(buf,4)=-src->id;
+ clif_send(buf,packet_len(0x117),src,SELF);
+ } else
+ clif_send(buf,packet_len(0x117),src,AREA);
}
@@ -5029,69 +5089,69 @@ void clif_skill_poseffect(struct block_list *src,int skill_id,int val,int x,int
//FIXME: this is just an AREA version of clif_getareachar_skillunit()
void clif_skill_setunit(struct skill_unit *unit)
{
- unsigned char buf[128];
+ unsigned char buf[128];
- nullpo_retv(unit);
+ nullpo_retv(unit);
- if (unit->group->state.guildaura)
- return;
+ if( unit->group->state.guildaura )
+ return;
#if PACKETVER >= 3
- if (unit->group->unit_id==UNT_GRAFFITI) { // Graffiti [Valaris]
- WBUFW(buf, 0)=0x1c9;
- WBUFL(buf, 2)=unit->bl.id;
- WBUFL(buf, 6)=unit->group->src_id;
- WBUFW(buf,10)=unit->bl.x;
- WBUFW(buf,12)=unit->bl.y;
- WBUFB(buf,14)=unit->group->unit_id;
- WBUFB(buf,15)=1;
- WBUFB(buf,16)=1;
- safestrncpy((char *)WBUFP(buf,17),unit->group->valstr,MESSAGE_SIZE);
- clif_send(buf,packet_len(0x1c9),&unit->bl,AREA);
- return;
- }
+ if(unit->group->unit_id==UNT_GRAFFITI) { // Graffiti [Valaris]
+ WBUFW(buf, 0)=0x1c9;
+ WBUFL(buf, 2)=unit->bl.id;
+ WBUFL(buf, 6)=unit->group->src_id;
+ WBUFW(buf,10)=unit->bl.x;
+ WBUFW(buf,12)=unit->bl.y;
+ WBUFB(buf,14)=unit->group->unit_id;
+ WBUFB(buf,15)=1;
+ WBUFB(buf,16)=1;
+ safestrncpy((char*)WBUFP(buf,17),unit->group->valstr,MESSAGE_SIZE);
+ clif_send(buf,packet_len(0x1c9),&unit->bl,AREA);
+ return;
+ }
#endif
- WBUFW(buf, 0)=0x11f;
- WBUFL(buf, 2)=unit->bl.id;
- WBUFL(buf, 6)=unit->group->src_id;
- WBUFW(buf,10)=unit->bl.x;
- WBUFW(buf,12)=unit->bl.y;
- if (unit->group->state.song_dance&0x1 && unit->val2&UF_ENSEMBLE)
- WBUFB(buf,14)=unit->val2&UF_SONG?UNT_DISSONANCE:UNT_UGLYDANCE;
+ WBUFW(buf, 0)=0x11f;
+ WBUFL(buf, 2)=unit->bl.id;
+ WBUFL(buf, 6)=unit->group->src_id;
+ WBUFW(buf,10)=unit->bl.x;
+ WBUFW(buf,12)=unit->bl.y;
+ if (unit->group->state.song_dance&0x1 && unit->val2&UF_ENSEMBLE)
+ WBUFB(buf,14)=unit->val2&UF_SONG?UNT_DISSONANCE:UNT_UGLYDANCE;
else if (skill_get_unit_flag(unit->group->skill_id) & UF_RANGEDSINGLEUNIT && !(unit->val2 & UF_RANGEDSINGLEUNIT))
WBUFB(buf, 14) = UNT_DUMMYSKILL; // Only display the unit at center.
- else
- WBUFB(buf,14)=unit->group->unit_id;
- WBUFB(buf,15)=1; // ignored by client (always gets set to 1)
- clif_send(buf,packet_len(0x11f),&unit->bl,AREA);
+ else
+ WBUFB(buf,14)=unit->group->unit_id;
+ WBUFB(buf,15)=1; // ignored by client (always gets set to 1)
+ clif_send(buf,packet_len(0x11f),&unit->bl,AREA);
}
/// Presents a list of available warp destinations (ZC_WARPLIST).
/// 011c <skill id>.W { <map name>.16B }*4
-void clif_skill_warppoint(struct map_session_data *sd, short skill_num, short skill_lv, unsigned short map1, unsigned short map2, unsigned short map3, unsigned short map4)
+void clif_skill_warppoint(struct map_session_data* sd, short skill_num, short skill_lv, unsigned short map1, unsigned short map2, unsigned short map3, unsigned short map4)
{
- int fd;
- nullpo_retv(sd);
- fd = sd->fd;
-
- WFIFOHEAD(fd,packet_len(0x11c));
- WFIFOW(fd,0) = 0x11c;
- WFIFOW(fd,2) = skill_num;
- memset(WFIFOP(fd,4), 0x00, 4*MAP_NAME_LENGTH_EXT);
- if (map1 == (unsigned short)-1) strcpy((char *)WFIFOP(fd,4), "Random");
- else // normal map name
- if (map1 > 0) mapindex_getmapname_ext(mapindex_id2name(map1), (char *)WFIFOP(fd,4));
- if (map2 > 0) mapindex_getmapname_ext(mapindex_id2name(map2), (char *)WFIFOP(fd,20));
- if (map3 > 0) mapindex_getmapname_ext(mapindex_id2name(map3), (char *)WFIFOP(fd,36));
- if (map4 > 0) mapindex_getmapname_ext(mapindex_id2name(map4), (char *)WFIFOP(fd,52));
- WFIFOSET(fd,packet_len(0x11c));
-
- sd->menuskill_id = skill_num;
- if (skill_num == AL_WARP)
- sd->menuskill_val = (sd->ud.skillx<<16)|sd->ud.skilly; //Store warp position here.
- else
- sd->menuskill_val = skill_lv;
+ int fd;
+ nullpo_retv(sd);
+ fd = sd->fd;
+
+ WFIFOHEAD(fd,packet_len(0x11c));
+ WFIFOW(fd,0) = 0x11c;
+ WFIFOW(fd,2) = skill_num;
+ memset(WFIFOP(fd,4), 0x00, 4*MAP_NAME_LENGTH_EXT);
+ if (map1 == (unsigned short)-1) strcpy((char*)WFIFOP(fd,4), "Random");
+ else // normal map name
+ if (map1 > 0) mapindex_getmapname_ext(mapindex_id2name(map1), (char*)WFIFOP(fd,4));
+ if (map2 > 0) mapindex_getmapname_ext(mapindex_id2name(map2), (char*)WFIFOP(fd,20));
+ if (map3 > 0) mapindex_getmapname_ext(mapindex_id2name(map3), (char*)WFIFOP(fd,36));
+ if (map4 > 0) mapindex_getmapname_ext(mapindex_id2name(map4), (char*)WFIFOP(fd,52));
+ WFIFOSET(fd,packet_len(0x11c));
+
+ sd->menuskill_id = skill_num;
+ if (skill_num == AL_WARP)
+ sd->menuskill_val = (sd->ud.skillx<<16)|sd->ud.skilly; //Store warp position here.
+ else
+ sd->menuskill_val = skill_lv;
}
@@ -5104,17 +5164,17 @@ void clif_skill_warppoint(struct map_session_data *sd, short skill_num, short sk
///
/// @param sd Who receives the message
/// @param type What message
-void clif_skill_memomessage(struct map_session_data *sd, int type)
+void clif_skill_memomessage(struct map_session_data* sd, int type)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x11e));
- WFIFOW(fd,0)=0x11e;
- WFIFOB(fd,2)=type;
- WFIFOSET(fd,packet_len(0x11e));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0x11e));
+ WFIFOW(fd,0)=0x11e;
+ WFIFOB(fd,2)=type;
+ WFIFOSET(fd,packet_len(0x11e));
}
@@ -5128,15 +5188,15 @@ void clif_skill_memomessage(struct map_session_data *sd, int type)
/// @param type What message
void clif_skill_teleportmessage(struct map_session_data *sd, int type)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x189));
- WFIFOW(fd,0)=0x189;
- WFIFOW(fd,2)=type;
- WFIFOSET(fd,packet_len(0x189));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0x189));
+ WFIFOW(fd,0)=0x189;
+ WFIFOW(fd,2)=type;
+ WFIFOSET(fd,packet_len(0x189));
}
@@ -5145,35 +5205,35 @@ void clif_skill_teleportmessage(struct map_session_data *sd, int type)
/// <water%>.B <earth%>.B <fire%>.B <wind%>.B <poison%>.B <holy%>.B <shadow%>.B <ghost%>.B <undead%>.B
void clif_skill_estimation(struct map_session_data *sd,struct block_list *dst)
{
- struct status_data *status;
- unsigned char buf[64];
- int i;//, fix;
+ struct status_data *status;
+ unsigned char buf[64];
+ int i;//, fix;
- nullpo_retv(sd);
- nullpo_retv(dst);
+ nullpo_retv(sd);
+ nullpo_retv(dst);
- if (dst->type != BL_MOB)
- return;
+ if( dst->type != BL_MOB )
+ return;
- status = status_get_status_data(dst);
+ status = status_get_status_data(dst);
- WBUFW(buf, 0)=0x18c;
- WBUFW(buf, 2)=status_get_class(dst);
- WBUFW(buf, 4)=status_get_lv(dst);
- WBUFW(buf, 6)=status->size;
- WBUFL(buf, 8)=status->hp;
- WBUFW(buf,12)= (battle_config.estimation_type&1?status->def:0)
- +(battle_config.estimation_type&2?status->def2:0);
- WBUFW(buf,14)=status->race;
- WBUFW(buf,16)= (battle_config.estimation_type&1?status->mdef:0)
- +(battle_config.estimation_type&2?status->mdef2:0);
- WBUFW(buf,18)= status->def_ele;
- for (i=0; i<9; i++)
- WBUFB(buf,20+i)= (unsigned char)battle_attr_ratio(i+1,status->def_ele, status->ele_lv);
- // The following caps negative attributes to 0 since the client displays them as 255-fix. [Skotlex]
- // WBUFB(buf,20+i)= (unsigned char)((fix=battle_attr_ratio(i+1,status->def_ele, status->ele_lv))<0?0:fix);
+ WBUFW(buf, 0)=0x18c;
+ WBUFW(buf, 2)=status_get_class(dst);
+ WBUFW(buf, 4)=status_get_lv(dst);
+ WBUFW(buf, 6)=status->size;
+ WBUFL(buf, 8)=status->hp;
+ WBUFW(buf,12)= (battle_config.estimation_type&1?status->def:0)
+ +(battle_config.estimation_type&2?status->def2:0);
+ WBUFW(buf,14)=status->race;
+ WBUFW(buf,16)= (battle_config.estimation_type&1?status->mdef:0)
+ +(battle_config.estimation_type&2?status->mdef2:0);
+ WBUFW(buf,18)= status->def_ele;
+ for(i=0;i<9;i++)
+ WBUFB(buf,20+i)= (unsigned char)battle_attr_ratio(i+1,status->def_ele, status->ele_lv);
+// The following caps negative attributes to 0 since the client displays them as 255-fix. [Skotlex]
+// WBUFB(buf,20+i)= (unsigned char)((fix=battle_attr_ratio(i+1,status->def_ele, status->ele_lv))<0?0:fix);
- clif_send(buf,packet_len(0x18c),&sd->bl,sd->status.party_id>0?PARTY_SAMEMAP:SELF);
+ clif_send(buf,packet_len(0x18c),&sd->bl,sd->status.party_id>0?PARTY_SAMEMAP:SELF);
}
@@ -5183,39 +5243,39 @@ void clif_skill_estimation(struct map_session_data *sd,struct block_list *dst)
/// unused by the client
void clif_skill_produce_mix_list(struct map_session_data *sd, int skillid , int trigger)
{
- int i,c,view,fd;
- nullpo_retv(sd);
-
- if (sd->menuskill_id == skillid)
- return; //Avoid resending the menu twice or more times...
- if (skillid == GC_CREATENEWPOISON)
- skillid = GC_RESEARCHNEWPOISON;
-
- fd=sd->fd;
- WFIFOHEAD(fd, MAX_SKILL_PRODUCE_DB * 8 + 8);
- WFIFOW(fd, 0)=0x18d;
-
- for (i=0,c=0; i<MAX_SKILL_PRODUCE_DB; i++) {
- if (skill_can_produce_mix(sd,skill_produce_db[i].nameid, trigger, 1) &&
- ((skillid > 0 && skill_produce_db[i].req_skill == skillid) || skillid < 0)
- ) {
- if ((view = itemdb_viewid(skill_produce_db[i].nameid)) > 0)
- WFIFOW(fd,c*8+ 4)= view;
- else
- WFIFOW(fd,c*8+ 4)= skill_produce_db[i].nameid;
- WFIFOW(fd,c*8+ 6)= 0;
- WFIFOW(fd,c*8+ 8)= 0;
- WFIFOW(fd,c*8+10)= 0;
- c++;
- }
- }
- WFIFOW(fd, 2)=c*8+8;
- WFIFOSET(fd,WFIFOW(fd,2));
- if (c > 0) {
- sd->menuskill_id = skillid;
- sd->menuskill_val = trigger;
- return;
- }
+ int i,c,view,fd;
+ nullpo_retv(sd);
+
+ if(sd->menuskill_id == skillid)
+ return; //Avoid resending the menu twice or more times...
+ if( skillid == GC_CREATENEWPOISON )
+ skillid = GC_RESEARCHNEWPOISON;
+
+ fd=sd->fd;
+ WFIFOHEAD(fd, MAX_SKILL_PRODUCE_DB * 8 + 8);
+ WFIFOW(fd, 0)=0x18d;
+
+ for(i=0,c=0;i<MAX_SKILL_PRODUCE_DB;i++){
+ if( skill_can_produce_mix(sd,skill_produce_db[i].nameid, trigger, 1) &&
+ ( ( skillid > 0 && skill_produce_db[i].req_skill == skillid ) || skillid < 0 )
+ ){
+ if((view = itemdb_viewid(skill_produce_db[i].nameid)) > 0)
+ WFIFOW(fd,c*8+ 4)= view;
+ else
+ WFIFOW(fd,c*8+ 4)= skill_produce_db[i].nameid;
+ WFIFOW(fd,c*8+ 6)= 0;
+ WFIFOW(fd,c*8+ 8)= 0;
+ WFIFOW(fd,c*8+10)= 0;
+ c++;
+ }
+ }
+ WFIFOW(fd, 2)=c*8+8;
+ WFIFOSET(fd,WFIFOW(fd,2));
+ if(c > 0) {
+ sd->menuskill_id = skillid;
+ sd->menuskill_val = trigger;
+ return;
+ }
}
@@ -5230,55 +5290,55 @@ void clif_skill_produce_mix_list(struct map_session_data *sd, int skillid , int
/// 6 = GN_S_PHARMACY
void clif_cooking_list(struct map_session_data *sd, int trigger, int skill_id, int qty, int list_type)
{
- int fd;
- int i, c;
- int view;
-
- nullpo_retv(sd);
- fd = sd->fd;
-
- WFIFOHEAD(fd, 6 + 2 * MAX_SKILL_PRODUCE_DB);
- WFIFOW(fd,0) = 0x25a;
- WFIFOW(fd,4) = list_type; // list type
-
- c = 0;
- for (i = 0; i < MAX_SKILL_PRODUCE_DB; i++) {
- if (!skill_can_produce_mix(sd,skill_produce_db[i].nameid,trigger, qty))
- continue;
-
- if ((view = itemdb_viewid(skill_produce_db[i].nameid)) > 0)
- WFIFOW(fd, 6 + 2 * c) = view;
- else
- WFIFOW(fd, 6 + 2 * c) = skill_produce_db[i].nameid;
-
- c++;
- }
-
- if (skill_id == AM_PHARMACY) { // Only send it while Cooking else check for c.
- WFIFOW(fd,2) = 6 + 2 * c;
- WFIFOSET(fd,WFIFOW(fd,2));
- }
-
- if (c > 0) {
- sd->menuskill_id = skill_id;
- sd->menuskill_val = trigger;
- if (skill_id != AM_PHARMACY) {
- sd->menuskill_val2 = qty; // amount.
- WFIFOW(fd,2) = 6 + 2 * c;
- WFIFOSET(fd,WFIFOW(fd,2));
- }
- } else {
- clif_menuskill_clear(sd);
- if (skill_id != AM_PHARMACY) { // AM_PHARMACY is used to Cooking.
- // It fails.
+ int fd;
+ int i, c;
+ int view;
+
+ nullpo_retv(sd);
+ fd = sd->fd;
+
+ WFIFOHEAD(fd, 6 + 2 * MAX_SKILL_PRODUCE_DB);
+ WFIFOW(fd,0) = 0x25a;
+ WFIFOW(fd,4) = list_type; // list type
+
+ c = 0;
+ for( i = 0; i < MAX_SKILL_PRODUCE_DB; i++ ) {
+ if( !skill_can_produce_mix(sd,skill_produce_db[i].nameid,trigger, qty) )
+ continue;
+
+ if( (view = itemdb_viewid(skill_produce_db[i].nameid)) > 0 )
+ WFIFOW(fd, 6 + 2 * c) = view;
+ else
+ WFIFOW(fd, 6 + 2 * c) = skill_produce_db[i].nameid;
+
+ c++;
+ }
+
+ if( skill_id == AM_PHARMACY ) { // Only send it while Cooking else check for c.
+ WFIFOW(fd,2) = 6 + 2 * c;
+ WFIFOSET(fd,WFIFOW(fd,2));
+ }
+
+ if( c > 0 ) {
+ sd->menuskill_id = skill_id;
+ sd->menuskill_val = trigger;
+ if( skill_id != AM_PHARMACY ) {
+ sd->menuskill_val2 = qty; // amount.
+ WFIFOW(fd,2) = 6 + 2 * c;
+ WFIFOSET(fd,WFIFOW(fd,2));
+ }
+ } else {
+ clif_menuskill_clear(sd);
+ if( skill_id != AM_PHARMACY ) { // AM_PHARMACY is used to Cooking.
+ // It fails.
#if PACKETVER >= 20090922
- clif_msg_skill(sd,skill_id,0x625);
+ clif_msg_skill(sd,skill_id,0x625);
#else
- WFIFOW(fd,2) = 6 + 2 * c;
- WFIFOSET(fd,WFIFOW(fd,2));
+ WFIFOW(fd,2) = 6 + 2 * c;
+ WFIFOSET(fd,WFIFOW(fd,2));
#endif
- }
- }
+ }
+ }
}
@@ -5287,162 +5347,161 @@ void clif_cooking_list(struct map_session_data *sd, int trigger, int skill_id, i
/// 043f <index>.W <id>.L <state>.B <remain msec>.L { <val>.L }*3 (ZC_MSG_STATE_CHANGE2) [used exclusively for starting statuses on pcs]
void clif_status_change(struct block_list *bl,int type,int flag,int tick,int val1, int val2, int val3)
{
- unsigned char buf[32];
- struct map_session_data *sd;
+ unsigned char buf[32];
+ struct map_session_data *sd;
- if (type == SI_BLANK) //It shows nothing on the client...
- return;
+ if (type == SI_BLANK) //It shows nothing on the client...
+ return;
- nullpo_retv(bl);
+ nullpo_retv(bl);
- sd = BL_CAST(BL_PC, bl);
+ sd = BL_CAST(BL_PC, bl);
- if (!(status_type2relevant_bl_types(type)&bl->type)) // only send status changes that actually matter to the client
- return;
+ if (!(status_type2relevant_bl_types(type)&bl->type)) // only send status changes that actually matter to the client
+ return;
#if PACKETVER >= 20090121
- if (flag && battle_config.display_status_timers && sd)
- WBUFW(buf,0)=0x43f;
- else
+ if(flag && battle_config.display_status_timers && sd)
+ WBUFW(buf,0)=0x43f;
+ else
#endif
- WBUFW(buf,0)=0x196;
- WBUFW(buf,2)=type;
- WBUFL(buf,4)=bl->id;
- WBUFB(buf,8)=flag;
+ WBUFW(buf,0)=0x196;
+ WBUFW(buf,2)=type;
+ WBUFL(buf,4)=bl->id;
+ WBUFB(buf,8)=flag;
#if PACKETVER >= 20090121
- if (flag && battle_config.display_status_timers && sd) {
- if (tick <= 0)
- tick = 9999; // this is indeed what official servers do
-
- WBUFL(buf,9) = tick;
- WBUFL(buf,13) = val1;
- WBUFL(buf,17) = val2;
- WBUFL(buf,21) = val3;
- }
+ if(flag && battle_config.display_status_timers && sd)
+ {
+ if (tick <= 0)
+ tick = 9999; // this is indeed what official servers do
+
+ WBUFL(buf,9) = tick;
+ WBUFL(buf,13) = val1;
+ WBUFL(buf,17) = val2;
+ WBUFL(buf,21) = val3;
+ }
#endif
- clif_send(buf,packet_len(WBUFW(buf,0)),bl, (sd && sd->status.option&OPTION_INVISIBLE) ? SELF : AREA);
+ clif_send(buf,packet_len(WBUFW(buf,0)),bl, (sd && sd->status.option&OPTION_INVISIBLE) ? SELF : AREA);
}
/// Send message (modified by [Yor]) (ZC_NOTIFY_PLAYERCHAT).
/// 008e <packet len>.W <message>.?B
-void clif_displaymessage(const int fd, const char *mes)
-{
- nullpo_retv(mes);
-
- //Scrapped, as these are shared by disconnected players =X [Skotlex]
- if (fd == 0)
- ;
- else {
- char *message, *line;
-
- message = aStrdup(mes);
- line = strtok(message, "\n");
- while (line != NULL) {
- // Limit message to 255+1 characters (otherwise it causes a buffer overflow in the client)
- int len = strnlen(line, 255);
-
- if (len > 0) { // don't send a void message (it's not displaying on the client chat). @help can send void line.
- WFIFOHEAD(fd, 5 + len);
- WFIFOW(fd,0) = 0x8e;
- WFIFOW(fd,2) = 5 + len; // 4 + len + NULL teminate
- safestrncpy((char *)WFIFOP(fd,4), line, len + 1);
- WFIFOSET(fd, 5 + len);
- }
- line = strtok(NULL, "\n");
- }
- aFree(message);
- }
+void clif_displaymessage(const int fd, const char* mes)
+{
+ nullpo_retv(mes);
+
+ //Scrapped, as these are shared by disconnected players =X [Skotlex]
+ if (fd == 0)
+ ;
+ else {
+ char *message, *line;
+
+ message = aStrdup(mes);
+ line = strtok(message, "\n");
+ while(line != NULL) {
+ // Limit message to 255+1 characters (otherwise it causes a buffer overflow in the client)
+ int len = strnlen(line, 255);
+
+ if (len > 0) { // don't send a void message (it's not displaying on the client chat). @help can send void line.
+ WFIFOHEAD(fd, 5 + len);
+ WFIFOW(fd,0) = 0x8e;
+ WFIFOW(fd,2) = 5 + len; // 4 + len + NULL teminate
+ safestrncpy(WFIFOP(fd,4), line, len + 1);
+ WFIFOSET(fd, 5 + len);
+ }
+ line = strtok(NULL, "\n");
+ }
+ aFree(message);
+ }
}
/// Send broadcast message in yellow or blue without font formatting (ZC_BROADCAST).
/// 009a <packet len>.W <message>.?B
-void clif_broadcast(struct block_list *bl, const char *mes, int len, int type, enum send_target target)
+void clif_broadcast(struct block_list* bl, const char* mes, int len, int type, enum send_target target)
{
- int lp = type ? 4 : 0;
- unsigned char *buf = (unsigned char *)aMalloc((4 + lp + len)*sizeof(unsigned char));
+ int lp = type ? 4 : 0;
+ unsigned char *buf = (unsigned char*)aMalloc((4 + lp + len)*sizeof(unsigned char));
- WBUFW(buf,0) = 0x9a;
- WBUFW(buf,2) = 4 + lp + len;
- if (type == 0x10) // bc_blue
- WBUFL(buf,4) = 0x65756c62; //If there's "blue" at the beginning of the message, game client will display it in blue instead of yellow.
- else if (type == 0x20) // bc_woe
- WBUFL(buf,4) = 0x73737373; //If there's "ssss", game client will recognize message as 'WoE broadcast'.
- memcpy(WBUFP(buf, 4 + lp), mes, len);
- clif_send(buf, WBUFW(buf,2), bl, target);
+ WBUFW(buf,0) = 0x9a;
+ WBUFW(buf,2) = 4 + lp + len;
+ if (type == 0x10) // bc_blue
+ WBUFL(buf,4) = 0x65756c62; //If there's "blue" at the beginning of the message, game client will display it in blue instead of yellow.
+ else if (type == 0x20) // bc_woe
+ WBUFL(buf,4) = 0x73737373; //If there's "ssss", game client will recognize message as 'WoE broadcast'.
+ memcpy(WBUFP(buf, 4 + lp), mes, len);
+ clif_send(buf, WBUFW(buf,2), bl, target);
- if (buf)
- aFree(buf);
+ if (buf)
+ aFree(buf);
}
/*==========================================
* Displays a message on a 'bl' to all it's nearby clients
* Used by npc_globalmessage
*------------------------------------------*/
-void clif_GlobalMessage(struct block_list *bl, const char *message)
-{
- char buf[100];
- int len;
- nullpo_retv(bl);
+void clif_GlobalMessage(struct block_list* bl, const char* message) {
+ char buf[100];
+ int len;
+ nullpo_retv(bl);
- if (!message)
- return;
+ if(!message)
+ return;
- len = strlen(message)+1;
+ len = strlen(message)+1;
- if (len > sizeof(buf)-8) {
- ShowWarning("clif_GlobalMessage: Truncating too long message '%s' (len=%d).\n", message, len);
- len = sizeof(buf)-8;
- }
+ if( len > sizeof(buf)-8 ) {
+ ShowWarning("clif_GlobalMessage: Truncating too long message '%s' (len=%d).\n", message, len);
+ len = sizeof(buf)-8;
+ }
- WBUFW(buf,0)=0x8d;
- WBUFW(buf,2)=len+8;
- WBUFL(buf,4)=bl->id;
- safestrncpy((char *) WBUFP(buf,8),message,len);
- clif_send((unsigned char *) buf,WBUFW(buf,2),bl,ALL_CLIENT);
+ WBUFW(buf,0)=0x8d;
+ WBUFW(buf,2)=len+8;
+ WBUFL(buf,4)=bl->id;
+ safestrncpy((char *) WBUFP(buf,8),message,len);
+ clif_send((unsigned char *) buf,WBUFW(buf,2),bl,ALL_CLIENT);
}
/*==========================================
* Send main chat message [LuzZza]
*------------------------------------------*/
-void clif_MainChatMessage(const char *message)
-{
- uint8 buf[200];
- int len;
+void clif_MainChatMessage(const char* message) {
+ uint8 buf[200];
+ int len;
- if (!message)
- return;
+ if(!message)
+ return;
- len = strlen(message)+1;
- if (len+8 > sizeof(buf)) {
- ShowDebug("clif_MainChatMessage: Received message too long (len %d): %s\n", len, message);
- len = sizeof(buf)-8;
- }
- WBUFW(buf,0)=0x8d;
- WBUFW(buf,2)=len+8;
- WBUFL(buf,4)=0;
- safestrncpy((char *) WBUFP(buf,8),message,len);
- clif_send(buf,WBUFW(buf,2),NULL,CHAT_MAINCHAT);
+ len = strlen(message)+1;
+ if (len+8 > sizeof(buf)) {
+ ShowDebug("clif_MainChatMessage: Received message too long (len %d): %s\n", len, message);
+ len = sizeof(buf)-8;
+ }
+ WBUFW(buf,0)=0x8d;
+ WBUFW(buf,2)=len+8;
+ WBUFL(buf,4)=0;
+ safestrncpy((char *) WBUFP(buf,8),message,len);
+ clif_send(buf,WBUFW(buf,2),NULL,CHAT_MAINCHAT);
}
/// Send broadcast message with font formatting (ZC_BROADCAST2).
/// 01c3 <packet len>.W <fontColor>.L <fontType>.W <fontSize>.W <fontAlign>.W <fontY>.W <message>.?B
-void clif_broadcast2(struct block_list *bl, const char *mes, int len, unsigned long fontColor, short fontType, short fontSize, short fontAlign, short fontY, enum send_target target)
+void clif_broadcast2(struct block_list* bl, const char* mes, int len, unsigned long fontColor, short fontType, short fontSize, short fontAlign, short fontY, enum send_target target)
{
- unsigned char *buf = (unsigned char *)aMalloc((16 + len)*sizeof(unsigned char));
+ unsigned char *buf = (unsigned char*)aMalloc((16 + len)*sizeof(unsigned char));
- WBUFW(buf,0) = 0x1c3;
- WBUFW(buf,2) = len + 16;
- WBUFL(buf,4) = fontColor;
- WBUFW(buf,8) = fontType;
- WBUFW(buf,10) = fontSize;
- WBUFW(buf,12) = fontAlign;
- WBUFW(buf,14) = fontY;
- memcpy(WBUFP(buf,16), mes, len);
- clif_send(buf, WBUFW(buf,2), bl, target);
+ WBUFW(buf,0) = 0x1c3;
+ WBUFW(buf,2) = len + 16;
+ WBUFL(buf,4) = fontColor;
+ WBUFW(buf,8) = fontType;
+ WBUFW(buf,10) = fontSize;
+ WBUFW(buf,12) = fontAlign;
+ WBUFW(buf,14) = fontY;
+ memcpy(WBUFP(buf,16), mes, len);
+ clif_send(buf, WBUFW(buf,2), bl, target);
- if (buf)
- aFree(buf);
+ if (buf)
+ aFree(buf);
}
@@ -5454,11 +5513,11 @@ void clif_broadcast2(struct block_list *bl, const char *mes, int len, unsigned l
/// ? = ignored
void clif_heal(int fd,int type,int val)
{
- WFIFOHEAD(fd,packet_len(0x13d));
- WFIFOW(fd,0)=0x13d;
- WFIFOW(fd,2)=type;
- WFIFOW(fd,4)=cap_value(val,0,INT16_MAX);
- WFIFOSET(fd,packet_len(0x13d));
+ WFIFOHEAD(fd,packet_len(0x13d));
+ WFIFOW(fd,0)=0x13d;
+ WFIFOW(fd,2)=type;
+ WFIFOW(fd,4)=cap_value(val,0,INT16_MAX);
+ WFIFOSET(fd,packet_len(0x13d));
}
@@ -5468,49 +5527,49 @@ void clif_heal(int fd,int type,int val)
/// ignored
void clif_resurrection(struct block_list *bl,int type)
{
- unsigned char buf[16];
+ unsigned char buf[16];
- nullpo_retv(bl);
+ nullpo_retv(bl);
- WBUFW(buf,0)=0x148;
- WBUFL(buf,2)=bl->id;
- WBUFW(buf,6)=0;
+ WBUFW(buf,0)=0x148;
+ WBUFL(buf,2)=bl->id;
+ WBUFW(buf,6)=0;
- clif_send(buf,packet_len(0x148),bl,type==1 ? AREA : AREA_WOS);
- if (disguised(bl))
- clif_spawn(bl);
+ clif_send(buf,packet_len(0x148),bl,type==1 ? AREA : AREA_WOS);
+ if (disguised(bl))
+ clif_spawn(bl);
}
/// Sets the map property (ZC_NOTIFY_MAPPROPERTY).
/// 0199 <type>.W
-void clif_map_property(struct map_session_data *sd, enum map_property property)
+void clif_map_property(struct map_session_data* sd, enum map_property property)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x199));
- WFIFOW(fd,0)=0x199;
- WFIFOW(fd,2)=property;
- WFIFOSET(fd,packet_len(0x199));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0x199));
+ WFIFOW(fd,0)=0x199;
+ WFIFOW(fd,2)=property;
+ WFIFOSET(fd,packet_len(0x199));
}
/// Set the map type (ZC_NOTIFY_MAPPROPERTY2).
/// 01d6 <type>.W
-void clif_map_type(struct map_session_data *sd, enum map_type type)
+void clif_map_type(struct map_session_data* sd, enum map_type type)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x1D6));
- WFIFOW(fd,0)=0x1D6;
- WFIFOW(fd,2)=type;
- WFIFOSET(fd,packet_len(0x1D6));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0x1D6));
+ WFIFOW(fd,0)=0x1D6;
+ WFIFOW(fd,2)=type;
+ WFIFOSET(fd,packet_len(0x1D6));
}
@@ -5518,30 +5577,30 @@ void clif_map_type(struct map_session_data *sd, enum map_type type)
/// 019a <id>.L <ranking>.L <total>.L
void clif_pvpset(struct map_session_data *sd,int pvprank,int pvpnum,int type)
{
- if (type == 2) {
- int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x19a));
- WFIFOW(fd,0) = 0x19a;
- WFIFOL(fd,2) = sd->bl.id;
- WFIFOL(fd,6) = pvprank;
- WFIFOL(fd,10) = pvpnum;
- WFIFOSET(fd,packet_len(0x19a));
- } else {
- unsigned char buf[32];
- WBUFW(buf,0) = 0x19a;
- WBUFL(buf,2) = sd->bl.id;
- if (sd->sc.option&(OPTION_HIDE|OPTION_CLOAK))
- WBUFL(buf,6) = UINT32_MAX; //On client displays as --
- else
- WBUFL(buf,6) = pvprank;
- WBUFL(buf,10) = pvpnum;
- if (sd->sc.option&OPTION_INVISIBLE || sd->disguise) //Causes crashes when a 'mob' with pvp info dies.
- clif_send(buf,packet_len(0x19a),&sd->bl,SELF);
- else if (!type)
- clif_send(buf,packet_len(0x19a),&sd->bl,AREA);
- else
- clif_send(buf,packet_len(0x19a),&sd->bl,ALL_SAMEMAP);
- }
+ if(type == 2) {
+ int fd = sd->fd;
+ WFIFOHEAD(fd,packet_len(0x19a));
+ WFIFOW(fd,0) = 0x19a;
+ WFIFOL(fd,2) = sd->bl.id;
+ WFIFOL(fd,6) = pvprank;
+ WFIFOL(fd,10) = pvpnum;
+ WFIFOSET(fd,packet_len(0x19a));
+ } else {
+ unsigned char buf[32];
+ WBUFW(buf,0) = 0x19a;
+ WBUFL(buf,2) = sd->bl.id;
+ if(sd->sc.option&(OPTION_HIDE|OPTION_CLOAK))
+ WBUFL(buf,6) = UINT32_MAX; //On client displays as --
+ else
+ WBUFL(buf,6) = pvprank;
+ WBUFL(buf,10) = pvpnum;
+ if(sd->sc.option&OPTION_INVISIBLE || sd->disguise) //Causes crashes when a 'mob' with pvp info dies.
+ clif_send(buf,packet_len(0x19a),&sd->bl,SELF);
+ else if(!type)
+ clif_send(buf,packet_len(0x19a),&sd->bl,AREA);
+ else
+ clif_send(buf,packet_len(0x19a),&sd->bl,ALL_SAMEMAP);
+ }
}
@@ -5550,15 +5609,15 @@ void clif_pvpset(struct map_session_data *sd,int pvprank,int pvpnum,int type)
*------------------------------------------*/
void clif_map_property_mapall(int map, enum map_property property)
{
- struct block_list bl;
- unsigned char buf[16];
+ struct block_list bl;
+ unsigned char buf[16];
- bl.id = 0;
- bl.type = BL_NUL;
- bl.m = map;
- WBUFW(buf,0)=0x199;
- WBUFW(buf,2)=property;
- clif_send(buf,packet_len(0x199),&bl,ALL_SAMEMAP);
+ bl.id = 0;
+ bl.type = BL_NUL;
+ bl.m = map;
+ WBUFW(buf,0)=0x199;
+ WBUFW(buf,2)=property;
+ clif_send(buf,packet_len(0x199),&bl,ALL_SAMEMAP);
}
@@ -5570,12 +5629,12 @@ void clif_map_property_mapall(int map, enum map_property property)
/// 2 = downgrade
void clif_refine(int fd, int fail, int index, int val)
{
- WFIFOHEAD(fd,packet_len(0x188));
- WFIFOW(fd,0)=0x188;
- WFIFOW(fd,2)=fail;
- WFIFOW(fd,4)=index+2;
- WFIFOW(fd,6)=val;
- WFIFOSET(fd,packet_len(0x188));
+ WFIFOHEAD(fd,packet_len(0x188));
+ WFIFOW(fd,0)=0x188;
+ WFIFOW(fd,2)=fail;
+ WFIFOW(fd,4)=index+2;
+ WFIFOW(fd,6)=val;
+ WFIFOSET(fd,packet_len(0x188));
}
@@ -5588,35 +5647,35 @@ void clif_refine(int fd, int fail, int index, int val)
/// 3 = "you lack the item %s to upgrade the weapon" MsgStringTable[914] in rgb(255,200,200)
void clif_upgrademessage(int fd, int result, int item_id)
{
- WFIFOHEAD(fd,packet_len(0x223));
- WFIFOW(fd,0)=0x223;
- WFIFOL(fd,2)=result;
- WFIFOW(fd,6)=item_id;
- WFIFOSET(fd,packet_len(0x223));
+ WFIFOHEAD(fd,packet_len(0x223));
+ WFIFOW(fd,0)=0x223;
+ WFIFOL(fd,2)=result;
+ WFIFOW(fd,6)=item_id;
+ WFIFOSET(fd,packet_len(0x223));
}
/// Whisper is transmitted to the destination player (ZC_WHISPER).
/// 0097 <packet len>.W <nick>.24B <message>.?B
/// 0097 <packet len>.W <nick>.24B <isAdmin>.L <message>.?B (PACKETVER >= 20091104)
-void clif_wis_message(int fd, const char *nick, const char *mes, int mes_len)
+void clif_wis_message(int fd, const char* nick, const char* mes, int mes_len)
{
#if PACKETVER < 20091104
- WFIFOHEAD(fd, mes_len + NAME_LENGTH + 4);
- WFIFOW(fd,0) = 0x97;
- WFIFOW(fd,2) = mes_len + NAME_LENGTH + 4;
- safestrncpy((char *)WFIFOP(fd,4), nick, NAME_LENGTH);
- safestrncpy((char *)WFIFOP(fd,28), mes, mes_len);
- WFIFOSET(fd,WFIFOW(fd,2));
+ WFIFOHEAD(fd, mes_len + NAME_LENGTH + 4);
+ WFIFOW(fd,0) = 0x97;
+ WFIFOW(fd,2) = mes_len + NAME_LENGTH + 4;
+ safestrncpy((char*)WFIFOP(fd,4), nick, NAME_LENGTH);
+ safestrncpy((char*)WFIFOP(fd,28), mes, mes_len);
+ WFIFOSET(fd,WFIFOW(fd,2));
#else
- WFIFOHEAD(fd, mes_len + NAME_LENGTH + 8);
- WFIFOW(fd,0) = 0x97;
- WFIFOW(fd,2) = mes_len + NAME_LENGTH + 8;
- safestrncpy((char *)WFIFOP(fd,4), nick, NAME_LENGTH);
- WFIFOL(fd,28) = 0; // isAdmin; if nonzero, also displays text above char
- // TODO: WFIFOL(fd,28) = pc_get_group_level(ssd);
- safestrncpy((char *)WFIFOP(fd,32), mes, mes_len);
- WFIFOSET(fd,WFIFOW(fd,2));
+ WFIFOHEAD(fd, mes_len + NAME_LENGTH + 8);
+ WFIFOW(fd,0) = 0x97;
+ WFIFOW(fd,2) = mes_len + NAME_LENGTH + 8;
+ safestrncpy((char*)WFIFOP(fd,4), nick, NAME_LENGTH);
+ WFIFOL(fd,28) = 0; // isAdmin; if nonzero, also displays text above char
+ // TODO: WFIFOL(fd,28) = pc_get_group_level(ssd);
+ safestrncpy((char*)WFIFOP(fd,32), mes, mes_len);
+ WFIFOSET(fd,WFIFOW(fd,2));
#endif
}
@@ -5630,22 +5689,22 @@ void clif_wis_message(int fd, const char *nick, const char *mes, int mes_len)
/// 3 = everyone ignored by target
void clif_wis_end(int fd, int flag)
{
- WFIFOHEAD(fd,packet_len(0x98));
- WFIFOW(fd,0) = 0x98;
- WFIFOW(fd,2) = flag;
- WFIFOSET(fd,packet_len(0x98));
+ WFIFOHEAD(fd,packet_len(0x98));
+ WFIFOW(fd,0) = 0x98;
+ WFIFOW(fd,2) = flag;
+ WFIFOSET(fd,packet_len(0x98));
}
/// Returns character name requested by char_id (ZC_ACK_REQNAME_BYGID).
/// 0194 <char id>.L <name>.24B
-void clif_solved_charname(int fd, int charid, const char *name)
+void clif_solved_charname(int fd, int charid, const char* name)
{
- WFIFOHEAD(fd,packet_len(0x194));
- WFIFOW(fd,0)=0x194;
- WFIFOL(fd,2)=charid;
- safestrncpy((char *)WFIFOP(fd,6), name, NAME_LENGTH);
- WFIFOSET(fd,packet_len(0x194));
+ WFIFOHEAD(fd,packet_len(0x194));
+ WFIFOW(fd,0)=0x194;
+ WFIFOL(fd,2)=charid;
+ safestrncpy((char*)WFIFOP(fd,6), name, NAME_LENGTH);
+ WFIFOSET(fd,packet_len(0x194));
}
@@ -5653,48 +5712,48 @@ void clif_solved_charname(int fd, int charid, const char *name)
/// 017b <packet len>.W { <name id>.W }*
void clif_use_card(struct map_session_data *sd,int idx)
{
- int i,c,ep;
- int fd=sd->fd;
+ int i,c,ep;
+ int fd=sd->fd;
- nullpo_retv(sd);
- if (idx < 0 || idx >= MAX_INVENTORY) //Crash-fix from bad packets.
- return;
+ nullpo_retv(sd);
+ if (idx < 0 || idx >= MAX_INVENTORY) //Crash-fix from bad packets.
+ return;
- if (!sd->inventory_data[idx] || sd->inventory_data[idx]->type != IT_CARD)
- return; //Avoid parsing invalid item indexes (no card/no item)
+ if (!sd->inventory_data[idx] || sd->inventory_data[idx]->type != IT_CARD)
+ return; //Avoid parsing invalid item indexes (no card/no item)
- ep=sd->inventory_data[idx]->equip;
- WFIFOHEAD(fd,MAX_INVENTORY * 2 + 4);
- WFIFOW(fd,0)=0x17b;
+ ep=sd->inventory_data[idx]->equip;
+ WFIFOHEAD(fd,MAX_INVENTORY * 2 + 4);
+ WFIFOW(fd,0)=0x17b;
- for (i=c=0; i<MAX_INVENTORY; i++) {
- int j;
+ for(i=c=0;i<MAX_INVENTORY;i++){
+ int j;
- if (sd->inventory_data[i] == NULL)
- continue;
- if (sd->inventory_data[i]->type!=IT_WEAPON && sd->inventory_data[i]->type!=IT_ARMOR)
- continue;
- if (itemdb_isspecial(sd->status.inventory[i].card[0])) //Can't slot it
- continue;
+ if(sd->inventory_data[i] == NULL)
+ continue;
+ if(sd->inventory_data[i]->type!=IT_WEAPON && sd->inventory_data[i]->type!=IT_ARMOR)
+ continue;
+ if(itemdb_isspecial(sd->status.inventory[i].card[0])) //Can't slot it
+ continue;
- if (sd->status.inventory[i].identify==0) //Not identified
- continue;
+ if(sd->status.inventory[i].identify==0 ) //Not identified
+ continue;
- if ((sd->inventory_data[i]->equip&ep)==0) //Not equippable on this part.
- continue;
+ if((sd->inventory_data[i]->equip&ep)==0) //Not equippable on this part.
+ continue;
- if (sd->inventory_data[i]->type==IT_WEAPON && ep==EQP_SHIELD) //Shield card won't go on left weapon.
- continue;
+ if(sd->inventory_data[i]->type==IT_WEAPON && ep==EQP_SHIELD) //Shield card won't go on left weapon.
+ continue;
- ARR_FIND(0, sd->inventory_data[i]->slot, j, sd->status.inventory[i].card[j] == 0);
- if (j == sd->inventory_data[i]->slot) // No room
- continue;
+ ARR_FIND( 0, sd->inventory_data[i]->slot, j, sd->status.inventory[i].card[j] == 0 );
+ if( j == sd->inventory_data[i]->slot ) // No room
+ continue;
- WFIFOW(fd,4+c*2)=i+2;
- c++;
- }
- WFIFOW(fd,2)=4+c*2;
- WFIFOSET(fd,WFIFOW(fd,2));
+ WFIFOW(fd,4+c*2)=i+2;
+ c++;
+ }
+ WFIFOW(fd,2)=4+c*2;
+ WFIFOSET(fd,WFIFOW(fd,2));
}
@@ -5705,17 +5764,17 @@ void clif_use_card(struct map_session_data *sd,int idx)
/// 1 = failure
void clif_insert_card(struct map_session_data *sd,int idx_equip,int idx_card,int flag)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x17d));
- WFIFOW(fd,0)=0x17d;
- WFIFOW(fd,2)=idx_equip+2;
- WFIFOW(fd,4)=idx_card+2;
- WFIFOB(fd,6)=flag;
- WFIFOSET(fd,packet_len(0x17d));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0x17d));
+ WFIFOW(fd,0)=0x17d;
+ WFIFOW(fd,2)=idx_equip+2;
+ WFIFOW(fd,4)=idx_card+2;
+ WFIFOB(fd,6)=flag;
+ WFIFOSET(fd,packet_len(0x17d));
}
@@ -5723,27 +5782,27 @@ void clif_insert_card(struct map_session_data *sd,int idx_equip,int idx_card,int
/// 0177 <packet len>.W { <name id>.W }*
void clif_item_identify_list(struct map_session_data *sd)
{
- int i,c;
- int fd;
+ int i,c;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
+ fd=sd->fd;
- WFIFOHEAD(fd,MAX_INVENTORY * 2 + 4);
- WFIFOW(fd,0)=0x177;
- for (i=c=0; i<MAX_INVENTORY; i++) {
- if (sd->status.inventory[i].nameid > 0 && !sd->status.inventory[i].identify) {
- WFIFOW(fd,c*2+4)=i+2;
- c++;
- }
- }
- if (c > 0) {
- WFIFOW(fd,2)=c*2+4;
- WFIFOSET(fd,WFIFOW(fd,2));
- sd->menuskill_id = MC_IDENTIFY;
- sd->menuskill_val = c;
- }
+ WFIFOHEAD(fd,MAX_INVENTORY * 2 + 4);
+ WFIFOW(fd,0)=0x177;
+ for(i=c=0;i<MAX_INVENTORY;i++){
+ if(sd->status.inventory[i].nameid > 0 && !sd->status.inventory[i].identify){
+ WFIFOW(fd,c*2+4)=i+2;
+ c++;
+ }
+ }
+ if(c > 0) {
+ WFIFOW(fd,2)=c*2+4;
+ WFIFOSET(fd,WFIFOW(fd,2));
+ sd->menuskill_id = MC_IDENTIFY;
+ sd->menuskill_val = c;
+ }
}
@@ -5751,16 +5810,16 @@ void clif_item_identify_list(struct map_session_data *sd)
/// 0179 <index>.W <result>.B
void clif_item_identified(struct map_session_data *sd,int idx,int flag)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x179));
- WFIFOW(fd, 0)=0x179;
- WFIFOW(fd, 2)=idx+2;
- WFIFOB(fd, 4)=flag;
- WFIFOSET(fd,packet_len(0x179));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0x179));
+ WFIFOW(fd, 0)=0x179;
+ WFIFOW(fd, 2)=idx+2;
+ WFIFOB(fd, 4)=flag;
+ WFIFOSET(fd,packet_len(0x179));
}
@@ -5768,34 +5827,34 @@ void clif_item_identified(struct map_session_data *sd,int idx,int flag)
/// 01fc <packet len>.W { <index>.W <name id>.W <refine>.B <card1>.W <card2>.W <card3>.W <card4>.W }*
void clif_item_repair_list(struct map_session_data *sd,struct map_session_data *dstsd, int lv)
{
- int i,c;
- int fd;
- int nameid;
-
- nullpo_retv(sd);
- nullpo_retv(dstsd);
-
- fd=sd->fd;
-
- WFIFOHEAD(fd, MAX_INVENTORY * 13 + 4);
- WFIFOW(fd,0)=0x1fc;
- for (i=c=0; i<MAX_INVENTORY; i++) {
- if ((nameid=dstsd->status.inventory[i].nameid) > 0 && dstsd->status.inventory[i].attribute!=0) { // && skill_can_repair(sd,nameid)){
- WFIFOW(fd,c*13+4) = i;
- WFIFOW(fd,c*13+6) = nameid;
- WFIFOB(fd,c*13+8) = dstsd->status.inventory[i].refine;
- clif_addcards(WFIFOP(fd,c*13+9), &dstsd->status.inventory[i]);
- c++;
- }
- }
- if (c > 0) {
- WFIFOW(fd,2)=c*13+4;
- WFIFOSET(fd,WFIFOW(fd,2));
- sd->menuskill_id = BS_REPAIRWEAPON;
- sd->menuskill_val = dstsd->bl.id;
- sd->menuskill_val2 = lv;
- } else
- clif_skill_fail(sd,sd->ud.skillid,USESKILL_FAIL_LEVEL,0);
+ int i,c;
+ int fd;
+ int nameid;
+
+ nullpo_retv(sd);
+ nullpo_retv(dstsd);
+
+ fd=sd->fd;
+
+ WFIFOHEAD(fd, MAX_INVENTORY * 13 + 4);
+ WFIFOW(fd,0)=0x1fc;
+ for(i=c=0;i<MAX_INVENTORY;i++){
+ if((nameid=dstsd->status.inventory[i].nameid) > 0 && dstsd->status.inventory[i].attribute!=0){// && skill_can_repair(sd,nameid)){
+ WFIFOW(fd,c*13+4) = i;
+ WFIFOW(fd,c*13+6) = nameid;
+ WFIFOB(fd,c*13+8) = dstsd->status.inventory[i].refine;
+ clif_addcards(WFIFOP(fd,c*13+9), &dstsd->status.inventory[i]);
+ c++;
+ }
+ }
+ if(c > 0) {
+ WFIFOW(fd,2)=c*13+4;
+ WFIFOSET(fd,WFIFOW(fd,2));
+ sd->menuskill_id = BS_REPAIRWEAPON;
+ sd->menuskill_val = dstsd->bl.id;
+ sd->menuskill_val2 = lv;
+ }else
+ clif_skill_fail(sd,sd->ud.skillid,USESKILL_FAIL_LEVEL,0);
}
@@ -5808,32 +5867,32 @@ void clif_item_repair_list(struct map_session_data *sd,struct map_session_data *
/// 1 = Item repair failure.
void clif_item_repaireffect(struct map_session_data *sd,int idx,int flag)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd = sd->fd;
+ fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x1fe));
- WFIFOW(fd, 0)=0x1fe;
- WFIFOW(fd, 2)=idx+2;
- WFIFOB(fd, 4)=flag;
- WFIFOSET(fd,packet_len(0x1fe));
+ WFIFOHEAD(fd,packet_len(0x1fe));
+ WFIFOW(fd, 0)=0x1fe;
+ WFIFOW(fd, 2)=idx+2;
+ WFIFOB(fd, 4)=flag;
+ WFIFOSET(fd,packet_len(0x1fe));
}
/// Displays a message, that an equipment got damaged (ZC_EQUIPITEM_DAMAGED).
/// 02bb <equip location>.W <account id>.L
-void clif_item_damaged(struct map_session_data *sd, unsigned short position)
+void clif_item_damaged(struct map_session_data* sd, unsigned short position)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x2bb));
- WFIFOW(fd,0) = 0x2bb;
- WFIFOW(fd,2) = position;
- WFIFOL(fd,4) = sd->bl.id; // TODO: the packet seems to be sent to other people as well, probably party and/or guild.
- WFIFOSET(fd,packet_len(0x2bb));
+ WFIFOHEAD(fd,packet_len(0x2bb));
+ WFIFOW(fd,0) = 0x2bb;
+ WFIFOW(fd,2) = position;
+ WFIFOL(fd,4) = sd->bl.id; // TODO: the packet seems to be sent to other people as well, probably party and/or guild.
+ WFIFOSET(fd,packet_len(0x2bb));
}
@@ -5841,42 +5900,42 @@ void clif_item_damaged(struct map_session_data *sd, unsigned short position)
/// 0221 <packet len>.W { <index>.W <name id>.W <refine>.B <card1>.W <card2>.W <card3>.W <card4>.W }*
void clif_item_refine_list(struct map_session_data *sd)
{
- int i,c;
- int fd;
- int skilllv;
- int wlv;
- int refine_item[5];
-
- nullpo_retv(sd);
-
- skilllv = pc_checkskill(sd,WS_WEAPONREFINE);
-
- fd=sd->fd;
-
- refine_item[0] = -1;
- refine_item[1] = pc_search_inventory(sd,1010);
- refine_item[2] = pc_search_inventory(sd,1011);
- refine_item[3] = refine_item[4] = pc_search_inventory(sd,984);
-
- WFIFOHEAD(fd, MAX_INVENTORY * 13 + 4);
- WFIFOW(fd,0)=0x221;
- for (i=c=0; i<MAX_INVENTORY; i++) {
- if (sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].refine < skilllv &&
- sd->status.inventory[i].identify && (wlv=itemdb_wlv(sd->status.inventory[i].nameid)) >=1 &&
- refine_item[wlv]!=-1 && !(sd->status.inventory[i].equip&EQP_ARMS)) {
- WFIFOW(fd,c*13+ 4)=i+2;
- WFIFOW(fd,c*13+ 6)=sd->status.inventory[i].nameid;
- WFIFOB(fd,c*13+ 8)=sd->status.inventory[i].refine;
- clif_addcards(WFIFOP(fd,c*13+9), &sd->status.inventory[i]);
- c++;
- }
- }
- WFIFOW(fd,2)=c*13+4;
- WFIFOSET(fd,WFIFOW(fd,2));
- if (c > 0) {
- sd->menuskill_id = WS_WEAPONREFINE;
- sd->menuskill_val = skilllv;
- }
+ int i,c;
+ int fd;
+ int skilllv;
+ int wlv;
+ int refine_item[5];
+
+ nullpo_retv(sd);
+
+ skilllv = pc_checkskill(sd,WS_WEAPONREFINE);
+
+ fd=sd->fd;
+
+ refine_item[0] = -1;
+ refine_item[1] = pc_search_inventory(sd,1010);
+ refine_item[2] = pc_search_inventory(sd,1011);
+ refine_item[3] = refine_item[4] = pc_search_inventory(sd,984);
+
+ WFIFOHEAD(fd, MAX_INVENTORY * 13 + 4);
+ WFIFOW(fd,0)=0x221;
+ for(i=c=0;i<MAX_INVENTORY;i++){
+ if(sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].refine < skilllv &&
+ sd->status.inventory[i].identify && (wlv=itemdb_wlv(sd->status.inventory[i].nameid)) >=1 &&
+ refine_item[wlv]!=-1 && !(sd->status.inventory[i].equip&EQP_ARMS)){
+ WFIFOW(fd,c*13+ 4)=i+2;
+ WFIFOW(fd,c*13+ 6)=sd->status.inventory[i].nameid;
+ WFIFOB(fd,c*13+ 8)=sd->status.inventory[i].refine;
+ clif_addcards(WFIFOP(fd,c*13+9), &sd->status.inventory[i]);
+ c++;
+ }
+ }
+ WFIFOW(fd,2)=c*13+4;
+ WFIFOSET(fd,WFIFOW(fd,2));
+ if (c > 0) {
+ sd->menuskill_id = WS_WEAPONREFINE;
+ sd->menuskill_val = skilllv;
+ }
}
@@ -5884,22 +5943,22 @@ void clif_item_refine_list(struct map_session_data *sd)
/// 0147 <skill id>.W <type>.L <level>.W <sp cost>.W <atk range>.W <skill name>.24B <upgradable>.B
void clif_item_skill(struct map_session_data *sd,int skillid,int skilllv)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x147));
- WFIFOW(fd, 0)=0x147;
- WFIFOW(fd, 2)=skillid;
- WFIFOW(fd, 4)=skill_get_inf(skillid);
- WFIFOW(fd, 6)=0;
- WFIFOW(fd, 8)=skilllv;
- WFIFOW(fd,10)=skill_get_sp(skillid,skilllv);
- WFIFOW(fd,12)=skill_get_range2(&sd->bl, skillid,skilllv);
- safestrncpy((char *)WFIFOP(fd,14),skill_get_name(skillid),NAME_LENGTH);
- WFIFOB(fd,38)=0;
- WFIFOSET(fd,packet_len(0x147));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0x147));
+ WFIFOW(fd, 0)=0x147;
+ WFIFOW(fd, 2)=skillid;
+ WFIFOW(fd, 4)=skill_get_inf(skillid);
+ WFIFOW(fd, 6)=0;
+ WFIFOW(fd, 8)=skilllv;
+ WFIFOW(fd,10)=skill_get_sp(skillid,skilllv);
+ WFIFOW(fd,12)=skill_get_range2(&sd->bl, skillid,skilllv);
+ safestrncpy((char*)WFIFOP(fd,14),skill_get_name(skillid),NAME_LENGTH);
+ WFIFOB(fd,38)=0;
+ WFIFOSET(fd,packet_len(0x147));
}
@@ -5908,46 +5967,46 @@ void clif_item_skill(struct map_session_data *sd,int skillid,int skilllv)
/// 01c5 <index>.W <amount>.L <name id>.W <type>.B <identified>.B <damaged>.B <refine>.B <card1>.W <card2>.W <card3>.W <card4>.W (ZC_ADD_ITEM_TO_CART2)
void clif_cart_additem(struct map_session_data *sd,int n,int amount,int fail)
{
- int view,fd;
- unsigned char *buf;
+ int view,fd;
+ unsigned char *buf;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- if (n<0 || n>=MAX_CART || sd->status.cart[n].nameid<=0)
- return;
+ fd=sd->fd;
+ if(n<0 || n>=MAX_CART || sd->status.cart[n].nameid<=0)
+ return;
#if PACKETVER < 5
- WFIFOHEAD(fd,packet_len(0x124));
- buf=WFIFOP(fd,0);
- WBUFW(buf,0)=0x124;
- WBUFW(buf,2)=n+2;
- WBUFL(buf,4)=amount;
- if ((view = itemdb_viewid(sd->status.cart[n].nameid)) > 0)
- WBUFW(buf,8)=view;
- else
- WBUFW(buf,8)=sd->status.cart[n].nameid;
- WBUFB(buf,10)=sd->status.cart[n].identify;
- WBUFB(buf,11)=sd->status.cart[n].attribute;
- WBUFB(buf,12)=sd->status.cart[n].refine;
- clif_addcards(WBUFP(buf,13), &sd->status.cart[n]);
- WFIFOSET(fd,packet_len(0x124));
+ WFIFOHEAD(fd,packet_len(0x124));
+ buf=WFIFOP(fd,0);
+ WBUFW(buf,0)=0x124;
+ WBUFW(buf,2)=n+2;
+ WBUFL(buf,4)=amount;
+ if((view = itemdb_viewid(sd->status.cart[n].nameid)) > 0)
+ WBUFW(buf,8)=view;
+ else
+ WBUFW(buf,8)=sd->status.cart[n].nameid;
+ WBUFB(buf,10)=sd->status.cart[n].identify;
+ WBUFB(buf,11)=sd->status.cart[n].attribute;
+ WBUFB(buf,12)=sd->status.cart[n].refine;
+ clif_addcards(WBUFP(buf,13), &sd->status.cart[n]);
+ WFIFOSET(fd,packet_len(0x124));
#else
- WFIFOHEAD(fd,packet_len(0x1c5));
- buf=WFIFOP(fd,0);
- WBUFW(buf,0)=0x1c5;
- WBUFW(buf,2)=n+2;
- WBUFL(buf,4)=amount;
- if ((view = itemdb_viewid(sd->status.cart[n].nameid)) > 0)
- WBUFW(buf,8)=view;
- else
- WBUFW(buf,8)=sd->status.cart[n].nameid;
- WBUFB(buf,10)=itemdb_type(sd->status.cart[n].nameid);
- WBUFB(buf,11)=sd->status.cart[n].identify;
- WBUFB(buf,12)=sd->status.cart[n].attribute;
- WBUFB(buf,13)=sd->status.cart[n].refine;
- clif_addcards(WBUFP(buf,14), &sd->status.cart[n]);
- WFIFOSET(fd,packet_len(0x1c5));
+ WFIFOHEAD(fd,packet_len(0x1c5));
+ buf=WFIFOP(fd,0);
+ WBUFW(buf,0)=0x1c5;
+ WBUFW(buf,2)=n+2;
+ WBUFL(buf,4)=amount;
+ if((view = itemdb_viewid(sd->status.cart[n].nameid)) > 0)
+ WBUFW(buf,8)=view;
+ else
+ WBUFW(buf,8)=sd->status.cart[n].nameid;
+ WBUFB(buf,10)=itemdb_type(sd->status.cart[n].nameid);
+ WBUFB(buf,11)=sd->status.cart[n].identify;
+ WBUFB(buf,12)=sd->status.cart[n].attribute;
+ WBUFB(buf,13)=sd->status.cart[n].refine;
+ clif_addcards(WBUFP(buf,14), &sd->status.cart[n]);
+ WFIFOSET(fd,packet_len(0x1c5));
#endif
}
@@ -5956,17 +6015,17 @@ void clif_cart_additem(struct map_session_data *sd,int n,int amount,int fail)
/// 0125 <index>.W <amount>.L
void clif_cart_delitem(struct map_session_data *sd,int n,int amount)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
+ fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x125));
- WFIFOW(fd,0)=0x125;
- WFIFOW(fd,2)=n+2;
- WFIFOL(fd,4)=amount;
- WFIFOSET(fd,packet_len(0x125));
+ WFIFOHEAD(fd,packet_len(0x125));
+ WFIFOW(fd,0)=0x125;
+ WFIFOW(fd,2)=n+2;
+ WFIFOL(fd,4)=amount;
+ WFIFOSET(fd,packet_len(0x125));
}
@@ -5974,107 +6033,108 @@ void clif_cart_delitem(struct map_session_data *sd,int n,int amount)
/// 012d <num>.W
/// num:
/// number of allowed item slots
-void clif_openvendingreq(struct map_session_data *sd, int num)
+void clif_openvendingreq(struct map_session_data* sd, int num)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x12d));
- WFIFOW(fd,0) = 0x12d;
- WFIFOW(fd,2) = num;
- WFIFOSET(fd,packet_len(0x12d));
+ fd = sd->fd;
+ WFIFOHEAD(fd,packet_len(0x12d));
+ WFIFOW(fd,0) = 0x12d;
+ WFIFOW(fd,2) = num;
+ WFIFOSET(fd,packet_len(0x12d));
}
/// Displays a vending board to target/area (ZC_STORE_ENTRY).
/// 0131 <owner id>.L <message>.80B
-void clif_showvendingboard(struct block_list *bl, const char *message, int fd)
+void clif_showvendingboard(struct block_list* bl, const char* message, int fd)
{
- unsigned char buf[128];
+ unsigned char buf[128];
- nullpo_retv(bl);
+ nullpo_retv(bl);
- WBUFW(buf,0) = 0x131;
- WBUFL(buf,2) = bl->id;
- safestrncpy((char *)WBUFP(buf,6), message, 80);
+ WBUFW(buf,0) = 0x131;
+ WBUFL(buf,2) = bl->id;
+ safestrncpy((char*)WBUFP(buf,6), message, 80);
- if (fd) {
- WFIFOHEAD(fd,packet_len(0x131));
- memcpy(WFIFOP(fd,0),buf,packet_len(0x131));
- WFIFOSET(fd,packet_len(0x131));
- } else {
- clif_send(buf,packet_len(0x131),bl,AREA_WOS);
- }
+ if( fd ) {
+ WFIFOHEAD(fd,packet_len(0x131));
+ memcpy(WFIFOP(fd,0),buf,packet_len(0x131));
+ WFIFOSET(fd,packet_len(0x131));
+ } else {
+ clif_send(buf,packet_len(0x131),bl,AREA_WOS);
+ }
}
/// Removes a vending board from screen (ZC_DISAPPEAR_ENTRY).
/// 0132 <owner id>.L
-void clif_closevendingboard(struct block_list *bl, int fd)
+void clif_closevendingboard(struct block_list* bl, int fd)
{
- unsigned char buf[16];
+ unsigned char buf[16];
- nullpo_retv(bl);
+ nullpo_retv(bl);
- WBUFW(buf,0) = 0x132;
- WBUFL(buf,2) = bl->id;
- if (fd) {
- WFIFOHEAD(fd,packet_len(0x132));
- memcpy(WFIFOP(fd,0),buf,packet_len(0x132));
- WFIFOSET(fd,packet_len(0x132));
- } else {
- clif_send(buf,packet_len(0x132),bl,AREA_WOS);
- }
+ WBUFW(buf,0) = 0x132;
+ WBUFL(buf,2) = bl->id;
+ if( fd ) {
+ WFIFOHEAD(fd,packet_len(0x132));
+ memcpy(WFIFOP(fd,0),buf,packet_len(0x132));
+ WFIFOSET(fd,packet_len(0x132));
+ } else {
+ clif_send(buf,packet_len(0x132),bl,AREA_WOS);
+ }
}
/// Sends a list of items in a shop.
/// R 0133 <packet len>.W <owner id>.L { <price>.L <amount>.W <index>.W <type>.B <name id>.W <identified>.B <damaged>.B <refine>.B <card1>.W <card2>.W <card3>.W <card4>.W }* (ZC_PC_PURCHASE_ITEMLIST_FROMMC)
/// R 0800 <packet len>.W <owner id>.L <unique id>.L { <price>.L <amount>.W <index>.W <type>.B <name id>.W <identified>.B <damaged>.B <refine>.B <card1>.W <card2>.W <card3>.W <card4>.W }* (ZC_PC_PURCHASE_ITEMLIST_FROMMC2)
-void clif_vendinglist(struct map_session_data *sd, int id, struct s_vending *vending)
+void clif_vendinglist(struct map_session_data* sd, int id, struct s_vending* vending)
{
- int i,fd;
- int count;
- struct map_session_data *vsd;
+ int i,fd;
+ int count;
+ struct map_session_data* vsd;
#if PACKETVER < 20100105
- const int cmd = 0x133;
- const int offset = 8;
+ const int cmd = 0x133;
+ const int offset = 8;
#else
- const int cmd = 0x800;
- const int offset = 12;
+ const int cmd = 0x800;
+ const int offset = 12;
#endif
- nullpo_retv(sd);
- nullpo_retv(vending);
- nullpo_retv(vsd=map_id2sd(id));
+ nullpo_retv(sd);
+ nullpo_retv(vending);
+ nullpo_retv(vsd=map_id2sd(id));
- fd = sd->fd;
- count = vsd->vend_num;
+ fd = sd->fd;
+ count = vsd->vend_num;
- WFIFOHEAD(fd, offset+count*22);
- WFIFOW(fd,0) = cmd;
- WFIFOW(fd,2) = offset+count*22;
- WFIFOL(fd,4) = id;
+ WFIFOHEAD(fd, offset+count*22);
+ WFIFOW(fd,0) = cmd;
+ WFIFOW(fd,2) = offset+count*22;
+ WFIFOL(fd,4) = id;
#if PACKETVER >= 20100105
- WFIFOL(fd,8) = vsd->vender_id;
+ WFIFOL(fd,8) = vsd->vender_id;
#endif
- for (i = 0; i < count; i++) {
- int index = vending[i].index;
- struct item_data *data = itemdb_search(vsd->status.cart[index].nameid);
- WFIFOL(fd,offset+ 0+i*22) = vending[i].value;
- WFIFOW(fd,offset+ 4+i*22) = vending[i].amount;
- WFIFOW(fd,offset+ 6+i*22) = vending[i].index + 2;
- WFIFOB(fd,offset+ 8+i*22) = itemtype(data->type);
- WFIFOW(fd,offset+ 9+i*22) = (data->view_id > 0) ? data->view_id : vsd->status.cart[index].nameid;
- WFIFOB(fd,offset+11+i*22) = vsd->status.cart[index].identify;
- WFIFOB(fd,offset+12+i*22) = vsd->status.cart[index].attribute;
- WFIFOB(fd,offset+13+i*22) = vsd->status.cart[index].refine;
- clif_addcards(WFIFOP(fd,offset+14+i*22), &vsd->status.cart[index]);
- }
- WFIFOSET(fd,WFIFOW(fd,2));
+ for( i = 0; i < count; i++ )
+ {
+ int index = vending[i].index;
+ struct item_data* data = itemdb_search(vsd->status.cart[index].nameid);
+ WFIFOL(fd,offset+ 0+i*22) = vending[i].value;
+ WFIFOW(fd,offset+ 4+i*22) = vending[i].amount;
+ WFIFOW(fd,offset+ 6+i*22) = vending[i].index + 2;
+ WFIFOB(fd,offset+ 8+i*22) = itemtype(data->type);
+ WFIFOW(fd,offset+ 9+i*22) = ( data->view_id > 0 ) ? data->view_id : vsd->status.cart[index].nameid;
+ WFIFOB(fd,offset+11+i*22) = vsd->status.cart[index].identify;
+ WFIFOB(fd,offset+12+i*22) = vsd->status.cart[index].attribute;
+ WFIFOB(fd,offset+13+i*22) = vsd->status.cart[index].refine;
+ clif_addcards(WFIFOP(fd,offset+14+i*22), &vsd->status.cart[index]);
+ }
+ WFIFOSET(fd,WFIFOW(fd,2));
}
@@ -6088,69 +6148,70 @@ void clif_vendinglist(struct map_session_data *sd, int id, struct s_vending *ven
/// 5 = "cannot use an npc shop while in a trade"
/// 6 = Because the store information was incorrect the item was not purchased.
/// 7 = No sales information.
-void clif_buyvending(struct map_session_data *sd, int index, int amount, int fail)
+void clif_buyvending(struct map_session_data* sd, int index, int amount, int fail)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x135));
- WFIFOW(fd,0) = 0x135;
- WFIFOW(fd,2) = index+2;
- WFIFOW(fd,4) = amount;
- WFIFOB(fd,6) = fail;
- WFIFOSET(fd,packet_len(0x135));
+ fd = sd->fd;
+ WFIFOHEAD(fd,packet_len(0x135));
+ WFIFOW(fd,0) = 0x135;
+ WFIFOW(fd,2) = index+2;
+ WFIFOW(fd,4) = amount;
+ WFIFOB(fd,6) = fail;
+ WFIFOSET(fd,packet_len(0x135));
}
/// Shop creation success (ZC_PC_PURCHASE_MYITEMLIST).
/// 0136 <packet len>.W <owner id>.L { <price>.L <index>.W <amount>.W <type>.B <name id>.W <identified>.B <damaged>.B <refine>.B <card1>.W <card2>.W <card3>.W <card4>.W }*
-void clif_openvending(struct map_session_data *sd, int id, struct s_vending *vending)
-{
- int i,fd;
- int count;
-
- nullpo_retv(sd);
-
- fd = sd->fd;
- count = sd->vend_num;
-
- WFIFOHEAD(fd, 8+count*22);
- WFIFOW(fd,0) = 0x136;
- WFIFOW(fd,2) = 8+count*22;
- WFIFOL(fd,4) = id;
- for (i = 0; i < count; i++) {
- int index = vending[i].index;
- struct item_data *data = itemdb_search(sd->status.cart[index].nameid);
- WFIFOL(fd, 8+i*22) = vending[i].value;
- WFIFOW(fd,12+i*22) = vending[i].index + 2;
- WFIFOW(fd,14+i*22) = vending[i].amount;
- WFIFOB(fd,16+i*22) = itemtype(data->type);
- WFIFOW(fd,17+i*22) = (data->view_id > 0) ? data->view_id : sd->status.cart[index].nameid;
- WFIFOB(fd,19+i*22) = sd->status.cart[index].identify;
- WFIFOB(fd,20+i*22) = sd->status.cart[index].attribute;
- WFIFOB(fd,21+i*22) = sd->status.cart[index].refine;
- clif_addcards(WFIFOP(fd,22+i*22), &sd->status.cart[index]);
- }
- WFIFOSET(fd,WFIFOW(fd,2));
+void clif_openvending(struct map_session_data* sd, int id, struct s_vending* vending)
+{
+ int i,fd;
+ int count;
+
+ nullpo_retv(sd);
+
+ fd = sd->fd;
+ count = sd->vend_num;
+
+ WFIFOHEAD(fd, 8+count*22);
+ WFIFOW(fd,0) = 0x136;
+ WFIFOW(fd,2) = 8+count*22;
+ WFIFOL(fd,4) = id;
+ for( i = 0; i < count; i++ )
+ {
+ int index = vending[i].index;
+ struct item_data* data = itemdb_search(sd->status.cart[index].nameid);
+ WFIFOL(fd, 8+i*22) = vending[i].value;
+ WFIFOW(fd,12+i*22) = vending[i].index + 2;
+ WFIFOW(fd,14+i*22) = vending[i].amount;
+ WFIFOB(fd,16+i*22) = itemtype(data->type);
+ WFIFOW(fd,17+i*22) = ( data->view_id > 0 ) ? data->view_id : sd->status.cart[index].nameid;
+ WFIFOB(fd,19+i*22) = sd->status.cart[index].identify;
+ WFIFOB(fd,20+i*22) = sd->status.cart[index].attribute;
+ WFIFOB(fd,21+i*22) = sd->status.cart[index].refine;
+ clif_addcards(WFIFOP(fd,22+i*22), &sd->status.cart[index]);
+ }
+ WFIFOSET(fd,WFIFOW(fd,2));
}
/// Inform merchant that someone has bought an item (ZC_DELETEITEM_FROM_MCSTORE).
/// 0137 <index>.W <amount>.W
-void clif_vendingreport(struct map_session_data *sd, int index, int amount)
+void clif_vendingreport(struct map_session_data* sd, int index, int amount)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x137));
- WFIFOW(fd,0) = 0x137;
- WFIFOW(fd,2) = index+2;
- WFIFOW(fd,4) = amount;
- WFIFOSET(fd,packet_len(0x137));
+ fd = sd->fd;
+ WFIFOHEAD(fd,packet_len(0x137));
+ WFIFOW(fd,0) = 0x137;
+ WFIFOW(fd,2) = index+2;
+ WFIFOW(fd,4) = amount;
+ WFIFOSET(fd,packet_len(0x137));
}
@@ -6164,15 +6225,15 @@ void clif_vendingreport(struct map_session_data *sd, int index, int amount)
/// ? = nothing
void clif_party_created(struct map_session_data *sd,int result)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0xfa));
- WFIFOW(fd,0)=0xfa;
- WFIFOB(fd,2)=result;
- WFIFOSET(fd,packet_len(0xfa));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0xfa));
+ WFIFOW(fd,0)=0xfa;
+ WFIFOB(fd,2)=result;
+ WFIFOSET(fd,packet_len(0xfa));
}
@@ -6187,29 +6248,29 @@ void clif_party_created(struct map_session_data *sd,int result)
/// 1 = disconnected
void clif_party_member_info(struct party_data *p, struct map_session_data *sd)
{
- unsigned char buf[81];
- int i;
+ unsigned char buf[81];
+ int i;
- if (!sd) { //Pick any party member (this call is used when changing item share rules)
- ARR_FIND(0, MAX_PARTY, i, p->data[i].sd != 0);
- } else {
- ARR_FIND(0, MAX_PARTY, i, p->data[i].sd == sd);
- }
- if (i >= MAX_PARTY) return; //Should never happen...
- sd = p->data[i].sd;
+ if (!sd) { //Pick any party member (this call is used when changing item share rules)
+ ARR_FIND( 0, MAX_PARTY, i, p->data[i].sd != 0 );
+ } else {
+ ARR_FIND( 0, MAX_PARTY, i, p->data[i].sd == sd );
+ }
+ if (i >= MAX_PARTY) return; //Should never happen...
+ sd = p->data[i].sd;
- WBUFW(buf, 0) = 0x1e9;
- WBUFL(buf, 2) = sd->status.account_id;
- WBUFL(buf, 6) = (p->party.member[i].leader)?0:1;
- WBUFW(buf,10) = sd->bl.x;
- WBUFW(buf,12) = sd->bl.y;
- WBUFB(buf,14) = (p->party.member[i].online)?0:1;
- memcpy(WBUFP(buf,15), p->party.name, NAME_LENGTH);
- memcpy(WBUFP(buf,39), sd->status.name, NAME_LENGTH);
- mapindex_getmapname_ext(map[sd->bl.m].name, (char *)WBUFP(buf,63));
- WBUFB(buf,79) = (p->party.item&1)?1:0;
- WBUFB(buf,80) = (p->party.item&2)?1:0;
- clif_send(buf,packet_len(0x1e9),&sd->bl,PARTY);
+ WBUFW(buf, 0) = 0x1e9;
+ WBUFL(buf, 2) = sd->status.account_id;
+ WBUFL(buf, 6) = (p->party.member[i].leader)?0:1;
+ WBUFW(buf,10) = sd->bl.x;
+ WBUFW(buf,12) = sd->bl.y;
+ WBUFB(buf,14) = (p->party.member[i].online)?0:1;
+ memcpy(WBUFP(buf,15), p->party.name, NAME_LENGTH);
+ memcpy(WBUFP(buf,39), sd->status.name, NAME_LENGTH);
+ mapindex_getmapname_ext(map[sd->bl.m].name, (char*)WBUFP(buf,63));
+ WBUFB(buf,79) = (p->party.item&1)?1:0;
+ WBUFB(buf,80) = (p->party.item&2)?1:0;
+ clif_send(buf,packet_len(0x1e9),&sd->bl,PARTY);
}
@@ -6221,36 +6282,37 @@ void clif_party_member_info(struct party_data *p, struct map_session_data *sd)
/// state:
/// 0 = connected
/// 1 = disconnected
-void clif_party_info(struct party_data *p, struct map_session_data *sd)
+void clif_party_info(struct party_data* p, struct map_session_data *sd)
{
- unsigned char buf[2+2+NAME_LENGTH+(4+NAME_LENGTH+MAP_NAME_LENGTH_EXT+1+1)*MAX_PARTY];
- struct map_session_data *party_sd = NULL;
- int i, c;
+ unsigned char buf[2+2+NAME_LENGTH+(4+NAME_LENGTH+MAP_NAME_LENGTH_EXT+1+1)*MAX_PARTY];
+ struct map_session_data* party_sd = NULL;
+ int i, c;
- nullpo_retv(p);
+ nullpo_retv(p);
- WBUFW(buf,0) = 0xfb;
- memcpy(WBUFP(buf,4), p->party.name, NAME_LENGTH);
- for (i = 0, c = 0; i < MAX_PARTY; i++) {
- struct party_member *m = &p->party.member[i];
- if (!m->account_id) continue;
+ WBUFW(buf,0) = 0xfb;
+ memcpy(WBUFP(buf,4), p->party.name, NAME_LENGTH);
+ for(i = 0, c = 0; i < MAX_PARTY; i++)
+ {
+ struct party_member* m = &p->party.member[i];
+ if(!m->account_id) continue;
- if (party_sd == NULL) party_sd = p->data[i].sd;
+ if(party_sd == NULL) party_sd = p->data[i].sd;
- WBUFL(buf,28+c*46) = m->account_id;
- memcpy(WBUFP(buf,28+c*46+4), m->name, NAME_LENGTH);
- mapindex_getmapname_ext(mapindex_id2name(m->map), (char *)WBUFP(buf,28+c*46+28));
- WBUFB(buf,28+c*46+44) = (m->leader) ? 0 : 1;
- WBUFB(buf,28+c*46+45) = (m->online) ? 0 : 1;
- c++;
- }
- WBUFW(buf,2) = 28+c*46;
+ WBUFL(buf,28+c*46) = m->account_id;
+ memcpy(WBUFP(buf,28+c*46+4), m->name, NAME_LENGTH);
+ mapindex_getmapname_ext(mapindex_id2name(m->map), (char*)WBUFP(buf,28+c*46+28));
+ WBUFB(buf,28+c*46+44) = (m->leader) ? 0 : 1;
+ WBUFB(buf,28+c*46+45) = (m->online) ? 0 : 1;
+ c++;
+ }
+ WBUFW(buf,2) = 28+c*46;
- if (sd) { // send only to self
- clif_send(buf, WBUFW(buf,2), &sd->bl, SELF);
- } else if (party_sd) { // send to whole party
- clif_send(buf, WBUFW(buf,2), &party_sd->bl, PARTY);
- }
+ if(sd) { // send only to self
+ clif_send(buf, WBUFW(buf,2), &sd->bl, SELF);
+ } else if (party_sd) { // send to whole party
+ clif_send(buf, WBUFW(buf,2), &party_sd->bl, PARTY);
+ }
}
@@ -6259,16 +6321,16 @@ void clif_party_info(struct party_data *p, struct map_session_data *sd)
/// flag:
/// 0 = allow party invites
/// 1 = auto-deny party invites
-void clif_partyinvitationstate(struct map_session_data *sd)
+void clif_partyinvitationstate(struct map_session_data* sd)
{
- int fd;
- nullpo_retv(sd);
- fd = sd->fd;
+ int fd;
+ nullpo_retv(sd);
+ fd = sd->fd;
- WFIFOHEAD(fd, packet_len(0x2c9));
- WFIFOW(fd, 0) = 0x2c9;
- WFIFOB(fd, 2) = 0; // not implemented
- WFIFOSET(fd, packet_len(0x2c9));
+ WFIFOHEAD(fd, packet_len(0x2c9));
+ WFIFOW(fd, 0) = 0x2c9;
+ WFIFOB(fd, 2) = 0; // not implemented
+ WFIFOSET(fd, packet_len(0x2c9));
}
@@ -6278,26 +6340,26 @@ void clif_partyinvitationstate(struct map_session_data *sd)
void clif_party_invite(struct map_session_data *sd,struct map_session_data *tsd)
{
#if PACKETVER < 20070821
- const int cmd = 0xfe;
+ const int cmd = 0xfe;
#else
- const int cmd = 0x2c6;
+ const int cmd = 0x2c6;
#endif
- int fd;
- struct party_data *p;
+ int fd;
+ struct party_data *p;
- nullpo_retv(sd);
- nullpo_retv(tsd);
+ nullpo_retv(sd);
+ nullpo_retv(tsd);
- fd=tsd->fd;
+ fd=tsd->fd;
- if ((p=party_search(sd->status.party_id))==NULL)
- return;
+ if( (p=party_search(sd->status.party_id))==NULL )
+ return;
- WFIFOHEAD(fd,packet_len(cmd));
- WFIFOW(fd,0)=cmd;
- WFIFOL(fd,2)=sd->status.party_id;
- memcpy(WFIFOP(fd,6),p->party.name,NAME_LENGTH);
- WFIFOSET(fd,packet_len(cmd));
+ WFIFOHEAD(fd,packet_len(cmd));
+ WFIFOW(fd,0)=cmd;
+ WFIFOL(fd,2)=sd->status.party_id;
+ memcpy(WFIFOP(fd,6),p->party.name,NAME_LENGTH);
+ WFIFOSET(fd,packet_len(cmd));
}
@@ -6313,31 +6375,31 @@ void clif_party_invite(struct map_session_data *sd,struct map_session_data *tsd)
/// result=7 : char is not online or doesn't exist -> MsgStringTable[71] (since 20070904)
/// result=8 : (%s) TODO instance related? -> MsgStringTable[1388] (since 20080527)
/// return=9 : TODO map prohibits party joining? -> MsgStringTable[1871] (since 20110205)
-void clif_party_inviteack(struct map_session_data *sd, const char *nick, int result)
+void clif_party_inviteack(struct map_session_data* sd, const char* nick, int result)
{
- int fd;
- nullpo_retv(sd);
- fd=sd->fd;
+ int fd;
+ nullpo_retv(sd);
+ fd=sd->fd;
#if PACKETVER < 20070904
- if (result == 7) {
- clif_displaymessage(fd, msg_txt(3));
- return;
- }
+ if( result == 7 ) {
+ clif_displaymessage(fd, msg_txt(3));
+ return;
+ }
#endif
#if PACKETVER < 20070821
- WFIFOHEAD(fd,packet_len(0xfd));
- WFIFOW(fd,0) = 0xfd;
- safestrncpy((char *)WFIFOP(fd,2),nick,NAME_LENGTH);
- WFIFOB(fd,26) = result;
- WFIFOSET(fd,packet_len(0xfd));
+ WFIFOHEAD(fd,packet_len(0xfd));
+ WFIFOW(fd,0) = 0xfd;
+ safestrncpy((char*)WFIFOP(fd,2),nick,NAME_LENGTH);
+ WFIFOB(fd,26) = result;
+ WFIFOSET(fd,packet_len(0xfd));
#else
- WFIFOHEAD(fd,packet_len(0x2c5));
- WFIFOW(fd,0) = 0x2c5;
- safestrncpy((char *)WFIFOP(fd,2),nick,NAME_LENGTH);
- WFIFOL(fd,26) = result;
- WFIFOSET(fd,packet_len(0x2c5));
+ WFIFOHEAD(fd,packet_len(0x2c5));
+ WFIFOW(fd,0) = 0x2c5;
+ safestrncpy((char*)WFIFOP(fd,2),nick,NAME_LENGTH);
+ WFIFOL(fd,26) = result;
+ WFIFOSET(fd,packet_len(0x2c5));
#endif
}
@@ -6355,32 +6417,32 @@ void clif_party_inviteack(struct map_session_data *sd, const char *nick, int res
/// 1 = send to sd
void clif_party_option(struct party_data *p,struct map_session_data *sd,int flag)
{
- unsigned char buf[16];
+ unsigned char buf[16];
#if PACKETVER < 20090603
- const int cmd = 0x101;
+ const int cmd = 0x101;
#else
- const int cmd = 0x7d8;
+ const int cmd = 0x7d8;
#endif
- nullpo_retv(p);
-
- if (!sd && flag==0) {
- int i;
- for (i=0; i<MAX_PARTY && !p->data[i].sd; i++);
- if (i < MAX_PARTY)
- sd = p->data[i].sd;
- }
- if (!sd) return;
- WBUFW(buf,0)=cmd;
- WBUFL(buf,2)=((flag&0x01)?2:p->party.exp);
+ nullpo_retv(p);
+
+ if(!sd && flag==0){
+ int i;
+ for(i=0;i<MAX_PARTY && !p->data[i].sd;i++);
+ if (i < MAX_PARTY)
+ sd = p->data[i].sd;
+ }
+ if(!sd) return;
+ WBUFW(buf,0)=cmd;
+ WBUFL(buf,2)=((flag&0x01)?2:p->party.exp);
#if PACKETVER >= 20090603
- WBUFB(buf,6)=(p->party.item&1)?1:0;
- WBUFB(buf,7)=(p->party.item&2)?1:0;
+ WBUFB(buf,6)=(p->party.item&1)?1:0;
+ WBUFB(buf,7)=(p->party.item&2)?1:0;
#endif
- if (flag==0)
- clif_send(buf,packet_len(cmd),&sd->bl,PARTY);
- else
- clif_send(buf,packet_len(cmd),&sd->bl,SELF);
+ if(flag==0)
+ clif_send(buf,packet_len(cmd),&sd->bl,PARTY);
+ else
+ clif_send(buf,packet_len(cmd),&sd->bl,SELF);
}
@@ -6390,57 +6452,59 @@ void clif_party_option(struct party_data *p,struct map_session_data *sd,int flag
/// 1 = expel
/// 2 = cannot leave party on this map
/// 3 = cannot expel from party on this map
-void clif_party_withdraw(struct party_data *p, struct map_session_data *sd, int account_id, const char *name, int flag)
+void clif_party_withdraw(struct party_data* p, struct map_session_data* sd, int account_id, const char* name, int flag)
{
- unsigned char buf[64];
- int i;
+ unsigned char buf[64];
+ int i;
- nullpo_retv(p);
+ nullpo_retv(p);
- if (!sd && (flag&0xf0)==0) {
- for (i=0; i<MAX_PARTY && !p->data[i].sd; i++);
- if (i < MAX_PARTY)
- sd = p->data[i].sd;
- }
+ if(!sd && (flag&0xf0)==0)
+ {
+ for(i=0;i<MAX_PARTY && !p->data[i].sd;i++);
+ if (i < MAX_PARTY)
+ sd = p->data[i].sd;
+ }
- if (!sd) return;
+ if(!sd) return;
- WBUFW(buf,0)=0x105;
- WBUFL(buf,2)=account_id;
- memcpy(WBUFP(buf,6),name,NAME_LENGTH);
- WBUFB(buf,30)=flag&0x0f;
- if ((flag&0xf0)==0)
- clif_send(buf,packet_len(0x105),&sd->bl,PARTY);
- else
- clif_send(buf,packet_len(0x105),&sd->bl,SELF);
+ WBUFW(buf,0)=0x105;
+ WBUFL(buf,2)=account_id;
+ memcpy(WBUFP(buf,6),name,NAME_LENGTH);
+ WBUFB(buf,30)=flag&0x0f;
+ if((flag&0xf0)==0)
+ clif_send(buf,packet_len(0x105),&sd->bl,PARTY);
+ else
+ clif_send(buf,packet_len(0x105),&sd->bl,SELF);
}
/// Party chat message (ZC_NOTIFY_CHAT_PARTY).
/// 0109 <packet len>.W <account id>.L <message>.?B
-void clif_party_message(struct party_data *p, int account_id, const char *mes, int len)
+void clif_party_message(struct party_data* p, int account_id, const char* mes, int len)
{
- struct map_session_data *sd;
- int i;
+ struct map_session_data *sd;
+ int i;
- nullpo_retv(p);
+ nullpo_retv(p);
- for (i=0; i < MAX_PARTY && !p->data[i].sd; i++);
- if (i < MAX_PARTY) {
- unsigned char buf[1024];
+ for(i=0; i < MAX_PARTY && !p->data[i].sd;i++);
+ if(i < MAX_PARTY){
+ unsigned char buf[1024];
- if (len > sizeof(buf)-8) {
- ShowWarning("clif_party_message: Truncated message '%s' (len=%d, max=%d, party_id=%d).\n", mes, len, sizeof(buf)-8, p->party.party_id);
- len = sizeof(buf)-8;
- }
+ if( len > sizeof(buf)-8 )
+ {
+ ShowWarning("clif_party_message: Truncated message '%s' (len=%d, max=%d, party_id=%d).\n", mes, len, sizeof(buf)-8, p->party.party_id);
+ len = sizeof(buf)-8;
+ }
- sd = p->data[i].sd;
- WBUFW(buf,0)=0x109;
- WBUFW(buf,2)=len+8;
- WBUFL(buf,4)=account_id;
- safestrncpy((char *)WBUFP(buf,8), mes, len);
- clif_send(buf,len+8,&sd->bl,PARTY);
- }
+ sd = p->data[i].sd;
+ WBUFW(buf,0)=0x109;
+ WBUFW(buf,2)=len+8;
+ WBUFL(buf,4)=account_id;
+ safestrncpy(WBUFP(buf,8), mes, len);
+ clif_send(buf,len+8,&sd->bl,PARTY);
+ }
}
@@ -6448,15 +6512,15 @@ void clif_party_message(struct party_data *p, int account_id, const char *mes, i
/// 0107 <account id>.L <x>.W <y>.W
void clif_party_xy(struct map_session_data *sd)
{
- unsigned char buf[16];
+ unsigned char buf[16];
- nullpo_retv(sd);
+ nullpo_retv(sd);
- WBUFW(buf,0)=0x107;
- WBUFL(buf,2)=sd->status.account_id;
- WBUFW(buf,6)=sd->bl.x;
- WBUFW(buf,8)=sd->bl.y;
- clif_send(buf,packet_len(0x107),&sd->bl,PARTY_SAMEMAP_WOS);
+ WBUFW(buf,0)=0x107;
+ WBUFL(buf,2)=sd->status.account_id;
+ WBUFW(buf,6)=sd->bl.x;
+ WBUFW(buf,8)=sd->bl.y;
+ clif_send(buf,packet_len(0x107),&sd->bl,PARTY_SAMEMAP_WOS);
}
@@ -6465,12 +6529,12 @@ void clif_party_xy(struct map_session_data *sd)
*------------------------------------------*/
void clif_party_xy_single(int fd, struct map_session_data *sd)
{
- WFIFOHEAD(fd,packet_len(0x107));
- WFIFOW(fd,0)=0x107;
- WFIFOL(fd,2)=sd->status.account_id;
- WFIFOW(fd,6)=sd->bl.x;
- WFIFOW(fd,8)=sd->bl.y;
- WFIFOSET(fd,packet_len(0x107));
+ WFIFOHEAD(fd,packet_len(0x107));
+ WFIFOW(fd,0)=0x107;
+ WFIFOL(fd,2)=sd->status.account_id;
+ WFIFOW(fd,6)=sd->bl.x;
+ WFIFOW(fd,8)=sd->bl.y;
+ WFIFOSET(fd,packet_len(0x107));
}
@@ -6479,30 +6543,30 @@ void clif_party_xy_single(int fd, struct map_session_data *sd)
/// 080e <account id>.L <hp>.L <max hp>.L (ZC_NOTIFY_HP_TO_GROUPM_R2)
void clif_party_hp(struct map_session_data *sd)
{
- unsigned char buf[16];
+ unsigned char buf[16];
#if PACKETVER < 20100126
- const int cmd = 0x106;
+ const int cmd = 0x106;
#else
- const int cmd = 0x80e;
+ const int cmd = 0x80e;
#endif
- nullpo_retv(sd);
+ nullpo_retv(sd);
- WBUFW(buf,0)=cmd;
- WBUFL(buf,2)=sd->status.account_id;
+ WBUFW(buf,0)=cmd;
+ WBUFL(buf,2)=sd->status.account_id;
#if PACKETVER < 20100126
- if (sd->battle_status.max_hp > INT16_MAX) { //To correctly display the %hp bar. [Skotlex]
- WBUFW(buf,6) = sd->battle_status.hp/(sd->battle_status.max_hp/100);
- WBUFW(buf,8) = 100;
- } else {
- WBUFW(buf,6) = sd->battle_status.hp;
- WBUFW(buf,8) = sd->battle_status.max_hp;
- }
+ if (sd->battle_status.max_hp > INT16_MAX) { //To correctly display the %hp bar. [Skotlex]
+ WBUFW(buf,6) = sd->battle_status.hp/(sd->battle_status.max_hp/100);
+ WBUFW(buf,8) = 100;
+ } else {
+ WBUFW(buf,6) = sd->battle_status.hp;
+ WBUFW(buf,8) = sd->battle_status.max_hp;
+ }
#else
- WBUFL(buf,6) = sd->battle_status.hp;
- WBUFL(buf,10) = sd->battle_status.max_hp;
+ WBUFL(buf,6) = sd->battle_status.hp;
+ WBUFL(buf,10) = sd->battle_status.max_hp;
#endif
- clif_send(buf,packet_len(cmd),&sd->bl,PARTY_AREA_WOS);
+ clif_send(buf,packet_len(cmd),&sd->bl,PARTY_AREA_WOS);
}
@@ -6512,48 +6576,48 @@ void clif_party_hp(struct map_session_data *sd)
void clif_hpmeter_single(int fd, int id, unsigned int hp, unsigned int maxhp)
{
#if PACKETVER < 20100126
- const int cmd = 0x106;
+ const int cmd = 0x106;
#else
- const int cmd = 0x80e;
+ const int cmd = 0x80e;
#endif
- WFIFOHEAD(fd,packet_len(cmd));
- WFIFOW(fd,0) = cmd;
- WFIFOL(fd,2) = id;
+ WFIFOHEAD(fd,packet_len(cmd));
+ WFIFOW(fd,0) = cmd;
+ WFIFOL(fd,2) = id;
#if PACKETVER < 20100126
- if (maxhp > INT16_MAX) {
- // To correctly display the %hp bar. [Skotlex]
- WFIFOW(fd,6) = hp/(maxhp/100);
- WFIFOW(fd,8) = 100;
- } else {
- WFIFOW(fd,6) = hp;
- WFIFOW(fd,8) = maxhp;
- }
+ if( maxhp > INT16_MAX )
+ {// To correctly display the %hp bar. [Skotlex]
+ WFIFOW(fd,6) = hp/(maxhp/100);
+ WFIFOW(fd,8) = 100;
+ } else {
+ WFIFOW(fd,6) = hp;
+ WFIFOW(fd,8) = maxhp;
+ }
#else
- WFIFOL(fd,6) = hp;
- WFIFOL(fd,10) = maxhp;
+ WFIFOL(fd,6) = hp;
+ WFIFOL(fd,10) = maxhp;
#endif
- WFIFOSET(fd, packet_len(cmd));
+ WFIFOSET(fd, packet_len(cmd));
}
/// Notifies the client, that it's attack target is too far (ZC_ATTACK_FAILURE_FOR_DISTANCE).
/// 0139 <target id>.L <target x>.W <target y>.W <x>.W <y>.W <atk range>.W
void clif_movetoattack(struct map_session_data *sd,struct block_list *bl)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
- nullpo_retv(bl);
+ nullpo_retv(sd);
+ nullpo_retv(bl);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x139));
- WFIFOW(fd, 0)=0x139;
- WFIFOL(fd, 2)=bl->id;
- WFIFOW(fd, 6)=bl->x;
- WFIFOW(fd, 8)=bl->y;
- WFIFOW(fd,10)=sd->bl.x;
- WFIFOW(fd,12)=sd->bl.y;
- WFIFOW(fd,14)=sd->battle_status.rhw.range;
- WFIFOSET(fd,packet_len(0x139));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0x139));
+ WFIFOW(fd, 0)=0x139;
+ WFIFOL(fd, 2)=bl->id;
+ WFIFOW(fd, 6)=bl->x;
+ WFIFOW(fd, 8)=bl->y;
+ WFIFOW(fd,10)=sd->bl.x;
+ WFIFOW(fd,12)=sd->bl.y;
+ WFIFOW(fd,14)=sd->battle_status.rhw.range;
+ WFIFOSET(fd,packet_len(0x139));
}
@@ -6564,22 +6628,22 @@ void clif_movetoattack(struct map_session_data *sd,struct block_list *bl)
/// 1 = failure
/// 2 = success (alchemist)
/// 3 = failure (alchemist)
-void clif_produceeffect(struct map_session_data *sd,int flag,int nameid)
+void clif_produceeffect(struct map_session_data* sd,int flag,int nameid)
{
- int view,fd;
+ int view,fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd = sd->fd;
- clif_solved_charname(fd, sd->status.char_id, sd->status.name);
- WFIFOHEAD(fd,packet_len(0x18f));
- WFIFOW(fd, 0)=0x18f;
- WFIFOW(fd, 2)=flag;
- if ((view = itemdb_viewid(nameid)) > 0)
- WFIFOW(fd, 4)=view;
- else
- WFIFOW(fd, 4)=nameid;
- WFIFOSET(fd,packet_len(0x18f));
+ fd = sd->fd;
+ clif_solved_charname(fd, sd->status.char_id, sd->status.name);
+ WFIFOHEAD(fd,packet_len(0x18f));
+ WFIFOW(fd, 0)=0x18f;
+ WFIFOW(fd, 2)=flag;
+ if((view = itemdb_viewid(nameid)) > 0)
+ WFIFOW(fd, 4)=view;
+ else
+ WFIFOW(fd, 4)=nameid;
+ WFIFOSET(fd,packet_len(0x18f));
}
@@ -6587,14 +6651,14 @@ void clif_produceeffect(struct map_session_data *sd,int flag,int nameid)
/// 019e
void clif_catch_process(struct map_session_data *sd)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x19e));
- WFIFOW(fd,0)=0x19e;
- WFIFOSET(fd,packet_len(0x19e));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0x19e));
+ WFIFOW(fd,0)=0x19e;
+ WFIFOSET(fd,packet_len(0x19e));
}
@@ -6604,15 +6668,15 @@ void clif_catch_process(struct map_session_data *sd)
/// 1 = success
void clif_pet_roulette(struct map_session_data *sd,int data)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x1a0));
- WFIFOW(fd,0)=0x1a0;
- WFIFOB(fd,2)=data;
- WFIFOSET(fd,packet_len(0x1a0));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0x1a0));
+ WFIFOW(fd,0)=0x1a0;
+ WFIFOB(fd,2)=data;
+ WFIFOSET(fd,packet_len(0x1a0));
}
@@ -6620,31 +6684,31 @@ void clif_pet_roulette(struct map_session_data *sd,int data)
/// 01a6 <packet len>.W { <index>.W }*
void clif_sendegg(struct map_session_data *sd)
{
- int i,n=0,fd;
+ int i,n=0,fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- if (battle_config.pet_no_gvg && map_flag_gvg(sd->bl.m)) {
- //Disable pet hatching in GvG grounds during Guild Wars [Skotlex]
- clif_displaymessage(fd, msg_txt(666));
- return;
- }
- WFIFOHEAD(fd, MAX_INVENTORY * 2 + 4);
- WFIFOW(fd,0)=0x1a6;
- for (i=0,n=0; i<MAX_INVENTORY; i++) {
- if (sd->status.inventory[i].nameid<=0 || sd->inventory_data[i] == NULL ||
- sd->inventory_data[i]->type!=IT_PETEGG ||
- sd->status.inventory[i].amount<=0)
- continue;
- WFIFOW(fd,n*2+4)=i+2;
- n++;
- }
- WFIFOW(fd,2)=4+n*2;
- WFIFOSET(fd,WFIFOW(fd,2));
+ fd=sd->fd;
+ if (battle_config.pet_no_gvg && map_flag_gvg(sd->bl.m))
+ { //Disable pet hatching in GvG grounds during Guild Wars [Skotlex]
+ clif_displaymessage(fd, msg_txt(666));
+ return;
+ }
+ WFIFOHEAD(fd, MAX_INVENTORY * 2 + 4);
+ WFIFOW(fd,0)=0x1a6;
+ for(i=0,n=0;i<MAX_INVENTORY;i++){
+ if(sd->status.inventory[i].nameid<=0 || sd->inventory_data[i] == NULL ||
+ sd->inventory_data[i]->type!=IT_PETEGG ||
+ sd->status.inventory[i].amount<=0)
+ continue;
+ WFIFOW(fd,n*2+4)=i+2;
+ n++;
+ }
+ WFIFOW(fd,2)=4+n*2;
+ WFIFOSET(fd,WFIFOW(fd,2));
- sd->menuskill_id = SA_TAMINGMONSTER;
- sd->menuskill_val = -1;
+ sd->menuskill_id = SA_TAMINGMONSTER;
+ sd->menuskill_val = -1;
}
@@ -6659,19 +6723,19 @@ void clif_sendegg(struct map_session_data *sd)
/// 5 = hairstyle
///
/// If sd is null, the update is sent to nearby objects, otherwise it is sent only to that player.
-void clif_send_petdata(struct map_session_data *sd, struct pet_data *pd, int type, int param)
+void clif_send_petdata(struct map_session_data* sd, struct pet_data* pd, int type, int param)
{
- uint8 buf[16];
- nullpo_retv(pd);
+ uint8 buf[16];
+ nullpo_retv(pd);
- WBUFW(buf,0) = 0x1a4;
- WBUFB(buf,2) = type;
- WBUFL(buf,3) = pd->bl.id;
- WBUFL(buf,7) = param;
- if (sd)
- clif_send(buf, packet_len(0x1a4), &sd->bl, SELF);
- else
- clif_send(buf, packet_len(0x1a4), &pd->bl, AREA);
+ WBUFW(buf,0) = 0x1a4;
+ WBUFB(buf,2) = type;
+ WBUFL(buf,3) = pd->bl.id;
+ WBUFL(buf,7) = param;
+ if (sd)
+ clif_send(buf, packet_len(0x1a4), &sd->bl, SELF);
+ else
+ clif_send(buf, packet_len(0x1a4), &pd->bl, AREA);
}
@@ -6679,26 +6743,26 @@ void clif_send_petdata(struct map_session_data *sd, struct pet_data *pd, int typ
/// 01a2 <name>.24B <renamed>.B <level>.W <hunger>.W <intimacy>.W <accessory id>.W <class>.W
void clif_send_petstatus(struct map_session_data *sd)
{
- int fd;
- struct s_pet *pet;
-
- nullpo_retv(sd);
- nullpo_retv(sd->pd);
-
- fd=sd->fd;
- pet = &sd->pd->pet;
- WFIFOHEAD(fd,packet_len(0x1a2));
- WFIFOW(fd,0)=0x1a2;
- memcpy(WFIFOP(fd,2),pet->name,NAME_LENGTH);
- WFIFOB(fd,26)=battle_config.pet_rename?0:pet->rename_flag;
- WFIFOW(fd,27)=pet->level;
- WFIFOW(fd,29)=pet->hungry;
- WFIFOW(fd,31)=pet->intimate;
- WFIFOW(fd,33)=pet->equip;
+ int fd;
+ struct s_pet *pet;
+
+ nullpo_retv(sd);
+ nullpo_retv(sd->pd);
+
+ fd=sd->fd;
+ pet = &sd->pd->pet;
+ WFIFOHEAD(fd,packet_len(0x1a2));
+ WFIFOW(fd,0)=0x1a2;
+ memcpy(WFIFOP(fd,2),pet->name,NAME_LENGTH);
+ WFIFOB(fd,26)=battle_config.pet_rename?0:pet->rename_flag;
+ WFIFOW(fd,27)=pet->level;
+ WFIFOW(fd,29)=pet->hungry;
+ WFIFOW(fd,31)=pet->intimate;
+ WFIFOW(fd,33)=pet->equip;
#if PACKETVER >= 20081126
- WFIFOW(fd,35)=pet->class_;
+ WFIFOW(fd,35)=pet->class_;
#endif
- WFIFOSET(fd,packet_len(0x1a2));
+ WFIFOSET(fd,packet_len(0x1a2));
}
@@ -6708,26 +6772,26 @@ void clif_send_petstatus(struct map_session_data *sd)
/// @see CZ_PET_ACT.
void clif_pet_emotion(struct pet_data *pd,int param)
{
- unsigned char buf[16];
+ unsigned char buf[16];
- nullpo_retv(pd);
+ nullpo_retv(pd);
- memset(buf,0,packet_len(0x1aa));
+ memset(buf,0,packet_len(0x1aa));
- WBUFW(buf,0)=0x1aa;
- WBUFL(buf,2)=pd->bl.id;
- if (param >= 100 && pd->petDB->talk_convert_class) {
- if (pd->petDB->talk_convert_class < 0)
- return;
- else if (pd->petDB->talk_convert_class > 0) {
- // replace mob_id component of talk/act data
- param -= (pd->pet.class_ - 100)*100;
- param += (pd->petDB->talk_convert_class - 100)*100;
- }
- }
- WBUFL(buf,6)=param;
+ WBUFW(buf,0)=0x1aa;
+ WBUFL(buf,2)=pd->bl.id;
+ if(param >= 100 && pd->petDB->talk_convert_class) {
+ if(pd->petDB->talk_convert_class < 0)
+ return;
+ else if(pd->petDB->talk_convert_class > 0) {
+ // replace mob_id component of talk/act data
+ param -= (pd->pet.class_ - 100)*100;
+ param += (pd->petDB->talk_convert_class - 100)*100;
+ }
+ }
+ WBUFL(buf,6)=param;
- clif_send(buf,packet_len(0x1aa),&pd->bl,AREA);
+ clif_send(buf,packet_len(0x1aa),&pd->bl,AREA);
}
@@ -6738,16 +6802,16 @@ void clif_pet_emotion(struct pet_data *pd,int param)
/// 1 = success
void clif_pet_food(struct map_session_data *sd,int foodid,int fail)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x1a3));
- WFIFOW(fd,0)=0x1a3;
- WFIFOB(fd,2)=fail;
- WFIFOW(fd,3)=foodid;
- WFIFOSET(fd,packet_len(0x1a3));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0x1a3));
+ WFIFOW(fd,0)=0x1a3;
+ WFIFOB(fd,2)=fail;
+ WFIFOW(fd,3)=foodid;
+ WFIFOSET(fd,packet_len(0x1a3));
}
@@ -6755,46 +6819,46 @@ void clif_pet_food(struct map_session_data *sd,int foodid,int fail)
/// 01cd { <skill id>.L }*7
void clif_autospell(struct map_session_data *sd,int skilllv)
{
- int fd;
-
- nullpo_retv(sd);
-
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x1cd));
- WFIFOW(fd, 0)=0x1cd;
-
- if (skilllv>0 && pc_checkskill(sd,MG_NAPALMBEAT)>0)
- WFIFOL(fd,2)= MG_NAPALMBEAT;
- else
- WFIFOL(fd,2)= 0x00000000;
- if (skilllv>1 && pc_checkskill(sd,MG_COLDBOLT)>0)
- WFIFOL(fd,6)= MG_COLDBOLT;
- else
- WFIFOL(fd,6)= 0x00000000;
- if (skilllv>1 && pc_checkskill(sd,MG_FIREBOLT)>0)
- WFIFOL(fd,10)= MG_FIREBOLT;
- else
- WFIFOL(fd,10)= 0x00000000;
- if (skilllv>1 && pc_checkskill(sd,MG_LIGHTNINGBOLT)>0)
- WFIFOL(fd,14)= MG_LIGHTNINGBOLT;
- else
- WFIFOL(fd,14)= 0x00000000;
- if (skilllv>4 && pc_checkskill(sd,MG_SOULSTRIKE)>0)
- WFIFOL(fd,18)= MG_SOULSTRIKE;
- else
- WFIFOL(fd,18)= 0x00000000;
- if (skilllv>7 && pc_checkskill(sd,MG_FIREBALL)>0)
- WFIFOL(fd,22)= MG_FIREBALL;
- else
- WFIFOL(fd,22)= 0x00000000;
- if (skilllv>9 && pc_checkskill(sd,MG_FROSTDIVER)>0)
- WFIFOL(fd,26)= MG_FROSTDIVER;
- else
- WFIFOL(fd,26)= 0x00000000;
-
- WFIFOSET(fd,packet_len(0x1cd));
- sd->menuskill_id = SA_AUTOSPELL;
- sd->menuskill_val = skilllv;
+ int fd;
+
+ nullpo_retv(sd);
+
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0x1cd));
+ WFIFOW(fd, 0)=0x1cd;
+
+ if(skilllv>0 && pc_checkskill(sd,MG_NAPALMBEAT)>0)
+ WFIFOL(fd,2)= MG_NAPALMBEAT;
+ else
+ WFIFOL(fd,2)= 0x00000000;
+ if(skilllv>1 && pc_checkskill(sd,MG_COLDBOLT)>0)
+ WFIFOL(fd,6)= MG_COLDBOLT;
+ else
+ WFIFOL(fd,6)= 0x00000000;
+ if(skilllv>1 && pc_checkskill(sd,MG_FIREBOLT)>0)
+ WFIFOL(fd,10)= MG_FIREBOLT;
+ else
+ WFIFOL(fd,10)= 0x00000000;
+ if(skilllv>1 && pc_checkskill(sd,MG_LIGHTNINGBOLT)>0)
+ WFIFOL(fd,14)= MG_LIGHTNINGBOLT;
+ else
+ WFIFOL(fd,14)= 0x00000000;
+ if(skilllv>4 && pc_checkskill(sd,MG_SOULSTRIKE)>0)
+ WFIFOL(fd,18)= MG_SOULSTRIKE;
+ else
+ WFIFOL(fd,18)= 0x00000000;
+ if(skilllv>7 && pc_checkskill(sd,MG_FIREBALL)>0)
+ WFIFOL(fd,22)= MG_FIREBALL;
+ else
+ WFIFOL(fd,22)= 0x00000000;
+ if(skilllv>9 && pc_checkskill(sd,MG_FROSTDIVER)>0)
+ WFIFOL(fd,26)= MG_FROSTDIVER;
+ else
+ WFIFOL(fd,26)= 0x00000000;
+
+ WFIFOSET(fd,packet_len(0x1cd));
+ sd->menuskill_id = SA_AUTOSPELL;
+ sd->menuskill_val = skilllv;
}
@@ -6802,34 +6866,37 @@ void clif_autospell(struct map_session_data *sd,int skilllv)
/// 01cf <devoter id>.L { <devotee id>.L }*5 <max distance>.W
void clif_devotion(struct block_list *src, struct map_session_data *tsd)
{
- unsigned char buf[56];
- int i;
+ unsigned char buf[56];
+ int i;
- nullpo_retv(src);
- memset(buf,0,packet_len(0x1cf));
+ nullpo_retv(src);
+ memset(buf,0,packet_len(0x1cf));
- WBUFW(buf,0) = 0x1cf;
- WBUFL(buf,2) = src->id;
- if (src->type == BL_MER) {
- struct mercenary_data *md = BL_CAST(BL_MER,src);
- if (md && md->master && md->devotion_flag)
- WBUFL(buf,6) = md->master->bl.id;
+ WBUFW(buf,0) = 0x1cf;
+ WBUFL(buf,2) = src->id;
+ if( src->type == BL_MER )
+ {
+ struct mercenary_data *md = BL_CAST(BL_MER,src);
+ if( md && md->master && md->devotion_flag )
+ WBUFL(buf,6) = md->master->bl.id;
- WBUFW(buf,26) = skill_get_range2(src, ML_DEVOTION, mercenary_checkskill(md, ML_DEVOTION));
- } else {
- struct map_session_data *sd = BL_CAST(BL_PC,src);
- if (sd == NULL)
- return;
+ WBUFW(buf,26) = skill_get_range2(src, ML_DEVOTION, mercenary_checkskill(md, ML_DEVOTION));
+ }
+ else
+ {
+ struct map_session_data *sd = BL_CAST(BL_PC,src);
+ if( sd == NULL )
+ return;
- for (i = 0; i < 5; i++)
- WBUFL(buf,6+4*i) = sd->devotion[i];
- WBUFW(buf,26) = skill_get_range2(src, CR_DEVOTION, pc_checkskill(sd, CR_DEVOTION));
- }
+ for( i = 0; i < 5; i++ )
+ WBUFL(buf,6+4*i) = sd->devotion[i];
+ WBUFW(buf,26) = skill_get_range2(src, CR_DEVOTION, pc_checkskill(sd, CR_DEVOTION));
+ }
- if (tsd)
- clif_send(buf, packet_len(0x1cf), &tsd->bl, SELF);
- else
- clif_send(buf, packet_len(0x1cf), src, AREA);
+ if( tsd )
+ clif_send(buf, packet_len(0x1cf), &tsd->bl, SELF);
+ else
+ clif_send(buf, packet_len(0x1cf), src, AREA);
}
/*==========================================
@@ -6838,8 +6905,7 @@ void clif_devotion(struct block_list *src, struct map_session_data *tsd)
* 01d0 <id>.L <amount>.W (ZC_SPIRITS)
* 01e1 <id>.L <amount>.W (ZC_SPIRITS2)
*------------------------------------------*/
-void clif_spiritball(struct block_list *bl)
-{
+void clif_spiritball(struct block_list *bl) {
unsigned char buf[16];
TBL_PC *sd = BL_CAST(BL_PC,bl);
TBL_HOM *hd = BL_CAST(BL_HOM,bl);
@@ -6848,14 +6914,10 @@ void clif_spiritball(struct block_list *bl)
WBUFW(buf, 0) = 0x1d0;
WBUFL(buf, 2) = bl->id;
- WBUFW(buf, 6) = 0; //init to 0
- switch (bl->type) {
- case BL_PC:
- WBUFW(buf, 6) = sd->spiritball;
- break;
- case BL_HOM:
- WBUFW(buf, 6) = hd->spiritball;
- break;
+ WBUFW(buf, 6) = 0; //init to 0
+ switch(bl->type){
+ case BL_PC: WBUFW(buf, 6) = sd->spiritball; break;
+ case BL_HOM: WBUFW(buf, 6) = hd->spiritball; break;
}
clif_send(buf, packet_len(0x1d0), bl, AREA);
}
@@ -6865,14 +6927,14 @@ void clif_spiritball(struct block_list *bl)
/// 01d2 <account id>.L <delay>.L
void clif_combo_delay(struct block_list *bl,int wait)
{
- unsigned char buf[32];
+ unsigned char buf[32];
- nullpo_retv(bl);
+ nullpo_retv(bl);
- WBUFW(buf,0)=0x1d2;
- WBUFL(buf,2)=bl->id;
- WBUFL(buf,6)=wait;
- clif_send(buf,packet_len(0x1d2),bl,AREA);
+ WBUFW(buf,0)=0x1d2;
+ WBUFL(buf,2)=bl->id;
+ WBUFL(buf,6)=wait;
+ clif_send(buf,packet_len(0x1d2),bl,AREA);
}
@@ -6883,16 +6945,16 @@ void clif_combo_delay(struct block_list *bl,int wait)
/// 1 = active
void clif_bladestop(struct block_list *src, int dst_id, int active)
{
- unsigned char buf[32];
+ unsigned char buf[32];
- nullpo_retv(src);
+ nullpo_retv(src);
- WBUFW(buf,0)=0x1d1;
- WBUFL(buf,2)=src->id;
- WBUFL(buf,6)=dst_id;
- WBUFL(buf,10)=active;
+ WBUFW(buf,0)=0x1d1;
+ WBUFL(buf,2)=src->id;
+ WBUFL(buf,6)=dst_id;
+ WBUFL(buf,10)=active;
- clif_send(buf,packet_len(0x1d1),src,AREA);
+ clif_send(buf,packet_len(0x1d1),src,AREA);
}
@@ -6900,13 +6962,13 @@ void clif_bladestop(struct block_list *src, int dst_id, int active)
/// 010c <account id>.L
void clif_mvp_effect(struct map_session_data *sd)
{
- unsigned char buf[16];
+ unsigned char buf[16];
- nullpo_retv(sd);
+ nullpo_retv(sd);
- WBUFW(buf,0)=0x10c;
- WBUFL(buf,2)=sd->bl.id;
- clif_send(buf,packet_len(0x10c),&sd->bl,AREA);
+ WBUFW(buf,0)=0x10c;
+ WBUFL(buf,2)=sd->bl.id;
+ clif_send(buf,packet_len(0x10c),&sd->bl,AREA);
}
@@ -6914,18 +6976,18 @@ void clif_mvp_effect(struct map_session_data *sd)
/// 010a <name id>.W
void clif_mvp_item(struct map_session_data *sd,int nameid)
{
- int view,fd;
+ int view,fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x10a));
- WFIFOW(fd,0)=0x10a;
- if ((view = itemdb_viewid(nameid)) > 0)
- WFIFOW(fd,2)=view;
- else
- WFIFOW(fd,2)=nameid;
- WFIFOSET(fd,packet_len(0x10a));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0x10a));
+ WFIFOW(fd,0)=0x10a;
+ if((view = itemdb_viewid(nameid)) > 0)
+ WFIFOW(fd,2)=view;
+ else
+ WFIFOW(fd,2)=nameid;
+ WFIFOSET(fd,packet_len(0x10a));
}
@@ -6933,15 +6995,15 @@ void clif_mvp_item(struct map_session_data *sd,int nameid)
/// 010b <exp>.L
void clif_mvp_exp(struct map_session_data *sd, unsigned int exp)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x10b));
- WFIFOW(fd,0)=0x10b;
- WFIFOL(fd,2)=cap_value(exp,0,INT32_MAX);
- WFIFOSET(fd,packet_len(0x10b));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0x10b));
+ WFIFOW(fd,0)=0x10b;
+ WFIFOL(fd,2)=cap_value(exp,0,INT32_MAX);
+ WFIFOSET(fd,packet_len(0x10b));
}
@@ -6950,13 +7012,13 @@ void clif_mvp_exp(struct map_session_data *sd, unsigned int exp)
///
/// "You are the MVP, but cannot obtain the reward because
/// you are overweight."
-void clif_mvp_noitem(struct map_session_data *sd)
+void clif_mvp_noitem(struct map_session_data* sd)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x10d));
- WFIFOW(fd,0) = 0x10d;
- WFIFOSET(fd,packet_len(0x10d));
+ WFIFOHEAD(fd,packet_len(0x10d));
+ WFIFOW(fd,0) = 0x10d;
+ WFIFOSET(fd,packet_len(0x10d));
}
@@ -6969,15 +7031,15 @@ void clif_mvp_noitem(struct map_session_data *sd)
/// 3 = "You need the neccessary item to create a Guild."
void clif_guild_created(struct map_session_data *sd,int flag)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x167));
- WFIFOW(fd,0)=0x167;
- WFIFOB(fd,2)=flag;
- WFIFOSET(fd,packet_len(0x167));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0x167));
+ WFIFOW(fd,0)=0x167;
+ WFIFOB(fd,2)=flag;
+ WFIFOSET(fd,packet_len(0x167));
}
@@ -6988,21 +7050,21 @@ void clif_guild_created(struct map_session_data *sd,int flag)
/// &0x10 = allow expel
void clif_guild_belonginfo(struct map_session_data *sd, struct guild *g)
{
- int ps,fd;
- nullpo_retv(sd);
- nullpo_retv(g);
+ int ps,fd;
+ nullpo_retv(sd);
+ nullpo_retv(g);
- fd=sd->fd;
- ps=guild_getposition(g,sd);
- WFIFOHEAD(fd,packet_len(0x16c));
- WFIFOW(fd,0)=0x16c;
- WFIFOL(fd,2)=g->guild_id;
- WFIFOL(fd,6)=g->emblem_id;
- WFIFOL(fd,10)=g->position[ps].mode;
- WFIFOB(fd,14)=(bool)(sd->state.gmaster_flag==g);
- WFIFOL(fd,15)=0; // InterSID (unknown purpose)
- memcpy(WFIFOP(fd,19),g->name,NAME_LENGTH);
- WFIFOSET(fd,packet_len(0x16c));
+ fd=sd->fd;
+ ps=guild_getposition(g,sd);
+ WFIFOHEAD(fd,packet_len(0x16c));
+ WFIFOW(fd,0)=0x16c;
+ WFIFOL(fd,2)=g->guild_id;
+ WFIFOL(fd,6)=g->emblem_id;
+ WFIFOL(fd,10)=g->position[ps].mode;
+ WFIFOB(fd,14)=(bool)(sd->state.gmaster_flag==g);
+ WFIFOL(fd,15)=0; // InterSID (unknown purpose)
+ memcpy(WFIFOP(fd,19),g->name,NAME_LENGTH);
+ WFIFOSET(fd,packet_len(0x16c));
}
@@ -7014,27 +7076,30 @@ void clif_guild_belonginfo(struct map_session_data *sd, struct guild *g)
/// 1 = online
void clif_guild_memberlogin_notice(struct guild *g,int idx,int flag)
{
- unsigned char buf[64];
- struct map_session_data *sd;
-
- nullpo_retv(g);
-
- WBUFW(buf, 0)=0x1f2;
- WBUFL(buf, 2)=g->member[idx].account_id;
- WBUFL(buf, 6)=g->member[idx].char_id;
- WBUFL(buf,10)=flag;
-
- if ((sd = g->member[idx].sd) != NULL) {
- WBUFW(buf,14) = sd->status.sex;
- WBUFW(buf,16) = sd->status.hair;
- WBUFW(buf,18) = sd->status.hair_color;
- clif_send(buf,packet_len(0x1f2),&sd->bl,GUILD_WOS);
- } else if ((sd = guild_getavailablesd(g)) != NULL) {
- WBUFW(buf,14) = 0;
- WBUFW(buf,16) = 0;
- WBUFW(buf,18) = 0;
- clif_send(buf,packet_len(0x1f2),&sd->bl,GUILD);
- }
+ unsigned char buf[64];
+ struct map_session_data* sd;
+
+ nullpo_retv(g);
+
+ WBUFW(buf, 0)=0x1f2;
+ WBUFL(buf, 2)=g->member[idx].account_id;
+ WBUFL(buf, 6)=g->member[idx].char_id;
+ WBUFL(buf,10)=flag;
+
+ if( ( sd = g->member[idx].sd ) != NULL )
+ {
+ WBUFW(buf,14) = sd->status.sex;
+ WBUFW(buf,16) = sd->status.hair;
+ WBUFW(buf,18) = sd->status.hair_color;
+ clif_send(buf,packet_len(0x1f2),&sd->bl,GUILD_WOS);
+ }
+ else if( ( sd = guild_getavailablesd(g) ) != NULL )
+ {
+ WBUFW(buf,14) = 0;
+ WBUFW(buf,16) = 0;
+ WBUFW(buf,18) = 0;
+ clif_send(buf,packet_len(0x1f2),&sd->bl,GUILD);
+ }
}
// Function `clif_guild_memberlogin_notice` sends info about
@@ -7048,31 +7113,31 @@ void clif_guild_memberlogin_notice(struct guild *g,int idx,int flag)
// to economize traffic. [LuzZza]
void clif_guild_send_onlineinfo(struct map_session_data *sd)
{
- struct guild *g;
- unsigned char buf[14*128];
- int i, count=0, p_len;
+ struct guild *g;
+ unsigned char buf[14*128];
+ int i, count=0, p_len;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- p_len = packet_len(0x16d);
+ p_len = packet_len(0x16d);
- if (!(g = guild_search(sd->status.guild_id)))
- return;
+ if(!(g = guild_search(sd->status.guild_id)))
+ return;
- for (i=0; i<g->max_member; i++) {
+ for(i=0; i<g->max_member; i++) {
- if (g->member[i].account_id > 0 &&
- g->member[i].account_id != sd->status.account_id) {
+ if(g->member[i].account_id > 0 &&
+ g->member[i].account_id != sd->status.account_id) {
- WBUFW(buf,count*p_len) = 0x16d;
- WBUFL(buf,count*p_len+2) = g->member[i].account_id;
- WBUFL(buf,count*p_len+6) = g->member[i].char_id;
- WBUFL(buf,count*p_len+10) = g->member[i].online;
- count++;
- }
- }
+ WBUFW(buf,count*p_len) = 0x16d;
+ WBUFL(buf,count*p_len+2) = g->member[i].account_id;
+ WBUFL(buf,count*p_len+6) = g->member[i].char_id;
+ WBUFL(buf,count*p_len+10) = g->member[i].online;
+ count++;
+ }
+ }
- clif_send(buf, p_len*count, &sd->bl, SELF);
+ clif_send(buf, p_len*count, &sd->bl, SELF);
}
@@ -7088,52 +7153,51 @@ void clif_guild_send_onlineinfo(struct map_session_data *sd)
/// &0x80 = Notice
void clif_guild_masterormember(struct map_session_data *sd)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x14e));
- WFIFOW(fd,0) = 0x14e;
- WFIFOL(fd,2) = (sd->state.gmaster_flag) ? 0xd7 : 0x57;
- WFIFOSET(fd,packet_len(0x14e));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0x14e));
+ WFIFOW(fd,0) = 0x14e;
+ WFIFOL(fd,2) = (sd->state.gmaster_flag) ? 0xd7 : 0x57;
+ WFIFOSET(fd,packet_len(0x14e));
}
/// Guild basic information (Territories [Valaris])
/// 0150 <guild id>.L <level>.L <member num>.L <member max>.L <exp>.L <max exp>.L <points>.L <honor>.L <virtue>.L <emblem id>.L <name>.24B <master name>.24B <manage land>.16B (ZC_GUILD_INFO)
/// 01b6 <guild id>.L <level>.L <member num>.L <member max>.L <exp>.L <max exp>.L <points>.L <honor>.L <virtue>.L <emblem id>.L <name>.24B <master name>.24B <manage land>.16B <zeny>.L (ZC_GUILD_INFO2)
-void clif_guild_basicinfo(struct map_session_data *sd)
-{
- int fd;
- struct guild *g;
+void clif_guild_basicinfo(struct map_session_data *sd) {
+ int fd;
+ struct guild *g;
- nullpo_retv(sd);
- fd = sd->fd;
+ nullpo_retv(sd);
+ fd = sd->fd;
- if ((g = guild_search(sd->status.guild_id)) == NULL)
- return;
+ if( (g = guild_search(sd->status.guild_id)) == NULL )
+ return;
- WFIFOHEAD(fd,packet_len(0x1b6));
- WFIFOW(fd, 0)=0x1b6;//0x150;
- WFIFOL(fd, 2)=g->guild_id;
- WFIFOL(fd, 6)=g->guild_lv;
- WFIFOL(fd,10)=g->connect_member;
- WFIFOL(fd,14)=g->max_member;
- WFIFOL(fd,18)=g->average_lv;
- WFIFOL(fd,22)=(uint32)cap_value(g->exp,0,INT32_MAX);
- WFIFOL(fd,26)=g->next_exp;
- WFIFOL(fd,30)=0; // Tax Points
- WFIFOL(fd,34)=0; // Honor: (left) Vulgar [-100,100] Famed (right)
- WFIFOL(fd,38)=0; // Virtue: (down) Wicked [-100,100] Righteous (up)
- WFIFOL(fd,42)=g->emblem_id;
- memcpy(WFIFOP(fd,46),g->name, NAME_LENGTH);
- memcpy(WFIFOP(fd,70),g->master, NAME_LENGTH);
+ WFIFOHEAD(fd,packet_len(0x1b6));
+ WFIFOW(fd, 0)=0x1b6;//0x150;
+ WFIFOL(fd, 2)=g->guild_id;
+ WFIFOL(fd, 6)=g->guild_lv;
+ WFIFOL(fd,10)=g->connect_member;
+ WFIFOL(fd,14)=g->max_member;
+ WFIFOL(fd,18)=g->average_lv;
+ WFIFOL(fd,22)=(uint32)cap_value(g->exp,0,INT32_MAX);
+ WFIFOL(fd,26)=g->next_exp;
+ WFIFOL(fd,30)=0; // Tax Points
+ WFIFOL(fd,34)=0; // Honor: (left) Vulgar [-100,100] Famed (right)
+ WFIFOL(fd,38)=0; // Virtue: (down) Wicked [-100,100] Righteous (up)
+ WFIFOL(fd,42)=g->emblem_id;
+ memcpy(WFIFOP(fd,46),g->name, NAME_LENGTH);
+ memcpy(WFIFOP(fd,70),g->master, NAME_LENGTH);
- safestrncpy((char *)WFIFOP(fd,94),msg_txt(300+guild_checkcastles(g)),16); // "'N' castles"
- WFIFOL(fd,110) = 0; // zeny
+ safestrncpy((char*)WFIFOP(fd,94),msg_txt(300+guild_checkcastles(g)),16); // "'N' castles"
+ WFIFOL(fd,110) = 0; // zeny
- WFIFOSET(fd,packet_len(0x1b6));
+ WFIFOSET(fd,packet_len(0x1b6));
}
@@ -7141,27 +7205,27 @@ void clif_guild_basicinfo(struct map_session_data *sd)
/// 014c <packet len>.W { <relation>.L <guild id>.L <guild name>.24B }*
void clif_guild_allianceinfo(struct map_session_data *sd)
{
- int fd,i,c;
- struct guild *g;
+ int fd,i,c;
+ struct guild *g;
- nullpo_retv(sd);
- if ((g = guild_search(sd->status.guild_id)) == NULL)
- return;
-
- fd = sd->fd;
- WFIFOHEAD(fd, MAX_GUILDALLIANCE * 32 + 4);
- WFIFOW(fd, 0)=0x14c;
- for (i=c=0; i<MAX_GUILDALLIANCE; i++) {
- struct guild_alliance *a=&g->alliance[i];
- if (a->guild_id>0) {
- WFIFOL(fd,c*32+4)=a->opposition;
- WFIFOL(fd,c*32+8)=a->guild_id;
- memcpy(WFIFOP(fd,c*32+12),a->name,NAME_LENGTH);
- c++;
- }
- }
- WFIFOW(fd, 2)=c*32+4;
- WFIFOSET(fd,WFIFOW(fd,2));
+ nullpo_retv(sd);
+ if( (g = guild_search(sd->status.guild_id)) == NULL )
+ return;
+
+ fd = sd->fd;
+ WFIFOHEAD(fd, MAX_GUILDALLIANCE * 32 + 4);
+ WFIFOW(fd, 0)=0x14c;
+ for(i=c=0;i<MAX_GUILDALLIANCE;i++){
+ struct guild_alliance *a=&g->alliance[i];
+ if(a->guild_id>0){
+ WFIFOL(fd,c*32+4)=a->opposition;
+ WFIFOL(fd,c*32+8)=a->guild_id;
+ memcpy(WFIFOP(fd,c*32+12),a->name,NAME_LENGTH);
+ c++;
+ }
+ }
+ WFIFOW(fd, 2)=c*32+4;
+ WFIFOSET(fd,WFIFOW(fd,2));
}
@@ -7174,38 +7238,38 @@ void clif_guild_allianceinfo(struct map_session_data *sd)
/// probably member's self-introduction (unused, no client UI/packets for editing it)
void clif_guild_memberlist(struct map_session_data *sd)
{
- int fd;
- int i,c;
- struct guild *g;
- nullpo_retv(sd);
-
- if ((fd = sd->fd) == 0)
- return;
- if ((g = guild_search(sd->status.guild_id)) == NULL)
- return;
-
- WFIFOHEAD(fd, g->max_member * 104 + 4);
- WFIFOW(fd, 0)=0x154;
- for (i=0,c=0; i<g->max_member; i++) {
- struct guild_member *m=&g->member[i];
- if (m->account_id==0)
- continue;
- WFIFOL(fd,c*104+ 4)=m->account_id;
- WFIFOL(fd,c*104+ 8)=m->char_id;
- 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+20)=m->lv;
- WFIFOL(fd,c*104+22)=(int)cap_value(m->exp,0,INT32_MAX);
- WFIFOL(fd,c*104+26)=m->online;
- WFIFOL(fd,c*104+30)=m->position;
- memset(WFIFOP(fd,c*104+34),0,50); //[Ind] - This is displayed in the 'note' column but being you can't edit it it's sent empty.
- memcpy(WFIFOP(fd,c*104+84),m->name,NAME_LENGTH);
- c++;
- }
- WFIFOW(fd, 2)=c*104+4;
- WFIFOSET(fd,WFIFOW(fd,2));
+ int fd;
+ int i,c;
+ struct guild *g;
+ nullpo_retv(sd);
+
+ if( (fd = sd->fd) == 0 )
+ return;
+ if( (g = guild_search(sd->status.guild_id)) == NULL )
+ return;
+
+ WFIFOHEAD(fd, g->max_member * 104 + 4);
+ WFIFOW(fd, 0)=0x154;
+ for(i=0,c=0;i<g->max_member;i++){
+ struct guild_member *m=&g->member[i];
+ if(m->account_id==0)
+ continue;
+ WFIFOL(fd,c*104+ 4)=m->account_id;
+ WFIFOL(fd,c*104+ 8)=m->char_id;
+ 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+20)=m->lv;
+ WFIFOL(fd,c*104+22)=(int)cap_value(m->exp,0,INT32_MAX);
+ WFIFOL(fd,c*104+26)=m->online;
+ WFIFOL(fd,c*104+30)=m->position;
+ memset(WFIFOP(fd,c*104+34),0,50); //[Ind] - This is displayed in the 'note' column but being you can't edit it it's sent empty.
+ memcpy(WFIFOP(fd,c*104+84),m->name,NAME_LENGTH);
+ c++;
+ }
+ WFIFOW(fd, 2)=c*104+4;
+ WFIFOSET(fd,WFIFOW(fd,2));
}
@@ -7213,22 +7277,22 @@ void clif_guild_memberlist(struct map_session_data *sd)
/// 0166 <packet len>.W { <position id>.L <position name>.24B }*
void clif_guild_positionnamelist(struct map_session_data *sd)
{
- int i,fd;
- struct guild *g;
+ int i,fd;
+ struct guild *g;
- nullpo_retv(sd);
- if ((g = guild_search(sd->status.guild_id)) == NULL)
- return;
-
- fd = sd->fd;
- WFIFOHEAD(fd, MAX_GUILDPOSITION * 28 + 4);
- WFIFOW(fd, 0)=0x166;
- for (i=0; i<MAX_GUILDPOSITION; i++) {
- WFIFOL(fd,i*28+4)=i;
- memcpy(WFIFOP(fd,i*28+8),g->position[i].name,NAME_LENGTH);
- }
- WFIFOW(fd,2)=i*28+4;
- WFIFOSET(fd,WFIFOW(fd,2));
+ nullpo_retv(sd);
+ if( (g = guild_search(sd->status.guild_id)) == NULL )
+ return;
+
+ fd = sd->fd;
+ WFIFOHEAD(fd, MAX_GUILDPOSITION * 28 + 4);
+ WFIFOW(fd, 0)=0x166;
+ for(i=0;i<MAX_GUILDPOSITION;i++){
+ WFIFOL(fd,i*28+4)=i;
+ memcpy(WFIFOP(fd,i*28+8),g->position[i].name,NAME_LENGTH);
+ }
+ WFIFOW(fd,2)=i*28+4;
+ WFIFOSET(fd,WFIFOW(fd,2));
}
@@ -7241,25 +7305,25 @@ void clif_guild_positionnamelist(struct map_session_data *sd)
/// TODO
void clif_guild_positioninfolist(struct map_session_data *sd)
{
- int i,fd;
- struct guild *g;
+ int i,fd;
+ struct guild *g;
- nullpo_retv(sd);
- if ((g = guild_search(sd->status.guild_id)) == NULL)
- return;
-
- fd = sd->fd;
- WFIFOHEAD(fd, MAX_GUILDPOSITION * 16 + 4);
- WFIFOW(fd, 0)=0x160;
- for (i=0; i<MAX_GUILDPOSITION; i++) {
- struct guild_position *p=&g->position[i];
- WFIFOL(fd,i*16+ 4)=i;
- WFIFOL(fd,i*16+ 8)=p->mode;
- WFIFOL(fd,i*16+12)=i;
- WFIFOL(fd,i*16+16)=p->exp_mode;
- }
- WFIFOW(fd, 2)=i*16+4;
- WFIFOSET(fd,WFIFOW(fd,2));
+ nullpo_retv(sd);
+ if( (g = guild_search(sd->status.guild_id)) == NULL )
+ return;
+
+ fd = sd->fd;
+ WFIFOHEAD(fd, MAX_GUILDPOSITION * 16 + 4);
+ WFIFOW(fd, 0)=0x160;
+ for(i=0;i<MAX_GUILDPOSITION;i++){
+ struct guild_position *p=&g->position[i];
+ WFIFOL(fd,i*16+ 4)=i;
+ WFIFOL(fd,i*16+ 8)=p->mode;
+ WFIFOL(fd,i*16+12)=i;
+ WFIFOL(fd,i*16+16)=p->exp_mode;
+ }
+ WFIFOW(fd, 2)=i*16+4;
+ WFIFOSET(fd,WFIFOW(fd,2));
}
@@ -7272,25 +7336,25 @@ void clif_guild_positioninfolist(struct map_session_data *sd)
/// TODO
void clif_guild_positionchanged(struct guild *g,int idx)
{
- // FIXME: This packet is intended to update the clients after a
- // commit of position info changes, not sending one packet per
- // position.
- struct map_session_data *sd;
- unsigned char buf[128];
+ // FIXME: This packet is intended to update the clients after a
+ // commit of position info changes, not sending one packet per
+ // position.
+ struct map_session_data *sd;
+ unsigned char buf[128];
- nullpo_retv(g);
+ nullpo_retv(g);
- WBUFW(buf, 0)=0x174;
- WBUFW(buf, 2)=44; // packet len
- // GUILD_REG_POSITION_INFO{
- WBUFL(buf, 4)=idx;
- WBUFL(buf, 8)=g->position[idx].mode;
- WBUFL(buf,12)=idx;
- WBUFL(buf,16)=g->position[idx].exp_mode;
- memcpy(WBUFP(buf,20),g->position[idx].name,NAME_LENGTH);
- // }*
- if ((sd=guild_getavailablesd(g))!=NULL)
- clif_send(buf,WBUFW(buf,2),&sd->bl,GUILD);
+ WBUFW(buf, 0)=0x174;
+ WBUFW(buf, 2)=44; // packet len
+ // GUILD_REG_POSITION_INFO{
+ WBUFL(buf, 4)=idx;
+ WBUFL(buf, 8)=g->position[idx].mode;
+ WBUFL(buf,12)=idx;
+ WBUFL(buf,16)=g->position[idx].exp_mode;
+ memcpy(WBUFP(buf,20),g->position[idx].name,NAME_LENGTH);
+ // }*
+ if( (sd=guild_getavailablesd(g))!=NULL )
+ clif_send(buf,WBUFW(buf,2),&sd->bl,GUILD);
}
@@ -7298,23 +7362,23 @@ void clif_guild_positionchanged(struct guild *g,int idx)
/// 0156 <packet len>.W { <account id>.L <char id>.L <position id>.L }*
void clif_guild_memberpositionchanged(struct guild *g,int idx)
{
- // FIXME: This packet is intended to update the clients after a
- // commit of member position assignment changes, not sending one
- // packet per position.
- struct map_session_data *sd;
- unsigned char buf[64];
+ // FIXME: This packet is intended to update the clients after a
+ // commit of member position assignment changes, not sending one
+ // packet per position.
+ struct map_session_data *sd;
+ unsigned char buf[64];
- nullpo_retv(g);
+ nullpo_retv(g);
- WBUFW(buf, 0)=0x156;
- WBUFW(buf, 2)=16; // packet len
- // MEMBER_POSITION_INFO{
- WBUFL(buf, 4)=g->member[idx].account_id;
- WBUFL(buf, 8)=g->member[idx].char_id;
- WBUFL(buf,12)=g->member[idx].position;
- // }*
- if ((sd=guild_getavailablesd(g))!=NULL)
- clif_send(buf,WBUFW(buf,2),&sd->bl,GUILD);
+ WBUFW(buf, 0)=0x156;
+ WBUFW(buf, 2)=16; // packet len
+ // MEMBER_POSITION_INFO{
+ WBUFL(buf, 4)=g->member[idx].account_id;
+ WBUFL(buf, 8)=g->member[idx].char_id;
+ WBUFL(buf,12)=g->member[idx].position;
+ // }*
+ if( (sd=guild_getavailablesd(g))!=NULL )
+ clif_send(buf,WBUFW(buf,2),&sd->bl,GUILD);
}
@@ -7322,99 +7386,101 @@ void clif_guild_memberpositionchanged(struct guild *g,int idx)
/// 0152 <packet len>.W <guild id>.L <emblem id>.L <emblem data>.?B
void clif_guild_emblem(struct map_session_data *sd,struct guild *g)
{
- int fd;
- nullpo_retv(sd);
- nullpo_retv(g);
+ int fd;
+ nullpo_retv(sd);
+ nullpo_retv(g);
- fd = sd->fd;
- if (g->emblem_len <= 0)
- return;
+ fd = sd->fd;
+ if( g->emblem_len <= 0 )
+ return;
- WFIFOHEAD(fd,g->emblem_len+12);
- WFIFOW(fd,0)=0x152;
- WFIFOW(fd,2)=g->emblem_len+12;
- WFIFOL(fd,4)=g->guild_id;
- WFIFOL(fd,8)=g->emblem_id;
- memcpy(WFIFOP(fd,12),g->emblem_data,g->emblem_len);
- WFIFOSET(fd,WFIFOW(fd,2));
+ WFIFOHEAD(fd,g->emblem_len+12);
+ WFIFOW(fd,0)=0x152;
+ WFIFOW(fd,2)=g->emblem_len+12;
+ WFIFOL(fd,4)=g->guild_id;
+ WFIFOL(fd,8)=g->emblem_id;
+ memcpy(WFIFOP(fd,12),g->emblem_data,g->emblem_len);
+ WFIFOSET(fd,WFIFOW(fd,2));
}
/// Sends update of the guild id/emblem id to everyone in the area (ZC_CHANGE_GUILD).
/// 01b4 <id>.L <guild id>.L <emblem id>.W
-void clif_guild_emblem_area(struct block_list *bl)
+void clif_guild_emblem_area(struct block_list* bl)
{
- uint8 buf[12];
+ uint8 buf[12];
- nullpo_retv(bl);
+ nullpo_retv(bl);
- // TODO this packet doesn't force the update of ui components that have the emblem visible
- // (emblem in the flag npcs and emblem over the head in agit maps) [FlavioJS]
- WBUFW(buf,0) = 0x1b4;
- WBUFL(buf,2) = bl->id;
- WBUFL(buf,6) = status_get_guild_id(bl);
- WBUFW(buf,10) = status_get_emblem_id(bl);
- clif_send(buf, 12, bl, AREA_WOS);
+ // TODO this packet doesn't force the update of ui components that have the emblem visible
+ // (emblem in the flag npcs and emblem over the head in agit maps) [FlavioJS]
+ WBUFW(buf,0) = 0x1b4;
+ WBUFL(buf,2) = bl->id;
+ WBUFL(buf,6) = status_get_guild_id(bl);
+ WBUFW(buf,10) = status_get_emblem_id(bl);
+ clif_send(buf, 12, bl, AREA_WOS);
}
/// Sends guild skills (ZC_GUILD_SKILLINFO).
/// 0162 <packet len>.W <skill points>.W { <skill id>.W <type>.L <level>.W <sp cost>.W <atk range>.W <skill name>.24B <upgradable>.B }*
-void clif_guild_skillinfo(struct map_session_data *sd)
-{
- int fd;
- struct guild *g;
- int i,c;
-
- nullpo_retv(sd);
- if ((g = guild_search(sd->status.guild_id)) == NULL)
- return;
-
- fd = sd->fd;
- WFIFOHEAD(fd, 6 + MAX_GUILDSKILL*37);
- WFIFOW(fd,0) = 0x0162;
- WFIFOW(fd,4) = g->skill_point;
- for (i = 0, c = 0; i < MAX_GUILDSKILL; i++) {
- if (g->skill[i].id > 0 && guild_check_skill_require(g, g->skill[i].id)) {
- int id = g->skill[i].id;
- int p = 6 + c*37;
- WFIFOW(fd,p+0) = id;
- WFIFOL(fd,p+2) = skill_get_inf(id);
- WFIFOW(fd,p+6) = g->skill[i].lv;
- WFIFOW(fd,p+8) = skill_get_sp(id, g->skill[i].lv);
- WFIFOW(fd,p+10) = skill_get_range(id, g->skill[i].lv);
- safestrncpy((char *)WFIFOP(fd,p+12), skill_get_name(id), NAME_LENGTH);
- WFIFOB(fd,p+36)= (g->skill[i].lv < guild_skill_get_max(id) && sd == g->member[0].sd) ? 1 : 0;
- c++;
- }
- }
- WFIFOW(fd,2) = 6 + c*37;
- WFIFOSET(fd,WFIFOW(fd,2));
+void clif_guild_skillinfo(struct map_session_data* sd)
+{
+ int fd;
+ struct guild* g;
+ int i,c;
+
+ nullpo_retv(sd);
+ if( (g = guild_search(sd->status.guild_id)) == NULL )
+ return;
+
+ fd = sd->fd;
+ WFIFOHEAD(fd, 6 + MAX_GUILDSKILL*37);
+ WFIFOW(fd,0) = 0x0162;
+ WFIFOW(fd,4) = g->skill_point;
+ for(i = 0, c = 0; i < MAX_GUILDSKILL; i++)
+ {
+ if(g->skill[i].id > 0 && guild_check_skill_require(g, g->skill[i].id))
+ {
+ int id = g->skill[i].id;
+ int p = 6 + c*37;
+ WFIFOW(fd,p+0) = id;
+ WFIFOL(fd,p+2) = skill_get_inf(id);
+ WFIFOW(fd,p+6) = g->skill[i].lv;
+ WFIFOW(fd,p+8) = skill_get_sp(id, g->skill[i].lv);
+ WFIFOW(fd,p+10) = skill_get_range(id, g->skill[i].lv);
+ safestrncpy((char*)WFIFOP(fd,p+12), skill_get_name(id), NAME_LENGTH);
+ WFIFOB(fd,p+36)= (g->skill[i].lv < guild_skill_get_max(id) && sd == g->member[0].sd) ? 1 : 0;
+ c++;
+ }
+ }
+ WFIFOW(fd,2) = 6 + c*37;
+ WFIFOSET(fd,WFIFOW(fd,2));
}
/// Sends guild notice to client (ZC_GUILD_NOTICE).
/// 016f <subject>.60B <notice>.120B
-void clif_guild_notice(struct map_session_data *sd, struct guild *g)
+void clif_guild_notice(struct map_session_data* sd, struct guild* g)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
- nullpo_retv(g);
+ nullpo_retv(sd);
+ nullpo_retv(g);
- fd = sd->fd;
+ fd = sd->fd;
- if (!session_isActive(fd))
- return;
+ if ( !session_isActive(fd) )
+ return;
- if (g->mes1[0] == '\0' && g->mes2[0] == '\0')
- return;
+ if(g->mes1[0] == '\0' && g->mes2[0] == '\0')
+ return;
- WFIFOHEAD(fd,packet_len(0x16f));
- WFIFOW(fd,0) = 0x16f;
- memcpy(WFIFOP(fd,2), g->mes1, MAX_GUILDMES1);
- memcpy(WFIFOP(fd,62), g->mes2, MAX_GUILDMES2);
- WFIFOSET(fd,packet_len(0x16f));
+ WFIFOHEAD(fd,packet_len(0x16f));
+ WFIFOW(fd,0) = 0x16f;
+ memcpy(WFIFOP(fd,2), g->mes1, MAX_GUILDMES1);
+ memcpy(WFIFOP(fd,62), g->mes2, MAX_GUILDMES2);
+ WFIFOSET(fd,packet_len(0x16f));
}
@@ -7422,17 +7488,17 @@ void clif_guild_notice(struct map_session_data *sd, struct guild *g)
/// 016a <guild id>.L <guild name>.24B
void clif_guild_invite(struct map_session_data *sd,struct guild *g)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
- nullpo_retv(g);
+ nullpo_retv(sd);
+ nullpo_retv(g);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x16a));
- WFIFOW(fd,0)=0x16a;
- WFIFOL(fd,2)=g->guild_id;
- memcpy(WFIFOP(fd,6),g->name,NAME_LENGTH);
- WFIFOSET(fd,packet_len(0x16a));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0x16a));
+ WFIFOW(fd,0)=0x16a;
+ WFIFOL(fd,2)=g->guild_id;
+ memcpy(WFIFOP(fd,6),g->name,NAME_LENGTH);
+ WFIFOSET(fd,packet_len(0x16a));
}
@@ -7445,15 +7511,15 @@ void clif_guild_invite(struct map_session_data *sd,struct guild *g)
/// 3 = Guild full.
void clif_guild_inviteack(struct map_session_data *sd,int flag)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x169));
- WFIFOW(fd,0)=0x169;
- WFIFOB(fd,2)=flag;
- WFIFOSET(fd,packet_len(0x169));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0x169));
+ WFIFOW(fd,0)=0x169;
+ WFIFOB(fd,2)=flag;
+ WFIFOSET(fd,packet_len(0x169));
}
@@ -7461,104 +7527,108 @@ void clif_guild_inviteack(struct map_session_data *sd,int flag)
/// 015a <char name>.24B <reason>.40B
void clif_guild_leave(struct map_session_data *sd,const char *name,const char *mes)
{
- unsigned char buf[128];
+ unsigned char buf[128];
- nullpo_retv(sd);
+ nullpo_retv(sd);
- WBUFW(buf, 0)=0x15a;
- memcpy(WBUFP(buf, 2),name,NAME_LENGTH);
- memcpy(WBUFP(buf,26),mes,40);
- clif_send(buf,packet_len(0x15a),&sd->bl,GUILD_NOBG);
+ WBUFW(buf, 0)=0x15a;
+ memcpy(WBUFP(buf, 2),name,NAME_LENGTH);
+ memcpy(WBUFP(buf,26),mes,40);
+ clif_send(buf,packet_len(0x15a),&sd->bl,GUILD_NOBG);
}
/// Notifies clients of a guild of an expelled member.
/// 015c <char name>.24B <reason>.40B <account name>.24B (ZC_ACK_BAN_GUILD)
/// 0839 <char name>.24B <reason>.40B (ZC_ACK_BAN_GUILD_SSO)
-void clif_guild_expulsion(struct map_session_data *sd, const char *name, const char *mes, int account_id)
+void clif_guild_expulsion(struct map_session_data* sd, const char* name, const char* mes, int account_id)
{
- unsigned char buf[128];
+ unsigned char buf[128];
#if PACKETVER < 20100803
- const unsigned short cmd = 0x15c;
+ const unsigned short cmd = 0x15c;
#else
- const unsigned short cmd = 0x839;
+ const unsigned short cmd = 0x839;
#endif
- nullpo_retv(sd);
+ nullpo_retv(sd);
- WBUFW(buf,0) = cmd;
- safestrncpy((char *)WBUFP(buf,2), name, NAME_LENGTH);
- safestrncpy((char *)WBUFP(buf,26), mes, 40);
+ WBUFW(buf,0) = cmd;
+ safestrncpy((char*)WBUFP(buf,2), name, NAME_LENGTH);
+ safestrncpy((char*)WBUFP(buf,26), mes, 40);
#if PACKETVER < 20100803
- memset(WBUFP(buf,66), 0, NAME_LENGTH); // account name (not used for security reasons)
+ memset(WBUFP(buf,66), 0, NAME_LENGTH); // account name (not used for security reasons)
#endif
- clif_send(buf, packet_len(cmd), &sd->bl, GUILD_NOBG);
+ clif_send(buf, packet_len(cmd), &sd->bl, GUILD_NOBG);
}
/// Guild expulsion list (ZC_BAN_LIST).
/// 0163 <packet len>.W { <char name>.24B <account name>.24B <reason>.40B }*
/// 0163 <packet len>.W { <char name>.24B <reason>.40B }* (PACKETVER >= 20100803)
-void clif_guild_expulsionlist(struct map_session_data *sd)
+void clif_guild_expulsionlist(struct map_session_data* sd)
{
#if PACKETVER < 20100803
- const int offset = NAME_LENGTH*2+40;
+ const int offset = NAME_LENGTH*2+40;
#else
- const int offset = NAME_LENGTH+40;
+ const int offset = NAME_LENGTH+40;
#endif
- int fd, i, c = 0;
- struct guild *g;
+ int fd, i, c = 0;
+ struct guild* g;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- if ((g = guild_search(sd->status.guild_id)) == NULL)
- return;
+ if( (g = guild_search(sd->status.guild_id)) == NULL )
+ return;
- fd = sd->fd;
+ fd = sd->fd;
- WFIFOHEAD(fd,4 + MAX_GUILDEXPULSION * offset);
- WFIFOW(fd,0) = 0x163;
+ WFIFOHEAD(fd,4 + MAX_GUILDEXPULSION * offset);
+ WFIFOW(fd,0) = 0x163;
- for (i = 0; i < MAX_GUILDEXPULSION; i++) {
- struct guild_expulsion *e = &g->expulsion[i];
+ for( i = 0; i < MAX_GUILDEXPULSION; i++ )
+ {
+ struct guild_expulsion* e = &g->expulsion[i];
- if (e->account_id > 0) {
- memcpy(WFIFOP(fd,4 + c*offset), e->name, NAME_LENGTH);
+ if( e->account_id > 0 )
+ {
+ memcpy(WFIFOP(fd,4 + c*offset), e->name, NAME_LENGTH);
#if PACKETVER < 20100803
- memset(WFIFOP(fd,4 + c*offset+24), 0, NAME_LENGTH); // account name (not used for security reasons)
- memcpy(WFIFOP(fd,4 + c*offset+48), e->mes, 40);
+ memset(WFIFOP(fd,4 + c*offset+24), 0, NAME_LENGTH); // account name (not used for security reasons)
+ memcpy(WFIFOP(fd,4 + c*offset+48), e->mes, 40);
#else
- memcpy(WFIFOP(fd,4 + c*offset+24), e->mes, 40);
+ memcpy(WFIFOP(fd,4 + c*offset+24), e->mes, 40);
#endif
- c++;
- }
- }
- WFIFOW(fd,2) = 4 + c*offset;
- WFIFOSET(fd,WFIFOW(fd,2));
+ c++;
+ }
+ }
+ WFIFOW(fd,2) = 4 + c*offset;
+ WFIFOSET(fd,WFIFOW(fd,2));
}
/// Guild chat message (ZC_GUILD_CHAT).
/// 017f <packet len>.W <message>.?B
void clif_guild_message(struct guild *g,int account_id,const char *mes,int len)
-{
- // TODO: account_id is not used, candidate for deletion? [Ai4rei]
- struct map_session_data *sd;
- uint8 buf[256];
+{// TODO: account_id is not used, candidate for deletion? [Ai4rei]
+ struct map_session_data *sd;
+ uint8 buf[256];
- if (len == 0) {
- return;
- } else if (len > sizeof(buf)-5) {
- ShowWarning("clif_guild_message: Truncated message '%s' (len=%d, max=%d, guild_id=%d).\n", mes, len, sizeof(buf)-5, g->guild_id);
- len = sizeof(buf)-5;
- }
+ if( len == 0 )
+ {
+ return;
+ }
+ else if( len > sizeof(buf)-5 )
+ {
+ ShowWarning("clif_guild_message: Truncated message '%s' (len=%d, max=%d, guild_id=%d).\n", mes, len, sizeof(buf)-5, g->guild_id);
+ len = sizeof(buf)-5;
+ }
- WBUFW(buf, 0) = 0x17f;
- WBUFW(buf, 2) = len + 5;
- safestrncpy((char *)WBUFP(buf,4), mes, len+1);
+ WBUFW(buf, 0) = 0x17f;
+ WBUFW(buf, 2) = len + 5;
+ safestrncpy((char*)WBUFP(buf,4), mes, len+1);
- if ((sd = guild_getavailablesd(g)) != NULL)
- clif_send(buf, WBUFW(buf,2), &sd->bl, GUILD_NOBG);
+ if ((sd = guild_getavailablesd(g)) != NULL)
+ clif_send(buf, WBUFW(buf,2), &sd->bl, GUILD_NOBG);
}
@@ -7566,22 +7636,21 @@ void clif_guild_message(struct guild *g,int account_id,const char *mes,int len)
* Server tells client 'sd' that his guild skill 'skill_num' gone to level 'lv'
*------------------------------------------*/
int clif_guild_skillup(struct map_session_data *sd,int skill_num,int lv)
-{
- // TODO: Merge with clif_skillup (same packet).
- int fd;
+{// TODO: Merge with clif_skillup (same packet).
+ int fd;
- nullpo_ret(sd);
+ nullpo_ret(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,11);
- WFIFOW(fd,0) = 0x10e;
- WFIFOW(fd,2) = skill_num;
- WFIFOW(fd,4) = lv;
- WFIFOW(fd,6) = skill_get_sp(skill_num,lv);
- WFIFOW(fd,8) = skill_get_range(skill_num,lv);
- WFIFOB(fd,10) = 1;
- WFIFOSET(fd,11);
- return 0;
+ fd=sd->fd;
+ WFIFOHEAD(fd,11);
+ WFIFOW(fd,0) = 0x10e;
+ WFIFOW(fd,2) = skill_num;
+ WFIFOW(fd,4) = lv;
+ WFIFOW(fd,6) = skill_get_sp(skill_num,lv);
+ WFIFOW(fd,8) = skill_get_range(skill_num,lv);
+ WFIFOB(fd,10) = 1;
+ WFIFOSET(fd,11);
+ return 0;
}
@@ -7589,16 +7658,16 @@ int clif_guild_skillup(struct map_session_data *sd,int skill_num,int lv)
/// 0171 <inviter account id>.L <guild name>.24B
void clif_guild_reqalliance(struct map_session_data *sd,int account_id,const char *name)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x171));
- WFIFOW(fd,0)=0x171;
- WFIFOL(fd,2)=account_id;
- memcpy(WFIFOP(fd,6),name,NAME_LENGTH);
- WFIFOSET(fd,packet_len(0x171));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0x171));
+ WFIFOW(fd,0)=0x171;
+ WFIFOL(fd,2)=account_id;
+ memcpy(WFIFOP(fd,6),name,NAME_LENGTH);
+ WFIFOSET(fd,packet_len(0x171));
}
@@ -7613,15 +7682,15 @@ void clif_guild_reqalliance(struct map_session_data *sd,int account_id,const cha
/// 5 = Alliances are disabled.
void clif_guild_allianceack(struct map_session_data *sd,int flag)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x173));
- WFIFOW(fd,0)=0x173;
- WFIFOL(fd,2)=flag;
- WFIFOSET(fd,packet_len(0x173));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0x173));
+ WFIFOW(fd,0)=0x173;
+ WFIFOL(fd,2)=flag;
+ WFIFOSET(fd,packet_len(0x173));
}
@@ -7632,18 +7701,18 @@ void clif_guild_allianceack(struct map_session_data *sd,int flag)
/// 1 = Enemy
void clif_guild_delalliance(struct map_session_data *sd,int guild_id,int flag)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd = sd->fd;
- if (fd <= 0)
- return;
- WFIFOHEAD(fd,packet_len(0x184));
- WFIFOW(fd,0)=0x184;
- WFIFOL(fd,2)=guild_id;
- WFIFOL(fd,6)=flag;
- WFIFOSET(fd,packet_len(0x184));
+ fd = sd->fd;
+ if (fd <= 0)
+ return;
+ WFIFOHEAD(fd,packet_len(0x184));
+ WFIFOW(fd,0)=0x184;
+ WFIFOL(fd,2)=guild_id;
+ WFIFOL(fd,6)=flag;
+ WFIFOSET(fd,packet_len(0x184));
}
@@ -7656,15 +7725,15 @@ void clif_guild_delalliance(struct map_session_data *sd,int guild_id,int flag)
/// 3 = Antagonists are disabled.
void clif_guild_oppositionack(struct map_session_data *sd,int flag)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x181));
- WFIFOW(fd,0)=0x181;
- WFIFOB(fd,2)=flag;
- WFIFOSET(fd,packet_len(0x181));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0x181));
+ WFIFOW(fd,0)=0x181;
+ WFIFOB(fd,2)=flag;
+ WFIFOSET(fd,packet_len(0x181));
}
@@ -7673,12 +7742,12 @@ void clif_guild_oppositionack(struct map_session_data *sd,int flag)
/*
void clif_guild_allianceadded(struct guild *g,int idx)
{
- unsigned char buf[64];
- WBUFW(buf,0)=0x185;
- WBUFL(buf,2)=g->alliance[idx].opposition;
- WBUFL(buf,6)=g->alliance[idx].guild_id;
- memcpy(WBUFP(buf,10),g->alliance[idx].name,NAME_LENGTH);
- clif_send(buf,packet_len(0x185),guild_getavailablesd(g),GUILD);
+ unsigned char buf[64];
+ WBUFW(buf,0)=0x185;
+ WBUFL(buf,2)=g->alliance[idx].opposition;
+ WBUFL(buf,6)=g->alliance[idx].guild_id;
+ memcpy(WBUFP(buf,10),g->alliance[idx].name,NAME_LENGTH);
+ clif_send(buf,packet_len(0x185),guild_getavailablesd(g),GUILD);
}
*/
@@ -7690,15 +7759,15 @@ void clif_guild_allianceadded(struct guild *g,int idx)
/// 2 = there are still members in the guild
void clif_guild_broken(struct map_session_data *sd,int flag)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x15e));
- WFIFOW(fd,0)=0x15e;
- WFIFOL(fd,2)=flag;
- WFIFOSET(fd,packet_len(0x15e));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0x15e));
+ WFIFOW(fd,0)=0x15e;
+ WFIFOL(fd,2)=flag;
+ WFIFOSET(fd,packet_len(0x15e));
}
@@ -7708,28 +7777,28 @@ void clif_guild_broken(struct map_session_data *sd,int flag)
/// enum emotion_type
void clif_emotion(struct block_list *bl,int type)
{
- unsigned char buf[8];
+ unsigned char buf[8];
- nullpo_retv(bl);
+ nullpo_retv(bl);
- WBUFW(buf,0)=0xc0;
- WBUFL(buf,2)=bl->id;
- WBUFB(buf,6)=type;
- clif_send(buf,packet_len(0xc0),bl,AREA);
+ WBUFW(buf,0)=0xc0;
+ WBUFL(buf,2)=bl->id;
+ WBUFB(buf,6)=type;
+ clif_send(buf,packet_len(0xc0),bl,AREA);
}
/// Displays the contents of a talkiebox trap (ZC_TALKBOX_CHATCONTENTS).
/// 0191 <id>.L <contents>.80B
-void clif_talkiebox(struct block_list *bl, const char *talkie)
+void clif_talkiebox(struct block_list* bl, const char* talkie)
{
- unsigned char buf[MESSAGE_SIZE+6];
- nullpo_retv(bl);
+ unsigned char buf[MESSAGE_SIZE+6];
+ nullpo_retv(bl);
- WBUFW(buf,0) = 0x191;
- WBUFL(buf,2) = bl->id;
- safestrncpy((char *)WBUFP(buf,6),talkie,MESSAGE_SIZE);
- clif_send(buf,packet_len(0x191),bl,AREA);
+ WBUFW(buf,0) = 0x191;
+ WBUFL(buf,2) = bl->id;
+ safestrncpy((char*)WBUFP(buf,6),talkie,MESSAGE_SIZE);
+ clif_send(buf,packet_len(0x191),bl,AREA);
}
@@ -7737,13 +7806,13 @@ void clif_talkiebox(struct block_list *bl, const char *talkie)
/// 01ea <id>.L
void clif_wedding_effect(struct block_list *bl)
{
- unsigned char buf[6];
+ unsigned char buf[6];
- nullpo_retv(bl);
+ nullpo_retv(bl);
- WBUFW(buf,0) = 0x1ea;
- WBUFL(buf,2) = bl->id;
- clif_send(buf, packet_len(0x1ea), bl, AREA);
+ WBUFW(buf,0) = 0x1ea;
+ WBUFL(buf,2) = bl->id;
+ clif_send(buf, packet_len(0x1ea), bl, AREA);
}
@@ -7751,25 +7820,30 @@ void clif_wedding_effect(struct block_list *bl)
/// 01e6 <partner name>.24B
void clif_callpartner(struct map_session_data *sd)
{
- unsigned char buf[26];
- const char *p;
+ unsigned char buf[26];
+ const char *p;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- WBUFW(buf,0) = 0x1e6;
+ WBUFW(buf,0) = 0x1e6;
- if (sd->status.partner_id) {
- if ((p = map_charid2nick(sd->status.partner_id)) != NULL) {
- memcpy(WBUFP(buf,2), p, NAME_LENGTH);
- } else {
- WBUFB(buf,2) = 0;
- }
- } else {
- // Send zero-length name if no partner, to initialize the client buffer.
- WBUFB(buf,2) = 0;
- }
+ if( sd->status.partner_id )
+ {
+ if( ( p = map_charid2nick(sd->status.partner_id) ) != NULL )
+ {
+ memcpy(WBUFP(buf,2), p, NAME_LENGTH);
+ }
+ else
+ {
+ WBUFB(buf,2) = 0;
+ }
+ }
+ else
+ {// Send zero-length name if no partner, to initialize the client buffer.
+ WBUFB(buf,2) = 0;
+ }
- clif_send(buf, packet_len(0x1e6), &sd->bl, AREA);
+ clif_send(buf, packet_len(0x1e6), &sd->bl, AREA);
}
@@ -7779,29 +7853,29 @@ void clif_callpartner(struct map_session_data *sd)
/*
void clif_marriage_process(struct map_session_data *sd)
{
- int fd;
- nullpo_retv(sd);
+ int fd;
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x1e4));
- WFIFOW(fd,0)=0x1e4;
- WFIFOSET(fd,packet_len(0x1e4));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0x1e4));
+ WFIFOW(fd,0)=0x1e4;
+ WFIFOSET(fd,packet_len(0x1e4));
}
*/
/// Notice of divorce (ZC_DIVORCE).
/// 0205 <partner name>.24B
-void clif_divorced(struct map_session_data *sd, const char *name)
+void clif_divorced(struct map_session_data* sd, const char* name)
{
- int fd;
- nullpo_retv(sd);
+ int fd;
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x205));
- WFIFOW(fd,0)=0x205;
- memcpy(WFIFOP(fd,2), name, NAME_LENGTH);
- WFIFOSET(fd, packet_len(0x205));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0x205));
+ WFIFOW(fd,0)=0x205;
+ memcpy(WFIFOP(fd,2), name, NAME_LENGTH);
+ WFIFOSET(fd, packet_len(0x205));
}
@@ -7811,14 +7885,14 @@ void clif_divorced(struct map_session_data *sd, const char *name)
/*
void clif_marriage_proposal(int fd, struct map_session_data *sd, struct map_session_data* ssd)
{
- nullpo_retv(sd);
+ nullpo_retv(sd);
- WFIFOHEAD(fd,packet_len(0x1e2));
- WFIFOW(fd,0) = 0x1e2;
- WFIFOL(fd,2) = ssd->status.account_id;
- WFIFOL(fd,6) = ssd->status.char_id;
- safestrncpy((char*)WFIFOP(fd,10), ssd->status.name, NAME_LENGTH);
- WFIFOSET(fd, packet_len(0x1e2));
+ WFIFOHEAD(fd,packet_len(0x1e2));
+ WFIFOW(fd,0) = 0x1e2;
+ WFIFOL(fd,2) = ssd->status.account_id;
+ WFIFOL(fd,6) = ssd->status.char_id;
+ safestrncpy((char*)WFIFOP(fd,10), ssd->status.name, NAME_LENGTH);
+ WFIFOSET(fd, packet_len(0x1e2));
}
*/
@@ -7828,27 +7902,30 @@ void clif_marriage_proposal(int fd, struct map_session_data *sd, struct map_sess
*------------------------------------------*/
void clif_disp_onlyself(struct map_session_data *sd, const char *mes, int len)
{
- clif_disp_message(&sd->bl, mes, len, SELF);
+ clif_disp_message(&sd->bl, mes, len, SELF);
}
/*==========================================
* Displays a message using the guild-chat colors to the specified targets. [Skotlex]
*------------------------------------------*/
-void clif_disp_message(struct block_list *src, const char *mes, int len, enum send_target target)
+void clif_disp_message(struct block_list* src, const char* mes, int len, enum send_target target)
{
- unsigned char buf[256];
+ unsigned char buf[256];
- if (len == 0) {
- return;
- } else if (len > sizeof(buf)-5) {
- ShowWarning("clif_disp_message: Truncated message '%s' (len=%d, max=%d, aid=%d).\n", mes, len, sizeof(buf)-5, src->id);
- len = sizeof(buf)-5;
- }
+ if( len == 0 )
+ {
+ return;
+ }
+ else if( len > sizeof(buf)-5 )
+ {
+ ShowWarning("clif_disp_message: Truncated message '%s' (len=%d, max=%d, aid=%d).\n", mes, len, sizeof(buf)-5, src->id);
+ len = sizeof(buf)-5;
+ }
- WBUFW(buf, 0) = 0x17f;
- WBUFW(buf, 2) = len + 5;
- safestrncpy((char *)WBUFP(buf,4), mes, len+1);
- clif_send(buf, WBUFW(buf,2), src, target);
+ WBUFW(buf, 0) = 0x17f;
+ WBUFW(buf, 2) = len + 5;
+ safestrncpy((char*)WBUFP(buf,4), mes, len+1);
+ clif_send(buf, WBUFW(buf,2), src, target);
}
@@ -7860,29 +7937,29 @@ void clif_disp_message(struct block_list *src, const char *mes, int len, enum se
/// 1 = success
void clif_GM_kickack(struct map_session_data *sd, int id)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0xcd));
- WFIFOW(fd,0) = 0xcd;
- WFIFOB(fd,2) = id; // FIXME: this is not account id
- WFIFOSET(fd, packet_len(0xcd));
+ fd = sd->fd;
+ WFIFOHEAD(fd,packet_len(0xcd));
+ WFIFOW(fd,0) = 0xcd;
+ WFIFOB(fd,2) = id; // FIXME: this is not account id
+ WFIFOSET(fd, packet_len(0xcd));
}
void clif_GM_kick(struct map_session_data *sd,struct map_session_data *tsd)
{
- int fd = tsd->fd;
+ int fd = tsd->fd;
- if (fd > 0)
- clif_authfail_fd(fd, 15);
- else
- map_quit(tsd);
+ if( fd > 0 )
+ clif_authfail_fd(fd, 15);
+ else
+ map_quit(tsd);
- if (sd)
- clif_GM_kickack(sd,tsd->status.account_id);
+ if( sd )
+ clif_GM_kickack(sd,tsd->status.account_id);
}
@@ -7895,16 +7972,16 @@ void clif_GM_kick(struct map_session_data *sd,struct map_session_data *tsd)
/// 3 = "Chat Block has been applied by GM due to your ill-mannerous action."
/// 4 = "Automated Chat Block has been applied due to Anti-Spam System."
/// 5 = "You got a good point from %s."
-void clif_manner_message(struct map_session_data *sd, uint32 type)
+void clif_manner_message(struct map_session_data* sd, uint32 type)
{
- int fd;
- nullpo_retv(sd);
+ int fd;
+ nullpo_retv(sd);
- fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x14a));
- WFIFOW(fd,0) = 0x14a;
- WFIFOL(fd,2) = type;
- WFIFOSET(fd, packet_len(0x14a));
+ fd = sd->fd;
+ WFIFOHEAD(fd,packet_len(0x14a));
+ WFIFOW(fd,0) = 0x14a;
+ WFIFOL(fd,2) = type;
+ WFIFOSET(fd, packet_len(0x14a));
}
@@ -7913,18 +7990,18 @@ void clif_manner_message(struct map_session_data *sd, uint32 type)
/// type:
/// 0 = positive (unmute)
/// 1 = negative (mute)
-void clif_GM_silence(struct map_session_data *sd, struct map_session_data *tsd, uint8 type)
+void clif_GM_silence(struct map_session_data* sd, struct map_session_data* tsd, uint8 type)
{
- int fd;
- nullpo_retv(sd);
- nullpo_retv(tsd);
+ int fd;
+ nullpo_retv(sd);
+ nullpo_retv(tsd);
- fd = tsd->fd;
- WFIFOHEAD(fd,packet_len(0x14b));
- WFIFOW(fd,0) = 0x14b;
- WFIFOB(fd,2) = type;
- safestrncpy((char *)WFIFOP(fd,3), sd->status.name, NAME_LENGTH);
- WFIFOSET(fd, packet_len(0x14b));
+ fd = tsd->fd;
+ WFIFOHEAD(fd,packet_len(0x14b));
+ WFIFOW(fd,0) = 0x14b;
+ WFIFOB(fd,2) = type;
+ safestrncpy((char*)WFIFOP(fd,3), sd->status.name, NAME_LENGTH);
+ WFIFOSET(fd, packet_len(0x14b));
}
@@ -7939,16 +8016,16 @@ void clif_GM_silence(struct map_session_data *sd, struct map_session_data *tsd,
/// 2 = too many blocks
void clif_wisexin(struct map_session_data *sd,int type,int flag)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0xd1));
- WFIFOW(fd,0)=0xd1;
- WFIFOB(fd,2)=type;
- WFIFOB(fd,3)=flag;
- WFIFOSET(fd,packet_len(0xd1));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0xd1));
+ WFIFOW(fd,0)=0xd1;
+ WFIFOB(fd,2)=type;
+ WFIFOB(fd,3)=flag;
+ WFIFOSET(fd,packet_len(0xd1));
}
/// Notifies the client about the result of a request to allow/deny whispers from anyone (ZC_SETTING_WHISPER_STATE).
@@ -7961,32 +8038,32 @@ void clif_wisexin(struct map_session_data *sd,int type,int flag)
/// 1 = failure
void clif_wisall(struct map_session_data *sd,int type,int flag)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0xd2));
- WFIFOW(fd,0)=0xd2;
- WFIFOB(fd,2)=type;
- WFIFOB(fd,3)=flag;
- WFIFOSET(fd,packet_len(0xd2));
+ fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0xd2));
+ WFIFOW(fd,0)=0xd2;
+ WFIFOB(fd,2)=type;
+ WFIFOB(fd,3)=flag;
+ WFIFOSET(fd,packet_len(0xd2));
}
/// Play a BGM! [Rikter/Yommy] (ZC_PLAY_NPC_BGM).
/// 07fe <bgm>.24B
-void clif_playBGM(struct map_session_data *sd, const char *name)
+void clif_playBGM(struct map_session_data* sd, const char* name)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x7fe));
- WFIFOW(fd,0) = 0x7fe;
- safestrncpy((char *)WFIFOP(fd,2), name, NAME_LENGTH);
- WFIFOSET(fd,packet_len(0x7fe));
+ fd = sd->fd;
+ WFIFOHEAD(fd,packet_len(0x7fe));
+ WFIFOW(fd,0) = 0x7fe;
+ safestrncpy((char*)WFIFOP(fd,2), name, NAME_LENGTH);
+ WFIFOSET(fd,packet_len(0x7fe));
}
@@ -8003,35 +8080,35 @@ void clif_playBGM(struct map_session_data *sd, const char *name)
/// npc id:
/// The accustic direction of the sound is determined by the
/// relative position of the NPC to the player (3D sound).
-void clif_soundeffect(struct map_session_data *sd, struct block_list *bl, const char *name, int type)
+void clif_soundeffect(struct map_session_data* sd, struct block_list* bl, const char* name, int type)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
- nullpo_retv(bl);
+ nullpo_retv(sd);
+ nullpo_retv(bl);
- fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x1d3));
- WFIFOW(fd,0) = 0x1d3;
- safestrncpy((char *)WFIFOP(fd,2), name, NAME_LENGTH);
- WFIFOB(fd,26) = type;
- WFIFOL(fd,27) = 0;
- WFIFOL(fd,31) = bl->id;
- WFIFOSET(fd,packet_len(0x1d3));
+ fd = sd->fd;
+ WFIFOHEAD(fd,packet_len(0x1d3));
+ WFIFOW(fd,0) = 0x1d3;
+ safestrncpy((char*)WFIFOP(fd,2), name, NAME_LENGTH);
+ WFIFOB(fd,26) = type;
+ WFIFOL(fd,27) = 0;
+ WFIFOL(fd,31) = bl->id;
+ WFIFOSET(fd,packet_len(0x1d3));
}
-void clif_soundeffectall(struct block_list *bl, const char *name, int type, enum send_target coverage)
+void clif_soundeffectall(struct block_list* bl, const char* name, int type, enum send_target coverage)
{
- unsigned char buf[40];
+ unsigned char buf[40];
- nullpo_retv(bl);
+ nullpo_retv(bl);
- WBUFW(buf,0) = 0x1d3;
- safestrncpy((char *)WBUFP(buf,2), name, NAME_LENGTH);
- WBUFB(buf,26) = type;
- WBUFL(buf,27) = 0;
- WBUFL(buf,31) = bl->id;
- clif_send(buf, packet_len(0x1d3), bl, coverage);
+ WBUFW(buf,0) = 0x1d3;
+ safestrncpy((char*)WBUFP(buf,2), name, NAME_LENGTH);
+ WBUFB(buf,26) = type;
+ WBUFL(buf,27) = 0;
+ WBUFL(buf,31) = bl->id;
+ clif_send(buf, packet_len(0x1d3), bl, coverage);
}
@@ -8039,33 +8116,33 @@ void clif_soundeffectall(struct block_list *bl, const char *name, int type, enum
/// 01f3 <id>.L <effect id>.L
/// effect id:
/// @see doc/effect_list.txt
-void clif_specialeffect(struct block_list *bl, int type, enum send_target target)
+void clif_specialeffect(struct block_list* bl, int type, enum send_target target)
{
- unsigned char buf[24];
+ unsigned char buf[24];
- nullpo_retv(bl);
+ nullpo_retv(bl);
- memset(buf, 0, packet_len(0x1f3));
+ memset(buf, 0, packet_len(0x1f3));
- WBUFW(buf,0) = 0x1f3;
- WBUFL(buf,2) = bl->id;
- WBUFL(buf,6) = type;
+ WBUFW(buf,0) = 0x1f3;
+ WBUFL(buf,2) = bl->id;
+ WBUFL(buf,6) = type;
- clif_send(buf, packet_len(0x1f3), bl, target);
+ clif_send(buf, packet_len(0x1f3), bl, target);
- if (disguised(bl)) {
- WBUFL(buf,2) = -bl->id;
- clif_send(buf, packet_len(0x1f3), bl, SELF);
- }
+ if (disguised(bl)) {
+ WBUFL(buf,2) = -bl->id;
+ clif_send(buf, packet_len(0x1f3), bl, SELF);
+ }
}
-void clif_specialeffect_single(struct block_list *bl, int type, int fd)
+void clif_specialeffect_single(struct block_list* bl, int type, int fd)
{
- WFIFOHEAD(fd,10);
- WFIFOW(fd,0) = 0x1f3;
- WFIFOL(fd,2) = bl->id;
- WFIFOL(fd,6) = type;
- WFIFOSET(fd,10);
+ WFIFOHEAD(fd,10);
+ WFIFOW(fd,0) = 0x1f3;
+ WFIFOL(fd,2) = bl->id;
+ WFIFOL(fd,6) = type;
+ WFIFOSET(fd,10);
}
@@ -8075,317 +8152,332 @@ void clif_specialeffect_single(struct block_list *bl, int type, int fd)
/// @see doc/effect_list.txt
/// num data:
/// effect-dependent value
-void clif_specialeffect_value(struct block_list *bl, int effect_id, int num, send_target target)
+void clif_specialeffect_value(struct block_list* bl, int effect_id, int num, send_target target)
{
- uint8 buf[14];
+ uint8 buf[14];
- WBUFW(buf,0) = 0x284;
- WBUFL(buf,2) = bl->id;
- WBUFL(buf,6) = effect_id;
- WBUFL(buf,10) = num;
+ WBUFW(buf,0) = 0x284;
+ WBUFL(buf,2) = bl->id;
+ WBUFL(buf,6) = effect_id;
+ WBUFL(buf,10) = num;
- clif_send(buf, packet_len(0x284), bl, target);
+ clif_send(buf, packet_len(0x284), bl, target);
- if (disguised(bl)) {
- WBUFL(buf,2) = -bl->id;
- clif_send(buf, packet_len(0x284), bl, SELF);
- }
+ if( disguised(bl) )
+ {
+ WBUFL(buf,2) = -bl->id;
+ clif_send(buf, packet_len(0x284), bl, SELF);
+ }
}
// Modification of clif_messagecolor to send colored messages to players to chat log only (doesn't display overhead)
/// 02c1 <packet len>.W <id>.L <color>.L <message>.?B
-int clif_colormes(struct map_session_data *sd, enum clif_colors color, const char *msg)
-{
- unsigned short msg_len = strlen(msg) + 1;
+int clif_colormes(struct map_session_data * sd, enum clif_colors color, const char* msg) {
+ unsigned short msg_len = strlen(msg) + 1;
- WFIFOHEAD(sd->fd,msg_len + 12);
- WFIFOW(sd->fd,0) = 0x2C1;
- WFIFOW(sd->fd,2) = msg_len + 12;
- WFIFOL(sd->fd,4) = 0;
- WFIFOL(sd->fd,8) = color_table[color];
- safestrncpy((char *)WFIFOP(sd->fd,12), msg, msg_len);
- clif_send(WFIFOP(sd->fd,0), WFIFOW(sd->fd,2), &sd->bl, SELF);
+ WFIFOHEAD(sd->fd,msg_len + 12);
+ WFIFOW(sd->fd,0) = 0x2C1;
+ WFIFOW(sd->fd,2) = msg_len + 12;
+ WFIFOL(sd->fd,4) = 0;
+ WFIFOL(sd->fd,8) = color_table[color];
+ safestrncpy((char*)WFIFOP(sd->fd,12), msg, msg_len);
+ clif_send(WFIFOP(sd->fd,0), WFIFOW(sd->fd,2), &sd->bl, SELF);
- return 0;
+ return 0;
}
/// Monster/NPC color chat [SnakeDrak] (ZC_NPC_CHAT).
/// 02c1 <packet len>.W <id>.L <color>.L <message>.?B
-void clif_messagecolor(struct block_list *bl, unsigned long color, const char *msg)
-{
- unsigned short msg_len = strlen(msg) + 1;
- uint8 buf[256];
- color = (color & 0x0000FF) << 16 | (color & 0x00FF00) | (color & 0xFF0000) >> 16; // RGB to BGR
+void clif_messagecolor(struct block_list* bl, unsigned long color, const char* msg) {
+ unsigned short msg_len = strlen(msg) + 1;
+ uint8 buf[256];
+ color = (color & 0x0000FF) << 16 | (color & 0x00FF00) | (color & 0xFF0000) >> 16; // RGB to BGR
- nullpo_retv(bl);
+ nullpo_retv(bl);
- if (msg_len > sizeof(buf)-12) {
- ShowWarning("clif_messagecolor: Truncating too long message '%s' (len=%u).\n", msg, msg_len);
- msg_len = sizeof(buf)-12;
- }
+ if( msg_len > sizeof(buf)-12 )
+ {
+ ShowWarning("clif_messagecolor: Truncating too long message '%s' (len=%u).\n", msg, msg_len);
+ msg_len = sizeof(buf)-12;
+ }
- WBUFW(buf,0) = 0x2C1;
- WBUFW(buf,2) = msg_len + 12;
- WBUFL(buf,4) = bl->id;
- WBUFL(buf,8) = color;
- memcpy(WBUFP(buf,12), msg, msg_len);
+ WBUFW(buf,0) = 0x2C1;
+ WBUFW(buf,2) = msg_len + 12;
+ WBUFL(buf,4) = bl->id;
+ WBUFL(buf,8) = color;
+ memcpy(WBUFP(buf,12), msg, msg_len);
- clif_send(buf, WBUFW(buf,2), bl, AREA_CHAT_WOC);
+ clif_send(buf, WBUFW(buf,2), bl, AREA_CHAT_WOC);
}
/// Public chat message [Valaris] (ZC_NOTIFY_CHAT).
/// 008d <packet len>.W <id>.L <message>.?B
-void clif_message(struct block_list *bl, const char *msg)
-{
- unsigned short msg_len = strlen(msg) + 1;
- uint8 buf[256];
- nullpo_retv(bl);
+void clif_message(struct block_list* bl, const char* msg) {
+ unsigned short msg_len = strlen(msg) + 1;
+ uint8 buf[256];
+ nullpo_retv(bl);
- if (msg_len > sizeof(buf)-8) {
- ShowWarning("clif_message: Truncating too long message '%s' (len=%u).\n", msg, msg_len);
- msg_len = sizeof(buf)-8;
- }
+ if( msg_len > sizeof(buf)-8 ) {
+ ShowWarning("clif_message: Truncating too long message '%s' (len=%u).\n", msg, msg_len);
+ msg_len = sizeof(buf)-8;
+ }
- WBUFW(buf,0) = 0x8d;
- WBUFW(buf,2) = msg_len + 8;
- WBUFL(buf,4) = bl->id;
- safestrncpy((char *)WBUFP(buf,8), msg, msg_len);
+ WBUFW(buf,0) = 0x8d;
+ WBUFW(buf,2) = msg_len + 8;
+ WBUFL(buf,4) = bl->id;
+ safestrncpy((char*)WBUFP(buf,8), msg, msg_len);
- clif_send(buf, WBUFW(buf,2), bl, AREA_CHAT_WOC);
+ clif_send(buf, WBUFW(buf,2), bl, AREA_CHAT_WOC);
}
// refresh the client's screen, getting rid of any effects
void clif_refresh(struct map_session_data *sd)
{
- int i;
- nullpo_retv(sd);
-
- clif_changemap(sd,sd->mapindex,sd->bl.x,sd->bl.y);
- clif_inventorylist(sd);
- if (pc_iscarton(sd)) {
- clif_cartlist(sd);
- clif_updatestatus(sd,SP_CARTINFO);
- }
- clif_updatestatus(sd,SP_WEIGHT);
- clif_updatestatus(sd,SP_MAXWEIGHT);
- clif_updatestatus(sd,SP_STR);
- clif_updatestatus(sd,SP_AGI);
- clif_updatestatus(sd,SP_VIT);
- clif_updatestatus(sd,SP_INT);
- clif_updatestatus(sd,SP_DEX);
- clif_updatestatus(sd,SP_LUK);
- if (sd->spiritball)
- clif_spiritball_single(sd->fd, sd);
- for (i = 1; i < 5; i++) {
- if (sd->talisman[i] > 0)
- clif_talisman_single(sd->fd, sd, i);
- }
- if (sd->vd.cloth_color)
- clif_refreshlook(&sd->bl,sd->bl.id,LOOK_CLOTHES_COLOR,sd->vd.cloth_color,SELF);
- if (merc_is_hom_active(sd->hd))
- clif_send_homdata(sd,SP_ACK,0);
- if (sd->md) {
- clif_mercenary_info(sd);
- clif_mercenary_skillblock(sd);
- }
- if (sd->ed)
- clif_elemental_info(sd);
- map_foreachinrange(clif_getareachar,&sd->bl,AREA_SIZE,BL_ALL,sd);
- clif_weather_check(sd);
- if (sd->chatID)
- chat_leavechat(sd,0);
- if (sd->state.vending)
- clif_openvending(sd, sd->bl.id, sd->vending);
- if (pc_issit(sd))
- clif_sitting(&sd->bl); // FIXME: just send to self, not area
- if (pc_isdead(sd)) // When you refresh, resend the death packet.
- clif_clearunit_single(sd->bl.id,CLR_DEAD,sd->fd);
- else
- clif_changed_dir(&sd->bl, SELF);
-
- // unlike vending, resuming buyingstore crashes the client.
- buyingstore_close(sd);
-
- mail_clear(sd);
+ int i;
+ nullpo_retv(sd);
+
+ clif_changemap(sd,sd->mapindex,sd->bl.x,sd->bl.y);
+ clif_inventorylist(sd);
+ if(pc_iscarton(sd)) {
+ clif_cartlist(sd);
+ clif_updatestatus(sd,SP_CARTINFO);
+ }
+ clif_updatestatus(sd,SP_WEIGHT);
+ clif_updatestatus(sd,SP_MAXWEIGHT);
+ clif_updatestatus(sd,SP_STR);
+ clif_updatestatus(sd,SP_AGI);
+ clif_updatestatus(sd,SP_VIT);
+ clif_updatestatus(sd,SP_INT);
+ clif_updatestatus(sd,SP_DEX);
+ clif_updatestatus(sd,SP_LUK);
+ if (sd->spiritball)
+ clif_spiritball_single(sd->fd, sd);
+ for(i = 1; i < 5; i++){
+ if( sd->talisman[i] > 0 )
+ clif_talisman_single(sd->fd, sd, i);
+ }
+ if (sd->vd.cloth_color)
+ clif_refreshlook(&sd->bl,sd->bl.id,LOOK_CLOTHES_COLOR,sd->vd.cloth_color,SELF);
+ if(merc_is_hom_active(sd->hd))
+ clif_send_homdata(sd,SP_ACK,0);
+ if( sd->md ) {
+ clif_mercenary_info(sd);
+ clif_mercenary_skillblock(sd);
+ }
+ if( sd->ed )
+ clif_elemental_info(sd);
+ map_foreachinrange(clif_getareachar,&sd->bl,AREA_SIZE,BL_ALL,sd);
+ clif_weather_check(sd);
+ if( sd->chatID )
+ chat_leavechat(sd,0);
+ if( sd->state.vending )
+ clif_openvending(sd, sd->bl.id, sd->vending);
+ if( pc_issit(sd) )
+ clif_sitting(&sd->bl); // FIXME: just send to self, not area
+ if( pc_isdead(sd) ) // When you refresh, resend the death packet.
+ clif_clearunit_single(sd->bl.id,CLR_DEAD,sd->fd);
+ else
+ clif_changed_dir(&sd->bl, SELF);
+
+ // unlike vending, resuming buyingstore crashes the client.
+ buyingstore_close(sd);
+
+ mail_clear(sd);
}
/// Updates the object's (bl) name on client.
/// 0095 <id>.L <char name>.24B (ZC_ACK_REQNAME)
/// 0195 <id>.L <char name>.24B <party name>.24B <guild name>.24B <position name>.24B (ZC_ACK_REQNAMEALL)
-void clif_charnameack(int fd, struct block_list *bl)
-{
- unsigned char buf[103];
- int cmd = 0x95, i, ps = -1;
-
- nullpo_retv(bl);
-
- WBUFW(buf,0) = cmd;
- WBUFL(buf,2) = bl->id;
-
- switch (bl->type) {
- case BL_PC: {
- struct map_session_data *ssd = (struct map_session_data *)bl;
- struct party_data *p = NULL;
- struct guild *g = NULL;
-
- //Requesting your own "shadow" name. [Skotlex]
- if (ssd->fd == fd && ssd->disguise)
- WBUFL(buf,2) = -bl->id;
-
- if (ssd->fakename[0]) {
- WBUFW(buf, 0) = cmd = 0x195;
- memcpy(WBUFP(buf,6), ssd->fakename, NAME_LENGTH);
- WBUFB(buf,30) = WBUFB(buf,54) = WBUFB(buf,78) = 0;
- break;
- }
- memcpy(WBUFP(buf,6), ssd->status.name, NAME_LENGTH);
-
- if (ssd->status.party_id) {
- p = party_search(ssd->status.party_id);
- }
- if (ssd->status.guild_id) {
- if ((g = guild_search(ssd->status.guild_id)) != NULL) {
- ARR_FIND(0, g->max_member, i, g->member[i].account_id == ssd->status.account_id && g->member[i].char_id == ssd->status.char_id);
- if (i < g->max_member) ps = g->member[i].position;
- }
- }
-
- if (!battle_config.display_party_name && g == NULL) {
- // do not display party unless the player is also in a guild
- p = NULL;
- }
-
- if (p == NULL && g == NULL)
- break;
-
- WBUFW(buf, 0) = cmd = 0x195;
- if (p)
- memcpy(WBUFP(buf,30), p->party.name, NAME_LENGTH);
- else
- WBUFB(buf,30) = 0;
-
- if (g && ps >= 0 && ps < MAX_GUILDPOSITION) {
- memcpy(WBUFP(buf,54), g->name,NAME_LENGTH);
- memcpy(WBUFP(buf,78), g->position[ps].name, NAME_LENGTH);
- } else { //Assume no guild.
- WBUFB(buf,54) = 0;
- WBUFB(buf,78) = 0;
- }
- }
- break;
- //[blackhole89]
- case BL_HOM:
- memcpy(WBUFP(buf,6), ((TBL_HOM *)bl)->homunculus.name, NAME_LENGTH);
- break;
- case BL_MER:
- memcpy(WBUFP(buf,6), ((TBL_MER *)bl)->db->name, NAME_LENGTH);
- break;
- case BL_PET:
- memcpy(WBUFP(buf,6), ((TBL_PET *)bl)->pet.name, NAME_LENGTH);
- break;
- case BL_NPC:
- memcpy(WBUFP(buf,6), ((TBL_NPC *)bl)->name, NAME_LENGTH);
- break;
- case BL_MOB: {
- struct mob_data *md = (struct mob_data *)bl;
- nullpo_retv(md);
-
- memcpy(WBUFP(buf,6), md->name, NAME_LENGTH);
- if (md->guardian_data && md->guardian_data->guild_id) {
- WBUFW(buf, 0) = cmd = 0x195;
- WBUFB(buf,30) = 0;
- memcpy(WBUFP(buf,54), md->guardian_data->guild_name, NAME_LENGTH);
- memcpy(WBUFP(buf,78), md->guardian_data->castle->castle_name, NAME_LENGTH);
- } else if (battle_config.show_mob_info) {
- char mobhp[50], *str_p = mobhp;
- WBUFW(buf, 0) = cmd = 0x195;
- if (battle_config.show_mob_info&4)
- str_p += sprintf(str_p, "Lv. %d | ", md->level);
- if (battle_config.show_mob_info&1)
- str_p += sprintf(str_p, "HP: %u/%u | ", md->status.hp, md->status.max_hp);
- if (battle_config.show_mob_info&2)
- str_p += sprintf(str_p, "HP: %d%% | ", get_percentage(md->status.hp, md->status.max_hp));
- //Even thought mobhp ain't a name, we send it as one so the client
- //can parse it. [Skotlex]
- if (str_p != mobhp) {
- *(str_p-3) = '\0'; //Remove trailing space + pipe.
- memcpy(WBUFP(buf,30), mobhp, NAME_LENGTH);
- WBUFB(buf,54) = 0;
- WBUFB(buf,78) = 0;
- }
- }
- }
- break;
- case BL_CHAT: //FIXME: Clients DO request this... what should be done about it? The chat's title may not fit... [Skotlex]
- // memcpy(WBUFP(buf,6), (struct chat*)->title, NAME_LENGTH);
- // break;
- return;
- case BL_ELEM:
- memcpy(WBUFP(buf,6), ((TBL_ELEM *)bl)->db->name, NAME_LENGTH);
- break;
- default:
- ShowError("clif_charnameack: bad type %d(%d)\n", bl->type, bl->id);
- return;
- }
-
- // if no receipient specified just update nearby clients
- if (fd == 0)
- clif_send(buf, packet_len(cmd), bl, AREA);
- else {
- WFIFOHEAD(fd, packet_len(cmd));
- memcpy(WFIFOP(fd, 0), buf, packet_len(cmd));
- WFIFOSET(fd, packet_len(cmd));
- }
+void clif_charnameack (int fd, struct block_list *bl)
+{
+ unsigned char buf[103];
+ int cmd = 0x95, i, ps = -1;
+
+ nullpo_retv(bl);
+
+ WBUFW(buf,0) = cmd;
+ WBUFL(buf,2) = bl->id;
+
+ switch( bl->type )
+ {
+ case BL_PC:
+ {
+ struct map_session_data *ssd = (struct map_session_data *)bl;
+ struct party_data *p = NULL;
+ struct guild *g = NULL;
+
+ //Requesting your own "shadow" name. [Skotlex]
+ if (ssd->fd == fd && ssd->disguise)
+ WBUFL(buf,2) = -bl->id;
+
+ if( ssd->fakename[0] )
+ {
+ WBUFW(buf, 0) = cmd = 0x195;
+ memcpy(WBUFP(buf,6), ssd->fakename, NAME_LENGTH);
+ WBUFB(buf,30) = WBUFB(buf,54) = WBUFB(buf,78) = 0;
+ break;
+ }
+ memcpy(WBUFP(buf,6), ssd->status.name, NAME_LENGTH);
+
+ if( ssd->status.party_id )
+ {
+ p = party_search(ssd->status.party_id);
+ }
+ if( ssd->status.guild_id )
+ {
+ if( ( g = guild_search(ssd->status.guild_id) ) != NULL )
+ {
+ ARR_FIND(0, g->max_member, i, g->member[i].account_id == ssd->status.account_id && g->member[i].char_id == ssd->status.char_id);
+ if( i < g->max_member ) ps = g->member[i].position;
+ }
+ }
+
+ if( !battle_config.display_party_name && g == NULL )
+ {// do not display party unless the player is also in a guild
+ p = NULL;
+ }
+
+ if (p == NULL && g == NULL)
+ break;
+
+ WBUFW(buf, 0) = cmd = 0x195;
+ if (p)
+ memcpy(WBUFP(buf,30), p->party.name, NAME_LENGTH);
+ else
+ WBUFB(buf,30) = 0;
+
+ if (g && ps >= 0 && ps < MAX_GUILDPOSITION)
+ {
+ memcpy(WBUFP(buf,54), g->name,NAME_LENGTH);
+ memcpy(WBUFP(buf,78), g->position[ps].name, NAME_LENGTH);
+ } else { //Assume no guild.
+ WBUFB(buf,54) = 0;
+ WBUFB(buf,78) = 0;
+ }
+ }
+ break;
+ //[blackhole89]
+ case BL_HOM:
+ memcpy(WBUFP(buf,6), ((TBL_HOM*)bl)->homunculus.name, NAME_LENGTH);
+ break;
+ case BL_MER:
+ memcpy(WBUFP(buf,6), ((TBL_MER*)bl)->db->name, NAME_LENGTH);
+ break;
+ case BL_PET:
+ memcpy(WBUFP(buf,6), ((TBL_PET*)bl)->pet.name, NAME_LENGTH);
+ break;
+ case BL_NPC:
+ memcpy(WBUFP(buf,6), ((TBL_NPC*)bl)->name, NAME_LENGTH);
+ break;
+ case BL_MOB:
+ {
+ struct mob_data *md = (struct mob_data *)bl;
+ nullpo_retv(md);
+
+ memcpy(WBUFP(buf,6), md->name, NAME_LENGTH);
+ if( md->guardian_data && md->guardian_data->guild_id )
+ {
+ WBUFW(buf, 0) = cmd = 0x195;
+ WBUFB(buf,30) = 0;
+ memcpy(WBUFP(buf,54), md->guardian_data->guild_name, NAME_LENGTH);
+ memcpy(WBUFP(buf,78), md->guardian_data->castle->castle_name, NAME_LENGTH);
+ }
+ else if( battle_config.show_mob_info )
+ {
+ char mobhp[50], *str_p = mobhp;
+ WBUFW(buf, 0) = cmd = 0x195;
+ if( battle_config.show_mob_info&4 )
+ str_p += sprintf(str_p, "Lv. %d | ", md->level);
+ if( battle_config.show_mob_info&1 )
+ str_p += sprintf(str_p, "HP: %u/%u | ", md->status.hp, md->status.max_hp);
+ if( battle_config.show_mob_info&2 )
+ str_p += sprintf(str_p, "HP: %d%% | ", get_percentage(md->status.hp, md->status.max_hp));
+ //Even thought mobhp ain't a name, we send it as one so the client
+ //can parse it. [Skotlex]
+ if( str_p != mobhp )
+ {
+ *(str_p-3) = '\0'; //Remove trailing space + pipe.
+ memcpy(WBUFP(buf,30), mobhp, NAME_LENGTH);
+ WBUFB(buf,54) = 0;
+ WBUFB(buf,78) = 0;
+ }
+ }
+ }
+ break;
+ case BL_CHAT: //FIXME: Clients DO request this... what should be done about it? The chat's title may not fit... [Skotlex]
+// memcpy(WBUFP(buf,6), (struct chat*)->title, NAME_LENGTH);
+// break;
+ return;
+ case BL_ELEM:
+ memcpy(WBUFP(buf,6), ((TBL_ELEM*)bl)->db->name, NAME_LENGTH);
+ break;
+ default:
+ ShowError("clif_charnameack: bad type %d(%d)\n", bl->type, bl->id);
+ return;
+ }
+
+ // if no receipient specified just update nearby clients
+ if (fd == 0)
+ clif_send(buf, packet_len(cmd), bl, AREA);
+ else {
+ WFIFOHEAD(fd, packet_len(cmd));
+ memcpy(WFIFOP(fd, 0), buf, packet_len(cmd));
+ WFIFOSET(fd, packet_len(cmd));
+ }
}
//Used to update when a char leaves a party/guild. [Skotlex]
//Needed because when you send a 0x95 packet, the client will not remove the cached party/guild info that is not sent.
-void clif_charnameupdate(struct map_session_data *ssd)
+void clif_charnameupdate (struct map_session_data *ssd)
{
- unsigned char buf[103];
- int cmd = 0x195, ps = -1, i;
- struct party_data *p = NULL;
- struct guild *g = NULL;
+ unsigned char buf[103];
+ int cmd = 0x195, ps = -1, i;
+ struct party_data *p = NULL;
+ struct guild *g = NULL;
- nullpo_retv(ssd);
+ nullpo_retv(ssd);
- if (ssd->fakename[0])
- return; //No need to update as the party/guild was not displayed anyway.
+ if( ssd->fakename[0] )
+ return; //No need to update as the party/guild was not displayed anyway.
- WBUFW(buf,0) = cmd;
- WBUFL(buf,2) = ssd->bl.id;
+ WBUFW(buf,0) = cmd;
+ WBUFL(buf,2) = ssd->bl.id;
- memcpy(WBUFP(buf,6), ssd->status.name, NAME_LENGTH);
+ memcpy(WBUFP(buf,6), ssd->status.name, NAME_LENGTH);
- if (!battle_config.display_party_name) {
- if (ssd->status.party_id > 0 && ssd->status.guild_id > 0 && (g = guild_search(ssd->status.guild_id)) != NULL)
- p = party_search(ssd->status.party_id);
- } else {
- if (ssd->status.party_id > 0)
- p = party_search(ssd->status.party_id);
- }
+ if (!battle_config.display_party_name) {
+ if (ssd->status.party_id > 0 && ssd->status.guild_id > 0 && (g = guild_search(ssd->status.guild_id)) != NULL)
+ p = party_search(ssd->status.party_id);
+ }else{
+ if (ssd->status.party_id > 0)
+ p = party_search(ssd->status.party_id);
+ }
- if (ssd->status.guild_id > 0 && (g = guild_search(ssd->status.guild_id)) != NULL) {
- ARR_FIND(0, g->max_member, i, g->member[i].account_id == ssd->status.account_id && g->member[i].char_id == ssd->status.char_id);
- if (i < g->max_member) ps = g->member[i].position;
- }
+ if( ssd->status.guild_id > 0 && (g = guild_search(ssd->status.guild_id)) != NULL )
+ {
+ ARR_FIND(0, g->max_member, i, g->member[i].account_id == ssd->status.account_id && g->member[i].char_id == ssd->status.char_id);
+ if( i < g->max_member ) ps = g->member[i].position;
+ }
- if (p)
- memcpy(WBUFP(buf,30), p->party.name, NAME_LENGTH);
- else
- WBUFB(buf,30) = 0;
-
- if (g && ps >= 0 && ps < MAX_GUILDPOSITION) {
- memcpy(WBUFP(buf,54), g->name,NAME_LENGTH);
- memcpy(WBUFP(buf,78), g->position[ps].name, NAME_LENGTH);
- } else {
- WBUFB(buf,54) = 0;
- WBUFB(buf,78) = 0;
- }
+ if( p )
+ memcpy(WBUFP(buf,30), p->party.name, NAME_LENGTH);
+ else
+ WBUFB(buf,30) = 0;
+
+ if( g && ps >= 0 && ps < MAX_GUILDPOSITION )
+ {
+ memcpy(WBUFP(buf,54), g->name,NAME_LENGTH);
+ memcpy(WBUFP(buf,78), g->position[ps].name, NAME_LENGTH);
+ }
+ else
+ {
+ WBUFB(buf,54) = 0;
+ WBUFB(buf,78) = 0;
+ }
- // Update nearby clients
- clif_send(buf, packet_len(cmd), &ssd->bl, AREA);
+ // Update nearby clients
+ clif_send(buf, packet_len(cmd), &ssd->bl, AREA);
}
@@ -8397,46 +8489,47 @@ void clif_charnameupdate(struct map_session_data *ssd)
/// stays that way.
void clif_slide(struct block_list *bl, int x, int y)
{
- unsigned char buf[10];
- nullpo_retv(bl);
+ unsigned char buf[10];
+ nullpo_retv(bl);
- WBUFW(buf, 0) = 0x01ff;
- WBUFL(buf, 2) = bl->id;
- WBUFW(buf, 6) = x;
- WBUFW(buf, 8) = y;
- clif_send(buf, packet_len(0x1ff), bl, AREA);
+ WBUFW(buf, 0) = 0x01ff;
+ WBUFL(buf, 2) = bl->id;
+ WBUFW(buf, 6) = x;
+ WBUFW(buf, 8) = y;
+ clif_send(buf, packet_len(0x1ff), bl, AREA);
- if (disguised(bl)) {
- WBUFL(buf,2) = -bl->id;
- clif_send(buf, packet_len(0x1ff), bl, SELF);
- }
+ if( disguised(bl) )
+ {
+ WBUFL(buf,2) = -bl->id;
+ clif_send(buf, packet_len(0x1ff), bl, SELF);
+ }
}
/*------------------------------------------
* @me command by lordalfa, rewritten implementation by Skotlex
*------------------------------------------*/
-void clif_disp_overhead(struct map_session_data *sd, const char *mes)
+void clif_disp_overhead(struct map_session_data *sd, const char* mes)
{
- unsigned char buf[256]; //This should be more than sufficient, the theorical max is CHAT_SIZE + 8 (pads and extra inserted crap)
- int len_mes = strlen(mes)+1; //Account for \0
+ unsigned char buf[256]; //This should be more than sufficient, the theorical max is CHAT_SIZE + 8 (pads and extra inserted crap)
+ int len_mes = strlen(mes)+1; //Account for \0
- if (len_mes > sizeof(buf)-8) {
- ShowError("clif_disp_overhead: Message too long (length %d)\n", len_mes);
- len_mes = sizeof(buf)-8; //Trunk it to avoid problems.
- }
- // send message to others
- WBUFW(buf,0) = 0x8d;
- WBUFW(buf,2) = len_mes + 8; // len of message + 8 (command+len+id)
- WBUFL(buf,4) = sd->bl.id;
- safestrncpy((char *)WBUFP(buf,8), mes, len_mes);
- clif_send(buf, WBUFW(buf,2), &sd->bl, AREA_CHAT_WOC);
+ if (len_mes > sizeof(buf)-8) {
+ ShowError("clif_disp_overhead: Message too long (length %d)\n", len_mes);
+ len_mes = sizeof(buf)-8; //Trunk it to avoid problems.
+ }
+ // send message to others
+ WBUFW(buf,0) = 0x8d;
+ WBUFW(buf,2) = len_mes + 8; // len of message + 8 (command+len+id)
+ WBUFL(buf,4) = sd->bl.id;
+ safestrncpy((char*)WBUFP(buf,8), mes, len_mes);
+ clif_send(buf, WBUFW(buf,2), &sd->bl, AREA_CHAT_WOC);
- // send back message to the speaker
- WBUFW(buf,0) = 0x8e;
- WBUFW(buf, 2) = len_mes + 4;
- safestrncpy((char *)WBUFP(buf,4), mes, len_mes);
- clif_send(buf, WBUFW(buf,2), &sd->bl, SELF);
+ // send back message to the speaker
+ WBUFW(buf,0) = 0x8e;
+ WBUFW(buf, 2) = len_mes + 4;
+ safestrncpy((char*)WBUFP(buf,4), mes, len_mes);
+ clif_send(buf, WBUFW(buf,2), &sd->bl, SELF);
}
/*==========================
@@ -8445,13 +8538,13 @@ void clif_disp_overhead(struct map_session_data *sd, const char *mes)
*--------------------------*/
void clif_party_xy_remove(struct map_session_data *sd)
{
- unsigned char buf[16];
- nullpo_retv(sd);
- WBUFW(buf,0)=0x107;
- WBUFL(buf,2)=sd->status.account_id;
- WBUFW(buf,6)=-1;
- WBUFW(buf,8)=-1;
- clif_send(buf,packet_len(0x107),&sd->bl,PARTY_SAMEMAP_WOS);
+ unsigned char buf[16];
+ nullpo_retv(sd);
+ WBUFW(buf,0)=0x107;
+ WBUFL(buf,2)=sd->status.account_id;
+ WBUFW(buf,6)=-1;
+ WBUFW(buf,8)=-1;
+ clif_send(buf,packet_len(0x107),&sd->bl,PARTY_SAMEMAP_WOS);
}
@@ -8472,11 +8565,11 @@ void clif_party_xy_remove(struct map_session_data *sd)
/// ? = nothing
void clif_gospel_info(struct map_session_data *sd, int type)
{
- int fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x215));
- WFIFOW(fd,0)=0x215;
- WFIFOL(fd,2)=type;
- WFIFOSET(fd, packet_len(0x215));
+ int fd=sd->fd;
+ WFIFOHEAD(fd,packet_len(0x215));
+ WFIFOW(fd,0)=0x215;
+ WFIFOL(fd,2)=type;
+ WFIFOSET(fd, packet_len(0x215));
}
@@ -8509,29 +8602,29 @@ void clif_gospel_info(struct map_session_data *sd, int type)
/// 22 = [Collector Rank] Target Item : <monster_id used as item id>
/// 30 = [Sun, Moon and Stars Angel] Designed places and monsters have been reset.
/// 40 = Target HP : <monster_id used as HP>
-void clif_starskill(struct map_session_data *sd, const char *mapname, int monster_id, unsigned char star, unsigned char result)
+void clif_starskill(struct map_session_data* sd, const char* mapname, int monster_id, unsigned char star, unsigned char result)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x20e));
- WFIFOW(fd,0) = 0x20e;
- safestrncpy((char *)WFIFOP(fd,2), mapname, NAME_LENGTH);
- WFIFOL(fd,26) = monster_id;
- WFIFOB(fd,30) = star;
- WFIFOB(fd,31) = result;
- WFIFOSET(fd,packet_len(0x20e));
+ WFIFOHEAD(fd,packet_len(0x20e));
+ WFIFOW(fd,0) = 0x20e;
+ safestrncpy((char*)WFIFOP(fd,2), mapname, NAME_LENGTH);
+ WFIFOL(fd,26) = monster_id;
+ WFIFOB(fd,30) = star;
+ WFIFOB(fd,31) = result;
+ WFIFOSET(fd,packet_len(0x20e));
}
/*==========================================
* Info about Star Glaldiator save map [Komurka]
* type: 1: Information, 0: Map registered
*------------------------------------------*/
-void clif_feel_info(struct map_session_data *sd, unsigned char feel_level, unsigned char type)
+void clif_feel_info(struct map_session_data* sd, unsigned char feel_level, unsigned char type)
{
- char mapname[MAP_NAME_LENGTH_EXT];
+ char mapname[MAP_NAME_LENGTH_EXT];
- mapindex_getmapname_ext(mapindex_id2name(sd->feel_map[feel_level].index), mapname);
- clif_starskill(sd, mapname, 0, feel_level, type ? 1 : 0);
+ mapindex_getmapname_ext(mapindex_id2name(sd->feel_map[feel_level].index), mapname);
+ clif_starskill(sd, mapname, 0, feel_level, type ? 1 : 0);
}
/*==========================================
@@ -8540,13 +8633,18 @@ void clif_feel_info(struct map_session_data *sd, unsigned char feel_level, unsig
*------------------------------------------*/
void clif_hate_info(struct map_session_data *sd, unsigned char hate_level,int class_, unsigned char type)
{
- if (pcdb_checkid(class_)) {
- clif_starskill(sd, job_name(class_), class_, hate_level, type ? 10 : 11);
- } else if (mobdb_checkid(class_)) {
- clif_starskill(sd, mob_db(class_)->jname, class_, hate_level, type ? 10 : 11);
- } else {
- ShowWarning("clif_hate_info: Received invalid class %d for this packet (char_id=%d, hate_level=%u, type=%u).\n", class_, sd->status.char_id, (unsigned int)hate_level, (unsigned int)type);
- }
+ if( pcdb_checkid(class_) )
+ {
+ clif_starskill(sd, job_name(class_), class_, hate_level, type ? 10 : 11);
+ }
+ else if( mobdb_checkid(class_) )
+ {
+ clif_starskill(sd, mob_db(class_)->jname, class_, hate_level, type ? 10 : 11);
+ }
+ else
+ {
+ ShowWarning("clif_hate_info: Received invalid class %d for this packet (char_id=%d, hate_level=%u, type=%u).\n", class_, sd->status.char_id, (unsigned int)hate_level, (unsigned int)type);
+ }
}
/*==========================================
@@ -8554,7 +8652,7 @@ void clif_hate_info(struct map_session_data *sd, unsigned char hate_level,int cl
*------------------------------------------*/
void clif_mission_info(struct map_session_data *sd, int mob_id, unsigned char progress)
{
- clif_starskill(sd, mob_db(mob_id)->jname, mob_id, progress, 20);
+ clif_starskill(sd, mob_db(mob_id)->jname, mob_id, progress, 20);
}
/*==========================================
@@ -8562,7 +8660,7 @@ void clif_mission_info(struct map_session_data *sd, int mob_id, unsigned char pr
*------------------------------------------*/
void clif_feel_hate_reset(struct map_session_data *sd)
{
- clif_starskill(sd, "", 0, 0, 30);
+ clif_starskill(sd, "", 0, 0, 30);
}
@@ -8573,17 +8671,17 @@ void clif_feel_hate_reset(struct map_session_data *sd)
/// value:
/// 0 = disabled
/// 1 = enabled
-void clif_equiptickack(struct map_session_data *sd, int flag)
+void clif_equiptickack(struct map_session_data* sd, int flag)
{
- int fd;
- nullpo_retv(sd);
- fd = sd->fd;
+ int fd;
+ nullpo_retv(sd);
+ fd = sd->fd;
- WFIFOHEAD(fd, packet_len(0x2d9));
- WFIFOW(fd, 0) = 0x2d9;
- WFIFOL(fd, 2) = 0;
- WFIFOL(fd, 6) = flag;
- WFIFOSET(fd, packet_len(0x2d9));
+ WFIFOHEAD(fd, packet_len(0x2d9));
+ WFIFOW(fd, 0) = 0x2d9;
+ WFIFOL(fd, 2) = 0;
+ WFIFOL(fd, 6) = flag;
+ WFIFOSET(fd, packet_len(0x2d9));
}
@@ -8592,16 +8690,16 @@ void clif_equiptickack(struct map_session_data *sd, int flag)
/// open equip window:
/// 0 = disabled
/// 1 = enabled
-void clif_equipcheckbox(struct map_session_data *sd)
+void clif_equipcheckbox(struct map_session_data* sd)
{
- int fd;
- nullpo_retv(sd);
- fd = sd->fd;
+ int fd;
+ nullpo_retv(sd);
+ fd = sd->fd;
- WFIFOHEAD(fd, packet_len(0x2da));
- WFIFOW(fd, 0) = 0x2da;
- WFIFOB(fd, 2) = (sd->status.show_equip ? 1 : 0);
- WFIFOSET(fd, packet_len(0x2da));
+ WFIFOHEAD(fd, packet_len(0x2da));
+ WFIFOW(fd, 0) = 0x2da;
+ WFIFOB(fd, 2) = (sd->status.show_equip ? 1 : 0);
+ WFIFOSET(fd, packet_len(0x2da));
}
@@ -8610,97 +8708,98 @@ void clif_equipcheckbox(struct map_session_data *sd)
/// 02d7 <packet len>.W <name>.24B <class>.W <hairstyle>.W <bottom-viewid>.W <mid-viewid>.W <up-viewid>.W <haircolor>.W <cloth-dye>.W <gender>.B {equip item}.28B* (ZC_EQUIPWIN_MICROSCOPE, PACKETVER >= 20100629)
/// 0859 <packet len>.W <name>.24B <class>.W <hairstyle>.W <bottom-viewid>.W <mid-viewid>.W <up-viewid>.W <haircolor>.W <cloth-dye>.W <gender>.B {equip item}.28B* (ZC_EQUIPWIN_MICROSCOPE2, PACKETVER >= 20101124)
/// 0859 <packet len>.W <name>.24B <class>.W <hairstyle>.W <bottom-viewid>.W <mid-viewid>.W <up-viewid>.W <robe>.W <haircolor>.W <cloth-dye>.W <gender>.B {equip item}.28B* (ZC_EQUIPWIN_MICROSCOPE2, PACKETVER >= 20110111)
-void clif_viewequip_ack(struct map_session_data *sd, struct map_session_data *tsd)
+void clif_viewequip_ack(struct map_session_data* sd, struct map_session_data* tsd)
{
- uint8 *buf;
- int i, n, fd, offset = 0;
+ uint8* buf;
+ int i, n, fd, offset = 0;
#if PACKETVER < 20100629
- const int s = 26;
+ const int s = 26;
#else
- const int s = 28;
+ const int s = 28;
#endif
- nullpo_retv(sd);
- nullpo_retv(tsd);
- fd = sd->fd;
+ nullpo_retv(sd);
+ nullpo_retv(tsd);
+ fd = sd->fd;
- WFIFOHEAD(fd, MAX_INVENTORY * s + 43);
- buf = WFIFOP(fd,0);
+ WFIFOHEAD(fd, MAX_INVENTORY * s + 43);
+ buf = WFIFOP(fd,0);
#if PACKETVER < 20101124
- WBUFW(buf, 0) = 0x2d7;
+ WBUFW(buf, 0) = 0x2d7;
#else
- WBUFW(buf, 0) = 0x859;
+ WBUFW(buf, 0) = 0x859;
#endif
- safestrncpy((char *)WBUFP(buf, 4), tsd->status.name, NAME_LENGTH);
- WBUFW(buf,28) = tsd->status.class_;
- WBUFW(buf,30) = tsd->vd.hair_style;
- WBUFW(buf,32) = tsd->vd.head_bottom;
- WBUFW(buf,34) = tsd->vd.head_mid;
- WBUFW(buf,36) = tsd->vd.head_top;
+ safestrncpy((char*)WBUFP(buf, 4), tsd->status.name, NAME_LENGTH);
+ WBUFW(buf,28) = tsd->status.class_;
+ WBUFW(buf,30) = tsd->vd.hair_style;
+ WBUFW(buf,32) = tsd->vd.head_bottom;
+ WBUFW(buf,34) = tsd->vd.head_mid;
+ WBUFW(buf,36) = tsd->vd.head_top;
#if PACKETVER >= 20110111
- WBUFW(buf,38) = tsd->vd.robe;
- offset+= 2;
- buf = WBUFP(buf,2);
+ WBUFW(buf,38) = tsd->vd.robe;
+ offset+= 2;
+ buf = WBUFP(buf,2);
#endif
- WBUFW(buf,38) = tsd->vd.hair_color;
- WBUFW(buf,40) = tsd->vd.cloth_color;
- WBUFB(buf,42) = tsd->vd.sex;
-
- for (i=0,n=0; i < MAX_INVENTORY; i++) {
- if (tsd->status.inventory[i].nameid <= 0 || tsd->inventory_data[i] == NULL) // Item doesn't exist
- continue;
- if (!itemdb_isequip2(tsd->inventory_data[i])) // Is not equippable
- continue;
-
- // Inventory position
- WBUFW(buf, n*s+43) = i + 2;
- // Add refine, identify flag, element, etc.
- clif_item_sub(WBUFP(buf,0), n*s+45, &tsd->status.inventory[i], tsd->inventory_data[i], pc_equippoint(tsd, i));
- // Add cards
- clif_addcards(WBUFP(buf, n*s+55), &tsd->status.inventory[i]);
- // Expiration date stuff, if all of those are set to 0 then the client doesn't show anything related (6 bytes)
- WBUFL(buf, n*s+63) = tsd->status.inventory[i].expire_time;
- WBUFW(buf, n*s+67) = 0;
+ WBUFW(buf,38) = tsd->vd.hair_color;
+ WBUFW(buf,40) = tsd->vd.cloth_color;
+ WBUFB(buf,42) = tsd->vd.sex;
+
+ for(i=0,n=0; i < MAX_INVENTORY; i++)
+ {
+ if (tsd->status.inventory[i].nameid <= 0 || tsd->inventory_data[i] == NULL) // Item doesn't exist
+ continue;
+ if (!itemdb_isequip2(tsd->inventory_data[i])) // Is not equippable
+ continue;
+
+ // Inventory position
+ WBUFW(buf, n*s+43) = i + 2;
+ // Add refine, identify flag, element, etc.
+ clif_item_sub(WBUFP(buf,0), n*s+45, &tsd->status.inventory[i], tsd->inventory_data[i], pc_equippoint(tsd, i));
+ // Add cards
+ clif_addcards(WBUFP(buf, n*s+55), &tsd->status.inventory[i]);
+ // Expiration date stuff, if all of those are set to 0 then the client doesn't show anything related (6 bytes)
+ WBUFL(buf, n*s+63) = tsd->status.inventory[i].expire_time;
+ WBUFW(buf, n*s+67) = 0;
#if PACKETVER >= 20100629
- if (tsd->inventory_data[i]->equip&EQP_VISIBLE)
- WBUFW(buf, n*s+69) = tsd->inventory_data[i]->look;
- else
- WBUFW(buf, n*s+69) = 0;
+ if (tsd->inventory_data[i]->equip&EQP_VISIBLE)
+ WBUFW(buf, n*s+69) = tsd->inventory_data[i]->look;
+ else
+ WBUFW(buf, n*s+69) = 0;
#endif
- n++;
- }
+ n++;
+ }
- WFIFOW(fd, 2) = 43+offset+n*s; // Set length
- WFIFOSET(fd, WFIFOW(fd, 2));
+ WFIFOW(fd, 2) = 43+offset+n*s; // Set length
+ WFIFOSET(fd, WFIFOW(fd, 2));
}
/// Display msgstringtable.txt string (ZC_MSG).
/// 0291 <message>.W
-void clif_msg(struct map_session_data *sd, unsigned short id)
+void clif_msg(struct map_session_data* sd, unsigned short id)
{
- int fd;
- nullpo_retv(sd);
- fd = sd->fd;
+ int fd;
+ nullpo_retv(sd);
+ fd = sd->fd;
- WFIFOHEAD(fd, packet_len(0x291));
- WFIFOW(fd, 0) = 0x291;
- WFIFOW(fd, 2) = id; // zero-based msgstringtable.txt index
- WFIFOSET(fd, packet_len(0x291));
+ WFIFOHEAD(fd, packet_len(0x291));
+ WFIFOW(fd, 0) = 0x291;
+ WFIFOW(fd, 2) = id; // zero-based msgstringtable.txt index
+ WFIFOSET(fd, packet_len(0x291));
}
/// Display msgstringtable.txt string and fill in a valid for %d format (ZC_MSG_VALUE).
/// 0x7e2 <message>.W <value>.L
-void clif_msg_value(struct map_session_data *sd, unsigned short id, int value)
+void clif_msg_value(struct map_session_data* sd, unsigned short id, int value)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd, packet_len(0x7e2));
- WFIFOW(fd,0) = 0x7e2;
- WFIFOW(fd,2) = id;
- WFIFOL(fd,4) = value;
- WFIFOSET(fd, packet_len(0x7e2));
+ WFIFOHEAD(fd, packet_len(0x7e2));
+ WFIFOW(fd,0) = 0x7e2;
+ WFIFOW(fd,2) = id;
+ WFIFOL(fd,4) = value;
+ WFIFOSET(fd, packet_len(0x7e2));
}
@@ -8709,22 +8808,22 @@ void clif_msg_value(struct map_session_data *sd, unsigned short id, int value)
///
/// NOTE: Message has following format and is printed in color 0xCDCDFF (purple):
/// "[SkillName] Message"
-void clif_msg_skill(struct map_session_data *sd, unsigned short skill_id, int msg_id)
+void clif_msg_skill(struct map_session_data* sd, unsigned short skill_id, int msg_id)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd, packet_len(0x7e6));
- WFIFOW(fd,0) = 0x7e6;
- WFIFOW(fd,2) = skill_id;
- WFIFOL(fd,4) = msg_id;
- WFIFOSET(fd, packet_len(0x7e6));
+ WFIFOHEAD(fd, packet_len(0x7e6));
+ WFIFOW(fd,0) = 0x7e6;
+ WFIFOW(fd,2) = skill_id;
+ WFIFOL(fd,4) = msg_id;
+ WFIFOSET(fd, packet_len(0x7e6));
}
/// View player equip request denied
-void clif_viewequip_fail(struct map_session_data *sd)
+void clif_viewequip_fail(struct map_session_data* sd)
{
- clif_msg(sd, 0x54d);
+ clif_msg(sd, 0x54d);
}
@@ -8732,92 +8831,95 @@ void clif_viewequip_fail(struct map_session_data *sd)
/// Returns true if the packet was parsed successfully.
/// Formats: 0 - <packet id>.w <packet len>.w (<name> : <message>).?B 00
/// 1 - <packet id>.w <packet len>.w <name>.24B <message>.?B 00
-static bool clif_process_message(struct map_session_data *sd, int format, char **name_, int *namelen_, char **message_, int *messagelen_)
-{
- char *text, *name, *message;
- unsigned int packetlen, textlen, namelen, messagelen;
- int fd = sd->fd;
-
- *name_ = NULL;
- *namelen_ = 0;
- *message_ = NULL;
- *messagelen_ = 0;
-
- packetlen = RFIFOW(fd,2);
- // basic structure checks
- if (packetlen < 4 + 1) {
- // 4-byte header and at least an empty string is expected
- ShowWarning("clif_process_message: Received malformed packet from player '%s' (no message data)!\n", sd->status.name);
- return false;
- }
-
- text = (char *)RFIFOP(fd,4);
- textlen = packetlen - 4;
-
- // process <name> part of the packet
- if (format == 0) {
- // name and message are separated by ' : '
- // validate name
- name = text;
- namelen = strnlen(sd->status.name, NAME_LENGTH-1); // name length (w/o zero byte)
-
- if (strncmp(name, sd->status.name, namelen) || // the text must start with the speaker's name
- name[namelen] != ' ' || name[namelen+1] != ':' || name[namelen+2] != ' ') { // followed by ' : '
- //Hacked message, or infamous "client desynch" issue where they pick one char while loading another.
- ShowWarning("clif_process_message: Player '%s' sent a message using an incorrect name! Forcing a relog...\n", sd->status.name);
- set_eof(fd); // Just kick them out to correct it.
- return false;
- }
-
- message = name + namelen + 3;
- messagelen = textlen - namelen - 3; // this should be the message length (w/ zero byte included)
- } else {
- // name has fixed width
- if (textlen < NAME_LENGTH + 1) {
- ShowWarning("clif_process_message: Received malformed packet from player '%s' (packet length is incorrect)!\n", sd->status.name);
- return false;
- }
-
- // validate name
- name = text;
- namelen = strnlen(name, NAME_LENGTH-1); // name length (w/o zero byte)
-
- if (name[namelen] != '\0') {
- // only restriction is that the name must be zero-terminated
- ShowWarning("clif_process_message: Player '%s' sent an unterminated name!\n", sd->status.name);
- return false;
- }
-
- message = name + NAME_LENGTH;
- messagelen = textlen - NAME_LENGTH; // this should be the message length (w/ zero byte included)
- }
-
- if (messagelen != strnlen(message, messagelen)+1) {
- // the declared length must match real length
- ShowWarning("clif_process_message: Received malformed packet from player '%s' (length is incorrect)!\n", sd->status.name);
- return false;
- }
- // verify <message> part of the packet
- if (message[messagelen-1] != '\0') {
- // message must be zero-terminated
- ShowWarning("clif_process_message: Player '%s' sent an unterminated message string!\n", sd->status.name);
- return false;
- }
- if (messagelen > CHAT_SIZE_MAX-1) {
- // messages mustn't be too long
- // Normally you can only enter CHATBOX_SIZE-1 letters into the chat box, but Frost Joke / Dazzler's text can be longer.
- // Also, the physical size of strings that use multibyte encoding can go multiple times over the chatbox capacity.
- // Neither the official client nor server place any restriction on the length of the data in the packet,
- // but we'll only allow reasonably long strings here. This also makes sure that they fit into the `chatlog` table.
- ShowWarning("clif_process_message: Player '%s' sent a message too long ('%.*s')!\n", sd->status.name, CHAT_SIZE_MAX-1, message);
- return false;
- }
-
- *name_ = name;
- *namelen_ = namelen;
- *message_ = message;
- *messagelen_ = messagelen;
- return true;
+static bool clif_process_message(struct map_session_data* sd, int format, char** name_, int* namelen_, char** message_, int* messagelen_)
+{
+ char *text, *name, *message;
+ unsigned int packetlen, textlen, namelen, messagelen;
+ int fd = sd->fd;
+
+ *name_ = NULL;
+ *namelen_ = 0;
+ *message_ = NULL;
+ *messagelen_ = 0;
+
+ packetlen = RFIFOW(fd,2);
+ // basic structure checks
+ if( packetlen < 4 + 1 )
+ { // 4-byte header and at least an empty string is expected
+ ShowWarning("clif_process_message: Received malformed packet from player '%s' (no message data)!\n", sd->status.name);
+ return false;
+ }
+
+ text = (char*)RFIFOP(fd,4);
+ textlen = packetlen - 4;
+
+ // process <name> part of the packet
+ if( format == 0 )
+ {// name and message are separated by ' : '
+ // validate name
+ name = text;
+ namelen = strnlen(sd->status.name, NAME_LENGTH-1); // name length (w/o zero byte)
+
+ if( strncmp(name, sd->status.name, namelen) || // the text must start with the speaker's name
+ name[namelen] != ' ' || name[namelen+1] != ':' || name[namelen+2] != ' ' ) // followed by ' : '
+ {
+ //Hacked message, or infamous "client desynch" issue where they pick one char while loading another.
+ ShowWarning("clif_process_message: Player '%s' sent a message using an incorrect name! Forcing a relog...\n", sd->status.name);
+ set_eof(fd); // Just kick them out to correct it.
+ return false;
+ }
+
+ message = name + namelen + 3;
+ messagelen = textlen - namelen - 3; // this should be the message length (w/ zero byte included)
+ }
+ else
+ {// name has fixed width
+ if( textlen < NAME_LENGTH + 1 )
+ {
+ ShowWarning("clif_process_message: Received malformed packet from player '%s' (packet length is incorrect)!\n", sd->status.name);
+ return false;
+ }
+
+ // validate name
+ name = text;
+ namelen = strnlen(name, NAME_LENGTH-1); // name length (w/o zero byte)
+
+ if( name[namelen] != '\0' )
+ { // only restriction is that the name must be zero-terminated
+ ShowWarning("clif_process_message: Player '%s' sent an unterminated name!\n", sd->status.name);
+ return false;
+ }
+
+ message = name + NAME_LENGTH;
+ messagelen = textlen - NAME_LENGTH; // this should be the message length (w/ zero byte included)
+ }
+
+ if( messagelen != strnlen(message, messagelen)+1 )
+ { // the declared length must match real length
+ ShowWarning("clif_process_message: Received malformed packet from player '%s' (length is incorrect)!\n", sd->status.name);
+ return false;
+ }
+ // verify <message> part of the packet
+ if( message[messagelen-1] != '\0' )
+ { // message must be zero-terminated
+ ShowWarning("clif_process_message: Player '%s' sent an unterminated message string!\n", sd->status.name);
+ return false;
+ }
+ if( messagelen > CHAT_SIZE_MAX-1 )
+ { // messages mustn't be too long
+ // Normally you can only enter CHATBOX_SIZE-1 letters into the chat box, but Frost Joke / Dazzler's text can be longer.
+ // Also, the physical size of strings that use multibyte encoding can go multiple times over the chatbox capacity.
+ // Neither the official client nor server place any restriction on the length of the data in the packet,
+ // but we'll only allow reasonably long strings here. This also makes sure that they fit into the `chatlog` table.
+ ShowWarning("clif_process_message: Player '%s' sent a message too long ('%.*s')!\n", sd->status.name, CHAT_SIZE_MAX-1, message);
+ return false;
+ }
+
+ *name_ = name;
+ *namelen_ = namelen;
+ *message_ = message;
+ *messagelen_ = messagelen;
+ return true;
}
// ---------------------
@@ -8835,62 +8937,62 @@ static bool clif_process_message(struct map_session_data *sd, int format, char *
// Only the first 'invalid' error that appears is used.
static int clif_guess_PacketVer(int fd, int get_previous, int *error)
{
- static int err = 1;
- static int packet_ver = -1;
- int cmd, packet_len, value; //Value is used to temporarily store account/char_id/sex
+ static int err = 1;
+ static int packet_ver = -1;
+ int cmd, packet_len, value; //Value is used to temporarily store account/char_id/sex
- if (get_previous) {
- //For quick reruns, since the normal code flow is to fetch this once to identify the packet version, then again in the wanttoconnect function. [Skotlex]
- if (error)
- *error = err;
- return packet_ver;
- }
+ if (get_previous)
+ {//For quick reruns, since the normal code flow is to fetch this once to identify the packet version, then again in the wanttoconnect function. [Skotlex]
+ if( error )
+ *error = err;
+ return packet_ver;
+ }
- //By default, start searching on the default one.
- err = 1;
- packet_ver = clif_config.packet_db_ver;
- cmd = RFIFOW(fd,0);
- packet_len = RFIFOREST(fd);
+ //By default, start searching on the default one.
+ err = 1;
+ packet_ver = clif_config.packet_db_ver;
+ cmd = RFIFOW(fd,0);
+ packet_len = RFIFOREST(fd);
#define SET_ERROR(n) \
- if( err == 1 )\
- err = n;\
- //define SET_ERROR
-
- // FIXME: If the packet is not received at once, this will FAIL.
- // Figure out, when it happens, that only part of the packet is
- // received, or fix the function to be able to deal with that
- // case.
+ if( err == 1 )\
+ err = n;\
+//define SET_ERROR
+
+ // FIXME: If the packet is not received at once, this will FAIL.
+ // Figure out, when it happens, that only part of the packet is
+ // received, or fix the function to be able to deal with that
+ // case.
#define CHECK_PACKET_VER() \
- if( cmd != clif_config.connect_cmd[packet_ver] || packet_len != packet_db[packet_ver][cmd].len )\
- ;/* not wanttoconnection or wrong length */\
- else if( (value=(int)RFIFOL(fd, packet_db[packet_ver][cmd].pos[0])) < START_ACCOUNT_NUM || value > END_ACCOUNT_NUM )\
- { SET_ERROR(2); }/* invalid account_id */\
- else if( (value=(int)RFIFOL(fd, packet_db[packet_ver][cmd].pos[1])) <= 0 )\
- { SET_ERROR(3); }/* invalid char_id */\
- /* RFIFOL(fd, packet_db[packet_ver][cmd].pos[2]) - don't care about login_id1 */\
- /* RFIFOL(fd, packet_db[packet_ver][cmd].pos[3]) - don't care about client_tick */\
- else if( (value=(int)RFIFOB(fd, packet_db[packet_ver][cmd].pos[4])) != 0 && value != 1 )\
- { SET_ERROR(6); }/* invalid sex */\
- else\
- {\
- err = 0;\
- if( error )\
- *error = 0;\
- return packet_ver;\
- }\
- //define CHECK_PACKET_VER
-
- CHECK_PACKET_VER();//Default packet version found.
-
- for (packet_ver = MAX_PACKET_VER; packet_ver > 0; packet_ver--) {
- //Start guessing the version, giving priority to the newer ones. [Skotlex]
- CHECK_PACKET_VER();
- }
- if (error)
- *error = err;
- packet_ver = -1;
- return -1;
+ if( cmd != clif_config.connect_cmd[packet_ver] || packet_len != packet_db[packet_ver][cmd].len )\
+ ;/* not wanttoconnection or wrong length */\
+ else if( (value=(int)RFIFOL(fd, packet_db[packet_ver][cmd].pos[0])) < START_ACCOUNT_NUM || value > END_ACCOUNT_NUM )\
+ { SET_ERROR(2); }/* invalid account_id */\
+ else if( (value=(int)RFIFOL(fd, packet_db[packet_ver][cmd].pos[1])) <= 0 )\
+ { SET_ERROR(3); }/* invalid char_id */\
+ /* RFIFOL(fd, packet_db[packet_ver][cmd].pos[2]) - don't care about login_id1 */\
+ /* RFIFOL(fd, packet_db[packet_ver][cmd].pos[3]) - don't care about client_tick */\
+ else if( (value=(int)RFIFOB(fd, packet_db[packet_ver][cmd].pos[4])) != 0 && value != 1 )\
+ { SET_ERROR(6); }/* invalid sex */\
+ else\
+ {\
+ err = 0;\
+ if( error )\
+ *error = 0;\
+ return packet_ver;\
+ }\
+//define CHECK_PACKET_VER
+
+ CHECK_PACKET_VER();//Default packet version found.
+
+ for (packet_ver = MAX_PACKET_VER; packet_ver > 0; packet_ver--)
+ { //Start guessing the version, giving priority to the newer ones. [Skotlex]
+ CHECK_PACKET_VER();
+ }
+ if( error )
+ *error = err;
+ packet_ver = -1;
+ return -1;
#undef SET_ERROR
#undef CHECK_PACKET_VER
}
@@ -8905,86 +9007,87 @@ static int clif_guess_PacketVer(int fd, int get_previous, int *error)
/// 0072 <account id>.L <char id>.L <auth code>.L <client time>.L <gender>.B (CZ_ENTER)
/// 0436 <account id>.L <char id>.L <auth code>.L <client time>.L <gender>.B (CZ_ENTER2)
/// There are various variants of this packet, some of them have padding between fields.
-void clif_parse_WantToConnection(int fd, TBL_PC *sd)
-{
- struct block_list *bl;
- struct auth_node *node;
- int cmd, account_id, char_id, login_id1, sex;
- unsigned int client_tick; //The client tick is a tick, therefore it needs be unsigned. [Skotlex]
- 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])
-
- if (sd) {
- ShowError("clif_parse_WantToConnection : invalid request (character already logged in)\n");
- return;
- }
-
- // Only valid packet version get here
- packet_ver = clif_guess_PacketVer(fd, 1, NULL);
-
- cmd = RFIFOW(fd,0);
- account_id = RFIFOL(fd, packet_db[packet_ver][cmd].pos[0]);
- char_id = RFIFOL(fd, packet_db[packet_ver][cmd].pos[1]);
- login_id1 = RFIFOL(fd, packet_db[packet_ver][cmd].pos[2]);
- client_tick = RFIFOL(fd, packet_db[packet_ver][cmd].pos[3]);
- sex = RFIFOB(fd, packet_db[packet_ver][cmd].pos[4]);
-
- if (packet_ver < 5 || // reject really old client versions
- (packet_ver <= 9 && (battle_config.packet_ver_flag & 1) == 0) || // older than 6sept04
- (packet_ver > 9 && (battle_config.packet_ver_flag & 1<<(packet_ver-9)) == 0)) { // version not allowed
- // packet version rejected
- ShowInfo("Rejected connection attempt, forbidden packet version (AID/CID: '"CL_WHITE"%d/%d"CL_RESET"', Packet Ver: '"CL_WHITE"%d"CL_RESET"', IP: '"CL_WHITE"%s"CL_RESET"').\n", account_id, char_id, packet_ver, ip2str(session[fd]->client_addr, NULL));
- WFIFOHEAD(fd,packet_len(0x6a));
- WFIFOW(fd,0) = 0x6a;
- WFIFOB(fd,2) = 5; // Your Game's EXE file is not the latest version
- WFIFOSET(fd,packet_len(0x6a));
- set_eof(fd);
- return;
- }
-
- if (runflag != MAPSERVER_ST_RUNNING) {
- // not allowed
- clif_authfail_fd(fd,1);// server closed
- return;
- }
-
- //Check for double login.
- bl = map_id2bl(account_id);
- if (bl && bl->type != BL_PC) {
- ShowError("clif_parse_WantToConnection: a non-player object already has id %d, please increase the starting account number\n", account_id);
- WFIFOHEAD(fd,packet_len(0x6a));
- WFIFOW(fd,0) = 0x6a;
- WFIFOB(fd,2) = 3; // Rejected by server
- WFIFOSET(fd,packet_len(0x6a));
- set_eof(fd);
- return;
- }
-
- if (bl ||
- ((node=chrif_search(account_id)) && //An already existing node is valid only if it is for this login.
- !(node->account_id == account_id && node->char_id == char_id && node->state == ST_LOGIN))) {
- clif_authfail_fd(fd, 8); //Still recognizes last connection
- return;
- }
-
- CREATE(sd, TBL_PC, 1);
- sd->fd = fd;
- sd->packet_ver = packet_ver;
- session[fd]->session_data = sd;
-
- pc_setnewpc(sd, account_id, char_id, login_id1, client_tick, sex, fd);
+void clif_parse_WantToConnection(int fd, TBL_PC* sd)
+{
+ struct block_list* bl;
+ struct auth_node* node;
+ int cmd, account_id, char_id, login_id1, sex;
+ unsigned int client_tick; //The client tick is a tick, therefore it needs be unsigned. [Skotlex]
+ 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])
+
+ if (sd) {
+ ShowError("clif_parse_WantToConnection : invalid request (character already logged in)\n");
+ return;
+ }
+
+ // Only valid packet version get here
+ packet_ver = clif_guess_PacketVer(fd, 1, NULL);
+
+ cmd = RFIFOW(fd,0);
+ account_id = RFIFOL(fd, packet_db[packet_ver][cmd].pos[0]);
+ char_id = RFIFOL(fd, packet_db[packet_ver][cmd].pos[1]);
+ login_id1 = RFIFOL(fd, packet_db[packet_ver][cmd].pos[2]);
+ client_tick = RFIFOL(fd, packet_db[packet_ver][cmd].pos[3]);
+ sex = RFIFOB(fd, packet_db[packet_ver][cmd].pos[4]);
+
+ if( packet_ver < 5 || // reject really old client versions
+ (packet_ver <= 9 && (battle_config.packet_ver_flag & 1) == 0) || // older than 6sept04
+ (packet_ver > 9 && (battle_config.packet_ver_flag & 1<<(packet_ver-9)) == 0)) // version not allowed
+ {// packet version rejected
+ ShowInfo("Rejected connection attempt, forbidden packet version (AID/CID: '"CL_WHITE"%d/%d"CL_RESET"', Packet Ver: '"CL_WHITE"%d"CL_RESET"', IP: '"CL_WHITE"%s"CL_RESET"').\n", account_id, char_id, packet_ver, ip2str(session[fd]->client_addr, NULL));
+ WFIFOHEAD(fd,packet_len(0x6a));
+ WFIFOW(fd,0) = 0x6a;
+ WFIFOB(fd,2) = 5; // Your Game's EXE file is not the latest version
+ WFIFOSET(fd,packet_len(0x6a));
+ set_eof(fd);
+ return;
+ }
+
+ if( runflag != MAPSERVER_ST_RUNNING )
+ {// not allowed
+ clif_authfail_fd(fd,1);// server closed
+ return;
+ }
+
+ //Check for double login.
+ bl = map_id2bl(account_id);
+ if(bl && bl->type != BL_PC) {
+ ShowError("clif_parse_WantToConnection: a non-player object already has id %d, please increase the starting account number\n", account_id);
+ WFIFOHEAD(fd,packet_len(0x6a));
+ WFIFOW(fd,0) = 0x6a;
+ WFIFOB(fd,2) = 3; // Rejected by server
+ WFIFOSET(fd,packet_len(0x6a));
+ set_eof(fd);
+ return;
+ }
+
+ if (bl ||
+ ((node=chrif_search(account_id)) && //An already existing node is valid only if it is for this login.
+ !(node->account_id == account_id && node->char_id == char_id && node->state == ST_LOGIN)))
+ {
+ clif_authfail_fd(fd, 8); //Still recognizes last connection
+ return;
+ }
+
+ CREATE(sd, TBL_PC, 1);
+ sd->fd = fd;
+ sd->packet_ver = packet_ver;
+ session[fd]->session_data = sd;
+
+ pc_setnewpc(sd, account_id, char_id, login_id1, client_tick, sex, fd);
#if PACKETVER < 20070521
- WFIFOHEAD(fd,4);
- WFIFOL(fd,0) = sd->bl.id;
- WFIFOSET(fd,4);
+ WFIFOHEAD(fd,4);
+ WFIFOL(fd,0) = sd->bl.id;
+ WFIFOSET(fd,4);
#else
- WFIFOHEAD(fd,packet_len(0x283));
- WFIFOW(fd,0) = 0x283;
- WFIFOL(fd,2) = sd->bl.id;
- WFIFOSET(fd,packet_len(0x283));
+ WFIFOHEAD(fd,packet_len(0x283));
+ WFIFOW(fd,0) = 0x283;
+ WFIFOL(fd,2) = sd->bl.id;
+ WFIFOSET(fd,packet_len(0x283));
#endif
- chrif_authreq(sd);
+ chrif_authreq(sd);
}
@@ -8992,325 +9095,332 @@ void clif_parse_WantToConnection(int fd, TBL_PC *sd)
/// 007d
void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
{
- if (sd->bl.prev != NULL)
- return;
+ if(sd->bl.prev != NULL)
+ return;
- if (!sd->state.active) {
- //Character loading is not complete yet!
- //Let pc_reg_received reinvoke this when ready.
- sd->state.connect_new = 0;
- return;
- }
+ if (!sd->state.active)
+ { //Character loading is not complete yet!
+ //Let pc_reg_received reinvoke this when ready.
+ sd->state.connect_new = 0;
+ return;
+ }
- if (sd->state.rewarp) {
- //Rewarp player.
- sd->state.rewarp = 0;
- clif_changemap(sd, sd->mapindex, sd->bl.x, sd->bl.y);
- return;
- }
+ if (sd->state.rewarp)
+ { //Rewarp player.
+ sd->state.rewarp = 0;
+ clif_changemap(sd, sd->mapindex, sd->bl.x, sd->bl.y);
+ return;
+ }
- sd->state.warping = 0;
+ sd->state.warping = 0;
- // look
+ // look
#if PACKETVER < 4
- clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
- clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
+ 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);
+ clif_changelook(&sd->bl,LOOK_WEAPON,0);
#endif
- if (sd->vd.cloth_color)
- clif_refreshlook(&sd->bl,sd->bl.id,LOOK_CLOTHES_COLOR,sd->vd.cloth_color,SELF);
-
- // item
- clif_inventorylist(sd); // inventory list first, otherwise deleted items in pc_checkitem show up as 'unknown item'
- pc_checkitem(sd);
-
- // cart
- if (pc_iscarton(sd)) {
- clif_cartlist(sd);
- clif_updatestatus(sd,SP_CARTINFO);
- }
-
- // weight
- clif_updatestatus(sd,SP_WEIGHT);
- clif_updatestatus(sd,SP_MAXWEIGHT);
-
- // guild
- // (needs to go before clif_spawn() to show guild emblems correctly)
- if (sd->status.guild_id)
- guild_send_memberinfoshort(sd,1);
-
- if (battle_config.pc_invincible_time > 0) {
- if (map_flag_gvg(sd->bl.m))
- pc_setinvincibletimer(sd,battle_config.pc_invincible_time<<1);
- else
- pc_setinvincibletimer(sd,battle_config.pc_invincible_time);
- }
-
- if (map[sd->bl.m].users++ == 0 && battle_config.dynamic_mobs)
- map_spawnmobs(sd->bl.m);
- if (!(sd->sc.option&OPTION_INVISIBLE)) {
- // increment the number of pvp players on the map
- map[sd->bl.m].users_pvp++;
- }
- if (map[sd->bl.m].instance_id) {
- instance[map[sd->bl.m].instance_id].users++;
- instance_check_idle(map[sd->bl.m].instance_id);
- }
- sd->state.debug_remove_map = 0; // temporary state to track double remove_map's [FlavioJS]
-
- // reset the callshop flag if the player changes map
- sd->state.callshop = 0;
-
- map_addblock(&sd->bl);
- clif_spawn(&sd->bl);
-
- // Party
- // (needs to go after clif_spawn() to show hp bars correctly)
- if (sd->status.party_id) {
- party_send_movemap(sd);
- clif_party_hp(sd); // Show hp after displacement [LuzZza]
- }
-
- if (sd->bg_id) clif_bg_hp(sd); // BattleGround System
-
- if (map[sd->bl.m].flag.pvp && !(sd->sc.option&OPTION_INVISIBLE)) {
- if (!battle_config.pk_mode) { // remove pvp stuff for pk_mode [Valaris]
- if (!map[sd->bl.m].flag.pvp_nocalcrank)
- sd->pvp_timer = add_timer(gettick()+200, pc_calc_pvprank_timer, sd->bl.id, 0);
- sd->pvp_rank = 0;
- sd->pvp_lastusers = 0;
- sd->pvp_point = 5;
- sd->pvp_won = 0;
- sd->pvp_lost = 0;
- }
- clif_map_property(sd, MAPPROPERTY_FREEPVPZONE);
- } else
- // set flag, if it's a duel [LuzZza]
- if (sd->duel_group)
- clif_map_property(sd, MAPPROPERTY_FREEPVPZONE);
-
- if (map[sd->bl.m].flag.gvg_dungeon)
- clif_map_property(sd, MAPPROPERTY_FREEPVPZONE); //TODO: Figure out the real packet to send here.
-
- if (map_flag_gvg(sd->bl.m))
- clif_map_property(sd, MAPPROPERTY_AGITZONE);
-
- // info about nearby objects
- // must use foreachinarea (CIRCULAR_AREA interferes with foreachinrange)
- 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, BL_ALL, sd);
-
- // pet
- if (sd->pd) {
- if (battle_config.pet_no_gvg && map_flag_gvg(sd->bl.m)) {
- //Return the pet to egg. [Skotlex]
- clif_displaymessage(sd->fd, msg_txt(666));
- pet_menu(sd, 3); //Option 3 is return to egg.
- } else {
- map_addblock(&sd->pd->bl);
- clif_spawn(&sd->pd->bl);
- clif_send_petdata(sd,sd->pd,0,0);
- clif_send_petstatus(sd);
- // skill_unit_move(&sd->pd->bl,gettick(),1);
- }
- }
-
- //homunculus [blackhole89]
- if (merc_is_hom_active(sd->hd)) {
- map_addblock(&sd->hd->bl);
- clif_spawn(&sd->hd->bl);
- clif_send_homdata(sd,SP_ACK,0);
- clif_hominfo(sd,sd->hd,1);
- clif_hominfo(sd,sd->hd,0); //for some reason, at least older clients want this sent twice
- clif_homskillinfoblock(sd);
- if (battle_config.hom_setting&0x8)
- status_calc_bl(&sd->hd->bl, SCB_SPEED); //Homunc mimic their master's speed on each map change
- if (!(battle_config.hom_setting&0x2))
- skill_unit_move(&sd->hd->bl,gettick(),1); // apply land skills immediately
- }
-
- if (sd->md) {
- map_addblock(&sd->md->bl);
- clif_spawn(&sd->md->bl);
- clif_mercenary_info(sd);
- clif_mercenary_skillblock(sd);
- status_calc_bl(&sd->md->bl, SCB_SPEED); //Mercenary mimic their master's speed on each map change
- }
-
- if (sd->ed) {
- map_addblock(&sd->ed->bl);
- clif_spawn(&sd->ed->bl);
- clif_elemental_info(sd);
- clif_elemental_updatestatus(sd,SP_HP);
- clif_hpmeter_single(sd->fd,sd->ed->bl.id,sd->ed->battle_status.hp,sd->ed->battle_status.matk_max);
- clif_elemental_updatestatus(sd,SP_SP);
- status_calc_bl(&sd->ed->bl, SCB_SPEED); //Elemental mimic their master's speed on each map change
- }
-
- if (sd->state.connect_new) {
- int lv;
- sd->state.connect_new = 0;
- clif_skillinfoblock(sd);
- clif_hotkeys_send(sd);
- clif_updatestatus(sd,SP_BASEEXP);
- clif_updatestatus(sd,SP_NEXTBASEEXP);
- clif_updatestatus(sd,SP_JOBEXP);
- clif_updatestatus(sd,SP_NEXTJOBEXP);
- clif_updatestatus(sd,SP_SKILLPOINT);
- clif_initialstatus(sd);
-
- if (sd->sc.option&OPTION_FALCON)
- clif_status_load(&sd->bl, SI_FALCON, 1);
-
- if (sd->sc.option&OPTION_RIDING)
- clif_status_load(&sd->bl, SI_RIDING, 1);
- else if (sd->sc.option&OPTION_WUGRIDER)
- clif_status_load(&sd->bl, SI_WUGRIDER, 1);
-
- if (sd->status.manner < 0)
- sc_start(&sd->bl,SC_NOCHAT,100,0,0);
-
- //Auron reported that This skill only triggers when you logon on the map o.O [Skotlex]
- if ((lv = pc_checkskill(sd,SG_KNOWLEDGE)) > 0) {
- if (sd->bl.m == sd->feel_map[0].m
- || sd->bl.m == sd->feel_map[1].m
- || sd->bl.m == sd->feel_map[2].m)
- sc_start(&sd->bl, SC_KNOWLEDGE, 100, lv, skill_get_time(SG_KNOWLEDGE, lv));
- }
-
- if (sd->pd && sd->pd->pet.intimate > 900)
- clif_pet_emotion(sd->pd,(sd->pd->pet.class_ - 100)*100 + 50 + pet_hungry_val(sd->pd));
-
- if (merc_is_hom_active(sd->hd))
- merc_hom_init_timers(sd->hd);
-
- if (night_flag && map[sd->bl.m].flag.nightenabled) {
- sd->state.night = 1;
- clif_status_load(&sd->bl, SI_NIGHT, 1);
- }
-
- // Notify everyone that this char logged in [Skotlex].
- map_foreachpc(clif_friendslist_toggle_sub, sd->status.account_id, sd->status.char_id, 1);
-
- //Login Event
- npc_script_event(sd, NPCE_LOGIN);
- } else {
- //For some reason the client "loses" these on warp/map-change.
- clif_updatestatus(sd,SP_STR);
- clif_updatestatus(sd,SP_AGI);
- clif_updatestatus(sd,SP_VIT);
- clif_updatestatus(sd,SP_INT);
- clif_updatestatus(sd,SP_DEX);
- clif_updatestatus(sd,SP_LUK);
-
- // abort currently running script
- sd->state.using_fake_npc = 0;
- sd->state.menu_or_input = 0;
- sd->npc_menu = 0;
-
- if (sd->npc_id)
- npc_event_dequeue(sd);
- }
-
- if (sd->state.changemap) {
- // restore information that gets lost on map-change
+ if(sd->vd.cloth_color)
+ clif_refreshlook(&sd->bl,sd->bl.id,LOOK_CLOTHES_COLOR,sd->vd.cloth_color,SELF);
+
+ // item
+ clif_inventorylist(sd); // inventory list first, otherwise deleted items in pc_checkitem show up as 'unknown item'
+ pc_checkitem(sd);
+
+ // cart
+ if(pc_iscarton(sd)) {
+ clif_cartlist(sd);
+ clif_updatestatus(sd,SP_CARTINFO);
+ }
+
+ // weight
+ clif_updatestatus(sd,SP_WEIGHT);
+ clif_updatestatus(sd,SP_MAXWEIGHT);
+
+ // guild
+ // (needs to go before clif_spawn() to show guild emblems correctly)
+ if(sd->status.guild_id)
+ guild_send_memberinfoshort(sd,1);
+
+ if(battle_config.pc_invincible_time > 0) {
+ if(map_flag_gvg(sd->bl.m))
+ pc_setinvincibletimer(sd,battle_config.pc_invincible_time<<1);
+ else
+ pc_setinvincibletimer(sd,battle_config.pc_invincible_time);
+ }
+
+ if( map[sd->bl.m].users++ == 0 && battle_config.dynamic_mobs )
+ map_spawnmobs(sd->bl.m);
+ if( !(sd->sc.option&OPTION_INVISIBLE) )
+ {// increment the number of pvp players on the map
+ map[sd->bl.m].users_pvp++;
+ }
+ if( map[sd->bl.m].instance_id )
+ {
+ instance[map[sd->bl.m].instance_id].users++;
+ instance_check_idle(map[sd->bl.m].instance_id);
+ }
+ sd->state.debug_remove_map = 0; // temporary state to track double remove_map's [FlavioJS]
+
+ // reset the callshop flag if the player changes map
+ sd->state.callshop = 0;
+
+ map_addblock(&sd->bl);
+ clif_spawn(&sd->bl);
+
+ // Party
+ // (needs to go after clif_spawn() to show hp bars correctly)
+ if(sd->status.party_id) {
+ party_send_movemap(sd);
+ clif_party_hp(sd); // Show hp after displacement [LuzZza]
+ }
+
+ if( sd->bg_id ) clif_bg_hp(sd); // BattleGround System
+
+ if(map[sd->bl.m].flag.pvp && !(sd->sc.option&OPTION_INVISIBLE)) {
+ if(!battle_config.pk_mode) { // remove pvp stuff for pk_mode [Valaris]
+ if (!map[sd->bl.m].flag.pvp_nocalcrank)
+ sd->pvp_timer = add_timer(gettick()+200, pc_calc_pvprank_timer, sd->bl.id, 0);
+ sd->pvp_rank = 0;
+ sd->pvp_lastusers = 0;
+ sd->pvp_point = 5;
+ sd->pvp_won = 0;
+ sd->pvp_lost = 0;
+ }
+ clif_map_property(sd, MAPPROPERTY_FREEPVPZONE);
+ } else
+ // set flag, if it's a duel [LuzZza]
+ if(sd->duel_group)
+ clif_map_property(sd, MAPPROPERTY_FREEPVPZONE);
+
+ if (map[sd->bl.m].flag.gvg_dungeon)
+ clif_map_property(sd, MAPPROPERTY_FREEPVPZONE); //TODO: Figure out the real packet to send here.
+
+ if( map_flag_gvg(sd->bl.m) )
+ clif_map_property(sd, MAPPROPERTY_AGITZONE);
+
+ // info about nearby objects
+ // must use foreachinarea (CIRCULAR_AREA interferes with foreachinrange)
+ 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, BL_ALL, sd);
+
+ // pet
+ if( sd->pd )
+ {
+ if( battle_config.pet_no_gvg && map_flag_gvg(sd->bl.m) )
+ { //Return the pet to egg. [Skotlex]
+ clif_displaymessage(sd->fd, msg_txt(666));
+ pet_menu(sd, 3); //Option 3 is return to egg.
+ }
+ else
+ {
+ map_addblock(&sd->pd->bl);
+ clif_spawn(&sd->pd->bl);
+ clif_send_petdata(sd,sd->pd,0,0);
+ clif_send_petstatus(sd);
+// skill_unit_move(&sd->pd->bl,gettick(),1);
+ }
+ }
+
+ //homunculus [blackhole89]
+ if( merc_is_hom_active(sd->hd) )
+ {
+ map_addblock(&sd->hd->bl);
+ clif_spawn(&sd->hd->bl);
+ clif_send_homdata(sd,SP_ACK,0);
+ clif_hominfo(sd,sd->hd,1);
+ clif_hominfo(sd,sd->hd,0); //for some reason, at least older clients want this sent twice
+ clif_homskillinfoblock(sd);
+ if( battle_config.hom_setting&0x8 )
+ status_calc_bl(&sd->hd->bl, SCB_SPEED); //Homunc mimic their master's speed on each map change
+ if( !(battle_config.hom_setting&0x2) )
+ skill_unit_move(&sd->hd->bl,gettick(),1); // apply land skills immediately
+ }
+
+ if( sd->md ) {
+ map_addblock(&sd->md->bl);
+ clif_spawn(&sd->md->bl);
+ clif_mercenary_info(sd);
+ clif_mercenary_skillblock(sd);
+ }
+
+ if( sd->ed ) {
+ map_addblock(&sd->ed->bl);
+ clif_spawn(&sd->ed->bl);
+ clif_elemental_info(sd);
+ clif_elemental_updatestatus(sd,SP_HP);
+ clif_hpmeter_single(sd->fd,sd->ed->bl.id,sd->ed->battle_status.hp,sd->ed->battle_status.matk_max);
+ clif_elemental_updatestatus(sd,SP_SP);
+ }
+
+ if(sd->state.connect_new) {
+ int lv;
+ sd->state.connect_new = 0;
+ clif_skillinfoblock(sd);
+ clif_hotkeys_send(sd);
+ clif_updatestatus(sd,SP_BASEEXP);
+ clif_updatestatus(sd,SP_NEXTBASEEXP);
+ clif_updatestatus(sd,SP_JOBEXP);
+ clif_updatestatus(sd,SP_NEXTJOBEXP);
+ clif_updatestatus(sd,SP_SKILLPOINT);
+ clif_initialstatus(sd);
+
+ if (sd->sc.option&OPTION_FALCON)
+ clif_status_load(&sd->bl, SI_FALCON, 1);
+
+ if (sd->sc.option&OPTION_RIDING)
+ clif_status_load(&sd->bl, SI_RIDING, 1);
+ else if (sd->sc.option&OPTION_WUGRIDER)
+ clif_status_load(&sd->bl, SI_WUGRIDER, 1);
+
+ if(sd->status.manner < 0)
+ sc_start(&sd->bl,SC_NOCHAT,100,0,0);
+
+ //Auron reported that This skill only triggers when you logon on the map o.O [Skotlex]
+ if ((lv = pc_checkskill(sd,SG_KNOWLEDGE)) > 0) {
+ if(sd->bl.m == sd->feel_map[0].m
+ || sd->bl.m == sd->feel_map[1].m
+ || sd->bl.m == sd->feel_map[2].m)
+ sc_start(&sd->bl, SC_KNOWLEDGE, 100, lv, skill_get_time(SG_KNOWLEDGE, lv));
+ }
+
+ if(sd->pd && sd->pd->pet.intimate > 900)
+ clif_pet_emotion(sd->pd,(sd->pd->pet.class_ - 100)*100 + 50 + pet_hungry_val(sd->pd));
+
+ if(merc_is_hom_active(sd->hd))
+ merc_hom_init_timers(sd->hd);
+
+ if (night_flag && map[sd->bl.m].flag.nightenabled) {
+ sd->state.night = 1;
+ clif_status_load(&sd->bl, SI_NIGHT, 1);
+ }
+
+ // Notify everyone that this char logged in [Skotlex].
+ map_foreachpc(clif_friendslist_toggle_sub, sd->status.account_id, sd->status.char_id, 1);
+
+ //Login Event
+ npc_script_event(sd, NPCE_LOGIN);
+ } else {
+ //For some reason the client "loses" these on warp/map-change.
+ clif_updatestatus(sd,SP_STR);
+ clif_updatestatus(sd,SP_AGI);
+ clif_updatestatus(sd,SP_VIT);
+ clif_updatestatus(sd,SP_INT);
+ clif_updatestatus(sd,SP_DEX);
+ clif_updatestatus(sd,SP_LUK);
+
+ // abort currently running script
+ sd->state.using_fake_npc = 0;
+ sd->state.menu_or_input = 0;
+ sd->npc_menu = 0;
+
+ if(sd->npc_id)
+ npc_event_dequeue(sd);
+ }
+
+ if( sd->state.changemap )
+ {// restore information that gets lost on map-change
#if PACKETVER >= 20070918
- clif_partyinvitationstate(sd);
- clif_equipcheckbox(sd);
+ clif_partyinvitationstate(sd);
+ clif_equipcheckbox(sd);
#endif
- if ((battle_config.bg_flee_penalty != 100 || battle_config.gvg_flee_penalty != 100) &&
- (map_flag_gvg(sd->state.pmap) || map_flag_gvg(sd->bl.m) || map[sd->state.pmap].flag.battleground || map[sd->bl.m].flag.battleground))
- status_calc_bl(&sd->bl, SCB_FLEE); //Refresh flee penalty
-
- if (night_flag && map[sd->bl.m].flag.nightenabled) {
- //Display night.
- if (!sd->state.night) {
- sd->state.night = 1;
- clif_status_load(&sd->bl, SI_NIGHT, 1);
- }
- } else if (sd->state.night) {
- //Clear night display.
- sd->state.night = 0;
- clif_status_load(&sd->bl, SI_NIGHT, 0);
- }
-
- if (map[sd->bl.m].flag.battleground) {
- clif_map_type(sd, MAPTYPE_BATTLEFIELD); // Battleground Mode
- if (map[sd->bl.m].flag.battleground == 2)
- clif_bg_updatescore_single(sd);
- }
-
- if (map[sd->bl.m].flag.allowks && !map_flag_ks(sd->bl.m)) {
- char output[128];
- sprintf(output, "[ Kill Steal Protection Disable. KS is allowed in this map ]");
- clif_broadcast(&sd->bl, output, strlen(output) + 1, 0x10, SELF);
- }
-
- map_iwall_get(sd); // Updates Walls Info on this Map to Client
- sd->state.changemap = false;
- }
-
- mail_clear(sd);
-
- /* Guild Aura Init */
- if (sd->state.gmaster_flag) {
- guild_guildaura_refresh(sd,GD_LEADERSHIP,guild_checkskill(sd->state.gmaster_flag,GD_LEADERSHIP));
- guild_guildaura_refresh(sd,GD_GLORYWOUNDS,guild_checkskill(sd->state.gmaster_flag,GD_GLORYWOUNDS));
- guild_guildaura_refresh(sd,GD_SOULCOLD,guild_checkskill(sd->state.gmaster_flag,GD_SOULCOLD));
- guild_guildaura_refresh(sd,GD_HAWKEYES,guild_checkskill(sd->state.gmaster_flag,GD_HAWKEYES));
- }
-
- if (sd->state.vending) { /* show we have a vending */
- clif_openvending(sd,sd->bl.id,sd->vending);
- clif_showvendingboard(&sd->bl,sd->message,0);
- }
-
- if (map[sd->bl.m].flag.loadevent) // Lance
- npc_script_event(sd, NPCE_LOADMAP);
-
- if (pc_checkskill(sd, SG_DEVIL) && !pc_nextjobexp(sd))
- clif_status_load(&sd->bl, SI_DEVIL, 1); //blindness [Komurka]
-
- if (sd->sc.opt2) //Client loses these on warp.
- clif_changeoption(&sd->bl);
-
- clif_weather_check(sd);
-
- // For automatic triggering of NPCs after map loading (so you don't need to walk 1 step first)
- 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;
-
- /* it broke at some point (e.g. during a crash), so we make it visibly dead again. */
- if (!sd->status.hp && !pc_isdead(sd) && status_isdead(&sd->bl))
- pc_setdead(sd);
-
- // If player is dead, and is spawned (such as @refresh) send death packet. [Valaris]
- if (pc_isdead(sd))
- clif_clearunit_area(&sd->bl, CLR_DEAD);
- else {
- skill_usave_trigger(sd);
- clif_changed_dir(&sd->bl, SELF);
- }
-
- // Trigger skill effects if you appear standing on them
- if (!battle_config.pc_invincible_time)
- skill_unit_move(&sd->bl,gettick(),1);
+ if( (battle_config.bg_flee_penalty != 100 || battle_config.gvg_flee_penalty != 100) &&
+ (map_flag_gvg(sd->state.pmap) || map_flag_gvg(sd->bl.m) || map[sd->state.pmap].flag.battleground || map[sd->bl.m].flag.battleground) )
+ status_calc_bl(&sd->bl, SCB_FLEE); //Refresh flee penalty
+
+ if( night_flag && map[sd->bl.m].flag.nightenabled )
+ { //Display night.
+ if( !sd->state.night )
+ {
+ sd->state.night = 1;
+ clif_status_load(&sd->bl, SI_NIGHT, 1);
+ }
+ }
+ else if( sd->state.night )
+ { //Clear night display.
+ sd->state.night = 0;
+ clif_status_load(&sd->bl, SI_NIGHT, 0);
+ }
+
+ if( map[sd->bl.m].flag.battleground )
+ {
+ clif_map_type(sd, MAPTYPE_BATTLEFIELD); // Battleground Mode
+ if( map[sd->bl.m].flag.battleground == 2 )
+ clif_bg_updatescore_single(sd);
+ }
+
+ if( map[sd->bl.m].flag.allowks && !map_flag_ks(sd->bl.m) )
+ {
+ char output[128];
+ sprintf(output, "[ Kill Steal Protection Disable. KS is allowed in this map ]");
+ clif_broadcast(&sd->bl, output, strlen(output) + 1, 0x10, SELF);
+ }
+
+ map_iwall_get(sd); // Updates Walls Info on this Map to Client
+ sd->state.changemap = false;
+ }
+
+ mail_clear(sd);
+
+ /* Guild Aura Init */
+ if( sd->state.gmaster_flag ) {
+ guild_guildaura_refresh(sd,GD_LEADERSHIP,guild_checkskill(sd->state.gmaster_flag,GD_LEADERSHIP));
+ guild_guildaura_refresh(sd,GD_GLORYWOUNDS,guild_checkskill(sd->state.gmaster_flag,GD_GLORYWOUNDS));
+ guild_guildaura_refresh(sd,GD_SOULCOLD,guild_checkskill(sd->state.gmaster_flag,GD_SOULCOLD));
+ guild_guildaura_refresh(sd,GD_HAWKEYES,guild_checkskill(sd->state.gmaster_flag,GD_HAWKEYES));
+ }
+
+ if( sd->state.vending ) { /* show we have a vending */
+ clif_openvending(sd,sd->bl.id,sd->vending);
+ clif_showvendingboard(&sd->bl,sd->message,0);
+ }
+
+ if(map[sd->bl.m].flag.loadevent) // Lance
+ npc_script_event(sd, NPCE_LOADMAP);
+
+ if (pc_checkskill(sd, SG_DEVIL) && !pc_nextjobexp(sd))
+ clif_status_load(&sd->bl, SI_DEVIL, 1); //blindness [Komurka]
+
+ if (sd->sc.opt2) //Client loses these on warp.
+ clif_changeoption(&sd->bl);
+
+ clif_weather_check(sd);
+
+ // For automatic triggering of NPCs after map loading (so you don't need to walk 1 step first)
+ 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;
+
+ /* it broke at some point (e.g. during a crash), so we make it visibly dead again. */
+ if( !sd->status.hp && !pc_isdead(sd) && status_isdead(&sd->bl) )
+ pc_setdead(sd);
+
+ // If player is dead, and is spawned (such as @refresh) send death packet. [Valaris]
+ if(pc_isdead(sd))
+ clif_clearunit_area(&sd->bl, CLR_DEAD);
+ else {
+ skill_usave_trigger(sd);
+ clif_changed_dir(&sd->bl, SELF);
+ }
+
+// Trigger skill effects if you appear standing on them
+ if(!battle_config.pc_invincible_time)
+ skill_unit_move(&sd->bl,gettick(),1);
}
/// Server's tick (ZC_NOTIFY_TIME).
/// 007f <time>.L
-void clif_notify_time(struct map_session_data *sd, unsigned long time)
+void clif_notify_time(struct map_session_data* sd, unsigned long time)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x7f));
- WFIFOW(fd,0) = 0x7f;
- WFIFOL(fd,2) = time;
- WFIFOSET(fd,packet_len(0x7f));
+ WFIFOHEAD(fd,packet_len(0x7f));
+ WFIFOW(fd,0) = 0x7f;
+ WFIFOL(fd,2) = time;
+ WFIFOSET(fd,packet_len(0x7f));
}
@@ -9320,9 +9430,9 @@ void clif_notify_time(struct map_session_data *sd, unsigned long time)
/// There are various variants of this packet, some of them have padding between fields.
void clif_parse_TickSend(int fd, struct map_session_data *sd)
{
- sd->client_tick = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
+ sd->client_tick = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
- clif_notify_time(sd, gettick());
+ clif_notify_time(sd, gettick());
}
@@ -9330,85 +9440,83 @@ void clif_parse_TickSend(int fd, struct map_session_data *sd)
/// 02b9 { <is skill>.B <id>.L <count>.W }*27 (ZC_SHORTCUT_KEY_LIST)
/// 07d9 { <is skill>.B <id>.L <count>.W }*36 (ZC_SHORTCUT_KEY_LIST_V2, PACKETVER >= 20090603)
/// 07d9 { <is skill>.B <id>.L <count>.W }*38 (ZC_SHORTCUT_KEY_LIST_V2, PACKETVER >= 20090617)
-void clif_hotkeys_send(struct map_session_data *sd)
-{
+void clif_hotkeys_send(struct map_session_data *sd) {
#ifdef HOTKEY_SAVING
- const int fd = sd->fd;
- int i;
+ const int fd = sd->fd;
+ int i;
#if PACKETVER < 20090603
- const int cmd = 0x2b9;
+ const int cmd = 0x2b9;
#else
- const int cmd = 0x7d9;
+ const int cmd = 0x7d9;
#endif
- if (!fd) return;
- WFIFOHEAD(fd, 2+MAX_HOTKEYS*7);
- WFIFOW(fd, 0) = cmd;
- for (i = 0; i < MAX_HOTKEYS; i++) {
- WFIFOB(fd, 2 + 0 + i * 7) = sd->status.hotkeys[i].type; // type: 0: item, 1: skill
- WFIFOL(fd, 2 + 1 + i * 7) = sd->status.hotkeys[i].id; // item or skill ID
- WFIFOW(fd, 2 + 5 + i * 7) = sd->status.hotkeys[i].lv; // skill level
- }
- WFIFOSET(fd, packet_len(cmd));
+ if (!fd) return;
+ WFIFOHEAD(fd, 2+MAX_HOTKEYS*7);
+ WFIFOW(fd, 0) = cmd;
+ for(i = 0; i < MAX_HOTKEYS; i++) {
+ WFIFOB(fd, 2 + 0 + i * 7) = sd->status.hotkeys[i].type; // type: 0: item, 1: skill
+ WFIFOL(fd, 2 + 1 + i * 7) = sd->status.hotkeys[i].id; // item or skill ID
+ WFIFOW(fd, 2 + 5 + i * 7) = sd->status.hotkeys[i].lv; // skill level
+ }
+ WFIFOSET(fd, packet_len(cmd));
#endif
}
/// Request to update a position on the hotkey bar (CZ_SHORTCUT_KEY_CHANGE).
/// 02ba <index>.W <is skill>.B <id>.L <count>.W
-void clif_parse_Hotkey(int fd, struct map_session_data *sd)
-{
+void clif_parse_Hotkey(int fd, struct map_session_data *sd) {
#ifdef HOTKEY_SAVING
- unsigned short idx;
- int cmd;
+ unsigned short idx;
+ int cmd;
- cmd = RFIFOW(fd, 0);
- idx = RFIFOW(fd, packet_db[sd->packet_ver][cmd].pos[0]);
- if (idx >= MAX_HOTKEYS) return;
+ cmd = RFIFOW(fd, 0);
+ idx = RFIFOW(fd, packet_db[sd->packet_ver][cmd].pos[0]);
+ if (idx >= MAX_HOTKEYS) return;
- sd->status.hotkeys[idx].type = RFIFOB(fd, packet_db[sd->packet_ver][cmd].pos[1]);
- sd->status.hotkeys[idx].id = RFIFOL(fd, packet_db[sd->packet_ver][cmd].pos[2]);
- sd->status.hotkeys[idx].lv = RFIFOW(fd, packet_db[sd->packet_ver][cmd].pos[3]);
+ sd->status.hotkeys[idx].type = RFIFOB(fd, packet_db[sd->packet_ver][cmd].pos[1]);
+ sd->status.hotkeys[idx].id = RFIFOL(fd, packet_db[sd->packet_ver][cmd].pos[2]);
+ sd->status.hotkeys[idx].lv = RFIFOW(fd, packet_db[sd->packet_ver][cmd].pos[3]);
#endif
}
/// Displays cast-like progress bar (ZC_PROGRESS).
/// 02f0 <color>.L <time>.L
-void clif_progressbar(struct map_session_data *sd, unsigned long color, unsigned int second)
+void clif_progressbar(struct map_session_data * sd, unsigned long color, unsigned int second)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x2f0));
- WFIFOW(fd,0) = 0x2f0;
- WFIFOL(fd,2) = color;
- WFIFOL(fd,6) = second;
- WFIFOSET(fd,packet_len(0x2f0));
+ WFIFOHEAD(fd,packet_len(0x2f0));
+ WFIFOW(fd,0) = 0x2f0;
+ WFIFOL(fd,2) = color;
+ WFIFOL(fd,6) = second;
+ WFIFOSET(fd,packet_len(0x2f0));
}
/// Removes an ongoing progress bar (ZC_PROGRESS_CANCEL).
/// 02f2
-void clif_progressbar_abort(struct map_session_data *sd)
+void clif_progressbar_abort(struct map_session_data * sd)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x2f2));
- WFIFOW(fd,0) = 0x2f2;
- WFIFOSET(fd,packet_len(0x2f2));
+ WFIFOHEAD(fd,packet_len(0x2f2));
+ WFIFOW(fd,0) = 0x2f2;
+ WFIFOSET(fd,packet_len(0x2f2));
}
/// Notification from the client, that the progress bar has reached 100% (CZ_PROGRESS).
/// 02f1
-void clif_parse_progressbar(int fd, struct map_session_data *sd)
+void clif_parse_progressbar(int fd, struct map_session_data * sd)
{
- int npc_id = sd->progressbar.npc_id;
+ int npc_id = sd->progressbar.npc_id;
- if (gettick() < sd->progressbar.timeout && sd->st)
- sd->st->state = END;
+ if( gettick() < sd->progressbar.timeout && sd->st )
+ sd->st->state = END;
- sd->progressbar.npc_id = sd->progressbar.timeout = 0;
- npc_scriptcont(sd, npc_id);
+ sd->progressbar.npc_id = sd->progressbar.timeout = 0;
+ npc_scriptcont(sd, npc_id);
}
@@ -9418,31 +9526,31 @@ void clif_parse_progressbar(int fd, struct map_session_data *sd)
/// There are various variants of this packet, some of them have padding between fields.
void clif_parse_WalkToXY(int fd, struct map_session_data *sd)
{
- short x, y;
+ short x, y;
- if (pc_isdead(sd)) {
- clif_clearunit_area(&sd->bl, CLR_DEAD);
- return;
- }
+ if (pc_isdead(sd)) {
+ clif_clearunit_area(&sd->bl, CLR_DEAD);
+ return;
+ }
- if (sd->sc.opt1 && (sd->sc.opt1 == OPT1_STONEWAIT || sd->sc.opt1 == OPT1_BURNING))
- ; //You CAN walk on this OPT1 value.
- else if (sd->progressbar.npc_id)
- clif_progressbar_abort(sd);
- else if (pc_cant_act(sd))
- return;
+ if (sd->sc.opt1 && ( sd->sc.opt1 == OPT1_STONEWAIT || sd->sc.opt1 == OPT1_BURNING ))
+ ; //You CAN walk on this OPT1 value.
+ else if( sd->progressbar.npc_id )
+ clif_progressbar_abort(sd);
+ else if (pc_cant_act(sd))
+ return;
- if (sd->sc.data[SC_RUN] || sd->sc.data[SC_WUGDASH])
- return;
+ if(sd->sc.data[SC_RUN] || sd->sc.data[SC_WUGDASH])
+ return;
- pc_delinvincibletimer(sd);
+ pc_delinvincibletimer(sd);
- RFIFOPOS(fd, packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0], &x, &y, NULL);
+ RFIFOPOS(fd, packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0], &x, &y, NULL);
- //Set last idle time... [Skotlex]
- sd->idletime = last_tick;
+ //Set last idle time... [Skotlex]
+ sd->idletime = last_tick;
- unit_walktoxy(&sd->bl, x, y, 4);
+ unit_walktoxy(&sd->bl, x, y, 4);
}
@@ -9452,14 +9560,14 @@ void clif_parse_WalkToXY(int fd, struct map_session_data *sd)
/// 0 = disconnect (quit)
/// 1 = cannot disconnect (wait 10 seconds)
/// ? = ignored
-void clif_disconnect_ack(struct map_session_data *sd, short result)
+void clif_disconnect_ack(struct map_session_data* sd, short result)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x18b));
- WFIFOW(fd,0) = 0x18b;
- WFIFOW(fd,2) = result;
- WFIFOSET(fd,packet_len(0x18b));
+ WFIFOHEAD(fd,packet_len(0x18b));
+ WFIFOW(fd,0) = 0x18b;
+ WFIFOW(fd,2) = result;
+ WFIFOSET(fd,packet_len(0x18b));
}
@@ -9469,14 +9577,15 @@ void clif_disconnect_ack(struct map_session_data *sd, short result)
/// 0 = quit
void clif_parse_QuitGame(int fd, struct map_session_data *sd)
{
- /* Rovert's prevent logout option fixed [Valaris] */
- if (!sd->sc.data[SC_CLOAKING] && !sd->sc.data[SC_HIDING] && !sd->sc.data[SC_CHASEWALK] && !sd->sc.data[SC_CLOAKINGEXCEED] &&
- (!battle_config.prevent_logout || DIFF_TICK(gettick(), sd->canlog_tick) > battle_config.prevent_logout)) {
- set_eof(fd);
- clif_disconnect_ack(sd, 0);
- } else {
- clif_disconnect_ack(sd, 1);
- }
+ /* Rovert's prevent logout option fixed [Valaris] */
+ if( !sd->sc.data[SC_CLOAKING] && !sd->sc.data[SC_HIDING] && !sd->sc.data[SC_CHASEWALK] && !sd->sc.data[SC_CLOAKINGEXCEED] &&
+ (!battle_config.prevent_logout || DIFF_TICK(gettick(), sd->canlog_tick) > battle_config.prevent_logout) )
+ {
+ set_eof(fd);
+ clif_disconnect_ack(sd, 0);
+ } else {
+ clif_disconnect_ack(sd, 1);
+ }
}
@@ -9486,106 +9595,106 @@ void clif_parse_QuitGame(int fd, struct map_session_data *sd)
/// There are various variants of this packet, some of them have padding between fields.
void clif_parse_GetCharNameRequest(int fd, struct map_session_data *sd)
{
- int id = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
- struct block_list *bl;
- //struct status_change *sc;
-
- if (id < 0 && -id == sd->bl.id) // for disguises [Valaris]
- id = sd->bl.id;
-
- bl = map_id2bl(id);
- if (bl == NULL)
- return; // Lagged clients could request names of already gone mobs/players. [Skotlex]
-
- if (sd->bl.m != bl->m || !check_distance_bl(&sd->bl, bl, AREA_SIZE))
- return; // Block namerequests past view range
-
- // 'see people in GM hide' cheat detection
- /* disabled due to false positives (network lag + request name of char that's about to hide = race condition)
- sc = status_get_sc(bl);
- if (sc && sc->option&OPTION_INVISIBLE && !disguised(bl) &&
- bl->type != BL_NPC && //Skip hidden NPCs which can be seen using Maya Purple
- pc_get_group_level(sd) < battle_config.hack_info_GM_level
- ) {
- char gm_msg[256];
- sprintf(gm_msg, "Hack on NameRequest: character '%s' (account: %d) requested the name of an invisible target (id: %d).\n", sd->status.name, sd->status.account_id, id);
- ShowWarning(gm_msg);
- // information is sent to all online GMs
- intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, gm_msg);
- return;
- }
- */
+ int id = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
+ struct block_list* bl;
+ //struct status_change *sc;
- clif_charnameack(fd, bl);
-}
+ if( id < 0 && -id == sd->bl.id ) // for disguises [Valaris]
+ id = sd->bl.id;
+ bl = map_id2bl(id);
+ if( bl == NULL )
+ return; // Lagged clients could request names of already gone mobs/players. [Skotlex]
-/// Validates and processes global messages
-/// 008c <packet len>.W <text>.?B (<name> : <message>) 00 (CZ_REQUEST_CHAT)
-/// There are various variants of this packet.
-void clif_parse_GlobalMessage(int fd, struct map_session_data *sd)
-{
- const char *text = (char *)RFIFOP(fd,4);
- int textlen = RFIFOW(fd,2) - 4;
-
- char *name, *message, *fakename = NULL;
- int namelen, messagelen;
+ if( sd->bl.m != bl->m || !check_distance_bl(&sd->bl, bl, AREA_SIZE) )
+ return; // Block namerequests past view range
- bool is_fake;
+ // 'see people in GM hide' cheat detection
+ /* disabled due to false positives (network lag + request name of char that's about to hide = race condition)
+ sc = status_get_sc(bl);
+ if (sc && sc->option&OPTION_INVISIBLE && !disguised(bl) &&
+ bl->type != BL_NPC && //Skip hidden NPCs which can be seen using Maya Purple
+ pc_get_group_level(sd) < battle_config.hack_info_GM_level
+ ) {
+ char gm_msg[256];
+ sprintf(gm_msg, "Hack on NameRequest: character '%s' (account: %d) requested the name of an invisible target (id: %d).\n", sd->status.name, sd->status.account_id, id);
+ ShowWarning(gm_msg);
+ // information is sent to all online GMs
+ intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, gm_msg);
+ return;
+ }
+ */
- // validate packet and retrieve name and message
- if (!clif_process_message(sd, 0, &name, &namelen, &message, &messagelen))
- return;
-
- if (is_atcommand(fd, sd, message, 1))
- return;
+ clif_charnameack(fd, bl);
+}
- if (sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT))
- return;
- if (battle_config.min_chat_delay) {
- //[Skotlex]
- if (DIFF_TICK(sd->cantalk_tick, gettick()) > 0)
- return;
- sd->cantalk_tick = gettick() + battle_config.min_chat_delay;
- }
- /**
- * Fake Name Design by FatalEror (bug report #9)
- **/
- if ((is_fake = (sd->fakename[0]))) {
- fakename = (char *) aMalloc(strlen(sd->fakename)+messagelen+3);
- strcpy(fakename, sd->fakename);
- strcat(fakename, " : ");
- strcat(fakename, message);
- textlen = strlen(fakename) + 1;
- }
- // send message to others (using the send buffer for temp. storage)
- WFIFOHEAD(fd, 8 + textlen);
- WFIFOW(fd,0) = 0x8d;
- WFIFOW(fd,2) = 8 + textlen;
- WFIFOL(fd,4) = sd->bl.id;
- safestrncpy((char *)WFIFOP(fd,8), is_fake ? fakename : text, textlen);
- //FIXME: chat has range of 9 only
- clif_send(WFIFOP(fd,0), WFIFOW(fd,2), &sd->bl, sd->chatID ? CHAT_WOS : AREA_CHAT_WOC);
-
- // send back message to the speaker
- if (is_fake) {
- WFIFOW(fd,0) = 0x8e;
- WFIFOW(fd,2) = textlen + 4;
- safestrncpy((char *)WFIFOP(fd,4), fakename, textlen);
- aFree(fakename);
- } else {
- memcpy(WFIFOP(fd,0), RFIFOP(fd,0), RFIFOW(fd,2));
- WFIFOW(fd,0) = 0x8e;
- }
- WFIFOSET(fd, WFIFOW(fd,2));
+/// Validates and processes global messages
+/// 008c <packet len>.W <text>.?B (<name> : <message>) 00 (CZ_REQUEST_CHAT)
+/// There are various variants of this packet.
+void clif_parse_GlobalMessage(int fd, struct map_session_data* sd)
+{
+ const char* text = (char*)RFIFOP(fd,4);
+ int textlen = RFIFOW(fd,2) - 4;
+
+ char *name, *message, *fakename = NULL;
+ int namelen, messagelen;
+
+ bool is_fake;
+
+ // validate packet and retrieve name and message
+ if( !clif_process_message(sd, 0, &name, &namelen, &message, &messagelen) )
+ return;
+
+ if( is_atcommand(fd, sd, message, 1) )
+ return;
+
+ if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) )
+ return;
+
+ if( battle_config.min_chat_delay )
+ { //[Skotlex]
+ if (DIFF_TICK(sd->cantalk_tick, gettick()) > 0)
+ return;
+ sd->cantalk_tick = gettick() + battle_config.min_chat_delay;
+ }
+ /**
+ * Fake Name Design by FatalEror (bug report #9)
+ **/
+ if( ( is_fake = ( sd->fakename[0] ) ) ) {
+ fakename = (char*) aMalloc(strlen(sd->fakename)+messagelen+3);
+ strcpy(fakename, sd->fakename);
+ strcat(fakename, " : ");
+ strcat(fakename, message);
+ textlen = strlen(fakename) + 1;
+ }
+ // send message to others (using the send buffer for temp. storage)
+ WFIFOHEAD(fd, 8 + textlen);
+ WFIFOW(fd,0) = 0x8d;
+ WFIFOW(fd,2) = 8 + textlen;
+ WFIFOL(fd,4) = sd->bl.id;
+ safestrncpy((char*)WFIFOP(fd,8), is_fake ? fakename : text, textlen);
+ //FIXME: chat has range of 9 only
+ clif_send(WFIFOP(fd,0), WFIFOW(fd,2), &sd->bl, sd->chatID ? CHAT_WOS : AREA_CHAT_WOC);
+
+ // send back message to the speaker
+ if( is_fake ) {
+ WFIFOW(fd,0) = 0x8e;
+ WFIFOW(fd,2) = textlen + 4;
+ safestrncpy((char*)WFIFOP(fd,4), fakename, textlen);
+ aFree(fakename);
+ } else {
+ memcpy(WFIFOP(fd,0), RFIFOP(fd,0), RFIFOW(fd,2));
+ WFIFOW(fd,0) = 0x8e;
+ }
+ WFIFOSET(fd, WFIFOW(fd,2));
#ifdef PCRE_SUPPORT
- // trigger listening npcs
- map_foreachinrange(npc_chat_sub, &sd->bl, AREA_SIZE, BL_NPC, text, textlen, &sd->bl);
+ // trigger listening npcs
+ map_foreachinrange(npc_chat_sub, &sd->bl, AREA_SIZE, BL_NPC, text, textlen, &sd->bl);
#endif
- // Chat logging type 'O' / Global Chat
- log_chat(LOG_CHAT_GLOBAL, 0, sd->status.char_id, sd->status.account_id, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y, NULL, message);
+ // Chat logging type 'O' / Global Chat
+ log_chat(LOG_CHAT_GLOBAL, 0, sd->status.char_id, sd->status.account_id, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y, NULL, message);
}
@@ -9594,13 +9703,13 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data *sd)
/// 0140 <map name>.16B <x>.W <y>.W
void clif_parse_MapMove(int fd, struct map_session_data *sd)
{
- char command[MAP_NAME_LENGTH_EXT+25];
- char *map_name;
+ char command[MAP_NAME_LENGTH_EXT+25];
+ char* map_name;
- map_name = (char *)RFIFOP(fd,2);
- map_name[MAP_NAME_LENGTH_EXT-1]='\0';
- sprintf(command, "%cmapmove %s %d %d", atcommand_symbol, map_name, RFIFOW(fd,18), RFIFOW(fd,20));
- is_atcommand(fd, sd, command, 1);
+ map_name = (char*)RFIFOP(fd,2);
+ map_name[MAP_NAME_LENGTH_EXT-1]='\0';
+ sprintf(command, "%cmapmove %s %d %d", atcommand_symbol, map_name, RFIFOW(fd,18), RFIFOW(fd,20));
+ is_atcommand(fd, sd, command, 1);
}
@@ -9621,20 +9730,20 @@ void clif_parse_MapMove(int fd, struct map_session_data *sd)
/// 7 = northeast
void clif_changed_dir(struct block_list *bl, enum send_target target)
{
- unsigned char buf[64];
+ unsigned char buf[64];
- WBUFW(buf,0) = 0x9c;
- WBUFL(buf,2) = bl->id;
- WBUFW(buf,6) = bl->type==BL_PC?((TBL_PC *)bl)->head_dir:0;
- WBUFB(buf,8) = unit_getdir(bl);
+ WBUFW(buf,0) = 0x9c;
+ WBUFL(buf,2) = bl->id;
+ WBUFW(buf,6) = bl->type==BL_PC?((TBL_PC*)bl)->head_dir:0;
+ WBUFB(buf,8) = unit_getdir(bl);
- clif_send(buf, packet_len(0x9c), bl, target);
+ clif_send(buf, packet_len(0x9c), bl, target);
- if (disguised(bl)) {
- WBUFL(buf,2) = -bl->id;
- WBUFW(buf,6) = 0;
- clif_send(buf, packet_len(0x9c), bl, SELF);
- }
+ if (disguised(bl)) {
+ WBUFL(buf,2) = -bl->id;
+ WBUFW(buf,6) = 0;
+ clif_send(buf, packet_len(0x9c), bl, SELF);
+ }
}
@@ -9644,13 +9753,13 @@ void clif_changed_dir(struct block_list *bl, enum send_target target)
/// There are various variants of this packet, some of them have padding between fields.
void clif_parse_ChangeDir(int fd, struct map_session_data *sd)
{
- unsigned char headdir, dir;
+ unsigned char headdir, dir;
- headdir = RFIFOB(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
- dir = RFIFOB(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]);
- pc_setdir(sd, dir, headdir);
+ headdir = RFIFOB(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
+ dir = RFIFOB(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]);
+ pc_setdir(sd, dir, headdir);
- clif_changed_dir(&sd->bl, AREA_WOS);
+ clif_changed_dir(&sd->bl, AREA_WOS);
}
@@ -9660,42 +9769,42 @@ void clif_parse_ChangeDir(int fd, struct map_session_data *sd)
/// @see enum emotion_type
void clif_parse_Emotion(int fd, struct map_session_data *sd)
{
- int emoticon = RFIFOB(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
+ int emoticon = RFIFOB(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
- if (battle_config.basic_skill_check == 0 || pc_checkskill(sd, NV_BASIC) >= 2) {
- if (emoticon == E_MUTE) {// prevent use of the mute emote [Valaris]
- clif_skill_fail(sd, 1, USESKILL_FAIL_LEVEL, 1);
- return;
- }
- // fix flood of emotion icon (ro-proxy): flood only the hacker player
- if (sd->emotionlasttime + 1 >= time(NULL)) { // not more than 1 per second
- sd->emotionlasttime = time(NULL);
- clif_skill_fail(sd, 1, USESKILL_FAIL_LEVEL, 1);
- return;
- }
- sd->emotionlasttime = time(NULL);
+ if (battle_config.basic_skill_check == 0 || pc_checkskill(sd, NV_BASIC) >= 2) {
+ if (emoticon == E_MUTE) {// prevent use of the mute emote [Valaris]
+ clif_skill_fail(sd, 1, USESKILL_FAIL_LEVEL, 1);
+ return;
+ }
+ // fix flood of emotion icon (ro-proxy): flood only the hacker player
+ if (sd->emotionlasttime + 1 >= time(NULL)) { // not more than 1 per second
+ sd->emotionlasttime = time(NULL);
+ clif_skill_fail(sd, 1, USESKILL_FAIL_LEVEL, 1);
+ return;
+ }
+ sd->emotionlasttime = time(NULL);
- if (battle_config.client_reshuffle_dice && emoticon>=E_DICE1 && emoticon<=E_DICE6) {
- // re-roll dice
- emoticon = rnd()%6+E_DICE1;
- }
+ if(battle_config.client_reshuffle_dice && emoticon>=E_DICE1 && emoticon<=E_DICE6)
+ {// re-roll dice
+ emoticon = rnd()%6+E_DICE1;
+ }
- clif_emotion(&sd->bl, emoticon);
- } else
- clif_skill_fail(sd, 1, USESKILL_FAIL_LEVEL, 1);
+ clif_emotion(&sd->bl, emoticon);
+ } else
+ clif_skill_fail(sd, 1, USESKILL_FAIL_LEVEL, 1);
}
/// Amount of currently online players, reply to /w /who (ZC_USER_COUNT).
/// 00c2 <count>.L
-void clif_user_count(struct map_session_data *sd, int count)
+void clif_user_count(struct map_session_data* sd, int count)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0xc2));
- WFIFOW(fd,0) = 0xc2;
- WFIFOL(fd,2) = count;
- WFIFOSET(fd,packet_len(0xc2));
+ WFIFOHEAD(fd,packet_len(0xc2));
+ WFIFOW(fd,0) = 0xc2;
+ WFIFOL(fd,2) = count;
+ WFIFOSET(fd,packet_len(0xc2));
}
@@ -9704,92 +9813,93 @@ void clif_user_count(struct map_session_data *sd, int count)
/// 00c1
void clif_parse_HowManyConnections(int fd, struct map_session_data *sd)
{
- clif_user_count(sd, map_getusers());
+ clif_user_count(sd, map_getusers());
}
void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, int target_id, unsigned int tick)
{
- if (pc_isdead(sd)) {
- clif_clearunit_area(&sd->bl, CLR_DEAD);
- return;
- }
-
- if (sd->sc.count &&
- (sd->sc.data[SC_TRICKDEAD] ||
- sd->sc.data[SC_AUTOCOUNTER] ||
- sd->sc.data[SC_BLADESTOP] ||
- sd->sc.data[SC__MANHOLE] ||
- sd->sc.data[SC_CURSEDCIRCLE_ATKER] ||
- sd->sc.data[SC_CURSEDCIRCLE_TARGET]))
- return;
-
- pc_stop_walking(sd, 1);
- pc_stop_attack(sd);
-
- if (target_id<0 && -target_id == sd->bl.id) // for disguises [Valaris]
- target_id = sd->bl.id;
-
- switch (action_type) {
- case 0x00: // once attack
- case 0x07: // continuous attack
-
- if (pc_cant_act(sd) || sd->sc.option&OPTION_HIDE)
- return;
-
- if (sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER))
- return;
-
- if (sd->sc.data[SC_BASILICA] || sd->sc.data[SC__SHADOWFORM])
- return;
-
- if (!battle_config.sdelay_attack_enable && pc_checkskill(sd, SA_FREECAST) <= 0) {
- if (DIFF_TICK(tick, sd->ud.canact_tick) < 0) {
- clif_skill_fail(sd, 1, USESKILL_FAIL_SKILLINTERVAL, 0);
- return;
- }
- }
-
- pc_delinvincibletimer(sd);
- sd->idletime = last_tick;
- unit_attack(&sd->bl, target_id, action_type != 0);
- break;
- case 0x02: // sitdown
- if (battle_config.basic_skill_check && pc_checkskill(sd, NV_BASIC) < 3) {
- clif_skill_fail(sd, 1, USESKILL_FAIL_LEVEL, 2);
- break;
- }
-
- if (pc_issit(sd)) {
- //Bugged client? Just refresh them.
- clif_sitting(&sd->bl);
- return;
- }
-
- if (sd->ud.skilltimer != INVALID_TIMER || (sd->sc.opt1 && sd->sc.opt1 != OPT1_BURNING))
- break;
-
- if (sd->sc.count && (
- sd->sc.data[SC_DANCING] ||
- (sd->sc.data[SC_GRAVITATION] && sd->sc.data[SC_GRAVITATION]->val3 == BCT_SELF)
- )) //No sitting during these states either.
- break;
-
- pc_setsit(sd);
- skill_sit(sd,1);
- clif_sitting(&sd->bl);
- break;
- case 0x03: // standup
- if (!pc_issit(sd)) {
- //Bugged client? Just refresh them.
- clif_standing(&sd->bl);
- return;
- }
- pc_setstand(sd);
- skill_sit(sd,0);
- clif_standing(&sd->bl);
- break;
- }
+ if (pc_isdead(sd)) {
+ clif_clearunit_area(&sd->bl, CLR_DEAD);
+ return;
+ }
+
+ if (sd->sc.count &&
+ (sd->sc.data[SC_TRICKDEAD] ||
+ sd->sc.data[SC_AUTOCOUNTER] ||
+ sd->sc.data[SC_BLADESTOP] ||
+ sd->sc.data[SC__MANHOLE] ||
+ sd->sc.data[SC_CURSEDCIRCLE_ATKER] ||
+ sd->sc.data[SC_CURSEDCIRCLE_TARGET] ))
+ return;
+
+ pc_stop_walking(sd, 1);
+ pc_stop_attack(sd);
+
+ if(target_id<0 && -target_id == sd->bl.id) // for disguises [Valaris]
+ target_id = sd->bl.id;
+
+ switch(action_type)
+ {
+ case 0x00: // once attack
+ case 0x07: // continuous attack
+
+ if( pc_cant_act(sd) || sd->sc.option&OPTION_HIDE )
+ return;
+
+ if( sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER) )
+ return;
+
+ if( sd->sc.data[SC_BASILICA] || sd->sc.data[SC__SHADOWFORM] )
+ return;
+
+ if (!battle_config.sdelay_attack_enable && pc_checkskill(sd, SA_FREECAST) <= 0) {
+ if (DIFF_TICK(tick, sd->ud.canact_tick) < 0) {
+ clif_skill_fail(sd, 1, USESKILL_FAIL_SKILLINTERVAL, 0);
+ return;
+ }
+ }
+
+ pc_delinvincibletimer(sd);
+ sd->idletime = last_tick;
+ unit_attack(&sd->bl, target_id, action_type != 0);
+ break;
+ case 0x02: // sitdown
+ if (battle_config.basic_skill_check && pc_checkskill(sd, NV_BASIC) < 3) {
+ clif_skill_fail(sd, 1, USESKILL_FAIL_LEVEL, 2);
+ break;
+ }
+
+ if(pc_issit(sd)) {
+ //Bugged client? Just refresh them.
+ clif_sitting(&sd->bl);
+ return;
+ }
+
+ if (sd->ud.skilltimer != INVALID_TIMER || (sd->sc.opt1 && sd->sc.opt1 != OPT1_BURNING ))
+ break;
+
+ if (sd->sc.count && (
+ sd->sc.data[SC_DANCING] ||
+ (sd->sc.data[SC_GRAVITATION] && sd->sc.data[SC_GRAVITATION]->val3 == BCT_SELF)
+ )) //No sitting during these states either.
+ break;
+
+ pc_setsit(sd);
+ skill_sit(sd,1);
+ clif_sitting(&sd->bl);
+ break;
+ case 0x03: // standup
+ if (!pc_issit(sd)) {
+ //Bugged client? Just refresh them.
+ clif_standing(&sd->bl);
+ return;
+ }
+ pc_setstand(sd);
+ skill_sit(sd,0);
+ clif_standing(&sd->bl);
+ break;
+ }
}
@@ -9806,11 +9916,11 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type,
/// There are various variants of this packet, some of them have padding between fields.
void clif_parse_ActionRequest(int fd, struct map_session_data *sd)
{
- clif_parse_ActionRequest_sub(sd,
- RFIFOB(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]),
- RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]),
- gettick()
- );
+ clif_parse_ActionRequest_sub(sd,
+ RFIFOB(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]),
+ RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]),
+ gettick()
+ );
}
@@ -9821,162 +9931,162 @@ void clif_parse_ActionRequest(int fd, struct map_session_data *sd)
/// 1 = char-select (disconnect)
void clif_parse_Restart(int fd, struct map_session_data *sd)
{
- switch (RFIFOB(fd,2)) {
- case 0x00:
- pc_respawn(sd,CLR_RESPAWN);
- break;
- case 0x01:
- /* Rovert's Prevent logout option - Fixed [Valaris] */
- if (!sd->sc.data[SC_CLOAKING] && !sd->sc.data[SC_HIDING] && !sd->sc.data[SC_CHASEWALK] && !sd->sc.data[SC_CLOAKINGEXCEED] &&
- (!battle_config.prevent_logout || DIFF_TICK(gettick(), sd->canlog_tick) > battle_config.prevent_logout)) {
- //Send to char-server for character selection.
- chrif_charselectreq(sd, session[fd]->client_addr);
- } else {
- clif_disconnect_ack(sd, 1);
- }
- break;
- }
+ switch(RFIFOB(fd,2)) {
+ case 0x00:
+ pc_respawn(sd,CLR_RESPAWN);
+ break;
+ case 0x01:
+ /* Rovert's Prevent logout option - Fixed [Valaris] */
+ if( !sd->sc.data[SC_CLOAKING] && !sd->sc.data[SC_HIDING] && !sd->sc.data[SC_CHASEWALK] && !sd->sc.data[SC_CLOAKINGEXCEED] &&
+ (!battle_config.prevent_logout || DIFF_TICK(gettick(), sd->canlog_tick) > battle_config.prevent_logout) )
+ { //Send to char-server for character selection.
+ chrif_charselectreq(sd, session[fd]->client_addr);
+ } else {
+ clif_disconnect_ack(sd, 1);
+ }
+ break;
+ }
}
/// Validates and processes whispered messages (CZ_WHISPER).
/// 0096 <packet len>.W <nick>.24B <message>.?B
-void clif_parse_WisMessage(int fd, struct map_session_data *sd)
-{
- struct map_session_data *dstsd;
- int i;
-
- char *target, *message;
- int namelen, messagelen;
-
- // validate packet and retrieve name and message
- if (!clif_process_message(sd, 1, &target, &namelen, &message, &messagelen))
- return;
-
- if (is_atcommand(fd, sd, message, 1))
- return;
-
- if (sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT))
- return;
-
- if (battle_config.min_chat_delay) { //[Skotlex]
- if (DIFF_TICK(sd->cantalk_tick, gettick()) > 0) {
- return;
- }
- sd->cantalk_tick = gettick() + battle_config.min_chat_delay;
- }
-
- // Chat logging type 'W' / Whisper
- log_chat(LOG_CHAT_WHISPER, 0, sd->status.char_id, sd->status.account_id, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y, target, message);
-
- //-------------------------------------------------------//
- // Lordalfa - Paperboy - To whisper NPC commands //
- //-------------------------------------------------------//
- if (target[0] && (strncasecmp(target,"NPC:",4) == 0) && (strlen(target) > 4)) {
- char *str = target+4; //Skip the NPC: string part.
- struct npc_data *npc;
- if ((npc = npc_name2id(str))) {
- char split_data[NUM_WHISPER_VAR][CHAT_SIZE_MAX];
- char *split;
- char output[256];
-
- str = message;
- // skip codepage indicator, if detected
- if (str[0] == '|' && strlen(str) >= 4)
- str += 3;
- for (i = 0; i < NUM_WHISPER_VAR; ++i) { // Splits the message using '#' as separators
- split = strchr(str,'#');
- if (split == NULL) { // use the remaining string
- safestrncpy(split_data[i], str, ARRAYLENGTH(split_data[i]));
- for (++i; i < NUM_WHISPER_VAR; ++i)
- split_data[i][0] = '\0';
- break;
- }
- *split = '\0';
- safestrncpy(split_data[i], str, ARRAYLENGTH(split_data[i]));
- str = split+1;
- }
-
- for (i = 0; i < NUM_WHISPER_VAR; ++i) {
- sprintf(output, "@whispervar%d$", i);
- set_var(sd,output,(char *) split_data[i]);
- }
-
- sprintf(output, "%s::OnWhisperGlobal", npc->exname);
- npc_event(sd,output,0); // Calls the NPC label
-
- return;
- }
- } else if (strcmpi(target, main_chat_nick) == 0) { // Main chat [LuzZza]
- if (!sd->state.mainchat)
- clif_displaymessage(fd, msg_txt(388)); // You should enable main chat with "@main on" command.
- else {
- // send the main message using inter-server system
- intif_main_message(sd, message);
- }
-
- return;
- }
-
- // searching destination character
- dstsd = map_nick2sd(target);
-
- if (dstsd == NULL || strcmp(dstsd->status.name, target) != 0) {
- // player is not on this map-server
- // 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).
- intif_wis_message(sd, target, message, messagelen);
- return;
- }
-
- // if player ignores everyone
- if (dstsd->state.ignoreAll) {
- if (dstsd->sc.option & OPTION_INVISIBLE && pc_get_group_level(sd) < pc_get_group_level(dstsd))
- clif_wis_end(fd, 1); // 1: target character is not loged in
- else
- clif_wis_end(fd, 3); // 3: everyone ignored by target
- return;
- }
-
- // if player is autotrading
- if (dstsd->state.autotrade == 1) {
- char output[256];
- sprintf(output, "%s is in autotrade mode and cannot receive whispered messages.", dstsd->status.name);
- clif_wis_message(fd, wisp_server_name, output, strlen(output) + 1);
- return;
- }
-
- // if player ignores the source character
- ARR_FIND(0, MAX_IGNORE_LIST, i, dstsd->ignore[i].name[0] == '\0' || strcmp(dstsd->ignore[i].name, sd->status.name) == 0);
- if (i < MAX_IGNORE_LIST && dstsd->ignore[i].name[0] != '\0') { // source char present in ignore list
- clif_wis_end(fd, 2); // 2: ignored by target
- return;
- }
-
- // notify sender of success
- clif_wis_end(fd, 0); // 0: success to send wisper
-
- // Normal message
- clif_wis_message(dstsd->fd, sd->status.name, message, messagelen);
+void clif_parse_WisMessage(int fd, struct map_session_data* sd)
+{
+ struct map_session_data* dstsd;
+ int i;
+
+ char *target, *message;
+ int namelen, messagelen;
+
+ // validate packet and retrieve name and message
+ if( !clif_process_message(sd, 1, &target, &namelen, &message, &messagelen) )
+ return;
+
+ if ( is_atcommand(fd, sd, message, 1) )
+ return;
+
+ if (sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT))
+ return;
+
+ if (battle_config.min_chat_delay) { //[Skotlex]
+ if (DIFF_TICK(sd->cantalk_tick, gettick()) > 0) {
+ return;
+ }
+ sd->cantalk_tick = gettick() + battle_config.min_chat_delay;
+ }
+
+ // Chat logging type 'W' / Whisper
+ log_chat(LOG_CHAT_WHISPER, 0, sd->status.char_id, sd->status.account_id, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y, target, message);
+
+ //-------------------------------------------------------//
+ // Lordalfa - Paperboy - To whisper NPC commands //
+ //-------------------------------------------------------//
+ if (target[0] && (strncasecmp(target,"NPC:",4) == 0) && (strlen(target) > 4))
+ {
+ char* str = target+4; //Skip the NPC: string part.
+ struct npc_data* npc;
+ if ((npc = npc_name2id(str))) {
+ char split_data[NUM_WHISPER_VAR][CHAT_SIZE_MAX];
+ char *split;
+ char output[256];
+
+ str = message;
+ // skip codepage indicator, if detected
+ if( str[0] == '|' && strlen(str) >= 4 )
+ str += 3;
+ for( i = 0; i < NUM_WHISPER_VAR; ++i ) {// Splits the message using '#' as separators
+ split = strchr(str,'#');
+ if( split == NULL ) { // use the remaining string
+ safestrncpy(split_data[i], str, ARRAYLENGTH(split_data[i]));
+ for( ++i; i < NUM_WHISPER_VAR; ++i )
+ split_data[i][0] = '\0';
+ break;
+ }
+ *split = '\0';
+ safestrncpy(split_data[i], str, ARRAYLENGTH(split_data[i]));
+ str = split+1;
+ }
+
+ for( i = 0; i < NUM_WHISPER_VAR; ++i ) {
+ sprintf(output, "@whispervar%d$", i);
+ set_var(sd,output,(char *) split_data[i]);
+ }
+
+ sprintf(output, "%s::OnWhisperGlobal", npc->exname);
+ npc_event(sd,output,0); // Calls the NPC label
+
+ return;
+ }
+ } else if(strcmpi(target, main_chat_nick) == 0) { // Main chat [LuzZza]
+ if(!sd->state.mainchat)
+ clif_displaymessage(fd, msg_txt(388)); // You should enable main chat with "@main on" command.
+ else {
+ // send the main message using inter-server system
+ intif_main_message( sd, message );
+ }
+
+ return;
+ }
+
+ // searching destination character
+ dstsd = map_nick2sd(target);
+
+ if (dstsd == NULL || strcmp(dstsd->status.name, target) != 0) {
+ // player is not on this map-server
+ // 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).
+ intif_wis_message(sd, target, message, messagelen);
+ return;
+ }
+
+ // if player ignores everyone
+ if (dstsd->state.ignoreAll) {
+ if (dstsd->sc.option & OPTION_INVISIBLE && pc_get_group_level(sd) < pc_get_group_level(dstsd))
+ clif_wis_end(fd, 1); // 1: target character is not loged in
+ else
+ clif_wis_end(fd, 3); // 3: everyone ignored by target
+ return;
+ }
+
+ // if player is autotrading
+ if( dstsd->state.autotrade == 1 ) {
+ char output[256];
+ sprintf(output, "%s is in autotrade mode and cannot receive whispered messages.", dstsd->status.name);
+ clif_wis_message(fd, wisp_server_name, output, strlen(output) + 1);
+ return;
+ }
+
+ // if player ignores the source character
+ ARR_FIND(0, MAX_IGNORE_LIST, i, dstsd->ignore[i].name[0] == '\0' || strcmp(dstsd->ignore[i].name, sd->status.name) == 0);
+ if(i < MAX_IGNORE_LIST && dstsd->ignore[i].name[0] != '\0') { // source char present in ignore list
+ clif_wis_end(fd, 2); // 2: ignored by target
+ return;
+ }
+
+ // notify sender of success
+ clif_wis_end(fd, 0); // 0: success to send wisper
+
+ // Normal message
+ clif_wis_message(dstsd->fd, sd->status.name, message, messagelen);
}
/// /b /nb (CZ_BROADCAST).
/// Request to broadcast a message on whole server.
/// 0099 <packet len>.W <text>.?B 00
-void clif_parse_Broadcast(int fd, struct map_session_data *sd)
-{
- char command[CHAT_SIZE_MAX+11];
- char *msg = (char *)RFIFOP(fd,4);
- unsigned int len = RFIFOW(fd,2)-4;
+void clif_parse_Broadcast(int fd, struct map_session_data* sd) {
+ char command[CHAT_SIZE_MAX+11];
+ char* msg = (char*)RFIFOP(fd,4);
+ unsigned int len = RFIFOW(fd,2)-4;
- // as the length varies depending on the command used, just block unreasonably long strings
- mes_len_check(msg, len, CHAT_SIZE_MAX);
+ // as the length varies depending on the command used, just block unreasonably long strings
+ mes_len_check(msg, len, CHAT_SIZE_MAX);
- sprintf(command, "%ckami %s", atcommand_symbol, msg);
- is_atcommand(fd, sd, command, 1);
+ sprintf(command, "%ckami %s", atcommand_symbol, msg);
+ is_atcommand(fd, sd, command, 1);
}
@@ -9986,35 +10096,35 @@ void clif_parse_Broadcast(int fd, struct map_session_data *sd)
/// There are various variants of this packet, some of them have padding between fields.
void clif_parse_TakeItem(int fd, struct map_session_data *sd)
{
- struct flooritem_data *fitem;
- int map_object_id;
+ struct flooritem_data *fitem;
+ int map_object_id;
- map_object_id = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
+ map_object_id = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
- fitem = (struct flooritem_data *)map_id2bl(map_object_id);
+ fitem = (struct flooritem_data*)map_id2bl(map_object_id);
- do {
- if (pc_isdead(sd)) {
- clif_clearunit_area(&sd->bl, CLR_DEAD);
- break;
- }
+ do {
+ if (pc_isdead(sd)) {
+ clif_clearunit_area(&sd->bl, CLR_DEAD);
+ break;
+ }
- if (fitem == NULL || fitem->bl.type != BL_ITEM || fitem->bl.m != sd->bl.m)
- break;
+ if (fitem == NULL || fitem->bl.type != BL_ITEM || fitem->bl.m != sd->bl.m)
+ break;
- if (sd->sc.cant.pickup)
- break;
+ if( sd->sc.cant.pickup )
+ break;
- if (pc_cant_act(sd))
- break;
+ if (pc_cant_act(sd))
+ break;
- if (!pc_takeitem(sd, fitem))
- break;
+ if (!pc_takeitem(sd, fitem))
+ break;
- return;
- } while (0);
- // Client REQUIRES a fail packet or you can no longer pick items.
- clif_additem(sd,0,0,6);
+ return;
+ } while (0);
+ // Client REQUIRES a fail packet or you can no longer pick items.
+ clif_additem(sd,0,0,6);
}
@@ -10024,31 +10134,31 @@ void clif_parse_TakeItem(int fd, struct map_session_data *sd)
/// There are various variants of this packet, some of them have padding between fields.
void clif_parse_DropItem(int fd, struct map_session_data *sd)
{
- int item_index = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0])-2;
- int item_amount = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]);
+ int item_index = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0])-2;
+ int item_amount = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]);
- for (;;) {
- if (pc_isdead(sd))
- break;
+ for(;;) {
+ if (pc_isdead(sd))
+ break;
- if (pc_cant_act(sd))
- break;
+ if (pc_cant_act(sd))
+ break;
- if (sd->sc.count && (
- sd->sc.data[SC_AUTOCOUNTER] ||
- sd->sc.data[SC_BLADESTOP] ||
- (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOITEM)
- ))
- break;
+ if (sd->sc.count && (
+ sd->sc.data[SC_AUTOCOUNTER] ||
+ sd->sc.data[SC_BLADESTOP] ||
+ (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOITEM)
+ ))
+ break;
- if (!pc_dropitem(sd, item_index, item_amount))
- break;
+ if (!pc_dropitem(sd, item_index, item_amount))
+ break;
- return;
- }
+ return;
+ }
- //Because the client does not like being ignored.
- clif_dropitem(sd, item_index,0);
+ //Because the client does not like being ignored.
+ clif_dropitem(sd, item_index,0);
}
@@ -10058,28 +10168,29 @@ void clif_parse_DropItem(int fd, struct map_session_data *sd)
/// There are various variants of this packet, some of them have padding between fields.
void clif_parse_UseItem(int fd, struct map_session_data *sd)
{
- int n;
+ int n;
- if (pc_isdead(sd)) {
- clif_clearunit_area(&sd->bl, CLR_DEAD);
- return;
- }
+ if (pc_isdead(sd)) {
+ clif_clearunit_area(&sd->bl, CLR_DEAD);
+ return;
+ }
- //This flag enables you to use items while in an NPC. [Skotlex]
- if (sd->npc_id) {
- if (sd->npc_id != sd->npc_item_flag)
- return;
- } else if (pc_istrading(sd))
- return;
+ //This flag enables you to use items while in an NPC. [Skotlex]
+ if (sd->npc_id) {
+ if (sd->npc_id != sd->npc_item_flag)
+ return;
+ }
+ else if (pc_istrading(sd))
+ return;
- //Whether the item is used or not is irrelevant, the char ain't idle. [Skotlex]
- sd->idletime = last_tick;
- n = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0])-2;
+ //Whether the item is used or not is irrelevant, the char ain't idle. [Skotlex]
+ sd->idletime = last_tick;
+ n = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0])-2;
- if (n <0 || n >= MAX_INVENTORY)
- return;
- if (!pc_useitem(sd,n))
- clif_useitemack(sd,n,0,false); //Send an empty ack packet or the client gets stuck.
+ if(n <0 || n >= MAX_INVENTORY)
+ return;
+ if (!pc_useitem(sd,n))
+ clif_useitemack(sd,n,0,false); //Send an empty ack packet or the client gets stuck.
}
@@ -10087,42 +10198,42 @@ void clif_parse_UseItem(int fd, struct map_session_data *sd)
/// 00a9 <index>.W <position>.W
void clif_parse_EquipItem(int fd,struct map_session_data *sd)
{
- int index;
+ int index;
- if (pc_isdead(sd)) {
- clif_clearunit_area(&sd->bl,CLR_DEAD);
- return;
- }
- index = RFIFOW(fd,2)-2;
- if (index < 0 || index >= MAX_INVENTORY)
- return; //Out of bounds check.
+ if(pc_isdead(sd)) {
+ clif_clearunit_area(&sd->bl,CLR_DEAD);
+ return;
+ }
+ index = RFIFOW(fd,2)-2;
+ if (index < 0 || index >= MAX_INVENTORY)
+ return; //Out of bounds check.
- if (sd->npc_id) {
- if (sd->npc_id != sd->npc_item_flag)
- return;
- } else if (sd->state.storage_flag || sd->sc.opt1)
- ; //You can equip/unequip stuff while storage is open/under status changes
- else if (pc_cant_act(sd))
- return;
-
- if (!sd->status.inventory[index].identify) {
- clif_equipitemack(sd,index,0,0); // fail
- return;
- }
+ if(sd->npc_id) {
+ if (sd->npc_id != sd->npc_item_flag)
+ return;
+ } else if (sd->state.storage_flag || sd->sc.opt1)
+ ; //You can equip/unequip stuff while storage is open/under status changes
+ else if (pc_cant_act(sd))
+ return;
- if (!sd->inventory_data[index])
- return;
+ if(!sd->status.inventory[index].identify) {
+ clif_equipitemack(sd,index,0,0); // fail
+ return;
+ }
- if (sd->inventory_data[index]->type == IT_PETARMOR) {
- pet_equipitem(sd,index);
- return;
- }
+ if(!sd->inventory_data[index])
+ return;
- //Client doesn't send the position for ammo.
- if (sd->inventory_data[index]->type == IT_AMMO)
- pc_equipitem(sd,index,EQP_AMMO);
- else
- pc_equipitem(sd,index,RFIFOW(fd,4));
+ if(sd->inventory_data[index]->type == IT_PETARMOR){
+ pet_equipitem(sd,index);
+ return;
+ }
+
+ //Client doesn't send the position for ammo.
+ if(sd->inventory_data[index]->type == IT_AMMO)
+ pc_equipitem(sd,index,EQP_AMMO);
+ else
+ pc_equipitem(sd,index,RFIFOW(fd,4));
}
@@ -10130,21 +10241,21 @@ void clif_parse_EquipItem(int fd,struct map_session_data *sd)
/// 00ab <index>.W
void clif_parse_UnequipItem(int fd,struct map_session_data *sd)
{
- int index;
+ int index;
- if (pc_isdead(sd)) {
- clif_clearunit_area(&sd->bl,CLR_DEAD);
- return;
- }
+ if(pc_isdead(sd)) {
+ clif_clearunit_area(&sd->bl,CLR_DEAD);
+ return;
+ }
- if (sd->state.storage_flag || sd->sc.opt1)
- ; //You can equip/unequip stuff while storage is open/under status changes
- else if (pc_cant_act(sd))
- return;
+ if (sd->state.storage_flag || sd->sc.opt1)
+ ; //You can equip/unequip stuff while storage is open/under status changes
+ else if (pc_cant_act(sd))
+ return;
- index = RFIFOW(fd,2)-2;
+ index = RFIFOW(fd,2)-2;
- pc_unequipitem(sd,index,1);
+ pc_unequipitem(sd,index,1);
}
@@ -10154,28 +10265,28 @@ void clif_parse_UnequipItem(int fd,struct map_session_data *sd)
/// 1 = click
void clif_parse_NpcClicked(int fd,struct map_session_data *sd)
{
- struct block_list *bl;
+ struct block_list *bl;
- if (pc_isdead(sd)) {
- clif_clearunit_area(&sd->bl,CLR_DEAD);
- return;
- }
+ if(pc_isdead(sd)) {
+ clif_clearunit_area(&sd->bl,CLR_DEAD);
+ return;
+ }
- if (pc_cant_act(sd))
- return;
-
- bl = map_id2bl(RFIFOL(fd,2));
- if (!bl) return;
- switch (bl->type) {
- case BL_MOB:
- case BL_PC:
- clif_parse_ActionRequest_sub(sd, 0x07, bl->id, gettick());
- break;
- case BL_NPC:
- if (bl->m != -1) // the user can't click floating npcs directly (hack attempt)
- npc_click(sd,(TBL_NPC *)bl);
- break;
- }
+ if (pc_cant_act(sd))
+ return;
+
+ bl = map_id2bl(RFIFOL(fd,2));
+ if (!bl) return;
+ switch (bl->type) {
+ case BL_MOB:
+ case BL_PC:
+ clif_parse_ActionRequest_sub(sd, 0x07, bl->id, gettick());
+ break;
+ case BL_NPC:
+ if( bl->m != -1 )// the user can't click floating npcs directly (hack attempt)
+ npc_click(sd,(TBL_NPC*)bl);
+ break;
+ }
}
@@ -10186,9 +10297,9 @@ void clif_parse_NpcClicked(int fd,struct map_session_data *sd)
/// 1 = sell
void clif_parse_NpcBuySellSelected(int fd,struct map_session_data *sd)
{
- if (sd->state.trading)
- return;
- npc_buysellsel(sd,RFIFOL(fd,2),RFIFOB(fd,6));
+ if (sd->state.trading)
+ return;
+ npc_buysellsel(sd,RFIFOL(fd,2),RFIFOB(fd,6));
}
@@ -10199,33 +10310,33 @@ void clif_parse_NpcBuySellSelected(int fd,struct map_session_data *sd)
/// 1 = "You do not have enough zeny."
/// 2 = "You are over your Weight Limit."
/// 3 = "Out of the maximum capacity, you have too many items."
-void clif_npc_buy_result(struct map_session_data *sd, unsigned char result)
+void clif_npc_buy_result(struct map_session_data* sd, unsigned char result)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0xca));
- WFIFOW(fd,0) = 0xca;
- WFIFOB(fd,2) = result;
- WFIFOSET(fd,packet_len(0xca));
+ WFIFOHEAD(fd,packet_len(0xca));
+ WFIFOW(fd,0) = 0xca;
+ WFIFOB(fd,2) = result;
+ WFIFOSET(fd,packet_len(0xca));
}
/// Request to buy chosen items from npc shop (CZ_PC_PURCHASE_ITEMLIST).
/// 00c8 <packet len>.W { <amount>.W <name id>.W }*
-void clif_parse_NpcBuyListSend(int fd, struct map_session_data *sd)
+void clif_parse_NpcBuyListSend(int fd, struct map_session_data* sd)
{
- int n = (RFIFOW(fd,2)-4) /4;
- unsigned short *item_list = (unsigned short *)RFIFOP(fd,4);
- int result;
+ int n = (RFIFOW(fd,2)-4) /4;
+ unsigned short* item_list = (unsigned short*)RFIFOP(fd,4);
+ int result;
- if (sd->state.trading || !sd->npc_shopid)
- result = 1;
- else
- result = npc_buylist(sd,n,item_list);
+ if( sd->state.trading || !sd->npc_shopid )
+ result = 1;
+ else
+ result = npc_buylist(sd,n,item_list);
- sd->npc_shopid = 0; //Clear shop data.
+ sd->npc_shopid = 0; //Clear shop data.
- clif_npc_buy_result(sd, result);
+ clif_npc_buy_result(sd, result);
}
@@ -10234,14 +10345,14 @@ void clif_parse_NpcBuyListSend(int fd, struct map_session_data *sd)
/// result:
/// 0 = "The deal has successfully completed."
/// 1 = "The deal has failed."
-void clif_npc_sell_result(struct map_session_data *sd, unsigned char result)
+void clif_npc_sell_result(struct map_session_data* sd, unsigned char result)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0xcb));
- WFIFOW(fd,0) = 0xcb;
- WFIFOB(fd,2) = result;
- WFIFOSET(fd,packet_len(0xcb));
+ WFIFOHEAD(fd,packet_len(0xcb));
+ WFIFOW(fd,0) = 0xcb;
+ WFIFOB(fd,2) = result;
+ WFIFOSET(fd,packet_len(0xcb));
}
@@ -10249,20 +10360,20 @@ void clif_npc_sell_result(struct map_session_data *sd, unsigned char result)
/// 00c9 <packet len>.W { <index>.W <amount>.W }*
void clif_parse_NpcSellListSend(int fd,struct map_session_data *sd)
{
- int fail=0,n;
- unsigned short *item_list;
+ int fail=0,n;
+ unsigned short *item_list;
- n = (RFIFOW(fd,2)-4) /4;
- item_list = (unsigned short *)RFIFOP(fd,4);
+ n = (RFIFOW(fd,2)-4) /4;
+ item_list = (unsigned short*)RFIFOP(fd,4);
- if (sd->state.trading || !sd->npc_shopid)
- fail = 1;
- else
- fail = npc_selllist(sd,n,item_list);
+ if (sd->state.trading || !sd->npc_shopid)
+ fail = 1;
+ else
+ fail = npc_selllist(sd,n,item_list);
- sd->npc_shopid = 0; //Clear shop data.
+ sd->npc_shopid = 0; //Clear shop data.
- clif_npc_sell_result(sd, fail);
+ clif_npc_sell_result(sd, fail);
}
@@ -10271,41 +10382,41 @@ void clif_parse_NpcSellListSend(int fd,struct map_session_data *sd)
/// type:
/// 0 = private
/// 1 = public
-void clif_parse_CreateChatRoom(int fd, struct map_session_data *sd)
-{
- int len = RFIFOW(fd,2)-15;
- int limit = RFIFOW(fd,4);
- bool pub = (RFIFOB(fd,6) != 0);
- const char *password = (char *)RFIFOP(fd,7); //not zero-terminated
- const char *title = (char *)RFIFOP(fd,15); // not zero-terminated
- char s_password[CHATROOM_PASS_SIZE];
- char s_title[CHATROOM_TITLE_SIZE];
-
- if (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOROOM)
- return;
- if (battle_config.basic_skill_check && pc_checkskill(sd,NV_BASIC) < 4) {
- clif_skill_fail(sd,1,USESKILL_FAIL_LEVEL,3);
- return;
- }
+void clif_parse_CreateChatRoom(int fd, struct map_session_data* sd)
+{
+ int len = RFIFOW(fd,2)-15;
+ int limit = RFIFOW(fd,4);
+ bool pub = (RFIFOB(fd,6) != 0);
+ const char* password = (char*)RFIFOP(fd,7); //not zero-terminated
+ const char* title = (char*)RFIFOP(fd,15); // not zero-terminated
+ char s_password[CHATROOM_PASS_SIZE];
+ char s_title[CHATROOM_TITLE_SIZE];
+
+ if (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOROOM)
+ return;
+ if(battle_config.basic_skill_check && pc_checkskill(sd,NV_BASIC) < 4) {
+ clif_skill_fail(sd,1,USESKILL_FAIL_LEVEL,3);
+ return;
+ }
- if (len <= 0)
- return; // invalid input
+ if( len <= 0 )
+ return; // invalid input
- safestrncpy(s_password, password, CHATROOM_PASS_SIZE);
- safestrncpy(s_title, title, min(len+1,CHATROOM_TITLE_SIZE)); //NOTE: assumes that safestrncpy will not access the len+1'th byte
+ safestrncpy(s_password, password, CHATROOM_PASS_SIZE);
+ safestrncpy(s_title, title, min(len+1,CHATROOM_TITLE_SIZE)); //NOTE: assumes that safestrncpy will not access the len+1'th byte
- chat_createpcchat(sd, s_title, s_password, limit, pub);
+ chat_createpcchat(sd, s_title, s_password, limit, pub);
}
/// Chatroom join request (CZ_REQ_ENTER_ROOM).
/// 00d9 <chat ID>.L <passwd>.8B
-void clif_parse_ChatAddMember(int fd, struct map_session_data *sd)
+void clif_parse_ChatAddMember(int fd, struct map_session_data* sd)
{
- int chatid = RFIFOL(fd,2);
- const char *password = (char *)RFIFOP(fd,6); // not zero-terminated
+ int chatid = RFIFOL(fd,2);
+ const char* password = (char*)RFIFOP(fd,6); // not zero-terminated
- chat_joinchat(sd,chatid,password);
+ chat_joinchat(sd,chatid,password);
}
@@ -10314,23 +10425,23 @@ void clif_parse_ChatAddMember(int fd, struct map_session_data *sd)
/// type:
/// 0 = private
/// 1 = public
-void clif_parse_ChatRoomStatusChange(int fd, struct map_session_data *sd)
+void clif_parse_ChatRoomStatusChange(int fd, struct map_session_data* sd)
{
- int len = RFIFOW(fd,2)-15;
- int limit = RFIFOW(fd,4);
- bool pub = (RFIFOB(fd,6) != 0);
- const char *password = (char *)RFIFOP(fd,7); // not zero-terminated
- const char *title = (char *)RFIFOP(fd,15); // not zero-terminated
- char s_password[CHATROOM_PASS_SIZE];
- char s_title[CHATROOM_TITLE_SIZE];
+ int len = RFIFOW(fd,2)-15;
+ int limit = RFIFOW(fd,4);
+ bool pub = (RFIFOB(fd,6) != 0);
+ const char* password = (char*)RFIFOP(fd,7); // not zero-terminated
+ const char* title = (char*)RFIFOP(fd,15); // not zero-terminated
+ char s_password[CHATROOM_PASS_SIZE];
+ char s_title[CHATROOM_TITLE_SIZE];
- if (len <= 0)
- return; // invalid input
+ if( len <= 0 )
+ return; // invalid input
- safestrncpy(s_password, password, CHATROOM_PASS_SIZE);
- safestrncpy(s_title, title, min(len+1,CHATROOM_TITLE_SIZE)); //NOTE: assumes that safestrncpy will not access the len+1'th byte
+ safestrncpy(s_password, password, CHATROOM_PASS_SIZE);
+ safestrncpy(s_title, title, min(len+1,CHATROOM_TITLE_SIZE)); //NOTE: assumes that safestrncpy will not access the len+1'th byte
- chat_changechatstatus(sd, s_title, s_password, limit, pub);
+ chat_changechatstatus(sd, s_title, s_password, limit, pub);
}
@@ -10339,9 +10450,9 @@ void clif_parse_ChatRoomStatusChange(int fd, struct map_session_data *sd)
/// role:
/// 0 = owner
/// 1 = normal
-void clif_parse_ChangeChatOwner(int fd, struct map_session_data *sd)
+void clif_parse_ChangeChatOwner(int fd, struct map_session_data* sd)
{
- chat_changechatowner(sd,(char *)RFIFOP(fd,6));
+ chat_changechatowner(sd,(char*)RFIFOP(fd,6));
}
@@ -10349,15 +10460,15 @@ void clif_parse_ChangeChatOwner(int fd, struct map_session_data *sd)
/// 00e2 <name>.24B
void clif_parse_KickFromChat(int fd,struct map_session_data *sd)
{
- chat_kickchat(sd,(char *)RFIFOP(fd,2));
+ chat_kickchat(sd,(char*)RFIFOP(fd,2));
}
/// Request to leave the current chatroom (CZ_EXIT_ROOM).
/// 00e3
-void clif_parse_ChatLeave(int fd, struct map_session_data *sd)
+void clif_parse_ChatLeave(int fd, struct map_session_data* sd)
{
- chat_leavechat(sd,0);
+ chat_leavechat(sd,0);
}
@@ -10366,14 +10477,14 @@ void clif_parse_ChatLeave(int fd, struct map_session_data *sd)
//0:
static void clif_noask_sub(struct map_session_data *src, struct map_session_data *target, int type)
{
- const char *msg;
- char output[256];
- // Your request has been rejected by autoreject option.
- msg = msg_txt(392);
- clif_disp_onlyself(src, msg, strlen(msg));
- //Notice that a request was rejected.
- snprintf(output, 256, msg_txt(393+type), src->status.name, 256);
- clif_disp_onlyself(target, output, strlen(output));
+ const char* msg;
+ char output[256];
+ // Your request has been rejected by autoreject option.
+ msg = msg_txt(392);
+ clif_disp_onlyself(src, msg, strlen(msg));
+ //Notice that a request was rejected.
+ snprintf(output, 256, msg_txt(393+type), src->status.name, 256);
+ clif_disp_onlyself(target, output, strlen(output));
}
@@ -10381,25 +10492,26 @@ static void clif_noask_sub(struct map_session_data *src, struct map_session_data
/// 00e4 <account id>.L
void clif_parse_TradeRequest(int fd,struct map_session_data *sd)
{
- struct map_session_data *t_sd;
+ struct map_session_data *t_sd;
- t_sd = map_id2sd(RFIFOL(fd,2));
+ t_sd = map_id2sd(RFIFOL(fd,2));
- if (!sd->chatID && pc_cant_act(sd))
- return; //You can trade while in a chatroom.
+ if(!sd->chatID && pc_cant_act(sd))
+ return; //You can trade while in a chatroom.
- // @noask [LuzZza]
- if (t_sd && t_sd->state.noask) {
- clif_noask_sub(sd, t_sd, 0);
- return;
- }
+ // @noask [LuzZza]
+ if(t_sd && t_sd->state.noask) {
+ clif_noask_sub(sd, t_sd, 0);
+ return;
+ }
- if (battle_config.basic_skill_check && pc_checkskill(sd,NV_BASIC) < 1) {
- clif_skill_fail(sd,1,USESKILL_FAIL_LEVEL,0);
- return;
- }
+ if( battle_config.basic_skill_check && pc_checkskill(sd,NV_BASIC) < 1)
+ {
+ clif_skill_fail(sd,1,USESKILL_FAIL_LEVEL,0);
+ return;
+ }
- trade_traderequest(sd,t_sd);
+ trade_traderequest(sd,t_sd);
}
@@ -10410,7 +10522,7 @@ void clif_parse_TradeRequest(int fd,struct map_session_data *sd)
/// 4 = rejected
void clif_parse_TradeAck(int fd,struct map_session_data *sd)
{
- trade_tradeack(sd,RFIFOB(fd,2));
+ trade_tradeack(sd,RFIFOB(fd,2));
}
@@ -10418,13 +10530,13 @@ void clif_parse_TradeAck(int fd,struct map_session_data *sd)
/// 00e8 <index>.W <amount>.L
void clif_parse_TradeAddItem(int fd,struct map_session_data *sd)
{
- short index = RFIFOW(fd,2);
- int amount = RFIFOL(fd,4);
+ short index = RFIFOW(fd,2);
+ int amount = RFIFOL(fd,4);
- if (index == 0)
- trade_tradeaddzeny(sd, amount);
- else
- trade_tradeadditem(sd, index, (short)amount);
+ if( index == 0 )
+ trade_tradeaddzeny(sd, amount);
+ else
+ trade_tradeadditem(sd, index, (short)amount);
}
@@ -10432,7 +10544,7 @@ void clif_parse_TradeAddItem(int fd,struct map_session_data *sd)
/// 00eb
void clif_parse_TradeOk(int fd,struct map_session_data *sd)
{
- trade_tradeok(sd);
+ trade_tradeok(sd);
}
@@ -10440,7 +10552,7 @@ void clif_parse_TradeOk(int fd,struct map_session_data *sd)
/// 00ed
void clif_parse_TradeCancel(int fd,struct map_session_data *sd)
{
- trade_tradecancel(sd);
+ trade_tradecancel(sd);
}
@@ -10448,7 +10560,7 @@ void clif_parse_TradeCancel(int fd,struct map_session_data *sd)
/// 00ef
void clif_parse_TradeCommit(int fd,struct map_session_data *sd)
{
- trade_tradecommit(sd);
+ trade_tradecommit(sd);
}
@@ -10456,7 +10568,7 @@ void clif_parse_TradeCommit(int fd,struct map_session_data *sd)
/// 0118
void clif_parse_StopAttack(int fd,struct map_session_data *sd)
{
- pc_stop_attack(sd);
+ pc_stop_attack(sd);
}
@@ -10464,11 +10576,11 @@ void clif_parse_StopAttack(int fd,struct map_session_data *sd)
/// 0126 <index>.W <amount>.L
void clif_parse_PutItemToCart(int fd,struct map_session_data *sd)
{
- if (pc_istrading(sd))
- return;
- if (!pc_iscarton(sd))
- return;
- pc_putitemtocart(sd,RFIFOW(fd,2)-2,RFIFOL(fd,4));
+ if (pc_istrading(sd))
+ return;
+ if (!pc_iscarton(sd))
+ return;
+ pc_putitemtocart(sd,RFIFOW(fd,2)-2,RFIFOL(fd,4));
}
@@ -10476,9 +10588,9 @@ void clif_parse_PutItemToCart(int fd,struct map_session_data *sd)
/// 0127 <index>.W <amount>.L
void clif_parse_GetItemFromCart(int fd,struct map_session_data *sd)
{
- if (!pc_iscarton(sd))
- return;
- pc_getitemfromcart(sd,RFIFOW(fd,2)-2,RFIFOL(fd,4));
+ if (!pc_iscarton(sd))
+ return;
+ pc_getitemfromcart(sd,RFIFOW(fd,2)-2,RFIFOL(fd,4));
}
@@ -10486,15 +10598,15 @@ void clif_parse_GetItemFromCart(int fd,struct map_session_data *sd)
/// 012a
void clif_parse_RemoveOption(int fd,struct map_session_data *sd)
{
- /**
- * Attempts to remove these options when this function is called (will remove all available)
- **/
+ /**
+ * Attempts to remove these options when this function is called (will remove all available)
+ **/
#ifdef NEW_CARTS
- pc_setoption(sd,sd->sc.option&~(OPTION_RIDING|OPTION_FALCON|OPTION_DRAGON|OPTION_MADOGEAR));
- if (sd->sc.data[SC_PUSH_CART])
- pc_setcart(sd,0);
+ pc_setoption(sd,sd->sc.option&~(OPTION_RIDING|OPTION_FALCON|OPTION_DRAGON|OPTION_MADOGEAR));
+ if( sd->sc.data[SC_PUSH_CART] )
+ pc_setcart(sd,0);
#else
- pc_setoption(sd,sd->sc.option&~(OPTION_CART|OPTION_RIDING|OPTION_FALCON|OPTION_DRAGON|OPTION_MADOGEAR));
+ pc_setoption(sd,sd->sc.option&~(OPTION_CART|OPTION_RIDING|OPTION_FALCON|OPTION_DRAGON|OPTION_MADOGEAR));
#endif
}
@@ -10502,32 +10614,31 @@ void clif_parse_RemoveOption(int fd,struct map_session_data *sd)
/// Request to change cart's visual look (CZ_REQ_CHANGECART).
/// 01af <num>.W
void clif_parse_ChangeCart(int fd,struct map_session_data *sd)
-{
- // TODO: State tracking?
- int type;
+{// TODO: State tracking?
+ int type;
- if (sd && pc_checkskill(sd, MC_CHANGECART) < 1)
- return;
+ if( sd && pc_checkskill(sd, MC_CHANGECART) < 1 )
+ return;
- type = (int)RFIFOW(fd,2);
+ type = (int)RFIFOW(fd,2);
#ifdef NEW_CARTS
- if ((type == 9 && sd->status.base_level > 131) ||
- (type == 8 && sd->status.base_level > 121) ||
- (type == 7 && sd->status.base_level > 111) ||
- (type == 6 && sd->status.base_level > 101) ||
- (type == 5 && sd->status.base_level > 90) ||
- (type == 4 && sd->status.base_level > 80) ||
- (type == 3 && sd->status.base_level > 65) ||
- (type == 2 && sd->status.base_level > 40) ||
- (type == 1))
+ if( (type == 9 && sd->status.base_level > 131) ||
+ (type == 8 && sd->status.base_level > 121) ||
+ (type == 7 && sd->status.base_level > 111) ||
+ (type == 6 && sd->status.base_level > 101) ||
+ (type == 5 && sd->status.base_level > 90) ||
+ (type == 4 && sd->status.base_level > 80) ||
+ (type == 3 && sd->status.base_level > 65) ||
+ (type == 2 && sd->status.base_level > 40) ||
+ (type == 1))
#else
- if ((type == 5 && sd->status.base_level > 90) ||
- (type == 4 && sd->status.base_level > 80) ||
- (type == 3 && sd->status.base_level > 65) ||
- (type == 2 && sd->status.base_level > 40) ||
- (type == 1))
+ if( (type == 5 && sd->status.base_level > 90) ||
+ (type == 4 && sd->status.base_level > 80) ||
+ (type == 3 && sd->status.base_level > 65) ||
+ (type == 2 && sd->status.base_level > 40) ||
+ (type == 1))
#endif
- pc_setcart(sd,type);
+ pc_setcart(sd,type);
}
@@ -10540,7 +10651,7 @@ void clif_parse_ChangeCart(int fd,struct map_session_data *sd)
/// the like
void clif_parse_StatusUp(int fd,struct map_session_data *sd)
{
- pc_statusup(sd,RFIFOW(fd,2));
+ pc_statusup(sd,RFIFOW(fd,2));
}
@@ -10548,95 +10659,100 @@ void clif_parse_StatusUp(int fd,struct map_session_data *sd)
/// 0112 <skill id>.W
void clif_parse_SkillUp(int fd,struct map_session_data *sd)
{
- pc_skillup(sd,RFIFOW(fd,2));
+ pc_skillup(sd,RFIFOW(fd,2));
}
static void clif_parse_UseSkillToId_homun(struct homun_data *hd, struct map_session_data *sd, unsigned int tick, short skillnum, short skilllv, int target_id)
{
- int lv;
+ int lv;
- if (!hd)
- return;
- if (skillnotok_hom(skillnum, hd))
- return;
- if (hd->bl.id != target_id && skill_get_inf(skillnum)&INF_SELF_SKILL)
- target_id = hd->bl.id;
- if (hd->ud.skilltimer != INVALID_TIMER) {
- if (skillnum != SA_CASTCANCEL && skillnum != SO_SPELLFIST) return;
- } else if (DIFF_TICK(tick, hd->ud.canact_tick) < 0)
- return;
+ if( !hd )
+ return;
+ if( skillnotok_hom(skillnum, hd) )
+ return;
+ if( hd->bl.id != target_id && skill_get_inf(skillnum)&INF_SELF_SKILL )
+ target_id = hd->bl.id;
+ if( hd->ud.skilltimer != INVALID_TIMER )
+ {
+ if( skillnum != SA_CASTCANCEL && skillnum != SO_SPELLFIST ) return;
+ }
+ else if( DIFF_TICK(tick, hd->ud.canact_tick) < 0 )
+ return;
- lv = merc_hom_checkskill(hd, skillnum);
- if (skilllv > lv)
- skilllv = lv;
- if (skilllv)
- unit_skilluse_id(&hd->bl, target_id, skillnum, skilllv);
+ lv = merc_hom_checkskill(hd, skillnum);
+ if( skilllv > lv )
+ skilllv = lv;
+ if( skilllv )
+ unit_skilluse_id(&hd->bl, target_id, skillnum, skilllv);
}
static void clif_parse_UseSkillToPos_homun(struct homun_data *hd, struct map_session_data *sd, unsigned int tick, short skillnum, short skilllv, short x, short y, int skillmoreinfo)
{
- int lv;
- if (!hd)
- return;
- if (skillnotok_hom(skillnum, hd))
- return;
- if (hd->ud.skilltimer != INVALID_TIMER) {
- if (skillnum != SA_CASTCANCEL && skillnum != SO_SPELLFIST) return;
- } else if (DIFF_TICK(tick, hd->ud.canact_tick) < 0)
- return;
-
- if (hd->sc.data[SC_BASILICA])
- return;
- lv = merc_hom_checkskill(hd, skillnum);
- if (skilllv > lv)
- skilllv = lv;
- if (skilllv)
- unit_skilluse_pos(&hd->bl, x, y, skillnum, skilllv);
+ int lv;
+ if( !hd )
+ return;
+ if( skillnotok_hom(skillnum, hd) )
+ return;
+ if( hd->ud.skilltimer != INVALID_TIMER ) {
+ if( skillnum != SA_CASTCANCEL && skillnum != SO_SPELLFIST ) return;
+ } else if( DIFF_TICK(tick, hd->ud.canact_tick) < 0 )
+ return;
+
+ if( hd->sc.data[SC_BASILICA] )
+ return;
+ lv = merc_hom_checkskill(hd, skillnum);
+ if( skilllv > lv )
+ skilllv = lv;
+ if( skilllv )
+ unit_skilluse_pos(&hd->bl, x, y, skillnum, skilllv);
}
static void clif_parse_UseSkillToId_mercenary(struct mercenary_data *md, struct map_session_data *sd, unsigned int tick, short skillnum, short skilllv, int target_id)
{
- int lv;
+ int lv;
- if (!md)
- return;
- if (skillnotok_mercenary(skillnum, md))
- return;
- if (md->bl.id != target_id && skill_get_inf(skillnum)&INF_SELF_SKILL)
- target_id = md->bl.id;
- if (md->ud.skilltimer != INVALID_TIMER) {
- if (skillnum != SA_CASTCANCEL && skillnum != SO_SPELLFIST) return;
- } else if (DIFF_TICK(tick, md->ud.canact_tick) < 0)
- return;
+ if( !md )
+ return;
+ if( skillnotok_mercenary(skillnum, md) )
+ return;
+ if( md->bl.id != target_id && skill_get_inf(skillnum)&INF_SELF_SKILL )
+ target_id = md->bl.id;
+ if( md->ud.skilltimer != INVALID_TIMER )
+ {
+ if( skillnum != SA_CASTCANCEL && skillnum != SO_SPELLFIST ) return;
+ }
+ else if( DIFF_TICK(tick, md->ud.canact_tick) < 0 )
+ return;
- lv = mercenary_checkskill(md, skillnum);
- if (skilllv > lv)
- skilllv = lv;
- if (skilllv)
- unit_skilluse_id(&md->bl, target_id, skillnum, skilllv);
+ lv = mercenary_checkskill(md, skillnum);
+ if( skilllv > lv )
+ skilllv = lv;
+ if( skilllv )
+ unit_skilluse_id(&md->bl, target_id, skillnum, skilllv);
}
static void clif_parse_UseSkillToPos_mercenary(struct mercenary_data *md, struct map_session_data *sd, unsigned int tick, short skillnum, short skilllv, short x, short y, int skillmoreinfo)
{
- int lv;
- if (!md)
- return;
- if (skillnotok_mercenary(skillnum, md))
- return;
- if (md->ud.skilltimer != INVALID_TIMER)
- return;
- if (DIFF_TICK(tick, md->ud.canact_tick) < 0) {
- clif_skill_fail(md->master, skillnum, USESKILL_FAIL_SKILLINTERVAL, 0);
- return;
- }
-
- if (md->sc.data[SC_BASILICA])
- return;
- lv = mercenary_checkskill(md, skillnum);
- if (skilllv > lv)
- skilllv = lv;
- if (skilllv)
- unit_skilluse_pos(&md->bl, x, y, skillnum, skilllv);
+ int lv;
+ if( !md )
+ return;
+ if( skillnotok_mercenary(skillnum, md) )
+ return;
+ if( md->ud.skilltimer != INVALID_TIMER )
+ return;
+ if( DIFF_TICK(tick, md->ud.canact_tick) < 0 )
+ {
+ clif_skill_fail(md->master, skillnum, USESKILL_FAIL_SKILLINTERVAL, 0);
+ return;
+ }
+
+ if( md->sc.data[SC_BASILICA] )
+ return;
+ lv = mercenary_checkskill(md, skillnum);
+ if( skilllv > lv )
+ skilllv = lv;
+ if( skilllv )
+ unit_skilluse_pos(&md->bl, x, y, skillnum, skilllv);
}
@@ -10646,95 +10762,101 @@ static void clif_parse_UseSkillToPos_mercenary(struct mercenary_data *md, struct
/// There are various variants of this packet, some of them have padding between fields.
void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
{
- short skillnum, skilllv;
- int tmp, target_id;
- unsigned int tick = gettick();
-
- skilllv = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
- skillnum = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]);
- target_id = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[2]);
-
- if (skilllv < 1) skilllv = 1; //No clue, I have seen the client do this with guild skills :/ [Skotlex]
-
- tmp = skill_get_inf(skillnum);
- if (tmp&INF_GROUND_SKILL || !tmp)
- return; //Using a ground/passive skill on a target? WRONG.
-
- if (skillnum >= HM_SKILLBASE && skillnum < HM_SKILLBASE + MAX_HOMUNSKILL) {
- clif_parse_UseSkillToId_homun(sd->hd, sd, tick, skillnum, skilllv, target_id);
- return;
- }
-
- if (skillnum >= MC_SKILLBASE && skillnum < MC_SKILLBASE + MAX_MERCSKILL) {
- clif_parse_UseSkillToId_mercenary(sd->md, sd, tick, skillnum, skilllv, target_id);
- return;
- }
-
- // Whether skill fails or not is irrelevant, the char ain't idle. [Skotlex]
- sd->idletime = last_tick;
-
- if( pc_cant_act(sd) && skillnum != RK_REFRESH && !(skillnum == SR_GENTLETOUCH_CURE && (sd->sc.opt1 == OPT1_STONE || sd->sc.opt1 == OPT1_FREEZE || sd->sc.opt1 == OPT1_STUN)) )
- return;
- if (pc_issit(sd))
- return;
-
- if (skillnotok(skillnum, sd))
- return;
-
- if (sd->bl.id != target_id && tmp&INF_SELF_SKILL)
- target_id = sd->bl.id; // never trust the client
-
- if (target_id < 0 && -target_id == sd->bl.id) // for disguises [Valaris]
- target_id = sd->bl.id;
-
- if (sd->ud.skilltimer != INVALID_TIMER) {
- if (skillnum != SA_CASTCANCEL && skillnum != SO_SPELLFIST)
- return;
- } else if (DIFF_TICK(tick, sd->ud.canact_tick) < 0) {
- if (sd->skillitem != skillnum) {
- clif_skill_fail(sd, skillnum, USESKILL_FAIL_SKILLINTERVAL, 0);
- return;
- }
- }
-
- if (sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER))
- return;
-
- if (sd->sc.data[SC_BASILICA] && (skillnum != HP_BASILICA || sd->sc.data[SC_BASILICA]->val4 != sd->bl.id))
- return; // On basilica only caster can use Basilica again to stop it.
-
- if (sd->menuskill_id) {
- if (sd->menuskill_id == SA_TAMINGMONSTER) {
- clif_menuskill_clear(sd); //Cancel pet capture.
- } else if (sd->menuskill_id != SA_AUTOSPELL)
- return; //Can't use skills while a menu is open.
- }
- if (sd->skillitem == skillnum) {
- if (skilllv != sd->skillitemlv)
- skilllv = sd->skillitemlv;
- if (!(tmp&INF_SELF_SKILL))
- pc_delinvincibletimer(sd); // Target skills thru items cancel invincibility. [Inkfish]
- unit_skilluse_id(&sd->bl, target_id, skillnum, skilllv);
- return;
- }
-
- sd->skillitem = sd->skillitemlv = 0;
-
- if (skillnum >= GD_SKILLBASE) {
- if (sd->state.gmaster_flag)
- skilllv = guild_checkskill(sd->state.gmaster_flag, skillnum);
- else
- skilllv = 0;
- } else {
- tmp = pc_checkskill(sd, skillnum);
- if (skilllv > tmp)
- skilllv = tmp;
- }
-
- pc_delinvincibletimer(sd);
-
- if (skilllv)
- unit_skilluse_id(&sd->bl, target_id, skillnum, skilllv);
+ short skillnum, skilllv;
+ int tmp, target_id;
+ unsigned int tick = gettick();
+
+ skilllv = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
+ skillnum = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]);
+ target_id = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[2]);
+
+ if( skilllv < 1 ) skilllv = 1; //No clue, I have seen the client do this with guild skills :/ [Skotlex]
+
+ tmp = skill_get_inf(skillnum);
+ if (tmp&INF_GROUND_SKILL || !tmp)
+ return; //Using a ground/passive skill on a target? WRONG.
+
+ if( skillnum >= HM_SKILLBASE && skillnum < HM_SKILLBASE + MAX_HOMUNSKILL )
+ {
+ clif_parse_UseSkillToId_homun(sd->hd, sd, tick, skillnum, skilllv, target_id);
+ return;
+ }
+
+ if( skillnum >= MC_SKILLBASE && skillnum < MC_SKILLBASE + MAX_MERCSKILL )
+ {
+ clif_parse_UseSkillToId_mercenary(sd->md, sd, tick, skillnum, skilllv, target_id);
+ return;
+ }
+
+ // Whether skill fails or not is irrelevant, the char ain't idle. [Skotlex]
+ sd->idletime = last_tick;
+
+ if( pc_cant_act(sd) && !(skillnum == SR_GENTLETOUCH_CURE && (sd->sc.opt1 == OPT1_STONE || sd->sc.opt1 == OPT1_FREEZE || sd->sc.opt1 == OPT1_STUN)) )
+ return;
+ if( pc_issit(sd) )
+ return;
+
+ if( skillnotok(skillnum, sd) )
+ return;
+
+ if( sd->bl.id != target_id && tmp&INF_SELF_SKILL )
+ target_id = sd->bl.id; // never trust the client
+
+ if( target_id < 0 && -target_id == sd->bl.id ) // for disguises [Valaris]
+ target_id = sd->bl.id;
+
+ if( sd->ud.skilltimer != INVALID_TIMER )
+ {
+ if( skillnum != SA_CASTCANCEL && skillnum != SO_SPELLFIST )
+ return;
+ }
+ else if( DIFF_TICK(tick, sd->ud.canact_tick) < 0 )
+ {
+ if( sd->skillitem != skillnum )
+ {
+ clif_skill_fail(sd, skillnum, USESKILL_FAIL_SKILLINTERVAL, 0);
+ return;
+ }
+ }
+
+ if( sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER) )
+ return;
+
+ if( sd->sc.data[SC_BASILICA] && (skillnum != HP_BASILICA || sd->sc.data[SC_BASILICA]->val4 != sd->bl.id) )
+ return; // On basilica only caster can use Basilica again to stop it.
+
+ if( sd->menuskill_id ) {
+ if( sd->menuskill_id == SA_TAMINGMONSTER ) {
+ clif_menuskill_clear(sd); //Cancel pet capture.
+ } else if( sd->menuskill_id != SA_AUTOSPELL )
+ return; //Can't use skills while a menu is open.
+ }
+ if( sd->skillitem == skillnum ) {
+ if( skilllv != sd->skillitemlv )
+ skilllv = sd->skillitemlv;
+ if( !(tmp&INF_SELF_SKILL) )
+ pc_delinvincibletimer(sd); // Target skills thru items cancel invincibility. [Inkfish]
+ unit_skilluse_id(&sd->bl, target_id, skillnum, skilllv);
+ return;
+ }
+
+ sd->skillitem = sd->skillitemlv = 0;
+
+ if( skillnum >= GD_SKILLBASE ) {
+ if( sd->state.gmaster_flag )
+ skilllv = guild_checkskill(sd->state.gmaster_flag, skillnum);
+ else
+ skilllv = 0;
+ } else {
+ tmp = pc_checkskill(sd, skillnum);
+ if( skilllv > tmp )
+ skilllv = tmp;
+ }
+
+ pc_delinvincibletimer(sd);
+
+ if( skilllv )
+ unit_skilluse_id(&sd->bl, target_id, skillnum, skilllv);
}
/*==========================================
@@ -10742,73 +10864,76 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
*------------------------------------------*/
static void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, short skilllv, short skillnum, short x, short y, int skillmoreinfo)
{
- unsigned int tick = gettick();
-
- if (!(skill_get_inf(skillnum)&INF_GROUND_SKILL))
- return; //Using a target skill on the ground? WRONG.
-
- if (skillnum >= HM_SKILLBASE && skillnum < HM_SKILLBASE + MAX_HOMUNSKILL) {
- clif_parse_UseSkillToPos_homun(sd->hd, sd, tick, skillnum, skilllv, x, y, skillmoreinfo);
- return;
- }
-
- if (skillnum >= MC_SKILLBASE && skillnum < MC_SKILLBASE + MAX_MERCSKILL) {
- clif_parse_UseSkillToPos_mercenary(sd->md, sd, tick, skillnum, skilllv, x, y, skillmoreinfo);
- return;
- }
-
- //Whether skill fails or not is irrelevant, the char ain't idle. [Skotlex]
- sd->idletime = last_tick;
-
- if (skillnotok(skillnum, sd))
- return;
- if (skillmoreinfo != -1) {
- if (pc_issit(sd)) {
- clif_skill_fail(sd, skillnum, USESKILL_FAIL_LEVEL, 0);
- return;
- }
- //You can't use Graffiti/TalkieBox AND have a vending open, so this is safe.
- safestrncpy(sd->message, (char *)RFIFOP(fd,skillmoreinfo), MESSAGE_SIZE);
- }
-
- if (sd->ud.skilltimer != INVALID_TIMER)
- return;
-
- if (DIFF_TICK(tick, sd->ud.canact_tick) < 0) {
- if (sd->skillitem != skillnum) {
- clif_skill_fail(sd, skillnum, USESKILL_FAIL_SKILLINTERVAL, 0);
- return;
- }
- }
-
- if (sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER))
- return;
-
- if (sd->sc.data[SC_BASILICA] && (skillnum != HP_BASILICA || sd->sc.data[SC_BASILICA]->val4 != sd->bl.id))
- return; // On basilica only caster can use Basilica again to stop it.
-
- if (sd->menuskill_id) {
- if (sd->menuskill_id == SA_TAMINGMONSTER) {
- clif_menuskill_clear(sd); //Cancel pet capture.
- } else if (sd->menuskill_id != SA_AUTOSPELL)
- return; //Can't use skills while a menu is open.
- }
-
- pc_delinvincibletimer(sd);
-
- if (sd->skillitem == skillnum) {
- if (skilllv != sd->skillitemlv)
- skilllv = sd->skillitemlv;
- unit_skilluse_pos(&sd->bl, x, y, skillnum, skilllv);
- } else {
- int lv;
- sd->skillitem = sd->skillitemlv = 0;
- if ((lv = pc_checkskill(sd, skillnum)) > 0) {
- if (skilllv > lv)
- skilllv = lv;
- unit_skilluse_pos(&sd->bl, x, y, skillnum,skilllv);
- }
- }
+ unsigned int tick = gettick();
+
+ if( !(skill_get_inf(skillnum)&INF_GROUND_SKILL) )
+ return; //Using a target skill on the ground? WRONG.
+
+ if( skillnum >= HM_SKILLBASE && skillnum < HM_SKILLBASE + MAX_HOMUNSKILL ) {
+ clif_parse_UseSkillToPos_homun(sd->hd, sd, tick, skillnum, skilllv, x, y, skillmoreinfo);
+ return;
+ }
+
+ if( skillnum >= MC_SKILLBASE && skillnum < MC_SKILLBASE + MAX_MERCSKILL )
+ {
+ clif_parse_UseSkillToPos_mercenary(sd->md, sd, tick, skillnum, skilllv, x, y, skillmoreinfo);
+ return;
+ }
+
+ //Whether skill fails or not is irrelevant, the char ain't idle. [Skotlex]
+ sd->idletime = last_tick;
+
+ if( skillnotok(skillnum, sd) )
+ return;
+ if( skillmoreinfo != -1 )
+ {
+ if( pc_issit(sd) )
+ {
+ clif_skill_fail(sd, skillnum, USESKILL_FAIL_LEVEL, 0);
+ return;
+ }
+ //You can't use Graffiti/TalkieBox AND have a vending open, so this is safe.
+ safestrncpy(sd->message, (char*)RFIFOP(fd,skillmoreinfo), MESSAGE_SIZE);
+ }
+
+ if( sd->ud.skilltimer != INVALID_TIMER )
+ return;
+
+ if( DIFF_TICK(tick, sd->ud.canact_tick) < 0 ) {
+ if( sd->skillitem != skillnum ) {
+ clif_skill_fail(sd, skillnum, USESKILL_FAIL_SKILLINTERVAL, 0);
+ return;
+ }
+ }
+
+ if( sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER) )
+ return;
+
+ if( sd->sc.data[SC_BASILICA] && (skillnum != HP_BASILICA || sd->sc.data[SC_BASILICA]->val4 != sd->bl.id) )
+ return; // On basilica only caster can use Basilica again to stop it.
+
+ if( sd->menuskill_id ) {
+ if( sd->menuskill_id == SA_TAMINGMONSTER ) {
+ clif_menuskill_clear(sd); //Cancel pet capture.
+ } else if( sd->menuskill_id != SA_AUTOSPELL )
+ return; //Can't use skills while a menu is open.
+ }
+
+ pc_delinvincibletimer(sd);
+
+ if( sd->skillitem == skillnum ) {
+ if( skilllv != sd->skillitemlv )
+ skilllv = sd->skillitemlv;
+ unit_skilluse_pos(&sd->bl, x, y, skillnum, skilllv);
+ } else {
+ int lv;
+ sd->skillitem = sd->skillitemlv = 0;
+ if( (lv = pc_checkskill(sd, skillnum)) > 0 ) {
+ if( skilllv > lv )
+ skilllv = lv;
+ unit_skilluse_pos(&sd->bl, x, y, skillnum,skilllv);
+ }
+ }
}
@@ -10818,18 +10943,18 @@ static void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, sho
/// There are various variants of this packet, some of them have padding between fields.
void clif_parse_UseSkillToPos(int fd, struct map_session_data *sd)
{
- if (pc_cant_act(sd))
- return;
- if (pc_issit(sd))
- return;
+ if (pc_cant_act(sd))
+ return;
+ if (pc_issit(sd))
+ return;
- clif_parse_UseSkillToPosSub(fd, sd,
- RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]), //skill lv
- RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]), //skill num
- RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[2]), //pos x
- RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[3]), //pos y
- -1 //Skill more info.
- );
+ clif_parse_UseSkillToPosSub(fd, sd,
+ RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]), //skill lv
+ RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]), //skill num
+ RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[2]), //pos x
+ RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[3]), //pos y
+ -1 //Skill more info.
+ );
}
@@ -10839,39 +10964,39 @@ void clif_parse_UseSkillToPos(int fd, struct map_session_data *sd)
/// There are various variants of this packet, some of them have padding between fields.
void clif_parse_UseSkillToPosMoreInfo(int fd, struct map_session_data *sd)
{
- if (pc_cant_act(sd))
- return;
- if (pc_issit(sd))
- return;
+ if (pc_cant_act(sd))
+ return;
+ if (pc_issit(sd))
+ return;
- clif_parse_UseSkillToPosSub(fd, sd,
- RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]), //Skill lv
- RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]), //Skill num
- RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[2]), //pos x
- RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[3]), //pos y
- packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[4] //skill more info
- );
+ clif_parse_UseSkillToPosSub(fd, sd,
+ RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]), //Skill lv
+ RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]), //Skill num
+ RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[2]), //pos x
+ RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[3]), //pos y
+ packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[4] //skill more info
+ );
}
/// Answer to map selection dialog (CZ_SELECT_WARPPOINT).
/// 011b <skill id>.W <map name>.16B
-void clif_parse_UseSkillMap(int fd, struct map_session_data *sd)
+void clif_parse_UseSkillMap(int fd, struct map_session_data* sd)
{
- short skill_num = RFIFOW(fd,2);
- char map_name[MAP_NAME_LENGTH];
- mapindex_getmapname((char *)RFIFOP(fd,4), map_name);
+ short skill_num = RFIFOW(fd,2);
+ char map_name[MAP_NAME_LENGTH];
+ mapindex_getmapname((char*)RFIFOP(fd,4), map_name);
- if (skill_num != sd->menuskill_id)
- return;
+ if(skill_num != sd->menuskill_id)
+ return;
- if (pc_cant_act(sd)) {
- clif_menuskill_clear(sd);
- return;
- }
+ if( pc_cant_act(sd) ) {
+ clif_menuskill_clear(sd);
+ return;
+ }
- pc_delinvincibletimer(sd);
- skill_castend_map(sd,skill_num,map_name);
+ pc_delinvincibletimer(sd);
+ skill_castend_map(sd,skill_num,map_name);
}
@@ -10879,8 +11004,8 @@ void clif_parse_UseSkillMap(int fd, struct map_session_data *sd)
/// 011d
void clif_parse_RequestMemo(int fd,struct map_session_data *sd)
{
- if (!pc_isdead(sd))
- pc_memo(sd,-1);
+ if (!pc_isdead(sd))
+ pc_memo(sd,-1);
}
@@ -10888,24 +11013,24 @@ void clif_parse_RequestMemo(int fd,struct map_session_data *sd)
/// 018e <name id>.W { <material id>.W }*3
void clif_parse_ProduceMix(int fd,struct map_session_data *sd)
{
- switch (sd->menuskill_id) {
- case -1:
- case AM_PHARMACY:
- case RK_RUNEMASTERY:
- case GC_RESEARCHNEWPOISON:
- break;
- default:
- return;
- }
- if (pc_istrading(sd)) {
- //Make it fail to avoid shop exploits where you sell something different than you see.
- clif_skill_fail(sd,sd->ud.skillid,USESKILL_FAIL_LEVEL,0);
- clif_menuskill_clear(sd);
- return;
- }
- if (skill_can_produce_mix(sd,RFIFOW(fd,2),sd->menuskill_val, 1))
- skill_produce_mix(sd,0,RFIFOW(fd,2),RFIFOW(fd,4),RFIFOW(fd,6),RFIFOW(fd,8), 1);
- clif_menuskill_clear(sd);
+ switch( sd->menuskill_id ) {
+ case -1:
+ case AM_PHARMACY:
+ case RK_RUNEMASTERY:
+ case GC_RESEARCHNEWPOISON:
+ break;
+ default:
+ return;
+ }
+ if (pc_istrading(sd)) {
+ //Make it fail to avoid shop exploits where you sell something different than you see.
+ clif_skill_fail(sd,sd->ud.skillid,USESKILL_FAIL_LEVEL,0);
+ clif_menuskill_clear(sd);
+ return;
+ }
+ if( skill_can_produce_mix(sd,RFIFOW(fd,2),sd->menuskill_val, 1) )
+ skill_produce_mix(sd,0,RFIFOW(fd,2),RFIFOW(fd,4),RFIFOW(fd,6),RFIFOW(fd,8), 1);
+ clif_menuskill_clear(sd);
}
@@ -10918,23 +11043,22 @@ void clif_parse_ProduceMix(int fd,struct map_session_data *sd)
/// 4 = GN_MIX_COOKING
/// 5 = GN_MAKEBOMB
/// 6 = GN_S_PHARMACY
-void clif_parse_Cooking(int fd,struct map_session_data *sd)
-{
- int type = RFIFOW(fd,2);
- int nameid = RFIFOW(fd,4);
- int amount = sd->menuskill_val2?sd->menuskill_val2:1;
- if (type == 6 && sd->menuskill_id != GN_MIX_COOKING && sd->menuskill_id != GN_S_PHARMACY)
- return;
-
- if (pc_istrading(sd)) {
- //Make it fail to avoid shop exploits where you sell something different than you see.
- clif_skill_fail(sd,sd->ud.skillid,USESKILL_FAIL_LEVEL,0);
- clif_menuskill_clear(sd);
- return;
- }
- if (skill_can_produce_mix(sd,nameid,sd->menuskill_val, amount))
- skill_produce_mix(sd,sd->menuskill_id,nameid,0,0,0,amount);
- clif_menuskill_clear(sd);
+void clif_parse_Cooking(int fd,struct map_session_data *sd) {
+ int type = RFIFOW(fd,2);
+ int nameid = RFIFOW(fd,4);
+ int amount = sd->menuskill_val2?sd->menuskill_val2:1;
+ if( type == 6 && sd->menuskill_id != GN_MIX_COOKING && sd->menuskill_id != GN_S_PHARMACY )
+ return;
+
+ if (pc_istrading(sd)) {
+ //Make it fail to avoid shop exploits where you sell something different than you see.
+ clif_skill_fail(sd,sd->ud.skillid,USESKILL_FAIL_LEVEL,0);
+ clif_menuskill_clear(sd);
+ return;
+ }
+ if( skill_can_produce_mix(sd,nameid,sd->menuskill_val, amount) )
+ skill_produce_mix(sd,sd->menuskill_id,nameid,0,0,0,amount);
+ clif_menuskill_clear(sd);
}
@@ -10942,16 +11066,16 @@ void clif_parse_Cooking(int fd,struct map_session_data *sd)
/// 01fd <index>.W <name id>.W <refine>.B <card1>.W <card2>.W <card3>.W <card4>.W
void clif_parse_RepairItem(int fd, struct map_session_data *sd)
{
- if (sd->menuskill_id != BS_REPAIRWEAPON)
- return;
- if (pc_istrading(sd)) {
- //Make it fail to avoid shop exploits where you sell something different than you see.
- clif_skill_fail(sd,sd->ud.skillid,USESKILL_FAIL_LEVEL,0);
- clif_menuskill_clear(sd);
- return;
- }
- skill_repairweapon(sd,RFIFOW(fd,2));
- clif_menuskill_clear(sd);
+ if (sd->menuskill_id != BS_REPAIRWEAPON)
+ return;
+ if (pc_istrading(sd)) {
+ //Make it fail to avoid shop exploits where you sell something different than you see.
+ clif_skill_fail(sd,sd->ud.skillid,USESKILL_FAIL_LEVEL,0);
+ clif_menuskill_clear(sd);
+ return;
+ }
+ skill_repairweapon(sd,RFIFOW(fd,2));
+ clif_menuskill_clear(sd);
}
@@ -10959,19 +11083,19 @@ void clif_parse_RepairItem(int fd, struct map_session_data *sd)
/// 0222 <index>.L
void clif_parse_WeaponRefine(int fd, struct map_session_data *sd)
{
- int idx;
+ int idx;
- if (sd->menuskill_id != WS_WEAPONREFINE) //Packet exploit?
- return;
- if (pc_istrading(sd)) {
- //Make it fail to avoid shop exploits where you sell something different than you see.
- clif_skill_fail(sd,sd->ud.skillid,USESKILL_FAIL_LEVEL,0);
- clif_menuskill_clear(sd);
- return;
- }
- idx = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
- skill_weaponrefine(sd, idx-2);
- clif_menuskill_clear(sd);
+ if (sd->menuskill_id != WS_WEAPONREFINE) //Packet exploit?
+ return;
+ if (pc_istrading(sd)) {
+ //Make it fail to avoid shop exploits where you sell something different than you see.
+ clif_skill_fail(sd,sd->ud.skillid,USESKILL_FAIL_LEVEL,0);
+ clif_menuskill_clear(sd);
+ return;
+ }
+ idx = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
+ skill_weaponrefine(sd, idx-2);
+ clif_menuskill_clear(sd);
}
@@ -10984,18 +11108,19 @@ void clif_parse_WeaponRefine(int fd, struct map_session_data *sd)
/// overflows to choice%256.
void clif_parse_NpcSelectMenu(int fd,struct map_session_data *sd)
{
- int npc_id = RFIFOL(fd,2);
- uint8 select = RFIFOB(fd,6);
+ int npc_id = RFIFOL(fd,2);
+ uint8 select = RFIFOB(fd,6);
- if ((select > sd->npc_menu && select != 0xff) || select == 0) {
- TBL_NPC *nd = map_id2nd(npc_id);
- ShowWarning("Invalid menu selection on npc %d:'%s' - got %d, valid range is [%d..%d] (player AID:%d, CID:%d, name:'%s')!\n", npc_id, (nd)?nd->name:"invalid npc id", select, 1, sd->npc_menu, sd->bl.id, sd->status.char_id, sd->status.name);
- clif_GM_kick(NULL,sd);
- return;
- }
+ if( (select > sd->npc_menu && select != 0xff) || select == 0 )
+ {
+ TBL_NPC* nd = map_id2nd(npc_id);
+ ShowWarning("Invalid menu selection on npc %d:'%s' - got %d, valid range is [%d..%d] (player AID:%d, CID:%d, name:'%s')!\n", npc_id, (nd)?nd->name:"invalid npc id", select, 1, sd->npc_menu, sd->bl.id, sd->status.char_id, sd->status.name);
+ clif_GM_kick(NULL,sd);
+ return;
+ }
- sd->npc_menu = select;
- npc_scriptcont(sd,npc_id);
+ sd->npc_menu = select;
+ npc_scriptcont(sd,npc_id);
}
@@ -11003,7 +11128,7 @@ void clif_parse_NpcSelectMenu(int fd,struct map_session_data *sd)
/// 00b9 <npc id>.L
void clif_parse_NpcNextClicked(int fd,struct map_session_data *sd)
{
- npc_scriptcont(sd,RFIFOL(fd,2));
+ npc_scriptcont(sd,RFIFOL(fd,2));
}
@@ -11011,27 +11136,27 @@ void clif_parse_NpcNextClicked(int fd,struct map_session_data *sd)
/// 0143 <npc id>.L <value>.L
void clif_parse_NpcAmountInput(int fd,struct map_session_data *sd)
{
- int npcid = RFIFOL(fd,2);
- int amount = (int)RFIFOL(fd,6);
+ int npcid = RFIFOL(fd,2);
+ int amount = (int)RFIFOL(fd,6);
- sd->npc_amount = amount;
- npc_scriptcont(sd, npcid);
+ sd->npc_amount = amount;
+ npc_scriptcont(sd, npcid);
}
/// NPC text input dialog value (CZ_INPUT_EDITDLGSTR).
/// 01d5 <packet len>.W <npc id>.L <string>.?B
-void clif_parse_NpcStringInput(int fd, struct map_session_data *sd)
+void clif_parse_NpcStringInput(int fd, struct map_session_data* sd)
{
- int message_len = RFIFOW(fd,2)-8;
- int npcid = RFIFOL(fd,4);
- const char *message = (char *)RFIFOP(fd,8);
+ int message_len = RFIFOW(fd,2)-8;
+ int npcid = RFIFOL(fd,4);
+ const char* message = (char*)RFIFOP(fd,8);
- if (message_len <= 0)
- return; // invalid input
+ if( message_len <= 0 )
+ return; // invalid input
- safestrncpy(sd->npc_str, message, min(message_len,CHATBOX_SIZE));
- npc_scriptcont(sd, npcid);
+ safestrncpy(sd->npc_str, message, min(message_len,CHATBOX_SIZE));
+ npc_scriptcont(sd, npcid);
}
@@ -11039,9 +11164,9 @@ void clif_parse_NpcStringInput(int fd, struct map_session_data *sd)
/// 0146 <npc id>.L
void clif_parse_NpcCloseClicked(int fd,struct map_session_data *sd)
{
- if (!sd->npc_id) //Avoid parsing anything when the script was done with. [Skotlex]
- return;
- npc_scriptcont(sd,RFIFOL(fd,2));
+ if (!sd->npc_id) //Avoid parsing anything when the script was done with. [Skotlex]
+ return;
+ npc_scriptcont(sd,RFIFOL(fd,2));
}
@@ -11051,16 +11176,16 @@ void clif_parse_NpcCloseClicked(int fd,struct map_session_data *sd)
/// -1 = cancel
void clif_parse_ItemIdentify(int fd,struct map_session_data *sd)
{
- short idx = RFIFOW(fd,2);
+ short idx = RFIFOW(fd,2);
- if (sd->menuskill_id != MC_IDENTIFY)
- return;
- if (idx == -1) { // cancel pressed
- clif_menuskill_clear(sd);
- return;
- }
- skill_identify(sd,idx-2);
- clif_menuskill_clear(sd);
+ if (sd->menuskill_id != MC_IDENTIFY)
+ return;
+ if( idx == -1 ) {// cancel pressed
+ clif_menuskill_clear(sd);
+ return;
+ }
+ skill_identify(sd,idx-2);
+ clif_menuskill_clear(sd);
}
@@ -11068,31 +11193,31 @@ void clif_parse_ItemIdentify(int fd,struct map_session_data *sd)
/// 01ae <name id>.W
void clif_parse_SelectArrow(int fd,struct map_session_data *sd)
{
- if (pc_istrading(sd)) {
- //Make it fail to avoid shop exploits where you sell something different than you see.
- clif_skill_fail(sd,sd->ud.skillid,USESKILL_FAIL_LEVEL,0);
- clif_menuskill_clear(sd);
- return;
- }
- switch (sd->menuskill_id) {
- case AC_MAKINGARROW:
- skill_arrow_create(sd,RFIFOW(fd,2));
- break;
- case SA_CREATECON:
- skill_produce_mix(sd,SA_CREATECON,RFIFOW(fd,2),0,0,0, 1);
- break;
- case WL_READING_SB:
- skill_spellbook(sd,RFIFOW(fd,2));
- break;
- case GC_POISONINGWEAPON:
- skill_poisoningweapon(sd,RFIFOW(fd,2));
- break;
- case NC_MAGICDECOY:
- skill_magicdecoy(sd,RFIFOW(fd,2));
- break;
- }
-
- clif_menuskill_clear(sd);
+ if (pc_istrading(sd)) {
+ //Make it fail to avoid shop exploits where you sell something different than you see.
+ clif_skill_fail(sd,sd->ud.skillid,USESKILL_FAIL_LEVEL,0);
+ clif_menuskill_clear(sd);
+ return;
+ }
+ switch( sd->menuskill_id ) {
+ case AC_MAKINGARROW:
+ skill_arrow_create(sd,RFIFOW(fd,2));
+ break;
+ case SA_CREATECON:
+ skill_produce_mix(sd,SA_CREATECON,RFIFOW(fd,2),0,0,0, 1);
+ break;
+ case WL_READING_SB:
+ skill_spellbook(sd,RFIFOW(fd,2));
+ break;
+ case GC_POISONINGWEAPON:
+ skill_poisoningweapon(sd,RFIFOW(fd,2));
+ break;
+ case NC_MAGICDECOY:
+ skill_magicdecoy(sd,RFIFOW(fd,2));
+ break;
+ }
+
+ clif_menuskill_clear(sd);
}
@@ -11100,10 +11225,10 @@ void clif_parse_SelectArrow(int fd,struct map_session_data *sd)
/// 01ce <skill id>.L
void clif_parse_AutoSpell(int fd,struct map_session_data *sd)
{
- if (sd->menuskill_id != SA_AUTOSPELL)
- return;
- skill_autospell(sd,RFIFOL(fd,2));
- clif_menuskill_clear(sd);
+ if (sd->menuskill_id != SA_AUTOSPELL)
+ return;
+ skill_autospell(sd,RFIFOL(fd,2));
+ clif_menuskill_clear(sd);
}
@@ -11111,9 +11236,9 @@ void clif_parse_AutoSpell(int fd,struct map_session_data *sd)
/// 017a <card index>.W
void clif_parse_UseCard(int fd,struct map_session_data *sd)
{
- if (sd->state.trading != 0)
- return;
- clif_use_card(sd,RFIFOW(fd,2)-2);
+ if (sd->state.trading != 0)
+ return;
+ clif_use_card(sd,RFIFOW(fd,2)-2);
}
@@ -11121,9 +11246,9 @@ void clif_parse_UseCard(int fd,struct map_session_data *sd)
/// 017c <card index>.W <equip index>.W
void clif_parse_InsertCard(int fd,struct map_session_data *sd)
{
- if (sd->state.trading != 0)
- return;
- pc_insert_card(sd,RFIFOW(fd,2)-2,RFIFOW(fd,4)-2);
+ if (sd->state.trading != 0)
+ return;
+ pc_insert_card(sd,RFIFOW(fd,2)-2,RFIFOW(fd,4)-2);
}
@@ -11133,10 +11258,10 @@ void clif_parse_InsertCard(int fd,struct map_session_data *sd)
/// There are various variants of this packet, some of them have padding between fields.
void clif_parse_SolveCharName(int fd, struct map_session_data *sd)
{
- int charid;
+ int charid;
- charid = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
- map_reqnickdb(sd, charid);
+ charid = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
+ map_reqnickdb(sd, charid);
}
@@ -11146,33 +11271,32 @@ void clif_parse_SolveCharName(int fd, struct map_session_data *sd)
/// type:
/// 0 = state
/// 1 = skill
-void clif_parse_ResetChar(int fd, struct map_session_data *sd)
-{
- char cmd[15];
+void clif_parse_ResetChar(int fd, struct map_session_data *sd) {
+ char cmd[15];
- if (RFIFOW(fd,2))
- sprintf(cmd,"%cresetskill",atcommand_symbol);
- else
- sprintf(cmd,"%cresetstat",atcommand_symbol);
+ if( RFIFOW(fd,2) )
+ sprintf(cmd,"%cresetskill",atcommand_symbol);
+ else
+ sprintf(cmd,"%cresetstat",atcommand_symbol);
- is_atcommand(fd, sd, cmd, 1);
+ is_atcommand(fd, sd, cmd, 1);
}
/// /lb /nlb (CZ_LOCALBROADCAST).
/// Request to broadcast a message on current map.
/// 019c <packet len>.W <text>.?B
-void clif_parse_LocalBroadcast(int fd, struct map_session_data *sd)
+void clif_parse_LocalBroadcast(int fd, struct map_session_data* sd)
{
- char command[CHAT_SIZE_MAX+16];
- char *msg = (char *)RFIFOP(fd,4);
- unsigned int len = RFIFOW(fd,2)-4;
+ char command[CHAT_SIZE_MAX+16];
+ char* msg = (char*)RFIFOP(fd,4);
+ unsigned int len = RFIFOW(fd,2)-4;
- // as the length varies depending on the command used, just block unreasonably long strings
- mes_len_check(msg, len, CHAT_SIZE_MAX);
+ // as the length varies depending on the command used, just block unreasonably long strings
+ mes_len_check(msg, len, CHAT_SIZE_MAX);
- sprintf(command, "%clkami %s", atcommand_symbol, msg);
- is_atcommand(fd, sd, command, 1);
+ sprintf(command, "%clkami %s", atcommand_symbol, msg);
+ is_atcommand(fd, sd, command, 1);
}
@@ -11182,20 +11306,21 @@ void clif_parse_LocalBroadcast(int fd, struct map_session_data *sd)
/// There are various variants of this packet, some of them have padding between fields.
void clif_parse_MoveToKafra(int fd, struct map_session_data *sd)
{
- int item_index, item_amount;
+ int item_index, item_amount;
- if (pc_istrading(sd))
- return;
+ if (pc_istrading(sd))
+ return;
- item_index = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0])-2;
- item_amount = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]);
- if (item_index < 0 || item_index >= MAX_INVENTORY || item_amount < 1)
- return;
+ item_index = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0])-2;
+ item_amount = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]);
+ if (item_index < 0 || item_index >= MAX_INVENTORY || item_amount < 1)
+ return;
- if (sd->state.storage_flag == 1)
- storage_storageadd(sd, item_index, item_amount);
- else if (sd->state.storage_flag == 2)
- storage_guild_storageadd(sd, item_index, item_amount);
+ if (sd->state.storage_flag == 1)
+ storage_storageadd(sd, item_index, item_amount);
+ else
+ if (sd->state.storage_flag == 2)
+ storage_guild_storageadd(sd, item_index, item_amount);
}
@@ -11205,15 +11330,16 @@ void clif_parse_MoveToKafra(int fd, struct map_session_data *sd)
/// There are various variants of this packet, some of them have padding between fields.
void clif_parse_MoveFromKafra(int fd,struct map_session_data *sd)
{
- int item_index, item_amount;
+ int item_index, item_amount;
- item_index = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0])-1;
- item_amount = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]);
+ item_index = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0])-1;
+ item_amount = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]);
- if (sd->state.storage_flag == 1)
- storage_storageget(sd, item_index, item_amount);
- else if (sd->state.storage_flag == 2)
- storage_guild_storageget(sd, item_index, item_amount);
+ if (sd->state.storage_flag == 1)
+ storage_storageget(sd, item_index, item_amount);
+ else
+ if(sd->state.storage_flag == 2)
+ storage_guild_storageget(sd, item_index, item_amount);
}
@@ -11221,15 +11347,16 @@ void clif_parse_MoveFromKafra(int fd,struct map_session_data *sd)
/// 0129 <index>.W <amount>.L
void clif_parse_MoveToKafraFromCart(int fd, struct map_session_data *sd)
{
- if (sd->state.vending)
- return;
- if (!pc_iscarton(sd))
- return;
+ if( sd->state.vending )
+ return;
+ if (!pc_iscarton(sd))
+ return;
- if (sd->state.storage_flag == 1)
- storage_storageaddfromcart(sd, RFIFOW(fd,2) - 2, RFIFOL(fd,4));
- else if (sd->state.storage_flag == 2)
- storage_guild_storageaddfromcart(sd, RFIFOW(fd,2) - 2, RFIFOL(fd,4));
+ if (sd->state.storage_flag == 1)
+ storage_storageaddfromcart(sd, RFIFOW(fd,2) - 2, RFIFOL(fd,4));
+ else
+ if (sd->state.storage_flag == 2)
+ storage_guild_storageaddfromcart(sd, RFIFOW(fd,2) - 2, RFIFOL(fd,4));
}
@@ -11237,15 +11364,16 @@ void clif_parse_MoveToKafraFromCart(int fd, struct map_session_data *sd)
/// 0128 <index>.W <amount>.L
void clif_parse_MoveFromKafraToCart(int fd, struct map_session_data *sd)
{
- if (sd->state.vending)
- return;
- if (!pc_iscarton(sd))
- return;
+ if( sd->state.vending )
+ return;
+ if (!pc_iscarton(sd))
+ return;
- if (sd->state.storage_flag == 1)
- storage_storagegettocart(sd, RFIFOW(fd,2)-1, RFIFOL(fd,4));
- else if (sd->state.storage_flag == 2)
- storage_guild_storagegettocart(sd, RFIFOW(fd,2)-1, RFIFOL(fd,4));
+ if (sd->state.storage_flag == 1)
+ storage_storagegettocart(sd, RFIFOW(fd,2)-1, RFIFOL(fd,4));
+ else
+ if (sd->state.storage_flag == 2)
+ storage_guild_storagegettocart(sd, RFIFOW(fd,2)-1, RFIFOL(fd,4));
}
@@ -11253,10 +11381,11 @@ void clif_parse_MoveFromKafraToCart(int fd, struct map_session_data *sd)
/// 00f7
void clif_parse_CloseKafra(int fd, struct map_session_data *sd)
{
- if (sd->state.storage_flag == 1)
- storage_storageclose(sd);
- else if (sd->state.storage_flag == 2)
- storage_guild_storageclose(sd);
+ if( sd->state.storage_flag == 1 )
+ storage_storageclose(sd);
+ else
+ if( sd->state.storage_flag == 2 )
+ storage_guild_storageclose(sd);
}
@@ -11268,14 +11397,14 @@ void clif_parse_CloseKafra(int fd, struct map_session_data *sd)
/// 8 = too many wrong passwords
/// ? = ignored
/// NOTE: This packet is only available on certain non-kRO clients.
-void clif_storagepassword(struct map_session_data *sd, short info)
+void clif_storagepassword(struct map_session_data* sd, short info)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x23a));
- WFIFOW(fd,0) = 0x23a;
- WFIFOW(fd,2) = info;
- WFIFOSET(fd,packet_len(0x23a));
+ WFIFOHEAD(fd,packet_len(0x23a));
+ WFIFOW(fd,0) = 0x23a;
+ WFIFOW(fd,2) = info;
+ WFIFOSET(fd,packet_len(0x23a));
}
@@ -11287,7 +11416,7 @@ void clif_storagepassword(struct map_session_data *sd, short info)
/// NOTE: This packet is only available on certain non-kRO clients.
void clif_parse_StoragePassword(int fd, struct map_session_data *sd)
{
- //TODO
+ //TODO
}
@@ -11301,15 +11430,15 @@ void clif_parse_StoragePassword(int fd, struct map_session_data *sd)
/// 8 = too many wrong passwords
/// ? = ignored
/// NOTE: This packet is only available on certain non-kRO clients.
-void clif_storagepassword_result(struct map_session_data *sd, short result, short error_count)
+void clif_storagepassword_result(struct map_session_data* sd, short result, short error_count)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x23c));
- WFIFOW(fd,0) = 0x23c;
- WFIFOW(fd,2) = result;
- WFIFOW(fd,4) = error_count;
- WFIFOSET(fd,packet_len(0x23c));
+ WFIFOHEAD(fd,packet_len(0x23c));
+ WFIFOW(fd,0) = 0x23c;
+ WFIFOW(fd,2) = result;
+ WFIFOW(fd,4) = error_count;
+ WFIFOSET(fd,packet_len(0x23c));
}
@@ -11318,40 +11447,42 @@ void clif_storagepassword_result(struct map_session_data *sd, short result, shor
/// 01e8 <party name>.24B <item pickup rule>.B <item share rule>.B (CZ_MAKE_GROUP2)
void clif_parse_CreateParty(int fd, struct map_session_data *sd)
{
- char *name = (char *)RFIFOP(fd,2);
- name[NAME_LENGTH-1] = '\0';
+ char* name = (char*)RFIFOP(fd,2);
+ name[NAME_LENGTH-1] = '\0';
- if (map[sd->bl.m].flag.partylock) {
- // Party locked.
- clif_displaymessage(fd, msg_txt(227));
- return;
- }
- if (battle_config.basic_skill_check && pc_checkskill(sd,NV_BASIC) < 7) {
- clif_skill_fail(sd,1,USESKILL_FAIL_LEVEL,4);
- return;
- }
+ if( map[sd->bl.m].flag.partylock )
+ {// Party locked.
+ clif_displaymessage(fd, msg_txt(227));
+ return;
+ }
+ if( battle_config.basic_skill_check && pc_checkskill(sd,NV_BASIC) < 7 )
+ {
+ clif_skill_fail(sd,1,USESKILL_FAIL_LEVEL,4);
+ return;
+ }
- party_create(sd,name,0,0);
+ party_create(sd,name,0,0);
}
void clif_parse_CreateParty2(int fd, struct map_session_data *sd)
{
- char *name = (char *)RFIFOP(fd,2);
- int item1 = RFIFOB(fd,26);
- int item2 = RFIFOB(fd,27);
- name[NAME_LENGTH-1] = '\0';
+ char* name = (char*)RFIFOP(fd,2);
+ int item1 = RFIFOB(fd,26);
+ int item2 = RFIFOB(fd,27);
+ name[NAME_LENGTH-1] = '\0';
- if (map[sd->bl.m].flag.partylock) {
- // Party locked.
- clif_displaymessage(fd, msg_txt(227));
- return;
- }
- if (battle_config.basic_skill_check && pc_checkskill(sd,NV_BASIC) < 7) {
- clif_skill_fail(sd,1,USESKILL_FAIL_LEVEL,4);
- return;
- }
+ if( map[sd->bl.m].flag.partylock )
+ {// Party locked.
+ clif_displaymessage(fd, msg_txt(227));
+ return;
+ }
+ if( battle_config.basic_skill_check && pc_checkskill(sd,NV_BASIC) < 7 )
+ {
+ clif_skill_fail(sd,1,USESKILL_FAIL_LEVEL,4);
+ return;
+ }
- party_create(sd,name,item1,item2);
+ party_create(sd,name,item1,item2);
}
@@ -11360,46 +11491,46 @@ void clif_parse_CreateParty2(int fd, struct map_session_data *sd)
/// 02c4 <char name>.24B (CZ_PARTY_JOIN_REQ)
void clif_parse_PartyInvite(int fd, struct map_session_data *sd)
{
- struct map_session_data *t_sd;
+ struct map_session_data *t_sd;
- if (map[sd->bl.m].flag.partylock) {
- // Party locked.
- clif_displaymessage(fd, msg_txt(227));
- return;
- }
+ if(map[sd->bl.m].flag.partylock)
+ {// Party locked.
+ clif_displaymessage(fd, msg_txt(227));
+ return;
+ }
- t_sd = map_id2sd(RFIFOL(fd,2));
+ t_sd = map_id2sd(RFIFOL(fd,2));
- if (t_sd && t_sd->state.noask) {
- // @noask [LuzZza]
- clif_noask_sub(sd, t_sd, 1);
- return;
- }
+ if(t_sd && t_sd->state.noask)
+ {// @noask [LuzZza]
+ clif_noask_sub(sd, t_sd, 1);
+ return;
+ }
- party_invite(sd, t_sd);
+ party_invite(sd, t_sd);
}
void clif_parse_PartyInvite2(int fd, struct map_session_data *sd)
{
- struct map_session_data *t_sd;
- char *name = (char *)RFIFOP(fd,2);
- name[NAME_LENGTH-1] = '\0';
+ struct map_session_data *t_sd;
+ char *name = (char*)RFIFOP(fd,2);
+ name[NAME_LENGTH-1] = '\0';
- if (map[sd->bl.m].flag.partylock) {
- // Party locked.
- clif_displaymessage(fd, msg_txt(227));
- return;
- }
+ if(map[sd->bl.m].flag.partylock)
+ {// Party locked.
+ clif_displaymessage(fd, msg_txt(227));
+ return;
+ }
- t_sd = map_nick2sd(name);
+ t_sd = map_nick2sd(name);
- if (t_sd && t_sd->state.noask) {
- // @noask [LuzZza]
- clif_noask_sub(sd, t_sd, 1);
- return;
- }
+ if(t_sd && t_sd->state.noask)
+ {// @noask [LuzZza]
+ clif_noask_sub(sd, t_sd, 1);
+ return;
+ }
- party_invite(sd, t_sd);
+ party_invite(sd, t_sd);
}
@@ -11411,12 +11542,12 @@ void clif_parse_PartyInvite2(int fd, struct map_session_data *sd)
/// 1 = accept
void clif_parse_ReplyPartyInvite(int fd,struct map_session_data *sd)
{
- party_reply_invite(sd,RFIFOL(fd,2),RFIFOL(fd,6));
+ party_reply_invite(sd,RFIFOL(fd,2),RFIFOL(fd,6));
}
void clif_parse_ReplyPartyInvite2(int fd,struct map_session_data *sd)
{
- party_reply_invite(sd,RFIFOL(fd,2),RFIFOB(fd,6));
+ party_reply_invite(sd,RFIFOL(fd,2),RFIFOB(fd,6));
}
@@ -11424,12 +11555,12 @@ void clif_parse_ReplyPartyInvite2(int fd,struct map_session_data *sd)
/// 0100
void clif_parse_LeaveParty(int fd, struct map_session_data *sd)
{
- if (map[sd->bl.m].flag.partylock) {
- //Guild locked.
- clif_displaymessage(fd, msg_txt(227));
- return;
- }
- party_leave(sd);
+ if(map[sd->bl.m].flag.partylock)
+ { //Guild locked.
+ clif_displaymessage(fd, msg_txt(227));
+ return;
+ }
+ party_leave(sd);
}
@@ -11437,12 +11568,12 @@ void clif_parse_LeaveParty(int fd, struct map_session_data *sd)
/// 0103 <account id>.L <char name>.24B
void clif_parse_RemovePartyMember(int fd, struct map_session_data *sd)
{
- if (map[sd->bl.m].flag.partylock) {
- //Guild locked.
- clif_displaymessage(fd, msg_txt(227));
- return;
- }
- party_removemember(sd,RFIFOL(fd,2),(char *)RFIFOP(fd,6));
+ if(map[sd->bl.m].flag.partylock)
+ { //Guild locked.
+ clif_displaymessage(fd, msg_txt(227));
+ return;
+ }
+ party_removemember(sd,RFIFOL(fd,2),(char*)RFIFOP(fd,6));
}
@@ -11451,68 +11582,68 @@ void clif_parse_RemovePartyMember(int fd, struct map_session_data *sd)
/// 07d7 <exp share rule>.L <item pickup rule>.B <item share rule>.B (CZ_GROUPINFO_CHANGE_V2)
void clif_parse_PartyChangeOption(int fd, struct map_session_data *sd)
{
- struct party_data *p;
- int i;
+ struct party_data *p;
+ int i;
- if (!sd->status.party_id)
- return;
+ if( !sd->status.party_id )
+ return;
- p = party_search(sd->status.party_id);
- if (p == NULL)
- return;
+ p = party_search(sd->status.party_id);
+ if( p == NULL )
+ return;
- ARR_FIND(0, MAX_PARTY, i, p->data[i].sd == sd);
- if (i == MAX_PARTY)
- return; //Shouldn't happen
+ ARR_FIND( 0, MAX_PARTY, i, p->data[i].sd == sd );
+ if( i == MAX_PARTY )
+ return; //Shouldn't happen
- if (!p->party.member[i].leader)
- return;
+ if( !p->party.member[i].leader )
+ return;
#if PACKETVER < 20090603
- //Client can't change the item-field
- party_changeoption(sd, RFIFOL(fd,2), p->party.item);
+ //Client can't change the item-field
+ party_changeoption(sd, RFIFOL(fd,2), p->party.item);
#else
- party_changeoption(sd, RFIFOL(fd,2), ((RFIFOB(fd,6)?1:0)|(RFIFOB(fd,7)?2:0)));
+ party_changeoption(sd, RFIFOL(fd,2), ((RFIFOB(fd,6)?1:0)|(RFIFOB(fd,7)?2:0)));
#endif
}
/// Validates and processes party messages (CZ_REQUEST_CHAT_PARTY).
/// 0108 <packet len>.W <text>.?B (<name> : <message>) 00
-void clif_parse_PartyMessage(int fd, struct map_session_data *sd)
+void clif_parse_PartyMessage(int fd, struct map_session_data* sd)
{
- const char *text = (char *)RFIFOP(fd,4);
- int textlen = RFIFOW(fd,2) - 4;
+ const char* text = (char*)RFIFOP(fd,4);
+ int textlen = RFIFOW(fd,2) - 4;
- char *name, *message;
- int namelen, messagelen;
+ char *name, *message;
+ int namelen, messagelen;
- // validate packet and retrieve name and message
- if (!clif_process_message(sd, 0, &name, &namelen, &message, &messagelen))
- return;
+ // validate packet and retrieve name and message
+ if( !clif_process_message(sd, 0, &name, &namelen, &message, &messagelen) )
+ return;
- if (is_atcommand(fd, sd, message, 1))
- return;
+ if( is_atcommand(fd, sd, message, 1) )
+ return;
- if (sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT))
- return;
+ if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) )
+ return;
- if (battle_config.min_chat_delay) {
- //[Skotlex]
- if (DIFF_TICK(sd->cantalk_tick, gettick()) > 0)
- return;
- sd->cantalk_tick = gettick() + battle_config.min_chat_delay;
- }
+ if( battle_config.min_chat_delay )
+ { //[Skotlex]
+ if (DIFF_TICK(sd->cantalk_tick, gettick()) > 0)
+ return;
+ sd->cantalk_tick = gettick() + battle_config.min_chat_delay;
+ }
- party_send_message(sd, text, textlen);
+ party_send_message(sd, text, textlen);
}
/// Changes Party Leader (CZ_CHANGE_GROUP_MASTER).
/// 07da <account id>.L
-void clif_parse_PartyChangeLeader(int fd, struct map_session_data *sd)
+void clif_parse_PartyChangeLeader(int fd, struct map_session_data* sd)
{
- party_changeleader(sd, map_id2sd(RFIFOL(fd,2)));
+ party_changeleader(sd, map_id2sd(RFIFOL(fd,2)));
}
@@ -11521,17 +11652,17 @@ void clif_parse_PartyChangeLeader(int fd, struct map_session_data *sd)
/// Request to register a party booking advertisment (CZ_PARTY_BOOKING_REQ_REGISTER).
/// 0802 <level>.W <map id>.W { <job>.W }*6
-void clif_parse_PartyBookingRegisterReq(int fd, struct map_session_data *sd)
+void clif_parse_PartyBookingRegisterReq(int fd, struct map_session_data* sd)
{
- short level = RFIFOW(fd,2);
- short mapid = RFIFOW(fd,4);
- short job[PARTY_BOOKING_JOBS];
- int i;
+ short level = RFIFOW(fd,2);
+ short mapid = RFIFOW(fd,4);
+ short job[PARTY_BOOKING_JOBS];
+ int i;
- for (i=0; i<PARTY_BOOKING_JOBS; i++)
- job[i] = RFIFOB(fd,6+i*2);
+ for(i=0; i<PARTY_BOOKING_JOBS; i++)
+ job[i] = RFIFOB(fd,6+i*2);
- party_booking_register(sd, level, mapid, job);
+ party_booking_register(sd, level, mapid, job);
}
@@ -11543,26 +11674,26 @@ void clif_parse_PartyBookingRegisterReq(int fd, struct map_session_data *sd)
/// 2 = already registered
void clif_PartyBookingRegisterAck(struct map_session_data *sd, int flag)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x803));
- WFIFOW(fd,0) = 0x803;
- WFIFOW(fd,2) = flag;
- WFIFOSET(fd,packet_len(0x803));
+ WFIFOHEAD(fd,packet_len(0x803));
+ WFIFOW(fd,0) = 0x803;
+ WFIFOW(fd,2) = flag;
+ WFIFOSET(fd,packet_len(0x803));
}
/// Request to search for party booking advertisments (CZ_PARTY_BOOKING_REQ_SEARCH).
/// 0804 <level>.W <map id>.W <job>.W <last index>.L <result count>.W
-void clif_parse_PartyBookingSearchReq(int fd, struct map_session_data *sd)
+void clif_parse_PartyBookingSearchReq(int fd, struct map_session_data* sd)
{
- short level = RFIFOW(fd,2);
- short mapid = RFIFOW(fd,4);
- short job = RFIFOW(fd,6);
- unsigned long lastindex = RFIFOL(fd,8);
- short resultcount = RFIFOW(fd,12);
+ short level = RFIFOW(fd,2);
+ short mapid = RFIFOW(fd,4);
+ short job = RFIFOW(fd,6);
+ unsigned long lastindex = RFIFOL(fd,8);
+ short resultcount = RFIFOW(fd,12);
- party_booking_search(sd, level, mapid, job, lastindex, resultcount);
+ party_booking_search(sd, level, mapid, job, lastindex, resultcount);
}
@@ -11571,35 +11702,36 @@ void clif_parse_PartyBookingSearchReq(int fd, struct map_session_data *sd)
/// more results:
/// 0 = no
/// 1 = yes
-void clif_PartyBookingSearchAck(int fd, struct party_booking_ad_info **results, int count, bool more_result)
-{
- int i, j;
- int size = sizeof(struct party_booking_ad_info); // structure size (48)
- struct party_booking_ad_info *pb_ad;
- WFIFOHEAD(fd,size*count + 5);
- WFIFOW(fd,0) = 0x805;
- WFIFOW(fd,2) = size*count + 5;
- WFIFOB(fd,4) = more_result;
- for (i=0; i<count; i++) {
- pb_ad = results[i];
- WFIFOL(fd,i*size+5) = pb_ad->index;
- memcpy(WFIFOP(fd,i*size+9),pb_ad->charname,NAME_LENGTH);
- WFIFOL(fd,i*size+33) = pb_ad->starttime; // FIXME: This is expire time
- WFIFOW(fd,i*size+37) = pb_ad->p_detail.level;
- WFIFOW(fd,i*size+39) = pb_ad->p_detail.mapid;
- for (j=0; j<PARTY_BOOKING_JOBS; j++)
- WFIFOW(fd,i*size+41+j*2) = pb_ad->p_detail.job[j];
- }
- WFIFOSET(fd,WFIFOW(fd,2));
+void clif_PartyBookingSearchAck(int fd, struct party_booking_ad_info** results, int count, bool more_result)
+{
+ int i, j;
+ int size = sizeof(struct party_booking_ad_info); // structure size (48)
+ struct party_booking_ad_info *pb_ad;
+ WFIFOHEAD(fd,size*count + 5);
+ WFIFOW(fd,0) = 0x805;
+ WFIFOW(fd,2) = size*count + 5;
+ WFIFOB(fd,4) = more_result;
+ for(i=0; i<count; i++)
+ {
+ pb_ad = results[i];
+ WFIFOL(fd,i*size+5) = pb_ad->index;
+ memcpy(WFIFOP(fd,i*size+9),pb_ad->charname,NAME_LENGTH);
+ WFIFOL(fd,i*size+33) = pb_ad->starttime; // FIXME: This is expire time
+ WFIFOW(fd,i*size+37) = pb_ad->p_detail.level;
+ WFIFOW(fd,i*size+39) = pb_ad->p_detail.mapid;
+ for(j=0; j<PARTY_BOOKING_JOBS; j++)
+ WFIFOW(fd,i*size+41+j*2) = pb_ad->p_detail.job[j];
+ }
+ WFIFOSET(fd,WFIFOW(fd,2));
}
/// Request to delete own party booking advertisment (CZ_PARTY_BOOKING_REQ_DELETE).
/// 0806
-void clif_parse_PartyBookingDeleteReq(int fd, struct map_session_data *sd)
+void clif_parse_PartyBookingDeleteReq(int fd, struct map_session_data* sd)
{
- if (party_booking_delete(sd))
- clif_PartyBookingDeleteAck(sd, 0);
+ if(party_booking_delete(sd))
+ clif_PartyBookingDeleteAck(sd, 0);
}
@@ -11610,131 +11742,131 @@ void clif_parse_PartyBookingDeleteReq(int fd, struct map_session_data *sd)
/// 1 = success (auto-removed expired ad)
/// 2 = failure
/// 3 = nothing registered
-void clif_PartyBookingDeleteAck(struct map_session_data *sd, int flag)
+void clif_PartyBookingDeleteAck(struct map_session_data* sd, int flag)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x807));
- WFIFOW(fd,0) = 0x807;
- WFIFOW(fd,2) = flag;
- WFIFOSET(fd,packet_len(0x807));
+ WFIFOHEAD(fd,packet_len(0x807));
+ WFIFOW(fd,0) = 0x807;
+ WFIFOW(fd,2) = flag;
+ WFIFOSET(fd,packet_len(0x807));
}
/// Request to update party booking advertisment (CZ_PARTY_BOOKING_REQ_UPDATE).
/// 0808 { <job>.W }*6
-void clif_parse_PartyBookingUpdateReq(int fd, struct map_session_data *sd)
+void clif_parse_PartyBookingUpdateReq(int fd, struct map_session_data* sd)
{
- short job[PARTY_BOOKING_JOBS];
- int i;
+ short job[PARTY_BOOKING_JOBS];
+ int i;
- for (i=0; i<PARTY_BOOKING_JOBS; i++)
- job[i] = RFIFOW(fd,2+i*2);
+ for(i=0; i<PARTY_BOOKING_JOBS; i++)
+ job[i] = RFIFOW(fd,2+i*2);
- party_booking_update(sd, job);
+ party_booking_update(sd, job);
}
/// Notification about new party booking advertisment (ZC_PARTY_BOOKING_NOTIFY_INSERT).
/// 0809 <index>.L <char name>.24B <expire time>.L <level>.W <map id>.W { <job>.W }*6
-void clif_PartyBookingInsertNotify(struct map_session_data *sd, struct party_booking_ad_info *pb_ad)
+void clif_PartyBookingInsertNotify(struct map_session_data* sd, struct party_booking_ad_info* pb_ad)
{
- int i;
- uint8 buf[38+PARTY_BOOKING_JOBS*2];
+ int i;
+ uint8 buf[38+PARTY_BOOKING_JOBS*2];
- if (pb_ad == NULL) return;
+ if(pb_ad == NULL) return;
- WBUFW(buf,0) = 0x809;
- WBUFL(buf,2) = pb_ad->index;
- memcpy(WBUFP(buf,6),pb_ad->charname,NAME_LENGTH);
- WBUFL(buf,30) = pb_ad->starttime; // FIXME: This is expire time
- WBUFW(buf,34) = pb_ad->p_detail.level;
- WBUFW(buf,36) = pb_ad->p_detail.mapid;
- for (i=0; i<PARTY_BOOKING_JOBS; i++)
- WBUFW(buf,38+i*2) = pb_ad->p_detail.job[i];
+ WBUFW(buf,0) = 0x809;
+ WBUFL(buf,2) = pb_ad->index;
+ memcpy(WBUFP(buf,6),pb_ad->charname,NAME_LENGTH);
+ WBUFL(buf,30) = pb_ad->starttime; // FIXME: This is expire time
+ WBUFW(buf,34) = pb_ad->p_detail.level;
+ WBUFW(buf,36) = pb_ad->p_detail.mapid;
+ for(i=0; i<PARTY_BOOKING_JOBS; i++)
+ WBUFW(buf,38+i*2) = pb_ad->p_detail.job[i];
- clif_send(buf, packet_len(0x809), &sd->bl, ALL_CLIENT);
+ clif_send(buf, packet_len(0x809), &sd->bl, ALL_CLIENT);
}
/// Notification about updated party booking advertisment (ZC_PARTY_BOOKING_NOTIFY_UPDATE).
/// 080a <index>.L { <job>.W }*6
-void clif_PartyBookingUpdateNotify(struct map_session_data *sd, struct party_booking_ad_info *pb_ad)
+void clif_PartyBookingUpdateNotify(struct map_session_data* sd, struct party_booking_ad_info* pb_ad)
{
- int i;
- uint8 buf[6+PARTY_BOOKING_JOBS*2];
+ int i;
+ uint8 buf[6+PARTY_BOOKING_JOBS*2];
- if (pb_ad == NULL) return;
+ if(pb_ad == NULL) return;
- WBUFW(buf,0) = 0x80a;
- WBUFL(buf,2) = pb_ad->index;
- for (i=0; i<PARTY_BOOKING_JOBS; i++)
- WBUFW(buf,6+i*2) = pb_ad->p_detail.job[i];
- clif_send(buf,packet_len(0x80a),&sd->bl,ALL_CLIENT); // Now UPDATE all client.
+ WBUFW(buf,0) = 0x80a;
+ WBUFL(buf,2) = pb_ad->index;
+ for(i=0; i<PARTY_BOOKING_JOBS; i++)
+ WBUFW(buf,6+i*2) = pb_ad->p_detail.job[i];
+ clif_send(buf,packet_len(0x80a),&sd->bl,ALL_CLIENT); // Now UPDATE all client.
}
/// Notification about deleted party booking advertisment (ZC_PARTY_BOOKING_NOTIFY_DELETE).
/// 080b <index>.L
-void clif_PartyBookingDeleteNotify(struct map_session_data *sd, int index)
+void clif_PartyBookingDeleteNotify(struct map_session_data* sd, int index)
{
- uint8 buf[6];
+ uint8 buf[6];
- WBUFW(buf,0) = 0x80b;
- WBUFL(buf,2) = index;
+ WBUFW(buf,0) = 0x80b;
+ WBUFL(buf,2) = index;
- clif_send(buf, packet_len(0x80b), &sd->bl, ALL_CLIENT); // Now UPDATE all client.
+ clif_send(buf, packet_len(0x80b), &sd->bl, ALL_CLIENT); // Now UPDATE all client.
}
/// Request to close own vending (CZ_REQ_CLOSESTORE).
/// 012e
-void clif_parse_CloseVending(int fd, struct map_session_data *sd)
+void clif_parse_CloseVending(int fd, struct map_session_data* sd)
{
- vending_closevending(sd);
+ vending_closevending(sd);
}
/// Request to open a vending shop (CZ_REQ_BUY_FROMMC).
/// 0130 <account id>.L
-void clif_parse_VendingListReq(int fd, struct map_session_data *sd)
+void clif_parse_VendingListReq(int fd, struct map_session_data* sd)
{
- if (sd->npc_id) {
- // using an NPC
- return;
- }
- vending_vendinglistreq(sd,RFIFOL(fd,2));
+ if( sd->npc_id )
+ {// using an NPC
+ return;
+ }
+ vending_vendinglistreq(sd,RFIFOL(fd,2));
}
/// Shop item(s) purchase request (CZ_PC_PURCHASE_ITEMLIST_FROMMC).
/// 0134 <packet len>.W <account id>.L { <amount>.W <index>.W }*
-void clif_parse_PurchaseReq(int fd, struct map_session_data *sd)
+void clif_parse_PurchaseReq(int fd, struct map_session_data* sd)
{
- int len = (int)RFIFOW(fd,2) - 8;
- int id = (int)RFIFOL(fd,4);
- const uint8 *data = (uint8 *)RFIFOP(fd,8);
+ int len = (int)RFIFOW(fd,2) - 8;
+ int id = (int)RFIFOL(fd,4);
+ const uint8* data = (uint8*)RFIFOP(fd,8);
- vending_purchasereq(sd, id, sd->vended_id, data, len/4);
+ vending_purchasereq(sd, id, sd->vended_id, data, len/4);
- // whether it fails or not, the buy window is closed
- sd->vended_id = 0;
+ // whether it fails or not, the buy window is closed
+ sd->vended_id = 0;
}
/// Shop item(s) purchase request (CZ_PC_PURCHASE_ITEMLIST_FROMMC2).
/// 0801 <packet len>.W <account id>.L <unique id>.L { <amount>.W <index>.W }*
-void clif_parse_PurchaseReq2(int fd, struct map_session_data *sd)
+void clif_parse_PurchaseReq2(int fd, struct map_session_data* sd)
{
- int len = (int)RFIFOW(fd,2) - 12;
- int aid = (int)RFIFOL(fd,4);
- int uid = (int)RFIFOL(fd,8);
- const uint8 *data = (uint8 *)RFIFOP(fd,12);
+ int len = (int)RFIFOW(fd,2) - 12;
+ int aid = (int)RFIFOL(fd,4);
+ int uid = (int)RFIFOL(fd,8);
+ const uint8* data = (uint8*)RFIFOP(fd,12);
- vending_purchasereq(sd, aid, uid, data, len/4);
+ vending_purchasereq(sd, aid, uid, data, len/4);
- // whether it fails or not, the buy window is closed
- sd->vended_id = 0;
+ // whether it fails or not, the buy window is closed
+ sd->vended_id = 0;
}
@@ -11744,36 +11876,36 @@ void clif_parse_PurchaseReq2(int fd, struct map_session_data *sd)
/// result:
/// 0 = canceled
/// 1 = open
-void clif_parse_OpenVending(int fd, struct map_session_data *sd)
-{
- short len = (short)RFIFOW(fd,2) - 85;
- const char *message = (char *)RFIFOP(fd,4);
- bool flag = (bool)RFIFOB(fd,84);
- const uint8 *data = (uint8 *)RFIFOP(fd,85);
-
- if (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOROOM)
- return;
- if (map[sd->bl.m].flag.novending) {
- clif_displaymessage(sd->fd, msg_txt(276)); // "You can't open a shop on this map"
- return;
- }
- if (map_getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKNOVENDING)) {
- clif_displaymessage(sd->fd, msg_txt(204)); // "You can't open a shop on this cell."
- return;
- }
+void clif_parse_OpenVending(int fd, struct map_session_data* sd)
+{
+ short len = (short)RFIFOW(fd,2) - 85;
+ const char* message = (char*)RFIFOP(fd,4);
+ bool flag = (bool)RFIFOB(fd,84);
+ const uint8* data = (uint8*)RFIFOP(fd,85);
- if (vending_checknearnpc(&sd->bl)) {
- char output[150];
- sprintf(output, msg_txt(662), battle_config.min_npc_vending_distance);
- clif_displaymessage(sd->fd, output);
- clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0);
- return;
- }
+ if( sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOROOM )
+ return;
+ if( map[sd->bl.m].flag.novending ) {
+ clif_displaymessage (sd->fd, msg_txt(276)); // "You can't open a shop on this map"
+ return;
+ }
+ if( map_getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKNOVENDING) ) {
+ clif_displaymessage (sd->fd, msg_txt(204)); // "You can't open a shop on this cell."
+ return;
+ }
- if (message[0] == '\0') // invalid input
- return;
+ if( vending_checknearnpc(&sd->bl) ) {
+ char output[150];
+ sprintf(output, msg_txt(662), battle_config.min_npc_vending_distance);
+ clif_displaymessage(sd->fd, output);
+ clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0);
+ return;
+ }
- vending_openvending(sd, message, flag, data, len/8);
+ if( message[0] == '\0' ) // invalid input
+ return;
+
+ vending_openvending(sd, message, flag, data, len/8);
}
@@ -11781,16 +11913,16 @@ void clif_parse_OpenVending(int fd, struct map_session_data *sd)
/// 0165 <char id>.L <guild name>.24B
void clif_parse_CreateGuild(int fd,struct map_session_data *sd)
{
- char *name = (char *)RFIFOP(fd,6);
- name[NAME_LENGTH-1] = '\0';
+ char* name = (char*)RFIFOP(fd,6);
+ name[NAME_LENGTH-1] = '\0';
- if (map[sd->bl.m].flag.guildlock) {
- //Guild locked.
- clif_displaymessage(fd, msg_txt(228));
- return;
- }
+ if(map[sd->bl.m].flag.guildlock)
+ { //Guild locked.
+ clif_displaymessage(fd, msg_txt(228));
+ return;
+ }
- guild_create(sd, name);
+ guild_create(sd, name);
}
@@ -11798,7 +11930,7 @@ void clif_parse_CreateGuild(int fd,struct map_session_data *sd)
/// 014d
void clif_parse_GuildCheckMaster(int fd, struct map_session_data *sd)
{
- clif_guild_masterormember(sd);
+ clif_guild_masterormember(sd);
}
@@ -11814,32 +11946,33 @@ void clif_parse_GuildCheckMaster(int fd, struct map_session_data *sd)
/// 6 = notice
void clif_parse_GuildRequestInfo(int fd, struct map_session_data *sd)
{
- if (!sd->status.guild_id && !sd->bg_id)
- return;
-
- switch (RFIFOL(fd,2)) {
- case 0: // Basic Information Guild, hostile alliance information
- clif_guild_basicinfo(sd);
- clif_guild_allianceinfo(sd);
- break;
- case 1: // Members list, list job title
- clif_guild_positionnamelist(sd);
- clif_guild_memberlist(sd);
- break;
- case 2: // List job title, title information list
- clif_guild_positionnamelist(sd);
- clif_guild_positioninfolist(sd);
- break;
- case 3: // Skill list
- clif_guild_skillinfo(sd);
- break;
- case 4: // Expulsion list
- clif_guild_expulsionlist(sd);
- break;
- default:
- ShowError("clif: guild request info: unknown type %d\n", RFIFOL(fd,2));
- break;
- }
+ if( !sd->status.guild_id && !sd->bg_id )
+ return;
+
+ switch( RFIFOL(fd,2) )
+ {
+ case 0: // Basic Information Guild, hostile alliance information
+ clif_guild_basicinfo(sd);
+ clif_guild_allianceinfo(sd);
+ break;
+ case 1: // Members list, list job title
+ clif_guild_positionnamelist(sd);
+ clif_guild_memberlist(sd);
+ break;
+ case 2: // List job title, title information list
+ clif_guild_positionnamelist(sd);
+ clif_guild_positioninfolist(sd);
+ break;
+ case 3: // Skill list
+ clif_guild_skillinfo(sd);
+ break;
+ case 4: // Expulsion list
+ clif_guild_expulsionlist(sd);
+ break;
+ default:
+ ShowError("clif: guild request info: unknown type %d\n", RFIFOL(fd,2));
+ break;
+ }
}
@@ -11847,14 +11980,14 @@ void clif_parse_GuildRequestInfo(int fd, struct map_session_data *sd)
/// 0161 <packet len>.W { <position id>.L <mode>.L <ranking>.L <pay rate>.L <name>.24B }*
void clif_parse_GuildChangePositionInfo(int fd, struct map_session_data *sd)
{
- int i;
+ int i;
- if (!sd->state.gmaster_flag)
- return;
+ if(!sd->state.gmaster_flag)
+ return;
- for (i = 4; i < RFIFOW(fd,2); i += 40) {
- guild_change_position(sd->status.guild_id, RFIFOL(fd,i), RFIFOL(fd,i+4), RFIFOL(fd,i+12), (char *)RFIFOP(fd,i+16));
- }
+ for(i = 4; i < RFIFOW(fd,2); i += 40 ){
+ guild_change_position(sd->status.guild_id, RFIFOL(fd,i), RFIFOL(fd,i+4), RFIFOL(fd,i+12), (char*)RFIFOP(fd,i+16));
+ }
}
@@ -11862,15 +11995,15 @@ void clif_parse_GuildChangePositionInfo(int fd, struct map_session_data *sd)
/// 0155 <packet len>.W { <account id>.L <char id>.L <position id>.L }*
void clif_parse_GuildChangeMemberPosition(int fd, struct map_session_data *sd)
{
- int i;
+ int i;
- if (!sd->state.gmaster_flag)
- return;
+ if(!sd->state.gmaster_flag)
+ return;
- for (i=4; i<RFIFOW(fd,2); i+=12) {
- guild_change_memberposition(sd->status.guild_id,
- RFIFOL(fd,i),RFIFOL(fd,i+4),RFIFOL(fd,i+8));
- }
+ for(i=4;i<RFIFOW(fd,2);i+=12){
+ guild_change_memberposition(sd->status.guild_id,
+ RFIFOL(fd,i),RFIFOL(fd,i+4),RFIFOL(fd,i+8));
+ }
}
@@ -11878,28 +12011,28 @@ void clif_parse_GuildChangeMemberPosition(int fd, struct map_session_data *sd)
/// 0151 <guild id>.L
void clif_parse_GuildRequestEmblem(int fd,struct map_session_data *sd)
{
- struct guild *g;
- int guild_id = RFIFOL(fd,2);
+ struct guild* g;
+ int guild_id = RFIFOL(fd,2);
- if ((g = guild_search(guild_id)) != NULL)
- clif_guild_emblem(sd,g);
+ if( (g = guild_search(guild_id)) != NULL )
+ clif_guild_emblem(sd,g);
}
/// Validates data of a guild emblem (compressed bitmap)
-static bool clif_validate_emblem(const uint8 *emblem, unsigned long emblem_len)
+static bool clif_validate_emblem(const uint8* emblem, unsigned long emblem_len)
{
- bool success;
- uint8 buf[1800]; // no well-formed emblem bitmap is larger than 1782 (24 bit) / 1654 (8 bit) bytes
- unsigned long buf_len = sizeof(buf);
+ bool success;
+ uint8 buf[1800]; // no well-formed emblem bitmap is larger than 1782 (24 bit) / 1654 (8 bit) bytes
+ unsigned long buf_len = sizeof(buf);
- success = (decode_zip(buf, &buf_len, emblem, emblem_len) == 0 && buf_len >= 18) // sizeof(BITMAPFILEHEADER) + sizeof(biSize) of the following info header struct
- && RBUFW(buf,0) == 0x4d42 // BITMAPFILEHEADER.bfType (signature)
- && RBUFL(buf,2) == buf_len // BITMAPFILEHEADER.bfSize (file size)
- && RBUFL(buf,10) < buf_len // BITMAPFILEHEADER.bfOffBits (offset to bitmap bits)
- ;
+ success = ( decode_zip(buf, &buf_len, emblem, emblem_len) == 0 && buf_len >= 18 ) // sizeof(BITMAPFILEHEADER) + sizeof(biSize) of the following info header struct
+ && RBUFW(buf,0) == 0x4d42 // BITMAPFILEHEADER.bfType (signature)
+ && RBUFL(buf,2) == buf_len // BITMAPFILEHEADER.bfSize (file size)
+ && RBUFL(buf,10) < buf_len // BITMAPFILEHEADER.bfOffBits (offset to bitmap bits)
+ ;
- return success;
+ return success;
}
@@ -11907,38 +12040,39 @@ static bool clif_validate_emblem(const uint8 *emblem, unsigned long emblem_len)
/// 0153 <packet len>.W <emblem data>.?B
void clif_parse_GuildChangeEmblem(int fd,struct map_session_data *sd)
{
- unsigned long emblem_len = RFIFOW(fd,2)-4;
- const uint8 *emblem = RFIFOP(fd,4);
+ unsigned long emblem_len = RFIFOW(fd,2)-4;
+ const uint8* emblem = RFIFOP(fd,4);
- if (!emblem_len || !sd->state.gmaster_flag)
- return;
+ if( !emblem_len || !sd->state.gmaster_flag )
+ return;
- if (!clif_validate_emblem(emblem, emblem_len)) {
- ShowWarning("clif_parse_GuildChangeEmblem: Rejected malformed guild emblem (size=%lu, accound_id=%d, char_id=%d, guild_id=%d).\n", emblem_len, sd->status.account_id, sd->status.char_id, sd->status.guild_id);
- return;
- }
+ if( !clif_validate_emblem(emblem, emblem_len) )
+ {
+ ShowWarning("clif_parse_GuildChangeEmblem: Rejected malformed guild emblem (size=%lu, accound_id=%d, char_id=%d, guild_id=%d).\n", emblem_len, sd->status.account_id, sd->status.char_id, sd->status.guild_id);
+ return;
+ }
- guild_change_emblem(sd, emblem_len, (const char *)emblem);
+ guild_change_emblem(sd, emblem_len, (const char*)emblem);
}
/// Guild notice update request (CZ_GUILD_NOTICE).
/// 016e <guild id>.L <msg1>.60B <msg2>.120B
-void clif_parse_GuildChangeNotice(int fd, struct map_session_data *sd)
+void clif_parse_GuildChangeNotice(int fd, struct map_session_data* sd)
{
- int guild_id = RFIFOL(fd,2);
- char *msg1 = (char *)RFIFOP(fd,6);
- char *msg2 = (char *)RFIFOP(fd,66);
+ int guild_id = RFIFOL(fd,2);
+ char* msg1 = (char*)RFIFOP(fd,6);
+ char* msg2 = (char*)RFIFOP(fd,66);
- if (!sd->state.gmaster_flag)
- return;
+ if(!sd->state.gmaster_flag)
+ return;
- // compensate for some client defects when using multilanguage mode
- if (msg1[0] == '|' && msg1[3] == '|') msg1+= 3; // skip duplicate marker
- if (msg2[0] == '|' && msg2[3] == '|') msg2+= 3; // skip duplicate marker
- if (msg2[0] == '|') msg2[strnlen(msg2, MAX_GUILDMES2)-1] = '\0'; // delete extra space at the end of string
+ // compensate for some client defects when using multilanguage mode
+ if (msg1[0] == '|' && msg1[3] == '|') msg1+= 3; // skip duplicate marker
+ if (msg2[0] == '|' && msg2[3] == '|') msg2+= 3; // skip duplicate marker
+ if (msg2[0] == '|') msg2[strnlen(msg2, MAX_GUILDMES2)-1] = '\0'; // delete extra space at the end of string
- guild_change_notice(sd, guild_id, msg1, msg2);
+ guild_change_notice(sd, guild_id, msg1, msg2);
}
@@ -11946,23 +12080,23 @@ void clif_parse_GuildChangeNotice(int fd, struct map_session_data *sd)
/// 0168 <account id>.L <inviter account id>.L <inviter char id>.L
void clif_parse_GuildInvite(int fd,struct map_session_data *sd)
{
- struct map_session_data *t_sd;
+ struct map_session_data *t_sd;
- if (map[sd->bl.m].flag.guildlock) {
- //Guild locked.
- clif_displaymessage(fd, msg_txt(228));
- return;
- }
+ if(map[sd->bl.m].flag.guildlock)
+ { //Guild locked.
+ clif_displaymessage(fd, msg_txt(228));
+ return;
+ }
- t_sd = map_id2sd(RFIFOL(fd,2));
+ t_sd = map_id2sd(RFIFOL(fd,2));
- // @noask [LuzZza]
- if (t_sd && t_sd->state.noask) {
- clif_noask_sub(sd, t_sd, 2);
- return;
- }
+ // @noask [LuzZza]
+ if(t_sd && t_sd->state.noask) {
+ clif_noask_sub(sd, t_sd, 2);
+ return;
+ }
- guild_invite(sd,t_sd);
+ guild_invite(sd,t_sd);
}
@@ -11973,7 +12107,7 @@ void clif_parse_GuildInvite(int fd,struct map_session_data *sd)
/// 1 = accept
void clif_parse_GuildReplyInvite(int fd,struct map_session_data *sd)
{
- guild_reply_invite(sd,RFIFOL(fd,2),RFIFOL(fd,6));
+ guild_reply_invite(sd,RFIFOL(fd,2),RFIFOL(fd,6));
}
@@ -11981,17 +12115,18 @@ void clif_parse_GuildReplyInvite(int fd,struct map_session_data *sd)
/// 0159 <guild id>.L <account id>.L <char id>.L <reason>.40B
void clif_parse_GuildLeave(int fd,struct map_session_data *sd)
{
- if (map[sd->bl.m].flag.guildlock) {
- //Guild locked.
- clif_displaymessage(fd, msg_txt(228));
- return;
- }
- if (sd->bg_id) {
- clif_displaymessage(fd, msg_txt(670)); //"You can't leave battleground guilds."
- return;
- }
+ if(map[sd->bl.m].flag.guildlock)
+ { //Guild locked.
+ clif_displaymessage(fd, msg_txt(228));
+ return;
+ }
+ if( sd->bg_id )
+ {
+ clif_displaymessage(fd, msg_txt(670)); //"You can't leave battleground guilds."
+ return;
+ }
- guild_leave(sd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),(char *)RFIFOP(fd,14));
+ guild_leave(sd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),(char*)RFIFOP(fd,14));
}
@@ -11999,46 +12134,46 @@ void clif_parse_GuildLeave(int fd,struct map_session_data *sd)
/// 015b <guild id>.L <account id>.L <char id>.L <reason>.40B
void clif_parse_GuildExpulsion(int fd,struct map_session_data *sd)
{
- if (map[sd->bl.m].flag.guildlock || sd->bg_id) {
- // Guild locked.
- clif_displaymessage(fd, msg_txt(228));
- return;
- }
- guild_expulsion(sd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),(char *)RFIFOP(fd,14));
+ if( map[sd->bl.m].flag.guildlock || sd->bg_id )
+ { // Guild locked.
+ clif_displaymessage(fd, msg_txt(228));
+ return;
+ }
+ guild_expulsion(sd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),(char*)RFIFOP(fd,14));
}
/// Validates and processes guild messages (CZ_GUILD_CHAT).
/// 017e <packet len>.W <text>.?B (<name> : <message>) 00
-void clif_parse_GuildMessage(int fd, struct map_session_data *sd)
+void clif_parse_GuildMessage(int fd, struct map_session_data* sd)
{
- const char *text = (char *)RFIFOP(fd,4);
- int textlen = RFIFOW(fd,2) - 4;
+ const char* text = (char*)RFIFOP(fd,4);
+ int textlen = RFIFOW(fd,2) - 4;
- char *name, *message;
- int namelen, messagelen;
+ char *name, *message;
+ int namelen, messagelen;
- // validate packet and retrieve name and message
- if (!clif_process_message(sd, 0, &name, &namelen, &message, &messagelen))
- return;
+ // validate packet and retrieve name and message
+ if( !clif_process_message(sd, 0, &name, &namelen, &message, &messagelen) )
+ return;
- if (is_atcommand(fd, sd, message, 1))
- return;
+ if( is_atcommand(fd, sd, message, 1) )
+ return;
- if (sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT))
- return;
+ if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) )
+ return;
- if (battle_config.min_chat_delay) {
- //[Skotlex]
- if (DIFF_TICK(sd->cantalk_tick, gettick()) > 0)
- return;
- sd->cantalk_tick = gettick() + battle_config.min_chat_delay;
- }
+ if( battle_config.min_chat_delay )
+ { //[Skotlex]
+ if (DIFF_TICK(sd->cantalk_tick, gettick()) > 0)
+ return;
+ sd->cantalk_tick = gettick() + battle_config.min_chat_delay;
+ }
- if (sd->bg_id)
- bg_send_message(sd, text, textlen);
- else
- guild_send_message(sd, text, textlen);
+ if( sd->bg_id )
+ bg_send_message(sd, text, textlen);
+ else
+ guild_send_message(sd, text, textlen);
}
@@ -12046,26 +12181,26 @@ void clif_parse_GuildMessage(int fd, struct map_session_data *sd)
/// 0170 <account id>.L <inviter account id>.L <inviter char id>.L
void clif_parse_GuildRequestAlliance(int fd, struct map_session_data *sd)
{
- struct map_session_data *t_sd;
+ struct map_session_data *t_sd;
- if (!sd->state.gmaster_flag)
- return;
+ if(!sd->state.gmaster_flag)
+ return;
- if (map[sd->bl.m].flag.guildlock) {
- //Guild locked.
- clif_displaymessage(fd, msg_txt(228));
- return;
- }
+ if(map[sd->bl.m].flag.guildlock)
+ { //Guild locked.
+ clif_displaymessage(fd, msg_txt(228));
+ return;
+ }
- t_sd = map_id2sd(RFIFOL(fd,2));
+ t_sd = map_id2sd(RFIFOL(fd,2));
- // @noask [LuzZza]
- if (t_sd && t_sd->state.noask) {
- clif_noask_sub(sd, t_sd, 3);
- return;
- }
+ // @noask [LuzZza]
+ if(t_sd && t_sd->state.noask) {
+ clif_noask_sub(sd, t_sd, 3);
+ return;
+ }
- guild_reqalliance(sd,t_sd);
+ guild_reqalliance(sd,t_sd);
}
@@ -12076,7 +12211,7 @@ void clif_parse_GuildRequestAlliance(int fd, struct map_session_data *sd)
/// 1 = accept
void clif_parse_GuildReplyAlliance(int fd, struct map_session_data *sd)
{
- guild_reply_reqalliance(sd,RFIFOL(fd,2),RFIFOL(fd,6));
+ guild_reply_reqalliance(sd,RFIFOL(fd,2),RFIFOL(fd,6));
}
@@ -12087,15 +12222,15 @@ void clif_parse_GuildReplyAlliance(int fd, struct map_session_data *sd)
/// 1 = Enemy
void clif_parse_GuildDelAlliance(int fd, struct map_session_data *sd)
{
- if (!sd->state.gmaster_flag)
- return;
+ if(!sd->state.gmaster_flag)
+ return;
- if (map[sd->bl.m].flag.guildlock) {
- //Guild locked.
- clif_displaymessage(fd, msg_txt(228));
- return;
- }
- guild_delalliance(sd,RFIFOL(fd,2),RFIFOL(fd,6));
+ if(map[sd->bl.m].flag.guildlock)
+ { //Guild locked.
+ clif_displaymessage(fd, msg_txt(228));
+ return;
+ }
+ guild_delalliance(sd,RFIFOL(fd,2),RFIFOL(fd,6));
}
@@ -12103,26 +12238,26 @@ void clif_parse_GuildDelAlliance(int fd, struct map_session_data *sd)
/// 0180 <account id>.L
void clif_parse_GuildOpposition(int fd, struct map_session_data *sd)
{
- struct map_session_data *t_sd;
+ struct map_session_data *t_sd;
- if (!sd->state.gmaster_flag)
- return;
+ if(!sd->state.gmaster_flag)
+ return;
- if (map[sd->bl.m].flag.guildlock) {
- //Guild locked.
- clif_displaymessage(fd, msg_txt(228));
- return;
- }
+ if(map[sd->bl.m].flag.guildlock)
+ { //Guild locked.
+ clif_displaymessage(fd, msg_txt(228));
+ return;
+ }
- t_sd = map_id2sd(RFIFOL(fd,2));
+ t_sd = map_id2sd(RFIFOL(fd,2));
- // @noask [LuzZza]
- if (t_sd && t_sd->state.noask) {
- clif_noask_sub(sd, t_sd, 4);
- return;
- }
+ // @noask [LuzZza]
+ if(t_sd && t_sd->state.noask) {
+ clif_noask_sub(sd, t_sd, 4);
+ return;
+ }
- guild_opposition(sd,t_sd);
+ guild_opposition(sd,t_sd);
}
@@ -12133,12 +12268,12 @@ void clif_parse_GuildOpposition(int fd, struct map_session_data *sd)
/// field name and size is same as the one in CH_DELETE_CHAR.
void clif_parse_GuildBreak(int fd, struct map_session_data *sd)
{
- if (map[sd->bl.m].flag.guildlock) {
- //Guild locked.
- clif_displaymessage(fd, msg_txt(228));
- return;
- }
- guild_break(sd,(char *)RFIFOP(fd,2));
+ if( map[sd->bl.m].flag.guildlock )
+ { //Guild locked.
+ clif_displaymessage(fd, msg_txt(228));
+ return;
+ }
+ guild_break(sd,(char*)RFIFOP(fd,2));
}
@@ -12155,7 +12290,7 @@ void clif_parse_GuildBreak(int fd, struct map_session_data *sd)
/// 4 = unequip accessory
void clif_parse_PetMenu(int fd, struct map_session_data *sd)
{
- pet_menu(sd,RFIFOB(fd,2));
+ pet_menu(sd,RFIFOB(fd,2));
}
@@ -12163,7 +12298,7 @@ void clif_parse_PetMenu(int fd, struct map_session_data *sd)
/// 019f <id>.L
void clif_parse_CatchPet(int fd, struct map_session_data *sd)
{
- pet_catch_process2(sd,RFIFOL(fd,2));
+ pet_catch_process2(sd,RFIFOL(fd,2));
}
@@ -12171,13 +12306,14 @@ void clif_parse_CatchPet(int fd, struct map_session_data *sd)
/// 01a7 <index>.W
void clif_parse_SelectEgg(int fd, struct map_session_data *sd)
{
- if (sd->menuskill_id != SA_TAMINGMONSTER || sd->menuskill_val != -1) {
- //Forged packet, disconnect them [Kevin]
- clif_authfail_fd(fd, 0);
- return;
- }
- pet_select_egg(sd,RFIFOW(fd,2)-2);
- clif_menuskill_clear(sd);
+ if (sd->menuskill_id != SA_TAMINGMONSTER || sd->menuskill_val != -1)
+ {
+ //Forged packet, disconnect them [Kevin]
+ clif_authfail_fd(fd, 0);
+ return;
+ }
+ pet_select_egg(sd,RFIFOW(fd,2)-2);
+ clif_menuskill_clear(sd);
}
@@ -12207,8 +12343,8 @@ void clif_parse_SelectEgg(int fd, struct map_session_data *sd)
/// 4 = full (so_full)
void clif_parse_SendEmotion(int fd, struct map_session_data *sd)
{
- if (sd->pd)
- clif_pet_emotion(sd->pd,RFIFOL(fd,2));
+ if(sd->pd)
+ clif_pet_emotion(sd->pd,RFIFOL(fd,2));
}
@@ -12216,7 +12352,7 @@ void clif_parse_SendEmotion(int fd, struct map_session_data *sd)
/// 01a5 <name>.24B
void clif_parse_ChangePetName(int fd, struct map_session_data *sd)
{
- pet_change_name(sd,(char *)RFIFOP(fd,2));
+ pet_change_name(sd,(char*)RFIFOP(fd,2));
}
@@ -12226,60 +12362,62 @@ void clif_parse_ChangePetName(int fd, struct map_session_data *sd)
/// NOTE: Also sent when using GM right click menu "(name) force to quit"
void clif_parse_GMKick(int fd, struct map_session_data *sd)
{
- struct block_list *target;
- int tid;
-
- tid = RFIFOL(fd,2);
- target = map_id2bl(tid);
- if (!target) {
- clif_GM_kickack(sd, 0);
- return;
- }
-
- switch (target->type) {
- case BL_PC: {
- char command[NAME_LENGTH+6];
- sprintf(command, "%ckick %s", atcommand_symbol, status_get_name(target));
- is_atcommand(fd, sd, command, 1);
- }
- break;
-
- /**
- * This one does not invoke any atcommand, so we need to check for permissions.
- */
- case BL_MOB: {
- char command[100];
- if (!pc_can_use_command(sd, "killmonster", COMMAND_ATCOMMAND)) {
- clif_GM_kickack(sd, 0);
- return;
- }
- sprintf(command, "/kick %s (%d)", status_get_name(target), status_get_class(target));
- log_atcommand(sd, command);
- status_percent_damage(&sd->bl, target, 100, 0, true); // can invalidate 'target'
- }
- break;
-
- case BL_NPC: {
- char command[NAME_LENGTH+11];
- sprintf(command, "%cunloadnpc %s", atcommand_symbol, status_get_name(target));
- is_atcommand(fd, sd, command, 1);
- }
- break;
-
- default:
- clif_GM_kickack(sd, 0);
- }
+ struct block_list *target;
+ int tid;
+
+ tid = RFIFOL(fd,2);
+ target = map_id2bl(tid);
+ if (!target) {
+ clif_GM_kickack(sd, 0);
+ return;
+ }
+
+ switch (target->type) {
+ case BL_PC:
+ {
+ char command[NAME_LENGTH+6];
+ sprintf(command, "%ckick %s", atcommand_symbol, status_get_name(target));
+ is_atcommand(fd, sd, command, 1);
+ }
+ break;
+
+ /**
+ * This one does not invoke any atcommand, so we need to check for permissions.
+ */
+ case BL_MOB:
+ {
+ char command[100];
+ if( !pc_can_use_command(sd, "killmonster", COMMAND_ATCOMMAND)) {
+ clif_GM_kickack(sd, 0);
+ return;
+ }
+ sprintf(command, "/kick %s (%d)", status_get_name(target), status_get_class(target));
+ log_atcommand(sd, command);
+ status_percent_damage(&sd->bl, target, 100, 0, true); // can invalidate 'target'
+ }
+ break;
+
+ case BL_NPC:
+ {
+ char command[NAME_LENGTH+11];
+ sprintf(command, "%cunloadnpc %s", atcommand_symbol, status_get_name(target));
+ is_atcommand(fd, sd, command, 1);
+ }
+ break;
+
+ default:
+ clif_GM_kickack(sd, 0);
+ }
}
/// /killall (CZ_DISCONNECT_ALL_CHARACTER).
/// Request to disconnect all characters.
/// 00ce
-void clif_parse_GMKickAll(int fd, struct map_session_data *sd)
-{
- char cmd[15];
- sprintf(cmd,"%ckickall",atcommand_symbol);
- is_atcommand(fd, sd, cmd, 1);
+void clif_parse_GMKickAll(int fd, struct map_session_data* sd) {
+ char cmd[15];
+ sprintf(cmd,"%ckickall",atcommand_symbol);
+ is_atcommand(fd, sd, cmd, 1);
}
@@ -12291,33 +12429,33 @@ void clif_parse_GMKickAll(int fd, struct map_session_data *sd)
/// Request to warp to a character with given name.
/// 01bb <char name>.24B
void clif_parse_GMShift(int fd, struct map_session_data *sd)
-{
- // FIXME: remove is supposed to receive account name for clients prior 20100803RE
- char *player_name;
- char command[NAME_LENGTH+8];
+{// FIXME: remove is supposed to receive account name for clients prior 20100803RE
+ char *player_name;
+ char command[NAME_LENGTH+8];
- player_name = (char *)RFIFOP(fd,2);
- player_name[NAME_LENGTH-1] = '\0';
+ player_name = (char*)RFIFOP(fd,2);
+ player_name[NAME_LENGTH-1] = '\0';
- sprintf(command, "%cjumpto %s", atcommand_symbol, player_name);
- is_atcommand(fd, sd, command, 1);
+ sprintf(command, "%cjumpto %s", atcommand_symbol, player_name);
+ is_atcommand(fd, sd, command, 1);
}
/// /remove (CZ_REMOVE_AID_SSO).
/// Request to warp to a character with given account ID.
/// 0843 <account id>.L
-void clif_parse_GMRemove2(int fd, struct map_session_data *sd)
+void clif_parse_GMRemove2(int fd, struct map_session_data* sd)
{
- int account_id;
- struct map_session_data *pl_sd;
+ int account_id;
+ struct map_session_data* pl_sd;
- account_id = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
- if ((pl_sd = map_id2sd(account_id)) != NULL) {
- char command[NAME_LENGTH+8];
- sprintf(command, "%cjumpto %s", atcommand_symbol, pl_sd->status.name);
- is_atcommand(fd, sd, command, 1);
- }
+ account_id = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
+ if( (pl_sd = map_id2sd(account_id)) != NULL )
+ {
+ char command[NAME_LENGTH+8];
+ sprintf(command, "%cjumpto %s", atcommand_symbol, pl_sd->status.name);
+ is_atcommand(fd, sd, command, 1);
+ }
}
@@ -12329,33 +12467,33 @@ void clif_parse_GMRemove2(int fd, struct map_session_data *sd)
/// Request to summon a player with given name to own position.
/// 01bd <char name>.24B
void clif_parse_GMRecall(int fd, struct map_session_data *sd)
-{
- // FIXME: recall is supposed to receive account name for clients prior 20100803RE
- char *player_name;
- char command [NAME_LENGTH+8];
+{// FIXME: recall is supposed to receive account name for clients prior 20100803RE
+ char *player_name;
+ char command [NAME_LENGTH+8];
- player_name = (char *)RFIFOP(fd,2);
- player_name[NAME_LENGTH-1] = '\0';
+ player_name = (char*)RFIFOP(fd,2);
+ player_name[NAME_LENGTH-1] = '\0';
- sprintf(command, "%crecall %s", atcommand_symbol, player_name);
- is_atcommand(fd, sd, command, 1);
+ sprintf(command, "%crecall %s", atcommand_symbol, player_name);
+ is_atcommand(fd, sd, command, 1);
}
/// /recall (CZ_RECALL_SSO).
/// Request to summon a player with given account ID to own position.
/// 0842 <account id>.L
-void clif_parse_GMRecall2(int fd, struct map_session_data *sd)
+void clif_parse_GMRecall2(int fd, struct map_session_data* sd)
{
- int account_id;
- struct map_session_data *pl_sd;
+ int account_id;
+ struct map_session_data* pl_sd;
- account_id = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
- if ((pl_sd = map_id2sd(account_id)) != NULL) {
- char command[NAME_LENGTH+8];
- sprintf(command, "%crecall %s", atcommand_symbol, pl_sd->status.name);
- is_atcommand(fd, sd, command, 1);
- }
+ account_id = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
+ if( (pl_sd = map_id2sd(account_id)) != NULL )
+ {
+ char command[NAME_LENGTH+8];
+ sprintf(command, "%crecall %s", atcommand_symbol, pl_sd->status.name);
+ is_atcommand(fd, sd, command, 1);
+ }
}
@@ -12364,27 +12502,27 @@ void clif_parse_GMRecall2(int fd, struct map_session_data *sd)
/// 013f <item/mob name>.24B
void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd)
{
- char *monster_item_name;
- char command[NAME_LENGTH+10];
+ char *monster_item_name;
+ char command[NAME_LENGTH+10];
- monster_item_name = (char *)RFIFOP(fd,2);
- monster_item_name[NAME_LENGTH-1] = '\0';
+ monster_item_name = (char*)RFIFOP(fd,2);
+ monster_item_name[NAME_LENGTH-1] = '\0';
- // FIXME: Should look for item first, then for monster.
- // FIXME: /monster takes mob_db Sprite_Name as argument
- if (mobdb_searchname(monster_item_name)) {
- snprintf(command, sizeof(command)-1, "%cmonster %s", atcommand_symbol, monster_item_name);
- is_atcommand(fd, sd, command, 1);
- return;
- }
- // FIXME: Stackables have a quantity of 20.
- // FIXME: Equips are supposed to be unidentified.
+ // FIXME: Should look for item first, then for monster.
+ // FIXME: /monster takes mob_db Sprite_Name as argument
+ if( mobdb_searchname(monster_item_name) ) {
+ snprintf(command, sizeof(command)-1, "%cmonster %s", atcommand_symbol, monster_item_name);
+ is_atcommand(fd, sd, command, 1);
+ return;
+ }
+ // FIXME: Stackables have a quantity of 20.
+ // FIXME: Equips are supposed to be unidentified.
- if (itemdb_searchname(monster_item_name)) {
- snprintf(command, sizeof(command)-1, "%citem %s", atcommand_symbol, monster_item_name);
- is_atcommand(fd, sd, command, 1);
- return;
- }
+ if( itemdb_searchname(monster_item_name) ) {
+ snprintf(command, sizeof(command)-1, "%citem %s", atcommand_symbol, monster_item_name);
+ is_atcommand(fd, sd, command, 1);
+ return;
+ }
}
@@ -12392,13 +12530,12 @@ void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd)
/// 019d <effect state>.L
/// effect state:
/// TODO: Any OPTION_* ?
-void clif_parse_GMHide(int fd, struct map_session_data *sd)
-{
- char cmd[6];
+void clif_parse_GMHide(int fd, struct map_session_data *sd) {
+ char cmd[6];
- sprintf(cmd,"%chide",atcommand_symbol);
+ sprintf(cmd,"%chide",atcommand_symbol);
- is_atcommand(fd, sd, cmd, 1);
+ is_atcommand(fd, sd, cmd, 1);
}
@@ -12410,56 +12547,56 @@ void clif_parse_GMHide(int fd, struct map_session_data *sd)
/// 2 = self mute (+10 minutes)
void clif_parse_GMReqNoChat(int fd,struct map_session_data *sd)
{
- int id, type, value;
- struct map_session_data *dstsd;
- char command[NAME_LENGTH+15];
+ int id, type, value;
+ struct map_session_data *dstsd;
+ char command[NAME_LENGTH+15];
- id = RFIFOL(fd,2);
- type = RFIFOB(fd,6);
- value = RFIFOW(fd,7);
+ id = RFIFOL(fd,2);
+ type = RFIFOB(fd,6);
+ value = RFIFOW(fd,7);
- if (type == 0)
- value = -value;
+ if( type == 0 )
+ value = -value;
- //If type is 2 and the ids don't match, this is a crafted hacked packet!
- //Disabled because clients keep self-muting when you give players public @ commands... [Skotlex]
- if (type == 2 /* && (pc_get_group_level(sd) > 0 || sd->bl.id != id)*/)
- return;
+ //If type is 2 and the ids don't match, this is a crafted hacked packet!
+ //Disabled because clients keep self-muting when you give players public @ commands... [Skotlex]
+ if (type == 2 /* && (pc_get_group_level(sd) > 0 || sd->bl.id != id)*/)
+ return;
- dstsd = map_id2sd(id);
- if (dstsd == NULL)
- return;
+ dstsd = map_id2sd(id);
+ if( dstsd == NULL )
+ return;
- sprintf(command, "%cmute %d %s", atcommand_symbol, value, dstsd->status.name);
- is_atcommand(fd, sd, command, 1);
+ sprintf(command, "%cmute %d %s", atcommand_symbol, value, dstsd->status.name);
+ is_atcommand(fd, sd, command, 1);
}
/// /rc (CZ_REQ_GIVE_MANNER_BYNAME).
/// GM adjustment of a player's manner value by -60.
/// 0212 <char name>.24B
-void clif_parse_GMRc(int fd, struct map_session_data *sd)
+void clif_parse_GMRc(int fd, struct map_session_data* sd)
{
- char command[NAME_LENGTH+15];
- char *name = (char *)RFIFOP(fd,2);
+ char command[NAME_LENGTH+15];
+ char *name = (char*)RFIFOP(fd,2);
- name[NAME_LENGTH-1] = '\0';
- sprintf(command, "%cmute %d %s", atcommand_symbol, 60, name);
- is_atcommand(fd, sd, command, 1);
+ name[NAME_LENGTH-1] = '\0';
+ sprintf(command, "%cmute %d %s", atcommand_symbol, 60, name);
+ is_atcommand(fd, sd, command, 1);
}
/// Result of request to resolve account name (ZC_ACK_ACCOUNTNAME).
/// 01e0 <account id>.L <account name>.24B
-void clif_account_name(struct map_session_data *sd, int account_id, const char *accname)
+void clif_account_name(struct map_session_data* sd, int account_id, const char* accname)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x1e0));
- WFIFOW(fd,0) = 0x1e0;
- WFIFOL(fd,2) = account_id;
- safestrncpy((char *)WFIFOP(fd,6), accname, NAME_LENGTH);
- WFIFOSET(fd,packet_len(0x1e0));
+ WFIFOHEAD(fd,packet_len(0x1e0));
+ WFIFOW(fd,0) = 0x1e0;
+ WFIFOL(fd,2) = account_id;
+ safestrncpy((char*)WFIFOP(fd,6), accname, NAME_LENGTH);
+ WFIFOSET(fd,packet_len(0x1e0));
}
@@ -12467,10 +12604,10 @@ void clif_account_name(struct map_session_data *sd, int account_id, const char *
/// 01df <account id>.L
void clif_parse_GMReqAccountName(int fd, struct map_session_data *sd)
{
- int account_id = RFIFOL(fd,2);
+ int account_id = RFIFOL(fd,2);
- //TODO: find out if this works for any player or only for authorized GMs
- clif_account_name(sd, account_id, ""); // insert account name here >_<
+ //TODO: find out if this works for any player or only for authorized GMs
+ clif_account_name(sd, account_id, ""); // insert account name here >_<
}
@@ -12482,18 +12619,18 @@ void clif_parse_GMReqAccountName(int fd, struct map_session_data *sd)
/// 1 = walkable
void clif_parse_GMChangeMapType(int fd, struct map_session_data *sd)
{
- int x,y,type;
+ int x,y,type;
- if (pc_has_permission(sd, PC_PERM_USE_CHANGEMAPTYPE))
- return;
+ if( pc_has_permission(sd, PC_PERM_USE_CHANGEMAPTYPE) )
+ return;
- x = RFIFOW(fd,2);
- y = RFIFOW(fd,4);
- type = RFIFOW(fd,6);
+ x = RFIFOW(fd,2);
+ y = RFIFOW(fd,4);
+ type = RFIFOW(fd,6);
- map_setgatcell(sd->bl.m,x,y,type);
- clif_changemapcell(0,sd->bl.m,x,y,type,ALL_SAMEMAP);
- //FIXME: once players leave the map, the client 'forgets' this information.
+ map_setgatcell(sd->bl.m,x,y,type);
+ clif_changemapcell(0,sd->bl.m,x,y,type,ALL_SAMEMAP);
+ //FIXME: once players leave the map, the client 'forgets' this information.
}
@@ -12503,55 +12640,56 @@ void clif_parse_GMChangeMapType(int fd, struct map_session_data *sd)
/// type:
/// 0 = (/ex nick) deny speech from nick
/// 1 = (/in nick) allow speech from nick
-void clif_parse_PMIgnore(int fd, struct map_session_data *sd)
-{
- char *nick;
- uint8 type;
- int i;
-
- nick = (char *)RFIFOP(fd,2); // speed up
- nick[NAME_LENGTH-1] = '\0'; // to be sure that the player name has at most 23 characters
- type = RFIFOB(fd,26);
-
- if (type == 0) {
- // Add name to ignore list (block)
- if (strcmp(wisp_server_name, nick) == 0) {
- clif_wisexin(sd, type, 1); // fail
- return;
- }
-
- // try to find a free spot, while checking for duplicates at the same time
- ARR_FIND(0, MAX_IGNORE_LIST, i, sd->ignore[i].name[0] == '\0' || strcmp(sd->ignore[i].name, nick) == 0);
- if (i == MAX_IGNORE_LIST) {
- // no space for new entry
- clif_wisexin(sd, type, 2); // too many blocks
- return;
- }
- if (sd->ignore[i].name[0] != '\0') {
- // name already exists
- clif_wisexin(sd, type, 0); // Aegis reports success.
- return;
- }
-
- //Insert in position i
- safestrncpy(sd->ignore[i].name, nick, NAME_LENGTH);
- } else {
- // Remove name from ignore list (unblock)
-
- // find entry
- ARR_FIND(0, MAX_IGNORE_LIST, i, sd->ignore[i].name[0] == '\0' || strcmp(sd->ignore[i].name, nick) == 0);
- if (i == MAX_IGNORE_LIST || sd->ignore[i].name[i] == '\0') {
- //Not found
- clif_wisexin(sd, type, 1); // fail
- return;
- }
- // move everything one place down to overwrite removed entry
- memmove(sd->ignore[i].name, sd->ignore[i+1].name, (MAX_IGNORE_LIST-i-1)*sizeof(sd->ignore[0].name));
- // wipe last entry
- memset(sd->ignore[MAX_IGNORE_LIST-1].name, 0, sizeof(sd->ignore[0].name));
- }
-
- clif_wisexin(sd, type, 0); // success
+void clif_parse_PMIgnore(int fd, struct map_session_data* sd)
+{
+ char* nick;
+ uint8 type;
+ int i;
+
+ nick = (char*)RFIFOP(fd,2); // speed up
+ nick[NAME_LENGTH-1] = '\0'; // to be sure that the player name has at most 23 characters
+ type = RFIFOB(fd,26);
+
+ if( type == 0 )
+ { // Add name to ignore list (block)
+ if (strcmp(wisp_server_name, nick) == 0) {
+ clif_wisexin(sd, type, 1); // fail
+ return;
+ }
+
+ // try to find a free spot, while checking for duplicates at the same time
+ ARR_FIND( 0, MAX_IGNORE_LIST, i, sd->ignore[i].name[0] == '\0' || strcmp(sd->ignore[i].name, nick) == 0 );
+ if( i == MAX_IGNORE_LIST )
+ {// no space for new entry
+ clif_wisexin(sd, type, 2); // too many blocks
+ return;
+ }
+ if( sd->ignore[i].name[0] != '\0' )
+ {// name already exists
+ clif_wisexin(sd, type, 0); // Aegis reports success.
+ return;
+ }
+
+ //Insert in position i
+ safestrncpy(sd->ignore[i].name, nick, NAME_LENGTH);
+ }
+ else
+ { // Remove name from ignore list (unblock)
+
+ // find entry
+ ARR_FIND( 0, MAX_IGNORE_LIST, i, sd->ignore[i].name[0] == '\0' || strcmp(sd->ignore[i].name, nick) == 0 );
+ if( i == MAX_IGNORE_LIST || sd->ignore[i].name[i] == '\0' )
+ { //Not found
+ clif_wisexin(sd, type, 1); // fail
+ return;
+ }
+ // move everything one place down to overwrite removed entry
+ memmove(sd->ignore[i].name, sd->ignore[i+1].name, (MAX_IGNORE_LIST-i-1)*sizeof(sd->ignore[0].name));
+ // wipe last entry
+ memset(sd->ignore[MAX_IGNORE_LIST-1].name, 0, sizeof(sd->ignore[0].name));
+ }
+
+ clif_wisexin(sd, type, 0); // success
}
@@ -12563,51 +12701,53 @@ void clif_parse_PMIgnore(int fd, struct map_session_data *sd)
/// 1 = (/inall) allow all speech
void clif_parse_PMIgnoreAll(int fd, struct map_session_data *sd)
{
- int type = RFIFOB(fd,2), flag;
-
- if (type == 0) {
- // Deny all
- if (sd->state.ignoreAll) {
- flag = 1; // fail
- } else {
- sd->state.ignoreAll = 1;
- flag = 0; // success
- }
- } else {
- //Unblock everyone
- if (sd->state.ignoreAll) {
- sd->state.ignoreAll = 0;
- flag = 0; // success
- } else {
- if (sd->ignore[0].name[0] != '\0') {
- //Wipe the ignore list.
- memset(sd->ignore, 0, sizeof(sd->ignore));
- flag = 0; // success
- } else {
- flag = 1; // fail
- }
- }
- }
-
- clif_wisall(sd, type, flag);
+ int type = RFIFOB(fd,2), flag;
+
+ if( type == 0 )
+ {// Deny all
+ if( sd->state.ignoreAll ) {
+ flag = 1; // fail
+ } else {
+ sd->state.ignoreAll = 1;
+ flag = 0; // success
+ }
+ }
+ else
+ {//Unblock everyone
+ if( sd->state.ignoreAll ) {
+ sd->state.ignoreAll = 0;
+ flag = 0; // success
+ } else {
+ if (sd->ignore[0].name[0] != '\0')
+ { //Wipe the ignore list.
+ memset(sd->ignore, 0, sizeof(sd->ignore));
+ flag = 0; // success
+ } else {
+ flag = 1; // fail
+ }
+ }
+ }
+
+ clif_wisall(sd, type, flag);
}
/// Whisper ignore list (ZC_WHISPER_LIST).
/// 00d4 <packet len>.W { <char name>.24B }*
-void clif_PMIgnoreList(struct map_session_data *sd)
+void clif_PMIgnoreList(struct map_session_data* sd)
{
- int i, fd = sd->fd;
+ int i, fd = sd->fd;
- WFIFOHEAD(fd,4+ARRAYLENGTH(sd->ignore)*NAME_LENGTH);
- WFIFOW(fd,0) = 0xd4;
+ WFIFOHEAD(fd,4+ARRAYLENGTH(sd->ignore)*NAME_LENGTH);
+ WFIFOW(fd,0) = 0xd4;
- for (i = 0; i < ARRAYLENGTH(sd->ignore) && sd->ignore[i].name[0]; i++) {
- memcpy(WFIFOP(fd,4+i*NAME_LENGTH), sd->ignore[i].name, NAME_LENGTH);
- }
+ for( i = 0; i < ARRAYLENGTH(sd->ignore) && sd->ignore[i].name[0]; i++ )
+ {
+ memcpy(WFIFOP(fd,4+i*NAME_LENGTH), sd->ignore[i].name, NAME_LENGTH);
+ }
- WFIFOW(fd,2) = 4+i*NAME_LENGTH;
- WFIFOSET(fd,WFIFOW(fd,2));
+ WFIFOW(fd,2) = 4+i*NAME_LENGTH;
+ WFIFOSET(fd,WFIFOW(fd,2));
}
@@ -12615,7 +12755,7 @@ void clif_PMIgnoreList(struct map_session_data *sd)
/// 00d3
void clif_parse_PMIgnoreList(int fd,struct map_session_data *sd)
{
- clif_PMIgnoreList(sd);
+ clif_PMIgnoreList(sd);
}
@@ -12623,18 +12763,19 @@ void clif_parse_PMIgnoreList(int fd,struct map_session_data *sd)
/// 01e7
void clif_parse_NoviceDoriDori(int fd, struct map_session_data *sd)
{
- if (sd->state.doridori) return;
-
- switch (sd->class_&MAPID_UPPERMASK) {
- case MAPID_SOUL_LINKER:
- case MAPID_STAR_GLADIATOR:
- case MAPID_TAEKWON:
- if (!sd->state.rest)
- break;
- case MAPID_SUPER_NOVICE:
- sd->state.doridori=1;
- break;
- }
+ if (sd->state.doridori) return;
+
+ switch (sd->class_&MAPID_UPPERMASK)
+ {
+ case MAPID_SOUL_LINKER:
+ case MAPID_STAR_GLADIATOR:
+ case MAPID_TAEKWON:
+ if (!sd->state.rest)
+ break;
+ case MAPID_SUPER_NOVICE:
+ sd->state.doridori=1;
+ break;
+ }
}
@@ -12648,19 +12789,21 @@ void clif_parse_NoviceDoriDori(int fd, struct map_session_data *sd)
/// "Help me out~ Please~ T_T"
void clif_parse_NoviceExplosionSpirits(int fd, struct map_session_data *sd)
{
- if ((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE) {
- unsigned int next = pc_nextbaseexp(sd);
- if (next == 0) next = pc_thisbaseexp(sd);
- if (next) {
- int percent = (int)(((float)sd->status.base_exp/(float)next)*1000.);
-
- if (percent && (percent%100) == 0) {
- // 10.0%, 20.0%, ..., 90.0%
- sc_start(&sd->bl, status_skill2sc(MO_EXPLOSIONSPIRITS), 100, 17, skill_get_time(MO_EXPLOSIONSPIRITS, 5)); //Lv17-> +50 critical (noted by Poki) [Skotlex]
- clif_skill_nodamage(&sd->bl, &sd->bl, MO_EXPLOSIONSPIRITS, 5, 1); // prayer always shows successful Lv5 cast and disregards noskill restrictions
- }
- }
- }
+ if( ( sd->class_&MAPID_UPPERMASK ) == MAPID_SUPER_NOVICE )
+ {
+ unsigned int next = pc_nextbaseexp(sd);
+ if( next == 0 ) next = pc_thisbaseexp(sd);
+ if( next )
+ {
+ int percent = (int)( ( (float)sd->status.base_exp/(float)next )*1000. );
+
+ if( percent && ( percent%100 ) == 0 )
+ {// 10.0%, 20.0%, ..., 90.0%
+ sc_start(&sd->bl, status_skill2sc(MO_EXPLOSIONSPIRITS), 100, 17, skill_get_time(MO_EXPLOSIONSPIRITS, 5)); //Lv17-> +50 critical (noted by Poki) [Skotlex]
+ clif_skill_nodamage(&sd->bl, &sd->bl, MO_EXPLOSIONSPIRITS, 5, 1); // prayer always shows successful Lv5 cast and disregards noskill restrictions
+ }
+ }
+ }
}
@@ -12674,33 +12817,33 @@ void clif_parse_NoviceExplosionSpirits(int fd, struct map_session_data *sd)
/// 1 = offline
void clif_friendslist_toggle(struct map_session_data *sd,int account_id, int char_id, int online)
{
- int i, fd = sd->fd;
+ int i, fd = sd->fd;
- //Seek friend.
- for (i = 0; i < MAX_FRIENDS && sd->status.friends[i].char_id &&
- (sd->status.friends[i].char_id != char_id || sd->status.friends[i].account_id != account_id); i++);
+ //Seek friend.
+ for (i = 0; i < MAX_FRIENDS && sd->status.friends[i].char_id &&
+ (sd->status.friends[i].char_id != char_id || sd->status.friends[i].account_id != account_id); i++);
- if (i == MAX_FRIENDS || sd->status.friends[i].char_id == 0)
- return; //Not found
+ if(i == MAX_FRIENDS || sd->status.friends[i].char_id == 0)
+ return; //Not found
- WFIFOHEAD(fd,packet_len(0x206));
- WFIFOW(fd, 0) = 0x206;
- WFIFOL(fd, 2) = sd->status.friends[i].account_id;
- WFIFOL(fd, 6) = sd->status.friends[i].char_id;
- WFIFOB(fd,10) = !online; //Yeah, a 1 here means "logged off", go figure...
- WFIFOSET(fd, packet_len(0x206));
+ WFIFOHEAD(fd,packet_len(0x206));
+ WFIFOW(fd, 0) = 0x206;
+ WFIFOL(fd, 2) = sd->status.friends[i].account_id;
+ WFIFOL(fd, 6) = sd->status.friends[i].char_id;
+ WFIFOB(fd,10) = !online; //Yeah, a 1 here means "logged off", go figure...
+ WFIFOSET(fd, packet_len(0x206));
}
//Subfunction called from clif_foreachclient to toggle friends on/off [Skotlex]
int clif_friendslist_toggle_sub(struct map_session_data *sd,va_list ap)
{
- int account_id, char_id, online;
- account_id = va_arg(ap, int);
- char_id = va_arg(ap, int);
- online = va_arg(ap, int);
- clif_friendslist_toggle(sd, account_id, char_id, online);
- return 0;
+ int account_id, char_id, online;
+ account_id = va_arg(ap, int);
+ char_id = va_arg(ap, int);
+ online = va_arg(ap, int);
+ clif_friendslist_toggle(sd, account_id, char_id, online);
+ return 0;
}
@@ -12708,27 +12851,28 @@ int clif_friendslist_toggle_sub(struct map_session_data *sd,va_list ap)
/// 0201 <packet len>.W { <account id>.L <char id>.L <name>.24B }*
void clif_friendslist_send(struct map_session_data *sd)
{
- int i = 0, n, fd = sd->fd;
+ int i = 0, n, fd = sd->fd;
- // Send friends list
- WFIFOHEAD(fd, MAX_FRIENDS * 32 + 4);
- WFIFOW(fd, 0) = 0x201;
- for (i = 0; i < MAX_FRIENDS && sd->status.friends[i].char_id; i++) {
- WFIFOL(fd, 4 + 32 * i + 0) = sd->status.friends[i].account_id;
- WFIFOL(fd, 4 + 32 * i + 4) = sd->status.friends[i].char_id;
- memcpy(WFIFOP(fd, 4 + 32 * i + 8), &sd->status.friends[i].name, NAME_LENGTH);
- }
+ // Send friends list
+ WFIFOHEAD(fd, MAX_FRIENDS * 32 + 4);
+ WFIFOW(fd, 0) = 0x201;
+ for(i = 0; i < MAX_FRIENDS && sd->status.friends[i].char_id; i++)
+ {
+ WFIFOL(fd, 4 + 32 * i + 0) = sd->status.friends[i].account_id;
+ WFIFOL(fd, 4 + 32 * i + 4) = sd->status.friends[i].char_id;
+ memcpy(WFIFOP(fd, 4 + 32 * i + 8), &sd->status.friends[i].name, NAME_LENGTH);
+ }
- if (i) {
- WFIFOW(fd,2) = 4 + 32 * i;
- WFIFOSET(fd, WFIFOW(fd,2));
- }
+ if (i) {
+ WFIFOW(fd,2) = 4 + 32 * i;
+ WFIFOSET(fd, WFIFOW(fd,2));
+ }
- for (n = 0; n < i; n++) {
- //Sending the online players
- if (map_charid2sd(sd->status.friends[n].char_id))
- clif_friendslist_toggle(sd, sd->status.friends[n].account_id, sd->status.friends[n].char_id, 1);
- }
+ for (n = 0; n < i; n++)
+ { //Sending the online players
+ if (map_charid2sd(sd->status.friends[n].char_id))
+ clif_friendslist_toggle(sd, sd->status.friends[n].account_id, sd->status.friends[n].char_id, 1);
+ }
}
@@ -12741,34 +12885,35 @@ void clif_friendslist_send(struct map_session_data *sd)
/// 3 = MsgStringTable[820]="(%s)'s Friend List is full."
void clif_friendslist_reqack(struct map_session_data *sd, struct map_session_data *f_sd, int type)
{
- int fd;
- nullpo_retv(sd);
+ int fd;
+ nullpo_retv(sd);
- fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x209));
- WFIFOW(fd,0) = 0x209;
- WFIFOW(fd,2) = type;
- if (f_sd) {
- WFIFOL(fd,4) = f_sd->status.account_id;
- WFIFOL(fd,8) = f_sd->status.char_id;
- memcpy(WFIFOP(fd, 12), f_sd->status.name,NAME_LENGTH);
- }
- WFIFOSET(fd, packet_len(0x209));
+ fd = sd->fd;
+ WFIFOHEAD(fd,packet_len(0x209));
+ WFIFOW(fd,0) = 0x209;
+ WFIFOW(fd,2) = type;
+ if (f_sd)
+ {
+ WFIFOL(fd,4) = f_sd->status.account_id;
+ WFIFOL(fd,8) = f_sd->status.char_id;
+ memcpy(WFIFOP(fd, 12), f_sd->status.name,NAME_LENGTH);
+ }
+ WFIFOSET(fd, packet_len(0x209));
}
/// Asks a player for permission to be added as friend (ZC_REQ_ADD_FRIENDS).
/// 0207 <req account id>.L <req char id>.L <req char name>.24B
-void clif_friendlist_req(struct map_session_data *sd, int account_id, int char_id, const char *name)
+void clif_friendlist_req(struct map_session_data* sd, int account_id, int char_id, const char* name)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x207));
- WFIFOW(fd,0) = 0x207;
- WFIFOL(fd,2) = account_id;
- WFIFOL(fd,6) = char_id;
- memcpy(WFIFOP(fd,10), name, NAME_LENGTH);
- WFIFOSET(fd,packet_len(0x207));
+ WFIFOHEAD(fd,packet_len(0x207));
+ WFIFOW(fd,0) = 0x207;
+ WFIFOL(fd,2) = account_id;
+ WFIFOL(fd,6) = char_id;
+ memcpy(WFIFOP(fd,10), name, NAME_LENGTH);
+ WFIFOSET(fd,packet_len(0x207));
}
@@ -12776,48 +12921,48 @@ void clif_friendlist_req(struct map_session_data *sd, int account_id, int char_i
/// 0202 <name>.24B
void clif_parse_FriendsListAdd(int fd, struct map_session_data *sd)
{
- struct map_session_data *f_sd;
- int i;
+ struct map_session_data *f_sd;
+ int i;
- f_sd = map_nick2sd((char *)RFIFOP(fd,2));
+ f_sd = map_nick2sd((char*)RFIFOP(fd,2));
- // ensure that the request player's friend list is not full
- ARR_FIND(0, MAX_FRIENDS, i, sd->status.friends[i].char_id == 0);
+ // ensure that the request player's friend list is not full
+ ARR_FIND(0, MAX_FRIENDS, i, sd->status.friends[i].char_id == 0);
- if (i == MAX_FRIENDS) {
- clif_friendslist_reqack(sd, f_sd, 2);
- return;
- }
+ if( i == MAX_FRIENDS ) {
+ clif_friendslist_reqack(sd, f_sd, 2);
+ return;
+ }
- // Friend doesn't exist (no player with this name)
- if (f_sd == NULL) {
- clif_displaymessage(fd, msg_txt(3));
- return;
- }
+ // Friend doesn't exist (no player with this name)
+ if (f_sd == NULL) {
+ clif_displaymessage(fd, msg_txt(3));
+ return;
+ }
- if (sd->bl.id == f_sd->bl.id) {
- // adding oneself as friend
- return;
- }
+ if( sd->bl.id == f_sd->bl.id )
+ {// adding oneself as friend
+ return;
+ }
- // @noask [LuzZza]
- if (f_sd->state.noask) {
- clif_noask_sub(sd, f_sd, 5);
- return;
- }
+ // @noask [LuzZza]
+ if(f_sd->state.noask) {
+ clif_noask_sub(sd, f_sd, 5);
+ return;
+ }
- // Friend already exists
- for (i = 0; i < MAX_FRIENDS && sd->status.friends[i].char_id != 0; i++) {
- if (sd->status.friends[i].char_id == f_sd->status.char_id) {
- clif_displaymessage(fd, msg_txt(671)); //"Friend already exists."
- return;
- }
- }
+ // Friend already exists
+ for (i = 0; i < MAX_FRIENDS && sd->status.friends[i].char_id != 0; i++) {
+ if (sd->status.friends[i].char_id == f_sd->status.char_id) {
+ clif_displaymessage(fd, msg_txt(671)); //"Friend already exists."
+ return;
+ }
+ }
- f_sd->friend_req = sd->status.char_id;
- sd->friend_req = f_sd->status.char_id;
+ f_sd->friend_req = sd->status.char_id;
+ sd->friend_req = f_sd->status.char_id;
- clif_friendlist_req(f_sd, sd->status.account_id, sd->status.char_id, sd->status.name);
+ clif_friendlist_req(f_sd, sd->status.account_id, sd->status.char_id, sd->status.name);
}
@@ -12829,64 +12974,64 @@ void clif_parse_FriendsListAdd(int fd, struct map_session_data *sd)
/// 1 = accepted
void clif_parse_FriendsListReply(int fd, struct map_session_data *sd)
{
- struct map_session_data *f_sd;
- int account_id;
- char reply;
+ struct map_session_data *f_sd;
+ int account_id;
+ char reply;
- account_id = RFIFOL(fd,2);
- //char_id = RFIFOL(fd,6);
+ account_id = RFIFOL(fd,2);
+ //char_id = RFIFOL(fd,6);
#if PACKETVER < 6
- reply = RFIFOB(fd,10);
+ reply = RFIFOB(fd,10);
#else
- reply = RFIFOL(fd,10);
+ reply = RFIFOL(fd,10);
#endif
- if (sd->bl.id == account_id) {
- // adding oneself as friend
- return;
- }
-
- f_sd = map_id2sd(account_id); //The account id is the same as the bl.id of players.
- if (f_sd == NULL)
- return;
-
- if (reply == 0 || !(sd->friend_req == f_sd->status.char_id && f_sd->friend_req == sd->status.char_id))
- clif_friendslist_reqack(f_sd, sd, 1);
- else {
- int i;
- // Find an empty slot
- for (i = 0; i < MAX_FRIENDS; i++)
- if (f_sd->status.friends[i].char_id == 0)
- break;
- if (i == MAX_FRIENDS) {
- clif_friendslist_reqack(f_sd, sd, 2);
- return;
- }
-
- f_sd->status.friends[i].account_id = sd->status.account_id;
- f_sd->status.friends[i].char_id = sd->status.char_id;
- memcpy(f_sd->status.friends[i].name, sd->status.name, NAME_LENGTH);
- clif_friendslist_reqack(f_sd, sd, 0);
-
- if (battle_config.friend_auto_add) {
- // Also add f_sd to sd's friendlist.
- for (i = 0; i < MAX_FRIENDS; i++) {
- if (sd->status.friends[i].char_id == f_sd->status.char_id)
- return; //No need to add anything.
- if (sd->status.friends[i].char_id == 0)
- break;
- }
- if (i == MAX_FRIENDS) {
- clif_friendslist_reqack(sd, f_sd, 2);
- return;
- }
-
- sd->status.friends[i].account_id = f_sd->status.account_id;
- sd->status.friends[i].char_id = f_sd->status.char_id;
- memcpy(sd->status.friends[i].name, f_sd->status.name, NAME_LENGTH);
- clif_friendslist_reqack(sd, f_sd, 0);
- }
- }
+ if( sd->bl.id == account_id )
+ {// adding oneself as friend
+ return;
+ }
+
+ f_sd = map_id2sd(account_id); //The account id is the same as the bl.id of players.
+ if (f_sd == NULL)
+ return;
+
+ if (reply == 0 || !( sd->friend_req == f_sd->status.char_id && f_sd->friend_req == sd->status.char_id ) )
+ clif_friendslist_reqack(f_sd, sd, 1);
+ else {
+ int i;
+ // Find an empty slot
+ for (i = 0; i < MAX_FRIENDS; i++)
+ if (f_sd->status.friends[i].char_id == 0)
+ break;
+ if (i == MAX_FRIENDS) {
+ clif_friendslist_reqack(f_sd, sd, 2);
+ return;
+ }
+
+ f_sd->status.friends[i].account_id = sd->status.account_id;
+ f_sd->status.friends[i].char_id = sd->status.char_id;
+ memcpy(f_sd->status.friends[i].name, sd->status.name, NAME_LENGTH);
+ clif_friendslist_reqack(f_sd, sd, 0);
+
+ if (battle_config.friend_auto_add) {
+ // Also add f_sd to sd's friendlist.
+ for (i = 0; i < MAX_FRIENDS; i++) {
+ if (sd->status.friends[i].char_id == f_sd->status.char_id)
+ return; //No need to add anything.
+ if (sd->status.friends[i].char_id == 0)
+ break;
+ }
+ if (i == MAX_FRIENDS) {
+ clif_friendslist_reqack(sd, f_sd, 2);
+ return;
+ }
+
+ sd->status.friends[i].account_id = f_sd->status.account_id;
+ sd->status.friends[i].char_id = f_sd->status.char_id;
+ memcpy(sd->status.friends[i].name, f_sd->status.name, NAME_LENGTH);
+ clif_friendslist_reqack(sd, f_sd, 0);
+ }
+ }
}
@@ -12894,80 +13039,80 @@ void clif_parse_FriendsListReply(int fd, struct map_session_data *sd)
/// 0203 <account id>.L <char id>.L
void clif_parse_FriendsListRemove(int fd, struct map_session_data *sd)
{
- struct map_session_data *f_sd = NULL;
- int account_id, char_id;
- int i, j;
-
- account_id = RFIFOL(fd,2);
- char_id = RFIFOL(fd,6);
-
- // Search friend
- for (i = 0; i < MAX_FRIENDS &&
- (sd->status.friends[i].char_id != char_id || sd->status.friends[i].account_id != account_id); i++);
-
- if (i == MAX_FRIENDS) {
- clif_displaymessage(fd, msg_txt(672)); //"Name not found in list."
- return;
- }
-
- //remove from friend's list first
- if ((f_sd = map_id2sd(account_id)) && f_sd->status.char_id == char_id) {
- for (i = 0; i < MAX_FRIENDS &&
- (f_sd->status.friends[i].char_id != sd->status.char_id || f_sd->status.friends[i].account_id != sd->status.account_id); i++);
-
- if (i != MAX_FRIENDS) {
- // move all chars up
- for (j = i + 1; j < MAX_FRIENDS; j++)
- memcpy(&f_sd->status.friends[j-1], &f_sd->status.friends[j], sizeof(f_sd->status.friends[0]));
-
- memset(&f_sd->status.friends[MAX_FRIENDS-1], 0, sizeof(f_sd->status.friends[MAX_FRIENDS-1]));
- //should the guy be notified of some message? we should add it here if so
- WFIFOHEAD(f_sd->fd,packet_len(0x20a));
- WFIFOW(f_sd->fd,0) = 0x20a;
- WFIFOL(f_sd->fd,2) = sd->status.account_id;
- WFIFOL(f_sd->fd,6) = sd->status.char_id;
- WFIFOSET(f_sd->fd, packet_len(0x20a));
- }
-
- } else { //friend not online -- ask char server to delete from his friendlist
- if (chrif_removefriend(char_id,sd->status.char_id)) { // char-server offline, abort
- clif_displaymessage(fd, msg_txt(673)); //"This action can't be performed at the moment. Please try again later."
- return;
- }
- }
-
- // We can now delete from original requester
- for (i = 0; i < MAX_FRIENDS &&
- (sd->status.friends[i].char_id != char_id || sd->status.friends[i].account_id != account_id); i++);
- // move all chars up
- for (j = i + 1; j < MAX_FRIENDS; j++)
- memcpy(&sd->status.friends[j-1], &sd->status.friends[j], sizeof(sd->status.friends[0]));
-
- memset(&sd->status.friends[MAX_FRIENDS-1], 0, sizeof(sd->status.friends[MAX_FRIENDS-1]));
- clif_displaymessage(fd, msg_txt(674)); //"Friend removed"
-
- WFIFOHEAD(fd,packet_len(0x20a));
- WFIFOW(fd,0) = 0x20a;
- WFIFOL(fd,2) = account_id;
- WFIFOL(fd,6) = char_id;
- WFIFOSET(fd, packet_len(0x20a));
+ struct map_session_data *f_sd = NULL;
+ int account_id, char_id;
+ int i, j;
+
+ account_id = RFIFOL(fd,2);
+ char_id = RFIFOL(fd,6);
+
+ // Search friend
+ for (i = 0; i < MAX_FRIENDS &&
+ (sd->status.friends[i].char_id != char_id || sd->status.friends[i].account_id != account_id); i++);
+
+ if (i == MAX_FRIENDS) {
+ clif_displaymessage(fd, msg_txt(672)); //"Name not found in list."
+ return;
+ }
+
+ //remove from friend's list first
+ if( (f_sd = map_id2sd(account_id)) && f_sd->status.char_id == char_id) {
+ for (i = 0; i < MAX_FRIENDS &&
+ (f_sd->status.friends[i].char_id != sd->status.char_id || f_sd->status.friends[i].account_id != sd->status.account_id); i++);
+
+ if (i != MAX_FRIENDS) {
+ // move all chars up
+ for(j = i + 1; j < MAX_FRIENDS; j++)
+ memcpy(&f_sd->status.friends[j-1], &f_sd->status.friends[j], sizeof(f_sd->status.friends[0]));
+
+ memset(&f_sd->status.friends[MAX_FRIENDS-1], 0, sizeof(f_sd->status.friends[MAX_FRIENDS-1]));
+ //should the guy be notified of some message? we should add it here if so
+ WFIFOHEAD(f_sd->fd,packet_len(0x20a));
+ WFIFOW(f_sd->fd,0) = 0x20a;
+ WFIFOL(f_sd->fd,2) = sd->status.account_id;
+ WFIFOL(f_sd->fd,6) = sd->status.char_id;
+ WFIFOSET(f_sd->fd, packet_len(0x20a));
+ }
+
+ } else { //friend not online -- ask char server to delete from his friendlist
+ if(chrif_removefriend(char_id,sd->status.char_id)) { // char-server offline, abort
+ clif_displaymessage(fd, msg_txt(673)); //"This action can't be performed at the moment. Please try again later."
+ return;
+ }
+ }
+
+ // We can now delete from original requester
+ for (i = 0; i < MAX_FRIENDS &&
+ (sd->status.friends[i].char_id != char_id || sd->status.friends[i].account_id != account_id); i++);
+ // move all chars up
+ for(j = i + 1; j < MAX_FRIENDS; j++)
+ memcpy(&sd->status.friends[j-1], &sd->status.friends[j], sizeof(sd->status.friends[0]));
+
+ memset(&sd->status.friends[MAX_FRIENDS-1], 0, sizeof(sd->status.friends[MAX_FRIENDS-1]));
+ clif_displaymessage(fd, msg_txt(674)); //"Friend removed"
+
+ WFIFOHEAD(fd,packet_len(0x20a));
+ WFIFOW(fd,0) = 0x20a;
+ WFIFOL(fd,2) = account_id;
+ WFIFOL(fd,6) = char_id;
+ WFIFOSET(fd, packet_len(0x20a));
}
/// /pvpinfo list (ZC_ACK_PVPPOINT).
/// 0210 <char id>.L <account id>.L <win point>.L <lose point>.L <point>.L
-void clif_PVPInfo(struct map_session_data *sd)
+void clif_PVPInfo(struct map_session_data* sd)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x210));
- WFIFOW(fd,0) = 0x210;
- WFIFOL(fd,2) = sd->status.char_id;
- WFIFOL(fd,6) = sd->status.account_id;
- WFIFOL(fd,10) = sd->pvp_won; // times won
- WFIFOL(fd,14) = sd->pvp_lost; // times lost
- WFIFOL(fd,18) = sd->pvp_point;
- WFIFOSET(fd, packet_len(0x210));
+ WFIFOHEAD(fd,packet_len(0x210));
+ WFIFOW(fd,0) = 0x210;
+ WFIFOL(fd,2) = sd->status.char_id;
+ WFIFOL(fd,6) = sd->status.account_id;
+ WFIFOL(fd,10) = sd->pvp_won; // times won
+ WFIFOL(fd,14) = sd->pvp_lost; // times lost
+ WFIFOL(fd,18) = sd->pvp_point;
+ WFIFOSET(fd, packet_len(0x210));
}
@@ -12975,38 +13120,39 @@ void clif_PVPInfo(struct map_session_data *sd)
/// 020f <char id>.L <account id>.L
void clif_parse_PVPInfo(int fd,struct map_session_data *sd)
{
- // TODO: Is there a way to use this on an another player (char/acc id)?
- clif_PVPInfo(sd);
+ // TODO: Is there a way to use this on an another player (char/acc id)?
+ clif_PVPInfo(sd);
}
/// /blacksmith list (ZC_BLACKSMITH_RANK).
/// 0219 { <name>.24B }*10 { <point>.L }*10
-void clif_blacksmith(struct map_session_data *sd)
-{
- int i, fd = sd->fd;
- const char *name;
-
- WFIFOHEAD(fd,packet_len(0x219));
- WFIFOW(fd,0) = 0x219;
- //Packet size limits this list to 10 elements. [Skotlex]
- for (i = 0; i < 10 && i < MAX_FAME_LIST; i++) {
- if (smith_fame_list[i].id > 0) {
- if (strcmp(smith_fame_list[i].name, "-") == 0 &&
- (name = map_charid2nick(smith_fame_list[i].id)) != NULL) {
- strncpy((char *)(WFIFOP(fd, 2 + 24 * i)), name, NAME_LENGTH);
- } else
- strncpy((char *)(WFIFOP(fd, 2 + 24 * i)), smith_fame_list[i].name, NAME_LENGTH);
- } else
- strncpy((char *)(WFIFOP(fd, 2 + 24 * i)), "None", 5);
- WFIFOL(fd, 242 + i * 4) = smith_fame_list[i].fame;
- }
- for (; i < 10; i++) { //In case the MAX is less than 10.
- strncpy((char *)(WFIFOP(fd, 2 + 24 * i)), "Unavailable", 12);
- WFIFOL(fd, 242 + i * 4) = 0;
- }
-
- WFIFOSET(fd, packet_len(0x219));
+void clif_blacksmith(struct map_session_data* sd)
+{
+ int i, fd = sd->fd;
+ const char* name;
+
+ WFIFOHEAD(fd,packet_len(0x219));
+ WFIFOW(fd,0) = 0x219;
+ //Packet size limits this list to 10 elements. [Skotlex]
+ for (i = 0; i < 10 && i < MAX_FAME_LIST; i++) {
+ if (smith_fame_list[i].id > 0) {
+ if (strcmp(smith_fame_list[i].name, "-") == 0 &&
+ (name = map_charid2nick(smith_fame_list[i].id)) != NULL)
+ {
+ strncpy((char *)(WFIFOP(fd, 2 + 24 * i)), name, NAME_LENGTH);
+ } else
+ strncpy((char *)(WFIFOP(fd, 2 + 24 * i)), smith_fame_list[i].name, NAME_LENGTH);
+ } else
+ strncpy((char *)(WFIFOP(fd, 2 + 24 * i)), "None", 5);
+ WFIFOL(fd, 242 + i * 4) = smith_fame_list[i].fame;
+ }
+ for(;i < 10; i++) { //In case the MAX is less than 10.
+ strncpy((char *)(WFIFOP(fd, 2 + 24 * i)), "Unavailable", 12);
+ WFIFOL(fd, 242 + i * 4) = 0;
+ }
+
+ WFIFOSET(fd, packet_len(0x219));
}
@@ -13014,7 +13160,7 @@ void clif_blacksmith(struct map_session_data *sd)
/// 0217
void clif_parse_Blacksmith(int fd,struct map_session_data *sd)
{
- clif_blacksmith(sd);
+ clif_blacksmith(sd);
}
@@ -13022,43 +13168,44 @@ void clif_parse_Blacksmith(int fd,struct map_session_data *sd)
/// 021b <points>.L <total points>.L
void clif_fame_blacksmith(struct map_session_data *sd, int points)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x21b));
- WFIFOW(fd,0) = 0x21b;
- WFIFOL(fd,2) = points;
- WFIFOL(fd,6) = sd->status.fame;
- WFIFOSET(fd, packet_len(0x21b));
+ WFIFOHEAD(fd,packet_len(0x21b));
+ WFIFOW(fd,0) = 0x21b;
+ WFIFOL(fd,2) = points;
+ WFIFOL(fd,6) = sd->status.fame;
+ WFIFOSET(fd, packet_len(0x21b));
}
/// /alchemist list (ZC_ALCHEMIST_RANK).
/// 021a { <name>.24B }*10 { <point>.L }*10
-void clif_alchemist(struct map_session_data *sd)
-{
- int i, fd = sd->fd;
- const char *name;
-
- WFIFOHEAD(fd,packet_len(0x21a));
- WFIFOW(fd,0) = 0x21a;
- //Packet size limits this list to 10 elements. [Skotlex]
- for (i = 0; i < 10 && i < MAX_FAME_LIST; i++) {
- if (chemist_fame_list[i].id > 0) {
- if (strcmp(chemist_fame_list[i].name, "-") == 0 &&
- (name = map_charid2nick(chemist_fame_list[i].id)) != NULL) {
- memcpy(WFIFOP(fd, 2 + 24 * i), name, NAME_LENGTH);
- } else
- memcpy(WFIFOP(fd, 2 + 24 * i), chemist_fame_list[i].name, NAME_LENGTH);
- } else
- memcpy(WFIFOP(fd, 2 + 24 * i), "None", NAME_LENGTH);
- WFIFOL(fd, 242 + i * 4) = chemist_fame_list[i].fame;
- }
- for (; i < 10; i++) { //In case the MAX is less than 10.
- memcpy(WFIFOP(fd, 2 + 24 * i), "Unavailable", NAME_LENGTH);
- WFIFOL(fd, 242 + i * 4) = 0;
- }
-
- WFIFOSET(fd, packet_len(0x21a));
+void clif_alchemist(struct map_session_data* sd)
+{
+ int i, fd = sd->fd;
+ const char* name;
+
+ WFIFOHEAD(fd,packet_len(0x21a));
+ WFIFOW(fd,0) = 0x21a;
+ //Packet size limits this list to 10 elements. [Skotlex]
+ for (i = 0; i < 10 && i < MAX_FAME_LIST; i++) {
+ if (chemist_fame_list[i].id > 0) {
+ if (strcmp(chemist_fame_list[i].name, "-") == 0 &&
+ (name = map_charid2nick(chemist_fame_list[i].id)) != NULL)
+ {
+ memcpy(WFIFOP(fd, 2 + 24 * i), name, NAME_LENGTH);
+ } else
+ memcpy(WFIFOP(fd, 2 + 24 * i), chemist_fame_list[i].name, NAME_LENGTH);
+ } else
+ memcpy(WFIFOP(fd, 2 + 24 * i), "None", NAME_LENGTH);
+ WFIFOL(fd, 242 + i * 4) = chemist_fame_list[i].fame;
+ }
+ for(;i < 10; i++) { //In case the MAX is less than 10.
+ memcpy(WFIFOP(fd, 2 + 24 * i), "Unavailable", NAME_LENGTH);
+ WFIFOL(fd, 242 + i * 4) = 0;
+ }
+
+ WFIFOSET(fd, packet_len(0x21a));
}
@@ -13066,7 +13213,7 @@ void clif_alchemist(struct map_session_data *sd)
/// 0218
void clif_parse_Alchemist(int fd,struct map_session_data *sd)
{
- clif_alchemist(sd);
+ clif_alchemist(sd);
}
@@ -13074,42 +13221,43 @@ void clif_parse_Alchemist(int fd,struct map_session_data *sd)
/// 021c <points>.L <total points>.L
void clif_fame_alchemist(struct map_session_data *sd, int points)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x21c));
- WFIFOW(fd,0) = 0x21c;
- WFIFOL(fd,2) = points;
- WFIFOL(fd,6) = sd->status.fame;
- WFIFOSET(fd, packet_len(0x21c));
+ WFIFOHEAD(fd,packet_len(0x21c));
+ WFIFOW(fd,0) = 0x21c;
+ WFIFOL(fd,2) = points;
+ WFIFOL(fd,6) = sd->status.fame;
+ WFIFOSET(fd, packet_len(0x21c));
}
/// /taekwon list (ZC_TAEKWON_RANK).
/// 0226 { <name>.24B }*10 { <point>.L }*10
-void clif_taekwon(struct map_session_data *sd)
-{
- int i, fd = sd->fd;
- const char *name;
-
- WFIFOHEAD(fd,packet_len(0x226));
- WFIFOW(fd,0) = 0x226;
- //Packet size limits this list to 10 elements. [Skotlex]
- for (i = 0; i < 10 && i < MAX_FAME_LIST; i++) {
- if (taekwon_fame_list[i].id > 0) {
- if (strcmp(taekwon_fame_list[i].name, "-") == 0 &&
- (name = map_charid2nick(taekwon_fame_list[i].id)) != NULL) {
- memcpy(WFIFOP(fd, 2 + 24 * i), name, NAME_LENGTH);
- } else
- memcpy(WFIFOP(fd, 2 + 24 * i), taekwon_fame_list[i].name, NAME_LENGTH);
- } else
- memcpy(WFIFOP(fd, 2 + 24 * i), "None", NAME_LENGTH);
- WFIFOL(fd, 242 + i * 4) = taekwon_fame_list[i].fame;
- }
- for (; i < 10; i++) { //In case the MAX is less than 10.
- memcpy(WFIFOP(fd, 2 + 24 * i), "Unavailable", NAME_LENGTH);
- WFIFOL(fd, 242 + i * 4) = 0;
- }
- WFIFOSET(fd, packet_len(0x226));
+void clif_taekwon(struct map_session_data* sd)
+{
+ int i, fd = sd->fd;
+ const char* name;
+
+ WFIFOHEAD(fd,packet_len(0x226));
+ WFIFOW(fd,0) = 0x226;
+ //Packet size limits this list to 10 elements. [Skotlex]
+ for (i = 0; i < 10 && i < MAX_FAME_LIST; i++) {
+ if (taekwon_fame_list[i].id > 0) {
+ if (strcmp(taekwon_fame_list[i].name, "-") == 0 &&
+ (name = map_charid2nick(taekwon_fame_list[i].id)) != NULL)
+ {
+ memcpy(WFIFOP(fd, 2 + 24 * i), name, NAME_LENGTH);
+ } else
+ memcpy(WFIFOP(fd, 2 + 24 * i), taekwon_fame_list[i].name, NAME_LENGTH);
+ } else
+ memcpy(WFIFOP(fd, 2 + 24 * i), "None", NAME_LENGTH);
+ WFIFOL(fd, 242 + i * 4) = taekwon_fame_list[i].fame;
+ }
+ for(;i < 10; i++) { //In case the MAX is less than 10.
+ memcpy(WFIFOP(fd, 2 + 24 * i), "Unavailable", NAME_LENGTH);
+ WFIFOL(fd, 242 + i * 4) = 0;
+ }
+ WFIFOSET(fd, packet_len(0x226));
}
@@ -13117,7 +13265,7 @@ void clif_taekwon(struct map_session_data *sd)
/// 0225
void clif_parse_Taekwon(int fd,struct map_session_data *sd)
{
- clif_taekwon(sd);
+ clif_taekwon(sd);
}
@@ -13125,29 +13273,29 @@ void clif_parse_Taekwon(int fd,struct map_session_data *sd)
/// 0224 <points>.L <total points>.L
void clif_fame_taekwon(struct map_session_data *sd, int points)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x224));
- WFIFOW(fd,0) = 0x224;
- WFIFOL(fd,2) = points;
- WFIFOL(fd,6) = sd->status.fame;
- WFIFOSET(fd, packet_len(0x224));
+ WFIFOHEAD(fd,packet_len(0x224));
+ WFIFOW(fd,0) = 0x224;
+ WFIFOL(fd,2) = points;
+ WFIFOL(fd,6) = sd->status.fame;
+ WFIFOSET(fd, packet_len(0x224));
}
/// /pk list (ZC_KILLER_RANK).
/// 0238 { <name>.24B }*10 { <point>.L }*10
-void clif_ranking_pk(struct map_session_data *sd)
+void clif_ranking_pk(struct map_session_data* sd)
{
- int i, fd = sd->fd;
+ int i, fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x238));
- WFIFOW(fd,0) = 0x238;
- for (i=0; i<10; i++) {
- memcpy(WFIFOP(fd,i*24+2), "Unknown", NAME_LENGTH);
- WFIFOL(fd,i*4+242) = 0;
- }
- WFIFOSET(fd, packet_len(0x238));
+ WFIFOHEAD(fd,packet_len(0x238));
+ WFIFOW(fd,0) = 0x238;
+ for(i=0;i<10;i++){
+ memcpy(WFIFOP(fd,i*24+2), "Unknown", NAME_LENGTH);
+ WFIFOL(fd,i*4+242) = 0;
+ }
+ WFIFOSET(fd, packet_len(0x238));
}
@@ -13155,7 +13303,7 @@ void clif_ranking_pk(struct map_session_data *sd)
/// 0237
void clif_parse_RankingPk(int fd,struct map_session_data *sd)
{
- clif_ranking_pk(sd);
+ clif_ranking_pk(sd);
}
@@ -13167,21 +13315,21 @@ void clif_parse_RankingPk(int fd,struct map_session_data *sd)
/// 2 = star
void clif_parse_FeelSaveOk(int fd,struct map_session_data *sd)
{
- int i;
- if (sd->menuskill_id != SG_FEEL)
- return;
- i = sd->menuskill_val-1;
- if (i<0 || i >= MAX_PC_FEELHATE) return; //Bug?
+ int i;
+ if (sd->menuskill_id != SG_FEEL)
+ return;
+ i = sd->menuskill_val-1;
+ if (i<0 || i >= MAX_PC_FEELHATE) return; //Bug?
- sd->feel_map[i].index = map_id2index(sd->bl.m);
- sd->feel_map[i].m = sd->bl.m;
- pc_setglobalreg(sd,sg_info[i].feel_var,sd->feel_map[i].index);
+ sd->feel_map[i].index = map_id2index(sd->bl.m);
+ sd->feel_map[i].m = sd->bl.m;
+ pc_setglobalreg(sd,sg_info[i].feel_var,sd->feel_map[i].index);
- //Are these really needed? Shouldn't they show up automatically from the feel save packet?
- // clif_misceffect2(&sd->bl, 0x1b0);
- // clif_misceffect2(&sd->bl, 0x21f);
- clif_feel_info(sd, i, 0);
- clif_menuskill_clear(sd);
+//Are these really needed? Shouldn't they show up automatically from the feel save packet?
+// clif_misceffect2(&sd->bl, 0x1b0);
+// clif_misceffect2(&sd->bl, 0x21f);
+ clif_feel_info(sd, i, 0);
+ clif_menuskill_clear(sd);
}
@@ -13193,12 +13341,12 @@ void clif_parse_FeelSaveOk(int fd,struct map_session_data *sd)
/// 2 = star
void clif_feel_req(int fd, struct map_session_data *sd, int skilllv)
{
- WFIFOHEAD(fd,packet_len(0x253));
- WFIFOW(fd,0)=0x253;
- WFIFOB(fd,2)=TOB(skilllv-1);
- WFIFOSET(fd, packet_len(0x253));
- sd->menuskill_id = SG_FEEL;
- sd->menuskill_val = skilllv;
+ WFIFOHEAD(fd,packet_len(0x253));
+ WFIFOW(fd,0)=0x253;
+ WFIFOB(fd,2)=TOB(skilllv-1);
+ WFIFOSET(fd, packet_len(0x253));
+ sd->menuskill_id = SG_FEEL;
+ sd->menuskill_val = skilllv;
}
@@ -13206,7 +13354,7 @@ void clif_feel_req(int fd, struct map_session_data *sd, int skilllv)
/// 0231 <name>.24B
void clif_parse_ChangeHomunculusName(int fd, struct map_session_data *sd)
{
- merc_hom_change_name(sd,(char *)RFIFOP(fd,2));
+ merc_hom_change_name(sd,(char*)RFIFOP(fd,2));
}
@@ -13214,20 +13362,20 @@ void clif_parse_ChangeHomunculusName(int fd, struct map_session_data *sd)
/// 0234 <id>.L
void clif_parse_HomMoveToMaster(int fd, struct map_session_data *sd)
{
- int id = RFIFOL(fd,2); // Mercenary or Homunculus
- struct block_list *bl = NULL;
- struct unit_data *ud = NULL;
+ int id = RFIFOL(fd,2); // Mercenary or Homunculus
+ struct block_list *bl = NULL;
+ struct unit_data *ud = NULL;
- if (sd->md && sd->md->bl.id == id)
- bl = &sd->md->bl;
- else if (merc_is_hom_active(sd->hd) && sd->hd->bl.id == id)
- bl = &sd->hd->bl; // Moving Homunculus
- else
- return;
+ if( sd->md && sd->md->bl.id == id )
+ bl = &sd->md->bl;
+ else if( merc_is_hom_active(sd->hd) && sd->hd->bl.id == id )
+ bl = &sd->hd->bl; // Moving Homunculus
+ else
+ return;
- unit_calc_pos(bl, sd->bl.x, sd->bl.y, sd->ud.dir);
- ud = unit_bl2ud(bl);
- unit_walktoxy(bl, ud->to_x, ud->to_y, 4);
+ unit_calc_pos(bl, sd->bl.x, sd->bl.y, sd->ud.dir);
+ ud = unit_bl2ud(bl);
+ unit_walktoxy(bl, ud->to_x, ud->to_y, 4);
}
@@ -13235,20 +13383,20 @@ void clif_parse_HomMoveToMaster(int fd, struct map_session_data *sd)
/// 0232 <id>.L <position data>.3B
void clif_parse_HomMoveTo(int fd, struct map_session_data *sd)
{
- int id = RFIFOL(fd,2); // Mercenary or Homunculus
- struct block_list *bl = NULL;
- short x, y;
+ int id = RFIFOL(fd,2); // Mercenary or Homunculus
+ struct block_list *bl = NULL;
+ short x, y;
- RFIFOPOS(fd, packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1], &x, &y, NULL);
+ RFIFOPOS(fd, packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1], &x, &y, NULL);
- if (sd->md && sd->md->bl.id == id)
- bl = &sd->md->bl; // Moving Mercenary
- else if (merc_is_hom_active(sd->hd) && sd->hd->bl.id == id)
- bl = &sd->hd->bl; // Moving Homunculus
- else
- return;
+ if( sd->md && sd->md->bl.id == id )
+ bl = &sd->md->bl; // Moving Mercenary
+ else if( merc_is_hom_active(sd->hd) && sd->hd->bl.id == id )
+ bl = &sd->hd->bl; // Moving Homunculus
+ else
+ return;
- unit_walktoxy(bl, x, y, 4);
+ unit_walktoxy(bl, x, y, 4);
}
@@ -13258,19 +13406,19 @@ void clif_parse_HomMoveTo(int fd, struct map_session_data *sd)
/// always 0
void clif_parse_HomAttack(int fd,struct map_session_data *sd)
{
- struct block_list *bl = NULL;
- int id = RFIFOL(fd,2),
- target_id = RFIFOL(fd,6),
- action_type = RFIFOB(fd,10);
+ struct block_list *bl = NULL;
+ int id = RFIFOL(fd,2),
+ target_id = RFIFOL(fd,6),
+ action_type = RFIFOB(fd,10);
- if (merc_is_hom_active(sd->hd) && sd->hd->bl.id == id)
- bl = &sd->hd->bl;
- else if (sd->md && sd->md->bl.id == id)
- bl = &sd->md->bl;
- else return;
+ if( merc_is_hom_active(sd->hd) && sd->hd->bl.id == id )
+ bl = &sd->hd->bl;
+ else if( sd->md && sd->md->bl.id == id )
+ bl = &sd->md->bl;
+ else return;
- unit_stop_attack(bl);
- unit_attack(bl, target_id, action_type != 0);
+ unit_stop_attack(bl);
+ unit_attack(bl, target_id, action_type != 0);
}
@@ -13283,16 +13431,15 @@ void clif_parse_HomAttack(int fd,struct map_session_data *sd)
/// 1 = feed
/// 2 = delete
void clif_parse_HomMenu(int fd, struct map_session_data *sd)
-{
- //[orn]
- int cmd;
+{ //[orn]
+ int cmd;
- cmd = RFIFOW(fd,0);
+ cmd = RFIFOW(fd,0);
- if (!merc_is_hom_active(sd->hd))
- return;
+ if(!merc_is_hom_active(sd->hd))
+ return;
- merc_menu(sd,RFIFOB(fd,packet_db[sd->packet_ver][cmd].pos[1]));
+ merc_menu(sd,RFIFOB(fd,packet_db[sd->packet_ver][cmd].pos[1]));
}
@@ -13300,19 +13447,19 @@ void clif_parse_HomMenu(int fd, struct map_session_data *sd)
/// 0292
void clif_parse_AutoRevive(int fd, struct map_session_data *sd)
{
- int item_position = pc_search_inventory(sd, ITEMID_TOKEN_OF_SIEGFRIED);
+ int item_position = pc_search_inventory(sd, ITEMID_TOKEN_OF_SIEGFRIED);
- if (item_position < 0)
- return;
+ if (item_position < 0)
+ return;
- if (sd->sc.data[SC_HELLPOWER]) //Cannot res while under the effect of SC_HELLPOWER.
- return;
+ if (sd->sc.data[SC_HELLPOWER]) //Cannot res while under the effect of SC_HELLPOWER.
+ return;
- if (!status_revive(&sd->bl, 100, 100))
- return;
+ if (!status_revive(&sd->bl, 100, 100))
+ return;
- clif_skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION,4,1);
- pc_delitem(sd, item_position, 1, 0, 1, LOG_TYPE_CONSUME);
+ clif_skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION,4,1);
+ pc_delitem(sd, item_position, 1, 0, 1, LOG_TYPE_CONSUME);
}
@@ -13323,37 +13470,37 @@ void clif_parse_AutoRevive(int fd, struct map_session_data *sd)
/// <itemdefPower>.W <plusdefPower>.W <mdefPower>.W <plusmdefPower>.W
/// <hitSuccessValue>.W <avoidSuccessValue>.W <plusAvoidSuccessValue>.W
/// <criticalSuccessValue>.W <ASPD>.W <plusASPD>.W
-void clif_check(int fd, struct map_session_data *pl_sd)
-{
- WFIFOHEAD(fd,packet_len(0x214));
- WFIFOW(fd, 0) = 0x214;
- WFIFOB(fd, 2) = min(pl_sd->status.str, UINT8_MAX);
- WFIFOB(fd, 3) = pc_need_status_point(pl_sd, SP_STR, 1);
- WFIFOB(fd, 4) = min(pl_sd->status.agi, UINT8_MAX);
- WFIFOB(fd, 5) = pc_need_status_point(pl_sd, SP_AGI, 1);
- WFIFOB(fd, 6) = min(pl_sd->status.vit, UINT8_MAX);
- WFIFOB(fd, 7) = pc_need_status_point(pl_sd, SP_VIT, 1);
- WFIFOB(fd, 8) = min(pl_sd->status.int_, UINT8_MAX);
- WFIFOB(fd, 9) = pc_need_status_point(pl_sd, SP_INT, 1);
- WFIFOB(fd,10) = min(pl_sd->status.dex, UINT8_MAX);
- WFIFOB(fd,11) = pc_need_status_point(pl_sd, SP_DEX, 1);
- WFIFOB(fd,12) = min(pl_sd->status.luk, UINT8_MAX);
- WFIFOB(fd,13) = pc_need_status_point(pl_sd, SP_LUK, 1);
- WFIFOW(fd,14) = pl_sd->battle_status.batk+pl_sd->battle_status.rhw.atk+pl_sd->battle_status.lhw.atk;
- WFIFOW(fd,16) = pl_sd->battle_status.rhw.atk2+pl_sd->battle_status.lhw.atk2;
- WFIFOW(fd,18) = pl_sd->battle_status.matk_max;
- WFIFOW(fd,20) = pl_sd->battle_status.matk_min;
- WFIFOW(fd,22) = pl_sd->battle_status.def;
- WFIFOW(fd,24) = pl_sd->battle_status.def2;
- WFIFOW(fd,26) = pl_sd->battle_status.mdef;
- WFIFOW(fd,28) = pl_sd->battle_status.mdef2;
- WFIFOW(fd,30) = pl_sd->battle_status.hit;
- WFIFOW(fd,32) = pl_sd->battle_status.flee;
- WFIFOW(fd,34) = pl_sd->battle_status.flee2/10;
- WFIFOW(fd,36) = pl_sd->battle_status.cri/10;
- WFIFOW(fd,38) = (2000-pl_sd->battle_status.amotion)/10; // aspd
- WFIFOW(fd,40) = 0; // FIXME: What is 'plusASPD' supposed to be? Maybe adelay?
- WFIFOSET(fd,packet_len(0x214));
+void clif_check(int fd, struct map_session_data* pl_sd)
+{
+ WFIFOHEAD(fd,packet_len(0x214));
+ WFIFOW(fd, 0) = 0x214;
+ WFIFOB(fd, 2) = min(pl_sd->status.str, UINT8_MAX);
+ WFIFOB(fd, 3) = pc_need_status_point(pl_sd, SP_STR, 1);
+ WFIFOB(fd, 4) = min(pl_sd->status.agi, UINT8_MAX);
+ WFIFOB(fd, 5) = pc_need_status_point(pl_sd, SP_AGI, 1);
+ WFIFOB(fd, 6) = min(pl_sd->status.vit, UINT8_MAX);
+ WFIFOB(fd, 7) = pc_need_status_point(pl_sd, SP_VIT, 1);
+ WFIFOB(fd, 8) = min(pl_sd->status.int_, UINT8_MAX);
+ WFIFOB(fd, 9) = pc_need_status_point(pl_sd, SP_INT, 1);
+ WFIFOB(fd,10) = min(pl_sd->status.dex, UINT8_MAX);
+ WFIFOB(fd,11) = pc_need_status_point(pl_sd, SP_DEX, 1);
+ WFIFOB(fd,12) = min(pl_sd->status.luk, UINT8_MAX);
+ WFIFOB(fd,13) = pc_need_status_point(pl_sd, SP_LUK, 1);
+ WFIFOW(fd,14) = pl_sd->battle_status.batk+pl_sd->battle_status.rhw.atk+pl_sd->battle_status.lhw.atk;
+ WFIFOW(fd,16) = pl_sd->battle_status.rhw.atk2+pl_sd->battle_status.lhw.atk2;
+ WFIFOW(fd,18) = pl_sd->battle_status.matk_max;
+ WFIFOW(fd,20) = pl_sd->battle_status.matk_min;
+ WFIFOW(fd,22) = pl_sd->battle_status.def;
+ WFIFOW(fd,24) = pl_sd->battle_status.def2;
+ WFIFOW(fd,26) = pl_sd->battle_status.mdef;
+ WFIFOW(fd,28) = pl_sd->battle_status.mdef2;
+ WFIFOW(fd,30) = pl_sd->battle_status.hit;
+ WFIFOW(fd,32) = pl_sd->battle_status.flee;
+ WFIFOW(fd,34) = pl_sd->battle_status.flee2/10;
+ WFIFOW(fd,36) = pl_sd->battle_status.cri/10;
+ WFIFOW(fd,38) = (2000-pl_sd->battle_status.amotion)/10; // aspd
+ WFIFOW(fd,40) = 0; // FIXME: What is 'plusASPD' supposed to be? Maybe adelay?
+ WFIFOSET(fd,packet_len(0x214));
}
@@ -13362,19 +13509,20 @@ void clif_check(int fd, struct map_session_data *pl_sd)
/// 0213 <char name>.24B
void clif_parse_Check(int fd, struct map_session_data *sd)
{
- char charname[NAME_LENGTH];
- struct map_session_data *pl_sd;
+ char charname[NAME_LENGTH];
+ struct map_session_data* pl_sd;
- if (!pc_has_permission(sd, PC_PERM_USE_CHECK))
- return;
+ if(!pc_has_permission(sd, PC_PERM_USE_CHECK))
+ return;
- safestrncpy(charname, (const char *)RFIFOP(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]), sizeof(charname));
+ safestrncpy(charname, (const char*)RFIFOP(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]), sizeof(charname));
- if ((pl_sd = map_nick2sd(charname)) == NULL || pc_get_group_level(sd) < pc_get_group_level(pl_sd)) {
- return;
- }
+ if( ( pl_sd = map_nick2sd(charname) ) == NULL || pc_get_group_level(sd) < pc_get_group_level(pl_sd) )
+ {
+ return;
+ }
- clif_check(fd, pl_sd);
+ clif_check(fd, pl_sd);
}
@@ -13390,11 +13538,11 @@ void clif_parse_Check(int fd, struct map_session_data *sd)
/// 1 = failure
void clif_Mail_setattachment(int fd, int index, uint8 flag)
{
- WFIFOHEAD(fd,packet_len(0x255));
- WFIFOW(fd,0) = 0x255;
- WFIFOW(fd,2) = index;
- WFIFOB(fd,4) = flag;
- WFIFOSET(fd,packet_len(0x255));
+ WFIFOHEAD(fd,packet_len(0x255));
+ WFIFOW(fd,0) = 0x255;
+ WFIFOW(fd,2) = index;
+ WFIFOB(fd,4) = flag;
+ WFIFOSET(fd,packet_len(0x255));
}
@@ -13406,10 +13554,10 @@ void clif_Mail_setattachment(int fd, int index, uint8 flag)
/// 2 = too many items
void clif_Mail_getattachment(int fd, uint8 flag)
{
- WFIFOHEAD(fd,packet_len(0x245));
- WFIFOW(fd,0) = 0x245;
- WFIFOB(fd,2) = flag;
- WFIFOSET(fd,packet_len(0x245));
+ WFIFOHEAD(fd,packet_len(0x245));
+ WFIFOW(fd,0) = 0x245;
+ WFIFOB(fd,2) = flag;
+ WFIFOSET(fd,packet_len(0x245));
}
@@ -13420,10 +13568,10 @@ void clif_Mail_getattachment(int fd, uint8 flag)
/// 1 = recipinent does not exist
void clif_Mail_send(int fd, bool fail)
{
- WFIFOHEAD(fd,packet_len(0x249));
- WFIFOW(fd,0) = 0x249;
- WFIFOB(fd,2) = fail;
- WFIFOSET(fd,packet_len(0x249));
+ WFIFOHEAD(fd,packet_len(0x249));
+ WFIFOW(fd,0) = 0x249;
+ WFIFOB(fd,2) = fail;
+ WFIFOSET(fd,packet_len(0x249));
}
@@ -13434,11 +13582,11 @@ void clif_Mail_send(int fd, bool fail)
/// 1 = failure
void clif_Mail_delete(int fd, int mail_id, short fail)
{
- WFIFOHEAD(fd, packet_len(0x257));
- WFIFOW(fd,0) = 0x257;
- WFIFOL(fd,2) = mail_id;
- WFIFOW(fd,6) = fail;
- WFIFOSET(fd, packet_len(0x257));
+ WFIFOHEAD(fd, packet_len(0x257));
+ WFIFOW(fd,0) = 0x257;
+ WFIFOL(fd,2) = mail_id;
+ WFIFOW(fd,6) = fail;
+ WFIFOSET(fd, packet_len(0x257));
}
@@ -13449,11 +13597,11 @@ void clif_Mail_delete(int fd, int mail_id, short fail)
/// 1 = failure
void clif_Mail_return(int fd, int mail_id, short fail)
{
- WFIFOHEAD(fd,packet_len(0x274));
- WFIFOW(fd,0) = 0x274;
- WFIFOL(fd,2) = mail_id;
- WFIFOW(fd,6) = fail;
- WFIFOSET(fd,packet_len(0x274));
+ WFIFOHEAD(fd,packet_len(0x274));
+ WFIFOW(fd,0) = 0x274;
+ WFIFOL(fd,2) = mail_id;
+ WFIFOW(fd,6) = fail;
+ WFIFOSET(fd,packet_len(0x274));
}
@@ -13461,12 +13609,12 @@ void clif_Mail_return(int fd, int mail_id, short fail)
/// 024a <mail id>.L <title>.40B <sender>.24B
void clif_Mail_new(int fd, int mail_id, const char *sender, const char *title)
{
- WFIFOHEAD(fd,packet_len(0x24a));
- WFIFOW(fd,0) = 0x24a;
- WFIFOL(fd,2) = mail_id;
- safestrncpy((char *)WFIFOP(fd,6), title, MAIL_TITLE_LENGTH);
- safestrncpy((char *)WFIFOP(fd,46), sender, NAME_LENGTH);
- WFIFOSET(fd,packet_len(0x24a));
+ WFIFOHEAD(fd,packet_len(0x24a));
+ WFIFOW(fd,0) = 0x24a;
+ WFIFOL(fd,2) = mail_id;
+ safestrncpy((char*)WFIFOP(fd,6), title, MAIL_TITLE_LENGTH);
+ safestrncpy((char*)WFIFOP(fd,46), sender, NAME_LENGTH);
+ WFIFOSET(fd,packet_len(0x24a));
}
@@ -13477,10 +13625,10 @@ void clif_Mail_new(int fd, int mail_id, const char *sender, const char *title)
/// 1 = close
void clif_Mail_window(int fd, int flag)
{
- WFIFOHEAD(fd,packet_len(0x260));
- WFIFOW(fd,0) = 0x260;
- WFIFOL(fd,2) = flag;
- WFIFOSET(fd,packet_len(0x260));
+ WFIFOHEAD(fd,packet_len(0x260));
+ WFIFOW(fd,0) = 0x260;
+ WFIFOL(fd,2) = flag;
+ WFIFOSET(fd,packet_len(0x260));
}
@@ -13491,37 +13639,38 @@ void clif_Mail_window(int fd, int flag)
/// 1 = read
void clif_Mail_refreshinbox(struct map_session_data *sd)
{
- int fd = sd->fd;
- struct mail_data *md = &sd->mail.inbox;
- struct mail_message *msg;
- int len, i, j;
-
- len = 8 + (73 * md->amount);
-
- WFIFOHEAD(fd,len);
- WFIFOW(fd,0) = 0x240;
- WFIFOW(fd,2) = len;
- WFIFOL(fd,4) = md->amount;
- for (i = j = 0; i < MAIL_MAX_INBOX && j < md->amount; i++) {
- msg = &md->msg[i];
- if (msg->id < 1)
- continue;
-
- WFIFOL(fd,8+73*j) = msg->id;
- memcpy(WFIFOP(fd,12+73*j), msg->title, MAIL_TITLE_LENGTH);
- WFIFOB(fd,52+73*j) = (msg->status != MAIL_UNREAD);
- memcpy(WFIFOP(fd,53+73*j), msg->send_name, NAME_LENGTH);
- WFIFOL(fd,77+73*j) = (uint32)msg->timestamp;
- j++;
- }
- WFIFOSET(fd,len);
-
- if (md->full) {
- // TODO: is this official?
- char output[100];
- sprintf(output, "Inbox is full (Max %d). Delete some mails.", MAIL_MAX_INBOX);
- clif_disp_onlyself(sd, output, strlen(output));
- }
+ int fd = sd->fd;
+ struct mail_data *md = &sd->mail.inbox;
+ struct mail_message *msg;
+ int len, i, j;
+
+ len = 8 + (73 * md->amount);
+
+ WFIFOHEAD(fd,len);
+ WFIFOW(fd,0) = 0x240;
+ WFIFOW(fd,2) = len;
+ WFIFOL(fd,4) = md->amount;
+ for( i = j = 0; i < MAIL_MAX_INBOX && j < md->amount; i++ )
+ {
+ msg = &md->msg[i];
+ if (msg->id < 1)
+ continue;
+
+ WFIFOL(fd,8+73*j) = msg->id;
+ memcpy(WFIFOP(fd,12+73*j), msg->title, MAIL_TITLE_LENGTH);
+ WFIFOB(fd,52+73*j) = (msg->status != MAIL_UNREAD);
+ memcpy(WFIFOP(fd,53+73*j), msg->send_name, NAME_LENGTH);
+ WFIFOL(fd,77+73*j) = (uint32)msg->timestamp;
+ j++;
+ }
+ WFIFOSET(fd,len);
+
+ if( md->full )
+ {// TODO: is this official?
+ char output[100];
+ sprintf(output, "Inbox is full (Max %d). Delete some mails.", MAIL_MAX_INBOX);
+ clif_disp_onlyself(sd, output, strlen(output));
+ }
}
@@ -13529,15 +13678,15 @@ void clif_Mail_refreshinbox(struct map_session_data *sd)
/// 023f
void clif_parse_Mail_refreshinbox(int fd, struct map_session_data *sd)
{
- struct mail_data *md = &sd->mail.inbox;
+ struct mail_data* md = &sd->mail.inbox;
- if (md->amount < MAIL_MAX_INBOX && (md->full || sd->mail.changed))
- intif_Mail_requestinbox(sd->status.char_id, 1);
- else
- clif_Mail_refreshinbox(sd);
+ if( md->amount < MAIL_MAX_INBOX && (md->full || sd->mail.changed) )
+ intif_Mail_requestinbox(sd->status.char_id, 1);
+ else
+ clif_Mail_refreshinbox(sd);
- mail_removeitem(sd, 0);
- mail_removezeny(sd, 0);
+ mail_removeitem(sd, 0);
+ mail_removezeny(sd, 0);
}
@@ -13547,59 +13696,64 @@ void clif_parse_Mail_refreshinbox(int fd, struct map_session_data *sd)
/// <card1>.W <card2>.W <card3>.W <card4>.W <message>.?B
void clif_Mail_read(struct map_session_data *sd, int mail_id)
{
- int i, fd = sd->fd;
-
- ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id);
- if (i == MAIL_MAX_INBOX) {
- clif_Mail_return(sd->fd, mail_id, 1); // Mail doesn't exist
- ShowWarning("clif_parse_Mail_read: char '%s' trying to read a message not the inbox.\n", sd->status.name);
- return;
- } else {
- struct mail_message *msg = &sd->mail.inbox.msg[i];
- struct item *item = &msg->item;
- struct item_data *data;
- int msg_len = strlen(msg->body), len;
-
- if (msg_len == 0) {
- strcpy(msg->body, "(no message)");
- msg_len = strlen(msg->body);
- }
-
- len = 101 + msg_len;
-
- WFIFOHEAD(fd,len);
- WFIFOW(fd,0) = 0x242;
- WFIFOW(fd,2) = len;
- WFIFOL(fd,4) = msg->id;
- safestrncpy((char *)WFIFOP(fd,8), msg->title, MAIL_TITLE_LENGTH + 1);
- safestrncpy((char *)WFIFOP(fd,48), msg->send_name, NAME_LENGTH + 1);
- WFIFOL(fd,72) = 0;
- WFIFOL(fd,76) = msg->zeny;
-
- if (item->nameid && (data = itemdb_exists(item->nameid)) != NULL) {
- WFIFOL(fd,80) = item->amount;
- WFIFOW(fd,84) = (data->view_id)?data->view_id:item->nameid;
- WFIFOW(fd,86) = data->type;
- WFIFOB(fd,88) = item->identify;
- WFIFOB(fd,89) = item->attribute;
- WFIFOB(fd,90) = item->refine;
- WFIFOW(fd,91) = item->card[0];
- WFIFOW(fd,93) = item->card[1];
- WFIFOW(fd,95) = item->card[2];
- WFIFOW(fd,97) = item->card[3];
- } else // no item, set all to zero
- memset(WFIFOP(fd,80), 0x00, 19);
-
- WFIFOB(fd,99) = (unsigned char)msg_len;
- safestrncpy((char *)WFIFOP(fd,100), msg->body, msg_len + 1);
- WFIFOSET(fd,len);
-
- if (msg->status == MAIL_UNREAD) {
- msg->status = MAIL_READ;
- intif_Mail_read(mail_id);
- clif_parse_Mail_refreshinbox(fd, sd);
- }
- }
+ int i, fd = sd->fd;
+
+ ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id);
+ if( i == MAIL_MAX_INBOX )
+ {
+ clif_Mail_return(sd->fd, mail_id, 1); // Mail doesn't exist
+ ShowWarning("clif_parse_Mail_read: char '%s' trying to read a message not the inbox.\n", sd->status.name);
+ return;
+ }
+ else
+ {
+ struct mail_message *msg = &sd->mail.inbox.msg[i];
+ struct item *item = &msg->item;
+ struct item_data *data;
+ int msg_len = strlen(msg->body), len;
+
+ if( msg_len == 0 ) {
+ strcpy(msg->body, "(no message)");
+ msg_len = strlen(msg->body);
+ }
+
+ len = 101 + msg_len;
+
+ WFIFOHEAD(fd,len);
+ WFIFOW(fd,0) = 0x242;
+ WFIFOW(fd,2) = len;
+ WFIFOL(fd,4) = msg->id;
+ safestrncpy((char*)WFIFOP(fd,8), msg->title, MAIL_TITLE_LENGTH + 1);
+ safestrncpy((char*)WFIFOP(fd,48), msg->send_name, NAME_LENGTH + 1);
+ WFIFOL(fd,72) = 0;
+ WFIFOL(fd,76) = msg->zeny;
+
+ if( item->nameid && (data = itemdb_exists(item->nameid)) != NULL )
+ {
+ WFIFOL(fd,80) = item->amount;
+ WFIFOW(fd,84) = (data->view_id)?data->view_id:item->nameid;
+ WFIFOW(fd,86) = data->type;
+ WFIFOB(fd,88) = item->identify;
+ WFIFOB(fd,89) = item->attribute;
+ WFIFOB(fd,90) = item->refine;
+ WFIFOW(fd,91) = item->card[0];
+ WFIFOW(fd,93) = item->card[1];
+ WFIFOW(fd,95) = item->card[2];
+ WFIFOW(fd,97) = item->card[3];
+ }
+ else // no item, set all to zero
+ memset(WFIFOP(fd,80), 0x00, 19);
+
+ WFIFOB(fd,99) = (unsigned char)msg_len;
+ safestrncpy((char*)WFIFOP(fd,100), msg->body, msg_len + 1);
+ WFIFOSET(fd,len);
+
+ if (msg->status == MAIL_UNREAD) {
+ msg->status = MAIL_READ;
+ intif_Mail_read(mail_id);
+ clif_parse_Mail_refreshinbox(fd, sd);
+ }
+ }
}
@@ -13607,14 +13761,14 @@ void clif_Mail_read(struct map_session_data *sd, int mail_id)
/// 0241 <mail id>.L
void clif_parse_Mail_read(int fd, struct map_session_data *sd)
{
- int mail_id = RFIFOL(fd,2);
+ int mail_id = RFIFOL(fd,2);
- if (mail_id <= 0)
- return;
- if (mail_invalid_operation(sd))
- return;
+ if( mail_id <= 0 )
+ return;
+ if( mail_invalid_operation(sd) )
+ return;
- clif_Mail_read(sd, RFIFOL(fd,2));
+ clif_Mail_read(sd, RFIFOL(fd,2));
}
@@ -13622,61 +13776,66 @@ void clif_parse_Mail_read(int fd, struct map_session_data *sd)
/// 0244 <mail id>.L
void clif_parse_Mail_getattach(int fd, struct map_session_data *sd)
{
- int mail_id = RFIFOL(fd,2);
- int i;
- bool fail = false;
-
- if (!chrif_isconnected())
- return;
- if (mail_id <= 0)
- return;
- if (mail_invalid_operation(sd))
- return;
-
- ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id);
- if (i == MAIL_MAX_INBOX)
- return;
-
- if (sd->mail.inbox.msg[i].zeny < 1 && (sd->mail.inbox.msg[i].item.nameid < 1 || sd->mail.inbox.msg[i].item.amount < 1))
- return;
-
- if (sd->mail.inbox.msg[i].zeny + sd->status.zeny > MAX_ZENY) {
- clif_Mail_getattachment(fd, 1);
- return;
- }
-
- if (sd->mail.inbox.msg[i].item.nameid > 0) {
- struct item_data *data;
- unsigned int weight;
-
- if ((data = itemdb_exists(sd->mail.inbox.msg[i].item.nameid)) == NULL)
- return;
-
- switch (pc_checkadditem(sd, data->nameid, sd->mail.inbox.msg[i].item.amount)) {
- case ADDITEM_NEW:
- fail = (pc_inventoryblank(sd) == 0);
- break;
- case ADDITEM_OVERAMOUNT:
- fail = true;
- }
-
- if (fail) {
- clif_Mail_getattachment(fd, 1);
- return;
- }
-
- weight = data->weight * sd->mail.inbox.msg[i].item.amount;
- if (sd->weight + weight > sd->max_weight) {
- clif_Mail_getattachment(fd, 2);
- return;
- }
- }
-
- sd->mail.inbox.msg[i].zeny = 0;
- memset(&sd->mail.inbox.msg[i].item, 0, sizeof(struct item));
- clif_Mail_read(sd, mail_id);
-
- intif_Mail_getattach(sd->status.char_id, mail_id);
+ int mail_id = RFIFOL(fd,2);
+ int i;
+ bool fail = false;
+
+ if( !chrif_isconnected() )
+ return;
+ if( mail_id <= 0 )
+ return;
+ if( mail_invalid_operation(sd) )
+ return;
+
+ ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id);
+ if( i == MAIL_MAX_INBOX )
+ return;
+
+ if( sd->mail.inbox.msg[i].zeny < 1 && (sd->mail.inbox.msg[i].item.nameid < 1 || sd->mail.inbox.msg[i].item.amount < 1) )
+ return;
+
+ if( sd->mail.inbox.msg[i].zeny + sd->status.zeny > MAX_ZENY )
+ {
+ clif_Mail_getattachment(fd, 1);
+ return;
+ }
+
+ if( sd->mail.inbox.msg[i].item.nameid > 0 )
+ {
+ struct item_data *data;
+ unsigned int weight;
+
+ if ((data = itemdb_exists(sd->mail.inbox.msg[i].item.nameid)) == NULL)
+ return;
+
+ switch( pc_checkadditem(sd, data->nameid, sd->mail.inbox.msg[i].item.amount) )
+ {
+ case ADDITEM_NEW:
+ fail = ( pc_inventoryblank(sd) == 0 );
+ break;
+ case ADDITEM_OVERAMOUNT:
+ fail = true;
+ }
+
+ if( fail )
+ {
+ clif_Mail_getattachment(fd, 1);
+ return;
+ }
+
+ weight = data->weight * sd->mail.inbox.msg[i].item.amount;
+ if( sd->weight + weight > sd->max_weight )
+ {
+ clif_Mail_getattachment(fd, 2);
+ return;
+ }
+ }
+
+ sd->mail.inbox.msg[i].zeny = 0;
+ memset(&sd->mail.inbox.msg[i].item, 0, sizeof(struct item));
+ clif_Mail_read(sd, mail_id);
+
+ intif_Mail_getattach(sd->status.char_id, mail_id);
}
@@ -13684,28 +13843,29 @@ void clif_parse_Mail_getattach(int fd, struct map_session_data *sd)
/// 0243 <mail id>.L
void clif_parse_Mail_delete(int fd, struct map_session_data *sd)
{
- int mail_id = RFIFOL(fd,2);
- int i;
+ int mail_id = RFIFOL(fd,2);
+ int i;
- if (!chrif_isconnected())
- return;
- if (mail_id <= 0)
- return;
- if (mail_invalid_operation(sd))
- return;
+ if( !chrif_isconnected() )
+ return;
+ if( mail_id <= 0 )
+ return;
+ if( mail_invalid_operation(sd) )
+ return;
- ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id);
- if (i < MAIL_MAX_INBOX) {
- struct mail_message *msg = &sd->mail.inbox.msg[i];
+ ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id);
+ if (i < MAIL_MAX_INBOX)
+ {
+ struct mail_message *msg = &sd->mail.inbox.msg[i];
- if ((msg->item.nameid > 0 && msg->item.amount > 0) || msg->zeny > 0) {
- // can't delete mail without removing attachment first
- clif_Mail_delete(sd->fd, mail_id, 1);
- return;
- }
+ if( (msg->item.nameid > 0 && msg->item.amount > 0) || msg->zeny > 0 )
+ {// can't delete mail without removing attachment first
+ clif_Mail_delete(sd->fd, mail_id, 1);
+ return;
+ }
- intif_Mail_delete(sd->status.char_id, mail_id);
- }
+ intif_Mail_delete(sd->status.char_id, mail_id);
+ }
}
@@ -13713,19 +13873,19 @@ void clif_parse_Mail_delete(int fd, struct map_session_data *sd)
/// 0273 <mail id>.L <receive name>.24B
void clif_parse_Mail_return(int fd, struct map_session_data *sd)
{
- int mail_id = RFIFOL(fd,2);
- int i;
+ int mail_id = RFIFOL(fd,2);
+ int i;
- if (mail_id <= 0)
- return;
- if (mail_invalid_operation(sd))
- return;
+ if( mail_id <= 0 )
+ return;
+ if( mail_invalid_operation(sd) )
+ return;
- ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id);
- if (i < MAIL_MAX_INBOX && sd->mail.inbox.msg[i].send_id != 0)
- intif_Mail_return(sd->status.char_id, mail_id);
- else
- clif_Mail_return(sd->fd, mail_id, 1);
+ ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id);
+ if( i < MAIL_MAX_INBOX && sd->mail.inbox.msg[i].send_id != 0 )
+ intif_Mail_return(sd->status.char_id, mail_id);
+ else
+ clif_Mail_return(sd->fd, mail_id, 1);
}
@@ -13733,17 +13893,17 @@ void clif_parse_Mail_return(int fd, struct map_session_data *sd)
/// 0247 <index>.W <amount>.L
void clif_parse_Mail_setattach(int fd, struct map_session_data *sd)
{
- int idx = RFIFOW(fd,2);
- int amount = RFIFOL(fd,4);
- unsigned char flag;
+ int idx = RFIFOW(fd,2);
+ int amount = RFIFOL(fd,4);
+ unsigned char flag;
- if (!chrif_isconnected())
- return;
- if (idx < 0 || amount < 0)
- return;
+ if( !chrif_isconnected() )
+ return;
+ if (idx < 0 || amount < 0)
+ return;
- flag = mail_setitem(sd, idx, amount);
- clif_Mail_setattachment(fd,idx,flag);
+ flag = mail_setitem(sd, idx, amount);
+ clif_Mail_setattachment(fd,idx,flag);
}
@@ -13755,12 +13915,12 @@ void clif_parse_Mail_setattach(int fd, struct map_session_data *sd)
/// 2 = remove zeny
void clif_parse_Mail_winopen(int fd, struct map_session_data *sd)
{
- int flag = RFIFOW(fd,2);
+ int flag = RFIFOW(fd,2);
- if (flag == 0 || flag == 1)
- mail_removeitem(sd, 0);
- if (flag == 0 || flag == 2)
- mail_removezeny(sd, 0);
+ if (flag == 0 || flag == 1)
+ mail_removeitem(sd, 0);
+ if (flag == 0 || flag == 2)
+ mail_removezeny(sd, 0);
}
@@ -13768,59 +13928,56 @@ void clif_parse_Mail_winopen(int fd, struct map_session_data *sd)
/// 0248 <packet len>.W <recipient>.24B <title>.40B <body len>.B <body>.?B
void clif_parse_Mail_send(int fd, struct map_session_data *sd)
{
- struct mail_message msg;
- int body_len;
+ struct mail_message msg;
+ int body_len;
- if (!chrif_isconnected())
- return;
- if (sd->state.trading)
- return;
+ if( !chrif_isconnected() )
+ return;
+ if( sd->state.trading )
+ return;
- if (RFIFOW(fd,2) < 69) {
- ShowWarning("Invalid Msg Len from account %d.\n", sd->status.account_id);
- return;
- }
+ if( RFIFOW(fd,2) < 69 ) {
+ ShowWarning("Invalid Msg Len from account %d.\n", sd->status.account_id);
+ return;
+ }
- if (DIFF_TICK(sd->cansendmail_tick, gettick()) > 0) {
- clif_displaymessage(sd->fd,msg_txt(675)); //"Cannot send mails too fast!!."
- clif_Mail_send(fd, true); // fail
- return;
- }
+ if( DIFF_TICK(sd->cansendmail_tick, gettick()) > 0 )
+ {
+ clif_displaymessage(sd->fd,msg_txt(675)); //"Cannot send mails too fast!!."
+ clif_Mail_send(fd, true); // fail
+ return;
+ }
- body_len = RFIFOB(fd,68);
+ body_len = RFIFOB(fd,68);
- if (body_len > MAIL_BODY_LENGTH)
- body_len = MAIL_BODY_LENGTH;
+ if (body_len > MAIL_BODY_LENGTH)
+ body_len = MAIL_BODY_LENGTH;
- if (!mail_setattachment(sd, &msg)) {
- // Invalid Append condition
- clif_Mail_send(sd->fd, true); // fail
- mail_removeitem(sd,0);
- mail_removezeny(sd,0);
- return;
- }
+ if( !mail_setattachment(sd, &msg) )
+ { // Invalid Append condition
+ clif_Mail_send(sd->fd, true); // fail
+ mail_removeitem(sd,0);
+ mail_removezeny(sd,0);
+ return;
+ }
- msg.id = 0; // id will be assigned by charserver
- msg.send_id = sd->status.char_id;
- msg.dest_id = 0; // will attempt to resolve name
- safestrncpy(msg.send_name, sd->status.name, NAME_LENGTH);
- safestrncpy(msg.dest_name, (char *)RFIFOP(fd,4), NAME_LENGTH);
- safestrncpy(msg.title, (char *)RFIFOP(fd,28), MAIL_TITLE_LENGTH);
+ msg.id = 0; // id will be assigned by charserver
+ msg.send_id = sd->status.char_id;
+ msg.dest_id = 0; // will attempt to resolve name
+ safestrncpy(msg.send_name, sd->status.name, NAME_LENGTH);
+ safestrncpy(msg.dest_name, (char*)RFIFOP(fd,4), NAME_LENGTH);
+ safestrncpy(msg.title, (char*)RFIFOP(fd,28), MAIL_TITLE_LENGTH);
- if (msg.title[0] == '\0') {
- return; // Message has no length and somehow client verification was skipped.
- }
-
- if (body_len)
- safestrncpy(msg.body, (char *)RFIFOP(fd,69), body_len + 1);
- else
- memset(msg.body, 0x00, MAIL_BODY_LENGTH);
+ if (body_len)
+ safestrncpy(msg.body, (char*)RFIFOP(fd,69), body_len + 1);
+ else
+ memset(msg.body, 0x00, MAIL_BODY_LENGTH);
- msg.timestamp = time(NULL);
- if (!intif_Mail_send(sd->status.account_id, &msg))
- mail_deliveryfail(sd, &msg);
+ msg.timestamp = time(NULL);
+ if( !intif_Mail_send(sd->status.account_id, &msg) )
+ mail_deliveryfail(sd, &msg);
- sd->cansendmail_tick = gettick() + 1000; // 1 Second flood Protection
+ sd->cansendmail_tick = gettick() + 1000; // 1 Second flood Protection
}
@@ -13835,15 +13992,15 @@ void clif_parse_Mail_send(int fd, struct map_session_data *sd)
/// 1 = close
void clif_Auction_openwindow(struct map_session_data *sd)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- if (sd->state.storage_flag || sd->state.vending || sd->state.buyingstore || sd->state.trading)
- return;
+ if( sd->state.storage_flag || sd->state.vending || sd->state.buyingstore || sd->state.trading )
+ return;
- WFIFOHEAD(fd,packet_len(0x25f));
- WFIFOW(fd,0) = 0x25f;
- WFIFOL(fd,2) = 0;
- WFIFOSET(fd,packet_len(0x25f));
+ WFIFOHEAD(fd,packet_len(0x25f));
+ WFIFOW(fd,0) = 0x25f;
+ WFIFOL(fd,2) = 0;
+ WFIFOSET(fd,packet_len(0x25f));
}
@@ -13851,44 +14008,45 @@ void clif_Auction_openwindow(struct map_session_data *sd)
/// 0252 <packet len>.W <pages>.L <count>.L { <auction id>.L <seller name>.24B <name id>.W <type>.L <amount>.W <identified>.B <damaged>.B <refine>.B <card1>.W <card2>.W <card3>.W <card4>.W <now price>.L <max price>.L <buyer name>.24B <delete time>.L }*
void clif_Auction_results(struct map_session_data *sd, short count, short pages, uint8 *buf)
{
- int i, fd = sd->fd, len = sizeof(struct auction_data);
- struct auction_data auction;
- struct item_data *item;
- int k;
-
- WFIFOHEAD(fd,12 + (count * 83));
- WFIFOW(fd,0) = 0x252;
- WFIFOW(fd,2) = 12 + (count * 83);
- WFIFOL(fd,4) = pages;
- WFIFOL(fd,8) = count;
-
- for (i = 0; i < count; i++) {
- memcpy(&auction, RBUFP(buf,i * len), len);
- k = 12 + (i * 83);
-
- WFIFOL(fd,k) = auction.auction_id;
- safestrncpy((char *)WFIFOP(fd,4+k), auction.seller_name, NAME_LENGTH);
-
- if ((item = itemdb_exists(auction.item.nameid)) != NULL && item->view_id > 0)
- WFIFOW(fd,28+k) = item->view_id;
- else
- WFIFOW(fd,28+k) = auction.item.nameid;
-
- WFIFOL(fd,30+k) = auction.type;
- WFIFOW(fd,34+k) = auction.item.amount; // Always 1
- WFIFOB(fd,36+k) = auction.item.identify;
- WFIFOB(fd,37+k) = auction.item.attribute;
- WFIFOB(fd,38+k) = auction.item.refine;
- WFIFOW(fd,39+k) = auction.item.card[0];
- WFIFOW(fd,41+k) = auction.item.card[1];
- WFIFOW(fd,43+k) = auction.item.card[2];
- WFIFOW(fd,45+k) = auction.item.card[3];
- WFIFOL(fd,47+k) = auction.price;
- WFIFOL(fd,51+k) = auction.buynow;
- safestrncpy((char *)WFIFOP(fd,55+k), auction.buyer_name, NAME_LENGTH);
- WFIFOL(fd,79+k) = (uint32)auction.timestamp;
- }
- WFIFOSET(fd,WFIFOW(fd,2));
+ int i, fd = sd->fd, len = sizeof(struct auction_data);
+ struct auction_data auction;
+ struct item_data *item;
+ int k;
+
+ WFIFOHEAD(fd,12 + (count * 83));
+ WFIFOW(fd,0) = 0x252;
+ WFIFOW(fd,2) = 12 + (count * 83);
+ WFIFOL(fd,4) = pages;
+ WFIFOL(fd,8) = count;
+
+ for( i = 0; i < count; i++ )
+ {
+ memcpy(&auction, RBUFP(buf,i * len), len);
+ k = 12 + (i * 83);
+
+ WFIFOL(fd,k) = auction.auction_id;
+ safestrncpy((char*)WFIFOP(fd,4+k), auction.seller_name, NAME_LENGTH);
+
+ if( (item = itemdb_exists(auction.item.nameid)) != NULL && item->view_id > 0 )
+ WFIFOW(fd,28+k) = item->view_id;
+ else
+ WFIFOW(fd,28+k) = auction.item.nameid;
+
+ WFIFOL(fd,30+k) = auction.type;
+ WFIFOW(fd,34+k) = auction.item.amount; // Always 1
+ WFIFOB(fd,36+k) = auction.item.identify;
+ WFIFOB(fd,37+k) = auction.item.attribute;
+ WFIFOB(fd,38+k) = auction.item.refine;
+ WFIFOW(fd,39+k) = auction.item.card[0];
+ WFIFOW(fd,41+k) = auction.item.card[1];
+ WFIFOW(fd,43+k) = auction.item.card[2];
+ WFIFOW(fd,45+k) = auction.item.card[3];
+ WFIFOL(fd,47+k) = auction.price;
+ WFIFOL(fd,51+k) = auction.buynow;
+ safestrncpy((char*)WFIFOP(fd,55+k), auction.buyer_name, NAME_LENGTH);
+ WFIFOL(fd,79+k) = (uint32)auction.timestamp;
+ }
+ WFIFOSET(fd,WFIFOW(fd,2));
}
@@ -13899,11 +14057,11 @@ void clif_Auction_results(struct map_session_data *sd, short count, short pages,
/// 1 = failure
static void clif_Auction_setitem(int fd, int index, bool fail)
{
- WFIFOHEAD(fd,packet_len(0x256));
- WFIFOW(fd,0) = 0x256;
- WFIFOW(fd,2) = index;
- WFIFOB(fd,4) = fail;
- WFIFOSET(fd,packet_len(0x256));
+ WFIFOHEAD(fd,packet_len(0x256));
+ WFIFOW(fd,0) = 0x256;
+ WFIFOW(fd,2) = index;
+ WFIFOB(fd,4) = fail;
+ WFIFOSET(fd,packet_len(0x256));
}
@@ -13915,10 +14073,10 @@ static void clif_Auction_setitem(int fd, int index, bool fail)
/// ? = junk, uninitialized value (ex. when switching between list filters)
void clif_parse_Auction_cancelreg(int fd, struct map_session_data *sd)
{
- if (sd->auction.amount > 0)
- clif_additem(sd, sd->auction.index, sd->auction.amount, 0);
+ if( sd->auction.amount > 0 )
+ clif_additem(sd, sd->auction.index, sd->auction.amount, 0);
- sd->auction.amount = 0;
+ sd->auction.amount = 0;
}
@@ -13926,40 +14084,41 @@ void clif_parse_Auction_cancelreg(int fd, struct map_session_data *sd)
/// 024c <index>.W <count>.L
void clif_parse_Auction_setitem(int fd, struct map_session_data *sd)
{
- int idx = RFIFOW(fd,2) - 2;
- int amount = RFIFOL(fd,4); // Always 1
- struct item_data *item;
+ int idx = RFIFOW(fd,2) - 2;
+ int amount = RFIFOL(fd,4); // Always 1
+ struct item_data *item;
- if (sd->auction.amount > 0)
- sd->auction.amount = 0;
+ if( sd->auction.amount > 0 )
+ sd->auction.amount = 0;
- if (idx < 0 || idx >= MAX_INVENTORY) {
- ShowWarning("Character %s trying to set invalid item index in auctions.\n", sd->status.name);
- return;
- }
+ if( idx < 0 || idx >= MAX_INVENTORY )
+ {
+ ShowWarning("Character %s trying to set invalid item index in auctions.\n", sd->status.name);
+ return;
+ }
- if (amount != 1 || amount > sd->status.inventory[idx].amount) {
- // By client, amount is always set to 1. Maybe this is a future implementation.
- ShowWarning("Character %s trying to set invalid amount in auctions.\n", sd->status.name);
- return;
- }
+ if( amount != 1 || amount > sd->status.inventory[idx].amount )
+ { // By client, amount is always set to 1. Maybe this is a future implementation.
+ ShowWarning("Character %s trying to set invalid amount in auctions.\n", sd->status.name);
+ return;
+ }
- if ((item = itemdb_exists(sd->status.inventory[idx].nameid)) != NULL && !(item->type == IT_ARMOR || item->type == IT_PETARMOR || item->type == IT_WEAPON || item->type == IT_CARD || item->type == IT_ETC)) {
- // Consumable or pets are not allowed
- clif_Auction_setitem(sd->fd, idx, true);
- return;
- }
+ if( (item = itemdb_exists(sd->status.inventory[idx].nameid)) != NULL && !(item->type == IT_ARMOR || item->type == IT_PETARMOR || item->type == IT_WEAPON || item->type == IT_CARD || item->type == IT_ETC) )
+ { // Consumable or pets are not allowed
+ clif_Auction_setitem(sd->fd, idx, true);
+ return;
+ }
- if (!pc_can_give_items(sd) || sd->status.inventory[idx].expire_time ||
- !sd->status.inventory[idx].identify ||
- !itemdb_canauction(&sd->status.inventory[idx],pc_get_group_level(sd))) { // Quest Item or something else
- clif_Auction_setitem(sd->fd, idx, true);
- return;
- }
+ if( !pc_can_give_items(sd) || sd->status.inventory[idx].expire_time ||
+ !sd->status.inventory[idx].identify ||
+ !itemdb_canauction(&sd->status.inventory[idx],pc_get_group_level(sd)) ) { // Quest Item or something else
+ clif_Auction_setitem(sd->fd, idx, true);
+ return;
+ }
- sd->auction.index = idx;
- sd->auction.amount = amount;
- clif_Auction_setitem(fd, idx + 2, false);
+ sd->auction.index = idx;
+ sd->auction.amount = amount;
+ clif_Auction_setitem(fd, idx + 2, false);
}
/// Result from an auction action (ZC_AUCTION_RESULT).
@@ -13977,10 +14136,10 @@ void clif_parse_Auction_setitem(int fd, struct map_session_data *sd)
/// 9 = You cannot place more than 5 bids at a time
void clif_Auction_message(int fd, unsigned char flag)
{
- WFIFOHEAD(fd,packet_len(0x250));
- WFIFOW(fd,0) = 0x250;
- WFIFOB(fd,2) = flag;
- WFIFOSET(fd,packet_len(0x250));
+ WFIFOHEAD(fd,packet_len(0x250));
+ WFIFOW(fd,0) = 0x250;
+ WFIFOB(fd,2) = flag;
+ WFIFOSET(fd,packet_len(0x250));
}
@@ -13992,10 +14151,10 @@ void clif_Auction_message(int fd, unsigned char flag)
/// 2 = Auction ID is incorrect
void clif_Auction_close(int fd, unsigned char flag)
{
- WFIFOHEAD(fd,packet_len(0x25e));
- WFIFOW(fd,0) = 0x25d; // BUG: The client identifies this packet as 0x25d (CZ_AUCTION_REQ_MY_SELL_STOP)
- WFIFOW(fd,2) = flag;
- WFIFOSET(fd,packet_len(0x25e));
+ WFIFOHEAD(fd,packet_len(0x25e));
+ WFIFOW(fd,0) = 0x25d; // BUG: The client identifies this packet as 0x25d (CZ_AUCTION_REQ_MY_SELL_STOP)
+ WFIFOW(fd,2) = flag;
+ WFIFOSET(fd,packet_len(0x25e));
}
@@ -14003,75 +14162,81 @@ void clif_Auction_close(int fd, unsigned char flag)
/// 024d <now money>.L <max money>.L <delete hour>.W
void clif_parse_Auction_register(int fd, struct map_session_data *sd)
{
- struct auction_data auction;
- struct item_data *item;
-
- auction.price = RFIFOL(fd,2);
- auction.buynow = RFIFOL(fd,6);
- auction.hours = RFIFOW(fd,10);
-
- // Invalid Situations...
- if (sd->auction.amount < 1) {
- ShowWarning("Character %s trying to register auction without item.\n", sd->status.name);
- return;
- }
-
- if (auction.price >= auction.buynow) {
- ShowWarning("Character %s trying to alter auction prices.\n", sd->status.name);
- return;
- }
-
- if (auction.hours < 1 || auction.hours > 48) {
- ShowWarning("Character %s trying to enter an invalid time for auction.\n", sd->status.name);
- return;
- }
-
- // Auction checks...
- if (sd->status.zeny < (auction.hours * battle_config.auction_feeperhour)) {
- clif_Auction_message(fd, 5); // You do not have enough zeny to pay the Auction Fee.
- return;
- }
-
- if (auction.buynow > battle_config.auction_maximumprice) {
- // Zeny Limits
- auction.buynow = battle_config.auction_maximumprice;
- if (auction.price >= auction.buynow)
- auction.price = auction.buynow - 1;
- }
-
- auction.auction_id = 0;
- auction.seller_id = sd->status.char_id;
- safestrncpy(auction.seller_name, sd->status.name, sizeof(auction.seller_name));
- auction.buyer_id = 0;
- memset(auction.buyer_name, '\0', sizeof(auction.buyer_name));
-
- if (sd->status.inventory[sd->auction.index].nameid == 0 || sd->status.inventory[sd->auction.index].amount < sd->auction.amount) {
- clif_Auction_message(fd, 2); // The auction has been canceled
- return;
- }
-
- if ((item = itemdb_exists(sd->status.inventory[sd->auction.index].nameid)) == NULL) {
- // Just in case
- clif_Auction_message(fd, 2); // The auction has been canceled
- return;
- }
-
- safestrncpy(auction.item_name, item->jname, sizeof(auction.item_name));
- auction.type = item->type;
- memcpy(&auction.item, &sd->status.inventory[sd->auction.index], sizeof(struct item));
- auction.item.amount = 1;
- auction.timestamp = 0;
-
- if (!intif_Auction_register(&auction))
- clif_Auction_message(fd, 4); // No Char Server? lets say something to the client
- else {
- int zeny = auction.hours*battle_config.auction_feeperhour;
-
- pc_delitem(sd, sd->auction.index, sd->auction.amount, 1, 6, LOG_TYPE_AUCTION);
- sd->auction.amount = 0;
-
- pc_payzeny(sd, zeny, LOG_TYPE_AUCTION, NULL);
- }
+ struct auction_data auction;
+ struct item_data *item;
+
+ auction.price = RFIFOL(fd,2);
+ auction.buynow = RFIFOL(fd,6);
+ auction.hours = RFIFOW(fd,10);
+
+ // Invalid Situations...
+ if( sd->auction.amount < 1 )
+ {
+ ShowWarning("Character %s trying to register auction without item.\n", sd->status.name);
+ return;
+ }
+
+ if( auction.price >= auction.buynow )
+ {
+ ShowWarning("Character %s trying to alter auction prices.\n", sd->status.name);
+ return;
+ }
+
+ if( auction.hours < 1 || auction.hours > 48 )
+ {
+ ShowWarning("Character %s trying to enter an invalid time for auction.\n", sd->status.name);
+ return;
+ }
+
+ // Auction checks...
+ if( sd->status.zeny < (auction.hours * battle_config.auction_feeperhour) )
+ {
+ clif_Auction_message(fd, 5); // You do not have enough zeny to pay the Auction Fee.
+ return;
+ }
+
+ if( auction.buynow > battle_config.auction_maximumprice )
+ { // Zeny Limits
+ auction.buynow = battle_config.auction_maximumprice;
+ if( auction.price >= auction.buynow )
+ auction.price = auction.buynow - 1;
+ }
+
+ auction.auction_id = 0;
+ auction.seller_id = sd->status.char_id;
+ safestrncpy(auction.seller_name, sd->status.name, sizeof(auction.seller_name));
+ auction.buyer_id = 0;
+ memset(auction.buyer_name, '\0', sizeof(auction.buyer_name));
+
+ if( sd->status.inventory[sd->auction.index].nameid == 0 || sd->status.inventory[sd->auction.index].amount < sd->auction.amount )
+ {
+ clif_Auction_message(fd, 2); // The auction has been canceled
+ return;
+ }
+
+ if( (item = itemdb_exists(sd->status.inventory[sd->auction.index].nameid)) == NULL )
+ { // Just in case
+ clif_Auction_message(fd, 2); // The auction has been canceled
+ return;
+ }
+
+ safestrncpy(auction.item_name, item->jname, sizeof(auction.item_name));
+ auction.type = item->type;
+ memcpy(&auction.item, &sd->status.inventory[sd->auction.index], sizeof(struct item));
+ auction.item.amount = 1;
+ auction.timestamp = 0;
+
+ if( !intif_Auction_register(&auction) )
+ clif_Auction_message(fd, 4); // No Char Server? lets say something to the client
+ else
+ {
+ int zeny = auction.hours*battle_config.auction_feeperhour;
+
+ pc_delitem(sd, sd->auction.index, sd->auction.amount, 1, 6, LOG_TYPE_AUCTION);
+ sd->auction.amount = 0;
+
+ pc_payzeny(sd, zeny, LOG_TYPE_AUCTION, NULL);
+ }
}
@@ -14079,9 +14244,9 @@ void clif_parse_Auction_register(int fd, struct map_session_data *sd)
/// 024e <auction id>.L
void clif_parse_Auction_cancel(int fd, struct map_session_data *sd)
{
- unsigned int auction_id = RFIFOL(fd,2);
+ unsigned int auction_id = RFIFOL(fd,2);
- intif_Auction_cancel(sd->status.char_id, auction_id);
+ intif_Auction_cancel(sd->status.char_id, auction_id);
}
@@ -14089,9 +14254,9 @@ void clif_parse_Auction_cancel(int fd, struct map_session_data *sd)
/// 025d <auction id>.L
void clif_parse_Auction_close(int fd, struct map_session_data *sd)
{
- unsigned int auction_id = RFIFOL(fd,2);
+ unsigned int auction_id = RFIFOL(fd,2);
- intif_Auction_close(sd->status.char_id, auction_id);
+ intif_Auction_close(sd->status.char_id, auction_id);
}
@@ -14099,24 +14264,24 @@ void clif_parse_Auction_close(int fd, struct map_session_data *sd)
/// 024f <auction id>.L <money>.L
void clif_parse_Auction_bid(int fd, struct map_session_data *sd)
{
- unsigned int auction_id = RFIFOL(fd,2);
- int bid = RFIFOL(fd,6);
+ unsigned int auction_id = RFIFOL(fd,2);
+ int bid = RFIFOL(fd,6);
- if (!pc_can_give_items(sd)) { //They aren't supposed to give zeny [Inkfish]
- clif_displaymessage(sd->fd, msg_txt(246));
- return;
- }
+ if( !pc_can_give_items(sd) ) { //They aren't supposed to give zeny [Inkfish]
+ clif_displaymessage(sd->fd, msg_txt(246));
+ return;
+ }
- if (bid <= 0)
- clif_Auction_message(fd, 0); // You have failed to bid into the auction
- else if (bid > sd->status.zeny)
- clif_Auction_message(fd, 8); // You do not have enough zeny
- else if (CheckForCharServer()) // char server is down (bugreport:1138)
- clif_Auction_message(fd, 0); // You have failed to bid into the auction
- else {
- pc_payzeny(sd, bid, LOG_TYPE_AUCTION, NULL);
- intif_Auction_bid(sd->status.char_id, sd->status.name, auction_id, bid);
- }
+ if( bid <= 0 )
+ clif_Auction_message(fd, 0); // You have failed to bid into the auction
+ else if( bid > sd->status.zeny )
+ clif_Auction_message(fd, 8); // You do not have enough zeny
+ else if ( CheckForCharServer() ) // char server is down (bugreport:1138)
+ clif_Auction_message(fd, 0); // You have failed to bid into the auction
+ else {
+ pc_payzeny(sd, bid, LOG_TYPE_AUCTION, NULL);
+ intif_Auction_bid(sd->status.char_id, sd->status.name, auction_id, bid);
+ }
}
@@ -14129,16 +14294,16 @@ void clif_parse_Auction_bid(int fd, struct map_session_data *sd)
/// 3 = misc
/// 4 = name search
/// 5 = auction id search
-void clif_parse_Auction_search(int fd, struct map_session_data *sd)
+void clif_parse_Auction_search(int fd, struct map_session_data* sd)
{
- char search_text[NAME_LENGTH];
- short type = RFIFOW(fd,2), page = RFIFOW(fd,32);
- int price = RFIFOL(fd,4); // FIXME: bug #5071
+ char search_text[NAME_LENGTH];
+ short type = RFIFOW(fd,2), page = RFIFOW(fd,32);
+ int price = RFIFOL(fd,4); // FIXME: bug #5071
- clif_parse_Auction_cancelreg(fd, sd);
+ clif_parse_Auction_cancelreg(fd, sd);
- safestrncpy(search_text, (char *)RFIFOP(fd,8), sizeof(search_text));
- intif_Auction_requestlist(sd->status.char_id, type, price, search_text, page);
+ safestrncpy(search_text, (char*)RFIFOP(fd,8), sizeof(search_text));
+ intif_Auction_requestlist(sd->status.char_id, type, price, search_text, page);
}
@@ -14147,12 +14312,12 @@ void clif_parse_Auction_search(int fd, struct map_session_data *sd)
/// type:
/// 0 = sell (own auctions)
/// 1 = buy (own bids)
-void clif_parse_Auction_buysell(int fd, struct map_session_data *sd)
+void clif_parse_Auction_buysell(int fd, struct map_session_data* sd)
{
- short type = RFIFOW(fd,2) + 6;
- clif_parse_Auction_cancelreg(fd, sd);
+ short type = RFIFOW(fd,2) + 6;
+ clif_parse_Auction_cancelreg(fd, sd);
- intif_Auction_requestlist(sd->status.char_id, type, 0, "", 1);
+ intif_Auction_requestlist(sd->status.char_id, type, 0, "", 1);
}
@@ -14164,34 +14329,35 @@ void clif_parse_Auction_buysell(int fd, struct map_session_data *sd)
/// 0287 <packet len>.W <cash point>.L <kafra point>.L { <sell price>.L <discount price>.L <item type>.B <name id>.W }* (PACKETVER >= 20070711)
void clif_cashshop_show(struct map_session_data *sd, struct npc_data *nd)
{
- int fd,i;
+ int fd,i;
#if PACKETVER < 20070711
- const int offset = 8;
+ const int offset = 8;
#else
- const int offset = 12;
+ const int offset = 12;
#endif
- nullpo_retv(sd);
- nullpo_retv(nd);
-
- fd = sd->fd;
- sd->npc_shopid = nd->bl.id;
- WFIFOHEAD(fd,offset+nd->u.shop.count*11);
- WFIFOW(fd,0) = 0x287;
- WFIFOW(fd,2) = offset+nd->u.shop.count*11;
- WFIFOL(fd,4) = sd->cashPoints; // Cash Points
+ nullpo_retv(sd);
+ nullpo_retv(nd);
+
+ fd = sd->fd;
+ sd->npc_shopid = nd->bl.id;
+ WFIFOHEAD(fd,offset+nd->u.shop.count*11);
+ WFIFOW(fd,0) = 0x287;
+ WFIFOW(fd,2) = offset+nd->u.shop.count*11;
+ WFIFOL(fd,4) = sd->cashPoints; // Cash Points
#if PACKETVER >= 20070711
- WFIFOL(fd,8) = sd->kafraPoints; // Kafra Points
+ WFIFOL(fd,8) = sd->kafraPoints; // Kafra Points
#endif
- for (i = 0; i < nd->u.shop.count; i++) {
- struct item_data *id = itemdb_search(nd->u.shop.shop_item[i].nameid);
- WFIFOL(fd,offset+0+i*11) = nd->u.shop.shop_item[i].value;
- WFIFOL(fd,offset+4+i*11) = nd->u.shop.shop_item[i].value; // Discount Price
- WFIFOB(fd,offset+8+i*11) = itemtype(id->type);
- WFIFOW(fd,offset+9+i*11) = (id->view_id > 0) ? id->view_id : id->nameid;
- }
- WFIFOSET(fd,WFIFOW(fd,2));
+ for( i = 0; i < nd->u.shop.count; i++ )
+ {
+ struct item_data* id = itemdb_search(nd->u.shop.shop_item[i].nameid);
+ WFIFOL(fd,offset+0+i*11) = nd->u.shop.shop_item[i].value;
+ WFIFOL(fd,offset+4+i*11) = nd->u.shop.shop_item[i].value; // Discount Price
+ WFIFOB(fd,offset+8+i*11) = itemtype(id->type);
+ WFIFOW(fd,offset+9+i*11) = ( id->view_id > 0 ) ? id->view_id : id->nameid;
+ }
+ WFIFOSET(fd,WFIFOW(fd,2));
}
@@ -14208,20 +14374,20 @@ void clif_cashshop_show(struct map_session_data *sd, struct npc_data *nd)
/// 6 = You do not have enough Kafra Credit Points. (ERROR_TYPE_MONEY)
/// 7 = You can purchase up to 10 items.
/// 8 = Some items could not be purchased.
-void clif_cashshop_ack(struct map_session_data *sd, int error)
+void clif_cashshop_ack(struct map_session_data* sd, int error)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd, packet_len(0x289));
- WFIFOW(fd,0) = 0x289;
- WFIFOL(fd,2) = sd->cashPoints;
+ WFIFOHEAD(fd, packet_len(0x289));
+ WFIFOW(fd,0) = 0x289;
+ WFIFOL(fd,2) = sd->cashPoints;
#if PACKETVER < 20070711
- WFIFOW(fd,6) = TOW(error);
+ WFIFOW(fd,6) = TOW(error);
#else
- WFIFOL(fd,6) = sd->kafraPoints;
- WFIFOW(fd,10) = TOW(error);
+ WFIFOL(fd,6) = sd->kafraPoints;
+ WFIFOW(fd,10) = TOW(error);
#endif
- WFIFOSET(fd, packet_len(0x289));
+ WFIFOSET(fd, packet_len(0x289));
}
@@ -14234,9 +14400,10 @@ void clif_parse_cashshop_buy(int fd, struct map_session_data *sd)
int fail = 0;
nullpo_retv(sd);
- if (sd->state.trading || !sd->npc_shopid)
+ if( sd->state.trading || !sd->npc_shopid )
fail = 1;
- else {
+ else
+ {
#if PACKETVER < 20101116
short nameid = RFIFOW(fd,2);
short amount = RFIFOW(fd,4);
@@ -14247,9 +14414,10 @@ void clif_parse_cashshop_buy(int fd, struct map_session_data *sd)
int len = RFIFOW(fd,2);
int points = RFIFOL(fd,4);
int count = RFIFOW(fd,8);
- unsigned short *item_list = (unsigned short *)RFIFOP(fd,10);
+ unsigned short* item_list = (unsigned short*)RFIFOP(fd,10);
- if (len < 10 || len != 10 + count * 4) {
+ if( len < 10 || len != 10 + count * 4)
+ {
ShowWarning("Player %u sent incorrect cash shop buy packet (len %u:%u)!\n", sd->status.char_id, len, 10 + count * 4);
return;
}
@@ -14272,12 +14440,12 @@ void clif_parse_cashshop_buy(int fd, struct map_session_data *sd)
/// 2 = "You cannot adopt a married person."
void clif_Adopt_reply(struct map_session_data *sd, int type)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,6);
- WFIFOW(fd,0) = 0x216;
- WFIFOL(fd,2) = type;
- WFIFOSET(fd,6);
+ WFIFOHEAD(fd,6);
+ WFIFOW(fd,0) = 0x216;
+ WFIFOL(fd,2) = type;
+ WFIFOSET(fd,6);
}
@@ -14285,14 +14453,14 @@ void clif_Adopt_reply(struct map_session_data *sd, int type)
/// 01f6 <account id>.L <char id>.L <name>.B
void clif_Adopt_request(struct map_session_data *sd, struct map_session_data *src, int p_id)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,34);
- WFIFOW(fd,0) = 0x1f6;
- WFIFOL(fd,2) = src->status.account_id;
- WFIFOL(fd,6) = p_id;
- memcpy(WFIFOP(fd,10), src->status.name, NAME_LENGTH);
- WFIFOSET(fd,34);
+ WFIFOHEAD(fd,34);
+ WFIFOW(fd,0) = 0x1f6;
+ WFIFOL(fd,2) = src->status.account_id;
+ WFIFOL(fd,6) = p_id;
+ memcpy(WFIFOP(fd,10), src->status.name, NAME_LENGTH);
+ WFIFOSET(fd,34);
}
@@ -14300,12 +14468,13 @@ void clif_Adopt_request(struct map_session_data *sd, struct map_session_data *sr
/// 01f9 <account id>.L
void clif_parse_Adopt_request(int fd, struct map_session_data *sd)
{
- struct map_session_data *tsd = map_id2sd(RFIFOL(fd,2)), *p_sd = map_charid2sd(sd->status.partner_id);
+ struct map_session_data *tsd = map_id2sd(RFIFOL(fd,2)), *p_sd = map_charid2sd(sd->status.partner_id);
- if (pc_can_Adopt(sd, p_sd, tsd)) {
- tsd->adopt_invite = sd->status.account_id;
- clif_Adopt_request(tsd, sd, p_sd->status.account_id);
- }
+ if( pc_can_Adopt(sd, p_sd, tsd) )
+ {
+ tsd->adopt_invite = sd->status.account_id;
+ clif_Adopt_request(tsd, sd, p_sd->status.account_id);
+ }
}
@@ -14316,25 +14485,25 @@ void clif_parse_Adopt_request(int fd, struct map_session_data *sd)
/// 1 = accepted
void clif_parse_Adopt_reply(int fd, struct map_session_data *sd)
{
- int p1_id = RFIFOL(fd,2);
- int p2_id = RFIFOL(fd,6);
- int result = RFIFOL(fd,10);
- struct map_session_data *p1_sd = map_id2sd(p1_id);
- struct map_session_data *p2_sd = map_id2sd(p2_id);
+ int p1_id = RFIFOL(fd,2);
+ int p2_id = RFIFOL(fd,6);
+ int result = RFIFOL(fd,10);
+ struct map_session_data* p1_sd = map_id2sd(p1_id);
+ struct map_session_data* p2_sd = map_id2sd(p2_id);
- int pid = sd->adopt_invite;
- sd->adopt_invite = 0;
+ int pid = sd->adopt_invite;
+ sd->adopt_invite = 0;
- if (p1_sd == NULL || p2_sd == NULL)
- return; // Both players need to be online
+ if( p1_sd == NULL || p2_sd == NULL )
+ return; // Both players need to be online
- if (pid != p1_sd->status.account_id)
- return; // Incorrect values
+ if( pid != p1_sd->status.account_id )
+ return; // Incorrect values
- if (result == 0)
- return; // Rejected
+ if( result == 0 )
+ return; // Rejected
- pc_adoption(p1_sd, p2_sd, sd);
+ pc_adoption(p1_sd, p2_sd, sd);
}
@@ -14347,55 +14516,59 @@ void clif_parse_Adopt_reply(int fd, struct map_session_data *sd)
/// 3 = Boss is dead (BOSS_INFO_DEAD).
void clif_bossmapinfo(int fd, struct mob_data *md, short flag)
{
- WFIFOHEAD(fd,70);
- memset(WFIFOP(fd,0),0,70);
- WFIFOW(fd,0) = 0x293;
-
- if (md != NULL) {
- if (md->bl.prev != NULL) {
- // Boss on This Map
- if (flag) {
- WFIFOB(fd,2) = 1;
- WFIFOL(fd,3) = md->bl.x;
- WFIFOL(fd,7) = md->bl.y;
- } else
- WFIFOB(fd,2) = 2; // First Time
- } else if (md->spawn_timer != INVALID_TIMER) {
- // Boss is Dead
- const struct TimerData *timer_data = get_timer(md->spawn_timer);
- unsigned int seconds;
- int hours, minutes;
-
- seconds = DIFF_TICK(timer_data->tick, gettick()) / 1000 + 60;
- hours = seconds / (60 * 60);
- seconds = seconds - (60 * 60 * hours);
- minutes = seconds / 60;
-
- WFIFOB(fd,2) = 3;
- WFIFOW(fd,11) = hours; // Hours
- WFIFOW(fd,13) = minutes; // Minutes
- }
- safestrncpy((char *)WFIFOP(fd,19), md->db->jname, NAME_LENGTH);
- }
-
- WFIFOSET(fd,70);
+ WFIFOHEAD(fd,70);
+ memset(WFIFOP(fd,0),0,70);
+ WFIFOW(fd,0) = 0x293;
+
+ if( md != NULL )
+ {
+ if( md->bl.prev != NULL )
+ { // Boss on This Map
+ if( flag )
+ {
+ WFIFOB(fd,2) = 1;
+ WFIFOL(fd,3) = md->bl.x;
+ WFIFOL(fd,7) = md->bl.y;
+ }
+ else
+ WFIFOB(fd,2) = 2; // First Time
+ }
+ else if (md->spawn_timer != INVALID_TIMER)
+ { // Boss is Dead
+ const struct TimerData * timer_data = get_timer(md->spawn_timer);
+ unsigned int seconds;
+ int hours, minutes;
+
+ seconds = DIFF_TICK(timer_data->tick, gettick()) / 1000 + 60;
+ hours = seconds / (60 * 60);
+ seconds = seconds - (60 * 60 * hours);
+ minutes = seconds / 60;
+
+ WFIFOB(fd,2) = 3;
+ WFIFOW(fd,11) = hours; // Hours
+ WFIFOW(fd,13) = minutes; // Minutes
+ }
+ safestrncpy((char*)WFIFOP(fd,19), md->db->jname, NAME_LENGTH);
+ }
+
+ WFIFOSET(fd,70);
}
/// Requesting equip of a player (CZ_EQUIPWIN_MICROSCOPE).
/// 02d6 <account id>.L
-void clif_parse_ViewPlayerEquip(int fd, struct map_session_data *sd)
+void clif_parse_ViewPlayerEquip(int fd, struct map_session_data* sd)
{
- int charid = RFIFOL(fd, 2);
- struct map_session_data *tsd = map_id2sd(charid);
+ int charid = RFIFOL(fd, 2);
+ struct map_session_data* tsd = map_id2sd(charid);
- if (!tsd)
- return;
+ if (!tsd)
+ return;
- if (tsd->status.show_equip || pc_has_permission(sd, PC_PERM_VIEW_EQUIPMENT))
- clif_viewequip_ack(sd, tsd);
- else
- clif_viewequip_fail(sd);
+ if( tsd->status.show_equip || pc_has_permission(sd, PC_PERM_VIEW_EQUIPMENT) )
+ clif_viewequip_ack(sd, tsd);
+ else
+ clif_viewequip_fail(sd);
}
@@ -14406,11 +14579,11 @@ void clif_parse_ViewPlayerEquip(int fd, struct map_session_data *sd)
/// value:
/// 0 = disabled
/// 1 = enabled
-void clif_parse_EquipTick(int fd, struct map_session_data *sd)
+void clif_parse_EquipTick(int fd, struct map_session_data* sd)
{
- bool flag = (bool)RFIFOL(fd,6);
- sd->status.show_equip = flag;
- clif_equiptickack(sd, flag);
+ bool flag = (bool)RFIFOL(fd,6);
+ sd->status.show_equip = flag;
+ clif_equiptickack(sd, flag);
}
@@ -14419,141 +14592,146 @@ void clif_parse_EquipTick(int fd, struct map_session_data *sd)
/// Sends list of all quest states (ZC_ALL_QUEST_LIST).
/// 02b1 <packet len>.W <num>.L { <quest id>.L <active>.B }*num
-void clif_quest_send_list(struct map_session_data *sd)
+void clif_quest_send_list(struct map_session_data * sd)
{
- int fd = sd->fd;
- int i;
- int len = sd->avail_quests*5+8;
+ int fd = sd->fd;
+ int i;
+ int len = sd->avail_quests*5+8;
- WFIFOHEAD(fd,len);
- WFIFOW(fd, 0) = 0x2b1;
- WFIFOW(fd, 2) = len;
- WFIFOL(fd, 4) = sd->avail_quests;
+ WFIFOHEAD(fd,len);
+ WFIFOW(fd, 0) = 0x2b1;
+ WFIFOW(fd, 2) = len;
+ WFIFOL(fd, 4) = sd->avail_quests;
- for (i = 0; i < sd->avail_quests; i++) {
- WFIFOL(fd, i*5+8) = sd->quest_log[i].quest_id;
- WFIFOB(fd, i*5+12) = sd->quest_log[i].state;
- }
+ for( i = 0; i < sd->avail_quests; i++ )
+ {
+ WFIFOL(fd, i*5+8) = sd->quest_log[i].quest_id;
+ WFIFOB(fd, i*5+12) = sd->quest_log[i].state;
+ }
- WFIFOSET(fd, len);
+ WFIFOSET(fd, len);
}
/// Sends list of all quest missions (ZC_ALL_QUEST_MISSION).
/// 02b2 <packet len>.W <num>.L { <quest id>.L <start time>.L <expire time>.L <mobs>.W { <mob id>.L <mob count>.W <mob name>.24B }*3 }*num
-void clif_quest_send_mission(struct map_session_data *sd)
-{
- int fd = sd->fd;
- int i, j;
- int len = sd->avail_quests*104+8;
- struct mob_db *mob;
-
- WFIFOHEAD(fd, len);
- WFIFOW(fd, 0) = 0x2b2;
- WFIFOW(fd, 2) = len;
- WFIFOL(fd, 4) = sd->avail_quests;
-
- for (i = 0; i < sd->avail_quests; i++) {
- WFIFOL(fd, i*104+8) = sd->quest_log[i].quest_id;
- WFIFOL(fd, i*104+12) = sd->quest_log[i].time - quest_db[sd->quest_index[i]].time;
- WFIFOL(fd, i*104+16) = sd->quest_log[i].time;
- WFIFOW(fd, i*104+20) = quest_db[sd->quest_index[i]].num_objectives;
-
- for (j = 0 ; j < quest_db[sd->quest_index[i]].num_objectives; j++) {
- WFIFOL(fd, i*104+22+j*30) = quest_db[sd->quest_index[i]].mob[j];
- WFIFOW(fd, i*104+26+j*30) = sd->quest_log[i].count[j];
- mob = mob_db(quest_db[sd->quest_index[i]].mob[j]);
- memcpy(WFIFOP(fd, i*104+28+j*30), mob?mob->jname:"NULL", NAME_LENGTH);
- }
- }
+void clif_quest_send_mission(struct map_session_data * sd)
+{
+ int fd = sd->fd;
+ int i, j;
+ int len = sd->avail_quests*104+8;
+ struct mob_db *mob;
- WFIFOSET(fd, len);
+ WFIFOHEAD(fd, len);
+ WFIFOW(fd, 0) = 0x2b2;
+ WFIFOW(fd, 2) = len;
+ WFIFOL(fd, 4) = sd->avail_quests;
+
+ for( i = 0; i < sd->avail_quests; i++ )
+ {
+ WFIFOL(fd, i*104+8) = sd->quest_log[i].quest_id;
+ WFIFOL(fd, i*104+12) = sd->quest_log[i].time - quest_db[sd->quest_index[i]].time;
+ WFIFOL(fd, i*104+16) = sd->quest_log[i].time;
+ WFIFOW(fd, i*104+20) = quest_db[sd->quest_index[i]].num_objectives;
+
+ for( j = 0 ; j < quest_db[sd->quest_index[i]].num_objectives; j++ )
+ {
+ WFIFOL(fd, i*104+22+j*30) = quest_db[sd->quest_index[i]].mob[j];
+ WFIFOW(fd, i*104+26+j*30) = sd->quest_log[i].count[j];
+ mob = mob_db(quest_db[sd->quest_index[i]].mob[j]);
+ memcpy(WFIFOP(fd, i*104+28+j*30), mob?mob->jname:"NULL", NAME_LENGTH);
+ }
+ }
+
+ WFIFOSET(fd, len);
}
/// Notification about a new quest (ZC_ADD_QUEST).
/// 02b3 <quest id>.L <active>.B <start time>.L <expire time>.L <mobs>.W { <mob id>.L <mob count>.W <mob name>.24B }*3
-void clif_quest_add(struct map_session_data *sd, struct quest *qd, int index)
-{
- int fd = sd->fd;
- int i;
- struct mob_db *mob;
-
- WFIFOHEAD(fd, packet_len(0x2b3));
- WFIFOW(fd, 0) = 0x2b3;
- WFIFOL(fd, 2) = qd->quest_id;
- WFIFOB(fd, 6) = qd->state;
- WFIFOB(fd, 7) = qd->time - quest_db[index].time;
- WFIFOL(fd, 11) = qd->time;
- WFIFOW(fd, 15) = quest_db[index].num_objectives;
-
- for (i = 0; i < quest_db[index].num_objectives; i++) {
- WFIFOL(fd, i*30+17) = quest_db[index].mob[i];
- WFIFOW(fd, i*30+21) = qd->count[i];
- mob = mob_db(quest_db[index].mob[i]);
- memcpy(WFIFOP(fd, i*30+23), mob?mob->jname:"NULL", NAME_LENGTH);
- }
+void clif_quest_add(struct map_session_data * sd, struct quest * qd, int index)
+{
+ int fd = sd->fd;
+ int i;
+ struct mob_db *mob;
+
+ WFIFOHEAD(fd, packet_len(0x2b3));
+ WFIFOW(fd, 0) = 0x2b3;
+ WFIFOL(fd, 2) = qd->quest_id;
+ WFIFOB(fd, 6) = qd->state;
+ WFIFOB(fd, 7) = qd->time - quest_db[index].time;
+ WFIFOL(fd, 11) = qd->time;
+ WFIFOW(fd, 15) = quest_db[index].num_objectives;
- WFIFOSET(fd, packet_len(0x2b3));
+ for( i = 0; i < quest_db[index].num_objectives; i++ )
+ {
+ WFIFOL(fd, i*30+17) = quest_db[index].mob[i];
+ WFIFOW(fd, i*30+21) = qd->count[i];
+ mob = mob_db(quest_db[index].mob[i]);
+ memcpy(WFIFOP(fd, i*30+23), mob?mob->jname:"NULL", NAME_LENGTH);
+ }
+
+ WFIFOSET(fd, packet_len(0x2b3));
}
/// Notification about a quest being removed (ZC_DEL_QUEST).
/// 02b4 <quest id>.L
-void clif_quest_delete(struct map_session_data *sd, int quest_id)
+void clif_quest_delete(struct map_session_data * sd, int quest_id)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd, packet_len(0x2b4));
- WFIFOW(fd, 0) = 0x2b4;
- WFIFOL(fd, 2) = quest_id;
- WFIFOSET(fd, packet_len(0x2b4));
+ WFIFOHEAD(fd, packet_len(0x2b4));
+ WFIFOW(fd, 0) = 0x2b4;
+ WFIFOL(fd, 2) = quest_id;
+ WFIFOSET(fd, packet_len(0x2b4));
}
/// Notification of an update to the hunting mission counter (ZC_UPDATE_MISSION_HUNT).
/// 02b5 <packet len>.W <mobs>.W { <quest id>.L <mob id>.L <total count>.W <current count>.W }*3
-void clif_quest_update_objective(struct map_session_data *sd, struct quest *qd, int index)
-{
- int fd = sd->fd;
- int i;
- int len = quest_db[index].num_objectives*12+6;
-
- WFIFOHEAD(fd, len);
- WFIFOW(fd, 0) = 0x2b5;
- WFIFOW(fd, 2) = len;
- WFIFOW(fd, 4) = quest_db[index].num_objectives;
-
- for (i = 0; i < quest_db[index].num_objectives; i++) {
- WFIFOL(fd, i*12+6) = qd->quest_id;
- WFIFOL(fd, i*12+10) = quest_db[index].mob[i];
- WFIFOW(fd, i*12+14) = quest_db[index].count[i];
- WFIFOW(fd, i*12+16) = qd->count[i];
- }
+void clif_quest_update_objective(struct map_session_data * sd, struct quest * qd, int index)
+{
+ int fd = sd->fd;
+ int i;
+ int len = quest_db[index].num_objectives*12+6;
+
+ WFIFOHEAD(fd, len);
+ WFIFOW(fd, 0) = 0x2b5;
+ WFIFOW(fd, 2) = len;
+ WFIFOW(fd, 4) = quest_db[index].num_objectives;
+
+ for( i = 0; i < quest_db[index].num_objectives; i++ )
+ {
+ WFIFOL(fd, i*12+6) = qd->quest_id;
+ WFIFOL(fd, i*12+10) = quest_db[index].mob[i];
+ WFIFOW(fd, i*12+14) = quest_db[index].count[i];
+ WFIFOW(fd, i*12+16) = qd->count[i];
+ }
- WFIFOSET(fd, len);
+ WFIFOSET(fd, len);
}
/// Request to change the state of a quest (CZ_ACTIVE_QUEST).
/// 02b6 <quest id>.L <active>.B
-void clif_parse_questStateAck(int fd, struct map_session_data *sd)
+void clif_parse_questStateAck(int fd, struct map_session_data * sd)
{
- quest_update_status(sd, RFIFOL(fd,2), RFIFOB(fd,6)?Q_ACTIVE:Q_INACTIVE);
+ quest_update_status(sd, RFIFOL(fd,2), RFIFOB(fd,6)?Q_ACTIVE:Q_INACTIVE);
}
/// Notification about the change of a quest state (ZC_ACTIVE_QUEST).
/// 02b7 <quest id>.L <active>.B
-void clif_quest_update_status(struct map_session_data *sd, int quest_id, bool active)
+void clif_quest_update_status(struct map_session_data * sd, int quest_id, bool active)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd, packet_len(0x2b7));
- WFIFOW(fd, 0) = 0x2b7;
- WFIFOL(fd, 2) = quest_id;
- WFIFOB(fd, 6) = active;
- WFIFOSET(fd, packet_len(0x2b7));
+ WFIFOHEAD(fd, packet_len(0x2b7));
+ WFIFOW(fd, 0) = 0x2b7;
+ WFIFOL(fd, 2) = quest_id;
+ WFIFOB(fd, 6) = active;
+ WFIFOSET(fd, packet_len(0x2b7));
}
@@ -14571,16 +14749,16 @@ void clif_quest_update_status(struct map_session_data *sd, int quest_id, bool ac
void clif_quest_show_event(struct map_session_data *sd, struct block_list *bl, short state, short color)
{
#if PACKETVER >= 20090218
- int fd = sd->fd;
-
- WFIFOHEAD(fd, packet_len(0x446));
- WFIFOW(fd, 0) = 0x446;
- WFIFOL(fd, 2) = bl->id;
- WFIFOW(fd, 6) = bl->x;
- WFIFOW(fd, 8) = bl->y;
- WFIFOW(fd, 10) = state;
- WFIFOW(fd, 12) = color;
- WFIFOSET(fd, packet_len(0x446));
+ int fd = sd->fd;
+
+ WFIFOHEAD(fd, packet_len(0x446));
+ WFIFOW(fd, 0) = 0x446;
+ WFIFOL(fd, 2) = bl->id;
+ WFIFOW(fd, 6) = bl->x;
+ WFIFOW(fd, 8) = bl->y;
+ WFIFOW(fd, 10) = state;
+ WFIFOW(fd, 12) = color;
+ WFIFOSET(fd, packet_len(0x446));
#endif
}
@@ -14592,64 +14770,66 @@ void clif_quest_show_event(struct map_session_data *sd, struct block_list *bl, s
/// 02a2 <var id>.W <value>.L
void clif_mercenary_updatestatus(struct map_session_data *sd, int type)
{
- struct mercenary_data *md;
- struct status_data *status;
- int fd;
- if (sd == NULL || (md = sd->md) == NULL)
- return;
-
- fd = sd->fd;
- status = &md->battle_status;
- WFIFOHEAD(fd,packet_len(0x2a2));
- WFIFOW(fd,0) = 0x2a2;
- WFIFOW(fd,2) = type;
- switch (type) {
- case SP_ATK1: {
- int atk = rnd()%(status->rhw.atk2 - status->rhw.atk + 1) + status->rhw.atk;
- WFIFOL(fd,4) = cap_value(atk, 0, INT16_MAX);
- }
- break;
- case SP_MATK1:
- WFIFOL(fd,4) = cap_value(status->matk_max, 0, INT16_MAX);
- break;
- case SP_HIT:
- WFIFOL(fd,4) = status->hit;
- break;
- case SP_CRITICAL:
- WFIFOL(fd,4) = status->cri/10;
- break;
- case SP_DEF1:
- WFIFOL(fd,4) = status->def;
- break;
- case SP_MDEF1:
- WFIFOL(fd,4) = status->mdef;
- break;
- case SP_MERCFLEE:
- WFIFOL(fd,4) = status->flee;
- break;
- case SP_ASPD:
- WFIFOL(fd,4) = status->amotion;
- break;
- case SP_HP:
- WFIFOL(fd,4) = status->hp;
- break;
- case SP_MAXHP:
- WFIFOL(fd,4) = status->max_hp;
- break;
- case SP_SP:
- WFIFOL(fd,4) = status->sp;
- break;
- case SP_MAXSP:
- WFIFOL(fd,4) = status->max_sp;
- break;
- case SP_MERCKILLS:
- WFIFOL(fd,4) = md->mercenary.kill_count;
- break;
- case SP_MERCFAITH:
- WFIFOL(fd,4) = mercenary_get_faith(md);
- break;
- }
- WFIFOSET(fd,packet_len(0x2a2));
+ struct mercenary_data *md;
+ struct status_data *status;
+ int fd;
+ if( sd == NULL || (md = sd->md) == NULL )
+ return;
+
+ fd = sd->fd;
+ status = &md->battle_status;
+ WFIFOHEAD(fd,packet_len(0x2a2));
+ WFIFOW(fd,0) = 0x2a2;
+ WFIFOW(fd,2) = type;
+ switch( type )
+ {
+ case SP_ATK1:
+ {
+ int atk = rnd()%(status->rhw.atk2 - status->rhw.atk + 1) + status->rhw.atk;
+ WFIFOL(fd,4) = cap_value(atk, 0, INT16_MAX);
+ }
+ break;
+ case SP_MATK1:
+ WFIFOL(fd,4) = cap_value(status->matk_max, 0, INT16_MAX);
+ break;
+ case SP_HIT:
+ WFIFOL(fd,4) = status->hit;
+ break;
+ case SP_CRITICAL:
+ WFIFOL(fd,4) = status->cri/10;
+ break;
+ case SP_DEF1:
+ WFIFOL(fd,4) = status->def;
+ break;
+ case SP_MDEF1:
+ WFIFOL(fd,4) = status->mdef;
+ break;
+ case SP_MERCFLEE:
+ WFIFOL(fd,4) = status->flee;
+ break;
+ case SP_ASPD:
+ WFIFOL(fd,4) = status->amotion;
+ break;
+ case SP_HP:
+ WFIFOL(fd,4) = status->hp;
+ break;
+ case SP_MAXHP:
+ WFIFOL(fd,4) = status->max_hp;
+ break;
+ case SP_SP:
+ WFIFOL(fd,4) = status->sp;
+ break;
+ case SP_MAXSP:
+ WFIFOL(fd,4) = status->max_sp;
+ break;
+ case SP_MERCKILLS:
+ WFIFOL(fd,4) = md->mercenary.kill_count;
+ break;
+ case SP_MERCFAITH:
+ WFIFOL(fd,4) = mercenary_get_faith(md);
+ break;
+ }
+ WFIFOSET(fd,packet_len(0x2a2));
}
@@ -14659,43 +14839,43 @@ void clif_mercenary_updatestatus(struct map_session_data *sd, int type)
/// <calls>.L <kills>.L <atk range>.W
void clif_mercenary_info(struct map_session_data *sd)
{
- int fd;
- struct mercenary_data *md;
- struct status_data *status;
- int atk;
-
- if (sd == NULL || (md = sd->md) == NULL)
- return;
-
- fd = sd->fd;
- status = &md->battle_status;
-
- WFIFOHEAD(fd,packet_len(0x29b));
- WFIFOW(fd,0) = 0x29b;
- WFIFOL(fd,2) = md->bl.id;
-
- // Mercenary shows ATK as a random value between ATK ~ ATK2
- atk = rnd()%(status->rhw.atk2 - status->rhw.atk + 1) + status->rhw.atk;
- WFIFOW(fd,6) = cap_value(atk, 0, INT16_MAX);
- WFIFOW(fd,8) = cap_value(status->matk_max, 0, INT16_MAX);
- WFIFOW(fd,10) = status->hit;
- WFIFOW(fd,12) = status->cri/10;
- WFIFOW(fd,14) = status->def;
- WFIFOW(fd,16) = status->mdef;
- WFIFOW(fd,18) = status->flee;
- WFIFOW(fd,20) = status->amotion;
- safestrncpy((char *)WFIFOP(fd,22), md->db->name, NAME_LENGTH);
- WFIFOW(fd,46) = md->db->lv;
- WFIFOL(fd,48) = status->hp;
- WFIFOL(fd,52) = status->max_hp;
- WFIFOL(fd,56) = status->sp;
- WFIFOL(fd,60) = status->max_sp;
- WFIFOL(fd,64) = (int)time(NULL) + (mercenary_get_lifetime(md) / 1000);
- WFIFOW(fd,68) = mercenary_get_faith(md);
- WFIFOL(fd,70) = mercenary_get_calls(md);
- WFIFOL(fd,74) = md->mercenary.kill_count;
- WFIFOW(fd,78) = md->battle_status.rhw.range;
- WFIFOSET(fd,packet_len(0x29b));
+ int fd;
+ struct mercenary_data *md;
+ struct status_data *status;
+ int atk;
+
+ if( sd == NULL || (md = sd->md) == NULL )
+ return;
+
+ fd = sd->fd;
+ status = &md->battle_status;
+
+ WFIFOHEAD(fd,packet_len(0x29b));
+ WFIFOW(fd,0) = 0x29b;
+ WFIFOL(fd,2) = md->bl.id;
+
+ // Mercenary shows ATK as a random value between ATK ~ ATK2
+ atk = rnd()%(status->rhw.atk2 - status->rhw.atk + 1) + status->rhw.atk;
+ WFIFOW(fd,6) = cap_value(atk, 0, INT16_MAX);
+ WFIFOW(fd,8) = cap_value(status->matk_max, 0, INT16_MAX);
+ WFIFOW(fd,10) = status->hit;
+ WFIFOW(fd,12) = status->cri/10;
+ WFIFOW(fd,14) = status->def;
+ WFIFOW(fd,16) = status->mdef;
+ WFIFOW(fd,18) = status->flee;
+ WFIFOW(fd,20) = status->amotion;
+ safestrncpy((char*)WFIFOP(fd,22), md->db->name, NAME_LENGTH);
+ WFIFOW(fd,46) = md->db->lv;
+ WFIFOL(fd,48) = status->hp;
+ WFIFOL(fd,52) = status->max_hp;
+ WFIFOL(fd,56) = status->sp;
+ WFIFOL(fd,60) = status->max_sp;
+ WFIFOL(fd,64) = (int)time(NULL) + (mercenary_get_lifetime(md) / 1000);
+ WFIFOW(fd,68) = mercenary_get_faith(md);
+ WFIFOL(fd,70) = mercenary_get_calls(md);
+ WFIFOL(fd,74) = md->mercenary.kill_count;
+ WFIFOW(fd,78) = md->battle_status.rhw.range;
+ WFIFOSET(fd,packet_len(0x29b));
}
@@ -14703,31 +14883,32 @@ void clif_mercenary_info(struct map_session_data *sd)
/// 029d <packet len>.W { <skill id>.W <type>.L <level>.W <sp cost>.W <attack range>.W <skill name>.24B <upgradable>.B }*
void clif_mercenary_skillblock(struct map_session_data *sd)
{
- struct mercenary_data *md;
- int fd, i, len = 4, id, j;
-
- if (sd == NULL || (md = sd->md) == NULL)
- return;
-
- fd = sd->fd;
- WFIFOHEAD(fd,4+37*MAX_MERCSKILL);
- WFIFOW(fd,0) = 0x29d;
- for (i = 0; i < MAX_MERCSKILL; i++) {
- if ((id = md->db->skill[i].id) == 0)
- continue;
- j = id - MC_SKILLBASE;
- WFIFOW(fd,len) = id;
- WFIFOL(fd,len+2) = skill_get_inf(id);
- WFIFOW(fd,len+6) = md->db->skill[j].lv;
- WFIFOW(fd,len+8) = skill_get_sp(id, md->db->skill[j].lv);
- WFIFOW(fd,len+10) = skill_get_range2(&md->bl, id, md->db->skill[j].lv);
- safestrncpy((char *)WFIFOP(fd,len+12), skill_get_name(id), NAME_LENGTH);
- WFIFOB(fd,len+36) = 0; // Skillable for Mercenary?
- len += 37;
- }
+ struct mercenary_data *md;
+ int fd, i, len = 4, id, j;
- WFIFOW(fd,2) = len;
- WFIFOSET(fd,len);
+ if( sd == NULL || (md = sd->md) == NULL )
+ return;
+
+ fd = sd->fd;
+ WFIFOHEAD(fd,4+37*MAX_MERCSKILL);
+ WFIFOW(fd,0) = 0x29d;
+ for( i = 0; i < MAX_MERCSKILL; i++ )
+ {
+ if( (id = md->db->skill[i].id) == 0 )
+ continue;
+ j = id - MC_SKILLBASE;
+ WFIFOW(fd,len) = id;
+ WFIFOL(fd,len+2) = skill_get_inf(id);
+ WFIFOW(fd,len+6) = md->db->skill[j].lv;
+ WFIFOW(fd,len+8) = skill_get_sp(id, md->db->skill[j].lv);
+ WFIFOW(fd,len+10) = skill_get_range2(&md->bl, id, md->db->skill[j].lv);
+ safestrncpy((char*)WFIFOP(fd,len+12), skill_get_name(id), NAME_LENGTH);
+ WFIFOB(fd,len+36) = 0; // Skillable for Mercenary?
+ len += 37;
+ }
+
+ WFIFOW(fd,2) = len;
+ WFIFOSET(fd,len);
}
@@ -14735,13 +14916,13 @@ void clif_mercenary_skillblock(struct map_session_data *sd)
/// 029f <command>.B
/// 1 = mercenary information
/// 2 = delete
-void clif_parse_mercenary_action(int fd, struct map_session_data *sd)
+void clif_parse_mercenary_action(int fd, struct map_session_data* sd)
{
- int option = RFIFOB(fd,2);
- if (sd->md == NULL)
- return;
+ int option = RFIFOB(fd,2);
+ if( sd->md == NULL )
+ return;
- if (option == 2) merc_delete(sd->md, 2);
+ if( option == 2 ) merc_delete(sd->md, 2);
}
@@ -14751,35 +14932,33 @@ void clif_parse_mercenary_action(int fd, struct map_session_data *sd)
/// 1 = Your mercenary soldier has been killed.
/// 2 = Your mercenary soldier has been fired.
/// 3 = Your mercenary soldier has ran away.
-void clif_mercenary_message(struct map_session_data *sd, int message)
+void clif_mercenary_message(struct map_session_data* sd, int message)
{
- clif_msg(sd, 1266 + message);
+ clif_msg(sd, 1266 + message);
}
/// Notification about the remaining time of a rental item (ZC_CASH_TIME_COUNTER).
/// 0298 <name id>.W <seconds>.L
void clif_rental_time(int fd, int nameid, int seconds)
-{
- // '<ItemName>' item will disappear in <seconds/60> minutes.
- WFIFOHEAD(fd,packet_len(0x298));
- WFIFOW(fd,0) = 0x298;
- WFIFOW(fd,2) = nameid;
- WFIFOL(fd,4) = seconds;
- WFIFOSET(fd,packet_len(0x298));
+{ // '<ItemName>' item will disappear in <seconds/60> minutes.
+ WFIFOHEAD(fd,packet_len(0x298));
+ WFIFOW(fd,0) = 0x298;
+ WFIFOW(fd,2) = nameid;
+ WFIFOL(fd,4) = seconds;
+ WFIFOSET(fd,packet_len(0x298));
}
/// Deletes a rental item from client's inventory (ZC_CASH_ITEM_DELETE).
/// 0299 <index>.W <name id>.W
void clif_rental_expired(int fd, int index, int nameid)
-{
- // '<ItemName>' item has been deleted from the Inventory
- WFIFOHEAD(fd,packet_len(0x299));
- WFIFOW(fd,0) = 0x299;
- WFIFOW(fd,2) = index+2;
- WFIFOW(fd,4) = nameid;
- WFIFOSET(fd,packet_len(0x299));
+{ // '<ItemName>' item has been deleted from the Inventory
+ WFIFOHEAD(fd,packet_len(0x299));
+ WFIFOW(fd,0) = 0x299;
+ WFIFOW(fd,2) = index+2;
+ WFIFOW(fd,4) = nameid;
+ WFIFOSET(fd,packet_len(0x299));
}
@@ -14787,11 +14966,11 @@ void clif_rental_expired(int fd, int index, int nameid)
/// 0294 <book id>.L <page>.L
void clif_readbook(int fd, int book_id, int page)
{
- WFIFOHEAD(fd,packet_len(0x294));
- WFIFOW(fd,0) = 0x294;
- WFIFOL(fd,2) = book_id;
- WFIFOL(fd,6) = page;
- WFIFOSET(fd,packet_len(0x294));
+ WFIFOHEAD(fd,packet_len(0x294));
+ WFIFOW(fd,0) = 0x294;
+ WFIFOL(fd,2) = book_id;
+ WFIFOL(fd,6) = page;
+ WFIFOSET(fd,packet_len(0x294));
}
@@ -14802,24 +14981,26 @@ void clif_readbook(int fd, int book_id, int page)
/// 02e0 <account id>.L <name>.24B <hp>.W <max hp>.W
void clif_bg_hp(struct map_session_data *sd)
{
- unsigned char buf[34];
- const int cmd = 0x2e0;
- nullpo_retv(sd);
+ unsigned char buf[34];
+ const int cmd = 0x2e0;
+ nullpo_retv(sd);
- WBUFW(buf,0) = cmd;
- WBUFL(buf,2) = sd->status.account_id;
- memcpy(WBUFP(buf,6), sd->status.name, NAME_LENGTH);
-
- if (sd->battle_status.max_hp > INT16_MAX) {
- // To correctly display the %hp bar. [Skotlex]
- WBUFW(buf,30) = sd->battle_status.hp/(sd->battle_status.max_hp/100);
- WBUFW(buf,32) = 100;
- } else {
- WBUFW(buf,30) = sd->battle_status.hp;
- WBUFW(buf,32) = sd->battle_status.max_hp;
- }
+ WBUFW(buf,0) = cmd;
+ WBUFL(buf,2) = sd->status.account_id;
+ memcpy(WBUFP(buf,6), sd->status.name, NAME_LENGTH);
- clif_send(buf, packet_len(cmd), &sd->bl, BG_AREA_WOS);
+ if( sd->battle_status.max_hp > INT16_MAX )
+ { // To correctly display the %hp bar. [Skotlex]
+ WBUFW(buf,30) = sd->battle_status.hp/(sd->battle_status.max_hp/100);
+ WBUFW(buf,32) = 100;
+ }
+ else
+ {
+ WBUFW(buf,30) = sd->battle_status.hp;
+ WBUFW(buf,32) = sd->battle_status.max_hp;
+ }
+
+ clif_send(buf, packet_len(cmd), &sd->bl, BG_AREA_WOS);
}
@@ -14827,32 +15008,32 @@ void clif_bg_hp(struct map_session_data *sd)
/// 02df <account id>.L <name>.24B <class>.W <x>.W <y>.W
void clif_bg_xy(struct map_session_data *sd)
{
- unsigned char buf[36];
- nullpo_retv(sd);
+ unsigned char buf[36];
+ nullpo_retv(sd);
- WBUFW(buf,0)=0x2df;
- WBUFL(buf,2)=sd->status.account_id;
- memcpy(WBUFP(buf,6), sd->status.name, NAME_LENGTH);
- WBUFW(buf,30)=sd->status.class_;
- WBUFW(buf,32)=sd->bl.x;
- WBUFW(buf,34)=sd->bl.y;
+ WBUFW(buf,0)=0x2df;
+ WBUFL(buf,2)=sd->status.account_id;
+ memcpy(WBUFP(buf,6), sd->status.name, NAME_LENGTH);
+ WBUFW(buf,30)=sd->status.class_;
+ WBUFW(buf,32)=sd->bl.x;
+ WBUFW(buf,34)=sd->bl.y;
- clif_send(buf, packet_len(0x2df), &sd->bl, BG_SAMEMAP_WOS);
+ clif_send(buf, packet_len(0x2df), &sd->bl, BG_SAMEMAP_WOS);
}
void clif_bg_xy_remove(struct map_session_data *sd)
{
- unsigned char buf[36];
- nullpo_retv(sd);
+ unsigned char buf[36];
+ nullpo_retv(sd);
- WBUFW(buf,0)=0x2df;
- WBUFL(buf,2)=sd->status.account_id;
- memset(WBUFP(buf,6), 0, NAME_LENGTH);
- WBUFW(buf,30)=0;
- WBUFW(buf,32)=-1;
- WBUFW(buf,34)=-1;
+ WBUFW(buf,0)=0x2df;
+ WBUFL(buf,2)=sd->status.account_id;
+ memset(WBUFP(buf,6), 0, NAME_LENGTH);
+ WBUFW(buf,30)=0;
+ WBUFW(buf,32)=-1;
+ WBUFW(buf,34)=-1;
- clif_send(buf, packet_len(0x2df), &sd->bl, BG_SAMEMAP_WOS);
+ clif_send(buf, packet_len(0x2df), &sd->bl, BG_SAMEMAP_WOS);
}
@@ -14860,51 +15041,52 @@ void clif_bg_xy_remove(struct map_session_data *sd)
/// 02dc <packet len>.W <account id>.L <name>.24B <message>.?B
void clif_bg_message(struct battleground_data *bg, int src_id, const char *name, const char *mes, int len)
{
- struct map_session_data *sd;
- unsigned char *buf;
- if ((sd = bg_getavailablesd(bg)) == NULL)
- return;
+ struct map_session_data *sd;
+ unsigned char *buf;
+ if( (sd = bg_getavailablesd(bg)) == NULL )
+ return;
- buf = (unsigned char *)aMalloc((len + NAME_LENGTH + 8)*sizeof(unsigned char));
+ buf = (unsigned char*)aMalloc((len + NAME_LENGTH + 8)*sizeof(unsigned char));
- WBUFW(buf,0) = 0x2dc;
- WBUFW(buf,2) = len + NAME_LENGTH + 8;
- WBUFL(buf,4) = src_id;
- memcpy(WBUFP(buf,8), name, NAME_LENGTH);
- memcpy(WBUFP(buf,32), mes, len);
- clif_send(buf,WBUFW(buf,2), &sd->bl, BG);
+ WBUFW(buf,0) = 0x2dc;
+ WBUFW(buf,2) = len + NAME_LENGTH + 8;
+ WBUFL(buf,4) = src_id;
+ memcpy(WBUFP(buf,8), name, NAME_LENGTH);
+ memcpy(WBUFP(buf,32), mes, len);
+ clif_send(buf,WBUFW(buf,2), &sd->bl, BG);
- if (buf)
- aFree(buf);
+ if( buf )
+ aFree(buf);
}
/// Validates and processes battlechat messages [pakpil] (CZ_BATTLEFIELD_CHAT).
/// 0x2db <packet len>.W <text>.?B (<name> : <message>) 00
-void clif_parse_BattleChat(int fd, struct map_session_data *sd)
+void clif_parse_BattleChat(int fd, struct map_session_data* sd)
{
- const char *text = (char *)RFIFOP(fd,4);
- int textlen = RFIFOW(fd,2) - 4;
+ const char* text = (char*)RFIFOP(fd,4);
+ int textlen = RFIFOW(fd,2) - 4;
- char *name, *message;
- int namelen, messagelen;
+ char *name, *message;
+ int namelen, messagelen;
- if (!clif_process_message(sd, 0, &name, &namelen, &message, &messagelen))
- return;
+ if( !clif_process_message(sd, 0, &name, &namelen, &message, &messagelen) )
+ return;
- if (is_atcommand(fd, sd, message, 1))
- return;
+ if( is_atcommand(fd, sd, message, 1) )
+ return;
- if (sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT))
- return;
+ if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) )
+ return;
- if (battle_config.min_chat_delay) {
- if (DIFF_TICK(sd->cantalk_tick, gettick()) > 0)
- return;
- sd->cantalk_tick = gettick() + battle_config.min_chat_delay;
- }
+ if( battle_config.min_chat_delay )
+ {
+ if( DIFF_TICK(sd->cantalk_tick, gettick()) > 0 )
+ return;
+ sd->cantalk_tick = gettick() + battle_config.min_chat_delay;
+ }
- bg_send_message(sd, text, textlen);
+ bg_send_message(sd, text, textlen);
}
@@ -14912,30 +15094,30 @@ void clif_parse_BattleChat(int fd, struct map_session_data *sd)
/// 02de <camp A points>.W <camp B points>.W
void clif_bg_updatescore(int m)
{
- struct block_list bl;
- unsigned char buf[6];
+ struct block_list bl;
+ unsigned char buf[6];
- bl.id = 0;
- bl.type = BL_NUL;
- bl.m = m;
+ bl.id = 0;
+ bl.type = BL_NUL;
+ bl.m = m;
- WBUFW(buf,0) = 0x2de;
- WBUFW(buf,2) = map[m].bgscore_lion;
- WBUFW(buf,4) = map[m].bgscore_eagle;
- clif_send(buf,packet_len(0x2de),&bl,ALL_SAMEMAP);
+ WBUFW(buf,0) = 0x2de;
+ WBUFW(buf,2) = map[m].bgscore_lion;
+ WBUFW(buf,4) = map[m].bgscore_eagle;
+ clif_send(buf,packet_len(0x2de),&bl,ALL_SAMEMAP);
}
void clif_bg_updatescore_single(struct map_session_data *sd)
{
- int fd;
- nullpo_retv(sd);
- fd = sd->fd;
+ int fd;
+ nullpo_retv(sd);
+ fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x2de));
- WFIFOW(fd,0) = 0x2de;
- WFIFOW(fd,2) = map[sd->bl.m].bgscore_lion;
- WFIFOW(fd,4) = map[sd->bl.m].bgscore_eagle;
- WFIFOSET(fd,packet_len(0x2de));
+ WFIFOHEAD(fd,packet_len(0x2de));
+ WFIFOW(fd,0) = 0x2de;
+ WFIFOW(fd,2) = map[sd->bl.m].bgscore_lion;
+ WFIFOW(fd,4) = map[sd->bl.m].bgscore_eagle;
+ WFIFOSET(fd,packet_len(0x2de));
}
@@ -14943,25 +15125,25 @@ void clif_bg_updatescore_single(struct map_session_data *sd)
/// 02dd <account id>.L <name>.24B <camp>.W
void clif_sendbgemblem_area(struct map_session_data *sd)
{
- unsigned char buf[33];
- nullpo_retv(sd);
+ unsigned char buf[33];
+ nullpo_retv(sd);
- WBUFW(buf, 0) = 0x2dd;
- WBUFL(buf,2) = sd->bl.id;
- safestrncpy((char *)WBUFP(buf,6), sd->status.name, NAME_LENGTH); // name don't show in screen.
- WBUFW(buf,30) = sd->bg_id;
- clif_send(buf,packet_len(0x2dd), &sd->bl, AREA);
+ WBUFW(buf, 0) = 0x2dd;
+ WBUFL(buf,2) = sd->bl.id;
+ safestrncpy((char*)WBUFP(buf,6), sd->status.name, NAME_LENGTH); // name don't show in screen.
+ WBUFW(buf,30) = sd->bg_id;
+ clif_send(buf,packet_len(0x2dd), &sd->bl, AREA);
}
void clif_sendbgemblem_single(int fd, struct map_session_data *sd)
{
- nullpo_retv(sd);
- WFIFOHEAD(fd,32);
- WFIFOW(fd,0) = 0x2dd;
- WFIFOL(fd,2) = sd->bl.id;
- safestrncpy((char *)WFIFOP(fd,6), sd->status.name, NAME_LENGTH);
- WFIFOW(fd,30) = sd->bg_id;
- WFIFOSET(fd,packet_len(0x2dd));
+ nullpo_retv(sd);
+ WFIFOHEAD(fd,32);
+ WFIFOW(fd,0) = 0x2dd;
+ WFIFOL(fd,2) = sd->bl.id;
+ safestrncpy((char*)WFIFOP(fd,6), sd->status.name, NAME_LENGTH);
+ WFIFOW(fd,30) = sd->bg_id;
+ WFIFOSET(fd,packet_len(0x2dd));
}
@@ -14970,12 +15152,12 @@ void clif_sendbgemblem_single(int fd, struct map_session_data *sd)
void clif_font(struct map_session_data *sd)
{
#if PACKETVER >= 20080102
- unsigned char buf[8];
- nullpo_retv(sd);
- WBUFW(buf,0) = 0x2ef;
- WBUFL(buf,2) = sd->bl.id;
- WBUFW(buf,6) = sd->user_font;
- clif_send(buf, packet_len(0x2ef), &sd->bl, AREA);
+ unsigned char buf[8];
+ nullpo_retv(sd);
+ WBUFW(buf,0) = 0x2ef;
+ WBUFL(buf,2) = sd->bl.id;
+ WBUFW(buf,6) = sd->user_font;
+ clif_send(buf, packet_len(0x2ef), &sd->bl, AREA);
#endif
}
@@ -14985,112 +15167,121 @@ void clif_font(struct map_session_data *sd)
*------------------------------------------*/
int clif_instance(int instance_id, int type, int flag)
{
- struct map_session_data *sd;
- struct party_data *p;
- unsigned char buf[255];
-
- if ((p = party_search(instance[instance_id].party_id)) == NULL || (sd = party_getavailablesd(p)) == NULL)
- return 0;
-
- switch (type) {
- case 1:
- // S 0x2cb <Instance name>.61B <Standby Position>.W
- // Required to start the instancing information window on Client
- // This window re-appear each "refresh" of client automatically until type 4 is send to client.
- WBUFW(buf,0) = 0x02CB;
- memcpy(WBUFP(buf,2),instance[instance_id].name,INSTANCE_NAME_LENGTH);
- WBUFW(buf,63) = flag;
- clif_send(buf,packet_len(0x02CB),&sd->bl,PARTY);
- break;
- case 2:
- // S 0x2cc <Standby Position>.W
- // To announce Instancing queue creation if no maps available
- WBUFW(buf,0) = 0x02CC;
- WBUFW(buf,2) = flag;
- clif_send(buf,packet_len(0x02CC),&sd->bl,PARTY);
- break;
- case 3:
- case 4:
- // S 0x2cd <Instance Name>.61B <Instance Remaining Time>.L <Instance Noplayers close time>.L
- WBUFW(buf,0) = 0x02CD;
- memcpy(WBUFP(buf,2),instance[instance_id].name,61);
- if (type == 3) {
- WBUFL(buf,63) = (uint32)instance[instance_id].progress_timeout;
- WBUFL(buf,67) = 0;
- } else {
- WBUFL(buf,63) = 0;
- WBUFL(buf,67) = (uint32)instance[instance_id].idle_timeout;
- }
- clif_send(buf,packet_len(0x02CD),&sd->bl,PARTY);
- break;
- case 5:
- // S 0x2ce <Message ID>.L
- // 0 = Notification (EnterLimitDate update?)
- // 1 = The Memorial Dungeon expired; it has been destroyed
- // 2 = The Memorial Dungeon's entry time limit expired; it has been destroyed
- // 3 = The Memorial Dungeon has been removed.
- // 4 = Create failure (removes the instance window)
- WBUFW(buf,0) = 0x02CE;
- WBUFL(buf,2) = flag;
- //WBUFL(buf,6) = EnterLimitDate;
- clif_send(buf,packet_len(0x02CE),&sd->bl,PARTY);
- break;
- }
- return 0;
+ struct map_session_data *sd;
+ struct party_data *p;
+ unsigned char buf[255];
+
+ if( (p = party_search(instance[instance_id].party_id)) == NULL || (sd = party_getavailablesd(p)) == NULL )
+ return 0;
+
+ switch( type )
+ {
+ case 1:
+ // S 0x2cb <Instance name>.61B <Standby Position>.W
+ // Required to start the instancing information window on Client
+ // This window re-appear each "refresh" of client automatically until type 4 is send to client.
+ WBUFW(buf,0) = 0x02CB;
+ memcpy(WBUFP(buf,2),instance[instance_id].name,INSTANCE_NAME_LENGTH);
+ WBUFW(buf,63) = flag;
+ clif_send(buf,packet_len(0x02CB),&sd->bl,PARTY);
+ break;
+ case 2:
+ // S 0x2cc <Standby Position>.W
+ // To announce Instancing queue creation if no maps available
+ WBUFW(buf,0) = 0x02CC;
+ WBUFW(buf,2) = flag;
+ clif_send(buf,packet_len(0x02CC),&sd->bl,PARTY);
+ break;
+ case 3:
+ case 4:
+ // S 0x2cd <Instance Name>.61B <Instance Remaining Time>.L <Instance Noplayers close time>.L
+ WBUFW(buf,0) = 0x02CD;
+ memcpy(WBUFP(buf,2),instance[instance_id].name,61);
+ if( type == 3 )
+ {
+ WBUFL(buf,63) = (uint32)instance[instance_id].progress_timeout;
+ WBUFL(buf,67) = 0;
+ }
+ else
+ {
+ WBUFL(buf,63) = 0;
+ WBUFL(buf,67) = (uint32)instance[instance_id].idle_timeout;
+ }
+ clif_send(buf,packet_len(0x02CD),&sd->bl,PARTY);
+ break;
+ case 5:
+ // S 0x2ce <Message ID>.L
+ // 0 = Notification (EnterLimitDate update?)
+ // 1 = The Memorial Dungeon expired; it has been destroyed
+ // 2 = The Memorial Dungeon's entry time limit expired; it has been destroyed
+ // 3 = The Memorial Dungeon has been removed.
+ // 4 = Create failure (removes the instance window)
+ WBUFW(buf,0) = 0x02CE;
+ WBUFL(buf,2) = flag;
+ //WBUFL(buf,6) = EnterLimitDate;
+ clif_send(buf,packet_len(0x02CE),&sd->bl,PARTY);
+ break;
+ }
+ return 0;
}
void clif_instance_join(int fd, int instance_id)
{
- if (instance[instance_id].idle_timer != INVALID_TIMER) {
- WFIFOHEAD(fd,packet_len(0x02CD));
- WFIFOW(fd,0) = 0x02CD;
- memcpy(WFIFOP(fd,2),instance[instance_id].name,61);
- WFIFOL(fd,63) = 0;
- WFIFOL(fd,67) = (uint32)instance[instance_id].idle_timeout;
- WFIFOSET(fd,packet_len(0x02CD));
- } else if (instance[instance_id].progress_timer != INVALID_TIMER) {
- WFIFOHEAD(fd,packet_len(0x02CD));
- WFIFOW(fd,0) = 0x02CD;
- memcpy(WFIFOP(fd,2),instance[instance_id].name,61);
- WFIFOL(fd,63) = (uint32)instance[instance_id].progress_timeout;;
- WFIFOL(fd,67) = 0;
- WFIFOSET(fd,packet_len(0x02CD));
- } else {
- WFIFOHEAD(fd,packet_len(0x02CB));
- WFIFOW(fd,0) = 0x02CB;
- memcpy(WFIFOP(fd,2),instance[instance_id].name,61);
- WFIFOW(fd,63) = 0;
- WFIFOSET(fd,packet_len(0x02CB));
- }
+ if( instance[instance_id].idle_timer != INVALID_TIMER )
+ {
+ WFIFOHEAD(fd,packet_len(0x02CD));
+ WFIFOW(fd,0) = 0x02CD;
+ memcpy(WFIFOP(fd,2),instance[instance_id].name,61);
+ WFIFOL(fd,63) = 0;
+ WFIFOL(fd,67) = (uint32)instance[instance_id].idle_timeout;
+ WFIFOSET(fd,packet_len(0x02CD));
+ }
+ else if( instance[instance_id].progress_timer != INVALID_TIMER )
+ {
+ WFIFOHEAD(fd,packet_len(0x02CD));
+ WFIFOW(fd,0) = 0x02CD;
+ memcpy(WFIFOP(fd,2),instance[instance_id].name,61);
+ WFIFOL(fd,63) = (uint32)instance[instance_id].progress_timeout;;
+ WFIFOL(fd,67) = 0;
+ WFIFOSET(fd,packet_len(0x02CD));
+ }
+ else
+ {
+ WFIFOHEAD(fd,packet_len(0x02CB));
+ WFIFOW(fd,0) = 0x02CB;
+ memcpy(WFIFOP(fd,2),instance[instance_id].name,61);
+ WFIFOW(fd,63) = 0;
+ WFIFOSET(fd,packet_len(0x02CB));
+ }
}
void clif_instance_leave(int fd)
{
- WFIFOHEAD(fd,packet_len(0x02CE));
- WFIFOW(fd,0) = 0x02ce;
- WFIFOL(fd,2) = 4;
- WFIFOSET(fd,packet_len(0x02CE));
+ WFIFOHEAD(fd,packet_len(0x02CE));
+ WFIFOW(fd,0) = 0x02ce;
+ WFIFOL(fd,2) = 4;
+ WFIFOSET(fd,packet_len(0x02CE));
}
/// Notifies clients about item picked up by a party member (ZC_ITEM_PICKUP_PARTY).
/// 02b8 <account id>.L <name id>.W <identified>.B <damaged>.B <refine>.B <card1>.W <card2>.W <card3>.W <card4>.W <equip location>.W <item type>.B
-void clif_party_show_picker(struct map_session_data *sd, struct item *item_data)
+void clif_party_show_picker(struct map_session_data * sd, struct item * item_data)
{
#if PACKETVER >= 20071002
- unsigned char buf[22];
- struct item_data *id = itemdb_search(item_data->nameid);
-
- WBUFW(buf,0) = 0x2b8;
- WBUFL(buf,2) = sd->status.account_id;
- WBUFW(buf,6) = item_data->nameid;
- WBUFB(buf,8) = item_data->identify;
- WBUFB(buf,9) = item_data->attribute;
- WBUFB(buf,10) = item_data->refine;
- clif_addcards(WBUFP(buf,11), item_data);
- WBUFW(buf,19) = id->equip; // equip location
- WBUFB(buf,21) = itemtype(id->type); // item type
- clif_send(buf, packet_len(0x2b8), &sd->bl, PARTY_SAMEMAP_WOS);
+ unsigned char buf[22];
+ struct item_data* id = itemdb_search(item_data->nameid);
+
+ WBUFW(buf,0) = 0x2b8;
+ WBUFL(buf,2) = sd->status.account_id;
+ WBUFW(buf,6) = item_data->nameid;
+ WBUFB(buf,8) = item_data->identify;
+ WBUFB(buf,9) = item_data->attribute;
+ WBUFB(buf,10) = item_data->refine;
+ clif_addcards(WBUFP(buf,11), item_data);
+ WBUFW(buf,19) = id->equip; // equip location
+ WBUFB(buf,21) = itemtype(id->type); // item type
+ clif_send(buf, packet_len(0x2b8), &sd->bl, PARTY_SAMEMAP_WOS);
#endif
}
@@ -15104,19 +15295,19 @@ void clif_party_show_picker(struct map_session_data *sd, struct item *item_data)
/// 1 = quest exp gain/loss
void clif_displayexp(struct map_session_data *sd, unsigned int exp, char type, bool quest)
{
- int fd;
+ int fd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- fd = sd->fd;
+ fd = sd->fd;
- WFIFOHEAD(fd, packet_len(0x7f6));
- WFIFOW(fd,0) = 0x7f6;
- WFIFOL(fd,2) = sd->bl.id;
- WFIFOL(fd,6) = exp;
- WFIFOW(fd,10) = type;
- WFIFOW(fd,12) = quest?1:0;// Normal exp is shown in yellow, quest exp is shown in purple.
- WFIFOSET(fd,packet_len(0x7f6));
+ WFIFOHEAD(fd, packet_len(0x7f6));
+ WFIFOW(fd,0) = 0x7f6;
+ WFIFOL(fd,2) = sd->bl.id;
+ WFIFOL(fd,6) = exp;
+ WFIFOW(fd,10) = type;
+ WFIFOW(fd,12) = quest?1:0;// Normal exp is shown in yellow, quest exp is shown in purple.
+ WFIFOSET(fd,packet_len(0x7f6));
}
@@ -15128,13 +15319,13 @@ void clif_displayexp(struct map_session_data *sd, unsigned int exp, char type, b
/// 3 = Decremental counter (1 tick/second), 'value' specifies start value (stops when reaching 0, displays at most 2 digits).
/// value:
/// Except for type 3 it is interpreted as seconds for displaying as DD:HH:MM:SS, HH:MM:SS, MM:SS or SS (leftmost '00' is not displayed).
-void clif_showdigit(struct map_session_data *sd, unsigned char type, int value)
+void clif_showdigit(struct map_session_data* sd, unsigned char type, int value)
{
- WFIFOHEAD(sd->fd, packet_len(0x1b1));
- WFIFOW(sd->fd,0) = 0x1b1;
- WFIFOB(sd->fd,2) = type;
- WFIFOL(sd->fd,3) = value;
- WFIFOSET(sd->fd, packet_len(0x1b1));
+ WFIFOHEAD(sd->fd, packet_len(0x1b1));
+ WFIFOW(sd->fd,0) = 0x1b1;
+ WFIFOB(sd->fd,2) = type;
+ WFIFOL(sd->fd,3) = value;
+ WFIFOSET(sd->fd, packet_len(0x1b1));
}
@@ -15150,102 +15341,99 @@ void clif_showdigit(struct map_session_data *sd, unsigned char type, int value)
/// constructed, this state tracking was rendered useless,
/// as the only skill unit, that is sent with 0x1c9 is
/// Graffiti.
-void clif_parse_LessEffect(int fd, struct map_session_data *sd)
+void clif_parse_LessEffect(int fd, struct map_session_data* sd)
{
- int isLess = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
+ int isLess = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
- sd->state.lesseffect = (isLess != 0);
+ sd->state.lesseffect = ( isLess != 0 );
}
/// S 07e4 <length>.w <option>.l <val>.l {<index>.w <amount>.w).4b*
-void clif_parse_ItemListWindowSelected(int fd, struct map_session_data *sd)
-{
- int n = (RFIFOW(fd,2)-12) / 4;
- int type = RFIFOL(fd,4);
- int flag = RFIFOL(fd,8); // Button clicked: 0 = Cancel, 1 = OK
- unsigned short *item_list = (unsigned short *)RFIFOP(fd,12);
-
- if (sd->state.trading || sd->npc_shopid)
- return;
-
- if (flag == 0 || n == 0) {
- clif_menuskill_clear(sd);
- return; // Canceled by player.
- }
-
- if (sd->menuskill_id != SO_EL_ANALYSIS && sd->menuskill_id != GN_CHANGEMATERIAL) {
- clif_menuskill_clear(sd);
- return; // Prevent hacking.
- }
-
- switch (type) {
- case 0: // Change Material
- skill_changematerial(sd,n,item_list);
- break;
- case 1: // Level 1: Pure to Rough
- case 2: // Level 2: Rough to Pure
- skill_elementalanalysis(sd,n,type,item_list);
- break;
- }
- clif_menuskill_clear(sd);
-
- return;
+void clif_parse_ItemListWindowSelected(int fd, struct map_session_data* sd) {
+ int n = (RFIFOW(fd,2)-12) / 4;
+ int type = RFIFOL(fd,4);
+ int flag = RFIFOL(fd,8); // Button clicked: 0 = Cancel, 1 = OK
+ unsigned short* item_list = (unsigned short*)RFIFOP(fd,12);
+
+ if( sd->state.trading || sd->npc_shopid )
+ return;
+
+ if( flag == 0 || n == 0) {
+ clif_menuskill_clear(sd);
+ return; // Canceled by player.
+ }
+
+ if( sd->menuskill_id != SO_EL_ANALYSIS && sd->menuskill_id != GN_CHANGEMATERIAL ) {
+ clif_menuskill_clear(sd);
+ return; // Prevent hacking.
+ }
+
+ switch( type ) {
+ case 0: // Change Material
+ skill_changematerial(sd,n,item_list);
+ break;
+ case 1: // Level 1: Pure to Rough
+ case 2: // Level 2: Rough to Pure
+ skill_elementalanalysis(sd,n,type,item_list);
+ break;
+ }
+ clif_menuskill_clear(sd);
+
+ return;
}
/*==========================================
* Elemental System
*==========================================*/
-void clif_elemental_updatestatus(struct map_session_data *sd, int type)
-{
- struct elemental_data *ed;
- struct status_data *status;
- int fd;
-
- if (sd == NULL || (ed = sd->ed) == NULL)
- return;
-
- fd = sd->fd;
- status = &ed->battle_status;
- WFIFOHEAD(fd,8);
- WFIFOW(fd,0) = 0x81e;
- WFIFOW(fd,2) = type;
- switch (type) {
- case SP_HP:
- WFIFOL(fd,4) = status->hp;
- break;
- case SP_MAXHP:
- WFIFOL(fd,4) = status->max_hp;
- break;
- case SP_SP:
- WFIFOL(fd,4) = status->sp;
- break;
- case SP_MAXSP:
- WFIFOL(fd,4) = status->max_sp;
- break;
- }
- WFIFOSET(fd,8);
-}
-
-void clif_elemental_info(struct map_session_data *sd)
-{
- int fd;
- struct elemental_data *ed;
- struct status_data *status;
-
- if (sd == NULL || (ed = sd->ed) == NULL)
- return;
-
- fd = sd->fd;
- status = &ed->battle_status;
-
- WFIFOHEAD(fd,22);
- WFIFOW(fd, 0) = 0x81d;
- WFIFOL(fd, 2) = ed->bl.id;
- WFIFOL(fd, 6) = status->hp;
- WFIFOL(fd,10) = status->max_hp;
- WFIFOL(fd,14) = status->sp;
- WFIFOL(fd,18) = status->max_sp;
- WFIFOSET(fd,22);
+void clif_elemental_updatestatus(struct map_session_data *sd, int type) {
+ struct elemental_data *ed;
+ struct status_data *status;
+ int fd;
+
+ if( sd == NULL || (ed = sd->ed) == NULL )
+ return;
+
+ fd = sd->fd;
+ status = &ed->battle_status;
+ WFIFOHEAD(fd,8);
+ WFIFOW(fd,0) = 0x81e;
+ WFIFOW(fd,2) = type;
+ switch( type ) {
+ case SP_HP:
+ WFIFOL(fd,4) = status->hp;
+ break;
+ case SP_MAXHP:
+ WFIFOL(fd,4) = status->max_hp;
+ break;
+ case SP_SP:
+ WFIFOL(fd,4) = status->sp;
+ break;
+ case SP_MAXSP:
+ WFIFOL(fd,4) = status->max_sp;
+ break;
+ }
+ WFIFOSET(fd,8);
+}
+
+void clif_elemental_info(struct map_session_data *sd) {
+ int fd;
+ struct elemental_data *ed;
+ struct status_data *status;
+
+ if( sd == NULL || (ed = sd->ed) == NULL )
+ return;
+
+ fd = sd->fd;
+ status = &ed->battle_status;
+
+ WFIFOHEAD(fd,22);
+ WFIFOW(fd, 0) = 0x81d;
+ WFIFOL(fd, 2) = ed->bl.id;
+ WFIFOL(fd, 6) = status->hp;
+ WFIFOL(fd,10) = status->max_hp;
+ WFIFOL(fd,14) = status->sp;
+ WFIFOL(fd,18) = status->max_sp;
+ WFIFOSET(fd,22);
}
@@ -15254,14 +15442,14 @@ void clif_elemental_info(struct map_session_data *sd)
/// Opens preparation window for buying store (ZC_OPEN_BUYING_STORE).
/// 0810 <slots>.B
-void clif_buyingstore_open(struct map_session_data *sd)
+void clif_buyingstore_open(struct map_session_data* sd)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x810));
- WFIFOW(fd,0) = 0x810;
- WFIFOB(fd,2) = sd->buyingstore.slots;
- WFIFOSET(fd,packet_len(0x810));
+ WFIFOHEAD(fd,packet_len(0x810));
+ WFIFOW(fd,0) = 0x810;
+ WFIFOB(fd,2) = sd->buyingstore.slots;
+ WFIFOSET(fd,packet_len(0x810));
}
@@ -15270,40 +15458,41 @@ void clif_buyingstore_open(struct map_session_data *sd)
/// result:
/// 0 = cancel
/// 1 = open
-static void clif_parse_ReqOpenBuyingStore(int fd, struct map_session_data *sd)
-{
- const unsigned int blocksize = 8;
- uint8 *itemlist;
- char storename[MESSAGE_SIZE];
- unsigned char result;
- int zenylimit;
- unsigned int count, packet_len;
- struct s_packet_db *info = &packet_db[sd->packet_ver][RFIFOW(fd,0)];
-
- packet_len = RFIFOW(fd,info->pos[0]);
-
- // TODO: Make this check global for all variable length packets.
- if (packet_len < 89) {
- // minimum packet length
- ShowError("clif_parse_ReqOpenBuyingStore: Malformed packet (expected length=%u, length=%u, account_id=%d).\n", 89, packet_len, sd->bl.id);
- return;
- }
+static void clif_parse_ReqOpenBuyingStore(int fd, struct map_session_data* sd)
+{
+ const unsigned int blocksize = 8;
+ uint8* itemlist;
+ char storename[MESSAGE_SIZE];
+ unsigned char result;
+ int zenylimit;
+ unsigned int count, packet_len;
+ struct s_packet_db* info = &packet_db[sd->packet_ver][RFIFOW(fd,0)];
- zenylimit = RFIFOL(fd,info->pos[1]);
- result = RFIFOL(fd,info->pos[2]);
- safestrncpy(storename, (const char *)RFIFOP(fd,info->pos[3]), sizeof(storename));
- itemlist = RFIFOP(fd,info->pos[4]);
+ packet_len = RFIFOW(fd,info->pos[0]);
- // so that buyingstore_create knows, how many elements it has access to
- packet_len-= info->pos[4];
+ // TODO: Make this check global for all variable length packets.
+ if( packet_len < 89 )
+ {// minimum packet length
+ ShowError("clif_parse_ReqOpenBuyingStore: Malformed packet (expected length=%u, length=%u, account_id=%d).\n", 89, packet_len, sd->bl.id);
+ return;
+ }
- if (packet_len%blocksize) {
- ShowError("clif_parse_ReqOpenBuyingStore: Unexpected item list size %u (account_id=%d, block size=%u)\n", packet_len, sd->bl.id, blocksize);
- return;
- }
- count = packet_len/blocksize;
+ zenylimit = RFIFOL(fd,info->pos[1]);
+ result = RFIFOL(fd,info->pos[2]);
+ safestrncpy(storename, (const char*)RFIFOP(fd,info->pos[3]), sizeof(storename));
+ itemlist = RFIFOP(fd,info->pos[4]);
+
+ // so that buyingstore_create knows, how many elements it has access to
+ packet_len-= info->pos[4];
+
+ if( packet_len%blocksize )
+ {
+ ShowError("clif_parse_ReqOpenBuyingStore: Unexpected item list size %u (account_id=%d, block size=%u)\n", packet_len, sd->bl.id, blocksize);
+ return;
+ }
+ count = packet_len/blocksize;
- buyingstore_create(sd, zenylimit, result, storename, itemlist, count);
+ buyingstore_create(sd, zenylimit, result, storename, itemlist, count);
}
@@ -15314,165 +15503,168 @@ static void clif_parse_ReqOpenBuyingStore(int fd, struct map_session_data *sd)
/// 2 = "Total amount of then possessed items exceeds the weight limit by <weight/10-maxweight*90%>. Please re-enter." (0x6ce, MSI_BUYINGSTORE_OVERWEIGHT)
/// 8 = "No sale (purchase) information available." (0x705)
/// ? = nothing
-void clif_buyingstore_open_failed(struct map_session_data *sd, unsigned short result, unsigned int weight)
+void clif_buyingstore_open_failed(struct map_session_data* sd, unsigned short result, unsigned int weight)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x812));
- WFIFOW(fd,0) = 0x812;
- WFIFOW(fd,2) = result;
- WFIFOL(fd,4) = weight;
- WFIFOSET(fd,packet_len(0x812));
+ WFIFOHEAD(fd,packet_len(0x812));
+ WFIFOW(fd,0) = 0x812;
+ WFIFOW(fd,2) = result;
+ WFIFOL(fd,4) = weight;
+ WFIFOSET(fd,packet_len(0x812));
}
/// Notification, that the requested buying store was created (ZC_MYITEMLIST_BUYING_STORE).
/// 0813 <packet len>.W <account id>.L <limit zeny>.L { <price>.L <count>.W <type>.B <name id>.W }*
-void clif_buyingstore_myitemlist(struct map_session_data *sd)
-{
- int fd = sd->fd;
- unsigned int i;
-
- WFIFOHEAD(fd,12+sd->buyingstore.slots*9);
- WFIFOW(fd,0) = 0x813;
- WFIFOW(fd,2) = 12+sd->buyingstore.slots*9;
- WFIFOL(fd,4) = sd->bl.id;
- WFIFOL(fd,8) = sd->buyingstore.zenylimit;
-
- for (i = 0; i < sd->buyingstore.slots; i++) {
- WFIFOL(fd,12+i*9) = sd->buyingstore.items[i].price;
- WFIFOW(fd,16+i*9) = sd->buyingstore.items[i].amount;
- WFIFOB(fd,18+i*9) = itemtype(itemdb_type(sd->buyingstore.items[i].nameid));
- WFIFOW(fd,19+i*9) = sd->buyingstore.items[i].nameid;
- }
+void clif_buyingstore_myitemlist(struct map_session_data* sd)
+{
+ int fd = sd->fd;
+ unsigned int i;
+
+ WFIFOHEAD(fd,12+sd->buyingstore.slots*9);
+ WFIFOW(fd,0) = 0x813;
+ WFIFOW(fd,2) = 12+sd->buyingstore.slots*9;
+ WFIFOL(fd,4) = sd->bl.id;
+ WFIFOL(fd,8) = sd->buyingstore.zenylimit;
+
+ for( i = 0; i < sd->buyingstore.slots; i++ )
+ {
+ WFIFOL(fd,12+i*9) = sd->buyingstore.items[i].price;
+ WFIFOW(fd,16+i*9) = sd->buyingstore.items[i].amount;
+ WFIFOB(fd,18+i*9) = itemtype(itemdb_type(sd->buyingstore.items[i].nameid));
+ WFIFOW(fd,19+i*9) = sd->buyingstore.items[i].nameid;
+ }
- WFIFOSET(fd,WFIFOW(fd,2));
+ WFIFOSET(fd,WFIFOW(fd,2));
}
/// Notifies clients in area of a buying store (ZC_BUYING_STORE_ENTRY).
/// 0814 <account id>.L <store name>.80B
-void clif_buyingstore_entry(struct map_session_data *sd)
+void clif_buyingstore_entry(struct map_session_data* sd)
{
- uint8 buf[86];
+ uint8 buf[86];
- WBUFW(buf,0) = 0x814;
- WBUFL(buf,2) = sd->bl.id;
- memcpy(WBUFP(buf,6), sd->message, MESSAGE_SIZE);
+ WBUFW(buf,0) = 0x814;
+ WBUFL(buf,2) = sd->bl.id;
+ memcpy(WBUFP(buf,6), sd->message, MESSAGE_SIZE);
- clif_send(buf, packet_len(0x814), &sd->bl, AREA_WOS);
+ clif_send(buf, packet_len(0x814), &sd->bl, AREA_WOS);
}
-void clif_buyingstore_entry_single(struct map_session_data *sd, struct map_session_data *pl_sd)
+void clif_buyingstore_entry_single(struct map_session_data* sd, struct map_session_data* pl_sd)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x814));
- WFIFOW(fd,0) = 0x814;
- WFIFOL(fd,2) = pl_sd->bl.id;
- memcpy(WFIFOP(fd,6), pl_sd->message, MESSAGE_SIZE);
- WFIFOSET(fd,packet_len(0x814));
+ WFIFOHEAD(fd,packet_len(0x814));
+ WFIFOW(fd,0) = 0x814;
+ WFIFOL(fd,2) = pl_sd->bl.id;
+ memcpy(WFIFOP(fd,6), pl_sd->message, MESSAGE_SIZE);
+ WFIFOSET(fd,packet_len(0x814));
}
/// Request to close own buying store (CZ_REQ_CLOSE_BUYING_STORE).
/// 0815
-static void clif_parse_ReqCloseBuyingStore(int fd, struct map_session_data *sd)
+static void clif_parse_ReqCloseBuyingStore(int fd, struct map_session_data* sd)
{
- buyingstore_close(sd);
+ buyingstore_close(sd);
}
/// Notifies clients in area that a buying store was closed (ZC_DISAPPEAR_BUYING_STORE_ENTRY).
/// 0816 <account id>.L
-void clif_buyingstore_disappear_entry(struct map_session_data *sd)
+void clif_buyingstore_disappear_entry(struct map_session_data* sd)
{
- uint8 buf[6];
+ uint8 buf[6];
- WBUFW(buf,0) = 0x816;
- WBUFL(buf,2) = sd->bl.id;
+ WBUFW(buf,0) = 0x816;
+ WBUFL(buf,2) = sd->bl.id;
- clif_send(buf, packet_len(0x816), &sd->bl, AREA_WOS);
+ clif_send(buf, packet_len(0x816), &sd->bl, AREA_WOS);
}
-void clif_buyingstore_disappear_entry_single(struct map_session_data *sd, struct map_session_data *pl_sd)
+void clif_buyingstore_disappear_entry_single(struct map_session_data* sd, struct map_session_data* pl_sd)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x816));
- WFIFOW(fd,0) = 0x816;
- WFIFOL(fd,2) = pl_sd->bl.id;
- WFIFOSET(fd,packet_len(0x816));
+ WFIFOHEAD(fd,packet_len(0x816));
+ WFIFOW(fd,0) = 0x816;
+ WFIFOL(fd,2) = pl_sd->bl.id;
+ WFIFOSET(fd,packet_len(0x816));
}
/// Request to open someone else's buying store (CZ_REQ_CLICK_TO_BUYING_STORE).
/// 0817 <account id>.L
-static void clif_parse_ReqClickBuyingStore(int fd, struct map_session_data *sd)
+static void clif_parse_ReqClickBuyingStore(int fd, struct map_session_data* sd)
{
- int account_id;
+ int account_id;
- account_id = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
+ account_id = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
- buyingstore_open(sd, account_id);
+ buyingstore_open(sd, account_id);
}
/// Sends buying store item list (ZC_ACK_ITEMLIST_BUYING_STORE).
/// 0818 <packet len>.W <account id>.L <store id>.L <limit zeny>.L { <price>.L <amount>.W <type>.B <name id>.W }*
-void clif_buyingstore_itemlist(struct map_session_data *sd, struct map_session_data *pl_sd)
-{
- int fd = sd->fd;
- unsigned int i;
-
- WFIFOHEAD(fd,16+pl_sd->buyingstore.slots*9);
- WFIFOW(fd,0) = 0x818;
- WFIFOW(fd,2) = 16+pl_sd->buyingstore.slots*9;
- WFIFOL(fd,4) = pl_sd->bl.id;
- WFIFOL(fd,8) = pl_sd->buyer_id;
- WFIFOL(fd,12) = pl_sd->buyingstore.zenylimit;
-
- for (i = 0; i < pl_sd->buyingstore.slots; i++) {
- WFIFOL(fd,16+i*9) = pl_sd->buyingstore.items[i].price;
- WFIFOW(fd,20+i*9) = pl_sd->buyingstore.items[i].amount; // TODO: Figure out, if no longer needed items (amount == 0) are listed on official.
- WFIFOB(fd,22+i*9) = itemtype(itemdb_type(pl_sd->buyingstore.items[i].nameid));
- WFIFOW(fd,23+i*9) = pl_sd->buyingstore.items[i].nameid;
- }
+void clif_buyingstore_itemlist(struct map_session_data* sd, struct map_session_data* pl_sd)
+{
+ int fd = sd->fd;
+ unsigned int i;
+
+ WFIFOHEAD(fd,16+pl_sd->buyingstore.slots*9);
+ WFIFOW(fd,0) = 0x818;
+ WFIFOW(fd,2) = 16+pl_sd->buyingstore.slots*9;
+ WFIFOL(fd,4) = pl_sd->bl.id;
+ WFIFOL(fd,8) = pl_sd->buyer_id;
+ WFIFOL(fd,12) = pl_sd->buyingstore.zenylimit;
+
+ for( i = 0; i < pl_sd->buyingstore.slots; i++ )
+ {
+ WFIFOL(fd,16+i*9) = pl_sd->buyingstore.items[i].price;
+ WFIFOW(fd,20+i*9) = pl_sd->buyingstore.items[i].amount; // TODO: Figure out, if no longer needed items (amount == 0) are listed on official.
+ WFIFOB(fd,22+i*9) = itemtype(itemdb_type(pl_sd->buyingstore.items[i].nameid));
+ WFIFOW(fd,23+i*9) = pl_sd->buyingstore.items[i].nameid;
+ }
- WFIFOSET(fd,WFIFOW(fd,2));
+ WFIFOSET(fd,WFIFOW(fd,2));
}
/// Request to sell items to a buying store (CZ_REQ_TRADE_BUYING_STORE).
/// 0819 <packet len>.W <account id>.L <store id>.L { <index>.W <name id>.W <amount>.W }*
-static void clif_parse_ReqTradeBuyingStore(int fd, struct map_session_data *sd)
+static void clif_parse_ReqTradeBuyingStore(int fd, struct map_session_data* sd)
{
- const unsigned int blocksize = 6;
- uint8 *itemlist;
- int account_id;
- unsigned int count, packet_len, buyer_id;
- struct s_packet_db *info = &packet_db[sd->packet_ver][RFIFOW(fd,0)];
+ const unsigned int blocksize = 6;
+ uint8* itemlist;
+ int account_id;
+ unsigned int count, packet_len, buyer_id;
+ struct s_packet_db* info = &packet_db[sd->packet_ver][RFIFOW(fd,0)];
- packet_len = RFIFOW(fd,info->pos[0]);
+ packet_len = RFIFOW(fd,info->pos[0]);
- if (packet_len < 12) {
- // minimum packet length
- ShowError("clif_parse_ReqTradeBuyingStore: Malformed packet (expected length=%u, length=%u, account_id=%d).\n", 12, packet_len, sd->bl.id);
- return;
- }
+ if( packet_len < 12 )
+ {// minimum packet length
+ ShowError("clif_parse_ReqTradeBuyingStore: Malformed packet (expected length=%u, length=%u, account_id=%d).\n", 12, packet_len, sd->bl.id);
+ return;
+ }
- account_id = RFIFOL(fd,info->pos[1]);
- buyer_id = RFIFOL(fd,info->pos[2]);
- itemlist = RFIFOP(fd,info->pos[3]);
+ account_id = RFIFOL(fd,info->pos[1]);
+ buyer_id = RFIFOL(fd,info->pos[2]);
+ itemlist = RFIFOP(fd,info->pos[3]);
- // so that buyingstore_trade knows, how many elements it has access to
- packet_len-= info->pos[3];
+ // so that buyingstore_trade knows, how many elements it has access to
+ packet_len-= info->pos[3];
- if (packet_len%blocksize) {
- ShowError("clif_parse_ReqTradeBuyingStore: Unexpected item list size %u (account_id=%d, buyer_id=%d, block size=%u)\n", packet_len, sd->bl.id, account_id, blocksize);
- return;
- }
- count = packet_len/blocksize;
+ if( packet_len%blocksize )
+ {
+ ShowError("clif_parse_ReqTradeBuyingStore: Unexpected item list size %u (account_id=%d, buyer_id=%d, block size=%u)\n", packet_len, sd->bl.id, account_id, blocksize);
+ return;
+ }
+ count = packet_len/blocksize;
- buyingstore_trade(sd, account_id, buyer_id, itemlist, count);
+ buyingstore_trade(sd, account_id, buyer_id, itemlist, count);
}
@@ -15482,29 +15674,29 @@ static void clif_parse_ReqTradeBuyingStore(int fd, struct map_session_data *sd)
/// 3 = "All items within the buy limit were purchased." (0x6cf, MSI_BUYINGSTORE_TRADE_OVERLIMITZENY)
/// 4 = "All items were purchased." (0x6d0, MSI_BUYINGSTORE_TRADE_BUYCOMPLETE)
/// ? = nothing
-void clif_buyingstore_trade_failed_buyer(struct map_session_data *sd, short result)
+void clif_buyingstore_trade_failed_buyer(struct map_session_data* sd, short result)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x81a));
- WFIFOW(fd,0) = 0x81a;
- WFIFOW(fd,2) = result;
- WFIFOSET(fd,packet_len(0x81a));
+ WFIFOHEAD(fd,packet_len(0x81a));
+ WFIFOW(fd,0) = 0x81a;
+ WFIFOW(fd,2) = result;
+ WFIFOSET(fd,packet_len(0x81a));
}
/// Updates the zeny limit and an item in the buying store item list (ZC_UPDATE_ITEM_FROM_BUYING_STORE).
/// 081b <name id>.W <amount>.W <limit zeny>.L
-void clif_buyingstore_update_item(struct map_session_data *sd, unsigned short nameid, unsigned short amount)
+void clif_buyingstore_update_item(struct map_session_data* sd, unsigned short nameid, unsigned short amount)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x81b));
- WFIFOW(fd,0) = 0x81b;
- WFIFOW(fd,2) = nameid;
- WFIFOW(fd,4) = amount; // amount of nameid received
- WFIFOL(fd,6) = sd->buyingstore.zenylimit;
- WFIFOSET(fd,packet_len(0x81b));
+ WFIFOHEAD(fd,packet_len(0x81b));
+ WFIFOW(fd,0) = 0x81b;
+ WFIFOW(fd,2) = nameid;
+ WFIFOW(fd,4) = amount; // amount of nameid received
+ WFIFOL(fd,6) = sd->buyingstore.zenylimit;
+ WFIFOSET(fd,packet_len(0x81b));
}
@@ -15514,16 +15706,16 @@ void clif_buyingstore_update_item(struct map_session_data *sd, unsigned short na
/// "%s (%d) were sold at %dz." (0x6d2, MSI_BUYINGSTORE_TRADE_SELLCOMPLETE)
///
/// NOTE: This function has to be called _instead_ of clif_delitem/clif_dropitem.
-void clif_buyingstore_delete_item(struct map_session_data *sd, short index, unsigned short amount, int price)
+void clif_buyingstore_delete_item(struct map_session_data* sd, short index, unsigned short amount, int price)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x81c));
- WFIFOW(fd,0) = 0x81c;
- WFIFOW(fd,2) = index+2;
- WFIFOW(fd,4) = amount;
- WFIFOL(fd,6) = price; // price per item, client calculates total Zeny by itself
- WFIFOSET(fd,packet_len(0x81c));
+ WFIFOHEAD(fd,packet_len(0x81c));
+ WFIFOW(fd,0) = 0x81c;
+ WFIFOW(fd,2) = index+2;
+ WFIFOW(fd,4) = amount;
+ WFIFOL(fd,6) = price; // price per item, client calculates total Zeny by itself
+ WFIFOSET(fd,packet_len(0x81c));
}
@@ -15534,15 +15726,15 @@ void clif_buyingstore_delete_item(struct map_session_data *sd, short index, unsi
/// 6 = "The trade failed, because the entered amount of item %s is higher, than the buyer is willing to buy." (0x6d3, MSI_BUYINGSTORE_TRADE_OVERCOUNT)
/// 7 = "The trade failed, because the buyer is lacking required balance." (0x6d1, MSI_BUYINGSTORE_TRADE_LACKBUYERZENY)
/// ? = nothing
-void clif_buyingstore_trade_failed_seller(struct map_session_data *sd, short result, unsigned short nameid)
+void clif_buyingstore_trade_failed_seller(struct map_session_data* sd, short result, unsigned short nameid)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x824));
- WFIFOW(fd,0) = 0x824;
- WFIFOW(fd,2) = result;
- WFIFOW(fd,4) = nameid;
- WFIFOSET(fd,packet_len(0x824));
+ WFIFOHEAD(fd,packet_len(0x824));
+ WFIFOW(fd,0) = 0x824;
+ WFIFOW(fd,2) = result;
+ WFIFOW(fd,4) = nameid;
+ WFIFOSET(fd,packet_len(0x824));
}
@@ -15558,46 +15750,48 @@ void clif_buyingstore_trade_failed_seller(struct map_session_data *sd, short res
/// NOTE: The client determines the item ids by specifying a name and optionally,
/// amount of card slots. If the client does not know about the item it
/// cannot be searched.
-static void clif_parse_SearchStoreInfo(int fd, struct map_session_data *sd)
+static void clif_parse_SearchStoreInfo(int fd, struct map_session_data* sd)
{
- const unsigned int blocksize = 2;
- const uint8 *itemlist;
- const uint8 *cardlist;
- unsigned char type;
- unsigned int min_price, max_price, packet_len, count, item_count, card_count;
- struct s_packet_db *info = &packet_db[sd->packet_ver][RFIFOW(fd,0)];
+ const unsigned int blocksize = 2;
+ const uint8* itemlist;
+ const uint8* cardlist;
+ unsigned char type;
+ unsigned int min_price, max_price, packet_len, count, item_count, card_count;
+ struct s_packet_db* info = &packet_db[sd->packet_ver][RFIFOW(fd,0)];
- packet_len = RFIFOW(fd,info->pos[0]);
+ packet_len = RFIFOW(fd,info->pos[0]);
- if (packet_len < 15) {
- // minimum packet length
- ShowError("clif_parse_SearchStoreInfo: Malformed packet (expected length=%u, length=%u, account_id=%d).\n", 15, packet_len, sd->bl.id);
- return;
- }
+ if( packet_len < 15 )
+ {// minimum packet length
+ ShowError("clif_parse_SearchStoreInfo: Malformed packet (expected length=%u, length=%u, account_id=%d).\n", 15, packet_len, sd->bl.id);
+ return;
+ }
- type = RFIFOB(fd,info->pos[1]);
- max_price = RFIFOL(fd,info->pos[2]);
- min_price = RFIFOL(fd,info->pos[3]);
- item_count = RFIFOB(fd,info->pos[4]);
- card_count = RFIFOB(fd,info->pos[5]);
- itemlist = RFIFOP(fd,info->pos[6]);
- cardlist = RFIFOP(fd,info->pos[6]+blocksize*item_count);
+ type = RFIFOB(fd,info->pos[1]);
+ max_price = RFIFOL(fd,info->pos[2]);
+ min_price = RFIFOL(fd,info->pos[3]);
+ item_count = RFIFOB(fd,info->pos[4]);
+ card_count = RFIFOB(fd,info->pos[5]);
+ itemlist = RFIFOP(fd,info->pos[6]);
+ cardlist = RFIFOP(fd,info->pos[6]+blocksize*item_count);
- // check, if there is enough data for the claimed count of items
- packet_len-= info->pos[6];
+ // check, if there is enough data for the claimed count of items
+ packet_len-= info->pos[6];
- if (packet_len%blocksize) {
- ShowError("clif_parse_SearchStoreInfo: Unexpected item list size %u (account_id=%d, block size=%u)\n", packet_len, sd->bl.id, blocksize);
- return;
- }
- count = packet_len/blocksize;
+ if( packet_len%blocksize )
+ {
+ ShowError("clif_parse_SearchStoreInfo: Unexpected item list size %u (account_id=%d, block size=%u)\n", packet_len, sd->bl.id, blocksize);
+ return;
+ }
+ count = packet_len/blocksize;
- if (count < item_count+card_count) {
- ShowError("clif_parse_SearchStoreInfo: Malformed packet (expected count=%u, count=%u, account_id=%d).\n", item_count+card_count, count, sd->bl.id);
- return;
- }
+ if( count < item_count+card_count )
+ {
+ ShowError("clif_parse_SearchStoreInfo: Malformed packet (expected count=%u, count=%u, account_id=%d).\n", item_count+card_count, count, sd->bl.id);
+ return;
+ }
- searchstore_query(sd, type, min_price, max_price, (const unsigned short *)itemlist, item_count, (const unsigned short *)cardlist, card_count);
+ searchstore_query(sd, type, min_price, max_price, (const unsigned short*)itemlist, item_count, (const unsigned short*)cardlist, card_count);
}
@@ -15609,45 +15803,46 @@ static void clif_parse_SearchStoreInfo(int fd, struct map_session_data *sd)
/// is next page:
/// 0 = no "next" label
/// 1 = "next" label to retrieve more results
-void clif_search_store_info_ack(struct map_session_data *sd)
-{
- const unsigned int blocksize = MESSAGE_SIZE+26;
- int fd = sd->fd;
- unsigned int i, start, end;
-
- start = sd->searchstore.pages*SEARCHSTORE_RESULTS_PER_PAGE;
- end = min(sd->searchstore.count, start+SEARCHSTORE_RESULTS_PER_PAGE);
-
- WFIFOHEAD(fd,7+(end-start)*blocksize);
- WFIFOW(fd,0) = 0x836;
- WFIFOW(fd,2) = 7+(end-start)*blocksize;
- WFIFOB(fd,4) = !sd->searchstore.pages;
- WFIFOB(fd,5) = searchstore_querynext(sd);
- WFIFOB(fd,6) = (unsigned char)min(sd->searchstore.uses, UINT8_MAX);
-
- for (i = start; i < end; i++) {
- struct s_search_store_info_item *ssitem = &sd->searchstore.items[i];
- struct item it;
-
- WFIFOL(fd,i*blocksize+ 7) = ssitem->store_id;
- WFIFOL(fd,i*blocksize+11) = ssitem->account_id;
- memcpy(WFIFOP(fd,i*blocksize+15), ssitem->store_name, MESSAGE_SIZE);
- WFIFOW(fd,i*blocksize+15+MESSAGE_SIZE) = ssitem->nameid;
- WFIFOB(fd,i*blocksize+17+MESSAGE_SIZE) = itemtype(itemdb_type(ssitem->nameid));
- WFIFOL(fd,i*blocksize+18+MESSAGE_SIZE) = ssitem->price;
- WFIFOW(fd,i*blocksize+22+MESSAGE_SIZE) = ssitem->amount;
- WFIFOB(fd,i*blocksize+24+MESSAGE_SIZE) = ssitem->refine;
-
- // make-up an item for clif_addcards
- memset(&it, 0, sizeof(it));
- memcpy(&it.card, &ssitem->card, sizeof(it.card));
- it.nameid = ssitem->nameid;
- it.amount = ssitem->amount;
-
- clif_addcards(WFIFOP(fd,i*blocksize+25+MESSAGE_SIZE), &it);
- }
+void clif_search_store_info_ack(struct map_session_data* sd)
+{
+ const unsigned int blocksize = MESSAGE_SIZE+26;
+ int fd = sd->fd;
+ unsigned int i, start, end;
+
+ start = sd->searchstore.pages*SEARCHSTORE_RESULTS_PER_PAGE;
+ end = min(sd->searchstore.count, start+SEARCHSTORE_RESULTS_PER_PAGE);
+
+ WFIFOHEAD(fd,7+(end-start)*blocksize);
+ WFIFOW(fd,0) = 0x836;
+ WFIFOW(fd,2) = 7+(end-start)*blocksize;
+ WFIFOB(fd,4) = !sd->searchstore.pages;
+ WFIFOB(fd,5) = searchstore_querynext(sd);
+ WFIFOB(fd,6) = (unsigned char)min(sd->searchstore.uses, UINT8_MAX);
- WFIFOSET(fd,WFIFOW(fd,2));
+ for( i = start; i < end; i++ )
+ {
+ struct s_search_store_info_item* ssitem = &sd->searchstore.items[i];
+ struct item it;
+
+ WFIFOL(fd,i*blocksize+ 7) = ssitem->store_id;
+ WFIFOL(fd,i*blocksize+11) = ssitem->account_id;
+ memcpy(WFIFOP(fd,i*blocksize+15), ssitem->store_name, MESSAGE_SIZE);
+ WFIFOW(fd,i*blocksize+15+MESSAGE_SIZE) = ssitem->nameid;
+ WFIFOB(fd,i*blocksize+17+MESSAGE_SIZE) = itemtype(itemdb_type(ssitem->nameid));
+ WFIFOL(fd,i*blocksize+18+MESSAGE_SIZE) = ssitem->price;
+ WFIFOW(fd,i*blocksize+22+MESSAGE_SIZE) = ssitem->amount;
+ WFIFOB(fd,i*blocksize+24+MESSAGE_SIZE) = ssitem->refine;
+
+ // make-up an item for clif_addcards
+ memset(&it, 0, sizeof(it));
+ memcpy(&it.card, &ssitem->card, sizeof(it.card));
+ it.nameid = ssitem->nameid;
+ it.amount = ssitem->amount;
+
+ clif_addcards(WFIFOP(fd,i*blocksize+25+MESSAGE_SIZE), &it);
+ }
+
+ WFIFOSET(fd,WFIFOW(fd,2));
}
@@ -15659,22 +15854,22 @@ void clif_search_store_info_ack(struct map_session_data *sd)
/// 2 = "You cannot search anymore." (0x706)
/// 3 = "You cannot search yet." (0x708)
/// 4 = "No sale (purchase) information available." (0x705)
-void clif_search_store_info_failed(struct map_session_data *sd, unsigned char reason)
+void clif_search_store_info_failed(struct map_session_data* sd, unsigned char reason)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x837));
- WFIFOW(fd,0) = 0x837;
- WFIFOB(fd,2) = reason;
- WFIFOSET(fd,packet_len(0x837));
+ WFIFOHEAD(fd,packet_len(0x837));
+ WFIFOW(fd,0) = 0x837;
+ WFIFOB(fd,2) = reason;
+ WFIFOSET(fd,packet_len(0x837));
}
/// Request to display next page of results (CZ_SEARCH_STORE_INFO_NEXT_PAGE).
/// 0838
-static void clif_parse_SearchStoreInfoNextPage(int fd, struct map_session_data *sd)
+static void clif_parse_SearchStoreInfoNextPage(int fd, struct map_session_data* sd)
{
- searchstore_next(sd);
+ searchstore_next(sd);
}
@@ -15683,131 +15878,133 @@ static void clif_parse_SearchStoreInfoNextPage(int fd, struct map_session_data *
/// type:
/// 0 = Search Stores
/// 1 = Search Stores (Cash), asks for confirmation, when clicking a store
-void clif_open_search_store_info(struct map_session_data *sd)
+void clif_open_search_store_info(struct map_session_data* sd)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x83a));
- WFIFOW(fd,0) = 0x83a;
- WFIFOW(fd,2) = sd->searchstore.effect;
+ WFIFOHEAD(fd,packet_len(0x83a));
+ WFIFOW(fd,0) = 0x83a;
+ WFIFOW(fd,2) = sd->searchstore.effect;
#if PACKETVER > 20100701
- WFIFOB(fd,4) = (unsigned char)min(sd->searchstore.uses, UINT8_MAX);
+ WFIFOB(fd,4) = (unsigned char)min(sd->searchstore.uses, UINT8_MAX);
#endif
- WFIFOSET(fd,packet_len(0x83a));
+ WFIFOSET(fd,packet_len(0x83a));
}
/// Request to close the store search window (CZ_CLOSE_SEARCH_STORE_INFO).
/// 083b
-static void clif_parse_CloseSearchStoreInfo(int fd, struct map_session_data *sd)
+static void clif_parse_CloseSearchStoreInfo(int fd, struct map_session_data* sd)
{
- searchstore_close(sd);
+ searchstore_close(sd);
}
/// Request to invoke catalog effect on a store from search results (CZ_SSILIST_ITEM_CLICK).
/// 083c <account id>.L <store id>.L <nameid>.W
-static void clif_parse_SearchStoreInfoListItemClick(int fd, struct map_session_data *sd)
+static void clif_parse_SearchStoreInfoListItemClick(int fd, struct map_session_data* sd)
{
- unsigned short nameid;
- int account_id, store_id;
- struct s_packet_db *info = &packet_db[sd->packet_ver][RFIFOW(fd,0)];
+ unsigned short nameid;
+ int account_id, store_id;
+ struct s_packet_db* info = &packet_db[sd->packet_ver][RFIFOW(fd,0)];
- account_id = RFIFOL(fd,info->pos[0]);
- store_id = RFIFOL(fd,info->pos[1]);
- nameid = RFIFOW(fd,info->pos[2]);
+ account_id = RFIFOL(fd,info->pos[0]);
+ store_id = RFIFOL(fd,info->pos[1]);
+ nameid = RFIFOW(fd,info->pos[2]);
- searchstore_click(sd, account_id, store_id, nameid);
+ searchstore_click(sd, account_id, store_id, nameid);
}
/// Notification of the store position on current map (ZC_SSILIST_ITEM_CLICK_ACK).
/// 083d <xPos>.W <yPos>.W
-void clif_search_store_info_click_ack(struct map_session_data *sd, short x, short y)
+void clif_search_store_info_click_ack(struct map_session_data* sd, short x, short y)
{
- int fd = sd->fd;
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x83d));
- WFIFOW(fd,0) = 0x83d;
- WFIFOW(fd,2) = x;
- WFIFOW(fd,4) = y;
- WFIFOSET(fd,packet_len(0x83d));
+ WFIFOHEAD(fd,packet_len(0x83d));
+ WFIFOW(fd,0) = 0x83d;
+ WFIFOW(fd,2) = x;
+ WFIFOW(fd,4) = y;
+ WFIFOSET(fd,packet_len(0x83d));
}
/// Parse function for packet debugging.
void clif_parse_debug(int fd,struct map_session_data *sd)
{
- int cmd, packet_len;
-
- // clif_parse ensures, that there is at least 2 bytes of data
- cmd = RFIFOW(fd,0);
-
- if (sd) {
- packet_len = packet_db[sd->packet_ver][cmd].len;
-
- if (packet_len == 0) {
- // unknown
- packet_len = RFIFOREST(fd);
- } else if (packet_len == -1) {
- // variable length
- packet_len = RFIFOW(fd,2); // clif_parse ensures, that this amount of data is already received
- }
- ShowDebug("Packet debug of 0x%04X (length %d), %s session #%d, %d/%d (AID/CID)\n", cmd, packet_len, sd->state.active ? "authed" : "unauthed", fd, sd->status.account_id, sd->status.char_id);
- } else {
- packet_len = RFIFOREST(fd);
- ShowDebug("Packet debug of 0x%04X (length %d), session #%d\n", cmd, packet_len, fd);
- }
-
- ShowDump(RFIFOP(fd,0), packet_len);
+ int cmd, packet_len;
+
+ // clif_parse ensures, that there is at least 2 bytes of data
+ cmd = RFIFOW(fd,0);
+
+ if( sd )
+ {
+ packet_len = packet_db[sd->packet_ver][cmd].len;
+
+ if( packet_len == 0 )
+ {// unknown
+ packet_len = RFIFOREST(fd);
+ }
+ else if( packet_len == -1 )
+ {// variable length
+ packet_len = RFIFOW(fd,2); // clif_parse ensures, that this amount of data is already received
+ }
+ ShowDebug("Packet debug of 0x%04X (length %d), %s session #%d, %d/%d (AID/CID)\n", cmd, packet_len, sd->state.active ? "authed" : "unauthed", fd, sd->status.account_id, sd->status.char_id);
+ }
+ else
+ {
+ packet_len = RFIFOREST(fd);
+ ShowDebug("Packet debug of 0x%04X (length %d), session #%d\n", cmd, packet_len, fd);
+ }
+
+ ShowDump(RFIFOP(fd,0), packet_len);
}
/*==========================================
* Server tells client to display a window similar to Magnifier (item) one
* Server populates the window with avilable elemental converter options according to player's inventory
*------------------------------------------*/
-int clif_elementalconverter_list(struct map_session_data *sd)
-{
- int i,c,view,fd;
-
- nullpo_ret(sd);
-
-
- /// Main client packet processing function
- fd=sd->fd;
- WFIFOHEAD(fd, MAX_SKILL_PRODUCE_DB *2+4);
- WFIFOW(fd, 0)=0x1ad;
-
- for (i=0,c=0; i<MAX_SKILL_PRODUCE_DB; i++) {
- if (skill_can_produce_mix(sd,skill_produce_db[i].nameid,23, 1)) {
- if ((view = itemdb_viewid(skill_produce_db[i].nameid)) > 0)
- WFIFOW(fd,c*2+ 4)= view;
- else
- WFIFOW(fd,c*2+ 4)= skill_produce_db[i].nameid;
- c++;
- }
- }
- WFIFOW(fd,2) = c*2+4;
- WFIFOSET(fd, WFIFOW(fd,2));
- if (c > 0) {
- sd->menuskill_id = SA_CREATECON;
- sd->menuskill_val = c;
- }
-
- return 0;
+int clif_elementalconverter_list(struct map_session_data *sd) {
+ int i,c,view,fd;
+
+ nullpo_ret(sd);
+
+
+/// Main client packet processing function
+ fd=sd->fd;
+ WFIFOHEAD(fd, MAX_SKILL_PRODUCE_DB *2+4);
+ WFIFOW(fd, 0)=0x1ad;
+
+ for(i=0,c=0;i<MAX_SKILL_PRODUCE_DB;i++){
+ if( skill_can_produce_mix(sd,skill_produce_db[i].nameid,23, 1) ){
+ if((view = itemdb_viewid(skill_produce_db[i].nameid)) > 0)
+ WFIFOW(fd,c*2+ 4)= view;
+ else
+ WFIFOW(fd,c*2+ 4)= skill_produce_db[i].nameid;
+ c++;
+ }
+ }
+ WFIFOW(fd,2) = c*2+4;
+ WFIFOSET(fd, WFIFOW(fd,2));
+ if (c > 0) {
+ sd->menuskill_id = SA_CREATECON;
+ sd->menuskill_val = c;
+ }
+
+ return 0;
}
/**
* Rune Knight
**/
-void clif_millenniumshield(struct map_session_data *sd, short shields)
-{
+void clif_millenniumshield(struct map_session_data *sd, short shields ) {
#if PACKETVER >= 20081217
- unsigned char buf[10];
+ unsigned char buf[10];
- WBUFW(buf,0) = 0x440;
- WBUFL(buf,2) = sd->bl.id;
- WBUFW(buf,6) = shields;
- WBUFW(buf,8) = 0;
- clif_send(buf,packet_len(0x440),&sd->bl,AREA);
+ WBUFW(buf,0) = 0x440;
+ WBUFL(buf,2) = sd->bl.id;
+ WBUFW(buf,6) = shields;
+ WBUFW(buf,8) = 0;
+ clif_send(buf,packet_len(0x440),&sd->bl,AREA);
#endif
}
/**
@@ -15818,33 +16015,37 @@ void clif_millenniumshield(struct map_session_data *sd, short shields)
*------------------------------------------*/
int clif_spellbook_list(struct map_session_data *sd)
{
- int i, c;
- int fd;
-
- nullpo_ret(sd);
-
- fd = sd->fd;
- WFIFOHEAD(fd, 8 * 8 + 8);
- WFIFOW(fd,0) = 0x1ad;
-
- for (i = 0, c = 0; i < MAX_INVENTORY; i ++) {
- if (itemdb_is_spellbook(sd->status.inventory[i].nameid)) {
- WFIFOW(fd, c * 2 + 4) = sd->status.inventory[i].nameid;
- c ++;
- }
- }
-
- if (c > 0) {
- WFIFOW(fd,2) = c * 2 + 4;
- WFIFOSET(fd, WFIFOW(fd, 2));
- sd->menuskill_id = WL_READING_SB;
- sd->menuskill_val = c;
- } else {
- status_change_end(&sd->bl,SC_STOP,INVALID_TIMER);
- clif_skill_fail(sd, WL_READING_SB, USESKILL_FAIL_SPELLBOOK, 0);
- }
-
- return 1;
+ int i, c;
+ int fd;
+
+ nullpo_ret(sd);
+
+ fd = sd->fd;
+ WFIFOHEAD(fd, 8 * 8 + 8);
+ WFIFOW(fd,0) = 0x1ad;
+
+ for( i = 0, c = 0; i < MAX_INVENTORY; i ++ )
+ {
+ if( itemdb_is_spellbook(sd->status.inventory[i].nameid) )
+ {
+ WFIFOW(fd, c * 2 + 4) = sd->status.inventory[i].nameid;
+ c ++;
+ }
+ }
+
+ if( c > 0 )
+ {
+ WFIFOW(fd,2) = c * 2 + 4;
+ WFIFOSET(fd, WFIFOW(fd, 2));
+ sd->menuskill_id = WL_READING_SB;
+ sd->menuskill_val = c;
+ }
+ else{
+ status_change_end(&sd->bl,SC_STOP,INVALID_TIMER);
+ clif_skill_fail(sd, WL_READING_SB, USESKILL_FAIL_SPELLBOOK, 0);
+ }
+
+ return 1;
}
/**
* Mechanic
@@ -15852,36 +16053,35 @@ int clif_spellbook_list(struct map_session_data *sd)
/*==========================================
* Magic Decoy Material List
*------------------------------------------*/
-int clif_magicdecoy_list(struct map_session_data *sd, int skill_lv, short x, short y)
-{
- int i, c;
- int fd;
-
- nullpo_ret(sd);
-
- fd = sd->fd;
- WFIFOHEAD(fd, 8 * 8 + 8);
- WFIFOW(fd,0) = 0x1ad; // This is the official packet. [pakpil]
-
- for (i = 0, c = 0; i < MAX_INVENTORY; i ++) {
- if (itemdb_is_element(sd->status.inventory[i].nameid)) {
- WFIFOW(fd, c * 2 + 4) = sd->status.inventory[i].nameid;
- c ++;
- }
- }
- if (c > 0) {
- sd->menuskill_id = NC_MAGICDECOY;
- sd->menuskill_val = skill_lv;
- sd->sc.comet_x = x;
- sd->sc.comet_y = y;
- WFIFOW(fd,2) = c * 2 + 4;
- WFIFOSET(fd, WFIFOW(fd, 2));
- } else {
- clif_skill_fail(sd,NC_MAGICDECOY,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
-
- return 1;
+int clif_magicdecoy_list(struct map_session_data *sd, int skill_lv, short x, short y) {
+ int i, c;
+ int fd;
+
+ nullpo_ret(sd);
+
+ fd = sd->fd;
+ WFIFOHEAD(fd, 8 * 8 + 8);
+ WFIFOW(fd,0) = 0x1ad; // This is the official packet. [pakpil]
+
+ for( i = 0, c = 0; i < MAX_INVENTORY; i ++ ) {
+ if( itemdb_is_element(sd->status.inventory[i].nameid) ) {
+ WFIFOW(fd, c * 2 + 4) = sd->status.inventory[i].nameid;
+ c ++;
+ }
+ }
+ if( c > 0 ) {
+ sd->menuskill_id = NC_MAGICDECOY;
+ sd->menuskill_val = skill_lv;
+ sd->sc.comet_x = x;
+ sd->sc.comet_y = y;
+ WFIFOW(fd,2) = c * 2 + 4;
+ WFIFOSET(fd, WFIFOW(fd, 2));
+ } else {
+ clif_skill_fail(sd,NC_MAGICDECOY,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+
+ return 1;
}
/**
* Guilotine Cross
@@ -15889,260 +16089,249 @@ int clif_magicdecoy_list(struct map_session_data *sd, int skill_lv, short x, sho
/*==========================================
* Guillotine Cross Poisons List
*------------------------------------------*/
-int clif_poison_list(struct map_session_data *sd, int skill_lv)
-{
- int i, c;
- int fd;
-
- nullpo_ret(sd);
-
- fd = sd->fd;
- WFIFOHEAD(fd, 8 * 8 + 8);
- WFIFOW(fd,0) = 0x1ad; // This is the official packet. [pakpil]
-
- for (i = 0, c = 0; i < MAX_INVENTORY; i ++) {
- if (itemdb_is_poison(sd->status.inventory[i].nameid)) {
- WFIFOW(fd, c * 2 + 4) = sd->status.inventory[i].nameid;
- c ++;
- }
- }
- if (c > 0) {
- sd->menuskill_id = GC_POISONINGWEAPON;
- sd->menuskill_val = skill_lv;
- WFIFOW(fd,2) = c * 2 + 4;
- WFIFOSET(fd, WFIFOW(fd, 2));
- } else {
- clif_skill_fail(sd,GC_POISONINGWEAPON,USESKILL_FAIL_GUILLONTINE_POISON,0);
- return 0;
- }
-
- return 1;
-}
-int clif_autoshadowspell_list(struct map_session_data *sd)
-{
- int fd, i, c;
- nullpo_ret(sd);
- fd = sd->fd;
- if (!fd) return 0;
-
- if (sd->menuskill_id == SC_AUTOSHADOWSPELL)
- return 0;
-
- WFIFOHEAD(fd, 2 * 6 + 4);
- WFIFOW(fd,0) = 0x442;
- for (i = 0, c = 0; i < MAX_SKILL; i++)
- if (sd->status.skill[i].flag == SKILL_FLAG_PLAGIARIZED && sd->status.skill[i].id > 0 &&
- sd->status.skill[i].id < GS_GLITTERING && skill_get_type(sd->status.skill[i].id) == BF_MAGIC) {
- // Can't auto cast both Extended class and 3rd class skills.
- WFIFOW(fd,8+c*2) = sd->status.skill[i].id;
- c++;
- }
-
- if (c > 0) {
- WFIFOW(fd,2) = 8 + c * 2;
- WFIFOL(fd,4) = c;
- WFIFOSET(fd,WFIFOW(fd,2));
- sd->menuskill_id = SC_AUTOSHADOWSPELL;
- sd->menuskill_val = c;
- } else {
- status_change_end(&sd->bl,SC_STOP,INVALID_TIMER);
- clif_skill_fail(sd,SC_AUTOSHADOWSPELL,USESKILL_FAIL_IMITATION_SKILL_NONE,0);
- }
-
- return 1;
+int clif_poison_list(struct map_session_data *sd, int skill_lv) {
+ int i, c;
+ int fd;
+
+ nullpo_ret(sd);
+
+ fd = sd->fd;
+ WFIFOHEAD(fd, 8 * 8 + 8);
+ WFIFOW(fd,0) = 0x1ad; // This is the official packet. [pakpil]
+
+ for( i = 0, c = 0; i < MAX_INVENTORY; i ++ ) {
+ if( itemdb_is_poison(sd->status.inventory[i].nameid) ) {
+ WFIFOW(fd, c * 2 + 4) = sd->status.inventory[i].nameid;
+ c ++;
+ }
+ }
+ if( c > 0 ) {
+ sd->menuskill_id = GC_POISONINGWEAPON;
+ sd->menuskill_val = skill_lv;
+ WFIFOW(fd,2) = c * 2 + 4;
+ WFIFOSET(fd, WFIFOW(fd, 2));
+ } else {
+ clif_skill_fail(sd,GC_POISONINGWEAPON,USESKILL_FAIL_GUILLONTINE_POISON,0);
+ return 0;
+ }
+
+ return 1;
+}
+int clif_autoshadowspell_list(struct map_session_data *sd) {
+ int fd, i, c;
+ nullpo_ret(sd);
+ fd = sd->fd;
+ if( !fd ) return 0;
+
+ if( sd->menuskill_id == SC_AUTOSHADOWSPELL )
+ return 0;
+
+ WFIFOHEAD(fd, 2 * 6 + 4);
+ WFIFOW(fd,0) = 0x442;
+ for( i = 0, c = 0; i < MAX_SKILL; i++ )
+ if( sd->status.skill[i].flag == SKILL_FLAG_PLAGIARIZED && sd->status.skill[i].id > 0 &&
+ sd->status.skill[i].id < GS_GLITTERING && skill_get_type(sd->status.skill[i].id) == BF_MAGIC )
+ { // Can't auto cast both Extended class and 3rd class skills.
+ WFIFOW(fd,8+c*2) = sd->status.skill[i].id;
+ c++;
+ }
+
+ if( c > 0 ) {
+ WFIFOW(fd,2) = 8 + c * 2;
+ WFIFOL(fd,4) = c;
+ WFIFOSET(fd,WFIFOW(fd,2));
+ sd->menuskill_id = SC_AUTOSHADOWSPELL;
+ sd->menuskill_val = c;
+ } else {
+ status_change_end(&sd->bl,SC_STOP,INVALID_TIMER);
+ clif_skill_fail(sd,SC_AUTOSHADOWSPELL,USESKILL_FAIL_IMITATION_SKILL_NONE,0);
+ }
+
+ return 1;
}
/*===========================================
* Skill list for Four Elemental Analysis
* and Change Material skills.
*------------------------------------------*/
-int clif_skill_itemlistwindow(struct map_session_data *sd, int skill_id, int skill_lv)
+int clif_skill_itemlistwindow( struct map_session_data *sd, int skill_id, int skill_lv )
{
#if PACKETVER >= 20090922
- int fd;
+ int fd;
- nullpo_ret(sd);
+ nullpo_ret(sd);
- sd->menuskill_id = skill_id; // To prevent hacking.
- sd->menuskill_val = skill_lv;
+ sd->menuskill_id = skill_id; // To prevent hacking.
+ sd->menuskill_val = skill_lv;
- if (skill_id == GN_CHANGEMATERIAL)
- skill_lv = 0; // Changematerial
+ if( skill_id == GN_CHANGEMATERIAL )
+ skill_lv = 0; // Changematerial
- fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x7e3));
- WFIFOW(fd,0) = 0x7e3;
- WFIFOL(fd,2) = skill_lv;
- WFIFOL(fd,4) = 0;
- WFIFOSET(fd,packet_len(0x7e3));
+ fd = sd->fd;
+ WFIFOHEAD(fd,packet_len(0x7e3));
+ WFIFOW(fd,0) = 0x7e3;
+ WFIFOL(fd,2) = skill_lv;
+ WFIFOL(fd,4) = 0;
+ WFIFOSET(fd,packet_len(0x7e3));
#endif
- return 1;
+ return 1;
}
/**
* Sends a new status without a tick (currently used by the new mounts)
**/
-int clif_status_load_notick(struct block_list *bl,int type,int flag,int val1, int val2, int val3)
-{
- unsigned char buf[32];
+int clif_status_load_notick(struct block_list *bl,int type,int flag,int val1, int val2, int val3) {
+ unsigned char buf[32];
- nullpo_ret(bl);
+ nullpo_ret(bl);
- WBUFW(buf,0)=0x043f;
- WBUFW(buf,2)=type;
- WBUFL(buf,4)=bl->id;
- WBUFB(buf,8)=flag;
- WBUFL(buf,9) = 0;
- WBUFL(buf,13) = val1;
- WBUFL(buf,17) = val2;
- WBUFL(buf,21) = val3;
+ WBUFW(buf,0)=0x043f;
+ WBUFW(buf,2)=type;
+ WBUFL(buf,4)=bl->id;
+ WBUFB(buf,8)=flag;
+ WBUFL(buf,9) = 0;
+ WBUFL(buf,13) = val1;
+ WBUFL(buf,17) = val2;
+ WBUFL(buf,21) = val3;
- clif_send(buf,packet_len(0x043f),bl,AREA);
- return 0;
+ clif_send(buf,packet_len(0x043f),bl,AREA);
+ return 0;
}
//Notifies FD of ID's type
-int clif_status_load_single(int fd, int id,int type,int flag,int val1, int val2, int val3)
-{
- WFIFOHEAD(fd, packet_len(0x043f));
- WFIFOW(fd,0)=0x043f;
- WFIFOW(fd,2)=type;
- WFIFOL(fd,4)=id;
- WFIFOB(fd,8)=flag;
- WFIFOL(fd,9) = 0;
- WFIFOL(fd,13) = val1;
- WFIFOL(fd,17) = val2;
- WFIFOL(fd,21) = val3;
- WFIFOSET(fd, packet_len(0x043f));
- return 0;
+int clif_status_load_single(int fd, int id,int type,int flag,int val1, int val2, int val3) {
+ WFIFOHEAD(fd, packet_len(0x043f));
+ WFIFOW(fd,0)=0x043f;
+ WFIFOW(fd,2)=type;
+ WFIFOL(fd,4)=id;
+ WFIFOB(fd,8)=flag;
+ WFIFOL(fd,9) = 0;
+ WFIFOL(fd,13) = val1;
+ WFIFOL(fd,17) = val2;
+ WFIFOL(fd,21) = val3;
+ WFIFOSET(fd, packet_len(0x043f));
+ return 0;
}
// msgstringtable.txt
// 0x291 <line>.W
-void clif_msgtable(int fd, int line)
-{
- WFIFOHEAD(fd, packet_len(0x291));
- WFIFOW(fd, 0) = 0x291;
- WFIFOW(fd, 2) = line;
- WFIFOSET(fd, packet_len(0x291));
+void clif_msgtable(int fd, int line) {
+ WFIFOHEAD(fd, packet_len(0x291));
+ WFIFOW(fd, 0) = 0x291;
+ WFIFOW(fd, 2) = line;
+ WFIFOSET(fd, packet_len(0x291));
}
// msgstringtable.txt
// 0x7e2 <line>.W <value>.L
-void clif_msgtable_num(int fd, int line, int num)
-{
+void clif_msgtable_num(int fd, int line, int num) {
#if PACKETVER >= 20090805
- WFIFOHEAD(fd, packet_len(0x7e2));
- WFIFOW(fd, 0) = 0x7e2;
- WFIFOW(fd, 2) = line;
- WFIFOL(fd, 4) = num;
- WFIFOSET(fd, packet_len(0x7e2));
+ WFIFOHEAD(fd, packet_len(0x7e2));
+ WFIFOW(fd, 0) = 0x7e2;
+ WFIFOW(fd, 2) = line;
+ WFIFOL(fd, 4) = num;
+ WFIFOSET(fd, packet_len(0x7e2));
#endif
}
/*==========================================
* used by SC_AUTOSHADOWSPELL
* RFIFOL(fd,2) - flag (currently not used)
*------------------------------------------*/
-void clif_parse_SkillSelectMenu(int fd, struct map_session_data *sd)
-{
+void clif_parse_SkillSelectMenu(int fd, struct map_session_data *sd) {
- if (sd->menuskill_id != SC_AUTOSHADOWSPELL)
- return;
+ if( sd->menuskill_id != SC_AUTOSHADOWSPELL )
+ return;
- if (pc_istrading(sd)) {
- clif_skill_fail(sd,sd->ud.skillid,0,0);
- clif_menuskill_clear(sd);
- return;
- }
+ if( pc_istrading(sd) ) {
+ clif_skill_fail(sd,sd->ud.skillid,0,0);
+ clif_menuskill_clear(sd);
+ return;
+ }
- skill_select_menu(sd,RFIFOW(fd,6));
+ skill_select_menu(sd,RFIFOW(fd,6));
- clif_menuskill_clear(sd);
+ clif_menuskill_clear(sd);
}
/*==========================================
* Kagerou/Oboro amulet spirit
*------------------------------------------*/
void clif_talisman(struct map_session_data *sd,short type)
{
- unsigned char buf[10];
+ unsigned char buf[10];
- nullpo_retv(sd);
+ nullpo_retv(sd);
- WBUFW(buf,0)=0x08cf;
- WBUFL(buf,2)=sd->bl.id;
- WBUFW(buf,6)=type;
- WBUFW(buf,8)=sd->talisman[type];
- clif_send(buf,packet_len(0x08cf),&sd->bl,AREA);
+ WBUFW(buf,0)=0x08cf;
+ WBUFL(buf,2)=sd->bl.id;
+ WBUFW(buf,6)=type;
+ WBUFW(buf,8)=sd->talisman[type];
+ clif_send(buf,packet_len(0x08cf),&sd->bl,AREA);
}
/// Move Item from or to Personal Tab (CZ_WHATSOEVER) [FE]
/// 0907 <index>.W
///
/// R 0908 <index>.w <type>.b
/// type:
-/// 0 = move item to personal tab
-/// 1 = move item to normal tab
-void clif_parse_MoveItem(int fd, struct map_session_data *sd)
-{
+/// 0 = move item to personal tab
+/// 1 = move item to normal tab
+void clif_parse_MoveItem(int fd, struct map_session_data *sd) {
#if PACKETVER >= 20111122
- int index;
+ int index;
- /* can't move while dead. */
- if (pc_isdead(sd)) {
- return;
- }
+ /* can't move while dead. */
+ if(pc_isdead(sd)) {
+ return;
+ }
- index = RFIFOW(fd,2)-2;
+ index = RFIFOW(fd,2)-2;
- if (index < 0 || index >= MAX_INVENTORY)
- return;
+ if (index < 0 || index >= MAX_INVENTORY)
+ return;
- if (sd->status.inventory[index].favorite && RFIFOB(fd, 4) == 1)
- sd->status.inventory[index].favorite = 0;
- else if (RFIFOB(fd, 4) == 0)
- sd->status.inventory[index].favorite = 1;
- else
- return;/* nothing to do. */
+ if ( sd->status.inventory[index].favorite && RFIFOB(fd, 4) == 1 )
+ sd->status.inventory[index].favorite = 0;
+ else if( RFIFOB(fd, 4) == 0 )
+ sd->status.inventory[index].favorite = 1;
+ else
+ return;/* nothing to do. */
- clif_favorite_item(sd, index);
+ clif_favorite_item(sd, index);
#endif
}
/// Items that are in favorite tab of inventory (ZC_ITEM_FAVORITE).
/// 0900 <index>.W <favorite>.B
-void clif_favorite_item(struct map_session_data *sd, unsigned short index)
-{
- int fd = sd->fd;
+void clif_favorite_item(struct map_session_data* sd, unsigned short index) {
+ int fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x908));
- WFIFOW(fd,0) = 0x908;
- WFIFOW(fd,2) = index+2;
- WFIFOL(fd,4) = (sd->status.inventory[index].favorite == 1) ? 0 : 1;
- WFIFOSET(fd,packet_len(0x908));
+ WFIFOHEAD(fd,packet_len(0x908));
+ WFIFOW(fd,0) = 0x908;
+ WFIFOW(fd,2) = index+2;
+ WFIFOL(fd,4) = (sd->status.inventory[index].favorite == 1) ? 0 : 1;
+ WFIFOSET(fd,packet_len(0x908));
}
-void clif_snap(struct block_list *bl, short x, short y)
-{
- unsigned char buf[10];
+void clif_snap( struct block_list *bl, short x, short y ) {
+ unsigned char buf[10];
- WBUFW(buf,0) = 0x8d2;
- WBUFL(buf,2) = bl->id;
- WBUFW(buf,6) = x;
- WBUFW(buf,8) = y;
+ WBUFW(buf,0) = 0x8d2;
+ WBUFL(buf,2) = bl->id;
+ WBUFW(buf,6) = x;
+ WBUFW(buf,8) = y;
- clif_send(buf,packet_len(0x8d2),bl,AREA);
+ clif_send(buf,packet_len(0x8d2),bl,AREA);
}
-void clif_monster_hp_bar(struct mob_data *md, int fd)
-{
+void clif_monster_hp_bar( struct mob_data* md, int fd ) {
#if PACKETVER >= 20120404
- WFIFOHEAD(fd,packet_len(0x977));
+ WFIFOHEAD(fd,packet_len(0x977));
- WFIFOW(fd,0) = 0x977;
- WFIFOL(fd,2) = md->bl.id;
- WFIFOL(fd,6) = md->status.hp;
- WFIFOL(fd,10) = md->status.max_hp;
+ WFIFOW(fd,0) = 0x977;
+ WFIFOL(fd,2) = md->bl.id;
+ WFIFOL(fd,6) = md->status.hp;
+ WFIFOL(fd,10) = md->status.max_hp;
- WFIFOSET(fd,packet_len(0x977));
+ WFIFOSET(fd,packet_len(0x977));
#endif
}
@@ -16151,153 +16340,156 @@ void clif_monster_hp_bar(struct mob_data *md, int fd)
*------------------------------------------*/
static int clif_parse(int fd)
{
- int cmd, packet_ver, packet_len, err;
- TBL_PC *sd;
- int pnum;
-
- //TODO apply delays or disconnect based on packet throughput [FlavioJS]
- // Note: "click masters" can do 80+ clicks in 10 seconds
-
- for (pnum = 0; pnum < 3; ++pnum) { // Limit max packets per cycle to 3 (delay packet spammers) [FlavioJS] -- This actually aids packet spammers, but stuff like /str+ gets slow without it [Ai4rei]
- // begin main client packet processing loop
-
- sd = (TBL_PC *)session[fd]->session_data;
- if (session[fd]->flag.eof) {
- if (sd) {
- if (sd->state.autotrade) {
- //Disassociate character from the socket connection.
- session[fd]->session_data = NULL;
- sd->fd = 0;
- ShowInfo("Character '"CL_WHITE"%s"CL_RESET"' logged off (using @autotrade).\n", sd->status.name);
- } else if (sd->state.active) {
- // Player logout display [Valaris]
- ShowInfo("Character '"CL_WHITE"%s"CL_RESET"' logged off.\n", sd->status.name);
- clif_quitsave(fd, sd);
- } else {
- //Unusual logout (during log on/off/map-changer procedure)
- ShowInfo("Player AID:%d/CID:%d logged off.\n", sd->status.account_id, sd->status.char_id);
- map_quit(sd);
- }
- } else {
- ShowInfo("Closed connection from '"CL_WHITE"%s"CL_RESET"'.\n", ip2str(session[fd]->client_addr, NULL));
- }
- do_close(fd);
- return 0;
- }
-
- if (RFIFOREST(fd) < 2)
- return 0;
-
- cmd = RFIFOW(fd,0);
-
- // identify client's packet version
- if (sd) {
- packet_ver = sd->packet_ver;
- } else {
- // check authentification packet to know packet version
- packet_ver = clif_guess_PacketVer(fd, 0, &err);
- if (err) { // failed to identify packet version
- ShowInfo("clif_parse: Disconnecting session #%d with unknown packet version%s (p:0x%04x,l:%d).\n", fd, (
- err == 1 ? "" :
- err == 2 ? ", possibly for having an invalid account_id" :
- err == 3 ? ", possibly for having an invalid char_id." :
- /* Uncomment when checks are added in clif_guess_PacketVer. [FlavioJS]
- err == 4 ? ", possibly for having an invalid login_id1." :
- err == 5 ? ", possibly for having an invalid client_tick." :
- */
- err == 6 ? ", possibly for having an invalid sex." :
- ". ERROR invalid error code"), cmd, RFIFOREST(fd));
- WFIFOHEAD(fd,packet_len(0x6a));
- WFIFOW(fd,0) = 0x6a;
- WFIFOB(fd,2) = 3; // Rejected from Server
- WFIFOSET(fd,packet_len(0x6a));
+ int cmd, packet_ver, packet_len, err;
+ TBL_PC* sd;
+ int pnum;
+
+ //TODO apply delays or disconnect based on packet throughput [FlavioJS]
+ // Note: "click masters" can do 80+ clicks in 10 seconds
+
+ for( pnum = 0; pnum < 3; ++pnum )// Limit max packets per cycle to 3 (delay packet spammers) [FlavioJS] -- This actually aids packet spammers, but stuff like /str+ gets slow without it [Ai4rei]
+ { // begin main client packet processing loop
+
+ sd = (TBL_PC *)session[fd]->session_data;
+ if (session[fd]->flag.eof) {
+ if (sd) {
+ if (sd->state.autotrade) {
+ //Disassociate character from the socket connection.
+ session[fd]->session_data = NULL;
+ sd->fd = 0;
+ ShowInfo("Character '"CL_WHITE"%s"CL_RESET"' logged off (using @autotrade).\n", sd->status.name);
+ } else
+ if (sd->state.active) {
+ // Player logout display [Valaris]
+ ShowInfo("Character '"CL_WHITE"%s"CL_RESET"' logged off.\n", sd->status.name);
+ clif_quitsave(fd, sd);
+ } else {
+ //Unusual logout (during log on/off/map-changer procedure)
+ ShowInfo("Player AID:%d/CID:%d logged off.\n", sd->status.account_id, sd->status.char_id);
+ map_quit(sd);
+ }
+ } else {
+ ShowInfo("Closed connection from '"CL_WHITE"%s"CL_RESET"'.\n", ip2str(session[fd]->client_addr, NULL));
+ }
+ do_close(fd);
+ return 0;
+ }
+
+ if (RFIFOREST(fd) < 2)
+ return 0;
+
+ cmd = RFIFOW(fd,0);
+
+ // identify client's packet version
+ if (sd) {
+ packet_ver = sd->packet_ver;
+ } else {
+ // check authentification packet to know packet version
+ packet_ver = clif_guess_PacketVer(fd, 0, &err);
+ if( err ) {// failed to identify packet version
+ ShowInfo("clif_parse: Disconnecting session #%d with unknown packet version%s (p:0x%04x,l:%d).\n", fd, (
+ err == 1 ? "" :
+ err == 2 ? ", possibly for having an invalid account_id" :
+ err == 3 ? ", possibly for having an invalid char_id." :
+ /* Uncomment when checks are added in clif_guess_PacketVer. [FlavioJS]
+ err == 4 ? ", possibly for having an invalid login_id1." :
+ err == 5 ? ", possibly for having an invalid client_tick." :
+ */
+ err == 6 ? ", possibly for having an invalid sex." :
+ ". ERROR invalid error code"), cmd, RFIFOREST(fd));
+ WFIFOHEAD(fd,packet_len(0x6a));
+ WFIFOW(fd,0) = 0x6a;
+ WFIFOB(fd,2) = 3; // Rejected from Server
+ WFIFOSET(fd,packet_len(0x6a));
#ifdef DUMP_INVALID_PACKET
- ShowDump(RFIFOP(fd,0), RFIFOREST(fd));
+ ShowDump(RFIFOP(fd,0), RFIFOREST(fd));
#endif
- RFIFOSKIP(fd, RFIFOREST(fd));
- set_eof(fd);
- return 0;
- }
- }
+ RFIFOSKIP(fd, RFIFOREST(fd));
+ set_eof(fd);
+ return 0;
+ }
+ }
- // filter out invalid / unsupported packets
- if (cmd > MAX_PACKET_DB || packet_db[packet_ver][cmd].len == 0) {
- ShowWarning("clif_parse: Received unsupported packet (packet 0x%04x, %d bytes received), disconnecting session #%d.\n", cmd, RFIFOREST(fd), fd);
+ // filter out invalid / unsupported packets
+ if (cmd > MAX_PACKET_DB || packet_db[packet_ver][cmd].len == 0) {
+ ShowWarning("clif_parse: Received unsupported packet (packet 0x%04x, %d bytes received), disconnecting session #%d.\n", cmd, RFIFOREST(fd), fd);
#ifdef DUMP_INVALID_PACKET
- ShowDump(RFIFOP(fd,0), RFIFOREST(fd));
+ ShowDump(RFIFOP(fd,0), RFIFOREST(fd));
#endif
- set_eof(fd);
- return 0;
- }
-
- // determine real packet length
- packet_len = packet_db[packet_ver][cmd].len;
- if (packet_len == -1) { // variable-length packet
- if (RFIFOREST(fd) < 4)
- return 0;
-
- packet_len = RFIFOW(fd,2);
- if (packet_len < 4 || packet_len > 32768) {
- ShowWarning("clif_parse: Received packet 0x%04x specifies invalid packet_len (%d), disconnecting session #%d.\n", cmd, packet_len, fd);
+ set_eof(fd);
+ return 0;
+ }
+
+ // determine real packet length
+ packet_len = packet_db[packet_ver][cmd].len;
+ if (packet_len == -1) { // variable-length packet
+ if (RFIFOREST(fd) < 4)
+ return 0;
+
+ packet_len = RFIFOW(fd,2);
+ if (packet_len < 4 || packet_len > 32768) {
+ ShowWarning("clif_parse: Received packet 0x%04x specifies invalid packet_len (%d), disconnecting session #%d.\n", cmd, packet_len, fd);
#ifdef DUMP_INVALID_PACKET
- ShowDump(RFIFOP(fd,0), RFIFOREST(fd));
+ ShowDump(RFIFOP(fd,0), RFIFOREST(fd));
#endif
- set_eof(fd);
- return 0;
- }
- }
- if ((int)RFIFOREST(fd) < packet_len)
- return 0; // not enough data received to form the packet
-
- if (packet_db[packet_ver][cmd].func == clif_parse_debug)
- packet_db[packet_ver][cmd].func(fd, sd);
- else if (packet_db[packet_ver][cmd].func != NULL) {
- if (!sd && packet_db[packet_ver][cmd].func != clif_parse_WantToConnection)
- ; //Only valid packet when there is no session
- else if (sd && sd->bl.prev == NULL && packet_db[packet_ver][cmd].func != clif_parse_LoadEndAck)
- ; //Only valid packet when player is not on a map
- else if (sd && session[sd->fd]->flag.eof)
- ; //No more packets accepted
- else
- packet_db[packet_ver][cmd].func(fd, sd);
- }
+ set_eof(fd);
+ return 0;
+ }
+ }
+ if ((int)RFIFOREST(fd) < packet_len)
+ return 0; // not enough data received to form the packet
+
+ if( packet_db[packet_ver][cmd].func == clif_parse_debug )
+ packet_db[packet_ver][cmd].func(fd, sd);
+ else if( packet_db[packet_ver][cmd].func != NULL ) {
+ if( !sd && packet_db[packet_ver][cmd].func != clif_parse_WantToConnection )
+ ; //Only valid packet when there is no session
+ else
+ if( sd && sd->bl.prev == NULL && packet_db[packet_ver][cmd].func != clif_parse_LoadEndAck )
+ ; //Only valid packet when player is not on a map
+ else
+ if( sd && session[sd->fd]->flag.eof )
+ ; //No more packets accepted
+ else
+ packet_db[packet_ver][cmd].func(fd, sd);
+ }
#ifdef DUMP_UNKNOWN_PACKET
- else {
- const char *packet_txt = "save/packet.txt";
- FILE *fp;
-
- if ((fp = fopen(packet_txt , "a")) != NULL) {
- if (sd) {
- fprintf(fp, "Unknown packet 0x%04X (length %d), %s session #%d, %d/%d (AID/CID)\n", cmd, packet_len, sd->state.active ? "authed" : "unauthed", fd, sd->status.account_id, sd->status.char_id);
- } else {
- fprintf(fp, "Unknown packet 0x%04X (length %d), session #%d\n", cmd, packet_len, fd);
- }
-
- WriteDump(fp, RFIFOP(fd,0), packet_len);
- fprintf(fp, "\n");
- fclose(fp);
- } else {
- ShowError("Failed to write '%s'.\n", packet_txt);
-
- // Dump on console instead
- if (sd) {
- ShowDebug("Unknown packet 0x%04X (length %d), %s session #%d, %d/%d (AID/CID)\n", cmd, packet_len, sd->state.active ? "authed" : "unauthed", fd, sd->status.account_id, sd->status.char_id);
- } else {
- ShowDebug("Unknown packet 0x%04X (length %d), session #%d\n", cmd, packet_len, fd);
- }
-
- ShowDump(RFIFOP(fd,0), packet_len);
- }
- }
+ else {
+ const char* packet_txt = "save/packet.txt";
+ FILE* fp;
+
+ if( ( fp = fopen( packet_txt , "a" ) ) != NULL ) {
+ if( sd ) {
+ fprintf(fp, "Unknown packet 0x%04X (length %d), %s session #%d, %d/%d (AID/CID)\n", cmd, packet_len, sd->state.active ? "authed" : "unauthed", fd, sd->status.account_id, sd->status.char_id);
+ } else {
+ fprintf(fp, "Unknown packet 0x%04X (length %d), session #%d\n", cmd, packet_len, fd);
+ }
+
+ WriteDump(fp, RFIFOP(fd,0), packet_len);
+ fprintf(fp, "\n");
+ fclose(fp);
+ } else {
+ ShowError("Failed to write '%s'.\n", packet_txt);
+
+ // Dump on console instead
+ if( sd ) {
+ ShowDebug("Unknown packet 0x%04X (length %d), %s session #%d, %d/%d (AID/CID)\n", cmd, packet_len, sd->state.active ? "authed" : "unauthed", fd, sd->status.account_id, sd->status.char_id);
+ } else {
+ ShowDebug("Unknown packet 0x%04X (length %d), session #%d\n", cmd, packet_len, fd);
+ }
+
+ ShowDump(RFIFOP(fd,0), packet_len);
+ }
+ }
#endif
- RFIFOSKIP(fd, packet_len);
+ RFIFOSKIP(fd, packet_len);
- }; // main loop end
+ }; // main loop end
- return 0;
+ return 0;
}
/*==========================================
@@ -16305,620 +16497,628 @@ static int clif_parse(int fd)
*------------------------------------------*/
static int packetdb_readdb(void)
{
- FILE *fp;
- char line[1024];
- int ln=0;
- int cmd,i,j,packet_ver;
- int max_cmd=-1;
- int skip_ver = 0;
- int warned = 0;
- char *str[64],*p,*str2[64],*p2,w1[64],w2[64];
- 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,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- //#0x0040
- 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,
+ FILE *fp;
+ char line[1024];
+ int ln=0;
+ int cmd,i,j,packet_ver;
+ int max_cmd=-1;
+ int skip_ver = 0;
+ int warned = 0;
+ char *str[64],*p,*str2[64],*p2,w1[64],w2[64];
+ 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,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ //#0x0040
+ 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,
#if PACKETVER <= 20081217
- 0, 0, 0, 0, 55, 17, 3, 37, 46, -1, 23, -1, 3,110, 3, 2,
+ 0, 0, 0, 0, 55, 17, 3, 37, 46, -1, 23, -1, 3,110, 3, 2,
#else
- 0, 0, 0, 0, 55, 17, 3, 37, 46, -1, 23, -1, 3,114, 3, 2,
+ 0, 0, 0, 0, 55, 17, 3, 37, 46, -1, 23, -1, 3,114, 3, 2,
#endif
#if PACKETVER < 2
- 3, 28, 19, 11, 3, -1, 9, 5, 52, 51, 56, 58, 41, 2, 6, 6,
-#elif PACKETVER < 20071106 // 78-7b Lv99 effect for later Kameshima
- 3, 28, 19, 11, 3, -1, 9, 5, 54, 53, 58, 60, 41, 2, 6, 6,
+ 3, 28, 19, 11, 3, -1, 9, 5, 52, 51, 56, 58, 41, 2, 6, 6,
+#elif PACKETVER < 20071106 // 78-7b Lv99 effect for later Kameshima
+ 3, 28, 19, 11, 3, -1, 9, 5, 54, 53, 58, 60, 41, 2, 6, 6,
#elif PACKETVER <= 20081217 // change in 0x78 and 0x7c
- 3, 28, 19, 11, 3, -1, 9, 5, 55, 53, 58, 60, 42, 2, 6, 6,
+ 3, 28, 19, 11, 3, -1, 9, 5, 55, 53, 58, 60, 42, 2, 6, 6,
#else
- 3, 28, 19, 11, 3, -1, 9, 5, 55, 53, 58, 60, 44, 2, 6, 6,
+ 3, 28, 19, 11, 3, -1, 9, 5, 55, 53, 58, 60, 44, 2, 6, 6,
#endif
- //#0x0080
- 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,
+ //#0x0080
+ 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,
#if PACKETVER <= 20100622
- 23, 6, 6, -1, -1, -1, -1, 8, 7, 6, 7, 4, 7, 0, -1, 6,
+ 23, 6, 6, -1, -1, -1, -1, 8, 7, 6, 7, 4, 7, 0, -1, 6,
#else
- 23, 6, 6, -1, -1, -1, -1, 8, 7, 6, 9, 4, 7, 0, -1, 6, // 0xaa changed to 9 (was 7)
+ 23, 6, 6, -1, -1, -1, -1, 8, 7, 6, 9, 4, 7, 0, -1, 6, // 0xaa changed to 9 (was 7)
#endif
- 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, 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,
- //#0x0100
- 2, 6, 6, 30, 79, 31, 10, 10, -1, -1, 4, 6, 6, 2, 11, -1,
- 10, 39, 4, 10, 31, 35, 10, 18, 2, 13, 15, 20, 68, 2, 3, 16,
- 6, 14, -1, -1, 21, 8, 8, 8, 8, 8, 2, 2, 3, 4, 2, -1,
- 6, 86, 6, -1, -1, 7, -1, 6, 3, 16, 4, 4, 4, 6, 24, 26,
- //#0x0140
- 22, 14, 6, 10, 23, 19, 6, 39, 8, 9, 6, 27, -1, 2, 6, 6,
- 110, 6, -1, -1, -1, -1, -1, 6, -1, 54, 66, 54, 90, 42, 6, 42,
- -1, -1, -1, -1, -1, 30, -1, 3, 14, 3, 30, 10, 43, 14,186,182,
- 14, 30, 10, 3, -1, 6,106, -1, 4, 5, 4, -1, 6, 7, -1, -1,
- //#0x0180
- 6, 3,106, 10, 10, 34, 0, 6, 8, 4, 4, 4, 29, -1, 10, 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, 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,
+ //#0x0100
+ 2, 6, 6, 30, 79, 31, 10, 10, -1, -1, 4, 6, 6, 2, 11, -1,
+ 10, 39, 4, 10, 31, 35, 10, 18, 2, 13, 15, 20, 68, 2, 3, 16,
+ 6, 14, -1, -1, 21, 8, 8, 8, 8, 8, 2, 2, 3, 4, 2, -1,
+ 6, 86, 6, -1, -1, 7, -1, 6, 3, 16, 4, 4, 4, 6, 24, 26,
+ //#0x0140
+ 22, 14, 6, 10, 23, 19, 6, 39, 8, 9, 6, 27, -1, 2, 6, 6,
+ 110, 6, -1, -1, -1, -1, -1, 6, -1, 54, 66, 54, 90, 42, 6, 42,
+ -1, -1, -1, -1, -1, 30, -1, 3, 14, 3, 30, 10, 43, 14,186,182,
+ 14, 30, 10, 3, -1, 6,106, -1, 4, 5, 4, -1, 6, 7, -1, -1,
+ //#0x0180
+ 6, 3,106, 10, 10, 34, 0, 6, 8, 4, 4, 4, 29, -1, 10, 6,
#if PACKETVER < 1
- 90, 86, 24, 6, 30,102, 8, 4, 8, 4, 14, 10, -1, 6, 2, 6,
-#else // 196 comodo icon status display for later
- 90, 86, 24, 6, 30,102, 9, 4, 8, 4, 14, 10, -1, 6, 2, 6,
+ 90, 86, 24, 6, 30,102, 8, 4, 8, 4, 14, 10, -1, 6, 2, 6,
+#else // 196 comodo icon status display for later
+ 90, 86, 24, 6, 30,102, 9, 4, 8, 4, 14, 10, -1, 6, 2, 6,
#endif
#if PACKETVER < 20081126
- 3, 3, 35, 5, 11, 26, -1, 4, 4, 6, 10, 12, 6, -1, 4, 4,
+ 3, 3, 35, 5, 11, 26, -1, 4, 4, 6, 10, 12, 6, -1, 4, 4,
#else // 0x1a2 changed (35->37)
- 3, 3, 37, 5, 11, 26, -1, 4, 4, 6, 10, 12, 6, -1, 4, 4,
+ 3, 3, 37, 5, 11, 26, -1, 4, 4, 6, 10, 12, 6, -1, 4, 4,
#endif
- 11, 7, -1, 67, 12, 18,114, 6, 3, 6, 26, 26, 26, 26, 2, 3,
- //#0x01C0, Set 0x1d5=-1
- 2, 14, 10, -1, 22, 22, 4, 2, 13, 97, 3, 9, 9, 30, 6, 28,
- 8, 14, 10, 35, 6, -1, 4, 11, 54, 53, 60, 2, -1, 47, 33, 6,
- 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,
- //#0x0200
- 26, -1, 26, 10, 18, 26, 11, 34, 14, 36, 10, 0, 0, -1, 32, 10, // 0x20c change to 0 (was 19)
- 22, 0, 26, 26, 42, 6, 6, 2, 2,282,282, 10, 10, -1, -1, 66,
+ 11, 7, -1, 67, 12, 18,114, 6, 3, 6, 26, 26, 26, 26, 2, 3,
+ //#0x01C0, Set 0x1d5=-1
+ 2, 14, 10, -1, 22, 22, 4, 2, 13, 97, 3, 9, 9, 30, 6, 28,
+ 8, 14, 10, 35, 6, -1, 4, 11, 54, 53, 60, 2, -1, 47, 33, 6,
+ 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,
+ //#0x0200
+ 26, -1, 26, 10, 18, 26, 11, 34, 14, 36, 10, 0, 0, -1, 32, 10, // 0x20c change to 0 (was 19)
+ 22, 0, 26, 26, 42, 6, 6, 2, 2,282,282, 10, 10, -1, -1, 66,
#if PACKETVER < 20071106
- 10, -1, -1, 8, 10, 2,282, 18, 18, 15, 58, 57, 64, 5, 71, 5,
+ 10, -1, -1, 8, 10, 2,282, 18, 18, 15, 58, 57, 64, 5, 71, 5,
#else // 0x22c changed
- 10, -1, -1, 8, 10, 2,282, 18, 18, 15, 58, 57, 65, 5, 71, 5,
+ 10, -1, -1, 8, 10, 2,282, 18, 18, 15, 58, 57, 65, 5, 71, 5,
#endif
- 12, 26, 9, 11, -1, -1, 10, 2,282, 11, 4, 36, 6, -1, 4, 2,
- //#0x0240
- -1, -1, -1, -1, -1, 3, 4, 8, -1, 3, 70, 4, 8, 12, 4, 10,
- 3, 32, -1, 3, 3, 5, 5, 8, 2, 3, -1, 6, 4, 6, 4, 6,
- 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- //#0x0280
+ 12, 26, 9, 11, -1, -1, 10, 2,282, 11, 4, 36, 6, -1, 4, 2,
+ //#0x0240
+ -1, -1, -1, -1, -1, 3, 4, 8, -1, 3, 70, 4, 8, 12, 4, 10,
+ 3, 32, -1, 3, 3, 5, 5, 8, 2, 3, -1, 6, 4, 6, 4, 6,
+ 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ //#0x0280
#if PACKETVER < 20070711
- 0, 0, 0, 6, 14, 0, 0, -1, 6, 8, 18, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 14, 0, 0, -1, 6, 8, 18, 0, 0, 0, 0, 0,
#else
- 0, 0, 0, 6, 14, 0, 0, -1, 10, 12, 18, 0, 0, 0, 0, 0, // 0x288, 0x289 increase by 4 (kafra points)
+ 0, 0, 0, 6, 14, 0, 0, -1, 10, 12, 18, 0, 0, 0, 0, 0, // 0x288, 0x289 increase by 4 (kafra points)
#endif
- 0, 4, 0, 70, 10, 0, 0, 0, 8, 6, 27, 80, 0, -1, 0, 0,
- 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 85, -1, -1,107, 6, -1, 7, 7, 22,191, 0, 8, 0, 0, 0, 0,
- //#0x02C0
- 0, -1, 0, 0, 0, 30, 30, 0, 0, 3, 0, 65, 4, 71, 10, 0,
- -1, -1, -1, 0, 29, 0, 6, -1, 10, 10, 3, 0, -1, 32, 6, 36,
- 34, 33, 0, 0, 0, 0, 0, 0, -1, -1, -1, 13, 67, 59, 60, 8,
- 10, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- //#0x0300
- 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, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- //#0x0340
- 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, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- //#0x0380
- 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, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- //#0x03C0
- 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, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- //#0x0400
- 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, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 25,
- //#0x0440
- 10, 4, -1, 0, 0, 0, 14, 0, 0, 0, 6, 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, 0, 0, 0, 0, 0, 0,
- //#0x0480
- 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, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- //#0x04C0
- 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, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- //#0x0500
- 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, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25,
- //#0x0540
- 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, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- //#0x0580
- 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, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- //#0x05C0
- 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, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- //#0x0600
- 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, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25,
- //#0x0640
- 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, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- //#0x0680
- 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, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- //#0x06C0
- 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, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- //#0x0700
- 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, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25,
- //#0x0740
- 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, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- //#0x0780
- 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, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- //#0x07C0
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 4, 0, 70, 10, 0, 0, 0, 8, 6, 27, 80, 0, -1, 0, 0,
+ 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 85, -1, -1,107, 6, -1, 7, 7, 22,191, 0, 8, 0, 0, 0, 0,
+ //#0x02C0
+ 0, -1, 0, 0, 0, 30, 30, 0, 0, 3, 0, 65, 4, 71, 10, 0,
+ -1, -1, -1, 0, 29, 0, 6, -1, 10, 10, 3, 0, -1, 32, 6, 36,
+ 34, 33, 0, 0, 0, 0, 0, 0, -1, -1, -1, 13, 67, 59, 60, 8,
+ 10, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ //#0x0300
+ 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, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ //#0x0340
+ 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, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ //#0x0380
+ 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, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ //#0x03C0
+ 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, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ //#0x0400
+ 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, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 25,
+ //#0x0440
+ 10, 4, -1, 0, 0, 0, 14, 0, 0, 0, 6, 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, 0, 0, 0, 0, 0, 0,
+ //#0x0480
+ 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, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ //#0x04C0
+ 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, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ //#0x0500
+ 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, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25,
+ //#0x0540
+ 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, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ //#0x0580
+ 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, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ //#0x05C0
+ 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, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ //#0x0600
+ 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, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25,
+ //#0x0640
+ 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, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ //#0x0680
+ 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, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ //#0x06C0
+ 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, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ //#0x0700
+ 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, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25,
+ //#0x0740
+ 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, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ //#0x0780
+ 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, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ //#0x07C0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
#if PACKETVER < 20090617
- 6, 2, -1, 4, 4, 4, 4, 8, 8,254, 6, 8, 6, 54, 30, 54,
+ 6, 2, -1, 4, 4, 4, 4, 8, 8,254, 6, 8, 6, 54, 30, 54,
#else // 0x7d9 changed
- 6, 2, -1, 4, 4, 4, 4, 8, 8,268, 6, 8, 6, 54, 30, 54,
+ 6, 2, -1, 4, 4, 4, 4, 8, 8,268, 6, 8, 6, 54, 30, 54,
#endif
- 0, 15, 8, 6, -1, 8, 8, 32, -1, 5, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 14, -1, -1, -1, 8, 25, 0, 0, 26, 0,
- //#0x0800
+ 0, 15, 8, 6, -1, 8, 8, 32, -1, 5, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 14, -1, -1, -1, 8, 25, 0, 0, 26, 0,
+ //#0x0800
#if PACKETVER < 20091229
- -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 20,
+ -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 20,
#else // for Party booking ( PACKETVER >= 20091229 )
- -1, -1, 18, 4, 8, 6, 2, 4, 14, 50, 18, 6, 2, 3, 14, 20,
+ -1, -1, 18, 4, 8, 6, 2, 4, 14, 50, 18, 6, 2, 3, 14, 20,
#endif
- 3, -1, 8, -1, 86, 2, 6, 6, -1, -1, 4, 10, 10, 0, 0, 0,
- 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, -1, -1, 3, 2, 66, 5, 2, 12, 6, 0, 0,
- //#0x0840
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, 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,
- //#0x0880
- 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, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- //#0x08C0
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,
- 0, 0, 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,
- //#0x0900
- 0, 0, 0, 0, 0, 0, 0, 0, 5, 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, 0, 0, 0, 0, 0, 0, 0, 0,
- //#0x0940
- 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, 0,
- 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0,
-
- };
- 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_WisMessage,"wis"},
- {clif_parse_Broadcast,"broadcast"},
- {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_UseSkillToPosMoreInfo,"useskilltoposinfo"},
- {clif_parse_UseSkillMap,"useskillmap"},
- {clif_parse_RequestMemo,"requestmemo"},
- {clif_parse_ProduceMix,"producemix"},
- {clif_parse_Cooking,"cooking"},
- {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_RepairItem,"repairitem"},
- {clif_parse_WeaponRefine,"weaponrefine"},
- {clif_parse_SolveCharName,"solvecharname"},
- {clif_parse_ResetChar,"resetchar"},
- {clif_parse_LocalBroadcast,"localbroadcast"},
- {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_PartyInvite2,"partyinvite2"},
- {clif_parse_ReplyPartyInvite,"replypartyinvite"},
- {clif_parse_ReplyPartyInvite2,"replypartyinvite2"},
- {clif_parse_LeaveParty,"leaveparty"},
- {clif_parse_RemovePartyMember,"removepartymember"},
- {clif_parse_PartyChangeOption,"partychangeoption"},
- {clif_parse_PartyMessage,"partymessage"},
- {clif_parse_PartyChangeLeader,"partychangeleader"},
- {clif_parse_CloseVending,"closevending"},
- {clif_parse_VendingListReq,"vendinglistreq"},
- {clif_parse_PurchaseReq,"purchasereq"},
- {clif_parse_PurchaseReq2,"purchasereq2"},
- {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_GuildExpulsion,"guildexpulsion"},
- {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_GMReqAccountName,"gmreqaccname"},
- {clif_parse_GMKickAll,"killall"},
- {clif_parse_GMRecall,"recall"},
- {clif_parse_GMRecall,"summon"},
- {clif_parse_GM_Monster_Item,"itemmonster"},
- {clif_parse_GMShift,"remove"},
- {clif_parse_GMShift,"shift"},
- {clif_parse_GMChangeMapType,"changemaptype"},
- {clif_parse_GMRc,"rc"},
- {clif_parse_GMRecall2,"recall2"},
- {clif_parse_GMRemove2,"remove2"},
-
- {clif_parse_NoviceDoriDori,"sndoridori"},
- {clif_parse_NoviceExplosionSpirits,"snexplosionspirits"},
- {clif_parse_PMIgnore,"wisexin"},
- {clif_parse_PMIgnoreList,"wisexlist"},
- {clif_parse_PMIgnoreAll,"wisall"},
- {clif_parse_FriendsListAdd,"friendslistadd"},
- {clif_parse_FriendsListRemove,"friendslistremove"},
- {clif_parse_FriendsListReply,"friendslistreply"},
- {clif_parse_Blacksmith,"blacksmith"},
- {clif_parse_Alchemist,"alchemist"},
- {clif_parse_Taekwon,"taekwon"},
- {clif_parse_RankingPk,"rankingpk"},
- {clif_parse_FeelSaveOk,"feelsaveok"},
- {clif_parse_debug,"debug"},
- {clif_parse_ChangeHomunculusName,"changehomunculusname"},
- {clif_parse_HomMoveToMaster,"hommovetomaster"},
- {clif_parse_HomMoveTo,"hommoveto"},
- {clif_parse_HomAttack,"homattack"},
- {clif_parse_HomMenu,"hommenu"},
- {clif_parse_StoragePassword,"storagepassword"},
- {clif_parse_Hotkey,"hotkey"},
- {clif_parse_AutoRevive,"autorevive"},
- {clif_parse_Check,"check"},
- {clif_parse_Adopt_request,"adoptrequest"},
- {clif_parse_Adopt_reply,"adoptreply"},
- // MAIL SYSTEM
- {clif_parse_Mail_refreshinbox,"mailrefresh"},
- {clif_parse_Mail_read,"mailread"},
- {clif_parse_Mail_getattach,"mailgetattach"},
- {clif_parse_Mail_delete,"maildelete"},
- {clif_parse_Mail_return,"mailreturn"},
- {clif_parse_Mail_setattach,"mailsetattach"},
- {clif_parse_Mail_winopen,"mailwinopen"},
- {clif_parse_Mail_send,"mailsend"},
- // AUCTION SYSTEM
- {clif_parse_Auction_search,"auctionsearch"},
- {clif_parse_Auction_buysell,"auctionbuysell"},
- {clif_parse_Auction_setitem,"auctionsetitem"},
- {clif_parse_Auction_cancelreg,"auctioncancelreg"},
- {clif_parse_Auction_register,"auctionregister"},
- {clif_parse_Auction_cancel,"auctioncancel"},
- {clif_parse_Auction_close,"auctionclose"},
- {clif_parse_Auction_bid,"auctionbid"},
- // Quest Log System
- {clif_parse_questStateAck,"queststate"},
- {clif_parse_cashshop_buy,"cashshopbuy"},
- {clif_parse_ViewPlayerEquip,"viewplayerequip"},
- {clif_parse_EquipTick,"equiptickbox"},
- {clif_parse_BattleChat,"battlechat"},
- {clif_parse_mercenary_action,"mermenu"},
- {clif_parse_progressbar,"progressbar"},
- {clif_parse_SkillSelectMenu,"skillselectmenu"},
- {clif_parse_ItemListWindowSelected,"itemlistwindowselected"},
+ 3, -1, 8, -1, 86, 2, 6, 6, -1, -1, 4, 10, 10, 0, 0, 0,
+ 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, -1, -1, 3, 2, 66, 5, 2, 12, 6, 0, 0,
+ //#0x0840
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, 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,
+ //#0x0880
+ 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, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ //#0x08C0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,
+ 0, 0, 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,
+ //#0x0900
+ 0, 0, 0, 0, 0, 0, 0, 0, 5, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ //#0x0940
+ 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, 0,
+ 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ };
+ 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_WisMessage,"wis"},
+ {clif_parse_Broadcast,"broadcast"},
+ {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_UseSkillToPosMoreInfo,"useskilltoposinfo"},
+ {clif_parse_UseSkillMap,"useskillmap"},
+ {clif_parse_RequestMemo,"requestmemo"},
+ {clif_parse_ProduceMix,"producemix"},
+ {clif_parse_Cooking,"cooking"},
+ {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_RepairItem,"repairitem"},
+ {clif_parse_WeaponRefine,"weaponrefine"},
+ {clif_parse_SolveCharName,"solvecharname"},
+ {clif_parse_ResetChar,"resetchar"},
+ {clif_parse_LocalBroadcast,"localbroadcast"},
+ {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_PartyInvite2,"partyinvite2"},
+ {clif_parse_ReplyPartyInvite,"replypartyinvite"},
+ {clif_parse_ReplyPartyInvite2,"replypartyinvite2"},
+ {clif_parse_LeaveParty,"leaveparty"},
+ {clif_parse_RemovePartyMember,"removepartymember"},
+ {clif_parse_PartyChangeOption,"partychangeoption"},
+ {clif_parse_PartyMessage,"partymessage"},
+ {clif_parse_PartyChangeLeader,"partychangeleader"},
+ {clif_parse_CloseVending,"closevending"},
+ {clif_parse_VendingListReq,"vendinglistreq"},
+ {clif_parse_PurchaseReq,"purchasereq"},
+ {clif_parse_PurchaseReq2,"purchasereq2"},
+ {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_GuildExpulsion,"guildexpulsion"},
+ {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_GMReqAccountName,"gmreqaccname"},
+ {clif_parse_GMKickAll,"killall"},
+ {clif_parse_GMRecall,"recall"},
+ {clif_parse_GMRecall,"summon"},
+ {clif_parse_GM_Monster_Item,"itemmonster"},
+ {clif_parse_GMShift,"remove"},
+ {clif_parse_GMShift,"shift"},
+ {clif_parse_GMChangeMapType,"changemaptype"},
+ {clif_parse_GMRc,"rc"},
+ {clif_parse_GMRecall2,"recall2"},
+ {clif_parse_GMRemove2,"remove2"},
+
+ {clif_parse_NoviceDoriDori,"sndoridori"},
+ {clif_parse_NoviceExplosionSpirits,"snexplosionspirits"},
+ {clif_parse_PMIgnore,"wisexin"},
+ {clif_parse_PMIgnoreList,"wisexlist"},
+ {clif_parse_PMIgnoreAll,"wisall"},
+ {clif_parse_FriendsListAdd,"friendslistadd"},
+ {clif_parse_FriendsListRemove,"friendslistremove"},
+ {clif_parse_FriendsListReply,"friendslistreply"},
+ {clif_parse_Blacksmith,"blacksmith"},
+ {clif_parse_Alchemist,"alchemist"},
+ {clif_parse_Taekwon,"taekwon"},
+ {clif_parse_RankingPk,"rankingpk"},
+ {clif_parse_FeelSaveOk,"feelsaveok"},
+ {clif_parse_debug,"debug"},
+ {clif_parse_ChangeHomunculusName,"changehomunculusname"},
+ {clif_parse_HomMoveToMaster,"hommovetomaster"},
+ {clif_parse_HomMoveTo,"hommoveto"},
+ {clif_parse_HomAttack,"homattack"},
+ {clif_parse_HomMenu,"hommenu"},
+ {clif_parse_StoragePassword,"storagepassword"},
+ {clif_parse_Hotkey,"hotkey"},
+ {clif_parse_AutoRevive,"autorevive"},
+ {clif_parse_Check,"check"},
+ {clif_parse_Adopt_request,"adoptrequest"},
+ {clif_parse_Adopt_reply,"adoptreply"},
+ // MAIL SYSTEM
+ {clif_parse_Mail_refreshinbox,"mailrefresh"},
+ {clif_parse_Mail_read,"mailread"},
+ {clif_parse_Mail_getattach,"mailgetattach"},
+ {clif_parse_Mail_delete,"maildelete"},
+ {clif_parse_Mail_return,"mailreturn"},
+ {clif_parse_Mail_setattach,"mailsetattach"},
+ {clif_parse_Mail_winopen,"mailwinopen"},
+ {clif_parse_Mail_send,"mailsend"},
+ // AUCTION SYSTEM
+ {clif_parse_Auction_search,"auctionsearch"},
+ {clif_parse_Auction_buysell,"auctionbuysell"},
+ {clif_parse_Auction_setitem,"auctionsetitem"},
+ {clif_parse_Auction_cancelreg,"auctioncancelreg"},
+ {clif_parse_Auction_register,"auctionregister"},
+ {clif_parse_Auction_cancel,"auctioncancel"},
+ {clif_parse_Auction_close,"auctionclose"},
+ {clif_parse_Auction_bid,"auctionbid"},
+ // Quest Log System
+ {clif_parse_questStateAck,"queststate"},
+ {clif_parse_cashshop_buy,"cashshopbuy"},
+ {clif_parse_ViewPlayerEquip,"viewplayerequip"},
+ {clif_parse_EquipTick,"equiptickbox"},
+ {clif_parse_BattleChat,"battlechat"},
+ {clif_parse_mercenary_action,"mermenu"},
+ {clif_parse_progressbar,"progressbar"},
+ {clif_parse_SkillSelectMenu,"skillselectmenu"},
+ {clif_parse_ItemListWindowSelected,"itemlistwindowselected"},
#if PACKETVER >= 20091229
- {clif_parse_PartyBookingRegisterReq,"bookingregreq"},
- {clif_parse_PartyBookingSearchReq,"bookingsearchreq"},
- {clif_parse_PartyBookingUpdateReq,"bookingupdatereq"},
- {clif_parse_PartyBookingDeleteReq,"bookingdelreq"},
+ {clif_parse_PartyBookingRegisterReq,"bookingregreq"},
+ {clif_parse_PartyBookingSearchReq,"bookingsearchreq"},
+ {clif_parse_PartyBookingUpdateReq,"bookingupdatereq"},
+ {clif_parse_PartyBookingDeleteReq,"bookingdelreq"},
#endif
- {clif_parse_PVPInfo,"pvpinfo"},
- {clif_parse_LessEffect,"lesseffect"},
- // Buying Store
- {clif_parse_ReqOpenBuyingStore,"reqopenbuyingstore"},
- {clif_parse_ReqCloseBuyingStore,"reqclosebuyingstore"},
- {clif_parse_ReqClickBuyingStore,"reqclickbuyingstore"},
- {clif_parse_ReqTradeBuyingStore,"reqtradebuyingstore"},
- // Store Search
- {clif_parse_SearchStoreInfo,"searchstoreinfo"},
- {clif_parse_SearchStoreInfoNextPage,"searchstoreinfonextpage"},
- {clif_parse_CloseSearchStoreInfo,"closesearchstoreinfo"},
- {clif_parse_SearchStoreInfoListItemClick,"searchstoreinfolistitemclick"},
- /* */
- { clif_parse_MoveItem , "moveitem" },
- {NULL,NULL}
- };
-
- // initialize packet_db[SERVER] from hardcoded packet_len_table[] values
- memset(packet_db,0,sizeof(packet_db));
- for (i = 0; i < ARRAYLENGTH(packet_len_table); ++i)
- packet_len(i) = packet_len_table[i];
-
- sprintf(line, "%s/packet_db.txt", db_path);
- if ((fp=fopen(line,"r"))==NULL) {
- ShowFatalError("can't read %s\n", line);
- exit(EXIT_FAILURE);
- }
-
- clif_config.packet_db_ver = MAX_PACKET_VER;
- packet_ver = MAX_PACKET_VER; // read into packet_db's version by default
- while (fgets(line, sizeof(line), fp)) {
- ln++;
- if (line[0]=='/' && line[1]=='/')
- continue;
- if (sscanf(line,"%256[^:]: %256[^\r\n]",w1,w2) == 2) {
- if (strcmpi(w1,"packet_ver")==0) {
- int prev_ver = packet_ver;
- skip_ver = 0;
- packet_ver = atoi(w2);
- if (packet_ver > MAX_PACKET_VER) {
- //Check to avoid overflowing. [Skotlex]
- if ((warned&1) == 0)
- ShowWarning("The packet_db table only has support up to version %d.\n", MAX_PACKET_VER);
- warned &= 1;
- skip_ver = 1;
- } else if (packet_ver < 0) {
- if ((warned&2) == 0)
- ShowWarning("Negative packet versions are not supported.\n");
- warned &= 2;
- skip_ver = 1;
- } else if (packet_ver == SERVER) {
- if ((warned&4) == 0)
- ShowWarning("Packet version %d is reserved for server use only.\n", SERVER);
- warned &= 4;
- skip_ver = 1;
- }
-
- if (skip_ver) {
- ShowWarning("Skipping packet version %d.\n", packet_ver);
- packet_ver = prev_ver;
- continue;
- }
- // copy from previous version into new version and continue
- // - indicating all following packets should be read into the newer version
- memcpy(&packet_db[packet_ver], &packet_db[prev_ver], sizeof(packet_db[0]));
- continue;
- } else if (strcmpi(w1,"packet_db_ver")==0) {
- if (strcmpi(w2,"default")==0) //This is the preferred version.
- clif_config.packet_db_ver = MAX_PACKET_VER;
- else // to manually set the packet DB version
- clif_config.packet_db_ver = cap_value(atoi(w2), 0, MAX_PACKET_VER);
-
- continue;
- }
- }
-
- if (skip_ver != 0)
- continue; // Skipping current packet version
-
- 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 (max_cmd < cmd)
- max_cmd = cmd;
- if (cmd <= 0 || cmd > MAX_PACKET_DB)
- continue;
- if (str[1]==NULL) {
- ShowError("packet_db: packet len error\n");
- continue;
- }
-
- packet_db[packet_ver][cmd].len = (short)atoi(str[1]);
-
- if (str[2]==NULL) {
- packet_db[packet_ver][cmd].func = NULL;
- ln++;
- continue;
- }
-
- // look up processing function by name
- ARR_FIND(0, ARRAYLENGTH(clif_parse_func), j, clif_parse_func[j].name != NULL && strcmp(str[2],clif_parse_func[j].name)==0);
- if (j < ARRAYLENGTH(clif_parse_func))
- packet_db[packet_ver][cmd].func = clif_parse_func[j].func;
-
- // set the identifying cmd for the packet_db version
- if (strcmp(str[2],"wanttoconnection")==0)
- clif_config.connect_cmd[packet_ver] = cmd;
-
- if (str[3]==NULL) {
- ShowError("packet_db: packet error\n");
- exit(EXIT_FAILURE);
- }
- for (j=0,p2=str[3]; p2; j++) {
- short k;
- 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
-
- if (j >= MAX_PACKET_POS) {
- ShowError("Too many positions found for packet 0x%04x (max=%d).\n", cmd, MAX_PACKET_POS);
- break;
- }
-
- packet_db[packet_ver][cmd].pos[j] = k;
- }
- }
- fclose(fp);
- if (max_cmd > MAX_PACKET_DB) {
- ShowWarning("Found packets up to 0x%X, ignored 0x%X and above.\n", max_cmd, MAX_PACKET_DB);
- ShowWarning("Please increase MAX_PACKET_DB and recompile.\n");
- }
- if (!clif_config.connect_cmd[clif_config.packet_db_ver]) {
- //Locate the nearest version that we still support. [Skotlex]
- for (j = clif_config.packet_db_ver; j >= 0 && !clif_config.connect_cmd[j]; j--);
-
- clif_config.packet_db_ver = j?j:MAX_PACKET_VER;
- }
- ShowStatus("Done reading packet database from '"CL_WHITE"%s"CL_RESET"'. Using default packet version: "CL_WHITE"%d"CL_RESET".\n", "packet_db.txt", clif_config.packet_db_ver);
- return 0;
+ {clif_parse_PVPInfo,"pvpinfo"},
+ {clif_parse_LessEffect,"lesseffect"},
+ // Buying Store
+ {clif_parse_ReqOpenBuyingStore,"reqopenbuyingstore"},
+ {clif_parse_ReqCloseBuyingStore,"reqclosebuyingstore"},
+ {clif_parse_ReqClickBuyingStore,"reqclickbuyingstore"},
+ {clif_parse_ReqTradeBuyingStore,"reqtradebuyingstore"},
+ // Store Search
+ {clif_parse_SearchStoreInfo,"searchstoreinfo"},
+ {clif_parse_SearchStoreInfoNextPage,"searchstoreinfonextpage"},
+ {clif_parse_CloseSearchStoreInfo,"closesearchstoreinfo"},
+ {clif_parse_SearchStoreInfoListItemClick,"searchstoreinfolistitemclick"},
+ /* */
+ { clif_parse_MoveItem , "moveitem" },
+ {NULL,NULL}
+ };
+
+ // initialize packet_db[SERVER] from hardcoded packet_len_table[] values
+ memset(packet_db,0,sizeof(packet_db));
+ for( i = 0; i < ARRAYLENGTH(packet_len_table); ++i )
+ packet_len(i) = packet_len_table[i];
+
+ sprintf(line, "%s/packet_db.txt", db_path);
+ if( (fp=fopen(line,"r"))==NULL ){
+ ShowFatalError("can't read %s\n", line);
+ exit(EXIT_FAILURE);
+ }
+
+ clif_config.packet_db_ver = MAX_PACKET_VER;
+ packet_ver = MAX_PACKET_VER; // read into packet_db's version by default
+ while( fgets(line, sizeof(line), fp) )
+ {
+ ln++;
+ if(line[0]=='/' && line[1]=='/')
+ continue;
+ if (sscanf(line,"%256[^:]: %256[^\r\n]",w1,w2) == 2)
+ {
+ if(strcmpi(w1,"packet_ver")==0) {
+ int prev_ver = packet_ver;
+ skip_ver = 0;
+ packet_ver = atoi(w2);
+ if ( packet_ver > MAX_PACKET_VER )
+ { //Check to avoid overflowing. [Skotlex]
+ if( (warned&1) == 0 )
+ ShowWarning("The packet_db table only has support up to version %d.\n", MAX_PACKET_VER);
+ warned &= 1;
+ skip_ver = 1;
+ }
+ else if( packet_ver < 0 )
+ {
+ if( (warned&2) == 0 )
+ ShowWarning("Negative packet versions are not supported.\n");
+ warned &= 2;
+ skip_ver = 1;
+ }
+ else if( packet_ver == SERVER )
+ {
+ if( (warned&4) == 0 )
+ ShowWarning("Packet version %d is reserved for server use only.\n", SERVER);
+ warned &= 4;
+ skip_ver = 1;
+ }
+
+ if( skip_ver )
+ {
+ ShowWarning("Skipping packet version %d.\n", packet_ver);
+ packet_ver = prev_ver;
+ continue;
+ }
+ // copy from previous version into new version and continue
+ // - indicating all following packets should be read into the newer version
+ memcpy(&packet_db[packet_ver], &packet_db[prev_ver], sizeof(packet_db[0]));
+ continue;
+ } else if(strcmpi(w1,"packet_db_ver")==0) {
+ if(strcmpi(w2,"default")==0) //This is the preferred version.
+ clif_config.packet_db_ver = MAX_PACKET_VER;
+ else // to manually set the packet DB version
+ clif_config.packet_db_ver = cap_value(atoi(w2), 0, MAX_PACKET_VER);
+
+ continue;
+ }
+ }
+
+ if( skip_ver != 0 )
+ continue; // Skipping current packet version
+
+ 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(max_cmd < cmd)
+ max_cmd = cmd;
+ if(cmd <= 0 || cmd > MAX_PACKET_DB)
+ continue;
+ if(str[1]==NULL){
+ ShowError("packet_db: packet len error\n");
+ continue;
+ }
+
+ packet_db[packet_ver][cmd].len = (short)atoi(str[1]);
+
+ if(str[2]==NULL){
+ packet_db[packet_ver][cmd].func = NULL;
+ ln++;
+ continue;
+ }
+
+ // look up processing function by name
+ ARR_FIND( 0, ARRAYLENGTH(clif_parse_func), j, clif_parse_func[j].name != NULL && strcmp(str[2],clif_parse_func[j].name)==0 );
+ if( j < ARRAYLENGTH(clif_parse_func) )
+ packet_db[packet_ver][cmd].func = clif_parse_func[j].func;
+
+ // set the identifying cmd for the packet_db version
+ if (strcmp(str[2],"wanttoconnection")==0)
+ clif_config.connect_cmd[packet_ver] = cmd;
+
+ if(str[3]==NULL){
+ ShowError("packet_db: packet error\n");
+ exit(EXIT_FAILURE);
+ }
+ for(j=0,p2=str[3];p2;j++){
+ short k;
+ 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
+
+ if( j >= MAX_PACKET_POS )
+ {
+ ShowError("Too many positions found for packet 0x%04x (max=%d).\n", cmd, MAX_PACKET_POS);
+ break;
+ }
+
+ packet_db[packet_ver][cmd].pos[j] = k;
+ }
+ }
+ fclose(fp);
+ if(max_cmd > MAX_PACKET_DB)
+ {
+ ShowWarning("Found packets up to 0x%X, ignored 0x%X and above.\n", max_cmd, MAX_PACKET_DB);
+ ShowWarning("Please increase MAX_PACKET_DB and recompile.\n");
+ }
+ if (!clif_config.connect_cmd[clif_config.packet_db_ver])
+ { //Locate the nearest version that we still support. [Skotlex]
+ for(j = clif_config.packet_db_ver; j >= 0 && !clif_config.connect_cmd[j]; j--);
+
+ clif_config.packet_db_ver = j?j:MAX_PACKET_VER;
+ }
+ ShowStatus("Done reading packet database from '"CL_WHITE"%s"CL_RESET"'. Using default packet version: "CL_WHITE"%d"CL_RESET".\n", "packet_db.txt", clif_config.packet_db_ver);
+ return 0;
}
/*==========================================
*
*------------------------------------------*/
-int do_init_clif(void)
-{
- const char *colors[COLOR_MAX] = { "0xFF0000" };
- int i;
- /**
- * Setup Color Table (saves unnecessary load of strtoul on every call)
- **/
- for (i = 0; i < COLOR_MAX; i++) {
- color_table[i] = strtoul(colors[i],NULL,0);
- color_table[i] = (color_table[i] & 0x0000FF) << 16 | (color_table[i] & 0x00FF00) | (color_table[i] & 0xFF0000) >> 16;//RGB to BGR
- }
+int do_init_clif(void) {
+ const char* colors[COLOR_MAX] = { "0xFF0000" };
+ int i;
+ /**
+ * Setup Color Table (saves unnecessary load of strtoul on every call)
+ **/
+ for(i = 0; i < COLOR_MAX; i++) {
+ color_table[i] = strtoul(colors[i],NULL,0);
+ color_table[i] = (color_table[i] & 0x0000FF) << 16 | (color_table[i] & 0x00FF00) | (color_table[i] & 0xFF0000) >> 16;//RGB to BGR
+ }
- clif_config.packet_db_ver = -1; // the main packet version of the DB
- memset(clif_config.connect_cmd, 0, sizeof(clif_config.connect_cmd)); //The default connect command will be determined after reading the packet_db [Skotlex]
+ clif_config.packet_db_ver = -1; // the main packet version of the DB
+ memset(clif_config.connect_cmd, 0, sizeof(clif_config.connect_cmd)); //The default connect command will be determined after reading the packet_db [Skotlex]
- memset(packet_db,0,sizeof(packet_db));
- //Using the packet_db file is the only way to set up packets now [Skotlex]
- packetdb_readdb();
+ memset(packet_db,0,sizeof(packet_db));
+ //Using the packet_db file is the only way to set up packets now [Skotlex]
+ packetdb_readdb();
- set_defaultparse(clif_parse);
- if (make_listen_bind(bind_ip,map_port) == -1) {
- ShowFatalError("can't bind game port\n");
- exit(EXIT_FAILURE);
- }
+ set_defaultparse(clif_parse);
+ if( make_listen_bind(bind_ip,map_port) == -1 ) {
+ ShowFatalError("can't bind game port\n");
+ exit(EXIT_FAILURE);
+ }
- add_timer_func_list(clif_clearunit_delayed_sub, "clif_clearunit_delayed_sub");
- add_timer_func_list(clif_delayquit, "clif_delayquit");
+ add_timer_func_list(clif_clearunit_delayed_sub, "clif_clearunit_delayed_sub");
+ add_timer_func_list(clif_delayquit, "clif_delayquit");
- delay_clearunit_ers = ers_new(sizeof(struct block_list),"clif.c::delay_clearunit_ers",ERS_OPT_CLEAR);
+ delay_clearunit_ers = ers_new(sizeof(struct block_list),"clif.c::delay_clearunit_ers",ERS_OPT_CLEAR);
- return 0;
+ return 0;
}
-void do_final_clif(void)
-{
- ers_destroy(delay_clearunit_ers);
+void do_final_clif(void) {
+ ers_destroy(delay_clearunit_ers);
}
diff --git a/src/map/clif.h b/src/map/clif.h
index cde892638..0948a12c1 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -29,17 +29,17 @@ struct quest;
struct party_booking_ad_info;
#include <stdarg.h>
-enum {
- // packet DB
- MAX_PACKET_DB = 0xA00,
- MAX_PACKET_VER = 30,
- MAX_PACKET_POS = 20,
+enum
+{// packet DB
+ MAX_PACKET_DB = 0xA00,
+ MAX_PACKET_VER = 30,
+ MAX_PACKET_POS = 20,
};
struct s_packet_db {
- short len;
- void (*func)(int, struct map_session_data *);
- short pos[MAX_PACKET_POS];
+ short len;
+ void (*func)(int, struct map_session_data *);
+ short pos[MAX_PACKET_POS];
};
// packet_db[SERVER] is reserved for server use
@@ -49,271 +49,273 @@ extern struct s_packet_db packet_db[MAX_PACKET_VER+1][MAX_PACKET_DB+1];
// local define
typedef enum send_target {
- ALL_CLIENT,
- ALL_SAMEMAP,
- AREA, // area
- AREA_WOS, // area, without self
- AREA_WOC, // area, without chatrooms
- AREA_WOSC, // area, without own chatroom
- AREA_CHAT_WOC, // hearable area, without chatrooms
- CHAT, // current chatroom
- CHAT_WOS, // current chatroom, without self
- PARTY,
- PARTY_WOS,
- PARTY_SAMEMAP,
- PARTY_SAMEMAP_WOS,
- PARTY_AREA,
- PARTY_AREA_WOS,
- GUILD,
- GUILD_WOS,
- GUILD_SAMEMAP,
- GUILD_SAMEMAP_WOS,
- GUILD_AREA,
- GUILD_AREA_WOS,
- GUILD_NOBG,
- DUEL,
- DUEL_WOS,
- CHAT_MAINCHAT, // everyone on main chat
- SELF,
- BG, // BattleGround System
- BG_WOS,
- BG_SAMEMAP,
- BG_SAMEMAP_WOS,
- BG_AREA,
- BG_AREA_WOS,
+ ALL_CLIENT,
+ ALL_SAMEMAP,
+ AREA, // area
+ AREA_WOS, // area, without self
+ AREA_WOC, // area, without chatrooms
+ AREA_WOSC, // area, without own chatroom
+ AREA_CHAT_WOC, // hearable area, without chatrooms
+ CHAT, // current chatroom
+ CHAT_WOS, // current chatroom, without self
+ PARTY,
+ PARTY_WOS,
+ PARTY_SAMEMAP,
+ PARTY_SAMEMAP_WOS,
+ PARTY_AREA,
+ PARTY_AREA_WOS,
+ GUILD,
+ GUILD_WOS,
+ GUILD_SAMEMAP,
+ GUILD_SAMEMAP_WOS,
+ GUILD_AREA,
+ GUILD_AREA_WOS,
+ GUILD_NOBG,
+ DUEL,
+ DUEL_WOS,
+ CHAT_MAINCHAT, // everyone on main chat
+ SELF,
+ BG, // BattleGround System
+ BG_WOS,
+ BG_SAMEMAP,
+ BG_SAMEMAP_WOS,
+ BG_AREA,
+ BG_AREA_WOS,
} send_target;
-typedef enum emotion_type {
- E_GASP = 0, // /!
- E_WHAT, // /?
- E_HO,
- E_LV,
- E_SWT,
- E_IC,
- E_AN,
- E_AG,
- E_CASH, // /$
- E_DOTS, // /...
- E_SCISSORS, // /gawi --- 10
- E_ROCK, // /bawi
- E_PAPER, // /bo
- E_KOREA,
- E_LV2,
- E_THX,
- E_WAH,
- E_SRY,
- E_HEH,
- E_SWT2,
- E_HMM, // --- 20
- E_NO1,
- E_NO, // /??
- E_OMG,
- E_OH,
- E_X,
- E_HLP,
- E_GO,
- E_SOB,
- E_GG,
- E_KIS, // --- 30
- E_KIS2,
- E_PIF,
- E_OK,
- E_MUTE, // red /... used for muted characters
- E_INDONESIA,
- E_BZZ, // /bzz, /stare
- E_RICE,
- E_AWSM, // /awsm, /cool
- E_MEH,
- E_SHY, // --- 40
- E_PAT, // /pat, /goodboy
- E_MP, // /mp, /sptime
- E_SLUR,
- E_COM, // /com, /comeon
- E_YAWN, // /yawn, /sleepy
- E_GRAT, // /grat, /congrats
- E_HP, // /hp, /hptime
- E_PHILIPPINES,
- E_MALAYSIA,
- E_SINGAPORE, // --- 50
- E_BRAZIL,
- E_FLASH, // /fsh
- E_SPIN, // /spin
- E_SIGH,
- E_DUM, // /dum
- E_LOUD, // /crwd
- E_OTL, // /otl, /desp
- E_DICE1,
- E_DICE2,
- E_DICE3, // --- 60
- E_DICE4,
- E_DICE5,
- E_DICE6,
- E_INDIA,
- E_LUV, // /love
- E_RUSSIA,
- E_VIRGIN,
- E_MOBILE,
- E_MAIL,
- E_CHINESE, // --- 70
- E_ANTENNA1,
- E_ANTENNA2,
- E_ANTENNA3,
- E_HUM,
- E_ABS,
- E_OOPS,
- E_SPIT,
- E_ENE,
- E_PANIC,
- E_WHISP, // --- 80
- E_YUT1,
- E_YUT2,
- E_YUT3,
- E_YUT4,
- E_YUT5,
- E_YUT6,
- E_YUT7,
- //
- E_MAX
+typedef enum emotion_type
+{
+ E_GASP = 0, // /!
+ E_WHAT, // /?
+ E_HO,
+ E_LV,
+ E_SWT,
+ E_IC,
+ E_AN,
+ E_AG,
+ E_CASH, // /$
+ E_DOTS, // /...
+ E_SCISSORS, // /gawi --- 10
+ E_ROCK, // /bawi
+ E_PAPER, // /bo
+ E_KOREA,
+ E_LV2,
+ E_THX,
+ E_WAH,
+ E_SRY,
+ E_HEH,
+ E_SWT2,
+ E_HMM, // --- 20
+ E_NO1,
+ E_NO, // /??
+ E_OMG,
+ E_OH,
+ E_X,
+ E_HLP,
+ E_GO,
+ E_SOB,
+ E_GG,
+ E_KIS, // --- 30
+ E_KIS2,
+ E_PIF,
+ E_OK,
+ E_MUTE, // red /... used for muted characters
+ E_INDONESIA,
+ E_BZZ, // /bzz, /stare
+ E_RICE,
+ E_AWSM, // /awsm, /cool
+ E_MEH,
+ E_SHY, // --- 40
+ E_PAT, // /pat, /goodboy
+ E_MP, // /mp, /sptime
+ E_SLUR,
+ E_COM, // /com, /comeon
+ E_YAWN, // /yawn, /sleepy
+ E_GRAT, // /grat, /congrats
+ E_HP, // /hp, /hptime
+ E_PHILIPPINES,
+ E_MALAYSIA,
+ E_SINGAPORE, // --- 50
+ E_BRAZIL,
+ E_FLASH, // /fsh
+ E_SPIN, // /spin
+ E_SIGH,
+ E_DUM, // /dum
+ E_LOUD, // /crwd
+ E_OTL, // /otl, /desp
+ E_DICE1,
+ E_DICE2,
+ E_DICE3, // --- 60
+ E_DICE4,
+ E_DICE5,
+ E_DICE6,
+ E_INDIA,
+ E_LUV, // /love
+ E_RUSSIA,
+ E_VIRGIN,
+ E_MOBILE,
+ E_MAIL,
+ E_CHINESE, // --- 70
+ E_ANTENNA1,
+ E_ANTENNA2,
+ E_ANTENNA3,
+ E_HUM,
+ E_ABS,
+ E_OOPS,
+ E_SPIT,
+ E_ENE,
+ E_PANIC,
+ E_WHISP, // --- 80
+ E_YUT1,
+ E_YUT2,
+ E_YUT3,
+ E_YUT4,
+ E_YUT5,
+ E_YUT6,
+ E_YUT7,
+ //
+ E_MAX
} emotion_type;
-typedef enum clr_type {
- CLR_OUTSIGHT = 0,
- CLR_DEAD,
- CLR_RESPAWN,
- CLR_TELEPORT,
- CLR_TRICKDEAD,
+typedef enum clr_type
+{
+ CLR_OUTSIGHT = 0,
+ CLR_DEAD,
+ CLR_RESPAWN,
+ CLR_TELEPORT,
+ CLR_TRICKDEAD,
} clr_type;
-enum map_property {
- // clif_map_property
- MAPPROPERTY_NOTHING = 0,
- MAPPROPERTY_FREEPVPZONE = 1,
- MAPPROPERTY_EVENTPVPZONE = 2,
- MAPPROPERTY_AGITZONE = 3,
- MAPPROPERTY_PKSERVERZONE = 4, // message "You are in a PK area. Please beware of sudden attacks." in color 0x9B9BFF (light red)
- MAPPROPERTY_PVPSERVERZONE = 5,
- MAPPROPERTY_DENYSKILLZONE = 6,
+enum map_property
+{// clif_map_property
+ MAPPROPERTY_NOTHING = 0,
+ MAPPROPERTY_FREEPVPZONE = 1,
+ MAPPROPERTY_EVENTPVPZONE = 2,
+ MAPPROPERTY_AGITZONE = 3,
+ MAPPROPERTY_PKSERVERZONE = 4, // message "You are in a PK area. Please beware of sudden attacks." in color 0x9B9BFF (light red)
+ MAPPROPERTY_PVPSERVERZONE = 5,
+ MAPPROPERTY_DENYSKILLZONE = 6,
};
-enum map_type {
- // clif_map_type
- MAPTYPE_VILLAGE = 0,
- MAPTYPE_VILLAGE_IN = 1,
- MAPTYPE_FIELD = 2,
- MAPTYPE_DUNGEON = 3,
- MAPTYPE_ARENA = 4,
- MAPTYPE_PENALTY_FREEPKZONE = 5,
- MAPTYPE_NOPENALTY_FREEPKZONE = 6,
- MAPTYPE_EVENT_GUILDWAR = 7,
- MAPTYPE_AGIT = 8,
- MAPTYPE_DUNGEON2 = 9,
- MAPTYPE_DUNGEON3 = 10,
- MAPTYPE_PKSERVER = 11,
- MAPTYPE_PVPSERVER = 12,
- MAPTYPE_DENYSKILL = 13,
- MAPTYPE_TURBOTRACK = 14,
- MAPTYPE_JAIL = 15,
- MAPTYPE_MONSTERTRACK = 16,
- MAPTYPE_PORINGBATTLE = 17,
- MAPTYPE_AGIT_SIEGEV15 = 18,
- MAPTYPE_BATTLEFIELD = 19,
- MAPTYPE_PVP_TOURNAMENT = 20,
- //Map types 21 - 24 not used.
- MAPTYPE_SIEGE_LOWLEVEL = 25,
- //Map types 26 - 28 remains opens for future types.
- MAPTYPE_UNUSED = 29,
+enum map_type
+{// clif_map_type
+ MAPTYPE_VILLAGE = 0,
+ MAPTYPE_VILLAGE_IN = 1,
+ MAPTYPE_FIELD = 2,
+ MAPTYPE_DUNGEON = 3,
+ MAPTYPE_ARENA = 4,
+ MAPTYPE_PENALTY_FREEPKZONE = 5,
+ MAPTYPE_NOPENALTY_FREEPKZONE = 6,
+ MAPTYPE_EVENT_GUILDWAR = 7,
+ MAPTYPE_AGIT = 8,
+ MAPTYPE_DUNGEON2 = 9,
+ MAPTYPE_DUNGEON3 = 10,
+ MAPTYPE_PKSERVER = 11,
+ MAPTYPE_PVPSERVER = 12,
+ MAPTYPE_DENYSKILL = 13,
+ MAPTYPE_TURBOTRACK = 14,
+ MAPTYPE_JAIL = 15,
+ MAPTYPE_MONSTERTRACK = 16,
+ MAPTYPE_PORINGBATTLE = 17,
+ MAPTYPE_AGIT_SIEGEV15 = 18,
+ MAPTYPE_BATTLEFIELD = 19,
+ MAPTYPE_PVP_TOURNAMENT = 20,
+ //Map types 21 - 24 not used.
+ MAPTYPE_SIEGE_LOWLEVEL = 25,
+ //Map types 26 - 28 remains opens for future types.
+ MAPTYPE_UNUSED = 29,
};
-enum useskill_fail_cause {
- // clif_skill_fail
- USESKILL_FAIL_LEVEL = 0,
- USESKILL_FAIL_SP_INSUFFICIENT = 1,
- USESKILL_FAIL_HP_INSUFFICIENT = 2,
- USESKILL_FAIL_STUFF_INSUFFICIENT = 3,
- USESKILL_FAIL_SKILLINTERVAL = 4,
- USESKILL_FAIL_MONEY = 5,
- USESKILL_FAIL_THIS_WEAPON = 6,
- USESKILL_FAIL_REDJAMSTONE = 7,
- USESKILL_FAIL_BLUEJAMSTONE = 8,
- USESKILL_FAIL_WEIGHTOVER = 9,
- USESKILL_FAIL = 10,
- USESKILL_FAIL_TOTARGET = 11,
- USESKILL_FAIL_ANCILLA_NUMOVER = 12,
- USESKILL_FAIL_HOLYWATER = 13,
- USESKILL_FAIL_ANCILLA = 14,
- USESKILL_FAIL_DUPLICATE_RANGEIN = 15,
- USESKILL_FAIL_NEED_OTHER_SKILL = 16,
- USESKILL_FAIL_NEED_HELPER = 17,
- USESKILL_FAIL_INVALID_DIR = 18,
- USESKILL_FAIL_SUMMON = 19,
- USESKILL_FAIL_SUMMON_NONE = 20,
- USESKILL_FAIL_IMITATION_SKILL_NONE = 21,
- USESKILL_FAIL_DUPLICATE = 22,
- USESKILL_FAIL_CONDITION = 23,
- USESKILL_FAIL_PAINTBRUSH = 24,
- USESKILL_FAIL_DRAGON = 25,
- USESKILL_FAIL_POS = 26,
- USESKILL_FAIL_HELPER_SP_INSUFFICIENT = 27,
- USESKILL_FAIL_NEER_WALL = 28,
- USESKILL_FAIL_NEED_EXP_1PERCENT = 29,
- USESKILL_FAIL_CHORUS_SP_INSUFFICIENT = 30,
- USESKILL_FAIL_GC_WEAPONBLOCKING = 31,
- USESKILL_FAIL_GC_POISONINGWEAPON = 32,
- USESKILL_FAIL_MADOGEAR = 33,
- USESKILL_FAIL_NEED_EQUIPMENT_KUNAI = 34,
- USESKILL_FAIL_TOTARGET_PLAYER = 35,
- USESKILL_FAIL_SIZE = 36,
- USESKILL_FAIL_CANONBALL = 37,
- //XXX_USESKILL_FAIL_II_MADOGEAR_ACCELERATION = 38,
- //XXX_USESKILL_FAIL_II_MADOGEAR_HOVERING_BOOSTER = 39,
- USESKILL_FAIL_MADOGEAR_HOVERING = 40,
- //XXX_USESKILL_FAIL_II_MADOGEAR_SELFDESTRUCTION_DEVICE = 41,
- //XXX_USESKILL_FAIL_II_MADOGEAR_SHAPESHIFTER = 42,
- USESKILL_FAIL_GUILLONTINE_POISON = 43,
- //XXX_USESKILL_FAIL_II_MADOGEAR_COOLING_DEVICE = 44,
- //XXX_USESKILL_FAIL_II_MADOGEAR_MAGNETICFIELD_GENERATOR = 45,
- //XXX_USESKILL_FAIL_II_MADOGEAR_BARRIER_GENERATOR = 46,
- //XXX_USESKILL_FAIL_II_MADOGEAR_OPTICALCAMOUFLAGE_GENERATOR = 47,
- //XXX_USESKILL_FAIL_II_MADOGEAR_REPAIRKIT = 48,
- //XXX_USESKILL_FAIL_II_MONKEY_SPANNER = 49,
- USESKILL_FAIL_MADOGEAR_RIDE = 50,
- USESKILL_FAIL_SPELLBOOK = 51,
- USESKILL_FAIL_SPELLBOOK_DIFFICULT_SLEEP = 52,
- USESKILL_FAIL_SPELLBOOK_PRESERVATION_POINT = 53,
- USESKILL_FAIL_SPELLBOOK_READING = 54,
- //XXX_USESKILL_FAIL_II_FACE_PAINTS = 55,
- //XXX_USESKILL_FAIL_II_MAKEUP_BRUSH = 56,
- USESKILL_FAIL_CART = 57,
- //XXX_USESKILL_FAIL_II_THORNS_SEED = 58,
- //XXX_USESKILL_FAIL_II_BLOOD_SUCKER_SEED = 59,
- USESKILL_FAIL_NO_MORE_SPELL = 60,
- //XXX_USESKILL_FAIL_II_BOMB_MUSHROOM_SPORE = 61,
- //XXX_USESKILL_FAIL_II_GASOLINE_BOOMB = 62,
- //XXX_USESKILL_FAIL_II_OIL_BOTTLE = 63,
- //XXX_USESKILL_FAIL_II_EXPLOSION_POWDER = 64,
- //XXX_USESKILL_FAIL_II_SMOKE_POWDER = 65,
- //XXX_USESKILL_FAIL_II_TEAR_GAS = 66,
- //XXX_USESKILL_FAIL_II_HYDROCHLORIC_ACID_BOTTLE = 67,
- //XXX_USESKILL_FAIL_II_HELLS_PLANT_BOTTLE = 68,
- //XXX_USESKILL_FAIL_II_MANDRAGORA_FLOWERPOT = 69,
- USESKILL_FAIL_MANUAL_NOTIFY = 70,
- USESKILL_FAIL_NEED_ITEM = 71,
- USESKILL_FAIL_NEED_EQUIPMENT = 72,
- USESKILL_FAIL_COMBOSKILL = 73,
- USESKILL_FAIL_SPIRITS = 74,
- USESKILL_FAIL_EXPLOSIONSPIRITS = 75,
- USESKILL_FAIL_HP_TOOMANY = 76,
- USESKILL_FAIL_NEED_ROYAL_GUARD_BANDING = 77,
- USESKILL_FAIL_NEED_EQUIPPED_WEAPON_CLASS = 78,
- USESKILL_FAIL_EL_SUMMON = 79,
- USESKILL_FAIL_RELATIONGRADE = 80,
- USESKILL_FAIL_STYLE_CHANGE_FIGHTER = 81,
- USESKILL_FAIL_STYLE_CHANGE_GRAPPLER = 82,
- USESKILL_FAIL_THERE_ARE_NPC_AROUND = 83,
+enum useskill_fail_cause
+{// clif_skill_fail
+ USESKILL_FAIL_LEVEL = 0,
+ USESKILL_FAIL_SP_INSUFFICIENT = 1,
+ USESKILL_FAIL_HP_INSUFFICIENT = 2,
+ USESKILL_FAIL_STUFF_INSUFFICIENT = 3,
+ USESKILL_FAIL_SKILLINTERVAL = 4,
+ USESKILL_FAIL_MONEY = 5,
+ USESKILL_FAIL_THIS_WEAPON = 6,
+ USESKILL_FAIL_REDJAMSTONE = 7,
+ USESKILL_FAIL_BLUEJAMSTONE = 8,
+ USESKILL_FAIL_WEIGHTOVER = 9,
+ USESKILL_FAIL = 10,
+ USESKILL_FAIL_TOTARGET = 11,
+ USESKILL_FAIL_ANCILLA_NUMOVER = 12,
+ USESKILL_FAIL_HOLYWATER = 13,
+ USESKILL_FAIL_ANCILLA = 14,
+ USESKILL_FAIL_DUPLICATE_RANGEIN = 15,
+ USESKILL_FAIL_NEED_OTHER_SKILL = 16,
+ USESKILL_FAIL_NEED_HELPER = 17,
+ USESKILL_FAIL_INVALID_DIR = 18,
+ USESKILL_FAIL_SUMMON = 19,
+ USESKILL_FAIL_SUMMON_NONE = 20,
+ USESKILL_FAIL_IMITATION_SKILL_NONE = 21,
+ USESKILL_FAIL_DUPLICATE = 22,
+ USESKILL_FAIL_CONDITION = 23,
+ USESKILL_FAIL_PAINTBRUSH = 24,
+ USESKILL_FAIL_DRAGON = 25,
+ USESKILL_FAIL_POS = 26,
+ USESKILL_FAIL_HELPER_SP_INSUFFICIENT = 27,
+ USESKILL_FAIL_NEER_WALL = 28,
+ USESKILL_FAIL_NEED_EXP_1PERCENT = 29,
+ USESKILL_FAIL_CHORUS_SP_INSUFFICIENT = 30,
+ USESKILL_FAIL_GC_WEAPONBLOCKING = 31,
+ USESKILL_FAIL_GC_POISONINGWEAPON = 32,
+ USESKILL_FAIL_MADOGEAR = 33,
+ USESKILL_FAIL_NEED_EQUIPMENT_KUNAI = 34,
+ USESKILL_FAIL_TOTARGET_PLAYER = 35,
+ USESKILL_FAIL_SIZE = 36,
+ USESKILL_FAIL_CANONBALL = 37,
+ //XXX_USESKILL_FAIL_II_MADOGEAR_ACCELERATION = 38,
+ //XXX_USESKILL_FAIL_II_MADOGEAR_HOVERING_BOOSTER = 39,
+ USESKILL_FAIL_MADOGEAR_HOVERING = 40,
+ //XXX_USESKILL_FAIL_II_MADOGEAR_SELFDESTRUCTION_DEVICE = 41,
+ //XXX_USESKILL_FAIL_II_MADOGEAR_SHAPESHIFTER = 42,
+ USESKILL_FAIL_GUILLONTINE_POISON = 43,
+ //XXX_USESKILL_FAIL_II_MADOGEAR_COOLING_DEVICE = 44,
+ //XXX_USESKILL_FAIL_II_MADOGEAR_MAGNETICFIELD_GENERATOR = 45,
+ //XXX_USESKILL_FAIL_II_MADOGEAR_BARRIER_GENERATOR = 46,
+ //XXX_USESKILL_FAIL_II_MADOGEAR_OPTICALCAMOUFLAGE_GENERATOR = 47,
+ //XXX_USESKILL_FAIL_II_MADOGEAR_REPAIRKIT = 48,
+ //XXX_USESKILL_FAIL_II_MONKEY_SPANNER = 49,
+ USESKILL_FAIL_MADOGEAR_RIDE = 50,
+ USESKILL_FAIL_SPELLBOOK = 51,
+ USESKILL_FAIL_SPELLBOOK_DIFFICULT_SLEEP = 52,
+ USESKILL_FAIL_SPELLBOOK_PRESERVATION_POINT = 53,
+ USESKILL_FAIL_SPELLBOOK_READING = 54,
+ //XXX_USESKILL_FAIL_II_FACE_PAINTS = 55,
+ //XXX_USESKILL_FAIL_II_MAKEUP_BRUSH = 56,
+ USESKILL_FAIL_CART = 57,
+ //XXX_USESKILL_FAIL_II_THORNS_SEED = 58,
+ //XXX_USESKILL_FAIL_II_BLOOD_SUCKER_SEED = 59,
+ USESKILL_FAIL_NO_MORE_SPELL = 60,
+ //XXX_USESKILL_FAIL_II_BOMB_MUSHROOM_SPORE = 61,
+ //XXX_USESKILL_FAIL_II_GASOLINE_BOOMB = 62,
+ //XXX_USESKILL_FAIL_II_OIL_BOTTLE = 63,
+ //XXX_USESKILL_FAIL_II_EXPLOSION_POWDER = 64,
+ //XXX_USESKILL_FAIL_II_SMOKE_POWDER = 65,
+ //XXX_USESKILL_FAIL_II_TEAR_GAS = 66,
+ //XXX_USESKILL_FAIL_II_HYDROCHLORIC_ACID_BOTTLE = 67,
+ //XXX_USESKILL_FAIL_II_HELLS_PLANT_BOTTLE = 68,
+ //XXX_USESKILL_FAIL_II_MANDRAGORA_FLOWERPOT = 69,
+ USESKILL_FAIL_MANUAL_NOTIFY = 70,
+ USESKILL_FAIL_NEED_ITEM = 71,
+ USESKILL_FAIL_NEED_EQUIPMENT = 72,
+ USESKILL_FAIL_COMBOSKILL = 73,
+ USESKILL_FAIL_SPIRITS = 74,
+ USESKILL_FAIL_EXPLOSIONSPIRITS = 75,
+ USESKILL_FAIL_HP_TOOMANY = 76,
+ USESKILL_FAIL_NEED_ROYAL_GUARD_BANDING = 77,
+ USESKILL_FAIL_NEED_EQUIPPED_WEAPON_CLASS = 78,
+ USESKILL_FAIL_EL_SUMMON = 79,
+ USESKILL_FAIL_RELATIONGRADE = 80,
+ USESKILL_FAIL_STYLE_CHANGE_FIGHTER = 81,
+ USESKILL_FAIL_STYLE_CHANGE_GRAPPLER = 82,
+ USESKILL_FAIL_THERE_ARE_NPC_AROUND = 83,
};
-int clif_setip(const char *ip);
-void clif_setbindip(const char *ip);
+int clif_setip(const char* ip);
+void clif_setbindip(const char* ip);
void clif_setport(uint16 port);
uint32 clif_getip(void);
@@ -324,100 +326,100 @@ void clif_authok(struct map_session_data *sd);
void clif_authrefuse(int fd, uint8 error_code);
void clif_authfail_fd(int fd, int type);
void clif_charselectok(int id, uint8 ok);
-void clif_dropflooritem(struct flooritem_data *fitem);
+void clif_dropflooritem(struct flooritem_data* fitem);
void clif_clearflooritem(struct flooritem_data *fitem, int fd);
void clif_clearunit_single(int id, clr_type type, int fd);
-void clif_clearunit_area(struct block_list *bl, clr_type type);
-void clif_clearunit_delayed(struct block_list *bl, clr_type type, unsigned int tick);
-int clif_spawn(struct block_list *bl); //area
-void clif_walkok(struct map_session_data *sd); // self
+void clif_clearunit_area(struct block_list* bl, clr_type type);
+void clif_clearunit_delayed(struct block_list* bl, clr_type type, unsigned int tick);
+int clif_spawn(struct block_list *bl); //area
+void clif_walkok(struct map_session_data *sd); // self
void clif_move(struct unit_data *ud); //area
-void clif_changemap(struct map_session_data *sd, short map, int x, int y); //self
-void clif_changemapserver(struct map_session_data *sd, unsigned short map_index, int x, int y, uint32 ip, uint16 port); //self
+void clif_changemap(struct map_session_data *sd, short map, int x, int y); //self
+void clif_changemapserver(struct map_session_data* sd, unsigned short map_index, int x, int y, uint32 ip, uint16 port); //self
void clif_blown(struct block_list *bl); // area
void clif_slide(struct block_list *bl, int x, int y); // area
-void clif_fixpos(struct block_list *bl); // area
-void clif_npcbuysell(struct map_session_data *sd, int id); //self
-void clif_buylist(struct map_session_data *sd, struct npc_data *nd); //self
-void clif_selllist(struct map_session_data *sd); //self
-void clif_scriptmes(struct map_session_data *sd, int npcid, const char *mes); //self
-void clif_scriptnext(struct map_session_data *sd,int npcid); //self
-void clif_scriptclose(struct map_session_data *sd, int npcid); //self
-void clif_scriptmenu(struct map_session_data *sd, int npcid, const char *mes); //self
-void clif_scriptinput(struct map_session_data *sd, int npcid); //self
-void clif_scriptinputstr(struct map_session_data *sd, int npcid); // self
-void clif_cutin(struct map_session_data *sd, const char *image, int type); //self
-void clif_viewpoint(struct map_session_data *sd, int npc_id, int type, int x, int y, int id, int color); //self
+void clif_fixpos(struct block_list *bl); // area
+void clif_npcbuysell(struct map_session_data* sd, int id); //self
+void clif_buylist(struct map_session_data *sd, struct npc_data *nd); //self
+void clif_selllist(struct map_session_data *sd); //self
+void clif_scriptmes(struct map_session_data *sd, int npcid, const char *mes); //self
+void clif_scriptnext(struct map_session_data *sd,int npcid); //self
+void clif_scriptclose(struct map_session_data *sd, int npcid); //self
+void clif_scriptmenu(struct map_session_data* sd, int npcid, const char* mes); //self
+void clif_scriptinput(struct map_session_data *sd, int npcid); //self
+void clif_scriptinputstr(struct map_session_data *sd, int npcid); // self
+void clif_cutin(struct map_session_data* sd, const char* image, int type); //self
+void clif_viewpoint(struct map_session_data *sd, int npc_id, int type, int x, int y, int id, int color); //self
void clif_additem(struct map_session_data *sd, int n, int amount, int fail); // self
-void clif_dropitem(struct map_session_data *sd,int n,int amount); //self
+void clif_dropitem(struct map_session_data *sd,int n,int amount); //self
void clif_delitem(struct map_session_data *sd,int n,int amount, short reason); //self
-void clif_updatestatus(struct map_session_data *sd,int type); //self
-void clif_changestatus(struct map_session_data *sd,int type,int val); //area
-int clif_damage(struct block_list *src, struct block_list *dst, unsigned int tick, int sdelay, int ddelay, int damage, int div, int type, int damage2); // area
-void clif_takeitem(struct block_list *src, struct block_list *dst);
-void clif_sitting(struct block_list *bl);
-void clif_standing(struct block_list *bl);
-void clif_changelook(struct block_list *bl,int type,int val); // area
+void clif_updatestatus(struct map_session_data *sd,int type); //self
+void clif_changestatus(struct map_session_data* sd,int type,int val); //area
+int clif_damage(struct block_list* src, struct block_list* dst, unsigned int tick, int sdelay, int ddelay, int damage, int div, int type, int damage2); // area
+void clif_takeitem(struct block_list* src, struct block_list* dst);
+void clif_sitting(struct block_list* bl);
+void clif_standing(struct block_list* bl);
+void clif_changelook(struct block_list *bl,int type,int val); // area
void clif_changetraplook(struct block_list *bl,int val); // area
void clif_refreshlook(struct block_list *bl,int id,int type,int val,enum send_target target); //area specified in 'target'
void clif_arrowequip(struct map_session_data *sd,int val); //self
void clif_arrow_fail(struct map_session_data *sd,int type); //self
-void clif_arrow_create_list(struct map_session_data *sd); //self
-void clif_statusupack(struct map_session_data *sd,int type,int ok,int val); // self
-void clif_equipitemack(struct map_session_data *sd,int n,int pos,int ok); // self
-void clif_unequipitemack(struct map_session_data *sd,int n,int pos,int ok); // self
-void clif_misceffect(struct block_list *bl,int type); // area
-void clif_changeoption(struct block_list *bl); // area
-void clif_changeoption2(struct block_list *bl); // area
-void clif_useitemack(struct map_session_data *sd,int index,int amount,bool ok); // self
-void clif_GlobalMessage(struct block_list *bl, const char *message);
-void clif_createchat(struct map_session_data *sd, int flag); // self
-void clif_dispchat(struct chat_data *cd, int fd); // area or fd
-void clif_joinchatfail(struct map_session_data *sd,int flag); // self
-void clif_joinchatok(struct map_session_data *sd,struct chat_data *cd); // self
-void clif_addchat(struct chat_data *cd,struct map_session_data *sd); // chat
-void clif_changechatowner(struct chat_data *cd, struct map_session_data *sd); // chat
-void clif_clearchat(struct chat_data *cd,int fd); // area or fd
-void clif_leavechat(struct chat_data *cd, struct map_session_data *sd, bool flag); // chat
-void clif_changechatstatus(struct chat_data *cd); // chat
-void clif_refresh(struct map_session_data *sd); // self
+void clif_arrow_create_list(struct map_session_data *sd); //self
+void clif_statusupack(struct map_session_data *sd,int type,int ok,int val); // self
+void clif_equipitemack(struct map_session_data *sd,int n,int pos,int ok); // self
+void clif_unequipitemack(struct map_session_data *sd,int n,int pos,int ok); // self
+void clif_misceffect(struct block_list* bl,int type); // area
+void clif_changeoption(struct block_list* bl); // area
+void clif_changeoption2(struct block_list* bl); // area
+void clif_useitemack(struct map_session_data *sd,int index,int amount,bool ok); // self
+void clif_GlobalMessage(struct block_list* bl, const char* message);
+void clif_createchat(struct map_session_data* sd, int flag); // self
+void clif_dispchat(struct chat_data* cd, int fd); // area or fd
+void clif_joinchatfail(struct map_session_data *sd,int flag); // self
+void clif_joinchatok(struct map_session_data *sd,struct chat_data* cd); // self
+void clif_addchat(struct chat_data* cd,struct map_session_data *sd); // chat
+void clif_changechatowner(struct chat_data* cd, struct map_session_data* sd); // chat
+void clif_clearchat(struct chat_data *cd,int fd); // area or fd
+void clif_leavechat(struct chat_data* cd, struct map_session_data* sd, bool flag); // chat
+void clif_changechatstatus(struct chat_data* cd); // chat
+void clif_refresh(struct map_session_data *sd); // self
void clif_fame_blacksmith(struct map_session_data *sd, int points);
void clif_fame_alchemist(struct map_session_data *sd, int points);
void clif_fame_taekwon(struct map_session_data *sd, int points);
void clif_emotion(struct block_list *bl,int type);
-void clif_talkiebox(struct block_list *bl, const char *talkie);
+void clif_talkiebox(struct block_list* bl, const char* talkie);
void clif_wedding_effect(struct block_list *bl);
-void clif_divorced(struct map_session_data *sd, const char *name);
+void clif_divorced(struct map_session_data* sd, const char* name);
void clif_callpartner(struct map_session_data *sd);
-void clif_playBGM(struct map_session_data *sd, const char *name);
-void clif_soundeffect(struct map_session_data *sd, struct block_list *bl, const char *name, int type);
-void clif_soundeffectall(struct block_list *bl, const char *name, int type, enum send_target coverage);
+void clif_playBGM(struct map_session_data* sd, const char* name);
+void clif_soundeffect(struct map_session_data* sd, struct block_list* bl, const char* name, int type);
+void clif_soundeffectall(struct block_list* bl, const char* name, int type, enum send_target coverage);
void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, int target_id, unsigned int tick);
void clif_parse_LoadEndAck(int fd,struct map_session_data *sd);
void clif_hotkeys_send(struct map_session_data *sd);
// trade
-void clif_traderequest(struct map_session_data *sd, const char *name);
-void clif_tradestart(struct map_session_data *sd, uint8 type);
-void clif_tradeadditem(struct map_session_data *sd, struct map_session_data *tsd, int index, int amount);
-void clif_tradeitemok(struct map_session_data *sd, int index, int fail);
-void clif_tradedeal_lock(struct map_session_data *sd, int fail);
-void clif_tradecancelled(struct map_session_data *sd);
-void clif_tradecompleted(struct map_session_data *sd, int fail);
-void clif_tradeundo(struct map_session_data *sd);
+void clif_traderequest(struct map_session_data* sd, const char* name);
+void clif_tradestart(struct map_session_data* sd, uint8 type);
+void clif_tradeadditem(struct map_session_data* sd, struct map_session_data* tsd, int index, int amount);
+void clif_tradeitemok(struct map_session_data* sd, int index, int fail);
+void clif_tradedeal_lock(struct map_session_data* sd, int fail);
+void clif_tradecancelled(struct map_session_data* sd);
+void clif_tradecompleted(struct map_session_data* sd, int fail);
+void clif_tradeundo(struct map_session_data* sd);
// storage
-void clif_storagelist(struct map_session_data *sd, struct item *items, int items_length);
-void clif_updatestorageamount(struct map_session_data *sd, int amount, int max_amount);
-void clif_storageitemadded(struct map_session_data *sd, struct item *i, int index, int amount);
-void clif_storageitemremoved(struct map_session_data *sd, int index, int amount);
-void clif_storageclose(struct map_session_data *sd);
+void clif_storagelist(struct map_session_data* sd, struct item* items, int items_length);
+void clif_updatestorageamount(struct map_session_data* sd, int amount, int max_amount);
+void clif_storageitemadded(struct map_session_data* sd, struct item* i, int index, int amount);
+void clif_storageitemremoved(struct map_session_data* sd, int index, int amount);
+void clif_storageclose(struct map_session_data* sd);
-int clif_insight(struct block_list *bl,va_list ap); // map_forallinmovearea callback
-int clif_outsight(struct block_list *bl,va_list ap); // map_forallinmovearea callback
+int clif_insight(struct block_list *bl,va_list ap); // map_forallinmovearea callback
+int clif_outsight(struct block_list *bl,va_list ap); // map_forallinmovearea callback
void clif_class_change(struct block_list *bl,int class_,int type);
#define clif_mob_class_change(md, class_) clif_class_change(&md->bl, class_, 1)
@@ -428,8 +430,8 @@ void clif_skillinfo(struct map_session_data *sd,int skill, int inf);
void clif_addskill(struct map_session_data *sd, int id);
void clif_deleteskill(struct map_session_data *sd, int id);
-void clif_skillcasting(struct block_list *bl, int src_id, int dst_id, int dst_x, int dst_y, int skill_num, int property, int casttime);
-void clif_skillcastcancel(struct block_list *bl);
+void clif_skillcasting(struct block_list* bl, int src_id, int dst_id, int dst_x, int dst_y, int skill_num, int property, int casttime);
+void clif_skillcastcancel(struct block_list* bl);
void clif_skill_fail(struct map_session_data *sd,int skill_id,enum useskill_fail_cause cause,int btype);
void clif_skill_cooldown(struct map_session_data *sd, int skillid, unsigned int tick);
int clif_skill_damage(struct block_list *src,struct block_list *dst,unsigned int tick,int sdelay,int ddelay,int damage,int div,int skill_id,int skill_lv,int type);
@@ -437,18 +439,18 @@ int clif_skill_damage(struct block_list *src,struct block_list *dst,unsigned int
int clif_skill_nodamage(struct block_list *src,struct block_list *dst,int skill_id,int heal,int fail);
void clif_skill_poseffect(struct block_list *src,int skill_id,int val,int x,int y,int tick);
void clif_skill_estimation(struct map_session_data *sd,struct block_list *dst);
-void clif_skill_warppoint(struct map_session_data *sd, short skill_num, short skill_lv, unsigned short map1, unsigned short map2, unsigned short map3, unsigned short map4);
-void clif_skill_memomessage(struct map_session_data *sd, int type);
+void clif_skill_warppoint(struct map_session_data* sd, short skill_num, short skill_lv, unsigned short map1, unsigned short map2, unsigned short map3, unsigned short map4);
+void clif_skill_memomessage(struct map_session_data* sd, int type);
void clif_skill_teleportmessage(struct map_session_data *sd, int type);
void clif_skill_produce_mix_list(struct map_session_data *sd, int skillid, int trigger);
void clif_cooking_list(struct map_session_data *sd, int trigger, int skill_id, int qty, int list_type);
-void clif_produceeffect(struct map_session_data *sd,int flag,int nameid);
+void clif_produceeffect(struct map_session_data* sd,int flag,int nameid);
void clif_skill_setunit(struct skill_unit *unit);
void clif_skill_delunit(struct skill_unit *unit);
-void clif_skillunit_update(struct block_list *bl);
+void clif_skillunit_update(struct block_list* bl);
void clif_autospell(struct map_session_data *sd,int skilllv);
void clif_devotion(struct block_list *src, struct map_session_data *tsd);
@@ -460,10 +462,10 @@ void clif_changemapcell(int fd, int m, int x, int y, int type, enum send_target
#define clif_status_load(bl, type, flag) clif_status_change((bl), (type), (flag), 0, 0, 0, 0)
void clif_status_change(struct block_list *bl,int type,int flag,int tick,int val1, int val2, int val3);
-void clif_wis_message(int fd, const char *nick, const char *mes, int mes_len);
+void clif_wis_message(int fd, const char* nick, const char* mes, int mes_len);
void clif_wis_end(int fd, int flag);
-void clif_solved_charname(int fd, int charid, const char *name);
+void clif_solved_charname(int fd, int charid, const char* name);
void clif_charnameack(int fd, struct block_list *bl);
void clif_charnameupdate(struct map_session_data *ssd);
@@ -482,7 +484,7 @@ void clif_item_identify_list(struct map_session_data *sd);
void clif_item_identified(struct map_session_data *sd,int idx,int flag);
void clif_item_repair_list(struct map_session_data *sd, struct map_session_data *dstsd, int lv);
void clif_item_repaireffect(struct map_session_data *sd, int idx, int flag);
-void clif_item_damaged(struct map_session_data *sd, unsigned short position);
+void clif_item_damaged(struct map_session_data* sd, unsigned short position);
void clif_item_refine_list(struct map_session_data *sd);
void clif_item_skill(struct map_session_data *sd,int skillid,int skilllv);
@@ -490,29 +492,29 @@ void clif_item_skill(struct map_session_data *sd,int skillid,int skilllv);
void clif_mvp_effect(struct map_session_data *sd);
void clif_mvp_item(struct map_session_data *sd,int nameid);
void clif_mvp_exp(struct map_session_data *sd, unsigned int exp);
-void clif_mvp_noitem(struct map_session_data *sd);
+void clif_mvp_noitem(struct map_session_data* sd);
void clif_changed_dir(struct block_list *bl, enum send_target target);
// vending
-void clif_openvendingreq(struct map_session_data *sd, int num);
-void clif_showvendingboard(struct block_list *bl, const char *message, int fd);
-void clif_closevendingboard(struct block_list *bl, int fd);
-void clif_vendinglist(struct map_session_data *sd, int id, struct s_vending *vending);
-void clif_buyvending(struct map_session_data *sd, int index, int amount, int fail);
-void clif_openvending(struct map_session_data *sd, int id, struct s_vending *vending);
-void clif_vendingreport(struct map_session_data *sd, int index, int amount);
+void clif_openvendingreq(struct map_session_data* sd, int num);
+void clif_showvendingboard(struct block_list* bl, const char* message, int fd);
+void clif_closevendingboard(struct block_list* bl, int fd);
+void clif_vendinglist(struct map_session_data* sd, int id, struct s_vending* vending);
+void clif_buyvending(struct map_session_data* sd, int index, int amount, int fail);
+void clif_openvending(struct map_session_data* sd, int id, struct s_vending* vending);
+void clif_vendingreport(struct map_session_data* sd, int index, int amount);
void clif_movetoattack(struct map_session_data *sd,struct block_list *bl);
// party
void clif_party_created(struct map_session_data *sd,int result);
void clif_party_member_info(struct party_data *p, struct map_session_data *sd);
-void clif_party_info(struct party_data *p, struct map_session_data *sd);
+void clif_party_info(struct party_data* p, struct map_session_data *sd);
void clif_party_invite(struct map_session_data *sd,struct map_session_data *tsd);
-void clif_party_inviteack(struct map_session_data *sd, const char *nick, int result);
+void clif_party_inviteack(struct map_session_data* sd, const char* nick, int result);
void clif_party_option(struct party_data *p,struct map_session_data *sd,int flag);
-void clif_party_withdraw(struct party_data *p, struct map_session_data *sd, int account_id, const char *name, int flag);
-void clif_party_message(struct party_data *p, int account_id, const char *mes, int len);
+void clif_party_withdraw(struct party_data* p, struct map_session_data* sd, int account_id, const char* name, int flag);
+void clif_party_message(struct party_data* p, int account_id, const char* mes, int len);
void clif_party_xy(struct map_session_data *sd);
void clif_party_xy_single(int fd, struct map_session_data *sd);
void clif_party_hp(struct map_session_data *sd);
@@ -525,18 +527,18 @@ void clif_guild_masterormember(struct map_session_data *sd);
void clif_guild_basicinfo(struct map_session_data *sd);
void clif_guild_allianceinfo(struct map_session_data *sd);
void clif_guild_memberlist(struct map_session_data *sd);
-void clif_guild_skillinfo(struct map_session_data *sd);
+void clif_guild_skillinfo(struct map_session_data* sd);
void clif_guild_send_onlineinfo(struct map_session_data *sd); //[LuzZza]
void clif_guild_memberlogin_notice(struct guild *g,int idx,int flag);
void clif_guild_invite(struct map_session_data *sd,struct guild *g);
void clif_guild_inviteack(struct map_session_data *sd,int flag);
void clif_guild_leave(struct map_session_data *sd,const char *name,const char *mes);
-void clif_guild_expulsion(struct map_session_data *sd, const char *name, const char *mes, int account_id);
+void clif_guild_expulsion(struct map_session_data* sd, const char* name, const char* mes, int account_id);
void clif_guild_positionchanged(struct guild *g,int idx);
void clif_guild_memberpositionchanged(struct guild *g,int idx);
void clif_guild_emblem(struct map_session_data *sd,struct guild *g);
-void clif_guild_emblem_area(struct block_list *bl);
-void clif_guild_notice(struct map_session_data *sd, struct guild *g);
+void clif_guild_emblem_area(struct block_list* bl);
+void clif_guild_notice(struct map_session_data* sd, struct guild* g);
void clif_guild_message(struct guild *g,int account_id,const char *mes,int len);
int clif_guild_skillup(struct map_session_data *sd,int skill_num,int lv);
void clif_guild_reqalliance(struct map_session_data *sd,int account_id,const char *name);
@@ -567,15 +569,15 @@ void clif_instance_leave(int fd);
void clif_font(struct map_session_data *sd);
// atcommand
-void clif_displaymessage(const int fd, const char *mes);
+void clif_displaymessage(const int fd, const char* mes);
void clif_disp_onlyself(struct map_session_data *sd, const char *mes, int len);
-void clif_disp_message(struct block_list *src, const char *mes, int len, enum send_target target);
-void clif_broadcast(struct block_list *bl, const char *mes, int len, int type, enum send_target target);
-void clif_MainChatMessage(const char *message);
-void clif_broadcast2(struct block_list *bl, const char *mes, int len, unsigned long fontColor, short fontType, short fontSize, short fontAlign, short fontY, enum send_target target);
+void clif_disp_message(struct block_list* src, const char* mes, int len, enum send_target target);
+void clif_broadcast(struct block_list* bl, const char* mes, int len, int type, enum send_target target);
+void clif_MainChatMessage(const char* message);
+void clif_broadcast2(struct block_list* bl, const char* mes, int len, unsigned long fontColor, short fontType, short fontSize, short fontAlign, short fontY, enum send_target target);
void clif_heal(int fd,int type,int val);
void clif_resurrection(struct block_list *bl,int type);
-void clif_map_property(struct map_session_data *sd, enum map_property property);
+void clif_map_property(struct map_session_data* sd, enum map_property property);
void clif_pvpset(struct map_session_data *sd, int pvprank, int pvpnum,int type);
void clif_map_property_mapall(int map, enum map_property property);
void clif_refine(int fd, int fail, int index, int val);
@@ -586,7 +588,7 @@ void clif_catch_process(struct map_session_data *sd);
void clif_pet_roulette(struct map_session_data *sd,int data);
void clif_sendegg(struct map_session_data *sd);
void clif_send_petstatus(struct map_session_data *sd);
-void clif_send_petdata(struct map_session_data *sd, struct pet_data *pd, int type, int param);
+void clif_send_petdata(struct map_session_data* sd, struct pet_data* pd, int type, int param);
#define clif_pet_equip(sd, pd) clif_send_petdata(sd, pd, 3, (pd)->vd.head_bottom)
#define clif_pet_equip_area(pd) clif_send_petdata(NULL, pd, 3, (pd)->vd.head_bottom)
#define clif_pet_performance(pd, param) clif_send_petdata(NULL, pd, 4, param)
@@ -599,26 +601,26 @@ void clif_friendslist_send(struct map_session_data *sd);
void clif_friendslist_reqack(struct map_session_data *sd, struct map_session_data *f_sd, int type);
void clif_weather(int m); // [Valaris]
-void clif_specialeffect(struct block_list *bl, int type, enum send_target target); // special effects [Valaris]
-void clif_specialeffect_single(struct block_list *bl, int type, int fd);
-void clif_messagecolor(struct block_list *bl, unsigned long color, const char *msg); // Mob/Npc color talk [SnakeDrak]
-void clif_message(struct block_list *bl, const char *msg);
-void clif_specialeffect_value(struct block_list *bl, int effect_id, int num, send_target target);
+void clif_specialeffect(struct block_list* bl, int type, enum send_target target); // special effects [Valaris]
+void clif_specialeffect_single(struct block_list* bl, int type, int fd);
+void clif_messagecolor(struct block_list* bl, unsigned long color, const char* msg); // Mob/Npc color talk [SnakeDrak]
+void clif_message(struct block_list* bl, const char* msg);
+void clif_specialeffect_value(struct block_list* bl, int effect_id, int num, send_target target);
void clif_GM_kickack(struct map_session_data *sd, int id);
void clif_GM_kick(struct map_session_data *sd,struct map_session_data *tsd);
-void clif_manner_message(struct map_session_data *sd, uint32 type);
-void clif_GM_silence(struct map_session_data *sd, struct map_session_data *tsd, uint8 type);
+void clif_manner_message(struct map_session_data* sd, uint32 type);
+void clif_GM_silence(struct map_session_data* sd, struct map_session_data* tsd, uint8 type);
-void clif_disp_overhead(struct map_session_data *sd, const char *mes);
+void clif_disp_overhead(struct map_session_data *sd, const char* mes);
-void clif_get_weapon_view(struct map_session_data *sd, unsigned short *rhand, unsigned short *lhand);
+void clif_get_weapon_view(struct map_session_data* sd, unsigned short *rhand, unsigned short *lhand);
void clif_party_xy_remove(struct map_session_data *sd); //Fix for minimap [Kevin]
void clif_gospel_info(struct map_session_data *sd, int type);
void clif_feel_req(int fd, struct map_session_data *sd, int skilllv);
-void clif_starskill(struct map_session_data *sd, const char *mapname, int monster_id, unsigned char star, unsigned char result);
-void clif_feel_info(struct map_session_data *sd, unsigned char feel_level, unsigned char type);
+void clif_starskill(struct map_session_data* sd, const char* mapname, int monster_id, unsigned char star, unsigned char result);
+void clif_feel_info(struct map_session_data* sd, unsigned char feel_level, unsigned char type);
void clif_hate_info(struct map_session_data *sd, unsigned char hate_level,int class_, unsigned char type);
void clif_mission_info(struct map_session_data *sd, int mob_id, unsigned char progress);
void clif_feel_hate_reset(struct map_session_data *sd);
@@ -626,30 +628,30 @@ void clif_feel_hate_reset(struct map_session_data *sd);
// [blackhole89]
void clif_hominfo(struct map_session_data *sd, struct homun_data *hd, int flag);
int clif_homskillinfoblock(struct map_session_data *sd);
-void clif_homskillup(struct map_session_data *sd, int skill_num); //[orn]
-int clif_hom_food(struct map_session_data *sd,int foodid,int fail); //[orn]
-void clif_send_homdata(struct map_session_data *sd, int state, int param); //[orn]
+void clif_homskillup(struct map_session_data *sd, int skill_num); //[orn]
+int clif_hom_food(struct map_session_data *sd,int foodid,int fail); //[orn]
+void clif_send_homdata(struct map_session_data *sd, int state, int param); //[orn]
-void clif_equiptickack(struct map_session_data *sd, int flag);
-void clif_viewequip_ack(struct map_session_data *sd, struct map_session_data *tsd);
-void clif_viewequip_fail(struct map_session_data *sd);
-void clif_equipcheckbox(struct map_session_data *sd);
+void clif_equiptickack(struct map_session_data* sd, int flag);
+void clif_viewequip_ack(struct map_session_data* sd, struct map_session_data* tsd);
+void clif_viewequip_fail(struct map_session_data* sd);
+void clif_equipcheckbox(struct map_session_data* sd);
-void clif_msg(struct map_session_data *sd, unsigned short id);
-void clif_msg_value(struct map_session_data *sd, unsigned short id, int value);
-void clif_msg_skill(struct map_session_data *sd, unsigned short skill_id, int msg_id);
+void clif_msg(struct map_session_data* sd, unsigned short id);
+void clif_msg_value(struct map_session_data* sd, unsigned short id, int value);
+void clif_msg_skill(struct map_session_data* sd, unsigned short skill_id, int msg_id);
//quest system [Kevin] [Inkfish]
-void clif_quest_send_list(struct map_session_data *sd);
-void clif_quest_send_mission(struct map_session_data *sd);
-void clif_quest_add(struct map_session_data *sd, struct quest *qd, int index);
-void clif_quest_delete(struct map_session_data *sd, int quest_id);
-void clif_quest_update_status(struct map_session_data *sd, int quest_id, bool active);
-void clif_quest_update_objective(struct map_session_data *sd, struct quest *qd, int index);
+void clif_quest_send_list(struct map_session_data * sd);
+void clif_quest_send_mission(struct map_session_data * sd);
+void clif_quest_add(struct map_session_data * sd, struct quest * qd, int index);
+void clif_quest_delete(struct map_session_data * sd, int quest_id);
+void clif_quest_update_status(struct map_session_data * sd, int quest_id, bool active);
+void clif_quest_update_objective(struct map_session_data * sd, struct quest * qd, int index);
void clif_quest_show_event(struct map_session_data *sd, struct block_list *bl, short state, short color);
void clif_displayexp(struct map_session_data *sd, unsigned int exp, char type, bool quest);
-int clif_send(const uint8 *buf, int len, struct block_list *bl, enum send_target type);
+int clif_send(const uint8* buf, int len, struct block_list* bl, enum send_target type);
int do_init_clif(void);
void do_final_clif(void);
@@ -678,7 +680,7 @@ void clif_Adopt_reply(struct map_session_data *sd, int type);
// MERCENARIES
void clif_mercenary_info(struct map_session_data *sd);
void clif_mercenary_skillblock(struct map_session_data *sd);
-void clif_mercenary_message(struct map_session_data *sd, int message);
+void clif_mercenary_message(struct map_session_data* sd, int message);
void clif_mercenary_updatestatus(struct map_session_data *sd, int type);
// RENTAL SYSTEM
@@ -689,40 +691,40 @@ void clif_rental_expired(int fd, int index, int nameid);
void clif_readbook(int fd, int book_id, int page);
// Show Picker
-void clif_party_show_picker(struct map_session_data *sd, struct item *item_data);
+void clif_party_show_picker(struct map_session_data * sd, struct item * item_data);
// Progress Bar [Inkfish]
-void clif_progressbar(struct map_session_data *sd, unsigned long color, unsigned int second);
-void clif_progressbar_abort(struct map_session_data *sd);
+void clif_progressbar(struct map_session_data * sd, unsigned long color, unsigned int second);
+void clif_progressbar_abort(struct map_session_data * sd);
void clif_PartyBookingRegisterAck(struct map_session_data *sd, int flag);
-void clif_PartyBookingDeleteAck(struct map_session_data *sd, int flag);
-void clif_PartyBookingSearchAck(int fd, struct party_booking_ad_info **results, int count, bool more_result);
-void clif_PartyBookingUpdateNotify(struct map_session_data *sd, struct party_booking_ad_info *pb_ad);
-void clif_PartyBookingDeleteNotify(struct map_session_data *sd, int index);
-void clif_PartyBookingInsertNotify(struct map_session_data *sd, struct party_booking_ad_info *pb_ad);
+void clif_PartyBookingDeleteAck(struct map_session_data* sd, int flag);
+void clif_PartyBookingSearchAck(int fd, struct party_booking_ad_info** results, int count, bool more_result);
+void clif_PartyBookingUpdateNotify(struct map_session_data* sd, struct party_booking_ad_info* pb_ad);
+void clif_PartyBookingDeleteNotify(struct map_session_data* sd, int index);
+void clif_PartyBookingInsertNotify(struct map_session_data* sd, struct party_booking_ad_info* pb_ad);
-void clif_showdigit(struct map_session_data *sd, unsigned char type, int value);
+void clif_showdigit(struct map_session_data* sd, unsigned char type, int value);
/// Buying Store System
-void clif_buyingstore_open(struct map_session_data *sd);
-void clif_buyingstore_open_failed(struct map_session_data *sd, unsigned short result, unsigned int weight);
-void clif_buyingstore_myitemlist(struct map_session_data *sd);
-void clif_buyingstore_entry(struct map_session_data *sd);
-void clif_buyingstore_entry_single(struct map_session_data *sd, struct map_session_data *pl_sd);
-void clif_buyingstore_disappear_entry(struct map_session_data *sd);
-void clif_buyingstore_disappear_entry_single(struct map_session_data *sd, struct map_session_data *pl_sd);
-void clif_buyingstore_itemlist(struct map_session_data *sd, struct map_session_data *pl_sd);
-void clif_buyingstore_trade_failed_buyer(struct map_session_data *sd, short result);
-void clif_buyingstore_update_item(struct map_session_data *sd, unsigned short nameid, unsigned short amount);
-void clif_buyingstore_delete_item(struct map_session_data *sd, short index, unsigned short amount, int price);
-void clif_buyingstore_trade_failed_seller(struct map_session_data *sd, short result, unsigned short nameid);
+void clif_buyingstore_open(struct map_session_data* sd);
+void clif_buyingstore_open_failed(struct map_session_data* sd, unsigned short result, unsigned int weight);
+void clif_buyingstore_myitemlist(struct map_session_data* sd);
+void clif_buyingstore_entry(struct map_session_data* sd);
+void clif_buyingstore_entry_single(struct map_session_data* sd, struct map_session_data* pl_sd);
+void clif_buyingstore_disappear_entry(struct map_session_data* sd);
+void clif_buyingstore_disappear_entry_single(struct map_session_data* sd, struct map_session_data* pl_sd);
+void clif_buyingstore_itemlist(struct map_session_data* sd, struct map_session_data* pl_sd);
+void clif_buyingstore_trade_failed_buyer(struct map_session_data* sd, short result);
+void clif_buyingstore_update_item(struct map_session_data* sd, unsigned short nameid, unsigned short amount);
+void clif_buyingstore_delete_item(struct map_session_data* sd, short index, unsigned short amount, int price);
+void clif_buyingstore_trade_failed_seller(struct map_session_data* sd, short result, unsigned short nameid);
/// Search Store System
-void clif_search_store_info_ack(struct map_session_data *sd);
-void clif_search_store_info_failed(struct map_session_data *sd, unsigned char reason);
-void clif_open_search_store_info(struct map_session_data *sd);
-void clif_search_store_info_click_ack(struct map_session_data *sd, short x, short y);
+void clif_search_store_info_ack(struct map_session_data* sd);
+void clif_search_store_info_failed(struct map_session_data* sd, unsigned char reason);
+void clif_open_search_store_info(struct map_session_data* sd);
+void clif_search_store_info_click_ack(struct map_session_data* sd, short x, short y);
/**
* 3CeAM
**/
@@ -731,7 +733,7 @@ void clif_msgtable_num(int fd, int line, int num);
int clif_elementalconverter_list(struct map_session_data *sd);
-void clif_millenniumshield(struct map_session_data *sd, short shields);
+void clif_millenniumshield(struct map_session_data *sd, short shields );
int clif_spellbook_list(struct map_session_data *sd);
@@ -745,25 +747,25 @@ int clif_status_load_notick(struct block_list *bl,int type,int flag,int val1, in
int clif_status_load_single(int fd, int id,int type,int flag,int val1, int val2, int val3);
-int clif_skill_itemlistwindow(struct map_session_data *sd, int skill_id, int skill_lv);
+int clif_skill_itemlistwindow( struct map_session_data *sd, int skill_id, int skill_lv );
void clif_elemental_info(struct map_session_data *sd);
void clif_elemental_updatestatus(struct map_session_data *sd, int type);
void clif_talisman(struct map_session_data *sd, short type);
-void clif_snap(struct block_list *bl, short x, short y);
-void clif_monster_hp_bar(struct mob_data *md, int fd);
+void clif_snap( struct block_list *bl, short x, short y );
+void clif_monster_hp_bar( struct mob_data* md, int fd );
/**
* Color Table
**/
enum clif_colors {
- COLOR_RED,
+ COLOR_RED,
- COLOR_MAX
+ COLOR_MAX
};
unsigned long color_table[COLOR_MAX];
-int clif_colormes(struct map_session_data *sd, enum clif_colors color, const char *msg);
+int clif_colormes(struct map_session_data * sd, enum clif_colors color, const char* msg);
#define clif_menuskill_clear(sd) (sd)->menuskill_id = (sd)->menuskill_val = (sd)->menuskill_val2 = 0;
diff --git a/src/map/date.c b/src/map/date.c
index 255fabf18..9f2bc4bee 100644
--- a/src/map/date.c
+++ b/src/map/date.c
@@ -6,66 +6,66 @@
int date_get_year(void)
{
- time_t t;
- struct tm *lt;
- t = time(NULL);
- lt = localtime(&t);
- return lt->tm_year+1900;
+ time_t t;
+ struct tm * lt;
+ t = time(NULL);
+ lt = localtime(&t);
+ return lt->tm_year+1900;
}
int date_get_month(void)
{
- time_t t;
- struct tm *lt;
- t = time(NULL);
- lt = localtime(&t);
- return lt->tm_mon+1;
+ time_t t;
+ struct tm * lt;
+ t = time(NULL);
+ lt = localtime(&t);
+ return lt->tm_mon+1;
}
int date_get_day(void)
{
- time_t t;
- struct tm *lt;
- t = time(NULL);
- lt = localtime(&t);
- return lt->tm_mday;
+ time_t t;
+ struct tm * lt;
+ t = time(NULL);
+ lt = localtime(&t);
+ return lt->tm_mday;
}
int date_get_hour(void)
{
- time_t t;
- struct tm *lt;
- t = time(NULL);
- lt = localtime(&t);
- return lt->tm_hour;
+ time_t t;
+ struct tm * lt;
+ t = time(NULL);
+ lt = localtime(&t);
+ return lt->tm_hour;
}
int date_get_min(void)
{
- time_t t;
- struct tm *lt;
- t = time(NULL);
- lt = localtime(&t);
- return lt->tm_min;
+ time_t t;
+ struct tm * lt;
+ t = time(NULL);
+ lt = localtime(&t);
+ return lt->tm_min;
}
int date_get_sec(void)
{
- time_t t;
- struct tm *lt;
- t = time(NULL);
- lt = localtime(&t);
- return lt->tm_sec;
+ time_t t;
+ struct tm * lt;
+ t = time(NULL);
+ lt = localtime(&t);
+ return lt->tm_sec;
}
int is_day_of_sun(void)
{
- return date_get_day()%2 == 0;
+ return date_get_day()%2 == 0;
}
int is_day_of_moon(void)
{
- return date_get_day()%2 == 1;
+ return date_get_day()%2 == 1;
}
int is_day_of_star(void)
{
- return date_get_day()%5 == 0;
+ return date_get_day()%5 == 0;
}
diff --git a/src/map/duel.c b/src/map/duel.c
index 808193dc0..c13d004b0 100644
--- a/src/map/duel.c
+++ b/src/map/duel.c
@@ -19,157 +19,157 @@ int duel_count = 0;
/*==========================================
* Duel organizing functions [LuzZza]
*------------------------------------------*/
-void duel_savetime(struct map_session_data *sd)
+void duel_savetime(struct map_session_data* sd)
{
- time_t timer;
- struct tm *t;
-
- time(&timer);
- t = localtime(&timer);
-
- pc_setglobalreg(sd, "PC_LAST_DUEL_TIME", t->tm_mday*24*60 + t->tm_hour*60 + t->tm_min);
+ time_t timer;
+ struct tm *t;
+
+ time(&timer);
+ t = localtime(&timer);
+
+ pc_setglobalreg(sd, "PC_LAST_DUEL_TIME", t->tm_mday*24*60 + t->tm_hour*60 + t->tm_min);
}
-int duel_checktime(struct map_session_data *sd)
+int duel_checktime(struct map_session_data* sd)
{
- int diff;
- time_t timer;
- struct tm *t;
-
- time(&timer);
+ int diff;
+ time_t timer;
+ struct tm *t;
+
+ time(&timer);
t = localtime(&timer);
-
- diff = t->tm_mday*24*60 + t->tm_hour*60 + t->tm_min - pc_readglobalreg(sd, "PC_LAST_DUEL_TIME");
-
- return !(diff >= 0 && diff < battle_config.duel_time_interval);
+
+ diff = t->tm_mday*24*60 + t->tm_hour*60 + t->tm_min - pc_readglobalreg(sd, "PC_LAST_DUEL_TIME");
+
+ return !(diff >= 0 && diff < battle_config.duel_time_interval);
}
-static int duel_showinfo_sub(struct map_session_data *sd, va_list va)
+static int duel_showinfo_sub(struct map_session_data* sd, va_list va)
{
- struct map_session_data *ssd = va_arg(va, struct map_session_data *);
- int *p = va_arg(va, int *);
- char output[256];
-
- if (sd->duel_group != ssd->duel_group) return 0;
-
- sprintf(output, " %d. %s", ++(*p), sd->status.name);
- clif_disp_onlyself(ssd, output, strlen(output));
- return 1;
+ struct map_session_data *ssd = va_arg(va, struct map_session_data*);
+ int *p = va_arg(va, int*);
+ char output[256];
+
+ if (sd->duel_group != ssd->duel_group) return 0;
+
+ sprintf(output, " %d. %s", ++(*p), sd->status.name);
+ clif_disp_onlyself(ssd, output, strlen(output));
+ return 1;
}
-void duel_showinfo(const unsigned int did, struct map_session_data *sd)
+void duel_showinfo(const unsigned int did, struct map_session_data* sd)
{
- int p=0;
- char output[256];
-
- if (duel_list[did].max_players_limit > 0)
- sprintf(output, msg_txt(370), //" -- Duels: %d/%d, Members: %d/%d, Max players: %d --"
- did, duel_count,
- duel_list[did].members_count,
- duel_list[did].members_count + duel_list[did].invites_count,
- duel_list[did].max_players_limit);
- else
- sprintf(output, msg_txt(371), //" -- Duels: %d/%d, Members: %d/%d --"
- did, duel_count,
- duel_list[did].members_count,
- duel_list[did].members_count + duel_list[did].invites_count);
-
- clif_disp_onlyself(sd, output, strlen(output));
- map_foreachpc(duel_showinfo_sub, sd, &p);
+ int p=0;
+ char output[256];
+
+ if(duel_list[did].max_players_limit > 0)
+ sprintf(output, msg_txt(370), //" -- Duels: %d/%d, Members: %d/%d, Max players: %d --"
+ did, duel_count,
+ duel_list[did].members_count,
+ duel_list[did].members_count + duel_list[did].invites_count,
+ duel_list[did].max_players_limit);
+ else
+ sprintf(output, msg_txt(371), //" -- Duels: %d/%d, Members: %d/%d --"
+ did, duel_count,
+ duel_list[did].members_count,
+ duel_list[did].members_count + duel_list[did].invites_count);
+
+ clif_disp_onlyself(sd, output, strlen(output));
+ map_foreachpc(duel_showinfo_sub, sd, &p);
}
-int duel_create(struct map_session_data *sd, const unsigned int maxpl)
+int duel_create(struct map_session_data* sd, const unsigned int maxpl)
{
- int i=1;
- char output[256];
-
- while (duel_list[i].members_count > 0 && i < MAX_DUEL) i++;
- if (i == MAX_DUEL) return 0;
-
- duel_count++;
- sd->duel_group = i;
- duel_list[i].members_count++;
- duel_list[i].invites_count = 0;
- duel_list[i].max_players_limit = maxpl;
-
- strcpy(output, msg_txt(372)); // " -- Duel has been created (@invite/@leave) --"
- clif_disp_onlyself(sd, output, strlen(output));
-
- clif_map_property(sd, MAPPROPERTY_FREEPVPZONE);
- //clif_misceffect2(&sd->bl, 159);
- return i;
+ int i=1;
+ char output[256];
+
+ while(duel_list[i].members_count > 0 && i < MAX_DUEL) i++;
+ if(i == MAX_DUEL) return 0;
+
+ duel_count++;
+ sd->duel_group = i;
+ duel_list[i].members_count++;
+ duel_list[i].invites_count = 0;
+ duel_list[i].max_players_limit = maxpl;
+
+ strcpy(output, msg_txt(372)); // " -- Duel has been created (@invite/@leave) --"
+ clif_disp_onlyself(sd, output, strlen(output));
+
+ clif_map_property(sd, MAPPROPERTY_FREEPVPZONE);
+ //clif_misceffect2(&sd->bl, 159);
+ return i;
}
-void duel_invite(const unsigned int did, struct map_session_data *sd, struct map_session_data *target_sd)
+void duel_invite(const unsigned int did, struct map_session_data* sd, struct map_session_data* target_sd)
{
- char output[256];
-
- // " -- Player %s invites %s to duel --"
- sprintf(output, msg_txt(373), sd->status.name, target_sd->status.name);
- clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
-
- target_sd->duel_invite = did;
- duel_list[did].invites_count++;
-
- // "Blue -- Player %s invites you to PVP duel (@accept/@reject) --"
- sprintf(output, msg_txt(374), sd->status.name);
- clif_broadcast((struct block_list *)target_sd, output, strlen(output)+1, 0x10, SELF);
+ char output[256];
+
+ // " -- Player %s invites %s to duel --"
+ sprintf(output, msg_txt(373), sd->status.name, target_sd->status.name);
+ clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
+
+ target_sd->duel_invite = did;
+ duel_list[did].invites_count++;
+
+ // "Blue -- Player %s invites you to PVP duel (@accept/@reject) --"
+ sprintf(output, msg_txt(374), sd->status.name);
+ clif_broadcast((struct block_list *)target_sd, output, strlen(output)+1, 0x10, SELF);
}
-static int duel_leave_sub(struct map_session_data *sd, va_list va)
+static int duel_leave_sub(struct map_session_data* sd, va_list va)
{
- int did = va_arg(va, int);
- if (sd->duel_invite == did)
- sd->duel_invite = 0;
- return 0;
+ int did = va_arg(va, int);
+ if (sd->duel_invite == did)
+ sd->duel_invite = 0;
+ return 0;
}
-void duel_leave(const unsigned int did, struct map_session_data *sd)
+void duel_leave(const unsigned int did, struct map_session_data* sd)
{
- char output[256];
-
- // " <- Player %s has left duel --"
- sprintf(output, msg_txt(375), sd->status.name);
- clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
-
- duel_list[did].members_count--;
-
- if (duel_list[did].members_count == 0) {
- map_foreachpc(duel_leave_sub, did);
- duel_count--;
- }
-
- sd->duel_group = 0;
- duel_savetime(sd);
- clif_map_property(sd, MAPPROPERTY_NOTHING);
+ char output[256];
+
+ // " <- Player %s has left duel --"
+ sprintf(output, msg_txt(375), sd->status.name);
+ clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
+
+ duel_list[did].members_count--;
+
+ if(duel_list[did].members_count == 0) {
+ map_foreachpc(duel_leave_sub, did);
+ duel_count--;
+ }
+
+ sd->duel_group = 0;
+ duel_savetime(sd);
+ clif_map_property(sd, MAPPROPERTY_NOTHING);
}
-void duel_accept(const unsigned int did, struct map_session_data *sd)
+void duel_accept(const unsigned int did, struct map_session_data* sd)
{
- char output[256];
-
- duel_list[did].members_count++;
- sd->duel_group = sd->duel_invite;
- duel_list[did].invites_count--;
- sd->duel_invite = 0;
-
- // " -> Player %s has accepted duel --"
- sprintf(output, msg_txt(376), sd->status.name);
- clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
-
- clif_map_property(sd, MAPPROPERTY_FREEPVPZONE);
- //clif_misceffect2(&sd->bl, 159);
+ char output[256];
+
+ duel_list[did].members_count++;
+ sd->duel_group = sd->duel_invite;
+ duel_list[did].invites_count--;
+ sd->duel_invite = 0;
+
+ // " -> Player %s has accepted duel --"
+ sprintf(output, msg_txt(376), sd->status.name);
+ clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
+
+ clif_map_property(sd, MAPPROPERTY_FREEPVPZONE);
+ //clif_misceffect2(&sd->bl, 159);
}
-void duel_reject(const unsigned int did, struct map_session_data *sd)
+void duel_reject(const unsigned int did, struct map_session_data* sd)
{
- char output[256];
-
- // " -- Player %s has rejected duel --"
- sprintf(output, msg_txt(377), sd->status.name);
- clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
-
- duel_list[did].invites_count--;
- sd->duel_invite = 0;
+ char output[256];
+
+ // " -- Player %s has rejected duel --"
+ sprintf(output, msg_txt(377), sd->status.name);
+ clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
+
+ duel_list[did].invites_count--;
+ sd->duel_invite = 0;
}
void do_final_duel(void)
@@ -178,5 +178,5 @@ void do_final_duel(void)
void do_init_duel(void)
{
- memset(&duel_list[0], 0, sizeof(duel_list));
+ memset(&duel_list[0], 0, sizeof(duel_list));
}
diff --git a/src/map/duel.h b/src/map/duel.h
index aeed77d4f..04d8e4e84 100644
--- a/src/map/duel.h
+++ b/src/map/duel.h
@@ -5,9 +5,9 @@
#define _DUEL_H_
struct duel {
- int members_count;
- int invites_count;
- int max_players_limit;
+ int members_count;
+ int invites_count;
+ int max_players_limit;
};
#define MAX_DUEL 1024
@@ -15,13 +15,13 @@ extern struct duel duel_list[MAX_DUEL];
extern int duel_count;
//Duel functions // [LuzZza]
-int duel_create(struct map_session_data *sd, const unsigned int maxpl);
-void duel_invite(const unsigned int did, struct map_session_data *sd, struct map_session_data *target_sd);
-void duel_accept(const unsigned int did, struct map_session_data *sd);
-void duel_reject(const unsigned int did, struct map_session_data *sd);
-void duel_leave(const unsigned int did, struct map_session_data *sd);
-void duel_showinfo(const unsigned int did, struct map_session_data *sd);
-int duel_checktime(struct map_session_data *sd);
+int duel_create(struct map_session_data* sd, const unsigned int maxpl);
+void duel_invite(const unsigned int did, struct map_session_data* sd, struct map_session_data* target_sd);
+void duel_accept(const unsigned int did, struct map_session_data* sd);
+void duel_reject(const unsigned int did, struct map_session_data* sd);
+void duel_leave(const unsigned int did, struct map_session_data* sd);
+void duel_showinfo(const unsigned int did, struct map_session_data* sd);
+int duel_checktime(struct map_session_data* sd);
void do_init_duel(void);
void do_final_duel(void);
diff --git a/src/map/elemental.c b/src/map/elemental.c
index a28982d72..770047138 100644
--- a/src/map/elemental.c
+++ b/src/map/elemental.c
@@ -39,815 +39,785 @@
struct s_elemental_db elemental_db[MAX_ELEMENTAL_CLASS]; // Elemental Database
-int elemental_search_index(int class_)
-{
- int i;
- ARR_FIND(0, MAX_ELEMENTAL_CLASS, i, elemental_db[i].class_ == class_);
- return (i == MAX_ELEMENTAL_CLASS)?-1:i;
+int elemental_search_index(int class_) {
+ int i;
+ ARR_FIND(0, MAX_ELEMENTAL_CLASS, i, elemental_db[i].class_ == class_);
+ return (i == MAX_ELEMENTAL_CLASS)?-1:i;
}
-bool elemental_class(int class_)
-{
- return (bool)(elemental_search_index(class_) > -1);
+bool elemental_class(int class_) {
+ return (bool)(elemental_search_index(class_) > -1);
}
-struct view_data *elemental_get_viewdata(int class_) {
- int i = elemental_search_index(class_);
- if (i < 0)
- return 0;
-
- return &elemental_db[i].vd;
+struct view_data * elemental_get_viewdata(int class_) {
+ int i = elemental_search_index(class_);
+ if( i < 0 )
+ return 0;
+
+ return &elemental_db[i].vd;
}
-int elemental_create(struct map_session_data *sd, int class_, unsigned int lifetime)
-{
- struct s_elemental ele;
- struct s_elemental_db *db;
- int i;
-
- nullpo_retr(1,sd);
-
- if ((i = elemental_search_index(class_)) < 0)
- return 0;
-
- db = &elemental_db[i];
- memset(&ele,0,sizeof(struct s_elemental));
-
- ele.char_id = sd->status.char_id;
- ele.class_ = class_;
- ele.mode = EL_MODE_PASSIVE; // Initial mode
- ele.hp = db->status.max_hp;
- ele.sp = db->status.max_sp;
- ele.life_time = lifetime;
-
- // Request Char Server to create this elemental
- intif_elemental_create(&ele);
-
- return 1;
+int elemental_create(struct map_session_data *sd, int class_, unsigned int lifetime) {
+ struct s_elemental ele;
+ struct s_elemental_db *db;
+ int i;
+
+ nullpo_retr(1,sd);
+
+ if( (i = elemental_search_index(class_)) < 0 )
+ return 0;
+
+ db = &elemental_db[i];
+ memset(&ele,0,sizeof(struct s_elemental));
+
+ ele.char_id = sd->status.char_id;
+ ele.class_ = class_;
+ ele.mode = EL_MODE_PASSIVE; // Initial mode
+ ele.hp = db->status.max_hp;
+ ele.sp = db->status.max_sp;
+ ele.life_time = lifetime;
+
+ // Request Char Server to create this elemental
+ intif_elemental_create(&ele);
+
+ return 1;
}
-int elemental_get_lifetime(struct elemental_data *ed)
-{
- const struct TimerData *td;
- if (ed == NULL || ed->summon_timer == INVALID_TIMER)
- return 0;
-
- td = get_timer(ed->summon_timer);
- return (td != NULL) ? DIFF_TICK(td->tick, gettick()) : 0;
+int elemental_get_lifetime(struct elemental_data *ed) {
+ const struct TimerData * td;
+ if( ed == NULL || ed->summon_timer == INVALID_TIMER )
+ return 0;
+
+ td = get_timer(ed->summon_timer);
+ return (td != NULL) ? DIFF_TICK(td->tick, gettick()) : 0;
}
-int elemental_save(struct elemental_data *ed)
-{
- ed->elemental.hp = ed->battle_status.hp;
- ed->elemental.sp = ed->battle_status.sp;
- ed->elemental.life_time = elemental_get_lifetime(ed);
-
- intif_elemental_save(&ed->elemental);
- return 1;
+int elemental_save(struct elemental_data *ed) {
+ ed->elemental.hp = ed->battle_status.hp;
+ ed->elemental.sp = ed->battle_status.sp;
+ ed->elemental.life_time = elemental_get_lifetime(ed);
+
+ intif_elemental_save(&ed->elemental);
+ return 1;
}
-static int elemental_summon_end(int tid, unsigned int tick, int id, intptr_t data)
-{
- struct map_session_data *sd;
- struct elemental_data *ed;
-
- if ((sd = map_id2sd(id)) == NULL)
- return 1;
- if ((ed = sd->ed) == NULL)
- return 1;
-
- if (ed->summon_timer != tid) {
- ShowError("elemental_summon_end %d != %d.\n", ed->summon_timer, tid);
- return 0;
- }
-
- ed->summon_timer = INVALID_TIMER;
- elemental_delete(ed, 0); // Elemental's summon time is over.
-
- return 0;
+static int elemental_summon_end(int tid, unsigned int tick, int id, intptr_t data) {
+ struct map_session_data *sd;
+ struct elemental_data *ed;
+
+ if( (sd = map_id2sd(id)) == NULL )
+ return 1;
+ if( (ed = sd->ed) == NULL )
+ return 1;
+
+ if( ed->summon_timer != tid ) {
+ ShowError("elemental_summon_end %d != %d.\n", ed->summon_timer, tid);
+ return 0;
+ }
+
+ ed->summon_timer = INVALID_TIMER;
+ elemental_delete(ed, 0); // Elemental's summon time is over.
+
+ return 0;
}
-void elemental_summon_stop(struct elemental_data *ed)
-{
- nullpo_retv(ed);
- if (ed->summon_timer != INVALID_TIMER)
- delete_timer(ed->summon_timer, elemental_summon_end);
- ed->summon_timer = INVALID_TIMER;
+void elemental_summon_stop(struct elemental_data *ed) {
+ nullpo_retv(ed);
+ if( ed->summon_timer != INVALID_TIMER )
+ delete_timer(ed->summon_timer, elemental_summon_end);
+ ed->summon_timer = INVALID_TIMER;
}
-int elemental_delete(struct elemental_data *ed, int reply)
-{
- struct map_session_data *sd;
-
- nullpo_ret(ed);
-
- sd = ed->master;
- ed->elemental.life_time = 0;
-
- elemental_clean_effect(ed);
- elemental_summon_stop(ed);
-
- if (!sd)
- return unit_free(&ed->bl, 0);
-
- sd->ed = NULL;
- sd->status.ele_id = 0;
-
- return unit_remove_map(&ed->bl, 0);
+int elemental_delete(struct elemental_data *ed, int reply) {
+ struct map_session_data *sd;
+
+ nullpo_ret(ed);
+
+ sd = ed->master;
+ ed->elemental.life_time = 0;
+
+ elemental_clean_effect(ed);
+ elemental_summon_stop(ed);
+
+ if( !sd )
+ return unit_free(&ed->bl, 0);
+
+ sd->ed = NULL;
+ sd->status.ele_id = 0;
+
+ return unit_remove_map(&ed->bl, 0);
}
-void elemental_summon_init(struct elemental_data *ed)
-{
- if (ed->summon_timer == INVALID_TIMER)
- ed->summon_timer = add_timer(gettick() + ed->elemental.life_time, elemental_summon_end, ed->master->bl.id, 0);
-
- ed->regen.state.block = 0;
+void elemental_summon_init(struct elemental_data *ed) {
+ if( ed->summon_timer == INVALID_TIMER )
+ ed->summon_timer = add_timer(gettick() + ed->elemental.life_time, elemental_summon_end, ed->master->bl.id, 0);
+
+ ed->regen.state.block = 0;
}
-int elemental_data_received(struct s_elemental *ele, bool flag)
-{
- struct map_session_data *sd;
- struct elemental_data *ed;
- struct s_elemental_db *db;
- int i = elemental_search_index(ele->class_);
-
- if ((sd = map_charid2sd(ele->char_id)) == NULL)
- return 0;
-
- if (!flag || i < 0) { // Not created - loaded - DB info
- sd->status.ele_id = 0;
- return 0;
- }
-
- db = &elemental_db[i];
- if (!sd->ed) { // Initialize it after first summon.
- sd->ed = ed = (struct elemental_data *)aCalloc(1,sizeof(struct elemental_data));
- ed->bl.type = BL_ELEM;
- ed->bl.id = npc_get_new_npc_id();
- ed->master = sd;
- ed->db = db;
- memcpy(&ed->elemental, ele, sizeof(struct s_elemental));
- status_set_viewdata(&ed->bl, ed->elemental.class_);
- ed->vd->head_mid = 10; // Why?
- status_change_init(&ed->bl);
- unit_dataset(&ed->bl);
- ed->ud.dir = sd->ud.dir;
-
- ed->bl.m = sd->bl.m;
- ed->bl.x = sd->bl.x;
- ed->bl.y = sd->bl.y;
- unit_calc_pos(&ed->bl, sd->bl.x, sd->bl.y, sd->ud.dir);
- ed->bl.x = ed->ud.to_x;
- ed->bl.y = ed->ud.to_y;
-
- map_addiddb(&ed->bl);
- status_calc_elemental(ed,1);
- ed->last_thinktime = gettick();
- ed->summon_timer = INVALID_TIMER;
- ed->battle_status.mode = ele->mode = EL_MODE_PASSIVE; // Initial mode.
- elemental_summon_init(ed);
- } else {
- memcpy(&sd->ed->elemental, ele, sizeof(struct s_elemental));
- ed = sd->ed;
- }
-
- sd->status.ele_id = ele->elemental_id;
- ed->battle_status.mode = ele->mode = EL_MODE_PASSIVE; // Initial mode.
-
- if (ed->bl.prev == NULL && sd->bl.prev != NULL) {
- map_addblock(&ed->bl);
- clif_spawn(&ed->bl);
- clif_elemental_info(sd);
- clif_elemental_updatestatus(sd,SP_HP);
- clif_hpmeter_single(sd->fd,ed->bl.id,ed->battle_status.hp,ed->battle_status.matk_max);
- clif_elemental_updatestatus(sd,SP_SP);
- }
-
- return 1;
+int elemental_data_received(struct s_elemental *ele, bool flag) {
+ struct map_session_data *sd;
+ struct elemental_data *ed;
+ struct s_elemental_db *db;
+ int i = elemental_search_index(ele->class_);
+
+ if( (sd = map_charid2sd(ele->char_id)) == NULL )
+ return 0;
+
+ if( !flag || i < 0 ) { // Not created - loaded - DB info
+ sd->status.ele_id = 0;
+ return 0;
+ }
+
+ db = &elemental_db[i];
+ if( !sd->ed ) { // Initialize it after first summon.
+ sd->ed = ed = (struct elemental_data*)aCalloc(1,sizeof(struct elemental_data));
+ ed->bl.type = BL_ELEM;
+ ed->bl.id = npc_get_new_npc_id();
+ ed->master = sd;
+ ed->db = db;
+ memcpy(&ed->elemental, ele, sizeof(struct s_elemental));
+ status_set_viewdata(&ed->bl, ed->elemental.class_);
+ ed->vd->head_mid = 10; // Why?
+ status_change_init(&ed->bl);
+ unit_dataset(&ed->bl);
+ ed->ud.dir = sd->ud.dir;
+
+ ed->bl.m = sd->bl.m;
+ ed->bl.x = sd->bl.x;
+ ed->bl.y = sd->bl.y;
+ unit_calc_pos(&ed->bl, sd->bl.x, sd->bl.y, sd->ud.dir);
+ ed->bl.x = ed->ud.to_x;
+ ed->bl.y = ed->ud.to_y;
+
+ map_addiddb(&ed->bl);
+ status_calc_elemental(ed,1);
+ ed->last_thinktime = gettick();
+ ed->summon_timer = INVALID_TIMER;
+ ed->battle_status.mode = ele->mode = EL_MODE_PASSIVE; // Initial mode.
+ elemental_summon_init(ed);
+ } else {
+ memcpy(&sd->ed->elemental, ele, sizeof(struct s_elemental));
+ ed = sd->ed;
+ }
+
+ sd->status.ele_id = ele->elemental_id;
+ ed->battle_status.mode = ele->mode = EL_MODE_PASSIVE; // Initial mode.
+
+ if( ed->bl.prev == NULL && sd->bl.prev != NULL ) {
+ map_addblock(&ed->bl);
+ clif_spawn(&ed->bl);
+ clif_elemental_info(sd);
+ clif_elemental_updatestatus(sd,SP_HP);
+ clif_hpmeter_single(sd->fd,ed->bl.id,ed->battle_status.hp,ed->battle_status.matk_max);
+ clif_elemental_updatestatus(sd,SP_SP);
+ }
+
+ return 1;
}
-int elemental_clean_single_effect(struct elemental_data *ed, int skill_num)
-{
- struct block_list *bl;
- sc_type type = status_skill2sc(skill_num);
-
- nullpo_ret(ed);
-
- bl = battle_get_master(&ed->bl);
-
- if (type) {
- switch (type) {
- // Just remove status change.
- case SC_PYROTECHNIC_OPTION:
- case SC_HEATER_OPTION:
- case SC_TROPIC_OPTION:
- case SC_FIRE_CLOAK_OPTION:
- case SC_AQUAPLAY_OPTION:
- case SC_WATER_SCREEN_OPTION:
- case SC_COOLER_OPTION:
- case SC_CHILLY_AIR_OPTION:
- case SC_GUST_OPTION:
- case SC_WIND_STEP_OPTION:
- case SC_BLAST_OPTION:
- case SC_WATER_DROP_OPTION:
- case SC_WIND_CURTAIN_OPTION:
- case SC_WILD_STORM_OPTION:
- case SC_PETROLOGY_OPTION:
- case SC_SOLID_SKIN_OPTION:
- case SC_CURSED_SOIL_OPTION:
- case SC_STONE_SHIELD_OPTION:
- case SC_UPHEAVAL_OPTION:
- case SC_CIRCLE_OF_FIRE_OPTION:
- case SC_TIDAL_WEAPON_OPTION:
- if (bl) status_change_end(bl,type,INVALID_TIMER); // Master
- status_change_end(&ed->bl,type-1,INVALID_TIMER); // Elemental Spirit
- break;
- case SC_ZEPHYR:
- if (bl) status_change_end(bl,type,INVALID_TIMER);
- break;
- default:
- ShowWarning("Invalid SC=%d in elemental_clean_single_effect\n",type);
- break;
- }
- }
- if (skill_get_unit_id(skill_num,0))
- skill_clear_unitgroup(&ed->bl);
-
- return 1;
+int elemental_clean_single_effect(struct elemental_data *ed, int skill_num) {
+ struct block_list *bl;
+ sc_type type = status_skill2sc(skill_num);
+
+ nullpo_ret(ed);
+
+ bl = battle_get_master(&ed->bl);
+
+ if( type ) {
+ switch( type ) {
+ // Just remove status change.
+ case SC_PYROTECHNIC_OPTION:
+ case SC_HEATER_OPTION:
+ case SC_TROPIC_OPTION:
+ case SC_FIRE_CLOAK_OPTION:
+ case SC_AQUAPLAY_OPTION:
+ case SC_WATER_SCREEN_OPTION:
+ case SC_COOLER_OPTION:
+ case SC_CHILLY_AIR_OPTION:
+ case SC_GUST_OPTION:
+ case SC_WIND_STEP_OPTION:
+ case SC_BLAST_OPTION:
+ case SC_WATER_DROP_OPTION:
+ case SC_WIND_CURTAIN_OPTION:
+ case SC_WILD_STORM_OPTION:
+ case SC_PETROLOGY_OPTION:
+ case SC_SOLID_SKIN_OPTION:
+ case SC_CURSED_SOIL_OPTION:
+ case SC_STONE_SHIELD_OPTION:
+ case SC_UPHEAVAL_OPTION:
+ case SC_CIRCLE_OF_FIRE_OPTION:
+ case SC_TIDAL_WEAPON_OPTION:
+ if( bl ) status_change_end(bl,type,INVALID_TIMER); // Master
+ status_change_end(&ed->bl,type-1,INVALID_TIMER); // Elemental Spirit
+ break;
+ case SC_ZEPHYR:
+ if( bl ) status_change_end(bl,type,INVALID_TIMER);
+ break;
+ default:
+ ShowWarning("Invalid SC=%d in elemental_clean_single_effect\n",type);
+ break;
+ }
+ }
+ if( skill_get_unit_id(skill_num,0) )
+ skill_clear_unitgroup(&ed->bl);
+
+ return 1;
}
-int elemental_clean_effect(struct elemental_data *ed)
-{
- struct map_session_data *sd;
-
- nullpo_ret(ed);
-
- // Elemental side
- status_change_end(&ed->bl, SC_TROPIC, INVALID_TIMER);
- status_change_end(&ed->bl, SC_HEATER, INVALID_TIMER);
- status_change_end(&ed->bl, SC_AQUAPLAY, INVALID_TIMER);
- status_change_end(&ed->bl, SC_COOLER, INVALID_TIMER);
- status_change_end(&ed->bl, SC_CHILLY_AIR, INVALID_TIMER);
- status_change_end(&ed->bl, SC_PYROTECHNIC, INVALID_TIMER);
- status_change_end(&ed->bl, SC_FIRE_CLOAK, INVALID_TIMER);
- status_change_end(&ed->bl, SC_WATER_DROP, INVALID_TIMER);
- status_change_end(&ed->bl, SC_WATER_SCREEN, INVALID_TIMER);
- status_change_end(&ed->bl, SC_GUST, INVALID_TIMER);
- status_change_end(&ed->bl, SC_WIND_STEP, INVALID_TIMER);
- status_change_end(&ed->bl, SC_BLAST, INVALID_TIMER);
- status_change_end(&ed->bl, SC_WIND_CURTAIN, INVALID_TIMER);
- status_change_end(&ed->bl, SC_WILD_STORM, INVALID_TIMER);
- status_change_end(&ed->bl, SC_PETROLOGY, INVALID_TIMER);
- status_change_end(&ed->bl, SC_SOLID_SKIN, INVALID_TIMER);
- status_change_end(&ed->bl, SC_CURSED_SOIL, INVALID_TIMER);
- status_change_end(&ed->bl, SC_STONE_SHIELD, INVALID_TIMER);
- status_change_end(&ed->bl, SC_UPHEAVAL, INVALID_TIMER);
- status_change_end(&ed->bl, SC_CIRCLE_OF_FIRE, INVALID_TIMER);
- status_change_end(&ed->bl, SC_TIDAL_WEAPON, INVALID_TIMER);
-
- skill_clear_unitgroup(&ed->bl);
-
- if ((sd = ed->master) == NULL)
- return 0;
-
- // Master side
- status_change_end(&sd->bl, SC_TROPIC_OPTION, INVALID_TIMER);
- status_change_end(&sd->bl, SC_HEATER_OPTION, INVALID_TIMER);
- status_change_end(&sd->bl, SC_AQUAPLAY_OPTION, INVALID_TIMER);
- status_change_end(&sd->bl, SC_COOLER_OPTION, INVALID_TIMER);
- status_change_end(&sd->bl, SC_CHILLY_AIR_OPTION, INVALID_TIMER);
- status_change_end(&sd->bl, SC_PYROTECHNIC_OPTION, INVALID_TIMER);
- status_change_end(&sd->bl, SC_FIRE_CLOAK_OPTION, INVALID_TIMER);
- status_change_end(&sd->bl, SC_WATER_DROP_OPTION, INVALID_TIMER);
- status_change_end(&sd->bl, SC_WATER_SCREEN_OPTION, INVALID_TIMER);
- status_change_end(&sd->bl, SC_GUST_OPTION, INVALID_TIMER);
- status_change_end(&sd->bl, SC_WIND_STEP_OPTION, INVALID_TIMER);
- status_change_end(&sd->bl, SC_BLAST_OPTION, INVALID_TIMER);
- status_change_end(&sd->bl, SC_WATER_DROP_OPTION, INVALID_TIMER);
- status_change_end(&sd->bl, SC_WIND_CURTAIN_OPTION, INVALID_TIMER);
- status_change_end(&sd->bl, SC_WILD_STORM_OPTION, INVALID_TIMER);
- status_change_end(&sd->bl, SC_ZEPHYR, INVALID_TIMER);
- status_change_end(&sd->bl, SC_WIND_STEP_OPTION, INVALID_TIMER);
- status_change_end(&sd->bl, SC_PETROLOGY_OPTION, INVALID_TIMER);
- status_change_end(&sd->bl, SC_SOLID_SKIN_OPTION, INVALID_TIMER);
- status_change_end(&sd->bl, SC_CURSED_SOIL_OPTION, INVALID_TIMER);
- status_change_end(&sd->bl, SC_STONE_SHIELD_OPTION, INVALID_TIMER);
- status_change_end(&sd->bl, SC_UPHEAVAL_OPTION, INVALID_TIMER);
- status_change_end(&sd->bl, SC_CIRCLE_OF_FIRE_OPTION, INVALID_TIMER);
- status_change_end(&sd->bl, SC_TIDAL_WEAPON_OPTION, INVALID_TIMER);
-
- return 1;
+int elemental_clean_effect(struct elemental_data *ed) {
+ struct map_session_data *sd;
+
+ nullpo_ret(ed);
+
+ // Elemental side
+ status_change_end(&ed->bl, SC_TROPIC, INVALID_TIMER);
+ status_change_end(&ed->bl, SC_HEATER, INVALID_TIMER);
+ status_change_end(&ed->bl, SC_AQUAPLAY, INVALID_TIMER);
+ status_change_end(&ed->bl, SC_COOLER, INVALID_TIMER);
+ status_change_end(&ed->bl, SC_CHILLY_AIR, INVALID_TIMER);
+ status_change_end(&ed->bl, SC_PYROTECHNIC, INVALID_TIMER);
+ status_change_end(&ed->bl, SC_FIRE_CLOAK, INVALID_TIMER);
+ status_change_end(&ed->bl, SC_WATER_DROP, INVALID_TIMER);
+ status_change_end(&ed->bl, SC_WATER_SCREEN, INVALID_TIMER);
+ status_change_end(&ed->bl, SC_GUST, INVALID_TIMER);
+ status_change_end(&ed->bl, SC_WIND_STEP, INVALID_TIMER);
+ status_change_end(&ed->bl, SC_BLAST, INVALID_TIMER);
+ status_change_end(&ed->bl, SC_WIND_CURTAIN, INVALID_TIMER);
+ status_change_end(&ed->bl, SC_WILD_STORM, INVALID_TIMER);
+ status_change_end(&ed->bl, SC_PETROLOGY, INVALID_TIMER);
+ status_change_end(&ed->bl, SC_SOLID_SKIN, INVALID_TIMER);
+ status_change_end(&ed->bl, SC_CURSED_SOIL, INVALID_TIMER);
+ status_change_end(&ed->bl, SC_STONE_SHIELD, INVALID_TIMER);
+ status_change_end(&ed->bl, SC_UPHEAVAL, INVALID_TIMER);
+ status_change_end(&ed->bl, SC_CIRCLE_OF_FIRE, INVALID_TIMER);
+ status_change_end(&ed->bl, SC_TIDAL_WEAPON, INVALID_TIMER);
+
+ skill_clear_unitgroup(&ed->bl);
+
+ if( (sd = ed->master) == NULL )
+ return 0;
+
+ // Master side
+ status_change_end(&sd->bl, SC_TROPIC_OPTION, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_HEATER_OPTION, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_AQUAPLAY_OPTION, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_COOLER_OPTION, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_CHILLY_AIR_OPTION, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_PYROTECHNIC_OPTION, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_FIRE_CLOAK_OPTION, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_WATER_DROP_OPTION, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_WATER_SCREEN_OPTION, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_GUST_OPTION, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_WIND_STEP_OPTION, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_BLAST_OPTION, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_WATER_DROP_OPTION, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_WIND_CURTAIN_OPTION, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_WILD_STORM_OPTION, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_ZEPHYR, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_WIND_STEP_OPTION, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_PETROLOGY_OPTION, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_SOLID_SKIN_OPTION, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_CURSED_SOIL_OPTION, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_STONE_SHIELD_OPTION, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_UPHEAVAL_OPTION, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_CIRCLE_OF_FIRE_OPTION, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_TIDAL_WEAPON_OPTION, INVALID_TIMER);
+
+ return 1;
}
-int elemental_action(struct elemental_data *ed, struct block_list *bl, unsigned int tick)
-{
- short skillnum, skilllv;
- int i;
-
- nullpo_ret(ed);
- nullpo_ret(bl);
-
- if (!ed->master)
- return 0;
-
- if (ed->target_id)
- elemental_unlocktarget(ed); // Remove previous target.
-
- ARR_FIND(0, MAX_ELESKILLTREE, i, ed->db->skill[i].id && (ed->db->skill[i].mode&EL_SKILLMODE_AGGRESSIVE));
- if (i == MAX_ELESKILLTREE)
- return 0;
-
- skillnum = ed->db->skill[i].id;
- skilllv = ed->db->skill[i].lv;
-
- if (elemental_skillnotok(skillnum, ed))
- return 0;
-
- if (ed->ud.skilltimer != INVALID_TIMER)
- return 0;
- else if (DIFF_TICK(tick, ed->ud.canact_tick) < 0)
- return 0;
-
- ed->target_id = ed->ud.skilltarget = bl->id; // Set new target
- ed->last_thinktime = tick;
-
- // Not in skill range.
- if (!battle_check_range(&ed->bl,bl,skill_get_range(skillnum,skilllv))) {
- // Try to walk to the target.
- if (!unit_walktobl(&ed->bl, bl, skill_get_range(skillnum,skilllv), 2))
- elemental_unlocktarget(ed);
- else {
- // Walking, waiting to be in range. Client don't handle it, then we must handle it here.
- int walk_dist = distance_bl(&ed->bl,bl) - skill_get_range(skillnum,skilllv);
- ed->ud.skillid = skillnum;
- ed->ud.skilllv = skilllv;
-
- if (skill_get_inf(skillnum) & INF_GROUND_SKILL)
- ed->ud.skilltimer = add_timer(tick+status_get_speed(&ed->bl)*walk_dist, skill_castend_pos, ed->bl.id, 0);
- else
- ed->ud.skilltimer = add_timer(tick+status_get_speed(&ed->bl)*walk_dist, skill_castend_id, ed->bl.id, 0);
- }
- return 1;
-
- }
- //Otherwise, just cast the skill.
- if (skill_get_inf(skillnum) & INF_GROUND_SKILL)
- unit_skilluse_pos(&ed->bl, bl->x, bl->y, skillnum, skilllv);
- else
- unit_skilluse_id(&ed->bl, bl->id, skillnum, skilllv);
-
- // Reset target.
- ed->target_id = 0;
-
- return 1;
+int elemental_action(struct elemental_data *ed, struct block_list *bl, unsigned int tick) {
+ short skillnum, skilllv;
+ int i;
+
+ nullpo_ret(ed);
+ nullpo_ret(bl);
+
+ if( !ed->master )
+ return 0;
+
+ if( ed->target_id )
+ elemental_unlocktarget(ed); // Remove previous target.
+
+ ARR_FIND(0, MAX_ELESKILLTREE, i, ed->db->skill[i].id && (ed->db->skill[i].mode&EL_SKILLMODE_AGGRESSIVE));
+ if( i == MAX_ELESKILLTREE )
+ return 0;
+
+ skillnum = ed->db->skill[i].id;
+ skilllv = ed->db->skill[i].lv;
+
+ if( elemental_skillnotok(skillnum, ed) )
+ return 0;
+
+ if( ed->ud.skilltimer != INVALID_TIMER )
+ return 0;
+ else if( DIFF_TICK(tick, ed->ud.canact_tick) < 0 )
+ return 0;
+
+ ed->target_id = ed->ud.skilltarget = bl->id; // Set new target
+ ed->last_thinktime = tick;
+
+ // Not in skill range.
+ if( !battle_check_range(&ed->bl,bl,skill_get_range(skillnum,skilllv)) ) {
+ // Try to walk to the target.
+ if( !unit_walktobl(&ed->bl, bl, skill_get_range(skillnum,skilllv), 2) )
+ elemental_unlocktarget(ed);
+ else {
+ // Walking, waiting to be in range. Client don't handle it, then we must handle it here.
+ int walk_dist = distance_bl(&ed->bl,bl) - skill_get_range(skillnum,skilllv);
+ ed->ud.skillid = skillnum;
+ ed->ud.skilllv = skilllv;
+
+ if( skill_get_inf(skillnum) & INF_GROUND_SKILL )
+ ed->ud.skilltimer = add_timer( tick+status_get_speed(&ed->bl)*walk_dist, skill_castend_pos, ed->bl.id, 0 );
+ else
+ ed->ud.skilltimer = add_timer( tick+status_get_speed(&ed->bl)*walk_dist, skill_castend_id, ed->bl.id, 0 );
+ }
+ return 1;
+
+ }
+ //Otherwise, just cast the skill.
+ if( skill_get_inf(skillnum) & INF_GROUND_SKILL )
+ unit_skilluse_pos(&ed->bl, bl->x, bl->y, skillnum, skilllv);
+ else
+ unit_skilluse_id(&ed->bl, bl->id, skillnum, skilllv);
+
+ // Reset target.
+ ed->target_id = 0;
+
+ return 1;
}
/*===============================================================
* Action that elemental perform after changing mode.
* Activates one of the skills of the new mode.
*-------------------------------------------------------------*/
-int elemental_change_mode_ack(struct elemental_data *ed, int mode)
-{
- struct block_list *bl = &ed->master->bl;
- short skillnum, skilllv;
- int i;
-
- nullpo_ret(ed);
-
- if (!bl)
- return 0;
-
- // Select a skill.
- ARR_FIND(0, MAX_ELESKILLTREE, i, ed->db->skill[i].id && (ed->db->skill[i].mode&mode));
- if (i == MAX_ELESKILLTREE)
- return 0;
-
- skillnum = ed->db->skill[i].id;
- skilllv = ed->db->skill[i].lv;
-
- if (elemental_skillnotok(skillnum, ed))
- return 0;
-
- if (ed->ud.skilltimer != INVALID_TIMER)
- return 0;
- else if (DIFF_TICK(gettick(), ed->ud.canact_tick) < 0)
- return 0;
-
- ed->target_id = bl->id; // Set new target
- ed->last_thinktime = gettick();
-
- if (skill_get_inf(skillnum) & INF_GROUND_SKILL)
- unit_skilluse_pos(&ed->bl, bl->x, bl->y, skillnum, skilllv);
- else
- unit_skilluse_id(&ed->bl,bl->id,skillnum,skilllv);
-
- ed->target_id = 0; // Reset target after casting the skill to avoid continious attack.
-
- return 1;
+int elemental_change_mode_ack(struct elemental_data *ed, int mode) {
+ struct block_list *bl = &ed->master->bl;
+ short skillnum, skilllv;
+ int i;
+
+ nullpo_ret(ed);
+
+ if( !bl )
+ return 0;
+
+ // Select a skill.
+ ARR_FIND(0, MAX_ELESKILLTREE, i, ed->db->skill[i].id && (ed->db->skill[i].mode&mode));
+ if( i == MAX_ELESKILLTREE )
+ return 0;
+
+ skillnum = ed->db->skill[i].id;
+ skilllv = ed->db->skill[i].lv;
+
+ if( elemental_skillnotok(skillnum, ed) )
+ return 0;
+
+ if( ed->ud.skilltimer != INVALID_TIMER )
+ return 0;
+ else if( DIFF_TICK(gettick(), ed->ud.canact_tick) < 0 )
+ return 0;
+
+ ed->target_id = bl->id; // Set new target
+ ed->last_thinktime = gettick();
+
+ if( skill_get_inf(skillnum) & INF_GROUND_SKILL )
+ unit_skilluse_pos(&ed->bl, bl->x, bl->y, skillnum, skilllv);
+ else
+ unit_skilluse_id(&ed->bl,bl->id,skillnum,skilllv);
+
+ ed->target_id = 0; // Reset target after casting the skill to avoid continious attack.
+
+ return 1;
}
/*===============================================================
* Change elemental mode.
*-------------------------------------------------------------*/
-int elemental_change_mode(struct elemental_data *ed, int mode)
-{
- nullpo_ret(ed);
-
- // Remove target
- elemental_unlocktarget(ed);
-
- // Removes the effects of the previous mode.
- if (ed->elemental.mode != mode) elemental_clean_effect(ed);
-
- ed->battle_status.mode = ed->elemental.mode = mode;
-
- // Normalize elemental mode to elemental skill mode.
- if (mode == EL_MODE_AGGRESSIVE) mode = EL_SKILLMODE_AGGRESSIVE; // Aggressive spirit mode -> Aggressive spirit skill.
- else if (mode == EL_MODE_ASSIST) mode = EL_SKILLMODE_ASSIST; // Assist spirit mode -> Assist spirit skill.
- else mode = EL_SKILLMODE_PASIVE; // Passive spirit mode -> Passive spirit skill.
-
- // Use a skill inmediately after every change mode.
- if (mode != EL_SKILLMODE_AGGRESSIVE)
- elemental_change_mode_ack(ed,mode);
- return 1;
+int elemental_change_mode(struct elemental_data *ed, int mode) {
+ nullpo_ret(ed);
+
+ // Remove target
+ elemental_unlocktarget(ed);
+
+ // Removes the effects of the previous mode.
+ if(ed->elemental.mode != mode ) elemental_clean_effect(ed);
+
+ ed->battle_status.mode = ed->elemental.mode = mode;
+
+ // Normalize elemental mode to elemental skill mode.
+ if( mode == EL_MODE_AGGRESSIVE ) mode = EL_SKILLMODE_AGGRESSIVE; // Aggressive spirit mode -> Aggressive spirit skill.
+ else if( mode == EL_MODE_ASSIST ) mode = EL_SKILLMODE_ASSIST; // Assist spirit mode -> Assist spirit skill.
+ else mode = EL_SKILLMODE_PASIVE; // Passive spirit mode -> Passive spirit skill.
+
+ // Use a skill inmediately after every change mode.
+ if( mode != EL_SKILLMODE_AGGRESSIVE )
+ elemental_change_mode_ack(ed,mode);
+ return 1;
}
-void elemental_heal(struct elemental_data *ed, int hp, int sp)
-{
- if (hp)
- clif_elemental_updatestatus(ed->master, SP_HP);
- if (sp)
- clif_elemental_updatestatus(ed->master, SP_SP);
+void elemental_heal(struct elemental_data *ed, int hp, int sp) {
+ if( hp )
+ clif_elemental_updatestatus(ed->master, SP_HP);
+ if( sp )
+ clif_elemental_updatestatus(ed->master, SP_SP);
}
-int elemental_dead(struct elemental_data *ed)
-{
- elemental_delete(ed, 1);
- return 0;
+int elemental_dead(struct elemental_data *ed) {
+ elemental_delete(ed, 1);
+ return 0;
}
-int elemental_unlocktarget(struct elemental_data *ed)
-{
- nullpo_ret(ed);
-
- ed->target_id = 0;
- elemental_stop_attack(ed);
- elemental_stop_walking(ed,1);
- return 0;
+int elemental_unlocktarget(struct elemental_data *ed) {
+ nullpo_ret(ed);
+
+ ed->target_id = 0;
+ elemental_stop_attack(ed);
+ elemental_stop_walking(ed,1);
+ return 0;
}
-int elemental_skillnotok(int skillid, struct elemental_data *ed)
-{
- int i = skill_get_index(skillid);
- nullpo_retr(1,ed);
-
- if (i == 0)
- return 1; // invalid skill id
-
- return skillnotok(skillid, ed->master);
+int elemental_skillnotok(int skillid, struct elemental_data *ed) {
+ int i = skill_get_index(skillid);
+ nullpo_retr(1,ed);
+
+ if (i == 0)
+ return 1; // invalid skill id
+
+ return skillnotok(skillid, ed->master);
}
-int elemental_set_target(struct map_session_data *sd, struct block_list *bl)
-{
- struct elemental_data *ed = sd->ed;
-
- nullpo_ret(ed);
- nullpo_ret(bl);
-
- if (ed->bl.m != bl->m || !check_distance_bl(&ed->bl, bl, ed->db->range2))
- return 0;
-
- if (!status_check_skilluse(&ed->bl, bl, 0, 0))
- return 0;
-
- if (ed->target_id == 0)
- ed->target_id = bl->id;
-
- return 1;
+int elemental_set_target( struct map_session_data *sd, struct block_list *bl ) {
+ struct elemental_data *ed = sd->ed;
+
+ nullpo_ret(ed);
+ nullpo_ret(bl);
+
+ if( ed->bl.m != bl->m || !check_distance_bl(&ed->bl, bl, ed->db->range2) )
+ return 0;
+
+ if( !status_check_skilluse(&ed->bl, bl, 0, 0) )
+ return 0;
+
+ if( ed->target_id == 0 )
+ ed->target_id = bl->id;
+
+ return 1;
}
-static int elemental_ai_sub_timer_activesearch(struct block_list *bl, va_list ap)
-{
- struct elemental_data *ed;
- struct block_list **target;
- int dist;
-
- nullpo_ret(bl);
-
- ed = va_arg(ap,struct elemental_data *);
- target = va_arg(ap,struct block_list **);
-
- //If can't seek yet, not an enemy, or you can't attack it, skip.
- if ((*target) == bl || !status_check_skilluse(&ed->bl, bl, 0, 0))
- return 0;
-
- if (battle_check_target(&ed->bl,bl,BCT_ENEMY) <= 0)
- return 0;
-
- switch (bl->type) {
- case BL_PC:
- if (!map_flag_vs(ed->bl.m))
- return 0;
- default:
- dist = distance_bl(&ed->bl, bl);
- if (((*target) == NULL || !check_distance_bl(&ed->bl, *target, dist)) && battle_check_range(&ed->bl,bl,ed->db->range2)) { //Pick closest target?
- (*target) = bl;
- ed->target_id = bl->id;
- ed->min_chase = dist + ed->db->range3;
- if (ed->min_chase > AREA_SIZE)
- ed->min_chase = AREA_SIZE;
- return 1;
- }
- break;
- }
- return 0;
+static int elemental_ai_sub_timer_activesearch(struct block_list *bl, va_list ap) {
+ struct elemental_data *ed;
+ struct block_list **target;
+ int dist;
+
+ nullpo_ret(bl);
+
+ ed = va_arg(ap,struct elemental_data *);
+ target = va_arg(ap,struct block_list**);
+
+ //If can't seek yet, not an enemy, or you can't attack it, skip.
+ if( (*target) == bl || !status_check_skilluse(&ed->bl, bl, 0, 0) )
+ return 0;
+
+ if( battle_check_target(&ed->bl,bl,BCT_ENEMY) <= 0 )
+ return 0;
+
+ switch( bl->type ) {
+ case BL_PC:
+ if( !map_flag_vs(ed->bl.m) )
+ return 0;
+ default:
+ dist = distance_bl(&ed->bl, bl);
+ if( ((*target) == NULL || !check_distance_bl(&ed->bl, *target, dist)) && battle_check_range(&ed->bl,bl,ed->db->range2) ) { //Pick closest target?
+ (*target) = bl;
+ ed->target_id = bl->id;
+ ed->min_chase = dist + ed->db->range3;
+ if( ed->min_chase > AREA_SIZE )
+ ed->min_chase = AREA_SIZE;
+ return 1;
+ }
+ break;
+ }
+ return 0;
}
-static int elemental_ai_sub_timer(struct elemental_data *ed, struct map_session_data *sd, unsigned int tick)
-{
- struct block_list *target = NULL;
- int master_dist, view_range, mode;
-
- nullpo_ret(ed);
- nullpo_ret(sd);
-
- if (ed->bl.prev == NULL || sd == NULL || sd->bl.prev == NULL)
- return 0;
-
- if (DIFF_TICK(tick,ed->last_thinktime) < MIN_ELETHINKTIME)
- return 0;
-
- ed->last_thinktime = tick;
-
- if (ed->ud.skilltimer != INVALID_TIMER)
- return 0;
-
- if (ed->ud.walktimer != INVALID_TIMER && ed->ud.walkpath.path_pos <= 2)
- return 0; //No thinking when you just started to walk.
-
- if (ed->ud.walkpath.path_pos < ed->ud.walkpath.path_len && ed->ud.target == sd->bl.id)
- return 0; //No thinking until be near the master.
-
- if (ed->sc.count && ed->sc.data[SC_BLIND])
- view_range = 3;
- else
- view_range = ed->db->range2;
-
- mode = status_get_mode(&ed->bl);
-
- master_dist = distance_bl(&sd->bl, &ed->bl);
- if (master_dist > AREA_SIZE) { // Master out of vision range.
- elemental_unlocktarget(ed);
- unit_warp(&ed->bl,sd->bl.m,sd->bl.x,sd->bl.y,CLR_TELEPORT);
- return 0;
- } else if (master_dist > MAX_ELEDISTANCE) { // Master too far, chase.
- short x = sd->bl.x, y = sd->bl.y;
- if (ed->target_id)
- elemental_unlocktarget(ed);
- if (ed->ud.walktimer != INVALID_TIMER && ed->ud.target == sd->bl.id)
- return 0; //Already walking to him
- if (DIFF_TICK(tick, ed->ud.canmove_tick) < 0)
- return 0; //Can't move yet.
- if (map_search_freecell(&ed->bl, sd->bl.m, &x, &y, MIN_ELEDISTANCE, MIN_ELEDISTANCE, 1)
- && unit_walktoxy(&ed->bl, x, y, 0))
- return 0;
- }
-
- if (mode == EL_MODE_AGGRESSIVE) {
- target = map_id2bl(ed->ud.target);
-
- if (!target)
- map_foreachinrange(elemental_ai_sub_timer_activesearch, &ed->bl, view_range, BL_CHAR, ed, &target, status_get_mode(&ed->bl));
-
- if (!target) { //No targets available.
- elemental_unlocktarget(ed);
- return 1;
- }
-
- if (battle_check_range(&ed->bl,target,view_range) && rnd()%100 < 2) { // 2% chance to cast attack skill.
- if (elemental_action(ed,target,tick))
- return 1;
- }
-
- //Attempt to attack.
- //At this point we know the target is attackable, we just gotta check if the range matches.
- if (ed->ud.target == target->id && ed->ud.attacktimer != INVALID_TIMER) //Already locked.
- return 1;
-
- if (battle_check_range(&ed->bl, target, ed->base_status.rhw.range)) { //Target within range, engage
- unit_attack(&ed->bl,target->id,1);
- return 1;
- }
-
- //Follow up if possible.
- if (!unit_walktobl(&ed->bl, target, ed->base_status.rhw.range, 2))
- elemental_unlocktarget(ed);
- }
-
- return 0;
+static int elemental_ai_sub_timer(struct elemental_data *ed, struct map_session_data *sd, unsigned int tick) {
+ struct block_list *target = NULL;
+ int master_dist, view_range, mode;
+
+ nullpo_ret(ed);
+ nullpo_ret(sd);
+
+ if( ed->bl.prev == NULL || sd == NULL || sd->bl.prev == NULL )
+ return 0;
+
+ if( DIFF_TICK(tick,ed->last_thinktime) < MIN_ELETHINKTIME )
+ return 0;
+
+ ed->last_thinktime = tick;
+
+ if( ed->ud.skilltimer != INVALID_TIMER )
+ return 0;
+
+ if( ed->ud.walktimer != INVALID_TIMER && ed->ud.walkpath.path_pos <= 2 )
+ return 0; //No thinking when you just started to walk.
+
+ if(ed->ud.walkpath.path_pos < ed->ud.walkpath.path_len && ed->ud.target == sd->bl.id)
+ return 0; //No thinking until be near the master.
+
+ if( ed->sc.count && ed->sc.data[SC_BLIND] )
+ view_range = 3;
+ else
+ view_range = ed->db->range2;
+
+ mode = status_get_mode(&ed->bl);
+
+ master_dist = distance_bl(&sd->bl, &ed->bl);
+ if( master_dist > AREA_SIZE ) { // Master out of vision range.
+ elemental_unlocktarget(ed);
+ unit_warp(&ed->bl,sd->bl.m,sd->bl.x,sd->bl.y,CLR_TELEPORT);
+ return 0;
+ } else if( master_dist > MAX_ELEDISTANCE ) { // Master too far, chase.
+ short x = sd->bl.x, y = sd->bl.y;
+ if( ed->target_id )
+ elemental_unlocktarget(ed);
+ if( ed->ud.walktimer != INVALID_TIMER && ed->ud.target == sd->bl.id )
+ return 0; //Already walking to him
+ if( DIFF_TICK(tick, ed->ud.canmove_tick) < 0 )
+ return 0; //Can't move yet.
+ if( map_search_freecell(&ed->bl, sd->bl.m, &x, &y, MIN_ELEDISTANCE, MIN_ELEDISTANCE, 1)
+ && unit_walktoxy(&ed->bl, x, y, 0) )
+ return 0;
+ }
+
+ if( mode == EL_MODE_AGGRESSIVE ) {
+ target = map_id2bl(ed->ud.target);
+
+ if( !target )
+ map_foreachinrange(elemental_ai_sub_timer_activesearch, &ed->bl, view_range, BL_CHAR, ed, &target, status_get_mode(&ed->bl));
+
+ if( !target ) { //No targets available.
+ elemental_unlocktarget(ed);
+ return 1;
+ }
+
+ if( battle_check_range(&ed->bl,target,view_range) && rnd()%100 < 2 ) { // 2% chance to cast attack skill.
+ if( elemental_action(ed,target,tick) )
+ return 1;
+ }
+
+ //Attempt to attack.
+ //At this point we know the target is attackable, we just gotta check if the range matches.
+ if( ed->ud.target == target->id && ed->ud.attacktimer != INVALID_TIMER ) //Already locked.
+ return 1;
+
+ if( battle_check_range(&ed->bl, target, ed->base_status.rhw.range) ) {//Target within range, engage
+ unit_attack(&ed->bl,target->id,1);
+ return 1;
+ }
+
+ //Follow up if possible.
+ if( !unit_walktobl(&ed->bl, target, ed->base_status.rhw.range, 2) )
+ elemental_unlocktarget(ed);
+ }
+
+ return 0;
}
-static int elemental_ai_sub_foreachclient(struct map_session_data *sd, va_list ap)
-{
- unsigned int tick = va_arg(ap,unsigned int);
- if (sd->status.ele_id && sd->ed)
- elemental_ai_sub_timer(sd->ed,sd,tick);
-
- return 0;
+static int elemental_ai_sub_foreachclient(struct map_session_data *sd, va_list ap) {
+ unsigned int tick = va_arg(ap,unsigned int);
+ if(sd->status.ele_id && sd->ed)
+ elemental_ai_sub_timer(sd->ed,sd,tick);
+
+ return 0;
}
-static int elemental_ai_timer(int tid, unsigned int tick, int id, intptr_t data)
-{
- map_foreachpc(elemental_ai_sub_foreachclient,tick);
- return 0;
+static int elemental_ai_timer(int tid, unsigned int tick, int id, intptr_t data) {
+ map_foreachpc(elemental_ai_sub_foreachclient,tick);
+ return 0;
}
-int read_elementaldb(void)
-{
- FILE *fp;
- char line[1024], *p;
- char *str[26];
- int i, j = 0, k = 0, ele;
- struct s_elemental_db *db;
- struct status_data *status;
-
- sprintf(line, "%s/%s", db_path, "elemental_db.txt");
- memset(elemental_db,0,sizeof(elemental_db));
-
- fp = fopen(line, "r");
- if (!fp) {
- ShowError("read_elementaldb : can't read elemental_db.txt\n");
- return -1;
- }
-
- while (fgets(line, sizeof(line), fp) && j < MAX_ELEMENTAL_CLASS) {
- k++;
- if (line[0] == '/' && line[1] == '/')
- continue;
-
- if (line[0] == '\0' || line[0] == '\n' || line[0] == '\r')
- continue;
-
- i = 0;
- p = strtok(line, ",");
- while (p != NULL && i < 26) {
- str[i++] = p;
- p = strtok(NULL, ",");
- }
- if (i < 26) {
- ShowError("read_elementaldb : Incorrect number of columns at elemental_db.txt line %d.\n", k);
- continue;
- }
-
- db = &elemental_db[j];
- db->class_ = atoi(str[0]);
- strncpy(db->sprite, str[1], NAME_LENGTH);
- strncpy(db->name, str[2], NAME_LENGTH);
- db->lv = atoi(str[3]);
-
- status = &db->status;
- db->vd.class_ = db->class_;
-
- status->max_hp = atoi(str[4]);
- status->max_sp = atoi(str[5]);
- status->rhw.range = atoi(str[6]);
- status->rhw.atk = atoi(str[7]);
- status->rhw.atk2 = status->rhw.atk + atoi(str[8]);
- status->def = atoi(str[9]);
- status->mdef = atoi(str[10]);
- status->str = atoi(str[11]);
- status->agi = atoi(str[12]);
- status->vit = atoi(str[13]);
- status->int_ = atoi(str[14]);
- status->dex = atoi(str[15]);
- status->luk = atoi(str[16]);
- db->range2 = atoi(str[17]);
- db->range3 = atoi(str[18]);
- status->size = atoi(str[19]);
- status->race = atoi(str[20]);
-
- ele = atoi(str[21]);
- status->def_ele = ele%10;
- status->ele_lv = ele/20;
- if (status->def_ele >= ELE_MAX) {
- ShowWarning("Elemental %d has invalid element type %d (max element is %d)\n", db->class_, status->def_ele, ELE_MAX - 1);
- status->def_ele = ELE_NEUTRAL;
- }
- if (status->ele_lv < 1 || status->ele_lv > 4) {
- ShowWarning("Elemental %d has invalid element level %d (max is 4)\n", db->class_, status->ele_lv);
- status->ele_lv = 1;
- }
-
- status->aspd_rate = 1000;
- status->speed = atoi(str[22]);
- status->adelay = atoi(str[23]);
- status->amotion = atoi(str[24]);
- status->dmotion = atoi(str[25]);
-
- j++;
- }
-
- fclose(fp);
- ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' elementals in '"CL_WHITE"db/elemental_db.txt"CL_RESET"'.\n",j);
-
- return 0;
+int read_elementaldb(void) {
+ FILE *fp;
+ char line[1024], *p;
+ char *str[26];
+ int i, j = 0, k = 0, ele;
+ struct s_elemental_db *db;
+ struct status_data *status;
+
+ sprintf(line, "%s/%s", db_path, "elemental_db.txt");
+ memset(elemental_db,0,sizeof(elemental_db));
+
+ fp = fopen(line, "r");
+ if( !fp ) {
+ ShowError("read_elementaldb : can't read elemental_db.txt\n");
+ return -1;
+ }
+
+ while( fgets(line, sizeof(line), fp) && j < MAX_ELEMENTAL_CLASS ) {
+ k++;
+ if( line[0] == '/' && line[1] == '/' )
+ continue;
+
+ if( line[0] == '\0' || line[0] == '\n' || line[0] == '\r')
+ continue;
+
+ i = 0;
+ p = strtok(line, ",");
+ while( p != NULL && i < 26 ) {
+ str[i++] = p;
+ p = strtok(NULL, ",");
+ }
+ if( i < 26 ) {
+ ShowError("read_elementaldb : Incorrect number of columns at elemental_db.txt line %d.\n", k);
+ continue;
+ }
+
+ db = &elemental_db[j];
+ db->class_ = atoi(str[0]);
+ strncpy(db->sprite, str[1], NAME_LENGTH);
+ strncpy(db->name, str[2], NAME_LENGTH);
+ db->lv = atoi(str[3]);
+
+ status = &db->status;
+ db->vd.class_ = db->class_;
+
+ status->max_hp = atoi(str[4]);
+ status->max_sp = atoi(str[5]);
+ status->rhw.range = atoi(str[6]);
+ status->rhw.atk = atoi(str[7]);
+ status->rhw.atk2 = status->rhw.atk + atoi(str[8]);
+ status->def = atoi(str[9]);
+ status->mdef = atoi(str[10]);
+ status->str = atoi(str[11]);
+ status->agi = atoi(str[12]);
+ status->vit = atoi(str[13]);
+ status->int_ = atoi(str[14]);
+ status->dex = atoi(str[15]);
+ status->luk = atoi(str[16]);
+ db->range2 = atoi(str[17]);
+ db->range3 = atoi(str[18]);
+ status->size = atoi(str[19]);
+ status->race = atoi(str[20]);
+
+ ele = atoi(str[21]);
+ status->def_ele = ele%10;
+ status->ele_lv = ele/20;
+ if( status->def_ele >= ELE_MAX ) {
+ ShowWarning("Elemental %d has invalid element type %d (max element is %d)\n", db->class_, status->def_ele, ELE_MAX - 1);
+ status->def_ele = ELE_NEUTRAL;
+ }
+ if( status->ele_lv < 1 || status->ele_lv > 4 ) {
+ ShowWarning("Elemental %d has invalid element level %d (max is 4)\n", db->class_, status->ele_lv);
+ status->ele_lv = 1;
+ }
+
+ status->aspd_rate = 1000;
+ status->speed = atoi(str[22]);
+ status->adelay = atoi(str[23]);
+ status->amotion = atoi(str[24]);
+ status->dmotion = atoi(str[25]);
+
+ j++;
+ }
+
+ fclose(fp);
+ ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' elementals in '"CL_WHITE"db/elemental_db.txt"CL_RESET"'.\n",j);
+
+ return 0;
}
-int read_elemental_skilldb(void)
-{
- FILE *fp;
- char line[1024], *p;
- char *str[4];
- struct s_elemental_db *db;
- int i, j = 0, k = 0, class_;
- int skillid, skilllv, skillmode;
-
- sprintf(line, "%s/%s", db_path, "elemental_skill_db.txt");
- fp = fopen(line, "r");
- if (!fp) {
- ShowError("read_elemental_skilldb : can't read elemental_skill_db.txt\n");
- return -1;
- }
-
- while (fgets(line, sizeof(line), fp)) {
- k++;
- if (line[0] == '/' && line[1] == '/')
- continue;
-
- if (line[0] == '\0' || line[0] == '\n' || line[0] == '\r')
- continue;
-
- i = 0;
- p = strtok(line, ",");
- while (p != NULL && i < 4) {
- str[i++] = p;
- p = strtok(NULL, ",");
- }
- if (i < 4) {
- ShowError("read_elemental_skilldb : Incorrect number of columns at elemental_skill_db.txt line %d.\n", k);
- continue;
- }
-
- class_ = atoi(str[0]);
- ARR_FIND(0, MAX_ELEMENTAL_CLASS, i, class_ == elemental_db[i].class_);
- if (i == MAX_ELEMENTAL_CLASS) {
- ShowError("read_elemental_skilldb : Class not found in elemental_db for skill entry, line %d.\n", k);
- continue;
- }
-
- skillid = atoi(str[1]);
- if (skillid < EL_SKILLBASE || skillid >= EL_SKILLBASE + MAX_ELEMENTALSKILL) {
- ShowError("read_elemental_skilldb : Skill out of range, line %d.\n", k);
- continue;
- }
-
- db = &elemental_db[i];
- skilllv = atoi(str[2]);
-
- skillmode = atoi(str[3]);
- if (skillmode < EL_SKILLMODE_PASIVE || skillmode > EL_SKILLMODE_AGGRESSIVE) {
- ShowError("read_elemental_skilldb : Skillmode out of range, line %d.\n",k);
- continue;
- }
- ARR_FIND(0, MAX_ELESKILLTREE, i, db->skill[i].id == 0 || db->skill[i].id == skillid);
- if (i == MAX_ELESKILLTREE) {
- ShowWarning("Unable to load skill %d into Elemental %d's tree. Maximum number of skills per elemental has been reached.\n", skillid, class_);
- continue;
- }
- db->skill[i].id = skillid;
- db->skill[i].lv = skilllv;
- db->skill[i].mode = skillmode;
- j++;
- }
-
- fclose(fp);
- ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"db/elemental_skill_db.txt"CL_RESET"'.\n",j);
- return 0;
+int read_elemental_skilldb(void) {
+ FILE *fp;
+ char line[1024], *p;
+ char *str[4];
+ struct s_elemental_db *db;
+ int i, j = 0, k = 0, class_;
+ int skillid, skilllv, skillmode;
+
+ sprintf(line, "%s/%s", db_path, "elemental_skill_db.txt");
+ fp = fopen(line, "r");
+ if( !fp ) {
+ ShowError("read_elemental_skilldb : can't read elemental_skill_db.txt\n");
+ return -1;
+ }
+
+ while( fgets(line, sizeof(line), fp) ) {
+ k++;
+ if( line[0] == '/' && line[1] == '/' )
+ continue;
+
+ if( line[0] == '\0' || line[0] == '\n' || line[0] == '\r')
+ continue;
+
+ i = 0;
+ p = strtok(line, ",");
+ while( p != NULL && i < 4 ) {
+ str[i++] = p;
+ p = strtok(NULL, ",");
+ }
+ if( i < 4 ) {
+ ShowError("read_elemental_skilldb : Incorrect number of columns at elemental_skill_db.txt line %d.\n", k);
+ continue;
+ }
+
+ class_ = atoi(str[0]);
+ ARR_FIND(0, MAX_ELEMENTAL_CLASS, i, class_ == elemental_db[i].class_);
+ if( i == MAX_ELEMENTAL_CLASS ) {
+ ShowError("read_elemental_skilldb : Class not found in elemental_db for skill entry, line %d.\n", k);
+ continue;
+ }
+
+ skillid = atoi(str[1]);
+ if( skillid < EL_SKILLBASE || skillid >= EL_SKILLBASE + MAX_ELEMENTALSKILL ) {
+ ShowError("read_elemental_skilldb : Skill out of range, line %d.\n", k);
+ continue;
+ }
+
+ db = &elemental_db[i];
+ skilllv = atoi(str[2]);
+
+ skillmode = atoi(str[3]);
+ if( skillmode < EL_SKILLMODE_PASIVE || skillmode > EL_SKILLMODE_AGGRESSIVE ) {
+ ShowError("read_elemental_skilldb : Skillmode out of range, line %d.\n",k);
+ continue;
+ }
+ ARR_FIND( 0, MAX_ELESKILLTREE, i, db->skill[i].id == 0 || db->skill[i].id == skillid );
+ if( i == MAX_ELESKILLTREE ) {
+ ShowWarning("Unable to load skill %d into Elemental %d's tree. Maximum number of skills per elemental has been reached.\n", skillid, class_);
+ continue;
+ }
+ db->skill[i].id = skillid;
+ db->skill[i].lv = skilllv;
+ db->skill[i].mode = skillmode;
+ j++;
+ }
+
+ fclose(fp);
+ ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"db/elemental_skill_db.txt"CL_RESET"'.\n",j);
+ return 0;
}
-void reload_elementaldb(void)
-{
- read_elementaldb();
- reload_elemental_skilldb();
+void reload_elementaldb(void) {
+ read_elementaldb();
+ reload_elemental_skilldb();
}
-void reload_elemental_skilldb(void)
-{
- read_elemental_skilldb();
+void reload_elemental_skilldb(void) {
+ read_elemental_skilldb();
}
-int do_init_elemental(void)
-{
- read_elementaldb();
- read_elemental_skilldb();
-
- add_timer_func_list(elemental_ai_timer,"elemental_ai_timer");
- add_timer_interval(gettick()+MIN_ELETHINKTIME,elemental_ai_timer,0,0,MIN_ELETHINKTIME);
-
- return 0;
+int do_init_elemental(void) {
+ read_elementaldb();
+ read_elemental_skilldb();
+
+ add_timer_func_list(elemental_ai_timer,"elemental_ai_timer");
+ add_timer_interval(gettick()+MIN_ELETHINKTIME,elemental_ai_timer,0,0,MIN_ELETHINKTIME);
+
+ return 0;
}
-void do_final_elemental(void)
-{
- return;
+void do_final_elemental(void) {
+ return;
}
diff --git a/src/map/elemental.h b/src/map/elemental.h
index 221ae3b9f..1f99bcba9 100644
--- a/src/map/elemental.h
+++ b/src/map/elemental.h
@@ -20,44 +20,44 @@
#define EL_SKILLMODE_AGGRESSIVE 0x4
struct elemental_skill {
- unsigned short id, lv;
- short mode;
+ unsigned short id, lv;
+ short mode;
};
struct s_elemental_db {
- int class_;
- char sprite[NAME_LENGTH], name[NAME_LENGTH];
- unsigned short lv;
- short range2, range3;
- struct status_data status;
- struct view_data vd;
- struct elemental_skill skill[MAX_ELESKILLTREE];
+ int class_;
+ char sprite[NAME_LENGTH], name[NAME_LENGTH];
+ unsigned short lv;
+ short range2, range3;
+ struct status_data status;
+ struct view_data vd;
+ struct elemental_skill skill[MAX_ELESKILLTREE];
};
extern struct s_elemental_db elemental_db[MAX_ELEMENTAL_CLASS];
struct elemental_data {
- struct block_list bl;
- struct unit_data ud;
- struct view_data *vd;
- struct status_data base_status, battle_status;
- struct status_change sc;
- struct regen_data regen;
-
- struct s_elemental_db *db;
- struct s_elemental elemental;
-
- struct map_session_data *master;
- int summon_timer;
- int skill_timer;
-
- unsigned last_thinktime, last_linktime;
- short min_chase;
- int target_id, attacked_id;
+ struct block_list bl;
+ struct unit_data ud;
+ struct view_data *vd;
+ struct status_data base_status, battle_status;
+ struct status_change sc;
+ struct regen_data regen;
+
+ struct s_elemental_db *db;
+ struct s_elemental elemental;
+
+ struct map_session_data *master;
+ int summon_timer;
+ int skill_timer;
+
+ unsigned last_thinktime, last_linktime;
+ short min_chase;
+ int target_id, attacked_id;
};
bool elemental_class(int class_);
-struct view_data *elemental_get_viewdata(int class_);
+struct view_data * elemental_get_viewdata(int class_);
int elemental_create(struct map_session_data *sd, int class_, unsigned int lifetime);
int elemental_data_received(struct s_elemental *ele, bool flag);
@@ -76,7 +76,7 @@ int elemental_get_lifetime(struct elemental_data *ed);
int elemental_unlocktarget(struct elemental_data *ed);
int elemental_skillnotok(int skillid, struct elemental_data *ed);
-int elemental_set_target(struct map_session_data *sd, struct block_list *bl);
+int elemental_set_target( struct map_session_data *sd, struct block_list *bl );
int elemental_clean_single_effect(struct elemental_data *ed, int skill_num);
int elemental_clean_effect(struct elemental_data *ed);
int elemental_action(struct elemental_data *ed, struct block_list *bl, unsigned int tick);
diff --git a/src/map/guild.c b/src/map/guild.c
index b276114be..9eeae7cf1 100644
--- a/src/map/guild.c
+++ b/src/map/guild.c
@@ -29,37 +29,37 @@
#include <string.h>
-static DBMap *guild_db; // int guild_id -> struct guild*
-static DBMap *castle_db; // int castle_id -> struct guild_castle*
-static DBMap *guild_expcache_db; // int char_id -> struct guild_expcache*
-static DBMap *guild_infoevent_db; // int guild_id -> struct eventlist*
+static DBMap* guild_db; // int guild_id -> struct guild*
+static DBMap* castle_db; // int castle_id -> struct guild_castle*
+static DBMap* guild_expcache_db; // int char_id -> struct guild_expcache*
+static DBMap* guild_infoevent_db; // int guild_id -> struct eventlist*
struct eventlist {
- char name[EVENT_NAME_LENGTH];
- struct eventlist *next;
+ char name[EVENT_NAME_LENGTH];
+ struct eventlist *next;
};
//Constant related to the flash of the Guild EXP cache
-#define GUILD_SEND_XY_INVERVAL 5000 // Interval of sending coordinates and HP
+#define GUILD_SEND_XY_INVERVAL 5000 // Interval of sending coordinates and HP
#define GUILD_PAYEXP_INVERVAL 10000 //Interval (maximum survival time of the cache, in milliseconds)
#define GUILD_PAYEXP_LIST 8192 //The maximum number of cache
//Guild EXP cache
struct guild_expcache {
- int guild_id, account_id, char_id;
- uint64 exp;
+ int guild_id, account_id, char_id;
+ uint64 exp;
};
static struct eri *expcache_ers; //For handling of guild exp payment.
#define MAX_GUILD_SKILL_REQUIRE 5
-struct {
- int id;
- int max;
- struct {
- short id;
- short lv;
- } need[MAX_GUILD_SKILL_REQUIRE];
+struct{
+ int id;
+ int max;
+ struct{
+ short id;
+ short lv;
+ }need[MAX_GUILD_SKILL_REQUIRE];
} guild_skill_tree[MAX_GUILDSKILL];
int guild_payexp_timer(int tid, unsigned int tick, int id, intptr_t data);
@@ -72,34 +72,33 @@ unsigned short guild_flags_count;
/*==========================================
* Retrieves and validates the sd pointer for this guild member [Skotlex]
*------------------------------------------*/
-static TBL_PC *guild_sd_check(int guild_id, int account_id, int char_id)
+static TBL_PC* guild_sd_check(int guild_id, int account_id, int char_id)
{
- TBL_PC *sd = map_id2sd(account_id);
+ TBL_PC* sd = map_id2sd(account_id);
- if (!(sd && sd->status.char_id == char_id))
- return NULL;
+ if (!(sd && sd->status.char_id == char_id))
+ return NULL;
- if (sd->status.guild_id != guild_id) {
- //If player belongs to a different guild, kick him out.
- intif_guild_leave(guild_id,account_id,char_id,0,"** Guild Mismatch **");
- return NULL;
- }
+ if (sd->status.guild_id != guild_id)
+ { //If player belongs to a different guild, kick him out.
+ intif_guild_leave(guild_id,account_id,char_id,0,"** Guild Mismatch **");
+ return NULL;
+ }
- return sd;
+ return sd;
}
-// Modified [Komurka]
-int guild_skill_get_max(int id)
+ // Modified [Komurka]
+int guild_skill_get_max (int id)
{
- if (id < GD_SKILLBASE || id >= GD_SKILLBASE+MAX_GUILDSKILL)
- return 0;
- return guild_skill_tree[id-GD_SKILLBASE].max;
+ if (id < GD_SKILLBASE || id >= GD_SKILLBASE+MAX_GUILDSKILL)
+ return 0;
+ return guild_skill_tree[id-GD_SKILLBASE].max;
}
// Retrive skilllv learned by guild
-int guild_checkskill(struct guild *g, int id)
-{
+int guild_checkskill(struct guild *g, int id) {
int idx = id - GD_SKILLBASE;
if (idx < 0 || idx >= MAX_GUILDSKILL)
return 0;
@@ -109,33 +108,34 @@ int guild_checkskill(struct guild *g, int id)
/*==========================================
* guild_skill_tree.txt reading - from jA [Komurka]
*------------------------------------------*/
-static bool guild_read_guildskill_tree_db(char *split[], int columns, int current)
-{
- // <skill id>,<max lv>,<req id1>,<req lv1>,<req id2>,<req lv2>,<req id3>,<req lv3>,<req id4>,<req lv4>,<req id5>,<req lv5>
- int k, id, skillid;
+static bool guild_read_guildskill_tree_db(char* split[], int columns, int current)
+{// <skill id>,<max lv>,<req id1>,<req lv1>,<req id2>,<req lv2>,<req id3>,<req lv3>,<req id4>,<req lv4>,<req id5>,<req lv5>
+ int k, id, skillid;
- skillid = atoi(split[0]);
- id = skillid - GD_SKILLBASE;
+ skillid = atoi(split[0]);
+ id = skillid - GD_SKILLBASE;
- if (id < 0 || id >= MAX_GUILDSKILL) {
- ShowWarning("guild_read_guildskill_tree_db: Invalid skill id %d.\n", skillid);
- return false;
- }
+ if( id < 0 || id >= MAX_GUILDSKILL )
+ {
+ ShowWarning("guild_read_guildskill_tree_db: Invalid skill id %d.\n", skillid);
+ return false;
+ }
- guild_skill_tree[id].id = skillid;
- guild_skill_tree[id].max = atoi(split[1]);
+ guild_skill_tree[id].id = skillid;
+ guild_skill_tree[id].max = atoi(split[1]);
- if (guild_skill_tree[id].id == GD_GLORYGUILD && battle_config.require_glory_guild && guild_skill_tree[id].max == 0) {
- // enable guild's glory when required for emblems
- guild_skill_tree[id].max = 1;
- }
+ if( guild_skill_tree[id].id == GD_GLORYGUILD && battle_config.require_glory_guild && guild_skill_tree[id].max == 0 )
+ {// enable guild's glory when required for emblems
+ guild_skill_tree[id].max = 1;
+ }
- for (k = 0; k < MAX_GUILD_SKILL_REQUIRE; k++) {
- guild_skill_tree[id].need[k].id = atoi(split[k*2+2]);
- guild_skill_tree[id].need[k].lv = atoi(split[k*2+3]);
- }
+ for( k = 0; k < MAX_GUILD_SKILL_REQUIRE; k++ )
+ {
+ guild_skill_tree[id].need[k].id = atoi(split[k*2+2]);
+ guild_skill_tree[id].need[k].lv = atoi(split[k*2+3]);
+ }
- return true;
+ return true;
}
/*==========================================
@@ -143,179 +143,186 @@ static bool guild_read_guildskill_tree_db(char *split[], int columns, int curren
*------------------------------------------*/
int guild_check_skill_require(struct guild *g,int id)
{
- int i;
- int idx = id-GD_SKILLBASE;
+ int i;
+ int idx = id-GD_SKILLBASE;
- if (g == NULL)
- return 0;
+ if(g == NULL)
+ return 0;
- if (idx < 0 || idx >= MAX_GUILDSKILL)
- return 0;
+ if (idx < 0 || idx >= MAX_GUILDSKILL)
+ return 0;
- for (i=0; i<MAX_GUILD_SKILL_REQUIRE; i++) {
- if (guild_skill_tree[idx].need[i].id == 0) break;
- if (guild_skill_tree[idx].need[i].lv > guild_checkskill(g,guild_skill_tree[idx].need[i].id))
- return 0;
- }
- return 1;
+ for(i=0;i<MAX_GUILD_SKILL_REQUIRE;i++)
+ {
+ if(guild_skill_tree[idx].need[i].id == 0) break;
+ if(guild_skill_tree[idx].need[i].lv > guild_checkskill(g,guild_skill_tree[idx].need[i].id))
+ return 0;
+ }
+ return 1;
}
-static bool guild_read_castledb(char *str[], int columns, int current)
-{
- // <castle id>,<map name>,<castle name>,<castle event>[,<reserved/unused switch flag>]
- struct guild_castle *gc;
- int mapindex = mapindex_name2id(str[1]);
+static bool guild_read_castledb(char* str[], int columns, int current)
+{// <castle id>,<map name>,<castle name>,<castle event>[,<reserved/unused switch flag>]
+ struct guild_castle *gc;
+ int mapindex = mapindex_name2id(str[1]);
- if (map_mapindex2mapid(mapindex) < 0) // Map not found or on another map-server
- return false;
+ if (map_mapindex2mapid(mapindex) < 0) // Map not found or on another map-server
+ return false;
- CREATE(gc, struct guild_castle, 1);
- gc->castle_id = atoi(str[0]);
- gc->mapindex = mapindex;
- safestrncpy(gc->castle_name, str[2], sizeof(gc->castle_name));
- safestrncpy(gc->castle_event, str[3], sizeof(gc->castle_event));
+ CREATE(gc, struct guild_castle, 1);
+ gc->castle_id = atoi(str[0]);
+ gc->mapindex = mapindex;
+ safestrncpy(gc->castle_name, str[2], sizeof(gc->castle_name));
+ safestrncpy(gc->castle_event, str[3], sizeof(gc->castle_event));
- idb_put(castle_db,gc->castle_id,gc);
+ idb_put(castle_db,gc->castle_id,gc);
- //intif_guild_castle_info(gc->castle_id);
+ //intif_guild_castle_info(gc->castle_id);
- return true;
+ return true;
}
/// lookup: guild id -> guild*
-struct guild *guild_search(int guild_id) {
- return (struct guild *)idb_get(guild_db,guild_id);
+struct guild* guild_search(int guild_id)
+{
+ return (struct guild*)idb_get(guild_db,guild_id);
}
/// lookup: guild name -> guild*
-struct guild *guild_searchname(char *str) {
- struct guild *g;
- DBIterator *iter = db_iterator(guild_db);
+struct guild* guild_searchname(char* str)
+{
+ struct guild* g;
+ DBIterator *iter = db_iterator(guild_db);
- for (g = dbi_first(iter); dbi_exists(iter); g = dbi_next(iter)) {
- if (strcmpi(g->name, str) == 0)
- break;
- }
- dbi_destroy(iter);
+ for( g = dbi_first(iter); dbi_exists(iter); g = dbi_next(iter) )
+ {
+ if( strcmpi(g->name, str) == 0 )
+ break;
+ }
+ dbi_destroy(iter);
- return g;
+ return g;
}
/// lookup: castle id -> castle*
-struct guild_castle *guild_castle_search(int gcid) {
- return (struct guild_castle *)idb_get(castle_db,gcid);
+struct guild_castle* guild_castle_search(int gcid)
+{
+ return (struct guild_castle*)idb_get(castle_db,gcid);
}
/// lookup: map index -> castle*
-struct guild_castle *guild_mapindex2gc(short mapindex) {
- struct guild_castle *gc;
- DBIterator *iter = db_iterator(castle_db);
+struct guild_castle* guild_mapindex2gc(short mapindex)
+{
+ struct guild_castle* gc;
+ DBIterator *iter = db_iterator(castle_db);
- for (gc = dbi_first(iter); dbi_exists(iter); gc = dbi_next(iter)) {
- if (gc->mapindex == mapindex)
- break;
- }
- dbi_destroy(iter);
+ for( gc = dbi_first(iter); dbi_exists(iter); gc = dbi_next(iter) )
+ {
+ if( gc->mapindex == mapindex )
+ break;
+ }
+ dbi_destroy(iter);
- return gc;
+ return gc;
}
/// lookup: map name -> castle*
-struct guild_castle *guild_mapname2gc(const char *mapname) {
- return guild_mapindex2gc(mapindex_name2id(mapname));
+struct guild_castle* guild_mapname2gc(const char* mapname)
+{
+ return guild_mapindex2gc(mapindex_name2id(mapname));
}
-struct map_session_data *guild_getavailablesd(struct guild *g) {
- int i;
+struct map_session_data* guild_getavailablesd(struct guild* g)
+{
+ int i;
- nullpo_retr(NULL, g);
+ nullpo_retr(NULL, g);
- ARR_FIND(0, g->max_member, i, g->member[i].sd != NULL);
- return(i < g->max_member) ? g->member[i].sd : NULL;
+ ARR_FIND( 0, g->max_member, i, g->member[i].sd != NULL );
+ return( i < g->max_member ) ? g->member[i].sd : NULL;
}
/// lookup: player AID/CID -> member index
int guild_getindex(struct guild *g,int account_id,int char_id)
{
- int i;
+ int i;
- if (g == NULL)
- return -1;
+ if( g == NULL )
+ return -1;
- ARR_FIND(0, g->max_member, i, g->member[i].account_id == account_id && g->member[i].char_id == char_id);
- return(i < g->max_member) ? i : -1;
+ ARR_FIND( 0, g->max_member, i, g->member[i].account_id == account_id && g->member[i].char_id == char_id );
+ return( i < g->max_member ) ? i : -1;
}
/// lookup: player sd -> member position
-int guild_getposition(struct guild *g, struct map_session_data *sd)
+int guild_getposition(struct guild* g, struct map_session_data* sd)
{
- int i;
-
- if (g == NULL && (g=guild_search(sd->status.guild_id)) == NULL)
- return -1;
+ int i;
- ARR_FIND(0, g->max_member, i, g->member[i].account_id == sd->status.account_id && g->member[i].char_id == sd->status.char_id);
- return(i < g->max_member) ? g->member[i].position : -1;
+ if( g == NULL && (g=guild_search(sd->status.guild_id)) == NULL )
+ return -1;
+
+ ARR_FIND( 0, g->max_member, i, g->member[i].account_id == sd->status.account_id && g->member[i].char_id == sd->status.char_id );
+ return( i < g->max_member ) ? g->member[i].position : -1;
}
//Creation of member information
void guild_makemember(struct guild_member *m,struct map_session_data *sd)
{
- nullpo_retv(sd);
+ nullpo_retv(sd);
- memset(m,0,sizeof(struct guild_member));
- m->account_id =sd->status.account_id;
- m->char_id =sd->status.char_id;
- m->hair =sd->status.hair;
- m->hair_color =sd->status.hair_color;
- m->gender =sd->status.sex;
- m->class_ =sd->status.class_;
- m->lv =sd->status.base_level;
- // m->exp =0;
- // m->exp_payper =0;
- m->online =1;
- m->position =MAX_GUILDPOSITION-1;
- memcpy(m->name,sd->status.name,NAME_LENGTH);
- return;
+ memset(m,0,sizeof(struct guild_member));
+ m->account_id =sd->status.account_id;
+ m->char_id =sd->status.char_id;
+ m->hair =sd->status.hair;
+ m->hair_color =sd->status.hair_color;
+ m->gender =sd->status.sex;
+ m->class_ =sd->status.class_;
+ m->lv =sd->status.base_level;
+// m->exp =0;
+// m->exp_payper =0;
+ m->online =1;
+ m->position =MAX_GUILDPOSITION-1;
+ memcpy(m->name,sd->status.name,NAME_LENGTH);
+ return;
}
/**
* Server cache to be flushed to inter the Guild EXP
* @see DBApply
*/
-int guild_payexp_timer_sub(DBKey key, DBData *data, va_list ap)
-{
- int i;
- struct guild_expcache *c;
- struct guild *g;
-
- c = db_data2ptr(data);
-
- if (
- (g = guild_search(c->guild_id)) == NULL ||
- (i = guild_getindex(g, c->account_id, c->char_id)) < 0
- ) {
- ers_free(expcache_ers, c);
- return 0;
- }
-
- if (g->member[i].exp > UINT64_MAX - c->exp)
- g->member[i].exp = UINT64_MAX;
- else
- g->member[i].exp+= c->exp;
-
- intif_guild_change_memberinfo(g->guild_id,c->account_id,c->char_id,
- GMI_EXP,&g->member[i].exp,sizeof(g->member[i].exp));
- c->exp=0;
-
- ers_free(expcache_ers, c);
- return 0;
+int guild_payexp_timer_sub(DBKey key, DBData *data, va_list ap) {
+ int i;
+ struct guild_expcache *c;
+ struct guild *g;
+
+ c = db_data2ptr(data);
+
+ if (
+ (g = guild_search(c->guild_id)) == NULL ||
+ (i = guild_getindex(g, c->account_id, c->char_id)) < 0
+ ) {
+ ers_free(expcache_ers, c);
+ return 0;
+ }
+
+ if (g->member[i].exp > UINT64_MAX - c->exp)
+ g->member[i].exp = UINT64_MAX;
+ else
+ g->member[i].exp+= c->exp;
+
+ intif_guild_change_memberinfo(g->guild_id,c->account_id,c->char_id,
+ GMI_EXP,&g->member[i].exp,sizeof(g->member[i].exp));
+ c->exp=0;
+
+ ers_free(expcache_ers, c);
+ return 0;
}
int guild_payexp_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- guild_expcache_db->clear(guild_expcache_db,guild_payexp_timer_sub);
- return 0;
+ guild_expcache_db->clear(guild_expcache_db,guild_payexp_timer_sub);
+ return 0;
}
/**
@@ -324,218 +331,226 @@ int guild_payexp_timer(int tid, unsigned int tick, int id, intptr_t data)
*/
int guild_send_xy_timer_sub(DBKey key, DBData *data, va_list ap)
{
- struct guild *g = db_data2ptr(data);
- int i;
+ struct guild *g = db_data2ptr(data);
+ int i;
- nullpo_ret(g);
+ nullpo_ret(g);
- if (!g->connect_member) {
- // no members connected to this guild so do not iterate
- return 0;
- }
+ if( !g->connect_member )
+ {// no members connected to this guild so do not iterate
+ return 0;
+ }
- for (i=0; i<g->max_member; i++) {
- struct map_session_data *sd = g->member[i].sd;
- if (sd != NULL && sd->fd && (sd->guild_x != sd->bl.x || sd->guild_y != sd->bl.y) && !sd->bg_id) {
- clif_guild_xy(sd);
- sd->guild_x = sd->bl.x;
- sd->guild_y = sd->bl.y;
- }
- }
- return 0;
+ for(i=0;i<g->max_member;i++){
+ struct map_session_data* sd = g->member[i].sd;
+ if( sd != NULL && sd->fd && (sd->guild_x != sd->bl.x || sd->guild_y != sd->bl.y) && !sd->bg_id )
+ {
+ clif_guild_xy(sd);
+ sd->guild_x = sd->bl.x;
+ sd->guild_y = sd->bl.y;
+ }
+ }
+ return 0;
}
//Code from party_send_xy_timer [Skotlex]
static int guild_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- guild_db->foreach(guild_db,guild_send_xy_timer_sub,tick);
- return 0;
+ guild_db->foreach(guild_db,guild_send_xy_timer_sub,tick);
+ return 0;
}
int guild_send_dot_remove(struct map_session_data *sd)
{
- if (sd->status.guild_id)
- clif_guild_xy_remove(sd);
- return 0;
+ if (sd->status.guild_id)
+ clif_guild_xy_remove(sd);
+ return 0;
}
//------------------------------------------------------------------------
int guild_create(struct map_session_data *sd, const char *name)
{
- char tname[NAME_LENGTH];
- struct guild_member m;
- nullpo_ret(sd);
+ char tname[NAME_LENGTH];
+ struct guild_member m;
+ nullpo_ret(sd);
- safestrncpy(tname, name, NAME_LENGTH);
- trim(tname);
+ safestrncpy(tname, name, NAME_LENGTH);
+ trim(tname);
- if (!tname[0])
- return 0; // empty name
+ if( !tname[0] )
+ return 0; // empty name
- if (sd->status.guild_id) {
- // already in a guild
- clif_guild_created(sd,1);
- return 0;
- }
- if (battle_config.guild_emperium_check && pc_search_inventory(sd,714) == -1) {
- // item required
- clif_guild_created(sd,3);
- return 0;
- }
+ if( sd->status.guild_id )
+ {// already in a guild
+ clif_guild_created(sd,1);
+ return 0;
+ }
+ if( battle_config.guild_emperium_check && pc_search_inventory(sd,714) == -1 )
+ {// item required
+ clif_guild_created(sd,3);
+ return 0;
+ }
- guild_makemember(&m,sd);
- m.position=0;
- intif_guild_create(name,&m);
- return 1;
+ guild_makemember(&m,sd);
+ m.position=0;
+ intif_guild_create(name,&m);
+ return 1;
}
//Whether or not to create guild
int guild_created(int account_id,int guild_id)
{
- struct map_session_data *sd=map_id2sd(account_id);
+ struct map_session_data *sd=map_id2sd(account_id);
- if (sd==NULL)
- return 0;
- if (!guild_id) {
+ if(sd==NULL)
+ return 0;
+ if(!guild_id) {
clif_guild_created(sd, 2); // Creation failure (presence of the same name Guild)
- return 0;
- }
- //struct guild *g;
- sd->status.guild_id=guild_id;
- clif_guild_created(sd,0);
- if (battle_config.guild_emperium_check)
- pc_delitem(sd,pc_search_inventory(sd,ITEMID_EMPERIUM),1,0,0,LOG_TYPE_CONSUME); //emperium consumption
- return 0;
+ return 0;
+ }
+ //struct guild *g;
+ sd->status.guild_id=guild_id;
+ clif_guild_created(sd,0);
+ if(battle_config.guild_emperium_check)
+ pc_delitem(sd,pc_search_inventory(sd,ITEMID_EMPERIUM),1,0,0,LOG_TYPE_CONSUME); //emperium consumption
+ return 0;
}
//Information request
int guild_request_info(int guild_id)
{
- return intif_guild_request_info(guild_id);
+ return intif_guild_request_info(guild_id);
}
//Information request with event
int guild_npc_request_info(int guild_id,const char *event)
{
- if (guild_search(guild_id)) {
- if (event && *event)
- npc_event_do(event);
+ if( guild_search(guild_id) )
+ {
+ if( event && *event )
+ npc_event_do(event);
- return 0;
- }
+ return 0;
+ }
- if (event && *event) {
- struct eventlist *ev;
- DBData prev;
- ev=(struct eventlist *)aCalloc(sizeof(struct eventlist),1);
- memcpy(ev->name,event,strlen(event));
- //The one in the db (if present) becomes the next event from this.
- if (guild_infoevent_db->put(guild_infoevent_db, db_i2key(guild_id), db_ptr2data(ev), &prev))
- ev->next = db_data2ptr(&prev);
- }
+ if( event && *event )
+ {
+ struct eventlist *ev;
+ DBData prev;
+ ev=(struct eventlist *)aCalloc(sizeof(struct eventlist),1);
+ memcpy(ev->name,event,strlen(event));
+ //The one in the db (if present) becomes the next event from this.
+ if (guild_infoevent_db->put(guild_infoevent_db, db_i2key(guild_id), db_ptr2data(ev), &prev))
+ ev->next = db_data2ptr(&prev);
+ }
- return guild_request_info(guild_id);
+ return guild_request_info(guild_id);
}
//Confirmation of the character belongs to guild
int guild_check_member(struct guild *g)
{
- int i;
- struct map_session_data *sd;
- struct s_mapiterator *iter;
+ int i;
+ struct map_session_data *sd;
+ struct s_mapiterator* iter;
- nullpo_ret(g);
+ nullpo_ret(g);
- iter = mapit_getallusers();
- for (sd = (TBL_PC *)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC *)mapit_next(iter)) {
- if (sd->status.guild_id != g->guild_id)
- continue;
+ iter = mapit_getallusers();
+ for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
+ {
+ if( sd->status.guild_id != g->guild_id )
+ continue;
- i = guild_getindex(g,sd->status.account_id,sd->status.char_id);
- if (i < 0) {
- sd->status.guild_id=0;
- sd->guild_emblem_id=0;
- ShowWarning("guild: check_member %d[%s] is not member\n",sd->status.account_id,sd->status.name);
- }
- }
- mapit_free(iter);
+ i = guild_getindex(g,sd->status.account_id,sd->status.char_id);
+ if (i < 0) {
+ sd->status.guild_id=0;
+ sd->guild_emblem_id=0;
+ ShowWarning("guild: check_member %d[%s] is not member\n",sd->status.account_id,sd->status.name);
+ }
+ }
+ mapit_free(iter);
- return 0;
+ return 0;
}
//Delete association with guild_id for all characters
int guild_recv_noinfo(int guild_id)
{
- struct map_session_data *sd;
- struct s_mapiterator *iter;
+ struct map_session_data *sd;
+ struct s_mapiterator* iter;
- iter = mapit_getallusers();
- for (sd = (TBL_PC *)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC *)mapit_next(iter)) {
- if (sd->status.guild_id == guild_id)
- sd->status.guild_id = 0; // erase guild
- }
- mapit_free(iter);
+ iter = mapit_getallusers();
+ for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
+ {
+ if( sd->status.guild_id == guild_id )
+ sd->status.guild_id = 0; // erase guild
+ }
+ mapit_free(iter);
- return 0;
+ return 0;
}
//Get and display information for all member
int guild_recv_info(struct guild *sg)
{
- struct guild *g,before;
- int i,bm,m;
- DBData data;
- struct map_session_data *sd;
- bool guild_new = false;
+ struct guild *g,before;
+ int i,bm,m;
+ DBData data;
+ struct map_session_data *sd;
+ bool guild_new = false;
- nullpo_ret(sg);
+ nullpo_ret(sg);
- if ((g = (struct guild *)idb_get(guild_db,sg->guild_id))==NULL) {
- guild_new = true;
- g=(struct guild *)aCalloc(1,sizeof(struct guild));
- idb_put(guild_db,sg->guild_id,g);
- before=*sg;
+ if((g = (struct guild*)idb_get(guild_db,sg->guild_id))==NULL)
+ {
+ guild_new = true;
+ g=(struct guild *)aCalloc(1,sizeof(struct guild));
+ idb_put(guild_db,sg->guild_id,g);
+ before=*sg;
//Perform the check on the user because the first load
- guild_check_member(sg);
- if ((sd = map_nick2sd(sg->master)) != NULL) {
- //If the guild master is online the first time the guild_info is received,
- //that means he was the first to join, so apply guild skill blocking here.
- if (battle_config.guild_skill_relog_delay)
- guild_block_skill(sd, 300000);
-
- //Also set the guild master flag.
- sd->state.gmaster_flag = g;
- clif_charnameupdate(sd); // [LuzZza]
- clif_guild_masterormember(sd);
- }
- } else
- before=*g;
- memcpy(g,sg,sizeof(struct guild));
-
- if (g->max_member > MAX_GUILD) {
- ShowError("guild_recv_info: Received guild with %d members, but MAX_GUILD is only %d. Extra guild-members have been lost!\n", g->max_member, MAX_GUILD);
- g->max_member = MAX_GUILD;
- }
-
- for (i=bm=m=0; i<g->max_member; i++) {
- if (g->member[i].account_id>0) {
- sd = g->member[i].sd = guild_sd_check(g->guild_id, g->member[i].account_id, g->member[i].char_id);
- if (sd) clif_charnameupdate(sd); // [LuzZza]
- m++;
- } else
- g->member[i].sd=NULL;
- if (before.member[i].account_id>0)
- bm++;
- }
+ guild_check_member(sg);
+ if ((sd = map_nick2sd(sg->master)) != NULL)
+ {
+ //If the guild master is online the first time the guild_info is received,
+ //that means he was the first to join, so apply guild skill blocking here.
+ if( battle_config.guild_skill_relog_delay )
+ guild_block_skill(sd, 300000);
+
+ //Also set the guild master flag.
+ sd->state.gmaster_flag = g;
+ clif_charnameupdate(sd); // [LuzZza]
+ clif_guild_masterormember(sd);
+ }
+ }else
+ before=*g;
+ memcpy(g,sg,sizeof(struct guild));
+
+ if(g->max_member > MAX_GUILD)
+ {
+ ShowError("guild_recv_info: Received guild with %d members, but MAX_GUILD is only %d. Extra guild-members have been lost!\n", g->max_member, MAX_GUILD);
+ g->max_member = MAX_GUILD;
+ }
+
+ for(i=bm=m=0;i<g->max_member;i++){
+ if(g->member[i].account_id>0){
+ sd = g->member[i].sd = guild_sd_check(g->guild_id, g->member[i].account_id, g->member[i].char_id);
+ if (sd) clif_charnameupdate(sd); // [LuzZza]
+ m++;
+ }else
+ g->member[i].sd=NULL;
+ if(before.member[i].account_id>0)
+ bm++;
+ }
for (i = 0; i < g->max_member; i++) { //Transmission of information at all members
- sd = g->member[i].sd;
- if (sd==NULL)
- continue;
+ sd = g->member[i].sd;
+ if( sd==NULL )
+ continue;
if (before.guild_lv != g->guild_lv || bm != m ||
- before.max_member != g->max_member) {
+ before.max_member != g->max_member) {
clif_guild_basicinfo(sd); //Submit basic information
clif_guild_emblem(sd, g); //Submit emblem
}
@@ -555,122 +570,126 @@ int guild_recv_info(struct guild *sg)
}
//Occurrence of an event
- if (guild_infoevent_db->remove(guild_infoevent_db, db_i2key(sg->guild_id), &data)) {
- struct eventlist *ev = db_data2ptr(&data), *ev2;
- while (ev) {
- npc_event_do(ev->name);
- ev2=ev->next;
- aFree(ev);
- ev=ev2;
- }
- }
+ if (guild_infoevent_db->remove(guild_infoevent_db, db_i2key(sg->guild_id), &data))
+ {
+ struct eventlist *ev = db_data2ptr(&data), *ev2;
+ while(ev){
+ npc_event_do(ev->name);
+ ev2=ev->next;
+ aFree(ev);
+ ev=ev2;
+ }
+ }
- return 0;
+ return 0;
}
/*=============================================
* Player sd send a guild invatation to player tsd to join his guild
*--------------------------------------------*/
-int guild_invite(struct map_session_data *sd, struct map_session_data *tsd)
-{
+int guild_invite(struct map_session_data *sd, struct map_session_data *tsd) {
struct guild *g;
int i;
- nullpo_ret(sd);
+ nullpo_ret(sd);
- g=guild_search(sd->status.guild_id);
+ g=guild_search(sd->status.guild_id);
- if (tsd==NULL || g==NULL)
- return 0;
+ if(tsd==NULL || g==NULL)
+ return 0;
- if ((i=guild_getposition(g,sd))<0 || !(g->position[i].mode&0x0001))
- return 0; //Invite permission.
+ if( (i=guild_getposition(g,sd))<0 || !(g->position[i].mode&0x0001) )
+ return 0; //Invite permission.
- if (!battle_config.invite_request_check) {
+ if(!battle_config.invite_request_check) {
if (tsd->party_invite > 0 || tsd->trade_partner || tsd->adopt_invite) { //checking if there no other invitation pending
- clif_guild_inviteack(sd,0);
- return 0;
- }
- }
-
- if (!tsd->fd) { //You can't invite someone who has already disconnected.
- clif_guild_inviteack(sd,1);
- return 0;
- }
-
- if (tsd->status.guild_id>0 ||
- tsd->guild_invite>0 ||
- ((agit_flag || agit2_flag) && map[tsd->bl.m].flag.gvg_castle)) {
- //Can't invite people inside castles. [Skotlex]
- clif_guild_inviteack(sd,0);
- return 0;
- }
+ clif_guild_inviteack(sd,0);
+ return 0;
+ }
+ }
+
+ if (!tsd->fd) { //You can't invite someone who has already disconnected.
+ clif_guild_inviteack(sd,1);
+ return 0;
+ }
+
+ if(tsd->status.guild_id>0 ||
+ tsd->guild_invite>0 ||
+ ((agit_flag || agit2_flag) && map[tsd->bl.m].flag.gvg_castle))
+ { //Can't invite people inside castles. [Skotlex]
+ clif_guild_inviteack(sd,0);
+ return 0;
+ }
//search an empty spot in guild
- ARR_FIND(0, g->max_member, i, g->member[i].account_id == 0);
- if (i==g->max_member) {
- clif_guild_inviteack(sd,3);
- return 0;
- }
+ ARR_FIND( 0, g->max_member, i, g->member[i].account_id == 0 );
+ if(i==g->max_member){
+ clif_guild_inviteack(sd,3);
+ return 0;
+ }
- tsd->guild_invite=sd->status.guild_id;
- tsd->guild_invite_account=sd->status.account_id;
+ tsd->guild_invite=sd->status.guild_id;
+ tsd->guild_invite_account=sd->status.account_id;
- clif_guild_invite(tsd,g);
- return 0;
+ clif_guild_invite(tsd,g);
+ return 0;
}
/// Guild invitation reply.
/// flag: 0:rejected, 1:accepted
-int guild_reply_invite(struct map_session_data *sd, int guild_id, int flag)
-{
- struct map_session_data *tsd;
-
- nullpo_ret(sd);
-
- // subsequent requests may override the value
- if (sd->guild_invite != guild_id)
- return 0; // mismatch
-
- // look up the person who sent the invite
- //NOTE: this can be NULL because the person might have logged off in the meantime
- tsd = map_id2sd(sd->guild_invite_account);
-
- if (sd->status.guild_id > 0) { // [Paradox924X]
- // Already in another guild.
- if (tsd) clif_guild_inviteack(tsd,0);
- return 0;
- } else if (flag == 0) {
- // rejected
- sd->guild_invite = 0;
- sd->guild_invite_account = 0;
- if (tsd) clif_guild_inviteack(tsd,1);
- } else {
- // accepted
- struct guild_member m;
- struct guild *g;
- int i;
-
- if ((g=guild_search(guild_id)) == NULL) {
- sd->guild_invite = 0;
- sd->guild_invite_account = 0;
- return 0;
- }
-
- ARR_FIND(0, g->max_member, i, g->member[i].account_id == 0);
- if (i == g->max_member) {
- sd->guild_invite = 0;
- sd->guild_invite_account = 0;
- if (tsd) clif_guild_inviteack(tsd,3);
- return 0;
- }
-
- guild_makemember(&m,sd);
- intif_guild_addmember(guild_id, &m);
- //TODO: send a minimap update to this player
- }
-
- return 0;
+int guild_reply_invite(struct map_session_data* sd, int guild_id, int flag)
+{
+ struct map_session_data* tsd;
+
+ nullpo_ret(sd);
+
+ // subsequent requests may override the value
+ if( sd->guild_invite != guild_id )
+ return 0; // mismatch
+
+ // look up the person who sent the invite
+ //NOTE: this can be NULL because the person might have logged off in the meantime
+ tsd = map_id2sd(sd->guild_invite_account);
+
+ if ( sd->status.guild_id > 0 ) // [Paradox924X]
+ { // Already in another guild.
+ if ( tsd ) clif_guild_inviteack(tsd,0);
+ return 0;
+ }
+ else if( flag == 0 )
+ {// rejected
+ sd->guild_invite = 0;
+ sd->guild_invite_account = 0;
+ if( tsd ) clif_guild_inviteack(tsd,1);
+ }
+ else
+ {// accepted
+ struct guild_member m;
+ struct guild* g;
+ int i;
+
+ if( (g=guild_search(guild_id)) == NULL )
+ {
+ sd->guild_invite = 0;
+ sd->guild_invite_account = 0;
+ return 0;
+ }
+
+ ARR_FIND( 0, g->max_member, i, g->member[i].account_id == 0 );
+ if( i == g->max_member )
+ {
+ sd->guild_invite = 0;
+ sd->guild_invite_account = 0;
+ if( tsd ) clif_guild_inviteack(tsd,3);
+ return 0;
+ }
+
+ guild_makemember(&m,sd);
+ intif_guild_addmember(guild_id, &m);
+ //TODO: send a minimap update to this player
+ }
+
+ return 0;
}
//Invoked when a player joins.
@@ -679,25 +698,25 @@ int guild_reply_invite(struct map_session_data *sd, int guild_id, int flag)
//- Player must be authed and must belong to a guild before invoking this method
void guild_member_joined(struct map_session_data *sd)
{
- struct guild *g;
- int i;
- g=guild_search(sd->status.guild_id);
- if (!g) {
- guild_request_info(sd->status.guild_id);
- return;
- }
- if (strcmp(sd->status.name,g->master) == 0) {
- // set the Guild Master flag
- sd->state.gmaster_flag = g;
- // prevent Guild Skills from being used directly after relog
- if (battle_config.guild_skill_relog_delay)
- guild_block_skill(sd, 300000);
- }
- i = guild_getindex(g, sd->status.account_id, sd->status.char_id);
- if (i == -1)
- sd->status.guild_id = 0;
- else
- g->member[i].sd = sd;
+ struct guild* g;
+ int i;
+ g=guild_search(sd->status.guild_id);
+ if (!g) {
+ guild_request_info(sd->status.guild_id);
+ return;
+ }
+ if (strcmp(sd->status.name,g->master) == 0)
+ { // set the Guild Master flag
+ sd->state.gmaster_flag = g;
+ // prevent Guild Skills from being used directly after relog
+ if( battle_config.guild_skill_relog_delay )
+ guild_block_skill(sd, 300000);
+ }
+ i = guild_getindex(g, sd->status.account_id, sd->status.char_id);
+ if (i == -1)
+ sd->status.guild_id = 0;
+ else
+ g->member[i].sd = sd;
}
/*==========================================
@@ -705,246 +724,245 @@ void guild_member_joined(struct map_session_data *sd)
*----------------------------------------*/
int guild_member_added(int guild_id,int account_id,int char_id,int flag)
{
- struct map_session_data *sd= map_id2sd(account_id),*sd2;
- struct guild *g;
+ struct map_session_data *sd= map_id2sd(account_id),*sd2;
+ struct guild *g;
- if ((g=guild_search(guild_id))==NULL)
- return 0;
+ if( (g=guild_search(guild_id))==NULL )
+ return 0;
- if (sd==NULL || sd->guild_invite==0) {
+ if(sd==NULL || sd->guild_invite==0){
// cancel if player not present or invalide guild_id invitation
- if (flag == 0) {
- ShowError("guild: member added error %d is not online\n",account_id);
- intif_guild_leave(guild_id,account_id,char_id,0,"** Data Error **");
- }
- return 0;
- }
- sd2 = map_id2sd(sd->guild_invite_account);
- sd->guild_invite = 0;
- sd->guild_invite_account = 0;
+ if (flag == 0) {
+ ShowError("guild: member added error %d is not online\n",account_id);
+ intif_guild_leave(guild_id,account_id,char_id,0,"** Data Error **");
+ }
+ return 0;
+ }
+ sd2 = map_id2sd(sd->guild_invite_account);
+ sd->guild_invite = 0;
+ sd->guild_invite_account = 0;
if (flag == 1) { //failure
- if (sd2!=NULL)
- clif_guild_inviteack(sd2,3);
- return 0;
- }
+ if( sd2!=NULL )
+ clif_guild_inviteack(sd2,3);
+ return 0;
+ }
//if all ok add player to guild
- sd->status.guild_id = g->guild_id;
- sd->guild_emblem_id = g->emblem_id;
- //Packets which were sent in the previous 'guild_sent' implementation.
- clif_guild_belonginfo(sd,g);
- clif_guild_notice(sd,g);
+ sd->status.guild_id = g->guild_id;
+ sd->guild_emblem_id = g->emblem_id;
+ //Packets which were sent in the previous 'guild_sent' implementation.
+ clif_guild_belonginfo(sd,g);
+ clif_guild_notice(sd,g);
- //TODO: send new emblem info to others
+ //TODO: send new emblem info to others
- if (sd2!=NULL)
- clif_guild_inviteack(sd2,2);
+ if( sd2!=NULL )
+ clif_guild_inviteack(sd2,2);
- //Next line commented because it do nothing, look at guild_recv_info [LuzZza]
- //clif_charnameupdate(sd); //Update display name [Skotlex]
+ //Next line commented because it do nothing, look at guild_recv_info [LuzZza]
+ //clif_charnameupdate(sd); //Update display name [Skotlex]
- return 0;
+ return 0;
}
/*==========================================
* Player request leaving a given guild_id
*----------------------------------------*/
-int guild_leave(struct map_session_data *sd, int guild_id, int account_id, int char_id, const char *mes)
+int guild_leave(struct map_session_data* sd, int guild_id, int account_id, int char_id, const char* mes)
{
- struct guild *g;
+ struct guild *g;
- nullpo_ret(sd);
+ nullpo_ret(sd);
- g = guild_search(sd->status.guild_id);
+ g = guild_search(sd->status.guild_id);
- if (g==NULL)
- return 0;
+ if(g==NULL)
+ return 0;
- if (sd->status.account_id!=account_id ||
- sd->status.char_id!=char_id || sd->status.guild_id!=guild_id ||
- ((agit_flag || agit2_flag) && map[sd->bl.m].flag.gvg_castle))
- return 0;
+ if(sd->status.account_id!=account_id ||
+ sd->status.char_id!=char_id || sd->status.guild_id!=guild_id ||
+ ((agit_flag || agit2_flag) && map[sd->bl.m].flag.gvg_castle))
+ return 0;
- intif_guild_leave(sd->status.guild_id, sd->status.account_id, sd->status.char_id,0,mes);
- return 0;
+ intif_guild_leave(sd->status.guild_id, sd->status.account_id, sd->status.char_id,0,mes);
+ return 0;
}
/*==========================================
* Request remove a player to a given guild_id
*----------------------------------------*/
-int guild_expulsion(struct map_session_data *sd, int guild_id, int account_id, int char_id, const char *mes)
+int guild_expulsion(struct map_session_data* sd, int guild_id, int account_id, int char_id, const char* mes)
{
- struct map_session_data *tsd;
- struct guild *g;
- int i,ps;
+ struct map_session_data *tsd;
+ struct guild *g;
+ int i,ps;
- nullpo_ret(sd);
+ nullpo_ret(sd);
- g = guild_search(sd->status.guild_id);
+ g = guild_search(sd->status.guild_id);
- if (g==NULL)
- return 0;
+ if(g==NULL)
+ return 0;
- if (sd->status.guild_id!=guild_id)
- return 0;
+ if(sd->status.guild_id!=guild_id)
+ return 0;
- if ((ps=guild_getposition(g,sd))<0 || !(g->position[ps].mode&0x0010))
- return 0; //Expulsion permission
+ if( (ps=guild_getposition(g,sd))<0 || !(g->position[ps].mode&0x0010) )
+ return 0; //Expulsion permission
- //Can't leave inside guild castles.
- if ((tsd = map_id2sd(account_id)) &&
- tsd->status.char_id == char_id &&
- ((agit_flag || agit2_flag) && map[tsd->bl.m].flag.gvg_castle))
- return 0;
+ //Can't leave inside guild castles.
+ if ((tsd = map_id2sd(account_id)) &&
+ tsd->status.char_id == char_id &&
+ ((agit_flag || agit2_flag) && map[tsd->bl.m].flag.gvg_castle))
+ return 0;
- // find the member and perform expulsion
- i = guild_getindex(g, account_id, char_id);
- if (i != -1 && strcmp(g->member[i].name,g->master) != 0) //Can't expel the GL!
- intif_guild_leave(g->guild_id,account_id,char_id,1,mes);
+ // find the member and perform expulsion
+ i = guild_getindex(g, account_id, char_id);
+ if( i != -1 && strcmp(g->member[i].name,g->master) != 0 ) //Can't expel the GL!
+ intif_guild_leave(g->guild_id,account_id,char_id,1,mes);
- return 0;
+ return 0;
}
-int guild_member_withdraw(int guild_id, int account_id, int char_id, int flag, const char *name, const char *mes)
+int guild_member_withdraw(int guild_id, int account_id, int char_id, int flag, const char* name, const char* mes)
{
- int i;
- struct guild *g = guild_search(guild_id);
- struct map_session_data *sd = map_charid2sd(char_id);
- struct map_session_data *online_member_sd;
-
- if (g == NULL)
- return 0; // no such guild (error!)
-
- i = guild_getindex(g, account_id, char_id);
- if (i == -1)
- return 0; // not a member (inconsistency!)
-
- online_member_sd = guild_getavailablesd(g);
- if (online_member_sd == NULL)
- return 0; // noone online to inform
-
- if (!flag)
- clif_guild_leave(online_member_sd, name, mes);
- else
- clif_guild_expulsion(online_member_sd, name, mes, account_id);
-
- // remove member from guild
- memset(&g->member[i],0,sizeof(struct guild_member));
- clif_guild_memberlist(online_member_sd);
-
- // update char, if online
- if (sd != NULL && sd->status.guild_id == guild_id) {
- // do stuff that needs the guild_id first, BEFORE we wipe it
- if (sd->state.storage_flag == 2) //Close the guild storage.
- storage_guild_storageclose(sd);
- guild_send_dot_remove(sd);
-
- sd->status.guild_id = 0;
- sd->guild_emblem_id = 0;
-
- clif_charnameupdate(sd); //Update display name [Skotlex]
- //TODO: send emblem update to self and people around
- }
- return 0;
-}
+ int i;
+ struct guild* g = guild_search(guild_id);
+ struct map_session_data* sd = map_charid2sd(char_id);
+ struct map_session_data* online_member_sd;
-int guild_send_memberinfoshort(struct map_session_data *sd,int online)
-{
- // cleaned up [LuzZza]
- struct guild *g;
+ if(g == NULL)
+ return 0; // no such guild (error!)
+
+ i = guild_getindex(g, account_id, char_id);
+ if( i == -1 )
+ return 0; // not a member (inconsistency!)
- nullpo_ret(sd);
+ online_member_sd = guild_getavailablesd(g);
+ if(online_member_sd == NULL)
+ return 0; // noone online to inform
- if (sd->status.guild_id <= 0)
- return 0;
+ if(!flag)
+ clif_guild_leave(online_member_sd, name, mes);
+ else
+ clif_guild_expulsion(online_member_sd, name, mes, account_id);
- if (!(g = guild_search(sd->status.guild_id)))
- return 0;
+ // remove member from guild
+ memset(&g->member[i],0,sizeof(struct guild_member));
+ clif_guild_memberlist(online_member_sd);
- intif_guild_memberinfoshort(g->guild_id,
- sd->status.account_id,sd->status.char_id,online,sd->status.base_level,sd->status.class_);
+ // update char, if online
+ if(sd != NULL && sd->status.guild_id == guild_id)
+ {
+ // do stuff that needs the guild_id first, BEFORE we wipe it
+ if (sd->state.storage_flag == 2) //Close the guild storage.
+ storage_guild_storageclose(sd);
+ guild_send_dot_remove(sd);
- if (!online) {
- int i=guild_getindex(g,sd->status.account_id,sd->status.char_id);
- if (i>=0)
- g->member[i].sd=NULL;
- else
- ShowError("guild_send_memberinfoshort: Failed to locate member %d:%d in guild %d!\n", sd->status.account_id, sd->status.char_id, g->guild_id);
- return 0;
- }
+ sd->status.guild_id = 0;
+ sd->guild_emblem_id = 0;
+
+ clif_charnameupdate(sd); //Update display name [Skotlex]
+ //TODO: send emblem update to self and people around
+ }
+ return 0;
+}
- if (sd->state.connect_new) {
- //Note that this works because it is invoked in parse_LoadEndAck before connect_new is cleared.
- clif_guild_belonginfo(sd,g);
- clif_guild_notice(sd,g);
- sd->guild_emblem_id = g->emblem_id;
- }
- return 0;
+int guild_send_memberinfoshort(struct map_session_data *sd,int online)
+{ // cleaned up [LuzZza]
+ struct guild *g;
+
+ nullpo_ret(sd);
+
+ if(sd->status.guild_id <= 0)
+ return 0;
+
+ if(!(g = guild_search(sd->status.guild_id)))
+ return 0;
+
+ intif_guild_memberinfoshort(g->guild_id,
+ sd->status.account_id,sd->status.char_id,online,sd->status.base_level,sd->status.class_);
+
+ if(!online){
+ int i=guild_getindex(g,sd->status.account_id,sd->status.char_id);
+ if(i>=0)
+ g->member[i].sd=NULL;
+ else
+ ShowError("guild_send_memberinfoshort: Failed to locate member %d:%d in guild %d!\n", sd->status.account_id, sd->status.char_id, g->guild_id);
+ return 0;
+ }
+
+ if(sd->state.connect_new)
+ { //Note that this works because it is invoked in parse_LoadEndAck before connect_new is cleared.
+ clif_guild_belonginfo(sd,g);
+ clif_guild_notice(sd,g);
+ sd->guild_emblem_id = g->emblem_id;
+ }
+ return 0;
}
int guild_recv_memberinfoshort(int guild_id,int account_id,int char_id,int online,int lv,int class_)
-{
- // cleaned up [LuzZza]
-
- int i,alv,c,idx=-1,om=0,oldonline=-1;
- struct guild *g = guild_search(guild_id);
-
- if (g == NULL)
- return 0;
-
- for (i=0,alv=0,c=0,om=0; i<g->max_member; i++) {
- struct guild_member *m=&g->member[i];
- if (!m->account_id) continue;
- if (m->account_id==account_id && m->char_id==char_id) {
- oldonline=m->online;
- m->online=online;
- m->lv=lv;
- m->class_=class_;
- idx=i;
- }
- alv+=m->lv;
- c++;
- if (m->online)
- om++;
- }
-
- if (idx == -1 || c == 0) {
+{ // cleaned up [LuzZza]
+
+ int i,alv,c,idx=-1,om=0,oldonline=-1;
+ struct guild *g = guild_search(guild_id);
+
+ if(g == NULL)
+ return 0;
+
+ for(i=0,alv=0,c=0,om=0;i<g->max_member;i++){
+ struct guild_member *m=&g->member[i];
+ if(!m->account_id) continue;
+ if(m->account_id==account_id && m->char_id==char_id ){
+ oldonline=m->online;
+ m->online=online;
+ m->lv=lv;
+ m->class_=class_;
+ idx=i;
+ }
+ alv+=m->lv;
+ c++;
+ if(m->online)
+ om++;
+ }
+
+ if(idx == -1 || c == 0) {
//Treat char_id who doesn't match guild_id (not found as member)
- struct map_session_data *sd = map_id2sd(account_id);
- if (sd && sd->status.char_id == char_id) {
- sd->status.guild_id=0;
- sd->guild_emblem_id=0;
- }
- ShowWarning("guild: not found member %d,%d on %d[%s]\n", account_id,char_id,guild_id,g->name);
- return 0;
- }
-
- g->average_lv=alv/c;
- g->connect_member=om;
-
- //Ensure validity of pointer (ie: player logs in/out, changes map-server)
- g->member[idx].sd = guild_sd_check(guild_id, account_id, char_id);
-
- if (oldonline!=online)
- clif_guild_memberlogin_notice(g, idx, online);
-
- if (!g->member[idx].sd)
- return 0;
-
- //Send XY dot updates. [Skotlex]
- //Moved from guild_send_memberinfoshort [LuzZza]
- for (i=0; i < g->max_member; i++) {
-
- if (!g->member[i].sd || i == idx ||
- g->member[i].sd->bl.m != g->member[idx].sd->bl.m)
- continue;
-
- clif_guild_xy_single(g->member[idx].sd->fd, g->member[i].sd);
- clif_guild_xy_single(g->member[i].sd->fd, g->member[idx].sd);
- }
-
- return 0;
+ struct map_session_data *sd = map_id2sd(account_id);
+ if(sd && sd->status.char_id == char_id) {
+ sd->status.guild_id=0;
+ sd->guild_emblem_id=0;
+ }
+ ShowWarning("guild: not found member %d,%d on %d[%s]\n", account_id,char_id,guild_id,g->name);
+ return 0;
+ }
+
+ g->average_lv=alv/c;
+ g->connect_member=om;
+
+ //Ensure validity of pointer (ie: player logs in/out, changes map-server)
+ g->member[idx].sd = guild_sd_check(guild_id, account_id, char_id);
+
+ if(oldonline!=online)
+ clif_guild_memberlogin_notice(g, idx, online);
+
+ if(!g->member[idx].sd)
+ return 0;
+
+ //Send XY dot updates. [Skotlex]
+ //Moved from guild_send_memberinfoshort [LuzZza]
+ for(i=0; i < g->max_member; i++) {
+
+ if(!g->member[i].sd || i == idx ||
+ g->member[i].sd->bl.m != g->member[idx].sd->bl.m)
+ continue;
+
+ clif_guild_xy_single(g->member[idx].sd->fd, g->member[i].sd);
+ clif_guild_xy_single(g->member[i].sd->fd, g->member[idx].sd);
+ }
+
+ return 0;
}
/*====================================================
@@ -952,17 +970,17 @@ int guild_recv_memberinfoshort(int guild_id,int account_id,int char_id,int onlin
*---------------------------------------------------*/
int guild_send_message(struct map_session_data *sd,const char *mes,int len)
{
- nullpo_ret(sd);
+ nullpo_ret(sd);
- 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);
+ 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);
- // Chat logging type 'G' / Guild Chat
- log_chat(LOG_CHAT_GUILD, sd->status.guild_id, sd->status.char_id, sd->status.account_id, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y, NULL, mes);
+ // Chat logging type 'G' / Guild Chat
+ log_chat(LOG_CHAT_GUILD, sd->status.guild_id, sd->status.char_id, sd->status.account_id, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y, NULL, mes);
- return 0;
+ return 0;
}
/*====================================================
@@ -970,11 +988,11 @@ int guild_send_message(struct map_session_data *sd,const char *mes,int len)
*---------------------------------------------------*/
int guild_recv_message(int guild_id,int account_id,const char *mes,int len)
{
- struct guild *g;
- if ((g=guild_search(guild_id))==NULL)
- return 0;
- clif_guild_message(g,account_id,mes,len);
- return 0;
+ struct guild *g;
+ if( (g=guild_search(guild_id))==NULL)
+ return 0;
+ clif_guild_message(g,account_id,mes,len);
+ return 0;
}
/*====================================================
@@ -982,7 +1000,7 @@ int guild_recv_message(int guild_id,int account_id,const char *mes,int len)
*---------------------------------------------------*/
int guild_change_memberposition(int guild_id,int account_id,int char_id,short idx)
{
- return intif_guild_change_memberinfo(guild_id,account_id,char_id,GMI_POSITION,&idx,sizeof(idx));
+ return intif_guild_change_memberinfo(guild_id,account_id,char_id,GMI_POSITION,&idx,sizeof(idx));
}
/*====================================================
@@ -990,32 +1008,32 @@ int guild_change_memberposition(int guild_id,int account_id,int char_id,short id
*---------------------------------------------------*/
int guild_memberposition_changed(struct guild *g,int idx,int pos)
{
- nullpo_ret(g);
-
- g->member[idx].position=pos;
- clif_guild_memberpositionchanged(g,idx);
+ nullpo_ret(g);
- // Update char position in client [LuzZza]
- if (g->member[idx].sd != NULL)
- clif_charnameupdate(g->member[idx].sd);
- return 0;
+ g->member[idx].position=pos;
+ clif_guild_memberpositionchanged(g,idx);
+
+ // Update char position in client [LuzZza]
+ if(g->member[idx].sd != NULL)
+ clif_charnameupdate(g->member[idx].sd);
+ return 0;
}
/*====================================================
* Change guild title or member
*---------------------------------------------------*/
int guild_change_position(int guild_id,int idx,
- int mode,int exp_mode,const char *name)
+ int mode,int exp_mode,const char *name)
{
- struct guild_position p;
+ struct guild_position p;
- exp_mode = cap_value(exp_mode, 0, battle_config.guild_exp_limit);
- //Mode 0x01 <- Invite
- //Mode 0x10 <- Expel.
- p.mode=mode&0x11;
- p.exp_mode=exp_mode;
- safestrncpy(p.name,name,NAME_LENGTH);
- return intif_guild_position(guild_id,idx,&p);
+ exp_mode = cap_value(exp_mode, 0, battle_config.guild_exp_limit);
+ //Mode 0x01 <- Invite
+ //Mode 0x10 <- Expel.
+ p.mode=mode&0x11;
+ p.exp_mode=exp_mode;
+ safestrncpy(p.name,name,NAME_LENGTH);
+ return intif_guild_position(guild_id,idx,&p);
}
/*====================================================
@@ -1023,18 +1041,18 @@ int guild_change_position(int guild_id,int idx,
*---------------------------------------------------*/
int guild_position_changed(int guild_id,int idx,struct guild_position *p)
{
- struct guild *g=guild_search(guild_id);
- int i;
- if (g==NULL)
- return 0;
- memcpy(&g->position[idx],p,sizeof(struct guild_position));
- clif_guild_positionchanged(g,idx);
-
- // Update char name in client [LuzZza]
- for (i=0; i<g->max_member; i++)
- if (g->member[i].position == idx && g->member[i].sd != NULL)
- clif_charnameupdate(g->member[i].sd);
- return 0;
+ struct guild *g=guild_search(guild_id);
+ int i;
+ if(g==NULL)
+ return 0;
+ memcpy(&g->position[idx],p,sizeof(struct guild_position));
+ clif_guild_positionchanged(g,idx);
+
+ // Update char name in client [LuzZza]
+ for(i=0;i<g->max_member;i++)
+ if(g->member[i].position == idx && g->member[i].sd != NULL)
+ clif_charnameupdate(g->member[i].sd);
+ return 0;
}
/*====================================================
@@ -1042,11 +1060,11 @@ int guild_position_changed(int guild_id,int idx,struct guild_position *p)
*---------------------------------------------------*/
int guild_change_notice(struct map_session_data *sd,int guild_id,const char *mes1,const char *mes2)
{
- nullpo_ret(sd);
+ nullpo_ret(sd);
- if (guild_id!=sd->status.guild_id)
- return 0;
- return intif_guild_notice(guild_id,mes1,mes2);
+ if(guild_id!=sd->status.guild_id)
+ return 0;
+ return intif_guild_notice(guild_id,mes1,mes2);
}
/*====================================================
@@ -1054,20 +1072,20 @@ int guild_change_notice(struct map_session_data *sd,int guild_id,const char *mes
*---------------------------------------------------*/
int guild_notice_changed(int guild_id,const char *mes1,const char *mes2)
{
- int i;
- struct map_session_data *sd;
- struct guild *g=guild_search(guild_id);
- if (g==NULL)
- return 0;
+ int i;
+ struct map_session_data *sd;
+ struct guild *g=guild_search(guild_id);
+ if(g==NULL)
+ return 0;
- memcpy(g->mes1,mes1,MAX_GUILDMES1);
- memcpy(g->mes2,mes2,MAX_GUILDMES2);
+ memcpy(g->mes1,mes1,MAX_GUILDMES1);
+ memcpy(g->mes2,mes2,MAX_GUILDMES2);
- for (i=0; i<g->max_member; i++) {
- if ((sd=g->member[i].sd)!=NULL)
- clif_guild_notice(sd,g);
- }
- return 0;
+ for(i=0;i<g->max_member;i++){
+ if((sd=g->member[i].sd)!=NULL)
+ clif_guild_notice(sd,g);
+ }
+ return 0;
}
/*====================================================
@@ -1075,16 +1093,16 @@ int guild_notice_changed(int guild_id,const char *mes1,const char *mes2)
*---------------------------------------------------*/
int guild_change_emblem(struct map_session_data *sd,int len,const char *data)
{
- struct guild *g;
- nullpo_ret(sd);
+ struct guild *g;
+ nullpo_ret(sd);
- 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,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
+ 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,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
- return intif_guild_emblem(sd->status.guild_id,len,data);
+ return intif_guild_emblem(sd->status.guild_id,len,data);
}
/*====================================================
@@ -1092,59 +1110,60 @@ int guild_change_emblem(struct map_session_data *sd,int len,const char *data)
*---------------------------------------------------*/
int guild_emblem_changed(int len,int guild_id,int emblem_id,const char *data)
{
- int i;
- struct map_session_data *sd;
- struct guild *g=guild_search(guild_id);
- if (g==NULL)
- return 0;
-
- memcpy(g->emblem_data,data,len);
- g->emblem_len=len;
- g->emblem_id=emblem_id;
-
- for (i=0; i<g->max_member; i++) {
- if ((sd=g->member[i].sd)!=NULL) {
- sd->guild_emblem_id=emblem_id;
- clif_guild_belonginfo(sd,g);
- clif_guild_emblem(sd,g);
- clif_guild_emblem_area(&sd->bl);
- }
- }
- {
- // update guardians (mobs)
- DBIterator *iter = db_iterator(castle_db);
- struct guild_castle *gc;
- for (gc = (struct guild_castle *)dbi_first(iter) ; dbi_exists(iter); gc = (struct guild_castle *)dbi_next(iter)) {
- if (gc->guild_id != guild_id)
- continue;
- // update permanent guardians
- for (i = 0; i < ARRAYLENGTH(gc->guardian); ++i) {
- TBL_MOB *md = (gc->guardian[i].id ? map_id2md(gc->guardian[i].id) : NULL);
- if (md == NULL || md->guardian_data == NULL)
- continue;
- md->guardian_data->emblem_id = emblem_id;
- clif_guild_emblem_area(&md->bl);
- }
- // update temporary guardians
- for (i = 0; i < gc->temp_guardians_max; ++i) {
- TBL_MOB *md = (gc->temp_guardians[i] ? map_id2md(gc->temp_guardians[i]) : NULL);
- if (md == NULL || md->guardian_data == NULL)
- continue;
- md->guardian_data->emblem_id = emblem_id;
- clif_guild_emblem_area(&md->bl);
- }
- }
- dbi_destroy(iter);
- }
- {
- // update npcs (flags or other npcs that used flagemblem to attach to this guild)
- for (i = 0; i < guild_flags_count; i++) {
- if (guild_flags[i] && guild_flags[i]->u.scr.guild_id == guild_id) {
- clif_guild_emblem_area(&guild_flags[i]->bl);
- }
- }
- }
- return 0;
+ int i;
+ struct map_session_data *sd;
+ struct guild *g=guild_search(guild_id);
+ if(g==NULL)
+ return 0;
+
+ memcpy(g->emblem_data,data,len);
+ g->emblem_len=len;
+ g->emblem_id=emblem_id;
+
+ for(i=0;i<g->max_member;i++){
+ if((sd=g->member[i].sd)!=NULL){
+ sd->guild_emblem_id=emblem_id;
+ clif_guild_belonginfo(sd,g);
+ clif_guild_emblem(sd,g);
+ clif_guild_emblem_area(&sd->bl);
+ }
+ }
+ {// update guardians (mobs)
+ DBIterator* iter = db_iterator(castle_db);
+ struct guild_castle* gc;
+ for( gc = (struct guild_castle*)dbi_first(iter) ; dbi_exists(iter); gc = (struct guild_castle*)dbi_next(iter) )
+ {
+ if( gc->guild_id != guild_id )
+ continue;
+ // update permanent guardians
+ for( i = 0; i < ARRAYLENGTH(gc->guardian); ++i )
+ {
+ TBL_MOB* md = (gc->guardian[i].id ? map_id2md(gc->guardian[i].id) : NULL);
+ if( md == NULL || md->guardian_data == NULL )
+ continue;
+ md->guardian_data->emblem_id = emblem_id;
+ clif_guild_emblem_area(&md->bl);
+ }
+ // update temporary guardians
+ for( i = 0; i < gc->temp_guardians_max; ++i )
+ {
+ TBL_MOB* md = (gc->temp_guardians[i] ? map_id2md(gc->temp_guardians[i]) : NULL);
+ if( md == NULL || md->guardian_data == NULL )
+ continue;
+ md->guardian_data->emblem_id = emblem_id;
+ clif_guild_emblem_area(&md->bl);
+ }
+ }
+ dbi_destroy(iter);
+ }
+ {// update npcs (flags or other npcs that used flagemblem to attach to this guild)
+ for( i = 0; i < guild_flags_count; i++ ) {
+ if( guild_flags[i] && guild_flags[i]->u.scr.guild_id == guild_id ) {
+ clif_guild_emblem_area(&guild_flags[i]->bl);
+ }
+ }
+ }
+ return 0;
}
/**
@@ -1152,15 +1171,15 @@ int guild_emblem_changed(int len,int guild_id,int emblem_id,const char *data)
*/
static DBData create_expcache(DBKey key, va_list args)
{
- struct guild_expcache *c;
- struct map_session_data *sd = va_arg(args, struct map_session_data *);
+ struct guild_expcache *c;
+ struct map_session_data *sd = va_arg(args, struct map_session_data*);
- c = ers_alloc(expcache_ers, 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 = 0;
- return db_ptr2data(c);
+ c = ers_alloc(expcache_ers, 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 = 0;
+ return db_ptr2data(c);
}
/*====================================================
@@ -1168,33 +1187,33 @@ static DBData create_expcache(DBKey key, va_list args)
*---------------------------------------------------*/
unsigned int guild_payexp(struct map_session_data *sd,unsigned int exp)
{
- struct guild *g;
- struct guild_expcache *c;
- int per;
-
- nullpo_ret(sd);
-
- if (!exp) return 0;
-
- if (sd->status.guild_id == 0 ||
- (g = guild_search(sd->status.guild_id)) == NULL ||
- (per = guild_getposition(g,sd)) < 0 ||
- (per = g->position[per].exp_mode) < 1)
- return 0;
-
-
- if (per < 100)
- exp = exp * per / 100;
- //Otherwise tax everything.
-
- c = db_data2ptr(guild_expcache_db->ensure(guild_expcache_db, db_i2key(sd->status.char_id), create_expcache, sd));
-
- if (c->exp > UINT64_MAX - exp)
- c->exp = UINT64_MAX;
- else
- c->exp += exp;
-
- return exp;
+ struct guild *g;
+ struct guild_expcache *c;
+ int per;
+
+ nullpo_ret(sd);
+
+ if (!exp) return 0;
+
+ if (sd->status.guild_id == 0 ||
+ (g = guild_search(sd->status.guild_id)) == NULL ||
+ (per = guild_getposition(g,sd)) < 0 ||
+ (per = g->position[per].exp_mode) < 1)
+ return 0;
+
+
+ if (per < 100)
+ exp = exp * per / 100;
+ //Otherwise tax everything.
+
+ c = db_data2ptr(guild_expcache_db->ensure(guild_expcache_db, db_i2key(sd->status.char_id), create_expcache, sd));
+
+ if (c->exp > UINT64_MAX - exp)
+ c->exp = UINT64_MAX;
+ else
+ c->exp += exp;
+
+ return exp;
}
/*====================================================
@@ -1204,42 +1223,42 @@ unsigned int guild_payexp(struct map_session_data *sd,unsigned int exp)
*---------------------------------------------------*/
int guild_getexp(struct map_session_data *sd,int exp)
{
- struct guild_expcache *c;
- nullpo_ret(sd);
+ struct guild_expcache *c;
+ nullpo_ret(sd);
- if (sd->status.guild_id == 0 || guild_search(sd->status.guild_id) == NULL)
- return 0;
+ if (sd->status.guild_id == 0 || guild_search(sd->status.guild_id) == NULL)
+ return 0;
- c = db_data2ptr(guild_expcache_db->ensure(guild_expcache_db, db_i2key(sd->status.char_id), create_expcache, sd));
- if (c->exp > UINT64_MAX - exp)
- c->exp = UINT64_MAX;
- else
- c->exp += exp;
- return exp;
+ c = db_data2ptr(guild_expcache_db->ensure(guild_expcache_db, db_i2key(sd->status.char_id), create_expcache, sd));
+ if (c->exp > UINT64_MAX - exp)
+ c->exp = UINT64_MAX;
+ else
+ c->exp += exp;
+ return exp;
}
/*====================================================
* Ask to increase guildskill skill_num
*---------------------------------------------------*/
-int guild_skillup(TBL_PC *sd, int skill_num)
+int guild_skillup(TBL_PC* sd, int skill_num)
{
- struct guild *g;
- int idx = skill_num - GD_SKILLBASE;
- int max = guild_skill_get_max(skill_num);
+ struct guild* g;
+ int idx = skill_num - GD_SKILLBASE;
+ int max = guild_skill_get_max(skill_num);
- nullpo_ret(sd);
+ nullpo_ret(sd);
- if (idx < 0 || idx >= MAX_GUILDSKILL || // not a guild skill
- sd->status.guild_id == 0 || (g=guild_search(sd->status.guild_id)) == NULL || // no guild
- strcmp(sd->status.name, g->master)) // not the guild master
- return 0;
+ if( idx < 0 || idx >= MAX_GUILDSKILL || // not a guild skill
+ sd->status.guild_id == 0 || (g=guild_search(sd->status.guild_id)) == NULL || // no guild
+ strcmp(sd->status.name, g->master) ) // not the guild master
+ return 0;
- if (g->skill_point > 0 &&
- g->skill[idx].id != 0 &&
- g->skill[idx].lv < max)
- intif_guild_skillup(g->guild_id, skill_num, sd->status.account_id, max);
+ if( g->skill_point > 0 &&
+ g->skill[idx].id != 0 &&
+ g->skill[idx].lv < max )
+ intif_guild_skillup(g->guild_id, skill_num, sd->status.account_id, max);
- return 0;
+ return 0;
}
/*====================================================
@@ -1247,100 +1266,99 @@ int guild_skillup(TBL_PC *sd, int skill_num)
*---------------------------------------------------*/
int guild_skillupack(int guild_id,int skill_num,int account_id)
{
- struct map_session_data *sd=map_id2sd(account_id);
- struct guild *g=guild_search(guild_id);
- int i;
- if (g==NULL)
- return 0;
- if (sd != NULL) {
- clif_guild_skillup(sd,skill_num,g->skill[skill_num-GD_SKILLBASE].lv);
-
- /* Guild Aura handling */
- switch (skill_num) {
- case GD_LEADERSHIP:
- case GD_GLORYWOUNDS:
- case GD_SOULCOLD:
- case GD_HAWKEYES:
- guild_guildaura_refresh(sd,skill_num,g->skill[skill_num-GD_SKILLBASE].lv);
- break;
- }
- }
-
- // Inform all members
- for (i=0; i<g->max_member; i++)
- if ((sd=g->member[i].sd)!=NULL)
- clif_guild_skillinfo(sd);
-
- return 0;
-}
-
-void guild_guildaura_refresh(struct map_session_data *sd, int skill_num, int skill_lv)
-{
- struct skill_unit_group *group = NULL;
- int type = status_skill2sc(skill_num);
- if (!(battle_config.guild_aura&((agit_flag || agit2_flag)?2:1)) &&
- !(battle_config.guild_aura&(map_flag_gvg2(sd->bl.m)?8:4)))
- return;
- if (skill_lv <= 0)
- return;
- if (sd->sc.data[type] && (group = skill_id2group(sd->sc.data[type]->val4))) {
- skill_delunitgroup(group);
- status_change_end(&sd->bl,type,INVALID_TIMER);
- }
- group = skill_unitsetting(&sd->bl,skill_num,skill_lv,sd->bl.x,sd->bl.y,0);
- if (group) {
- sc_start4(&sd->bl,type,100,(battle_config.guild_aura&16)?0:skill_lv,0,0,group->group_id,600000);//duration doesn't matter these status never end with val4
- }
- return;
+ struct map_session_data *sd=map_id2sd(account_id);
+ struct guild *g=guild_search(guild_id);
+ int i;
+ if(g==NULL)
+ return 0;
+ if( sd != NULL ) {
+ clif_guild_skillup(sd,skill_num,g->skill[skill_num-GD_SKILLBASE].lv);
+
+ /* Guild Aura handling */
+ switch( skill_num ) {
+ case GD_LEADERSHIP:
+ case GD_GLORYWOUNDS:
+ case GD_SOULCOLD:
+ case GD_HAWKEYES:
+ guild_guildaura_refresh(sd,skill_num,g->skill[skill_num-GD_SKILLBASE].lv);
+ break;
+ }
+ }
+
+ // Inform all members
+ for(i=0;i<g->max_member;i++)
+ if((sd=g->member[i].sd)!=NULL)
+ clif_guild_skillinfo(sd);
+
+ return 0;
+}
+
+void guild_guildaura_refresh(struct map_session_data *sd, int skill_num, int skill_lv) {
+ struct skill_unit_group* group = NULL;
+ int type = status_skill2sc(skill_num);
+ if( !(battle_config.guild_aura&((agit_flag || agit2_flag)?2:1)) &&
+ !(battle_config.guild_aura&(map_flag_gvg2(sd->bl.m)?8:4)) )
+ return;
+ if( skill_lv <= 0 )
+ return;
+ if( sd->sc.data[type] && (group = skill_id2group(sd->sc.data[type]->val4)) ) {
+ skill_delunitgroup(group);
+ status_change_end(&sd->bl,type,INVALID_TIMER);
+ }
+ group = skill_unitsetting(&sd->bl,skill_num,skill_lv,sd->bl.x,sd->bl.y,0);
+ if( group ) {
+ sc_start4(&sd->bl,type,100,(battle_config.guild_aura&16)?0:skill_lv,0,0,group->group_id,600000);//duration doesn't matter these status never end with val4
+ }
+ return;
}
/*====================================================
* Count number of relations the guild has.
* Flag:
- * 0 = allied
- * 1 = enemy
+ * 0 = allied
+ * 1 = enemy
*---------------------------------------------------*/
int guild_get_alliance_count(struct guild *g,int flag)
{
- int i,c;
+ int i,c;
- nullpo_ret(g);
+ nullpo_ret(g);
- for (i=c=0; i<MAX_GUILDALLIANCE; i++) {
- if (g->alliance[i].guild_id>0 &&
- g->alliance[i].opposition==flag)
- c++;
- }
- return c;
+ for(i=c=0;i<MAX_GUILDALLIANCE;i++){
+ if( g->alliance[i].guild_id>0 &&
+ g->alliance[i].opposition==flag )
+ c++;
+ }
+ return c;
}
// Blocks all guild skills which have a common delay time.
void guild_block_skill(struct map_session_data *sd, int time)
{
- int skill_num[] = { GD_BATTLEORDER, GD_REGENERATION, GD_RESTORE, GD_EMERGENCYCALL };
- int i;
- for (i = 0; i < 4; i++)
- skill_blockpc_start_(sd, skill_num[i], time , true);
+ int skill_num[] = { GD_BATTLEORDER, GD_REGENERATION, GD_RESTORE, GD_EMERGENCYCALL };
+ int i;
+ for (i = 0; i < 4; i++)
+ skill_blockpc_start_(sd, skill_num[i], time , true);
}
/*====================================================
* Check relation between guild_id1 and guild_id2.
* Flag:
- * 0 = allied
- * 1 = enemy
+ * 0 = allied
+ * 1 = enemy
* Returns true if yes.
*---------------------------------------------------*/
int guild_check_alliance(int guild_id1, int guild_id2, int flag)
{
- struct guild *g;
- int i;
+ struct guild *g;
+ int i;
- g = guild_search(guild_id1);
- if (g == NULL)
- return 0;
+ g = guild_search(guild_id1);
+ if (g == NULL)
+ return 0;
- ARR_FIND(0, MAX_GUILDALLIANCE, i, g->alliance[i].guild_id == guild_id2 && g->alliance[i].opposition == flag);
- return(i < MAX_GUILDALLIANCE) ? 1 : 0;
+ ARR_FIND( 0, MAX_GUILDALLIANCE, i, g->alliance[i].guild_id == guild_id2 && g->alliance[i].opposition == flag );
+ return( i < MAX_GUILDALLIANCE ) ? 1 : 0;
}
/*====================================================
@@ -1348,57 +1366,57 @@ int guild_check_alliance(int guild_id1, int guild_id2, int flag)
*---------------------------------------------------*/
int guild_reqalliance(struct map_session_data *sd,struct map_session_data *tsd)
{
- struct guild *g[2];
- int i;
+ struct guild *g[2];
+ int i;
- if (agit_flag || agit2_flag) { // Disable alliance creation during woe [Valaris]
- clif_displaymessage(sd->fd,msg_txt(676)); //"Alliances cannot be made during Guild Wars!"
- return 0;
- } // end addition [Valaris]
+ if(agit_flag || agit2_flag) { // Disable alliance creation during woe [Valaris]
+ clif_displaymessage(sd->fd,msg_txt(676)); //"Alliances cannot be made during Guild Wars!"
+ return 0;
+ } // end addition [Valaris]
- nullpo_ret(sd);
+ nullpo_ret(sd);
- if (tsd==NULL || tsd->status.guild_id<=0)
- return 0;
+ if(tsd==NULL || tsd->status.guild_id<=0)
+ return 0;
- g[0]=guild_search(sd->status.guild_id);
- g[1]=guild_search(tsd->status.guild_id);
+ g[0]=guild_search(sd->status.guild_id);
+ g[1]=guild_search(tsd->status.guild_id);
- if (g[0]==NULL || g[1]==NULL)
- return 0;
+ if(g[0]==NULL || g[1]==NULL)
+ return 0;
- // Prevent creation alliance with same guilds [LuzZza]
- if (sd->status.guild_id == tsd->status.guild_id)
- return 0;
+ // Prevent creation alliance with same guilds [LuzZza]
+ if(sd->status.guild_id == tsd->status.guild_id)
+ return 0;
- if (guild_get_alliance_count(g[0],0) >= battle_config.max_guild_alliance) {
- clif_guild_allianceack(sd,4);
- return 0;
- }
- if (guild_get_alliance_count(g[1],0) >= battle_config.max_guild_alliance) {
- clif_guild_allianceack(sd,3);
- return 0;
- }
+ if( guild_get_alliance_count(g[0],0) >= battle_config.max_guild_alliance ) {
+ clif_guild_allianceack(sd,4);
+ return 0;
+ }
+ if( guild_get_alliance_count(g[1],0) >= battle_config.max_guild_alliance ) {
+ clif_guild_allianceack(sd,3);
+ return 0;
+ }
- if (tsd->guild_alliance>0) {
- clif_guild_allianceack(sd,1);
- return 0;
- }
+ if( tsd->guild_alliance>0 ){
+ clif_guild_allianceack(sd,1);
+ return 0;
+ }
for (i = 0; i < MAX_GUILDALLIANCE; i++) { // check if already allied
- if (g[0]->alliance[i].guild_id==tsd->status.guild_id &&
- g[0]->alliance[i].opposition==0) {
- clif_guild_allianceack(sd,0);
- return 0;
- }
- }
+ if( g[0]->alliance[i].guild_id==tsd->status.guild_id &&
+ g[0]->alliance[i].opposition==0){
+ clif_guild_allianceack(sd,0);
+ return 0;
+ }
+ }
- tsd->guild_alliance=sd->status.guild_id;
- tsd->guild_alliance_account=sd->status.account_id;
+ tsd->guild_alliance=sd->status.guild_id;
+ tsd->guild_alliance_account=sd->status.account_id;
- clif_guild_reqalliance(tsd,sd->status.account_id,g[0]->name);
- return 0;
+ clif_guild_reqalliance(tsd,sd->status.account_id,g[0]->name);
+ return 0;
}
/*====================================================
@@ -1406,60 +1424,60 @@ int guild_reqalliance(struct map_session_data *sd,struct map_session_data *tsd)
*---------------------------------------------------*/
int guild_reply_reqalliance(struct map_session_data *sd,int account_id,int flag)
{
- struct map_session_data *tsd;
+ struct map_session_data *tsd;
- nullpo_ret(sd);
- tsd= map_id2sd(account_id);
- if (!tsd) { //Character left? Cancel alliance.
- clif_guild_allianceack(sd,3);
- return 0;
- }
+ nullpo_ret(sd);
+ tsd= map_id2sd( account_id );
+ if (!tsd) { //Character left? Cancel alliance.
+ clif_guild_allianceack(sd,3);
+ return 0;
+ }
if (sd->guild_alliance != tsd->status.guild_id) // proposed guild_id alliance doesn't match tsd guildid
- return 0;
+ return 0;
if (flag == 1) { // consent
- int i;
+ int i;
struct guild *g, *tg; // Reconfirm the number of alliance
- g=guild_search(sd->status.guild_id);
- tg=guild_search(tsd->status.guild_id);
-
- if (g==NULL || guild_get_alliance_count(g,0) >= battle_config.max_guild_alliance) {
- clif_guild_allianceack(sd,4);
- clif_guild_allianceack(tsd,3);
- return 0;
- }
- if (tg==NULL || guild_get_alliance_count(tg,0) >= battle_config.max_guild_alliance) {
- clif_guild_allianceack(sd,3);
- clif_guild_allianceack(tsd,4);
- return 0;
- }
-
- for (i=0; i<MAX_GUILDALLIANCE; i++) {
- if (g->alliance[i].guild_id==tsd->status.guild_id &&
- g->alliance[i].opposition==1)
- intif_guild_alliance(sd->status.guild_id,tsd->status.guild_id,
- sd->status.account_id,tsd->status.account_id,9);
- }
- for (i=0; i<MAX_GUILDALLIANCE; i++) {
- if (tg->alliance[i].guild_id==sd->status.guild_id &&
- tg->alliance[i].opposition==1)
- intif_guild_alliance(tsd->status.guild_id,sd->status.guild_id,
- tsd->status.account_id,sd->status.account_id,9);
- }
+ g=guild_search(sd->status.guild_id);
+ tg=guild_search(tsd->status.guild_id);
+
+ if(g==NULL || guild_get_alliance_count(g,0) >= battle_config.max_guild_alliance){
+ clif_guild_allianceack(sd,4);
+ clif_guild_allianceack(tsd,3);
+ return 0;
+ }
+ if(tg==NULL || guild_get_alliance_count(tg,0) >= battle_config.max_guild_alliance){
+ clif_guild_allianceack(sd,3);
+ clif_guild_allianceack(tsd,4);
+ return 0;
+ }
+
+ for(i=0;i<MAX_GUILDALLIANCE;i++){
+ if(g->alliance[i].guild_id==tsd->status.guild_id &&
+ g->alliance[i].opposition==1)
+ intif_guild_alliance( sd->status.guild_id,tsd->status.guild_id,
+ sd->status.account_id,tsd->status.account_id,9 );
+ }
+ for(i=0;i<MAX_GUILDALLIANCE;i++){
+ if(tg->alliance[i].guild_id==sd->status.guild_id &&
+ tg->alliance[i].opposition==1)
+ intif_guild_alliance( tsd->status.guild_id,sd->status.guild_id,
+ tsd->status.account_id,sd->status.account_id,9 );
+ }
// inform other servers
- intif_guild_alliance(sd->status.guild_id,tsd->status.guild_id,
- sd->status.account_id,tsd->status.account_id,0);
- return 0;
+ intif_guild_alliance( sd->status.guild_id,tsd->status.guild_id,
+ sd->status.account_id,tsd->status.account_id,0 );
+ return 0;
} else { // deny
- sd->guild_alliance=0;
- sd->guild_alliance_account=0;
- if (tsd!=NULL)
- clif_guild_allianceack(tsd,3);
- }
- return 0;
+ sd->guild_alliance=0;
+ sd->guild_alliance_account=0;
+ if(tsd!=NULL)
+ clif_guild_allianceack(tsd,3);
+ }
+ return 0;
}
/*====================================================
@@ -1467,15 +1485,15 @@ int guild_reply_reqalliance(struct map_session_data *sd,int account_id,int flag)
*---------------------------------------------------*/
int guild_delalliance(struct map_session_data *sd,int guild_id,int flag)
{
- nullpo_ret(sd);
+ nullpo_ret(sd);
- if (agit_flag || agit2_flag) { // Disable alliance breaking during woe [Valaris]
- clif_displaymessage(sd->fd,msg_txt(677)); //"Alliances cannot be broken during Guild Wars!"
- return 0;
- } // end addition [Valaris]
+ if(agit_flag || agit2_flag) { // Disable alliance breaking during woe [Valaris]
+ clif_displaymessage(sd->fd,msg_txt(677)); //"Alliances cannot be broken during Guild Wars!"
+ return 0;
+ } // end addition [Valaris]
- intif_guild_alliance(sd->status.guild_id,guild_id,sd->status.account_id,0,flag|8);
- return 0;
+ intif_guild_alliance( sd->status.guild_id,guild_id,sd->status.account_id,0,flag|8 );
+ return 0;
}
/*====================================================
@@ -1483,42 +1501,42 @@ int guild_delalliance(struct map_session_data *sd,int guild_id,int flag)
*---------------------------------------------------*/
int guild_opposition(struct map_session_data *sd,struct map_session_data *tsd)
{
- struct guild *g;
- int i;
+ struct guild *g;
+ int i;
- nullpo_ret(sd);
+ nullpo_ret(sd);
- g=guild_search(sd->status.guild_id);
- if (g==NULL || tsd==NULL)
- return 0;
+ g=guild_search(sd->status.guild_id);
+ if(g==NULL || tsd==NULL)
+ return 0;
- // Prevent creation opposition with same guilds [LuzZza]
- if (sd->status.guild_id == tsd->status.guild_id)
- return 0;
+ // Prevent creation opposition with same guilds [LuzZza]
+ if(sd->status.guild_id == tsd->status.guild_id)
+ return 0;
- if (guild_get_alliance_count(g,1) >= battle_config.max_guild_alliance) {
- clif_guild_oppositionack(sd,1);
- return 0;
- }
+ if( guild_get_alliance_count(g,1) >= battle_config.max_guild_alliance ) {
+ clif_guild_oppositionack(sd,1);
+ return 0;
+ }
for (i = 0; i < MAX_GUILDALLIANCE; i++) { // checking relations
- if (g->alliance[i].guild_id==tsd->status.guild_id) {
+ if(g->alliance[i].guild_id==tsd->status.guild_id){
if (g->alliance[i].opposition == 1) { // check if not already hostile
- clif_guild_oppositionack(sd,2);
- return 0;
- }
- if (agit_flag || agit2_flag) // Prevent the changing of alliances to oppositions during WoE.
- return 0;
- //Change alliance to opposition.
- intif_guild_alliance(sd->status.guild_id,tsd->status.guild_id,
- sd->status.account_id,tsd->status.account_id,8);
- }
- }
+ clif_guild_oppositionack(sd,2);
+ return 0;
+ }
+ if(agit_flag || agit2_flag) // Prevent the changing of alliances to oppositions during WoE.
+ return 0;
+ //Change alliance to opposition.
+ intif_guild_alliance( sd->status.guild_id,tsd->status.guild_id,
+ sd->status.account_id,tsd->status.account_id,8 );
+ }
+ }
// inform other serv
- intif_guild_alliance(sd->status.guild_id,tsd->status.guild_id,
- sd->status.account_id,tsd->status.account_id,1);
- return 0;
+ intif_guild_alliance( sd->status.guild_id,tsd->status.guild_id,
+ sd->status.account_id,tsd->status.account_id,1 );
+ return 0;
}
/*====================================================
@@ -1526,74 +1544,79 @@ int guild_opposition(struct map_session_data *sd,struct map_session_data *tsd)
*---------------------------------------------------*/
int guild_allianceack(int guild_id1,int guild_id2,int account_id1,int account_id2,int flag,const char *name1,const char *name2)
{
- struct guild *g[2];
- 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);
-
- if (sd[0]!=NULL && (flag&0x0f)==0) {
- sd[0]->guild_alliance=0;
- sd[0]->guild_alliance_account=0;
- }
+ struct guild *g[2];
+ 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);
+
+ if(sd[0]!=NULL && (flag&0x0f)==0){
+ sd[0]->guild_alliance=0;
+ sd[0]->guild_alliance_account=0;
+ }
if (flag & 0x70) { // failure
- for (i=0; i<2-(flag&1); i++)
- if (sd[i]!=NULL)
- clif_guild_allianceack(sd[i],((flag>>4)==i+1)?3:4);
- return 0;
- }
+ for(i=0;i<2-(flag&1);i++)
+ if( sd[i]!=NULL )
+ clif_guild_allianceack(sd[i],((flag>>4)==i+1)?3:4);
+ return 0;
+ }
if (!(flag & 0x08)) { // new relationship
- for (i=0; i<2-(flag&1); i++) {
- if (g[i]!=NULL) {
- ARR_FIND(0, MAX_GUILDALLIANCE, j, g[i]->alliance[j].guild_id == 0);
- if (j < MAX_GUILDALLIANCE) {
- g[i]->alliance[j].guild_id=guild_id[1-i];
- memcpy(g[i]->alliance[j].name,guild_name[1-i],NAME_LENGTH);
- g[i]->alliance[j].opposition=flag&1;
- }
- }
- }
+ for(i=0;i<2-(flag&1);i++)
+ {
+ if(g[i]!=NULL)
+ {
+ ARR_FIND( 0, MAX_GUILDALLIANCE, j, g[i]->alliance[j].guild_id == 0 );
+ if( j < MAX_GUILDALLIANCE )
+ {
+ g[i]->alliance[j].guild_id=guild_id[1-i];
+ memcpy(g[i]->alliance[j].name,guild_name[1-i],NAME_LENGTH);
+ g[i]->alliance[j].opposition=flag&1;
+ }
+ }
+ }
} else { // remove relationship
- for (i=0; i<2-(flag&1); i++) {
- if (g[i]!=NULL) {
- ARR_FIND(0, MAX_GUILDALLIANCE, j, g[i]->alliance[j].guild_id == guild_id[1-i] && g[i]->alliance[j].opposition == (flag&1));
- if (j < MAX_GUILDALLIANCE)
- g[i]->alliance[j].guild_id = 0;
- }
+ for(i=0;i<2-(flag&1);i++)
+ {
+ if(g[i]!=NULL)
+ {
+ ARR_FIND( 0, MAX_GUILDALLIANCE, j, g[i]->alliance[j].guild_id == guild_id[1-i] && g[i]->alliance[j].opposition == (flag&1) );
+ if( j < MAX_GUILDALLIANCE )
+ g[i]->alliance[j].guild_id = 0;
+ }
if (sd[i] != NULL) // notify players
- clif_guild_delalliance(sd[i],guild_id[1-i],(flag&1));
- }
- }
+ clif_guild_delalliance(sd[i],guild_id[1-i],(flag&1));
+ }
+ }
if ((flag & 0x0f) == 0) { // alliance notification
- if (sd[1]!=NULL)
- clif_guild_allianceack(sd[1],2);
+ if( sd[1]!=NULL )
+ clif_guild_allianceack(sd[1],2);
} else if ((flag & 0x0f) == 1) { // enemy notification
- if (sd[0]!=NULL)
- clif_guild_oppositionack(sd[0],0);
- }
+ if( sd[0]!=NULL )
+ clif_guild_oppositionack(sd[0],0);
+ }
for (i = 0; i < 2 - (flag & 1); i++) { // Retransmission of the relationship list to all members
- struct map_session_data *sd;
- if (g[i]!=NULL)
- for (j=0; j<g[i]->max_member; j++)
- if ((sd=g[i]->member[j].sd)!=NULL)
- clif_guild_allianceinfo(sd);
- }
- return 0;
+ struct map_session_data *sd;
+ if(g[i]!=NULL)
+ for(j=0;j<g[i]->max_member;j++)
+ if((sd=g[i]->member[j].sd)!=NULL)
+ clif_guild_allianceinfo(sd);
+ }
+ return 0;
}
/**
@@ -1602,23 +1625,23 @@ int guild_allianceack(int guild_id1,int guild_id2,int account_id1,int account_id
*/
int guild_broken_sub(DBKey key, DBData *data, va_list ap)
{
- struct guild *g = db_data2ptr(data);
- int guild_id=va_arg(ap,int);
- int i,j;
- struct map_session_data *sd=NULL;
+ struct guild *g = db_data2ptr(data);
+ int guild_id=va_arg(ap,int);
+ int i,j;
+ struct map_session_data *sd=NULL;
- nullpo_ret(g);
+ nullpo_ret(g);
- for (i=0; i<MAX_GUILDALLIANCE; i++) { // Destroy all relationships
- if (g->alliance[i].guild_id==guild_id) {
- for (j=0; j<g->max_member; j++)
- if ((sd=g->member[j].sd)!=NULL)
- clif_guild_delalliance(sd,guild_id,g->alliance[i].opposition);
- intif_guild_alliance(g->guild_id, guild_id,0,0,g->alliance[i].opposition|8);
- g->alliance[i].guild_id=0;
- }
- }
- return 0;
+ for(i=0;i<MAX_GUILDALLIANCE;i++){ // Destroy all relationships
+ if(g->alliance[i].guild_id==guild_id){
+ for(j=0;j<g->max_member;j++)
+ if( (sd=g->member[j].sd)!=NULL )
+ clif_guild_delalliance(sd,guild_id,g->alliance[i].opposition);
+ intif_guild_alliance(g->guild_id, guild_id,0,0,g->alliance[i].opposition|8);
+ g->alliance[i].guild_id=0;
+ }
+ }
+ return 0;
}
/**
@@ -1627,120 +1650,124 @@ int guild_broken_sub(DBKey key, DBData *data, va_list ap)
*/
int castle_guild_broken_sub(DBKey key, DBData *data, va_list ap)
{
- char name[EVENT_NAME_LENGTH];
- struct guild_castle *gc = db_data2ptr(data);
- int guild_id = va_arg(ap, int);
+ char name[EVENT_NAME_LENGTH];
+ struct guild_castle *gc = db_data2ptr(data);
+ int guild_id = va_arg(ap, int);
- nullpo_ret(gc);
+ nullpo_ret(gc);
- if (gc->guild_id == guild_id) {
- // We call castle_event::OnGuildBreak of all castles of the guild
- // You can set all castle_events in the 'db/castle_db.txt'
- safestrncpy(name, gc->castle_event, sizeof(name));
- npc_event_do(strcat(name, "::OnGuildBreak"));
+ if (gc->guild_id == guild_id) {
+ // We call castle_event::OnGuildBreak of all castles of the guild
+ // You can set all castle_events in the 'db/castle_db.txt'
+ safestrncpy(name, gc->castle_event, sizeof(name));
+ npc_event_do(strcat(name, "::OnGuildBreak"));
- //Save the new 'owner', this should invoke guardian clean up and other such things.
- guild_castledatasave(gc->castle_id, 1, 0);
- }
- return 0;
+ //Save the new 'owner', this should invoke guardian clean up and other such things.
+ guild_castledatasave(gc->castle_id, 1, 0);
+ }
+ return 0;
}
//Invoked on /breakguild "Guild name"
int guild_broken(int guild_id,int flag)
{
- struct guild *g = guild_search(guild_id);
- struct map_session_data *sd = NULL;
- int i;
+ struct guild *g = guild_search(guild_id);
+ struct map_session_data *sd = NULL;
+ int i;
- if (flag!=0 || g==NULL)
- return 0;
+ if(flag!=0 || g==NULL)
+ return 0;
- for (i=0; i<g->max_member; i++) { // Destroy all relationships
- if ((sd=g->member[i].sd)!=NULL) {
- if (sd->state.storage_flag == 2)
- storage_guild_storage_quit(sd,1);
- sd->status.guild_id=0;
- clif_guild_broken(g->member[i].sd,0);
- clif_charnameupdate(sd); // [LuzZza]
- }
- }
+ for(i=0;i<g->max_member;i++){ // Destroy all relationships
+ if((sd=g->member[i].sd)!=NULL){
+ if(sd->state.storage_flag == 2)
+ storage_guild_storage_quit(sd,1);
+ sd->status.guild_id=0;
+ clif_guild_broken(g->member[i].sd,0);
+ clif_charnameupdate(sd); // [LuzZza]
+ }
+ }
- guild_db->foreach(guild_db,guild_broken_sub,guild_id);
- castle_db->foreach(castle_db,castle_guild_broken_sub,guild_id);
- guild_storage_delete(guild_id);
- idb_remove(guild_db,guild_id);
- return 0;
+ guild_db->foreach(guild_db,guild_broken_sub,guild_id);
+ castle_db->foreach(castle_db,castle_guild_broken_sub,guild_id);
+ guild_storage_delete(guild_id);
+ idb_remove(guild_db,guild_id);
+ return 0;
}
//Changes the Guild Master to the specified player. [Skotlex]
int guild_gm_change(int guild_id, struct map_session_data *sd)
{
- struct guild *g;
- nullpo_ret(sd);
+ struct guild *g;
+ nullpo_ret(sd);
- if (sd->status.guild_id != guild_id)
- return 0;
+ if (sd->status.guild_id != guild_id)
+ return 0;
+
+ g=guild_search(guild_id);
- g=guild_search(guild_id);
+ nullpo_ret(g);
- nullpo_ret(g);
-
- if (strcmp(g->master, sd->status.name) == 0) //Nothing to change.
- return 0;
+ if (strcmp(g->master, sd->status.name) == 0) //Nothing to change.
+ return 0;
- //Notify servers that master has changed.
- intif_guild_change_gm(guild_id, sd->status.name, strlen(sd->status.name)+1);
- return 1;
+ //Notify servers that master has changed.
+ intif_guild_change_gm(guild_id, sd->status.name, strlen(sd->status.name)+1);
+ return 1;
}
//Notification from Char server that a guild's master has changed. [Skotlex]
int guild_gm_changed(int guild_id, int account_id, int char_id)
{
- struct guild *g;
- struct guild_member gm;
- int pos, i;
-
- g=guild_search(guild_id);
-
- if (!g)
- return 0;
-
- for (pos=0; pos<g->max_member && !(
- g->member[pos].account_id==account_id &&
- g->member[pos].char_id==char_id);
- pos++);
-
- if (pos == 0 || pos == g->max_member) return 0;
-
- memcpy(&gm, &g->member[pos], sizeof(struct guild_member));
- memcpy(&g->member[pos], &g->member[0], sizeof(struct guild_member));
- memcpy(&g->member[0], &gm, sizeof(struct guild_member));
-
- g->member[pos].position = g->member[0].position;
- g->member[0].position = 0; //Position 0: guild Master.
- strcpy(g->master, g->member[0].name);
-
- if (g->member[pos].sd && g->member[pos].sd->fd) {
- clif_displaymessage(g->member[pos].sd->fd, msg_txt(678)); //"You no longer are the Guild Master."
- g->member[pos].sd->state.gmaster_flag = 0;
- }
-
- if (g->member[0].sd && g->member[0].sd->fd) {
- clif_displaymessage(g->member[0].sd->fd, msg_txt(679)); //"You have become the Guild Master!"
- g->member[0].sd->state.gmaster_flag = g;
- //Block his skills for 5 minutes to prevent abuse.
- guild_block_skill(g->member[0].sd, 300000);
- }
-
- // announce the change to all guild members
- for (i = 0; i < g->max_member; i++) {
- if (g->member[i].sd && g->member[i].sd->fd) {
- clif_guild_basicinfo(g->member[i].sd);
- clif_guild_memberlist(g->member[i].sd);
- }
- }
-
- return 1;
+ struct guild *g;
+ struct guild_member gm;
+ int pos, i;
+
+ g=guild_search(guild_id);
+
+ if (!g)
+ return 0;
+
+ for(pos=0; pos<g->max_member && !(
+ g->member[pos].account_id==account_id &&
+ g->member[pos].char_id==char_id);
+ pos++);
+
+ if (pos == 0 || pos == g->max_member) return 0;
+
+ memcpy(&gm, &g->member[pos], sizeof (struct guild_member));
+ memcpy(&g->member[pos], &g->member[0], sizeof(struct guild_member));
+ memcpy(&g->member[0], &gm, sizeof(struct guild_member));
+
+ g->member[pos].position = g->member[0].position;
+ g->member[0].position = 0; //Position 0: guild Master.
+ strcpy(g->master, g->member[0].name);
+
+ if (g->member[pos].sd && g->member[pos].sd->fd)
+ {
+ clif_displaymessage(g->member[pos].sd->fd, msg_txt(678)); //"You no longer are the Guild Master."
+ g->member[pos].sd->state.gmaster_flag = 0;
+ }
+
+ if (g->member[0].sd && g->member[0].sd->fd)
+ {
+ clif_displaymessage(g->member[0].sd->fd, msg_txt(679)); //"You have become the Guild Master!"
+ g->member[0].sd->state.gmaster_flag = g;
+ //Block his skills for 5 minutes to prevent abuse.
+ guild_block_skill(g->member[0].sd, 300000);
+ }
+
+ // announce the change to all guild members
+ for( i = 0; i < g->max_member; i++ )
+ {
+ if( g->member[i].sd && g->member[i].sd->fd )
+ {
+ clif_guild_basicinfo(g->member[i].sd);
+ clif_guild_memberlist(g->member[i].sd);
+ }
+ }
+
+ return 1;
}
/*====================================================
@@ -1748,30 +1775,30 @@ int guild_gm_changed(int guild_id, int account_id, int char_id)
*---------------------------------------------------*/
int guild_break(struct map_session_data *sd,char *name)
{
- struct guild *g;
- int i;
+ struct guild *g;
+ int i;
- nullpo_ret(sd);
+ nullpo_ret(sd);
- if ((g=guild_search(sd->status.guild_id))==NULL)
- return 0;
- if (strcmp(g->name,name)!=0)
- return 0;
- if (!sd->state.gmaster_flag)
- return 0;
- for (i=0; i<g->max_member; i++) {
- if (g->member[i].account_id>0 && (
- g->member[i].account_id!=sd->status.account_id ||
- g->member[i].char_id!=sd->status.char_id))
- break;
- }
- if (i<g->max_member) {
- clif_guild_broken(sd,2);
- return 0;
- }
+ if( (g=guild_search(sd->status.guild_id))==NULL )
+ return 0;
+ if(strcmp(g->name,name)!=0)
+ return 0;
+ if(!sd->state.gmaster_flag)
+ return 0;
+ for(i=0;i<g->max_member;i++){
+ if( g->member[i].account_id>0 && (
+ g->member[i].account_id!=sd->status.account_id ||
+ g->member[i].char_id!=sd->status.char_id ))
+ break;
+ }
+ if(i<g->max_member){
+ clif_guild_broken(sd,2);
+ return 0;
+ }
- intif_guild_break(g->guild_id);
- return 0;
+ intif_guild_break(g->guild_id);
+ return 0;
}
/**
@@ -1780,24 +1807,24 @@ int guild_break(struct map_session_data *sd,char *name)
*/
void guild_castle_map_init(void)
{
- DBIterator *iter = NULL;
- int num = db_size(castle_db);
+ DBIterator* iter = NULL;
+ int num = db_size(castle_db);
- if (num > 0) {
- struct guild_castle *gc = NULL;
- int *castle_ids, *cursor;
+ if (num > 0) {
+ struct guild_castle* gc = NULL;
+ int *castle_ids, *cursor;
- CREATE(castle_ids, int, num);
- cursor = castle_ids;
- iter = db_iterator(castle_db);
- for (gc = dbi_first(iter); dbi_exists(iter); gc = dbi_next(iter)) {
- *(cursor++) = gc->castle_id;
- }
- dbi_destroy(iter);
- if (intif_guild_castle_dataload(num, castle_ids))
- ShowStatus("Requested '"CL_WHITE"%d"CL_RESET"' guild castles from char-server...\n", num);
- aFree(castle_ids);
- }
+ CREATE(castle_ids, int, num);
+ cursor = castle_ids;
+ iter = db_iterator(castle_db);
+ for (gc = dbi_first(iter); dbi_exists(iter); gc = dbi_next(iter)) {
+ *(cursor++) = gc->castle_id;
+ }
+ dbi_destroy(iter);
+ if (intif_guild_castle_dataload(num, castle_ids))
+ ShowStatus("Requested '"CL_WHITE"%d"CL_RESET"' guild castles from char-server...\n", num);
+ aFree(castle_ids);
+ }
}
/**
@@ -1810,325 +1837,311 @@ void guild_castle_map_init(void)
*/
int guild_castledatasave(int castle_id, int index, int value)
{
- struct guild_castle *gc = guild_castle_search(castle_id);
-
- if (gc == NULL) {
- ShowWarning("guild_castledatasave: guild castle '%d' not found\n", castle_id);
- return 0;
- }
-
- switch (index) {
- case 1: { // The castle's owner has changed? Update or remove Guardians too. [Skotlex]
- int i;
- struct mob_data *gd;
- gc->guild_id = value;
- for (i = 0; i < MAX_GUARDIANS; i++)
- if (gc->guardian[i].visible && (gd = map_id2md(gc->guardian[i].id)) != NULL)
- mob_guardian_guildchange(gd);
- break;
- }
- case 2:
- gc->economy = value;
- break;
- case 3: { // defense invest change -> recalculate guardian hp
- int i;
- struct mob_data *gd;
- gc->defense = value;
- for (i = 0; i < MAX_GUARDIANS; i++)
- if (gc->guardian[i].visible && (gd = map_id2md(gc->guardian[i].id)) != NULL)
- status_calc_mob(gd, 0);
- break;
- }
- case 4:
- gc->triggerE = value;
- break;
- case 5:
- gc->triggerD = value;
- break;
- case 6:
- gc->nextTime = value;
- break;
- case 7:
- gc->payTime = value;
- break;
- case 8:
- gc->createTime = value;
- break;
- case 9:
- gc->visibleC = value;
- break;
- default:
- if (index > 9 && index <= 9+MAX_GUARDIANS) {
- gc->guardian[index-10].visible = value;
- break;
- }
- ShowWarning("guild_castledatasave: index = '%d' is out of allowed range\n", index);
- return 0;
- }
-
- if (!intif_guild_castle_datasave(castle_id, index, value)) {
- guild_castle_reconnect(castle_id, index, value);
- }
- return 0;
+ struct guild_castle *gc = guild_castle_search(castle_id);
+
+ if (gc == NULL) {
+ ShowWarning("guild_castledatasave: guild castle '%d' not found\n", castle_id);
+ return 0;
+ }
+
+ switch (index) {
+ case 1: // The castle's owner has changed? Update or remove Guardians too. [Skotlex]
+ {
+ int i;
+ struct mob_data *gd;
+ gc->guild_id = value;
+ for (i = 0; i < MAX_GUARDIANS; i++)
+ if (gc->guardian[i].visible && (gd = map_id2md(gc->guardian[i].id)) != NULL)
+ mob_guardian_guildchange(gd);
+ break;
+ }
+ case 2:
+ gc->economy = value; break;
+ case 3: // defense invest change -> recalculate guardian hp
+ {
+ int i;
+ struct mob_data *gd;
+ gc->defense = value;
+ for (i = 0; i < MAX_GUARDIANS; i++)
+ if (gc->guardian[i].visible && (gd = map_id2md(gc->guardian[i].id)) != NULL)
+ status_calc_mob(gd, 0);
+ break;
+ }
+ case 4:
+ gc->triggerE = value; break;
+ case 5:
+ gc->triggerD = value; break;
+ case 6:
+ gc->nextTime = value; break;
+ case 7:
+ gc->payTime = value; break;
+ case 8:
+ gc->createTime = value; break;
+ case 9:
+ gc->visibleC = value; break;
+ default:
+ if (index > 9 && index <= 9+MAX_GUARDIANS) {
+ gc->guardian[index-10].visible = value;
+ break;
+ }
+ ShowWarning("guild_castledatasave: index = '%d' is out of allowed range\n", index);
+ return 0;
+ }
+
+ if (!intif_guild_castle_datasave(castle_id, index, value)) {
+ guild_castle_reconnect(castle_id, index, value);
+ }
+ return 0;
}
void guild_castle_reconnect_sub(void *key, void *data, va_list ap)
{
- int castle_id = GetWord((int)__64BPRTSIZE(key), 0);
- int index = GetWord((int)__64BPRTSIZE(key), 1);
- intif_guild_castle_datasave(castle_id, index, *(int *)data);
- aFree(data);
+ int castle_id = GetWord((int)__64BPRTSIZE(key), 0);
+ int index = GetWord((int)__64BPRTSIZE(key), 1);
+ intif_guild_castle_datasave(castle_id, index, *(int *)data);
+ aFree(data);
}
/**
- * Saves pending guild castle data changes when char-server is
+ * Saves pending guild castle data changes when char-server is
* disconnected.
* On reconnect pushes all changes to char-server for saving.
*/
void guild_castle_reconnect(int castle_id, int index, int value)
{
- static struct linkdb_node *gc_save_pending = NULL;
+ static struct linkdb_node *gc_save_pending = NULL;
- if (castle_id < 0) { // char-server reconnected
- linkdb_foreach(&gc_save_pending, guild_castle_reconnect_sub);
- linkdb_final(&gc_save_pending);
- } else {
- int *data;
- CREATE(data, int, 1);
- *data = value;
- linkdb_replace(&gc_save_pending, (void *)__64BPRTSIZE((MakeDWord(castle_id, index))), data);
- }
+ if (castle_id < 0) { // char-server reconnected
+ linkdb_foreach(&gc_save_pending, guild_castle_reconnect_sub);
+ linkdb_final(&gc_save_pending);
+ } else {
+ int *data;
+ CREATE(data, int, 1);
+ *data = value;
+ linkdb_replace(&gc_save_pending, (void*)__64BPRTSIZE((MakeDWord(castle_id, index))), data);
+ }
}
// Load castle data then invoke OnAgitInit* on last
int guild_castledataloadack(int len, struct guild_castle *gc)
{
- int i;
- int n = (len-4) / sizeof(struct guild_castle);
- int ev;
-
- nullpo_ret(gc);
-
- //Last owned castle in the list invokes ::OnAgitInit
- for (i = n-1; i >= 0 && !(gc[i].guild_id); --i);
- ev = i; // offset of castle or -1
-
- if (ev < 0) { //No castles owned, invoke OnAgitInit as it is.
- npc_event_doall("OnAgitInit");
- npc_event_doall("OnAgitInit2");
- } else // load received castles into memory, one by one
- for (i = 0; i < n; i++, gc++) {
- struct guild_castle *c = guild_castle_search(gc->castle_id);
- if (!c) {
- ShowError("guild_castledataloadack: castle id=%d not found.\n", gc->castle_id);
- continue;
- }
-
- // update map-server castle data with new info
- memcpy(&c->guild_id, &gc->guild_id, sizeof(struct guild_castle) - offsetof(struct guild_castle, guild_id));
-
- if (c->guild_id) {
- if (i != ev)
- guild_request_info(c->guild_id);
- else { // last owned one
- guild_npc_request_info(c->guild_id, "::OnAgitInit");
- guild_npc_request_info(c->guild_id, "::OnAgitInit2");
- }
- }
- }
- ShowStatus("Received '"CL_WHITE"%d"CL_RESET"' guild castles from char-server.\n", n);
- return 0;
+ int i;
+ int n = (len-4) / sizeof(struct guild_castle);
+ int ev;
+
+ nullpo_ret(gc);
+
+ //Last owned castle in the list invokes ::OnAgitInit
+ for( i = n-1; i >= 0 && !(gc[i].guild_id); --i );
+ ev = i; // offset of castle or -1
+
+ if( ev < 0 ) { //No castles owned, invoke OnAgitInit as it is.
+ npc_event_doall("OnAgitInit");
+ npc_event_doall("OnAgitInit2");
+ }
+ else // load received castles into memory, one by one
+ for( i = 0; i < n; i++, gc++ )
+ {
+ struct guild_castle *c = guild_castle_search(gc->castle_id);
+ if (!c) {
+ ShowError("guild_castledataloadack: castle id=%d not found.\n", gc->castle_id);
+ continue;
+ }
+
+ // update map-server castle data with new info
+ memcpy(&c->guild_id, &gc->guild_id, sizeof(struct guild_castle) - offsetof(struct guild_castle, guild_id));
+
+ if( c->guild_id )
+ {
+ if( i != ev )
+ guild_request_info(c->guild_id);
+ else { // last owned one
+ guild_npc_request_info(c->guild_id, "::OnAgitInit");
+ guild_npc_request_info(c->guild_id, "::OnAgitInit2");
+ }
+ }
+ }
+ ShowStatus("Received '"CL_WHITE"%d"CL_RESET"' guild castles from char-server.\n", n);
+ return 0;
}
/*====================================================
* Start normal woe and triggers all npc OnAgitStart
*---------------------------------------------------*/
void guild_agit_start(void)
-{
- // Run All NPC_Event[OnAgitStart]
- int c = npc_event_doall("OnAgitStart");
- ShowStatus("NPC_Event:[OnAgitStart] Run (%d) Events by @AgitStart.\n",c);
+{ // Run All NPC_Event[OnAgitStart]
+ int c = npc_event_doall("OnAgitStart");
+ ShowStatus("NPC_Event:[OnAgitStart] Run (%d) Events by @AgitStart.\n",c);
}
/*====================================================
* End normal woe and triggers all npc OnAgitEnd
*---------------------------------------------------*/
void guild_agit_end(void)
-{
- // Run All NPC_Event[OnAgitEnd]
- int c = npc_event_doall("OnAgitEnd");
- ShowStatus("NPC_Event:[OnAgitEnd] Run (%d) Events by @AgitEnd.\n",c);
+{ // Run All NPC_Event[OnAgitEnd]
+ int c = npc_event_doall("OnAgitEnd");
+ ShowStatus("NPC_Event:[OnAgitEnd] Run (%d) Events by @AgitEnd.\n",c);
}
/*====================================================
* Start woe2 and triggers all npc OnAgitStart2
*---------------------------------------------------*/
void guild_agit2_start(void)
-{
- // Run All NPC_Event[OnAgitStart2]
- int c = npc_event_doall("OnAgitStart2");
- ShowStatus("NPC_Event:[OnAgitStart2] Run (%d) Events by @AgitStart2.\n",c);
+{ // Run All NPC_Event[OnAgitStart2]
+ int c = npc_event_doall("OnAgitStart2");
+ ShowStatus("NPC_Event:[OnAgitStart2] Run (%d) Events by @AgitStart2.\n",c);
}
/*====================================================
* End woe2 and triggers all npc OnAgitEnd2
*---------------------------------------------------*/
void guild_agit2_end(void)
-{
- // Run All NPC_Event[OnAgitEnd2]
- int c = npc_event_doall("OnAgitEnd2");
- ShowStatus("NPC_Event:[OnAgitEnd2] Run (%d) Events by @AgitEnd2.\n",c);
+{ // Run All NPC_Event[OnAgitEnd2]
+ int c = npc_event_doall("OnAgitEnd2");
+ ShowStatus("NPC_Event:[OnAgitEnd2] Run (%d) Events by @AgitEnd2.\n",c);
}
// How many castles does this guild have?
int guild_checkcastles(struct guild *g)
{
- int nb_cas = 0;
- struct guild_castle *gc = NULL;
- DBIterator *iter = db_iterator(castle_db);
+ int nb_cas = 0;
+ struct guild_castle* gc = NULL;
+ DBIterator *iter = db_iterator(castle_db);
- for (gc = dbi_first(iter); dbi_exists(iter); gc = dbi_next(iter)) {
- if (gc->guild_id == g->guild_id) {
- nb_cas++;
- }
- }
- dbi_destroy(iter);
- return nb_cas;
+ for (gc = dbi_first(iter); dbi_exists(iter); gc = dbi_next(iter)) {
+ if (gc->guild_id == g->guild_id) {
+ nb_cas++;
+ }
+ }
+ dbi_destroy(iter);
+ return nb_cas;
}
// Are these two guilds allied?
bool guild_isallied(int guild_id, int guild_id2)
{
- int i;
- struct guild *g = guild_search(guild_id);
- nullpo_ret(g);
-
- ARR_FIND(0, MAX_GUILDALLIANCE, i, g->alliance[i].guild_id == guild_id2);
- return(i < MAX_GUILDALLIANCE && g->alliance[i].opposition == 0);
-}
-
-void guild_flag_add(struct npc_data *nd)
-{
- int i;
-
- /* check */
- for (i = 0; i < guild_flags_count; i++) {
- if (guild_flags[i] && guild_flags[i]->bl.id == nd->bl.id) {
- return;/* exists, most likely updated the id. */
- }
- }
-
- i = guild_flags_count;/* save the current slot */
- /* add */
- RECREATE(guild_flags,struct npc_data *,++guild_flags_count);
- /* save */
- guild_flags[i] = nd;
-}
-
-void guild_flag_remove(struct npc_data *nd)
-{
- int i, cursor;
- if (guild_flags_count == 0)
- return;
- /* find it */
- for (i = 0; i < guild_flags_count; i++) {
- if (guild_flags[i] && guild_flags[i]->bl.id == nd->bl.id) { /* found */
- guild_flags[i] = NULL;
- break;
- }
- }
-
- /* compact list */
- for (i = 0, cursor = 0; i < guild_flags_count; i++) {
- if (guild_flags[i] == NULL)
- continue;
-
- if (cursor != i) {
- memmove(&guild_flags[cursor], &guild_flags[i], sizeof(struct npc_data *));
- }
-
- cursor++;
- }
+ int i;
+ struct guild* g = guild_search(guild_id);
+ nullpo_ret(g);
+
+ ARR_FIND( 0, MAX_GUILDALLIANCE, i, g->alliance[i].guild_id == guild_id2 );
+ return( i < MAX_GUILDALLIANCE && g->alliance[i].opposition == 0 );
+}
+
+void guild_flag_add(struct npc_data *nd) {
+ int i;
+
+ /* check */
+ for( i = 0; i < guild_flags_count; i++ ) {
+ if( guild_flags[i] && guild_flags[i]->bl.id == nd->bl.id ) {
+ return;/* exists, most likely updated the id. */
+ }
+ }
+
+ i = guild_flags_count;/* save the current slot */
+ /* add */
+ RECREATE(guild_flags,struct npc_data*,++guild_flags_count);
+ /* save */
+ guild_flags[i] = nd;
+}
+
+void guild_flag_remove(struct npc_data *nd) {
+ int i, cursor;
+ if( guild_flags_count == 0 )
+ return;
+ /* find it */
+ for( i = 0; i < guild_flags_count; i++ ) {
+ if( guild_flags[i] && guild_flags[i]->bl.id == nd->bl.id ) {/* found */
+ guild_flags[i] = NULL;
+ break;
+ }
+ }
+
+ /* compact list */
+ for( i = 0, cursor = 0; i < guild_flags_count; i++ ) {
+ if( guild_flags[i] == NULL )
+ continue;
+
+ if( cursor != i ) {
+ memmove(&guild_flags[cursor], &guild_flags[i], sizeof(struct npc_data*));
+ }
+
+ cursor++;
+ }
}
/**
* @see DBApply
*/
-static int eventlist_db_final(DBKey key, DBData *data, va_list ap)
-{
- struct eventlist *next = NULL;
- struct eventlist *current = db_data2ptr(data);
- while (current != NULL) {
- next = current->next;
- aFree(current);
- current = next;
- }
- return 0;
+static int eventlist_db_final(DBKey key, DBData *data, va_list ap) {
+ struct eventlist *next = NULL;
+ struct eventlist *current = db_data2ptr(data);
+ while (current != NULL) {
+ next = current->next;
+ aFree(current);
+ current = next;
+ }
+ return 0;
}
/**
* @see DBApply
*/
-static int guild_expcache_db_final(DBKey key, DBData *data, va_list ap)
-{
- ers_free(expcache_ers, db_data2ptr(data));
- return 0;
+static int guild_expcache_db_final(DBKey key, DBData *data, va_list ap) {
+ ers_free(expcache_ers, db_data2ptr(data));
+ return 0;
}
/**
* @see DBApply
*/
-static int guild_castle_db_final(DBKey key, DBData *data, va_list ap)
-{
- struct guild_castle *gc = db_data2ptr(data);
- if (gc->temp_guardians)
- aFree(gc->temp_guardians);
- aFree(gc);
- return 0;
+static int guild_castle_db_final(DBKey key, DBData *data, va_list ap) {
+ struct guild_castle* gc = db_data2ptr(data);
+ if( gc->temp_guardians )
+ aFree(gc->temp_guardians);
+ aFree(gc);
+ return 0;
}
/* called when scripts are reloaded/unloaded */
-void guild_flags_clear(void)
-{
- int i;
- for (i = 0; i < guild_flags_count; i++) {
- if (guild_flags[i])
- guild_flags[i] = NULL;
- }
-
- guild_flags_count = 0;
-}
-
-void do_init_guild(void)
-{
- guild_db = idb_alloc(DB_OPT_RELEASE_DATA);
- castle_db = idb_alloc(DB_OPT_BASE);
- guild_expcache_db = idb_alloc(DB_OPT_BASE);
- guild_infoevent_db = idb_alloc(DB_OPT_BASE);
- expcache_ers = ers_new(sizeof(struct guild_expcache),"guild.c::expcache_ers",ERS_OPT_NONE);
-
- guild_flags_count = 0;
-
- sv_readdb(db_path, "castle_db.txt", ',', 4, 5, -1, &guild_read_castledb);
-
- memset(guild_skill_tree,0,sizeof(guild_skill_tree));
- sv_readdb(db_path, "guild_skill_tree.txt", ',', 2+MAX_GUILD_SKILL_REQUIRE*2, 2+MAX_GUILD_SKILL_REQUIRE*2, -1, &guild_read_guildskill_tree_db); //guild skill tree [Komurka]
-
- add_timer_func_list(guild_payexp_timer,"guild_payexp_timer");
- add_timer_func_list(guild_send_xy_timer, "guild_send_xy_timer");
- add_timer_interval(gettick()+GUILD_PAYEXP_INVERVAL,guild_payexp_timer,0,0,GUILD_PAYEXP_INVERVAL);
- add_timer_interval(gettick()+GUILD_SEND_XY_INVERVAL,guild_send_xy_timer,0,0,GUILD_SEND_XY_INVERVAL);
-}
-
-void do_final_guild(void)
-{
-
- db_destroy(guild_db);
- castle_db->destroy(castle_db,guild_castle_db_final);
- guild_expcache_db->destroy(guild_expcache_db,guild_expcache_db_final);
- guild_infoevent_db->destroy(guild_infoevent_db,eventlist_db_final);
- ers_destroy(expcache_ers);
-
- aFree(guild_flags);/* never empty; created on boot */
+void guild_flags_clear(void) {
+ int i;
+ for( i = 0; i < guild_flags_count; i++ ) {
+ if( guild_flags[i] )
+ guild_flags[i] = NULL;
+ }
+
+ guild_flags_count = 0;
+}
+
+void do_init_guild(void) {
+ guild_db = idb_alloc(DB_OPT_RELEASE_DATA);
+ castle_db = idb_alloc(DB_OPT_BASE);
+ guild_expcache_db = idb_alloc(DB_OPT_BASE);
+ guild_infoevent_db = idb_alloc(DB_OPT_BASE);
+ expcache_ers = ers_new(sizeof(struct guild_expcache),"guild.c::expcache_ers",ERS_OPT_NONE);
+
+ guild_flags_count = 0;
+
+ sv_readdb(db_path, "castle_db.txt", ',', 4, 5, -1, &guild_read_castledb);
+
+ memset(guild_skill_tree,0,sizeof(guild_skill_tree));
+ sv_readdb(db_path, "guild_skill_tree.txt", ',', 2+MAX_GUILD_SKILL_REQUIRE*2, 2+MAX_GUILD_SKILL_REQUIRE*2, -1, &guild_read_guildskill_tree_db); //guild skill tree [Komurka]
+
+ add_timer_func_list(guild_payexp_timer,"guild_payexp_timer");
+ add_timer_func_list(guild_send_xy_timer, "guild_send_xy_timer");
+ add_timer_interval(gettick()+GUILD_PAYEXP_INVERVAL,guild_payexp_timer,0,0,GUILD_PAYEXP_INVERVAL);
+ add_timer_interval(gettick()+GUILD_SEND_XY_INVERVAL,guild_send_xy_timer,0,0,GUILD_SEND_XY_INVERVAL);
+}
+
+void do_final_guild(void) {
+
+ db_destroy(guild_db);
+ castle_db->destroy(castle_db,guild_castle_db_final);
+ guild_expcache_db->destroy(guild_expcache_db,guild_expcache_db_final);
+ guild_infoevent_db->destroy(guild_infoevent_db,eventlist_db_final);
+ ers_destroy(expcache_ers);
+
+ aFree(guild_flags);/* never empty; created on boot */
}
diff --git a/src/map/guild.h b/src/map/guild.h
index ecae8a30e..3e7b98f59 100644
--- a/src/map/guild.h
+++ b/src/map/guild.h
@@ -15,12 +15,12 @@ struct mob_data;
//For quick linking to a guardian's info. [Skotlex]
struct guardian_data {
- int number; //0-MAX_GUARDIANS-1 = Guardians. MAX_GUARDIANS = Emperium.
- int guild_id;
- int emblem_id;
- int guardup_lv; //Level of GD_GUARDUP skill.
- char guild_name[NAME_LENGTH];
- struct guild_castle *castle;
+ int number; //0-MAX_GUARDIANS-1 = Guardians. MAX_GUARDIANS = Emperium.
+ int guild_id;
+ int emblem_id;
+ int guardup_lv; //Level of GD_GUARDUP skill.
+ char guild_name[NAME_LENGTH];
+ struct guild_castle* castle;
};
int guild_skill_get_max(int id);
@@ -35,8 +35,8 @@ struct guild *guild_search(int guild_id);
struct guild *guild_searchname(char *str);
struct guild_castle *guild_castle_search(int gcid);
-struct guild_castle *guild_mapname2gc(const char *mapname);
-struct guild_castle *guild_mapindex2gc(short mapindex);
+struct guild_castle* guild_mapname2gc(const char* mapname);
+struct guild_castle* guild_mapindex2gc(short mapindex);
struct map_session_data *guild_getavailablesd(struct guild *g);
int guild_getindex(struct guild *g,int account_id,int char_id);
@@ -55,18 +55,18 @@ int guild_reply_invite(struct map_session_data *sd,int guild_id,int flag);
void guild_member_joined(struct map_session_data *sd);
int guild_member_added(int guild_id,int account_id,int char_id,int flag);
int guild_leave(struct map_session_data *sd,int guild_id,
- int account_id,int char_id,const char *mes);
+ int account_id,int char_id,const char *mes);
int guild_member_withdraw(int guild_id,int account_id,int char_id,int flag,
- const char *name,const char *mes);
+ const char *name,const char *mes);
int guild_expulsion(struct map_session_data *sd,int guild_id,
- int account_id,int char_id,const char *mes);
-int guild_skillup(struct map_session_data *sd, int skill_num);
+ int account_id,int char_id,const char *mes);
+int guild_skillup(struct map_session_data* sd, int skill_num);
void guild_block_skill(struct map_session_data *sd, int time);
int guild_reqalliance(struct map_session_data *sd,struct map_session_data *tsd);
int guild_reply_reqalliance(struct map_session_data *sd,int account_id,int flag);
int guild_alliance(int guild_id1,int guild_id2,int account_id1,int account_id2);
int guild_allianceack(int guild_id1,int guild_id2,int account_id1,int account_id2,
- int flag,const char *name1,const char *name2);
+ 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,struct map_session_data *tsd);
int guild_check_alliance(int guild_id1, int guild_id2, int flag);
diff --git a/src/map/homunculus.c b/src/map/homunculus.c
index fda53e18d..ab3d811b2 100644
--- a/src/map/homunculus.c
+++ b/src/map/homunculus.c
@@ -39,7 +39,7 @@
#include <string.h>
#include <math.h>
-struct s_homunculus_db homunculus_db[MAX_HOMUNCULUS_CLASS]; //[orn]
+struct s_homunculus_db homunculus_db[MAX_HOMUNCULUS_CLASS]; //[orn]
struct homun_skill_tree_entry hskill_tree[MAX_HOMUNCULUS_CLASS][MAX_SKILL_TREE];
static int merc_hom_hungry(int tid, unsigned int tick, int id, intptr_t data);
@@ -49,61 +49,39 @@ static unsigned int hexptbl[MAX_LEVEL];
//For holding the view data of npc classes. [Skotlex]
static struct view_data hom_viewdb[MAX_HOMUNCULUS_CLASS];
-struct view_data *merc_get_hom_viewdata(int class_) {
- //Returns the viewdata for homunculus
- if (homdb_checkid(class_))
- return &hom_viewdb[class_-HM_CLASS_BASE];
- return NULL;
+struct view_data* merc_get_hom_viewdata(int class_)
+{ //Returns the viewdata for homunculus
+ if (homdb_checkid(class_))
+ return &hom_viewdb[class_-HM_CLASS_BASE];
+ return NULL;
}
int hom_class2mapid(int hom_class)
{
- switch (hom_class) {
- // Normal Homunculus
- case 6001:
- case 6005:
- return MAPID_LIF;
- case 6002:
- case 6006:
- return MAPID_AMISTR;
- case 6003:
- case 6007:
- return MAPID_FILIR;
- case 6004:
- case 6008:
- return MAPID_VANILMIRTH;
- // Evolved Homunculus
- case 6009:
- case 6013:
- return MAPID_LIF_E;
- case 6010:
- case 6014:
- return MAPID_AMISTR_E;
- case 6011:
- case 6015:
- return MAPID_FILIR_E;
- case 6012:
- case 6016:
- return MAPID_VANILMIRTH_E;
- // Homunculus S
- case 6048:
- return MAPID_EIRA;
- case 6049:
- return MAPID_BAYERI;
- case 6050:
- return MAPID_SERA;
- case 6051:
- return MAPID_DIETER;
- case 6052:
- return MAPID_ELANOR;
-
- default:
- return -1;
- }
+ switch(hom_class)
+ {
+ // Normal Homunculus
+ case 6001: case 6005: return MAPID_LIF;
+ case 6002: case 6006: return MAPID_AMISTR;
+ case 6003: case 6007: return MAPID_FILIR;
+ case 6004: case 6008: return MAPID_VANILMIRTH;
+ // Evolved Homunculus
+ case 6009: case 6013: return MAPID_LIF_E;
+ case 6010: case 6014: return MAPID_AMISTR_E;
+ case 6011: case 6015: return MAPID_FILIR_E;
+ case 6012: case 6016: return MAPID_VANILMIRTH_E;
+ // Homunculus S
+ case 6048: return MAPID_EIRA;
+ case 6049: return MAPID_BAYERI;
+ case 6050: return MAPID_SERA;
+ case 6051: return MAPID_DIETER;
+ case 6052: return MAPID_ELANOR;
+
+ default: return -1;
+ }
}
-int hom_addspiritball(TBL_HOM *hd, int max)
-{
+int hom_addspiritball(TBL_HOM *hd, int max) {
nullpo_ret(hd);
if (max > MAX_SKILL_LEVEL)
@@ -112,17 +90,17 @@ int hom_addspiritball(TBL_HOM *hd, int max)
hd->spiritball = 0;
if (hd->spiritball && hd->spiritball >= max) {
- hd->spiritball = max;
- } else
+ hd->spiritball = max;
+ }
+ else
hd->spiritball++;
-
+
clif_spiritball(&hd->bl);
return 0;
}
-int hom_delspiritball(TBL_HOM *hd, int count, int type)
-{
+int hom_delspiritball(TBL_HOM *hd, int count, int type) {
nullpo_ret(hd);
if (hd->spiritball <= 0) {
@@ -135,7 +113,7 @@ int hom_delspiritball(TBL_HOM *hd, int count, int type)
count = MAX_SKILL_LEVEL;
if (count > hd->spiritball)
count = hd->spiritball;
-
+
hd->spiritball -= count;
if (!type)
clif_spiritball(&hd->bl);
@@ -143,1154 +121,1164 @@ int hom_delspiritball(TBL_HOM *hd, int count, int type)
return 0;
}
-void merc_damage(struct homun_data *hd)
-{
- clif_hominfo(hd->master,hd,0);
+void merc_damage(struct homun_data *hd) {
+ clif_hominfo(hd->master,hd,0);
}
int merc_hom_dead(struct homun_data *hd)
{
- //There's no intimacy penalties on death (from Tharis)
- struct map_session_data *sd = hd->master;
+ //There's no intimacy penalties on death (from Tharis)
+ struct map_session_data *sd = hd->master;
- clif_emotion(&hd->bl, E_WAH);
+ clif_emotion(&hd->bl, E_WAH);
- //Delete timers when dead.
- merc_hom_hungry_timer_delete(hd);
- hd->homunculus.hp = 0;
+ //Delete timers when dead.
+ merc_hom_hungry_timer_delete(hd);
+ hd->homunculus.hp = 0;
- if (!sd) //unit remove map will invoke unit free
- return 3;
+ if (!sd) //unit remove map will invoke unit free
+ return 3;
- clif_emotion(&sd->bl, E_SOB);
- //Remove from map (if it has no intimacy, it is auto-removed from memory)
- return 3;
+ clif_emotion(&sd->bl, E_SOB);
+ //Remove from map (if it has no intimacy, it is auto-removed from memory)
+ return 3;
}
//Vaporize a character's homun. If flag, HP needs to be 80% or above.
int merc_hom_vaporize(struct map_session_data *sd, int flag)
{
- struct homun_data *hd;
-
- nullpo_ret(sd);
-
- hd = sd->hd;
- if (!hd || hd->homunculus.vaporize)
- return 0;
-
- if (status_isdead(&hd->bl))
- return 0; //Can't vaporize a dead homun.
-
- if (flag && get_percentage(hd->battle_status.hp, hd->battle_status.max_hp) < 80)
- return 0;
-
- hd->regen.state.block = 3; //Block regen while vaporized.
- //Delete timers when vaporized.
- merc_hom_hungry_timer_delete(hd);
- hd->homunculus.vaporize = 1;
- if (battle_config.hom_setting&0x40)
- memset(hd->blockskill, 0, sizeof(hd->blockskill));
- clif_hominfo(sd, sd->hd, 0);
- merc_save(hd);
- return unit_remove_map(&hd->bl, CLR_OUTSIGHT);
+ struct homun_data *hd;
+
+ nullpo_ret(sd);
+
+ hd = sd->hd;
+ if (!hd || hd->homunculus.vaporize)
+ return 0;
+
+ if (status_isdead(&hd->bl))
+ return 0; //Can't vaporize a dead homun.
+
+ if (flag && get_percentage(hd->battle_status.hp, hd->battle_status.max_hp) < 80)
+ return 0;
+
+ hd->regen.state.block = 3; //Block regen while vaporized.
+ //Delete timers when vaporized.
+ merc_hom_hungry_timer_delete(hd);
+ hd->homunculus.vaporize = 1;
+ if(battle_config.hom_setting&0x40)
+ memset(hd->blockskill, 0, sizeof(hd->blockskill));
+ clif_hominfo(sd, sd->hd, 0);
+ merc_save(hd);
+ return unit_remove_map(&hd->bl, CLR_OUTSIGHT);
}
-//delete a homunculus, completely "killing it".
+//delete a homunculus, completely "killing it".
//Emote is the emotion the master should use, send negative to disable.
int merc_hom_delete(struct homun_data *hd, int emote)
{
- struct map_session_data *sd;
- nullpo_ret(hd);
- sd = hd->master;
-
- if (!sd)
- return unit_free(&hd->bl,CLR_DEAD);
-
- if (emote >= 0)
- clif_emotion(&sd->bl, emote);
-
- //This makes it be deleted right away.
- hd->homunculus.intimacy = 0;
- // Send homunculus_dead to client
- hd->homunculus.hp = 0;
- clif_hominfo(sd, hd, 0);
- return unit_remove_map(&hd->bl,CLR_OUTSIGHT);
+ struct map_session_data *sd;
+ nullpo_ret(hd);
+ sd = hd->master;
+
+ if (!sd)
+ return unit_free(&hd->bl,CLR_DEAD);
+
+ if (emote >= 0)
+ clif_emotion(&sd->bl, emote);
+
+ //This makes it be deleted right away.
+ hd->homunculus.intimacy = 0;
+ // Send homunculus_dead to client
+ hd->homunculus.hp = 0;
+ clif_hominfo(sd, hd, 0);
+ return unit_remove_map(&hd->bl,CLR_OUTSIGHT);
}
int merc_hom_calc_skilltree(struct homun_data *hd, int flag_evolve)
{
- int i, id = 0;
- int j, f = 1;
- int c = 0;
-
- nullpo_ret(hd);
- /* load previous homunculus form skills first. */
- if (hd->homunculus.prev_class != 0) {
- c = hd->homunculus.prev_class - HM_CLASS_BASE;
-
- for (i = 0; i < MAX_SKILL_TREE && (id = hskill_tree[c][i].id) > 0; i++) {
- if (hd->homunculus.hskill[ id - HM_SKILLBASE ].id)
- continue; //Skill already known.
- if (!battle_config.skillfree) {
- for (j = 0; j < MAX_PC_SKILL_REQUIRE; j++) {
- if (hskill_tree[c][i].need[j].id &&
- merc_hom_checkskill(hd,hskill_tree[c][i].need[j].id) < hskill_tree[c][i].need[j].lv) {
- f = 0;
- break;
- }
- }
- }
- if (f)
- hd->homunculus.hskill[id-HM_SKILLBASE].id = id;
- }
-
- f = 1;
- }
-
- c = hd->homunculus.class_ - HM_CLASS_BASE;
-
- for (i = 0; i < MAX_SKILL_TREE && (id = hskill_tree[c][i].id) > 0; i++) {
- if (hd->homunculus.hskill[ id - HM_SKILLBASE ].id)
- continue; //Skill already known.
- j = (flag_evolve) ? 10 : hd->homunculus.intimacy;
- if (j < hskill_tree[c][i].intimacylv)
- continue;
- if (!battle_config.skillfree) {
- for (j = 0; j < MAX_PC_SKILL_REQUIRE; j++) {
- if (hskill_tree[c][i].need[j].id &&
- merc_hom_checkskill(hd,hskill_tree[c][i].need[j].id) < hskill_tree[c][i].need[j].lv) {
- f = 0;
- break;
- }
- }
- }
- if (f)
- hd->homunculus.hskill[id-HM_SKILLBASE].id = id;
- }
-
- if (hd->master)
- clif_homskillinfoblock(hd->master);
- return 0;
+ int i, id = 0;
+ int j, f = 1;
+ int c = 0;
+
+ nullpo_ret(hd);
+ /* load previous homunculus form skills first. */
+ if( hd->homunculus.prev_class != 0 ) {
+ c = hd->homunculus.prev_class - HM_CLASS_BASE;
+
+ for( i = 0; i < MAX_SKILL_TREE && ( id = hskill_tree[c][i].id ) > 0; i++ ) {
+ if( hd->homunculus.hskill[ id - HM_SKILLBASE ].id )
+ continue; //Skill already known.
+ if(!battle_config.skillfree) {
+ for( j = 0; j < MAX_PC_SKILL_REQUIRE; j++ ) {
+ if( hskill_tree[c][i].need[j].id &&
+ merc_hom_checkskill(hd,hskill_tree[c][i].need[j].id) < hskill_tree[c][i].need[j].lv ) {
+ f = 0;
+ break;
+ }
+ }
+ }
+ if ( f )
+ hd->homunculus.hskill[id-HM_SKILLBASE].id = id;
+ }
+
+ f = 1;
+ }
+
+ c = hd->homunculus.class_ - HM_CLASS_BASE;
+
+ for( i = 0; i < MAX_SKILL_TREE && ( id = hskill_tree[c][i].id ) > 0; i++ ) {
+ if( hd->homunculus.hskill[ id - HM_SKILLBASE ].id )
+ continue; //Skill already known.
+ j = ( flag_evolve ) ? 10 : hd->homunculus.intimacy;
+ if( j < hskill_tree[c][i].intimacylv )
+ continue;
+ if(!battle_config.skillfree) {
+ for( j = 0; j < MAX_PC_SKILL_REQUIRE; j++ ) {
+ if( hskill_tree[c][i].need[j].id &&
+ merc_hom_checkskill(hd,hskill_tree[c][i].need[j].id) < hskill_tree[c][i].need[j].lv ) {
+ f = 0;
+ break;
+ }
+ }
+ }
+ if ( f )
+ hd->homunculus.hskill[id-HM_SKILLBASE].id = id;
+ }
+
+ if( hd->master )
+ clif_homskillinfoblock(hd->master);
+ return 0;
}
int merc_hom_checkskill(struct homun_data *hd,int skill_id)
{
- int i = skill_id - HM_SKILLBASE;
- if (!hd)
- return 0;
+ int i = skill_id - HM_SKILLBASE;
+ if(!hd)
+ return 0;
- if (hd->homunculus.hskill[i].id == skill_id)
- return (hd->homunculus.hskill[i].lv);
+ if(hd->homunculus.hskill[i].id == skill_id)
+ return (hd->homunculus.hskill[i].lv);
- return 0;
+ return 0;
}
-int merc_skill_tree_get_max(int id, int b_class)
-{
- int i, skillid;
- b_class -= HM_CLASS_BASE;
- for (i=0; (skillid=hskill_tree[b_class][i].id)>0; i++)
- if (id == skillid)
- return hskill_tree[b_class][i].max;
- return skill_get_max(id);
+int merc_skill_tree_get_max(int id, int b_class){
+ int i, skillid;
+ b_class -= HM_CLASS_BASE;
+ for(i=0;(skillid=hskill_tree[b_class][i].id)>0;i++)
+ if (id == skillid)
+ return hskill_tree[b_class][i].max;
+ return skill_get_max(id);
}
void merc_hom_skillup(struct homun_data *hd,int skillnum)
{
- int i = 0 ;
- nullpo_retv(hd);
-
- if (hd->homunculus.vaporize)
- return;
-
- i = skillnum - HM_SKILLBASE;
- if (hd->homunculus.skillpts > 0 &&
- hd->homunculus.hskill[i].id &&
- hd->homunculus.hskill[i].flag == SKILL_FLAG_PERMANENT && //Don't allow raising while you have granted skills. [Skotlex]
- hd->homunculus.hskill[i].lv < merc_skill_tree_get_max(skillnum, hd->homunculus.class_)
- ) {
- hd->homunculus.hskill[i].lv++;
- hd->homunculus.skillpts-- ;
- status_calc_homunculus(hd,0);
- if (hd->master) {
- clif_homskillup(hd->master, skillnum);
- clif_hominfo(hd->master,hd,0);
- clif_homskillinfoblock(hd->master);
- }
- }
+ int i = 0 ;
+ nullpo_retv(hd);
+
+ if(hd->homunculus.vaporize)
+ return;
+
+ i = skillnum - HM_SKILLBASE;
+ if(hd->homunculus.skillpts > 0 &&
+ hd->homunculus.hskill[i].id &&
+ hd->homunculus.hskill[i].flag == SKILL_FLAG_PERMANENT && //Don't allow raising while you have granted skills. [Skotlex]
+ hd->homunculus.hskill[i].lv < merc_skill_tree_get_max(skillnum, hd->homunculus.class_)
+ )
+ {
+ hd->homunculus.hskill[i].lv++;
+ hd->homunculus.skillpts-- ;
+ status_calc_homunculus(hd,0);
+ if (hd->master) {
+ clif_homskillup(hd->master, skillnum);
+ clif_hominfo(hd->master,hd,0);
+ clif_homskillinfoblock(hd->master);
+ }
+ }
}
int merc_hom_levelup(struct homun_data *hd)
{
- struct s_homunculus *hom;
- struct h_stats *min, *max;
- int growth_str, growth_agi, growth_vit, growth_int, growth_dex, growth_luk ;
- int growth_max_hp, growth_max_sp ;
- char output[256] ;
- int m_class;
-
- if ((m_class = hom_class2mapid(hd->homunculus.class_)) == -1) {
- ShowError("merc_hom_levelup: Invalid class %d. \n", hd->homunculus.class_);
- return 0;
- }
-
- if ((m_class&HOM_REG) && (hd->homunculus.level >= battle_config.hom_max_level || ((m_class&HOM_S) && hd->homunculus.level >= battle_config.hom_S_max_level) || !hd->exp_next || hd->homunculus.exp < hd->exp_next))
- return 0;
-
- hom = &hd->homunculus;
- hom->level++ ;
- if (!(hom->level % 3))
- hom->skillpts++ ; //1 skillpoint each 3 base level
-
- hom->exp -= hd->exp_next ;
- hd->exp_next = hexptbl[hom->level - 1] ;
-
- max = &hd->homunculusDB->gmax;
- min = &hd->homunculusDB->gmin;
-
- growth_max_hp = rnd_value(min->HP, max->HP);
- growth_max_sp = rnd_value(min->SP, max->SP);
- growth_str = rnd_value(min->str, max->str);
- growth_agi = rnd_value(min->agi, max->agi);
- growth_vit = rnd_value(min->vit, max->vit);
- growth_dex = rnd_value(min->dex, max->dex);
- growth_int = rnd_value(min->int_,max->int_);
- growth_luk = rnd_value(min->luk, max->luk);
-
- //Aegis discards the decimals in the stat growth values!
- growth_str-=growth_str%10;
- growth_agi-=growth_agi%10;
- growth_vit-=growth_vit%10;
- growth_dex-=growth_dex%10;
- growth_int-=growth_int%10;
- growth_luk-=growth_luk%10;
-
- hom->max_hp += growth_max_hp;
- hom->max_sp += growth_max_sp;
- hom->str += growth_str;
- hom->agi += growth_agi;
- hom->vit += growth_vit;
- hom->dex += growth_dex;
- hom->int_+= growth_int;
- hom->luk += growth_luk;
-
- if (battle_config.homunculus_show_growth) {
- sprintf(output,
- "Growth: hp:%d sp:%d str(%.2f) agi(%.2f) vit(%.2f) int(%.2f) dex(%.2f) luk(%.2f) ",
- growth_max_hp, growth_max_sp,
- growth_str/10.0, growth_agi/10.0, growth_vit/10.0,
- growth_int/10.0, growth_dex/10.0, growth_luk/10.0);
- clif_disp_onlyself(hd->master,output,strlen(output));
- }
- return 1 ;
+ struct s_homunculus *hom;
+ struct h_stats *min, *max;
+ int growth_str, growth_agi, growth_vit, growth_int, growth_dex, growth_luk ;
+ int growth_max_hp, growth_max_sp ;
+ char output[256] ;
+ int m_class;
+
+ if((m_class = hom_class2mapid(hd->homunculus.class_)) == -1) {
+ ShowError("merc_hom_levelup: Invalid class %d. \n", hd->homunculus.class_);
+ return 0;
+ }
+
+ if((m_class&HOM_REG) && (hd->homunculus.level >= battle_config.hom_max_level || ((m_class&HOM_S) && hd->homunculus.level >= battle_config.hom_S_max_level) || !hd->exp_next || hd->homunculus.exp < hd->exp_next))
+ return 0;
+
+ hom = &hd->homunculus;
+ hom->level++ ;
+ if (!(hom->level % 3))
+ hom->skillpts++ ; //1 skillpoint each 3 base level
+
+ hom->exp -= hd->exp_next ;
+ hd->exp_next = hexptbl[hom->level - 1] ;
+
+ max = &hd->homunculusDB->gmax;
+ min = &hd->homunculusDB->gmin;
+
+ growth_max_hp = rnd_value(min->HP, max->HP);
+ growth_max_sp = rnd_value(min->SP, max->SP);
+ growth_str = rnd_value(min->str, max->str);
+ growth_agi = rnd_value(min->agi, max->agi);
+ growth_vit = rnd_value(min->vit, max->vit);
+ growth_dex = rnd_value(min->dex, max->dex);
+ growth_int = rnd_value(min->int_,max->int_);
+ growth_luk = rnd_value(min->luk, max->luk);
+
+ //Aegis discards the decimals in the stat growth values!
+ growth_str-=growth_str%10;
+ growth_agi-=growth_agi%10;
+ growth_vit-=growth_vit%10;
+ growth_dex-=growth_dex%10;
+ growth_int-=growth_int%10;
+ growth_luk-=growth_luk%10;
+
+ hom->max_hp += growth_max_hp;
+ hom->max_sp += growth_max_sp;
+ hom->str += growth_str;
+ hom->agi += growth_agi;
+ hom->vit += growth_vit;
+ hom->dex += growth_dex;
+ hom->int_+= growth_int;
+ hom->luk += growth_luk;
+
+ if ( battle_config.homunculus_show_growth ) {
+ sprintf(output,
+ "Growth: hp:%d sp:%d str(%.2f) agi(%.2f) vit(%.2f) int(%.2f) dex(%.2f) luk(%.2f) ",
+ growth_max_hp, growth_max_sp,
+ growth_str/10.0, growth_agi/10.0, growth_vit/10.0,
+ growth_int/10.0, growth_dex/10.0, growth_luk/10.0);
+ clif_disp_onlyself(hd->master,output,strlen(output));
+ }
+ return 1 ;
}
int merc_hom_change_class(struct homun_data *hd, short class_)
{
- int i;
- i = search_homunculusDB_index(class_,HOMUNCULUS_CLASS);
- if (i < 0)
- return 0;
- hd->homunculusDB = &homunculus_db[i];
- hd->homunculus.class_ = class_;
- status_set_viewdata(&hd->bl, class_);
- merc_hom_calc_skilltree(hd, 1);
- return 1;
+ int i;
+ i = search_homunculusDB_index(class_,HOMUNCULUS_CLASS);
+ if(i < 0)
+ return 0;
+ hd->homunculusDB = &homunculus_db[i];
+ hd->homunculus.class_ = class_;
+ status_set_viewdata(&hd->bl, class_);
+ merc_hom_calc_skilltree(hd, 1);
+ return 1;
}
int merc_hom_evolution(struct homun_data *hd)
{
- struct s_homunculus *hom;
- struct h_stats *max, *min;
- struct map_session_data *sd;
- nullpo_ret(hd);
-
- if (!hd->homunculusDB->evo_class || hd->homunculus.class_ == hd->homunculusDB->evo_class) {
- clif_emotion(&hd->bl, E_SWT);
- return 0 ;
- }
- sd = hd->master;
- if (!sd)
- return 0;
-
- if (!merc_hom_change_class(hd, hd->homunculusDB->evo_class)) {
- ShowError("merc_hom_evolution: Can't evolve homunc from %d to %d", hd->homunculus.class_, hd->homunculusDB->evo_class);
- return 0;
- }
-
- //Apply evolution bonuses
- hom = &hd->homunculus;
- max = &hd->homunculusDB->emax;
- min = &hd->homunculusDB->emin;
- hom->max_hp += rnd_value(min->HP, max->HP);
- hom->max_sp += rnd_value(min->SP, max->SP);
- hom->str += 10*rnd_value(min->str, max->str);
- hom->agi += 10*rnd_value(min->agi, max->agi);
- hom->vit += 10*rnd_value(min->vit, max->vit);
- hom->int_+= 10*rnd_value(min->int_,max->int_);
- hom->dex += 10*rnd_value(min->dex, max->dex);
- hom->luk += 10*rnd_value(min->luk, max->luk);
- hom->intimacy = 500;
-
- unit_remove_map(&hd->bl, CLR_OUTSIGHT);
- map_addblock(&hd->bl);
-
- clif_spawn(&hd->bl);
- clif_emotion(&sd->bl, E_NO1);
- clif_specialeffect(&hd->bl,568,AREA);
-
- //status_Calc flag&1 will make current HP/SP be reloaded from hom structure
- hom->hp = hd->battle_status.hp;
- hom->sp = hd->battle_status.sp;
- status_calc_homunculus(hd,1);
-
- if (!(battle_config.hom_setting&0x2))
- skill_unit_move(&sd->hd->bl,gettick(),1); // apply land skills immediately
-
- return 1 ;
+ struct s_homunculus *hom;
+ struct h_stats *max, *min;
+ struct map_session_data *sd;
+ nullpo_ret(hd);
+
+ if(!hd->homunculusDB->evo_class || hd->homunculus.class_ == hd->homunculusDB->evo_class)
+ {
+ clif_emotion(&hd->bl, E_SWT);
+ return 0 ;
+ }
+ sd = hd->master;
+ if (!sd)
+ return 0;
+
+ if (!merc_hom_change_class(hd, hd->homunculusDB->evo_class)) {
+ ShowError("merc_hom_evolution: Can't evolve homunc from %d to %d", hd->homunculus.class_, hd->homunculusDB->evo_class);
+ return 0;
+ }
+
+ //Apply evolution bonuses
+ hom = &hd->homunculus;
+ max = &hd->homunculusDB->emax;
+ min = &hd->homunculusDB->emin;
+ hom->max_hp += rnd_value(min->HP, max->HP);
+ hom->max_sp += rnd_value(min->SP, max->SP);
+ hom->str += 10*rnd_value(min->str, max->str);
+ hom->agi += 10*rnd_value(min->agi, max->agi);
+ hom->vit += 10*rnd_value(min->vit, max->vit);
+ hom->int_+= 10*rnd_value(min->int_,max->int_);
+ hom->dex += 10*rnd_value(min->dex, max->dex);
+ hom->luk += 10*rnd_value(min->luk, max->luk);
+ hom->intimacy = 500;
+
+ unit_remove_map(&hd->bl, CLR_OUTSIGHT);
+ map_addblock(&hd->bl);
+
+ clif_spawn(&hd->bl);
+ clif_emotion(&sd->bl, E_NO1);
+ clif_specialeffect(&hd->bl,568,AREA);
+
+ //status_Calc flag&1 will make current HP/SP be reloaded from hom structure
+ hom->hp = hd->battle_status.hp;
+ hom->sp = hd->battle_status.sp;
+ status_calc_homunculus(hd,1);
+
+ if (!(battle_config.hom_setting&0x2))
+ skill_unit_move(&sd->hd->bl,gettick(),1); // apply land skills immediately
+
+ return 1 ;
}
int hom_mutate(struct homun_data *hd, int homun_id)
{
- struct s_homunculus *hom;
- struct map_session_data *sd;
- int m_class, m_id, prev_class = 0;
- nullpo_ret(hd);
-
- m_class = hom_class2mapid(hd->homunculus.class_);
- m_id = hom_class2mapid(homun_id);
-
- if (m_class == -1 || m_id == -1 || !(m_class&HOM_EVO) || !(m_id&HOM_S)) {
- clif_emotion(&hd->bl, E_SWT);
- return 0;
- }
-
- sd = hd->master;
- if (!sd)
- return 0;
-
- prev_class = hd->homunculus.class_;
-
- if (!merc_hom_change_class(hd, homun_id)) {
- ShowError("hom_mutate: Can't evolve homunc from %d to %d", hd->homunculus.class_, homun_id);
- return 0;
- }
-
- unit_remove_map(&hd->bl, CLR_OUTSIGHT);
- map_addblock(&hd->bl);
-
- clif_spawn(&hd->bl);
- clif_emotion(&sd->bl, E_NO1);
- clif_specialeffect(&hd->bl,568,AREA);
-
-
- //status_Calc flag&1 will make current HP/SP be reloaded from hom structure
- hom = &hd->homunculus;
- hom->hp = hd->battle_status.hp;
- hom->sp = hd->battle_status.sp;
- hom->prev_class = prev_class;
- status_calc_homunculus(hd,1);
-
- if (!(battle_config.hom_setting&0x2))
- skill_unit_move(&sd->hd->bl,gettick(),1); // apply land skills immediately
-
- return 1;
+ struct s_homunculus *hom;
+ struct map_session_data *sd;
+ int m_class, m_id, prev_class = 0;
+ nullpo_ret(hd);
+
+ m_class = hom_class2mapid(hd->homunculus.class_);
+ m_id = hom_class2mapid(homun_id);
+
+ if( m_class == -1 || m_id == -1 || !(m_class&HOM_EVO) || !(m_id&HOM_S) ) {
+ clif_emotion(&hd->bl, E_SWT);
+ return 0;
+ }
+
+ sd = hd->master;
+ if (!sd)
+ return 0;
+
+ prev_class = hd->homunculus.class_;
+
+ if (!merc_hom_change_class(hd, homun_id)) {
+ ShowError("hom_mutate: Can't evolve homunc from %d to %d", hd->homunculus.class_, homun_id);
+ return 0;
+ }
+
+ unit_remove_map(&hd->bl, CLR_OUTSIGHT);
+ map_addblock(&hd->bl);
+
+ clif_spawn(&hd->bl);
+ clif_emotion(&sd->bl, E_NO1);
+ clif_specialeffect(&hd->bl,568,AREA);
+
+
+ //status_Calc flag&1 will make current HP/SP be reloaded from hom structure
+ hom = &hd->homunculus;
+ hom->hp = hd->battle_status.hp;
+ hom->sp = hd->battle_status.sp;
+ hom->prev_class = prev_class;
+ status_calc_homunculus(hd,1);
+
+ if (!(battle_config.hom_setting&0x2))
+ skill_unit_move(&sd->hd->bl,gettick(),1); // apply land skills immediately
+
+ return 1;
}
int merc_hom_gainexp(struct homun_data *hd,int exp)
{
- int m_class;
-
- if (hd->homunculus.vaporize)
- return 1;
-
- if ((m_class = hom_class2mapid(hd->homunculus.class_)) == -1) {
- ShowError("merc_hom_gainexp: Invalid class %d. \n", hd->homunculus.class_);
- return 0;
- }
-
- if (hd->exp_next == 0 ||
- ((m_class&HOM_REG) && hd->homunculus.level >= battle_config.hom_max_level) ||
- ((m_class&HOM_S) && hd->homunculus.level >= battle_config.hom_S_max_level)) {
- hd->homunculus.exp = 0;
- return 0;
- }
-
- hd->homunculus.exp += exp;
-
- if (hd->homunculus.exp < hd->exp_next) {
- clif_hominfo(hd->master,hd,0);
- return 0;
- }
-
- //levelup
- do {
- merc_hom_levelup(hd) ;
- } while (hd->homunculus.exp > hd->exp_next && hd->exp_next != 0);
-
- if (hd->exp_next == 0)
- hd->homunculus.exp = 0 ;
-
- clif_specialeffect(&hd->bl,568,AREA);
- status_calc_homunculus(hd,0);
- status_percent_heal(&hd->bl, 100, 100);
- return 0;
+ int m_class;
+
+ if(hd->homunculus.vaporize)
+ return 1;
+
+ if((m_class = hom_class2mapid(hd->homunculus.class_)) == -1) {
+ ShowError("merc_hom_gainexp: Invalid class %d. \n", hd->homunculus.class_);
+ return 0;
+ }
+
+ if( hd->exp_next == 0 ||
+ ((m_class&HOM_REG) && hd->homunculus.level >= battle_config.hom_max_level) ||
+ ((m_class&HOM_S) && hd->homunculus.level >= battle_config.hom_S_max_level) ) {
+ hd->homunculus.exp = 0;
+ return 0;
+ }
+
+ hd->homunculus.exp += exp;
+
+ if(hd->homunculus.exp < hd->exp_next) {
+ clif_hominfo(hd->master,hd,0);
+ return 0;
+ }
+
+ //levelup
+ do
+ {
+ merc_hom_levelup(hd) ;
+ }
+ while(hd->homunculus.exp > hd->exp_next && hd->exp_next != 0 );
+
+ if( hd->exp_next == 0 )
+ hd->homunculus.exp = 0 ;
+
+ clif_specialeffect(&hd->bl,568,AREA);
+ status_calc_homunculus(hd,0);
+ status_percent_heal(&hd->bl, 100, 100);
+ return 0;
}
// Return the new value
-int merc_hom_increase_intimacy(struct homun_data *hd, unsigned int value)
+int merc_hom_increase_intimacy(struct homun_data * hd, unsigned int value)
{
- if (battle_config.homunculus_friendly_rate != 100)
- value = (value * battle_config.homunculus_friendly_rate) / 100;
-
- if (hd->homunculus.intimacy + value <= 100000)
- hd->homunculus.intimacy += value;
- else
- hd->homunculus.intimacy = 100000;
- return hd->homunculus.intimacy;
+ if (battle_config.homunculus_friendly_rate != 100)
+ value = (value * battle_config.homunculus_friendly_rate) / 100;
+
+ if (hd->homunculus.intimacy + value <= 100000)
+ hd->homunculus.intimacy += value;
+ else
+ hd->homunculus.intimacy = 100000;
+ return hd->homunculus.intimacy;
}
// Return 0 if decrease fails or intimacy became 0 else the new value
-int merc_hom_decrease_intimacy(struct homun_data *hd, unsigned int value)
+int merc_hom_decrease_intimacy(struct homun_data * hd, unsigned int value)
{
- if (hd->homunculus.intimacy >= value)
- hd->homunculus.intimacy -= value;
- else
- hd->homunculus.intimacy = 0;
+ if (hd->homunculus.intimacy >= value)
+ hd->homunculus.intimacy -= value;
+ else
+ hd->homunculus.intimacy = 0;
- return hd->homunculus.intimacy;
+ return hd->homunculus.intimacy;
}
-void merc_hom_heal(struct homun_data *hd)
-{
- clif_hominfo(hd->master,hd,0);
+void merc_hom_heal(struct homun_data *hd) {
+ clif_hominfo(hd->master,hd,0);
}
void merc_save(struct homun_data *hd)
{
- // copy data that must be saved in homunculus struct ( hp / sp )
- TBL_PC *sd = hd->master;
- //Do not check for max_hp/max_sp caps as current could be higher to max due
- //to status changes/skills (they will be capped as needed upon stat
- //calculation on login)
- hd->homunculus.hp = hd->battle_status.hp;
- hd->homunculus.sp = hd->battle_status.sp;
- intif_homunculus_requestsave(sd->status.account_id, &hd->homunculus);
+ // copy data that must be saved in homunculus struct ( hp / sp )
+ TBL_PC * sd = hd->master;
+ //Do not check for max_hp/max_sp caps as current could be higher to max due
+ //to status changes/skills (they will be capped as needed upon stat
+ //calculation on login)
+ hd->homunculus.hp = hd->battle_status.hp;
+ hd->homunculus.sp = hd->battle_status.sp;
+ intif_homunculus_requestsave(sd->status.account_id, &hd->homunculus);
}
int merc_menu(struct map_session_data *sd,int menunum)
{
- nullpo_ret(sd);
- if (sd->hd == NULL)
- return 1;
-
- switch (menunum) {
- case 0:
- break;
- case 1:
- merc_hom_food(sd, sd->hd);
- break;
- case 2:
- merc_hom_delete(sd->hd, -1);
- break;
- default:
- ShowError("merc_menu : unknown menu choice : %d\n", menunum) ;
- break;
- }
- return 0;
+ nullpo_ret(sd);
+ if (sd->hd == NULL)
+ return 1;
+
+ switch(menunum) {
+ case 0:
+ break;
+ case 1:
+ merc_hom_food(sd, sd->hd);
+ break;
+ case 2:
+ merc_hom_delete(sd->hd, -1);
+ break;
+ default:
+ ShowError("merc_menu : unknown menu choice : %d\n", menunum) ;
+ break;
+ }
+ return 0;
}
int merc_hom_food(struct map_session_data *sd, struct homun_data *hd)
{
- int i, foodID, emotion;
-
- if (hd->homunculus.vaporize)
- return 1 ;
-
- foodID = hd->homunculusDB->foodID;
- i = pc_search_inventory(sd,foodID);
- if (i < 0) {
- clif_hom_food(sd,foodID,0);
- return 1;
- }
- pc_delitem(sd,i,1,0,0,LOG_TYPE_CONSUME);
-
- if (hd->homunculus.hunger >= 91) {
- merc_hom_decrease_intimacy(hd, 50);
- emotion = E_WAH;
- } else if (hd->homunculus.hunger >= 76) {
- merc_hom_decrease_intimacy(hd, 5);
- emotion = E_SWT2;
- } else if (hd->homunculus.hunger >= 26) {
- merc_hom_increase_intimacy(hd, 75);
- emotion = E_HO;
- } else if (hd->homunculus.hunger >= 11) {
- merc_hom_increase_intimacy(hd, 100);
- emotion = E_HO;
- } else {
- merc_hom_increase_intimacy(hd, 50);
- emotion = E_HO;
- }
-
- hd->homunculus.hunger += 10; //dunno increase value for each food
- if (hd->homunculus.hunger > 100)
- hd->homunculus.hunger = 100;
-
- clif_emotion(&hd->bl,emotion);
- clif_send_homdata(sd,SP_HUNGRY,hd->homunculus.hunger);
- clif_send_homdata(sd,SP_INTIMATE,hd->homunculus.intimacy / 100);
- clif_hom_food(sd,foodID,1);
-
- // Too much food :/
- if (hd->homunculus.intimacy == 0)
- return merc_hom_delete(sd->hd, E_OMG);
-
- return 0;
+ int i, foodID, emotion;
+
+ if(hd->homunculus.vaporize)
+ return 1 ;
+
+ foodID = hd->homunculusDB->foodID;
+ i = pc_search_inventory(sd,foodID);
+ if(i < 0) {
+ clif_hom_food(sd,foodID,0);
+ return 1;
+ }
+ pc_delitem(sd,i,1,0,0,LOG_TYPE_CONSUME);
+
+ if ( hd->homunculus.hunger >= 91 ) {
+ merc_hom_decrease_intimacy(hd, 50);
+ emotion = E_WAH;
+ } else if ( hd->homunculus.hunger >= 76 ) {
+ merc_hom_decrease_intimacy(hd, 5);
+ emotion = E_SWT2;
+ } else if ( hd->homunculus.hunger >= 26 ) {
+ merc_hom_increase_intimacy(hd, 75);
+ emotion = E_HO;
+ } else if ( hd->homunculus.hunger >= 11 ) {
+ merc_hom_increase_intimacy(hd, 100);
+ emotion = E_HO;
+ } else {
+ merc_hom_increase_intimacy(hd, 50);
+ emotion = E_HO;
+ }
+
+ hd->homunculus.hunger += 10; //dunno increase value for each food
+ if(hd->homunculus.hunger > 100)
+ hd->homunculus.hunger = 100;
+
+ clif_emotion(&hd->bl,emotion);
+ clif_send_homdata(sd,SP_HUNGRY,hd->homunculus.hunger);
+ clif_send_homdata(sd,SP_INTIMATE,hd->homunculus.intimacy / 100);
+ clif_hom_food(sd,foodID,1);
+
+ // Too much food :/
+ if(hd->homunculus.intimacy == 0)
+ return merc_hom_delete(sd->hd, E_OMG);
+
+ return 0;
}
static int merc_hom_hungry(int tid, unsigned int tick, int id, intptr_t data)
{
- struct map_session_data *sd;
- struct homun_data *hd;
-
- sd=map_id2sd(id);
- if (!sd)
- return 1;
-
- if (!sd->status.hom_id || !(hd=sd->hd))
- return 1;
-
- if (hd->hungry_timer != tid) {
- ShowError("merc_hom_hungry_timer %d != %d\n",hd->hungry_timer,tid);
- return 0;
- }
-
- hd->hungry_timer = INVALID_TIMER;
-
- hd->homunculus.hunger-- ;
- if (hd->homunculus.hunger <= 10) {
- clif_emotion(&hd->bl, E_AN);
- } else if (hd->homunculus.hunger == 25) {
- clif_emotion(&hd->bl, E_HMM);
- } else if (hd->homunculus.hunger == 75) {
- clif_emotion(&hd->bl, E_OK);
- }
-
- if (hd->homunculus.hunger < 0) {
- hd->homunculus.hunger = 0;
- // Delete the homunculus if intimacy <= 100
- if (!merc_hom_decrease_intimacy(hd, 100))
- return merc_hom_delete(hd, E_OMG);
- clif_send_homdata(sd,SP_INTIMATE,hd->homunculus.intimacy / 100);
- }
-
- clif_send_homdata(sd,SP_HUNGRY,hd->homunculus.hunger);
- hd->hungry_timer = add_timer(tick+hd->homunculusDB->hungryDelay,merc_hom_hungry,sd->bl.id,0); //simple Fix albator
- return 0;
+ struct map_session_data *sd;
+ struct homun_data *hd;
+
+ sd=map_id2sd(id);
+ if(!sd)
+ return 1;
+
+ if(!sd->status.hom_id || !(hd=sd->hd))
+ return 1;
+
+ if(hd->hungry_timer != tid){
+ ShowError("merc_hom_hungry_timer %d != %d\n",hd->hungry_timer,tid);
+ return 0;
+ }
+
+ hd->hungry_timer = INVALID_TIMER;
+
+ hd->homunculus.hunger-- ;
+ if(hd->homunculus.hunger <= 10) {
+ clif_emotion(&hd->bl, E_AN);
+ } else if(hd->homunculus.hunger == 25) {
+ clif_emotion(&hd->bl, E_HMM);
+ } else if(hd->homunculus.hunger == 75) {
+ clif_emotion(&hd->bl, E_OK);
+ }
+
+ if(hd->homunculus.hunger < 0) {
+ hd->homunculus.hunger = 0;
+ // Delete the homunculus if intimacy <= 100
+ if ( !merc_hom_decrease_intimacy(hd, 100) )
+ return merc_hom_delete(hd, E_OMG);
+ clif_send_homdata(sd,SP_INTIMATE,hd->homunculus.intimacy / 100);
+ }
+
+ clif_send_homdata(sd,SP_HUNGRY,hd->homunculus.hunger);
+ hd->hungry_timer = add_timer(tick+hd->homunculusDB->hungryDelay,merc_hom_hungry,sd->bl.id,0); //simple Fix albator
+ return 0;
}
int merc_hom_hungry_timer_delete(struct homun_data *hd)
{
- nullpo_ret(hd);
- if (hd->hungry_timer != INVALID_TIMER) {
- delete_timer(hd->hungry_timer,merc_hom_hungry);
- hd->hungry_timer = INVALID_TIMER;
- }
- return 1;
+ nullpo_ret(hd);
+ if(hd->hungry_timer != INVALID_TIMER) {
+ delete_timer(hd->hungry_timer,merc_hom_hungry);
+ hd->hungry_timer = INVALID_TIMER;
+ }
+ return 1;
}
int merc_hom_change_name(struct map_session_data *sd,char *name)
{
- int i;
- struct homun_data *hd;
- nullpo_retr(1, sd);
-
- hd = sd->hd;
- if (!merc_is_hom_active(hd))
- return 1;
- if (hd->homunculus.rename_flag && !battle_config.hom_rename)
- return 1;
-
- for (i=0; i<NAME_LENGTH && name[i]; i++) {
- if (!(name[i]&0xe0) || name[i]==0x7f)
- return 1;
- }
-
- return intif_rename_hom(sd, name);
+ int i;
+ struct homun_data *hd;
+ nullpo_retr(1, sd);
+
+ hd = sd->hd;
+ if (!merc_is_hom_active(hd))
+ return 1;
+ if(hd->homunculus.rename_flag && !battle_config.hom_rename)
+ return 1;
+
+ for(i=0;i<NAME_LENGTH && name[i];i++){
+ if( !(name[i]&0xe0) || name[i]==0x7f)
+ return 1;
+ }
+
+ return intif_rename_hom(sd, name);
}
-int merc_hom_change_name_ack(struct map_session_data *sd, char *name, int flag)
+int merc_hom_change_name_ack(struct map_session_data *sd, char* name, int flag)
{
- struct homun_data *hd = sd->hd;
- if (!merc_is_hom_active(hd)) return 0;
-
- normalize_name(name," ");//bugreport:3032
-
- if (!flag || !strlen(name)) {
- clif_displaymessage(sd->fd, msg_txt(280)); // You cannot use this name
- return 0;
- }
- strncpy(hd->homunculus.name,name,NAME_LENGTH);
- clif_charnameack(0,&hd->bl);
- hd->homunculus.rename_flag = 1;
- clif_hominfo(sd,hd,0);
- return 1;
+ struct homun_data *hd = sd->hd;
+ if (!merc_is_hom_active(hd)) return 0;
+
+ normalize_name(name," ");//bugreport:3032
+
+ if ( !flag || !strlen(name) ) {
+ clif_displaymessage(sd->fd, msg_txt(280)); // You cannot use this name
+ return 0;
+ }
+ strncpy(hd->homunculus.name,name,NAME_LENGTH);
+ clif_charnameack (0,&hd->bl);
+ hd->homunculus.rename_flag = 1;
+ clif_hominfo(sd,hd,0);
+ return 1;
}
int search_homunculusDB_index(int key,int type)
{
- int i;
-
- for (i=0; i<MAX_HOMUNCULUS_CLASS; i++) {
- if (homunculus_db[i].base_class <= 0)
- continue;
- switch (type) {
- case HOMUNCULUS_CLASS:
- if (homunculus_db[i].base_class == key ||
- homunculus_db[i].evo_class == key)
- return i;
- break;
- case HOMUNCULUS_FOOD:
- if (homunculus_db[i].foodID == key)
- return i;
- break;
- default:
- return -1;
- }
- }
- return -1;
+ int i;
+
+ for(i=0;i<MAX_HOMUNCULUS_CLASS;i++) {
+ if(homunculus_db[i].base_class <= 0)
+ continue;
+ switch(type) {
+ case HOMUNCULUS_CLASS:
+ if(homunculus_db[i].base_class == key ||
+ homunculus_db[i].evo_class == key)
+ return i;
+ break;
+ case HOMUNCULUS_FOOD:
+ if(homunculus_db[i].foodID == key)
+ return i;
+ break;
+ default:
+ return -1;
+ }
+ }
+ return -1;
}
// Create homunc structure
int merc_hom_alloc(struct map_session_data *sd, struct s_homunculus *hom)
{
- struct homun_data *hd;
- int i = 0;
-
- nullpo_retr(1, sd);
-
- Assert((sd->status.hom_id == 0 || sd->hd == 0) || sd->hd->master == sd);
-
- i = search_homunculusDB_index(hom->class_,HOMUNCULUS_CLASS);
- if (i < 0) {
- ShowError("merc_hom_alloc: unknown class [%d] for homunculus '%s', requesting deletion.\n", hom->class_, hom->name);
- sd->status.hom_id = 0;
- intif_homunculus_requestdelete(hom->hom_id);
- return 1;
- }
- sd->hd = hd = (struct homun_data *)aCalloc(1,sizeof(struct homun_data));
- hd->bl.type = BL_HOM;
- hd->bl.id = npc_get_new_npc_id();
-
- hd->master = sd;
- hd->homunculusDB = &homunculus_db[i];
- memcpy(&hd->homunculus, hom, sizeof(struct s_homunculus));
- hd->exp_next = hexptbl[hd->homunculus.level - 1];
-
- status_set_viewdata(&hd->bl, hd->homunculus.class_);
- status_change_init(&hd->bl);
- unit_dataset(&hd->bl);
- hd->ud.dir = sd->ud.dir;
-
- // Find a random valid pos around the player
- hd->bl.m = sd->bl.m;
- hd->bl.x = sd->bl.x;
- hd->bl.y = sd->bl.y;
- unit_calc_pos(&hd->bl, sd->bl.x, sd->bl.y, sd->ud.dir);
- hd->bl.x = hd->ud.to_x;
- hd->bl.y = hd->ud.to_y;
-
- map_addiddb(&hd->bl);
- status_calc_homunculus(hd,1);
-
- hd->hungry_timer = INVALID_TIMER;
- return 0;
+ struct homun_data *hd;
+ int i = 0;
+
+ nullpo_retr(1, sd);
+
+ Assert((sd->status.hom_id == 0 || sd->hd == 0) || sd->hd->master == sd);
+
+ i = search_homunculusDB_index(hom->class_,HOMUNCULUS_CLASS);
+ if(i < 0) {
+ ShowError("merc_hom_alloc: unknown class [%d] for homunculus '%s', requesting deletion.\n", hom->class_, hom->name);
+ sd->status.hom_id = 0;
+ intif_homunculus_requestdelete(hom->hom_id);
+ return 1;
+ }
+ sd->hd = hd = (struct homun_data*)aCalloc(1,sizeof(struct homun_data));
+ hd->bl.type = BL_HOM;
+ hd->bl.id = npc_get_new_npc_id();
+
+ hd->master = sd;
+ hd->homunculusDB = &homunculus_db[i];
+ memcpy(&hd->homunculus, hom, sizeof(struct s_homunculus));
+ hd->exp_next = hexptbl[hd->homunculus.level - 1];
+
+ status_set_viewdata(&hd->bl, hd->homunculus.class_);
+ status_change_init(&hd->bl);
+ unit_dataset(&hd->bl);
+ hd->ud.dir = sd->ud.dir;
+
+ // Find a random valid pos around the player
+ hd->bl.m = sd->bl.m;
+ hd->bl.x = sd->bl.x;
+ hd->bl.y = sd->bl.y;
+ unit_calc_pos(&hd->bl, sd->bl.x, sd->bl.y, sd->ud.dir);
+ hd->bl.x = hd->ud.to_x;
+ hd->bl.y = hd->ud.to_y;
+
+ map_addiddb(&hd->bl);
+ status_calc_homunculus(hd,1);
+
+ hd->hungry_timer = INVALID_TIMER;
+ return 0;
}
-void merc_hom_init_timers(struct homun_data *hd)
+void merc_hom_init_timers(struct homun_data * hd)
{
- if (hd->hungry_timer == INVALID_TIMER)
- hd->hungry_timer = add_timer(gettick()+hd->homunculusDB->hungryDelay,merc_hom_hungry,hd->master->bl.id,0);
- hd->regen.state.block = 0; //Restore HP/SP block.
+ if (hd->hungry_timer == INVALID_TIMER)
+ hd->hungry_timer = add_timer(gettick()+hd->homunculusDB->hungryDelay,merc_hom_hungry,hd->master->bl.id,0);
+ hd->regen.state.block = 0; //Restore HP/SP block.
}
int merc_call_homunculus(struct map_session_data *sd)
{
- struct homun_data *hd;
-
- if (!sd->status.hom_id) //Create a new homun.
- return merc_create_homunculus_request(sd, HM_CLASS_BASE + rnd_value(0, 7)) ;
-
- // If homunc not yet loaded, load it
- if (!sd->hd)
- return intif_homunculus_requestload(sd->status.account_id, sd->status.hom_id);
-
- hd = sd->hd;
-
- if (!hd->homunculus.vaporize)
- return 0; //Can't use this if homun wasn't vaporized.
-
- merc_hom_init_timers(hd);
- hd->homunculus.vaporize = 0;
- if (hd->bl.prev == NULL) {
- //Spawn him
- hd->bl.x = sd->bl.x;
- hd->bl.y = sd->bl.y;
- hd->bl.m = sd->bl.m;
- map_addblock(&hd->bl);
- clif_spawn(&hd->bl);
- clif_send_homdata(sd,SP_ACK,0);
- clif_hominfo(sd,hd,1);
- clif_hominfo(sd,hd,0); // send this x2. dunno why, but kRO does that [blackhole89]
- clif_homskillinfoblock(sd);
- if (battle_config.slaves_inherit_speed&1)
- status_calc_bl(&hd->bl, SCB_SPEED);
- merc_save(hd);
- } else
- //Warp him to master.
- unit_warp(&hd->bl,sd->bl.m, sd->bl.x, sd->bl.y,CLR_OUTSIGHT);
- return 1;
+ struct homun_data *hd;
+
+ if (!sd->status.hom_id) //Create a new homun.
+ return merc_create_homunculus_request(sd, HM_CLASS_BASE + rnd_value(0, 7)) ;
+
+ // If homunc not yet loaded, load it
+ if (!sd->hd)
+ return intif_homunculus_requestload(sd->status.account_id, sd->status.hom_id);
+
+ hd = sd->hd;
+
+ if (!hd->homunculus.vaporize)
+ return 0; //Can't use this if homun wasn't vaporized.
+
+ merc_hom_init_timers(hd);
+ hd->homunculus.vaporize = 0;
+ if (hd->bl.prev == NULL)
+ { //Spawn him
+ hd->bl.x = sd->bl.x;
+ hd->bl.y = sd->bl.y;
+ hd->bl.m = sd->bl.m;
+ map_addblock(&hd->bl);
+ clif_spawn(&hd->bl);
+ clif_send_homdata(sd,SP_ACK,0);
+ clif_hominfo(sd,hd,1);
+ clif_hominfo(sd,hd,0); // send this x2. dunno why, but kRO does that [blackhole89]
+ clif_homskillinfoblock(sd);
+ if (battle_config.slaves_inherit_speed&1)
+ status_calc_bl(&hd->bl, SCB_SPEED);
+ merc_save(hd);
+ } else
+ //Warp him to master.
+ unit_warp(&hd->bl,sd->bl.m, sd->bl.x, sd->bl.y,CLR_OUTSIGHT);
+ return 1;
}
// Recv homunculus data from char server
int merc_hom_recv_data(int account_id, struct s_homunculus *sh, int flag)
{
- struct map_session_data *sd;
- struct homun_data *hd;
-
- sd = map_id2sd(account_id);
- if (!sd)
- return 0;
- if (sd->status.char_id != sh->char_id) {
- if (sd->status.hom_id == sh->hom_id)
- sh->char_id = sd->status.char_id; //Correct char id.
- else
- return 0;
- }
- if (!flag) { // Failed to load
- sd->status.hom_id = 0;
- return 0;
- }
-
- if (!sd->status.hom_id) //Hom just created.
- sd->status.hom_id = sh->hom_id;
- if (sd->hd) //uh? Overwrite the data.
- memcpy(&sd->hd->homunculus, sh, sizeof(struct s_homunculus));
- else
- merc_hom_alloc(sd, sh);
-
- hd = sd->hd;
- if (hd && hd->homunculus.hp && !hd->homunculus.vaporize && hd->bl.prev == NULL && sd->bl.prev != NULL) {
- map_addblock(&hd->bl);
- clif_spawn(&hd->bl);
- clif_send_homdata(sd,SP_ACK,0);
- clif_hominfo(sd,hd,1);
- clif_hominfo(sd,hd,0); // send this x2. dunno why, but kRO does that [blackhole89]
- clif_homskillinfoblock(sd);
- merc_hom_init_timers(hd);
- }
- return 1;
+ struct map_session_data *sd;
+ struct homun_data *hd;
+
+ sd = map_id2sd(account_id);
+ if(!sd)
+ return 0;
+ if (sd->status.char_id != sh->char_id)
+ {
+ if (sd->status.hom_id == sh->hom_id)
+ sh->char_id = sd->status.char_id; //Correct char id.
+ else
+ return 0;
+ }
+ if(!flag) { // Failed to load
+ sd->status.hom_id = 0;
+ return 0;
+ }
+
+ if (!sd->status.hom_id) //Hom just created.
+ sd->status.hom_id = sh->hom_id;
+ if (sd->hd) //uh? Overwrite the data.
+ memcpy(&sd->hd->homunculus, sh, sizeof(struct s_homunculus));
+ else
+ merc_hom_alloc(sd, sh);
+
+ hd = sd->hd;
+ if(hd && hd->homunculus.hp && !hd->homunculus.vaporize && hd->bl.prev == NULL && sd->bl.prev != NULL)
+ {
+ map_addblock(&hd->bl);
+ clif_spawn(&hd->bl);
+ clif_send_homdata(sd,SP_ACK,0);
+ clif_hominfo(sd,hd,1);
+ clif_hominfo(sd,hd,0); // send this x2. dunno why, but kRO does that [blackhole89]
+ clif_homskillinfoblock(sd);
+ merc_hom_init_timers(hd);
+ }
+ return 1;
}
// Ask homunculus creation to char server
int merc_create_homunculus_request(struct map_session_data *sd, int class_)
{
- struct s_homunculus homun;
- struct h_stats *base;
- int i;
-
- nullpo_retr(1, sd);
-
- i = search_homunculusDB_index(class_,HOMUNCULUS_CLASS);
- if (i < 0) return 0;
-
- memset(&homun, 0, sizeof(struct s_homunculus));
- //Initial data
- strncpy(homun.name, homunculus_db[i].name, NAME_LENGTH-1);
- homun.class_ = class_;
- homun.level = 1;
- homun.hunger = 32; //32%
- homun.intimacy = 2100; //21/1000
- homun.char_id = sd->status.char_id;
-
- homun.hp = 10 ;
- base = &homunculus_db[i].base;
- homun.max_hp = base->HP;
- homun.max_sp = base->SP;
- homun.str = base->str *10;
- homun.agi = base->agi *10;
- homun.vit = base->vit *10;
- homun.int_= base->int_*10;
- homun.dex = base->dex *10;
- homun.luk = base->luk *10;
-
- // Request homunculus creation
- intif_homunculus_create(sd->status.account_id, &homun);
- return 1;
+ struct s_homunculus homun;
+ struct h_stats *base;
+ int i;
+
+ nullpo_retr(1, sd);
+
+ i = search_homunculusDB_index(class_,HOMUNCULUS_CLASS);
+ if(i < 0) return 0;
+
+ memset(&homun, 0, sizeof(struct s_homunculus));
+ //Initial data
+ strncpy(homun.name, homunculus_db[i].name, NAME_LENGTH-1);
+ homun.class_ = class_;
+ homun.level = 1;
+ homun.hunger = 32; //32%
+ homun.intimacy = 2100; //21/1000
+ homun.char_id = sd->status.char_id;
+
+ homun.hp = 10 ;
+ base = &homunculus_db[i].base;
+ homun.max_hp = base->HP;
+ homun.max_sp = base->SP;
+ homun.str = base->str *10;
+ homun.agi = base->agi *10;
+ homun.vit = base->vit *10;
+ homun.int_= base->int_*10;
+ homun.dex = base->dex *10;
+ homun.luk = base->luk *10;
+
+ // Request homunculus creation
+ intif_homunculus_create(sd->status.account_id, &homun);
+ return 1;
}
-int merc_resurrect_homunculus(struct map_session_data *sd, unsigned char per, short x, short y)
+int merc_resurrect_homunculus(struct map_session_data* sd, unsigned char per, short x, short y)
{
- struct homun_data *hd;
- nullpo_ret(sd);
-
- if (!sd->status.hom_id)
- return 0; // no homunculus
-
- if (!sd->hd) //Load homun data;
- return intif_homunculus_requestload(sd->status.account_id, sd->status.hom_id);
-
- hd = sd->hd;
-
- if (hd->homunculus.vaporize)
- return 0; // vaporized homunculi need to be 'called'
-
- if (!status_isdead(&hd->bl))
- return 0; // already alive
-
- merc_hom_init_timers(hd);
-
- if (!hd->bl.prev) {
- //Add it back to the map.
- hd->bl.m = sd->bl.m;
- hd->bl.x = x;
- hd->bl.y = y;
- map_addblock(&hd->bl);
- clif_spawn(&hd->bl);
- }
- status_revive(&hd->bl, per, 0);
- return 1;
+ struct homun_data* hd;
+ nullpo_ret(sd);
+
+ if (!sd->status.hom_id)
+ return 0; // no homunculus
+
+ if (!sd->hd) //Load homun data;
+ return intif_homunculus_requestload(sd->status.account_id, sd->status.hom_id);
+
+ hd = sd->hd;
+
+ if (hd->homunculus.vaporize)
+ return 0; // vaporized homunculi need to be 'called'
+
+ if (!status_isdead(&hd->bl))
+ return 0; // already alive
+
+ merc_hom_init_timers(hd);
+
+ if (!hd->bl.prev)
+ { //Add it back to the map.
+ hd->bl.m = sd->bl.m;
+ hd->bl.x = x;
+ hd->bl.y = y;
+ map_addblock(&hd->bl);
+ clif_spawn(&hd->bl);
+ }
+ status_revive(&hd->bl, per, 0);
+ return 1;
}
void merc_hom_revive(struct homun_data *hd, unsigned int hp, unsigned int sp)
{
- struct map_session_data *sd = hd->master;
- hd->homunculus.hp = hd->battle_status.hp;
- if (!sd)
- return;
- clif_send_homdata(sd,SP_ACK,0);
- clif_hominfo(sd,hd,1);
- clif_hominfo(sd,hd,0);
- clif_homskillinfoblock(sd);
+ struct map_session_data *sd = hd->master;
+ hd->homunculus.hp = hd->battle_status.hp;
+ if (!sd)
+ return;
+ clif_send_homdata(sd,SP_ACK,0);
+ clif_hominfo(sd,hd,1);
+ clif_hominfo(sd,hd,0);
+ clif_homskillinfoblock(sd);
}
void merc_reset_stats(struct homun_data *hd)
-{
- //Resets a homunc stats back to zero (but doesn't touches hunger or intimacy)
- struct s_homunculus_db *db;
- struct s_homunculus *hom;
- struct h_stats *base;
- hom = &hd->homunculus;
- db = hd->homunculusDB;
- base = &db->base;
- hom->level = 1;
- hom->hp = 10;
- hom->max_hp = base->HP;
- hom->max_sp = base->SP;
- hom->str = base->str *10;
- hom->agi = base->agi *10;
- hom->vit = base->vit *10;
- hom->int_= base->int_*10;
- hom->dex = base->dex *10;
- hom->luk = base->luk *10;
- hom->exp = 0;
- hd->exp_next = hexptbl[0];
- memset(&hd->homunculus.hskill, 0, sizeof hd->homunculus.hskill);
- hd->homunculus.skillpts = 0;
+{ //Resets a homunc stats back to zero (but doesn't touches hunger or intimacy)
+ struct s_homunculus_db *db;
+ struct s_homunculus *hom;
+ struct h_stats *base;
+ hom = &hd->homunculus;
+ db = hd->homunculusDB;
+ base = &db->base;
+ hom->level = 1;
+ hom->hp = 10;
+ hom->max_hp = base->HP;
+ hom->max_sp = base->SP;
+ hom->str = base->str *10;
+ hom->agi = base->agi *10;
+ hom->vit = base->vit *10;
+ hom->int_= base->int_*10;
+ hom->dex = base->dex *10;
+ hom->luk = base->luk *10;
+ hom->exp = 0;
+ hd->exp_next = hexptbl[0];
+ memset(&hd->homunculus.hskill, 0, sizeof hd->homunculus.hskill);
+ hd->homunculus.skillpts = 0;
}
int merc_hom_shuffle(struct homun_data *hd)
{
- struct map_session_data *sd;
- int lv, i, skillpts;
- unsigned int exp;
- struct s_skill b_skill[MAX_HOMUNSKILL];
-
- if (!merc_is_hom_active(hd))
- return 0;
-
- sd = hd->master;
- lv = hd->homunculus.level;
- exp = hd->homunculus.exp;
- memcpy(&b_skill, &hd->homunculus.hskill, sizeof(b_skill));
- skillpts = hd->homunculus.skillpts;
- //Reset values to level 1.
- merc_reset_stats(hd);
- //Level it back up
- for (i = 1; i < lv && hd->exp_next; i++) {
- hd->homunculus.exp += hd->exp_next;
- merc_hom_levelup(hd);
- }
-
- if (hd->homunculus.class_ == hd->homunculusDB->evo_class) {
- //Evolved bonuses
- struct s_homunculus *hom = &hd->homunculus;
- struct h_stats *max = &hd->homunculusDB->emax, *min = &hd->homunculusDB->emin;
- hom->max_hp += rnd_value(min->HP, max->HP);
- hom->max_sp += rnd_value(min->SP, max->SP);
- hom->str += 10*rnd_value(min->str, max->str);
- hom->agi += 10*rnd_value(min->agi, max->agi);
- hom->vit += 10*rnd_value(min->vit, max->vit);
- hom->int_+= 10*rnd_value(min->int_,max->int_);
- hom->dex += 10*rnd_value(min->dex, max->dex);
- hom->luk += 10*rnd_value(min->luk, max->luk);
- }
-
- hd->homunculus.exp = exp;
- memcpy(&hd->homunculus.hskill, &b_skill, sizeof(b_skill));
- hd->homunculus.skillpts = skillpts;
- clif_homskillinfoblock(sd);
- status_calc_homunculus(hd,0);
- status_percent_heal(&hd->bl, 100, 100);
- clif_specialeffect(&hd->bl,568,AREA);
-
- return 1;
+ struct map_session_data *sd;
+ int lv, i, skillpts;
+ unsigned int exp;
+ struct s_skill b_skill[MAX_HOMUNSKILL];
+
+ if (!merc_is_hom_active(hd))
+ return 0;
+
+ sd = hd->master;
+ lv = hd->homunculus.level;
+ exp = hd->homunculus.exp;
+ memcpy(&b_skill, &hd->homunculus.hskill, sizeof(b_skill));
+ skillpts = hd->homunculus.skillpts;
+ //Reset values to level 1.
+ merc_reset_stats(hd);
+ //Level it back up
+ for (i = 1; i < lv && hd->exp_next; i++){
+ hd->homunculus.exp += hd->exp_next;
+ merc_hom_levelup(hd);
+ }
+
+ if(hd->homunculus.class_ == hd->homunculusDB->evo_class) {
+ //Evolved bonuses
+ struct s_homunculus *hom = &hd->homunculus;
+ struct h_stats *max = &hd->homunculusDB->emax, *min = &hd->homunculusDB->emin;
+ hom->max_hp += rnd_value(min->HP, max->HP);
+ hom->max_sp += rnd_value(min->SP, max->SP);
+ hom->str += 10*rnd_value(min->str, max->str);
+ hom->agi += 10*rnd_value(min->agi, max->agi);
+ hom->vit += 10*rnd_value(min->vit, max->vit);
+ hom->int_+= 10*rnd_value(min->int_,max->int_);
+ hom->dex += 10*rnd_value(min->dex, max->dex);
+ hom->luk += 10*rnd_value(min->luk, max->luk);
+ }
+
+ hd->homunculus.exp = exp;
+ memcpy(&hd->homunculus.hskill, &b_skill, sizeof(b_skill));
+ hd->homunculus.skillpts = skillpts;
+ clif_homskillinfoblock(sd);
+ status_calc_homunculus(hd,0);
+ status_percent_heal(&hd->bl, 100, 100);
+ clif_specialeffect(&hd->bl,568,AREA);
+
+ return 1;
}
-static bool read_homunculusdb_sub(char *str[], int columns, int current)
+static bool read_homunculusdb_sub(char* str[], int columns, int current)
{
- int classid;
- struct s_homunculus_db *db;
-
- //Base Class,Evo Class
- classid = atoi(str[0]);
- if (classid < HM_CLASS_BASE || classid > HM_CLASS_MAX) {
- ShowError("read_homunculusdb : Invalid class %d\n", classid);
- return false;
- }
- db = &homunculus_db[current];
- db->base_class = classid;
- classid = atoi(str[1]);
- if (classid < HM_CLASS_BASE || classid > HM_CLASS_MAX) {
- db->base_class = 0;
- ShowError("read_homunculusdb : Invalid class %d\n", classid);
- return false;
- }
- db->evo_class = classid;
- //Name, Food, Hungry Delay, Base Size, Evo Size, Race, Element, ASPD
- strncpy(db->name,str[2],NAME_LENGTH-1);
- db->foodID = atoi(str[3]);
- db->hungryDelay = atoi(str[4]);
- db->base_size = atoi(str[5]);
- db->evo_size = atoi(str[6]);
- db->race = atoi(str[7]);
- db->element = atoi(str[8]);
- db->baseASPD = atoi(str[9]);
- //base HP, SP, str, agi, vit, int, dex, luk
- db->base.HP = atoi(str[10]);
- db->base.SP = atoi(str[11]);
- db->base.str = atoi(str[12]);
- db->base.agi = atoi(str[13]);
- db->base.vit = atoi(str[14]);
- db->base.int_= atoi(str[15]);
- db->base.dex = atoi(str[16]);
- db->base.luk = atoi(str[17]);
- //Growth Min/Max HP, SP, str, agi, vit, int, dex, luk
- db->gmin.HP = atoi(str[18]);
- db->gmax.HP = atoi(str[19]);
- db->gmin.SP = atoi(str[20]);
- db->gmax.SP = atoi(str[21]);
- db->gmin.str = atoi(str[22]);
- db->gmax.str = atoi(str[23]);
- db->gmin.agi = atoi(str[24]);
- db->gmax.agi = atoi(str[25]);
- db->gmin.vit = atoi(str[26]);
- db->gmax.vit = atoi(str[27]);
- db->gmin.int_= atoi(str[28]);
- db->gmax.int_= atoi(str[29]);
- db->gmin.dex = atoi(str[30]);
- db->gmax.dex = atoi(str[31]);
- db->gmin.luk = atoi(str[32]);
- db->gmax.luk = atoi(str[33]);
- //Evolution Min/Max HP, SP, str, agi, vit, int, dex, luk
- db->emin.HP = atoi(str[34]);
- db->emax.HP = atoi(str[35]);
- db->emin.SP = atoi(str[36]);
- db->emax.SP = atoi(str[37]);
- db->emin.str = atoi(str[38]);
- db->emax.str = atoi(str[39]);
- db->emin.agi = atoi(str[40]);
- db->emax.agi = atoi(str[41]);
- db->emin.vit = atoi(str[42]);
- db->emax.vit = atoi(str[43]);
- db->emin.int_= atoi(str[44]);
- db->emax.int_= atoi(str[45]);
- db->emin.dex = atoi(str[46]);
- db->emax.dex = atoi(str[47]);
- db->emin.luk = atoi(str[48]);
- db->emax.luk = atoi(str[49]);
-
- //Check that the min/max values really are below the other one.
- if (db->gmin.HP > db->gmax.HP)
- db->gmin.HP = db->gmax.HP;
- if (db->gmin.SP > db->gmax.SP)
- db->gmin.SP = db->gmax.SP;
- if (db->gmin.str > db->gmax.str)
- db->gmin.str = db->gmax.str;
- if (db->gmin.agi > db->gmax.agi)
- db->gmin.agi = db->gmax.agi;
- if (db->gmin.vit > db->gmax.vit)
- db->gmin.vit = db->gmax.vit;
- if (db->gmin.int_> db->gmax.int_)
- db->gmin.int_= db->gmax.int_;
- if (db->gmin.dex > db->gmax.dex)
- db->gmin.dex = db->gmax.dex;
- if (db->gmin.luk > db->gmax.luk)
- db->gmin.luk = db->gmax.luk;
-
- if (db->emin.HP > db->emax.HP)
- db->emin.HP = db->emax.HP;
- if (db->emin.SP > db->emax.SP)
- db->emin.SP = db->emax.SP;
- if (db->emin.str > db->emax.str)
- db->emin.str = db->emax.str;
- if (db->emin.agi > db->emax.agi)
- db->emin.agi = db->emax.agi;
- if (db->emin.vit > db->emax.vit)
- db->emin.vit = db->emax.vit;
- if (db->emin.int_> db->emax.int_)
- db->emin.int_= db->emax.int_;
- if (db->emin.dex > db->emax.dex)
- db->emin.dex = db->emax.dex;
- if (db->emin.luk > db->emax.luk)
- db->emin.luk = db->emax.luk;
-
- return true;
+ int classid;
+ struct s_homunculus_db *db;
+
+ //Base Class,Evo Class
+ classid = atoi(str[0]);
+ if (classid < HM_CLASS_BASE || classid > HM_CLASS_MAX)
+ {
+ ShowError("read_homunculusdb : Invalid class %d\n", classid);
+ return false;
+ }
+ db = &homunculus_db[current];
+ db->base_class = classid;
+ classid = atoi(str[1]);
+ if (classid < HM_CLASS_BASE || classid > HM_CLASS_MAX)
+ {
+ db->base_class = 0;
+ ShowError("read_homunculusdb : Invalid class %d\n", classid);
+ return false;
+ }
+ db->evo_class = classid;
+ //Name, Food, Hungry Delay, Base Size, Evo Size, Race, Element, ASPD
+ strncpy(db->name,str[2],NAME_LENGTH-1);
+ db->foodID = atoi(str[3]);
+ db->hungryDelay = atoi(str[4]);
+ db->base_size = atoi(str[5]);
+ db->evo_size = atoi(str[6]);
+ db->race = atoi(str[7]);
+ db->element = atoi(str[8]);
+ db->baseASPD = atoi(str[9]);
+ //base HP, SP, str, agi, vit, int, dex, luk
+ db->base.HP = atoi(str[10]);
+ db->base.SP = atoi(str[11]);
+ db->base.str = atoi(str[12]);
+ db->base.agi = atoi(str[13]);
+ db->base.vit = atoi(str[14]);
+ db->base.int_= atoi(str[15]);
+ db->base.dex = atoi(str[16]);
+ db->base.luk = atoi(str[17]);
+ //Growth Min/Max HP, SP, str, agi, vit, int, dex, luk
+ db->gmin.HP = atoi(str[18]);
+ db->gmax.HP = atoi(str[19]);
+ db->gmin.SP = atoi(str[20]);
+ db->gmax.SP = atoi(str[21]);
+ db->gmin.str = atoi(str[22]);
+ db->gmax.str = atoi(str[23]);
+ db->gmin.agi = atoi(str[24]);
+ db->gmax.agi = atoi(str[25]);
+ db->gmin.vit = atoi(str[26]);
+ db->gmax.vit = atoi(str[27]);
+ db->gmin.int_= atoi(str[28]);
+ db->gmax.int_= atoi(str[29]);
+ db->gmin.dex = atoi(str[30]);
+ db->gmax.dex = atoi(str[31]);
+ db->gmin.luk = atoi(str[32]);
+ db->gmax.luk = atoi(str[33]);
+ //Evolution Min/Max HP, SP, str, agi, vit, int, dex, luk
+ db->emin.HP = atoi(str[34]);
+ db->emax.HP = atoi(str[35]);
+ db->emin.SP = atoi(str[36]);
+ db->emax.SP = atoi(str[37]);
+ db->emin.str = atoi(str[38]);
+ db->emax.str = atoi(str[39]);
+ db->emin.agi = atoi(str[40]);
+ db->emax.agi = atoi(str[41]);
+ db->emin.vit = atoi(str[42]);
+ db->emax.vit = atoi(str[43]);
+ db->emin.int_= atoi(str[44]);
+ db->emax.int_= atoi(str[45]);
+ db->emin.dex = atoi(str[46]);
+ db->emax.dex = atoi(str[47]);
+ db->emin.luk = atoi(str[48]);
+ db->emax.luk = atoi(str[49]);
+
+ //Check that the min/max values really are below the other one.
+ if(db->gmin.HP > db->gmax.HP)
+ db->gmin.HP = db->gmax.HP;
+ if(db->gmin.SP > db->gmax.SP)
+ db->gmin.SP = db->gmax.SP;
+ if(db->gmin.str > db->gmax.str)
+ db->gmin.str = db->gmax.str;
+ if(db->gmin.agi > db->gmax.agi)
+ db->gmin.agi = db->gmax.agi;
+ if(db->gmin.vit > db->gmax.vit)
+ db->gmin.vit = db->gmax.vit;
+ if(db->gmin.int_> db->gmax.int_)
+ db->gmin.int_= db->gmax.int_;
+ if(db->gmin.dex > db->gmax.dex)
+ db->gmin.dex = db->gmax.dex;
+ if(db->gmin.luk > db->gmax.luk)
+ db->gmin.luk = db->gmax.luk;
+
+ if(db->emin.HP > db->emax.HP)
+ db->emin.HP = db->emax.HP;
+ if(db->emin.SP > db->emax.SP)
+ db->emin.SP = db->emax.SP;
+ if(db->emin.str > db->emax.str)
+ db->emin.str = db->emax.str;
+ if(db->emin.agi > db->emax.agi)
+ db->emin.agi = db->emax.agi;
+ if(db->emin.vit > db->emax.vit)
+ db->emin.vit = db->emax.vit;
+ if(db->emin.int_> db->emax.int_)
+ db->emin.int_= db->emax.int_;
+ if(db->emin.dex > db->emax.dex)
+ db->emin.dex = db->emax.dex;
+ if(db->emin.luk > db->emax.luk)
+ db->emin.luk = db->emax.luk;
+
+ return true;
}
int read_homunculusdb(void)
{
- int i;
- const char *filename[]= {"homunculus_db.txt","homunculus_db2.txt"};
+ int i;
+ const char *filename[]={"homunculus_db.txt","homunculus_db2.txt"};
- memset(homunculus_db,0,sizeof(homunculus_db));
- for (i = 0; i<ARRAYLENGTH(filename); i++) {
- char path[256];
+ memset(homunculus_db,0,sizeof(homunculus_db));
+ for(i = 0; i<ARRAYLENGTH(filename); i++)
+ {
+ char path[256];
- if (i > 0) {
- sprintf(path, "%s/%s", db_path, filename[i]);
+ if( i > 0 )
+ {
+ sprintf(path, "%s/%s", db_path, filename[i]);
- if (!exists(path)) {
- continue;
- }
- }
+ if( !exists(path) )
+ {
+ continue;
+ }
+ }
- sv_readdb(db_path, filename[i], ',', 50, 50, MAX_HOMUNCULUS_CLASS, &read_homunculusdb_sub);
- }
+ sv_readdb(db_path, filename[i], ',', 50, 50, MAX_HOMUNCULUS_CLASS, &read_homunculusdb_sub);
+ }
- return 0;
+ return 0;
}
-static bool read_homunculus_skilldb_sub(char *split[], int columns, int current)
-{
- // <hom class>,<skill id>,<max level>[,<job level>],<req id1>,<req lv1>,<req id2>,<req lv2>,<req id3>,<req lv3>,<req id4>,<req lv4>,<req id5>,<req lv5>,<intimacy lv req>
- int k, classid;
- int j;
- int minJobLevelPresent = 0;
-
- if (columns == 14)
- minJobLevelPresent = 1; // MinJobLvl has been added
-
- // check for bounds [celest]
- classid = atoi(split[0]) - HM_CLASS_BASE;
- if (classid >= MAX_HOMUNCULUS_CLASS) {
- ShowWarning("read_homunculus_skilldb: Invalud homunculus class %d.\n", atoi(split[0]));
- return false;
- }
-
- k = atoi(split[1]); //This is to avoid adding two lines for the same skill. [Skotlex]
- // Search an empty line or a line with the same skill_id (stored in j)
- ARR_FIND(0, MAX_SKILL_TREE, j, !hskill_tree[classid][j].id || hskill_tree[classid][j].id == k);
- if (j == MAX_SKILL_TREE) {
- ShowWarning("Unable to load skill %d into homunculus %d's tree. Maximum number of skills per class has been reached.\n", k, classid);
- return false;
- }
-
- hskill_tree[classid][j].id = k;
- hskill_tree[classid][j].max = atoi(split[2]);
- if (minJobLevelPresent)
- hskill_tree[classid][j].joblv = atoi(split[3]);
-
- for (k = 0; k < MAX_PC_SKILL_REQUIRE; k++) {
- hskill_tree[classid][j].need[k].id = atoi(split[3+k*2+minJobLevelPresent]);
- hskill_tree[classid][j].need[k].lv = atoi(split[3+k*2+minJobLevelPresent+1]);
- }
-
- hskill_tree[classid][j].intimacylv = atoi(split[13+minJobLevelPresent]);
-
- return true;
+static bool read_homunculus_skilldb_sub(char* split[], int columns, int current)
+{// <hom class>,<skill id>,<max level>[,<job level>],<req id1>,<req lv1>,<req id2>,<req lv2>,<req id3>,<req lv3>,<req id4>,<req lv4>,<req id5>,<req lv5>,<intimacy lv req>
+ int k, classid;
+ int j;
+ int minJobLevelPresent = 0;
+
+ if( columns == 14 )
+ minJobLevelPresent = 1; // MinJobLvl has been added
+
+ // check for bounds [celest]
+ classid = atoi(split[0]) - HM_CLASS_BASE;
+ if ( classid >= MAX_HOMUNCULUS_CLASS )
+ {
+ ShowWarning("read_homunculus_skilldb: Invalud homunculus class %d.\n", atoi(split[0]));
+ return false;
+ }
+
+ k = atoi(split[1]); //This is to avoid adding two lines for the same skill. [Skotlex]
+ // Search an empty line or a line with the same skill_id (stored in j)
+ ARR_FIND( 0, MAX_SKILL_TREE, j, !hskill_tree[classid][j].id || hskill_tree[classid][j].id == k );
+ if (j == MAX_SKILL_TREE)
+ {
+ ShowWarning("Unable to load skill %d into homunculus %d's tree. Maximum number of skills per class has been reached.\n", k, classid);
+ return false;
+ }
+
+ hskill_tree[classid][j].id = k;
+ hskill_tree[classid][j].max = atoi(split[2]);
+ if (minJobLevelPresent)
+ hskill_tree[classid][j].joblv = atoi(split[3]);
+
+ for( k = 0; k < MAX_PC_SKILL_REQUIRE; k++ )
+ {
+ hskill_tree[classid][j].need[k].id = atoi(split[3+k*2+minJobLevelPresent]);
+ hskill_tree[classid][j].need[k].lv = atoi(split[3+k*2+minJobLevelPresent+1]);
+ }
+
+ hskill_tree[classid][j].intimacylv = atoi(split[13+minJobLevelPresent]);
+
+ return true;
}
int read_homunculus_skilldb(void)
{
- memset(hskill_tree,0,sizeof(hskill_tree));
- sv_readdb(db_path, "homun_skill_tree.txt", ',', 13, 15, -1, &read_homunculus_skilldb_sub);
+ memset(hskill_tree,0,sizeof(hskill_tree));
+ sv_readdb(db_path, "homun_skill_tree.txt", ',', 13, 15, -1, &read_homunculus_skilldb_sub);
- return 0;
+ return 0;
}
void read_homunculus_expdb(void)
{
- FILE *fp;
- char line[1024];
- int i, j=0;
- char *filename[]= {
- DBPATH"exp_homun.txt",
- "exp_homun2.txt"
- };
-
- memset(hexptbl,0,sizeof(hexptbl));
- for (i=0; i<2; i++) {
- sprintf(line, "%s/%s", db_path, filename[i]);
- fp=fopen(line,"r");
- if (fp == NULL) {
- if (i != 0)
- continue;
- ShowError("can't read %s\n",line);
- return;
- }
- while (fgets(line, sizeof(line), fp) && j < MAX_LEVEL) {
- if (line[0] == '/' && line[1] == '/')
- continue;
-
- hexptbl[j] = strtoul(line, NULL, 10);
- if (!hexptbl[j++])
- break;
- }
- if (hexptbl[MAX_LEVEL - 1]) { // Last permitted level have to be 0!
- ShowWarning("read_hexptbl: Reached max level in exp_homun [%d]. Remaining lines were not read.\n ", MAX_LEVEL);
- hexptbl[MAX_LEVEL - 1] = 0;
- }
- fclose(fp);
- ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' levels in '"CL_WHITE"%s"CL_RESET"'.\n", j, filename[i]);
- }
+ FILE *fp;
+ char line[1024];
+ int i, j=0;
+ char *filename[]={
+ DBPATH"exp_homun.txt",
+ "exp_homun2.txt"};
+
+ memset(hexptbl,0,sizeof(hexptbl));
+ for(i=0; i<2; i++){
+ sprintf(line, "%s/%s", db_path, filename[i]);
+ fp=fopen(line,"r");
+ if(fp == NULL){
+ if(i != 0)
+ continue;
+ ShowError("can't read %s\n",line);
+ return;
+ }
+ while(fgets(line, sizeof(line), fp) && j < MAX_LEVEL)
+ {
+ if(line[0] == '/' && line[1] == '/')
+ continue;
+
+ hexptbl[j] = strtoul(line, NULL, 10);
+ if (!hexptbl[j++])
+ break;
+ }
+ if (hexptbl[MAX_LEVEL - 1]) // Last permitted level have to be 0!
+ {
+ ShowWarning("read_hexptbl: Reached max level in exp_homun [%d]. Remaining lines were not read.\n ", MAX_LEVEL);
+ hexptbl[MAX_LEVEL - 1] = 0;
+ }
+ fclose(fp);
+ ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' levels in '"CL_WHITE"%s"CL_RESET"'.\n", j, filename[i]);
+ }
}
void merc_reload(void)
{
- read_homunculusdb();
- read_homunculus_expdb();
+ read_homunculusdb();
+ read_homunculus_expdb();
}
void merc_skill_reload(void)
{
- read_homunculus_skilldb();
+ read_homunculus_skilldb();
}
int do_init_merc(void)
{
- int class_;
- read_homunculusdb();
- read_homunculus_expdb();
- read_homunculus_skilldb();
- // Add homunc timer function to timer func list [Toms]
- add_timer_func_list(merc_hom_hungry, "merc_hom_hungry");
-
- //Stock view data for homuncs
- memset(&hom_viewdb, 0, sizeof(hom_viewdb));
- for (class_ = 0; class_ < ARRAYLENGTH(hom_viewdb); class_++)
- hom_viewdb[class_].class_ = HM_CLASS_BASE+class_;
- return 0;
+ int class_;
+ read_homunculusdb();
+ read_homunculus_expdb();
+ read_homunculus_skilldb();
+ // Add homunc timer function to timer func list [Toms]
+ add_timer_func_list(merc_hom_hungry, "merc_hom_hungry");
+
+ //Stock view data for homuncs
+ memset(&hom_viewdb, 0, sizeof(hom_viewdb));
+ for (class_ = 0; class_ < ARRAYLENGTH(hom_viewdb); class_++)
+ hom_viewdb[class_].class_ = HM_CLASS_BASE+class_;
+ return 0;
}
int do_final_merc(void);
diff --git a/src/map/homunculus.h b/src/map/homunculus.h
index d9fbfa9cc..e46420692 100644
--- a/src/map/homunculus.h
+++ b/src/map/homunculus.h
@@ -8,57 +8,57 @@
#include "unit.h" // struct unit_data
struct h_stats {
- unsigned int HP, SP;
- unsigned short str, agi, vit, int_, dex, luk;
+ unsigned int HP, SP;
+ unsigned short str, agi, vit, int_, dex, luk;
};
struct s_homunculus_db {
- int base_class, evo_class;
- char name[NAME_LENGTH];
- struct h_stats base, gmin, gmax, emin, emax;
- int foodID ;
- int baseASPD ;
- long hungryDelay ;
- unsigned char element, race, base_size, evo_size;
+ int base_class, evo_class;
+ char name[NAME_LENGTH];
+ struct h_stats base, gmin, gmax, emin, emax;
+ int foodID ;
+ int baseASPD ;
+ long hungryDelay ;
+ unsigned char element, race, base_size, evo_size;
};
extern struct s_homunculus_db homunculus_db[MAX_HOMUNCULUS_CLASS];
enum { HOMUNCULUS_CLASS, HOMUNCULUS_FOOD };
enum {
- SP_ACK = 0x0,
- SP_INTIMATE = 0x1,
- SP_HUNGRY = 0x2,
+ SP_ACK = 0x0,
+ SP_INTIMATE = 0x1,
+ SP_HUNGRY = 0x2,
};
struct homun_data {
- struct block_list bl;
- struct unit_data ud;
- struct view_data *vd;
- struct status_data base_status, battle_status;
- struct status_change sc;
- struct regen_data regen;
- struct s_homunculus_db *homunculusDB; //[orn]
- struct s_homunculus homunculus; //[orn]
-
- struct map_session_data *master; //pointer back to its master
- int hungry_timer; //[orn]
- unsigned int exp_next;
- char blockskill[MAX_SKILL]; // [orn]
-
+ struct block_list bl;
+ struct unit_data ud;
+ struct view_data *vd;
+ struct status_data base_status, battle_status;
+ struct status_change sc;
+ struct regen_data regen;
+ struct s_homunculus_db *homunculusDB; //[orn]
+ struct s_homunculus homunculus; //[orn]
+
+ struct map_session_data *master; //pointer back to its master
+ int hungry_timer; //[orn]
+ unsigned int exp_next;
+ char blockskill[MAX_SKILL]; // [orn]
+
int spiritball; //for homun S [lighta]
};
#define MAX_HOM_SKILL_REQUIRE 5
struct homun_skill_tree_entry {
- short id;
- unsigned char max;
- unsigned char joblv;
- short intimacylv;
- struct {
- short id;
- unsigned char lv;
- } need[MAX_HOM_SKILL_REQUIRE];
+ short id;
+ unsigned char max;
+ unsigned char joblv;
+ short intimacylv;
+ struct {
+ short id;
+ unsigned char lv;
+ } need[MAX_HOM_SKILL_REQUIRE];
}; // Celest
#define HOM_EVO 0x100 //256
@@ -67,22 +67,22 @@ struct homun_skill_tree_entry {
#define HOM_REG 0x1000 //4096
enum {
- // Normal Homunculus
- MAPID_LIF = HOM_REG|0x0,
- MAPID_AMISTR,
- MAPID_FILIR,
- MAPID_VANILMIRTH,
- // Evolved Homunulus
- MAPID_LIF_E = HOM_REG|HOM_EVO|0x0,
- MAPID_AMISTR_E,
- MAPID_FILIR_E,
- MAPID_VANILMIRTH_E,
- // Homunculus S
- MAPID_EIRA = HOM_S|0x0,
- MAPID_BAYERI,
- MAPID_SERA,
- MAPID_DIETER,
- MAPID_ELANOR,
+// Normal Homunculus
+ MAPID_LIF = HOM_REG|0x0,
+ MAPID_AMISTR,
+ MAPID_FILIR,
+ MAPID_VANILMIRTH,
+// Evolved Homunulus
+ MAPID_LIF_E = HOM_REG|HOM_EVO|0x0,
+ MAPID_AMISTR_E,
+ MAPID_FILIR_E,
+ MAPID_VANILMIRTH_E,
+// Homunculus S
+ MAPID_EIRA = HOM_S|0x0,
+ MAPID_BAYERI,
+ MAPID_SERA,
+ MAPID_DIETER,
+ MAPID_ELANOR,
};
#define homdb_checkid(id) (id >= HM_CLASS_BASE && id <= HM_CLASS_MAX)
@@ -91,7 +91,7 @@ enum {
#define merc_is_hom_active(x) (x && x->homunculus.vaporize != 1 && x->battle_status.hp > 0)
int do_init_merc(void);
int merc_hom_recv_data(int account_id, struct s_homunculus *sh, int flag); //albator
-struct view_data *merc_get_hom_viewdata(int class_);
+struct view_data* merc_get_hom_viewdata(int class_);
int hom_class2mapid(int hom_class);
void merc_damage(struct homun_data *hd);
int merc_hom_dead(struct homun_data *hd);
@@ -116,13 +116,13 @@ int merc_menu(struct map_session_data *sd,int menunum);
int merc_hom_food(struct map_session_data *sd, struct homun_data *hd);
int merc_hom_hungry_timer_delete(struct homun_data *hd);
int merc_hom_change_name(struct map_session_data *sd,char *name);
-int merc_hom_change_name_ack(struct map_session_data *sd, char *name, int flag);
+int merc_hom_change_name_ack(struct map_session_data *sd, char* name, int flag);
#define merc_stop_walking(hd, type) unit_stop_walking(&(hd)->bl, type)
#define merc_stop_attack(hd) unit_stop_attack(&(hd)->bl)
-int merc_hom_increase_intimacy(struct homun_data *hd, unsigned int value);
-int merc_hom_decrease_intimacy(struct homun_data *hd, unsigned int value);
+int merc_hom_increase_intimacy(struct homun_data * hd, unsigned int value);
+int merc_hom_decrease_intimacy(struct homun_data * hd, unsigned int value);
int merc_skill_tree_get_max(int id, int b_class);
-void merc_hom_init_timers(struct homun_data *hd);
+void merc_hom_init_timers(struct homun_data * hd);
void merc_skill_reload(void);
void merc_reload(void);
diff --git a/src/map/instance.c b/src/map/instance.c
index 10d4a8d6a..f5ae125a6 100644
--- a/src/map/instance.c
+++ b/src/map/instance.c
@@ -31,17 +31,17 @@ struct s_instance instance[MAX_INSTANCE];
/// Checks whether given instance id is valid or not.
static bool instance_is_valid(int instance_id)
{
- if (instance_id < 1 || instance_id >= ARRAYLENGTH(instance)) {
- // out of range
- return false;
- }
+ if( instance_id < 1 || instance_id >= ARRAYLENGTH(instance) )
+ {// out of range
+ return false;
+ }
- if (instance[instance_id].state == INSTANCE_FREE) {
- // uninitialized/freed instance slot
- return false;
- }
+ if( instance[instance_id].state == INSTANCE_FREE )
+ {// uninitialized/freed instance slot
+ return false;
+ }
- return true;
+ return true;
}
@@ -53,42 +53,44 @@ static bool instance_is_valid(int instance_id)
*--------------------------------------*/
int instance_create(int party_id, const char *name)
{
- int i;
- struct party_data *p;
-
- if ((p = party_search(party_id)) == NULL) {
- ShowError("instance_create: party %d not found for instance '%s'.\n", party_id, name);
- return -2;
- }
-
- if (p->instance_id)
- return -4; // Party already instancing
-
- // Searching a Free Instance
- // 0 is ignored as this mean "no instance" on maps
- ARR_FIND(1, MAX_INSTANCE, i, instance[i].state == INSTANCE_FREE);
- if (i == MAX_INSTANCE) {
- ShowError("instance_create: no free instances, consider increasing MAX_INSTANCE.\n");
- return -3;
- }
-
- instance[i].state = INSTANCE_IDLE;
- instance[i].instance_id = i;
- instance[i].idle_timer = INVALID_TIMER;
- instance[i].idle_timeout = instance[i].idle_timeoutval = 0;
- instance[i].progress_timer = INVALID_TIMER;
- instance[i].progress_timeout = 0;
- instance[i].users = 0;
- instance[i].party_id = party_id;
- instance[i].vars = idb_alloc(DB_OPT_RELEASE_DATA);
-
- safestrncpy(instance[i].name, name, sizeof(instance[i].name));
- memset(instance[i].map, 0x00, sizeof(instance[i].map));
- p->instance_id = i;
-
- clif_instance(i, 1, 0); // Start instancing window
- ShowInfo("[Instance] Created: %s.\n", name);
- return i;
+ int i;
+ struct party_data* p;
+
+ if( ( p = party_search(party_id) ) == NULL )
+ {
+ ShowError("instance_create: party %d not found for instance '%s'.\n", party_id, name);
+ return -2;
+ }
+
+ if( p->instance_id )
+ return -4; // Party already instancing
+
+ // Searching a Free Instance
+ // 0 is ignored as this mean "no instance" on maps
+ ARR_FIND(1, MAX_INSTANCE, i, instance[i].state == INSTANCE_FREE);
+ if( i == MAX_INSTANCE )
+ {
+ ShowError("instance_create: no free instances, consider increasing MAX_INSTANCE.\n");
+ return -3;
+ }
+
+ instance[i].state = INSTANCE_IDLE;
+ instance[i].instance_id = i;
+ instance[i].idle_timer = INVALID_TIMER;
+ instance[i].idle_timeout = instance[i].idle_timeoutval = 0;
+ instance[i].progress_timer = INVALID_TIMER;
+ instance[i].progress_timeout = 0;
+ instance[i].users = 0;
+ instance[i].party_id = party_id;
+ instance[i].vars = idb_alloc(DB_OPT_RELEASE_DATA);
+
+ safestrncpy( instance[i].name, name, sizeof(instance[i].name) );
+ memset( instance[i].map, 0x00, sizeof(instance[i].map) );
+ p->instance_id = i;
+
+ clif_instance(i, 1, 0); // Start instancing window
+ ShowInfo("[Instance] Created: %s.\n", name);
+ return i;
}
/*--------------------------------------
@@ -96,68 +98,72 @@ int instance_create(int party_id, const char *name)
*--------------------------------------*/
int instance_add_map(const char *name, int instance_id, bool usebasename)
{
- int m = map_mapname2mapid(name), i, im = -1;
- size_t num_cell, size;
-
- if (m < 0)
- return -1; // source map not found
-
- if (!instance_is_valid(instance_id)) {
- ShowError("instance_add_map: trying to attach '%s' map to non-existing instance %d.\n", name, instance_id);
- return -1;
- }
- if (instance[instance_id].num_map >= MAX_MAP_PER_INSTANCE) {
- ShowError("instance_add_map: trying to add '%s' map to instance %d (%s) failed. Please increase MAX_MAP_PER_INSTANCE.\n", name, instance_id, instance[instance_id].name);
- return -2;
- }
- if (map[m].instance_id != 0) {
- // Source map already belong to a Instance.
- ShowError("instance_add_map: trying to instance already instanced map %s.\n", name);
- return -4;
- }
-
- ARR_FIND(instance_start, map_num, i, !map[i].name[0]); // Searching for a Free Map
- if (i < map_num) im = i; // Unused map found (old instance)
- else if (map_num - 1 >= MAX_MAP_PER_SERVER) {
- // No more free maps
- ShowError("instance_add_map: no more free space to create maps on this server.\n");
- return -5;
- } else im = map_num++; // Using next map index
-
- memcpy(&map[im], &map[m], sizeof(struct map_data)); // Copy source map
- snprintf(map[im].name, MAP_NAME_LENGTH, (usebasename ? "%.3d#%s" : "%.3d%s"), instance_id, name); // Generate Name for Instance Map
- map[im].index = mapindex_addmap(-1, map[im].name); // Add map index
-
- if (!map[im].index) {
- map[im].name[0] = '\0';
- ShowError("instance_add_map: no more free map indexes.\n");
- return -3; // No free map index
- }
-
- // Reallocate cells
- num_cell = map[im].xs * map[im].ys;
- CREATE(map[im].cell, struct mapcell, num_cell);
- memcpy(map[im].cell, map[m].cell, num_cell * sizeof(struct mapcell));
-
- size = map[im].bxs * map[im].bys * sizeof(struct block_list *);
- map[im].block = (struct block_list **)aCalloc(size, 1);
- map[im].block_mob = (struct block_list **)aCalloc(size, 1);
-
- memset(map[im].npc, 0x00, sizeof(map[i].npc));
- map[im].npc_num = 0;
-
- memset(map[im].moblist, 0x00, sizeof(map[im].moblist));
- map[im].mob_delete_timer = INVALID_TIMER;
-
- map[im].m = im;
- map[im].instance_id = instance_id;
- map[im].instance_src_map = m;
- map[m].flag.src4instance = 1; // Flag this map as a src map for instances
-
- instance[instance_id].map[instance[instance_id].num_map++] = im; // Attach to actual instance
- map_addmap2db(&map[im]);
-
- return im;
+ int m = map_mapname2mapid(name), i, im = -1;
+ size_t num_cell, size;
+
+ if( m < 0 )
+ return -1; // source map not found
+
+ if( !instance_is_valid(instance_id) )
+ {
+ ShowError("instance_add_map: trying to attach '%s' map to non-existing instance %d.\n", name, instance_id);
+ return -1;
+ }
+ if( instance[instance_id].num_map >= MAX_MAP_PER_INSTANCE )
+ {
+ ShowError("instance_add_map: trying to add '%s' map to instance %d (%s) failed. Please increase MAX_MAP_PER_INSTANCE.\n", name, instance_id, instance[instance_id].name);
+ return -2;
+ }
+ if( map[m].instance_id != 0 )
+ { // Source map already belong to a Instance.
+ ShowError("instance_add_map: trying to instance already instanced map %s.\n", name);
+ return -4;
+ }
+
+ ARR_FIND( instance_start, map_num, i, !map[i].name[0] ); // Searching for a Free Map
+ if( i < map_num ) im = i; // Unused map found (old instance)
+ else if( map_num - 1 >= MAX_MAP_PER_SERVER )
+ { // No more free maps
+ ShowError("instance_add_map: no more free space to create maps on this server.\n");
+ return -5;
+ }
+ else im = map_num++; // Using next map index
+
+ memcpy( &map[im], &map[m], sizeof(struct map_data) ); // Copy source map
+ snprintf(map[im].name, MAP_NAME_LENGTH, (usebasename ? "%.3d#%s" : "%.3d%s"), instance_id, name); // Generate Name for Instance Map
+ map[im].index = mapindex_addmap(-1, map[im].name); // Add map index
+
+ if( !map[im].index )
+ {
+ map[im].name[0] = '\0';
+ ShowError("instance_add_map: no more free map indexes.\n");
+ return -3; // No free map index
+ }
+
+ // Reallocate cells
+ num_cell = map[im].xs * map[im].ys;
+ CREATE( map[im].cell, struct mapcell, num_cell );
+ memcpy( map[im].cell, map[m].cell, num_cell * sizeof(struct mapcell) );
+
+ size = map[im].bxs * map[im].bys * sizeof(struct block_list*);
+ map[im].block = (struct block_list**)aCalloc(size, 1);
+ map[im].block_mob = (struct block_list**)aCalloc(size, 1);
+
+ memset(map[im].npc, 0x00, sizeof(map[i].npc));
+ map[im].npc_num = 0;
+
+ memset(map[im].moblist, 0x00, sizeof(map[im].moblist));
+ map[im].mob_delete_timer = INVALID_TIMER;
+
+ map[im].m = im;
+ map[im].instance_id = instance_id;
+ map[im].instance_src_map = m;
+ map[m].flag.src4instance = 1; // Flag this map as a src map for instances
+
+ instance[instance_id].map[instance[instance_id].num_map++] = im; // Attach to actual instance
+ map_addmap2db(&map[im]);
+
+ return im;
}
/*--------------------------------------
@@ -167,17 +173,19 @@ int instance_add_map(const char *name, int instance_id, bool usebasename)
*--------------------------------------*/
int instance_map2imap(int m, int instance_id)
{
- int i;
-
- if (!instance_is_valid(instance_id)) {
- return -1;
- }
-
- for (i = 0; i < instance[instance_id].num_map; i++) {
- if (instance[instance_id].map[i] && map[instance[instance_id].map[i]].instance_src_map == m)
- return instance[instance_id].map[i];
- }
- return -1;
+ int i;
+
+ if( !instance_is_valid(instance_id) )
+ {
+ return -1;
+ }
+
+ for( i = 0; i < instance[instance_id].num_map; i++ )
+ {
+ if( instance[instance_id].map[i] && map[instance[instance_id].map[i]].instance_src_map == m )
+ return instance[instance_id].map[i];
+ }
+ return -1;
}
/*--------------------------------------
@@ -187,31 +195,31 @@ int instance_map2imap(int m, int instance_id)
*--------------------------------------*/
int instance_mapid2imapid(int m, int instance_id)
{
- if (map[m].flag.src4instance == 0)
- return m; // not instances found for this map
- else if (map[m].instance_id) {
- // This map is a instance, not a src map instance
- ShowError("map_instance_mapid2imapid: already instanced (%d / %d)\n", m, instance_id);
- return -1;
- }
-
- if (!instance_is_valid(instance_id))
- return -1;
-
- return instance_map2imap(m, instance_id);
+ if( map[m].flag.src4instance == 0 )
+ return m; // not instances found for this map
+ else if( map[m].instance_id )
+ { // This map is a instance, not a src map instance
+ ShowError("map_instance_mapid2imapid: already instanced (%d / %d)\n", m, instance_id);
+ return -1;
+ }
+
+ if( !instance_is_valid(instance_id) )
+ return -1;
+
+ return instance_map2imap(m, instance_id);
}
/*--------------------------------------
* map_instance_map_npcsub
* Used on Init instance. Duplicates each script on source map
*--------------------------------------*/
-int instance_map_npcsub(struct block_list *bl, va_list args)
+int instance_map_npcsub(struct block_list* bl, va_list args)
{
- struct npc_data *nd = (struct npc_data *)bl;
- int m = va_arg(args, int); // Destination Map
+ struct npc_data* nd = (struct npc_data*)bl;
+ int m = va_arg(args, int); // Destination Map
- npc_duplicate4instance(nd, m);
- return 1;
+ npc_duplicate4instance(nd, m);
+ return 1;
}
/*--------------------------------------
@@ -219,59 +227,58 @@ int instance_map_npcsub(struct block_list *bl, va_list args)
*--------------------------------------*/
void instance_init(int instance_id)
{
- int i;
+ int i;
- if (!instance_is_valid(instance_id))
- return; // nothing to do
+ if( !instance_is_valid(instance_id) )
+ return; // nothing to do
- for (i = 0; i < instance[instance_id].num_map; i++)
- map_foreachinmap(instance_map_npcsub, map[instance[instance_id].map[i]].instance_src_map, BL_NPC, instance[instance_id].map[i]);
+ for( i = 0; i < instance[instance_id].num_map; i++ )
+ map_foreachinmap(instance_map_npcsub, map[instance[instance_id].map[i]].instance_src_map, BL_NPC, instance[instance_id].map[i]);
- instance[instance_id].state = INSTANCE_BUSY;
- ShowInfo("[Instance] Initialized %s.\n", instance[instance_id].name);
+ instance[instance_id].state = INSTANCE_BUSY;
+ ShowInfo("[Instance] Initialized %s.\n", instance[instance_id].name);
}
/*--------------------------------------
* Used on instance deleting process.
* Warps all players on each instance map to its save points.
*--------------------------------------*/
-int instance_del_load(struct map_session_data *sd, va_list args)
+int instance_del_load(struct map_session_data* sd, va_list args)
{
- int m = va_arg(args,int);
- if (!sd || sd->bl.m != m)
- return 0;
+ int m = va_arg(args,int);
+ if( !sd || sd->bl.m != m )
+ return 0;
- pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_OUTSIGHT);
- return 1;
+ pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_OUTSIGHT);
+ return 1;
}
/* for npcs behave differently when being unloaded within a instance */
-int instance_cleanup_sub(struct block_list *bl, va_list ap)
-{
- nullpo_ret(bl);
-
- switch (bl->type) {
- case BL_PC:
- map_quit((struct map_session_data *) bl);
- break;
- case BL_NPC:
- npc_unload((struct npc_data *)bl,true);
- break;
- case BL_MOB:
- unit_free(bl,CLR_OUTSIGHT);
- break;
- case BL_PET:
- //There is no need for this, the pet is removed together with the player. [Skotlex]
- break;
- case BL_ITEM:
- map_clearflooritem(bl);
- break;
- case BL_SKILL:
- skill_delunit((struct skill_unit *) bl);
- break;
- }
-
- return 1;
+int instance_cleanup_sub(struct block_list *bl, va_list ap) {
+ nullpo_ret(bl);
+
+ switch(bl->type) {
+ case BL_PC:
+ map_quit((struct map_session_data *) bl);
+ break;
+ case BL_NPC:
+ npc_unload((struct npc_data *)bl,true);
+ break;
+ case BL_MOB:
+ unit_free(bl,CLR_OUTSIGHT);
+ break;
+ case BL_PET:
+ //There is no need for this, the pet is removed together with the player. [Skotlex]
+ break;
+ case BL_ITEM:
+ map_clearflooritem(bl);
+ break;
+ case BL_SKILL:
+ skill_delunit((struct skill_unit *) bl);
+ break;
+ }
+
+ return 1;
}
/*--------------------------------------
@@ -279,43 +286,46 @@ int instance_cleanup_sub(struct block_list *bl, va_list ap)
*--------------------------------------*/
void instance_del_map(int m)
{
- int i;
- if (m <= 0 || !map[m].instance_id) {
- ShowError("Tried to remove non-existing instance map (%d)\n", m);
- return;
- }
-
- map_foreachpc(instance_del_load, m);
- map_foreachinmap(instance_cleanup_sub, m, BL_ALL);
-
- if (map[m].mob_delete_timer != INVALID_TIMER)
- delete_timer(map[m].mob_delete_timer, map_removemobs_timer);
-
- mapindex_removemap(map[m].index);
-
- // Free memory
- aFree(map[m].cell);
- aFree(map[m].block);
- aFree(map[m].block_mob);
-
- // Remove from instance
- for (i = 0; i < instance[map[m].instance_id].num_map; i++) {
- if (instance[map[m].instance_id].map[i] == m) {
- instance[map[m].instance_id].num_map--;
- for (; i < instance[map[m].instance_id].num_map; i++)
- instance[map[m].instance_id].map[i] = instance[map[m].instance_id].map[i+1];
- i = -1;
- break;
- }
- }
- if (i == instance[map[m].instance_id].num_map)
- ShowError("map_instance_del: failed to remove %s from instance list (%s): %d\n", map[m].name, instance[map[m].instance_id].name, m);
-
- map_removemapdb(&map[m]);
- memset(&map[m], 0x00, sizeof(map[0]));
-
- /* for it is default and makes it not try to delete a non-existent timer since we did not delete this entry. */
- map[m].mob_delete_timer = INVALID_TIMER;
+ int i;
+ if( m <= 0 || !map[m].instance_id )
+ {
+ ShowError("Tried to remove non-existing instance map (%d)\n", m);
+ return;
+ }
+
+ map_foreachpc(instance_del_load, m);
+ map_foreachinmap(instance_cleanup_sub, m, BL_ALL);
+
+ if( map[m].mob_delete_timer != INVALID_TIMER )
+ delete_timer(map[m].mob_delete_timer, map_removemobs_timer);
+
+ mapindex_removemap( map[m].index );
+
+ // Free memory
+ aFree(map[m].cell);
+ aFree(map[m].block);
+ aFree(map[m].block_mob);
+
+ // Remove from instance
+ for( i = 0; i < instance[map[m].instance_id].num_map; i++ )
+ {
+ if( instance[map[m].instance_id].map[i] == m )
+ {
+ instance[map[m].instance_id].num_map--;
+ for( ; i < instance[map[m].instance_id].num_map; i++ )
+ instance[map[m].instance_id].map[i] = instance[map[m].instance_id].map[i+1];
+ i = -1;
+ break;
+ }
+ }
+ if( i == instance[map[m].instance_id].num_map )
+ ShowError("map_instance_del: failed to remove %s from instance list (%s): %d\n", map[m].name, instance[map[m].instance_id].name, m);
+
+ map_removemapdb(&map[m]);
+ memset(&map[m], 0x00, sizeof(map[0]));
+
+ /* for it is default and makes it not try to delete a non-existent timer since we did not delete this entry. */
+ map[m].mob_delete_timer = INVALID_TIMER;
}
/*--------------------------------------
@@ -323,8 +333,8 @@ void instance_del_map(int m)
*--------------------------------------*/
int instance_destroy_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- instance_destroy(id);
- return 0;
+ instance_destroy(id);
+ return 0;
}
/*--------------------------------------
@@ -332,45 +342,45 @@ int instance_destroy_timer(int tid, unsigned int tick, int id, intptr_t data)
*--------------------------------------*/
void instance_destroy(int instance_id)
{
- int last = 0, type;
- struct party_data *p;
- time_t now = time(NULL);
+ int last = 0, type;
+ struct party_data *p;
+ time_t now = time(NULL);
- if (!instance_is_valid(instance_id))
- return; // nothing to do
+ if( !instance_is_valid(instance_id) )
+ return; // nothing to do
- if (instance[instance_id].progress_timeout && instance[instance_id].progress_timeout <= now)
- type = 1;
- else if (instance[instance_id].idle_timeout && instance[instance_id].idle_timeout <= now)
- type = 2;
- else
- type = 3;
+ if( instance[instance_id].progress_timeout && instance[instance_id].progress_timeout <= now )
+ type = 1;
+ else if( instance[instance_id].idle_timeout && instance[instance_id].idle_timeout <= now )
+ type = 2;
+ else
+ type = 3;
- clif_instance(instance_id, 5, type); // Report users this instance has been destroyed
+ clif_instance(instance_id, 5, type); // Report users this instance has been destroyed
- while (instance[instance_id].num_map && last != instance[instance_id].map[0]) {
- // Remove all maps from instance
- last = instance[instance_id].map[0];
- instance_del_map(instance[instance_id].map[0]);
- }
+ while( instance[instance_id].num_map && last != instance[instance_id].map[0] )
+ { // Remove all maps from instance
+ last = instance[instance_id].map[0];
+ instance_del_map( instance[instance_id].map[0] );
+ }
- if (instance[instance_id].vars)
- db_destroy(instance[instance_id].vars);
+ if( instance[instance_id].vars )
+ db_destroy(instance[instance_id].vars);
- if (instance[instance_id].progress_timer != INVALID_TIMER)
- delete_timer(instance[instance_id].progress_timer, instance_destroy_timer);
- if (instance[instance_id].idle_timer != INVALID_TIMER)
- delete_timer(instance[instance_id].idle_timer, instance_destroy_timer);
+ if( instance[instance_id].progress_timer != INVALID_TIMER )
+ delete_timer( instance[instance_id].progress_timer, instance_destroy_timer);
+ if( instance[instance_id].idle_timer != INVALID_TIMER )
+ delete_timer( instance[instance_id].idle_timer, instance_destroy_timer);
- instance[instance_id].vars = NULL;
+ instance[instance_id].vars = NULL;
- if (instance[instance_id].party_id && (p = party_search(instance[instance_id].party_id)) != NULL)
- p->instance_id = 0; // Update Party information
+ if( instance[instance_id].party_id && (p = party_search(instance[instance_id].party_id)) != NULL )
+ p->instance_id = 0; // Update Party information
- ShowInfo("[Instance] Destroyed %s.\n", instance[instance_id].name);
- memset(&instance[instance_id], 0x00, sizeof(instance[0]));
+ ShowInfo("[Instance] Destroyed %s.\n", instance[instance_id].name);
+ memset( &instance[instance_id], 0x00, sizeof(instance[0]) );
- instance[instance_id].state = INSTANCE_FREE;
+ instance[instance_id].state = INSTANCE_FREE;
}
/*--------------------------------------
@@ -378,25 +388,28 @@ void instance_destroy(int instance_id)
*--------------------------------------*/
void instance_check_idle(int instance_id)
{
- bool idle = true;
- time_t now = time(NULL);
-
- if (!instance_is_valid(instance_id) || instance[instance_id].idle_timeoutval == 0)
- return;
-
- if (instance[instance_id].users)
- idle = false;
-
- if (instance[instance_id].idle_timer != INVALID_TIMER && !idle) {
- delete_timer(instance[instance_id].idle_timer, instance_destroy_timer);
- instance[instance_id].idle_timer = INVALID_TIMER;
- instance[instance_id].idle_timeout = 0;
- clif_instance(instance_id, 3, 0); // Notify instance users normal instance expiration
- } else if (instance[instance_id].idle_timer == INVALID_TIMER && idle) {
- instance[instance_id].idle_timeout = now + instance[instance_id].idle_timeoutval;
- instance[instance_id].idle_timer = add_timer(gettick() + (unsigned int)instance[instance_id].idle_timeoutval * 1000, instance_destroy_timer, instance_id, 0);
- clif_instance(instance_id, 4, 0); // Notify instance users it will be destroyed of no user join it again in "X" time
- }
+ bool idle = true;
+ time_t now = time(NULL);
+
+ if( !instance_is_valid(instance_id) || instance[instance_id].idle_timeoutval == 0 )
+ return;
+
+ if( instance[instance_id].users )
+ idle = false;
+
+ if( instance[instance_id].idle_timer != INVALID_TIMER && !idle )
+ {
+ delete_timer(instance[instance_id].idle_timer, instance_destroy_timer);
+ instance[instance_id].idle_timer = INVALID_TIMER;
+ instance[instance_id].idle_timeout = 0;
+ clif_instance(instance_id, 3, 0); // Notify instance users normal instance expiration
+ }
+ else if( instance[instance_id].idle_timer == INVALID_TIMER && idle )
+ {
+ instance[instance_id].idle_timeout = now + instance[instance_id].idle_timeoutval;
+ instance[instance_id].idle_timer = add_timer( gettick() + (unsigned int)instance[instance_id].idle_timeoutval * 1000, instance_destroy_timer, instance_id, 0);
+ clif_instance(instance_id, 4, 0); // Notify instance users it will be destroyed of no user join it again in "X" time
+ }
}
/*--------------------------------------
@@ -404,36 +417,42 @@ void instance_check_idle(int instance_id)
*--------------------------------------*/
void instance_set_timeout(int instance_id, unsigned int progress_timeout, unsigned int idle_timeout)
{
- time_t now = time(0);
-
- if (!instance_is_valid(instance_id))
- return;
-
- if (instance[instance_id].progress_timer != INVALID_TIMER)
- delete_timer(instance[instance_id].progress_timer, instance_destroy_timer);
- if (instance[instance_id].idle_timer != INVALID_TIMER)
- delete_timer(instance[instance_id].idle_timer, instance_destroy_timer);
-
- if (progress_timeout) {
- instance[instance_id].progress_timeout = now + progress_timeout;
- instance[instance_id].progress_timer = add_timer(gettick() + progress_timeout * 1000, instance_destroy_timer, instance_id, 0);
- } else {
- instance[instance_id].progress_timeout = 0;
- instance[instance_id].progress_timer = INVALID_TIMER;
- }
-
- if (idle_timeout) {
- instance[instance_id].idle_timeoutval = idle_timeout;
- instance[instance_id].idle_timer = INVALID_TIMER;
- instance_check_idle(instance_id);
- } else {
- instance[instance_id].idle_timeoutval = 0;
- instance[instance_id].idle_timeout = 0;
- instance[instance_id].idle_timer = INVALID_TIMER;
- }
-
- if (instance[instance_id].idle_timer == INVALID_TIMER && instance[instance_id].progress_timer != INVALID_TIMER)
- clif_instance(instance_id, 3, 0);
+ time_t now = time(0);
+
+ if( !instance_is_valid(instance_id) )
+ return;
+
+ if( instance[instance_id].progress_timer != INVALID_TIMER )
+ delete_timer( instance[instance_id].progress_timer, instance_destroy_timer);
+ if( instance[instance_id].idle_timer != INVALID_TIMER )
+ delete_timer( instance[instance_id].idle_timer, instance_destroy_timer);
+
+ if( progress_timeout )
+ {
+ instance[instance_id].progress_timeout = now + progress_timeout;
+ instance[instance_id].progress_timer = add_timer( gettick() + progress_timeout * 1000, instance_destroy_timer, instance_id, 0);
+ }
+ else
+ {
+ instance[instance_id].progress_timeout = 0;
+ instance[instance_id].progress_timer = INVALID_TIMER;
+ }
+
+ if( idle_timeout )
+ {
+ instance[instance_id].idle_timeoutval = idle_timeout;
+ instance[instance_id].idle_timer = INVALID_TIMER;
+ instance_check_idle(instance_id);
+ }
+ else
+ {
+ instance[instance_id].idle_timeoutval = 0;
+ instance[instance_id].idle_timeout = 0;
+ instance[instance_id].idle_timer = INVALID_TIMER;
+ }
+
+ if( instance[instance_id].idle_timer == INVALID_TIMER && instance[instance_id].progress_timer != INVALID_TIMER )
+ clif_instance(instance_id, 3, 0);
}
/*--------------------------------------
@@ -441,28 +460,28 @@ void instance_set_timeout(int instance_id, unsigned int progress_timeout, unsign
*--------------------------------------*/
void instance_check_kick(struct map_session_data *sd)
{
- int m = sd->bl.m;
-
- clif_instance_leave(sd->fd);
- if (map[m].instance_id) {
- // User was on the instance map
- if (map[m].save.map)
- pc_setpos(sd, map[m].save.map, map[m].save.x, map[m].save.y, CLR_TELEPORT);
- else
- pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT);
- }
+ int m = sd->bl.m;
+
+ clif_instance_leave(sd->fd);
+ if( map[m].instance_id )
+ { // User was on the instance map
+ if( map[m].save.map )
+ pc_setpos(sd, map[m].save.map, map[m].save.x, map[m].save.y, CLR_TELEPORT);
+ else
+ pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT);
+ }
}
void do_final_instance(void)
{
- int i;
+ int i;
- for (i = 1; i < MAX_INSTANCE; i++)
- instance_destroy(i);
+ for( i = 1; i < MAX_INSTANCE; i++ )
+ instance_destroy(i);
}
void do_init_instance(void)
{
- memset(instance, 0x00, sizeof(instance));
- add_timer_func_list(instance_destroy_timer, "instance_destroy_timer");
+ memset(instance, 0x00, sizeof(instance));
+ add_timer_func_list(instance_destroy_timer, "instance_destroy_timer");
}
diff --git a/src/map/instance.h b/src/map/instance.h
index cfb1d0b77..f8f7387f7 100644
--- a/src/map/instance.h
+++ b/src/map/instance.h
@@ -12,22 +12,22 @@
typedef enum instance_state { INSTANCE_FREE, INSTANCE_IDLE, INSTANCE_BUSY } instance_state;
struct s_instance {
- char name[INSTANCE_NAME_LENGTH]; // Instance Name - required for clif functions.
- instance_state state;
- short instance_id;
- int party_id;
-
- int map[MAX_MAP_PER_INSTANCE];
- int num_map;
- int users;
-
- struct DBMap *vars; // Instance Variable for scripts
-
- int progress_timer;
- time_t progress_timeout;
-
- int idle_timer;
- time_t idle_timeout, idle_timeoutval;
+ char name[INSTANCE_NAME_LENGTH]; // Instance Name - required for clif functions.
+ instance_state state;
+ short instance_id;
+ int party_id;
+
+ int map[MAX_MAP_PER_INSTANCE];
+ int num_map;
+ int users;
+
+ struct DBMap* vars; // Instance Variable for scripts
+
+ int progress_timer;
+ time_t progress_timeout;
+
+ int idle_timer;
+ time_t idle_timeout, idle_timeoutval;
};
extern int instance_start;
diff --git a/src/map/intif.c b/src/map/intif.c
index 8c66db6be..3bbb92216 100644
--- a/src/map/intif.c
+++ b/src/map/intif.c
@@ -33,735 +33,735 @@
#include <string.h>
-static const int packet_len_table[]= {
- -1,-1,27,-1, -1, 0,37,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3800-0x380f
- 0, 0, 0, 0, 0, 0, 0, 0, -1,11, 0, 0, 0, 0, 0, 0, //0x3810
- 39,-1,15,15, 14,19, 7,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3820
- 10,-1,15, 0, 79,19, 7,-1, 0,-1,-1,-1, 14,67,186,-1, //0x3830
- -1, 0, 0,14, 0, 0, 0, 0, -1,74,-1,11, 11,-1, 0, 0, //0x3840
- -1,-1, 7, 7, 7,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3850 Auctions [Zephyrus]
- -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3860 Quests [Kevin] [Inkfish]
- -1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 3, 3, 0, //0x3870 Mercenaries [Zephyrus] / Elemental [pakpil]
- 11,-1, 7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3880
- -1,-1, 7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3890 Homunculus [albator]
+static const int packet_len_table[]={
+ -1,-1,27,-1, -1, 0,37,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3800-0x380f
+ 0, 0, 0, 0, 0, 0, 0, 0, -1,11, 0, 0, 0, 0, 0, 0, //0x3810
+ 39,-1,15,15, 14,19, 7,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3820
+ 10,-1,15, 0, 79,19, 7,-1, 0,-1,-1,-1, 14,67,186,-1, //0x3830
+ -1, 0, 0,14, 0, 0, 0, 0, -1,74,-1,11, 11,-1, 0, 0, //0x3840
+ -1,-1, 7, 7, 7,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3850 Auctions [Zephyrus]
+ -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3860 Quests [Kevin] [Inkfish]
+ -1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 3, 3, 0, //0x3870 Mercenaries [Zephyrus] / Elemental [pakpil]
+ 11,-1, 7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3880
+ -1,-1, 7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3890 Homunculus [albator]
};
extern int char_fd; // inter server Fd used for char_fd
-#define inter_fd char_fd // alias
+#define inter_fd char_fd // alias
//-----------------------------------------------------------------
// Send to inter server
int CheckForCharServer(void)
{
- return ((char_fd <= 0) || session[char_fd] == NULL || session[char_fd]->wdata == NULL);
+ return ((char_fd <= 0) || 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;
- WFIFOHEAD(inter_fd, 24 + NAME_LENGTH);
- WFIFOW(inter_fd,0) = 0x3080;
- WFIFOL(inter_fd,2) = account_id;
- WFIFOL(inter_fd,6) = char_id;
- WFIFOW(inter_fd,10) = pet_class;
- WFIFOW(inter_fd,12) = pet_lv;
- WFIFOW(inter_fd,14) = pet_egg_id;
- WFIFOW(inter_fd,16) = pet_equip;
- WFIFOW(inter_fd,18) = intimate;
- WFIFOW(inter_fd,20) = hungry;
- WFIFOB(inter_fd,22) = rename_flag;
- WFIFOB(inter_fd,23) = incuvate;
- memcpy(WFIFOP(inter_fd,24),pet_name,NAME_LENGTH);
- WFIFOSET(inter_fd,24+NAME_LENGTH);
-
- return 0;
+ short pet_equip,short intimate,short hungry,char rename_flag,char incuvate,char *pet_name)
+{
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd, 24 + NAME_LENGTH);
+ WFIFOW(inter_fd,0) = 0x3080;
+ WFIFOL(inter_fd,2) = account_id;
+ WFIFOL(inter_fd,6) = char_id;
+ WFIFOW(inter_fd,10) = pet_class;
+ WFIFOW(inter_fd,12) = pet_lv;
+ WFIFOW(inter_fd,14) = pet_egg_id;
+ WFIFOW(inter_fd,16) = pet_equip;
+ WFIFOW(inter_fd,18) = intimate;
+ WFIFOW(inter_fd,20) = hungry;
+ WFIFOB(inter_fd,22) = rename_flag;
+ WFIFOB(inter_fd,23) = incuvate;
+ memcpy(WFIFOP(inter_fd,24),pet_name,NAME_LENGTH);
+ WFIFOSET(inter_fd,24+NAME_LENGTH);
+
+ return 0;
}
int intif_request_petdata(int account_id,int char_id,int pet_id)
{
- if (CheckForCharServer())
- return 0;
- WFIFOHEAD(inter_fd, 14);
- WFIFOW(inter_fd,0) = 0x3081;
- WFIFOL(inter_fd,2) = account_id;
- WFIFOL(inter_fd,6) = char_id;
- WFIFOL(inter_fd,10) = pet_id;
- WFIFOSET(inter_fd,14);
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd, 14);
+ WFIFOW(inter_fd,0) = 0x3081;
+ WFIFOL(inter_fd,2) = account_id;
+ WFIFOL(inter_fd,6) = char_id;
+ WFIFOL(inter_fd,10) = pet_id;
+ WFIFOSET(inter_fd,14);
- return 0;
+ return 0;
}
int intif_save_petdata(int account_id,struct s_pet *p)
{
- if (CheckForCharServer())
- return 0;
- WFIFOHEAD(inter_fd, sizeof(struct s_pet) + 8);
- WFIFOW(inter_fd,0) = 0x3082;
- WFIFOW(inter_fd,2) = sizeof(struct s_pet) + 8;
- WFIFOL(inter_fd,4) = account_id;
- memcpy(WFIFOP(inter_fd,8),p,sizeof(struct s_pet));
- WFIFOSET(inter_fd,WFIFOW(inter_fd,2));
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd, sizeof(struct s_pet) + 8);
+ WFIFOW(inter_fd,0) = 0x3082;
+ WFIFOW(inter_fd,2) = sizeof(struct s_pet) + 8;
+ WFIFOL(inter_fd,4) = account_id;
+ memcpy(WFIFOP(inter_fd,8),p,sizeof(struct s_pet));
+ WFIFOSET(inter_fd,WFIFOW(inter_fd,2));
- return 0;
+ return 0;
}
int intif_delete_petdata(int pet_id)
{
- if (CheckForCharServer())
- return 0;
- WFIFOHEAD(inter_fd,6);
- WFIFOW(inter_fd,0) = 0x3083;
- WFIFOL(inter_fd,2) = pet_id;
- WFIFOSET(inter_fd,6);
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd,6);
+ WFIFOW(inter_fd,0) = 0x3083;
+ WFIFOL(inter_fd,2) = pet_id;
+ WFIFOSET(inter_fd,6);
- return 1;
+ return 1;
}
int intif_rename(struct map_session_data *sd, int type, char *name)
{
- if (CheckForCharServer())
- return 1;
+ if (CheckForCharServer())
+ return 1;
- WFIFOHEAD(inter_fd,NAME_LENGTH+12);
- WFIFOW(inter_fd,0) = 0x3006;
- WFIFOL(inter_fd,2) = sd->status.account_id;
- WFIFOL(inter_fd,6) = sd->status.char_id;
- WFIFOB(inter_fd,10) = type; //Type: 0 - PC, 1 - PET, 2 - HOM
- memcpy(WFIFOP(inter_fd,11),name, NAME_LENGTH);
- WFIFOSET(inter_fd,NAME_LENGTH+12);
- return 0;
+ WFIFOHEAD(inter_fd,NAME_LENGTH+12);
+ WFIFOW(inter_fd,0) = 0x3006;
+ WFIFOL(inter_fd,2) = sd->status.account_id;
+ WFIFOL(inter_fd,6) = sd->status.char_id;
+ WFIFOB(inter_fd,10) = type; //Type: 0 - PC, 1 - PET, 2 - HOM
+ memcpy(WFIFOP(inter_fd,11),name, NAME_LENGTH);
+ WFIFOSET(inter_fd,NAME_LENGTH+12);
+ return 0;
}
// GM Send a message
-int intif_broadcast(const char *mes, int len, int type)
-{
- int lp = type ? 4 : 0;
-
- // Send to the local players
- clif_broadcast(NULL, mes, len, type, ALL_CLIENT);
-
- if (CheckForCharServer())
- return 0;
-
- if (other_mapserver_count < 1)
- return 0; //No need to send.
-
- WFIFOHEAD(inter_fd, 16 + lp + len);
- WFIFOW(inter_fd,0) = 0x3000;
- WFIFOW(inter_fd,2) = 16 + lp + len;
- WFIFOL(inter_fd,4) = 0xFF000000; // 0xFF000000 color signals standard broadcast
- WFIFOW(inter_fd,8) = 0; // fontType not used with standard broadcast
- WFIFOW(inter_fd,10) = 0; // fontSize not used with standard broadcast
- WFIFOW(inter_fd,12) = 0; // fontAlign not used with standard broadcast
- WFIFOW(inter_fd,14) = 0; // fontY not used with standard broadcast
- if (type == 0x10) // bc_blue
- WFIFOL(inter_fd,16) = 0x65756c62; //If there's "blue" at the beginning of the message, game client will display it in blue instead of yellow.
- else if (type == 0x20) // bc_woe
- WFIFOL(inter_fd,16) = 0x73737373; //If there's "ssss", game client will recognize message as 'WoE broadcast'.
- memcpy(WFIFOP(inter_fd,16 + lp), mes, len);
- WFIFOSET(inter_fd, WFIFOW(inter_fd,2));
- return 0;
-}
-
-int intif_broadcast2(const char *mes, int len, unsigned long fontColor, short fontType, short fontSize, short fontAlign, short fontY)
-{
- // Send to the local players
- if (fontColor == 0xFE000000) // This is main chat message [LuzZza]
- clif_MainChatMessage(mes);
- else
- clif_broadcast2(NULL, mes, len, fontColor, fontType, fontSize, fontAlign, fontY, ALL_CLIENT);
-
- if (CheckForCharServer())
- return 0;
-
- if (other_mapserver_count < 1)
- return 0; //No need to send.
-
- WFIFOHEAD(inter_fd, 16 + len);
- WFIFOW(inter_fd,0) = 0x3000;
- WFIFOW(inter_fd,2) = 16 + len;
- WFIFOL(inter_fd,4) = fontColor;
- WFIFOW(inter_fd,8) = fontType;
- WFIFOW(inter_fd,10) = fontSize;
- WFIFOW(inter_fd,12) = fontAlign;
- WFIFOW(inter_fd,14) = fontY;
- memcpy(WFIFOP(inter_fd,16), mes, len);
- WFIFOSET(inter_fd, WFIFOW(inter_fd,2));
- return 0;
+int intif_broadcast(const char* mes, int len, int type)
+{
+ int lp = type ? 4 : 0;
+
+ // Send to the local players
+ clif_broadcast(NULL, mes, len, type, ALL_CLIENT);
+
+ if (CheckForCharServer())
+ return 0;
+
+ if (other_mapserver_count < 1)
+ return 0; //No need to send.
+
+ WFIFOHEAD(inter_fd, 16 + lp + len);
+ WFIFOW(inter_fd,0) = 0x3000;
+ WFIFOW(inter_fd,2) = 16 + lp + len;
+ WFIFOL(inter_fd,4) = 0xFF000000; // 0xFF000000 color signals standard broadcast
+ WFIFOW(inter_fd,8) = 0; // fontType not used with standard broadcast
+ WFIFOW(inter_fd,10) = 0; // fontSize not used with standard broadcast
+ WFIFOW(inter_fd,12) = 0; // fontAlign not used with standard broadcast
+ WFIFOW(inter_fd,14) = 0; // fontY not used with standard broadcast
+ if (type == 0x10) // bc_blue
+ WFIFOL(inter_fd,16) = 0x65756c62; //If there's "blue" at the beginning of the message, game client will display it in blue instead of yellow.
+ else if (type == 0x20) // bc_woe
+ WFIFOL(inter_fd,16) = 0x73737373; //If there's "ssss", game client will recognize message as 'WoE broadcast'.
+ memcpy(WFIFOP(inter_fd,16 + lp), mes, len);
+ WFIFOSET(inter_fd, WFIFOW(inter_fd,2));
+ return 0;
+}
+
+int intif_broadcast2(const char* mes, int len, unsigned long fontColor, short fontType, short fontSize, short fontAlign, short fontY)
+{
+ // Send to the local players
+ if (fontColor == 0xFE000000) // This is main chat message [LuzZza]
+ clif_MainChatMessage(mes);
+ else
+ clif_broadcast2(NULL, mes, len, fontColor, fontType, fontSize, fontAlign, fontY, ALL_CLIENT);
+
+ if (CheckForCharServer())
+ return 0;
+
+ if (other_mapserver_count < 1)
+ return 0; //No need to send.
+
+ WFIFOHEAD(inter_fd, 16 + len);
+ WFIFOW(inter_fd,0) = 0x3000;
+ WFIFOW(inter_fd,2) = 16 + len;
+ WFIFOL(inter_fd,4) = fontColor;
+ WFIFOW(inter_fd,8) = fontType;
+ WFIFOW(inter_fd,10) = fontSize;
+ WFIFOW(inter_fd,12) = fontAlign;
+ WFIFOW(inter_fd,14) = fontY;
+ memcpy(WFIFOP(inter_fd,16), mes, len);
+ WFIFOSET(inter_fd, WFIFOW(inter_fd,2));
+ return 0;
}
/// send a message using the main chat system
/// <sd> the source of message
/// <message> the message that was sent
-int intif_main_message(struct map_session_data *sd, const char *message)
+int intif_main_message(struct map_session_data* sd, const char* message)
{
- char output[256];
+ char output[256];
- nullpo_ret(sd);
+ nullpo_ret(sd);
- // format the message for main broadcasting
- snprintf(output, sizeof(output), msg_txt(386), sd->status.name, message);
+ // format the message for main broadcasting
+ snprintf( output, sizeof(output), msg_txt(386), sd->status.name, message );
- // send the message using the inter-server broadcast service
- intif_broadcast2(output, strlen(output) + 1, 0xFE000000, 0, 0, 0, 0);
+ // send the message using the inter-server broadcast service
+ intif_broadcast2( output, strlen(output) + 1, 0xFE000000, 0, 0, 0, 0 );
- // log the chat message
- log_chat(LOG_CHAT_MAINCHAT, 0, sd->status.char_id, sd->status.account_id, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y, NULL, message);
+ // log the chat message
+ log_chat( LOG_CHAT_MAINCHAT, 0, sd->status.char_id, sd->status.account_id, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y, NULL, message );
- return 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_ret(sd);
- if (CheckForCharServer())
- return 0;
+ nullpo_ret(sd);
+ if (CheckForCharServer())
+ return 0;
- if (other_mapserver_count < 1) {
- //Character not found.
- clif_wis_end(sd->fd, 1);
- return 0;
- }
+ if (other_mapserver_count < 1)
+ { //Character not found.
+ clif_wis_end(sd->fd, 1);
+ return 0;
+ }
- WFIFOHEAD(inter_fd,mes_len + 52);
- WFIFOW(inter_fd,0) = 0x3001;
- WFIFOW(inter_fd,2) = mes_len + 52;
- memcpy(WFIFOP(inter_fd,4), sd->status.name, NAME_LENGTH);
- memcpy(WFIFOP(inter_fd,4+NAME_LENGTH), nick, NAME_LENGTH);
- memcpy(WFIFOP(inter_fd,4+2*NAME_LENGTH), mes, mes_len);
- WFIFOSET(inter_fd, WFIFOW(inter_fd,2));
+ WFIFOHEAD(inter_fd,mes_len + 52);
+ WFIFOW(inter_fd,0) = 0x3001;
+ WFIFOW(inter_fd,2) = mes_len + 52;
+ memcpy(WFIFOP(inter_fd,4), sd->status.name, NAME_LENGTH);
+ memcpy(WFIFOP(inter_fd,4+NAME_LENGTH), nick, NAME_LENGTH);
+ memcpy(WFIFOP(inter_fd,4+2*NAME_LENGTH), mes, mes_len);
+ WFIFOSET(inter_fd, WFIFOW(inter_fd,2));
- if (battle_config.etc_log)
- ShowInfo("intif_wis_message from %s to %s (message: '%s')\n", sd->status.name, nick, mes);
+ if (battle_config.etc_log)
+ ShowInfo("intif_wis_message from %s to %s (message: '%s')\n", sd->status.name, nick, mes);
- return 0;
+ return 0;
}
// The reply of Wisp/page
int intif_wis_replay(int id, int flag)
{
- if (CheckForCharServer())
- return 0;
- WFIFOHEAD(inter_fd,7);
- 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
- WFIFOSET(inter_fd,7);
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd,7);
+ 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
+ WFIFOSET(inter_fd,7);
- if (battle_config.etc_log)
- ShowInfo("intif_wis_replay: id: %d, flag:%d\n", id, flag);
+ if (battle_config.etc_log)
+ ShowInfo("intif_wis_replay: id: %d, flag:%d\n", id, flag);
- return 0;
+ return 0;
}
// The transmission of GM only Wisp/Page from server to inter-server
int intif_wis_message_to_gm(char *wisp_name, int permission, char *mes)
{
- int mes_len;
- if (CheckForCharServer())
- return 0;
- mes_len = strlen(mes) + 1; // + null
- WFIFOHEAD(inter_fd, mes_len + 32);
- WFIFOW(inter_fd,0) = 0x3003;
- WFIFOW(inter_fd,2) = mes_len + 32;
- memcpy(WFIFOP(inter_fd,4), wisp_name, NAME_LENGTH);
- WFIFOL(inter_fd,4+NAME_LENGTH) = permission;
- memcpy(WFIFOP(inter_fd,8+NAME_LENGTH), mes, mes_len);
- WFIFOSET(inter_fd, WFIFOW(inter_fd,2));
+ int mes_len;
+ if (CheckForCharServer())
+ return 0;
+ mes_len = strlen(mes) + 1; // + null
+ WFIFOHEAD(inter_fd, mes_len + 32);
+ WFIFOW(inter_fd,0) = 0x3003;
+ WFIFOW(inter_fd,2) = mes_len + 32;
+ memcpy(WFIFOP(inter_fd,4), wisp_name, NAME_LENGTH);
+ WFIFOL(inter_fd,4+NAME_LENGTH) = permission;
+ memcpy(WFIFOP(inter_fd,8+NAME_LENGTH), mes, mes_len);
+ WFIFOSET(inter_fd, WFIFOW(inter_fd,2));
- if (battle_config.etc_log)
- ShowNotice("intif_wis_message_to_gm: from: '%s', required permission: %d, message: '%s'.\n", wisp_name, permission, mes);
+ if (battle_config.etc_log)
+ ShowNotice("intif_wis_message_to_gm: from: '%s', required permission: %d, message: '%s'.\n", wisp_name, permission, mes);
- return 0;
+ return 0;
}
-int intif_regtostr(char *str, struct global_reg *reg, int qty)
+int intif_regtostr(char* str, struct global_reg *reg, int qty)
{
- int len =0, i;
+ int len =0, i;
- for (i = 0; i < qty; i++) {
- len+= sprintf(str+len, "%s", reg[i].str)+1; //We add 1 to consider the '\0' in place.
- len+= sprintf(str+len, "%s", reg[i].value)+1;
- }
- return len;
+ for (i = 0; i < qty; i++) {
+ len+= sprintf(str+len, "%s", reg[i].str)+1; //We add 1 to consider the '\0' in place.
+ len+= sprintf(str+len, "%s", reg[i].value)+1;
+ }
+ return len;
}
//Request for saving registry values.
int intif_saveregistry(struct map_session_data *sd, int type)
{
- struct global_reg *reg;
- int count;
- int i, p;
-
- if (CheckForCharServer())
- return -1;
-
- switch (type) {
- case 3: //Character reg
- reg = sd->save_reg.global;
- count = sd->save_reg.global_num;
- sd->state.reg_dirty &= ~0x4;
- break;
- case 2: //Account reg
- reg = sd->save_reg.account;
- count = sd->save_reg.account_num;
- sd->state.reg_dirty &= ~0x2;
- break;
- case 1: //Account2 reg
- reg = sd->save_reg.account2;
- count = sd->save_reg.account2_num;
- sd->state.reg_dirty &= ~0x1;
- break;
- default: //Broken code?
- ShowError("intif_saveregistry: Invalid type %d\n", type);
- return -1;
- }
- WFIFOHEAD(inter_fd, 288 * MAX_REG_NUM+13);
- WFIFOW(inter_fd,0)=0x3004;
- WFIFOL(inter_fd,4)=sd->status.account_id;
- WFIFOL(inter_fd,8)=sd->status.char_id;
- WFIFOB(inter_fd,12)=type;
- for (p = 13, i = 0; i < count; i++) {
- if (reg[i].str[0] != '\0' && reg[i].value[0] != '\0') {
- p+= sprintf((char *)WFIFOP(inter_fd,p), "%s", reg[i].str)+1; //We add 1 to consider the '\0' in place.
- p+= sprintf((char *)WFIFOP(inter_fd,p), "%s", reg[i].value)+1;
- }
- }
- WFIFOW(inter_fd,2)=p;
- WFIFOSET(inter_fd,WFIFOW(inter_fd,2));
- return 0;
+ struct global_reg *reg;
+ int count;
+ int i, p;
+
+ if (CheckForCharServer())
+ return -1;
+
+ switch (type) {
+ case 3: //Character reg
+ reg = sd->save_reg.global;
+ count = sd->save_reg.global_num;
+ sd->state.reg_dirty &= ~0x4;
+ break;
+ case 2: //Account reg
+ reg = sd->save_reg.account;
+ count = sd->save_reg.account_num;
+ sd->state.reg_dirty &= ~0x2;
+ break;
+ case 1: //Account2 reg
+ reg = sd->save_reg.account2;
+ count = sd->save_reg.account2_num;
+ sd->state.reg_dirty &= ~0x1;
+ break;
+ default: //Broken code?
+ ShowError("intif_saveregistry: Invalid type %d\n", type);
+ return -1;
+ }
+ WFIFOHEAD(inter_fd, 288 * MAX_REG_NUM+13);
+ WFIFOW(inter_fd,0)=0x3004;
+ WFIFOL(inter_fd,4)=sd->status.account_id;
+ WFIFOL(inter_fd,8)=sd->status.char_id;
+ WFIFOB(inter_fd,12)=type;
+ for( p = 13, i = 0; i < count; i++ ) {
+ if (reg[i].str[0] != '\0' && reg[i].value[0] != '\0') {
+ p+= sprintf((char*)WFIFOP(inter_fd,p), "%s", reg[i].str)+1; //We add 1 to consider the '\0' in place.
+ p+= sprintf((char*)WFIFOP(inter_fd,p), "%s", reg[i].value)+1;
+ }
+ }
+ WFIFOW(inter_fd,2)=p;
+ WFIFOSET(inter_fd,WFIFOW(inter_fd,2));
+ return 0;
}
//Request the registries for this player.
int intif_request_registry(struct map_session_data *sd, int flag)
{
- nullpo_ret(sd);
+ nullpo_ret(sd);
- sd->save_reg.account2_num = -1;
- sd->save_reg.account_num = -1;
- sd->save_reg.global_num = -1;
+ sd->save_reg.account2_num = -1;
+ sd->save_reg.account_num = -1;
+ sd->save_reg.global_num = -1;
- if (CheckForCharServer())
- return 0;
+ if (CheckForCharServer())
+ return 0;
- WFIFOHEAD(inter_fd,6);
- WFIFOW(inter_fd,0) = 0x3005;
- WFIFOL(inter_fd,2) = sd->status.account_id;
- WFIFOL(inter_fd,6) = sd->status.char_id;
- WFIFOB(inter_fd,10) = (flag&1?1:0); //Request Acc Reg 2
- WFIFOB(inter_fd,11) = (flag&2?1:0); //Request Acc Reg
- WFIFOB(inter_fd,12) = (flag&4?1:0); //Request Char Reg
- WFIFOSET(inter_fd,13);
+ WFIFOHEAD(inter_fd,6);
+ WFIFOW(inter_fd,0) = 0x3005;
+ WFIFOL(inter_fd,2) = sd->status.account_id;
+ WFIFOL(inter_fd,6) = sd->status.char_id;
+ WFIFOB(inter_fd,10) = (flag&1?1:0); //Request Acc Reg 2
+ WFIFOB(inter_fd,11) = (flag&2?1:0); //Request Acc Reg
+ WFIFOB(inter_fd,12) = (flag&4?1:0); //Request Char Reg
+ WFIFOSET(inter_fd,13);
- return 0;
+ return 0;
}
int intif_request_guild_storage(int account_id,int guild_id)
{
- if (CheckForCharServer())
- return 0;
- WFIFOHEAD(inter_fd,10);
- WFIFOW(inter_fd,0) = 0x3018;
- WFIFOL(inter_fd,2) = account_id;
- WFIFOL(inter_fd,6) = guild_id;
- WFIFOSET(inter_fd,10);
- return 0;
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd,10);
+ WFIFOW(inter_fd,0) = 0x3018;
+ WFIFOL(inter_fd,2) = account_id;
+ WFIFOL(inter_fd,6) = guild_id;
+ WFIFOSET(inter_fd,10);
+ return 0;
}
int intif_send_guild_storage(int account_id,struct guild_storage *gstor)
{
- if (CheckForCharServer())
- return 0;
- WFIFOHEAD(inter_fd,sizeof(struct guild_storage)+12);
- WFIFOW(inter_fd,0) = 0x3019;
- WFIFOW(inter_fd,2) = (unsigned short)sizeof(struct guild_storage)+12;
- WFIFOL(inter_fd,4) = account_id;
- WFIFOL(inter_fd,8) = gstor->guild_id;
- memcpy(WFIFOP(inter_fd,12),gstor, sizeof(struct guild_storage));
- WFIFOSET(inter_fd,WFIFOW(inter_fd,2));
- return 0;
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd,sizeof(struct guild_storage)+12);
+ WFIFOW(inter_fd,0) = 0x3019;
+ WFIFOW(inter_fd,2) = (unsigned short)sizeof(struct guild_storage)+12;
+ WFIFOL(inter_fd,4) = account_id;
+ WFIFOL(inter_fd,8) = gstor->guild_id;
+ memcpy( WFIFOP(inter_fd,12),gstor, sizeof(struct guild_storage) );
+ WFIFOSET(inter_fd,WFIFOW(inter_fd,2));
+ return 0;
}
// Party creation request
int intif_create_party(struct party_member *member,char *name,int item,int item2)
{
- if (CheckForCharServer())
- return 0;
- nullpo_ret(member);
+ if (CheckForCharServer())
+ return 0;
+ nullpo_ret(member);
- WFIFOHEAD(inter_fd,64);
- WFIFOW(inter_fd,0) = 0x3020;
- WFIFOW(inter_fd,2) = 30+sizeof(struct party_member);
- memcpy(WFIFOP(inter_fd,4),name, NAME_LENGTH);
- WFIFOB(inter_fd,28)= item;
- WFIFOB(inter_fd,29)= item2;
- memcpy(WFIFOP(inter_fd,30), member, sizeof(struct party_member));
- WFIFOSET(inter_fd,WFIFOW(inter_fd, 2));
- return 0;
+ WFIFOHEAD(inter_fd,64);
+ WFIFOW(inter_fd,0) = 0x3020;
+ WFIFOW(inter_fd,2) = 30+sizeof(struct party_member);
+ memcpy(WFIFOP(inter_fd,4),name, NAME_LENGTH);
+ WFIFOB(inter_fd,28)= item;
+ WFIFOB(inter_fd,29)= item2;
+ memcpy(WFIFOP(inter_fd,30), member, sizeof(struct party_member));
+ WFIFOSET(inter_fd,WFIFOW(inter_fd, 2));
+ return 0;
}
// Party information request
int intif_request_partyinfo(int party_id, int char_id)
{
- if (CheckForCharServer())
- return 0;
- WFIFOHEAD(inter_fd,10);
- WFIFOW(inter_fd,0) = 0x3021;
- WFIFOL(inter_fd,2) = party_id;
- WFIFOL(inter_fd,6) = char_id;
- WFIFOSET(inter_fd,10);
- return 0;
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd,10);
+ WFIFOW(inter_fd,0) = 0x3021;
+ WFIFOL(inter_fd,2) = party_id;
+ WFIFOL(inter_fd,6) = char_id;
+ WFIFOSET(inter_fd,10);
+ return 0;
}
// Request to add a member to party
int intif_party_addmember(int party_id,struct party_member *member)
{
- if (CheckForCharServer())
- return 0;
- WFIFOHEAD(inter_fd,42);
- WFIFOW(inter_fd,0)=0x3022;
- WFIFOW(inter_fd,2)=8+sizeof(struct party_member);
- WFIFOL(inter_fd,4)=party_id;
- memcpy(WFIFOP(inter_fd,8),member,sizeof(struct party_member));
- WFIFOSET(inter_fd,WFIFOW(inter_fd, 2));
- return 1;
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd,42);
+ WFIFOW(inter_fd,0)=0x3022;
+ WFIFOW(inter_fd,2)=8+sizeof(struct party_member);
+ WFIFOL(inter_fd,4)=party_id;
+ memcpy(WFIFOP(inter_fd,8),member,sizeof(struct party_member));
+ WFIFOSET(inter_fd,WFIFOW(inter_fd, 2));
+ return 1;
}
// Request to change party configuration (exp,item share)
int intif_party_changeoption(int party_id,int account_id,int exp,int item)
{
- if (CheckForCharServer())
- return 0;
- WFIFOHEAD(inter_fd,14);
- WFIFOW(inter_fd,0)=0x3023;
- WFIFOL(inter_fd,2)=party_id;
- WFIFOL(inter_fd,6)=account_id;
- WFIFOW(inter_fd,10)=exp;
- WFIFOW(inter_fd,12)=item;
- WFIFOSET(inter_fd,14);
- return 0;
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd,14);
+ WFIFOW(inter_fd,0)=0x3023;
+ WFIFOL(inter_fd,2)=party_id;
+ WFIFOL(inter_fd,6)=account_id;
+ WFIFOW(inter_fd,10)=exp;
+ WFIFOW(inter_fd,12)=item;
+ WFIFOSET(inter_fd,14);
+ return 0;
}
// Request to leave party
int intif_party_leave(int party_id,int account_id, int char_id)
{
- if (CheckForCharServer())
- return 0;
- WFIFOHEAD(inter_fd,14);
- WFIFOW(inter_fd,0)=0x3024;
- WFIFOL(inter_fd,2)=party_id;
- WFIFOL(inter_fd,6)=account_id;
- WFIFOL(inter_fd,10)=char_id;
- WFIFOSET(inter_fd,14);
- return 0;
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd,14);
+ WFIFOW(inter_fd,0)=0x3024;
+ WFIFOL(inter_fd,2)=party_id;
+ WFIFOL(inter_fd,6)=account_id;
+ WFIFOL(inter_fd,10)=char_id;
+ WFIFOSET(inter_fd,14);
+ return 0;
}
// Request keeping party for new map ??
int intif_party_changemap(struct map_session_data *sd,int online)
{
- int m, mapindex;
+ int m, mapindex;
- if (CheckForCharServer())
- return 0;
- if (!sd)
- return 0;
+ if (CheckForCharServer())
+ return 0;
+ if(!sd)
+ return 0;
- if ((m=map_mapindex2mapid(sd->mapindex)) >= 0 && map[m].instance_id)
- mapindex = map[map[m].instance_src_map].index;
- else
- mapindex = sd->mapindex;
+ if( (m=map_mapindex2mapid(sd->mapindex)) >= 0 && map[m].instance_id )
+ mapindex = map[map[m].instance_src_map].index;
+ else
+ mapindex = sd->mapindex;
- WFIFOHEAD(inter_fd,19);
- WFIFOW(inter_fd,0)=0x3025;
- WFIFOL(inter_fd,2)=sd->status.party_id;
- WFIFOL(inter_fd,6)=sd->status.account_id;
- WFIFOL(inter_fd,10)=sd->status.char_id;
- WFIFOW(inter_fd,14)=mapindex;
- WFIFOB(inter_fd,16)=online;
- WFIFOW(inter_fd,17)=sd->status.base_level;
- WFIFOSET(inter_fd,19);
- return 1;
+ WFIFOHEAD(inter_fd,19);
+ WFIFOW(inter_fd,0)=0x3025;
+ WFIFOL(inter_fd,2)=sd->status.party_id;
+ WFIFOL(inter_fd,6)=sd->status.account_id;
+ WFIFOL(inter_fd,10)=sd->status.char_id;
+ WFIFOW(inter_fd,14)=mapindex;
+ WFIFOB(inter_fd,16)=online;
+ WFIFOW(inter_fd,17)=sd->status.base_level;
+ WFIFOSET(inter_fd,19);
+ return 1;
}
// Request breaking party
int intif_break_party(int party_id)
{
- if (CheckForCharServer())
- return 0;
- WFIFOHEAD(inter_fd,6);
- WFIFOW(inter_fd,0)=0x3026;
- WFIFOL(inter_fd,2)=party_id;
- WFIFOSET(inter_fd,6);
- return 0;
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd,6);
+ WFIFOW(inter_fd,0)=0x3026;
+ WFIFOL(inter_fd,2)=party_id;
+ WFIFOSET(inter_fd,6);
+ return 0;
}
// Sending party chat
int intif_party_message(int party_id,int account_id,const char *mes,int len)
{
- if (CheckForCharServer())
- return 0;
+ if (CheckForCharServer())
+ return 0;
- if (other_mapserver_count < 1)
- return 0; //No need to send.
+ if (other_mapserver_count < 1)
+ return 0; //No need to send.
- WFIFOHEAD(inter_fd,len + 12);
- WFIFOW(inter_fd,0)=0x3027;
- WFIFOW(inter_fd,2)=len+12;
- WFIFOL(inter_fd,4)=party_id;
- WFIFOL(inter_fd,8)=account_id;
- memcpy(WFIFOP(inter_fd,12),mes,len);
- WFIFOSET(inter_fd,len+12);
- return 0;
+ WFIFOHEAD(inter_fd,len + 12);
+ WFIFOW(inter_fd,0)=0x3027;
+ WFIFOW(inter_fd,2)=len+12;
+ WFIFOL(inter_fd,4)=party_id;
+ WFIFOL(inter_fd,8)=account_id;
+ memcpy(WFIFOP(inter_fd,12),mes,len);
+ WFIFOSET(inter_fd,len+12);
+ return 0;
}
// Request a new leader for party
int intif_party_leaderchange(int party_id,int account_id,int char_id)
{
- if (CheckForCharServer())
- return 0;
- WFIFOHEAD(inter_fd,14);
- WFIFOW(inter_fd,0)=0x3029;
- WFIFOL(inter_fd,2)=party_id;
- WFIFOL(inter_fd,6)=account_id;
- WFIFOL(inter_fd,10)=char_id;
- WFIFOSET(inter_fd,14);
- return 0;
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd,14);
+ WFIFOW(inter_fd,0)=0x3029;
+ WFIFOL(inter_fd,2)=party_id;
+ WFIFOL(inter_fd,6)=account_id;
+ WFIFOL(inter_fd,10)=char_id;
+ WFIFOSET(inter_fd,14);
+ return 0;
}
// Request a Guild creation
int intif_guild_create(const char *name,const struct guild_member *master)
{
- if (CheckForCharServer())
- return 0;
- nullpo_ret(master);
+ if (CheckForCharServer())
+ return 0;
+ nullpo_ret(master);
- WFIFOHEAD(inter_fd,sizeof(struct guild_member)+(8+NAME_LENGTH));
- WFIFOW(inter_fd,0)=0x3030;
- WFIFOW(inter_fd,2)=sizeof(struct guild_member)+(8+NAME_LENGTH);
- WFIFOL(inter_fd,4)=master->account_id;
- memcpy(WFIFOP(inter_fd,8),name,NAME_LENGTH);
- memcpy(WFIFOP(inter_fd,8+NAME_LENGTH),master,sizeof(struct guild_member));
- WFIFOSET(inter_fd,WFIFOW(inter_fd,2));
- return 0;
+ WFIFOHEAD(inter_fd,sizeof(struct guild_member)+(8+NAME_LENGTH));
+ WFIFOW(inter_fd,0)=0x3030;
+ WFIFOW(inter_fd,2)=sizeof(struct guild_member)+(8+NAME_LENGTH);
+ WFIFOL(inter_fd,4)=master->account_id;
+ memcpy(WFIFOP(inter_fd,8),name,NAME_LENGTH);
+ memcpy(WFIFOP(inter_fd,8+NAME_LENGTH),master,sizeof(struct guild_member));
+ WFIFOSET(inter_fd,WFIFOW(inter_fd,2));
+ return 0;
}
// Request Guild information
int intif_guild_request_info(int guild_id)
{
- if (CheckForCharServer())
- return 0;
- WFIFOHEAD(inter_fd,6);
- WFIFOW(inter_fd,0) = 0x3031;
- WFIFOL(inter_fd,2) = guild_id;
- WFIFOSET(inter_fd,6);
- return 0;
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd,6);
+ WFIFOW(inter_fd,0) = 0x3031;
+ WFIFOL(inter_fd,2) = guild_id;
+ WFIFOSET(inter_fd,6);
+ return 0;
}
// Request to add member to the guild
int intif_guild_addmember(int guild_id,struct guild_member *m)
{
- if (CheckForCharServer())
- return 0;
- WFIFOHEAD(inter_fd,sizeof(struct guild_member)+8);
- WFIFOW(inter_fd,0) = 0x3032;
- WFIFOW(inter_fd,2) = sizeof(struct guild_member)+8;
- WFIFOL(inter_fd,4) = guild_id;
- memcpy(WFIFOP(inter_fd,8),m,sizeof(struct guild_member));
- WFIFOSET(inter_fd,WFIFOW(inter_fd,2));
- return 0;
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd,sizeof(struct guild_member)+8);
+ WFIFOW(inter_fd,0) = 0x3032;
+ WFIFOW(inter_fd,2) = sizeof(struct guild_member)+8;
+ WFIFOL(inter_fd,4) = guild_id;
+ memcpy(WFIFOP(inter_fd,8),m,sizeof(struct guild_member));
+ WFIFOSET(inter_fd,WFIFOW(inter_fd,2));
+ return 0;
}
// Request a new leader for guild
-int intif_guild_change_gm(int guild_id, const char *name, int len)
+int intif_guild_change_gm(int guild_id, const char* name, int len)
{
- if (CheckForCharServer())
- return 0;
- WFIFOHEAD(inter_fd, len + 8);
- WFIFOW(inter_fd, 0)=0x3033;
- WFIFOW(inter_fd, 2)=len+8;
- WFIFOL(inter_fd, 4)=guild_id;
- memcpy(WFIFOP(inter_fd,8),name,len);
- WFIFOSET(inter_fd,len+8);
- return 0;
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd, len + 8);
+ WFIFOW(inter_fd, 0)=0x3033;
+ WFIFOW(inter_fd, 2)=len+8;
+ WFIFOL(inter_fd, 4)=guild_id;
+ memcpy(WFIFOP(inter_fd,8),name,len);
+ WFIFOSET(inter_fd,len+8);
+ return 0;
}
// Request to leave guild
int intif_guild_leave(int guild_id,int account_id,int char_id,int flag,const char *mes)
{
- if (CheckForCharServer())
- return 0;
- WFIFOHEAD(inter_fd, 55);
- WFIFOW(inter_fd, 0) = 0x3034;
- WFIFOL(inter_fd, 2) = guild_id;
- WFIFOL(inter_fd, 6) = account_id;
- WFIFOL(inter_fd,10) = char_id;
- WFIFOB(inter_fd,14) = flag;
- safestrncpy((char *)WFIFOP(inter_fd,15),mes,40);
- WFIFOSET(inter_fd,55);
- return 0;
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd, 55);
+ WFIFOW(inter_fd, 0) = 0x3034;
+ WFIFOL(inter_fd, 2) = guild_id;
+ WFIFOL(inter_fd, 6) = account_id;
+ WFIFOL(inter_fd,10) = char_id;
+ WFIFOB(inter_fd,14) = flag;
+ safestrncpy((char*)WFIFOP(inter_fd,15),mes,40);
+ WFIFOSET(inter_fd,55);
+ return 0;
}
//Update request / Lv online status of the guild members
int intif_guild_memberinfoshort(int guild_id,int account_id,int char_id,int online,int lv,int class_)
{
- if (CheckForCharServer())
- return 0;
- WFIFOHEAD(inter_fd, 19);
- 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_;
- WFIFOSET(inter_fd,19);
- return 0;
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd, 19);
+ 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_;
+ WFIFOSET(inter_fd,19);
+ return 0;
}
//Guild disbanded notification
int intif_guild_break(int guild_id)
{
- if (CheckForCharServer())
- return 0;
- WFIFOHEAD(inter_fd, 6);
- WFIFOW(inter_fd, 0) = 0x3036;
- WFIFOL(inter_fd, 2) = guild_id;
- WFIFOSET(inter_fd,6);
- return 0;
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd, 6);
+ WFIFOW(inter_fd, 0) = 0x3036;
+ WFIFOL(inter_fd, 2) = guild_id;
+ WFIFOSET(inter_fd,6);
+ return 0;
}
// Send a guild message
int intif_guild_message(int guild_id,int account_id,const char *mes,int len)
{
- if (CheckForCharServer())
- return 0;
+ if (CheckForCharServer())
+ return 0;
- if (other_mapserver_count < 1)
- return 0; //No need to send.
+ if (other_mapserver_count < 1)
+ return 0; //No need to send.
- WFIFOHEAD(inter_fd, len + 12);
- 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);
+ WFIFOHEAD(inter_fd, len + 12);
+ 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;
+ return 0;
}
// Request a change of Guild basic information
int intif_guild_change_basicinfo(int guild_id,int type,const void *data,int len)
{
- if (CheckForCharServer())
- return 0;
- WFIFOHEAD(inter_fd, len + 10);
- WFIFOW(inter_fd,0)=0x3039;
- WFIFOW(inter_fd,2)=len+10;
- WFIFOL(inter_fd,4)=guild_id;
- WFIFOW(inter_fd,8)=type;
- memcpy(WFIFOP(inter_fd,10),data,len);
- WFIFOSET(inter_fd,len+10);
- return 0;
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd, len + 10);
+ WFIFOW(inter_fd,0)=0x3039;
+ WFIFOW(inter_fd,2)=len+10;
+ WFIFOL(inter_fd,4)=guild_id;
+ WFIFOW(inter_fd,8)=type;
+ memcpy(WFIFOP(inter_fd,10),data,len);
+ WFIFOSET(inter_fd,len+10);
+ return 0;
}
// Request a change of Guild member information
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;
- WFIFOHEAD(inter_fd, len + 18);
- WFIFOW(inter_fd, 0)=0x303a;
- WFIFOW(inter_fd, 2)=len+18;
- WFIFOL(inter_fd, 4)=guild_id;
- WFIFOL(inter_fd, 8)=account_id;
- WFIFOL(inter_fd,12)=char_id;
- WFIFOW(inter_fd,16)=type;
- memcpy(WFIFOP(inter_fd,18),data,len);
- WFIFOSET(inter_fd,len+18);
- return 0;
+ int type,const void *data,int len)
+{
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd, len + 18);
+ WFIFOW(inter_fd, 0)=0x303a;
+ WFIFOW(inter_fd, 2)=len+18;
+ WFIFOL(inter_fd, 4)=guild_id;
+ WFIFOL(inter_fd, 8)=account_id;
+ WFIFOL(inter_fd,12)=char_id;
+ WFIFOW(inter_fd,16)=type;
+ memcpy(WFIFOP(inter_fd,18),data,len);
+ WFIFOSET(inter_fd,len+18);
+ return 0;
}
// Request a change of Guild title
int intif_guild_position(int guild_id,int idx,struct guild_position *p)
{
- if (CheckForCharServer())
- return 0;
- WFIFOHEAD(inter_fd, sizeof(struct guild_position)+12);
- WFIFOW(inter_fd,0)=0x303b;
- WFIFOW(inter_fd,2)=sizeof(struct guild_position)+12;
- WFIFOL(inter_fd,4)=guild_id;
- WFIFOL(inter_fd,8)=idx;
- memcpy(WFIFOP(inter_fd,12),p,sizeof(struct guild_position));
- WFIFOSET(inter_fd,WFIFOW(inter_fd,2));
- return 0;
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd, sizeof(struct guild_position)+12);
+ WFIFOW(inter_fd,0)=0x303b;
+ WFIFOW(inter_fd,2)=sizeof(struct guild_position)+12;
+ WFIFOL(inter_fd,4)=guild_id;
+ WFIFOL(inter_fd,8)=idx;
+ memcpy(WFIFOP(inter_fd,12),p,sizeof(struct guild_position));
+ WFIFOSET(inter_fd,WFIFOW(inter_fd,2));
+ return 0;
}
// Request an update of Guildskill skillnum
int intif_guild_skillup(int guild_id, int skill_num, int account_id, int max)
{
- if (CheckForCharServer())
- return 0;
- WFIFOHEAD(inter_fd, 18);
- WFIFOW(inter_fd, 0) = 0x303c;
- WFIFOL(inter_fd, 2) = guild_id;
- WFIFOL(inter_fd, 6) = skill_num;
- WFIFOL(inter_fd, 10) = account_id;
- WFIFOL(inter_fd, 14) = max;
- WFIFOSET(inter_fd, 18);
- return 0;
+ if( CheckForCharServer() )
+ return 0;
+ WFIFOHEAD(inter_fd, 18);
+ WFIFOW(inter_fd, 0) = 0x303c;
+ WFIFOL(inter_fd, 2) = guild_id;
+ WFIFOL(inter_fd, 6) = skill_num;
+ WFIFOL(inter_fd, 10) = account_id;
+ WFIFOL(inter_fd, 14) = max;
+ WFIFOSET(inter_fd, 18);
+ return 0;
}
// Request a new guild relationship
int intif_guild_alliance(int guild_id1,int guild_id2,int account_id1,int account_id2,int flag)
{
- if (CheckForCharServer())
- return 0;
- WFIFOHEAD(inter_fd,19);
- WFIFOW(inter_fd, 0)=0x303d;
- WFIFOL(inter_fd, 2)=guild_id1;
- WFIFOL(inter_fd, 6)=guild_id2;
- WFIFOL(inter_fd,10)=account_id1;
- WFIFOL(inter_fd,14)=account_id2;
- WFIFOB(inter_fd,18)=flag;
- WFIFOSET(inter_fd,19);
- return 0;
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd,19);
+ WFIFOW(inter_fd, 0)=0x303d;
+ WFIFOL(inter_fd, 2)=guild_id1;
+ WFIFOL(inter_fd, 6)=guild_id2;
+ WFIFOL(inter_fd,10)=account_id1;
+ WFIFOL(inter_fd,14)=account_id2;
+ WFIFOB(inter_fd,18)=flag;
+ WFIFOSET(inter_fd,19);
+ return 0;
}
// Request to change guild notice
int intif_guild_notice(int guild_id,const char *mes1,const char *mes2)
{
- if (CheckForCharServer())
- return 0;
- WFIFOHEAD(inter_fd,186);
- WFIFOW(inter_fd,0)=0x303e;
- WFIFOL(inter_fd,2)=guild_id;
- memcpy(WFIFOP(inter_fd,6),mes1,MAX_GUILDMES1);
- memcpy(WFIFOP(inter_fd,66),mes2,MAX_GUILDMES2);
- WFIFOSET(inter_fd,186);
- return 0;
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd,186);
+ WFIFOW(inter_fd,0)=0x303e;
+ WFIFOL(inter_fd,2)=guild_id;
+ memcpy(WFIFOP(inter_fd,6),mes1,MAX_GUILDMES1);
+ memcpy(WFIFOP(inter_fd,66),mes2,MAX_GUILDMES2);
+ WFIFOSET(inter_fd,186);
+ return 0;
}
// Request to change guild emblem
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;
- WFIFOHEAD(inter_fd,len + 12);
- WFIFOW(inter_fd,0)=0x303f;
- WFIFOW(inter_fd,2)=len+12;
- WFIFOL(inter_fd,4)=guild_id;
- WFIFOL(inter_fd,8)=0;
- memcpy(WFIFOP(inter_fd,12),data,len);
- WFIFOSET(inter_fd,len+12);
- return 0;
+ if (CheckForCharServer())
+ return 0;
+ if(guild_id<=0 || len<0 || len>2000)
+ return 0;
+ WFIFOHEAD(inter_fd,len + 12);
+ WFIFOW(inter_fd,0)=0x303f;
+ WFIFOW(inter_fd,2)=len+12;
+ WFIFOL(inter_fd,4)=guild_id;
+ WFIFOL(inter_fd,8)=0;
+ memcpy(WFIFOP(inter_fd,12),data,len);
+ WFIFOSET(inter_fd,len+12);
+ return 0;
}
/**
@@ -771,29 +771,29 @@ int intif_guild_emblem(int guild_id,int len,const char *data)
*/
int intif_guild_castle_dataload(int num, int *castle_ids)
{
- if (CheckForCharServer())
- return 0;
- WFIFOHEAD(inter_fd, 4 + num * sizeof(int));
- WFIFOW(inter_fd, 0) = 0x3040;
- WFIFOW(inter_fd, 2) = 4 + num * sizeof(int);
- memcpy(WFIFOP(inter_fd, 4), castle_ids, num * sizeof(int));
- WFIFOSET(inter_fd, WFIFOW(inter_fd, 2));
- return 1;
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd, 4 + num * sizeof(int));
+ WFIFOW(inter_fd, 0) = 0x3040;
+ WFIFOW(inter_fd, 2) = 4 + num * sizeof(int);
+ memcpy(WFIFOP(inter_fd, 4), castle_ids, num * sizeof(int));
+ WFIFOSET(inter_fd, WFIFOW(inter_fd, 2));
+ return 1;
}
// Request change castle guild owner and save data
int intif_guild_castle_datasave(int castle_id,int index, int value)
{
- if (CheckForCharServer())
- return 0;
- WFIFOHEAD(inter_fd,9);
- WFIFOW(inter_fd,0)=0x3041;
- WFIFOW(inter_fd,2)=castle_id;
- WFIFOB(inter_fd,4)=index;
- WFIFOL(inter_fd,5)=value;
- WFIFOSET(inter_fd,9);
- return 1;
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd,9);
+ WFIFOW(inter_fd,0)=0x3041;
+ WFIFOW(inter_fd,2)=castle_id;
+ WFIFOB(inter_fd,4)=index;
+ WFIFOL(inter_fd,5)=value;
+ WFIFOSET(inter_fd,9);
+ return 1;
}
//-----------------------------------------------------------------
@@ -802,52 +802,52 @@ int intif_guild_castle_datasave(int castle_id,int index, int value)
int intif_homunculus_create(int account_id, struct s_homunculus *sh)
{
- if (CheckForCharServer())
- return 0;
- WFIFOHEAD(inter_fd, sizeof(struct s_homunculus)+8);
- WFIFOW(inter_fd,0) = 0x3090;
- WFIFOW(inter_fd,2) = sizeof(struct s_homunculus)+8;
- WFIFOL(inter_fd,4) = account_id;
- memcpy(WFIFOP(inter_fd,8),sh,sizeof(struct s_homunculus));
- WFIFOSET(inter_fd, WFIFOW(inter_fd,2));
- return 0;
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd, sizeof(struct s_homunculus)+8);
+ WFIFOW(inter_fd,0) = 0x3090;
+ WFIFOW(inter_fd,2) = sizeof(struct s_homunculus)+8;
+ WFIFOL(inter_fd,4) = account_id;
+ memcpy(WFIFOP(inter_fd,8),sh,sizeof(struct s_homunculus));
+ WFIFOSET(inter_fd, WFIFOW(inter_fd,2));
+ return 0;
}
int intif_homunculus_requestload(int account_id, int homun_id)
{
- if (CheckForCharServer())
- return 0;
- WFIFOHEAD(inter_fd, 10);
- WFIFOW(inter_fd,0) = 0x3091;
- WFIFOL(inter_fd,2) = account_id;
- WFIFOL(inter_fd,6) = homun_id;
- WFIFOSET(inter_fd, 10);
- return 1;
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd, 10);
+ WFIFOW(inter_fd,0) = 0x3091;
+ WFIFOL(inter_fd,2) = account_id;
+ WFIFOL(inter_fd,6) = homun_id;
+ WFIFOSET(inter_fd, 10);
+ return 1;
}
-int intif_homunculus_requestsave(int account_id, struct s_homunculus *sh)
+int intif_homunculus_requestsave(int account_id, struct s_homunculus* sh)
{
- if (CheckForCharServer())
- return 0;
- WFIFOHEAD(inter_fd, sizeof(struct s_homunculus)+8);
- WFIFOW(inter_fd,0) = 0x3092;
- WFIFOW(inter_fd,2) = sizeof(struct s_homunculus)+8;
- WFIFOL(inter_fd,4) = account_id;
- memcpy(WFIFOP(inter_fd,8),sh,sizeof(struct s_homunculus));
- WFIFOSET(inter_fd, WFIFOW(inter_fd,2));
- return 0;
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd, sizeof(struct s_homunculus)+8);
+ WFIFOW(inter_fd,0) = 0x3092;
+ WFIFOW(inter_fd,2) = sizeof(struct s_homunculus)+8;
+ WFIFOL(inter_fd,4) = account_id;
+ memcpy(WFIFOP(inter_fd,8),sh,sizeof(struct s_homunculus));
+ WFIFOSET(inter_fd, WFIFOW(inter_fd,2));
+ return 0;
}
int intif_homunculus_requestdelete(int homun_id)
{
- if (CheckForCharServer())
- return 0;
- WFIFOHEAD(inter_fd, 6);
- WFIFOW(inter_fd, 0) = 0x3093;
- WFIFOL(inter_fd,2) = homun_id;
- WFIFOSET(inter_fd,6);
- return 0;
+ if (CheckForCharServer())
+ return 0;
+ WFIFOHEAD(inter_fd, 6);
+ WFIFOW(inter_fd, 0) = 0x3093;
+ WFIFOL(inter_fd,2) = homun_id;
+ WFIFOSET(inter_fd,6);
+ return 0;
}
@@ -858,509 +858,489 @@ int intif_homunculus_requestdelete(int homun_id)
// Wisp/Page reception // rewritten by [Yor]
int intif_parse_WisMessage(int fd)
{
- struct map_session_data *sd;
- char *wisp_source;
- char name[NAME_LENGTH];
- int id, i;
-
- id=RFIFOL(fd,4);
-
- safestrncpy(name, (char *)RFIFOP(fd,32), NAME_LENGTH);
- sd = map_nick2sd(name);
- if (sd == NULL || strcmp(sd->status.name, name) != 0) {
- //Not found
- intif_wis_replay(id,1);
- return 0;
- }
- if (sd->state.ignoreAll) {
- intif_wis_replay(id, 2);
- return 0;
- }
- wisp_source = (char *) RFIFOP(fd,8); // speed up [Yor]
- for (i=0; i < MAX_IGNORE_LIST &&
- sd->ignore[i].name[0] != '\0' &&
- strcmp(sd->ignore[i].name, wisp_source) != 0
- ; i++);
-
- if (i < MAX_IGNORE_LIST && sd->ignore[i].name[0] != '\0') {
- //Ignored
- intif_wis_replay(id, 2);
- return 0;
- }
- //Success to send whisper.
- clif_wis_message(sd->fd, wisp_source, (char *)RFIFOP(fd,56),RFIFOW(fd,2)-56);
- intif_wis_replay(id,0); // succes
- return 0;
+ struct map_session_data* sd;
+ char *wisp_source;
+ char name[NAME_LENGTH];
+ int id, i;
+
+ id=RFIFOL(fd,4);
+
+ safestrncpy(name, (char*)RFIFOP(fd,32), NAME_LENGTH);
+ sd = map_nick2sd(name);
+ if(sd == NULL || strcmp(sd->status.name, name) != 0)
+ { //Not found
+ intif_wis_replay(id,1);
+ return 0;
+ }
+ if(sd->state.ignoreAll) {
+ intif_wis_replay(id, 2);
+ return 0;
+ }
+ wisp_source = (char *) RFIFOP(fd,8); // speed up [Yor]
+ for(i=0; i < MAX_IGNORE_LIST &&
+ sd->ignore[i].name[0] != '\0' &&
+ strcmp(sd->ignore[i].name, wisp_source) != 0
+ ; i++);
+
+ if (i < MAX_IGNORE_LIST && sd->ignore[i].name[0] != '\0')
+ { //Ignored
+ intif_wis_replay(id, 2);
+ return 0;
+ }
+ //Success to send whisper.
+ clif_wis_message(sd->fd, wisp_source, (char*)RFIFOP(fd,56),RFIFOW(fd,2)-56);
+ intif_wis_replay(id,0); // succes
+ return 0;
}
// Wisp/page transmission result reception
int intif_parse_WisEnd(int fd)
{
- struct map_session_data *sd;
+ struct map_session_data* sd;
- if (battle_config.etc_log)
- ShowInfo("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 = (struct map_session_data *)map_nick2sd((char *) RFIFOP(fd,2));
- if (sd != NULL)
- clif_wis_end(sd->fd, RFIFOB(fd,26));
+ if (battle_config.etc_log)
+ ShowInfo("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 = (struct map_session_data *)map_nick2sd((char *) RFIFOP(fd,2));
+ if (sd != NULL)
+ clif_wis_end(sd->fd, RFIFOB(fd,26));
- return 0;
+ return 0;
}
-static int mapif_parse_WisToGM_sub(struct map_session_data *sd,va_list va)
+static int mapif_parse_WisToGM_sub(struct map_session_data* sd,va_list va)
{
- int permission = va_arg(va, int);
- char *wisp_name;
- char *message;
- int len;
+ int permission = va_arg(va, int);
+ char *wisp_name;
+ char *message;
+ int len;
- if (!pc_has_permission(sd, permission))
- return 0;
- wisp_name = va_arg(va, char *);
- message = va_arg(va, char *);
- len = va_arg(va, int);
- clif_wis_message(sd->fd, wisp_name, message, len);
- return 1;
+ if (!pc_has_permission(sd, permission))
+ return 0;
+ wisp_name = va_arg(va, char*);
+ message = va_arg(va, char*);
+ len = va_arg(va, int);
+ clif_wis_message(sd->fd, wisp_name, message, len);
+ return 1;
}
// Received wisp message from map-server via char-server for ALL gm
// 0x3003/0x3803 <packet_len>.w <wispname>.24B <permission>.l <message>.?B
int mapif_parse_WisToGM(int fd)
{
- int permission, mes_len;
- char Wisp_name[NAME_LENGTH];
- char mbuf[255];
- char *message;
+ int permission, mes_len;
+ char Wisp_name[NAME_LENGTH];
+ char mbuf[255];
+ char *message;
- mes_len = RFIFOW(fd,2) - 32;
- message = (char *)(mes_len >= 255 ? (char *) aMalloc(mes_len) : mbuf);
+ mes_len = RFIFOW(fd,2) - 32;
+ message = (char *) (mes_len >= 255 ? (char *) aMalloc(mes_len) : mbuf);
- permission = RFIFOL(fd,28);
- safestrncpy(Wisp_name, (char *)RFIFOP(fd,4), NAME_LENGTH);
- safestrncpy(message, (char *)RFIFOP(fd,32), mes_len);
- // information is sent to all online GM
- map_foreachpc(mapif_parse_WisToGM_sub, permission, Wisp_name, message, mes_len);
+ permission = RFIFOL(fd,28);
+ safestrncpy(Wisp_name, (char*)RFIFOP(fd,4), NAME_LENGTH);
+ safestrncpy(message, (char*)RFIFOP(fd,32), mes_len);
+ // information is sent to all online GM
+ map_foreachpc(mapif_parse_WisToGM_sub, permission, Wisp_name, message, mes_len);
- if (message != mbuf)
- aFree(message);
- return 0;
+ if (message != mbuf)
+ aFree(message);
+ return 0;
}
// Request player registre
int intif_parse_Registers(int fd)
{
- int j,p,len,max, flag;
- struct map_session_data *sd;
- struct global_reg *reg;
- int *qty;
- int account_id = RFIFOL(fd,4), char_id = RFIFOL(fd,8);
- struct auth_node *node = chrif_auth_check(account_id, char_id, ST_LOGIN);
- if (node)
- sd = node->sd;
- else { //Normally registries should arrive for in log-in chars.
- sd = map_id2sd(account_id);
- if (sd && RFIFOB(fd,12) == 3 && sd->status.char_id != char_id)
- sd = NULL; //Character registry from another character.
- }
- if (!sd) return 1;
-
- flag = (sd->save_reg.global_num == -1 || sd->save_reg.account_num == -1 || sd->save_reg.account2_num == -1);
-
- switch (RFIFOB(fd,12)) {
- case 3: //Character Registry
- reg = sd->save_reg.global;
- qty = &sd->save_reg.global_num;
- max = GLOBAL_REG_NUM;
- break;
- case 2: //Account Registry
- reg = sd->save_reg.account;
- qty = &sd->save_reg.account_num;
- max = ACCOUNT_REG_NUM;
- break;
- case 1: //Account2 Registry
- reg = sd->save_reg.account2;
- qty = &sd->save_reg.account2_num;
- max = ACCOUNT_REG2_NUM;
- break;
- default:
- ShowError("intif_parse_Registers: Unrecognized type %d\n",RFIFOB(fd,12));
- return 0;
- }
- for (j=0,p=13; j<max && p<RFIFOW(fd,2); j++) {
- sscanf((char *)RFIFOP(fd,p), "%31c%n", reg[j].str,&len);
- reg[j].str[len]='\0';
- p += len+1; //+1 to skip the '\0' between strings.
- sscanf((char *)RFIFOP(fd,p), "%255c%n", reg[j].value,&len);
- reg[j].value[len]='\0';
- p += len+1;
- }
- *qty = j;
-
- if (flag && sd->save_reg.global_num > -1 && sd->save_reg.account_num > -1 && sd->save_reg.account2_num > -1)
- pc_reg_received(sd); //Received all registry values, execute init scripts and what-not. [Skotlex]
- return 1;
+ int j,p,len,max, flag;
+ struct map_session_data *sd;
+ struct global_reg *reg;
+ int *qty;
+ int account_id = RFIFOL(fd,4), char_id = RFIFOL(fd,8);
+ struct auth_node *node = chrif_auth_check(account_id, char_id, ST_LOGIN);
+ if (node)
+ sd = node->sd;
+ else { //Normally registries should arrive for in log-in chars.
+ sd = map_id2sd(account_id);
+ if (sd && RFIFOB(fd,12) == 3 && sd->status.char_id != char_id)
+ sd = NULL; //Character registry from another character.
+ }
+ if (!sd) return 1;
+
+ flag = (sd->save_reg.global_num == -1 || sd->save_reg.account_num == -1 || sd->save_reg.account2_num == -1);
+
+ switch (RFIFOB(fd,12)) {
+ case 3: //Character Registry
+ reg = sd->save_reg.global;
+ qty = &sd->save_reg.global_num;
+ max = GLOBAL_REG_NUM;
+ break;
+ case 2: //Account Registry
+ reg = sd->save_reg.account;
+ qty = &sd->save_reg.account_num;
+ max = ACCOUNT_REG_NUM;
+ break;
+ case 1: //Account2 Registry
+ reg = sd->save_reg.account2;
+ qty = &sd->save_reg.account2_num;
+ max = ACCOUNT_REG2_NUM;
+ break;
+ default:
+ ShowError("intif_parse_Registers: Unrecognized type %d\n",RFIFOB(fd,12));
+ return 0;
+ }
+ for(j=0,p=13;j<max && p<RFIFOW(fd,2);j++){
+ sscanf((char*)RFIFOP(fd,p), "%31c%n", reg[j].str,&len);
+ reg[j].str[len]='\0';
+ p += len+1; //+1 to skip the '\0' between strings.
+ sscanf((char*)RFIFOP(fd,p), "%255c%n", reg[j].value,&len);
+ reg[j].value[len]='\0';
+ p += len+1;
+ }
+ *qty = j;
+
+ if (flag && sd->save_reg.global_num > -1 && sd->save_reg.account_num > -1 && sd->save_reg.account2_num > -1)
+ pc_reg_received(sd); //Received all registry values, execute init scripts and what-not. [Skotlex]
+ return 1;
}
int intif_parse_LoadGuildStorage(int fd)
{
- struct guild_storage *gstor;
- struct map_session_data *sd;
- int guild_id;
-
- guild_id = RFIFOL(fd,8);
- if (guild_id <= 0)
- return 1;
- sd=map_id2sd(RFIFOL(fd,4));
- if (sd==NULL) {
- ShowError("intif_parse_LoadGuildStorage: user not found %d\n",RFIFOL(fd,4));
- return 1;
- }
- gstor=guild2storage(guild_id);
- if (!gstor) {
- ShowWarning("intif_parse_LoadGuildStorage: error guild_id %d not exist\n",guild_id);
- return 1;
- }
- if (gstor->storage_status == 1) { // Already open.. lets ignore this update
- ShowWarning("intif_parse_LoadGuildStorage: storage received for a client already open (User %d:%d)\n", sd->status.account_id, sd->status.char_id);
- return 1;
- }
- if (gstor->dirty) { // Already have storage, and it has been modified and not saved yet! Exploit! [Skotlex]
- ShowWarning("intif_parse_LoadGuildStorage: received storage for an already modified non-saved storage! (User %d:%d)\n", sd->status.account_id, sd->status.char_id);
- return 1;
- }
- if (RFIFOW(fd,2)-12 != sizeof(struct guild_storage)) {
- ShowError("intif_parse_LoadGuildStorage: data size error %d %d\n",RFIFOW(fd,2)-12 , sizeof(struct guild_storage));
- gstor->storage_status = 0;
- return 1;
- }
-
- memcpy(gstor,RFIFOP(fd,12),sizeof(struct guild_storage));
- storage_guild_storageopen(sd);
- return 0;
+ struct guild_storage *gstor;
+ struct map_session_data *sd;
+ int guild_id;
+
+ guild_id = RFIFOL(fd,8);
+ if(guild_id <= 0)
+ return 1;
+ sd=map_id2sd( RFIFOL(fd,4) );
+ if(sd==NULL){
+ ShowError("intif_parse_LoadGuildStorage: user not found %d\n",RFIFOL(fd,4));
+ return 1;
+ }
+ gstor=guild2storage(guild_id);
+ if(!gstor) {
+ ShowWarning("intif_parse_LoadGuildStorage: error guild_id %d not exist\n",guild_id);
+ return 1;
+ }
+ if (gstor->storage_status == 1) { // Already open.. lets ignore this update
+ ShowWarning("intif_parse_LoadGuildStorage: storage received for a client already open (User %d:%d)\n", sd->status.account_id, sd->status.char_id);
+ return 1;
+ }
+ if (gstor->dirty) { // Already have storage, and it has been modified and not saved yet! Exploit! [Skotlex]
+ ShowWarning("intif_parse_LoadGuildStorage: received storage for an already modified non-saved storage! (User %d:%d)\n", sd->status.account_id, sd->status.char_id);
+ return 1;
+ }
+ if( RFIFOW(fd,2)-12 != sizeof(struct guild_storage) ){
+ ShowError("intif_parse_LoadGuildStorage: data size error %d %d\n",RFIFOW(fd,2)-12 , sizeof(struct guild_storage));
+ gstor->storage_status = 0;
+ return 1;
+ }
+
+ memcpy(gstor,RFIFOP(fd,12),sizeof(struct guild_storage));
+ storage_guild_storageopen(sd);
+ return 0;
}
// ACK guild_storage saved
int intif_parse_SaveGuildStorage(int fd)
{
- storage_guild_storagesaved(/*RFIFOL(fd,2), */RFIFOL(fd,6));
- return 0;
+ storage_guild_storagesaved(/*RFIFOL(fd,2), */RFIFOL(fd,6));
+ return 0;
}
// ACK party creation
int intif_parse_PartyCreated(int fd)
{
- if (battle_config.etc_log)
- ShowInfo("intif: party created by account %d\n\n", RFIFOL(fd,2));
- party_created(RFIFOL(fd,2), RFIFOL(fd,6),RFIFOB(fd,10),RFIFOL(fd,11), (char *)RFIFOP(fd,15));
- return 0;
+ if(battle_config.etc_log)
+ ShowInfo("intif: party created by account %d\n\n", RFIFOL(fd,2));
+ party_created(RFIFOL(fd,2), RFIFOL(fd,6),RFIFOB(fd,10),RFIFOL(fd,11), (char *)RFIFOP(fd,15));
+ return 0;
}
// Receive party info
int intif_parse_PartyInfo(int fd)
{
- if (RFIFOW(fd,2) == 12) {
- ShowWarning("intif: party noinfo (char_id=%d party_id=%d)\n", RFIFOL(fd,4), RFIFOL(fd,8));
- party_recv_noinfo(RFIFOL(fd,8), RFIFOL(fd,4));
- return 0;
- }
+ if( RFIFOW(fd,2) == 12 ){
+ ShowWarning("intif: party noinfo (char_id=%d party_id=%d)\n", RFIFOL(fd,4), RFIFOL(fd,8));
+ party_recv_noinfo(RFIFOL(fd,8), RFIFOL(fd,4));
+ return 0;
+ }
- if (RFIFOW(fd,2) != 8+sizeof(struct party))
- ShowError("intif: party info : data size error (char_id=%d party_id=%d packet_len=%d expected_len=%d)\n", RFIFOL(fd,4), RFIFOL(fd,8), RFIFOW(fd,2), 8+sizeof(struct party));
- party_recv_info((struct party *)RFIFOP(fd,8), RFIFOL(fd,4));
- return 0;
+ if( RFIFOW(fd,2) != 8+sizeof(struct party) )
+ ShowError("intif: party info : data size error (char_id=%d party_id=%d packet_len=%d expected_len=%d)\n", RFIFOL(fd,4), RFIFOL(fd,8), RFIFOW(fd,2), 8+sizeof(struct party));
+ party_recv_info((struct party *)RFIFOP(fd,8), RFIFOL(fd,4));
+ return 0;
}
// ACK adding party member
int intif_parse_PartyMemberAdded(int fd)
{
- if (battle_config.etc_log)
- ShowInfo("intif: party member added Party (%d), Account(%d), Char(%d)\n",RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10));
- party_member_added(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10), RFIFOB(fd, 14));
- return 0;
+ if(battle_config.etc_log)
+ ShowInfo("intif: party member added Party (%d), Account(%d), Char(%d)\n",RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10));
+ party_member_added(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10), RFIFOB(fd, 14));
+ return 0;
}
// ACK changing party option
int intif_parse_PartyOptionChanged(int fd)
{
- party_optionchanged(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOW(fd,10),RFIFOW(fd,12),RFIFOB(fd,14));
- return 0;
+ party_optionchanged(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOW(fd,10),RFIFOW(fd,12),RFIFOB(fd,14));
+ return 0;
}
// ACK member leaving party
int intif_parse_PartyMemberWithdraw(int fd)
{
- if (battle_config.etc_log)
- ShowInfo("intif: party member withdraw: Party(%d), Account(%d), Char(%d)\n",RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10));
- party_member_withdraw(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10));
- return 0;
+ if(battle_config.etc_log)
+ ShowInfo("intif: party member withdraw: Party(%d), Account(%d), Char(%d)\n",RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10));
+ party_member_withdraw(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10));
+ return 0;
}
// ACK party break
int intif_parse_PartyBroken(int fd)
{
- party_broken(RFIFOL(fd,2));
- return 0;
+ party_broken(RFIFOL(fd,2));
+ return 0;
}
// ACK party on new map
int intif_parse_PartyMove(int fd)
{
- party_recv_movemap(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOW(fd,14),RFIFOB(fd,16),RFIFOW(fd,17));
- return 0;
+ party_recv_movemap(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOW(fd,14),RFIFOB(fd,16),RFIFOW(fd,17));
+ return 0;
}
// ACK party messages
int intif_parse_PartyMessage(int fd)
{
- party_recv_message(RFIFOL(fd,4),RFIFOL(fd,8),(char *) RFIFOP(fd,12),RFIFOW(fd,2)-12);
- return 0;
+ party_recv_message(RFIFOL(fd,4),RFIFOL(fd,8),(char *) RFIFOP(fd,12),RFIFOW(fd,2)-12);
+ return 0;
}
// ACK guild creation
int intif_parse_GuildCreated(int fd)
{
- guild_created(RFIFOL(fd,2),RFIFOL(fd,6));
- return 0;
+ guild_created(RFIFOL(fd,2),RFIFOL(fd,6));
+ return 0;
}
// ACK guild infos
int intif_parse_GuildInfo(int fd)
{
- if (RFIFOW(fd,2) == 8) {
- ShowWarning("intif: guild noinfo %d\n",RFIFOL(fd,4));
- guild_recv_noinfo(RFIFOL(fd,4));
- return 0;
- }
- if (RFIFOW(fd,2)!=sizeof(struct guild)+4)
- ShowError("intif: guild info : data size error Gid: %d recv size: %d Expected size: %d\n",RFIFOL(fd,4),RFIFOW(fd,2),sizeof(struct guild)+4);
- guild_recv_info((struct guild *)RFIFOP(fd,4));
- return 0;
+ if(RFIFOW(fd,2) == 8) {
+ ShowWarning("intif: guild noinfo %d\n",RFIFOL(fd,4));
+ guild_recv_noinfo(RFIFOL(fd,4));
+ return 0;
+ }
+ if( RFIFOW(fd,2)!=sizeof(struct guild)+4 )
+ ShowError("intif: guild info : data size error Gid: %d recv size: %d Expected size: %d\n",RFIFOL(fd,4),RFIFOW(fd,2),sizeof(struct guild)+4);
+ guild_recv_info((struct guild *)RFIFOP(fd,4));
+ return 0;
}
// ACK adding guild member
int intif_parse_GuildMemberAdded(int fd)
{
- if (battle_config.etc_log)
- ShowInfo("intif: guild member added %d %d %d %d\n",RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOB(fd,14));
- guild_member_added(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOB(fd,14));
- return 0;
+ if(battle_config.etc_log)
+ ShowInfo("intif: guild member added %d %d %d %d\n",RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOB(fd,14));
+ guild_member_added(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOB(fd,14));
+ return 0;
}
// ACK member leaving guild
int intif_parse_GuildMemberWithdraw(int fd)
{
- guild_member_withdraw(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOB(fd,14),(char *)RFIFOP(fd,55),(char *)RFIFOP(fd,15));
- return 0;
+ guild_member_withdraw(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOB(fd,14),(char *)RFIFOP(fd,55),(char *)RFIFOP(fd,15));
+ return 0;
}
// ACK guild member basic info
int intif_parse_GuildMemberInfoShort(int fd)
{
- guild_recv_memberinfoshort(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOB(fd,14),RFIFOW(fd,15),RFIFOW(fd,17));
- return 0;
+ guild_recv_memberinfoshort(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOB(fd,14),RFIFOW(fd,15),RFIFOW(fd,17));
+ return 0;
}
// ACK guild break
int intif_parse_GuildBroken(int fd)
{
- guild_broken(RFIFOL(fd,2),RFIFOB(fd,6));
- return 0;
+ guild_broken(RFIFOL(fd,2),RFIFOB(fd,6));
+ return 0;
}
// basic guild info change notice
// 0x3839 <packet len>.w <guild id>.l <type>.w <data>.?b
int intif_parse_GuildBasicInfoChanged(int fd)
{
- //int len = RFIFOW(fd,2) - 10;
- int guild_id = RFIFOL(fd,4);
- int type = RFIFOW(fd,8);
- //void* data = RFIFOP(fd,10);
+ //int len = RFIFOW(fd,2) - 10;
+ int guild_id = RFIFOL(fd,4);
+ int type = RFIFOW(fd,8);
+ //void* data = RFIFOP(fd,10);
- struct guild *g = guild_search(guild_id);
- if (g == NULL)
- return 0;
+ struct guild* g = guild_search(guild_id);
+ if( g == NULL )
+ return 0;
- switch (type) {
- case GBI_EXP:
- g->exp = RFIFOQ(fd,10);
- break;
- case GBI_GUILDLV:
- g->guild_lv = RFIFOW(fd,10);
- break;
- case GBI_SKILLPOINT:
- g->skill_point = RFIFOL(fd,10);
- break;
- }
+ switch(type) {
+ case GBI_EXP: g->exp = RFIFOQ(fd,10); break;
+ case GBI_GUILDLV: g->guild_lv = RFIFOW(fd,10); break;
+ case GBI_SKILLPOINT: g->skill_point = RFIFOL(fd,10); break;
+ }
- return 0;
+ return 0;
}
// guild member info change notice
// 0x383a <packet len>.w <guild id>.l <account id>.l <char id>.l <type>.w <data>.?b
int intif_parse_GuildMemberInfoChanged(int fd)
{
- //int len = RFIFOW(fd,2) - 18;
- int guild_id = RFIFOL(fd,4);
- int account_id = RFIFOL(fd,8);
- int char_id = RFIFOL(fd,12);
- int type = RFIFOW(fd,16);
- //void* data = RFIFOP(fd,18);
-
- struct guild *g;
- int idx;
-
- g = guild_search(guild_id);
- if (g == NULL)
- return 0;
-
- idx = guild_getindex(g,account_id,char_id);
- if (idx == -1)
- return 0;
-
- switch (type) {
- case GMI_POSITION:
- g->member[idx].position = RFIFOW(fd,18);
- guild_memberposition_changed(g,idx,RFIFOW(fd,18));
- break;
- case GMI_EXP:
- g->member[idx].exp = RFIFOQ(fd,18);
- break;
- case GMI_HAIR:
- g->member[idx].hair = RFIFOW(fd,18);
- break;
- case GMI_HAIR_COLOR:
- g->member[idx].hair_color = RFIFOW(fd,18);
- break;
- case GMI_GENDER:
- g->member[idx].gender = RFIFOW(fd,18);
- break;
- case GMI_CLASS:
- g->member[idx].class_ = RFIFOW(fd,18);
- break;
- case GMI_LEVEL:
- g->member[idx].lv = RFIFOW(fd,18);
- break;
- }
- return 0;
+ //int len = RFIFOW(fd,2) - 18;
+ int guild_id = RFIFOL(fd,4);
+ int account_id = RFIFOL(fd,8);
+ int char_id = RFIFOL(fd,12);
+ int type = RFIFOW(fd,16);
+ //void* data = RFIFOP(fd,18);
+
+ struct guild* g;
+ int idx;
+
+ g = guild_search(guild_id);
+ if( g == NULL )
+ return 0;
+
+ idx = guild_getindex(g,account_id,char_id);
+ if( idx == -1 )
+ return 0;
+
+ switch( type ) {
+ case GMI_POSITION: g->member[idx].position = RFIFOW(fd,18); guild_memberposition_changed(g,idx,RFIFOW(fd,18)); break;
+ case GMI_EXP: g->member[idx].exp = RFIFOQ(fd,18); break;
+ case GMI_HAIR: g->member[idx].hair = RFIFOW(fd,18); break;
+ case GMI_HAIR_COLOR: g->member[idx].hair_color = RFIFOW(fd,18); break;
+ case GMI_GENDER: g->member[idx].gender = RFIFOW(fd,18); break;
+ case GMI_CLASS: g->member[idx].class_ = RFIFOW(fd,18); break;
+ case GMI_LEVEL: g->member[idx].lv = RFIFOW(fd,18); break;
+ }
+ return 0;
}
// ACK change of guild title
int intif_parse_GuildPosition(int fd)
{
- if (RFIFOW(fd,2)!=sizeof(struct guild_position)+12)
- ShowError("intif: guild info : data size error\n %d %d %d",RFIFOL(fd,4),RFIFOW(fd,2),sizeof(struct guild_position)+12);
- guild_position_changed(RFIFOL(fd,4),RFIFOL(fd,8),(struct guild_position *)RFIFOP(fd,12));
- return 0;
+ if( RFIFOW(fd,2)!=sizeof(struct guild_position)+12 )
+ ShowError("intif: guild info : data size error\n %d %d %d",RFIFOL(fd,4),RFIFOW(fd,2),sizeof(struct guild_position)+12);
+ guild_position_changed(RFIFOL(fd,4),RFIFOL(fd,8),(struct guild_position *)RFIFOP(fd,12));
+ return 0;
}
// ACK change of guild skill update
int intif_parse_GuildSkillUp(int fd)
{
- guild_skillupack(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10));
- return 0;
+ guild_skillupack(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10));
+ return 0;
}
// ACK change of guild relationship
int intif_parse_GuildAlliance(int fd)
{
- guild_allianceack(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOL(fd,14),RFIFOB(fd,18),(char *) RFIFOP(fd,19),(char *) RFIFOP(fd,43));
- return 0;
+ guild_allianceack(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOL(fd,14),RFIFOB(fd,18),(char *) RFIFOP(fd,19),(char *) RFIFOP(fd,43));
+ return 0;
}
// ACK change of guild notice
int intif_parse_GuildNotice(int fd)
{
- guild_notice_changed(RFIFOL(fd,2),(char *) RFIFOP(fd,6),(char *) RFIFOP(fd,66));
- return 0;
+ guild_notice_changed(RFIFOL(fd,2),(char *) RFIFOP(fd,6),(char *) RFIFOP(fd,66));
+ return 0;
}
// ACK change of guild emblem
int intif_parse_GuildEmblem(int fd)
{
- guild_emblem_changed(RFIFOW(fd,2)-12,RFIFOL(fd,4),RFIFOL(fd,8), (char *)RFIFOP(fd,12));
- return 0;
+ guild_emblem_changed(RFIFOW(fd,2)-12,RFIFOL(fd,4),RFIFOL(fd,8), (char *)RFIFOP(fd,12));
+ return 0;
}
// ACK guild message
int intif_parse_GuildMessage(int fd)
{
- guild_recv_message(RFIFOL(fd,4),RFIFOL(fd,8),(char *) RFIFOP(fd,12),RFIFOW(fd,2)-12);
- return 0;
+ guild_recv_message(RFIFOL(fd,4),RFIFOL(fd,8),(char *) RFIFOP(fd,12),RFIFOW(fd,2)-12);
+ return 0;
}
// Reply guild castle data request
int intif_parse_GuildCastleDataLoad(int fd)
{
- return guild_castledataloadack(RFIFOW(fd,2), (struct guild_castle *)RFIFOP(fd,4));
+ return guild_castledataloadack(RFIFOW(fd,2), (struct guild_castle *)RFIFOP(fd,4));
}
// ACK change of guildmaster
int intif_parse_GuildMasterChanged(int fd)
{
- return guild_gm_changed(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10));
+ return guild_gm_changed(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10));
}
// Request pet creation
int intif_parse_CreatePet(int fd)
{
- pet_get_egg(RFIFOL(fd,2),RFIFOL(fd,7),RFIFOB(fd,6));
- return 0;
+ pet_get_egg(RFIFOL(fd,2),RFIFOL(fd,7),RFIFOB(fd,6));
+ return 0;
}
// ACK pet data
int intif_parse_RecvPetData(int fd)
{
- struct s_pet p;
- int len;
- len=RFIFOW(fd,2);
- if (sizeof(struct s_pet)!=len-9) {
- if (battle_config.etc_log)
- ShowError("intif: pet data: data size error %d %d\n",sizeof(struct s_pet),len-9);
- } else {
- memcpy(&p,RFIFOP(fd,9),sizeof(struct s_pet));
- pet_recv_petdata(RFIFOL(fd,4),&p,RFIFOB(fd,8));
- }
+ struct s_pet p;
+ int len;
+ len=RFIFOW(fd,2);
+ if(sizeof(struct s_pet)!=len-9) {
+ if(battle_config.etc_log)
+ ShowError("intif: pet data: data size error %d %d\n",sizeof(struct s_pet),len-9);
+ }
+ else{
+ memcpy(&p,RFIFOP(fd,9),sizeof(struct s_pet));
+ pet_recv_petdata(RFIFOL(fd,4),&p,RFIFOB(fd,8));
+ }
- return 0;
+ return 0;
}
// ACK pet save data
int intif_parse_SavePetOk(int fd)
{
- if (RFIFOB(fd,6) == 1)
- ShowError("pet data save failure\n");
+ if(RFIFOB(fd,6) == 1)
+ ShowError("pet data save failure\n");
- return 0;
+ return 0;
}
// ACK deleting pet
int intif_parse_DeletePetOk(int fd)
{
- if (RFIFOB(fd,2) == 1)
- ShowError("pet data delete failure\n");
+ if(RFIFOB(fd,2) == 1)
+ ShowError("pet data delete failure\n");
- return 0;
+ return 0;
}
// ACK changing name resquest, players,pets,hommon
int intif_parse_ChangeNameOk(int fd)
{
- struct map_session_data *sd = NULL;
- if ((sd=map_id2sd(RFIFOL(fd,2)))==NULL ||
- sd->status.char_id != RFIFOL(fd,6))
- return 0;
+ struct map_session_data *sd = NULL;
+ if((sd=map_id2sd(RFIFOL(fd,2)))==NULL ||
+ sd->status.char_id != RFIFOL(fd,6))
+ return 0;
- switch (RFIFOB(fd,10)) {
- case 0: //Players [NOT SUPPORTED YET]
- break;
- case 1: //Pets
- pet_change_name_ack(sd, (char *)RFIFOP(fd,12), RFIFOB(fd,11));
- break;
- case 2: //Hom
- merc_hom_change_name_ack(sd, (char *)RFIFOP(fd,12), RFIFOB(fd,11));
- break;
- }
- return 0;
+ switch (RFIFOB(fd,10)) {
+ case 0: //Players [NOT SUPPORTED YET]
+ break;
+ case 1: //Pets
+ pet_change_name_ack(sd, (char*)RFIFOP(fd,12), RFIFOB(fd,11));
+ break;
+ case 2: //Hom
+ merc_hom_change_name_ack(sd, (char*)RFIFOP(fd,12), RFIFOB(fd,11));
+ break;
+ }
+ return 0;
}
//----------------------------------------------------------------
@@ -1368,46 +1348,46 @@ int intif_parse_ChangeNameOk(int fd)
int intif_parse_CreateHomunculus(int fd)
{
- int len;
- len=RFIFOW(fd,2)-9;
- if (sizeof(struct s_homunculus)!=len) {
- if (battle_config.etc_log)
- ShowError("intif: create homun data: data size error %d != %d\n",sizeof(struct s_homunculus),len);
- return 0;
- }
- merc_hom_recv_data(RFIFOL(fd,4), (struct s_homunculus *)RFIFOP(fd,9), RFIFOB(fd,8)) ;
- return 0;
+ int len;
+ len=RFIFOW(fd,2)-9;
+ if(sizeof(struct s_homunculus)!=len) {
+ if(battle_config.etc_log)
+ ShowError("intif: create homun data: data size error %d != %d\n",sizeof(struct s_homunculus),len);
+ return 0;
+ }
+ merc_hom_recv_data(RFIFOL(fd,4), (struct s_homunculus*)RFIFOP(fd,9), RFIFOB(fd,8)) ;
+ return 0;
}
int intif_parse_RecvHomunculusData(int fd)
{
- int len;
+ int len;
- len=RFIFOW(fd,2)-9;
+ len=RFIFOW(fd,2)-9;
- if (sizeof(struct s_homunculus)!=len) {
- if (battle_config.etc_log)
- ShowError("intif: homun data: data size error %d %d\n",sizeof(struct s_homunculus),len);
- return 0;
- }
- merc_hom_recv_data(RFIFOL(fd,4), (struct s_homunculus *)RFIFOP(fd,9), RFIFOB(fd,8));
- return 0;
+ if(sizeof(struct s_homunculus)!=len) {
+ if(battle_config.etc_log)
+ ShowError("intif: homun data: data size error %d %d\n",sizeof(struct s_homunculus),len);
+ return 0;
+ }
+ merc_hom_recv_data(RFIFOL(fd,4), (struct s_homunculus*)RFIFOP(fd,9), RFIFOB(fd,8));
+ return 0;
}
int intif_parse_SaveHomunculusOk(int fd)
{
- if (RFIFOB(fd,6) != 1)
- ShowError("homunculus data save failure for account %d\n", RFIFOL(fd,2));
+ if(RFIFOB(fd,6) != 1)
+ ShowError("homunculus data save failure for account %d\n", RFIFOL(fd,2));
- return 0;
+ return 0;
}
int intif_parse_DeleteHomunculusOk(int fd)
{
- if (RFIFOB(fd,2) != 1)
- ShowError("Homunculus data delete failure\n");
+ if(RFIFOB(fd,2) != 1)
+ ShowError("Homunculus data delete failure\n");
- return 0;
+ return 0;
}
/**************************************
@@ -1418,80 +1398,82 @@ QUESTLOG SYSTEM FUNCTIONS
int intif_request_questlog(TBL_PC *sd)
{
- WFIFOHEAD(inter_fd,6);
- WFIFOW(inter_fd,0) = 0x3060;
- WFIFOL(inter_fd,2) = sd->status.char_id;
- WFIFOSET(inter_fd,6);
- return 0;
+ WFIFOHEAD(inter_fd,6);
+ WFIFOW(inter_fd,0) = 0x3060;
+ WFIFOL(inter_fd,2) = sd->status.char_id;
+ WFIFOSET(inter_fd,6);
+ return 0;
}
int intif_parse_questlog(int fd)
{
- int char_id = RFIFOL(fd, 4);
- int i;
- TBL_PC *sd = map_charid2sd(char_id);
+ int char_id = RFIFOL(fd, 4);
+ int i;
+ TBL_PC * sd = map_charid2sd(char_id);
- //User not online anymore
- if (!sd)
- return -1;
+ //User not online anymore
+ if(!sd)
+ return -1;
- sd->avail_quests = sd->num_quests = (RFIFOW(fd, 2)-8)/sizeof(struct quest);
+ sd->avail_quests = sd->num_quests = (RFIFOW(fd, 2)-8)/sizeof(struct quest);
- memset(&sd->quest_log, 0, sizeof(sd->quest_log));
+ memset(&sd->quest_log, 0, sizeof(sd->quest_log));
- for (i = 0; i < sd->num_quests; i++) {
- memcpy(&sd->quest_log[i], RFIFOP(fd, i*sizeof(struct quest)+8), sizeof(struct quest));
+ for( i = 0; i < sd->num_quests; i++ )
+ {
+ memcpy(&sd->quest_log[i], RFIFOP(fd, i*sizeof(struct quest)+8), sizeof(struct quest));
- sd->quest_index[i] = quest_search_db(sd->quest_log[i].quest_id);
+ sd->quest_index[i] = quest_search_db(sd->quest_log[i].quest_id);
- if (sd->quest_index[i] < 0) {
- ShowError("intif_parse_questlog: quest %d not found in DB.\n",sd->quest_log[i].quest_id);
- sd->avail_quests--;
- sd->num_quests--;
- i--;
- continue;
- }
+ if( sd->quest_index[i] < 0 )
+ {
+ ShowError("intif_parse_questlog: quest %d not found in DB.\n",sd->quest_log[i].quest_id);
+ sd->avail_quests--;
+ sd->num_quests--;
+ i--;
+ continue;
+ }
- if (sd->quest_log[i].state == Q_COMPLETE)
- sd->avail_quests--;
- }
+ if( sd->quest_log[i].state == Q_COMPLETE )
+ sd->avail_quests--;
+ }
- quest_pc_login(sd);
+ quest_pc_login(sd);
- return 0;
+ return 0;
}
int intif_parse_questsave(int fd)
{
- int cid = RFIFOL(fd, 2);
- TBL_PC *sd = map_id2sd(cid);
+ int cid = RFIFOL(fd, 2);
+ TBL_PC *sd = map_id2sd(cid);
- if (!RFIFOB(fd, 6))
- ShowError("intif_parse_questsave: Failed to save quest(s) for character %d!\n", cid);
- else if (sd)
- sd->save_quest = false;
+ if( !RFIFOB(fd, 6) )
+ ShowError("intif_parse_questsave: Failed to save quest(s) for character %d!\n", cid);
+ else if( sd )
+ sd->save_quest = false;
- return 0;
+ return 0;
}
int intif_quest_save(TBL_PC *sd)
{
- int len;
+ int len;
- if (CheckForCharServer())
- return 0;
+ if(CheckForCharServer())
+ return 0;
- len = sizeof(struct quest)*sd->num_quests + 8;
+ len = sizeof(struct quest)*sd->num_quests + 8;
- WFIFOHEAD(inter_fd, len);
- WFIFOW(inter_fd,0) = 0x3061;
- WFIFOW(inter_fd,2) = len;
- WFIFOL(inter_fd,4) = sd->status.char_id;
- if (sd->num_quests)
- memcpy(WFIFOP(inter_fd,8), &sd->quest_log, sizeof(struct quest)*sd->num_quests);
- WFIFOSET(inter_fd, len);
+ WFIFOHEAD(inter_fd, len);
+ WFIFOW(inter_fd,0) = 0x3061;
+ WFIFOW(inter_fd,2) = len;
+ WFIFOL(inter_fd,4) = sd->status.char_id;
+ if( sd->num_quests )
+ memcpy(WFIFOP(inter_fd,8), &sd->quest_log, sizeof(struct quest)*sd->num_quests);
+ WFIFOSET(inter_fd, len);
- return 0;
+ return 0;
}
/*==========================================
@@ -1505,449 +1487,462 @@ int intif_quest_save(TBL_PC *sd)
*------------------------------------------*/
int intif_Mail_requestinbox(int char_id, unsigned char flag)
{
- if (CheckForCharServer())
- return 0;
+ if (CheckForCharServer())
+ return 0;
- WFIFOHEAD(inter_fd,7);
- WFIFOW(inter_fd,0) = 0x3048;
- WFIFOL(inter_fd,2) = char_id;
- WFIFOB(inter_fd,6) = flag;
- WFIFOSET(inter_fd,7);
+ WFIFOHEAD(inter_fd,7);
+ WFIFOW(inter_fd,0) = 0x3048;
+ WFIFOL(inter_fd,2) = char_id;
+ WFIFOB(inter_fd,6) = flag;
+ WFIFOSET(inter_fd,7);
- return 0;
+ return 0;
}
int intif_parse_Mail_inboxreceived(int fd)
{
- struct map_session_data *sd;
- unsigned char flag = RFIFOB(fd,8);
-
- sd = map_charid2sd(RFIFOL(fd,4));
-
- if (sd == NULL) {
- ShowError("intif_parse_Mail_inboxreceived: char not found %d\n",RFIFOL(fd,4));
- return 1;
- }
-
- if (RFIFOW(fd,2) - 9 != sizeof(struct mail_data)) {
- ShowError("intif_parse_Mail_inboxreceived: data size error %d %d\n", RFIFOW(fd,2) - 9, sizeof(struct mail_data));
- return 1;
- }
-
- //FIXME: this operation is not safe [ultramage]
- memcpy(&sd->mail.inbox, RFIFOP(fd,9), sizeof(struct mail_data));
- sd->mail.changed = false; // cache is now in sync
-
- if (flag)
- clif_Mail_refreshinbox(sd);
- else if (battle_config.mail_show_status && (battle_config.mail_show_status == 1 || sd->mail.inbox.unread)) {
- char output[128];
- sprintf(output, msg_txt(510), sd->mail.inbox.unchecked, sd->mail.inbox.unread + sd->mail.inbox.unchecked);
- clif_disp_onlyself(sd, output, strlen(output));
- }
- return 0;
+ struct map_session_data *sd;
+ unsigned char flag = RFIFOB(fd,8);
+
+ sd = map_charid2sd(RFIFOL(fd,4));
+
+ if (sd == NULL)
+ {
+ ShowError("intif_parse_Mail_inboxreceived: char not found %d\n",RFIFOL(fd,4));
+ return 1;
+ }
+
+ if (RFIFOW(fd,2) - 9 != sizeof(struct mail_data))
+ {
+ ShowError("intif_parse_Mail_inboxreceived: data size error %d %d\n", RFIFOW(fd,2) - 9, sizeof(struct mail_data));
+ return 1;
+ }
+
+ //FIXME: this operation is not safe [ultramage]
+ memcpy(&sd->mail.inbox, RFIFOP(fd,9), sizeof(struct mail_data));
+ sd->mail.changed = false; // cache is now in sync
+
+ if (flag)
+ clif_Mail_refreshinbox(sd);
+ else if( battle_config.mail_show_status && ( battle_config.mail_show_status == 1 || sd->mail.inbox.unread ) )
+ {
+ char output[128];
+ sprintf(output, msg_txt(510), sd->mail.inbox.unchecked, sd->mail.inbox.unread + sd->mail.inbox.unchecked);
+ clif_disp_onlyself(sd, output, strlen(output));
+ }
+ return 0;
}
/*------------------------------------------
* Mail Read
*------------------------------------------*/
int intif_Mail_read(int mail_id)
{
- if (CheckForCharServer())
- return 0;
+ if (CheckForCharServer())
+ return 0;
- WFIFOHEAD(inter_fd,6);
- WFIFOW(inter_fd,0) = 0x3049;
- WFIFOL(inter_fd,2) = mail_id;
- WFIFOSET(inter_fd,6);
+ WFIFOHEAD(inter_fd,6);
+ WFIFOW(inter_fd,0) = 0x3049;
+ WFIFOL(inter_fd,2) = mail_id;
+ WFIFOSET(inter_fd,6);
- return 0;
+ return 0;
}
/*------------------------------------------
* Get Attachment
*------------------------------------------*/
int intif_Mail_getattach(int char_id, int mail_id)
{
- if (CheckForCharServer())
- return 0;
+ if (CheckForCharServer())
+ return 0;
- WFIFOHEAD(inter_fd,10);
- WFIFOW(inter_fd,0) = 0x304a;
- WFIFOL(inter_fd,2) = char_id;
- WFIFOL(inter_fd,6) = mail_id;
- WFIFOSET(inter_fd, 10);
+ WFIFOHEAD(inter_fd,10);
+ WFIFOW(inter_fd,0) = 0x304a;
+ WFIFOL(inter_fd,2) = char_id;
+ WFIFOL(inter_fd,6) = mail_id;
+ WFIFOSET(inter_fd, 10);
- return 0;
+ return 0;
}
int intif_parse_Mail_getattach(int fd)
{
- struct map_session_data *sd;
- struct item item;
- int zeny = RFIFOL(fd,8);
+ struct map_session_data *sd;
+ struct item item;
+ int zeny = RFIFOL(fd,8);
- sd = map_charid2sd(RFIFOL(fd,4));
+ sd = map_charid2sd( RFIFOL(fd,4) );
- if (sd == NULL) {
- ShowError("intif_parse_Mail_getattach: char not found %d\n",RFIFOL(fd,4));
- return 1;
- }
+ if (sd == NULL)
+ {
+ ShowError("intif_parse_Mail_getattach: char not found %d\n",RFIFOL(fd,4));
+ return 1;
+ }
- if (RFIFOW(fd,2) - 12 != sizeof(struct item)) {
- ShowError("intif_parse_Mail_getattach: data size error %d %d\n", RFIFOW(fd,2) - 16, sizeof(struct item));
- return 1;
- }
+ if (RFIFOW(fd,2) - 12 != sizeof(struct item))
+ {
+ ShowError("intif_parse_Mail_getattach: data size error %d %d\n", RFIFOW(fd,2) - 16, sizeof(struct item));
+ return 1;
+ }
- memcpy(&item, RFIFOP(fd,12), sizeof(struct item));
+ memcpy(&item, RFIFOP(fd,12), sizeof(struct item));
- mail_getattachment(sd, zeny, &item);
- return 0;
+ mail_getattachment(sd, zeny, &item);
+ return 0;
}
/*------------------------------------------
* Delete Message
*------------------------------------------*/
int intif_Mail_delete(int char_id, int mail_id)
{
- if (CheckForCharServer())
- return 0;
+ if (CheckForCharServer())
+ return 0;
- WFIFOHEAD(inter_fd,10);
- WFIFOW(inter_fd,0) = 0x304b;
- WFIFOL(inter_fd,2) = char_id;
- WFIFOL(inter_fd,6) = mail_id;
- WFIFOSET(inter_fd,10);
+ WFIFOHEAD(inter_fd,10);
+ WFIFOW(inter_fd,0) = 0x304b;
+ WFIFOL(inter_fd,2) = char_id;
+ WFIFOL(inter_fd,6) = mail_id;
+ WFIFOSET(inter_fd,10);
- return 0;
+ return 0;
}
int intif_parse_Mail_delete(int fd)
{
- int char_id = RFIFOL(fd,2);
- int mail_id = RFIFOL(fd,6);
- bool failed = RFIFOB(fd,10);
-
- struct map_session_data *sd = map_charid2sd(char_id);
- if (sd == NULL) {
- ShowError("intif_parse_Mail_delete: char not found %d\n", char_id);
- return 1;
- }
-
- if (!failed) {
- int i;
- ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id);
- if (i < MAIL_MAX_INBOX) {
- memset(&sd->mail.inbox.msg[i], 0, sizeof(struct mail_message));
- sd->mail.inbox.amount--;
- }
-
- if (sd->mail.inbox.full)
- intif_Mail_requestinbox(sd->status.char_id, 1); // Free space is available for new mails
- }
-
- clif_Mail_delete(sd->fd, mail_id, failed);
- return 0;
+ int char_id = RFIFOL(fd,2);
+ int mail_id = RFIFOL(fd,6);
+ bool failed = RFIFOB(fd,10);
+
+ struct map_session_data *sd = map_charid2sd(char_id);
+ if (sd == NULL)
+ {
+ ShowError("intif_parse_Mail_delete: char not found %d\n", char_id);
+ return 1;
+ }
+
+ if (!failed)
+ {
+ int i;
+ ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id);
+ if( i < MAIL_MAX_INBOX )
+ {
+ memset(&sd->mail.inbox.msg[i], 0, sizeof(struct mail_message));
+ sd->mail.inbox.amount--;
+ }
+
+ if( sd->mail.inbox.full )
+ intif_Mail_requestinbox(sd->status.char_id, 1); // Free space is available for new mails
+ }
+
+ clif_Mail_delete(sd->fd, mail_id, failed);
+ return 0;
}
/*------------------------------------------
* Return Message
*------------------------------------------*/
int intif_Mail_return(int char_id, int mail_id)
{
- if (CheckForCharServer())
- return 0;
+ if (CheckForCharServer())
+ return 0;
- WFIFOHEAD(inter_fd,10);
- WFIFOW(inter_fd,0) = 0x304c;
- WFIFOL(inter_fd,2) = char_id;
- WFIFOL(inter_fd,6) = mail_id;
- WFIFOSET(inter_fd,10);
+ WFIFOHEAD(inter_fd,10);
+ WFIFOW(inter_fd,0) = 0x304c;
+ WFIFOL(inter_fd,2) = char_id;
+ WFIFOL(inter_fd,6) = mail_id;
+ WFIFOSET(inter_fd,10);
- return 0;
+ return 0;
}
int intif_parse_Mail_return(int fd)
{
- struct map_session_data *sd = map_charid2sd(RFIFOL(fd,2));
- int mail_id = RFIFOL(fd,6);
- short fail = RFIFOB(fd,10);
-
- if (sd == NULL) {
- ShowError("intif_parse_Mail_return: char not found %d\n",RFIFOL(fd,2));
- return 1;
- }
-
- if (!fail) {
- int i;
- ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id);
- if (i < MAIL_MAX_INBOX) {
- memset(&sd->mail.inbox.msg[i], 0, sizeof(struct mail_message));
- sd->mail.inbox.amount--;
- }
-
- if (sd->mail.inbox.full)
- intif_Mail_requestinbox(sd->status.char_id, 1); // Free space is available for new mails
- }
-
- clif_Mail_return(sd->fd, mail_id, fail);
- return 0;
+ struct map_session_data *sd = map_charid2sd(RFIFOL(fd,2));
+ int mail_id = RFIFOL(fd,6);
+ short fail = RFIFOB(fd,10);
+
+ if( sd == NULL )
+ {
+ ShowError("intif_parse_Mail_return: char not found %d\n",RFIFOL(fd,2));
+ return 1;
+ }
+
+ if( !fail )
+ {
+ int i;
+ ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id);
+ if( i < MAIL_MAX_INBOX )
+ {
+ memset(&sd->mail.inbox.msg[i], 0, sizeof(struct mail_message));
+ sd->mail.inbox.amount--;
+ }
+
+ if( sd->mail.inbox.full )
+ intif_Mail_requestinbox(sd->status.char_id, 1); // Free space is available for new mails
+ }
+
+ clif_Mail_return(sd->fd, mail_id, fail);
+ return 0;
}
/*------------------------------------------
* Send Mail
*------------------------------------------*/
int intif_Mail_send(int account_id, struct mail_message *msg)
{
- int len = sizeof(struct mail_message) + 8;
+ int len = sizeof(struct mail_message) + 8;
- if (CheckForCharServer())
- return 0;
+ if (CheckForCharServer())
+ return 0;
- WFIFOHEAD(inter_fd,len);
- WFIFOW(inter_fd,0) = 0x304d;
- WFIFOW(inter_fd,2) = len;
- WFIFOL(inter_fd,4) = account_id;
- memcpy(WFIFOP(inter_fd,8), msg, sizeof(struct mail_message));
- WFIFOSET(inter_fd,len);
+ WFIFOHEAD(inter_fd,len);
+ WFIFOW(inter_fd,0) = 0x304d;
+ WFIFOW(inter_fd,2) = len;
+ WFIFOL(inter_fd,4) = account_id;
+ memcpy(WFIFOP(inter_fd,8), msg, sizeof(struct mail_message));
+ WFIFOSET(inter_fd,len);
- return 1;
+ return 1;
}
static void intif_parse_Mail_send(int fd)
{
- struct mail_message msg;
- struct map_session_data *sd;
- bool fail;
-
- if (RFIFOW(fd,2) - 4 != sizeof(struct mail_message)) {
- ShowError("intif_parse_Mail_send: data size error %d %d\n", RFIFOW(fd,2) - 4, sizeof(struct mail_message));
- return;
- }
-
- memcpy(&msg, RFIFOP(fd,4), sizeof(struct mail_message));
- fail = (msg.id == 0);
-
- // notify sender
- sd = map_charid2sd(msg.send_id);
- if (sd != NULL) {
- if (fail)
- mail_deliveryfail(sd, &msg);
- else {
- clif_Mail_send(sd->fd, false);
- if (save_settings&16)
- chrif_save(sd, 0);
- }
- }
+ struct mail_message msg;
+ struct map_session_data *sd;
+ bool fail;
+
+ if( RFIFOW(fd,2) - 4 != sizeof(struct mail_message) )
+ {
+ ShowError("intif_parse_Mail_send: data size error %d %d\n", RFIFOW(fd,2) - 4, sizeof(struct mail_message));
+ return;
+ }
+
+ memcpy(&msg, RFIFOP(fd,4), sizeof(struct mail_message));
+ fail = (msg.id == 0);
+
+ // notify sender
+ sd = map_charid2sd(msg.send_id);
+ if( sd != NULL )
+ {
+ if( fail )
+ mail_deliveryfail(sd, &msg);
+ else
+ {
+ clif_Mail_send(sd->fd, false);
+ if( save_settings&16 )
+ chrif_save(sd, 0);
+ }
+ }
}
static void intif_parse_Mail_new(int fd)
{
- struct map_session_data *sd = map_charid2sd(RFIFOL(fd,2));
- int mail_id = RFIFOL(fd,6);
- const char *sender_name = (char *)RFIFOP(fd,10);
- const char *title = (char *)RFIFOP(fd,34);
+ struct map_session_data *sd = map_charid2sd(RFIFOL(fd,2));
+ int mail_id = RFIFOL(fd,6);
+ const char* sender_name = (char*)RFIFOP(fd,10);
+ const char* title = (char*)RFIFOP(fd,34);
- if (sd == NULL)
- return;
+ if( sd == NULL )
+ return;
- sd->mail.changed = true;
- clif_Mail_new(sd->fd, mail_id, sender_name, title);
+ sd->mail.changed = true;
+ clif_Mail_new(sd->fd, mail_id, sender_name, title);
}
/*==========================================
* AUCTION SYSTEM
* By Zephyrus
*==========================================*/
-int intif_Auction_requestlist(int char_id, short type, int price, const char *searchtext, short page)
+int intif_Auction_requestlist(int char_id, short type, int price, const char* searchtext, short page)
{
- int len = NAME_LENGTH + 16;
+ int len = NAME_LENGTH + 16;
- if (CheckForCharServer())
- return 0;
+ if( CheckForCharServer() )
+ return 0;
- WFIFOHEAD(inter_fd,len);
- WFIFOW(inter_fd,0) = 0x3050;
- WFIFOW(inter_fd,2) = len;
- WFIFOL(inter_fd,4) = char_id;
- WFIFOW(inter_fd,8) = type;
- WFIFOL(inter_fd,10) = price;
- WFIFOW(inter_fd,14) = page;
- memcpy(WFIFOP(inter_fd,16), searchtext, NAME_LENGTH);
- WFIFOSET(inter_fd,len);
+ WFIFOHEAD(inter_fd,len);
+ WFIFOW(inter_fd,0) = 0x3050;
+ WFIFOW(inter_fd,2) = len;
+ WFIFOL(inter_fd,4) = char_id;
+ WFIFOW(inter_fd,8) = type;
+ WFIFOL(inter_fd,10) = price;
+ WFIFOW(inter_fd,14) = page;
+ memcpy(WFIFOP(inter_fd,16), searchtext, NAME_LENGTH);
+ WFIFOSET(inter_fd,len);
- return 0;
+ return 0;
}
static void intif_parse_Auction_results(int fd)
{
- struct map_session_data *sd = map_charid2sd(RFIFOL(fd,4));
- short count = RFIFOW(fd,8);
- short pages = RFIFOW(fd,10);
- uint8 *data = RFIFOP(fd,12);
+ struct map_session_data *sd = map_charid2sd(RFIFOL(fd,4));
+ short count = RFIFOW(fd,8);
+ short pages = RFIFOW(fd,10);
+ uint8* data = RFIFOP(fd,12);
- if (sd == NULL)
- return;
+ if( sd == NULL )
+ return;
- clif_Auction_results(sd, count, pages, data);
+ clif_Auction_results(sd, count, pages, data);
}
int intif_Auction_register(struct auction_data *auction)
{
- int len = sizeof(struct auction_data) + 4;
+ int len = sizeof(struct auction_data) + 4;
- if (CheckForCharServer())
- return 0;
+ if( CheckForCharServer() )
+ return 0;
- WFIFOHEAD(inter_fd,len);
- WFIFOW(inter_fd,0) = 0x3051;
- WFIFOW(inter_fd,2) = len;
- memcpy(WFIFOP(inter_fd,4), auction, sizeof(struct auction_data));
- WFIFOSET(inter_fd,len);
+ WFIFOHEAD(inter_fd,len);
+ WFIFOW(inter_fd,0) = 0x3051;
+ WFIFOW(inter_fd,2) = len;
+ memcpy(WFIFOP(inter_fd,4), auction, sizeof(struct auction_data));
+ WFIFOSET(inter_fd,len);
- return 1;
+ return 1;
}
static void intif_parse_Auction_register(int fd)
{
- struct map_session_data *sd;
- struct auction_data auction;
+ struct map_session_data *sd;
+ struct auction_data auction;
- if (RFIFOW(fd,2) - 4 != sizeof(struct auction_data)) {
- ShowError("intif_parse_Auction_register: data size error %d %d\n", RFIFOW(fd,2) - 4, sizeof(struct auction_data));
- return;
- }
+ if( RFIFOW(fd,2) - 4 != sizeof(struct auction_data) )
+ {
+ ShowError("intif_parse_Auction_register: data size error %d %d\n", RFIFOW(fd,2) - 4, sizeof(struct auction_data));
+ return;
+ }
- memcpy(&auction, RFIFOP(fd,4), sizeof(struct auction_data));
- if ((sd = map_charid2sd(auction.seller_id)) == NULL)
- return;
+ memcpy(&auction, RFIFOP(fd,4), sizeof(struct auction_data));
+ if( (sd = map_charid2sd(auction.seller_id)) == NULL )
+ return;
- if (auction.auction_id > 0) {
- clif_Auction_message(sd->fd, 1); // Confirmation Packet ??
- if (save_settings&32)
- chrif_save(sd,0);
- } else {
- int zeny = auction.hours*battle_config.auction_feeperhour;
+ if( auction.auction_id > 0 )
+ {
+ clif_Auction_message(sd->fd, 1); // Confirmation Packet ??
+ if( save_settings&32 )
+ chrif_save(sd,0);
+ }
+ else
+ {
+ int zeny = auction.hours*battle_config.auction_feeperhour;
- clif_Auction_message(sd->fd, 4);
- pc_additem(sd, &auction.item, auction.item.amount, LOG_TYPE_AUCTION);
+ clif_Auction_message(sd->fd, 4);
+ pc_additem(sd, &auction.item, auction.item.amount, LOG_TYPE_AUCTION);
- pc_getzeny(sd, zeny, LOG_TYPE_AUCTION, NULL);
- }
+ pc_getzeny(sd, zeny, LOG_TYPE_AUCTION, NULL);
+ }
}
int intif_Auction_cancel(int char_id, unsigned int auction_id)
{
- if (CheckForCharServer())
- return 0;
+ if( CheckForCharServer() )
+ return 0;
- WFIFOHEAD(inter_fd,10);
- WFIFOW(inter_fd,0) = 0x3052;
- WFIFOL(inter_fd,2) = char_id;
- WFIFOL(inter_fd,6) = auction_id;
- WFIFOSET(inter_fd,10);
+ WFIFOHEAD(inter_fd,10);
+ WFIFOW(inter_fd,0) = 0x3052;
+ WFIFOL(inter_fd,2) = char_id;
+ WFIFOL(inter_fd,6) = auction_id;
+ WFIFOSET(inter_fd,10);
- return 0;
+ return 0;
}
static void intif_parse_Auction_cancel(int fd)
{
- struct map_session_data *sd = map_charid2sd(RFIFOL(fd,2));
- int result = RFIFOB(fd,6);
+ struct map_session_data *sd = map_charid2sd(RFIFOL(fd,2));
+ int result = RFIFOB(fd,6);
- if (sd == NULL)
- return;
+ if( sd == NULL )
+ return;
- switch (result) {
- case 0:
- clif_Auction_message(sd->fd, 2);
- break;
- case 1:
- clif_Auction_close(sd->fd, 2);
- break;
- case 2:
- clif_Auction_close(sd->fd, 1);
- break;
- case 3:
- clif_Auction_message(sd->fd, 3);
- break;
- }
+ switch( result )
+ {
+ case 0: clif_Auction_message(sd->fd, 2); break;
+ case 1: clif_Auction_close(sd->fd, 2); break;
+ case 2: clif_Auction_close(sd->fd, 1); break;
+ case 3: clif_Auction_message(sd->fd, 3); break;
+ }
}
int intif_Auction_close(int char_id, unsigned int auction_id)
{
- if (CheckForCharServer())
- return 0;
+ if( CheckForCharServer() )
+ return 0;
- WFIFOHEAD(inter_fd,10);
- WFIFOW(inter_fd,0) = 0x3053;
- WFIFOL(inter_fd,2) = char_id;
- WFIFOL(inter_fd,6) = auction_id;
- WFIFOSET(inter_fd,10);
+ WFIFOHEAD(inter_fd,10);
+ WFIFOW(inter_fd,0) = 0x3053;
+ WFIFOL(inter_fd,2) = char_id;
+ WFIFOL(inter_fd,6) = auction_id;
+ WFIFOSET(inter_fd,10);
- return 0;
+ return 0;
}
static void intif_parse_Auction_close(int fd)
{
- struct map_session_data *sd = map_charid2sd(RFIFOL(fd,2));
- unsigned char result = RFIFOB(fd,6);
+ struct map_session_data *sd = map_charid2sd(RFIFOL(fd,2));
+ unsigned char result = RFIFOB(fd,6);
- if (sd == NULL)
- return;
+ if( sd == NULL )
+ return;
- clif_Auction_close(sd->fd, result);
- if (result == 0) {
- // FIXME: Leeching off a parse function
- clif_parse_Auction_cancelreg(fd, sd);
- intif_Auction_requestlist(sd->status.char_id, 6, 0, "", 1);
- }
+ clif_Auction_close(sd->fd, result);
+ if( result == 0 )
+ {
+ // FIXME: Leeching off a parse function
+ clif_parse_Auction_cancelreg(fd, sd);
+ intif_Auction_requestlist(sd->status.char_id, 6, 0, "", 1);
+ }
}
-int intif_Auction_bid(int char_id, const char *name, unsigned int auction_id, int bid)
+int intif_Auction_bid(int char_id, const char* name, unsigned int auction_id, int bid)
{
- int len = 16 + NAME_LENGTH;
+ int len = 16 + NAME_LENGTH;
- if (CheckForCharServer())
- return 0;
+ if( CheckForCharServer() )
+ return 0;
- WFIFOHEAD(inter_fd,len);
- WFIFOW(inter_fd,0) = 0x3055;
- WFIFOW(inter_fd,2) = len;
- WFIFOL(inter_fd,4) = char_id;
- WFIFOL(inter_fd,8) = auction_id;
- WFIFOL(inter_fd,12) = bid;
- memcpy(WFIFOP(inter_fd,16), name, NAME_LENGTH);
- WFIFOSET(inter_fd,len);
+ WFIFOHEAD(inter_fd,len);
+ WFIFOW(inter_fd,0) = 0x3055;
+ WFIFOW(inter_fd,2) = len;
+ WFIFOL(inter_fd,4) = char_id;
+ WFIFOL(inter_fd,8) = auction_id;
+ WFIFOL(inter_fd,12) = bid;
+ memcpy(WFIFOP(inter_fd,16), name, NAME_LENGTH);
+ WFIFOSET(inter_fd,len);
- return 0;
+ return 0;
}
static void intif_parse_Auction_bid(int fd)
{
- struct map_session_data *sd = map_charid2sd(RFIFOL(fd,2));
- int bid = RFIFOL(fd,6);
- unsigned char result = RFIFOB(fd,10);
+ struct map_session_data *sd = map_charid2sd(RFIFOL(fd,2));
+ int bid = RFIFOL(fd,6);
+ unsigned char result = RFIFOB(fd,10);
- if (sd == NULL)
- return;
+ if( sd == NULL )
+ return;
- clif_Auction_message(sd->fd, result);
- if (bid > 0) {
- pc_getzeny(sd, bid, LOG_TYPE_AUCTION,NULL);
- }
- if (result == 1) {
- // To update the list, display your buy list
- clif_parse_Auction_cancelreg(fd, sd);
- intif_Auction_requestlist(sd->status.char_id, 7, 0, "", 1);
- }
+ clif_Auction_message(sd->fd, result);
+ if( bid > 0 )
+ {
+ pc_getzeny(sd, bid, LOG_TYPE_AUCTION,NULL);
+ }
+ if( result == 1 )
+ { // To update the list, display your buy list
+ clif_parse_Auction_cancelreg(fd, sd);
+ intif_Auction_requestlist(sd->status.char_id, 7, 0, "", 1);
+ }
}
// Used to send 'You have won the auction' and 'You failed to won the auction' messages
static void intif_parse_Auction_message(int fd)
{
- struct map_session_data *sd = map_charid2sd(RFIFOL(fd,2));
- unsigned char result = RFIFOB(fd,6);
+ struct map_session_data *sd = map_charid2sd(RFIFOL(fd,2));
+ unsigned char result = RFIFOB(fd,6);
- if (sd == NULL)
- return;
+ if( sd == NULL )
+ return;
- clif_Auction_message(sd->fd, result);
+ clif_Auction_message(sd->fd, result);
}
/*==========================================
@@ -1955,86 +1950,87 @@ static void intif_parse_Auction_message(int fd)
*------------------------------------------*/
int intif_mercenary_create(struct s_mercenary *merc)
{
- int size = sizeof(struct s_mercenary) + 4;
+ int size = sizeof(struct s_mercenary) + 4;
- if (CheckForCharServer())
- return 0;
+ if( CheckForCharServer() )
+ return 0;
- WFIFOHEAD(inter_fd,size);
- WFIFOW(inter_fd,0) = 0x3070;
- WFIFOW(inter_fd,2) = size;
- memcpy(WFIFOP(inter_fd,4), merc, sizeof(struct s_mercenary));
- WFIFOSET(inter_fd,size);
- return 0;
+ WFIFOHEAD(inter_fd,size);
+ WFIFOW(inter_fd,0) = 0x3070;
+ WFIFOW(inter_fd,2) = size;
+ memcpy(WFIFOP(inter_fd,4), merc, sizeof(struct s_mercenary));
+ WFIFOSET(inter_fd,size);
+ return 0;
}
int intif_parse_mercenary_received(int fd)
{
- int len = RFIFOW(fd,2) - 5;
- if (sizeof(struct s_mercenary) != len) {
- if (battle_config.etc_log)
- ShowError("intif: create mercenary data size error %d != %d\n", sizeof(struct s_mercenary), len);
- return 0;
- }
+ int len = RFIFOW(fd,2) - 5;
+ if( sizeof(struct s_mercenary) != len )
+ {
+ if( battle_config.etc_log )
+ ShowError("intif: create mercenary data size error %d != %d\n", sizeof(struct s_mercenary), len);
+ return 0;
+ }
- merc_data_received((struct s_mercenary *)RFIFOP(fd,5), RFIFOB(fd,4));
- return 0;
+ merc_data_received((struct s_mercenary*)RFIFOP(fd,5), RFIFOB(fd,4));
+ return 0;
}
int intif_mercenary_request(int merc_id, int char_id)
{
- if (CheckForCharServer())
- return 0;
+ if (CheckForCharServer())
+ return 0;
- WFIFOHEAD(inter_fd,10);
- WFIFOW(inter_fd,0) = 0x3071;
- WFIFOL(inter_fd,2) = merc_id;
- WFIFOL(inter_fd,6) = char_id;
- WFIFOSET(inter_fd,10);
- return 0;
+ WFIFOHEAD(inter_fd,10);
+ WFIFOW(inter_fd,0) = 0x3071;
+ WFIFOL(inter_fd,2) = merc_id;
+ WFIFOL(inter_fd,6) = char_id;
+ WFIFOSET(inter_fd,10);
+ return 0;
}
int intif_mercenary_delete(int merc_id)
{
- if (CheckForCharServer())
- return 0;
+ if (CheckForCharServer())
+ return 0;
- WFIFOHEAD(inter_fd,6);
- WFIFOW(inter_fd,0) = 0x3072;
- WFIFOL(inter_fd,2) = merc_id;
- WFIFOSET(inter_fd,6);
- return 0;
+ WFIFOHEAD(inter_fd,6);
+ WFIFOW(inter_fd,0) = 0x3072;
+ WFIFOL(inter_fd,2) = merc_id;
+ WFIFOSET(inter_fd,6);
+ return 0;
}
int intif_parse_mercenary_deleted(int fd)
{
- if (RFIFOB(fd,2) != 1)
- ShowError("Mercenary data delete failure\n");
+ if( RFIFOB(fd,2) != 1 )
+ ShowError("Mercenary data delete failure\n");
- return 0;
+ return 0;
}
int intif_mercenary_save(struct s_mercenary *merc)
{
- int size = sizeof(struct s_mercenary) + 4;
+ int size = sizeof(struct s_mercenary) + 4;
- if (CheckForCharServer())
- return 0;
+ if( CheckForCharServer() )
+ return 0;
- WFIFOHEAD(inter_fd,size);
- WFIFOW(inter_fd,0) = 0x3073;
- WFIFOW(inter_fd,2) = size;
- memcpy(WFIFOP(inter_fd,4), merc, sizeof(struct s_mercenary));
- WFIFOSET(inter_fd,size);
- return 0;
+ WFIFOHEAD(inter_fd,size);
+ WFIFOW(inter_fd,0) = 0x3073;
+ WFIFOW(inter_fd,2) = size;
+ memcpy(WFIFOP(inter_fd,4), merc, sizeof(struct s_mercenary));
+ WFIFOSET(inter_fd,size);
+ return 0;
}
int intif_parse_mercenary_saved(int fd)
{
- if (RFIFOB(fd,2) != 1)
- ShowError("Mercenary data save failure\n");
+ if( RFIFOB(fd,2) != 1 )
+ ShowError("Mercenary data save failure\n");
- return 0;
+ return 0;
}
/*==========================================
@@ -2042,122 +2038,121 @@ int intif_parse_mercenary_saved(int fd)
*------------------------------------------*/
int intif_elemental_create(struct s_elemental *ele)
{
- int size = sizeof(struct s_elemental) + 4;
+ int size = sizeof(struct s_elemental) + 4;
- if (CheckForCharServer())
- return 0;
+ if( CheckForCharServer() )
+ return 0;
- WFIFOHEAD(inter_fd,size);
- WFIFOW(inter_fd,0) = 0x307c;
- WFIFOW(inter_fd,2) = size;
- memcpy(WFIFOP(inter_fd,4), ele, sizeof(struct s_elemental));
- WFIFOSET(inter_fd,size);
- return 0;
+ WFIFOHEAD(inter_fd,size);
+ WFIFOW(inter_fd,0) = 0x307c;
+ WFIFOW(inter_fd,2) = size;
+ memcpy(WFIFOP(inter_fd,4), ele, sizeof(struct s_elemental));
+ WFIFOSET(inter_fd,size);
+ return 0;
}
int intif_parse_elemental_received(int fd)
{
- int len = RFIFOW(fd,2) - 5;
- if (sizeof(struct s_elemental) != len) {
- if (battle_config.etc_log)
- ShowError("intif: create elemental data size error %d != %d\n", sizeof(struct s_elemental), len);
- return 0;
- }
+ int len = RFIFOW(fd,2) - 5;
+ if( sizeof(struct s_elemental) != len )
+ {
+ if( battle_config.etc_log )
+ ShowError("intif: create elemental data size error %d != %d\n", sizeof(struct s_elemental), len);
+ return 0;
+ }
- elemental_data_received((struct s_elemental *)RFIFOP(fd,5), RFIFOB(fd,4));
- return 0;
+ elemental_data_received((struct s_elemental*)RFIFOP(fd,5), RFIFOB(fd,4));
+ return 0;
}
int intif_elemental_request(int ele_id, int char_id)
{
- if (CheckForCharServer())
- return 0;
+ if (CheckForCharServer())
+ return 0;
- WFIFOHEAD(inter_fd,10);
- WFIFOW(inter_fd,0) = 0x307d;
- WFIFOL(inter_fd,2) = ele_id;
- WFIFOL(inter_fd,6) = char_id;
- WFIFOSET(inter_fd,10);
- return 0;
+ WFIFOHEAD(inter_fd,10);
+ WFIFOW(inter_fd,0) = 0x307d;
+ WFIFOL(inter_fd,2) = ele_id;
+ WFIFOL(inter_fd,6) = char_id;
+ WFIFOSET(inter_fd,10);
+ return 0;
}
int intif_elemental_delete(int ele_id)
{
- if (CheckForCharServer())
- return 0;
+ if (CheckForCharServer())
+ return 0;
- WFIFOHEAD(inter_fd,6);
- WFIFOW(inter_fd,0) = 0x307e;
- WFIFOL(inter_fd,2) = ele_id;
- WFIFOSET(inter_fd,6);
- return 0;
+ WFIFOHEAD(inter_fd,6);
+ WFIFOW(inter_fd,0) = 0x307e;
+ WFIFOL(inter_fd,2) = ele_id;
+ WFIFOSET(inter_fd,6);
+ return 0;
}
int intif_parse_elemental_deleted(int fd)
{
- if (RFIFOB(fd,2) != 1)
- ShowError("Elemental data delete failure\n");
+ if( RFIFOB(fd,2) != 1 )
+ ShowError("Elemental data delete failure\n");
- return 0;
+ return 0;
}
int intif_elemental_save(struct s_elemental *ele)
{
- int size = sizeof(struct s_elemental) + 4;
+ int size = sizeof(struct s_elemental) + 4;
- if (CheckForCharServer())
- return 0;
+ if( CheckForCharServer() )
+ return 0;
- WFIFOHEAD(inter_fd,size);
- WFIFOW(inter_fd,0) = 0x307f;
- WFIFOW(inter_fd,2) = size;
- memcpy(WFIFOP(inter_fd,4), ele, sizeof(struct s_elemental));
- WFIFOSET(inter_fd,size);
- return 0;
+ WFIFOHEAD(inter_fd,size);
+ WFIFOW(inter_fd,0) = 0x307f;
+ WFIFOW(inter_fd,2) = size;
+ memcpy(WFIFOP(inter_fd,4), ele, sizeof(struct s_elemental));
+ WFIFOSET(inter_fd,size);
+ return 0;
}
int intif_parse_elemental_saved(int fd)
{
- if (RFIFOB(fd,2) != 1)
- ShowError("Elemental data save failure\n");
+ if( RFIFOB(fd,2) != 1 )
+ ShowError("Elemental data save failure\n");
- return 0;
+ return 0;
}
-void intif_request_accinfo(int u_fd, int aid, int group_id, char *query)
-{
+void intif_request_accinfo( int u_fd, int aid, int group_id, char* query ) {
- WFIFOHEAD(inter_fd,2 + 4 + 4 + 4 + NAME_LENGTH);
+ WFIFOHEAD(inter_fd,2 + 4 + 4 + 4 + NAME_LENGTH);
- WFIFOW(inter_fd,0) = 0x3007;
- WFIFOL(inter_fd,2) = u_fd;
- WFIFOL(inter_fd,6) = aid;
- WFIFOL(inter_fd,10) = group_id;
- safestrncpy((char *)WFIFOP(inter_fd,14), query, NAME_LENGTH);
+ WFIFOW(inter_fd,0) = 0x3007;
+ WFIFOL(inter_fd,2) = u_fd;
+ WFIFOL(inter_fd,6) = aid;
+ WFIFOL(inter_fd,10) = group_id;
+ safestrncpy(WFIFOP(inter_fd,14), query, NAME_LENGTH);
- WFIFOSET(inter_fd,2 + 4 + 4 + 4 + NAME_LENGTH);
+ WFIFOSET(inter_fd,2 + 4 + 4 + 4 + NAME_LENGTH);
- return;
+ return;
}
-void intif_parse_MessageToFD(int fd)
-{
- int u_fd = RFIFOL(fd,4);
+void intif_parse_MessageToFD(int fd) {
+ int u_fd = RFIFOL(fd,4);
- if (session[u_fd] && session[u_fd]->session_data) {
- int aid = RFIFOL(fd,8);
- struct map_session_data *sd = session[u_fd]->session_data;
- /* matching e.g. previous fd owner didn't dc during request or is still the same */
- if (sd->bl.id == aid) {
- char msg[512];
- safestrncpy(msg, (char *)RFIFOP(fd,12), RFIFOW(fd,2) - 12);
- clif_displaymessage(u_fd,msg);
- }
+ if( session[u_fd] && session[u_fd]->session_data ) {
+ int aid = RFIFOL(fd,8);
+ struct map_session_data * sd = session[u_fd]->session_data;
+ /* matching e.g. previous fd owner didn't dc during request or is still the same */
+ if( sd->bl.id == aid ) {
+ char msg[512];
+ safestrncpy(msg, (char*)RFIFOP(fd,12), RFIFOW(fd,2) - 12);
+ clif_displaymessage(u_fd,msg);
+ }
- }
+ }
- return;
+ return;
}
//-----------------------------------------------------------------
@@ -2166,227 +2161,107 @@ void intif_parse_MessageToFD(int fd)
// 1, 2 if there are not enough to return the length of the packet if the packet processing
int intif_parse(int fd)
{
- int packet_len, cmd;
- cmd = RFIFOW(fd,0);
+ int packet_len, cmd;
+ cmd = RFIFOW(fd,0);
// Verify ID of the packet
- if (cmd<0x3800 || cmd>=0x3800+(sizeof(packet_len_table)/sizeof(packet_len_table[0])) ||
- packet_len_table[cmd-0x3800]==0) {
- return 0;
- }
+ if(cmd<0x3800 || cmd>=0x3800+(sizeof(packet_len_table)/sizeof(packet_len_table[0])) ||
+ packet_len_table[cmd-0x3800]==0){
+ return 0;
+ }
// Check the length of the packet
- packet_len = packet_len_table[cmd-0x3800];
- if (packet_len==-1) {
- if (RFIFOREST(fd)<4)
- return 2;
- packet_len = RFIFOW(fd,2);
- }
- if ((int)RFIFOREST(fd)<packet_len) {
- return 2;
- }
+ packet_len = packet_len_table[cmd-0x3800];
+ if(packet_len==-1){
+ if(RFIFOREST(fd)<4)
+ return 2;
+ packet_len = RFIFOW(fd,2);
+ }
+ if((int)RFIFOREST(fd)<packet_len){
+ return 2;
+ }
// Processing branch
- switch (cmd) {
- case 0x3800:
- if (RFIFOL(fd,4) == 0xFF000000) //Normal announce.
- clif_broadcast(NULL, (char *) RFIFOP(fd,16), packet_len-16, 0, ALL_CLIENT);
- else if (RFIFOL(fd,4) == 0xFE000000) //Main chat message [LuzZza]
- clif_MainChatMessage((char *)RFIFOP(fd,16));
- else //Color announce.
- clif_broadcast2(NULL, (char *) RFIFOP(fd,16), packet_len-16, RFIFOL(fd,4), RFIFOW(fd,8), RFIFOW(fd,10), RFIFOW(fd,12), RFIFOW(fd,14), ALL_CLIENT);
- break;
- case 0x3801:
- intif_parse_WisMessage(fd);
- break;
- case 0x3802:
- intif_parse_WisEnd(fd);
- break;
- case 0x3803:
- mapif_parse_WisToGM(fd);
- break;
- case 0x3804:
- intif_parse_Registers(fd);
- break;
- case 0x3806:
- intif_parse_ChangeNameOk(fd);
- break;
- case 0x3807:
- intif_parse_MessageToFD(fd);
- break;
- case 0x3818:
- intif_parse_LoadGuildStorage(fd);
- break;
- case 0x3819:
- intif_parse_SaveGuildStorage(fd);
- break;
- case 0x3820:
- intif_parse_PartyCreated(fd);
- break;
- case 0x3821:
- intif_parse_PartyInfo(fd);
- break;
- case 0x3822:
- intif_parse_PartyMemberAdded(fd);
- break;
- case 0x3823:
- intif_parse_PartyOptionChanged(fd);
- break;
- case 0x3824:
- intif_parse_PartyMemberWithdraw(fd);
- break;
- case 0x3825:
- intif_parse_PartyMove(fd);
- break;
- case 0x3826:
- intif_parse_PartyBroken(fd);
- break;
- case 0x3827:
- intif_parse_PartyMessage(fd);
- break;
- case 0x3830:
- intif_parse_GuildCreated(fd);
- break;
- case 0x3831:
- intif_parse_GuildInfo(fd);
- break;
- case 0x3832:
- intif_parse_GuildMemberAdded(fd);
- break;
- case 0x3834:
- intif_parse_GuildMemberWithdraw(fd);
- break;
- case 0x3835:
- intif_parse_GuildMemberInfoShort(fd);
- break;
- case 0x3836:
- intif_parse_GuildBroken(fd);
- break;
- case 0x3837:
- intif_parse_GuildMessage(fd);
- break;
- case 0x3839:
- intif_parse_GuildBasicInfoChanged(fd);
- break;
- case 0x383a:
- intif_parse_GuildMemberInfoChanged(fd);
- break;
- case 0x383b:
- intif_parse_GuildPosition(fd);
- break;
- case 0x383c:
- intif_parse_GuildSkillUp(fd);
- break;
- case 0x383d:
- intif_parse_GuildAlliance(fd);
- break;
- case 0x383e:
- intif_parse_GuildNotice(fd);
- break;
- case 0x383f:
- intif_parse_GuildEmblem(fd);
- break;
- case 0x3840:
- intif_parse_GuildCastleDataLoad(fd);
- break;
- case 0x3843:
- intif_parse_GuildMasterChanged(fd);
- break;
-
- //Quest system
- case 0x3860:
- intif_parse_questlog(fd);
- break;
- case 0x3861:
- intif_parse_questsave(fd);
- break;
-
- // Mail System
- case 0x3848:
- intif_parse_Mail_inboxreceived(fd);
- break;
- case 0x3849:
- intif_parse_Mail_new(fd);
- break;
- case 0x384a:
- intif_parse_Mail_getattach(fd);
- break;
- case 0x384b:
- intif_parse_Mail_delete(fd);
- break;
- case 0x384c:
- intif_parse_Mail_return(fd);
- break;
- case 0x384d:
- intif_parse_Mail_send(fd);
- break;
- // Auction System
- case 0x3850:
- intif_parse_Auction_results(fd);
- break;
- case 0x3851:
- intif_parse_Auction_register(fd);
- break;
- case 0x3852:
- intif_parse_Auction_cancel(fd);
- break;
- case 0x3853:
- intif_parse_Auction_close(fd);
- break;
- case 0x3854:
- intif_parse_Auction_message(fd);
- break;
- case 0x3855:
- intif_parse_Auction_bid(fd);
- break;
-
- // Mercenary System
- case 0x3870:
- intif_parse_mercenary_received(fd);
- break;
- case 0x3871:
- intif_parse_mercenary_deleted(fd);
- break;
- case 0x3872:
- intif_parse_mercenary_saved(fd);
- break;
- // Elemental System
- case 0x387c:
- intif_parse_elemental_received(fd);
- break;
- case 0x387d:
- intif_parse_elemental_deleted(fd);
- break;
- case 0x387e:
- intif_parse_elemental_saved(fd);
- break;
-
- case 0x3880:
- intif_parse_CreatePet(fd);
- break;
- case 0x3881:
- intif_parse_RecvPetData(fd);
- break;
- case 0x3882:
- intif_parse_SavePetOk(fd);
- break;
- case 0x3883:
- intif_parse_DeletePetOk(fd);
- break;
- case 0x3890:
- intif_parse_CreateHomunculus(fd);
- break;
- case 0x3891:
- intif_parse_RecvHomunculusData(fd);
- break;
- case 0x3892:
- intif_parse_SaveHomunculusOk(fd);
- break;
- case 0x3893:
- intif_parse_DeleteHomunculusOk(fd);
- break;
- default:
- ShowError("intif_parse : unknown packet %d %x\n",fd,RFIFOW(fd,0));
- return 0;
- }
+ switch(cmd){
+ case 0x3800:
+ if (RFIFOL(fd,4) == 0xFF000000) //Normal announce.
+ clif_broadcast(NULL, (char *) RFIFOP(fd,16), packet_len-16, 0, ALL_CLIENT);
+ else if (RFIFOL(fd,4) == 0xFE000000) //Main chat message [LuzZza]
+ clif_MainChatMessage((char *)RFIFOP(fd,16));
+ else //Color announce.
+ clif_broadcast2(NULL, (char *) RFIFOP(fd,16), packet_len-16, RFIFOL(fd,4), RFIFOW(fd,8), RFIFOW(fd,10), RFIFOW(fd,12), RFIFOW(fd,14), ALL_CLIENT);
+ break;
+ case 0x3801: intif_parse_WisMessage(fd); break;
+ case 0x3802: intif_parse_WisEnd(fd); break;
+ case 0x3803: mapif_parse_WisToGM(fd); break;
+ case 0x3804: intif_parse_Registers(fd); break;
+ case 0x3806: intif_parse_ChangeNameOk(fd); break;
+ case 0x3807: intif_parse_MessageToFD(fd); break;
+ case 0x3818: intif_parse_LoadGuildStorage(fd); break;
+ case 0x3819: intif_parse_SaveGuildStorage(fd); break;
+ case 0x3820: intif_parse_PartyCreated(fd); break;
+ case 0x3821: intif_parse_PartyInfo(fd); break;
+ case 0x3822: intif_parse_PartyMemberAdded(fd); break;
+ case 0x3823: intif_parse_PartyOptionChanged(fd); break;
+ case 0x3824: intif_parse_PartyMemberWithdraw(fd); break;
+ case 0x3825: intif_parse_PartyMove(fd); break;
+ case 0x3826: intif_parse_PartyBroken(fd); break;
+ case 0x3827: intif_parse_PartyMessage(fd); break;
+ case 0x3830: intif_parse_GuildCreated(fd); break;
+ case 0x3831: intif_parse_GuildInfo(fd); break;
+ case 0x3832: intif_parse_GuildMemberAdded(fd); break;
+ case 0x3834: intif_parse_GuildMemberWithdraw(fd); break;
+ case 0x3835: intif_parse_GuildMemberInfoShort(fd); break;
+ case 0x3836: intif_parse_GuildBroken(fd); break;
+ case 0x3837: intif_parse_GuildMessage(fd); break;
+ case 0x3839: intif_parse_GuildBasicInfoChanged(fd); break;
+ case 0x383a: intif_parse_GuildMemberInfoChanged(fd); break;
+ case 0x383b: intif_parse_GuildPosition(fd); break;
+ case 0x383c: intif_parse_GuildSkillUp(fd); break;
+ case 0x383d: intif_parse_GuildAlliance(fd); break;
+ case 0x383e: intif_parse_GuildNotice(fd); break;
+ case 0x383f: intif_parse_GuildEmblem(fd); break;
+ case 0x3840: intif_parse_GuildCastleDataLoad(fd); break;
+ case 0x3843: intif_parse_GuildMasterChanged(fd); break;
+
+ //Quest system
+ case 0x3860: intif_parse_questlog(fd); break;
+ case 0x3861: intif_parse_questsave(fd); break;
+
+// Mail System
+ case 0x3848: intif_parse_Mail_inboxreceived(fd); break;
+ case 0x3849: intif_parse_Mail_new(fd); break;
+ case 0x384a: intif_parse_Mail_getattach(fd); break;
+ case 0x384b: intif_parse_Mail_delete(fd); break;
+ case 0x384c: intif_parse_Mail_return(fd); break;
+ case 0x384d: intif_parse_Mail_send(fd); break;
+// Auction System
+ case 0x3850: intif_parse_Auction_results(fd); break;
+ case 0x3851: intif_parse_Auction_register(fd); break;
+ case 0x3852: intif_parse_Auction_cancel(fd); break;
+ case 0x3853: intif_parse_Auction_close(fd); break;
+ case 0x3854: intif_parse_Auction_message(fd); break;
+ case 0x3855: intif_parse_Auction_bid(fd); break;
+
+// Mercenary System
+ case 0x3870: intif_parse_mercenary_received(fd); break;
+ case 0x3871: intif_parse_mercenary_deleted(fd); break;
+ case 0x3872: intif_parse_mercenary_saved(fd); break;
+// Elemental System
+ case 0x387c: intif_parse_elemental_received(fd); break;
+ case 0x387d: intif_parse_elemental_deleted(fd); break;
+ case 0x387e: intif_parse_elemental_saved(fd); break;
+
+ case 0x3880: intif_parse_CreatePet(fd); break;
+ case 0x3881: intif_parse_RecvPetData(fd); break;
+ case 0x3882: intif_parse_SavePetOk(fd); break;
+ case 0x3883: intif_parse_DeletePetOk(fd); break;
+ case 0x3890: intif_parse_CreateHomunculus(fd); break;
+ case 0x3891: intif_parse_RecvHomunculusData(fd); break;
+ case 0x3892: intif_parse_SaveHomunculusOk(fd); break;
+ case 0x3893: intif_parse_DeleteHomunculusOk(fd); break;
+ default:
+ ShowError("intif_parse : unknown packet %d %x\n",fd,RFIFOW(fd,0));
+ return 0;
+ }
// Skip packet
- RFIFOSKIP(fd,packet_len);
- return 1;
+ RFIFOSKIP(fd,packet_len);
+ return 1;
}
diff --git a/src/map/intif.h b/src/map/intif.h
index 623f37ba0..081667545 100644
--- a/src/map/intif.h
+++ b/src/map/intif.h
@@ -17,9 +17,9 @@ struct auction_data;
int intif_parse(int fd);
-int intif_broadcast(const char *mes, int len, int type);
-int intif_broadcast2(const char *mes, int len, unsigned long fontColor, short fontType, short fontSize, short fontAlign, short fontY);
-int intif_main_message(struct map_session_data *sd, const char *message);
+int intif_broadcast(const char* mes, int len, int type);
+int intif_broadcast2(const char* mes, int len, unsigned long fontColor, short fontType, short fontSize, short fontAlign, short fontY);
+int intif_main_message(struct map_session_data* sd, const char* message);
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 permission, char *mes);
@@ -50,7 +50,7 @@ int intif_guild_leave(int guild_id, int account_id, int char_id, int flag, const
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, const char *mes, int len);
-int intif_guild_change_gm(int guild_id, const char *name, int len);
+int intif_guild_change_gm(int guild_id, const char* name, int len);
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);
int intif_guild_position(int guild_id, int idx, struct guild_position *p);
@@ -72,12 +72,12 @@ int intif_rename(struct map_session_data *sd, int type, char *name);
#define intif_rename_hom(sd, name) intif_rename(sd, 2, name)
int intif_homunculus_create(int account_id, struct s_homunculus *sh);
int intif_homunculus_requestload(int account_id, int homun_id);
-int intif_homunculus_requestsave(int account_id, struct s_homunculus *sh);
+int intif_homunculus_requestsave(int account_id, struct s_homunculus* sh);
int intif_homunculus_requestdelete(int homun_id);
/******QUEST SYTEM*******/
-int intif_request_questlog(struct map_session_data *sd);
-int intif_quest_save(struct map_session_data *sd);
+int intif_request_questlog(struct map_session_data * sd);
+int intif_quest_save(struct map_session_data * sd);
// MERCENARY SYSTEM
int intif_mercenary_create(struct s_mercenary *merc);
@@ -93,11 +93,11 @@ int intif_Mail_delete(int char_id, int mail_id);
int intif_Mail_return(int char_id, int mail_id);
int intif_Mail_send(int account_id, struct mail_message *msg);
// AUCTION SYSTEM
-int intif_Auction_requestlist(int char_id, short type, int price, const char *searchtext, short page);
+int intif_Auction_requestlist(int char_id, short type, int price, const char* searchtext, short page);
int intif_Auction_register(struct auction_data *auction);
int intif_Auction_cancel(int char_id, unsigned int auction_id);
int intif_Auction_close(int char_id, unsigned int auction_id);
-int intif_Auction_bid(int char_id, const char *name, unsigned int auction_id, int bid);
+int intif_Auction_bid(int char_id, const char* name, unsigned int auction_id, int bid);
// ELEMENTAL SYSTEM
int intif_elemental_create(struct s_elemental *ele);
int intif_elemental_request(int ele_id, int char_id);
@@ -105,7 +105,7 @@ int intif_elemental_delete(int ele_id);
int intif_elemental_save(struct s_elemental *ele);
/* @accinfo */
-void intif_request_accinfo(int u_fd, int aid, int group_id, char *query);
+void intif_request_accinfo( int u_fd, int aid, int group_id, char* query );
int CheckForCharServer(void);
diff --git a/src/map/itemdb.c b/src/map/itemdb.c
index 18f8f5c07..e0c964de3 100644
--- a/src/map/itemdb.c
+++ b/src/map/itemdb.c
@@ -17,64 +17,66 @@
#include <stdlib.h>
#include <string.h>
-static struct item_data *itemdb_array[MAX_ITEMDB];
-static DBMap *itemdb_other;// int nameid -> struct item_data*
+static struct item_data* itemdb_array[MAX_ITEMDB];
+static DBMap* itemdb_other;// int nameid -> struct item_data*
static struct item_group itemgroup_db[MAX_ITEMGROUP];
struct item_data dummy_item; //This is the default dummy item used for non-existant items. [Skotlex]
/**
- * Search for item name
+ * Search for item name
* name = item alias, so we should find items aliases first. if not found then look for "jname" (full name)
* @see DBApply
*/
static int itemdb_searchname_sub(DBKey key, DBData *data, va_list ap)
{
- struct item_data *item = db_data2ptr(data), **dst, **dst2;
- char *str;
- str=va_arg(ap,char *);
- dst=va_arg(ap,struct item_data **);
- dst2=va_arg(ap,struct item_data **);
- if (item == &dummy_item) return 0;
-
- //Absolute priority to Aegis code name.
- if (*dst != NULL) return 0;
- if (strcmpi(item->name,str)==0)
- *dst=item;
-
- //Second priority to Client displayed name.
- if (*dst2 != NULL) return 0;
- if (strcmpi(item->jname,str)==0)
- *dst2=item;
- return 0;
+ struct item_data *item = db_data2ptr(data), **dst, **dst2;
+ char *str;
+ str=va_arg(ap,char *);
+ dst=va_arg(ap,struct item_data **);
+ dst2=va_arg(ap,struct item_data **);
+ if(item == &dummy_item) return 0;
+
+ //Absolute priority to Aegis code name.
+ if (*dst != NULL) return 0;
+ if( strcmpi(item->name,str)==0 )
+ *dst=item;
+
+ //Second priority to Client displayed name.
+ if (*dst2 != NULL) return 0;
+ if( strcmpi(item->jname,str)==0 )
+ *dst2=item;
+ return 0;
}
/*==========================================
- * Return item data from item name. (lookup)
+ * Return item data from item name. (lookup)
*------------------------------------------*/
-struct item_data *itemdb_searchname(const char *str) {
- struct item_data *item;
- struct item_data *item2=NULL;
- int i;
-
- for (i = 0; i < ARRAYLENGTH(itemdb_array); ++i) {
- item = itemdb_array[i];
- if (item == NULL)
- continue;
-
- // Absolute priority to Aegis code name.
- if (strcasecmp(item->name,str) == 0)
- return item;
-
- //Second priority to Client displayed name.
- if (strcasecmp(item->jname,str) == 0)
- item2 = item;
- }
-
- item = NULL;
- itemdb_other->foreach(itemdb_other,itemdb_searchname_sub,str,&item,&item2);
- return item?item:item2;
+struct item_data* itemdb_searchname(const char *str)
+{
+ struct item_data* item;
+ struct item_data* item2=NULL;
+ int i;
+
+ for( i = 0; i < ARRAYLENGTH(itemdb_array); ++i )
+ {
+ item = itemdb_array[i];
+ if( item == NULL )
+ continue;
+
+ // Absolute priority to Aegis code name.
+ if( strcasecmp(item->name,str) == 0 )
+ return item;
+
+ //Second priority to Client displayed name.
+ if( strcasecmp(item->jname,str) == 0 )
+ item2 = item;
+ }
+
+ item = NULL;
+ itemdb_other->foreach(itemdb_other,itemdb_searchname_sub,str,&item,&item2);
+ return item?item:item2;
}
/**
@@ -82,258 +84,258 @@ struct item_data *itemdb_searchname(const char *str) {
*/
static int itemdb_searchname_array_sub(DBKey key, DBData data, va_list ap)
{
- struct item_data *item = db_data2ptr(&data);
- char *str;
- str=va_arg(ap,char *);
- if (item == &dummy_item)
- return 1; //Invalid item.
- if (stristr(item->jname,str))
- return 0;
- if (stristr(item->name,str))
- return 0;
- return strcmpi(item->jname,str);
+ struct item_data *item = db_data2ptr(&data);
+ char *str;
+ str=va_arg(ap,char *);
+ if (item == &dummy_item)
+ return 1; //Invalid item.
+ if(stristr(item->jname,str))
+ return 0;
+ if(stristr(item->name,str))
+ return 0;
+ return strcmpi(item->jname,str);
}
/*==========================================
* Founds up to N matches. Returns number of matches [Skotlex]
*------------------------------------------*/
-int itemdb_searchname_array(struct item_data **data, int size, const char *str)
+int itemdb_searchname_array(struct item_data** data, int size, const char *str)
{
- struct item_data *item;
- int i;
- int count=0;
-
- // Search in the array
- for (i = 0; i < ARRAYLENGTH(itemdb_array); ++i) {
- item = itemdb_array[i];
- if (item == NULL)
- continue;
-
- if (stristr(item->jname,str) || stristr(item->name,str)) {
- if (count < size)
- data[count] = item;
- ++count;
- }
- }
-
- // search in the db
- if (count < size) {
- DBData *db_data[MAX_SEARCH];
- int db_count = 0;
- size -= count;
- db_count = itemdb_other->getall(itemdb_other, (DBData **)&db_data, size, itemdb_searchname_array_sub, str);
- for (i = 0; i < db_count; i++)
- data[count++] = db_data2ptr(db_data[i]);
- count += db_count;
- }
- return count;
+ struct item_data* item;
+ int i;
+ int count=0;
+
+ // Search in the array
+ for( i = 0; i < ARRAYLENGTH(itemdb_array); ++i )
+ {
+ item = itemdb_array[i];
+ if( item == NULL )
+ continue;
+
+ if( stristr(item->jname,str) || stristr(item->name,str) )
+ {
+ if( count < size )
+ data[count] = item;
+ ++count;
+ }
+ }
+
+ // search in the db
+ if( count < size )
+ {
+ DBData *db_data[MAX_SEARCH];
+ int db_count = 0;
+ size -= count;
+ db_count = itemdb_other->getall(itemdb_other, (DBData**)&db_data, size, itemdb_searchname_array_sub, str);
+ for (i = 0; i < db_count; i++)
+ data[count++] = db_data2ptr(db_data[i]);
+ count += db_count;
+ }
+ return count;
}
/*==========================================
- * Return a random item id from group. (takes into account % chance giving/tot group)
+ * Return a random item id from group. (takes into account % chance giving/tot group)
*------------------------------------------*/
int itemdb_searchrandomid(int group)
{
- if (group<1 || group>=MAX_ITEMGROUP) {
- ShowError("itemdb_searchrandomid: Invalid group id %d\n", group);
- return UNKNOWN_ITEM_ID;
- }
- if (itemgroup_db[group].qty)
- return itemgroup_db[group].nameid[rnd()%itemgroup_db[group].qty];
-
- ShowError("itemdb_searchrandomid: No item entries for group id %d\n", group);
- return UNKNOWN_ITEM_ID;
+ if(group<1 || group>=MAX_ITEMGROUP) {
+ ShowError("itemdb_searchrandomid: Invalid group id %d\n", group);
+ return UNKNOWN_ITEM_ID;
+ }
+ if (itemgroup_db[group].qty)
+ return itemgroup_db[group].nameid[rnd()%itemgroup_db[group].qty];
+
+ ShowError("itemdb_searchrandomid: No item entries for group id %d\n", group);
+ return UNKNOWN_ITEM_ID;
}
/*==========================================
* Calculates total item-group related bonuses for the given item
*------------------------------------------*/
-int itemdb_group_bonus(struct map_session_data *sd, int itemid)
+int itemdb_group_bonus(struct map_session_data* sd, int itemid)
{
- int bonus = 0, i, j;
- for (i=0; i < MAX_ITEMGROUP; i++) {
- if (!sd->itemgrouphealrate[i])
- continue;
- ARR_FIND(0, itemgroup_db[i].qty, j, itemgroup_db[i].nameid[j] == itemid);
- if (j < itemgroup_db[i].qty)
- bonus += sd->itemgrouphealrate[i];
- }
- return bonus;
+ int bonus = 0, i, j;
+ for (i=0; i < MAX_ITEMGROUP; i++) {
+ if (!sd->itemgrouphealrate[i])
+ continue;
+ ARR_FIND( 0, itemgroup_db[i].qty, j, itemgroup_db[i].nameid[j] == itemid );
+ if( j < itemgroup_db[i].qty )
+ bonus += sd->itemgrouphealrate[i];
+ }
+ return bonus;
}
/// Searches for the item_data.
/// Returns the item_data or NULL if it does not exist.
-struct item_data *itemdb_exists(int nameid) {
- struct item_data *item;
-
- if (nameid >= 0 && nameid < ARRAYLENGTH(itemdb_array))
- return itemdb_array[nameid];
- item = (struct item_data *)idb_get(itemdb_other,nameid);
- if (item == &dummy_item)
- return NULL;// dummy data, doesn't exist
- return item;
+struct item_data* itemdb_exists(int nameid)
+{
+ struct item_data* item;
+
+ if( nameid >= 0 && nameid < ARRAYLENGTH(itemdb_array) )
+ return itemdb_array[nameid];
+ item = (struct item_data*)idb_get(itemdb_other,nameid);
+ if( item == &dummy_item )
+ return NULL;// dummy data, doesn't exist
+ return item;
}
/// Returns human readable name for given item type.
/// @param type Type id to retrieve name for ( IT_* ).
-const char *itemdb_typename(int type)
+const char* itemdb_typename(int type)
{
- switch (type) {
- case IT_HEALING:
- return "Potion/Food";
- case IT_USABLE:
- return "Usable";
- case IT_ETC:
- return "Etc.";
- case IT_WEAPON:
- return "Weapon";
- case IT_ARMOR:
- return "Armor";
- case IT_CARD:
- return "Card";
- case IT_PETEGG:
- return "Pet Egg";
- case IT_PETARMOR:
- return "Pet Accessory";
- case IT_AMMO:
- return "Arrow/Ammunition";
- case IT_DELAYCONSUME:
- return "Delay-Consume Usable";
- case IT_CASH:
- return "Cash Usable";
- }
- return "Unknown Type";
+ switch(type)
+ {
+ case IT_HEALING: return "Potion/Food";
+ case IT_USABLE: return "Usable";
+ case IT_ETC: return "Etc.";
+ case IT_WEAPON: return "Weapon";
+ case IT_ARMOR: return "Armor";
+ case IT_CARD: return "Card";
+ case IT_PETEGG: return "Pet Egg";
+ case IT_PETARMOR: return "Pet Accessory";
+ case IT_AMMO: return "Arrow/Ammunition";
+ case IT_DELAYCONSUME: return "Delay-Consume Usable";
+ case IT_CASH: return "Cash Usable";
+ }
+ return "Unknown Type";
}
/*==========================================
- * Converts the jobid from the format in itemdb
+ * Converts the jobid from the format in itemdb
* to the format used by the map server. [Skotlex]
*------------------------------------------*/
static void itemdb_jobid2mapid(unsigned int *bclass, unsigned int jobmask)
{
- int i;
- bclass[0]= bclass[1]= bclass[2]= 0;
- //Base classes
- if (jobmask & 1<<JOB_NOVICE) {
- //Both Novice/Super-Novice are counted with the same ID
- bclass[0] |= 1<<MAPID_NOVICE;
- bclass[1] |= 1<<MAPID_NOVICE;
- }
- for (i = JOB_NOVICE+1; i <= JOB_THIEF; i++) {
- if (jobmask & 1<<i)
- bclass[0] |= 1<<(MAPID_NOVICE+i);
- }
- //2-1 classes
- if (jobmask & 1<<JOB_KNIGHT)
- bclass[1] |= 1<<MAPID_SWORDMAN;
- if (jobmask & 1<<JOB_PRIEST)
- bclass[1] |= 1<<MAPID_ACOLYTE;
- if (jobmask & 1<<JOB_WIZARD)
- bclass[1] |= 1<<MAPID_MAGE;
- if (jobmask & 1<<JOB_BLACKSMITH)
- bclass[1] |= 1<<MAPID_MERCHANT;
- if (jobmask & 1<<JOB_HUNTER)
- bclass[1] |= 1<<MAPID_ARCHER;
- if (jobmask & 1<<JOB_ASSASSIN)
- bclass[1] |= 1<<MAPID_THIEF;
- //2-2 classes
- if (jobmask & 1<<JOB_CRUSADER)
- bclass[2] |= 1<<MAPID_SWORDMAN;
- if (jobmask & 1<<JOB_MONK)
- bclass[2] |= 1<<MAPID_ACOLYTE;
- if (jobmask & 1<<JOB_SAGE)
- bclass[2] |= 1<<MAPID_MAGE;
- if (jobmask & 1<<JOB_ALCHEMIST)
- bclass[2] |= 1<<MAPID_MERCHANT;
- if (jobmask & 1<<JOB_BARD)
- bclass[2] |= 1<<MAPID_ARCHER;
- // Bard/Dancer share the same slot now.
- // if (jobmask & 1<<JOB_DANCER)
- // bclass[2] |= 1<<MAPID_ARCHER;
- if (jobmask & 1<<JOB_ROGUE)
- bclass[2] |= 1<<MAPID_THIEF;
- //Special classes that don't fit above.
- if (jobmask & 1<<21) //Taekwon boy
- bclass[0] |= 1<<MAPID_TAEKWON;
- if (jobmask & 1<<22) //Star Gladiator
- bclass[1] |= 1<<MAPID_TAEKWON;
- if (jobmask & 1<<23) //Soul Linker
- bclass[2] |= 1<<MAPID_TAEKWON;
- if (jobmask & 1<<JOB_GUNSLINGER)
- bclass[0] |= 1<<MAPID_GUNSLINGER;
- if (jobmask & 1<<JOB_NINJA) {
- bclass[0] |= 1<<MAPID_NINJA;
- bclass[1] |= 1<<MAPID_NINJA;
- }//Kagerou/Oboro jobs can equip Ninja equips. [Rytech]
- if (jobmask & 1<<26) //Bongun/Munak
- bclass[0] |= 1<<MAPID_GANGSI;
- if (jobmask & 1<<27) //Death Knight
- bclass[1] |= 1<<MAPID_GANGSI;
- if (jobmask & 1<<28) //Dark Collector
- bclass[2] |= 1<<MAPID_GANGSI;
- if (jobmask & 1<<29) //Kagerou / Oboro
- bclass[1] |= 1<<MAPID_NINJA;
+ int i;
+ bclass[0]= bclass[1]= bclass[2]= 0;
+ //Base classes
+ if (jobmask & 1<<JOB_NOVICE)
+ { //Both Novice/Super-Novice are counted with the same ID
+ bclass[0] |= 1<<MAPID_NOVICE;
+ bclass[1] |= 1<<MAPID_NOVICE;
+ }
+ for (i = JOB_NOVICE+1; i <= JOB_THIEF; i++)
+ {
+ if (jobmask & 1<<i)
+ bclass[0] |= 1<<(MAPID_NOVICE+i);
+ }
+ //2-1 classes
+ if (jobmask & 1<<JOB_KNIGHT)
+ bclass[1] |= 1<<MAPID_SWORDMAN;
+ if (jobmask & 1<<JOB_PRIEST)
+ bclass[1] |= 1<<MAPID_ACOLYTE;
+ if (jobmask & 1<<JOB_WIZARD)
+ bclass[1] |= 1<<MAPID_MAGE;
+ if (jobmask & 1<<JOB_BLACKSMITH)
+ bclass[1] |= 1<<MAPID_MERCHANT;
+ if (jobmask & 1<<JOB_HUNTER)
+ bclass[1] |= 1<<MAPID_ARCHER;
+ if (jobmask & 1<<JOB_ASSASSIN)
+ bclass[1] |= 1<<MAPID_THIEF;
+ //2-2 classes
+ if (jobmask & 1<<JOB_CRUSADER)
+ bclass[2] |= 1<<MAPID_SWORDMAN;
+ if (jobmask & 1<<JOB_MONK)
+ bclass[2] |= 1<<MAPID_ACOLYTE;
+ if (jobmask & 1<<JOB_SAGE)
+ bclass[2] |= 1<<MAPID_MAGE;
+ if (jobmask & 1<<JOB_ALCHEMIST)
+ bclass[2] |= 1<<MAPID_MERCHANT;
+ if (jobmask & 1<<JOB_BARD)
+ bclass[2] |= 1<<MAPID_ARCHER;
+// Bard/Dancer share the same slot now.
+// if (jobmask & 1<<JOB_DANCER)
+// bclass[2] |= 1<<MAPID_ARCHER;
+ if (jobmask & 1<<JOB_ROGUE)
+ bclass[2] |= 1<<MAPID_THIEF;
+ //Special classes that don't fit above.
+ if (jobmask & 1<<21) //Taekwon boy
+ bclass[0] |= 1<<MAPID_TAEKWON;
+ if (jobmask & 1<<22) //Star Gladiator
+ bclass[1] |= 1<<MAPID_TAEKWON;
+ if (jobmask & 1<<23) //Soul Linker
+ bclass[2] |= 1<<MAPID_TAEKWON;
+ if (jobmask & 1<<JOB_GUNSLINGER)
+ bclass[0] |= 1<<MAPID_GUNSLINGER;
+ if (jobmask & 1<<JOB_NINJA)
+ {bclass[0] |= 1<<MAPID_NINJA;
+ bclass[1] |= 1<<MAPID_NINJA;}//Kagerou/Oboro jobs can equip Ninja equips. [Rytech]
+ if (jobmask & 1<<26) //Bongun/Munak
+ bclass[0] |= 1<<MAPID_GANGSI;
+ if (jobmask & 1<<27) //Death Knight
+ bclass[1] |= 1<<MAPID_GANGSI;
+ if (jobmask & 1<<28) //Dark Collector
+ bclass[2] |= 1<<MAPID_GANGSI;
+ if (jobmask & 1<<29) //Kagerou / Oboro
+ bclass[1] |= 1<<MAPID_NINJA;
}
static void create_dummy_data(void)
{
- memset(&dummy_item, 0, sizeof(struct item_data));
- dummy_item.nameid=500;
- dummy_item.weight=1;
- dummy_item.value_sell=1;
- dummy_item.type=IT_ETC; //Etc item
- safestrncpy(dummy_item.name,"UNKNOWN_ITEM",sizeof(dummy_item.name));
- safestrncpy(dummy_item.jname,"UNKNOWN_ITEM",sizeof(dummy_item.jname));
- dummy_item.view_id=UNKNOWN_ITEM_ID;
+ memset(&dummy_item, 0, sizeof(struct item_data));
+ dummy_item.nameid=500;
+ dummy_item.weight=1;
+ dummy_item.value_sell=1;
+ dummy_item.type=IT_ETC; //Etc item
+ safestrncpy(dummy_item.name,"UNKNOWN_ITEM",sizeof(dummy_item.name));
+ safestrncpy(dummy_item.jname,"UNKNOWN_ITEM",sizeof(dummy_item.jname));
+ dummy_item.view_id=UNKNOWN_ITEM_ID;
}
-static struct item_data *create_item_data(int nameid) {
- struct item_data *id;
- CREATE(id, struct item_data, 1);
- id->nameid = nameid;
- id->weight = 1;
- id->type = IT_ETC;
- return id;
+static struct item_data* create_item_data(int nameid)
+{
+ struct item_data *id;
+ CREATE(id, struct item_data, 1);
+ id->nameid = nameid;
+ id->weight = 1;
+ id->type = IT_ETC;
+ return id;
}
/*==========================================
* Loads (and creates if not found) an item from the db.
*------------------------------------------*/
-struct item_data *itemdb_load(int nameid) {
- struct item_data *id;
-
- if (nameid >= 0 && nameid < ARRAYLENGTH(itemdb_array)) {
- id = itemdb_array[nameid];
- if (id == NULL || id == &dummy_item)
- id = itemdb_array[nameid] = create_item_data(nameid);
- return id;
- }
-
- id = (struct item_data *)idb_get(itemdb_other, nameid);
- if (id == NULL || id == &dummy_item) {
- id = create_item_data(nameid);
- idb_put(itemdb_other, nameid, id);
- }
- return id;
+struct item_data* itemdb_load(int nameid)
+{
+ struct item_data *id;
+
+ if( nameid >= 0 && nameid < ARRAYLENGTH(itemdb_array) )
+ {
+ id = itemdb_array[nameid];
+ if( id == NULL || id == &dummy_item )
+ id = itemdb_array[nameid] = create_item_data(nameid);
+ return id;
+ }
+
+ id = (struct item_data*)idb_get(itemdb_other, nameid);
+ if( id == NULL || id == &dummy_item )
+ {
+ id = create_item_data(nameid);
+ idb_put(itemdb_other, nameid, id);
+ }
+ return id;
}
/*==========================================
* Loads an item from the db. If not found, it will return the dummy item.
*------------------------------------------*/
-struct item_data *itemdb_search(int nameid) {
- struct item_data *id;
- if (nameid >= 0 && nameid < ARRAYLENGTH(itemdb_array))
- id = itemdb_array[nameid];
- else
- id = (struct item_data *)idb_get(itemdb_other, nameid);
-
- if (id == NULL) {
- ShowWarning("itemdb_search: Item ID %d does not exists in the item_db. Using dummy data.\n", nameid);
- id = &dummy_item;
- dummy_item.nameid = nameid;
- }
- return id;
+struct item_data* itemdb_search(int nameid)
+{
+ struct item_data* id;
+ if( nameid >= 0 && nameid < ARRAYLENGTH(itemdb_array) )
+ id = itemdb_array[nameid];
+ else
+ id = (struct item_data*)idb_get(itemdb_other, nameid);
+
+ if( id == NULL )
+ {
+ ShowWarning("itemdb_search: Item ID %d does not exists in the item_db. Using dummy data.\n", nameid);
+ id = &dummy_item;
+ dummy_item.nameid = nameid;
+ }
+ return id;
}
/*==========================================
@@ -341,31 +343,31 @@ struct item_data *itemdb_search(int nameid) {
*------------------------------------------*/
int itemdb_isequip(int nameid)
{
- int type=itemdb_type(nameid);
- switch (type) {
- case IT_WEAPON:
- case IT_ARMOR:
- case IT_AMMO:
- return 1;
- default:
- return 0;
- }
+ int type=itemdb_type(nameid);
+ switch (type) {
+ case IT_WEAPON:
+ case IT_ARMOR:
+ case IT_AMMO:
+ return 1;
+ default:
+ return 0;
+ }
}
/*==========================================
* Alternate version of itemdb_isequip
*------------------------------------------*/
int itemdb_isequip2(struct item_data *data)
-{
- nullpo_ret(data);
- switch (data->type) {
- case IT_WEAPON:
- case IT_ARMOR:
- case IT_AMMO:
- return 1;
- default:
- return 0;
- }
+{
+ nullpo_ret(data);
+ switch(data->type) {
+ case IT_WEAPON:
+ case IT_ARMOR:
+ case IT_AMMO:
+ return 1;
+ default:
+ return 0;
+ }
}
/*==========================================
@@ -373,16 +375,16 @@ int itemdb_isequip2(struct item_data *data)
*------------------------------------------*/
int itemdb_isstackable(int nameid)
{
- int type=itemdb_type(nameid);
- switch (type) {
- case IT_WEAPON:
- case IT_ARMOR:
- case IT_PETEGG:
- case IT_PETARMOR:
- return 0;
- default:
- return 1;
- }
+ int type=itemdb_type(nameid);
+ switch(type) {
+ case IT_WEAPON:
+ case IT_ARMOR:
+ case IT_PETEGG:
+ case IT_PETARMOR:
+ return 0;
+ default:
+ return 1;
+ }
}
/*==========================================
@@ -390,515 +392,513 @@ int itemdb_isstackable(int nameid)
*------------------------------------------*/
int itemdb_isstackable2(struct item_data *data)
{
- nullpo_ret(data);
- switch (data->type) {
- case IT_WEAPON:
- case IT_ARMOR:
- case IT_PETEGG:
- case IT_PETARMOR:
- return 0;
- default:
- return 1;
- }
+ nullpo_ret(data);
+ switch(data->type) {
+ case IT_WEAPON:
+ case IT_ARMOR:
+ case IT_PETEGG:
+ case IT_PETARMOR:
+ return 0;
+ default:
+ return 1;
+ }
}
/*==========================================
* Trade Restriction functions [Skotlex]
*------------------------------------------*/
-int itemdb_isdropable_sub(struct item_data *item, int gmlv, int unused)
-{
- return (item && (!(item->flag.trade_restriction&1) || gmlv >= item->gm_lv_trade_override));
+int itemdb_isdropable_sub(struct item_data *item, int gmlv, int unused) {
+ return (item && (!(item->flag.trade_restriction&1) || gmlv >= item->gm_lv_trade_override));
}
-int itemdb_cantrade_sub(struct item_data *item, int gmlv, int gmlv2)
-{
- return (item && (!(item->flag.trade_restriction&2) || gmlv >= item->gm_lv_trade_override || gmlv2 >= item->gm_lv_trade_override));
+int itemdb_cantrade_sub(struct item_data* item, int gmlv, int gmlv2) {
+ return (item && (!(item->flag.trade_restriction&2) || gmlv >= item->gm_lv_trade_override || gmlv2 >= item->gm_lv_trade_override));
}
-int itemdb_canpartnertrade_sub(struct item_data *item, int gmlv, int gmlv2)
-{
- return (item && (item->flag.trade_restriction&4 || gmlv >= item->gm_lv_trade_override || gmlv2 >= item->gm_lv_trade_override));
+int itemdb_canpartnertrade_sub(struct item_data* item, int gmlv, int gmlv2) {
+ return (item && (item->flag.trade_restriction&4 || gmlv >= item->gm_lv_trade_override || gmlv2 >= item->gm_lv_trade_override));
}
-int itemdb_cansell_sub(struct item_data *item, int gmlv, int unused)
-{
- return (item && (!(item->flag.trade_restriction&8) || gmlv >= item->gm_lv_trade_override));
+int itemdb_cansell_sub(struct item_data* item, int gmlv, int unused) {
+ return (item && (!(item->flag.trade_restriction&8) || gmlv >= item->gm_lv_trade_override));
}
-int itemdb_cancartstore_sub(struct item_data *item, int gmlv, int unused)
-{
- return (item && (!(item->flag.trade_restriction&16) || gmlv >= item->gm_lv_trade_override));
+int itemdb_cancartstore_sub(struct item_data* item, int gmlv, int unused) {
+ return (item && (!(item->flag.trade_restriction&16) || gmlv >= item->gm_lv_trade_override));
}
-int itemdb_canstore_sub(struct item_data *item, int gmlv, int unused)
-{
- return (item && (!(item->flag.trade_restriction&32) || gmlv >= item->gm_lv_trade_override));
+int itemdb_canstore_sub(struct item_data* item, int gmlv, int unused) {
+ return (item && (!(item->flag.trade_restriction&32) || gmlv >= item->gm_lv_trade_override));
}
-int itemdb_canguildstore_sub(struct item_data *item, int gmlv, int unused)
-{
- return (item && (!(item->flag.trade_restriction&64) || gmlv >= item->gm_lv_trade_override));
+int itemdb_canguildstore_sub(struct item_data* item, int gmlv, int unused) {
+ return (item && (!(item->flag.trade_restriction&64) || gmlv >= item->gm_lv_trade_override));
}
-int itemdb_canmail_sub(struct item_data *item, int gmlv, int unused)
-{
- return (item && (!(item->flag.trade_restriction&128) || gmlv >= item->gm_lv_trade_override));
+int itemdb_canmail_sub(struct item_data* item, int gmlv, int unused) {
+ return (item && (!(item->flag.trade_restriction&128) || gmlv >= item->gm_lv_trade_override));
}
-int itemdb_canauction_sub(struct item_data *item, int gmlv, int unused)
-{
- return (item && (!(item->flag.trade_restriction&256) || gmlv >= item->gm_lv_trade_override));
+int itemdb_canauction_sub(struct item_data* item, int gmlv, int unused) {
+ return (item && (!(item->flag.trade_restriction&256) || gmlv >= item->gm_lv_trade_override));
}
-int itemdb_isrestricted(struct item *item, int gmlv, int gmlv2, int (*func)(struct item_data *, int, int))
+int itemdb_isrestricted(struct item* item, int gmlv, int gmlv2, int (*func)(struct item_data*, int, int))
{
- struct item_data *item_data = itemdb_search(item->nameid);
- int i;
-
- if (!func(item_data, gmlv, gmlv2))
- return 0;
-
- if (item_data->slot == 0 || itemdb_isspecial(item->card[0]))
- return 1;
-
- for (i = 0; i < item_data->slot; i++) {
- if (!item->card[i]) continue;
- if (!func(itemdb_search(item->card[i]), gmlv, gmlv2))
- return 0;
- }
- return 1;
+ struct item_data* item_data = itemdb_search(item->nameid);
+ int i;
+
+ if (!func(item_data, gmlv, gmlv2))
+ return 0;
+
+ if(item_data->slot == 0 || itemdb_isspecial(item->card[0]))
+ return 1;
+
+ for(i = 0; i < item_data->slot; i++) {
+ if (!item->card[i]) continue;
+ if (!func(itemdb_search(item->card[i]), gmlv, gmlv2))
+ return 0;
+ }
+ return 1;
}
/*==========================================
- * Specifies if item-type should drop unidentified.
+ * Specifies if item-type should drop unidentified.
*------------------------------------------*/
int itemdb_isidentified(int nameid)
{
- int type=itemdb_type(nameid);
- switch (type) {
- case IT_WEAPON:
- case IT_ARMOR:
- case IT_PETARMOR:
- return 0;
- default:
- return 1;
- }
+ int type=itemdb_type(nameid);
+ switch (type) {
+ case IT_WEAPON:
+ case IT_ARMOR:
+ case IT_PETARMOR:
+ return 0;
+ default:
+ return 1;
+ }
}
/*==========================================
* Search by name for the override flags available items
* (Give item another sprite)
*------------------------------------------*/
-static bool itemdb_read_itemavail(char *str[], int columns, int current)
-{
- // <nameid>,<sprite>
- int nameid, sprite;
- struct item_data *id;
-
- nameid = atoi(str[0]);
-
- if ((id = itemdb_exists(nameid)) == NULL) {
- ShowWarning("itemdb_read_itemavail: Invalid item id %d.\n", nameid);
- return false;
- }
-
- sprite = atoi(str[1]);
-
- if (sprite > 0) {
- id->flag.available = 1;
- id->view_id = sprite;
- } else {
- id->flag.available = 0;
- }
-
- return true;
+static bool itemdb_read_itemavail(char* str[], int columns, int current)
+{// <nameid>,<sprite>
+ int nameid, sprite;
+ struct item_data *id;
+
+ nameid = atoi(str[0]);
+
+ if( ( id = itemdb_exists(nameid) ) == NULL )
+ {
+ ShowWarning("itemdb_read_itemavail: Invalid item id %d.\n", nameid);
+ return false;
+ }
+
+ sprite = atoi(str[1]);
+
+ if( sprite > 0 )
+ {
+ id->flag.available = 1;
+ id->view_id = sprite;
+ }
+ else
+ {
+ id->flag.available = 0;
+ }
+
+ return true;
}
/*==========================================
* read item group data
*------------------------------------------*/
-static void itemdb_read_itemgroup_sub(const char *filename)
+static void itemdb_read_itemgroup_sub(const char* filename)
{
- FILE *fp;
- char line[1024];
- int ln=0;
- int groupid,j,k,nameid;
- char *str[3],*p;
- char w1[1024], w2[1024];
-
- if ((fp=fopen(filename,"r"))==NULL) {
- ShowError("can't read %s\n", filename);
- return;
- }
-
- while (fgets(line, sizeof(line), fp)) {
- ln++;
- if (line[0]=='/' && line[1]=='/')
- continue;
- if (strstr(line,"import")) {
- if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) == 2 &&
- strcmpi(w1, "import") == 0) {
- itemdb_read_itemgroup_sub(w2);
- continue;
- }
- }
- memset(str,0,sizeof(str));
- for (j=0,p=line; j<3 && p; j++) {
- str[j]=p;
- p=strchr(p,',');
- if (p) *p++=0;
- }
- if (str[0]==NULL)
- continue;
- if (j<3) {
- if (j>1) //Or else it barks on blank lines...
- ShowWarning("itemdb_read_itemgroup: Insufficient fields for entry at %s:%d\n", filename, ln);
- continue;
- }
- groupid = atoi(str[0]);
- if (groupid < 0 || groupid >= MAX_ITEMGROUP) {
- ShowWarning("itemdb_read_itemgroup: Invalid group %d in %s:%d\n", groupid, filename, ln);
- continue;
- }
- nameid = atoi(str[1]);
- if (!itemdb_exists(nameid)) {
- ShowWarning("itemdb_read_itemgroup: Non-existant item %d in %s:%d\n", nameid, filename, ln);
- continue;
- }
- k = atoi(str[2]);
- if (itemgroup_db[groupid].qty+k >= MAX_RANDITEM) {
- ShowWarning("itemdb_read_itemgroup: Group %d is full (%d entries) in %s:%d\n", groupid, MAX_RANDITEM, filename, ln);
- continue;
- }
- for (j=0; j<k; j++)
- itemgroup_db[groupid].nameid[itemgroup_db[groupid].qty++] = nameid;
- }
- fclose(fp);
- return;
+ FILE *fp;
+ char line[1024];
+ int ln=0;
+ int groupid,j,k,nameid;
+ char *str[3],*p;
+ char w1[1024], w2[1024];
+
+ if( (fp=fopen(filename,"r"))==NULL ){
+ ShowError("can't read %s\n", filename);
+ return;
+ }
+
+ while(fgets(line, sizeof(line), fp))
+ {
+ ln++;
+ if(line[0]=='/' && line[1]=='/')
+ continue;
+ if(strstr(line,"import")) {
+ if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) == 2 &&
+ strcmpi(w1, "import") == 0) {
+ itemdb_read_itemgroup_sub(w2);
+ continue;
+ }
+ }
+ memset(str,0,sizeof(str));
+ for(j=0,p=line;j<3 && p;j++){
+ str[j]=p;
+ p=strchr(p,',');
+ if(p) *p++=0;
+ }
+ if(str[0]==NULL)
+ continue;
+ if (j<3) {
+ if (j>1) //Or else it barks on blank lines...
+ ShowWarning("itemdb_read_itemgroup: Insufficient fields for entry at %s:%d\n", filename, ln);
+ continue;
+ }
+ groupid = atoi(str[0]);
+ if (groupid < 0 || groupid >= MAX_ITEMGROUP) {
+ ShowWarning("itemdb_read_itemgroup: Invalid group %d in %s:%d\n", groupid, filename, ln);
+ continue;
+ }
+ nameid = atoi(str[1]);
+ if (!itemdb_exists(nameid)) {
+ ShowWarning("itemdb_read_itemgroup: Non-existant item %d in %s:%d\n", nameid, filename, ln);
+ continue;
+ }
+ k = atoi(str[2]);
+ if (itemgroup_db[groupid].qty+k >= MAX_RANDITEM) {
+ ShowWarning("itemdb_read_itemgroup: Group %d is full (%d entries) in %s:%d\n", groupid, MAX_RANDITEM, filename, ln);
+ continue;
+ }
+ for(j=0;j<k;j++)
+ itemgroup_db[groupid].nameid[itemgroup_db[groupid].qty++] = nameid;
+ }
+ fclose(fp);
+ return;
}
static void itemdb_read_itemgroup(void)
{
- char path[256];
- snprintf(path, 255, "%s/"DBPATH"item_group_db.txt", db_path);
- memset(&itemgroup_db, 0, sizeof(itemgroup_db));
- itemdb_read_itemgroup_sub(path);
- ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n", "item_group_db.txt");
- return;
+ char path[256];
+ snprintf(path, 255, "%s/"DBPATH"item_group_db.txt", db_path);
+ memset(&itemgroup_db, 0, sizeof(itemgroup_db));
+ itemdb_read_itemgroup_sub(path);
+ ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n", "item_group_db.txt");
+ return;
}
/*==========================================
* Read item forbidden by mapflag (can't equip item)
*------------------------------------------*/
-static bool itemdb_read_noequip(char *str[], int columns, int current)
-{
- // <nameid>,<mode>
- int nameid;
- struct item_data *id;
+static bool itemdb_read_noequip(char* str[], int columns, int current)
+{// <nameid>,<mode>
+ int nameid;
+ struct item_data *id;
- nameid = atoi(str[0]);
+ nameid = atoi(str[0]);
- if ((id = itemdb_exists(nameid)) == NULL) {
- ShowWarning("itemdb_read_noequip: Invalid item id %d.\n", nameid);
- return false;
- }
+ if( ( id = itemdb_exists(nameid) ) == NULL )
+ {
+ ShowWarning("itemdb_read_noequip: Invalid item id %d.\n", nameid);
+ return false;
+ }
- id->flag.no_equip |= atoi(str[1]);
+ id->flag.no_equip |= atoi(str[1]);
- return true;
+ return true;
}
/*==========================================
* Reads item trade restrictions [Skotlex]
*------------------------------------------*/
-static bool itemdb_read_itemtrade(char *str[], int columns, int current)
-{
- // <nameid>,<mask>,<gm level>
- int nameid, flag, gmlv;
- struct item_data *id;
-
- nameid = atoi(str[0]);
-
- if ((id = itemdb_exists(nameid)) == NULL) {
- //ShowWarning("itemdb_read_itemtrade: Invalid item id %d.\n", nameid);
- //return false;
- // FIXME: item_trade.txt contains items, which are commented in item database.
- return true;
- }
-
- flag = atoi(str[1]);
- gmlv = atoi(str[2]);
-
- if (flag < 0 || flag > 511) { //Check range
- ShowWarning("itemdb_read_itemtrade: Invalid trading mask %d for item id %d.\n", flag, nameid);
- return false;
- }
- if (gmlv < 1) {
- ShowWarning("itemdb_read_itemtrade: Invalid override GM level %d for item id %d.\n", gmlv, nameid);
- return false;
- }
-
- id->flag.trade_restriction = flag;
- id->gm_lv_trade_override = gmlv;
-
- return true;
+static bool itemdb_read_itemtrade(char* str[], int columns, int current)
+{// <nameid>,<mask>,<gm level>
+ int nameid, flag, gmlv;
+ struct item_data *id;
+
+ nameid = atoi(str[0]);
+
+ if( ( id = itemdb_exists(nameid) ) == NULL )
+ {
+ //ShowWarning("itemdb_read_itemtrade: Invalid item id %d.\n", nameid);
+ //return false;
+ // FIXME: item_trade.txt contains items, which are commented in item database.
+ return true;
+ }
+
+ flag = atoi(str[1]);
+ gmlv = atoi(str[2]);
+
+ if( flag < 0 || flag > 511 ) {//Check range
+ ShowWarning("itemdb_read_itemtrade: Invalid trading mask %d for item id %d.\n", flag, nameid);
+ return false;
+ }
+ if( gmlv < 1 )
+ {
+ ShowWarning("itemdb_read_itemtrade: Invalid override GM level %d for item id %d.\n", gmlv, nameid);
+ return false;
+ }
+
+ id->flag.trade_restriction = flag;
+ id->gm_lv_trade_override = gmlv;
+
+ return true;
}
/*==========================================
* Reads item delay amounts [Paradox924X]
*------------------------------------------*/
-static bool itemdb_read_itemdelay(char *str[], int columns, int current)
-{
- // <nameid>,<delay>
- int nameid, delay;
- struct item_data *id;
+static bool itemdb_read_itemdelay(char* str[], int columns, int current)
+{// <nameid>,<delay>
+ int nameid, delay;
+ struct item_data *id;
- nameid = atoi(str[0]);
+ nameid = atoi(str[0]);
- if ((id = itemdb_exists(nameid)) == NULL) {
- ShowWarning("itemdb_read_itemdelay: Invalid item id %d.\n", nameid);
- return false;
- }
+ if( ( id = itemdb_exists(nameid) ) == NULL )
+ {
+ ShowWarning("itemdb_read_itemdelay: Invalid item id %d.\n", nameid);
+ return false;
+ }
- delay = atoi(str[1]);
+ delay = atoi(str[1]);
- if (delay < 0) {
- ShowWarning("itemdb_read_itemdelay: Invalid delay %d for item id %d.\n", id->delay, nameid);
- return false;
- }
+ if( delay < 0 )
+ {
+ ShowWarning("itemdb_read_itemdelay: Invalid delay %d for item id %d.\n", id->delay, nameid);
+ return false;
+ }
- id->delay = delay;
+ id->delay = delay;
- return true;
+ return true;
}
/*==================================================================
* Reads item stacking restrictions
*----------------------------------------------------------------*/
-static bool itemdb_read_stack(char *fields[], int columns, int current)
-{
- // <item id>,<stack limit amount>,<type>
- unsigned short nameid, amount;
- unsigned int type;
- struct item_data *id;
-
- nameid = (unsigned short)strtoul(fields[0], NULL, 10);
-
- if ((id = itemdb_exists(nameid)) == NULL) {
- ShowWarning("itemdb_read_stack: Unknown item id '%hu'.\n", nameid);
- return false;
- }
-
- if (!itemdb_isstackable2(id)) {
- ShowWarning("itemdb_read_stack: Item id '%hu' is not stackable.\n", nameid);
- return false;
- }
-
- amount = (unsigned short)strtoul(fields[1], NULL, 10);
- type = strtoul(fields[2], NULL, 10);
-
- if (!amount) {
- // ignore
- return true;
- }
-
- id->stack.amount = amount;
- id->stack.inventory = (type&1)!=0;
- id->stack.cart = (type&2)!=0;
- id->stack.storage = (type&4)!=0;
- id->stack.guildstorage = (type&8)!=0;
-
- return true;
+static bool itemdb_read_stack(char* fields[], int columns, int current)
+{// <item id>,<stack limit amount>,<type>
+ unsigned short nameid, amount;
+ unsigned int type;
+ struct item_data* id;
+
+ nameid = (unsigned short)strtoul(fields[0], NULL, 10);
+
+ if( ( id = itemdb_exists(nameid) ) == NULL )
+ {
+ ShowWarning("itemdb_read_stack: Unknown item id '%hu'.\n", nameid);
+ return false;
+ }
+
+ if( !itemdb_isstackable2(id) )
+ {
+ ShowWarning("itemdb_read_stack: Item id '%hu' is not stackable.\n", nameid);
+ return false;
+ }
+
+ amount = (unsigned short)strtoul(fields[1], NULL, 10);
+ type = strtoul(fields[2], NULL, 10);
+
+ if( !amount )
+ {// ignore
+ return true;
+ }
+
+ id->stack.amount = amount;
+ id->stack.inventory = (type&1)!=0;
+ id->stack.cart = (type&2)!=0;
+ id->stack.storage = (type&4)!=0;
+ id->stack.guildstorage = (type&8)!=0;
+
+ return true;
}
/// Reads items allowed to be sold in buying stores
-static bool itemdb_read_buyingstore(char *fields[], int columns, int current)
-{
- // <nameid>
- int nameid;
- struct item_data *id;
+static bool itemdb_read_buyingstore(char* fields[], int columns, int current)
+{// <nameid>
+ int nameid;
+ struct item_data* id;
- nameid = atoi(fields[0]);
+ nameid = atoi(fields[0]);
- if ((id = itemdb_exists(nameid)) == NULL) {
- ShowWarning("itemdb_read_buyingstore: Invalid item id %d.\n", nameid);
- return false;
- }
+ if( ( id = itemdb_exists(nameid) ) == NULL )
+ {
+ ShowWarning("itemdb_read_buyingstore: Invalid item id %d.\n", nameid);
+ return false;
+ }
- if (!itemdb_isstackable2(id)) {
- ShowWarning("itemdb_read_buyingstore: Non-stackable item id %d cannot be enabled for buying store.\n", nameid);
- return false;
- }
+ if( !itemdb_isstackable2(id) )
+ {
+ ShowWarning("itemdb_read_buyingstore: Non-stackable item id %d cannot be enabled for buying store.\n", nameid);
+ return false;
+ }
- id->flag.buyingstore = true;
+ id->flag.buyingstore = true;
- return true;
+ return true;
}
/**
* @return: amount of retrieved entries.
**/
-int itemdb_combo_split_atoi(char *str, int *val)
-{
- int i;
-
- for (i=0; i<MAX_ITEMS_PER_COMBO; i++) {
- if (!str) break;
-
- val[i] = atoi(str);
-
- str = strchr(str,':');
-
- if (str)
- *str++=0;
- }
-
- if (i == 0) //No data found.
- return 0;
-
- return i;
+int itemdb_combo_split_atoi (char *str, int *val) {
+ int i;
+
+ for (i=0; i<MAX_ITEMS_PER_COMBO; i++) {
+ if (!str) break;
+
+ val[i] = atoi(str);
+
+ str = strchr(str,':');
+
+ if (str)
+ *str++=0;
+ }
+
+ if( i == 0 ) //No data found.
+ return 0;
+
+ return i;
}
/**
* <combo{:combo{:combo:{..}}}>,<{ script }>
**/
-void itemdb_read_combos()
-{
- uint32 lines = 0, count = 0;
- char line[1024];
-
- char path[256];
- FILE *fp;
-
- sprintf(path, "%s/%s", db_path, DBPATH"item_combo_db.txt");
-
- if ((fp = fopen(path, "r")) == NULL) {
- ShowError("itemdb_read_combos: File not found \"%s\".\n", path);
- return;
- }
-
- // process rows one by one
- while (fgets(line, sizeof(line), fp)) {
- char *str[2], *p;
-
- lines++;
-
- if (line[0] == '/' && line[1] == '/')
- continue;
-
- memset(str, 0, sizeof(str));
-
- p = line;
-
- p = trim(p);
-
- if (*p == '\0')
- continue;// empty line
-
- if (!strchr(p,',')) {
- /* is there even a single column? */
- ShowError("itemdb_read_combos: Insufficient columns in line %d of \"%s\", skipping.\n", lines, path);
- continue;
- }
-
- str[0] = p;
- p = strchr(p,',');
- *p = '\0';
- p++;
-
- str[1] = p;
- p = strchr(p,',');
- p++;
-
- if (str[1][0] != '{') {
- ShowError("itemdb_read_combos(#1): Invalid format (Script column) in line %d of \"%s\", skipping.\n", lines, path);
- continue;
- }
-
- /* no ending key anywhere (missing \}\) */
- if (str[1][strlen(str[1])-1] != '}') {
- ShowError("itemdb_read_combos(#2): Invalid format (Script column) in line %d of \"%s\", skipping.\n", lines, path);
- continue;
- } else {
- int items[MAX_ITEMS_PER_COMBO];
- int v = 0, retcount = 0;
- struct item_data *id = NULL;
- int idx = 0;
-
- if ((retcount = itemdb_combo_split_atoi(str[0], items)) < 2) {
- ShowError("itemdb_read_combos: line %d of \"%s\" doesn't have enough items to make for a combo (min:2), skipping.\n", lines, path);
- continue;
- }
-
- /* validate */
- for (v = 0; v < retcount; v++) {
- if (!itemdb_exists(items[v])) {
- ShowError("itemdb_read_combos: line %d of \"%s\" contains unknown item ID %d, skipping.\n", lines, path,items[v]);
- break;
- }
- }
- /* failed at some item */
- if (v < retcount)
- continue;
-
- id = itemdb_exists(items[0]);
-
- idx = id->combos_count;
-
- /* first entry, create */
- if (id->combos == NULL) {
- CREATE(id->combos, struct item_combo *, 1);
- id->combos_count = 1;
- } else {
- RECREATE(id->combos, struct item_combo *, ++id->combos_count);
- }
-
- CREATE(id->combos[idx],struct item_combo,1);
-
- id->combos[idx]->nameid = aMalloc(retcount * sizeof(unsigned short));
- id->combos[idx]->count = retcount;
- id->combos[idx]->script = parse_script(str[1], path, lines, 0);
- id->combos[idx]->id = count;
- id->combos[idx]->isRef = false;
- /* populate ->nameid field */
- for (v = 0; v < retcount; v++) {
- id->combos[idx]->nameid[v] = items[v];
- }
-
- /* populate the children to refer to this combo */
- for (v = 1; v < retcount; v++) {
- struct item_data *it = NULL;
- int index;
-
- it = itemdb_exists(items[v]);
-
- index = it->combos_count;
-
- if (it->combos == NULL) {
- CREATE(it->combos, struct item_combo *, 1);
- it->combos_count = 1;
- } else {
- RECREATE(it->combos, struct item_combo *, ++it->combos_count);
- }
-
- CREATE(it->combos[index],struct item_combo,1);
-
- /* we copy previously alloc'd pointers and just set it to reference */
- memcpy(it->combos[index],id->combos[idx],sizeof(struct item_combo));
- /* we flag this way to ensure we don't double-dealloc same data */
- it->combos[index]->isRef = true;
- }
-
- }
-
- count++;
- }
-
- fclose(fp);
-
- ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"item_combo_db"CL_RESET"'.\n", count);
-
- return;
+void itemdb_read_combos() {
+ uint32 lines = 0, count = 0;
+ char line[1024];
+
+ char path[256];
+ FILE* fp;
+
+ sprintf(path, "%s/%s", db_path, DBPATH"item_combo_db.txt");
+
+ if ((fp = fopen(path, "r")) == NULL) {
+ ShowError("itemdb_read_combos: File not found \"%s\".\n", path);
+ return;
+ }
+
+ // process rows one by one
+ while(fgets(line, sizeof(line), fp)) {
+ char *str[2], *p;
+
+ lines++;
+
+ if (line[0] == '/' && line[1] == '/')
+ continue;
+
+ memset(str, 0, sizeof(str));
+
+ p = line;
+
+ p = trim(p);
+
+ if (*p == '\0')
+ continue;// empty line
+
+ if (!strchr(p,','))
+ {
+ /* is there even a single column? */
+ ShowError("itemdb_read_combos: Insufficient columns in line %d of \"%s\", skipping.\n", lines, path);
+ continue;
+ }
+
+ str[0] = p;
+ p = strchr(p,',');
+ *p = '\0';
+ p++;
+
+ str[1] = p;
+ p = strchr(p,',');
+ p++;
+
+ if (str[1][0] != '{') {
+ ShowError("itemdb_read_combos(#1): Invalid format (Script column) in line %d of \"%s\", skipping.\n", lines, path);
+ continue;
+ }
+
+ /* no ending key anywhere (missing \}\) */
+ if ( str[1][strlen(str[1])-1] != '}' ) {
+ ShowError("itemdb_read_combos(#2): Invalid format (Script column) in line %d of \"%s\", skipping.\n", lines, path);
+ continue;
+ } else {
+ int items[MAX_ITEMS_PER_COMBO];
+ int v = 0, retcount = 0;
+ struct item_data * id = NULL;
+ int idx = 0;
+
+ if((retcount = itemdb_combo_split_atoi(str[0], items)) < 2) {
+ ShowError("itemdb_read_combos: line %d of \"%s\" doesn't have enough items to make for a combo (min:2), skipping.\n", lines, path);
+ continue;
+ }
+
+ /* validate */
+ for(v = 0; v < retcount; v++) {
+ if( !itemdb_exists(items[v]) ) {
+ ShowError("itemdb_read_combos: line %d of \"%s\" contains unknown item ID %d, skipping.\n", lines, path,items[v]);
+ break;
+ }
+ }
+ /* failed at some item */
+ if( v < retcount )
+ continue;
+
+ id = itemdb_exists(items[0]);
+
+ idx = id->combos_count;
+
+ /* first entry, create */
+ if( id->combos == NULL ) {
+ CREATE(id->combos, struct item_combo*, 1);
+ id->combos_count = 1;
+ } else {
+ RECREATE(id->combos, struct item_combo*, ++id->combos_count);
+ }
+
+ CREATE(id->combos[idx],struct item_combo,1);
+
+ id->combos[idx]->nameid = aMalloc( retcount * sizeof(unsigned short) );
+ id->combos[idx]->count = retcount;
+ id->combos[idx]->script = parse_script(str[1], path, lines, 0);
+ id->combos[idx]->id = count;
+ id->combos[idx]->isRef = false;
+ /* populate ->nameid field */
+ for( v = 0; v < retcount; v++ ) {
+ id->combos[idx]->nameid[v] = items[v];
+ }
+
+ /* populate the children to refer to this combo */
+ for( v = 1; v < retcount; v++ ) {
+ struct item_data * it = NULL;
+ int index;
+
+ it = itemdb_exists(items[v]);
+
+ index = it->combos_count;
+
+ if( it->combos == NULL ) {
+ CREATE(it->combos, struct item_combo*, 1);
+ it->combos_count = 1;
+ } else {
+ RECREATE(it->combos, struct item_combo*, ++it->combos_count);
+ }
+
+ CREATE(it->combos[index],struct item_combo,1);
+
+ /* we copy previously alloc'd pointers and just set it to reference */
+ memcpy(it->combos[index],id->combos[idx],sizeof(struct item_combo));
+ /* we flag this way to ensure we don't double-dealloc same data */
+ it->combos[index]->isRef = true;
+ }
+
+ }
+
+ count++;
+ }
+
+ fclose(fp);
+
+ ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"item_combo_db"CL_RESET"'.\n", count);
+
+ return;
}
@@ -908,170 +908,171 @@ void itemdb_read_combos()
*======================================*/
static int itemdb_gendercheck(struct item_data *id)
{
- if (id->nameid == WEDDING_RING_M) //Grom Ring
- return 1;
- if (id->nameid == WEDDING_RING_F) //Bride Ring
- return 0;
- if (id->look == W_MUSICAL && id->type == IT_WEAPON) //Musical instruments are always male-only
- return 1;
- if (id->look == W_WHIP && id->type == IT_WEAPON) //Whips are always female-only
- return 0;
-
- return (battle_config.ignore_items_gender) ? 2 : id->sex;
+ if (id->nameid == WEDDING_RING_M) //Grom Ring
+ return 1;
+ if (id->nameid == WEDDING_RING_F) //Bride Ring
+ return 0;
+ if (id->look == W_MUSICAL && id->type == IT_WEAPON) //Musical instruments are always male-only
+ return 1;
+ if (id->look == W_WHIP && id->type == IT_WEAPON) //Whips are always female-only
+ return 0;
+
+ return (battle_config.ignore_items_gender) ? 2 : id->sex;
}
/**
* [RRInd]
* For backwards compatibility, in Renewal mode, MATK from weapons comes from the atk slot
* We use a ':' delimiter which, if not found, assumes the weapon does not provide any matk.
**/
-void itemdb_re_split_atoi(char *str, int *atk, int *matk)
-{
- int i, val[2];
-
- for (i=0; i<2; i++) {
- if (!str) break;
- val[i] = atoi(str);
- str = strchr(str,':');
- if (str)
- *str++=0;
- }
- if (i == 0) {
- *atk = *matk = 0;
- return;//no data found
- }
- if (i == 1) { //Single Value, we assume it's the ATK
- *atk = val[0];
- *matk = 0;
- return;
- }
- //We assume we have 2 values.
- *atk = val[0];
- *matk = val[1];
- return;
+void itemdb_re_split_atoi(char *str, int *atk, int *matk) {
+ int i, val[2];
+
+ for (i=0; i<2; i++) {
+ if (!str) break;
+ val[i] = atoi(str);
+ str = strchr(str,':');
+ if (str)
+ *str++=0;
+ }
+ if( i == 0 ) {
+ *atk = *matk = 0;
+ return;//no data found
+ }
+ if( i == 1 ) {//Single Value, we assume it's the ATK
+ *atk = val[0];
+ *matk = 0;
+ return;
+ }
+ //We assume we have 2 values.
+ *atk = val[0];
+ *matk = val[1];
+ return;
}
/*==========================================
* processes one itemdb entry
*------------------------------------------*/
-static bool itemdb_parse_dbrow(char **str, const char *source, int line, int scriptopt)
-{
- /*
- +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+
- | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
- +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+
- | id | name_english | name_japanese | type | price_buy | price_sell | weight | attack | defence | range | slots | equip_jobs | equip_upper | equip_genders | equip_locations | weapon_level | equip_level | refineable | view | script | equip_script | unequip_script |
- +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+
- */
- int nameid;
- struct item_data *id;
-
- nameid = atoi(str[0]);
- if (nameid <= 0) {
- ShowWarning("itemdb_parse_dbrow: Invalid id %d in line %d of \"%s\", skipping.\n", nameid, line, source);
- return false;
- }
-
- //ID,Name,Jname,Type,Price,Sell,Weight,ATK,DEF,Range,Slot,Job,Job Upper,Gender,Loc,wLV,eLV,refineable,View
- id = itemdb_load(nameid);
- safestrncpy(id->name, str[1], sizeof(id->name));
- safestrncpy(id->jname, str[2], sizeof(id->jname));
-
- id->type = atoi(str[3]);
-
- if (id->type < 0 || id->type == IT_UNKNOWN || id->type == IT_UNKNOWN2 || (id->type > IT_DELAYCONSUME && id->type < IT_CASH) || id->type >= IT_MAX) {
- // catch invalid item types
- ShowWarning("itemdb_parse_dbrow: Invalid item type %d for item %d. IT_ETC will be used.\n", id->type, nameid);
- id->type = IT_ETC;
- }
-
- if (id->type == IT_DELAYCONSUME) {
- //Items that are consumed only after target confirmation
- id->type = IT_USABLE;
- id->flag.delay_consume = 1;
- } else //In case of an itemdb reload and the item type changed.
- id->flag.delay_consume = 0;
-
- //When a particular price is not given, we should base it off the other one
- //(it is important to make a distinction between 'no price' and 0z)
- if (str[4][0])
- id->value_buy = atoi(str[4]);
- else
- id->value_buy = atoi(str[5]) * 2;
-
- if (str[5][0])
- id->value_sell = atoi(str[5]);
- else
- id->value_sell = id->value_buy / 2;
- /*
- if ( !str[4][0] && !str[5][0])
- {
- ShowWarning("itemdb_parse_dbrow: No buying/selling price defined for item %d (%s), using 20/10z\n", nameid, id->jname);
- id->value_buy = 20;
- id->value_sell = 10;
- } else
- */
- if (id->value_buy/124. < id->value_sell/75.)
- ShowWarning("itemdb_parse_dbrow: Buying/Selling [%d/%d] price of item %d (%s) allows Zeny making exploit through buying/selling at discounted/overcharged prices!\n",
- id->value_buy, id->value_sell, nameid, id->jname);
-
- id->weight = atoi(str[6]);
+static bool itemdb_parse_dbrow(char** str, const char* source, int line, int scriptopt) {
+ /*
+ +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+
+ | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
+ +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+
+ | id | name_english | name_japanese | type | price_buy | price_sell | weight | attack | defence | range | slots | equip_jobs | equip_upper | equip_genders | equip_locations | weapon_level | equip_level | refineable | view | script | equip_script | unequip_script |
+ +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+
+ */
+ int nameid;
+ struct item_data* id;
+
+ nameid = atoi(str[0]);
+ if( nameid <= 0 )
+ {
+ ShowWarning("itemdb_parse_dbrow: Invalid id %d in line %d of \"%s\", skipping.\n", nameid, line, source);
+ return false;
+ }
+
+ //ID,Name,Jname,Type,Price,Sell,Weight,ATK,DEF,Range,Slot,Job,Job Upper,Gender,Loc,wLV,eLV,refineable,View
+ id = itemdb_load(nameid);
+ safestrncpy(id->name, str[1], sizeof(id->name));
+ safestrncpy(id->jname, str[2], sizeof(id->jname));
+
+ id->type = atoi(str[3]);
+
+ if( id->type < 0 || id->type == IT_UNKNOWN || id->type == IT_UNKNOWN2 || ( id->type > IT_DELAYCONSUME && id->type < IT_CASH ) || id->type >= IT_MAX )
+ {// catch invalid item types
+ ShowWarning("itemdb_parse_dbrow: Invalid item type %d for item %d. IT_ETC will be used.\n", id->type, nameid);
+ id->type = IT_ETC;
+ }
+
+ if (id->type == IT_DELAYCONSUME)
+ { //Items that are consumed only after target confirmation
+ id->type = IT_USABLE;
+ id->flag.delay_consume = 1;
+ } else //In case of an itemdb reload and the item type changed.
+ id->flag.delay_consume = 0;
+
+ //When a particular price is not given, we should base it off the other one
+ //(it is important to make a distinction between 'no price' and 0z)
+ if ( str[4][0] )
+ id->value_buy = atoi(str[4]);
+ else
+ id->value_buy = atoi(str[5]) * 2;
+
+ if ( str[5][0] )
+ id->value_sell = atoi(str[5]);
+ else
+ id->value_sell = id->value_buy / 2;
+ /*
+ if ( !str[4][0] && !str[5][0])
+ {
+ ShowWarning("itemdb_parse_dbrow: No buying/selling price defined for item %d (%s), using 20/10z\n", nameid, id->jname);
+ id->value_buy = 20;
+ id->value_sell = 10;
+ } else
+ */
+ if (id->value_buy/124. < id->value_sell/75.)
+ ShowWarning("itemdb_parse_dbrow: Buying/Selling [%d/%d] price of item %d (%s) allows Zeny making exploit through buying/selling at discounted/overcharged prices!\n",
+ id->value_buy, id->value_sell, nameid, id->jname);
+
+ id->weight = atoi(str[6]);
#ifdef RENEWAL
- itemdb_re_split_atoi(str[7],&id->atk,&id->matk);
+ itemdb_re_split_atoi(str[7],&id->atk,&id->matk);
#else
- id->atk = atoi(str[7]);
+ id->atk = atoi(str[7]);
#endif
- id->def = atoi(str[8]);
- id->range = atoi(str[9]);
- id->slot = atoi(str[10]);
-
- if (id->slot > MAX_SLOTS) {
- ShowWarning("itemdb_parse_dbrow: Item %d (%s) specifies %d slots, but the server only supports up to %d. Using %d slots.\n", nameid, id->jname, id->slot, MAX_SLOTS, MAX_SLOTS);
- id->slot = MAX_SLOTS;
- }
-
- itemdb_jobid2mapid(id->class_base, (unsigned int)strtoul(str[11],NULL,0));
- id->class_upper = atoi(str[12]);
- id->sex = atoi(str[13]);
- id->equip = atoi(str[14]);
-
- if (!id->equip && itemdb_isequip2(id)) {
- ShowWarning("Item %d (%s) is an equipment with no equip-field! Making it an etc item.\n", nameid, id->jname);
- id->type = IT_ETC;
- }
-
- id->wlv = cap_value(atoi(str[15]), REFINE_TYPE_ARMOR, REFINE_TYPE_MAX);
+ id->def = atoi(str[8]);
+ id->range = atoi(str[9]);
+ id->slot = atoi(str[10]);
+
+ if (id->slot > MAX_SLOTS)
+ {
+ ShowWarning("itemdb_parse_dbrow: Item %d (%s) specifies %d slots, but the server only supports up to %d. Using %d slots.\n", nameid, id->jname, id->slot, MAX_SLOTS, MAX_SLOTS);
+ id->slot = MAX_SLOTS;
+ }
+
+ itemdb_jobid2mapid(id->class_base, (unsigned int)strtoul(str[11],NULL,0));
+ id->class_upper = atoi(str[12]);
+ id->sex = atoi(str[13]);
+ id->equip = atoi(str[14]);
+
+ if (!id->equip && itemdb_isequip2(id))
+ {
+ ShowWarning("Item %d (%s) is an equipment with no equip-field! Making it an etc item.\n", nameid, id->jname);
+ id->type = IT_ETC;
+ }
+
+ id->wlv = cap_value(atoi(str[15]), REFINE_TYPE_ARMOR, REFINE_TYPE_MAX);
#ifdef RENEWAL
- itemdb_re_split_atoi(str[16],&id->elv,&id->elvmax);
+ itemdb_re_split_atoi(str[16],&id->elv,&id->elvmax);
#else
- id->elv = atoi(str[16]);
+ id->elv = atoi(str[16]);
#endif
- id->flag.no_refine = atoi(str[17]) ? 0 : 1; //FIXME: verify this
- id->look = atoi(str[18]);
-
- id->flag.available = 1;
- id->view_id = 0;
- id->sex = itemdb_gendercheck(id); //Apply gender filtering.
-
- if (id->script) {
- script_free_code(id->script);
- id->script = NULL;
- }
- if (id->equip_script) {
- script_free_code(id->equip_script);
- id->equip_script = NULL;
- }
- if (id->unequip_script) {
- script_free_code(id->unequip_script);
- id->unequip_script = NULL;
- }
-
- if (*str[19])
- id->script = parse_script(str[19], source, line, scriptopt);
- if (*str[20])
- id->equip_script = parse_script(str[20], source, line, scriptopt);
- if (*str[21])
- id->unequip_script = parse_script(str[21], source, line, scriptopt);
-
- return true;
+ id->flag.no_refine = atoi(str[17]) ? 0 : 1; //FIXME: verify this
+ id->look = atoi(str[18]);
+
+ id->flag.available = 1;
+ id->view_id = 0;
+ id->sex = itemdb_gendercheck(id); //Apply gender filtering.
+
+ if (id->script) {
+ script_free_code(id->script);
+ id->script = NULL;
+ }
+ if (id->equip_script) {
+ script_free_code(id->equip_script);
+ id->equip_script = NULL;
+ }
+ if (id->unequip_script) {
+ script_free_code(id->unequip_script);
+ id->unequip_script = NULL;
+ }
+
+ if (*str[19])
+ id->script = parse_script(str[19], source, line, scriptopt);
+ if (*str[20])
+ id->equip_script = parse_script(str[20], source, line, scriptopt);
+ if (*str[21])
+ id->unequip_script = parse_script(str[21], source, line, scriptopt);
+
+ return true;
}
/*==========================================
@@ -1080,191 +1081,195 @@ static bool itemdb_parse_dbrow(char **str, const char *source, int line, int scr
*------------------------------------------*/
static int itemdb_readdb(void)
{
- const char *filename[] = {
- DBPATH"item_db.txt",
- "item_db2.txt"
- };
-
- int fi;
-
- for (fi = 0; fi < ARRAYLENGTH(filename); ++fi) {
- uint32 lines = 0, count = 0;
- char line[1024];
-
- char path[256];
- FILE *fp;
-
- sprintf(path, "%s/%s", db_path, filename[fi]);
- fp = fopen(path, "r");
- if (fp == NULL) {
- ShowWarning("itemdb_readdb: File not found \"%s\", skipping.\n", path);
- continue;
- }
-
- // process rows one by one
- while (fgets(line, sizeof(line), fp)) {
- char *str[32], *p;
- int i;
- lines++;
- if (line[0] == '/' && line[1] == '/')
- continue;
- memset(str, 0, sizeof(str));
-
- p = line;
- while (ISSPACE(*p))
- ++p;
- if (*p == '\0')
- continue;// empty line
- for (i = 0; i < 19; ++i) {
- str[i] = p;
- p = strchr(p,',');
- if (p == NULL)
- break;// comma not found
- *p = '\0';
- ++p;
- }
-
- if (p == NULL) {
- ShowError("itemdb_readdb: Insufficient columns in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
- continue;
- }
-
- // Script
- if (*p != '{') {
- ShowError("itemdb_readdb: Invalid format (Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
- continue;
- }
- str[19] = p;
- p = strstr(p+1,"},");
- if (p == NULL) {
- ShowError("itemdb_readdb: Invalid format (Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
- continue;
- }
- p[1] = '\0';
- p += 2;
-
- // OnEquip_Script
- if (*p != '{') {
- ShowError("itemdb_readdb: Invalid format (OnEquip_Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
- continue;
- }
- str[20] = p;
- p = strstr(p+1,"},");
- if (p == NULL) {
- ShowError("itemdb_readdb: Invalid format (OnEquip_Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
- continue;
- }
- p[1] = '\0';
- p += 2;
-
- // OnUnequip_Script (last column)
- if (*p != '{') {
- ShowError("itemdb_readdb: Invalid format (OnUnequip_Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
- continue;
- }
- str[21] = p;
-
- if (str[21][strlen(str[21])-2] != '}') {
- /* lets count to ensure it's not something silly e.g. a extra space at line ending */
- int v, lcurly = 0, rcurly = 0;
-
- for (v = 0; v < strlen(str[21]); v++) {
- if (str[21][v] == '{')
- lcurly++;
- else if (str[21][v] == '}')
- rcurly++;
- }
-
- if (lcurly != rcurly) {
- ShowError("itemdb_readdb: Mismatching curly braces in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
- continue;
- }
- }
-
- if (!itemdb_parse_dbrow(str, path, lines, 0))
- continue;
-
- count++;
- }
-
- fclose(fp);
-
- ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, filename[fi]);
- }
-
- return 0;
+ const char* filename[] = {
+ DBPATH"item_db.txt",
+ "item_db2.txt" };
+
+ int fi;
+
+ for( fi = 0; fi < ARRAYLENGTH(filename); ++fi ) {
+ uint32 lines = 0, count = 0;
+ char line[1024];
+
+ char path[256];
+ FILE* fp;
+
+ sprintf(path, "%s/%s", db_path, filename[fi]);
+ fp = fopen(path, "r");
+ if( fp == NULL ) {
+ ShowWarning("itemdb_readdb: File not found \"%s\", skipping.\n", path);
+ continue;
+ }
+
+ // process rows one by one
+ while(fgets(line, sizeof(line), fp))
+ {
+ char *str[32], *p;
+ int i;
+ lines++;
+ if(line[0] == '/' && line[1] == '/')
+ continue;
+ memset(str, 0, sizeof(str));
+
+ p = line;
+ while( ISSPACE(*p) )
+ ++p;
+ if( *p == '\0' )
+ continue;// empty line
+ for( i = 0; i < 19; ++i )
+ {
+ str[i] = p;
+ p = strchr(p,',');
+ if( p == NULL )
+ break;// comma not found
+ *p = '\0';
+ ++p;
+ }
+
+ if( p == NULL )
+ {
+ ShowError("itemdb_readdb: Insufficient columns in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
+ continue;
+ }
+
+ // Script
+ if( *p != '{' )
+ {
+ ShowError("itemdb_readdb: Invalid format (Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
+ continue;
+ }
+ str[19] = p;
+ p = strstr(p+1,"},");
+ if( p == NULL )
+ {
+ ShowError("itemdb_readdb: Invalid format (Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
+ continue;
+ }
+ p[1] = '\0';
+ p += 2;
+
+ // OnEquip_Script
+ if( *p != '{' )
+ {
+ ShowError("itemdb_readdb: Invalid format (OnEquip_Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
+ continue;
+ }
+ str[20] = p;
+ p = strstr(p+1,"},");
+ if( p == NULL )
+ {
+ ShowError("itemdb_readdb: Invalid format (OnEquip_Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
+ continue;
+ }
+ p[1] = '\0';
+ p += 2;
+
+ // OnUnequip_Script (last column)
+ if( *p != '{' )
+ {
+ ShowError("itemdb_readdb: Invalid format (OnUnequip_Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
+ continue;
+ }
+ str[21] = p;
+
+ if ( str[21][strlen(str[21])-2] != '}' ) {
+ /* lets count to ensure it's not something silly e.g. a extra space at line ending */
+ int v, lcurly = 0, rcurly = 0;
+
+ for( v = 0; v < strlen(str[21]); v++ ) {
+ if( str[21][v] == '{' )
+ lcurly++;
+ else if ( str[21][v] == '}' )
+ rcurly++;
+ }
+
+ if( lcurly != rcurly ) {
+ ShowError("itemdb_readdb: Mismatching curly braces in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
+ continue;
+ }
+ }
+
+ if (!itemdb_parse_dbrow(str, path, lines, 0))
+ continue;
+
+ count++;
+ }
+
+ fclose(fp);
+
+ ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, filename[fi]);
+ }
+
+ return 0;
}
/*======================================
* item_db table reading
*======================================*/
-static int itemdb_read_sqldb(void)
-{
-
- const char *item_db_name[] = {
-#ifdef RENEWAL
- item_db_re_db,
-#else
- item_db_db,
-#endif
- item_db2_db
- };
- int fi;
-
- for (fi = 0; fi < ARRAYLENGTH(item_db_name); ++fi) {
- uint32 lines = 0, count = 0;
-
- // retrieve all rows from the item database
- if (SQL_ERROR == Sql_Query(mmysql_handle, "SELECT * FROM `%s`", item_db_name[fi])) {
- Sql_ShowDebug(mmysql_handle);
- continue;
- }
-
- // process rows one by one
- while (SQL_SUCCESS == Sql_NextRow(mmysql_handle)) { // wrap the result into a TXT-compatible format
- char *str[22];
- char *dummy = "";
- int i;
- ++lines;
- for (i = 0; i < 22; ++i) {
- Sql_GetData(mmysql_handle, i, &str[i], NULL);
- if (str[i] == NULL)
- str[i] = dummy; // get rid of NULL columns
- }
-
- if (!itemdb_parse_dbrow(str, item_db_name[fi], lines, SCRIPT_IGNORE_EXTERNAL_BRACKETS))
- continue;
- ++count;
- }
-
- // free the query result
- Sql_FreeResult(mmysql_handle);
-
- ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, item_db_name[fi]);
- }
-
- return 0;
+static int itemdb_read_sqldb(void) {
+
+ const char* item_db_name[] = {
+ #ifdef RENEWAL
+ item_db_re_db,
+ #else
+ item_db_db,
+ #endif
+ item_db2_db };
+ int fi;
+
+ for( fi = 0; fi < ARRAYLENGTH(item_db_name); ++fi ) {
+ uint32 lines = 0, count = 0;
+
+ // retrieve all rows from the item database
+ if( SQL_ERROR == Sql_Query(mmysql_handle, "SELECT * FROM `%s`", item_db_name[fi]) ) {
+ Sql_ShowDebug(mmysql_handle);
+ continue;
+ }
+
+ // process rows one by one
+ while( SQL_SUCCESS == Sql_NextRow(mmysql_handle) ) {// wrap the result into a TXT-compatible format
+ char* str[22];
+ char* dummy = "";
+ int i;
+ ++lines;
+ for( i = 0; i < 22; ++i ) {
+ Sql_GetData(mmysql_handle, i, &str[i], NULL);
+ if( str[i] == NULL )
+ str[i] = dummy; // get rid of NULL columns
+ }
+
+ if (!itemdb_parse_dbrow(str, item_db_name[fi], lines, SCRIPT_IGNORE_EXTERNAL_BRACKETS))
+ continue;
+ ++count;
+ }
+
+ // free the query result
+ Sql_FreeResult(mmysql_handle);
+
+ ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, item_db_name[fi]);
+ }
+
+ return 0;
}
/*====================================
* read all item-related databases
*------------------------------------*/
-static void itemdb_read(void)
-{
-
- if (db_use_sqldbs)
- itemdb_read_sqldb();
- else
- itemdb_readdb();
-
- itemdb_read_combos();
- itemdb_read_itemgroup();
- sv_readdb(db_path, "item_avail.txt", ',', 2, 2, -1, &itemdb_read_itemavail);
- sv_readdb(db_path, DBPATH"item_noequip.txt", ',', 2, 2, -1, &itemdb_read_noequip);
- sv_readdb(db_path, DBPATH"item_trade.txt", ',', 3, 3, -1, &itemdb_read_itemtrade);
- sv_readdb(db_path, "item_delay.txt", ',', 2, 2, -1, &itemdb_read_itemdelay);
- sv_readdb(db_path, "item_stack.txt", ',', 3, 3, -1, &itemdb_read_stack);
- sv_readdb(db_path, DBPATH"item_buyingstore.txt", ',', 1, 1, -1, &itemdb_read_buyingstore);
+static void itemdb_read(void) {
+
+ if (db_use_sqldbs)
+ itemdb_read_sqldb();
+ else
+ itemdb_readdb();
+
+ itemdb_read_combos();
+ itemdb_read_itemgroup();
+ sv_readdb(db_path, "item_avail.txt", ',', 2, 2, -1, &itemdb_read_itemavail);
+ sv_readdb(db_path, DBPATH"item_noequip.txt", ',', 2, 2, -1, &itemdb_read_noequip);
+ sv_readdb(db_path, DBPATH"item_trade.txt", ',', 3, 3, -1, &itemdb_read_itemtrade);
+ sv_readdb(db_path, "item_delay.txt", ',', 2, 2, -1, &itemdb_read_itemdelay);
+ sv_readdb(db_path, "item_stack.txt", ',', 3, 3, -1, &itemdb_read_stack);
+ sv_readdb(db_path, DBPATH"item_buyingstore.txt", ',', 1, 1, -1, &itemdb_read_buyingstore);
}
/*==========================================
@@ -1272,35 +1277,35 @@ static void itemdb_read(void)
*------------------------------------------*/
/// Destroys the item_data.
-static void destroy_item_data(struct item_data *self, int free_self)
+static void destroy_item_data(struct item_data* self, int free_self)
{
- if (self == NULL)
- return;
- // free scripts
- if (self->script)
- script_free_code(self->script);
- if (self->equip_script)
- script_free_code(self->equip_script);
- if (self->unequip_script)
- script_free_code(self->unequip_script);
- if (self->combos_count) {
- int i;
- for (i = 0; i < self->combos_count; i++) {
- if (!self->combos[i]->isRef) {
- aFree(self->combos[i]->nameid);
- script_free_code(self->combos[i]->script);
- }
- aFree(self->combos[i]);
- }
- aFree(self->combos);
- }
+ if( self == NULL )
+ return;
+ // free scripts
+ if( self->script )
+ script_free_code(self->script);
+ if( self->equip_script )
+ script_free_code(self->equip_script);
+ if( self->unequip_script )
+ script_free_code(self->unequip_script);
+ if( self->combos_count ) {
+ int i;
+ for( i = 0; i < self->combos_count; i++ ) {
+ if( !self->combos[i]->isRef ) {
+ aFree(self->combos[i]->nameid);
+ script_free_code(self->combos[i]->script);
+ }
+ aFree(self->combos[i]);
+ }
+ aFree(self->combos);
+ }
#if defined(DEBUG)
- // trash item
- memset(self, 0xDD, sizeof(struct item_data));
+ // trash item
+ memset(self, 0xDD, sizeof(struct item_data));
#endif
- // free self
- if (free_self)
- aFree(self);
+ // free self
+ if( free_self )
+ aFree(self);
}
/**
@@ -1308,99 +1313,98 @@ static void destroy_item_data(struct item_data *self, int free_self)
*/
static int itemdb_final_sub(DBKey key, DBData *data, va_list ap)
{
- struct item_data *id = db_data2ptr(data);
+ struct item_data *id = db_data2ptr(data);
- if (id != &dummy_item)
- destroy_item_data(id, 1);
+ if( id != &dummy_item )
+ destroy_item_data(id, 1);
- return 0;
+ return 0;
}
void itemdb_reload(void)
{
- struct s_mapiterator *iter;
- struct map_session_data *sd;
-
- int i,d,k;
-
- // clear the previous itemdb data
- for (i = 0; i < ARRAYLENGTH(itemdb_array); ++i)
- if (itemdb_array[i])
- destroy_item_data(itemdb_array[i], 1);
-
- itemdb_other->clear(itemdb_other, itemdb_final_sub);
-
- memset(itemdb_array, 0, sizeof(itemdb_array));
-
- // read new data
- itemdb_read();
-
- //Epoque's awesome @reloaditemdb fix - thanks! [Ind]
- //- Fixes the need of a @reloadmobdb after a @reloaditemdb to re-link monster drop data
- for (i = 0; i < MAX_MOB_DB; i++) {
- struct mob_db *entry;
- if (!((i < 1324 || i > 1363) && (i < 1938 || i > 1946)))
- continue;
- entry = mob_db(i);
- for (d = 0; d < MAX_MOB_DROP; d++) {
- struct item_data *id;
- if (!entry->dropitem[d].nameid)
- continue;
- id = itemdb_search(entry->dropitem[d].nameid);
-
- for (k = 0; k < MAX_SEARCH; k++) {
- if (id->mob[k].chance <= entry->dropitem[d].p)
- break;
- }
-
- if (k == MAX_SEARCH)
- continue;
-
- if (id->mob[k].id != i)
- memmove(&id->mob[k+1], &id->mob[k], (MAX_SEARCH-k-1)*sizeof(id->mob[0]));
- id->mob[k].chance = entry->dropitem[d].p;
- id->mob[k].id = i;
- }
- }
-
- // readjust itemdb pointer cache for each player
- iter = mapit_geteachpc();
- for (sd = (struct map_session_data *)mapit_first(iter); mapit_exists(iter); sd = (struct map_session_data *)mapit_next(iter)) {
- memset(sd->item_delay, 0, sizeof(sd->item_delay)); // reset item delays
- pc_setinventorydata(sd);
- /* clear combo bonuses */
- if (sd->combos.count) {
- aFree(sd->combos.bonus);
- aFree(sd->combos.id);
- sd->combos.bonus = NULL;
- sd->combos.id = NULL;
- sd->combos.count = 0;
- if (pc_load_combo(sd) > 0)
- status_calc_pc(sd,0);
- }
-
- }
- mapit_free(iter);
+ struct s_mapiterator* iter;
+ struct map_session_data* sd;
+
+ int i,d,k;
+
+ // clear the previous itemdb data
+ for( i = 0; i < ARRAYLENGTH(itemdb_array); ++i )
+ if( itemdb_array[i] )
+ destroy_item_data(itemdb_array[i], 1);
+
+ itemdb_other->clear(itemdb_other, itemdb_final_sub);
+
+ memset(itemdb_array, 0, sizeof(itemdb_array));
+
+ // read new data
+ itemdb_read();
+
+ //Epoque's awesome @reloaditemdb fix - thanks! [Ind]
+ //- Fixes the need of a @reloadmobdb after a @reloaditemdb to re-link monster drop data
+ for( i = 0; i < MAX_MOB_DB; i++ ) {
+ struct mob_db *entry;
+ if( !((i < 1324 || i > 1363) && (i < 1938 || i > 1946)) )
+ continue;
+ entry = mob_db(i);
+ for(d = 0; d < MAX_MOB_DROP; d++) {
+ struct item_data *id;
+ if( !entry->dropitem[d].nameid )
+ continue;
+ id = itemdb_search(entry->dropitem[d].nameid);
+
+ for (k = 0; k < MAX_SEARCH; k++) {
+ if (id->mob[k].chance <= entry->dropitem[d].p)
+ break;
+ }
+
+ if (k == MAX_SEARCH)
+ continue;
+
+ if (id->mob[k].id != i)
+ memmove(&id->mob[k+1], &id->mob[k], (MAX_SEARCH-k-1)*sizeof(id->mob[0]));
+ id->mob[k].chance = entry->dropitem[d].p;
+ id->mob[k].id = i;
+ }
+ }
+
+ // readjust itemdb pointer cache for each player
+ iter = mapit_geteachpc();
+ for( sd = (struct map_session_data*)mapit_first(iter); mapit_exists(iter); sd = (struct map_session_data*)mapit_next(iter) ) {
+ memset(sd->item_delay, 0, sizeof(sd->item_delay)); // reset item delays
+ pc_setinventorydata(sd);
+ /* clear combo bonuses */
+ if( sd->combos.count ) {
+ aFree(sd->combos.bonus);
+ aFree(sd->combos.id);
+ sd->combos.bonus = NULL;
+ sd->combos.id = NULL;
+ sd->combos.count = 0;
+ if( pc_load_combo(sd) > 0 )
+ status_calc_pc(sd,0);
+ }
+
+ }
+ mapit_free(iter);
}
void do_final_itemdb(void)
{
- int i;
+ int i;
- for (i = 0; i < ARRAYLENGTH(itemdb_array); ++i)
- if (itemdb_array[i])
- destroy_item_data(itemdb_array[i], 1);
+ for( i = 0; i < ARRAYLENGTH(itemdb_array); ++i )
+ if( itemdb_array[i] )
+ destroy_item_data(itemdb_array[i], 1);
- itemdb_other->destroy(itemdb_other, itemdb_final_sub);
- destroy_item_data(&dummy_item, 0);
+ itemdb_other->destroy(itemdb_other, itemdb_final_sub);
+ destroy_item_data(&dummy_item, 0);
}
-int do_init_itemdb(void)
-{
- memset(itemdb_array, 0, sizeof(itemdb_array));
- itemdb_other = idb_alloc(DB_OPT_BASE);
- create_dummy_data(); //Dummy data item.
- itemdb_read();
+int do_init_itemdb(void) {
+ memset(itemdb_array, 0, sizeof(itemdb_array));
+ itemdb_other = idb_alloc(DB_OPT_BASE);
+ create_dummy_data(); //Dummy data item.
+ itemdb_read();
- return 0;
+ return 0;
}
diff --git a/src/map/itemdb.h b/src/map/itemdb.h
index d18c35b3a..4d4b62818 100644
--- a/src/map/itemdb.h
+++ b/src/map/itemdb.h
@@ -11,28 +11,28 @@
// 32k array entries in array (the rest goes to the db)
#define MAX_ITEMDB 0x8000
-#define MAX_RANDITEM 11000
+#define MAX_RANDITEM 11000
// The maximum number of item delays
-#define MAX_ITEMDELAYS 10
+#define MAX_ITEMDELAYS 10
-#define MAX_SEARCH 5 //Designed for search functions, species max number of matches to display.
+#define MAX_SEARCH 5 //Designed for search functions, species max number of matches to display.
/* maximum amount of items a combo may require */
#define MAX_ITEMS_PER_COMBO 6
enum item_itemid {
- ITEMID_EMPERIUM = 714,
- ITEMID_YELLOW_GEMSTONE = 715,
- ITEMID_RED_GEMSTONE = 716,
- ITEMID_BLUE_GEMSTONE = 717,
- ITEMID_TRAP = 1065,
- ITEMID_STONE = 7049,
- ITEMID_SKULL_ = 7420,
- ITEMID_TOKEN_OF_SIEGFRIED = 7621,
- ITEMID_TRAP_ALLOY = 7940,
- ITEMID_ANCILLA = 12333,
- ITEMID_REINS_OF_MOUNT = 12622,
+ ITEMID_EMPERIUM = 714,
+ ITEMID_YELLOW_GEMSTONE = 715,
+ ITEMID_RED_GEMSTONE = 716,
+ ITEMID_BLUE_GEMSTONE = 717,
+ ITEMID_TRAP = 1065,
+ ITEMID_STONE = 7049,
+ ITEMID_SKULL_ = 7420,
+ ITEMID_TOKEN_OF_SIEGFRIED = 7621,
+ ITEMID_TRAP_ALLOY = 7940,
+ ITEMID_ANCILLA = 12333,
+ ITEMID_REINS_OF_MOUNT = 12622,
};
/**
@@ -40,33 +40,33 @@ enum item_itemid {
**/
enum {
- ITEMID_NAUTHIZ = 12725,
- ITEMID_RAIDO,
- ITEMID_BERKANA,
- ITEMID_ISA,
- ITEMID_OTHILA,
- ITEMID_URUZ,
- ITEMID_THURISAZ,
- ITEMID_WYRD,
- ITEMID_HAGALAZ,
+ ITEMID_NAUTHIZ = 12725,
+ ITEMID_RAIDO,
+ ITEMID_BERKANA,
+ ITEMID_ISA,
+ ITEMID_OTHILA,
+ ITEMID_URUZ,
+ ITEMID_THURISAZ,
+ ITEMID_WYRD,
+ ITEMID_HAGALAZ,
} rune_list;
/**
* Mechanic
**/
enum {
- ITEMID_ACCELERATOR = 2800,
- ITEMID_HOVERING_BOOSTER,
- ITEMID_SUICIDAL_DEVICE,
- ITEMID_SHAPE_SHIFTER,
- ITEMID_COOLING_DEVICE,
- ITEMID_MAGNETIC_FIELD_GENERATOR,
- ITEMID_BARRIER_BUILDER,
- ITEMID_REPAIR_KIT,
- ITEMID_CAMOUFLAGE_GENERATOR,
- ITEMID_HIGH_QUALITY_COOLER,
- ITEMID_SPECIAL_COOLER,
-} mecha_item_list;
+ ITEMID_ACCELERATOR = 2800,
+ ITEMID_HOVERING_BOOSTER,
+ ITEMID_SUICIDAL_DEVICE,
+ ITEMID_SHAPE_SHIFTER,
+ ITEMID_COOLING_DEVICE,
+ ITEMID_MAGNETIC_FIELD_GENERATOR,
+ ITEMID_BARRIER_BUILDER,
+ ITEMID_REPAIR_KIT,
+ ITEMID_CAMOUFLAGE_GENERATOR,
+ ITEMID_HIGH_QUALITY_COOLER,
+ ITEMID_SPECIAL_COOLER,
+ } mecha_item_list;
//The only item group required by the code to be known. See const.txt for the full list.
#define IG_FINDINGORE 6
@@ -85,82 +85,82 @@ enum {
#define UNKNOWN_ITEM_ID 512
struct item_data {
- int nameid;
- char name[ITEM_NAME_LENGTH],jname[ITEM_NAME_LENGTH];
-
- //Do not add stuff between value_buy and view_id (see how getiteminfo works)
- int value_buy;
- int value_sell;
- int type;
- int maxchance; //For logs, for external game info, for scripts: Max drop chance of this item (e.g. 0.01% , etc.. if it = 0, then monsters don't drop it, -1 denotes items sold in shops only) [Lupus]
- int sex;
- int equip;
- int weight;
- int atk;
- int def;
- int range;
- int slot;
- int look;
- int elv;
- int wlv;
- int view_id;
+ int nameid;
+ char name[ITEM_NAME_LENGTH],jname[ITEM_NAME_LENGTH];
+
+ //Do not add stuff between value_buy and view_id (see how getiteminfo works)
+ int value_buy;
+ int value_sell;
+ int type;
+ int maxchance; //For logs, for external game info, for scripts: Max drop chance of this item (e.g. 0.01% , etc.. if it = 0, then monsters don't drop it, -1 denotes items sold in shops only) [Lupus]
+ int sex;
+ int equip;
+ int weight;
+ int atk;
+ int def;
+ int range;
+ int slot;
+ int look;
+ int elv;
+ int wlv;
+ int view_id;
#ifdef RENEWAL
- int matk;
- int elvmax;/* maximum level for this item */
+ int matk;
+ int elvmax;/* maximum level for this item */
#endif
- int delay;
- //Lupus: I rearranged order of these fields due to compatibility with ITEMINFO script command
- // some script commands should be revised as well...
- unsigned int class_base[3]; //Specifies if the base can wear this item (split in 3 indexes per type: 1-1, 2-1, 2-2)
- unsigned class_upper : 4; //Specifies if the upper-type can equip it (bitfield, 1: normal, 2: upper, 3: baby,4:third)
- struct {
- unsigned short chance;
- int id;
- } mob[MAX_SEARCH]; //Holds the mobs that have the highest drop rate for this item. [Skotlex]
- struct script_code *script; //Default script for everything.
- struct script_code *equip_script; //Script executed once when equipping.
- struct script_code *unequip_script;//Script executed once when unequipping.
- struct {
- unsigned available : 1;
- short no_equip;
- unsigned no_refine : 1; // [celest]
- unsigned delay_consume : 1; // Signifies items that are not consumed immediately upon double-click [Skotlex]
- unsigned trade_restriction : 9; //Item restrictions mask [Skotlex]
- unsigned autoequip: 1;
- unsigned buyingstore : 1;
- } flag;
- struct {// item stacking limitation
- unsigned short amount;
- unsigned int inventory:1;
- unsigned int cart:1;
- unsigned int storage:1;
- unsigned int guildstorage:1;
- } stack;
- short gm_lv_trade_override; //GM-level to override trade_restriction
- /* bugreport:309 */
- struct item_combo **combos;
- unsigned char combos_count;
+ int delay;
+//Lupus: I rearranged order of these fields due to compatibility with ITEMINFO script command
+// some script commands should be revised as well...
+ unsigned int class_base[3]; //Specifies if the base can wear this item (split in 3 indexes per type: 1-1, 2-1, 2-2)
+ unsigned class_upper : 4; //Specifies if the upper-type can equip it (bitfield, 1: normal, 2: upper, 3: baby,4:third)
+ struct {
+ unsigned short chance;
+ int id;
+ } mob[MAX_SEARCH]; //Holds the mobs that have the highest drop rate for this item. [Skotlex]
+ struct script_code *script; //Default script for everything.
+ struct script_code *equip_script; //Script executed once when equipping.
+ struct script_code *unequip_script;//Script executed once when unequipping.
+ struct {
+ unsigned available : 1;
+ short no_equip;
+ unsigned no_refine : 1; // [celest]
+ unsigned delay_consume : 1; // Signifies items that are not consumed immediately upon double-click [Skotlex]
+ unsigned trade_restriction : 9; //Item restrictions mask [Skotlex]
+ unsigned autoequip: 1;
+ unsigned buyingstore : 1;
+ } flag;
+ struct {// item stacking limitation
+ unsigned short amount;
+ unsigned int inventory:1;
+ unsigned int cart:1;
+ unsigned int storage:1;
+ unsigned int guildstorage:1;
+ } stack;
+ short gm_lv_trade_override; //GM-level to override trade_restriction
+ /* bugreport:309 */
+ struct item_combo **combos;
+ unsigned char combos_count;
};
struct item_group {
- int nameid[MAX_RANDITEM];
- int qty; //Counts amount of items in the group.
+ int nameid[MAX_RANDITEM];
+ int qty; //Counts amount of items in the group.
};
struct item_combo {
- struct script_code *script;
- unsigned short *nameid;/* nameid array */
- unsigned char count;
- unsigned short id;/* id of this combo */
- bool isRef;/* whether this struct is a reference or the master */
+ struct script_code *script;
+ unsigned short *nameid;/* nameid array */
+ unsigned char count;
+ unsigned short id;/* id of this combo */
+ bool isRef;/* whether this struct is a reference or the master */
};
-struct item_data *itemdb_searchname(const char *name);
-int itemdb_searchname_array(struct item_data **data, int size, const char *str);
-struct item_data *itemdb_load(int nameid);
-struct item_data *itemdb_search(int nameid);
-struct item_data *itemdb_exists(int nameid);
+struct item_data* itemdb_searchname(const char *name);
+int itemdb_searchname_array(struct item_data** data, int size, const char *str);
+struct item_data* itemdb_load(int nameid);
+struct item_data* itemdb_search(int nameid);
+struct item_data* itemdb_exists(int nameid);
#define itemdb_name(n) itemdb_search(n)->name
#define itemdb_jname(n) itemdb_search(n)->jname
#define itemdb_type(n) itemdb_search(n)->type
@@ -185,9 +185,9 @@ struct item_data *itemdb_exists(int nameid);
#define itemdb_iscashfood(id) ( (id) >= 12202 && (id) <= 12207 )
#define itemdb_is_GNbomb(n) (n >= 13260 && n <= 13267)
#define itemdb_is_GNthrowable(n) (n >= 13268 && n <= 13290)
-const char *itemdb_typename(int type);
+const char* itemdb_typename(int type);
-int itemdb_group_bonus(struct map_session_data *sd, int itemid);
+int itemdb_group_bonus(struct map_session_data* sd, int itemid);
int itemdb_searchrandomid(int flags);
#define itemdb_value_buy(n) itemdb_search(n)->value_buy
@@ -195,22 +195,22 @@ int itemdb_searchrandomid(int flags);
#define itemdb_canrefine(n) (!itemdb_search(n)->flag.no_refine)
//Item trade restrictions [Skotlex]
int itemdb_isdropable_sub(struct item_data *, int, int);
-int itemdb_cantrade_sub(struct item_data *, int, int);
-int itemdb_canpartnertrade_sub(struct item_data *, int, int);
-int itemdb_cansell_sub(struct item_data *,int, int);
-int itemdb_cancartstore_sub(struct item_data *, int, int);
-int itemdb_canstore_sub(struct item_data *, int, int);
-int itemdb_canguildstore_sub(struct item_data *, int, int);
-int itemdb_canmail_sub(struct item_data *, int, int);
-int itemdb_canauction_sub(struct item_data *, int, int);
-int itemdb_isrestricted(struct item *item, int gmlv, int gmlv2, int (*func)(struct item_data *, int, int));
+int itemdb_cantrade_sub(struct item_data*, int, int);
+int itemdb_canpartnertrade_sub(struct item_data*, int, int);
+int itemdb_cansell_sub(struct item_data*,int, int);
+int itemdb_cancartstore_sub(struct item_data*, int, int);
+int itemdb_canstore_sub(struct item_data*, int, int);
+int itemdb_canguildstore_sub(struct item_data*, int, int);
+int itemdb_canmail_sub(struct item_data*, int, int);
+int itemdb_canauction_sub(struct item_data*, int, int);
+int itemdb_isrestricted(struct item* item, int gmlv, int gmlv2, int (*func)(struct item_data*, int, int));
#define itemdb_isdropable(item, gmlv) itemdb_isrestricted(item, gmlv, 0, itemdb_isdropable_sub)
#define itemdb_cantrade(item, gmlv, gmlv2) itemdb_isrestricted(item, gmlv, gmlv2, itemdb_cantrade_sub)
#define itemdb_canpartnertrade(item, gmlv, gmlv2) itemdb_isrestricted(item, gmlv, gmlv2, itemdb_canpartnertrade_sub)
#define itemdb_cansell(item, gmlv) itemdb_isrestricted(item, gmlv, 0, itemdb_cansell_sub)
#define itemdb_cancartstore(item, gmlv) itemdb_isrestricted(item, gmlv, 0, itemdb_cancartstore_sub)
-#define itemdb_canstore(item, gmlv) itemdb_isrestricted(item, gmlv, 0, itemdb_canstore_sub)
-#define itemdb_canguildstore(item, gmlv) itemdb_isrestricted(item , gmlv, 0, itemdb_canguildstore_sub)
+#define itemdb_canstore(item, gmlv) itemdb_isrestricted(item, gmlv, 0, itemdb_canstore_sub)
+#define itemdb_canguildstore(item, gmlv) itemdb_isrestricted(item , gmlv, 0, itemdb_canguildstore_sub)
#define itemdb_canmail(item, gmlv) itemdb_isrestricted(item , gmlv, 0, itemdb_canmail_sub)
#define itemdb_canauction(item, gmlv) itemdb_isrestricted(item , gmlv, 0, itemdb_canauction_sub)
diff --git a/src/map/log.c b/src/map/log.c
index 7663a63bf..749bd5c28 100644
--- a/src/map/log.c
+++ b/src/map/log.c
@@ -19,21 +19,22 @@
/// filters for item logging
-typedef enum e_log_filter {
- LOG_FILTER_NONE = 0x000,
- LOG_FILTER_ALL = 0x001,
- // bits
- LOG_FILTER_HEALING = 0x002, // Healing items (0)
- LOG_FILTER_ETC_AMMO = 0x004, // Etc Items(3) + Arrows (10)
- LOG_FILTER_USABLE = 0x008, // Usable Items(2) + Scrolls, Lures(11) + Usable Cash Items(18)
- LOG_FILTER_WEAPON = 0x010, // Weapons(4)
- LOG_FILTER_ARMOR = 0x020, // Shields, Armors, Headgears, Accessories, Garments and Shoes(5)
- LOG_FILTER_CARD = 0x040, // Cards(6)
- LOG_FILTER_PETITEM = 0x080, // Pet Accessories(8) + Eggs(7) (well, monsters don't drop 'em but we'll use the same system for ALL logs)
- LOG_FILTER_PRICE = 0x100, // Log expensive items ( >= price_log )
- LOG_FILTER_AMOUNT = 0x200, // Log large amount of items ( >= amount_log )
- LOG_FILTER_REFINE = 0x400, // Log refined items ( refine >= refine_log ) [not implemented]
- LOG_FILTER_CHANCE = 0x800, // Log rare items and Emperium ( drop chance <= rare_log )
+typedef enum e_log_filter
+{
+ LOG_FILTER_NONE = 0x000,
+ LOG_FILTER_ALL = 0x001,
+ // bits
+ LOG_FILTER_HEALING = 0x002, // Healing items (0)
+ LOG_FILTER_ETC_AMMO = 0x004, // Etc Items(3) + Arrows (10)
+ LOG_FILTER_USABLE = 0x008, // Usable Items(2) + Scrolls, Lures(11) + Usable Cash Items(18)
+ LOG_FILTER_WEAPON = 0x010, // Weapons(4)
+ LOG_FILTER_ARMOR = 0x020, // Shields, Armors, Headgears, Accessories, Garments and Shoes(5)
+ LOG_FILTER_CARD = 0x040, // Cards(6)
+ LOG_FILTER_PETITEM = 0x080, // Pet Accessories(8) + Eggs(7) (well, monsters don't drop 'em but we'll use the same system for ALL logs)
+ LOG_FILTER_PRICE = 0x100, // Log expensive items ( >= price_log )
+ LOG_FILTER_AMOUNT = 0x200, // Log large amount of items ( >= amount_log )
+ LOG_FILTER_REFINE = 0x400, // Log refined items ( refine >= refine_log ) [not implemented]
+ LOG_FILTER_CHANCE = 0x800, // Log rare items and Emperium ( drop chance <= rare_log )
}
e_log_filter;
@@ -53,515 +54,530 @@ struct Log_Config log_config;
/// obtain log type character for item/zeny logs
static char log_picktype2char(e_log_pick_type type)
{
- switch (type) {
- case LOG_TYPE_TRADE:
- return 'T'; // (T)rade
- case LOG_TYPE_VENDING:
- return 'V'; // (V)ending
- case LOG_TYPE_PICKDROP_PLAYER:
- return 'P'; // (P)player
- case LOG_TYPE_PICKDROP_MONSTER:
- return 'M'; // (M)onster
- case LOG_TYPE_NPC:
- return 'S'; // NPC (S)hop
- case LOG_TYPE_SCRIPT:
- return 'N'; // (N)PC Script
- case LOG_TYPE_STEAL:
- return 'D'; // Steal/Snatcher
- case LOG_TYPE_CONSUME:
- return 'C'; // (C)onsumed
- case LOG_TYPE_PRODUCE:
- return 'O'; // Pr(O)duced/Ingredients
- case LOG_TYPE_MVP:
- return 'U'; // MVP Rewards
- case LOG_TYPE_COMMAND:
- return 'A'; // (A)dmin command
- case LOG_TYPE_STORAGE:
- return 'R'; // Sto(R)age
- case LOG_TYPE_GSTORAGE:
- return 'G'; // (G)uild storage
- case LOG_TYPE_MAIL:
- return 'E'; // (E)mail attachment
- case LOG_TYPE_AUCTION:
- return 'I'; // Auct(I)on
- case LOG_TYPE_BUYING_STORE:
- return 'B'; // (B)uying Store
- case LOG_TYPE_LOOT:
- return 'L'; // (L)oot (consumed monster pick/drop)
- case LOG_TYPE_OTHER:
- return 'X'; // Other
- }
-
- // should not get here, fallback
- ShowDebug("log_picktype2char: Unknown pick type %d.\n", type);
- return 'X';
+ switch( type )
+ {
+ case LOG_TYPE_TRADE: return 'T'; // (T)rade
+ case LOG_TYPE_VENDING: return 'V'; // (V)ending
+ case LOG_TYPE_PICKDROP_PLAYER: return 'P'; // (P)player
+ case LOG_TYPE_PICKDROP_MONSTER: return 'M'; // (M)onster
+ case LOG_TYPE_NPC: return 'S'; // NPC (S)hop
+ case LOG_TYPE_SCRIPT: return 'N'; // (N)PC Script
+ case LOG_TYPE_STEAL: return 'D'; // Steal/Snatcher
+ case LOG_TYPE_CONSUME: return 'C'; // (C)onsumed
+ case LOG_TYPE_PRODUCE: return 'O'; // Pr(O)duced/Ingredients
+ case LOG_TYPE_MVP: return 'U'; // MVP Rewards
+ case LOG_TYPE_COMMAND: return 'A'; // (A)dmin command
+ case LOG_TYPE_STORAGE: return 'R'; // Sto(R)age
+ case LOG_TYPE_GSTORAGE: return 'G'; // (G)uild storage
+ case LOG_TYPE_MAIL: return 'E'; // (E)mail attachment
+ case LOG_TYPE_AUCTION: return 'I'; // Auct(I)on
+ case LOG_TYPE_BUYING_STORE: return 'B'; // (B)uying Store
+ case LOG_TYPE_LOOT: return 'L'; // (L)oot (consumed monster pick/drop)
+ case LOG_TYPE_OTHER: return 'X'; // Other
+ }
+
+ // should not get here, fallback
+ ShowDebug("log_picktype2char: Unknown pick type %d.\n", type);
+ return 'X';
}
/// obtain log type character for chat logs
static char log_chattype2char(e_log_chat_type type)
{
- switch (type) {
- case LOG_CHAT_GLOBAL:
- return 'O'; // Gl(O)bal
- case LOG_CHAT_WHISPER:
- return 'W'; // (W)hisper
- case LOG_CHAT_PARTY:
- return 'P'; // (P)arty
- case LOG_CHAT_GUILD:
- return 'G'; // (G)uild
- case LOG_CHAT_MAINCHAT:
- return 'M'; // (M)ain chat
- }
-
- // should not get here, fallback
- ShowDebug("log_chattype2char: Unknown chat type %d.\n", type);
- return 'O';
+ switch( type )
+ {
+ case LOG_CHAT_GLOBAL: return 'O'; // Gl(O)bal
+ case LOG_CHAT_WHISPER: return 'W'; // (W)hisper
+ case LOG_CHAT_PARTY: return 'P'; // (P)arty
+ case LOG_CHAT_GUILD: return 'G'; // (G)uild
+ case LOG_CHAT_MAINCHAT: return 'M'; // (M)ain chat
+ }
+
+ // should not get here, fallback
+ ShowDebug("log_chattype2char: Unknown chat type %d.\n", type);
+ return 'O';
}
/// check if this item should be logged according the settings
static bool should_log_item(int nameid, int amount, int refine)
{
- int filter = log_config.filter;
- struct item_data *id;
-
- if ((id = itemdb_exists(nameid)) == NULL)
- return false;
-
- if ((filter&LOG_FILTER_ALL) ||
- (filter&LOG_FILTER_HEALING && id->type == IT_HEALING) ||
- (filter&LOG_FILTER_ETC_AMMO && (id->type == IT_ETC || id->type == IT_AMMO)) ||
- (filter&LOG_FILTER_USABLE && (id->type == IT_USABLE || id->type == IT_CASH)) ||
- (filter&LOG_FILTER_WEAPON && id->type == IT_WEAPON) ||
- (filter&LOG_FILTER_ARMOR && id->type == IT_ARMOR) ||
- (filter&LOG_FILTER_CARD && id->type == IT_CARD) ||
- (filter&LOG_FILTER_PETITEM && (id->type == IT_PETEGG || id->type == IT_PETARMOR)) ||
- (filter&LOG_FILTER_PRICE && id->value_buy >= log_config.price_items_log) ||
- (filter&LOG_FILTER_AMOUNT && abs(amount) >= log_config.amount_items_log) ||
- (filter&LOG_FILTER_REFINE && refine >= log_config.refine_items_log) ||
- (filter&LOG_FILTER_CHANCE && ((id->maxchance != -1 && id->maxchance <= log_config.rare_items_log) || id->nameid == ITEMID_EMPERIUM))
- )
- return true;
-
- return false;
+ int filter = log_config.filter;
+ struct item_data* id;
+
+ if( ( id = itemdb_exists(nameid) ) == NULL )
+ return false;
+
+ if( ( filter&LOG_FILTER_ALL ) ||
+ ( filter&LOG_FILTER_HEALING && id->type == IT_HEALING ) ||
+ ( filter&LOG_FILTER_ETC_AMMO && ( id->type == IT_ETC || id->type == IT_AMMO ) ) ||
+ ( filter&LOG_FILTER_USABLE && ( id->type == IT_USABLE || id->type == IT_CASH ) ) ||
+ ( filter&LOG_FILTER_WEAPON && id->type == IT_WEAPON ) ||
+ ( filter&LOG_FILTER_ARMOR && id->type == IT_ARMOR ) ||
+ ( filter&LOG_FILTER_CARD && id->type == IT_CARD ) ||
+ ( filter&LOG_FILTER_PETITEM && ( id->type == IT_PETEGG || id->type == IT_PETARMOR ) ) ||
+ ( filter&LOG_FILTER_PRICE && id->value_buy >= log_config.price_items_log ) ||
+ ( filter&LOG_FILTER_AMOUNT && abs(amount) >= log_config.amount_items_log ) ||
+ ( filter&LOG_FILTER_REFINE && refine >= log_config.refine_items_log ) ||
+ ( filter&LOG_FILTER_CHANCE && ( ( id->maxchance != -1 && id->maxchance <= log_config.rare_items_log ) || id->nameid == ITEMID_EMPERIUM ) )
+ )
+ return true;
+
+ return false;
}
/// logs items, that summon monsters
-void log_branch(struct map_session_data *sd)
+void log_branch(struct map_session_data* sd)
{
- nullpo_retv(sd);
+ nullpo_retv(sd);
- if (!log_config.branch)
- return;
+ if( !log_config.branch )
+ return;
- if (log_config.sql_logs) {
+ if( log_config.sql_logs ) {
#ifdef BETA_THREAD_TEST
- char entry[512];
- int e_length = 0;
- e_length = sprintf(entry, LOG_QUERY " INTO `%s` (`branch_date`, `account_id`, `char_id`, `char_name`, `map`) VALUES (NOW(), '%d', '%d', '%s', '%s')", log_config.log_branch, sd->status.account_id, sd->status.char_id, sd->status.name, mapindex_id2name(sd->mapindex));
- queryThread_log(entry,e_length);
+ char entry[512];
+ int e_length = 0;
+ e_length = sprintf(entry, LOG_QUERY " INTO `%s` (`branch_date`, `account_id`, `char_id`, `char_name`, `map`) VALUES (NOW(), '%d', '%d', '%s', '%s')", log_config.log_branch, sd->status.account_id, sd->status.char_id, sd->status.name, mapindex_id2name(sd->mapindex));
+ queryThread_log(entry,e_length);
#else
- SqlStmt *stmt;
- stmt = SqlStmt_Malloc(logmysql_handle);
- if (SQL_SUCCESS != SqlStmt_Prepare(stmt, LOG_QUERY " INTO `%s` (`branch_date`, `account_id`, `char_id`, `char_name`, `map`) VALUES (NOW(), '%d', '%d', ?, '%s')", log_config.log_branch, sd->status.account_id, sd->status.char_id, mapindex_id2name(sd->mapindex))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, sd->status.name, strnlen(sd->status.name, NAME_LENGTH))
- || SQL_SUCCESS != SqlStmt_Execute(stmt)) {
- SqlStmt_ShowDebug(stmt);
- SqlStmt_Free(stmt);
- return;
- }
- SqlStmt_Free(stmt);
+ SqlStmt* stmt;
+ stmt = SqlStmt_Malloc(logmysql_handle);
+ if( SQL_SUCCESS != SqlStmt_Prepare(stmt, LOG_QUERY " INTO `%s` (`branch_date`, `account_id`, `char_id`, `char_name`, `map`) VALUES (NOW(), '%d', '%d', ?, '%s')", log_config.log_branch, sd->status.account_id, sd->status.char_id, mapindex_id2name(sd->mapindex) )
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, sd->status.name, strnlen(sd->status.name, NAME_LENGTH))
+ || SQL_SUCCESS != SqlStmt_Execute(stmt) )
+ {
+ SqlStmt_ShowDebug(stmt);
+ SqlStmt_Free(stmt);
+ return;
+ }
+ SqlStmt_Free(stmt);
#endif
- } else {
- char timestring[255];
- time_t curtime;
- FILE *logfp;
-
- if ((logfp = fopen(log_config.log_branch, "a")) == NULL)
- return;
- time(&curtime);
- strftime(timestring, sizeof(timestring), "%m/%d/%Y %H:%M:%S", localtime(&curtime));
- fprintf(logfp,"%s - %s[%d:%d]\t%s\n", timestring, sd->status.name, sd->status.account_id, sd->status.char_id, mapindex_id2name(sd->mapindex));
- fclose(logfp);
- }
+ }
+ else
+ {
+ char timestring[255];
+ time_t curtime;
+ FILE* logfp;
+
+ if( ( logfp = fopen(log_config.log_branch, "a") ) == NULL )
+ return;
+ time(&curtime);
+ strftime(timestring, sizeof(timestring), "%m/%d/%Y %H:%M:%S", localtime(&curtime));
+ fprintf(logfp,"%s - %s[%d:%d]\t%s\n", timestring, sd->status.name, sd->status.account_id, sd->status.char_id, mapindex_id2name(sd->mapindex));
+ fclose(logfp);
+ }
}
/// logs item transactions (generic)
-void log_pick(int id, int m, e_log_pick_type type, int amount, struct item *itm)
+void log_pick(int id, int m, e_log_pick_type type, int amount, struct item* itm)
{
- nullpo_retv(itm);
- if ((log_config.enable_logs&type) == 0) {
- // disabled
- return;
- }
+ nullpo_retv(itm);
+ if( ( log_config.enable_logs&type ) == 0 )
+ {// disabled
+ return;
+ }
- if (!should_log_item(itm->nameid, amount, itm->refine))
- return; //we skip logging this item set - it doesn't meet our logging conditions [Lupus]
+ if( !should_log_item(itm->nameid, amount, itm->refine) )
+ return; //we skip logging this item set - it doesn't meet our logging conditions [Lupus]
- if (log_config.sql_logs) {
+ if( log_config.sql_logs )
+ {
#ifdef BETA_THREAD_TEST
- char entry[512];
- int e_length = 0;
- e_length = sprintf(entry, LOG_QUERY " INTO `%s` (`time`, `char_id`, `type`, `nameid`, `amount`, `refine`, `card0`, `card1`, `card2`, `card3`, `map`) VALUES (NOW(), '%d', '%c', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%s')",
- log_config.log_pick, id, log_picktype2char(type), itm->nameid, amount, itm->refine, itm->card[0], itm->card[1], itm->card[2], itm->card[3], map[m].name?map[m].name:"");
- queryThread_log(entry,e_length);
+ char entry[512];
+ int e_length = 0;
+ e_length = sprintf(entry, LOG_QUERY " INTO `%s` (`time`, `char_id`, `type`, `nameid`, `amount`, `refine`, `card0`, `card1`, `card2`, `card3`, `map`) VALUES (NOW(), '%d', '%c', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%s')",
+ log_config.log_pick, id, log_picktype2char(type), itm->nameid, amount, itm->refine, itm->card[0], itm->card[1], itm->card[2], itm->card[3], map[m].name?map[m].name:"" );
+ queryThread_log(entry,e_length);
#else
- if (SQL_ERROR == Sql_Query(logmysql_handle, LOG_QUERY " INTO `%s` (`time`, `char_id`, `type`, `nameid`, `amount`, `refine`, `card0`, `card1`, `card2`, `card3`, `map`) VALUES (NOW(), '%d', '%c', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%s')",
- log_config.log_pick, id, log_picktype2char(type), itm->nameid, amount, itm->refine, itm->card[0], itm->card[1], itm->card[2], itm->card[3], map[m].name?map[m].name:"")) {
- Sql_ShowDebug(logmysql_handle);
- return;
- }
+ if( SQL_ERROR == Sql_Query(logmysql_handle, LOG_QUERY " INTO `%s` (`time`, `char_id`, `type`, `nameid`, `amount`, `refine`, `card0`, `card1`, `card2`, `card3`, `map`) VALUES (NOW(), '%d', '%c', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%s')",
+ log_config.log_pick, id, log_picktype2char(type), itm->nameid, amount, itm->refine, itm->card[0], itm->card[1], itm->card[2], itm->card[3], map[m].name?map[m].name:"") )
+ {
+ Sql_ShowDebug(logmysql_handle);
+ return;
+ }
#endif
- } else {
- char timestring[255];
- time_t curtime;
- FILE *logfp;
-
- if ((logfp = fopen(log_config.log_pick, "a")) == NULL)
- return;
- time(&curtime);
- strftime(timestring, sizeof(timestring), "%m/%d/%Y %H:%M:%S", localtime(&curtime));
- fprintf(logfp,"%s - %d\t%c\t%d,%d,%d,%d,%d,%d,%d,%s\n", timestring, id, log_picktype2char(type), itm->nameid, amount, itm->refine, itm->card[0], itm->card[1], itm->card[2], itm->card[3], map[m].name?map[m].name:"");
- fclose(logfp);
- }
+ }
+ else
+ {
+ char timestring[255];
+ time_t curtime;
+ FILE* logfp;
+
+ if( ( logfp = fopen(log_config.log_pick, "a") ) == NULL )
+ return;
+ time(&curtime);
+ strftime(timestring, sizeof(timestring), "%m/%d/%Y %H:%M:%S", localtime(&curtime));
+ fprintf(logfp,"%s - %d\t%c\t%d,%d,%d,%d,%d,%d,%d,%s\n", timestring, id, log_picktype2char(type), itm->nameid, amount, itm->refine, itm->card[0], itm->card[1], itm->card[2], itm->card[3], map[m].name?map[m].name:"");
+ fclose(logfp);
+ }
}
/// logs item transactions (players)
-void log_pick_pc(struct map_session_data *sd, e_log_pick_type type, int amount, struct item *itm)
+void log_pick_pc(struct map_session_data* sd, e_log_pick_type type, int amount, struct item* itm)
{
- nullpo_retv(sd);
- log_pick(sd->status.char_id, sd->bl.m, type, amount, itm);
+ nullpo_retv(sd);
+ log_pick(sd->status.char_id, sd->bl.m, type, amount, itm);
}
/// logs item transactions (monsters)
-void log_pick_mob(struct mob_data *md, e_log_pick_type type, int amount, struct item *itm)
+void log_pick_mob(struct mob_data* md, e_log_pick_type type, int amount, struct item* itm)
{
- nullpo_retv(md);
- log_pick(md->class_, md->bl.m, type, amount, itm);
+ nullpo_retv(md);
+ log_pick(md->class_, md->bl.m, type, amount, itm);
}
/// logs zeny transactions
-void log_zeny(struct map_session_data *sd, e_log_pick_type type, struct map_session_data *src_sd, int amount)
+void log_zeny(struct map_session_data* sd, e_log_pick_type type, struct map_session_data* src_sd, int amount)
{
- nullpo_retv(sd);
+ nullpo_retv(sd);
- if (!log_config.zeny || (log_config.zeny != 1 && abs(amount) < log_config.zeny))
- return;
+ if( !log_config.zeny || ( log_config.zeny != 1 && abs(amount) < log_config.zeny ) )
+ return;
- if (log_config.sql_logs) {
+ if( log_config.sql_logs )
+ {
#ifdef BETA_THREAD_TEST
- char entry[512];
- int e_length = 0;
- e_length = sprintf(entry, LOG_QUERY " INTO `%s` (`time`, `char_id`, `src_id`, `type`, `amount`, `map`) VALUES (NOW(), '%d', '%d', '%c', '%d', '%s')",
- log_config.log_zeny, sd->status.char_id, src_sd->status.char_id, log_picktype2char(type), amount, mapindex_id2name(sd->mapindex));
- queryThread_log(entry,e_length);
+ char entry[512];
+ int e_length = 0;
+ e_length = sprintf(entry, LOG_QUERY " INTO `%s` (`time`, `char_id`, `src_id`, `type`, `amount`, `map`) VALUES (NOW(), '%d', '%d', '%c', '%d', '%s')",
+ log_config.log_zeny, sd->status.char_id, src_sd->status.char_id, log_picktype2char(type), amount, mapindex_id2name(sd->mapindex));
+ queryThread_log(entry,e_length);
#else
- if (SQL_ERROR == Sql_Query(logmysql_handle, LOG_QUERY " INTO `%s` (`time`, `char_id`, `src_id`, `type`, `amount`, `map`) VALUES (NOW(), '%d', '%d', '%c', '%d', '%s')",
- log_config.log_zeny, sd->status.char_id, src_sd->status.char_id, log_picktype2char(type), amount, mapindex_id2name(sd->mapindex))) {
- Sql_ShowDebug(logmysql_handle);
- return;
- }
+ if( SQL_ERROR == Sql_Query(logmysql_handle, LOG_QUERY " INTO `%s` (`time`, `char_id`, `src_id`, `type`, `amount`, `map`) VALUES (NOW(), '%d', '%d', '%c', '%d', '%s')",
+ log_config.log_zeny, sd->status.char_id, src_sd->status.char_id, log_picktype2char(type), amount, mapindex_id2name(sd->mapindex)) )
+ {
+ Sql_ShowDebug(logmysql_handle);
+ return;
+ }
#endif
- } else {
- char timestring[255];
- time_t curtime;
- FILE *logfp;
-
- if ((logfp = fopen(log_config.log_zeny, "a")) == NULL)
- return;
- time(&curtime);
- strftime(timestring, sizeof(timestring), "%m/%d/%Y %H:%M:%S", localtime(&curtime));
- fprintf(logfp, "%s - %s[%d]\t%s[%d]\t%d\t\n", timestring, src_sd->status.name, src_sd->status.account_id, sd->status.name, sd->status.account_id, amount);
- fclose(logfp);
- }
+ }
+ else
+ {
+ char timestring[255];
+ time_t curtime;
+ FILE* logfp;
+
+ if( ( logfp = fopen(log_config.log_zeny, "a") ) == NULL )
+ return;
+ time(&curtime);
+ strftime(timestring, sizeof(timestring), "%m/%d/%Y %H:%M:%S", localtime(&curtime));
+ fprintf(logfp, "%s - %s[%d]\t%s[%d]\t%d\t\n", timestring, src_sd->status.name, src_sd->status.account_id, sd->status.name, sd->status.account_id, amount);
+ fclose(logfp);
+ }
}
/// logs MVP monster rewards
-void log_mvpdrop(struct map_session_data *sd, int monster_id, int *log_mvp)
+void log_mvpdrop(struct map_session_data* sd, int monster_id, int* log_mvp)
{
- nullpo_retv(sd);
+ nullpo_retv(sd);
- if (!log_config.mvpdrop)
- return;
+ if( !log_config.mvpdrop )
+ return;
- if (log_config.sql_logs) {
+ if( log_config.sql_logs )
+ {
#ifdef BETA_THREAD_TEST
- char entry[512];
- int e_length = 0;
- e_length = sprintf(entry, LOG_QUERY " INTO `%s` (`mvp_date`, `kill_char_id`, `monster_id`, `prize`, `mvpexp`, `map`) VALUES (NOW(), '%d', '%d', '%d', '%d', '%s') ",
- log_config.log_mvpdrop, sd->status.char_id, monster_id, log_mvp[0], log_mvp[1], mapindex_id2name(sd->mapindex));
- queryThread_log(entry,e_length);
-#else
- if (SQL_ERROR == Sql_Query(logmysql_handle, LOG_QUERY " INTO `%s` (`mvp_date`, `kill_char_id`, `monster_id`, `prize`, `mvpexp`, `map`) VALUES (NOW(), '%d', '%d', '%d', '%d', '%s') ",
- log_config.log_mvpdrop, sd->status.char_id, monster_id, log_mvp[0], log_mvp[1], mapindex_id2name(sd->mapindex))) {
- Sql_ShowDebug(logmysql_handle);
- return;
- }
+ char entry[512];
+ int e_length = 0;
+ e_length = sprintf(entry, LOG_QUERY " INTO `%s` (`mvp_date`, `kill_char_id`, `monster_id`, `prize`, `mvpexp`, `map`) VALUES (NOW(), '%d', '%d', '%d', '%d', '%s') ",
+ log_config.log_mvpdrop, sd->status.char_id, monster_id, log_mvp[0], log_mvp[1], mapindex_id2name(sd->mapindex));
+ queryThread_log(entry,e_length);
+#else
+ if( SQL_ERROR == Sql_Query(logmysql_handle, LOG_QUERY " INTO `%s` (`mvp_date`, `kill_char_id`, `monster_id`, `prize`, `mvpexp`, `map`) VALUES (NOW(), '%d', '%d', '%d', '%d', '%s') ",
+ log_config.log_mvpdrop, sd->status.char_id, monster_id, log_mvp[0], log_mvp[1], mapindex_id2name(sd->mapindex)) )
+ {
+ Sql_ShowDebug(logmysql_handle);
+ return;
+ }
#endif
- } else {
- char timestring[255];
- time_t curtime;
- FILE *logfp;
-
- if ((logfp = fopen(log_config.log_mvpdrop,"a")) == NULL)
- return;
- time(&curtime);
- strftime(timestring, sizeof(timestring), "%m/%d/%Y %H:%M:%S", localtime(&curtime));
- fprintf(logfp,"%s - %s[%d:%d]\t%d\t%d,%d\n", timestring, sd->status.name, sd->status.account_id, sd->status.char_id, monster_id, log_mvp[0], log_mvp[1]);
- fclose(logfp);
- }
+ }
+ else
+ {
+ char timestring[255];
+ time_t curtime;
+ FILE* logfp;
+
+ if( ( logfp = fopen(log_config.log_mvpdrop,"a") ) == NULL )
+ return;
+ time(&curtime);
+ strftime(timestring, sizeof(timestring), "%m/%d/%Y %H:%M:%S", localtime(&curtime));
+ fprintf(logfp,"%s - %s[%d:%d]\t%d\t%d,%d\n", timestring, sd->status.name, sd->status.account_id, sd->status.char_id, monster_id, log_mvp[0], log_mvp[1]);
+ fclose(logfp);
+ }
}
/// logs used atcommands
-void log_atcommand(struct map_session_data *sd, const char *message)
+void log_atcommand(struct map_session_data* sd, const char* message)
{
- nullpo_retv(sd);
+ nullpo_retv(sd);
- if (!log_config.commands ||
- !pc_should_log_commands(sd))
- return;
+ if( !log_config.commands ||
+ !pc_should_log_commands(sd) )
+ return;
- if (log_config.sql_logs) {
+ if( log_config.sql_logs )
+ {
#ifdef BETA_THREAD_TEST
- char entry[512];
- int e_length = 0;
- e_length = sprintf(entry, LOG_QUERY " INTO `%s` (`atcommand_date`, `account_id`, `char_id`, `char_name`, `map`, `command`) VALUES (NOW(), '%d', '%d', '%s', '%s', '%s')", log_config.log_gm, sd->status.account_id, sd->status.char_id, sd->status.name ,mapindex_id2name(sd->mapindex), message);
- queryThread_log(entry,e_length);
-#else
- SqlStmt *stmt;
-
- stmt = SqlStmt_Malloc(logmysql_handle);
- if (SQL_SUCCESS != SqlStmt_Prepare(stmt, LOG_QUERY " INTO `%s` (`atcommand_date`, `account_id`, `char_id`, `char_name`, `map`, `command`) VALUES (NOW(), '%d', '%d', ?, '%s', ?)", log_config.log_gm, sd->status.account_id, sd->status.char_id, mapindex_id2name(sd->mapindex))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, sd->status.name, strnlen(sd->status.name, NAME_LENGTH))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (char *)message, safestrnlen(message, 255))
- || SQL_SUCCESS != SqlStmt_Execute(stmt)) {
- SqlStmt_ShowDebug(stmt);
- SqlStmt_Free(stmt);
- return;
- }
- SqlStmt_Free(stmt);
+ char entry[512];
+ int e_length = 0;
+ e_length = sprintf(entry, LOG_QUERY " INTO `%s` (`atcommand_date`, `account_id`, `char_id`, `char_name`, `map`, `command`) VALUES (NOW(), '%d', '%d', '%s', '%s', '%s')", log_config.log_gm, sd->status.account_id, sd->status.char_id, sd->status.name ,mapindex_id2name(sd->mapindex), message);
+ queryThread_log(entry,e_length);
+#else
+ SqlStmt* stmt;
+
+ stmt = SqlStmt_Malloc(logmysql_handle);
+ if( SQL_SUCCESS != SqlStmt_Prepare(stmt, LOG_QUERY " INTO `%s` (`atcommand_date`, `account_id`, `char_id`, `char_name`, `map`, `command`) VALUES (NOW(), '%d', '%d', ?, '%s', ?)", log_config.log_gm, sd->status.account_id, sd->status.char_id, mapindex_id2name(sd->mapindex) )
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, sd->status.name, strnlen(sd->status.name, NAME_LENGTH))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (char*)message, safestrnlen(message, 255))
+ || SQL_SUCCESS != SqlStmt_Execute(stmt) )
+ {
+ SqlStmt_ShowDebug(stmt);
+ SqlStmt_Free(stmt);
+ return;
+ }
+ SqlStmt_Free(stmt);
#endif
- } else {
- char timestring[255];
- time_t curtime;
- FILE *logfp;
-
- if ((logfp = fopen(log_config.log_gm, "a")) == NULL)
- return;
- time(&curtime);
- strftime(timestring, sizeof(timestring), "%m/%d/%Y %H:%M:%S", localtime(&curtime));
- fprintf(logfp, "%s - %s[%d]: %s\n", timestring, sd->status.name, sd->status.account_id, message);
- fclose(logfp);
- }
+ }
+ else
+ {
+ char timestring[255];
+ time_t curtime;
+ FILE* logfp;
+
+ if( ( logfp = fopen(log_config.log_gm, "a") ) == NULL )
+ return;
+ time(&curtime);
+ strftime(timestring, sizeof(timestring), "%m/%d/%Y %H:%M:%S", localtime(&curtime));
+ fprintf(logfp, "%s - %s[%d]: %s\n", timestring, sd->status.name, sd->status.account_id, message);
+ fclose(logfp);
+ }
}
/// logs messages passed to script command 'logmes'
-void log_npc(struct map_session_data *sd, const char *message)
+void log_npc(struct map_session_data* sd, const char* message)
{
- nullpo_retv(sd);
+ nullpo_retv(sd);
- if (!log_config.npc)
- return;
+ if( !log_config.npc )
+ return;
- if (log_config.sql_logs) {
+ if( log_config.sql_logs )
+ {
#ifdef BETA_THREAD_TEST
- char entry[512];
- int e_length = 0;
- e_length = sprintf(entry, LOG_QUERY " INTO `%s` (`npc_date`, `account_id`, `char_id`, `char_name`, `map`, `mes`) VALUES (NOW(), '%d', '%d', '%s', '%s', '%s')", log_config.log_npc, sd->status.account_id, sd->status.char_id, sd->status.name, mapindex_id2name(sd->mapindex), message);
- queryThread_log(entry,e_length);
-#else
- SqlStmt *stmt;
- stmt = SqlStmt_Malloc(logmysql_handle);
- if (SQL_SUCCESS != SqlStmt_Prepare(stmt, LOG_QUERY " INTO `%s` (`npc_date`, `account_id`, `char_id`, `char_name`, `map`, `mes`) VALUES (NOW(), '%d', '%d', ?, '%s', ?)", log_config.log_npc, sd->status.account_id, sd->status.char_id, mapindex_id2name(sd->mapindex))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, sd->status.name, strnlen(sd->status.name, NAME_LENGTH))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (char *)message, safestrnlen(message, 255))
- || SQL_SUCCESS != SqlStmt_Execute(stmt)) {
- SqlStmt_ShowDebug(stmt);
- SqlStmt_Free(stmt);
- return;
- }
- SqlStmt_Free(stmt);
+ char entry[512];
+ int e_length = 0;
+ e_length = sprintf(entry, LOG_QUERY " INTO `%s` (`npc_date`, `account_id`, `char_id`, `char_name`, `map`, `mes`) VALUES (NOW(), '%d', '%d', '%s', '%s', '%s')", log_config.log_npc, sd->status.account_id, sd->status.char_id, sd->status.name, mapindex_id2name(sd->mapindex), message );
+ queryThread_log(entry,e_length);
+#else
+ SqlStmt* stmt;
+ stmt = SqlStmt_Malloc(logmysql_handle);
+ if( SQL_SUCCESS != SqlStmt_Prepare(stmt, LOG_QUERY " INTO `%s` (`npc_date`, `account_id`, `char_id`, `char_name`, `map`, `mes`) VALUES (NOW(), '%d', '%d', ?, '%s', ?)", log_config.log_npc, sd->status.account_id, sd->status.char_id, mapindex_id2name(sd->mapindex) )
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, sd->status.name, strnlen(sd->status.name, NAME_LENGTH))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (char*)message, safestrnlen(message, 255))
+ || SQL_SUCCESS != SqlStmt_Execute(stmt) )
+ {
+ SqlStmt_ShowDebug(stmt);
+ SqlStmt_Free(stmt);
+ return;
+ }
+ SqlStmt_Free(stmt);
#endif
- } else {
- char timestring[255];
- time_t curtime;
- FILE *logfp;
-
- if ((logfp = fopen(log_config.log_npc, "a")) == NULL)
- return;
- time(&curtime);
- strftime(timestring, sizeof(timestring), "%m/%d/%Y %H:%M:%S", localtime(&curtime));
- fprintf(logfp, "%s - %s[%d]: %s\n", timestring, sd->status.name, sd->status.account_id, message);
- fclose(logfp);
- }
+ }
+ else
+ {
+ char timestring[255];
+ time_t curtime;
+ FILE* logfp;
+
+ if( ( logfp = fopen(log_config.log_npc, "a") ) == NULL )
+ return;
+ time(&curtime);
+ strftime(timestring, sizeof(timestring), "%m/%d/%Y %H:%M:%S", localtime(&curtime));
+ fprintf(logfp, "%s - %s[%d]: %s\n", timestring, sd->status.name, sd->status.account_id, message);
+ fclose(logfp);
+ }
}
/// logs chat
-void log_chat(e_log_chat_type type, int type_id, int src_charid, int src_accid, const char *map, int x, int y, const char *dst_charname, const char *message)
+void log_chat(e_log_chat_type type, int type_id, int src_charid, int src_accid, const char* map, int x, int y, const char* dst_charname, const char* message)
{
- if ((log_config.chat&type) == 0) {
- // disabled
- return;
- }
+ if( ( log_config.chat&type ) == 0 )
+ {// disabled
+ return;
+ }
- if (log_config.log_chat_woe_disable && (agit_flag || agit2_flag)) {
- // no chat logging during woe
- return;
- }
+ if( log_config.log_chat_woe_disable && ( agit_flag || agit2_flag ) )
+ {// no chat logging during woe
+ return;
+ }
- if (log_config.sql_logs) {
+ if( log_config.sql_logs ) {
#ifdef BETA_THREAD_TEST
- char entry[512];
- int e_length = 0;
- e_length = sprintf(entry, LOG_QUERY " INTO `%s` (`time`, `type`, `type_id`, `src_charid`, `src_accountid`, `src_map`, `src_map_x`, `src_map_y`, `dst_charname`, `message`) VALUES (NOW(), '%c', '%d', '%d', '%d', '%s', '%d', '%d', '%s', '%s')", log_config.log_chat, log_chattype2char(type), type_id, src_charid, src_accid, map, x, y, dst_charname, message);
- queryThread_log(entry,e_length);
-#else
- SqlStmt *stmt;
-
- stmt = SqlStmt_Malloc(logmysql_handle);
- if (SQL_SUCCESS != SqlStmt_Prepare(stmt, LOG_QUERY " INTO `%s` (`time`, `type`, `type_id`, `src_charid`, `src_accountid`, `src_map`, `src_map_x`, `src_map_y`, `dst_charname`, `message`) VALUES (NOW(), '%c', '%d', '%d', '%d', '%s', '%d', '%d', ?, ?)", log_config.log_chat, log_chattype2char(type), type_id, src_charid, src_accid, map, x, y)
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, (char *)dst_charname, safestrnlen(dst_charname, NAME_LENGTH))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (char *)message, safestrnlen(message, CHAT_SIZE_MAX))
- || SQL_SUCCESS != SqlStmt_Execute(stmt)) {
- SqlStmt_ShowDebug(stmt);
- SqlStmt_Free(stmt);
- return;
- }
- SqlStmt_Free(stmt);
+ char entry[512];
+ int e_length = 0;
+ e_length = sprintf(entry, LOG_QUERY " INTO `%s` (`time`, `type`, `type_id`, `src_charid`, `src_accountid`, `src_map`, `src_map_x`, `src_map_y`, `dst_charname`, `message`) VALUES (NOW(), '%c', '%d', '%d', '%d', '%s', '%d', '%d', '%s', '%s')", log_config.log_chat, log_chattype2char(type), type_id, src_charid, src_accid, map, x, y, dst_charname, message );
+ queryThread_log(entry,e_length);
+#else
+ SqlStmt* stmt;
+
+ stmt = SqlStmt_Malloc(logmysql_handle);
+ if( SQL_SUCCESS != SqlStmt_Prepare(stmt, LOG_QUERY " INTO `%s` (`time`, `type`, `type_id`, `src_charid`, `src_accountid`, `src_map`, `src_map_x`, `src_map_y`, `dst_charname`, `message`) VALUES (NOW(), '%c', '%d', '%d', '%d', '%s', '%d', '%d', ?, ?)", log_config.log_chat, log_chattype2char(type), type_id, src_charid, src_accid, map, x, y)
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, (char*)dst_charname, safestrnlen(dst_charname, NAME_LENGTH))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (char*)message, safestrnlen(message, CHAT_SIZE_MAX))
+ || SQL_SUCCESS != SqlStmt_Execute(stmt) )
+ {
+ SqlStmt_ShowDebug(stmt);
+ SqlStmt_Free(stmt);
+ return;
+ }
+ SqlStmt_Free(stmt);
#endif
- } else {
- char timestring[255];
- time_t curtime;
- FILE *logfp;
-
- if ((logfp = fopen(log_config.log_chat, "a")) == NULL)
- return;
- time(&curtime);
- strftime(timestring, sizeof(timestring), "%m/%d/%Y %H:%M:%S", localtime(&curtime));
- fprintf(logfp, "%s - %c,%d,%d,%d,%s,%d,%d,%s,%s\n", timestring, log_chattype2char(type), type_id, src_charid, src_accid, map, x, y, dst_charname, message);
- fclose(logfp);
- }
+ }
+ else
+ {
+ char timestring[255];
+ time_t curtime;
+ FILE* logfp;
+
+ if( ( logfp = fopen(log_config.log_chat, "a") ) == NULL )
+ return;
+ time(&curtime);
+ strftime(timestring, sizeof(timestring), "%m/%d/%Y %H:%M:%S", localtime(&curtime));
+ fprintf(logfp, "%s - %c,%d,%d,%d,%s,%d,%d,%s,%s\n", timestring, log_chattype2char(type), type_id, src_charid, src_accid, map, x, y, dst_charname, message);
+ fclose(logfp);
+ }
}
void log_set_defaults(void)
{
- memset(&log_config, 0, sizeof(log_config));
+ memset(&log_config, 0, sizeof(log_config));
- //LOG FILTER Default values
- log_config.refine_items_log = 5; // log refined items, with refine >= +5
- 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;
+ //LOG FILTER Default values
+ log_config.refine_items_log = 5; // log refined items, with refine >= +5
+ 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;
}
-int log_config_read(const char *cfgName)
+int log_config_read(const char* cfgName)
{
- static int count = 0;
- char line[1024], w1[1024], w2[1024];
- FILE *fp;
-
- if (count++ == 0)
- log_set_defaults();
-
- if ((fp = fopen(cfgName, "r")) == NULL) {
- ShowError("Log configuration file not found at: %s\n", cfgName);
- return 1;
- }
-
- while (fgets(line, sizeof(line), fp)) {
- if (line[0] == '/' && line[1] == '/')
- continue;
-
- if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) == 2) {
- if (strcmpi(w1, "enable_logs") == 0)
- log_config.enable_logs = (e_log_pick_type)config_switch(w2);
- else if (strcmpi(w1, "sql_logs") == 0)
- log_config.sql_logs = (bool)config_switch(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 = config_switch(w2);
- else if (strcmpi(w1, "log_filter") == 0)
- log_config.filter = config_switch(w2);
- else if (strcmpi(w1, "log_zeny") == 0)
- log_config.zeny = config_switch(w2);
- else if (strcmpi(w1, "log_commands") == 0)
- log_config.commands = config_switch(w2);
- else if (strcmpi(w1, "log_npc") == 0)
- log_config.npc = config_switch(w2);
- else if (strcmpi(w1, "log_chat") == 0)
- log_config.chat = config_switch(w2);
- else if (strcmpi(w1, "log_mvpdrop") == 0)
- log_config.mvpdrop = config_switch(w2);
- else if (strcmpi(w1, "log_chat_woe_disable") == 0)
- log_config.log_chat_woe_disable = (bool)config_switch(w2);
- else if (strcmpi(w1, "log_branch_db") == 0)
- safestrncpy(log_config.log_branch, w2, sizeof(log_config.log_branch));
- else if (strcmpi(w1, "log_pick_db") == 0)
- safestrncpy(log_config.log_pick, w2, sizeof(log_config.log_pick));
- else if (strcmpi(w1, "log_zeny_db") == 0)
- safestrncpy(log_config.log_zeny, w2, sizeof(log_config.log_zeny));
- else if (strcmpi(w1, "log_mvpdrop_db") == 0)
- safestrncpy(log_config.log_mvpdrop, w2, sizeof(log_config.log_mvpdrop));
- else if (strcmpi(w1, "log_gm_db") == 0)
- safestrncpy(log_config.log_gm, w2, sizeof(log_config.log_gm));
- else if (strcmpi(w1, "log_npc_db") == 0)
- safestrncpy(log_config.log_npc, w2, sizeof(log_config.log_npc));
- else if (strcmpi(w1, "log_chat_db") == 0)
- safestrncpy(log_config.log_chat, w2, sizeof(log_config.log_chat));
- //support the import command, just like any other config
- else if (strcmpi(w1,"import") == 0)
- log_config_read(w2);
- else
- ShowWarning("Unknown setting '%s' in file %s\n", w1, cfgName);
- }
- }
-
- fclose(fp);
-
- if (--count == 0) {
- // report final logging state
- const char *target = log_config.sql_logs ? "table" : "file";
-
- if (log_config.enable_logs && log_config.filter) {
- ShowInfo("Logging item transactions to %s '%s'.\n", target, log_config.log_pick);
- }
- if (log_config.branch) {
- ShowInfo("Logging monster summon item usage to %s '%s'.\n", target, log_config.log_pick);
- }
- if (log_config.chat) {
- ShowInfo("Logging chat to %s '%s'.\n", target, log_config.log_chat);
- }
- if (log_config.commands) {
- ShowInfo("Logging commands to %s '%s'.\n", target, log_config.log_gm);
- }
- if (log_config.mvpdrop) {
- ShowInfo("Logging MVP monster rewards to %s '%s'.\n", target, log_config.log_mvpdrop);
- }
- if (log_config.npc) {
- ShowInfo("Logging 'logmes' messages to %s '%s'.\n", target, log_config.log_npc);
- }
- if (log_config.zeny) {
- ShowInfo("Logging Zeny transactions to %s '%s'.\n", target, log_config.log_zeny);
- }
- }
-
- return 0;
+ static int count = 0;
+ char line[1024], w1[1024], w2[1024];
+ FILE *fp;
+
+ if( count++ == 0 )
+ log_set_defaults();
+
+ if( ( fp = fopen(cfgName, "r") ) == NULL )
+ {
+ ShowError("Log configuration file not found at: %s\n", cfgName);
+ return 1;
+ }
+
+ while( fgets(line, sizeof(line), fp) )
+ {
+ if( line[0] == '/' && line[1] == '/' )
+ continue;
+
+ if( sscanf(line, "%[^:]: %[^\r\n]", w1, w2) == 2 )
+ {
+ if( strcmpi(w1, "enable_logs") == 0 )
+ log_config.enable_logs = (e_log_pick_type)config_switch(w2);
+ else if( strcmpi(w1, "sql_logs") == 0 )
+ log_config.sql_logs = (bool)config_switch(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 = config_switch(w2);
+ else if( strcmpi(w1, "log_filter") == 0 )
+ log_config.filter = config_switch(w2);
+ else if( strcmpi(w1, "log_zeny") == 0 )
+ log_config.zeny = config_switch(w2);
+ else if( strcmpi(w1, "log_commands") == 0 )
+ log_config.commands = config_switch(w2);
+ else if( strcmpi(w1, "log_npc") == 0 )
+ log_config.npc = config_switch(w2);
+ else if( strcmpi(w1, "log_chat") == 0 )
+ log_config.chat = config_switch(w2);
+ else if( strcmpi(w1, "log_mvpdrop") == 0 )
+ log_config.mvpdrop = config_switch(w2);
+ else if( strcmpi(w1, "log_chat_woe_disable") == 0 )
+ log_config.log_chat_woe_disable = (bool)config_switch(w2);
+ else if( strcmpi(w1, "log_branch_db") == 0 )
+ safestrncpy(log_config.log_branch, w2, sizeof(log_config.log_branch));
+ else if( strcmpi(w1, "log_pick_db") == 0 )
+ safestrncpy(log_config.log_pick, w2, sizeof(log_config.log_pick));
+ else if( strcmpi(w1, "log_zeny_db") == 0 )
+ safestrncpy(log_config.log_zeny, w2, sizeof(log_config.log_zeny));
+ else if( strcmpi(w1, "log_mvpdrop_db") == 0 )
+ safestrncpy(log_config.log_mvpdrop, w2, sizeof(log_config.log_mvpdrop));
+ else if( strcmpi(w1, "log_gm_db") == 0 )
+ safestrncpy(log_config.log_gm, w2, sizeof(log_config.log_gm));
+ else if( strcmpi(w1, "log_npc_db") == 0 )
+ safestrncpy(log_config.log_npc, w2, sizeof(log_config.log_npc));
+ else if( strcmpi(w1, "log_chat_db") == 0 )
+ safestrncpy(log_config.log_chat, w2, sizeof(log_config.log_chat));
+ //support the import command, just like any other config
+ else if( strcmpi(w1,"import") == 0 )
+ log_config_read(w2);
+ else
+ ShowWarning("Unknown setting '%s' in file %s\n", w1, cfgName);
+ }
+ }
+
+ fclose(fp);
+
+ if( --count == 0 )
+ {// report final logging state
+ const char* target = log_config.sql_logs ? "table" : "file";
+
+ if( log_config.enable_logs && log_config.filter )
+ {
+ ShowInfo("Logging item transactions to %s '%s'.\n", target, log_config.log_pick);
+ }
+ if( log_config.branch )
+ {
+ ShowInfo("Logging monster summon item usage to %s '%s'.\n", target, log_config.log_pick);
+ }
+ if( log_config.chat )
+ {
+ ShowInfo("Logging chat to %s '%s'.\n", target, log_config.log_chat);
+ }
+ if( log_config.commands )
+ {
+ ShowInfo("Logging commands to %s '%s'.\n", target, log_config.log_gm);
+ }
+ if( log_config.mvpdrop )
+ {
+ ShowInfo("Logging MVP monster rewards to %s '%s'.\n", target, log_config.log_mvpdrop);
+ }
+ if( log_config.npc )
+ {
+ ShowInfo("Logging 'logmes' messages to %s '%s'.\n", target, log_config.log_npc);
+ }
+ if( log_config.zeny )
+ {
+ ShowInfo("Logging Zeny transactions to %s '%s'.\n", target, log_config.log_zeny);
+ }
+ }
+
+ return 0;
}
diff --git a/src/map/log.h b/src/map/log.h
index 051e31fc0..a40a3fcf4 100644
--- a/src/map/log.h
+++ b/src/map/log.h
@@ -11,76 +11,79 @@ struct mob_data;
struct item;
-typedef enum e_log_chat_type {
- LOG_CHAT_GLOBAL = 0x01,
- LOG_CHAT_WHISPER = 0x02,
- LOG_CHAT_PARTY = 0x04,
- LOG_CHAT_GUILD = 0x08,
- LOG_CHAT_MAINCHAT = 0x10,
- // all
- LOG_CHAT_ALL = 0xFF,
+typedef enum e_log_chat_type
+{
+ LOG_CHAT_GLOBAL = 0x01,
+ LOG_CHAT_WHISPER = 0x02,
+ LOG_CHAT_PARTY = 0x04,
+ LOG_CHAT_GUILD = 0x08,
+ LOG_CHAT_MAINCHAT = 0x10,
+ // all
+ LOG_CHAT_ALL = 0xFF,
}
e_log_chat_type;
-typedef enum e_log_pick_type {
- LOG_TYPE_NONE = 0,
- LOG_TYPE_TRADE = 0x00001,
- LOG_TYPE_VENDING = 0x00002,
- LOG_TYPE_PICKDROP_PLAYER = 0x00004,
- LOG_TYPE_PICKDROP_MONSTER = 0x00008,
- LOG_TYPE_NPC = 0x00010,
- LOG_TYPE_SCRIPT = 0x00020,
- LOG_TYPE_STEAL = 0x00040,
- LOG_TYPE_CONSUME = 0x00080,
- LOG_TYPE_PRODUCE = 0x00100,
- LOG_TYPE_MVP = 0x00200,
- LOG_TYPE_COMMAND = 0x00400,
- LOG_TYPE_STORAGE = 0x00800,
- LOG_TYPE_GSTORAGE = 0x01000,
- LOG_TYPE_MAIL = 0x02000,
- LOG_TYPE_AUCTION = 0x04000,
- LOG_TYPE_BUYING_STORE = 0x08000,
- LOG_TYPE_OTHER = 0x10000,
- // combinations
- LOG_TYPE_LOOT = LOG_TYPE_PICKDROP_MONSTER|LOG_TYPE_CONSUME,
- // all
- LOG_TYPE_ALL = 0xFFFFF,
+typedef enum e_log_pick_type
+{
+ LOG_TYPE_NONE = 0,
+ LOG_TYPE_TRADE = 0x00001,
+ LOG_TYPE_VENDING = 0x00002,
+ LOG_TYPE_PICKDROP_PLAYER = 0x00004,
+ LOG_TYPE_PICKDROP_MONSTER = 0x00008,
+ LOG_TYPE_NPC = 0x00010,
+ LOG_TYPE_SCRIPT = 0x00020,
+ LOG_TYPE_STEAL = 0x00040,
+ LOG_TYPE_CONSUME = 0x00080,
+ LOG_TYPE_PRODUCE = 0x00100,
+ LOG_TYPE_MVP = 0x00200,
+ LOG_TYPE_COMMAND = 0x00400,
+ LOG_TYPE_STORAGE = 0x00800,
+ LOG_TYPE_GSTORAGE = 0x01000,
+ LOG_TYPE_MAIL = 0x02000,
+ LOG_TYPE_AUCTION = 0x04000,
+ LOG_TYPE_BUYING_STORE = 0x08000,
+ LOG_TYPE_OTHER = 0x10000,
+ // combinations
+ LOG_TYPE_LOOT = LOG_TYPE_PICKDROP_MONSTER|LOG_TYPE_CONSUME,
+ // all
+ LOG_TYPE_ALL = 0xFFFFF,
}
e_log_pick_type;
/// new logs
-void log_pick_pc(struct map_session_data *sd, e_log_pick_type type, int amount, struct item *itm);
-void log_pick_mob(struct mob_data *md, e_log_pick_type type, int amount, struct item *itm);
-void log_zeny(struct map_session_data *sd, e_log_pick_type type, struct map_session_data *src_sd, int amount);
+void log_pick_pc(struct map_session_data* sd, e_log_pick_type type, int amount, struct item* itm);
+void log_pick_mob(struct mob_data* md, e_log_pick_type type, int amount, struct item* itm);
+void log_zeny(struct map_session_data* sd, e_log_pick_type type, struct map_session_data* src_sd, int amount);
-void log_npc(struct map_session_data *sd, const char *message);
-void log_chat(e_log_chat_type type, int type_id, int src_charid, int src_accid, const char *map, int x, int y, const char *dst_charname, const char *message);
-void log_atcommand(struct map_session_data *sd, const char *message);
+void log_npc(struct map_session_data* sd, const char *message);
+void log_chat(e_log_chat_type type, int type_id, int src_charid, int src_accid, const char* map, int x, int y, const char* dst_charname, const char* message);
+void log_atcommand(struct map_session_data* sd, const char* message);
/// old, but useful logs
-void log_branch(struct map_session_data *sd);
-void log_mvpdrop(struct map_session_data *sd, int monster_id, int *log_mvp);
+void log_branch(struct map_session_data* sd);
+void log_mvpdrop(struct map_session_data* sd, int monster_id, int* log_mvp);
-int log_config_read(const char *cfgName);
+int log_config_read(const char* cfgName);
-extern struct Log_Config {
- e_log_pick_type enable_logs;
- int filter;
- bool sql_logs;
- bool log_chat_woe_disable;
- int rare_items_log,refine_items_log,price_items_log,amount_items_log; //for filter
- int branch, mvpdrop, zeny, commands, npc, chat;
- char log_branch[64], log_pick[64], log_zeny[64], log_mvpdrop[64], log_gm[64], log_npc[64], log_chat[64];
+extern struct Log_Config
+{
+ e_log_pick_type enable_logs;
+ int filter;
+ bool sql_logs;
+ bool log_chat_woe_disable;
+ int rare_items_log,refine_items_log,price_items_log,amount_items_log; //for filter
+ int branch, mvpdrop, zeny, commands, npc, chat;
+ char log_branch[64], log_pick[64], log_zeny[64], log_mvpdrop[64], log_gm[64], log_npc[64], log_chat[64];
}
log_config;
#ifdef BETA_THREAD_TEST
-struct {
- char **entry;
- int count;
-} logThreadData;
+ struct {
+ char** entry;
+ int count;
+ } logThreadData;
#endif
#endif /* _LOG_H_ */
diff --git a/src/map/mail.c b/src/map/mail.c
index ecd79f957..03b8227b5 100644
--- a/src/map/mail.c
+++ b/src/map/mail.c
@@ -16,164 +16,170 @@
void mail_clear(struct map_session_data *sd)
{
- sd->mail.nameid = 0;
- sd->mail.index = 0;
- sd->mail.amount = 0;
- sd->mail.zeny = 0;
+ sd->mail.nameid = 0;
+ sd->mail.index = 0;
+ sd->mail.amount = 0;
+ sd->mail.zeny = 0;
- return;
+ return;
}
int mail_removeitem(struct map_session_data *sd, short flag)
{
- nullpo_ret(sd);
-
- if (sd->mail.amount) {
- if (flag) // Item send
- pc_delitem(sd, sd->mail.index, sd->mail.amount, 1, 0, LOG_TYPE_MAIL);
- else
- clif_additem(sd, sd->mail.index, sd->mail.amount, 0);
- }
-
- sd->mail.nameid = 0;
- sd->mail.index = 0;
- sd->mail.amount = 0;
- return 1;
+ nullpo_ret(sd);
+
+ if( sd->mail.amount )
+ {
+ if (flag) // Item send
+ pc_delitem(sd, sd->mail.index, sd->mail.amount, 1, 0, LOG_TYPE_MAIL);
+ else
+ clif_additem(sd, sd->mail.index, sd->mail.amount, 0);
+ }
+
+ sd->mail.nameid = 0;
+ sd->mail.index = 0;
+ sd->mail.amount = 0;
+ return 1;
}
int mail_removezeny(struct map_session_data *sd, short flag)
{
- nullpo_ret(sd);
+ nullpo_ret(sd);
- if (flag && sd->mail.zeny > 0) {
- //Zeny send
- pc_payzeny(sd,sd->mail.zeny,LOG_TYPE_MAIL, NULL);
- }
- sd->mail.zeny = 0;
+ if (flag && sd->mail.zeny > 0)
+ { //Zeny send
+ pc_payzeny(sd,sd->mail.zeny,LOG_TYPE_MAIL, NULL);
+ }
+ sd->mail.zeny = 0;
- return 1;
+ return 1;
}
-unsigned char mail_setitem(struct map_session_data *sd, int idx, int amount)
-{
+unsigned char mail_setitem(struct map_session_data *sd, int idx, int amount) {
+
+ if( pc_istrading(sd) )
+ return 1;
+
+ if( idx == 0 ) { // Zeny Transfer
+ if( amount < 0 || !pc_can_give_items(sd) )
+ return 1;
+
+ if( amount > sd->status.zeny )
+ amount = sd->status.zeny;
+
+ sd->mail.zeny = amount;
+ // clif_updatestatus(sd, SP_ZENY);
+ return 0;
+ } else { // Item Transfer
+ idx -= 2;
+ mail_removeitem(sd, 0);
+
+ if( idx < 0 || idx >= MAX_INVENTORY )
+ return 1;
+ if( amount < 0 || amount > sd->status.inventory[idx].amount )
+ return 1;
+ if( !pc_can_give_items(sd) || sd->status.inventory[idx].expire_time ||
+ !itemdb_canmail(&sd->status.inventory[idx],pc_get_group_level(sd)) )
+ return 1;
+
+ sd->mail.index = idx;
+ sd->mail.nameid = sd->status.inventory[idx].nameid;
+ sd->mail.amount = amount;
- if (pc_istrading(sd))
- return 1;
-
- if (idx == 0) { // Zeny Transfer
- if (amount < 0 || !pc_can_give_items(sd))
- return 1;
-
- if (amount > sd->status.zeny)
- amount = sd->status.zeny;
-
- sd->mail.zeny = amount;
- // clif_updatestatus(sd, SP_ZENY);
- return 0;
- } else { // Item Transfer
- idx -= 2;
- mail_removeitem(sd, 0);
-
- if (idx < 0 || idx >= MAX_INVENTORY)
- return 1;
- if (amount < 0 || amount > sd->status.inventory[idx].amount)
- return 1;
- if (!pc_can_give_items(sd) || sd->status.inventory[idx].expire_time ||
- !itemdb_canmail(&sd->status.inventory[idx],pc_get_group_level(sd)))
- return 1;
-
- sd->mail.index = idx;
- sd->mail.nameid = sd->status.inventory[idx].nameid;
- sd->mail.amount = amount;
-
- return 0;
- }
+ return 0;
+ }
}
bool mail_setattachment(struct map_session_data *sd, struct mail_message *msg)
{
- int n;
+ int n;
- nullpo_retr(false,sd);
- nullpo_retr(false,msg);
+ nullpo_retr(false,sd);
+ nullpo_retr(false,msg);
- if (sd->mail.zeny < 0 || sd->mail.zeny > sd->status.zeny)
- return false;
+ if( sd->mail.zeny < 0 || sd->mail.zeny > sd->status.zeny )
+ return false;
- n = sd->mail.index;
- if (sd->mail.amount) {
- if (sd->status.inventory[n].nameid != sd->mail.nameid)
- return false;
+ n = sd->mail.index;
+ if( sd->mail.amount )
+ {
+ if( sd->status.inventory[n].nameid != sd->mail.nameid )
+ return false;
- if (sd->status.inventory[n].amount < sd->mail.amount)
- return false;
+ if( sd->status.inventory[n].amount < sd->mail.amount )
+ return false;
- if (sd->weight > sd->max_weight)
- return false;
+ if( sd->weight > sd->max_weight )
+ return false;
- memcpy(&msg->item, &sd->status.inventory[n], sizeof(struct item));
- msg->item.amount = sd->mail.amount;
- } else
- memset(&msg->item, 0x00, sizeof(struct item));
+ memcpy(&msg->item, &sd->status.inventory[n], sizeof(struct item));
+ msg->item.amount = sd->mail.amount;
+ }
+ else
+ memset(&msg->item, 0x00, sizeof(struct item));
- msg->zeny = sd->mail.zeny;
+ msg->zeny = sd->mail.zeny;
- // Removes the attachment from sender
- mail_removeitem(sd,1);
- mail_removezeny(sd,1);
+ // Removes the attachment from sender
+ mail_removeitem(sd,1);
+ mail_removezeny(sd,1);
- return true;
+ return true;
}
-void mail_getattachment(struct map_session_data *sd, int zeny, struct item *item)
+void mail_getattachment(struct map_session_data* sd, int zeny, struct item* item)
{
- if (item->nameid > 0 && item->amount > 0) {
- pc_additem(sd, item, item->amount, LOG_TYPE_MAIL);
- clif_Mail_getattachment(sd->fd, 0);
- }
-
- if (zeny > 0) {
- //Zeny receive
- pc_getzeny(sd, zeny,LOG_TYPE_MAIL, NULL);
- }
+ if( item->nameid > 0 && item->amount > 0 )
+ {
+ pc_additem(sd, item, item->amount, LOG_TYPE_MAIL);
+ clif_Mail_getattachment(sd->fd, 0);
+ }
+
+ if( zeny > 0 )
+ { //Zeny receive
+ pc_getzeny(sd, zeny,LOG_TYPE_MAIL, NULL);
+ }
}
int mail_openmail(struct map_session_data *sd)
{
- nullpo_ret(sd);
+ nullpo_ret(sd);
- if (sd->state.storage_flag || sd->state.vending || sd->state.buyingstore || sd->state.trading)
- return 0;
+ if( sd->state.storage_flag || sd->state.vending || sd->state.buyingstore || sd->state.trading )
+ return 0;
- clif_Mail_window(sd->fd, 0);
+ clif_Mail_window(sd->fd, 0);
- return 1;
+ return 1;
}
void mail_deliveryfail(struct map_session_data *sd, struct mail_message *msg)
{
- nullpo_retv(sd);
- nullpo_retv(msg);
+ nullpo_retv(sd);
+ nullpo_retv(msg);
- if (msg->item.amount > 0) {
- // Item receive (due to failure)
- pc_additem(sd, &msg->item, msg->item.amount, LOG_TYPE_MAIL);
- }
+ if( msg->item.amount > 0 )
+ {
+ // Item receive (due to failure)
+ pc_additem(sd, &msg->item, msg->item.amount, LOG_TYPE_MAIL);
+ }
- if (msg->zeny > 0) {
- pc_getzeny(sd,msg->zeny,LOG_TYPE_MAIL, NULL); //Zeny receive (due to failure)
- }
+ if( msg->zeny > 0 )
+ {
+ pc_getzeny(sd,msg->zeny,LOG_TYPE_MAIL, NULL); //Zeny receive (due to failure)
+ }
- clif_Mail_send(sd->fd, true);
+ clif_Mail_send(sd->fd, true);
}
// This function only check if the mail operations are valid
bool mail_invalid_operation(struct map_session_data *sd)
{
- if (!map[sd->bl.m].flag.town && !pc_can_use_command(sd, "mail", COMMAND_ATCOMMAND)) {
- ShowWarning("clif_parse_Mail: char '%s' trying to do invalid mail operations.\n", sd->status.name);
- return true;
- }
+ if( !map[sd->bl.m].flag.town && !pc_can_use_command(sd, "mail", COMMAND_ATCOMMAND) )
+ {
+ ShowWarning("clif_parse_Mail: char '%s' trying to do invalid mail operations.\n", sd->status.name);
+ return true;
+ }
- return false;
+ return false;
}
diff --git a/src/map/mail.h b/src/map/mail.h
index eb4e76c4d..cab582e55 100644
--- a/src/map/mail.h
+++ b/src/map/mail.h
@@ -11,7 +11,7 @@ int mail_removeitem(struct map_session_data *sd, short flag);
int mail_removezeny(struct map_session_data *sd, short flag);
unsigned char mail_setitem(struct map_session_data *sd, int idx, int amount);
bool mail_setattachment(struct map_session_data *sd, struct mail_message *msg);
-void mail_getattachment(struct map_session_data *sd, int zeny, struct item *item);
+void mail_getattachment(struct map_session_data* sd, int zeny, struct item* item);
int mail_openmail(struct map_session_data *sd);
void mail_deliveryfail(struct map_session_data *sd, struct mail_message *msg);
bool mail_invalid_operation(struct map_session_data *sd);
diff --git a/src/map/map.c b/src/map/map.c
index 69e343fb3..9238af9f9 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -61,7 +61,7 @@ char map_server_ip[32] = "127.0.0.1";
char map_server_id[32] = "ragnarok";
char map_server_pw[32] = "ragnarok";
char map_server_db[32] = "ragnarok";
-Sql *mmysql_handle;
+Sql* mmysql_handle;
int db_use_sqldbs = 0;
char item_db_db[32] = "item_db";
@@ -78,7 +78,7 @@ int log_db_port = 3306;
char log_db_id[32] = "ragnarok";
char log_db_pw[32] = "ragnarok";
char log_db_db[32] = "log";
-Sql *logmysql_handle;
+Sql* logmysql_handle;
// This param using for sending mainchat
// messages like whispers to this nick. [LuzZza]
@@ -94,14 +94,14 @@ char *MSG_CONF_NAME;
char *GRF_PATH_FILENAME;
// DBMap declaartion
-static DBMap *id_db=NULL; // int id -> struct block_list*
-static DBMap *pc_db=NULL; // int id -> struct map_session_data*
-static DBMap *mobid_db=NULL; // int id -> struct mob_data*
-static DBMap *bossid_db=NULL; // int id -> struct mob_data* (MVP db)
-static DBMap *map_db=NULL; // unsigned int mapindex -> struct map_data*
-static DBMap *nick_db=NULL; // int char_id -> struct charid2nick* (requested names of offline characters)
-static DBMap *charid_db=NULL; // int char_id -> struct map_session_data*
-static DBMap *regen_db=NULL; // int id -> struct block_list* (status_natural_heal processing)
+static DBMap* id_db=NULL; // int id -> struct block_list*
+static DBMap* pc_db=NULL; // int id -> struct map_session_data*
+static DBMap* mobid_db=NULL; // int id -> struct mob_data*
+static DBMap* bossid_db=NULL; // int id -> struct mob_data* (MVP db)
+static DBMap* map_db=NULL; // unsigned int mapindex -> struct map_data*
+static DBMap* nick_db=NULL; // int char_id -> struct charid2nick* (requested names of offline characters)
+static DBMap* charid_db=NULL; // int char_id -> struct map_session_data*
+static DBMap* regen_db=NULL; // int id -> struct block_list* (status_natural_heal processing)
static int map_users=0;
@@ -126,26 +126,26 @@ int agit2_flag = 0;
int night_flag = 0; // 0=day, 1=night [Yor]
struct charid_request {
- struct charid_request *next;
- int charid;// who want to be notified of the nick
+ struct charid_request* next;
+ int charid;// who want to be notified of the nick
};
struct charid2nick {
- char nick[NAME_LENGTH];
- struct charid_request *requests;// requests of notification on this nick
+ char nick[NAME_LENGTH];
+ struct charid_request* requests;// requests of notification on this nick
};
// This is the main header found at the very beginning of the map cache
struct map_cache_main_header {
- uint32 file_size;
- uint16 map_count;
+ uint32 file_size;
+ uint16 map_count;
};
// This is the header appended before every compressed map cells info in the map cache
struct map_cache_map_info {
- char name[MAP_NAME_LENGTH];
- int16 xs;
- int16 ys;
- int32 len;
+ char name[MAP_NAME_LENGTH];
+ int16 xs;
+ int16 ys;
+ int32 len;
};
char db_path[256] = "db";
@@ -158,19 +158,19 @@ char wisp_server_name[NAME_LENGTH] = "Server"; // can be modified in char-server
int console = 0;
int enable_spy = 0; //To enable/disable @spy commands, which consume too much cpu time when sending packets. [Skotlex]
-int enable_grf = 0; //To enable/disable reading maps from GRF files, bypassing mapcache [blackhole89]
+int enable_grf = 0; //To enable/disable reading maps from GRF files, bypassing mapcache [blackhole89]
/*==========================================
* server player count (of all mapservers)
*------------------------------------------*/
void map_setusers(int users)
{
- map_users = users;
+ map_users = users;
}
int map_getusers(void)
{
- return map_users;
+ return map_users;
}
/*==========================================
@@ -178,65 +178,67 @@ int map_getusers(void)
*------------------------------------------*/
int map_usercount(void)
{
- return pc_db->size(pc_db);
+ return pc_db->size(pc_db);
}
/*==========================================
* Attempt to free a map blocklist
*------------------------------------------*/
-int map_freeblock(struct block_list *bl)
+int map_freeblock (struct block_list *bl)
{
- nullpo_retr(block_free_lock, bl);
- if (block_free_lock == 0 || block_free_count >= block_free_max) {
- aFree(bl);
- bl = NULL;
- if (block_free_count >= block_free_max)
- ShowWarning("map_freeblock: too many free block! %d %d\n", block_free_count, block_free_lock);
- } else
- block_free[block_free_count++] = bl;
+ nullpo_retr(block_free_lock, bl);
+ if (block_free_lock == 0 || block_free_count >= block_free_max)
+ {
+ aFree(bl);
+ bl = NULL;
+ if (block_free_count >= block_free_max)
+ ShowWarning("map_freeblock: too many free block! %d %d\n", block_free_count, block_free_lock);
+ } else
+ block_free[block_free_count++] = bl;
- return block_free_lock;
+ return block_free_lock;
}
/*==========================================
* Lock blocklist, (prevent map_freeblock usage)
*------------------------------------------*/
-int map_freeblock_lock(void)
+int map_freeblock_lock (void)
{
- return ++block_free_lock;
+ return ++block_free_lock;
}
/*==========================================
* Remove the lock on map_bl
*------------------------------------------*/
-int map_freeblock_unlock(void)
+int map_freeblock_unlock (void)
{
- if ((--block_free_lock) == 0) {
- int i;
- for (i = 0; i < block_free_count; i++) {
- aFree(block_free[i]);
- block_free[i] = NULL;
- }
- block_free_count = 0;
- } else if (block_free_lock < 0) {
- ShowError("map_freeblock_unlock: lock count < 0 !\n");
- block_free_lock = 0;
- }
+ if ((--block_free_lock) == 0) {
+ int i;
+ for (i = 0; i < block_free_count; i++)
+ {
+ aFree(block_free[i]);
+ block_free[i] = NULL;
+ }
+ block_free_count = 0;
+ } else if (block_free_lock < 0) {
+ ShowError("map_freeblock_unlock: lock count < 0 !\n");
+ block_free_lock = 0;
+ }
- return block_free_lock;
+ return block_free_lock;
}
// Timer function to check if there some remaining lock and remove them if so.
// Called each 1s
int map_freeblock_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- if (block_free_lock > 0) {
- ShowError("map_freeblock_timer: block_free_lock(%d) is invalid.\n", block_free_lock);
- block_free_lock = 1;
- map_freeblock_unlock();
- }
+ if (block_free_lock > 0) {
+ ShowError("map_freeblock_timer: block_free_lock(%d) is invalid.\n", block_free_lock);
+ block_free_lock = 1;
+ map_freeblock_unlock();
+ }
- return 0;
+ return 0;
}
//
@@ -255,17 +257,17 @@ static struct block_list bl_head;
*------------------------------------------*/
static void map_addblcell(struct block_list *bl)
{
- if (bl->m<0 || bl->x<0 || bl->x>=map[bl->m].xs || bl->y<0 || bl->y>=map[bl->m].ys || !(bl->type&BL_CHAR))
- return;
- map[bl->m].cell[bl->x+bl->y*map[bl->m].xs].cell_bl++;
- return;
+ if( bl->m<0 || bl->x<0 || bl->x>=map[bl->m].xs || bl->y<0 || bl->y>=map[bl->m].ys || !(bl->type&BL_CHAR) )
+ return;
+ map[bl->m].cell[bl->x+bl->y*map[bl->m].xs].cell_bl++;
+ return;
}
static void map_delblcell(struct block_list *bl)
{
- if (bl->m <0 || bl->x<0 || bl->x>=map[bl->m].xs || bl->y<0 || bl->y>=map[bl->m].ys || !(bl->type&BL_CHAR))
- return;
- map[bl->m].cell[bl->x+bl->y*map[bl->m].xs].cell_bl--;
+ if( bl->m <0 || bl->x<0 || bl->x>=map[bl->m].xs || bl->y<0 || bl->y>=map[bl->m].ys || !(bl->type&BL_CHAR) )
+ return;
+ map[bl->m].cell[bl->x+bl->y*map[bl->m].xs].cell_bl--;
}
#endif
@@ -273,89 +275,91 @@ static void map_delblcell(struct block_list *bl)
* Adds a block to the map.
* Returns 0 on success, 1 on failure (illegal coordinates).
*------------------------------------------*/
-int map_addblock(struct block_list *bl)
-{
- int m, x, y, pos;
-
- nullpo_ret(bl);
-
- if (bl->prev != NULL) {
- ShowError("map_addblock: bl->prev != NULL\n");
- return 1;
- }
-
- m = bl->m;
- x = bl->x;
- y = bl->y;
- if (m < 0 || m >= map_num) {
- ShowError("map_addblock: invalid map id (%d), only %d are loaded.\n", m, map_num);
- return 1;
- }
- if (x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys) {
- ShowError("map_addblock: out-of-bounds coordinates (\"%s\",%d,%d), map is %dx%d\n", map[m].name, x, y, map[m].xs, map[m].ys);
- return 1;
- }
-
- pos = x/BLOCK_SIZE+(y/BLOCK_SIZE)*map[m].bxs;
-
- if (bl->type == BL_MOB) {
- bl->next = map[m].block_mob[pos];
- bl->prev = &bl_head;
- if (bl->next) bl->next->prev = bl;
- map[m].block_mob[pos] = bl;
- } else {
- bl->next = map[m].block[pos];
- bl->prev = &bl_head;
- if (bl->next) bl->next->prev = bl;
- map[m].block[pos] = bl;
- }
+int map_addblock(struct block_list* bl)
+{
+ int m, x, y, pos;
+
+ nullpo_ret(bl);
+
+ if (bl->prev != NULL) {
+ ShowError("map_addblock: bl->prev != NULL\n");
+ return 1;
+ }
+
+ m = bl->m;
+ x = bl->x;
+ y = bl->y;
+ if( m < 0 || m >= map_num )
+ {
+ ShowError("map_addblock: invalid map id (%d), only %d are loaded.\n", m, map_num);
+ return 1;
+ }
+ if( x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys )
+ {
+ ShowError("map_addblock: out-of-bounds coordinates (\"%s\",%d,%d), map is %dx%d\n", map[m].name, x, y, map[m].xs, map[m].ys);
+ return 1;
+ }
+
+ pos = x/BLOCK_SIZE+(y/BLOCK_SIZE)*map[m].bxs;
+
+ if (bl->type == BL_MOB) {
+ bl->next = map[m].block_mob[pos];
+ bl->prev = &bl_head;
+ if (bl->next) bl->next->prev = bl;
+ map[m].block_mob[pos] = bl;
+ } else {
+ bl->next = map[m].block[pos];
+ bl->prev = &bl_head;
+ if (bl->next) bl->next->prev = bl;
+ map[m].block[pos] = bl;
+ }
#ifdef CELL_NOSTACK
- map_addblcell(bl);
+ map_addblcell(bl);
#endif
- return 0;
+ return 0;
}
/*==========================================
* Removes a block from the map.
*------------------------------------------*/
-int map_delblock(struct block_list *bl)
+int map_delblock(struct block_list* bl)
{
- int pos;
- nullpo_ret(bl);
+ int pos;
+ nullpo_ret(bl);
// blocklist (2ways chainlist)
- if (bl->prev == NULL) {
- if (bl->next != NULL) {
- // can't delete block (already at the begining of the chain)
- ShowError("map_delblock error : bl->next!=NULL\n");
- }
- return 0;
- }
+ if (bl->prev == NULL) {
+ if (bl->next != NULL) {
+ // can't delete block (already at the begining of the chain)
+ ShowError("map_delblock error : bl->next!=NULL\n");
+ }
+ return 0;
+ }
#ifdef CELL_NOSTACK
- map_delblcell(bl);
+ map_delblcell(bl);
#endif
- pos = bl->x/BLOCK_SIZE+(bl->y/BLOCK_SIZE)*map[bl->m].bxs;
+ pos = bl->x/BLOCK_SIZE+(bl->y/BLOCK_SIZE)*map[bl->m].bxs;
- if (bl->next)
- bl->next->prev = bl->prev;
- if (bl->prev == &bl_head) {
- //Since the head of the list, update the block_list map of []
- if (bl->type == BL_MOB) {
- map[bl->m].block_mob[pos] = bl->next;
- } else {
- map[bl->m].block[pos] = bl->next;
- }
- } else {
- bl->prev->next = bl->next;
- }
- bl->next = NULL;
- bl->prev = NULL;
+ if (bl->next)
+ bl->next->prev = bl->prev;
+ if (bl->prev == &bl_head) {
+ //Since the head of the list, update the block_list map of []
+ if (bl->type == BL_MOB) {
+ map[bl->m].block_mob[pos] = bl->next;
+ } else {
+ map[bl->m].block[pos] = bl->next;
+ }
+ } else {
+ bl->prev->next = bl->next;
+ }
+ bl->next = NULL;
+ bl->prev = NULL;
- return 0;
+ return 0;
}
/*==========================================
@@ -365,105 +369,107 @@ int map_delblock(struct block_list *bl)
*------------------------------------------*/
int map_moveblock(struct block_list *bl, int x1, int y1, unsigned int tick)
{
- int x0 = bl->x, y0 = bl->y;
- struct status_change *sc = NULL;
- int moveblock = (x0/BLOCK_SIZE != x1/BLOCK_SIZE || y0/BLOCK_SIZE != y1/BLOCK_SIZE);
-
- if (!bl->prev) {
- //Block not in map, just update coordinates, but do naught else.
- bl->x = x1;
- bl->y = y1;
- return 0;
- }
-
- //TODO: Perhaps some outs of bounds checking should be placed here?
- if (bl->type&BL_CHAR) {
- sc = status_get_sc(bl);
-
- skill_unit_move(bl,tick,2);
- status_change_end(bl, SC_CLOSECONFINE, INVALID_TIMER);
- status_change_end(bl, SC_CLOSECONFINE2, INVALID_TIMER);
- // status_change_end(bl, SC_BLADESTOP, INVALID_TIMER); //Won't stop when you are knocked away, go figure...
- status_change_end(bl, SC_TATAMIGAESHI, INVALID_TIMER);
- status_change_end(bl, SC_MAGICROD, INVALID_TIMER);
- if (sc->data[SC_PROPERTYWALK] &&
- sc->data[SC_PROPERTYWALK]->val3 >= skill_get_maxcount(sc->data[SC_PROPERTYWALK]->val1,sc->data[SC_PROPERTYWALK]->val2))
- status_change_end(bl,SC_PROPERTYWALK,INVALID_TIMER);
- } else if (bl->type == BL_NPC)
- npc_unsetcells((TBL_NPC *)bl);
-
- if (moveblock) map_delblock(bl);
+ int x0 = bl->x, y0 = bl->y;
+ struct status_change *sc = NULL;
+ int moveblock = ( x0/BLOCK_SIZE != x1/BLOCK_SIZE || y0/BLOCK_SIZE != y1/BLOCK_SIZE);
+
+ if (!bl->prev) {
+ //Block not in map, just update coordinates, but do naught else.
+ bl->x = x1;
+ bl->y = y1;
+ return 0;
+ }
+
+ //TODO: Perhaps some outs of bounds checking should be placed here?
+ if (bl->type&BL_CHAR) {
+ sc = status_get_sc(bl);
+
+ skill_unit_move(bl,tick,2);
+ status_change_end(bl, SC_CLOSECONFINE, INVALID_TIMER);
+ status_change_end(bl, SC_CLOSECONFINE2, INVALID_TIMER);
+// status_change_end(bl, SC_BLADESTOP, INVALID_TIMER); //Won't stop when you are knocked away, go figure...
+ status_change_end(bl, SC_TATAMIGAESHI, INVALID_TIMER);
+ status_change_end(bl, SC_MAGICROD, INVALID_TIMER);
+ if (sc->data[SC_PROPERTYWALK] &&
+ sc->data[SC_PROPERTYWALK]->val3 >= skill_get_maxcount(sc->data[SC_PROPERTYWALK]->val1,sc->data[SC_PROPERTYWALK]->val2) )
+ status_change_end(bl,SC_PROPERTYWALK,INVALID_TIMER);
+ } else
+ if (bl->type == BL_NPC)
+ npc_unsetcells((TBL_NPC*)bl);
+
+ if (moveblock) map_delblock(bl);
#ifdef CELL_NOSTACK
- else map_delblcell(bl);
+ else map_delblcell(bl);
#endif
- bl->x = x1;
- bl->y = y1;
- if (moveblock) map_addblock(bl);
+ bl->x = x1;
+ bl->y = y1;
+ if (moveblock) map_addblock(bl);
#ifdef CELL_NOSTACK
- else map_addblcell(bl);
+ else map_addblcell(bl);
#endif
- if (bl->type&BL_CHAR) {
-
- skill_unit_move(bl,tick,3);
-
- if (bl->type == BL_PC && ((TBL_PC *)bl)->shadowform_id) {//Shadow Form Target Moving
- struct block_list *d_bl;
- if ((d_bl = map_id2bl(((TBL_PC *)bl)->shadowform_id)) == NULL || bl->m != d_bl->m || !check_distance_bl(bl,d_bl,10)) {
- if (d_bl)
- status_change_end(d_bl,SC__SHADOWFORM,INVALID_TIMER);
- ((TBL_PC *)bl)->shadowform_id = 0;
- }
- }
-
- if (sc && sc->count) {
- if (sc->data[SC_DANCING])
- skill_unit_move_unit_group(skill_id2group(sc->data[SC_DANCING]->val2), bl->m, x1-x0, y1-y0);
- else {
- if (sc->data[SC_CLOAKING])
- skill_check_cloaking(bl, sc->data[SC_CLOAKING]);
- if (sc->data[SC_WARM])
- skill_unit_move_unit_group(skill_id2group(sc->data[SC_WARM]->val4), bl->m, x1-x0, y1-y0);
- if (sc->data[SC_BANDING])
- skill_unit_move_unit_group(skill_id2group(sc->data[SC_BANDING]->val4), bl->m, x1-x0, y1-y0);
-
- if (sc->data[SC_NEUTRALBARRIER_MASTER])
- skill_unit_move_unit_group(skill_id2group(sc->data[SC_NEUTRALBARRIER_MASTER]->val2), bl->m, x1-x0, y1-y0);
- else if (sc->data[SC_STEALTHFIELD_MASTER])
- skill_unit_move_unit_group(skill_id2group(sc->data[SC_STEALTHFIELD_MASTER]->val2), bl->m, x1-x0, y1-y0);
-
- if (sc->data[SC__SHADOWFORM]) { //Shadow Form Caster Moving
- struct block_list *d_bl;
- if ((d_bl = map_id2bl(sc->data[SC__SHADOWFORM]->val2)) == NULL || bl->m != d_bl->m || !check_distance_bl(bl,d_bl,10))
- status_change_end(bl,SC__SHADOWFORM,INVALID_TIMER);
- }
-
- if (sc->data[SC_PROPERTYWALK]
- && sc->data[SC_PROPERTYWALK]->val3 < skill_get_maxcount(sc->data[SC_PROPERTYWALK]->val1,sc->data[SC_PROPERTYWALK]->val2)
- && map_find_skill_unit_oncell(bl,bl->x,bl->y,SO_ELECTRICWALK,NULL,0) == NULL
- && map_find_skill_unit_oncell(bl,bl->x,bl->y,SO_FIREWALK,NULL,0) == NULL
- && skill_unitsetting(bl,sc->data[SC_PROPERTYWALK]->val1,sc->data[SC_PROPERTYWALK]->val2,x0, y0,0)) {
- sc->data[SC_PROPERTYWALK]->val3++;
- }
-
-
- }
- /* Guild Aura Moving */
- if (bl->type == BL_PC && ((TBL_PC *)bl)->state.gmaster_flag) {
- if (sc->data[SC_LEADERSHIP])
- skill_unit_move_unit_group(skill_id2group(sc->data[SC_LEADERSHIP]->val4), bl->m, x1-x0, y1-y0);
- if (sc->data[SC_GLORYWOUNDS])
- skill_unit_move_unit_group(skill_id2group(sc->data[SC_GLORYWOUNDS]->val4), bl->m, x1-x0, y1-y0);
- if (sc->data[SC_SOULCOLD])
- skill_unit_move_unit_group(skill_id2group(sc->data[SC_SOULCOLD]->val4), bl->m, x1-x0, y1-y0);
- if (sc->data[SC_HAWKEYES])
- skill_unit_move_unit_group(skill_id2group(sc->data[SC_HAWKEYES]->val4), bl->m, x1-x0, y1-y0);
- }
- }
- } else if (bl->type == BL_NPC)
- npc_setcells((TBL_NPC *)bl);
-
- return 0;
+ if (bl->type&BL_CHAR) {
+
+ skill_unit_move(bl,tick,3);
+
+ if( bl->type == BL_PC && ((TBL_PC*)bl)->shadowform_id ) {//Shadow Form Target Moving
+ struct block_list *d_bl;
+ if( (d_bl = map_id2bl(((TBL_PC*)bl)->shadowform_id)) == NULL || bl->m != d_bl->m || !check_distance_bl(bl,d_bl,10) ) {
+ if( d_bl )
+ status_change_end(d_bl,SC__SHADOWFORM,INVALID_TIMER);
+ ((TBL_PC*)bl)->shadowform_id = 0;
+ }
+ }
+
+ if (sc && sc->count) {
+ if (sc->data[SC_DANCING])
+ skill_unit_move_unit_group(skill_id2group(sc->data[SC_DANCING]->val2), bl->m, x1-x0, y1-y0);
+ else {
+ if (sc->data[SC_CLOAKING])
+ skill_check_cloaking(bl, sc->data[SC_CLOAKING]);
+ if (sc->data[SC_WARM])
+ skill_unit_move_unit_group(skill_id2group(sc->data[SC_WARM]->val4), bl->m, x1-x0, y1-y0);
+ if (sc->data[SC_BANDING])
+ skill_unit_move_unit_group(skill_id2group(sc->data[SC_BANDING]->val4), bl->m, x1-x0, y1-y0);
+
+ if (sc->data[SC_NEUTRALBARRIER_MASTER])
+ skill_unit_move_unit_group(skill_id2group(sc->data[SC_NEUTRALBARRIER_MASTER]->val2), bl->m, x1-x0, y1-y0);
+ else if (sc->data[SC_STEALTHFIELD_MASTER])
+ skill_unit_move_unit_group(skill_id2group(sc->data[SC_STEALTHFIELD_MASTER]->val2), bl->m, x1-x0, y1-y0);
+
+ if( sc->data[SC__SHADOWFORM] ) {//Shadow Form Caster Moving
+ struct block_list *d_bl;
+ if( (d_bl = map_id2bl(sc->data[SC__SHADOWFORM]->val2)) == NULL || bl->m != d_bl->m || !check_distance_bl(bl,d_bl,10) )
+ status_change_end(bl,SC__SHADOWFORM,INVALID_TIMER);
+ }
+
+ if (sc->data[SC_PROPERTYWALK]
+ && sc->data[SC_PROPERTYWALK]->val3 < skill_get_maxcount(sc->data[SC_PROPERTYWALK]->val1,sc->data[SC_PROPERTYWALK]->val2)
+ && map_find_skill_unit_oncell(bl,bl->x,bl->y,SO_ELECTRICWALK,NULL,0) == NULL
+ && map_find_skill_unit_oncell(bl,bl->x,bl->y,SO_FIREWALK,NULL,0) == NULL
+ && skill_unitsetting(bl,sc->data[SC_PROPERTYWALK]->val1,sc->data[SC_PROPERTYWALK]->val2,x0, y0,0)) {
+ sc->data[SC_PROPERTYWALK]->val3++;
+ }
+
+
+ }
+ /* Guild Aura Moving */
+ if( bl->type == BL_PC && ((TBL_PC*)bl)->state.gmaster_flag ) {
+ if (sc->data[SC_LEADERSHIP])
+ skill_unit_move_unit_group(skill_id2group(sc->data[SC_LEADERSHIP]->val4), bl->m, x1-x0, y1-y0);
+ if (sc->data[SC_GLORYWOUNDS])
+ skill_unit_move_unit_group(skill_id2group(sc->data[SC_GLORYWOUNDS]->val4), bl->m, x1-x0, y1-y0);
+ if (sc->data[SC_SOULCOLD])
+ skill_unit_move_unit_group(skill_id2group(sc->data[SC_SOULCOLD]->val4), bl->m, x1-x0, y1-y0);
+ if (sc->data[SC_HAWKEYES])
+ skill_unit_move_unit_group(skill_id2group(sc->data[SC_HAWKEYES]->val4), bl->m, x1-x0, y1-y0);
+ }
+ }
+ } else
+ if (bl->type == BL_NPC)
+ npc_setcells((TBL_NPC*)bl);
+
+ return 0;
}
/*==========================================
@@ -471,189 +477,190 @@ int map_moveblock(struct block_list *bl, int x1, int y1, unsigned int tick)
*------------------------------------------*/
int map_count_oncell(int m, int x, int y, int type)
{
- int bx,by;
- struct block_list *bl;
- int count = 0;
+ int bx,by;
+ struct block_list *bl;
+ int count = 0;
- if (x < 0 || y < 0 || (x >= map[m].xs) || (y >= map[m].ys))
- return 0;
+ if (x < 0 || y < 0 || (x >= map[m].xs) || (y >= map[m].ys))
+ return 0;
- bx = x/BLOCK_SIZE;
- by = y/BLOCK_SIZE;
+ bx = x/BLOCK_SIZE;
+ by = y/BLOCK_SIZE;
- if (type&~BL_MOB)
- for (bl = map[m].block[bx+by*map[m].bxs] ; bl != NULL ; bl = bl->next)
- if (bl->x == x && bl->y == y && bl->type&type)
- count++;
+ if (type&~BL_MOB)
+ for( bl = map[m].block[bx+by*map[m].bxs] ; bl != NULL ; bl = bl->next )
+ if(bl->x == x && bl->y == y && bl->type&type)
+ count++;
- if (type&BL_MOB)
- for (bl = map[m].block_mob[bx+by*map[m].bxs] ; bl != NULL ; bl = bl->next)
- if (bl->x == x && bl->y == y)
- count++;
+ if (type&BL_MOB)
+ for( bl = map[m].block_mob[bx+by*map[m].bxs] ; bl != NULL ; bl = bl->next )
+ if(bl->x == x && bl->y == y)
+ count++;
- return count;
+ return count;
}
/*
* Looks for a skill unit on a given cell
* flag&1: runs battle_check_target check based on unit->group->target_flag
*/
-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 flag) {
- int m,bx,by;
- struct block_list *bl;
- struct skill_unit *unit;
- m = target->m;
+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 flag) {
+ int m,bx,by;
+ struct block_list *bl;
+ struct skill_unit *unit;
+ m = target->m;
- if (x < 0 || y < 0 || (x >= map[m].xs) || (y >= map[m].ys))
- return NULL;
+ if (x < 0 || y < 0 || (x >= map[m].xs) || (y >= map[m].ys))
+ return NULL;
- bx = x/BLOCK_SIZE;
- by = y/BLOCK_SIZE;
+ bx = x/BLOCK_SIZE;
+ by = y/BLOCK_SIZE;
- for (bl = map[m].block[bx+by *map[m].bxs] ; bl != NULL ; bl = bl->next) {
- if (bl->x != x || bl->y != y || bl->type != BL_SKILL)
- continue;
+ for( bl = map[m].block[bx+by*map[m].bxs] ; bl != NULL ; 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 (!(flag&1) || battle_check_target(&unit->bl,target,unit->group->target_flag) > 0)
- return unit;
- }
- return NULL;
+ unit = (struct skill_unit *) bl;
+ if( unit == out_unit || !unit->alive || !unit->group || unit->group->skill_id != skill_id )
+ continue;
+ if( !(flag&1) || battle_check_target(&unit->bl,target,unit->group->target_flag) > 0 )
+ return unit;
+ }
+ return NULL;
}
/*==========================================
* Adapted from foreachinarea for an easier invocation. [Skotlex]
*------------------------------------------*/
-int map_foreachinrange(int (*func)(struct block_list *,va_list), struct block_list *center, int range, int type, ...)
-{
- int bx, by, m;
- int returnCount = 0; //total sum of returned values of func() [Skotlex]
- struct block_list *bl;
- int blockcount = bl_list_count, i;
- int x0, x1, y0, y1;
- va_list ap;
-
- m = center->m;
- x0 = max(center->x - range, 0);
- y0 = max(center->y - range, 0);
- x1 = min(center->x + range, map[ m ].xs - 1);
- y1 = min(center->y + range, map[ m ].ys - 1);
-
- if (type&~BL_MOB)
- for (by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++) {
- for (bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++) {
- for (bl = map[m].block[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next) {
- if (bl->type&type
- && bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1
+int map_foreachinrange(int (*func)(struct block_list*,va_list), struct block_list* center, int range, int type, ...)
+{
+ int bx, by, m;
+ int returnCount = 0; //total sum of returned values of func() [Skotlex]
+ struct block_list *bl;
+ int blockcount = bl_list_count, i;
+ int x0, x1, y0, y1;
+ va_list ap;
+
+ m = center->m;
+ x0 = max(center->x - range, 0);
+ y0 = max(center->y - range, 0);
+ x1 = min(center->x + range, map[ m ].xs - 1);
+ y1 = min(center->y + range, map[ m ].ys - 1);
+
+ if ( type&~BL_MOB )
+ for ( by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++ ) {
+ for( bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++ ) {
+ for( bl = map[m].block[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next ) {
+ if( bl->type&type
+ && bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1
#ifdef CIRCULAR_AREA
- && check_distance_bl(center, bl, range)
+ && check_distance_bl(center, bl, range)
#endif
- && bl_list_count < BL_LIST_MAX)
- bl_list[ bl_list_count++ ] = bl;
- }
- }
- }
-
- if (type&BL_MOB)
- for (by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++) {
- for (bx=x0/BLOCK_SIZE; bx<=x1/BLOCK_SIZE; bx++) {
- for (bl = map[ m ].block_mob[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next) {
- if (bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1
+ && bl_list_count < BL_LIST_MAX )
+ bl_list[ bl_list_count++ ] = bl;
+ }
+ }
+ }
+
+ if( type&BL_MOB )
+ for( by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++ ) {
+ for(bx=x0/BLOCK_SIZE;bx<=x1/BLOCK_SIZE;bx++) {
+ for( bl = map[ m ].block_mob[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next ) {
+ if( bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1
#ifdef CIRCULAR_AREA
- && check_distance_bl(center, bl, range)
+ && check_distance_bl(center, bl, range)
#endif
- && bl_list_count < BL_LIST_MAX)
- bl_list[ bl_list_count++ ] = bl;
- }
- }
- }
+ && bl_list_count < BL_LIST_MAX )
+ bl_list[ bl_list_count++ ] = bl;
+ }
+ }
+ }
- if (bl_list_count >= BL_LIST_MAX)
- ShowWarning("map_foreachinrange: block count too many!\n");
+ if( bl_list_count >= BL_LIST_MAX )
+ ShowWarning("map_foreachinrange: block count too many!\n");
- map_freeblock_lock();
+ map_freeblock_lock();
- for (i = blockcount; i < bl_list_count; i++)
- if (bl_list[ i ]->prev) { //func() may delete this bl_list[] slot, checking for prev ensures it wasnt queued for deletion.
- va_start(ap, type);
- returnCount += func(bl_list[ i ], ap);
- va_end(ap);
- }
+ for( i = blockcount; i < bl_list_count; i++ )
+ if( bl_list[ i ]->prev ) { //func() may delete this bl_list[] slot, checking for prev ensures it wasnt queued for deletion.
+ va_start(ap, type);
+ returnCount += func(bl_list[ i ], ap);
+ va_end(ap);
+ }
- map_freeblock_unlock();
+ map_freeblock_unlock();
- bl_list_count = blockcount;
- return returnCount; //[Skotlex]
+ bl_list_count = blockcount;
+ return returnCount; //[Skotlex]
}
/*==========================================
* Same as foreachinrange, but there must be a shoot-able range between center and target to be counted in. [Skotlex]
*------------------------------------------*/
-int map_foreachinshootrange(int (*func)(struct block_list *,va_list),struct block_list *center, int range, int type,...)
-{
- int bx, by, m;
- int returnCount = 0; //total sum of returned values of func() [Skotlex]
- struct block_list *bl;
- int blockcount = bl_list_count, i;
- int x0, x1, y0, y1;
- va_list ap;
-
- m = center->m;
- if (m < 0)
- return 0;
-
- x0 = max(center->x-range, 0);
- y0 = max(center->y-range, 0);
- x1 = min(center->x+range, map[m].xs-1);
- y1 = min(center->y+range, map[m].ys-1);
-
- if (type&~BL_MOB)
- for (by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++) {
- for (bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++) {
- for (bl = map[ m ].block[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next) {
- if (bl->type&type
- && bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1
+int map_foreachinshootrange(int (*func)(struct block_list*,va_list),struct block_list* center, int range, int type,...)
+{
+ int bx, by, m;
+ int returnCount = 0; //total sum of returned values of func() [Skotlex]
+ struct block_list *bl;
+ int blockcount = bl_list_count, i;
+ int x0, x1, y0, y1;
+ va_list ap;
+
+ m = center->m;
+ if ( m < 0 )
+ return 0;
+
+ x0 = max(center->x-range, 0);
+ y0 = max(center->y-range, 0);
+ x1 = min(center->x+range, map[m].xs-1);
+ y1 = min(center->y+range, map[m].ys-1);
+
+ if ( type&~BL_MOB )
+ for( by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++ ) {
+ for( bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++ ) {
+ for( bl = map[ m ].block[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next ) {
+ if( bl->type&type
+ && bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1
#ifdef CIRCULAR_AREA
- && check_distance_bl(center, bl, range)
+ && check_distance_bl(center, bl, range)
#endif
- && path_search_long(NULL, center->m, center->x, center->y, bl->x, bl->y, CELL_CHKWALL)
- && bl_list_count < BL_LIST_MAX)
- bl_list[ bl_list_count++ ] = bl;
- }
- }
- }
- if (type&BL_MOB)
- for (by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++) {
- for (bx=x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++) {
- for (bl = map[ m ].block_mob[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next) {
- if (bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1
+ && path_search_long(NULL, center->m, center->x, center->y, bl->x, bl->y, CELL_CHKWALL)
+ && bl_list_count < BL_LIST_MAX )
+ bl_list[ bl_list_count++ ] = bl;
+ }
+ }
+ }
+ if( type&BL_MOB )
+ for( by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++ ) {
+ for( bx=x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++ ) {
+ for( bl = map[ m ].block_mob[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next ) {
+ if( bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1
#ifdef CIRCULAR_AREA
- && check_distance_bl(center, bl, range)
+ && check_distance_bl(center, bl, range)
#endif
- && path_search_long(NULL, center->m, center->x, center->y, bl->x, bl->y, CELL_CHKWALL)
- && bl_list_count < BL_LIST_MAX)
- bl_list[ bl_list_count++ ] = bl;
- }
- }
- }
+ && path_search_long(NULL, center->m, center->x, center->y, bl->x, bl->y, CELL_CHKWALL)
+ && bl_list_count < BL_LIST_MAX )
+ bl_list[ bl_list_count++ ] = bl;
+ }
+ }
+ }
- if (bl_list_count >= BL_LIST_MAX)
- ShowWarning("map_foreachinrange: block count too many!\n");
+ if( bl_list_count >= BL_LIST_MAX )
+ ShowWarning("map_foreachinrange: block count too many!\n");
- map_freeblock_lock();
+ map_freeblock_lock();
- for (i = blockcount; i < bl_list_count; i++)
- if (bl_list[ i ]->prev) { //func() may delete this bl_list[] slot, checking for prev ensures it wasnt queued for deletion.
- va_start(ap, type);
- returnCount += func(bl_list[ i ], ap);
- va_end(ap);
- }
+ for( i = blockcount; i < bl_list_count; i++ )
+ if( bl_list[ i ]->prev ) { //func() may delete this bl_list[] slot, checking for prev ensures it wasnt queued for deletion.
+ va_start(ap, type);
+ returnCount += func(bl_list[ i ], ap);
+ va_end(ap);
+ }
- map_freeblock_unlock();
+ map_freeblock_unlock();
- bl_list_count = blockcount;
- return returnCount; //[Skotlex]
+ bl_list_count = blockcount;
+ return returnCount; //[Skotlex]
}
/*==========================================
@@ -661,175 +668,175 @@ int map_foreachinshootrange(int (*func)(struct block_list *,va_list),struct bloc
* Apply *func with ... arguments for the range.
* @type = BL_PC/BL_MOB etc..
*------------------------------------------*/
-int map_foreachinarea(int (*func)(struct block_list *,va_list), int m, int x0, int y0, int x1, int y1, int type, ...)
-{
- int bx, by;
- int returnCount = 0; //total sum of returned values of func() [Skotlex]
- struct block_list *bl;
- int blockcount = bl_list_count, i;
- va_list ap;
-
- if (m < 0)
- return 0;
-
- if (x1 < x0)
- swap(x0, x1);
- if (y1 < y0)
- swap(y0, y1);
-
- x0 = max(x0, 0);
- y0 = max(y0, 0);
- x1 = min(x1, map[ m ].xs - 1);
- y1 = min(y1, map[ m ].ys - 1);
- if (type&~BL_MOB)
- for (by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++)
- for (bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++)
- for (bl = map[ m ].block[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next)
- if (bl->type&type && bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1 && bl_list_count < BL_LIST_MAX)
- bl_list[ bl_list_count++ ] = bl;
-
- if (type&BL_MOB)
- for (by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++)
- for (bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++)
- for (bl = map[ m ].block_mob[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next)
- if (bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1 && bl_list_count < BL_LIST_MAX)
- bl_list[ bl_list_count++ ] = bl;
-
- if (bl_list_count >= BL_LIST_MAX)
- ShowWarning("map_foreachinarea: block count too many!\n");
-
- map_freeblock_lock();
-
- for (i = blockcount; i < bl_list_count; i++)
- if (bl_list[ i ]->prev) { //func() may delete this bl_list[] slot, checking for prev ensures it wasnt queued for deletion.
- va_start(ap, type);
- returnCount += func(bl_list[ i ], ap);
- va_end(ap);
- }
-
- map_freeblock_unlock();
-
- bl_list_count = blockcount;
- return returnCount; //[Skotlex]
+int map_foreachinarea(int (*func)(struct block_list*,va_list), int m, int x0, int y0, int x1, int y1, int type, ...)
+{
+ int bx, by;
+ int returnCount = 0; //total sum of returned values of func() [Skotlex]
+ struct block_list *bl;
+ int blockcount = bl_list_count, i;
+ va_list ap;
+
+ if ( m < 0 )
+ return 0;
+
+ if ( x1 < x0 )
+ swap(x0, x1);
+ if ( y1 < y0 )
+ swap(y0, y1);
+
+ x0 = max(x0, 0);
+ y0 = max(y0, 0);
+ x1 = min(x1, map[ m ].xs - 1);
+ y1 = min(y1, map[ m ].ys - 1);
+ if ( type&~BL_MOB )
+ for( by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++ )
+ for( bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++ )
+ for( bl = map[ m ].block[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next )
+ if( bl->type&type && bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1 && bl_list_count < BL_LIST_MAX )
+ bl_list[ bl_list_count++ ] = bl;
+
+ if( type&BL_MOB )
+ for( by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++ )
+ for( bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++ )
+ for( bl = map[ m ].block_mob[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next )
+ if( bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1 && bl_list_count < BL_LIST_MAX )
+ bl_list[ bl_list_count++ ] = bl;
+
+ if( bl_list_count >= BL_LIST_MAX )
+ ShowWarning("map_foreachinarea: block count too many!\n");
+
+ map_freeblock_lock();
+
+ for( i = blockcount; i < bl_list_count; i++ )
+ if( bl_list[ i ]->prev ) { //func() may delete this bl_list[] slot, checking for prev ensures it wasnt queued for deletion.
+ va_start(ap, type);
+ returnCount += func(bl_list[ i ], ap);
+ va_end(ap);
+ }
+
+ map_freeblock_unlock();
+
+ bl_list_count = blockcount;
+ return returnCount; //[Skotlex]
}
/*==========================================
* Adapted from forcountinarea for an easier invocation. [pakpil]
*------------------------------------------*/
-int map_forcountinrange(int (*func)(struct block_list *,va_list), struct block_list *center, int range, int count, int type, ...)
-{
- int bx, by, m;
- int returnCount = 0; //total sum of returned values of func() [Skotlex]
- struct block_list *bl;
- int blockcount = bl_list_count, i;
- int x0, x1, y0, y1;
- va_list ap;
-
- m = center->m;
- x0 = max(center->x - range, 0);
- y0 = max(center->y - range, 0);
- x1 = min(center->x + range, map[ m ].xs - 1);
- y1 = min(center->y + range, map[ m ].ys - 1);
-
- if (type&~BL_MOB)
- for (by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++) {
- for (bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++) {
- for (bl = map[ m ].block[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next) {
- if (bl->type&type
- && bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1
+int map_forcountinrange(int (*func)(struct block_list*,va_list), struct block_list* center, int range, int count, int type, ...)
+{
+ int bx, by, m;
+ int returnCount = 0; //total sum of returned values of func() [Skotlex]
+ struct block_list *bl;
+ int blockcount = bl_list_count, i;
+ int x0, x1, y0, y1;
+ va_list ap;
+
+ m = center->m;
+ x0 = max(center->x - range, 0);
+ y0 = max(center->y - range, 0);
+ x1 = min(center->x + range, map[ m ].xs - 1);
+ y1 = min(center->y + range, map[ m ].ys - 1);
+
+ if ( type&~BL_MOB )
+ for ( by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++ ) {
+ for( bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++ ) {
+ for( bl = map[ m ].block[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next ) {
+ if( bl->type&type
+ && bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1
#ifdef CIRCULAR_AREA
- && check_distance_bl(center, bl, range)
+ && check_distance_bl(center, bl, range)
#endif
- && bl_list_count < BL_LIST_MAX)
- bl_list[ bl_list_count++ ] = bl;
- }
- }
- }
- if (type&BL_MOB)
- for (by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++) {
- for (bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++) {
- for (bl = map[ m ].block_mob[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next) {
- if (bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1
+ && bl_list_count < BL_LIST_MAX )
+ bl_list[ bl_list_count++ ] = bl;
+ }
+ }
+ }
+ if( type&BL_MOB )
+ for( by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++ ) {
+ for( bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++ ){
+ for( bl = map[ m ].block_mob[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next ) {
+ if( bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1
#ifdef CIRCULAR_AREA
- && check_distance_bl(center, bl, range)
+ && check_distance_bl(center, bl, range)
#endif
- && bl_list_count < BL_LIST_MAX)
- bl_list[ bl_list_count++ ] = bl;
- }
- }
- }
-
- if (bl_list_count >= BL_LIST_MAX)
- ShowWarning("map_forcountinrange: block count too many!\n");
-
- map_freeblock_lock();
-
- for (i = blockcount; i < bl_list_count; i++)
- if (bl_list[ i ]->prev) { //func() may delete this bl_list[] slot, checking for prev ensures it wasnt queued for deletion.
- va_start(ap, type);
- returnCount += func(bl_list[ i ], ap);
- va_end(ap);
- if (count && returnCount >= count)
- break;
- }
-
- map_freeblock_unlock();
-
- bl_list_count = blockcount;
- return returnCount; //[Skotlex]
-}
-int map_forcountinarea(int (*func)(struct block_list *,va_list), int m, int x0, int y0, int x1, int y1, int count, int type, ...)
-{
- int bx, by;
- int returnCount = 0; //total sum of returned values of func() [Skotlex]
- struct block_list *bl;
- int blockcount = bl_list_count, i;
- va_list ap;
-
- if (m < 0)
- return 0;
-
- if (x1 < x0)
- swap(x0, x1);
- if (y1 < y0)
- swap(y0, y1);
-
- x0 = max(x0, 0);
- y0 = max(y0, 0);
- x1 = min(x1, map[ m ].xs - 1);
- y1 = min(y1, map[ m ].ys - 1);
-
- if (type&~BL_MOB)
- for (by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++)
- for (bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++)
- for (bl = map[ m ].block[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next)
- if (bl->type&type && bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1 && bl_list_count < BL_LIST_MAX)
- bl_list[ bl_list_count++ ] = bl;
-
- if (type&BL_MOB)
- for (by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++)
- for (bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++)
- for (bl = map[ m ].block_mob[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next)
- if (bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1 && bl_list_count < BL_LIST_MAX)
- bl_list[ bl_list_count++ ] = bl;
-
- if (bl_list_count >= BL_LIST_MAX)
- ShowWarning("map_foreachinarea: block count too many!\n");
-
- map_freeblock_lock();
-
- for (i = blockcount; i < bl_list_count; i++)
- if (bl_list[ i ]->prev) { //func() may delete this bl_list[] slot, checking for prev ensures it wasnt queued for deletion.
- va_start(ap, type);
- returnCount += func(bl_list[ i ], ap);
- va_end(ap);
- if (count && returnCount >= count)
- break;
- }
-
- map_freeblock_unlock();
-
- bl_list_count = blockcount;
- return returnCount; //[Skotlex]
+ && bl_list_count < BL_LIST_MAX )
+ bl_list[ bl_list_count++ ] = bl;
+ }
+ }
+ }
+
+ if( bl_list_count >= BL_LIST_MAX )
+ ShowWarning("map_forcountinrange: block count too many!\n");
+
+ map_freeblock_lock();
+
+ for( i = blockcount; i < bl_list_count; i++ )
+ if( bl_list[ i ]->prev ) { //func() may delete this bl_list[] slot, checking for prev ensures it wasnt queued for deletion.
+ va_start(ap, type);
+ returnCount += func(bl_list[ i ], ap);
+ va_end(ap);
+ if( count && returnCount >= count )
+ break;
+ }
+
+ map_freeblock_unlock();
+
+ bl_list_count = blockcount;
+ return returnCount; //[Skotlex]
+}
+int map_forcountinarea(int (*func)(struct block_list*,va_list), int m, int x0, int y0, int x1, int y1, int count, int type, ...)
+{
+ int bx, by;
+ int returnCount = 0; //total sum of returned values of func() [Skotlex]
+ struct block_list *bl;
+ int blockcount = bl_list_count, i;
+ va_list ap;
+
+ if ( m < 0 )
+ return 0;
+
+ if ( x1 < x0 )
+ swap(x0, x1);
+ if ( y1 < y0 )
+ swap(y0, y1);
+
+ x0 = max(x0, 0);
+ y0 = max(y0, 0);
+ x1 = min(x1, map[ m ].xs - 1);
+ y1 = min(y1, map[ m ].ys - 1);
+
+ if ( type&~BL_MOB )
+ for( by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++ )
+ for( bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++ )
+ for( bl = map[ m ].block[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next )
+ if( bl->type&type && bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1 && bl_list_count < BL_LIST_MAX )
+ bl_list[ bl_list_count++ ] = bl;
+
+ if( type&BL_MOB )
+ for( by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++ )
+ for( bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++ )
+ for( bl = map[ m ].block_mob[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next )
+ if( bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1 && bl_list_count < BL_LIST_MAX )
+ bl_list[ bl_list_count++ ] = bl;
+
+ if( bl_list_count >= BL_LIST_MAX )
+ ShowWarning("map_foreachinarea: block count too many!\n");
+
+ map_freeblock_lock();
+
+ for( i = blockcount; i < bl_list_count; i++ )
+ if(bl_list[ i ]->prev) { //func() may delete this bl_list[] slot, checking for prev ensures it wasnt queued for deletion.
+ va_start(ap, type);
+ returnCount += func(bl_list[ i ], ap);
+ va_end(ap);
+ if( count && returnCount >= count )
+ break;
+ }
+
+ map_freeblock_unlock();
+
+ bl_list_count = blockcount;
+ return returnCount; //[Skotlex]
}
/*==========================================
@@ -837,390 +844,390 @@ int map_forcountinarea(int (*func)(struct block_list *,va_list), int m, int x0,
* Move bl and do func* with va_list while moving.
* Mouvement is set by dx dy wich are distance in x and y
*------------------------------------------*/
-int map_foreachinmovearea(int (*func)(struct block_list *,va_list), struct block_list *center, int range, int dx, int dy, int type, ...)
-{
- int bx, by, m;
- int returnCount = 0; //total sum of returned values of func() [Skotlex]
- struct block_list *bl;
- int blockcount = bl_list_count, i;
- int x0, x1, y0, y1;
- va_list ap;
-
- if (!range) return 0;
- if (!dx && !dy) return 0; //No movement.
-
- m = center->m;
-
- x0 = center->x - range;
- x1 = center->x + range;
- y0 = center->y - range;
- y1 = center->y + range;
-
- if (x1 < x0)
- swap(x0, x1);
- if (y1 < y0)
- swap(y0, y1);
-
- if (dx == 0 || dy == 0) {
- //Movement along one axis only.
- if (dx == 0) {
- if (dy < 0) //Moving south
- y0 = y1 + dy + 1;
- else //North
- y1 = y0 + dy - 1;
- } else { //dy == 0
- if (dx < 0) //West
- x0 = x1 + dx + 1;
- else //East
- x1 = x0 + dx - 1;
- }
-
- x0 = max(x0, 0);
- y0 = max(y0, 0);
- x1 = min(x1, map[ m ].xs - 1);
- y1 = min(y1, map[ m ].ys - 1);
-
- for (by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++) {
- for (bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++) {
- if (type&~BL_MOB) {
- for (bl = map[m].block[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next) {
- if (bl->type&type &&
- bl->x >= x0 && bl->x <= x1 &&
- bl->y >= y0 && bl->y <= y1 &&
- bl_list_count < BL_LIST_MAX)
- bl_list[ bl_list_count++ ] = bl;
- }
- }
- if (type&BL_MOB) {
- for (bl = map[ m ].block_mob[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next) {
- if (bl->x >= x0 && bl->x <= x1 &&
- bl->y >= y0 && bl->y <= y1 &&
- bl_list_count < BL_LIST_MAX)
- bl_list[ bl_list_count++ ] = bl;
- }
- }
- }
- }
- } else { // Diagonal movement
-
- x0 = max(x0, 0);
- y0 = max(y0, 0);
- x1 = min(x1, map[ m ].xs - 1);
- y1 = min(y1, map[ m ].ys - 1);
-
- for (by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++) {
- for (bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++) {
- if (type & ~BL_MOB) {
- for (bl = map[ m ].block[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next) {
- if (bl->type&type &&
- bl->x >= x0 && bl->x <= x1 &&
- bl->y >= y0 && bl->y <= y1 &&
- bl_list_count < BL_LIST_MAX)
- if ((dx > 0 && bl->x < x0 + dx) ||
- (dx < 0 && bl->x > x1 + dx) ||
- (dy > 0 && bl->y < y0 + dy) ||
- (dy < 0 && bl->y > y1 + dy))
- bl_list[ bl_list_count++ ] = bl;
- }
- }
- if (type&BL_MOB) {
- for (bl = map[ m ].block_mob[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next) {
- if (bl->x >= x0 && bl->x <= x1 &&
- bl->y >= y0 && bl->y <= y1 &&
- bl_list_count < BL_LIST_MAX)
- if ((dx > 0 && bl->x < x0 + dx) ||
- (dx < 0 && bl->x > x1 + dx) ||
- (dy > 0 && bl->y < y0 + dy) ||
- (dy < 0 && bl->y > y1 + dy))
- bl_list[ bl_list_count++ ] = bl;
- }
- }
- }
- }
-
- }
-
- if (bl_list_count >= BL_LIST_MAX)
- ShowWarning("map_foreachinmovearea: block count too many!\n");
-
- map_freeblock_lock(); // Prohibit the release from memory
-
- for (i = blockcount; i < bl_list_count; i++)
- if (bl_list[ i ]->prev) { //func() may delete this bl_list[] slot, checking for prev ensures it wasnt queued for deletion.
- va_start(ap, type);
- returnCount += func(bl_list[ i ], ap);
- va_end(ap);
- }
-
- map_freeblock_unlock(); // Allow Free
-
- bl_list_count = blockcount;
- return returnCount;
-}
-
-// -- moonsoul (added map_foreachincell which is a rework of map_foreachinarea but
-// which only checks the exact single x/y passed to it rather than an
-// area radius - may be more useful in some instances)
+int map_foreachinmovearea(int (*func)(struct block_list*,va_list), struct block_list* center, int range, int dx, int dy, int type, ...)
+{
+ int bx, by, m;
+ int returnCount = 0; //total sum of returned values of func() [Skotlex]
+ struct block_list *bl;
+ int blockcount = bl_list_count, i;
+ int x0, x1, y0, y1;
+ va_list ap;
+
+ if ( !range ) return 0;
+ if ( !dx && !dy ) return 0; //No movement.
+
+ m = center->m;
+
+ x0 = center->x - range;
+ x1 = center->x + range;
+ y0 = center->y - range;
+ y1 = center->y + range;
+
+ if ( x1 < x0 )
+ swap(x0, x1);
+ if ( y1 < y0 )
+ swap(y0, y1);
+
+ if( dx == 0 || dy == 0 ) {
+ //Movement along one axis only.
+ if( dx == 0 ){
+ if( dy < 0 ) //Moving south
+ y0 = y1 + dy + 1;
+ else //North
+ y1 = y0 + dy - 1;
+ } else { //dy == 0
+ if( dx < 0 ) //West
+ x0 = x1 + dx + 1;
+ else //East
+ x1 = x0 + dx - 1;
+ }
+
+ x0 = max(x0, 0);
+ y0 = max(y0, 0);
+ x1 = min(x1, map[ m ].xs - 1);
+ y1 = min(y1, map[ m ].ys - 1);
+
+ for( by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++ ) {
+ for( bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++ ) {
+ if ( type&~BL_MOB ) {
+ for( bl = map[m].block[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next ) {
+ if( bl->type&type &&
+ bl->x >= x0 && bl->x <= x1 &&
+ bl->y >= y0 && bl->y <= y1 &&
+ bl_list_count < BL_LIST_MAX )
+ bl_list[ bl_list_count++ ] = bl;
+ }
+ }
+ if ( type&BL_MOB ) {
+ for( bl = map[ m ].block_mob[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next ) {
+ if( bl->x >= x0 && bl->x <= x1 &&
+ bl->y >= y0 && bl->y <= y1 &&
+ bl_list_count < BL_LIST_MAX )
+ bl_list[ bl_list_count++ ] = bl;
+ }
+ }
+ }
+ }
+ } else { // Diagonal movement
+
+ x0 = max(x0, 0);
+ y0 = max(y0, 0);
+ x1 = min(x1, map[ m ].xs - 1);
+ y1 = min(y1, map[ m ].ys - 1);
+
+ for( by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++ ) {
+ for( bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++ ) {
+ if ( type & ~BL_MOB ) {
+ for( bl = map[ m ].block[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next ) {
+ if( bl->type&type &&
+ bl->x >= x0 && bl->x <= x1 &&
+ bl->y >= y0 && bl->y <= y1 &&
+ bl_list_count < BL_LIST_MAX )
+ if( ( dx > 0 && bl->x < x0 + dx) ||
+ ( dx < 0 && bl->x > x1 + dx) ||
+ ( dy > 0 && bl->y < y0 + dy) ||
+ ( dy < 0 && bl->y > y1 + dy) )
+ bl_list[ bl_list_count++ ] = bl;
+ }
+ }
+ if ( type&BL_MOB ) {
+ for( bl = map[ m ].block_mob[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next ) {
+ if( bl->x >= x0 && bl->x <= x1 &&
+ bl->y >= y0 && bl->y <= y1 &&
+ bl_list_count < BL_LIST_MAX)
+ if( ( dx > 0 && bl->x < x0 + dx) ||
+ ( dx < 0 && bl->x > x1 + dx) ||
+ ( dy > 0 && bl->y < y0 + dy) ||
+ ( dy < 0 && bl->y > y1 + dy) )
+ bl_list[ bl_list_count++ ] = bl;
+ }
+ }
+ }
+ }
+
+ }
+
+ if( bl_list_count >= BL_LIST_MAX )
+ ShowWarning("map_foreachinmovearea: block count too many!\n");
+
+ map_freeblock_lock(); // Prohibit the release from memory
+
+ for( i = blockcount; i < bl_list_count; i++ )
+ if( bl_list[ i ]->prev ) { //func() may delete this bl_list[] slot, checking for prev ensures it wasnt queued for deletion.
+ va_start(ap, type);
+ returnCount += func(bl_list[ i ], ap);
+ va_end(ap);
+ }
+
+ map_freeblock_unlock(); // Allow Free
+
+ bl_list_count = blockcount;
+ return returnCount;
+}
+
+// -- moonsoul (added map_foreachincell which is a rework of map_foreachinarea but
+// which only checks the exact single x/y passed to it rather than an
+// area radius - may be more useful in some instances)
//
-int map_foreachincell(int (*func)(struct block_list *,va_list), int m, int x, int y, int type, ...)
+int map_foreachincell(int (*func)(struct block_list*,va_list), int m, int x, int y, int type, ...)
{
- int bx, by;
- int returnCount = 0; //total sum of returned values of func() [Skotlex]
- struct block_list *bl;
- int blockcount = bl_list_count, i;
- va_list ap;
+ int bx, by;
+ int returnCount = 0; //total sum of returned values of func() [Skotlex]
+ struct block_list *bl;
+ int blockcount = bl_list_count, i;
+ va_list ap;
- if (x < 0 || y < 0 || x >= map[ m ].xs || y >= map[ m ].ys) return 0;
+ if ( x < 0 || y < 0 || x >= map[ m ].xs || y >= map[ m ].ys ) return 0;
- by = y / BLOCK_SIZE;
- bx = x / BLOCK_SIZE;
+ by = y / BLOCK_SIZE;
+ bx = x / BLOCK_SIZE;
- if (type&~BL_MOB)
- for (bl = map[ m ].block[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next)
- if (bl->type&type && bl->x == x && bl->y == y && bl_list_count < BL_LIST_MAX)
- bl_list[ bl_list_count++ ] = bl;
- if (type&BL_MOB)
- for (bl = map[ m ].block_mob[ bx + by * map[ m ].bxs]; bl != NULL; bl = bl->next)
- if (bl->x == x && bl->y == y && bl_list_count < BL_LIST_MAX)
- bl_list[ bl_list_count++ ] = bl;
+ if( type&~BL_MOB )
+ for( bl = map[ m ].block[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next )
+ if( bl->type&type && bl->x == x && bl->y == y && bl_list_count < BL_LIST_MAX )
+ bl_list[ bl_list_count++ ] = bl;
+ if( type&BL_MOB )
+ for( bl = map[ m ].block_mob[ bx + by * map[ m ].bxs]; bl != NULL; bl = bl->next )
+ if( bl->x == x && bl->y == y && bl_list_count < BL_LIST_MAX)
+ bl_list[ bl_list_count++ ] = bl;
- if (bl_list_count >= BL_LIST_MAX)
- ShowWarning("map_foreachincell: block count too many!\n");
+ if( bl_list_count >= BL_LIST_MAX )
+ ShowWarning("map_foreachincell: block count too many!\n");
- map_freeblock_lock();
+ map_freeblock_lock();
- for (i = blockcount; i < bl_list_count; i++)
- if (bl_list[ i ]->prev) { //func() may delete this bl_list[] slot, checking for prev ensures it wasnt queued for deletion.
- va_start(ap, type);
- returnCount += func(bl_list[ i ], ap);
- va_end(ap);
- }
+ for( i = blockcount; i < bl_list_count; i++ )
+ if( bl_list[ i ]->prev ) { //func() may delete this bl_list[] slot, checking for prev ensures it wasnt queued for deletion.
+ va_start(ap, type);
+ returnCount += func(bl_list[ i ], ap);
+ va_end(ap);
+ }
- map_freeblock_unlock();
+ map_freeblock_unlock();
- bl_list_count = blockcount;
- return returnCount;
+ bl_list_count = blockcount;
+ return returnCount;
}
/*============================================================
* For checking a path between two points (x0, y0) and (x1, y1)
*------------------------------------------------------------*/
-int map_foreachinpath(int (*func)(struct block_list *,va_list),int m,int x0,int y0,int x1,int y1,int range,int length, int type,...)
-{
- int returnCount = 0; //total sum of returned values of func() [Skotlex]
- //////////////////////////////////////////////////////////////
- //
- // sharp shooting 3 [Skotlex]
- //
- //////////////////////////////////////////////////////////////
- // problem:
- // Same as Sharp Shooting 1. Hits all targets within range of
- // the line.
- // (t1,t2 t3 and t4 get hit)
- //
- // target 1
- // x t4
- // t2
- // t3 x
- // x
- // S
- //////////////////////////////////////////////////////////////
- // Methodology:
- // My trigonometrics and math are a little rusty... so the approach I am writing
- // here is basicly do a double for to check for all targets in the square that
- // contains the initial and final positions (area range increased to match the
- // radius given), then for each object to test, calculate the distance to the
- // path and include it if the range fits and the target is in the line (0<k<1,
- // as they call it).
- // The implementation I took as reference is found at
- // http://astronomy.swin.edu.au/~pbourke/geometry/pointline/
- // (they have a link to a C implementation, too)
- // This approach is a lot like #2 commented on this function, which I have no
- // idea why it was commented. I won't use doubles/floats, but pure int math for
- // speed purposes. The range considered is always the same no matter how
- // close/far the target is because that's how SharpShooting works currently in
- // kRO.
-
- //Generic map_foreach* variables.
- int i, blockcount = bl_list_count;
- struct block_list *bl;
- int bx, by;
- //method specific variables
- int magnitude2, len_limit; //The square of the magnitude
- int k, xi, yi, xu, yu;
- int mx0 = x0, mx1 = x1, my0 = y0, my1 = y1;
- va_list ap;
-
- //Avoid needless calculations by not getting the sqrt right away.
-#define MAGNITUDE2(x0, y0, x1, y1) ( ( ( x1 ) - ( x0 ) ) * ( ( x1 ) - ( x0 ) ) + ( ( y1 ) - ( y0 ) ) * ( ( y1 ) - ( y0 ) ) )
-
- if (m < 0)
- return 0;
-
- len_limit = magnitude2 = MAGNITUDE2(x0, y0, x1, y1);
- if (magnitude2 < 1) //Same begin and ending point, can't trace path.
- return 0;
-
- if (length) { //Adjust final position to fit in the given area.
- //TODO: Find an alternate method which does not requires a square root calculation.
- k = (int)sqrt((float)magnitude2);
- mx1 = x0 + (x1 - x0) * length / k;
- my1 = y0 + (y1 - y0) * length / k;
- len_limit = MAGNITUDE2(x0, y0, mx1, my1);
- }
- //Expand target area to cover range.
- if (mx0 > mx1) {
- mx0 += range;
- mx1 -= range;
- } else {
- mx0 -= range;
- mx1 += range;
- }
- if (my0 > my1) {
- my0 += range;
- my1 -= range;
- } else {
- my0 -= range;
- my1 += range;
- }
-
- //The two fors assume mx0 < mx1 && my0 < my1
- if (mx0 > mx1)
- swap(mx0, mx1);
- if (my0 > my1)
- swap(my0, my1);
-
- mx0 = max(mx0, 0);
- my0 = max(my0, 0);
- mx1 = min(mx1, map[ m ].xs - 1);
- my1 = min(my1, map[ m ].ys - 1);
-
- range *= range << 8; //Values are shifted later on for higher precision using int math.
-
- if (type&~BL_MOB)
- for (by = my0 / BLOCK_SIZE; by <= my1 / BLOCK_SIZE; by++) {
- for (bx = mx0 / BLOCK_SIZE; bx <= mx1 / BLOCK_SIZE; bx++) {
- for (bl = map[ m ].block[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next) {
- if (bl->prev && bl->type&type && bl_list_count < BL_LIST_MAX) {
- xi = bl->x;
- yi = bl->y;
-
- k = (xi - x0) * (x1 - x0) + (yi - y0) * (y1 - y0);
-
- if (k < 0 || k > len_limit) //Since more skills use this, check for ending point as well.
- continue;
-
- if (k > magnitude2 && !path_search_long(NULL, m, x0, y0, xi, yi, CELL_CHKWALL))
- continue; //Targets beyond the initial ending point need the wall check.
-
- //All these shifts are to increase the precision of the intersection point and distance considering how it's
- //int math.
- k = (k << 4) / magnitude2; //k will be between 1~16 instead of 0~1
- xi <<= 4;
- yi <<= 4;
- xu = (x0 << 4) + k * (x1 - x0);
- yu = (y0 << 4) + k * (y1 - y0);
- k = MAGNITUDE2(xi, yi, xu, yu);
-
- //If all dot coordinates were <<4 the square of the magnitude is <<8
- if (k > range)
- continue;
-
- bl_list[ bl_list_count++ ] = bl;
- }
- }
- }
- }
- if (type&BL_MOB)
- for (by = my0 / BLOCK_SIZE; by <= my1 / BLOCK_SIZE; by++) {
- for (bx = mx0 / BLOCK_SIZE; bx <= mx1 / BLOCK_SIZE; bx++) {
- for (bl = map[ m ].block_mob[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next) {
- if (bl->prev && bl_list_count < BL_LIST_MAX) {
- xi = bl->x;
- yi = bl->y;
- k = (xi - x0) * (x1 - x0) + (yi - y0) * (y1 - y0);
-
- if (k < 0 || k > len_limit)
- continue;
-
- if (k > magnitude2 && !path_search_long(NULL, m, x0, y0, xi, yi, CELL_CHKWALL))
- continue; //Targets beyond the initial ending point need the wall check.
-
- k = (k << 4) / magnitude2; //k will be between 1~16 instead of 0~1
- xi <<= 4;
- yi <<= 4;
- xu = (x0 << 4) + k * (x1 - x0);
- yu = (y0 << 4) + k * (y1 - y0);
- k = MAGNITUDE2(xi, yi, xu, yu);
-
- //If all dot coordinates were <<4 the square of the magnitude is <<8
- if (k > range)
- continue;
-
- bl_list[ bl_list_count++ ] = bl;
- }
- }
- }
- }
-
- if (bl_list_count >= BL_LIST_MAX)
- ShowWarning("map_foreachinpath: block count too many!\n");
-
- map_freeblock_lock();
-
- for (i = blockcount; i < bl_list_count; i++)
- if (bl_list[ i ]->prev) { //func() may delete this bl_list[] slot, checking for prev ensures it wasnt queued for deletion.
- va_start(ap, type);
- returnCount += func(bl_list[ i ], ap);
- va_end(ap);
- }
-
- map_freeblock_unlock();
-
- bl_list_count = blockcount;
- return returnCount; //[Skotlex]
+int map_foreachinpath(int (*func)(struct block_list*,va_list),int m,int x0,int y0,int x1,int y1,int range,int length, int type,...)
+{
+ int returnCount = 0; //total sum of returned values of func() [Skotlex]
+//////////////////////////////////////////////////////////////
+//
+// sharp shooting 3 [Skotlex]
+//
+//////////////////////////////////////////////////////////////
+// problem:
+// Same as Sharp Shooting 1. Hits all targets within range of
+// the line.
+// (t1,t2 t3 and t4 get hit)
+//
+// target 1
+// x t4
+// t2
+// t3 x
+// x
+// S
+//////////////////////////////////////////////////////////////
+// Methodology:
+// My trigonometrics and math are a little rusty... so the approach I am writing
+// here is basicly do a double for to check for all targets in the square that
+// contains the initial and final positions (area range increased to match the
+// radius given), then for each object to test, calculate the distance to the
+// path and include it if the range fits and the target is in the line (0<k<1,
+// as they call it).
+// The implementation I took as reference is found at
+// http://astronomy.swin.edu.au/~pbourke/geometry/pointline/
+// (they have a link to a C implementation, too)
+// This approach is a lot like #2 commented on this function, which I have no
+// idea why it was commented. I won't use doubles/floats, but pure int math for
+// speed purposes. The range considered is always the same no matter how
+// close/far the target is because that's how SharpShooting works currently in
+// kRO.
+
+ //Generic map_foreach* variables.
+ int i, blockcount = bl_list_count;
+ struct block_list *bl;
+ int bx, by;
+ //method specific variables
+ int magnitude2, len_limit; //The square of the magnitude
+ int k, xi, yi, xu, yu;
+ int mx0 = x0, mx1 = x1, my0 = y0, my1 = y1;
+ va_list ap;
+
+ //Avoid needless calculations by not getting the sqrt right away.
+ #define MAGNITUDE2(x0, y0, x1, y1) ( ( ( x1 ) - ( x0 ) ) * ( ( x1 ) - ( x0 ) ) + ( ( y1 ) - ( y0 ) ) * ( ( y1 ) - ( y0 ) ) )
+
+ if ( m < 0 )
+ return 0;
+
+ len_limit = magnitude2 = MAGNITUDE2(x0, y0, x1, y1);
+ if ( magnitude2 < 1 ) //Same begin and ending point, can't trace path.
+ return 0;
+
+ if ( length ) { //Adjust final position to fit in the given area.
+ //TODO: Find an alternate method which does not requires a square root calculation.
+ k = (int)sqrt((float)magnitude2);
+ mx1 = x0 + (x1 - x0) * length / k;
+ my1 = y0 + (y1 - y0) * length / k;
+ len_limit = MAGNITUDE2(x0, y0, mx1, my1);
+ }
+ //Expand target area to cover range.
+ if ( mx0 > mx1 ) {
+ mx0 += range;
+ mx1 -= range;
+ } else {
+ mx0 -= range;
+ mx1 += range;
+ }
+ if (my0 > my1) {
+ my0 += range;
+ my1 -= range;
+ } else {
+ my0 -= range;
+ my1 += range;
+ }
+
+ //The two fors assume mx0 < mx1 && my0 < my1
+ if ( mx0 > mx1 )
+ swap(mx0, mx1);
+ if ( my0 > my1 )
+ swap(my0, my1);
+
+ mx0 = max(mx0, 0);
+ my0 = max(my0, 0);
+ mx1 = min(mx1, map[ m ].xs - 1);
+ my1 = min(my1, map[ m ].ys - 1);
+
+ range *= range << 8; //Values are shifted later on for higher precision using int math.
+
+ if ( type&~BL_MOB )
+ for ( by = my0 / BLOCK_SIZE; by <= my1 / BLOCK_SIZE; by++ ) {
+ for( bx = mx0 / BLOCK_SIZE; bx <= mx1 / BLOCK_SIZE; bx++ ) {
+ for( bl = map[ m ].block[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next ) {
+ if( bl->prev && bl->type&type && bl_list_count < BL_LIST_MAX ) {
+ xi = bl->x;
+ yi = bl->y;
+
+ k = ( xi - x0 ) * ( x1 - x0 ) + ( yi - y0 ) * ( y1 - y0 );
+
+ if ( k < 0 || k > len_limit ) //Since more skills use this, check for ending point as well.
+ continue;
+
+ if ( k > magnitude2 && !path_search_long(NULL, m, x0, y0, xi, yi, CELL_CHKWALL) )
+ continue; //Targets beyond the initial ending point need the wall check.
+
+ //All these shifts are to increase the precision of the intersection point and distance considering how it's
+ //int math.
+ k = ( k << 4 ) / magnitude2; //k will be between 1~16 instead of 0~1
+ xi <<= 4;
+ yi <<= 4;
+ xu = ( x0 << 4 ) + k * ( x1 - x0 );
+ yu = ( y0 << 4 ) + k * ( y1 - y0 );
+ k = MAGNITUDE2(xi, yi, xu, yu);
+
+ //If all dot coordinates were <<4 the square of the magnitude is <<8
+ if ( k > range )
+ continue;
+
+ bl_list[ bl_list_count++ ] = bl;
+ }
+ }
+ }
+ }
+ if( type&BL_MOB )
+ for( by = my0 / BLOCK_SIZE; by <= my1 / BLOCK_SIZE; by++ ) {
+ for( bx = mx0 / BLOCK_SIZE; bx <= mx1 / BLOCK_SIZE; bx++ ) {
+ for( bl = map[ m ].block_mob[ bx + by * map[ m ].bxs ]; bl != NULL; bl = bl->next ) {
+ if( bl->prev && bl_list_count < BL_LIST_MAX ) {
+ xi = bl->x;
+ yi = bl->y;
+ k = ( xi - x0 ) * ( x1 - x0 ) + ( yi - y0 ) * ( y1 - y0 );
+
+ if ( k < 0 || k > len_limit )
+ continue;
+
+ if ( k > magnitude2 && !path_search_long(NULL, m, x0, y0, xi, yi, CELL_CHKWALL) )
+ continue; //Targets beyond the initial ending point need the wall check.
+
+ k = ( k << 4 ) / magnitude2; //k will be between 1~16 instead of 0~1
+ xi <<= 4;
+ yi <<= 4;
+ xu = ( x0 << 4 ) + k * ( x1 - x0 );
+ yu = ( y0 << 4 ) + k * ( y1 - y0 );
+ k = MAGNITUDE2(xi, yi, xu, yu);
+
+ //If all dot coordinates were <<4 the square of the magnitude is <<8
+ if ( k > range )
+ continue;
+
+ bl_list[ bl_list_count++ ] = bl;
+ }
+ }
+ }
+ }
+
+ if( bl_list_count >= BL_LIST_MAX )
+ ShowWarning("map_foreachinpath: block count too many!\n");
+
+ map_freeblock_lock();
+
+ for( i = blockcount; i < bl_list_count; i++ )
+ if( bl_list[ i ]->prev ) { //func() may delete this bl_list[] slot, checking for prev ensures it wasnt queued for deletion.
+ va_start(ap, type);
+ returnCount += func(bl_list[ i ], ap);
+ va_end(ap);
+ }
+
+ map_freeblock_unlock();
+
+ bl_list_count = blockcount;
+ return returnCount; //[Skotlex]
}
// Copy of map_foreachincell, but applied to the whole map. [Skotlex]
-int map_foreachinmap(int (*func)(struct block_list *,va_list), int m, int type,...)
+int map_foreachinmap(int (*func)(struct block_list*,va_list), int m, int type,...)
{
- int b, bsize;
- int returnCount = 0; //total sum of returned values of func() [Skotlex]
- struct block_list *bl;
- int blockcount = bl_list_count, i;
- va_list ap;
-
- bsize = map[ m ].bxs * map[ m ].bys;
+ int b, bsize;
+ int returnCount = 0; //total sum of returned values of func() [Skotlex]
+ struct block_list *bl;
+ int blockcount = bl_list_count, i;
+ va_list ap;
+
+ bsize = map[ m ].bxs * map[ m ].bys;
- if (type&~BL_MOB)
- for (b = 0; b < bsize; b++)
- for (bl = map[ m ].block[ b ]; bl != NULL; bl = bl->next)
- if (bl->type&type && bl_list_count < BL_LIST_MAX)
- bl_list[ bl_list_count++ ] = bl;
+ if( type&~BL_MOB )
+ for( b = 0; b < bsize; b++ )
+ for( bl = map[ m ].block[ b ]; bl != NULL; bl = bl->next )
+ if( bl->type&type && bl_list_count < BL_LIST_MAX )
+ bl_list[ bl_list_count++ ] = bl;
- if (type&BL_MOB)
- for (b = 0; b < bsize; b++)
- for (bl = map[ m ].block_mob[ b ]; bl != NULL; bl = bl->next)
- if (bl_list_count < BL_LIST_MAX)
- bl_list[ bl_list_count++ ] = bl;
+ if( type&BL_MOB )
+ for( b = 0; b < bsize; b++ )
+ for( bl = map[ m ].block_mob[ b ]; bl != NULL; bl = bl->next )
+ if( bl_list_count < BL_LIST_MAX )
+ bl_list[ bl_list_count++ ] = bl;
- if (bl_list_count >= BL_LIST_MAX)
- ShowWarning("map_foreachinmap: block count too many!\n");
+ if( bl_list_count >= BL_LIST_MAX )
+ ShowWarning("map_foreachinmap: block count too many!\n");
- map_freeblock_lock();
+ map_freeblock_lock();
- for (i = blockcount; i < bl_list_count ; i++)
- if (bl_list[ i ]->prev) { //func() may delete this bl_list[] slot, checking for prev ensures it wasnt queued for deletion.
- va_start(ap, type);
- returnCount += func(bl_list[ i ], ap);
- va_end(ap);
- }
+ for( i = blockcount; i < bl_list_count ; i++ )
+ if( bl_list[ i ]->prev ) { //func() may delete this bl_list[] slot, checking for prev ensures it wasnt queued for deletion.
+ va_start(ap, type);
+ returnCount += func(bl_list[ i ], ap);
+ va_end(ap);
+ }
- map_freeblock_unlock();
+ map_freeblock_unlock();
- bl_list_count = blockcount;
- return returnCount;
+ bl_list_count = blockcount;
+ return returnCount;
}
@@ -1229,30 +1236,30 @@ int map_foreachinmap(int (*func)(struct block_list *,va_list), int m, int type,.
/// @return The new object id
int map_get_new_object_id(void)
{
- static int last_object_id = MIN_FLOORITEM - 1;
- int i;
+ static int last_object_id = MIN_FLOORITEM - 1;
+ int i;
- // find a free id
- i = last_object_id + 1;
- while (i != last_object_id) {
- if (i == MAX_FLOORITEM)
- i = MIN_FLOORITEM;
+ // find a free id
+ i = last_object_id + 1;
+ while( i != last_object_id ) {
+ if( i == MAX_FLOORITEM )
+ i = MIN_FLOORITEM;
- if (!idb_exists(id_db, i))
- break;
+ if( !idb_exists(id_db, i) )
+ break;
- ++i;
- }
+ ++i;
+ }
- if (i == last_object_id) {
- ShowError("map_addobject: no free object id!\n");
- return 0;
- }
+ if( i == last_object_id ) {
+ ShowError("map_addobject: no free object id!\n");
+ return 0;
+ }
- // update cursor
- last_object_id = i;
+ // update cursor
+ last_object_id = i;
- return i;
+ return i;
}
/*==========================================
@@ -1261,38 +1268,37 @@ int map_get_new_object_id(void)
*------------------------------------------*/
int map_clearflooritem_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- struct flooritem_data *fitem = (struct flooritem_data *)idb_get(id_db, id);
+ struct flooritem_data* fitem = (struct flooritem_data*)idb_get(id_db, id);
- if (fitem == NULL || fitem->bl.type != BL_ITEM || (fitem->cleartimer != tid)) {
- ShowError("map_clearflooritem_timer : error\n");
- return 1;
- }
+ if (fitem == NULL || fitem->bl.type != BL_ITEM || (fitem->cleartimer != tid)) {
+ ShowError("map_clearflooritem_timer : error\n");
+ return 1;
+ }
- if (search_petDB_index(fitem->item_data.nameid, PET_EGG) >= 0)
- intif_delete_petdata(MakeDWord(fitem->item_data.card[1], fitem->item_data.card[2]));
+ if (search_petDB_index(fitem->item_data.nameid, PET_EGG) >= 0)
+ intif_delete_petdata(MakeDWord(fitem->item_data.card[1], fitem->item_data.card[2]));
- clif_clearflooritem(fitem, 0);
- map_deliddb(&fitem->bl);
- map_delblock(&fitem->bl);
- map_freeblock(&fitem->bl);
- return 0;
+ clif_clearflooritem(fitem, 0);
+ map_deliddb(&fitem->bl);
+ map_delblock(&fitem->bl);
+ map_freeblock(&fitem->bl);
+ return 0;
}
-/*
+/*
* clears a single bl item out of the bazooonga.
*/
-void map_clearflooritem(struct block_list *bl)
-{
- struct flooritem_data *fitem = (struct flooritem_data *)bl;
-
- if (fitem->cleartimer)
- delete_timer(fitem->cleartimer,map_clearflooritem_timer);
-
- clif_clearflooritem(fitem, 0);
- map_deliddb(&fitem->bl);
- map_delblock(&fitem->bl);
- map_freeblock(&fitem->bl);
+void map_clearflooritem(struct block_list *bl) {
+ struct flooritem_data* fitem = (struct flooritem_data*)bl;
+
+ if( fitem->cleartimer )
+ delete_timer(fitem->cleartimer,map_clearflooritem_timer);
+
+ clif_clearflooritem(fitem, 0);
+ map_deliddb(&fitem->bl);
+ map_delblock(&fitem->bl);
+ map_freeblock(&fitem->bl);
}
/*==========================================
@@ -1300,38 +1306,37 @@ void map_clearflooritem(struct block_list *bl)
* to place an BL_ITEM object. Scan area is 9x9, returns 1 on success.
* x and y are modified with the target cell when successful.
*------------------------------------------*/
-int map_searchrandfreecell(int m,int *x,int *y,int stack)
-{
- int free_cell,i,j;
- int free_cells[9][2];
-
- for (free_cell=0,i=-1; i<=1; i++) {
- if (i+*y<0 || i+*y>=map[m].ys)
- continue;
- for (j=-1; j<=1; j++) {
- if (j+*x<0 || j+*x>=map[m].xs)
- continue;
- if (map_getcell(m,j+*x,i+*y,CELL_CHKNOPASS) && !map_getcell(m,j+*x,i+*y,CELL_CHKICEWALL))
- continue;
- //Avoid item stacking to prevent against exploits. [Skotlex]
- if (stack && map_count_oncell(m,j+*x,i+*y, BL_ITEM) > stack)
- continue;
- free_cells[free_cell][0] = j+*x;
- free_cells[free_cell++][1] = i+*y;
- }
- }
- if (free_cell==0)
- return 0;
- free_cell = rnd()%free_cell;
- *x = free_cells[free_cell][0];
- *y = free_cells[free_cell][1];
- return 1;
+int map_searchrandfreecell(int m,int *x,int *y,int stack) {
+ int free_cell,i,j;
+ int free_cells[9][2];
+
+ for(free_cell=0,i=-1;i<=1;i++){
+ if(i+*y<0 || i+*y>=map[m].ys)
+ continue;
+ for(j=-1;j<=1;j++){
+ if(j+*x<0 || j+*x>=map[m].xs)
+ continue;
+ if(map_getcell(m,j+*x,i+*y,CELL_CHKNOPASS) && !map_getcell(m,j+*x,i+*y,CELL_CHKICEWALL))
+ continue;
+ //Avoid item stacking to prevent against exploits. [Skotlex]
+ if(stack && map_count_oncell(m,j+*x,i+*y, BL_ITEM) > stack)
+ continue;
+ free_cells[free_cell][0] = j+*x;
+ free_cells[free_cell++][1] = i+*y;
+ }
+ }
+ if(free_cell==0)
+ return 0;
+ free_cell = rnd()%free_cell;
+ *x = free_cells[free_cell][0];
+ *y = free_cells[free_cell][1];
+ return 1;
}
static int map_count_sub(struct block_list *bl,va_list ap)
{
- return 1;
+ return 1;
}
/*==========================================
@@ -1348,64 +1353,66 @@ static int map_count_sub(struct block_list *bl,va_list ap)
*------------------------------------------*/
int map_search_freecell(struct block_list *src, int m, short *x,short *y, int rx, int ry, int flag)
{
- int tries, spawn=0;
- int bx, by;
- int rx2 = 2*rx+1;
- int ry2 = 2*ry+1;
-
- if (!src && (!(flag&1) || flag&2)) {
- ShowDebug("map_search_freecell: Incorrect usage! When src is NULL, flag has to be &1 and can't have &2\n");
- return 0;
- }
-
- if (flag&1) {
- bx = *x;
- by = *y;
- } else {
- bx = src->x;
- by = src->y;
- m = src->m;
- }
- if (!rx && !ry) {
- //No range? Return the target cell then....
- *x = bx;
- *y = by;
- return map_getcell(m,*x,*y,CELL_CHKREACH);
- }
-
- if (rx >= 0 && ry >= 0) {
- tries = rx2*ry2;
- if (tries > 100) tries = 100;
- } else {
- tries = map[m].xs*map[m].ys;
- if (tries > 500) tries = 500;
- }
-
- while (tries--) {
- *x = (rx >= 0)?(rnd()%rx2-rx+bx):(rnd()%(map[m].xs-2)+1);
- *y = (ry >= 0)?(rnd()%ry2-ry+by):(rnd()%(map[m].ys-2)+1);
-
- if (*x == bx && *y == by)
- continue; //Avoid picking the same target tile.
-
- if (map_getcell(m,*x,*y,CELL_CHKREACH)) {
- if (flag&2 && !unit_can_reach_pos(src, *x, *y, 1))
- continue;
- if (flag&4) {
- if (spawn >= 100) return 0; //Limit of retries reached.
- if (spawn++ < battle_config.no_spawn_on_player &&
- map_foreachinarea(map_count_sub, m,
- *x-AREA_SIZE, *y-AREA_SIZE,
- *x+AREA_SIZE, *y+AREA_SIZE, BL_PC)
- )
- continue;
- }
- return 1;
- }
- }
- *x = bx;
- *y = by;
- return 0;
+ int tries, spawn=0;
+ int bx, by;
+ int rx2 = 2*rx+1;
+ int ry2 = 2*ry+1;
+
+ if( !src && (!(flag&1) || flag&2) )
+ {
+ ShowDebug("map_search_freecell: Incorrect usage! When src is NULL, flag has to be &1 and can't have &2\n");
+ return 0;
+ }
+
+ if (flag&1) {
+ bx = *x;
+ by = *y;
+ } else {
+ bx = src->x;
+ by = src->y;
+ m = src->m;
+ }
+ if (!rx && !ry) {
+ //No range? Return the target cell then....
+ *x = bx;
+ *y = by;
+ return map_getcell(m,*x,*y,CELL_CHKREACH);
+ }
+
+ if (rx >= 0 && ry >= 0) {
+ tries = rx2*ry2;
+ if (tries > 100) tries = 100;
+ } else {
+ tries = map[m].xs*map[m].ys;
+ if (tries > 500) tries = 500;
+ }
+
+ while(tries--) {
+ *x = (rx >= 0)?(rnd()%rx2-rx+bx):(rnd()%(map[m].xs-2)+1);
+ *y = (ry >= 0)?(rnd()%ry2-ry+by):(rnd()%(map[m].ys-2)+1);
+
+ if (*x == bx && *y == by)
+ continue; //Avoid picking the same target tile.
+
+ if (map_getcell(m,*x,*y,CELL_CHKREACH))
+ {
+ if(flag&2 && !unit_can_reach_pos(src, *x, *y, 1))
+ continue;
+ if(flag&4) {
+ if (spawn >= 100) return 0; //Limit of retries reached.
+ if (spawn++ < battle_config.no_spawn_on_player &&
+ map_foreachinarea(map_count_sub, m,
+ *x-AREA_SIZE, *y-AREA_SIZE,
+ *x+AREA_SIZE, *y+AREA_SIZE, BL_PC)
+ )
+ continue;
+ }
+ return 1;
+ }
+ }
+ *x = bx;
+ *y = by;
+ return 0;
}
/*==========================================
@@ -1419,45 +1426,45 @@ int map_search_freecell(struct block_list *src, int m, short *x,short *y, int rx
*------------------------------------------*/
int map_addflooritem(struct item *item_data,int amount,int m,int x,int y,int first_charid,int second_charid,int third_charid,int flags)
{
- int r;
- struct flooritem_data *fitem=NULL;
+ int r;
+ struct flooritem_data *fitem=NULL;
- nullpo_ret(item_data);
+ nullpo_ret(item_data);
- if (!map_searchrandfreecell(m,&x,&y,flags&2?1:0))
- return 0;
- r=rnd();
+ if(!map_searchrandfreecell(m,&x,&y,flags&2?1:0))
+ return 0;
+ r=rnd();
- CREATE(fitem, struct flooritem_data, 1);
- fitem->bl.type=BL_ITEM;
- fitem->bl.prev = fitem->bl.next = NULL;
- fitem->bl.m=m;
- fitem->bl.x=x;
- fitem->bl.y=y;
- fitem->bl.id = map_get_new_object_id();
- if (fitem->bl.id==0) {
- aFree(fitem);
- return 0;
- }
+ CREATE(fitem, struct flooritem_data, 1);
+ fitem->bl.type=BL_ITEM;
+ fitem->bl.prev = fitem->bl.next = NULL;
+ fitem->bl.m=m;
+ fitem->bl.x=x;
+ fitem->bl.y=y;
+ fitem->bl.id = map_get_new_object_id();
+ if(fitem->bl.id==0){
+ aFree(fitem);
+ return 0;
+ }
- fitem->first_get_charid = first_charid;
- fitem->first_get_tick = gettick() + (flags&1 ? battle_config.mvp_item_first_get_time : battle_config.item_first_get_time);
- fitem->second_get_charid = second_charid;
- fitem->second_get_tick = fitem->first_get_tick + (flags&1 ? battle_config.mvp_item_second_get_time : battle_config.item_second_get_time);
- fitem->third_get_charid = third_charid;
- fitem->third_get_tick = fitem->second_get_tick + (flags&1 ? battle_config.mvp_item_third_get_time : battle_config.item_third_get_time);
+ fitem->first_get_charid = first_charid;
+ fitem->first_get_tick = gettick() + (flags&1 ? battle_config.mvp_item_first_get_time : battle_config.item_first_get_time);
+ fitem->second_get_charid = second_charid;
+ fitem->second_get_tick = fitem->first_get_tick + (flags&1 ? battle_config.mvp_item_second_get_time : battle_config.item_second_get_time);
+ fitem->third_get_charid = third_charid;
+ fitem->third_get_tick = fitem->second_get_tick + (flags&1 ? battle_config.mvp_item_third_get_time : battle_config.item_third_get_time);
- memcpy(&fitem->item_data,item_data,sizeof(*item_data));
- fitem->item_data.amount=amount;
- fitem->subx=(r&3)*3+3;
- fitem->suby=((r>>2)&3)*3+3;
- fitem->cleartimer=add_timer(gettick()+battle_config.flooritem_lifetime,map_clearflooritem_timer,fitem->bl.id,0);
+ memcpy(&fitem->item_data,item_data,sizeof(*item_data));
+ fitem->item_data.amount=amount;
+ fitem->subx=(r&3)*3+3;
+ fitem->suby=((r>>2)&3)*3+3;
+ fitem->cleartimer=add_timer(gettick()+battle_config.flooritem_lifetime,map_clearflooritem_timer,fitem->bl.id,0);
- map_addiddb(&fitem->bl);
- map_addblock(&fitem->bl);
- clif_dropflooritem(fitem);
+ map_addiddb(&fitem->bl);
+ map_addblock(&fitem->bl);
+ clif_dropflooritem(fitem);
- return fitem->bl.id;
+ return fitem->bl.id;
}
/**
@@ -1465,85 +1472,89 @@ int map_addflooritem(struct item *item_data,int amount,int m,int x,int y,int fir
*/
static DBData create_charid2nick(DBKey key, va_list args)
{
- struct charid2nick *p;
- CREATE(p, struct charid2nick, 1);
- return db_ptr2data(p);
+ struct charid2nick *p;
+ CREATE(p, struct charid2nick, 1);
+ return db_ptr2data(p);
}
/// Adds(or replaces) the nick of charid to nick_db and fullfils pending requests.
/// Does nothing if the character is online.
-void map_addnickdb(int charid, const char *nick)
+void map_addnickdb(int charid, const char* nick)
{
- struct charid2nick *p;
- struct charid_request *req;
- struct map_session_data *sd;
+ struct charid2nick* p;
+ struct charid_request* req;
+ struct map_session_data* sd;
- if (map_charid2sd(charid))
- return;// already online
+ if( map_charid2sd(charid) )
+ return;// already online
- p = idb_ensure(nick_db, charid, create_charid2nick);
- safestrncpy(p->nick, nick, sizeof(p->nick));
+ p = idb_ensure(nick_db, charid, create_charid2nick);
+ safestrncpy(p->nick, nick, sizeof(p->nick));
- while (p->requests) {
- req = p->requests;
- p->requests = req->next;
- sd = map_charid2sd(req->charid);
- if (sd)
- clif_solved_charname(sd->fd, charid, p->nick);
- aFree(req);
- }
+ while( p->requests )
+ {
+ req = p->requests;
+ p->requests = req->next;
+ sd = map_charid2sd(req->charid);
+ if( sd )
+ clif_solved_charname(sd->fd, charid, p->nick);
+ aFree(req);
+ }
}
/// Removes the nick of charid from nick_db.
/// Sends name to all pending requests on charid.
-void map_delnickdb(int charid, const char *name)
+void map_delnickdb(int charid, const char* name)
{
- struct charid2nick *p;
- struct charid_request *req;
- struct map_session_data *sd;
- DBData data;
+ struct charid2nick* p;
+ struct charid_request* req;
+ struct map_session_data* sd;
+ DBData data;
- if (!nick_db->remove(nick_db, db_i2key(charid), &data) || (p = db_data2ptr(&data)) == NULL)
- return;
+ if (!nick_db->remove(nick_db, db_i2key(charid), &data) || (p = db_data2ptr(&data)) == NULL)
+ return;
- while (p->requests) {
- req = p->requests;
- p->requests = req->next;
- sd = map_charid2sd(req->charid);
- if (sd)
- clif_solved_charname(sd->fd, charid, name);
- aFree(req);
- }
- aFree(p);
+ while( p->requests )
+ {
+ req = p->requests;
+ p->requests = req->next;
+ sd = map_charid2sd(req->charid);
+ if( sd )
+ clif_solved_charname(sd->fd, charid, name);
+ aFree(req);
+ }
+ aFree(p);
}
/// Notifies sd of the nick of charid.
/// Uses the name in the character if online.
/// Uses the name in nick_db if offline.
-void map_reqnickdb(struct map_session_data *sd, int charid)
-{
- struct charid2nick *p;
- struct charid_request *req;
- struct map_session_data *tsd;
-
- nullpo_retv(sd);
-
- tsd = map_charid2sd(charid);
- if (tsd) {
- clif_solved_charname(sd->fd, charid, tsd->status.name);
- return;
- }
-
- p = idb_ensure(nick_db, charid, create_charid2nick);
- if (*p->nick) {
- clif_solved_charname(sd->fd, charid, p->nick);
- return;
- }
- // not in cache, request it
- CREATE(req, struct charid_request, 1);
- req->next = p->requests;
- p->requests = req;
- chrif_searchcharid(charid);
+void map_reqnickdb(struct map_session_data * sd, int charid)
+{
+ struct charid2nick* p;
+ struct charid_request* req;
+ struct map_session_data* tsd;
+
+ nullpo_retv(sd);
+
+ tsd = map_charid2sd(charid);
+ if( tsd )
+ {
+ clif_solved_charname(sd->fd, charid, tsd->status.name);
+ return;
+ }
+
+ p = idb_ensure(nick_db, charid, create_charid2nick);
+ if( *p->nick )
+ {
+ clif_solved_charname(sd->fd, charid, p->nick);
+ return;
+ }
+ // not in cache, request it
+ CREATE(req, struct charid_request, 1);
+ req->next = p->requests;
+ p->requests = req;
+ chrif_searchcharid(charid);
}
/*==========================================
@@ -1551,24 +1562,27 @@ void map_reqnickdb(struct map_session_data *sd, int charid)
*------------------------------------------*/
void map_addiddb(struct block_list *bl)
{
- nullpo_retv(bl);
+ nullpo_retv(bl);
- if (bl->type == BL_PC) {
- TBL_PC *sd = (TBL_PC *)bl;
- idb_put(pc_db,sd->bl.id,sd);
- idb_put(charid_db,sd->status.char_id,sd);
- } else if (bl->type == BL_MOB) {
- TBL_MOB *md = (TBL_MOB *)bl;
- idb_put(mobid_db,bl->id,bl);
+ if( bl->type == BL_PC )
+ {
+ TBL_PC* sd = (TBL_PC*)bl;
+ idb_put(pc_db,sd->bl.id,sd);
+ idb_put(charid_db,sd->status.char_id,sd);
+ }
+ else if( bl->type == BL_MOB )
+ {
+ TBL_MOB* md = (TBL_MOB*)bl;
+ idb_put(mobid_db,bl->id,bl);
- if (md->state.boss)
- idb_put(bossid_db, bl->id, bl);
- }
+ if( md->state.boss )
+ idb_put(bossid_db, bl->id, bl);
+ }
- if (bl->type & BL_REGEN)
- idb_put(regen_db, bl->id, bl);
+ if( bl->type & BL_REGEN )
+ idb_put(regen_db, bl->id, bl);
- idb_put(id_db,bl->id,bl);
+ idb_put(id_db,bl->id,bl);
}
/*==========================================
@@ -1576,202 +1590,211 @@ void map_addiddb(struct block_list *bl)
*------------------------------------------*/
void map_deliddb(struct block_list *bl)
{
- nullpo_retv(bl);
+ nullpo_retv(bl);
- if (bl->type == BL_PC) {
- TBL_PC *sd = (TBL_PC *)bl;
- idb_remove(pc_db,sd->bl.id);
- idb_remove(charid_db,sd->status.char_id);
- } else if (bl->type == BL_MOB) {
- idb_remove(mobid_db,bl->id);
- idb_remove(bossid_db,bl->id);
- }
+ if( bl->type == BL_PC )
+ {
+ TBL_PC* sd = (TBL_PC*)bl;
+ idb_remove(pc_db,sd->bl.id);
+ idb_remove(charid_db,sd->status.char_id);
+ }
+ else if( bl->type == BL_MOB )
+ {
+ idb_remove(mobid_db,bl->id);
+ idb_remove(bossid_db,bl->id);
+ }
- if (bl->type & BL_REGEN)
- idb_remove(regen_db,bl->id);
+ if( bl->type & BL_REGEN )
+ idb_remove(regen_db,bl->id);
- idb_remove(id_db,bl->id);
+ idb_remove(id_db,bl->id);
}
/*==========================================
* Standard call when a player connection is closed.
*------------------------------------------*/
-int map_quit(struct map_session_data *sd)
-{
- int i;
-
- if (!sd->state.active) { //Removing a player that is not active.
- struct auth_node *node = chrif_search(sd->status.account_id);
- if (node && node->char_id == sd->status.char_id &&
- node->state != ST_LOGOUT)
- //Except when logging out, clear the auth-connect data immediately.
- chrif_auth_delete(node->account_id, node->char_id, node->state);
- //Non-active players should not have loaded any data yet (or it was cleared already) so no additional cleanups are needed.
- return 0;
- }
-
- if (sd->npc_timer_id != INVALID_TIMER) //Cancel the event timer.
- npc_timerevent_quit(sd);
-
- if (sd->npc_id)
- npc_event_dequeue(sd);
-
- if (sd->bg_id)
- bg_team_leave(sd,1);
-
- pc_itemcd_do(sd,false);
-
- npc_script_event(sd, NPCE_LOGOUT);
-
- //Unit_free handles clearing the player related data,
- //map_quit handles extra specific data which is related to quitting normally
- //(changing map-servers invokes unit_free but bypasses map_quit)
- if (sd->sc.count) {
- //Status that are not saved...
- status_change_end(&sd->bl, SC_BOSSMAPINFO, INVALID_TIMER);
- status_change_end(&sd->bl, SC_AUTOTRADE, INVALID_TIMER);
- status_change_end(&sd->bl, SC_SPURT, INVALID_TIMER);
- status_change_end(&sd->bl, SC_BERSERK, INVALID_TIMER);
- status_change_end(&sd->bl, SC__BLOODYLUST, INVALID_TIMER);
- status_change_end(&sd->bl, SC_TRICKDEAD, INVALID_TIMER);
- status_change_end(&sd->bl, SC_LEADERSHIP, INVALID_TIMER);
- status_change_end(&sd->bl, SC_GLORYWOUNDS, INVALID_TIMER);
- status_change_end(&sd->bl, SC_SOULCOLD, INVALID_TIMER);
- status_change_end(&sd->bl, SC_HAWKEYES, INVALID_TIMER);
- if (sd->sc.data[SC_ENDURE] && sd->sc.data[SC_ENDURE]->val4)
- status_change_end(&sd->bl, SC_ENDURE, INVALID_TIMER); //No need to save infinite endure.
- status_change_end(&sd->bl, SC_WEIGHT50, INVALID_TIMER);
- status_change_end(&sd->bl, SC_WEIGHT90, INVALID_TIMER);
+int map_quit(struct map_session_data *sd) {
+ int i;
+
+ if(!sd->state.active) { //Removing a player that is not active.
+ struct auth_node *node = chrif_search(sd->status.account_id);
+ if (node && node->char_id == sd->status.char_id &&
+ node->state != ST_LOGOUT)
+ //Except when logging out, clear the auth-connect data immediately.
+ chrif_auth_delete(node->account_id, node->char_id, node->state);
+ //Non-active players should not have loaded any data yet (or it was cleared already) so no additional cleanups are needed.
+ return 0;
+ }
+
+ if (sd->npc_timer_id != INVALID_TIMER) //Cancel the event timer.
+ npc_timerevent_quit(sd);
+
+ if (sd->npc_id)
+ npc_event_dequeue(sd);
+
+ if( sd->bg_id )
+ bg_team_leave(sd,1);
+
+ pc_itemcd_do(sd,false);
+
+ npc_script_event(sd, NPCE_LOGOUT);
+
+ //Unit_free handles clearing the player related data,
+ //map_quit handles extra specific data which is related to quitting normally
+ //(changing map-servers invokes unit_free but bypasses map_quit)
+ if( sd->sc.count ) {
+ //Status that are not saved...
+ status_change_end(&sd->bl, SC_BOSSMAPINFO, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_AUTOTRADE, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_SPURT, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_BERSERK, INVALID_TIMER);
+ status_change_end(&sd->bl, SC__BLOODYLUST, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_TRICKDEAD, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_LEADERSHIP, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_GLORYWOUNDS, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_SOULCOLD, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_HAWKEYES, INVALID_TIMER);
+ if(sd->sc.data[SC_ENDURE] && sd->sc.data[SC_ENDURE]->val4)
+ status_change_end(&sd->bl, SC_ENDURE, INVALID_TIMER); //No need to save infinite endure.
+ status_change_end(&sd->bl, SC_WEIGHT50, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_WEIGHT90, INVALID_TIMER);
status_change_end(&sd->bl, SC_SATURDAYNIGHTFEVER, INVALID_TIMER);
- status_change_end(&sd->bl, SC_KYOUGAKU, INVALID_TIMER);
- if (battle_config.debuff_on_logout&1) {
- status_change_end(&sd->bl, SC_ORCISH, INVALID_TIMER);
- status_change_end(&sd->bl, SC_STRIPWEAPON, INVALID_TIMER);
- status_change_end(&sd->bl, SC_STRIPARMOR, INVALID_TIMER);
- status_change_end(&sd->bl, SC_STRIPSHIELD, INVALID_TIMER);
- status_change_end(&sd->bl, SC_STRIPHELM, INVALID_TIMER);
- status_change_end(&sd->bl, SC_EXTREMITYFIST, INVALID_TIMER);
- status_change_end(&sd->bl, SC_EXPLOSIONSPIRITS, INVALID_TIMER);
- if (sd->sc.data[SC_REGENERATION] && sd->sc.data[SC_REGENERATION]->val4)
- status_change_end(&sd->bl, SC_REGENERATION, INVALID_TIMER);
- //TO-DO Probably there are way more NPC_type negative status that are removed
- status_change_end(&sd->bl, SC_CHANGEUNDEAD, INVALID_TIMER);
- // Both these statuses are removed on logout. [L0ne_W0lf]
- status_change_end(&sd->bl, SC_SLOWCAST, INVALID_TIMER);
- status_change_end(&sd->bl, SC_CRITICALWOUND, INVALID_TIMER);
- }
- if (battle_config.debuff_on_logout&2) {
- status_change_end(&sd->bl, SC_MAXIMIZEPOWER, INVALID_TIMER);
- status_change_end(&sd->bl, SC_MAXOVERTHRUST, INVALID_TIMER);
- status_change_end(&sd->bl, SC_STEELBODY, INVALID_TIMER);
- status_change_end(&sd->bl, SC_PRESERVE, INVALID_TIMER);
- status_change_end(&sd->bl, SC_KAAHI, INVALID_TIMER);
- status_change_end(&sd->bl, SC_SPIRIT, INVALID_TIMER);
- }
- }
-
- for (i = 0; i < EQI_MAX; i++) {
- if (sd->equip_index[ i ] >= 0)
- if (!pc_isequip(sd , sd->equip_index[ i ]))
- pc_unequipitem(sd , sd->equip_index[ i ] , 2);
- }
-
- // Return loot to owner
- if (sd->pd) pet_lootitem_drop(sd->pd, sd);
-
- if (sd->state.storage_flag == 1) sd->state.storage_flag = 0; // No need to Double Save Storage on Quit.
-
- if (sd->ed) {
- elemental_clean_effect(sd->ed);
- unit_remove_map(&sd->ed->bl,CLR_TELEPORT);
- }
-
- unit_remove_map_pc(sd,CLR_TELEPORT);
-
- if (map[sd->bl.m].instance_id) {
- // Avoid map conflicts and warnings on next login
- int m;
- struct point *pt;
- if (map[sd->bl.m].save.map)
- pt = &map[sd->bl.m].save;
- else
- pt = &sd->status.save_point;
-
- if ((m=map_mapindex2mapid(pt->map)) >= 0) {
- sd->bl.m = m;
- sd->bl.x = pt->x;
- sd->bl.y = pt->y;
- sd->mapindex = pt->map;
- }
- }
-
- party_booking_delete(sd); // Party Booking [Spiria]
- pc_makesavestatus(sd);
- pc_clean_skilltree(sd);
- chrif_save(sd,1);
- unit_free_pc(sd);
- return 0;
+ status_change_end(&sd->bl, SC_KYOUGAKU, INVALID_TIMER);
+ if (battle_config.debuff_on_logout&1) {
+ status_change_end(&sd->bl, SC_ORCISH, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_STRIPWEAPON, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_STRIPARMOR, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_STRIPSHIELD, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_STRIPHELM, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_EXTREMITYFIST, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_EXPLOSIONSPIRITS, INVALID_TIMER);
+ if(sd->sc.data[SC_REGENERATION] && sd->sc.data[SC_REGENERATION]->val4)
+ status_change_end(&sd->bl, SC_REGENERATION, INVALID_TIMER);
+ //TO-DO Probably there are way more NPC_type negative status that are removed
+ status_change_end(&sd->bl, SC_CHANGEUNDEAD, INVALID_TIMER);
+ // Both these statuses are removed on logout. [L0ne_W0lf]
+ status_change_end(&sd->bl, SC_SLOWCAST, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_CRITICALWOUND, INVALID_TIMER);
+ }
+ if (battle_config.debuff_on_logout&2) {
+ status_change_end(&sd->bl, SC_MAXIMIZEPOWER, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_MAXOVERTHRUST, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_STEELBODY, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_PRESERVE, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_KAAHI, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_SPIRIT, INVALID_TIMER);
+ }
+ }
+
+ for( i = 0; i < EQI_MAX; i++ ) {
+ if( sd->equip_index[ i ] >= 0 )
+ if( !pc_isequip( sd , sd->equip_index[ i ] ) )
+ pc_unequipitem( sd , sd->equip_index[ i ] , 2 );
+ }
+
+ // Return loot to owner
+ if( sd->pd ) pet_lootitem_drop(sd->pd, sd);
+
+ if( sd->state.storage_flag == 1 ) sd->state.storage_flag = 0; // No need to Double Save Storage on Quit.
+
+ if( sd->ed ) {
+ elemental_clean_effect(sd->ed);
+ unit_remove_map(&sd->ed->bl,CLR_TELEPORT);
+ }
+
+ unit_remove_map_pc(sd,CLR_TELEPORT);
+
+ if( map[sd->bl.m].instance_id )
+ { // Avoid map conflicts and warnings on next login
+ int m;
+ struct point *pt;
+ if( map[sd->bl.m].save.map )
+ pt = &map[sd->bl.m].save;
+ else
+ pt = &sd->status.save_point;
+
+ if( (m=map_mapindex2mapid(pt->map)) >= 0 )
+ {
+ sd->bl.m = m;
+ sd->bl.x = pt->x;
+ sd->bl.y = pt->y;
+ sd->mapindex = pt->map;
+ }
+ }
+
+ party_booking_delete(sd); // Party Booking [Spiria]
+ pc_makesavestatus(sd);
+ pc_clean_skilltree(sd);
+ chrif_save(sd,1);
+ unit_free_pc(sd);
+ return 0;
}
/*==========================================
* Lookup, id to session (player,mob,npc,homon,merc..)
*------------------------------------------*/
-struct map_session_data *map_id2sd(int id) {
- if (id <= 0) return NULL;
- return (struct map_session_data *)idb_get(pc_db,id);
+struct map_session_data * map_id2sd(int id)
+{
+ if (id <= 0) return NULL;
+ return (struct map_session_data*)idb_get(pc_db,id);
}
-struct mob_data *map_id2md(int id) {
- if (id <= 0) return NULL;
- return (struct mob_data *)idb_get(mobid_db,id);
+struct mob_data * map_id2md(int id)
+{
+ if (id <= 0) return NULL;
+ return (struct mob_data*)idb_get(mobid_db,id);
}
-struct npc_data *map_id2nd(int id) {
- // just a id2bl lookup because there's no npc_db
- struct block_list *bl = map_id2bl(id);
+struct npc_data * map_id2nd(int id)
+{// just a id2bl lookup because there's no npc_db
+ struct block_list* bl = map_id2bl(id);
- return BL_CAST(BL_NPC, bl);
+ return BL_CAST(BL_NPC, bl);
}
-struct homun_data *map_id2hd(int id) {
- struct block_list *bl = map_id2bl(id);
+struct homun_data* map_id2hd(int id)
+{
+ struct block_list* bl = map_id2bl(id);
- return BL_CAST(BL_HOM, bl);
+ return BL_CAST(BL_HOM, bl);
}
-struct mercenary_data *map_id2mc(int id) {
- struct block_list *bl = map_id2bl(id);
+struct mercenary_data* map_id2mc(int id)
+{
+ struct block_list* bl = map_id2bl(id);
- return BL_CAST(BL_MER, bl);
+ return BL_CAST(BL_MER, bl);
}
-struct chat_data *map_id2cd(int id) {
- struct block_list *bl = map_id2bl(id);
+struct chat_data* map_id2cd(int id)
+{
+ struct block_list* bl = map_id2bl(id);
- return BL_CAST(BL_CHAT, bl);
+ return BL_CAST(BL_CHAT, bl);
}
/// Returns the nick of the target charid or NULL if unknown (requests the nick to the char server).
-const char *map_charid2nick(int charid)
+const char* map_charid2nick(int charid)
{
- struct charid2nick *p;
- struct map_session_data *sd;
+ struct charid2nick *p;
+ struct map_session_data* sd;
- sd = map_charid2sd(charid);
- if (sd)
- return sd->status.name;// character is online, return it's name
+ sd = map_charid2sd(charid);
+ if( sd )
+ return sd->status.name;// character is online, return it's name
- p = idb_ensure(nick_db, charid, create_charid2nick);
- if (*p->nick)
- return p->nick;// name in nick_db
+ p = idb_ensure(nick_db, charid, create_charid2nick);
+ if( *p->nick )
+ return p->nick;// name in nick_db
- chrif_searchcharid(charid);// request the name
- return NULL;
+ chrif_searchcharid(charid);// request the name
+ return NULL;
}
/// Returns the struct map_session_data of the charid or NULL if the char is not online.
-struct map_session_data *map_charid2sd(int charid) {
- return (struct map_session_data *)idb_get(charid_db, charid);
+struct map_session_data* map_charid2sd(int charid)
+{
+ return (struct map_session_data*)idb_get(charid_db, charid);
}
/*==========================================
@@ -1779,202 +1802,216 @@ struct map_session_data *map_charid2sd(int charid) {
* (without sensitive case if necessary)
* return map_session_data pointer or NULL
*------------------------------------------*/
-struct map_session_data *map_nick2sd(const char *nick) {
- struct map_session_data *sd;
- struct map_session_data *found_sd;
- struct s_mapiterator *iter;
- size_t nicklen;
- int qty = 0;
-
- if (nick == NULL)
- return NULL;
-
- nicklen = strlen(nick);
- iter = mapit_getallusers();
-
- found_sd = NULL;
- for (sd = (TBL_PC *)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC *)mapit_next(iter)) {
- if (battle_config.partial_name_scan) {
- // partial name search
- if (strnicmp(sd->status.name, nick, nicklen) == 0) {
- found_sd = sd;
-
- if (strcmp(sd->status.name, nick) == 0) {
- // Perfect Match
- qty = 1;
- break;
- }
-
- qty++;
- }
- } else if (strcasecmp(sd->status.name, nick) == 0) {
- // exact search only
- found_sd = sd;
- break;
- }
- }
- mapit_free(iter);
-
- if (battle_config.partial_name_scan && qty != 1)
- found_sd = NULL;
-
- return found_sd;
+struct map_session_data * map_nick2sd(const char *nick)
+{
+ struct map_session_data* sd;
+ struct map_session_data* found_sd;
+ struct s_mapiterator* iter;
+ size_t nicklen;
+ int qty = 0;
+
+ if( nick == NULL )
+ return NULL;
+
+ nicklen = strlen(nick);
+ iter = mapit_getallusers();
+
+ found_sd = NULL;
+ for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
+ {
+ if( battle_config.partial_name_scan )
+ {// partial name search
+ if( strnicmp(sd->status.name, nick, nicklen) == 0 )
+ {
+ found_sd = sd;
+
+ if( strcmp(sd->status.name, nick) == 0 )
+ {// Perfect Match
+ qty = 1;
+ break;
+ }
+
+ qty++;
+ }
+ }
+ else if( strcasecmp(sd->status.name, nick) == 0 )
+ {// exact search only
+ found_sd = sd;
+ break;
+ }
+ }
+ mapit_free(iter);
+
+ if( battle_config.partial_name_scan && qty != 1 )
+ found_sd = NULL;
+
+ return found_sd;
}
/*==========================================
* Looksup id_db DBMap and returns BL pointer of 'id' or NULL if not found
*------------------------------------------*/
-struct block_list *map_id2bl(int id) {
- return (struct block_list *)idb_get(id_db,id);
+struct block_list * map_id2bl(int id) {
+ return (struct block_list*)idb_get(id_db,id);
}
/**
* Same as map_id2bl except it only checks for its existence
**/
-bool map_blid_exists(int id)
-{
- return (idb_exists(id_db,id));
+bool map_blid_exists( int id ) {
+ return (idb_exists(id_db,id));
}
/*==========================================
* Convext Mirror
*------------------------------------------*/
-struct mob_data *map_getmob_boss(int m) {
- DBIterator *iter;
- struct mob_data *md = NULL;
- bool found = false;
+struct mob_data * map_getmob_boss(int m)
+{
+ DBIterator* iter;
+ struct mob_data *md = NULL;
+ bool found = false;
- iter = db_iterator(bossid_db);
- for (md = (struct mob_data *)dbi_first(iter); dbi_exists(iter); md = (struct mob_data *)dbi_next(iter)) {
- if (md->bl.m == m) {
- found = true;
- break;
- }
- }
- dbi_destroy(iter);
+ iter = db_iterator(bossid_db);
+ for( md = (struct mob_data*)dbi_first(iter); dbi_exists(iter); md = (struct mob_data*)dbi_next(iter) )
+ {
+ if( md->bl.m == m )
+ {
+ found = true;
+ break;
+ }
+ }
+ dbi_destroy(iter);
- return (found)? md : NULL;
+ return (found)? md : NULL;
}
-struct mob_data *map_id2boss(int id) {
- if (id <= 0) return NULL;
- return (struct mob_data *)idb_get(bossid_db,id);
+struct mob_data * map_id2boss(int id)
+{
+ if (id <= 0) return NULL;
+ return (struct mob_data*)idb_get(bossid_db,id);
}
/// Applies func to all the players in the db.
/// Stops iterating if func returns -1.
-void map_foreachpc(int (*func)(struct map_session_data *sd, va_list args), ...)
+void map_foreachpc(int (*func)(struct map_session_data* sd, va_list args), ...)
{
- DBIterator *iter;
- struct map_session_data *sd;
+ DBIterator* iter;
+ struct map_session_data* sd;
- iter = db_iterator(pc_db);
- for (sd = dbi_first(iter); dbi_exists(iter); sd = dbi_next(iter)) {
- va_list args;
- int ret;
+ iter = db_iterator(pc_db);
+ for( sd = dbi_first(iter); dbi_exists(iter); sd = dbi_next(iter) )
+ {
+ va_list args;
+ int ret;
- va_start(args, func);
- ret = func(sd, args);
- va_end(args);
- if (ret == -1)
- break;// stop iterating
- }
- dbi_destroy(iter);
+ va_start(args, func);
+ ret = func(sd, args);
+ va_end(args);
+ if( ret == -1 )
+ break;// stop iterating
+ }
+ dbi_destroy(iter);
}
/// Applies func to all the mobs in the db.
/// Stops iterating if func returns -1.
-void map_foreachmob(int (*func)(struct mob_data *md, va_list args), ...)
+void map_foreachmob(int (*func)(struct mob_data* md, va_list args), ...)
{
- DBIterator *iter;
- struct mob_data *md;
+ DBIterator* iter;
+ struct mob_data* md;
- iter = db_iterator(mobid_db);
- for (md = (struct mob_data *)dbi_first(iter); dbi_exists(iter); md = (struct mob_data *)dbi_next(iter)) {
- va_list args;
- int ret;
+ iter = db_iterator(mobid_db);
+ for( md = (struct mob_data*)dbi_first(iter); dbi_exists(iter); md = (struct mob_data*)dbi_next(iter) )
+ {
+ va_list args;
+ int ret;
- va_start(args, func);
- ret = func(md, args);
- va_end(args);
- if (ret == -1)
- break;// stop iterating
- }
- dbi_destroy(iter);
+ va_start(args, func);
+ ret = func(md, args);
+ va_end(args);
+ if( ret == -1 )
+ break;// stop iterating
+ }
+ dbi_destroy(iter);
}
/// Applies func to all the npcs in the db.
/// Stops iterating if func returns -1.
-void map_foreachnpc(int (*func)(struct npc_data *nd, va_list args), ...)
-{
- DBIterator *iter;
- struct block_list *bl;
-
- iter = db_iterator(id_db);
- for (bl = (struct block_list *)dbi_first(iter); dbi_exists(iter); bl = (struct block_list *)dbi_next(iter)) {
- if (bl->type == BL_NPC) {
- struct npc_data *nd = (struct npc_data *)bl;
- va_list args;
- int ret;
-
- va_start(args, func);
- ret = func(nd, args);
- va_end(args);
- if (ret == -1)
- break;// stop iterating
- }
- }
- dbi_destroy(iter);
+void map_foreachnpc(int (*func)(struct npc_data* nd, va_list args), ...)
+{
+ DBIterator* iter;
+ struct block_list* bl;
+
+ iter = db_iterator(id_db);
+ for( bl = (struct block_list*)dbi_first(iter); dbi_exists(iter); bl = (struct block_list*)dbi_next(iter) )
+ {
+ if( bl->type == BL_NPC )
+ {
+ struct npc_data* nd = (struct npc_data*)bl;
+ va_list args;
+ int ret;
+
+ va_start(args, func);
+ ret = func(nd, args);
+ va_end(args);
+ if( ret == -1 )
+ break;// stop iterating
+ }
+ }
+ dbi_destroy(iter);
}
/// Applies func to everything in the db.
/// Stops iteratin gif func returns -1.
-void map_foreachregen(int (*func)(struct block_list *bl, va_list args), ...)
+void map_foreachregen(int (*func)(struct block_list* bl, va_list args), ...)
{
- DBIterator *iter;
- struct block_list *bl;
+ DBIterator* iter;
+ struct block_list* bl;
- iter = db_iterator(regen_db);
- for (bl = (struct block_list *)dbi_first(iter); dbi_exists(iter); bl = (struct block_list *)dbi_next(iter)) {
- va_list args;
- int ret;
+ iter = db_iterator(regen_db);
+ for( bl = (struct block_list*)dbi_first(iter); dbi_exists(iter); bl = (struct block_list*)dbi_next(iter) )
+ {
+ va_list args;
+ int ret;
- va_start(args, func);
- ret = func(bl, args);
- va_end(args);
- if (ret == -1)
- break;// stop iterating
- }
- dbi_destroy(iter);
+ va_start(args, func);
+ ret = func(bl, args);
+ va_end(args);
+ if( ret == -1 )
+ break;// stop iterating
+ }
+ dbi_destroy(iter);
}
/// Applies func to everything in the db.
/// Stops iterating if func returns -1.
-void map_foreachiddb(int (*func)(struct block_list *bl, va_list args), ...)
+void map_foreachiddb(int (*func)(struct block_list* bl, va_list args), ...)
{
- DBIterator *iter;
- struct block_list *bl;
+ DBIterator* iter;
+ struct block_list* bl;
- iter = db_iterator(id_db);
- for (bl = (struct block_list *)dbi_first(iter); dbi_exists(iter); bl = (struct block_list *)dbi_next(iter)) {
- va_list args;
- int ret;
+ iter = db_iterator(id_db);
+ for( bl = (struct block_list*)dbi_first(iter); dbi_exists(iter); bl = (struct block_list*)dbi_next(iter) )
+ {
+ va_list args;
+ int ret;
- va_start(args, func);
- ret = func(bl, args);
- va_end(args);
- if (ret == -1)
- break;// stop iterating
- }
- dbi_destroy(iter);
+ va_start(args, func);
+ ret = func(bl, args);
+ va_end(args);
+ if( ret == -1 )
+ break;// stop iterating
+ }
+ dbi_destroy(iter);
}
/// Iterator.
/// Can filter by bl type.
-struct s_mapiterator {
- enum e_mapitflags flags;// flags for special behaviour
- enum bl_type types;// what bl types to return
- DBIterator *dbi;// database iterator
+struct s_mapiterator
+{
+ enum e_mapitflags flags;// flags for special behaviour
+ enum bl_type types;// what bl types to return
+ DBIterator* dbi;// database iterator
};
/// Returns true if the block_list matches the description in the iterator.
@@ -1983,9 +2020,9 @@ struct s_mapiterator {
/// @param _bl_ block_list
/// @return true if it matches
#define MAPIT_MATCHES(_mapit_,_bl_) \
- ( \
- ( (_bl_)->type & (_mapit_)->types /* type matches */ ) \
- )
+ ( \
+ ( (_bl_)->type & (_mapit_)->types /* type matches */ ) \
+ )
/// Allocates a new iterator.
/// Returns the new iterator.
@@ -1995,27 +2032,28 @@ struct s_mapiterator {
/// @param flags Flags of the iterator
/// @param type Target types
/// @return Iterator
-struct s_mapiterator *mapit_alloc(enum e_mapitflags flags, enum bl_type types) {
- struct s_mapiterator *mapit;
+struct s_mapiterator* mapit_alloc(enum e_mapitflags flags, enum bl_type types)
+{
+ struct s_mapiterator* mapit;
- CREATE(mapit, struct s_mapiterator, 1);
- mapit->flags = flags;
- mapit->types = types;
- if (types == BL_PC) mapit->dbi = db_iterator(pc_db);
- else if (types == BL_MOB) mapit->dbi = db_iterator(mobid_db);
- else mapit->dbi = db_iterator(id_db);
- return mapit;
+ CREATE(mapit, struct s_mapiterator, 1);
+ mapit->flags = flags;
+ mapit->types = types;
+ if( types == BL_PC ) mapit->dbi = db_iterator(pc_db);
+ else if( types == BL_MOB ) mapit->dbi = db_iterator(mobid_db);
+ else mapit->dbi = db_iterator(id_db);
+ return mapit;
}
/// Frees the iterator.
///
/// @param mapit Iterator
-void mapit_free(struct s_mapiterator *mapit)
+void mapit_free(struct s_mapiterator* mapit)
{
- nullpo_retv(mapit);
+ nullpo_retv(mapit);
- dbi_destroy(mapit->dbi);
- aFree(mapit);
+ dbi_destroy(mapit->dbi);
+ aFree(mapit);
}
/// Returns the first block_list that matches the description.
@@ -2023,16 +2061,18 @@ void mapit_free(struct s_mapiterator *mapit)
///
/// @param mapit Iterator
/// @return first block_list or NULL
-struct block_list *mapit_first(struct s_mapiterator *mapit) {
- struct block_list *bl;
+struct block_list* mapit_first(struct s_mapiterator* mapit)
+{
+ struct block_list* bl;
- nullpo_retr(NULL,mapit);
+ nullpo_retr(NULL,mapit);
- for (bl = (struct block_list *)dbi_first(mapit->dbi); bl != NULL; bl = (struct block_list *)dbi_next(mapit->dbi)) {
- if (MAPIT_MATCHES(mapit,bl))
- break;// found match
- }
- return bl;
+ for( bl = (struct block_list*)dbi_first(mapit->dbi); bl != NULL; bl = (struct block_list*)dbi_next(mapit->dbi) )
+ {
+ if( MAPIT_MATCHES(mapit,bl) )
+ break;// found match
+ }
+ return bl;
}
/// Returns the last block_list that matches the description.
@@ -2040,16 +2080,18 @@ struct block_list *mapit_first(struct s_mapiterator *mapit) {
///
/// @param mapit Iterator
/// @return last block_list or NULL
-struct block_list *mapit_last(struct s_mapiterator *mapit) {
- struct block_list *bl;
+struct block_list* mapit_last(struct s_mapiterator* mapit)
+{
+ struct block_list* bl;
- nullpo_retr(NULL,mapit);
+ nullpo_retr(NULL,mapit);
- for (bl = (struct block_list *)dbi_last(mapit->dbi); bl != NULL; bl = (struct block_list *)dbi_prev(mapit->dbi)) {
- if (MAPIT_MATCHES(mapit,bl))
- break;// found match
- }
- return bl;
+ for( bl = (struct block_list*)dbi_last(mapit->dbi); bl != NULL; bl = (struct block_list*)dbi_prev(mapit->dbi) )
+ {
+ if( MAPIT_MATCHES(mapit,bl) )
+ break;// found match
+ }
+ return bl;
}
/// Returns the next block_list that matches the description.
@@ -2057,20 +2099,22 @@ struct block_list *mapit_last(struct s_mapiterator *mapit) {
///
/// @param mapit Iterator
/// @return next block_list or NULL
-struct block_list *mapit_next(struct s_mapiterator *mapit) {
- struct block_list *bl;
+struct block_list* mapit_next(struct s_mapiterator* mapit)
+{
+ struct block_list* bl;
- nullpo_retr(NULL,mapit);
+ nullpo_retr(NULL,mapit);
- for (; ;) {
- bl = (struct block_list *)dbi_next(mapit->dbi);
- if (bl == NULL)
- break;// end
- if (MAPIT_MATCHES(mapit,bl))
- break;// found a match
- // try next
- }
- return bl;
+ for( ; ; )
+ {
+ bl = (struct block_list*)dbi_next(mapit->dbi);
+ if( bl == NULL )
+ break;// end
+ if( MAPIT_MATCHES(mapit,bl) )
+ break;// found a match
+ // try next
+ }
+ return bl;
}
/// Returns the previous block_list that matches the description.
@@ -2078,31 +2122,33 @@ struct block_list *mapit_next(struct s_mapiterator *mapit) {
///
/// @param mapit Iterator
/// @return previous block_list or NULL
-struct block_list *mapit_prev(struct s_mapiterator *mapit) {
- struct block_list *bl;
+struct block_list* mapit_prev(struct s_mapiterator* mapit)
+{
+ struct block_list* bl;
- nullpo_retr(NULL,mapit);
+ nullpo_retr(NULL,mapit);
- for (; ;) {
- bl = (struct block_list *)dbi_prev(mapit->dbi);
- if (bl == NULL)
- break;// end
- if (MAPIT_MATCHES(mapit,bl))
- break;// found a match
- // try prev
- }
- return bl;
+ for( ; ; )
+ {
+ bl = (struct block_list*)dbi_prev(mapit->dbi);
+ if( bl == NULL )
+ break;// end
+ if( MAPIT_MATCHES(mapit,bl) )
+ break;// found a match
+ // try prev
+ }
+ return bl;
}
/// Returns true if the current block_list exists in the database.
///
/// @param mapit Iterator
/// @return true if it exists
-bool mapit_exists(struct s_mapiterator *mapit)
+bool mapit_exists(struct s_mapiterator* mapit)
{
- nullpo_retr(false,mapit);
+ nullpo_retr(false,mapit);
- return dbi_exists(mapit->dbi);
+ return dbi_exists(mapit->dbi);
}
/*==========================================
@@ -2110,20 +2156,21 @@ bool mapit_exists(struct s_mapiterator *mapit)
*------------------------------------------*/
bool map_addnpc(int m,struct npc_data *nd)
{
- nullpo_ret(nd);
+ nullpo_ret(nd);
- if (m < 0 || m >= map_num)
- return false;
+ if( m < 0 || m >= map_num )
+ return false;
- if (map[m].npc_num == MAX_NPC_PER_MAP) {
- ShowWarning("too many NPCs in one map %s\n",map[m].name);
- return false;
- }
+ if( map[m].npc_num == MAX_NPC_PER_MAP )
+ {
+ ShowWarning("too many NPCs in one map %s\n",map[m].name);
+ return false;
+ }
- map[m].npc[map[m].npc_num]=nd;
- map[m].npc_num++;
- idb_put(id_db,nd->bl.id,nd);
- return true;
+ map[m].npc[map[m].npc_num]=nd;
+ map[m].npc_num++;
+ idb_put(id_db,nd->bl.id,nd);
+ return true;
}
/*=========================================
@@ -2133,107 +2180,110 @@ bool map_addnpc(int m,struct npc_data *nd)
// Returns the index of successful, or -1 if the list was full.
int map_addmobtolist(unsigned short m, struct spawn_data *spawn)
{
- size_t i;
- ARR_FIND(0, MAX_MOB_LIST_PER_MAP, i, map[m].moblist[i] == NULL);
- if (i < MAX_MOB_LIST_PER_MAP) {
- map[m].moblist[i] = spawn;
- return i;
- }
- return -1;
+ size_t i;
+ ARR_FIND( 0, MAX_MOB_LIST_PER_MAP, i, map[m].moblist[i] == NULL );
+ if( i < MAX_MOB_LIST_PER_MAP )
+ {
+ map[m].moblist[i] = spawn;
+ return i;
+ }
+ return -1;
}
void map_spawnmobs(int m)
{
- int i, k=0;
- if (map[m].mob_delete_timer != INVALID_TIMER) {
- //Mobs have not been removed yet [Skotlex]
- delete_timer(map[m].mob_delete_timer, map_removemobs_timer);
- map[m].mob_delete_timer = INVALID_TIMER;
- return;
- }
- for (i=0; i<MAX_MOB_LIST_PER_MAP; i++)
- if (map[m].moblist[i]!=NULL) {
- k+=map[m].moblist[i]->num;
- npc_parse_mob2(map[m].moblist[i]);
- }
-
- if (battle_config.etc_log && k > 0) {
- ShowStatus("Map %s: Spawned '"CL_WHITE"%d"CL_RESET"' mobs.\n",map[m].name, k);
- }
+ int i, k=0;
+ if (map[m].mob_delete_timer != INVALID_TIMER)
+ { //Mobs have not been removed yet [Skotlex]
+ delete_timer(map[m].mob_delete_timer, map_removemobs_timer);
+ map[m].mob_delete_timer = INVALID_TIMER;
+ return;
+ }
+ for(i=0; i<MAX_MOB_LIST_PER_MAP; i++)
+ if(map[m].moblist[i]!=NULL)
+ {
+ k+=map[m].moblist[i]->num;
+ npc_parse_mob2(map[m].moblist[i]);
+ }
+
+ if (battle_config.etc_log && k > 0)
+ {
+ ShowStatus("Map %s: Spawned '"CL_WHITE"%d"CL_RESET"' mobs.\n",map[m].name, k);
+ }
}
int map_removemobs_sub(struct block_list *bl, va_list ap)
{
- struct mob_data *md = (struct mob_data *)bl;
- nullpo_ret(md);
+ struct mob_data *md = (struct mob_data *)bl;
+ nullpo_ret(md);
- //When not to remove mob:
- // doesn't respawn and is not a slave
- if (!md->spawn && !md->master_id)
- return 0;
- // respawn data is not in cache
- if (md->spawn && !md->spawn->state.dynamic)
- return 0;
- // hasn't spawned yet
- if (md->spawn_timer != INVALID_TIMER)
- return 0;
- // is damaged and mob_remove_damaged is off
- if (!battle_config.mob_remove_damaged && md->status.hp < md->status.max_hp)
- return 0;
- // is a mvp
- if (md->db->mexp > 0)
- return 0;
+ //When not to remove mob:
+ // doesn't respawn and is not a slave
+ if( !md->spawn && !md->master_id )
+ return 0;
+ // respawn data is not in cache
+ if( md->spawn && !md->spawn->state.dynamic )
+ return 0;
+ // hasn't spawned yet
+ if( md->spawn_timer != INVALID_TIMER )
+ return 0;
+ // is damaged and mob_remove_damaged is off
+ if( !battle_config.mob_remove_damaged && md->status.hp < md->status.max_hp )
+ return 0;
+ // is a mvp
+ if( md->db->mexp > 0 )
+ return 0;
- unit_free(&md->bl,CLR_OUTSIGHT);
+ unit_free(&md->bl,CLR_OUTSIGHT);
- return 1;
+ return 1;
}
int map_removemobs_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- int count;
- const int m = id;
+ int count;
+ const int m = id;
- if (m < 0 || m >= MAX_MAP_PER_SERVER) {
- //Incorrect map id!
- ShowError("map_removemobs_timer error: timer %d points to invalid map %d\n",tid, m);
- return 0;
- }
- if (map[m].mob_delete_timer != tid) {
- //Incorrect timer call!
- ShowError("map_removemobs_timer mismatch: %d != %d (map %s)\n",map[m].mob_delete_timer, tid, map[m].name);
- return 0;
- }
- map[m].mob_delete_timer = INVALID_TIMER;
- if (map[m].users > 0) //Map not empty!
- return 1;
+ if (m < 0 || m >= MAX_MAP_PER_SERVER)
+ { //Incorrect map id!
+ ShowError("map_removemobs_timer error: timer %d points to invalid map %d\n",tid, m);
+ return 0;
+ }
+ if (map[m].mob_delete_timer != tid)
+ { //Incorrect timer call!
+ ShowError("map_removemobs_timer mismatch: %d != %d (map %s)\n",map[m].mob_delete_timer, tid, map[m].name);
+ return 0;
+ }
+ map[m].mob_delete_timer = INVALID_TIMER;
+ if (map[m].users > 0) //Map not empty!
+ return 1;
- count = map_foreachinmap(map_removemobs_sub, m, BL_MOB);
+ count = map_foreachinmap(map_removemobs_sub, m, BL_MOB);
- if (battle_config.etc_log && count > 0)
- ShowStatus("Map %s: Removed '"CL_WHITE"%d"CL_RESET"' mobs.\n",map[m].name, count);
+ if (battle_config.etc_log && count > 0)
+ ShowStatus("Map %s: Removed '"CL_WHITE"%d"CL_RESET"' mobs.\n",map[m].name, count);
- return 1;
+ return 1;
}
void map_removemobs(int m)
{
- if (map[m].mob_delete_timer != INVALID_TIMER) // should never happen
- return; //Mobs are already scheduled for removal
+ if (map[m].mob_delete_timer != INVALID_TIMER) // should never happen
+ return; //Mobs are already scheduled for removal
- map[m].mob_delete_timer = add_timer(gettick()+battle_config.mob_remove_delay, map_removemobs_timer, m, 0);
+ map[m].mob_delete_timer = add_timer(gettick()+battle_config.mob_remove_delay, map_removemobs_timer, m, 0);
}
/*==========================================
* Hookup, get map_id from map_name
*------------------------------------------*/
-int map_mapname2mapid(const char *name)
+int map_mapname2mapid(const char* name)
{
- unsigned short map_index;
- map_index = mapindex_name2id(name);
- if (!map_index)
- return -1;
- return map_mapindex2mapid(map_index);
+ unsigned short map_index;
+ map_index = mapindex_name2id(name);
+ if (!map_index)
+ return -1;
+ return map_mapindex2mapid(map_index);
}
/*==========================================
@@ -2241,30 +2291,30 @@ int map_mapname2mapid(const char *name)
*------------------------------------------*/
int map_mapindex2mapid(unsigned short mapindex)
{
- struct map_data *md=NULL;
+ struct map_data *md=NULL;
- if (!mapindex)
- return -1;
+ if (!mapindex)
+ return -1;
- md = (struct map_data *)uidb_get(map_db,(unsigned int)mapindex);
- if (md==NULL || md->cell==NULL)
- return -1;
- return md->m;
+ md = (struct map_data*)uidb_get(map_db,(unsigned int)mapindex);
+ if(md==NULL || md->cell==NULL)
+ return -1;
+ return md->m;
}
/*==========================================
* Switching Ip, port ? (like changing map_server) get ip/port from map_name
*------------------------------------------*/
-int map_mapname2ipport(unsigned short name, uint32 *ip, uint16 *port)
+int map_mapname2ipport(unsigned short name, uint32* ip, uint16* port)
{
- struct map_data_other_server *mdos=NULL;
+ struct map_data_other_server *mdos=NULL;
- mdos = (struct map_data_other_server *)uidb_get(map_db,(unsigned int)name);
- if (mdos==NULL || mdos->cell) //If gat isn't null, this is a local map.
- return -1;
- *ip=mdos->ip;
- *port=mdos->port;
- return 0;
+ mdos = (struct map_data_other_server*)uidb_get(map_db,(unsigned int)name);
+ if(mdos==NULL || mdos->cell) //If gat isn't null, this is a local map.
+ return -1;
+ *ip=mdos->ip;
+ *port=mdos->port;
+ return 0;
}
/*==========================================
@@ -2272,76 +2322,64 @@ int map_mapname2ipport(unsigned short name, uint32 *ip, uint16 *port)
*------------------------------------------*/
int map_check_dir(int s_dir,int t_dir)
{
- if (s_dir == t_dir)
- return 0;
- switch (s_dir) {
- case 0:
- if (t_dir == 7 || t_dir == 1 || t_dir == 0) return 0;
- break;
- case 1:
- if (t_dir == 0 || t_dir == 2 || t_dir == 1) return 0;
- break;
- case 2:
- if (t_dir == 1 || t_dir == 3 || t_dir == 2) return 0;
- break;
- case 3:
- if (t_dir == 2 || t_dir == 4 || t_dir == 3) return 0;
- break;
- case 4:
- if (t_dir == 3 || t_dir == 5 || t_dir == 4) return 0;
- break;
- case 5:
- if (t_dir == 4 || t_dir == 6 || t_dir == 5) return 0;
- break;
- case 6:
- if (t_dir == 5 || t_dir == 7 || t_dir == 6) return 0;
- break;
- case 7:
- if (t_dir == 6 || t_dir == 0 || t_dir == 7) return 0;
- break;
- }
- return 1;
+ if(s_dir == t_dir)
+ return 0;
+ switch(s_dir) {
+ case 0: if(t_dir == 7 || t_dir == 1 || t_dir == 0) return 0; break;
+ case 1: if(t_dir == 0 || t_dir == 2 || t_dir == 1) return 0; break;
+ case 2: if(t_dir == 1 || t_dir == 3 || t_dir == 2) return 0; break;
+ case 3: if(t_dir == 2 || t_dir == 4 || t_dir == 3) return 0; break;
+ case 4: if(t_dir == 3 || t_dir == 5 || t_dir == 4) return 0; break;
+ case 5: if(t_dir == 4 || t_dir == 6 || t_dir == 5) return 0; break;
+ case 6: if(t_dir == 5 || t_dir == 7 || t_dir == 6) return 0; break;
+ case 7: if(t_dir == 6 || t_dir == 0 || t_dir == 7) return 0; break;
+ }
+ return 1;
}
/*==========================================
* Returns the direction of the given cell, relative to 'src'
*------------------------------------------*/
-uint8 map_calc_dir(struct block_list *src, int x, int y)
-{
- unsigned char dir = 0;
- int dx, dy;
-
- nullpo_ret(src);
-
- dx = x-src->x;
- dy = y-src->y;
- if (dx == 0 && dy == 0) {
- // both are standing on the same spot
- //dir = 6; // aegis-style, makes knockback default to the left
- dir = unit_getdir(src); // athena-style, makes knockback default to behind 'src'
- } else if (dx >= 0 && dy >=0) {
- // upper-right
- if (dx*2 <= dy) dir = 0; // up
- else if (dx > dy*2) dir = 6; // right
- else dir = 7; // up-right
- } else if (dx >= 0 && dy <= 0) {
- // lower-right
- if (dx*2 <= -dy) dir = 4; // down
- else if (dx > -dy*2) dir = 6; // right
- else dir = 5; // down-right
- } else if (dx <= 0 && dy <= 0) {
- // lower-left
- if (dx*2 >= dy) dir = 4; // down
- else if (dx < dy*2) dir = 2; // left
- else dir = 3; // down-left
- } else {
- // upper-left
- if (-dx*2 <= dy) dir = 0; // up
- else if (-dx > dy*2) dir = 2; // left
- else dir = 1; // up-left
-
- }
- return dir;
+uint8 map_calc_dir(struct block_list* src, int x, int y)
+{
+ unsigned char dir = 0;
+ int dx, dy;
+
+ nullpo_ret(src);
+
+ dx = x-src->x;
+ dy = y-src->y;
+ if( dx == 0 && dy == 0 )
+ { // both are standing on the same spot
+ //dir = 6; // aegis-style, makes knockback default to the left
+ dir = unit_getdir(src); // athena-style, makes knockback default to behind 'src'
+ }
+ else if( dx >= 0 && dy >=0 )
+ { // upper-right
+ if( dx*2 <= dy ) dir = 0; // up
+ else if( dx > dy*2 ) dir = 6; // right
+ else dir = 7; // up-right
+ }
+ else if( dx >= 0 && dy <= 0 )
+ { // lower-right
+ if( dx*2 <= -dy ) dir = 4; // down
+ else if( dx > -dy*2 ) dir = 6; // right
+ else dir = 5; // down-right
+ }
+ else if( dx <= 0 && dy <= 0 )
+ { // lower-left
+ if( dx*2 >= dy ) dir = 4; // down
+ else if( dx < dy*2 ) dir = 2; // left
+ else dir = 3; // down-left
+ }
+ else
+ { // upper-left
+ if( -dx*2 <= dy ) dir = 0; // up
+ else if( -dx > dy*2 ) dir = 2; // left
+ else dir = 1; // up-left
+
+ }
+ return dir;
}
/*==========================================
@@ -2350,92 +2388,64 @@ uint8 map_calc_dir(struct block_list *src, int x, int y)
*------------------------------------------*/
int map_random_dir(struct block_list *bl, short *x, short *y)
{
- short xi = *x-bl->x;
- short yi = *y-bl->y;
- short i=0, j;
- int dist2 = xi*xi + yi*yi;
- short dist = (short)sqrt((float)dist2);
- short segment;
-
- if (dist < 1) dist =1;
-
- do {
- j = 1 + 2*(rnd()%4); //Pick a random diagonal direction
- segment = 1+(rnd()%dist); //Pick a random interval from the whole vector in that direction
- xi = bl->x + segment*dirx[j];
- segment = (short)sqrt((float)(dist2 - segment*segment)); //The complement of the previously picked segment
- yi = bl->y + segment*diry[j];
- } while (
- (map_getcell(bl->m,xi,yi,CELL_CHKNOPASS) || !path_search(NULL,bl->m,bl->x,bl->y,xi,yi,1,CELL_CHKNOREACH))
- && (++i)<100);
-
- if (i < 100) {
- *x = xi;
- *y = yi;
- return 1;
- }
- return 0;
+ short xi = *x-bl->x;
+ short yi = *y-bl->y;
+ short i=0, j;
+ int dist2 = xi*xi + yi*yi;
+ short dist = (short)sqrt((float)dist2);
+ short segment;
+
+ if (dist < 1) dist =1;
+
+ do {
+ j = 1 + 2*(rnd()%4); //Pick a random diagonal direction
+ segment = 1+(rnd()%dist); //Pick a random interval from the whole vector in that direction
+ xi = bl->x + segment*dirx[j];
+ segment = (short)sqrt((float)(dist2 - segment*segment)); //The complement of the previously picked segment
+ yi = bl->y + segment*diry[j];
+ } while (
+ (map_getcell(bl->m,xi,yi,CELL_CHKNOPASS) || !path_search(NULL,bl->m,bl->x,bl->y,xi,yi,1,CELL_CHKNOREACH))
+ && (++i)<100 );
+
+ if (i < 100) {
+ *x = xi;
+ *y = yi;
+ return 1;
+ }
+ return 0;
}
// gat system
inline static struct mapcell map_gat2cell(int gat) {
- struct mapcell cell;
-
- memset(&cell,0,sizeof(struct mapcell));
-
- switch (gat) {
- case 0:
- cell.walkable = 1;
- cell.shootable = 1;
- cell.water = 0;
- break; // walkable ground
- case 1:
- cell.walkable = 0;
- cell.shootable = 0;
- cell.water = 0;
- break; // non-walkable ground
- case 2:
- cell.walkable = 1;
- cell.shootable = 1;
- cell.water = 0;
- break; // ???
- case 3:
- cell.walkable = 1;
- cell.shootable = 1;
- cell.water = 1;
- break; // walkable water
- case 4:
- cell.walkable = 1;
- cell.shootable = 1;
- cell.water = 0;
- break; // ???
- case 5:
- cell.walkable = 0;
- cell.shootable = 1;
- cell.water = 0;
- break; // gap (snipable)
- case 6:
- cell.walkable = 1;
- cell.shootable = 1;
- cell.water = 0;
- break; // ???
- default:
- ShowWarning("map_gat2cell: unrecognized gat type '%d'\n", gat);
- break;
- }
-
- return cell;
+ struct mapcell cell;
+
+ memset(&cell,0,sizeof(struct mapcell));
+
+ switch( gat ) {
+ case 0: cell.walkable = 1; cell.shootable = 1; cell.water = 0; break; // walkable ground
+ case 1: cell.walkable = 0; cell.shootable = 0; cell.water = 0; break; // non-walkable ground
+ case 2: cell.walkable = 1; cell.shootable = 1; cell.water = 0; break; // ???
+ case 3: cell.walkable = 1; cell.shootable = 1; cell.water = 1; break; // walkable water
+ case 4: cell.walkable = 1; cell.shootable = 1; cell.water = 0; break; // ???
+ case 5: cell.walkable = 0; cell.shootable = 1; cell.water = 0; break; // gap (snipable)
+ case 6: cell.walkable = 1; cell.shootable = 1; cell.water = 0; break; // ???
+ default:
+ ShowWarning("map_gat2cell: unrecognized gat type '%d'\n", gat);
+ break;
+ }
+
+ return cell;
}
static int map_cell2gat(struct mapcell cell)
{
- if (cell.walkable == 1 && cell.shootable == 1 && cell.water == 0) return 0;
- if (cell.walkable == 0 && cell.shootable == 0 && cell.water == 0) return 1;
- if (cell.walkable == 1 && cell.shootable == 1 && cell.water == 1) return 3;
- if (cell.walkable == 0 && cell.shootable == 1 && cell.water == 0) return 5;
+ if( cell.walkable == 1 && cell.shootable == 1 && cell.water == 0 ) return 0;
+ if( cell.walkable == 0 && cell.shootable == 0 && cell.water == 0 ) return 1;
+ if( cell.walkable == 1 && cell.shootable == 1 && cell.water == 1 ) return 3;
+ if( cell.walkable == 0 && cell.shootable == 1 && cell.water == 0 ) return 5;
- ShowWarning("map_cell2gat: cell has no matching gat type\n");
- return 1; // default to 'wall'
+ ShowWarning("map_cell2gat: cell has no matching gat type\n");
+ return 1; // default to 'wall'
}
/*==========================================
@@ -2443,78 +2453,79 @@ static int map_cell2gat(struct mapcell cell)
*------------------------------------------*/
int map_getcell(int m,int x,int y,cell_chk cellchk)
{
- return (m < 0 || m >= MAX_MAP_PER_SERVER) ? 0 : map_getcellp(&map[m],x,y,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_chk cellchk)
+int map_getcellp(struct map_data* m,int x,int y,cell_chk cellchk)
{
- struct mapcell cell;
+ struct mapcell cell;
- nullpo_ret(m);
+ nullpo_ret(m);
- //NOTE: this intentionally overrides the last row and column
- if (x<0 || x>=m->xs-1 || y<0 || y>=m->ys-1)
- return(cellchk == CELL_CHKNOPASS);
+ //NOTE: this intentionally overrides the last row and column
+ if(x<0 || x>=m->xs-1 || y<0 || y>=m->ys-1)
+ return( cellchk == CELL_CHKNOPASS );
- cell = m->cell[x + y*m->xs];
+ cell = m->cell[x + y*m->xs];
- switch (cellchk) {
- // gat type retrieval
- case CELL_GETTYPE:
- return map_cell2gat(cell);
+ switch(cellchk)
+ {
+ // gat type retrieval
+ case CELL_GETTYPE:
+ return map_cell2gat(cell);
- // base gat type checks
- case CELL_CHKWALL:
- return (!cell.walkable && !cell.shootable);
+ // base gat type checks
+ case CELL_CHKWALL:
+ return (!cell.walkable && !cell.shootable);
- case CELL_CHKWATER:
- return (cell.water);
+ case CELL_CHKWATER:
+ return (cell.water);
- case CELL_CHKCLIFF:
- return (!cell.walkable && cell.shootable);
+ case CELL_CHKCLIFF:
+ return (!cell.walkable && cell.shootable);
- // base cell type checks
- case CELL_CHKNPC:
- return (cell.npc);
- case CELL_CHKBASILICA:
- return (cell.basilica);
- case CELL_CHKLANDPROTECTOR:
- return (cell.landprotector);
- case CELL_CHKNOVENDING:
- return (cell.novending);
- case CELL_CHKNOCHAT:
- return (cell.nochat);
- case CELL_CHKMAELSTROM:
- return (cell.maelstrom);
- case CELL_CHKICEWALL:
- return (cell.icewall);
+ // base cell type checks
+ case CELL_CHKNPC:
+ return (cell.npc);
+ case CELL_CHKBASILICA:
+ return (cell.basilica);
+ case CELL_CHKLANDPROTECTOR:
+ return (cell.landprotector);
+ case CELL_CHKNOVENDING:
+ return (cell.novending);
+ case CELL_CHKNOCHAT:
+ return (cell.nochat);
+ case CELL_CHKMAELSTROM:
+ return (cell.maelstrom);
+ case CELL_CHKICEWALL:
+ return (cell.icewall);
- // special checks
- case CELL_CHKPASS:
+ // special checks
+ case CELL_CHKPASS:
#ifdef CELL_NOSTACK
- if (cell.cell_bl >= battle_config.cell_stack_limit) return 0;
+ if (cell.cell_bl >= battle_config.cell_stack_limit) return 0;
#endif
- case CELL_CHKREACH:
- return (cell.walkable);
+ case CELL_CHKREACH:
+ return (cell.walkable);
- case CELL_CHKNOPASS:
+ case CELL_CHKNOPASS:
#ifdef CELL_NOSTACK
- if (cell.cell_bl >= battle_config.cell_stack_limit) return 1;
+ if (cell.cell_bl >= battle_config.cell_stack_limit) return 1;
#endif
- case CELL_CHKNOREACH:
- return (!cell.walkable);
+ case CELL_CHKNOREACH:
+ return (!cell.walkable);
- case CELL_CHKSTACK:
+ case CELL_CHKSTACK:
#ifdef CELL_NOSTACK
- return (cell.cell_bl >= battle_config.cell_stack_limit);
+ return (cell.cell_bl >= battle_config.cell_stack_limit);
#else
- return 0;
+ return 0;
#endif
- default:
- return 0;
- }
+ default:
+ return 0;
+ }
}
/*==========================================
@@ -2524,174 +2535,158 @@ int map_getcellp(struct map_data *m,int x,int y,cell_chk cellchk)
*------------------------------------------*/
void map_setcell(int m, int x, int y, cell_t cell, bool flag)
{
- int j;
-
- if (m < 0 || m >= map_num || x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys)
- return;
-
- j = x + y*map[m].xs;
-
- switch (cell) {
- case CELL_WALKABLE:
- map[m].cell[j].walkable = flag;
- break;
- case CELL_SHOOTABLE:
- map[m].cell[j].shootable = flag;
- break;
- case CELL_WATER:
- map[m].cell[j].water = flag;
- break;
-
- case CELL_NPC:
- map[m].cell[j].npc = flag;
- break;
- case CELL_BASILICA:
- map[m].cell[j].basilica = flag;
- break;
- case CELL_LANDPROTECTOR:
- map[m].cell[j].landprotector = flag;
- break;
- case CELL_NOVENDING:
- map[m].cell[j].novending = flag;
- break;
- case CELL_NOCHAT:
- map[m].cell[j].nochat = flag;
- break;
- case CELL_MAELSTROM:
- map[m].cell[j].maelstrom = flag;
- break;
- case CELL_ICEWALL:
- map[m].cell[j].icewall = flag;
- break;
- default:
- ShowWarning("map_setcell: invalid cell type '%d'\n", (int)cell);
- break;
- }
+ int j;
+
+ if( m < 0 || m >= map_num || x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys )
+ return;
+
+ j = x + y*map[m].xs;
+
+ switch( cell ) {
+ case CELL_WALKABLE: map[m].cell[j].walkable = flag; break;
+ case CELL_SHOOTABLE: map[m].cell[j].shootable = flag; break;
+ case CELL_WATER: map[m].cell[j].water = flag; break;
+
+ case CELL_NPC: map[m].cell[j].npc = flag; break;
+ case CELL_BASILICA: map[m].cell[j].basilica = flag; break;
+ case CELL_LANDPROTECTOR: map[m].cell[j].landprotector = flag; break;
+ case CELL_NOVENDING: map[m].cell[j].novending = flag; break;
+ case CELL_NOCHAT: map[m].cell[j].nochat = flag; break;
+ case CELL_MAELSTROM: map[m].cell[j].maelstrom = flag; break;
+ case CELL_ICEWALL: map[m].cell[j].icewall = flag; break;
+ default:
+ ShowWarning("map_setcell: invalid cell type '%d'\n", (int)cell);
+ break;
+ }
}
void map_setgatcell(int m, int x, int y, int gat)
{
- int j;
- struct mapcell cell;
+ int j;
+ struct mapcell cell;
- if (m < 0 || m >= map_num || x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys)
- return;
+ if( m < 0 || m >= map_num || x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys )
+ return;
- j = x + y*map[m].xs;
+ j = x + y*map[m].xs;
- cell = map_gat2cell(gat);
- map[m].cell[j].walkable = cell.walkable;
- map[m].cell[j].shootable = cell.shootable;
- map[m].cell[j].water = cell.water;
+ cell = map_gat2cell(gat);
+ map[m].cell[j].walkable = cell.walkable;
+ map[m].cell[j].shootable = cell.shootable;
+ map[m].cell[j].water = cell.water;
}
/*==========================================
* Invisible Walls
*------------------------------------------*/
-static DBMap *iwall_db;
+static DBMap* iwall_db;
void map_iwall_nextxy(int x, int y, int dir, int pos, int *x1, int *y1)
{
- if (dir == 0 || dir == 4)
- *x1 = x; // Keep X
- else if (dir > 0 && dir < 4)
- *x1 = x - pos; // Going left
- else
- *x1 = x + pos; // Going right
+ if( dir == 0 || dir == 4 )
+ *x1 = x; // Keep X
+ else if( dir > 0 && dir < 4 )
+ *x1 = x - pos; // Going left
+ else
+ *x1 = x + pos; // Going right
- if (dir == 2 || dir == 6)
- *y1 = y;
- else if (dir > 2 && dir < 6)
- *y1 = y - pos;
- else
- *y1 = y + pos;
+ if( dir == 2 || dir == 6 )
+ *y1 = y;
+ else if( dir > 2 && dir < 6 )
+ *y1 = y - pos;
+ else
+ *y1 = y + pos;
}
-bool map_iwall_set(int m, int x, int y, int size, int dir, bool shootable, const char *wall_name)
+bool map_iwall_set(int m, int x, int y, int size, int dir, bool shootable, const char* wall_name)
{
- struct iwall_data *iwall;
- int i, x1 = 0, y1 = 0;
+ struct iwall_data *iwall;
+ int i, x1 = 0, y1 = 0;
- if (size < 1 || !wall_name)
- return false;
+ if( size < 1 || !wall_name )
+ return false;
- if ((iwall = (struct iwall_data *)strdb_get(iwall_db, wall_name)) != NULL)
- return false; // Already Exists
+ if( (iwall = (struct iwall_data *)strdb_get(iwall_db, wall_name)) != NULL )
+ return false; // Already Exists
- if (map_getcell(m, x, y, CELL_CHKNOREACH))
- return false; // Starting cell problem
+ if( map_getcell(m, x, y, CELL_CHKNOREACH) )
+ return false; // Starting cell problem
- CREATE(iwall, struct iwall_data, 1);
- iwall->m = m;
- iwall->x = x;
- iwall->y = y;
- iwall->size = size;
- iwall->dir = dir;
- iwall->shootable = shootable;
- safestrncpy(iwall->wall_name, wall_name, sizeof(iwall->wall_name));
+ CREATE(iwall, struct iwall_data, 1);
+ iwall->m = m;
+ iwall->x = x;
+ iwall->y = y;
+ iwall->size = size;
+ iwall->dir = dir;
+ iwall->shootable = shootable;
+ safestrncpy(iwall->wall_name, wall_name, sizeof(iwall->wall_name));
- for (i = 0; i < size; i++) {
- map_iwall_nextxy(x, y, dir, i, &x1, &y1);
+ for( i = 0; i < size; i++ )
+ {
+ map_iwall_nextxy(x, y, dir, i, &x1, &y1);
- if (map_getcell(m, x1, y1, CELL_CHKNOREACH))
- break; // Collision
+ if( map_getcell(m, x1, y1, CELL_CHKNOREACH) )
+ break; // Collision
- map_setcell(m, x1, y1, CELL_WALKABLE, false);
- map_setcell(m, x1, y1, CELL_SHOOTABLE, shootable);
+ map_setcell(m, x1, y1, CELL_WALKABLE, false);
+ map_setcell(m, x1, y1, CELL_SHOOTABLE, shootable);
- clif_changemapcell(0, m, x1, y1, map_getcell(m, x1, y1, CELL_GETTYPE), ALL_SAMEMAP);
- }
+ clif_changemapcell(0, m, x1, y1, map_getcell(m, x1, y1, CELL_GETTYPE), ALL_SAMEMAP);
+ }
- iwall->size = i;
+ iwall->size = i;
- strdb_put(iwall_db, iwall->wall_name, iwall);
- map[m].iwall_num++;
+ strdb_put(iwall_db, iwall->wall_name, iwall);
+ map[m].iwall_num++;
- return true;
+ return true;
}
void map_iwall_get(struct map_session_data *sd)
{
- struct iwall_data *iwall;
- DBIterator *iter;
- int x1, y1;
- int i;
+ struct iwall_data *iwall;
+ DBIterator* iter;
+ int x1, y1;
+ int i;
- if (map[sd->bl.m].iwall_num < 1)
- return;
+ if( map[sd->bl.m].iwall_num < 1 )
+ return;
- iter = db_iterator(iwall_db);
- for (iwall = dbi_first(iter); dbi_exists(iter); iwall = dbi_next(iter)) {
- if (iwall->m != sd->bl.m)
- continue;
+ iter = db_iterator(iwall_db);
+ for( iwall = dbi_first(iter); dbi_exists(iter); iwall = dbi_next(iter) )
+ {
+ if( iwall->m != sd->bl.m )
+ continue;
- for (i = 0; i < iwall->size; i++) {
- map_iwall_nextxy(iwall->x, iwall->y, iwall->dir, i, &x1, &y1);
- clif_changemapcell(sd->fd, iwall->m, x1, y1, map_getcell(iwall->m, x1, y1, CELL_GETTYPE), SELF);
- }
- }
- dbi_destroy(iter);
+ for( i = 0; i < iwall->size; i++ )
+ {
+ map_iwall_nextxy(iwall->x, iwall->y, iwall->dir, i, &x1, &y1);
+ clif_changemapcell(sd->fd, iwall->m, x1, y1, map_getcell(iwall->m, x1, y1, CELL_GETTYPE), SELF);
+ }
+ }
+ dbi_destroy(iter);
}
void map_iwall_remove(const char *wall_name)
{
- struct iwall_data *iwall;
- int i, x1, y1;
+ struct iwall_data *iwall;
+ int i, x1, y1;
- if ((iwall = (struct iwall_data *)strdb_get(iwall_db, wall_name)) == NULL)
- return; // Nothing to do
+ if( (iwall = (struct iwall_data *)strdb_get(iwall_db, wall_name)) == NULL )
+ return; // Nothing to do
- for (i = 0; i < iwall->size; i++) {
- map_iwall_nextxy(iwall->x, iwall->y, iwall->dir, i, &x1, &y1);
+ for( i = 0; i < iwall->size; i++ )
+ {
+ map_iwall_nextxy(iwall->x, iwall->y, iwall->dir, i, &x1, &y1);
- map_setcell(iwall->m, x1, y1, CELL_SHOOTABLE, true);
- map_setcell(iwall->m, x1, y1, CELL_WALKABLE, true);
+ map_setcell(iwall->m, x1, y1, CELL_SHOOTABLE, true);
+ map_setcell(iwall->m, x1, y1, CELL_WALKABLE, true);
- clif_changemapcell(0, iwall->m, x1, y1, map_getcell(iwall->m, x1, y1, CELL_GETTYPE), ALL_SAMEMAP);
- }
+ clif_changemapcell(0, iwall->m, x1, y1, map_getcell(iwall->m, x1, y1, CELL_GETTYPE), ALL_SAMEMAP);
+ }
- map[iwall->m].iwall_num--;
- strdb_remove(iwall_db, iwall->wall_name);
+ map[iwall->m].iwall_num--;
+ strdb_remove(iwall_db, iwall->wall_name);
}
/**
@@ -2699,12 +2694,12 @@ void map_iwall_remove(const char *wall_name)
*/
static DBData create_map_data_other_server(DBKey key, va_list args)
{
- struct map_data_other_server *mdos;
- unsigned short mapindex = (unsigned short)key.ui;
- mdos=(struct map_data_other_server *)aCalloc(1,sizeof(struct map_data_other_server));
- mdos->index = mapindex;
- memcpy(mdos->name, mapindex_id2name(mapindex), MAP_NAME_LENGTH);
- return db_ptr2data(mdos);
+ struct map_data_other_server *mdos;
+ unsigned short mapindex = (unsigned short)key.ui;
+ mdos=(struct map_data_other_server *)aCalloc(1,sizeof(struct map_data_other_server));
+ mdos->index = mapindex;
+ memcpy(mdos->name, mapindex_id2name(mapindex), MAP_NAME_LENGTH);
+ return db_ptr2data(mdos);
}
/*==========================================
@@ -2712,20 +2707,20 @@ static DBData create_map_data_other_server(DBKey key, va_list args)
*------------------------------------------*/
int map_setipport(unsigned short mapindex, uint32 ip, uint16 port)
{
- struct map_data_other_server *mdos=NULL;
+ struct map_data_other_server *mdos=NULL;
- mdos= uidb_ensure(map_db,(unsigned int)mapindex, create_map_data_other_server);
+ mdos= uidb_ensure(map_db,(unsigned int)mapindex, create_map_data_other_server);
- if (mdos->cell) //Local map,Do nothing. Give priority to our own local maps over ones from another server. [Skotlex]
- return 0;
- if (ip == clif_getip() && port == clif_getport()) {
- //That's odd, we received info that we are the ones with this map, but... we don't have it.
- ShowFatalError("map_setipport : received info that this map-server SHOULD have map '%s', but it is not loaded.\n",mapindex_id2name(mapindex));
- exit(EXIT_FAILURE);
- }
- mdos->ip = ip;
- mdos->port = port;
- return 1;
+ if(mdos->cell) //Local map,Do nothing. Give priority to our own local maps over ones from another server. [Skotlex]
+ return 0;
+ if(ip == clif_getip() && port == clif_getport()) {
+ //That's odd, we received info that we are the ones with this map, but... we don't have it.
+ ShowFatalError("map_setipport : received info that this map-server SHOULD have map '%s', but it is not loaded.\n",mapindex_id2name(mapindex));
+ exit(EXIT_FAILURE);
+ }
+ mdos->ip = ip;
+ mdos->port = port;
+ return 1;
}
/**
@@ -2734,18 +2729,18 @@ int map_setipport(unsigned short mapindex, uint32 ip, uint16 port)
*/
int map_eraseallipport_sub(DBKey key, DBData *data, va_list va)
{
- struct map_data_other_server *mdos = db_data2ptr(data);
- if (mdos->cell == NULL) {
- db_remove(map_db,key);
- aFree(mdos);
- }
- return 0;
+ struct map_data_other_server *mdos = db_data2ptr(data);
+ if(mdos->cell == NULL) {
+ db_remove(map_db,key);
+ aFree(mdos);
+ }
+ return 0;
}
int map_eraseallipport(void)
{
- map_db->foreach(map_db,map_eraseallipport_sub);
- return 1;
+ map_db->foreach(map_db,map_eraseallipport_sub);
+ return 1;
}
/*==========================================
@@ -2753,18 +2748,18 @@ int map_eraseallipport(void)
*------------------------------------------*/
int map_eraseipport(unsigned short mapindex, uint32 ip, uint16 port)
{
- struct map_data_other_server *mdos;
+ struct map_data_other_server *mdos;
- mdos = (struct map_data_other_server *)uidb_get(map_db,(unsigned int)mapindex);
- if (!mdos || mdos->cell) //Map either does not exists or is a local map.
- return 0;
+ mdos = (struct map_data_other_server*)uidb_get(map_db,(unsigned int)mapindex);
+ if(!mdos || mdos->cell) //Map either does not exists or is a local map.
+ return 0;
- if (mdos->ip==ip && mdos->port == port) {
- uidb_remove(map_db,(unsigned int)mapindex);
- aFree(mdos);
- return 1;
- }
- return 0;
+ if(mdos->ip==ip && mdos->port == port) {
+ uidb_remove(map_db,(unsigned int)mapindex);
+ aFree(mdos);
+ return 1;
+ }
+ return 0;
}
/*==========================================
@@ -2772,30 +2767,30 @@ int map_eraseipport(unsigned short mapindex, uint32 ip, uint16 port)
*------------------------------------------*/
static char *map_init_mapcache(FILE *fp)
{
- size_t size = 0;
- char *buffer;
+ size_t size = 0;
+ char *buffer;
- // No file open? Return..
- nullpo_ret(fp);
+ // No file open? Return..
+ nullpo_ret(fp);
- // Get file size
- fseek(fp, 0, SEEK_END);
- size = ftell(fp);
- fseek(fp, 0, SEEK_SET);
+ // Get file size
+ fseek(fp, 0, SEEK_END);
+ size = ftell(fp);
+ fseek(fp, 0, SEEK_SET);
- // Allocate enough space
- CREATE(buffer, char, size);
+ // Allocate enough space
+ CREATE(buffer, char, size);
- // No memory? Return..
- nullpo_ret(buffer);
+ // No memory? Return..
+ nullpo_ret(buffer);
- // Read file into buffer..
- if (fread(buffer, sizeof(char), size, fp) != size) {
- ShowError("map_init_mapcache: Could not read entire mapcache file\n");
- return NULL;
- }
+ // Read file into buffer..
+ if(fread(buffer, sizeof(char), size, fp) != size) {
+ ShowError("map_init_mapcache: Could not read entire mapcache file\n");
+ return NULL;
+ }
- return buffer;
+ return buffer;
}
/*==========================================
@@ -2804,116 +2799,119 @@ static char *map_init_mapcache(FILE *fp)
*==========================================*/
int map_readfromcache(struct map_data *m, char *buffer, char *decode_buffer)
{
- int i;
- struct map_cache_main_header *header = (struct map_cache_main_header *)buffer;
- struct map_cache_map_info *info = NULL;
- char *p = buffer + sizeof(struct map_cache_main_header);
+ int i;
+ struct map_cache_main_header *header = (struct map_cache_main_header *)buffer;
+ struct map_cache_map_info *info = NULL;
+ char *p = buffer + sizeof(struct map_cache_main_header);
- for (i = 0; i < header->map_count; i++) {
- info = (struct map_cache_map_info *)p;
+ for(i = 0; i < header->map_count; i++) {
+ info = (struct map_cache_map_info *)p;
- if (strcmp(m->name, info->name) == 0)
- break; // Map found
+ if( strcmp(m->name, info->name) == 0 )
+ break; // Map found
- // Jump to next entry..
- p += sizeof(struct map_cache_map_info) + info->len;
- }
+ // Jump to next entry..
+ p += sizeof(struct map_cache_map_info) + info->len;
+ }
- if (info && i < header->map_count) {
- unsigned long size, xy;
+ if( info && i < header->map_count ) {
+ unsigned long size, xy;
- if (info->xs <= 0 || info->ys <= 0)
- return 0;// Invalid
+ if( info->xs <= 0 || info->ys <= 0 )
+ return 0;// Invalid
- m->xs = info->xs;
- m->ys = info->ys;
- size = (unsigned long)info->xs*(unsigned long)info->ys;
+ m->xs = info->xs;
+ m->ys = info->ys;
+ size = (unsigned long)info->xs*(unsigned long)info->ys;
- if (size > MAX_MAP_SIZE) {
- ShowWarning("map_readfromcache: %s exceeded MAX_MAP_SIZE of %d\n", info->name, MAX_MAP_SIZE);
- return 0; // Say not found to remove it from list.. [Shinryo]
- }
+ if(size > MAX_MAP_SIZE) {
+ ShowWarning("map_readfromcache: %s exceeded MAX_MAP_SIZE of %d\n", info->name, MAX_MAP_SIZE);
+ return 0; // Say not found to remove it from list.. [Shinryo]
+ }
- // TO-DO: Maybe handle the scenario, if the decoded buffer isn't the same size as expected? [Shinryo]
- decode_zip(decode_buffer, &size, p+sizeof(struct map_cache_map_info), info->len);
+ // TO-DO: Maybe handle the scenario, if the decoded buffer isn't the same size as expected? [Shinryo]
+ decode_zip(decode_buffer, &size, p+sizeof(struct map_cache_map_info), info->len);
- CREATE(m->cell, struct mapcell, size);
+ CREATE(m->cell, struct mapcell, size);
- for (xy = 0; xy < size; ++xy)
- m->cell[xy] = map_gat2cell(decode_buffer[xy]);
+ for( xy = 0; xy < size; ++xy )
+ m->cell[xy] = map_gat2cell(decode_buffer[xy]);
- return 1;
- }
+ return 1;
+ }
- return 0; // Not found
+ return 0; // Not found
}
-int map_addmap(char *mapname)
+int map_addmap(char* mapname)
{
- if (strcmpi(mapname,"clear")==0) {
- map_num = 0;
- instance_start = 0;
- return 0;
- }
+ if( strcmpi(mapname,"clear")==0 )
+ {
+ map_num = 0;
+ instance_start = 0;
+ return 0;
+ }
- if (map_num >= MAX_MAP_PER_SERVER - 1) {
- ShowError("Could not add map '"CL_WHITE"%s"CL_RESET"', the limit of maps has been reached.\n",mapname);
- return 1;
- }
+ if( map_num >= MAX_MAP_PER_SERVER - 1 )
+ {
+ ShowError("Could not add map '"CL_WHITE"%s"CL_RESET"', the limit of maps has been reached.\n",mapname);
+ return 1;
+ }
- mapindex_getmapname(mapname, map[map_num].name);
- map_num++;
- return 0;
+ mapindex_getmapname(mapname, map[map_num].name);
+ map_num++;
+ return 0;
}
static void map_delmapid(int id)
{
- ShowNotice("Removing map [ %s ] from maplist"CL_CLL"\n",map[id].name);
- memmove(map+id, map+id+1, sizeof(map[0])*(map_num-id-1));
- map_num--;
+ ShowNotice("Removing map [ %s ] from maplist"CL_CLL"\n",map[id].name);
+ memmove(map+id, map+id+1, sizeof(map[0])*(map_num-id-1));
+ map_num--;
}
-int map_delmap(char *mapname)
+int map_delmap(char* mapname)
{
- int i;
- char map_name[MAP_NAME_LENGTH];
+ int i;
+ char map_name[MAP_NAME_LENGTH];
- if (strcmpi(mapname, "all") == 0) {
- map_num = 0;
- return 0;
- }
+ if (strcmpi(mapname, "all") == 0) {
+ map_num = 0;
+ return 0;
+ }
- mapindex_getmapname(mapname, map_name);
- for (i = 0; i < map_num; i++) {
- if (strcmp(map[i].name, map_name) == 0) {
- map_delmapid(i);
- return 1;
- }
- }
- return 0;
+ mapindex_getmapname(mapname, map_name);
+ for(i = 0; i < map_num; i++) {
+ if (strcmp(map[i].name, map_name) == 0) {
+ map_delmapid(i);
+ return 1;
+ }
+ }
+ return 0;
}
/// Initializes map flags and adjusts them depending on configuration.
void map_flags_init(void)
{
- int i;
+ int i;
- for (i = 0; i < map_num; i++) {
- // mapflags
- memset(&map[i].flag, 0, sizeof(map[i].flag));
+ for( i = 0; i < map_num; i++ )
+ {
+ // mapflags
+ memset(&map[i].flag, 0, sizeof(map[i].flag));
- // additional mapflag data
- map[i].zone = 0; // restricted mapflag zone
- map[i].nocommand = 0; // nocommand mapflag level
- map[i].bexp = 100; // per map base exp multiplicator
- map[i].jexp = 100; // per map job exp multiplicator
- memset(map[i].drop_list, 0, sizeof(map[i].drop_list)); // pvp nightmare drop list
+ // additional mapflag data
+ map[i].zone = 0; // restricted mapflag zone
+ map[i].nocommand = 0; // nocommand mapflag level
+ map[i].bexp = 100; // per map base exp multiplicator
+ map[i].jexp = 100; // per map job exp multiplicator
+ memset(map[i].drop_list, 0, sizeof(map[i].drop_list)); // pvp nightmare drop list
- // adjustments
- if (battle_config.pk_mode)
- map[i].flag.pvp = 1; // make all maps pvp for pk_mode [Valaris]
- }
+ // adjustments
+ if( battle_config.pk_mode )
+ map[i].flag.pvp = 1; // make all maps pvp for pk_mode [Valaris]
+ }
}
#define NO_WATER 1000000
@@ -2924,69 +2922,70 @@ void map_flags_init(void)
* Assumed path for file is data/mapname.rsw
* Credits to LittleWolf
*/
-int map_waterheight(char *mapname)
+int map_waterheight(char* mapname)
{
- char fn[256];
- char *rsw, *found;
+ char fn[256];
+ char *rsw, *found;
- //Look up for the rsw
- sprintf(fn, "data\\%s.rsw", mapname);
+ //Look up for the rsw
+ sprintf(fn, "data\\%s.rsw", mapname);
- found = grfio_find_file(fn);
- if (found) strcpy(fn, found); // replace with real name
+ found = grfio_find_file(fn);
+ if (found) strcpy(fn, found); // replace with real name
- // read & convert fn
- rsw = (char *) grfio_read(fn);
- if (rsw) {
- //Load water height from file
- int wh = (int) *(float *)(rsw+166);
- aFree(rsw);
- return wh;
- }
- ShowWarning("Failed to find water level for (%s)\n", mapname, fn);
- return NO_WATER;
+ // read & convert fn
+ rsw = (char *) grfio_read (fn);
+ if (rsw)
+ { //Load water height from file
+ int wh = (int) *(float*)(rsw+166);
+ aFree(rsw);
+ return wh;
+ }
+ ShowWarning("Failed to find water level for (%s)\n", mapname, fn);
+ return NO_WATER;
}
/*==================================
* .GAT format
*----------------------------------*/
-int map_readgat(struct map_data *m)
+int map_readgat (struct map_data* m)
{
- char filename[256];
- uint8 *gat;
- int water_height;
- size_t xy, off, num_cells;
+ char filename[256];
+ uint8* gat;
+ int water_height;
+ size_t xy, off, num_cells;
- sprintf(filename, "data\\%s.gat", m->name);
+ sprintf(filename, "data\\%s.gat", m->name);
- gat = (uint8 *) grfio_read(filename);
- if (gat == NULL)
- return 0;
+ gat = (uint8 *) grfio_read(filename);
+ if (gat == NULL)
+ return 0;
- m->xs = *(int32 *)(gat+6);
- m->ys = *(int32 *)(gat+10);
- num_cells = m->xs * m->ys;
- CREATE(m->cell, struct mapcell, num_cells);
+ m->xs = *(int32*)(gat+6);
+ m->ys = *(int32*)(gat+10);
+ num_cells = m->xs * m->ys;
+ CREATE(m->cell, struct mapcell, num_cells);
- water_height = map_waterheight(m->name);
+ water_height = map_waterheight(m->name);
- // Set cell properties
- off = 14;
- for (xy = 0; xy < num_cells; ++xy) {
- // read cell data
- float height = *(float *)(gat + off);
- uint32 type = *(uint32 *)(gat + off + 16);
- off += 20;
+ // Set cell properties
+ off = 14;
+ for( xy = 0; xy < num_cells; ++xy )
+ {
+ // read cell data
+ float height = *(float*)( gat + off );
+ uint32 type = *(uint32*)( gat + off + 16 );
+ off += 20;
- if (type == 0 && water_height != NO_WATER && height > water_height)
- type = 3; // Cell is 0 (walkable) but under water level, set to 3 (walkable water)
+ if( type == 0 && water_height != NO_WATER && height > water_height )
+ type = 3; // Cell is 0 (walkable) but under water level, set to 3 (walkable water)
- m->cell[xy] = map_gat2cell(type);
- }
+ m->cell[xy] = map_gat2cell(type);
+ }
- aFree(gat);
+ aFree(gat);
- return 1;
+ return 1;
}
/*======================================
@@ -2994,109 +2993,110 @@ int map_readgat(struct map_data *m)
*--------------------------------------*/
void map_addmap2db(struct map_data *m)
{
- uidb_put(map_db, (unsigned int)m->index, m);
+ uidb_put(map_db, (unsigned int)m->index, m);
}
void map_removemapdb(struct map_data *m)
{
- uidb_remove(map_db, (unsigned int)m->index);
+ uidb_remove(map_db, (unsigned int)m->index);
}
/*======================================
* Initiate maps loading stage
*--------------------------------------*/
-int map_readallmaps(void)
-{
- int i;
- FILE *fp=NULL;
- int maps_removed = 0;
- char *map_cache_buffer = NULL; // Has the uncompressed gat data of all maps, so just one allocation has to be made
- char map_cache_decode_buffer[MAX_MAP_SIZE];
-
- if (enable_grf)
- ShowStatus("Loading maps (using GRF files)...\n");
- else {
- char mapcachefilepath[254];
- sprintf(mapcachefilepath,"%s/%s%s",db_path,DBPATH,"map_cache.dat");
- ShowStatus("Loading maps (using %s as map cache)...\n", mapcachefilepath);
- if ((fp = fopen(mapcachefilepath, "rb")) == NULL) {
- ShowFatalError("Unable to open map cache file "CL_WHITE"%s"CL_RESET"\n", mapcachefilepath);
- exit(EXIT_FAILURE); //No use launching server if maps can't be read.
- }
-
- // Init mapcache data.. [Shinryo]
- map_cache_buffer = map_init_mapcache(fp);
- if (!map_cache_buffer) {
- ShowFatalError("Failed to initialize mapcache data (%s)..\n", mapcachefilepath);
- exit(EXIT_FAILURE);
- }
- }
-
- for (i = 0; i < map_num; i++) {
- size_t size;
-
- // show progress
- if (enable_grf)
- ShowStatus("Loading maps [%i/%i]: %s"CL_CLL"\r", i, map_num, map[i].name);
-
- // try to load the map
- if (!
- (enable_grf?
- map_readgat(&map[i])
- :map_readfromcache(&map[i], map_cache_buffer, map_cache_decode_buffer))
- ) {
- map_delmapid(i);
- maps_removed++;
- i--;
- continue;
- }
-
- map[i].index = mapindex_name2id(map[i].name);
-
- if (uidb_get(map_db,(unsigned int)map[i].index) != NULL) {
- ShowWarning("Map %s already loaded!"CL_CLL"\n", map[i].name);
- if (map[i].cell) {
- aFree(map[i].cell);
- map[i].cell = NULL;
- }
- map_delmapid(i);
- maps_removed++;
- i--;
- continue;
- }
-
- map_addmap2db(&map[i]);
-
- map[i].m = i;
- memset(map[i].moblist, 0, sizeof(map[i].moblist)); //Initialize moblist [Skotlex]
- map[i].mob_delete_timer = INVALID_TIMER; //Initialize timer [Skotlex]
-
- map[i].bxs = (map[i].xs + BLOCK_SIZE - 1) / BLOCK_SIZE;
- map[i].bys = (map[i].ys + BLOCK_SIZE - 1) / BLOCK_SIZE;
-
- size = map[i].bxs * map[i].bys * sizeof(struct block_list *);
- map[i].block = (struct block_list **)aCalloc(size, 1);
- map[i].block_mob = (struct block_list **)aCalloc(size, 1);
- }
-
- // intialization and configuration-dependent adjustments of mapflags
- map_flags_init();
-
- if (!enable_grf) {
- fclose(fp);
-
- // The cache isn't needed anymore, so free it.. [Shinryo]
- aFree(map_cache_buffer);
- }
-
- // finished map loading
- ShowInfo("Successfully loaded '"CL_WHITE"%d"CL_RESET"' maps."CL_CLL"\n",map_num);
- instance_start = map_num; // Next Map Index will be instances
-
- if (maps_removed)
- ShowNotice("Maps removed: '"CL_WHITE"%d"CL_RESET"'\n",maps_removed);
-
- return 0;
+int map_readallmaps (void)
+{
+ int i;
+ FILE* fp=NULL;
+ int maps_removed = 0;
+ char *map_cache_buffer = NULL; // Has the uncompressed gat data of all maps, so just one allocation has to be made
+ char map_cache_decode_buffer[MAX_MAP_SIZE];
+
+ if( enable_grf )
+ ShowStatus("Loading maps (using GRF files)...\n");
+ else {
+ char mapcachefilepath[254];
+ sprintf(mapcachefilepath,"%s/%s%s",db_path,DBPATH,"map_cache.dat");
+ ShowStatus("Loading maps (using %s as map cache)...\n", mapcachefilepath);
+ if( (fp = fopen(mapcachefilepath, "rb")) == NULL ) {
+ ShowFatalError("Unable to open map cache file "CL_WHITE"%s"CL_RESET"\n", mapcachefilepath);
+ exit(EXIT_FAILURE); //No use launching server if maps can't be read.
+ }
+
+ // Init mapcache data.. [Shinryo]
+ map_cache_buffer = map_init_mapcache(fp);
+ if(!map_cache_buffer) {
+ ShowFatalError("Failed to initialize mapcache data (%s)..\n", mapcachefilepath);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ for(i = 0; i < map_num; i++) {
+ size_t size;
+
+ // show progress
+ if(enable_grf)
+ ShowStatus("Loading maps [%i/%i]: %s"CL_CLL"\r", i, map_num, map[i].name);
+
+ // try to load the map
+ if( !
+ (enable_grf?
+ map_readgat(&map[i])
+ :map_readfromcache(&map[i], map_cache_buffer, map_cache_decode_buffer))
+ ) {
+ map_delmapid(i);
+ maps_removed++;
+ i--;
+ continue;
+ }
+
+ map[i].index = mapindex_name2id(map[i].name);
+
+ if (uidb_get(map_db,(unsigned int)map[i].index) != NULL)
+ {
+ ShowWarning("Map %s already loaded!"CL_CLL"\n", map[i].name);
+ if (map[i].cell) {
+ aFree(map[i].cell);
+ map[i].cell = NULL;
+ }
+ map_delmapid(i);
+ maps_removed++;
+ i--;
+ continue;
+ }
+
+ map_addmap2db(&map[i]);
+
+ map[i].m = i;
+ memset(map[i].moblist, 0, sizeof(map[i].moblist)); //Initialize moblist [Skotlex]
+ map[i].mob_delete_timer = INVALID_TIMER; //Initialize timer [Skotlex]
+
+ map[i].bxs = (map[i].xs + BLOCK_SIZE - 1) / BLOCK_SIZE;
+ map[i].bys = (map[i].ys + BLOCK_SIZE - 1) / BLOCK_SIZE;
+
+ size = map[i].bxs * map[i].bys * sizeof(struct block_list*);
+ map[i].block = (struct block_list**)aCalloc(size, 1);
+ map[i].block_mob = (struct block_list**)aCalloc(size, 1);
+ }
+
+ // intialization and configuration-dependent adjustments of mapflags
+ map_flags_init();
+
+ if( !enable_grf ) {
+ fclose(fp);
+
+ // The cache isn't needed anymore, so free it.. [Shinryo]
+ aFree(map_cache_buffer);
+ }
+
+ // finished map loading
+ ShowInfo("Successfully loaded '"CL_WHITE"%d"CL_RESET"' maps."CL_CLL"\n",map_num);
+ instance_start = map_num; // Next Map Index will be instances
+
+ if (maps_removed)
+ ShowNotice("Maps removed: '"CL_WHITE"%d"CL_RESET"'\n",maps_removed);
+
+ return 0;
}
////////////////////////////////////////////////////////////////////////
@@ -3106,67 +3106,79 @@ static int char_ip_set = 0;
/*==========================================
* Console Command Parser [Wizputer]
*------------------------------------------*/
-int parse_console(const char *buf)
-{
- char type[64];
- char command[64];
- char map[64];
- int x = 0;
- int y = 0;
- int m;
- int n;
- struct map_session_data sd;
-
- memset(&sd, 0, sizeof(struct map_session_data));
- strcpy(sd.status.name, "console");
-
- if ((n = sscanf(buf, "%63[^:]:%63[^:]:%63s %d %d[^\n]", type, command, map, &x, &y)) < 5) {
- if ((n = sscanf(buf, "%63[^:]:%63[^\n]", type, command)) < 2) {
- n = sscanf(buf, "%63[^\n]", type);
- }
- }
-
- if (n == 5) {
- m = map_mapname2mapid(map);
- if (m < 0) {
- ShowWarning("Console: Unknown map.\n");
- return 0;
- }
- sd.bl.m = m;
- map_search_freecell(&sd.bl, m, &sd.bl.x, &sd.bl.y, -1, -1, 0);
- if (x > 0)
- sd.bl.x = x;
- if (y > 0)
- sd.bl.y = y;
- } else {
- map[0] = '\0';
- if (n < 2)
- command[0] = '\0';
- if (n < 1)
- type[0] = '\0';
- }
-
- ShowNotice("Type of command: '%s' || Command: '%s' || Map: '%s' Coords: %d %d\n", type, command, map, x, y);
-
- if (n == 5 && strcmpi("admin",type) == 0) {
- if (!is_atcommand(sd.fd, &sd, command, 0))
- ShowInfo("Console: not atcommand\n");
- } else if (n == 2 && strcmpi("server", type) == 0) {
- if (strcmpi("shutdown", command) == 0 || strcmpi("exit", command) == 0 || strcmpi("quit", command) == 0) {
- runflag = 0;
- }
- } else if (strcmpi("help", type) == 0) {
- ShowInfo("To use GM commands:\n");
- ShowInfo(" admin:<gm command>:<map of \"gm\"> <x> <y>\n");
- ShowInfo("You can use any GM command that doesn't require the GM.\n");
- ShowInfo("No using @item or @warp however you can use @charwarp\n");
- ShowInfo("The <map of \"gm\"> <x> <y> is for commands that need coords of the GM\n");
- ShowInfo("IE: @spawn\n");
- ShowInfo("To shutdown the server:\n");
- ShowInfo(" server:shutdown\n");
- }
-
- return 0;
+int parse_console(const char* buf)
+{
+ char type[64];
+ char command[64];
+ char map[64];
+ int x = 0;
+ int y = 0;
+ int m;
+ int n;
+ struct map_session_data sd;
+
+ memset(&sd, 0, sizeof(struct map_session_data));
+ strcpy(sd.status.name, "console");
+
+ if( ( n = sscanf(buf, "%63[^:]:%63[^:]:%63s %d %d[^\n]", type, command, map, &x, &y) ) < 5 )
+ {
+ if( ( n = sscanf(buf, "%63[^:]:%63[^\n]", type, command) ) < 2 )
+ {
+ n = sscanf(buf, "%63[^\n]", type);
+ }
+ }
+
+ if( n == 5 )
+ {
+ m = map_mapname2mapid(map);
+ if( m < 0 )
+ {
+ ShowWarning("Console: Unknown map.\n");
+ return 0;
+ }
+ sd.bl.m = m;
+ map_search_freecell(&sd.bl, m, &sd.bl.x, &sd.bl.y, -1, -1, 0);
+ if( x > 0 )
+ sd.bl.x = x;
+ if( y > 0 )
+ sd.bl.y = y;
+ }
+ else
+ {
+ map[0] = '\0';
+ if( n < 2 )
+ command[0] = '\0';
+ if( n < 1 )
+ type[0] = '\0';
+ }
+
+ ShowNotice("Type of command: '%s' || Command: '%s' || Map: '%s' Coords: %d %d\n", type, command, map, x, y);
+
+ if( n == 5 && strcmpi("admin",type) == 0 )
+ {
+ if( !is_atcommand(sd.fd, &sd, command, 0) )
+ ShowInfo("Console: not atcommand\n");
+ }
+ else if( n == 2 && strcmpi("server", type) == 0 )
+ {
+ if( strcmpi("shutdown", command) == 0 || strcmpi("exit", command) == 0 || strcmpi("quit", command) == 0 )
+ {
+ runflag = 0;
+ }
+ }
+ else if( strcmpi("help", type) == 0 )
+ {
+ ShowInfo("To use GM commands:\n");
+ ShowInfo(" admin:<gm command>:<map of \"gm\"> <x> <y>\n");
+ ShowInfo("You can use any GM command that doesn't require the GM.\n");
+ ShowInfo("No using @item or @warp however you can use @charwarp\n");
+ ShowInfo("The <map of \"gm\"> <x> <y> is for commands that need coords of the GM\n");
+ ShowInfo("IE: @spawn\n");
+ ShowInfo("To shutdown the server:\n");
+ ShowInfo(" server:shutdown\n");
+ }
+
+ return 0;
}
/*==========================================
@@ -3174,218 +3186,241 @@ int parse_console(const char *buf)
*------------------------------------------*/
int map_config_read(char *cfgName)
{
- char line[1024], w1[1024], w2[1024];
- FILE *fp;
-
- fp = fopen(cfgName,"r");
- if (fp == NULL) {
- ShowError("Map configuration file not found at: %s\n", cfgName);
- return 1;
- }
-
- while (fgets(line, sizeof(line), fp)) {
- char *ptr;
-
- if (line[0] == '/' && line[1] == '/')
- continue;
- if ((ptr = strstr(line, "//")) != NULL)
- *ptr = '\n'; //Strip comments
- if (sscanf(line, "%[^:]: %[^\t\r\n]", w1, w2) < 2)
- continue;
-
- //Strip trailing spaces
- ptr = w2 + strlen(w2);
- while (--ptr >= w2 && *ptr == ' ');
- ptr++;
- *ptr = '\0';
-
- if (strcmpi(w1,"timestamp_format")==0)
- strncpy(timestamp_format, w2, 20);
- else if (strcmpi(w1,"stdout_with_ansisequence")==0)
- stdout_with_ansisequence = config_switch(w2);
- else if (strcmpi(w1,"console_silent")==0) {
- msg_silent = atoi(w2);
- if (msg_silent) // only bother if its actually enabled
- ShowInfo("Console Silent Setting: %d\n", atoi(w2));
- } else if (strcmpi(w1, "userid")==0)
- chrif_setuserid(w2);
- else if (strcmpi(w1, "passwd") == 0)
- chrif_setpasswd(w2);
- else if (strcmpi(w1, "char_ip") == 0)
- char_ip_set = chrif_setip(w2);
- else if (strcmpi(w1, "char_port") == 0)
- chrif_setport(atoi(w2));
- else if (strcmpi(w1, "map_ip") == 0)
- map_ip_set = clif_setip(w2);
- else if (strcmpi(w1, "bind_ip") == 0)
- clif_setbindip(w2);
- else if (strcmpi(w1, "map_port") == 0) {
- clif_setport(atoi(w2));
- map_port = (atoi(w2));
- } else if (strcmpi(w1, "map") == 0)
- map_addmap(w2);
- else if (strcmpi(w1, "delmap") == 0)
- map_delmap(w2);
- else if (strcmpi(w1, "npc") == 0)
- npc_addsrcfile(w2);
- else if (strcmpi(w1, "delnpc") == 0)
- npc_delsrcfile(w2);
- else if (strcmpi(w1, "autosave_time") == 0) {
- autosave_interval = atoi(w2);
- if (autosave_interval < 1) //Revert to default saving.
- autosave_interval = DEFAULT_AUTOSAVE_INTERVAL;
- else
- autosave_interval *= 1000; //Pass from sec to ms
- } else if (strcmpi(w1, "minsave_time") == 0) {
- minsave_interval= atoi(w2);
- if (minsave_interval < 1)
- minsave_interval = 1;
- } else if (strcmpi(w1, "save_settings") == 0)
- save_settings = atoi(w2);
- else if (strcmpi(w1, "motd_txt") == 0)
- strcpy(motd_txt, w2);
- else if (strcmpi(w1, "help_txt") == 0)
- strcpy(help_txt, w2);
- else if (strcmpi(w1, "help2_txt") == 0)
- strcpy(help2_txt, w2);
- else if (strcmpi(w1, "charhelp_txt") == 0)
- strcpy(charhelp_txt, w2);
- else if (strcmpi(w1,"db_path") == 0)
- strncpy(db_path,w2,255);
- else if (strcmpi(w1, "console") == 0) {
- console = config_switch(w2);
- if (console)
- ShowNotice("Console Commands are enabled.\n");
- } else if (strcmpi(w1, "enable_spy") == 0)
- enable_spy = config_switch(w2);
- else if (strcmpi(w1, "use_grf") == 0)
- enable_grf = config_switch(w2);
- else if (strcmpi(w1, "console_msg_log") == 0)
- console_msg_log = atoi(w2);//[Ind]
- else if (strcmpi(w1, "import") == 0)
- map_config_read(w2);
- else
- ShowWarning("Unknown setting '%s' in file %s\n", w1, cfgName);
- }
-
- fclose(fp);
- return 0;
+ char line[1024], w1[1024], w2[1024];
+ FILE *fp;
+
+ fp = fopen(cfgName,"r");
+ if( fp == NULL )
+ {
+ ShowError("Map configuration file not found at: %s\n", cfgName);
+ return 1;
+ }
+
+ while( fgets(line, sizeof(line), fp) )
+ {
+ char* ptr;
+
+ if( line[0] == '/' && line[1] == '/' )
+ continue;
+ if( (ptr = strstr(line, "//")) != NULL )
+ *ptr = '\n'; //Strip comments
+ if( sscanf(line, "%[^:]: %[^\t\r\n]", w1, w2) < 2 )
+ continue;
+
+ //Strip trailing spaces
+ ptr = w2 + strlen(w2);
+ while (--ptr >= w2 && *ptr == ' ');
+ ptr++;
+ *ptr = '\0';
+
+ if(strcmpi(w1,"timestamp_format")==0)
+ strncpy(timestamp_format, w2, 20);
+ else if(strcmpi(w1,"stdout_with_ansisequence")==0)
+ stdout_with_ansisequence = config_switch(w2);
+ else if(strcmpi(w1,"console_silent")==0) {
+ msg_silent = atoi(w2);
+ if( msg_silent ) // only bother if its actually enabled
+ ShowInfo("Console Silent Setting: %d\n", atoi(w2));
+ } else if (strcmpi(w1, "userid")==0)
+ chrif_setuserid(w2);
+ else if (strcmpi(w1, "passwd") == 0)
+ chrif_setpasswd(w2);
+ else if (strcmpi(w1, "char_ip") == 0)
+ char_ip_set = chrif_setip(w2);
+ else if (strcmpi(w1, "char_port") == 0)
+ chrif_setport(atoi(w2));
+ else if (strcmpi(w1, "map_ip") == 0)
+ map_ip_set = clif_setip(w2);
+ else if (strcmpi(w1, "bind_ip") == 0)
+ clif_setbindip(w2);
+ else if (strcmpi(w1, "map_port") == 0) {
+ clif_setport(atoi(w2));
+ map_port = (atoi(w2));
+ } else if (strcmpi(w1, "map") == 0)
+ map_addmap(w2);
+ else if (strcmpi(w1, "delmap") == 0)
+ map_delmap(w2);
+ else if (strcmpi(w1, "npc") == 0)
+ npc_addsrcfile(w2);
+ else if (strcmpi(w1, "delnpc") == 0)
+ npc_delsrcfile(w2);
+ else if (strcmpi(w1, "autosave_time") == 0) {
+ autosave_interval = atoi(w2);
+ if (autosave_interval < 1) //Revert to default saving.
+ autosave_interval = DEFAULT_AUTOSAVE_INTERVAL;
+ else
+ autosave_interval *= 1000; //Pass from sec to ms
+ } else if (strcmpi(w1, "minsave_time") == 0) {
+ minsave_interval= atoi(w2);
+ if (minsave_interval < 1)
+ minsave_interval = 1;
+ } else if (strcmpi(w1, "save_settings") == 0)
+ save_settings = atoi(w2);
+ else if (strcmpi(w1, "motd_txt") == 0)
+ strcpy(motd_txt, w2);
+ else if (strcmpi(w1, "help_txt") == 0)
+ strcpy(help_txt, w2);
+ else if (strcmpi(w1, "help2_txt") == 0)
+ strcpy(help2_txt, w2);
+ else if (strcmpi(w1, "charhelp_txt") == 0)
+ strcpy(charhelp_txt, w2);
+ else if(strcmpi(w1,"db_path") == 0)
+ strncpy(db_path,w2,255);
+ else if (strcmpi(w1, "console") == 0) {
+ console = config_switch(w2);
+ if (console)
+ ShowNotice("Console Commands are enabled.\n");
+ } else if (strcmpi(w1, "enable_spy") == 0)
+ enable_spy = config_switch(w2);
+ else if (strcmpi(w1, "use_grf") == 0)
+ enable_grf = config_switch(w2);
+ else if (strcmpi(w1, "console_msg_log") == 0)
+ console_msg_log = atoi(w2);//[Ind]
+ else if (strcmpi(w1, "import") == 0)
+ map_config_read(w2);
+ else
+ ShowWarning("Unknown setting '%s' in file %s\n", w1, cfgName);
+ }
+
+ fclose(fp);
+ return 0;
}
void map_reloadnpc_sub(char *cfgName)
{
- char line[1024], w1[1024], w2[1024];
- FILE *fp;
+ char line[1024], w1[1024], w2[1024];
+ FILE *fp;
- fp = fopen(cfgName,"r");
- if (fp == NULL) {
- ShowError("Map configuration file not found at: %s\n", cfgName);
- return;
- }
+ fp = fopen(cfgName,"r");
+ if( fp == NULL )
+ {
+ ShowError("Map configuration file not found at: %s\n", cfgName);
+ return;
+ }
- while (fgets(line, sizeof(line), fp)) {
- char *ptr;
+ while( fgets(line, sizeof(line), fp) )
+ {
+ char* ptr;
- if (line[0] == '/' && line[1] == '/')
- continue;
- if ((ptr = strstr(line, "//")) != NULL)
- *ptr = '\n'; //Strip comments
- if (sscanf(line, "%[^:]: %[^\t\r\n]", w1, w2) < 2)
- continue;
+ if( line[0] == '/' && line[1] == '/' )
+ continue;
+ if( (ptr = strstr(line, "//")) != NULL )
+ *ptr = '\n'; //Strip comments
+ if( sscanf(line, "%[^:]: %[^\t\r\n]", w1, w2) < 2 )
+ continue;
- //Strip trailing spaces
- ptr = w2 + strlen(w2);
- while (--ptr >= w2 && *ptr == ' ');
- ptr++;
- *ptr = '\0';
+ //Strip trailing spaces
+ ptr = w2 + strlen(w2);
+ while (--ptr >= w2 && *ptr == ' ');
+ ptr++;
+ *ptr = '\0';
- if (strcmpi(w1, "npc") == 0)
- npc_addsrcfile(w2);
- else if (strcmpi(w1, "import") == 0)
- map_reloadnpc_sub(w2);
- else
- ShowWarning("Unknown setting '%s' in file %s\n", w1, cfgName);
- }
+ if (strcmpi(w1, "npc") == 0)
+ npc_addsrcfile(w2);
+ else if (strcmpi(w1, "import") == 0)
+ map_reloadnpc_sub(w2);
+ else
+ ShowWarning("Unknown setting '%s' in file %s\n", w1, cfgName);
+ }
- fclose(fp);
+ fclose(fp);
}
void map_reloadnpc(bool clear)
{
- if (clear)
- npc_addsrcfile("clear"); // this will clear the current script list
+ if (clear)
+ npc_addsrcfile("clear"); // this will clear the current script list
#ifdef RENEWAL
- map_reloadnpc_sub("npc/re/scripts_main.conf");
+ map_reloadnpc_sub("npc/re/scripts_main.conf");
#else
- map_reloadnpc_sub("npc/pre-re/scripts_main.conf");
+ map_reloadnpc_sub("npc/pre-re/scripts_main.conf");
#endif
}
int inter_config_read(char *cfgName)
{
- char line[1024],w1[1024],w2[1024];
- FILE *fp;
-
- fp=fopen(cfgName,"r");
- if (fp==NULL) {
- ShowError("File not found: %s\n",cfgName);
- return 1;
- }
- while (fgets(line, sizeof(line), fp)) {
- if (line[0] == '/' && line[1] == '/')
- continue;
- if (sscanf(line,"%[^:]: %[^\r\n]",w1,w2) < 2)
- continue;
-
- if (strcmpi(w1, "main_chat_nick")==0)
- safestrncpy(main_chat_nick, w2, sizeof(main_chat_nick));
- 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);
- else if (strcmpi(w1,"item_db2_db")==0)
- strcpy(item_db2_db,w2);
- else if (strcmpi(w1,"item_db_re_db")==0)
- strcpy(item_db_re_db,w2);
- else if (strcmpi(w1,"mob_db2_db")==0)
- strcpy(mob_db2_db,w2);
- else
- //Map Server SQL DB
- if (strcmpi(w1,"map_server_ip")==0)
- strcpy(map_server_ip, w2);
- else if (strcmpi(w1,"map_server_port")==0)
- map_server_port=atoi(w2);
- else if (strcmpi(w1,"map_server_id")==0)
- strcpy(map_server_id, w2);
- else if (strcmpi(w1,"map_server_pw")==0)
- strcpy(map_server_pw, w2);
- else if (strcmpi(w1,"map_server_db")==0)
- strcpy(map_server_db, w2);
- else if (strcmpi(w1,"default_codepage")==0)
- strcpy(default_codepage, w2);
- else if (strcmpi(w1,"use_sql_db")==0) {
- db_use_sqldbs = config_switch(w2);
- ShowStatus("Using SQL dbs: %s\n",w2);
- } else if (strcmpi(w1,"log_db_ip")==0)
- strcpy(log_db_ip, w2);
- else if (strcmpi(w1,"log_db_id")==0)
- strcpy(log_db_id, w2);
- else if (strcmpi(w1,"log_db_pw")==0)
- strcpy(log_db_pw, w2);
- else if (strcmpi(w1,"log_db_port")==0)
- log_db_port = atoi(w2);
- else if (strcmpi(w1,"log_db_db")==0)
- strcpy(log_db_db, w2);
- else if (mapreg_config_read(w1,w2))
- continue;
- //support the import command, just like any other config
- else if (strcmpi(w1,"import")==0)
- inter_config_read(w2);
- }
- fclose(fp);
-
- return 0;
+ char line[1024],w1[1024],w2[1024];
+ FILE *fp;
+
+ fp=fopen(cfgName,"r");
+ if(fp==NULL){
+ ShowError("File not found: %s\n",cfgName);
+ return 1;
+ }
+ while(fgets(line, sizeof(line), fp))
+ {
+ if(line[0] == '/' && line[1] == '/')
+ continue;
+ if( sscanf(line,"%[^:]: %[^\r\n]",w1,w2) < 2 )
+ continue;
+
+ if(strcmpi(w1, "main_chat_nick")==0)
+ safestrncpy(main_chat_nick, w2, sizeof(main_chat_nick));
+ 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);
+ else
+ if(strcmpi(w1,"item_db2_db")==0)
+ strcpy(item_db2_db,w2);
+ else
+ if(strcmpi(w1,"item_db_re_db")==0)
+ strcpy(item_db_re_db,w2);
+ else
+ if(strcmpi(w1,"mob_db2_db")==0)
+ strcpy(mob_db2_db,w2);
+ else
+ //Map Server SQL DB
+ if(strcmpi(w1,"map_server_ip")==0)
+ strcpy(map_server_ip, w2);
+ else
+ if(strcmpi(w1,"map_server_port")==0)
+ map_server_port=atoi(w2);
+ else
+ if(strcmpi(w1,"map_server_id")==0)
+ strcpy(map_server_id, w2);
+ else
+ if(strcmpi(w1,"map_server_pw")==0)
+ strcpy(map_server_pw, w2);
+ else
+ if(strcmpi(w1,"map_server_db")==0)
+ strcpy(map_server_db, w2);
+ else
+ if(strcmpi(w1,"default_codepage")==0)
+ strcpy(default_codepage, w2);
+ else
+ if(strcmpi(w1,"use_sql_db")==0) {
+ db_use_sqldbs = config_switch(w2);
+ ShowStatus ("Using SQL dbs: %s\n",w2);
+ } else
+ if(strcmpi(w1,"log_db_ip")==0)
+ strcpy(log_db_ip, w2);
+ else
+ if(strcmpi(w1,"log_db_id")==0)
+ strcpy(log_db_id, w2);
+ else
+ if(strcmpi(w1,"log_db_pw")==0)
+ strcpy(log_db_pw, w2);
+ else
+ if(strcmpi(w1,"log_db_port")==0)
+ log_db_port = atoi(w2);
+ else
+ if(strcmpi(w1,"log_db_db")==0)
+ strcpy(log_db_db, w2);
+ else
+ if( mapreg_config_read(w1,w2) )
+ continue;
+ //support the import command, just like any other config
+ else
+ if(strcmpi(w1,"import")==0)
+ inter_config_read(w2);
+ }
+ fclose(fp);
+
+ return 0;
}
/*=======================================
@@ -3393,52 +3428,53 @@ int inter_config_read(char *cfgName)
*---------------------------------------*/
int map_sql_init(void)
{
- // main db connection
- mmysql_handle = Sql_Malloc();
+ // main db connection
+ mmysql_handle = Sql_Malloc();
- ShowInfo("Connecting to the Map DB Server....\n");
- if (SQL_ERROR == Sql_Connect(mmysql_handle, map_server_id, map_server_pw, map_server_ip, map_server_port, map_server_db))
- exit(EXIT_FAILURE);
- ShowStatus("connect success! (Map Server Connection)\n");
+ ShowInfo("Connecting to the Map DB Server....\n");
+ if( SQL_ERROR == Sql_Connect(mmysql_handle, map_server_id, map_server_pw, map_server_ip, map_server_port, map_server_db) )
+ exit(EXIT_FAILURE);
+ ShowStatus("connect success! (Map Server Connection)\n");
- if (strlen(default_codepage) > 0)
- if (SQL_ERROR == Sql_SetEncoding(mmysql_handle, default_codepage))
- Sql_ShowDebug(mmysql_handle);
+ if( strlen(default_codepage) > 0 )
+ if ( SQL_ERROR == Sql_SetEncoding(mmysql_handle, default_codepage) )
+ Sql_ShowDebug(mmysql_handle);
- return 0;
+ return 0;
}
int map_sql_close(void)
{
- ShowStatus("Close Map DB Connection....\n");
- Sql_Free(mmysql_handle);
- mmysql_handle = NULL;
+ ShowStatus("Close Map DB Connection....\n");
+ Sql_Free(mmysql_handle);
+ mmysql_handle = NULL;
#ifndef BETA_THREAD_TEST
- if (log_config.sql_logs) {
- ShowStatus("Close Log DB Connection....\n");
- Sql_Free(logmysql_handle);
- logmysql_handle = NULL;
- }
+ if (log_config.sql_logs)
+ {
+ ShowStatus("Close Log DB Connection....\n");
+ Sql_Free(logmysql_handle);
+ logmysql_handle = NULL;
+ }
#endif
- return 0;
+ return 0;
}
int log_sql_init(void)
{
#ifndef BETA_THREAD_TEST
- // log db connection
- logmysql_handle = Sql_Malloc();
+ // log db connection
+ logmysql_handle = Sql_Malloc();
- ShowInfo(""CL_WHITE"[SQL]"CL_RESET": Connecting to the Log Database "CL_WHITE"%s"CL_RESET" At "CL_WHITE"%s"CL_RESET"...\n",log_db_db,log_db_ip);
- if (SQL_ERROR == Sql_Connect(logmysql_handle, log_db_id, log_db_pw, log_db_ip, log_db_port, log_db_db))
- exit(EXIT_FAILURE);
- ShowStatus(""CL_WHITE"[SQL]"CL_RESET": Successfully '"CL_GREEN"connected"CL_RESET"' to Database '"CL_WHITE"%s"CL_RESET"'.\n", log_db_db);
+ ShowInfo(""CL_WHITE"[SQL]"CL_RESET": Connecting to the Log Database "CL_WHITE"%s"CL_RESET" At "CL_WHITE"%s"CL_RESET"...\n",log_db_db,log_db_ip);
+ if ( SQL_ERROR == Sql_Connect(logmysql_handle, log_db_id, log_db_pw, log_db_ip, log_db_port, log_db_db) )
+ exit(EXIT_FAILURE);
+ ShowStatus(""CL_WHITE"[SQL]"CL_RESET": Successfully '"CL_GREEN"connected"CL_RESET"' to Database '"CL_WHITE"%s"CL_RESET"'.\n", log_db_db);
- if (strlen(default_codepage) > 0)
- if (SQL_ERROR == Sql_SetEncoding(logmysql_handle, default_codepage))
- Sql_ShowDebug(logmysql_handle);
+ if( strlen(default_codepage) > 0 )
+ if ( SQL_ERROR == Sql_SetEncoding(logmysql_handle, default_codepage) )
+ Sql_ShowDebug(logmysql_handle);
#endif
- return 0;
+ return 0;
}
/**
@@ -3446,10 +3482,10 @@ int log_sql_init(void)
*/
int map_db_final(DBKey key, DBData *data, va_list ap)
{
- struct map_data_other_server *mdos = db_data2ptr(data);
- if (mdos && mdos->cell == NULL)
- aFree(mdos);
- return 0;
+ struct map_data_other_server *mdos = db_data2ptr(data);
+ if(mdos && mdos->cell == NULL)
+ aFree(mdos);
+ return 0;
}
/**
@@ -3457,46 +3493,47 @@ int map_db_final(DBKey key, DBData *data, va_list ap)
*/
int nick_db_final(DBKey key, DBData *data, va_list args)
{
- struct charid2nick *p = db_data2ptr(data);
- struct charid_request *req;
+ struct charid2nick* p = db_data2ptr(data);
+ struct charid_request* req;
- if (p == NULL)
- return 0;
- while (p->requests) {
- req = p->requests;
- p->requests = req->next;
- aFree(req);
- }
- aFree(p);
- return 0;
+ if( p == NULL )
+ return 0;
+ while( p->requests )
+ {
+ req = p->requests;
+ p->requests = req->next;
+ aFree(req);
+ }
+ aFree(p);
+ return 0;
}
int cleanup_sub(struct block_list *bl, va_list ap)
{
- nullpo_ret(bl);
-
- switch (bl->type) {
- case BL_PC:
- map_quit((struct map_session_data *) bl);
- break;
- case BL_NPC:
- npc_unload((struct npc_data *)bl,false);
- break;
- case BL_MOB:
- unit_free(bl,CLR_OUTSIGHT);
- break;
- case BL_PET:
- //There is no need for this, the pet is removed together with the player. [Skotlex]
- break;
- case BL_ITEM:
- map_clearflooritem(bl);
- break;
- case BL_SKILL:
- skill_delunit((struct skill_unit *) bl);
- break;
- }
-
- return 1;
+ nullpo_ret(bl);
+
+ switch(bl->type) {
+ case BL_PC:
+ map_quit((struct map_session_data *) bl);
+ break;
+ case BL_NPC:
+ npc_unload((struct npc_data *)bl,false);
+ break;
+ case BL_MOB:
+ unit_free(bl,CLR_OUTSIGHT);
+ break;
+ case BL_PET:
+ //There is no need for this, the pet is removed together with the player. [Skotlex]
+ break;
+ case BL_ITEM:
+ map_clearflooritem(bl);
+ break;
+ case BL_SKILL:
+ skill_delunit((struct skill_unit *) bl);
+ break;
+ }
+
+ return 1;
}
/**
@@ -3504,7 +3541,7 @@ int cleanup_sub(struct block_list *bl, va_list ap)
*/
static int cleanup_db_sub(DBKey key, DBData *data, va_list va)
{
- return cleanup_sub(db_data2ptr(data), va);
+ return cleanup_sub(db_data2ptr(data), va);
}
/*==========================================
@@ -3512,91 +3549,91 @@ static int cleanup_db_sub(DBKey key, DBData *data, va_list va)
*------------------------------------------*/
void do_final(void)
{
- int i, j;
- struct map_session_data *sd;
- struct s_mapiterator *iter;
-
- ShowStatus("Terminating...\n");
-
- //Ladies and babies first.
- iter = mapit_getallusers();
- for (sd = (TBL_PC *)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC *)mapit_next(iter))
- map_quit(sd);
- mapit_free(iter);
-
- /* prepares npcs for a faster shutdown process */
- do_clear_npc();
-
- // remove all objects on maps
- for (i = 0; i < map_num; i++) {
- ShowStatus("Cleaning up maps [%d/%d]: %s..."CL_CLL"\r", i+1, map_num, map[i].name);
- if (map[i].m >= 0)
- map_foreachinmap(cleanup_sub, i, BL_ALL);
- }
- ShowStatus("Cleaned up %d maps."CL_CLL"\n", map_num);
-
- id_db->foreach(id_db,cleanup_db_sub);
- chrif_char_reset_offline();
- chrif_flush_fifo();
-
- do_final_atcommand();
- do_final_battle();
- do_final_chrif();
- do_final_clif();
- do_final_npc();
- do_final_script();
- do_final_instance();
- do_final_itemdb();
- do_final_storage();
- do_final_guild();
- do_final_party();
- do_final_pc();
- do_final_pet();
- do_final_mob();
- do_final_msg();
- do_final_skill();
- do_final_status();
- do_final_unit();
- do_final_battleground();
- do_final_duel();
- do_final_elemental();
-
- map_db->destroy(map_db, map_db_final);
-
- for (i=0; i<map_num; i++) {
- if (map[i].cell) aFree(map[i].cell);
- if (map[i].block) aFree(map[i].block);
- if (map[i].block_mob) aFree(map[i].block_mob);
- if (battle_config.dynamic_mobs) { //Dynamic mobs flag by [random]
- if (map[i].mob_delete_timer != INVALID_TIMER)
- delete_timer(map[i].mob_delete_timer, map_removemobs_timer);
- for (j=0; j<MAX_MOB_LIST_PER_MAP; j++)
- if (map[i].moblist[j]) aFree(map[i].moblist[j]);
- }
- }
-
- mapindex_final();
- if (enable_grf)
- grfio_final();
-
- id_db->destroy(id_db, NULL);
- pc_db->destroy(pc_db, NULL);
- mobid_db->destroy(mobid_db, NULL);
- bossid_db->destroy(bossid_db, NULL);
- nick_db->destroy(nick_db, nick_db_final);
- charid_db->destroy(charid_db, NULL);
- iwall_db->destroy(iwall_db, NULL);
- regen_db->destroy(regen_db, NULL);
+ int i, j;
+ struct map_session_data* sd;
+ struct s_mapiterator* iter;
+
+ ShowStatus("Terminating...\n");
+
+ //Ladies and babies first.
+ iter = mapit_getallusers();
+ for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
+ map_quit(sd);
+ mapit_free(iter);
+
+ /* prepares npcs for a faster shutdown process */
+ do_clear_npc();
+
+ // remove all objects on maps
+ for (i = 0; i < map_num; i++) {
+ ShowStatus("Cleaning up maps [%d/%d]: %s..."CL_CLL"\r", i+1, map_num, map[i].name);
+ if (map[i].m >= 0)
+ map_foreachinmap(cleanup_sub, i, BL_ALL);
+ }
+ ShowStatus("Cleaned up %d maps."CL_CLL"\n", map_num);
+
+ id_db->foreach(id_db,cleanup_db_sub);
+ chrif_char_reset_offline();
+ chrif_flush_fifo();
+
+ do_final_atcommand();
+ do_final_battle();
+ do_final_chrif();
+ do_final_clif();
+ do_final_npc();
+ do_final_script();
+ do_final_instance();
+ do_final_itemdb();
+ do_final_storage();
+ do_final_guild();
+ do_final_party();
+ do_final_pc();
+ do_final_pet();
+ do_final_mob();
+ do_final_msg();
+ do_final_skill();
+ do_final_status();
+ do_final_unit();
+ do_final_battleground();
+ do_final_duel();
+ do_final_elemental();
+
+ map_db->destroy(map_db, map_db_final);
+
+ for (i=0; i<map_num; i++) {
+ if(map[i].cell) aFree(map[i].cell);
+ if(map[i].block) aFree(map[i].block);
+ if(map[i].block_mob) aFree(map[i].block_mob);
+ if(battle_config.dynamic_mobs) { //Dynamic mobs flag by [random]
+ if(map[i].mob_delete_timer != INVALID_TIMER)
+ delete_timer(map[i].mob_delete_timer, map_removemobs_timer);
+ for (j=0; j<MAX_MOB_LIST_PER_MAP; j++)
+ if (map[i].moblist[j]) aFree(map[i].moblist[j]);
+ }
+ }
+
+ mapindex_final();
+ if(enable_grf)
+ grfio_final();
+
+ id_db->destroy(id_db, NULL);
+ pc_db->destroy(pc_db, NULL);
+ mobid_db->destroy(mobid_db, NULL);
+ bossid_db->destroy(bossid_db, NULL);
+ nick_db->destroy(nick_db, nick_db_final);
+ charid_db->destroy(charid_db, NULL);
+ iwall_db->destroy(iwall_db, NULL);
+ regen_db->destroy(regen_db, NULL);
map_sql_close();
- ShowStatus("Finished.\n");
+ ShowStatus("Finished.\n");
}
-static int map_abort_sub(struct map_session_data *sd, va_list ap)
+static int map_abort_sub(struct map_session_data* sd, va_list ap)
{
- chrif_save(sd,1);
- return 1;
+ chrif_save(sd,1);
+ return 1;
}
@@ -3606,21 +3643,22 @@ static int map_abort_sub(struct map_session_data *sd, va_list ap)
//------------------------------
void do_abort(void)
{
- static int run = 0;
- //Save all characters and then flush the inter-connection.
- if (run) {
- ShowFatalError("Server has crashed while trying to save characters. Character data can't be saved!\n");
- return;
- }
- run = 1;
- if (!chrif_isconnected()) {
- if (pc_db->size(pc_db))
- ShowFatalError("Server has crashed without a connection to the char-server, %u characters can't be saved!\n", pc_db->size(pc_db));
- return;
- }
- ShowError("Server received crash signal! Attempting to save all online characters!\n");
- map_foreachpc(map_abort_sub);
- chrif_flush_fifo();
+ static int run = 0;
+ //Save all characters and then flush the inter-connection.
+ if (run) {
+ ShowFatalError("Server has crashed while trying to save characters. Character data can't be saved!\n");
+ return;
+ }
+ run = 1;
+ if (!chrif_isconnected())
+ {
+ if (pc_db->size(pc_db))
+ ShowFatalError("Server has crashed without a connection to the char-server, %u characters can't be saved!\n", pc_db->size(pc_db));
+ return;
+ }
+ ShowError("Server received crash signal! Attempting to save all online characters!\n");
+ map_foreachpc(map_abort_sub);
+ chrif_flush_fifo();
}
/*======================================================
@@ -3628,22 +3666,22 @@ void do_abort(void)
*------------------------------------------------------*/
static void map_helpscreen(bool do_exit)
{
- ShowInfo("Usage: %s [options]\n", SERVER_NAME);
- ShowInfo("\n");
- ShowInfo("Options:\n");
- ShowInfo(" -?, -h [--help]\t\tDisplays this help screen.\n");
- ShowInfo(" -v [--version]\t\tDisplays the server's version.\n");
- ShowInfo(" --run-once\t\t\tCloses server after loading (testing).\n");
- ShowInfo(" --map-config <file>\t\tAlternative map-server configuration.\n");
- ShowInfo(" --battle-config <file>\tAlternative battle configuration.\n");
- ShowInfo(" --atcommand-config <file>\tAlternative atcommand configuration.\n");
- ShowInfo(" --script-config <file>\tAlternative script configuration.\n");
- ShowInfo(" --msg-config <file>\t\tAlternative message configuration.\n");
- ShowInfo(" --grf-path <file>\t\tAlternative GRF path configuration.\n");
- ShowInfo(" --inter-config <file>\t\tAlternative inter-server configuration.\n");
- ShowInfo(" --log-config <file>\t\tAlternative logging configuration.\n");
- if (do_exit)
- exit(EXIT_SUCCESS);
+ ShowInfo("Usage: %s [options]\n", SERVER_NAME);
+ ShowInfo("\n");
+ ShowInfo("Options:\n");
+ ShowInfo(" -?, -h [--help]\t\tDisplays this help screen.\n");
+ ShowInfo(" -v [--version]\t\tDisplays the server's version.\n");
+ ShowInfo(" --run-once\t\t\tCloses server after loading (testing).\n");
+ ShowInfo(" --map-config <file>\t\tAlternative map-server configuration.\n");
+ ShowInfo(" --battle-config <file>\tAlternative battle configuration.\n");
+ ShowInfo(" --atcommand-config <file>\tAlternative atcommand configuration.\n");
+ ShowInfo(" --script-config <file>\tAlternative script configuration.\n");
+ ShowInfo(" --msg-config <file>\t\tAlternative message configuration.\n");
+ ShowInfo(" --grf-path <file>\t\tAlternative GRF path configuration.\n");
+ ShowInfo(" --inter-config <file>\t\tAlternative inter-server configuration.\n");
+ ShowInfo(" --log-config <file>\t\tAlternative logging configuration.\n");
+ if( do_exit )
+ exit(EXIT_SUCCESS);
}
/*======================================================
@@ -3651,12 +3689,12 @@ static void map_helpscreen(bool do_exit)
*------------------------------------------------------*/
static void map_versionscreen(bool do_exit)
{
- ShowInfo(CL_WHITE"rAthena SVN version: %s" CL_RESET"\n", get_svn_revision());
- ShowInfo(CL_GREEN"Website/Forum:"CL_RESET"\thttp://rathena.org/\n");
- ShowInfo(CL_GREEN"IRC Channel:"CL_RESET"\tirc://irc.rathena.net/#rathena\n");
- ShowInfo("Open "CL_WHITE"readme.txt"CL_RESET" for more information.\n");
- if (do_exit)
- exit(EXIT_SUCCESS);
+ ShowInfo(CL_WHITE"rAthena SVN version: %s" CL_RESET"\n", get_svn_revision());
+ ShowInfo(CL_GREEN"Website/Forum:"CL_RESET"\thttp://rathena.org/\n");
+ ShowInfo(CL_GREEN"IRC Channel:"CL_RESET"\tirc://irc.rathena.net/#rathena\n");
+ ShowInfo("Open "CL_WHITE"readme.html"CL_RESET" for more information.\n");
+ if( do_exit )
+ exit(EXIT_SUCCESS);
}
/*======================================================
@@ -3664,219 +3702,249 @@ static void map_versionscreen(bool do_exit)
*------------------------------------------------------*/
void set_server_type(void)
{
- SERVER_TYPE = ATHENA_SERVER_MAP;
+ SERVER_TYPE = ATHENA_SERVER_MAP;
}
/// Called when a terminate signal is received.
void do_shutdown(void)
{
- if (runflag != MAPSERVER_ST_SHUTDOWN) {
- runflag = MAPSERVER_ST_SHUTDOWN;
- ShowStatus("Shutting down...\n");
- {
- struct map_session_data *sd;
- struct s_mapiterator *iter = mapit_getallusers();
- for (sd = (TBL_PC *)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC *)mapit_next(iter))
- clif_GM_kick(NULL, sd);
- mapit_free(iter);
- flush_fifos();
- }
- chrif_check_shutdown();
- }
+ if( runflag != MAPSERVER_ST_SHUTDOWN )
+ {
+ runflag = MAPSERVER_ST_SHUTDOWN;
+ ShowStatus("Shutting down...\n");
+ {
+ struct map_session_data* sd;
+ struct s_mapiterator* iter = mapit_getallusers();
+ for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
+ clif_GM_kick(NULL, sd);
+ mapit_free(iter);
+ flush_fifos();
+ }
+ chrif_check_shutdown();
+ }
}
-static bool map_arg_next_value(const char *option, int i, int argc)
+static bool map_arg_next_value(const char* option, int i, int argc)
{
- if (i >= argc-1) {
- ShowWarning("Missing value for option '%s'.\n", option);
- return false;
- }
+ if( i >= argc-1 )
+ {
+ ShowWarning("Missing value for option '%s'.\n", option);
+ return false;
+ }
- return true;
+ return true;
}
int do_init(int argc, char *argv[])
{
- int i;
+ int i;
#ifdef GCOLLECT
- GC_enable_incremental();
+ GC_enable_incremental();
#endif
- 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";
- SCRIPT_CONF_NAME = "conf/script_athena.conf";
- MSG_CONF_NAME = "conf/msg_athena.conf";
- GRF_PATH_FILENAME = "conf/grf-files.txt";
-
- rnd_init();
-
- for (i = 1; i < argc ; i++) {
- const char *arg = argv[i];
-
- if (arg[0] != '-' && (arg[0] != '/' || arg[1] == '-')) {
- // -, -- and /
- ShowError("Unknown option '%s'.\n", argv[i]);
- exit(EXIT_FAILURE);
- } else if ((++arg)[0] == '-') {
- // long option
- arg++;
-
- if (strcmp(arg, "help") == 0) {
- map_helpscreen(true);
- } else if (strcmp(arg, "version") == 0) {
- map_versionscreen(true);
- } else if (strcmp(arg, "map-config") == 0) {
- if (map_arg_next_value(arg, i, argc))
- MAP_CONF_NAME = argv[++i];
- } else if (strcmp(arg, "battle-config") == 0) {
- if (map_arg_next_value(arg, i, argc))
- BATTLE_CONF_FILENAME = argv[++i];
- } else if (strcmp(arg, "atcommand-config") == 0) {
- if (map_arg_next_value(arg, i, argc))
- ATCOMMAND_CONF_FILENAME = argv[++i];
- } else if (strcmp(arg, "script-config") == 0) {
- if (map_arg_next_value(arg, i, argc))
- SCRIPT_CONF_NAME = argv[++i];
- } else if (strcmp(arg, "msg-config") == 0) {
- if (map_arg_next_value(arg, i, argc))
- MSG_CONF_NAME = argv[++i];
- } else if (strcmp(arg, "grf-path-file") == 0) {
- if (map_arg_next_value(arg, i, argc))
- GRF_PATH_FILENAME = argv[++i];
- } else if (strcmp(arg, "inter-config") == 0) {
- if (map_arg_next_value(arg, i, argc))
- INTER_CONF_NAME = argv[++i];
- } else if (strcmp(arg, "log-config") == 0) {
- if (map_arg_next_value(arg, i, argc))
- LOG_CONF_NAME = argv[++i];
- } else if (strcmp(arg, "run-once") == 0) { // close the map-server as soon as its done.. for testing [Celest]
- runflag = CORE_ST_STOP;
- } else {
- ShowError("Unknown option '%s'.\n", argv[i]);
- exit(EXIT_FAILURE);
- }
- } else switch (arg[0]) {
- // short option
- case '?':
- case 'h':
- map_helpscreen(true);
- break;
- case 'v':
- map_versionscreen(true);
- break;
- default:
- ShowError("Unknown option '%s'.\n", argv[i]);
- exit(EXIT_FAILURE);
- }
- }
-
- map_config_read(MAP_CONF_NAME);
- /* only temporary until sirius's datapack patch is complete */
-
- // loads npcs
- map_reloadnpc(false);
-
- chrif_checkdefaultlogin();
-
- if (!map_ip_set || !char_ip_set) {
- char ip_str[16];
- ip2str(addr_[0], ip_str);
-
- ShowWarning("Not all IP addresses in map_athena.conf configured, autodetecting...\n");
-
- if (naddr_ == 0)
- ShowError("Unable to determine your IP address...\n");
- else if (naddr_ > 1)
- ShowNotice("Multiple interfaces detected...\n");
-
- ShowInfo("Defaulting to %s as our IP address\n", ip_str);
-
- if (!map_ip_set)
- clif_setip(ip_str);
- if (!char_ip_set)
- chrif_setip(ip_str);
- }
-
- battle_config_read(BATTLE_CONF_FILENAME);
- msg_config_read(MSG_CONF_NAME);
- script_config_read(SCRIPT_CONF_NAME);
- inter_config_read(INTER_CONF_NAME);
- log_config_read(LOG_CONF_NAME);
-
- id_db = idb_alloc(DB_OPT_BASE);
- pc_db = idb_alloc(DB_OPT_BASE); //Added for reliable map_id2sd() use. [Skotlex]
- mobid_db = idb_alloc(DB_OPT_BASE); //Added to lower the load of the lazy mob ai. [Skotlex]
- bossid_db = idb_alloc(DB_OPT_BASE); // Used for Convex Mirror quick MVP search
- map_db = uidb_alloc(DB_OPT_BASE);
- nick_db = idb_alloc(DB_OPT_BASE);
- charid_db = idb_alloc(DB_OPT_BASE);
- regen_db = idb_alloc(DB_OPT_BASE); // efficient status_natural_heal processing
-
- iwall_db = strdb_alloc(DB_OPT_RELEASE_DATA,2*NAME_LENGTH+2+1); // [Zephyrus] Invisible Walls
-
- map_sql_init();
- if (log_config.sql_logs)
- log_sql_init();
-
- mapindex_init();
- if (enable_grf)
- grfio_init(GRF_PATH_FILENAME);
-
- map_readallmaps();
-
- add_timer_func_list(map_freeblock_timer, "map_freeblock_timer");
- add_timer_func_list(map_clearflooritem_timer, "map_clearflooritem_timer");
- add_timer_func_list(map_removemobs_timer, "map_removemobs_timer");
- add_timer_interval(gettick()+1000, map_freeblock_timer, 0, 0, 60*1000);
-
- do_init_atcommand();
- do_init_battle();
- do_init_instance();
- do_init_chrif();
- do_init_clif();
- do_init_script();
- do_init_itemdb();
- do_init_skill();
- do_init_mob();
- do_init_pc();
- do_init_status();
- do_init_party();
- do_init_guild();
- do_init_storage();
- do_init_pet();
- do_init_merc();
- do_init_mercenary();
- do_init_elemental();
- do_init_quest();
- do_init_npc();
- do_init_unit();
- do_init_battleground();
- do_init_duel();
-
- npc_event_do_oninit(); // Init npcs (OnInit)
-
- if (console) {
- //##TODO invoke a CONSOLE_START plugin event
- }
-
- if (battle_config.pk_mode)
- ShowNotice("Server is running on '"CL_WHITE"PK Mode"CL_RESET"'.\n");
-
- ShowStatus("Server is '"CL_GREEN"ready"CL_RESET"' and listening on port '"CL_WHITE"%d"CL_RESET"'.\n\n", map_port);
-
- if (runflag != CORE_ST_STOP) {
- shutdown_callback = do_shutdown;
- runflag = MAPSERVER_ST_RUNNING;
- }
+ 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";
+ SCRIPT_CONF_NAME = "conf/script_athena.conf";
+ MSG_CONF_NAME = "conf/msg_athena.conf";
+ GRF_PATH_FILENAME = "conf/grf-files.txt";
+
+ rnd_init();
+
+ for( i = 1; i < argc ; i++ )
+ {
+ const char* arg = argv[i];
+
+ if( arg[0] != '-' && ( arg[0] != '/' || arg[1] == '-' ) )
+ {// -, -- and /
+ ShowError("Unknown option '%s'.\n", argv[i]);
+ exit(EXIT_FAILURE);
+ }
+ else if( (++arg)[0] == '-' )
+ {// long option
+ arg++;
+
+ if( strcmp(arg, "help") == 0 )
+ {
+ map_helpscreen(true);
+ }
+ else if( strcmp(arg, "version") == 0 )
+ {
+ map_versionscreen(true);
+ }
+ else if( strcmp(arg, "map-config") == 0 )
+ {
+ if( map_arg_next_value(arg, i, argc) )
+ MAP_CONF_NAME = argv[++i];
+ }
+ else if( strcmp(arg, "battle-config") == 0 )
+ {
+ if( map_arg_next_value(arg, i, argc) )
+ BATTLE_CONF_FILENAME = argv[++i];
+ }
+ else if( strcmp(arg, "atcommand-config") == 0 )
+ {
+ if( map_arg_next_value(arg, i, argc) )
+ ATCOMMAND_CONF_FILENAME = argv[++i];
+ }
+ else if( strcmp(arg, "script-config") == 0 )
+ {
+ if( map_arg_next_value(arg, i, argc) )
+ SCRIPT_CONF_NAME = argv[++i];
+ }
+ else if( strcmp(arg, "msg-config") == 0 )
+ {
+ if( map_arg_next_value(arg, i, argc) )
+ MSG_CONF_NAME = argv[++i];
+ }
+ else if( strcmp(arg, "grf-path-file") == 0 )
+ {
+ if( map_arg_next_value(arg, i, argc) )
+ GRF_PATH_FILENAME = argv[++i];
+ }
+ else if( strcmp(arg, "inter-config") == 0 )
+ {
+ if( map_arg_next_value(arg, i, argc) )
+ INTER_CONF_NAME = argv[++i];
+ }
+ else if( strcmp(arg, "log-config") == 0 )
+ {
+ if( map_arg_next_value(arg, i, argc) )
+ LOG_CONF_NAME = argv[++i];
+ }
+ else if( strcmp(arg, "run-once") == 0 ) // close the map-server as soon as its done.. for testing [Celest]
+ {
+ runflag = CORE_ST_STOP;
+ }
+ else
+ {
+ ShowError("Unknown option '%s'.\n", argv[i]);
+ exit(EXIT_FAILURE);
+ }
+ }
+ else switch( arg[0] )
+ {// short option
+ case '?':
+ case 'h':
+ map_helpscreen(true);
+ break;
+ case 'v':
+ map_versionscreen(true);
+ break;
+ default:
+ ShowError("Unknown option '%s'.\n", argv[i]);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ map_config_read(MAP_CONF_NAME);
+ /* only temporary until sirius's datapack patch is complete */
+
+ // loads npcs
+ map_reloadnpc(false);
+
+ chrif_checkdefaultlogin();
+
+ if (!map_ip_set || !char_ip_set) {
+ char ip_str[16];
+ ip2str(addr_[0], ip_str);
+
+ ShowWarning("Not all IP addresses in map_athena.conf configured, autodetecting...\n");
+
+ if (naddr_ == 0)
+ ShowError("Unable to determine your IP address...\n");
+ else if (naddr_ > 1)
+ ShowNotice("Multiple interfaces detected...\n");
+
+ ShowInfo("Defaulting to %s as our IP address\n", ip_str);
+
+ if (!map_ip_set)
+ clif_setip(ip_str);
+ if (!char_ip_set)
+ chrif_setip(ip_str);
+ }
+
+ battle_config_read(BATTLE_CONF_FILENAME);
+ msg_config_read(MSG_CONF_NAME);
+ script_config_read(SCRIPT_CONF_NAME);
+ inter_config_read(INTER_CONF_NAME);
+ log_config_read(LOG_CONF_NAME);
+
+ id_db = idb_alloc(DB_OPT_BASE);
+ pc_db = idb_alloc(DB_OPT_BASE); //Added for reliable map_id2sd() use. [Skotlex]
+ mobid_db = idb_alloc(DB_OPT_BASE); //Added to lower the load of the lazy mob ai. [Skotlex]
+ bossid_db = idb_alloc(DB_OPT_BASE); // Used for Convex Mirror quick MVP search
+ map_db = uidb_alloc(DB_OPT_BASE);
+ nick_db = idb_alloc(DB_OPT_BASE);
+ charid_db = idb_alloc(DB_OPT_BASE);
+ regen_db = idb_alloc(DB_OPT_BASE); // efficient status_natural_heal processing
+
+ iwall_db = strdb_alloc(DB_OPT_RELEASE_DATA,2*NAME_LENGTH+2+1); // [Zephyrus] Invisible Walls
+
+ map_sql_init();
+ if (log_config.sql_logs)
+ log_sql_init();
+
+ mapindex_init();
+ if(enable_grf)
+ grfio_init(GRF_PATH_FILENAME);
+
+ map_readallmaps();
+
+ add_timer_func_list(map_freeblock_timer, "map_freeblock_timer");
+ add_timer_func_list(map_clearflooritem_timer, "map_clearflooritem_timer");
+ add_timer_func_list(map_removemobs_timer, "map_removemobs_timer");
+ add_timer_interval(gettick()+1000, map_freeblock_timer, 0, 0, 60*1000);
+
+ do_init_atcommand();
+ do_init_battle();
+ do_init_instance();
+ do_init_chrif();
+ do_init_clif();
+ do_init_script();
+ do_init_itemdb();
+ do_init_skill();
+ do_init_mob();
+ do_init_pc();
+ do_init_status();
+ do_init_party();
+ do_init_guild();
+ do_init_storage();
+ do_init_pet();
+ do_init_merc();
+ do_init_mercenary();
+ do_init_elemental();
+ do_init_quest();
+ do_init_npc();
+ do_init_unit();
+ do_init_battleground();
+ do_init_duel();
+
+ npc_event_do_oninit(); // Init npcs (OnInit)
+
+ if( console )
+ {
+ //##TODO invoke a CONSOLE_START plugin event
+ }
+
+ if (battle_config.pk_mode)
+ ShowNotice("Server is running on '"CL_WHITE"PK Mode"CL_RESET"'.\n");
+
+ ShowStatus("Server is '"CL_GREEN"ready"CL_RESET"' and listening on port '"CL_WHITE"%d"CL_RESET"'.\n\n", map_port);
+
+ if( runflag != CORE_ST_STOP )
+ {
+ shutdown_callback = do_shutdown;
+ runflag = MAPSERVER_ST_RUNNING;
+ }
#if defined(BUILDBOT)
- if (buildbotflag)
- exit(EXIT_FAILURE);
+ if( buildbotflag )
+ exit(EXIT_FAILURE);
#endif
- return 0;
+ return 0;
}
diff --git a/src/map/map.h b/src/map/map.h
index e8c95ed35..b011c8193 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -20,10 +20,11 @@
struct npc_data;
struct item_data;
-enum E_MAPSERVER_ST {
- MAPSERVER_ST_RUNNING = CORE_ST_LAST,
- MAPSERVER_ST_SHUTDOWN,
- MAPSERVER_ST_LAST
+enum E_MAPSERVER_ST
+{
+ MAPSERVER_ST_RUNNING = CORE_ST_LAST,
+ MAPSERVER_ST_SHUTDOWN,
+ MAPSERVER_ST_LAST
};
@@ -82,130 +83,130 @@ enum MOBID {
//Note the oddity of the novice:
//Super Novices are considered the 2-1 version of the novice! Novices are considered a first class type, too...
enum {
- //Novice And 1-1 Jobs
- MAPID_NOVICE = 0x0,
- MAPID_SWORDMAN,
- MAPID_MAGE,
- MAPID_ARCHER,
- MAPID_ACOLYTE,
- MAPID_MERCHANT,
- MAPID_THIEF,
- MAPID_TAEKWON,
- MAPID_WEDDING,
- MAPID_GUNSLINGER,
- MAPID_NINJA,
- MAPID_XMAS,
- MAPID_SUMMER,
- MAPID_GANGSI,
- //2-1 Jobs
- MAPID_SUPER_NOVICE = JOBL_2_1|0x0,
- MAPID_KNIGHT,
- MAPID_WIZARD,
- MAPID_HUNTER,
- MAPID_PRIEST,
- MAPID_BLACKSMITH,
- MAPID_ASSASSIN,
- MAPID_STAR_GLADIATOR,
- MAPID_KAGEROUOBORO = JOBL_2_1|0x0A,
- MAPID_DEATH_KNIGHT = JOBL_2_1|0x0D,
- //2-2 Jobs
- MAPID_CRUSADER = JOBL_2_2|0x1,
- MAPID_SAGE,
- MAPID_BARDDANCER,
- MAPID_MONK,
- MAPID_ALCHEMIST,
- MAPID_ROGUE,
- MAPID_SOUL_LINKER,
- MAPID_DARK_COLLECTOR = JOBL_2_2|0x0D,
- //Trans Novice And Trans 1-1 Jobs
- MAPID_NOVICE_HIGH = JOBL_UPPER|0x0,
- MAPID_SWORDMAN_HIGH,
- MAPID_MAGE_HIGH,
- MAPID_ARCHER_HIGH,
- MAPID_ACOLYTE_HIGH,
- MAPID_MERCHANT_HIGH,
- MAPID_THIEF_HIGH,
- //Trans 2-1 Jobs
- MAPID_LORD_KNIGHT = JOBL_UPPER|JOBL_2_1|0x1,
- MAPID_HIGH_WIZARD,
- MAPID_SNIPER,
- MAPID_HIGH_PRIEST,
- MAPID_WHITESMITH,
- MAPID_ASSASSIN_CROSS,
- //Trans 2-2 Jobs
- MAPID_PALADIN = JOBL_UPPER|JOBL_2_2|0x1,
- MAPID_PROFESSOR,
- MAPID_CLOWNGYPSY,
- MAPID_CHAMPION,
- MAPID_CREATOR,
- MAPID_STALKER,
- //Baby Novice And Baby 1-1 Jobs
- MAPID_BABY = JOBL_BABY|0x0,
- MAPID_BABY_SWORDMAN,
- MAPID_BABY_MAGE,
- MAPID_BABY_ARCHER,
- MAPID_BABY_ACOLYTE,
- MAPID_BABY_MERCHANT,
- MAPID_BABY_THIEF,
- //Baby 2-1 Jobs
- MAPID_SUPER_BABY = JOBL_BABY|JOBL_2_1|0x0,
- MAPID_BABY_KNIGHT,
- MAPID_BABY_WIZARD,
- MAPID_BABY_HUNTER,
- MAPID_BABY_PRIEST,
- MAPID_BABY_BLACKSMITH,
- MAPID_BABY_ASSASSIN,
- //Baby 2-2 Jobs
- MAPID_BABY_CRUSADER = JOBL_BABY|JOBL_2_2|0x1,
- MAPID_BABY_SAGE,
- MAPID_BABY_BARDDANCER,
- MAPID_BABY_MONK,
- MAPID_BABY_ALCHEMIST,
- MAPID_BABY_ROGUE,
- //3-1 Jobs
- MAPID_SUPER_NOVICE_E = JOBL_THIRD|JOBL_2_1|0x0,
- MAPID_RUNE_KNIGHT,
- MAPID_WARLOCK,
- MAPID_RANGER,
- MAPID_ARCH_BISHOP,
- MAPID_MECHANIC,
- MAPID_GUILLOTINE_CROSS,
- //3-2 Jobs
- MAPID_ROYAL_GUARD = JOBL_THIRD|JOBL_2_2|0x1,
- MAPID_SORCERER,
- MAPID_MINSTRELWANDERER,
- MAPID_SURA,
- MAPID_GENETIC,
- MAPID_SHADOW_CHASER,
- //Trans 3-1 Jobs
- MAPID_RUNE_KNIGHT_T = JOBL_THIRD|JOBL_UPPER|JOBL_2_1|0x1,
- MAPID_WARLOCK_T,
- MAPID_RANGER_T,
- MAPID_ARCH_BISHOP_T,
- MAPID_MECHANIC_T,
- MAPID_GUILLOTINE_CROSS_T,
- //Trans 3-2 Jobs
- MAPID_ROYAL_GUARD_T = JOBL_THIRD|JOBL_UPPER|JOBL_2_2|0x1,
- MAPID_SORCERER_T,
- MAPID_MINSTRELWANDERER_T,
- MAPID_SURA_T,
- MAPID_GENETIC_T,
- MAPID_SHADOW_CHASER_T,
- //Baby 3-1 Jobs
- MAPID_SUPER_BABY_E = JOBL_THIRD|JOBL_BABY|JOBL_2_1|0x0,
- MAPID_BABY_RUNE,
- MAPID_BABY_WARLOCK,
- MAPID_BABY_RANGER,
- MAPID_BABY_BISHOP,
- MAPID_BABY_MECHANIC,
- MAPID_BABY_CROSS,
- //Baby 3-2 Jobs
- MAPID_BABY_GUARD = JOBL_THIRD|JOBL_BABY|JOBL_2_2|0x1,
- MAPID_BABY_SORCERER,
- MAPID_BABY_MINSTRELWANDERER,
- MAPID_BABY_SURA,
- MAPID_BABY_GENETIC,
- MAPID_BABY_CHASER,
+//Novice And 1-1 Jobs
+ MAPID_NOVICE = 0x0,
+ MAPID_SWORDMAN,
+ MAPID_MAGE,
+ MAPID_ARCHER,
+ MAPID_ACOLYTE,
+ MAPID_MERCHANT,
+ MAPID_THIEF,
+ MAPID_TAEKWON,
+ MAPID_WEDDING,
+ MAPID_GUNSLINGER,
+ MAPID_NINJA,
+ MAPID_XMAS,
+ MAPID_SUMMER,
+ MAPID_GANGSI,
+//2-1 Jobs
+ MAPID_SUPER_NOVICE = JOBL_2_1|0x0,
+ MAPID_KNIGHT,
+ MAPID_WIZARD,
+ MAPID_HUNTER,
+ MAPID_PRIEST,
+ MAPID_BLACKSMITH,
+ MAPID_ASSASSIN,
+ MAPID_STAR_GLADIATOR,
+ MAPID_KAGEROUOBORO = JOBL_2_1|0x0A,
+ MAPID_DEATH_KNIGHT = JOBL_2_1|0x0D,
+//2-2 Jobs
+ MAPID_CRUSADER = JOBL_2_2|0x1,
+ MAPID_SAGE,
+ MAPID_BARDDANCER,
+ MAPID_MONK,
+ MAPID_ALCHEMIST,
+ MAPID_ROGUE,
+ MAPID_SOUL_LINKER,
+ MAPID_DARK_COLLECTOR = JOBL_2_2|0x0D,
+//Trans Novice And Trans 1-1 Jobs
+ MAPID_NOVICE_HIGH = JOBL_UPPER|0x0,
+ MAPID_SWORDMAN_HIGH,
+ MAPID_MAGE_HIGH,
+ MAPID_ARCHER_HIGH,
+ MAPID_ACOLYTE_HIGH,
+ MAPID_MERCHANT_HIGH,
+ MAPID_THIEF_HIGH,
+//Trans 2-1 Jobs
+ MAPID_LORD_KNIGHT = JOBL_UPPER|JOBL_2_1|0x1,
+ MAPID_HIGH_WIZARD,
+ MAPID_SNIPER,
+ MAPID_HIGH_PRIEST,
+ MAPID_WHITESMITH,
+ MAPID_ASSASSIN_CROSS,
+//Trans 2-2 Jobs
+ MAPID_PALADIN = JOBL_UPPER|JOBL_2_2|0x1,
+ MAPID_PROFESSOR,
+ MAPID_CLOWNGYPSY,
+ MAPID_CHAMPION,
+ MAPID_CREATOR,
+ MAPID_STALKER,
+//Baby Novice And Baby 1-1 Jobs
+ MAPID_BABY = JOBL_BABY|0x0,
+ MAPID_BABY_SWORDMAN,
+ MAPID_BABY_MAGE,
+ MAPID_BABY_ARCHER,
+ MAPID_BABY_ACOLYTE,
+ MAPID_BABY_MERCHANT,
+ MAPID_BABY_THIEF,
+//Baby 2-1 Jobs
+ MAPID_SUPER_BABY = JOBL_BABY|JOBL_2_1|0x0,
+ MAPID_BABY_KNIGHT,
+ MAPID_BABY_WIZARD,
+ MAPID_BABY_HUNTER,
+ MAPID_BABY_PRIEST,
+ MAPID_BABY_BLACKSMITH,
+ MAPID_BABY_ASSASSIN,
+//Baby 2-2 Jobs
+ MAPID_BABY_CRUSADER = JOBL_BABY|JOBL_2_2|0x1,
+ MAPID_BABY_SAGE,
+ MAPID_BABY_BARDDANCER,
+ MAPID_BABY_MONK,
+ MAPID_BABY_ALCHEMIST,
+ MAPID_BABY_ROGUE,
+//3-1 Jobs
+ MAPID_SUPER_NOVICE_E = JOBL_THIRD|JOBL_2_1|0x0,
+ MAPID_RUNE_KNIGHT,
+ MAPID_WARLOCK,
+ MAPID_RANGER,
+ MAPID_ARCH_BISHOP,
+ MAPID_MECHANIC,
+ MAPID_GUILLOTINE_CROSS,
+//3-2 Jobs
+ MAPID_ROYAL_GUARD = JOBL_THIRD|JOBL_2_2|0x1,
+ MAPID_SORCERER,
+ MAPID_MINSTRELWANDERER,
+ MAPID_SURA,
+ MAPID_GENETIC,
+ MAPID_SHADOW_CHASER,
+//Trans 3-1 Jobs
+ MAPID_RUNE_KNIGHT_T = JOBL_THIRD|JOBL_UPPER|JOBL_2_1|0x1,
+ MAPID_WARLOCK_T,
+ MAPID_RANGER_T,
+ MAPID_ARCH_BISHOP_T,
+ MAPID_MECHANIC_T,
+ MAPID_GUILLOTINE_CROSS_T,
+//Trans 3-2 Jobs
+ MAPID_ROYAL_GUARD_T = JOBL_THIRD|JOBL_UPPER|JOBL_2_2|0x1,
+ MAPID_SORCERER_T,
+ MAPID_MINSTRELWANDERER_T,
+ MAPID_SURA_T,
+ MAPID_GENETIC_T,
+ MAPID_SHADOW_CHASER_T,
+//Baby 3-1 Jobs
+ MAPID_SUPER_BABY_E = JOBL_THIRD|JOBL_BABY|JOBL_2_1|0x0,
+ MAPID_BABY_RUNE,
+ MAPID_BABY_WARLOCK,
+ MAPID_BABY_RANGER,
+ MAPID_BABY_BISHOP,
+ MAPID_BABY_MECHANIC,
+ MAPID_BABY_CROSS,
+//Baby 3-2 Jobs
+ MAPID_BABY_GUARD = JOBL_THIRD|JOBL_BABY|JOBL_2_2|0x1,
+ MAPID_BABY_SORCERER,
+ MAPID_BABY_MINSTRELWANDERER,
+ MAPID_BABY_SURA,
+ MAPID_BABY_GENETIC,
+ MAPID_BABY_CHASER,
};
//Max size for inputs to Graffiti, Talkie Box and Vending text prompts
@@ -234,19 +235,19 @@ enum {
//This stackable implementation does not means a BL can be more than one type at a time, but it's
//meant to make it easier to check for multiple types at a time on invocations such as map_foreach* calls [Skotlex]
enum bl_type {
- BL_NUL = 0x000,
- BL_PC = 0x001,
- BL_MOB = 0x002,
- BL_PET = 0x004,
- BL_HOM = 0x008,
- BL_MER = 0x010,
- BL_ITEM = 0x020,
- BL_SKILL = 0x040,
- BL_NPC = 0x080,
- BL_CHAT = 0x100,
- BL_ELEM = 0x200,
-
- BL_ALL = 0xFFF,
+ BL_NUL = 0x000,
+ BL_PC = 0x001,
+ BL_MOB = 0x002,
+ BL_PET = 0x004,
+ BL_HOM = 0x008,
+ BL_MER = 0x010,
+ BL_ITEM = 0x020,
+ BL_SKILL = 0x040,
+ BL_NPC = 0x080,
+ BL_CHAT = 0x100,
+ BL_ELEM = 0x200,
+
+ BL_ALL = 0xFFF,
};
//For common mapforeach calls. Since pets cannot be affected, they aren't included here yet.
@@ -255,349 +256,350 @@ enum bl_type {
enum npc_subtype { WARP, SHOP, SCRIPT, CASHSHOP, TOMB };
enum {
- RC_FORMLESS=0,
- RC_UNDEAD,
- RC_BRUTE,
- RC_PLANT,
- RC_INSECT,
- RC_FISH,
- RC_DEMON,
- RC_DEMIHUMAN,
- RC_ANGEL,
- RC_DRAGON,
- RC_BOSS,
- RC_NONBOSS,
- RC_NONDEMIHUMAN,
- RC_MAX
+ RC_FORMLESS=0,
+ RC_UNDEAD,
+ RC_BRUTE,
+ RC_PLANT,
+ RC_INSECT,
+ RC_FISH,
+ RC_DEMON,
+ RC_DEMIHUMAN,
+ RC_ANGEL,
+ RC_DRAGON,
+ RC_BOSS,
+ RC_NONBOSS,
+ RC_NONDEMIHUMAN,
+ RC_MAX
};
enum {
- RC2_NONE = 0,
- RC2_GOBLIN,
- RC2_KOBOLD,
- RC2_ORC,
- RC2_GOLEM,
- RC2_GUARDIAN,
- RC2_NINJA,
- RC2_MAX
+ RC2_NONE = 0,
+ RC2_GOBLIN,
+ RC2_KOBOLD,
+ RC2_ORC,
+ RC2_GOLEM,
+ RC2_GUARDIAN,
+ RC2_NINJA,
+ RC2_MAX
};
enum {
- ELE_NEUTRAL=0,
- ELE_WATER,
- ELE_EARTH,
- ELE_FIRE,
- ELE_WIND,
- ELE_POISON,
- ELE_HOLY,
- ELE_DARK,
- ELE_GHOST,
- ELE_UNDEAD,
- ELE_MAX
+ ELE_NEUTRAL=0,
+ ELE_WATER,
+ ELE_EARTH,
+ ELE_FIRE,
+ ELE_WIND,
+ ELE_POISON,
+ ELE_HOLY,
+ ELE_DARK,
+ ELE_GHOST,
+ ELE_UNDEAD,
+ ELE_MAX
};
enum auto_trigger_flag {
- ATF_SELF=0x01,
- ATF_TARGET=0x02,
- ATF_SHORT=0x04,
- ATF_LONG=0x08,
- ATF_WEAPON=0x10,
- ATF_MAGIC=0x20,
- ATF_MISC=0x40,
+ ATF_SELF=0x01,
+ ATF_TARGET=0x02,
+ ATF_SHORT=0x04,
+ ATF_LONG=0x08,
+ ATF_WEAPON=0x10,
+ ATF_MAGIC=0x20,
+ ATF_MISC=0x40,
};
struct block_list {
- struct block_list *next,*prev;
- int id;
- short m,x,y;
- enum bl_type type;
+ struct block_list *next,*prev;
+ int id;
+ short m,x,y;
+ enum bl_type type;
};
// Mob List Held in memory for Dynamic Mobs [Wizputer]
// Expanded to specify all mob-related spawn data by [Skotlex]
struct spawn_data {
- short class_; //Class, used because a mob can change it's class
- unsigned short m, x, y; //Spawn information (map, point, spawn-area around point)
- signed short xs, ys;
- unsigned short num; //Number of mobs using this structure
- unsigned short active;//Number of mobs that are already spawned (for mob_remove_damaged: no)
- unsigned int delay1, delay2; //Spawn delay (fixed base + random variance)
- unsigned int level;
- struct {
- unsigned int size : 2; //Holds if mob has to be tiny/large
- unsigned int ai : 4; //Special ai for summoned monsters.
- //0: Normal mob | 1: Standard summon, attacks mobs
- //2: Alchemist Marine Sphere | 3: Alchemist Summon Flora | 4: Summon Zanzou
- unsigned int dynamic : 1; //Whether this data is indexed by a map's dynamic mob list
- unsigned int boss : 1; //0: Non-boss monster | 1: Boss monster
- } state;
- char name[NAME_LENGTH], eventname[EVENT_NAME_LENGTH]; //Name/event
+ short class_; //Class, used because a mob can change it's class
+ unsigned short m, x, y; //Spawn information (map, point, spawn-area around point)
+ signed short xs, ys;
+ unsigned short num; //Number of mobs using this structure
+ unsigned short active;//Number of mobs that are already spawned (for mob_remove_damaged: no)
+ unsigned int delay1, delay2; //Spawn delay (fixed base + random variance)
+ unsigned int level;
+ struct {
+ unsigned int size : 2; //Holds if mob has to be tiny/large
+ unsigned int ai : 4; //Special ai for summoned monsters.
+ //0: Normal mob | 1: Standard summon, attacks mobs
+ //2: Alchemist Marine Sphere | 3: Alchemist Summon Flora | 4: Summon Zanzou
+ unsigned int dynamic : 1; //Whether this data is indexed by a map's dynamic mob list
+ unsigned int boss : 1; //0: Non-boss monster | 1: Boss monster
+ } state;
+ char name[NAME_LENGTH], eventname[EVENT_NAME_LENGTH]; //Name/event
};
struct flooritem_data {
- struct block_list bl;
- unsigned char subx,suby;
- int cleartimer;
- int first_get_charid,second_get_charid,third_get_charid;
- unsigned int first_get_tick,second_get_tick,third_get_tick;
- struct item item_data;
+ struct block_list bl;
+ unsigned char subx,suby;
+ int cleartimer;
+ int first_get_charid,second_get_charid,third_get_charid;
+ unsigned int first_get_tick,second_get_tick,third_get_tick;
+ struct item item_data;
};
enum _sp {
- SP_SPEED,SP_BASEEXP,SP_JOBEXP,SP_KARMA,SP_MANNER,SP_HP,SP_MAXHP,SP_SP, // 0-7
- SP_MAXSP,SP_STATUSPOINT,SP_0a,SP_BASELEVEL,SP_SKILLPOINT,SP_STR,SP_AGI,SP_VIT, // 8-15
- SP_INT,SP_DEX,SP_LUK,SP_CLASS,SP_ZENY,SP_SEX,SP_NEXTBASEEXP,SP_NEXTJOBEXP, // 16-23
- SP_WEIGHT,SP_MAXWEIGHT,SP_1a,SP_1b,SP_1c,SP_1d,SP_1e,SP_1f, // 24-31
- 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-60
- SP_CARTINFO=99, // 99
-
- SP_BASEJOB=119, // 100+19 - celest
- SP_BASECLASS=120, //Hmm.. why 100+19? I just use the next one... [Skotlex]
- SP_KILLERRID=121,
- SP_KILLEDRID=122,
-
- // Mercenaries
- SP_MERCFLEE=165, SP_MERCKILLS=189, SP_MERCFAITH=190,
-
- // original 1000-
- SP_ATTACKRANGE=1000, SP_ATKELE,SP_DEFELE, // 1000-1002
- SP_CASTRATE, SP_MAXHPRATE, SP_MAXSPRATE, SP_SPRATE, // 1003-1006
- SP_ADDELE, SP_ADDRACE, SP_ADDSIZE, SP_SUBELE, SP_SUBRACE, // 1007-1011
- SP_ADDEFF, SP_RESEFF, // 1012-1013
- SP_BASE_ATK,SP_ASPD_RATE,SP_HP_RECOV_RATE,SP_SP_RECOV_RATE,SP_SPEED_RATE, // 1014-1018
- SP_CRITICAL_DEF,SP_NEAR_ATK_DEF,SP_LONG_ATK_DEF, // 1019-1021
- SP_DOUBLE_RATE, SP_DOUBLE_ADD_RATE, SP_SKILL_HEAL, SP_MATK_RATE, // 1022-1025
- SP_IGNORE_DEF_ELE,SP_IGNORE_DEF_RACE, // 1026-1027
- SP_ATK_RATE,SP_SPEED_ADDRATE,SP_SP_REGEN_RATE, // 1028-1030
- SP_MAGIC_ATK_DEF,SP_MISC_ATK_DEF, // 1031-1032
- SP_IGNORE_MDEF_ELE,SP_IGNORE_MDEF_RACE, // 1033-1034
- SP_MAGIC_ADDELE,SP_MAGIC_ADDRACE,SP_MAGIC_ADDSIZE, // 1035-1037
- SP_PERFECT_HIT_RATE,SP_PERFECT_HIT_ADD_RATE,SP_CRITICAL_RATE,SP_GET_ZENY_NUM,SP_ADD_GET_ZENY_NUM, // 1038-1042
- SP_ADD_DAMAGE_CLASS,SP_ADD_MAGIC_DAMAGE_CLASS,SP_ADD_DEF_CLASS,SP_ADD_MDEF_CLASS, // 1043-1046
- SP_ADD_MONSTER_DROP_ITEM,SP_DEF_RATIO_ATK_ELE,SP_DEF_RATIO_ATK_RACE,SP_UNBREAKABLE_GARMENT, // 1047-1050
- SP_HIT_RATE,SP_FLEE_RATE,SP_FLEE2_RATE,SP_DEF_RATE,SP_DEF2_RATE,SP_MDEF_RATE,SP_MDEF2_RATE, // 1051-1057
- SP_SPLASH_RANGE,SP_SPLASH_ADD_RANGE,SP_AUTOSPELL,SP_HP_DRAIN_RATE,SP_SP_DRAIN_RATE, // 1058-1062
- SP_SHORT_WEAPON_DAMAGE_RETURN,SP_LONG_WEAPON_DAMAGE_RETURN,SP_WEAPON_COMA_ELE,SP_WEAPON_COMA_RACE, // 1063-1066
- SP_ADDEFF2,SP_BREAK_WEAPON_RATE,SP_BREAK_ARMOR_RATE,SP_ADD_STEAL_RATE, // 1067-1070
- SP_MAGIC_DAMAGE_RETURN,SP_ALL_STATS=1073,SP_AGI_VIT,SP_AGI_DEX_STR,SP_PERFECT_HIDE, // 1071-1076
- SP_NO_KNOCKBACK,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,SP_HP_DRAIN_RATE_RACE,SP_SP_DRAIN_RATE_RACE, // 1083-1085
- SP_IGNORE_MDEF_RATE,SP_IGNORE_DEF_RATE,SP_SKILL_HEAL2,SP_ADDEFF_ONSKILL, //1086-1089
- SP_ADD_HEAL_RATE,SP_ADD_HEAL2_RATE, //1090-1091
-
- SP_RESTART_FULL_RECOVER=2000,SP_NO_CASTCANCEL,SP_NO_SIZEFIX,SP_NO_MAGIC_DAMAGE,SP_NO_WEAPON_DAMAGE,SP_NO_GEMSTONE, // 2000-2005
- SP_NO_CASTCANCEL2,SP_NO_MISC_DAMAGE,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_AUTOSPELL_ONSKILL, // 2018-2020
- SP_SP_GAIN_VALUE, SP_HP_REGEN_RATE, SP_HP_LOSS_RATE, SP_ADDRACE2, SP_HP_GAIN_VALUE, // 2021-2025
- SP_SUBSIZE, SP_HP_DRAIN_VALUE_RACE, SP_ADD_ITEM_HEAL_RATE, SP_SP_DRAIN_VALUE_RACE, SP_EXP_ADDRACE, // 2026-2030
- SP_SP_GAIN_RACE, SP_SUBRACE2, SP_UNBREAKABLE_SHOES, // 2031-2033
- SP_UNSTRIPABLE_WEAPON,SP_UNSTRIPABLE_ARMOR,SP_UNSTRIPABLE_HELM,SP_UNSTRIPABLE_SHIELD, // 2034-2037
- SP_INTRAVISION, SP_ADD_MONSTER_DROP_ITEMGROUP, SP_SP_LOSS_RATE, // 2038-2040
- SP_ADD_SKILL_BLOW, SP_SP_VANISH_RATE, SP_MAGIC_SP_GAIN_VALUE, SP_MAGIC_HP_GAIN_VALUE, SP_ADD_CLASS_DROP_ITEM, //2041-2045
- SP_EMATK, SP_SP_GAIN_RACE_ATTACK, SP_HP_GAIN_RACE_ATTACK, SP_SKILL_USE_SP_RATE, //2046-2049
- SP_SKILL_COOLDOWN,SP_SKILL_FIXEDCAST, SP_SKILL_VARIABLECAST, SP_FIXCASTRATE, SP_VARCASTRATE, //2050-2054
- SP_SKILL_USE_SP //2055
+ SP_SPEED,SP_BASEEXP,SP_JOBEXP,SP_KARMA,SP_MANNER,SP_HP,SP_MAXHP,SP_SP, // 0-7
+ SP_MAXSP,SP_STATUSPOINT,SP_0a,SP_BASELEVEL,SP_SKILLPOINT,SP_STR,SP_AGI,SP_VIT, // 8-15
+ SP_INT,SP_DEX,SP_LUK,SP_CLASS,SP_ZENY,SP_SEX,SP_NEXTBASEEXP,SP_NEXTJOBEXP, // 16-23
+ SP_WEIGHT,SP_MAXWEIGHT,SP_1a,SP_1b,SP_1c,SP_1d,SP_1e,SP_1f, // 24-31
+ 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-60
+ SP_CARTINFO=99, // 99
+
+ SP_BASEJOB=119, // 100+19 - celest
+ SP_BASECLASS=120, //Hmm.. why 100+19? I just use the next one... [Skotlex]
+ SP_KILLERRID=121,
+ SP_KILLEDRID=122,
+
+ // Mercenaries
+ SP_MERCFLEE=165, SP_MERCKILLS=189, SP_MERCFAITH=190,
+
+ // original 1000-
+ SP_ATTACKRANGE=1000, SP_ATKELE,SP_DEFELE, // 1000-1002
+ SP_CASTRATE, SP_MAXHPRATE, SP_MAXSPRATE, SP_SPRATE, // 1003-1006
+ SP_ADDELE, SP_ADDRACE, SP_ADDSIZE, SP_SUBELE, SP_SUBRACE, // 1007-1011
+ SP_ADDEFF, SP_RESEFF, // 1012-1013
+ SP_BASE_ATK,SP_ASPD_RATE,SP_HP_RECOV_RATE,SP_SP_RECOV_RATE,SP_SPEED_RATE, // 1014-1018
+ SP_CRITICAL_DEF,SP_NEAR_ATK_DEF,SP_LONG_ATK_DEF, // 1019-1021
+ SP_DOUBLE_RATE, SP_DOUBLE_ADD_RATE, SP_SKILL_HEAL, SP_MATK_RATE, // 1022-1025
+ SP_IGNORE_DEF_ELE,SP_IGNORE_DEF_RACE, // 1026-1027
+ SP_ATK_RATE,SP_SPEED_ADDRATE,SP_SP_REGEN_RATE, // 1028-1030
+ SP_MAGIC_ATK_DEF,SP_MISC_ATK_DEF, // 1031-1032
+ SP_IGNORE_MDEF_ELE,SP_IGNORE_MDEF_RACE, // 1033-1034
+ SP_MAGIC_ADDELE,SP_MAGIC_ADDRACE,SP_MAGIC_ADDSIZE, // 1035-1037
+ SP_PERFECT_HIT_RATE,SP_PERFECT_HIT_ADD_RATE,SP_CRITICAL_RATE,SP_GET_ZENY_NUM,SP_ADD_GET_ZENY_NUM, // 1038-1042
+ SP_ADD_DAMAGE_CLASS,SP_ADD_MAGIC_DAMAGE_CLASS,SP_ADD_DEF_CLASS,SP_ADD_MDEF_CLASS, // 1043-1046
+ SP_ADD_MONSTER_DROP_ITEM,SP_DEF_RATIO_ATK_ELE,SP_DEF_RATIO_ATK_RACE,SP_UNBREAKABLE_GARMENT, // 1047-1050
+ SP_HIT_RATE,SP_FLEE_RATE,SP_FLEE2_RATE,SP_DEF_RATE,SP_DEF2_RATE,SP_MDEF_RATE,SP_MDEF2_RATE, // 1051-1057
+ SP_SPLASH_RANGE,SP_SPLASH_ADD_RANGE,SP_AUTOSPELL,SP_HP_DRAIN_RATE,SP_SP_DRAIN_RATE, // 1058-1062
+ SP_SHORT_WEAPON_DAMAGE_RETURN,SP_LONG_WEAPON_DAMAGE_RETURN,SP_WEAPON_COMA_ELE,SP_WEAPON_COMA_RACE, // 1063-1066
+ SP_ADDEFF2,SP_BREAK_WEAPON_RATE,SP_BREAK_ARMOR_RATE,SP_ADD_STEAL_RATE, // 1067-1070
+ SP_MAGIC_DAMAGE_RETURN,SP_ALL_STATS=1073,SP_AGI_VIT,SP_AGI_DEX_STR,SP_PERFECT_HIDE, // 1071-1076
+ SP_NO_KNOCKBACK,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,SP_HP_DRAIN_RATE_RACE,SP_SP_DRAIN_RATE_RACE, // 1083-1085
+ SP_IGNORE_MDEF_RATE,SP_IGNORE_DEF_RATE,SP_SKILL_HEAL2,SP_ADDEFF_ONSKILL, //1086-1089
+ SP_ADD_HEAL_RATE,SP_ADD_HEAL2_RATE, //1090-1091
+
+ SP_RESTART_FULL_RECOVER=2000,SP_NO_CASTCANCEL,SP_NO_SIZEFIX,SP_NO_MAGIC_DAMAGE,SP_NO_WEAPON_DAMAGE,SP_NO_GEMSTONE, // 2000-2005
+ SP_NO_CASTCANCEL2,SP_NO_MISC_DAMAGE,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_AUTOSPELL_ONSKILL, // 2018-2020
+ SP_SP_GAIN_VALUE, SP_HP_REGEN_RATE, SP_HP_LOSS_RATE, SP_ADDRACE2, SP_HP_GAIN_VALUE, // 2021-2025
+ SP_SUBSIZE, SP_HP_DRAIN_VALUE_RACE, SP_ADD_ITEM_HEAL_RATE, SP_SP_DRAIN_VALUE_RACE, SP_EXP_ADDRACE, // 2026-2030
+ SP_SP_GAIN_RACE, SP_SUBRACE2, SP_UNBREAKABLE_SHOES, // 2031-2033
+ SP_UNSTRIPABLE_WEAPON,SP_UNSTRIPABLE_ARMOR,SP_UNSTRIPABLE_HELM,SP_UNSTRIPABLE_SHIELD, // 2034-2037
+ SP_INTRAVISION, SP_ADD_MONSTER_DROP_ITEMGROUP, SP_SP_LOSS_RATE, // 2038-2040
+ SP_ADD_SKILL_BLOW, SP_SP_VANISH_RATE, SP_MAGIC_SP_GAIN_VALUE, SP_MAGIC_HP_GAIN_VALUE, SP_ADD_CLASS_DROP_ITEM, //2041-2045
+ SP_WEAPON_MATK, SP_BASE_MATK, SP_SP_GAIN_RACE_ATTACK, SP_HP_GAIN_RACE_ATTACK, SP_SKILL_USE_SP_RATE, //2046-2050
+ SP_SKILL_COOLDOWN,SP_SKILL_FIXEDCAST, SP_SKILL_VARIABLECAST, SP_FIXCASTRATE, SP_VARCASTRATE, //2051-2055
+ SP_SKILL_USE_SP //2056
};
enum _look {
- 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,
- LOOK_BODY,
- LOOK_FLOOR,
- LOOK_ROBE,
+ 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,
+ LOOK_BODY,
+ LOOK_FLOOR,
+ LOOK_ROBE,
};
// used by map_setcell()
typedef enum {
- CELL_WALKABLE,
- CELL_SHOOTABLE,
- CELL_WATER,
-
- CELL_NPC,
- CELL_BASILICA,
- CELL_LANDPROTECTOR,
- CELL_NOVENDING,
- CELL_NOCHAT,
- CELL_MAELSTROM,
- CELL_ICEWALL,
+ CELL_WALKABLE,
+ CELL_SHOOTABLE,
+ CELL_WATER,
+
+ CELL_NPC,
+ CELL_BASILICA,
+ CELL_LANDPROTECTOR,
+ CELL_NOVENDING,
+ CELL_NOCHAT,
+ CELL_MAELSTROM,
+ CELL_ICEWALL,
} cell_t;
// used by map_getcell()
typedef enum {
- CELL_GETTYPE, // retrieves a cell's 'gat' type
-
- CELL_CHKWALL, // wall (gat type 1)
- CELL_CHKWATER, // water (gat type 3)
- CELL_CHKCLIFF, // cliff/gap (gat type 5)
-
- CELL_CHKPASS, // passable cell (gat type non-1/5)
- CELL_CHKREACH, // Same as PASS, but ignores the cell-stacking mod.
- CELL_CHKNOPASS, // non-passable cell (gat types 1 and 5)
- CELL_CHKNOREACH, // Same as NOPASS, but ignores the cell-stacking mod.
- CELL_CHKSTACK, // whether cell is full (reached cell stacking limit)
-
- CELL_CHKNPC,
- CELL_CHKBASILICA,
- CELL_CHKLANDPROTECTOR,
- CELL_CHKNOVENDING,
- CELL_CHKNOCHAT,
- CELL_CHKMAELSTROM,
- CELL_CHKICEWALL,
+ CELL_GETTYPE, // retrieves a cell's 'gat' type
+
+ CELL_CHKWALL, // wall (gat type 1)
+ CELL_CHKWATER, // water (gat type 3)
+ CELL_CHKCLIFF, // cliff/gap (gat type 5)
+
+ CELL_CHKPASS, // passable cell (gat type non-1/5)
+ CELL_CHKREACH, // Same as PASS, but ignores the cell-stacking mod.
+ CELL_CHKNOPASS, // non-passable cell (gat types 1 and 5)
+ CELL_CHKNOREACH, // Same as NOPASS, but ignores the cell-stacking mod.
+ CELL_CHKSTACK, // whether cell is full (reached cell stacking limit)
+
+ CELL_CHKNPC,
+ CELL_CHKBASILICA,
+ CELL_CHKLANDPROTECTOR,
+ CELL_CHKNOVENDING,
+ CELL_CHKNOCHAT,
+ CELL_CHKMAELSTROM,
+ CELL_CHKICEWALL,
} cell_chk;
-struct mapcell {
- // terrain flags
- unsigned char
- walkable : 1,
- shootable : 1,
- water : 1;
-
- // dynamic flags
- unsigned char
- npc : 1,
- basilica : 1,
- landprotector : 1,
- novending : 1,
- nochat : 1,
- maelstrom : 1,
- icewall : 1;
+struct mapcell
+{
+ // terrain flags
+ unsigned char
+ walkable : 1,
+ shootable : 1,
+ water : 1;
+
+ // dynamic flags
+ unsigned char
+ npc : 1,
+ basilica : 1,
+ landprotector : 1,
+ novending : 1,
+ nochat : 1,
+ maelstrom : 1,
+ icewall : 1;
#ifdef CELL_NOSTACK
- unsigned char cell_bl; //Holds amount of bls in this cell.
+ unsigned char cell_bl; //Holds amount of bls in this cell.
#endif
};
struct iwall_data {
- char wall_name[50];
- short m, x, y, size, dir;
- bool shootable;
+ char wall_name[50];
+ short m, x, y, size, dir;
+ bool shootable;
};
struct map_data {
- char name[MAP_NAME_LENGTH];
- unsigned short index; // The map index used by the mapindex* functions.
- struct mapcell *cell; // Holds the information of each map cell (NULL if the map is not on this map-server).
- struct block_list **block;
- struct block_list **block_mob;
- int m;
- short xs,ys; // map dimensions (in cells)
- short bxs,bys; // map dimensions (in blocks)
- short bgscore_lion, bgscore_eagle; // Battleground ScoreBoard
- int npc_num;
- int users;
- int users_pvp;
- int iwall_num; // Total of invisible walls in this map
- struct map_flag {
- unsigned town : 1; // [Suggestion to protect Mail System]
- unsigned autotrade : 1;
- unsigned allowks : 1; // [Kill Steal Protection]
- unsigned nomemo : 1;
- unsigned noteleport : 1;
- unsigned noreturn : 1;
- unsigned monster_noteleport : 1;
- unsigned nosave : 1;
- unsigned nobranch : 1;
- unsigned noexppenalty : 1;
- unsigned pvp : 1;
- unsigned pvp_noparty : 1;
- unsigned pvp_noguild : 1;
- unsigned pvp_nightmaredrop :1;
- unsigned pvp_nocalcrank : 1;
- unsigned gvg_castle : 1;
- unsigned gvg : 1; // Now it identifies gvg versus maps that are active 24/7
- unsigned gvg_dungeon : 1; // Celest
- unsigned gvg_noparty : 1;
- unsigned battleground : 2; // [BattleGround System]
- unsigned nozenypenalty : 1;
- unsigned notrade : 1;
- unsigned noskill : 1;
- unsigned nowarp : 1;
- unsigned nowarpto : 1;
- unsigned noicewall : 1; // [Valaris]
- unsigned snow : 1; // [Valaris]
- unsigned clouds : 1;
- unsigned clouds2 : 1; // [Valaris]
- unsigned fog : 1; // [Valaris]
- unsigned fireworks : 1;
- unsigned sakura : 1; // [Valaris]
- unsigned leaves : 1; // [Valaris]
- /**
- * No longer available, keeping here just in case it's back someday. [Ind]
- **/
- //unsigned rain : 1; // [Valaris]
- unsigned nogo : 1; // [Valaris]
- unsigned nobaseexp : 1; // [Lorky] added by Lupus
- unsigned nojobexp : 1; // [Lorky]
- unsigned nomobloot : 1; // [Lorky]
- unsigned nomvploot : 1; // [Lorky]
- unsigned nightenabled :1; //For night display. [Skotlex]
- unsigned restricted : 1; // [Komurka]
- unsigned nodrop : 1;
- unsigned novending : 1;
- unsigned loadevent : 1;
- unsigned nochat :1;
- unsigned partylock :1;
- unsigned guildlock :1;
- unsigned src4instance : 1; // To flag this map when it's used as a src map for instances
- unsigned reset :1; // [Daegaladh]
- } flag;
- struct point save;
- struct npc_data *npc[MAX_NPC_PER_MAP];
- struct {
- int drop_id;
- int drop_type;
- int drop_per;
- } drop_list[MAX_DROP_PER_MAP];
-
- struct spawn_data *moblist[MAX_MOB_LIST_PER_MAP]; // [Wizputer]
- int mob_delete_timer; // [Skotlex]
- int zone; // zone number (for item/skill restrictions)
- int jexp; // map experience multiplicator
- int bexp; // map experience multiplicator
- int nocommand; //Blocks @/# commands for non-gms. [Skotlex]
- /**
- * Ice wall reference counter for bugreport:3574
- * - since there are a thounsand mobs out there in a lot of maps checking on,
- * - every targetting for icewall on attack path would just be a waste, so,
- * - this counter allows icewall checking be only run when there is a actual ice wall on the map
- **/
- int icewall_num;
- // Instance Variables
- int instance_id;
- int instance_src_map;
+ char name[MAP_NAME_LENGTH];
+ unsigned short index; // The map index used by the mapindex* functions.
+ struct mapcell* cell; // Holds the information of each map cell (NULL if the map is not on this map-server).
+ struct block_list **block;
+ struct block_list **block_mob;
+ int m;
+ short xs,ys; // map dimensions (in cells)
+ short bxs,bys; // map dimensions (in blocks)
+ short bgscore_lion, bgscore_eagle; // Battleground ScoreBoard
+ int npc_num;
+ int users;
+ int users_pvp;
+ int iwall_num; // Total of invisible walls in this map
+ struct map_flag {
+ unsigned town : 1; // [Suggestion to protect Mail System]
+ unsigned autotrade : 1;
+ unsigned allowks : 1; // [Kill Steal Protection]
+ unsigned nomemo : 1;
+ unsigned noteleport : 1;
+ unsigned noreturn : 1;
+ unsigned monster_noteleport : 1;
+ unsigned nosave : 1;
+ unsigned nobranch : 1;
+ unsigned noexppenalty : 1;
+ unsigned pvp : 1;
+ unsigned pvp_noparty : 1;
+ unsigned pvp_noguild : 1;
+ unsigned pvp_nightmaredrop :1;
+ unsigned pvp_nocalcrank : 1;
+ unsigned gvg_castle : 1;
+ unsigned gvg : 1; // Now it identifies gvg versus maps that are active 24/7
+ unsigned gvg_dungeon : 1; // Celest
+ unsigned gvg_noparty : 1;
+ unsigned battleground : 2; // [BattleGround System]
+ unsigned nozenypenalty : 1;
+ unsigned notrade : 1;
+ unsigned noskill : 1;
+ unsigned nowarp : 1;
+ unsigned nowarpto : 1;
+ unsigned noicewall : 1; // [Valaris]
+ unsigned snow : 1; // [Valaris]
+ unsigned clouds : 1;
+ unsigned clouds2 : 1; // [Valaris]
+ unsigned fog : 1; // [Valaris]
+ unsigned fireworks : 1;
+ unsigned sakura : 1; // [Valaris]
+ unsigned leaves : 1; // [Valaris]
+ /**
+ * No longer available, keeping here just in case it's back someday. [Ind]
+ **/
+ //unsigned rain : 1; // [Valaris]
+ unsigned nogo : 1; // [Valaris]
+ unsigned nobaseexp : 1; // [Lorky] added by Lupus
+ unsigned nojobexp : 1; // [Lorky]
+ unsigned nomobloot : 1; // [Lorky]
+ unsigned nomvploot : 1; // [Lorky]
+ unsigned nightenabled :1; //For night display. [Skotlex]
+ unsigned restricted : 1; // [Komurka]
+ unsigned nodrop : 1;
+ unsigned novending : 1;
+ unsigned loadevent : 1;
+ unsigned nochat :1;
+ unsigned partylock :1;
+ unsigned guildlock :1;
+ unsigned src4instance : 1; // To flag this map when it's used as a src map for instances
+ unsigned reset :1; // [Daegaladh]
+ } flag;
+ struct point save;
+ struct npc_data *npc[MAX_NPC_PER_MAP];
+ struct {
+ int drop_id;
+ int drop_type;
+ int drop_per;
+ } drop_list[MAX_DROP_PER_MAP];
+
+ struct spawn_data *moblist[MAX_MOB_LIST_PER_MAP]; // [Wizputer]
+ int mob_delete_timer; // [Skotlex]
+ int zone; // zone number (for item/skill restrictions)
+ int jexp; // map experience multiplicator
+ int bexp; // map experience multiplicator
+ int nocommand; //Blocks @/# commands for non-gms. [Skotlex]
+ /**
+ * Ice wall reference counter for bugreport:3574
+ * - since there are a thounsand mobs out there in a lot of maps checking on,
+ * - every targetting for icewall on attack path would just be a waste, so,
+ * - this counter allows icewall checking be only run when there is a actual ice wall on the map
+ **/
+ int icewall_num;
+ // Instance Variables
+ int instance_id;
+ int instance_src_map;
};
/// Stores information about a remote map (for multi-mapserver setups).
/// Beginning of data structure matches 'map_data', to allow typecasting.
struct map_data_other_server {
- char name[MAP_NAME_LENGTH];
- unsigned short index; //Index is the map index used by the mapindex* functions.
- struct mapcell *cell; // If this is NULL, the map is not on this map-server
- uint32 ip;
- uint16 port;
+ char name[MAP_NAME_LENGTH];
+ unsigned short index; //Index is the map index used by the mapindex* functions.
+ struct mapcell* cell; // If this is NULL, the map is not on this map-server
+ uint32 ip;
+ uint16 port;
};
int map_getcell(int,int,int,cell_chk);
-int map_getcellp(struct map_data *,int,int,cell_chk);
+int map_getcellp(struct map_data*,int,int,cell_chk);
void map_setcell(int m, int x, int y, cell_t cell, bool flag);
void map_setgatcell(int m, int x, int y, int gat);
@@ -630,18 +632,18 @@ int map_freeblock(struct block_list *bl);
int map_freeblock_lock(void);
int map_freeblock_unlock(void);
// blocklist manipulation
-int map_addblock(struct block_list *bl);
-int map_delblock(struct block_list *bl);
+int map_addblock(struct block_list* bl);
+int map_delblock(struct block_list* bl);
int map_moveblock(struct block_list *, int, int, unsigned int);
-int map_foreachinrange(int (*func)(struct block_list *,va_list), struct block_list *center, int range, int type, ...);
-int map_foreachinshootrange(int (*func)(struct block_list *,va_list), struct block_list *center, int range, int type, ...);
-int map_foreachinarea(int (*func)(struct block_list *,va_list), int m, int x0, int y0, int x1, int y1, int type, ...);
-int map_forcountinrange(int (*func)(struct block_list *,va_list), struct block_list *center, int range, int count, int type, ...);
-int map_forcountinarea(int (*func)(struct block_list *,va_list), int m, int x0, int y0, int x1, int y1, int count, int type, ...);
-int map_foreachinmovearea(int (*func)(struct block_list *,va_list), struct block_list *center, int range, int dx, int dy, int type, ...);
-int map_foreachincell(int (*func)(struct block_list *,va_list), int m, int x, int y, int type, ...);
-int map_foreachinpath(int (*func)(struct block_list *,va_list), int m, int x0, int y0, int x1, int y1, int range, int length, int type, ...);
-int map_foreachinmap(int (*func)(struct block_list *,va_list), int m, int type, ...);
+int map_foreachinrange(int (*func)(struct block_list*,va_list), struct block_list* center, int range, int type, ...);
+int map_foreachinshootrange(int (*func)(struct block_list*,va_list), struct block_list* center, int range, int type, ...);
+int map_foreachinarea(int (*func)(struct block_list*,va_list), int m, int x0, int y0, int x1, int y1, int type, ...);
+int map_forcountinrange(int (*func)(struct block_list*,va_list), struct block_list* center, int range, int count, int type, ...);
+int map_forcountinarea(int (*func)(struct block_list*,va_list), int m, int x0, int y0, int x1, int y1, int count, int type, ...);
+int map_foreachinmovearea(int (*func)(struct block_list*,va_list), struct block_list* center, int range, int dx, int dy, int type, ...);
+int map_foreachincell(int (*func)(struct block_list*,va_list), int m, int x, int y, int type, ...);
+int map_foreachinpath(int (*func)(struct block_list*,va_list), int m, int x0, int y0, int x1, int y1, int range, int length, int type, ...);
+int map_foreachinmap(int (*func)(struct block_list*,va_list), int m, int type, ...);
//blocklist nb in one cell
int map_count_oncell(int m,int x,int y,int type);
struct skill_unit *map_find_skill_unit_oncell(struct block_list *,int x,int y,int skill_id,struct skill_unit *, int flag);
@@ -656,59 +658,60 @@ bool map_addnpc(int,struct npc_data *);
// map item
int map_clearflooritem_timer(int tid, unsigned int tick, int id, intptr_t data);
int map_removemobs_timer(int tid, unsigned int tick, int id, intptr_t data);
-void map_clearflooritem(struct block_list *bl);
+void map_clearflooritem(struct block_list* bl);
int map_addflooritem(struct item *item_data,int amount,int m,int x,int y,int first_charid,int second_charid,int third_charid,int flags);
// player to map session
-void map_addnickdb(int charid, const char *nick);
-void map_delnickdb(int charid, const char *nick);
-void map_reqnickdb(struct map_session_data *sd,int charid);
-const char *map_charid2nick(int charid);
-struct map_session_data *map_charid2sd(int charid);
-
-struct map_session_data *map_id2sd(int id);
-struct mob_data *map_id2md(int id);
-struct npc_data *map_id2nd(int id);
-struct homun_data *map_id2hd(int id);
-struct mercenary_data *map_id2mc(int id);
-struct chat_data *map_id2cd(int id);
-struct block_list *map_id2bl(int id);
-bool map_blid_exists(int id);
+void map_addnickdb(int charid, const char* nick);
+void map_delnickdb(int charid, const char* nick);
+void map_reqnickdb(struct map_session_data* sd,int charid);
+const char* map_charid2nick(int charid);
+struct map_session_data* map_charid2sd(int charid);
+
+struct map_session_data * map_id2sd(int id);
+struct mob_data * map_id2md(int id);
+struct npc_data * map_id2nd(int id);
+struct homun_data* map_id2hd(int id);
+struct mercenary_data* map_id2mc(int id);
+struct chat_data* map_id2cd(int id);
+struct block_list * map_id2bl(int id);
+bool map_blid_exists( int id );
#define map_id2index(id) map[(id)].index
int map_mapindex2mapid(unsigned short mapindex);
-int map_mapname2mapid(const char *name);
-int map_mapname2ipport(unsigned short name, uint32 *ip, uint16 *port);
+int map_mapname2mapid(const char* name);
+int map_mapname2ipport(unsigned short name, uint32* ip, uint16* port);
int map_setipport(unsigned short map, uint32 ip, uint16 port);
int map_eraseipport(unsigned short map, uint32 ip, uint16 port);
int map_eraseallipport(void);
void map_addiddb(struct block_list *);
void map_deliddb(struct block_list *bl);
-void map_foreachpc(int (*func)(struct map_session_data *sd, va_list args), ...);
-void map_foreachmob(int (*func)(struct mob_data *md, va_list args), ...);
-void map_foreachnpc(int (*func)(struct npc_data *nd, va_list args), ...);
-void map_foreachregen(int (*func)(struct block_list *bl, va_list args), ...);
-void map_foreachiddb(int (*func)(struct block_list *bl, va_list args), ...);
-struct map_session_data *map_nick2sd(const char *);
-struct mob_data *map_getmob_boss(int m);
-struct mob_data *map_id2boss(int id);
+void map_foreachpc(int (*func)(struct map_session_data* sd, va_list args), ...);
+void map_foreachmob(int (*func)(struct mob_data* md, va_list args), ...);
+void map_foreachnpc(int (*func)(struct npc_data* nd, va_list args), ...);
+void map_foreachregen(int (*func)(struct block_list* bl, va_list args), ...);
+void map_foreachiddb(int (*func)(struct block_list* bl, va_list args), ...);
+struct map_session_data * map_nick2sd(const char*);
+struct mob_data * map_getmob_boss(int m);
+struct mob_data * map_id2boss(int id);
// reload config file looking only for npcs
void map_reloadnpc(bool clear);
/// Bitfield of flags for the iterator.
-enum e_mapitflags {
- MAPIT_NORMAL = 0,
- // MAPIT_PCISPLAYING = 1,// Unneeded as pc_db/id_db will only hold auth'ed, active players.
+enum e_mapitflags
+{
+ MAPIT_NORMAL = 0,
+// MAPIT_PCISPLAYING = 1,// Unneeded as pc_db/id_db will only hold auth'ed, active players.
};
struct s_mapiterator;
-struct s_mapiterator *mapit_alloc(enum e_mapitflags flags, enum bl_type types);
-void mapit_free(struct s_mapiterator *mapit);
-struct block_list *mapit_first(struct s_mapiterator *mapit);
-struct block_list *mapit_last(struct s_mapiterator *mapit);
-struct block_list *mapit_next(struct s_mapiterator *mapit);
-struct block_list *mapit_prev(struct s_mapiterator *mapit);
-bool mapit_exists(struct s_mapiterator *mapit);
+struct s_mapiterator* mapit_alloc(enum e_mapitflags flags, enum bl_type types);
+void mapit_free(struct s_mapiterator* mapit);
+struct block_list* mapit_first(struct s_mapiterator* mapit);
+struct block_list* mapit_last(struct s_mapiterator* mapit);
+struct block_list* mapit_next(struct s_mapiterator* mapit);
+struct block_list* mapit_prev(struct s_mapiterator* mapit);
+bool mapit_exists(struct s_mapiterator* mapit);
#define mapit_getallusers() mapit_alloc(MAPIT_NORMAL,BL_PC)
#define mapit_geteachpc() mapit_alloc(MAPIT_NORMAL,BL_PC)
#define mapit_geteachmob() mapit_alloc(MAPIT_NORMAL,BL_MOB)
@@ -716,19 +719,19 @@ bool mapit_exists(struct s_mapiterator *mapit);
#define mapit_geteachiddb() mapit_alloc(MAPIT_NORMAL,BL_ALL)
int map_check_dir(int s_dir,int t_dir);
-unsigned char map_calc_dir(struct block_list *src,int x,int y);
+unsigned char map_calc_dir( struct block_list *src,int x,int y);
int map_random_dir(struct block_list *bl, short *x, short *y); // [Skotlex]
int cleanup_sub(struct block_list *bl, va_list ap);
-int map_delmap(char *mapname);
+int map_delmap(char* mapname);
void map_flags_init(void);
-bool map_iwall_set(int m, int x, int y, int size, int dir, bool shootable, const char *wall_name);
+bool map_iwall_set(int m, int x, int y, int size, int dir, bool shootable, const char* wall_name);
void map_iwall_get(struct map_session_data *sd);
void map_iwall_remove(const char *wall_name);
-int map_addmobtolist(unsigned short m, struct spawn_data *spawn); // [Wizputer]
+int map_addmobtolist(unsigned short m, struct spawn_data *spawn); // [Wizputer]
void map_spawnmobs(int); // [Wizputer]
void map_removemobs(int); // [Wizputer]
void do_reconnect_map(void); //Invoked on map-char reconnection [Skotlex]
@@ -754,10 +757,10 @@ typedef struct skill_unit TBL_SKILL;
typedef struct pet_data TBL_PET;
typedef struct homun_data TBL_HOM;
typedef struct mercenary_data TBL_MER;
-typedef struct elemental_data TBL_ELEM;
+typedef struct elemental_data TBL_ELEM;
#define BL_CAST(type_, bl) \
- ( ((bl) == (struct block_list*)NULL || (bl)->type != (type_)) ? (T ## type_ *)NULL : (T ## type_ *)(bl) )
+ ( ((bl) == (struct block_list*)NULL || (bl)->type != (type_)) ? (T ## type_ *)NULL : (T ## type_ *)(bl) )
extern char main_chat_nick[16];
@@ -783,8 +786,8 @@ extern char log_db_db[32];
extern int db_use_sqldbs;
-extern Sql *mmysql_handle;
-extern Sql *logmysql_handle;
+extern Sql* mmysql_handle;
+extern Sql* logmysql_handle;
extern char item_db_db[32];
extern char item_db2_db[32];
diff --git a/src/map/mapreg.h b/src/map/mapreg.h
index 2d761cbbb..d5fadafc5 100644
--- a/src/map/mapreg.h
+++ b/src/map/mapreg.h
@@ -7,11 +7,11 @@
void mapreg_reload(void);
void mapreg_final(void);
void mapreg_init(void);
-bool mapreg_config_read(const char *w1, const char *w2);
+bool mapreg_config_read(const char* w1, const char* w2);
int mapreg_readreg(int uid);
-char *mapreg_readregstr(int uid);
+char* mapreg_readregstr(int uid);
bool mapreg_setreg(int uid, int val);
-bool mapreg_setregstr(int uid, const char *str);
+bool mapreg_setregstr(int uid, const char* str);
#endif /* _MAPREG_H_ */
diff --git a/src/map/mapreg_sql.c b/src/map/mapreg_sql.c
index 4fa943b2e..7782f7f02 100644
--- a/src/map/mapreg_sql.c
+++ b/src/map/mapreg_sql.c
@@ -13,8 +13,8 @@
#include <stdlib.h>
#include <string.h>
-static DBMap *mapreg_db = NULL; // int var_id -> int value
-static DBMap *mapregstr_db = NULL; // int var_id -> char* value
+static DBMap* mapreg_db = NULL; // int var_id -> int value
+static DBMap* mapregstr_db = NULL; // int var_id -> char* value
static char mapreg_table[32] = "mapreg";
static bool mapreg_dirty = false;
@@ -24,203 +24,212 @@ static bool mapreg_dirty = false;
/// Looks up the value of an integer variable using its uid.
int mapreg_readreg(int uid)
{
- return idb_iget(mapreg_db, uid);
+ return idb_iget(mapreg_db, uid);
}
/// Looks up the value of a string variable using its uid.
-char *mapreg_readregstr(int uid)
+char* mapreg_readregstr(int uid)
{
- return idb_get(mapregstr_db, uid);
+ return idb_get(mapregstr_db, uid);
}
/// Modifies the value of an integer variable.
bool mapreg_setreg(int uid, int val)
{
- int num = (uid & 0x00ffffff);
- int i = (uid & 0xff000000) >> 24;
- const char *name = get_str(num);
-
- if (val != 0) {
- if (idb_iput(mapreg_db,uid,val))
- mapreg_dirty = true; // already exists, delay write
- else if (name[1] != '@') {
- // write new variable to database
- char tmp_str[32*2+1];
- Sql_EscapeStringLen(mmysql_handle, tmp_str, name, strnlen(name, 32));
- if (SQL_ERROR == Sql_Query(mmysql_handle, "INSERT INTO `%s`(`varname`,`index`,`value`) VALUES ('%s','%d','%d')", mapreg_table, tmp_str, i, val))
- Sql_ShowDebug(mmysql_handle);
- }
- } else { // val == 0
- idb_remove(mapreg_db,uid);
-
- if (name[1] != '@') {
- // Remove from database because it is unused.
- if (SQL_ERROR == Sql_Query(mmysql_handle, "DELETE FROM `%s` WHERE `varname`='%s' AND `index`='%d'", mapreg_table, name, i))
- Sql_ShowDebug(mmysql_handle);
- }
- }
-
- return true;
+ int num = (uid & 0x00ffffff);
+ int i = (uid & 0xff000000) >> 24;
+ const char* name = get_str(num);
+
+ if( val != 0 )
+ {
+ if( idb_iput(mapreg_db,uid,val) )
+ mapreg_dirty = true; // already exists, delay write
+ else if(name[1] != '@')
+ {// write new variable to database
+ char tmp_str[32*2+1];
+ Sql_EscapeStringLen(mmysql_handle, tmp_str, name, strnlen(name, 32));
+ if( SQL_ERROR == Sql_Query(mmysql_handle, "INSERT INTO `%s`(`varname`,`index`,`value`) VALUES ('%s','%d','%d')", mapreg_table, tmp_str, i, val) )
+ Sql_ShowDebug(mmysql_handle);
+ }
+ }
+ else // val == 0
+ {
+ idb_remove(mapreg_db,uid);
+
+ if( name[1] != '@' )
+ {// Remove from database because it is unused.
+ if( SQL_ERROR == Sql_Query(mmysql_handle, "DELETE FROM `%s` WHERE `varname`='%s' AND `index`='%d'", mapreg_table, name, i) )
+ Sql_ShowDebug(mmysql_handle);
+ }
+ }
+
+ return true;
}
/// Modifies the value of a string variable.
-bool mapreg_setregstr(int uid, const char *str)
+bool mapreg_setregstr(int uid, const char* str)
{
- int num = (uid & 0x00ffffff);
- int i = (uid & 0xff000000) >> 24;
- const char *name = get_str(num);
-
- if (str == NULL || *str == 0) {
- if (name[1] != '@') {
- if (SQL_ERROR == Sql_Query(mmysql_handle, "DELETE FROM `%s` WHERE `varname`='%s' AND `index`='%d'", mapreg_table, name, i))
- Sql_ShowDebug(mmysql_handle);
- }
- idb_remove(mapregstr_db,uid);
- } else {
- if (idb_put(mapregstr_db,uid, aStrdup(str)))
- mapreg_dirty = true;
- else if (name[1] != '@') { //put returned null, so we must insert.
- // Someone is causing a database size infinite increase here without name[1] != '@' [Lance]
- char tmp_str[32*2+1];
- char tmp_str2[255*2+1];
- Sql_EscapeStringLen(mmysql_handle, tmp_str, name, strnlen(name, 32));
- Sql_EscapeStringLen(mmysql_handle, tmp_str2, str, strnlen(str, 255));
- if (SQL_ERROR == Sql_Query(mmysql_handle, "INSERT INTO `%s`(`varname`,`index`,`value`) VALUES ('%s','%d','%s')", mapreg_table, tmp_str, i, tmp_str2))
- Sql_ShowDebug(mmysql_handle);
- }
- }
-
- return true;
+ int num = (uid & 0x00ffffff);
+ int i = (uid & 0xff000000) >> 24;
+ const char* name = get_str(num);
+
+ if( str == NULL || *str == 0 )
+ {
+ if(name[1] != '@') {
+ if( SQL_ERROR == Sql_Query(mmysql_handle, "DELETE FROM `%s` WHERE `varname`='%s' AND `index`='%d'", mapreg_table, name, i) )
+ Sql_ShowDebug(mmysql_handle);
+ }
+ idb_remove(mapregstr_db,uid);
+ }
+ else
+ {
+ if (idb_put(mapregstr_db,uid, aStrdup(str)))
+ mapreg_dirty = true;
+ else if(name[1] != '@') { //put returned null, so we must insert.
+ // Someone is causing a database size infinite increase here without name[1] != '@' [Lance]
+ char tmp_str[32*2+1];
+ char tmp_str2[255*2+1];
+ Sql_EscapeStringLen(mmysql_handle, tmp_str, name, strnlen(name, 32));
+ Sql_EscapeStringLen(mmysql_handle, tmp_str2, str, strnlen(str, 255));
+ if( SQL_ERROR == Sql_Query(mmysql_handle, "INSERT INTO `%s`(`varname`,`index`,`value`) VALUES ('%s','%d','%s')", mapreg_table, tmp_str, i, tmp_str2) )
+ Sql_ShowDebug(mmysql_handle);
+ }
+ }
+
+ return true;
}
/// Loads permanent variables from database
static void script_load_mapreg(void)
{
- /*
- 0 1 2
- +-------------------------+
- | varname | index | value |
- +-------------------------+
- */
- SqlStmt *stmt = SqlStmt_Malloc(mmysql_handle);
- char varname[32+1];
- int index;
- char value[255+1];
- uint32 length;
-
- if (SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `varname`, `index`, `value` FROM `%s`", mapreg_table)
- || SQL_ERROR == SqlStmt_Execute(stmt)
- ) {
- SqlStmt_ShowDebug(stmt);
- SqlStmt_Free(stmt);
- return;
- }
-
- SqlStmt_BindColumn(stmt, 0, SQLDT_STRING, &varname[0], sizeof(varname), &length, NULL);
- SqlStmt_BindColumn(stmt, 1, SQLDT_INT, &index, 0, NULL, NULL);
- SqlStmt_BindColumn(stmt, 2, SQLDT_STRING, &value[0], sizeof(value), NULL, NULL);
-
- while (SQL_SUCCESS == SqlStmt_NextRow(stmt)) {
- int s = add_str(varname);
- int i = index;
-
- if (varname[length-1] == '$')
- idb_put(mapregstr_db, (i<<24)|s, aStrdup(value));
- else
- idb_iput(mapreg_db, (i<<24)|s, atoi(value));
- }
-
- SqlStmt_Free(stmt);
-
- mapreg_dirty = false;
+ /*
+ 0 1 2
+ +-------------------------+
+ | varname | index | value |
+ +-------------------------+
+ */
+ SqlStmt* stmt = SqlStmt_Malloc(mmysql_handle);
+ char varname[32+1];
+ int index;
+ char value[255+1];
+ uint32 length;
+
+ if ( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `varname`, `index`, `value` FROM `%s`", mapreg_table)
+ || SQL_ERROR == SqlStmt_Execute(stmt)
+ ) {
+ SqlStmt_ShowDebug(stmt);
+ SqlStmt_Free(stmt);
+ return;
+ }
+
+ SqlStmt_BindColumn(stmt, 0, SQLDT_STRING, &varname[0], sizeof(varname), &length, NULL);
+ SqlStmt_BindColumn(stmt, 1, SQLDT_INT, &index, 0, NULL, NULL);
+ SqlStmt_BindColumn(stmt, 2, SQLDT_STRING, &value[0], sizeof(value), NULL, NULL);
+
+ while ( SQL_SUCCESS == SqlStmt_NextRow(stmt) )
+ {
+ int s = add_str(varname);
+ int i = index;
+
+ if( varname[length-1] == '$' )
+ idb_put(mapregstr_db, (i<<24)|s, aStrdup(value));
+ else
+ idb_iput(mapreg_db, (i<<24)|s, atoi(value));
+ }
+
+ SqlStmt_Free(stmt);
+
+ mapreg_dirty = false;
}
/// Saves permanent variables to database
static void script_save_mapreg(void)
{
- DBIterator *iter;
- DBData *data;
- DBKey key;
-
- iter = db_iterator(mapreg_db);
- for (data = iter->first(iter,&key); iter->exists(iter); data = iter->next(iter,&key)) {
- int num = (key.i & 0x00ffffff);
- int i = (key.i & 0xff000000) >> 24;
- const char *name = get_str(num);
-
- if (name[1] == '@')
- continue;
-
- if (SQL_ERROR == Sql_Query(mmysql_handle, "UPDATE `%s` SET `value`='%d' WHERE `varname`='%s' AND `index`='%d'", mapreg_table, db_data2i(data), name, i))
- Sql_ShowDebug(mmysql_handle);
- }
- dbi_destroy(iter);
-
- iter = db_iterator(mapregstr_db);
- for (data = iter->first(iter,&key); iter->exists(iter); data = iter->next(iter,&key)) {
- int num = (key.i & 0x00ffffff);
- int i = (key.i & 0xff000000) >> 24;
- const char *name = get_str(num);
- char tmp_str2[2*255+1];
-
- if (name[1] == '@')
- continue;
-
- Sql_EscapeStringLen(mmysql_handle, tmp_str2, db_data2ptr(data), safestrnlen(db_data2ptr(data), 255));
- if (SQL_ERROR == Sql_Query(mmysql_handle, "UPDATE `%s` SET `value`='%s' WHERE `varname`='%s' AND `index`='%d'", mapreg_table, tmp_str2, name, i))
- Sql_ShowDebug(mmysql_handle);
- }
- dbi_destroy(iter);
-
- mapreg_dirty = false;
+ DBIterator* iter;
+ DBData *data;
+ DBKey key;
+
+ iter = db_iterator(mapreg_db);
+ for( data = iter->first(iter,&key); iter->exists(iter); data = iter->next(iter,&key) )
+ {
+ int num = (key.i & 0x00ffffff);
+ int i = (key.i & 0xff000000) >> 24;
+ const char* name = get_str(num);
+
+ if( name[1] == '@' )
+ continue;
+
+ if( SQL_ERROR == Sql_Query(mmysql_handle, "UPDATE `%s` SET `value`='%d' WHERE `varname`='%s' AND `index`='%d'", mapreg_table, db_data2i(data), name, i) )
+ Sql_ShowDebug(mmysql_handle);
+ }
+ dbi_destroy(iter);
+
+ iter = db_iterator(mapregstr_db);
+ for( data = iter->first(iter,&key); iter->exists(iter); data = iter->next(iter,&key) )
+ {
+ int num = (key.i & 0x00ffffff);
+ int i = (key.i & 0xff000000) >> 24;
+ const char* name = get_str(num);
+ char tmp_str2[2*255+1];
+
+ if( name[1] == '@' )
+ continue;
+
+ Sql_EscapeStringLen(mmysql_handle, tmp_str2, db_data2ptr(data), safestrnlen(db_data2ptr(data), 255));
+ if( SQL_ERROR == Sql_Query(mmysql_handle, "UPDATE `%s` SET `value`='%s' WHERE `varname`='%s' AND `index`='%d'", mapreg_table, tmp_str2, name, i) )
+ Sql_ShowDebug(mmysql_handle);
+ }
+ dbi_destroy(iter);
+
+ mapreg_dirty = false;
}
static int script_autosave_mapreg(int tid, unsigned int tick, int id, intptr_t data)
{
- if (mapreg_dirty)
- script_save_mapreg();
+ if( mapreg_dirty )
+ script_save_mapreg();
- return 0;
+ return 0;
}
void mapreg_reload(void)
{
- if (mapreg_dirty)
- script_save_mapreg();
+ if( mapreg_dirty )
+ script_save_mapreg();
- db_clear(mapreg_db);
- db_clear(mapregstr_db);
+ db_clear(mapreg_db);
+ db_clear(mapregstr_db);
- script_load_mapreg();
+ script_load_mapreg();
}
void mapreg_final(void)
{
- if (mapreg_dirty)
- script_save_mapreg();
+ if( mapreg_dirty )
+ script_save_mapreg();
- db_destroy(mapreg_db);
- db_destroy(mapregstr_db);
+ db_destroy(mapreg_db);
+ db_destroy(mapregstr_db);
}
void mapreg_init(void)
{
- mapreg_db = idb_alloc(DB_OPT_BASE);
- mapregstr_db = idb_alloc(DB_OPT_RELEASE_DATA);
+ mapreg_db = idb_alloc(DB_OPT_BASE);
+ mapregstr_db = idb_alloc(DB_OPT_RELEASE_DATA);
- script_load_mapreg();
+ script_load_mapreg();
- add_timer_func_list(script_autosave_mapreg, "script_autosave_mapreg");
- add_timer_interval(gettick() + MAPREG_AUTOSAVE_INTERVAL, script_autosave_mapreg, 0, 0, MAPREG_AUTOSAVE_INTERVAL);
+ add_timer_func_list(script_autosave_mapreg, "script_autosave_mapreg");
+ add_timer_interval(gettick() + MAPREG_AUTOSAVE_INTERVAL, script_autosave_mapreg, 0, 0, MAPREG_AUTOSAVE_INTERVAL);
}
-bool mapreg_config_read(const char *w1, const char *w2)
+bool mapreg_config_read(const char* w1, const char* w2)
{
- if (!strcmpi(w1, "mapreg_db"))
- safestrncpy(mapreg_table, w2, sizeof(mapreg_table));
- else
- return false;
+ if(!strcmpi(w1, "mapreg_db"))
+ safestrncpy(mapreg_table, w2, sizeof(mapreg_table));
+ else
+ return false;
- return true;
+ return true;
}
diff --git a/src/map/mercenary.c b/src/map/mercenary.c
index d2945886a..832cc835b 100644
--- a/src/map/mercenary.c
+++ b/src/map/mercenary.c
@@ -42,461 +42,469 @@ struct s_mercenary_db mercenary_db[MAX_MERCENARY_CLASS]; // Mercenary Database
int merc_search_index(int class_)
{
- int i;
- ARR_FIND(0, MAX_MERCENARY_CLASS, i, mercenary_db[i].class_ == class_);
- return (i == MAX_MERCENARY_CLASS)?-1:i;
+ int i;
+ ARR_FIND(0, MAX_MERCENARY_CLASS, i, mercenary_db[i].class_ == class_);
+ return (i == MAX_MERCENARY_CLASS)?-1:i;
}
bool merc_class(int class_)
{
- return (bool)(merc_search_index(class_) > -1);
+ return (bool)(merc_search_index(class_) > -1);
}
-struct view_data *merc_get_viewdata(int class_) {
- int i = merc_search_index(class_);
- if (i < 0)
- return 0;
+struct view_data * merc_get_viewdata(int class_)
+{
+ int i = merc_search_index(class_);
+ if( i < 0 )
+ return 0;
- return &mercenary_db[i].vd;
+ return &mercenary_db[i].vd;
}
int merc_create(struct map_session_data *sd, int class_, unsigned int lifetime)
{
- struct s_mercenary merc;
- struct s_mercenary_db *db;
- int i;
- nullpo_retr(0,sd);
+ struct s_mercenary merc;
+ struct s_mercenary_db *db;
+ int i;
+ nullpo_retr(0,sd);
- if ((i = merc_search_index(class_)) < 0)
- return 0;
+ if( (i = merc_search_index(class_)) < 0 )
+ return 0;
- db = &mercenary_db[i];
- memset(&merc,0,sizeof(struct s_mercenary));
+ db = &mercenary_db[i];
+ memset(&merc,0,sizeof(struct s_mercenary));
- merc.char_id = sd->status.char_id;
- merc.class_ = class_;
- merc.hp = db->status.max_hp;
- merc.sp = db->status.max_sp;
- merc.life_time = lifetime;
+ merc.char_id = sd->status.char_id;
+ merc.class_ = class_;
+ merc.hp = db->status.max_hp;
+ merc.sp = db->status.max_sp;
+ merc.life_time = lifetime;
- // Request Char Server to create this mercenary
- intif_mercenary_create(&merc);
+ // Request Char Server to create this mercenary
+ intif_mercenary_create(&merc);
- return 1;
+ return 1;
}
int mercenary_get_lifetime(struct mercenary_data *md)
{
- const struct TimerData *td;
- if (md == NULL || md->contract_timer == INVALID_TIMER)
- return 0;
+ const struct TimerData * td;
+ if( md == NULL || md->contract_timer == INVALID_TIMER )
+ return 0;
- td = get_timer(md->contract_timer);
- return (td != NULL) ? DIFF_TICK(td->tick, gettick()) : 0;
+ td = get_timer(md->contract_timer);
+ return (td != NULL) ? DIFF_TICK(td->tick, gettick()) : 0;
}
int mercenary_get_guild(struct mercenary_data *md)
{
- int class_;
+ int class_;
- if (md == NULL || md->db == NULL)
- return -1;
+ if( md == NULL || md->db == NULL )
+ return -1;
- class_ = md->db->class_;
+ class_ = md->db->class_;
- if (class_ >= 6017 && class_ <= 6026)
- return ARCH_MERC_GUILD;
- if (class_ >= 6027 && class_ <= 6036)
- return SPEAR_MERC_GUILD;
- if (class_ >= 6037 && class_ <= 6046)
- return SWORD_MERC_GUILD;
+ if( class_ >= 6017 && class_ <= 6026 )
+ return ARCH_MERC_GUILD;
+ if( class_ >= 6027 && class_ <= 6036 )
+ return SPEAR_MERC_GUILD;
+ if( class_ >= 6037 && class_ <= 6046 )
+ return SWORD_MERC_GUILD;
- return -1;
+ return -1;
}
int mercenary_get_faith(struct mercenary_data *md)
{
- struct map_session_data *sd;
- int class_;
+ struct map_session_data *sd;
+ int class_;
- if (md == NULL || md->db == NULL || (sd = md->master) == NULL)
- return 0;
+ if( md == NULL || md->db == NULL || (sd = md->master) == NULL )
+ return 0;
- class_ = md->db->class_;
+ class_ = md->db->class_;
- if (class_ >= 6017 && class_ <= 6026)
- return sd->status.arch_faith;
- if (class_ >= 6027 && class_ <= 6036)
- return sd->status.spear_faith;
- if (class_ >= 6037 && class_ <= 6046)
- return sd->status.sword_faith;
+ if( class_ >= 6017 && class_ <= 6026 )
+ return sd->status.arch_faith;
+ if( class_ >= 6027 && class_ <= 6036 )
+ return sd->status.spear_faith;
+ if( class_ >= 6037 && class_ <= 6046 )
+ return sd->status.sword_faith;
- return 0;
+ return 0;
}
int mercenary_set_faith(struct mercenary_data *md, int value)
{
- struct map_session_data *sd;
- int class_, *faith;
+ struct map_session_data *sd;
+ int class_, *faith;
- if (md == NULL || md->db == NULL || (sd = md->master) == NULL)
- return 0;
+ if( md == NULL || md->db == NULL || (sd = md->master) == NULL )
+ return 0;
- class_ = md->db->class_;
+ class_ = md->db->class_;
- if (class_ >= 6017 && class_ <= 6026)
- faith = &sd->status.arch_faith;
- else if (class_ >= 6027 && class_ <= 6036)
- faith = &sd->status.spear_faith;
- else if (class_ >= 6037 && class_ <= 6046)
- faith = &sd->status.sword_faith;
- else
- return 0;
+ if( class_ >= 6017 && class_ <= 6026 )
+ faith = &sd->status.arch_faith;
+ else if( class_ >= 6027 && class_ <= 6036 )
+ faith = &sd->status.spear_faith;
+ else if( class_ >= 6037 && class_ <= 6046 )
+ faith = &sd->status.sword_faith;
+ else
+ return 0;
- *faith += value;
- *faith = cap_value(*faith, 0, SHRT_MAX);
- clif_mercenary_updatestatus(sd, SP_MERCFAITH);
+ *faith += value;
+ *faith = cap_value(*faith, 0, SHRT_MAX);
+ clif_mercenary_updatestatus(sd, SP_MERCFAITH);
- return 0;
+ return 0;
}
int mercenary_get_calls(struct mercenary_data *md)
{
- struct map_session_data *sd;
- int class_;
+ struct map_session_data *sd;
+ int class_;
- if (md == NULL || md->db == NULL || (sd = md->master) == NULL)
- return 0;
+ if( md == NULL || md->db == NULL || (sd = md->master) == NULL )
+ return 0;
- class_ = md->db->class_;
+ class_ = md->db->class_;
- if (class_ >= 6017 && class_ <= 6026)
- return sd->status.arch_calls;
- if (class_ >= 6027 && class_ <= 6036)
- return sd->status.spear_calls;
- if (class_ >= 6037 && class_ <= 6046)
- return sd->status.sword_calls;
+ if( class_ >= 6017 && class_ <= 6026 )
+ return sd->status.arch_calls;
+ if( class_ >= 6027 && class_ <= 6036 )
+ return sd->status.spear_calls;
+ if( class_ >= 6037 && class_ <= 6046 )
+ return sd->status.sword_calls;
- return 0;
+ return 0;
}
int mercenary_set_calls(struct mercenary_data *md, int value)
{
- struct map_session_data *sd;
- int class_, *calls;
+ struct map_session_data *sd;
+ int class_, *calls;
- if (md == NULL || md->db == NULL || (sd = md->master) == NULL)
- return 0;
+ if( md == NULL || md->db == NULL || (sd = md->master) == NULL )
+ return 0;
- class_ = md->db->class_;
+ class_ = md->db->class_;
- if (class_ >= 6017 && class_ <= 6026)
- calls = &sd->status.arch_calls;
- else if (class_ >= 6027 && class_ <= 6036)
- calls = &sd->status.spear_calls;
- else if (class_ >= 6037 && class_ <= 6046)
- calls = &sd->status.sword_calls;
- else
- return 0;
+ if( class_ >= 6017 && class_ <= 6026 )
+ calls = &sd->status.arch_calls;
+ else if( class_ >= 6027 && class_ <= 6036 )
+ calls = &sd->status.spear_calls;
+ else if( class_ >= 6037 && class_ <= 6046 )
+ calls = &sd->status.sword_calls;
+ else
+ return 0;
- *calls += value;
- *calls = cap_value(*calls, 0, INT_MAX);
+ *calls += value;
+ *calls = cap_value(*calls, 0, INT_MAX);
- return 0;
+ return 0;
}
int mercenary_save(struct mercenary_data *md)
{
- md->mercenary.hp = md->battle_status.hp;
- md->mercenary.sp = md->battle_status.sp;
- md->mercenary.life_time = mercenary_get_lifetime(md);
+ md->mercenary.hp = md->battle_status.hp;
+ md->mercenary.sp = md->battle_status.sp;
+ md->mercenary.life_time = mercenary_get_lifetime(md);
- intif_mercenary_save(&md->mercenary);
- return 1;
+ intif_mercenary_save(&md->mercenary);
+ return 1;
}
static int merc_contract_end(int tid, unsigned int tick, int id, intptr_t data)
{
- struct map_session_data *sd;
- struct mercenary_data *md;
+ struct map_session_data *sd;
+ struct mercenary_data *md;
- if ((sd = map_id2sd(id)) == NULL)
- return 1;
- if ((md = sd->md) == NULL)
- return 1;
+ if( (sd = map_id2sd(id)) == NULL )
+ return 1;
+ if( (md = sd->md) == NULL )
+ return 1;
- if (md->contract_timer != tid) {
- ShowError("merc_contract_end %d != %d.\n", md->contract_timer, tid);
- return 0;
- }
+ if( md->contract_timer != tid )
+ {
+ ShowError("merc_contract_end %d != %d.\n", md->contract_timer, tid);
+ return 0;
+ }
- md->contract_timer = INVALID_TIMER;
- merc_delete(md, 0); // Mercenary soldier's duty hour is over.
+ md->contract_timer = INVALID_TIMER;
+ merc_delete(md, 0); // Mercenary soldier's duty hour is over.
- return 0;
+ return 0;
}
int merc_delete(struct mercenary_data *md, int reply)
{
- struct map_session_data *sd = md->master;
- md->mercenary.life_time = 0;
-
- merc_contract_stop(md);
-
- if (!sd)
- return unit_free(&md->bl, CLR_OUTSIGHT);
-
- if (md->devotion_flag) {
- md->devotion_flag = 0;
- status_change_end(&sd->bl, SC_DEVOTION, INVALID_TIMER);
- }
-
- switch (reply) {
- case 0:
- mercenary_set_faith(md, 1);
- break; // +1 Loyalty on Contract ends.
- case 1:
- mercenary_set_faith(md, -1);
- break; // -1 Loyalty on Mercenary killed
- }
-
- clif_mercenary_message(sd, reply);
- return unit_remove_map(&md->bl, CLR_OUTSIGHT);
+ struct map_session_data *sd = md->master;
+ md->mercenary.life_time = 0;
+
+ merc_contract_stop(md);
+
+ if( !sd )
+ return unit_free(&md->bl, CLR_OUTSIGHT);
+
+ if( md->devotion_flag )
+ {
+ md->devotion_flag = 0;
+ status_change_end(&sd->bl, SC_DEVOTION, INVALID_TIMER);
+ }
+
+ switch( reply )
+ {
+ case 0: mercenary_set_faith(md, 1); break; // +1 Loyalty on Contract ends.
+ case 1: mercenary_set_faith(md, -1); break; // -1 Loyalty on Mercenary killed
+ }
+
+ clif_mercenary_message(sd, reply);
+ return unit_remove_map(&md->bl, CLR_OUTSIGHT);
}
void merc_contract_stop(struct mercenary_data *md)
{
- nullpo_retv(md);
- if (md->contract_timer != INVALID_TIMER)
- delete_timer(md->contract_timer, merc_contract_end);
- md->contract_timer = INVALID_TIMER;
+ nullpo_retv(md);
+ if( md->contract_timer != INVALID_TIMER )
+ delete_timer(md->contract_timer, merc_contract_end);
+ md->contract_timer = INVALID_TIMER;
}
void merc_contract_init(struct mercenary_data *md)
{
- if (md->contract_timer == INVALID_TIMER)
- md->contract_timer = add_timer(gettick() + md->mercenary.life_time, merc_contract_end, md->master->bl.id, 0);
+ if( md->contract_timer == INVALID_TIMER )
+ md->contract_timer = add_timer(gettick() + md->mercenary.life_time, merc_contract_end, md->master->bl.id, 0);
- md->regen.state.block = 0;
+ md->regen.state.block = 0;
}
int merc_data_received(struct s_mercenary *merc, bool flag)
{
- struct map_session_data *sd;
- struct mercenary_data *md;
- struct s_mercenary_db *db;
- int i = merc_search_index(merc->class_);
-
- if ((sd = map_charid2sd(merc->char_id)) == NULL)
- return 0;
- if (!flag || i < 0) {
- // Not created - loaded - DB info
- sd->status.mer_id = 0;
- return 0;
- }
-
- db = &mercenary_db[i];
- if (!sd->md) {
- sd->md = md = (struct mercenary_data *)aCalloc(1,sizeof(struct mercenary_data));
- md->bl.type = BL_MER;
- md->bl.id = npc_get_new_npc_id();
- md->devotion_flag = 0;
-
- md->master = sd;
- md->db = db;
- memcpy(&md->mercenary, merc, sizeof(struct s_mercenary));
- status_set_viewdata(&md->bl, md->mercenary.class_);
- status_change_init(&md->bl);
- unit_dataset(&md->bl);
- md->ud.dir = sd->ud.dir;
-
- md->bl.m = sd->bl.m;
- md->bl.x = sd->bl.x;
- md->bl.y = sd->bl.y;
- unit_calc_pos(&md->bl, sd->bl.x, sd->bl.y, sd->ud.dir);
- md->bl.x = md->ud.to_x;
- md->bl.y = md->ud.to_y;
-
- map_addiddb(&md->bl);
- status_calc_mercenary(md,1);
- md->contract_timer = INVALID_TIMER;
- merc_contract_init(md);
- } else {
- memcpy(&sd->md->mercenary, merc, sizeof(struct s_mercenary));
- md = sd->md;
- }
-
- if (sd->status.mer_id == 0)
- mercenary_set_calls(md, 1);
- sd->status.mer_id = merc->mercenary_id;
-
- if (md && md->bl.prev == NULL && sd->bl.prev != NULL) {
- map_addblock(&md->bl);
- clif_spawn(&md->bl);
- clif_mercenary_info(sd);
- clif_mercenary_skillblock(sd);
- }
-
- return 1;
+ struct map_session_data *sd;
+ struct mercenary_data *md;
+ struct s_mercenary_db *db;
+ int i = merc_search_index(merc->class_);
+
+ if( (sd = map_charid2sd(merc->char_id)) == NULL )
+ return 0;
+ if( !flag || i < 0 )
+ { // Not created - loaded - DB info
+ sd->status.mer_id = 0;
+ return 0;
+ }
+
+ db = &mercenary_db[i];
+ if( !sd->md )
+ {
+ sd->md = md = (struct mercenary_data*)aCalloc(1,sizeof(struct mercenary_data));
+ md->bl.type = BL_MER;
+ md->bl.id = npc_get_new_npc_id();
+ md->devotion_flag = 0;
+
+ md->master = sd;
+ md->db = db;
+ memcpy(&md->mercenary, merc, sizeof(struct s_mercenary));
+ status_set_viewdata(&md->bl, md->mercenary.class_);
+ status_change_init(&md->bl);
+ unit_dataset(&md->bl);
+ md->ud.dir = sd->ud.dir;
+
+ md->bl.m = sd->bl.m;
+ md->bl.x = sd->bl.x;
+ md->bl.y = sd->bl.y;
+ unit_calc_pos(&md->bl, sd->bl.x, sd->bl.y, sd->ud.dir);
+ md->bl.x = md->ud.to_x;
+ md->bl.y = md->ud.to_y;
+
+ map_addiddb(&md->bl);
+ status_calc_mercenary(md,1);
+ md->contract_timer = INVALID_TIMER;
+ merc_contract_init(md);
+ }
+ else
+ {
+ memcpy(&sd->md->mercenary, merc, sizeof(struct s_mercenary));
+ md = sd->md;
+ }
+
+ if( sd->status.mer_id == 0 )
+ mercenary_set_calls(md, 1);
+ sd->status.mer_id = merc->mercenary_id;
+
+ if( md && md->bl.prev == NULL && sd->bl.prev != NULL )
+ {
+ map_addblock(&md->bl);
+ clif_spawn(&md->bl);
+ clif_mercenary_info(sd);
+ clif_mercenary_skillblock(sd);
+ }
+
+ return 1;
}
void mercenary_heal(struct mercenary_data *md, int hp, int sp)
{
- if (hp)
- clif_mercenary_updatestatus(md->master, SP_HP);
- if (sp)
- clif_mercenary_updatestatus(md->master, SP_SP);
+ if( hp )
+ clif_mercenary_updatestatus(md->master, SP_HP);
+ if( sp )
+ clif_mercenary_updatestatus(md->master, SP_SP);
}
int mercenary_dead(struct mercenary_data *md)
{
- merc_delete(md, 1);
- return 0;
+ merc_delete(md, 1);
+ return 0;
}
int mercenary_killbonus(struct mercenary_data *md)
{
- const enum sc_type scs[] = { SC_MERC_FLEEUP, SC_MERC_ATKUP, SC_MERC_HPUP, SC_MERC_SPUP, SC_MERC_HITUP };
- int index = rnd() % ARRAYLENGTH(scs);
+ const enum sc_type scs[] = { SC_MERC_FLEEUP, SC_MERC_ATKUP, SC_MERC_HPUP, SC_MERC_SPUP, SC_MERC_HITUP };
+ int index = rnd() % ARRAYLENGTH(scs);
sc_start(&md->bl, scs[index], 100, rnd() % 5, 600000);
- return 0;
+ return 0;
}
int mercenary_kills(struct mercenary_data *md)
{
- md->mercenary.kill_count++;
- md->mercenary.kill_count = cap_value(md->mercenary.kill_count, 0, INT_MAX);
+ md->mercenary.kill_count++;
+ md->mercenary.kill_count = cap_value(md->mercenary.kill_count, 0, INT_MAX);
- if ((md->mercenary.kill_count % 50) == 0) {
- mercenary_set_faith(md, 1);
- mercenary_killbonus(md);
- }
+ if( (md->mercenary.kill_count % 50) == 0 )
+ {
+ mercenary_set_faith(md, 1);
+ mercenary_killbonus(md);
+ }
- if (md->master)
- clif_mercenary_updatestatus(md->master, SP_MERCKILLS);
+ if( md->master )
+ clif_mercenary_updatestatus(md->master, SP_MERCKILLS);
- return 0;
+ return 0;
}
int mercenary_checkskill(struct mercenary_data *md, int skill_id)
{
- int i = skill_id - MC_SKILLBASE;
+ int i = skill_id - MC_SKILLBASE;
- if (!md || !md->db)
- return 0;
- if (md->db->skill[i].id == skill_id)
- return md->db->skill[i].lv;
+ if( !md || !md->db )
+ return 0;
+ if( md->db->skill[i].id == skill_id )
+ return md->db->skill[i].lv;
- return 0;
+ return 0;
}
-static bool read_mercenarydb_sub(char *str[], int columns, int current)
+static bool read_mercenarydb_sub(char* str[], int columns, int current)
{
- int ele;
- struct s_mercenary_db *db;
- struct status_data *status;
-
- db = &mercenary_db[current];
- db->class_ = atoi(str[0]);
- strncpy(db->sprite, str[1], NAME_LENGTH);
- strncpy(db->name, str[2], NAME_LENGTH);
- db->lv = atoi(str[3]);
-
- status = &db->status;
- db->vd.class_ = db->class_;
-
- status->max_hp = atoi(str[4]);
- status->max_sp = atoi(str[5]);
- status->rhw.range = atoi(str[6]);
- status->rhw.atk = atoi(str[7]);
- status->rhw.atk2 = status->rhw.atk + atoi(str[8]);
- status->def = atoi(str[9]);
- status->mdef = atoi(str[10]);
- status->str = atoi(str[11]);
- status->agi = atoi(str[12]);
- status->vit = atoi(str[13]);
- status->int_ = atoi(str[14]);
- status->dex = atoi(str[15]);
- status->luk = atoi(str[16]);
- db->range2 = atoi(str[17]);
- db->range3 = atoi(str[18]);
- status->size = atoi(str[19]);
- status->race = atoi(str[20]);
-
- ele = atoi(str[21]);
- status->def_ele = ele%10;
- status->ele_lv = ele/20;
- if (status->def_ele >= ELE_MAX) {
- ShowWarning("Mercenary %d has invalid element type %d (max element is %d)\n", db->class_, status->def_ele, ELE_MAX - 1);
- status->def_ele = ELE_NEUTRAL;
- }
- if (status->ele_lv < 1 || status->ele_lv > 4) {
- ShowWarning("Mercenary %d has invalid element level %d (max is 4)\n", db->class_, status->ele_lv);
- status->ele_lv = 1;
- }
-
- status->aspd_rate = 1000;
- status->speed = atoi(str[22]);
- status->adelay = atoi(str[23]);
- status->amotion = atoi(str[24]);
- status->dmotion = atoi(str[25]);
-
- return true;
+ int ele;
+ struct s_mercenary_db *db;
+ struct status_data *status;
+
+ db = &mercenary_db[current];
+ db->class_ = atoi(str[0]);
+ strncpy(db->sprite, str[1], NAME_LENGTH);
+ strncpy(db->name, str[2], NAME_LENGTH);
+ db->lv = atoi(str[3]);
+
+ status = &db->status;
+ db->vd.class_ = db->class_;
+
+ status->max_hp = atoi(str[4]);
+ status->max_sp = atoi(str[5]);
+ status->rhw.range = atoi(str[6]);
+ status->rhw.atk = atoi(str[7]);
+ status->rhw.atk2 = status->rhw.atk + atoi(str[8]);
+ status->def = atoi(str[9]);
+ status->mdef = atoi(str[10]);
+ status->str = atoi(str[11]);
+ status->agi = atoi(str[12]);
+ status->vit = atoi(str[13]);
+ status->int_ = atoi(str[14]);
+ status->dex = atoi(str[15]);
+ status->luk = atoi(str[16]);
+ db->range2 = atoi(str[17]);
+ db->range3 = atoi(str[18]);
+ status->size = atoi(str[19]);
+ status->race = atoi(str[20]);
+
+ ele = atoi(str[21]);
+ status->def_ele = ele%10;
+ status->ele_lv = ele/20;
+ if( status->def_ele >= ELE_MAX )
+ {
+ ShowWarning("Mercenary %d has invalid element type %d (max element is %d)\n", db->class_, status->def_ele, ELE_MAX - 1);
+ status->def_ele = ELE_NEUTRAL;
+ }
+ if( status->ele_lv < 1 || status->ele_lv > 4 )
+ {
+ ShowWarning("Mercenary %d has invalid element level %d (max is 4)\n", db->class_, status->ele_lv);
+ status->ele_lv = 1;
+ }
+
+ status->aspd_rate = 1000;
+ status->speed = atoi(str[22]);
+ status->adelay = atoi(str[23]);
+ status->amotion = atoi(str[24]);
+ status->dmotion = atoi(str[25]);
+
+ return true;
}
int read_mercenarydb(void)
{
- memset(mercenary_db,0,sizeof(mercenary_db));
- sv_readdb(db_path, "mercenary_db.txt", ',', 26, 26, MAX_MERCENARY_CLASS, &read_mercenarydb_sub);
+ memset(mercenary_db,0,sizeof(mercenary_db));
+ sv_readdb(db_path, "mercenary_db.txt", ',', 26, 26, MAX_MERCENARY_CLASS, &read_mercenarydb_sub);
- return 0;
+ return 0;
}
-static bool read_mercenary_skilldb_sub(char *str[], int columns, int current)
-{
- // <merc id>,<skill id>,<skill level>
- struct s_mercenary_db *db;
- int i, class_;
- int skillid, skilllv;
-
- class_ = atoi(str[0]);
- ARR_FIND(0, MAX_MERCENARY_CLASS, i, class_ == mercenary_db[i].class_);
- if (i == MAX_MERCENARY_CLASS) {
- ShowError("read_mercenary_skilldb : Class %d not found in mercenary_db for skill entry.\n", class_);
- return false;
- }
-
- skillid = atoi(str[1]);
- if (skillid < MC_SKILLBASE || skillid >= MC_SKILLBASE + MAX_MERCSKILL) {
- ShowError("read_mercenary_skilldb : Skill %d out of range.\n", skillid);
- return false;
- }
-
- db = &mercenary_db[i];
- skilllv = atoi(str[2]);
-
- i = skillid - MC_SKILLBASE;
- db->skill[i].id = skillid;
- db->skill[i].lv = skilllv;
-
- return true;
+static bool read_mercenary_skilldb_sub(char* str[], int columns, int current)
+{// <merc id>,<skill id>,<skill level>
+ struct s_mercenary_db *db;
+ int i, class_;
+ int skillid, skilllv;
+
+ class_ = atoi(str[0]);
+ ARR_FIND(0, MAX_MERCENARY_CLASS, i, class_ == mercenary_db[i].class_);
+ if( i == MAX_MERCENARY_CLASS )
+ {
+ ShowError("read_mercenary_skilldb : Class %d not found in mercenary_db for skill entry.\n", class_);
+ return false;
+ }
+
+ skillid = atoi(str[1]);
+ if( skillid < MC_SKILLBASE || skillid >= MC_SKILLBASE + MAX_MERCSKILL )
+ {
+ ShowError("read_mercenary_skilldb : Skill %d out of range.\n", skillid);
+ return false;
+ }
+
+ db = &mercenary_db[i];
+ skilllv = atoi(str[2]);
+
+ i = skillid - MC_SKILLBASE;
+ db->skill[i].id = skillid;
+ db->skill[i].lv = skilllv;
+
+ return true;
}
int read_mercenary_skilldb(void)
{
- sv_readdb(db_path, "mercenary_skill_db.txt", ',', 3, 3, -1, &read_mercenary_skilldb_sub);
+ sv_readdb(db_path, "mercenary_skill_db.txt", ',', 3, 3, -1, &read_mercenary_skilldb_sub);
- return 0;
+ return 0;
}
int do_init_mercenary(void)
{
- read_mercenarydb();
- read_mercenary_skilldb();
-
- //add_timer_func_list(mercenary_contract, "mercenary_contract");
- return 0;
+ read_mercenarydb();
+ read_mercenary_skilldb();
+
+ //add_timer_func_list(mercenary_contract, "mercenary_contract");
+ return 0;
}
int do_final_mercenary(void);
diff --git a/src/map/mercenary.h b/src/map/mercenary.h
index 4de3f304e..014bd8937 100644
--- a/src/map/mercenary.h
+++ b/src/map/mercenary.h
@@ -11,46 +11,46 @@
#define MAX_MER_DISTANCE 15
enum {
- ARCH_MERC_GUILD,
- SPEAR_MERC_GUILD,
- SWORD_MERC_GUILD,
+ ARCH_MERC_GUILD,
+ SPEAR_MERC_GUILD,
+ SWORD_MERC_GUILD,
};
struct s_mercenary_db {
- int class_;
- char sprite[NAME_LENGTH], name[NAME_LENGTH];
- unsigned short lv;
- short range2, range3;
- struct status_data status;
- struct view_data vd;
- struct {
- unsigned short id, lv;
- } skill[MAX_MERCSKILL];
+ int class_;
+ char sprite[NAME_LENGTH], name[NAME_LENGTH];
+ unsigned short lv;
+ short range2, range3;
+ struct status_data status;
+ struct view_data vd;
+ struct {
+ unsigned short id, lv;
+ } skill[MAX_MERCSKILL];
};
extern struct s_mercenary_db mercenary_db[MAX_MERCENARY_CLASS];
struct mercenary_data {
- struct block_list bl;
- struct unit_data ud;
- struct view_data *vd;
- struct status_data base_status, battle_status;
- struct status_change sc;
- struct regen_data regen;
-
- struct s_mercenary_db *db;
- struct s_mercenary mercenary;
- char blockskill[MAX_SKILL];
-
- struct map_session_data *master;
- int contract_timer;
-
- unsigned devotion_flag : 1;
- unsigned int masterteleport_timer;
+ struct block_list bl;
+ struct unit_data ud;
+ struct view_data *vd;
+ struct status_data base_status, battle_status;
+ struct status_change sc;
+ struct regen_data regen;
+
+ struct s_mercenary_db *db;
+ struct s_mercenary mercenary;
+ char blockskill[MAX_SKILL];
+
+ struct map_session_data *master;
+ int contract_timer;
+
+ unsigned devotion_flag : 1;
+ unsigned int masterteleport_timer;
};
bool merc_class(int class_);
-struct view_data *merc_get_viewdata(int class_);
+struct view_data * merc_get_viewdata(int class_);
int merc_create(struct map_session_data *sd, int class_, unsigned int lifetime);
int merc_data_received(struct s_mercenary *merc, bool flag);
diff --git a/src/map/mob.c b/src/map/mob.c
index acec51df6..b512e0b26 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -42,40 +42,34 @@
#include <string.h>
#include <math.h>
-#define ACTIVE_AI_RANGE 2 //Distance added on top of 'AREA_SIZE' at which mobs enter active AI mode.
+#define ACTIVE_AI_RANGE 2 //Distance added on top of 'AREA_SIZE' at which mobs enter active AI mode.
-#define IDLE_SKILL_INTERVAL 10 //Active idle skills should be triggered every 1 second (1000/MIN_MOBTHINKTIME)
+#define IDLE_SKILL_INTERVAL 10 //Active idle skills should be triggered every 1 second (1000/MIN_MOBTHINKTIME)
-#define MOB_LAZYSKILLPERC 0 // Probability for mobs far from players from doing their IDLE skill. (rate of 1000 minute)
+#define MOB_LAZYSKILLPERC 0 // Probability for mobs far from players from doing their IDLE skill. (rate of 1000 minute)
// Move probability for mobs away from players (rate of 1000 minute)
// in Aegis, this is 100% for mobs that have been activated by players and none otherwise.
#define MOB_LAZYMOVEPERC(md) (md->state.spotted?1000:0)
#define MOB_MAX_DELAY (24*3600*1000)
-#define MAX_MINCHASE 30 //Max minimum chase value to use for mobs.
-#define RUDE_ATTACKED_COUNT 2 //After how many rude-attacks should the skill be used?
+#define MAX_MINCHASE 30 //Max minimum chase value to use for mobs.
+#define RUDE_ATTACKED_COUNT 2 //After how many rude-attacks should the skill be used?
#define MAX_MOB_CHAT 250 //Max Skill's messages
//Dynamic mob database, allows saving of memory when there's big gaps in the mob_db [Skotlex]
struct mob_db *mob_db_data[MAX_MOB_DB+1];
-struct mob_db *mob_dummy = NULL; //Dummy mob to be returned when a non-existant one is requested.
+struct mob_db *mob_dummy = NULL; //Dummy mob to be returned when a non-existant one is requested.
-struct mob_db *mob_db(int index) {
- if (index < 0 || index > MAX_MOB_DB || mob_db_data[index] == NULL) return mob_dummy;
- return mob_db_data[index];
-}
+struct mob_db *mob_db(int index) { if (index < 0 || index > MAX_MOB_DB || mob_db_data[index] == NULL) return mob_dummy; return mob_db_data[index]; }
//Dynamic mob chat database
struct mob_chat *mob_chat_db[MAX_MOB_CHAT+1];
-struct mob_chat *mob_chat(short id) {
- if (id<=0 || id>MAX_MOB_CHAT || mob_chat_db[id]==NULL) return (struct mob_chat *)NULL;
- return mob_chat_db[id];
-}
+struct mob_chat *mob_chat(short id) { if(id<=0 || id>MAX_MOB_CHAT || mob_chat_db[id]==NULL) return (struct mob_chat*)NULL; return mob_chat_db[id]; }
//Dynamic item drop ratio database for per-item drop ratio modifiers overriding global drop ratios.
#define MAX_ITEMRATIO_MOBS 10
struct item_drop_ratio {
- int drop_ratio;
- int mob_id[MAX_ITEMRATIO_MOBS];
+ int drop_ratio;
+ int mob_id[MAX_ITEMRATIO_MOBS];
};
static struct item_drop_ratio *item_drop_ratio_db[MAX_ITEMDB];
@@ -83,8 +77,8 @@ static struct eri *item_drop_ers; //For loot drops delay structures.
static struct eri *item_drop_list_ers;
static struct {
- int qty;
- int class_[350];
+ int qty;
+ int class_[350];
} summon[MAX_RANDOMMONSTER];
//Defines the Manuk/Splendide mob groups for the status reductions [Epoque]
@@ -103,29 +97,29 @@ int mob_skillid2skillidx(int class_,int skillid);
*------------------------------------------*/
int mobdb_searchname(const char *str)
{
- int i;
- struct mob_db *mob;
- for (i=0; i<=MAX_MOB_DB; i++) {
- mob = mob_db(i);
- if (mob == mob_dummy) //Skip dummy mobs.
- continue;
- if (strcmpi(mob->name,str)==0 || strcmpi(mob->jname,str)==0 || strcmpi(mob->sprite,str)==0)
- return i;
- }
-
- return 0;
+ int i;
+ struct mob_db* mob;
+ for(i=0;i<=MAX_MOB_DB;i++){
+ mob = mob_db(i);
+ if(mob == mob_dummy) //Skip dummy mobs.
+ continue;
+ if(strcmpi(mob->name,str)==0 || strcmpi(mob->jname,str)==0 || strcmpi(mob->sprite,str)==0)
+ return i;
+ }
+
+ return 0;
}
-static int mobdb_searchname_array_sub(struct mob_db *mob, const char *str)
+static int mobdb_searchname_array_sub(struct mob_db* mob, const char *str)
{
- if (mob == mob_dummy)
- return 1; //Invalid mob.
- if (!mob->base_exp && !mob->job_exp)
- return 1; //Discount slave-mobs (no exp) as requested by Playtester. [Skotlex]
- if (stristr(mob->jname,str))
- return 0;
- if (stristr(mob->name,str))
- return 0;
- return strcmpi(mob->jname,str);
+ if (mob == mob_dummy)
+ return 1; //Invalid mob.
+ if(!mob->base_exp && !mob->job_exp)
+ return 1; //Discount slave-mobs (no exp) as requested by Playtester. [Skotlex]
+ if(stristr(mob->jname,str))
+ return 0;
+ if(stristr(mob->name,str))
+ return 0;
+ return strcmpi(mob->jname,str);
}
/*==========================================
@@ -133,90 +127,89 @@ static int mobdb_searchname_array_sub(struct mob_db *mob, const char *str)
*------------------------------------------*/
void mvptomb_create(struct mob_data *md, char *killer, time_t time)
{
- struct npc_data *nd;
+ struct npc_data *nd;
- if (md->tomb_nid)
- mvptomb_destroy(md);
+ if ( md->tomb_nid )
+ mvptomb_destroy(md);
- CREATE(nd, struct npc_data, 1);
+ CREATE(nd, struct npc_data, 1);
- nd->bl.id = md->tomb_nid = npc_get_new_npc_id();
+ nd->bl.id = md->tomb_nid = npc_get_new_npc_id();
nd->ud.dir = md->ud.dir;
- nd->bl.m = md->bl.m;
- nd->bl.x = md->bl.x;
- nd->bl.y = md->bl.y;
- nd->bl.type = BL_NPC;
+ nd->bl.m = md->bl.m;
+ nd->bl.x = md->bl.x;
+ nd->bl.y = md->bl.y;
+ nd->bl.type = BL_NPC;
- safestrncpy(nd->name, msg_txt(656), sizeof(nd->name));
+ safestrncpy(nd->name, msg_txt(656), sizeof(nd->name));
- nd->class_ = 565;
- nd->speed = 200;
- nd->subtype = TOMB;
+ nd->class_ = 565;
+ nd->speed = 200;
+ nd->subtype = TOMB;
- nd->u.tomb.md = md;
- nd->u.tomb.kill_time = time;
+ nd->u.tomb.md = md;
+ nd->u.tomb.kill_time = time;
- if (killer)
- safestrncpy(nd->u.tomb.killer_name, killer, NAME_LENGTH);
- else
- nd->u.tomb.killer_name[0] = '\0';
+ if (killer)
+ safestrncpy(nd->u.tomb.killer_name, killer, NAME_LENGTH);
+ else
+ nd->u.tomb.killer_name[0] = '\0';
- map_addnpc(nd->bl.m, nd);
- map_addblock(&nd->bl);
- status_set_viewdata(&nd->bl, nd->class_);
+ map_addnpc(nd->bl.m, nd);
+ map_addblock(&nd->bl);
+ status_set_viewdata(&nd->bl, nd->class_);
status_change_init(&nd->bl);
unit_dataset(&nd->bl);
clif_spawn(&nd->bl);
}
-void mvptomb_destroy(struct mob_data *md)
-{
- struct npc_data *nd;
+void mvptomb_destroy(struct mob_data *md) {
+ struct npc_data *nd;
- if ((nd = map_id2nd(md->tomb_nid))) {
- int m, i;
+ if ( (nd = map_id2nd(md->tomb_nid)) ) {
+ int m, i;
- m = nd->bl.m;
+ m = nd->bl.m;
- clif_clearunit_area(&nd->bl,CLR_OUTSIGHT);
+ clif_clearunit_area(&nd->bl,CLR_OUTSIGHT);
- map_delblock(&nd->bl);
+ map_delblock(&nd->bl);
- ARR_FIND(0, map[m].npc_num, i, map[m].npc[i] == nd);
- if (!(i == map[m].npc_num)) {
- map[m].npc_num--;
- map[m].npc[i] = map[m].npc[map[m].npc_num];
- map[m].npc[map[m].npc_num] = NULL;
- }
+ ARR_FIND( 0, map[m].npc_num, i, map[m].npc[i] == nd );
+ if( !(i == map[m].npc_num) ) {
+ map[m].npc_num--;
+ map[m].npc[i] = map[m].npc[map[m].npc_num];
+ map[m].npc[map[m].npc_num] = NULL;
+ }
- map_deliddb(&nd->bl);
+ map_deliddb(&nd->bl);
- aFree(nd);
- }
+ aFree(nd);
+ }
- md->tomb_nid = 0;
+ md->tomb_nid = 0;
}
/*==========================================
* Founds up to N matches. Returns number of matches [Skotlex]
*------------------------------------------*/
-int mobdb_searchname_array(struct mob_db **data, int size, const char *str)
+int mobdb_searchname_array(struct mob_db** data, int size, const char *str)
{
- int count = 0, i;
- struct mob_db *mob;
- for (i=0; i<=MAX_MOB_DB; i++) {
- mob = mob_db(i);
- if (mob == mob_dummy || mob_is_clone(i)) //keep clones out (or you leak player stats)
- continue;
- if (!mobdb_searchname_array_sub(mob, str)) {
- if (count < size)
- data[count] = mob;
- count++;
- }
- }
- return count;
+ int count = 0, i;
+ struct mob_db* mob;
+ for(i=0;i<=MAX_MOB_DB;i++){
+ mob = mob_db(i);
+ if (mob == mob_dummy || mob_is_clone(i) ) //keep clones out (or you leak player stats)
+ continue;
+ if (!mobdb_searchname_array_sub(mob, str)) {
+ if (count < size)
+ data[count] = mob;
+ count++;
+ }
+ }
+ return count;
}
/*==========================================
@@ -224,78 +217,81 @@ int mobdb_searchname_array(struct mob_db **data, int size, const char *str)
*------------------------------------------*/
int mobdb_checkid(const int id)
{
- if (mob_db(id) == mob_dummy)
- return 0;
- if (mob_is_clone(id)) //checkid is used mostly for random ID based code, therefore clone mobs are out of the question.
- return 0;
- return id;
+ if (mob_db(id) == mob_dummy)
+ return 0;
+ if (mob_is_clone(id)) //checkid is used mostly for random ID based code, therefore clone mobs are out of the question.
+ return 0;
+ return id;
}
/*==========================================
* Returns the view data associated to this mob class.
*------------------------------------------*/
-struct view_data *mob_get_viewdata(int class_) {
- if (mob_db(class_) == mob_dummy)
- return 0;
- return &mob_db(class_)->vd;
+struct view_data * mob_get_viewdata(int class_)
+{
+ if (mob_db(class_) == mob_dummy)
+ return 0;
+ return &mob_db(class_)->vd;
}
/*==========================================
* Cleans up mob-spawn data to make it "valid"
*------------------------------------------*/
int mob_parse_dataset(struct spawn_data *data)
{
- size_t len;
+ size_t len;
- if ((!mobdb_checkid(data->class_) && !mob_is_clone(data->class_)) || !data->num)
- return 0;
+ if ((!mobdb_checkid(data->class_) && !mob_is_clone(data->class_)) || !data->num)
+ return 0;
- if ((len = strlen(data->eventname)) > 0) {
- if (data->eventname[len-1] == '"')
- data->eventname[len-1] = '\0'; //Remove trailing quote.
- if (data->eventname[0] == '"') //Strip leading quotes
- memmove(data->eventname, data->eventname+1, len-1);
- }
+ if( ( len = strlen(data->eventname) ) > 0 )
+ {
+ if( data->eventname[len-1] == '"' )
+ data->eventname[len-1] = '\0'; //Remove trailing quote.
+ if( data->eventname[0] == '"' ) //Strip leading quotes
+ memmove(data->eventname, data->eventname+1, len-1);
+ }
- if (strcmp(data->name,"--en--")==0)
- safestrncpy(data->name, mob_db(data->class_)->name, sizeof(data->name));
- else if (strcmp(data->name,"--ja--")==0)
- safestrncpy(data->name, mob_db(data->class_)->jname, sizeof(data->name));
+ if(strcmp(data->name,"--en--")==0)
+ safestrncpy(data->name, mob_db(data->class_)->name, sizeof(data->name));
+ else if(strcmp(data->name,"--ja--")==0)
+ safestrncpy(data->name, mob_db(data->class_)->jname, sizeof(data->name));
- return 1;
+ return 1;
}
/*==========================================
* Generates the basic mob data using the spawn_data provided.
*------------------------------------------*/
-struct mob_data *mob_spawn_dataset(struct spawn_data *data) {
- struct mob_data *md = (struct mob_data *)aCalloc(1, sizeof(struct mob_data));
- md->bl.id= npc_get_new_npc_id();
- md->bl.type = BL_MOB;
- md->bl.m = data->m;
- md->bl.x = data->x;
- md->bl.y = data->y;
- md->class_ = data->class_;
- md->state.boss = data->state.boss;
- md->db = mob_db(md->class_);
- if (data->level > 0 && data->level <= MAX_LEVEL)
- md->level = data->level;
- memcpy(md->name, data->name, NAME_LENGTH);
- if (data->state.ai)
- md->special_state.ai = data->state.ai;
- if (data->state.size)
- md->special_state.size = data->state.size;
- if (data->eventname[0] && strlen(data->eventname) >= 4)
- memcpy(md->npc_event, data->eventname, 50);
- if (md->db->status.mode &MD_LOOTER)
- md->lootitem = (struct item *)aCalloc(LOOTITEM_SIZE,sizeof(struct item));
- md->spawn_timer = INVALID_TIMER;
- md->deletetimer = INVALID_TIMER;
- md->skillidx = -1;
- status_set_viewdata(&md->bl, md->class_);
- status_change_init(&md->bl);
- unit_dataset(&md->bl);
-
- map_addiddb(&md->bl);
- return md;
+struct mob_data* mob_spawn_dataset(struct spawn_data *data)
+{
+ struct mob_data *md = (struct mob_data*)aCalloc(1, sizeof(struct mob_data));
+ md->bl.id= npc_get_new_npc_id();
+ md->bl.type = BL_MOB;
+ md->bl.m = data->m;
+ md->bl.x = data->x;
+ md->bl.y = data->y;
+ md->class_ = data->class_;
+ md->state.boss = data->state.boss;
+ md->db = mob_db(md->class_);
+ if (data->level > 0 && data->level <= MAX_LEVEL)
+ md->level = data->level;
+ memcpy(md->name, data->name, NAME_LENGTH);
+ if (data->state.ai)
+ md->special_state.ai = data->state.ai;
+ if (data->state.size)
+ md->special_state.size = data->state.size;
+ if (data->eventname[0] && strlen(data->eventname) >= 4)
+ memcpy(md->npc_event, data->eventname, 50);
+ if(md->db->status.mode&MD_LOOTER)
+ md->lootitem = (struct item *)aCalloc(LOOTITEM_SIZE,sizeof(struct item));
+ md->spawn_timer = INVALID_TIMER;
+ md->deletetimer = INVALID_TIMER;
+ md->skillidx = -1;
+ status_set_viewdata(&md->bl, md->class_);
+ status_change_init(&md->bl);
+ unit_dataset(&md->bl);
+
+ map_addiddb(&md->bl);
+ return md;
}
/*==========================================
@@ -313,436 +309,460 @@ struct mob_data *mob_spawn_dataset(struct spawn_data *data) {
*------------------------------------------*/
int mob_get_random_id(int type, int flag, int lv)
{
- struct mob_db *mob;
- int i=0, class_;
- if (type < 0 || type >= MAX_RANDOMMONSTER) {
- ShowError("mob_get_random_id: Invalid type (%d) of random monster.\n", type);
- return 0;
- }
- do {
- if (type)
- class_ = summon[type].class_[rnd()%summon[type].qty];
- else //Dead branch
- class_ = rnd() % MAX_MOB_DB;
- mob = mob_db(class_);
- } while ((mob == mob_dummy ||
- mob_is_clone(class_) ||
- (flag&1 && mob->summonper[type] <= rnd() % 1000000) ||
- (flag&2 && lv < mob->lv) ||
- (flag&4 && mob->status.mode&MD_BOSS) ||
- (flag&8 && mob->spawn[0].qty < 1)
- ) && (i++) < MAX_MOB_DB);
-
- if (i >= MAX_MOB_DB) // no suitable monster found, use fallback for given list
- class_ = mob_db_data[0]->summonper[type];
- return class_;
+ struct mob_db *mob;
+ int i=0, class_;
+ if(type < 0 || type >= MAX_RANDOMMONSTER) {
+ ShowError("mob_get_random_id: Invalid type (%d) of random monster.\n", type);
+ return 0;
+ }
+ do {
+ if (type)
+ class_ = summon[type].class_[rnd()%summon[type].qty];
+ else //Dead branch
+ class_ = rnd() % MAX_MOB_DB;
+ mob = mob_db(class_);
+ } while ((mob == mob_dummy ||
+ mob_is_clone(class_) ||
+ (flag&1 && mob->summonper[type] <= rnd() % 1000000) ||
+ (flag&2 && lv < mob->lv) ||
+ (flag&4 && mob->status.mode&MD_BOSS) ||
+ (flag&8 && mob->spawn[0].qty < 1)
+ ) && (i++) < MAX_MOB_DB);
+
+ if(i >= MAX_MOB_DB) // no suitable monster found, use fallback for given list
+ class_ = mob_db_data[0]->summonper[type];
+ return class_;
}
/*==========================================
* Kill Steal Protection [Zephyrus]
*------------------------------------------*/
-bool mob_ksprotected(struct block_list *src, struct block_list *target)
+bool mob_ksprotected (struct block_list *src, struct block_list *target)
{
- struct block_list *s_bl, *t_bl;
- struct map_session_data
- *sd, // Source
- *pl_sd, // Owner
- *t_sd; // Mob Target
- struct status_change_entry *sce;
- struct mob_data *md;
- unsigned int tick = gettick();
- char output[128];
+ struct block_list *s_bl, *t_bl;
+ struct map_session_data
+ *sd, // Source
+ *pl_sd, // Owner
+ *t_sd; // Mob Target
+ struct status_change_entry *sce;
+ struct mob_data *md;
+ unsigned int tick = gettick();
+ char output[128];
- if (!battle_config.ksprotection)
- return false; // KS Protection Disabled
+ if( !battle_config.ksprotection )
+ return false; // KS Protection Disabled
- if (!(md = BL_CAST(BL_MOB,target)))
- return false; // Tarjet is not MOB
+ if( !(md = BL_CAST(BL_MOB,target)) )
+ return false; // Tarjet is not MOB
- if ((s_bl = battle_get_master(src)) == NULL)
- s_bl = src;
+ if( (s_bl = battle_get_master(src)) == NULL )
+ s_bl = src;
- if (!(sd = BL_CAST(BL_PC,s_bl)))
- return false; // Master is not PC
+ if( !(sd = BL_CAST(BL_PC,s_bl)) )
+ return false; // Master is not PC
- t_bl = map_id2bl(md->target_id);
- if (!t_bl || (s_bl = battle_get_master(t_bl)) == NULL)
- s_bl = t_bl;
+ t_bl = map_id2bl(md->target_id);
+ if( !t_bl || (s_bl = battle_get_master(t_bl)) == NULL )
+ s_bl = t_bl;
- t_sd = BL_CAST(BL_PC,s_bl);
+ t_sd = BL_CAST(BL_PC,s_bl);
- do {
- if (map[md->bl.m].flag.allowks || map_flag_ks(md->bl.m))
- return false; // Ignores GVG, PVP and AllowKS map flags
+ do {
+ if( map[md->bl.m].flag.allowks || map_flag_ks(md->bl.m) )
+ return false; // Ignores GVG, PVP and AllowKS map flags
- if (md->db->mexp || md->master_id)
- return false; // MVP, Slaves mobs ignores KS
+ if( md->db->mexp || md->master_id )
+ return false; // MVP, Slaves mobs ignores KS
- if ((sce = md->sc.data[SC_KSPROTECTED]) == NULL)
- break; // No KS Protected
+ if( (sce = md->sc.data[SC_KSPROTECTED]) == NULL )
+ break; // No KS Protected
- if (sd->bl.id == sce->val1 || // Same Owner
- (sce->val2 == 2 && sd->status.party_id && sd->status.party_id == sce->val3) || // Party KS allowed
- (sce->val2 == 3 && sd->status.guild_id && sd->status.guild_id == sce->val4)) // Guild KS allowed
- break;
+ if( sd->bl.id == sce->val1 || // Same Owner
+ (sce->val2 == 2 && sd->status.party_id && sd->status.party_id == sce->val3) || // Party KS allowed
+ (sce->val2 == 3 && sd->status.guild_id && sd->status.guild_id == sce->val4) ) // Guild KS allowed
+ break;
- if (t_sd && (
- (sce->val2 == 1 && sce->val1 != t_sd->bl.id) ||
- (sce->val2 == 2 && sce->val3 && sce->val3 != t_sd->status.party_id) ||
- (sce->val2 == 3 && sce->val4 && sce->val4 != t_sd->status.guild_id)))
- break;
+ if( t_sd && (
+ (sce->val2 == 1 && sce->val1 != t_sd->bl.id) ||
+ (sce->val2 == 2 && sce->val3 && sce->val3 != t_sd->status.party_id) ||
+ (sce->val2 == 3 && sce->val4 && sce->val4 != t_sd->status.guild_id)) )
+ break;
- if ((pl_sd = map_id2sd(sce->val1)) == NULL || pl_sd->bl.m != md->bl.m)
- break;
+ if( (pl_sd = map_id2sd(sce->val1)) == NULL || pl_sd->bl.m != md->bl.m )
+ break;
- if (!pl_sd->state.noks)
- return false; // No KS Protected, but normal players should be protected too
+ if( !pl_sd->state.noks )
+ return false; // No KS Protected, but normal players should be protected too
- // Message to KS
- if (DIFF_TICK(sd->ks_floodprotect_tick, tick) <= 0) {
- sprintf(output, "[KS Warning!! - Owner : %s]", pl_sd->status.name);
- clif_disp_onlyself(sd, output, strlen(output));
+ // Message to KS
+ if( DIFF_TICK(sd->ks_floodprotect_tick, tick) <= 0 )
+ {
+ sprintf(output, "[KS Warning!! - Owner : %s]", pl_sd->status.name);
+ clif_disp_onlyself(sd, output, strlen(output));
- sd->ks_floodprotect_tick = tick + 2000;
- }
+ sd->ks_floodprotect_tick = tick + 2000;
+ }
- // Message to Owner
- if (DIFF_TICK(pl_sd->ks_floodprotect_tick, tick) <= 0) {
- sprintf(output, "[Watch out! %s is trying to KS you!]", sd->status.name);
- clif_disp_onlyself(pl_sd, output, strlen(output));
+ // Message to Owner
+ if( DIFF_TICK(pl_sd->ks_floodprotect_tick, tick) <= 0 )
+ {
+ sprintf(output, "[Watch out! %s is trying to KS you!]", sd->status.name);
+ clif_disp_onlyself(pl_sd, output, strlen(output));
- pl_sd->ks_floodprotect_tick = tick + 2000;
- }
+ pl_sd->ks_floodprotect_tick = tick + 2000;
+ }
- return true;
- } while (0);
+ return true;
+ } while(0);
- status_change_start(target, SC_KSPROTECTED, 10000, sd->bl.id, sd->state.noks, sd->status.party_id, sd->status.guild_id, battle_config.ksprotection, 0);
+ status_change_start(target, SC_KSPROTECTED, 10000, sd->bl.id, sd->state.noks, sd->status.party_id, sd->status.guild_id, battle_config.ksprotection, 0);
- return false;
+ return false;
}
-struct mob_data *mob_once_spawn_sub(struct block_list *bl, int m, short x, short y, const char *mobname, int class_, const char *event, unsigned int size, unsigned int ai) {
- struct spawn_data data;
+struct mob_data *mob_once_spawn_sub(struct block_list *bl, int m, short x, short y, const char *mobname, int class_, const char *event, unsigned int size, unsigned int ai)
+{
+ struct spawn_data data;
- memset(&data, 0, sizeof(struct spawn_data));
- data.m = m;
- data.num = 1;
- data.class_ = class_;
- data.state.size = size;
- data.state.ai = ai;
+ memset(&data, 0, sizeof(struct spawn_data));
+ data.m = m;
+ data.num = 1;
+ data.class_ = class_;
+ data.state.size = size;
+ data.state.ai = ai;
- if (mobname)
- safestrncpy(data.name, mobname, sizeof(data.name));
- else if (battle_config.override_mob_names == 1)
- strcpy(data.name, "--en--");
- else
- strcpy(data.name, "--ja--");
+ if (mobname)
+ safestrncpy(data.name, mobname, sizeof(data.name));
+ else
+ if (battle_config.override_mob_names == 1)
+ strcpy(data.name, "--en--");
+ else
+ strcpy(data.name, "--ja--");
- if (event)
- safestrncpy(data.eventname, event, sizeof(data.eventname));
+ if (event)
+ safestrncpy(data.eventname, event, sizeof(data.eventname));
- // Locate spot next to player.
- if (bl && (x < 0 || y < 0))
- map_search_freecell(bl, m, &x, &y, 1, 1, 0);
+ // Locate spot next to player.
+ if (bl && (x < 0 || y < 0))
+ map_search_freecell(bl, m, &x, &y, 1, 1, 0);
- // if none found, pick random position on map
- if (x <= 0 || y <= 0 || map_getcell(m,x,y,CELL_CHKNOREACH))
- map_search_freecell(NULL, m, &x, &y, -1, -1, 1);
+ // if none found, pick random position on map
+ if (x <= 0 || y <= 0 || map_getcell(m,x,y,CELL_CHKNOREACH))
+ map_search_freecell(NULL, m, &x, &y, -1, -1, 1);
- data.x = x;
- data.y = y;
+ data.x = x;
+ data.y = y;
- if (!mob_parse_dataset(&data))
- return NULL;
+ if (!mob_parse_dataset(&data))
+ return NULL;
- return mob_spawn_dataset(&data);
+ return mob_spawn_dataset(&data);
}
/*==========================================
* Spawn a single mob on the specified coordinates.
*------------------------------------------*/
-int mob_once_spawn(struct map_session_data *sd, int m, short x, short y, const char *mobname, int class_, int amount, const char *event, unsigned int size, unsigned int ai)
+int mob_once_spawn(struct map_session_data* sd, int m, short x, short y, const char* mobname, int class_, int amount, const char* event, unsigned int size, unsigned int ai)
{
- struct mob_data *md = NULL;
- int count, lv;
-
- if (m < 0 || amount <= 0)
- return 0; // invalid input
-
- lv = (sd) ? sd->status.base_level : 255;
-
- for (count = 0; count < amount; count++) {
- int c = (class_ >= 0) ? class_ : mob_get_random_id(-class_ - 1, (battle_config.random_monster_checklv) ? 3 : 1, lv);
- md = mob_once_spawn_sub((sd) ? &sd->bl : NULL, m, x, y, mobname, c, event, size, ai);
-
- if (!md)
- continue;
-
- if (class_ == MOBID_EMPERIUM) {
- struct guild_castle *gc = guild_mapindex2gc(map[m].index);
- struct guild *g = (gc) ? guild_search(gc->guild_id) : NULL;
- if (gc) {
- md->guardian_data = (struct guardian_data *)aCalloc(1, sizeof(struct guardian_data));
- md->guardian_data->castle = gc;
- md->guardian_data->number = MAX_GUARDIANS;
- md->guardian_data->guild_id = gc->guild_id;
- if (g) {
- md->guardian_data->emblem_id = g->emblem_id;
- memcpy(md->guardian_data->guild_name, g->name, NAME_LENGTH);
- } else if (gc->guild_id) //Guild not yet available, retry in 5.
- add_timer(gettick()+5000,mob_spawn_guardian_sub,md->bl.id,md->guardian_data->guild_id);
- }
- } // end addition [Valaris]
-
- mob_spawn(md);
-
- if (class_ < 0 && battle_config.dead_branch_active)
- //Behold Aegis's masterful decisions yet again...
- //"I understand the "Aggressive" part, but the "Can Move" and "Can Attack" is just stupid" - Poki#3
- sc_start4(&md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE|MD_CANATTACK|MD_CANMOVE|MD_ANGRY, 0, 60000);
- }
-
- return (md) ? md->bl.id : 0; // id of last spawned mob
+ struct mob_data* md = NULL;
+ int count, lv;
+
+ if (m < 0 || amount <= 0)
+ return 0; // invalid input
+
+ lv = (sd) ? sd->status.base_level : 255;
+
+ for (count = 0; count < amount; count++)
+ {
+ int c = (class_ >= 0) ? class_ : mob_get_random_id(-class_ - 1, (battle_config.random_monster_checklv) ? 3 : 1, lv);
+ md = mob_once_spawn_sub((sd) ? &sd->bl : NULL, m, x, y, mobname, c, event, size, ai);
+
+ if (!md)
+ continue;
+
+ if (class_ == MOBID_EMPERIUM)
+ {
+ struct guild_castle* gc = guild_mapindex2gc(map[m].index);
+ struct guild* g = (gc) ? guild_search(gc->guild_id) : NULL;
+ if (gc)
+ {
+ md->guardian_data = (struct guardian_data*)aCalloc(1, sizeof(struct guardian_data));
+ md->guardian_data->castle = gc;
+ md->guardian_data->number = MAX_GUARDIANS;
+ md->guardian_data->guild_id = gc->guild_id;
+ if (g)
+ {
+ md->guardian_data->emblem_id = g->emblem_id;
+ memcpy(md->guardian_data->guild_name, g->name, NAME_LENGTH);
+ }
+ else if (gc->guild_id) //Guild not yet available, retry in 5.
+ add_timer(gettick()+5000,mob_spawn_guardian_sub,md->bl.id,md->guardian_data->guild_id);
+ }
+ } // end addition [Valaris]
+
+ mob_spawn(md);
+
+ if (class_ < 0 && battle_config.dead_branch_active)
+ //Behold Aegis's masterful decisions yet again...
+ //"I understand the "Aggressive" part, but the "Can Move" and "Can Attack" is just stupid" - Poki#3
+ sc_start4(&md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE|MD_CANATTACK|MD_CANMOVE|MD_ANGRY, 0, 60000);
+ }
+
+ return (md) ? md->bl.id : 0; // id of last spawned mob
}
/*==========================================
* Spawn mobs in the specified area.
*------------------------------------------*/
-int mob_once_spawn_area(struct map_session_data *sd, int m, int x0, int y0, int x1, int y1, const char *mobname, int class_, int amount, const char *event, unsigned int size, unsigned int ai)
+int mob_once_spawn_area(struct map_session_data* sd, int m, int x0, int y0, int x1, int y1, const char* mobname, int class_, int amount, const char* event, unsigned int size, unsigned int ai)
{
- int i, max, id = 0;
- int lx = -1, ly = -1;
-
- if (m < 0 || amount <= 0)
- return 0; // invalid input
-
- // normalize x/y coordinates
- if (x0 > x1)
- swap(x0, x1);
- if (y0 > y1)
- swap(y0, y1);
-
- // choose a suitable max. number of attempts
- max = (y1 - y0 + 1)*(x1 - x0 + 1)*3;
- if (max > 1000)
- max = 1000;
-
- // spawn mobs, one by one
- for (i = 0; i < amount; i++) {
- int x, y;
- int j = 0;
-
- // find a suitable map cell
- do {
- x = rnd()%(x1-x0+1)+x0;
- y = rnd()%(y1-y0+1)+y0;
- j++;
- } while (map_getcell(m,x,y,CELL_CHKNOPASS) && j < max);
-
- if (j == max) {
- // attempt to find an available cell failed
- if (lx == -1 && ly == -1)
- return 0; // total failure
-
- // fallback to last good x/y pair
- x = lx;
- y = ly;
- }
-
- // record last successful coordinates
- lx = x;
- ly = y;
-
- id = mob_once_spawn(sd, m, x, y, mobname, class_, 1, event, size, ai);
- }
-
- return id; // id of last spawned mob
+ int i, max, id = 0;
+ int lx = -1, ly = -1;
+
+ if (m < 0 || amount <= 0)
+ return 0; // invalid input
+
+ // normalize x/y coordinates
+ if (x0 > x1)
+ swap(x0, x1);
+ if (y0 > y1)
+ swap(y0, y1);
+
+ // choose a suitable max. number of attempts
+ max = (y1 - y0 + 1)*(x1 - x0 + 1)*3;
+ if (max > 1000)
+ max = 1000;
+
+ // spawn mobs, one by one
+ for (i = 0; i < amount; i++)
+ {
+ int x, y;
+ int j = 0;
+
+ // find a suitable map cell
+ do {
+ x = rnd()%(x1-x0+1)+x0;
+ y = rnd()%(y1-y0+1)+y0;
+ j++;
+ } while (map_getcell(m,x,y,CELL_CHKNOPASS) && j < max);
+
+ if (j == max)
+ {// attempt to find an available cell failed
+ if (lx == -1 && ly == -1)
+ return 0; // total failure
+
+ // fallback to last good x/y pair
+ x = lx;
+ y = ly;
+ }
+
+ // record last successful coordinates
+ lx = x;
+ ly = y;
+
+ id = mob_once_spawn(sd, m, x, y, mobname, class_, 1, event, size, ai);
+ }
+
+ return id; // id of last spawned mob
}
/*==========================================
* Set a Guardian's guild data [Skotlex]
*------------------------------------------*/
static int mob_spawn_guardian_sub(int tid, unsigned int tick, int id, intptr_t data)
-{
- //Needed because the guild_data may not be available at guardian spawn time.
- struct block_list *bl = map_id2bl(id);
- struct mob_data *md;
- struct guild *g;
- int guardup_lv;
-
- if (bl == NULL) //It is possible mob was already removed from map when the castle has no owner. [Skotlex]
- return 0;
-
- if (bl->type != BL_MOB) {
- ShowError("mob_spawn_guardian_sub: Block error!\n");
- return 0;
- }
-
- md = (struct mob_data *)bl;
- nullpo_ret(md->guardian_data);
- g = guild_search((int)data);
-
- if (g == NULL) {
- //Liberate castle, if the guild is not found this is an error! [Skotlex]
- ShowError("mob_spawn_guardian_sub: Couldn't load guild %d!\n", (int)data);
- if (md->class_ == MOBID_EMPERIUM) {
- //Not sure this is the best way, but otherwise we'd be invoking this for ALL guardians spawned later on.
- md->guardian_data->guild_id = 0;
- if (md->guardian_data->castle->guild_id) { //Free castle up.
- ShowNotice("Clearing ownership of castle %d (%s)\n", md->guardian_data->castle->castle_id, md->guardian_data->castle->castle_name);
- guild_castledatasave(md->guardian_data->castle->castle_id, 1, 0);
- }
- } else {
- if (md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS && md->guardian_data->castle->guardian[md->guardian_data->number].visible)
- guild_castledatasave(md->guardian_data->castle->castle_id, 10+md->guardian_data->number,0);
- unit_free(&md->bl,CLR_OUTSIGHT); //Remove guardian.
- }
- return 0;
- }
- guardup_lv = guild_checkskill(g,GD_GUARDUP);
- md->guardian_data->emblem_id = g->emblem_id;
- memcpy(md->guardian_data->guild_name, g->name, NAME_LENGTH);
- md->guardian_data->guardup_lv = guardup_lv;
- if (guardup_lv)
- status_calc_mob(md, 0); //Give bonuses.
- return 0;
+{ //Needed because the guild_data may not be available at guardian spawn time.
+ struct block_list* bl = map_id2bl(id);
+ struct mob_data* md;
+ struct guild* g;
+ int guardup_lv;
+
+ if (bl == NULL) //It is possible mob was already removed from map when the castle has no owner. [Skotlex]
+ return 0;
+
+ if (bl->type != BL_MOB)
+ {
+ ShowError("mob_spawn_guardian_sub: Block error!\n");
+ return 0;
+ }
+
+ md = (struct mob_data*)bl;
+ nullpo_ret(md->guardian_data);
+ g = guild_search((int)data);
+
+ if (g == NULL)
+ { //Liberate castle, if the guild is not found this is an error! [Skotlex]
+ ShowError("mob_spawn_guardian_sub: Couldn't load guild %d!\n", (int)data);
+ if (md->class_ == MOBID_EMPERIUM)
+ { //Not sure this is the best way, but otherwise we'd be invoking this for ALL guardians spawned later on.
+ md->guardian_data->guild_id = 0;
+ if (md->guardian_data->castle->guild_id) //Free castle up.
+ {
+ ShowNotice("Clearing ownership of castle %d (%s)\n", md->guardian_data->castle->castle_id, md->guardian_data->castle->castle_name);
+ guild_castledatasave(md->guardian_data->castle->castle_id, 1, 0);
+ }
+ } else {
+ if (md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS && md->guardian_data->castle->guardian[md->guardian_data->number].visible)
+ guild_castledatasave(md->guardian_data->castle->castle_id, 10+md->guardian_data->number,0);
+ unit_free(&md->bl,CLR_OUTSIGHT); //Remove guardian.
+ }
+ return 0;
+ }
+ guardup_lv = guild_checkskill(g,GD_GUARDUP);
+ md->guardian_data->emblem_id = g->emblem_id;
+ memcpy(md->guardian_data->guild_name, g->name, NAME_LENGTH);
+ md->guardian_data->guardup_lv = guardup_lv;
+ if( guardup_lv )
+ status_calc_mob(md, 0); //Give bonuses.
+ return 0;
}
/*==========================================
* Summoning Guardians [Valaris]
*------------------------------------------*/
-int mob_spawn_guardian(const char *mapname, short x, short y, const char *mobname, int class_, const char *event, int guardian, bool has_index)
+int mob_spawn_guardian(const char* mapname, short x, short y, const char* mobname, int class_, const char* event, int guardian, bool has_index)
{
- struct mob_data *md=NULL;
- struct spawn_data data;
- struct guild *g=NULL;
- struct guild_castle *gc;
- int m;
- memset(&data, 0, sizeof(struct spawn_data));
- data.num = 1;
-
- m=map_mapname2mapid(mapname);
-
- if (m<0) {
- ShowWarning("mob_spawn_guardian: Map [%s] not found.\n", mapname);
- return 0;
- }
- data.m = m;
- data.num = 1;
- if (class_<=0) {
- class_ = mob_get_random_id(-class_-1, 1, 99);
- if (!class_) return 0;
- }
-
- data.class_ = class_;
-
- if (!has_index) {
- guardian = -1;
- } else if (guardian < 0 || guardian >= MAX_GUARDIANS) {
- ShowError("mob_spawn_guardian: Invalid guardian index %d for guardian %d (castle map %s)\n", guardian, class_, map[m].name);
- return 0;
- }
-
- if ((x<=0 || y<=0) && !map_search_freecell(NULL, m, &x, &y, -1,-1, 1)) {
- ShowWarning("mob_spawn_guardian: Couldn't locate a spawn cell for guardian class %d (index %d) at castle map %s\n",class_, guardian, map[m].name);
- return 0;
- }
- data.x = x;
- data.y = y;
- safestrncpy(data.name, mobname, sizeof(data.name));
- safestrncpy(data.eventname, event, sizeof(data.eventname));
- if (!mob_parse_dataset(&data))
- return 0;
-
- gc=guild_mapname2gc(map[m].name);
- if (gc == NULL) {
- ShowError("mob_spawn_guardian: No castle set at map %s\n", map[m].name);
- return 0;
- }
- if (!gc->guild_id)
- ShowWarning("mob_spawn_guardian: Spawning guardian %d on a castle with no guild (castle map %s)\n", class_, map[m].name);
- else
- g = guild_search(gc->guild_id);
-
- if (has_index && gc->guardian[guardian].id) {
- //Check if guardian already exists, refuse to spawn if so.
- struct mob_data *md2 = (TBL_MOB *)map_id2bl(gc->guardian[guardian].id);
- if (md2 && md2->bl.type == BL_MOB &&
- md2->guardian_data && md2->guardian_data->number == guardian) {
- ShowError("mob_spawn_guardian: Attempted to spawn guardian in position %d which already has a guardian (castle map %s)\n", guardian, map[m].name);
- return 0;
- }
- }
-
- md = mob_spawn_dataset(&data);
- md->guardian_data = (struct guardian_data *)aCalloc(1, sizeof(struct guardian_data));
- md->guardian_data->number = guardian;
- md->guardian_data->guild_id = gc->guild_id;
- md->guardian_data->castle = gc;
- if (has_index) {
- // permanent guardian
- gc->guardian[guardian].id = md->bl.id;
- } else {
- // temporary guardian
- int i;
- ARR_FIND(0, gc->temp_guardians_max, i, gc->temp_guardians[i] == 0);
- if (i == gc->temp_guardians_max) {
- ++(gc->temp_guardians_max);
- RECREATE(gc->temp_guardians, int, gc->temp_guardians_max);
- }
- gc->temp_guardians[i] = md->bl.id;
- }
- if (g) {
- md->guardian_data->emblem_id = g->emblem_id;
- memcpy(md->guardian_data->guild_name, g->name, NAME_LENGTH);
- md->guardian_data->guardup_lv = guild_checkskill(g,GD_GUARDUP);
- } else if (md->guardian_data->guild_id)
- add_timer(gettick()+5000,mob_spawn_guardian_sub,md->bl.id,md->guardian_data->guild_id);
- mob_spawn(md);
-
- return md->bl.id;
+ struct mob_data *md=NULL;
+ struct spawn_data data;
+ struct guild *g=NULL;
+ struct guild_castle *gc;
+ int m;
+ memset(&data, 0, sizeof(struct spawn_data));
+ data.num = 1;
+
+ m=map_mapname2mapid(mapname);
+
+ if(m<0)
+ {
+ ShowWarning("mob_spawn_guardian: Map [%s] not found.\n", mapname);
+ return 0;
+ }
+ data.m = m;
+ data.num = 1;
+ if(class_<=0) {
+ class_ = mob_get_random_id(-class_-1, 1, 99);
+ if (!class_) return 0;
+ }
+
+ data.class_ = class_;
+
+ if( !has_index )
+ {
+ guardian = -1;
+ }
+ else if( guardian < 0 || guardian >= MAX_GUARDIANS )
+ {
+ ShowError("mob_spawn_guardian: Invalid guardian index %d for guardian %d (castle map %s)\n", guardian, class_, map[m].name);
+ return 0;
+ }
+
+ if((x<=0 || y<=0) && !map_search_freecell(NULL, m, &x, &y, -1,-1, 1))
+ {
+ ShowWarning("mob_spawn_guardian: Couldn't locate a spawn cell for guardian class %d (index %d) at castle map %s\n",class_, guardian, map[m].name);
+ return 0;
+ }
+ data.x = x;
+ data.y = y;
+ safestrncpy(data.name, mobname, sizeof(data.name));
+ safestrncpy(data.eventname, event, sizeof(data.eventname));
+ if (!mob_parse_dataset(&data))
+ return 0;
+
+ gc=guild_mapname2gc(map[m].name);
+ if (gc == NULL)
+ {
+ ShowError("mob_spawn_guardian: No castle set at map %s\n", map[m].name);
+ return 0;
+ }
+ if (!gc->guild_id)
+ ShowWarning("mob_spawn_guardian: Spawning guardian %d on a castle with no guild (castle map %s)\n", class_, map[m].name);
+ else
+ g = guild_search(gc->guild_id);
+
+ if( has_index && gc->guardian[guardian].id )
+ { //Check if guardian already exists, refuse to spawn if so.
+ struct mob_data *md2 = (TBL_MOB*)map_id2bl(gc->guardian[guardian].id);
+ if (md2 && md2->bl.type == BL_MOB &&
+ md2->guardian_data && md2->guardian_data->number == guardian)
+ {
+ ShowError("mob_spawn_guardian: Attempted to spawn guardian in position %d which already has a guardian (castle map %s)\n", guardian, map[m].name);
+ return 0;
+ }
+ }
+
+ md = mob_spawn_dataset(&data);
+ md->guardian_data = (struct guardian_data*)aCalloc(1, sizeof(struct guardian_data));
+ md->guardian_data->number = guardian;
+ md->guardian_data->guild_id = gc->guild_id;
+ md->guardian_data->castle = gc;
+ if( has_index )
+ {// permanent guardian
+ gc->guardian[guardian].id = md->bl.id;
+ }
+ else
+ {// temporary guardian
+ int i;
+ ARR_FIND(0, gc->temp_guardians_max, i, gc->temp_guardians[i] == 0);
+ if( i == gc->temp_guardians_max )
+ {
+ ++(gc->temp_guardians_max);
+ RECREATE(gc->temp_guardians, int, gc->temp_guardians_max);
+ }
+ gc->temp_guardians[i] = md->bl.id;
+ }
+ if (g)
+ {
+ md->guardian_data->emblem_id = g->emblem_id;
+ memcpy (md->guardian_data->guild_name, g->name, NAME_LENGTH);
+ md->guardian_data->guardup_lv = guild_checkskill(g,GD_GUARDUP);
+ } else if (md->guardian_data->guild_id)
+ add_timer(gettick()+5000,mob_spawn_guardian_sub,md->bl.id,md->guardian_data->guild_id);
+ mob_spawn(md);
+
+ return md->bl.id;
}
/*==========================================
* Summoning BattleGround [Zephyrus]
*------------------------------------------*/
-int mob_spawn_bg(const char *mapname, short x, short y, const char *mobname, int class_, const char *event, unsigned int bg_id)
+int mob_spawn_bg(const char* mapname, short x, short y, const char* mobname, int class_, const char* event, unsigned int bg_id)
{
- struct mob_data *md = NULL;
- struct spawn_data data;
- int m;
-
- if ((m = map_mapname2mapid(mapname)) < 0) {
- ShowWarning("mob_spawn_bg: Map [%s] not found.\n", mapname);
- return 0;
- }
-
- memset(&data, 0, sizeof(struct spawn_data));
- data.m = m;
- data.num = 1;
- if (class_ <= 0) {
- class_ = mob_get_random_id(-class_-1,1,99);
- if (!class_) return 0;
- }
-
- data.class_ = class_;
- if ((x <= 0 || y <= 0) && !map_search_freecell(NULL, m, &x, &y, -1,-1, 1)) {
- ShowWarning("mob_spawn_bg: Couldn't locate a spawn cell for guardian class %d (bg_id %d) at map %s\n",class_, bg_id, map[m].name);
- return 0;
- }
-
- data.x = x;
- data.y = y;
- safestrncpy(data.name, mobname, sizeof(data.name));
- safestrncpy(data.eventname, event, sizeof(data.eventname));
- if (!mob_parse_dataset(&data))
- return 0;
-
- md = mob_spawn_dataset(&data);
- mob_spawn(md);
- md->bg_id = bg_id; // BG Team ID
-
- return md->bl.id;
+ struct mob_data *md = NULL;
+ struct spawn_data data;
+ int m;
+
+ if( (m = map_mapname2mapid(mapname)) < 0 )
+ {
+ ShowWarning("mob_spawn_bg: Map [%s] not found.\n", mapname);
+ return 0;
+ }
+
+ memset(&data, 0, sizeof(struct spawn_data));
+ data.m = m;
+ data.num = 1;
+ if( class_ <= 0 )
+ {
+ class_ = mob_get_random_id(-class_-1,1,99);
+ if( !class_ ) return 0;
+ }
+
+ data.class_ = class_;
+ if( (x <= 0 || y <= 0) && !map_search_freecell(NULL, m, &x, &y, -1,-1, 1) )
+ {
+ ShowWarning("mob_spawn_bg: Couldn't locate a spawn cell for guardian class %d (bg_id %d) at map %s\n",class_, bg_id, map[m].name);
+ return 0;
+ }
+
+ data.x = x;
+ data.y = y;
+ safestrncpy(data.name, mobname, sizeof(data.name));
+ safestrncpy(data.eventname, event, sizeof(data.eventname));
+ if( !mob_parse_dataset(&data) )
+ return 0;
+
+ md = mob_spawn_dataset(&data);
+ mob_spawn(md);
+ md->bg_id = bg_id; // BG Team ID
+
+ return md->bl.id;
}
/*==========================================
@@ -754,21 +774,21 @@ int mob_spawn_bg(const char *mapname, short x, short y, const char *mobname, int
*------------------------------------------*/
int mob_can_reach(struct mob_data *md,struct block_list *bl,int range, int state)
{
- int easy = 0;
-
- nullpo_ret(md);
- nullpo_ret(bl);
- switch (state) {
- case MSS_RUSH:
- case MSS_FOLLOW:
- easy = 0; //(battle_config.mob_ai&0x1?0:1);
- break;
- case MSS_LOOT:
- default:
- easy = 1;
- break;
- }
- return unit_can_reach_bl(&md->bl, bl, range, easy, NULL, NULL);
+ int easy = 0;
+
+ nullpo_ret(md);
+ nullpo_ret(bl);
+ switch (state) {
+ case MSS_RUSH:
+ case MSS_FOLLOW:
+ easy = 0; //(battle_config.mob_ai&0x1?0:1);
+ break;
+ case MSS_LOOT:
+ default:
+ easy = 1;
+ break;
+ }
+ return unit_can_reach_bl(&md->bl, bl, range, easy, NULL, NULL);
}
/*==========================================
@@ -776,28 +796,29 @@ int mob_can_reach(struct mob_data *md,struct block_list *bl,int range, int state
*------------------------------------------*/
int mob_linksearch(struct block_list *bl,va_list ap)
{
- struct mob_data *md;
- int class_;
- struct block_list *target;
- unsigned int tick;
-
- nullpo_ret(bl);
- md=(struct mob_data *)bl;
- class_ = va_arg(ap, int);
- target = va_arg(ap, struct block_list *);
- tick=va_arg(ap, unsigned int);
-
- if (md->class_ == class_ && DIFF_TICK(md->last_linktime, tick) < MIN_MOBLINKTIME
- && !md->target_id) {
- md->last_linktime = tick;
- if (mob_can_reach(md,target,md->db->range2, MSS_FOLLOW)) { // Reachability judging
- md->target_id = target->id;
- md->min_chase=md->db->range3;
- return 1;
- }
- }
-
- return 0;
+ struct mob_data *md;
+ int class_;
+ struct block_list *target;
+ unsigned int tick;
+
+ nullpo_ret(bl);
+ md=(struct mob_data *)bl;
+ class_ = va_arg(ap, int);
+ target = va_arg(ap, struct block_list *);
+ tick=va_arg(ap, unsigned int);
+
+ if (md->class_ == class_ && DIFF_TICK(md->last_linktime, tick) < MIN_MOBLINKTIME
+ && !md->target_id)
+ {
+ md->last_linktime = tick;
+ if( mob_can_reach(md,target,md->db->range2, MSS_FOLLOW) ){ // Reachability judging
+ md->target_id = target->id;
+ md->min_chase=md->db->range3;
+ return 1;
+ }
+ }
+
+ return 0;
}
/*==========================================
@@ -805,18 +826,20 @@ int mob_linksearch(struct block_list *bl,va_list ap)
*------------------------------------------*/
int mob_delayspawn(int tid, unsigned int tick, int id, intptr_t data)
{
- struct block_list *bl = map_id2bl(id);
- struct mob_data *md = BL_CAST(BL_MOB, bl);
-
- if (md) {
- if (md->spawn_timer != tid) {
- ShowError("mob_delayspawn: Timer mismatch: %d != %d\n", tid, md->spawn_timer);
- return 0;
- }
- md->spawn_timer = INVALID_TIMER;
- mob_spawn(md);
- }
- return 0;
+ struct block_list* bl = map_id2bl(id);
+ struct mob_data* md = BL_CAST(BL_MOB, bl);
+
+ if( md )
+ {
+ if( md->spawn_timer != tid )
+ {
+ ShowError("mob_delayspawn: Timer mismatch: %d != %d\n", tid, md->spawn_timer);
+ return 0;
+ }
+ md->spawn_timer = INVALID_TIMER;
+ mob_spawn(md);
+ }
+ return 0;
}
/*==========================================
@@ -824,44 +847,43 @@ int mob_delayspawn(int tid, unsigned int tick, int id, intptr_t data)
*------------------------------------------*/
int mob_setdelayspawn(struct mob_data *md)
{
- unsigned int spawntime, mode;
- struct mob_db *db;
-
- if (!md->spawn) //Doesn't has respawn data!
- return unit_free(&md->bl,CLR_DEAD);
-
- spawntime = md->spawn->delay1; //Base respawn time
- if (md->spawn->delay2) //random variance
- spawntime+= rnd()%md->spawn->delay2;
-
- //Apply the spawn delay fix [Skotlex]
- db = mob_db(md->spawn->class_);
- mode = db->status.mode;
- if (mode & MD_BOSS) { //Bosses
- if (battle_config.boss_spawn_delay != 100) {
- // Divide by 100 first to prevent overflows
- //(precision loss is minimal as duration is in ms already)
- spawntime = spawntime/100*battle_config.boss_spawn_delay;
- }
- } else if (mode&MD_PLANT) { //Plants
- if (battle_config.plant_spawn_delay != 100) {
- spawntime = spawntime/100*battle_config.plant_spawn_delay;
- }
- } else if (battle_config.mob_spawn_delay != 100) { //Normal mobs
- spawntime = spawntime/100*battle_config.mob_spawn_delay;
- }
-
- if (spawntime < 500) //Min respawn time (is it needed?)
- spawntime = 500;
-
- if (md->spawn_timer != INVALID_TIMER)
- delete_timer(md->spawn_timer, mob_delayspawn);
- md->spawn_timer = add_timer(gettick()+spawntime, mob_delayspawn, md->bl.id, 0);
- return 0;
+ unsigned int spawntime, mode;
+ struct mob_db *db;
+
+ if (!md->spawn) //Doesn't has respawn data!
+ return unit_free(&md->bl,CLR_DEAD);
+
+ spawntime = md->spawn->delay1; //Base respawn time
+ if (md->spawn->delay2) //random variance
+ spawntime+= rnd()%md->spawn->delay2;
+
+ //Apply the spawn delay fix [Skotlex]
+ db = mob_db(md->spawn->class_);
+ mode = db->status.mode;
+ if (mode & MD_BOSS) { //Bosses
+ if (battle_config.boss_spawn_delay != 100) {
+ // Divide by 100 first to prevent overflows
+ //(precision loss is minimal as duration is in ms already)
+ spawntime = spawntime/100*battle_config.boss_spawn_delay;
+ }
+ } else if (mode&MD_PLANT) { //Plants
+ if (battle_config.plant_spawn_delay != 100) {
+ spawntime = spawntime/100*battle_config.plant_spawn_delay;
+ }
+ } else if (battle_config.mob_spawn_delay != 100) { //Normal mobs
+ spawntime = spawntime/100*battle_config.mob_spawn_delay;
+ }
+
+ if (spawntime < 500) //Min respawn time (is it needed?)
+ spawntime = 500;
+
+ if( md->spawn_timer != INVALID_TIMER )
+ delete_timer(md->spawn_timer, mob_delayspawn);
+ md->spawn_timer = add_timer(gettick()+spawntime, mob_delayspawn, md->bl.id, 0);
+ return 0;
}
-int mob_count_sub(struct block_list *bl, va_list ap)
-{
+int mob_count_sub(struct block_list *bl, va_list ap) {
int mobid[10], i;
ARR_FIND(0, 10, i, (mobid[i] = va_arg(ap, int)) == 0); //fetch till 0
if (mobid[0]) { //if there one let's check it otherwise go backward
@@ -875,123 +897,128 @@ int mob_count_sub(struct block_list *bl, va_list ap)
/*==========================================
* Mob spawning. Initialization is also variously here.
*------------------------------------------*/
-int mob_spawn(struct mob_data *md)
+int mob_spawn (struct mob_data *md)
{
- int i=0;
- unsigned int tick = gettick();
- int c =0;
-
- md->last_thinktime = tick;
- if (md->bl.prev != NULL)
- unit_remove_map(&md->bl,CLR_RESPAWN);
- else if (md->spawn && md->class_ != md->spawn->class_) {
- md->class_ = md->spawn->class_;
- status_set_viewdata(&md->bl, md->class_);
- md->db = mob_db(md->class_);
- memcpy(md->name,md->spawn->name,NAME_LENGTH);
- }
-
- if (md->spawn) { //Respawn data
- md->bl.m = md->spawn->m;
- md->bl.x = md->spawn->x;
- md->bl.y = md->spawn->y;
-
- if ((md->bl.x == 0 && md->bl.y == 0) || md->spawn->xs || md->spawn->ys) {
- //Monster can be spawned on an area.
- if (!map_search_freecell(&md->bl, -1, &md->bl.x, &md->bl.y, md->spawn->xs, md->spawn->ys, battle_config.no_spawn_on_player?4:0)) {
- // retry again later
- if (md->spawn_timer != INVALID_TIMER)
- delete_timer(md->spawn_timer, mob_delayspawn);
- md->spawn_timer = add_timer(tick+5000,mob_delayspawn,md->bl.id,0);
- return 1;
- }
- } else if (battle_config.no_spawn_on_player > 99 && map_foreachinrange(mob_count_sub, &md->bl, AREA_SIZE, BL_PC)) {
- // retry again later (players on sight)
- if (md->spawn_timer != INVALID_TIMER)
- delete_timer(md->spawn_timer, mob_delayspawn);
- md->spawn_timer = add_timer(tick+5000,mob_delayspawn,md->bl.id,0);
- return 1;
- }
- }
-
- memset(&md->state, 0, sizeof(md->state));
- status_calc_mob(md, 1);
- md->attacked_id = 0;
- md->target_id = 0;
- md->move_fail_count = 0;
- md->ud.state.attack_continue = 0;
- md->ud.target_to = 0;
- if (md->spawn_timer != INVALID_TIMER) {
- delete_timer(md->spawn_timer, mob_delayspawn);
- md->spawn_timer = INVALID_TIMER;
- }
-
- // md->master_id = 0;
- md->master_dist = 0;
-
- md->state.aggressive = md->status.mode&MD_ANGRY?1:0;
- md->state.skillstate = MSS_IDLE;
- md->next_walktime = tick+rnd()%5000+1000;
- md->last_linktime = tick;
- md->dmgtick = tick - 5000;
- md->last_pcneartime = 0;
-
- for (i = 0, c = tick-MOB_MAX_DELAY; i < MAX_MOBSKILL; i++)
- md->skilldelay[i] = c;
-
- memset(md->dmglog, 0, sizeof(md->dmglog));
- md->tdmg = 0;
-
- if (md->lootitem)
- memset(md->lootitem, 0, sizeof(*md->lootitem));
-
- md->lootitem_count = 0;
-
- if (md->db->option)
- // Added for carts, falcons and pecos for cloned monsters. [Valaris]
- md->sc.option = md->db->option;
-
- // MvP tomb [GreenBox]
- if (md->tomb_nid)
- mvptomb_destroy(md);
-
- map_addblock(&md->bl);
- if (map[md->bl.m].users)
- clif_spawn(&md->bl);
- skill_unit_move(&md->bl,tick,1);
- mobskill_use(md, tick, MSC_SPAWN);
- return 0;
+ int i=0;
+ unsigned int tick = gettick();
+ int c =0;
+
+ md->last_thinktime = tick;
+ if (md->bl.prev != NULL)
+ unit_remove_map(&md->bl,CLR_RESPAWN);
+ else
+ if (md->spawn && md->class_ != md->spawn->class_)
+ {
+ md->class_ = md->spawn->class_;
+ status_set_viewdata(&md->bl, md->class_);
+ md->db = mob_db(md->class_);
+ memcpy(md->name,md->spawn->name,NAME_LENGTH);
+ }
+
+ if (md->spawn) { //Respawn data
+ md->bl.m = md->spawn->m;
+ md->bl.x = md->spawn->x;
+ md->bl.y = md->spawn->y;
+
+ if( (md->bl.x == 0 && md->bl.y == 0) || md->spawn->xs || md->spawn->ys )
+ { //Monster can be spawned on an area.
+ if( !map_search_freecell(&md->bl, -1, &md->bl.x, &md->bl.y, md->spawn->xs, md->spawn->ys, battle_config.no_spawn_on_player?4:0) )
+ { // retry again later
+ if( md->spawn_timer != INVALID_TIMER )
+ delete_timer(md->spawn_timer, mob_delayspawn);
+ md->spawn_timer = add_timer(tick+5000,mob_delayspawn,md->bl.id,0);
+ return 1;
+ }
+ }
+ else if( battle_config.no_spawn_on_player > 99 && map_foreachinrange(mob_count_sub, &md->bl, AREA_SIZE, BL_PC) )
+ { // retry again later (players on sight)
+ if( md->spawn_timer != INVALID_TIMER )
+ delete_timer(md->spawn_timer, mob_delayspawn);
+ md->spawn_timer = add_timer(tick+5000,mob_delayspawn,md->bl.id,0);
+ return 1;
+ }
+ }
+
+ memset(&md->state, 0, sizeof(md->state));
+ status_calc_mob(md, 1);
+ md->attacked_id = 0;
+ md->target_id = 0;
+ md->move_fail_count = 0;
+ md->ud.state.attack_continue = 0;
+ md->ud.target_to = 0;
+ if( md->spawn_timer != INVALID_TIMER )
+ {
+ delete_timer(md->spawn_timer, mob_delayspawn);
+ md->spawn_timer = INVALID_TIMER;
+ }
+
+// md->master_id = 0;
+ md->master_dist = 0;
+
+ md->state.aggressive = md->status.mode&MD_ANGRY?1:0;
+ md->state.skillstate = MSS_IDLE;
+ md->next_walktime = tick+rnd()%5000+1000;
+ md->last_linktime = tick;
+ md->dmgtick = tick - 5000;
+ md->last_pcneartime = 0;
+
+ for (i = 0, c = tick-MOB_MAX_DELAY; i < MAX_MOBSKILL; i++)
+ md->skilldelay[i] = c;
+
+ memset(md->dmglog, 0, sizeof(md->dmglog));
+ md->tdmg = 0;
+
+ if (md->lootitem)
+ memset(md->lootitem, 0, sizeof(*md->lootitem));
+
+ md->lootitem_count = 0;
+
+ if(md->db->option)
+ // Added for carts, falcons and pecos for cloned monsters. [Valaris]
+ md->sc.option = md->db->option;
+
+ // MvP tomb [GreenBox]
+ if ( md->tomb_nid )
+ mvptomb_destroy(md);
+
+ map_addblock(&md->bl);
+ if( map[md->bl.m].users )
+ clif_spawn(&md->bl);
+ skill_unit_move(&md->bl,tick,1);
+ mobskill_use(md, tick, MSC_SPAWN);
+ return 0;
}
/*==========================================
* Determines if the mob can change target. [Skotlex]
*------------------------------------------*/
-static int mob_can_changetarget(struct mob_data *md, struct block_list *target, int mode)
+static int mob_can_changetarget(struct mob_data* md, struct block_list* target, int mode)
{
- // if the monster was provoked ignore the above rule [celest]
- if (md->state.provoke_flag) {
- if (md->state.provoke_flag == target->id)
- return 1;
- else if (!(battle_config.mob_ai&0x4))
- return 0;
- }
-
- switch (md->state.skillstate) {
- case MSS_BERSERK:
- if (!(mode&MD_CHANGETARGET_MELEE))
- return 0;
- return (battle_config.mob_ai&0x4 || check_distance_bl(&md->bl, target, 3));
- case MSS_RUSH:
- return (mode&MD_CHANGETARGET_CHASE);
- case MSS_FOLLOW:
- case MSS_ANGRY:
- case MSS_IDLE:
- case MSS_WALK:
- case MSS_LOOT:
- return 1;
- default:
- return 0;
- }
+ // if the monster was provoked ignore the above rule [celest]
+ if(md->state.provoke_flag)
+ {
+ if (md->state.provoke_flag == target->id)
+ return 1;
+ else if (!(battle_config.mob_ai&0x4))
+ return 0;
+ }
+
+ switch (md->state.skillstate) {
+ case MSS_BERSERK:
+ if (!(mode&MD_CHANGETARGET_MELEE))
+ return 0;
+ return (battle_config.mob_ai&0x4 || check_distance_bl(&md->bl, target, 3));
+ case MSS_RUSH:
+ return (mode&MD_CHANGETARGET_CHASE);
+ case MSS_FOLLOW:
+ case MSS_ANGRY:
+ case MSS_IDLE:
+ case MSS_WALK:
+ case MSS_LOOT:
+ return 1;
+ default:
+ return 0;
+ }
}
/*==========================================
@@ -999,23 +1026,23 @@ static int mob_can_changetarget(struct mob_data *md, struct block_list *target,
*------------------------------------------*/
int mob_target(struct mob_data *md,struct block_list *bl,int dist)
{
- nullpo_ret(md);
- nullpo_ret(bl);
-
- // Nothing will be carried out if there is no mind of changing TAGE by TAGE ending.
- if (md->target_id && !mob_can_changetarget(md, bl, status_get_mode(&md->bl)))
- return 0;
-
- if (!status_check_skilluse(&md->bl, bl, 0, 0))
- return 0;
-
- md->target_id = bl->id; // Since there was no disturbance, it locks on to target.
- if (md->state.provoke_flag && bl->id != md->state.provoke_flag)
- md->state.provoke_flag = 0;
- md->min_chase=dist+md->db->range3;
- if (md->min_chase>MAX_MINCHASE)
- md->min_chase=MAX_MINCHASE;
- return 0;
+ nullpo_ret(md);
+ nullpo_ret(bl);
+
+ // Nothing will be carried out if there is no mind of changing TAGE by TAGE ending.
+ if(md->target_id && !mob_can_changetarget(md, bl, status_get_mode(&md->bl)))
+ return 0;
+
+ if(!status_check_skilluse(&md->bl, bl, 0, 0))
+ return 0;
+
+ md->target_id = bl->id; // Since there was no disturbance, it locks on to target.
+ if (md->state.provoke_flag && bl->id != md->state.provoke_flag)
+ md->state.provoke_flag = 0;
+ md->min_chase=dist+md->db->range3;
+ if(md->min_chase>MAX_MINCHASE)
+ md->min_chase=MAX_MINCHASE;
+ return 0;
}
/*==========================================
@@ -1023,60 +1050,61 @@ int mob_target(struct mob_data *md,struct block_list *bl,int dist)
*------------------------------------------*/
static int mob_ai_sub_hard_activesearch(struct block_list *bl,va_list ap)
{
- struct mob_data *md;
- struct block_list **target;
- int mode;
- int dist;
-
- nullpo_ret(bl);
- md=va_arg(ap,struct mob_data *);
- target= va_arg(ap,struct block_list **);
- mode= va_arg(ap,int);
-
- //If can't seek yet, not an enemy, or you can't attack it, skip.
- if ((*target) == bl || !status_check_skilluse(&md->bl, bl, 0, 0))
- return 0;
-
- if ((mode&MD_TARGETWEAK) && status_get_lv(bl) >= md->level-5)
- return 0;
-
- if (battle_check_target(&md->bl,bl,BCT_ENEMY)<=0)
- return 0;
-
- switch (bl->type) {
- case BL_PC:
- if (((TBL_PC *)bl)->state.gangsterparadise &&
- !(status_get_mode(&md->bl)&MD_BOSS))
- return 0; //Gangster paradise protection.
- default:
- if (battle_config.hom_setting&0x4 &&
- (*target) && (*target)->type == BL_HOM && bl->type != BL_HOM)
- return 0; //For some reason Homun targets are never overriden.
-
- dist = distance_bl(&md->bl, bl);
- if (
- ((*target) == NULL || !check_distance_bl(&md->bl, *target, dist)) &&
- battle_check_range(&md->bl,bl,md->db->range2)
- ) { //Pick closest target?
-
- if (map[bl->m].icewall_num &&
- !path_search_long(NULL,bl->m,md->bl.x,md->bl.y,bl->x,bl->y,CELL_CHKICEWALL)) {
-
- if (!check_distance_bl(&md->bl, bl, status_get_range(&md->bl)))
- return 0;
-
- }
-
- (*target) = bl;
- md->target_id=bl->id;
- md->min_chase= dist + md->db->range3;
- if (md->min_chase>MAX_MINCHASE)
- md->min_chase=MAX_MINCHASE;
- return 1;
- }
- break;
- }
- return 0;
+ struct mob_data *md;
+ struct block_list **target;
+ int mode;
+ int dist;
+
+ nullpo_ret(bl);
+ md=va_arg(ap,struct mob_data *);
+ target= va_arg(ap,struct block_list**);
+ mode= va_arg(ap,int);
+
+ //If can't seek yet, not an enemy, or you can't attack it, skip.
+ if ((*target) == bl || !status_check_skilluse(&md->bl, bl, 0, 0))
+ return 0;
+
+ if ((mode&MD_TARGETWEAK) && status_get_lv(bl) >= md->level-5)
+ return 0;
+
+ if(battle_check_target(&md->bl,bl,BCT_ENEMY)<=0)
+ return 0;
+
+ switch (bl->type)
+ {
+ case BL_PC:
+ if (((TBL_PC*)bl)->state.gangsterparadise &&
+ !(status_get_mode(&md->bl)&MD_BOSS))
+ return 0; //Gangster paradise protection.
+ default:
+ if (battle_config.hom_setting&0x4 &&
+ (*target) && (*target)->type == BL_HOM && bl->type != BL_HOM)
+ return 0; //For some reason Homun targets are never overriden.
+
+ dist = distance_bl(&md->bl, bl);
+ if(
+ ((*target) == NULL || !check_distance_bl(&md->bl, *target, dist)) &&
+ battle_check_range(&md->bl,bl,md->db->range2)
+ ) { //Pick closest target?
+
+ if( map[bl->m].icewall_num &&
+ !path_search_long(NULL,bl->m,md->bl.x,md->bl.y,bl->x,bl->y,CELL_CHKICEWALL) ) {
+
+ if( !check_distance_bl(&md->bl, bl, status_get_range(&md->bl) ) )
+ return 0;
+
+ }
+
+ (*target) = bl;
+ md->target_id=bl->id;
+ md->min_chase= dist + md->db->range3;
+ if(md->min_chase>MAX_MINCHASE)
+ md->min_chase=MAX_MINCHASE;
+ return 1;
+ }
+ break;
+ }
+ return 0;
}
/*==========================================
@@ -1084,43 +1112,43 @@ static int mob_ai_sub_hard_activesearch(struct block_list *bl,va_list ap)
*------------------------------------------*/
static int mob_ai_sub_hard_changechase(struct block_list *bl,va_list ap)
{
- struct mob_data *md;
- struct block_list **target;
-
- nullpo_ret(bl);
- md=va_arg(ap,struct mob_data *);
- target= va_arg(ap,struct block_list **);
-
- //If can't seek yet, not an enemy, or you can't attack it, skip.
- if ((*target) == bl ||
- battle_check_target(&md->bl,bl,BCT_ENEMY)<=0 ||
- !status_check_skilluse(&md->bl, bl, 0, 0))
- return 0;
-
- if (battle_check_range(&md->bl, bl, md->status.rhw.range)) {
- (*target) = bl;
- md->target_id=bl->id;
- md->min_chase= md->db->range3;
- }
- return 1;
+ struct mob_data *md;
+ struct block_list **target;
+
+ nullpo_ret(bl);
+ md=va_arg(ap,struct mob_data *);
+ target= va_arg(ap,struct block_list**);
+
+ //If can't seek yet, not an enemy, or you can't attack it, skip.
+ if ((*target) == bl ||
+ battle_check_target(&md->bl,bl,BCT_ENEMY)<=0 ||
+ !status_check_skilluse(&md->bl, bl, 0, 0))
+ return 0;
+
+ if(battle_check_range (&md->bl, bl, md->status.rhw.range))
+ {
+ (*target) = bl;
+ md->target_id=bl->id;
+ md->min_chase= md->db->range3;
+ }
+ return 1;
}
/*==========================================
* finds nearby bg ally for guardians looking for users to follow.
*------------------------------------------*/
-static int mob_ai_sub_hard_bg_ally(struct block_list *bl,va_list ap)
-{
- struct mob_data *md;
- struct block_list **target;
-
- nullpo_ret(bl);
- md=va_arg(ap,struct mob_data *);
- target= va_arg(ap,struct block_list **);
-
- if (status_check_skilluse(&md->bl, bl, 0, 0) && battle_check_target(&md->bl,bl,BCT_ENEMY)<=0) {
- (*target) = bl;
- }
- return 1;
+static int mob_ai_sub_hard_bg_ally(struct block_list *bl,va_list ap) {
+ struct mob_data *md;
+ struct block_list **target;
+
+ nullpo_ret(bl);
+ md=va_arg(ap,struct mob_data *);
+ target= va_arg(ap,struct block_list**);
+
+ if( status_check_skilluse(&md->bl, bl, 0, 0) && battle_check_target(&md->bl,bl,BCT_ENEMY)<=0 ) {
+ (*target) = bl;
+ }
+ return 1;
}
/*==========================================
@@ -1128,130 +1156,131 @@ static int mob_ai_sub_hard_bg_ally(struct block_list *bl,va_list ap)
*------------------------------------------*/
static int mob_ai_sub_hard_lootsearch(struct block_list *bl,va_list ap)
{
- struct mob_data *md;
- struct block_list **target;
- int dist;
-
- md=va_arg(ap,struct mob_data *);
- target= va_arg(ap,struct block_list **);
-
- dist=distance_bl(&md->bl, bl);
- if (mob_can_reach(md,bl,dist+1, MSS_LOOT) &&
- ((*target) == NULL || !check_distance_bl(&md->bl, *target, dist)) //New target closer than previous one.
- ) {
- (*target) = bl;
- md->target_id=bl->id;
- md->min_chase=md->db->range3;
- }
- return 0;
+ struct mob_data* md;
+ struct block_list **target;
+ int dist;
+
+ md=va_arg(ap,struct mob_data *);
+ target= va_arg(ap,struct block_list**);
+
+ dist=distance_bl(&md->bl, bl);
+ if(mob_can_reach(md,bl,dist+1, MSS_LOOT) &&
+ ((*target) == NULL || !check_distance_bl(&md->bl, *target, dist)) //New target closer than previous one.
+ ) {
+ (*target) = bl;
+ md->target_id=bl->id;
+ md->min_chase=md->db->range3;
+ }
+ return 0;
}
-static int mob_warpchase_sub(struct block_list *bl,va_list ap)
-{
- struct block_list *target;
- struct npc_data **target_nd;
- struct npc_data *nd;
- int *min_distance;
- int cur_distance;
-
- target= va_arg(ap, struct block_list *);
- target_nd= va_arg(ap, struct npc_data **);
- min_distance= va_arg(ap, int *);
-
- nd = (TBL_NPC *) bl;
-
- if (nd->subtype != WARP)
- return 0; //Not a warp
-
- if (nd->u.warp.mapindex != map[target->m].index)
- return 0; //Does not lead to the same map.
-
- cur_distance = distance_blxy(target, nd->u.warp.x, nd->u.warp.y);
- if (cur_distance < *min_distance) {
- //Pick warp that leads closest to target.
- *target_nd = nd;
- *min_distance = cur_distance;
- return 1;
- }
- return 0;
+static int mob_warpchase_sub(struct block_list *bl,va_list ap) {
+ struct block_list *target;
+ struct npc_data **target_nd;
+ struct npc_data *nd;
+ int *min_distance;
+ int cur_distance;
+
+ target= va_arg(ap, struct block_list*);
+ target_nd= va_arg(ap, struct npc_data**);
+ min_distance= va_arg(ap, int*);
+
+ nd = (TBL_NPC*) bl;
+
+ if(nd->subtype != WARP)
+ return 0; //Not a warp
+
+ if(nd->u.warp.mapindex != map[target->m].index)
+ return 0; //Does not lead to the same map.
+
+ cur_distance = distance_blxy(target, nd->u.warp.x, nd->u.warp.y);
+ if (cur_distance < *min_distance)
+ { //Pick warp that leads closest to target.
+ *target_nd = nd;
+ *min_distance = cur_distance;
+ return 1;
+ }
+ return 0;
}
/*==========================================
* Processing of slave monsters
*------------------------------------------*/
static int mob_ai_sub_hard_slavemob(struct mob_data *md,unsigned int tick)
{
- struct block_list *bl;
-
- bl=map_id2bl(md->master_id);
-
- if (!bl || status_isdead(bl)) {
- status_kill(&md->bl);
- return 1;
- }
- if (bl->prev == NULL)
- return 0; //Master not on a map? Could be warping, do not process.
-
- if (status_get_mode(&md->bl)&MD_CANMOVE) {
- //If the mob can move, follow around. [Check by Skotlex]
- int old_dist;
-
- // Distance with between slave and master is measured.
- old_dist=md->master_dist;
- md->master_dist=distance_bl(&md->bl, bl);
-
- // Since the master was in near immediately before, teleport is carried out and it pursues.
- if (bl->m != md->bl.m ||
- (old_dist<10 && md->master_dist>18) ||
- md->master_dist > MAX_MINCHASE
- ) {
- md->master_dist = 0;
- unit_warp(&md->bl,bl->m,bl->x,bl->y,CLR_TELEPORT);
- return 1;
- }
-
- if (md->target_id) //Slave is busy with a target.
- return 0;
-
- // Approach master if within view range, chase back to Master's area also if standing on top of the master.
- if ((md->master_dist>MOB_SLAVEDISTANCE || md->master_dist == 0) &&
- unit_can_move(&md->bl)) {
- short x = bl->x, y = bl->y;
- mob_stop_attack(md);
- if (map_search_freecell(&md->bl, bl->m, &x, &y, MOB_SLAVEDISTANCE, MOB_SLAVEDISTANCE, 1)
- && unit_walktoxy(&md->bl, x, y, 0))
- return 1;
- }
- } else if (bl->m != md->bl.m && map_flag_gvg(md->bl.m)) {
- //Delete the summoned mob if it's in a gvg ground and the master is elsewhere. [Skotlex]
- status_kill(&md->bl);
- return 1;
- }
-
- //Avoid attempting to lock the master's target too often to avoid unnecessary overload. [Skotlex]
- if (DIFF_TICK(md->last_linktime, tick) < MIN_MOBLINKTIME && !md->target_id) {
- struct unit_data *ud = unit_bl2ud(bl);
- md->last_linktime = tick;
-
- if (ud) {
- struct block_list *tbl=NULL;
- if (ud->target && ud->state.attack_continue)
- tbl=map_id2bl(ud->target);
- else if (ud->skilltarget) {
- tbl = map_id2bl(ud->skilltarget);
- //Required check as skilltarget is not always an enemy. [Skotlex]
- if (tbl && battle_check_target(&md->bl, tbl, BCT_ENEMY) <= 0)
- tbl = NULL;
- }
- if (tbl && status_check_skilluse(&md->bl, tbl, 0, 0)) {
- md->target_id=tbl->id;
- md->min_chase=md->db->range3+distance_bl(&md->bl, tbl);
- if (md->min_chase>MAX_MINCHASE)
- md->min_chase=MAX_MINCHASE;
- return 1;
- }
- }
- }
- return 0;
+ struct block_list *bl;
+
+ bl=map_id2bl(md->master_id);
+
+ if (!bl || status_isdead(bl)) {
+ status_kill(&md->bl);
+ return 1;
+ }
+ if (bl->prev == NULL)
+ return 0; //Master not on a map? Could be warping, do not process.
+
+ if(status_get_mode(&md->bl)&MD_CANMOVE)
+ { //If the mob can move, follow around. [Check by Skotlex]
+ int old_dist;
+
+ // Distance with between slave and master is measured.
+ old_dist=md->master_dist;
+ md->master_dist=distance_bl(&md->bl, bl);
+
+ // Since the master was in near immediately before, teleport is carried out and it pursues.
+ if(bl->m != md->bl.m ||
+ (old_dist<10 && md->master_dist>18) ||
+ md->master_dist > MAX_MINCHASE
+ ){
+ md->master_dist = 0;
+ unit_warp(&md->bl,bl->m,bl->x,bl->y,CLR_TELEPORT);
+ return 1;
+ }
+
+ if(md->target_id) //Slave is busy with a target.
+ return 0;
+
+ // Approach master if within view range, chase back to Master's area also if standing on top of the master.
+ if((md->master_dist>MOB_SLAVEDISTANCE || md->master_dist == 0) &&
+ unit_can_move(&md->bl))
+ {
+ short x = bl->x, y = bl->y;
+ mob_stop_attack(md);
+ if(map_search_freecell(&md->bl, bl->m, &x, &y, MOB_SLAVEDISTANCE, MOB_SLAVEDISTANCE, 1)
+ && unit_walktoxy(&md->bl, x, y, 0))
+ return 1;
+ }
+ } else if (bl->m != md->bl.m && map_flag_gvg(md->bl.m)) {
+ //Delete the summoned mob if it's in a gvg ground and the master is elsewhere. [Skotlex]
+ status_kill(&md->bl);
+ return 1;
+ }
+
+ //Avoid attempting to lock the master's target too often to avoid unnecessary overload. [Skotlex]
+ if (DIFF_TICK(md->last_linktime, tick) < MIN_MOBLINKTIME && !md->target_id)
+ {
+ struct unit_data *ud = unit_bl2ud(bl);
+ md->last_linktime = tick;
+
+ if (ud) {
+ struct block_list *tbl=NULL;
+ if (ud->target && ud->state.attack_continue)
+ tbl=map_id2bl(ud->target);
+ else if (ud->skilltarget) {
+ tbl = map_id2bl(ud->skilltarget);
+ //Required check as skilltarget is not always an enemy. [Skotlex]
+ if (tbl && battle_check_target(&md->bl, tbl, BCT_ENEMY) <= 0)
+ tbl = NULL;
+ }
+ if (tbl && status_check_skilluse(&md->bl, tbl, 0, 0)) {
+ md->target_id=tbl->id;
+ md->min_chase=md->db->range3+distance_bl(&md->bl, tbl);
+ if(md->min_chase>MAX_MINCHASE)
+ md->min_chase=MAX_MINCHASE;
+ return 1;
+ }
+ }
+ }
+ return 0;
}
/*==========================================
@@ -1262,112 +1291,112 @@ static int mob_ai_sub_hard_slavemob(struct mob_data *md,unsigned int tick)
*------------------------------------------*/
int mob_unlocktarget(struct mob_data *md, unsigned int tick)
{
- nullpo_ret(md);
-
- switch (md->state.skillstate) {
- case MSS_WALK:
- if (md->ud.walktimer != INVALID_TIMER)
- break;
- //Because it is not unset when the mob finishes walking.
- md->state.skillstate = MSS_IDLE;
- case MSS_IDLE:
- // Idle skill.
- if ((md->target_id || !(++md->ud.walk_count%IDLE_SKILL_INTERVAL)) &&
- mobskill_use(md, tick, -1))
- break;
- //Random walk.
- if (!md->master_id &&
- DIFF_TICK(md->next_walktime, tick) <= 0 &&
- !mob_randomwalk(md,tick))
- //Delay next random walk when this one failed.
- md->next_walktime=tick+rnd()%3000;
- break;
- default:
- mob_stop_attack(md);
- if (battle_config.mob_ai&0x8)
- mob_stop_walking(md,1); //Immediately stop chasing.
- md->state.skillstate = MSS_IDLE;
- md->next_walktime=tick+rnd()%3000+3000;
- break;
- }
- if (md->target_id) {
- md->target_id=0;
- unit_set_target(&md->ud, 0);
- }
- return 0;
+ nullpo_ret(md);
+
+ switch (md->state.skillstate) {
+ case MSS_WALK:
+ if (md->ud.walktimer != INVALID_TIMER)
+ break;
+ //Because it is not unset when the mob finishes walking.
+ md->state.skillstate = MSS_IDLE;
+ case MSS_IDLE:
+ // Idle skill.
+ if ((md->target_id || !(++md->ud.walk_count%IDLE_SKILL_INTERVAL)) &&
+ mobskill_use(md, tick, -1))
+ break;
+ //Random walk.
+ if (!md->master_id &&
+ DIFF_TICK(md->next_walktime, tick) <= 0 &&
+ !mob_randomwalk(md,tick))
+ //Delay next random walk when this one failed.
+ md->next_walktime=tick+rnd()%3000;
+ break;
+ default:
+ mob_stop_attack(md);
+ if (battle_config.mob_ai&0x8)
+ mob_stop_walking(md,1); //Immediately stop chasing.
+ md->state.skillstate = MSS_IDLE;
+ md->next_walktime=tick+rnd()%3000+3000;
+ break;
+ }
+ if (md->target_id) {
+ md->target_id=0;
+ unit_set_target(&md->ud, 0);
+ }
+ return 0;
}
/*==========================================
* Random walk
*------------------------------------------*/
int mob_randomwalk(struct mob_data *md,unsigned int tick)
{
- const int retrycount=20;
- int i,x,y,c,d;
- int speed;
-
- nullpo_ret(md);
-
- if (DIFF_TICK(md->next_walktime,tick)>0 ||
- !unit_can_move(&md->bl) ||
- !(status_get_mode(&md->bl)&MD_CANMOVE))
- return 0;
-
- d =12-md->move_fail_count;
- if (d<5) d=5;
- for (i=0; i<retrycount; i++) { // Search of a movable place
- int r=rnd();
- x=r%(d*2+1)-d;
- y=r/(d*2+1)%(d*2+1)-d;
- x+=md->bl.x;
- y+=md->bl.y;
-
- if ((map_getcell(md->bl.m,x,y,CELL_CHKPASS)) && unit_walktoxy(&md->bl,x,y,1)) {
- break;
- }
- }
- if (i==retrycount) {
- md->move_fail_count++;
- if (md->move_fail_count>1000) {
- ShowWarning("MOB can't move. random spawn %d, class = %d, at %s (%d,%d)\n",md->bl.id,md->class_,map[md->bl.m].name, md->bl.x, md->bl.y);
- md->move_fail_count=0;
- mob_spawn(md);
- }
- return 0;
- }
- speed=status_get_speed(&md->bl);
- for (i=c=0; i<md->ud.walkpath.path_len; i++) { // The next walk start time is calculated.
- if (md->ud.walkpath.path[i]&1)
- c+=speed*14/10;
- else
- c+=speed;
- }
- md->state.skillstate=MSS_WALK;
- md->move_fail_count=0;
- md->next_walktime = tick+rnd()%3000+3000+c;
- return 1;
+ const int retrycount=20;
+ int i,x,y,c,d;
+ int speed;
+
+ nullpo_ret(md);
+
+ if(DIFF_TICK(md->next_walktime,tick)>0 ||
+ !unit_can_move(&md->bl) ||
+ !(status_get_mode(&md->bl)&MD_CANMOVE))
+ return 0;
+
+ d =12-md->move_fail_count;
+ if(d<5) d=5;
+ for(i=0;i<retrycount;i++){ // Search of a movable place
+ int r=rnd();
+ x=r%(d*2+1)-d;
+ y=r/(d*2+1)%(d*2+1)-d;
+ x+=md->bl.x;
+ y+=md->bl.y;
+
+ if((map_getcell(md->bl.m,x,y,CELL_CHKPASS)) && unit_walktoxy(&md->bl,x,y,1)){
+ break;
+ }
+ }
+ if(i==retrycount){
+ md->move_fail_count++;
+ if(md->move_fail_count>1000){
+ ShowWarning("MOB can't move. random spawn %d, class = %d, at %s (%d,%d)\n",md->bl.id,md->class_,map[md->bl.m].name, md->bl.x, md->bl.y);
+ md->move_fail_count=0;
+ mob_spawn(md);
+ }
+ return 0;
+ }
+ speed=status_get_speed(&md->bl);
+ for(i=c=0;i<md->ud.walkpath.path_len;i++){ // The next walk start time is calculated.
+ if(md->ud.walkpath.path[i]&1)
+ c+=speed*14/10;
+ else
+ c+=speed;
+ }
+ md->state.skillstate=MSS_WALK;
+ md->move_fail_count=0;
+ md->next_walktime = tick+rnd()%3000+3000+c;
+ return 1;
}
int mob_warpchase(struct mob_data *md, struct block_list *target)
{
- struct npc_data *warp = NULL;
- int distance = AREA_SIZE;
- if (!(target && battle_config.mob_ai&0x40 && battle_config.mob_warp&1))
- return 0; //Can't warp chase.
+ struct npc_data *warp = NULL;
+ int distance = AREA_SIZE;
+ if (!(target && battle_config.mob_ai&0x40 && battle_config.mob_warp&1))
+ return 0; //Can't warp chase.
- if (target->m == md->bl.m && check_distance_bl(&md->bl, target, AREA_SIZE))
- return 0; //No need to do a warp chase.
+ if (target->m == md->bl.m && check_distance_bl(&md->bl, target, AREA_SIZE))
+ return 0; //No need to do a warp chase.
- if (md->ud.walktimer != INVALID_TIMER &&
- map_getcell(md->bl.m,md->ud.to_x,md->ud.to_y,CELL_CHKNPC))
- return 1; //Already walking to a warp.
+ if (md->ud.walktimer != INVALID_TIMER &&
+ map_getcell(md->bl.m,md->ud.to_x,md->ud.to_y,CELL_CHKNPC))
+ return 1; //Already walking to a warp.
- //Search for warps within mob's viewing range.
- map_foreachinrange(mob_warpchase_sub, &md->bl,
- md->db->range2, BL_NPC, target, &warp, &distance);
+ //Search for warps within mob's viewing range.
+ map_foreachinrange (mob_warpchase_sub, &md->bl,
+ md->db->range2, BL_NPC, target, &warp, &distance);
- if (warp && unit_walktobl(&md->bl, &warp->bl, 1, 1))
- return 1;
- return 0;
+ if (warp && unit_walktobl(&md->bl, &warp->bl, 1, 1))
+ return 1;
+ return 0;
}
/*==========================================
@@ -1375,269 +1404,281 @@ int mob_warpchase(struct mob_data *md, struct block_list *target)
*------------------------------------------*/
static bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick)
{
- struct block_list *tbl = NULL, *abl = NULL;
- int dist;
- int mode;
- int search_size;
- int view_range, can_move;
-
- if (md->bl.prev == NULL || md->status.hp <= 0)
- return false;
-
- if (DIFF_TICK(tick, md->last_thinktime) < MIN_MOBTHINKTIME)
- return false;
-
- md->last_thinktime = tick;
-
- if (md->ud.skilltimer != INVALID_TIMER)
- return false;
-
- if (md->ud.walktimer != INVALID_TIMER && md->ud.walkpath.path_pos <= 3)
- return false;
-
- // Abnormalities
- if ((md->sc.opt1 > 0 && md->sc.opt1 != OPT1_STONEWAIT && md->sc.opt1 != OPT1_BURNING && md->sc.opt1 != OPT1_CRYSTALIZE)
- || md->sc.data[SC_BLADESTOP] || md->sc.data[SC__MANHOLE] || md->sc.data[SC_CURSEDCIRCLE_TARGET]) {//Should reset targets.
- md->target_id = md->attacked_id = 0;
- return false;
- }
-
- if (md->sc.count && md->sc.data[SC_BLIND])
- view_range = 3;
- else
- view_range = md->db->range2;
- mode = status_get_mode(&md->bl);
-
- can_move = (mode&MD_CANMOVE)&&unit_can_move(&md->bl);
-
- if (md->target_id) {
- //Check validity of current target. [Skotlex]
- tbl = map_id2bl(md->target_id);
- if (!tbl || tbl->m != md->bl.m ||
- (md->ud.attacktimer == INVALID_TIMER && !status_check_skilluse(&md->bl, tbl, 0, 0)) ||
- (md->ud.walktimer != INVALID_TIMER && !(battle_config.mob_ai&0x1) && !check_distance_bl(&md->bl, tbl, md->min_chase)) ||
- (
- tbl->type == BL_PC &&
- ((((TBL_PC *)tbl)->state.gangsterparadise && !(mode&MD_BOSS)) ||
- ((TBL_PC *)tbl)->invincible_timer != INVALID_TIMER)
- )) { //Unlock current target.
- if (mob_warpchase(md, tbl))
- return true; //Chasing this target.
- mob_unlocktarget(md, tick-(battle_config.mob_ai&0x8?3000:0)); //Imediately do random walk.
- tbl = NULL;
- }
- }
-
- // Check for target change.
- if (md->attacked_id && mode&MD_CANATTACK) {
- if (md->attacked_id == md->target_id) {
- //Rude attacked check.
- if (!battle_check_range(&md->bl, tbl, md->status.rhw.range)
- && ( //Can't attack back and can't reach back.
- (!can_move && DIFF_TICK(tick, md->ud.canmove_tick) > 0 && (battle_config.mob_ai&0x2 || (md->sc.data[SC_SPIDERWEB] && md->sc.data[SC_SPIDERWEB]->val1)
- || md->sc.data[SC_BITE] || md->sc.data[SC_VACUUM_EXTREME] || md->sc.data[SC_THORNSTRAP]
- || md->sc.data[SC__MANHOLE])) // Not yet confirmed if boss will teleport once it can't reach target.
- || !mob_can_reach(md, tbl, md->min_chase, MSS_RUSH)
- )
- && md->state.attacked_count++ >= RUDE_ATTACKED_COUNT
- && !mobskill_use(md, tick, MSC_RUDEATTACKED) // If can't rude Attack
- && can_move && unit_escape(&md->bl, tbl, rnd()%10 +1)) { // Attempt escape
- //Escaped
- md->attacked_id = 0;
- return true;
- }
- } else if ((abl = map_id2bl(md->attacked_id)) && (!tbl || mob_can_changetarget(md, abl, mode))) {
- if (md->bl.m != abl->m || abl->prev == NULL
- || (dist = distance_bl(&md->bl, abl)) >= MAX_MINCHASE // Attacker longer than visual area
- || battle_check_target(&md->bl, abl, BCT_ENEMY) <= 0 // Attacker is not enemy of mob
- || (battle_config.mob_ai&0x2 && !status_check_skilluse(&md->bl, abl, 0, 0)) // Cannot normal attack back to Attacker
- || (!battle_check_range(&md->bl, abl, md->status.rhw.range) // Not on Melee Range and ...
- && ( // Reach check
- (!can_move && DIFF_TICK(tick, md->ud.canmove_tick) > 0 && (battle_config.mob_ai&0x2 || (md->sc.data[SC_SPIDERWEB] && md->sc.data[SC_SPIDERWEB]->val1)
- || md->sc.data[SC_BITE] || md->sc.data[SC_VACUUM_EXTREME] || md->sc.data[SC_THORNSTRAP]
- || md->sc.data[SC__MANHOLE])) // Not yet confirmed if boss will teleport once it can't reach target.
- || !mob_can_reach(md, abl, dist+md->db->range3, MSS_RUSH)
- )
- )) {
- // Rude attacked
- if (md->state.attacked_count++ >= RUDE_ATTACKED_COUNT
- && !mobskill_use(md, tick, MSC_RUDEATTACKED) && can_move
- && !tbl && unit_escape(&md->bl, abl, rnd()%10 +1)) {
- //Escaped.
- //TODO: Maybe it shouldn't attempt to run if it has another, valid target?
- md->attacked_id = 0;
- return true;
- }
- } else if (!(battle_config.mob_ai&0x2) && !status_check_skilluse(&md->bl, abl, 0, 0)) {
- //Can't attack back, but didn't invoke a rude attacked skill...
- } else {
- //Attackable
- if (!tbl || dist < md->status.rhw.range || !check_distance_bl(&md->bl, tbl, dist)
- || battle_gettarget(tbl) != md->bl.id) {
- //Change if the new target is closer than the actual one
- //or if the previous target is not attacking the mob. [Skotlex]
- md->target_id = md->attacked_id; // set target
- if (md->state.attacked_count)
- md->state.attacked_count--; //Should we reset rude attack count?
- md->min_chase = dist+md->db->range3;
- if (md->min_chase>MAX_MINCHASE)
- md->min_chase=MAX_MINCHASE;
- tbl = abl; //Set the new target
- }
- }
- }
-
- //Clear it since it's been checked for already.
- md->attacked_id = 0;
- }
-
- // Processing of slave monster
- if (md->master_id > 0 && mob_ai_sub_hard_slavemob(md, tick))
- return true;
-
- // Scan area for targets
- if (!tbl && mode&MD_LOOTER && md->lootitem && DIFF_TICK(tick, md->ud.canact_tick) > 0 &&
- (md->lootitem_count < LOOTITEM_SIZE || battle_config.monster_loot_type != 1)) {
- // Scan area for items to loot, avoid trying to loot of the mob is full and can't consume the items.
- map_foreachinrange(mob_ai_sub_hard_lootsearch, &md->bl, view_range, BL_ITEM, md, &tbl);
- }
-
- if ((!tbl && mode&MD_AGGRESSIVE) || md->state.skillstate == MSS_FOLLOW) {
- map_foreachinrange(mob_ai_sub_hard_activesearch, &md->bl, view_range, DEFAULT_ENEMY_TYPE(md), md, &tbl, mode);
- } else if (mode&MD_CHANGECHASE && (md->state.skillstate == MSS_RUSH || md->state.skillstate == MSS_FOLLOW)) {
- search_size = view_range<md->status.rhw.range ? view_range:md->status.rhw.range;
- map_foreachinrange(mob_ai_sub_hard_changechase, &md->bl, search_size, DEFAULT_ENEMY_TYPE(md), md, &tbl);
- }
-
- if (!tbl) { //No targets available.
- if (mode&MD_ANGRY && !md->state.aggressive)
- md->state.aggressive = 1; //Restore angry state when no targets are available.
-
- /* bg guardians follow allies when no targets nearby */
- if (md->bg_id && mode&MD_CANATTACK) {
- if (md->ud.walktimer != INVALID_TIMER)
- return true;/* we are already moving */
- map_foreachinrange(mob_ai_sub_hard_bg_ally, &md->bl, view_range, BL_PC, md, &tbl, mode);
- if (tbl) {
- if (distance_blxy(&md->bl, tbl->x, tbl->y) <= 3 || unit_walktobl(&md->bl, tbl, 1, 1))
- return true;/* we're moving or close enough don't unlock the target. */
- }
- }
-
- //This handles triggering idle walk/skill.
- mob_unlocktarget(md, tick);
- return true;
- }
-
- //Target exists, attack or loot as applicable.
- if (tbl->type == BL_ITEM) {
- //Loot time.
- struct flooritem_data *fitem;
- if (md->ud.target == tbl->id && md->ud.walktimer != INVALID_TIMER)
- return true; //Already locked.
- if (md->lootitem == NULL) {
- //Can't loot...
- mob_unlocktarget(md, tick);
- return true;
- }
- if (!check_distance_bl(&md->bl, tbl, 1)) {
- //Still not within loot range.
- if (!(mode&MD_CANMOVE)) {
- //A looter that can't move? Real smart.
- mob_unlocktarget(md,tick);
- return true;
- }
- if (!can_move) //Stuck. Wait before walking.
- return true;
- md->state.skillstate = MSS_LOOT;
- if (!unit_walktobl(&md->bl, tbl, 1, 1))
- mob_unlocktarget(md, tick); //Can't loot...
- return true;
- }
- //Within looting range.
- if (md->ud.attacktimer != INVALID_TIMER)
- return true; //Busy attacking?
-
- fitem = (struct flooritem_data *)tbl;
- //Logs items, taken by (L)ooter Mobs [Lupus]
- log_pick_mob(md, LOG_TYPE_LOOT, fitem->item_data.amount, &fitem->item_data);
-
- if (md->lootitem_count < LOOTITEM_SIZE) {
- memcpy(&md->lootitem[md->lootitem_count++], &fitem->item_data, sizeof(md->lootitem[0]));
- } else { //Destroy first looted item...
- if (md->lootitem[0].card[0] == CARD0_PET)
- intif_delete_petdata(MakeDWord(md->lootitem[0].card[1],md->lootitem[0].card[2]));
- memmove(&md->lootitem[0], &md->lootitem[1], (LOOTITEM_SIZE-1)*sizeof(md->lootitem[0]));
- memcpy(&md->lootitem[LOOTITEM_SIZE-1], &fitem->item_data, sizeof(md->lootitem[0]));
- }
- if (pcdb_checkid(md->vd->class_)) {
- //Give them walk act/delay to properly mimic players. [Skotlex]
- clif_takeitem(&md->bl,tbl);
- md->ud.canact_tick = tick + md->status.amotion;
- unit_set_walkdelay(&md->bl, tick, md->status.amotion, 1);
- }
- //Clear item.
- map_clearflooritem(tbl);
- mob_unlocktarget(md,tick);
- return true;
- }
- //Attempt to attack.
- //At this point we know the target is attackable, we just gotta check if the range matches.
- if (md->ud.target == tbl->id && md->ud.attacktimer != INVALID_TIMER) //Already locked.
- return true;
-
- if (battle_check_range(&md->bl, tbl, md->status.rhw.range)) {
- //Target within range, engage
-
- if (tbl->type == BL_PC)
- mob_log_damage(md, tbl, 0); //Log interaction (counts as 'attacker' for the exp bonus)
- unit_attack(&md->bl,tbl->id,1);
- return true;
- }
-
- //Out of range...
- if (!(mode&MD_CANMOVE)) {
- //Can't chase. Attempt an idle skill before unlocking.
- md->state.skillstate = MSS_IDLE;
- if (!mobskill_use(md, tick, -1))
- mob_unlocktarget(md,tick);
- return true;
- }
-
- if (!can_move) {
- //Stuck. Attempt an idle skill
- md->state.skillstate = MSS_IDLE;
- if (!(++md->ud.walk_count%IDLE_SKILL_INTERVAL))
- mobskill_use(md, tick, -1);
- return true;
- }
-
- if (md->ud.walktimer != INVALID_TIMER && md->ud.target == tbl->id &&
- (
- !(battle_config.mob_ai&0x1) ||
- check_distance_blxy(tbl, md->ud.to_x, md->ud.to_y, md->status.rhw.range)
- )) //Current target tile is still within attack range.
- return true;
-
- //Follow up if possible.
- if (!mob_can_reach(md, tbl, md->min_chase, MSS_RUSH) ||
- !unit_walktobl(&md->bl, tbl, md->status.rhw.range, 2))
- mob_unlocktarget(md,tick);
-
- return true;
+ struct block_list *tbl = NULL, *abl = NULL;
+ int dist;
+ int mode;
+ int search_size;
+ int view_range, can_move;
+
+ if(md->bl.prev == NULL || md->status.hp <= 0)
+ return false;
+
+ if (DIFF_TICK(tick, md->last_thinktime) < MIN_MOBTHINKTIME)
+ return false;
+
+ md->last_thinktime = tick;
+
+ if (md->ud.skilltimer != INVALID_TIMER)
+ return false;
+
+ if(md->ud.walktimer != INVALID_TIMER && md->ud.walkpath.path_pos <= 3)
+ return false;
+
+ // Abnormalities
+ if(( md->sc.opt1 > 0 && md->sc.opt1 != OPT1_STONEWAIT && md->sc.opt1 != OPT1_BURNING && md->sc.opt1 != OPT1_CRYSTALIZE )
+ || md->sc.data[SC_BLADESTOP] || md->sc.data[SC__MANHOLE] || md->sc.data[SC_CURSEDCIRCLE_TARGET]) {//Should reset targets.
+ md->target_id = md->attacked_id = 0;
+ return false;
+ }
+
+ if (md->sc.count && md->sc.data[SC_BLIND])
+ view_range = 3;
+ else
+ view_range = md->db->range2;
+ mode = status_get_mode(&md->bl);
+
+ can_move = (mode&MD_CANMOVE)&&unit_can_move(&md->bl);
+
+ if (md->target_id)
+ { //Check validity of current target. [Skotlex]
+ tbl = map_id2bl(md->target_id);
+ if (!tbl || tbl->m != md->bl.m ||
+ (md->ud.attacktimer == INVALID_TIMER && !status_check_skilluse(&md->bl, tbl, 0, 0)) ||
+ (md->ud.walktimer != INVALID_TIMER && !(battle_config.mob_ai&0x1) && !check_distance_bl(&md->bl, tbl, md->min_chase)) ||
+ (
+ tbl->type == BL_PC &&
+ ((((TBL_PC*)tbl)->state.gangsterparadise && !(mode&MD_BOSS)) ||
+ ((TBL_PC*)tbl)->invincible_timer != INVALID_TIMER)
+ )) { //Unlock current target.
+ if (mob_warpchase(md, tbl))
+ return true; //Chasing this target.
+ mob_unlocktarget(md, tick-(battle_config.mob_ai&0x8?3000:0)); //Imediately do random walk.
+ tbl = NULL;
+ }
+ }
+
+ // Check for target change.
+ if( md->attacked_id && mode&MD_CANATTACK )
+ {
+ if( md->attacked_id == md->target_id )
+ { //Rude attacked check.
+ if( !battle_check_range(&md->bl, tbl, md->status.rhw.range)
+ && ( //Can't attack back and can't reach back.
+ (!can_move && DIFF_TICK(tick, md->ud.canmove_tick) > 0 && (battle_config.mob_ai&0x2 || (md->sc.data[SC_SPIDERWEB] && md->sc.data[SC_SPIDERWEB]->val1)
+ || md->sc.data[SC_BITE] || md->sc.data[SC_VACUUM_EXTREME] || md->sc.data[SC_THORNSTRAP]
+ || md->sc.data[SC__MANHOLE])) // Not yet confirmed if boss will teleport once it can't reach target.
+ || !mob_can_reach(md, tbl, md->min_chase, MSS_RUSH)
+ )
+ && md->state.attacked_count++ >= RUDE_ATTACKED_COUNT
+ && !mobskill_use(md, tick, MSC_RUDEATTACKED) // If can't rude Attack
+ && can_move && unit_escape(&md->bl, tbl, rnd()%10 +1)) // Attempt escape
+ { //Escaped
+ md->attacked_id = 0;
+ return true;
+ }
+ }
+ else
+ if( (abl = map_id2bl(md->attacked_id)) && (!tbl || mob_can_changetarget(md, abl, mode)) )
+ {
+ if( md->bl.m != abl->m || abl->prev == NULL
+ || (dist = distance_bl(&md->bl, abl)) >= MAX_MINCHASE // Attacker longer than visual area
+ || battle_check_target(&md->bl, abl, BCT_ENEMY) <= 0 // Attacker is not enemy of mob
+ || (battle_config.mob_ai&0x2 && !status_check_skilluse(&md->bl, abl, 0, 0)) // Cannot normal attack back to Attacker
+ || (!battle_check_range(&md->bl, abl, md->status.rhw.range) // Not on Melee Range and ...
+ && ( // Reach check
+ (!can_move && DIFF_TICK(tick, md->ud.canmove_tick) > 0 && (battle_config.mob_ai&0x2 || (md->sc.data[SC_SPIDERWEB] && md->sc.data[SC_SPIDERWEB]->val1)
+ || md->sc.data[SC_BITE] || md->sc.data[SC_VACUUM_EXTREME] || md->sc.data[SC_THORNSTRAP]
+ || md->sc.data[SC__MANHOLE])) // Not yet confirmed if boss will teleport once it can't reach target.
+ || !mob_can_reach(md, abl, dist+md->db->range3, MSS_RUSH)
+ )
+ ) )
+ { // Rude attacked
+ if (md->state.attacked_count++ >= RUDE_ATTACKED_COUNT
+ && !mobskill_use(md, tick, MSC_RUDEATTACKED) && can_move
+ && !tbl && unit_escape(&md->bl, abl, rnd()%10 +1))
+ { //Escaped.
+ //TODO: Maybe it shouldn't attempt to run if it has another, valid target?
+ md->attacked_id = 0;
+ return true;
+ }
+ }
+ else
+ if (!(battle_config.mob_ai&0x2) && !status_check_skilluse(&md->bl, abl, 0, 0))
+ {
+ //Can't attack back, but didn't invoke a rude attacked skill...
+ }
+ else
+ { //Attackable
+ if (!tbl || dist < md->status.rhw.range || !check_distance_bl(&md->bl, tbl, dist)
+ || battle_gettarget(tbl) != md->bl.id)
+ { //Change if the new target is closer than the actual one
+ //or if the previous target is not attacking the mob. [Skotlex]
+ md->target_id = md->attacked_id; // set target
+ if (md->state.attacked_count)
+ md->state.attacked_count--; //Should we reset rude attack count?
+ md->min_chase = dist+md->db->range3;
+ if(md->min_chase>MAX_MINCHASE)
+ md->min_chase=MAX_MINCHASE;
+ tbl = abl; //Set the new target
+ }
+ }
+ }
+
+ //Clear it since it's been checked for already.
+ md->attacked_id = 0;
+ }
+
+ // Processing of slave monster
+ if (md->master_id > 0 && mob_ai_sub_hard_slavemob(md, tick))
+ return true;
+
+ // Scan area for targets
+ if (!tbl && mode&MD_LOOTER && md->lootitem && DIFF_TICK(tick, md->ud.canact_tick) > 0 &&
+ (md->lootitem_count < LOOTITEM_SIZE || battle_config.monster_loot_type != 1))
+ { // Scan area for items to loot, avoid trying to loot of the mob is full and can't consume the items.
+ map_foreachinrange (mob_ai_sub_hard_lootsearch, &md->bl, view_range, BL_ITEM, md, &tbl);
+ }
+
+ if ((!tbl && mode&MD_AGGRESSIVE) || md->state.skillstate == MSS_FOLLOW)
+ {
+ map_foreachinrange (mob_ai_sub_hard_activesearch, &md->bl, view_range, DEFAULT_ENEMY_TYPE(md), md, &tbl, mode);
+ }
+ else
+ if (mode&MD_CHANGECHASE && (md->state.skillstate == MSS_RUSH || md->state.skillstate == MSS_FOLLOW))
+ {
+ search_size = view_range<md->status.rhw.range ? view_range:md->status.rhw.range;
+ map_foreachinrange (mob_ai_sub_hard_changechase, &md->bl, search_size, DEFAULT_ENEMY_TYPE(md), md, &tbl);
+ }
+
+ if (!tbl) { //No targets available.
+ if (mode&MD_ANGRY && !md->state.aggressive)
+ md->state.aggressive = 1; //Restore angry state when no targets are available.
+
+ /* bg guardians follow allies when no targets nearby */
+ if( md->bg_id && mode&MD_CANATTACK ) {
+ if( md->ud.walktimer != INVALID_TIMER )
+ return true;/* we are already moving */
+ map_foreachinrange (mob_ai_sub_hard_bg_ally, &md->bl, view_range, BL_PC, md, &tbl, mode);
+ if( tbl ) {
+ if( distance_blxy(&md->bl, tbl->x, tbl->y) <= 3 || unit_walktobl(&md->bl, tbl, 1, 1) )
+ return true;/* we're moving or close enough don't unlock the target. */
+ }
+ }
+
+ //This handles triggering idle walk/skill.
+ mob_unlocktarget(md, tick);
+ return true;
+ }
+
+ //Target exists, attack or loot as applicable.
+ if (tbl->type == BL_ITEM)
+ { //Loot time.
+ struct flooritem_data *fitem;
+ if (md->ud.target == tbl->id && md->ud.walktimer != INVALID_TIMER)
+ return true; //Already locked.
+ if (md->lootitem == NULL)
+ { //Can't loot...
+ mob_unlocktarget (md, tick);
+ return true;
+ }
+ if (!check_distance_bl(&md->bl, tbl, 1))
+ { //Still not within loot range.
+ if (!(mode&MD_CANMOVE))
+ { //A looter that can't move? Real smart.
+ mob_unlocktarget(md,tick);
+ return true;
+ }
+ if (!can_move) //Stuck. Wait before walking.
+ return true;
+ md->state.skillstate = MSS_LOOT;
+ if (!unit_walktobl(&md->bl, tbl, 1, 1))
+ mob_unlocktarget(md, tick); //Can't loot...
+ return true;
+ }
+ //Within looting range.
+ if (md->ud.attacktimer != INVALID_TIMER)
+ return true; //Busy attacking?
+
+ fitem = (struct flooritem_data *)tbl;
+ //Logs items, taken by (L)ooter Mobs [Lupus]
+ log_pick_mob(md, LOG_TYPE_LOOT, fitem->item_data.amount, &fitem->item_data);
+
+ if (md->lootitem_count < LOOTITEM_SIZE) {
+ memcpy (&md->lootitem[md->lootitem_count++], &fitem->item_data, sizeof(md->lootitem[0]));
+ } else { //Destroy first looted item...
+ if (md->lootitem[0].card[0] == CARD0_PET)
+ intif_delete_petdata( MakeDWord(md->lootitem[0].card[1],md->lootitem[0].card[2]) );
+ memmove(&md->lootitem[0], &md->lootitem[1], (LOOTITEM_SIZE-1)*sizeof(md->lootitem[0]));
+ memcpy (&md->lootitem[LOOTITEM_SIZE-1], &fitem->item_data, sizeof(md->lootitem[0]));
+ }
+ if (pcdb_checkid(md->vd->class_))
+ { //Give them walk act/delay to properly mimic players. [Skotlex]
+ clif_takeitem(&md->bl,tbl);
+ md->ud.canact_tick = tick + md->status.amotion;
+ unit_set_walkdelay(&md->bl, tick, md->status.amotion, 1);
+ }
+ //Clear item.
+ map_clearflooritem (tbl);
+ mob_unlocktarget (md,tick);
+ return true;
+ }
+ //Attempt to attack.
+ //At this point we know the target is attackable, we just gotta check if the range matches.
+ if (md->ud.target == tbl->id && md->ud.attacktimer != INVALID_TIMER) //Already locked.
+ return true;
+
+ if (battle_check_range (&md->bl, tbl, md->status.rhw.range))
+ { //Target within range, engage
+
+ if(tbl->type == BL_PC)
+ mob_log_damage(md, tbl, 0); //Log interaction (counts as 'attacker' for the exp bonus)
+ unit_attack(&md->bl,tbl->id,1);
+ return true;
+ }
+
+ //Out of range...
+ if (!(mode&MD_CANMOVE))
+ { //Can't chase. Attempt an idle skill before unlocking.
+ md->state.skillstate = MSS_IDLE;
+ if (!mobskill_use(md, tick, -1))
+ mob_unlocktarget(md,tick);
+ return true;
+ }
+
+ if (!can_move)
+ { //Stuck. Attempt an idle skill
+ md->state.skillstate = MSS_IDLE;
+ if (!(++md->ud.walk_count%IDLE_SKILL_INTERVAL))
+ mobskill_use(md, tick, -1);
+ return true;
+ }
+
+ if (md->ud.walktimer != INVALID_TIMER && md->ud.target == tbl->id &&
+ (
+ !(battle_config.mob_ai&0x1) ||
+ check_distance_blxy(tbl, md->ud.to_x, md->ud.to_y, md->status.rhw.range)
+ )) //Current target tile is still within attack range.
+ return true;
+
+ //Follow up if possible.
+ if(!mob_can_reach(md, tbl, md->min_chase, MSS_RUSH) ||
+ !unit_walktobl(&md->bl, tbl, md->status.rhw.range, 2))
+ mob_unlocktarget(md,tick);
+
+ return true;
}
static int mob_ai_sub_hard_timer(struct block_list *bl,va_list ap)
{
- struct mob_data *md = (struct mob_data *)bl;
- unsigned int tick = va_arg(ap, unsigned int);
- if (mob_ai_sub_hard(md, tick)) {
- //Hard AI triggered.
- if (!md->state.spotted)
- md->state.spotted = 1;
- md->last_pcneartime = tick;
- }
- return 0;
+ struct mob_data *md = (struct mob_data*)bl;
+ unsigned int tick = va_arg(ap, unsigned int);
+ if (mob_ai_sub_hard(md, tick))
+ { //Hard AI triggered.
+ if(!md->state.spotted)
+ md->state.spotted = 1;
+ md->last_pcneartime = tick;
+ }
+ return 0;
}
/*==========================================
@@ -1645,11 +1686,11 @@ static int mob_ai_sub_hard_timer(struct block_list *bl,va_list ap)
*------------------------------------------*/
static int mob_ai_sub_foreachclient(struct map_session_data *sd,va_list ap)
{
- unsigned int tick;
- tick=va_arg(ap,unsigned int);
- map_foreachinrange(mob_ai_sub_hard_timer,&sd->bl, AREA_SIZE+ACTIVE_AI_RANGE, BL_MOB,tick);
+ unsigned int tick;
+ tick=va_arg(ap,unsigned int);
+ map_foreachinrange(mob_ai_sub_hard_timer,&sd->bl, AREA_SIZE+ACTIVE_AI_RANGE, BL_MOB,tick);
- return 0;
+ return 0;
}
/*==========================================
@@ -1657,61 +1698,68 @@ static int mob_ai_sub_foreachclient(struct map_session_data *sd,va_list ap)
*------------------------------------------*/
static int mob_ai_sub_lazy(struct mob_data *md, va_list args)
{
- unsigned int tick;
-
- nullpo_ret(md);
-
- if (md->bl.prev == NULL)
- return 0;
-
- tick = va_arg(args,unsigned int);
-
- if (battle_config.mob_ai&0x20 && map[md->bl.m].users>0)
- return (int)mob_ai_sub_hard(md, tick);
-
- if (md->bl.prev==NULL || md->status.hp == 0)
- return 1;
-
- if (battle_config.mob_active_time &&
- md->last_pcneartime &&
- !(md->status.mode&MD_BOSS) &&
- DIFF_TICK(tick,md->last_thinktime) > MIN_MOBTHINKTIME) {
- if (DIFF_TICK(tick,md->last_pcneartime) < battle_config.mob_active_time)
- return (int)mob_ai_sub_hard(md, tick);
- md->last_pcneartime = 0;
- }
-
- if (battle_config.boss_active_time &&
- md->last_pcneartime &&
- (md->status.mode&MD_BOSS) &&
- DIFF_TICK(tick,md->last_thinktime) > MIN_MOBTHINKTIME) {
- if (DIFF_TICK(tick,md->last_pcneartime) < battle_config.boss_active_time)
- return (int)mob_ai_sub_hard(md, tick);
- md->last_pcneartime = 0;
- }
-
- if (DIFF_TICK(tick,md->last_thinktime)< 10*MIN_MOBTHINKTIME)
- return 0;
-
- md->last_thinktime=tick;
-
- if (md->master_id) {
- mob_ai_sub_hard_slavemob(md,tick);
- return 0;
- }
-
- if (DIFF_TICK(md->next_walktime,tick) < 0 && (status_get_mode(&md->bl)&MD_CANMOVE) && unit_can_move(&md->bl)) {
- if (map[md->bl.m].users > 0) {
- if (rnd()%1000 < MOB_LAZYMOVEPERC(md))
- mob_randomwalk(md, tick);
- else if (rnd()%1000 < MOB_LAZYSKILLPERC) //Chance to do a mob's idle skill.
- mobskill_use(md, tick, -1);
- } else {
- if (rnd()%1000 < MOB_LAZYMOVEPERC(md))
- mob_randomwalk(md, tick);
- }
- }
- return 0;
+ unsigned int tick;
+
+ nullpo_ret(md);
+
+ if(md->bl.prev == NULL)
+ return 0;
+
+ tick = va_arg(args,unsigned int);
+
+ if (battle_config.mob_ai&0x20 && map[md->bl.m].users>0)
+ return (int)mob_ai_sub_hard(md, tick);
+
+ if (md->bl.prev==NULL || md->status.hp == 0)
+ return 1;
+
+ if(battle_config.mob_active_time &&
+ md->last_pcneartime &&
+ !(md->status.mode&MD_BOSS) &&
+ DIFF_TICK(tick,md->last_thinktime) > MIN_MOBTHINKTIME)
+ {
+ if (DIFF_TICK(tick,md->last_pcneartime) < battle_config.mob_active_time)
+ return (int)mob_ai_sub_hard(md, tick);
+ md->last_pcneartime = 0;
+ }
+
+ if(battle_config.boss_active_time &&
+ md->last_pcneartime &&
+ (md->status.mode&MD_BOSS) &&
+ DIFF_TICK(tick,md->last_thinktime) > MIN_MOBTHINKTIME)
+ {
+ if (DIFF_TICK(tick,md->last_pcneartime) < battle_config.boss_active_time)
+ return (int)mob_ai_sub_hard(md, tick);
+ md->last_pcneartime = 0;
+ }
+
+ if(DIFF_TICK(tick,md->last_thinktime)< 10*MIN_MOBTHINKTIME)
+ return 0;
+
+ md->last_thinktime=tick;
+
+ if (md->master_id) {
+ mob_ai_sub_hard_slavemob (md,tick);
+ return 0;
+ }
+
+ if( DIFF_TICK(md->next_walktime,tick) < 0 && (status_get_mode(&md->bl)&MD_CANMOVE) && unit_can_move(&md->bl) )
+ {
+ if( map[md->bl.m].users > 0 )
+ {
+ if( rnd()%1000 < MOB_LAZYMOVEPERC(md) )
+ mob_randomwalk(md, tick);
+ else
+ if( rnd()%1000 < MOB_LAZYSKILLPERC ) //Chance to do a mob's idle skill.
+ mobskill_use(md, tick, -1);
+ }
+ else
+ {
+ if( rnd()%1000 < MOB_LAZYMOVEPERC(md) )
+ mob_randomwalk(md, tick);
+ }
+ }
+ return 0;
}
/*==========================================
@@ -1719,8 +1767,8 @@ static int mob_ai_sub_lazy(struct mob_data *md, va_list args)
*------------------------------------------*/
static int mob_ai_lazy(int tid, unsigned int tick, int id, intptr_t data)
{
- map_foreachmob(mob_ai_sub_lazy,tick);
- return 0;
+ map_foreachmob(mob_ai_sub_lazy,tick);
+ return 0;
}
/*==========================================
@@ -1729,35 +1777,37 @@ static int mob_ai_lazy(int tid, unsigned int tick, int id, intptr_t data)
static int mob_ai_hard(int tid, unsigned int tick, int id, intptr_t data)
{
- if (battle_config.mob_ai&0x20)
- map_foreachmob(mob_ai_sub_lazy,tick);
- else
- map_foreachpc(mob_ai_sub_foreachclient,tick);
+ if (battle_config.mob_ai&0x20)
+ map_foreachmob(mob_ai_sub_lazy,tick);
+ else
+ map_foreachpc(mob_ai_sub_foreachclient,tick);
- return 0;
+ return 0;
}
/*==========================================
* Initializes the delay drop structure for mob-dropped items.
*------------------------------------------*/
-static struct item_drop *mob_setdropitem(int nameid, int qty) {
- struct item_drop *drop = ers_alloc(item_drop_ers, struct item_drop);
- memset(&drop->item_data, 0, sizeof(struct item));
- drop->item_data.nameid = nameid;
- drop->item_data.amount = qty;
- drop->item_data.identify = itemdb_isidentified(nameid);
- drop->next = NULL;
- return drop;
+static struct item_drop* mob_setdropitem(int nameid, int qty)
+{
+ struct item_drop *drop = ers_alloc(item_drop_ers, struct item_drop);
+ memset(&drop->item_data, 0, sizeof(struct item));
+ drop->item_data.nameid = nameid;
+ drop->item_data.amount = qty;
+ drop->item_data.identify = itemdb_isidentified(nameid);
+ drop->next = NULL;
+ return drop;
}
/*==========================================
* Initializes the delay drop structure for mob-looted items.
*------------------------------------------*/
-static struct item_drop *mob_setlootitem(struct item *item) {
- struct item_drop *drop = ers_alloc(item_drop_ers, struct item_drop);
- memcpy(&drop->item_data, item, sizeof(struct item));
- drop->next = NULL;
- return drop;
+static struct item_drop* mob_setlootitem(struct item* item)
+{
+ struct item_drop *drop = ers_alloc(item_drop_ers, struct item_drop);
+ memcpy(&drop->item_data, item, sizeof(struct item));
+ drop->next = NULL;
+ return drop;
}
/*==========================================
@@ -1765,20 +1815,20 @@ static struct item_drop *mob_setlootitem(struct item *item) {
*------------------------------------------*/
static int mob_delay_item_drop(int tid, unsigned int tick, int id, intptr_t data)
{
- struct item_drop_list *list;
- struct item_drop *ditem, *ditem_prev;
- list=(struct item_drop_list *)data;
- ditem = list->item;
- while (ditem) {
- map_addflooritem(&ditem->item_data,ditem->item_data.amount,
- list->m,list->x,list->y,
- list->first_charid,list->second_charid,list->third_charid,0);
- ditem_prev = ditem;
- ditem = ditem->next;
- ers_free(item_drop_ers, ditem_prev);
- }
- ers_free(item_drop_list_ers, list);
- return 0;
+ struct item_drop_list *list;
+ struct item_drop *ditem, *ditem_prev;
+ list=(struct item_drop_list *)data;
+ ditem = list->item;
+ while (ditem) {
+ map_addflooritem(&ditem->item_data,ditem->item_data.amount,
+ list->m,list->x,list->y,
+ list->first_charid,list->second_charid,list->third_charid,0);
+ ditem_prev = ditem;
+ ditem = ditem->next;
+ ers_free(item_drop_ers, ditem_prev);
+ }
+ ers_free(item_drop_list_ers, list);
+ return 0;
}
/*==========================================
@@ -1789,50 +1839,52 @@ static int mob_delay_item_drop(int tid, unsigned int tick, int id, intptr_t data
*------------------------------------------*/
static void mob_item_drop(struct mob_data *md, struct item_drop_list *dlist, struct item_drop *ditem, int loot, int drop_rate, unsigned short flag)
{
- TBL_PC *sd;
+ TBL_PC* sd;
- //Logs items, dropped by mobs [Lupus]
- log_pick_mob(md, loot?LOG_TYPE_LOOT:LOG_TYPE_PICKDROP_MONSTER, -ditem->item_data.amount, &ditem->item_data);
+ //Logs items, dropped by mobs [Lupus]
+ log_pick_mob(md, loot?LOG_TYPE_LOOT:LOG_TYPE_PICKDROP_MONSTER, -ditem->item_data.amount, &ditem->item_data);
- sd = map_charid2sd(dlist->first_charid);
- if (sd == NULL) sd = map_charid2sd(dlist->second_charid);
- if (sd == NULL) sd = map_charid2sd(dlist->third_charid);
+ sd = map_charid2sd(dlist->first_charid);
+ if( sd == NULL ) sd = map_charid2sd(dlist->second_charid);
+ if( sd == NULL ) sd = map_charid2sd(dlist->third_charid);
- if (sd
- && (drop_rate <= sd->state.autoloot || pc_isautolooting(sd, ditem->item_data.nameid))
- && (battle_config.idle_no_autoloot == 0 || DIFF_TICK(last_tick, sd->idletime) < battle_config.idle_no_autoloot)
- && (battle_config.homunculus_autoloot?1:!flag)
+ if( sd
+ && (drop_rate <= sd->state.autoloot || pc_isautolooting(sd, ditem->item_data.nameid))
+ && (battle_config.idle_no_autoloot == 0 || DIFF_TICK(last_tick, sd->idletime) < battle_config.idle_no_autoloot)
+ && (battle_config.homunculus_autoloot?1:!flag)
#ifdef AUTOLOOT_DISTANCE
- && sd->bl.m == md->bl.m
- && check_distance_blxy(&sd->bl, dlist->x, dlist->y, AUTOLOOT_DISTANCE)
+ && sd->bl.m == md->bl.m
+ && check_distance_blxy(&sd->bl, dlist->x, dlist->y, AUTOLOOT_DISTANCE)
#endif
- ) { //Autoloot.
- if (party_share_loot(party_search(sd->status.party_id),
- sd, &ditem->item_data, sd->status.char_id) == 0
- ) {
- ers_free(item_drop_ers, ditem);
- return;
- }
- }
- ditem->next = dlist->item;
- dlist->item = ditem;
+ ) { //Autoloot.
+ if (party_share_loot(party_search(sd->status.party_id),
+ sd, &ditem->item_data, sd->status.char_id) == 0
+ ) {
+ ers_free(item_drop_ers, ditem);
+ return;
+ }
+ }
+ ditem->next = dlist->item;
+ dlist->item = ditem;
}
int mob_timer_delete(int tid, unsigned int tick, int id, intptr_t data)
{
- struct block_list *bl = map_id2bl(id);
- struct mob_data *md = BL_CAST(BL_MOB, bl);
-
- if (md) {
- if (md->deletetimer != tid) {
- ShowError("mob_timer_delete: Timer mismatch: %d != %d\n", tid, md->deletetimer);
- return 0;
- }
- //for Alchemist CANNIBALIZE [Lupus]
- md->deletetimer = INVALID_TIMER;
- unit_free(bl, CLR_TELEPORT);
- }
- return 0;
+ struct block_list* bl = map_id2bl(id);
+ struct mob_data* md = BL_CAST(BL_MOB, bl);
+
+ if( md )
+ {
+ if( md->deletetimer != tid )
+ {
+ ShowError("mob_timer_delete: Timer mismatch: %d != %d\n", tid, md->deletetimer);
+ return 0;
+ }
+ //for Alchemist CANNIBALIZE [Lupus]
+ md->deletetimer = INVALID_TIMER;
+ unit_free(bl, CLR_TELEPORT);
+ }
+ return 0;
}
/*==========================================
@@ -1840,16 +1892,16 @@ int mob_timer_delete(int tid, unsigned int tick, int id, intptr_t data)
*------------------------------------------*/
int mob_deleteslave_sub(struct block_list *bl,va_list ap)
{
- struct mob_data *md;
- int id;
+ struct mob_data *md;
+ int id;
- nullpo_ret(bl);
- nullpo_ret(md = (struct mob_data *)bl);
+ nullpo_ret(bl);
+ nullpo_ret(md = (struct mob_data *)bl);
- id=va_arg(ap,int);
- if (md->master_id > 0 && md->master_id == id)
- status_kill(bl);
- return 0;
+ id=va_arg(ap,int);
+ if(md->master_id > 0 && md->master_id == id )
+ status_kill(bl);
+ return 0;
}
/*==========================================
@@ -1857,170 +1909,179 @@ int mob_deleteslave_sub(struct block_list *bl,va_list ap)
*------------------------------------------*/
int mob_deleteslave(struct mob_data *md)
{
- nullpo_ret(md);
+ nullpo_ret(md);
- map_foreachinmap(mob_deleteslave_sub, md->bl.m, BL_MOB,md->bl.id);
- return 0;
+ map_foreachinmap(mob_deleteslave_sub, md->bl.m, BL_MOB,md->bl.id);
+ return 0;
}
// Mob respawning through KAIZEL or NPC_REBIRTH [Skotlex]
int mob_respawn(int tid, unsigned int tick, int id, intptr_t data)
{
- struct block_list *bl = map_id2bl(id);
+ struct block_list *bl = map_id2bl(id);
- if (!bl) return 0;
- status_revive(bl, (uint8)data, 0);
- return 1;
+ if(!bl) return 0;
+ status_revive(bl, (uint8)data, 0);
+ return 1;
}
void mob_log_damage(struct mob_data *md, struct block_list *src, int damage)
{
- int char_id = 0, flag = MDLF_NORMAL;
-
- if (damage < 0)
- return; //Do nothing for absorbed damage.
- if (!damage && !(src->type&DEFAULT_ENEMY_TYPE(md)))
- return; //Do not log non-damaging effects from non-enemies.
- if (src->id == md->bl.id)
- return; //Do not log self-damage.
-
- switch (src->type) {
- case BL_PC: {
- struct map_session_data *sd = (TBL_PC *)src;
- char_id = sd->status.char_id;
- if (damage)
- md->attacked_id = src->id;
- break;
- }
- case BL_HOM: {
- struct homun_data *hd = (TBL_HOM *)src;
- flag = MDLF_HOMUN;
- if (hd->master)
- char_id = hd->master->status.char_id;
- if (damage)
- md->attacked_id = src->id;
- break;
- }
- case BL_MER: {
- struct mercenary_data *mer = (TBL_MER *)src;
- if (mer->master)
- char_id = mer->master->status.char_id;
- if (damage)
- md->attacked_id = src->id;
- break;
- }
- case BL_PET: {
- struct pet_data *pd = (TBL_PET *)src;
- flag = MDLF_PET;
- if (pd->msd) {
- char_id = pd->msd->status.char_id;
- if (damage) //Let mobs retaliate against the pet's master [Skotlex]
- md->attacked_id = pd->msd->bl.id;
- }
- break;
- }
- case BL_MOB: {
- struct mob_data *md2 = (TBL_MOB *)src;
- if (md2->special_state.ai && md2->master_id) {
- struct map_session_data *msd = map_id2sd(md2->master_id);
- if (msd)
- char_id = msd->status.char_id;
- }
- if (!damage)
- break;
- //Let players decide whether to retaliate versus the master or the mob. [Skotlex]
- if (md2->master_id && battle_config.retaliate_to_master)
- md->attacked_id = md2->master_id;
- else
- md->attacked_id = src->id;
- break;
- }
- case BL_ELEM: {
- struct elemental_data *ele = (TBL_ELEM *)src;
- if (ele->master)
- char_id = ele->master->status.char_id;
- if (damage)
- md->attacked_id = src->id;
- break;
- }
- default: //For all unhandled types.
- md->attacked_id = src->id;
- }
-
- if (char_id) {
- //Log damage...
- int i,minpos;
- unsigned int mindmg;
- for (i=0,minpos=DAMAGELOG_SIZE-1,mindmg=UINT_MAX; i<DAMAGELOG_SIZE; i++) {
- if (md->dmglog[i].id==char_id &&
- md->dmglog[i].flag==flag)
- break;
- if (md->dmglog[i].id==0) { //Store data in first empty slot.
- md->dmglog[i].id = char_id;
- md->dmglog[i].flag= flag;
- break;
- }
- if (md->dmglog[i].dmg<mindmg && i) {
- //Never overwrite first hit slot (he gets double exp bonus)
- minpos=i;
- mindmg=md->dmglog[i].dmg;
- }
- }
- if (i<DAMAGELOG_SIZE)
- md->dmglog[i].dmg+=damage;
- else {
- md->dmglog[minpos].id = char_id;
- md->dmglog[minpos].flag= flag;
- md->dmglog[minpos].dmg = damage;
- }
- }
- return;
+ int char_id = 0, flag = MDLF_NORMAL;
+
+ if( damage < 0 )
+ return; //Do nothing for absorbed damage.
+ if( !damage && !(src->type&DEFAULT_ENEMY_TYPE(md)) )
+ return; //Do not log non-damaging effects from non-enemies.
+ if( src->id == md->bl.id )
+ return; //Do not log self-damage.
+
+ switch( src->type )
+ {
+ case BL_PC:
+ {
+ struct map_session_data *sd = (TBL_PC*)src;
+ char_id = sd->status.char_id;
+ if( damage )
+ md->attacked_id = src->id;
+ break;
+ }
+ case BL_HOM:
+ {
+ struct homun_data *hd = (TBL_HOM*)src;
+ flag = MDLF_HOMUN;
+ if( hd->master )
+ char_id = hd->master->status.char_id;
+ if( damage )
+ md->attacked_id = src->id;
+ break;
+ }
+ case BL_MER:
+ {
+ struct mercenary_data *mer = (TBL_MER*)src;
+ if( mer->master )
+ char_id = mer->master->status.char_id;
+ if( damage )
+ md->attacked_id = src->id;
+ break;
+ }
+ case BL_PET:
+ {
+ struct pet_data *pd = (TBL_PET*)src;
+ flag = MDLF_PET;
+ if( pd->msd )
+ {
+ char_id = pd->msd->status.char_id;
+ if( damage ) //Let mobs retaliate against the pet's master [Skotlex]
+ md->attacked_id = pd->msd->bl.id;
+ }
+ break;
+ }
+ case BL_MOB:
+ {
+ struct mob_data* md2 = (TBL_MOB*)src;
+ if( md2->special_state.ai && md2->master_id )
+ {
+ struct map_session_data* msd = map_id2sd(md2->master_id);
+ if( msd )
+ char_id = msd->status.char_id;
+ }
+ if( !damage )
+ break;
+ //Let players decide whether to retaliate versus the master or the mob. [Skotlex]
+ if( md2->master_id && battle_config.retaliate_to_master )
+ md->attacked_id = md2->master_id;
+ else
+ md->attacked_id = src->id;
+ break;
+ }
+ case BL_ELEM:
+ {
+ struct elemental_data *ele = (TBL_ELEM*)src;
+ if( ele->master )
+ char_id = ele->master->status.char_id;
+ if( damage )
+ md->attacked_id = src->id;
+ break;
+ }
+ default: //For all unhandled types.
+ md->attacked_id = src->id;
+ }
+
+ if( char_id )
+ { //Log damage...
+ int i,minpos;
+ unsigned int mindmg;
+ for(i=0,minpos=DAMAGELOG_SIZE-1,mindmg=UINT_MAX;i<DAMAGELOG_SIZE;i++){
+ if(md->dmglog[i].id==char_id &&
+ md->dmglog[i].flag==flag)
+ break;
+ if(md->dmglog[i].id==0) { //Store data in first empty slot.
+ md->dmglog[i].id = char_id;
+ md->dmglog[i].flag= flag;
+ break;
+ }
+ if(md->dmglog[i].dmg<mindmg && i)
+ { //Never overwrite first hit slot (he gets double exp bonus)
+ minpos=i;
+ mindmg=md->dmglog[i].dmg;
+ }
+ }
+ if(i<DAMAGELOG_SIZE)
+ md->dmglog[i].dmg+=damage;
+ else {
+ md->dmglog[minpos].id = char_id;
+ md->dmglog[minpos].flag= flag;
+ md->dmglog[minpos].dmg = damage;
+ }
+ }
+ return;
}
//Call when a mob has received damage.
void mob_damage(struct mob_data *md, struct block_list *src, int damage)
{
- if (damage > 0) { //Store total damage...
- if (UINT_MAX - (unsigned int)damage > md->tdmg)
- md->tdmg+=damage;
- else if (md->tdmg == UINT_MAX)
- damage = 0; //Stop recording damage once the cap has been reached.
- else { //Cap damage log...
- damage = (int)(UINT_MAX - md->tdmg);
- md->tdmg = UINT_MAX;
- }
- if (md->state.aggressive) { //No longer aggressive, change to retaliate AI.
- md->state.aggressive = 0;
- if (md->state.skillstate== MSS_ANGRY)
- md->state.skillstate = MSS_BERSERK;
- if (md->state.skillstate== MSS_FOLLOW)
- md->state.skillstate = MSS_RUSH;
- }
- //Log damage
- if (src)
- mob_log_damage(md, src, damage);
- md->dmgtick = gettick();
- }
-
- if (battle_config.show_mob_info&3)
- clif_charnameack(0, &md->bl);
-
- if (!src)
- return;
+ if (damage > 0) { //Store total damage...
+ if (UINT_MAX - (unsigned int)damage > md->tdmg)
+ md->tdmg+=damage;
+ else if (md->tdmg == UINT_MAX)
+ damage = 0; //Stop recording damage once the cap has been reached.
+ else { //Cap damage log...
+ damage = (int)(UINT_MAX - md->tdmg);
+ md->tdmg = UINT_MAX;
+ }
+ if (md->state.aggressive) { //No longer aggressive, change to retaliate AI.
+ md->state.aggressive = 0;
+ if(md->state.skillstate== MSS_ANGRY)
+ md->state.skillstate = MSS_BERSERK;
+ if(md->state.skillstate== MSS_FOLLOW)
+ md->state.skillstate = MSS_RUSH;
+ }
+ //Log damage
+ if (src)
+ mob_log_damage(md, src, damage);
+ md->dmgtick = gettick();
+ }
+
+ if (battle_config.show_mob_info&3)
+ clif_charnameack (0, &md->bl);
+
+ if (!src)
+ return;
#if PACKETVER >= 20120404
- if (!(md->status.mode&MD_BOSS)) {
- int i;
- for (i = 0; i < DAMAGELOG_SIZE; i++) { // must show hp bar to all char who already hit the mob.
- struct map_session_data *sd = map_charid2sd(md->dmglog[i].id);
- if (sd && check_distance_bl(&md->bl, &sd->bl, AREA_SIZE)) // check if in range
- clif_monster_hp_bar(md, sd->fd);
- }
- }
+ if( !(md->status.mode&MD_BOSS) ){
+ int i;
+ for(i = 0; i < DAMAGELOG_SIZE; i++){ // must show hp bar to all char who already hit the mob.
+ struct map_session_data *sd = map_charid2sd(md->dmglog[i].id);
+ if( sd && check_distance_bl(&md->bl, &sd->bl, AREA_SIZE) ) // check if in range
+ clif_monster_hp_bar(md, sd->fd);
+ }
+ }
#endif
- if (md->special_state.ai == 2) { //LOne WOlf explained that ANYONE can trigger the marine countdown skill. [Skotlex]
- md->state.alchemist = 1;
- mobskill_use(md, gettick(), MSC_ALCHEMIST);
- }
+ if( md->special_state.ai == 2 ) {//LOne WOlf explained that ANYONE can trigger the marine countdown skill. [Skotlex]
+ md->state.alchemist = 1;
+ mobskill_use(md, gettick(), MSC_ALCHEMIST);
+ }
}
/*==========================================
@@ -2029,704 +2090,704 @@ void mob_damage(struct mob_data *md, struct block_list *src, int damage)
*------------------------------------------*/
int mob_dead(struct mob_data *md, struct block_list *src, int type)
{
- struct status_data *status;
- struct map_session_data *sd = NULL, *tmpsd[DAMAGELOG_SIZE];
- struct map_session_data *mvp_sd = NULL, *second_sd = NULL, *third_sd = NULL;
-
- struct {
- struct party_data *p;
- int id,zeny;
- unsigned int base_exp,job_exp;
- } pt[DAMAGELOG_SIZE];
- int i,temp,count,pnum=0,m=md->bl.m;
- int dmgbltypes = 0; // bitfield of all bl types, that caused damage to the mob and are elligible for exp distribution
- unsigned int mvp_damage, tick = gettick();
- bool rebirth, homkillonly;
-
- status = &md->status;
-
- if (src && src->type == BL_PC) {
- sd = (struct map_session_data *)src;
- mvp_sd = sd;
- }
-
- if (md->guardian_data && md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS)
- guild_castledatasave(md->guardian_data->castle->castle_id, 10+md->guardian_data->number,0);
-
- if (src) {
- // Use Dead skill only if not killed by Script or Command
- md->state.skillstate = MSS_DEAD;
- mobskill_use(md,tick,-1);
- }
-
- map_freeblock_lock();
-
- memset(pt,0,sizeof(pt));
-
- if (src && src->type == BL_MOB)
- mob_unlocktarget((struct mob_data *)src,tick);
-
- // filter out entries not eligible for exp distribution
- memset(tmpsd,0,sizeof(tmpsd));
- for (i = 0, count = 0, mvp_damage = 0; i < DAMAGELOG_SIZE && md->dmglog[i].id; i++) {
- struct map_session_data *tsd = map_charid2sd(md->dmglog[i].id);
-
- if (tsd == NULL)
- continue; // skip empty entries
- if (tsd->bl.m != m)
- continue; // skip players not on this map
- count++; //Only logged into same map chars are counted for the total.
- if (pc_isdead(tsd))
- continue; // skip dead players
- if (md->dmglog[i].flag == MDLF_HOMUN && !merc_is_hom_active(tsd->hd))
- continue; // skip homunc's share if inactive
- if (md->dmglog[i].flag == MDLF_PET && (!tsd->status.pet_id || !tsd->pd))
- continue; // skip pet's share if inactive
-
- if (md->dmglog[i].dmg > mvp_damage) {
- third_sd = second_sd;
- second_sd = mvp_sd;
- mvp_sd = tsd;
- mvp_damage = md->dmglog[i].dmg;
- }
-
- tmpsd[i] = tsd; // record as valid damage-log entry
-
- switch (md->dmglog[i].flag) {
- case MDLF_NORMAL:
- dmgbltypes|= BL_PC;
- break;
- case MDLF_HOMUN:
- dmgbltypes|= BL_HOM;
- break;
- case MDLF_PET:
- dmgbltypes|= BL_PET;
- break;
- }
- }
-
- // determines, if the monster was killed by homunculus' damage only
- homkillonly = (bool)((dmgbltypes&BL_HOM) && !(dmgbltypes&~BL_HOM));
-
- if (!battle_config.exp_calc_type && count > 1) {
- //Apply first-attacker 200% exp share bonus
- //TODO: Determine if this should go before calculating the MVP player instead of after.
- if (UINT_MAX - md->dmglog[0].dmg > md->tdmg) {
- md->tdmg += md->dmglog[0].dmg;
- md->dmglog[0].dmg<<=1;
- } else {
- md->dmglog[0].dmg+= UINT_MAX - md->tdmg;
- md->tdmg = UINT_MAX;
- }
- }
-
- if (!(type&2) && //No exp
- (!map[m].flag.pvp || battle_config.pvp_exp) && //Pvp no exp rule [MouseJstr]
- (!md->master_id || !md->special_state.ai) && //Only player-summoned mobs do not give exp. [Skotlex]
- (!map[m].flag.nobaseexp || !map[m].flag.nojobexp) //Gives Exp
- ) { //Experience calculation.
- int bonus = 100; //Bonus on top of your share (common to all attackers).
- if (md->sc.data[SC_RICHMANKIM])
- bonus += md->sc.data[SC_RICHMANKIM]->val2;
- if (sd) {
- temp = status_get_class(&md->bl);
- if (sd->sc.data[SC_MIRACLE]) i = 2; //All mobs are Star Targets
- else
- ARR_FIND(0, MAX_PC_FEELHATE, i, temp == sd->hate_mob[i] &&
- (battle_config.allow_skill_without_day || sg_info[i].day_func()));
- if (i<MAX_PC_FEELHATE && (temp=pc_checkskill(sd,sg_info[i].bless_id)))
- bonus += (i==2?20:10)*temp;
- }
- if (battle_config.mobs_level_up && md->level > md->db->lv) // [Valaris]
- bonus += (md->level-md->db->lv)*battle_config.mobs_level_up_exp_rate;
-
- for (i = 0; i < DAMAGELOG_SIZE && md->dmglog[i].id; i++) {
- int flag=1,zeny=0;
- unsigned int base_exp, job_exp;
- double per; //Your share of the mob's exp
-
- if (!tmpsd[i]) continue;
-
- if (!battle_config.exp_calc_type && md->tdmg)
- //jAthena's exp formula based on total damage.
- per = (double)md->dmglog[i].dmg/(double)md->tdmg;
- else {
- //eAthena's exp formula based on max hp.
- per = (double)md->dmglog[i].dmg/(double)status->max_hp;
- if (per > 2) per = 2; // prevents unlimited exp gain
- }
-
- if (count>1 && battle_config.exp_bonus_attacker) {
- //Exp bonus per additional attacker.
- if (count > battle_config.exp_bonus_max_attacker)
- count = battle_config.exp_bonus_max_attacker;
- per += per*((count-1)*battle_config.exp_bonus_attacker)/100.;
- }
-
- // change experience for different sized monsters [Valaris]
- if (battle_config.mob_size_influence) {
- if (md->special_state.size == SZ_MEDIUM)
- per /= 2.;
- else if (md->special_state.size == SZ_BIG)
- per *= 2.;
- }
-
- if (md->dmglog[i].flag == MDLF_PET)
- per *= battle_config.pet_attack_exp_rate/100.;
-
- if (battle_config.zeny_from_mobs && md->level) {
- // zeny calculation moblv + random moblv [Valaris]
- zeny=(int)((md->level+rnd()%md->level)*per*bonus/100.);
- if (md->db->mexp > 0)
- zeny*=rnd()%250;
- }
-
- if (map[m].flag.nobaseexp || !md->db->base_exp)
- base_exp = 0;
- else
- base_exp = (unsigned int)cap_value(md->db->base_exp * per * bonus/100. * map[m].bexp/100., 1, UINT_MAX);
-
- if (map[m].flag.nojobexp || !md->db->job_exp || md->dmglog[i].flag == MDLF_HOMUN) //Homun earned job-exp is always lost.
- job_exp = 0;
- else
- job_exp = (unsigned int)cap_value(md->db->job_exp * per * bonus/100. * map[m].jexp/100., 1, UINT_MAX);
-
- if ((temp = tmpsd[i]->status.party_id)>0 /*&& !md->dmglog[i].flag == MDLF_HOMUN*/) { //Homun-done damage (flag 1) is given to party
- int j;
- for (j=0; j<pnum && pt[j].id!=temp; j++); //Locate party.
-
- if (j==pnum) { //Possibly add party.
- pt[pnum].p = party_search(temp);
- if (pt[pnum].p && pt[pnum].p->party.exp) {
- pt[pnum].id=temp;
- pt[pnum].base_exp=base_exp;
- pt[pnum].job_exp=job_exp;
- pt[pnum].zeny=zeny; // zeny share [Valaris]
- pnum++;
- flag=0;
- }
- } else { //Add to total
- if (pt[j].base_exp > UINT_MAX - base_exp)
- pt[j].base_exp=UINT_MAX;
- else
- pt[j].base_exp+=base_exp;
-
- if (pt[j].job_exp > UINT_MAX - job_exp)
- pt[j].job_exp=UINT_MAX;
- else
- pt[j].job_exp+=job_exp;
-
- pt[j].zeny+=zeny; // zeny share [Valaris]
- flag=0;
- }
- }
- if (flag) {
- if (base_exp && md->dmglog[i].flag == MDLF_HOMUN) //tmpsd[i] is null if it has no homunc.
- merc_hom_gainexp(tmpsd[i]->hd, base_exp);
- if (base_exp || job_exp) {
- if (md->dmglog[i].flag != MDLF_PET || battle_config.pet_attack_exp_to_master) {
+ struct status_data *status;
+ struct map_session_data *sd = NULL, *tmpsd[DAMAGELOG_SIZE];
+ struct map_session_data *mvp_sd = NULL, *second_sd = NULL, *third_sd = NULL;
+
+ struct {
+ struct party_data *p;
+ int id,zeny;
+ unsigned int base_exp,job_exp;
+ } pt[DAMAGELOG_SIZE];
+ int i,temp,count,pnum=0,m=md->bl.m;
+ int dmgbltypes = 0; // bitfield of all bl types, that caused damage to the mob and are elligible for exp distribution
+ unsigned int mvp_damage, tick = gettick();
+ bool rebirth, homkillonly;
+
+ status = &md->status;
+
+ if( src && src->type == BL_PC )
+ {
+ sd = (struct map_session_data *)src;
+ mvp_sd = sd;
+ }
+
+ if( md->guardian_data && md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS )
+ guild_castledatasave(md->guardian_data->castle->castle_id, 10+md->guardian_data->number,0);
+
+ if( src )
+ { // Use Dead skill only if not killed by Script or Command
+ md->state.skillstate = MSS_DEAD;
+ mobskill_use(md,tick,-1);
+ }
+
+ map_freeblock_lock();
+
+ memset(pt,0,sizeof(pt));
+
+ if(src && src->type == BL_MOB)
+ mob_unlocktarget((struct mob_data *)src,tick);
+
+ // filter out entries not eligible for exp distribution
+ memset(tmpsd,0,sizeof(tmpsd));
+ for(i = 0, count = 0, mvp_damage = 0; i < DAMAGELOG_SIZE && md->dmglog[i].id; i++)
+ {
+ struct map_session_data* tsd = map_charid2sd(md->dmglog[i].id);
+
+ if(tsd == NULL)
+ continue; // skip empty entries
+ if(tsd->bl.m != m)
+ continue; // skip players not on this map
+ count++; //Only logged into same map chars are counted for the total.
+ if (pc_isdead(tsd))
+ continue; // skip dead players
+ if(md->dmglog[i].flag == MDLF_HOMUN && !merc_is_hom_active(tsd->hd))
+ continue; // skip homunc's share if inactive
+ if( md->dmglog[i].flag == MDLF_PET && (!tsd->status.pet_id || !tsd->pd) )
+ continue; // skip pet's share if inactive
+
+ if(md->dmglog[i].dmg > mvp_damage)
+ {
+ third_sd = second_sd;
+ second_sd = mvp_sd;
+ mvp_sd = tsd;
+ mvp_damage = md->dmglog[i].dmg;
+ }
+
+ tmpsd[i] = tsd; // record as valid damage-log entry
+
+ switch( md->dmglog[i].flag )
+ {
+ case MDLF_NORMAL: dmgbltypes|= BL_PC; break;
+ case MDLF_HOMUN: dmgbltypes|= BL_HOM; break;
+ case MDLF_PET: dmgbltypes|= BL_PET; break;
+ }
+ }
+
+ // determines, if the monster was killed by homunculus' damage only
+ homkillonly = (bool)( ( dmgbltypes&BL_HOM ) && !( dmgbltypes&~BL_HOM ) );
+
+ if(!battle_config.exp_calc_type && count > 1)
+ { //Apply first-attacker 200% exp share bonus
+ //TODO: Determine if this should go before calculating the MVP player instead of after.
+ if (UINT_MAX - md->dmglog[0].dmg > md->tdmg) {
+ md->tdmg += md->dmglog[0].dmg;
+ md->dmglog[0].dmg<<=1;
+ } else {
+ md->dmglog[0].dmg+= UINT_MAX - md->tdmg;
+ md->tdmg = UINT_MAX;
+ }
+ }
+
+ if(!(type&2) && //No exp
+ (!map[m].flag.pvp || battle_config.pvp_exp) && //Pvp no exp rule [MouseJstr]
+ (!md->master_id || !md->special_state.ai) && //Only player-summoned mobs do not give exp. [Skotlex]
+ (!map[m].flag.nobaseexp || !map[m].flag.nojobexp) //Gives Exp
+ ) { //Experience calculation.
+ int bonus = 100; //Bonus on top of your share (common to all attackers).
+ if (md->sc.data[SC_RICHMANKIM])
+ bonus += md->sc.data[SC_RICHMANKIM]->val2;
+ if(sd) {
+ temp = status_get_class(&md->bl);
+ if(sd->sc.data[SC_MIRACLE]) i = 2; //All mobs are Star Targets
+ else
+ ARR_FIND(0, MAX_PC_FEELHATE, i, temp == sd->hate_mob[i] &&
+ (battle_config.allow_skill_without_day || sg_info[i].day_func()));
+ if(i<MAX_PC_FEELHATE && (temp=pc_checkskill(sd,sg_info[i].bless_id)))
+ bonus += (i==2?20:10)*temp;
+ }
+ if(battle_config.mobs_level_up && md->level > md->db->lv) // [Valaris]
+ bonus += (md->level-md->db->lv)*battle_config.mobs_level_up_exp_rate;
+
+ for(i = 0; i < DAMAGELOG_SIZE && md->dmglog[i].id; i++)
+ {
+ int flag=1,zeny=0;
+ unsigned int base_exp, job_exp;
+ double per; //Your share of the mob's exp
+
+ if (!tmpsd[i]) continue;
+
+ if (!battle_config.exp_calc_type && md->tdmg)
+ //jAthena's exp formula based on total damage.
+ per = (double)md->dmglog[i].dmg/(double)md->tdmg;
+ else {
+ //eAthena's exp formula based on max hp.
+ per = (double)md->dmglog[i].dmg/(double)status->max_hp;
+ if (per > 2) per = 2; // prevents unlimited exp gain
+ }
+
+ if (count>1 && battle_config.exp_bonus_attacker) {
+ //Exp bonus per additional attacker.
+ if (count > battle_config.exp_bonus_max_attacker)
+ count = battle_config.exp_bonus_max_attacker;
+ per += per*((count-1)*battle_config.exp_bonus_attacker)/100.;
+ }
+
+ // change experience for different sized monsters [Valaris]
+ if (battle_config.mob_size_influence)
+ {
+ if (md->special_state.size == SZ_MEDIUM)
+ per /= 2.;
+ else if (md->special_state.size == SZ_BIG)
+ per *= 2.;
+ }
+
+ if( md->dmglog[i].flag == MDLF_PET )
+ per *= battle_config.pet_attack_exp_rate/100.;
+
+ if(battle_config.zeny_from_mobs && md->level) {
+ // zeny calculation moblv + random moblv [Valaris]
+ zeny=(int) ((md->level+rnd()%md->level)*per*bonus/100.);
+ if(md->db->mexp > 0)
+ zeny*=rnd()%250;
+ }
+
+ if (map[m].flag.nobaseexp || !md->db->base_exp)
+ base_exp = 0;
+ else
+ base_exp = (unsigned int)cap_value(md->db->base_exp * per * bonus/100. * map[m].bexp/100., 1, UINT_MAX);
+
+ if (map[m].flag.nojobexp || !md->db->job_exp || md->dmglog[i].flag == MDLF_HOMUN) //Homun earned job-exp is always lost.
+ job_exp = 0;
+ else
+ job_exp = (unsigned int)cap_value(md->db->job_exp * per * bonus/100. * map[m].jexp/100., 1, UINT_MAX);
+
+ if((temp = tmpsd[i]->status.party_id )>0 && !md->dmglog[i].flag == MDLF_HOMUN) //Homun-done damage (flag 1) is not given to party
+ {
+ int j;
+ for(j=0;j<pnum && pt[j].id!=temp;j++); //Locate party.
+
+ if(j==pnum){ //Possibly add party.
+ pt[pnum].p = party_search(temp);
+ if(pt[pnum].p && pt[pnum].p->party.exp)
+ {
+ pt[pnum].id=temp;
+ pt[pnum].base_exp=base_exp;
+ pt[pnum].job_exp=job_exp;
+ pt[pnum].zeny=zeny; // zeny share [Valaris]
+ pnum++;
+ flag=0;
+ }
+ }else{ //Add to total
+ if (pt[j].base_exp > UINT_MAX - base_exp)
+ pt[j].base_exp=UINT_MAX;
+ else
+ pt[j].base_exp+=base_exp;
+
+ if (pt[j].job_exp > UINT_MAX - job_exp)
+ pt[j].job_exp=UINT_MAX;
+ else
+ pt[j].job_exp+=job_exp;
+
+ pt[j].zeny+=zeny; // zeny share [Valaris]
+ flag=0;
+ }
+ }
+ if(flag) {
+ if(base_exp && md->dmglog[i].flag == MDLF_HOMUN) //tmpsd[i] is null if it has no homunc.
+ merc_hom_gainexp(tmpsd[i]->hd, base_exp);
+ if(base_exp || job_exp)
+ {
+ if( md->dmglog[i].flag != MDLF_PET || battle_config.pet_attack_exp_to_master ) {
#ifdef RENEWAL_EXP
- int rate = pc_level_penalty_mod(tmpsd[i], md, 1);
- base_exp = (unsigned int)cap_value(base_exp * rate / 100, 1, UINT_MAX);
- job_exp = (unsigned int)cap_value(job_exp * rate / 100, 1, UINT_MAX);
+ int rate = pc_level_penalty_mod(tmpsd[i], md, 1);
+ base_exp = (unsigned int)cap_value(base_exp * rate / 100, 1, UINT_MAX);
+ job_exp = (unsigned int)cap_value(job_exp * rate / 100, 1, UINT_MAX);
#endif
- pc_gainexp(tmpsd[i], &md->bl, base_exp, job_exp, false);
- }
- }
- if (zeny) // zeny from mobs [Valaris]
- pc_getzeny(tmpsd[i], zeny, LOG_TYPE_PICKDROP_MONSTER, NULL);
- }
- }
-
- for (i=0; i<pnum; i++) //Party share.
- party_exp_share(pt[i].p, &md->bl, pt[i].base_exp,pt[i].job_exp,pt[i].zeny);
-
- } //End EXP giving.
-
- if (!(type&1) && !map[m].flag.nomobloot && !md->state.rebirth && (
- !md->special_state.ai || //Non special mob
- battle_config.alchemist_summon_reward == 2 || //All summoned give drops
- (md->special_state.ai==2 && battle_config.alchemist_summon_reward == 1) //Marine Sphere Drops items.
- )) {
- // Item Drop
- struct item_drop_list *dlist = ers_alloc(item_drop_list_ers, struct item_drop_list);
- struct item_drop *ditem;
- struct item_data *it = NULL;
- int drop_rate;
+ pc_gainexp(tmpsd[i], &md->bl, base_exp, job_exp, false);
+ }
+ }
+ if(zeny) // zeny from mobs [Valaris]
+ pc_getzeny(tmpsd[i], zeny, LOG_TYPE_PICKDROP_MONSTER, NULL);
+ }
+ }
+
+ for(i=0;i<pnum;i++) //Party share.
+ party_exp_share(pt[i].p, &md->bl, pt[i].base_exp,pt[i].job_exp,pt[i].zeny);
+
+ } //End EXP giving.
+
+ if( !(type&1) && !map[m].flag.nomobloot && !md->state.rebirth && (
+ !md->special_state.ai || //Non special mob
+ battle_config.alchemist_summon_reward == 2 || //All summoned give drops
+ (md->special_state.ai==2 && battle_config.alchemist_summon_reward == 1) //Marine Sphere Drops items.
+ ) )
+ { // Item Drop
+ struct item_drop_list *dlist = ers_alloc(item_drop_list_ers, struct item_drop_list);
+ struct item_drop *ditem;
+ struct item_data* it = NULL;
+ int drop_rate;
#ifdef RENEWAL_DROP
- int drop_modifier = mvp_sd ? pc_level_penalty_mod(mvp_sd, md, 2) :
- second_sd ? pc_level_penalty_mod(second_sd, md, 2):
- third_sd ? pc_level_penalty_mod(third_sd, md, 2) :
- 100;/* no player was attached, we dont use any modifier (100 = rates are not touched) */
+ int drop_modifier = mvp_sd ? pc_level_penalty_mod(mvp_sd, md, 2) :
+ second_sd ? pc_level_penalty_mod(second_sd, md, 2):
+ third_sd ? pc_level_penalty_mod(third_sd, md, 2) :
+ 100;/* no player was attached, we dont use any modifier (100 = rates are not touched) */
#endif
- dlist->m = md->bl.m;
- dlist->x = md->bl.x;
- dlist->y = md->bl.y;
- dlist->first_charid = (mvp_sd ? mvp_sd->status.char_id : 0);
- dlist->second_charid = (second_sd ? second_sd->status.char_id : 0);
- dlist->third_charid = (third_sd ? third_sd->status.char_id : 0);
- dlist->item = NULL;
-
- for (i = 0; i < MAX_MOB_DROP; i++) {
- if (md->db->dropitem[i].nameid <= 0)
- continue;
- if (!(it = itemdb_exists(md->db->dropitem[i].nameid)))
- continue;
- drop_rate = md->db->dropitem[i].p;
- if (drop_rate <= 0) {
- if (battle_config.drop_rate0item)
- continue;
- drop_rate = 1;
- }
-
- // change drops depending on monsters size [Valaris]
- if (battle_config.mob_size_influence) {
- if (md->special_state.size == SZ_MEDIUM && drop_rate >= 2)
- drop_rate /= 2;
- else if (md->special_state.size == SZ_BIG)
- drop_rate *= 2;
- }
-
- if (src) {
- //Drops affected by luk as a fixed increase [Valaris]
- if (battle_config.drops_by_luk)
- drop_rate += status_get_luk(src)*battle_config.drops_by_luk/100;
- //Drops affected by luk as a % increase [Skotlex]
- if (battle_config.drops_by_luk2)
- drop_rate += (int)(0.5+drop_rate*status_get_luk(src)*battle_config.drops_by_luk2/10000.);
- }
- if (sd && battle_config.pk_mode &&
- (int)(md->level - sd->status.base_level) >= 20)
- drop_rate = (int)(drop_rate*1.25); // pk_mode increase drops if 20 level difference [Valaris]
-
- // Increase drop rate if user has SC_ITEMBOOST
- if (sd && sd->sc.data[SC_ITEMBOOST]) // now rig the drop rate to never be over 90% unless it is originally >90%.
- drop_rate = max(drop_rate,cap_value((int)(0.5+drop_rate*(sd->sc.data[SC_ITEMBOOST]->val1)/100.),0,9000));
+ dlist->m = md->bl.m;
+ dlist->x = md->bl.x;
+ dlist->y = md->bl.y;
+ dlist->first_charid = (mvp_sd ? mvp_sd->status.char_id : 0);
+ dlist->second_charid = (second_sd ? second_sd->status.char_id : 0);
+ dlist->third_charid = (third_sd ? third_sd->status.char_id : 0);
+ dlist->item = NULL;
+
+ for (i = 0; i < MAX_MOB_DROP; i++)
+ {
+ if (md->db->dropitem[i].nameid <= 0)
+ continue;
+ if ( !(it = itemdb_exists(md->db->dropitem[i].nameid)) )
+ continue;
+ drop_rate = md->db->dropitem[i].p;
+ if (drop_rate <= 0) {
+ if (battle_config.drop_rate0item)
+ continue;
+ drop_rate = 1;
+ }
+
+ // change drops depending on monsters size [Valaris]
+ if (battle_config.mob_size_influence)
+ {
+ if (md->special_state.size == SZ_MEDIUM && drop_rate >= 2)
+ drop_rate /= 2;
+ else if( md->special_state.size == SZ_BIG)
+ drop_rate *= 2;
+ }
+
+ if (src) {
+ //Drops affected by luk as a fixed increase [Valaris]
+ if (battle_config.drops_by_luk)
+ drop_rate += status_get_luk(src)*battle_config.drops_by_luk/100;
+ //Drops affected by luk as a % increase [Skotlex]
+ if (battle_config.drops_by_luk2)
+ drop_rate += (int)(0.5+drop_rate*status_get_luk(src)*battle_config.drops_by_luk2/10000.);
+ }
+ if (sd && battle_config.pk_mode &&
+ (int)(md->level - sd->status.base_level) >= 20)
+ drop_rate = (int)(drop_rate*1.25); // pk_mode increase drops if 20 level difference [Valaris]
+
+ // Increase drop rate if user has SC_ITEMBOOST
+ if (sd && sd->sc.data[SC_ITEMBOOST]) // now rig the drop rate to never be over 90% unless it is originally >90%.
+ drop_rate = max(drop_rate,cap_value((int)(0.5+drop_rate*(sd->sc.data[SC_ITEMBOOST]->val1)/100.),0,9000));
#ifdef RENEWAL_DROP
- if (drop_modifier != 100) {
- drop_rate = drop_rate * drop_modifier / 100;
- if (drop_rate < 1)
- drop_rate = 1;
- }
+ if( drop_modifier != 100 ) {
+ drop_rate = drop_rate * drop_modifier / 100;
+ if( drop_rate < 1 )
+ drop_rate = 1;
+ }
#endif
- // attempt to drop the item
- if (rnd() % 10000 >= drop_rate)
- continue;
-
- if (mvp_sd && it->type == IT_PETEGG) {
- pet_create_egg(mvp_sd, md->db->dropitem[i].nameid);
- continue;
- }
-
- ditem = mob_setdropitem(md->db->dropitem[i].nameid, 1);
-
- //A Rare Drop Global Announce by Lupus
- if (mvp_sd && drop_rate <= battle_config.rare_drop_announce) {
- char message[128];
- sprintf(message, msg_txt(541), mvp_sd->status.name, md->name, it->jname, (float)drop_rate/100);
- //MSG: "'%s' won %s's %s (chance: %0.02f%%)"
- intif_broadcast(message,strlen(message)+1,0);
- }
- // Announce first, or else ditem will be freed. [Lance]
- // By popular demand, use base drop rate for autoloot code. [Skotlex]
- mob_item_drop(md, dlist, ditem, 0, md->db->dropitem[i].p, homkillonly);
- }
-
- // Ore Discovery [Celest]
- if (sd == mvp_sd && pc_checkskill(sd,BS_FINDINGORE)>0 && battle_config.finding_ore_rate/10 >= rnd()%10000) {
- ditem = mob_setdropitem(itemdb_searchrandomid(IG_FINDINGORE), 1);
- mob_item_drop(md, dlist, ditem, 0, battle_config.finding_ore_rate/10, homkillonly);
- }
-
- if (sd) {
- // process script-granted extra drop bonuses
- int itemid = 0;
- for (i = 0; i < ARRAYLENGTH(sd->add_drop) && (sd->add_drop[i].id || sd->add_drop[i].group); i++) {
- if (sd->add_drop[i].race == -md->class_ ||
- (sd->add_drop[i].race > 0 && (
- sd->add_drop[i].race & (1<<status->race) ||
- sd->add_drop[i].race & (1<<(status->mode&MD_BOSS?RC_BOSS:RC_NONBOSS))
- ))) {
- //check if the bonus item drop rate should be multiplied with mob level/10 [Lupus]
- if (sd->add_drop[i].rate < 0) {
- //it's negative, then it should be multiplied. e.g. for Mimic,Myst Case Cards, etc
- // rate = base_rate * (mob_level/10) + 1
- drop_rate = -sd->add_drop[i].rate*(md->level/10)+1;
- drop_rate = cap_value(drop_rate, battle_config.item_drop_adddrop_min, battle_config.item_drop_adddrop_max);
- if (drop_rate > 10000) drop_rate = 10000;
- } else
- //it's positive, then it goes as it is
- drop_rate = sd->add_drop[i].rate;
-
- if (rnd()%10000 >= drop_rate)
- continue;
- itemid = (sd->add_drop[i].id > 0) ? sd->add_drop[i].id : itemdb_searchrandomid(sd->add_drop[i].group);
- mob_item_drop(md, dlist, mob_setdropitem(itemid,1), 0, drop_rate, homkillonly);
- }
- }
-
- // process script-granted zeny bonus (get_zeny_num) [Skotlex]
- if (sd->bonus.get_zeny_num && rnd()%100 < sd->bonus.get_zeny_rate) {
- i = sd->bonus.get_zeny_num > 0 ? sd->bonus.get_zeny_num : -md->level * sd->bonus.get_zeny_num;
- if (!i) i = 1;
- pc_getzeny(sd, 1+rnd()%i, LOG_TYPE_PICKDROP_MONSTER, NULL);
- }
- }
-
- // process items looted by the mob
- if (md->lootitem) {
- for (i = 0; i < md->lootitem_count; i++)
- mob_item_drop(md, dlist, mob_setlootitem(&md->lootitem[i]), 1, 10000, homkillonly);
- }
- if (dlist->item) //There are drop items.
- add_timer(tick + (!battle_config.delay_battle_damage?500:0), mob_delay_item_drop, 0, (intptr_t)dlist);
- else //No drops
- ers_free(item_drop_list_ers, dlist);
- } else if (md->lootitem && md->lootitem_count) { //Loot MUST drop!
- struct item_drop_list *dlist = ers_alloc(item_drop_list_ers, struct item_drop_list);
- dlist->m = md->bl.m;
- dlist->x = md->bl.x;
- dlist->y = md->bl.y;
- dlist->first_charid = (mvp_sd ? mvp_sd->status.char_id : 0);
- dlist->second_charid = (second_sd ? second_sd->status.char_id : 0);
- dlist->third_charid = (third_sd ? third_sd->status.char_id : 0);
- dlist->item = NULL;
- for (i = 0; i < md->lootitem_count; i++)
- mob_item_drop(md, dlist, mob_setlootitem(&md->lootitem[i]), 1, 10000, homkillonly);
- add_timer(tick + (!battle_config.delay_battle_damage?500:0), mob_delay_item_drop, 0, (intptr_t)dlist);
- }
-
- if (mvp_sd && md->db->mexp > 0 && !md->special_state.ai) {
- int log_mvp[2] = {0};
- unsigned int mexp;
- struct item item;
- double exp;
-
- //mapflag: noexp check [Lorky]
- if (map[m].flag.nobaseexp || type&2)
- exp =1;
- else {
- exp = md->db->mexp;
- if (count > 1)
- exp += exp*(battle_config.exp_bonus_attacker*(count-1))/100.; //[Gengar]
- }
-
- mexp = (unsigned int)cap_value(exp, 1, UINT_MAX);
-
- clif_mvp_effect(mvp_sd);
- clif_mvp_exp(mvp_sd,mexp);
- pc_gainexp(mvp_sd, &md->bl, mexp,0, false);
- log_mvp[1] = mexp;
-
- if (!(map[m].flag.nomvploot || type&1)) {
- /* pose them randomly in the list -- so on 100% drop servers it wont always drop the same item */
- int mdrop_id[MAX_MVP_DROP];
- int mdrop_p[MAX_MVP_DROP];
-
- memset(&mdrop_id,0,MAX_MVP_DROP*sizeof(int));
-
- for (i = 0; i < MAX_MVP_DROP; i++) {
- while (1) {
- int va = rand()%MAX_MVP_DROP;
- if (!mdrop_id[va] || !md->db->mvpitem[i].nameid) {
- mdrop_id[va] = md->db->mvpitem[i].nameid;
- mdrop_p[va] = md->db->mvpitem[i].p;
- break;
- }
- }
- }
-
- for (i = 0; i < MAX_MVP_DROP; i++) {
- if (mdrop_id[i] <= 0)
- continue;
- if (!itemdb_exists(mdrop_id[i]))
- continue;
-
- temp = mdrop_p[i];
- if (temp <= 0 && !battle_config.drop_rate0item)
- temp = 1;
- if (temp <= rnd()%10000+1) //if ==0, then it doesn't drop
- continue;
-
- memset(&item,0,sizeof(item));
- item.nameid=mdrop_id[i];
- item.identify= itemdb_isidentified(item.nameid);
- clif_mvp_item(mvp_sd,item.nameid);
- log_mvp[0] = item.nameid;
-
- //A Rare MVP Drop Global Announce by Lupus
- if (temp<=battle_config.rare_drop_announce) {
- struct item_data *i_data;
- char message[128];
- i_data = itemdb_exists(item.nameid);
- sprintf(message, msg_txt(541), mvp_sd->status.name, md->name, i_data->jname, temp/100.);
- //MSG: "'%s' won %s's %s (chance: %0.02f%%)"
- intif_broadcast(message,strlen(message)+1,0);
- }
-
- if ((temp = pc_additem(mvp_sd,&item,1,LOG_TYPE_PICKDROP_PLAYER)) != 0) {
- clif_additem(mvp_sd,0,0,temp);
- map_addflooritem(&item,1,mvp_sd->bl.m,mvp_sd->bl.x,mvp_sd->bl.y,mvp_sd->status.char_id,(second_sd?second_sd->status.char_id:0),(third_sd?third_sd->status.char_id:0),1);
- }
-
- //Logs items, MVP prizes [Lupus]
- log_pick_mob(md, LOG_TYPE_MVP, -1, &item);
- break;
- }
- }
-
- log_mvpdrop(mvp_sd, md->class_, log_mvp);
- }
-
- if (type&2 && !sd && md->class_ == MOBID_EMPERIUM)
- //Emperium destroyed by script. Discard mvp character. [Skotlex]
- mvp_sd = NULL;
-
- rebirth = (md->sc.data[SC_KAIZEL] || (md->sc.data[SC_REBIRTH] && !md->state.rebirth));
- if (!rebirth) { // Only trigger event on final kill
- md->status.hp = 0; //So that npc_event invoked functions KNOW that mob is dead
- if (src) {
- switch (src->type) {
- case BL_PET:
- sd = ((TBL_PET *)src)->msd;
- break;
- case BL_HOM:
- sd = ((TBL_HOM *)src)->master;
- break;
- case BL_MER:
- sd = ((TBL_MER *)src)->master;
- break;
- case BL_ELEM:
- sd = ((TBL_ELEM *)src)->master;
- break;
- }
- }
-
- if (sd) {
- if (sd->mission_mobid == md->class_) { //TK_MISSION [Skotlex]
- if (++sd->mission_count >= 100 && (temp = mob_get_random_id(0, 0xE, sd->status.base_level))) {
- pc_addfame(sd, 1);
- sd->mission_mobid = temp;
- pc_setglobalreg(sd,"TK_MISSION_ID", temp);
- sd->mission_count = 0;
- clif_mission_info(sd, temp, 0);
- }
- pc_setglobalreg(sd,"TK_MISSION_COUNT", sd->mission_count);
- }
-
- if (sd->status.party_id)
- map_foreachinrange(quest_update_objective_sub,&md->bl,AREA_SIZE,BL_PC,sd->status.party_id,md->class_);
- else if (sd->avail_quests)
- quest_update_objective(sd, md->class_);
-
- if (sd->md && src && src->type != BL_HOM && mob_db(md->class_)->lv > sd->status.base_level/2)
- mercenary_kills(sd->md);
- }
-
- if (md->npc_event[0] && !md->state.npc_killmonster) {
- if (sd && battle_config.mob_npc_event_type) {
- pc_setparam(sd, SP_KILLERRID, sd->bl.id);
- npc_event(sd,md->npc_event,0);
- } else if (mvp_sd) {
- pc_setparam(mvp_sd, SP_KILLERRID, sd?sd->bl.id:0);
- npc_event(mvp_sd,md->npc_event,0);
- } else
- npc_event_do(md->npc_event);
- } else if (mvp_sd && !md->state.npc_killmonster) {
- pc_setparam(mvp_sd, SP_KILLEDRID, md->class_);
- npc_script_event(mvp_sd, NPCE_KILLNPC); // PCKillNPC [Lance]
- }
-
- md->status.hp = 1;
- }
-
- if (md->deletetimer != INVALID_TIMER) {
- delete_timer(md->deletetimer,mob_timer_delete);
- md->deletetimer = INVALID_TIMER;
- }
- /**
- * Only loops if necessary (e.g. a poring would never need to loop)
- **/
- if (md->can_summon)
- mob_deleteslave(md);
-
- map_freeblock_unlock();
-
- if (!rebirth) {
-
- if (pcdb_checkid(md->vd->class_)) { //Player mobs are not removed automatically by the client.
- /* first we set them dead, then we delay the outsight effect */
- clif_clearunit_area(&md->bl,CLR_DEAD);
- clif_clearunit_delayed(&md->bl, CLR_OUTSIGHT,tick+3000);
- } else
- /**
- * We give the client some time to breath and this allows it to display anything it'd like with the dead corpose
- * For example, this delay allows it to display soul drain effect
- **/
- clif_clearunit_delayed(&md->bl, CLR_DEAD, tick+250);
-
- }
-
- if (!md->spawn) //Tell status_damage to remove it from memory.
- return 5; // Note: Actually, it's 4. Oh well...
-
- // MvP tomb [GreenBox]
- if (battle_config.mvp_tomb_enabled && md->spawn->state.boss)
- mvptomb_create(md, mvp_sd ? mvp_sd->status.name : NULL, time(NULL));
-
- if (!rebirth)
- mob_setdelayspawn(md); //Set respawning.
- return 3; //Remove from map.
+ // attempt to drop the item
+ if (rnd() % 10000 >= drop_rate)
+ continue;
+
+ if( mvp_sd && it->type == IT_PETEGG ) {
+ pet_create_egg(mvp_sd, md->db->dropitem[i].nameid);
+ continue;
+ }
+
+ ditem = mob_setdropitem(md->db->dropitem[i].nameid, 1);
+
+ //A Rare Drop Global Announce by Lupus
+ if( mvp_sd && drop_rate <= battle_config.rare_drop_announce ) {
+ char message[128];
+ sprintf (message, msg_txt(541), mvp_sd->status.name, md->name, it->jname, (float)drop_rate/100);
+ //MSG: "'%s' won %s's %s (chance: %0.02f%%)"
+ intif_broadcast(message,strlen(message)+1,0);
+ }
+ // Announce first, or else ditem will be freed. [Lance]
+ // By popular demand, use base drop rate for autoloot code. [Skotlex]
+ mob_item_drop(md, dlist, ditem, 0, md->db->dropitem[i].p, homkillonly);
+ }
+
+ // Ore Discovery [Celest]
+ if (sd == mvp_sd && pc_checkskill(sd,BS_FINDINGORE)>0 && battle_config.finding_ore_rate/10 >= rnd()%10000) {
+ ditem = mob_setdropitem(itemdb_searchrandomid(IG_FINDINGORE), 1);
+ mob_item_drop(md, dlist, ditem, 0, battle_config.finding_ore_rate/10, homkillonly);
+ }
+
+ if(sd) {
+ // process script-granted extra drop bonuses
+ int itemid = 0;
+ for (i = 0; i < ARRAYLENGTH(sd->add_drop) && (sd->add_drop[i].id || sd->add_drop[i].group); i++)
+ {
+ if ( sd->add_drop[i].race == -md->class_ ||
+ ( sd->add_drop[i].race > 0 && (
+ sd->add_drop[i].race & (1<<status->race) ||
+ sd->add_drop[i].race & (1<<(status->mode&MD_BOSS?RC_BOSS:RC_NONBOSS))
+ )))
+ {
+ //check if the bonus item drop rate should be multiplied with mob level/10 [Lupus]
+ if(sd->add_drop[i].rate < 0) {
+ //it's negative, then it should be multiplied. e.g. for Mimic,Myst Case Cards, etc
+ // rate = base_rate * (mob_level/10) + 1
+ drop_rate = -sd->add_drop[i].rate*(md->level/10)+1;
+ drop_rate = cap_value(drop_rate, battle_config.item_drop_adddrop_min, battle_config.item_drop_adddrop_max);
+ if (drop_rate > 10000) drop_rate = 10000;
+ }
+ else
+ //it's positive, then it goes as it is
+ drop_rate = sd->add_drop[i].rate;
+
+ if (rnd()%10000 >= drop_rate)
+ continue;
+ itemid = (sd->add_drop[i].id > 0) ? sd->add_drop[i].id : itemdb_searchrandomid(sd->add_drop[i].group);
+ mob_item_drop(md, dlist, mob_setdropitem(itemid,1), 0, drop_rate, homkillonly);
+ }
+ }
+
+ // process script-granted zeny bonus (get_zeny_num) [Skotlex]
+ if( sd->bonus.get_zeny_num && rnd()%100 < sd->bonus.get_zeny_rate ) {
+ i = sd->bonus.get_zeny_num > 0 ? sd->bonus.get_zeny_num : -md->level * sd->bonus.get_zeny_num;
+ if (!i) i = 1;
+ pc_getzeny(sd, 1+rnd()%i, LOG_TYPE_PICKDROP_MONSTER, NULL);
+ }
+ }
+
+ // process items looted by the mob
+ if(md->lootitem) {
+ for(i = 0; i < md->lootitem_count; i++)
+ mob_item_drop(md, dlist, mob_setlootitem(&md->lootitem[i]), 1, 10000, homkillonly);
+ }
+ if (dlist->item) //There are drop items.
+ add_timer(tick + (!battle_config.delay_battle_damage?500:0), mob_delay_item_drop, 0, (intptr_t)dlist);
+ else //No drops
+ ers_free(item_drop_list_ers, dlist);
+ } else if (md->lootitem && md->lootitem_count) { //Loot MUST drop!
+ struct item_drop_list *dlist = ers_alloc(item_drop_list_ers, struct item_drop_list);
+ dlist->m = md->bl.m;
+ dlist->x = md->bl.x;
+ dlist->y = md->bl.y;
+ dlist->first_charid = (mvp_sd ? mvp_sd->status.char_id : 0);
+ dlist->second_charid = (second_sd ? second_sd->status.char_id : 0);
+ dlist->third_charid = (third_sd ? third_sd->status.char_id : 0);
+ dlist->item = NULL;
+ for(i = 0; i < md->lootitem_count; i++)
+ mob_item_drop(md, dlist, mob_setlootitem(&md->lootitem[i]), 1, 10000, homkillonly);
+ add_timer(tick + (!battle_config.delay_battle_damage?500:0), mob_delay_item_drop, 0, (intptr_t)dlist);
+ }
+
+ if(mvp_sd && md->db->mexp > 0 && !md->special_state.ai) {
+ int log_mvp[2] = {0};
+ unsigned int mexp;
+ struct item item;
+ double exp;
+
+ //mapflag: noexp check [Lorky]
+ if (map[m].flag.nobaseexp || type&2)
+ exp =1;
+ else {
+ exp = md->db->mexp;
+ if (count > 1)
+ exp += exp*(battle_config.exp_bonus_attacker*(count-1))/100.; //[Gengar]
+ }
+
+ mexp = (unsigned int)cap_value(exp, 1, UINT_MAX);
+
+ clif_mvp_effect(mvp_sd);
+ clif_mvp_exp(mvp_sd,mexp);
+ pc_gainexp(mvp_sd, &md->bl, mexp,0, false);
+ log_mvp[1] = mexp;
+
+ if( !(map[m].flag.nomvploot || type&1) ) {
+ /* pose them randomly in the list -- so on 100% drop servers it wont always drop the same item */
+ int mdrop_id[MAX_MVP_DROP];
+ int mdrop_p[MAX_MVP_DROP];
+
+ memset(&mdrop_id,0,MAX_MVP_DROP*sizeof(int));
+
+ for(i = 0; i < MAX_MVP_DROP; i++) {
+ while( 1 ) {
+ int va = rand()%MAX_MVP_DROP;
+ if( !mdrop_id[va] || !md->db->mvpitem[i].nameid ) {
+ mdrop_id[va] = md->db->mvpitem[i].nameid;
+ mdrop_p[va] = md->db->mvpitem[i].p;
+ break;
+ }
+ }
+ }
+
+ for(i = 0; i < MAX_MVP_DROP; i++) {
+ if(mdrop_id[i] <= 0)
+ continue;
+ if(!itemdb_exists(mdrop_id[i]))
+ continue;
+
+ temp = mdrop_p[i];
+ if(temp <= 0 && !battle_config.drop_rate0item)
+ temp = 1;
+ if(temp <= rnd()%10000+1) //if ==0, then it doesn't drop
+ continue;
+
+ memset(&item,0,sizeof(item));
+ item.nameid=mdrop_id[i];
+ item.identify= itemdb_isidentified(item.nameid);
+ clif_mvp_item(mvp_sd,item.nameid);
+ log_mvp[0] = item.nameid;
+
+ //A Rare MVP Drop Global Announce by Lupus
+ if(temp<=battle_config.rare_drop_announce) {
+ struct item_data *i_data;
+ char message[128];
+ i_data = itemdb_exists(item.nameid);
+ sprintf (message, msg_txt(541), mvp_sd->status.name, md->name, i_data->jname, temp/100.);
+ //MSG: "'%s' won %s's %s (chance: %0.02f%%)"
+ intif_broadcast(message,strlen(message)+1,0);
+ }
+
+ if((temp = pc_additem(mvp_sd,&item,1,LOG_TYPE_PICKDROP_PLAYER)) != 0) {
+ clif_additem(mvp_sd,0,0,temp);
+ map_addflooritem(&item,1,mvp_sd->bl.m,mvp_sd->bl.x,mvp_sd->bl.y,mvp_sd->status.char_id,(second_sd?second_sd->status.char_id:0),(third_sd?third_sd->status.char_id:0),1);
+ }
+
+ //Logs items, MVP prizes [Lupus]
+ log_pick_mob(md, LOG_TYPE_MVP, -1, &item);
+ break;
+ }
+ }
+
+ log_mvpdrop(mvp_sd, md->class_, log_mvp);
+ }
+
+ if (type&2 && !sd && md->class_ == MOBID_EMPERIUM)
+ //Emperium destroyed by script. Discard mvp character. [Skotlex]
+ mvp_sd = NULL;
+
+ rebirth = ( md->sc.data[SC_KAIZEL] || (md->sc.data[SC_REBIRTH] && !md->state.rebirth) );
+ if( !rebirth ) { // Only trigger event on final kill
+ md->status.hp = 0; //So that npc_event invoked functions KNOW that mob is dead
+ if( src ) {
+ switch( src->type ) {
+ case BL_PET: sd = ((TBL_PET*)src)->msd; break;
+ case BL_HOM: sd = ((TBL_HOM*)src)->master; break;
+ case BL_MER: sd = ((TBL_MER*)src)->master; break;
+ case BL_ELEM: sd = ((TBL_ELEM*)src)->master; break;
+ }
+ }
+
+ if( sd ) {
+ if( sd->mission_mobid == md->class_) { //TK_MISSION [Skotlex]
+ if( ++sd->mission_count >= 100 && (temp = mob_get_random_id(0, 0xE, sd->status.base_level)) ) {
+ pc_addfame(sd, 1);
+ sd->mission_mobid = temp;
+ pc_setglobalreg(sd,"TK_MISSION_ID", temp);
+ sd->mission_count = 0;
+ clif_mission_info(sd, temp, 0);
+ }
+ pc_setglobalreg(sd,"TK_MISSION_COUNT", sd->mission_count);
+ }
+
+ if( sd->status.party_id )
+ map_foreachinrange(quest_update_objective_sub,&md->bl,AREA_SIZE,BL_PC,sd->status.party_id,md->class_);
+ else if( sd->avail_quests )
+ quest_update_objective(sd, md->class_);
+
+ if( sd->md && src && src->type != BL_HOM && mob_db(md->class_)->lv > sd->status.base_level/2 )
+ mercenary_kills(sd->md);
+ }
+
+ if( md->npc_event[0] && !md->state.npc_killmonster ) {
+ if( sd && battle_config.mob_npc_event_type ) {
+ pc_setparam(sd, SP_KILLERRID, sd->bl.id);
+ npc_event(sd,md->npc_event,0);
+ } else if( mvp_sd ) {
+ pc_setparam(mvp_sd, SP_KILLERRID, sd?sd->bl.id:0);
+ npc_event(mvp_sd,md->npc_event,0);
+ } else
+ npc_event_do(md->npc_event);
+ } else if( mvp_sd && !md->state.npc_killmonster ) {
+ pc_setparam(mvp_sd, SP_KILLEDRID, md->class_);
+ npc_script_event(mvp_sd, NPCE_KILLNPC); // PCKillNPC [Lance]
+ }
+
+ md->status.hp = 1;
+ }
+
+ if(md->deletetimer != INVALID_TIMER) {
+ delete_timer(md->deletetimer,mob_timer_delete);
+ md->deletetimer = INVALID_TIMER;
+ }
+ /**
+ * Only loops if necessary (e.g. a poring would never need to loop)
+ **/
+ if( md->can_summon )
+ mob_deleteslave(md);
+
+ map_freeblock_unlock();
+
+ if( !rebirth ) {
+
+ if( pcdb_checkid(md->vd->class_) ) {//Player mobs are not removed automatically by the client.
+ /* first we set them dead, then we delay the outsight effect */
+ clif_clearunit_area(&md->bl,CLR_DEAD);
+ clif_clearunit_delayed(&md->bl, CLR_OUTSIGHT,tick+3000);
+ } else
+ /**
+ * We give the client some time to breath and this allows it to display anything it'd like with the dead corpose
+ * For example, this delay allows it to display soul drain effect
+ **/
+ clif_clearunit_delayed(&md->bl, CLR_DEAD, tick+250);
+
+ }
+
+ if(!md->spawn) //Tell status_damage to remove it from memory.
+ return 5; // Note: Actually, it's 4. Oh well...
+
+ // MvP tomb [GreenBox]
+ if (battle_config.mvp_tomb_enabled && md->spawn->state.boss)
+ mvptomb_create(md, mvp_sd ? mvp_sd->status.name : NULL, time(NULL));
+
+ if( !rebirth )
+ mob_setdelayspawn(md); //Set respawning.
+ return 3; //Remove from map.
}
void mob_revive(struct mob_data *md, unsigned int hp)
{
- unsigned int tick = gettick();
- md->state.skillstate = MSS_IDLE;
- md->last_thinktime = tick;
- md->next_walktime = tick+rnd()%50+5000;
- md->last_linktime = tick;
- md->last_pcneartime = 0;
- memset(md->dmglog, 0, sizeof(md->dmglog)); // Reset the damage done on the rebirthed monster, otherwise will grant full exp + damage done. [Valaris]
- md->tdmg = 0;
- if (!md->bl.prev)
- map_addblock(&md->bl);
- clif_spawn(&md->bl);
- skill_unit_move(&md->bl,tick,1);
- mobskill_use(md, tick, MSC_SPAWN);
- if (battle_config.show_mob_info&3)
- clif_charnameack(0, &md->bl);
+ unsigned int tick = gettick();
+ md->state.skillstate = MSS_IDLE;
+ md->last_thinktime = tick;
+ md->next_walktime = tick+rnd()%50+5000;
+ md->last_linktime = tick;
+ md->last_pcneartime = 0;
+ memset(md->dmglog, 0, sizeof(md->dmglog)); // Reset the damage done on the rebirthed monster, otherwise will grant full exp + damage done. [Valaris]
+ md->tdmg = 0;
+ if (!md->bl.prev)
+ map_addblock(&md->bl);
+ clif_spawn(&md->bl);
+ skill_unit_move(&md->bl,tick,1);
+ mobskill_use(md, tick, MSC_SPAWN);
+ if (battle_config.show_mob_info&3)
+ clif_charnameack (0, &md->bl);
}
int mob_guardian_guildchange(struct mob_data *md)
{
- struct guild *g;
- nullpo_ret(md);
-
- if (!md->guardian_data)
- return 0;
-
- if (md->guardian_data->castle->guild_id == 0) {
- //Castle with no owner? Delete the guardians.
- if (md->class_ == MOBID_EMPERIUM) {
- //But don't delete the emperium, just clear it's guild-data
- md->guardian_data->guild_id = 0;
- md->guardian_data->emblem_id = 0;
- md->guardian_data->guild_name[0] = '\0';
- } else {
- if (md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS && md->guardian_data->castle->guardian[md->guardian_data->number].visible)
- guild_castledatasave(md->guardian_data->castle->castle_id, 10+md->guardian_data->number, 0);
- unit_free(&md->bl,CLR_OUTSIGHT); //Remove guardian.
- }
- return 0;
- }
-
- g = guild_search(md->guardian_data->castle->guild_id);
- if (g == NULL) {
- //Properly remove guardian info from Castle data.
- ShowError("mob_guardian_guildchange: New Guild (id %d) does not exists!\n", md->guardian_data->guild_id);
- if (md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS)
- guild_castledatasave(md->guardian_data->castle->castle_id, 10+md->guardian_data->number, 0);
- unit_free(&md->bl,CLR_OUTSIGHT);
- return 0;
- }
-
- md->guardian_data->guild_id = g->guild_id;
- md->guardian_data->emblem_id = g->emblem_id;
- md->guardian_data->guardup_lv = guild_checkskill(g,GD_GUARDUP);
- memcpy(md->guardian_data->guild_name, g->name, NAME_LENGTH);
-
- return 1;
+ struct guild *g;
+ nullpo_ret(md);
+
+ if (!md->guardian_data)
+ return 0;
+
+ if (md->guardian_data->castle->guild_id == 0)
+ { //Castle with no owner? Delete the guardians.
+ if (md->class_ == MOBID_EMPERIUM)
+ { //But don't delete the emperium, just clear it's guild-data
+ md->guardian_data->guild_id = 0;
+ md->guardian_data->emblem_id = 0;
+ md->guardian_data->guild_name[0] = '\0';
+ } else {
+ if (md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS && md->guardian_data->castle->guardian[md->guardian_data->number].visible)
+ guild_castledatasave(md->guardian_data->castle->castle_id, 10+md->guardian_data->number, 0);
+ unit_free(&md->bl,CLR_OUTSIGHT); //Remove guardian.
+ }
+ return 0;
+ }
+
+ g = guild_search(md->guardian_data->castle->guild_id);
+ if (g == NULL)
+ { //Properly remove guardian info from Castle data.
+ ShowError("mob_guardian_guildchange: New Guild (id %d) does not exists!\n", md->guardian_data->guild_id);
+ if (md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS)
+ guild_castledatasave(md->guardian_data->castle->castle_id, 10+md->guardian_data->number, 0);
+ unit_free(&md->bl,CLR_OUTSIGHT);
+ return 0;
+ }
+
+ md->guardian_data->guild_id = g->guild_id;
+ md->guardian_data->emblem_id = g->emblem_id;
+ md->guardian_data->guardup_lv = guild_checkskill(g,GD_GUARDUP);
+ memcpy(md->guardian_data->guild_name, g->name, NAME_LENGTH);
+
+ return 1;
}
/*==========================================
* Pick a random class for the mob
*------------------------------------------*/
-int mob_random_class(int *value, size_t count)
+int mob_random_class (int *value, size_t count)
{
- nullpo_ret(value);
-
- // no count specified, look into the array manually, but take only max 5 elements
- if (count < 1) {
- count = 0;
- while (count < 5 && mobdb_checkid(value[count])) count++;
- if (count < 1) // nothing found
- return 0;
- } else {
- // check if at least the first value is valid
- if (mobdb_checkid(value[0]) == 0)
- return 0;
- }
- //Pick a random value, hoping it exists. [Skotlex]
- return mobdb_checkid(value[rnd()%count]);
+ nullpo_ret(value);
+
+ // no count specified, look into the array manually, but take only max 5 elements
+ if (count < 1) {
+ count = 0;
+ while(count < 5 && mobdb_checkid(value[count])) count++;
+ if(count < 1) // nothing found
+ return 0;
+ } else {
+ // check if at least the first value is valid
+ if(mobdb_checkid(value[0]) == 0)
+ return 0;
+ }
+ //Pick a random value, hoping it exists. [Skotlex]
+ return mobdb_checkid(value[rnd()%count]);
}
/*==========================================
* Change mob base class
*------------------------------------------*/
-int mob_class_change(struct mob_data *md, int class_)
+int mob_class_change (struct mob_data *md, int class_)
{
- unsigned int tick = gettick();
- int i, c, hp_rate;
-
- nullpo_ret(md);
-
- if (md->bl.prev == NULL)
- return 0;
-
- //Disable class changing for some targets...
- if (md->guardian_data)
- return 0; //Guardians/Emperium
-
- if (mob_is_treasure(md))
- return 0; //Treasure Boxes
-
- if (md->special_state.ai > 1)
- return 0; //Marine Spheres and Floras.
-
- if (mob_is_clone(md->class_))
- return 0; //Clones
-
- if (md->class_ == class_)
- return 0; //Nothing to change.
-
- hp_rate = get_percentage(md->status.hp, md->status.max_hp);
- md->class_ = class_;
- md->db = mob_db(class_);
- if (battle_config.override_mob_names==1)
- memcpy(md->name,md->db->name,NAME_LENGTH);
- else
- memcpy(md->name,md->db->jname,NAME_LENGTH);
-
- mob_stop_attack(md);
- mob_stop_walking(md, 0);
- unit_skillcastcancel(&md->bl, 0);
- status_set_viewdata(&md->bl, class_);
- clif_mob_class_change(md,md->vd->class_);
- status_calc_mob(md, 1);
- md->ud.state.speed_changed = 1; //Speed change update.
-
- if (battle_config.monster_class_change_recover) {
- memset(md->dmglog, 0, sizeof(md->dmglog));
- md->tdmg = 0;
- } else {
- md->status.hp = md->status.max_hp*hp_rate/100;
- if (md->status.hp < 1) md->status.hp = 1;
- }
-
- for (i=0,c=tick-MOB_MAX_DELAY; i<MAX_MOBSKILL; i++)
- md->skilldelay[i] = c;
-
- if (md->lootitem == NULL && md->db->status.mode&MD_LOOTER)
- md->lootitem=(struct item *)aCalloc(LOOTITEM_SIZE,sizeof(struct item));
-
- //Targets should be cleared no morph
- md->target_id = md->attacked_id = 0;
-
- //Need to update name display.
- clif_charnameack(0, &md->bl);
- status_change_end(&md->bl,SC_KEEPING,INVALID_TIMER);
- return 0;
+ unsigned int tick = gettick();
+ int i, c, hp_rate;
+
+ nullpo_ret(md);
+
+ if( md->bl.prev == NULL )
+ return 0;
+
+ //Disable class changing for some targets...
+ if (md->guardian_data)
+ return 0; //Guardians/Emperium
+
+ if( mob_is_treasure(md) )
+ return 0; //Treasure Boxes
+
+ if( md->special_state.ai > 1 )
+ return 0; //Marine Spheres and Floras.
+
+ if( mob_is_clone(md->class_) )
+ return 0; //Clones
+
+ if( md->class_ == class_ )
+ return 0; //Nothing to change.
+
+ hp_rate = get_percentage(md->status.hp, md->status.max_hp);
+ md->class_ = class_;
+ md->db = mob_db(class_);
+ if (battle_config.override_mob_names==1)
+ memcpy(md->name,md->db->name,NAME_LENGTH);
+ else
+ memcpy(md->name,md->db->jname,NAME_LENGTH);
+
+ mob_stop_attack(md);
+ mob_stop_walking(md, 0);
+ unit_skillcastcancel(&md->bl, 0);
+ status_set_viewdata(&md->bl, class_);
+ clif_mob_class_change(md,md->vd->class_);
+ status_calc_mob(md, 1);
+ md->ud.state.speed_changed = 1; //Speed change update.
+
+ if (battle_config.monster_class_change_recover) {
+ memset(md->dmglog, 0, sizeof(md->dmglog));
+ md->tdmg = 0;
+ } else {
+ md->status.hp = md->status.max_hp*hp_rate/100;
+ if(md->status.hp < 1) md->status.hp = 1;
+ }
+
+ for(i=0,c=tick-MOB_MAX_DELAY;i<MAX_MOBSKILL;i++)
+ md->skilldelay[i] = c;
+
+ if(md->lootitem == NULL && md->db->status.mode&MD_LOOTER)
+ md->lootitem=(struct item *)aCalloc(LOOTITEM_SIZE,sizeof(struct item));
+
+ //Targets should be cleared no morph
+ md->target_id = md->attacked_id = 0;
+
+ //Need to update name display.
+ clif_charnameack(0, &md->bl);
+ status_change_end(&md->bl,SC_KEEPING,INVALID_TIMER);
+ return 0;
}
/*==========================================
@@ -2734,8 +2795,8 @@ int mob_class_change(struct mob_data *md, int class_)
*------------------------------------------*/
void mob_heal(struct mob_data *md,unsigned int heal)
{
- if (battle_config.show_mob_info&3)
- clif_charnameack(0, &md->bl);
+ if (battle_config.show_mob_info&3)
+ clif_charnameack (0, &md->bl);
}
/*==========================================
@@ -2743,18 +2804,18 @@ void mob_heal(struct mob_data *md,unsigned int heal)
*------------------------------------------*/
int mob_warpslave_sub(struct block_list *bl,va_list ap)
{
- struct mob_data *md=(struct mob_data *)bl;
- struct block_list *master;
- short x,y,range=0;
- master = va_arg(ap, struct block_list *);
- range = va_arg(ap, int);
-
- if (md->master_id!=master->id)
- return 0;
-
- map_search_freecell(master, 0, &x, &y, range, range, 0);
- unit_warp(&md->bl, master->m, x, y,CLR_RESPAWN);
- return 1;
+ struct mob_data *md=(struct mob_data *)bl;
+ struct block_list *master;
+ short x,y,range=0;
+ master = va_arg(ap, struct block_list*);
+ range = va_arg(ap, int);
+
+ if(md->master_id!=master->id)
+ return 0;
+
+ map_search_freecell(master, 0, &x, &y, range, range, 0);
+ unit_warp(&md->bl, master->m, x, y,CLR_RESPAWN);
+ return 1;
}
/*==========================================
@@ -2764,10 +2825,10 @@ int mob_warpslave_sub(struct block_list *bl,va_list ap)
*------------------------------------------*/
int mob_warpslave(struct block_list *bl, int range)
{
- if (range < 1)
- range = 1; //Min range needed to avoid crashes and stuff. [Skotlex]
+ if (range < 1)
+ range = 1; //Min range needed to avoid crashes and stuff. [Skotlex]
- return map_foreachinmap(mob_warpslave_sub, bl->m, BL_MOB, bl, range);
+ return map_foreachinmap(mob_warpslave_sub, bl->m, BL_MOB, bl, range);
}
/*==========================================
@@ -2775,14 +2836,14 @@ int mob_warpslave(struct block_list *bl, int range)
*------------------------------------------*/
int mob_countslave_sub(struct block_list *bl,va_list ap)
{
- int id;
- struct mob_data *md;
- id=va_arg(ap,int);
-
- md = (struct mob_data *)bl;
- if (md->master_id==id)
- return 1;
- return 0;
+ int id;
+ struct mob_data *md;
+ id=va_arg(ap,int);
+
+ md = (struct mob_data *)bl;
+ if( md->master_id==id )
+ return 1;
+ return 0;
}
/*==========================================
@@ -2790,7 +2851,7 @@ int mob_countslave_sub(struct block_list *bl,va_list ap)
*------------------------------------------*/
int mob_countslave(struct block_list *bl)
{
- return map_foreachinmap(mob_countslave_sub, bl->m, BL_MOB,bl->id);
+ return map_foreachinmap(mob_countslave_sub, bl->m, BL_MOB,bl->id);
}
/*==========================================
@@ -2798,96 +2859,97 @@ int mob_countslave(struct block_list *bl)
*------------------------------------------*/
int mob_summonslave(struct mob_data *md2,int *value,int amount,int skill_id)
{
- struct mob_data *md;
- struct spawn_data data;
- int count = 0,k=0,hp_rate=0;
-
- nullpo_ret(md2);
- nullpo_ret(value);
-
- memset(&data, 0, sizeof(struct spawn_data));
- data.m = md2->bl.m;
- data.x = md2->bl.x;
- data.y = md2->bl.y;
- data.num = 1;
- data.state.size = md2->special_state.size;
- data.state.ai = md2->special_state.ai;
-
- if (mobdb_checkid(value[0]) == 0)
- return 0;
- /**
- * Flags this monster is able to summon; saves a worth amount of memory upon deletion
- **/
- md2->can_summon = 1;
-
- while (count < 5 && mobdb_checkid(value[count])) count++;
- if (count < 1) return 0;
- if (amount > 0 && amount < count) { //Do not start on 0, pick some random sub subset [Skotlex]
- k = rnd()%count;
- amount+=k; //Increase final value by same amount to preserve total number to summon.
- }
-
- if (!battle_config.monster_class_change_recover &&
- (skill_id == NPC_TRANSFORMATION || skill_id == NPC_METAMORPHOSIS))
- hp_rate = get_percentage(md2->status.hp, md2->status.max_hp);
-
- for (; k<amount; k++) {
- short x,y;
- data.class_ = value[k%count]; //Summon slaves in round-robin fashion. [Skotlex]
- if (mobdb_checkid(data.class_) == 0)
- continue;
-
- if (map_search_freecell(&md2->bl, 0, &x, &y, MOB_SLAVEDISTANCE, MOB_SLAVEDISTANCE, 0)) {
- data.x = x;
- data.y = y;
- } else {
- data.x = md2->bl.x;
- data.y = md2->bl.y;
- }
-
- //These two need to be loaded from the db for each slave.
- if (battle_config.override_mob_names==1)
- strcpy(data.name,"--en--");
- else
- strcpy(data.name,"--ja--");
-
- if (!mob_parse_dataset(&data))
- continue;
-
- md= mob_spawn_dataset(&data);
- if (skill_id == NPC_SUMMONSLAVE) {
- md->master_id=md2->bl.id;
- md->special_state.ai = md2->special_state.ai;
- }
- mob_spawn(md);
-
- if (hp_rate) //Scale HP
- md->status.hp = md->status.max_hp*hp_rate/100;
-
- //Inherit the aggressive mode of the master.
- if (battle_config.slaves_inherit_mode && md->master_id) {
- switch (battle_config.slaves_inherit_mode) {
- case 1: //Always aggressive
- if (!(md->status.mode&MD_AGGRESSIVE))
- sc_start4(&md->bl, SC_MODECHANGE, 100,1,0, MD_AGGRESSIVE, 0, 0);
- break;
- case 2: //Always passive
- if (md->status.mode&MD_AGGRESSIVE)
- sc_start4(&md->bl, SC_MODECHANGE, 100,1,0, 0, MD_AGGRESSIVE, 0);
- break;
- default: //Copy master.
- if (md2->status.mode&MD_AGGRESSIVE)
- sc_start4(&md->bl, SC_MODECHANGE, 100,1,0, MD_AGGRESSIVE, 0, 0);
- else
- sc_start4(&md->bl, SC_MODECHANGE, 100,1,0, 0, MD_AGGRESSIVE, 0);
- break;
- }
- }
-
- clif_skill_nodamage(&md->bl,&md->bl,skill_id,amount,1);
- }
-
- return 0;
+ struct mob_data *md;
+ struct spawn_data data;
+ int count = 0,k=0,hp_rate=0;
+
+ nullpo_ret(md2);
+ nullpo_ret(value);
+
+ memset(&data, 0, sizeof(struct spawn_data));
+ data.m = md2->bl.m;
+ data.x = md2->bl.x;
+ data.y = md2->bl.y;
+ data.num = 1;
+ data.state.size = md2->special_state.size;
+ data.state.ai = md2->special_state.ai;
+
+ if(mobdb_checkid(value[0]) == 0)
+ return 0;
+ /**
+ * Flags this monster is able to summon; saves a worth amount of memory upon deletion
+ **/
+ md2->can_summon = 1;
+
+ while(count < 5 && mobdb_checkid(value[count])) count++;
+ if(count < 1) return 0;
+ if (amount > 0 && amount < count) { //Do not start on 0, pick some random sub subset [Skotlex]
+ k = rnd()%count;
+ amount+=k; //Increase final value by same amount to preserve total number to summon.
+ }
+
+ if (!battle_config.monster_class_change_recover &&
+ (skill_id == NPC_TRANSFORMATION || skill_id == NPC_METAMORPHOSIS))
+ hp_rate = get_percentage(md2->status.hp, md2->status.max_hp);
+
+ for(;k<amount;k++) {
+ short x,y;
+ data.class_ = value[k%count]; //Summon slaves in round-robin fashion. [Skotlex]
+ if (mobdb_checkid(data.class_) == 0)
+ continue;
+
+ if (map_search_freecell(&md2->bl, 0, &x, &y, MOB_SLAVEDISTANCE, MOB_SLAVEDISTANCE, 0)) {
+ data.x = x;
+ data.y = y;
+ } else {
+ data.x = md2->bl.x;
+ data.y = md2->bl.y;
+ }
+
+ //These two need to be loaded from the db for each slave.
+ if(battle_config.override_mob_names==1)
+ strcpy(data.name,"--en--");
+ else
+ strcpy(data.name,"--ja--");
+
+ if (!mob_parse_dataset(&data))
+ continue;
+
+ md= mob_spawn_dataset(&data);
+ if(skill_id == NPC_SUMMONSLAVE){
+ md->master_id=md2->bl.id;
+ md->special_state.ai = md2->special_state.ai;
+ }
+ mob_spawn(md);
+
+ if (hp_rate) //Scale HP
+ md->status.hp = md->status.max_hp*hp_rate/100;
+
+ //Inherit the aggressive mode of the master.
+ if (battle_config.slaves_inherit_mode && md->master_id)
+ {
+ switch (battle_config.slaves_inherit_mode) {
+ case 1: //Always aggressive
+ if (!(md->status.mode&MD_AGGRESSIVE))
+ sc_start4(&md->bl, SC_MODECHANGE, 100,1,0, MD_AGGRESSIVE, 0, 0);
+ break;
+ case 2: //Always passive
+ if (md->status.mode&MD_AGGRESSIVE)
+ sc_start4(&md->bl, SC_MODECHANGE, 100,1,0, 0, MD_AGGRESSIVE, 0);
+ break;
+ default: //Copy master.
+ if (md2->status.mode&MD_AGGRESSIVE)
+ sc_start4(&md->bl, SC_MODECHANGE, 100,1,0, MD_AGGRESSIVE, 0, 0);
+ else
+ sc_start4(&md->bl, SC_MODECHANGE, 100,1,0, 0, MD_AGGRESSIVE, 0);
+ break;
+ }
+ }
+
+ clif_skill_nodamage(&md->bl,&md->bl,skill_id,amount,1);
+ }
+
+ return 0;
}
/*==========================================
@@ -2896,14 +2958,14 @@ int mob_summonslave(struct mob_data *md2,int *value,int amount,int skill_id)
*------------------------------------------*/
int mob_skillid2skillidx(int class_,int skillid)
{
- int i, max = mob_db(class_)->maxskill;
- struct mob_skill *ms=mob_db(class_)->skill;
+ int i, max = mob_db(class_)->maxskill;
+ struct mob_skill *ms=mob_db(class_)->skill;
- if (ms==NULL)
- return -1;
+ if(ms==NULL)
+ return -1;
- ARR_FIND(0, max, i, ms[i].skill_id == skillid);
- return (i < max) ? i : -1;
+ ARR_FIND( 0, max, i, ms[i].skill_id == skillid );
+ return ( i < max ) ? i : -1;
}
/*==========================================
@@ -2911,95 +2973,99 @@ int mob_skillid2skillidx(int class_,int skillid)
*------------------------------------------*/
int mob_getfriendhprate_sub(struct block_list *bl,va_list ap)
{
- int min_rate, max_rate,rate;
- struct block_list **fr;
- struct mob_data *md;
+ int min_rate, max_rate,rate;
+ struct block_list **fr;
+ struct mob_data *md;
- md = va_arg(ap,struct mob_data *);
- min_rate=va_arg(ap,int);
- max_rate=va_arg(ap,int);
- fr=va_arg(ap,struct block_list **);
+ md = va_arg(ap,struct mob_data *);
+ min_rate=va_arg(ap,int);
+ max_rate=va_arg(ap,int);
+ fr=va_arg(ap,struct block_list **);
- if (md->bl.id == bl->id && !(battle_config.mob_ai&0x10))
- return 0;
+ if( md->bl.id == bl->id && !(battle_config.mob_ai&0x10))
+ return 0;
- if ((*fr) != NULL) //A friend was already found.
- return 0;
+ if ((*fr) != NULL) //A friend was already found.
+ return 0;
- if (battle_check_target(&md->bl,bl,BCT_ENEMY)>0)
- return 0;
+ if (battle_check_target(&md->bl,bl,BCT_ENEMY)>0)
+ return 0;
- rate = get_percentage(status_get_hp(bl), status_get_max_hp(bl));
+ rate = get_percentage(status_get_hp(bl), status_get_max_hp(bl));
- if (rate >= min_rate && rate <= max_rate)
- (*fr) = bl;
- return 1;
+ if (rate >= min_rate && rate <= max_rate)
+ (*fr) = bl;
+ return 1;
}
-static struct block_list *mob_getfriendhprate(struct mob_data *md,int min_rate,int max_rate) {
- struct block_list *fr=NULL;
- int type = BL_MOB;
+static struct block_list *mob_getfriendhprate(struct mob_data *md,int min_rate,int max_rate)
+{
+ struct block_list *fr=NULL;
+ int type = BL_MOB;
- nullpo_retr(NULL, md);
+ nullpo_retr(NULL, md);
- if (md->special_state.ai) //Summoned creatures. [Skotlex]
- type = BL_PC;
+ if (md->special_state.ai) //Summoned creatures. [Skotlex]
+ type = BL_PC;
- map_foreachinrange(mob_getfriendhprate_sub, &md->bl, 8, type,md,min_rate,max_rate,&fr);
- return fr;
+ map_foreachinrange(mob_getfriendhprate_sub, &md->bl, 8, type,md,min_rate,max_rate,&fr);
+ return fr;
}
/*==========================================
* Check hp rate of its master
*------------------------------------------*/
-struct block_list *mob_getmasterhpltmaxrate(struct mob_data *md,int rate) {
- if (md && md->master_id > 0) {
- struct block_list *bl = map_id2bl(md->master_id);
- if (bl && get_percentage(status_get_hp(bl), status_get_max_hp(bl)) < rate)
- return bl;
- }
-
- return NULL;
+struct block_list *mob_getmasterhpltmaxrate(struct mob_data *md,int rate)
+{
+ if( md && md->master_id > 0 )
+ {
+ struct block_list *bl = map_id2bl(md->master_id);
+ if( bl && get_percentage(status_get_hp(bl), status_get_max_hp(bl)) < rate )
+ return bl;
+ }
+
+ return NULL;
}
/*==========================================
* What a status state suits by nearby MOB is looked for.
*------------------------------------------*/
int mob_getfriendstatus_sub(struct block_list *bl,va_list ap)
{
- int cond1,cond2;
- struct mob_data **fr, *md, *mmd;
- int flag=0;
-
- nullpo_ret(bl);
- nullpo_ret(md=(struct mob_data *)bl);
- nullpo_ret(mmd=va_arg(ap,struct mob_data *));
-
- if (mmd->bl.id == bl->id && !(battle_config.mob_ai&0x10))
- return 0;
-
- if (battle_check_target(&mmd->bl,bl,BCT_ENEMY)>0)
- return 0;
- cond1=va_arg(ap,int);
- cond2=va_arg(ap,int);
- fr=va_arg(ap,struct mob_data **);
- if (cond2==-1) {
- int j;
- for (j=SC_COMMON_MIN; j<=SC_COMMON_MAX && !flag; j++) {
- if ((flag=(md->sc.data[j] != NULL))) //Once an effect was found, break out. [Skotlex]
- break;
- }
- } else
- flag=(md->sc.data[cond2] != NULL);
- if (flag^(cond1==MSC_FRIENDSTATUSOFF))
- (*fr)=md;
-
- return 0;
+ int cond1,cond2;
+ struct mob_data **fr, *md, *mmd;
+ int flag=0;
+
+ nullpo_ret(bl);
+ nullpo_ret(md=(struct mob_data *)bl);
+ nullpo_ret(mmd=va_arg(ap,struct mob_data *));
+
+ if( mmd->bl.id == bl->id && !(battle_config.mob_ai&0x10) )
+ return 0;
+
+ if (battle_check_target(&mmd->bl,bl,BCT_ENEMY)>0)
+ return 0;
+ cond1=va_arg(ap,int);
+ cond2=va_arg(ap,int);
+ fr=va_arg(ap,struct mob_data **);
+ if( cond2==-1 ){
+ int j;
+ for(j=SC_COMMON_MIN;j<=SC_COMMON_MAX && !flag;j++){
+ if ((flag=(md->sc.data[j] != NULL))) //Once an effect was found, break out. [Skotlex]
+ break;
+ }
+ }else
+ flag=( md->sc.data[cond2] != NULL );
+ if( flag^( cond1==MSC_FRIENDSTATUSOFF ) )
+ (*fr)=md;
+
+ return 0;
}
-struct mob_data *mob_getfriendstatus(struct mob_data *md,int cond1,int cond2) {
- struct mob_data *fr = NULL;
- nullpo_ret(md);
+struct mob_data *mob_getfriendstatus(struct mob_data *md,int cond1,int cond2)
+{
+ struct mob_data* fr = NULL;
+ nullpo_ret(md);
- map_foreachinrange(mob_getfriendstatus_sub, &md->bl, 8,BL_MOB, md,cond1,cond2,&fr);
- return fr;
+ map_foreachinrange(mob_getfriendstatus_sub, &md->bl, 8,BL_MOB, md,cond1,cond2,&fr);
+ return fr;
}
/*==========================================
@@ -3007,269 +3073,260 @@ struct mob_data *mob_getfriendstatus(struct mob_data *md,int cond1,int cond2) {
*------------------------------------------*/
int mobskill_use(struct mob_data *md, unsigned int tick, int event)
{
- struct mob_skill *ms;
- struct block_list *fbl = NULL; //Friend bl, which can either be a BL_PC or BL_MOB depending on the situation. [Skotlex]
- struct block_list *bl;
- struct mob_data *fmd = NULL;
- int i,j,n;
-
- nullpo_ret(md);
- nullpo_ret(ms = md->db->skill);
-
- if (!battle_config.mob_skill_rate || md->ud.skilltimer != INVALID_TIMER || !md->db->maxskill)
- return 0;
-
- if (event == -1 && DIFF_TICK(md->ud.canact_tick, tick) > 0)
- return 0; //Skill act delay only affects non-event skills.
-
- //Pick a starting position and loop from that.
- i = battle_config.mob_ai&0x100?rnd()%md->db->maxskill:0;
- for (n = 0; n < md->db->maxskill; i++, n++) {
- int c2, flag = 0;
-
- if (i == md->db->maxskill)
- i = 0;
-
- if (DIFF_TICK(tick, md->skilldelay[i]) < ms[i].delay)
- continue;
-
- c2 = ms[i].cond2;
-
- if (ms[i].state != md->state.skillstate) {
- if (md->state.skillstate != MSS_DEAD && (ms[i].state == MSS_ANY ||
- (ms[i].state == MSS_ANYTARGET && md->target_id && md->state.skillstate != MSS_LOOT)
- )) //ANYTARGET works with any state as long as there's a target. [Skotlex]
- ;
- else
- continue;
- }
- if (rnd() % 10000 > ms[i].permillage) //Lupus (max value = 10000)
- continue;
-
- if (ms[i].cond1 == event)
- flag = 1; //Trigger skill.
- else if (ms[i].cond1 == MSC_SKILLUSED)
- flag = ((event & 0xffff) == MSC_SKILLUSED && ((event >> 16) == c2 || c2 == 0));
- else if (event == -1) {
- //Avoid entering on defined events to avoid "hyper-active skill use" due to the overflow of calls to this function in battle.
- switch (ms[i].cond1) {
- case MSC_ALWAYS:
- flag = 1;
- break;
- case MSC_MYHPLTMAXRATE: // HP< maxhp%
- flag = get_percentage(md->status.hp, md->status.max_hp);
- flag = (flag <= c2);
- break;
- case MSC_MYHPINRATE:
- flag = get_percentage(md->status.hp, md->status.max_hp);
- flag = (flag >= c2 && flag <= ms[i].val[0]);
- break;
- case MSC_MYSTATUSON: // status[num] on
- case MSC_MYSTATUSOFF: // status[num] off
- if (!md->sc.count) {
- flag = 0;
- } else if (ms[i].cond2 == -1) {
- for (j = SC_COMMON_MIN; j <= SC_COMMON_MAX; j++)
- if ((flag = (md->sc.data[j]!=NULL)) != 0)
- break;
- } else {
- flag = (md->sc.data[ms[i].cond2]!=NULL);
- }
- flag ^= (ms[i].cond1 == MSC_MYSTATUSOFF);
- break;
- case MSC_FRIENDHPLTMAXRATE: // friend HP < maxhp%
- flag = ((fbl = mob_getfriendhprate(md, 0, ms[i].cond2)) != NULL);
- break;
- case MSC_FRIENDHPINRATE :
- flag = ((fbl = mob_getfriendhprate(md, ms[i].cond2, ms[i].val[0])) != NULL);
- break;
- case MSC_FRIENDSTATUSON: // friend status[num] on
- case MSC_FRIENDSTATUSOFF: // friend status[num] off
- flag = ((fmd = mob_getfriendstatus(md, ms[i].cond1, ms[i].cond2)) != NULL);
- break;
- case MSC_SLAVELT: // slave < num
- flag = (mob_countslave(&md->bl) < c2);
- break;
- case MSC_ATTACKPCGT: // attack pc > num
- flag = (unit_counttargeted(&md->bl) > c2);
- break;
- case MSC_SLAVELE: // slave <= num
- flag = (mob_countslave(&md->bl) <= c2);
- break;
- case MSC_ATTACKPCGE: // attack pc >= num
- flag = (unit_counttargeted(&md->bl) >= c2);
- break;
- case MSC_AFTERSKILL:
- flag = (md->ud.skillid == c2);
- break;
- case MSC_RUDEATTACKED:
- flag = (md->state.attacked_count >= RUDE_ATTACKED_COUNT);
- if (flag) md->state.attacked_count = 0; //Rude attacked count should be reset after the skill condition is met. Thanks to Komurka [Skotlex]
- break;
- case MSC_MASTERHPLTMAXRATE:
- flag = ((fbl = mob_getmasterhpltmaxrate(md, ms[i].cond2)) != NULL);
- break;
- case MSC_MASTERATTACKED:
- flag = (md->master_id > 0 && (fbl=map_id2bl(md->master_id)) && unit_counttargeted(fbl) > 0);
- break;
- case MSC_ALCHEMIST:
- flag = (md->state.alchemist);
- break;
- }
- }
-
- if (!flag)
- continue; //Skill requisite failed to be fulfilled.
-
- //Execute skill
- if (skill_get_casttype(ms[i].skill_id) == CAST_GROUND) {
- //Ground skill.
- short x, y;
- switch (ms[i].target) {
- case MST_RANDOM: //Pick a random enemy within skill range.
- bl = battle_getenemy(&md->bl, DEFAULT_ENEMY_TYPE(md),
- skill_get_range2(&md->bl, ms[i].skill_id, ms[i].skill_lv));
- break;
- case MST_TARGET:
- case MST_AROUND5:
- case MST_AROUND6:
- case MST_AROUND7:
- case MST_AROUND8:
- bl = map_id2bl(md->target_id);
- break;
- case MST_MASTER:
- bl = &md->bl;
- if (md->master_id)
- bl = map_id2bl(md->master_id);
- if (bl) //Otherwise, fall through.
- break;
- case MST_FRIEND:
- bl = fbl?fbl:(fmd?&fmd->bl:&md->bl);
- break;
- default:
- bl = &md->bl;
- break;
- }
- if (!bl) continue;
-
- x = bl->x;
- y = bl->y;
- // Look for an area to cast the spell around...
- if (ms[i].target >= MST_AROUND1 || ms[i].target >= MST_AROUND5) {
- j = ms[i].target >= MST_AROUND1?
- (ms[i].target-MST_AROUND1) +1:
- (ms[i].target-MST_AROUND5) +1;
- map_search_freecell(&md->bl, md->bl.m, &x, &y, j, j, 3);
- }
- md->skillidx = i;
- map_freeblock_lock();
- if (!battle_check_range(&md->bl,bl,skill_get_range2(&md->bl, ms[i].skill_id,ms[i].skill_lv)) ||
- !unit_skilluse_pos2(&md->bl, x, y,ms[i].skill_id, ms[i].skill_lv,ms[i].casttime, ms[i].cancel)) {
- map_freeblock_unlock();
- continue;
- }
- } else {
- //Targetted skill
- switch (ms[i].target) {
- case MST_RANDOM: //Pick a random enemy within skill range.
- bl = battle_getenemy(&md->bl, DEFAULT_ENEMY_TYPE(md),
- skill_get_range2(&md->bl, ms[i].skill_id, ms[i].skill_lv));
- break;
- case MST_TARGET:
- bl = map_id2bl(md->target_id);
- break;
- case MST_MASTER:
- bl = &md->bl;
- if (md->master_id)
- bl = map_id2bl(md->master_id);
- if (bl) //Otherwise, fall through.
- break;
- case MST_FRIEND:
- if (fbl) {
- bl = fbl;
- break;
- } else if (fmd) {
- bl = &fmd->bl;
- break;
- } // else fall through
- default:
- bl = &md->bl;
- break;
- }
- if (!bl) continue;
-
- md->skillidx = i;
- map_freeblock_lock();
- if (!battle_check_range(&md->bl,bl,skill_get_range2(&md->bl, ms[i].skill_id,ms[i].skill_lv)) ||
- !unit_skilluse_id2(&md->bl, bl->id,ms[i].skill_id, ms[i].skill_lv,ms[i].casttime, ms[i].cancel)) {
- map_freeblock_unlock();
- continue;
- }
- }
- //Skill used. Post-setups...
- if (ms[ i ].msg_id) { //Display color message [SnakeDrak]
- struct mob_chat *mc = mob_chat(ms[i].msg_id);
- char temp[CHAT_SIZE_MAX];
- char name[NAME_LENGTH];
- snprintf(name, sizeof name,"%s", md->name);
- strtok(name, "#"); // discard extra name identifier if present [Daegaladh]
- snprintf(temp, sizeof temp,"%s : %s", name, mc->msg);
- clif_messagecolor(&md->bl, mc->color, temp);
- }
- if (!(battle_config.mob_ai&0x200)) { //pass on delay to same skill.
- for (j = 0; j < md->db->maxskill; j++)
- if (md->db->skill[j].skill_id == ms[i].skill_id)
- md->skilldelay[j]=tick;
- } else
- md->skilldelay[i]=tick;
- map_freeblock_unlock();
- return 1;
- }
- //No skill was used.
- md->skillidx = -1;
- return 0;
+ struct mob_skill *ms;
+ struct block_list *fbl = NULL; //Friend bl, which can either be a BL_PC or BL_MOB depending on the situation. [Skotlex]
+ struct block_list *bl;
+ struct mob_data *fmd = NULL;
+ int i,j,n;
+
+ nullpo_ret(md);
+ nullpo_ret(ms = md->db->skill);
+
+ if (!battle_config.mob_skill_rate || md->ud.skilltimer != INVALID_TIMER || !md->db->maxskill)
+ return 0;
+
+ if (event == -1 && DIFF_TICK(md->ud.canact_tick, tick) > 0)
+ return 0; //Skill act delay only affects non-event skills.
+
+ //Pick a starting position and loop from that.
+ i = battle_config.mob_ai&0x100?rnd()%md->db->maxskill:0;
+ for (n = 0; n < md->db->maxskill; i++, n++) {
+ int c2, flag = 0;
+
+ if (i == md->db->maxskill)
+ i = 0;
+
+ if (DIFF_TICK(tick, md->skilldelay[i]) < ms[i].delay)
+ continue;
+
+ c2 = ms[i].cond2;
+
+ if (ms[i].state != md->state.skillstate) {
+ if (md->state.skillstate != MSS_DEAD && (ms[i].state == MSS_ANY ||
+ (ms[i].state == MSS_ANYTARGET && md->target_id && md->state.skillstate != MSS_LOOT)
+ )) //ANYTARGET works with any state as long as there's a target. [Skotlex]
+ ;
+ else
+ continue;
+ }
+ if (rnd() % 10000 > ms[i].permillage) //Lupus (max value = 10000)
+ continue;
+
+ if (ms[i].cond1 == event)
+ flag = 1; //Trigger skill.
+ else if (ms[i].cond1 == MSC_SKILLUSED)
+ flag = ((event & 0xffff) == MSC_SKILLUSED && ((event >> 16) == c2 || c2 == 0));
+ else if(event == -1){
+ //Avoid entering on defined events to avoid "hyper-active skill use" due to the overflow of calls to this function in battle.
+ switch (ms[i].cond1)
+ {
+ case MSC_ALWAYS:
+ flag = 1; break;
+ case MSC_MYHPLTMAXRATE: // HP< maxhp%
+ flag = get_percentage(md->status.hp, md->status.max_hp);
+ flag = (flag <= c2);
+ break;
+ case MSC_MYHPINRATE:
+ flag = get_percentage(md->status.hp, md->status.max_hp);
+ flag = (flag >= c2 && flag <= ms[i].val[0]);
+ break;
+ case MSC_MYSTATUSON: // status[num] on
+ case MSC_MYSTATUSOFF: // status[num] off
+ if (!md->sc.count) {
+ flag = 0;
+ } else if (ms[i].cond2 == -1) {
+ for (j = SC_COMMON_MIN; j <= SC_COMMON_MAX; j++)
+ if ((flag = (md->sc.data[j]!=NULL)) != 0)
+ break;
+ } else {
+ flag = (md->sc.data[ms[i].cond2]!=NULL);
+ }
+ flag ^= (ms[i].cond1 == MSC_MYSTATUSOFF); break;
+ case MSC_FRIENDHPLTMAXRATE: // friend HP < maxhp%
+ flag = ((fbl = mob_getfriendhprate(md, 0, ms[i].cond2)) != NULL); break;
+ case MSC_FRIENDHPINRATE :
+ flag = ((fbl = mob_getfriendhprate(md, ms[i].cond2, ms[i].val[0])) != NULL); break;
+ case MSC_FRIENDSTATUSON: // friend status[num] on
+ case MSC_FRIENDSTATUSOFF: // friend status[num] off
+ flag = ((fmd = mob_getfriendstatus(md, ms[i].cond1, ms[i].cond2)) != NULL); break;
+ case MSC_SLAVELT: // slave < num
+ flag = (mob_countslave(&md->bl) < c2 ); break;
+ case MSC_ATTACKPCGT: // attack pc > num
+ flag = (unit_counttargeted(&md->bl) > c2); break;
+ case MSC_SLAVELE: // slave <= num
+ flag = (mob_countslave(&md->bl) <= c2 ); break;
+ case MSC_ATTACKPCGE: // attack pc >= num
+ flag = (unit_counttargeted(&md->bl) >= c2); break;
+ case MSC_AFTERSKILL:
+ flag = (md->ud.skillid == c2); break;
+ case MSC_RUDEATTACKED:
+ flag = (md->state.attacked_count >= RUDE_ATTACKED_COUNT);
+ if (flag) md->state.attacked_count = 0; //Rude attacked count should be reset after the skill condition is met. Thanks to Komurka [Skotlex]
+ break;
+ case MSC_MASTERHPLTMAXRATE:
+ flag = ((fbl = mob_getmasterhpltmaxrate(md, ms[i].cond2)) != NULL); break;
+ case MSC_MASTERATTACKED:
+ flag = (md->master_id > 0 && (fbl=map_id2bl(md->master_id)) && unit_counttargeted(fbl) > 0); break;
+ case MSC_ALCHEMIST:
+ flag = (md->state.alchemist);
+ break;
+ }
+ }
+
+ if (!flag)
+ continue; //Skill requisite failed to be fulfilled.
+
+ //Execute skill
+ if (skill_get_casttype(ms[i].skill_id) == CAST_GROUND)
+ { //Ground skill.
+ short x, y;
+ switch (ms[i].target) {
+ case MST_RANDOM: //Pick a random enemy within skill range.
+ bl = battle_getenemy(&md->bl, DEFAULT_ENEMY_TYPE(md),
+ skill_get_range2(&md->bl, ms[i].skill_id, ms[i].skill_lv));
+ break;
+ case MST_TARGET:
+ case MST_AROUND5:
+ case MST_AROUND6:
+ case MST_AROUND7:
+ case MST_AROUND8:
+ bl = map_id2bl(md->target_id);
+ break;
+ case MST_MASTER:
+ bl = &md->bl;
+ if (md->master_id)
+ bl = map_id2bl(md->master_id);
+ if (bl) //Otherwise, fall through.
+ break;
+ case MST_FRIEND:
+ bl = fbl?fbl:(fmd?&fmd->bl:&md->bl);
+ break;
+ default:
+ bl = &md->bl;
+ break;
+ }
+ if (!bl) continue;
+
+ x = bl->x;
+ y = bl->y;
+ // Look for an area to cast the spell around...
+ if (ms[i].target >= MST_AROUND1 || ms[i].target >= MST_AROUND5) {
+ j = ms[i].target >= MST_AROUND1?
+ (ms[i].target-MST_AROUND1) +1:
+ (ms[i].target-MST_AROUND5) +1;
+ map_search_freecell(&md->bl, md->bl.m, &x, &y, j, j, 3);
+ }
+ md->skillidx = i;
+ map_freeblock_lock();
+ if( !battle_check_range(&md->bl,bl,skill_get_range2(&md->bl, ms[i].skill_id,ms[i].skill_lv)) ||
+ !unit_skilluse_pos2(&md->bl, x, y,ms[i].skill_id, ms[i].skill_lv,ms[i].casttime, ms[i].cancel) )
+ {
+ map_freeblock_unlock();
+ continue;
+ }
+ } else {
+ //Targetted skill
+ switch (ms[i].target) {
+ case MST_RANDOM: //Pick a random enemy within skill range.
+ bl = battle_getenemy(&md->bl, DEFAULT_ENEMY_TYPE(md),
+ skill_get_range2(&md->bl, ms[i].skill_id, ms[i].skill_lv));
+ break;
+ case MST_TARGET:
+ bl = map_id2bl(md->target_id);
+ break;
+ case MST_MASTER:
+ bl = &md->bl;
+ if (md->master_id)
+ bl = map_id2bl(md->master_id);
+ if (bl) //Otherwise, fall through.
+ break;
+ case MST_FRIEND:
+ if (fbl) {
+ bl = fbl;
+ break;
+ } else if (fmd) {
+ bl = &fmd->bl;
+ break;
+ } // else fall through
+ default:
+ bl = &md->bl;
+ break;
+ }
+ if (!bl) continue;
+
+ md->skillidx = i;
+ map_freeblock_lock();
+ if( !battle_check_range(&md->bl,bl,skill_get_range2(&md->bl, ms[i].skill_id,ms[i].skill_lv)) ||
+ !unit_skilluse_id2(&md->bl, bl->id,ms[i].skill_id, ms[i].skill_lv,ms[i].casttime, ms[i].cancel) )
+ {
+ map_freeblock_unlock();
+ continue;
+ }
+ }
+ //Skill used. Post-setups...
+ if ( ms[ i ].msg_id ){ //Display color message [SnakeDrak]
+ struct mob_chat *mc = mob_chat(ms[i].msg_id);
+ char temp[CHAT_SIZE_MAX];
+ char name[NAME_LENGTH];
+ snprintf(name, sizeof name,"%s", md->name);
+ strtok(name, "#"); // discard extra name identifier if present [Daegaladh]
+ snprintf(temp, sizeof temp,"%s : %s", name, mc->msg);
+ clif_messagecolor(&md->bl, mc->color, temp);
+ }
+ if(!(battle_config.mob_ai&0x200)) { //pass on delay to same skill.
+ for (j = 0; j < md->db->maxskill; j++)
+ if (md->db->skill[j].skill_id == ms[i].skill_id)
+ md->skilldelay[j]=tick;
+ } else
+ md->skilldelay[i]=tick;
+ map_freeblock_unlock();
+ return 1;
+ }
+ //No skill was used.
+ md->skillidx = -1;
+ return 0;
}
/*==========================================
* Skill use event processing
*------------------------------------------*/
int mobskill_event(struct mob_data *md, struct block_list *src, unsigned int tick, int flag)
{
- int target_id, res = 0;
-
- if (md->bl.prev == NULL || md->status.hp <= 0)
- return 0;
-
- target_id = md->target_id;
- if (!target_id || battle_config.mob_changetarget_byskill)
- md->target_id = src->id;
-
- if (flag == -1)
- res = mobskill_use(md, tick, MSC_CASTTARGETED);
- else if ((flag&0xffff) == MSC_SKILLUSED)
- res = mobskill_use(md, tick, flag);
- else if (flag&BF_SHORT)
- res = mobskill_use(md, tick, MSC_CLOSEDATTACKED);
- else if (flag&BF_LONG && !(flag&BF_MAGIC)) //Long-attacked should not include magic.
- res = mobskill_use(md, tick, MSC_LONGRANGEATTACKED);
-
- if (!res)
- //Restore previous target only if skill condition failed to trigger. [Skotlex]
- md->target_id = target_id;
- //Otherwise check if the target is an enemy, and unlock if needed.
- else if (battle_check_target(&md->bl, src, BCT_ENEMY) <= 0)
- md->target_id = target_id;
-
- return res;
+ int target_id, res = 0;
+
+ if(md->bl.prev == NULL || md->status.hp <= 0)
+ return 0;
+
+ target_id = md->target_id;
+ if (!target_id || battle_config.mob_changetarget_byskill)
+ md->target_id = src->id;
+
+ if (flag == -1)
+ res = mobskill_use(md, tick, MSC_CASTTARGETED);
+ else if ((flag&0xffff) == MSC_SKILLUSED)
+ res = mobskill_use(md, tick, flag);
+ else if (flag&BF_SHORT)
+ res = mobskill_use(md, tick, MSC_CLOSEDATTACKED);
+ else if (flag&BF_LONG && !(flag&BF_MAGIC)) //Long-attacked should not include magic.
+ res = mobskill_use(md, tick, MSC_LONGRANGEATTACKED);
+
+ if (!res)
+ //Restore previous target only if skill condition failed to trigger. [Skotlex]
+ md->target_id = target_id;
+ //Otherwise check if the target is an enemy, and unlock if needed.
+ else if (battle_check_target(&md->bl, src, BCT_ENEMY) <= 0)
+ md->target_id = target_id;
+
+ return res;
}
// Player cloned mobs. [Valaris]
int mob_is_clone(int class_)
{
- if (class_ < MOB_CLONE_START || class_ > MOB_CLONE_END)
- return 0;
- if (mob_db(class_) == mob_dummy)
- return 0;
- return class_;
+ if(class_ < MOB_CLONE_START || class_ > MOB_CLONE_END)
+ return 0;
+ if (mob_db(class_) == mob_dummy)
+ return 0;
+ return class_;
}
//Flag values:
@@ -3279,212 +3336,213 @@ int mob_is_clone(int class_)
//Returns: ID of newly crafted copy.
int mob_clone_spawn(struct map_session_data *sd, int m, int x, int y, const char *event, int master_id, int mode, int flag, unsigned int duration)
{
- int class_;
- int i,j,inf,skill_id, fd;
- struct mob_data *md;
- struct mob_skill *ms;
- struct mob_db *db;
- struct status_data *status;
-
- nullpo_ret(sd);
-
- if (pc_isdead(sd) && master_id && flag&1)
- return 0;
-
- ARR_FIND(MOB_CLONE_START, MOB_CLONE_END, class_, mob_db_data[class_] == NULL);
- if (class_ >= MOB_CLONE_END)
- return 0;
-
- db = mob_db_data[class_]=(struct mob_db *)aCalloc(1, sizeof(struct mob_db));
- status = &db->status;
- strcpy(db->sprite,sd->status.name);
- strcpy(db->name,sd->status.name);
- strcpy(db->jname,sd->status.name);
- db->lv=status_get_lv(&sd->bl);
- memcpy(status, &sd->base_status, sizeof(struct status_data));
- status->rhw.atk2= status->dex + status->rhw.atk + status->rhw.atk2; //Max ATK
- status->rhw.atk = status->dex; //Min ATK
- if (status->lhw.atk) {
- status->lhw.atk2= status->dex + status->lhw.atk + status->lhw.atk2; //Max ATK
- status->lhw.atk = status->dex; //Min ATK
- }
- if (mode) //User provided mode.
- status->mode = mode;
- else if (flag&1) //Friendly Character, remove looting.
- status->mode &= ~MD_LOOTER;
- status->hp = status->max_hp;
- status->sp = status->max_sp;
- memcpy(&db->vd, &sd->vd, sizeof(struct view_data));
- db->base_exp=1;
- db->job_exp=1;
- db->range2=AREA_SIZE; //Let them have the same view-range as players.
- db->range3=AREA_SIZE; //Min chase of a screen.
- db->option=sd->sc.option;
-
- //Skill copy [Skotlex]
- ms = &db->skill[0];
-
- /**
- * We temporarily disable sd's fd so it doesn't receive the messages from skill_check_condition_castbegin
- **/
- fd = sd->fd;
- sd->fd = 0;
-
- //Go Backwards to give better priority to advanced skills.
- for (i=0,j = MAX_SKILL_TREE-1; j>=0 && i< MAX_MOBSKILL ; j--) {
- skill_id = skill_tree[pc_class2idx(sd->status.class_)][j].id;
- if (!skill_id || sd->status.skill[skill_id].lv < 1 ||
- (skill_get_inf2(skill_id)&(INF2_WEDDING_SKILL|INF2_GUILD_SKILL)) ||
- skill_get_nocast(skill_id)&16
- )
- continue;
- //Normal aggressive mob, disable skills that cannot help them fight
- //against players (those with flags UF_NOMOB and UF_NOPC are specific
- //to always aid players!) [Skotlex]
- if (!(flag&1) &&
- skill_get_unit_id(skill_id, 0) &&
- skill_get_unit_flag(skill_id)&(UF_NOMOB|UF_NOPC))
- continue;
- /**
- * The clone should be able to cast the skill (e.g. have the required weapon) bugreport:5299)
- **/
- if (!skill_check_condition_castbegin(sd,skill_id,sd->status.skill[skill_id].lv))
- continue;
-
- memset(&ms[i], 0, sizeof(struct mob_skill));
- ms[i].skill_id = skill_id;
- ms[i].skill_lv = sd->status.skill[skill_id].lv;
- ms[i].state = MSS_ANY;
- ms[i].permillage = 500*battle_config.mob_skill_rate/100; //Default chance of all skills: 5%
- ms[i].emotion = -1;
- ms[i].cancel = 0;
- ms[i].casttime = skill_castfix(&sd->bl,skill_id, ms[i].skill_lv);
- ms[i].delay = 5000+skill_delayfix(&sd->bl,skill_id, ms[i].skill_lv);
-
- inf = skill_get_inf(skill_id);
- if (inf&INF_ATTACK_SKILL) {
- ms[i].target = MST_TARGET;
- ms[i].cond1 = MSC_ALWAYS;
- if (skill_get_range(skill_id, ms[i].skill_lv) > 3)
- ms[i].state = MSS_ANYTARGET;
- else
- ms[i].state = MSS_BERSERK;
- } else if (inf&INF_GROUND_SKILL) {
- if (skill_get_inf2(skill_id)&INF2_TRAP) { //Traps!
- ms[i].state = MSS_IDLE;
- ms[i].target = MST_AROUND2;
- ms[i].delay = 60000;
- } else if (skill_get_unit_target(skill_id) == BCT_ENEMY) { //Target Enemy
- ms[i].state = MSS_ANYTARGET;
- ms[i].target = MST_TARGET;
- ms[i].cond1 = MSC_ALWAYS;
- } else { //Target allies
- ms[i].target = MST_FRIEND;
- ms[i].cond1 = MSC_FRIENDHPLTMAXRATE;
- ms[i].cond2 = 95;
- }
- } else if (inf&INF_SELF_SKILL) {
- if (skill_get_inf2(skill_id)&INF2_NO_TARGET_SELF) { //auto-select target skill.
- ms[i].target = MST_TARGET;
- ms[i].cond1 = MSC_ALWAYS;
- if (skill_get_range(skill_id, ms[i].skill_lv) > 3) {
- ms[i].state = MSS_ANYTARGET;
- } else {
- ms[i].state = MSS_BERSERK;
- }
- } else { //Self skill
- ms[i].target = MST_SELF;
- ms[i].cond1 = MSC_MYHPLTMAXRATE;
- ms[i].cond2 = 90;
- ms[i].permillage = 2000;
- //Delay: Remove the stock 5 secs and add half of the support time.
- ms[i].delay += -5000 +(skill_get_time(skill_id, ms[i].skill_lv) + skill_get_time2(skill_id, ms[i].skill_lv))/2;
- if (ms[i].delay < 5000)
- ms[i].delay = 5000; //With a minimum of 5 secs.
- }
- } else if (inf&INF_SUPPORT_SKILL) {
- ms[i].target = MST_FRIEND;
- ms[i].cond1 = MSC_FRIENDHPLTMAXRATE;
- ms[i].cond2 = 90;
- if (skill_id == AL_HEAL)
- ms[i].permillage = 5000; //Higher skill rate usage for heal.
- else if (skill_id == ALL_RESURRECTION)
- ms[i].cond2 = 1;
- //Delay: Remove the stock 5 secs and add half of the support time.
- ms[i].delay += -5000 +(skill_get_time(skill_id, ms[i].skill_lv) + skill_get_time2(skill_id, ms[i].skill_lv))/2;
- if (ms[i].delay < 2000)
- ms[i].delay = 2000; //With a minimum of 2 secs.
-
- if (i+1 < MAX_MOBSKILL) { //duplicate this so it also triggers on self.
- memcpy(&ms[i+1], &ms[i], sizeof(struct mob_skill));
- db->maxskill = ++i;
- ms[i].target = MST_SELF;
- ms[i].cond1 = MSC_MYHPLTMAXRATE;
- }
- } else {
- switch (skill_id) { //Certain Special skills that are passive, and thus, never triggered.
- case MO_TRIPLEATTACK:
- case TF_DOUBLE:
- case GS_CHAINACTION:
- ms[i].state = MSS_BERSERK;
- ms[i].target = MST_TARGET;
- ms[i].cond1 = MSC_ALWAYS;
- ms[i].permillage = skill_id==MO_TRIPLEATTACK?(3000-ms[i].skill_lv*100):(ms[i].skill_lv*500);
- ms[i].delay -= 5000; //Remove the added delay as these could trigger on "all hits".
- break;
- default: //Untreated Skill
- continue;
- }
- }
- if (battle_config.mob_skill_rate!= 100)
- ms[i].permillage = ms[i].permillage*battle_config.mob_skill_rate/100;
- if (battle_config.mob_skill_delay != 100)
- ms[i].delay = ms[i].delay*battle_config.mob_skill_delay/100;
-
- db->maxskill = ++i;
- }
-
- /**
- * We grant the session it's fd value back.
- **/
- sd->fd = fd;
-
- //Finally, spawn it.
- md = mob_once_spawn_sub(&sd->bl, m, x, y, "--en--", class_, event, SZ_SMALL, AI_NONE);
- if (!md) return 0; //Failed?
-
- md->special_state.clone = 1;
-
- if (master_id || flag || duration) { //Further manipulate crafted char.
- if (flag&1) //Friendly Character
- md->special_state.ai = AI_ATTACK;
- if (master_id) //Attach to Master
- md->master_id = master_id;
- if (duration) { //Auto Delete after a while.
- if (md->deletetimer != INVALID_TIMER)
- delete_timer(md->deletetimer, mob_timer_delete);
- md->deletetimer = add_timer(gettick() + duration, mob_timer_delete, md->bl.id, 0);
- }
- }
-
- mob_spawn(md);
-
- return md->bl.id;
+ int class_;
+ int i,j,inf,skill_id, fd;
+ struct mob_data *md;
+ struct mob_skill *ms;
+ struct mob_db* db;
+ struct status_data *status;
+
+ nullpo_ret(sd);
+
+ if(pc_isdead(sd) && master_id && flag&1)
+ return 0;
+
+ ARR_FIND( MOB_CLONE_START, MOB_CLONE_END, class_, mob_db_data[class_] == NULL );
+ if(class_ >= MOB_CLONE_END)
+ return 0;
+
+ db = mob_db_data[class_]=(struct mob_db*)aCalloc(1, sizeof(struct mob_db));
+ status = &db->status;
+ strcpy(db->sprite,sd->status.name);
+ strcpy(db->name,sd->status.name);
+ strcpy(db->jname,sd->status.name);
+ db->lv=status_get_lv(&sd->bl);
+ memcpy(status, &sd->base_status, sizeof(struct status_data));
+ status->rhw.atk2= status->dex + status->rhw.atk + status->rhw.atk2; //Max ATK
+ status->rhw.atk = status->dex; //Min ATK
+ if (status->lhw.atk) {
+ status->lhw.atk2= status->dex + status->lhw.atk + status->lhw.atk2; //Max ATK
+ status->lhw.atk = status->dex; //Min ATK
+ }
+ if (mode) //User provided mode.
+ status->mode = mode;
+ else if (flag&1) //Friendly Character, remove looting.
+ status->mode &= ~MD_LOOTER;
+ status->hp = status->max_hp;
+ status->sp = status->max_sp;
+ memcpy(&db->vd, &sd->vd, sizeof(struct view_data));
+ db->base_exp=1;
+ db->job_exp=1;
+ db->range2=AREA_SIZE; //Let them have the same view-range as players.
+ db->range3=AREA_SIZE; //Min chase of a screen.
+ db->option=sd->sc.option;
+
+ //Skill copy [Skotlex]
+ ms = &db->skill[0];
+
+ /**
+ * We temporarily disable sd's fd so it doesn't receive the messages from skill_check_condition_castbegin
+ **/
+ fd = sd->fd;
+ sd->fd = 0;
+
+ //Go Backwards to give better priority to advanced skills.
+ for (i=0,j = MAX_SKILL_TREE-1;j>=0 && i< MAX_MOBSKILL ;j--) {
+ skill_id = skill_tree[pc_class2idx(sd->status.class_)][j].id;
+ if (!skill_id || sd->status.skill[skill_id].lv < 1 ||
+ (skill_get_inf2(skill_id)&(INF2_WEDDING_SKILL|INF2_GUILD_SKILL)) ||
+ skill_get_nocast(skill_id)&16
+ )
+ continue;
+ //Normal aggressive mob, disable skills that cannot help them fight
+ //against players (those with flags UF_NOMOB and UF_NOPC are specific
+ //to always aid players!) [Skotlex]
+ if (!(flag&1) &&
+ skill_get_unit_id(skill_id, 0) &&
+ skill_get_unit_flag(skill_id)&(UF_NOMOB|UF_NOPC))
+ continue;
+ /**
+ * The clone should be able to cast the skill (e.g. have the required weapon) bugreport:5299)
+ **/
+ if( !skill_check_condition_castbegin(sd,skill_id,sd->status.skill[skill_id].lv) )
+ continue;
+
+ memset (&ms[i], 0, sizeof(struct mob_skill));
+ ms[i].skill_id = skill_id;
+ ms[i].skill_lv = sd->status.skill[skill_id].lv;
+ ms[i].state = MSS_ANY;
+ ms[i].permillage = 500*battle_config.mob_skill_rate/100; //Default chance of all skills: 5%
+ ms[i].emotion = -1;
+ ms[i].cancel = 0;
+ ms[i].casttime = skill_castfix(&sd->bl,skill_id, ms[i].skill_lv);
+ ms[i].delay = 5000+skill_delayfix(&sd->bl,skill_id, ms[i].skill_lv);
+
+ inf = skill_get_inf(skill_id);
+ if (inf&INF_ATTACK_SKILL) {
+ ms[i].target = MST_TARGET;
+ ms[i].cond1 = MSC_ALWAYS;
+ if (skill_get_range(skill_id, ms[i].skill_lv) > 3)
+ ms[i].state = MSS_ANYTARGET;
+ else
+ ms[i].state = MSS_BERSERK;
+ } else if(inf&INF_GROUND_SKILL) {
+ if (skill_get_inf2(skill_id)&INF2_TRAP) { //Traps!
+ ms[i].state = MSS_IDLE;
+ ms[i].target = MST_AROUND2;
+ ms[i].delay = 60000;
+ } else if (skill_get_unit_target(skill_id) == BCT_ENEMY) { //Target Enemy
+ ms[i].state = MSS_ANYTARGET;
+ ms[i].target = MST_TARGET;
+ ms[i].cond1 = MSC_ALWAYS;
+ } else { //Target allies
+ ms[i].target = MST_FRIEND;
+ ms[i].cond1 = MSC_FRIENDHPLTMAXRATE;
+ ms[i].cond2 = 95;
+ }
+ } else if (inf&INF_SELF_SKILL) {
+ if (skill_get_inf2(skill_id)&INF2_NO_TARGET_SELF) { //auto-select target skill.
+ ms[i].target = MST_TARGET;
+ ms[i].cond1 = MSC_ALWAYS;
+ if (skill_get_range(skill_id, ms[i].skill_lv) > 3) {
+ ms[i].state = MSS_ANYTARGET;
+ } else {
+ ms[i].state = MSS_BERSERK;
+ }
+ } else { //Self skill
+ ms[i].target = MST_SELF;
+ ms[i].cond1 = MSC_MYHPLTMAXRATE;
+ ms[i].cond2 = 90;
+ ms[i].permillage = 2000;
+ //Delay: Remove the stock 5 secs and add half of the support time.
+ ms[i].delay += -5000 +(skill_get_time(skill_id, ms[i].skill_lv) + skill_get_time2(skill_id, ms[i].skill_lv))/2;
+ if (ms[i].delay < 5000)
+ ms[i].delay = 5000; //With a minimum of 5 secs.
+ }
+ } else if (inf&INF_SUPPORT_SKILL) {
+ ms[i].target = MST_FRIEND;
+ ms[i].cond1 = MSC_FRIENDHPLTMAXRATE;
+ ms[i].cond2 = 90;
+ if (skill_id == AL_HEAL)
+ ms[i].permillage = 5000; //Higher skill rate usage for heal.
+ else if (skill_id == ALL_RESURRECTION)
+ ms[i].cond2 = 1;
+ //Delay: Remove the stock 5 secs and add half of the support time.
+ ms[i].delay += -5000 +(skill_get_time(skill_id, ms[i].skill_lv) + skill_get_time2(skill_id, ms[i].skill_lv))/2;
+ if (ms[i].delay < 2000)
+ ms[i].delay = 2000; //With a minimum of 2 secs.
+
+ if (i+1 < MAX_MOBSKILL) { //duplicate this so it also triggers on self.
+ memcpy(&ms[i+1], &ms[i], sizeof(struct mob_skill));
+ db->maxskill = ++i;
+ ms[i].target = MST_SELF;
+ ms[i].cond1 = MSC_MYHPLTMAXRATE;
+ }
+ } else {
+ switch (skill_id) { //Certain Special skills that are passive, and thus, never triggered.
+ case MO_TRIPLEATTACK:
+ case TF_DOUBLE:
+ case GS_CHAINACTION:
+ ms[i].state = MSS_BERSERK;
+ ms[i].target = MST_TARGET;
+ ms[i].cond1 = MSC_ALWAYS;
+ ms[i].permillage = skill_id==MO_TRIPLEATTACK?(3000-ms[i].skill_lv*100):(ms[i].skill_lv*500);
+ ms[i].delay -= 5000; //Remove the added delay as these could trigger on "all hits".
+ break;
+ default: //Untreated Skill
+ continue;
+ }
+ }
+ if (battle_config.mob_skill_rate!= 100)
+ ms[i].permillage = ms[i].permillage*battle_config.mob_skill_rate/100;
+ if (battle_config.mob_skill_delay != 100)
+ ms[i].delay = ms[i].delay*battle_config.mob_skill_delay/100;
+
+ db->maxskill = ++i;
+ }
+
+ /**
+ * We grant the session it's fd value back.
+ **/
+ sd->fd = fd;
+
+ //Finally, spawn it.
+ md = mob_once_spawn_sub(&sd->bl, m, x, y, "--en--", class_, event, SZ_SMALL, AI_NONE);
+ if (!md) return 0; //Failed?
+
+ md->special_state.clone = 1;
+
+ if (master_id || flag || duration) { //Further manipulate crafted char.
+ if (flag&1) //Friendly Character
+ md->special_state.ai = AI_ATTACK;
+ if (master_id) //Attach to Master
+ md->master_id = master_id;
+ if (duration) //Auto Delete after a while.
+ {
+ if( md->deletetimer != INVALID_TIMER )
+ delete_timer(md->deletetimer, mob_timer_delete);
+ md->deletetimer = add_timer (gettick() + duration, mob_timer_delete, md->bl.id, 0);
+ }
+ }
+
+ mob_spawn(md);
+
+ return md->bl.id;
}
int mob_clone_delete(struct mob_data *md)
{
- const int class_ = md->class_;
- if (class_ >= MOB_CLONE_START && class_ < MOB_CLONE_END
- && mob_db_data[class_]!=NULL) {
- aFree(mob_db_data[class_]);
- mob_db_data[class_]=NULL;
- //Clear references to the db
- md->db = mob_dummy;
- md->vd = NULL;
- return 1;
- }
- return 0;
+ const int class_ = md->class_;
+ if (class_ >= MOB_CLONE_START && class_ < MOB_CLONE_END
+ && mob_db_data[class_]!=NULL) {
+ aFree(mob_db_data[class_]);
+ mob_db_data[class_]=NULL;
+ //Clear references to the db
+ md->db = mob_dummy;
+ md->vd = NULL;
+ return 1;
+ }
+ return 0;
}
//
@@ -3495,59 +3553,60 @@ int mob_clone_delete(struct mob_data *md)
*------------------------------------------*/
static int mob_makedummymobdb(int class_)
{
- if (mob_dummy != NULL) {
- if (mob_db(class_) == mob_dummy)
- return 1; //Using the mob_dummy data already. [Skotlex]
- if (class_ > 0 && class_ <= MAX_MOB_DB) {
- //Remove the mob data so that it uses the dummy data instead.
- aFree(mob_db_data[class_]);
- mob_db_data[class_] = NULL;
- }
- return 0;
- }
- //Initialize dummy data.
- mob_dummy = (struct mob_db *)aCalloc(1, sizeof(struct mob_db)); //Initializing the dummy mob.
- sprintf(mob_dummy->sprite,"DUMMY");
- sprintf(mob_dummy->name,"Dummy");
- sprintf(mob_dummy->jname,"Dummy");
- mob_dummy->lv=1;
- mob_dummy->status.max_hp=1000;
- mob_dummy->status.max_sp=1;
- mob_dummy->status.rhw.range=1;
- mob_dummy->status.rhw.atk=7;
- mob_dummy->status.rhw.atk2=10;
- mob_dummy->status.str=1;
- mob_dummy->status.agi=1;
- mob_dummy->status.vit=1;
- mob_dummy->status.int_=1;
- mob_dummy->status.dex=6;
- mob_dummy->status.luk=2;
- mob_dummy->status.speed=300;
- mob_dummy->status.adelay=1000;
- mob_dummy->status.amotion=500;
- mob_dummy->status.dmotion=500;
- mob_dummy->base_exp=2;
- mob_dummy->job_exp=1;
- mob_dummy->range2=10;
- mob_dummy->range3=10;
-
- return 0;
+ if (mob_dummy != NULL)
+ {
+ if (mob_db(class_) == mob_dummy)
+ return 1; //Using the mob_dummy data already. [Skotlex]
+ if (class_ > 0 && class_ <= MAX_MOB_DB)
+ { //Remove the mob data so that it uses the dummy data instead.
+ aFree(mob_db_data[class_]);
+ mob_db_data[class_] = NULL;
+ }
+ return 0;
+ }
+ //Initialize dummy data.
+ mob_dummy = (struct mob_db*)aCalloc(1, sizeof(struct mob_db)); //Initializing the dummy mob.
+ sprintf(mob_dummy->sprite,"DUMMY");
+ sprintf(mob_dummy->name,"Dummy");
+ sprintf(mob_dummy->jname,"Dummy");
+ mob_dummy->lv=1;
+ mob_dummy->status.max_hp=1000;
+ mob_dummy->status.max_sp=1;
+ mob_dummy->status.rhw.range=1;
+ mob_dummy->status.rhw.atk=7;
+ mob_dummy->status.rhw.atk2=10;
+ mob_dummy->status.str=1;
+ mob_dummy->status.agi=1;
+ mob_dummy->status.vit=1;
+ mob_dummy->status.int_=1;
+ mob_dummy->status.dex=6;
+ mob_dummy->status.luk=2;
+ mob_dummy->status.speed=300;
+ mob_dummy->status.adelay=1000;
+ mob_dummy->status.amotion=500;
+ mob_dummy->status.dmotion=500;
+ mob_dummy->base_exp=2;
+ mob_dummy->job_exp=1;
+ mob_dummy->range2=10;
+ mob_dummy->range3=10;
+
+ return 0;
}
//Adjusts the drop rate of item according to the criteria given. [Skotlex]
static unsigned int mob_drop_adjust(int baserate, int rate_adjust, unsigned short rate_min, unsigned short rate_max)
{
- double rate = baserate;
+ double rate = baserate;
- if (battle_config.logarithmic_drops && rate_adjust > 0 && baserate > 0) //Logarithmic drops equation by Ishizu-Chan
- //Equation: Droprate(x,y) = x * (5 - log(x)) ^ (ln(y) / ln(5))
- //x is the normal Droprate, y is the Modificator.
- rate = rate * pow((5.0 - log10(rate)), (log(rate_adjust/100.) / log(5.0))) + 0.5;
- else
- //Classical linear rate adjustment.
- rate = rate * rate_adjust/100;
+ if (battle_config.logarithmic_drops && rate_adjust > 0 && baserate > 0) //Logarithmic drops equation by Ishizu-Chan
+ //Equation: Droprate(x,y) = x * (5 - log(x)) ^ (ln(y) / ln(5))
+ //x is the normal Droprate, y is the Modificator.
+ rate = rate * pow((5.0 - log10(rate)), (log(rate_adjust/100.) / log(5.0))) + 0.5;
+ else
+ //Classical linear rate adjustment.
+ rate = rate * rate_adjust/100;
- return (unsigned int)cap_value(rate,rate_min,rate_max);
+ return (unsigned int)cap_value(rate,rate_min,rate_max);
}
/**
@@ -3559,289 +3618,293 @@ static unsigned int mob_drop_adjust(int baserate, int rate_adjust, unsigned shor
*/
static void item_dropratio_adjust(int nameid, int mob_id, int *rate_adjust)
{
- int i;
- if (item_drop_ratio_db[nameid]) {
- if (item_drop_ratio_db[nameid]->mob_id[0]) { // only for listed mobs
- ARR_FIND(0, MAX_ITEMRATIO_MOBS, i, item_drop_ratio_db[nameid]->mob_id[i] == mob_id);
- if (i < MAX_ITEMRATIO_MOBS) // found
- *rate_adjust = item_drop_ratio_db[nameid]->drop_ratio;
- } else // for all mobs
- *rate_adjust = item_drop_ratio_db[nameid]->drop_ratio;
- }
+ int i;
+ if( item_drop_ratio_db[nameid] ) {
+ if( item_drop_ratio_db[nameid]->mob_id[0] ) { // only for listed mobs
+ ARR_FIND(0, MAX_ITEMRATIO_MOBS, i, item_drop_ratio_db[nameid]->mob_id[i] == mob_id);
+ if(i < MAX_ITEMRATIO_MOBS) // found
+ *rate_adjust = item_drop_ratio_db[nameid]->drop_ratio;
+ }
+ else // for all mobs
+ *rate_adjust = item_drop_ratio_db[nameid]->drop_ratio;
+ }
}
/*==========================================
* processes one mobdb entry
*------------------------------------------*/
-static bool mob_parse_dbrow(char **str)
+static bool mob_parse_dbrow(char** str)
{
- struct mob_db *db, entry;
- struct status_data *status;
- int class_, i, k;
- double exp, maxhp;
- struct mob_data data;
-
- class_ = atoi(str[0]);
-
- if (class_ <= 1000 || class_ > MAX_MOB_DB) {
- ShowError("mob_parse_dbrow: Invalid monster ID %d, must be in range %d-%d.\n", class_, 1000, MAX_MOB_DB);
- return false;
- }
- if (pcdb_checkid(class_)) {
- ShowError("mob_parse_dbrow: Invalid monster ID %d, reserved for player classes.\n", class_);
- return false;
- }
-
- if (class_ >= MOB_CLONE_START && class_ < MOB_CLONE_END) {
- ShowError("mob_parse_dbrow: Invalid monster ID %d. Range %d-%d is reserved for player clones. Please increase MAX_MOB_DB (%d).\n", class_, MOB_CLONE_START, MOB_CLONE_END-1, MAX_MOB_DB);
- return false;
- }
-
- memset(&entry, 0, sizeof(entry));
-
- db = &entry;
- status = &db->status;
-
- db->vd.class_ = class_;
- safestrncpy(db->sprite, str[1], sizeof(db->sprite));
- safestrncpy(db->jname, str[2], sizeof(db->jname));
- safestrncpy(db->name, str[3], sizeof(db->name));
- db->lv = atoi(str[4]);
- db->lv = cap_value(db->lv, 1, USHRT_MAX);
- status->max_hp = atoi(str[5]);
- status->max_sp = atoi(str[6]);
-
- exp = (double)atoi(str[7]) * (double)battle_config.base_exp_rate / 100.;
- db->base_exp = (unsigned int)cap_value(exp, 0, UINT_MAX);
-
- exp = (double)atoi(str[8]) * (double)battle_config.job_exp_rate / 100.;
- db->job_exp = (unsigned int)cap_value(exp, 0, UINT_MAX);
-
- status->rhw.range = atoi(str[9]);
- status->rhw.atk = atoi(str[10]);
- status->rhw.atk2 = atoi(str[11]);
- status->def = atoi(str[12]);
- status->mdef = atoi(str[13]);
- status->str = atoi(str[14]);
- status->agi = atoi(str[15]);
- status->vit = atoi(str[16]);
- status->int_ = atoi(str[17]);
- status->dex = atoi(str[18]);
- status->luk = atoi(str[19]);
- //All status should be min 1 to prevent divisions by zero from some skills. [Skotlex]
- if (status->str < 1) status->str = 1;
- if (status->agi < 1) status->agi = 1;
- if (status->vit < 1) status->vit = 1;
- if (status->int_< 1) status->int_= 1;
- if (status->dex < 1) status->dex = 1;
- if (status->luk < 1) status->luk = 1;
-
- db->range2 = atoi(str[20]);
- db->range3 = atoi(str[21]);
- if (battle_config.view_range_rate != 100) {
- db->range2 = db->range2 * battle_config.view_range_rate / 100;
- if (db->range2 < 1)
- db->range2 = 1;
- }
- if (battle_config.chase_range_rate != 100) {
- db->range3 = db->range3 * battle_config.chase_range_rate / 100;
- if (db->range3 < db->range2)
- db->range3 = db->range2;
- }
-
- status->size = atoi(str[22]);
- status->race = atoi(str[23]);
-
- i = atoi(str[24]); //Element
- status->def_ele = i%10;
- status->ele_lv = i/20;
- if (status->def_ele >= ELE_MAX) {
- ShowError("mob_parse_dbrow: Invalid element type %d for monster ID %d (max=%d).\n", status->def_ele, class_, ELE_MAX-1);
- return false;
- }
- if (status->ele_lv < 1 || status->ele_lv > 4) {
- ShowError("mob_parse_dbrow: Invalid element level %d for monster ID %d, must be in range 1-4.\n", status->ele_lv, class_);
- return false;
- }
-
- status->mode = (int)strtol(str[25], NULL, 0);
- if (!battle_config.monster_active_enable)
- status->mode &= ~MD_AGGRESSIVE;
-
- status->speed = atoi(str[26]);
- status->aspd_rate = 1000;
- i = atoi(str[27]);
- status->adelay = cap_value(i, battle_config.monster_max_aspd*2, 4000);
- i = atoi(str[28]);
- status->amotion = cap_value(i, battle_config.monster_max_aspd, 2000);
- //If the attack animation is longer than the delay, the client crops the attack animation!
- //On aegis there is no real visible effect of having a recharge-time less than amotion anyway.
- if (status->adelay < status->amotion)
- status->adelay = status->amotion;
- status->dmotion = atoi(str[29]);
- if (battle_config.monster_damage_delay_rate != 100)
- status->dmotion = status->dmotion * battle_config.monster_damage_delay_rate / 100;
-
- // Fill in remaining status data by using a dummy monster.
- data.bl.type = BL_MOB;
- data.level = db->lv;
- memcpy(&data.status, status, sizeof(struct status_data));
- status_calc_misc(&data.bl, status, db->lv);
-
- // MVP EXP Bonus: MEXP
- // Some new MVP's MEXP multipled by high exp-rate cause overflow. [LuzZza]
- exp = (double)atoi(str[30]) * (double)battle_config.mvp_exp_rate / 100.;
- db->mexp = (unsigned int)cap_value(exp, 0, UINT_MAX);
-
- //Now that we know if it is an mvp or not, apply battle_config modifiers [Skotlex]
- maxhp = (double)status->max_hp;
- if (db->mexp > 0) { //Mvp
- if (battle_config.mvp_hp_rate != 100)
- maxhp = maxhp * (double)battle_config.mvp_hp_rate / 100.;
- } else //Normal mob
- if (battle_config.monster_hp_rate != 100)
- maxhp = maxhp * (double)battle_config.monster_hp_rate / 100.;
-
- status->max_hp = (unsigned int)cap_value(maxhp, 1, UINT_MAX);
- if (status->max_sp < 1) status->max_sp = 1;
-
- //Since mobs always respawn with full life...
- status->hp = status->max_hp;
- status->sp = status->max_sp;
-
- // MVP Drops: MVP1id,MVP1per,MVP2id,MVP2per,MVP3id,MVP3per
- for (i = 0; i < MAX_MVP_DROP; i++) {
- struct item_data *id;
- int rate_adjust = battle_config.item_rate_mvp;;
- db->mvpitem[i].nameid = atoi(str[31+i*2]);
- if (!db->mvpitem[i].nameid) {
- db->mvpitem[i].p = 0; //No item....
- continue;
- }
- item_dropratio_adjust(db->mvpitem[i].nameid, class_, &rate_adjust);
- db->mvpitem[i].p = mob_drop_adjust(atoi(str[32+i*2]), rate_adjust, battle_config.item_drop_mvp_min, battle_config.item_drop_mvp_max);
-
- //calculate and store Max available drop chance of the MVP item
- if (db->mvpitem[i].p) {
- id = itemdb_search(db->mvpitem[i].nameid);
- if (id->maxchance == -1 || (id->maxchance < db->mvpitem[i].p/10 + 1)) {
- //item has bigger drop chance or sold in shops
- id->maxchance = db->mvpitem[i].p/10 + 1; //reduce MVP drop info to not spoil common drop rate
- }
- }
- }
-
- for (i = 0; i < MAX_MOB_DROP; i++) {
- int rate = 0, rate_adjust, type;
- unsigned short ratemin, ratemax;
- struct item_data *id;
- k = 31 + MAX_MVP_DROP*2 + i*2;
- db->dropitem[i].nameid = atoi(str[k]);
- if (!db->dropitem[i].nameid) {
- db->dropitem[i].p = 0; //No drop.
- continue;
- }
- id = itemdb_search(db->dropitem[i].nameid);
- type = id->type;
- rate = atoi(str[k+1]);
- if ((class_ >= 1324 && class_ <= 1363) || (class_ >= 1938 && class_ <= 1946)) {
- //Treasure box drop rates [Skotlex]
- rate_adjust = battle_config.item_rate_treasure;
- ratemin = battle_config.item_drop_treasure_min;
- ratemax = battle_config.item_drop_treasure_max;
- } else switch (type) {
- // Added suport to restrict normal drops of MVP's [Reddozen]
- case IT_HEALING:
- rate_adjust = (status->mode&MD_BOSS) ? battle_config.item_rate_heal_boss : battle_config.item_rate_heal;
- ratemin = battle_config.item_drop_heal_min;
- ratemax = battle_config.item_drop_heal_max;
- break;
- case IT_USABLE:
- case IT_CASH:
- rate_adjust = (status->mode&MD_BOSS) ? battle_config.item_rate_use_boss : battle_config.item_rate_use;
- ratemin = battle_config.item_drop_use_min;
- ratemax = battle_config.item_drop_use_max;
- break;
- case IT_WEAPON:
- case IT_ARMOR:
- case IT_PETARMOR:
- rate_adjust = (status->mode&MD_BOSS) ? battle_config.item_rate_equip_boss : battle_config.item_rate_equip;
- ratemin = battle_config.item_drop_equip_min;
- ratemax = battle_config.item_drop_equip_max;
- break;
- case IT_CARD:
- rate_adjust = (status->mode&MD_BOSS) ? battle_config.item_rate_card_boss : battle_config.item_rate_card;
- ratemin = battle_config.item_drop_card_min;
- ratemax = battle_config.item_drop_card_max;
- break;
- default:
- rate_adjust = (status->mode&MD_BOSS) ? battle_config.item_rate_common_boss : battle_config.item_rate_common;
- ratemin = battle_config.item_drop_common_min;
- ratemax = battle_config.item_drop_common_max;
- break;
- }
- item_dropratio_adjust(id->nameid, class_, &rate_adjust);
- db->dropitem[i].p = mob_drop_adjust(rate, rate_adjust, ratemin, ratemax);
-
- //calculate and store Max available drop chance of the item
- if (db->dropitem[i].p && (class_ < 1324 || class_ > 1363) && (class_ < 1938 || class_ > 1946)) {
- //Skip treasure chests.
- if (id->maxchance == -1 || (id->maxchance < db->dropitem[i].p)) {
- id->maxchance = db->dropitem[i].p; //item has bigger drop chance or sold in shops
- }
- for (k = 0; k< MAX_SEARCH; k++) {
- if (id->mob[k].chance <= db->dropitem[i].p)
- break;
- }
- if (k == MAX_SEARCH)
- continue;
-
- if (id->mob[k].id != class_)
- memmove(&id->mob[k+1], &id->mob[k], (MAX_SEARCH-k-1)*sizeof(id->mob[0]));
- id->mob[k].chance = db->dropitem[i].p;
- id->mob[k].id = class_;
- }
- }
-
- // Finally insert monster's data into the database.
- if (mob_db_data[class_] == NULL)
- mob_db_data[class_] = (struct mob_db *)aCalloc(1, sizeof(struct mob_db));
- else
- //Copy over spawn data
- memcpy(&db->spawn, mob_db_data[class_]->spawn, sizeof(db->spawn));
-
- memcpy(mob_db_data[class_], db, sizeof(struct mob_db));
- return true;
+ struct mob_db *db, entry;
+ struct status_data *status;
+ int class_, i, k;
+ double exp, maxhp;
+ struct mob_data data;
+
+ class_ = atoi(str[0]);
+
+ if (class_ <= 1000 || class_ > MAX_MOB_DB) {
+ ShowError("mob_parse_dbrow: Invalid monster ID %d, must be in range %d-%d.\n", class_, 1000, MAX_MOB_DB);
+ return false;
+ }
+ if (pcdb_checkid(class_)) {
+ ShowError("mob_parse_dbrow: Invalid monster ID %d, reserved for player classes.\n", class_);
+ return false;
+ }
+
+ if (class_ >= MOB_CLONE_START && class_ < MOB_CLONE_END) {
+ ShowError("mob_parse_dbrow: Invalid monster ID %d. Range %d-%d is reserved for player clones. Please increase MAX_MOB_DB (%d).\n", class_, MOB_CLONE_START, MOB_CLONE_END-1, MAX_MOB_DB);
+ return false;
+ }
+
+ memset(&entry, 0, sizeof(entry));
+
+ db = &entry;
+ status = &db->status;
+
+ db->vd.class_ = class_;
+ safestrncpy(db->sprite, str[1], sizeof(db->sprite));
+ safestrncpy(db->jname, str[2], sizeof(db->jname));
+ safestrncpy(db->name, str[3], sizeof(db->name));
+ db->lv = atoi(str[4]);
+ db->lv = cap_value(db->lv, 1, USHRT_MAX);
+ status->max_hp = atoi(str[5]);
+ status->max_sp = atoi(str[6]);
+
+ exp = (double)atoi(str[7]) * (double)battle_config.base_exp_rate / 100.;
+ db->base_exp = (unsigned int)cap_value(exp, 0, UINT_MAX);
+
+ exp = (double)atoi(str[8]) * (double)battle_config.job_exp_rate / 100.;
+ db->job_exp = (unsigned int)cap_value(exp, 0, UINT_MAX);
+
+ status->rhw.range = atoi(str[9]);
+ status->rhw.atk = atoi(str[10]);
+ status->rhw.atk2 = atoi(str[11]);
+ status->def = atoi(str[12]);
+ status->mdef = atoi(str[13]);
+ status->str = atoi(str[14]);
+ status->agi = atoi(str[15]);
+ status->vit = atoi(str[16]);
+ status->int_ = atoi(str[17]);
+ status->dex = atoi(str[18]);
+ status->luk = atoi(str[19]);
+ //All status should be min 1 to prevent divisions by zero from some skills. [Skotlex]
+ if (status->str < 1) status->str = 1;
+ if (status->agi < 1) status->agi = 1;
+ if (status->vit < 1) status->vit = 1;
+ if (status->int_< 1) status->int_= 1;
+ if (status->dex < 1) status->dex = 1;
+ if (status->luk < 1) status->luk = 1;
+
+ db->range2 = atoi(str[20]);
+ db->range3 = atoi(str[21]);
+ if (battle_config.view_range_rate != 100) {
+ db->range2 = db->range2 * battle_config.view_range_rate / 100;
+ if (db->range2 < 1)
+ db->range2 = 1;
+ }
+ if (battle_config.chase_range_rate != 100) {
+ db->range3 = db->range3 * battle_config.chase_range_rate / 100;
+ if (db->range3 < db->range2)
+ db->range3 = db->range2;
+ }
+
+ status->size = atoi(str[22]);
+ status->race = atoi(str[23]);
+
+ i = atoi(str[24]); //Element
+ status->def_ele = i%10;
+ status->ele_lv = i/20;
+ if (status->def_ele >= ELE_MAX) {
+ ShowError("mob_parse_dbrow: Invalid element type %d for monster ID %d (max=%d).\n", status->def_ele, class_, ELE_MAX-1);
+ return false;
+ }
+ if (status->ele_lv < 1 || status->ele_lv > 4) {
+ ShowError("mob_parse_dbrow: Invalid element level %d for monster ID %d, must be in range 1-4.\n", status->ele_lv, class_);
+ return false;
+ }
+
+ status->mode = (int)strtol(str[25], NULL, 0);
+ if (!battle_config.monster_active_enable)
+ status->mode &= ~MD_AGGRESSIVE;
+
+ status->speed = atoi(str[26]);
+ status->aspd_rate = 1000;
+ i = atoi(str[27]);
+ status->adelay = cap_value(i, battle_config.monster_max_aspd*2, 4000);
+ i = atoi(str[28]);
+ status->amotion = cap_value(i, battle_config.monster_max_aspd, 2000);
+ //If the attack animation is longer than the delay, the client crops the attack animation!
+ //On aegis there is no real visible effect of having a recharge-time less than amotion anyway.
+ if (status->adelay < status->amotion)
+ status->adelay = status->amotion;
+ status->dmotion = atoi(str[29]);
+ if(battle_config.monster_damage_delay_rate != 100)
+ status->dmotion = status->dmotion * battle_config.monster_damage_delay_rate / 100;
+
+ // Fill in remaining status data by using a dummy monster.
+ data.bl.type = BL_MOB;
+ data.level = db->lv;
+ memcpy(&data.status, status, sizeof(struct status_data));
+ status_calc_misc(&data.bl, status, db->lv);
+
+ // MVP EXP Bonus: MEXP
+ // Some new MVP's MEXP multipled by high exp-rate cause overflow. [LuzZza]
+ exp = (double)atoi(str[30]) * (double)battle_config.mvp_exp_rate / 100.;
+ db->mexp = (unsigned int)cap_value(exp, 0, UINT_MAX);
+
+ //Now that we know if it is an mvp or not, apply battle_config modifiers [Skotlex]
+ maxhp = (double)status->max_hp;
+ if (db->mexp > 0) { //Mvp
+ if (battle_config.mvp_hp_rate != 100)
+ maxhp = maxhp * (double)battle_config.mvp_hp_rate / 100.;
+ } else //Normal mob
+ if (battle_config.monster_hp_rate != 100)
+ maxhp = maxhp * (double)battle_config.monster_hp_rate / 100.;
+
+ status->max_hp = (unsigned int)cap_value(maxhp, 1, UINT_MAX);
+ if(status->max_sp < 1) status->max_sp = 1;
+
+ //Since mobs always respawn with full life...
+ status->hp = status->max_hp;
+ status->sp = status->max_sp;
+
+ // MVP Drops: MVP1id,MVP1per,MVP2id,MVP2per,MVP3id,MVP3per
+ for(i = 0; i < MAX_MVP_DROP; i++) {
+ struct item_data *id;
+ int rate_adjust = battle_config.item_rate_mvp;;
+ db->mvpitem[i].nameid = atoi(str[31+i*2]);
+ if (!db->mvpitem[i].nameid) {
+ db->mvpitem[i].p = 0; //No item....
+ continue;
+ }
+ item_dropratio_adjust(db->mvpitem[i].nameid, class_, &rate_adjust);
+ db->mvpitem[i].p = mob_drop_adjust(atoi(str[32+i*2]), rate_adjust, battle_config.item_drop_mvp_min, battle_config.item_drop_mvp_max);
+
+ //calculate and store Max available drop chance of the MVP item
+ if (db->mvpitem[i].p) {
+ id = itemdb_search(db->mvpitem[i].nameid);
+ if (id->maxchance == -1 || (id->maxchance < db->mvpitem[i].p/10 + 1) ) {
+ //item has bigger drop chance or sold in shops
+ id->maxchance = db->mvpitem[i].p/10 + 1; //reduce MVP drop info to not spoil common drop rate
+ }
+ }
+ }
+
+ for(i = 0; i < MAX_MOB_DROP; i++) {
+ int rate = 0, rate_adjust, type;
+ unsigned short ratemin, ratemax;
+ struct item_data *id;
+ k = 31 + MAX_MVP_DROP*2 + i*2;
+ db->dropitem[i].nameid = atoi(str[k]);
+ if (!db->dropitem[i].nameid) {
+ db->dropitem[i].p = 0; //No drop.
+ continue;
+ }
+ id = itemdb_search(db->dropitem[i].nameid);
+ type = id->type;
+ rate = atoi(str[k+1]);
+ if( (class_ >= 1324 && class_ <= 1363) || (class_ >= 1938 && class_ <= 1946) )
+ { //Treasure box drop rates [Skotlex]
+ rate_adjust = battle_config.item_rate_treasure;
+ ratemin = battle_config.item_drop_treasure_min;
+ ratemax = battle_config.item_drop_treasure_max;
+ }
+ else switch (type)
+ { // Added suport to restrict normal drops of MVP's [Reddozen]
+ case IT_HEALING:
+ rate_adjust = (status->mode&MD_BOSS) ? battle_config.item_rate_heal_boss : battle_config.item_rate_heal;
+ ratemin = battle_config.item_drop_heal_min;
+ ratemax = battle_config.item_drop_heal_max;
+ break;
+ case IT_USABLE:
+ case IT_CASH:
+ rate_adjust = (status->mode&MD_BOSS) ? battle_config.item_rate_use_boss : battle_config.item_rate_use;
+ ratemin = battle_config.item_drop_use_min;
+ ratemax = battle_config.item_drop_use_max;
+ break;
+ case IT_WEAPON:
+ case IT_ARMOR:
+ case IT_PETARMOR:
+ rate_adjust = (status->mode&MD_BOSS) ? battle_config.item_rate_equip_boss : battle_config.item_rate_equip;
+ ratemin = battle_config.item_drop_equip_min;
+ ratemax = battle_config.item_drop_equip_max;
+ break;
+ case IT_CARD:
+ rate_adjust = (status->mode&MD_BOSS) ? battle_config.item_rate_card_boss : battle_config.item_rate_card;
+ ratemin = battle_config.item_drop_card_min;
+ ratemax = battle_config.item_drop_card_max;
+ break;
+ default:
+ rate_adjust = (status->mode&MD_BOSS) ? battle_config.item_rate_common_boss : battle_config.item_rate_common;
+ ratemin = battle_config.item_drop_common_min;
+ ratemax = battle_config.item_drop_common_max;
+ break;
+ }
+ item_dropratio_adjust(id->nameid, class_, &rate_adjust);
+ db->dropitem[i].p = mob_drop_adjust(rate, rate_adjust, ratemin, ratemax);
+
+ //calculate and store Max available drop chance of the item
+ if( db->dropitem[i].p && (class_ < 1324 || class_ > 1363) && (class_ < 1938 || class_ > 1946) )
+ { //Skip treasure chests.
+ if (id->maxchance == -1 || (id->maxchance < db->dropitem[i].p) ) {
+ id->maxchance = db->dropitem[i].p; //item has bigger drop chance or sold in shops
+ }
+ for (k = 0; k< MAX_SEARCH; k++) {
+ if (id->mob[k].chance <= db->dropitem[i].p)
+ break;
+ }
+ if (k == MAX_SEARCH)
+ continue;
+
+ if (id->mob[k].id != class_)
+ memmove(&id->mob[k+1], &id->mob[k], (MAX_SEARCH-k-1)*sizeof(id->mob[0]));
+ id->mob[k].chance = db->dropitem[i].p;
+ id->mob[k].id = class_;
+ }
+ }
+
+ // Finally insert monster's data into the database.
+ if (mob_db_data[class_] == NULL)
+ mob_db_data[class_] = (struct mob_db*)aCalloc(1, sizeof(struct mob_db));
+ else
+ //Copy over spawn data
+ memcpy(&db->spawn, mob_db_data[class_]->spawn, sizeof(db->spawn));
+
+ memcpy(mob_db_data[class_], db, sizeof(struct mob_db));
+ return true;
}
/*==========================================
* mob_db.txt reading
*------------------------------------------*/
-static bool mob_readdb_sub(char *fields[], int columns, int current)
+static bool mob_readdb_sub(char* fields[], int columns, int current)
{
- return mob_parse_dbrow(fields);
+ return mob_parse_dbrow(fields);
}
static void mob_readdb(void)
{
- const char *filename[] = {
- DBPATH"mob_db.txt",
- "mob_db2.txt"
- };
- int fi;
-
- for (fi = 0; fi < ARRAYLENGTH(filename); ++fi) {
- char path[256];
-
- if (fi > 0) {
- sprintf(path, "%s/%s", db_path, filename[fi]);
- if (!exists(path)) {
- continue;
- }
- }
-
- sv_readdb(db_path, filename[fi], ',', 31+2*MAX_MVP_DROP+2*MAX_MOB_DROP, 31+2*MAX_MVP_DROP+2*MAX_MOB_DROP, -1, &mob_readdb_sub);
- }
+ const char* filename[] = {
+ DBPATH"mob_db.txt",
+ "mob_db2.txt" };
+ int fi;
+
+ for( fi = 0; fi < ARRAYLENGTH(filename); ++fi )
+ {
+ char path[256];
+
+ if(fi > 0)
+ {
+ sprintf(path, "%s/%s", db_path, filename[fi]);
+ if(!exists(path))
+ {
+ continue;
+ }
+ }
+
+ sv_readdb(db_path, filename[fi], ',', 31+2*MAX_MVP_DROP+2*MAX_MOB_DROP, 31+2*MAX_MVP_DROP+2*MAX_MOB_DROP, -1, &mob_readdb_sub);
+ }
}
/*==========================================
@@ -3849,88 +3912,91 @@ static void mob_readdb(void)
*------------------------------------------*/
static int mob_read_sqldb(void)
{
- const char *mob_db_name[] = { mob_db_db, mob_db2_db };
- int fi;
-
- for (fi = 0; fi < ARRAYLENGTH(mob_db_name); ++fi) {
- uint32 lines = 0, count = 0;
-
- // retrieve all rows from the mob database
- if (SQL_ERROR == Sql_Query(mmysql_handle, "SELECT * FROM `%s`", mob_db_name[fi])) {
- Sql_ShowDebug(mmysql_handle);
- continue;
- }
-
- // process rows one by one
- while (SQL_SUCCESS == Sql_NextRow(mmysql_handle)) {
- // wrap the result into a TXT-compatible format
- char line[1024];
- char *str[31+2*MAX_MVP_DROP+2*MAX_MOB_DROP];
- char *p;
- int i;
-
- lines++;
- for (i = 0, p = line; i < 31+2*MAX_MVP_DROP+2*MAX_MOB_DROP; i++) {
- char *data;
- size_t len;
- Sql_GetData(mmysql_handle, i, &data, &len);
-
- strcpy(p, data);
- str[i] = p;
- p+= len + 1;
- }
-
- if (!mob_parse_dbrow(str))
- continue;
-
- count++;
- }
-
- // free the query result
- Sql_FreeResult(mmysql_handle);
-
- ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, mob_db_name[fi]);
- }
- return 0;
+ const char* mob_db_name[] = { mob_db_db, mob_db2_db };
+ int fi;
+
+ for( fi = 0; fi < ARRAYLENGTH(mob_db_name); ++fi ) {
+ uint32 lines = 0, count = 0;
+
+ // retrieve all rows from the mob database
+ if( SQL_ERROR == Sql_Query(mmysql_handle, "SELECT * FROM `%s`", mob_db_name[fi]) ) {
+ Sql_ShowDebug(mmysql_handle);
+ continue;
+ }
+
+ // process rows one by one
+ while( SQL_SUCCESS == Sql_NextRow(mmysql_handle) ) {
+ // wrap the result into a TXT-compatible format
+ char line[1024];
+ char* str[31+2*MAX_MVP_DROP+2*MAX_MOB_DROP];
+ char* p;
+ int i;
+
+ lines++;
+ for(i = 0, p = line; i < 31+2*MAX_MVP_DROP+2*MAX_MOB_DROP; i++)
+ {
+ char* data;
+ size_t len;
+ Sql_GetData(mmysql_handle, i, &data, &len);
+
+ strcpy(p, data);
+ str[i] = p;
+ p+= len + 1;
+ }
+
+ if (!mob_parse_dbrow(str))
+ continue;
+
+ count++;
+ }
+
+ // free the query result
+ Sql_FreeResult(mmysql_handle);
+
+ ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, mob_db_name[fi]);
+ }
+ return 0;
}
/*==========================================
* MOB display graphic change data reading
*------------------------------------------*/
-static bool mob_readdb_mobavail(char *str[], int columns, int current)
+static bool mob_readdb_mobavail(char* str[], int columns, int current)
{
- int class_, k;
-
- class_=atoi(str[0]);
-
- if (mob_db(class_) == mob_dummy) { // invalid class (probably undefined in db)
- ShowWarning("mob_readdb_mobavail: Unknown mob id %d.\n", class_);
- return false;
- }
-
- k=atoi(str[1]);
-
- memset(&mob_db_data[class_]->vd, 0, sizeof(struct view_data));
- mob_db_data[class_]->vd.class_=k;
-
- //Player sprites
- if (pcdb_checkid(k) && columns==12) {
- mob_db_data[class_]->vd.sex=atoi(str[2]);
- mob_db_data[class_]->vd.hair_style=atoi(str[3]);
- mob_db_data[class_]->vd.hair_color=atoi(str[4]);
- mob_db_data[class_]->vd.weapon=atoi(str[5]);
- mob_db_data[class_]->vd.shield=atoi(str[6]);
- mob_db_data[class_]->vd.head_top=atoi(str[7]);
- mob_db_data[class_]->vd.head_mid=atoi(str[8]);
- mob_db_data[class_]->vd.head_bottom=atoi(str[9]);
- mob_db_data[class_]->option=atoi(str[10])&~(OPTION_HIDE|OPTION_CLOAK|OPTION_INVISIBLE);
- mob_db_data[class_]->vd.cloth_color=atoi(str[11]); // Monster player dye option - Valaris
- } else if (columns==3)
- mob_db_data[class_]->vd.head_bottom=atoi(str[2]); // mob equipment [Valaris]
- else if (columns != 2)
- return false;
-
- return true;
+ int class_, k;
+
+ class_=atoi(str[0]);
+
+ if(mob_db(class_) == mob_dummy) // invalid class (probably undefined in db)
+ {
+ ShowWarning("mob_readdb_mobavail: Unknown mob id %d.\n", class_);
+ return false;
+ }
+
+ k=atoi(str[1]);
+
+ memset(&mob_db_data[class_]->vd, 0, sizeof(struct view_data));
+ mob_db_data[class_]->vd.class_=k;
+
+ //Player sprites
+ if(pcdb_checkid(k) && columns==12) {
+ mob_db_data[class_]->vd.sex=atoi(str[2]);
+ mob_db_data[class_]->vd.hair_style=atoi(str[3]);
+ mob_db_data[class_]->vd.hair_color=atoi(str[4]);
+ mob_db_data[class_]->vd.weapon=atoi(str[5]);
+ mob_db_data[class_]->vd.shield=atoi(str[6]);
+ mob_db_data[class_]->vd.head_top=atoi(str[7]);
+ mob_db_data[class_]->vd.head_mid=atoi(str[8]);
+ mob_db_data[class_]->vd.head_bottom=atoi(str[9]);
+ mob_db_data[class_]->option=atoi(str[10])&~(OPTION_HIDE|OPTION_CLOAK|OPTION_INVISIBLE);
+ mob_db_data[class_]->vd.cloth_color=atoi(str[11]); // Monster player dye option - Valaris
+ }
+ else if(columns==3)
+ mob_db_data[class_]->vd.head_bottom=atoi(str[2]); // mob equipment [Valaris]
+ else if( columns != 2 )
+ return false;
+
+ return true;
}
/*==========================================
@@ -3938,119 +4004,124 @@ static bool mob_readdb_mobavail(char *str[], int columns, int current)
*------------------------------------------*/
static int mob_read_randommonster(void)
{
- FILE *fp;
- char line[1024];
- char *str[10],*p;
- int i,j;
- const char *mobfile[] = {
- DBPATH"mob_branch.txt",
- DBPATH"mob_poring.txt",
- DBPATH"mob_boss.txt",
- "mob_pouch.txt",
- "mob_classchange.txt"
- };
-
- memset(&summon, 0, sizeof(summon));
-
- for (i = 0; i < ARRAYLENGTH(mobfile) && i < MAX_RANDOMMONSTER; i++) {
- mob_db_data[0]->summonper[i] = 1002; // Default fallback value, in case the database does not provide one
- sprintf(line, "%s/%s", db_path, mobfile[i]);
- fp=fopen(line,"r");
- if (fp==NULL) {
- ShowError("can't read %s\n",line);
- return -1;
- }
- while (fgets(line, sizeof(line), fp)) {
- int class_;
- if (line[0] == '/' && line[1] == '/')
- continue;
- memset(str,0,sizeof(str));
- for (j=0,p=line; j<3 && p; j++) {
- str[j]=p;
- p=strchr(p,',');
- if (p) *p++=0;
- }
-
- if (str[0]==NULL || str[2]==NULL)
- continue;
-
- class_ = atoi(str[0]);
- if (mob_db(class_) == mob_dummy)
- continue;
- mob_db_data[class_]->summonper[i]=atoi(str[2]);
- if (i) {
- if (summon[i].qty < ARRAYLENGTH(summon[i].class_)) //MvPs
- summon[i].class_[summon[i].qty++] = class_;
- else {
- ShowDebug("Can't store more random mobs from %s, increase size of mob.c:summon variable!\n", mobfile[i]);
- break;
- }
- }
- }
- if (i && !summon[i].qty) {
- //At least have the default here.
- summon[i].class_[0] = mob_db_data[0]->summonper[i];
- summon[i].qty = 1;
- }
- fclose(fp);
- ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n",mobfile[i]);
- }
- return 0;
+ FILE *fp;
+ char line[1024];
+ char *str[10],*p;
+ int i,j;
+ const char* mobfile[] = {
+ DBPATH"mob_branch.txt",
+ DBPATH"mob_poring.txt",
+ DBPATH"mob_boss.txt",
+ "mob_pouch.txt",
+ "mob_classchange.txt"};
+
+ memset(&summon, 0, sizeof(summon));
+
+ for( i = 0; i < ARRAYLENGTH(mobfile) && i < MAX_RANDOMMONSTER; i++ )
+ {
+ mob_db_data[0]->summonper[i] = 1002; // Default fallback value, in case the database does not provide one
+ sprintf(line, "%s/%s", db_path, mobfile[i]);
+ fp=fopen(line,"r");
+ if(fp==NULL){
+ ShowError("can't read %s\n",line);
+ return -1;
+ }
+ while(fgets(line, sizeof(line), fp))
+ {
+ int class_;
+ if(line[0] == '/' && line[1] == '/')
+ continue;
+ memset(str,0,sizeof(str));
+ for(j=0,p=line;j<3 && p;j++){
+ str[j]=p;
+ p=strchr(p,',');
+ if(p) *p++=0;
+ }
+
+ if(str[0]==NULL || str[2]==NULL)
+ continue;
+
+ class_ = atoi(str[0]);
+ if(mob_db(class_) == mob_dummy)
+ continue;
+ mob_db_data[class_]->summonper[i]=atoi(str[2]);
+ if (i) {
+ if( summon[i].qty < ARRAYLENGTH(summon[i].class_) ) //MvPs
+ summon[i].class_[summon[i].qty++] = class_;
+ else {
+ ShowDebug("Can't store more random mobs from %s, increase size of mob.c:summon variable!\n", mobfile[i]);
+ break;
+ }
+ }
+ }
+ if (i && !summon[i].qty)
+ { //At least have the default here.
+ summon[i].class_[0] = mob_db_data[0]->summonper[i];
+ summon[i].qty = 1;
+ }
+ fclose(fp);
+ ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n",mobfile[i]);
+ }
+ return 0;
}
/*==========================================
* processes one mob_chat_db entry [SnakeDrak]
* @param last_msg_id ensures that only one error message per mob id is printed
*------------------------------------------*/
-static bool mob_parse_row_chatdb(char **str, const char *source, int line, int *last_msg_id)
+static bool mob_parse_row_chatdb(char** str, const char* source, int line, int* last_msg_id)
{
- char *msg;
- struct mob_chat *ms;
- int msg_id;
- size_t len;
-
- msg_id = atoi(str[0]);
-
- if (msg_id <= 0 || msg_id > MAX_MOB_CHAT) {
- if (msg_id != *last_msg_id) {
- ShowError("mob_chat: Invalid chat ID: %d at %s, line %d\n", msg_id, source, line);
- *last_msg_id = msg_id;
- }
- return false;
- }
-
- if (mob_chat_db[msg_id] == NULL)
- mob_chat_db[msg_id] = (struct mob_chat *)aCalloc(1, sizeof(struct mob_chat));
-
- ms = mob_chat_db[msg_id];
- //MSG ID
- ms->msg_id=msg_id;
- //Color
- ms->color=strtoul(str[1],NULL,0);
- //Message
- msg = str[2];
- len = strlen(msg);
-
- while (len && (msg[len-1]=='\r' || msg[len-1]=='\n')) {
- // find EOL to strip
- len--;
- }
-
- if (len>(CHAT_SIZE_MAX-1)) {
- if (msg_id != *last_msg_id) {
- ShowError("mob_chat: readdb: Message too long! Line %d, id: %d\n", line, msg_id);
- *last_msg_id = msg_id;
- }
- return false;
- } else if (!len) {
- ShowWarning("mob_parse_row_chatdb: Empty message for id %d.\n", msg_id);
- return false;
- }
-
- msg[len] = 0; // strip previously found EOL
- strncpy(ms->msg, str[2], CHAT_SIZE_MAX);
-
- return true;
+ char* msg;
+ struct mob_chat *ms;
+ int msg_id;
+ size_t len;
+
+ msg_id = atoi(str[0]);
+
+ if (msg_id <= 0 || msg_id > MAX_MOB_CHAT)
+ {
+ if (msg_id != *last_msg_id) {
+ ShowError("mob_chat: Invalid chat ID: %d at %s, line %d\n", msg_id, source, line);
+ *last_msg_id = msg_id;
+ }
+ return false;
+ }
+
+ if (mob_chat_db[msg_id] == NULL)
+ mob_chat_db[msg_id] = (struct mob_chat*)aCalloc(1, sizeof (struct mob_chat));
+
+ ms = mob_chat_db[msg_id];
+ //MSG ID
+ ms->msg_id=msg_id;
+ //Color
+ ms->color=strtoul(str[1],NULL,0);
+ //Message
+ msg = str[2];
+ len = strlen(msg);
+
+ while( len && ( msg[len-1]=='\r' || msg[len-1]=='\n' ) )
+ {// find EOL to strip
+ len--;
+ }
+
+ if(len>(CHAT_SIZE_MAX-1))
+ {
+ if (msg_id != *last_msg_id) {
+ ShowError("mob_chat: readdb: Message too long! Line %d, id: %d\n", line, msg_id);
+ *last_msg_id = msg_id;
+ }
+ return false;
+ }
+ else if( !len )
+ {
+ ShowWarning("mob_parse_row_chatdb: Empty message for id %d.\n", msg_id);
+ return false;
+ }
+
+ msg[len] = 0; // strip previously found EOL
+ strncpy(ms->msg, str[2], CHAT_SIZE_MAX);
+
+ return true;
}
/*==========================================
@@ -4058,337 +4129,349 @@ static bool mob_parse_row_chatdb(char **str, const char *source, int line, int *
*-------------------------------------------------------------------------*/
static void mob_readchatdb(void)
{
- char arc[]="mob_chat_db.txt";
- uint32 lines=0, count=0;
- char line[1024], path[256];
- int i, tmp=0;
- FILE *fp;
- sprintf(path, "%s/%s", db_path, arc);
- fp=fopen(path, "r");
- if (fp == NULL) {
- ShowWarning("mob_readchatdb: File not found \"%s\", skipping.\n", path);
- return;
- }
-
- while (fgets(line, sizeof(line), fp)) {
- char *str[3], *p, *np;
- int j=0;
-
- lines++;
- if (line[0] == '/' && line[1] == '/')
- continue;
- memset(str, 0, sizeof(str));
-
- p=line;
- while (ISSPACE(*p))
- ++p;
- if (*p == '\0')
- continue;// empty line
- for (i = 0; i <= 2; i++) {
- str[i] = p;
- if (i<2 && (np = strchr(p, ',')) != NULL) {
- *np = '\0';
- p = np + 1;
- j++;
- }
- }
-
- if (j < 2 || str[2]==NULL) {
- ShowError("mob_readchatdb: Insufficient number of fields for skill at %s, line %d\n", arc, lines);
- continue;
- }
-
- if (!mob_parse_row_chatdb(str, path, lines, &tmp))
- continue;
-
- count++;
- }
- fclose(fp);
- ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n", arc);
+ char arc[]="mob_chat_db.txt";
+ uint32 lines=0, count=0;
+ char line[1024], path[256];
+ int i, tmp=0;
+ FILE *fp;
+ sprintf(path, "%s/%s", db_path, arc);
+ fp=fopen(path, "r");
+ if(fp == NULL)
+ {
+ ShowWarning("mob_readchatdb: File not found \"%s\", skipping.\n", path);
+ return;
+ }
+
+ while(fgets(line, sizeof(line), fp))
+ {
+ char *str[3], *p, *np;
+ int j=0;
+
+ lines++;
+ if(line[0] == '/' && line[1] == '/')
+ continue;
+ memset(str, 0, sizeof(str));
+
+ p=line;
+ while(ISSPACE(*p))
+ ++p;
+ if(*p == '\0')
+ continue;// empty line
+ for(i = 0; i <= 2; i++)
+ {
+ str[i] = p;
+ if(i<2 && (np = strchr(p, ',')) != NULL) {
+ *np = '\0'; p = np + 1; j++;
+ }
+ }
+
+ if( j < 2 || str[2]==NULL)
+ {
+ ShowError("mob_readchatdb: Insufficient number of fields for skill at %s, line %d\n", arc, lines);
+ continue;
+ }
+
+ if( !mob_parse_row_chatdb(str, path, lines, &tmp) )
+ continue;
+
+ count++;
+ }
+ fclose(fp);
+ ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n", arc);
}
/*==========================================
* processes one mob_skill_db entry
*------------------------------------------*/
-static bool mob_parse_row_mobskilldb(char **str, int columns, int current)
+static bool mob_parse_row_mobskilldb(char** str, int columns, int current)
{
- static const struct {
- char str[32];
- enum MobSkillState id;
- } state[] = {
- { "any", MSS_ANY }, //All states except Dead
- { "idle", MSS_IDLE },
- { "walk", MSS_WALK },
- { "loot", MSS_LOOT },
- { "dead", MSS_DEAD },
- { "attack", MSS_BERSERK }, //Retaliating attack
- { "angry", MSS_ANGRY }, //Preemptive attack (aggressive mobs)
- { "chase", MSS_RUSH }, //Chase escaping target
- { "follow", MSS_FOLLOW }, //Preemptive chase (aggressive mobs)
- { "anytarget",MSS_ANYTARGET }, //Berserk+Angry+Rush+Follow
- };
- static const struct {
- char str[32];
- int id;
- } cond1[] = {
- { "always", MSC_ALWAYS },
- { "myhpltmaxrate", MSC_MYHPLTMAXRATE },
- { "myhpinrate", MSC_MYHPINRATE },
- { "friendhpltmaxrate", MSC_FRIENDHPLTMAXRATE },
- { "friendhpinrate", MSC_FRIENDHPINRATE },
- { "mystatuson", MSC_MYSTATUSON },
- { "mystatusoff", MSC_MYSTATUSOFF },
- { "friendstatuson", MSC_FRIENDSTATUSON },
- { "friendstatusoff", MSC_FRIENDSTATUSOFF },
- { "attackpcgt", MSC_ATTACKPCGT },
- { "attackpcge", MSC_ATTACKPCGE },
- { "slavelt", MSC_SLAVELT },
- { "slavele", MSC_SLAVELE },
- { "closedattacked", MSC_CLOSEDATTACKED },
- { "longrangeattacked", MSC_LONGRANGEATTACKED },
- { "skillused", MSC_SKILLUSED },
- { "afterskill", MSC_AFTERSKILL },
- { "casttargeted", MSC_CASTTARGETED },
- { "rudeattacked", MSC_RUDEATTACKED },
- { "masterhpltmaxrate", MSC_MASTERHPLTMAXRATE },
- { "masterattacked", MSC_MASTERATTACKED },
- { "alchemist", MSC_ALCHEMIST },
- { "onspawn", MSC_SPAWN },
- }, cond2[] = {
- { "anybad", -1 },
- { "stone", SC_STONE },
- { "freeze", SC_FREEZE },
- { "stun", SC_STUN },
- { "sleep", SC_SLEEP },
- { "poison", SC_POISON },
- { "curse", SC_CURSE },
- { "silence", SC_SILENCE },
- { "confusion", SC_CONFUSION },
- { "blind", SC_BLIND },
- { "hiding", SC_HIDING },
- { "sight", SC_SIGHT },
- }, target[] = {
- { "target", MST_TARGET },
- { "randomtarget", MST_RANDOM },
- { "self", MST_SELF },
- { "friend", MST_FRIEND },
- { "master", MST_MASTER },
- { "around5", MST_AROUND5 },
- { "around6", MST_AROUND6 },
- { "around7", MST_AROUND7 },
- { "around8", MST_AROUND8 },
- { "around1", MST_AROUND1 },
- { "around2", MST_AROUND2 },
- { "around3", MST_AROUND3 },
- { "around4", MST_AROUND4 },
- { "around", MST_AROUND },
- };
- static int last_mob_id = 0; // ensures that only one error message per mob id is printed
-
- struct mob_skill *ms, gms;
- int mob_id;
- int i =0, j, tmp;
-
- mob_id = atoi(str[0]);
-
- if (mob_id > 0 && mob_db(mob_id) == mob_dummy) {
- if (mob_id != last_mob_id) {
- ShowError("mob_parse_row_mobskilldb: Non existant Mob id %d\n", mob_id);
- last_mob_id = mob_id;
- }
- return false;
- }
- if (strcmp(str[1],"clear")==0) {
- if (mob_id < 0)
- return false;
- memset(mob_db_data[mob_id]->skill,0,sizeof(struct mob_skill));
- mob_db_data[mob_id]->maxskill=0;
- return true;
- }
-
- if (mob_id < 0) {
- //Prepare global skill. [Skotlex]
- memset(&gms, 0, sizeof(struct mob_skill));
- ms = &gms;
- } else {
- ARR_FIND(0, MAX_MOBSKILL, i, (ms = &mob_db_data[mob_id]->skill[i])->skill_id == 0);
- if (i == MAX_MOBSKILL) {
- if (mob_id != last_mob_id) {
- ShowError("mob_parse_row_mobskilldb: Too many skills for monster %d[%s]\n", mob_id, mob_db_data[mob_id]->sprite);
- last_mob_id = mob_id;
- }
- return false;
- }
- }
-
- //State
- ARR_FIND(0, ARRAYLENGTH(state), j, strcmp(str[2],state[j].str) == 0);
- if (j < ARRAYLENGTH(state))
- ms->state = state[j].id;
- else {
- ShowWarning("mob_parse_row_mobskilldb: Unrecognized state %s\n", str[2]);
- ms->state = MSS_ANY;
- }
-
- //Skill ID
- j=atoi(str[3]);
- if (j<=0 || j>MAX_SKILL_DB) { //fixed Lupus
- if (mob_id < 0)
- ShowError("mob_parse_row_mobskilldb: Invalid Skill ID (%d) for all mobs\n", j);
- else
- ShowError("mob_parse_row_mobskilldb: Invalid Skill ID (%d) for mob %d (%s)\n", j, mob_id, mob_db_data[mob_id]->sprite);
- return false;
- }
- ms->skill_id=j;
-
- //Skill lvl
- j= atoi(str[4])<=0 ? 1 : atoi(str[4]);
- ms->skill_lv= j>battle_config.mob_max_skilllvl ? battle_config.mob_max_skilllvl : j; //we strip max skill level
-
- //Apply battle_config modifiers to rate (permillage) and delay [Skotlex]
- tmp = atoi(str[5]);
- if (battle_config.mob_skill_rate != 100)
- tmp = tmp*battle_config.mob_skill_rate/100;
- if (tmp > 10000)
- ms->permillage= 10000;
- else if (!tmp && battle_config.mob_skill_rate)
- ms->permillage= 1;
- else
- ms->permillage= tmp;
- ms->casttime=atoi(str[6]);
- ms->delay=atoi(str[7]);
- if (battle_config.mob_skill_delay != 100)
- ms->delay = ms->delay*battle_config.mob_skill_delay/100;
- if (ms->delay < 0 || ms->delay > MOB_MAX_DELAY) //time overflow?
- ms->delay = MOB_MAX_DELAY;
- ms->cancel=atoi(str[8]);
- if (strcmp(str[8],"yes")==0) ms->cancel=1;
-
- //Target
- ARR_FIND(0, ARRAYLENGTH(target), j, strcmp(str[9],target[j].str) == 0);
- if (j < ARRAYLENGTH(target))
- ms->target = target[j].id;
- else {
- ShowWarning("mob_parse_row_mobskilldb: Unrecognized target %s for %d\n", str[9], mob_id);
- ms->target = MST_TARGET;
- }
-
- //Check that the target condition is right for the skill type. [Skotlex]
- if (skill_get_casttype(ms->skill_id) == CAST_GROUND) {
- //Ground skill.
- if (ms->target > MST_AROUND) {
- ShowWarning("mob_parse_row_mobskilldb: Wrong mob skill target for ground skill %d (%s) for %s.\n",
- ms->skill_id, skill_get_name(ms->skill_id),
- mob_id < 0?"all mobs":mob_db_data[mob_id]->sprite);
- ms->target = MST_TARGET;
- }
- } else if (ms->target > MST_MASTER) {
- ShowWarning("mob_parse_row_mobskilldb: Wrong mob skill target 'around' for non-ground skill %d (%s) for %s.\n",
- ms->skill_id, skill_get_name(ms->skill_id),
- mob_id < 0?"all mobs":mob_db_data[mob_id]->sprite);
- ms->target = MST_TARGET;
- }
-
- //Cond1
- ARR_FIND(0, ARRAYLENGTH(cond1), j, strcmp(str[10],cond1[j].str) == 0);
- if (j < ARRAYLENGTH(cond1))
- ms->cond1 = cond1[j].id;
- else {
- ShowWarning("mob_parse_row_mobskilldb: Unrecognized condition 1 %s for %d\n", str[10], mob_id);
- ms->cond1 = -1;
- }
-
- //Cond2
- // numeric value
- ms->cond2 = atoi(str[11]);
- // or special constant
- ARR_FIND(0, ARRAYLENGTH(cond2), j, strcmp(str[11],cond2[j].str) == 0);
- if (j < ARRAYLENGTH(cond2))
- ms->cond2 = cond2[j].id;
-
- ms->val[0]=(int)strtol(str[12],NULL,0);
- ms->val[1]=(int)strtol(str[13],NULL,0);
- ms->val[2]=(int)strtol(str[14],NULL,0);
- ms->val[3]=(int)strtol(str[15],NULL,0);
- ms->val[4]=(int)strtol(str[16],NULL,0);
-
- if (ms->skill_id == NPC_EMOTION && mob_id>0 &&
- ms->val[1] == mob_db(mob_id)->status.mode) {
- ms->val[1] = 0;
- ms->val[4] = 1; //request to return mode to normal.
- }
- if (ms->skill_id == NPC_EMOTION_ON && mob_id>0 && ms->val[1]) {
- //Adds a mode to the mob.
- //Remove aggressive mode when the new mob type is passive.
- if (!(ms->val[1]&MD_AGGRESSIVE))
- ms->val[3]|=MD_AGGRESSIVE;
- ms->val[2]|= ms->val[1]; //Add the new mode.
- ms->val[1] = 0; //Do not "set" it.
- }
-
- if (*str[17])
- ms->emotion=atoi(str[17]);
- else
- ms->emotion=-1;
-
- if (str[18]!=NULL && mob_chat_db[atoi(str[18])]!=NULL)
- ms->msg_id=atoi(str[18]);
- else
- ms->msg_id=0;
-
- if (mob_id < 0) {
- //Set this skill to ALL mobs. [Skotlex]
- mob_id *= -1;
- for (i = 1; i < MAX_MOB_DB; i++) {
- if (mob_db_data[i] == NULL)
- continue;
- if (mob_db_data[i]->status.mode&MD_BOSS) {
- if (!(mob_id&2)) //Skill not for bosses
- continue;
- } else if (!(mob_id&1)) //Skill not for normal enemies.
- continue;
-
- ARR_FIND(0, MAX_MOBSKILL, j, mob_db_data[i]->skill[j].skill_id == 0);
- if (j==MAX_MOBSKILL)
- continue;
-
- memcpy(&mob_db_data[i]->skill[j], ms, sizeof(struct mob_skill));
- mob_db_data[i]->maxskill=j+1;
- }
- } else //Skill set on a single mob.
- mob_db_data[mob_id]->maxskill=i+1;
-
- return true;
+ static const struct {
+ char str[32];
+ enum MobSkillState id;
+ } state[] = {
+ { "any", MSS_ANY }, //All states except Dead
+ { "idle", MSS_IDLE },
+ { "walk", MSS_WALK },
+ { "loot", MSS_LOOT },
+ { "dead", MSS_DEAD },
+ { "attack", MSS_BERSERK }, //Retaliating attack
+ { "angry", MSS_ANGRY }, //Preemptive attack (aggressive mobs)
+ { "chase", MSS_RUSH }, //Chase escaping target
+ { "follow", MSS_FOLLOW }, //Preemptive chase (aggressive mobs)
+ { "anytarget",MSS_ANYTARGET }, //Berserk+Angry+Rush+Follow
+ };
+ static const struct {
+ char str[32];
+ int id;
+ } cond1[] = {
+ { "always", MSC_ALWAYS },
+ { "myhpltmaxrate", MSC_MYHPLTMAXRATE },
+ { "myhpinrate", MSC_MYHPINRATE },
+ { "friendhpltmaxrate", MSC_FRIENDHPLTMAXRATE },
+ { "friendhpinrate", MSC_FRIENDHPINRATE },
+ { "mystatuson", MSC_MYSTATUSON },
+ { "mystatusoff", MSC_MYSTATUSOFF },
+ { "friendstatuson", MSC_FRIENDSTATUSON },
+ { "friendstatusoff", MSC_FRIENDSTATUSOFF },
+ { "attackpcgt", MSC_ATTACKPCGT },
+ { "attackpcge", MSC_ATTACKPCGE },
+ { "slavelt", MSC_SLAVELT },
+ { "slavele", MSC_SLAVELE },
+ { "closedattacked", MSC_CLOSEDATTACKED },
+ { "longrangeattacked", MSC_LONGRANGEATTACKED },
+ { "skillused", MSC_SKILLUSED },
+ { "afterskill", MSC_AFTERSKILL },
+ { "casttargeted", MSC_CASTTARGETED },
+ { "rudeattacked", MSC_RUDEATTACKED },
+ { "masterhpltmaxrate", MSC_MASTERHPLTMAXRATE },
+ { "masterattacked", MSC_MASTERATTACKED },
+ { "alchemist", MSC_ALCHEMIST },
+ { "onspawn", MSC_SPAWN },
+ }, cond2[] ={
+ { "anybad", -1 },
+ { "stone", SC_STONE },
+ { "freeze", SC_FREEZE },
+ { "stun", SC_STUN },
+ { "sleep", SC_SLEEP },
+ { "poison", SC_POISON },
+ { "curse", SC_CURSE },
+ { "silence", SC_SILENCE },
+ { "confusion", SC_CONFUSION },
+ { "blind", SC_BLIND },
+ { "hiding", SC_HIDING },
+ { "sight", SC_SIGHT },
+ }, target[] = {
+ { "target", MST_TARGET },
+ { "randomtarget", MST_RANDOM },
+ { "self", MST_SELF },
+ { "friend", MST_FRIEND },
+ { "master", MST_MASTER },
+ { "around5", MST_AROUND5 },
+ { "around6", MST_AROUND6 },
+ { "around7", MST_AROUND7 },
+ { "around8", MST_AROUND8 },
+ { "around1", MST_AROUND1 },
+ { "around2", MST_AROUND2 },
+ { "around3", MST_AROUND3 },
+ { "around4", MST_AROUND4 },
+ { "around", MST_AROUND },
+ };
+ static int last_mob_id = 0; // ensures that only one error message per mob id is printed
+
+ struct mob_skill *ms, gms;
+ int mob_id;
+ int i =0, j, tmp;
+
+ mob_id = atoi(str[0]);
+
+ if (mob_id > 0 && mob_db(mob_id) == mob_dummy)
+ {
+ if (mob_id != last_mob_id) {
+ ShowError("mob_parse_row_mobskilldb: Non existant Mob id %d\n", mob_id);
+ last_mob_id = mob_id;
+ }
+ return false;
+ }
+ if( strcmp(str[1],"clear")==0 ){
+ if (mob_id < 0)
+ return false;
+ memset(mob_db_data[mob_id]->skill,0,sizeof(struct mob_skill));
+ mob_db_data[mob_id]->maxskill=0;
+ return true;
+ }
+
+ if (mob_id < 0)
+ { //Prepare global skill. [Skotlex]
+ memset(&gms, 0, sizeof (struct mob_skill));
+ ms = &gms;
+ } else {
+ ARR_FIND( 0, MAX_MOBSKILL, i, (ms = &mob_db_data[mob_id]->skill[i])->skill_id == 0 );
+ if( i == MAX_MOBSKILL )
+ {
+ if (mob_id != last_mob_id) {
+ ShowError("mob_parse_row_mobskilldb: Too many skills for monster %d[%s]\n", mob_id, mob_db_data[mob_id]->sprite);
+ last_mob_id = mob_id;
+ }
+ return false;
+ }
+ }
+
+ //State
+ ARR_FIND( 0, ARRAYLENGTH(state), j, strcmp(str[2],state[j].str) == 0 );
+ if( j < ARRAYLENGTH(state) )
+ ms->state = state[j].id;
+ else {
+ ShowWarning("mob_parse_row_mobskilldb: Unrecognized state %s\n", str[2]);
+ ms->state = MSS_ANY;
+ }
+
+ //Skill ID
+ j=atoi(str[3]);
+ if (j<=0 || j>MAX_SKILL_DB) //fixed Lupus
+ {
+ if (mob_id < 0)
+ ShowError("mob_parse_row_mobskilldb: Invalid Skill ID (%d) for all mobs\n", j);
+ else
+ ShowError("mob_parse_row_mobskilldb: Invalid Skill ID (%d) for mob %d (%s)\n", j, mob_id, mob_db_data[mob_id]->sprite);
+ return false;
+ }
+ ms->skill_id=j;
+
+ //Skill lvl
+ j= atoi(str[4])<=0 ? 1 : atoi(str[4]);
+ ms->skill_lv= j>battle_config.mob_max_skilllvl ? battle_config.mob_max_skilllvl : j; //we strip max skill level
+
+ //Apply battle_config modifiers to rate (permillage) and delay [Skotlex]
+ tmp = atoi(str[5]);
+ if (battle_config.mob_skill_rate != 100)
+ tmp = tmp*battle_config.mob_skill_rate/100;
+ if (tmp > 10000)
+ ms->permillage= 10000;
+ else if (!tmp && battle_config.mob_skill_rate)
+ ms->permillage= 1;
+ else
+ ms->permillage= tmp;
+ ms->casttime=atoi(str[6]);
+ ms->delay=atoi(str[7]);
+ if (battle_config.mob_skill_delay != 100)
+ ms->delay = ms->delay*battle_config.mob_skill_delay/100;
+ if (ms->delay < 0 || ms->delay > MOB_MAX_DELAY) //time overflow?
+ ms->delay = MOB_MAX_DELAY;
+ ms->cancel=atoi(str[8]);
+ if( strcmp(str[8],"yes")==0 ) ms->cancel=1;
+
+ //Target
+ ARR_FIND( 0, ARRAYLENGTH(target), j, strcmp(str[9],target[j].str) == 0 );
+ if( j < ARRAYLENGTH(target) )
+ ms->target = target[j].id;
+ else {
+ ShowWarning("mob_parse_row_mobskilldb: Unrecognized target %s for %d\n", str[9], mob_id);
+ ms->target = MST_TARGET;
+ }
+
+ //Check that the target condition is right for the skill type. [Skotlex]
+ if (skill_get_casttype(ms->skill_id) == CAST_GROUND)
+ { //Ground skill.
+ if (ms->target > MST_AROUND)
+ {
+ ShowWarning("mob_parse_row_mobskilldb: Wrong mob skill target for ground skill %d (%s) for %s.\n",
+ ms->skill_id, skill_get_name(ms->skill_id),
+ mob_id < 0?"all mobs":mob_db_data[mob_id]->sprite);
+ ms->target = MST_TARGET;
+ }
+ } else if (ms->target > MST_MASTER) {
+ ShowWarning("mob_parse_row_mobskilldb: Wrong mob skill target 'around' for non-ground skill %d (%s) for %s.\n",
+ ms->skill_id, skill_get_name(ms->skill_id),
+ mob_id < 0?"all mobs":mob_db_data[mob_id]->sprite);
+ ms->target = MST_TARGET;
+ }
+
+ //Cond1
+ ARR_FIND( 0, ARRAYLENGTH(cond1), j, strcmp(str[10],cond1[j].str) == 0 );
+ if( j < ARRAYLENGTH(cond1) )
+ ms->cond1 = cond1[j].id;
+ else {
+ ShowWarning("mob_parse_row_mobskilldb: Unrecognized condition 1 %s for %d\n", str[10], mob_id);
+ ms->cond1 = -1;
+ }
+
+ //Cond2
+ // numeric value
+ ms->cond2 = atoi(str[11]);
+ // or special constant
+ ARR_FIND( 0, ARRAYLENGTH(cond2), j, strcmp(str[11],cond2[j].str) == 0 );
+ if( j < ARRAYLENGTH(cond2) )
+ ms->cond2 = cond2[j].id;
+
+ ms->val[0]=(int)strtol(str[12],NULL,0);
+ ms->val[1]=(int)strtol(str[13],NULL,0);
+ ms->val[2]=(int)strtol(str[14],NULL,0);
+ ms->val[3]=(int)strtol(str[15],NULL,0);
+ ms->val[4]=(int)strtol(str[16],NULL,0);
+
+ if(ms->skill_id == NPC_EMOTION && mob_id>0 &&
+ ms->val[1] == mob_db(mob_id)->status.mode)
+ {
+ ms->val[1] = 0;
+ ms->val[4] = 1; //request to return mode to normal.
+ }
+ if(ms->skill_id == NPC_EMOTION_ON && mob_id>0 && ms->val[1])
+ { //Adds a mode to the mob.
+ //Remove aggressive mode when the new mob type is passive.
+ if (!(ms->val[1]&MD_AGGRESSIVE))
+ ms->val[3]|=MD_AGGRESSIVE;
+ ms->val[2]|= ms->val[1]; //Add the new mode.
+ ms->val[1] = 0; //Do not "set" it.
+ }
+
+ if(*str[17])
+ ms->emotion=atoi(str[17]);
+ else
+ ms->emotion=-1;
+
+ if(str[18]!=NULL && mob_chat_db[atoi(str[18])]!=NULL)
+ ms->msg_id=atoi(str[18]);
+ else
+ ms->msg_id=0;
+
+ if (mob_id < 0)
+ { //Set this skill to ALL mobs. [Skotlex]
+ mob_id *= -1;
+ for (i = 1; i < MAX_MOB_DB; i++)
+ {
+ if (mob_db_data[i] == NULL)
+ continue;
+ if (mob_db_data[i]->status.mode&MD_BOSS)
+ {
+ if (!(mob_id&2)) //Skill not for bosses
+ continue;
+ } else
+ if (!(mob_id&1)) //Skill not for normal enemies.
+ continue;
+
+ ARR_FIND( 0, MAX_MOBSKILL, j, mob_db_data[i]->skill[j].skill_id == 0 );
+ if(j==MAX_MOBSKILL)
+ continue;
+
+ memcpy (&mob_db_data[i]->skill[j], ms, sizeof(struct mob_skill));
+ mob_db_data[i]->maxskill=j+1;
+ }
+ } else //Skill set on a single mob.
+ mob_db_data[mob_id]->maxskill=i+1;
+
+ return true;
}
/*==========================================
* mob_skill_db.txt reading
*------------------------------------------*/
-static void mob_readskilldb(void)
-{
- const char *filename[] = {
- DBPATH"mob_skill_db.txt",
- "mob_skill_db2.txt"
- };
- int fi;
-
- if (battle_config.mob_skill_rate == 0) {
- ShowStatus("Mob skill use disabled. Not reading mob skills.\n");
- return;
- }
-
- for (fi = 0; fi < ARRAYLENGTH(filename); ++fi) {
- char path[256];
-
- if (fi > 0) {
- sprintf(path, "%s/%s", db_path, filename[fi]);
- if (!exists(path)) {
- continue;
- }
- }
-
- sv_readdb(db_path, filename[fi], ',', 19, 19, -1, &mob_parse_row_mobskilldb);
- }
+static void mob_readskilldb(void) {
+ const char* filename[] = {
+ DBPATH"mob_skill_db.txt",
+ "mob_skill_db2.txt" };
+ int fi;
+
+ if( battle_config.mob_skill_rate == 0 )
+ {
+ ShowStatus("Mob skill use disabled. Not reading mob skills.\n");
+ return;
+ }
+
+ for( fi = 0; fi < ARRAYLENGTH(filename); ++fi )
+ {
+ char path[256];
+
+ if(fi > 0)
+ {
+ sprintf(path, "%s/%s", db_path, filename[fi]);
+ if(!exists(path))
+ {
+ continue;
+ }
+ }
+
+ sv_readdb(db_path, filename[fi], ',', 19, 19, -1, &mob_parse_row_mobskilldb);
+ }
}
/**
@@ -4398,100 +4481,105 @@ static void mob_readskilldb(void)
*/
static int mob_read_sqlskilldb(void)
{
- const char *mob_skill_db_name[] = { mob_skill_db_db, mob_skill_db2_db };
- int fi;
-
- if (battle_config.mob_skill_rate == 0) {
- ShowStatus("Mob skill use disabled. Not reading mob skills.\n");
- return 0;
- }
-
-
- for (fi = 0; fi < ARRAYLENGTH(mob_skill_db_name); ++fi) {
- uint32 lines = 0, count = 0;
-
- // retrieve all rows from the mob skill database
- if (SQL_ERROR == Sql_Query(mmysql_handle, "SELECT * FROM `%s`", mob_skill_db_name[fi])) {
- Sql_ShowDebug(mmysql_handle);
- continue;
- }
-
- // process rows one by one
- while (SQL_SUCCESS == Sql_NextRow(mmysql_handle)) {
- // wrap the result into a TXT-compatible format
- char *str[19];
- char *dummy = "";
- int i;
- ++lines;
- for (i = 0; i < 19; ++i) {
- Sql_GetData(mmysql_handle, i, &str[i], NULL);
- if (str[i] == NULL) str[i] = dummy; // get rid of NULL columns
- }
-
- if (!mob_parse_row_mobskilldb(str, 19, count))
- continue;
-
- count++;
- }
-
- // free the query result
- Sql_FreeResult(mmysql_handle);
-
- ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, mob_skill_db_name[fi]);
- }
- return 0;
+ const char* mob_skill_db_name[] = { mob_skill_db_db, mob_skill_db2_db };
+ int fi;
+
+ if( battle_config.mob_skill_rate == 0 ) {
+ ShowStatus("Mob skill use disabled. Not reading mob skills.\n");
+ return 0;
+ }
+
+
+ for( fi = 0; fi < ARRAYLENGTH(mob_skill_db_name); ++fi ) {
+ uint32 lines = 0, count = 0;
+
+ // retrieve all rows from the mob skill database
+ if( SQL_ERROR == Sql_Query(mmysql_handle, "SELECT * FROM `%s`", mob_skill_db_name[fi]) ) {
+ Sql_ShowDebug(mmysql_handle);
+ continue;
+ }
+
+ // process rows one by one
+ while( SQL_SUCCESS == Sql_NextRow(mmysql_handle) ) {
+ // wrap the result into a TXT-compatible format
+ char* str[19];
+ char* dummy = "";
+ int i;
+ ++lines;
+ for( i = 0; i < 19; ++i )
+ {
+ Sql_GetData(mmysql_handle, i, &str[i], NULL);
+ if( str[i] == NULL ) str[i] = dummy; // get rid of NULL columns
+ }
+
+ if (!mob_parse_row_mobskilldb(str, 19, count))
+ continue;
+
+ count++;
+ }
+
+ // free the query result
+ Sql_FreeResult(mmysql_handle);
+
+ ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, mob_skill_db_name[fi]);
+ }
+ return 0;
}
/*==========================================
* mob_race2_db.txt reading
*------------------------------------------*/
-static bool mob_readdb_race2(char *fields[], int columns, int current)
+static bool mob_readdb_race2(char* fields[], int columns, int current)
{
- int race, mobid, i;
-
- race = atoi(fields[0]);
-
- if (race < RC2_NONE || race >= RC2_MAX) {
- ShowWarning("mob_readdb_race2: Unknown race2 %d.\n", race);
- return false;
- }
-
- for (i = 1; i<columns; i++) {
- mobid = atoi(fields[i]);
- if (mob_db(mobid) == mob_dummy) {
- ShowWarning("mob_readdb_race2: Unknown mob id %d for race2 %d.\n", mobid, race);
- continue;
- }
- mob_db_data[mobid]->race2 = race;
- }
- return true;
+ int race, mobid, i;
+
+ race = atoi(fields[0]);
+
+ if (race < RC2_NONE || race >= RC2_MAX)
+ {
+ ShowWarning("mob_readdb_race2: Unknown race2 %d.\n", race);
+ return false;
+ }
+
+ for(i = 1; i<columns; i++)
+ {
+ mobid = atoi(fields[i]);
+ if (mob_db(mobid) == mob_dummy)
+ {
+ ShowWarning("mob_readdb_race2: Unknown mob id %d for race2 %d.\n", mobid, race);
+ continue;
+ }
+ mob_db_data[mobid]->race2 = race;
+ }
+ return true;
}
/**
* Read mob_item_ratio.txt
*/
-static bool mob_readdb_itemratio(char *str[], int columns, int current)
+static bool mob_readdb_itemratio(char* str[], int columns, int current)
{
- int nameid, ratio, i;
- struct item_data *id;
+ int nameid, ratio, i;
+ struct item_data *id;
- nameid = atoi(str[0]);
+ nameid = atoi(str[0]);
- if ((id = itemdb_exists(nameid)) == NULL) {
- ShowWarning("itemdb_read_itemratio: Invalid item id %d.\n", nameid);
- return false;
- }
+ if( ( id = itemdb_exists(nameid) ) == NULL )
+ {
+ ShowWarning("itemdb_read_itemratio: Invalid item id %d.\n", nameid);
+ return false;
+ }
- ratio = atoi(str[1]);
+ ratio = atoi(str[1]);
- if (item_drop_ratio_db[nameid] == NULL)
- item_drop_ratio_db[nameid] = (struct item_drop_ratio *)aCalloc(1, sizeof(struct item_drop_ratio));
+ if(item_drop_ratio_db[nameid] == NULL)
+ item_drop_ratio_db[nameid] = (struct item_drop_ratio*)aCalloc(1, sizeof(struct item_drop_ratio));
- item_drop_ratio_db[nameid]->drop_ratio = ratio;
- for (i = 0; i < columns-2; i++)
- item_drop_ratio_db[nameid]->mob_id[i] = atoi(str[i+2]);
+ item_drop_ratio_db[nameid]->drop_ratio = ratio;
+ for(i = 0; i < columns-2; i++)
+ item_drop_ratio_db[nameid]->mob_id[i] = atoi(str[i+2]);
- return true;
+ return true;
}
/**
@@ -4499,76 +4587,76 @@ static bool mob_readdb_itemratio(char *str[], int columns, int current)
*/
static void mob_load(void)
{
- sv_readdb(db_path, "mob_item_ratio.txt", ',', 2, 2+MAX_ITEMRATIO_MOBS, -1, &mob_readdb_itemratio); // must be read before mobdb
- mob_readchatdb();
- if (db_use_sqldbs) {
- mob_read_sqldb();
- mob_read_sqlskilldb();
- } else {
- mob_readdb();
- mob_readskilldb();
- }
- sv_readdb(db_path, "mob_avail.txt", ',', 2, 12, -1, &mob_readdb_mobavail);
- mob_read_randommonster();
- sv_readdb(db_path, DBPATH"mob_race2_db.txt", ',', 2, 20, -1, &mob_readdb_race2);
+ sv_readdb(db_path, "mob_item_ratio.txt", ',', 2, 2+MAX_ITEMRATIO_MOBS, -1, &mob_readdb_itemratio); // must be read before mobdb
+ mob_readchatdb();
+ if (db_use_sqldbs)
+ {
+ mob_read_sqldb();
+ mob_read_sqlskilldb();
+ }
+ else
+ {
+ mob_readdb();
+ mob_readskilldb();
+ }
+ sv_readdb(db_path, "mob_avail.txt", ',', 2, 12, -1, &mob_readdb_mobavail);
+ mob_read_randommonster();
+ sv_readdb(db_path, DBPATH"mob_race2_db.txt", ',', 2, 20, -1, &mob_readdb_race2);
}
-void mob_reload(void)
-{
- int i;
-
- //Mob skills need to be cleared before re-reading them. [Skotlex]
- for (i = 0; i < MAX_MOB_DB; i++)
- if (mob_db_data[i]) {
- memset(&mob_db_data[i]->skill,0,sizeof(mob_db_data[i]->skill));
- mob_db_data[i]->maxskill=0;
- }
-
- // Clear item_drop_ratio_db
- for (i = 0; i < MAX_ITEMDB; i++) {
- if (item_drop_ratio_db[i]) {
- aFree(item_drop_ratio_db[i]);
- item_drop_ratio_db[i] = NULL;
- }
- }
-
- mob_load();
+void mob_reload(void) {
+ int i;
+
+ //Mob skills need to be cleared before re-reading them. [Skotlex]
+ for (i = 0; i < MAX_MOB_DB; i++)
+ if (mob_db_data[i]) {
+ memset(&mob_db_data[i]->skill,0,sizeof(mob_db_data[i]->skill));
+ mob_db_data[i]->maxskill=0;
+ }
+
+ // Clear item_drop_ratio_db
+ for (i = 0; i < MAX_ITEMDB; i++) {
+ if (item_drop_ratio_db[i]) {
+ aFree(item_drop_ratio_db[i]);
+ item_drop_ratio_db[i] = NULL;
+ }
+ }
+
+ mob_load();
}
void mob_clear_spawninfo()
-{
- //Clears spawn related information for a script reload.
- int i;
- for (i = 0; i < MAX_MOB_DB; i++)
- if (mob_db_data[i])
- memset(&mob_db_data[i]->spawn,0,sizeof(mob_db_data[i]->spawn));
+{ //Clears spawn related information for a script reload.
+ int i;
+ for (i = 0; i < MAX_MOB_DB; i++)
+ if (mob_db_data[i])
+ memset(&mob_db_data[i]->spawn,0,sizeof(mob_db_data[i]->spawn));
}
/*==========================================
* Circumference initialization of mob
*------------------------------------------*/
int do_init_mob(void)
-{
- //Initialize the mob database
- memset(mob_db_data,0,sizeof(mob_db_data)); //Clear the array
- mob_db_data[0] = (struct mob_db *)aCalloc(1, sizeof(struct mob_db)); //This mob is used for random spawns
- mob_makedummymobdb(0); //The first time this is invoked, it creates the dummy mob
- item_drop_ers = ers_new(sizeof(struct item_drop),"mob.c::item_drop_ers",ERS_OPT_NONE);
- item_drop_list_ers = ers_new(sizeof(struct item_drop_list),"mob.c::item_drop_list_ers",ERS_OPT_NONE);
-
- mob_load();
-
- add_timer_func_list(mob_delayspawn,"mob_delayspawn");
- add_timer_func_list(mob_delay_item_drop,"mob_delay_item_drop");
- add_timer_func_list(mob_ai_hard,"mob_ai_hard");
- add_timer_func_list(mob_ai_lazy,"mob_ai_lazy");
- add_timer_func_list(mob_timer_delete,"mob_timer_delete");
- add_timer_func_list(mob_spawn_guardian_sub,"mob_spawn_guardian_sub");
- add_timer_func_list(mob_respawn,"mob_respawn");
- add_timer_interval(gettick()+MIN_MOBTHINKTIME,mob_ai_hard,0,0,MIN_MOBTHINKTIME);
- add_timer_interval(gettick()+MIN_MOBTHINKTIME*10,mob_ai_lazy,0,0,MIN_MOBTHINKTIME*10);
-
- return 0;
+{ //Initialize the mob database
+ memset(mob_db_data,0,sizeof(mob_db_data)); //Clear the array
+ mob_db_data[0] = (struct mob_db*)aCalloc(1, sizeof (struct mob_db)); //This mob is used for random spawns
+ mob_makedummymobdb(0); //The first time this is invoked, it creates the dummy mob
+ item_drop_ers = ers_new(sizeof(struct item_drop),"mob.c::item_drop_ers",ERS_OPT_NONE);
+ item_drop_list_ers = ers_new(sizeof(struct item_drop_list),"mob.c::item_drop_list_ers",ERS_OPT_NONE);
+
+ mob_load();
+
+ add_timer_func_list(mob_delayspawn,"mob_delayspawn");
+ add_timer_func_list(mob_delay_item_drop,"mob_delay_item_drop");
+ add_timer_func_list(mob_ai_hard,"mob_ai_hard");
+ add_timer_func_list(mob_ai_lazy,"mob_ai_lazy");
+ add_timer_func_list(mob_timer_delete,"mob_timer_delete");
+ add_timer_func_list(mob_spawn_guardian_sub,"mob_spawn_guardian_sub");
+ add_timer_func_list(mob_respawn,"mob_respawn");
+ add_timer_interval(gettick()+MIN_MOBTHINKTIME,mob_ai_hard,0,0,MIN_MOBTHINKTIME);
+ add_timer_interval(gettick()+MIN_MOBTHINKTIME*10,mob_ai_lazy,0,0,MIN_MOBTHINKTIME*10);
+
+ return 0;
}
/*==========================================
@@ -4576,30 +4664,37 @@ int do_init_mob(void)
*------------------------------------------*/
int do_final_mob(void)
{
- int i;
- if (mob_dummy) {
- aFree(mob_dummy);
- mob_dummy = NULL;
- }
- for (i = 0; i <= MAX_MOB_DB; i++) {
- if (mob_db_data[i] != NULL) {
- aFree(mob_db_data[i]);
- mob_db_data[i] = NULL;
- }
- }
- for (i = 0; i <= MAX_MOB_CHAT; i++) {
- if (mob_chat_db[i] != NULL) {
- aFree(mob_chat_db[i]);
- mob_chat_db[i] = NULL;
- }
- }
- for (i = 0; i < MAX_ITEMDB; i++) {
- if (item_drop_ratio_db[i] != NULL) {
- aFree(item_drop_ratio_db[i]);
- item_drop_ratio_db[i] = NULL;
- }
- }
- ers_destroy(item_drop_ers);
- ers_destroy(item_drop_list_ers);
- return 0;
+ int i;
+ if (mob_dummy)
+ {
+ aFree(mob_dummy);
+ mob_dummy = NULL;
+ }
+ for (i = 0; i <= MAX_MOB_DB; i++)
+ {
+ if (mob_db_data[i] != NULL)
+ {
+ aFree(mob_db_data[i]);
+ mob_db_data[i] = NULL;
+ }
+ }
+ for (i = 0; i <= MAX_MOB_CHAT; i++)
+ {
+ if (mob_chat_db[i] != NULL)
+ {
+ aFree(mob_chat_db[i]);
+ mob_chat_db[i] = NULL;
+ }
+ }
+ for (i = 0; i < MAX_ITEMDB; i++)
+ {
+ if (item_drop_ratio_db[i] != NULL)
+ {
+ aFree(item_drop_ratio_db[i]);
+ item_drop_ratio_db[i] = NULL;
+ }
+ }
+ ers_destroy(item_drop_ers);
+ ers_destroy(item_drop_list_ers);
+ return 0;
}
diff --git a/src/map/mob.h b/src/map/mob.h
index 0923fe796..b052c3b16 100644
--- a/src/map/mob.h
+++ b/src/map/mob.h
@@ -44,234 +44,231 @@ extern const int mob_splendide[5];
//Mob skill states.
enum MobSkillState {
- MSS_ANY = -1,
- MSS_IDLE,
- MSS_WALK,
- MSS_LOOT,
- MSS_DEAD,
- MSS_BERSERK, //Aggressive mob attacking
- MSS_ANGRY, //Mob retaliating from being attacked.
- MSS_RUSH, //Mob following a player after being attacked.
- MSS_FOLLOW, //Mob following a player without being attacked.
- MSS_ANYTARGET,
+ MSS_ANY = -1,
+ MSS_IDLE,
+ MSS_WALK,
+ MSS_LOOT,
+ MSS_DEAD,
+ MSS_BERSERK, //Aggressive mob attacking
+ MSS_ANGRY, //Mob retaliating from being attacked.
+ MSS_RUSH, //Mob following a player after being attacked.
+ MSS_FOLLOW, //Mob following a player without being attacked.
+ MSS_ANYTARGET,
};
-enum MobDamageLogFlag {
- MDLF_NORMAL = 0,
- MDLF_HOMUN,
- MDLF_PET,
+enum MobDamageLogFlag
+{
+ MDLF_NORMAL = 0,
+ MDLF_HOMUN,
+ MDLF_PET,
};
enum size {
- SZ_SMALL = 0,
- SZ_MEDIUM,
- SZ_BIG,
+ SZ_SMALL = 0,
+ SZ_MEDIUM,
+ SZ_BIG,
};
enum ai {
- AI_NONE = 0,
- AI_ATTACK,
- AI_SPHERE,
- AI_FLORA,
- AI_ZANZOU,
+ AI_NONE = 0,
+ AI_ATTACK,
+ AI_SPHERE,
+ AI_FLORA,
+ AI_ZANZOU,
};
struct mob_skill {
- enum MobSkillState state;
- short skill_id,skill_lv;
- short permillage;
- int casttime,delay;
- short cancel;
- short cond1,cond2;
- short target;
- int val[5];
- short emotion;
- unsigned short msg_id;
+ enum MobSkillState state;
+ short skill_id,skill_lv;
+ short permillage;
+ int casttime,delay;
+ short cancel;
+ short cond1,cond2;
+ short target;
+ int val[5];
+ short emotion;
+ unsigned short msg_id;
};
struct mob_chat {
- unsigned short msg_id;
- unsigned long color;
- char msg[CHAT_SIZE_MAX];
+ unsigned short msg_id;
+ unsigned long color;
+ char msg[CHAT_SIZE_MAX];
};
struct spawn_info {
- unsigned short mapindex;
- unsigned short qty;
+ unsigned short mapindex;
+ unsigned short qty;
};
struct mob_db {
- char sprite[NAME_LENGTH],name[NAME_LENGTH],jname[NAME_LENGTH];
- unsigned int base_exp,job_exp;
- unsigned int mexp;
- short range2,range3;
- short race2; // celest
- unsigned short lv;
- struct {
- int nameid,p;
- } dropitem[MAX_MOB_DROP];
- struct {
- int nameid,p;
- } mvpitem[MAX_MVP_DROP];
- struct status_data status;
- struct view_data vd;
- unsigned int option;
- int summonper[MAX_RANDOMMONSTER];
- int maxskill;
- struct mob_skill skill[MAX_MOBSKILL];
- struct spawn_info spawn[10];
+ char sprite[NAME_LENGTH],name[NAME_LENGTH],jname[NAME_LENGTH];
+ unsigned int base_exp,job_exp;
+ unsigned int mexp;
+ short range2,range3;
+ short race2; // celest
+ unsigned short lv;
+ struct { int nameid,p; } dropitem[MAX_MOB_DROP];
+ struct { int nameid,p; } mvpitem[MAX_MVP_DROP];
+ struct status_data status;
+ struct view_data vd;
+ unsigned int option;
+ int summonper[MAX_RANDOMMONSTER];
+ int maxskill;
+ struct mob_skill skill[MAX_MOBSKILL];
+ struct spawn_info spawn[10];
};
struct mob_data {
- struct block_list bl;
- struct unit_data ud;
- struct view_data *vd;
- struct status_data status, *base_status; //Second one is in case of leveling up mobs, or tiny/large mobs.
- struct status_change sc;
- struct mob_db *db; //For quick data access (saves doing mob_db(md->class_) all the time) [Skotlex]
- char name[NAME_LENGTH];
- struct {
- unsigned int size : 2; //Small/Big monsters.
- unsigned int ai : 4; //Special ai for summoned monsters.
- //0: Normal mob.
- //1: Standard summon, attacks mobs.
- //2: Alchemist Marine Sphere
- //3: Alchemist Summon Flora
- //4: Summon Zanzou
- unsigned int clone : 1;/* is clone? 1:0 */
- } special_state; //Special mob information that does not needs to be zero'ed on mob respawn.
- struct {
- unsigned int aggressive : 1; //Signals whether the mob AI is in aggressive mode or reactive mode. [Skotlex]
- unsigned int steal_coin_flag : 1;
- unsigned int soul_change_flag : 1; // Celest
- unsigned int alchemist: 1;
- unsigned int spotted: 1;
- unsigned int npc_killmonster: 1; //for new killmonster behavior
- unsigned int rebirth: 1; // NPC_Rebirth used
- unsigned int boss : 1;
- enum MobSkillState skillstate;
- unsigned char steal_flag; //number of steal tries (to prevent steal exploit on mobs with few items) [Lupus]
- unsigned char attacked_count; //For rude attacked.
- int provoke_flag; // Celest
- } state;
- struct guardian_data *guardian_data;
- struct {
- int id;
- unsigned int dmg;
- unsigned int flag : 2; //0: Normal. 1: Homunc exp. 2: Pet exp
- } dmglog[DAMAGELOG_SIZE];
- struct spawn_data *spawn; //Spawn data.
- int spawn_timer; //Required for Convex Mirror
- struct item *lootitem;
- short class_;
- unsigned int tdmg; //Stores total damage given to the mob, for exp calculations. [Skotlex]
- int level;
- int target_id,attacked_id;
- int areanpc_id; //Required in OnTouchNPC (to avoid multiple area touchs)
- unsigned int bg_id; // BattleGround System
-
- unsigned int next_walktime,last_thinktime,last_linktime,last_pcneartime,dmgtick;
- short move_fail_count;
- short lootitem_count;
- short min_chase;
-
- int deletetimer;
- int master_id,master_dist;
-
- short skillidx;
- unsigned int skilldelay[MAX_MOBSKILL];
- char npc_event[EVENT_NAME_LENGTH];
- /**
- * Did this monster summon something?
- * Used to flag summon deletions, saves a worth amount of memory
- **/
- bool can_summon;
- /**
- * MvP Tombstone NPC ID
- **/
- int tomb_nid;
+ struct block_list bl;
+ struct unit_data ud;
+ struct view_data *vd;
+ struct status_data status, *base_status; //Second one is in case of leveling up mobs, or tiny/large mobs.
+ struct status_change sc;
+ struct mob_db *db; //For quick data access (saves doing mob_db(md->class_) all the time) [Skotlex]
+ char name[NAME_LENGTH];
+ struct {
+ unsigned int size : 2; //Small/Big monsters.
+ unsigned int ai : 4; //Special ai for summoned monsters.
+ //0: Normal mob.
+ //1: Standard summon, attacks mobs.
+ //2: Alchemist Marine Sphere
+ //3: Alchemist Summon Flora
+ //4: Summon Zanzou
+ unsigned int clone : 1;/* is clone? 1:0 */
+ } special_state; //Special mob information that does not needs to be zero'ed on mob respawn.
+ struct {
+ unsigned int aggressive : 1; //Signals whether the mob AI is in aggressive mode or reactive mode. [Skotlex]
+ unsigned int steal_coin_flag : 1;
+ unsigned int soul_change_flag : 1; // Celest
+ unsigned int alchemist: 1;
+ unsigned int spotted: 1;
+ unsigned int npc_killmonster: 1; //for new killmonster behavior
+ unsigned int rebirth: 1; // NPC_Rebirth used
+ unsigned int boss : 1;
+ enum MobSkillState skillstate;
+ unsigned char steal_flag; //number of steal tries (to prevent steal exploit on mobs with few items) [Lupus]
+ unsigned char attacked_count; //For rude attacked.
+ int provoke_flag; // Celest
+ } state;
+ struct guardian_data* guardian_data;
+ struct {
+ int id;
+ unsigned int dmg;
+ unsigned int flag : 2; //0: Normal. 1: Homunc exp. 2: Pet exp
+ } dmglog[DAMAGELOG_SIZE];
+ struct spawn_data *spawn; //Spawn data.
+ int spawn_timer; //Required for Convex Mirror
+ struct item *lootitem;
+ short class_;
+ unsigned int tdmg; //Stores total damage given to the mob, for exp calculations. [Skotlex]
+ int level;
+ int target_id,attacked_id;
+ int areanpc_id; //Required in OnTouchNPC (to avoid multiple area touchs)
+ unsigned int bg_id; // BattleGround System
+
+ unsigned int next_walktime,last_thinktime,last_linktime,last_pcneartime,dmgtick;
+ short move_fail_count;
+ short lootitem_count;
+ short min_chase;
+
+ int deletetimer;
+ int master_id,master_dist;
+
+ short skillidx;
+ unsigned int skilldelay[MAX_MOBSKILL];
+ char npc_event[EVENT_NAME_LENGTH];
+ /**
+ * Did this monster summon something?
+ * Used to flag summon deletions, saves a worth amount of memory
+ **/
+ bool can_summon;
+ /**
+ * MvP Tombstone NPC ID
+ **/
+ int tomb_nid;
};
enum {
- MST_TARGET = 0,
- MST_RANDOM, //Random Target!
- MST_SELF,
- MST_FRIEND,
- MST_MASTER,
- MST_AROUND5,
- MST_AROUND6,
- MST_AROUND7,
- MST_AROUND8,
- MST_AROUND1,
- MST_AROUND2,
- MST_AROUND3,
- MST_AROUND4,
- MST_AROUND = MST_AROUND4,
-
- MSC_ALWAYS = 0x0000,
- MSC_MYHPLTMAXRATE,
- MSC_MYHPINRATE,
- MSC_FRIENDHPLTMAXRATE,
- MSC_FRIENDHPINRATE,
- MSC_MYSTATUSON,
- MSC_MYSTATUSOFF,
- MSC_FRIENDSTATUSON,
- MSC_FRIENDSTATUSOFF,
- MSC_ATTACKPCGT,
- MSC_ATTACKPCGE,
- MSC_SLAVELT,
- MSC_SLAVELE,
- MSC_CLOSEDATTACKED,
- MSC_LONGRANGEATTACKED,
- MSC_AFTERSKILL,
- MSC_SKILLUSED,
- MSC_CASTTARGETED,
- MSC_RUDEATTACKED,
- MSC_MASTERHPLTMAXRATE,
- MSC_MASTERATTACKED,
- MSC_ALCHEMIST,
- MSC_SPAWN,
+ MST_TARGET = 0,
+ MST_RANDOM, //Random Target!
+ MST_SELF,
+ MST_FRIEND,
+ MST_MASTER,
+ MST_AROUND5,
+ MST_AROUND6,
+ MST_AROUND7,
+ MST_AROUND8,
+ MST_AROUND1,
+ MST_AROUND2,
+ MST_AROUND3,
+ MST_AROUND4,
+ MST_AROUND = MST_AROUND4,
+
+ MSC_ALWAYS = 0x0000,
+ MSC_MYHPLTMAXRATE,
+ MSC_MYHPINRATE,
+ MSC_FRIENDHPLTMAXRATE,
+ MSC_FRIENDHPINRATE,
+ MSC_MYSTATUSON,
+ MSC_MYSTATUSOFF,
+ MSC_FRIENDSTATUSON,
+ MSC_FRIENDSTATUSOFF,
+ MSC_ATTACKPCGT,
+ MSC_ATTACKPCGE,
+ MSC_SLAVELT,
+ MSC_SLAVELE,
+ MSC_CLOSEDATTACKED,
+ MSC_LONGRANGEATTACKED,
+ MSC_AFTERSKILL,
+ MSC_SKILLUSED,
+ MSC_CASTTARGETED,
+ MSC_RUDEATTACKED,
+ MSC_MASTERHPLTMAXRATE,
+ MSC_MASTERATTACKED,
+ MSC_ALCHEMIST,
+ MSC_SPAWN,
};
// The data structures for storing delayed item drops
struct item_drop {
- struct item item_data;
- struct item_drop *next;
+ struct item item_data;
+ struct item_drop* next;
};
struct item_drop_list {
- int m, x, y; // coordinates
- int first_charid, second_charid, third_charid; // charid's of players with higher pickup priority
- struct item_drop *item; // linked list of drops
+ int m, x, y; // coordinates
+ int first_charid, second_charid, third_charid; // charid's of players with higher pickup priority
+ struct item_drop* item; // linked list of drops
};
-struct mob_db *mob_db(int class_);
+struct mob_db* mob_db(int class_);
int mobdb_searchname(const char *str);
-int mobdb_searchname_array(struct mob_db **data, int size, const char *str);
+int mobdb_searchname_array(struct mob_db** data, int size, const char *str);
int mobdb_checkid(const int id);
-struct view_data *mob_get_viewdata(int class_);
+struct view_data* mob_get_viewdata(int class_);
struct mob_data *mob_once_spawn_sub(struct block_list *bl, int m,
- short x, short y, const char *mobname, int class_, const char *event, unsigned int size, unsigned int ai);
+ short x, short y, const char *mobname, int class_, const char *event, unsigned int size, unsigned int ai);
-int mob_once_spawn(struct map_session_data *sd, int m, short x, short y,
- const char *mobname, int class_, int amount, const char *event, unsigned int size, unsigned int ai);
+int mob_once_spawn(struct map_session_data* sd, int m, short x, short y,
+ const char* mobname, int class_, int amount, const char* event, unsigned int size, unsigned int ai);
-int mob_once_spawn_area(struct map_session_data *sd, int m,
- int x0, int y0, int x1, int y1, const char *mobname, int class_, int amount, const char *event, unsigned int size, unsigned int ai);
+int mob_once_spawn_area(struct map_session_data* sd, int m,
+ int x0, int y0, int x1, int y1, const char* mobname, int class_, int amount, const char* event, unsigned int size, unsigned int ai);
-bool mob_ksprotected(struct block_list *src, struct block_list *target);
+bool mob_ksprotected (struct block_list *src, struct block_list *target);
-int mob_spawn_guardian(const char *mapname, short x, short y, const char *mobname, int class_, const char *event, int guardian, bool has_index); // Spawning Guardians [Valaris]
-int mob_spawn_bg(const char *mapname, short x, short y, const char *mobname, int class_, const char *event, unsigned int bg_id);
+int mob_spawn_guardian(const char* mapname, short x, short y, const char* mobname, int class_, const char* event, int guardian, bool has_index); // Spawning Guardians [Valaris]
+int mob_spawn_bg(const char* mapname, short x, short y, const char* mobname, int class_, const char* event, unsigned int bg_id);
int mob_guardian_guildchange(struct mob_data *md); //Change Guardian's ownership. [Skotlex]
int mob_randomwalk(struct mob_data *md,unsigned int tick);
int mob_warpchase(struct mob_data *md, struct block_list *target);
int mob_target(struct mob_data *md,struct block_list *bl,int dist);
int mob_unlocktarget(struct mob_data *md, unsigned int tick);
-struct mob_data *mob_spawn_dataset(struct spawn_data *data);
+struct mob_data* mob_spawn_dataset(struct spawn_data *data);
int mob_spawn(struct mob_data *md);
int mob_delayspawn(int tid, unsigned int tick, int id, intptr_t data);
int mob_setdelayspawn(struct mob_data *md);
@@ -295,7 +292,7 @@ int do_final_mob(void);
int mob_timer_delete(int tid, unsigned int tick, int id, intptr_t data);
int mob_deleteslave(struct mob_data *md);
-int mob_random_class(int *value, size_t count);
+int mob_random_class (int *value, size_t count);
int mob_get_random_id(int type, int flag, int lv);
int mob_class_change(struct mob_data *md,int class_);
int mob_warpslave(struct block_list *bl, int range);
@@ -303,8 +300,8 @@ int mob_linksearch(struct block_list *bl,va_list ap);
int mobskill_use(struct mob_data *md,unsigned int tick,int event);
int mobskill_event(struct mob_data *md,struct block_list *src,unsigned int tick, 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 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 skill_id);
int mob_countslave(struct block_list *bl);
int mob_count_sub(struct block_list *bl, va_list ap);
diff --git a/src/map/npc.c b/src/map/npc.c
index 7cc8b27c9..cf267b73c 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -36,14 +36,14 @@
#include <errno.h>
-struct npc_data *fake_nd;
+struct npc_data* fake_nd;
// linked list of npc source files
struct npc_src_list {
- struct npc_src_list *next;
- char name[4]; // dynamic array, the structure is allocated with extra bytes (string length)
+ struct npc_src_list* next;
+ char name[4]; // dynamic array, the structure is allocated with extra bytes (string length)
};
-static struct npc_src_list *npc_src_files = NULL;
+static struct npc_src_list* npc_src_files = NULL;
static int npc_id=START_NPC_NUM;
static int npc_warp=0;
@@ -55,30 +55,29 @@ static int npc_cache_mob=0;
/// Returns a new npc id that isn't being used in id_db.
/// Fatal error if nothing is available.
-int npc_get_new_npc_id(void)
-{
- if (npc_id >= START_NPC_NUM && !map_blid_exists(npc_id))
- return npc_id++;// available
- else {// find next id
- int base_id = npc_id;
- while (base_id != ++npc_id) {
- if (npc_id < START_NPC_NUM)
- npc_id = START_NPC_NUM;
- if (!map_blid_exists(npc_id))
- return npc_id++;// available
- }
- // full loop, nothing available
- ShowFatalError("npc_get_new_npc_id: All ids are taken. Exiting...");
- exit(1);
- }
-}
-
-static DBMap *ev_db; // const char* event_name -> struct event_data*
-static DBMap *npcname_db; // const char* npc_name -> struct npc_data*
+int npc_get_new_npc_id(void) {
+ if( npc_id >= START_NPC_NUM && !map_blid_exists(npc_id) )
+ return npc_id++;// available
+ else {// find next id
+ int base_id = npc_id;
+ while( base_id != ++npc_id ) {
+ if( npc_id < START_NPC_NUM )
+ npc_id = START_NPC_NUM;
+ if( !map_blid_exists(npc_id) )
+ return npc_id++;// available
+ }
+ // full loop, nothing available
+ ShowFatalError("npc_get_new_npc_id: All ids are taken. Exiting...");
+ exit(1);
+ }
+}
+
+static DBMap* ev_db; // const char* event_name -> struct event_data*
+static DBMap* npcname_db; // const char* npc_name -> struct npc_data*
struct event_data {
- struct npc_data *nd;
- int pos;
+ struct npc_data *nd;
+ int pos;
};
static struct eri *timer_event_ers; //For the npc timer data. [Skotlex]
@@ -88,8 +87,8 @@ static char *npc_last_path;
static char *npc_last_ref;
struct npc_path_data {
- char *path;
- unsigned short references;
+ char* path;
+ unsigned short references;
};
struct npc_path_data *npc_last_npd;
static DBMap *npc_path_db;
@@ -97,45 +96,45 @@ static DBMap *npc_path_db;
//For holding the view data of npc classes. [Skotlex]
static struct view_data npc_viewdb[MAX_NPC_CLASS];
-static struct script_event_s {
- //Holds pointers to the commonly executed scripts for speedup. [Skotlex]
- struct event_data *event[UCHAR_MAX];
- const char *event_name[UCHAR_MAX];
- uint8 event_count;
+static struct script_event_s
+{ //Holds pointers to the commonly executed scripts for speedup. [Skotlex]
+ struct event_data *event[UCHAR_MAX];
+ const char *event_name[UCHAR_MAX];
+ uint8 event_count;
} script_event[NPCE_MAX];
-struct view_data *npc_get_viewdata(int class_) {
- //Returns the viewdata for normal npc classes.
- if (class_ == INVISIBLE_CLASS)
- return &npc_viewdb[0];
- if (npcdb_checkid(class_) || class_ == WARP_CLASS)
- return &npc_viewdb[class_];
- return NULL;
+struct view_data* npc_get_viewdata(int class_)
+{ //Returns the viewdata for normal npc classes.
+ if( class_ == INVISIBLE_CLASS )
+ return &npc_viewdb[0];
+ if (npcdb_checkid(class_) || class_ == WARP_CLASS)
+ return &npc_viewdb[class_];
+ return NULL;
}
int npc_ontouch_event(struct map_session_data *sd, struct npc_data *nd)
{
- char name[EVENT_NAME_LENGTH];
+ char name[EVENT_NAME_LENGTH];
- if (nd->touching_id)
- return 0; // Attached a player already. Can't trigger on anyone else.
+ if( nd->touching_id )
+ return 0; // Attached a player already. Can't trigger on anyone else.
- if (pc_ishiding(sd))
- return 1; // Can't trigger 'OnTouch_'. try 'OnTouch' later.
+ if( pc_ishiding(sd) )
+ return 1; // Can't trigger 'OnTouch_'. try 'OnTouch' later.
- snprintf(name, ARRAYLENGTH(name), "%s::%s", nd->exname, script_config.ontouch_name);
- return npc_event(sd,name,1);
+ snprintf(name, ARRAYLENGTH(name), "%s::%s", nd->exname, script_config.ontouch_name);
+ return npc_event(sd,name,1);
}
int npc_ontouch2_event(struct map_session_data *sd, struct npc_data *nd)
{
- char name[EVENT_NAME_LENGTH];
+ char name[EVENT_NAME_LENGTH];
- if (sd->areanpc_id == nd->bl.id)
- return 0;
+ if( sd->areanpc_id == nd->bl.id )
+ return 0;
- snprintf(name, ARRAYLENGTH(name), "%s::%s", nd->exname, script_config.ontouch2_name);
- return npc_event(sd,name,2);
+ snprintf(name, ARRAYLENGTH(name), "%s::%s", nd->exname, script_config.ontouch2_name);
+ return npc_event(sd,name,2);
}
/*==========================================
@@ -143,72 +142,75 @@ int npc_ontouch2_event(struct map_session_data *sd, struct npc_data *nd)
*------------------------------------------*/
int npc_enable_sub(struct block_list *bl, va_list ap)
{
- struct npc_data *nd;
+ struct npc_data *nd;
- nullpo_ret(bl);
- nullpo_ret(nd=va_arg(ap,struct npc_data *));
- if (bl->type == BL_PC) {
- TBL_PC *sd = (TBL_PC *)bl;
+ nullpo_ret(bl);
+ nullpo_ret(nd=va_arg(ap,struct npc_data *));
+ if(bl->type == BL_PC)
+ {
+ TBL_PC *sd = (TBL_PC*)bl;
- if (nd->sc.option&OPTION_INVISIBLE)
- return 1;
+ if (nd->sc.option&OPTION_INVISIBLE)
+ return 1;
- if (npc_ontouch_event(sd,nd) > 0 && npc_ontouch2_event(sd,nd) > 0) {
- // failed to run OnTouch event, so just click the npc
- if (sd->npc_id != 0)
- return 0;
+ if( npc_ontouch_event(sd,nd) > 0 && npc_ontouch2_event(sd,nd) > 0 )
+ { // failed to run OnTouch event, so just click the npc
+ if (sd->npc_id != 0)
+ return 0;
- pc_stop_walking(sd,1);
- npc_click(sd,nd);
- }
- }
- return 0;
+ pc_stop_walking(sd,1);
+ npc_click(sd,nd);
+ }
+ }
+ return 0;
}
/*==========================================
* Disable / Enable NPC
*------------------------------------------*/
-int npc_enable(const char *name, int flag)
-{
- struct npc_data *nd = npc_name2id(name);
-
- if (nd==NULL) {
- ShowError("npc_enable: Attempted to %s a non-existing NPC '%s' (flag=%d).\n", (flag&3) ? "show" : "hide", name, flag);
- return 0;
- }
-
- if (flag&1) {
- nd->sc.option&=~OPTION_INVISIBLE;
- clif_spawn(&nd->bl);
- } else if (flag&2)
- nd->sc.option&=~OPTION_HIDE;
- else if (flag&4)
- nd->sc.option|= OPTION_HIDE;
- else { //Can't change the view_data to invisible class because the view_data for all npcs is shared! [Skotlex]
- nd->sc.option|= OPTION_INVISIBLE;
- clif_clearunit_area(&nd->bl,CLR_OUTSIGHT); // Hack to trick maya purple card [Xazax]
- }
-
- if (nd->class_ == WARP_CLASS || nd->class_ == FLAG_CLASS) {
- //Client won't display option changes for these classes [Toms]
- if (nd->sc.option&(OPTION_HIDE|OPTION_INVISIBLE))
- clif_clearunit_area(&nd->bl, CLR_OUTSIGHT);
- else
- clif_spawn(&nd->bl);
- } else
- clif_changeoption(&nd->bl);
-
- if (flag&3 && (nd->u.scr.xs >= 0 || nd->u.scr.ys >= 0)) //check if player standing on a OnTouchArea
- map_foreachinarea(npc_enable_sub, nd->bl.m, nd->bl.x-nd->u.scr.xs, nd->bl.y-nd->u.scr.ys, nd->bl.x+nd->u.scr.xs, nd->bl.y+nd->u.scr.ys, BL_PC, nd);
-
- return 0;
+int npc_enable(const char* name, int flag)
+{
+ struct npc_data* nd = npc_name2id(name);
+
+ if (nd==NULL)
+ {
+ ShowError("npc_enable: Attempted to %s a non-existing NPC '%s' (flag=%d).\n", (flag&3) ? "show" : "hide", name, flag);
+ return 0;
+ }
+
+ if (flag&1) {
+ nd->sc.option&=~OPTION_INVISIBLE;
+ clif_spawn(&nd->bl);
+ } else if (flag&2)
+ nd->sc.option&=~OPTION_HIDE;
+ else if (flag&4)
+ nd->sc.option|= OPTION_HIDE;
+ else { //Can't change the view_data to invisible class because the view_data for all npcs is shared! [Skotlex]
+ nd->sc.option|= OPTION_INVISIBLE;
+ clif_clearunit_area(&nd->bl,CLR_OUTSIGHT); // Hack to trick maya purple card [Xazax]
+ }
+
+ if (nd->class_ == WARP_CLASS || nd->class_ == FLAG_CLASS)
+ { //Client won't display option changes for these classes [Toms]
+ if (nd->sc.option&(OPTION_HIDE|OPTION_INVISIBLE))
+ clif_clearunit_area(&nd->bl, CLR_OUTSIGHT);
+ else
+ clif_spawn(&nd->bl);
+ } else
+ clif_changeoption(&nd->bl);
+
+ if( flag&3 && (nd->u.scr.xs >= 0 || nd->u.scr.ys >= 0) ) //check if player standing on a OnTouchArea
+ map_foreachinarea( npc_enable_sub, nd->bl.m, nd->bl.x-nd->u.scr.xs, nd->bl.y-nd->u.scr.ys, nd->bl.x+nd->u.scr.xs, nd->bl.y+nd->u.scr.ys, BL_PC, nd );
+
+ return 0;
}
/*==========================================
* NPC lookup (get npc_data through npcname)
*------------------------------------------*/
-struct npc_data *npc_name2id(const char *name) {
- return (struct npc_data *) strdb_get(npcname_db, name);
+struct npc_data* npc_name2id(const char* name)
+{
+ return (struct npc_data *) strdb_get(npcname_db, name);
}
/**
* For the Secure NPC Timeout option (check config/Secure.h) [RR]
@@ -217,62 +219,61 @@ struct npc_data *npc_name2id(const char *name) {
/**
* Timer to check for idle time and timeout the dialog if necessary
**/
-int npc_rr_secure_timeout_timer(int tid, unsigned int tick, int id, intptr_t data)
-{
- struct map_session_data *sd = NULL;
- if ((sd = map_id2sd(id)) == NULL || !sd->npc_id) {
- if (sd) sd->npc_idle_timer = INVALID_TIMER;
- return 0;//Not logged in anymore OR no longer attached to a npc
- }
- if (DIFF_TICK(tick,sd->npc_idle_tick) > (SECURE_NPCTIMEOUT*1000)) {
- /**
- * If we still have the NPC script attached, tell it to stop.
- **/
- if (sd->st)
- sd->st->state = END;
- /**
- * This guy's been idle for longer than allowed, close him.
- **/
- clif_scriptclose(sd,sd->npc_id);
- sd->npc_idle_timer = INVALID_TIMER;
- } else //Create a new instance of ourselves to continue
- sd->npc_idle_timer = add_timer(gettick() + (SECURE_NPCTIMEOUT_INTERVAL*1000),npc_rr_secure_timeout_timer,sd->bl.id,0);
- return 0;
+int npc_rr_secure_timeout_timer(int tid, unsigned int tick, int id, intptr_t data) {
+ struct map_session_data* sd = NULL;
+ if( (sd = map_id2sd(id)) == NULL || !sd->npc_id ) {
+ if( sd ) sd->npc_idle_timer = INVALID_TIMER;
+ return 0;//Not logged in anymore OR no longer attached to a npc
+ }
+ if( DIFF_TICK(tick,sd->npc_idle_tick) > (SECURE_NPCTIMEOUT*1000) ) {
+ /**
+ * If we still have the NPC script attached, tell it to stop.
+ **/
+ if( sd->st )
+ sd->st->state = END;
+ /**
+ * This guy's been idle for longer than allowed, close him.
+ **/
+ clif_scriptclose(sd,sd->npc_id);
+ sd->npc_idle_timer = INVALID_TIMER;
+ } else //Create a new instance of ourselves to continue
+ sd->npc_idle_timer = add_timer(gettick() + (SECURE_NPCTIMEOUT_INTERVAL*1000),npc_rr_secure_timeout_timer,sd->bl.id,0);
+ return 0;
}
#endif
/*==========================================
* Dequeue event and add timer for execution (100ms)
*------------------------------------------*/
-int npc_event_dequeue(struct map_session_data *sd)
-{
- nullpo_ret(sd);
-
- if (sd->npc_id) {
- //Current script is aborted.
- if (sd->state.using_fake_npc) {
- clif_clearunit_single(sd->npc_id, CLR_OUTSIGHT, sd->fd);
- sd->state.using_fake_npc = 0;
- }
- if (sd->st) {
- script_free_state(sd->st);
- sd->st = NULL;
- }
- sd->npc_id = 0;
- }
-
- if (!sd->eventqueue[0][0])
- return 0; //Nothing to dequeue
-
- if (!pc_addeventtimer(sd,100,sd->eventqueue[0])) {
- //Failed to dequeue, couldn't set a timer.
- ShowWarning("npc_event_dequeue: event timer is full !\n");
- return 0;
- }
- //Event dequeued successfully, shift other elements.
- memmove(sd->eventqueue[0], sd->eventqueue[1], (MAX_EVENTQUEUE-1)*sizeof(sd->eventqueue[0]));
- sd->eventqueue[MAX_EVENTQUEUE-1][0]=0;
- return 1;
+int npc_event_dequeue(struct map_session_data* sd)
+{
+ nullpo_ret(sd);
+
+ if(sd->npc_id)
+ { //Current script is aborted.
+ if(sd->state.using_fake_npc){
+ clif_clearunit_single(sd->npc_id, CLR_OUTSIGHT, sd->fd);
+ sd->state.using_fake_npc = 0;
+ }
+ if (sd->st) {
+ script_free_state(sd->st);
+ sd->st = NULL;
+ }
+ sd->npc_id = 0;
+ }
+
+ if (!sd->eventqueue[0][0])
+ return 0; //Nothing to dequeue
+
+ if (!pc_addeventtimer(sd,100,sd->eventqueue[0]))
+ { //Failed to dequeue, couldn't set a timer.
+ ShowWarning("npc_event_dequeue: event timer is full !\n");
+ return 0;
+ }
+ //Event dequeued successfully, shift other elements.
+ memmove(sd->eventqueue[0], sd->eventqueue[1], (MAX_EVENTQUEUE-1)*sizeof(sd->eventqueue[0]));
+ sd->eventqueue[MAX_EVENTQUEUE-1][0]=0;
+ return 1;
}
/*==========================================
@@ -281,23 +282,23 @@ int npc_event_dequeue(struct map_session_data *sd)
*------------------------------------------*/
static int npc_event_export(struct npc_data *nd, int 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')) {
- struct event_data *ev;
- char buf[EVENT_NAME_LENGTH];
- snprintf(buf, ARRAYLENGTH(buf), "%s::%s", nd->exname, lname);
- // generate the data and insert it
- CREATE(ev, struct event_data, 1);
- ev->nd = nd;
- ev->pos = pos;
- if (strdb_put(ev_db, buf, ev)) // There was already another event of the same name?
- return 1;
- }
- return 0;
+ 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')) {
+ struct event_data *ev;
+ char buf[EVENT_NAME_LENGTH];
+ snprintf(buf, ARRAYLENGTH(buf), "%s::%s", nd->exname, lname);
+ // generate the data and insert it
+ CREATE(ev, struct event_data, 1);
+ ev->nd = nd;
+ ev->pos = pos;
+ if (strdb_put(ev_db, buf, ev)) // There was already another event of the same name?
+ return 1;
+ }
+ return 0;
}
-int npc_event_sub(struct map_session_data *sd, struct event_data *ev, const char *eventname); //[Lance]
+int npc_event_sub(struct map_session_data* sd, struct event_data* ev, const char* eventname); //[Lance]
/**
* Exec name (NPC events) on player or global
@@ -306,27 +307,28 @@ int npc_event_sub(struct map_session_data *sd, struct event_data *ev, const char
*/
int npc_event_doall_sub(DBKey key, DBData *data, va_list ap)
{
- const char *p = key.str;
- struct event_data *ev;
- int *c;
- const char *name;
- int rid;
-
- nullpo_ret(ev = db_data2ptr(data));
- nullpo_ret(c = va_arg(ap, int *));
- nullpo_ret(name = va_arg(ap, const char *));
- rid = va_arg(ap, int);
-
- p = strchr(p, ':'); // match only the event name
- if (p && strcmpi(name, p) == 0 /* && !ev->nd->src_id */) { // Do not run on duplicates. [Paradox924X]
- if (rid) // a player may only have 1 script running at the same time
- npc_event_sub(map_id2sd(rid),ev,key.str);
- else
- run_script(ev->nd->u.scr.script,ev->pos,rid,ev->nd->bl.id);
- (*c)++;
- }
+ const char* p = key.str;
+ struct event_data* ev;
+ int* c;
+ const char* name;
+ int rid;
- return 0;
+ nullpo_ret(ev = db_data2ptr(data));
+ nullpo_ret(c = va_arg(ap, int *));
+ nullpo_ret(name = va_arg(ap, const char *));
+ rid = va_arg(ap, int);
+
+ p = strchr(p, ':'); // match only the event name
+ if( p && strcmpi(name, p) == 0 /* && !ev->nd->src_id */ ) // Do not run on duplicates. [Paradox924X]
+ {
+ if(rid) // a player may only have 1 script running at the same time
+ npc_event_sub(map_id2sd(rid),ev,key.str);
+ else
+ run_script(ev->nd->u.scr.script,ev->pos,rid,ev->nd->bl.id);
+ (*c)++;
+ }
+
+ return 0;
}
/**
@@ -334,50 +336,51 @@ int npc_event_doall_sub(DBKey key, DBData *data, va_list ap)
*/
static int npc_event_do_sub(DBKey key, DBData *data, va_list ap)
{
- const char *p = key.str;
- struct event_data *ev;
- int *c;
- const char *name;
+ const char* p = key.str;
+ struct event_data* ev;
+ int* c;
+ const char* name;
- nullpo_ret(ev = db_data2ptr(data));
- nullpo_ret(c = va_arg(ap, int *));
- nullpo_ret(name = va_arg(ap, const char *));
+ nullpo_ret(ev = db_data2ptr(data));
+ nullpo_ret(c = va_arg(ap, int *));
+ nullpo_ret(name = va_arg(ap, const char *));
- if (p && strcmpi(name, p) == 0) {
- run_script(ev->nd->u.scr.script,ev->pos,0,ev->nd->bl.id);
- (*c)++;
- }
+ if( p && strcmpi(name, p) == 0 )
+ {
+ run_script(ev->nd->u.scr.script,ev->pos,0,ev->nd->bl.id);
+ (*c)++;
+ }
- return 0;
+ return 0;
}
// runs the specified event (supports both single-npc and global events)
-int npc_event_do(const char *name)
+int npc_event_do(const char* name)
{
- int c = 0;
+ int c = 0;
- if (name[0] == ':' && name[1] == ':')
- ev_db->foreach(ev_db,npc_event_doall_sub,&c,name,0);
- else
- ev_db->foreach(ev_db,npc_event_do_sub,&c,name);
+ if( name[0] == ':' && name[1] == ':' )
+ ev_db->foreach(ev_db,npc_event_doall_sub,&c,name,0);
+ else
+ ev_db->foreach(ev_db,npc_event_do_sub,&c,name);
- return c;
+ return c;
}
// runs the specified event (global only)
-int npc_event_doall(const char *name)
+int npc_event_doall(const char* name)
{
- return npc_event_doall_id(name, 0);
+ return npc_event_doall_id(name, 0);
}
// runs the specified event, with a RID attached (global only)
-int npc_event_doall_id(const char *name, int rid)
+int npc_event_doall_id(const char* name, int rid)
{
- int c = 0;
- char buf[64];
- safesnprintf(buf, sizeof(buf), "::%s", name);
- ev_db->foreach(ev_db,npc_event_doall_sub,&c,buf,rid);
- return c;
+ int c = 0;
+ char buf[64];
+ safesnprintf(buf, sizeof(buf), "::%s", name);
+ ev_db->foreach(ev_db,npc_event_doall_sub,&c,buf,rid);
+ return c;
}
/*==========================================
@@ -386,67 +389,51 @@ int npc_event_doall_id(const char *name, int rid)
*------------------------------------------*/
int npc_event_do_clock(int tid, unsigned int tick, int id, intptr_t data)
{
- static struct tm ev_tm_b; // tracks previous execution time
- time_t timer;
- struct tm *t;
- char buf[64];
- int c = 0;
+ static struct tm ev_tm_b; // tracks previous execution time
+ time_t timer;
+ struct tm* t;
+ char buf[64];
+ int c = 0;
- timer = time(NULL);
- t = localtime(&timer);
+ timer = time(NULL);
+ t = localtime(&timer);
- if (t->tm_min != ev_tm_b.tm_min) {
- char *day;
+ if (t->tm_min != ev_tm_b.tm_min ) {
+ char* day;
- switch (t->tm_wday) {
- case 0:
- day = "Sun";
- break;
- case 1:
- day = "Mon";
- break;
- case 2:
- day = "Tue";
- break;
- case 3:
- day = "Wed";
- break;
- case 4:
- day = "Thu";
- break;
- case 5:
- day = "Fri";
- break;
- case 6:
- day = "Sat";
- break;
- default:
- day = "";
- break;
- }
+ switch (t->tm_wday) {
+ case 0: day = "Sun"; break;
+ case 1: day = "Mon"; break;
+ case 2: day = "Tue"; break;
+ case 3: day = "Wed"; break;
+ case 4: day = "Thu"; break;
+ case 5: day = "Fri"; break;
+ case 6: day = "Sat"; break;
+ default:day = ""; break;
+ }
- sprintf(buf,"OnMinute%02d",t->tm_min);
- c += npc_event_doall(buf);
+ sprintf(buf,"OnMinute%02d",t->tm_min);
+ c += npc_event_doall(buf);
- sprintf(buf,"OnClock%02d%02d",t->tm_hour,t->tm_min);
- c += npc_event_doall(buf);
+ sprintf(buf,"OnClock%02d%02d",t->tm_hour,t->tm_min);
+ c += npc_event_doall(buf);
- sprintf(buf,"On%s%02d%02d",day,t->tm_hour,t->tm_min);
- c += npc_event_doall(buf);
- }
+ sprintf(buf,"On%s%02d%02d",day,t->tm_hour,t->tm_min);
+ c += npc_event_doall(buf);
+ }
- if (t->tm_hour != ev_tm_b.tm_hour) {
- sprintf(buf,"OnHour%02d",t->tm_hour);
- c += npc_event_doall(buf);
- }
+ if (t->tm_hour != ev_tm_b.tm_hour) {
+ sprintf(buf,"OnHour%02d",t->tm_hour);
+ c += npc_event_doall(buf);
+ }
- if (t->tm_mday != ev_tm_b.tm_mday) {
- sprintf(buf,"OnDay%02d%02d",t->tm_mon+1,t->tm_mday);
- c += npc_event_doall(buf);
- }
+ if (t->tm_mday != ev_tm_b.tm_mday) {
+ sprintf(buf,"OnDay%02d%02d",t->tm_mon+1,t->tm_mday);
+ c += npc_event_doall(buf);
+ }
- memcpy(&ev_tm_b,t,sizeof(ev_tm_b));
- return c;
+ memcpy(&ev_tm_b,t,sizeof(ev_tm_b));
+ return c;
}
/*==========================================
@@ -454,9 +441,9 @@ int npc_event_do_clock(int tid, unsigned int tick, int id, intptr_t data)
*------------------------------------------*/
void npc_event_do_oninit(void)
{
- ShowStatus("Event '"CL_WHITE"OnInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs."CL_CLL"\n", npc_event_doall("OnInit"));
+ ShowStatus("Event '"CL_WHITE"OnInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs."CL_CLL"\n", npc_event_doall("OnInit"));
- add_timer_interval(gettick()+100,npc_event_do_clock,0,0,1000);
+ add_timer_interval(gettick()+100,npc_event_do_clock,0,0,1000);
}
/*==========================================
@@ -465,35 +452,35 @@ void npc_event_do_oninit(void)
*------------------------------------------*/
int npc_timerevent_export(struct npc_data *nd, int i)
{
- int t = 0, k = 0;
- char *lname = nd->u.scr.label_list[i].name;
- int pos = nd->u.scr.label_list[i].pos;
- if (sscanf(lname, "OnTimer%d%n", &t, &k) == 1 && lname[k] == '\0') {
- // Timer event
- 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 *)aMalloc(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++) {
- if (te[j].timer > t) {
- memmove(te+j+1, te+j, sizeof(struct npc_timerevent_list)*(k-j));
- break;
- }
- }
- te[j].timer = t;
- te[j].pos = pos;
- nd->u.scr.timer_event = te;
- nd->u.scr.timeramount++;
- }
- return 0;
+ int t = 0, k = 0;
+ char *lname = nd->u.scr.label_list[i].name;
+ int pos = nd->u.scr.label_list[i].pos;
+ if (sscanf(lname, "OnTimer%d%n", &t, &k) == 1 && lname[k] == '\0') {
+ // Timer event
+ 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 *)aMalloc(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++) {
+ if (te[j].timer > t) {
+ memmove(te+j+1, te+j, sizeof(struct npc_timerevent_list)*(k-j));
+ break;
+ }
+ }
+ te[j].timer = t;
+ te[j].pos = pos;
+ nd->u.scr.timer_event = te;
+ nd->u.scr.timeramount++;
+ }
+ return 0;
}
struct timer_event_data {
- int rid; //Attached player for this timer.
- int next; //timer index (starts with 0, then goes up to nd->u.scr.timeramount)
- int time; //holds total time elapsed for the script from when timer was started to when last time the event triggered.
+ int rid; //Attached player for this timer.
+ int next; //timer index (starts with 0, then goes up to nd->u.scr.timeramount)
+ int time; //holds total time elapsed for the script from when timer was started to when last time the event triggered.
};
/*==========================================
@@ -501,306 +488,331 @@ struct timer_event_data {
*------------------------------------------*/
int npc_timerevent(int tid, unsigned int tick, int id, intptr_t data)
{
- int next;
- int old_rid, old_timer;
- unsigned int old_tick;
- struct npc_data *nd=(struct npc_data *)map_id2bl(id);
- struct npc_timerevent_list *te;
- struct timer_event_data *ted = (struct timer_event_data *)data;
- struct map_session_data *sd=NULL;
-
- if (nd == NULL) {
- ShowError("npc_timerevent: NPC not found??\n");
- return 0;
- }
-
- if (ted->rid && !(sd = map_id2sd(ted->rid))) {
- ShowError("npc_timerevent: Attached player not found.\n");
- ers_free(timer_event_ers, ted);
- return 0;
- }
-
- // These stuffs might need to be restored.
- old_rid = nd->u.scr.rid;
- old_tick = nd->u.scr.timertick;
- old_timer = nd->u.scr.timer;
-
- // Set the values of the timer
- nd->u.scr.rid = sd?sd->bl.id:0; //attached rid
- nd->u.scr.timertick = tick; //current time tick
- nd->u.scr.timer = ted->time; //total time from beginning to now
-
- // Locate the event
- te = nd->u.scr.timer_event + ted->next;
-
- // Arrange for the next event
- ted->next++;
- if (nd->u.scr.timeramount > ted->next) {
- next = nd->u.scr.timer_event[ ted->next ].timer - nd->u.scr.timer_event[ ted->next - 1 ].timer;
- ted->time += next;
- if (sd)
- sd->npc_timer_id = add_timer(tick+next,npc_timerevent,id,(intptr_t)ted);
- else
- nd->u.scr.timerid = add_timer(tick+next,npc_timerevent,id,(intptr_t)ted);
- } else {
- if (sd)
- sd->npc_timer_id = INVALID_TIMER;
- else
- nd->u.scr.timerid = INVALID_TIMER;
-
- ers_free(timer_event_ers, ted);
- }
-
- // Run the script
- run_script(nd->u.scr.script,te->pos,nd->u.scr.rid,nd->bl.id);
-
- nd->u.scr.rid = old_rid; // Attached-rid should be restored anyway.
- if (sd) {
- // Restore previous data, only if this timer is a player-attached one.
- nd->u.scr.timer = old_timer;
- nd->u.scr.timertick = old_tick;
- }
-
- return 0;
+ int next;
+ int old_rid, old_timer;
+ unsigned int old_tick;
+ struct npc_data* nd=(struct npc_data *)map_id2bl(id);
+ struct npc_timerevent_list *te;
+ struct timer_event_data *ted = (struct timer_event_data*)data;
+ struct map_session_data *sd=NULL;
+
+ if( nd == NULL )
+ {
+ ShowError("npc_timerevent: NPC not found??\n");
+ return 0;
+ }
+
+ if( ted->rid && !(sd = map_id2sd(ted->rid)) )
+ {
+ ShowError("npc_timerevent: Attached player not found.\n");
+ ers_free(timer_event_ers, ted);
+ return 0;
+ }
+
+ // These stuffs might need to be restored.
+ old_rid = nd->u.scr.rid;
+ old_tick = nd->u.scr.timertick;
+ old_timer = nd->u.scr.timer;
+
+ // Set the values of the timer
+ nd->u.scr.rid = sd?sd->bl.id:0; //attached rid
+ nd->u.scr.timertick = tick; //current time tick
+ nd->u.scr.timer = ted->time; //total time from beginning to now
+
+ // Locate the event
+ te = nd->u.scr.timer_event + ted->next;
+
+ // Arrange for the next event
+ ted->next++;
+ if( nd->u.scr.timeramount > ted->next )
+ {
+ next = nd->u.scr.timer_event[ ted->next ].timer - nd->u.scr.timer_event[ ted->next - 1 ].timer;
+ ted->time += next;
+ if( sd )
+ sd->npc_timer_id = add_timer(tick+next,npc_timerevent,id,(intptr_t)ted);
+ else
+ nd->u.scr.timerid = add_timer(tick+next,npc_timerevent,id,(intptr_t)ted);
+ }
+ else
+ {
+ if( sd )
+ sd->npc_timer_id = INVALID_TIMER;
+ else
+ nd->u.scr.timerid = INVALID_TIMER;
+
+ ers_free(timer_event_ers, ted);
+ }
+
+ // Run the script
+ run_script(nd->u.scr.script,te->pos,nd->u.scr.rid,nd->bl.id);
+
+ nd->u.scr.rid = old_rid; // Attached-rid should be restored anyway.
+ if( sd )
+ { // Restore previous data, only if this timer is a player-attached one.
+ nd->u.scr.timer = old_timer;
+ nd->u.scr.timertick = old_tick;
+ }
+
+ return 0;
}
/*==========================================
* Start/Resume NPC timer
*------------------------------------------*/
-int npc_timerevent_start(struct npc_data *nd, int rid)
-{
- int j, next;
- unsigned int tick = gettick();
- struct map_session_data *sd = NULL; //Player to whom script is attached.
- struct timer_event_data *ted;
-
- nullpo_ret(nd);
-
- // Check if there is an OnTimer Event
- ARR_FIND(0, nd->u.scr.timeramount, j, nd->u.scr.timer_event[j].timer > nd->u.scr.timer);
-
- if (nd->u.scr.rid > 0 && !(sd = map_id2sd(nd->u.scr.rid))) {
- // Failed to attach timer to this player.
- ShowError("npc_timerevent_start: Attached player not found!\n");
- return 1;
- }
-
- // Check if timer is already started.
- if (sd) {
- if (sd->npc_timer_id != INVALID_TIMER)
- return 0;
- } else if (nd->u.scr.timerid != INVALID_TIMER || nd->u.scr.timertick)
- return 0;
-
- if (j < nd->u.scr.timeramount) {
- // Arrange for the next event
- ted = ers_alloc(timer_event_ers, struct timer_event_data);
- ted->next = j; // Set event index
- ted->time = nd->u.scr.timer_event[j].timer;
- next = nd->u.scr.timer_event[j].timer - nd->u.scr.timer;
- if (sd) {
- ted->rid = sd->bl.id; // Attach only the player if attachplayerrid was used.
- sd->npc_timer_id = add_timer(tick+next,npc_timerevent,nd->bl.id,(intptr_t)ted);
- } else {
- ted->rid = 0;
- nd->u.scr.timertick = tick; // Set when timer is started
- nd->u.scr.timerid = add_timer(tick+next,npc_timerevent,nd->bl.id,(intptr_t)ted);
- }
- } else if (!sd) {
- nd->u.scr.timertick = tick;
- }
-
- return 0;
+int npc_timerevent_start(struct npc_data* nd, int rid)
+{
+ int j, next;
+ unsigned int tick = gettick();
+ struct map_session_data *sd = NULL; //Player to whom script is attached.
+ struct timer_event_data *ted;
+
+ nullpo_ret(nd);
+
+ // Check if there is an OnTimer Event
+ ARR_FIND( 0, nd->u.scr.timeramount, j, nd->u.scr.timer_event[j].timer > nd->u.scr.timer );
+
+ if( nd->u.scr.rid > 0 && !(sd = map_id2sd(nd->u.scr.rid)) )
+ { // Failed to attach timer to this player.
+ ShowError("npc_timerevent_start: Attached player not found!\n");
+ return 1;
+ }
+
+ // Check if timer is already started.
+ if( sd )
+ {
+ if( sd->npc_timer_id != INVALID_TIMER )
+ return 0;
+ }
+ else if( nd->u.scr.timerid != INVALID_TIMER || nd->u.scr.timertick )
+ return 0;
+
+ if (j < nd->u.scr.timeramount)
+ {
+ // Arrange for the next event
+ ted = ers_alloc(timer_event_ers, struct timer_event_data);
+ ted->next = j; // Set event index
+ ted->time = nd->u.scr.timer_event[j].timer;
+ next = nd->u.scr.timer_event[j].timer - nd->u.scr.timer;
+ if( sd )
+ {
+ ted->rid = sd->bl.id; // Attach only the player if attachplayerrid was used.
+ sd->npc_timer_id = add_timer(tick+next,npc_timerevent,nd->bl.id,(intptr_t)ted);
+ }
+ else
+ {
+ ted->rid = 0;
+ nd->u.scr.timertick = tick; // Set when timer is started
+ nd->u.scr.timerid = add_timer(tick+next,npc_timerevent,nd->bl.id,(intptr_t)ted);
+ }
+ }
+ else if (!sd)
+ {
+ nd->u.scr.timertick = tick;
+ }
+
+ return 0;
}
/*==========================================
* Stop NPC timer
*------------------------------------------*/
-int npc_timerevent_stop(struct npc_data *nd)
-{
- struct map_session_data *sd = NULL;
- const struct TimerData *td = NULL;
- int *tid;
-
- nullpo_ret(nd);
-
- if (nd->u.scr.rid && !(sd = map_id2sd(nd->u.scr.rid))) {
- ShowError("npc_timerevent_stop: Attached player not found!\n");
- return 1;
- }
-
- tid = sd?&sd->npc_timer_id:&nd->u.scr.timerid;
- if (*tid == INVALID_TIMER && (sd || !nd->u.scr.timertick)) // Nothing to stop
- return 0;
-
- // Delete timer
- if (*tid != INVALID_TIMER) {
- td = get_timer(*tid);
- if (td && td->data)
- ers_free(timer_event_ers, (void *)td->data);
- delete_timer(*tid,npc_timerevent);
- *tid = INVALID_TIMER;
- }
-
- if (!sd && nd->u.scr.timertick) {
- nd->u.scr.timer += DIFF_TICK(gettick(),nd->u.scr.timertick); // Set 'timer' to the time that has passed since the beginning of the timers
- nd->u.scr.timertick = 0; // Set 'tick' to zero so that we know it's off.
- }
-
- return 0;
+int npc_timerevent_stop(struct npc_data* nd)
+{
+ struct map_session_data *sd = NULL;
+ const struct TimerData *td = NULL;
+ int *tid;
+
+ nullpo_ret(nd);
+
+ if( nd->u.scr.rid && !(sd = map_id2sd(nd->u.scr.rid)) )
+ {
+ ShowError("npc_timerevent_stop: Attached player not found!\n");
+ return 1;
+ }
+
+ tid = sd?&sd->npc_timer_id:&nd->u.scr.timerid;
+ if( *tid == INVALID_TIMER && (sd || !nd->u.scr.timertick) ) // Nothing to stop
+ return 0;
+
+ // Delete timer
+ if ( *tid != INVALID_TIMER )
+ {
+ td = get_timer(*tid);
+ if( td && td->data )
+ ers_free(timer_event_ers, (void*)td->data);
+ delete_timer(*tid,npc_timerevent);
+ *tid = INVALID_TIMER;
+ }
+
+ if( !sd && nd->u.scr.timertick )
+ {
+ nd->u.scr.timer += DIFF_TICK(gettick(),nd->u.scr.timertick); // Set 'timer' to the time that has passed since the beginning of the timers
+ nd->u.scr.timertick = 0; // Set 'tick' to zero so that we know it's off.
+ }
+
+ return 0;
}
/*==========================================
* Aborts a running NPC timer that is attached to a player.
*------------------------------------------*/
-void npc_timerevent_quit(struct map_session_data *sd)
-{
- const struct TimerData *td;
- struct npc_data *nd;
- struct timer_event_data *ted;
-
- // Check timer existance
- if (sd->npc_timer_id == INVALID_TIMER)
- return;
- if (!(td = get_timer(sd->npc_timer_id))) {
- sd->npc_timer_id = INVALID_TIMER;
- return;
- }
-
- // Delete timer
- nd = (struct npc_data *)map_id2bl(td->id);
- ted = (struct timer_event_data *)td->data;
- delete_timer(sd->npc_timer_id, npc_timerevent);
- sd->npc_timer_id = INVALID_TIMER;
-
- // Execute OnTimerQuit
- if (nd && nd->bl.type == BL_NPC) {
- char buf[EVENT_NAME_LENGTH];
- struct event_data *ev;
-
- snprintf(buf, ARRAYLENGTH(buf), "%s::OnTimerQuit", nd->exname);
- ev = (struct event_data *)strdb_get(ev_db, buf);
- if (ev && ev->nd != nd) {
- ShowWarning("npc_timerevent_quit: Unable to execute \"OnTimerQuit\", two NPCs have the same event name [%s]!\n",buf);
- ev = NULL;
- }
- if (ev) {
- int old_rid,old_timer;
- unsigned int old_tick;
-
- //Set timer related info.
- old_rid = (nd->u.scr.rid == sd->bl.id ? 0 : nd->u.scr.rid); // Detach rid if the last attached player logged off.
- old_tick = nd->u.scr.timertick;
- old_timer = nd->u.scr.timer;
-
- nd->u.scr.rid = sd->bl.id;
- nd->u.scr.timertick = gettick();
- nd->u.scr.timer = ted->time;
-
- //Execute label
- run_script(nd->u.scr.script,ev->pos,sd->bl.id,nd->bl.id);
-
- //Restore previous data.
- nd->u.scr.rid = old_rid;
- nd->u.scr.timer = old_timer;
- nd->u.scr.timertick = old_tick;
- }
- }
- ers_free(timer_event_ers, ted);
+void npc_timerevent_quit(struct map_session_data* sd)
+{
+ const struct TimerData *td;
+ struct npc_data* nd;
+ struct timer_event_data *ted;
+
+ // Check timer existance
+ if( sd->npc_timer_id == INVALID_TIMER )
+ return;
+ if( !(td = get_timer(sd->npc_timer_id)) )
+ {
+ sd->npc_timer_id = INVALID_TIMER;
+ return;
+ }
+
+ // Delete timer
+ nd = (struct npc_data *)map_id2bl(td->id);
+ ted = (struct timer_event_data*)td->data;
+ delete_timer(sd->npc_timer_id, npc_timerevent);
+ sd->npc_timer_id = INVALID_TIMER;
+
+ // Execute OnTimerQuit
+ if( nd && nd->bl.type == BL_NPC )
+ {
+ char buf[EVENT_NAME_LENGTH];
+ struct event_data *ev;
+
+ snprintf(buf, ARRAYLENGTH(buf), "%s::OnTimerQuit", nd->exname);
+ ev = (struct event_data*)strdb_get(ev_db, buf);
+ if( ev && ev->nd != nd )
+ {
+ ShowWarning("npc_timerevent_quit: Unable to execute \"OnTimerQuit\", two NPCs have the same event name [%s]!\n",buf);
+ ev = NULL;
+ }
+ if( ev )
+ {
+ int old_rid,old_timer;
+ unsigned int old_tick;
+
+ //Set timer related info.
+ old_rid = (nd->u.scr.rid == sd->bl.id ? 0 : nd->u.scr.rid); // Detach rid if the last attached player logged off.
+ old_tick = nd->u.scr.timertick;
+ old_timer = nd->u.scr.timer;
+
+ nd->u.scr.rid = sd->bl.id;
+ nd->u.scr.timertick = gettick();
+ nd->u.scr.timer = ted->time;
+
+ //Execute label
+ run_script(nd->u.scr.script,ev->pos,sd->bl.id,nd->bl.id);
+
+ //Restore previous data.
+ nd->u.scr.rid = old_rid;
+ nd->u.scr.timer = old_timer;
+ nd->u.scr.timertick = old_tick;
+ }
+ }
+ ers_free(timer_event_ers, ted);
}
/*==========================================
* Get the tick value of an NPC timer
* If it's stopped, return stopped time
*------------------------------------------*/
-int npc_gettimerevent_tick(struct npc_data *nd)
+int npc_gettimerevent_tick(struct npc_data* nd)
{
- int tick;
- nullpo_ret(nd);
+ int tick;
+ nullpo_ret(nd);
- // TODO: Get player attached timer's tick. Now we can just get it by using 'getnpctimer' inside OnTimer event.
+ // TODO: Get player attached timer's tick. Now we can just get it by using 'getnpctimer' inside OnTimer event.
- tick = nd->u.scr.timer; // The last time it's active(start, stop or event trigger)
- if (nd->u.scr.timertick) // It's a running timer
- tick += DIFF_TICK(gettick(), nd->u.scr.timertick);
+ tick = nd->u.scr.timer; // The last time it's active(start, stop or event trigger)
+ if( nd->u.scr.timertick ) // It's a running timer
+ tick += DIFF_TICK(gettick(), nd->u.scr.timertick);
- return tick;
+ return tick;
}
/*==========================================
* Set tick for running and stopped timer
*------------------------------------------*/
-int npc_settimerevent_tick(struct npc_data *nd, int newtimer)
+int npc_settimerevent_tick(struct npc_data* nd, int newtimer)
{
- bool flag;
- int old_rid;
- //struct map_session_data *sd = NULL;
+ bool flag;
+ int old_rid;
+ //struct map_session_data *sd = NULL;
- nullpo_ret(nd);
+ nullpo_ret(nd);
- // TODO: Set player attached timer's tick.
+ // TODO: Set player attached timer's tick.
- old_rid = nd->u.scr.rid;
- nd->u.scr.rid = 0;
+ old_rid = nd->u.scr.rid;
+ nd->u.scr.rid = 0;
- // Check if timer is started
- flag = (nd->u.scr.timerid != INVALID_TIMER);
+ // Check if timer is started
+ flag = (nd->u.scr.timerid != INVALID_TIMER);
- if (flag) npc_timerevent_stop(nd);
- nd->u.scr.timer = newtimer;
- if (flag) npc_timerevent_start(nd, -1);
+ if( flag ) npc_timerevent_stop(nd);
+ nd->u.scr.timer = newtimer;
+ if( flag ) npc_timerevent_start(nd, -1);
- nd->u.scr.rid = old_rid;
- return 0;
+ nd->u.scr.rid = old_rid;
+ return 0;
}
-int npc_event_sub(struct map_session_data *sd, struct event_data *ev, const char *eventname)
+int npc_event_sub(struct map_session_data* sd, struct event_data* ev, const char* eventname)
{
- if (sd->npc_id != 0) {
- //Enqueue the event trigger.
- int i;
- ARR_FIND(0, MAX_EVENTQUEUE, i, sd->eventqueue[i][0] == '\0');
- if (i < MAX_EVENTQUEUE) {
- safestrncpy(sd->eventqueue[i],eventname,50); //Event enqueued.
- return 0;
- }
+ if ( sd->npc_id != 0 )
+ {
+ //Enqueue the event trigger.
+ int i;
+ ARR_FIND( 0, MAX_EVENTQUEUE, i, sd->eventqueue[i][0] == '\0' );
+ if( i < MAX_EVENTQUEUE )
+ {
+ safestrncpy(sd->eventqueue[i],eventname,50); //Event enqueued.
+ return 0;
+ }
- ShowWarning("npc_event: player's event queue is full, can't add event '%s' !\n", eventname);
- return 1;
- }
- if (ev->nd->sc.option&OPTION_INVISIBLE) {
- //Disabled npc, shouldn't trigger event.
- npc_event_dequeue(sd);
- return 2;
- }
- run_script(ev->nd->u.scr.script,ev->pos,sd->bl.id,ev->nd->bl.id);
- return 0;
+ ShowWarning("npc_event: player's event queue is full, can't add event '%s' !\n", eventname);
+ return 1;
+ }
+ if( ev->nd->sc.option&OPTION_INVISIBLE )
+ {
+ //Disabled npc, shouldn't trigger event.
+ npc_event_dequeue(sd);
+ return 2;
+ }
+ run_script(ev->nd->u.scr.script,ev->pos,sd->bl.id,ev->nd->bl.id);
+ return 0;
}
/*==========================================
* NPC processing event type
*------------------------------------------*/
-int npc_event(struct map_session_data *sd, const char *eventname, int ontouch)
+int npc_event(struct map_session_data* sd, const char* eventname, int ontouch)
{
- struct event_data *ev = (struct event_data *)strdb_get(ev_db, eventname);
- struct npc_data *nd;
+ struct event_data* ev = (struct event_data*)strdb_get(ev_db, eventname);
+ struct npc_data *nd;
- nullpo_ret(sd);
+ nullpo_ret(sd);
- if (ev == NULL || (nd = ev->nd) == NULL) {
- if (!ontouch)
- ShowError("npc_event: event not found [%s]\n", eventname);
- return ontouch;
- }
+ if( ev == NULL || (nd = ev->nd) == NULL )
+ {
+ if( !ontouch )
+ ShowError("npc_event: event not found [%s]\n", eventname);
+ return ontouch;
+ }
- switch (ontouch) {
- case 1:
- nd->touching_id = sd->bl.id;
- sd->touching_id = nd->bl.id;
- break;
- case 2:
- sd->areanpc_id = nd->bl.id;
- break;
- }
+ switch(ontouch)
+ {
+ case 1:
+ nd->touching_id = sd->bl.id;
+ sd->touching_id = nd->bl.id;
+ break;
+ case 2:
+ sd->areanpc_id = nd->bl.id;
+ break;
+ }
- return npc_event_sub(sd,ev,eventname);
+ return npc_event_sub(sd,ev,eventname);
}
/*==========================================
@@ -808,175 +820,181 @@ int npc_event(struct map_session_data *sd, const char *eventname, int ontouch)
*------------------------------------------*/
int npc_touch_areanpc_sub(struct block_list *bl, va_list ap)
{
- struct map_session_data *sd;
- int pc_id;
- char *name;
+ struct map_session_data *sd;
+ int pc_id;
+ char *name;
- nullpo_ret(bl);
- nullpo_ret((sd = map_id2sd(bl->id)));
+ nullpo_ret(bl);
+ nullpo_ret((sd = map_id2sd(bl->id)));
- pc_id = va_arg(ap,int);
- name = va_arg(ap,char *);
+ pc_id = va_arg(ap,int);
+ name = va_arg(ap,char*);
- if (pc_ishiding(sd))
- return 0;
- if (pc_id == sd->bl.id)
- return 0;
+ if( pc_ishiding(sd) )
+ return 0;
+ if( pc_id == sd->bl.id )
+ return 0;
- npc_event(sd,name,1);
+ npc_event(sd,name,1);
- return 1;
+ return 1;
}
/*==========================================
* Chk if sd is still touching his assigned npc.
* If not, it unsets it and searches for another player in range.
*------------------------------------------*/
-int npc_touchnext_areanpc(struct map_session_data *sd, bool leavemap)
+int npc_touchnext_areanpc(struct map_session_data* sd, bool leavemap)
{
- struct npc_data *nd = map_id2nd(sd->touching_id);
- short xs, ys;
+ struct npc_data *nd = map_id2nd(sd->touching_id);
+ short xs, ys;
- if (!nd || nd->touching_id != sd->bl.id)
- return 1;
+ if( !nd || nd->touching_id != sd->bl.id )
+ return 1;
- xs = nd->u.scr.xs;
- ys = nd->u.scr.ys;
+ xs = nd->u.scr.xs;
+ ys = nd->u.scr.ys;
- if (sd->bl.m != nd->bl.m ||
- sd->bl.x < nd->bl.x - xs || sd->bl.x > nd->bl.x + xs ||
- sd->bl.y < nd->bl.y - ys || sd->bl.y > nd->bl.y + ys ||
- pc_ishiding(sd) || leavemap) {
- char name[EVENT_NAME_LENGTH];
+ if( sd->bl.m != nd->bl.m ||
+ sd->bl.x < nd->bl.x - xs || sd->bl.x > nd->bl.x + xs ||
+ sd->bl.y < nd->bl.y - ys || sd->bl.y > nd->bl.y + ys ||
+ pc_ishiding(sd) || leavemap )
+ {
+ char name[EVENT_NAME_LENGTH];
- nd->touching_id = sd->touching_id = 0;
- snprintf(name, ARRAYLENGTH(name), "%s::%s", nd->exname, script_config.ontouch_name);
- map_forcountinarea(npc_touch_areanpc_sub,nd->bl.m,nd->bl.x - xs,nd->bl.y - ys,nd->bl.x + xs,nd->bl.y + ys,1,BL_PC,sd->bl.id,name);
- }
- return 0;
+ nd->touching_id = sd->touching_id = 0;
+ snprintf(name, ARRAYLENGTH(name), "%s::%s", nd->exname, script_config.ontouch_name);
+ map_forcountinarea(npc_touch_areanpc_sub,nd->bl.m,nd->bl.x - xs,nd->bl.y - ys,nd->bl.x + xs,nd->bl.y + ys,1,BL_PC,sd->bl.id,name);
+ }
+ return 0;
}
/*==========================================
* Exec OnTouch for player if in range of area event
*------------------------------------------*/
-int npc_touch_areanpc(struct map_session_data *sd, int m, int x, int y)
-{
- int xs,ys;
- int f = 1;
- int i;
-
- nullpo_retr(1, sd);
-
- // Why not enqueue it? [Inkfish]
- //if(sd->npc_id)
- // return 1;
-
- for (i=0; i<map[m].npc_num; i++) {
- if (map[m].npc[i]->sc.option&OPTION_INVISIBLE) {
- f=0; // a npc was found, but it is disabled; don't print warning
- continue;
- }
-
- switch (map[m].npc[i]->subtype) {
- case WARP:
- xs=map[m].npc[i]->u.warp.xs;
- ys=map[m].npc[i]->u.warp.ys;
- break;
- case SCRIPT:
- xs=map[m].npc[i]->u.scr.xs;
- ys=map[m].npc[i]->u.scr.ys;
- break;
- default:
- continue;
- }
- if (x >= map[m].npc[i]->bl.x-xs && x <= map[m].npc[i]->bl.x+xs
- && y >= map[m].npc[i]->bl.y-ys && y <= map[m].npc[i]->bl.y+ys)
- break;
- }
- if (i == map[m].npc_num) {
- if (f == 1) // no npc found
- ShowError("npc_touch_areanpc : stray NPC cell/NPC not found in the block on coordinates '%s',%d,%d\n", map[m].name, x, y);
- return 1;
- }
- switch (map[m].npc[i]->subtype) {
- case WARP:
- if (pc_ishiding(sd) || (sd->sc.count && sd->sc.data[SC_CAMOUFLAGE]))
- break; // hidden chars cannot use warps
- pc_setpos(sd,map[m].npc[i]->u.warp.mapindex,map[m].npc[i]->u.warp.x,map[m].npc[i]->u.warp.y,CLR_OUTSIGHT);
- break;
- case SCRIPT:
- if (npc_ontouch_event(sd,map[m].npc[i]) > 0 && npc_ontouch2_event(sd,map[m].npc[i]) > 0) {
- // failed to run OnTouch event, so just click the npc
- struct unit_data *ud = unit_bl2ud(&sd->bl);
- if (ud && ud->walkpath.path_pos < ud->walkpath.path_len) {
- // Since walktimer always == INVALID_TIMER at this time, we stop walking manually. [Inkfish]
- clif_fixpos(&sd->bl);
- ud->walkpath.path_pos = ud->walkpath.path_len;
- }
- sd->areanpc_id = map[m].npc[i]->bl.id;
- npc_click(sd,map[m].npc[i]);
- }
- break;
- }
- return 0;
+int npc_touch_areanpc(struct map_session_data* sd, int m, int x, int y)
+{
+ int xs,ys;
+ int f = 1;
+ int i;
+
+ nullpo_retr(1, sd);
+
+ // Why not enqueue it? [Inkfish]
+ //if(sd->npc_id)
+ // return 1;
+
+ for(i=0;i<map[m].npc_num;i++)
+ {
+ if (map[m].npc[i]->sc.option&OPTION_INVISIBLE) {
+ f=0; // a npc was found, but it is disabled; don't print warning
+ continue;
+ }
+
+ switch(map[m].npc[i]->subtype) {
+ case WARP:
+ xs=map[m].npc[i]->u.warp.xs;
+ ys=map[m].npc[i]->u.warp.ys;
+ break;
+ case SCRIPT:
+ xs=map[m].npc[i]->u.scr.xs;
+ ys=map[m].npc[i]->u.scr.ys;
+ break;
+ default:
+ continue;
+ }
+ if( x >= map[m].npc[i]->bl.x-xs && x <= map[m].npc[i]->bl.x+xs
+ && y >= map[m].npc[i]->bl.y-ys && y <= map[m].npc[i]->bl.y+ys )
+ break;
+ }
+ if( i == map[m].npc_num )
+ {
+ if( f == 1 ) // no npc found
+ ShowError("npc_touch_areanpc : stray NPC cell/NPC not found in the block on coordinates '%s',%d,%d\n", map[m].name, x, y);
+ return 1;
+ }
+ switch(map[m].npc[i]->subtype) {
+ case WARP:
+ if( pc_ishiding(sd) || (sd->sc.count && sd->sc.data[SC_CAMOUFLAGE]) )
+ break; // hidden chars cannot use warps
+ pc_setpos(sd,map[m].npc[i]->u.warp.mapindex,map[m].npc[i]->u.warp.x,map[m].npc[i]->u.warp.y,CLR_OUTSIGHT);
+ break;
+ case SCRIPT:
+ if( npc_ontouch_event(sd,map[m].npc[i]) > 0 && npc_ontouch2_event(sd,map[m].npc[i]) > 0 )
+ { // failed to run OnTouch event, so just click the npc
+ struct unit_data *ud = unit_bl2ud(&sd->bl);
+ if( ud && ud->walkpath.path_pos < ud->walkpath.path_len )
+ { // Since walktimer always == INVALID_TIMER at this time, we stop walking manually. [Inkfish]
+ clif_fixpos(&sd->bl);
+ ud->walkpath.path_pos = ud->walkpath.path_len;
+ }
+ sd->areanpc_id = map[m].npc[i]->bl.id;
+ npc_click(sd,map[m].npc[i]);
+ }
+ break;
+ }
+ return 0;
}
// OnTouch NPC or Warp for Mobs
// Return 1 if Warped
int npc_touch_areanpc2(struct mob_data *md)
{
- int i, m = md->bl.m, x = md->bl.x, y = md->bl.y, id;
- char eventname[EVENT_NAME_LENGTH];
- struct event_data *ev;
- int xs, ys;
-
- for (i = 0; i < map[m].npc_num; i++) {
- if (map[m].npc[i]->sc.option&OPTION_INVISIBLE)
- continue;
-
- switch (map[m].npc[i]->subtype) {
- case WARP:
- if (!(battle_config.mob_warp&1))
- continue;
- xs = map[m].npc[i]->u.warp.xs;
- ys = map[m].npc[i]->u.warp.ys;
- break;
- case SCRIPT:
- xs = map[m].npc[i]->u.scr.xs;
- ys = map[m].npc[i]->u.scr.ys;
- break;
- default:
- continue; // Keep Searching
- }
-
- if (x >= map[m].npc[i]->bl.x-xs && x <= map[m].npc[i]->bl.x+xs && y >= map[m].npc[i]->bl.y-ys && y <= map[m].npc[i]->bl.y+ys) {
- // In the npc touch area
- switch (map[m].npc[i]->subtype) {
- case WARP:
- xs = map_mapindex2mapid(map[m].npc[i]->u.warp.mapindex);
- if (m < 0)
- break; // Cannot Warp between map servers
- if (unit_warp(&md->bl, xs, map[m].npc[i]->u.warp.x, map[m].npc[i]->u.warp.y, CLR_OUTSIGHT) == 0)
- return 1; // Warped
- break;
- case SCRIPT:
- if (map[m].npc[i]->bl.id == md->areanpc_id)
- break; // Already touch this NPC
- snprintf(eventname, ARRAYLENGTH(eventname), "%s::OnTouchNPC", map[m].npc[i]->exname);
- if ((ev = (struct event_data *)strdb_get(ev_db, eventname)) == NULL || ev->nd == NULL)
- break; // No OnTouchNPC Event
- md->areanpc_id = map[m].npc[i]->bl.id;
- id = md->bl.id; // Stores Unique ID
- run_script(ev->nd->u.scr.script, ev->pos, md->bl.id, ev->nd->bl.id);
- if (map_id2md(id) == NULL) return 1; // Not Warped, but killed
- break;
- }
-
- return 0;
- }
- }
-
- return 0;
+ int i, m = md->bl.m, x = md->bl.x, y = md->bl.y, id;
+ char eventname[EVENT_NAME_LENGTH];
+ struct event_data* ev;
+ int xs, ys;
+
+ for( i = 0; i < map[m].npc_num; i++ )
+ {
+ if( map[m].npc[i]->sc.option&OPTION_INVISIBLE )
+ continue;
+
+ switch( map[m].npc[i]->subtype )
+ {
+ case WARP:
+ if( !( battle_config.mob_warp&1 ) )
+ continue;
+ xs = map[m].npc[i]->u.warp.xs;
+ ys = map[m].npc[i]->u.warp.ys;
+ break;
+ case SCRIPT:
+ xs = map[m].npc[i]->u.scr.xs;
+ ys = map[m].npc[i]->u.scr.ys;
+ break;
+ default:
+ continue; // Keep Searching
+ }
+
+ if( x >= map[m].npc[i]->bl.x-xs && x <= map[m].npc[i]->bl.x+xs && y >= map[m].npc[i]->bl.y-ys && y <= map[m].npc[i]->bl.y+ys )
+ { // In the npc touch area
+ switch( map[m].npc[i]->subtype )
+ {
+ case WARP:
+ xs = map_mapindex2mapid(map[m].npc[i]->u.warp.mapindex);
+ if( m < 0 )
+ break; // Cannot Warp between map servers
+ if( unit_warp(&md->bl, xs, map[m].npc[i]->u.warp.x, map[m].npc[i]->u.warp.y, CLR_OUTSIGHT) == 0 )
+ return 1; // Warped
+ break;
+ case SCRIPT:
+ if( map[m].npc[i]->bl.id == md->areanpc_id )
+ break; // Already touch this NPC
+ snprintf(eventname, ARRAYLENGTH(eventname), "%s::OnTouchNPC", map[m].npc[i]->exname);
+ if( (ev = (struct event_data*)strdb_get(ev_db, eventname)) == NULL || ev->nd == NULL )
+ break; // No OnTouchNPC Event
+ md->areanpc_id = map[m].npc[i]->bl.id;
+ id = md->bl.id; // Stores Unique ID
+ run_script(ev->nd->u.scr.script, ev->pos, md->bl.id, ev->nd->bl.id);
+ if( map_id2md(id) == NULL ) return 1; // Not Warped, but killed
+ break;
+ }
+
+ return 0;
+ }
+ }
+
+ return 0;
}
//Checks if there are any NPC on-touch objects on the given range.
@@ -985,111 +1003,114 @@ int npc_touch_areanpc2(struct mob_data *md)
//&2: NPCs with on-touch events.
int npc_check_areanpc(int flag, int m, int x, int y, int range)
{
- int i;
- int x0,y0,x1,y1;
- int xs,ys;
-
- if (range < 0) return 0;
- x0 = max(x-range, 0);
- y0 = max(y-range, 0);
- x1 = min(x+range, map[m].xs-1);
- y1 = min(y+range, map[m].ys-1);
-
- //First check for npc_cells on the range given
- i = 0;
- for (ys = y0; ys <= y1 && !i; ys++) {
- for (xs = x0; xs <= x1 && !i; xs++) {
- if (map_getcell(m,xs,ys,CELL_CHKNPC))
- i = 1;
- }
- }
- if (!i) return 0; //No NPC_CELLs.
-
- //Now check for the actual NPC on said range.
- for (i=0; i<map[m].npc_num; i++) {
- if (map[m].npc[i]->sc.option&OPTION_INVISIBLE)
- continue;
-
- switch (map[m].npc[i]->subtype) {
- case WARP:
- if (!(flag&1))
- continue;
- xs=map[m].npc[i]->u.warp.xs;
- ys=map[m].npc[i]->u.warp.ys;
- break;
- case SCRIPT:
- if (!(flag&2))
- continue;
- xs=map[m].npc[i]->u.scr.xs;
- ys=map[m].npc[i]->u.scr.ys;
- break;
- default:
- continue;
- }
-
- if (x1 >= map[m].npc[i]->bl.x-xs && x0 <= map[m].npc[i]->bl.x+xs
- && y1 >= map[m].npc[i]->bl.y-ys && y0 <= map[m].npc[i]->bl.y+ys)
- break; // found a npc
- }
- if (i==map[m].npc_num)
- return 0;
-
- return (map[m].npc[i]->bl.id);
+ int i;
+ int x0,y0,x1,y1;
+ int xs,ys;
+
+ if (range < 0) return 0;
+ x0 = max(x-range, 0);
+ y0 = max(y-range, 0);
+ x1 = min(x+range, map[m].xs-1);
+ y1 = min(y+range, map[m].ys-1);
+
+ //First check for npc_cells on the range given
+ i = 0;
+ for (ys = y0; ys <= y1 && !i; ys++) {
+ for(xs = x0; xs <= x1 && !i; xs++){
+ if (map_getcell(m,xs,ys,CELL_CHKNPC))
+ i = 1;
+ }
+ }
+ if (!i) return 0; //No NPC_CELLs.
+
+ //Now check for the actual NPC on said range.
+ for(i=0;i<map[m].npc_num;i++)
+ {
+ if (map[m].npc[i]->sc.option&OPTION_INVISIBLE)
+ continue;
+
+ switch(map[m].npc[i]->subtype)
+ {
+ case WARP:
+ if (!(flag&1))
+ continue;
+ xs=map[m].npc[i]->u.warp.xs;
+ ys=map[m].npc[i]->u.warp.ys;
+ break;
+ case SCRIPT:
+ if (!(flag&2))
+ continue;
+ xs=map[m].npc[i]->u.scr.xs;
+ ys=map[m].npc[i]->u.scr.ys;
+ break;
+ default:
+ continue;
+ }
+
+ if( x1 >= map[m].npc[i]->bl.x-xs && x0 <= map[m].npc[i]->bl.x+xs
+ && y1 >= map[m].npc[i]->bl.y-ys && y0 <= map[m].npc[i]->bl.y+ys )
+ break; // found a npc
+ }
+ if (i==map[m].npc_num)
+ return 0;
+
+ return (map[m].npc[i]->bl.id);
}
/*==========================================
* Chk if player not too far to access the npc.
* Returns npc_data (success) or NULL (fail).
*------------------------------------------*/
-struct npc_data *npc_checknear(struct map_session_data *sd, struct block_list *bl) {
- struct npc_data *nd;
+struct npc_data* npc_checknear(struct map_session_data* sd, struct block_list* bl)
+{
+ struct npc_data *nd;
- nullpo_retr(NULL, sd);
- if (bl == NULL) return NULL;
- if (bl->type != BL_NPC) return NULL;
- nd = (TBL_NPC *)bl;
+ nullpo_retr(NULL, sd);
+ if(bl == NULL) return NULL;
+ if(bl->type != BL_NPC) return NULL;
+ nd = (TBL_NPC*)bl;
- if (sd->state.using_fake_npc && sd->npc_id == bl->id)
- return nd;
+ if(sd->state.using_fake_npc && sd->npc_id == bl->id)
+ return nd;
- if (nd->class_<0) //Class-less npc, enable click from anywhere.
- return nd;
+ if (nd->class_<0) //Class-less npc, enable click from anywhere.
+ return nd;
- if (bl->m!=sd->bl.m ||
- bl->x<sd->bl.x-AREA_SIZE-1 || bl->x>sd->bl.x+AREA_SIZE+1 ||
- bl->y<sd->bl.y-AREA_SIZE-1 || bl->y>sd->bl.y+AREA_SIZE+1)
- return NULL;
+ if (bl->m!=sd->bl.m ||
+ bl->x<sd->bl.x-AREA_SIZE-1 || bl->x>sd->bl.x+AREA_SIZE+1 ||
+ bl->y<sd->bl.y-AREA_SIZE-1 || bl->y>sd->bl.y+AREA_SIZE+1)
+ return NULL;
- return nd;
+ return nd;
}
/*==========================================
* Make NPC talk in global chat (like npctalk)
*------------------------------------------*/
-int npc_globalmessage(const char *name, const char *mes)
+int npc_globalmessage(const char* name, const char* mes)
{
- struct npc_data *nd = npc_name2id(name);
- char temp[100];
+ struct npc_data* nd = npc_name2id(name);
+ char temp[100];
- if (!nd)
- return 0;
+ if (!nd)
+ return 0;
- snprintf(temp, sizeof(temp), "%s : %s", name, mes);
- clif_GlobalMessage(&nd->bl,temp);
+ snprintf(temp, sizeof(temp), "%s : %s", name, mes);
+ clif_GlobalMessage(&nd->bl,temp);
- return 0;
+ return 0;
}
// MvP tomb [GreenBox]
-void run_tomb(struct map_session_data *sd, struct npc_data *nd)
+void run_tomb(struct map_session_data* sd, struct npc_data* nd)
{
- char buffer[200];
+ char buffer[200];
char time[10];
strftime(time, sizeof(time), "%H:%M", localtime(&nd->u.tomb.kill_time));
- // TODO: Find exact color?
- snprintf(buffer, sizeof(buffer), msg_txt(657), nd->u.tomb.md->db->name);
+ // TODO: Find exact color?
+ snprintf(buffer, sizeof(buffer), msg_txt(657), nd->u.tomb.md->db->name);
clif_scriptmes(sd, nd->bl.id, buffer);
clif_scriptmes(sd, nd->bl.id, msg_txt(658));
@@ -1099,7 +1120,7 @@ void run_tomb(struct map_session_data *sd, struct npc_data *nd)
clif_scriptmes(sd, nd->bl.id, msg_txt(660));
- snprintf(buffer, sizeof(buffer), msg_txt(661), nd->u.tomb.killer_name[0] ? nd->u.tomb.killer_name : "Unknown");
+ snprintf(buffer, sizeof(buffer), msg_txt(661), nd->u.tomb.killer_name[0] ? nd->u.tomb.killer_name : "Unknown");
clif_scriptmes(sd, nd->bl.id, buffer);
clif_scriptclose(sd, nd->bl.id);
@@ -1109,131 +1130,131 @@ void run_tomb(struct map_session_data *sd, struct npc_data *nd)
* NPC 1st call when clicking on npc
* Do specific action for NPC type (openshop, run scripts...)
*------------------------------------------*/
-int npc_click(struct map_session_data *sd, struct npc_data *nd)
-{
- nullpo_retr(1, sd);
-
- if (sd->npc_id != 0) {
- ShowError("npc_click: npc_id != 0\n");
- return 1;
- }
-
- if (!nd) return 1;
- if ((nd = npc_checknear(sd,&nd->bl)) == NULL)
- return 1;
- //Hidden/Disabled npc.
- if (nd->class_ < 0 || nd->sc.option&(OPTION_INVISIBLE|OPTION_HIDE))
- return 1;
-
- switch (nd->subtype) {
- case SHOP:
- clif_npcbuysell(sd,nd->bl.id);
- break;
- case CASHSHOP:
- clif_cashshop_show(sd,nd);
- break;
- case SCRIPT:
- run_script(nd->u.scr.script,0,sd->bl.id,nd->bl.id);
- break;
- case TOMB:
- run_tomb(sd,nd);
- break;
- }
-
- return 0;
+int npc_click(struct map_session_data* sd, struct npc_data* nd)
+{
+ nullpo_retr(1, sd);
+
+ if (sd->npc_id != 0) {
+ ShowError("npc_click: npc_id != 0\n");
+ return 1;
+ }
+
+ if(!nd) return 1;
+ if ((nd = npc_checknear(sd,&nd->bl)) == NULL)
+ return 1;
+ //Hidden/Disabled npc.
+ if (nd->class_ < 0 || nd->sc.option&(OPTION_INVISIBLE|OPTION_HIDE))
+ return 1;
+
+ switch(nd->subtype) {
+ case SHOP:
+ clif_npcbuysell(sd,nd->bl.id);
+ break;
+ case CASHSHOP:
+ clif_cashshop_show(sd,nd);
+ break;
+ case SCRIPT:
+ run_script(nd->u.scr.script,0,sd->bl.id,nd->bl.id);
+ break;
+ case TOMB:
+ run_tomb(sd,nd);
+ break;
+ }
+
+ return 0;
}
/*==========================================
*
*------------------------------------------*/
-int npc_scriptcont(struct map_session_data *sd, int id)
-{
- nullpo_retr(1, sd);
-
- if (id != sd->npc_id) {
- TBL_NPC *nd_sd=(TBL_NPC *)map_id2bl(sd->npc_id);
- TBL_NPC *nd=(TBL_NPC *)map_id2bl(id);
- ShowDebug("npc_scriptcont: %s (sd->npc_id=%d) is not %s (id=%d).\n",
- nd_sd?(char *)nd_sd->name:"'Unknown NPC'", (int)sd->npc_id,
- nd?(char *)nd->name:"'Unknown NPC'", (int)id);
- return 1;
- }
-
- if (id != fake_nd->bl.id) { // Not item script
- if ((npc_checknear(sd,map_id2bl(id))) == NULL) {
- ShowWarning("npc_scriptcont: failed npc_checknear test.\n");
- return 1;
- }
- }
- /**
- * For the Secure NPC Timeout option (check config/Secure.h) [RR]
- **/
+int npc_scriptcont(struct map_session_data* sd, int id)
+{
+ nullpo_retr(1, sd);
+
+ if( id != sd->npc_id ){
+ TBL_NPC* nd_sd=(TBL_NPC*)map_id2bl(sd->npc_id);
+ TBL_NPC* nd=(TBL_NPC*)map_id2bl(id);
+ ShowDebug("npc_scriptcont: %s (sd->npc_id=%d) is not %s (id=%d).\n",
+ nd_sd?(char*)nd_sd->name:"'Unknown NPC'", (int)sd->npc_id,
+ nd?(char*)nd->name:"'Unknown NPC'", (int)id);
+ return 1;
+ }
+
+ if(id != fake_nd->bl.id) { // Not item script
+ if ((npc_checknear(sd,map_id2bl(id))) == NULL){
+ ShowWarning("npc_scriptcont: failed npc_checknear test.\n");
+ return 1;
+ }
+ }
+ /**
+ * For the Secure NPC Timeout option (check config/Secure.h) [RR]
+ **/
#if SECURE_NPCTIMEOUT
- /**
- * Update the last NPC iteration
- **/
- sd->npc_idle_tick = gettick();
+ /**
+ * Update the last NPC iteration
+ **/
+ sd->npc_idle_tick = gettick();
#endif
- /**
- * WPE can get to this point with a progressbar; we deny it.
- **/
- if (sd->progressbar.npc_id && DIFF_TICK(sd->progressbar.timeout,gettick()) > 0)
- return 1;
+ /**
+ * WPE can get to this point with a progressbar; we deny it.
+ **/
+ if( sd->progressbar.npc_id && DIFF_TICK(sd->progressbar.timeout,gettick()) > 0 )
+ return 1;
- run_script_main(sd->st);
+ run_script_main(sd->st);
- return 0;
+ return 0;
}
/*==========================================
* Chk if valid call then open buy or selling list
*------------------------------------------*/
-int npc_buysellsel(struct map_session_data *sd, int id, int type)
+int npc_buysellsel(struct map_session_data* sd, int id, int type)
{
- struct npc_data *nd;
+ struct npc_data *nd;
- nullpo_retr(1, sd);
+ nullpo_retr(1, sd);
- if ((nd = npc_checknear(sd,map_id2bl(id))) == NULL)
- return 1;
+ if ((nd = npc_checknear(sd,map_id2bl(id))) == NULL)
+ return 1;
- if (nd->subtype!=SHOP) {
- ShowError("no such shop npc : %d\n",id);
- if (sd->npc_id == id)
- sd->npc_id=0;
- return 1;
- }
+ if (nd->subtype!=SHOP) {
+ ShowError("no such shop npc : %d\n",id);
+ if (sd->npc_id == id)
+ sd->npc_id=0;
+ return 1;
+ }
if (nd->sc.option & OPTION_INVISIBLE) // can't buy if npc is not visible (hack?)
- return 1;
- if (nd->class_ < 0 && !sd->state.callshop) {
- // not called through a script and is not a visible NPC so an invalid call
- return 1;
- }
-
- // reset the callshop state for future calls
- sd->state.callshop = 0;
- sd->npc_shopid = id;
-
- if (type==0) {
- clif_buylist(sd,nd);
- } else {
- clif_selllist(sd);
- }
- return 0;
+ return 1;
+ if( nd->class_ < 0 && !sd->state.callshop )
+ {// not called through a script and is not a visible NPC so an invalid call
+ return 1;
+ }
+
+ // reset the callshop state for future calls
+ sd->state.callshop = 0;
+ sd->npc_shopid = id;
+
+ if (type==0) {
+ clif_buylist(sd,nd);
+ } else {
+ clif_selllist(sd);
+ }
+ return 0;
}
/*==========================================
* Cash Shop Buy List
*------------------------------------------*/
-int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, unsigned short *item_list)
+int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, unsigned short* item_list)
{
int i, j, nameid, amount, new_, w, vt;
struct npc_data *nd = (struct npc_data *)map_id2bl(sd->npc_shopid);
- if (!nd || nd->subtype != CASHSHOP)
+ if( !nd || nd->subtype != CASHSHOP )
return 1;
- if (sd->state.trading)
+ if( sd->state.trading )
return 4;
new_ = 0;
@@ -1241,23 +1262,26 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns
vt = 0; // Global Value
// Validating Process ----------------------------------------------------
- for (i = 0; i < count; i++) {
+ for( i = 0; i < count; i++ )
+ {
nameid = item_list[i*2+1];
amount = item_list[i*2+0];
- if (!itemdb_exists(nameid) || amount <= 0)
+ if( !itemdb_exists(nameid) || amount <= 0 )
return 5;
ARR_FIND(0,nd->u.shop.count,j,nd->u.shop.shop_item[j].nameid == nameid);
- if (j == nd->u.shop.count || nd->u.shop.shop_item[j].value <= 0)
+ if( j == nd->u.shop.count || nd->u.shop.shop_item[j].value <= 0 )
return 5;
- if (!itemdb_isstackable(nameid) && amount > 1) {
+ if( !itemdb_isstackable(nameid) && amount > 1 )
+ {
ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %d!\n", sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid);
amount = item_list[i*2+0] = 1;
}
- switch (pc_checkadditem(sd,nameid,amount)) {
+ switch( pc_checkadditem(sd,nameid,amount) )
+ {
case ADDITEM_NEW:
new_++;
break;
@@ -1269,19 +1293,20 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns
w += itemdb_weight(nameid) * amount;
}
- if (w + sd->weight > sd->max_weight)
+ if( w + sd->weight > sd->max_weight )
return 3;
- if (pc_inventoryblank(sd) < new_)
+ if( pc_inventoryblank(sd) < new_ )
return 3;
- if (points > vt) points = vt;
+ if( points > vt ) points = vt;
// Payment Process ----------------------------------------------------
- if (sd->kafraPoints < points || sd->cashPoints < (vt - points))
+ if( sd->kafraPoints < points || sd->cashPoints < (vt - points) )
return 6;
pc_paycash(sd,vt,points);
// Delivery Process ----------------------------------------------------
- for (i = 0; i < count; i++) {
+ for( i = 0; i < count; i++ )
+ {
struct item item_tmp;
nameid = item_list[i*2+1];
@@ -1289,7 +1314,8 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns
memset(&item_tmp,0,sizeof(item_tmp));
- if (!pet_create_egg(sd,nameid)) {
+ if( !pet_create_egg(sd,nameid) )
+ {
item_tmp.nameid = nameid;
item_tmp.identify = 1;
pc_additem(sd,&item_tmp,amount,LOG_TYPE_NPC);
@@ -1300,28 +1326,29 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns
}
//npc_buylist for script-controlled shops.
-static int npc_buylist_sub(struct map_session_data *sd, int n, unsigned short *item_list, struct npc_data *nd)
+static int npc_buylist_sub(struct map_session_data* sd, int n, unsigned short* item_list, struct npc_data* nd)
{
- char npc_ev[EVENT_NAME_LENGTH];
- int i;
- int key_nameid = 0;
- int key_amount = 0;
+ char npc_ev[EVENT_NAME_LENGTH];
+ int i;
+ int key_nameid = 0;
+ int key_amount = 0;
- // discard old contents
- script_cleararray_pc(sd, "@bought_nameid", (void *)0);
- script_cleararray_pc(sd, "@bought_quantity", (void *)0);
+ // discard old contents
+ script_cleararray_pc(sd, "@bought_nameid", (void*)0);
+ script_cleararray_pc(sd, "@bought_quantity", (void*)0);
- // save list of bought items
- for (i = 0; i < n; i++) {
- script_setarray_pc(sd, "@bought_nameid", i, (void *)(intptr_t)item_list[i*2+1], &key_nameid);
- script_setarray_pc(sd, "@bought_quantity", i, (void *)(intptr_t)item_list[i*2], &key_amount);
- }
+ // save list of bought items
+ for( i = 0; i < n; i++ )
+ {
+ script_setarray_pc(sd, "@bought_nameid", i, (void*)(intptr_t)item_list[i*2+1], &key_nameid);
+ script_setarray_pc(sd, "@bought_quantity", i, (void*)(intptr_t)item_list[i*2], &key_amount);
+ }
- // invoke event
- snprintf(npc_ev, ARRAYLENGTH(npc_ev), "%s::OnBuyItem", nd->exname);
- npc_event(sd, npc_ev, 0);
+ // invoke event
+ snprintf(npc_ev, ARRAYLENGTH(npc_ev), "%s::OnBuyItem", nd->exname);
+ npc_event(sd, npc_ev, 0);
- return 0;
+ return 0;
}
/*==========================================
@@ -1329,246 +1356,257 @@ static int npc_buylist_sub(struct map_session_data *sd, int n, unsigned short *i
*------------------------------------------*/
int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int points)
{
- struct npc_data *nd = (struct npc_data *)map_id2bl(sd->npc_shopid);
- struct item_data *item;
- int i, price, w;
+ struct npc_data *nd = (struct npc_data *)map_id2bl(sd->npc_shopid);
+ struct item_data *item;
+ int i, price, w;
- if (amount <= 0)
- return 5;
+ if( amount <= 0 )
+ return 5;
- if (points < 0)
- return 6;
+ if( points < 0 )
+ return 6;
- if (!nd || nd->subtype != CASHSHOP)
- return 1;
+ if( !nd || nd->subtype != CASHSHOP )
+ return 1;
- if (sd->state.trading)
- return 4;
+ if( sd->state.trading )
+ return 4;
- if ((item = itemdb_exists(nameid)) == NULL)
- return 5; // Invalid Item
+ if( (item = itemdb_exists(nameid)) == NULL )
+ return 5; // Invalid Item
- ARR_FIND(0, nd->u.shop.count, i, nd->u.shop.shop_item[i].nameid == nameid);
- if (i == nd->u.shop.count)
- return 5;
- if (nd->u.shop.shop_item[i].value <= 0)
- return 5;
+ ARR_FIND(0, nd->u.shop.count, i, nd->u.shop.shop_item[i].nameid == nameid);
+ if( i == nd->u.shop.count )
+ return 5;
+ if( nd->u.shop.shop_item[i].value <= 0 )
+ return 5;
- if (!itemdb_isstackable(nameid) && amount > 1) {
- ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %d!\n",
- sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid);
- amount = 1;
- }
+ if(!itemdb_isstackable(nameid) && amount > 1)
+ {
+ ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %d!\n",
+ sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid);
+ amount = 1;
+ }
- switch (pc_checkadditem(sd, nameid, amount)) {
- case ADDITEM_NEW:
- if (pc_inventoryblank(sd) == 0)
- return 3;
- break;
- case ADDITEM_OVERAMOUNT:
- return 3;
- }
+ switch( pc_checkadditem(sd, nameid, amount) )
+ {
+ case ADDITEM_NEW:
+ if( pc_inventoryblank(sd) == 0 )
+ return 3;
+ break;
+ case ADDITEM_OVERAMOUNT:
+ return 3;
+ }
- w = item->weight * amount;
- if (w + sd->weight > sd->max_weight)
- return 3;
+ w = item->weight * amount;
+ if( w + sd->weight > sd->max_weight )
+ return 3;
- if ((double)nd->u.shop.shop_item[i].value * amount > INT_MAX) {
- ShowWarning("npc_cashshop_buy: Item '%s' (%d) price overflow attempt!\n", item->name, nameid);
- ShowDebug("(NPC:'%s' (%s,%d,%d), player:'%s' (%d/%d), value:%d, amount:%d)\n", nd->exname, map[nd->bl.m].name, nd->bl.x, nd->bl.y, sd->status.name, sd->status.account_id, sd->status.char_id, nd->u.shop.shop_item[i].value, amount);
- return 5;
- }
+ if( (double)nd->u.shop.shop_item[i].value * amount > INT_MAX )
+ {
+ ShowWarning("npc_cashshop_buy: Item '%s' (%d) price overflow attempt!\n", item->name, nameid);
+ ShowDebug("(NPC:'%s' (%s,%d,%d), player:'%s' (%d/%d), value:%d, amount:%d)\n", nd->exname, map[nd->bl.m].name, nd->bl.x, nd->bl.y, sd->status.name, sd->status.account_id, sd->status.char_id, nd->u.shop.shop_item[i].value, amount);
+ return 5;
+ }
- price = nd->u.shop.shop_item[i].value * amount;
- if (points > price)
- points = price;
+ price = nd->u.shop.shop_item[i].value * amount;
+ if( points > price )
+ points = price;
- if ((sd->kafraPoints < points) || (sd->cashPoints < price - points))
- return 6;
+ if( (sd->kafraPoints < points) || (sd->cashPoints < price - points) )
+ return 6;
- pc_paycash(sd, price, points);
+ pc_paycash(sd, price, points);
- if (!pet_create_egg(sd, nameid)) {
- struct item item_tmp;
- memset(&item_tmp, 0, sizeof(struct item));
- item_tmp.nameid = nameid;
- item_tmp.identify = 1;
+ if( !pet_create_egg(sd, nameid) )
+ {
+ struct item item_tmp;
+ memset(&item_tmp, 0, sizeof(struct item));
+ item_tmp.nameid = nameid;
+ item_tmp.identify = 1;
- pc_additem(sd,&item_tmp, amount, LOG_TYPE_NPC);
- }
+ pc_additem(sd,&item_tmp, amount, LOG_TYPE_NPC);
+ }
- return 0;
+ return 0;
}
/// Player item purchase from npc shop.
///
/// @param item_list 'n' pairs <amount,itemid>
/// @return result code for clif_parse_NpcBuyListSend
-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,new_;
-
- nullpo_retr(3, sd);
- nullpo_retr(3, item_list);
-
- nd = npc_checknear(sd,map_id2bl(sd->npc_shopid));
- if (nd == NULL)
- return 3;
- if (nd->subtype != SHOP)
- return 3;
-
- z = 0;
- w = 0;
- new_ = 0;
- // process entries in buy list, one by one
- for (i = 0; i < n; ++i) {
- int nameid, amount, value;
-
- // find this entry in the shop's sell list
- ARR_FIND(0, nd->u.shop.count, j,
- item_list[i*2+1] == nd->u.shop.shop_item[j].nameid || //Normal items
- item_list[i*2+1] == itemdb_viewid(nd->u.shop.shop_item[j].nameid) //item_avail replacement
- );
-
- if (j == nd->u.shop.count)
- return 3; // no such item in shop
-
- amount = item_list[i*2+0];
- nameid = item_list[i*2+1] = nd->u.shop.shop_item[j].nameid; //item_avail replacement
- value = nd->u.shop.shop_item[j].value;
-
- if (!itemdb_exists(nameid))
- return 3; // item no longer in itemdb
-
- if (!itemdb_isstackable(nameid) && amount > 1) {
- //Exploit? You can't buy more than 1 of equipment types o.O
- ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %d!\n",
- sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid);
- amount = item_list[i*2+0] = 1;
- }
-
- if (nd->master_nd) {
- // Script-controlled shops decide by themselves, what can be bought and for what price.
- continue;
- }
-
- switch (pc_checkadditem(sd,nameid,amount)) {
- case ADDITEM_EXIST:
- break;
-
- case ADDITEM_NEW:
- new_++;
- break;
-
- case ADDITEM_OVERAMOUNT:
- return 2;
- }
-
- value = pc_modifybuyvalue(sd,value);
-
- z += (double)value * amount;
- w += itemdb_weight(nameid) * amount;
- }
-
- if (nd->master_nd != NULL) //Script-based shops.
- return npc_buylist_sub(sd,n,item_list,nd->master_nd);
-
- if (z > (double)sd->status.zeny)
- return 1; // Not enough Zeny
- if (w + sd->weight > sd->max_weight)
- return 2; // Too heavy
- if (pc_inventoryblank(sd) < new_)
- return 3; // Not enough space to store items
-
- pc_payzeny(sd,(int)z,LOG_TYPE_NPC, NULL);
-
- for (i = 0; i < n; ++i) {
- int nameid = item_list[i*2+1];
- int amount = item_list[i*2+0];
- struct item item_tmp;
-
- if (itemdb_type(nameid) == IT_PETEGG)
- pet_create_egg(sd, nameid);
- else {
- memset(&item_tmp,0,sizeof(item_tmp));
- item_tmp.nameid = nameid;
- item_tmp.identify = 1;
-
- pc_additem(sd,&item_tmp,amount,LOG_TYPE_NPC);
- }
- }
-
- // custom merchant shop exp bonus
- if (battle_config.shop_exp > 0 && z > 0 && (skill = pc_checkskill(sd,MC_DISCOUNT)) > 0) {
- if (sd->status.skill[MC_DISCOUNT].flag >= SKILL_FLAG_REPLACED_LV_0)
- skill = sd->status.skill[MC_DISCOUNT].flag - SKILL_FLAG_REPLACED_LV_0;
-
- if (skill > 0) {
- z = z * (double)skill * (double)battle_config.shop_exp/10000.;
- if (z < 1)
- z = 1;
- pc_gainexp(sd,NULL,0,(int)z, false);
- }
- }
-
- return 0;
+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,new_;
+
+ nullpo_retr(3, sd);
+ nullpo_retr(3, item_list);
+
+ nd = npc_checknear(sd,map_id2bl(sd->npc_shopid));
+ if( nd == NULL )
+ return 3;
+ if( nd->subtype != SHOP )
+ return 3;
+
+ z = 0;
+ w = 0;
+ new_ = 0;
+ // process entries in buy list, one by one
+ for( i = 0; i < n; ++i )
+ {
+ int nameid, amount, value;
+
+ // find this entry in the shop's sell list
+ ARR_FIND( 0, nd->u.shop.count, j,
+ item_list[i*2+1] == nd->u.shop.shop_item[j].nameid || //Normal items
+ item_list[i*2+1] == itemdb_viewid(nd->u.shop.shop_item[j].nameid) //item_avail replacement
+ );
+
+ if( j == nd->u.shop.count )
+ return 3; // no such item in shop
+
+ amount = item_list[i*2+0];
+ nameid = item_list[i*2+1] = nd->u.shop.shop_item[j].nameid; //item_avail replacement
+ value = nd->u.shop.shop_item[j].value;
+
+ if( !itemdb_exists(nameid) )
+ return 3; // item no longer in itemdb
+
+ if( !itemdb_isstackable(nameid) && amount > 1 )
+ { //Exploit? You can't buy more than 1 of equipment types o.O
+ ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %d!\n",
+ sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid);
+ amount = item_list[i*2+0] = 1;
+ }
+
+ if( nd->master_nd )
+ {// Script-controlled shops decide by themselves, what can be bought and for what price.
+ continue;
+ }
+
+ switch( pc_checkadditem(sd,nameid,amount) )
+ {
+ case ADDITEM_EXIST:
+ break;
+
+ case ADDITEM_NEW:
+ new_++;
+ break;
+
+ case ADDITEM_OVERAMOUNT:
+ return 2;
+ }
+
+ value = pc_modifybuyvalue(sd,value);
+
+ z += (double)value * amount;
+ w += itemdb_weight(nameid) * amount;
+ }
+
+ if( nd->master_nd != NULL ) //Script-based shops.
+ return npc_buylist_sub(sd,n,item_list,nd->master_nd);
+
+ if( z > (double)sd->status.zeny )
+ return 1; // Not enough Zeny
+ if( w + sd->weight > sd->max_weight )
+ return 2; // Too heavy
+ if( pc_inventoryblank(sd) < new_ )
+ return 3; // Not enough space to store items
+
+ pc_payzeny(sd,(int)z,LOG_TYPE_NPC, NULL);
+
+ for( i = 0; i < n; ++i )
+ {
+ int nameid = item_list[i*2+1];
+ int amount = item_list[i*2+0];
+ struct item item_tmp;
+
+ if (itemdb_type(nameid) == IT_PETEGG)
+ pet_create_egg(sd, nameid);
+ else
+ {
+ memset(&item_tmp,0,sizeof(item_tmp));
+ item_tmp.nameid = nameid;
+ item_tmp.identify = 1;
+
+ pc_additem(sd,&item_tmp,amount,LOG_TYPE_NPC);
+ }
+ }
+
+ // custom merchant shop exp bonus
+ if( battle_config.shop_exp > 0 && z > 0 && (skill = pc_checkskill(sd,MC_DISCOUNT)) > 0 )
+ {
+ if( sd->status.skill[MC_DISCOUNT].flag >= SKILL_FLAG_REPLACED_LV_0 )
+ skill = sd->status.skill[MC_DISCOUNT].flag - SKILL_FLAG_REPLACED_LV_0;
+
+ if( skill > 0 )
+ {
+ z = z * (double)skill * (double)battle_config.shop_exp/10000.;
+ if( z < 1 )
+ z = 1;
+ pc_gainexp(sd,NULL,0,(int)z, false);
+ }
+ }
+
+ return 0;
}
/// npc_selllist for script-controlled shops
-static int npc_selllist_sub(struct map_session_data *sd, int n, unsigned short *item_list, struct npc_data *nd)
-{
- char npc_ev[EVENT_NAME_LENGTH];
- char card_slot[NAME_LENGTH];
- int i, j, idx;
- int key_nameid = 0;
- int key_amount = 0;
- int key_refine = 0;
- int key_attribute = 0;
- int key_identify = 0;
- int key_card[MAX_SLOTS];
-
- // discard old contents
- script_cleararray_pc(sd, "@sold_nameid", (void *)0);
- script_cleararray_pc(sd, "@sold_quantity", (void *)0);
- script_cleararray_pc(sd, "@sold_refine", (void *)0);
- script_cleararray_pc(sd, "@sold_attribute", (void *)0);
- script_cleararray_pc(sd, "@sold_identify", (void *)0);
-
- for (j = 0; j < MAX_SLOTS; j++) {
- // clear each of the card slot entries
- key_card[j] = 0;
- snprintf(card_slot, sizeof(card_slot), "@sold_card%d", j + 1);
- script_cleararray_pc(sd, card_slot, (void *)0);
- }
-
- // save list of to be sold items
- for (i = 0; i < n; i++) {
- idx = item_list[i*2]-2;
-
- script_setarray_pc(sd, "@sold_nameid", i, (void *)(intptr_t)sd->status.inventory[idx].nameid, &key_nameid);
- script_setarray_pc(sd, "@sold_quantity", i, (void *)(intptr_t)item_list[i*2+1], &key_amount);
-
- if (itemdb_isequip(sd->status.inventory[idx].nameid)) {
- // process equipment based information into the arrays
- script_setarray_pc(sd, "@sold_refine", i, (void *)(intptr_t)sd->status.inventory[idx].refine, &key_refine);
- script_setarray_pc(sd, "@sold_attribute", i, (void *)(intptr_t)sd->status.inventory[idx].attribute, &key_attribute);
- script_setarray_pc(sd, "@sold_identify", i, (void *)(intptr_t)sd->status.inventory[idx].identify, &key_identify);
-
- for (j = 0; j < MAX_SLOTS; j++) {
- // store each of the cards from the equipment in the array
- snprintf(card_slot, sizeof(card_slot), "@sold_card%d", j + 1);
- script_setarray_pc(sd, card_slot, i, (void *)(intptr_t)sd->status.inventory[idx].card[j], &key_card[j]);
- }
- }
- }
-
- // invoke event
- snprintf(npc_ev, ARRAYLENGTH(npc_ev), "%s::OnSellItem", nd->exname);
- npc_event(sd, npc_ev, 0);
- return 0;
+static int npc_selllist_sub(struct map_session_data* sd, int n, unsigned short* item_list, struct npc_data* nd)
+{
+ char npc_ev[EVENT_NAME_LENGTH];
+ char card_slot[NAME_LENGTH];
+ int i, j, idx;
+ int key_nameid = 0;
+ int key_amount = 0;
+ int key_refine = 0;
+ int key_attribute = 0;
+ int key_identify = 0;
+ int key_card[MAX_SLOTS];
+
+ // discard old contents
+ script_cleararray_pc(sd, "@sold_nameid", (void*)0);
+ script_cleararray_pc(sd, "@sold_quantity", (void*)0);
+ script_cleararray_pc(sd, "@sold_refine", (void*)0);
+ script_cleararray_pc(sd, "@sold_attribute", (void*)0);
+ script_cleararray_pc(sd, "@sold_identify", (void*)0);
+
+ for( j = 0; j < MAX_SLOTS; j++ )
+ {// clear each of the card slot entries
+ key_card[j] = 0;
+ snprintf(card_slot, sizeof(card_slot), "@sold_card%d", j + 1);
+ script_cleararray_pc(sd, card_slot, (void*)0);
+ }
+
+ // save list of to be sold items
+ for( i = 0; i < n; i++ )
+ {
+ idx = item_list[i*2]-2;
+
+ script_setarray_pc(sd, "@sold_nameid", i, (void*)(intptr_t)sd->status.inventory[idx].nameid, &key_nameid);
+ script_setarray_pc(sd, "@sold_quantity", i, (void*)(intptr_t)item_list[i*2+1], &key_amount);
+
+ if( itemdb_isequip(sd->status.inventory[idx].nameid) )
+ {// process equipment based information into the arrays
+ script_setarray_pc(sd, "@sold_refine", i, (void*)(intptr_t)sd->status.inventory[idx].refine, &key_refine);
+ script_setarray_pc(sd, "@sold_attribute", i, (void*)(intptr_t)sd->status.inventory[idx].attribute, &key_attribute);
+ script_setarray_pc(sd, "@sold_identify", i, (void*)(intptr_t)sd->status.inventory[idx].identify, &key_identify);
+
+ for( j = 0; j < MAX_SLOTS; j++ )
+ {// store each of the cards from the equipment in the array
+ snprintf(card_slot, sizeof(card_slot), "@sold_card%d", j + 1);
+ script_setarray_pc(sd, card_slot, i, (void*)(intptr_t)sd->status.inventory[idx].card[j], &key_card[j]);
+ }
+ }
+ }
+
+ // invoke event
+ snprintf(npc_ev, ARRAYLENGTH(npc_ev), "%s::OnSellItem", nd->exname);
+ npc_event(sd, npc_ev, 0);
+ return 0;
}
@@ -1576,111 +1614,120 @@ static int npc_selllist_sub(struct map_session_data *sd, int n, unsigned short *
///
/// @param item_list 'n' pairs <index,amount>
/// @return result code for clif_parse_NpcSellListSend
-int npc_selllist(struct map_session_data *sd, int n, unsigned short *item_list)
+int npc_selllist(struct map_session_data* sd, int n, unsigned short* item_list)
{
- double z;
- int i,skill;
- struct npc_data *nd;
+ double z;
+ int i,skill;
+ struct npc_data *nd;
- nullpo_retr(1, sd);
- nullpo_retr(1, item_list);
+ nullpo_retr(1, sd);
+ nullpo_retr(1, item_list);
- if ((nd = npc_checknear(sd, map_id2bl(sd->npc_shopid))) == NULL || nd->subtype != SHOP) {
- return 1;
- }
+ if( ( nd = npc_checknear(sd, map_id2bl(sd->npc_shopid)) ) == NULL || nd->subtype != SHOP )
+ {
+ return 1;
+ }
- z = 0;
+ z = 0;
- // verify the sell list
- for (i = 0; i < n; i++) {
- int nameid, amount, idx, value;
+ // verify the sell list
+ for( i = 0; i < n; i++ )
+ {
+ int nameid, amount, idx, value;
- idx = item_list[i*2]-2;
- amount = item_list[i*2+1];
+ idx = item_list[i*2]-2;
+ amount = item_list[i*2+1];
- if (idx >= MAX_INVENTORY || idx < 0 || amount < 0) {
- return 1;
- }
+ if( idx >= MAX_INVENTORY || idx < 0 || amount < 0 )
+ {
+ return 1;
+ }
- nameid = sd->status.inventory[idx].nameid;
+ nameid = sd->status.inventory[idx].nameid;
- if (!nameid || !sd->inventory_data[idx] || sd->status.inventory[idx].amount < amount) {
- return 1;
- }
+ if( !nameid || !sd->inventory_data[idx] || sd->status.inventory[idx].amount < amount )
+ {
+ return 1;
+ }
- if (nd->master_nd) {
- // Script-controlled shops decide by themselves, what can be sold and at what price.
- continue;
- }
+ if( nd->master_nd )
+ {// Script-controlled shops decide by themselves, what can be sold and at what price.
+ continue;
+ }
- value = pc_modifysellvalue(sd, sd->inventory_data[idx]->value_sell);
+ value = pc_modifysellvalue(sd, sd->inventory_data[idx]->value_sell);
- z+= (double)value*amount;
- }
+ z+= (double)value*amount;
+ }
- if (nd->master_nd) {
- // Script-controlled shops
- return npc_selllist_sub(sd, n, item_list, nd->master_nd);
- }
+ if( nd->master_nd )
+ {// Script-controlled shops
+ return npc_selllist_sub(sd, n, item_list, nd->master_nd);
+ }
- // delete items
- for (i = 0; i < n; i++) {
- int amount, idx;
+ // delete items
+ for( i = 0; i < n; i++ )
+ {
+ int amount, idx;
- idx = item_list[i*2]-2;
- amount = item_list[i*2+1];
+ idx = item_list[i*2]-2;
+ amount = item_list[i*2+1];
- if (sd->inventory_data[idx]->type == IT_PETEGG && sd->status.inventory[idx].card[0] == CARD0_PET) {
- if (search_petDB_index(sd->status.inventory[idx].nameid, PET_EGG) >= 0) {
- intif_delete_petdata(MakeDWord(sd->status.inventory[idx].card[1], sd->status.inventory[idx].card[2]));
- }
- }
+ if( sd->inventory_data[idx]->type == IT_PETEGG && sd->status.inventory[idx].card[0] == CARD0_PET )
+ {
+ if( search_petDB_index(sd->status.inventory[idx].nameid, PET_EGG) >= 0 )
+ {
+ intif_delete_petdata(MakeDWord(sd->status.inventory[idx].card[1], sd->status.inventory[idx].card[2]));
+ }
+ }
- pc_delitem(sd, idx, amount, 0, 6, LOG_TYPE_NPC);
- }
+ pc_delitem(sd, idx, amount, 0, 6, LOG_TYPE_NPC);
+ }
- if (z > MAX_ZENY)
- z = MAX_ZENY;
+ if( z > MAX_ZENY )
+ z = MAX_ZENY;
- pc_getzeny(sd, (int)z, LOG_TYPE_NPC, NULL);
+ pc_getzeny(sd, (int)z, LOG_TYPE_NPC, NULL);
- // custom merchant shop exp bonus
- if (battle_config.shop_exp > 0 && z > 0 && (skill = pc_checkskill(sd,MC_OVERCHARGE)) > 0) {
- if (sd->status.skill[MC_OVERCHARGE].flag >= SKILL_FLAG_REPLACED_LV_0)
- skill = sd->status.skill[MC_OVERCHARGE].flag - SKILL_FLAG_REPLACED_LV_0;
+ // custom merchant shop exp bonus
+ if( battle_config.shop_exp > 0 && z > 0 && ( skill = pc_checkskill(sd,MC_OVERCHARGE) ) > 0)
+ {
+ if( sd->status.skill[MC_OVERCHARGE].flag >= SKILL_FLAG_REPLACED_LV_0 )
+ skill = sd->status.skill[MC_OVERCHARGE].flag - SKILL_FLAG_REPLACED_LV_0;
- if (skill > 0) {
- z = z * (double)skill * (double)battle_config.shop_exp/10000.;
- if (z < 1)
- z = 1;
- pc_gainexp(sd, NULL, 0, (int)z, false);
- }
- }
+ if( skill > 0 )
+ {
+ z = z * (double)skill * (double)battle_config.shop_exp/10000.;
+ if( z < 1 )
+ z = 1;
+ pc_gainexp(sd, NULL, 0, (int)z, false);
+ }
+ }
- return 0;
+ return 0;
}
//Atempt to remove an npc from a map
//This doesn't remove it from map_db
-int npc_remove_map(struct npc_data *nd)
-{
- int m,i;
- nullpo_retr(1, nd);
-
- if (nd->bl.prev == NULL || nd->bl.m < 0)
- return 1; //Not assigned to a map.
- m = nd->bl.m;
- clif_clearunit_area(&nd->bl,CLR_RESPAWN);
- npc_unsetcells(nd);
- map_delblock(&nd->bl);
- //Remove npc from map[].npc list. [Skotlex]
- ARR_FIND(0, map[m].npc_num, i, map[m].npc[i] == nd);
- if (i == map[m].npc_num) return 2; //failed to find it?
-
- map[m].npc_num--;
- map[m].npc[i] = map[m].npc[map[m].npc_num];
- map[m].npc[map[m].npc_num] = NULL;
- return 0;
+int npc_remove_map(struct npc_data* nd)
+{
+ int m,i;
+ nullpo_retr(1, nd);
+
+ if(nd->bl.prev == NULL || nd->bl.m < 0)
+ return 1; //Not assigned to a map.
+ m = nd->bl.m;
+ clif_clearunit_area(&nd->bl,CLR_RESPAWN);
+ npc_unsetcells(nd);
+ map_delblock(&nd->bl);
+ //Remove npc from map[].npc list. [Skotlex]
+ ARR_FIND( 0, map[m].npc_num, i, map[m].npc[i] == nd );
+ if( i == map[m].npc_num ) return 2; //failed to find it?
+
+ map[m].npc_num--;
+ map[m].npc[i] = map[m].npc[map[m].npc_num];
+ map[m].npc[map[m].npc_num] = NULL;
+ return 0;
}
/**
@@ -1688,119 +1735,118 @@ int npc_remove_map(struct npc_data *nd)
*/
static int npc_unload_ev(DBKey key, DBData *data, va_list ap)
{
- struct event_data *ev = db_data2ptr(data);
- char *npcname = va_arg(ap, char *);
+ struct event_data* ev = db_data2ptr(data);
+ char* npcname = va_arg(ap, char *);
- if (strcmp(ev->nd->exname,npcname)==0) {
- db_remove(ev_db, key);
- return 1;
- }
- return 0;
+ if(strcmp(ev->nd->exname,npcname)==0){
+ db_remove(ev_db, key);
+ return 1;
+ }
+ return 0;
}
//Chk if npc matches src_id, then unload.
//Sub-function used to find duplicates.
-static int npc_unload_dup_sub(struct npc_data *nd, va_list args)
+static int npc_unload_dup_sub(struct npc_data* nd, va_list args)
{
- int src_id;
+ int src_id;
- src_id = va_arg(args, int);
- if (nd->src_id == src_id)
- npc_unload(nd, true);
- return 0;
+ src_id = va_arg(args, int);
+ if (nd->src_id == src_id)
+ npc_unload(nd, true);
+ return 0;
}
//Removes all npcs that are duplicates of the passed one. [Skotlex]
-void npc_unload_duplicates(struct npc_data *nd)
+void npc_unload_duplicates(struct npc_data* nd)
{
- map_foreachnpc(npc_unload_dup_sub,nd->bl.id);
+ map_foreachnpc(npc_unload_dup_sub,nd->bl.id);
}
//Removes an npc from map and db.
//Single is to free name (for duplicates).
-int npc_unload(struct npc_data *nd, bool single)
-{
- nullpo_ret(nd);
+int npc_unload(struct npc_data* nd, bool single) {
+ nullpo_ret(nd);
- npc_remove_map(nd);
- map_deliddb(&nd->bl);
- if (single)
- strdb_remove(npcname_db, nd->exname);
+ npc_remove_map(nd);
+ map_deliddb(&nd->bl);
+ if( single )
+ strdb_remove(npcname_db, nd->exname);
- if (nd->chat_id) // remove npc chatroom object and kick users
- chat_deletenpcchat(nd);
+ if (nd->chat_id) // remove npc chatroom object and kick users
+ chat_deletenpcchat(nd);
#ifdef PCRE_SUPPORT
- npc_chat_finalize(nd); // deallocate npc PCRE data structures
+ npc_chat_finalize(nd); // deallocate npc PCRE data structures
#endif
- if (single && nd->path) {
- struct npc_path_data *npd = NULL;
- if (nd->path && nd->path != npc_last_ref) {
- npd = strdb_get(npc_path_db, nd->path);
- }
-
- if (npd && --npd->references == 0) {
- strdb_remove(npc_path_db, nd->path);/* remove from db */
- aFree(nd->path);/* remove now that no other instances exist */
- }
- }
-
- if ((nd->subtype == SHOP || nd->subtype == CASHSHOP) && nd->src_id == 0) //src check for duplicate shops [Orcao]
- aFree(nd->u.shop.shop_item);
- else if (nd->subtype == SCRIPT) {
- struct s_mapiterator *iter;
- struct block_list *bl;
-
- if (single)
- ev_db->foreach(ev_db,npc_unload_ev,nd->exname); //Clean up all events related
-
- iter = mapit_geteachpc();
- for (bl = (struct block_list *)mapit_first(iter); mapit_exists(iter); bl = (struct block_list *)mapit_next(iter)) {
- struct map_session_data *sd = ((TBL_PC *)bl);
- if (sd && sd->npc_timer_id != INVALID_TIMER) {
- const struct TimerData *td = get_timer(sd->npc_timer_id);
-
- if (td && td->id != nd->bl.id)
- continue;
-
- if (td && td->data)
- ers_free(timer_event_ers, (void *)td->data);
- delete_timer(sd->npc_timer_id, npc_timerevent);
- sd->npc_timer_id = INVALID_TIMER;
- }
- }
- mapit_free(iter);
-
- if (nd->u.scr.timerid != INVALID_TIMER) {
- const struct TimerData *td = NULL;
- td = get_timer(nd->u.scr.timerid);
- if (td && td->data)
- ers_free(timer_event_ers, (void *)td->data);
- delete_timer(nd->u.scr.timerid, npc_timerevent);
- }
- if (nd->u.scr.timer_event)
- aFree(nd->u.scr.timer_event);
- if (nd->src_id == 0) {
- if (nd->u.scr.script) {
- script_free_code(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;
- nd->u.scr.label_list_num = 0;
- }
- }
- if (nd->u.scr.guild_id)
- guild_flag_remove(nd);
- }
-
- script_stop_sleeptimers(nd->bl.id);
-
- aFree(nd);
-
- return 0;
+ if( single && nd->path ) {
+ struct npc_path_data* npd = NULL;
+ if( nd->path && nd->path != npc_last_ref ) {
+ npd = strdb_get(npc_path_db, nd->path);
+ }
+
+ if( npd && --npd->references == 0 ) {
+ strdb_remove(npc_path_db, nd->path);/* remove from db */
+ aFree(nd->path);/* remove now that no other instances exist */
+ }
+ }
+
+ if( (nd->subtype == SHOP || nd->subtype == CASHSHOP) && nd->src_id == 0) //src check for duplicate shops [Orcao]
+ aFree(nd->u.shop.shop_item);
+ else if( nd->subtype == SCRIPT ) {
+ struct s_mapiterator* iter;
+ struct block_list* bl;
+
+ if( single )
+ ev_db->foreach(ev_db,npc_unload_ev,nd->exname); //Clean up all events related
+
+ iter = mapit_geteachpc();
+ for( bl = (struct block_list*)mapit_first(iter); mapit_exists(iter); bl = (struct block_list*)mapit_next(iter) ) {
+ struct map_session_data *sd = ((TBL_PC*)bl);
+ if( sd && sd->npc_timer_id != INVALID_TIMER ) {
+ const struct TimerData *td = get_timer(sd->npc_timer_id);
+
+ if( td && td->id != nd->bl.id )
+ continue;
+
+ if( td && td->data )
+ ers_free(timer_event_ers, (void*)td->data);
+ delete_timer(sd->npc_timer_id, npc_timerevent);
+ sd->npc_timer_id = INVALID_TIMER;
+ }
+ }
+ mapit_free(iter);
+
+ if (nd->u.scr.timerid != INVALID_TIMER) {
+ const struct TimerData *td = NULL;
+ td = get_timer(nd->u.scr.timerid);
+ if (td && td->data)
+ ers_free(timer_event_ers, (void*)td->data);
+ delete_timer(nd->u.scr.timerid, npc_timerevent);
+ }
+ if (nd->u.scr.timer_event)
+ aFree(nd->u.scr.timer_event);
+ if (nd->src_id == 0) {
+ if(nd->u.scr.script) {
+ script_free_code(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;
+ nd->u.scr.label_list_num = 0;
+ }
+ }
+ if( nd->u.scr.guild_id )
+ guild_flag_remove(nd);
+ }
+
+ script_stop_sleeptimers(nd->bl.id);
+
+ aFree(nd);
+
+ return 0;
}
//
@@ -1810,369 +1856,385 @@ int npc_unload(struct npc_data *nd, bool single)
/// Clears the npc source file list
static void npc_clearsrcfile(void)
{
- struct npc_src_list *file = npc_src_files;
- struct npc_src_list *file_tofree;
+ struct npc_src_list* file = npc_src_files;
+ struct npc_src_list* file_tofree;
- while (file != NULL) {
- file_tofree = file;
- file = file->next;
- aFree(file_tofree);
- }
- npc_src_files = NULL;
+ while( file != NULL )
+ {
+ file_tofree = file;
+ file = file->next;
+ aFree(file_tofree);
+ }
+ npc_src_files = NULL;
}
/// Adds a npc source file (or removes all)
-void npc_addsrcfile(const char *name)
-{
- struct npc_src_list *file;
- struct npc_src_list *file_prev = NULL;
-
- if (strcmpi(name, "clear") == 0) {
- npc_clearsrcfile();
- return;
- }
-
- // prevent multiple insert of source files
- file = npc_src_files;
- while (file != NULL) {
- if (strcmp(name, file->name) == 0)
- return;// found the file, no need to insert it again
- file_prev = file;
- file = file->next;
- }
-
- file = (struct npc_src_list *)aMalloc(sizeof(struct npc_src_list) + strlen(name));
- file->next = NULL;
- strncpy(file->name, name, strlen(name) + 1);
- if (file_prev == NULL)
- npc_src_files = file;
- else
- file_prev->next = file;
+void npc_addsrcfile(const char* name)
+{
+ struct npc_src_list* file;
+ struct npc_src_list* file_prev = NULL;
+
+ if( strcmpi(name, "clear") == 0 )
+ {
+ npc_clearsrcfile();
+ return;
+ }
+
+ // prevent multiple insert of source files
+ file = npc_src_files;
+ while( file != NULL )
+ {
+ if( strcmp(name, file->name) == 0 )
+ return;// found the file, no need to insert it again
+ file_prev = file;
+ file = file->next;
+ }
+
+ file = (struct npc_src_list*)aMalloc(sizeof(struct npc_src_list) + strlen(name));
+ file->next = NULL;
+ strncpy(file->name, name, strlen(name) + 1);
+ if( file_prev == NULL )
+ npc_src_files = file;
+ else
+ file_prev->next = file;
}
/// Removes a npc source file (or all)
-void npc_delsrcfile(const char *name)
-{
- struct npc_src_list *file = npc_src_files;
- struct npc_src_list *file_prev = NULL;
-
- if (strcmpi(name, "all") == 0) {
- npc_clearsrcfile();
- return;
- }
-
- while (file != NULL) {
- if (strcmp(file->name, name) == 0) {
- if (npc_src_files == file)
- npc_src_files = file->next;
- else
- file_prev->next = file->next;
- aFree(file);
- break;
- }
- file_prev = file;
- file = file->next;
- }
+void npc_delsrcfile(const char* name)
+{
+ struct npc_src_list* file = npc_src_files;
+ struct npc_src_list* file_prev = NULL;
+
+ if( strcmpi(name, "all") == 0 )
+ {
+ npc_clearsrcfile();
+ return;
+ }
+
+ while( file != NULL )
+ {
+ if( strcmp(file->name, name) == 0 )
+ {
+ if( npc_src_files == file )
+ npc_src_files = file->next;
+ else
+ file_prev->next = file->next;
+ aFree(file);
+ break;
+ }
+ file_prev = file;
+ file = file->next;
+ }
}
/// Parses and sets the name and exname of a npc.
/// Assumes that m, x and y are already set in nd.
-static void npc_parsename(struct npc_data *nd, const char *name, const char *start, const char *buffer, const char *filepath)
-{
- const char *p;
- struct npc_data *dnd;// duplicate npc
- char newname[NAME_LENGTH];
-
- // parse name
- p = strstr(name,"::");
- if (p) { // <Display name>::<Unique name>
- size_t len = p-name;
- if (len > NAME_LENGTH) {
- ShowWarning("npc_parsename: Display name of '%s' is too long (len=%u) in file '%s', line'%d'. Truncating to %u characters.\n", name, (unsigned int)len, filepath, strline(buffer,start-buffer), NAME_LENGTH);
- safestrncpy(nd->name, name, sizeof(nd->name));
- } else {
- memcpy(nd->name, name, len);
- memset(nd->name+len, 0, sizeof(nd->name)-len);
- }
- len = strlen(p+2);
- if (len > NAME_LENGTH)
- ShowWarning("npc_parsename: Unique name of '%s' is too long (len=%u) in file '%s', line'%d'. Truncating to %u characters.\n", name, (unsigned int)len, filepath, strline(buffer,start-buffer), NAME_LENGTH);
- safestrncpy(nd->exname, p+2, sizeof(nd->exname));
- } else {// <Display name>
- size_t len = strlen(name);
- if (len > NAME_LENGTH)
- ShowWarning("npc_parsename: Name '%s' is too long (len=%u) in file '%s', line'%d'. Truncating to %u characters.\n", name, (unsigned int)len, filepath, strline(buffer,start-buffer), NAME_LENGTH);
- safestrncpy(nd->name, name, sizeof(nd->name));
- safestrncpy(nd->exname, name, sizeof(nd->exname));
- }
-
- if (*nd->exname == '\0' || strstr(nd->exname,"::") != NULL) { // invalid
- snprintf(newname, ARRAYLENGTH(newname), "0_%d_%d_%d", nd->bl.m, nd->bl.x, nd->bl.y);
- ShowWarning("npc_parsename: Invalid unique name in file '%s', line'%d'. Renaming '%s' to '%s'.\n", filepath, strline(buffer,start-buffer), nd->exname, newname);
- safestrncpy(nd->exname, newname, sizeof(nd->exname));
- }
-
- if ((dnd=npc_name2id(nd->exname)) != NULL) { // duplicate unique name, generate new one
- char this_mapname[32];
- char other_mapname[32];
- int i = 0;
-
- do {
- ++i;
- snprintf(newname, ARRAYLENGTH(newname), "%d_%d_%d_%d", i, nd->bl.m, nd->bl.x, nd->bl.y);
- } while (npc_name2id(newname) != NULL);
-
- strcpy(this_mapname, (nd->bl.m==-1?"(not on a map)":mapindex_id2name(map[nd->bl.m].index)));
- strcpy(other_mapname, (dnd->bl.m==-1?"(not on a map)":mapindex_id2name(map[dnd->bl.m].index)));
-
- ShowWarning("npc_parsename: Duplicate unique name in file '%s', line'%d'. Renaming '%s' to '%s'.\n", filepath, strline(buffer,start-buffer), nd->exname, newname);
- ShowDebug("this npc:\n display name '%s'\n unique name '%s'\n map=%s, x=%d, y=%d\n", nd->name, nd->exname, this_mapname, nd->bl.x, nd->bl.y);
- ShowDebug("other npc in '%s' :\n display name '%s'\n unique name '%s'\n map=%s, x=%d, y=%d\n",dnd->path, dnd->name, dnd->exname, other_mapname, dnd->bl.x, dnd->bl.y);
- safestrncpy(nd->exname, newname, sizeof(nd->exname));
- }
-
- if (npc_last_path != filepath) {
- struct npc_path_data *npd = NULL;
-
- if (!(npd = strdb_get(npc_path_db,filepath))) {
- CREATE(npd, struct npc_path_data, 1);
- strdb_put(npc_path_db, filepath, npd);
-
- CREATE(npd->path, char, strlen(filepath)+1);
- safestrncpy(npd->path, filepath, strlen(filepath)+1);
-
- npd->references = 0;
- }
-
- nd->path = npd->path;
- npd->references++;
-
- npc_last_npd = npd;
- npc_last_ref = npd->path;
- npc_last_path = (char *) filepath;
- } else {
- nd->path = npc_last_ref;
- if (npc_last_npd)
- npc_last_npd->references++;
- }
+static void npc_parsename(struct npc_data* nd, const char* name, const char* start, const char* buffer, const char* filepath)
+{
+ const char* p;
+ struct npc_data* dnd;// duplicate npc
+ char newname[NAME_LENGTH];
+
+ // parse name
+ p = strstr(name,"::");
+ if( p ) { // <Display name>::<Unique name>
+ size_t len = p-name;
+ if( len > NAME_LENGTH ) {
+ ShowWarning("npc_parsename: Display name of '%s' is too long (len=%u) in file '%s', line'%d'. Truncating to %u characters.\n", name, (unsigned int)len, filepath, strline(buffer,start-buffer), NAME_LENGTH);
+ safestrncpy(nd->name, name, sizeof(nd->name));
+ } else {
+ memcpy(nd->name, name, len);
+ memset(nd->name+len, 0, sizeof(nd->name)-len);
+ }
+ len = strlen(p+2);
+ if( len > NAME_LENGTH )
+ ShowWarning("npc_parsename: Unique name of '%s' is too long (len=%u) in file '%s', line'%d'. Truncating to %u characters.\n", name, (unsigned int)len, filepath, strline(buffer,start-buffer), NAME_LENGTH);
+ safestrncpy(nd->exname, p+2, sizeof(nd->exname));
+ } else {// <Display name>
+ size_t len = strlen(name);
+ if( len > NAME_LENGTH )
+ ShowWarning("npc_parsename: Name '%s' is too long (len=%u) in file '%s', line'%d'. Truncating to %u characters.\n", name, (unsigned int)len, filepath, strline(buffer,start-buffer), NAME_LENGTH);
+ safestrncpy(nd->name, name, sizeof(nd->name));
+ safestrncpy(nd->exname, name, sizeof(nd->exname));
+ }
+
+ if( *nd->exname == '\0' || strstr(nd->exname,"::") != NULL ) {// invalid
+ snprintf(newname, ARRAYLENGTH(newname), "0_%d_%d_%d", nd->bl.m, nd->bl.x, nd->bl.y);
+ ShowWarning("npc_parsename: Invalid unique name in file '%s', line'%d'. Renaming '%s' to '%s'.\n", filepath, strline(buffer,start-buffer), nd->exname, newname);
+ safestrncpy(nd->exname, newname, sizeof(nd->exname));
+ }
+
+ if( (dnd=npc_name2id(nd->exname)) != NULL ) {// duplicate unique name, generate new one
+ char this_mapname[32];
+ char other_mapname[32];
+ int i = 0;
+
+ do {
+ ++i;
+ snprintf(newname, ARRAYLENGTH(newname), "%d_%d_%d_%d", i, nd->bl.m, nd->bl.x, nd->bl.y);
+ } while( npc_name2id(newname) != NULL );
+
+ strcpy(this_mapname, (nd->bl.m==-1?"(not on a map)":mapindex_id2name(map[nd->bl.m].index)));
+ strcpy(other_mapname, (dnd->bl.m==-1?"(not on a map)":mapindex_id2name(map[dnd->bl.m].index)));
+
+ ShowWarning("npc_parsename: Duplicate unique name in file '%s', line'%d'. Renaming '%s' to '%s'.\n", filepath, strline(buffer,start-buffer), nd->exname, newname);
+ ShowDebug("this npc:\n display name '%s'\n unique name '%s'\n map=%s, x=%d, y=%d\n", nd->name, nd->exname, this_mapname, nd->bl.x, nd->bl.y);
+ ShowDebug("other npc in '%s' :\n display name '%s'\n unique name '%s'\n map=%s, x=%d, y=%d\n",dnd->path, dnd->name, dnd->exname, other_mapname, dnd->bl.x, dnd->bl.y);
+ safestrncpy(nd->exname, newname, sizeof(nd->exname));
+ }
+
+ if( npc_last_path != filepath ) {
+ struct npc_path_data * npd = NULL;
+
+ if( !(npd = strdb_get(npc_path_db,filepath) ) ) {
+ CREATE(npd, struct npc_path_data, 1);
+ strdb_put(npc_path_db, filepath, npd);
+
+ CREATE(npd->path, char, strlen(filepath)+1);
+ safestrncpy(npd->path, filepath, strlen(filepath)+1);
+
+ npd->references = 0;
+ }
+
+ nd->path = npd->path;
+ npd->references++;
+
+ npc_last_npd = npd;
+ npc_last_ref = npd->path;
+ npc_last_path = (char*) filepath;
+ } else {
+ nd->path = npc_last_ref;
+ if( npc_last_npd )
+ npc_last_npd->references++;
+ }
}
//Add then display an npc warp on map
-struct npc_data *npc_add_warp(char *name, short from_mapid, short from_x, short from_y, short xs, short ys, unsigned short to_mapindex, short to_x, short to_y) {
- int i, flag = 0;
- struct npc_data *nd;
-
- CREATE(nd, struct npc_data, 1);
- nd->bl.id = npc_get_new_npc_id();
- map_addnpc(from_mapid, nd);
- nd->bl.prev = nd->bl.next = NULL;
- nd->bl.m = from_mapid;
- nd->bl.x = from_x;
- nd->bl.y = from_y;
-
- safestrncpy(nd->exname, name, ARRAYLENGTH(nd->exname));
- if (npc_name2id(nd->exname) != NULL)
- flag = 1;
-
- if (flag == 1)
- snprintf(nd->exname, ARRAYLENGTH(nd->exname), "warp_%d_%d_%d", from_mapid, from_x, from_y);
-
- for (i = 0; npc_name2id(nd->exname) != NULL; ++i)
- snprintf(nd->exname, ARRAYLENGTH(nd->exname), "warp%d_%d_%d_%d", i, from_mapid, from_x, from_y);
- safestrncpy(nd->name, nd->exname, ARRAYLENGTH(nd->name));
-
- if (battle_config.warp_point_debug)
- nd->class_ = WARP_DEBUG_CLASS;
- else
- nd->class_ = WARP_CLASS;
- nd->speed = 200;
-
- nd->u.warp.mapindex = to_mapindex;
- nd->u.warp.x = to_x;
- nd->u.warp.y = to_y;
- nd->u.warp.xs = xs;
- nd->u.warp.ys = xs;
- nd->bl.type = BL_NPC;
- nd->subtype = WARP;
- npc_setcells(nd);
- map_addblock(&nd->bl);
- status_set_viewdata(&nd->bl, nd->class_);
- status_change_init(&nd->bl);
- unit_dataset(&nd->bl);
- if (map[nd->bl.m].users)
- clif_spawn(&nd->bl);
- strdb_put(npcname_db, nd->exname, nd);
-
- return nd;
+struct npc_data* npc_add_warp(char* name, short from_mapid, short from_x, short from_y, short xs, short ys, unsigned short to_mapindex, short to_x, short to_y)
+{
+ int i, flag = 0;
+ struct npc_data *nd;
+
+ CREATE(nd, struct npc_data, 1);
+ nd->bl.id = npc_get_new_npc_id();
+ map_addnpc(from_mapid, nd);
+ nd->bl.prev = nd->bl.next = NULL;
+ nd->bl.m = from_mapid;
+ nd->bl.x = from_x;
+ nd->bl.y = from_y;
+
+ safestrncpy(nd->exname, name, ARRAYLENGTH(nd->exname));
+ if (npc_name2id(nd->exname) != NULL)
+ flag = 1;
+
+ if (flag == 1)
+ snprintf(nd->exname, ARRAYLENGTH(nd->exname), "warp_%d_%d_%d", from_mapid, from_x, from_y);
+
+ for( i = 0; npc_name2id(nd->exname) != NULL; ++i )
+ snprintf(nd->exname, ARRAYLENGTH(nd->exname), "warp%d_%d_%d_%d", i, from_mapid, from_x, from_y);
+ safestrncpy(nd->name, nd->exname, ARRAYLENGTH(nd->name));
+
+ if( battle_config.warp_point_debug )
+ nd->class_ = WARP_DEBUG_CLASS;
+ else
+ nd->class_ = WARP_CLASS;
+ nd->speed = 200;
+
+ nd->u.warp.mapindex = to_mapindex;
+ nd->u.warp.x = to_x;
+ nd->u.warp.y = to_y;
+ nd->u.warp.xs = xs;
+ nd->u.warp.ys = xs;
+ nd->bl.type = BL_NPC;
+ nd->subtype = WARP;
+ npc_setcells(nd);
+ map_addblock(&nd->bl);
+ status_set_viewdata(&nd->bl, nd->class_);
+ status_change_init(&nd->bl);
+ unit_dataset(&nd->bl);
+ if( map[nd->bl.m].users )
+ clif_spawn(&nd->bl);
+ strdb_put(npcname_db, nd->exname, nd);
+
+ return nd;
}
/// Parses a warp npc.
-static const char *npc_parse_warp(char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath)
-{
- int x, y, xs, ys, to_x, to_y, m;
- unsigned short i;
- char mapname[32], to_mapname[32];
- struct npc_data *nd;
-
- // w1=<from map name>,<fromX>,<fromY>,<facing>
- // w4=<spanx>,<spany>,<to map name>,<toX>,<toY>
- if (sscanf(w1, "%31[^,],%d,%d", mapname, &x, &y) != 3
- || sscanf(w4, "%d,%d,%31[^,],%d,%d", &xs, &ys, to_mapname, &to_x, &to_y) != 5) {
- ShowError("npc_parse_warp: Invalid warp definition in file '%s', line '%d'.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
- return strchr(start,'\n');// skip and continue
- }
-
- m = map_mapname2mapid(mapname);
- i = mapindex_name2id(to_mapname);
- if (i == 0) {
- ShowError("npc_parse_warp: Unknown destination map in file '%s', line '%d' : %s\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), to_mapname, w1, w2, w3, w4);
- return strchr(start,'\n');// skip and continue
- }
-
- CREATE(nd, struct npc_data, 1);
-
- nd->bl.id = npc_get_new_npc_id();
- map_addnpc(m, nd);
- nd->bl.prev = nd->bl.next = NULL;
- nd->bl.m = m;
- nd->bl.x = x;
- nd->bl.y = y;
- npc_parsename(nd, w3, start, buffer, filepath);
-
- if (!battle_config.warp_point_debug)
- nd->class_ = WARP_CLASS;
- else
- nd->class_ = WARP_DEBUG_CLASS;
- nd->speed = 200;
-
- nd->u.warp.mapindex = i;
- nd->u.warp.x = to_x;
- nd->u.warp.y = to_y;
- nd->u.warp.xs = xs;
- nd->u.warp.ys = ys;
- npc_warp++;
- nd->bl.type = BL_NPC;
- nd->subtype = WARP;
- npc_setcells(nd);
- map_addblock(&nd->bl);
- status_set_viewdata(&nd->bl, nd->class_);
- status_change_init(&nd->bl);
- unit_dataset(&nd->bl);
- if (map[nd->bl.m].users)
- clif_spawn(&nd->bl);
- strdb_put(npcname_db, nd->exname, nd);
-
- return strchr(start,'\n');// continue
+static const char* npc_parse_warp(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath)
+{
+ int x, y, xs, ys, to_x, to_y, m;
+ unsigned short i;
+ char mapname[32], to_mapname[32];
+ struct npc_data *nd;
+
+ // w1=<from map name>,<fromX>,<fromY>,<facing>
+ // w4=<spanx>,<spany>,<to map name>,<toX>,<toY>
+ if( sscanf(w1, "%31[^,],%d,%d", mapname, &x, &y) != 3
+ || sscanf(w4, "%d,%d,%31[^,],%d,%d", &xs, &ys, to_mapname, &to_x, &to_y) != 5 )
+ {
+ ShowError("npc_parse_warp: Invalid warp definition in file '%s', line '%d'.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
+ return strchr(start,'\n');// skip and continue
+ }
+
+ m = map_mapname2mapid(mapname);
+ i = mapindex_name2id(to_mapname);
+ if( i == 0 )
+ {
+ ShowError("npc_parse_warp: Unknown destination map in file '%s', line '%d' : %s\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), to_mapname, w1, w2, w3, w4);
+ return strchr(start,'\n');// skip and continue
+ }
+
+ CREATE(nd, struct npc_data, 1);
+
+ nd->bl.id = npc_get_new_npc_id();
+ map_addnpc(m, nd);
+ nd->bl.prev = nd->bl.next = NULL;
+ nd->bl.m = m;
+ nd->bl.x = x;
+ nd->bl.y = y;
+ npc_parsename(nd, w3, start, buffer, filepath);
+
+ if (!battle_config.warp_point_debug)
+ nd->class_ = WARP_CLASS;
+ else
+ nd->class_ = WARP_DEBUG_CLASS;
+ nd->speed = 200;
+
+ nd->u.warp.mapindex = i;
+ nd->u.warp.x = to_x;
+ nd->u.warp.y = to_y;
+ nd->u.warp.xs = xs;
+ nd->u.warp.ys = ys;
+ npc_warp++;
+ nd->bl.type = BL_NPC;
+ nd->subtype = WARP;
+ npc_setcells(nd);
+ map_addblock(&nd->bl);
+ status_set_viewdata(&nd->bl, nd->class_);
+ status_change_init(&nd->bl);
+ unit_dataset(&nd->bl);
+ if( map[nd->bl.m].users )
+ clif_spawn(&nd->bl);
+ strdb_put(npcname_db, nd->exname, nd);
+
+ return strchr(start,'\n');// continue
}
/// Parses a shop/cashshop npc.
-static const char *npc_parse_shop(char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath)
-{
- //TODO: could be rewritten to NOT need this temp array [ultramage]
-#define MAX_SHOPITEM 100
- struct npc_item_list items[MAX_SHOPITEM];
- char *p;
- int x, y, dir, m, i;
- struct npc_data *nd;
- enum npc_subtype type;
-
- if (strcmp(w1,"-") == 0) {
- // 'floating' shop?
- x = y = dir = 0;
- m = -1;
- } else {
- // w1=<map name>,<x>,<y>,<facing>
- char mapname[32];
- if (sscanf(w1, "%31[^,],%d,%d,%d", mapname, &x, &y, &dir) != 4
- || strchr(w4, ',') == NULL) {
- ShowError("npc_parse_shop: Invalid shop definition in file '%s', line '%d'.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
- return strchr(start,'\n');// skip and continue
- }
-
- m = map_mapname2mapid(mapname);
- }
-
- if (!strcasecmp(w2,"cashshop"))
- type = CASHSHOP;
- else
- type = SHOP;
-
- p = strchr(w4,',');
- for (i = 0; i < ARRAYLENGTH(items) && p; ++i) {
- int nameid, value;
- struct item_data *id;
- if (sscanf(p, ",%d:%d", &nameid, &value) != 2) {
- ShowError("npc_parse_shop: Invalid item definition in file '%s', line '%d'. Ignoring the rest of the line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
- break;
- }
-
- if ((id = itemdb_exists(nameid)) == NULL) {
- ShowWarning("npc_parse_shop: Invalid sell item in file '%s', line '%d' (id '%d').\n", filepath, strline(buffer,start-buffer), nameid);
- p = strchr(p+1,',');
- continue;
- }
-
- if (value < 0) {
- if (type == SHOP) value = id->value_buy;
- else value = 0; // Cashshop doesn't have a "buy price" in the item_db
- }
-
- if (type == SHOP && value == 0) {
- // NPC selling items for free!
- ShowWarning("npc_parse_shop: Item %s [%d] is being sold for FREE in file '%s', line '%d'.\n",
- id->name, nameid, filepath, strline(buffer,start-buffer));
- }
- if (type == SHOP && value*0.75 < id->value_sell*1.24) {
- // Exploit possible: you can buy and sell back with profit
- ShowWarning("npc_parse_shop: Item %s [%d] discounted buying price (%d->%d) is less than overcharged selling price (%d->%d) at file '%s', line '%d'.\n",
- id->name, nameid, value, (int)(value*0.75), id->value_sell, (int)(id->value_sell*1.24), filepath, strline(buffer,start-buffer));
- }
- //for logs filters, atcommands and iteminfo script command
- if (id->maxchance == 0)
- id->maxchance = -1; // -1 would show that the item's sold in NPC Shop
-
- items[i].nameid = nameid;
- items[i].value = value;
- p = strchr(p+1,',');
- }
- if (i == 0) {
- ShowWarning("npc_parse_shop: Ignoring empty shop in file '%s', line '%d'.\n", filepath, strline(buffer,start-buffer));
- return strchr(start,'\n');// continue
- }
-
- CREATE(nd, struct npc_data, 1);
- CREATE(nd->u.shop.shop_item, struct npc_item_list, i);
- memcpy(nd->u.shop.shop_item, items, sizeof(struct npc_item_list)*i);
- nd->u.shop.count = i;
- nd->bl.prev = nd->bl.next = NULL;
- nd->bl.m = m;
- nd->bl.x = x;
- nd->bl.y = y;
- nd->bl.id = npc_get_new_npc_id();
- npc_parsename(nd, w3, start, buffer, filepath);
- nd->class_ = m==-1?-1:atoi(w4);
- nd->speed = 200;
-
- ++npc_shop;
- nd->bl.type = BL_NPC;
- nd->subtype = type;
- if (m >= 0) {
- // normal shop npc
- map_addnpc(m,nd);
- map_addblock(&nd->bl);
- status_set_viewdata(&nd->bl, nd->class_);
- status_change_init(&nd->bl);
- unit_dataset(&nd->bl);
- nd->ud.dir = dir;
- if (map[nd->bl.m].users)
- clif_spawn(&nd->bl);
- } else {
- // 'floating' shop?
- map_addiddb(&nd->bl);
- }
- strdb_put(npcname_db, nd->exname, nd);
-
- return strchr(start,'\n');// continue
+static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath)
+{
+ //TODO: could be rewritten to NOT need this temp array [ultramage]
+ #define MAX_SHOPITEM 100
+ struct npc_item_list items[MAX_SHOPITEM];
+ char *p;
+ int x, y, dir, m, i;
+ struct npc_data *nd;
+ enum npc_subtype type;
+
+ if( strcmp(w1,"-") == 0 )
+ {// 'floating' shop?
+ x = y = dir = 0;
+ m = -1;
+ }
+ else
+ {// w1=<map name>,<x>,<y>,<facing>
+ char mapname[32];
+ if( sscanf(w1, "%31[^,],%d,%d,%d", mapname, &x, &y, &dir) != 4
+ || strchr(w4, ',') == NULL )
+ {
+ ShowError("npc_parse_shop: Invalid shop definition in file '%s', line '%d'.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
+ return strchr(start,'\n');// skip and continue
+ }
+
+ m = map_mapname2mapid(mapname);
+ }
+
+ if( !strcasecmp(w2,"cashshop") )
+ type = CASHSHOP;
+ else
+ type = SHOP;
+
+ p = strchr(w4,',');
+ for( i = 0; i < ARRAYLENGTH(items) && p; ++i )
+ {
+ int nameid, value;
+ struct item_data* id;
+ if( sscanf(p, ",%d:%d", &nameid, &value) != 2 )
+ {
+ ShowError("npc_parse_shop: Invalid item definition in file '%s', line '%d'. Ignoring the rest of the line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
+ break;
+ }
+
+ if( (id = itemdb_exists(nameid)) == NULL )
+ {
+ ShowWarning("npc_parse_shop: Invalid sell item in file '%s', line '%d' (id '%d').\n", filepath, strline(buffer,start-buffer), nameid);
+ p = strchr(p+1,',');
+ continue;
+ }
+
+ if( value < 0 )
+ {
+ if( type == SHOP ) value = id->value_buy;
+ else value = 0; // Cashshop doesn't have a "buy price" in the item_db
+ }
+
+ if( type == SHOP && value == 0 )
+ { // NPC selling items for free!
+ ShowWarning("npc_parse_shop: Item %s [%d] is being sold for FREE in file '%s', line '%d'.\n",
+ id->name, nameid, filepath, strline(buffer,start-buffer));
+ }
+ if( type == SHOP && value*0.75 < id->value_sell*1.24 )
+ {// Exploit possible: you can buy and sell back with profit
+ ShowWarning("npc_parse_shop: Item %s [%d] discounted buying price (%d->%d) is less than overcharged selling price (%d->%d) at file '%s', line '%d'.\n",
+ id->name, nameid, value, (int)(value*0.75), id->value_sell, (int)(id->value_sell*1.24), filepath, strline(buffer,start-buffer));
+ }
+ //for logs filters, atcommands and iteminfo script command
+ if( id->maxchance == 0 )
+ id->maxchance = -1; // -1 would show that the item's sold in NPC Shop
+
+ items[i].nameid = nameid;
+ items[i].value = value;
+ p = strchr(p+1,',');
+ }
+ if( i == 0 )
+ {
+ ShowWarning("npc_parse_shop: Ignoring empty shop in file '%s', line '%d'.\n", filepath, strline(buffer,start-buffer));
+ return strchr(start,'\n');// continue
+ }
+
+ CREATE(nd, struct npc_data, 1);
+ CREATE(nd->u.shop.shop_item, struct npc_item_list, i);
+ memcpy(nd->u.shop.shop_item, items, sizeof(struct npc_item_list)*i);
+ nd->u.shop.count = i;
+ nd->bl.prev = nd->bl.next = NULL;
+ nd->bl.m = m;
+ nd->bl.x = x;
+ nd->bl.y = y;
+ nd->bl.id = npc_get_new_npc_id();
+ npc_parsename(nd, w3, start, buffer, filepath);
+ nd->class_ = m==-1?-1:atoi(w4);
+ nd->speed = 200;
+
+ ++npc_shop;
+ nd->bl.type = BL_NPC;
+ nd->subtype = type;
+ if( m >= 0 )
+ {// normal shop npc
+ map_addnpc(m,nd);
+ map_addblock(&nd->bl);
+ status_set_viewdata(&nd->bl, nd->class_);
+ status_change_init(&nd->bl);
+ unit_dataset(&nd->bl);
+ nd->ud.dir = dir;
+ if( map[nd->bl.m].users )
+ clif_spawn(&nd->bl);
+ } else
+ {// 'floating' shop?
+ map_addiddb(&nd->bl);
+ }
+ strdb_put(npcname_db, nd->exname, nd);
+
+ return strchr(start,'\n');// continue
}
/**
@@ -2182,91 +2244,102 @@ static const char *npc_parse_shop(char *w1, char *w2, char *w3, char *w4, const
*/
int npc_convertlabel_db(DBKey key, DBData *data, va_list ap)
{
- const char *lname = (const char *)key.str;
- int lpos = db_data2i(data);
- struct npc_label_list **label_list;
- int *label_list_num;
- const char *filepath;
- struct npc_label_list *label;
- const char *p;
- int len;
-
- nullpo_ret(label_list = va_arg(ap,struct npc_label_list **));
- nullpo_ret(label_list_num = va_arg(ap,int *));
- nullpo_ret(filepath = va_arg(ap,const char *));
-
- // In case of labels not terminated with ':', for user defined function support
- p = lname;
- while (ISALNUM(*p) || *p == '_')
- ++p;
- len = p-lname;
-
- // here we check if the label fit into the buffer
- if (len > 23) {
- ShowError("npc_parse_script: label name longer than 23 chars! '%s'\n (%s)", lname, filepath);
- return 0;
- }
-
- if (*label_list == NULL) {
- *label_list = (struct npc_label_list *) aCalloc(1, sizeof(struct npc_label_list));
- *label_list_num = 0;
- } else
- *label_list = (struct npc_label_list *) aRealloc(*label_list, sizeof(struct npc_label_list)*(*label_list_num+1));
- label = *label_list+*label_list_num;
-
- safestrncpy(label->name, lname, sizeof(label->name));
- label->pos = lpos;
- ++(*label_list_num);
-
- return 0;
+ const char* lname = (const char*)key.str;
+ int lpos = db_data2i(data);
+ struct npc_label_list** label_list;
+ int* label_list_num;
+ const char* filepath;
+ struct npc_label_list* label;
+ const char *p;
+ int len;
+
+ nullpo_ret(label_list = va_arg(ap,struct npc_label_list**));
+ nullpo_ret(label_list_num = va_arg(ap,int*));
+ nullpo_ret(filepath = va_arg(ap,const char*));
+
+ // In case of labels not terminated with ':', for user defined function support
+ p = lname;
+ while( ISALNUM(*p) || *p == '_' )
+ ++p;
+ len = p-lname;
+
+ // here we check if the label fit into the buffer
+ if( len > 23 )
+ {
+ ShowError("npc_parse_script: label name longer than 23 chars! '%s'\n (%s)", lname, filepath);
+ return 0;
+ }
+
+ if( *label_list == NULL )
+ {
+ *label_list = (struct npc_label_list *) aCalloc (1, sizeof(struct npc_label_list));
+ *label_list_num = 0;
+ } else
+ *label_list = (struct npc_label_list *) aRealloc (*label_list, sizeof(struct npc_label_list)*(*label_list_num+1));
+ label = *label_list+*label_list_num;
+
+ safestrncpy(label->name, lname, sizeof(label->name));
+ label->pos = lpos;
+ ++(*label_list_num);
+
+ return 0;
}
// Skip the contents of a script.
-static const char *npc_skip_script(const char *start, const char *buffer, const char *filepath)
-{
- const char *p;
- int curly_count;
-
- if (start == NULL)
- return NULL;// nothing to skip
-
- // initial bracket (assumes the previous part is ok)
- p = strchr(start,'{');
- if (p == NULL) {
- ShowError("npc_skip_script: Missing left curly in file '%s', line'%d'.", filepath, strline(buffer,start-buffer));
- return NULL;// can't continue
- }
-
- // skip everything
- for (curly_count = 1; curly_count > 0 ;) {
- p = skip_space(p+1) ;
- if (*p == '}') {
- // right curly
- --curly_count;
- } else if (*p == '{') {
- // left curly
- ++curly_count;
- } else if (*p == '"') {
- // string
- for (++p; *p != '"' ; ++p) {
- if (*p == '\\' && (unsigned char)p[-1] <= 0x7e)
- ++p;// escape sequence (not part of a multibyte character)
- else if (*p == '\0') {
- script_error(buffer, filepath, 0, "Unexpected end of string.", p);
- return NULL;// can't continue
- } else if (*p == '\n') {
- script_error(buffer, filepath, 0, "Unexpected newline at string.", p);
- return NULL;// can't continue
- }
- }
- } else if (*p == '\0') {
- // end of buffer
- ShowError("Missing %d right curlys at file '%s', line '%d'.\n", curly_count, filepath, strline(buffer,p-buffer));
- return NULL;// can't continue
- }
- }
-
- return p+1;// return after the last '}'
+static const char* npc_skip_script(const char* start, const char* buffer, const char* filepath)
+{
+ const char* p;
+ int curly_count;
+
+ if( start == NULL )
+ return NULL;// nothing to skip
+
+ // initial bracket (assumes the previous part is ok)
+ p = strchr(start,'{');
+ if( p == NULL )
+ {
+ ShowError("npc_skip_script: Missing left curly in file '%s', line'%d'.", filepath, strline(buffer,start-buffer));
+ return NULL;// can't continue
+ }
+
+ // skip everything
+ for( curly_count = 1; curly_count > 0 ; )
+ {
+ p = skip_space(p+1) ;
+ if( *p == '}' )
+ {// right curly
+ --curly_count;
+ }
+ else if( *p == '{' )
+ {// left curly
+ ++curly_count;
+ }
+ else if( *p == '"' )
+ {// string
+ for( ++p; *p != '"' ; ++p )
+ {
+ if( *p == '\\' && (unsigned char)p[-1] <= 0x7e )
+ ++p;// escape sequence (not part of a multibyte character)
+ else if( *p == '\0' )
+ {
+ script_error(buffer, filepath, 0, "Unexpected end of string.", p);
+ return NULL;// can't continue
+ }
+ else if( *p == '\n' )
+ {
+ script_error(buffer, filepath, 0, "Unexpected newline at string.", p);
+ return NULL;// can't continue
+ }
+ }
+ }
+ else if( *p == '\0' )
+ {// end of buffer
+ ShowError("Missing %d right curlys at file '%s', line '%d'.\n", curly_count, filepath, strline(buffer,p-buffer));
+ return NULL;// can't continue
+ }
+ }
+
+ return p+1;// return after the last '}'
}
/// Parses a npc script.
@@ -2274,128 +2347,136 @@ static const char *npc_skip_script(const char *start, const char *buffer, const
/// -%TAB%script%TAB%<NPC Name>%TAB%-1,{<code>}
/// <map name>,<x>,<y>,<facing>%TAB%script%TAB%<NPC Name>%TAB%<sprite id>,{<code>}
/// <map name>,<x>,<y>,<facing>%TAB%script%TAB%<NPC Name>%TAB%<sprite id>,<triggerX>,<triggerY>,{<code>}
-static const char *npc_parse_script(char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath, bool runOnInit)
-{
- int x, y, dir = 0, m, xs = 0, ys = 0, class_ = 0; // [Valaris] thanks to fov
- char mapname[32];
- struct script_code *script;
- int i;
- const char *end;
- const char *script_start;
-
- struct npc_label_list *label_list;
- int label_list_num;
- struct npc_data *nd;
-
- if (strcmp(w1, "-") == 0) {
- // floating npc
- x = 0;
- y = 0;
- m = -1;
- } else {
- // npc in a map
- if (sscanf(w1, "%31[^,],%d,%d,%d", mapname, &x, &y, &dir) != 4) {
- ShowError("npc_parse_script: Invalid placement format for a script in file '%s', line '%d'. Skipping the rest of file...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
- return NULL;// unknown format, don't continue
- }
- m = map_mapname2mapid(mapname);
- }
-
- script_start = strstr(start,",{");
- end = strchr(start,'\n');
- if (strstr(w4,",{") == NULL || script_start == NULL || (end != NULL && script_start > end)) {
- ShowError("npc_parse_script: Missing left curly ',{' in file '%s', line '%d'. Skipping the rest of the file.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
- return NULL;// can't continue
- }
- ++script_start;
-
- end = npc_skip_script(script_start, buffer, filepath);
- if (end == NULL)
- return NULL;// (simple) parse error, don't continue
-
- script = parse_script(script_start, filepath, strline(buffer,script_start-buffer), SCRIPT_USE_LABEL_DB);
- label_list = NULL;
- label_list_num = 0;
- if (script) {
- DBMap *label_db = script_get_label_db();
- label_db->foreach(label_db, npc_convertlabel_db, &label_list, &label_list_num, filepath);
- db_clear(label_db); // not needed anymore, so clear the db
- }
-
- CREATE(nd, struct npc_data, 1);
-
- if (sscanf(w4, "%d,%d,%d", &class_, &xs, &ys) == 3) {
- // OnTouch area defined
- nd->u.scr.xs = xs;
- nd->u.scr.ys = ys;
- } else {
- // no OnTouch area
- class_ = atoi(w4);
- nd->u.scr.xs = -1;
- nd->u.scr.ys = -1;
- }
-
- nd->bl.prev = nd->bl.next = NULL;
- nd->bl.m = m;
- nd->bl.x = x;
- nd->bl.y = y;
- npc_parsename(nd, w3, start, buffer, filepath);
- nd->bl.id = npc_get_new_npc_id();
- nd->class_ = class_;
- nd->speed = 200;
- nd->u.scr.script = script;
- nd->u.scr.label_list = label_list;
- nd->u.scr.label_list_num = label_list_num;
-
- ++npc_script;
- nd->bl.type = BL_NPC;
- nd->subtype = SCRIPT;
-
- if (m >= 0) {
- map_addnpc(m, nd);
- status_change_init(&nd->bl);
- unit_dataset(&nd->bl);
- nd->ud.dir = dir;
- npc_setcells(nd);
- map_addblock(&nd->bl);
- if (class_ >= 0) {
- status_set_viewdata(&nd->bl, nd->class_);
- if (map[nd->bl.m].users)
- clif_spawn(&nd->bl);
- }
- } else {
- // we skip map_addnpc, but still add it to the list of ID's
- map_addiddb(&nd->bl);
- }
- strdb_put(npcname_db, nd->exname, nd);
-
- //-----------------------------------------
- // Loop through labels to export them as necessary
- for (i = 0; i < nd->u.scr.label_list_num; i++) {
- if (npc_event_export(nd, i)) {
- ShowWarning("npc_parse_script : duplicate event %s::%s (%s)\n",
- nd->exname, nd->u.scr.label_list[i].name, filepath);
- }
- npc_timerevent_export(nd, i);
- }
-
- nd->u.scr.timerid = INVALID_TIMER;
-
- if (runOnInit) {
- char evname[EVENT_NAME_LENGTH];
- struct event_data *ev;
-
- snprintf(evname, ARRAYLENGTH(evname), "%s::OnInit", nd->exname);
-
- if ((ev = (struct event_data *)strdb_get(ev_db, evname))) {
-
- //Execute OnInit
- run_script(nd->u.scr.script,ev->pos,0,nd->bl.id);
-
- }
- }
-
- return end;
+static const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath, bool runOnInit) {
+ int x, y, dir = 0, m, xs = 0, ys = 0, class_ = 0; // [Valaris] thanks to fov
+ char mapname[32];
+ struct script_code *script;
+ int i;
+ const char* end;
+ const char* script_start;
+
+ struct npc_label_list* label_list;
+ int label_list_num;
+ struct npc_data* nd;
+
+ if( strcmp(w1, "-") == 0 )
+ {// floating npc
+ x = 0;
+ y = 0;
+ m = -1;
+ }
+ else
+ {// npc in a map
+ if( sscanf(w1, "%31[^,],%d,%d,%d", mapname, &x, &y, &dir) != 4 )
+ {
+ ShowError("npc_parse_script: Invalid placement format for a script in file '%s', line '%d'. Skipping the rest of file...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
+ return NULL;// unknown format, don't continue
+ }
+ m = map_mapname2mapid(mapname);
+ }
+
+ script_start = strstr(start,",{");
+ end = strchr(start,'\n');
+ if( strstr(w4,",{") == NULL || script_start == NULL || (end != NULL && script_start > end) )
+ {
+ ShowError("npc_parse_script: Missing left curly ',{' in file '%s', line '%d'. Skipping the rest of the file.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
+ return NULL;// can't continue
+ }
+ ++script_start;
+
+ end = npc_skip_script(script_start, buffer, filepath);
+ if( end == NULL )
+ return NULL;// (simple) parse error, don't continue
+
+ script = parse_script(script_start, filepath, strline(buffer,script_start-buffer), SCRIPT_USE_LABEL_DB);
+ label_list = NULL;
+ label_list_num = 0;
+ if( script )
+ {
+ DBMap* label_db = script_get_label_db();
+ label_db->foreach(label_db, npc_convertlabel_db, &label_list, &label_list_num, filepath);
+ db_clear(label_db); // not needed anymore, so clear the db
+ }
+
+ CREATE(nd, struct npc_data, 1);
+
+ if( sscanf(w4, "%d,%d,%d", &class_, &xs, &ys) == 3 )
+ {// OnTouch area defined
+ nd->u.scr.xs = xs;
+ nd->u.scr.ys = ys;
+ }
+ else
+ {// no OnTouch area
+ class_ = atoi(w4);
+ nd->u.scr.xs = -1;
+ nd->u.scr.ys = -1;
+ }
+
+ nd->bl.prev = nd->bl.next = NULL;
+ nd->bl.m = m;
+ nd->bl.x = x;
+ nd->bl.y = y;
+ npc_parsename(nd, w3, start, buffer, filepath);
+ nd->bl.id = npc_get_new_npc_id();
+ nd->class_ = class_;
+ nd->speed = 200;
+ nd->u.scr.script = script;
+ nd->u.scr.label_list = label_list;
+ nd->u.scr.label_list_num = label_list_num;
+
+ ++npc_script;
+ nd->bl.type = BL_NPC;
+ nd->subtype = SCRIPT;
+
+ if( m >= 0 )
+ {
+ map_addnpc(m, nd);
+ status_change_init(&nd->bl);
+ unit_dataset(&nd->bl);
+ nd->ud.dir = dir;
+ npc_setcells(nd);
+ map_addblock(&nd->bl);
+ if( class_ >= 0 )
+ {
+ status_set_viewdata(&nd->bl, nd->class_);
+ if( map[nd->bl.m].users )
+ clif_spawn(&nd->bl);
+ }
+ }
+ else
+ {
+ // we skip map_addnpc, but still add it to the list of ID's
+ map_addiddb(&nd->bl);
+ }
+ strdb_put(npcname_db, nd->exname, nd);
+
+ //-----------------------------------------
+ // Loop through labels to export them as necessary
+ for (i = 0; i < nd->u.scr.label_list_num; i++) {
+ if (npc_event_export(nd, i)) {
+ ShowWarning("npc_parse_script : duplicate event %s::%s (%s)\n",
+ nd->exname, nd->u.scr.label_list[i].name, filepath);
+ }
+ npc_timerevent_export(nd, i);
+ }
+
+ nd->u.scr.timerid = INVALID_TIMER;
+
+ if( runOnInit ) {
+ char evname[EVENT_NAME_LENGTH];
+ struct event_data *ev;
+
+ snprintf(evname, ARRAYLENGTH(evname), "%s::OnInit", nd->exname);
+
+ if( ( ev = (struct event_data*)strdb_get(ev_db, evname) ) ) {
+
+ //Execute OnInit
+ run_script(nd->u.scr.script,ev->pos,0,nd->bl.id);
+
+ }
+ }
+
+ return end;
}
/// Duplicate a warp, shop, cashshop or script. [Orcao]
@@ -2404,426 +2485,440 @@ static const char *npc_parse_script(char *w1, char *w2, char *w3, char *w4, cons
/// shop/cashshop/npc: <map name>,<x>,<y>,<facing>%TAB%duplicate(<name of target>)%TAB%<NPC Name>%TAB%<sprite id>
/// npc: -%TAB%duplicate(<name of target>)%TAB%<NPC Name>%TAB%<sprite id>,<triggerX>,<triggerY>
/// npc: <map name>,<x>,<y>,<facing>%TAB%duplicate(<name of target>)%TAB%<NPC Name>%TAB%<sprite id>,<triggerX>,<triggerY>
-const char *npc_parse_duplicate(char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath)
-{
- int x, y, dir, m, xs = -1, ys = -1, class_ = 0;
- char mapname[32];
- char srcname[128];
- int i;
- const char *end;
- size_t length;
-
- int src_id;
- int type;
- struct npc_data *nd;
- struct npc_data *dnd;
-
- end = strchr(start,'\n');
- length = strlen(w2);
-
- // get the npc being duplicated
- if (w2[length-1] != ')' || length <= 11 || length-11 >= sizeof(srcname)) {
- // does not match 'duplicate(%127s)', name is empty or too long
- ShowError("npc_parse_script: bad duplicate name in file '%s', line '%d' : %s\n", filepath, strline(buffer,start-buffer), w2);
- return end;// next line, try to continue
- }
- safestrncpy(srcname, w2+10, length-10);
-
- dnd = npc_name2id(srcname);
- if (dnd == NULL) {
- ShowError("npc_parse_script: original npc not found for duplicate in file '%s', line '%d' : %s\n", filepath, strline(buffer,start-buffer), srcname);
- return end;// next line, try to continue
- }
- src_id = dnd->bl.id;
- type = dnd->subtype;
-
- // get placement
- if ((type==SHOP || type==CASHSHOP || type==SCRIPT) && strcmp(w1, "-") == 0) {
- // floating shop/chashshop/script
- x = y = dir = 0;
- m = -1;
- } else {
- if (sscanf(w1, "%31[^,],%d,%d,%d", mapname, &x, &y, &dir) != 4) { // <map name>,<x>,<y>,<facing>
- ShowError("npc_parse_duplicate: Invalid placement format for duplicate in file '%s', line '%d'. Skipping line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
- return end;// next line, try to continue
- }
- m = map_mapname2mapid(mapname);
- }
-
- if (type == WARP && sscanf(w4, "%d,%d", &xs, &ys) == 2); // <spanx>,<spany>
- else if (type == SCRIPT && sscanf(w4, "%d,%d,%d", &class_, &xs, &ys) == 3);// <sprite id>,<triggerX>,<triggerY>
- else if (type != WARP) class_ = atoi(w4); // <sprite id>
- else {
- ShowError("npc_parse_duplicate: Invalid span format for duplicate warp in file '%s', line '%d'. Skipping line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
- return end;// next line, try to continue
- }
-
- CREATE(nd, struct npc_data, 1);
-
- nd->bl.prev = nd->bl.next = NULL;
- nd->bl.m = m;
- nd->bl.x = x;
- nd->bl.y = y;
- npc_parsename(nd, w3, start, buffer, filepath);
- nd->bl.id = npc_get_new_npc_id();
- nd->class_ = class_;
- nd->speed = 200;
- nd->src_id = src_id;
- nd->bl.type = BL_NPC;
- nd->subtype = (enum npc_subtype)type;
- switch (type) {
- case SCRIPT:
- ++npc_script;
- nd->u.scr.xs = xs;
- nd->u.scr.ys = ys;
- nd->u.scr.script = dnd->u.scr.script;
- nd->u.scr.label_list = dnd->u.scr.label_list;
- nd->u.scr.label_list_num = dnd->u.scr.label_list_num;
- break;
-
- case SHOP:
- case CASHSHOP:
- ++npc_shop;
- nd->u.shop.shop_item = dnd->u.shop.shop_item;
- nd->u.shop.count = dnd->u.shop.count;
- break;
-
- case WARP:
- ++npc_warp;
- if (!battle_config.warp_point_debug)
- nd->class_ = WARP_CLASS;
- else
- nd->class_ = WARP_DEBUG_CLASS;
- nd->u.warp.xs = xs;
- nd->u.warp.ys = ys;
- nd->u.warp.mapindex = dnd->u.warp.mapindex;
- nd->u.warp.x = dnd->u.warp.x;
- nd->u.warp.y = dnd->u.warp.y;
- break;
- }
-
- //Add the npc to its location
- if (m >= 0) {
- map_addnpc(m, nd);
- status_change_init(&nd->bl);
- unit_dataset(&nd->bl);
- nd->ud.dir = dir;
- npc_setcells(nd);
- map_addblock(&nd->bl);
- if (class_ >= 0) {
- status_set_viewdata(&nd->bl, nd->class_);
- if (map[nd->bl.m].users)
- clif_spawn(&nd->bl);
- }
- } else {
- // we skip map_addnpc, but still add it to the list of ID's
- map_addiddb(&nd->bl);
- }
- strdb_put(npcname_db, nd->exname, nd);
-
- if (type != SCRIPT)
- return end;
-
- //-----------------------------------------
- // Loop through labels to export them as necessary
- for (i = 0; i < nd->u.scr.label_list_num; i++) {
- if (npc_event_export(nd, i)) {
- ShowWarning("npc_parse_duplicate : duplicate event %s::%s (%s)\n",
- nd->exname, nd->u.scr.label_list[i].name, filepath);
- }
- npc_timerevent_export(nd, i);
- }
-
- nd->u.scr.timerid = INVALID_TIMER;
-
- return end;
+const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath)
+{
+ int x, y, dir, m, xs = -1, ys = -1, class_ = 0;
+ char mapname[32];
+ char srcname[128];
+ int i;
+ const char* end;
+ size_t length;
+
+ int src_id;
+ int type;
+ struct npc_data* nd;
+ struct npc_data* dnd;
+
+ end = strchr(start,'\n');
+ length = strlen(w2);
+
+ // get the npc being duplicated
+ if( w2[length-1] != ')' || length <= 11 || length-11 >= sizeof(srcname) )
+ {// does not match 'duplicate(%127s)', name is empty or too long
+ ShowError("npc_parse_script: bad duplicate name in file '%s', line '%d' : %s\n", filepath, strline(buffer,start-buffer), w2);
+ return end;// next line, try to continue
+ }
+ safestrncpy(srcname, w2+10, length-10);
+
+ dnd = npc_name2id(srcname);
+ if( dnd == NULL) {
+ ShowError("npc_parse_script: original npc not found for duplicate in file '%s', line '%d' : %s\n", filepath, strline(buffer,start-buffer), srcname);
+ return end;// next line, try to continue
+ }
+ src_id = dnd->bl.id;
+ type = dnd->subtype;
+
+ // get placement
+ if( (type==SHOP || type==CASHSHOP || type==SCRIPT) && strcmp(w1, "-") == 0 )
+ {// floating shop/chashshop/script
+ x = y = dir = 0;
+ m = -1;
+ }
+ else
+ {
+ if( sscanf(w1, "%31[^,],%d,%d,%d", mapname, &x, &y, &dir) != 4 )// <map name>,<x>,<y>,<facing>
+ {
+ ShowError("npc_parse_duplicate: Invalid placement format for duplicate in file '%s', line '%d'. Skipping line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
+ return end;// next line, try to continue
+ }
+ m = map_mapname2mapid(mapname);
+ }
+
+ if( type == WARP && sscanf(w4, "%d,%d", &xs, &ys) == 2 );// <spanx>,<spany>
+ else if( type == SCRIPT && sscanf(w4, "%d,%d,%d", &class_, &xs, &ys) == 3);// <sprite id>,<triggerX>,<triggerY>
+ else if( type != WARP ) class_ = atoi(w4);// <sprite id>
+ else
+ {
+ ShowError("npc_parse_duplicate: Invalid span format for duplicate warp in file '%s', line '%d'. Skipping line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
+ return end;// next line, try to continue
+ }
+
+ CREATE(nd, struct npc_data, 1);
+
+ nd->bl.prev = nd->bl.next = NULL;
+ nd->bl.m = m;
+ nd->bl.x = x;
+ nd->bl.y = y;
+ npc_parsename(nd, w3, start, buffer, filepath);
+ nd->bl.id = npc_get_new_npc_id();
+ nd->class_ = class_;
+ nd->speed = 200;
+ nd->src_id = src_id;
+ nd->bl.type = BL_NPC;
+ nd->subtype = (enum npc_subtype)type;
+ switch( type )
+ {
+ case SCRIPT:
+ ++npc_script;
+ nd->u.scr.xs = xs;
+ nd->u.scr.ys = ys;
+ nd->u.scr.script = dnd->u.scr.script;
+ nd->u.scr.label_list = dnd->u.scr.label_list;
+ nd->u.scr.label_list_num = dnd->u.scr.label_list_num;
+ break;
+
+ case SHOP:
+ case CASHSHOP:
+ ++npc_shop;
+ nd->u.shop.shop_item = dnd->u.shop.shop_item;
+ nd->u.shop.count = dnd->u.shop.count;
+ break;
+
+ case WARP:
+ ++npc_warp;
+ if( !battle_config.warp_point_debug )
+ nd->class_ = WARP_CLASS;
+ else
+ nd->class_ = WARP_DEBUG_CLASS;
+ nd->u.warp.xs = xs;
+ nd->u.warp.ys = ys;
+ nd->u.warp.mapindex = dnd->u.warp.mapindex;
+ nd->u.warp.x = dnd->u.warp.x;
+ nd->u.warp.y = dnd->u.warp.y;
+ break;
+ }
+
+ //Add the npc to its location
+ if( m >= 0 )
+ {
+ map_addnpc(m, nd);
+ status_change_init(&nd->bl);
+ unit_dataset(&nd->bl);
+ nd->ud.dir = dir;
+ npc_setcells(nd);
+ map_addblock(&nd->bl);
+ if( class_ >= 0 )
+ {
+ status_set_viewdata(&nd->bl, nd->class_);
+ if( map[nd->bl.m].users )
+ clif_spawn(&nd->bl);
+ }
+ }
+ else
+ {
+ // we skip map_addnpc, but still add it to the list of ID's
+ map_addiddb(&nd->bl);
+ }
+ strdb_put(npcname_db, nd->exname, nd);
+
+ if( type != SCRIPT )
+ return end;
+
+ //-----------------------------------------
+ // Loop through labels to export them as necessary
+ for (i = 0; i < nd->u.scr.label_list_num; i++) {
+ if (npc_event_export(nd, i)) {
+ ShowWarning("npc_parse_duplicate : duplicate event %s::%s (%s)\n",
+ nd->exname, nd->u.scr.label_list[i].name, filepath);
+ }
+ npc_timerevent_export(nd, i);
+ }
+
+ nd->u.scr.timerid = INVALID_TIMER;
+
+ return end;
+}
+
+int npc_duplicate4instance(struct npc_data *snd, int m) {
+ char newname[NAME_LENGTH];
+
+ if( map[m].instance_id == 0 )
+ return 1;
+
+ snprintf(newname, ARRAYLENGTH(newname), "dup_%d_%d", map[m].instance_id, snd->bl.id);
+ if( npc_name2id(newname) != NULL )
+ { // Name already in use
+ ShowError("npc_duplicate4instance: the npcname (%s) is already in use while trying to duplicate npc %s in instance %d.\n", newname, snd->exname, map[m].instance_id);
+ return 1;
+ }
+
+ if( snd->subtype == WARP )
+ { // Adjust destination, if instanced
+ struct npc_data *wnd = NULL; // New NPC
+ int dm = map_mapindex2mapid(snd->u.warp.mapindex), im;
+ if( dm < 0 ) return 1;
+
+ im = instance_mapid2imapid(dm, map[m].instance_id);
+ if( im == -1 )
+ {
+ ShowError("npc_duplicate4instance: warp (%s) leading to instanced map (%s), but instance map is not attached to current instance.\n", map[dm].name, snd->exname);
+ return 1;
+ }
+
+ CREATE(wnd, struct npc_data, 1);
+ wnd->bl.id = npc_get_new_npc_id();
+ map_addnpc(m, wnd);
+ wnd->bl.prev = wnd->bl.next = NULL;
+ wnd->bl.m = m;
+ wnd->bl.x = snd->bl.x;
+ wnd->bl.y = snd->bl.y;
+ safestrncpy(wnd->name, "", ARRAYLENGTH(wnd->name));
+ safestrncpy(wnd->exname, newname, ARRAYLENGTH(wnd->exname));
+ wnd->class_ = WARP_CLASS;
+ wnd->speed = 200;
+ wnd->u.warp.mapindex = map_id2index(im);
+ wnd->u.warp.x = snd->u.warp.x;
+ wnd->u.warp.y = snd->u.warp.y;
+ wnd->u.warp.xs = snd->u.warp.xs;
+ wnd->u.warp.ys = snd->u.warp.ys;
+ wnd->bl.type = BL_NPC;
+ wnd->subtype = WARP;
+ npc_setcells(wnd);
+ map_addblock(&wnd->bl);
+ status_set_viewdata(&wnd->bl, wnd->class_);
+ status_change_init(&wnd->bl);
+ unit_dataset(&wnd->bl);
+ if( map[wnd->bl.m].users )
+ clif_spawn(&wnd->bl);
+ strdb_put(npcname_db, wnd->exname, wnd);
+ }
+ else
+ {
+ static char w1[50], w2[50], w3[50], w4[50];
+ const char* stat_buf = "- call from instancing subsystem -\n";
+
+ snprintf(w1, sizeof(w1), "%s,%d,%d,%d", map[m].name, snd->bl.x, snd->bl.y, snd->ud.dir);
+ snprintf(w2, sizeof(w2), "duplicate(%s)", snd->exname);
+ snprintf(w3, sizeof(w3), "%s::%s", snd->name, newname);
+
+ if( snd->u.scr.xs >= 0 && snd->u.scr.ys >= 0 )
+ snprintf(w4, sizeof(w4), "%d,%d,%d", snd->class_, snd->u.scr.xs, snd->u.scr.ys); // Touch Area
+ else
+ snprintf(w4, sizeof(w4), "%d", snd->class_);
+
+ npc_parse_duplicate(w1, w2, w3, w4, stat_buf, stat_buf, "INSTANCING");
+ }
+
+ return 0;
}
-int npc_duplicate4instance(struct npc_data *snd, int m)
+//Set mapcell CELL_NPC to trigger event later
+void npc_setcells(struct npc_data* nd)
{
- char newname[NAME_LENGTH];
+ int m = nd->bl.m, x = nd->bl.x, y = nd->bl.y, xs, ys;
+ int i,j;
- if (map[m].instance_id == 0)
- return 1;
+ switch(nd->subtype)
+ {
+ case WARP:
+ xs = nd->u.warp.xs;
+ ys = nd->u.warp.ys;
+ break;
+ case SCRIPT:
+ xs = nd->u.scr.xs;
+ ys = nd->u.scr.ys;
+ break;
+ default:
+ return; // Other types doesn't have touch area
+ }
- snprintf(newname, ARRAYLENGTH(newname), "dup_%d_%d", map[m].instance_id, snd->bl.id);
- if (npc_name2id(newname) != NULL) {
- // Name already in use
- ShowError("npc_duplicate4instance: the npcname (%s) is already in use while trying to duplicate npc %s in instance %d.\n", newname, snd->exname, map[m].instance_id);
- return 1;
- }
+ if (m < 0 || xs < 0 || ys < 0) //invalid range or map
+ return;
- if (snd->subtype == WARP) {
- // Adjust destination, if instanced
- struct npc_data *wnd = NULL; // New NPC
- int dm = map_mapindex2mapid(snd->u.warp.mapindex), im;
- if (dm < 0) return 1;
-
- im = instance_mapid2imapid(dm, map[m].instance_id);
- if (im == -1) {
- ShowError("npc_duplicate4instance: warp (%s) leading to instanced map (%s), but instance map is not attached to current instance.\n", map[dm].name, snd->exname);
- return 1;
- }
-
- CREATE(wnd, struct npc_data, 1);
- wnd->bl.id = npc_get_new_npc_id();
- map_addnpc(m, wnd);
- wnd->bl.prev = wnd->bl.next = NULL;
- wnd->bl.m = m;
- wnd->bl.x = snd->bl.x;
- wnd->bl.y = snd->bl.y;
- safestrncpy(wnd->name, "", ARRAYLENGTH(wnd->name));
- safestrncpy(wnd->exname, newname, ARRAYLENGTH(wnd->exname));
- wnd->class_ = WARP_CLASS;
- wnd->speed = 200;
- wnd->u.warp.mapindex = map_id2index(im);
- wnd->u.warp.x = snd->u.warp.x;
- wnd->u.warp.y = snd->u.warp.y;
- wnd->u.warp.xs = snd->u.warp.xs;
- wnd->u.warp.ys = snd->u.warp.ys;
- wnd->bl.type = BL_NPC;
- wnd->subtype = WARP;
- npc_setcells(wnd);
- map_addblock(&wnd->bl);
- status_set_viewdata(&wnd->bl, wnd->class_);
- status_change_init(&wnd->bl);
- unit_dataset(&wnd->bl);
- if (map[wnd->bl.m].users)
- clif_spawn(&wnd->bl);
- strdb_put(npcname_db, wnd->exname, wnd);
- } else {
- static char w1[50], w2[50], w3[50], w4[50];
- const char *stat_buf = "- call from instancing subsystem -\n";
-
- snprintf(w1, sizeof(w1), "%s,%d,%d,%d", map[m].name, snd->bl.x, snd->bl.y, snd->ud.dir);
- snprintf(w2, sizeof(w2), "duplicate(%s)", snd->exname);
- snprintf(w3, sizeof(w3), "%s::%s", snd->name, newname);
-
- if (snd->u.scr.xs >= 0 && snd->u.scr.ys >= 0)
- snprintf(w4, sizeof(w4), "%d,%d,%d", snd->class_, snd->u.scr.xs, snd->u.scr.ys); // Touch Area
- else
- snprintf(w4, sizeof(w4), "%d", snd->class_);
-
- npc_parse_duplicate(w1, w2, w3, w4, stat_buf, stat_buf, "INSTANCING");
- }
-
- return 0;
+ for (i = y-ys; i <= y+ys; i++) {
+ for (j = x-xs; j <= x+xs; j++) {
+ if (map_getcell(m, j, i, CELL_CHKNOPASS))
+ continue;
+ map_setcell(m, j, i, CELL_NPC, true);
+ }
+ }
}
-//Set mapcell CELL_NPC to trigger event later
-void npc_setcells(struct npc_data *nd)
-{
- int m = nd->bl.m, x = nd->bl.x, y = nd->bl.y, xs, ys;
- int i,j;
-
- switch (nd->subtype) {
- case WARP:
- xs = nd->u.warp.xs;
- ys = nd->u.warp.ys;
- break;
- case SCRIPT:
- xs = nd->u.scr.xs;
- ys = nd->u.scr.ys;
- break;
- default:
- return; // Other types doesn't have touch area
- }
-
- if (m < 0 || xs < 0 || ys < 0) //invalid range or map
- return;
-
- for (i = y-ys; i <= y+ys; i++) {
- for (j = x-xs; j <= x+xs; j++) {
- if (map_getcell(m, j, i, CELL_CHKNOPASS))
- continue;
- map_setcell(m, j, i, CELL_NPC, true);
- }
- }
-}
-
-int npc_unsetcells_sub(struct block_list *bl, va_list ap)
+int npc_unsetcells_sub(struct block_list* bl, va_list ap)
{
- struct npc_data *nd = (struct npc_data *)bl;
- int id = va_arg(ap,int);
- if (nd->bl.id == id) return 0;
- npc_setcells(nd);
- return 1;
+ struct npc_data *nd = (struct npc_data*)bl;
+ int id = va_arg(ap,int);
+ if (nd->bl.id == id) return 0;
+ npc_setcells(nd);
+ return 1;
}
-void npc_unsetcells(struct npc_data *nd)
+void npc_unsetcells(struct npc_data* nd)
{
- int m = nd->bl.m, x = nd->bl.x, y = nd->bl.y, xs, ys;
- int i,j, x0, x1, y0, y1;
+ int m = nd->bl.m, x = nd->bl.x, y = nd->bl.y, xs, ys;
+ int i,j, x0, x1, y0, y1;
- if (nd->subtype == WARP) {
- xs = nd->u.warp.xs;
- ys = nd->u.warp.ys;
- } else {
- xs = nd->u.scr.xs;
- ys = nd->u.scr.ys;
- }
+ if (nd->subtype == WARP) {
+ xs = nd->u.warp.xs;
+ ys = nd->u.warp.ys;
+ } else {
+ xs = nd->u.scr.xs;
+ ys = nd->u.scr.ys;
+ }
- if (m < 0 || xs < 0 || ys < 0)
- return;
+ if (m < 0 || xs < 0 || ys < 0)
+ return;
- //Locate max range on which we can locate npc cells
- //FIXME: does this really do what it's supposed to do? [ultramage]
- for (x0 = x-xs; x0 > 0 && map_getcell(m, x0, y, CELL_CHKNPC); x0--);
- for (x1 = x+xs; x1 < map[m].xs-1 && map_getcell(m, x1, y, CELL_CHKNPC); x1++);
- for (y0 = y-ys; y0 > 0 && map_getcell(m, x, y0, CELL_CHKNPC); y0--);
- for (y1 = y+ys; y1 < map[m].ys-1 && map_getcell(m, x, y1, CELL_CHKNPC); y1++);
+ //Locate max range on which we can locate npc cells
+ //FIXME: does this really do what it's supposed to do? [ultramage]
+ for(x0 = x-xs; x0 > 0 && map_getcell(m, x0, y, CELL_CHKNPC); x0--);
+ for(x1 = x+xs; x1 < map[m].xs-1 && map_getcell(m, x1, y, CELL_CHKNPC); x1++);
+ for(y0 = y-ys; y0 > 0 && map_getcell(m, x, y0, CELL_CHKNPC); y0--);
+ for(y1 = y+ys; y1 < map[m].ys-1 && map_getcell(m, x, y1, CELL_CHKNPC); y1++);
- //Erase this npc's cells
- for (i = y-ys; i <= y+ys; i++)
- for (j = x-xs; j <= x+xs; j++)
- map_setcell(m, j, i, CELL_NPC, false);
+ //Erase this npc's cells
+ for (i = y-ys; i <= y+ys; i++)
+ for (j = x-xs; j <= x+xs; j++)
+ map_setcell(m, j, i, CELL_NPC, false);
- //Re-deploy NPC cells for other nearby npcs.
- map_foreachinarea(npc_unsetcells_sub, m, x0, y0, x1, y1, BL_NPC, nd->bl.id);
+ //Re-deploy NPC cells for other nearby npcs.
+ map_foreachinarea( npc_unsetcells_sub, m, x0, y0, x1, y1, BL_NPC, nd->bl.id );
}
-void npc_movenpc(struct npc_data *nd, int x, int y)
+void npc_movenpc(struct npc_data* nd, int x, int y)
{
- const int m = nd->bl.m;
- if (m < 0 || nd->bl.prev == NULL) return; //Not on a map.
+ const int m = nd->bl.m;
+ if (m < 0 || nd->bl.prev == NULL) return; //Not on a map.
- x = cap_value(x, 0, map[m].xs-1);
- y = cap_value(y, 0, map[m].ys-1);
+ x = cap_value(x, 0, map[m].xs-1);
+ y = cap_value(y, 0, map[m].ys-1);
- map_foreachinrange(clif_outsight, &nd->bl, AREA_SIZE, BL_PC, &nd->bl);
- map_moveblock(&nd->bl, x, y, gettick());
- map_foreachinrange(clif_insight, &nd->bl, AREA_SIZE, BL_PC, &nd->bl);
+ map_foreachinrange(clif_outsight, &nd->bl, AREA_SIZE, BL_PC, &nd->bl);
+ map_moveblock(&nd->bl, x, y, gettick());
+ map_foreachinrange(clif_insight, &nd->bl, AREA_SIZE, BL_PC, &nd->bl);
}
/// Changes the display name of the npc.
///
/// @param nd Target npc
/// @param newname New display name
-void npc_setdisplayname(struct npc_data *nd, const char *newname)
+void npc_setdisplayname(struct npc_data* nd, const char* newname)
{
- nullpo_retv(nd);
+ nullpo_retv(nd);
- safestrncpy(nd->name, newname, sizeof(nd->name));
- if (map[nd->bl.m].users)
- clif_charnameack(0, &nd->bl);
+ safestrncpy(nd->name, newname, sizeof(nd->name));
+ if( map[nd->bl.m].users )
+ clif_charnameack(0, &nd->bl);
}
/// Changes the display class of the npc.
///
/// @param nd Target npc
/// @param class_ New display class
-void npc_setclass(struct npc_data *nd, short class_)
+void npc_setclass(struct npc_data* nd, short class_)
{
- nullpo_retv(nd);
+ nullpo_retv(nd);
- if (nd->class_ == class_)
- return;
+ if( nd->class_ == class_ )
+ return;
- if (map[nd->bl.m].users)
- clif_clearunit_area(&nd->bl, CLR_OUTSIGHT);// fade out
- nd->class_ = class_;
- status_set_viewdata(&nd->bl, class_);
- if (map[nd->bl.m].users)
- clif_spawn(&nd->bl);// fade in
+ if( map[nd->bl.m].users )
+ clif_clearunit_area(&nd->bl, CLR_OUTSIGHT);// fade out
+ nd->class_ = class_;
+ status_set_viewdata(&nd->bl, class_);
+ if( map[nd->bl.m].users )
+ clif_spawn(&nd->bl);// fade in
}
// @commands (script based)
-int npc_do_atcmd_event(struct map_session_data *sd, const char *command, const char *message, const char *eventname)
-{
- struct event_data *ev = (struct event_data *)strdb_get(ev_db, eventname);
- struct npc_data *nd;
- struct script_state *st;
- int i = 0, j = 0, k = 0;
- char *temp;
-
- nullpo_ret(sd);
-
- if (ev == NULL || (nd = ev->nd) == NULL) {
- ShowError("npc_event: event not found [%s]\n", eventname);
- return 0;
- }
-
- if (sd->npc_id != 0) { // Enqueue the event trigger.
- int i;
- ARR_FIND(0, MAX_EVENTQUEUE, i, sd->eventqueue[i][0] == '\0');
- if (i < MAX_EVENTQUEUE) {
- safestrncpy(sd->eventqueue[i],eventname,50); //Event enqueued.
- return 0;
- }
-
- ShowWarning("npc_event: player's event queue is full, can't add event '%s' !\n", eventname);
- return 1;
- }
-
- if (ev->nd->sc.option&OPTION_INVISIBLE) { // Disabled npc, shouldn't trigger event.
- npc_event_dequeue(sd);
- return 2;
- }
+int npc_do_atcmd_event(struct map_session_data* sd, const char* command, const char* message, const char* eventname)
+{
+ struct event_data* ev = (struct event_data*)strdb_get(ev_db, eventname);
+ struct npc_data *nd;
+ struct script_state *st;
+ int i = 0, j = 0, k = 0;
+ char *temp;
+
+ nullpo_ret(sd);
+
+ if( ev == NULL || (nd = ev->nd) == NULL ) {
+ ShowError("npc_event: event not found [%s]\n", eventname);
+ return 0;
+ }
+
+ if( sd->npc_id != 0 ) { // Enqueue the event trigger.
+ int i;
+ ARR_FIND( 0, MAX_EVENTQUEUE, i, sd->eventqueue[i][0] == '\0' );
+ if( i < MAX_EVENTQUEUE ) {
+ safestrncpy(sd->eventqueue[i],eventname,50); //Event enqueued.
+ return 0;
+ }
+
+ ShowWarning("npc_event: player's event queue is full, can't add event '%s' !\n", eventname);
+ return 1;
+ }
+
+ if( ev->nd->sc.option&OPTION_INVISIBLE ) { // Disabled npc, shouldn't trigger event.
+ npc_event_dequeue(sd);
+ return 2;
+ }
+
+ st = script_alloc_state(ev->nd->u.scr.script, ev->pos, sd->bl.id, ev->nd->bl.id);
+ setd_sub(st, NULL, ".@atcmd_command$", 0, (void *)command, NULL);
+
+ // split atcmd parameters based on spaces
+ i = 0;
+ j = 0;
+
+ temp = (char*)aMalloc(strlen(message) + 1);
+
+ while( message[i] != '\0' ) {
+ if( message[i] == ' ' && k < 127 ) {
+ temp[j] = '\0';
+ setd_sub(st, NULL, ".@atcmd_parameters$", k++, (void *)temp, NULL);
+ j = 0;
+ ++i;
+ } else
+ temp[j++] = message[i++];
+ }
+
+ temp[j] = '\0';
+ setd_sub(st, NULL, ".@atcmd_parameters$", k++, (void *)temp, NULL);
+ setd_sub(st, NULL, ".@atcmd_numparameters", 0, (void *)&k, NULL);
+ aFree(temp);
+
+ run_script_main(st);
+ return 0;
+}
- st = script_alloc_state(ev->nd->u.scr.script, ev->pos, sd->bl.id, ev->nd->bl.id);
- setd_sub(st, NULL, ".@atcmd_command$", 0, (void *)command, NULL);
+/// Parses a function.
+/// function%TAB%script%TAB%<function name>%TAB%{<code>}
+static const char* npc_parse_function(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath)
+{
+ DBMap* func_db;
+ DBData old_data;
+ struct script_code *script;
+ const char* end;
+ const char* script_start;
- // split atcmd parameters based on spaces
- i = 0;
- j = 0;
+ script_start = strstr(start,"\t{");
+ end = strchr(start,'\n');
+ if( *w4 != '{' || script_start == NULL || (end != NULL && script_start > end) )
+ {
+ ShowError("npc_parse_function: Missing left curly '%%TAB%%{' in file '%s', line '%d'. Skipping the rest of the file.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
+ return NULL;// can't continue
+ }
+ ++script_start;
- temp = (char *)aMalloc(strlen(message) + 1);
+ end = npc_skip_script(script_start,buffer,filepath);
+ if( end == NULL )
+ return NULL;// (simple) parse error, don't continue
- while (message[i] != '\0') {
- if (message[i] == ' ' && k < 127) {
- temp[j] = '\0';
- setd_sub(st, NULL, ".@atcmd_parameters$", k++, (void *)temp, NULL);
- j = 0;
- ++i;
- } else
- temp[j++] = message[i++];
- }
+ script = parse_script(script_start, filepath, strline(buffer,start-buffer), SCRIPT_RETURN_EMPTY_SCRIPT);
+ if( script == NULL )// parse error, continue
+ return end;
- temp[j] = '\0';
- setd_sub(st, NULL, ".@atcmd_parameters$", k++, (void *)temp, NULL);
- setd_sub(st, NULL, ".@atcmd_numparameters", 0, (void *)&k, NULL);
- aFree(temp);
+ func_db = script_get_userfunc_db();
+ if (func_db->put(func_db, db_str2key(w3), db_ptr2data(script), &old_data))
+ {
+ struct script_code *oldscript = (struct script_code*)db_data2ptr(&old_data);
+ ShowInfo("npc_parse_function: Overwriting user function [%s] (%s:%d)\n", w3, filepath, strline(buffer,start-buffer));
+ script_free_vars(oldscript->script_vars);
+ aFree(oldscript->script_buf);
+ aFree(oldscript);
+ }
- run_script_main(st);
- return 0;
-}
-
-/// Parses a function.
-/// function%TAB%script%TAB%<function name>%TAB%{<code>}
-static const char *npc_parse_function(char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath)
-{
- DBMap *func_db;
- DBData old_data;
- struct script_code *script;
- const char *end;
- const char *script_start;
-
- script_start = strstr(start,"\t{");
- end = strchr(start,'\n');
- if (*w4 != '{' || script_start == NULL || (end != NULL && script_start > end)) {
- ShowError("npc_parse_function: Missing left curly '%%TAB%%{' in file '%s', line '%d'. Skipping the rest of the file.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
- return NULL;// can't continue
- }
- ++script_start;
-
- end = npc_skip_script(script_start,buffer,filepath);
- if (end == NULL)
- return NULL;// (simple) parse error, don't continue
-
- script = parse_script(script_start, filepath, strline(buffer,start-buffer), SCRIPT_RETURN_EMPTY_SCRIPT);
- if (script == NULL) // parse error, continue
- return end;
-
- func_db = script_get_userfunc_db();
- if (func_db->put(func_db, db_str2key(w3), db_ptr2data(script), &old_data)) {
- struct script_code *oldscript = (struct script_code *)db_data2ptr(&old_data);
- ShowInfo("npc_parse_function: Overwriting user function [%s] (%s:%d)\n", w3, filepath, strline(buffer,start-buffer));
- script_free_vars(oldscript->script_vars);
- aFree(oldscript->script_buf);
- aFree(oldscript);
- }
-
- return end;
+ return end;
}
@@ -2832,806 +2927,867 @@ static const char *npc_parse_function(char *w1, char *w2, char *w3, char *w4, co
* Parse Mob 2 - Actually Spawns Mob
* [Wizputer]
*------------------------------------------*/
-void npc_parse_mob2(struct spawn_data *mob)
-{
- int i;
-
- for (i = mob->active; i < mob->num; ++i) {
- struct mob_data *md = mob_spawn_dataset(mob);
- md->spawn = mob;
- md->spawn->active++;
- mob_spawn(md);
- }
-}
-
-static const char *npc_parse_mob(char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath)
-{
- int num, class_, m,x,y,xs,ys, i,j;
- int mob_lv = -1, ai = -1, size = -1;
- char mapname[32], mobname[NAME_LENGTH];
- struct spawn_data mob, *data;
- struct mob_db *db;
-
- memset(&mob, 0, sizeof(struct spawn_data));
-
- mob.state.boss = !strcmpi(w2,"boss_monster");
-
- // w1=<map name>,<x>,<y>,<xs>,<ys>
- // w3=<mob name>{,<mob level>}
- // w4=<mob id>,<amount>,<delay1>,<delay2>,<event>{,<mob size>,<mob ai>}
- if (sscanf(w1, "%31[^,],%d,%d,%d,%d", mapname, &x, &y, &xs, &ys) < 3
- || sscanf(w3, "%23[^,],%d", mobname, &mob_lv) < 1
- || sscanf(w4, "%d,%d,%u,%u,%127[^,],%d,%d[^\t\r\n]", &class_, &num, &mob.delay1, &mob.delay2, mob.eventname, &size, &ai) < 2) {
- ShowError("npc_parse_mob: Invalid mob definition in file '%s', line '%d'.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
- return strchr(start,'\n');// skip and continue
- }
- if (mapindex_name2id(mapname) == 0) {
- ShowError("npc_parse_mob: Unknown map '%s' in file '%s', line '%d'.\n", mapname, filepath, strline(buffer,start-buffer));
- return strchr(start,'\n');// skip and continue
- }
- m = map_mapname2mapid(mapname);
- if (m < 0) //Not loaded on this map-server instance.
- return strchr(start,'\n');// skip and continue
- mob.m = (unsigned short)m;
-
- if (x < 0 || x >= map[mob.m].xs || y < 0 || y >= map[mob.m].ys) {
- ShowError("npc_parse_mob: Spawn coordinates out of range: %s (%d,%d), map size is (%d,%d) - %s %s (file '%s', line '%d').\n", map[mob.m].name, x, y, (map[mob.m].xs-1), (map[mob.m].ys-1), w1, w3, filepath, strline(buffer,start-buffer));
- return strchr(start,'\n');// skip and continue
- }
-
- // check monster ID if exists!
- if (mobdb_checkid(class_) == 0) {
- ShowError("npc_parse_mob: Unknown mob ID %d (file '%s', line '%d').\n", class_, filepath, strline(buffer,start-buffer));
- return strchr(start,'\n');// skip and continue
- }
-
- if (num < 1 || num > 1000) {
- ShowError("npc_parse_mob: Invalid number of monsters %d, must be inside the range [1,1000] (file '%s', line '%d').\n", num, filepath, strline(buffer,start-buffer));
- return strchr(start,'\n');// skip and continue
- }
-
- if ((mob.state.size < 0 || mob.state.size > 2) && size != -1) {
- ShowError("npc_parse_mob: Invalid size number %d for mob ID %d (file '%s', line '%d').\n", mob.state.size, class_, filepath, strline(buffer, start - buffer));
- return strchr(start, '\n');
- }
-
- if ((mob.state.ai < 0 || mob.state.ai > 4) && ai != -1) {
- ShowError("npc_parse_mob: Invalid ai %d for mob ID %d (file '%s', line '%d').\n", mob.state.ai, class_, filepath, strline(buffer, start - buffer));
- return strchr(start, '\n');
- }
-
- if ((mob_lv == 0 || mob_lv > MAX_LEVEL) && mob_lv != -1) {
- ShowError("npc_parse_mob: Invalid level %d for mob ID %d (file '%s', line '%d').\n", mob_lv, class_, filepath, strline(buffer, start - buffer));
- return strchr(start, '\n');
- }
-
- mob.num = (unsigned short)num;
- mob.active = 0;
- mob.class_ = (short) class_;
- mob.x = (unsigned short)x;
- mob.y = (unsigned short)y;
- mob.xs = (signed short)xs;
- mob.ys = (signed short)ys;
- if (mob_lv > 0 && mob_lv <= MAX_LEVEL)
- mob.level = mob_lv;
- if (size > 0 && size <= 2)
- mob.state.size = size;
- if (ai > 0 && ai <= 4)
- mob.state.ai = ai;
-
- if (mob.num > 1 && battle_config.mob_count_rate != 100) {
- if ((mob.num = mob.num * battle_config.mob_count_rate / 100) < 1)
- mob.num = 1;
- }
-
- if (battle_config.force_random_spawn || (mob.x == 0 && mob.y == 0)) {
- //Force a random spawn anywhere on the map.
- mob.x = mob.y = 0;
- mob.xs = mob.ys = -1;
- }
-
- if (mob.delay1>0xfffffff || mob.delay2>0xfffffff) {
- ShowError("npc_parse_mob: Invalid spawn delays %u %u (file '%s', line '%d').\n", mob.delay1, mob.delay2, filepath, strline(buffer,start-buffer));
- return strchr(start,'\n');// skip and continue
- }
-
- //Use db names instead of the spawn file ones.
- if (battle_config.override_mob_names==1)
- strcpy(mob.name,"--en--");
- else if (battle_config.override_mob_names==2)
- strcpy(mob.name,"--ja--");
- else
- safestrncpy(mob.name, mobname, sizeof(mob.name));
-
- //Verify dataset.
- if (!mob_parse_dataset(&mob)) {
- ShowError("npc_parse_mob: Invalid dataset for monster ID %d (file '%s', line '%d').\n", class_, filepath, strline(buffer,start-buffer));
- return strchr(start,'\n');// skip and continue
- }
-
- //Update mob spawn lookup database
- db = mob_db(class_);
- for (i = 0; i < ARRAYLENGTH(db->spawn); ++i) {
- if (map[mob.m].index == db->spawn[i].mapindex) {
- //Update total
- db->spawn[i].qty += mob.num;
- //Re-sort list
- for (j = i; j > 0 && db->spawn[j-1].qty < db->spawn[i].qty; --j);
- if (j != i) {
- xs = db->spawn[i].mapindex;
- ys = db->spawn[i].qty;
- memmove(&db->spawn[j+1], &db->spawn[j], (i-j)*sizeof(db->spawn[0]));
- db->spawn[j].mapindex = xs;
- db->spawn[j].qty = ys;
- }
- break;
- }
- if (mob.num > db->spawn[i].qty) {
- //Insert into list
- memmove(&db->spawn[i+1], &db->spawn[i], sizeof(db->spawn) -(i+1)*sizeof(db->spawn[0]));
- db->spawn[i].mapindex = map[mob.m].index;
- db->spawn[i].qty = mob.num;
- break;
- }
- }
-
- //Now that all has been validated. We allocate the actual memory that the re-spawn data will use.
- data = (struct spawn_data *)aMalloc(sizeof(struct spawn_data));
- memcpy(data, &mob, sizeof(struct spawn_data));
-
- // spawn / cache the new mobs
- if (battle_config.dynamic_mobs && map_addmobtolist(data->m, data) >= 0) {
- data->state.dynamic = true;
- npc_cache_mob += data->num;
-
- // check if target map has players
- // (usually shouldn't occur when map server is just starting,
- // but not the case when we do @reloadscript
- if (map[data->m].users > 0)
- npc_parse_mob2(data);
- } else {
- data->state.dynamic = false;
- npc_parse_mob2(data);
- npc_delay_mob += data->num;
- }
-
- npc_mob++;
-
- return strchr(start,'\n');// continue
+void npc_parse_mob2(struct spawn_data* mob)
+{
+ int i;
+
+ for( i = mob->active; i < mob->num; ++i )
+ {
+ struct mob_data* md = mob_spawn_dataset(mob);
+ md->spawn = mob;
+ md->spawn->active++;
+ mob_spawn(md);
+ }
+}
+
+static const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath)
+{
+ int num, class_, m,x,y,xs,ys, i,j;
+ int mob_lv = -1, ai = -1, size = -1;
+ char mapname[32], mobname[NAME_LENGTH];
+ struct spawn_data mob, *data;
+ struct mob_db* db;
+
+ memset(&mob, 0, sizeof(struct spawn_data));
+
+ mob.state.boss = !strcmpi(w2,"boss_monster");
+
+ // w1=<map name>,<x>,<y>,<xs>,<ys>
+ // w3=<mob name>{,<mob level>}
+ // w4=<mob id>,<amount>,<delay1>,<delay2>,<event>{,<mob size>,<mob ai>}
+ if( sscanf(w1, "%31[^,],%d,%d,%d,%d", mapname, &x, &y, &xs, &ys) < 3
+ || sscanf(w3, "%23[^,],%d", mobname, &mob_lv) < 1
+ || sscanf(w4, "%d,%d,%u,%u,%127[^,],%d,%d[^\t\r\n]", &class_, &num, &mob.delay1, &mob.delay2, mob.eventname, &size, &ai) < 2 )
+ {
+ ShowError("npc_parse_mob: Invalid mob definition in file '%s', line '%d'.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
+ return strchr(start,'\n');// skip and continue
+ }
+ if( mapindex_name2id(mapname) == 0 )
+ {
+ ShowError("npc_parse_mob: Unknown map '%s' in file '%s', line '%d'.\n", mapname, filepath, strline(buffer,start-buffer));
+ return strchr(start,'\n');// skip and continue
+ }
+ m = map_mapname2mapid(mapname);
+ if( m < 0 )//Not loaded on this map-server instance.
+ return strchr(start,'\n');// skip and continue
+ mob.m = (unsigned short)m;
+
+ if( x < 0 || x >= map[mob.m].xs || y < 0 || y >= map[mob.m].ys )
+ {
+ ShowError("npc_parse_mob: Spawn coordinates out of range: %s (%d,%d), map size is (%d,%d) - %s %s (file '%s', line '%d').\n", map[mob.m].name, x, y, (map[mob.m].xs-1), (map[mob.m].ys-1), w1, w3, filepath, strline(buffer,start-buffer));
+ return strchr(start,'\n');// skip and continue
+ }
+
+ // check monster ID if exists!
+ if( mobdb_checkid(class_) == 0 )
+ {
+ ShowError("npc_parse_mob: Unknown mob ID %d (file '%s', line '%d').\n", class_, filepath, strline(buffer,start-buffer));
+ return strchr(start,'\n');// skip and continue
+ }
+
+ if( num < 1 || num > 1000 )
+ {
+ ShowError("npc_parse_mob: Invalid number of monsters %d, must be inside the range [1,1000] (file '%s', line '%d').\n", num, filepath, strline(buffer,start-buffer));
+ return strchr(start,'\n');// skip and continue
+ }
+
+ if( (mob.state.size < 0 || mob.state.size > 2) && size != -1 )
+ {
+ ShowError("npc_parse_mob: Invalid size number %d for mob ID %d (file '%s', line '%d').\n", mob.state.size, class_, filepath, strline(buffer, start - buffer));
+ return strchr(start, '\n');
+ }
+
+ if( (mob.state.ai < 0 || mob.state.ai > 4) && ai != -1 )
+ {
+ ShowError("npc_parse_mob: Invalid ai %d for mob ID %d (file '%s', line '%d').\n", mob.state.ai, class_, filepath, strline(buffer, start - buffer));
+ return strchr(start, '\n');
+ }
+
+ if( (mob_lv == 0 || mob_lv > MAX_LEVEL) && mob_lv != -1 )
+ {
+ ShowError("npc_parse_mob: Invalid level %d for mob ID %d (file '%s', line '%d').\n", mob_lv, class_, filepath, strline(buffer, start - buffer));
+ return strchr(start, '\n');
+ }
+
+ mob.num = (unsigned short)num;
+ mob.active = 0;
+ mob.class_ = (short) class_;
+ mob.x = (unsigned short)x;
+ mob.y = (unsigned short)y;
+ mob.xs = (signed short)xs;
+ mob.ys = (signed short)ys;
+ if (mob_lv > 0 && mob_lv <= MAX_LEVEL)
+ mob.level = mob_lv;
+ if (size > 0 && size <= 2)
+ mob.state.size = size;
+ if (ai > 0 && ai <= 4)
+ mob.state.ai = ai;
+
+ if (mob.num > 1 && battle_config.mob_count_rate != 100) {
+ if ((mob.num = mob.num * battle_config.mob_count_rate / 100) < 1)
+ mob.num = 1;
+ }
+
+ if (battle_config.force_random_spawn || (mob.x == 0 && mob.y == 0))
+ { //Force a random spawn anywhere on the map.
+ mob.x = mob.y = 0;
+ mob.xs = mob.ys = -1;
+ }
+
+ if(mob.delay1>0xfffffff || mob.delay2>0xfffffff) {
+ ShowError("npc_parse_mob: Invalid spawn delays %u %u (file '%s', line '%d').\n", mob.delay1, mob.delay2, filepath, strline(buffer,start-buffer));
+ return strchr(start,'\n');// skip and continue
+ }
+
+ //Use db names instead of the spawn file ones.
+ if(battle_config.override_mob_names==1)
+ strcpy(mob.name,"--en--");
+ else if (battle_config.override_mob_names==2)
+ strcpy(mob.name,"--ja--");
+ else
+ safestrncpy(mob.name, mobname, sizeof(mob.name));
+
+ //Verify dataset.
+ if( !mob_parse_dataset(&mob) )
+ {
+ ShowError("npc_parse_mob: Invalid dataset for monster ID %d (file '%s', line '%d').\n", class_, filepath, strline(buffer,start-buffer));
+ return strchr(start,'\n');// skip and continue
+ }
+
+ //Update mob spawn lookup database
+ db = mob_db(class_);
+ for( i = 0; i < ARRAYLENGTH(db->spawn); ++i )
+ {
+ if (map[mob.m].index == db->spawn[i].mapindex)
+ { //Update total
+ db->spawn[i].qty += mob.num;
+ //Re-sort list
+ for( j = i; j > 0 && db->spawn[j-1].qty < db->spawn[i].qty; --j );
+ if( j != i )
+ {
+ xs = db->spawn[i].mapindex;
+ ys = db->spawn[i].qty;
+ memmove(&db->spawn[j+1], &db->spawn[j], (i-j)*sizeof(db->spawn[0]));
+ db->spawn[j].mapindex = xs;
+ db->spawn[j].qty = ys;
+ }
+ break;
+ }
+ if (mob.num > db->spawn[i].qty)
+ { //Insert into list
+ memmove(&db->spawn[i+1], &db->spawn[i], sizeof(db->spawn) -(i+1)*sizeof(db->spawn[0]));
+ db->spawn[i].mapindex = map[mob.m].index;
+ db->spawn[i].qty = mob.num;
+ break;
+ }
+ }
+
+ //Now that all has been validated. We allocate the actual memory that the re-spawn data will use.
+ data = (struct spawn_data*)aMalloc(sizeof(struct spawn_data));
+ memcpy(data, &mob, sizeof(struct spawn_data));
+
+ // spawn / cache the new mobs
+ if( battle_config.dynamic_mobs && map_addmobtolist(data->m, data) >= 0 )
+ {
+ data->state.dynamic = true;
+ npc_cache_mob += data->num;
+
+ // check if target map has players
+ // (usually shouldn't occur when map server is just starting,
+ // but not the case when we do @reloadscript
+ if( map[data->m].users > 0 )
+ npc_parse_mob2(data);
+ }
+ else
+ {
+ data->state.dynamic = false;
+ npc_parse_mob2(data);
+ npc_delay_mob += data->num;
+ }
+
+ npc_mob++;
+
+ return strchr(start,'\n');// continue
}
/*==========================================
* Set or disable mapflag on map
- * eg : bat_c01 mapflag battleground 2
+ * eg : bat_c01 mapflag battleground 2
* also chking if mapflag conflict with another
*------------------------------------------*/
-static const char *npc_parse_mapflag(char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath)
-{
- int m;
- char mapname[32];
- int state = 1;
-
- // w1=<mapname>
- if (sscanf(w1, "%31[^,]", mapname) != 1) {
- ShowError("npc_parse_mapflag: Invalid mapflag definition in file '%s', line '%d'.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
- return strchr(start,'\n');// skip and continue
- }
- m = map_mapname2mapid(mapname);
- if (m < 0) {
- ShowWarning("npc_parse_mapflag: Unknown map in file '%s', line '%d' : %s\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", mapname, filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
- return strchr(start,'\n');// skip and continue
- }
-
- if (w4 && !strcmpi(w4, "off"))
- state = 0; //Disable mapflag rather than enable it. [Skotlex]
-
- if (!strcmpi(w3, "nosave")) {
- char savemap[32];
- int savex, savey;
- if (state == 0)
- ; //Map flag disabled.
- else if (!strcmpi(w4, "SavePoint")) {
- map[m].save.map = 0;
- map[m].save.x = -1;
- map[m].save.y = -1;
- } else if (sscanf(w4, "%31[^,],%d,%d", savemap, &savex, &savey) == 3) {
- map[m].save.map = mapindex_name2id(savemap);
- map[m].save.x = savex;
- map[m].save.y = savey;
- if (!map[m].save.map) {
- ShowWarning("npc_parse_mapflag: Specified save point map '%s' for mapflag 'nosave' not found (file '%s', line '%d'), using 'SavePoint'.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", savemap, filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
- map[m].save.x = -1;
- map[m].save.y = -1;
- }
- }
- map[m].flag.nosave = state;
- } else if (!strcmpi(w3,"autotrade"))
- map[m].flag.autotrade=state;
- else if (!strcmpi(w3,"allowks"))
- map[m].flag.allowks=state; // [Kill Steal Protection]
- else if (!strcmpi(w3,"town"))
- map[m].flag.town=state;
- else if (!strcmpi(w3,"nomemo"))
- map[m].flag.nomemo=state;
- else if (!strcmpi(w3,"noteleport"))
- map[m].flag.noteleport=state;
- else if (!strcmpi(w3,"nowarp"))
- map[m].flag.nowarp=state;
- else if (!strcmpi(w3,"nowarpto"))
- map[m].flag.nowarpto=state;
- else if (!strcmpi(w3,"noreturn"))
- map[m].flag.noreturn=state;
- else if (!strcmpi(w3,"monster_noteleport"))
- map[m].flag.monster_noteleport=state;
- else if (!strcmpi(w3,"nobranch"))
- map[m].flag.nobranch=state;
- else if (!strcmpi(w3,"nopenalty")) {
- map[m].flag.noexppenalty=state;
- map[m].flag.nozenypenalty=state;
- } else if (!strcmpi(w3,"pvp")) {
- map[m].flag.pvp = state;
- if (state && (map[m].flag.gvg || map[m].flag.gvg_dungeon || map[m].flag.gvg_castle)) {
- map[m].flag.gvg = 0;
- map[m].flag.gvg_dungeon = 0;
- map[m].flag.gvg_castle = 0;
- ShowWarning("npc_parse_mapflag: You can't set PvP and GvG flags for the same map! Removing GvG flags from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer));
- }
- if (state && map[m].flag.battleground) {
- map[m].flag.battleground = 0;
- ShowWarning("npc_parse_mapflag: You can't set PvP and BattleGround flags for the same map! Removing BattleGround flag from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer));
- }
- } else if (!strcmpi(w3,"pvp_noparty"))
- map[m].flag.pvp_noparty=state;
- else if (!strcmpi(w3,"pvp_noguild"))
- map[m].flag.pvp_noguild=state;
- else if (!strcmpi(w3, "pvp_nightmaredrop")) {
- char drop_arg1[16], drop_arg2[16];
- int drop_id = 0, drop_type = 0, drop_per = 0;
- if (sscanf(w4, "%[^,],%[^,],%d", drop_arg1, drop_arg2, &drop_per) == 3) {
- int i;
- if (!strcmpi(drop_arg1, "random"))
- drop_id = -1;
- else if (itemdb_exists((drop_id = atoi(drop_arg1))) == NULL)
- drop_id = 0;
- if (!strcmpi(drop_arg2, "inventory"))
- drop_type = 1;
- else if (!strcmpi(drop_arg2,"equip"))
- drop_type = 2;
- else if (!strcmpi(drop_arg2,"all"))
- drop_type = 3;
-
- if (drop_id != 0) {
- for (i = 0; i < MAX_DROP_PER_MAP; i++) {
- if (map[m].drop_list[i].drop_id == 0) {
- map[m].drop_list[i].drop_id = drop_id;
- map[m].drop_list[i].drop_type = drop_type;
- map[m].drop_list[i].drop_per = drop_per;
- break;
- }
- }
- map[m].flag.pvp_nightmaredrop = 1;
- }
- } else if (!state) //Disable
- map[m].flag.pvp_nightmaredrop = 0;
- } else if (!strcmpi(w3,"pvp_nocalcrank"))
- map[m].flag.pvp_nocalcrank=state;
- else if (!strcmpi(w3,"gvg")) {
- map[m].flag.gvg = state;
- if (state && map[m].flag.pvp) {
- map[m].flag.pvp = 0;
- ShowWarning("npc_parse_mapflag: You can't set PvP and GvG flags for the same map! Removing PvP flag from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer));
- }
- if (state && map[m].flag.battleground) {
- map[m].flag.battleground = 0;
- ShowWarning("npc_parse_mapflag: You can't set GvG and BattleGround flags for the same map! Removing BattleGround flag from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer));
- }
- } else if (!strcmpi(w3,"gvg_noparty"))
- map[m].flag.gvg_noparty=state;
- else if (!strcmpi(w3,"gvg_dungeon")) {
- map[m].flag.gvg_dungeon=state;
- if (state) map[m].flag.pvp=0;
- } else if (!strcmpi(w3,"gvg_castle")) {
- map[m].flag.gvg_castle=state;
- if (state) map[m].flag.pvp=0;
- } else if (!strcmpi(w3,"battleground")) {
- if (state) {
- if (sscanf(w4, "%d", &state) == 1)
- map[m].flag.battleground = state;
- else
- map[m].flag.battleground = 1; // Default value
- } else
- map[m].flag.battleground = 0;
-
- if (map[m].flag.battleground && map[m].flag.pvp) {
- map[m].flag.pvp = 0;
- ShowWarning("npc_parse_mapflag: You can't set PvP and BattleGround flags for the same map! Removing PvP flag from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer));
- }
- if (map[m].flag.battleground && (map[m].flag.gvg || map[m].flag.gvg_dungeon || map[m].flag.gvg_castle)) {
- map[m].flag.gvg = 0;
- map[m].flag.gvg_dungeon = 0;
- map[m].flag.gvg_castle = 0;
- ShowWarning("npc_parse_mapflag: You can't set GvG and BattleGround flags for the same map! Removing GvG flag from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer));
- }
- } else if (!strcmpi(w3,"noexppenalty"))
- map[m].flag.noexppenalty=state;
- else if (!strcmpi(w3,"nozenypenalty"))
- map[m].flag.nozenypenalty=state;
- else if (!strcmpi(w3,"notrade"))
- map[m].flag.notrade=state;
- else if (!strcmpi(w3,"novending"))
- map[m].flag.novending=state;
- else if (!strcmpi(w3,"nodrop"))
- map[m].flag.nodrop=state;
- else if (!strcmpi(w3,"noskill"))
- map[m].flag.noskill=state;
- else if (!strcmpi(w3,"noicewall"))
- map[m].flag.noicewall=state;
- else if (!strcmpi(w3,"snow"))
- map[m].flag.snow=state;
- else if (!strcmpi(w3,"clouds"))
- map[m].flag.clouds=state;
- else if (!strcmpi(w3,"clouds2"))
- map[m].flag.clouds2=state;
- else if (!strcmpi(w3,"fog"))
- map[m].flag.fog=state;
- else if (!strcmpi(w3,"fireworks"))
- map[m].flag.fireworks=state;
- else if (!strcmpi(w3,"sakura"))
- map[m].flag.sakura=state;
- else if (!strcmpi(w3,"leaves"))
- map[m].flag.leaves=state;
- /**
- * No longer available, keeping here just in case it's back someday. [Ind]
- **/
- //else if (!strcmpi(w3,"rain"))
- // map[m].flag.rain=state;
- else if (!strcmpi(w3,"nightenabled"))
- map[m].flag.nightenabled=state;
- else if (!strcmpi(w3,"nogo"))
- map[m].flag.nogo=state;
- else if (!strcmpi(w3,"noexp")) {
- map[m].flag.nobaseexp=state;
- map[m].flag.nojobexp=state;
- } else if (!strcmpi(w3,"nobaseexp"))
- map[m].flag.nobaseexp=state;
- else if (!strcmpi(w3,"nojobexp"))
- map[m].flag.nojobexp=state;
- else if (!strcmpi(w3,"noloot")) {
- map[m].flag.nomobloot=state;
- map[m].flag.nomvploot=state;
- } else if (!strcmpi(w3,"nomobloot"))
- map[m].flag.nomobloot=state;
- else if (!strcmpi(w3,"nomvploot"))
- map[m].flag.nomvploot=state;
- else if (!strcmpi(w3,"nocommand")) {
- if (state) {
- if (sscanf(w4, "%d", &state) == 1)
- map[m].nocommand =state;
- else //No level specified, block everyone.
- map[m].nocommand =100;
- } else
- map[m].nocommand=0;
- } else if (!strcmpi(w3,"restricted")) {
- if (state) {
- map[m].flag.restricted=1;
- sscanf(w4, "%d", &state);
- map[m].zone |= 1<<(state+1);
- } else {
- map[m].flag.restricted=0;
- map[m].zone = 0;
- }
- } else if (!strcmpi(w3,"jexp")) {
- map[m].jexp = (state) ? atoi(w4) : 100;
- if (map[m].jexp < 0) map[m].jexp = 100;
- map[m].flag.nojobexp = (map[m].jexp==0)?1:0;
- } else if (!strcmpi(w3,"bexp")) {
- map[m].bexp = (state) ? atoi(w4) : 100;
- if (map[m].bexp < 0) map[m].bexp = 100;
- map[m].flag.nobaseexp = (map[m].bexp==0)?1:0;
- } else if (!strcmpi(w3,"loadevent"))
- map[m].flag.loadevent=state;
- else if (!strcmpi(w3,"nochat"))
- map[m].flag.nochat=state;
- else if (!strcmpi(w3,"partylock"))
- map[m].flag.partylock=state;
- else if (!strcmpi(w3,"guildlock"))
- map[m].flag.guildlock=state;
- else if (!strcmpi(w3,"reset"))
- map[m].flag.reset=state;
- else
- ShowError("npc_parse_mapflag: unrecognized mapflag '%s' (file '%s', line '%d').\n", w3, filepath, strline(buffer,start-buffer));
-
- return strchr(start,'\n');// continue
+static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath)
+{
+ int m;
+ char mapname[32];
+ int state = 1;
+
+ // w1=<mapname>
+ if( sscanf(w1, "%31[^,]", mapname) != 1 )
+ {
+ ShowError("npc_parse_mapflag: Invalid mapflag definition in file '%s', line '%d'.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
+ return strchr(start,'\n');// skip and continue
+ }
+ m = map_mapname2mapid(mapname);
+ if( m < 0 )
+ {
+ ShowWarning("npc_parse_mapflag: Unknown map in file '%s', line '%d' : %s\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", mapname, filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
+ return strchr(start,'\n');// skip and continue
+ }
+
+ if (w4 && !strcmpi(w4, "off"))
+ state = 0; //Disable mapflag rather than enable it. [Skotlex]
+
+ if (!strcmpi(w3, "nosave")) {
+ char savemap[32];
+ int savex, savey;
+ if (state == 0)
+ ; //Map flag disabled.
+ else if (!strcmpi(w4, "SavePoint")) {
+ map[m].save.map = 0;
+ map[m].save.x = -1;
+ map[m].save.y = -1;
+ } else if (sscanf(w4, "%31[^,],%d,%d", savemap, &savex, &savey) == 3) {
+ map[m].save.map = mapindex_name2id(savemap);
+ map[m].save.x = savex;
+ map[m].save.y = savey;
+ if (!map[m].save.map) {
+ ShowWarning("npc_parse_mapflag: Specified save point map '%s' for mapflag 'nosave' not found (file '%s', line '%d'), using 'SavePoint'.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", savemap, filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
+ map[m].save.x = -1;
+ map[m].save.y = -1;
+ }
+ }
+ map[m].flag.nosave = state;
+ }
+ else if (!strcmpi(w3,"autotrade"))
+ map[m].flag.autotrade=state;
+ else if (!strcmpi(w3,"allowks"))
+ map[m].flag.allowks=state; // [Kill Steal Protection]
+ else if (!strcmpi(w3,"town"))
+ map[m].flag.town=state;
+ else if (!strcmpi(w3,"nomemo"))
+ map[m].flag.nomemo=state;
+ else if (!strcmpi(w3,"noteleport"))
+ map[m].flag.noteleport=state;
+ else if (!strcmpi(w3,"nowarp"))
+ map[m].flag.nowarp=state;
+ else if (!strcmpi(w3,"nowarpto"))
+ map[m].flag.nowarpto=state;
+ else if (!strcmpi(w3,"noreturn"))
+ map[m].flag.noreturn=state;
+ else if (!strcmpi(w3,"monster_noteleport"))
+ map[m].flag.monster_noteleport=state;
+ else if (!strcmpi(w3,"nobranch"))
+ map[m].flag.nobranch=state;
+ else if (!strcmpi(w3,"nopenalty")) {
+ map[m].flag.noexppenalty=state;
+ map[m].flag.nozenypenalty=state;
+ }
+ else if (!strcmpi(w3,"pvp")) {
+ map[m].flag.pvp = state;
+ if( state && (map[m].flag.gvg || map[m].flag.gvg_dungeon || map[m].flag.gvg_castle) )
+ {
+ map[m].flag.gvg = 0;
+ map[m].flag.gvg_dungeon = 0;
+ map[m].flag.gvg_castle = 0;
+ ShowWarning("npc_parse_mapflag: You can't set PvP and GvG flags for the same map! Removing GvG flags from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer));
+ }
+ if( state && map[m].flag.battleground )
+ {
+ map[m].flag.battleground = 0;
+ ShowWarning("npc_parse_mapflag: You can't set PvP and BattleGround flags for the same map! Removing BattleGround flag from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer));
+ }
+ }
+ else if (!strcmpi(w3,"pvp_noparty"))
+ map[m].flag.pvp_noparty=state;
+ else if (!strcmpi(w3,"pvp_noguild"))
+ map[m].flag.pvp_noguild=state;
+ else if (!strcmpi(w3, "pvp_nightmaredrop")) {
+ char drop_arg1[16], drop_arg2[16];
+ int drop_id = 0, drop_type = 0, drop_per = 0;
+ if (sscanf(w4, "%[^,],%[^,],%d", drop_arg1, drop_arg2, &drop_per) == 3) {
+ int i;
+ if (!strcmpi(drop_arg1, "random"))
+ drop_id = -1;
+ else if (itemdb_exists((drop_id = atoi(drop_arg1))) == NULL)
+ drop_id = 0;
+ if (!strcmpi(drop_arg2, "inventory"))
+ drop_type = 1;
+ else if (!strcmpi(drop_arg2,"equip"))
+ drop_type = 2;
+ else if (!strcmpi(drop_arg2,"all"))
+ drop_type = 3;
+
+ if (drop_id != 0){
+ for (i = 0; i < MAX_DROP_PER_MAP; i++) {
+ if (map[m].drop_list[i].drop_id == 0){
+ map[m].drop_list[i].drop_id = drop_id;
+ map[m].drop_list[i].drop_type = drop_type;
+ map[m].drop_list[i].drop_per = drop_per;
+ break;
+ }
+ }
+ map[m].flag.pvp_nightmaredrop = 1;
+ }
+ } else if (!state) //Disable
+ map[m].flag.pvp_nightmaredrop = 0;
+ }
+ else if (!strcmpi(w3,"pvp_nocalcrank"))
+ map[m].flag.pvp_nocalcrank=state;
+ else if (!strcmpi(w3,"gvg")) {
+ map[m].flag.gvg = state;
+ if( state && map[m].flag.pvp )
+ {
+ map[m].flag.pvp = 0;
+ ShowWarning("npc_parse_mapflag: You can't set PvP and GvG flags for the same map! Removing PvP flag from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer));
+ }
+ if( state && map[m].flag.battleground )
+ {
+ map[m].flag.battleground = 0;
+ ShowWarning("npc_parse_mapflag: You can't set GvG and BattleGround flags for the same map! Removing BattleGround flag from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer));
+ }
+ }
+ else if (!strcmpi(w3,"gvg_noparty"))
+ map[m].flag.gvg_noparty=state;
+ else if (!strcmpi(w3,"gvg_dungeon")) {
+ map[m].flag.gvg_dungeon=state;
+ if (state) map[m].flag.pvp=0;
+ }
+ else if (!strcmpi(w3,"gvg_castle")) {
+ map[m].flag.gvg_castle=state;
+ if (state) map[m].flag.pvp=0;
+ }
+ else if (!strcmpi(w3,"battleground")) {
+ if( state )
+ {
+ if( sscanf(w4, "%d", &state) == 1 )
+ map[m].flag.battleground = state;
+ else
+ map[m].flag.battleground = 1; // Default value
+ }
+ else
+ map[m].flag.battleground = 0;
+
+ if( map[m].flag.battleground && map[m].flag.pvp )
+ {
+ map[m].flag.pvp = 0;
+ ShowWarning("npc_parse_mapflag: You can't set PvP and BattleGround flags for the same map! Removing PvP flag from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer));
+ }
+ if( map[m].flag.battleground && (map[m].flag.gvg || map[m].flag.gvg_dungeon || map[m].flag.gvg_castle) )
+ {
+ map[m].flag.gvg = 0;
+ map[m].flag.gvg_dungeon = 0;
+ map[m].flag.gvg_castle = 0;
+ ShowWarning("npc_parse_mapflag: You can't set GvG and BattleGround flags for the same map! Removing GvG flag from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer));
+ }
+ }
+ else if (!strcmpi(w3,"noexppenalty"))
+ map[m].flag.noexppenalty=state;
+ else if (!strcmpi(w3,"nozenypenalty"))
+ map[m].flag.nozenypenalty=state;
+ else if (!strcmpi(w3,"notrade"))
+ map[m].flag.notrade=state;
+ else if (!strcmpi(w3,"novending"))
+ map[m].flag.novending=state;
+ else if (!strcmpi(w3,"nodrop"))
+ map[m].flag.nodrop=state;
+ else if (!strcmpi(w3,"noskill"))
+ map[m].flag.noskill=state;
+ else if (!strcmpi(w3,"noicewall"))
+ map[m].flag.noicewall=state;
+ else if (!strcmpi(w3,"snow"))
+ map[m].flag.snow=state;
+ else if (!strcmpi(w3,"clouds"))
+ map[m].flag.clouds=state;
+ else if (!strcmpi(w3,"clouds2"))
+ map[m].flag.clouds2=state;
+ else if (!strcmpi(w3,"fog"))
+ map[m].flag.fog=state;
+ else if (!strcmpi(w3,"fireworks"))
+ map[m].flag.fireworks=state;
+ else if (!strcmpi(w3,"sakura"))
+ map[m].flag.sakura=state;
+ else if (!strcmpi(w3,"leaves"))
+ map[m].flag.leaves=state;
+ /**
+ * No longer available, keeping here just in case it's back someday. [Ind]
+ **/
+ //else if (!strcmpi(w3,"rain"))
+ // map[m].flag.rain=state;
+ else if (!strcmpi(w3,"nightenabled"))
+ map[m].flag.nightenabled=state;
+ else if (!strcmpi(w3,"nogo"))
+ map[m].flag.nogo=state;
+ else if (!strcmpi(w3,"noexp")) {
+ map[m].flag.nobaseexp=state;
+ map[m].flag.nojobexp=state;
+ }
+ else if (!strcmpi(w3,"nobaseexp"))
+ map[m].flag.nobaseexp=state;
+ else if (!strcmpi(w3,"nojobexp"))
+ map[m].flag.nojobexp=state;
+ else if (!strcmpi(w3,"noloot")) {
+ map[m].flag.nomobloot=state;
+ map[m].flag.nomvploot=state;
+ }
+ else if (!strcmpi(w3,"nomobloot"))
+ map[m].flag.nomobloot=state;
+ else if (!strcmpi(w3,"nomvploot"))
+ map[m].flag.nomvploot=state;
+ else if (!strcmpi(w3,"nocommand")) {
+ if (state) {
+ if (sscanf(w4, "%d", &state) == 1)
+ map[m].nocommand =state;
+ else //No level specified, block everyone.
+ map[m].nocommand =100;
+ } else
+ map[m].nocommand=0;
+ }
+ else if (!strcmpi(w3,"restricted")) {
+ if (state) {
+ map[m].flag.restricted=1;
+ sscanf(w4, "%d", &state);
+ map[m].zone |= 1<<(state+1);
+ } else {
+ map[m].flag.restricted=0;
+ map[m].zone = 0;
+ }
+ }
+ else if (!strcmpi(w3,"jexp")) {
+ map[m].jexp = (state) ? atoi(w4) : 100;
+ if( map[m].jexp < 0 ) map[m].jexp = 100;
+ map[m].flag.nojobexp = (map[m].jexp==0)?1:0;
+ }
+ else if (!strcmpi(w3,"bexp")) {
+ map[m].bexp = (state) ? atoi(w4) : 100;
+ if( map[m].bexp < 0 ) map[m].bexp = 100;
+ map[m].flag.nobaseexp = (map[m].bexp==0)?1:0;
+ }
+ else if (!strcmpi(w3,"loadevent"))
+ map[m].flag.loadevent=state;
+ else if (!strcmpi(w3,"nochat"))
+ map[m].flag.nochat=state;
+ else if (!strcmpi(w3,"partylock"))
+ map[m].flag.partylock=state;
+ else if (!strcmpi(w3,"guildlock"))
+ map[m].flag.guildlock=state;
+ else if (!strcmpi(w3,"reset"))
+ map[m].flag.reset=state;
+ else
+ ShowError("npc_parse_mapflag: unrecognized mapflag '%s' (file '%s', line '%d').\n", w3, filepath, strline(buffer,start-buffer));
+
+ return strchr(start,'\n');// continue
}
//Read file and create npc/func/mapflag/monster... accordingly.
//@runOnInit should we exec OnInit when it's done ?
-void npc_parsesrcfile(const char *filepath, bool runOnInit)
-{
- int m, lines = 0;
- FILE *fp;
- size_t len;
- char *buffer;
- const char *p;
-
- // read whole file to buffer
- fp = fopen(filepath, "rb");
- if (fp == NULL) {
- ShowError("npc_parsesrcfile: File not found '%s'.\n", filepath);
- return;
- }
- fseek(fp, 0, SEEK_END);
- len = ftell(fp);
- buffer = (char *)aMalloc(len+1);
- fseek(fp, 0, SEEK_SET);
- len = fread(buffer, sizeof(char), len, fp);
- buffer[len] = '\0';
- if (ferror(fp)) {
- ShowError("npc_parsesrcfile: Failed to read file '%s' - %s\n", filepath, strerror(errno));
- aFree(buffer);
- fclose(fp);
- return;
- }
- fclose(fp);
-
- // parse buffer
- for (p = skip_space(buffer); p && *p ; p = skip_space(p)) {
- int pos[9];
- char w1[2048], w2[2048], w3[2048], w4[2048];
- int i, count;
- lines++;
-
- // w1<TAB>w2<TAB>w3<TAB>w4
- count = sv_parse(p, len+buffer-p, 0, '\t', pos, ARRAYLENGTH(pos), (e_svopt)(SV_TERMINATE_LF|SV_TERMINATE_CRLF));
- if (count < 0) {
- ShowError("npc_parsesrcfile: Parse error in file '%s', line '%d'. Stopping...\n", filepath, strline(buffer,p-buffer));
- break;
- }
- // fill w1
- if (pos[3]-pos[2] > ARRAYLENGTH(w1)-1)
- ShowWarning("npc_parsesrcfile: w1 truncated, too much data (%d) in file '%s', line '%d'.\n", pos[3]-pos[2], filepath, strline(buffer,p-buffer));
- i = min(pos[3]-pos[2], ARRAYLENGTH(w1)-1);
- memcpy(w1, p+pos[2], i*sizeof(char));
- w1[i] = '\0';
- // fill w2
- if (pos[5]-pos[4] > ARRAYLENGTH(w2)-1)
- ShowWarning("npc_parsesrcfile: w2 truncated, too much data (%d) in file '%s', line '%d'.\n", pos[5]-pos[4], filepath, strline(buffer,p-buffer));
- i = min(pos[5]-pos[4], ARRAYLENGTH(w2)-1);
- memcpy(w2, p+pos[4], i*sizeof(char));
- w2[i] = '\0';
- // fill w3
- if (pos[7]-pos[6] > ARRAYLENGTH(w3)-1)
- ShowWarning("npc_parsesrcfile: w3 truncated, too much data (%d) in file '%s', line '%d'.\n", pos[7]-pos[6], filepath, strline(buffer,p-buffer));
- i = min(pos[7]-pos[6], ARRAYLENGTH(w3)-1);
- memcpy(w3, p+pos[6], i*sizeof(char));
- w3[i] = '\0';
- // fill w4 (to end of line)
- if (pos[1]-pos[8] > ARRAYLENGTH(w4)-1)
- ShowWarning("npc_parsesrcfile: w4 truncated, too much data (%d) in file '%s', line '%d'.\n", pos[1]-pos[8], filepath, strline(buffer,p-buffer));
- if (pos[8] != -1) {
- i = min(pos[1]-pos[8], ARRAYLENGTH(w4)-1);
- memcpy(w4, p+pos[8], i*sizeof(char));
- w4[i] = '\0';
- } else
- w4[0] = '\0';
-
- if (count < 3) {
- // Unknown syntax
- ShowError("npc_parsesrcfile: Unknown syntax in file '%s', line '%d'. Stopping...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,p-buffer), w1, w2, w3, w4);
- break;
- }
-
- if (strcmp(w1,"-") !=0 && strcasecmp(w1,"function") != 0) {
- // w1 = <map name>,<x>,<y>,<facing>
- char mapname[2048];
- sscanf(w1,"%[^,]",mapname);
- if (!mapindex_name2id(mapname)) {
- // Incorrect map, we must skip the script info...
- ShowError("npc_parsesrcfile: Unknown map '%s' in file '%s', line '%d'. Skipping line...\n", mapname, filepath, strline(buffer,p-buffer));
- if (strcasecmp(w2,"script") == 0 && count > 3) {
- if ((p = npc_skip_script(p,buffer,filepath)) == NULL) {
- break;
- }
- }
- p = strchr(p,'\n');// next line
- continue;
- }
- m = map_mapname2mapid(mapname);
- if (m < 0) {
- // "mapname" is not assigned to this server, we must skip the script info...
- if (strcasecmp(w2,"script") == 0 && count > 3) {
- if ((p = npc_skip_script(p,buffer,filepath)) == NULL) {
- break;
- }
- }
- p = strchr(p,'\n');// next line
- continue;
- }
- }
-
- if (strcasecmp(w2,"warp") == 0 && count > 3) {
- p = npc_parse_warp(w1,w2,w3,w4, p, buffer, filepath);
- } else if ((!strcasecmp(w2,"shop") || !strcasecmp(w2,"cashshop")) && count > 3) {
- p = npc_parse_shop(w1,w2,w3,w4, p, buffer, filepath);
- } else if (strcasecmp(w2,"script") == 0 && count > 3) {
- if (strcasecmp(w1,"function") == 0)
- p = npc_parse_function(w1, w2, w3, w4, p, buffer, filepath);
- else
- p = npc_parse_script(w1,w2,w3,w4, p, buffer, filepath,runOnInit);
- } else if ((i=0, sscanf(w2,"duplicate%n",&i), (i > 0 && w2[i] == '(')) && count > 3) {
- p = npc_parse_duplicate(w1,w2,w3,w4, p, buffer, filepath);
- } else if ((strcmpi(w2,"monster") == 0 || strcmpi(w2,"boss_monster") == 0) && count > 3) {
- p = npc_parse_mob(w1, w2, w3, w4, p, buffer, filepath);
- } else if (strcmpi(w2,"mapflag") == 0 && count >= 3) {
- p = npc_parse_mapflag(w1, w2, trim(w3), trim(w4), p, buffer, filepath);
- } else {
- ShowError("npc_parsesrcfile: Unable to parse, probably a missing or extra TAB in file '%s', line '%d'. Skipping line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,p-buffer), w1, w2, w3, w4);
- p = strchr(p,'\n');// skip and continue
- }
- }
- aFree(buffer);
-
- return;
-}
-
-int npc_script_event(struct map_session_data *sd, enum npce_event type)
-{
- int i;
- if (type == NPCE_MAX)
- return 0;
- if (!sd) {
- ShowError("npc_script_event: NULL sd. Event Type %d\n", type);
- return 0;
- }
- for (i = 0; i<script_event[type].event_count; i++)
- npc_event_sub(sd,script_event[type].event[i],script_event[type].event_name[i]);
- return i;
+void npc_parsesrcfile(const char* filepath, bool runOnInit)
+{
+ int m, lines = 0;
+ FILE* fp;
+ size_t len;
+ char* buffer;
+ const char* p;
+
+ // read whole file to buffer
+ fp = fopen(filepath, "rb");
+ if( fp == NULL )
+ {
+ ShowError("npc_parsesrcfile: File not found '%s'.\n", filepath);
+ return;
+ }
+ fseek(fp, 0, SEEK_END);
+ len = ftell(fp);
+ buffer = (char*)aMalloc(len+1);
+ fseek(fp, 0, SEEK_SET);
+ len = fread(buffer, sizeof(char), len, fp);
+ buffer[len] = '\0';
+ if( ferror(fp) )
+ {
+ ShowError("npc_parsesrcfile: Failed to read file '%s' - %s\n", filepath, strerror(errno));
+ aFree(buffer);
+ fclose(fp);
+ return;
+ }
+ fclose(fp);
+
+ // parse buffer
+ for( p = skip_space(buffer); p && *p ; p = skip_space(p) )
+ {
+ int pos[9];
+ char w1[2048], w2[2048], w3[2048], w4[2048];
+ int i, count;
+ lines++;
+
+ // w1<TAB>w2<TAB>w3<TAB>w4
+ count = sv_parse(p, len+buffer-p, 0, '\t', pos, ARRAYLENGTH(pos), (e_svopt)(SV_TERMINATE_LF|SV_TERMINATE_CRLF));
+ if( count < 0 )
+ {
+ ShowError("npc_parsesrcfile: Parse error in file '%s', line '%d'. Stopping...\n", filepath, strline(buffer,p-buffer));
+ break;
+ }
+ // fill w1
+ if( pos[3]-pos[2] > ARRAYLENGTH(w1)-1 )
+ ShowWarning("npc_parsesrcfile: w1 truncated, too much data (%d) in file '%s', line '%d'.\n", pos[3]-pos[2], filepath, strline(buffer,p-buffer));
+ i = min(pos[3]-pos[2], ARRAYLENGTH(w1)-1);
+ memcpy(w1, p+pos[2], i*sizeof(char));
+ w1[i] = '\0';
+ // fill w2
+ if( pos[5]-pos[4] > ARRAYLENGTH(w2)-1 )
+ ShowWarning("npc_parsesrcfile: w2 truncated, too much data (%d) in file '%s', line '%d'.\n", pos[5]-pos[4], filepath, strline(buffer,p-buffer));
+ i = min(pos[5]-pos[4], ARRAYLENGTH(w2)-1);
+ memcpy(w2, p+pos[4], i*sizeof(char));
+ w2[i] = '\0';
+ // fill w3
+ if( pos[7]-pos[6] > ARRAYLENGTH(w3)-1 )
+ ShowWarning("npc_parsesrcfile: w3 truncated, too much data (%d) in file '%s', line '%d'.\n", pos[7]-pos[6], filepath, strline(buffer,p-buffer));
+ i = min(pos[7]-pos[6], ARRAYLENGTH(w3)-1);
+ memcpy(w3, p+pos[6], i*sizeof(char));
+ w3[i] = '\0';
+ // fill w4 (to end of line)
+ if( pos[1]-pos[8] > ARRAYLENGTH(w4)-1 )
+ ShowWarning("npc_parsesrcfile: w4 truncated, too much data (%d) in file '%s', line '%d'.\n", pos[1]-pos[8], filepath, strline(buffer,p-buffer));
+ if( pos[8] != -1 )
+ {
+ i = min(pos[1]-pos[8], ARRAYLENGTH(w4)-1);
+ memcpy(w4, p+pos[8], i*sizeof(char));
+ w4[i] = '\0';
+ }
+ else
+ w4[0] = '\0';
+
+ if( count < 3 )
+ {// Unknown syntax
+ ShowError("npc_parsesrcfile: Unknown syntax in file '%s', line '%d'. Stopping...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,p-buffer), w1, w2, w3, w4);
+ break;
+ }
+
+ if( strcmp(w1,"-") !=0 && strcasecmp(w1,"function") != 0 )
+ {// w1 = <map name>,<x>,<y>,<facing>
+ char mapname[2048];
+ sscanf(w1,"%[^,]",mapname);
+ if( !mapindex_name2id(mapname) )
+ {// Incorrect map, we must skip the script info...
+ ShowError("npc_parsesrcfile: Unknown map '%s' in file '%s', line '%d'. Skipping line...\n", mapname, filepath, strline(buffer,p-buffer));
+ if( strcasecmp(w2,"script") == 0 && count > 3 )
+ {
+ if((p = npc_skip_script(p,buffer,filepath)) == NULL)
+ {
+ break;
+ }
+ }
+ p = strchr(p,'\n');// next line
+ continue;
+ }
+ m = map_mapname2mapid(mapname);
+ if( m < 0 )
+ {// "mapname" is not assigned to this server, we must skip the script info...
+ if( strcasecmp(w2,"script") == 0 && count > 3 )
+ {
+ if((p = npc_skip_script(p,buffer,filepath)) == NULL)
+ {
+ break;
+ }
+ }
+ p = strchr(p,'\n');// next line
+ continue;
+ }
+ }
+
+ if( strcasecmp(w2,"warp") == 0 && count > 3 )
+ {
+ p = npc_parse_warp(w1,w2,w3,w4, p, buffer, filepath);
+ }
+ else if( (!strcasecmp(w2,"shop") || !strcasecmp(w2,"cashshop")) && count > 3 )
+ {
+ p = npc_parse_shop(w1,w2,w3,w4, p, buffer, filepath);
+ }
+ else if( strcasecmp(w2,"script") == 0 && count > 3 )
+ {
+ if( strcasecmp(w1,"function") == 0 )
+ p = npc_parse_function(w1, w2, w3, w4, p, buffer, filepath);
+ else
+ p = npc_parse_script(w1,w2,w3,w4, p, buffer, filepath,runOnInit);
+ }
+ else if( (i=0, sscanf(w2,"duplicate%n",&i), (i > 0 && w2[i] == '(')) && count > 3 )
+ {
+ p = npc_parse_duplicate(w1,w2,w3,w4, p, buffer, filepath);
+ }
+ else if( (strcmpi(w2,"monster") == 0 || strcmpi(w2,"boss_monster") == 0) && count > 3 )
+ {
+ p = npc_parse_mob(w1, w2, w3, w4, p, buffer, filepath);
+ }
+ else if( strcmpi(w2,"mapflag") == 0 && count >= 3 )
+ {
+ p = npc_parse_mapflag(w1, w2, trim(w3), trim(w4), p, buffer, filepath);
+ }
+ else
+ {
+ ShowError("npc_parsesrcfile: Unable to parse, probably a missing or extra TAB in file '%s', line '%d'. Skipping line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,p-buffer), w1, w2, w3, w4);
+ p = strchr(p,'\n');// skip and continue
+ }
+ }
+ aFree(buffer);
+
+ return;
+}
+
+int npc_script_event(struct map_session_data* sd, enum npce_event type)
+{
+ int i;
+ if (type == NPCE_MAX)
+ return 0;
+ if (!sd) {
+ ShowError("npc_script_event: NULL sd. Event Type %d\n", type);
+ return 0;
+ }
+ for (i = 0; i<script_event[type].event_count; i++)
+ npc_event_sub(sd,script_event[type].event[i],script_event[type].event_name[i]);
+ return i;
}
void npc_read_event_script(void)
{
- int i;
- struct {
- char *name;
- const char *event_name;
- } config[] = {
- {"Login Event",script_config.login_event_name},
- {"Logout Event",script_config.logout_event_name},
- {"Load Map Event",script_config.loadmap_event_name},
- {"Base LV Up Event",script_config.baselvup_event_name},
- {"Job LV Up Event",script_config.joblvup_event_name},
- {"Die Event",script_config.die_event_name},
- {"Kill PC Event",script_config.kill_pc_event_name},
- {"Kill NPC Event",script_config.kill_mob_event_name},
- };
-
- for (i = 0; i < NPCE_MAX; i++) {
- DBIterator *iter;
- DBKey key;
- DBData *data;
-
- char name[64]="::";
- strncpy(name+2,config[i].event_name,62);
-
- script_event[i].event_count = 0;
- iter = db_iterator(ev_db);
- for (data = iter->first(iter,&key); iter->exists(iter); data = iter->next(iter,&key)) {
- const char *p = key.str;
- struct event_data *ed = db_data2ptr(data);
- unsigned char count = script_event[i].event_count;
-
- if (count >= ARRAYLENGTH(script_event[i].event)) {
- ShowWarning("npc_read_event_script: too many occurences of event '%s'!\n", config[i].event_name);
- break;
- }
-
- if ((p=strchr(p,':')) && p && strcmpi(name,p)==0) {
- script_event[i].event[count] = ed;
- script_event[i].event_name[count] = key.str;
- script_event[i].event_count++;
- }
- }
- dbi_destroy(iter);
- }
-
- if (battle_config.etc_log) {
- //Print summary.
- for (i = 0; i < NPCE_MAX; i++)
- ShowInfo("%s: %d '%s' events.\n", config[i].name, script_event[i].event_count, config[i].event_name);
- }
-}
-
-void npc_clear_pathlist(void)
-{
- struct npc_path_data *npd = NULL;
- DBIterator *path_list = db_iterator(npc_path_db);
-
- /* free all npc_path_data filepaths */
- for (npd = dbi_first(path_list); dbi_exists(path_list); npd = dbi_next(path_list)) {
- if (npd->path)
- aFree(npd->path);
- }
-
- dbi_destroy(path_list);
+ int i;
+ struct {
+ char *name;
+ const char *event_name;
+ } config[] = {
+ {"Login Event",script_config.login_event_name},
+ {"Logout Event",script_config.logout_event_name},
+ {"Load Map Event",script_config.loadmap_event_name},
+ {"Base LV Up Event",script_config.baselvup_event_name},
+ {"Job LV Up Event",script_config.joblvup_event_name},
+ {"Die Event",script_config.die_event_name},
+ {"Kill PC Event",script_config.kill_pc_event_name},
+ {"Kill NPC Event",script_config.kill_mob_event_name},
+ };
+
+ for (i = 0; i < NPCE_MAX; i++)
+ {
+ DBIterator* iter;
+ DBKey key;
+ DBData *data;
+
+ char name[64]="::";
+ strncpy(name+2,config[i].event_name,62);
+
+ script_event[i].event_count = 0;
+ iter = db_iterator(ev_db);
+ for( data = iter->first(iter,&key); iter->exists(iter); data = iter->next(iter,&key) )
+ {
+ const char* p = key.str;
+ struct event_data* ed = db_data2ptr(data);
+ unsigned char count = script_event[i].event_count;
+
+ if( count >= ARRAYLENGTH(script_event[i].event) )
+ {
+ ShowWarning("npc_read_event_script: too many occurences of event '%s'!\n", config[i].event_name);
+ break;
+ }
+
+ if( (p=strchr(p,':')) && p && strcmpi(name,p)==0 )
+ {
+ script_event[i].event[count] = ed;
+ script_event[i].event_name[count] = key.str;
+ script_event[i].event_count++;
+ }
+ }
+ dbi_destroy(iter);
+ }
+
+ if (battle_config.etc_log) {
+ //Print summary.
+ for (i = 0; i < NPCE_MAX; i++)
+ ShowInfo("%s: %d '%s' events.\n", config[i].name, script_event[i].event_count, config[i].event_name);
+ }
+}
+
+void npc_clear_pathlist(void) {
+ struct npc_path_data *npd = NULL;
+ DBIterator *path_list = db_iterator(npc_path_db);
+
+ /* free all npc_path_data filepaths */
+ for( npd = dbi_first(path_list); dbi_exists(path_list); npd = dbi_next(path_list) ) {
+ if( npd->path )
+ aFree(npd->path);
+ }
+
+ dbi_destroy(path_list);
}
//Clear then reload npcs files
-int npc_reload(void)
-{
- struct npc_src_list *nsl;
- int m, i;
- int npc_new_min = npc_id;
- struct s_mapiterator *iter;
- struct block_list *bl;
-
- /* clear guild flag cache */
- guild_flags_clear();
-
- npc_clear_pathlist();
-
- db_clear(npc_path_db);
-
- db_clear(npcname_db);
- db_clear(ev_db);
-
- //Remove all npcs/mobs. [Skotlex]
-
- iter = mapit_geteachiddb();
- for (bl = (struct block_list *)mapit_first(iter); mapit_exists(iter); bl = (struct block_list *)mapit_next(iter)) {
- switch (bl->type) {
- case BL_NPC:
- if (bl->id != fake_nd->bl.id) // don't remove fake_nd
- npc_unload((struct npc_data *)bl, false);
- break;
- case BL_MOB:
- unit_free(bl,CLR_OUTSIGHT);
- break;
- }
- }
- mapit_free(iter);
-
- if (battle_config.dynamic_mobs) {
- // dynamic check by [random]
- for (m = 0; m < map_num; m++) {
- for (i = 0; i < MAX_MOB_LIST_PER_MAP; i++) {
- if (map[m].moblist[i] != NULL) {
- aFree(map[m].moblist[i]);
- map[m].moblist[i] = NULL;
- }
- if (map[m].mob_delete_timer != INVALID_TIMER) {
- // Mobs were removed anyway,so delete the timer [Inkfish]
- delete_timer(map[m].mob_delete_timer, map_removemobs_timer);
- map[m].mob_delete_timer = INVALID_TIMER;
- }
- }
- }
- if (map[m].npc_num > 0)
- ShowWarning("npc_reload: %d npcs weren't removed at map %s!\n", map[m].npc_num, map[m].name);
- }
-
- // clear mob spawn lookup index
- mob_clear_spawninfo();
-
- npc_warp = npc_shop = npc_script = 0;
- npc_mob = npc_cache_mob = npc_delay_mob = 0;
-
- // reset mapflags
- map_flags_init();
-
- //TODO: the following code is copy-pasted from do_init_npc(); clean it up
- // Reloading npcs now
- for (nsl = npc_src_files; nsl; nsl = nsl->next) {
- ShowStatus("Loading NPC file: %s"CL_CLL"\r", nsl->name);
- npc_parsesrcfile(nsl->name,false);
- }
- ShowInfo("Done loading '"CL_WHITE"%d"CL_RESET"' NPCs:"CL_CLL"\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"' Spawn sets\n"
- "\t-'"CL_WHITE"%d"CL_RESET"' Mobs Cached\n"
- "\t-'"CL_WHITE"%d"CL_RESET"' Mobs Not Cached\n",
- npc_id - npc_new_min, npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob);
-
- do_final_instance();
-
- for (i = 0; i < ARRAYLENGTH(instance); ++i)
- instance_init(instance[i].instance_id);
-
- //Re-read the NPC Script Events cache.
- npc_read_event_script();
-
- /* refresh guild castle flags on both woe setups */
- npc_event_doall("OnAgitInit");
- npc_event_doall("OnAgitInit2");
-
- //Execute the OnInit event for freshly loaded npcs. [Skotlex]
- ShowStatus("Event '"CL_WHITE"OnInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n",npc_event_doall("OnInit"));
-
- // Execute rest of the startup events if connected to char-server. [Lance]
- if (!CheckForCharServer()) {
- ShowStatus("Event '"CL_WHITE"OnInterIfInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc_event_doall("OnInterIfInit"));
- ShowStatus("Event '"CL_WHITE"OnInterIfInitOnce"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc_event_doall("OnInterIfInitOnce"));
- }
- return 0;
+int npc_reload(void) {
+ struct npc_src_list *nsl;
+ int m, i;
+ int npc_new_min = npc_id;
+ struct s_mapiterator* iter;
+ struct block_list* bl;
+
+ /* clear guild flag cache */
+ guild_flags_clear();
+
+ npc_clear_pathlist();
+
+ db_clear(npc_path_db);
+
+ db_clear(npcname_db);
+ db_clear(ev_db);
+
+ //Remove all npcs/mobs. [Skotlex]
+
+ iter = mapit_geteachiddb();
+ for( bl = (struct block_list*)mapit_first(iter); mapit_exists(iter); bl = (struct block_list*)mapit_next(iter) ) {
+ switch(bl->type) {
+ case BL_NPC:
+ if( bl->id != fake_nd->bl.id )// don't remove fake_nd
+ npc_unload((struct npc_data *)bl, false);
+ break;
+ case BL_MOB:
+ unit_free(bl,CLR_OUTSIGHT);
+ break;
+ }
+ }
+ mapit_free(iter);
+
+ if(battle_config.dynamic_mobs)
+ {// dynamic check by [random]
+ for (m = 0; m < map_num; m++) {
+ for (i = 0; i < MAX_MOB_LIST_PER_MAP; i++) {
+ if (map[m].moblist[i] != NULL) {
+ aFree(map[m].moblist[i]);
+ map[m].moblist[i] = NULL;
+ }
+ if( map[m].mob_delete_timer != INVALID_TIMER )
+ { // Mobs were removed anyway,so delete the timer [Inkfish]
+ delete_timer(map[m].mob_delete_timer, map_removemobs_timer);
+ map[m].mob_delete_timer = INVALID_TIMER;
+ }
+ }
+ }
+ if (map[m].npc_num > 0)
+ ShowWarning("npc_reload: %d npcs weren't removed at map %s!\n", map[m].npc_num, map[m].name);
+ }
+
+ // clear mob spawn lookup index
+ mob_clear_spawninfo();
+
+ npc_warp = npc_shop = npc_script = 0;
+ npc_mob = npc_cache_mob = npc_delay_mob = 0;
+
+ // reset mapflags
+ map_flags_init();
+
+ //TODO: the following code is copy-pasted from do_init_npc(); clean it up
+ // Reloading npcs now
+ for (nsl = npc_src_files; nsl; nsl = nsl->next) {
+ ShowStatus("Loading NPC file: %s"CL_CLL"\r", nsl->name);
+ npc_parsesrcfile(nsl->name,false);
+ }
+ ShowInfo ("Done loading '"CL_WHITE"%d"CL_RESET"' NPCs:"CL_CLL"\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"' Spawn sets\n"
+ "\t-'"CL_WHITE"%d"CL_RESET"' Mobs Cached\n"
+ "\t-'"CL_WHITE"%d"CL_RESET"' Mobs Not Cached\n",
+ npc_id - npc_new_min, npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob);
+
+ do_final_instance();
+
+ for( i = 0; i < ARRAYLENGTH(instance); ++i )
+ instance_init(instance[i].instance_id);
+
+ //Re-read the NPC Script Events cache.
+ npc_read_event_script();
+
+ /* refresh guild castle flags on both woe setups */
+ npc_event_doall("OnAgitInit");
+ npc_event_doall("OnAgitInit2");
+
+ //Execute the OnInit event for freshly loaded npcs. [Skotlex]
+ ShowStatus("Event '"CL_WHITE"OnInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n",npc_event_doall("OnInit"));
+
+ // Execute rest of the startup events if connected to char-server. [Lance]
+ if(!CheckForCharServer()){
+ ShowStatus("Event '"CL_WHITE"OnInterIfInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc_event_doall("OnInterIfInit"));
+ ShowStatus("Event '"CL_WHITE"OnInterIfInitOnce"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc_event_doall("OnInterIfInitOnce"));
+ }
+ return 0;
}
//Unload all npc in the given file
-bool npc_unloadfile(const char *path)
-{
- DBIterator *iter = db_iterator(npcname_db);
- struct npc_data *nd = NULL;
- bool found = false;
+bool npc_unloadfile( const char* path ) {
+ DBIterator * iter = db_iterator(npcname_db);
+ struct npc_data* nd = NULL;
+ bool found = false;
- for (nd = dbi_first(iter); dbi_exists(iter); nd = dbi_next(iter)) {
- if (nd->path && strcasecmp(nd->path,path) == 0) {
- found = true;
- npc_unload_duplicates(nd);/* unload any npcs which could duplicate this but be in a different file */
- npc_unload(nd, true);
- }
- }
+ for( nd = dbi_first(iter); dbi_exists(iter); nd = dbi_next(iter) ) {
+ if( nd->path && strcasecmp(nd->path,path) == 0 ) {
+ found = true;
+ npc_unload_duplicates(nd);/* unload any npcs which could duplicate this but be in a different file */
+ npc_unload(nd, true);
+ }
+ }
- dbi_destroy(iter);
+ dbi_destroy(iter);
- if (found) /* refresh event cache */
- npc_read_event_script();
+ if( found ) /* refresh event cache */
+ npc_read_event_script();
- return found;
+ return found;
}
-void do_clear_npc(void)
-{
- db_clear(npcname_db);
- db_clear(ev_db);
+void do_clear_npc(void) {
+ db_clear(npcname_db);
+ db_clear(ev_db);
}
/*==========================================
* Destructor
*------------------------------------------*/
-int do_final_npc(void)
-{
- npc_clear_pathlist();
- ev_db->destroy(ev_db, NULL);
- npcname_db->destroy(npcname_db, NULL);
- npc_path_db->destroy(npc_path_db, NULL);
- ers_destroy(timer_event_ers);
- npc_clearsrcfile();
-
- return 0;
-}
-
-static void npc_debug_warps_sub(struct npc_data *nd)
-{
- int m;
- if (nd->bl.type != BL_NPC || nd->subtype != WARP || nd->bl.m < 0)
- return;
-
- m = map_mapindex2mapid(nd->u.warp.mapindex);
- if (m < 0) return; //Warps to another map, nothing to do about it.
- if (nd->u.warp.x == 0 && nd->u.warp.y == 0) return; // random warp
-
- if (map_getcell(m, nd->u.warp.x, nd->u.warp.y, CELL_CHKNPC)) {
- ShowWarning("Warp %s at %s(%d,%d) warps directly on top of an area npc at %s(%d,%d)\n",
- nd->name,
- map[nd->bl.m].name, nd->bl.x, nd->bl.y,
- map[m].name, nd->u.warp.x, nd->u.warp.y
- );
- }
- if (map_getcell(m, nd->u.warp.x, nd->u.warp.y, CELL_CHKNOPASS)) {
- ShowWarning("Warp %s at %s(%d,%d) warps to a non-walkable tile at %s(%d,%d)\n",
- nd->name,
- map[nd->bl.m].name, nd->bl.x, nd->bl.y,
- map[m].name, nd->u.warp.x, nd->u.warp.y
- );
- }
+int do_final_npc(void) {
+ npc_clear_pathlist();
+ ev_db->destroy(ev_db, NULL);
+ npcname_db->destroy(npcname_db, NULL);
+ npc_path_db->destroy(npc_path_db, NULL);
+ ers_destroy(timer_event_ers);
+ npc_clearsrcfile();
+
+ return 0;
+}
+
+static void npc_debug_warps_sub(struct npc_data* nd)
+{
+ int m;
+ if (nd->bl.type != BL_NPC || nd->subtype != WARP || nd->bl.m < 0)
+ return;
+
+ m = map_mapindex2mapid(nd->u.warp.mapindex);
+ if (m < 0) return; //Warps to another map, nothing to do about it.
+ if (nd->u.warp.x == 0 && nd->u.warp.y == 0) return; // random warp
+
+ if (map_getcell(m, nd->u.warp.x, nd->u.warp.y, CELL_CHKNPC)) {
+ ShowWarning("Warp %s at %s(%d,%d) warps directly on top of an area npc at %s(%d,%d)\n",
+ nd->name,
+ map[nd->bl.m].name, nd->bl.x, nd->bl.y,
+ map[m].name, nd->u.warp.x, nd->u.warp.y
+ );
+ }
+ if (map_getcell(m, nd->u.warp.x, nd->u.warp.y, CELL_CHKNOPASS)) {
+ ShowWarning("Warp %s at %s(%d,%d) warps to a non-walkable tile at %s(%d,%d)\n",
+ nd->name,
+ map[nd->bl.m].name, nd->bl.x, nd->bl.y,
+ map[m].name, nd->u.warp.x, nd->u.warp.y
+ );
+ }
}
static void npc_debug_warps(void)
{
- int m, i;
- for (m = 0; m < map_num; m++)
- for (i = 0; i < map[m].npc_num; i++)
- npc_debug_warps_sub(map[m].npc[i]);
+ int m, i;
+ for (m = 0; m < map_num; m++)
+ for (i = 0; i < map[m].npc_num; i++)
+ npc_debug_warps_sub(map[m].npc[i]);
}
/*==========================================
@@ -3639,64 +3795,64 @@ static void npc_debug_warps(void)
*------------------------------------------*/
int do_init_npc(void)
{
- struct npc_src_list *file;
- int i;
-
- //Stock view data for normal npcs.
- memset(&npc_viewdb, 0, sizeof(npc_viewdb));
- npc_viewdb[0].class_ = INVISIBLE_CLASS; //Invisible class is stored here.
- for (i = 1; i < MAX_NPC_CLASS; i++)
- npc_viewdb[i].class_ = i;
-
- ev_db = strdb_alloc((DBOptions)(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA),2*NAME_LENGTH+2+1);
- npcname_db = strdb_alloc(DB_OPT_BASE,NAME_LENGTH);
- npc_path_db = strdb_alloc(DB_OPT_BASE|DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA,80);
-
- timer_event_ers = ers_new(sizeof(struct timer_event_data),"clif.c::timer_event_ers",ERS_OPT_NONE);
-
- // process all npc files
- ShowStatus("Loading NPCs...\r");
- for (file = npc_src_files; file != NULL; file = file->next) {
- ShowStatus("Loading NPC file: %s"CL_CLL"\r", file->name);
- npc_parsesrcfile(file->name,false);
- }
- ShowInfo("Done loading '"CL_WHITE"%d"CL_RESET"' NPCs:"CL_CLL"\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"' Spawn sets\n"
- "\t-'"CL_WHITE"%d"CL_RESET"' Mobs Cached\n"
- "\t-'"CL_WHITE"%d"CL_RESET"' Mobs Not Cached\n",
- npc_id - START_NPC_NUM, npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob);
-
- // set up the events cache
- memset(script_event, 0, sizeof(script_event));
- npc_read_event_script();
-
- //Debug function to locate all endless loop warps.
- if (battle_config.warp_point_debug)
- npc_debug_warps();
-
- add_timer_func_list(npc_event_do_clock,"npc_event_do_clock");
- add_timer_func_list(npc_timerevent,"npc_timerevent");
-
- // Init dummy NPC
- fake_nd = (struct npc_data *)aCalloc(1,sizeof(struct npc_data));
- fake_nd->bl.m = -1;
- fake_nd->bl.id = npc_get_new_npc_id();
- fake_nd->class_ = -1;
- fake_nd->speed = 200;
- strcpy(fake_nd->name,"FAKE_NPC");
- memcpy(fake_nd->exname, fake_nd->name, 9);
-
- npc_script++;
- fake_nd->bl.type = BL_NPC;
- fake_nd->subtype = SCRIPT;
-
- strdb_put(npcname_db, fake_nd->exname, fake_nd);
- fake_nd->u.scr.timerid = INVALID_TIMER;
- map_addiddb(&fake_nd->bl);
- // End of initialization
-
- return 0;
+ struct npc_src_list *file;
+ int i;
+
+ //Stock view data for normal npcs.
+ memset(&npc_viewdb, 0, sizeof(npc_viewdb));
+ npc_viewdb[0].class_ = INVISIBLE_CLASS; //Invisible class is stored here.
+ for( i = 1; i < MAX_NPC_CLASS; i++ )
+ npc_viewdb[i].class_ = i;
+
+ ev_db = strdb_alloc((DBOptions)(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA),2*NAME_LENGTH+2+1);
+ npcname_db = strdb_alloc(DB_OPT_BASE,NAME_LENGTH);
+ npc_path_db = strdb_alloc(DB_OPT_BASE|DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA,80);
+
+ timer_event_ers = ers_new(sizeof(struct timer_event_data),"clif.c::timer_event_ers",ERS_OPT_NONE);
+
+ // process all npc files
+ ShowStatus("Loading NPCs...\r");
+ for( file = npc_src_files; file != NULL; file = file->next ) {
+ ShowStatus("Loading NPC file: %s"CL_CLL"\r", file->name);
+ npc_parsesrcfile(file->name,false);
+ }
+ ShowInfo ("Done loading '"CL_WHITE"%d"CL_RESET"' NPCs:"CL_CLL"\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"' Spawn sets\n"
+ "\t-'"CL_WHITE"%d"CL_RESET"' Mobs Cached\n"
+ "\t-'"CL_WHITE"%d"CL_RESET"' Mobs Not Cached\n",
+ npc_id - START_NPC_NUM, npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob);
+
+ // set up the events cache
+ memset(script_event, 0, sizeof(script_event));
+ npc_read_event_script();
+
+ //Debug function to locate all endless loop warps.
+ if (battle_config.warp_point_debug)
+ npc_debug_warps();
+
+ add_timer_func_list(npc_event_do_clock,"npc_event_do_clock");
+ add_timer_func_list(npc_timerevent,"npc_timerevent");
+
+ // Init dummy NPC
+ fake_nd = (struct npc_data *)aCalloc(1,sizeof(struct npc_data));
+ fake_nd->bl.m = -1;
+ fake_nd->bl.id = npc_get_new_npc_id();
+ fake_nd->class_ = -1;
+ fake_nd->speed = 200;
+ strcpy(fake_nd->name,"FAKE_NPC");
+ memcpy(fake_nd->exname, fake_nd->name, 9);
+
+ npc_script++;
+ fake_nd->bl.type = BL_NPC;
+ fake_nd->subtype = SCRIPT;
+
+ strdb_put(npcname_db, fake_nd->exname, fake_nd);
+ fake_nd->u.scr.timerid = INVALID_TIMER;
+ map_addiddb(&fake_nd->bl);
+ // End of initialization
+
+ return 0;
}
diff --git a/src/map/npc.h b/src/map/npc.h
index 6e0fe0ee5..0379ae634 100644
--- a/src/map/npc.h
+++ b/src/map/npc.h
@@ -13,74 +13,75 @@ struct view_data;
struct npc_timerevent_list {
- int timer,pos;
+ int timer,pos;
};
struct npc_label_list {
- char name[NAME_LENGTH];
- int pos;
+ char name[NAME_LENGTH];
+ int pos;
};
struct npc_item_list {
- unsigned int nameid,value;
+ unsigned int nameid,value;
};
struct npc_data {
- struct block_list bl;
- struct unit_data ud; //Because they need to be able to move....
- struct view_data *vd;
- struct status_change sc; //They can't have status changes, but.. they want the visual opt values.
- struct npc_data *master_nd;
- short class_;
- short speed;
- char name[NAME_LENGTH+1];// display name
- char exname[NAME_LENGTH+1];// unique npc name
- int chat_id;
- int touching_id;
- unsigned int next_walktime;
-
- unsigned size : 2;
-
- void *chatdb; // pointer to a npc_parse struct (see npc_chat.c)
- char *path;/* path dir */
- enum npc_subtype subtype;
- int src_id;
- union {
- struct {
- struct script_code *script;
- short xs,ys; // OnTouch area radius
- int guild_id;
- int timer,timerid,timeramount,rid;
- unsigned int timertick;
- struct npc_timerevent_list *timer_event;
- int label_list_num;
- struct npc_label_list *label_list;
- } scr;
- struct {
- struct npc_item_list *shop_item;
- int count;
- } shop;
- struct {
- short xs,ys; // OnTouch area radius
- short x,y; // destination coords
- unsigned short mapindex; // destination map
- } warp;
- struct {
- struct mob_data *md;
- time_t kill_time;
- char killer_name[NAME_LENGTH];
- } tomb;
- } u;
+ struct block_list bl;
+ struct unit_data ud; //Because they need to be able to move....
+ struct view_data *vd;
+ struct status_change sc; //They can't have status changes, but.. they want the visual opt values.
+ struct npc_data *master_nd;
+ short class_;
+ short speed;
+ char name[NAME_LENGTH+1];// display name
+ char exname[NAME_LENGTH+1];// unique npc name
+ int chat_id;
+ int touching_id;
+ unsigned int next_walktime;
+
+ unsigned size : 2;
+
+ void* chatdb; // pointer to a npc_parse struct (see npc_chat.c)
+ char* path;/* path dir */
+ enum npc_subtype subtype;
+ int src_id;
+ union {
+ struct {
+ struct script_code *script;
+ short xs,ys; // OnTouch area radius
+ int guild_id;
+ int timer,timerid,timeramount,rid;
+ unsigned int timertick;
+ struct npc_timerevent_list *timer_event;
+ int label_list_num;
+ struct npc_label_list *label_list;
+ } scr;
+ struct {
+ struct npc_item_list* shop_item;
+ int count;
+ } shop;
+ struct {
+ short xs,ys; // OnTouch area radius
+ short x,y; // destination coords
+ unsigned short mapindex; // destination map
+ } warp;
+ struct {
+ struct mob_data *md;
+ time_t kill_time;
+ char killer_name[NAME_LENGTH];
+ } tomb;
+ } u;
};
#define START_NPC_NUM 110000000
-enum actor_classes {
- WARP_CLASS = 45,
- HIDDEN_WARP_CLASS = 139,
- WARP_DEBUG_CLASS = 722,
- FLAG_CLASS = 722,
- INVISIBLE_CLASS = 32767,
+enum actor_classes
+{
+ WARP_CLASS = 45,
+ HIDDEN_WARP_CLASS = 139,
+ WARP_DEBUG_CLASS = 722,
+ FLAG_CLASS = 722,
+ INVISIBLE_CLASS = 32767,
};
#define MAX_NPC_CLASS 1000
@@ -89,91 +90,91 @@ enum actor_classes {
#define npcdb_checkid(id) ( ( (id) >= 46 && (id) <= 125) || (id) == HIDDEN_WARP_CLASS || ( (id) > 400 && (id) < MAX_NPC_CLASS ) || (id) == INVISIBLE_CLASS )
#ifdef PCRE_SUPPORT
-void npc_chat_finalize(struct npc_data *nd);
+void npc_chat_finalize(struct npc_data* nd);
#endif
//Script NPC events.
enum npce_event {
- NPCE_LOGIN,
- NPCE_LOGOUT,
- NPCE_LOADMAP,
- NPCE_BASELVUP,
- NPCE_JOBLVUP,
- NPCE_DIE,
- NPCE_KILLPC,
- NPCE_KILLNPC,
- NPCE_MAX
+ NPCE_LOGIN,
+ NPCE_LOGOUT,
+ NPCE_LOADMAP,
+ NPCE_BASELVUP,
+ NPCE_JOBLVUP,
+ NPCE_DIE,
+ NPCE_KILLPC,
+ NPCE_KILLNPC,
+ NPCE_MAX
};
-struct view_data *npc_get_viewdata(int class_);
-int npc_chat_sub(struct block_list *bl, va_list ap);
-int npc_event_dequeue(struct map_session_data *sd);
-int npc_event(struct map_session_data *sd, const char *eventname, int ontouch);
-int npc_touch_areanpc(struct map_session_data *sd, int m, int x, int y);
+struct view_data* npc_get_viewdata(int class_);
+int npc_chat_sub(struct block_list* bl, va_list ap);
+int npc_event_dequeue(struct map_session_data* sd);
+int npc_event(struct map_session_data* sd, const char* eventname, int ontouch);
+int npc_touch_areanpc(struct map_session_data* sd, int m, int x, int y);
int npc_touch_areanpc2(struct mob_data *md); // [Skotlex]
int npc_check_areanpc(int flag, int m, int x, int y, int range);
-int npc_touchnext_areanpc(struct map_session_data *sd,bool leavemap);
-int npc_click(struct map_session_data *sd, struct npc_data *nd);
-int npc_scriptcont(struct map_session_data *sd, int id);
-struct npc_data *npc_checknear(struct map_session_data *sd, struct block_list *bl);
-int npc_buysellsel(struct map_session_data *sd, int id, int type);
-int npc_buylist(struct map_session_data *sd,int n, unsigned short *item_list);
-int npc_selllist(struct map_session_data *sd, int n, unsigned short *item_list);
-void npc_parse_mob2(struct spawn_data *mob);
-struct npc_data *npc_add_warp(char *name, short from_mapid, short from_x, short from_y, short xs, short ys, unsigned short to_mapindex, short to_x, short to_y);
-int npc_globalmessage(const char *name,const char *mes);
-
-void npc_setcells(struct npc_data *nd);
-void npc_unsetcells(struct npc_data *nd);
-void npc_movenpc(struct npc_data *nd, int x, int y);
-int npc_enable(const char *name, int flag);
-void npc_setdisplayname(struct npc_data *nd, const char *newname);
-void npc_setclass(struct npc_data *nd, short class_);
-struct npc_data *npc_name2id(const char *name);
+int npc_touchnext_areanpc(struct map_session_data* sd,bool leavemap);
+int npc_click(struct map_session_data* sd, struct npc_data* nd);
+int npc_scriptcont(struct map_session_data* sd, int id);
+struct npc_data* npc_checknear(struct map_session_data* sd, struct block_list* bl);
+int npc_buysellsel(struct map_session_data* sd, int id, int type);
+int npc_buylist(struct map_session_data* sd,int n, unsigned short* item_list);
+int npc_selllist(struct map_session_data* sd, int n, unsigned short* item_list);
+void npc_parse_mob2(struct spawn_data* mob);
+struct npc_data* npc_add_warp(char* name, short from_mapid, short from_x, short from_y, short xs, short ys, unsigned short to_mapindex, short to_x, short to_y);
+int npc_globalmessage(const char* name,const char* mes);
+
+void npc_setcells(struct npc_data* nd);
+void npc_unsetcells(struct npc_data* nd);
+void npc_movenpc(struct npc_data* nd, int x, int y);
+int npc_enable(const char* name, int flag);
+void npc_setdisplayname(struct npc_data* nd, const char* newname);
+void npc_setclass(struct npc_data* nd, short class_);
+struct npc_data* npc_name2id(const char* name);
int npc_get_new_npc_id(void);
-void npc_addsrcfile(const char *name);
-void npc_delsrcfile(const char *name);
-void npc_parsesrcfile(const char *filepath, bool runOnInit);
+void npc_addsrcfile(const char* name);
+void npc_delsrcfile(const char* name);
+void npc_parsesrcfile(const char* filepath, bool runOnInit);
void do_clear_npc(void);
int do_final_npc(void);
int do_init_npc(void);
void npc_event_do_oninit(void);
int npc_do_ontimer(int npc_id, int option);
-int npc_event_do(const char *name);
-int npc_event_doall(const char *name);
-int npc_event_doall_id(const char *name, int rid);
-
-int npc_timerevent_start(struct npc_data *nd, int rid);
-int npc_timerevent_stop(struct npc_data *nd);
-void npc_timerevent_quit(struct map_session_data *sd);
-int npc_gettimerevent_tick(struct npc_data *nd);
-int npc_settimerevent_tick(struct npc_data *nd, int newtimer);
-int npc_remove_map(struct npc_data *nd);
-void npc_unload_duplicates(struct npc_data *nd);
-int npc_unload(struct npc_data *nd, bool single);
+int npc_event_do(const char* name);
+int npc_event_doall(const char* name);
+int npc_event_doall_id(const char* name, int rid);
+
+int npc_timerevent_start(struct npc_data* nd, int rid);
+int npc_timerevent_stop(struct npc_data* nd);
+void npc_timerevent_quit(struct map_session_data* sd);
+int npc_gettimerevent_tick(struct npc_data* nd);
+int npc_settimerevent_tick(struct npc_data* nd, int newtimer);
+int npc_remove_map(struct npc_data* nd);
+void npc_unload_duplicates (struct npc_data* nd);
+int npc_unload(struct npc_data* nd, bool single);
int npc_reload(void);
void npc_read_event_script(void);
-int npc_script_event(struct map_session_data *sd, enum npce_event type);
+int npc_script_event(struct map_session_data* sd, enum npce_event type);
int npc_duplicate4instance(struct npc_data *snd, int m);
int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int points);
-extern struct npc_data *fake_nd;
+extern struct npc_data* fake_nd;
-int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, unsigned short *item_list);
+int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, unsigned short* item_list);
/**
* For the Secure NPC Timeout option (check config/Secure.h) [RR]
**/
#if SECURE_NPCTIMEOUT
-int npc_rr_secure_timeout_timer(int tid, unsigned int tick, int id, intptr_t data);
+ int npc_rr_secure_timeout_timer(int tid, unsigned int tick, int id, intptr_t data);
#endif
// @commands (script-based)
-int npc_do_atcmd_event(struct map_session_data *sd, const char *command, const char *message, const char *eventname);
+int npc_do_atcmd_event(struct map_session_data* sd, const char* command, const char* message, const char* eventname);
-bool npc_unloadfile(const char *path);
+bool npc_unloadfile( const char* path );
#endif /* _NPC_H_ */
diff --git a/src/map/npc_chat.c b/src/map/npc_chat.c
index c0a965e9d..39a3a8584 100644
--- a/src/map/npc_chat.c
+++ b/src/map/npc_chat.c
@@ -40,7 +40,7 @@
*
* defpattern 1, "[^:]+: (.*) loves (.*)", "label";
*
- * this defines a new pattern in set 1 using perl syntax
+ * 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.
@@ -50,7 +50,7 @@
* 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
@@ -71,22 +71,22 @@
/* 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;
+ 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 *prev;
- struct pcrematch_set *next;
- struct pcrematch_entry *head;
- int setid;
+ struct pcrematch_set* prev;
+ struct pcrematch_set* next;
+ 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
@@ -96,8 +96,8 @@ struct pcrematch_set {
* without having to do a large number of changes.
*/
struct npc_parse {
- struct pcrematch_set *active;
- struct pcrematch_set *inactive;
+ struct pcrematch_set* active;
+ struct pcrematch_set* inactive;
};
@@ -106,50 +106,51 @@ struct npc_parse {
*
* This does NOT do the list management
*/
-void finalize_pcrematch_entry(struct pcrematch_entry *e)
+void finalize_pcrematch_entry(struct pcrematch_entry* e)
{
- pcre_free(e->pcre_);
- pcre_free(e->pcre_extra_);
- aFree(e->pattern);
- aFree(e->label);
+ pcre_free(e->pcre_);
+ 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;
+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;
}
/**
@@ -157,32 +158,32 @@ static struct pcrematch_set *lookup_pcreset(struct npc_data *nd, int setid) {
*
* if the setid does not exist, this will silently return
*/
-static void activate_pcreset(struct npc_data *nd, int setid)
+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;
+ 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;
}
/**
@@ -190,255 +191,260 @@ static void activate_pcreset(struct npc_data *nd, int setid)
*
* if the setid does not exist, this will silently return
*/
-static void deactivate_pcreset(struct npc_data *nd, int setid)
+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;
+ 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)
+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;
-
- if (active)
- 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);
- aFree(pcreset->head); // Cleanin' the last ones.. [Lance]
- pcreset->head = n;
- }
-
- aFree(pcreset);
+ 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;
+
+ if(active)
+ 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);
+ aFree(pcreset->head); // Cleanin' the last ones.. [Lance]
+ pcreset->head = n;
+ }
+
+ aFree(pcreset);
}
/**
- * create a new pattern entry
+ * 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;
+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)
+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);
+ 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
+ * matching code
*
* this could be more efficent but.. how often do you do this?
*/
-void npc_chat_finalize(struct npc_data *nd)
+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);
-
- // Additional cleaning up [Lance]
- aFree(npcParse);
+ 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);
+
+ // Additional cleaning up [Lance]
+ aFree(npcParse);
}
/**
* Handler called whenever a global message is spoken in a NPC's area
*/
-int npc_chat_sub(struct block_list *bl, va_list ap)
+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;
- char *msg;
- int len, i;
- struct map_session_data *sd;
- struct npc_label_list *lst;
- struct pcrematch_set *pcreset;
- struct pcrematch_entry *e;
-
- // Not interested in anything you might have to say...
- if (npcParse == NULL || npcParse->active == NULL)
- return 0;
-
- msg = va_arg(ap,char *);
- len = va_arg(ap,int);
- sd = va_arg(ap,struct map_session_data *);
-
- // iterate across all active sets
- for (pcreset = npcParse->active; pcreset != NULL; pcreset = pcreset->next) {
- // interate across all patterns in that set
- for (e = pcreset->head; e != NULL; e = e->next) {
- int offsets[2*10 + 10]; // 1/3 reserved for temp space requred by pcre_exec
-
- // perform pattern match
- int r = pcre_exec(e->pcre_, e->pcre_extra_, msg, len, 0, 0, offsets, ARRAYLENGTH(offsets));
- if (r > 0) {
- // save out the matched strings
- for (i = 0; i < r; i++) {
- char var[6], val[255];
- snprintf(var, sizeof(var), "$@p%i$", i);
- pcre_copy_substring(msg, offsets, r, i, val, sizeof(val));
- set_var(sd, var, val);
- }
-
- // find the target label.. this sucks..
- lst = nd->u.scr.label_list;
- ARR_FIND(0, nd->u.scr.label_list_num, i, strncmp(lst[i].name, e->label, sizeof(lst[i].name)) == 0);
- if (i == nd->u.scr.label_list_num) {
- ShowWarning("Unable to find label: %s\n", e->label);
- return 0;
- }
-
- // run the npc script
- run_script(nd->u.scr.script,lst[i].pos,sd->bl.id,nd->bl.id);
- return 0;
- }
- }
- }
-
- return 0;
+ struct npc_data* nd = (struct npc_data *) bl;
+ struct npc_parse* npcParse = (struct npc_parse *) nd->chatdb;
+ char* msg;
+ int len, i;
+ struct map_session_data* sd;
+ struct npc_label_list* lst;
+ struct pcrematch_set* pcreset;
+ struct pcrematch_entry* e;
+
+ // Not interested in anything you might have to say...
+ if (npcParse == NULL || npcParse->active == NULL)
+ return 0;
+
+ msg = va_arg(ap,char*);
+ len = va_arg(ap,int);
+ sd = va_arg(ap,struct map_session_data *);
+
+ // iterate across all active sets
+ for (pcreset = npcParse->active; pcreset != NULL; pcreset = pcreset->next)
+ {
+ // interate across all patterns in that set
+ for (e = pcreset->head; e != NULL; e = e->next)
+ {
+ int offsets[2*10 + 10]; // 1/3 reserved for temp space requred by pcre_exec
+
+ // perform pattern match
+ int r = pcre_exec(e->pcre_, e->pcre_extra_, msg, len, 0, 0, offsets, ARRAYLENGTH(offsets));
+ if (r > 0)
+ {
+ // save out the matched strings
+ for (i = 0; i < r; i++)
+ {
+ char var[6], val[255];
+ snprintf(var, sizeof(var), "$@p%i$", i);
+ pcre_copy_substring(msg, offsets, r, i, val, sizeof(val));
+ set_var(sd, var, val);
+ }
+
+ // find the target label.. this sucks..
+ lst = nd->u.scr.label_list;
+ ARR_FIND(0, nd->u.scr.label_list_num, i, strncmp(lst[i].name, e->label, sizeof(lst[i].name)) == 0);
+ if (i == nd->u.scr.label_list_num) {
+ ShowWarning("Unable to find label: %s\n", e->label);
+ return 0;
+ }
+
+ // run the npc script
+ run_script(nd->u.scr.script,lst[i].pos,sd->bl.id,nd->bl.id);
+ return 0;
+ }
+ }
+ }
+
+ return 0;
}
// Various script builtins used to support these functions
-int buildin_defpattern(struct script_state *st)
+int buildin_defpattern(struct script_state* st)
{
- int setid = conv_num(st,& (st->stack->stack_data[st->start+2]));
- const char *pattern = conv_str(st,& (st->stack->stack_data[st->start+3]));
- const 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 setid = conv_num(st,& (st->stack->stack_data[st->start+2]));
+ const char* pattern = conv_str(st,& (st->stack->stack_data[st->start+3]));
+ const 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 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 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 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 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 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;
+ 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 //PCRE_SUPPORT
diff --git a/src/map/party.c b/src/map/party.c
index d17112caf..f7a2ebc6a 100644
--- a/src/map/party.c
+++ b/src/map/party.c
@@ -12,7 +12,7 @@
#include "../common/strlib.h"
#include "party.h"
-#include "atcommand.h" //msg_txt()
+#include "atcommand.h" //msg_txt()
#include "pc.h"
#include "map.h"
#include "instance.h"
@@ -29,8 +29,8 @@
#include <string.h>
-static DBMap *party_db; // int party_id -> struct party_data* (releases data)
-static DBMap *party_booking_db; // int char_id -> struct party_booking_ad_info* (releases data) // Party Booking [Spiria]
+static DBMap* party_db; // int party_id -> struct party_data* (releases data)
+static DBMap* party_booking_db; // int char_id -> struct party_booking_ad_info* (releases data) // Party Booking [Spiria]
static unsigned long party_booking_nextid = 1;
int party_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data);
@@ -39,66 +39,67 @@ int party_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data);
* Fills the given party_member structure according to the sd provided.
* Used when creating/adding people to a party. [Skotlex]
*------------------------------------------*/
-static void party_fill_member(struct party_member *member, struct map_session_data *sd, unsigned int leader)
+static void party_fill_member(struct party_member* member, struct map_session_data* sd, unsigned int leader)
{
- member->account_id = sd->status.account_id;
- member->char_id = sd->status.char_id;
- safestrncpy(member->name, sd->status.name, NAME_LENGTH);
- member->class_ = sd->status.class_;
- member->map = sd->mapindex;
- member->lv = sd->status.base_level;
- member->online = 1;
- member->leader = leader;
+ member->account_id = sd->status.account_id;
+ member->char_id = sd->status.char_id;
+ safestrncpy(member->name, sd->status.name, NAME_LENGTH);
+ member->class_ = sd->status.class_;
+ member->map = sd->mapindex;
+ member->lv = sd->status.base_level;
+ member->online = 1;
+ member->leader = leader;
}
/// Get the member_id of a party member.
/// Return -1 if not in party.
-int party_getmemberid(struct party_data *p, struct map_session_data *sd)
+int party_getmemberid(struct party_data* p, struct map_session_data* sd)
{
- int member_id;
- nullpo_retr(-1, p);
- if (sd == NULL)
- return -1;// no player
- ARR_FIND(0, MAX_PARTY, member_id,
- p->party.member[member_id].account_id == sd->status.account_id &&
- p->party.member[member_id].char_id == sd->status.char_id);
- if (member_id == MAX_PARTY)
- return -1;// not found
- return member_id;
+ int member_id;
+ nullpo_retr(-1, p);
+ if( sd == NULL )
+ return -1;// no player
+ ARR_FIND(0, MAX_PARTY, member_id,
+ p->party.member[member_id].account_id == sd->status.account_id &&
+ p->party.member[member_id].char_id == sd->status.char_id);
+ if( member_id == MAX_PARTY )
+ return -1;// not found
+ return member_id;
}
/*==========================================
* Request an available sd of this party
*------------------------------------------*/
-struct map_session_data *party_getavailablesd(struct party_data *p) {
- int i;
- nullpo_retr(NULL, p);
- ARR_FIND(0, MAX_PARTY, i, p->data[i].sd != NULL);
- return(i < MAX_PARTY) ? p->data[i].sd : NULL;
+struct map_session_data* party_getavailablesd(struct party_data *p)
+{
+ int i;
+ nullpo_retr(NULL, p);
+ ARR_FIND(0, MAX_PARTY, i, p->data[i].sd != NULL);
+ return( i < MAX_PARTY ) ? p->data[i].sd : NULL;
}
/*==========================================
* Retrieves and validates the sd pointer for this party member [Skotlex]
*------------------------------------------*/
-static TBL_PC *party_sd_check(int party_id, int account_id, int char_id)
+static TBL_PC* party_sd_check(int party_id, int account_id, int char_id)
{
- TBL_PC *sd = map_id2sd(account_id);
+ TBL_PC* sd = map_id2sd(account_id);
- if (!(sd && sd->status.char_id == char_id))
- return NULL;
+ if (!(sd && sd->status.char_id == char_id))
+ return NULL;
- if (sd->status.party_id == 0)
- sd->status.party_id = party_id;// auto-join if not in a party
- if (sd->status.party_id != party_id) {
- //If player belongs to a different party, kick him out.
- intif_party_leave(party_id,account_id,char_id);
- return NULL;
- }
+ if( sd->status.party_id == 0 )
+ sd->status.party_id = party_id;// auto-join if not in a party
+ if (sd->status.party_id != party_id)
+ { //If player belongs to a different party, kick him out.
+ intif_party_leave(party_id,account_id,char_id);
+ return NULL;
+ }
- return sd;
+ return sd;
}
/*==========================================
@@ -107,303 +108,318 @@ static TBL_PC *party_sd_check(int party_id, int account_id, int char_id)
*------------------------------------------*/
void do_final_party(void)
{
- party_db->destroy(party_db,NULL);
- party_booking_db->destroy(party_booking_db,NULL); // Party Booking [Spiria]
+ party_db->destroy(party_db,NULL);
+ party_booking_db->destroy(party_booking_db,NULL); // Party Booking [Spiria]
}
// Constructor, init vars
void do_init_party(void)
{
- party_db = idb_alloc(DB_OPT_RELEASE_DATA);
- party_booking_db = idb_alloc(DB_OPT_RELEASE_DATA); // Party Booking [Spiria]
- add_timer_func_list(party_send_xy_timer, "party_send_xy_timer");
- add_timer_interval(gettick()+battle_config.party_update_interval, party_send_xy_timer, 0, 0, battle_config.party_update_interval);
+ party_db = idb_alloc(DB_OPT_RELEASE_DATA);
+ party_booking_db = idb_alloc(DB_OPT_RELEASE_DATA); // Party Booking [Spiria]
+ add_timer_func_list(party_send_xy_timer, "party_send_xy_timer");
+ add_timer_interval(gettick()+battle_config.party_update_interval, party_send_xy_timer, 0, 0, battle_config.party_update_interval);
}
/// Party data lookup using party id.
-struct party_data *party_search(int party_id) {
- if (!party_id)
- return NULL;
- return (struct party_data *)idb_get(party_db,party_id);
+struct party_data* party_search(int party_id)
+{
+ if(!party_id)
+ return NULL;
+ return (struct party_data*)idb_get(party_db,party_id);
}
/// Party data lookup using party name.
-struct party_data *party_searchname(const char *str) {
- struct party_data *p;
+struct party_data* party_searchname(const char* str)
+{
+ struct party_data* p;
- DBIterator *iter = db_iterator(party_db);
- for (p = dbi_first(iter); dbi_exists(iter); p = dbi_next(iter)) {
- if (strncmpi(p->party.name,str,NAME_LENGTH) == 0)
- break;
- }
- dbi_destroy(iter);
+ DBIterator *iter = db_iterator(party_db);
+ for( p = dbi_first(iter); dbi_exists(iter); p = dbi_next(iter) )
+ {
+ if( strncmpi(p->party.name,str,NAME_LENGTH) == 0 )
+ break;
+ }
+ dbi_destroy(iter);
- return p;
+ return p;
}
int party_create(struct map_session_data *sd,char *name,int item,int item2)
{
- struct party_member leader;
- char tname[NAME_LENGTH];
+ struct party_member leader;
+ char tname[NAME_LENGTH];
- safestrncpy(tname, name, NAME_LENGTH);
- trim(tname);
+ safestrncpy(tname, name, NAME_LENGTH);
+ trim(tname);
- if (!tname[0]) {
- // empty name
- return 0;
- }
+ if( !tname[0] )
+ {// empty name
+ return 0;
+ }
- if (sd->status.party_id > 0 || sd->party_joining || sd->party_creating) {
- // already associated with a party
- clif_party_created(sd,2);
- return 0;
- }
+ if( sd->status.party_id > 0 || sd->party_joining || sd->party_creating )
+ {// already associated with a party
+ clif_party_created(sd,2);
+ return 0;
+ }
- sd->party_creating = true;
+ sd->party_creating = true;
- party_fill_member(&leader, sd, 1);
+ party_fill_member(&leader, sd, 1);
- intif_create_party(&leader,name,item,item2);
- return 0;
+ intif_create_party(&leader,name,item,item2);
+ return 0;
}
void party_created(int account_id,int char_id,int fail,int party_id,char *name)
{
- struct map_session_data *sd;
- sd=map_id2sd(account_id);
-
- if (!sd || sd->status.char_id != char_id || !sd->party_creating) {
- //Character logged off before creation ack?
- if (!fail) //break up party since player could not be added to it.
- intif_party_leave(party_id,account_id,char_id);
- return;
- }
-
- sd->party_creating = false;
-
- if (!fail) {
- sd->status.party_id = party_id;
- clif_party_created(sd,0); //Success message
- //We don't do any further work here because the char-server sends a party info packet right after creating the party.
- } else {
- clif_party_created(sd,1); // "party name already exists"
- }
+ struct map_session_data *sd;
+ sd=map_id2sd(account_id);
+
+ if (!sd || sd->status.char_id != char_id || !sd->party_creating )
+ { //Character logged off before creation ack?
+ if (!fail) //break up party since player could not be added to it.
+ intif_party_leave(party_id,account_id,char_id);
+ return;
+ }
+
+ sd->party_creating = false;
+
+ if( !fail ) {
+ sd->status.party_id = party_id;
+ clif_party_created(sd,0); //Success message
+ //We don't do any further work here because the char-server sends a party info packet right after creating the party.
+ } else {
+ clif_party_created(sd,1); // "party name already exists"
+ }
}
int party_request_info(int party_id, int char_id)
{
- return intif_request_partyinfo(party_id, char_id);
+ return intif_request_partyinfo(party_id, char_id);
}
/// Invoked (from char-server) when the party info is not found.
int party_recv_noinfo(int party_id, int char_id)
{
- struct map_session_data *sd;
-
- party_broken(party_id);
- if (char_id != 0) { // requester
- sd = map_charid2sd(char_id);
- if (sd && sd->status.party_id == party_id)
- sd->status.party_id = 0;
- }
- return 0;
+ struct map_session_data* sd;
+
+ party_broken(party_id);
+ if( char_id != 0 )// requester
+ {
+ sd = map_charid2sd(char_id);
+ if( sd && sd->status.party_id == party_id )
+ sd->status.party_id = 0;
+ }
+ return 0;
}
static void party_check_state(struct party_data *p)
{
- int i;
- memset(&p->state, 0, sizeof(p->state));
- for (i = 0; i < MAX_PARTY; i ++) {
- if (!p->party.member[i].online) continue; //Those not online shouldn't aport to skill usage and all that.
- switch (p->party.member[i].class_) {
- case JOB_MONK:
- case JOB_BABY_MONK:
- case JOB_CHAMPION:
- p->state.monk = 1;
- break;
- case JOB_STAR_GLADIATOR:
- p->state.sg = 1;
- break;
- case JOB_SUPER_NOVICE:
- case JOB_SUPER_BABY:
- p->state.snovice = 1;
- break;
- case JOB_TAEKWON:
- p->state.tk = 1;
- break;
- }
- }
+ int i;
+ memset(&p->state, 0, sizeof(p->state));
+ for (i = 0; i < MAX_PARTY; i ++)
+ {
+ if (!p->party.member[i].online) continue; //Those not online shouldn't aport to skill usage and all that.
+ switch (p->party.member[i].class_) {
+ case JOB_MONK:
+ case JOB_BABY_MONK:
+ case JOB_CHAMPION:
+ p->state.monk = 1;
+ break;
+ case JOB_STAR_GLADIATOR:
+ p->state.sg = 1;
+ break;
+ case JOB_SUPER_NOVICE:
+ case JOB_SUPER_BABY:
+ p->state.snovice = 1;
+ break;
+ case JOB_TAEKWON:
+ p->state.tk = 1;
+ break;
+ }
+ }
}
-int party_recv_info(struct party *sp, int char_id)
+int party_recv_info(struct party* sp, int char_id)
{
- struct party_data *p;
- struct party_member *member;
- struct map_session_data *sd;
- int removed[MAX_PARTY];// member_id in old data
- int removed_count = 0;
- int added[MAX_PARTY];// member_id in new data
- int added_count = 0;
- int i;
- int member_id;
-
- nullpo_ret(sp);
-
- p = (struct party_data *)idb_get(party_db, sp->party_id);
- if (p != NULL) { // diff members
- for (member_id = 0; member_id < MAX_PARTY; ++member_id) {
- member = &p->party.member[member_id];
- if (member->char_id == 0)
- continue;// empty
- ARR_FIND(0, MAX_PARTY, i,
- sp->member[i].account_id == member->account_id &&
- sp->member[i].char_id == member->char_id);
- if (i == MAX_PARTY)
- removed[removed_count++] = member_id;
- }
- for (member_id = 0; member_id < MAX_PARTY; ++member_id) {
- member = &sp->member[member_id];
- if (member->char_id == 0)
- continue;// empty
- ARR_FIND(0, MAX_PARTY, i,
- p->party.member[i].account_id == member->account_id &&
- p->party.member[i].char_id == member->char_id);
- if (i == MAX_PARTY)
- added[added_count++] = member_id;
- }
- } else {
- for (member_id = 0; member_id < MAX_PARTY; ++member_id)
- if (sp->member[member_id].char_id != 0)
- added[added_count++] = member_id;
- CREATE(p, struct party_data, 1);
- idb_put(party_db, sp->party_id, p);
- }
- while (removed_count > 0) { // no longer in party
- member_id = removed[--removed_count];
- sd = p->data[member_id].sd;
- if (sd == NULL)
- continue;// not online
- party_member_withdraw(sp->party_id, sd->status.account_id, sd->status.char_id);
- }
- memcpy(&p->party, sp, sizeof(struct party));
- memset(&p->state, 0, sizeof(p->state));
- memset(&p->data, 0, sizeof(p->data));
- for (member_id = 0; member_id < MAX_PARTY; member_id++) {
- member = &p->party.member[member_id];
- if (member->char_id == 0)
- continue;// empty
- p->data[member_id].sd = party_sd_check(sp->party_id, member->account_id, member->char_id);
- }
- party_check_state(p);
- while (added_count > 0) { // new in party
- member_id = added[--added_count];
- sd = p->data[member_id].sd;
- if (sd == NULL)
- continue;// not online
- clif_charnameupdate(sd); //Update other people's display. [Skotlex]
- clif_party_member_info(p,sd);
- clif_party_option(p,sd,0x100);
- clif_party_info(p,NULL);
- if (p->instance_id != 0)
- clif_instance_join(sd->fd, p->instance_id);
- }
- if (char_id != 0) { // requester
- sd = map_charid2sd(char_id);
- if (sd && sd->status.party_id == sp->party_id && party_getmemberid(p,sd) == -1)
- sd->status.party_id = 0;// was not in the party
- }
- return 0;
+ struct party_data* p;
+ struct party_member* member;
+ struct map_session_data* sd;
+ int removed[MAX_PARTY];// member_id in old data
+ int removed_count = 0;
+ int added[MAX_PARTY];// member_id in new data
+ int added_count = 0;
+ int i;
+ int member_id;
+
+ nullpo_ret(sp);
+
+ p = (struct party_data*)idb_get(party_db, sp->party_id);
+ if( p != NULL )// diff members
+ {
+ for( member_id = 0; member_id < MAX_PARTY; ++member_id )
+ {
+ member = &p->party.member[member_id];
+ if( member->char_id == 0 )
+ continue;// empty
+ ARR_FIND(0, MAX_PARTY, i,
+ sp->member[i].account_id == member->account_id &&
+ sp->member[i].char_id == member->char_id);
+ if( i == MAX_PARTY )
+ removed[removed_count++] = member_id;
+ }
+ for( member_id = 0; member_id < MAX_PARTY; ++member_id )
+ {
+ member = &sp->member[member_id];
+ if( member->char_id == 0 )
+ continue;// empty
+ ARR_FIND(0, MAX_PARTY, i,
+ p->party.member[i].account_id == member->account_id &&
+ p->party.member[i].char_id == member->char_id);
+ if( i == MAX_PARTY )
+ added[added_count++] = member_id;
+ }
+ }
+ else
+ {
+ for( member_id = 0; member_id < MAX_PARTY; ++member_id )
+ if( sp->member[member_id].char_id != 0 )
+ added[added_count++] = member_id;
+ CREATE(p, struct party_data, 1);
+ idb_put(party_db, sp->party_id, p);
+ }
+ while( removed_count > 0 )// no longer in party
+ {
+ member_id = removed[--removed_count];
+ sd = p->data[member_id].sd;
+ if( sd == NULL )
+ continue;// not online
+ party_member_withdraw(sp->party_id, sd->status.account_id, sd->status.char_id);
+ }
+ memcpy(&p->party, sp, sizeof(struct party));
+ memset(&p->state, 0, sizeof(p->state));
+ memset(&p->data, 0, sizeof(p->data));
+ for( member_id = 0; member_id < MAX_PARTY; member_id++ )
+ {
+ member = &p->party.member[member_id];
+ if ( member->char_id == 0 )
+ continue;// empty
+ p->data[member_id].sd = party_sd_check(sp->party_id, member->account_id, member->char_id);
+ }
+ party_check_state(p);
+ while( added_count > 0 )// new in party
+ {
+ member_id = added[--added_count];
+ sd = p->data[member_id].sd;
+ if( sd == NULL )
+ continue;// not online
+ clif_charnameupdate(sd); //Update other people's display. [Skotlex]
+ clif_party_member_info(p,sd);
+ clif_party_option(p,sd,0x100);
+ clif_party_info(p,NULL);
+ if( p->instance_id != 0 )
+ clif_instance_join(sd->fd, p->instance_id);
+ }
+ if( char_id != 0 )// requester
+ {
+ sd = map_charid2sd(char_id);
+ if( sd && sd->status.party_id == sp->party_id && party_getmemberid(p,sd) == -1 )
+ sd->status.party_id = 0;// was not in the party
+ }
+ return 0;
}
int party_invite(struct map_session_data *sd,struct map_session_data *tsd)
{
- struct party_data *p;
- int i;
-
- nullpo_ret(sd);
-
- if ((p = party_search(sd->status.party_id)) == NULL)
- return 0;
-
- // confirm if this player is a party leader
- ARR_FIND(0, MAX_PARTY, i, p->data[i].sd == sd);
-
- if (i == MAX_PARTY || !p->party.member[i].leader) {
- clif_displaymessage(sd->fd, msg_txt(282));
- return 0;
- }
-
- // confirm if there is an open slot in the party
- ARR_FIND(0, MAX_PARTY, i, p->party.member[i].account_id == 0);
-
- if (i == MAX_PARTY) {
- clif_party_inviteack(sd, (tsd?tsd->status.name:""), 3);
- return 0;
- }
-
- // confirm whether the account has the ability to invite before checking the player
- if (!pc_has_permission(sd, PC_PERM_PARTY) || (tsd && !pc_has_permission(tsd, PC_PERM_PARTY))) {
- clif_displaymessage(sd->fd, msg_txt(81)); // "Your GM level doesn't authorize you to preform this action on the specified player."
- return 0;
- }
-
- if (tsd == NULL) {
- clif_party_inviteack(sd, "", 7);
- return 0;
- }
-
- if (!battle_config.invite_request_check) {
- if (tsd->guild_invite>0 || tsd->trade_partner || tsd->adopt_invite) {
- clif_party_inviteack(sd,tsd->status.name,0);
- return 0;
- }
- }
-
- if (!tsd->fd) { //You can't invite someone who has already disconnected.
- clif_party_inviteack(sd,tsd->status.name,1);
- return 0;
- }
-
- if (tsd->status.party_id > 0 || tsd->party_invite > 0) {
- // already associated with a party
- clif_party_inviteack(sd,tsd->status.name,0);
- return 0;
- }
-
- tsd->party_invite=sd->status.party_id;
- tsd->party_invite_account=sd->status.account_id;
-
- clif_party_invite(sd,tsd);
- return 1;
+ struct party_data *p;
+ int i;
+
+ nullpo_ret(sd);
+
+ if( ( p = party_search(sd->status.party_id) ) == NULL )
+ return 0;
+
+ // confirm if this player is a party leader
+ ARR_FIND(0, MAX_PARTY, i, p->data[i].sd == sd);
+
+ if( i == MAX_PARTY || !p->party.member[i].leader ) {
+ clif_displaymessage(sd->fd, msg_txt(282));
+ return 0;
+ }
+
+ // confirm if there is an open slot in the party
+ ARR_FIND(0, MAX_PARTY, i, p->party.member[i].account_id == 0);
+
+ if( i == MAX_PARTY ) {
+ clif_party_inviteack(sd, (tsd?tsd->status.name:""), 3);
+ return 0;
+ }
+
+ // confirm whether the account has the ability to invite before checking the player
+ if( !pc_has_permission(sd, PC_PERM_PARTY) || (tsd && !pc_has_permission(tsd, PC_PERM_PARTY)) ) {
+ clif_displaymessage(sd->fd, msg_txt(81)); // "Your GM level doesn't authorize you to preform this action on the specified player."
+ return 0;
+ }
+
+ if( tsd == NULL) {
+ clif_party_inviteack(sd, "", 7);
+ return 0;
+ }
+
+ if(!battle_config.invite_request_check) {
+ if (tsd->guild_invite>0 || tsd->trade_partner || tsd->adopt_invite) {
+ clif_party_inviteack(sd,tsd->status.name,0);
+ return 0;
+ }
+ }
+
+ if (!tsd->fd) { //You can't invite someone who has already disconnected.
+ clif_party_inviteack(sd,tsd->status.name,1);
+ return 0;
+ }
+
+ if( tsd->status.party_id > 0 || tsd->party_invite > 0 )
+ {// already associated with a party
+ clif_party_inviteack(sd,tsd->status.name,0);
+ return 0;
+ }
+
+ tsd->party_invite=sd->status.party_id;
+ tsd->party_invite_account=sd->status.account_id;
+
+ clif_party_invite(sd,tsd);
+ return 1;
}
void party_reply_invite(struct map_session_data *sd,int party_id,int flag)
{
- struct map_session_data *tsd;
- struct party_member member;
-
- if (sd->party_invite != party_id) {
- // forged
- sd->party_invite = 0;
- sd->party_invite_account = 0;
- return;
- }
- tsd = map_id2sd(sd->party_invite_account);
-
- if (flag == 1 && !sd->party_creating && !sd->party_joining) {
- // accepted and allowed
- sd->party_joining = true;
- party_fill_member(&member, sd, 0);
- intif_party_addmember(sd->party_invite, &member);
- } else {
- // rejected or failure
- sd->party_invite = 0;
- sd->party_invite_account = 0;
- if (tsd != NULL)
- clif_party_inviteack(tsd,sd->status.name,1);
- }
+ struct map_session_data* tsd;
+ struct party_member member;
+
+ if( sd->party_invite != party_id )
+ {// forged
+ sd->party_invite = 0;
+ sd->party_invite_account = 0;
+ return;
+ }
+ tsd = map_id2sd(sd->party_invite_account);
+
+ if( flag == 1 && !sd->party_creating && !sd->party_joining )
+ {// accepted and allowed
+ sd->party_joining = true;
+ party_fill_member(&member, sd, 0);
+ intif_party_addmember(sd->party_invite, &member);
+ }
+ else
+ {// rejected or failure
+ sd->party_invite = 0;
+ sd->party_invite_account = 0;
+ if( tsd != NULL )
+ clif_party_inviteack(tsd,sd->status.name,1);
+ }
}
//Invoked when a player joins:
@@ -412,253 +428,263 @@ void party_reply_invite(struct map_session_data *sd,int party_id,int flag)
//- Player must be authed/active and belong to a party before calling this method
void party_member_joined(struct map_session_data *sd)
{
- struct party_data *p = party_search(sd->status.party_id);
- int i;
- if (!p) {
- party_request_info(sd->status.party_id, sd->status.char_id);
- return;
- }
- ARR_FIND(0, MAX_PARTY, i, p->party.member[i].account_id == sd->status.account_id && p->party.member[i].char_id == sd->status.char_id);
- if (i < MAX_PARTY) {
- p->data[i].sd = sd;
- if (p->instance_id)
- clif_instance_join(sd->fd,p->instance_id);
- } else
- sd->status.party_id = 0; //He does not belongs to the party really?
+ struct party_data* p = party_search(sd->status.party_id);
+ int i;
+ if (!p)
+ {
+ party_request_info(sd->status.party_id, sd->status.char_id);
+ return;
+ }
+ ARR_FIND( 0, MAX_PARTY, i, p->party.member[i].account_id == sd->status.account_id && p->party.member[i].char_id == sd->status.char_id );
+ if (i < MAX_PARTY)
+ {
+ p->data[i].sd = sd;
+ if( p->instance_id )
+ clif_instance_join(sd->fd,p->instance_id);
+ }
+ else
+ sd->status.party_id = 0; //He does not belongs to the party really?
}
/// Invoked (from char-server) when a new member is added to the party.
/// flag: 0-success, 1-failure
int party_member_added(int party_id,int account_id,int char_id, int flag)
{
- struct map_session_data *sd = map_id2sd(account_id),*sd2;
- struct party_data *p = party_search(party_id);
- int i;
-
- if (sd == NULL || sd->status.char_id != char_id || !sd->party_joining) {
- if (!flag) //Char logged off before being accepted into party.
- intif_party_leave(party_id,account_id,char_id);
- return 0;
- }
-
- sd2 = map_id2sd(sd->party_invite_account);
-
- sd->party_joining = false;
- sd->party_invite = 0;
- sd->party_invite_account = 0;
-
- if (!p) {
- ShowError("party_member_added: party %d not found.\n",party_id);
- intif_party_leave(party_id,account_id,char_id);
- return 0;
- }
-
- if (flag) {
- // failed
- if (sd2 != NULL)
- clif_party_inviteack(sd2,sd->status.name,3);
- return 0;
- }
-
- sd->status.party_id = party_id;
-
- clif_party_member_info(p,sd);
- clif_party_option(p,sd,0x100);
- clif_party_info(p,sd);
-
- if (sd2 != NULL)
- clif_party_inviteack(sd2,sd->status.name,2);
-
- for (i = 0; i < ARRAYLENGTH(p->data); ++i) {
- // hp of the other party members
- sd2 = p->data[i].sd;
- if (sd2 && sd2->status.account_id != account_id && sd2->status.char_id != char_id)
- clif_hpmeter_single(sd->fd, sd2->bl.id, sd2->battle_status.hp, sd2->battle_status.max_hp);
- }
- clif_party_hp(sd);
- clif_party_xy(sd);
- clif_charnameupdate(sd); //Update char name's display [Skotlex]
-
- if (p->instance_id)
- clif_instance_join(sd->fd, p->instance_id);
-
- return 0;
+ struct map_session_data *sd = map_id2sd(account_id),*sd2;
+ struct party_data *p = party_search(party_id);
+ int i;
+
+ if(sd == NULL || sd->status.char_id != char_id || !sd->party_joining ) {
+ if (!flag) //Char logged off before being accepted into party.
+ intif_party_leave(party_id,account_id,char_id);
+ return 0;
+ }
+
+ sd2 = map_id2sd(sd->party_invite_account);
+
+ sd->party_joining = false;
+ sd->party_invite = 0;
+ sd->party_invite_account = 0;
+
+ if (!p) {
+ ShowError("party_member_added: party %d not found.\n",party_id);
+ intif_party_leave(party_id,account_id,char_id);
+ return 0;
+ }
+
+ if( flag )
+ {// failed
+ if( sd2 != NULL )
+ clif_party_inviteack(sd2,sd->status.name,3);
+ return 0;
+ }
+
+ sd->status.party_id = party_id;
+
+ clif_party_member_info(p,sd);
+ clif_party_option(p,sd,0x100);
+ clif_party_info(p,sd);
+
+ if( sd2 != NULL )
+ clif_party_inviteack(sd2,sd->status.name,2);
+
+ for( i = 0; i < ARRAYLENGTH(p->data); ++i )
+ {// hp of the other party members
+ sd2 = p->data[i].sd;
+ if( sd2 && sd2->status.account_id != account_id && sd2->status.char_id != char_id )
+ clif_hpmeter_single(sd->fd, sd2->bl.id, sd2->battle_status.hp, sd2->battle_status.max_hp);
+ }
+ clif_party_hp(sd);
+ clif_party_xy(sd);
+ clif_charnameupdate(sd); //Update char name's display [Skotlex]
+
+ if( p->instance_id )
+ clif_instance_join(sd->fd, p->instance_id);
+
+ return 0;
}
/// Party member 'sd' requesting kick of member with <account_id, name>.
-int party_removemember(struct map_session_data *sd, int account_id, char *name)
+int party_removemember(struct map_session_data* sd, int account_id, char* name)
{
- struct party_data *p;
- int i;
-
- p = party_search(sd->status.party_id);
- if (p == NULL)
- return 0;
-
- // check the requesting char's party membership
- ARR_FIND(0, MAX_PARTY, i, p->party.member[i].account_id == sd->status.account_id && p->party.member[i].char_id == sd->status.char_id);
- if (i == MAX_PARTY)
- return 0; // request from someone not in party? o.O
- if (!p->party.member[i].leader)
- return 0; // only party leader may remove members
-
- ARR_FIND(0, MAX_PARTY, i, p->party.member[i].account_id == account_id && strncmp(p->party.member[i].name,name,NAME_LENGTH) == 0);
- if (i == MAX_PARTY)
- return 0; // no such char in party
-
- intif_party_leave(p->party.party_id,account_id,p->party.member[i].char_id);
- return 1;
+ struct party_data *p;
+ int i;
+
+ p = party_search(sd->status.party_id);
+ if( p == NULL )
+ return 0;
+
+ // check the requesting char's party membership
+ ARR_FIND( 0, MAX_PARTY, i, p->party.member[i].account_id == sd->status.account_id && p->party.member[i].char_id == sd->status.char_id );
+ if( i == MAX_PARTY )
+ return 0; // request from someone not in party? o.O
+ if( !p->party.member[i].leader )
+ return 0; // only party leader may remove members
+
+ ARR_FIND( 0, MAX_PARTY, i, p->party.member[i].account_id == account_id && strncmp(p->party.member[i].name,name,NAME_LENGTH) == 0 );
+ if( i == MAX_PARTY )
+ return 0; // no such char in party
+
+ intif_party_leave(p->party.party_id,account_id,p->party.member[i].char_id);
+ return 1;
}
/// Party member 'sd' requesting exit from party.
int party_leave(struct map_session_data *sd)
{
- struct party_data *p;
- int i;
+ struct party_data *p;
+ int i;
- p = party_search(sd->status.party_id);
- if (p == NULL)
- return 0;
+ p = party_search(sd->status.party_id);
+ if( p == NULL )
+ return 0;
- ARR_FIND(0, MAX_PARTY, i, p->party.member[i].account_id == sd->status.account_id && p->party.member[i].char_id == sd->status.char_id);
- if (i == MAX_PARTY)
- return 0;
+ ARR_FIND( 0, MAX_PARTY, i, p->party.member[i].account_id == sd->status.account_id && p->party.member[i].char_id == sd->status.char_id );
+ if( i == MAX_PARTY )
+ return 0;
- intif_party_leave(p->party.party_id,sd->status.account_id,sd->status.char_id);
- return 1;
+ intif_party_leave(p->party.party_id,sd->status.account_id,sd->status.char_id);
+ return 1;
}
/// Invoked (from char-server) when a party member leaves the party.
int party_member_withdraw(int party_id, int account_id, int char_id)
{
- struct map_session_data *sd = map_id2sd(account_id);
- struct party_data *p = party_search(party_id);
-
- if (p) {
- int i;
- ARR_FIND(0, MAX_PARTY, i, p->party.member[i].account_id == account_id && p->party.member[i].char_id == char_id);
- if (i < MAX_PARTY) {
- clif_party_withdraw(p,sd,account_id,p->party.member[i].name,0x0);
- memset(&p->party.member[i], 0, sizeof(p->party.member[0]));
- memset(&p->data[i], 0, sizeof(p->data[0]));
- p->party.count--;
- party_check_state(p);
- }
- }
-
- if (sd && sd->status.party_id == party_id && sd->status.char_id == char_id) {
- sd->status.party_id = 0;
- clif_charnameupdate(sd); //Update name display [Skotlex]
- //TODO: hp bars should be cleared too
- if (p->instance_id)
- instance_check_kick(sd);
- }
-
- return 0;
+ struct map_session_data* sd = map_id2sd(account_id);
+ struct party_data* p = party_search(party_id);
+
+ if( p )
+ {
+ int i;
+ ARR_FIND( 0, MAX_PARTY, i, p->party.member[i].account_id == account_id && p->party.member[i].char_id == char_id );
+ if( i < MAX_PARTY )
+ {
+ clif_party_withdraw(p,sd,account_id,p->party.member[i].name,0x0);
+ memset(&p->party.member[i], 0, sizeof(p->party.member[0]));
+ memset(&p->data[i], 0, sizeof(p->data[0]));
+ p->party.count--;
+ party_check_state(p);
+ }
+ }
+
+ if( sd && sd->status.party_id == party_id && sd->status.char_id == char_id )
+ {
+ sd->status.party_id = 0;
+ clif_charnameupdate(sd); //Update name display [Skotlex]
+ //TODO: hp bars should be cleared too
+ if( p->instance_id )
+ instance_check_kick(sd);
+ }
+
+ return 0;
}
/// Invoked (from char-server) when a party is disbanded.
int party_broken(int party_id)
{
- struct party_data *p;
- int i;
-
- p = party_search(party_id);
- if (p == NULL)
- return 0;
-
- if (p->instance_id) {
- instance[p->instance_id].party_id = 0;
- instance_destroy(p->instance_id);
- }
-
- for (i = 0; i < MAX_PARTY; i++) {
- if (p->data[i].sd!=NULL) {
- clif_party_withdraw(p,p->data[i].sd,p->party.member[i].account_id,p->party.member[i].name,0x10);
- p->data[i].sd->status.party_id=0;
- }
- }
-
- idb_remove(party_db,party_id);
- return 0;
+ struct party_data* p;
+ int i;
+
+ p = party_search(party_id);
+ if( p == NULL )
+ return 0;
+
+ if( p->instance_id )
+ {
+ instance[p->instance_id].party_id = 0;
+ instance_destroy( p->instance_id );
+ }
+
+ for( i = 0; i < MAX_PARTY; i++ )
+ {
+ if( p->data[i].sd!=NULL )
+ {
+ clif_party_withdraw(p,p->data[i].sd,p->party.member[i].account_id,p->party.member[i].name,0x10);
+ p->data[i].sd->status.party_id=0;
+ }
+ }
+
+ idb_remove(party_db,party_id);
+ return 0;
}
int party_changeoption(struct map_session_data *sd,int exp,int item)
{
- nullpo_ret(sd);
+ nullpo_ret(sd);
- if (sd->status.party_id==0)
- return 0;
- intif_party_changeoption(sd->status.party_id,sd->status.account_id,exp,item);
- return 0;
+ if( sd->status.party_id==0)
+ return 0;
+ intif_party_changeoption(sd->status.party_id,sd->status.account_id,exp,item);
+ return 0;
}
int party_optionchanged(int party_id,int account_id,int exp,int item,int flag)
{
- struct party_data *p;
- struct map_session_data *sd=map_id2sd(account_id);
- if ((p=party_search(party_id))==NULL)
- return 0;
-
- //Flag&1: Exp change denied. Flag&2: Item change denied.
- if (!(flag&0x01) && p->party.exp != exp)
- p->party.exp=exp;
- if (!(flag&0x10) && p->party.item != item) {
- p->party.item=item;
- }
-
- clif_party_option(p,sd,flag);
- return 0;
+ struct party_data *p;
+ struct map_session_data *sd=map_id2sd(account_id);
+ if( (p=party_search(party_id))==NULL)
+ return 0;
+
+ //Flag&1: Exp change denied. Flag&2: Item change denied.
+ if(!(flag&0x01) && p->party.exp != exp)
+ p->party.exp=exp;
+ if(!(flag&0x10) && p->party.item != item) {
+ p->party.item=item;
+ }
+
+ clif_party_option(p,sd,flag);
+ return 0;
}
bool party_changeleader(struct map_session_data *sd, struct map_session_data *tsd)
{
- struct party_data *p;
- int mi, tmi;
-
- if (!sd || !sd->status.party_id)
- return false;
-
- if (!tsd || tsd->status.party_id != sd->status.party_id) {
- clif_displaymessage(sd->fd, msg_txt(283));
- return false;
- }
-
- if (map[sd->bl.m].flag.partylock) {
- clif_displaymessage(sd->fd, msg_txt(287));
- return false;
- }
-
- if ((p = party_search(sd->status.party_id)) == NULL)
- return false;
-
- ARR_FIND(0, MAX_PARTY, mi, p->data[mi].sd == sd);
- if (mi == MAX_PARTY)
- return false; //Shouldn't happen
-
- if (!p->party.member[mi].leader) {
- //Need to be a party leader.
- clif_displaymessage(sd->fd, msg_txt(282));
- return false;
- }
-
- ARR_FIND(0, MAX_PARTY, tmi, p->data[tmi].sd == tsd);
- if (tmi == MAX_PARTY)
- return false; //Shouldn't happen
-
- //Change leadership.
- p->party.member[mi].leader = 0;
- if (p->data[mi].sd->fd)
- clif_displaymessage(p->data[mi].sd->fd, msg_txt(284));
-
- p->party.member[tmi].leader = 1;
- if (p->data[tmi].sd->fd)
- clif_displaymessage(p->data[tmi].sd->fd, msg_txt(285));
-
- //Update info.
- intif_party_leaderchange(p->party.party_id,p->party.member[tmi].account_id,p->party.member[tmi].char_id);
- clif_party_info(p,NULL);
- return true;
+ struct party_data *p;
+ int mi, tmi;
+
+ if (!sd || !sd->status.party_id)
+ return false;
+
+ if (!tsd || tsd->status.party_id != sd->status.party_id) {
+ clif_displaymessage(sd->fd, msg_txt(283));
+ return false;
+ }
+
+ if( map[sd->bl.m].flag.partylock )
+ {
+ clif_displaymessage(sd->fd, msg_txt(287));
+ return false;
+ }
+
+ if ((p = party_search(sd->status.party_id)) == NULL)
+ return false;
+
+ ARR_FIND( 0, MAX_PARTY, mi, p->data[mi].sd == sd );
+ if (mi == MAX_PARTY)
+ return false; //Shouldn't happen
+
+ if (!p->party.member[mi].leader)
+ { //Need to be a party leader.
+ clif_displaymessage(sd->fd, msg_txt(282));
+ return false;
+ }
+
+ ARR_FIND( 0, MAX_PARTY, tmi, p->data[tmi].sd == tsd);
+ if (tmi == MAX_PARTY)
+ return false; //Shouldn't happen
+
+ //Change leadership.
+ p->party.member[mi].leader = 0;
+ if (p->data[mi].sd->fd)
+ clif_displaymessage(p->data[mi].sd->fd, msg_txt(284));
+
+ p->party.member[tmi].leader = 1;
+ if (p->data[tmi].sd->fd)
+ clif_displaymessage(p->data[tmi].sd->fd, msg_txt(285));
+
+ //Update info.
+ intif_party_leaderchange(p->party.party_id,p->party.member[tmi].account_id,p->party.member[tmi].char_id);
+ clif_party_info(p,NULL);
+ return true;
}
/// Invoked (from char-server) when a party member
@@ -667,331 +693,338 @@ bool party_changeleader(struct map_session_data *sd, struct map_session_data *ts
/// - gains a level (disabled)
int party_recv_movemap(int party_id,int account_id,int char_id, unsigned short map,int online,int lv)
{
- struct party_member *m;
- struct party_data *p;
- int i;
-
- p = party_search(party_id);
- if (p == NULL)
- return 0;
-
- ARR_FIND(0, MAX_PARTY, i, p->party.member[i].account_id == account_id && p->party.member[i].char_id == char_id);
- if (i == MAX_PARTY) {
- ShowError("party_recv_movemap: char %d/%d not found in party %s (id:%d)",account_id,char_id,p->party.name,party_id);
- return 0;
- }
-
- m = &p->party.member[i];
- m->map = map;
- m->online = online;
- m->lv = lv;
- //Check if they still exist on this map server
- p->data[i].sd = party_sd_check(party_id, account_id, char_id);
-
- clif_party_info(p,NULL);
- return 0;
+ struct party_member* m;
+ struct party_data* p;
+ int i;
+
+ p = party_search(party_id);
+ if( p == NULL )
+ return 0;
+
+ ARR_FIND( 0, MAX_PARTY, i, p->party.member[i].account_id == account_id && p->party.member[i].char_id == char_id );
+ if( i == MAX_PARTY )
+ {
+ ShowError("party_recv_movemap: char %d/%d not found in party %s (id:%d)",account_id,char_id,p->party.name,party_id);
+ return 0;
+ }
+
+ m = &p->party.member[i];
+ m->map = map;
+ m->online = online;
+ m->lv = lv;
+ //Check if they still exist on this map server
+ p->data[i].sd = party_sd_check(party_id, account_id, char_id);
+
+ clif_party_info(p,NULL);
+ return 0;
}
void party_send_movemap(struct map_session_data *sd)
{
- int i;
- struct party_data *p;
-
- if (sd->status.party_id==0)
- return;
-
- intif_party_changemap(sd,1);
-
- p=party_search(sd->status.party_id);
- if (!p) return;
-
- if (sd->state.connect_new) {
- //Note that this works because this function is invoked before connect_new is cleared.
- clif_party_option(p,sd,0x100);
- clif_party_info(p,sd);
- clif_party_member_info(p,sd);
- }
-
- if (sd->fd) { // synchronize minimap positions with the rest of the party
- for (i=0; i < MAX_PARTY; i++) {
- if (p->data[i].sd &&
- p->data[i].sd != sd &&
- p->data[i].sd->bl.m == sd->bl.m) {
- clif_party_xy_single(sd->fd, p->data[i].sd);
- clif_party_xy_single(p->data[i].sd->fd, sd);
- }
- }
- }
- return;
+ int i;
+ struct party_data *p;
+
+ if( sd->status.party_id==0 )
+ return;
+
+ intif_party_changemap(sd,1);
+
+ p=party_search(sd->status.party_id);
+ if (!p) return;
+
+ if(sd->state.connect_new) {
+ //Note that this works because this function is invoked before connect_new is cleared.
+ clif_party_option(p,sd,0x100);
+ clif_party_info(p,sd);
+ clif_party_member_info(p,sd);
+ }
+
+ if (sd->fd) { // synchronize minimap positions with the rest of the party
+ for(i=0; i < MAX_PARTY; i++) {
+ if (p->data[i].sd &&
+ p->data[i].sd != sd &&
+ p->data[i].sd->bl.m == sd->bl.m)
+ {
+ clif_party_xy_single(sd->fd, p->data[i].sd);
+ clif_party_xy_single(p->data[i].sd->fd, sd);
+ }
+ }
+ }
+ return;
}
void party_send_levelup(struct map_session_data *sd)
{
- intif_party_changemap(sd,1);
+ intif_party_changemap(sd,1);
}
int party_send_logout(struct map_session_data *sd)
{
- struct party_data *p;
- int i;
+ struct party_data *p;
+ int i;
- if (!sd->status.party_id)
- return 0;
+ if(!sd->status.party_id)
+ return 0;
- intif_party_changemap(sd,0);
- p=party_search(sd->status.party_id);
- if (!p) return 0;
+ intif_party_changemap(sd,0);
+ p=party_search(sd->status.party_id);
+ if(!p) return 0;
- ARR_FIND(0, MAX_PARTY, i, p->data[i].sd == sd);
- if (i < MAX_PARTY)
- memset(&p->data[i], 0, sizeof(p->data[0]));
- else
- ShowError("party_send_logout: Failed to locate member %d:%d in party %d!\n", sd->status.account_id, sd->status.char_id, p->party.party_id);
+ ARR_FIND( 0, MAX_PARTY, i, p->data[i].sd == sd );
+ if( i < MAX_PARTY )
+ memset(&p->data[i], 0, sizeof(p->data[0]));
+ else
+ ShowError("party_send_logout: Failed to locate member %d:%d in party %d!\n", sd->status.account_id, sd->status.char_id, p->party.party_id);
- return 1;
+ return 1;
}
int party_send_message(struct map_session_data *sd,const 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);
+ 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);
- // Chat logging type 'P' / Party Chat
- log_chat(LOG_CHAT_PARTY, sd->status.party_id, sd->status.char_id, sd->status.account_id, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y, NULL, mes);
+ // Chat logging type 'P' / Party Chat
+ log_chat(LOG_CHAT_PARTY, sd->status.party_id, sd->status.char_id, sd->status.account_id, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y, NULL, mes);
- return 0;
+ return 0;
}
int party_recv_message(int party_id,int account_id,const char *mes,int len)
{
- struct party_data *p;
- if ((p=party_search(party_id))==NULL)
- return 0;
- clif_party_message(p,account_id,mes,len);
- return 0;
+ struct party_data *p;
+ if( (p=party_search(party_id))==NULL)
+ return 0;
+ clif_party_message(p,account_id,mes,len);
+ return 0;
}
int party_skill_check(struct map_session_data *sd, int party_id, int skillid, int skilllv)
{
- struct party_data *p;
- struct map_session_data *p_sd;
- int i;
-
- if (!party_id || (p=party_search(party_id))==NULL)
- return 0;
- switch (skillid) {
- case TK_COUNTER: //Increase Triple Attack rate of Monks.
- if (!p->state.monk) return 0;
- break;
- case MO_COMBOFINISH: //Increase Counter rate of Star Gladiators
- if (!p->state.sg) return 0;
- break;
- case AM_TWILIGHT2: //Twilight Pharmacy, requires Super Novice
- return p->state.snovice;
- case AM_TWILIGHT3: //Twilight Pharmacy, Requires Taekwon
- return p->state.tk;
- default:
- return 0; //Unknown case?
- }
-
- for (i=0; i<MAX_PARTY; i++) {
- if ((p_sd = p->data[i].sd) == NULL)
- continue;
- if (sd->bl.m != p_sd->bl.m)
- continue;
- switch (skillid) {
- case TK_COUNTER: //Increase Triple Attack rate of Monks.
- if ((p_sd->class_&MAPID_UPPERMASK) == MAPID_MONK
- && pc_checkskill(p_sd,MO_TRIPLEATTACK)) {
- sc_start4(&p_sd->bl,SC_SKILLRATE_UP,100,MO_TRIPLEATTACK,
- 50+50*skilllv, //+100/150/200% rate
- 0,0,skill_get_time(SG_FRIEND, 1));
- }
- break;
- case MO_COMBOFINISH: //Increase Counter rate of Star Gladiators
- if ((p_sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR
- && sd->sc.data[SC_READYCOUNTER]
- && pc_checkskill(p_sd,SG_FRIEND)) {
- sc_start4(&p_sd->bl,SC_SKILLRATE_UP,100,TK_COUNTER,
- 50+50*pc_checkskill(p_sd,SG_FRIEND), //+100/150/200% rate
- 0,0,skill_get_time(SG_FRIEND, 1));
- }
- break;
- }
- }
- return 0;
+ struct party_data *p;
+ struct map_session_data *p_sd;
+ int i;
+
+ if(!party_id || (p=party_search(party_id))==NULL)
+ return 0;
+ switch(skillid) {
+ case TK_COUNTER: //Increase Triple Attack rate of Monks.
+ if (!p->state.monk) return 0;
+ break;
+ case MO_COMBOFINISH: //Increase Counter rate of Star Gladiators
+ if (!p->state.sg) return 0;
+ break;
+ case AM_TWILIGHT2: //Twilight Pharmacy, requires Super Novice
+ return p->state.snovice;
+ case AM_TWILIGHT3: //Twilight Pharmacy, Requires Taekwon
+ return p->state.tk;
+ default:
+ return 0; //Unknown case?
+ }
+
+ for(i=0;i<MAX_PARTY;i++){
+ if ((p_sd = p->data[i].sd) == NULL)
+ continue;
+ if (sd->bl.m != p_sd->bl.m)
+ continue;
+ switch(skillid) {
+ case TK_COUNTER: //Increase Triple Attack rate of Monks.
+ if((p_sd->class_&MAPID_UPPERMASK) == MAPID_MONK
+ && pc_checkskill(p_sd,MO_TRIPLEATTACK)) {
+ sc_start4(&p_sd->bl,SC_SKILLRATE_UP,100,MO_TRIPLEATTACK,
+ 50+50*skilllv, //+100/150/200% rate
+ 0,0,skill_get_time(SG_FRIEND, 1));
+ }
+ break;
+ case MO_COMBOFINISH: //Increase Counter rate of Star Gladiators
+ if((p_sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR
+ && sd->sc.data[SC_READYCOUNTER]
+ && pc_checkskill(p_sd,SG_FRIEND)) {
+ sc_start4(&p_sd->bl,SC_SKILLRATE_UP,100,TK_COUNTER,
+ 50+50*pc_checkskill(p_sd,SG_FRIEND), //+100/150/200% rate
+ 0,0,skill_get_time(SG_FRIEND, 1));
+ }
+ break;
+ }
+ }
+ return 0;
}
int party_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- struct party_data *p;
-
- DBIterator *iter = db_iterator(party_db);
- // for each existing party,
- for (p = dbi_first(iter); dbi_exists(iter); p = dbi_next(iter)) {
- int i;
-
- if (!p->party.count) {
- // no online party members so do not iterate
- continue;
- }
-
- // for each member of this party,
- for (i = 0; i < MAX_PARTY; i++) {
- struct map_session_data *sd = p->data[i].sd;
- if (!sd) continue;
-
- if (p->data[i].x != sd->bl.x || p->data[i].y != sd->bl.y) {
- // perform position update
- clif_party_xy(sd);
- p->data[i].x = sd->bl.x;
- p->data[i].y = sd->bl.y;
- }
- if (battle_config.party_hp_mode && p->data[i].hp != sd->battle_status.hp) {
- // perform hp update
- clif_party_hp(sd);
- p->data[i].hp = sd->battle_status.hp;
- }
- }
- }
- dbi_destroy(iter);
-
- return 0;
+ struct party_data* p;
+
+ DBIterator *iter = db_iterator(party_db);
+ // for each existing party,
+ for( p = dbi_first(iter); dbi_exists(iter); p = dbi_next(iter) )
+ {
+ int i;
+
+ if( !p->party.count )
+ {// no online party members so do not iterate
+ continue;
+ }
+
+ // for each member of this party,
+ for( i = 0; i < MAX_PARTY; i++ )
+ {
+ struct map_session_data* sd = p->data[i].sd;
+ if( !sd ) continue;
+
+ if( p->data[i].x != sd->bl.x || p->data[i].y != sd->bl.y )
+ {// perform position update
+ clif_party_xy(sd);
+ p->data[i].x = sd->bl.x;
+ p->data[i].y = sd->bl.y;
+ }
+ if (battle_config.party_hp_mode && p->data[i].hp != sd->battle_status.hp)
+ {// perform hp update
+ clif_party_hp(sd);
+ p->data[i].hp = sd->battle_status.hp;
+ }
+ }
+ }
+ dbi_destroy(iter);
+
+ return 0;
}
int party_send_xy_clear(struct party_data *p)
{
- int i;
+ int i;
- nullpo_ret(p);
+ nullpo_ret(p);
- for (i=0; i<MAX_PARTY; i++) {
- if (!p->data[i].sd) continue;
- p->data[i].hp = 0;
- p->data[i].x = 0;
- p->data[i].y = 0;
- }
- return 0;
+ for(i=0;i<MAX_PARTY;i++){
+ if(!p->data[i].sd) continue;
+ p->data[i].hp = 0;
+ p->data[i].x = 0;
+ p->data[i].y = 0;
+ }
+ return 0;
}
// exp share and added zeny share [Valaris]
-int party_exp_share(struct party_data *p, struct block_list *src, unsigned int base_exp, unsigned int job_exp, int zeny)
+int party_exp_share(struct party_data* p, struct block_list* src, unsigned int base_exp, unsigned int job_exp, int zeny)
{
- struct map_session_data *sd[MAX_PARTY];
- unsigned int i, c;
-
- nullpo_ret(p);
-
- // count the number of players eligible for exp sharing
- for (i = c = 0; i < MAX_PARTY; i++) {
- if ((sd[c] = p->data[i].sd) == NULL || sd[c]->bl.m != src->m || pc_isdead(sd[c]) || (battle_config.idle_no_share && pc_isidle(sd[c])))
- continue;
- c++;
- }
- if (c < 1)
- return 0;
-
- base_exp/=c;
- job_exp/=c;
- zeny/=c;
-
- if (battle_config.party_even_share_bonus && c > 1) {
- double bonus = 100 + battle_config.party_even_share_bonus*(c-1);
- if (base_exp)
- base_exp = (unsigned int) cap_value(base_exp * bonus/100, 0, UINT_MAX);
- if (job_exp)
- job_exp = (unsigned int) cap_value(job_exp * bonus/100, 0, UINT_MAX);
- if (zeny)
- zeny = (unsigned int) cap_value(zeny * bonus/100, INT_MIN, INT_MAX);
- }
-
- for (i = 0; i < c; i++) {
+ struct map_session_data* sd[MAX_PARTY];
+ unsigned int i, c;
+
+ nullpo_ret(p);
+
+ // count the number of players eligible for exp sharing
+ for (i = c = 0; i < MAX_PARTY; i++) {
+ if( (sd[c] = p->data[i].sd) == NULL || sd[c]->bl.m != src->m || pc_isdead(sd[c]) || (battle_config.idle_no_share && pc_isidle(sd[c])) )
+ continue;
+ c++;
+ }
+ if (c < 1)
+ return 0;
+
+ base_exp/=c;
+ job_exp/=c;
+ zeny/=c;
+
+ if (battle_config.party_even_share_bonus && c > 1)
+ {
+ double bonus = 100 + battle_config.party_even_share_bonus*(c-1);
+ if (base_exp)
+ base_exp = (unsigned int) cap_value(base_exp * bonus/100, 0, UINT_MAX);
+ if (job_exp)
+ job_exp = (unsigned int) cap_value(job_exp * bonus/100, 0, UINT_MAX);
+ if (zeny)
+ zeny = (unsigned int) cap_value(zeny * bonus/100, INT_MIN, INT_MAX);
+ }
+
+ for (i = 0; i < c; i++) {
#ifdef RENEWAL_EXP
- if (!(src && src->type == BL_MOB && ((TBL_MOB *)src)->db->mexp)) {
- int rate = pc_level_penalty_mod(sd[i], (TBL_MOB *)src, 1);
- base_exp = (unsigned int)cap_value(base_exp * rate / 100, 1, UINT_MAX);
- job_exp = (unsigned int)cap_value(job_exp * rate / 100, 1, UINT_MAX);
- }
+ if( !(src && src->type == BL_MOB && ((TBL_MOB*)src)->db->mexp) ){
+ int rate = pc_level_penalty_mod(sd[i], (TBL_MOB*)src, 1);
+ base_exp = (unsigned int)cap_value(base_exp * rate / 100, 1, UINT_MAX);
+ job_exp = (unsigned int)cap_value(job_exp * rate / 100, 1, UINT_MAX);
+ }
#endif
- pc_gainexp(sd[i], src, base_exp, job_exp, false);
+ pc_gainexp(sd[i], src, base_exp, job_exp, false);
- if (zeny) // zeny from mobs [Valaris]
- pc_getzeny(sd[i],zeny,LOG_TYPE_PICKDROP_MONSTER,NULL);
- }
- return 0;
+ if (zeny) // zeny from mobs [Valaris]
+ pc_getzeny(sd[i],zeny,LOG_TYPE_PICKDROP_MONSTER,NULL);
+ }
+ return 0;
}
//Does party loot. first_charid holds the charid of the player who has time priority to take the item.
-int party_share_loot(struct party_data *p, struct map_session_data *sd, struct item *item_data, int first_charid)
+int party_share_loot(struct party_data* p, struct map_session_data* sd, struct item* item_data, int first_charid)
{
- TBL_PC *target = NULL;
- int i;
- if (p && p->party.item&2 && (first_charid || !(battle_config.party_share_type&1))) {
- //item distribution to party members.
- if (battle_config.party_share_type&2) {
- //Round Robin
- TBL_PC *psd;
- i = p->itemc;
- do {
- i++;
- if (i >= MAX_PARTY)
- i = 0; // reset counter to 1st person in party so it'll stop when it reaches "itemc"
-
- if ((psd = p->data[i].sd) == NULL || sd->bl.m != psd->bl.m || pc_isdead(psd) || (battle_config.idle_no_share && pc_isidle(psd)))
- continue;
-
- if (pc_additem(psd,item_data,item_data->amount,LOG_TYPE_PICKDROP_PLAYER))
- continue; //Chosen char can't pick up loot.
-
- //Successful pick.
- p->itemc = i;
- target = psd;
- break;
- } while (i != p->itemc);
- } else {
- //Random pick
- TBL_PC *psd[MAX_PARTY];
- int count = 0;
- //Collect pick candidates
- for (i = 0; i < MAX_PARTY; i++) {
- if ((psd[count] = p->data[i].sd) == NULL || psd[count]->bl.m != sd->bl.m || pc_isdead(psd[count]) || (battle_config.idle_no_share && pc_isidle(psd[count])))
- continue;
-
- count++;
- }
- while (count > 0) { //Pick a random member.
- i = rnd()%count;
- if (pc_additem(psd[i],item_data,item_data->amount,LOG_TYPE_PICKDROP_PLAYER)) {
- //Discard this receiver.
- psd[i] = psd[count-1];
- count--;
- } else { //Successful pick.
- target = psd[i];
- break;
- }
- }
- }
- }
-
- if (!target) {
- target = sd; //Give it to the char that picked it up
- if ((i=pc_additem(sd,item_data,item_data->amount,LOG_TYPE_PICKDROP_PLAYER)))
- return i;
- }
-
- if (p && battle_config.party_show_share_picker && battle_config.show_picker_item_type&(1<<itemdb_type(item_data->nameid)))
- clif_party_show_picker(target, item_data);
-
- return 0;
+ TBL_PC* target = NULL;
+ int i;
+ if (p && p->party.item&2 && (first_charid || !(battle_config.party_share_type&1)))
+ {
+ //item distribution to party members.
+ if (battle_config.party_share_type&2)
+ { //Round Robin
+ TBL_PC* psd;
+ i = p->itemc;
+ do {
+ i++;
+ if (i >= MAX_PARTY)
+ i = 0; // reset counter to 1st person in party so it'll stop when it reaches "itemc"
+
+ if( (psd = p->data[i].sd) == NULL || sd->bl.m != psd->bl.m || pc_isdead(psd) || (battle_config.idle_no_share && pc_isidle(psd)) )
+ continue;
+
+ if (pc_additem(psd,item_data,item_data->amount,LOG_TYPE_PICKDROP_PLAYER))
+ continue; //Chosen char can't pick up loot.
+
+ //Successful pick.
+ p->itemc = i;
+ target = psd;
+ break;
+ } while (i != p->itemc);
+ }
+ else
+ { //Random pick
+ TBL_PC* psd[MAX_PARTY];
+ int count = 0;
+ //Collect pick candidates
+ for (i = 0; i < MAX_PARTY; i++) {
+ if( (psd[count] = p->data[i].sd) == NULL || psd[count]->bl.m != sd->bl.m || pc_isdead(psd[count]) || (battle_config.idle_no_share && pc_isidle(psd[count])) )
+ continue;
+
+ count++;
+ }
+ while (count > 0) { //Pick a random member.
+ i = rnd()%count;
+ if (pc_additem(psd[i],item_data,item_data->amount,LOG_TYPE_PICKDROP_PLAYER))
+ { //Discard this receiver.
+ psd[i] = psd[count-1];
+ count--;
+ } else { //Successful pick.
+ target = psd[i];
+ break;
+ }
+ }
+ }
+ }
+
+ if (!target) {
+ target = sd; //Give it to the char that picked it up
+ if ((i=pc_additem(sd,item_data,item_data->amount,LOG_TYPE_PICKDROP_PLAYER)))
+ return i;
+ }
+
+ if( p && battle_config.party_show_share_picker && battle_config.show_picker_item_type&(1<<itemdb_type(item_data->nameid)) )
+ clif_party_show_picker(target, item_data);
+
+ return 0;
}
int party_send_dot_remove(struct map_session_data *sd)
{
- if (sd->status.party_id)
- clif_party_xy_remove(sd);
- return 0;
+ if (sd->status.party_id)
+ clif_party_xy_remove(sd);
+ return 0;
}
// To use for Taekwon's "Fighting Chant"
@@ -999,166 +1032,174 @@ int party_send_dot_remove(struct map_session_data *sd)
// party_foreachsamemap(party_sub_count, sd, 0, &c);
int party_sub_count(struct block_list *bl, va_list ap)
{
- struct map_session_data *sd = (TBL_PC *)bl;
+ struct map_session_data *sd = (TBL_PC *)bl;
- if (sd->state.autotrade)
- return 0;
+ if (sd->state.autotrade)
+ return 0;
- if (battle_config.idle_no_share && pc_isidle(sd))
- return 0;
+ if (battle_config.idle_no_share && pc_isidle(sd))
+ return 0;
- return 1;
+ return 1;
}
/// Executes 'func' for each party member on the same map and in range (0:whole map)
-int party_foreachsamemap(int (*func)(struct block_list *,va_list),struct map_session_data *sd,int range,...)
+int party_foreachsamemap(int (*func)(struct block_list*,va_list),struct map_session_data *sd,int range,...)
{
- struct party_data *p;
- int i;
- int x0,y0,x1,y1;
- struct block_list *list[MAX_PARTY];
- int blockcount=0;
- int total = 0; //Return value.
-
- nullpo_ret(sd);
-
- if ((p=party_search(sd->status.party_id))==NULL)
- return 0;
-
- x0=sd->bl.x-range;
- y0=sd->bl.y-range;
- x1=sd->bl.x+range;
- y1=sd->bl.y+range;
-
- for (i=0; i<MAX_PARTY; i++) {
- struct map_session_data *psd = p->data[i].sd;
- if (!psd) continue;
- if (psd->bl.m!=sd->bl.m || !psd->bl.prev)
- continue;
- if (range &&
- (psd->bl.x<x0 || psd->bl.y<y0 ||
- psd->bl.x>x1 || psd->bl.y>y1))
- continue;
- list[blockcount++]=&psd->bl;
- }
-
- map_freeblock_lock();
-
- for (i=0; i<blockcount; i++) {
- va_list ap;
- va_start(ap, range);
- total += func(list[i], ap);
- va_end(ap);
- }
-
- map_freeblock_unlock();
-
- return total;
+ struct party_data *p;
+ int i;
+ int x0,y0,x1,y1;
+ struct block_list *list[MAX_PARTY];
+ int blockcount=0;
+ int total = 0; //Return value.
+
+ nullpo_ret(sd);
+
+ if((p=party_search(sd->status.party_id))==NULL)
+ return 0;
+
+ x0=sd->bl.x-range;
+ y0=sd->bl.y-range;
+ x1=sd->bl.x+range;
+ y1=sd->bl.y+range;
+
+ for(i=0;i<MAX_PARTY;i++)
+ {
+ struct map_session_data *psd = p->data[i].sd;
+ if(!psd) continue;
+ if(psd->bl.m!=sd->bl.m || !psd->bl.prev)
+ continue;
+ if(range &&
+ (psd->bl.x<x0 || psd->bl.y<y0 ||
+ psd->bl.x>x1 || psd->bl.y>y1 ) )
+ continue;
+ list[blockcount++]=&psd->bl;
+ }
+
+ map_freeblock_lock();
+
+ for(i=0;i<blockcount;i++)
+ {
+ va_list ap;
+ va_start(ap, range);
+ total += func(list[i], ap);
+ va_end(ap);
+ }
+
+ map_freeblock_unlock();
+
+ return total;
}
/*==========================================
* Party Booking in KRO [Spiria]
*------------------------------------------*/
-static struct party_booking_ad_info *create_party_booking_data(void) {
- struct party_booking_ad_info *pb_ad;
- CREATE(pb_ad, struct party_booking_ad_info, 1);
- pb_ad->index = party_booking_nextid++;
- return pb_ad;
+static struct party_booking_ad_info* create_party_booking_data(void)
+{
+ struct party_booking_ad_info *pb_ad;
+ CREATE(pb_ad, struct party_booking_ad_info, 1);
+ pb_ad->index = party_booking_nextid++;
+ return pb_ad;
}
-void party_booking_register(struct map_session_data *sd, short level, short mapid, short *job)
+void party_booking_register(struct map_session_data *sd, short level, short mapid, short* job)
{
- struct party_booking_ad_info *pb_ad;
- int i;
-
- pb_ad = (struct party_booking_ad_info *)idb_get(party_booking_db, sd->status.char_id);
-
- if (pb_ad == NULL) {
- pb_ad = create_party_booking_data();
- idb_put(party_booking_db, sd->status.char_id, pb_ad);
- } else {
- // already registered
- clif_PartyBookingRegisterAck(sd, 2);
- return;
- }
-
- memcpy(pb_ad->charname,sd->status.name,NAME_LENGTH);
- pb_ad->starttime = (int)time(NULL);
- pb_ad->p_detail.level = level;
- pb_ad->p_detail.mapid = mapid;
-
- for (i=0; i<PARTY_BOOKING_JOBS; i++)
- if (job[i] != 0xFF)
- pb_ad->p_detail.job[i] = job[i];
- else pb_ad->p_detail.job[i] = -1;
-
- clif_PartyBookingRegisterAck(sd, 0);
- clif_PartyBookingInsertNotify(sd, pb_ad); // Notice
+ struct party_booking_ad_info *pb_ad;
+ int i;
+
+ pb_ad = (struct party_booking_ad_info*)idb_get(party_booking_db, sd->status.char_id);
+
+ if( pb_ad == NULL )
+ {
+ pb_ad = create_party_booking_data();
+ idb_put(party_booking_db, sd->status.char_id, pb_ad);
+ }
+ else
+ {// already registered
+ clif_PartyBookingRegisterAck(sd, 2);
+ return;
+ }
+
+ memcpy(pb_ad->charname,sd->status.name,NAME_LENGTH);
+ pb_ad->starttime = (int)time(NULL);
+ pb_ad->p_detail.level = level;
+ pb_ad->p_detail.mapid = mapid;
+
+ for(i=0;i<PARTY_BOOKING_JOBS;i++)
+ if(job[i] != 0xFF)
+ pb_ad->p_detail.job[i] = job[i];
+ else pb_ad->p_detail.job[i] = -1;
+
+ clif_PartyBookingRegisterAck(sd, 0);
+ clif_PartyBookingInsertNotify(sd, pb_ad); // Notice
}
-void party_booking_update(struct map_session_data *sd, short *job)
+void party_booking_update(struct map_session_data *sd, short* job)
{
- int i;
- struct party_booking_ad_info *pb_ad;
+ int i;
+ struct party_booking_ad_info *pb_ad;
- pb_ad = (struct party_booking_ad_info *)idb_get(party_booking_db, sd->status.char_id);
+ pb_ad = (struct party_booking_ad_info*)idb_get(party_booking_db, sd->status.char_id);
- if (pb_ad == NULL)
- return;
+ if( pb_ad == NULL )
+ return;
- pb_ad->starttime = (int)time(NULL);// Update time.
+ pb_ad->starttime = (int)time(NULL);// Update time.
- for (i=0; i<PARTY_BOOKING_JOBS; i++)
- if (job[i] != 0xFF)
- pb_ad->p_detail.job[i] = job[i];
- else pb_ad->p_detail.job[i] = -1;
+ for(i=0;i<PARTY_BOOKING_JOBS;i++)
+ if(job[i] != 0xFF)
+ pb_ad->p_detail.job[i] = job[i];
+ else pb_ad->p_detail.job[i] = -1;
- clif_PartyBookingUpdateNotify(sd, pb_ad);
+ clif_PartyBookingUpdateNotify(sd, pb_ad);
}
void party_booking_search(struct map_session_data *sd, short level, short mapid, short job, unsigned long lastindex, short resultcount)
{
- struct party_booking_ad_info *pb_ad;
- int i, count=0;
- struct party_booking_ad_info *result_list[PARTY_BOOKING_RESULTS];
- bool more_result = false;
- DBIterator *iter = db_iterator(party_booking_db);
-
- memset(result_list, 0, sizeof(result_list));
-
- for (pb_ad = dbi_first(iter); dbi_exists(iter); pb_ad = dbi_next(iter)) {
- if (pb_ad->index < lastindex || (level && (pb_ad->p_detail.level < level-15 || pb_ad->p_detail.level > level)))
- continue;
- if (count >= PARTY_BOOKING_RESULTS) {
- more_result = true;
- break;
- }
- if (mapid == 0 && job == -1)
- result_list[count] = pb_ad;
- else if (mapid == 0) {
- for (i=0; i<PARTY_BOOKING_JOBS; i++)
- if (pb_ad->p_detail.job[i] == job && job != -1)
- result_list[count] = pb_ad;
- } else if (job == -1) {
- if (pb_ad->p_detail.mapid == mapid)
- result_list[count] = pb_ad;
- }
- if (result_list[count]) {
- count++;
- }
- }
- dbi_destroy(iter);
- clif_PartyBookingSearchAck(sd->fd, result_list, count, more_result);
+ struct party_booking_ad_info *pb_ad;
+ int i, count=0;
+ struct party_booking_ad_info* result_list[PARTY_BOOKING_RESULTS];
+ bool more_result = false;
+ DBIterator* iter = db_iterator(party_booking_db);
+
+ memset(result_list, 0, sizeof(result_list));
+
+ for( pb_ad = dbi_first(iter); dbi_exists(iter); pb_ad = dbi_next(iter) )
+ {
+ if (pb_ad->index < lastindex || (level && (pb_ad->p_detail.level < level-15 || pb_ad->p_detail.level > level)))
+ continue;
+ if (count >= PARTY_BOOKING_RESULTS){
+ more_result = true;
+ break;
+ }
+ if (mapid == 0 && job == -1)
+ result_list[count] = pb_ad;
+ else if (mapid == 0) {
+ for(i=0; i<PARTY_BOOKING_JOBS; i++)
+ if (pb_ad->p_detail.job[i] == job && job != -1)
+ result_list[count] = pb_ad;
+ } else if (job == -1){
+ if (pb_ad->p_detail.mapid == mapid)
+ result_list[count] = pb_ad;
+ }
+ if( result_list[count] )
+ {
+ count++;
+ }
+ }
+ dbi_destroy(iter);
+ clif_PartyBookingSearchAck(sd->fd, result_list, count, more_result);
}
bool party_booking_delete(struct map_session_data *sd)
{
- struct party_booking_ad_info *pb_ad;
-
- if ((pb_ad = (struct party_booking_ad_info *)idb_get(party_booking_db, sd->status.char_id))!=NULL) {
- clif_PartyBookingDeleteNotify(sd, pb_ad->index);
- idb_remove(party_booking_db,sd->status.char_id);
- }
- return true;
+ struct party_booking_ad_info* pb_ad;
+
+ if((pb_ad = (struct party_booking_ad_info*)idb_get(party_booking_db, sd->status.char_id))!=NULL)
+ {
+ clif_PartyBookingDeleteNotify(sd, pb_ad->index);
+ idb_remove(party_booking_db,sd->status.char_id);
+ }
+ return true;
}
diff --git a/src/map/party.h b/src/map/party.h
index 49f6513e9..9fde5a6a4 100644
--- a/src/map/party.h
+++ b/src/map/party.h
@@ -16,43 +16,43 @@ struct item;
#define PARTY_BOOKING_RESULTS 10
struct party_member_data {
- struct map_session_data *sd;
- unsigned int hp; //For HP,x,y refreshing.
- unsigned short x, y;
+ struct map_session_data *sd;
+ unsigned int hp; //For HP,x,y refreshing.
+ unsigned short x, y;
};
struct party_data {
- struct party party;
- struct party_member_data data[MAX_PARTY];
- uint8 itemc; //For item distribution, position of last picker in party
- unsigned int instance_id;
- struct {
- unsigned monk : 1; //There's at least one monk in party?
- unsigned sg : 1; //There's at least one Star Gladiator in party?
- unsigned snovice :1; //There's a Super Novice
- unsigned tk : 1; //There's a taekwon
- } state;
+ struct party party;
+ struct party_member_data data[MAX_PARTY];
+ uint8 itemc; //For item distribution, position of last picker in party
+ unsigned int instance_id;
+ struct {
+ unsigned monk : 1; //There's at least one monk in party?
+ unsigned sg : 1; //There's at least one Star Gladiator in party?
+ unsigned snovice :1; //There's a Super Novice
+ unsigned tk : 1; //There's a taekwon
+ } state;
};
struct party_booking_detail {
- short level;
+ short level;
short mapid;
short job[PARTY_BOOKING_JOBS];
};
struct party_booking_ad_info {
- unsigned long index;
- char charname[NAME_LENGTH];
- long starttime;
- struct party_booking_detail p_detail;
+ unsigned long index;
+ char charname[NAME_LENGTH];
+ long starttime;
+ struct party_booking_detail p_detail;
};
void do_init_party(void);
void do_final_party(void);
-struct party_data *party_search(int party_id);
-struct party_data *party_searchname(const char *str);
-int party_getmemberid(struct party_data *p, struct map_session_data *sd);
-struct map_session_data *party_getavailablesd(struct party_data *p);
+struct party_data* party_search(int party_id);
+struct party_data* party_searchname(const char* str);
+int party_getmemberid(struct party_data* p, struct map_session_data* sd);
+struct map_session_data* party_getavailablesd(struct party_data *p);
int party_create(struct map_session_data *sd,char *name, int item, int item2);
void party_created(int account_id,int char_id,int fail,int party_id,char *name);
@@ -65,7 +65,7 @@ int party_removemember(struct map_session_data *sd,int account_id,char *name);
int party_member_withdraw(int party_id,int account_id,int char_id);
void party_reply_invite(struct map_session_data *sd,int party_id,int flag);
int party_recv_noinfo(int party_id, int char_id);
-int party_recv_info(struct party *sp, int char_id);
+int party_recv_info(struct party* sp, int char_id);
int party_recv_movemap(int party_id,int account_id,int char_id, unsigned short map,int online,int lv);
int party_broken(int party_id);
int party_optionchanged(int party_id,int account_id,int exp,int item,int flag);
@@ -79,7 +79,7 @@ int party_recv_message(int party_id,int account_id,const char *mes,int len);
int party_skill_check(struct map_session_data *sd, int party_id, int skillid, int skilllv);
int party_send_xy_clear(struct party_data *p);
int party_exp_share(struct party_data *p,struct block_list *src,unsigned int base_exp,unsigned int job_exp,int zeny);
-int party_share_loot(struct party_data *p, struct map_session_data *sd, struct item *item_data, int first_charid);
+int party_share_loot(struct party_data* p, struct map_session_data* sd, struct item* item_data, int first_charid);
int party_send_dot_remove(struct map_session_data *sd);
int party_sub_count(struct block_list *bl, va_list ap);
int party_foreachsamemap(int (*func)(struct block_list *,va_list),struct map_session_data *sd,int range,...);
@@ -87,8 +87,8 @@ int party_foreachsamemap(int (*func)(struct block_list *,va_list),struct map_ses
/*==========================================
* Party Booking in KRO [Spiria]
*------------------------------------------*/
-void party_booking_register(struct map_session_data *sd, short level, short mapid, short *job);
-void party_booking_update(struct map_session_data *sd, short *job);
+void party_booking_register(struct map_session_data *sd, short level, short mapid, short* job);
+void party_booking_update(struct map_session_data *sd, short* job);
void party_booking_search(struct map_session_data *sd, short level, short mapid, short job, unsigned long lastindex, short resultcount);
bool party_booking_delete(struct map_session_data *sd);
diff --git a/src/map/path.c b/src/map/path.c
index 4ccb73519..4505efcaa 100644
--- a/src/map/path.c
+++ b/src/map/path.c
@@ -17,15 +17,14 @@
#define MAX_HEAP 150
-struct tmp_path {
- short x,y,dist,before,cost,flag;
-};
+struct tmp_path { short x,y,dist,before,cost,flag;};
#define calc_index(x,y) (((x)+(y)*MAX_WALKPATH) & (MAX_WALKPATH*MAX_WALKPATH-1))
-const char walk_choices [3][3] = {
- {1,0,7},
- {2,-1,6},
- {3,4,5},
+const char walk_choices [3][3] =
+{
+ {1,0,7},
+ {2,-1,6},
+ {3,4,5},
};
/*==========================================
@@ -33,15 +32,15 @@ const char walk_choices [3][3] = {
*------------------------------------------*/
static void push_heap_path(int *heap,struct tmp_path *tp,int index)
{
- int i,h;
+ int i,h;
- h = heap[0];
- heap[0]++;
+ h = heap[0];
+ heap[0]++;
- for (i = (h-1)/2; h > 0 && tp[index].cost < tp[heap[i+1]].cost; i = (h-1)/2)
- heap[h+1] = heap[i+1], h = i;
+ for( i = (h-1)/2; h > 0 && tp[index].cost < tp[heap[i+1]].cost; i = (h-1)/2 )
+ heap[h+1] = heap[i+1], h = i;
- heap[h+1] = index;
+ heap[h+1] = index;
}
/*==========================================
@@ -50,18 +49,19 @@ static void push_heap_path(int *heap,struct tmp_path *tp,int index)
*------------------------------------------*/
static void update_heap_path(int *heap,struct tmp_path *tp,int index)
{
- int i,h;
+ int i,h;
- ARR_FIND(0, heap[0], h, heap[h+1] == index);
- if (h == heap[0]) {
- ShowError("update_heap_path bug\n");
- exit(EXIT_FAILURE);
- }
+ ARR_FIND( 0, heap[0], h, heap[h+1] == index );
+ if( h == heap[0] )
+ {
+ ShowError("update_heap_path bug\n");
+ exit(EXIT_FAILURE);
+ }
- for (i = (h-1)/2; h > 0 && tp[index].cost < tp[heap[i+1]].cost; i = (h-1)/2)
- heap[h+1] = heap[i+1], h = i;
+ for( i = (h-1)/2; h > 0 && tp[index].cost < tp[heap[i+1]].cost; i = (h-1)/2 )
+ heap[h+1] = heap[i+1], h = i;
- heap[h+1] = index;
+ heap[h+1] = index;
}
/*==========================================
@@ -69,30 +69,31 @@ static void update_heap_path(int *heap,struct tmp_path *tp,int index)
*------------------------------------------*/
static int pop_heap_path(int *heap,struct tmp_path *tp)
{
- int i,h,k;
- int ret,last;
+ int i,h,k;
+ int ret,last;
- if (heap[0] <= 0)
- return -1;
- ret = heap[1];
- last = heap[heap[0]];
- heap[0]--;
+ if( heap[0] <= 0 )
+ return -1;
+ ret = heap[1];
+ last = heap[heap[0]];
+ heap[0]--;
- for (h = 0, k = 2; k < heap[0]; k = k*2+2) {
- if (tp[heap[k+1]].cost > tp[heap[k]].cost)
- k--;
- heap[h+1] = heap[k+1], h = k;
- }
+ for( h = 0, k = 2; k < heap[0]; k = k*2+2 )
+ {
+ if( tp[heap[k+1]].cost > tp[heap[k]].cost )
+ k--;
+ heap[h+1] = heap[k+1], h = k;
+ }
- if (k == heap[0])
- heap[h+1] = heap[k], h = k-1;
+ if( k == heap[0] )
+ heap[h+1] = heap[k], h = k-1;
- for (i = (h-1)/2; h > 0 && tp[heap[i+1]].cost > tp[last].cost; i = (h-1)/2)
- heap[h+1] = heap[i+1], h = i;
+ for( i = (h-1)/2; h > 0 && tp[heap[i+1]].cost > tp[last].cost; i = (h-1)/2 )
+ heap[h+1] = heap[i+1], h = i;
- heap[h+1]=last;
+ heap[h+1]=last;
- return ret;
+ return ret;
}
/*==========================================
@@ -100,9 +101,9 @@ static int pop_heap_path(int *heap,struct tmp_path *tp)
*------------------------------------------*/
static int calc_cost(struct tmp_path *p,int x1,int y1)
{
- int xd = abs(x1 - p->x);
- int yd = abs(y1 - p->y);
- return (xd + yd)*10 + p->dist;
+ int xd = abs(x1 - p->x);
+ int yd = abs(y1 - p->y);
+ return (xd + yd)*10 + p->dist;
}
/*==========================================
@@ -110,36 +111,38 @@ static int calc_cost(struct tmp_path *p,int x1,int y1)
*------------------------------------------*/
static int add_path(int *heap,struct tmp_path *tp,int x,int y,int dist,int before,int cost)
{
- int i;
-
- i = calc_index(x,y);
-
- if (tp[i].x == x && tp[i].y == y) {
- if (tp[i].dist > dist) {
- tp[i].dist = dist;
- tp[i].before = before;
- tp[i].cost = cost;
- if (tp[i].flag)
- push_heap_path(heap,tp,i);
- else
- update_heap_path(heap,tp,i);
- tp[i].flag = 0;
- }
- return 0;
- }
-
- if (tp[i].x || tp[i].y)
- return 1;
-
- tp[i].x = x;
- tp[i].y = y;
- tp[i].dist = dist;
- tp[i].before = before;
- tp[i].cost = cost;
- tp[i].flag = 0;
- push_heap_path(heap,tp,i);
-
- return 0;
+ int i;
+
+ i = calc_index(x,y);
+
+ if( tp[i].x == x && tp[i].y == y )
+ {
+ if( tp[i].dist > dist )
+ {
+ tp[i].dist = dist;
+ tp[i].before = before;
+ tp[i].cost = cost;
+ if( tp[i].flag )
+ push_heap_path(heap,tp,i);
+ else
+ update_heap_path(heap,tp,i);
+ tp[i].flag = 0;
+ }
+ return 0;
+ }
+
+ if( tp[i].x || tp[i].y )
+ return 1;
+
+ tp[i].x = x;
+ tp[i].y = y;
+ tp[i].dist = dist;
+ tp[i].before = before;
+ tp[i].cost = cost;
+ tp[i].flag = 0;
+ push_heap_path(heap,tp,i);
+
+ return 0;
}
/*==========================================
@@ -148,45 +151,47 @@ static int add_path(int *heap,struct tmp_path *tp,int x,int y,int dist,int befor
*------------------------------------------*/
int path_blownpos(int m,int x0,int y0,int dx,int dy,int count)
{
- struct map_data *md;
-
- if (!map[m].cell)
- return -1;
- md = &map[m];
-
- if (count>25) { //Cap to prevent too much processing...?
- ShowWarning("path_blownpos: count too many %d !\n",count);
- count=25;
- }
- if (dx > 1 || dx < -1 || dy > 1 || dy < -1) {
- ShowError("path_blownpos: illegal dx=%d or dy=%d !\n",dx,dy);
- dx=(dx>0)?1:((dx<0)?-1:0);
- dy=(dy>0)?1:((dy<0)?-1:0);
- }
-
- while (count > 0 && (dx != 0 || dy != 0)) {
- if (!map_getcellp(md,x0+dx,y0+dy,CELL_CHKPASS)) {
- // attempt partial movement
- int fx = (dx != 0 && map_getcellp(md,x0+dx,y0,CELL_CHKPASS));
- int fy = (dy != 0 && map_getcellp(md,x0,y0+dy,CELL_CHKPASS));
- if (fx && fy) {
- if (rnd()&1)
- dx=0;
- else
- dy=0;
- }
- if (!fx)
- dx=0;
- if (!fy)
- dy=0;
- }
-
- x0 += dx;
- y0 += dy;
- count--;
- }
-
- return (x0<<16)|y0; //TODO: use 'struct point' here instead?
+ struct map_data *md;
+
+ if( !map[m].cell )
+ return -1;
+ md = &map[m];
+
+ if( count>25 ){ //Cap to prevent too much processing...?
+ ShowWarning("path_blownpos: count too many %d !\n",count);
+ count=25;
+ }
+ if( dx > 1 || dx < -1 || dy > 1 || dy < -1 ){
+ ShowError("path_blownpos: illegal dx=%d or dy=%d !\n",dx,dy);
+ dx=(dx>0)?1:((dx<0)?-1:0);
+ dy=(dy>0)?1:((dy<0)?-1:0);
+ }
+
+ while( count > 0 && (dx != 0 || dy != 0) )
+ {
+ if( !map_getcellp(md,x0+dx,y0+dy,CELL_CHKPASS) )
+ {// attempt partial movement
+ int fx = ( dx != 0 && map_getcellp(md,x0+dx,y0,CELL_CHKPASS) );
+ int fy = ( dy != 0 && map_getcellp(md,x0,y0+dy,CELL_CHKPASS) );
+ if( fx && fy )
+ {
+ if(rnd()&1)
+ dx=0;
+ else
+ dy=0;
+ }
+ if( !fx )
+ dx=0;
+ if( !fy )
+ dy=0;
+ }
+
+ x0 += dx;
+ y0 += dy;
+ count--;
+ }
+
+ return (x0<<16)|y0; //TODO: use 'struct point' here instead?
}
/*==========================================
@@ -194,67 +199,69 @@ int path_blownpos(int m,int x0,int y0,int dx,int dy,int count)
*------------------------------------------*/
bool path_search_long(struct shootpath_data *spd,int m,int x0,int y0,int x1,int y1,cell_chk cell)
{
- int dx, dy;
- int wx = 0, wy = 0;
- int weight;
- struct map_data *md;
- struct shootpath_data s_spd;
-
- if (spd == NULL)
- spd = &s_spd; // use dummy output variable
-
- if (!map[m].cell)
- return false;
- md = &map[m];
-
- dx = (x1 - x0);
- if (dx < 0) {
- swap(x0, x1);
- swap(y0, y1);
- dx = -dx;
- }
- dy = (y1 - y0);
-
- spd->rx = spd->ry = 0;
- spd->len = 1;
- spd->x[0] = x0;
- spd->y[0] = y0;
-
- if (map_getcellp(md,x1,y1,cell))
- return false;
-
- if (dx > abs(dy)) {
- weight = dx;
- spd->ry = 1;
- } else {
- weight = abs(y1 - y0);
- spd->rx = 1;
- }
-
- while (x0 != x1 || y0 != y1) {
- if (map_getcellp(md,x0,y0,cell))
- return false;
- 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->len<MAX_WALKPATH) {
- spd->x[spd->len] = x0;
- spd->y[spd->len] = y0;
- spd->len++;
- }
- }
-
- return true;
+ int dx, dy;
+ int wx = 0, wy = 0;
+ int weight;
+ struct map_data *md;
+ struct shootpath_data s_spd;
+
+ if( spd == NULL )
+ spd = &s_spd; // use dummy output variable
+
+ if (!map[m].cell)
+ return false;
+ md = &map[m];
+
+ dx = (x1 - x0);
+ if (dx < 0) {
+ swap(x0, x1);
+ swap(y0, y1);
+ dx = -dx;
+ }
+ dy = (y1 - y0);
+
+ spd->rx = spd->ry = 0;
+ spd->len = 1;
+ spd->x[0] = x0;
+ spd->y[0] = y0;
+
+ if (map_getcellp(md,x1,y1,cell))
+ return false;
+
+ if (dx > abs(dy)) {
+ weight = dx;
+ spd->ry = 1;
+ } else {
+ weight = abs(y1 - y0);
+ spd->rx = 1;
+ }
+
+ while (x0 != x1 || y0 != y1)
+ {
+ if (map_getcellp(md,x0,y0,cell))
+ return false;
+ 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->len<MAX_WALKPATH )
+ {
+ spd->x[spd->len] = x0;
+ spd->y[spd->len] = y0;
+ spd->len++;
+ }
+ }
+
+ return true;
}
/*==========================================
@@ -265,154 +272,152 @@ bool path_search_long(struct shootpath_data *spd,int m,int x0,int y0,int x1,int
*------------------------------------------*/
bool path_search(struct walkpath_data *wpd,int m,int x0,int y0,int x1,int y1,int flag,cell_chk cell)
{
- int heap[MAX_HEAP+1];
- struct tmp_path tp[MAX_WALKPATH*MAX_WALKPATH];
- register int i,j,len,x,y,dx,dy;
- int rp,xs,ys;
- struct map_data *md;
- struct walkpath_data s_wpd;
+ int heap[MAX_HEAP+1];
+ struct tmp_path tp[MAX_WALKPATH*MAX_WALKPATH];
+ register int i,j,len,x,y,dx,dy;
+ int rp,xs,ys;
+ struct map_data *md;
+ struct walkpath_data s_wpd;
- if (wpd == NULL)
- wpd = &s_wpd; // use dummy output variable
+ if( wpd == NULL )
+ wpd = &s_wpd; // use dummy output variable
- if (!map[m].cell)
- return false;
- md = &map[m];
+ if( !map[m].cell )
+ return false;
+ md = &map[m];
#ifdef CELL_NOSTACK
- //Do not check starting cell as that would get you stuck.
- if (x0 < 0 || x0 >= md->xs || y0 < 0 || y0 >= md->ys)
+ //Do not check starting cell as that would get you stuck.
+ if( x0 < 0 || x0 >= md->xs || y0 < 0 || y0 >= md->ys )
#else
- if (x0 < 0 || x0 >= md->xs || y0 < 0 || y0 >= md->ys /*|| map_getcellp(md,x0,y0,cell)*/)
+ if( x0 < 0 || x0 >= md->xs || y0 < 0 || y0 >= md->ys /*|| map_getcellp(md,x0,y0,cell)*/ )
#endif
- return false;
- if (x1 < 0 || x1 >= md->xs || y1 < 0 || y1 >= md->ys || map_getcellp(md,x1,y1,cell))
- return false;
-
- // calculate (sgn(x1-x0), sgn(y1-y0))
- dx = ((dx = x1-x0)) ? ((dx<0) ? -1 : 1) : 0;
- dy = ((dy = y1-y0)) ? ((dy<0) ? -1 : 1) : 0;
-
- // try finding direct path to target
- x = x0;
- y = y0;
- i = 0;
- while (i < ARRAYLENGTH(wpd->path)) {
- wpd->path[i] = walk_choices[-dy + 1][dx + 1];
- i++;
-
- x += dx;
- y += dy;
-
- if (x == x1) dx = 0;
- if (y == y1) dy = 0;
-
- if (dx == 0 && dy == 0)
- break; // success
- if (map_getcellp(md,x,y,cell))
- break; // obstacle = failure
- }
-
- if (x == x1 && y == y1) {
- //easy path successful.
- wpd->path_len = i;
- wpd->path_pos = 0;
- return true;
- }
-
- if (flag&1)
- return false;
-
- memset(tp,0,sizeof(tp));
-
- i=calc_index(x0,y0);
- tp[i].x=x0;
- tp[i].y=y0;
- tp[i].dist=0;
- tp[i].before=0;
- tp[i].cost=calc_cost(&tp[i],x1,y1);
- tp[i].flag=0;
- heap[0]=0;
- push_heap_path(heap,tp,calc_index(x0,y0));
+ return false;
+ if( x1 < 0 || x1 >= md->xs || y1 < 0 || y1 >= md->ys || map_getcellp(md,x1,y1,cell) )
+ return false;
+
+ // calculate (sgn(x1-x0), sgn(y1-y0))
+ dx = ((dx = x1-x0)) ? ((dx<0) ? -1 : 1) : 0;
+ dy = ((dy = y1-y0)) ? ((dy<0) ? -1 : 1) : 0;
+
+ // try finding direct path to target
+ x = x0;
+ y = y0;
+ i = 0;
+ while( i < ARRAYLENGTH(wpd->path) )
+ {
+ wpd->path[i] = walk_choices[-dy + 1][dx + 1];
+ i++;
+
+ x += dx;
+ y += dy;
+
+ if( x == x1 ) dx = 0;
+ if( y == y1 ) dy = 0;
+
+ if( dx == 0 && dy == 0 )
+ break; // success
+ if( map_getcellp(md,x,y,cell) )
+ break; // obstacle = failure
+ }
+
+ if( x == x1 && y == y1 )
+ { //easy path successful.
+ wpd->path_len = i;
+ wpd->path_pos = 0;
+ return true;
+ }
+
+ if( flag&1 )
+ return false;
+
+ memset(tp,0,sizeof(tp));
+
+ i=calc_index(x0,y0);
+ tp[i].x=x0;
+ tp[i].y=y0;
+ tp[i].dist=0;
+ tp[i].before=0;
+ tp[i].cost=calc_cost(&tp[i],x1,y1);
+ tp[i].flag=0;
+ heap[0]=0;
+ push_heap_path(heap,tp,calc_index(x0,y0));
xs = md->xs - 1; // Place by subtracting a pre-
- ys = md->ys-1;
-
- for (;;) {
- int e=0,f=0,dist,cost,dc[4]= {0,0,0,0};
-
- if (heap[0]==0)
- return false;
- rp = pop_heap_path(heap,tp);
- x = tp[rp].x;
- y = tp[rp].y;
- dist = tp[rp].dist + 10;
- cost = tp[rp].cost;
-
- if (x==x1 && y==y1)
- break;
-
- // dc[0] : y++ Incremental cost at the time
- // dc[1] : x--
- // dc[2] : y--
- // dc[3] : x++
-
- if (y < ys && !map_getcellp(md,x ,y+1,cell)) {
- f |= 1;
- dc[0] = (y >= y1 ? 20 : 0);
- e+=add_path(heap,tp,x ,y+1,dist,rp,cost+dc[0]); // (x, y+1)
- }
- if (x > 0 && !map_getcellp(md,x-1,y ,cell)) {
- f |= 2;
- dc[1] = (x <= x1 ? 20 : 0);
- e+=add_path(heap,tp,x-1,y ,dist,rp,cost+dc[1]); // (x-1, y )
- }
- if (y > 0 && !map_getcellp(md,x ,y-1,cell)) {
- f |= 4;
- dc[2] = (y <= y1 ? 20 : 0);
- e+=add_path(heap,tp,x ,y-1,dist,rp,cost+dc[2]); // (x , y-1)
- }
- if (x < xs && !map_getcellp(md,x+1,y ,cell)) {
- f |= 8;
- dc[3] = (x >= x1 ? 20 : 0);
- e+=add_path(heap,tp,x+1,y ,dist,rp,cost+dc[3]); // (x+1, y )
- }
- if ((f & (2+1)) == (2+1) && !map_getcellp(md,x-1,y+1,cell))
- e+=add_path(heap,tp,x-1,y+1,dist+4,rp,cost+dc[1]+dc[0]-6); // (x-1, y+1)
- if ((f & (2+4)) == (2+4) && !map_getcellp(md,x-1,y-1,cell))
- e+=add_path(heap,tp,x-1,y-1,dist+4,rp,cost+dc[1]+dc[2]-6); // (x-1, y-1)
- if ((f & (8+4)) == (8+4) && !map_getcellp(md,x+1,y-1,cell))
- e+=add_path(heap,tp,x+1,y-1,dist+4,rp,cost+dc[3]+dc[2]-6); // (x+1, y-1)
- if ((f & (8+1)) == (8+1) && !map_getcellp(md,x+1,y+1,cell))
- e+=add_path(heap,tp,x+1,y+1,dist+4,rp,cost+dc[3]+dc[0]-6); // (x+1, y+1)
- tp[rp].flag=1;
- if (e || heap[0]>=MAX_HEAP-5)
- return false;
- }
-
- if (!(x==x1 && y==y1)) // will never happen...
- return false;
-
- for (len=0,i=rp; len<100 && i!=calc_index(x0,y0); i=tp[i].before,len++);
- if (len==100 || len>=sizeof(wpd->path))
- return false;
-
- wpd->path_len = len;
- wpd->path_pos = 0;
- for (i=rp,j=len-1; j>=0; i=tp[i].before,j--) {
- int dx = tp[i].x - tp[tp[i].before].x;
- int dy = tp[i].y - tp[tp[i].before].y;
- int dir;
- if (dx == 0) {
- dir = (dy > 0 ? 0 : 4);
- } else if (dx > 0) {
- dir = (dy == 0 ? 6 : (dy < 0 ? 5 : 7));
- } else {
- dir = (dy == 0 ? 2 : (dy > 0 ? 1 : 3));
- }
- wpd->path[j] = dir;
- }
-
- return true;
+ ys = md->ys-1;
+
+ for(;;)
+ {
+ int e=0,f=0,dist,cost,dc[4]={0,0,0,0};
+
+ if(heap[0]==0)
+ return false;
+ rp = pop_heap_path(heap,tp);
+ x = tp[rp].x;
+ y = tp[rp].y;
+ dist = tp[rp].dist + 10;
+ cost = tp[rp].cost;
+
+ if(x==x1 && y==y1)
+ break;
+
+ // dc[0] : y++ Incremental cost at the time
+ // dc[1] : x--
+ // dc[2] : y--
+ // dc[3] : x++
+
+ if(y < ys && !map_getcellp(md,x ,y+1,cell)) {
+ f |= 1; dc[0] = (y >= y1 ? 20 : 0);
+ e+=add_path(heap,tp,x ,y+1,dist,rp,cost+dc[0]); // (x, y+1)
+ }
+ if(x > 0 && !map_getcellp(md,x-1,y ,cell)) {
+ f |= 2; dc[1] = (x <= x1 ? 20 : 0);
+ e+=add_path(heap,tp,x-1,y ,dist,rp,cost+dc[1]); // (x-1, y )
+ }
+ if(y > 0 && !map_getcellp(md,x ,y-1,cell)) {
+ f |= 4; dc[2] = (y <= y1 ? 20 : 0);
+ e+=add_path(heap,tp,x ,y-1,dist,rp,cost+dc[2]); // (x , y-1)
+ }
+ if(x < xs && !map_getcellp(md,x+1,y ,cell)) {
+ f |= 8; dc[3] = (x >= x1 ? 20 : 0);
+ e+=add_path(heap,tp,x+1,y ,dist,rp,cost+dc[3]); // (x+1, y )
+ }
+ if( (f & (2+1)) == (2+1) && !map_getcellp(md,x-1,y+1,cell))
+ e+=add_path(heap,tp,x-1,y+1,dist+4,rp,cost+dc[1]+dc[0]-6); // (x-1, y+1)
+ if( (f & (2+4)) == (2+4) && !map_getcellp(md,x-1,y-1,cell))
+ e+=add_path(heap,tp,x-1,y-1,dist+4,rp,cost+dc[1]+dc[2]-6); // (x-1, y-1)
+ if( (f & (8+4)) == (8+4) && !map_getcellp(md,x+1,y-1,cell))
+ e+=add_path(heap,tp,x+1,y-1,dist+4,rp,cost+dc[3]+dc[2]-6); // (x+1, y-1)
+ if( (f & (8+1)) == (8+1) && !map_getcellp(md,x+1,y+1,cell))
+ e+=add_path(heap,tp,x+1,y+1,dist+4,rp,cost+dc[3]+dc[0]-6); // (x+1, y+1)
+ tp[rp].flag=1;
+ if(e || heap[0]>=MAX_HEAP-5)
+ return false;
+ }
+
+ if( !(x==x1 && y==y1) ) // will never happen...
+ return false;
+
+ for(len=0,i=rp;len<100 && i!=calc_index(x0,y0);i=tp[i].before,len++);
+ if(len==100 || len>=sizeof(wpd->path))
+ return false;
+
+ wpd->path_len = len;
+ wpd->path_pos = 0;
+ for(i=rp,j=len-1;j>=0;i=tp[i].before,j--) {
+ int dx = tp[i].x - tp[tp[i].before].x;
+ int dy = tp[i].y - tp[tp[i].before].y;
+ int dir;
+ if( dx == 0 ) {
+ dir = (dy > 0 ? 0 : 4);
+ } else if( dx > 0 ) {
+ dir = (dy == 0 ? 6 : (dy < 0 ? 5 : 7) );
+ } else {
+ dir = (dy == 0 ? 2 : (dy > 0 ? 1 : 3) );
+ }
+ wpd->path[j] = dir;
+ }
+
+ return true;
}
@@ -420,39 +425,40 @@ bool path_search(struct walkpath_data *wpd,int m,int x0,int y0,int x1,int y1,int
int check_distance(int dx, int dy, int distance)
{
#ifdef CIRCULAR_AREA
- //In this case, we just do a square comparison. Add 1 tile grace for diagonal range checks.
- return (dx*dx + dy*dy <= distance*distance + (dx&&dy?1:0));
+ //In this case, we just do a square comparison. Add 1 tile grace for diagonal range checks.
+ return (dx*dx + dy*dy <= distance*distance + (dx&&dy?1:0));
#else
- if (dx < 0) dx = -dx;
- if (dy < 0) dy = -dy;
- return ((dx<dy?dy:dx) <= distance);
+ if (dx < 0) dx = -dx;
+ if (dy < 0) dy = -dy;
+ return ((dx<dy?dy:dx) <= distance);
#endif
}
unsigned int distance(int dx, int dy)
{
#ifdef CIRCULAR_AREA
- unsigned int min, max;
-
- if (dx < 0) dx = -dx;
- if (dy < 0) dy = -dy;
- //There appears to be something wrong with the aproximation below when either dx/dy is 0! [Skotlex]
- if (dx == 0) return dy;
- if (dy == 0) return dx;
-
- if (dx < dy) {
- min = dx;
- max = dy;
- } else {
- min = dy;
- max = dx;
- }
- // coefficients equivalent to ( 123/128 * max ) and ( 51/128 * min )
- return (((max << 8) + (max << 3) - (max << 4) - (max << 1) +
- (min << 7) - (min << 5) + (min << 3) - (min << 1)) >> 8);
+ unsigned int min, max;
+
+ if ( dx < 0 ) dx = -dx;
+ if ( dy < 0 ) dy = -dy;
+ //There appears to be something wrong with the aproximation below when either dx/dy is 0! [Skotlex]
+ if ( dx == 0 ) return dy;
+ if ( dy == 0 ) return dx;
+
+ if ( dx < dy )
+ {
+ min = dx;
+ max = dy;
+ } else {
+ min = dy;
+ max = dx;
+ }
+ // coefficients equivalent to ( 123/128 * max ) and ( 51/128 * min )
+ return ((( max << 8 ) + ( max << 3 ) - ( max << 4 ) - ( max << 1 ) +
+ ( min << 7 ) - ( min << 5 ) + ( min << 3 ) - ( min << 1 )) >> 8 );
#else
- if (dx < 0) dx = -dx;
- if (dy < 0) dy = -dy;
- return (dx<dy?dy:dx);
+ if (dx < 0) dx = -dx;
+ if (dy < 0) dy = -dy;
+ return (dx<dy?dy:dx);
#endif
}
diff --git a/src/map/path.h b/src/map/path.h
index 10f05f82d..1dc024655 100644
--- a/src/map/path.h
+++ b/src/map/path.h
@@ -9,14 +9,14 @@
#define MAX_WALKPATH 32
struct walkpath_data {
- unsigned char path_len,path_pos;
- unsigned char path[MAX_WALKPATH];
+ unsigned char path_len,path_pos;
+ unsigned char path[MAX_WALKPATH];
};
struct shootpath_data {
- int rx,ry,len;
- int x[MAX_WALKPATH];
- int y[MAX_WALKPATH];
+ int rx,ry,len;
+ int x[MAX_WALKPATH];
+ int y[MAX_WALKPATH];
};
// calculates destination cell for knockback
diff --git a/src/map/pc.c b/src/map/pc.c
index c2ca012ac..59709cdf1 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -47,7 +47,7 @@
#include <time.h>
-#define PVP_CALCRANK_INTERVAL 1000 // PVP calculation interval
+#define PVP_CALCRANK_INTERVAL 1000 // PVP calculation interval
static unsigned int exp_table[CLASS_COUNT][2][MAX_LEVEL];
static unsigned int max_level[CLASS_COUNT][2];
static unsigned int statp[MAX_LEVEL+1];
@@ -65,17 +65,17 @@ struct fame_list smith_fame_list[MAX_FAME_LIST];
struct fame_list chemist_fame_list[MAX_FAME_LIST];
struct fame_list taekwon_fame_list[MAX_FAME_LIST];
-static unsigned short equip_pos[EQI_MAX]= {EQP_ACC_L,EQP_ACC_R,EQP_SHOES,EQP_GARMENT,EQP_HEAD_LOW,EQP_HEAD_MID,EQP_HEAD_TOP,EQP_ARMOR,EQP_HAND_L,EQP_HAND_R,EQP_COSTUME_HEAD_TOP,EQP_COSTUME_HEAD_MID,EQP_COSTUME_HEAD_LOW,EQP_AMMO};
+static unsigned short equip_pos[EQI_MAX]={EQP_ACC_L,EQP_ACC_R,EQP_SHOES,EQP_GARMENT,EQP_HEAD_LOW,EQP_HEAD_MID,EQP_HEAD_TOP,EQP_ARMOR,EQP_HAND_L,EQP_HAND_R,EQP_COSTUME_HEAD_TOP,EQP_COSTUME_HEAD_MID,EQP_COSTUME_HEAD_LOW,EQP_AMMO};
#define MOTD_LINE_SIZE 128
static char motd_text[MOTD_LINE_SIZE][CHAT_SIZE_MAX]; // Message of the day buffer [Valaris]
//Links related info to the sd->hate_mob[]/sd->feel_map[] entries
const struct sg_data sg_info[MAX_PC_FEELHATE] = {
- { SG_SUN_ANGER, SG_SUN_BLESS, SG_SUN_COMFORT, "PC_FEEL_SUN", "PC_HATE_MOB_SUN", is_day_of_sun },
- { SG_MOON_ANGER, SG_MOON_BLESS, SG_MOON_COMFORT, "PC_FEEL_MOON", "PC_HATE_MOB_MOON", is_day_of_moon },
- { SG_STAR_ANGER, SG_STAR_BLESS, SG_STAR_COMFORT, "PC_FEEL_STAR", "PC_HATE_MOB_STAR", is_day_of_star }
-};
+ { SG_SUN_ANGER, SG_SUN_BLESS, SG_SUN_COMFORT, "PC_FEEL_SUN", "PC_HATE_MOB_SUN", is_day_of_sun },
+ { SG_MOON_ANGER, SG_MOON_BLESS, SG_MOON_COMFORT, "PC_FEEL_MOON", "PC_HATE_MOB_MOON", is_day_of_moon },
+ { SG_STAR_ANGER, SG_STAR_BLESS, SG_STAR_COMFORT, "PC_FEEL_STAR", "PC_HATE_MOB_STAR", is_day_of_star }
+ };
/**
* Item Cool Down Delay Saving
@@ -83,410 +83,420 @@ const struct sg_data sg_info[MAX_PC_FEELHATE] = {
* to keep cooldowns in memory between player log-ins.
* All cooldowns are reset when server is restarted.
**/
-DBMap *itemcd_db = NULL; // char_id -> struct skill_cd
+DBMap* itemcd_db = NULL; // char_id -> struct skill_cd
struct item_cd {
- unsigned int tick[MAX_ITEMDELAYS];//tick
- short nameid[MAX_ITEMDELAYS];//skill id
+ unsigned int tick[MAX_ITEMDELAYS];//tick
+ short nameid[MAX_ITEMDELAYS];//skill id
};
//Converts a class to its array index for CLASS_COUNT defined arrays.
//Note that it does not do a validity check for speed purposes, where parsing
//player input make sure to use a pcdb_checkid first!
-int pc_class2idx(int class_)
-{
- if (class_ >= JOB_NOVICE_HIGH)
- return class_- JOB_NOVICE_HIGH+JOB_MAX_BASIC;
- return class_;
+int pc_class2idx(int class_) {
+ if (class_ >= JOB_NOVICE_HIGH)
+ return class_- JOB_NOVICE_HIGH+JOB_MAX_BASIC;
+ return class_;
}
-inline int pc_get_group_id(struct map_session_data *sd)
-{
- return sd->group_id;
+inline int pc_get_group_id(struct map_session_data *sd) {
+ return sd->group_id;
}
-inline int pc_get_group_level(struct map_session_data *sd)
-{
- return sd->group_level;
+inline int pc_get_group_level(struct map_session_data *sd) {
+ return sd->group_level;
}
static int pc_invincible_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- struct map_session_data *sd;
+ struct map_session_data *sd;
- if ((sd=(struct map_session_data *)map_id2sd(id)) == NULL || sd->bl.type!=BL_PC)
- return 1;
+ if( (sd=(struct map_session_data *)map_id2sd(id)) == NULL || sd->bl.type!=BL_PC )
+ return 1;
- if (sd->invincible_timer != tid) {
- ShowError("invincible_timer %d != %d\n",sd->invincible_timer,tid);
- return 0;
- }
- sd->invincible_timer = INVALID_TIMER;
- skill_unit_move(&sd->bl,tick,1);
+ if(sd->invincible_timer != tid){
+ ShowError("invincible_timer %d != %d\n",sd->invincible_timer,tid);
+ return 0;
+ }
+ sd->invincible_timer = INVALID_TIMER;
+ skill_unit_move(&sd->bl,tick,1);
- return 0;
+ return 0;
}
-void pc_setinvincibletimer(struct map_session_data *sd, int val)
+void pc_setinvincibletimer(struct map_session_data* sd, int val)
{
- nullpo_retv(sd);
+ nullpo_retv(sd);
- if (sd->invincible_timer != INVALID_TIMER)
- delete_timer(sd->invincible_timer,pc_invincible_timer);
- sd->invincible_timer = add_timer(gettick()+val,pc_invincible_timer,sd->bl.id,0);
+ if( sd->invincible_timer != INVALID_TIMER )
+ delete_timer(sd->invincible_timer,pc_invincible_timer);
+ sd->invincible_timer = add_timer(gettick()+val,pc_invincible_timer,sd->bl.id,0);
}
-void pc_delinvincibletimer(struct map_session_data *sd)
+void pc_delinvincibletimer(struct map_session_data* sd)
{
- nullpo_retv(sd);
+ nullpo_retv(sd);
- if (sd->invincible_timer != INVALID_TIMER) {
- delete_timer(sd->invincible_timer,pc_invincible_timer);
- sd->invincible_timer = INVALID_TIMER;
- skill_unit_move(&sd->bl,gettick(),1);
- }
+ if( sd->invincible_timer != INVALID_TIMER )
+ {
+ delete_timer(sd->invincible_timer,pc_invincible_timer);
+ sd->invincible_timer = INVALID_TIMER;
+ skill_unit_move(&sd->bl,gettick(),1);
+ }
}
static int pc_spiritball_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- struct map_session_data *sd;
- int i;
+ struct map_session_data *sd;
+ int i;
- if ((sd=(struct map_session_data *)map_id2sd(id)) == NULL || sd->bl.type!=BL_PC)
- return 1;
+ if( (sd=(struct map_session_data *)map_id2sd(id)) == NULL || sd->bl.type!=BL_PC )
+ return 1;
- if (sd->spiritball <= 0) {
- ShowError("pc_spiritball_timer: %d spiritball's available. (aid=%d cid=%d tid=%d)\n", sd->spiritball, sd->status.account_id, sd->status.char_id, tid);
- sd->spiritball = 0;
- return 0;
- }
+ if( sd->spiritball <= 0 )
+ {
+ ShowError("pc_spiritball_timer: %d spiritball's available. (aid=%d cid=%d tid=%d)\n", sd->spiritball, sd->status.account_id, sd->status.char_id, tid);
+ sd->spiritball = 0;
+ return 0;
+ }
- ARR_FIND(0, sd->spiritball, i, sd->spirit_timer[i] == tid);
- if (i == sd->spiritball) {
- ShowError("pc_spiritball_timer: timer not found (aid=%d cid=%d tid=%d)\n", sd->status.account_id, sd->status.char_id, tid);
- return 0;
- }
+ ARR_FIND(0, sd->spiritball, i, sd->spirit_timer[i] == tid);
+ if( i == sd->spiritball )
+ {
+ ShowError("pc_spiritball_timer: timer not found (aid=%d cid=%d tid=%d)\n", sd->status.account_id, sd->status.char_id, tid);
+ return 0;
+ }
- sd->spiritball--;
- if (i != sd->spiritball)
- memmove(sd->spirit_timer+i, sd->spirit_timer+i+1, (sd->spiritball-i)*sizeof(int));
- sd->spirit_timer[sd->spiritball] = INVALID_TIMER;
+ sd->spiritball--;
+ if( i != sd->spiritball )
+ memmove(sd->spirit_timer+i, sd->spirit_timer+i+1, (sd->spiritball-i)*sizeof(int));
+ sd->spirit_timer[sd->spiritball] = INVALID_TIMER;
- clif_spiritball(&sd->bl);
+ clif_spiritball(&sd->bl);
- return 0;
+ return 0;
}
int pc_addspiritball(struct map_session_data *sd,int interval,int max)
{
- int tid, i;
+ int tid, i;
- nullpo_ret(sd);
+ nullpo_ret(sd);
- if (max > MAX_SKILL_LEVEL)
- max = MAX_SKILL_LEVEL;
- if (sd->spiritball < 0)
- sd->spiritball = 0;
+ if(max > MAX_SKILL_LEVEL)
+ max = MAX_SKILL_LEVEL;
+ if(sd->spiritball < 0)
+ sd->spiritball = 0;
- if (sd->spiritball && sd->spiritball >= max) {
- if (sd->spirit_timer[0] != INVALID_TIMER)
- delete_timer(sd->spirit_timer[0],pc_spiritball_timer);
- sd->spiritball--;
- if (sd->spiritball != 0)
- memmove(sd->spirit_timer+0, sd->spirit_timer+1, (sd->spiritball)*sizeof(int));
- sd->spirit_timer[sd->spiritball] = INVALID_TIMER;
- }
+ if( sd->spiritball && sd->spiritball >= max )
+ {
+ if(sd->spirit_timer[0] != INVALID_TIMER)
+ delete_timer(sd->spirit_timer[0],pc_spiritball_timer);
+ sd->spiritball--;
+ if( sd->spiritball != 0 )
+ memmove(sd->spirit_timer+0, sd->spirit_timer+1, (sd->spiritball)*sizeof(int));
+ sd->spirit_timer[sd->spiritball] = INVALID_TIMER;
+ }
- tid = add_timer(gettick()+interval, pc_spiritball_timer, sd->bl.id, 0);
- ARR_FIND(0, sd->spiritball, i, sd->spirit_timer[i] == INVALID_TIMER || DIFF_TICK(get_timer(tid)->tick, get_timer(sd->spirit_timer[i])->tick) < 0);
- if (i != sd->spiritball)
- memmove(sd->spirit_timer+i+1, sd->spirit_timer+i, (sd->spiritball-i)*sizeof(int));
- sd->spirit_timer[i] = tid;
- sd->spiritball++;
- if ((sd->class_&MAPID_THIRDMASK) == MAPID_ROYAL_GUARD)
- clif_millenniumshield(sd,sd->spiritball);
- else
- clif_spiritball(&sd->bl);
+ tid = add_timer(gettick()+interval, pc_spiritball_timer, sd->bl.id, 0);
+ ARR_FIND(0, sd->spiritball, i, sd->spirit_timer[i] == INVALID_TIMER || DIFF_TICK(get_timer(tid)->tick, get_timer(sd->spirit_timer[i])->tick) < 0);
+ if( i != sd->spiritball )
+ memmove(sd->spirit_timer+i+1, sd->spirit_timer+i, (sd->spiritball-i)*sizeof(int));
+ sd->spirit_timer[i] = tid;
+ sd->spiritball++;
+ if( (sd->class_&MAPID_THIRDMASK) == MAPID_ROYAL_GUARD )
+ clif_millenniumshield(sd,sd->spiritball);
+ else
+ clif_spiritball(&sd->bl);
- return 0;
+ return 0;
}
int pc_delspiritball(struct map_session_data *sd,int count,int type)
{
- int i;
-
- nullpo_ret(sd);
-
- if (sd->spiritball <= 0) {
- sd->spiritball = 0;
- return 0;
- }
-
- if (count <= 0)
- return 0;
- if (count > sd->spiritball)
- count = sd->spiritball;
- sd->spiritball -= count;
- if (count > MAX_SKILL_LEVEL)
- count = MAX_SKILL_LEVEL;
-
- for (i=0; i<count; i++) {
- if (sd->spirit_timer[i] != INVALID_TIMER) {
- delete_timer(sd->spirit_timer[i],pc_spiritball_timer);
- sd->spirit_timer[i] = INVALID_TIMER;
- }
- }
- for (i=count; i<MAX_SKILL_LEVEL; i++) {
- sd->spirit_timer[i-count] = sd->spirit_timer[i];
- sd->spirit_timer[i] = INVALID_TIMER;
- }
-
- if (!type) {
- if ((sd->class_&MAPID_THIRDMASK) == MAPID_ROYAL_GUARD)
- clif_millenniumshield(sd,sd->spiritball);
- else
- clif_spiritball(&sd->bl);
- }
- return 0;
-}
-static int pc_check_banding(struct block_list *bl, va_list ap)
-{
- int *c, *b_sd;
- struct block_list *src;
- struct map_session_data *tsd;
- struct status_change *sc;
-
- nullpo_ret(bl);
- nullpo_ret(tsd = (struct map_session_data *)bl);
- nullpo_ret(src = va_arg(ap,struct block_list *));
- c = va_arg(ap,int *);
- b_sd = va_arg(ap, int *);
-
- if (pc_isdead(tsd))
- return 0;
-
- sc = status_get_sc(bl);
-
- if (bl == src)
- return 0;
-
- if (sc && sc->data[SC_BANDING]) {
- b_sd[(*c)++] = tsd->bl.id;
- return 1;
- }
-
- return 0;
-}
-int pc_banding(struct map_session_data *sd, short skill_lv)
-{
- int c;
- int b_sd[MAX_PARTY]; // In case of a full Royal Guard party.
- int i, j, hp, extra_hp = 0, tmp_qty = 0, tmp_hp;
- struct map_session_data *bsd;
- struct status_change *sc;
- int range = skill_get_splash(LG_BANDING,skill_lv);
-
- nullpo_ret(sd);
-
- c = 0;
- memset(b_sd, 0, sizeof(b_sd));
- i = party_foreachsamemap(pc_check_banding,sd,range,&sd->bl,&c,&b_sd);
-
- if (c < 1) { //just recalc status no need to recalc hp
- // No more Royal Guards in Banding found.
- if ((sc = status_get_sc(&sd->bl)) != NULL && sc->data[SC_BANDING]) {
- sc->data[SC_BANDING]->val2 = 0; // Reset the counter
- status_calc_bl(&sd->bl, status_sc2scb_flag(SC_BANDING));
- }
- return 0;
- }
-
- //Add yourself
- hp = status_get_hp(&sd->bl);
- i++;
-
- // Get total HP of all Royal Guards in party.
- for (j = 0; j < i; j++) {
- bsd = map_id2sd(b_sd[j]);
- if (bsd != NULL)
- hp += status_get_hp(&bsd->bl);
- }
-
- // Set average HP.
- hp = hp / i;
-
- // If a Royal Guard have full HP, give more HP to others that haven't full HP.
- for (j = 0; j < i; j++) {
- bsd = map_id2sd(b_sd[j]);
- if (bsd != NULL && (tmp_hp = hp - status_get_max_hp(&bsd->bl)) > 0) {
- extra_hp += tmp_hp;
- tmp_qty++;
- }
- }
-
- if (extra_hp > 0 && tmp_qty > 0)
- hp += extra_hp / tmp_qty;
-
- for (j = 0; j < i; j++) {
- bsd = map_id2sd(b_sd[j]);
- if (bsd != NULL) {
- status_set_hp(&bsd->bl,hp,0); // Set hp
- if ((sc = status_get_sc(&bsd->bl)) != NULL && sc->data[SC_BANDING]) {
- sc->data[SC_BANDING]->val2 = c; // Set the counter. It doesn't count your self.
- status_calc_bl(&bsd->bl, status_sc2scb_flag(SC_BANDING)); // Set atk and def.
- }
- }
- }
-
- return c;
+ int i;
+
+ nullpo_ret(sd);
+
+ if(sd->spiritball <= 0) {
+ sd->spiritball = 0;
+ return 0;
+ }
+
+ if(count <= 0)
+ return 0;
+ if(count > sd->spiritball)
+ count = sd->spiritball;
+ sd->spiritball -= count;
+ if(count > MAX_SKILL_LEVEL)
+ count = MAX_SKILL_LEVEL;
+
+ for(i=0;i<count;i++) {
+ if(sd->spirit_timer[i] != INVALID_TIMER) {
+ delete_timer(sd->spirit_timer[i],pc_spiritball_timer);
+ sd->spirit_timer[i] = INVALID_TIMER;
+ }
+ }
+ for(i=count;i<MAX_SKILL_LEVEL;i++) {
+ sd->spirit_timer[i-count] = sd->spirit_timer[i];
+ sd->spirit_timer[i] = INVALID_TIMER;
+ }
+
+ if(!type) {
+ if( (sd->class_&MAPID_THIRDMASK) == MAPID_ROYAL_GUARD )
+ clif_millenniumshield(sd,sd->spiritball);
+ else
+ clif_spiritball(&sd->bl);
+ }
+ return 0;
+}
+static int pc_check_banding( struct block_list *bl, va_list ap ) {
+ int *c, *b_sd;
+ struct block_list *src;
+ struct map_session_data *tsd;
+ struct status_change *sc;
+
+ nullpo_ret(bl);
+ nullpo_ret(tsd = (struct map_session_data*)bl);
+ nullpo_ret(src = va_arg(ap,struct block_list *));
+ c = va_arg(ap,int *);
+ b_sd = va_arg(ap, int *);
+
+ if(pc_isdead(tsd))
+ return 0;
+
+ sc = status_get_sc(bl);
+
+ if( bl == src )
+ return 0;
+
+ if( sc && sc->data[SC_BANDING] )
+ {
+ b_sd[(*c)++] = tsd->bl.id;
+ return 1;
+ }
+
+ return 0;
+}
+int pc_banding(struct map_session_data *sd, short skill_lv) {
+ int c;
+ int b_sd[MAX_PARTY]; // In case of a full Royal Guard party.
+ int i, j, hp, extra_hp = 0, tmp_qty = 0, tmp_hp;
+ struct map_session_data *bsd;
+ struct status_change *sc;
+ int range = skill_get_splash(LG_BANDING,skill_lv);
+
+ nullpo_ret(sd);
+
+ c = 0;
+ memset(b_sd, 0, sizeof(b_sd));
+ i = party_foreachsamemap(pc_check_banding,sd,range,&sd->bl,&c,&b_sd);
+
+ if( c < 1 ) //just recalc status no need to recalc hp
+ { // No more Royal Guards in Banding found.
+ if( (sc = status_get_sc(&sd->bl)) != NULL && sc->data[SC_BANDING] )
+ {
+ sc->data[SC_BANDING]->val2 = 0; // Reset the counter
+ status_calc_bl(&sd->bl, status_sc2scb_flag(SC_BANDING));
+ }
+ return 0;
+ }
+
+ //Add yourself
+ hp = status_get_hp(&sd->bl);
+ i++;
+
+ // Get total HP of all Royal Guards in party.
+ for( j = 0; j < i; j++ )
+ {
+ bsd = map_id2sd(b_sd[j]);
+ if( bsd != NULL )
+ hp += status_get_hp(&bsd->bl);
+ }
+
+ // Set average HP.
+ hp = hp / i;
+
+ // If a Royal Guard have full HP, give more HP to others that haven't full HP.
+ for( j = 0; j < i; j++ )
+ {
+ bsd = map_id2sd(b_sd[j]);
+ if( bsd != NULL && (tmp_hp = hp - status_get_max_hp(&bsd->bl)) > 0 )
+ {
+ extra_hp += tmp_hp;
+ tmp_qty++;
+ }
+ }
+
+ if( extra_hp > 0 && tmp_qty > 0 )
+ hp += extra_hp / tmp_qty;
+
+ for( j = 0; j < i; j++ )
+ {
+ bsd = map_id2sd(b_sd[j]);
+ if( bsd != NULL )
+ {
+ status_set_hp(&bsd->bl,hp,0); // Set hp
+ if( (sc = status_get_sc(&bsd->bl)) != NULL && sc->data[SC_BANDING] )
+ {
+ sc->data[SC_BANDING]->val2 = c; // Set the counter. It doesn't count your self.
+ status_calc_bl(&bsd->bl, status_sc2scb_flag(SC_BANDING)); // Set atk and def.
+ }
+ }
+ }
+
+ return c;
}
// Increases a player's fame points and displays a notice to him
void pc_addfame(struct map_session_data *sd,int count)
{
- nullpo_retv(sd);
- sd->status.fame += count;
- if (sd->status.fame > MAX_FAME)
- sd->status.fame = MAX_FAME;
- switch (sd->class_&MAPID_UPPERMASK) {
- case MAPID_BLACKSMITH: // Blacksmith
- clif_fame_blacksmith(sd,count);
- break;
- case MAPID_ALCHEMIST: // Alchemist
- clif_fame_alchemist(sd,count);
- break;
- case MAPID_TAEKWON: // Taekwon
- clif_fame_taekwon(sd,count);
- break;
- }
- chrif_updatefamelist(sd);
+ nullpo_retv(sd);
+ sd->status.fame += count;
+ if(sd->status.fame > MAX_FAME)
+ sd->status.fame = MAX_FAME;
+ switch(sd->class_&MAPID_UPPERMASK){
+ case MAPID_BLACKSMITH: // Blacksmith
+ clif_fame_blacksmith(sd,count);
+ break;
+ case MAPID_ALCHEMIST: // Alchemist
+ clif_fame_alchemist(sd,count);
+ break;
+ case MAPID_TAEKWON: // Taekwon
+ clif_fame_taekwon(sd,count);
+ break;
+ }
+ chrif_updatefamelist(sd);
}
// Check whether a player ID is in the fame rankers' list of its job, returns his/her position if so, 0 else
unsigned char pc_famerank(int char_id, int job)
{
- int i;
-
- switch (job) {
- case MAPID_BLACKSMITH: // Blacksmith
- for (i = 0; i < MAX_FAME_LIST; i++) {
- if (smith_fame_list[i].id == char_id)
- return i + 1;
- }
- break;
- case MAPID_ALCHEMIST: // Alchemist
- for (i = 0; i < MAX_FAME_LIST; i++) {
- if (chemist_fame_list[i].id == char_id)
- return i + 1;
- }
- break;
- case MAPID_TAEKWON: // Taekwon
- for (i = 0; i < MAX_FAME_LIST; i++) {
- if (taekwon_fame_list[i].id == char_id)
- return i + 1;
- }
- break;
- }
-
- return 0;
-}
-
-int pc_setrestartvalue(struct map_session_data *sd,int type)
-{
- struct status_data *status, *b_status;
- nullpo_ret(sd);
-
- b_status = &sd->base_status;
- status = &sd->battle_status;
-
- if (type&1) { //Normal resurrection
- status->hp = 1; //Otherwise status_heal may fail if dead.
- status_heal(&sd->bl, b_status->hp, 0, 1);
- if (status->sp < b_status->sp)
- status_set_sp(&sd->bl, b_status->sp, 1);
- } else { //Just for saving on the char-server (with values as if respawned)
- sd->status.hp = b_status->hp;
- sd->status.sp = (status->sp < b_status->sp)?b_status->sp:status->sp;
- }
- return 0;
+ int i;
+
+ switch(job){
+ case MAPID_BLACKSMITH: // Blacksmith
+ for(i = 0; i < MAX_FAME_LIST; i++){
+ if(smith_fame_list[i].id == char_id)
+ return i + 1;
+ }
+ break;
+ case MAPID_ALCHEMIST: // Alchemist
+ for(i = 0; i < MAX_FAME_LIST; i++){
+ if(chemist_fame_list[i].id == char_id)
+ return i + 1;
+ }
+ break;
+ case MAPID_TAEKWON: // Taekwon
+ for(i = 0; i < MAX_FAME_LIST; i++){
+ if(taekwon_fame_list[i].id == char_id)
+ return i + 1;
+ }
+ break;
+ }
+
+ return 0;
+}
+
+int pc_setrestartvalue(struct map_session_data *sd,int type) {
+ struct status_data *status, *b_status;
+ nullpo_ret(sd);
+
+ b_status = &sd->base_status;
+ status = &sd->battle_status;
+
+ if (type&1) { //Normal resurrection
+ status->hp = 1; //Otherwise status_heal may fail if dead.
+ status_heal(&sd->bl, b_status->hp, 0, 1);
+ if( status->sp < b_status->sp )
+ status_set_sp(&sd->bl, b_status->sp, 1);
+ } else { //Just for saving on the char-server (with values as if respawned)
+ sd->status.hp = b_status->hp;
+ sd->status.sp = (status->sp < b_status->sp)?b_status->sp:status->sp;
+ }
+ return 0;
}
/*==========================================
- Rental System
+ Rental System
*------------------------------------------*/
static int pc_inventory_rental_end(int tid, unsigned int tick, int id, intptr_t data)
{
- struct map_session_data *sd = map_id2sd(id);
- if (sd == NULL)
- return 0;
- if (tid != sd->rental_timer) {
- ShowError("pc_inventory_rental_end: invalid timer id.\n");
- return 0;
- }
+ struct map_session_data *sd = map_id2sd(id);
+ if( sd == NULL )
+ return 0;
+ if( tid != sd->rental_timer )
+ {
+ ShowError("pc_inventory_rental_end: invalid timer id.\n");
+ return 0;
+ }
- pc_inventory_rentals(sd);
- return 1;
+ pc_inventory_rentals(sd);
+ return 1;
}
int pc_inventory_rental_clear(struct map_session_data *sd)
{
- if (sd->rental_timer != INVALID_TIMER) {
- delete_timer(sd->rental_timer, pc_inventory_rental_end);
- sd->rental_timer = INVALID_TIMER;
- }
+ if( sd->rental_timer != INVALID_TIMER )
+ {
+ delete_timer(sd->rental_timer, pc_inventory_rental_end);
+ sd->rental_timer = INVALID_TIMER;
+ }
- return 1;
+ return 1;
}
void pc_inventory_rentals(struct map_session_data *sd)
{
- int i, c = 0;
- unsigned int expire_tick, next_tick = UINT_MAX;
-
- for (i = 0; i < MAX_INVENTORY; i++) {
- // Check for Rentals on Inventory
- if (sd->status.inventory[i].nameid == 0)
- continue; // Nothing here
- if (sd->status.inventory[i].expire_time == 0)
- continue;
-
- if (sd->status.inventory[i].expire_time <= time(NULL)) {
- if (sd->status.inventory[i].nameid == ITEMID_REINS_OF_MOUNT
- && sd->sc.option&OPTION_MOUNTING) {
- pc_setoption(sd, sd->sc.option&~OPTION_MOUNTING);
- }
- clif_rental_expired(sd->fd, i, sd->status.inventory[i].nameid);
- pc_delitem(sd, i, sd->status.inventory[i].amount, 1, 0, LOG_TYPE_OTHER);
- } else {
- expire_tick = (unsigned int)(sd->status.inventory[i].expire_time - time(NULL)) * 1000;
- clif_rental_time(sd->fd, sd->status.inventory[i].nameid, (int)(expire_tick / 1000));
- next_tick = min(expire_tick, next_tick);
- c++;
- }
- }
-
- if (c > 0) // min(next_tick,3600000) 1 hour each timer to keep announcing to the owner, and to avoid a but with rental time > 15 days
- sd->rental_timer = add_timer(gettick() + min(next_tick,3600000), pc_inventory_rental_end, sd->bl.id, 0);
- else
- sd->rental_timer = INVALID_TIMER;
+ int i, c = 0;
+ unsigned int expire_tick, next_tick = UINT_MAX;
+
+ for( i = 0; i < MAX_INVENTORY; i++ )
+ { // Check for Rentals on Inventory
+ if( sd->status.inventory[i].nameid == 0 )
+ continue; // Nothing here
+ if( sd->status.inventory[i].expire_time == 0 )
+ continue;
+
+ if( sd->status.inventory[i].expire_time <= time(NULL) ) {
+ if( sd->status.inventory[i].nameid == ITEMID_REINS_OF_MOUNT
+ && sd->sc.option&OPTION_MOUNTING ) {
+ pc_setoption(sd, sd->sc.option&~OPTION_MOUNTING);
+ }
+ clif_rental_expired(sd->fd, i, sd->status.inventory[i].nameid);
+ pc_delitem(sd, i, sd->status.inventory[i].amount, 1, 0, LOG_TYPE_OTHER);
+ } else {
+ expire_tick = (unsigned int)(sd->status.inventory[i].expire_time - time(NULL)) * 1000;
+ clif_rental_time(sd->fd, sd->status.inventory[i].nameid, (int)(expire_tick / 1000));
+ next_tick = min(expire_tick, next_tick);
+ c++;
+ }
+ }
+
+ if( c > 0 ) // min(next_tick,3600000) 1 hour each timer to keep announcing to the owner, and to avoid a but with rental time > 15 days
+ sd->rental_timer = add_timer(gettick() + min(next_tick,3600000), pc_inventory_rental_end, sd->bl.id, 0);
+ else
+ sd->rental_timer = INVALID_TIMER;
}
void pc_inventory_rental_add(struct map_session_data *sd, int seconds)
{
- const struct TimerData *td;
- int tick = seconds * 1000;
+ const struct TimerData * td;
+ int tick = seconds * 1000;
- if (sd == NULL)
- return;
+ if( sd == NULL )
+ return;
- if (sd->rental_timer != INVALID_TIMER) {
- td = get_timer(sd->rental_timer);
- if (DIFF_TICK(td->tick, gettick()) > tick) {
- // Update Timer as this one ends first than the current one
- pc_inventory_rental_clear(sd);
- sd->rental_timer = add_timer(gettick() + tick, pc_inventory_rental_end, sd->bl.id, 0);
- }
- } else
- sd->rental_timer = add_timer(gettick() + min(tick,3600000), pc_inventory_rental_end, sd->bl.id, 0);
+ if( sd->rental_timer != INVALID_TIMER )
+ {
+ td = get_timer(sd->rental_timer);
+ if( DIFF_TICK(td->tick, gettick()) > tick )
+ { // Update Timer as this one ends first than the current one
+ pc_inventory_rental_clear(sd);
+ sd->rental_timer = add_timer(gettick() + tick, pc_inventory_rental_end, sd->bl.id, 0);
+ }
+ }
+ else
+ sd->rental_timer = add_timer(gettick() + min(tick,3600000), pc_inventory_rental_end, sd->bl.id, 0);
}
/**
@@ -494,7 +504,7 @@ void pc_inventory_rental_add(struct map_session_data *sd, int seconds)
*/
bool pc_can_give_items(struct map_session_data *sd)
{
- return pc_has_permission(sd, PC_PERM_TRADE);
+ return pc_has_permission(sd, PC_PERM_TRADE);
}
/*==========================================
@@ -502,52 +512,52 @@ bool pc_can_give_items(struct map_session_data *sd)
*------------------------------------------*/
int pc_makesavestatus(struct map_session_data *sd)
{
- nullpo_ret(sd);
+ nullpo_ret(sd);
- if (!battle_config.save_clothcolor)
- sd->status.clothes_color=0;
+ if(!battle_config.save_clothcolor)
+ sd->status.clothes_color=0;
- //Only copy the Cart/Peco/Falcon options, the rest are handled via
- //status change load/saving. [Skotlex]
+ //Only copy the Cart/Peco/Falcon options, the rest are handled via
+ //status change load/saving. [Skotlex]
#ifdef NEW_CARTS
- sd->status.option = sd->sc.option&(OPTION_FALCON|OPTION_RIDING|OPTION_DRAGON|OPTION_WUG|OPTION_WUGRIDER|OPTION_MADOGEAR|OPTION_MOUNTING);
+ sd->status.option = sd->sc.option&(OPTION_FALCON|OPTION_RIDING|OPTION_DRAGON|OPTION_WUG|OPTION_WUGRIDER|OPTION_MADOGEAR|OPTION_MOUNTING);
#else
- sd->status.option = sd->sc.option&(OPTION_CART|OPTION_FALCON|OPTION_RIDING|OPTION_DRAGON|OPTION_WUG|OPTION_WUGRIDER|OPTION_MADOGEAR|OPTION_MOUNTING);
+ sd->status.option = sd->sc.option&(OPTION_CART|OPTION_FALCON|OPTION_RIDING|OPTION_DRAGON|OPTION_WUG|OPTION_WUGRIDER|OPTION_MADOGEAR|OPTION_MOUNTING);
#endif
- if (sd->sc.data[SC_JAILED]) {
- //When Jailed, do not move last point.
- if (pc_isdead(sd)) {
- pc_setrestartvalue(sd,0);
- } else {
- sd->status.hp = sd->battle_status.hp;
- sd->status.sp = sd->battle_status.sp;
- }
- sd->status.last_point.map = sd->mapindex;
- sd->status.last_point.x = sd->bl.x;
- sd->status.last_point.y = sd->bl.y;
- return 0;
- }
-
- if (pc_isdead(sd)) {
- pc_setrestartvalue(sd,0);
- memcpy(&sd->status.last_point,&sd->status.save_point,sizeof(sd->status.last_point));
- } else {
- sd->status.hp = sd->battle_status.hp;
- sd->status.sp = sd->battle_status.sp;
- sd->status.last_point.map = sd->mapindex;
- sd->status.last_point.x = sd->bl.x;
- sd->status.last_point.y = sd->bl.y;
- }
-
- if (map[sd->bl.m].flag.nosave) {
- struct map_data *m=&map[sd->bl.m];
- if (m->save.map)
- memcpy(&sd->status.last_point,&m->save,sizeof(sd->status.last_point));
- else
- memcpy(&sd->status.last_point,&sd->status.save_point,sizeof(sd->status.last_point));
- }
-
- return 0;
+ if (sd->sc.data[SC_JAILED])
+ { //When Jailed, do not move last point.
+ if(pc_isdead(sd)){
+ pc_setrestartvalue(sd,0);
+ } else {
+ sd->status.hp = sd->battle_status.hp;
+ sd->status.sp = sd->battle_status.sp;
+ }
+ sd->status.last_point.map = sd->mapindex;
+ sd->status.last_point.x = sd->bl.x;
+ sd->status.last_point.y = sd->bl.y;
+ return 0;
+ }
+
+ if(pc_isdead(sd)){
+ pc_setrestartvalue(sd,0);
+ memcpy(&sd->status.last_point,&sd->status.save_point,sizeof(sd->status.last_point));
+ } else {
+ sd->status.hp = sd->battle_status.hp;
+ sd->status.sp = sd->battle_status.sp;
+ sd->status.last_point.map = sd->mapindex;
+ sd->status.last_point.x = sd->bl.x;
+ sd->status.last_point.y = sd->bl.y;
+ }
+
+ if(map[sd->bl.m].flag.nosave){
+ struct map_data *m=&map[sd->bl.m];
+ if(m->save.map)
+ memcpy(&sd->status.last_point,&m->save,sizeof(sd->status.last_point));
+ else
+ memcpy(&sd->status.last_point,&sd->status.save_point,sizeof(sd->status.last_point));
+ }
+
+ return 0;
}
/*==========================================
@@ -555,246 +565,231 @@ int pc_makesavestatus(struct map_session_data *sd)
*------------------------------------------*/
int pc_setnewpc(struct map_session_data *sd, int account_id, int char_id, int login_id1, unsigned int client_tick, int sex, int fd)
{
- nullpo_ret(sd);
+ nullpo_ret(sd);
- sd->bl.id = account_id;
- sd->status.account_id = account_id;
- sd->status.char_id = char_id;
- sd->status.sex = sex;
- sd->login_id1 = login_id1;
- sd->login_id2 = 0; // at this point, we can not know the value :(
- sd->client_tick = client_tick;
- sd->state.active = 0; //to be set to 1 after player is fully authed and loaded.
- sd->bl.type = BL_PC;
- sd->canlog_tick = gettick();
- //Required to prevent homunculus copuing a base speed of 0.
- sd->battle_status.speed = sd->base_status.speed = DEFAULT_WALK_SPEED;
- return 0;
+ sd->bl.id = account_id;
+ sd->status.account_id = account_id;
+ sd->status.char_id = char_id;
+ sd->status.sex = sex;
+ sd->login_id1 = login_id1;
+ sd->login_id2 = 0; // at this point, we can not know the value :(
+ sd->client_tick = client_tick;
+ sd->state.active = 0; //to be set to 1 after player is fully authed and loaded.
+ sd->bl.type = BL_PC;
+ sd->canlog_tick = gettick();
+ //Required to prevent homunculus copuing a base speed of 0.
+ sd->battle_status.speed = sd->base_status.speed = DEFAULT_WALK_SPEED;
+ return 0;
}
int pc_equippoint(struct map_session_data *sd,int n)
{
- int ep = 0;
+ int ep = 0;
- nullpo_ret(sd);
+ nullpo_ret(sd);
- if (!sd->inventory_data[n])
- return 0;
+ if(!sd->inventory_data[n])
+ return 0;
- if (!itemdb_isequip2(sd->inventory_data[n]))
- return 0; //Not equippable by players.
+ if (!itemdb_isequip2(sd->inventory_data[n]))
+ return 0; //Not equippable by players.
- ep = sd->inventory_data[n]->equip;
- if (sd->inventory_data[n]->look == W_DAGGER ||
- sd->inventory_data[n]->look == W_1HSWORD ||
- sd->inventory_data[n]->look == W_1HAXE) {
- if (ep == EQP_HAND_R && (pc_checkskill(sd,AS_LEFT) > 0 || (sd->class_&MAPID_UPPERMASK) == MAPID_ASSASSIN ||
- (sd->class_&MAPID_UPPERMASK) == MAPID_KAGEROUOBORO))//Kagerou and Oboro can dual wield daggers. [Rytech]
- return EQP_ARMS;
- }
- return ep;
+ ep = sd->inventory_data[n]->equip;
+ if(sd->inventory_data[n]->look == W_DAGGER ||
+ sd->inventory_data[n]->look == W_1HSWORD ||
+ sd->inventory_data[n]->look == W_1HAXE) {
+ if(ep == EQP_HAND_R && (pc_checkskill(sd,AS_LEFT) > 0 || (sd->class_&MAPID_UPPERMASK) == MAPID_ASSASSIN ||
+ (sd->class_&MAPID_UPPERMASK) == MAPID_KAGEROUOBORO))//Kagerou and Oboro can dual wield daggers. [Rytech]
+ return EQP_ARMS;
+ }
+ return ep;
}
int pc_setinventorydata(struct map_session_data *sd)
{
- int i,id;
+ int i,id;
- nullpo_ret(sd);
+ nullpo_ret(sd);
- for (i=0; i<MAX_INVENTORY; i++) {
- id = sd->status.inventory[i].nameid;
- sd->inventory_data[i] = id?itemdb_search(id):NULL;
- }
- return 0;
+ for(i=0;i<MAX_INVENTORY;i++) {
+ id = sd->status.inventory[i].nameid;
+ sd->inventory_data[i] = id?itemdb_search(id):NULL;
+ }
+ return 0;
}
int pc_calcweapontype(struct map_session_data *sd)
{
- nullpo_ret(sd);
-
- // single-hand
- if (sd->weapontype2 == W_FIST) {
- sd->status.weapon = sd->weapontype1;
- return 1;
- }
- if (sd->weapontype1 == W_FIST) {
- sd->status.weapon = sd->weapontype2;
- return 1;
- }
- // dual-wield
- sd->status.weapon = 0;
- switch (sd->weapontype1) {
- case W_DAGGER:
- switch (sd->weapontype2) {
- case W_DAGGER:
- sd->status.weapon = W_DOUBLE_DD;
- break;
- case W_1HSWORD:
- sd->status.weapon = W_DOUBLE_DS;
- break;
- case W_1HAXE:
- sd->status.weapon = W_DOUBLE_DA;
- break;
- }
- break;
- case W_1HSWORD:
- switch (sd->weapontype2) {
- case W_DAGGER:
- sd->status.weapon = W_DOUBLE_DS;
- break;
- case W_1HSWORD:
- sd->status.weapon = W_DOUBLE_SS;
- break;
- case W_1HAXE:
- sd->status.weapon = W_DOUBLE_SA;
- break;
- }
- break;
- case W_1HAXE:
- switch (sd->weapontype2) {
- case W_DAGGER:
- sd->status.weapon = W_DOUBLE_DA;
- break;
- case W_1HSWORD:
- sd->status.weapon = W_DOUBLE_SA;
- break;
- case W_1HAXE:
- sd->status.weapon = W_DOUBLE_AA;
- break;
- }
- }
- // unknown, default to right hand type
- if (!sd->status.weapon)
- sd->status.weapon = sd->weapontype1;
-
- return 2;
+ nullpo_ret(sd);
+
+ // single-hand
+ if(sd->weapontype2 == W_FIST) {
+ sd->status.weapon = sd->weapontype1;
+ return 1;
+ }
+ if(sd->weapontype1 == W_FIST) {
+ sd->status.weapon = sd->weapontype2;
+ return 1;
+ }
+ // dual-wield
+ sd->status.weapon = 0;
+ switch (sd->weapontype1){
+ case W_DAGGER:
+ switch (sd->weapontype2) {
+ case W_DAGGER: sd->status.weapon = W_DOUBLE_DD; break;
+ case W_1HSWORD: sd->status.weapon = W_DOUBLE_DS; break;
+ case W_1HAXE: sd->status.weapon = W_DOUBLE_DA; break;
+ }
+ break;
+ case W_1HSWORD:
+ switch (sd->weapontype2) {
+ case W_DAGGER: sd->status.weapon = W_DOUBLE_DS; break;
+ case W_1HSWORD: sd->status.weapon = W_DOUBLE_SS; break;
+ case W_1HAXE: sd->status.weapon = W_DOUBLE_SA; break;
+ }
+ break;
+ case W_1HAXE:
+ switch (sd->weapontype2) {
+ case W_DAGGER: sd->status.weapon = W_DOUBLE_DA; break;
+ case W_1HSWORD: sd->status.weapon = W_DOUBLE_SA; break;
+ case W_1HAXE: sd->status.weapon = W_DOUBLE_AA; break;
+ }
+ }
+ // unknown, default to right hand type
+ if (!sd->status.weapon)
+ sd->status.weapon = sd->weapontype1;
+
+ return 2;
}
int pc_setequipindex(struct map_session_data *sd)
{
- int i,j;
+ int i,j;
- nullpo_ret(sd);
+ nullpo_ret(sd);
- for (i=0; i<EQI_MAX; i++)
- sd->equip_index[i] = -1;
+ for(i=0;i<EQI_MAX;i++)
+ sd->equip_index[i] = -1;
- for (i=0; i<MAX_INVENTORY; i++) {
- if (sd->status.inventory[i].nameid <= 0)
- continue;
- if (sd->status.inventory[i].equip) {
- for (j=0; j<EQI_MAX; j++)
- if (sd->status.inventory[i].equip & equip_pos[j])
- sd->equip_index[j] = i;
+ for(i=0;i<MAX_INVENTORY;i++) {
+ if(sd->status.inventory[i].nameid <= 0)
+ continue;
+ if(sd->status.inventory[i].equip) {
+ for(j=0;j<EQI_MAX;j++)
+ if(sd->status.inventory[i].equip & equip_pos[j])
+ sd->equip_index[j] = i;
- if (sd->status.inventory[i].equip & EQP_HAND_R) {
- if (sd->inventory_data[i])
- sd->weapontype1 = sd->inventory_data[i]->look;
- else
- sd->weapontype1 = 0;
- }
+ if(sd->status.inventory[i].equip & EQP_HAND_R)
+ {
+ if(sd->inventory_data[i])
+ sd->weapontype1 = sd->inventory_data[i]->look;
+ else
+ sd->weapontype1 = 0;
+ }
- if (sd->status.inventory[i].equip & EQP_HAND_L) {
- if (sd->inventory_data[i] && sd->inventory_data[i]->type == IT_WEAPON)
- sd->weapontype2 = sd->inventory_data[i]->look;
- else
- sd->weapontype2 = 0;
- }
- }
- }
- pc_calcweapontype(sd);
+ if( sd->status.inventory[i].equip & EQP_HAND_L )
+ {
+ if( sd->inventory_data[i] && sd->inventory_data[i]->type == IT_WEAPON )
+ sd->weapontype2 = sd->inventory_data[i]->look;
+ else
+ sd->weapontype2 = 0;
+ }
+ }
+ }
+ pc_calcweapontype(sd);
- return 0;
+ return 0;
}
static int pc_isAllowedCardOn(struct map_session_data *sd,int s,int eqindex,int flag)
{
- int i;
- struct item *item = &sd->status.inventory[eqindex];
- struct item_data *data;
+ int i;
+ struct item *item = &sd->status.inventory[eqindex];
+ struct item_data *data;
- //Crafted/made/hatched items.
- if (itemdb_isspecial(item->card[0]))
- return 1;
+ //Crafted/made/hatched items.
+ if (itemdb_isspecial(item->card[0]))
+ return 1;
- /* scan for enchant armor gems */
- if (item->card[MAX_SLOTS - 1] && s < MAX_SLOTS - 1)
- s = MAX_SLOTS - 1;
+ /* scan for enchant armor gems */
+ if( item->card[MAX_SLOTS - 1] && s < MAX_SLOTS - 1 )
+ s = MAX_SLOTS - 1;
- ARR_FIND(0, s, i, item->card[i] && (data = itemdb_exists(item->card[i])) != NULL && data->flag.no_equip&flag);
- return(i < s) ? 0 : 1;
+ ARR_FIND( 0, s, i, item->card[i] && (data = itemdb_exists(item->card[i])) != NULL && data->flag.no_equip&flag );
+ return( i < s ) ? 0 : 1;
}
bool pc_isequipped(struct map_session_data *sd, int nameid)
{
- int i, j, index;
+ int i, j, index;
- for (i = 0; i < EQI_MAX; i++) {
- index = sd->equip_index[i];
- if (index < 0) continue;
+ for( i = 0; i < EQI_MAX; i++ )
+ {
+ index = sd->equip_index[i];
+ if( index < 0 ) continue;
- if (i == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == index) continue;
- if (i == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == index) continue;
- if (i == EQI_HEAD_TOP && (sd->equip_index[EQI_HEAD_MID] == index || sd->equip_index[EQI_HEAD_LOW] == index)) continue;
+ if( i == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == index ) continue;
+ if( i == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == index ) continue;
+ if( i == EQI_HEAD_TOP && (sd->equip_index[EQI_HEAD_MID] == index || sd->equip_index[EQI_HEAD_LOW] == index) ) continue;
- if (!sd->inventory_data[index]) continue;
+ if( !sd->inventory_data[index] ) continue;
- if (sd->inventory_data[index]->nameid == nameid)
- return true;
+ if( sd->inventory_data[index]->nameid == nameid )
+ return true;
- for (j = 0; j < sd->inventory_data[index]->slot; j++)
- if (sd->status.inventory[index].card[j] == nameid)
- return true;
- }
+ for( j = 0; j < sd->inventory_data[index]->slot; j++ )
+ if( sd->status.inventory[index].card[j] == nameid )
+ return true;
+ }
- return false;
+ return false;
}
-bool pc_can_Adopt(struct map_session_data *p1_sd, struct map_session_data *p2_sd, struct map_session_data *b_sd)
+bool pc_can_Adopt(struct map_session_data *p1_sd, struct map_session_data *p2_sd, struct map_session_data *b_sd )
{
- if (!p1_sd || !p2_sd || !b_sd)
- return false;
+ if( !p1_sd || !p2_sd || !b_sd )
+ return false;
- if (b_sd->status.father || b_sd->status.mother || b_sd->adopt_invite)
- return false; // already adopted baby / in adopt request
+ if( b_sd->status.father || b_sd->status.mother || b_sd->adopt_invite )
+ return false; // already adopted baby / in adopt request
- if (!p1_sd->status.partner_id || !p1_sd->status.party_id || p1_sd->status.party_id != b_sd->status.party_id)
- return false; // You need to be married and in party with baby to adopt
+ if( !p1_sd->status.partner_id || !p1_sd->status.party_id || p1_sd->status.party_id != b_sd->status.party_id )
+ return false; // You need to be married and in party with baby to adopt
- if (p1_sd->status.partner_id != p2_sd->status.char_id || p2_sd->status.partner_id != p1_sd->status.char_id)
- return false; // Not married, wrong married
+ if( p1_sd->status.partner_id != p2_sd->status.char_id || p2_sd->status.partner_id != p1_sd->status.char_id )
+ return false; // Not married, wrong married
- if (p2_sd->status.party_id != p1_sd->status.party_id)
- return false; // Both parents need to be in the same party
+ if( p2_sd->status.party_id != p1_sd->status.party_id )
+ return false; // Both parents need to be in the same party
- // Parents need to have their ring equipped
- if (!pc_isequipped(p1_sd, WEDDING_RING_M) && !pc_isequipped(p1_sd, WEDDING_RING_F))
- return false;
+ // Parents need to have their ring equipped
+ if( !pc_isequipped(p1_sd, WEDDING_RING_M) && !pc_isequipped(p1_sd, WEDDING_RING_F) )
+ return false;
- if (!pc_isequipped(p2_sd, WEDDING_RING_M) && !pc_isequipped(p2_sd, WEDDING_RING_F))
- return false;
+ if( !pc_isequipped(p2_sd, WEDDING_RING_M) && !pc_isequipped(p2_sd, WEDDING_RING_F) )
+ return false;
- // Already adopted a baby
- if (p1_sd->status.child || p2_sd->status.child) {
- clif_Adopt_reply(p1_sd, 0);
- return false;
- }
+ // Already adopted a baby
+ if( p1_sd->status.child || p2_sd->status.child ) {
+ clif_Adopt_reply(p1_sd, 0);
+ return false;
+ }
- // Parents need at least lvl 70 to adopt
- if (p1_sd->status.base_level < 70 || p2_sd->status.base_level < 70) {
- clif_Adopt_reply(p1_sd, 1);
- return false;
- }
+ // Parents need at least lvl 70 to adopt
+ if( p1_sd->status.base_level < 70 || p2_sd->status.base_level < 70 ) {
+ clif_Adopt_reply(p1_sd, 1);
+ return false;
+ }
- if (b_sd->status.partner_id) {
- clif_Adopt_reply(p1_sd, 2);
- return false;
- }
+ if( b_sd->status.partner_id ) {
+ clif_Adopt_reply(p1_sd, 2);
+ return false;
+ }
- if (!((b_sd->status.class_ >= JOB_NOVICE && b_sd->status.class_ <= JOB_THIEF) || b_sd->status.class_ == JOB_SUPER_NOVICE))
- return false;
+ if( !( ( b_sd->status.class_ >= JOB_NOVICE && b_sd->status.class_ <= JOB_THIEF ) || b_sd->status.class_ == JOB_SUPER_NOVICE ) )
+ return false;
- return true;
+ return true;
}
/*==========================================
@@ -802,42 +797,42 @@ bool pc_can_Adopt(struct map_session_data *p1_sd, struct map_session_data *p2_sd
*------------------------------------------*/
bool pc_adoption(struct map_session_data *p1_sd, struct map_session_data *p2_sd, struct map_session_data *b_sd)
{
- int job, joblevel;
- unsigned int jobexp;
+ int job, joblevel;
+ unsigned int jobexp;
- if (!pc_can_Adopt(p1_sd, p2_sd, b_sd))
- return false;
+ if( !pc_can_Adopt(p1_sd, p2_sd, b_sd) )
+ return false;
- // Preserve current job levels and progress
- joblevel = b_sd->status.job_level;
- jobexp = b_sd->status.job_exp;
+ // Preserve current job levels and progress
+ joblevel = b_sd->status.job_level;
+ jobexp = b_sd->status.job_exp;
- job = pc_mapid2jobid(b_sd->class_|JOBL_BABY, b_sd->status.sex);
- if (job != -1 && !pc_jobchange(b_sd, job, 0)) {
- // Success, proceed to configure parents and baby skills
- p1_sd->status.child = b_sd->status.char_id;
- p2_sd->status.child = b_sd->status.char_id;
- b_sd->status.father = p1_sd->status.char_id;
- b_sd->status.mother = p2_sd->status.char_id;
+ job = pc_mapid2jobid(b_sd->class_|JOBL_BABY, b_sd->status.sex);
+ if( job != -1 && !pc_jobchange(b_sd, job, 0) )
+ { // Success, proceed to configure parents and baby skills
+ p1_sd->status.child = b_sd->status.char_id;
+ p2_sd->status.child = b_sd->status.char_id;
+ b_sd->status.father = p1_sd->status.char_id;
+ b_sd->status.mother = p2_sd->status.char_id;
- // Restore progress
- b_sd->status.job_level = joblevel;
- clif_updatestatus(b_sd, SP_JOBLEVEL);
- b_sd->status.job_exp = jobexp;
- clif_updatestatus(b_sd, SP_JOBEXP);
+ // Restore progress
+ b_sd->status.job_level = joblevel;
+ clif_updatestatus(b_sd, SP_JOBLEVEL);
+ b_sd->status.job_exp = jobexp;
+ clif_updatestatus(b_sd, SP_JOBEXP);
- // Baby Skills
- pc_skill(b_sd, WE_BABY, 1, 0);
- pc_skill(b_sd, WE_CALLPARENT, 1, 0);
+ // Baby Skills
+ pc_skill(b_sd, WE_BABY, 1, 0);
+ pc_skill(b_sd, WE_CALLPARENT, 1, 0);
- // Parents Skills
- pc_skill(p1_sd, WE_CALLBABY, 1, 0);
- pc_skill(p2_sd, WE_CALLBABY, 1, 0);
+ // Parents Skills
+ pc_skill(p1_sd, WE_CALLBABY, 1, 0);
+ pc_skill(p2_sd, WE_CALLBABY, 1, 0);
- return true;
- }
+ return true;
+ }
- return false; // Job Change Fail
+ return false; // Job Change Fail
}
/*=================================================
@@ -846,83 +841,84 @@ bool pc_adoption(struct map_session_data *p1_sd, struct map_session_data *p2_sd,
*------------------------------------------------*/
int pc_isequip(struct map_session_data *sd,int n)
{
- struct item_data *item;
+ struct item_data *item;
- nullpo_ret(sd);
+ nullpo_ret(sd);
- item = sd->inventory_data[n];
+ item = sd->inventory_data[n];
- if (pc_has_permission(sd, PC_PERM_USE_ALL_EQUIPMENT))
- return 1;
+ if(pc_has_permission(sd, PC_PERM_USE_ALL_EQUIPMENT))
+ return 1;
- if (item == NULL)
- return 0;
- if (item->elv && sd->status.base_level < (unsigned int)item->elv)
- return 0;
+ if(item == NULL)
+ return 0;
+ if(item->elv && sd->status.base_level < (unsigned int)item->elv)
+ return 0;
#ifdef RENEWAL
- if (item->elvmax && sd->status.base_level > (unsigned int)item->elvmax)
- return 0;
+ if(item->elvmax && sd->status.base_level > (unsigned int)item->elvmax)
+ return 0;
#endif
- if (item->sex != 2 && sd->status.sex != item->sex)
- return 0;
- if (!map_flag_vs(sd->bl.m) && ((item->flag.no_equip&1) || !pc_isAllowedCardOn(sd,item->slot,n,1)))
- return 0;
- if (map[sd->bl.m].flag.pvp && ((item->flag.no_equip&2) || !pc_isAllowedCardOn(sd,item->slot,n,2)))
- return 0;
- if (map_flag_gvg(sd->bl.m) && ((item->flag.no_equip&4) || !pc_isAllowedCardOn(sd,item->slot,n,4)))
- return 0;
- if (map[sd->bl.m].flag.battleground && ((item->flag.no_equip&8) || !pc_isAllowedCardOn(sd,item->slot,n,8)))
- return 0;
- if (map[sd->bl.m].flag.restricted) {
- int flag =8*map[sd->bl.m].zone;
- if (item->flag.no_equip&flag || !pc_isAllowedCardOn(sd,item->slot,n,flag))
- return 0;
- }
-
- if (sd->sc.count) {
-
- if (item->equip & EQP_ARMS && item->type == IT_WEAPON && sd->sc.data[SC_STRIPWEAPON]) // Also works with left-hand weapons [DracoRPG]
- return 0;
- if (item->equip & EQP_SHIELD && item->type == IT_ARMOR && sd->sc.data[SC_STRIPSHIELD])
- return 0;
- if (item->equip & EQP_ARMOR && sd->sc.data[SC_STRIPARMOR])
- return 0;
- if (item->equip & EQP_HEAD_TOP && sd->sc.data[SC_STRIPHELM])
- return 0;
- if (item->equip & EQP_ACC && sd->sc.data[SC__STRIPACCESSORY])
- return 0;
- if (item->equip && sd->sc.data[SC_KYOUGAKU])
- return 0;
-
- if (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_SUPERNOVICE) {
- //Spirit of Super Novice equip bonuses. [Skotlex]
- if (sd->status.base_level > 90 && item->equip & EQP_HELM)
- return 1; //Can equip all helms
-
- if (sd->status.base_level > 96 && item->equip & EQP_ARMS && item->type == IT_WEAPON)
- switch (item->look) { //In weapons, the look determines type of weapon.
- case W_DAGGER: //Level 4 Knives are equippable.. this means all knives, I'd guess?
- case W_1HSWORD: //All 1H swords
- case W_1HAXE: //All 1H Axes
- case W_MACE: //All 1H Maces
- case W_STAFF: //All 1H Staves
- return 1;
- }
- }
- }
- //Not equipable by class. [Skotlex]
- if (!(1<<(sd->class_&MAPID_BASEMASK)&item->class_base[(sd->class_&JOBL_2_1)?1:((sd->class_&JOBL_2_2)?2:0)]))
- return 0;
- //Not usable by upper class. [Inkfish]
- while (1) {
- if (item->class_upper&1 && !(sd->class_&(JOBL_UPPER|JOBL_THIRD|JOBL_BABY))) break;
- if (item->class_upper&2 && sd->class_&(JOBL_UPPER|JOBL_THIRD)) break;
- if (item->class_upper&4 && sd->class_&JOBL_BABY) break;
- if (item->class_upper&8 && sd->class_&JOBL_THIRD) break;
- return 0;
- }
-
- return 1;
+ if(item->sex != 2 && sd->status.sex != item->sex)
+ return 0;
+ if(!map_flag_vs(sd->bl.m) && ((item->flag.no_equip&1) || !pc_isAllowedCardOn(sd,item->slot,n,1)))
+ return 0;
+ if(map[sd->bl.m].flag.pvp && ((item->flag.no_equip&2) || !pc_isAllowedCardOn(sd,item->slot,n,2)))
+ return 0;
+ if(map_flag_gvg(sd->bl.m) && ((item->flag.no_equip&4) || !pc_isAllowedCardOn(sd,item->slot,n,4)))
+ return 0;
+ if(map[sd->bl.m].flag.battleground && ((item->flag.no_equip&8) || !pc_isAllowedCardOn(sd,item->slot,n,8)))
+ return 0;
+ if(map[sd->bl.m].flag.restricted)
+ {
+ int flag =8*map[sd->bl.m].zone;
+ if (item->flag.no_equip&flag || !pc_isAllowedCardOn(sd,item->slot,n,flag))
+ return 0;
+ }
+
+ if (sd->sc.count) {
+
+ if(item->equip & EQP_ARMS && item->type == IT_WEAPON && sd->sc.data[SC_STRIPWEAPON]) // Also works with left-hand weapons [DracoRPG]
+ return 0;
+ if(item->equip & EQP_SHIELD && item->type == IT_ARMOR && sd->sc.data[SC_STRIPSHIELD])
+ return 0;
+ if(item->equip & EQP_ARMOR && sd->sc.data[SC_STRIPARMOR])
+ return 0;
+ if(item->equip & EQP_HEAD_TOP && sd->sc.data[SC_STRIPHELM])
+ return 0;
+ if(item->equip & EQP_ACC && sd->sc.data[SC__STRIPACCESSORY])
+ return 0;
+ if(item->equip && sd->sc.data[SC_KYOUGAKU])
+ return 0;
+
+ if (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_SUPERNOVICE) {
+ //Spirit of Super Novice equip bonuses. [Skotlex]
+ if (sd->status.base_level > 90 && item->equip & EQP_HELM)
+ return 1; //Can equip all helms
+
+ if (sd->status.base_level > 96 && item->equip & EQP_ARMS && item->type == IT_WEAPON)
+ switch(item->look) { //In weapons, the look determines type of weapon.
+ case W_DAGGER: //Level 4 Knives are equippable.. this means all knives, I'd guess?
+ case W_1HSWORD: //All 1H swords
+ case W_1HAXE: //All 1H Axes
+ case W_MACE: //All 1H Maces
+ case W_STAFF: //All 1H Staves
+ return 1;
+ }
+ }
+ }
+ //Not equipable by class. [Skotlex]
+ if (!(1<<(sd->class_&MAPID_BASEMASK)&item->class_base[(sd->class_&JOBL_2_1)?1:((sd->class_&JOBL_2_2)?2:0)]))
+ return 0;
+ //Not usable by upper class. [Inkfish]
+ while( 1 ) {
+ if( item->class_upper&1 && !(sd->class_&(JOBL_UPPER|JOBL_THIRD|JOBL_BABY)) ) break;
+ if( item->class_upper&2 && sd->class_&(JOBL_UPPER|JOBL_THIRD) ) break;
+ if( item->class_upper&4 && sd->class_&JOBL_BABY ) break;
+ if( item->class_upper&8 && sd->class_&JOBL_THIRD ) break;
+ return 0;
+ }
+
+ return 1;
}
/*==========================================
@@ -931,187 +927,190 @@ int pc_isequip(struct map_session_data *sd,int n)
*------------------------------------------*/
bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_time, int group_id, struct mmo_charstatus *st, bool changing_mapservers)
{
- int i;
- unsigned long tick = gettick();
- uint32 ip = session[sd->fd]->client_addr;
-
- sd->login_id2 = login_id2;
- sd->group_id = group_id;
-
- /* load user permissions */
- pc_group_pc_load(sd);
-
- memcpy(&sd->status, st, sizeof(*st));
-
- if (st->sex != sd->status.sex) {
- clif_authfail_fd(sd->fd, 0);
- return false;
- }
-
- //Set the map-server used job id. [Skotlex]
- i = pc_jobid2mapid(sd->status.class_);
- if (i == -1) { //Invalid class?
- ShowError("pc_authok: Invalid class %d for player %s (%d:%d). Class was changed to novice.\n", sd->status.class_, sd->status.name, sd->status.account_id, sd->status.char_id);
- sd->status.class_ = JOB_NOVICE;
- sd->class_ = MAPID_NOVICE;
- } else
- sd->class_ = i;
-
- // Checks and fixes to character status data, that are required
- // in case of configuration change or stuff, which cannot be
- // checked on char-server.
- if (sd->status.hair < MIN_HAIR_STYLE || sd->status.hair > MAX_HAIR_STYLE) {
- sd->status.hair = MIN_HAIR_STYLE;
- }
- if (sd->status.hair_color < MIN_HAIR_COLOR || sd->status.hair_color > MAX_HAIR_COLOR) {
- sd->status.hair_color = MIN_HAIR_COLOR;
- }
- if (sd->status.clothes_color < MIN_CLOTH_COLOR || sd->status.clothes_color > MAX_CLOTH_COLOR) {
- sd->status.clothes_color = MIN_CLOTH_COLOR;
- }
-
- //Initializations to null/0 unneeded since map_session_data was filled with 0 upon allocation.
- if (!sd->status.hp) pc_setdead(sd);
- sd->state.connect_new = 1;
-
- sd->followtimer = INVALID_TIMER; // [MouseJstr]
- sd->invincible_timer = INVALID_TIMER;
- sd->npc_timer_id = INVALID_TIMER;
- sd->pvp_timer = INVALID_TIMER;
- /**
- * For the Secure NPC Timeout option (check config/Secure.h) [RR]
- **/
+ int i;
+ unsigned long tick = gettick();
+ uint32 ip = session[sd->fd]->client_addr;
+
+ sd->login_id2 = login_id2;
+ sd->group_id = group_id;
+
+ /* load user permissions */
+ pc_group_pc_load(sd);
+
+ memcpy(&sd->status, st, sizeof(*st));
+
+ if (st->sex != sd->status.sex) {
+ clif_authfail_fd(sd->fd, 0);
+ return false;
+ }
+
+ //Set the map-server used job id. [Skotlex]
+ i = pc_jobid2mapid(sd->status.class_);
+ if (i == -1) { //Invalid class?
+ ShowError("pc_authok: Invalid class %d for player %s (%d:%d). Class was changed to novice.\n", sd->status.class_, sd->status.name, sd->status.account_id, sd->status.char_id);
+ sd->status.class_ = JOB_NOVICE;
+ sd->class_ = MAPID_NOVICE;
+ } else
+ sd->class_ = i;
+
+ // Checks and fixes to character status data, that are required
+ // in case of configuration change or stuff, which cannot be
+ // checked on char-server.
+ if( sd->status.hair < MIN_HAIR_STYLE || sd->status.hair > MAX_HAIR_STYLE )
+ {
+ sd->status.hair = MIN_HAIR_STYLE;
+ }
+ if( sd->status.hair_color < MIN_HAIR_COLOR || sd->status.hair_color > MAX_HAIR_COLOR )
+ {
+ sd->status.hair_color = MIN_HAIR_COLOR;
+ }
+ if( sd->status.clothes_color < MIN_CLOTH_COLOR || sd->status.clothes_color > MAX_CLOTH_COLOR )
+ {
+ sd->status.clothes_color = MIN_CLOTH_COLOR;
+ }
+
+ //Initializations to null/0 unneeded since map_session_data was filled with 0 upon allocation.
+ if(!sd->status.hp) pc_setdead(sd);
+ sd->state.connect_new = 1;
+
+ sd->followtimer = INVALID_TIMER; // [MouseJstr]
+ sd->invincible_timer = INVALID_TIMER;
+ sd->npc_timer_id = INVALID_TIMER;
+ sd->pvp_timer = INVALID_TIMER;
+ /**
+ * For the Secure NPC Timeout option (check config/Secure.h) [RR]
+ **/
#if SECURE_NPCTIMEOUT
- /**
- * Initialize to defaults/expected
- **/
- sd->npc_idle_timer = INVALID_TIMER;
- sd->npc_idle_tick = tick;
+ /**
+ * Initialize to defaults/expected
+ **/
+ sd->npc_idle_timer = INVALID_TIMER;
+ sd->npc_idle_tick = tick;
#endif
- sd->canuseitem_tick = tick;
- sd->canusecashfood_tick = tick;
- sd->canequip_tick = tick;
- sd->cantalk_tick = tick;
- sd->canskill_tick = tick;
- sd->cansendmail_tick = tick;
+ sd->canuseitem_tick = tick;
+ sd->canusecashfood_tick = tick;
+ sd->canequip_tick = tick;
+ sd->cantalk_tick = tick;
+ sd->canskill_tick = tick;
+ sd->cansendmail_tick = tick;
- for (i = 0; i < MAX_SKILL_LEVEL; i++)
- sd->spirit_timer[i] = INVALID_TIMER;
- for (i = 0; i < ARRAYLENGTH(sd->autobonus); i++)
- sd->autobonus[i].active = INVALID_TIMER;
- for (i = 0; i < ARRAYLENGTH(sd->autobonus2); i++)
- sd->autobonus2[i].active = INVALID_TIMER;
- for (i = 0; i < ARRAYLENGTH(sd->autobonus3); i++)
- sd->autobonus3[i].active = INVALID_TIMER;
+ for(i = 0; i < MAX_SKILL_LEVEL; i++)
+ sd->spirit_timer[i] = INVALID_TIMER;
+ for(i = 0; i < ARRAYLENGTH(sd->autobonus); i++)
+ sd->autobonus[i].active = INVALID_TIMER;
+ for(i = 0; i < ARRAYLENGTH(sd->autobonus2); i++)
+ sd->autobonus2[i].active = INVALID_TIMER;
+ for(i = 0; i < ARRAYLENGTH(sd->autobonus3); i++)
+ sd->autobonus3[i].active = INVALID_TIMER;
- if (battle_config.item_auto_get)
- sd->state.autoloot = 10000;
+ if (battle_config.item_auto_get)
+ sd->state.autoloot = 10000;
- if (battle_config.disp_experience)
- sd->state.showexp = 1;
- if (battle_config.disp_zeny)
- sd->state.showzeny = 1;
+ if (battle_config.disp_experience)
+ sd->state.showexp = 1;
+ if (battle_config.disp_zeny)
+ sd->state.showzeny = 1;
- if (!(battle_config.display_skill_fail&2))
- sd->state.showdelay = 1;
+ if (!(battle_config.display_skill_fail&2))
+ sd->state.showdelay = 1;
- pc_setinventorydata(sd);
- pc_setequipindex(sd);
+ pc_setinventorydata(sd);
+ pc_setequipindex(sd);
- status_change_init(&sd->bl);
+ status_change_init(&sd->bl);
- if (pc_can_use_command(sd, "hide", COMMAND_ATCOMMAND))
- sd->status.option &= (OPTION_MASK | OPTION_INVISIBLE);
- else
- sd->status.option &= OPTION_MASK;
+ if (pc_can_use_command(sd, "hide", COMMAND_ATCOMMAND))
+ sd->status.option &= (OPTION_MASK | OPTION_INVISIBLE);
+ else
+ sd->status.option &= OPTION_MASK;
- sd->sc.option = sd->status.option; //This is the actual option used in battle.
- //Set here because we need the inventory data for weapon sprite parsing.
- status_set_viewdata(&sd->bl, sd->status.class_);
- unit_dataset(&sd->bl);
+ sd->sc.option = sd->status.option; //This is the actual option used in battle.
+ //Set here because we need the inventory data for weapon sprite parsing.
+ status_set_viewdata(&sd->bl, sd->status.class_);
+ unit_dataset(&sd->bl);
- sd->guild_x = -1;
- sd->guild_y = -1;
+ sd->guild_x = -1;
+ sd->guild_y = -1;
- // Event Timers
- for (i = 0; i < MAX_EVENTTIMER; i++)
- sd->eventtimer[i] = INVALID_TIMER;
- // Rental Timer
- sd->rental_timer = INVALID_TIMER;
+ // Event Timers
+ for( i = 0; i < MAX_EVENTTIMER; i++ )
+ sd->eventtimer[i] = INVALID_TIMER;
+ // Rental Timer
+ sd->rental_timer = INVALID_TIMER;
- for (i = 0; i < 3; i++)
- sd->hate_mob[i] = -1;
+ for( i = 0; i < 3; i++ )
+ sd->hate_mob[i] = -1;
//warp player
- if ((i=pc_setpos(sd,sd->status.last_point.map, sd->status.last_point.x, sd->status.last_point.y, CLR_OUTSIGHT)) != 0) {
- ShowError("Last_point_map %s - id %d not found (error code %d)\n", mapindex_id2name(sd->status.last_point.map), sd->status.last_point.map, i);
-
- // try warping to a default map instead (church graveyard)
- if (pc_setpos(sd, mapindex_name2id(MAP_PRONTERA), 273, 354, CLR_OUTSIGHT) != 0) {
- // if we fail again
- clif_authfail_fd(sd->fd, 0);
- return false;
- }
- }
-
- clif_authok(sd);
-
- //Prevent S. Novices from getting the no-death bonus just yet. [Skotlex]
- sd->die_counter=-1;
-
- //display login notice
- ShowInfo("'"CL_WHITE"%s"CL_RESET"' logged in."
- " (AID/CID: '"CL_WHITE"%d/%d"CL_RESET"',"
- " Packet Ver: '"CL_WHITE"%d"CL_RESET"', IP: '"CL_WHITE"%d.%d.%d.%d"CL_RESET"',"
- " Group '"CL_WHITE"%d"CL_RESET"').\n",
- sd->status.name, sd->status.account_id, sd->status.char_id,
- sd->packet_ver, CONVIP(ip), sd->group_id);
- // Send friends list
- clif_friendslist_send(sd);
-
- if (!changing_mapservers) {
-
- if (battle_config.display_version == 1) {
- char buf[256];
- sprintf(buf, "SVN version: %s", get_svn_revision());
- clif_displaymessage(sd->fd, buf);
- }
-
- // Message of the Day [Valaris]
- for (i=0; motd_text[i][0] && i < MOTD_LINE_SIZE; i++) {
- if (battle_config.motd_type)
- clif_disp_onlyself(sd,motd_text[i],strlen(motd_text[i]));
- else
- clif_displaymessage(sd->fd, motd_text[i]);
- }
-
- // message of the limited time of the account
- if (expiration_time != 0) { // don't display if it's unlimited or unknow value
- char tmpstr[1024];
- strftime(tmpstr, sizeof(tmpstr) - 1, msg_txt(501), localtime(&expiration_time)); // "Your account time limit is: %d-%m-%Y %H:%M:%S."
- clif_wis_message(sd->fd, wisp_server_name, tmpstr, strlen(tmpstr)+1);
- }
-
- /**
- * Fixes login-without-aura glitch (the screen won't blink at this point, don't worry :P)
- **/
- clif_changemap(sd,sd->mapindex,sd->bl.x,sd->bl.y);
- }
-
- /**
- * Check if player have any cool downs on
- **/
- skill_cooldown_load(sd);
-
- /**
- * Check if player have any item cooldowns on
- **/
- pc_itemcd_do(sd,true);
-
- // Request all registries (auth is considered completed whence they arrive)
- intif_request_registry(sd,7);
- return true;
+ if ((i=pc_setpos(sd,sd->status.last_point.map, sd->status.last_point.x, sd->status.last_point.y, CLR_OUTSIGHT)) != 0) {
+ ShowError ("Last_point_map %s - id %d not found (error code %d)\n", mapindex_id2name(sd->status.last_point.map), sd->status.last_point.map, i);
+
+ // try warping to a default map instead (church graveyard)
+ if (pc_setpos(sd, mapindex_name2id(MAP_PRONTERA), 273, 354, CLR_OUTSIGHT) != 0) {
+ // if we fail again
+ clif_authfail_fd(sd->fd, 0);
+ return false;
+ }
+ }
+
+ clif_authok(sd);
+
+ //Prevent S. Novices from getting the no-death bonus just yet. [Skotlex]
+ sd->die_counter=-1;
+
+ //display login notice
+ ShowInfo("'"CL_WHITE"%s"CL_RESET"' logged in."
+ " (AID/CID: '"CL_WHITE"%d/%d"CL_RESET"',"
+ " Packet Ver: '"CL_WHITE"%d"CL_RESET"', IP: '"CL_WHITE"%d.%d.%d.%d"CL_RESET"',"
+ " Group '"CL_WHITE"%d"CL_RESET"').\n",
+ sd->status.name, sd->status.account_id, sd->status.char_id,
+ sd->packet_ver, CONVIP(ip), sd->group_id);
+ // Send friends list
+ clif_friendslist_send(sd);
+
+ if( !changing_mapservers ) {
+
+ if (battle_config.display_version == 1){
+ char buf[256];
+ sprintf(buf, "SVN version: %s", get_svn_revision());
+ clif_displaymessage(sd->fd, buf);
+ }
+
+ // Message of the Day [Valaris]
+ for(i=0; motd_text[i][0] && i < MOTD_LINE_SIZE; i++) {
+ if (battle_config.motd_type)
+ clif_disp_onlyself(sd,motd_text[i],strlen(motd_text[i]));
+ else
+ clif_displaymessage(sd->fd, motd_text[i]);
+ }
+
+ // message of the limited time of the account
+ if (expiration_time != 0) { // don't display if it's unlimited or unknow value
+ char tmpstr[1024];
+ strftime(tmpstr, sizeof(tmpstr) - 1, msg_txt(501), localtime(&expiration_time)); // "Your account time limit is: %d-%m-%Y %H:%M:%S."
+ clif_wis_message(sd->fd, wisp_server_name, tmpstr, strlen(tmpstr)+1);
+ }
+
+ /**
+ * Fixes login-without-aura glitch (the screen won't blink at this point, don't worry :P)
+ **/
+ clif_changemap(sd,sd->mapindex,sd->bl.x,sd->bl.y);
+ }
+
+ /**
+ * Check if player have any cool downs on
+ **/
+ skill_cooldown_load(sd);
+
+ /**
+ * Check if player have any item cooldowns on
+ **/
+ pc_itemcd_do(sd,true);
+
+ // Request all registries (auth is considered completed whence they arrive)
+ intif_request_registry(sd,7);
+ return true;
}
/*==========================================
@@ -1119,34 +1118,34 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
*------------------------------------------*/
void pc_authfail(struct map_session_data *sd)
{
- clif_authfail_fd(sd->fd, 0);
- return;
+ clif_authfail_fd(sd->fd, 0);
+ return;
}
//Attempts to set a mob.
int pc_set_hate_mob(struct map_session_data *sd, int pos, struct block_list *bl)
{
- int class_;
- if (!sd || !bl || pos < 0 || pos > 2)
- return 0;
- if (sd->hate_mob[pos] != -1) {
- //Can't change hate targets.
- clif_hate_info(sd, pos, sd->hate_mob[pos], 0); //Display current
- return 0;
- }
-
- class_ = status_get_class(bl);
- if (!pcdb_checkid(class_)) {
- unsigned int max_hp = status_get_max_hp(bl);
- if ((pos == 1 && max_hp < 6000) || (pos == 2 && max_hp < 20000))
- return 0;
- if (pos != status_get_size(bl))
- return 0; //Wrong size
- }
- sd->hate_mob[pos] = class_;
- pc_setglobalreg(sd,sg_info[pos].hate_var,class_+1);
- clif_hate_info(sd, pos, class_, 1);
- return 1;
+ int class_;
+ if (!sd || !bl || pos < 0 || pos > 2)
+ return 0;
+ if (sd->hate_mob[pos] != -1)
+ { //Can't change hate targets.
+ clif_hate_info(sd, pos, sd->hate_mob[pos], 0); //Display current
+ return 0;
+ }
+
+ class_ = status_get_class(bl);
+ if (!pcdb_checkid(class_)) {
+ unsigned int max_hp = status_get_max_hp(bl);
+ if ((pos == 1 && max_hp < 6000) || (pos == 2 && max_hp < 20000))
+ return 0;
+ if (pos != status_get_size(bl))
+ return 0; //Wrong size
+ }
+ sd->hate_mob[pos] = class_;
+ pc_setglobalreg(sd,sg_info[pos].hate_var,class_+1);
+ clif_hate_info(sd, pos, class_, 1);
+ return 1;
}
/*==========================================
@@ -1154,124 +1153,126 @@ int pc_set_hate_mob(struct map_session_data *sd, int pos, struct block_list *bl)
*------------------------------------------*/
int pc_reg_received(struct map_session_data *sd)
{
- int i,j;
-
- sd->change_level_2nd = pc_readglobalreg(sd,"jobchange_level");
- sd->change_level_3rd = pc_readglobalreg(sd,"jobchange_level_3rd");
- sd->die_counter = pc_readglobalreg(sd,"PC_DIE_COUNTER");
-
- // Cash shop
- sd->cashPoints = pc_readaccountreg(sd,"#CASHPOINTS");
- sd->kafraPoints = pc_readaccountreg(sd,"#KAFRAPOINTS");
-
- // Cooking Exp
- sd->cook_mastery = pc_readglobalreg(sd,"COOK_MASTERY");
-
- if ((sd->class_&MAPID_BASEMASK) == MAPID_TAEKWON) {
- // Better check for class rather than skill to prevent "skill resets" from unsetting this
- sd->mission_mobid = pc_readglobalreg(sd,"TK_MISSION_ID");
- sd->mission_count = pc_readglobalreg(sd,"TK_MISSION_COUNT");
- }
-
- //SG map and mob read [Komurka]
- for (i=0; i<MAX_PC_FEELHATE; i++) { //for now - someone need to make reading from txt/sql
- if ((j = pc_readglobalreg(sd,sg_info[i].feel_var))!=0) {
- sd->feel_map[i].index = j;
- sd->feel_map[i].m = map_mapindex2mapid(j);
- } else {
- sd->feel_map[i].index = 0;
- sd->feel_map[i].m = -1;
- }
- sd->hate_mob[i] = pc_readglobalreg(sd,sg_info[i].hate_var)-1;
- }
-
- if ((i = pc_checkskill(sd,RG_PLAGIARISM)) > 0) {
- sd->cloneskill_id = pc_readglobalreg(sd,"CLONE_SKILL");
- if (sd->cloneskill_id > 0) {
- sd->status.skill[sd->cloneskill_id].id = sd->cloneskill_id;
- sd->status.skill[sd->cloneskill_id].lv = pc_readglobalreg(sd,"CLONE_SKILL_LV");
- if (sd->status.skill[sd->cloneskill_id].lv > i)
- sd->status.skill[sd->cloneskill_id].lv = i;
- sd->status.skill[sd->cloneskill_id].flag = SKILL_FLAG_PLAGIARIZED;
- }
- }
- if ((i = pc_checkskill(sd,SC_REPRODUCE)) > 0) {
- sd->reproduceskill_id = pc_readglobalreg(sd,"REPRODUCE_SKILL");
- if (sd->reproduceskill_id > 0) {
- sd->status.skill[sd->reproduceskill_id].id = sd->reproduceskill_id;
- sd->status.skill[sd->reproduceskill_id].lv = pc_readglobalreg(sd,"REPRODUCE_SKILL_LV");
- if (i < sd->status.skill[sd->reproduceskill_id].lv)
- sd->status.skill[sd->reproduceskill_id].lv = i;
- sd->status.skill[sd->reproduceskill_id].flag = SKILL_FLAG_PLAGIARIZED;
- }
- }
- //Weird... maybe registries were reloaded?
- if (sd->state.active)
- return 0;
- sd->state.active = 1;
-
- if (sd->status.party_id)
- party_member_joined(sd);
- if (sd->status.guild_id)
- guild_member_joined(sd);
-
- // pet
- if (sd->status.pet_id > 0)
- intif_request_petdata(sd->status.account_id, sd->status.char_id, sd->status.pet_id);
-
- // Homunculus [albator]
- if (sd->status.hom_id > 0)
- intif_homunculus_requestload(sd->status.account_id, sd->status.hom_id);
- if (sd->status.mer_id > 0)
- intif_mercenary_request(sd->status.mer_id, sd->status.char_id);
- if (sd->status.ele_id > 0)
- intif_elemental_request(sd->status.ele_id, sd->status.char_id);
-
- map_addiddb(&sd->bl);
- map_delnickdb(sd->status.char_id, sd->status.name);
- if (!chrif_auth_finished(sd))
- ShowError("pc_reg_received: Failed to properly remove player %d:%d from logging db!\n", sd->status.account_id, sd->status.char_id);
-
- pc_load_combo(sd);
-
- status_calc_pc(sd,1);
- chrif_scdata_request(sd->status.account_id, sd->status.char_id);
-
- intif_Mail_requestinbox(sd->status.char_id, 0); // MAIL SYSTEM - Request Mail Inbox
- intif_request_questlog(sd);
-
- if (sd->state.connect_new == 0 && sd->fd) {
- //Character already loaded map! Gotta trigger LoadEndAck manually.
- sd->state.connect_new = 1;
- clif_parse_LoadEndAck(sd->fd, sd);
- }
-
- pc_inventory_rentals(sd);
-
- return 1;
-}
-
-static int pc_calc_skillpoint(struct map_session_data *sd)
-{
- int i,skill,inf2,skill_point=0;
-
- nullpo_ret(sd);
-
- for (i=1; i<MAX_SKILL; i++) {
- if ((skill = pc_checkskill(sd,i)) > 0) {
- inf2 = skill_get_inf2(i);
- if ((!(inf2&INF2_QUEST_SKILL) || battle_config.quest_skill_learn) &&
- !(inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL)) //Do not count wedding/link skills. [Skotlex]
- ) {
- if (sd->status.skill[i].flag == SKILL_FLAG_PERMANENT)
- skill_point += skill;
- else if (sd->status.skill[i].flag >= SKILL_FLAG_REPLACED_LV_0)
- skill_point += (sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0);
- }
- }
- }
-
- return skill_point;
+ int i,j;
+
+ sd->change_level_2nd = pc_readglobalreg(sd,"jobchange_level");
+ sd->change_level_3rd = pc_readglobalreg(sd,"jobchange_level_3rd");
+ sd->die_counter = pc_readglobalreg(sd,"PC_DIE_COUNTER");
+
+ // Cash shop
+ sd->cashPoints = pc_readaccountreg(sd,"#CASHPOINTS");
+ sd->kafraPoints = pc_readaccountreg(sd,"#KAFRAPOINTS");
+
+ // Cooking Exp
+ sd->cook_mastery = pc_readglobalreg(sd,"COOK_MASTERY");
+
+ if( (sd->class_&MAPID_BASEMASK) == MAPID_TAEKWON )
+ { // Better check for class rather than skill to prevent "skill resets" from unsetting this
+ sd->mission_mobid = pc_readglobalreg(sd,"TK_MISSION_ID");
+ sd->mission_count = pc_readglobalreg(sd,"TK_MISSION_COUNT");
+ }
+
+ //SG map and mob read [Komurka]
+ for(i=0;i<MAX_PC_FEELHATE;i++) //for now - someone need to make reading from txt/sql
+ {
+ if ((j = pc_readglobalreg(sd,sg_info[i].feel_var))!=0) {
+ sd->feel_map[i].index = j;
+ sd->feel_map[i].m = map_mapindex2mapid(j);
+ } else {
+ sd->feel_map[i].index = 0;
+ sd->feel_map[i].m = -1;
+ }
+ sd->hate_mob[i] = pc_readglobalreg(sd,sg_info[i].hate_var)-1;
+ }
+
+ if ((i = pc_checkskill(sd,RG_PLAGIARISM)) > 0) {
+ sd->cloneskill_id = pc_readglobalreg(sd,"CLONE_SKILL");
+ if (sd->cloneskill_id > 0) {
+ sd->status.skill[sd->cloneskill_id].id = sd->cloneskill_id;
+ sd->status.skill[sd->cloneskill_id].lv = pc_readglobalreg(sd,"CLONE_SKILL_LV");
+ if (sd->status.skill[sd->cloneskill_id].lv > i)
+ sd->status.skill[sd->cloneskill_id].lv = i;
+ sd->status.skill[sd->cloneskill_id].flag = SKILL_FLAG_PLAGIARIZED;
+ }
+ }
+ if ((i = pc_checkskill(sd,SC_REPRODUCE)) > 0) {
+ sd->reproduceskill_id = pc_readglobalreg(sd,"REPRODUCE_SKILL");
+ if( sd->reproduceskill_id > 0) {
+ sd->status.skill[sd->reproduceskill_id].id = sd->reproduceskill_id;
+ sd->status.skill[sd->reproduceskill_id].lv = pc_readglobalreg(sd,"REPRODUCE_SKILL_LV");
+ if( i < sd->status.skill[sd->reproduceskill_id].lv)
+ sd->status.skill[sd->reproduceskill_id].lv = i;
+ sd->status.skill[sd->reproduceskill_id].flag = SKILL_FLAG_PLAGIARIZED;
+ }
+ }
+ //Weird... maybe registries were reloaded?
+ if (sd->state.active)
+ return 0;
+ sd->state.active = 1;
+
+ if (sd->status.party_id)
+ party_member_joined(sd);
+ if (sd->status.guild_id)
+ guild_member_joined(sd);
+
+ // pet
+ if (sd->status.pet_id > 0)
+ intif_request_petdata(sd->status.account_id, sd->status.char_id, sd->status.pet_id);
+
+ // Homunculus [albator]
+ if( sd->status.hom_id > 0 )
+ intif_homunculus_requestload(sd->status.account_id, sd->status.hom_id);
+ if( sd->status.mer_id > 0 )
+ intif_mercenary_request(sd->status.mer_id, sd->status.char_id);
+ if( sd->status.ele_id > 0 )
+ intif_elemental_request(sd->status.ele_id, sd->status.char_id);
+
+ map_addiddb(&sd->bl);
+ map_delnickdb(sd->status.char_id, sd->status.name);
+ if (!chrif_auth_finished(sd))
+ ShowError("pc_reg_received: Failed to properly remove player %d:%d from logging db!\n", sd->status.account_id, sd->status.char_id);
+
+ pc_load_combo(sd);
+
+ status_calc_pc(sd,1);
+ chrif_scdata_request(sd->status.account_id, sd->status.char_id);
+
+ intif_Mail_requestinbox(sd->status.char_id, 0); // MAIL SYSTEM - Request Mail Inbox
+ intif_request_questlog(sd);
+
+ if (sd->state.connect_new == 0 && sd->fd)
+ { //Character already loaded map! Gotta trigger LoadEndAck manually.
+ sd->state.connect_new = 1;
+ clif_parse_LoadEndAck(sd->fd, sd);
+ }
+
+ pc_inventory_rentals(sd);
+
+ return 1;
+}
+
+static int pc_calc_skillpoint(struct map_session_data* sd)
+{
+ int i,skill,inf2,skill_point=0;
+
+ nullpo_ret(sd);
+
+ for(i=1;i<MAX_SKILL;i++){
+ if( (skill = pc_checkskill(sd,i)) > 0) {
+ inf2 = skill_get_inf2(i);
+ if((!(inf2&INF2_QUEST_SKILL) || battle_config.quest_skill_learn) &&
+ !(inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL)) //Do not count wedding/link skills. [Skotlex]
+ ) {
+ if(sd->status.skill[i].flag == SKILL_FLAG_PERMANENT)
+ skill_point += skill;
+ else
+ if(sd->status.skill[i].flag >= SKILL_FLAG_REPLACED_LV_0)
+ skill_point += (sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0);
+ }
+ }
+ }
+
+ return skill_point;
}
@@ -1280,298 +1281,327 @@ static int pc_calc_skillpoint(struct map_session_data *sd)
*------------------------------------------*/
int pc_calc_skilltree(struct map_session_data *sd)
{
- int i,id=0,flag;
- int c=0;
-
- nullpo_ret(sd);
- i = pc_calc_skilltree_normalize_job(sd);
- c = pc_mapid2jobid(i, sd->status.sex);
- if (c == -1) {
- //Unable to normalize job??
- ShowError("pc_calc_skilltree: Unable to normalize job %d for character %s (%d:%d)\n", i, sd->status.name, sd->status.account_id, sd->status.char_id);
- return 1;
- }
- c = pc_class2idx(c);
-
- for (i = 0; i < MAX_SKILL; i++) {
- if (sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED) //Don't touch plagiarized skills
- sd->status.skill[i].id = 0; //First clear skills.
- }
-
- for (i = 0; i < MAX_SKILL; i++) {
- if (sd->status.skill[i].flag != SKILL_FLAG_PERMANENT && sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED) {
- // Restore original level of skills after deleting earned skills.
- sd->status.skill[i].lv = (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY) ? 0 : sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0;
- sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
- }
-
- if (sd->sc.count && sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_BARDDANCER && i >= DC_HUMMING && i<= DC_SERVICEFORYOU) {
- //Enable Bard/Dancer spirit linked skills.
- if (sd->status.sex) {
- //Link dancer skills to bard.
- if (sd->status.skill[i-8].lv < 10)
- continue;
- sd->status.skill[i].id = i;
- sd->status.skill[i].lv = sd->status.skill[i-8].lv; // Set the level to the same as the linking skill
- sd->status.skill[i].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill
- } else {
- //Link bard skills to dancer.
- if (sd->status.skill[i].lv < 10)
- continue;
- sd->status.skill[i-8].id = i - 8;
- sd->status.skill[i-8].lv = sd->status.skill[i].lv; // Set the level to the same as the linking skill
- sd->status.skill[i-8].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill
- }
- }
- }
-
- if (pc_has_permission(sd, PC_PERM_ALL_SKILL)) {
- for (i = 0; i < MAX_SKILL; i++) {
- switch (i) {
- /**
- * Dummy skills must be added here otherwise they'll be displayed in the,
- * skill tree and since they have no icons they'll give resource errors
- **/
- case SM_SELFPROVOKE:
- case AB_DUPLELIGHT_MELEE:
- case AB_DUPLELIGHT_MAGIC:
- case WL_CHAINLIGHTNING_ATK:
- case WL_TETRAVORTEX_FIRE:
- case WL_TETRAVORTEX_WATER:
- case WL_TETRAVORTEX_WIND:
- case WL_TETRAVORTEX_GROUND:
- case WL_SUMMON_ATK_FIRE:
- case WL_SUMMON_ATK_WIND:
- case WL_SUMMON_ATK_WATER:
- case WL_SUMMON_ATK_GROUND:
- case LG_OVERBRAND_BRANDISH:
- case LG_OVERBRAND_PLUSATK:
- case WM_SEVERE_RAINSTORM_MELEE:
- continue;
- default:
- break;
- }
- if (skill_get_inf2(i)&(INF2_NPC_SKILL|INF2_GUILD_SKILL))
- continue; //Only skills you can't have are npc/guild ones
- if (skill_get_max(i) > 0)
- sd->status.skill[i].id = i;
- }
- return 0;
- }
-
- do {
- flag = 0;
- for (i = 0; i < MAX_SKILL_TREE && (id = skill_tree[c][i].id) > 0; i++) {
- int j, f, k, inf2;
-
- if (sd->status.skill[id].id)
- continue; //Skill already known.
-
- f = 1;
- if (!battle_config.skillfree) {
- for (j = 0; j < MAX_PC_SKILL_REQUIRE; j++) {
- if ((k=skill_tree[c][i].need[j].id)) {
- if (sd->status.skill[k].id == 0 || sd->status.skill[k].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[k].flag == SKILL_FLAG_PLAGIARIZED)
- k = 0; //Not learned.
- else if (sd->status.skill[k].flag >= SKILL_FLAG_REPLACED_LV_0) //Real lerned level
- k = sd->status.skill[skill_tree[c][i].need[j].id].flag - SKILL_FLAG_REPLACED_LV_0;
- else
- k = pc_checkskill(sd,k);
- if (k < skill_tree[c][i].need[j].lv) {
- f = 0;
- break;
- }
- }
- }
- if (sd->status.job_level < skill_tree[c][i].joblv)
- f = 0; // job level requirement wasn't satisfied
- }
-
- if (f) {
- inf2 = skill_get_inf2(id);
-
- if (!sd->status.skill[id].lv && (
- (inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) ||
- inf2&INF2_WEDDING_SKILL ||
- (inf2&INF2_SPIRIT_SKILL && !sd->sc.data[SC_SPIRIT])
- ))
- continue; //Cannot be learned via normal means. Note this check DOES allows raising already known skills.
-
- sd->status.skill[id].id = id;
-
- if (inf2&INF2_SPIRIT_SKILL) { //Spirit skills cannot be learned, they will only show up on your tree when you get buffed.
- sd->status.skill[id].lv = 1; // need to manually specify a skill level
- sd->status.skill[id].flag = SKILL_FLAG_TEMPORARY; //So it is not saved, and tagged as a "bonus" skill.
- }
- flag = 1; // skill list has changed, perform another pass
- }
- }
- } while (flag);
-
- //
- if (c > 0 && (sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && sd->status.skill_point == 0 && pc_famerank(sd->status.char_id, MAPID_TAEKWON)) {
- /* Taekwon Ranger Bonus Skill Tree
- ============================================
- - Grant All Taekwon Tree, but only as Bonus Skills in case they drop from ranking.
- - (c > 0) to avoid grant Novice Skill Tree in case of Skill Reset (need more logic)
- - (sd->status.skill_point == 0) to wait until all skill points are asigned to avoid problems with Job Change quest. */
-
- for (i = 0; i < MAX_SKILL_TREE && (id = skill_tree[c][i].id) > 0; i++) {
- if ((skill_get_inf2(id)&(INF2_QUEST_SKILL|INF2_WEDDING_SKILL)))
- continue; //Do not include Quest/Wedding skills.
-
- if (sd->status.skill[id].id == 0) {
- sd->status.skill[id].id = id;
- sd->status.skill[id].flag = SKILL_FLAG_TEMPORARY; // So it is not saved, and tagged as a "bonus" skill.
- } else {
- sd->status.skill[id].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[id].lv; // Remember original level
- }
-
- sd->status.skill[id].lv = skill_tree_get_max(id, sd->status.class_);
- }
- }
-
- return 0;
+ int i,id=0,flag;
+ int c=0;
+
+ nullpo_ret(sd);
+ i = pc_calc_skilltree_normalize_job(sd);
+ c = pc_mapid2jobid(i, sd->status.sex);
+ if( c == -1 )
+ { //Unable to normalize job??
+ ShowError("pc_calc_skilltree: Unable to normalize job %d for character %s (%d:%d)\n", i, sd->status.name, sd->status.account_id, sd->status.char_id);
+ return 1;
+ }
+ c = pc_class2idx(c);
+
+ for( i = 0; i < MAX_SKILL; i++ )
+ {
+ if( sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED ) //Don't touch plagiarized skills
+ sd->status.skill[i].id = 0; //First clear skills.
+ }
+
+ for( i = 0; i < MAX_SKILL; i++ )
+ {
+ if( sd->status.skill[i].flag != SKILL_FLAG_PERMANENT && sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED )
+ { // Restore original level of skills after deleting earned skills.
+ sd->status.skill[i].lv = (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY) ? 0 : sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0;
+ sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
+ }
+
+ if( sd->sc.count && sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_BARDDANCER && i >= DC_HUMMING && i<= DC_SERVICEFORYOU )
+ { //Enable Bard/Dancer spirit linked skills.
+ if( sd->status.sex )
+ { //Link dancer skills to bard.
+ if( sd->status.skill[i-8].lv < 10 )
+ continue;
+ sd->status.skill[i].id = i;
+ sd->status.skill[i].lv = sd->status.skill[i-8].lv; // Set the level to the same as the linking skill
+ sd->status.skill[i].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill
+ }
+ else
+ { //Link bard skills to dancer.
+ if( sd->status.skill[i].lv < 10 )
+ continue;
+ sd->status.skill[i-8].id = i - 8;
+ sd->status.skill[i-8].lv = sd->status.skill[i].lv; // Set the level to the same as the linking skill
+ sd->status.skill[i-8].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill
+ }
+ }
+ }
+
+ if( pc_has_permission(sd, PC_PERM_ALL_SKILL) ) {
+ for( i = 0; i < MAX_SKILL; i++ ) {
+ switch(i) {
+ /**
+ * Dummy skills must be added here otherwise they'll be displayed in the,
+ * skill tree and since they have no icons they'll give resource errors
+ **/
+ case SM_SELFPROVOKE:
+ case AB_DUPLELIGHT_MELEE:
+ case AB_DUPLELIGHT_MAGIC:
+ case WL_CHAINLIGHTNING_ATK:
+ case WL_TETRAVORTEX_FIRE:
+ case WL_TETRAVORTEX_WATER:
+ case WL_TETRAVORTEX_WIND:
+ case WL_TETRAVORTEX_GROUND:
+ case WL_SUMMON_ATK_FIRE:
+ case WL_SUMMON_ATK_WIND:
+ case WL_SUMMON_ATK_WATER:
+ case WL_SUMMON_ATK_GROUND:
+ case LG_OVERBRAND_BRANDISH:
+ case LG_OVERBRAND_PLUSATK:
+ case WM_SEVERE_RAINSTORM_MELEE:
+ continue;
+ default:
+ break;
+ }
+ if( skill_get_inf2(i)&(INF2_NPC_SKILL|INF2_GUILD_SKILL) )
+ continue; //Only skills you can't have are npc/guild ones
+ if( skill_get_max(i) > 0 )
+ sd->status.skill[i].id = i;
+ }
+ return 0;
+ }
+
+ do {
+ flag = 0;
+ for( i = 0; i < MAX_SKILL_TREE && (id = skill_tree[c][i].id) > 0; i++ )
+ {
+ int j, f, k, inf2;
+
+ if( sd->status.skill[id].id )
+ continue; //Skill already known.
+
+ f = 1;
+ if(!battle_config.skillfree) {
+ for(j = 0; j < MAX_PC_SKILL_REQUIRE; j++) {
+ if((k=skill_tree[c][i].need[j].id))
+ {
+ if (sd->status.skill[k].id == 0 || sd->status.skill[k].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[k].flag == SKILL_FLAG_PLAGIARIZED)
+ k = 0; //Not learned.
+ else
+ if (sd->status.skill[k].flag >= SKILL_FLAG_REPLACED_LV_0) //Real lerned level
+ k = sd->status.skill[skill_tree[c][i].need[j].id].flag - SKILL_FLAG_REPLACED_LV_0;
+ else
+ k = pc_checkskill(sd,k);
+ if (k < skill_tree[c][i].need[j].lv)
+ {
+ f = 0;
+ break;
+ }
+ }
+ }
+ if( sd->status.job_level < skill_tree[c][i].joblv )
+ f = 0; // job level requirement wasn't satisfied
+ }
+
+ if( f ) {
+ inf2 = skill_get_inf2(id);
+
+ if(!sd->status.skill[id].lv && (
+ (inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) ||
+ inf2&INF2_WEDDING_SKILL ||
+ (inf2&INF2_SPIRIT_SKILL && !sd->sc.data[SC_SPIRIT])
+ ))
+ continue; //Cannot be learned via normal means. Note this check DOES allows raising already known skills.
+
+ sd->status.skill[id].id = id;
+
+ if(inf2&INF2_SPIRIT_SKILL) { //Spirit skills cannot be learned, they will only show up on your tree when you get buffed.
+ sd->status.skill[id].lv = 1; // need to manually specify a skill level
+ sd->status.skill[id].flag = SKILL_FLAG_TEMPORARY; //So it is not saved, and tagged as a "bonus" skill.
+ }
+ flag = 1; // skill list has changed, perform another pass
+ }
+ }
+ } while(flag);
+
+ //
+ if( c > 0 && (sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && sd->status.skill_point == 0 && pc_famerank(sd->status.char_id, MAPID_TAEKWON) )
+ {
+ /* Taekwon Ranger Bonus Skill Tree
+ ============================================
+ - Grant All Taekwon Tree, but only as Bonus Skills in case they drop from ranking.
+ - (c > 0) to avoid grant Novice Skill Tree in case of Skill Reset (need more logic)
+ - (sd->status.skill_point == 0) to wait until all skill points are asigned to avoid problems with Job Change quest. */
+
+ for( i = 0; i < MAX_SKILL_TREE && (id = skill_tree[c][i].id) > 0; i++ )
+ {
+ if( (skill_get_inf2(id)&(INF2_QUEST_SKILL|INF2_WEDDING_SKILL)) )
+ continue; //Do not include Quest/Wedding skills.
+
+ if( sd->status.skill[id].id == 0 )
+ {
+ sd->status.skill[id].id = id;
+ sd->status.skill[id].flag = SKILL_FLAG_TEMPORARY; // So it is not saved, and tagged as a "bonus" skill.
+ }
+ else
+ {
+ sd->status.skill[id].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[id].lv; // Remember original level
+ }
+
+ sd->status.skill[id].lv = skill_tree_get_max(id, sd->status.class_);
+ }
+ }
+
+ return 0;
}
//Checks if you can learn a new skill after having leveled up a skill.
static void pc_check_skilltree(struct map_session_data *sd, int skill)
{
- int i,id=0,flag;
- int c=0;
-
- if (battle_config.skillfree)
- return; //Function serves no purpose if this is set
-
- i = pc_calc_skilltree_normalize_job(sd);
- c = pc_mapid2jobid(i, sd->status.sex);
- if (c == -1) { //Unable to normalize job??
- ShowError("pc_check_skilltree: Unable to normalize job %d for character %s (%d:%d)\n", i, sd->status.name, sd->status.account_id, sd->status.char_id);
- return;
- }
- c = pc_class2idx(c);
- do {
- flag = 0;
- for (i = 0; i < MAX_SKILL_TREE && (id=skill_tree[c][i].id)>0; i++) {
- int j, f = 1, k;
-
- if (sd->status.skill[id].id) //Already learned
- continue;
-
- for (j = 0; j < MAX_PC_SKILL_REQUIRE; j++) {
- if ((k = skill_tree[c][i].need[j].id)) {
- if (sd->status.skill[k].id == 0 || sd->status.skill[k].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[k].flag == SKILL_FLAG_PLAGIARIZED)
- k = 0; //Not learned.
- else if (sd->status.skill[k].flag >= SKILL_FLAG_REPLACED_LV_0) //Real lerned level
- k = sd->status.skill[skill_tree[c][i].need[j].id].flag - SKILL_FLAG_REPLACED_LV_0;
- else
- k = pc_checkskill(sd,k);
- if (k < skill_tree[c][i].need[j].lv) {
- f = 0;
- break;
- }
- }
- }
- if (!f)
- continue;
- if (sd->status.job_level < skill_tree[c][i].joblv)
- continue;
-
- j = skill_get_inf2(id);
- if (!sd->status.skill[id].lv && (
- (j&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) ||
- j&INF2_WEDDING_SKILL ||
- (j&INF2_SPIRIT_SKILL && !sd->sc.data[SC_SPIRIT])
- ))
- continue; //Cannot be learned via normal means.
-
- sd->status.skill[id].id = id;
- flag = 1;
- }
- } while (flag);
+ int i,id=0,flag;
+ int c=0;
+
+ if(battle_config.skillfree)
+ return; //Function serves no purpose if this is set
+
+ i = pc_calc_skilltree_normalize_job(sd);
+ c = pc_mapid2jobid(i, sd->status.sex);
+ if (c == -1) { //Unable to normalize job??
+ ShowError("pc_check_skilltree: Unable to normalize job %d for character %s (%d:%d)\n", i, sd->status.name, sd->status.account_id, sd->status.char_id);
+ return;
+ }
+ c = pc_class2idx(c);
+ do {
+ flag = 0;
+ for( i = 0; i < MAX_SKILL_TREE && (id=skill_tree[c][i].id)>0; i++ )
+ {
+ int j, f = 1, k;
+
+ if( sd->status.skill[id].id ) //Already learned
+ continue;
+
+ for( j = 0; j < MAX_PC_SKILL_REQUIRE; j++ )
+ {
+ if( (k = skill_tree[c][i].need[j].id) )
+ {
+ if( sd->status.skill[k].id == 0 || sd->status.skill[k].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[k].flag == SKILL_FLAG_PLAGIARIZED )
+ k = 0; //Not learned.
+ else
+ if( sd->status.skill[k].flag >= SKILL_FLAG_REPLACED_LV_0) //Real lerned level
+ k = sd->status.skill[skill_tree[c][i].need[j].id].flag - SKILL_FLAG_REPLACED_LV_0;
+ else
+ k = pc_checkskill(sd,k);
+ if( k < skill_tree[c][i].need[j].lv )
+ {
+ f = 0;
+ break;
+ }
+ }
+ }
+ if( !f )
+ continue;
+ if( sd->status.job_level < skill_tree[c][i].joblv )
+ continue;
+
+ j = skill_get_inf2(id);
+ if( !sd->status.skill[id].lv && (
+ (j&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) ||
+ j&INF2_WEDDING_SKILL ||
+ (j&INF2_SPIRIT_SKILL && !sd->sc.data[SC_SPIRIT])
+ ) )
+ continue; //Cannot be learned via normal means.
+
+ sd->status.skill[id].id = id;
+ flag = 1;
+ }
+ } while(flag);
}
// 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 == SKILL_FLAG_TEMPORARY || sd->status.skill[i].flag == SKILL_FLAG_PLAGIARIZED) {
- sd->status.skill[i].id = 0;
- sd->status.skill[i].lv = 0;
- sd->status.skill[i].flag = 0;
- } else if (sd->status.skill[i].flag >= SKILL_FLAG_REPLACED_LV_0) {
- sd->status.skill[i].lv = sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0;
- sd->status.skill[i].flag = 0;
- }
- }
+ int i;
+ for (i = 0; i < MAX_SKILL; i++){
+ if (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[i].flag == SKILL_FLAG_PLAGIARIZED)
+ {
+ sd->status.skill[i].id = 0;
+ sd->status.skill[i].lv = 0;
+ sd->status.skill[i].flag = 0;
+ }
+ else
+ if (sd->status.skill[i].flag >= SKILL_FLAG_REPLACED_LV_0){
+ sd->status.skill[i].lv = sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0;
+ sd->status.skill[i].flag = 0;
+ }
+ }
- return 0;
+ return 0;
}
int pc_calc_skilltree_normalize_job(struct map_session_data *sd)
{
- int skill_point, novice_skills;
- int c = sd->class_;
-
- if (!battle_config.skillup_limit || pc_has_permission(sd, PC_PERM_ALL_SKILL))
- return c;
-
- skill_point = pc_calc_skillpoint(sd);
-
- novice_skills = max_level[pc_class2idx(JOB_NOVICE)][1] - 1;
-
- // limit 1st class and above to novice job levels
- if (skill_point < novice_skills) {
- c = MAPID_NOVICE;
- }
- // limit 2nd class and above to first class job levels (super novices are exempt)
- else if ((sd->class_&JOBL_2) && (sd->class_&MAPID_UPPERMASK) != MAPID_SUPER_NOVICE) {
- // regenerate change_level_2nd
- if (!sd->change_level_2nd) {
- if (sd->class_&JOBL_THIRD) {
- // if neither 2nd nor 3rd jobchange levels are known, we have to assume a default for 2nd
- if (!sd->change_level_3rd)
- sd->change_level_2nd = max_level[pc_class2idx(pc_mapid2jobid(sd->class_&MAPID_UPPERMASK, sd->status.sex))][1];
- else
- sd->change_level_2nd = 1 + skill_point + sd->status.skill_point
- - (sd->status.job_level - 1)
- - (sd->change_level_3rd - 1)
- - novice_skills;
- } else {
- sd->change_level_2nd = 1 + skill_point + sd->status.skill_point
- - (sd->status.job_level - 1)
- - novice_skills;
-
- }
-
- pc_setglobalreg(sd, "jobchange_level", sd->change_level_2nd);
- }
-
- if (skill_point < novice_skills + (sd->change_level_2nd - 1)) {
- c &= MAPID_BASEMASK;
- }
- // limit 3rd class to 2nd class/trans job levels
- else if (sd->class_&JOBL_THIRD) {
- // regenerate change_level_3rd
- if (!sd->change_level_3rd) {
- sd->change_level_3rd = 1 + skill_point + sd->status.skill_point
- - (sd->status.job_level - 1)
- - (sd->change_level_2nd - 1)
- - novice_skills;
- pc_setglobalreg(sd, "jobchange_level_3rd", sd->change_level_3rd);
- }
-
- if (skill_point < novice_skills + (sd->change_level_2nd - 1) + (sd->change_level_3rd - 1))
- c &= MAPID_UPPERMASK;
- }
- }
-
- // restore non-limiting flags
- c |= sd->class_&(JOBL_UPPER|JOBL_BABY);
-
- return c;
+ int skill_point, novice_skills;
+ int c = sd->class_;
+
+ if (!battle_config.skillup_limit || pc_has_permission(sd, PC_PERM_ALL_SKILL))
+ return c;
+
+ skill_point = pc_calc_skillpoint(sd);
+
+ novice_skills = max_level[pc_class2idx(JOB_NOVICE)][1] - 1;
+
+ // limit 1st class and above to novice job levels
+ if(skill_point < novice_skills)
+ {
+ c = MAPID_NOVICE;
+ }
+ // limit 2nd class and above to first class job levels (super novices are exempt)
+ else if ((sd->class_&JOBL_2) && (sd->class_&MAPID_UPPERMASK) != MAPID_SUPER_NOVICE)
+ {
+ // regenerate change_level_2nd
+ if (!sd->change_level_2nd)
+ {
+ if (sd->class_&JOBL_THIRD)
+ {
+ // if neither 2nd nor 3rd jobchange levels are known, we have to assume a default for 2nd
+ if (!sd->change_level_3rd)
+ sd->change_level_2nd = max_level[pc_class2idx(pc_mapid2jobid(sd->class_&MAPID_UPPERMASK, sd->status.sex))][1];
+ else
+ sd->change_level_2nd = 1 + skill_point + sd->status.skill_point
+ - (sd->status.job_level - 1)
+ - (sd->change_level_3rd - 1)
+ - novice_skills;
+ }
+ else
+ {
+ sd->change_level_2nd = 1 + skill_point + sd->status.skill_point
+ - (sd->status.job_level - 1)
+ - novice_skills;
+
+ }
+
+ pc_setglobalreg (sd, "jobchange_level", sd->change_level_2nd);
+ }
+
+ if (skill_point < novice_skills + (sd->change_level_2nd - 1))
+ {
+ c &= MAPID_BASEMASK;
+ }
+ // limit 3rd class to 2nd class/trans job levels
+ else if(sd->class_&JOBL_THIRD)
+ {
+ // regenerate change_level_3rd
+ if (!sd->change_level_3rd)
+ {
+ sd->change_level_3rd = 1 + skill_point + sd->status.skill_point
+ - (sd->status.job_level - 1)
+ - (sd->change_level_2nd - 1)
+ - novice_skills;
+ pc_setglobalreg (sd, "jobchange_level_3rd", sd->change_level_3rd);
+ }
+
+ if (skill_point < novice_skills + (sd->change_level_2nd - 1) + (sd->change_level_3rd - 1))
+ c &= MAPID_UPPERMASK;
+ }
+ }
+
+ // restore non-limiting flags
+ c |= sd->class_&(JOBL_UPPER|JOBL_BABY);
+
+ return c;
}
/*==========================================
@@ -1583,384 +1613,405 @@ int pc_calc_skilltree_normalize_job(struct map_session_data *sd)
*/
int pc_updateweightstatus(struct map_session_data *sd)
{
- int old_overweight;
- int new_overweight;
+ int old_overweight;
+ int new_overweight;
- nullpo_retr(1, sd);
+ nullpo_retr(1, sd);
- old_overweight = (sd->sc.data[SC_WEIGHT90]) ? 2 : (sd->sc.data[SC_WEIGHT50]) ? 1 : 0;
- new_overweight = (pc_is90overweight(sd)) ? 2 : (pc_is50overweight(sd)) ? 1 : 0;
+ old_overweight = (sd->sc.data[SC_WEIGHT90]) ? 2 : (sd->sc.data[SC_WEIGHT50]) ? 1 : 0;
+ new_overweight = (pc_is90overweight(sd)) ? 2 : (pc_is50overweight(sd)) ? 1 : 0;
- if (old_overweight == new_overweight)
- return 0; // no change
+ if( old_overweight == new_overweight )
+ return 0; // no change
- // stop old status change
- if (old_overweight == 1)
- status_change_end(&sd->bl, SC_WEIGHT50, INVALID_TIMER);
- else if (old_overweight == 2)
- status_change_end(&sd->bl, SC_WEIGHT90, INVALID_TIMER);
+ // stop old status change
+ if( old_overweight == 1 )
+ status_change_end(&sd->bl, SC_WEIGHT50, INVALID_TIMER);
+ else if( old_overweight == 2 )
+ status_change_end(&sd->bl, SC_WEIGHT90, INVALID_TIMER);
- // start new status change
- if (new_overweight == 1)
- sc_start(&sd->bl, SC_WEIGHT50, 100, 0, 0);
- else if (new_overweight == 2)
- sc_start(&sd->bl, SC_WEIGHT90, 100, 0, 0);
+ // start new status change
+ if( new_overweight == 1 )
+ sc_start(&sd->bl, SC_WEIGHT50, 100, 0, 0);
+ else if( new_overweight == 2 )
+ sc_start(&sd->bl, SC_WEIGHT90, 100, 0, 0);
- // update overweight status
- sd->regen.state.overweight = new_overweight;
+ // update overweight status
+ sd->regen.state.overweight = new_overweight;
- return 0;
+ return 0;
}
int pc_disguise(struct map_session_data *sd, int class_)
{
- if (!class_ && !sd->disguise)
- return 0;
- if (class_ && sd->disguise == class_)
- return 0;
-
- if (sd->sc.option&OPTION_INVISIBLE) {
- //Character is invisible. Stealth class-change. [Skotlex]
- sd->disguise = class_; //viewdata is set on uncloaking.
- return 2;
- }
-
- if (sd->bl.prev != NULL) {
- pc_stop_walking(sd, 0);
- clif_clearunit_area(&sd->bl, CLR_OUTSIGHT);
- }
-
- if (!class_) {
- sd->disguise = 0;
- class_ = sd->status.class_;
- } else
- sd->disguise=class_;
-
- status_set_viewdata(&sd->bl, class_);
- clif_changeoption(&sd->bl);
-
- if (sd->bl.prev != NULL) {
- clif_spawn(&sd->bl);
- if (class_ == sd->status.class_ && pc_iscarton(sd)) {
- //It seems the cart info is lost on undisguise.
- clif_cartlist(sd);
- clif_updatestatus(sd,SP_CARTINFO);
- }
- }
- return 1;
+ if (!class_ && !sd->disguise)
+ return 0;
+ if (class_ && sd->disguise == class_)
+ return 0;
+
+ if(sd->sc.option&OPTION_INVISIBLE)
+ { //Character is invisible. Stealth class-change. [Skotlex]
+ sd->disguise = class_; //viewdata is set on uncloaking.
+ return 2;
+ }
+
+ if (sd->bl.prev != NULL) {
+ pc_stop_walking(sd, 0);
+ clif_clearunit_area(&sd->bl, CLR_OUTSIGHT);
+ }
+
+ if (!class_) {
+ sd->disguise = 0;
+ class_ = sd->status.class_;
+ } else
+ sd->disguise=class_;
+
+ status_set_viewdata(&sd->bl, class_);
+ clif_changeoption(&sd->bl);
+
+ if (sd->bl.prev != NULL) {
+ clif_spawn(&sd->bl);
+ if (class_ == sd->status.class_ && pc_iscarton(sd))
+ { //It seems the cart info is lost on undisguise.
+ clif_cartlist(sd);
+ clif_updatestatus(sd,SP_CARTINFO);
+ }
+ }
+ return 1;
}
static int pc_bonus_autospell(struct s_autospell *spell, int max, short id, short lv, short rate, short flag, short card_id)
{
- int i;
-
- if (!rate)
- return 0;
-
- for (i = 0; i < max && spell[i].id; i++) {
- if ((spell[i].card_id == card_id || spell[i].rate < 0 || rate < 0) && spell[i].id == id && spell[i].lv == lv) {
- if (!battle_config.autospell_stacking && spell[i].rate > 0 && rate > 0)
- return 0;
- rate += spell[i].rate;
- break;
- }
- }
- if (i == max) {
- ShowWarning("pc_bonus: Reached max (%d) number of autospells per character!\n", max);
- return 0;
- }
- spell[i].id = id;
- spell[i].lv = lv;
- spell[i].rate = rate;
- //Auto-update flag value.
- if (!(flag&BF_RANGEMASK)) flag|=BF_SHORT|BF_LONG; //No range defined? Use both.
- if (!(flag&BF_WEAPONMASK)) flag|=BF_WEAPON; //No attack type defined? Use weapon.
- if (!(flag&BF_SKILLMASK)) {
- if (flag&(BF_MAGIC|BF_MISC)) flag|=BF_SKILL; //These two would never trigger without BF_SKILL
- if (flag&BF_WEAPON) flag|=BF_NORMAL; //By default autospells should only trigger on normal weapon attacks.
- }
- spell[i].flag|= flag;
- spell[i].card_id = card_id;
- return 1;
+ int i;
+
+ if( !rate )
+ return 0;
+
+ for( i = 0; i < max && spell[i].id; i++ )
+ {
+ if( (spell[i].card_id == card_id || spell[i].rate < 0 || rate < 0) && spell[i].id == id && spell[i].lv == lv )
+ {
+ if( !battle_config.autospell_stacking && spell[i].rate > 0 && rate > 0 )
+ return 0;
+ rate += spell[i].rate;
+ break;
+ }
+ }
+ if (i == max) {
+ ShowWarning("pc_bonus: Reached max (%d) number of autospells per character!\n", max);
+ return 0;
+ }
+ spell[i].id = id;
+ spell[i].lv = lv;
+ spell[i].rate = rate;
+ //Auto-update flag value.
+ if (!(flag&BF_RANGEMASK)) flag|=BF_SHORT|BF_LONG; //No range defined? Use both.
+ if (!(flag&BF_WEAPONMASK)) flag|=BF_WEAPON; //No attack type defined? Use weapon.
+ if (!(flag&BF_SKILLMASK)) {
+ if (flag&(BF_MAGIC|BF_MISC)) flag|=BF_SKILL; //These two would never trigger without BF_SKILL
+ if (flag&BF_WEAPON) flag|=BF_NORMAL; //By default autospells should only trigger on normal weapon attacks.
+ }
+ spell[i].flag|= flag;
+ spell[i].card_id = card_id;
+ return 1;
}
static int pc_bonus_autospell_onskill(struct s_autospell *spell, int max, short src_skill, short id, short lv, short rate, short card_id)
{
- int i;
-
- if (!rate)
- return 0;
-
- for (i = 0; i < max && spell[i].id; i++) {
- ; // each autospell works independently
- }
-
- if (i == max) {
- ShowWarning("pc_bonus: Reached max (%d) number of autospells per character!\n", max);
- return 0;
- }
-
- spell[i].flag = src_skill;
- spell[i].id = id;
- spell[i].lv = lv;
- spell[i].rate = rate;
- spell[i].card_id = card_id;
- return 1;
-}
-
-static int pc_bonus_addeff(struct s_addeffect *effect, int max, enum sc_type id, short rate, short arrow_rate, unsigned char flag)
-{
- int i;
- if (!(flag&(ATF_SHORT|ATF_LONG)))
- flag|=ATF_SHORT|ATF_LONG; //Default range: both
- if (!(flag&(ATF_TARGET|ATF_SELF)))
- flag|=ATF_TARGET; //Default target: enemy.
- if (!(flag&(ATF_WEAPON|ATF_MAGIC|ATF_MISC)))
- flag|=ATF_WEAPON; //Default type: weapon.
-
- for (i = 0; i < max && effect[i].flag; i++) {
- if (effect[i].id == id && effect[i].flag == flag) {
- effect[i].rate += rate;
- effect[i].arrow_rate += arrow_rate;
- return 1;
- }
- }
- if (i == max) {
- ShowWarning("pc_bonus: Reached max (%d) number of add effects per character!\n", max);
- return 0;
- }
- effect[i].id = id;
- effect[i].rate = rate;
- effect[i].arrow_rate = arrow_rate;
- effect[i].flag = flag;
- return 1;
-}
-
-static int pc_bonus_addeff_onskill(struct s_addeffectonskill *effect, int max, enum sc_type id, short rate, short skill, unsigned char target)
-{
- int i;
- for (i = 0; i < max && effect[i].skill; i++) {
- if (effect[i].id == id && effect[i].skill == skill && effect[i].target == target) {
- effect[i].rate += rate;
- return 1;
- }
- }
- if (i == max) {
- ShowWarning("pc_bonus: Reached max (%d) number of add effects on skill per character!\n", max);
- return 0;
- }
- effect[i].id = id;
- effect[i].rate = rate;
- effect[i].skill = skill;
- effect[i].target = target;
- return 1;
+ int i;
+
+ if( !rate )
+ return 0;
+
+ for( i = 0; i < max && spell[i].id; i++ )
+ {
+ ; // each autospell works independently
+ }
+
+ if( i == max )
+ {
+ ShowWarning("pc_bonus: Reached max (%d) number of autospells per character!\n", max);
+ return 0;
+ }
+
+ spell[i].flag = src_skill;
+ spell[i].id = id;
+ spell[i].lv = lv;
+ spell[i].rate = rate;
+ spell[i].card_id = card_id;
+ return 1;
+}
+
+static int pc_bonus_addeff(struct s_addeffect* effect, int max, enum sc_type id, short rate, short arrow_rate, unsigned char flag)
+{
+ int i;
+ if (!(flag&(ATF_SHORT|ATF_LONG)))
+ flag|=ATF_SHORT|ATF_LONG; //Default range: both
+ if (!(flag&(ATF_TARGET|ATF_SELF)))
+ flag|=ATF_TARGET; //Default target: enemy.
+ if (!(flag&(ATF_WEAPON|ATF_MAGIC|ATF_MISC)))
+ flag|=ATF_WEAPON; //Default type: weapon.
+
+ for (i = 0; i < max && effect[i].flag; i++) {
+ if (effect[i].id == id && effect[i].flag == flag)
+ {
+ effect[i].rate += rate;
+ effect[i].arrow_rate += arrow_rate;
+ return 1;
+ }
+ }
+ if (i == max) {
+ ShowWarning("pc_bonus: Reached max (%d) number of add effects per character!\n", max);
+ return 0;
+ }
+ effect[i].id = id;
+ effect[i].rate = rate;
+ effect[i].arrow_rate = arrow_rate;
+ effect[i].flag = flag;
+ return 1;
+}
+
+static int pc_bonus_addeff_onskill(struct s_addeffectonskill* effect, int max, enum sc_type id, short rate, short skill, unsigned char target)
+{
+ int i;
+ for( i = 0; i < max && effect[i].skill; i++ )
+ {
+ if( effect[i].id == id && effect[i].skill == skill && effect[i].target == target )
+ {
+ effect[i].rate += rate;
+ return 1;
+ }
+ }
+ if( i == max ) {
+ ShowWarning("pc_bonus: Reached max (%d) number of add effects on skill per character!\n", max);
+ return 0;
+ }
+ effect[i].id = id;
+ effect[i].rate = rate;
+ effect[i].skill = skill;
+ effect[i].target = target;
+ return 1;
}
static int pc_bonus_item_drop(struct s_add_drop *drop, const short max, short id, short group, int race, int rate)
{
- int i;
- //Apply config rate adjustment settings.
- if (rate >= 0) { //Absolute drop.
- if (battle_config.item_rate_adddrop != 100)
- rate = rate*battle_config.item_rate_adddrop/100;
- if (rate < battle_config.item_drop_adddrop_min)
- rate = battle_config.item_drop_adddrop_min;
- else if (rate > battle_config.item_drop_adddrop_max)
- rate = battle_config.item_drop_adddrop_max;
- } else { //Relative drop, max/min limits are applied at drop time.
- if (battle_config.item_rate_adddrop != 100)
- rate = rate*battle_config.item_rate_adddrop/100;
- if (rate > -1)
- rate = -1;
- }
- for (i = 0; i < max && (drop[i].id || drop[i].group); i++) {
- if (
- ((id && drop[i].id == id) ||
- (group && drop[i].group == group))
- && race > 0
- ) {
- drop[i].race |= race;
- if (drop[i].rate > 0 && rate > 0) {
- //Both are absolute rates.
- if (drop[i].rate < rate)
- drop[i].rate = rate;
- } else if (drop[i].rate < 0 && rate < 0) {
- //Both are relative rates.
- if (drop[i].rate > rate)
- drop[i].rate = rate;
- } else if (rate < 0) //Give preference to relative rate.
- drop[i].rate = rate;
- return 1;
- }
- }
- if (i == max) {
- ShowWarning("pc_bonus: Reached max (%d) number of added drops per character!\n", max);
- return 0;
- }
- drop[i].id = id;
- drop[i].group = group;
- drop[i].race |= race;
- drop[i].rate = rate;
- return 1;
+ int i;
+ //Apply config rate adjustment settings.
+ if (rate >= 0) { //Absolute drop.
+ if (battle_config.item_rate_adddrop != 100)
+ rate = rate*battle_config.item_rate_adddrop/100;
+ if (rate < battle_config.item_drop_adddrop_min)
+ rate = battle_config.item_drop_adddrop_min;
+ else if (rate > battle_config.item_drop_adddrop_max)
+ rate = battle_config.item_drop_adddrop_max;
+ } else { //Relative drop, max/min limits are applied at drop time.
+ if (battle_config.item_rate_adddrop != 100)
+ rate = rate*battle_config.item_rate_adddrop/100;
+ if (rate > -1)
+ rate = -1;
+ }
+ for(i = 0; i < max && (drop[i].id || drop[i].group); i++) {
+ if(
+ ((id && drop[i].id == id) ||
+ (group && drop[i].group == group))
+ && race > 0
+ ) {
+ drop[i].race |= race;
+ if(drop[i].rate > 0 && rate > 0)
+ { //Both are absolute rates.
+ if (drop[i].rate < rate)
+ drop[i].rate = rate;
+ } else
+ if(drop[i].rate < 0 && rate < 0) {
+ //Both are relative rates.
+ if (drop[i].rate > rate)
+ drop[i].rate = rate;
+ } else if (rate < 0) //Give preference to relative rate.
+ drop[i].rate = rate;
+ return 1;
+ }
+ }
+ if(i == max) {
+ ShowWarning("pc_bonus: Reached max (%d) number of added drops per character!\n", max);
+ return 0;
+ }
+ drop[i].id = id;
+ drop[i].group = group;
+ drop[i].race |= race;
+ drop[i].rate = rate;
+ return 1;
}
int pc_addautobonus(struct s_autobonus *bonus,char max,const char *script,short rate,unsigned int dur,short flag,const char *other_script,unsigned short pos,bool onskill)
{
- int i;
-
- ARR_FIND(0, max, i, bonus[i].rate == 0);
- if (i == max) {
- ShowWarning("pc_addautobonus: Reached max (%d) number of autobonus per character!\n", max);
- return 0;
- }
-
- if (!onskill) {
- if (!(flag&BF_RANGEMASK))
- flag|=BF_SHORT|BF_LONG; //No range defined? Use both.
- if (!(flag&BF_WEAPONMASK))
- flag|=BF_WEAPON; //No attack type defined? Use weapon.
- if (!(flag&BF_SKILLMASK)) {
- if (flag&(BF_MAGIC|BF_MISC))
- flag|=BF_SKILL; //These two would never trigger without BF_SKILL
- if (flag&BF_WEAPON)
- flag|=BF_NORMAL|BF_SKILL;
- }
- }
-
- bonus[i].rate = rate;
- bonus[i].duration = dur;
- bonus[i].active = INVALID_TIMER;
- bonus[i].atk_type = flag;
- bonus[i].pos = pos;
- bonus[i].bonus_script = aStrdup(script);
- bonus[i].other_script = other_script?aStrdup(other_script):NULL;
- return 1;
-}
-
-int pc_delautobonus(struct map_session_data *sd, struct s_autobonus *autobonus,char max,bool restore)
-{
- int i;
- nullpo_ret(sd);
-
- for (i = 0; i < max; i++) {
- if (autobonus[i].active != INVALID_TIMER) {
- if (restore && sd->state.autobonus&autobonus[i].pos) {
- if (autobonus[i].bonus_script) {
- int j;
- ARR_FIND(0, EQI_MAX-1, j, sd->equip_index[j] >= 0 && sd->status.inventory[sd->equip_index[j]].equip == autobonus[i].pos);
- if (j < EQI_MAX-1)
- script_run_autobonus(autobonus[i].bonus_script,sd->bl.id,sd->equip_index[j]);
- }
- continue;
- } else {
- // Logout / Unequipped an item with an activated bonus
- delete_timer(autobonus[i].active,pc_endautobonus);
- autobonus[i].active = INVALID_TIMER;
- }
- }
-
- if (autobonus[i].bonus_script) aFree(autobonus[i].bonus_script);
- if (autobonus[i].other_script) aFree(autobonus[i].other_script);
- autobonus[i].bonus_script = autobonus[i].other_script = NULL;
- autobonus[i].rate = autobonus[i].atk_type = autobonus[i].duration = autobonus[i].pos = 0;
- autobonus[i].active = INVALID_TIMER;
- }
-
- return 0;
+ int i;
+
+ ARR_FIND(0, max, i, bonus[i].rate == 0);
+ if( i == max )
+ {
+ ShowWarning("pc_addautobonus: Reached max (%d) number of autobonus per character!\n", max);
+ return 0;
+ }
+
+ if( !onskill )
+ {
+ if( !(flag&BF_RANGEMASK) )
+ flag|=BF_SHORT|BF_LONG; //No range defined? Use both.
+ if( !(flag&BF_WEAPONMASK) )
+ flag|=BF_WEAPON; //No attack type defined? Use weapon.
+ if( !(flag&BF_SKILLMASK) )
+ {
+ if( flag&(BF_MAGIC|BF_MISC) )
+ flag|=BF_SKILL; //These two would never trigger without BF_SKILL
+ if( flag&BF_WEAPON )
+ flag|=BF_NORMAL|BF_SKILL;
+ }
+ }
+
+ bonus[i].rate = rate;
+ bonus[i].duration = dur;
+ bonus[i].active = INVALID_TIMER;
+ bonus[i].atk_type = flag;
+ bonus[i].pos = pos;
+ bonus[i].bonus_script = aStrdup(script);
+ bonus[i].other_script = other_script?aStrdup(other_script):NULL;
+ return 1;
+}
+
+int pc_delautobonus(struct map_session_data* sd, struct s_autobonus *autobonus,char max,bool restore)
+{
+ int i;
+ nullpo_ret(sd);
+
+ for( i = 0; i < max; i++ )
+ {
+ if( autobonus[i].active != INVALID_TIMER )
+ {
+ if( restore && sd->state.autobonus&autobonus[i].pos )
+ {
+ if( autobonus[i].bonus_script )
+ {
+ int j;
+ ARR_FIND( 0, EQI_MAX-1, j, sd->equip_index[j] >= 0 && sd->status.inventory[sd->equip_index[j]].equip == autobonus[i].pos );
+ if( j < EQI_MAX-1 )
+ script_run_autobonus(autobonus[i].bonus_script,sd->bl.id,sd->equip_index[j]);
+ }
+ continue;
+ }
+ else
+ { // Logout / Unequipped an item with an activated bonus
+ delete_timer(autobonus[i].active,pc_endautobonus);
+ autobonus[i].active = INVALID_TIMER;
+ }
+ }
+
+ if( autobonus[i].bonus_script ) aFree(autobonus[i].bonus_script);
+ if( autobonus[i].other_script ) aFree(autobonus[i].other_script);
+ autobonus[i].bonus_script = autobonus[i].other_script = NULL;
+ autobonus[i].rate = autobonus[i].atk_type = autobonus[i].duration = autobonus[i].pos = 0;
+ autobonus[i].active = INVALID_TIMER;
+ }
+
+ return 0;
}
int pc_exeautobonus(struct map_session_data *sd,struct s_autobonus *autobonus)
{
- nullpo_ret(sd);
- nullpo_ret(autobonus);
+ nullpo_ret(sd);
+ nullpo_ret(autobonus);
- if (autobonus->other_script) {
- int j;
- ARR_FIND(0, EQI_MAX-1, j, sd->equip_index[j] >= 0 && sd->status.inventory[sd->equip_index[j]].equip == autobonus->pos);
- if (j < EQI_MAX-1)
- script_run_autobonus(autobonus->other_script,sd->bl.id,sd->equip_index[j]);
- }
+ if( autobonus->other_script )
+ {
+ int j;
+ ARR_FIND( 0, EQI_MAX-1, j, sd->equip_index[j] >= 0 && sd->status.inventory[sd->equip_index[j]].equip == autobonus->pos );
+ if( j < EQI_MAX-1 )
+ script_run_autobonus(autobonus->other_script,sd->bl.id,sd->equip_index[j]);
+ }
- autobonus->active = add_timer(gettick()+autobonus->duration, pc_endautobonus, sd->bl.id, (intptr_t)autobonus);
- sd->state.autobonus |= autobonus->pos;
- status_calc_pc(sd,0);
+ autobonus->active = add_timer(gettick()+autobonus->duration, pc_endautobonus, sd->bl.id, (intptr_t)autobonus);
+ sd->state.autobonus |= autobonus->pos;
+ status_calc_pc(sd,0);
- return 0;
+ return 0;
}
int pc_endautobonus(int tid, unsigned int tick, int id, intptr_t data)
{
- struct map_session_data *sd = map_id2sd(id);
- struct s_autobonus *autobonus = (struct s_autobonus *)data;
+ struct map_session_data *sd = map_id2sd(id);
+ struct s_autobonus *autobonus = (struct s_autobonus *)data;
- nullpo_ret(sd);
- nullpo_ret(autobonus);
+ nullpo_ret(sd);
+ nullpo_ret(autobonus);
- autobonus->active = INVALID_TIMER;
- sd->state.autobonus &= ~autobonus->pos;
- status_calc_pc(sd,0);
- return 0;
+ autobonus->active = INVALID_TIMER;
+ sd->state.autobonus &= ~autobonus->pos;
+ status_calc_pc(sd,0);
+ return 0;
}
-int pc_bonus_addele(struct map_session_data *sd, unsigned char ele, short rate, short flag)
+int pc_bonus_addele(struct map_session_data* sd, unsigned char ele, short rate, short flag)
{
- int i;
- struct weapon_data *wd;
+ int i;
+ struct weapon_data* wd;
- wd = (sd->state.lr_flag ? &sd->left_weapon : &sd->right_weapon);
+ wd = (sd->state.lr_flag ? &sd->left_weapon : &sd->right_weapon);
- ARR_FIND(0, MAX_PC_BONUS, i, wd->addele2[i].rate == 0);
+ ARR_FIND(0, MAX_PC_BONUS, i, wd->addele2[i].rate == 0);
- if (i == MAX_PC_BONUS) {
- ShowWarning("pc_addele: Reached max (%d) possible bonuses for this player.\n", MAX_PC_BONUS);
- return 0;
- }
+ if (i == MAX_PC_BONUS)
+ {
+ ShowWarning("pc_addele: Reached max (%d) possible bonuses for this player.\n", MAX_PC_BONUS);
+ return 0;
+ }
- if (!(flag&BF_RANGEMASK))
- flag |= BF_SHORT|BF_LONG;
- if (!(flag&BF_WEAPONMASK))
- flag |= BF_WEAPON;
- if (!(flag&BF_SKILLMASK)) {
- if (flag&(BF_MAGIC|BF_MISC))
- flag |= BF_SKILL;
- if (flag&BF_WEAPON)
- flag |= BF_NORMAL|BF_SKILL;
- }
+ if (!(flag&BF_RANGEMASK))
+ flag |= BF_SHORT|BF_LONG;
+ if (!(flag&BF_WEAPONMASK))
+ flag |= BF_WEAPON;
+ if (!(flag&BF_SKILLMASK))
+ {
+ if (flag&(BF_MAGIC|BF_MISC))
+ flag |= BF_SKILL;
+ if (flag&BF_WEAPON)
+ flag |= BF_NORMAL|BF_SKILL;
+ }
- wd->addele2[i].ele = ele;
- wd->addele2[i].rate = rate;
- wd->addele2[i].flag = flag;
+ wd->addele2[i].ele = ele;
+ wd->addele2[i].rate = rate;
+ wd->addele2[i].flag = flag;
- return 0;
+ return 0;
}
-int pc_bonus_subele(struct map_session_data *sd, unsigned char ele, short rate, short flag)
+int pc_bonus_subele(struct map_session_data* sd, unsigned char ele, short rate, short flag)
{
- int i;
+ int i;
- ARR_FIND(0, MAX_PC_BONUS, i, sd->subele2[i].rate == 0);
+ ARR_FIND(0, MAX_PC_BONUS, i, sd->subele2[i].rate == 0);
- if (i == MAX_PC_BONUS) {
- ShowWarning("pc_subele: Reached max (%d) possible bonuses for this player.\n", MAX_PC_BONUS);
- return 0;
- }
+ if (i == MAX_PC_BONUS)
+ {
+ ShowWarning("pc_subele: Reached max (%d) possible bonuses for this player.\n", MAX_PC_BONUS);
+ return 0;
+ }
- if (!(flag&BF_RANGEMASK))
- flag |= BF_SHORT|BF_LONG;
- if (!(flag&BF_WEAPONMASK))
- flag |= BF_WEAPON;
- if (!(flag&BF_SKILLMASK)) {
- if (flag&(BF_MAGIC|BF_MISC))
- flag |= BF_SKILL;
- if (flag&BF_WEAPON)
- flag |= BF_NORMAL|BF_SKILL;
- }
+ if (!(flag&BF_RANGEMASK))
+ flag |= BF_SHORT|BF_LONG;
+ if (!(flag&BF_WEAPONMASK))
+ flag |= BF_WEAPON;
+ if (!(flag&BF_SKILLMASK))
+ {
+ if (flag&(BF_MAGIC|BF_MISC))
+ flag |= BF_SKILL;
+ if (flag&BF_WEAPON)
+ flag |= BF_NORMAL|BF_SKILL;
+ }
- sd->subele2[i].ele = ele;
- sd->subele2[i].rate = rate;
- sd->subele2[i].flag = flag;
+ sd->subele2[i].ele = ele;
+ sd->subele2[i].rate = rate;
+ sd->subele2[i].flag = flag;
- return 0;
+ return 0;
}
/*==========================================
@@ -1968,588 +2019,597 @@ int pc_bonus_subele(struct map_session_data *sd, unsigned char ele, short rate,
*------------------------------------------*/
int pc_bonus(struct map_session_data *sd,int type,int val)
{
- struct status_data *status;
- int bonus;
- nullpo_ret(sd);
-
- status = &sd->base_status;
-
- switch (type) {
- case SP_STR:
- case SP_AGI:
- case SP_VIT:
- case SP_INT:
- case SP_DEX:
- case SP_LUK:
- if (sd->state.lr_flag != 2)
- sd->param_bonus[type-SP_STR]+=val;
- break;
- case SP_ATK1:
- if (!sd->state.lr_flag) {
- bonus = status->rhw.atk + val;
- status->rhw.atk = cap_value(bonus, 0, USHRT_MAX);
- } else if (sd->state.lr_flag == 1) {
- bonus = status->lhw.atk + val;
- status->lhw.atk = cap_value(bonus, 0, USHRT_MAX);
- }
- break;
- case SP_ATK2:
- if (!sd->state.lr_flag) {
- bonus = status->rhw.atk2 + val;
- status->rhw.atk2 = cap_value(bonus, 0, USHRT_MAX);
- } else if (sd->state.lr_flag == 1) {
- bonus = status->lhw.atk2 + val;
- status->lhw.atk2 = cap_value(bonus, 0, USHRT_MAX);
- }
- break;
- case SP_BASE_ATK:
- if (sd->state.lr_flag != 2) {
- bonus = status->batk + val;
- status->batk = cap_value(bonus, 0, USHRT_MAX);
- }
- break;
- case SP_DEF1:
- if (sd->state.lr_flag != 2) {
- bonus = status->def + val;
+ struct status_data *status;
+ int bonus;
+ nullpo_ret(sd);
+
+ status = &sd->base_status;
+
+ switch(type){
+ case SP_STR:
+ case SP_AGI:
+ case SP_VIT:
+ case SP_INT:
+ case SP_DEX:
+ case SP_LUK:
+ if(sd->state.lr_flag != 2)
+ sd->param_bonus[type-SP_STR]+=val;
+ break;
+ case SP_ATK1:
+ if(!sd->state.lr_flag) {
+ bonus = status->rhw.atk + val;
+ status->rhw.atk = cap_value(bonus, 0, USHRT_MAX);
+ }
+ else if(sd->state.lr_flag == 1) {
+ bonus = status->lhw.atk + val;
+ status->lhw.atk = cap_value(bonus, 0, USHRT_MAX);
+ }
+ break;
+ case SP_ATK2:
+ if(!sd->state.lr_flag) {
+ bonus = status->rhw.atk2 + val;
+ status->rhw.atk2 = cap_value(bonus, 0, USHRT_MAX);
+ }
+ else if(sd->state.lr_flag == 1) {
+ bonus = status->lhw.atk2 + val;
+ status->lhw.atk2 = cap_value(bonus, 0, USHRT_MAX);
+ }
+ break;
+ case SP_BASE_ATK:
+ if(sd->state.lr_flag != 2) {
+ bonus = status->batk + val;
+ status->batk = cap_value(bonus, 0, USHRT_MAX);
+ }
+ break;
+ case SP_DEF1:
+ if(sd->state.lr_flag != 2) {
+ bonus = status->def + val;
#ifdef RENEWAL
- status->def = cap_value(bonus, SHRT_MIN, SHRT_MAX);
+ status->def = cap_value(bonus, SHRT_MIN, SHRT_MAX);
#else
- status->def = cap_value(bonus, CHAR_MIN, CHAR_MAX);
+ status->def = cap_value(bonus, CHAR_MIN, CHAR_MAX);
#endif
- }
- break;
- case SP_DEF2:
- if (sd->state.lr_flag != 2) {
- bonus = status->def2 + val;
- status->def2 = cap_value(bonus, SHRT_MIN, SHRT_MAX);
- }
- break;
- case SP_MDEF1:
- if (sd->state.lr_flag != 2) {
- bonus = status->mdef + val;
+ }
+ break;
+ case SP_DEF2:
+ if(sd->state.lr_flag != 2) {
+ bonus = status->def2 + val;
+ status->def2 = cap_value(bonus, SHRT_MIN, SHRT_MAX);
+ }
+ break;
+ case SP_MDEF1:
+ if(sd->state.lr_flag != 2) {
+ bonus = status->mdef + val;
#ifdef RENEWAL
- status->mdef = cap_value(bonus, SHRT_MIN, SHRT_MAX);
+ status->mdef = cap_value(bonus, SHRT_MIN, SHRT_MAX);
#else
- status->mdef = cap_value(bonus, CHAR_MIN, CHAR_MAX);
+ status->mdef = cap_value(bonus, CHAR_MIN, CHAR_MAX);
#endif
- if (sd->state.lr_flag == 3) { //Shield, used for royal guard
- sd->bonus.shieldmdef += bonus;
- }
- }
- break;
- case SP_MDEF2:
- if (sd->state.lr_flag != 2) {
- bonus = status->mdef2 + val;
- status->mdef2 = cap_value(bonus, SHRT_MIN, SHRT_MAX);
- }
- break;
- case SP_HIT:
- if (sd->state.lr_flag != 2) {
- bonus = status->hit + val;
- status->hit = cap_value(bonus, SHRT_MIN, SHRT_MAX);
- } else
- sd->bonus.arrow_hit+=val;
- break;
- case SP_FLEE1:
- if (sd->state.lr_flag != 2) {
- bonus = status->flee + val;
- status->flee = cap_value(bonus, SHRT_MIN, SHRT_MAX);
- }
- break;
- case SP_FLEE2:
- if (sd->state.lr_flag != 2) {
- bonus = status->flee2 + val*10;
- status->flee2 = cap_value(bonus, SHRT_MIN, SHRT_MAX);
- }
- break;
- case SP_CRITICAL:
- if (sd->state.lr_flag != 2) {
- bonus = status->cri + val*10;
- status->cri = cap_value(bonus, SHRT_MIN, SHRT_MAX);
- } else
- sd->bonus.arrow_cri += val*10;
- break;
- case SP_ATKELE:
- if (val >= ELE_MAX) {
- ShowError("pc_bonus: SP_ATKELE: Invalid element %d\n", val);
- break;
- }
- switch (sd->state.lr_flag) {
- case 2:
- switch (sd->status.weapon) {
- case W_BOW:
- case W_REVOLVER:
- case W_RIFLE:
- case W_GATLING:
- case W_SHOTGUN:
- case W_GRENADE:
- //Become weapon element.
- status->rhw.ele=val;
- break;
- default: //Become arrow element.
- sd->bonus.arrow_ele=val;
- break;
- }
- break;
- case 1:
- status->lhw.ele=val;
- break;
- default:
- status->rhw.ele=val;
- break;
- }
- break;
- case SP_DEFELE:
- if (val >= ELE_MAX) {
- ShowError("pc_bonus: SP_DEFELE: Invalid element %d\n", val);
- break;
- }
- if (sd->state.lr_flag != 2)
- status->def_ele=val;
- break;
- case SP_MAXHP:
- if (sd->state.lr_flag == 2)
- break;
- val += (int)status->max_hp;
- //Negative bonuses will underflow, this will be handled in status_calc_pc through casting
- //If this is called outside of status_calc_pc, you'd better pray they do not underflow and end with UINT_MAX max_hp.
- status->max_hp = (unsigned int)val;
- break;
- case SP_MAXSP:
- if (sd->state.lr_flag == 2)
- break;
- val += (int)status->max_sp;
- status->max_sp = (unsigned int)val;
- break;
- case SP_CASTRATE:
- if (sd->state.lr_flag != 2)
- sd->castrate+=val;
- break;
- case SP_MAXHPRATE:
- if (sd->state.lr_flag != 2)
- sd->hprate+=val;
- break;
- case SP_MAXSPRATE:
- if (sd->state.lr_flag != 2)
- sd->sprate+=val;
- break;
- case SP_SPRATE:
- if (sd->state.lr_flag != 2)
- sd->dsprate+=val;
- break;
- case SP_ATTACKRANGE:
- switch (sd->state.lr_flag) {
- case 2:
- switch (sd->status.weapon) {
- case W_BOW:
- case W_REVOLVER:
- case W_RIFLE:
- case W_GATLING:
- case W_SHOTGUN:
- case W_GRENADE:
- status->rhw.range += val;
- }
- break;
- case 1:
- status->lhw.range += val;
- break;
- default:
- status->rhw.range += val;
- break;
- }
- break;
- case SP_SPEED_RATE: //Non stackable increase
- if (sd->state.lr_flag != 2)
- sd->bonus.speed_rate = min(sd->bonus.speed_rate, -val);
- break;
- case SP_SPEED_ADDRATE: //Stackable increase
- if (sd->state.lr_flag != 2)
- sd->bonus.speed_add_rate -= val;
- break;
- case SP_ASPD: //Raw increase
- if (sd->state.lr_flag != 2)
- sd->bonus.aspd_add -= 10*val;
- break;
- case SP_ASPD_RATE: //Stackable increase - Made it linear as per rodatazone
- if (sd->state.lr_flag != 2)
+ if( sd->state.lr_flag == 3 ) {//Shield, used for royal guard
+ sd->bonus.shieldmdef += bonus;
+ }
+ }
+ break;
+ case SP_MDEF2:
+ if(sd->state.lr_flag != 2) {
+ bonus = status->mdef2 + val;
+ status->mdef2 = cap_value(bonus, SHRT_MIN, SHRT_MAX);
+ }
+ break;
+ case SP_HIT:
+ if(sd->state.lr_flag != 2) {
+ bonus = status->hit + val;
+ status->hit = cap_value(bonus, SHRT_MIN, SHRT_MAX);
+ } else
+ sd->bonus.arrow_hit+=val;
+ break;
+ case SP_FLEE1:
+ if(sd->state.lr_flag != 2) {
+ bonus = status->flee + val;
+ status->flee = cap_value(bonus, SHRT_MIN, SHRT_MAX);
+ }
+ break;
+ case SP_FLEE2:
+ if(sd->state.lr_flag != 2) {
+ bonus = status->flee2 + val*10;
+ status->flee2 = cap_value(bonus, SHRT_MIN, SHRT_MAX);
+ }
+ break;
+ case SP_CRITICAL:
+ if(sd->state.lr_flag != 2) {
+ bonus = status->cri + val*10;
+ status->cri = cap_value(bonus, SHRT_MIN, SHRT_MAX);
+ } else
+ sd->bonus.arrow_cri += val*10;
+ break;
+ case SP_ATKELE:
+ if(val >= ELE_MAX) {
+ ShowError("pc_bonus: SP_ATKELE: Invalid element %d\n", val);
+ break;
+ }
+ switch (sd->state.lr_flag)
+ {
+ case 2:
+ switch (sd->status.weapon) {
+ case W_BOW:
+ case W_REVOLVER:
+ case W_RIFLE:
+ case W_GATLING:
+ case W_SHOTGUN:
+ case W_GRENADE:
+ //Become weapon element.
+ status->rhw.ele=val;
+ break;
+ default: //Become arrow element.
+ sd->bonus.arrow_ele=val;
+ break;
+ }
+ break;
+ case 1:
+ status->lhw.ele=val;
+ break;
+ default:
+ status->rhw.ele=val;
+ break;
+ }
+ break;
+ case SP_DEFELE:
+ if(val >= ELE_MAX) {
+ ShowError("pc_bonus: SP_DEFELE: Invalid element %d\n", val);
+ break;
+ }
+ if(sd->state.lr_flag != 2)
+ status->def_ele=val;
+ break;
+ case SP_MAXHP:
+ if(sd->state.lr_flag == 2)
+ break;
+ val += (int)status->max_hp;
+ //Negative bonuses will underflow, this will be handled in status_calc_pc through casting
+ //If this is called outside of status_calc_pc, you'd better pray they do not underflow and end with UINT_MAX max_hp.
+ status->max_hp = (unsigned int)val;
+ break;
+ case SP_MAXSP:
+ if(sd->state.lr_flag == 2)
+ break;
+ val += (int)status->max_sp;
+ status->max_sp = (unsigned int)val;
+ break;
+ case SP_CASTRATE:
+ if(sd->state.lr_flag != 2)
+ sd->castrate+=val;
+ break;
+ case SP_MAXHPRATE:
+ if(sd->state.lr_flag != 2)
+ sd->hprate+=val;
+ break;
+ case SP_MAXSPRATE:
+ if(sd->state.lr_flag != 2)
+ sd->sprate+=val;
+ break;
+ case SP_SPRATE:
+ if(sd->state.lr_flag != 2)
+ sd->dsprate+=val;
+ break;
+ case SP_ATTACKRANGE:
+ switch (sd->state.lr_flag) {
+ case 2:
+ switch (sd->status.weapon) {
+ case W_BOW:
+ case W_REVOLVER:
+ case W_RIFLE:
+ case W_GATLING:
+ case W_SHOTGUN:
+ case W_GRENADE:
+ status->rhw.range += val;
+ }
+ break;
+ case 1:
+ status->lhw.range += val;
+ break;
+ default:
+ status->rhw.range += val;
+ break;
+ }
+ break;
+ case SP_SPEED_RATE: //Non stackable increase
+ if(sd->state.lr_flag != 2)
+ sd->bonus.speed_rate = min(sd->bonus.speed_rate, -val);
+ break;
+ case SP_SPEED_ADDRATE: //Stackable increase
+ if(sd->state.lr_flag != 2)
+ sd->bonus.speed_add_rate -= val;
+ break;
+ case SP_ASPD: //Raw increase
+ if(sd->state.lr_flag != 2)
+ sd->bonus.aspd_add -= 10*val;
+ break;
+ case SP_ASPD_RATE: //Stackable increase - Made it linear as per rodatazone
+ if(sd->state.lr_flag != 2)
#ifndef RENEWAL_ASPD
- status->aspd_rate -= 10*val;
+ status->aspd_rate -= 10*val;
#else
- status->aspd_rate2 += val;
+ status->aspd_rate2 += val;
#endif
- break;
- case SP_HP_RECOV_RATE:
- if (sd->state.lr_flag != 2)
- sd->hprecov_rate += val;
- break;
- case SP_SP_RECOV_RATE:
- if (sd->state.lr_flag != 2)
- sd->sprecov_rate += val;
- break;
- case SP_CRITICAL_DEF:
- if (sd->state.lr_flag != 2)
- sd->bonus.critical_def += val;
- break;
- case SP_NEAR_ATK_DEF:
- if (sd->state.lr_flag != 2)
- sd->bonus.near_attack_def_rate += val;
- break;
- case SP_LONG_ATK_DEF:
- if (sd->state.lr_flag != 2)
- sd->bonus.long_attack_def_rate += val;
- break;
- case SP_DOUBLE_RATE:
- if (sd->state.lr_flag == 0 && sd->bonus.double_rate < val)
- sd->bonus.double_rate = val;
- break;
- case SP_DOUBLE_ADD_RATE:
- if (sd->state.lr_flag == 0)
- sd->bonus.double_add_rate += val;
- break;
- case SP_MATK_RATE:
- if (sd->state.lr_flag != 2)
- sd->matk_rate += val;
- break;
- case SP_IGNORE_DEF_ELE:
- if (val >= ELE_MAX) {
- ShowError("pc_bonus: SP_IGNORE_DEF_ELE: Invalid element %d\n", val);
- break;
- }
- if (!sd->state.lr_flag)
- sd->right_weapon.ignore_def_ele |= 1<<val;
- else if (sd->state.lr_flag == 1)
- sd->left_weapon.ignore_def_ele |= 1<<val;
- break;
- case SP_IGNORE_DEF_RACE:
- if (!sd->state.lr_flag)
- sd->right_weapon.ignore_def_race |= 1<<val;
- else if (sd->state.lr_flag == 1)
- sd->left_weapon.ignore_def_race |= 1<<val;
- break;
- case SP_ATK_RATE:
- if (sd->state.lr_flag != 2)
- sd->bonus.atk_rate += val;
- break;
- case SP_MAGIC_ATK_DEF:
- if (sd->state.lr_flag != 2)
- sd->bonus.magic_def_rate += val;
- break;
- case SP_MISC_ATK_DEF:
- if (sd->state.lr_flag != 2)
- sd->bonus.misc_def_rate += val;
- break;
- case SP_IGNORE_MDEF_RATE:
- if (sd->state.lr_flag != 2) {
- sd->ignore_mdef[RC_NONBOSS] += val;
- sd->ignore_mdef[RC_BOSS] += val;
- }
- break;
- case SP_IGNORE_MDEF_ELE:
- if (val >= ELE_MAX) {
- ShowError("pc_bonus: SP_IGNORE_MDEF_ELE: Invalid element %d\n", val);
- break;
- }
- if (sd->state.lr_flag != 2)
- sd->bonus.ignore_mdef_ele |= 1<<val;
- break;
- case SP_IGNORE_MDEF_RACE:
- if (sd->state.lr_flag != 2)
- sd->bonus.ignore_mdef_race |= 1<<val;
- break;
- case SP_PERFECT_HIT_RATE:
- if (sd->state.lr_flag != 2 && sd->bonus.perfect_hit < val)
- sd->bonus.perfect_hit = val;
- break;
- case SP_PERFECT_HIT_ADD_RATE:
- if (sd->state.lr_flag != 2)
- sd->bonus.perfect_hit_add += val;
- break;
- case SP_CRITICAL_RATE:
- if (sd->state.lr_flag != 2)
- sd->critical_rate+=val;
- break;
- case SP_DEF_RATIO_ATK_ELE:
- if (val >= ELE_MAX) {
- ShowError("pc_bonus: SP_DEF_RATIO_ATK_ELE: Invalid element %d\n", val);
- break;
- }
- if (!sd->state.lr_flag)
- sd->right_weapon.def_ratio_atk_ele |= 1<<val;
- else if (sd->state.lr_flag == 1)
- sd->left_weapon.def_ratio_atk_ele |= 1<<val;
- break;
- case SP_DEF_RATIO_ATK_RACE:
- if (val >= RC_MAX) {
- ShowError("pc_bonus: SP_DEF_RATIO_ATK_RACE: Invalid race %d\n", val);
- break;
- }
- if (!sd->state.lr_flag)
- sd->right_weapon.def_ratio_atk_race |= 1<<val;
- else if (sd->state.lr_flag == 1)
- sd->left_weapon.def_ratio_atk_race |= 1<<val;
- break;
- case SP_HIT_RATE:
- if (sd->state.lr_flag != 2)
- sd->hit_rate += val;
- break;
- case SP_FLEE_RATE:
- if (sd->state.lr_flag != 2)
- sd->flee_rate += val;
- break;
- case SP_FLEE2_RATE:
- if (sd->state.lr_flag != 2)
- sd->flee2_rate += val;
- break;
- case SP_DEF_RATE:
- if (sd->state.lr_flag != 2)
- sd->def_rate += val;
- break;
- case SP_DEF2_RATE:
- if (sd->state.lr_flag != 2)
- sd->def2_rate += val;
- break;
- case SP_MDEF_RATE:
- if (sd->state.lr_flag != 2)
- sd->mdef_rate += val;
- break;
- case SP_MDEF2_RATE:
- if (sd->state.lr_flag != 2)
- sd->mdef2_rate += val;
- break;
- case SP_RESTART_FULL_RECOVER:
- if (sd->state.lr_flag != 2)
- sd->special_state.restart_full_recover = 1;
- break;
- case SP_NO_CASTCANCEL:
- if (sd->state.lr_flag != 2)
- sd->special_state.no_castcancel = 1;
- break;
- case SP_NO_CASTCANCEL2:
- if (sd->state.lr_flag != 2)
- sd->special_state.no_castcancel2 = 1;
- break;
- case SP_NO_SIZEFIX:
- if (sd->state.lr_flag != 2)
- sd->special_state.no_sizefix = 1;
- break;
- case SP_NO_MAGIC_DAMAGE:
- if (sd->state.lr_flag == 2)
- break;
- val+= sd->special_state.no_magic_damage;
- sd->special_state.no_magic_damage = cap_value(val,0,100);
- break;
- case SP_NO_WEAPON_DAMAGE:
- if (sd->state.lr_flag == 2)
- break;
- val+= sd->special_state.no_weapon_damage;
- sd->special_state.no_weapon_damage = cap_value(val,0,100);
- break;
- case SP_NO_MISC_DAMAGE:
- if (sd->state.lr_flag == 2)
- break;
- val+= sd->special_state.no_misc_damage;
- sd->special_state.no_misc_damage = cap_value(val,0,100);
- break;
- case SP_NO_GEMSTONE:
- if (sd->state.lr_flag != 2)
- sd->special_state.no_gemstone = 1;
- break;
- case SP_INTRAVISION: // Maya Purple Card effect allowing to see Hiding/Cloaking people [DracoRPG]
- if (sd->state.lr_flag != 2) {
- sd->special_state.intravision = 1;
- clif_status_load(&sd->bl, SI_INTRAVISION, 1);
- }
- break;
- case SP_NO_KNOCKBACK:
- if (sd->state.lr_flag != 2)
- sd->special_state.no_knockback = 1;
- break;
- case SP_SPLASH_RANGE:
- if (sd->bonus.splash_range < val)
- sd->bonus.splash_range = val;
- break;
- case SP_SPLASH_ADD_RANGE:
- sd->bonus.splash_add_range += val;
- break;
- case SP_SHORT_WEAPON_DAMAGE_RETURN:
- if (sd->state.lr_flag != 2)
- sd->bonus.short_weapon_damage_return += val;
- break;
- case SP_LONG_WEAPON_DAMAGE_RETURN:
- if (sd->state.lr_flag != 2)
- sd->bonus.long_weapon_damage_return += val;
- break;
- case SP_MAGIC_DAMAGE_RETURN: //AppleGirl Was Here
- if (sd->state.lr_flag != 2)
- sd->bonus.magic_damage_return += val;
- break;
- case SP_ALL_STATS: // [Valaris]
- if (sd->state.lr_flag!=2) {
- sd->param_bonus[SP_STR-SP_STR]+=val;
- sd->param_bonus[SP_AGI-SP_STR]+=val;
- sd->param_bonus[SP_VIT-SP_STR]+=val;
- sd->param_bonus[SP_INT-SP_STR]+=val;
- sd->param_bonus[SP_DEX-SP_STR]+=val;
- sd->param_bonus[SP_LUK-SP_STR]+=val;
- }
- break;
- case SP_AGI_VIT: // [Valaris]
- if (sd->state.lr_flag!=2) {
- sd->param_bonus[SP_AGI-SP_STR]+=val;
- sd->param_bonus[SP_VIT-SP_STR]+=val;
- }
- break;
- case SP_AGI_DEX_STR: // [Valaris]
- if (sd->state.lr_flag!=2) {
- sd->param_bonus[SP_AGI-SP_STR]+=val;
- sd->param_bonus[SP_DEX-SP_STR]+=val;
- sd->param_bonus[SP_STR-SP_STR]+=val;
- }
- break;
- case SP_PERFECT_HIDE: // [Valaris]
- if (sd->state.lr_flag!=2)
- sd->special_state.perfect_hiding=1;
- break;
- case SP_UNBREAKABLE:
- if (sd->state.lr_flag!=2)
- sd->bonus.unbreakable += val;
- break;
- case SP_UNBREAKABLE_WEAPON:
- if (sd->state.lr_flag != 2)
- sd->bonus.unbreakable_equip |= EQP_WEAPON;
- break;
- case SP_UNBREAKABLE_ARMOR:
- if (sd->state.lr_flag != 2)
- sd->bonus.unbreakable_equip |= EQP_ARMOR;
- break;
- case SP_UNBREAKABLE_HELM:
- if (sd->state.lr_flag != 2)
- sd->bonus.unbreakable_equip |= EQP_HELM;
- break;
- case SP_UNBREAKABLE_SHIELD:
- if (sd->state.lr_flag != 2)
- sd->bonus.unbreakable_equip |= EQP_SHIELD;
- break;
- case SP_UNBREAKABLE_GARMENT:
- if (sd->state.lr_flag != 2)
- sd->bonus.unbreakable_equip |= EQP_GARMENT;
- break;
- case SP_UNBREAKABLE_SHOES:
- if (sd->state.lr_flag != 2)
- sd->bonus.unbreakable_equip |= EQP_SHOES;
- break;
- case SP_CLASSCHANGE: // [Valaris]
- if (sd->state.lr_flag !=2)
- sd->bonus.classchange=val;
- break;
- case SP_LONG_ATK_RATE:
- if (sd->state.lr_flag != 2) //[Lupus] it should stack, too. As any other cards rate bonuses
- sd->bonus.long_attack_atk_rate+=val;
- break;
- case SP_BREAK_WEAPON_RATE:
- if (sd->state.lr_flag != 2)
- sd->bonus.break_weapon_rate+=val;
- break;
- case SP_BREAK_ARMOR_RATE:
- if (sd->state.lr_flag != 2)
- sd->bonus.break_armor_rate+=val;
- break;
- case SP_ADD_STEAL_RATE:
- if (sd->state.lr_flag != 2)
- sd->bonus.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->bonus.crit_atk_rate += val;
- break;
- case SP_NO_REGEN:
- if (sd->state.lr_flag != 2)
- sd->regen.state.block|=val;
- break;
- case SP_UNSTRIPABLE_WEAPON:
- if (sd->state.lr_flag != 2)
- sd->bonus.unstripable_equip |= EQP_WEAPON;
- break;
- case SP_UNSTRIPABLE:
- case SP_UNSTRIPABLE_ARMOR:
- if (sd->state.lr_flag != 2)
- sd->bonus.unstripable_equip |= EQP_ARMOR;
- break;
- case SP_UNSTRIPABLE_HELM:
- if (sd->state.lr_flag != 2)
- sd->bonus.unstripable_equip |= EQP_HELM;
- break;
- case SP_UNSTRIPABLE_SHIELD:
- if (sd->state.lr_flag != 2)
- sd->bonus.unstripable_equip |= EQP_SHIELD;
- break;
- case SP_HP_DRAIN_VALUE:
- if (!sd->state.lr_flag) {
- sd->right_weapon.hp_drain[RC_NONBOSS].value += val;
- sd->right_weapon.hp_drain[RC_BOSS].value += val;
- } else if (sd->state.lr_flag == 1) {
- sd->left_weapon.hp_drain[RC_NONBOSS].value += val;
- sd->left_weapon.hp_drain[RC_BOSS].value += val;
- }
- break;
- case SP_SP_DRAIN_VALUE:
- if (!sd->state.lr_flag) {
- sd->right_weapon.sp_drain[RC_NONBOSS].value += val;
- sd->right_weapon.sp_drain[RC_BOSS].value += val;
- } else if (sd->state.lr_flag == 1) {
- sd->left_weapon.sp_drain[RC_NONBOSS].value += val;
- sd->left_weapon.sp_drain[RC_BOSS].value += val;
- }
- break;
- case SP_SP_GAIN_VALUE:
- if (!sd->state.lr_flag)
- sd->bonus.sp_gain_value += val;
- break;
- case SP_HP_GAIN_VALUE:
- if (!sd->state.lr_flag)
- sd->bonus.hp_gain_value += val;
- break;
- case SP_MAGIC_SP_GAIN_VALUE:
- if (!sd->state.lr_flag)
- sd->bonus.magic_sp_gain_value += val;
- break;
- case SP_MAGIC_HP_GAIN_VALUE:
- if (!sd->state.lr_flag)
- sd->bonus.magic_hp_gain_value += val;
- break;
- case SP_ADD_HEAL_RATE:
- if (sd->state.lr_flag != 2)
- sd->bonus.add_heal_rate += val;
- break;
- case SP_ADD_HEAL2_RATE:
- if (sd->state.lr_flag != 2)
- sd->bonus.add_heal2_rate += val;
- break;
- case SP_ADD_ITEM_HEAL_RATE:
- if (sd->state.lr_flag != 2)
- sd->bonus.itemhealrate2 += val;
- break;
- case SP_EMATK:
- if(sd->state.lr_flag != 2)
- sd->bonus.ematk += val;
- break;
- case SP_FIXCASTRATE:
- if (sd->state.lr_flag != 2)
- sd->bonus.fixcastrate -= val;
- break;
- case SP_VARCASTRATE:
- if (sd->state.lr_flag != 2)
- sd->bonus.varcastrate -= val;
- break;
- default:
- ShowWarning("pc_bonus: unknown type %d %d !\n",type,val);
- break;
- }
- return 0;
+ break;
+ case SP_HP_RECOV_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->hprecov_rate += val;
+ break;
+ case SP_SP_RECOV_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->sprecov_rate += val;
+ break;
+ case SP_CRITICAL_DEF:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.critical_def += val;
+ break;
+ case SP_NEAR_ATK_DEF:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.near_attack_def_rate += val;
+ break;
+ case SP_LONG_ATK_DEF:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.long_attack_def_rate += val;
+ break;
+ case SP_DOUBLE_RATE:
+ if(sd->state.lr_flag == 0 && sd->bonus.double_rate < val)
+ sd->bonus.double_rate = val;
+ break;
+ case SP_DOUBLE_ADD_RATE:
+ if(sd->state.lr_flag == 0)
+ sd->bonus.double_add_rate += val;
+ break;
+ case SP_MATK_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->matk_rate += val;
+ break;
+ case SP_IGNORE_DEF_ELE:
+ if(val >= ELE_MAX) {
+ ShowError("pc_bonus: SP_IGNORE_DEF_ELE: Invalid element %d\n", val);
+ break;
+ }
+ if(!sd->state.lr_flag)
+ sd->right_weapon.ignore_def_ele |= 1<<val;
+ else if(sd->state.lr_flag == 1)
+ sd->left_weapon.ignore_def_ele |= 1<<val;
+ break;
+ case SP_IGNORE_DEF_RACE:
+ if(!sd->state.lr_flag)
+ sd->right_weapon.ignore_def_race |= 1<<val;
+ else if(sd->state.lr_flag == 1)
+ sd->left_weapon.ignore_def_race |= 1<<val;
+ break;
+ case SP_ATK_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.atk_rate += val;
+ break;
+ case SP_MAGIC_ATK_DEF:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.magic_def_rate += val;
+ break;
+ case SP_MISC_ATK_DEF:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.misc_def_rate += val;
+ break;
+ case SP_IGNORE_MDEF_RATE:
+ if(sd->state.lr_flag != 2) {
+ sd->ignore_mdef[RC_NONBOSS] += val;
+ sd->ignore_mdef[RC_BOSS] += val;
+ }
+ break;
+ case SP_IGNORE_MDEF_ELE:
+ if(val >= ELE_MAX) {
+ ShowError("pc_bonus: SP_IGNORE_MDEF_ELE: Invalid element %d\n", val);
+ break;
+ }
+ if(sd->state.lr_flag != 2)
+ sd->bonus.ignore_mdef_ele |= 1<<val;
+ break;
+ case SP_IGNORE_MDEF_RACE:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.ignore_mdef_race |= 1<<val;
+ break;
+ case SP_PERFECT_HIT_RATE:
+ if(sd->state.lr_flag != 2 && sd->bonus.perfect_hit < val)
+ sd->bonus.perfect_hit = val;
+ break;
+ case SP_PERFECT_HIT_ADD_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.perfect_hit_add += val;
+ break;
+ case SP_CRITICAL_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->critical_rate+=val;
+ break;
+ case SP_DEF_RATIO_ATK_ELE:
+ if(val >= ELE_MAX) {
+ ShowError("pc_bonus: SP_DEF_RATIO_ATK_ELE: Invalid element %d\n", val);
+ break;
+ }
+ if(!sd->state.lr_flag)
+ sd->right_weapon.def_ratio_atk_ele |= 1<<val;
+ else if(sd->state.lr_flag == 1)
+ sd->left_weapon.def_ratio_atk_ele |= 1<<val;
+ break;
+ case SP_DEF_RATIO_ATK_RACE:
+ if(val >= RC_MAX) {
+ ShowError("pc_bonus: SP_DEF_RATIO_ATK_RACE: Invalid race %d\n", val);
+ break;
+ }
+ if(!sd->state.lr_flag)
+ sd->right_weapon.def_ratio_atk_race |= 1<<val;
+ else if(sd->state.lr_flag == 1)
+ sd->left_weapon.def_ratio_atk_race |= 1<<val;
+ break;
+ case SP_HIT_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->hit_rate += val;
+ break;
+ case SP_FLEE_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->flee_rate += val;
+ break;
+ case SP_FLEE2_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->flee2_rate += val;
+ break;
+ case SP_DEF_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->def_rate += val;
+ break;
+ case SP_DEF2_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->def2_rate += val;
+ break;
+ case SP_MDEF_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->mdef_rate += val;
+ break;
+ case SP_MDEF2_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->mdef2_rate += val;
+ break;
+ case SP_RESTART_FULL_RECOVER:
+ if(sd->state.lr_flag != 2)
+ sd->special_state.restart_full_recover = 1;
+ break;
+ case SP_NO_CASTCANCEL:
+ if(sd->state.lr_flag != 2)
+ sd->special_state.no_castcancel = 1;
+ break;
+ case SP_NO_CASTCANCEL2:
+ if(sd->state.lr_flag != 2)
+ sd->special_state.no_castcancel2 = 1;
+ break;
+ case SP_NO_SIZEFIX:
+ if(sd->state.lr_flag != 2)
+ sd->special_state.no_sizefix = 1;
+ break;
+ case SP_NO_MAGIC_DAMAGE:
+ if(sd->state.lr_flag == 2)
+ break;
+ val+= sd->special_state.no_magic_damage;
+ sd->special_state.no_magic_damage = cap_value(val,0,100);
+ break;
+ case SP_NO_WEAPON_DAMAGE:
+ if(sd->state.lr_flag == 2)
+ break;
+ val+= sd->special_state.no_weapon_damage;
+ sd->special_state.no_weapon_damage = cap_value(val,0,100);
+ break;
+ case SP_NO_MISC_DAMAGE:
+ if(sd->state.lr_flag == 2)
+ break;
+ val+= sd->special_state.no_misc_damage;
+ sd->special_state.no_misc_damage = cap_value(val,0,100);
+ break;
+ case SP_NO_GEMSTONE:
+ if(sd->state.lr_flag != 2)
+ sd->special_state.no_gemstone = 1;
+ break;
+ case SP_INTRAVISION: // Maya Purple Card effect allowing to see Hiding/Cloaking people [DracoRPG]
+ if(sd->state.lr_flag != 2) {
+ sd->special_state.intravision = 1;
+ clif_status_load(&sd->bl, SI_INTRAVISION, 1);
+ }
+ break;
+ case SP_NO_KNOCKBACK:
+ if(sd->state.lr_flag != 2)
+ sd->special_state.no_knockback = 1;
+ break;
+ case SP_SPLASH_RANGE:
+ if(sd->bonus.splash_range < val)
+ sd->bonus.splash_range = val;
+ break;
+ case SP_SPLASH_ADD_RANGE:
+ sd->bonus.splash_add_range += val;
+ break;
+ case SP_SHORT_WEAPON_DAMAGE_RETURN:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.short_weapon_damage_return += val;
+ break;
+ case SP_LONG_WEAPON_DAMAGE_RETURN:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.long_weapon_damage_return += val;
+ break;
+ case SP_MAGIC_DAMAGE_RETURN: //AppleGirl Was Here
+ if(sd->state.lr_flag != 2)
+ sd->bonus.magic_damage_return += val;
+ break;
+ case SP_ALL_STATS: // [Valaris]
+ if(sd->state.lr_flag!=2) {
+ sd->param_bonus[SP_STR-SP_STR]+=val;
+ sd->param_bonus[SP_AGI-SP_STR]+=val;
+ sd->param_bonus[SP_VIT-SP_STR]+=val;
+ sd->param_bonus[SP_INT-SP_STR]+=val;
+ sd->param_bonus[SP_DEX-SP_STR]+=val;
+ sd->param_bonus[SP_LUK-SP_STR]+=val;
+ }
+ break;
+ case SP_AGI_VIT: // [Valaris]
+ if(sd->state.lr_flag!=2) {
+ sd->param_bonus[SP_AGI-SP_STR]+=val;
+ sd->param_bonus[SP_VIT-SP_STR]+=val;
+ }
+ break;
+ case SP_AGI_DEX_STR: // [Valaris]
+ if(sd->state.lr_flag!=2) {
+ sd->param_bonus[SP_AGI-SP_STR]+=val;
+ sd->param_bonus[SP_DEX-SP_STR]+=val;
+ sd->param_bonus[SP_STR-SP_STR]+=val;
+ }
+ break;
+ case SP_PERFECT_HIDE: // [Valaris]
+ if(sd->state.lr_flag!=2)
+ sd->special_state.perfect_hiding=1;
+ break;
+ case SP_UNBREAKABLE:
+ if(sd->state.lr_flag!=2)
+ sd->bonus.unbreakable += val;
+ break;
+ case SP_UNBREAKABLE_WEAPON:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.unbreakable_equip |= EQP_WEAPON;
+ break;
+ case SP_UNBREAKABLE_ARMOR:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.unbreakable_equip |= EQP_ARMOR;
+ break;
+ case SP_UNBREAKABLE_HELM:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.unbreakable_equip |= EQP_HELM;
+ break;
+ case SP_UNBREAKABLE_SHIELD:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.unbreakable_equip |= EQP_SHIELD;
+ break;
+ case SP_UNBREAKABLE_GARMENT:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.unbreakable_equip |= EQP_GARMENT;
+ break;
+ case SP_UNBREAKABLE_SHOES:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.unbreakable_equip |= EQP_SHOES;
+ break;
+ case SP_CLASSCHANGE: // [Valaris]
+ if(sd->state.lr_flag !=2)
+ sd->bonus.classchange=val;
+ break;
+ case SP_LONG_ATK_RATE:
+ if(sd->state.lr_flag != 2) //[Lupus] it should stack, too. As any other cards rate bonuses
+ sd->bonus.long_attack_atk_rate+=val;
+ break;
+ case SP_BREAK_WEAPON_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.break_weapon_rate+=val;
+ break;
+ case SP_BREAK_ARMOR_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.break_armor_rate+=val;
+ break;
+ case SP_ADD_STEAL_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.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->bonus.crit_atk_rate += val;
+ break;
+ case SP_NO_REGEN:
+ if(sd->state.lr_flag != 2)
+ sd->regen.state.block|=val;
+ break;
+ case SP_UNSTRIPABLE_WEAPON:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.unstripable_equip |= EQP_WEAPON;
+ break;
+ case SP_UNSTRIPABLE:
+ case SP_UNSTRIPABLE_ARMOR:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.unstripable_equip |= EQP_ARMOR;
+ break;
+ case SP_UNSTRIPABLE_HELM:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.unstripable_equip |= EQP_HELM;
+ break;
+ case SP_UNSTRIPABLE_SHIELD:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.unstripable_equip |= EQP_SHIELD;
+ break;
+ case SP_HP_DRAIN_VALUE:
+ if(!sd->state.lr_flag) {
+ sd->right_weapon.hp_drain[RC_NONBOSS].value += val;
+ sd->right_weapon.hp_drain[RC_BOSS].value += val;
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->left_weapon.hp_drain[RC_NONBOSS].value += val;
+ sd->left_weapon.hp_drain[RC_BOSS].value += val;
+ }
+ break;
+ case SP_SP_DRAIN_VALUE:
+ if(!sd->state.lr_flag) {
+ sd->right_weapon.sp_drain[RC_NONBOSS].value += val;
+ sd->right_weapon.sp_drain[RC_BOSS].value += val;
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->left_weapon.sp_drain[RC_NONBOSS].value += val;
+ sd->left_weapon.sp_drain[RC_BOSS].value += val;
+ }
+ break;
+ case SP_SP_GAIN_VALUE:
+ if(!sd->state.lr_flag)
+ sd->bonus.sp_gain_value += val;
+ break;
+ case SP_HP_GAIN_VALUE:
+ if(!sd->state.lr_flag)
+ sd->bonus.hp_gain_value += val;
+ break;
+ case SP_MAGIC_SP_GAIN_VALUE:
+ if(!sd->state.lr_flag)
+ sd->bonus.magic_sp_gain_value += val;
+ break;
+ case SP_MAGIC_HP_GAIN_VALUE:
+ if(!sd->state.lr_flag)
+ sd->bonus.magic_hp_gain_value += val;
+ break;
+ case SP_ADD_HEAL_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.add_heal_rate += val;
+ break;
+ case SP_ADD_HEAL2_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.add_heal2_rate += val;
+ break;
+ case SP_ADD_ITEM_HEAL_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.itemhealrate2 += val;
+ break;
+ case SP_WEAPON_MATK:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.sp_weapon_matk += val;
+ break;
+ case SP_BASE_MATK:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.sp_base_matk += val;
+ break;
+ case SP_FIXCASTRATE:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.fixcastrate -= val;
+ break;
+ case SP_VARCASTRATE:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.varcastrate -= val;
+ break;
+ default:
+ ShowWarning("pc_bonus: unknown type %d %d !\n",type,val);
+ break;
+ }
+ return 0;
}
/*==========================================
@@ -2557,855 +2617,879 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
*------------------------------------------*/
int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
{
- int i;
-
- nullpo_ret(sd);
-
- switch (type) {
- case SP_ADDELE:
- if (type2 >= ELE_MAX) {
- ShowError("pc_bonus2: SP_ADDELE: Invalid element %d\n", type2);
- break;
- }
- if (!sd->state.lr_flag)
- sd->right_weapon.addele[type2]+=val;
- else if (sd->state.lr_flag == 1)
- sd->left_weapon.addele[type2]+=val;
- else if (sd->state.lr_flag == 2)
- sd->arrow_addele[type2]+=val;
- break;
- case SP_ADDRACE:
- if (!sd->state.lr_flag)
- sd->right_weapon.addrace[type2]+=val;
- else if (sd->state.lr_flag == 1)
- sd->left_weapon.addrace[type2]+=val;
- else if (sd->state.lr_flag == 2)
- sd->arrow_addrace[type2]+=val;
- break;
- case SP_ADDSIZE:
- if (!sd->state.lr_flag)
- sd->right_weapon.addsize[type2]+=val;
- else if (sd->state.lr_flag == 1)
- sd->left_weapon.addsize[type2]+=val;
- else if (sd->state.lr_flag == 2)
- sd->arrow_addsize[type2]+=val;
- break;
- case SP_SUBELE:
- if (type2 >= ELE_MAX) {
- ShowError("pc_bonus2: SP_SUBELE: Invalid element %d\n", type2);
- break;
- }
- if (sd->state.lr_flag != 2)
- sd->subele[type2]+=val;
- break;
- case SP_SUBRACE:
- if (sd->state.lr_flag != 2)
- sd->subrace[type2]+=val;
- break;
- case SP_ADDEFF:
- if (type2 > SC_MAX) {
- ShowWarning("pc_bonus2 (Add Effect): %d is not supported.\n", type2);
- break;
- }
- pc_bonus_addeff(sd->addeff, ARRAYLENGTH(sd->addeff), (sc_type)type2,
- sd->state.lr_flag!=2?val:0, sd->state.lr_flag==2?val:0, 0);
- break;
- case SP_ADDEFF2:
- if (type2 > SC_MAX) {
- ShowWarning("pc_bonus2 (Add Effect2): %d is not supported.\n", type2);
- break;
- }
- pc_bonus_addeff(sd->addeff, ARRAYLENGTH(sd->addeff), (sc_type)type2,
- sd->state.lr_flag!=2?val:0, sd->state.lr_flag==2?val:0, ATF_SELF);
- break;
- case SP_RESEFF:
- if (type2 < SC_COMMON_MIN || type2 > SC_COMMON_MAX) {
- ShowWarning("pc_bonus2 (Resist Effect): %d is not supported.\n", type2);
- break;
- }
- if (sd->state.lr_flag == 2)
- break;
- i = sd->reseff[type2-SC_COMMON_MIN]+val;
- sd->reseff[type2-SC_COMMON_MIN]= cap_value(i, 0, 10000);
- break;
- case SP_MAGIC_ADDELE:
- if (type2 >= ELE_MAX) {
- ShowError("pc_bonus2: SP_MAGIC_ADDELE: Invalid element %d\n", type2);
- break;
- }
- if (sd->state.lr_flag != 2)
- sd->magic_addele[type2]+=val;
- break;
- case SP_MAGIC_ADDRACE:
- if (sd->state.lr_flag != 2)
- sd->magic_addrace[type2]+=val;
- break;
- case SP_MAGIC_ADDSIZE:
- if (sd->state.lr_flag != 2)
- sd->magic_addsize[type2]+=val;
- break;
- case SP_ADD_DAMAGE_CLASS:
- switch (sd->state.lr_flag) {
- case 0: //Right hand
- ARR_FIND(0, ARRAYLENGTH(sd->right_weapon.add_dmg), i, sd->right_weapon.add_dmg[i].rate == 0 || sd->right_weapon.add_dmg[i].class_ == type2);
- if (i == ARRAYLENGTH(sd->right_weapon.add_dmg)) {
- ShowWarning("pc_bonus2: Reached max (%d) number of add Class dmg bonuses per character!\n", ARRAYLENGTH(sd->right_weapon.add_dmg));
- break;
- }
- sd->right_weapon.add_dmg[i].class_ = type2;
- sd->right_weapon.add_dmg[i].rate += val;
- if (!sd->right_weapon.add_dmg[i].rate) //Shift the rest of elements up.
- memmove(&sd->right_weapon.add_dmg[i], &sd->right_weapon.add_dmg[i+1], sizeof(sd->right_weapon.add_dmg) - (i+1)*sizeof(sd->right_weapon.add_dmg[0]));
- break;
- case 1: //Left hand
- ARR_FIND(0, ARRAYLENGTH(sd->left_weapon.add_dmg), i, sd->left_weapon.add_dmg[i].rate == 0 || sd->left_weapon.add_dmg[i].class_ == type2);
- if (i == ARRAYLENGTH(sd->left_weapon.add_dmg)) {
- ShowWarning("pc_bonus2: Reached max (%d) number of add Class dmg bonuses per character!\n", ARRAYLENGTH(sd->left_weapon.add_dmg));
- break;
- }
- sd->left_weapon.add_dmg[i].class_ = type2;
- sd->left_weapon.add_dmg[i].rate += val;
- if (!sd->left_weapon.add_dmg[i].rate) //Shift the rest of elements up.
- memmove(&sd->left_weapon.add_dmg[i], &sd->left_weapon.add_dmg[i+1], sizeof(sd->left_weapon.add_dmg) - (i+1)*sizeof(sd->left_weapon.add_dmg[0]));
- break;
- }
- break;
- case SP_ADD_MAGIC_DAMAGE_CLASS:
- if (sd->state.lr_flag == 2)
- break;
- ARR_FIND(0, ARRAYLENGTH(sd->add_mdmg), i, sd->add_mdmg[i].rate == 0 || sd->add_mdmg[i].class_ == type2);
- if (i == ARRAYLENGTH(sd->add_mdmg)) {
- ShowWarning("pc_bonus2: Reached max (%d) number of add Class magic dmg bonuses per character!\n", ARRAYLENGTH(sd->add_mdmg));
- break;
- }
- sd->add_mdmg[i].class_ = type2;
- sd->add_mdmg[i].rate += val;
- if (!sd->add_mdmg[i].rate) //Shift the rest of elements up.
- memmove(&sd->add_mdmg[i], &sd->add_mdmg[i+1], sizeof(sd->add_mdmg) - (i+1)*sizeof(sd->add_mdmg[0]));
- break;
- case SP_ADD_DEF_CLASS:
- if (sd->state.lr_flag == 2)
- break;
- ARR_FIND(0, ARRAYLENGTH(sd->add_def), i, sd->add_def[i].rate == 0 || sd->add_def[i].class_ == type2);
- if (i == ARRAYLENGTH(sd->add_def)) {
- ShowWarning("pc_bonus2: Reached max (%d) number of add Class def bonuses per character!\n", ARRAYLENGTH(sd->add_def));
- break;
- }
- sd->add_def[i].class_ = type2;
- sd->add_def[i].rate += val;
- if (!sd->add_def[i].rate) //Shift the rest of elements up.
- memmove(&sd->add_def[i], &sd->add_def[i+1], sizeof(sd->add_def) - (i+1)*sizeof(sd->add_def[0]));
- break;
- case SP_ADD_MDEF_CLASS:
- if (sd->state.lr_flag == 2)
- break;
- ARR_FIND(0, ARRAYLENGTH(sd->add_mdef), i, sd->add_mdef[i].rate == 0 || sd->add_mdef[i].class_ == type2);
- if (i == ARRAYLENGTH(sd->add_mdef)) {
- ShowWarning("pc_bonus2: Reached max (%d) number of add Class mdef bonuses per character!\n", ARRAYLENGTH(sd->add_mdef));
- break;
- }
- sd->add_mdef[i].class_ = type2;
- sd->add_mdef[i].rate += val;
- if (!sd->add_mdef[i].rate) //Shift the rest of elements up.
- memmove(&sd->add_mdef[i], &sd->add_mdef[i+1], sizeof(sd->add_mdef) - (i+1)*sizeof(sd->add_mdef[0]));
- break;
- case SP_HP_DRAIN_RATE:
- if (!sd->state.lr_flag) {
- sd->right_weapon.hp_drain[RC_NONBOSS].rate += type2;
- sd->right_weapon.hp_drain[RC_NONBOSS].per += val;
- sd->right_weapon.hp_drain[RC_BOSS].rate += type2;
- sd->right_weapon.hp_drain[RC_BOSS].per += val;
- } else if (sd->state.lr_flag == 1) {
- sd->left_weapon.hp_drain[RC_NONBOSS].rate += type2;
- sd->left_weapon.hp_drain[RC_NONBOSS].per += val;
- sd->left_weapon.hp_drain[RC_BOSS].rate += type2;
- sd->left_weapon.hp_drain[RC_BOSS].per += val;
- }
- break;
- case SP_HP_DRAIN_VALUE:
- if (!sd->state.lr_flag) {
- sd->right_weapon.hp_drain[RC_NONBOSS].value += type2;
- sd->right_weapon.hp_drain[RC_NONBOSS].type = val;
- sd->right_weapon.hp_drain[RC_BOSS].value += type2;
- sd->right_weapon.hp_drain[RC_BOSS].type = val;
- } else if (sd->state.lr_flag == 1) {
- sd->left_weapon.hp_drain[RC_NONBOSS].value += type2;
- sd->left_weapon.hp_drain[RC_NONBOSS].type = val;
- sd->left_weapon.hp_drain[RC_BOSS].value += type2;
- sd->left_weapon.hp_drain[RC_BOSS].type = val;
- }
- break;
- case SP_SP_DRAIN_RATE:
- if (!sd->state.lr_flag) {
- sd->right_weapon.sp_drain[RC_NONBOSS].rate += type2;
- sd->right_weapon.sp_drain[RC_NONBOSS].per += val;
- sd->right_weapon.sp_drain[RC_BOSS].rate += type2;
- sd->right_weapon.sp_drain[RC_BOSS].per += val;
- } else if (sd->state.lr_flag == 1) {
- sd->left_weapon.sp_drain[RC_NONBOSS].rate += type2;
- sd->left_weapon.sp_drain[RC_NONBOSS].per += val;
- sd->left_weapon.sp_drain[RC_BOSS].rate += type2;
- sd->left_weapon.sp_drain[RC_BOSS].per += val;
- }
- break;
- case SP_SP_DRAIN_VALUE:
- if (!sd->state.lr_flag) {
- sd->right_weapon.sp_drain[RC_NONBOSS].value += type2;
- sd->right_weapon.sp_drain[RC_NONBOSS].type = val;
- sd->right_weapon.sp_drain[RC_BOSS].value += type2;
- sd->right_weapon.sp_drain[RC_BOSS].type = val;
- } else if (sd->state.lr_flag == 1) {
- sd->left_weapon.sp_drain[RC_NONBOSS].value += type2;
- sd->left_weapon.sp_drain[RC_NONBOSS].type = val;
- sd->left_weapon.sp_drain[RC_BOSS].value += type2;
- sd->left_weapon.sp_drain[RC_BOSS].type = val;
- }
- break;
- case SP_SP_VANISH_RATE:
- if (sd->state.lr_flag != 2) {
- sd->bonus.sp_vanish_rate += type2;
- sd->bonus.sp_vanish_per += val;
- }
- break;
- case SP_GET_ZENY_NUM:
- if (sd->state.lr_flag != 2 && sd->bonus.get_zeny_rate < val) {
- sd->bonus.get_zeny_rate = val;
- sd->bonus.get_zeny_num = type2;
- }
- break;
- case SP_ADD_GET_ZENY_NUM:
- if (sd->state.lr_flag != 2) {
- sd->bonus.get_zeny_rate += val;
- sd->bonus.get_zeny_num += type2;
- }
- break;
- case SP_WEAPON_COMA_ELE:
- if (type2 >= ELE_MAX) {
- ShowError("pc_bonus2: SP_WEAPON_COMA_ELE: Invalid element %d\n", type2);
- break;
- }
- if (sd->state.lr_flag == 2)
- break;
- sd->weapon_coma_ele[type2] += val;
- sd->special_state.bonus_coma = 1;
- break;
- case SP_WEAPON_COMA_RACE:
- if (sd->state.lr_flag == 2)
- break;
- sd->weapon_coma_race[type2] += val;
- sd->special_state.bonus_coma = 1;
- 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*10;
- break;
- case SP_ADDEFF_WHENHIT:
- if (type2 > SC_MAX) {
- ShowWarning("pc_bonus2 (Add Effect when hit): %d is not supported.\n", type2);
- break;
- }
- if (sd->state.lr_flag != 2)
- pc_bonus_addeff(sd->addeff2, ARRAYLENGTH(sd->addeff2), (sc_type)type2, val, 0, 0);
- break;
- case SP_SKILL_ATK:
- if (sd->state.lr_flag == 2)
- break;
- ARR_FIND(0, ARRAYLENGTH(sd->skillatk), i, sd->skillatk[i].id == 0 || sd->skillatk[i].id == type2);
- if (i == ARRAYLENGTH(sd->skillatk)) {
- //Better mention this so the array length can be updated. [Skotlex]
- ShowDebug("run_script: bonus2 bSkillAtk reached its limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillatk), type2, val);
- break;
- }
- if (sd->skillatk[i].id == type2)
- sd->skillatk[i].val += val;
- else {
- sd->skillatk[i].id = type2;
- sd->skillatk[i].val = val;
- }
- break;
- case SP_SKILL_HEAL:
- if (sd->state.lr_flag == 2)
- break;
- ARR_FIND(0, ARRAYLENGTH(sd->skillheal), i, sd->skillheal[i].id == 0 || sd->skillheal[i].id == type2);
- if (i == ARRAYLENGTH(sd->skillheal)) {
- // Better mention this so the array length can be updated. [Skotlex]
- ShowDebug("run_script: bonus2 bSkillHeal reached its limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillheal), type2, val);
- break;
- }
- if (sd->skillheal[i].id == type2)
- sd->skillheal[i].val += val;
- else {
- sd->skillheal[i].id = type2;
- sd->skillheal[i].val = val;
- }
- break;
- case SP_SKILL_HEAL2:
- if (sd->state.lr_flag == 2)
- break;
- ARR_FIND(0, ARRAYLENGTH(sd->skillheal2), i, sd->skillheal2[i].id == 0 || sd->skillheal2[i].id == type2);
- if (i == ARRAYLENGTH(sd->skillheal2)) {
- // Better mention this so the array length can be updated. [Skotlex]
- ShowDebug("run_script: bonus2 bSkillHeal2 reached its limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillheal2), type2, val);
- break;
- }
- if (sd->skillheal2[i].id == type2)
- sd->skillheal2[i].val += val;
- else {
- sd->skillheal2[i].id = type2;
- sd->skillheal2[i].val = val;
- }
- break;
- case SP_ADD_SKILL_BLOW:
- if (sd->state.lr_flag == 2)
- break;
- ARR_FIND(0, ARRAYLENGTH(sd->skillblown), i, sd->skillblown[i].id == 0 || sd->skillblown[i].id == type2);
- if (i == ARRAYLENGTH(sd->skillblown)) {
- //Better mention this so the array length can be updated. [Skotlex]
- ShowDebug("run_script: bonus2 bSkillBlown reached its limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillblown), type2, val);
- break;
- }
- if (sd->skillblown[i].id == type2)
- sd->skillblown[i].val += val;
- else {
- sd->skillblown[i].id = type2;
- sd->skillblown[i].val = val;
- }
- break;
-
- case SP_CASTRATE:
- if (sd->state.lr_flag == 2)
- break;
- ARR_FIND(0, ARRAYLENGTH(sd->skillcast), i, sd->skillcast[i].id == 0 || sd->skillcast[i].id == type2);
- if (i == ARRAYLENGTH(sd->skillcast)) {
- //Better mention this so the array length can be updated. [Skotlex]
- ShowDebug("run_script: bonus2 bCastRate reached its limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillcast), type2, val);
- break;
- }
- if (sd->skillcast[i].id == type2)
- sd->skillcast[i].val += val;
- else {
- sd->skillcast[i].id = type2;
- sd->skillcast[i].val = val;
- }
- 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_HP_REGEN_RATE:
- if (sd->state.lr_flag != 2) {
- sd->hp_regen.value = type2;
- sd->hp_regen.rate = val;
- }
- break;
- case SP_ADDRACE2:
- if (!(type2 > RC2_NONE && type2 < RC2_MAX))
- break;
- if (sd->state.lr_flag != 2)
- sd->right_weapon.addrace2[type2] += val;
- else
- sd->left_weapon.addrace2[type2] += val;
- break;
- case SP_SUBSIZE:
- if (sd->state.lr_flag != 2)
- sd->subsize[type2]+=val;
- break;
- case SP_SUBRACE2:
- if (!(type2 > RC2_NONE && type2 < RC2_MAX))
- break;
- if (sd->state.lr_flag != 2)
- sd->subrace2[type2]+=val;
- break;
- case SP_ADD_ITEM_HEAL_RATE:
- if (sd->state.lr_flag == 2)
- break;
- if (type2 < MAX_ITEMGROUP) { //Group bonus
- sd->itemgrouphealrate[type2] += val;
- break;
- }
- //Standard item bonus.
- for (i=0; i < ARRAYLENGTH(sd->itemhealrate) && sd->itemhealrate[i].nameid && sd->itemhealrate[i].nameid != type2; i++);
- if (i == ARRAYLENGTH(sd->itemhealrate)) {
- ShowWarning("pc_bonus2: Reached max (%d) number of item heal bonuses per character!\n", ARRAYLENGTH(sd->itemhealrate));
- break;
- }
- sd->itemhealrate[i].nameid = type2;
- sd->itemhealrate[i].rate += 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;
- case SP_ADD_MONSTER_DROP_ITEM:
- if (sd->state.lr_flag != 2)
- pc_bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), type2, 0, (1<<RC_BOSS)|(1<<RC_NONBOSS), val);
- break;
- case SP_ADD_MONSTER_DROP_ITEMGROUP:
- if (sd->state.lr_flag != 2)
- pc_bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), 0, type2, (1<<RC_BOSS)|(1<<RC_NONBOSS), val);
- break;
- case SP_SP_LOSS_RATE:
- if (sd->state.lr_flag != 2) {
- sd->sp_loss.value = type2;
- sd->sp_loss.rate = val;
- }
- break;
- case SP_SP_REGEN_RATE:
- if (sd->state.lr_flag != 2) {
- sd->sp_regen.value = type2;
- sd->sp_regen.rate = val;
- }
- break;
- case SP_HP_DRAIN_VALUE_RACE:
- if (!sd->state.lr_flag) {
- sd->right_weapon.hp_drain[type2].value += val;
- } else if (sd->state.lr_flag == 1) {
- sd->left_weapon.hp_drain[type2].value += val;
- }
- break;
- case SP_SP_DRAIN_VALUE_RACE:
- if (!sd->state.lr_flag) {
- sd->right_weapon.sp_drain[type2].value += val;
- } else if (sd->state.lr_flag == 1) {
- sd->left_weapon.sp_drain[type2].value += val;
- }
- break;
- case SP_IGNORE_MDEF_RATE:
- if (sd->state.lr_flag != 2)
- sd->ignore_mdef[type2] += val;
- break;
- case SP_IGNORE_DEF_RATE:
- if (sd->state.lr_flag != 2)
- sd->ignore_def[type2] += val;
- break;
- case SP_SP_GAIN_RACE_ATTACK:
- if (sd->state.lr_flag != 2)
- sd->sp_gain_race_attack[type2] = cap_value(sd->sp_gain_race_attack[type2] + val, 0, INT16_MAX);
- break;
- case SP_HP_GAIN_RACE_ATTACK:
- if (sd->state.lr_flag != 2)
- sd->hp_gain_race_attack[type2] = cap_value(sd->hp_gain_race_attack[type2] + val, 0, INT16_MAX);
- break;
- case SP_SKILL_USE_SP_RATE: //bonus2 bSkillUseSPrate,n,x;
- if (sd->state.lr_flag == 2)
- break;
- ARR_FIND(0, ARRAYLENGTH(sd->skillusesprate), i, sd->skillusesprate[i].id == 0 || sd->skillusesprate[i].id == type2);
- if (i == ARRAYLENGTH(sd->skillusesprate)) {
- ShowDebug("run_script: bonus2 bSkillUseSPrate reached its limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillusesprate), type2, val);
- break;
- }
- if (sd->skillusesprate[i].id == type2)
- sd->skillusesprate[i].val += val;
- else {
- sd->skillusesprate[i].id = type2;
- sd->skillusesprate[i].val = val;
- }
- break;
- case SP_SKILL_COOLDOWN:
- if (sd->state.lr_flag == 2)
- break;
- ARR_FIND(0, ARRAYLENGTH(sd->skillcooldown), i, sd->skillcooldown[i].id == 0 || sd->skillcooldown[i].id == type2);
- if (i == ARRAYLENGTH(sd->skillcooldown)) {
- ShowDebug("run_script: bonus2 bSkillCoolDown reached its limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillcooldown), type2, val);
- break;
- }
- if (sd->skillcooldown[i].id == type2)
- sd->skillcooldown[i].val += val;
- else {
- sd->skillcooldown[i].id = type2;
- sd->skillcooldown[i].val = val;
- }
- break;
- case SP_SKILL_FIXEDCAST:
- if (sd->state.lr_flag == 2)
- break;
- ARR_FIND(0, ARRAYLENGTH(sd->skillfixcast), i, sd->skillfixcast[i].id == 0 || sd->skillfixcast[i].id == type2);
- if (i == ARRAYLENGTH(sd->skillfixcast)) {
- ShowDebug("run_script: bonus2 bSkillFixedCast reached its limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillfixcast), type2, val);
- break;
- }
- if (sd->skillfixcast[i].id == type2)
- sd->skillfixcast[i].val += val;
- else {
- sd->skillfixcast[i].id = type2;
- sd->skillfixcast[i].val = val;
- }
- break;
- case SP_SKILL_VARIABLECAST:
- if (sd->state.lr_flag == 2)
- break;
- ARR_FIND(0, ARRAYLENGTH(sd->skillvarcast), i, sd->skillvarcast[i].id == 0 || sd->skillvarcast[i].id == type2);
- if (i == ARRAYLENGTH(sd->skillvarcast)) {
- ShowDebug("run_script: bonus2 bSkillVariableCast reached its limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillvarcast), type2, val);
- break;
- }
- if (sd->skillvarcast[i].id == type2)
- sd->skillvarcast[i].val += val;
- else {
- sd->skillvarcast[i].id = type2;
- sd->skillvarcast[i].val = val;
- }
- break;
- case SP_VARCASTRATE:
- if (sd->state.lr_flag == 2)
- break;
- ARR_FIND(0, ARRAYLENGTH(sd->skillcast), i, sd->skillcast[i].id == 0 || sd->skillcast[i].id == type2);
- if (i == ARRAYLENGTH(sd->skillcast)) {
- ShowDebug("run_script: bonus2 bVariableCastrate reached its limit (%d skills per character), bonus skill %d (+%d%%) lost.\n",ARRAYLENGTH(sd->skillcast), type2, val);
- break;
- }
- if (sd->skillcast[i].id == type2)
- sd->skillcast[i].val -= val;
- else {
- sd->skillcast[i].id = type2;
- sd->skillcast[i].val -= val;
- }
- break;
- case SP_SKILL_USE_SP: //bonus2 bSkillUseSP,n,x;
- if (sd->state.lr_flag == 2)
- break;
- ARR_FIND(0, ARRAYLENGTH(sd->skillusesp), i, sd->skillusesp[i].id == 0 || sd->skillusesp[i].id == type2);
- if (i == ARRAYLENGTH(sd->skillusesp)) {
- ShowDebug("run_script: bonus2 bSkillUseSP reached its limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillusesp), type2, val);
- break;
- }
- if (sd->skillusesp[i].id == type2)
- sd->skillusesp[i].val += val;
- else {
- sd->skillusesp[i].id = type2;
- sd->skillusesp[i].val = val;
- }
- break;
- default:
- ShowWarning("pc_bonus2: unknown type %d %d %d!\n",type,type2,val);
- break;
- }
- return 0;
+ int i;
+
+ nullpo_ret(sd);
+
+ switch(type){
+ case SP_ADDELE:
+ if(type2 >= ELE_MAX) {
+ ShowError("pc_bonus2: SP_ADDELE: Invalid element %d\n", type2);
+ break;
+ }
+ if(!sd->state.lr_flag)
+ sd->right_weapon.addele[type2]+=val;
+ else if(sd->state.lr_flag == 1)
+ sd->left_weapon.addele[type2]+=val;
+ else if(sd->state.lr_flag == 2)
+ sd->arrow_addele[type2]+=val;
+ break;
+ case SP_ADDRACE:
+ if(!sd->state.lr_flag)
+ sd->right_weapon.addrace[type2]+=val;
+ else if(sd->state.lr_flag == 1)
+ sd->left_weapon.addrace[type2]+=val;
+ else if(sd->state.lr_flag == 2)
+ sd->arrow_addrace[type2]+=val;
+ break;
+ case SP_ADDSIZE:
+ if(!sd->state.lr_flag)
+ sd->right_weapon.addsize[type2]+=val;
+ else if(sd->state.lr_flag == 1)
+ sd->left_weapon.addsize[type2]+=val;
+ else if(sd->state.lr_flag == 2)
+ sd->arrow_addsize[type2]+=val;
+ break;
+ case SP_SUBELE:
+ if(type2 >= ELE_MAX) {
+ ShowError("pc_bonus2: SP_SUBELE: Invalid element %d\n", type2);
+ break;
+ }
+ if(sd->state.lr_flag != 2)
+ sd->subele[type2]+=val;
+ break;
+ case SP_SUBRACE:
+ if(sd->state.lr_flag != 2)
+ sd->subrace[type2]+=val;
+ break;
+ case SP_ADDEFF:
+ if (type2 > SC_MAX) {
+ ShowWarning("pc_bonus2 (Add Effect): %d is not supported.\n", type2);
+ break;
+ }
+ pc_bonus_addeff(sd->addeff, ARRAYLENGTH(sd->addeff), (sc_type)type2,
+ sd->state.lr_flag!=2?val:0, sd->state.lr_flag==2?val:0, 0);
+ break;
+ case SP_ADDEFF2:
+ if (type2 > SC_MAX) {
+ ShowWarning("pc_bonus2 (Add Effect2): %d is not supported.\n", type2);
+ break;
+ }
+ pc_bonus_addeff(sd->addeff, ARRAYLENGTH(sd->addeff), (sc_type)type2,
+ sd->state.lr_flag!=2?val:0, sd->state.lr_flag==2?val:0, ATF_SELF);
+ break;
+ case SP_RESEFF:
+ if (type2 < SC_COMMON_MIN || type2 > SC_COMMON_MAX) {
+ ShowWarning("pc_bonus2 (Resist Effect): %d is not supported.\n", type2);
+ break;
+ }
+ if(sd->state.lr_flag == 2)
+ break;
+ i = sd->reseff[type2-SC_COMMON_MIN]+val;
+ sd->reseff[type2-SC_COMMON_MIN]= cap_value(i, 0, 10000);
+ break;
+ case SP_MAGIC_ADDELE:
+ if(type2 >= ELE_MAX) {
+ ShowError("pc_bonus2: SP_MAGIC_ADDELE: Invalid element %d\n", type2);
+ break;
+ }
+ if(sd->state.lr_flag != 2)
+ sd->magic_addele[type2]+=val;
+ break;
+ case SP_MAGIC_ADDRACE:
+ if(sd->state.lr_flag != 2)
+ sd->magic_addrace[type2]+=val;
+ break;
+ case SP_MAGIC_ADDSIZE:
+ if(sd->state.lr_flag != 2)
+ sd->magic_addsize[type2]+=val;
+ break;
+ case SP_ADD_DAMAGE_CLASS:
+ switch (sd->state.lr_flag) {
+ case 0: //Right hand
+ ARR_FIND(0, ARRAYLENGTH(sd->right_weapon.add_dmg), i, sd->right_weapon.add_dmg[i].rate == 0 || sd->right_weapon.add_dmg[i].class_ == type2);
+ if (i == ARRAYLENGTH(sd->right_weapon.add_dmg))
+ {
+ ShowWarning("pc_bonus2: Reached max (%d) number of add Class dmg bonuses per character!\n", ARRAYLENGTH(sd->right_weapon.add_dmg));
+ break;
+ }
+ sd->right_weapon.add_dmg[i].class_ = type2;
+ sd->right_weapon.add_dmg[i].rate += val;
+ if (!sd->right_weapon.add_dmg[i].rate) //Shift the rest of elements up.
+ memmove(&sd->right_weapon.add_dmg[i], &sd->right_weapon.add_dmg[i+1], sizeof(sd->right_weapon.add_dmg) - (i+1)*sizeof(sd->right_weapon.add_dmg[0]));
+ break;
+ case 1: //Left hand
+ ARR_FIND(0, ARRAYLENGTH(sd->left_weapon.add_dmg), i, sd->left_weapon.add_dmg[i].rate == 0 || sd->left_weapon.add_dmg[i].class_ == type2);
+ if (i == ARRAYLENGTH(sd->left_weapon.add_dmg))
+ {
+ ShowWarning("pc_bonus2: Reached max (%d) number of add Class dmg bonuses per character!\n", ARRAYLENGTH(sd->left_weapon.add_dmg));
+ break;
+ }
+ sd->left_weapon.add_dmg[i].class_ = type2;
+ sd->left_weapon.add_dmg[i].rate += val;
+ if (!sd->left_weapon.add_dmg[i].rate) //Shift the rest of elements up.
+ memmove(&sd->left_weapon.add_dmg[i], &sd->left_weapon.add_dmg[i+1], sizeof(sd->left_weapon.add_dmg) - (i+1)*sizeof(sd->left_weapon.add_dmg[0]));
+ break;
+ }
+ break;
+ case SP_ADD_MAGIC_DAMAGE_CLASS:
+ if(sd->state.lr_flag == 2)
+ break;
+ ARR_FIND(0, ARRAYLENGTH(sd->add_mdmg), i, sd->add_mdmg[i].rate == 0 || sd->add_mdmg[i].class_ == type2);
+ if (i == ARRAYLENGTH(sd->add_mdmg))
+ {
+ ShowWarning("pc_bonus2: Reached max (%d) number of add Class magic dmg bonuses per character!\n", ARRAYLENGTH(sd->add_mdmg));
+ break;
+ }
+ sd->add_mdmg[i].class_ = type2;
+ sd->add_mdmg[i].rate += val;
+ if (!sd->add_mdmg[i].rate) //Shift the rest of elements up.
+ memmove(&sd->add_mdmg[i], &sd->add_mdmg[i+1], sizeof(sd->add_mdmg) - (i+1)*sizeof(sd->add_mdmg[0]));
+ break;
+ case SP_ADD_DEF_CLASS:
+ if(sd->state.lr_flag == 2)
+ break;
+ ARR_FIND(0, ARRAYLENGTH(sd->add_def), i, sd->add_def[i].rate == 0 || sd->add_def[i].class_ == type2);
+ if (i == ARRAYLENGTH(sd->add_def))
+ {
+ ShowWarning("pc_bonus2: Reached max (%d) number of add Class def bonuses per character!\n", ARRAYLENGTH(sd->add_def));
+ break;
+ }
+ sd->add_def[i].class_ = type2;
+ sd->add_def[i].rate += val;
+ if (!sd->add_def[i].rate) //Shift the rest of elements up.
+ memmove(&sd->add_def[i], &sd->add_def[i+1], sizeof(sd->add_def) - (i+1)*sizeof(sd->add_def[0]));
+ break;
+ case SP_ADD_MDEF_CLASS:
+ if(sd->state.lr_flag == 2)
+ break;
+ ARR_FIND(0, ARRAYLENGTH(sd->add_mdef), i, sd->add_mdef[i].rate == 0 || sd->add_mdef[i].class_ == type2);
+ if (i == ARRAYLENGTH(sd->add_mdef))
+ {
+ ShowWarning("pc_bonus2: Reached max (%d) number of add Class mdef bonuses per character!\n", ARRAYLENGTH(sd->add_mdef));
+ break;
+ }
+ sd->add_mdef[i].class_ = type2;
+ sd->add_mdef[i].rate += val;
+ if (!sd->add_mdef[i].rate) //Shift the rest of elements up.
+ memmove(&sd->add_mdef[i], &sd->add_mdef[i+1], sizeof(sd->add_mdef) - (i+1)*sizeof(sd->add_mdef[0]));
+ break;
+ case SP_HP_DRAIN_RATE:
+ if(!sd->state.lr_flag) {
+ sd->right_weapon.hp_drain[RC_NONBOSS].rate += type2;
+ sd->right_weapon.hp_drain[RC_NONBOSS].per += val;
+ sd->right_weapon.hp_drain[RC_BOSS].rate += type2;
+ sd->right_weapon.hp_drain[RC_BOSS].per += val;
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->left_weapon.hp_drain[RC_NONBOSS].rate += type2;
+ sd->left_weapon.hp_drain[RC_NONBOSS].per += val;
+ sd->left_weapon.hp_drain[RC_BOSS].rate += type2;
+ sd->left_weapon.hp_drain[RC_BOSS].per += val;
+ }
+ break;
+ case SP_HP_DRAIN_VALUE:
+ if(!sd->state.lr_flag) {
+ sd->right_weapon.hp_drain[RC_NONBOSS].value += type2;
+ sd->right_weapon.hp_drain[RC_NONBOSS].type = val;
+ sd->right_weapon.hp_drain[RC_BOSS].value += type2;
+ sd->right_weapon.hp_drain[RC_BOSS].type = val;
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->left_weapon.hp_drain[RC_NONBOSS].value += type2;
+ sd->left_weapon.hp_drain[RC_NONBOSS].type = val;
+ sd->left_weapon.hp_drain[RC_BOSS].value += type2;
+ sd->left_weapon.hp_drain[RC_BOSS].type = val;
+ }
+ break;
+ case SP_SP_DRAIN_RATE:
+ if(!sd->state.lr_flag) {
+ sd->right_weapon.sp_drain[RC_NONBOSS].rate += type2;
+ sd->right_weapon.sp_drain[RC_NONBOSS].per += val;
+ sd->right_weapon.sp_drain[RC_BOSS].rate += type2;
+ sd->right_weapon.sp_drain[RC_BOSS].per += val;
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->left_weapon.sp_drain[RC_NONBOSS].rate += type2;
+ sd->left_weapon.sp_drain[RC_NONBOSS].per += val;
+ sd->left_weapon.sp_drain[RC_BOSS].rate += type2;
+ sd->left_weapon.sp_drain[RC_BOSS].per += val;
+ }
+ break;
+ case SP_SP_DRAIN_VALUE:
+ if(!sd->state.lr_flag) {
+ sd->right_weapon.sp_drain[RC_NONBOSS].value += type2;
+ sd->right_weapon.sp_drain[RC_NONBOSS].type = val;
+ sd->right_weapon.sp_drain[RC_BOSS].value += type2;
+ sd->right_weapon.sp_drain[RC_BOSS].type = val;
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->left_weapon.sp_drain[RC_NONBOSS].value += type2;
+ sd->left_weapon.sp_drain[RC_NONBOSS].type = val;
+ sd->left_weapon.sp_drain[RC_BOSS].value += type2;
+ sd->left_weapon.sp_drain[RC_BOSS].type = val;
+ }
+ break;
+ case SP_SP_VANISH_RATE:
+ if(sd->state.lr_flag != 2) {
+ sd->bonus.sp_vanish_rate += type2;
+ sd->bonus.sp_vanish_per += val;
+ }
+ break;
+ case SP_GET_ZENY_NUM:
+ if(sd->state.lr_flag != 2 && sd->bonus.get_zeny_rate < val) {
+ sd->bonus.get_zeny_rate = val;
+ sd->bonus.get_zeny_num = type2;
+ }
+ break;
+ case SP_ADD_GET_ZENY_NUM:
+ if(sd->state.lr_flag != 2) {
+ sd->bonus.get_zeny_rate += val;
+ sd->bonus.get_zeny_num += type2;
+ }
+ break;
+ case SP_WEAPON_COMA_ELE:
+ if(type2 >= ELE_MAX) {
+ ShowError("pc_bonus2: SP_WEAPON_COMA_ELE: Invalid element %d\n", type2);
+ break;
+ }
+ if(sd->state.lr_flag == 2)
+ break;
+ sd->weapon_coma_ele[type2] += val;
+ sd->special_state.bonus_coma = 1;
+ break;
+ case SP_WEAPON_COMA_RACE:
+ if(sd->state.lr_flag == 2)
+ break;
+ sd->weapon_coma_race[type2] += val;
+ sd->special_state.bonus_coma = 1;
+ 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*10;
+ break;
+ case SP_ADDEFF_WHENHIT:
+ if (type2 > SC_MAX) {
+ ShowWarning("pc_bonus2 (Add Effect when hit): %d is not supported.\n", type2);
+ break;
+ }
+ if(sd->state.lr_flag != 2)
+ pc_bonus_addeff(sd->addeff2, ARRAYLENGTH(sd->addeff2), (sc_type)type2, val, 0, 0);
+ break;
+ case SP_SKILL_ATK:
+ if(sd->state.lr_flag == 2)
+ break;
+ ARR_FIND(0, ARRAYLENGTH(sd->skillatk), i, sd->skillatk[i].id == 0 || sd->skillatk[i].id == type2);
+ if (i == ARRAYLENGTH(sd->skillatk))
+ { //Better mention this so the array length can be updated. [Skotlex]
+ ShowDebug("run_script: bonus2 bSkillAtk reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillatk), type2, val);
+ break;
+ }
+ if (sd->skillatk[i].id == type2)
+ sd->skillatk[i].val += val;
+ else {
+ sd->skillatk[i].id = type2;
+ sd->skillatk[i].val = val;
+ }
+ break;
+ case SP_SKILL_HEAL:
+ if(sd->state.lr_flag == 2)
+ break;
+ ARR_FIND(0, ARRAYLENGTH(sd->skillheal), i, sd->skillheal[i].id == 0 || sd->skillheal[i].id == type2);
+ if (i == ARRAYLENGTH(sd->skillheal))
+ { // Better mention this so the array length can be updated. [Skotlex]
+ ShowDebug("run_script: bonus2 bSkillHeal reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillheal), type2, val);
+ break;
+ }
+ if (sd->skillheal[i].id == type2)
+ sd->skillheal[i].val += val;
+ else {
+ sd->skillheal[i].id = type2;
+ sd->skillheal[i].val = val;
+ }
+ break;
+ case SP_SKILL_HEAL2:
+ if(sd->state.lr_flag == 2)
+ break;
+ ARR_FIND(0, ARRAYLENGTH(sd->skillheal2), i, sd->skillheal2[i].id == 0 || sd->skillheal2[i].id == type2);
+ if (i == ARRAYLENGTH(sd->skillheal2))
+ { // Better mention this so the array length can be updated. [Skotlex]
+ ShowDebug("run_script: bonus2 bSkillHeal2 reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillheal2), type2, val);
+ break;
+ }
+ if (sd->skillheal2[i].id == type2)
+ sd->skillheal2[i].val += val;
+ else {
+ sd->skillheal2[i].id = type2;
+ sd->skillheal2[i].val = val;
+ }
+ break;
+ case SP_ADD_SKILL_BLOW:
+ if(sd->state.lr_flag == 2)
+ break;
+ ARR_FIND(0, ARRAYLENGTH(sd->skillblown), i, sd->skillblown[i].id == 0 || sd->skillblown[i].id == type2);
+ if (i == ARRAYLENGTH(sd->skillblown))
+ { //Better mention this so the array length can be updated. [Skotlex]
+ ShowDebug("run_script: bonus2 bSkillBlown reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillblown), type2, val);
+ break;
+ }
+ if(sd->skillblown[i].id == type2)
+ sd->skillblown[i].val += val;
+ else {
+ sd->skillblown[i].id = type2;
+ sd->skillblown[i].val = val;
+ }
+ break;
+
+ case SP_CASTRATE:
+ if(sd->state.lr_flag == 2)
+ break;
+ ARR_FIND(0, ARRAYLENGTH(sd->skillcast), i, sd->skillcast[i].id == 0 || sd->skillcast[i].id == type2);
+ if (i == ARRAYLENGTH(sd->skillcast))
+ { //Better mention this so the array length can be updated. [Skotlex]
+ ShowDebug("run_script: bonus2 bCastRate reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillcast), type2, val);
+ break;
+ }
+ if(sd->skillcast[i].id == type2)
+ sd->skillcast[i].val += val;
+ else {
+ sd->skillcast[i].id = type2;
+ sd->skillcast[i].val = val;
+ }
+ 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_HP_REGEN_RATE:
+ if(sd->state.lr_flag != 2) {
+ sd->hp_regen.value = type2;
+ sd->hp_regen.rate = val;
+ }
+ break;
+ case SP_ADDRACE2:
+ if (!(type2 > RC2_NONE && type2 < RC2_MAX))
+ break;
+ if(sd->state.lr_flag != 2)
+ sd->right_weapon.addrace2[type2] += val;
+ else
+ sd->left_weapon.addrace2[type2] += val;
+ break;
+ case SP_SUBSIZE:
+ if(sd->state.lr_flag != 2)
+ sd->subsize[type2]+=val;
+ break;
+ case SP_SUBRACE2:
+ if (!(type2 > RC2_NONE && type2 < RC2_MAX))
+ break;
+ if(sd->state.lr_flag != 2)
+ sd->subrace2[type2]+=val;
+ break;
+ case SP_ADD_ITEM_HEAL_RATE:
+ if(sd->state.lr_flag == 2)
+ break;
+ if (type2 < MAX_ITEMGROUP) { //Group bonus
+ sd->itemgrouphealrate[type2] += val;
+ break;
+ }
+ //Standard item bonus.
+ for(i=0; i < ARRAYLENGTH(sd->itemhealrate) && sd->itemhealrate[i].nameid && sd->itemhealrate[i].nameid != type2; i++);
+ if(i == ARRAYLENGTH(sd->itemhealrate)) {
+ ShowWarning("pc_bonus2: Reached max (%d) number of item heal bonuses per character!\n", ARRAYLENGTH(sd->itemhealrate));
+ break;
+ }
+ sd->itemhealrate[i].nameid = type2;
+ sd->itemhealrate[i].rate += 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;
+ case SP_ADD_MONSTER_DROP_ITEM:
+ if (sd->state.lr_flag != 2)
+ pc_bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), type2, 0, (1<<RC_BOSS)|(1<<RC_NONBOSS), val);
+ break;
+ case SP_ADD_MONSTER_DROP_ITEMGROUP:
+ if (sd->state.lr_flag != 2)
+ pc_bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), 0, type2, (1<<RC_BOSS)|(1<<RC_NONBOSS), val);
+ break;
+ case SP_SP_LOSS_RATE:
+ if(sd->state.lr_flag != 2) {
+ sd->sp_loss.value = type2;
+ sd->sp_loss.rate = val;
+ }
+ break;
+ case SP_SP_REGEN_RATE:
+ if(sd->state.lr_flag != 2) {
+ sd->sp_regen.value = type2;
+ sd->sp_regen.rate = val;
+ }
+ break;
+ case SP_HP_DRAIN_VALUE_RACE:
+ if(!sd->state.lr_flag) {
+ sd->right_weapon.hp_drain[type2].value += val;
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->left_weapon.hp_drain[type2].value += val;
+ }
+ break;
+ case SP_SP_DRAIN_VALUE_RACE:
+ if(!sd->state.lr_flag) {
+ sd->right_weapon.sp_drain[type2].value += val;
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->left_weapon.sp_drain[type2].value += val;
+ }
+ break;
+ case SP_IGNORE_MDEF_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->ignore_mdef[type2] += val;
+ break;
+ case SP_IGNORE_DEF_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->ignore_def[type2] += val;
+ break;
+ case SP_SP_GAIN_RACE_ATTACK:
+ if(sd->state.lr_flag != 2)
+ sd->sp_gain_race_attack[type2] = cap_value(sd->sp_gain_race_attack[type2] + val, 0, INT16_MAX);
+ break;
+ case SP_HP_GAIN_RACE_ATTACK:
+ if(sd->state.lr_flag != 2)
+ sd->hp_gain_race_attack[type2] = cap_value(sd->hp_gain_race_attack[type2] + val, 0, INT16_MAX);
+ break;
+ case SP_SKILL_USE_SP_RATE: //bonus2 bSkillUseSPrate,n,x;
+ if(sd->state.lr_flag == 2)
+ break;
+ ARR_FIND(0, ARRAYLENGTH(sd->skillusesprate), i, sd->skillusesprate[i].id == 0 || sd->skillusesprate[i].id == type2);
+ if (i == ARRAYLENGTH(sd->skillusesprate)) {
+ ShowDebug("run_script: bonus2 bSkillUseSPrate reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillusesprate), type2, val);
+ break;
+ }
+ if (sd->skillusesprate[i].id == type2)
+ sd->skillusesprate[i].val += val;
+ else {
+ sd->skillusesprate[i].id = type2;
+ sd->skillusesprate[i].val = val;
+ }
+ break;
+ case SP_SKILL_COOLDOWN:
+ if(sd->state.lr_flag == 2)
+ break;
+ ARR_FIND(0, ARRAYLENGTH(sd->skillcooldown), i, sd->skillcooldown[i].id == 0 || sd->skillcooldown[i].id == type2);
+ if (i == ARRAYLENGTH(sd->skillcooldown))
+ {
+ ShowDebug("run_script: bonus2 bSkillCoolDown reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillcooldown), type2, val);
+ break;
+ }
+ if (sd->skillcooldown[i].id == type2)
+ sd->skillcooldown[i].val += val;
+ else {
+ sd->skillcooldown[i].id = type2;
+ sd->skillcooldown[i].val = val;
+ }
+ break;
+ case SP_SKILL_FIXEDCAST:
+ if(sd->state.lr_flag == 2)
+ break;
+ ARR_FIND(0, ARRAYLENGTH(sd->skillfixcast), i, sd->skillfixcast[i].id == 0 || sd->skillfixcast[i].id == type2);
+ if (i == ARRAYLENGTH(sd->skillfixcast))
+ {
+ ShowDebug("run_script: bonus2 bSkillFixedCast reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillfixcast), type2, val);
+ break;
+ }
+ if (sd->skillfixcast[i].id == type2)
+ sd->skillfixcast[i].val += val;
+ else {
+ sd->skillfixcast[i].id = type2;
+ sd->skillfixcast[i].val = val;
+ }
+ break;
+ case SP_SKILL_VARIABLECAST:
+ if(sd->state.lr_flag == 2)
+ break;
+ ARR_FIND(0, ARRAYLENGTH(sd->skillvarcast), i, sd->skillvarcast[i].id == 0 || sd->skillvarcast[i].id == type2);
+ if (i == ARRAYLENGTH(sd->skillvarcast))
+ {
+ ShowDebug("run_script: bonus2 bSkillVariableCast reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillvarcast), type2, val);
+ break;
+ }
+ if (sd->skillvarcast[i].id == type2)
+ sd->skillvarcast[i].val += val;
+ else {
+ sd->skillvarcast[i].id = type2;
+ sd->skillvarcast[i].val = val;
+ }
+ break;
+ case SP_VARCASTRATE:
+ if(sd->state.lr_flag == 2)
+ break;
+ ARR_FIND(0, ARRAYLENGTH(sd->skillcast), i, sd->skillcast[i].id == 0 || sd->skillcast[i].id == type2);
+ if (i == ARRAYLENGTH(sd->skillcast))
+ {
+ ShowDebug("run_script: bonus2 bVariableCastrate reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n",ARRAYLENGTH(sd->skillcast), type2, val);
+ break;
+ }
+ if(sd->skillcast[i].id == type2)
+ sd->skillcast[i].val -= val;
+ else {
+ sd->skillcast[i].id = type2;
+ sd->skillcast[i].val -= val;
+ }
+ break;
+ case SP_SKILL_USE_SP: //bonus2 bSkillUseSP,n,x;
+ if(sd->state.lr_flag == 2)
+ break;
+ ARR_FIND(0, ARRAYLENGTH(sd->skillusesp), i, sd->skillusesp[i].id == 0 || sd->skillusesp[i].id == type2);
+ if (i == ARRAYLENGTH(sd->skillusesp)) {
+ ShowDebug("run_script: bonus2 bSkillUseSP reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillusesp), type2, val);
+ break;
+ }
+ if (sd->skillusesp[i].id == type2)
+ sd->skillusesp[i].val += val;
+ else {
+ sd->skillusesp[i].id = type2;
+ sd->skillusesp[i].val = val;
+ }
+ break;
+ default:
+ ShowWarning("pc_bonus2: unknown type %d %d %d!\n",type,type2,val);
+ break;
+ }
+ return 0;
}
int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val)
{
- nullpo_ret(sd);
-
- switch (type) {
- case SP_ADD_MONSTER_DROP_ITEM:
- if (sd->state.lr_flag != 2)
- pc_bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), type2, 0, 1<<type3, val);
- break;
- case SP_ADD_CLASS_DROP_ITEM:
- if (sd->state.lr_flag != 2)
- pc_bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), type2, 0, -type3, val);
- break;
- case SP_AUTOSPELL:
- if (sd->state.lr_flag != 2) {
- int target = skill_get_inf(type2); //Support or Self (non-auto-target) skills should pick self.
- target = target&INF_SUPPORT_SKILL || (target&INF_SELF_SKILL && !(skill_get_inf2(type2)&INF2_NO_TARGET_SELF));
- pc_bonus_autospell(sd->autospell, ARRAYLENGTH(sd->autospell),
- target?-type2:type2, type3, val, 0, current_equip_card_id);
- }
- break;
- case SP_AUTOSPELL_WHENHIT:
- if (sd->state.lr_flag != 2) {
- int target = skill_get_inf(type2); //Support or Self (non-auto-target) skills should pick self.
- target = target&INF_SUPPORT_SKILL || (target&INF_SELF_SKILL && !(skill_get_inf2(type2)&INF2_NO_TARGET_SELF));
- pc_bonus_autospell(sd->autospell2, ARRAYLENGTH(sd->autospell2),
- target?-type2:type2, type3, val, BF_NORMAL|BF_SKILL, current_equip_card_id);
- }
- break;
- case SP_SP_DRAIN_RATE:
- if (!sd->state.lr_flag) {
- sd->right_weapon.sp_drain[RC_NONBOSS].rate += type2;
- sd->right_weapon.sp_drain[RC_NONBOSS].per += type3;
- sd->right_weapon.sp_drain[RC_NONBOSS].type = val;
- sd->right_weapon.sp_drain[RC_BOSS].rate += type2;
- sd->right_weapon.sp_drain[RC_BOSS].per += type3;
- sd->right_weapon.sp_drain[RC_BOSS].type = val;
-
- } else if (sd->state.lr_flag == 1) {
- sd->left_weapon.sp_drain[RC_NONBOSS].rate += type2;
- sd->left_weapon.sp_drain[RC_NONBOSS].per += type3;
- sd->left_weapon.sp_drain[RC_NONBOSS].type = val;
- sd->left_weapon.sp_drain[RC_BOSS].rate += type2;
- sd->left_weapon.sp_drain[RC_BOSS].per += type3;
- sd->left_weapon.sp_drain[RC_BOSS].type = val;
- }
- break;
- case SP_HP_DRAIN_RATE_RACE:
- if (!sd->state.lr_flag) {
- sd->right_weapon.hp_drain[type2].rate += type3;
- sd->right_weapon.hp_drain[type2].per += val;
- } else if (sd->state.lr_flag == 1) {
- sd->left_weapon.hp_drain[type2].rate += type3;
- sd->left_weapon.hp_drain[type2].per += val;
- }
- break;
- case SP_SP_DRAIN_RATE_RACE:
- if (!sd->state.lr_flag) {
- sd->right_weapon.sp_drain[type2].rate += type3;
- sd->right_weapon.sp_drain[type2].per += val;
- } else if (sd->state.lr_flag == 1) {
- sd->left_weapon.sp_drain[type2].rate += type3;
- sd->left_weapon.sp_drain[type2].per += val;
- }
- break;
- case SP_ADD_MONSTER_DROP_ITEMGROUP:
- if (sd->state.lr_flag != 2)
- pc_bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), 0, type2, 1<<type3, val);
- break;
-
- case SP_ADDEFF:
- if (type2 > SC_MAX) {
- ShowWarning("pc_bonus3 (Add Effect): %d is not supported.\n", type2);
- break;
- }
- pc_bonus_addeff(sd->addeff, ARRAYLENGTH(sd->addeff), (sc_type)type2,
- sd->state.lr_flag!=2?type3:0, sd->state.lr_flag==2?type3:0, val);
- break;
-
- case SP_ADDEFF_WHENHIT:
- if (type2 > SC_MAX) {
- ShowWarning("pc_bonus3 (Add Effect when hit): %d is not supported.\n", type2);
- break;
- }
- if (sd->state.lr_flag != 2)
- pc_bonus_addeff(sd->addeff2, ARRAYLENGTH(sd->addeff2), (sc_type)type2, type3, 0, val);
- break;
-
- case SP_ADDEFF_ONSKILL:
- if (type3 > SC_MAX) {
- ShowWarning("pc_bonus3 (Add Effect on skill): %d is not supported.\n", type3);
- break;
- }
- if (sd->state.lr_flag != 2)
- pc_bonus_addeff_onskill(sd->addeff3, ARRAYLENGTH(sd->addeff3), (sc_type)type3, val, type2, ATF_TARGET);
- break;
-
- case SP_ADDELE:
- if (type2 > ELE_MAX) {
- ShowWarning("pc_bonus3 (SP_ADDELE): element %d is out of range.\n", type2);
- break;
- }
- if (sd->state.lr_flag != 2)
- pc_bonus_addele(sd, (unsigned char)type2, type3, val);
- break;
-
- case SP_SUBELE:
- if (type2 > ELE_MAX) {
- ShowWarning("pc_bonus3 (SP_SUBELE): element %d is out of range.\n", type2);
- break;
- }
- if (sd->state.lr_flag != 2)
- pc_bonus_subele(sd, (unsigned char)type2, type3, val);
- break;
-
- default:
- ShowWarning("pc_bonus3: unknown type %d %d %d %d!\n",type,type2,type3,val);
- break;
- }
-
- return 0;
+ nullpo_ret(sd);
+
+ switch(type){
+ case SP_ADD_MONSTER_DROP_ITEM:
+ if(sd->state.lr_flag != 2)
+ pc_bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), type2, 0, 1<<type3, val);
+ break;
+ case SP_ADD_CLASS_DROP_ITEM:
+ if(sd->state.lr_flag != 2)
+ pc_bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), type2, 0, -type3, val);
+ break;
+ case SP_AUTOSPELL:
+ if(sd->state.lr_flag != 2)
+ {
+ int target = skill_get_inf(type2); //Support or Self (non-auto-target) skills should pick self.
+ target = target&INF_SUPPORT_SKILL || (target&INF_SELF_SKILL && !(skill_get_inf2(type2)&INF2_NO_TARGET_SELF));
+ pc_bonus_autospell(sd->autospell, ARRAYLENGTH(sd->autospell),
+ target?-type2:type2, type3, val, 0, current_equip_card_id);
+ }
+ break;
+ case SP_AUTOSPELL_WHENHIT:
+ if(sd->state.lr_flag != 2)
+ {
+ int target = skill_get_inf(type2); //Support or Self (non-auto-target) skills should pick self.
+ target = target&INF_SUPPORT_SKILL || (target&INF_SELF_SKILL && !(skill_get_inf2(type2)&INF2_NO_TARGET_SELF));
+ pc_bonus_autospell(sd->autospell2, ARRAYLENGTH(sd->autospell2),
+ target?-type2:type2, type3, val, BF_NORMAL|BF_SKILL, current_equip_card_id);
+ }
+ break;
+ case SP_SP_DRAIN_RATE:
+ if(!sd->state.lr_flag) {
+ sd->right_weapon.sp_drain[RC_NONBOSS].rate += type2;
+ sd->right_weapon.sp_drain[RC_NONBOSS].per += type3;
+ sd->right_weapon.sp_drain[RC_NONBOSS].type = val;
+ sd->right_weapon.sp_drain[RC_BOSS].rate += type2;
+ sd->right_weapon.sp_drain[RC_BOSS].per += type3;
+ sd->right_weapon.sp_drain[RC_BOSS].type = val;
+
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->left_weapon.sp_drain[RC_NONBOSS].rate += type2;
+ sd->left_weapon.sp_drain[RC_NONBOSS].per += type3;
+ sd->left_weapon.sp_drain[RC_NONBOSS].type = val;
+ sd->left_weapon.sp_drain[RC_BOSS].rate += type2;
+ sd->left_weapon.sp_drain[RC_BOSS].per += type3;
+ sd->left_weapon.sp_drain[RC_BOSS].type = val;
+ }
+ break;
+ case SP_HP_DRAIN_RATE_RACE:
+ if(!sd->state.lr_flag) {
+ sd->right_weapon.hp_drain[type2].rate += type3;
+ sd->right_weapon.hp_drain[type2].per += val;
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->left_weapon.hp_drain[type2].rate += type3;
+ sd->left_weapon.hp_drain[type2].per += val;
+ }
+ break;
+ case SP_SP_DRAIN_RATE_RACE:
+ if(!sd->state.lr_flag) {
+ sd->right_weapon.sp_drain[type2].rate += type3;
+ sd->right_weapon.sp_drain[type2].per += val;
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->left_weapon.sp_drain[type2].rate += type3;
+ sd->left_weapon.sp_drain[type2].per += val;
+ }
+ break;
+ case SP_ADD_MONSTER_DROP_ITEMGROUP:
+ if (sd->state.lr_flag != 2)
+ pc_bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), 0, type2, 1<<type3, val);
+ break;
+
+ case SP_ADDEFF:
+ if (type2 > SC_MAX) {
+ ShowWarning("pc_bonus3 (Add Effect): %d is not supported.\n", type2);
+ break;
+ }
+ pc_bonus_addeff(sd->addeff, ARRAYLENGTH(sd->addeff), (sc_type)type2,
+ sd->state.lr_flag!=2?type3:0, sd->state.lr_flag==2?type3:0, val);
+ break;
+
+ case SP_ADDEFF_WHENHIT:
+ if (type2 > SC_MAX) {
+ ShowWarning("pc_bonus3 (Add Effect when hit): %d is not supported.\n", type2);
+ break;
+ }
+ if(sd->state.lr_flag != 2)
+ pc_bonus_addeff(sd->addeff2, ARRAYLENGTH(sd->addeff2), (sc_type)type2, type3, 0, val);
+ break;
+
+ case SP_ADDEFF_ONSKILL:
+ if( type3 > SC_MAX ) {
+ ShowWarning("pc_bonus3 (Add Effect on skill): %d is not supported.\n", type3);
+ break;
+ }
+ if( sd->state.lr_flag != 2 )
+ pc_bonus_addeff_onskill(sd->addeff3, ARRAYLENGTH(sd->addeff3), (sc_type)type3, val, type2, ATF_TARGET);
+ break;
+
+ case SP_ADDELE:
+ if (type2 > ELE_MAX) {
+ ShowWarning("pc_bonus3 (SP_ADDELE): element %d is out of range.\n", type2);
+ break;
+ }
+ if (sd->state.lr_flag != 2)
+ pc_bonus_addele(sd, (unsigned char)type2, type3, val);
+ break;
+
+ case SP_SUBELE:
+ if (type2 > ELE_MAX) {
+ ShowWarning("pc_bonus3 (SP_SUBELE): element %d is out of range.\n", type2);
+ break;
+ }
+ if (sd->state.lr_flag != 2)
+ pc_bonus_subele(sd, (unsigned char)type2, type3, val);
+ break;
+
+ default:
+ ShowWarning("pc_bonus3: unknown type %d %d %d %d!\n",type,type2,type3,val);
+ break;
+ }
+
+ return 0;
}
int pc_bonus4(struct map_session_data *sd,int type,int type2,int type3,int type4,int val)
{
- nullpo_ret(sd);
+ nullpo_ret(sd);
- switch (type) {
- case SP_AUTOSPELL:
- if (sd->state.lr_flag != 2)
- pc_bonus_autospell(sd->autospell, ARRAYLENGTH(sd->autospell), (val&1?type2:-type2), (val&2?-type3:type3), type4, 0, current_equip_card_id);
- break;
+ switch(type){
+ case SP_AUTOSPELL:
+ if(sd->state.lr_flag != 2)
+ pc_bonus_autospell(sd->autospell, ARRAYLENGTH(sd->autospell), (val&1?type2:-type2), (val&2?-type3:type3), type4, 0, current_equip_card_id);
+ break;
- case SP_AUTOSPELL_WHENHIT:
- if (sd->state.lr_flag != 2)
- pc_bonus_autospell(sd->autospell2, ARRAYLENGTH(sd->autospell2), (val&1?type2:-type2), (val&2?-type3:type3), type4, BF_NORMAL|BF_SKILL, current_equip_card_id);
- break;
+ case SP_AUTOSPELL_WHENHIT:
+ if(sd->state.lr_flag != 2)
+ pc_bonus_autospell(sd->autospell2, ARRAYLENGTH(sd->autospell2), (val&1?type2:-type2), (val&2?-type3:type3), type4, BF_NORMAL|BF_SKILL, current_equip_card_id);
+ break;
- case SP_AUTOSPELL_ONSKILL:
- if (sd->state.lr_flag != 2) {
- int target = skill_get_inf(type2); //Support or Self (non-auto-target) skills should pick self.
- target = target&INF_SUPPORT_SKILL || (target&INF_SELF_SKILL && !(skill_get_inf2(type2)&INF2_NO_TARGET_SELF));
+ case SP_AUTOSPELL_ONSKILL:
+ if(sd->state.lr_flag != 2)
+ {
+ int target = skill_get_inf(type2); //Support or Self (non-auto-target) skills should pick self.
+ target = target&INF_SUPPORT_SKILL || (target&INF_SELF_SKILL && !(skill_get_inf2(type2)&INF2_NO_TARGET_SELF));
- pc_bonus_autospell_onskill(sd->autospell3, ARRAYLENGTH(sd->autospell3), type2, target?-type3:type3, type4, val, current_equip_card_id);
- }
- break;
+ pc_bonus_autospell_onskill(sd->autospell3, ARRAYLENGTH(sd->autospell3), type2, target?-type3:type3, type4, val, current_equip_card_id);
+ }
+ break;
- case SP_ADDEFF_ONSKILL:
- if (type2 > SC_MAX) {
- ShowWarning("pc_bonus3 (Add Effect on skill): %d is not supported.\n", type2);
- break;
- }
- if (sd->state.lr_flag != 2)
- pc_bonus_addeff_onskill(sd->addeff3, ARRAYLENGTH(sd->addeff3), (sc_type)type3, type4, type2, val);
- break;
+ case SP_ADDEFF_ONSKILL:
+ if( type2 > SC_MAX ) {
+ ShowWarning("pc_bonus3 (Add Effect on skill): %d is not supported.\n", type2);
+ break;
+ }
+ if( sd->state.lr_flag != 2 )
+ pc_bonus_addeff_onskill(sd->addeff3, ARRAYLENGTH(sd->addeff3), (sc_type)type3, type4, type2, val);
+ break;
- default:
- ShowWarning("pc_bonus4: unknown type %d %d %d %d %d!\n",type,type2,type3,type4,val);
- break;
- }
+ default:
+ ShowWarning("pc_bonus4: unknown type %d %d %d %d %d!\n",type,type2,type3,type4,val);
+ break;
+ }
- return 0;
+ return 0;
}
int pc_bonus5(struct map_session_data *sd,int type,int type2,int type3,int type4,int type5,int val)
{
- nullpo_ret(sd);
+ nullpo_ret(sd);
- switch (type) {
- case SP_AUTOSPELL:
- if (sd->state.lr_flag != 2)
- pc_bonus_autospell(sd->autospell, ARRAYLENGTH(sd->autospell), (val&1?type2:-type2), (val&2?-type3:type3), type4, type5, current_equip_card_id);
- break;
+ switch(type){
+ case SP_AUTOSPELL:
+ if(sd->state.lr_flag != 2)
+ pc_bonus_autospell(sd->autospell, ARRAYLENGTH(sd->autospell), (val&1?type2:-type2), (val&2?-type3:type3), type4, type5, current_equip_card_id);
+ break;
- case SP_AUTOSPELL_WHENHIT:
- if (sd->state.lr_flag != 2)
- pc_bonus_autospell(sd->autospell2, ARRAYLENGTH(sd->autospell2), (val&1?type2:-type2), (val&2?-type3:type3), type4, type5, current_equip_card_id);
- break;
+ case SP_AUTOSPELL_WHENHIT:
+ if(sd->state.lr_flag != 2)
+ pc_bonus_autospell(sd->autospell2, ARRAYLENGTH(sd->autospell2), (val&1?type2:-type2), (val&2?-type3:type3), type4, type5, current_equip_card_id);
+ break;
- case SP_AUTOSPELL_ONSKILL:
- if (sd->state.lr_flag != 2)
- pc_bonus_autospell_onskill(sd->autospell3, ARRAYLENGTH(sd->autospell3), type2, (val&1?-type3:type3), (val&2?-type4:type4), type5, current_equip_card_id);
- break;
+ case SP_AUTOSPELL_ONSKILL:
+ if(sd->state.lr_flag != 2)
+ pc_bonus_autospell_onskill(sd->autospell3, ARRAYLENGTH(sd->autospell3), type2, (val&1?-type3:type3), (val&2?-type4:type4), type5, current_equip_card_id);
+ break;
- default:
- ShowWarning("pc_bonus5: unknown type %d %d %d %d %d %d!\n",type,type2,type3,type4,type5,val);
- break;
- }
+ default:
+ ShowWarning("pc_bonus5: unknown type %d %d %d %d %d %d!\n",type,type2,type3,type4,type5,val);
+ break;
+ }
- return 0;
+ return 0;
}
/*==========================================
- * Grants a player a given skill. Flag values are:
- * 0 - Grant skill unconditionally and forever (only this one invokes status_calc_pc,
- * as the other two are assumed to be invoked from within it)
- * 1 - Grant an item skill (temporary)
- * 2 - Like 1, except the level granted can stack with previously learned level.
+ * Grants a player a given skill. Flag values are:
+ * 0 - Grant skill unconditionally and forever (only this one invokes status_calc_pc,
+ * as the other two are assumed to be invoked from within it)
+ * 1 - Grant an item skill (temporary)
+ * 2 - Like 1, except the level granted can stack with previously learned level.
*------------------------------------------*/
-int pc_skill(TBL_PC *sd, int id, int level, int flag)
-{
- nullpo_ret(sd);
-
- if (id <= 0 || id >= MAX_SKILL || skill_db[id].name == NULL) {
- ShowError("pc_skill: Skill with id %d does not exist in the skill database\n", id);
- return 0;
- }
- if (level > MAX_SKILL_LEVEL) {
- ShowError("pc_skill: Skill level %d too high. Max lv supported is %d\n", level, MAX_SKILL_LEVEL);
- return 0;
- }
- if (flag == 2 && sd->status.skill[id].lv + level > MAX_SKILL_LEVEL) {
- ShowError("pc_skill: Skill level bonus %d too high. Max lv supported is %d. Curr lv is %d\n", level, MAX_SKILL_LEVEL, sd->status.skill[id].lv);
- return 0;
- }
-
- switch (flag) {
- case 0: //Set skill data overwriting whatever was there before.
- sd->status.skill[id].id = id;
- sd->status.skill[id].lv = level;
- sd->status.skill[id].flag = SKILL_FLAG_PERMANENT;
- if (level == 0) { //Remove skill.
- sd->status.skill[id].id = 0;
- clif_deleteskill(sd,id);
- } else
- clif_addskill(sd,id);
- if (!skill_get_inf(id)) //Only recalculate for passive skills.
- status_calc_pc(sd, 0);
- break;
- case 1: //Item bonus skill.
- if (sd->status.skill[id].id == id) {
- if (sd->status.skill[id].lv >= level)
- return 0;
- if (sd->status.skill[id].flag == SKILL_FLAG_PERMANENT) //Non-granted skill, store it's level.
- sd->status.skill[id].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[id].lv;
- } else {
- sd->status.skill[id].id = id;
- sd->status.skill[id].flag = SKILL_FLAG_TEMPORARY;
- }
- sd->status.skill[id].lv = level;
- break;
- case 2: //Add skill bonus on top of what you had.
- if (sd->status.skill[id].id == id) {
- if (sd->status.skill[id].flag == SKILL_FLAG_PERMANENT)
- sd->status.skill[id].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[id].lv; // Store previous level.
- } else {
- sd->status.skill[id].id = id;
- sd->status.skill[id].flag = SKILL_FLAG_TEMPORARY; //Set that this is a bonus skill.
- }
- sd->status.skill[id].lv += level;
- break;
- default: //Unknown flag?
- return 0;
- }
- return 1;
+int pc_skill(TBL_PC* sd, int id, int level, int flag)
+{
+ nullpo_ret(sd);
+
+ if( id <= 0 || id >= MAX_SKILL || skill_db[id].name == NULL) {
+ ShowError("pc_skill: Skill with id %d does not exist in the skill database\n", id);
+ return 0;
+ }
+ if( level > MAX_SKILL_LEVEL ) {
+ ShowError("pc_skill: Skill level %d too high. Max lv supported is %d\n", level, MAX_SKILL_LEVEL);
+ return 0;
+ }
+ if( flag == 2 && sd->status.skill[id].lv + level > MAX_SKILL_LEVEL ) {
+ ShowError("pc_skill: Skill level bonus %d too high. Max lv supported is %d. Curr lv is %d\n", level, MAX_SKILL_LEVEL, sd->status.skill[id].lv);
+ return 0;
+ }
+
+ switch( flag ){
+ case 0: //Set skill data overwriting whatever was there before.
+ sd->status.skill[id].id = id;
+ sd->status.skill[id].lv = level;
+ sd->status.skill[id].flag = SKILL_FLAG_PERMANENT;
+ if( level == 0 ) //Remove skill.
+ {
+ sd->status.skill[id].id = 0;
+ clif_deleteskill(sd,id);
+ }
+ else
+ clif_addskill(sd,id);
+ if( !skill_get_inf(id) ) //Only recalculate for passive skills.
+ status_calc_pc(sd, 0);
+ break;
+ case 1: //Item bonus skill.
+ if( sd->status.skill[id].id == id ){
+ if( sd->status.skill[id].lv >= level )
+ return 0;
+ if( sd->status.skill[id].flag == SKILL_FLAG_PERMANENT ) //Non-granted skill, store it's level.
+ sd->status.skill[id].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[id].lv;
+ } else {
+ sd->status.skill[id].id = id;
+ sd->status.skill[id].flag = SKILL_FLAG_TEMPORARY;
+ }
+ sd->status.skill[id].lv = level;
+ break;
+ case 2: //Add skill bonus on top of what you had.
+ if( sd->status.skill[id].id == id ){
+ if( sd->status.skill[id].flag == SKILL_FLAG_PERMANENT )
+ sd->status.skill[id].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[id].lv; // Store previous level.
+ } else {
+ sd->status.skill[id].id = id;
+ sd->status.skill[id].flag = SKILL_FLAG_TEMPORARY; //Set that this is a bonus skill.
+ }
+ sd->status.skill[id].lv += level;
+ break;
+ default: //Unknown flag?
+ return 0;
+ }
+ return 1;
}
/*==========================================
* Append a card to an item ?
*------------------------------------------*/
-int pc_insert_card(struct map_session_data *sd, int idx_card, int idx_equip)
-{
- int i;
- int nameid;
-
- nullpo_ret(sd);
-
- if (idx_equip < 0 || idx_equip >= MAX_INVENTORY || sd->inventory_data[idx_equip] == NULL)
- return 0; //Invalid item index.
- if (idx_card < 0 || idx_card >= MAX_INVENTORY || sd->inventory_data[idx_card] == NULL)
- return 0; //Invalid card index.
- if (sd->status.inventory[idx_equip].nameid <= 0 || sd->status.inventory[idx_equip].amount < 1)
- return 0; // target item missing
- if (sd->status.inventory[idx_card].nameid <= 0 || sd->status.inventory[idx_card].amount < 1)
- return 0; // target card missing
- if (sd->inventory_data[idx_equip]->type != IT_WEAPON && sd->inventory_data[idx_equip]->type != IT_ARMOR)
- return 0; // only weapons and armor are allowed
- if (sd->inventory_data[idx_card]->type != IT_CARD)
- return 0; // must be a card
- if (sd->status.inventory[idx_equip].identify == 0)
- return 0; // target must be identified
- if (itemdb_isspecial(sd->status.inventory[idx_equip].card[0]))
- return 0; // card slots reserved for other purposes
- if ((sd->inventory_data[idx_equip]->equip & sd->inventory_data[idx_card]->equip) == 0)
- return 0; // card cannot be compounded on this item type
- if (sd->inventory_data[idx_equip]->type == IT_WEAPON && sd->inventory_data[idx_card]->equip == EQP_SHIELD)
- return 0; // attempted to place shield card on left-hand weapon.
- if (sd->status.inventory[idx_equip].equip != 0)
- return 0; // item must be unequipped
-
- ARR_FIND(0, sd->inventory_data[idx_equip]->slot, i, sd->status.inventory[idx_equip].card[i] == 0);
- if (i == sd->inventory_data[idx_equip]->slot)
- return 0; // no free slots
-
- // remember the card id to insert
- nameid = sd->status.inventory[idx_card].nameid;
-
- if (pc_delitem(sd,idx_card,1,1,0,LOG_TYPE_OTHER) == 1) {
- // failed
- clif_insert_card(sd,idx_equip,idx_card,1);
- } else {
- // success
- log_pick_pc(sd, LOG_TYPE_OTHER, -1, &sd->status.inventory[idx_equip]);
- sd->status.inventory[idx_equip].card[i] = nameid;
- log_pick_pc(sd, LOG_TYPE_OTHER, 1, &sd->status.inventory[idx_equip]);
- clif_insert_card(sd,idx_equip,idx_card,0);
- }
-
- return 0;
+int pc_insert_card(struct map_session_data* sd, int idx_card, int idx_equip)
+{
+ int i;
+ int nameid;
+
+ nullpo_ret(sd);
+
+ if( idx_equip < 0 || idx_equip >= MAX_INVENTORY || sd->inventory_data[idx_equip] == NULL )
+ return 0; //Invalid item index.
+ if( idx_card < 0 || idx_card >= MAX_INVENTORY || sd->inventory_data[idx_card] == NULL )
+ return 0; //Invalid card index.
+ if( sd->status.inventory[idx_equip].nameid <= 0 || sd->status.inventory[idx_equip].amount < 1 )
+ return 0; // target item missing
+ if( sd->status.inventory[idx_card].nameid <= 0 || sd->status.inventory[idx_card].amount < 1 )
+ return 0; // target card missing
+ if( sd->inventory_data[idx_equip]->type != IT_WEAPON && sd->inventory_data[idx_equip]->type != IT_ARMOR )
+ return 0; // only weapons and armor are allowed
+ if( sd->inventory_data[idx_card]->type != IT_CARD )
+ return 0; // must be a card
+ if( sd->status.inventory[idx_equip].identify == 0 )
+ return 0; // target must be identified
+ if( itemdb_isspecial(sd->status.inventory[idx_equip].card[0]) )
+ return 0; // card slots reserved for other purposes
+ if( (sd->inventory_data[idx_equip]->equip & sd->inventory_data[idx_card]->equip) == 0 )
+ return 0; // card cannot be compounded on this item type
+ if( sd->inventory_data[idx_equip]->type == IT_WEAPON && sd->inventory_data[idx_card]->equip == EQP_SHIELD )
+ return 0; // attempted to place shield card on left-hand weapon.
+ if( sd->status.inventory[idx_equip].equip != 0 )
+ return 0; // item must be unequipped
+
+ ARR_FIND( 0, sd->inventory_data[idx_equip]->slot, i, sd->status.inventory[idx_equip].card[i] == 0 );
+ if( i == sd->inventory_data[idx_equip]->slot )
+ return 0; // no free slots
+
+ // remember the card id to insert
+ nameid = sd->status.inventory[idx_card].nameid;
+
+ if( pc_delitem(sd,idx_card,1,1,0,LOG_TYPE_OTHER) == 1 )
+ {// failed
+ clif_insert_card(sd,idx_equip,idx_card,1);
+ }
+ else
+ {// success
+ log_pick_pc(sd, LOG_TYPE_OTHER, -1, &sd->status.inventory[idx_equip]);
+ sd->status.inventory[idx_equip].card[i] = nameid;
+ log_pick_pc(sd, LOG_TYPE_OTHER, 1, &sd->status.inventory[idx_equip]);
+ clif_insert_card(sd,idx_equip,idx_card,0);
+ }
+
+ return 0;
}
//
@@ -3417,18 +3501,18 @@ int pc_insert_card(struct map_session_data *sd, int idx_card, int idx_equip)
*------------------------------------------*/
int pc_modifybuyvalue(struct map_session_data *sd,int orig_value)
{
- int skill,val = orig_value,rate1 = 0,rate2 = 0;
- if ((skill=pc_checkskill(sd,MC_DISCOUNT))>0) // merchant discount
- rate1 = 5+skill*2-((skill==10)? 1:0);
- if ((skill=pc_checkskill(sd,RG_COMPULSION))>0) // rogue discount
- rate2 = 5+skill*4;
- if (rate1 < rate2) rate1 = rate2;
- if (rate1)
- val = (int)((double)orig_value*(double)(100-rate1)/100.);
- if (val < 0) val = 0;
- if (orig_value > 0 && val < 1) val = 1;
+ int skill,val = orig_value,rate1 = 0,rate2 = 0;
+ if((skill=pc_checkskill(sd,MC_DISCOUNT))>0) // merchant discount
+ rate1 = 5+skill*2-((skill==10)? 1:0);
+ if((skill=pc_checkskill(sd,RG_COMPULSION))>0) // rogue discount
+ rate2 = 5+skill*4;
+ if(rate1 < rate2) rate1 = rate2;
+ if(rate1)
+ val = (int)((double)orig_value*(double)(100-rate1)/100.);
+ if(val < 0) val = 0;
+ if(orig_value > 0 && val < 1) val = 1;
- return val;
+ return val;
}
/*==========================================
@@ -3436,15 +3520,15 @@ int pc_modifybuyvalue(struct map_session_data *sd,int orig_value)
*------------------------------------------*/
int pc_modifysellvalue(struct map_session_data *sd,int orig_value)
{
- int skill,val = orig_value,rate = 0;
- if ((skill=pc_checkskill(sd,MC_OVERCHARGE))>0) //OverCharge
- rate = 5+skill*2-((skill==10)? 1:0);
- if (rate)
- val = (int)((double)orig_value*(double)(100+rate)/100.);
- if (val < 0) val = 0;
- if (orig_value > 0 && val < 1) val = 1;
+ int skill,val = orig_value,rate = 0;
+ if((skill=pc_checkskill(sd,MC_OVERCHARGE))>0) //OverCharge
+ rate = 5+skill*2-((skill==10)? 1:0);
+ if(rate)
+ val = (int)((double)orig_value*(double)(100+rate)/100.);
+ if(val < 0) val = 0;
+ if(orig_value > 0 && val < 1) val = 1;
- return val;
+ return val;
}
/*==========================================
@@ -3453,32 +3537,32 @@ int pc_modifysellvalue(struct map_session_data *sd,int orig_value)
*------------------------------------------*/
int pc_checkadditem(struct map_session_data *sd,int nameid,int amount)
{
- int i;
- struct item_data *data;
+ int i;
+ struct item_data* data;
- nullpo_ret(sd);
+ nullpo_ret(sd);
- if (amount > MAX_AMOUNT)
- return ADDITEM_OVERAMOUNT;
+ if(amount > MAX_AMOUNT)
+ return ADDITEM_OVERAMOUNT;
- data = itemdb_search(nameid);
+ data = itemdb_search(nameid);
- if (!itemdb_isstackable2(data))
- return ADDITEM_NEW;
+ if(!itemdb_isstackable2(data))
+ return ADDITEM_NEW;
- if (data->stack.inventory && amount > data->stack.amount)
- return ADDITEM_OVERAMOUNT;
+ if( data->stack.inventory && amount > data->stack.amount )
+ return ADDITEM_OVERAMOUNT;
- for (i=0; i<MAX_INVENTORY; i++) {
- // FIXME: This does not consider the checked item's cards, thus could check a wrong slot for stackability.
- if (sd->status.inventory[i].nameid==nameid) {
- if (amount > MAX_AMOUNT - sd->status.inventory[i].amount || (data->stack.inventory && amount > data->stack.amount - sd->status.inventory[i].amount))
- return ADDITEM_OVERAMOUNT;
- return ADDITEM_EXIST;
- }
- }
+ for(i=0;i<MAX_INVENTORY;i++){
+ // FIXME: This does not consider the checked item's cards, thus could check a wrong slot for stackability.
+ if(sd->status.inventory[i].nameid==nameid){
+ if( amount > MAX_AMOUNT - sd->status.inventory[i].amount || ( data->stack.inventory && amount > data->stack.amount - sd->status.inventory[i].amount ) )
+ return ADDITEM_OVERAMOUNT;
+ return ADDITEM_EXIST;
+ }
+ }
- return ADDITEM_NEW;
+ return ADDITEM_NEW;
}
/*==========================================
@@ -3487,16 +3571,16 @@ int pc_checkadditem(struct map_session_data *sd,int nameid,int amount)
*------------------------------------------*/
int pc_inventoryblank(struct map_session_data *sd)
{
- int i,b;
+ int i,b;
- nullpo_ret(sd);
+ nullpo_ret(sd);
- for (i=0,b=0; i<MAX_INVENTORY; i++) {
- if (sd->status.inventory[i].nameid==0)
- b++;
- }
+ for(i=0,b=0;i<MAX_INVENTORY;i++){
+ if(sd->status.inventory[i].nameid==0)
+ b++;
+ }
- return b;
+ return b;
}
/*==========================================
@@ -3504,29 +3588,30 @@ int pc_inventoryblank(struct map_session_data *sd)
*------------------------------------------*/
int pc_payzeny(struct map_session_data *sd,int zeny, enum e_log_pick_type type, struct map_session_data *tsd)
{
- nullpo_retr(-1,sd);
+ nullpo_retr(-1,sd);
- zeny = cap_value(zeny,-MAX_ZENY,MAX_ZENY); //prevent command UB
- if (zeny < 0) {
- ShowError("pc_payzeny: Paying negative Zeny (zeny=%d, account_id=%d, char_id=%d).\n", zeny, sd->status.account_id, sd->status.char_id);
- return 1;
- }
+ zeny = cap_value(zeny,-MAX_ZENY,MAX_ZENY); //prevent command UB
+ if( zeny < 0 )
+ {
+ ShowError("pc_payzeny: Paying negative Zeny (zeny=%d, account_id=%d, char_id=%d).\n", zeny, sd->status.account_id, sd->status.char_id);
+ return 1;
+ }
- if (sd->status.zeny < zeny)
- return 1; //Not enough.
+ if( sd->status.zeny < zeny )
+ return 1; //Not enough.
- sd->status.zeny -= zeny;
- clif_updatestatus(sd,SP_ZENY);
+ sd->status.zeny -= zeny;
+ clif_updatestatus(sd,SP_ZENY);
- if (!tsd) tsd = sd;
- log_zeny(sd, type, tsd, -zeny);
- if (zeny > 0 && sd->state.showzeny) {
- char output[255];
- sprintf(output, "Removed %dz.", zeny);
- clif_disp_onlyself(sd,output,strlen(output));
- }
+ if(!tsd) tsd = sd;
+ log_zeny(sd, type, tsd, -zeny);
+ if( zeny > 0 && sd->state.showzeny ) {
+ char output[255];
+ sprintf(output, "Removed %dz.", zeny);
+ clif_disp_onlyself(sd,output,strlen(output));
+ }
- return 0;
+ return 0;
}
/*==========================================
* Cash Shop
@@ -3534,81 +3619,95 @@ int pc_payzeny(struct map_session_data *sd,int zeny, enum e_log_pick_type type,
int pc_paycash(struct map_session_data *sd, int price, int points)
{
- char output[128];
- int cash;
- nullpo_retr(-1,sd);
+ char output[128];
+ int cash;
+ nullpo_retr(-1,sd);
- points = cap_value(points,-MAX_ZENY,MAX_ZENY); //prevent command UB
- if (price < 0 || points < 0) {
- ShowError("pc_paycash: Paying negative points (price=%d, points=%d, account_id=%d, char_id=%d).\n", price, points, sd->status.account_id, sd->status.char_id);
- return -2;
- }
+ points = cap_value(points,-MAX_ZENY,MAX_ZENY); //prevent command UB
+ if( price < 0 || points < 0 )
+ {
+ ShowError("pc_paycash: Paying negative points (price=%d, points=%d, account_id=%d, char_id=%d).\n", price, points, sd->status.account_id, sd->status.char_id);
+ return -2;
+ }
- if (points > price) {
- ShowWarning("pc_paycash: More kafra points provided than needed (price=%d, points=%d, account_id=%d, char_id=%d).\n", price, points, sd->status.account_id, sd->status.char_id);
- points = price;
- }
+ if( points > price )
+ {
+ ShowWarning("pc_paycash: More kafra points provided than needed (price=%d, points=%d, account_id=%d, char_id=%d).\n", price, points, sd->status.account_id, sd->status.char_id);
+ points = price;
+ }
- cash = price-points;
+ cash = price-points;
- if (sd->cashPoints < cash || sd->kafraPoints < points) {
- ShowError("pc_paycash: Not enough points (cash=%d, kafra=%d) to cover the price (cash=%d, kafra=%d) (account_id=%d, char_id=%d).\n", sd->cashPoints, sd->kafraPoints, cash, points, sd->status.account_id, sd->status.char_id);
- return -1;
- }
+ if( sd->cashPoints < cash || sd->kafraPoints < points )
+ {
+ ShowError("pc_paycash: Not enough points (cash=%d, kafra=%d) to cover the price (cash=%d, kafra=%d) (account_id=%d, char_id=%d).\n", sd->cashPoints, sd->kafraPoints, cash, points, sd->status.account_id, sd->status.char_id);
+ return -1;
+ }
- pc_setaccountreg(sd, "#CASHPOINTS", sd->cashPoints-cash);
- pc_setaccountreg(sd, "#KAFRAPOINTS", sd->kafraPoints-points);
+ pc_setaccountreg(sd, "#CASHPOINTS", sd->cashPoints-cash);
+ pc_setaccountreg(sd, "#KAFRAPOINTS", sd->kafraPoints-points);
- if (battle_config.cashshop_show_points) {
- sprintf(output, msg_txt(504), points, cash, sd->kafraPoints, sd->cashPoints);
- clif_disp_onlyself(sd, output, strlen(output));
- }
- return cash+points;
+ if( battle_config.cashshop_show_points )
+ {
+ sprintf(output, msg_txt(504), points, cash, sd->kafraPoints, sd->cashPoints);
+ clif_disp_onlyself(sd, output, strlen(output));
+ }
+ return cash+points;
}
int pc_getcash(struct map_session_data *sd, int cash, int points)
{
- char output[128];
- nullpo_retr(-1,sd);
-
- cash = cap_value(cash,-MAX_ZENY,MAX_ZENY); //prevent command UB
- points = cap_value(points,-MAX_ZENY,MAX_ZENY); //prevent command UB
- if (cash > 0) {
- if (cash > MAX_ZENY-sd->cashPoints) {
- ShowWarning("pc_getcash: Cash point overflow (cash=%d, have cash=%d, account_id=%d, char_id=%d).\n", cash, sd->cashPoints, sd->status.account_id, sd->status.char_id);
- cash = MAX_ZENY-sd->cashPoints;
- }
-
- pc_setaccountreg(sd, "#CASHPOINTS", sd->cashPoints+cash);
-
- if (battle_config.cashshop_show_points) {
- sprintf(output, msg_txt(505), cash, sd->cashPoints);
- clif_disp_onlyself(sd, output, strlen(output));
- }
- return cash;
- } else if (cash < 0) {
- ShowError("pc_getcash: Obtaining negative cash points (cash=%d, account_id=%d, char_id=%d).\n", cash, sd->status.account_id, sd->status.char_id);
- return -1;
- }
-
- if (points > 0) {
- if (points > MAX_ZENY-sd->kafraPoints) {
- ShowWarning("pc_getcash: Kafra point overflow (points=%d, have points=%d, account_id=%d, char_id=%d).\n", points, sd->kafraPoints, sd->status.account_id, sd->status.char_id);
- points = MAX_ZENY-sd->kafraPoints;
- }
-
- pc_setaccountreg(sd, "#KAFRAPOINTS", sd->kafraPoints+points);
-
- if (battle_config.cashshop_show_points) {
- sprintf(output, msg_txt(506), points, sd->kafraPoints);
- clif_disp_onlyself(sd, output, strlen(output));
- }
- return points;
- } else if (points < 0) {
- ShowError("pc_getcash: Obtaining negative kafra points (points=%d, account_id=%d, char_id=%d).\n", points, sd->status.account_id, sd->status.char_id);
- return -1;
- }
- return -2; //shouldn't happen but jsut in case
+ char output[128];
+ nullpo_retr(-1,sd);
+
+ cash = cap_value(cash,-MAX_ZENY,MAX_ZENY); //prevent command UB
+ points = cap_value(points,-MAX_ZENY,MAX_ZENY); //prevent command UB
+ if( cash > 0 )
+ {
+ if( cash > MAX_ZENY-sd->cashPoints )
+ {
+ ShowWarning("pc_getcash: Cash point overflow (cash=%d, have cash=%d, account_id=%d, char_id=%d).\n", cash, sd->cashPoints, sd->status.account_id, sd->status.char_id);
+ cash = MAX_ZENY-sd->cashPoints;
+ }
+
+ pc_setaccountreg(sd, "#CASHPOINTS", sd->cashPoints+cash);
+
+ if( battle_config.cashshop_show_points )
+ {
+ sprintf(output, msg_txt(505), cash, sd->cashPoints);
+ clif_disp_onlyself(sd, output, strlen(output));
+ }
+ return cash;
+ }
+ else if( cash < 0 )
+ {
+ ShowError("pc_getcash: Obtaining negative cash points (cash=%d, account_id=%d, char_id=%d).\n", cash, sd->status.account_id, sd->status.char_id);
+ return -1;
+ }
+
+ if( points > 0 )
+ {
+ if( points > MAX_ZENY-sd->kafraPoints )
+ {
+ ShowWarning("pc_getcash: Kafra point overflow (points=%d, have points=%d, account_id=%d, char_id=%d).\n", points, sd->kafraPoints, sd->status.account_id, sd->status.char_id);
+ points = MAX_ZENY-sd->kafraPoints;
+ }
+
+ pc_setaccountreg(sd, "#KAFRAPOINTS", sd->kafraPoints+points);
+
+ if( battle_config.cashshop_show_points )
+ {
+ sprintf(output, msg_txt(506), points, sd->kafraPoints);
+ clif_disp_onlyself(sd, output, strlen(output));
+ }
+ return points;
+ }
+ else if( points < 0 )
+ {
+ ShowError("pc_getcash: Obtaining negative kafra points (points=%d, account_id=%d, char_id=%d).\n", points, sd->status.account_id, sd->status.char_id);
+ return -1;
+ }
+ return -2; //shouldn't happen but jsut in case
}
/*==========================================
@@ -3617,29 +3716,30 @@ int pc_getcash(struct map_session_data *sd, int cash, int points)
*------------------------------------------*/
int pc_getzeny(struct map_session_data *sd,int zeny, enum e_log_pick_type type, struct map_session_data *tsd)
{
- nullpo_retr(-1,sd);
+ nullpo_retr(-1,sd);
- zeny = cap_value(zeny,-MAX_ZENY,MAX_ZENY); //prevent command UB
- if (zeny < 0) {
- ShowError("pc_getzeny: Obtaining negative Zeny (zeny=%d, account_id=%d, char_id=%d).\n", zeny, sd->status.account_id, sd->status.char_id);
- return 1;
- }
+ zeny = cap_value(zeny,-MAX_ZENY,MAX_ZENY); //prevent command UB
+ if( zeny < 0 )
+ {
+ ShowError("pc_getzeny: Obtaining negative Zeny (zeny=%d, account_id=%d, char_id=%d).\n", zeny, sd->status.account_id, sd->status.char_id);
+ return 1;
+ }
- if (zeny > MAX_ZENY - sd->status.zeny)
- zeny = MAX_ZENY - sd->status.zeny;
+ if( zeny > MAX_ZENY - sd->status.zeny )
+ zeny = MAX_ZENY - sd->status.zeny;
- sd->status.zeny += zeny;
- clif_updatestatus(sd,SP_ZENY);
+ sd->status.zeny += zeny;
+ clif_updatestatus(sd,SP_ZENY);
- if (!tsd) tsd = sd;
- log_zeny(sd, type, tsd, zeny);
- if (zeny > 0 && sd->state.showzeny) {
- char output[255];
- sprintf(output, "Gained %dz.", zeny);
- clif_disp_onlyself(sd,output,strlen(output));
- }
+ if(!tsd) tsd = sd;
+ log_zeny(sd, type, tsd, zeny);
+ if( zeny > 0 && sd->state.showzeny ) {
+ char output[255];
+ sprintf(output, "Gained %dz.", zeny);
+ clif_disp_onlyself(sd,output,strlen(output));
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -3647,11 +3747,11 @@ int pc_getzeny(struct map_session_data *sd,int zeny, enum e_log_pick_type type,
*------------------------------------------*/
int pc_search_inventory(struct map_session_data *sd,int item_id)
{
- int i;
- nullpo_retr(-1, sd);
+ int i;
+ nullpo_retr(-1, sd);
- ARR_FIND(0, MAX_INVENTORY, i, sd->status.inventory[i].nameid == item_id && (sd->status.inventory[i].amount > 0 || item_id == 0));
- return (i < MAX_INVENTORY) ? i : -1;
+ ARR_FIND( 0, MAX_INVENTORY, i, sd->status.inventory[i].nameid == item_id && (sd->status.inventory[i].amount > 0 || item_id == 0) );
+ return ( i < MAX_INVENTORY ) ? i : -1;
}
/*==========================================
@@ -3660,641 +3760,676 @@ int pc_search_inventory(struct map_session_data *sd,int item_id)
0 = success
1 = invalid itemid not found or negative amount
2 = overweight
- 3 = ?
+ 3 = ?
4 = no free place found
5 = max amount reached
- 6 = ?
- 7 = stack limitation
+ 6 = ?
+ 7 = stack limitation
*------------------------------------------*/
int pc_additem(struct map_session_data *sd,struct item *item_data,int amount,e_log_pick_type log_type)
{
- struct item_data *data;
- int i;
- unsigned int w;
-
- nullpo_retr(1, sd);
- nullpo_retr(1, item_data);
-
- if (item_data->nameid <= 0 || amount <= 0)
- return 1;
- if (amount > MAX_AMOUNT)
- return 5;
-
- data = itemdb_search(item_data->nameid);
-
- if (data->stack.inventory && amount > data->stack.amount) {
- // item stack limitation
- return 7;
- }
-
- w = data->weight*amount;
- if (sd->weight + w > sd->max_weight)
- return 2;
-
- i = MAX_INVENTORY;
-
- if (itemdb_isstackable2(data) && item_data->expire_time == 0) {
- // Stackable | Non Rental
- for (i = 0; i < MAX_INVENTORY; i++) {
- if (sd->status.inventory[i].nameid == item_data->nameid && memcmp(&sd->status.inventory[i].card, &item_data->card, sizeof(item_data->card)) == 0) {
- if (amount > MAX_AMOUNT - sd->status.inventory[i].amount || (data->stack.inventory && amount > data->stack.amount - sd->status.inventory[i].amount))
- return 5;
- sd->status.inventory[i].amount += amount;
- clif_additem(sd,i,amount,0);
- break;
- }
- }
- }
-
- if (i >= MAX_INVENTORY) {
- i = pc_search_inventory(sd,0);
- if (i < 0)
- return 4;
-
- memcpy(&sd->status.inventory[i], item_data, sizeof(sd->status.inventory[0]));
- // clear equips field first, just in case
- if (item_data->equip)
- sd->status.inventory[i].equip = 0;
-
- sd->status.inventory[i].amount = amount;
- sd->inventory_data[i] = data;
- clif_additem(sd,i,amount,0);
- }
- log_pick_pc(sd, log_type, amount, &sd->status.inventory[i]);
-
- sd->weight += w;
- clif_updatestatus(sd,SP_WEIGHT);
- //Auto-equip
- if (data->flag.autoequip)
- pc_equipitem(sd, i, data->equip);
-
- /* rental item check */
- if (item_data->expire_time) {
- if (time(NULL) > item_data->expire_time) {
- clif_rental_expired(sd->fd, i, sd->status.inventory[i].nameid);
- pc_delitem(sd, i, sd->status.inventory[i].amount, 1, 0, LOG_TYPE_OTHER);
- } else {
- int seconds = (int)(item_data->expire_time - time(NULL));
- clif_rental_time(sd->fd, sd->status.inventory[i].nameid, seconds);
- pc_inventory_rental_add(sd, seconds);
- }
- }
-
- return 0;
+ struct item_data *data;
+ int i;
+ unsigned int w;
+
+ nullpo_retr(1, sd);
+ nullpo_retr(1, item_data);
+
+ if( item_data->nameid <= 0 || amount <= 0 )
+ return 1;
+ if( amount > MAX_AMOUNT )
+ return 5;
+
+ data = itemdb_search(item_data->nameid);
+
+ if( data->stack.inventory && amount > data->stack.amount )
+ {// item stack limitation
+ return 7;
+ }
+
+ w = data->weight*amount;
+ if(sd->weight + w > sd->max_weight)
+ return 2;
+
+ i = MAX_INVENTORY;
+
+ if( itemdb_isstackable2(data) && item_data->expire_time == 0 )
+ { // Stackable | Non Rental
+ for( i = 0; i < MAX_INVENTORY; i++ )
+ {
+ if( sd->status.inventory[i].nameid == item_data->nameid && memcmp(&sd->status.inventory[i].card, &item_data->card, sizeof(item_data->card)) == 0 )
+ {
+ if( amount > MAX_AMOUNT - sd->status.inventory[i].amount || ( data->stack.inventory && amount > data->stack.amount - sd->status.inventory[i].amount ) )
+ return 5;
+ sd->status.inventory[i].amount += amount;
+ clif_additem(sd,i,amount,0);
+ break;
+ }
+ }
+ }
+
+ if( i >= MAX_INVENTORY )
+ {
+ i = pc_search_inventory(sd,0);
+ if( i < 0 )
+ return 4;
+
+ memcpy(&sd->status.inventory[i], item_data, sizeof(sd->status.inventory[0]));
+ // clear equips field first, just in case
+ if( item_data->equip )
+ sd->status.inventory[i].equip = 0;
+
+ sd->status.inventory[i].amount = amount;
+ sd->inventory_data[i] = data;
+ clif_additem(sd,i,amount,0);
+ }
+ log_pick_pc(sd, log_type, amount, &sd->status.inventory[i]);
+
+ sd->weight += w;
+ clif_updatestatus(sd,SP_WEIGHT);
+ //Auto-equip
+ if(data->flag.autoequip)
+ pc_equipitem(sd, i, data->equip);
+
+ /* rental item check */
+ if( item_data->expire_time ) {
+ if( time(NULL) > item_data->expire_time ) {
+ clif_rental_expired(sd->fd, i, sd->status.inventory[i].nameid);
+ pc_delitem(sd, i, sd->status.inventory[i].amount, 1, 0, LOG_TYPE_OTHER);
+ } else {
+ int seconds = (int)( item_data->expire_time - time(NULL) );
+ clif_rental_time(sd->fd, sd->status.inventory[i].nameid, seconds);
+ pc_inventory_rental_add(sd, seconds);
+ }
+ }
+
+ return 0;
}
/*==========================================
* Remove an item at index n from inventory by amount.
* Parameters :
* @type
- * 1 : don't notify deletion
- * 2 : don't notify weight change
+ * 1 : don't notify deletion
+ * 2 : don't notify weight change
* Return:
- * 0 = success
- * 1 = invalid itemid or negative amount
+ * 0 = success
+ * 1 = invalid itemid or negative amount
*------------------------------------------*/
int pc_delitem(struct map_session_data *sd,int n,int amount,int type, short reason, e_log_pick_type log_type)
{
- nullpo_retr(1, sd);
+ nullpo_retr(1, sd);
- if (sd->status.inventory[n].nameid==0 || amount <= 0 || sd->status.inventory[n].amount<amount || sd->inventory_data[n] == NULL)
- return 1;
+ if(sd->status.inventory[n].nameid==0 || amount <= 0 || sd->status.inventory[n].amount<amount || sd->inventory_data[n] == NULL)
+ return 1;
- log_pick_pc(sd, log_type, -amount, &sd->status.inventory[n]);
+ log_pick_pc(sd, log_type, -amount, &sd->status.inventory[n]);
- sd->status.inventory[n].amount -= amount;
- 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,3);
- memset(&sd->status.inventory[n],0,sizeof(sd->status.inventory[0]));
- sd->inventory_data[n] = NULL;
- }
- if (!(type&1))
- clif_delitem(sd,n,amount,reason);
- if (!(type&2))
- clif_updatestatus(sd,SP_WEIGHT);
+ sd->status.inventory[n].amount -= amount;
+ 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,3);
+ memset(&sd->status.inventory[n],0,sizeof(sd->status.inventory[0]));
+ sd->inventory_data[n] = NULL;
+ }
+ if(!(type&1))
+ clif_delitem(sd,n,amount,reason);
+ if(!(type&2))
+ clif_updatestatus(sd,SP_WEIGHT);
- return 0;
+ return 0;
}
/*==========================================
* Attempt to drop an item.
* Return:
- * 0 = fail
- * 1 = success
+ * 0 = fail
+ * 1 = success
*------------------------------------------*/
int pc_dropitem(struct map_session_data *sd,int n,int amount)
{
- nullpo_retr(1, sd);
+ nullpo_retr(1, sd);
- if (n < 0 || n >= MAX_INVENTORY)
- return 0;
+ if(n < 0 || n >= MAX_INVENTORY)
+ return 0;
- if (amount <= 0)
- return 0;
+ if(amount <= 0)
+ return 0;
- if (sd->status.inventory[n].nameid <= 0 ||
- sd->status.inventory[n].amount <= 0 ||
- sd->status.inventory[n].amount < amount ||
- sd->state.trading || sd->state.vending ||
- !sd->inventory_data[n] //pc_delitem would fail on this case.
- )
- return 0;
+ if(sd->status.inventory[n].nameid <= 0 ||
+ sd->status.inventory[n].amount <= 0 ||
+ sd->status.inventory[n].amount < amount ||
+ sd->state.trading || sd->state.vending ||
+ !sd->inventory_data[n] //pc_delitem would fail on this case.
+ )
+ return 0;
- if (map[sd->bl.m].flag.nodrop) {
- clif_displaymessage(sd->fd, msg_txt(271));
- return 0; //Can't drop items in nodrop mapflag maps.
- }
+ if( map[sd->bl.m].flag.nodrop )
+ {
+ clif_displaymessage (sd->fd, msg_txt(271));
+ return 0; //Can't drop items in nodrop mapflag maps.
+ }
- if (!pc_candrop(sd,&sd->status.inventory[n])) {
- clif_displaymessage(sd->fd, msg_txt(263));
- return 0;
- }
+ if( !pc_candrop(sd,&sd->status.inventory[n]) )
+ {
+ clif_displaymessage (sd->fd, msg_txt(263));
+ return 0;
+ }
- if (!map_addflooritem(&sd->status.inventory[n], amount, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 2))
- return 0;
+ if (!map_addflooritem(&sd->status.inventory[n], amount, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 2))
+ return 0;
- pc_delitem(sd, n, amount, 1, 0, LOG_TYPE_PICKDROP_PLAYER);
- clif_dropitem(sd, n, amount);
- return 1;
+ pc_delitem(sd, n, amount, 1, 0, LOG_TYPE_PICKDROP_PLAYER);
+ clif_dropitem(sd, n, amount);
+ return 1;
}
/*==========================================
* Attempt to pick up an item.
* Return:
- * 0 = fail
- * 1 = success
+ * 0 = fail
+ * 1 = success
*------------------------------------------*/
int pc_takeitem(struct map_session_data *sd,struct flooritem_data *fitem)
{
- int flag=0;
- unsigned int tick = gettick();
- struct map_session_data *first_sd = NULL,*second_sd = NULL,*third_sd = NULL;
- struct party_data *p=NULL;
-
- nullpo_ret(sd);
- nullpo_ret(fitem);
-
- if (!check_distance_bl(&fitem->bl, &sd->bl, 2) && sd->ud.skillid!=BS_GREED)
- return 0; // Distance is too far
-
- if (sd->status.party_id)
- p = party_search(sd->status.party_id);
-
- if (fitem->first_get_charid > 0 && fitem->first_get_charid != sd->status.char_id) {
- first_sd = map_charid2sd(fitem->first_get_charid);
- if (DIFF_TICK(tick,fitem->first_get_tick) < 0) {
- if (!(p && p->party.item&1 &&
- first_sd && first_sd->status.party_id == sd->status.party_id
- ))
- return 0;
- } else if (fitem->second_get_charid > 0 && fitem->second_get_charid != sd->status.char_id) {
- second_sd = map_charid2sd(fitem->second_get_charid);
- if (DIFF_TICK(tick, fitem->second_get_tick) < 0) {
- if (!(p && p->party.item&1 &&
- ((first_sd && first_sd->status.party_id == sd->status.party_id) ||
- (second_sd && second_sd->status.party_id == sd->status.party_id))
- ))
- return 0;
- } else if (fitem->third_get_charid > 0 && fitem->third_get_charid != sd->status.char_id) {
- third_sd = map_charid2sd(fitem->third_get_charid);
- if (DIFF_TICK(tick,fitem->third_get_tick) < 0) {
- if (!(p && p->party.item&1 &&
- ((first_sd && first_sd->status.party_id == sd->status.party_id) ||
- (second_sd && second_sd->status.party_id == sd->status.party_id) ||
- (third_sd && third_sd->status.party_id == sd->status.party_id))
- ))
- return 0;
- }
- }
- }
- }
-
- //This function takes care of giving the item to whoever should have it, considering party-share options.
- if ((flag = party_share_loot(p,sd,&fitem->item_data, fitem->first_get_charid))) {
- clif_additem(sd,0,0,flag);
- return 1;
- }
-
- //Display pickup animation.
- pc_stop_attack(sd);
- clif_takeitem(&sd->bl,&fitem->bl);
- map_clearflooritem(&fitem->bl);
- return 1;
+ int flag=0;
+ unsigned int tick = gettick();
+ struct map_session_data *first_sd = NULL,*second_sd = NULL,*third_sd = NULL;
+ struct party_data *p=NULL;
+
+ nullpo_ret(sd);
+ nullpo_ret(fitem);
+
+ if(!check_distance_bl(&fitem->bl, &sd->bl, 2) && sd->ud.skillid!=BS_GREED)
+ return 0; // Distance is too far
+
+ if (sd->status.party_id)
+ p = party_search(sd->status.party_id);
+
+ if(fitem->first_get_charid > 0 && fitem->first_get_charid != sd->status.char_id)
+ {
+ first_sd = map_charid2sd(fitem->first_get_charid);
+ if(DIFF_TICK(tick,fitem->first_get_tick) < 0) {
+ if (!(p && p->party.item&1 &&
+ first_sd && first_sd->status.party_id == sd->status.party_id
+ ))
+ return 0;
+ }
+ else
+ if(fitem->second_get_charid > 0 && fitem->second_get_charid != sd->status.char_id)
+ {
+ second_sd = map_charid2sd(fitem->second_get_charid);
+ if(DIFF_TICK(tick, fitem->second_get_tick) < 0) {
+ if(!(p && p->party.item&1 &&
+ ((first_sd && first_sd->status.party_id == sd->status.party_id) ||
+ (second_sd && second_sd->status.party_id == sd->status.party_id))
+ ))
+ return 0;
+ }
+ else
+ if(fitem->third_get_charid > 0 && fitem->third_get_charid != sd->status.char_id)
+ {
+ third_sd = map_charid2sd(fitem->third_get_charid);
+ if(DIFF_TICK(tick,fitem->third_get_tick) < 0) {
+ if(!(p && p->party.item&1 &&
+ ((first_sd && first_sd->status.party_id == sd->status.party_id) ||
+ (second_sd && second_sd->status.party_id == sd->status.party_id) ||
+ (third_sd && third_sd->status.party_id == sd->status.party_id))
+ ))
+ return 0;
+ }
+ }
+ }
+ }
+
+ //This function takes care of giving the item to whoever should have it, considering party-share options.
+ if ((flag = party_share_loot(p,sd,&fitem->item_data, fitem->first_get_charid))) {
+ clif_additem(sd,0,0,flag);
+ return 1;
+ }
+
+ //Display pickup animation.
+ pc_stop_attack(sd);
+ clif_takeitem(&sd->bl,&fitem->bl);
+ map_clearflooritem(&fitem->bl);
+ return 1;
}
/*==========================================
* Check if item is usable.
* Return:
- * 0 = no
- * 1 = yes
+ * 0 = no
+ * 1 = yes
*------------------------------------------*/
int pc_isUseitem(struct map_session_data *sd,int n)
{
- struct item_data *item;
- int nameid;
-
- nullpo_ret(sd);
-
- item = sd->inventory_data[n];
- nameid = sd->status.inventory[n].nameid;
-
- if (item == NULL)
- return 0;
- //Not consumable item
- if (item->type != IT_HEALING && item->type != IT_USABLE && item->type != IT_CASH)
- return 0;
- if (!item->script) //if it has no script, you can't really consume it!
- return 0;
-
- switch (nameid) { //@TODO, lot oh harcoded nameid here
- case 605: // Anodyne
- if (map_flag_gvg(sd->bl.m))
- return 0;
- case 606:
- if (pc_issit(sd))
- return 0;
- break;
- case 601: // Fly Wing
- case 12212: // Giant Fly Wing
- if (map[sd->bl.m].flag.noteleport || map_flag_gvg(sd->bl.m)) {
- clif_skill_teleportmessage(sd,0);
- return 0;
- }
- case 602: // ButterFly Wing
- case 14527: // Dungeon Teleport Scroll
- case 14581: // Dungeon Teleport Scroll
- case 14582: // Yellow Butterfly Wing
- case 14583: // Green Butterfly Wing
- case 14584: // Red Butterfly Wing
- case 14585: // Blue Butterfly Wing
- case 14591: // Siege Teleport Scroll
- if (sd->duel_group && !battle_config.duel_allow_teleport) {
- clif_displaymessage(sd->fd, msg_txt(663));
- return 0;
- }
- if (nameid != 601 && nameid != 12212 && map[sd->bl.m].flag.noreturn)
- return 0;
- break;
- case 604: // Dead Branch
- case 12024: // Red Pouch
- case 12103: // Bloody Branch
- case 12109: // Poring Box
- if (map[sd->bl.m].flag.nobranch || map_flag_gvg(sd->bl.m))
- return 0;
- break;
- case 12210: // Bubble Gum
- case 12264: // Comp Bubble Gum
- if (sd->sc.data[SC_ITEMBOOST])
- return 0;
- break;
- case 12208: // Battle Manual
- case 12263: // Comp Battle Manual
- case 12312: // Thick Battle Manual
- case 12705: // Noble Nameplate
- case 14532: // Battle_Manual25
- case 14533: // Battle_Manual100
- case 14545: // Battle_Manual300
- if (sd->sc.data[SC_EXPBOOST])
- return 0;
- break;
- case 14592: // JOB_Battle_Manual
- if (sd->sc.data[SC_JEXPBOOST])
- return 0;
- break;
-
- // Mercenary Items
-
- case 12184: // Mercenary's Red Potion
- case 12185: // Mercenary's Blue Potion
- case 12241: // Mercenary's Concentration Potion
- case 12242: // Mercenary's Awakening Potion
- case 12243: // Mercenary's Berserk Potion
- if (sd->md == NULL || sd->md->db == NULL)
- return 0;
- if (sd->md->sc.data[SC_BERSERK] || sd->md->sc.data[SC_SATURDAYNIGHTFEVER] || sd->md->sc.data[SC__BLOODYLUST])
- return 0;
- if (nameid == 12242 && sd->md->db->lv < 40)
- return 0;
- if (nameid == 12243 && sd->md->db->lv < 80)
- return 0;
- break;
-
- case 12213: //Neuralizer
- if (!map[sd->bl.m].flag.reset)
- return 0;
- break;
- }
-
- if (nameid >= 12153 && nameid <= 12182 && sd->md != NULL)
- return 0; // Mercenary Scrolls
-
- /**
- * Only Rune Knights may use runes
- **/
- if (itemdb_is_rune(nameid) && (sd->class_&MAPID_THIRDMASK) != MAPID_RUNE_KNIGHT)
- return 0;
- /**
- * Only GCross may use poisons
- **/
- else if (itemdb_is_poison(nameid) && (sd->class_&MAPID_THIRDMASK) != MAPID_GUILLOTINE_CROSS)
- return 0;
-
- //added item_noequip.txt items check by Maya&[Lupus]
- if (
- (!map_flag_vs(sd->bl.m) && item->flag.no_equip&1) || // Normal
- (map[sd->bl.m].flag.pvp && item->flag.no_equip&2) || // PVP
- (map_flag_gvg(sd->bl.m) && item->flag.no_equip&4) || // GVG
- (map[sd->bl.m].flag.battleground && item->flag.no_equip&8) || // Battleground
- (map[sd->bl.m].flag.restricted && item->flag.no_equip&(8*map[sd->bl.m].zone)) // Zone restriction
- )
- return 0;
-
- //Gender check
- if (item->sex != 2 && sd->status.sex != item->sex)
- return 0;
- //Required level check
- if (item->elv && sd->status.base_level < (unsigned int)item->elv)
- return 0;
+ struct item_data *item;
+ int nameid;
+
+ nullpo_ret(sd);
+
+ item = sd->inventory_data[n];
+ nameid = sd->status.inventory[n].nameid;
+
+ if( item == NULL )
+ return 0;
+ //Not consumable item
+ if( item->type != IT_HEALING && item->type != IT_USABLE && item->type != IT_CASH )
+ return 0;
+ if( !item->script ) //if it has no script, you can't really consume it!
+ return 0;
+
+ switch( nameid ) //@TODO, lot oh harcoded nameid here
+ {
+ case 605: // Anodyne
+ if( map_flag_gvg(sd->bl.m) )
+ return 0;
+ case 606:
+ if( pc_issit(sd) )
+ return 0;
+ break;
+ case 601: // Fly Wing
+ case 12212: // Giant Fly Wing
+ if( map[sd->bl.m].flag.noteleport || map_flag_gvg(sd->bl.m) )
+ {
+ clif_skill_teleportmessage(sd,0);
+ return 0;
+ }
+ case 602: // ButterFly Wing
+ case 14527: // Dungeon Teleport Scroll
+ case 14581: // Dungeon Teleport Scroll
+ case 14582: // Yellow Butterfly Wing
+ case 14583: // Green Butterfly Wing
+ case 14584: // Red Butterfly Wing
+ case 14585: // Blue Butterfly Wing
+ case 14591: // Siege Teleport Scroll
+ if( sd->duel_group && !battle_config.duel_allow_teleport )
+ {
+ clif_displaymessage(sd->fd, msg_txt(663));
+ return 0;
+ }
+ if( nameid != 601 && nameid != 12212 && map[sd->bl.m].flag.noreturn )
+ return 0;
+ break;
+ case 604: // Dead Branch
+ case 12024: // Red Pouch
+ case 12103: // Bloody Branch
+ case 12109: // Poring Box
+ if( map[sd->bl.m].flag.nobranch || map_flag_gvg(sd->bl.m) )
+ return 0;
+ break;
+ case 12210: // Bubble Gum
+ case 12264: // Comp Bubble Gum
+ if( sd->sc.data[SC_ITEMBOOST] )
+ return 0;
+ break;
+ case 12208: // Battle Manual
+ case 12263: // Comp Battle Manual
+ case 12312: // Thick Battle Manual
+ case 12705: // Noble Nameplate
+ case 14532: // Battle_Manual25
+ case 14533: // Battle_Manual100
+ case 14545: // Battle_Manual300
+ if( sd->sc.data[SC_EXPBOOST] )
+ return 0;
+ break;
+ case 14592: // JOB_Battle_Manual
+ if( sd->sc.data[SC_JEXPBOOST] )
+ return 0;
+ break;
+
+ // Mercenary Items
+
+ case 12184: // Mercenary's Red Potion
+ case 12185: // Mercenary's Blue Potion
+ case 12241: // Mercenary's Concentration Potion
+ case 12242: // Mercenary's Awakening Potion
+ case 12243: // Mercenary's Berserk Potion
+ if( sd->md == NULL || sd->md->db == NULL )
+ return 0;
+ if (sd->md->sc.data[SC_BERSERK] || sd->md->sc.data[SC_SATURDAYNIGHTFEVER] || sd->md->sc.data[SC__BLOODYLUST])
+ return 0;
+ if( nameid == 12242 && sd->md->db->lv < 40 )
+ return 0;
+ if( nameid == 12243 && sd->md->db->lv < 80 )
+ return 0;
+ break;
+
+ case 12213: //Neuralizer
+ if( !map[sd->bl.m].flag.reset )
+ return 0;
+ break;
+ }
+
+ if( nameid >= 12153 && nameid <= 12182 && sd->md != NULL )
+ return 0; // Mercenary Scrolls
+
+ /**
+ * Only Rune Knights may use runes
+ **/
+ if( itemdb_is_rune(nameid) && (sd->class_&MAPID_THIRDMASK) != MAPID_RUNE_KNIGHT )
+ return 0;
+ /**
+ * Only GCross may use poisons
+ **/
+ else if( itemdb_is_poison(nameid) && (sd->class_&MAPID_THIRDMASK) != MAPID_GUILLOTINE_CROSS )
+ return 0;
+
+ //added item_noequip.txt items check by Maya&[Lupus]
+ if (
+ (!map_flag_vs(sd->bl.m) && item->flag.no_equip&1) || // Normal
+ (map[sd->bl.m].flag.pvp && item->flag.no_equip&2) || // PVP
+ (map_flag_gvg(sd->bl.m) && item->flag.no_equip&4) || // GVG
+ (map[sd->bl.m].flag.battleground && item->flag.no_equip&8) || // Battleground
+ (map[sd->bl.m].flag.restricted && item->flag.no_equip&(8*map[sd->bl.m].zone)) // Zone restriction
+ )
+ return 0;
+
+ //Gender check
+ if(item->sex != 2 && sd->status.sex != item->sex)
+ return 0;
+ //Required level check
+ if(item->elv && sd->status.base_level < (unsigned int)item->elv)
+ return 0;
#ifdef RENEWAL
- if (item->elvmax && sd->status.base_level > (unsigned int)item->elvmax)
- return 0;
+ if(item->elvmax && sd->status.base_level > (unsigned int)item->elvmax)
+ return 0;
#endif
- //Not equipable by class. [Skotlex]
- if (!(
- (1<<(sd->class_&MAPID_BASEMASK)) &
- (item->class_base[sd->class_&JOBL_2_1?1:(sd->class_&JOBL_2_2?2:0)])
- ))
- return 0;
- //Not usable by upper class. [Inkfish]
- while (1) {
- if (item->class_upper&1 && !(sd->class_&(JOBL_UPPER|JOBL_THIRD|JOBL_BABY))) break;
- if (item->class_upper&2 && sd->class_&(JOBL_UPPER|JOBL_THIRD)) break;
- if (item->class_upper&4 && sd->class_&JOBL_BABY) break;
- if (item->class_upper&8 && sd->class_&JOBL_THIRD) break;
- return 0;
- }
-
- //Dead Branch & Bloody Branch & Porings Box
- // FIXME: outdated, use constants or database
- if (nameid == 604 || nameid == 12103 || nameid == 12109)
- log_branch(sd);
-
- return 1;
+ //Not equipable by class. [Skotlex]
+ if (!(
+ (1<<(sd->class_&MAPID_BASEMASK)) &
+ (item->class_base[sd->class_&JOBL_2_1?1:(sd->class_&JOBL_2_2?2:0)])
+ ))
+ return 0;
+ //Not usable by upper class. [Inkfish]
+ while( 1 ) {
+ if( item->class_upper&1 && !(sd->class_&(JOBL_UPPER|JOBL_THIRD|JOBL_BABY)) ) break;
+ if( item->class_upper&2 && sd->class_&(JOBL_UPPER|JOBL_THIRD) ) break;
+ if( item->class_upper&4 && sd->class_&JOBL_BABY ) break;
+ if( item->class_upper&8 && sd->class_&JOBL_THIRD ) break;
+ return 0;
+ }
+
+ //Dead Branch & Bloody Branch & Porings Box
+ // FIXME: outdated, use constants or database
+ if( nameid == 604 || nameid == 12103 || nameid == 12109 )
+ log_branch(sd);
+
+ return 1;
}
/*==========================================
* Last checks to use an item.
* Return:
- * 0 = fail
- * 1 = success
+ * 0 = fail
+ * 1 = success
*------------------------------------------*/
int pc_useitem(struct map_session_data *sd,int n)
{
- unsigned int tick = gettick();
- int amount, i, nameid;
- struct script_code *script;
-
- nullpo_ret(sd);
-
- if (sd->status.inventory[n].nameid <= 0 || sd->status.inventory[n].amount <= 0)
- return 0;
-
- if (!pc_isUseitem(sd,n))
- return 0;
-
- // Store information for later use before it is lost (via pc_delitem) [Paradox924X]
- nameid = sd->inventory_data[n]->nameid;
-
- if (nameid != ITEMID_NAUTHIZ && sd->sc.opt1 > 0 && sd->sc.opt1 != OPT1_STONEWAIT && sd->sc.opt1 != OPT1_BURNING)
- return 0;
-
- if (sd->sc.count && (
- sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] ||
- (sd->sc.data[SC_GRAVITATION] && sd->sc.data[SC_GRAVITATION]->val3 == BCT_SELF) ||
- sd->sc.data[SC_TRICKDEAD] ||
- sd->sc.data[SC_HIDING] ||
- sd->sc.data[SC__SHADOWFORM] ||
- sd->sc.data[SC__MANHOLE] ||
- sd->sc.data[SC_KAGEHUMI] ||
- (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOITEM)
- ))
- return 0;
-
- //Prevent mass item usage. [Skotlex]
- if (DIFF_TICK(sd->canuseitem_tick, tick) > 0 ||
- (itemdb_iscashfood(nameid) && DIFF_TICK(sd->canusecashfood_tick, tick) > 0)
- )
- return 0;
-
- /* Items with delayed consume are not meant to work while in mounts except reins of mount(12622) */
- if (sd->inventory_data[n]->flag.delay_consume) {
- if (nameid != ITEMID_REINS_OF_MOUNT && sd->sc.option&OPTION_MOUNTING)
- return 0;
- else if (pc_issit(sd))
- return 0;
- }
- //Since most delay-consume items involve using a "skill-type" target cursor,
- //perform a skill-use check before going through. [Skotlex]
- //resurrection was picked as testing skill, as a non-offensive, generic skill, it will do.
- //FIXME: Is this really needed here? It'll be checked in unit.c after all and this prevents skill items using when silenced [Inkfish]
- if (sd->inventory_data[n]->flag.delay_consume && (sd->ud.skilltimer != INVALID_TIMER /*|| !status_check_skilluse(&sd->bl, &sd->bl, ALL_RESURRECTION, 0)*/))
- return 0;
-
- if (sd->inventory_data[n]->delay > 0) {
- ARR_FIND(0, MAX_ITEMDELAYS, i, sd->item_delay[i].nameid == nameid);
- if (i == MAX_ITEMDELAYS) /* item not found. try first empty now */
- ARR_FIND(0, MAX_ITEMDELAYS, i, !sd->item_delay[i].nameid);
- if (i < MAX_ITEMDELAYS) {
- if (sd->item_delay[i].nameid) { // found
- if (DIFF_TICK(sd->item_delay[i].tick, tick) > 0) {
- int e_tick = DIFF_TICK(sd->item_delay[i].tick, tick)/1000;
- char e_msg[100];
- if (e_tick > 99)
- sprintf(e_msg,"Item Failed. [%s] is cooling down. wait %.1f minutes.",
- itemdb_jname(sd->status.inventory[n].nameid),
- (double)e_tick / 60);
- else
- sprintf(e_msg,"Item Failed. [%s] is cooling down. wait %d seconds.",
- itemdb_jname(sd->status.inventory[n].nameid),
- e_tick+1);
- clif_colormes(sd,COLOR_RED,e_msg);
- return 0; // Delay has not expired yet
- }
- } else {// not yet used item (all slots are initially empty)
- sd->item_delay[i].nameid = nameid;
- }
- sd->item_delay[i].tick = tick + sd->inventory_data[n]->delay;
- } else {// should not happen
- ShowError("pc_useitem: Exceeded item delay array capacity! (nameid=%d, char_id=%d)\n", nameid, sd->status.char_id);
- }
- //clean up used delays so we can give room for more
- for (i = 0; i < MAX_ITEMDELAYS; i++) {
- if (DIFF_TICK(sd->item_delay[i].tick, tick) <= 0) {
- sd->item_delay[i].tick = 0;
- sd->item_delay[i].nameid = 0;
- }
- }
- }
-
- sd->itemid = sd->status.inventory[n].nameid;
- sd->itemindex = n;
- if (sd->catch_target_class != -1) //Abort pet catching.
- sd->catch_target_class = -1;
-
- amount = sd->status.inventory[n].amount;
- script = sd->inventory_data[n]->script;
- //Check if the item is to be consumed immediately [Skotlex]
- if (sd->inventory_data[n]->flag.delay_consume)
- clif_useitemack(sd,n,amount,true);
- else {
- if (sd->status.inventory[n].expire_time == 0) {
- clif_useitemack(sd,n,amount-1,true);
- pc_delitem(sd,n,1,1,0,LOG_TYPE_CONSUME); // Rental Usable Items are not deleted until expiration
- } else
- clif_useitemack(sd,n,0,false);
- }
- if (sd->status.inventory[n].card[0]==CARD0_CREATE &&
- pc_famerank(MakeDWord(sd->status.inventory[n].card[2],sd->status.inventory[n].card[3]), MAPID_ALCHEMIST)) {
- potion_flag = 2; // Famous player's potions have 50% more efficiency
- if (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_ROGUE)
- potion_flag = 3; //Even more effective potions.
- }
-
- //Update item use time.
- sd->canuseitem_tick = tick + battle_config.item_use_interval;
- if (itemdb_iscashfood(nameid))
- sd->canusecashfood_tick = tick + battle_config.cashfood_use_interval;
-
- run_script(script,0,sd->bl.id,fake_nd->bl.id);
- potion_flag = 0;
- return 1;
+ unsigned int tick = gettick();
+ int amount, i, nameid;
+ struct script_code *script;
+
+ nullpo_ret(sd);
+
+ if( sd->status.inventory[n].nameid <= 0 || sd->status.inventory[n].amount <= 0 )
+ return 0;
+
+ if( !pc_isUseitem(sd,n) )
+ return 0;
+
+ // Store information for later use before it is lost (via pc_delitem) [Paradox924X]
+ nameid = sd->inventory_data[n]->nameid;
+
+ if (nameid != ITEMID_NAUTHIZ && sd->sc.opt1 > 0 && sd->sc.opt1 != OPT1_STONEWAIT && sd->sc.opt1 != OPT1_BURNING)
+ return 0;
+
+ if( sd->sc.count){
+ if((nameid == ITEMID_NAUTHIZ) && ( //bugreport 6751
+ sd->sc.data[SC_FREEZE] ||
+ sd->sc.data[SC_STUN] ||
+ sd->sc.data[SC_DEEPSLEEP] ||
+ sd->sc.data[SC_STONE] ||
+ sd->sc.data[SC_CRYSTALIZE]
+ )
+ ){
+ sd->sc.opt1 = 0; //remove option and status to allow skill
+ status_change_end(&sd->bl,SC_FREEZE,INVALID_TIMER);
+ status_change_end(&sd->bl,SC_STUN,INVALID_TIMER);
+ status_change_end(&sd->bl,SC_DEEPSLEEP,INVALID_TIMER);
+ status_change_end(&sd->bl,SC_STONE,INVALID_TIMER);
+ status_change_end(&sd->bl,SC_CRYSTALIZE,INVALID_TIMER);
+ } //let us continue
+ else if(
+ sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] ||
+ (sd->sc.data[SC_GRAVITATION] && sd->sc.data[SC_GRAVITATION]->val3 == BCT_SELF) ||
+ sd->sc.data[SC_TRICKDEAD] ||
+ sd->sc.data[SC_HIDING] ||
+ sd->sc.data[SC__SHADOWFORM] ||
+ sd->sc.data[SC__MANHOLE] ||
+ sd->sc.data[SC_KAGEHUMI] ||
+ (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOITEM)
+ )
+ return 0;
+ }
+
+ //Prevent mass item usage. [Skotlex]
+ if( DIFF_TICK(sd->canuseitem_tick, tick) > 0 ||
+ (itemdb_iscashfood(nameid) && DIFF_TICK(sd->canusecashfood_tick, tick) > 0)
+ )
+ return 0;
+
+ /* Items with delayed consume are not meant to work while in mounts except reins of mount(12622) */
+ if( sd->inventory_data[n]->flag.delay_consume ) {
+ if( nameid != ITEMID_REINS_OF_MOUNT && sd->sc.option&OPTION_MOUNTING )
+ return 0;
+ else if( pc_issit(sd) )
+ return 0;
+ }
+ //Since most delay-consume items involve using a "skill-type" target cursor,
+ //perform a skill-use check before going through. [Skotlex]
+ //resurrection was picked as testing skill, as a non-offensive, generic skill, it will do.
+ //FIXME: Is this really needed here? It'll be checked in unit.c after all and this prevents skill items using when silenced [Inkfish]
+ if( sd->inventory_data[n]->flag.delay_consume && ( sd->ud.skilltimer != INVALID_TIMER /*|| !status_check_skilluse(&sd->bl, &sd->bl, ALL_RESURRECTION, 0)*/ ) )
+ return 0;
+
+ if( sd->inventory_data[n]->delay > 0 ) {
+ ARR_FIND(0, MAX_ITEMDELAYS, i, sd->item_delay[i].nameid == nameid );
+ if( i == MAX_ITEMDELAYS ) /* item not found. try first empty now */
+ ARR_FIND(0, MAX_ITEMDELAYS, i, !sd->item_delay[i].nameid );
+ if( i < MAX_ITEMDELAYS ) {
+ if( sd->item_delay[i].nameid ) {// found
+ if( DIFF_TICK(sd->item_delay[i].tick, tick) > 0 ) {
+ int e_tick = DIFF_TICK(sd->item_delay[i].tick, tick)/1000;
+ char e_msg[100];
+ if( e_tick > 99 )
+ sprintf(e_msg,"Item Failed. [%s] is cooling down. wait %.1f minutes.",
+ itemdb_jname(sd->status.inventory[n].nameid),
+ (double)e_tick / 60);
+ else
+ sprintf(e_msg,"Item Failed. [%s] is cooling down. wait %d seconds.",
+ itemdb_jname(sd->status.inventory[n].nameid),
+ e_tick+1);
+ clif_colormes(sd,COLOR_RED,e_msg);
+ return 0; // Delay has not expired yet
+ }
+ } else {// not yet used item (all slots are initially empty)
+ sd->item_delay[i].nameid = nameid;
+ }
+ sd->item_delay[i].tick = tick + sd->inventory_data[n]->delay;
+ } else {// should not happen
+ ShowError("pc_useitem: Exceeded item delay array capacity! (nameid=%d, char_id=%d)\n", nameid, sd->status.char_id);
+ }
+ //clean up used delays so we can give room for more
+ for(i = 0; i < MAX_ITEMDELAYS; i++) {
+ if( DIFF_TICK(sd->item_delay[i].tick, tick) <= 0 ) {
+ sd->item_delay[i].tick = 0;
+ sd->item_delay[i].nameid = 0;
+ }
+ }
+ }
+
+ sd->itemid = sd->status.inventory[n].nameid;
+ sd->itemindex = n;
+ if(sd->catch_target_class != -1) //Abort pet catching.
+ sd->catch_target_class = -1;
+
+ amount = sd->status.inventory[n].amount;
+ script = sd->inventory_data[n]->script;
+ //Check if the item is to be consumed immediately [Skotlex]
+ if( sd->inventory_data[n]->flag.delay_consume )
+ clif_useitemack(sd,n,amount,true);
+ else {
+ if( sd->status.inventory[n].expire_time == 0 ) {
+ clif_useitemack(sd,n,amount-1,true);
+ pc_delitem(sd,n,1,1,0,LOG_TYPE_CONSUME); // Rental Usable Items are not deleted until expiration
+ } else
+ clif_useitemack(sd,n,0,false);
+ }
+ if(sd->status.inventory[n].card[0]==CARD0_CREATE &&
+ pc_famerank(MakeDWord(sd->status.inventory[n].card[2],sd->status.inventory[n].card[3]), MAPID_ALCHEMIST))
+ {
+ potion_flag = 2; // Famous player's potions have 50% more efficiency
+ if (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_ROGUE)
+ potion_flag = 3; //Even more effective potions.
+ }
+
+ //Update item use time.
+ sd->canuseitem_tick = tick + battle_config.item_use_interval;
+ if( itemdb_iscashfood(nameid) )
+ sd->canusecashfood_tick = tick + battle_config.cashfood_use_interval;
+
+ run_script(script,0,sd->bl.id,fake_nd->bl.id);
+ potion_flag = 0;
+ return 1;
}
/*==========================================
* Add item on cart for given index.
* Return:
- * 0 = success
- * 1 = fail
+ * 0 = success
+ * 1 = fail
*------------------------------------------*/
int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amount,e_log_pick_type log_type)
{
- struct item_data *data;
- int i,w;
-
- nullpo_retr(1, sd);
- nullpo_retr(1, item_data);
-
- if (item_data->nameid <= 0 || amount <= 0)
- return 1;
- data = itemdb_search(item_data->nameid);
-
- if (data->stack.cart && amount > data->stack.amount) {
- // item stack limitation
- return 1;
- }
-
- if (!itemdb_cancartstore(item_data, pc_get_group_level(sd))) {
- // Check item trade restrictions [Skotlex]
- clif_displaymessage(sd->fd, msg_txt(264));
- return 1;
- }
-
- if ((w = data->weight*amount) + sd->cart_weight > sd->cart_weight_max)
- return 1;
-
- i = MAX_CART;
- if (itemdb_isstackable2(data) && !item_data->expire_time) {
- ARR_FIND(0, MAX_CART, i,
- 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] &&
- sd->status.cart[i].card[2] == item_data->card[2] && sd->status.cart[i].card[3] == item_data->card[3]);
- };
-
- if (i < MAX_CART) {
- // item already in cart, stack it
- if (amount > MAX_AMOUNT - sd->status.cart[i].amount || (data->stack.cart && amount > data->stack.amount - sd->status.cart[i].amount))
- return 1; // no room
-
- sd->status.cart[i].amount+=amount;
- clif_cart_additem(sd,i,amount,0);
- } else {
- // item not stackable or not present, add it
- ARR_FIND(0, MAX_CART, i, sd->status.cart[i].nameid == 0);
- if (i == MAX_CART)
- return 1; // no room
-
- memcpy(&sd->status.cart[i],item_data,sizeof(sd->status.cart[0]));
- sd->status.cart[i].amount=amount;
- sd->cart_num++;
- clif_cart_additem(sd,i,amount,0);
- }
- sd->status.cart[i].favorite = 0;/* clear */
- log_pick_pc(sd, log_type, amount, &sd->status.cart[i]);
-
- sd->cart_weight += w;
- clif_updatestatus(sd,SP_CARTINFO);
-
- return 0;
+ struct item_data *data;
+ int i,w;
+
+ nullpo_retr(1, sd);
+ nullpo_retr(1, item_data);
+
+ if(item_data->nameid <= 0 || amount <= 0)
+ return 1;
+ data = itemdb_search(item_data->nameid);
+
+ if( data->stack.cart && amount > data->stack.amount )
+ {// item stack limitation
+ return 1;
+ }
+
+ if( !itemdb_cancartstore(item_data, pc_get_group_level(sd)) )
+ { // Check item trade restrictions [Skotlex]
+ clif_displaymessage (sd->fd, msg_txt(264));
+ return 1;
+ }
+
+ if( (w = data->weight*amount) + sd->cart_weight > sd->cart_weight_max )
+ return 1;
+
+ i = MAX_CART;
+ if( itemdb_isstackable2(data) && !item_data->expire_time )
+ {
+ ARR_FIND( 0, MAX_CART, i,
+ 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] &&
+ sd->status.cart[i].card[2] == item_data->card[2] && sd->status.cart[i].card[3] == item_data->card[3] );
+ };
+
+ if( i < MAX_CART )
+ {// item already in cart, stack it
+ if( amount > MAX_AMOUNT - sd->status.cart[i].amount || ( data->stack.cart && amount > data->stack.amount - sd->status.cart[i].amount ) )
+ return 1; // no room
+
+ sd->status.cart[i].amount+=amount;
+ clif_cart_additem(sd,i,amount,0);
+ }
+ else
+ {// item not stackable or not present, add it
+ ARR_FIND( 0, MAX_CART, i, sd->status.cart[i].nameid == 0 );
+ if( i == MAX_CART )
+ return 1; // no room
+
+ memcpy(&sd->status.cart[i],item_data,sizeof(sd->status.cart[0]));
+ sd->status.cart[i].amount=amount;
+ sd->cart_num++;
+ clif_cart_additem(sd,i,amount,0);
+ }
+ sd->status.cart[i].favorite = 0;/* clear */
+ log_pick_pc(sd, log_type, amount, &sd->status.cart[i]);
+
+ sd->cart_weight += w;
+ clif_updatestatus(sd,SP_CARTINFO);
+
+ return 0;
}
/*==========================================
* Delete item on cart for given index.
* Return:
- * 0 = success
- * 1 = fail
+ * 0 = success
+ * 1 = fail
*------------------------------------------*/
int pc_cart_delitem(struct map_session_data *sd,int n,int amount,int type,e_log_pick_type log_type)
{
- nullpo_retr(1, sd);
+ nullpo_retr(1, sd);
- if (sd->status.cart[n].nameid==0 ||
- sd->status.cart[n].amount<amount)
- return 1;
+ if(sd->status.cart[n].nameid==0 ||
+ sd->status.cart[n].amount<amount)
+ return 1;
- log_pick_pc(sd, log_type, -amount, &sd->status.cart[n]);
+ log_pick_pc(sd, log_type, -amount, &sd->status.cart[n]);
- sd->status.cart[n].amount -= amount;
- sd->cart_weight -= itemdb_weight(sd->status.cart[n].nameid)*amount ;
- if (sd->status.cart[n].amount <= 0) {
- memset(&sd->status.cart[n],0,sizeof(sd->status.cart[0]));
- sd->cart_num--;
- }
- if (!type) {
- clif_cart_delitem(sd,n,amount);
- clif_updatestatus(sd,SP_CARTINFO);
- }
+ sd->status.cart[n].amount -= amount;
+ sd->cart_weight -= itemdb_weight(sd->status.cart[n].nameid)*amount ;
+ if(sd->status.cart[n].amount <= 0){
+ memset(&sd->status.cart[n],0,sizeof(sd->status.cart[0]));
+ sd->cart_num--;
+ }
+ if(!type) {
+ clif_cart_delitem(sd,n,amount);
+ clif_updatestatus(sd,SP_CARTINFO);
+ }
- return 0;
+ return 0;
}
/*==========================================
* Transfer item from inventory to cart.
* Return:
- * 0 = fail
- * 1 = succes
+ * 0 = fail
+ * 1 = succes
*------------------------------------------*/
int pc_putitemtocart(struct map_session_data *sd,int idx,int amount)
{
- struct item *item_data;
+ struct item *item_data;
- nullpo_ret(sd);
+ nullpo_ret(sd);
- if (idx < 0 || idx >= MAX_INVENTORY) //Invalid index check [Skotlex]
- return 1;
+ if (idx < 0 || idx >= MAX_INVENTORY) //Invalid index check [Skotlex]
+ return 1;
- item_data = &sd->status.inventory[idx];
+ item_data = &sd->status.inventory[idx];
- if (item_data->nameid == 0 || amount < 1 || item_data->amount < amount || sd->state.vending)
- return 1;
+ if( item_data->nameid == 0 || amount < 1 || item_data->amount < amount || sd->state.vending )
+ return 1;
- if (pc_cart_additem(sd,item_data,amount,LOG_TYPE_NONE) == 0)
- return pc_delitem(sd,idx,amount,0,5,LOG_TYPE_NONE);
+ if( pc_cart_additem(sd,item_data,amount,LOG_TYPE_NONE) == 0 )
+ return pc_delitem(sd,idx,amount,0,5,LOG_TYPE_NONE);
- return 1;
+ return 1;
}
/*==========================================
@@ -4303,44 +4438,44 @@ int pc_putitemtocart(struct map_session_data *sd,int idx,int amount)
-1 = itemid not found or no amount found
x = remaining itemid on cart after get
*------------------------------------------*/
-int pc_cartitem_amount(struct map_session_data *sd, int idx, int amount)
+int pc_cartitem_amount(struct map_session_data* sd, int idx, int amount)
{
- struct item *item_data;
+ struct item* item_data;
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- item_data = &sd->status.cart[idx];
- if (item_data->nameid == 0 || item_data->amount == 0)
- return -1;
+ item_data = &sd->status.cart[idx];
+ if( item_data->nameid == 0 || item_data->amount == 0 )
+ return -1;
- return item_data->amount - amount;
+ return item_data->amount - amount;
}
/*==========================================
* Retrieve an item at index idx from cart.
* Return:
- * 0 = player not found or (FIXME) succes (from pc_cart_delitem)
- * 1 = failure
+ * 0 = player not found or (FIXME) succes (from pc_cart_delitem)
+ * 1 = failure
*------------------------------------------*/
int pc_getitemfromcart(struct map_session_data *sd,int idx,int amount)
{
- struct item *item_data;
- int flag;
+ struct item *item_data;
+ int flag;
- nullpo_ret(sd);
+ nullpo_ret(sd);
- if (idx < 0 || idx >= MAX_CART) //Invalid index check [Skotlex]
- return 1;
+ if (idx < 0 || idx >= MAX_CART) //Invalid index check [Skotlex]
+ return 1;
- item_data=&sd->status.cart[idx];
+ item_data=&sd->status.cart[idx];
- if (item_data->nameid==0 || amount < 1 || item_data->amount<amount || sd->state.vending)
- return 1;
- if ((flag = pc_additem(sd,item_data,amount,LOG_TYPE_NONE)) == 0)
- return pc_cart_delitem(sd,idx,amount,0,LOG_TYPE_NONE);
+ if(item_data->nameid==0 || amount < 1 || item_data->amount<amount || sd->state.vending )
+ return 1;
+ if((flag = pc_additem(sd,item_data,amount,LOG_TYPE_NONE)) == 0)
+ return pc_cart_delitem(sd,idx,amount,0,LOG_TYPE_NONE);
- clif_additem(sd,0,0,flag);
- return 1;
+ clif_additem(sd,0,0,flag);
+ return 1;
}
/*==========================================
@@ -4348,136 +4483,137 @@ int pc_getitemfromcart(struct map_session_data *sd,int idx,int amount)
*------------------------------------------*/
int pc_show_steal(struct block_list *bl,va_list ap)
{
- struct map_session_data *sd;
- int itemid;
+ struct map_session_data *sd;
+ int itemid;
- struct item_data *item=NULL;
- char output[100];
+ struct item_data *item=NULL;
+ char output[100];
- sd=va_arg(ap,struct map_session_data *);
- itemid=va_arg(ap,int);
+ sd=va_arg(ap,struct map_session_data *);
+ itemid=va_arg(ap,int);
- if ((item=itemdb_exists(itemid))==NULL)
- sprintf(output,"%s stole an Unknown Item (id: %i).",sd->status.name, itemid);
- else
- sprintf(output,"%s stole %s.",sd->status.name,item->jname);
- clif_displaymessage(((struct map_session_data *)bl)->fd, output);
+ if((item=itemdb_exists(itemid))==NULL)
+ sprintf(output,"%s stole an Unknown Item (id: %i).",sd->status.name, itemid);
+ else
+ sprintf(output,"%s stole %s.",sd->status.name,item->jname);
+ clif_displaymessage( ((struct map_session_data *)bl)->fd, output);
- return 0;
+ return 0;
}
/*==========================================
* Steal an item from bl (mob).
* Return:
- * 0 = fail
- * 1 = succes
+ * 0 = fail
+ * 1 = succes
*------------------------------------------*/
int pc_steal_item(struct map_session_data *sd,struct block_list *bl, int lv)
{
- int i,itemid,flag;
- double rate;
- struct status_data *sd_status, *md_status;
- struct mob_data *md;
- struct item tmp_item;
-
- if (!sd || !bl || bl->type!=BL_MOB)
- return 0;
-
- md = (TBL_MOB *)bl;
-
- if (md->state.steal_flag == UCHAR_MAX || (md->sc.opt1 && md->sc.opt1 != OPT1_BURNING && md->sc.opt1 != OPT1_CRYSTALIZE)) //already stolen from / status change check
- return 0;
-
- sd_status= status_get_status_data(&sd->bl);
- md_status= status_get_status_data(bl);
-
- if (md->master_id || md_status->mode&MD_BOSS || mob_is_treasure(md) ||
- map[bl->m].flag.nomobloot || // check noloot map flag [Lorky]
- (battle_config.skill_steal_max_tries && //Reached limit of steal attempts. [Lupus]
- md->state.steal_flag++ >= battle_config.skill_steal_max_tries)
- ) { //Can't steal from
- md->state.steal_flag = UCHAR_MAX;
- return 0;
- }
-
- // base skill success chance (percentual)
- rate = (sd_status->dex - md_status->dex)/2 + lv*6 + 4;
- rate += sd->bonus.add_steal_rate;
-
- if (rate < 1)
- return 0;
-
- // Try dropping one item, in the order from first to last possible slot.
- // Droprate is affected by the skill success rate.
- for (i = 0; i < MAX_STEAL_DROP; i++)
- if (md->db->dropitem[i].nameid > 0 && itemdb_exists(md->db->dropitem[i].nameid) && rnd() % 10000 < md->db->dropitem[i].p * rate/100.)
- break;
- if (i == MAX_STEAL_DROP)
- return 0;
-
- itemid = md->db->dropitem[i].nameid;
- memset(&tmp_item,0,sizeof(tmp_item));
- tmp_item.nameid = itemid;
- tmp_item.amount = 1;
- tmp_item.identify = itemdb_isidentified(itemid);
- flag = pc_additem(sd,&tmp_item,1,LOG_TYPE_PICKDROP_PLAYER);
-
- //TODO: Should we disable stealing when the item you stole couldn't be added to your inventory? Perhaps players will figure out a way to exploit this behaviour otherwise?
- md->state.steal_flag = UCHAR_MAX; //you can't steal from this mob any more
-
- if (flag) { //Failed to steal due to overweight
- clif_additem(sd,0,0,flag);
- return 0;
- }
-
- if (battle_config.show_steal_in_same_party)
- party_foreachsamemap(pc_show_steal,sd,AREA_SIZE,sd,tmp_item.nameid);
-
- //Logs items, Stolen from mobs [Lupus]
- log_pick_mob(md, LOG_TYPE_STEAL, -1, &tmp_item);
-
- //A Rare Steal Global Announce by Lupus
- if (md->db->dropitem[i].p<=battle_config.rare_drop_announce) {
- struct item_data *i_data;
- char message[128];
- i_data = itemdb_search(itemid);
- sprintf(message, msg_txt(542), (sd->status.name != NULL)?sd->status.name :"GM", md->db->jname, i_data->jname, (float)md->db->dropitem[i].p/100);
- //MSG: "'%s' stole %s's %s (chance: %0.02f%%)"
- intif_broadcast(message,strlen(message)+1,0);
- }
- return 1;
+ int i,itemid,flag;
+ double rate;
+ struct status_data *sd_status, *md_status;
+ struct mob_data *md;
+ struct item tmp_item;
+
+ if(!sd || !bl || bl->type!=BL_MOB)
+ return 0;
+
+ md = (TBL_MOB *)bl;
+
+ if(md->state.steal_flag == UCHAR_MAX || ( md->sc.opt1 && md->sc.opt1 != OPT1_BURNING && md->sc.opt1 != OPT1_CRYSTALIZE ) ) //already stolen from / status change check
+ return 0;
+
+ sd_status= status_get_status_data(&sd->bl);
+ md_status= status_get_status_data(bl);
+
+ if( md->master_id || md_status->mode&MD_BOSS || mob_is_treasure(md) ||
+ map[bl->m].flag.nomobloot || // check noloot map flag [Lorky]
+ (battle_config.skill_steal_max_tries && //Reached limit of steal attempts. [Lupus]
+ md->state.steal_flag++ >= battle_config.skill_steal_max_tries)
+ ) { //Can't steal from
+ md->state.steal_flag = UCHAR_MAX;
+ return 0;
+ }
+
+ // base skill success chance (percentual)
+ rate = (sd_status->dex - md_status->dex)/2 + lv*6 + 4;
+ rate += sd->bonus.add_steal_rate;
+
+ if( rate < 1 )
+ return 0;
+
+ // Try dropping one item, in the order from first to last possible slot.
+ // Droprate is affected by the skill success rate.
+ for( i = 0; i < MAX_STEAL_DROP; i++ )
+ if( md->db->dropitem[i].nameid > 0 && itemdb_exists(md->db->dropitem[i].nameid) && rnd() % 10000 < md->db->dropitem[i].p * rate/100. )
+ break;
+ if( i == MAX_STEAL_DROP )
+ return 0;
+
+ itemid = md->db->dropitem[i].nameid;
+ memset(&tmp_item,0,sizeof(tmp_item));
+ tmp_item.nameid = itemid;
+ tmp_item.amount = 1;
+ tmp_item.identify = itemdb_isidentified(itemid);
+ flag = pc_additem(sd,&tmp_item,1,LOG_TYPE_PICKDROP_PLAYER);
+
+ //TODO: Should we disable stealing when the item you stole couldn't be added to your inventory? Perhaps players will figure out a way to exploit this behaviour otherwise?
+ md->state.steal_flag = UCHAR_MAX; //you can't steal from this mob any more
+
+ if(flag) { //Failed to steal due to overweight
+ clif_additem(sd,0,0,flag);
+ return 0;
+ }
+
+ if(battle_config.show_steal_in_same_party)
+ party_foreachsamemap(pc_show_steal,sd,AREA_SIZE,sd,tmp_item.nameid);
+
+ //Logs items, Stolen from mobs [Lupus]
+ log_pick_mob(md, LOG_TYPE_STEAL, -1, &tmp_item);
+
+ //A Rare Steal Global Announce by Lupus
+ if(md->db->dropitem[i].p<=battle_config.rare_drop_announce) {
+ struct item_data *i_data;
+ char message[128];
+ i_data = itemdb_search(itemid);
+ sprintf (message, msg_txt(542), (sd->status.name != NULL)?sd->status.name :"GM", md->db->jname, i_data->jname, (float)md->db->dropitem[i].p/100);
+ //MSG: "'%s' stole %s's %s (chance: %0.02f%%)"
+ intif_broadcast(message,strlen(message)+1,0);
+ }
+ return 1;
}
/*==========================================
* Stole zeny from bl (mob)
* return
- * 0 = fail
- * 1 = success
+ * 0 = fail
+ * 1 = success
*------------------------------------------*/
int pc_steal_coin(struct map_session_data *sd,struct block_list *target)
{
- int rate,skill;
- struct mob_data *md;
- if (!sd || !target || target->type != BL_MOB)
- return 0;
+ int rate,skill;
+ struct mob_data *md;
+ if(!sd || !target || target->type != BL_MOB)
+ return 0;
- md = (TBL_MOB *)target;
- if (md->state.steal_coin_flag || md->sc.data[SC_STONE] || md->sc.data[SC_FREEZE] || md->status.mode&MD_BOSS)
- return 0;
+ md = (TBL_MOB*)target;
+ if( md->state.steal_coin_flag || md->sc.data[SC_STONE] || md->sc.data[SC_FREEZE] || md->status.mode&MD_BOSS )
+ return 0;
- if (mob_is_treasure(md))
- return 0;
+ if( mob_is_treasure(md) )
+ return 0;
- // FIXME: This formula is either custom or outdated.
- skill = pc_checkskill(sd,RG_STEALCOIN)*10;
- rate = skill + (sd->status.base_level - md->level)*3 + sd->battle_status.dex*2 + sd->battle_status.luk*2;
- if (rnd()%1000 < rate) {
- int amount = md->level*10 + rnd()%100;
+ // FIXME: This formula is either custom or outdated.
+ skill = pc_checkskill(sd,RG_STEALCOIN)*10;
+ rate = skill + (sd->status.base_level - md->level)*3 + sd->battle_status.dex*2 + sd->battle_status.luk*2;
+ if(rnd()%1000 < rate)
+ {
+ int amount = md->level*10 + rnd()%100;
- pc_getzeny(sd, amount, LOG_TYPE_STEAL, NULL);
- md->state.steal_coin_flag = 1;
- return 1;
- }
- return 0;
+ pc_getzeny(sd, amount, LOG_TYPE_STEAL, NULL);
+ md->state.steal_coin_flag = 1;
+ return 1;
+ }
+ return 0;
}
/*==========================================
@@ -4487,242 +4623,250 @@ int pc_steal_coin(struct map_session_data *sd,struct block_list *target)
* 1 - Invalid map index.
* 2 - Map not in this map-server, and failed to locate alternate map-server.
*------------------------------------------*/
-int pc_setpos(struct map_session_data *sd, unsigned short mapindex, int x, int y, clr_type clrtype)
-{
- struct party_data *p;
- int m;
-
- nullpo_ret(sd);
-
- if (!mapindex || !mapindex_id2name(mapindex)) {
- ShowDebug("pc_setpos: Passed mapindex(%d) is invalid!\n", mapindex);
- return 1;
- }
-
- if (pc_isdead(sd)) {
- //Revive dead people before warping them
- pc_setstand(sd);
- pc_setrestartvalue(sd,1);
- }
-
- m = map_mapindex2mapid(mapindex);
- if (map[m].flag.src4instance && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id) {
- // Request the mapid of this src map into the instance of the party
- int im = instance_map2imap(m, p->instance_id);
- if (im < 0)
- ; // Player will enter the src map for instances
- else {
- // Changes destiny to the instance map, not the source map
- m = im;
- mapindex = map_id2index(m);
- }
- }
-
- sd->state.changemap = (sd->mapindex != mapindex);
- sd->state.warping = 1;
- if (sd->state.changemap) { // Misc map-changing settings
- int i;
- sd->state.pmap = sd->bl.m;
- if (sd->sc.count) { // Cancel some map related stuff.
- if (sd->sc.data[SC_JAILED])
- return 1; //You may not get out!
- status_change_end(&sd->bl, SC_BOSSMAPINFO, INVALID_TIMER);
- status_change_end(&sd->bl, SC_WARM, INVALID_TIMER);
- status_change_end(&sd->bl, SC_SUN_COMFORT, INVALID_TIMER);
- status_change_end(&sd->bl, SC_MOON_COMFORT, INVALID_TIMER);
- status_change_end(&sd->bl, SC_STAR_COMFORT, INVALID_TIMER);
- status_change_end(&sd->bl, SC_MIRACLE, INVALID_TIMER);
- if (sd->sc.data[SC_KNOWLEDGE]) {
- struct status_change_entry *sce = sd->sc.data[SC_KNOWLEDGE];
- if (sce->timer != INVALID_TIMER)
- delete_timer(sce->timer, status_change_timer);
- sce->timer = add_timer(gettick() + skill_get_time(SG_KNOWLEDGE, sce->val1), status_change_timer, sd->bl.id, SC_KNOWLEDGE);
- }
- status_change_end(&sd->bl, SC_PROPERTYWALK, INVALID_TIMER);
- status_change_end(&sd->bl, SC_CLOAKING, INVALID_TIMER);
- status_change_end(&sd->bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
- }
- for (i = 0; i < EQI_MAX; i++) {
- if (sd->equip_index[ i ] >= 0)
- if (!pc_isequip(sd , sd->equip_index[ i ]))
- pc_unequipitem(sd , sd->equip_index[ i ] , 2);
- }
- if (battle_config.clear_unit_onwarp&BL_PC)
- skill_clear_unitgroup(&sd->bl);
- party_send_dot_remove(sd); //minimap dot fix [Kevin]
- guild_send_dot_remove(sd);
- bg_send_dot_remove(sd);
- if (sd->regen.state.gc)
- sd->regen.state.gc = 0;
- // make sure vending is allowed here
- if (sd->state.vending && map[m].flag.novending) {
- clif_displaymessage(sd->fd, msg_txt(276)); // "You can't open a shop on this map"
- vending_closevending(sd);
- }
- }
-
- if (m < 0) {
- uint32 ip;
- uint16 port;
- //if can't find any map-servers, just abort setting position.
- if (!sd->mapindex || map_mapname2ipport(mapindex,&ip,&port))
- return 2;
-
- if (sd->npc_id)
- npc_event_dequeue(sd);
- npc_script_event(sd, NPCE_LOGOUT);
- //remove from map, THEN change x/y coordinates
- unit_remove_map_pc(sd,clrtype);
- sd->mapindex = mapindex;
- sd->bl.x=x;
- sd->bl.y=y;
- pc_clean_skilltree(sd);
- chrif_save(sd,2);
- chrif_changemapserver(sd, ip, (short)port);
-
- //Free session data from this map server [Kevin]
- unit_free_pc(sd);
-
- return 0;
- }
-
- if (x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys) {
- ShowError("pc_setpos: attempt to place player %s (%d:%d) on invalid coordinates (%s-%d,%d)\n", sd->status.name, sd->status.account_id, sd->status.char_id, mapindex_id2name(mapindex),x,y);
- x = y = 0; // make it random
- }
-
- if (x == 0 && y == 0) {
- // pick a random walkable cell
- do {
- x=rnd()%(map[m].xs-2)+1;
- y=rnd()%(map[m].ys-2)+1;
- } while (map_getcell(m,x,y,CELL_CHKNOPASS));
- }
-
- if (sd->state.vending && map_getcell(m,x,y,CELL_CHKNOVENDING)) {
- clif_displaymessage(sd->fd, msg_txt(204)); // "You can't open a shop on this cell."
- vending_closevending(sd);
- }
-
- if (sd->bl.prev != NULL) {
- unit_remove_map_pc(sd,clrtype);
- clif_changemap(sd,map[m].index,x,y); // [MouseJstr]
- } else if (sd->state.active)
- //Tag player for rewarping after map-loading is done. [Skotlex]
- sd->state.rewarp = 1;
-
- sd->mapindex = mapindex;
- sd->bl.m = m;
- sd->bl.x = sd->ud.to_x = x;
- sd->bl.y = sd->ud.to_y = y;
-
- if (sd->status.guild_id > 0 && map[m].flag.gvg_castle) {
- // Increased guild castle regen [Valaris]
- struct guild_castle *gc = guild_mapindex2gc(sd->mapindex);
- if (gc && gc->guild_id == sd->status.guild_id)
- sd->regen.state.gc = 1;
- }
-
- if (sd->status.pet_id > 0 && sd->pd && sd->pd->pet.intimate > 0) {
- sd->pd->bl.m = m;
- sd->pd->bl.x = sd->pd->ud.to_x = x;
- sd->pd->bl.y = sd->pd->ud.to_y = y;
- sd->pd->ud.dir = sd->ud.dir;
- }
-
- if (merc_is_hom_active(sd->hd)) {
- sd->hd->bl.m = m;
- sd->hd->bl.x = sd->hd->ud.to_x = x;
- sd->hd->bl.y = sd->hd->ud.to_y = y;
- sd->hd->ud.dir = sd->ud.dir;
- }
-
- if (sd->md) {
- sd->md->bl.m = m;
- sd->md->bl.x = sd->md->ud.to_x = x;
- sd->md->bl.y = sd->md->ud.to_y = y;
- sd->md->ud.dir = sd->ud.dir;
- }
-
- return 0;
+int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y, clr_type clrtype)
+{
+ struct party_data *p;
+ int m;
+
+ nullpo_ret(sd);
+
+ if( !mapindex || !mapindex_id2name(mapindex) )
+ {
+ ShowDebug("pc_setpos: Passed mapindex(%d) is invalid!\n", mapindex);
+ return 1;
+ }
+
+ if( pc_isdead(sd) )
+ { //Revive dead people before warping them
+ pc_setstand(sd);
+ pc_setrestartvalue(sd,1);
+ }
+
+ m = map_mapindex2mapid(mapindex);
+ if( map[m].flag.src4instance && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id )
+ {
+ // Request the mapid of this src map into the instance of the party
+ int im = instance_map2imap(m, p->instance_id);
+ if( im < 0 )
+ ; // Player will enter the src map for instances
+ else
+ { // Changes destiny to the instance map, not the source map
+ m = im;
+ mapindex = map_id2index(m);
+ }
+ }
+
+ sd->state.changemap = (sd->mapindex != mapindex);
+ sd->state.warping = 1;
+ if( sd->state.changemap ) { // Misc map-changing settings
+ int i;
+ sd->state.pmap = sd->bl.m;
+ if (sd->sc.count) { // Cancel some map related stuff.
+ if (sd->sc.data[SC_JAILED])
+ return 1; //You may not get out!
+ status_change_end(&sd->bl, SC_BOSSMAPINFO, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_WARM, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_SUN_COMFORT, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_MOON_COMFORT, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_STAR_COMFORT, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_MIRACLE, INVALID_TIMER);
+ if (sd->sc.data[SC_KNOWLEDGE]) {
+ struct status_change_entry *sce = sd->sc.data[SC_KNOWLEDGE];
+ if (sce->timer != INVALID_TIMER)
+ delete_timer(sce->timer, status_change_timer);
+ sce->timer = add_timer(gettick() + skill_get_time(SG_KNOWLEDGE, sce->val1), status_change_timer, sd->bl.id, SC_KNOWLEDGE);
+ }
+ status_change_end(&sd->bl, SC_PROPERTYWALK, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_CLOAKING, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
+ }
+ for( i = 0; i < EQI_MAX; i++ ) {
+ if( sd->equip_index[ i ] >= 0 )
+ if( !pc_isequip( sd , sd->equip_index[ i ] ) )
+ pc_unequipitem( sd , sd->equip_index[ i ] , 2 );
+ }
+ if (battle_config.clear_unit_onwarp&BL_PC)
+ skill_clear_unitgroup(&sd->bl);
+ party_send_dot_remove(sd); //minimap dot fix [Kevin]
+ guild_send_dot_remove(sd);
+ bg_send_dot_remove(sd);
+ if (sd->regen.state.gc)
+ sd->regen.state.gc = 0;
+ // make sure vending is allowed here
+ if (sd->state.vending && map[m].flag.novending) {
+ clif_displaymessage (sd->fd, msg_txt(276)); // "You can't open a shop on this map"
+ vending_closevending(sd);
+ }
+ }
+
+ if( m < 0 )
+ {
+ uint32 ip;
+ uint16 port;
+ //if can't find any map-servers, just abort setting position.
+ if(!sd->mapindex || map_mapname2ipport(mapindex,&ip,&port))
+ return 2;
+
+ if (sd->npc_id)
+ npc_event_dequeue(sd);
+ npc_script_event(sd, NPCE_LOGOUT);
+ //remove from map, THEN change x/y coordinates
+ unit_remove_map_pc(sd,clrtype);
+ sd->mapindex = mapindex;
+ sd->bl.x=x;
+ sd->bl.y=y;
+ pc_clean_skilltree(sd);
+ chrif_save(sd,2);
+ chrif_changemapserver(sd, ip, (short)port);
+
+ //Free session data from this map server [Kevin]
+ unit_free_pc(sd);
+
+ return 0;
+ }
+
+ if( x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys )
+ {
+ ShowError("pc_setpos: attempt to place player %s (%d:%d) on invalid coordinates (%s-%d,%d)\n", sd->status.name, sd->status.account_id, sd->status.char_id, mapindex_id2name(mapindex),x,y);
+ x = y = 0; // make it random
+ }
+
+ if( x == 0 && y == 0 )
+ {// pick a random walkable cell
+ do {
+ x=rnd()%(map[m].xs-2)+1;
+ y=rnd()%(map[m].ys-2)+1;
+ } while(map_getcell(m,x,y,CELL_CHKNOPASS));
+ }
+
+ if (sd->state.vending && map_getcell(m,x,y,CELL_CHKNOVENDING)) {
+ clif_displaymessage (sd->fd, msg_txt(204)); // "You can't open a shop on this cell."
+ vending_closevending(sd);
+ }
+
+ if(sd->bl.prev != NULL){
+ unit_remove_map_pc(sd,clrtype);
+ clif_changemap(sd,map[m].index,x,y); // [MouseJstr]
+ } else if(sd->state.active)
+ //Tag player for rewarping after map-loading is done. [Skotlex]
+ sd->state.rewarp = 1;
+
+ sd->mapindex = mapindex;
+ sd->bl.m = m;
+ sd->bl.x = sd->ud.to_x = x;
+ sd->bl.y = sd->ud.to_y = y;
+
+ if( sd->status.guild_id > 0 && map[m].flag.gvg_castle )
+ { // Increased guild castle regen [Valaris]
+ struct guild_castle *gc = guild_mapindex2gc(sd->mapindex);
+ if(gc && gc->guild_id == sd->status.guild_id)
+ sd->regen.state.gc = 1;
+ }
+
+ if( sd->status.pet_id > 0 && sd->pd && sd->pd->pet.intimate > 0 )
+ {
+ sd->pd->bl.m = m;
+ sd->pd->bl.x = sd->pd->ud.to_x = x;
+ sd->pd->bl.y = sd->pd->ud.to_y = y;
+ sd->pd->ud.dir = sd->ud.dir;
+ }
+
+ if( merc_is_hom_active(sd->hd) )
+ {
+ sd->hd->bl.m = m;
+ sd->hd->bl.x = sd->hd->ud.to_x = x;
+ sd->hd->bl.y = sd->hd->ud.to_y = y;
+ sd->hd->ud.dir = sd->ud.dir;
+ }
+
+ if( sd->md )
+ {
+ sd->md->bl.m = m;
+ sd->md->bl.x = sd->md->ud.to_x = x;
+ sd->md->bl.y = sd->md->ud.to_y = y;
+ sd->md->ud.dir = sd->ud.dir;
+ }
+
+ return 0;
}
/*==========================================
* Warp player sd to random location on current map.
* May fail if no walkable cell found (1000 attempts).
* Return:
- * 0 = fail or FIXME success (from pc_setpos)
- * x(1|2) = fail
+ * 0 = fail or FIXME success (from pc_setpos)
+ * x(1|2) = fail
*------------------------------------------*/
int pc_randomwarp(struct map_session_data *sd, clr_type type)
{
- int x,y,i=0;
- int m;
+ int x,y,i=0;
+ int m;
- nullpo_ret(sd);
+ nullpo_ret(sd);
- m=sd->bl.m;
+ m=sd->bl.m;
- if (map[sd->bl.m].flag.noteleport) //Teleport forbidden
- return 0;
+ if (map[sd->bl.m].flag.noteleport) //Teleport forbidden
+ return 0;
- do {
- x=rnd()%(map[m].xs-2)+1;
- y=rnd()%(map[m].ys-2)+1;
- } while (map_getcell(m,x,y,CELL_CHKNOPASS) && (i++)<1000);
+ do{
+ x=rnd()%(map[m].xs-2)+1;
+ y=rnd()%(map[m].ys-2)+1;
+ }while(map_getcell(m,x,y,CELL_CHKNOPASS) && (i++)<1000 );
- if (i < 1000)
- return pc_setpos(sd,map[sd->bl.m].index,x,y,type);
+ if (i < 1000)
+ return pc_setpos(sd,map[sd->bl.m].index,x,y,type);
- return 0;
+ return 0;
}
/*==========================================
* Records a memo point at sd's current position
* pos - entry to replace, (-1: shift oldest entry out)
*------------------------------------------*/
-int pc_memo(struct map_session_data *sd, int pos)
+int pc_memo(struct map_session_data* sd, int pos)
{
- int skill;
+ int skill;
- nullpo_ret(sd);
+ nullpo_ret(sd);
- // check mapflags
- if (sd->bl.m >= 0 && (map[sd->bl.m].flag.nomemo || map[sd->bl.m].flag.nowarpto) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
- clif_skill_teleportmessage(sd, 1); // "Saved point cannot be memorized."
- return 0;
- }
+ // check mapflags
+ if( sd->bl.m >= 0 && (map[sd->bl.m].flag.nomemo || map[sd->bl.m].flag.nowarpto) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE) ) {
+ clif_skill_teleportmessage(sd, 1); // "Saved point cannot be memorized."
+ return 0;
+ }
- // check inputs
- if (pos < -1 || pos >= MAX_MEMOPOINTS)
- return 0; // invalid input
+ // check inputs
+ if( pos < -1 || pos >= MAX_MEMOPOINTS )
+ return 0; // invalid input
- // check required skill level
- skill = pc_checkskill(sd, AL_WARP);
- if (skill < 1) {
- clif_skill_memomessage(sd,2); // "You haven't learned Warp."
- return 0;
- }
- if (skill < 2 || skill - 2 < pos) {
- clif_skill_memomessage(sd,1); // "Skill Level is not high enough."
- return 0;
- }
+ // check required skill level
+ skill = pc_checkskill(sd, AL_WARP);
+ if( skill < 1 ) {
+ clif_skill_memomessage(sd,2); // "You haven't learned Warp."
+ return 0;
+ }
+ if( skill < 2 || skill - 2 < pos ) {
+ clif_skill_memomessage(sd,1); // "Skill Level is not high enough."
+ return 0;
+ }
- if (pos == -1) {
- int i;
- // prevent memo-ing the same map multiple times
- ARR_FIND(0, MAX_MEMOPOINTS, i, sd->status.memo_point[i].map == map_id2index(sd->bl.m));
- memmove(&sd->status.memo_point[1], &sd->status.memo_point[0], (min(i,MAX_MEMOPOINTS-1))*sizeof(struct point));
- pos = 0;
- }
+ if( pos == -1 )
+ {
+ int i;
+ // prevent memo-ing the same map multiple times
+ ARR_FIND( 0, MAX_MEMOPOINTS, i, sd->status.memo_point[i].map == map_id2index(sd->bl.m) );
+ memmove(&sd->status.memo_point[1], &sd->status.memo_point[0], (min(i,MAX_MEMOPOINTS-1))*sizeof(struct point));
+ pos = 0;
+ }
- sd->status.memo_point[pos].map = map_id2index(sd->bl.m);
- sd->status.memo_point[pos].x = sd->bl.x;
- sd->status.memo_point[pos].y = sd->bl.y;
+ sd->status.memo_point[pos].map = map_id2index(sd->bl.m);
+ sd->status.memo_point[pos].x = sd->bl.x;
+ sd->status.memo_point[pos].y = sd->bl.y;
- clif_skill_memomessage(sd, 0);
+ clif_skill_memomessage(sd, 0);
- return 1;
+ return 1;
}
//
@@ -4733,75 +4877,78 @@ int pc_memo(struct map_session_data *sd, int pos)
*------------------------------------------*/
int pc_checkskill(struct map_session_data *sd,int skill_id)
{
- if (sd == NULL) return 0;
- if (skill_id >= GD_SKILLBASE && skill_id < GD_MAX) {
- struct guild *g;
+ if(sd == NULL) return 0;
+ if( skill_id >= GD_SKILLBASE && skill_id < GD_MAX )
+ {
+ struct guild *g;
- if (sd->status.guild_id>0 && (g=guild_search(sd->status.guild_id))!=NULL)
- return guild_checkskill(g,skill_id);
- return 0;
- } else if (skill_id < 0 || skill_id >= ARRAYLENGTH(sd->status.skill)) {
- ShowError("pc_checkskill: Invalid skill id %d (char_id=%d).\n", skill_id, sd->status.char_id);
- return 0;
- }
+ if( sd->status.guild_id>0 && (g=guild_search(sd->status.guild_id))!=NULL)
+ return guild_checkskill(g,skill_id);
+ return 0;
+ }
+ else if( skill_id < 0 || skill_id >= ARRAYLENGTH(sd->status.skill) )
+ {
+ ShowError("pc_checkskill: Invalid skill id %d (char_id=%d).\n", skill_id, sd->status.char_id);
+ return 0;
+ }
- if (sd->status.skill[skill_id].id == skill_id)
- return (sd->status.skill[skill_id].lv);
+ if(sd->status.skill[skill_id].id == skill_id)
+ return (sd->status.skill[skill_id].lv);
- return 0;
+ return 0;
}
/*==========================================
* Chk if we still have the correct weapon to continue the skill (actually status)
* If not ending it
* Return
- * 0 - No status found or all done
+ * 0 - No status found or all done
*------------------------------------------*/
int pc_checkallowskill(struct map_session_data *sd)
{
- const enum sc_type scw_list[] = {
- SC_TWOHANDQUICKEN,
- SC_ONEHAND,
- SC_AURABLADE,
- SC_PARRYING,
- SC_SPEARQUICKEN,
- SC_ADRENALINE,
- SC_ADRENALINE2,
- SC_DANCING,
- SC_GATLINGFEVER,
- SC_FEARBREEZE
- };
- const enum sc_type scs_list[] = {
- SC_AUTOGUARD,
- SC_DEFENDER,
- SC_REFLECTSHIELD,
- SC_REFLECTDAMAGE
- };
- int i;
- nullpo_ret(sd);
-
- if (!sd->sc.count)
- return 0;
-
- for (i = 0; i < ARRAYLENGTH(scw_list); i++) {
- // Skills requiring specific weapon types
- if (scw_list[i] == SC_DANCING && !battle_config.dancing_weaponswitch_fix)
- continue;
- if (sd->sc.data[scw_list[i]] &&
- !pc_check_weapontype(sd,skill_get_weapontype(status_sc2skill(scw_list[i]))))
- status_change_end(&sd->bl, scw_list[i], INVALID_TIMER);
- }
-
- if (sd->sc.data[SC_SPURT] && sd->status.weapon)
- // Spurt requires bare hands (feet, in fact xD)
- status_change_end(&sd->bl, SC_SPURT, INVALID_TIMER);
-
- if (sd->status.shield <= 0) { // Skills requiring a shield
- for (i = 0; i < ARRAYLENGTH(scs_list); i++)
- if (sd->sc.data[scs_list[i]])
- status_change_end(&sd->bl, scs_list[i], INVALID_TIMER);
- }
- return 0;
+ const enum sc_type scw_list[] = {
+ SC_TWOHANDQUICKEN,
+ SC_ONEHAND,
+ SC_AURABLADE,
+ SC_PARRYING,
+ SC_SPEARQUICKEN,
+ SC_ADRENALINE,
+ SC_ADRENALINE2,
+ SC_DANCING,
+ SC_GATLINGFEVER,
+ SC_FEARBREEZE
+ };
+ const enum sc_type scs_list[] = {
+ SC_AUTOGUARD,
+ SC_DEFENDER,
+ SC_REFLECTSHIELD,
+ SC_REFLECTDAMAGE
+ };
+ int i;
+ nullpo_ret(sd);
+
+ if(!sd->sc.count)
+ return 0;
+
+ for (i = 0; i < ARRAYLENGTH(scw_list); i++)
+ { // Skills requiring specific weapon types
+ if( scw_list[i] == SC_DANCING && !battle_config.dancing_weaponswitch_fix )
+ continue;
+ if(sd->sc.data[scw_list[i]] &&
+ !pc_check_weapontype(sd,skill_get_weapontype(status_sc2skill(scw_list[i]))))
+ status_change_end(&sd->bl, scw_list[i], INVALID_TIMER);
+ }
+
+ if(sd->sc.data[SC_SPURT] && sd->status.weapon)
+ // Spurt requires bare hands (feet, in fact xD)
+ status_change_end(&sd->bl, SC_SPURT, INVALID_TIMER);
+
+ if(sd->status.shield <= 0) { // Skills requiring a shield
+ for (i = 0; i < ARRAYLENGTH(scs_list); i++)
+ if(sd->sc.data[scs_list[i]])
+ status_change_end(&sd->bl, scs_list[i], INVALID_TIMER);
+ }
+ return 0;
}
/*==========================================
@@ -4812,16 +4959,16 @@ int pc_checkallowskill(struct map_session_data *sd)
*------------------------------------------*/
int pc_checkequip(struct map_session_data *sd,int pos)
{
- int i;
+ int i;
- nullpo_retr(-1, sd);
+ nullpo_retr(-1, sd);
- for (i=0; i<EQI_MAX; i++) {
- if (pos & equip_pos[i])
- return sd->equip_index[i];
- }
+ for(i=0;i<EQI_MAX;i++){
+ if(pos & equip_pos[i])
+ return sd->equip_index[i];
+ }
- return -1;
+ return -1;
}
/*==========================================
@@ -4830,871 +4977,655 @@ int pc_checkequip(struct map_session_data *sd,int pos)
*------------------------------------------*/
int pc_jobid2mapid(unsigned short b_class)
{
- switch (b_class) {
- //Novice And 1-1 Jobs
- case JOB_NOVICE:
- return MAPID_NOVICE;
- case JOB_SWORDMAN:
- return MAPID_SWORDMAN;
- case JOB_MAGE:
- return MAPID_MAGE;
- case JOB_ARCHER:
- return MAPID_ARCHER;
- case JOB_ACOLYTE:
- return MAPID_ACOLYTE;
- case JOB_MERCHANT:
- return MAPID_MERCHANT;
- case JOB_THIEF:
- return MAPID_THIEF;
- case JOB_TAEKWON:
- return MAPID_TAEKWON;
- case JOB_WEDDING:
- return MAPID_WEDDING;
- case JOB_GUNSLINGER:
- return MAPID_GUNSLINGER;
- case JOB_NINJA:
- return MAPID_NINJA;
- case JOB_XMAS:
- return MAPID_XMAS;
- case JOB_SUMMER:
- return MAPID_SUMMER;
- case JOB_GANGSI:
- return MAPID_GANGSI;
- //2-1 Jobs
- case JOB_SUPER_NOVICE:
- return MAPID_SUPER_NOVICE;
- case JOB_KNIGHT:
- return MAPID_KNIGHT;
- case JOB_WIZARD:
- return MAPID_WIZARD;
- case JOB_HUNTER:
- return MAPID_HUNTER;
- case JOB_PRIEST:
- return MAPID_PRIEST;
- case JOB_BLACKSMITH:
- return MAPID_BLACKSMITH;
- case JOB_ASSASSIN:
- return MAPID_ASSASSIN;
- case JOB_STAR_GLADIATOR:
- return MAPID_STAR_GLADIATOR;
- case JOB_KAGEROU:
- case JOB_OBORO:
- return MAPID_KAGEROUOBORO;
- case JOB_DEATH_KNIGHT:
- return MAPID_DEATH_KNIGHT;
- //2-2 Jobs
- case JOB_CRUSADER:
- return MAPID_CRUSADER;
- case JOB_SAGE:
- return MAPID_SAGE;
- case JOB_BARD:
- case JOB_DANCER:
- return MAPID_BARDDANCER;
- case JOB_MONK:
- return MAPID_MONK;
- case JOB_ALCHEMIST:
- return MAPID_ALCHEMIST;
- case JOB_ROGUE:
- return MAPID_ROGUE;
- case JOB_SOUL_LINKER:
- return MAPID_SOUL_LINKER;
- case JOB_DARK_COLLECTOR:
- return MAPID_DARK_COLLECTOR;
- //Trans Novice And Trans 1-1 Jobs
- case JOB_NOVICE_HIGH:
- return MAPID_NOVICE_HIGH;
- case JOB_SWORDMAN_HIGH:
- return MAPID_SWORDMAN_HIGH;
- case JOB_MAGE_HIGH:
- return MAPID_MAGE_HIGH;
- case JOB_ARCHER_HIGH:
- return MAPID_ARCHER_HIGH;
- case JOB_ACOLYTE_HIGH:
- return MAPID_ACOLYTE_HIGH;
- case JOB_MERCHANT_HIGH:
- return MAPID_MERCHANT_HIGH;
- case JOB_THIEF_HIGH:
- return MAPID_THIEF_HIGH;
- //Trans 2-1 Jobs
- case JOB_LORD_KNIGHT:
- return MAPID_LORD_KNIGHT;
- case JOB_HIGH_WIZARD:
- return MAPID_HIGH_WIZARD;
- case JOB_SNIPER:
- return MAPID_SNIPER;
- case JOB_HIGH_PRIEST:
- return MAPID_HIGH_PRIEST;
- case JOB_WHITESMITH:
- return MAPID_WHITESMITH;
- case JOB_ASSASSIN_CROSS:
- return MAPID_ASSASSIN_CROSS;
- //Trans 2-2 Jobs
- case JOB_PALADIN:
- return MAPID_PALADIN;
- case JOB_PROFESSOR:
- return MAPID_PROFESSOR;
- case JOB_CLOWN:
- case JOB_GYPSY:
- return MAPID_CLOWNGYPSY;
- case JOB_CHAMPION:
- return MAPID_CHAMPION;
- case JOB_CREATOR:
- return MAPID_CREATOR;
- case JOB_STALKER:
- return MAPID_STALKER;
- //Baby Novice And Baby 1-1 Jobs
- case JOB_BABY:
- return MAPID_BABY;
- case JOB_BABY_SWORDMAN:
- return MAPID_BABY_SWORDMAN;
- case JOB_BABY_MAGE:
- return MAPID_BABY_MAGE;
- case JOB_BABY_ARCHER:
- return MAPID_BABY_ARCHER;
- case JOB_BABY_ACOLYTE:
- return MAPID_BABY_ACOLYTE;
- case JOB_BABY_MERCHANT:
- return MAPID_BABY_MERCHANT;
- case JOB_BABY_THIEF:
- return MAPID_BABY_THIEF;
- //Baby 2-1 Jobs
- case JOB_SUPER_BABY:
- return MAPID_SUPER_BABY;
- case JOB_BABY_KNIGHT:
- return MAPID_BABY_KNIGHT;
- case JOB_BABY_WIZARD:
- return MAPID_BABY_WIZARD;
- case JOB_BABY_HUNTER:
- return MAPID_BABY_HUNTER;
- case JOB_BABY_PRIEST:
- return MAPID_BABY_PRIEST;
- case JOB_BABY_BLACKSMITH:
- return MAPID_BABY_BLACKSMITH;
- case JOB_BABY_ASSASSIN:
- return MAPID_BABY_ASSASSIN;
- //Baby 2-2 Jobs
- case JOB_BABY_CRUSADER:
- return MAPID_BABY_CRUSADER;
- case JOB_BABY_SAGE:
- return MAPID_BABY_SAGE;
- case JOB_BABY_BARD:
- case JOB_BABY_DANCER:
- return MAPID_BABY_BARDDANCER;
- case JOB_BABY_MONK:
- return MAPID_BABY_MONK;
- case JOB_BABY_ALCHEMIST:
- return MAPID_BABY_ALCHEMIST;
- case JOB_BABY_ROGUE:
- return MAPID_BABY_ROGUE;
- //3-1 Jobs
- case JOB_SUPER_NOVICE_E:
- return MAPID_SUPER_NOVICE_E;
- case JOB_RUNE_KNIGHT:
- return MAPID_RUNE_KNIGHT;
- case JOB_WARLOCK:
- return MAPID_WARLOCK;
- case JOB_RANGER:
- return MAPID_RANGER;
- case JOB_ARCH_BISHOP:
- return MAPID_ARCH_BISHOP;
- case JOB_MECHANIC:
- return MAPID_MECHANIC;
- case JOB_GUILLOTINE_CROSS:
- return MAPID_GUILLOTINE_CROSS;
- //3-2 Jobs
- case JOB_ROYAL_GUARD:
- return MAPID_ROYAL_GUARD;
- case JOB_SORCERER:
- return MAPID_SORCERER;
- case JOB_MINSTREL:
- case JOB_WANDERER:
- return MAPID_MINSTRELWANDERER;
- case JOB_SURA:
- return MAPID_SURA;
- case JOB_GENETIC:
- return MAPID_GENETIC;
- case JOB_SHADOW_CHASER:
- return MAPID_SHADOW_CHASER;
- //Trans 3-1 Jobs
- case JOB_RUNE_KNIGHT_T:
- return MAPID_RUNE_KNIGHT_T;
- case JOB_WARLOCK_T:
- return MAPID_WARLOCK_T;
- case JOB_RANGER_T:
- return MAPID_RANGER_T;
- case JOB_ARCH_BISHOP_T:
- return MAPID_ARCH_BISHOP_T;
- case JOB_MECHANIC_T:
- return MAPID_MECHANIC_T;
- case JOB_GUILLOTINE_CROSS_T:
- return MAPID_GUILLOTINE_CROSS_T;
- //Trans 3-2 Jobs
- case JOB_ROYAL_GUARD_T:
- return MAPID_ROYAL_GUARD_T;
- case JOB_SORCERER_T:
- return MAPID_SORCERER_T;
- case JOB_MINSTREL_T:
- case JOB_WANDERER_T:
- return MAPID_MINSTRELWANDERER_T;
- case JOB_SURA_T:
- return MAPID_SURA_T;
- case JOB_GENETIC_T:
- return MAPID_GENETIC_T;
- case JOB_SHADOW_CHASER_T:
- return MAPID_SHADOW_CHASER_T;
- //Baby 3-1 Jobs
- case JOB_SUPER_BABY_E:
- return MAPID_SUPER_BABY_E;
- case JOB_BABY_RUNE:
- return MAPID_BABY_RUNE;
- case JOB_BABY_WARLOCK:
- return MAPID_BABY_WARLOCK;
- case JOB_BABY_RANGER:
- return MAPID_BABY_RANGER;
- case JOB_BABY_BISHOP:
- return MAPID_BABY_BISHOP;
- case JOB_BABY_MECHANIC:
- return MAPID_BABY_MECHANIC;
- case JOB_BABY_CROSS:
- return MAPID_BABY_CROSS;
- //Baby 3-2 Jobs
- case JOB_BABY_GUARD:
- return MAPID_BABY_GUARD;
- case JOB_BABY_SORCERER:
- return MAPID_BABY_SORCERER;
- case JOB_BABY_MINSTREL:
- case JOB_BABY_WANDERER:
- return MAPID_BABY_MINSTRELWANDERER;
- case JOB_BABY_SURA:
- return MAPID_BABY_SURA;
- case JOB_BABY_GENETIC:
- return MAPID_BABY_GENETIC;
- case JOB_BABY_CHASER:
- return MAPID_BABY_CHASER;
- default:
- return -1;
- }
+ switch(b_class)
+ {
+ //Novice And 1-1 Jobs
+ case JOB_NOVICE: return MAPID_NOVICE;
+ case JOB_SWORDMAN: return MAPID_SWORDMAN;
+ case JOB_MAGE: return MAPID_MAGE;
+ case JOB_ARCHER: return MAPID_ARCHER;
+ case JOB_ACOLYTE: return MAPID_ACOLYTE;
+ case JOB_MERCHANT: return MAPID_MERCHANT;
+ case JOB_THIEF: return MAPID_THIEF;
+ case JOB_TAEKWON: return MAPID_TAEKWON;
+ case JOB_WEDDING: return MAPID_WEDDING;
+ case JOB_GUNSLINGER: return MAPID_GUNSLINGER;
+ case JOB_NINJA: return MAPID_NINJA;
+ case JOB_XMAS: return MAPID_XMAS;
+ case JOB_SUMMER: return MAPID_SUMMER;
+ case JOB_GANGSI: return MAPID_GANGSI;
+ //2-1 Jobs
+ case JOB_SUPER_NOVICE: return MAPID_SUPER_NOVICE;
+ case JOB_KNIGHT: return MAPID_KNIGHT;
+ case JOB_WIZARD: return MAPID_WIZARD;
+ case JOB_HUNTER: return MAPID_HUNTER;
+ case JOB_PRIEST: return MAPID_PRIEST;
+ case JOB_BLACKSMITH: return MAPID_BLACKSMITH;
+ case JOB_ASSASSIN: return MAPID_ASSASSIN;
+ case JOB_STAR_GLADIATOR: return MAPID_STAR_GLADIATOR;
+ case JOB_KAGEROU:
+ case JOB_OBORO: return MAPID_KAGEROUOBORO;
+ case JOB_DEATH_KNIGHT: return MAPID_DEATH_KNIGHT;
+ //2-2 Jobs
+ case JOB_CRUSADER: return MAPID_CRUSADER;
+ case JOB_SAGE: return MAPID_SAGE;
+ case JOB_BARD:
+ case JOB_DANCER: return MAPID_BARDDANCER;
+ case JOB_MONK: return MAPID_MONK;
+ case JOB_ALCHEMIST: return MAPID_ALCHEMIST;
+ case JOB_ROGUE: return MAPID_ROGUE;
+ case JOB_SOUL_LINKER: return MAPID_SOUL_LINKER;
+ case JOB_DARK_COLLECTOR: return MAPID_DARK_COLLECTOR;
+ //Trans Novice And Trans 1-1 Jobs
+ case JOB_NOVICE_HIGH: return MAPID_NOVICE_HIGH;
+ case JOB_SWORDMAN_HIGH: return MAPID_SWORDMAN_HIGH;
+ case JOB_MAGE_HIGH: return MAPID_MAGE_HIGH;
+ case JOB_ARCHER_HIGH: return MAPID_ARCHER_HIGH;
+ case JOB_ACOLYTE_HIGH: return MAPID_ACOLYTE_HIGH;
+ case JOB_MERCHANT_HIGH: return MAPID_MERCHANT_HIGH;
+ case JOB_THIEF_HIGH: return MAPID_THIEF_HIGH;
+ //Trans 2-1 Jobs
+ case JOB_LORD_KNIGHT: return MAPID_LORD_KNIGHT;
+ case JOB_HIGH_WIZARD: return MAPID_HIGH_WIZARD;
+ case JOB_SNIPER: return MAPID_SNIPER;
+ case JOB_HIGH_PRIEST: return MAPID_HIGH_PRIEST;
+ case JOB_WHITESMITH: return MAPID_WHITESMITH;
+ case JOB_ASSASSIN_CROSS: return MAPID_ASSASSIN_CROSS;
+ //Trans 2-2 Jobs
+ case JOB_PALADIN: return MAPID_PALADIN;
+ case JOB_PROFESSOR: return MAPID_PROFESSOR;
+ case JOB_CLOWN:
+ case JOB_GYPSY: return MAPID_CLOWNGYPSY;
+ case JOB_CHAMPION: return MAPID_CHAMPION;
+ case JOB_CREATOR: return MAPID_CREATOR;
+ case JOB_STALKER: return MAPID_STALKER;
+ //Baby Novice And Baby 1-1 Jobs
+ case JOB_BABY: return MAPID_BABY;
+ case JOB_BABY_SWORDMAN: return MAPID_BABY_SWORDMAN;
+ case JOB_BABY_MAGE: return MAPID_BABY_MAGE;
+ case JOB_BABY_ARCHER: return MAPID_BABY_ARCHER;
+ case JOB_BABY_ACOLYTE: return MAPID_BABY_ACOLYTE;
+ case JOB_BABY_MERCHANT: return MAPID_BABY_MERCHANT;
+ case JOB_BABY_THIEF: return MAPID_BABY_THIEF;
+ //Baby 2-1 Jobs
+ case JOB_SUPER_BABY: return MAPID_SUPER_BABY;
+ case JOB_BABY_KNIGHT: return MAPID_BABY_KNIGHT;
+ case JOB_BABY_WIZARD: return MAPID_BABY_WIZARD;
+ case JOB_BABY_HUNTER: return MAPID_BABY_HUNTER;
+ case JOB_BABY_PRIEST: return MAPID_BABY_PRIEST;
+ case JOB_BABY_BLACKSMITH: return MAPID_BABY_BLACKSMITH;
+ case JOB_BABY_ASSASSIN: return MAPID_BABY_ASSASSIN;
+ //Baby 2-2 Jobs
+ case JOB_BABY_CRUSADER: return MAPID_BABY_CRUSADER;
+ case JOB_BABY_SAGE: return MAPID_BABY_SAGE;
+ case JOB_BABY_BARD:
+ case JOB_BABY_DANCER: return MAPID_BABY_BARDDANCER;
+ case JOB_BABY_MONK: return MAPID_BABY_MONK;
+ case JOB_BABY_ALCHEMIST: return MAPID_BABY_ALCHEMIST;
+ case JOB_BABY_ROGUE: return MAPID_BABY_ROGUE;
+ //3-1 Jobs
+ case JOB_SUPER_NOVICE_E: return MAPID_SUPER_NOVICE_E;
+ case JOB_RUNE_KNIGHT: return MAPID_RUNE_KNIGHT;
+ case JOB_WARLOCK: return MAPID_WARLOCK;
+ case JOB_RANGER: return MAPID_RANGER;
+ case JOB_ARCH_BISHOP: return MAPID_ARCH_BISHOP;
+ case JOB_MECHANIC: return MAPID_MECHANIC;
+ case JOB_GUILLOTINE_CROSS: return MAPID_GUILLOTINE_CROSS;
+ //3-2 Jobs
+ case JOB_ROYAL_GUARD: return MAPID_ROYAL_GUARD;
+ case JOB_SORCERER: return MAPID_SORCERER;
+ case JOB_MINSTREL:
+ case JOB_WANDERER: return MAPID_MINSTRELWANDERER;
+ case JOB_SURA: return MAPID_SURA;
+ case JOB_GENETIC: return MAPID_GENETIC;
+ case JOB_SHADOW_CHASER: return MAPID_SHADOW_CHASER;
+ //Trans 3-1 Jobs
+ case JOB_RUNE_KNIGHT_T: return MAPID_RUNE_KNIGHT_T;
+ case JOB_WARLOCK_T: return MAPID_WARLOCK_T;
+ case JOB_RANGER_T: return MAPID_RANGER_T;
+ case JOB_ARCH_BISHOP_T: return MAPID_ARCH_BISHOP_T;
+ case JOB_MECHANIC_T: return MAPID_MECHANIC_T;
+ case JOB_GUILLOTINE_CROSS_T: return MAPID_GUILLOTINE_CROSS_T;
+ //Trans 3-2 Jobs
+ case JOB_ROYAL_GUARD_T: return MAPID_ROYAL_GUARD_T;
+ case JOB_SORCERER_T: return MAPID_SORCERER_T;
+ case JOB_MINSTREL_T:
+ case JOB_WANDERER_T: return MAPID_MINSTRELWANDERER_T;
+ case JOB_SURA_T: return MAPID_SURA_T;
+ case JOB_GENETIC_T: return MAPID_GENETIC_T;
+ case JOB_SHADOW_CHASER_T: return MAPID_SHADOW_CHASER_T;
+ //Baby 3-1 Jobs
+ case JOB_SUPER_BABY_E: return MAPID_SUPER_BABY_E;
+ case JOB_BABY_RUNE: return MAPID_BABY_RUNE;
+ case JOB_BABY_WARLOCK: return MAPID_BABY_WARLOCK;
+ case JOB_BABY_RANGER: return MAPID_BABY_RANGER;
+ case JOB_BABY_BISHOP: return MAPID_BABY_BISHOP;
+ case JOB_BABY_MECHANIC: return MAPID_BABY_MECHANIC;
+ case JOB_BABY_CROSS: return MAPID_BABY_CROSS;
+ //Baby 3-2 Jobs
+ case JOB_BABY_GUARD: return MAPID_BABY_GUARD;
+ case JOB_BABY_SORCERER: return MAPID_BABY_SORCERER;
+ case JOB_BABY_MINSTREL:
+ case JOB_BABY_WANDERER: return MAPID_BABY_MINSTRELWANDERER;
+ case JOB_BABY_SURA: return MAPID_BABY_SURA;
+ case JOB_BABY_GENETIC: return MAPID_BABY_GENETIC;
+ case JOB_BABY_CHASER: return MAPID_BABY_CHASER;
+ default:
+ return -1;
+ }
}
//Reverts the map-style class id to the client-style one.
int pc_mapid2jobid(unsigned short class_, int sex)
{
- switch (class_) {
- //Novice And 1-1 Jobs
- case MAPID_NOVICE:
- return JOB_NOVICE;
- case MAPID_SWORDMAN:
- return JOB_SWORDMAN;
- case MAPID_MAGE:
- return JOB_MAGE;
- case MAPID_ARCHER:
- return JOB_ARCHER;
- case MAPID_ACOLYTE:
- return JOB_ACOLYTE;
- case MAPID_MERCHANT:
- return JOB_MERCHANT;
- case MAPID_THIEF:
- return JOB_THIEF;
- case MAPID_TAEKWON:
- return JOB_TAEKWON;
- case MAPID_WEDDING:
- return JOB_WEDDING;
- case MAPID_GUNSLINGER:
- return JOB_GUNSLINGER;
- case MAPID_NINJA:
- return JOB_NINJA;
- case MAPID_XMAS:
- return JOB_XMAS;
- case MAPID_SUMMER:
- return JOB_SUMMER;
- case MAPID_GANGSI:
- return JOB_GANGSI;
- //2-1 Jobs
- case MAPID_SUPER_NOVICE:
- return JOB_SUPER_NOVICE;
- case MAPID_KNIGHT:
- return JOB_KNIGHT;
- case MAPID_WIZARD:
- return JOB_WIZARD;
- case MAPID_HUNTER:
- return JOB_HUNTER;
- case MAPID_PRIEST:
- return JOB_PRIEST;
- case MAPID_BLACKSMITH:
- return JOB_BLACKSMITH;
- case MAPID_ASSASSIN:
- return JOB_ASSASSIN;
- case MAPID_STAR_GLADIATOR:
- return JOB_STAR_GLADIATOR;
- case MAPID_KAGEROUOBORO:
- return sex?JOB_KAGEROU:JOB_OBORO;
- case MAPID_DEATH_KNIGHT:
- return JOB_DEATH_KNIGHT;
- //2-2 Jobs
- case MAPID_CRUSADER:
- return JOB_CRUSADER;
- case MAPID_SAGE:
- return JOB_SAGE;
- case MAPID_BARDDANCER:
- return sex?JOB_BARD:JOB_DANCER;
- case MAPID_MONK:
- return JOB_MONK;
- case MAPID_ALCHEMIST:
- return JOB_ALCHEMIST;
- case MAPID_ROGUE:
- return JOB_ROGUE;
- case MAPID_SOUL_LINKER:
- return JOB_SOUL_LINKER;
- case MAPID_DARK_COLLECTOR:
- return JOB_DARK_COLLECTOR;
- //Trans Novice And Trans 2-1 Jobs
- case MAPID_NOVICE_HIGH:
- return JOB_NOVICE_HIGH;
- case MAPID_SWORDMAN_HIGH:
- return JOB_SWORDMAN_HIGH;
- case MAPID_MAGE_HIGH:
- return JOB_MAGE_HIGH;
- case MAPID_ARCHER_HIGH:
- return JOB_ARCHER_HIGH;
- case MAPID_ACOLYTE_HIGH:
- return JOB_ACOLYTE_HIGH;
- case MAPID_MERCHANT_HIGH:
- return JOB_MERCHANT_HIGH;
- case MAPID_THIEF_HIGH:
- return JOB_THIEF_HIGH;
- //Trans 2-1 Jobs
- case MAPID_LORD_KNIGHT:
- return JOB_LORD_KNIGHT;
- case MAPID_HIGH_WIZARD:
- return JOB_HIGH_WIZARD;
- case MAPID_SNIPER:
- return JOB_SNIPER;
- case MAPID_HIGH_PRIEST:
- return JOB_HIGH_PRIEST;
- case MAPID_WHITESMITH:
- return JOB_WHITESMITH;
- case MAPID_ASSASSIN_CROSS:
- return JOB_ASSASSIN_CROSS;
- //Trans 2-2 Jobs
- case MAPID_PALADIN:
- return JOB_PALADIN;
- case MAPID_PROFESSOR:
- return JOB_PROFESSOR;
- case MAPID_CLOWNGYPSY:
- return sex?JOB_CLOWN:JOB_GYPSY;
- case MAPID_CHAMPION:
- return JOB_CHAMPION;
- case MAPID_CREATOR:
- return JOB_CREATOR;
- case MAPID_STALKER:
- return JOB_STALKER;
- //Baby Novice And Baby 1-1 Jobs
- case MAPID_BABY:
- return JOB_BABY;
- case MAPID_BABY_SWORDMAN:
- return JOB_BABY_SWORDMAN;
- case MAPID_BABY_MAGE:
- return JOB_BABY_MAGE;
- case MAPID_BABY_ARCHER:
- return JOB_BABY_ARCHER;
- case MAPID_BABY_ACOLYTE:
- return JOB_BABY_ACOLYTE;
- case MAPID_BABY_MERCHANT:
- return JOB_BABY_MERCHANT;
- case MAPID_BABY_THIEF:
- return JOB_BABY_THIEF;
- //Baby 2-1 Jobs
- case MAPID_SUPER_BABY:
- return JOB_SUPER_BABY;
- case MAPID_BABY_KNIGHT:
- return JOB_BABY_KNIGHT;
- case MAPID_BABY_WIZARD:
- return JOB_BABY_WIZARD;
- case MAPID_BABY_HUNTER:
- return JOB_BABY_HUNTER;
- case MAPID_BABY_PRIEST:
- return JOB_BABY_PRIEST;
- case MAPID_BABY_BLACKSMITH:
- return JOB_BABY_BLACKSMITH;
- case MAPID_BABY_ASSASSIN:
- return JOB_BABY_ASSASSIN;
- //Baby 2-2 Jobs
- case MAPID_BABY_CRUSADER:
- return JOB_BABY_CRUSADER;
- case MAPID_BABY_SAGE:
- return JOB_BABY_SAGE;
- case MAPID_BABY_BARDDANCER:
- return sex?JOB_BABY_BARD:JOB_BABY_DANCER;
- case MAPID_BABY_MONK:
- return JOB_BABY_MONK;
- case MAPID_BABY_ALCHEMIST:
- return JOB_BABY_ALCHEMIST;
- case MAPID_BABY_ROGUE:
- return JOB_BABY_ROGUE;
- //3-1 Jobs
- case MAPID_SUPER_NOVICE_E:
- return JOB_SUPER_NOVICE_E;
- case MAPID_RUNE_KNIGHT:
- return JOB_RUNE_KNIGHT;
- case MAPID_WARLOCK:
- return JOB_WARLOCK;
- case MAPID_RANGER:
- return JOB_RANGER;
- case MAPID_ARCH_BISHOP:
- return JOB_ARCH_BISHOP;
- case MAPID_MECHANIC:
- return JOB_MECHANIC;
- case MAPID_GUILLOTINE_CROSS:
- return JOB_GUILLOTINE_CROSS;
- //3-2 Jobs
- case MAPID_ROYAL_GUARD:
- return JOB_ROYAL_GUARD;
- case MAPID_SORCERER:
- return JOB_SORCERER;
- case MAPID_MINSTRELWANDERER:
- return sex?JOB_MINSTREL:JOB_WANDERER;
- case MAPID_SURA:
- return JOB_SURA;
- case MAPID_GENETIC:
- return JOB_GENETIC;
- case MAPID_SHADOW_CHASER:
- return JOB_SHADOW_CHASER;
- //Trans 3-1 Jobs
- case MAPID_RUNE_KNIGHT_T:
- return JOB_RUNE_KNIGHT_T;
- case MAPID_WARLOCK_T:
- return JOB_WARLOCK_T;
- case MAPID_RANGER_T:
- return JOB_RANGER_T;
- case MAPID_ARCH_BISHOP_T:
- return JOB_ARCH_BISHOP_T;
- case MAPID_MECHANIC_T:
- return JOB_MECHANIC_T;
- case MAPID_GUILLOTINE_CROSS_T:
- return JOB_GUILLOTINE_CROSS_T;
- //Trans 3-2 Jobs
- case MAPID_ROYAL_GUARD_T:
- return JOB_ROYAL_GUARD_T;
- case MAPID_SORCERER_T:
- return JOB_SORCERER_T;
- case MAPID_MINSTRELWANDERER_T:
- return sex?JOB_MINSTREL_T:JOB_WANDERER_T;
- case MAPID_SURA_T:
- return JOB_SURA_T;
- case MAPID_GENETIC_T:
- return JOB_GENETIC_T;
- case MAPID_SHADOW_CHASER_T:
- return JOB_SHADOW_CHASER_T;
- //Baby 3-1 Jobs
- case MAPID_SUPER_BABY_E:
- return JOB_SUPER_BABY_E;
- case MAPID_BABY_RUNE:
- return JOB_BABY_RUNE;
- case MAPID_BABY_WARLOCK:
- return JOB_BABY_WARLOCK;
- case MAPID_BABY_RANGER:
- return JOB_BABY_RANGER;
- case MAPID_BABY_BISHOP:
- return JOB_BABY_BISHOP;
- case MAPID_BABY_MECHANIC:
- return JOB_BABY_MECHANIC;
- case MAPID_BABY_CROSS:
- return JOB_BABY_CROSS;
- //Baby 3-2 Jobs
- case MAPID_BABY_GUARD:
- return JOB_BABY_GUARD;
- case MAPID_BABY_SORCERER:
- return JOB_BABY_SORCERER;
- case MAPID_BABY_MINSTRELWANDERER:
- return sex?JOB_BABY_MINSTREL:JOB_BABY_WANDERER;
- case MAPID_BABY_SURA:
- return JOB_BABY_SURA;
- case MAPID_BABY_GENETIC:
- return JOB_BABY_GENETIC;
- case MAPID_BABY_CHASER:
- return JOB_BABY_CHASER;
- default:
- return -1;
- }
+ switch(class_)
+ {
+ //Novice And 1-1 Jobs
+ case MAPID_NOVICE: return JOB_NOVICE;
+ case MAPID_SWORDMAN: return JOB_SWORDMAN;
+ case MAPID_MAGE: return JOB_MAGE;
+ case MAPID_ARCHER: return JOB_ARCHER;
+ case MAPID_ACOLYTE: return JOB_ACOLYTE;
+ case MAPID_MERCHANT: return JOB_MERCHANT;
+ case MAPID_THIEF: return JOB_THIEF;
+ case MAPID_TAEKWON: return JOB_TAEKWON;
+ case MAPID_WEDDING: return JOB_WEDDING;
+ case MAPID_GUNSLINGER: return JOB_GUNSLINGER;
+ case MAPID_NINJA: return JOB_NINJA;
+ case MAPID_XMAS: return JOB_XMAS;
+ case MAPID_SUMMER: return JOB_SUMMER;
+ case MAPID_GANGSI: return JOB_GANGSI;
+ //2-1 Jobs
+ case MAPID_SUPER_NOVICE: return JOB_SUPER_NOVICE;
+ case MAPID_KNIGHT: return JOB_KNIGHT;
+ case MAPID_WIZARD: return JOB_WIZARD;
+ case MAPID_HUNTER: return JOB_HUNTER;
+ case MAPID_PRIEST: return JOB_PRIEST;
+ case MAPID_BLACKSMITH: return JOB_BLACKSMITH;
+ case MAPID_ASSASSIN: return JOB_ASSASSIN;
+ case MAPID_STAR_GLADIATOR: return JOB_STAR_GLADIATOR;
+ case MAPID_KAGEROUOBORO: return sex?JOB_KAGEROU:JOB_OBORO;
+ case MAPID_DEATH_KNIGHT: return JOB_DEATH_KNIGHT;
+ //2-2 Jobs
+ case MAPID_CRUSADER: return JOB_CRUSADER;
+ case MAPID_SAGE: return JOB_SAGE;
+ case MAPID_BARDDANCER: return sex?JOB_BARD:JOB_DANCER;
+ case MAPID_MONK: return JOB_MONK;
+ case MAPID_ALCHEMIST: return JOB_ALCHEMIST;
+ case MAPID_ROGUE: return JOB_ROGUE;
+ case MAPID_SOUL_LINKER: return JOB_SOUL_LINKER;
+ case MAPID_DARK_COLLECTOR: return JOB_DARK_COLLECTOR;
+ //Trans Novice And Trans 2-1 Jobs
+ case MAPID_NOVICE_HIGH: return JOB_NOVICE_HIGH;
+ case MAPID_SWORDMAN_HIGH: return JOB_SWORDMAN_HIGH;
+ case MAPID_MAGE_HIGH: return JOB_MAGE_HIGH;
+ case MAPID_ARCHER_HIGH: return JOB_ARCHER_HIGH;
+ case MAPID_ACOLYTE_HIGH: return JOB_ACOLYTE_HIGH;
+ case MAPID_MERCHANT_HIGH: return JOB_MERCHANT_HIGH;
+ case MAPID_THIEF_HIGH: return JOB_THIEF_HIGH;
+ //Trans 2-1 Jobs
+ case MAPID_LORD_KNIGHT: return JOB_LORD_KNIGHT;
+ case MAPID_HIGH_WIZARD: return JOB_HIGH_WIZARD;
+ case MAPID_SNIPER: return JOB_SNIPER;
+ case MAPID_HIGH_PRIEST: return JOB_HIGH_PRIEST;
+ case MAPID_WHITESMITH: return JOB_WHITESMITH;
+ case MAPID_ASSASSIN_CROSS: return JOB_ASSASSIN_CROSS;
+ //Trans 2-2 Jobs
+ case MAPID_PALADIN: return JOB_PALADIN;
+ case MAPID_PROFESSOR: return JOB_PROFESSOR;
+ case MAPID_CLOWNGYPSY: return sex?JOB_CLOWN:JOB_GYPSY;
+ case MAPID_CHAMPION: return JOB_CHAMPION;
+ case MAPID_CREATOR: return JOB_CREATOR;
+ case MAPID_STALKER: return JOB_STALKER;
+ //Baby Novice And Baby 1-1 Jobs
+ case MAPID_BABY: return JOB_BABY;
+ case MAPID_BABY_SWORDMAN: return JOB_BABY_SWORDMAN;
+ case MAPID_BABY_MAGE: return JOB_BABY_MAGE;
+ case MAPID_BABY_ARCHER: return JOB_BABY_ARCHER;
+ case MAPID_BABY_ACOLYTE: return JOB_BABY_ACOLYTE;
+ case MAPID_BABY_MERCHANT: return JOB_BABY_MERCHANT;
+ case MAPID_BABY_THIEF: return JOB_BABY_THIEF;
+ //Baby 2-1 Jobs
+ case MAPID_SUPER_BABY: return JOB_SUPER_BABY;
+ case MAPID_BABY_KNIGHT: return JOB_BABY_KNIGHT;
+ case MAPID_BABY_WIZARD: return JOB_BABY_WIZARD;
+ case MAPID_BABY_HUNTER: return JOB_BABY_HUNTER;
+ case MAPID_BABY_PRIEST: return JOB_BABY_PRIEST;
+ case MAPID_BABY_BLACKSMITH: return JOB_BABY_BLACKSMITH;
+ case MAPID_BABY_ASSASSIN: return JOB_BABY_ASSASSIN;
+ //Baby 2-2 Jobs
+ case MAPID_BABY_CRUSADER: return JOB_BABY_CRUSADER;
+ case MAPID_BABY_SAGE: return JOB_BABY_SAGE;
+ case MAPID_BABY_BARDDANCER: return sex?JOB_BABY_BARD:JOB_BABY_DANCER;
+ case MAPID_BABY_MONK: return JOB_BABY_MONK;
+ case MAPID_BABY_ALCHEMIST: return JOB_BABY_ALCHEMIST;
+ case MAPID_BABY_ROGUE: return JOB_BABY_ROGUE;
+ //3-1 Jobs
+ case MAPID_SUPER_NOVICE_E: return JOB_SUPER_NOVICE_E;
+ case MAPID_RUNE_KNIGHT: return JOB_RUNE_KNIGHT;
+ case MAPID_WARLOCK: return JOB_WARLOCK;
+ case MAPID_RANGER: return JOB_RANGER;
+ case MAPID_ARCH_BISHOP: return JOB_ARCH_BISHOP;
+ case MAPID_MECHANIC: return JOB_MECHANIC;
+ case MAPID_GUILLOTINE_CROSS: return JOB_GUILLOTINE_CROSS;
+ //3-2 Jobs
+ case MAPID_ROYAL_GUARD: return JOB_ROYAL_GUARD;
+ case MAPID_SORCERER: return JOB_SORCERER;
+ case MAPID_MINSTRELWANDERER: return sex?JOB_MINSTREL:JOB_WANDERER;
+ case MAPID_SURA: return JOB_SURA;
+ case MAPID_GENETIC: return JOB_GENETIC;
+ case MAPID_SHADOW_CHASER: return JOB_SHADOW_CHASER;
+ //Trans 3-1 Jobs
+ case MAPID_RUNE_KNIGHT_T: return JOB_RUNE_KNIGHT_T;
+ case MAPID_WARLOCK_T: return JOB_WARLOCK_T;
+ case MAPID_RANGER_T: return JOB_RANGER_T;
+ case MAPID_ARCH_BISHOP_T: return JOB_ARCH_BISHOP_T;
+ case MAPID_MECHANIC_T: return JOB_MECHANIC_T;
+ case MAPID_GUILLOTINE_CROSS_T: return JOB_GUILLOTINE_CROSS_T;
+ //Trans 3-2 Jobs
+ case MAPID_ROYAL_GUARD_T: return JOB_ROYAL_GUARD_T;
+ case MAPID_SORCERER_T: return JOB_SORCERER_T;
+ case MAPID_MINSTRELWANDERER_T: return sex?JOB_MINSTREL_T:JOB_WANDERER_T;
+ case MAPID_SURA_T: return JOB_SURA_T;
+ case MAPID_GENETIC_T: return JOB_GENETIC_T;
+ case MAPID_SHADOW_CHASER_T: return JOB_SHADOW_CHASER_T;
+ //Baby 3-1 Jobs
+ case MAPID_SUPER_BABY_E: return JOB_SUPER_BABY_E;
+ case MAPID_BABY_RUNE: return JOB_BABY_RUNE;
+ case MAPID_BABY_WARLOCK: return JOB_BABY_WARLOCK;
+ case MAPID_BABY_RANGER: return JOB_BABY_RANGER;
+ case MAPID_BABY_BISHOP: return JOB_BABY_BISHOP;
+ case MAPID_BABY_MECHANIC: return JOB_BABY_MECHANIC;
+ case MAPID_BABY_CROSS: return JOB_BABY_CROSS;
+ //Baby 3-2 Jobs
+ case MAPID_BABY_GUARD: return JOB_BABY_GUARD;
+ case MAPID_BABY_SORCERER: return JOB_BABY_SORCERER;
+ case MAPID_BABY_MINSTRELWANDERER: return sex?JOB_BABY_MINSTREL:JOB_BABY_WANDERER;
+ case MAPID_BABY_SURA: return JOB_BABY_SURA;
+ case MAPID_BABY_GENETIC: return JOB_BABY_GENETIC;
+ case MAPID_BABY_CHASER: return JOB_BABY_CHASER;
+ default:
+ return -1;
+ }
}
/*====================================================
* This function return the name of the job (by [Yor])
*----------------------------------------------------*/
-const char *job_name(int class_)
-{
- switch (class_) {
- case JOB_NOVICE:
- case JOB_SWORDMAN:
- case JOB_MAGE:
- case JOB_ARCHER:
- case JOB_ACOLYTE:
- case JOB_MERCHANT:
- case JOB_THIEF:
- return msg_txt(550 - JOB_NOVICE+class_);
-
- case JOB_KNIGHT:
- case JOB_PRIEST:
- case JOB_WIZARD:
- case JOB_BLACKSMITH:
- case JOB_HUNTER:
- case JOB_ASSASSIN:
- return msg_txt(557 - JOB_KNIGHT+class_);
-
- case JOB_KNIGHT2:
- return msg_txt(557);
-
- case JOB_CRUSADER:
- case JOB_MONK:
- case JOB_SAGE:
- case JOB_ROGUE:
- case JOB_ALCHEMIST:
- case JOB_BARD:
- case JOB_DANCER:
- return msg_txt(563 - JOB_CRUSADER+class_);
-
- case JOB_CRUSADER2:
- return msg_txt(563);
-
- case JOB_WEDDING:
- case JOB_SUPER_NOVICE:
- case JOB_GUNSLINGER:
- case JOB_NINJA:
- case JOB_XMAS:
- return msg_txt(570 - JOB_WEDDING+class_);
-
- case JOB_SUMMER:
- return msg_txt(621);
-
- case JOB_NOVICE_HIGH:
- case JOB_SWORDMAN_HIGH:
- case JOB_MAGE_HIGH:
- case JOB_ARCHER_HIGH:
- case JOB_ACOLYTE_HIGH:
- case JOB_MERCHANT_HIGH:
- case JOB_THIEF_HIGH:
- return msg_txt(575 - JOB_NOVICE_HIGH+class_);
-
- case JOB_LORD_KNIGHT:
- case JOB_HIGH_PRIEST:
- case JOB_HIGH_WIZARD:
- case JOB_WHITESMITH:
- case JOB_SNIPER:
- case JOB_ASSASSIN_CROSS:
- return msg_txt(582 - JOB_LORD_KNIGHT+class_);
-
- case JOB_LORD_KNIGHT2:
- return msg_txt(582);
-
- case JOB_PALADIN:
- case JOB_CHAMPION:
- case JOB_PROFESSOR:
- case JOB_STALKER:
- case JOB_CREATOR:
- case JOB_CLOWN:
- case JOB_GYPSY:
- return msg_txt(588 - JOB_PALADIN + class_);
-
- case JOB_PALADIN2:
- return msg_txt(588);
-
- case JOB_BABY:
- case JOB_BABY_SWORDMAN:
- case JOB_BABY_MAGE:
- case JOB_BABY_ARCHER:
- case JOB_BABY_ACOLYTE:
- case JOB_BABY_MERCHANT:
- case JOB_BABY_THIEF:
- return msg_txt(595 - JOB_BABY + class_);
-
- case JOB_BABY_KNIGHT:
- case JOB_BABY_PRIEST:
- case JOB_BABY_WIZARD:
- case JOB_BABY_BLACKSMITH:
- case JOB_BABY_HUNTER:
- case JOB_BABY_ASSASSIN:
- return msg_txt(602 - JOB_BABY_KNIGHT + class_);
-
- case JOB_BABY_KNIGHT2:
- return msg_txt(602);
-
- case JOB_BABY_CRUSADER:
- case JOB_BABY_MONK:
- case JOB_BABY_SAGE:
- case JOB_BABY_ROGUE:
- case JOB_BABY_ALCHEMIST:
- case JOB_BABY_BARD:
- case JOB_BABY_DANCER:
- return msg_txt(608 - JOB_BABY_CRUSADER + class_);
-
- case JOB_BABY_CRUSADER2:
- return msg_txt(608);
-
- case JOB_SUPER_BABY:
- return msg_txt(615);
-
- case JOB_TAEKWON:
- return msg_txt(616);
- case JOB_STAR_GLADIATOR:
- case JOB_STAR_GLADIATOR2:
- return msg_txt(617);
- case JOB_SOUL_LINKER:
- return msg_txt(618);
-
- case JOB_GANGSI:
- case JOB_DEATH_KNIGHT:
- case JOB_DARK_COLLECTOR:
- return msg_txt(622 - JOB_GANGSI+class_);
-
- case JOB_RUNE_KNIGHT:
- case JOB_WARLOCK:
- case JOB_RANGER:
- case JOB_ARCH_BISHOP:
- case JOB_MECHANIC:
- case JOB_GUILLOTINE_CROSS:
- return msg_txt(625 - JOB_RUNE_KNIGHT+class_);
-
- case JOB_RUNE_KNIGHT_T:
- case JOB_WARLOCK_T:
- case JOB_RANGER_T:
- case JOB_ARCH_BISHOP_T:
- case JOB_MECHANIC_T:
- case JOB_GUILLOTINE_CROSS_T:
- return msg_txt(681 - JOB_RUNE_KNIGHT_T+class_);
-
- case JOB_ROYAL_GUARD:
- case JOB_SORCERER:
- case JOB_MINSTREL:
- case JOB_WANDERER:
- case JOB_SURA:
- case JOB_GENETIC:
- case JOB_SHADOW_CHASER:
- return msg_txt(631 - JOB_ROYAL_GUARD+class_);
-
- case JOB_ROYAL_GUARD_T:
- case JOB_SORCERER_T:
- case JOB_MINSTREL_T:
- case JOB_WANDERER_T:
- case JOB_SURA_T:
- case JOB_GENETIC_T:
- case JOB_SHADOW_CHASER_T:
- return msg_txt(687 - JOB_ROYAL_GUARD_T+class_);
-
- case JOB_RUNE_KNIGHT2:
- case JOB_RUNE_KNIGHT_T2:
- return msg_txt(625);
-
- case JOB_ROYAL_GUARD2:
- case JOB_ROYAL_GUARD_T2:
- return msg_txt(631);
-
- case JOB_RANGER2:
- case JOB_RANGER_T2:
- return msg_txt(627);
-
- case JOB_MECHANIC2:
- case JOB_MECHANIC_T2:
- return msg_txt(629);
-
- case JOB_BABY_RUNE:
- case JOB_BABY_WARLOCK:
- case JOB_BABY_RANGER:
- case JOB_BABY_BISHOP:
- case JOB_BABY_MECHANIC:
- case JOB_BABY_CROSS:
- case JOB_BABY_GUARD:
- case JOB_BABY_SORCERER:
- case JOB_BABY_MINSTREL:
- case JOB_BABY_WANDERER:
- case JOB_BABY_SURA:
- case JOB_BABY_GENETIC:
- case JOB_BABY_CHASER:
- return msg_txt(638 - JOB_BABY_RUNE+class_);
-
- case JOB_BABY_RUNE2:
- return msg_txt(638);
-
- case JOB_BABY_GUARD2:
- return msg_txt(644);
-
- case JOB_BABY_RANGER2:
- return msg_txt(640);
-
- case JOB_BABY_MECHANIC2:
- return msg_txt(642);
-
- case JOB_SUPER_NOVICE_E:
- case JOB_SUPER_BABY_E:
- return msg_txt(651 - JOB_SUPER_NOVICE_E+class_);
-
- case JOB_KAGEROU:
- case JOB_OBORO:
- return msg_txt(653 - JOB_KAGEROU+class_);
-
- default:
- return msg_txt(655);
- }
+const char* job_name(int class_)
+{
+ switch (class_) {
+ case JOB_NOVICE:
+ case JOB_SWORDMAN:
+ case JOB_MAGE:
+ case JOB_ARCHER:
+ case JOB_ACOLYTE:
+ case JOB_MERCHANT:
+ case JOB_THIEF:
+ return msg_txt(550 - JOB_NOVICE+class_);
+
+ case JOB_KNIGHT:
+ case JOB_PRIEST:
+ case JOB_WIZARD:
+ case JOB_BLACKSMITH:
+ case JOB_HUNTER:
+ case JOB_ASSASSIN:
+ return msg_txt(557 - JOB_KNIGHT+class_);
+
+ case JOB_KNIGHT2:
+ return msg_txt(557);
+
+ case JOB_CRUSADER:
+ case JOB_MONK:
+ case JOB_SAGE:
+ case JOB_ROGUE:
+ case JOB_ALCHEMIST:
+ case JOB_BARD:
+ case JOB_DANCER:
+ return msg_txt(563 - JOB_CRUSADER+class_);
+
+ case JOB_CRUSADER2:
+ return msg_txt(563);
+
+ case JOB_WEDDING:
+ case JOB_SUPER_NOVICE:
+ case JOB_GUNSLINGER:
+ case JOB_NINJA:
+ case JOB_XMAS:
+ return msg_txt(570 - JOB_WEDDING+class_);
+
+ case JOB_SUMMER:
+ return msg_txt(621);
+
+ case JOB_NOVICE_HIGH:
+ case JOB_SWORDMAN_HIGH:
+ case JOB_MAGE_HIGH:
+ case JOB_ARCHER_HIGH:
+ case JOB_ACOLYTE_HIGH:
+ case JOB_MERCHANT_HIGH:
+ case JOB_THIEF_HIGH:
+ return msg_txt(575 - JOB_NOVICE_HIGH+class_);
+
+ case JOB_LORD_KNIGHT:
+ case JOB_HIGH_PRIEST:
+ case JOB_HIGH_WIZARD:
+ case JOB_WHITESMITH:
+ case JOB_SNIPER:
+ case JOB_ASSASSIN_CROSS:
+ return msg_txt(582 - JOB_LORD_KNIGHT+class_);
+
+ case JOB_LORD_KNIGHT2:
+ return msg_txt(582);
+
+ case JOB_PALADIN:
+ case JOB_CHAMPION:
+ case JOB_PROFESSOR:
+ case JOB_STALKER:
+ case JOB_CREATOR:
+ case JOB_CLOWN:
+ case JOB_GYPSY:
+ return msg_txt(588 - JOB_PALADIN + class_);
+
+ case JOB_PALADIN2:
+ return msg_txt(588);
+
+ case JOB_BABY:
+ case JOB_BABY_SWORDMAN:
+ case JOB_BABY_MAGE:
+ case JOB_BABY_ARCHER:
+ case JOB_BABY_ACOLYTE:
+ case JOB_BABY_MERCHANT:
+ case JOB_BABY_THIEF:
+ return msg_txt(595 - JOB_BABY + class_);
+
+ case JOB_BABY_KNIGHT:
+ case JOB_BABY_PRIEST:
+ case JOB_BABY_WIZARD:
+ case JOB_BABY_BLACKSMITH:
+ case JOB_BABY_HUNTER:
+ case JOB_BABY_ASSASSIN:
+ return msg_txt(602 - JOB_BABY_KNIGHT + class_);
+
+ case JOB_BABY_KNIGHT2:
+ return msg_txt(602);
+
+ case JOB_BABY_CRUSADER:
+ case JOB_BABY_MONK:
+ case JOB_BABY_SAGE:
+ case JOB_BABY_ROGUE:
+ case JOB_BABY_ALCHEMIST:
+ case JOB_BABY_BARD:
+ case JOB_BABY_DANCER:
+ return msg_txt(608 - JOB_BABY_CRUSADER + class_);
+
+ case JOB_BABY_CRUSADER2:
+ return msg_txt(608);
+
+ case JOB_SUPER_BABY:
+ return msg_txt(615);
+
+ case JOB_TAEKWON:
+ return msg_txt(616);
+ case JOB_STAR_GLADIATOR:
+ case JOB_STAR_GLADIATOR2:
+ return msg_txt(617);
+ case JOB_SOUL_LINKER:
+ return msg_txt(618);
+
+ case JOB_GANGSI:
+ case JOB_DEATH_KNIGHT:
+ case JOB_DARK_COLLECTOR:
+ return msg_txt(622 - JOB_GANGSI+class_);
+
+ case JOB_RUNE_KNIGHT:
+ case JOB_WARLOCK:
+ case JOB_RANGER:
+ case JOB_ARCH_BISHOP:
+ case JOB_MECHANIC:
+ case JOB_GUILLOTINE_CROSS:
+ return msg_txt(625 - JOB_RUNE_KNIGHT+class_);
+
+ case JOB_RUNE_KNIGHT_T:
+ case JOB_WARLOCK_T:
+ case JOB_RANGER_T:
+ case JOB_ARCH_BISHOP_T:
+ case JOB_MECHANIC_T:
+ case JOB_GUILLOTINE_CROSS_T:
+ return msg_txt(625 - JOB_RUNE_KNIGHT_T+class_);
+
+ case JOB_ROYAL_GUARD:
+ case JOB_SORCERER:
+ case JOB_MINSTREL:
+ case JOB_WANDERER:
+ case JOB_SURA:
+ case JOB_GENETIC:
+ case JOB_SHADOW_CHASER:
+ return msg_txt(631 - JOB_ROYAL_GUARD+class_);
+
+ case JOB_ROYAL_GUARD_T:
+ case JOB_SORCERER_T:
+ case JOB_MINSTREL_T:
+ case JOB_WANDERER_T:
+ case JOB_SURA_T:
+ case JOB_GENETIC_T:
+ case JOB_SHADOW_CHASER_T:
+ return msg_txt(631 - JOB_ROYAL_GUARD_T+class_);
+
+ case JOB_RUNE_KNIGHT2:
+ case JOB_RUNE_KNIGHT_T2:
+ return msg_txt(625);
+
+ case JOB_ROYAL_GUARD2:
+ case JOB_ROYAL_GUARD_T2:
+ return msg_txt(631);
+
+ case JOB_RANGER2:
+ case JOB_RANGER_T2:
+ return msg_txt(627);
+
+ case JOB_MECHANIC2:
+ case JOB_MECHANIC_T2:
+ return msg_txt(629);
+
+ case JOB_BABY_RUNE:
+ case JOB_BABY_WARLOCK:
+ case JOB_BABY_RANGER:
+ case JOB_BABY_BISHOP:
+ case JOB_BABY_MECHANIC:
+ case JOB_BABY_CROSS:
+ case JOB_BABY_GUARD:
+ case JOB_BABY_SORCERER:
+ case JOB_BABY_MINSTREL:
+ case JOB_BABY_WANDERER:
+ case JOB_BABY_SURA:
+ case JOB_BABY_GENETIC:
+ case JOB_BABY_CHASER:
+ return msg_txt(638 - JOB_BABY_RUNE+class_);
+
+ case JOB_BABY_RUNE2:
+ return msg_txt(638);
+
+ case JOB_BABY_GUARD2:
+ return msg_txt(644);
+
+ case JOB_BABY_RANGER2:
+ return msg_txt(640);
+
+ case JOB_BABY_MECHANIC2:
+ return msg_txt(642);
+
+ case JOB_SUPER_NOVICE_E:
+ case JOB_SUPER_BABY_E:
+ return msg_txt(651 - JOB_SUPER_NOVICE_E+class_);
+
+ case JOB_KAGEROU:
+ case JOB_OBORO:
+ return msg_txt(653 - JOB_KAGEROU+class_);
+
+ default:
+ return msg_txt(655);
+ }
}
int pc_follow_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- struct map_session_data *sd;
- struct block_list *tbl;
+ struct map_session_data *sd;
+ struct block_list *tbl;
- sd = map_id2sd(id);
- nullpo_ret(sd);
+ sd = map_id2sd(id);
+ nullpo_ret(sd);
- if (sd->followtimer != tid) {
- ShowError("pc_follow_timer %d != %d\n",sd->followtimer,tid);
- sd->followtimer = INVALID_TIMER;
- return 0;
- }
+ if (sd->followtimer != tid){
+ ShowError("pc_follow_timer %d != %d\n",sd->followtimer,tid);
+ sd->followtimer = INVALID_TIMER;
+ return 0;
+ }
- sd->followtimer = INVALID_TIMER;
- tbl = map_id2bl(sd->followtarget);
+ sd->followtimer = INVALID_TIMER;
+ tbl = map_id2bl(sd->followtarget);
- if (tbl == NULL || pc_isdead(sd) || status_isdead(tbl)) {
- pc_stop_following(sd);
- return 0;
- }
+ if (tbl == NULL || pc_isdead(sd) || status_isdead(tbl))
+ {
+ pc_stop_following(sd);
+ return 0;
+ }
- // either player or target is currently detached from map blocks (could be teleporting),
- // but still connected to this map, so we'll just increment the timer and check back later
- if (sd->bl.prev != NULL && tbl->prev != NULL &&
- sd->ud.skilltimer == INVALID_TIMER && sd->ud.attacktimer == INVALID_TIMER && sd->ud.walktimer == INVALID_TIMER) {
- if ((sd->bl.m == tbl->m) && unit_can_reach_bl(&sd->bl,tbl, AREA_SIZE, 0, NULL, NULL)) {
- if (!check_distance_bl(&sd->bl, tbl, 5))
- unit_walktobl(&sd->bl, tbl, 5, 0);
- } else
- pc_setpos(sd, map_id2index(tbl->m), tbl->x, tbl->y, CLR_TELEPORT);
- }
- sd->followtimer = add_timer(
- tick + 1000, // increase time a bit to loosen up map's load
- pc_follow_timer, sd->bl.id, 0);
- return 0;
+ // either player or target is currently detached from map blocks (could be teleporting),
+ // but still connected to this map, so we'll just increment the timer and check back later
+ if (sd->bl.prev != NULL && tbl->prev != NULL &&
+ sd->ud.skilltimer == INVALID_TIMER && sd->ud.attacktimer == INVALID_TIMER && sd->ud.walktimer == INVALID_TIMER)
+ {
+ if((sd->bl.m == tbl->m) && unit_can_reach_bl(&sd->bl,tbl, AREA_SIZE, 0, NULL, NULL)) {
+ if (!check_distance_bl(&sd->bl, tbl, 5))
+ unit_walktobl(&sd->bl, tbl, 5, 0);
+ } else
+ pc_setpos(sd, map_id2index(tbl->m), tbl->x, tbl->y, CLR_TELEPORT);
+ }
+ sd->followtimer = add_timer(
+ tick + 1000, // increase time a bit to loosen up map's load
+ pc_follow_timer, sd->bl.id, 0);
+ return 0;
}
-int pc_stop_following(struct map_session_data *sd)
+int pc_stop_following (struct map_session_data *sd)
{
- nullpo_ret(sd);
+ nullpo_ret(sd);
- if (sd->followtimer != INVALID_TIMER) {
- delete_timer(sd->followtimer,pc_follow_timer);
- sd->followtimer = INVALID_TIMER;
- }
- sd->followtarget = -1;
+ if (sd->followtimer != INVALID_TIMER) {
+ delete_timer(sd->followtimer,pc_follow_timer);
+ sd->followtimer = INVALID_TIMER;
+ }
+ sd->followtarget = -1;
- return 0;
+ return 0;
}
int pc_follow(struct map_session_data *sd,int target_id)
{
- struct block_list *bl = map_id2bl(target_id);
- if (bl == NULL /*|| bl->type != BL_PC*/)
- return 1;
- if (sd->followtimer != INVALID_TIMER)
- pc_stop_following(sd);
+ struct block_list *bl = map_id2bl(target_id);
+ if (bl == NULL /*|| bl->type != BL_PC*/)
+ return 1;
+ if (sd->followtimer != INVALID_TIMER)
+ pc_stop_following(sd);
- sd->followtarget = target_id;
- pc_follow_timer(INVALID_TIMER, gettick(), sd->bl.id, 0);
+ sd->followtarget = target_id;
+ pc_follow_timer(INVALID_TIMER, gettick(), sd->bl.id, 0);
- return 0;
+ return 0;
}
-int pc_checkbaselevelup(struct map_session_data *sd)
-{
- unsigned int next = pc_nextbaseexp(sd);
+int pc_checkbaselevelup(struct map_session_data *sd) {
+ unsigned int next = pc_nextbaseexp(sd);
- if (!next || sd->status.base_exp < next)
- return 0;
+ if (!next || sd->status.base_exp < next)
+ return 0;
- do {
- sd->status.base_exp -= next;
- //Kyoki pointed out that the max overcarry exp is the exp needed for the previous level -1. [Skotlex]
- if (!battle_config.multi_level_up && sd->status.base_exp > next-1)
- sd->status.base_exp = next-1;
+ do {
+ sd->status.base_exp -= next;
+ //Kyoki pointed out that the max overcarry exp is the exp needed for the previous level -1. [Skotlex]
+ if(!battle_config.multi_level_up && sd->status.base_exp > next-1)
+ sd->status.base_exp = next-1;
- next = pc_gets_status_point(sd->status.base_level);
- sd->status.base_level ++;
- sd->status.status_point += next;
+ next = pc_gets_status_point(sd->status.base_level);
+ sd->status.base_level ++;
+ sd->status.status_point += next;
- } while ((next=pc_nextbaseexp(sd)) > 0 && sd->status.base_exp >= next);
+ } while ((next=pc_nextbaseexp(sd)) > 0 && sd->status.base_exp >= next);
- if (battle_config.pet_lv_rate && sd->pd) //<Skotlex> update pet's level
- status_calc_pet(sd->pd,0);
+ if (battle_config.pet_lv_rate && sd->pd) //<Skotlex> update pet's level
+ status_calc_pet(sd->pd,0);
- clif_updatestatus(sd,SP_STATUSPOINT);
- clif_updatestatus(sd,SP_BASELEVEL);
- clif_updatestatus(sd,SP_BASEEXP);
- clif_updatestatus(sd,SP_NEXTBASEEXP);
- status_calc_pc(sd,0);
- status_percent_heal(&sd->bl,100,100);
+ clif_updatestatus(sd,SP_STATUSPOINT);
+ clif_updatestatus(sd,SP_BASELEVEL);
+ clif_updatestatus(sd,SP_BASEEXP);
+ clif_updatestatus(sd,SP_NEXTBASEEXP);
+ status_calc_pc(sd,0);
+ status_percent_heal(&sd->bl,100,100);
- if ((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE) {
- sc_start(&sd->bl,status_skill2sc(PR_KYRIE),100,1,skill_get_time(PR_KYRIE,1));
- sc_start(&sd->bl,status_skill2sc(PR_IMPOSITIO),100,1,skill_get_time(PR_IMPOSITIO,1));
- sc_start(&sd->bl,status_skill2sc(PR_MAGNIFICAT),100,1,skill_get_time(PR_MAGNIFICAT,1));
- sc_start(&sd->bl,status_skill2sc(PR_GLORIA),100,1,skill_get_time(PR_GLORIA,1));
- sc_start(&sd->bl,status_skill2sc(PR_SUFFRAGIUM),100,1,skill_get_time(PR_SUFFRAGIUM,1));
- if (sd->state.snovice_dead_flag)
- sd->state.snovice_dead_flag = 0; //Reenable steelbody resurrection on dead.
- } else if ((sd->class_&MAPID_BASEMASK) == MAPID_TAEKWON) {
- sc_start(&sd->bl,status_skill2sc(AL_INCAGI),100,10,600000);
- sc_start(&sd->bl,status_skill2sc(AL_BLESSING),100,10,600000);
- }
- clif_misceffect(&sd->bl,0);
- npc_script_event(sd, NPCE_BASELVUP); //LORDALFA - LVLUPEVENT
+ if((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE) {
+ sc_start(&sd->bl,status_skill2sc(PR_KYRIE),100,1,skill_get_time(PR_KYRIE,1));
+ sc_start(&sd->bl,status_skill2sc(PR_IMPOSITIO),100,1,skill_get_time(PR_IMPOSITIO,1));
+ sc_start(&sd->bl,status_skill2sc(PR_MAGNIFICAT),100,1,skill_get_time(PR_MAGNIFICAT,1));
+ sc_start(&sd->bl,status_skill2sc(PR_GLORIA),100,1,skill_get_time(PR_GLORIA,1));
+ sc_start(&sd->bl,status_skill2sc(PR_SUFFRAGIUM),100,1,skill_get_time(PR_SUFFRAGIUM,1));
+ if (sd->state.snovice_dead_flag)
+ sd->state.snovice_dead_flag = 0; //Reenable steelbody resurrection on dead.
+ } else if( (sd->class_&MAPID_BASEMASK) == MAPID_TAEKWON ) {
+ sc_start(&sd->bl,status_skill2sc(AL_INCAGI),100,10,600000);
+ sc_start(&sd->bl,status_skill2sc(AL_BLESSING),100,10,600000);
+ }
+ clif_misceffect(&sd->bl,0);
+ npc_script_event(sd, NPCE_BASELVUP); //LORDALFA - LVLUPEVENT
- if (sd->status.party_id)
- party_send_levelup(sd);
+ if(sd->status.party_id)
+ party_send_levelup(sd);
- pc_baselevelchanged(sd);
- return 1;
+ pc_baselevelchanged(sd);
+ return 1;
}
-void pc_baselevelchanged(struct map_session_data *sd)
-{
+void pc_baselevelchanged(struct map_session_data *sd) {
#ifdef RENEWAL
- int i;
- for (i = 0; i < EQI_MAX; i++) {
- if (sd->equip_index[i] >= 0) {
- if (sd->inventory_data[ sd->equip_index[i] ]->elvmax && sd->status.base_level > (unsigned int)sd->inventory_data[ sd->equip_index[i] ]->elvmax)
- pc_unequipitem(sd, sd->equip_index[i], 3);
- }
- }
+ int i;
+ for( i = 0; i < EQI_MAX; i++ ) {
+ if( sd->equip_index[i] >= 0 ) {
+ if( sd->inventory_data[ sd->equip_index[i] ]->elvmax && sd->status.base_level > (unsigned int)sd->inventory_data[ sd->equip_index[i] ]->elvmax )
+ pc_unequipitem(sd, sd->equip_index[i], 3);
+ }
+ }
#endif
}
int pc_checkjoblevelup(struct map_session_data *sd)
{
- unsigned int next = pc_nextjobexp(sd);
+ unsigned int next = pc_nextjobexp(sd);
- nullpo_ret(sd);
- if (!next || sd->status.job_exp < next)
- return 0;
+ nullpo_ret(sd);
+ if(!next || sd->status.job_exp < next)
+ return 0;
- do {
- sd->status.job_exp -= next;
- //Kyoki pointed out that the max overcarry exp is the exp needed for the previous level -1. [Skotlex]
- if (!battle_config.multi_level_up && sd->status.job_exp > next-1)
- sd->status.job_exp = next-1;
+ do {
+ sd->status.job_exp -= next;
+ //Kyoki pointed out that the max overcarry exp is the exp needed for the previous level -1. [Skotlex]
+ if(!battle_config.multi_level_up && sd->status.job_exp > next-1)
+ sd->status.job_exp = next-1;
- sd->status.job_level ++;
- sd->status.skill_point ++;
+ sd->status.job_level ++;
+ sd->status.skill_point ++;
- } while ((next=pc_nextjobexp(sd)) > 0 && sd->status.job_exp >= next);
+ } while ((next=pc_nextjobexp(sd)) > 0 && sd->status.job_exp >= next);
- clif_updatestatus(sd,SP_JOBLEVEL);
- clif_updatestatus(sd,SP_JOBEXP);
- clif_updatestatus(sd,SP_NEXTJOBEXP);
- clif_updatestatus(sd,SP_SKILLPOINT);
- status_calc_pc(sd,0);
- clif_misceffect(&sd->bl,1);
- if (pc_checkskill(sd, SG_DEVIL) && !pc_nextjobexp(sd))
- clif_status_change(&sd->bl,SI_DEVIL, 1, 0, 0, 0, 1); //Permanent blind effect from SG_DEVIL.
+ clif_updatestatus(sd,SP_JOBLEVEL);
+ clif_updatestatus(sd,SP_JOBEXP);
+ clif_updatestatus(sd,SP_NEXTJOBEXP);
+ clif_updatestatus(sd,SP_SKILLPOINT);
+ status_calc_pc(sd,0);
+ clif_misceffect(&sd->bl,1);
+ if (pc_checkskill(sd, SG_DEVIL) && !pc_nextjobexp(sd))
+ clif_status_change(&sd->bl,SI_DEVIL, 1, 0, 0, 0, 1); //Permanent blind effect from SG_DEVIL.
- npc_script_event(sd, NPCE_JOBLVUP);
- return 1;
+ npc_script_event(sd, NPCE_JOBLVUP);
+ return 1;
}
/*==========================================
@@ -5702,107 +5633,107 @@ int pc_checkjoblevelup(struct map_session_data *sd)
*------------------------------------------*/
static void pc_calcexp(struct map_session_data *sd, unsigned int *base_exp, unsigned int *job_exp, struct block_list *src)
{
- int bonus = 0;
- struct status_data *status = status_get_status_data(src);
+ int bonus = 0;
+ struct status_data *status = status_get_status_data(src);
- if (sd->expaddrace[status->race])
- bonus += sd->expaddrace[status->race];
- bonus += sd->expaddrace[status->mode&MD_BOSS?RC_BOSS:RC_NONBOSS];
+ if (sd->expaddrace[status->race])
+ bonus += sd->expaddrace[status->race];
+ bonus += sd->expaddrace[status->mode&MD_BOSS?RC_BOSS:RC_NONBOSS];
- if (battle_config.pk_mode &&
- (int)(status_get_lv(src) - sd->status.base_level) >= 20)
- bonus += 15; // pk_mode additional exp if monster >20 levels [Valaris]
+ if (battle_config.pk_mode &&
+ (int)(status_get_lv(src) - sd->status.base_level) >= 20)
+ bonus += 15; // pk_mode additional exp if monster >20 levels [Valaris]
- if (sd->sc.data[SC_EXPBOOST])
- bonus += sd->sc.data[SC_EXPBOOST]->val1;
+ if (sd->sc.data[SC_EXPBOOST])
+ bonus += sd->sc.data[SC_EXPBOOST]->val1;
- *base_exp = (unsigned int) cap_value(*base_exp + (double)*base_exp * bonus/100., 1, UINT_MAX);
+ *base_exp = (unsigned int) cap_value(*base_exp + (double)*base_exp * bonus/100., 1, UINT_MAX);
- if (sd->sc.data[SC_JEXPBOOST])
- bonus += sd->sc.data[SC_JEXPBOOST]->val1;
+ if (sd->sc.data[SC_JEXPBOOST])
+ bonus += sd->sc.data[SC_JEXPBOOST]->val1;
- *job_exp = (unsigned int) cap_value(*job_exp + (double)*job_exp * bonus/100., 1, UINT_MAX);
+ *job_exp = (unsigned int) cap_value(*job_exp + (double)*job_exp * bonus/100., 1, UINT_MAX);
- return;
+ return;
}
/*==========================================
* Give x exp at sd player and calculate remaining exp for next lvl
*------------------------------------------*/
int pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned int base_exp,unsigned int job_exp,bool quest)
{
- float nextbp=0, nextjp=0;
- unsigned int nextb=0, nextj=0;
- nullpo_ret(sd);
-
- if (sd->bl.prev == NULL || pc_isdead(sd))
- return 0;
-
- if (!battle_config.pvp_exp && map[sd->bl.m].flag.pvp) // [MouseJstr]
- return 0; // no exp on pvp maps
-
- if (sd->status.guild_id>0)
- base_exp-=guild_payexp(sd,base_exp);
-
- if (src) pc_calcexp(sd, &base_exp, &job_exp, src);
-
- nextb = pc_nextbaseexp(sd);
- nextj = pc_nextjobexp(sd);
-
- if (sd->state.showexp || battle_config.max_exp_gain_rate) {
- if (nextb > 0)
- nextbp = (float) base_exp / (float) nextb;
- if (nextj > 0)
- nextjp = (float) job_exp / (float) nextj;
-
- if (battle_config.max_exp_gain_rate) {
- if (nextbp > battle_config.max_exp_gain_rate/1000.) {
- //Note that this value should never be greater than the original
- //base_exp, therefore no overflow checks are needed. [Skotlex]
- base_exp = (unsigned int)(battle_config.max_exp_gain_rate/1000.*nextb);
- if (sd->state.showexp)
- nextbp = (float) base_exp / (float) nextb;
- }
- if (nextjp > battle_config.max_exp_gain_rate/1000.) {
- job_exp = (unsigned int)(battle_config.max_exp_gain_rate/1000.*nextj);
- if (sd->state.showexp)
- nextjp = (float) job_exp / (float) nextj;
- }
- }
- }
-
- //Cap exp to the level up requirement of the previous level when you are at max level, otherwise cap at UINT_MAX (this is required for some S. Novice bonuses). [Skotlex]
- if (base_exp) {
- nextb = nextb?UINT_MAX:pc_thisbaseexp(sd);
- if (sd->status.base_exp > nextb - base_exp)
- sd->status.base_exp = nextb;
- else
- sd->status.base_exp += base_exp;
- pc_checkbaselevelup(sd);
- clif_updatestatus(sd,SP_BASEEXP);
- }
-
- if (job_exp) {
- nextj = nextj?UINT_MAX:pc_thisjobexp(sd);
- if (sd->status.job_exp > nextj - job_exp)
- sd->status.job_exp = nextj;
- else
- sd->status.job_exp += job_exp;
- pc_checkjoblevelup(sd);
- clif_updatestatus(sd,SP_JOBEXP);
- }
-
- if (base_exp)
- clif_displayexp(sd, base_exp, SP_BASEEXP, quest);
- if (job_exp)
- clif_displayexp(sd, job_exp, SP_JOBEXP, quest);
- if (sd->state.showexp) {
- char output[256];
- sprintf(output,
- "Experience Gained Base:%u (%.2f%%) Job:%u (%.2f%%)",base_exp,nextbp*(float)100,job_exp,nextjp*(float)100);
- clif_disp_onlyself(sd,output,strlen(output));
- }
-
- return 1;
+ float nextbp=0, nextjp=0;
+ unsigned int nextb=0, nextj=0;
+ nullpo_ret(sd);
+
+ if(sd->bl.prev == NULL || pc_isdead(sd))
+ return 0;
+
+ if(!battle_config.pvp_exp && map[sd->bl.m].flag.pvp) // [MouseJstr]
+ return 0; // no exp on pvp maps
+
+ if(sd->status.guild_id>0)
+ base_exp-=guild_payexp(sd,base_exp);
+
+ if(src) pc_calcexp(sd, &base_exp, &job_exp, src);
+
+ nextb = pc_nextbaseexp(sd);
+ nextj = pc_nextjobexp(sd);
+
+ if(sd->state.showexp || battle_config.max_exp_gain_rate){
+ if (nextb > 0)
+ nextbp = (float) base_exp / (float) nextb;
+ if (nextj > 0)
+ nextjp = (float) job_exp / (float) nextj;
+
+ if(battle_config.max_exp_gain_rate) {
+ if (nextbp > battle_config.max_exp_gain_rate/1000.) {
+ //Note that this value should never be greater than the original
+ //base_exp, therefore no overflow checks are needed. [Skotlex]
+ base_exp = (unsigned int)(battle_config.max_exp_gain_rate/1000.*nextb);
+ if (sd->state.showexp)
+ nextbp = (float) base_exp / (float) nextb;
+ }
+ if (nextjp > battle_config.max_exp_gain_rate/1000.) {
+ job_exp = (unsigned int)(battle_config.max_exp_gain_rate/1000.*nextj);
+ if (sd->state.showexp)
+ nextjp = (float) job_exp / (float) nextj;
+ }
+ }
+ }
+
+ //Cap exp to the level up requirement of the previous level when you are at max level, otherwise cap at UINT_MAX (this is required for some S. Novice bonuses). [Skotlex]
+ if (base_exp) {
+ nextb = nextb?UINT_MAX:pc_thisbaseexp(sd);
+ if(sd->status.base_exp > nextb - base_exp)
+ sd->status.base_exp = nextb;
+ else
+ sd->status.base_exp += base_exp;
+ pc_checkbaselevelup(sd);
+ clif_updatestatus(sd,SP_BASEEXP);
+ }
+
+ if (job_exp) {
+ nextj = nextj?UINT_MAX:pc_thisjobexp(sd);
+ if(sd->status.job_exp > nextj - job_exp)
+ sd->status.job_exp = nextj;
+ else
+ sd->status.job_exp += job_exp;
+ pc_checkjoblevelup(sd);
+ clif_updatestatus(sd,SP_JOBEXP);
+ }
+
+ if(base_exp)
+ clif_displayexp(sd, base_exp, SP_BASEEXP, quest);
+ if(job_exp)
+ clif_displayexp(sd, job_exp, SP_JOBEXP, quest);
+ if(sd->state.showexp) {
+ char output[256];
+ sprintf(output,
+ "Experience Gained Base:%u (%.2f%%) Job:%u (%.2f%%)",base_exp,nextbp*(float)100,job_exp,nextjp*(float)100);
+ clif_disp_onlyself(sd,output,strlen(output));
+ }
+
+ return 1;
}
/*==========================================
@@ -5810,12 +5741,12 @@ int pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned int
*------------------------------------------*/
unsigned int pc_maxbaselv(struct map_session_data *sd)
{
- return max_level[pc_class2idx(sd->status.class_)][0];
+ return max_level[pc_class2idx(sd->status.class_)][0];
}
unsigned int pc_maxjoblv(struct map_session_data *sd)
{
- return max_level[pc_class2idx(sd->status.class_)][1];
+ return max_level[pc_class2idx(sd->status.class_)][1];
}
/*==========================================
@@ -5825,141 +5756,123 @@ unsigned int pc_maxjoblv(struct map_session_data *sd)
//Base exp needed for next level.
unsigned int pc_nextbaseexp(struct map_session_data *sd)
{
- nullpo_ret(sd);
+ nullpo_ret(sd);
- if (sd->status.base_level>=pc_maxbaselv(sd) || sd->status.base_level<=0)
- return 0;
+ if(sd->status.base_level>=pc_maxbaselv(sd) || sd->status.base_level<=0)
+ return 0;
- return exp_table[pc_class2idx(sd->status.class_)][0][sd->status.base_level-1];
+ return exp_table[pc_class2idx(sd->status.class_)][0][sd->status.base_level-1];
}
//Base exp needed for this level.
unsigned int pc_thisbaseexp(struct map_session_data *sd)
{
- if (sd->status.base_level>pc_maxbaselv(sd) || sd->status.base_level<=1)
- return 0;
+ if(sd->status.base_level>pc_maxbaselv(sd) || sd->status.base_level<=1)
+ return 0;
- return exp_table[pc_class2idx(sd->status.class_)][0][sd->status.base_level-2];
+ return exp_table[pc_class2idx(sd->status.class_)][0][sd->status.base_level-2];
}
/*==========================================
* job level exp lookup
* Return:
- * 0 = not found
- * x = exp for level
+ * 0 = not found
+ * x = exp for level
*------------------------------------------*/
//Job exp needed for next level.
unsigned int pc_nextjobexp(struct map_session_data *sd)
{
- nullpo_ret(sd);
+ nullpo_ret(sd);
- if (sd->status.job_level>=pc_maxjoblv(sd) || sd->status.job_level<=0)
- return 0;
- return exp_table[pc_class2idx(sd->status.class_)][1][sd->status.job_level-1];
+ if(sd->status.job_level>=pc_maxjoblv(sd) || sd->status.job_level<=0)
+ return 0;
+ return exp_table[pc_class2idx(sd->status.class_)][1][sd->status.job_level-1];
}
//Job exp needed for this level.
unsigned int pc_thisjobexp(struct map_session_data *sd)
{
- if (sd->status.job_level>pc_maxjoblv(sd) || sd->status.job_level<=1)
- return 0;
- return exp_table[pc_class2idx(sd->status.class_)][1][sd->status.job_level-2];
+ if(sd->status.job_level>pc_maxjoblv(sd) || sd->status.job_level<=1)
+ return 0;
+ return exp_table[pc_class2idx(sd->status.class_)][1][sd->status.job_level-2];
}
/// Returns the value of the specified stat.
-static int pc_getstat(struct map_session_data *sd, int type)
-{
- nullpo_retr(-1, sd);
-
- switch (type) {
- case SP_STR:
- return sd->status.str;
- case SP_AGI:
- return sd->status.agi;
- case SP_VIT:
- return sd->status.vit;
- case SP_INT:
- return sd->status.int_;
- case SP_DEX:
- return sd->status.dex;
- case SP_LUK:
- return sd->status.luk;
- default:
- return -1;
- }
+static int pc_getstat(struct map_session_data* sd, int type)
+{
+ nullpo_retr(-1, sd);
+
+ switch( type ) {
+ case SP_STR: return sd->status.str;
+ case SP_AGI: return sd->status.agi;
+ case SP_VIT: return sd->status.vit;
+ case SP_INT: return sd->status.int_;
+ case SP_DEX: return sd->status.dex;
+ case SP_LUK: return sd->status.luk;
+ default:
+ return -1;
+ }
}
/// Sets the specified stat to the specified value.
/// Returns the new value.
-static int pc_setstat(struct map_session_data *sd, int type, int val)
-{
- nullpo_retr(-1, sd);
-
- switch (type) {
- case SP_STR:
- sd->status.str = val;
- break;
- case SP_AGI:
- sd->status.agi = val;
- break;
- case SP_VIT:
- sd->status.vit = val;
- break;
- case SP_INT:
- sd->status.int_ = val;
- break;
- case SP_DEX:
- sd->status.dex = val;
- break;
- case SP_LUK:
- sd->status.luk = val;
- break;
- default:
- return -1;
- }
-
- return val;
+static int pc_setstat(struct map_session_data* sd, int type, int val)
+{
+ nullpo_retr(-1, sd);
+
+ switch( type ) {
+ case SP_STR: sd->status.str = val; break;
+ case SP_AGI: sd->status.agi = val; break;
+ case SP_VIT: sd->status.vit = val; break;
+ case SP_INT: sd->status.int_ = val; break;
+ case SP_DEX: sd->status.dex = val; break;
+ case SP_LUK: sd->status.luk = val; break;
+ default:
+ return -1;
+ }
+
+ return val;
}
// Calculates the number of status points PC gets when leveling up (from level to level+1)
int pc_gets_status_point(int level)
{
- if (battle_config.use_statpoint_table) //Use values from "db/statpoint.txt"
- return (statp[level+1] - statp[level]);
- else //Default increase
- return ((level+15) / 5);
+ if (battle_config.use_statpoint_table) //Use values from "db/statpoint.txt"
+ return (statp[level+1] - statp[level]);
+ else //Default increase
+ return ((level+15) / 5);
}
/// Returns the number of stat points needed to change the specified stat by val.
/// If val is negative, returns the number of stat points that would be needed to
/// raise the specified stat from (current value - val) to current value.
-int pc_need_status_point(struct map_session_data *sd, int type, int val)
+int pc_need_status_point(struct map_session_data* sd, int type, int val)
{
- int low, high, sp = 0;
+ int low, high, sp = 0;
- if (val == 0)
- return 0;
+ if ( val == 0 )
+ return 0;
- low = pc_getstat(sd,type);
+ low = pc_getstat(sd,type);
- if (low >= pc_maxparameter(sd) && val > 0)
- return 0; // Official servers show '0' when max is reached
+ if ( low >= pc_maxparameter(sd) && val > 0 )
+ return 0; // Official servers show '0' when max is reached
- high = low + val;
+ high = low + val;
- if (val < 0)
- swap(low, high);
+ if ( val < 0 )
+ swap(low, high);
- for (; low < high; low++)
+ for ( ; low < high; low++ )
#ifdef RENEWAL // renewal status point cost formula
- sp += (low < 100) ? (2 + (low - 1) / 10) : (16 + 4 * ((low - 100) / 5));
+ sp += (low < 100) ? (2 + (low - 1) / 10) : (16 + 4 * ((low - 100) / 5));
#else
- sp += (1 + (low + 9) / 10);
+ sp += ( 1 + (low + 9) / 10 );
#endif
- return sp;
+ return sp;
}
/// Raises a stat by 1.
@@ -5967,45 +5880,47 @@ int pc_need_status_point(struct map_session_data *sd, int type, int val)
/// Subtracts stat points.
///
/// @param type The stat to change (see enum _sp)
-int pc_statusup(struct map_session_data *sd, int type)
+int pc_statusup(struct map_session_data* sd, int type)
{
- int max, need, val;
+ int max, need, val;
- nullpo_ret(sd);
+ nullpo_ret(sd);
- // check conditions
- need = pc_need_status_point(sd,type,1);
- if (type < SP_STR || type > SP_LUK || need < 0 || need > sd->status.status_point) {
- clif_statusupack(sd,type,0,0);
- return 1;
- }
+ // check conditions
+ need = pc_need_status_point(sd,type,1);
+ if( type < SP_STR || type > SP_LUK || need < 0 || need > sd->status.status_point )
+ {
+ clif_statusupack(sd,type,0,0);
+ return 1;
+ }
- // check limits
- max = pc_maxparameter(sd);
- if (pc_getstat(sd,type) >= max) {
- clif_statusupack(sd,type,0,0);
- return 1;
- }
+ // check limits
+ max = pc_maxparameter(sd);
+ if( pc_getstat(sd,type) >= max )
+ {
+ clif_statusupack(sd,type,0,0);
+ return 1;
+ }
- // set new values
- val = pc_setstat(sd, type, pc_getstat(sd,type) + 1);
- sd->status.status_point -= need;
+ // set new values
+ val = pc_setstat(sd, type, pc_getstat(sd,type) + 1);
+ sd->status.status_point -= need;
- status_calc_pc(sd,0);
+ status_calc_pc(sd,0);
- // update increase cost indicator
- if (need != pc_need_status_point(sd,type,1))
- clif_updatestatus(sd, SP_USTR + type-SP_STR);
+ // update increase cost indicator
+ if( need != pc_need_status_point(sd,type,1) )
+ clif_updatestatus(sd, SP_USTR + type-SP_STR);
- // update statpoint count
- clif_updatestatus(sd,SP_STATUSPOINT);
+ // update statpoint count
+ clif_updatestatus(sd,SP_STATUSPOINT);
- // update stat value
- clif_statusupack(sd,type,1,val); // required
- if (val > 255)
- clif_updatestatus(sd,type); // send after the 'ack' to override the truncated value
+ // update stat value
+ clif_statusupack(sd,type,1,val); // required
+ if( val > 255 )
+ clif_updatestatus(sd,type); // send after the 'ack' to override the truncated value
- return 0;
+ return 0;
}
/// Raises a stat by the specified amount.
@@ -6014,34 +5929,35 @@ int pc_statusup(struct map_session_data *sd, int type)
///
/// @param type The stat to change (see enum _sp)
/// @param val The stat increase amount.
-int pc_statusup2(struct map_session_data *sd, int type, int val)
+int pc_statusup2(struct map_session_data* sd, int type, int val)
{
- int max, need;
- nullpo_ret(sd);
+ int max, need;
+ nullpo_ret(sd);
- if (type < SP_STR || type > SP_LUK) {
- clif_statusupack(sd,type,0,0);
- return 1;
- }
+ if( type < SP_STR || type > SP_LUK )
+ {
+ clif_statusupack(sd,type,0,0);
+ return 1;
+ }
- need = pc_need_status_point(sd,type,1);
+ need = pc_need_status_point(sd,type,1);
- // set new value
- max = pc_maxparameter(sd);
- val = pc_setstat(sd, type, cap_value(pc_getstat(sd,type) + val, 1, max));
+ // set new value
+ max = pc_maxparameter(sd);
+ val = pc_setstat(sd, type, cap_value(pc_getstat(sd,type) + val, 1, max));
- status_calc_pc(sd,0);
+ status_calc_pc(sd,0);
- // update increase cost indicator
- if (need != pc_need_status_point(sd,type,1))
- clif_updatestatus(sd, SP_USTR + type-SP_STR);
+ // update increase cost indicator
+ if( need != pc_need_status_point(sd,type,1) )
+ clif_updatestatus(sd, SP_USTR + type-SP_STR);
- // update stat value
- clif_statusupack(sd,type,1,val); // required
- if (val > 255)
- clif_updatestatus(sd,type); // send after the 'ack' to override the truncated value
+ // update stat value
+ clif_statusupack(sd,type,1,val); // required
+ if( val > 255 )
+ clif_updatestatus(sd,type); // send after the 'ack' to override the truncated value
- return 0;
+ return 0;
}
/*==========================================
@@ -6050,43 +5966,46 @@ int pc_statusup2(struct map_session_data *sd, int type, int val)
*------------------------------------------*/
int pc_skillup(struct map_session_data *sd,int skill_num)
{
- nullpo_ret(sd);
-
- if (skill_num >= GD_SKILLBASE && skill_num < GD_SKILLBASE+MAX_GUILDSKILL) {
- guild_skillup(sd, skill_num);
- return 0;
- }
-
- if (skill_num >= HM_SKILLBASE && skill_num < HM_SKILLBASE+MAX_HOMUNSKILL && sd->hd) {
- merc_hom_skillup(sd->hd, skill_num);
- return 0;
- }
-
- if (skill_num < 0 || skill_num >= MAX_SKILL)
- return 0;
-
- if (sd->status.skill_point > 0 &&
- sd->status.skill[skill_num].id &&
- sd->status.skill[skill_num].flag == SKILL_FLAG_PERMANENT && //Don't allow raising while you have granted skills. [Skotlex]
- sd->status.skill[skill_num].lv < skill_tree_get_max(skill_num, sd->status.class_)) {
- sd->status.skill[skill_num].lv++;
- sd->status.skill_point--;
- if (!skill_get_inf(skill_num))
- status_calc_pc(sd,0); // Only recalculate for passive skills.
- else if (sd->status.skill_point == 0 && (sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc_famerank(sd->status.char_id, MAPID_TAEKWON))
- pc_calc_skilltree(sd); // Required to grant all TK Ranger skills.
- else
- pc_check_skilltree(sd, skill_num); // Check if a new skill can Lvlup
-
- clif_skillup(sd,skill_num);
- clif_updatestatus(sd,SP_SKILLPOINT);
- if (skill_num == GN_REMODELING_CART) /* cart weight info was updated by status_calc_pc */
- clif_updatestatus(sd,SP_CARTINFO);
- if (!pc_has_permission(sd, PC_PERM_ALL_SKILL)) // may skill everything at any time anyways, and this would cause a huge slowdown
- clif_skillinfoblock(sd);
- }
-
- return 0;
+ nullpo_ret(sd);
+
+ if( skill_num >= GD_SKILLBASE && skill_num < GD_SKILLBASE+MAX_GUILDSKILL )
+ {
+ guild_skillup(sd, skill_num);
+ return 0;
+ }
+
+ if( skill_num >= HM_SKILLBASE && skill_num < HM_SKILLBASE+MAX_HOMUNSKILL && sd->hd )
+ {
+ merc_hom_skillup(sd->hd, skill_num);
+ return 0;
+ }
+
+ if( skill_num < 0 || skill_num >= MAX_SKILL )
+ return 0;
+
+ if( sd->status.skill_point > 0 &&
+ sd->status.skill[skill_num].id &&
+ sd->status.skill[skill_num].flag == SKILL_FLAG_PERMANENT && //Don't allow raising while you have granted skills. [Skotlex]
+ sd->status.skill[skill_num].lv < skill_tree_get_max(skill_num, sd->status.class_) )
+ {
+ sd->status.skill[skill_num].lv++;
+ sd->status.skill_point--;
+ if( !skill_get_inf(skill_num) )
+ status_calc_pc(sd,0); // Only recalculate for passive skills.
+ else if( sd->status.skill_point == 0 && (sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc_famerank(sd->status.char_id, MAPID_TAEKWON) )
+ pc_calc_skilltree(sd); // Required to grant all TK Ranger skills.
+ else
+ pc_check_skilltree(sd, skill_num); // Check if a new skill can Lvlup
+
+ clif_skillup(sd,skill_num);
+ clif_updatestatus(sd,SP_SKILLPOINT);
+ if( skill_num == GN_REMODELING_CART ) /* cart weight info was updated by status_calc_pc */
+ clif_updatestatus(sd,SP_CARTINFO);
+ if (!pc_has_permission(sd, PC_PERM_ALL_SKILL)) // may skill everything at any time anyways, and this would cause a huge slowdown
+ clif_skillinfoblock(sd);
+ }
+
+ return 0;
}
/*==========================================
@@ -6094,205 +6013,207 @@ int pc_skillup(struct map_session_data *sd,int skill_num)
*------------------------------------------*/
int pc_allskillup(struct map_session_data *sd)
{
- int i,id;
-
- nullpo_ret(sd);
-
- for (i=0; i<MAX_SKILL; i++) {
- if (sd->status.skill[i].flag != SKILL_FLAG_PERMANENT && sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED) {
- sd->status.skill[i].lv = (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY) ? 0 : sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0;
- sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
- if (sd->status.skill[i].lv == 0)
- sd->status.skill[i].id = 0;
- }
- }
-
- if (pc_has_permission(sd, PC_PERM_ALL_SKILL)) {
- //Get ALL skills except npc/guild ones. [Skotlex]
- //and except SG_DEVIL [Komurka] and MO_TRIPLEATTACK and RG_SNATCHER [ultramage]
- for (i=0; i<MAX_SKILL; i++) {
- switch (i) {
- case SG_DEVIL:
- case MO_TRIPLEATTACK:
- case RG_SNATCHER:
- continue;
- default:
- if (!(skill_get_inf2(i)&(INF2_NPC_SKILL|INF2_GUILD_SKILL)))
- if ((sd->status.skill[i].lv = skill_get_max(i))) //Nonexistant skills should return a max of 0 anyway.
- sd->status.skill[i].id = i;
- }
- }
- } else {
- int inf2;
- for (i=0; i < MAX_SKILL_TREE && (id=skill_tree[pc_class2idx(sd->status.class_)][i].id)>0; i++) {
- inf2 = skill_get_inf2(id);
- if (
- (inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) ||
- (inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL)) ||
- id==SG_DEVIL
- )
- continue; //Cannot be learned normally.
-
- sd->status.skill[id].id = id;
- sd->status.skill[id].lv = skill_tree_get_max(id, sd->status.class_); // celest
- }
- }
- status_calc_pc(sd,0);
- //Required because if you could level up all skills previously,
- //the update will not be sent as only the lv variable changes.
- clif_skillinfoblock(sd);
- return 0;
+ int i,id;
+
+ nullpo_ret(sd);
+
+ for(i=0;i<MAX_SKILL;i++){
+ if (sd->status.skill[i].flag != SKILL_FLAG_PERMANENT && sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED) {
+ sd->status.skill[i].lv = (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY) ? 0 : sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0;
+ sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
+ if (sd->status.skill[i].lv == 0)
+ sd->status.skill[i].id = 0;
+ }
+ }
+
+ if (pc_has_permission(sd, PC_PERM_ALL_SKILL))
+ { //Get ALL skills except npc/guild ones. [Skotlex]
+ //and except SG_DEVIL [Komurka] and MO_TRIPLEATTACK and RG_SNATCHER [ultramage]
+ for(i=0;i<MAX_SKILL;i++){
+ switch( i ) {
+ case SG_DEVIL:
+ case MO_TRIPLEATTACK:
+ case RG_SNATCHER:
+ continue;
+ default:
+ if( !(skill_get_inf2(i)&(INF2_NPC_SKILL|INF2_GUILD_SKILL)) )
+ if ( ( sd->status.skill[i].lv = skill_get_max(i) ) )//Nonexistant skills should return a max of 0 anyway.
+ sd->status.skill[i].id = i;
+ }
+ }
+ } else {
+ int inf2;
+ for(i=0;i < MAX_SKILL_TREE && (id=skill_tree[pc_class2idx(sd->status.class_)][i].id)>0;i++){
+ inf2 = skill_get_inf2(id);
+ if (
+ (inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) ||
+ (inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL)) ||
+ id==SG_DEVIL
+ )
+ continue; //Cannot be learned normally.
+
+ sd->status.skill[id].id = id;
+ sd->status.skill[id].lv = skill_tree_get_max(id, sd->status.class_); // celest
+ }
+ }
+ status_calc_pc(sd,0);
+ //Required because if you could level up all skills previously,
+ //the update will not be sent as only the lv variable changes.
+ clif_skillinfoblock(sd);
+ return 0;
}
/*==========================================
* /resetlvl
*------------------------------------------*/
-int pc_resetlvl(struct map_session_data *sd,int type)
-{
- int i;
-
- nullpo_ret(sd);
-
- if (type != 3) //Also reset skills
- pc_resetskill(sd, 0);
-
- if (type == 1) {
- sd->status.skill_point=0;
- sd->status.base_level=1;
- sd->status.job_level=1;
- sd->status.base_exp=0;
- sd->status.job_exp=0;
- if (sd->sc.option !=0)
- sd->sc.option = 0;
-
- sd->status.str=1;
- sd->status.agi=1;
- sd->status.vit=1;
- sd->status.int_=1;
- sd->status.dex=1;
- sd->status.luk=1;
- if (sd->status.class_ == JOB_NOVICE_HIGH) {
- 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) {
- sd->status.skill_point=0;
- sd->status.base_level=1;
- sd->status.job_level=1;
- sd->status.base_exp=0;
- sd->status.job_exp=0;
- }
- if (type == 3) {
- sd->status.base_level=1;
- sd->status.base_exp=0;
- }
- if (type == 4) {
- sd->status.job_level=1;
- sd->status.job_exp=0;
- }
-
- clif_updatestatus(sd,SP_STATUSPOINT);
- clif_updatestatus(sd,SP_STR);
- clif_updatestatus(sd,SP_AGI);
- clif_updatestatus(sd,SP_VIT);
- clif_updatestatus(sd,SP_INT);
- clif_updatestatus(sd,SP_DEX);
- clif_updatestatus(sd,SP_LUK);
- clif_updatestatus(sd,SP_BASELEVEL);
- clif_updatestatus(sd,SP_JOBLEVEL);
- clif_updatestatus(sd,SP_STATUSPOINT);
- clif_updatestatus(sd,SP_BASEEXP);
- clif_updatestatus(sd,SP_JOBEXP);
- clif_updatestatus(sd,SP_NEXTBASEEXP);
- clif_updatestatus(sd,SP_NEXTJOBEXP);
- clif_updatestatus(sd,SP_SKILLPOINT);
-
- clif_updatestatus(sd,SP_USTR); // Updates needed stat points - Valaris
- clif_updatestatus(sd,SP_UAGI);
- clif_updatestatus(sd,SP_UVIT);
- clif_updatestatus(sd,SP_UINT);
- clif_updatestatus(sd,SP_UDEX);
- clif_updatestatus(sd,SP_ULUK); // End Addition
-
- for (i=0; i<EQI_MAX; 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],2);
- }
-
- if ((type == 1 || type == 2 || type == 3) && sd->status.party_id)
- party_send_levelup(sd);
-
- status_calc_pc(sd,0);
- clif_skillinfoblock(sd);
-
- return 0;
+int pc_resetlvl(struct map_session_data* sd,int type)
+{
+ int i;
+
+ nullpo_ret(sd);
+
+ if (type != 3) //Also reset skills
+ pc_resetskill(sd, 0);
+
+ if(type == 1){
+ sd->status.skill_point=0;
+ sd->status.base_level=1;
+ sd->status.job_level=1;
+ sd->status.base_exp=0;
+ sd->status.job_exp=0;
+ if(sd->sc.option !=0)
+ sd->sc.option = 0;
+
+ sd->status.str=1;
+ sd->status.agi=1;
+ sd->status.vit=1;
+ sd->status.int_=1;
+ sd->status.dex=1;
+ sd->status.luk=1;
+ if(sd->status.class_ == JOB_NOVICE_HIGH) {
+ 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){
+ sd->status.skill_point=0;
+ sd->status.base_level=1;
+ sd->status.job_level=1;
+ sd->status.base_exp=0;
+ sd->status.job_exp=0;
+ }
+ if(type == 3){
+ sd->status.base_level=1;
+ sd->status.base_exp=0;
+ }
+ if(type == 4){
+ sd->status.job_level=1;
+ sd->status.job_exp=0;
+ }
+
+ clif_updatestatus(sd,SP_STATUSPOINT);
+ clif_updatestatus(sd,SP_STR);
+ clif_updatestatus(sd,SP_AGI);
+ clif_updatestatus(sd,SP_VIT);
+ clif_updatestatus(sd,SP_INT);
+ clif_updatestatus(sd,SP_DEX);
+ clif_updatestatus(sd,SP_LUK);
+ clif_updatestatus(sd,SP_BASELEVEL);
+ clif_updatestatus(sd,SP_JOBLEVEL);
+ clif_updatestatus(sd,SP_STATUSPOINT);
+ clif_updatestatus(sd,SP_BASEEXP);
+ clif_updatestatus(sd,SP_JOBEXP);
+ clif_updatestatus(sd,SP_NEXTBASEEXP);
+ clif_updatestatus(sd,SP_NEXTJOBEXP);
+ clif_updatestatus(sd,SP_SKILLPOINT);
+
+ clif_updatestatus(sd,SP_USTR); // Updates needed stat points - Valaris
+ clif_updatestatus(sd,SP_UAGI);
+ clif_updatestatus(sd,SP_UVIT);
+ clif_updatestatus(sd,SP_UINT);
+ clif_updatestatus(sd,SP_UDEX);
+ clif_updatestatus(sd,SP_ULUK); // End Addition
+
+ for(i=0;i<EQI_MAX;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],2);
+ }
+
+ if ((type == 1 || type == 2 || type == 3) && sd->status.party_id)
+ party_send_levelup(sd);
+
+ status_calc_pc(sd,0);
+ clif_skillinfoblock(sd);
+
+ return 0;
}
/*==========================================
* /resetstate
*------------------------------------------*/
-int pc_resetstate(struct map_session_data *sd)
-{
- nullpo_ret(sd);
-
- if (battle_config.use_statpoint_table) {
- // New statpoint table used here - Dexity
- if (sd->status.base_level > MAX_LEVEL) {
- //statp[] goes out of bounds, can't reset!
- ShowError("pc_resetstate: Can't reset stats of %d:%d, the base level (%d) is greater than the max level supported (%d)\n",
- sd->status.account_id, sd->status.char_id, sd->status.base_level, MAX_LEVEL);
- return 0;
- }
-
- sd->status.status_point = statp[sd->status.base_level] + (sd->class_&JOBL_UPPER ? 52 : 0); // extra 52+48=100 stat points
- } else {
- int add=0;
- add += pc_need_status_point(sd, SP_STR, 1-pc_getstat(sd, SP_STR));
- add += pc_need_status_point(sd, SP_AGI, 1-pc_getstat(sd, SP_AGI));
- add += pc_need_status_point(sd, SP_VIT, 1-pc_getstat(sd, SP_VIT));
- add += pc_need_status_point(sd, SP_INT, 1-pc_getstat(sd, SP_INT));
- add += pc_need_status_point(sd, SP_DEX, 1-pc_getstat(sd, SP_DEX));
- add += pc_need_status_point(sd, SP_LUK, 1-pc_getstat(sd, SP_LUK));
-
- sd->status.status_point+=add;
- }
-
- pc_setstat(sd, SP_STR, 1);
- pc_setstat(sd, SP_AGI, 1);
- pc_setstat(sd, SP_VIT, 1);
- pc_setstat(sd, SP_INT, 1);
- pc_setstat(sd, SP_DEX, 1);
- pc_setstat(sd, SP_LUK, 1);
-
- clif_updatestatus(sd,SP_STR);
- clif_updatestatus(sd,SP_AGI);
- clif_updatestatus(sd,SP_VIT);
- clif_updatestatus(sd,SP_INT);
- clif_updatestatus(sd,SP_DEX);
- clif_updatestatus(sd,SP_LUK);
-
- clif_updatestatus(sd,SP_USTR); // Updates needed stat points - Valaris
- clif_updatestatus(sd,SP_UAGI);
- clif_updatestatus(sd,SP_UVIT);
- clif_updatestatus(sd,SP_UINT);
- clif_updatestatus(sd,SP_UDEX);
- clif_updatestatus(sd,SP_ULUK); // End Addition
-
- clif_updatestatus(sd,SP_STATUSPOINT);
-
- if (sd->mission_mobid) { //bugreport:2200
- sd->mission_mobid = 0;
- sd->mission_count = 0;
- pc_setglobalreg(sd,"TK_MISSION_ID", 0);
- }
-
- status_calc_pc(sd,0);
-
- return 1;
+int pc_resetstate(struct map_session_data* sd)
+{
+ nullpo_ret(sd);
+
+ if (battle_config.use_statpoint_table)
+ { // New statpoint table used here - Dexity
+ if (sd->status.base_level > MAX_LEVEL)
+ { //statp[] goes out of bounds, can't reset!
+ ShowError("pc_resetstate: Can't reset stats of %d:%d, the base level (%d) is greater than the max level supported (%d)\n",
+ sd->status.account_id, sd->status.char_id, sd->status.base_level, MAX_LEVEL);
+ return 0;
+ }
+
+ sd->status.status_point = statp[sd->status.base_level] + ( sd->class_&JOBL_UPPER ? 52 : 0 ); // extra 52+48=100 stat points
+ }
+ else
+ {
+ int add=0;
+ add += pc_need_status_point(sd, SP_STR, 1-pc_getstat(sd, SP_STR));
+ add += pc_need_status_point(sd, SP_AGI, 1-pc_getstat(sd, SP_AGI));
+ add += pc_need_status_point(sd, SP_VIT, 1-pc_getstat(sd, SP_VIT));
+ add += pc_need_status_point(sd, SP_INT, 1-pc_getstat(sd, SP_INT));
+ add += pc_need_status_point(sd, SP_DEX, 1-pc_getstat(sd, SP_DEX));
+ add += pc_need_status_point(sd, SP_LUK, 1-pc_getstat(sd, SP_LUK));
+
+ sd->status.status_point+=add;
+ }
+
+ pc_setstat(sd, SP_STR, 1);
+ pc_setstat(sd, SP_AGI, 1);
+ pc_setstat(sd, SP_VIT, 1);
+ pc_setstat(sd, SP_INT, 1);
+ pc_setstat(sd, SP_DEX, 1);
+ pc_setstat(sd, SP_LUK, 1);
+
+ clif_updatestatus(sd,SP_STR);
+ clif_updatestatus(sd,SP_AGI);
+ clif_updatestatus(sd,SP_VIT);
+ clif_updatestatus(sd,SP_INT);
+ clif_updatestatus(sd,SP_DEX);
+ clif_updatestatus(sd,SP_LUK);
+
+ clif_updatestatus(sd,SP_USTR); // Updates needed stat points - Valaris
+ clif_updatestatus(sd,SP_UAGI);
+ clif_updatestatus(sd,SP_UVIT);
+ clif_updatestatus(sd,SP_UINT);
+ clif_updatestatus(sd,SP_UDEX);
+ clif_updatestatus(sd,SP_ULUK); // End Addition
+
+ clif_updatestatus(sd,SP_STATUSPOINT);
+
+ if( sd->mission_mobid ) { //bugreport:2200
+ sd->mission_mobid = 0;
+ sd->mission_count = 0;
+ pc_setglobalreg(sd,"TK_MISSION_ID", 0);
+ }
+
+ status_calc_pc(sd,0);
+
+ return 1;
}
/*==========================================
@@ -6301,215 +6222,210 @@ int pc_resetstate(struct map_session_data *sd)
* if flag&2, just count total amount of skill points used by player, do not really reset.
* if flag&4, just reset the skills if the player class is a bard/dancer type (for changesex.)
*------------------------------------------*/
-int pc_resetskill(struct map_session_data *sd, int flag)
-{
- int i, lv, inf2, skill_point=0;
- nullpo_ret(sd);
-
- if (flag&4 && (sd->class_&MAPID_UPPERMASK) != MAPID_BARDDANCER)
- return 0;
-
- if (!(flag&2)) { //Remove stuff lost when resetting skills.
-
- /**
- * It has been confirmed on official server that when you reset skills with a ranked tweakwon your skills are not reset (because you have all of them anyway)
- **/
- if ((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc_famerank(sd->status.char_id, MAPID_TAEKWON))
- return 0;
-
- if (pc_checkskill(sd, SG_DEVIL) && !pc_nextjobexp(sd))
- clif_status_load(&sd->bl, SI_DEVIL, 0); //Remove perma blindness due to skill-reset. [Skotlex]
- i = sd->sc.option;
- if (i&OPTION_RIDING && pc_checkskill(sd, KN_RIDING))
- i &= ~OPTION_RIDING;
- if (i&OPTION_FALCON && pc_checkskill(sd, HT_FALCON))
- i &= ~OPTION_FALCON;
- if (i&OPTION_DRAGON && pc_checkskill(sd, RK_DRAGONTRAINING))
- i &= ~OPTION_DRAGON;
- if (i&OPTION_WUG && pc_checkskill(sd, RA_WUGMASTERY))
- i &= ~OPTION_WUG;
- if (i&OPTION_WUGRIDER && pc_checkskill(sd, RA_WUGRIDER))
- i &= ~OPTION_WUGRIDER;
- if (i&OPTION_MADOGEAR && (sd->class_&MAPID_THIRDMASK) == MAPID_MECHANIC)
- i &= ~OPTION_MADOGEAR;
- if (i&OPTION_MOUNTING)
- i &= ~OPTION_MOUNTING;
+int pc_resetskill(struct map_session_data* sd, int flag)
+{
+ int i, lv, inf2, skill_point=0;
+ nullpo_ret(sd);
+
+ if( flag&4 && (sd->class_&MAPID_UPPERMASK) != MAPID_BARDDANCER )
+ return 0;
+
+ if( !(flag&2) ) { //Remove stuff lost when resetting skills.
+
+ /**
+ * It has been confirmed on official server that when you reset skills with a ranked tweakwon your skills are not reset (because you have all of them anyway)
+ **/
+ if( (sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc_famerank(sd->status.char_id, MAPID_TAEKWON) )
+ return 0;
+
+ if( pc_checkskill(sd, SG_DEVIL) && !pc_nextjobexp(sd) )
+ clif_status_load(&sd->bl, SI_DEVIL, 0); //Remove perma blindness due to skill-reset. [Skotlex]
+ i = sd->sc.option;
+ if( i&OPTION_RIDING && pc_checkskill(sd, KN_RIDING) )
+ i &= ~OPTION_RIDING;
+ if( i&OPTION_FALCON && pc_checkskill(sd, HT_FALCON) )
+ i &= ~OPTION_FALCON;
+ if( i&OPTION_DRAGON && pc_checkskill(sd, RK_DRAGONTRAINING) )
+ i &= ~OPTION_DRAGON;
+ if( i&OPTION_WUG && pc_checkskill(sd, RA_WUGMASTERY) )
+ i &= ~OPTION_WUG;
+ if( i&OPTION_WUGRIDER && pc_checkskill(sd, RA_WUGRIDER) )
+ i &= ~OPTION_WUGRIDER;
+ if( i&OPTION_MADOGEAR && ( sd->class_&MAPID_THIRDMASK ) == MAPID_MECHANIC )
+ i &= ~OPTION_MADOGEAR;
+ if( i&OPTION_MOUNTING )
+ i &= ~OPTION_MOUNTING;
#ifndef NEW_CARTS
- if (i&OPTION_CART && pc_checkskill(sd, MC_PUSHCART))
- i &= ~OPTION_CART;
+ if( i&OPTION_CART && pc_checkskill(sd, MC_PUSHCART) )
+ i &= ~OPTION_CART;
#else
- if (sd->sc.data[SC_PUSH_CART])
- pc_setcart(sd, 0);
+ if( sd->sc.data[SC_PUSH_CART] )
+ pc_setcart(sd, 0);
#endif
- if (i != sd->sc.option)
- pc_setoption(sd, i);
-
- if (merc_is_hom_active(sd->hd) && pc_checkskill(sd, AM_CALLHOMUN))
- merc_hom_vaporize(sd, 0);
- }
-
- for (i = 1; i < MAX_SKILL; i++) {
- lv = sd->status.skill[i].lv;
- if (lv < 1) continue;
-
- inf2 = skill_get_inf2(i);
-
- if (inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL)) //Avoid reseting wedding/linker skills.
- continue;
-
- // Don't reset trick dead if not a novice/baby
- if (i == NV_TRICKDEAD && (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE) {
- sd->status.skill[i].lv = 0;
- sd->status.skill[i].flag = 0;
- continue;
- }
-
- // do not reset basic skill
- if (i == NV_BASIC && (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE)
- continue;
-
- if (flag&4 && !skill_ischangesex(i))
- continue;
-
- if (inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) {
- //Only handle quest skills in a special way when you can't learn them manually
- if (battle_config.quest_skill_reset && !(flag&2)) {
- //Wipe them
- sd->status.skill[i].lv = 0;
- sd->status.skill[i].flag = 0;
- }
- continue;
- }
- if (sd->status.skill[i].flag == SKILL_FLAG_PERMANENT)
- skill_point += lv;
- else if (sd->status.skill[i].flag >= SKILL_FLAG_REPLACED_LV_0)
- skill_point += (sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0);
-
- if (!(flag&2)) {
- // reset
- sd->status.skill[i].lv = 0;
- sd->status.skill[i].flag = 0;
- }
- }
-
- if (flag&2 || !skill_point) return skill_point;
-
- sd->status.skill_point += skill_point;
-
- if (flag&1) {
- clif_updatestatus(sd,SP_SKILLPOINT);
- clif_skillinfoblock(sd);
- status_calc_pc(sd,0);
- }
-
- return skill_point;
+ if( i != sd->sc.option )
+ pc_setoption(sd, i);
+
+ if( merc_is_hom_active(sd->hd) && pc_checkskill(sd, AM_CALLHOMUN) )
+ merc_hom_vaporize(sd, 0);
+ }
+
+ for( i = 1; i < MAX_SKILL; i++ )
+ {
+ lv = sd->status.skill[i].lv;
+ if (lv < 1) continue;
+
+ inf2 = skill_get_inf2(i);
+
+ if( inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL) ) //Avoid reseting wedding/linker skills.
+ continue;
+
+ // Don't reset trick dead if not a novice/baby
+ if( i == NV_TRICKDEAD && (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE )
+ {
+ sd->status.skill[i].lv = 0;
+ sd->status.skill[i].flag = 0;
+ continue;
+ }
+
+ // do not reset basic skill
+ if( i == NV_BASIC && (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE )
+ continue;
+
+ if( flag&4 && !skill_ischangesex(i) )
+ continue;
+
+ if( inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn )
+ { //Only handle quest skills in a special way when you can't learn them manually
+ if( battle_config.quest_skill_reset && !(flag&2) )
+ { //Wipe them
+ sd->status.skill[i].lv = 0;
+ sd->status.skill[i].flag = 0;
+ }
+ continue;
+ }
+ if( sd->status.skill[i].flag == SKILL_FLAG_PERMANENT )
+ skill_point += lv;
+ else
+ if( sd->status.skill[i].flag >= SKILL_FLAG_REPLACED_LV_0 )
+ skill_point += (sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0);
+
+ if( !(flag&2) )
+ {// reset
+ sd->status.skill[i].lv = 0;
+ sd->status.skill[i].flag = 0;
+ }
+ }
+
+ if( flag&2 || !skill_point ) return skill_point;
+
+ sd->status.skill_point += skill_point;
+
+ if( flag&1 )
+ {
+ clif_updatestatus(sd,SP_SKILLPOINT);
+ clif_skillinfoblock(sd);
+ status_calc_pc(sd,0);
+ }
+
+ return skill_point;
}
/*==========================================
* /resetfeel [Komurka]
*------------------------------------------*/
-int pc_resetfeel(struct map_session_data *sd)
+int pc_resetfeel(struct map_session_data* sd)
{
- int i;
- nullpo_ret(sd);
+ int i;
+ nullpo_ret(sd);
- for (i=0; i<MAX_PC_FEELHATE; i++) {
- sd->feel_map[i].m = -1;
- sd->feel_map[i].index = 0;
- pc_setglobalreg(sd,sg_info[i].feel_var,0);
- }
+ for (i=0; i<MAX_PC_FEELHATE; i++)
+ {
+ sd->feel_map[i].m = -1;
+ sd->feel_map[i].index = 0;
+ pc_setglobalreg(sd,sg_info[i].feel_var,0);
+ }
- return 0;
+ return 0;
}
-int pc_resethate(struct map_session_data *sd)
+int pc_resethate(struct map_session_data* sd)
{
- int i;
- nullpo_ret(sd);
+ int i;
+ nullpo_ret(sd);
- for (i=0; i<3; i++) {
- sd->hate_mob[i] = -1;
- pc_setglobalreg(sd,sg_info[i].hate_var,0);
- }
- return 0;
+ for (i=0; i<3; i++)
+ {
+ sd->hate_mob[i] = -1;
+ pc_setglobalreg(sd,sg_info[i].hate_var,0);
+ }
+ return 0;
}
int pc_skillatk_bonus(struct map_session_data *sd, int skill_num)
{
- int i, bonus = 0;
+ int i, bonus = 0;
- ARR_FIND(0, ARRAYLENGTH(sd->skillatk), i, sd->skillatk[i].id == skill_num);
- if (i < ARRAYLENGTH(sd->skillatk)) bonus = sd->skillatk[i].val;
+ ARR_FIND(0, ARRAYLENGTH(sd->skillatk), i, sd->skillatk[i].id == skill_num);
+ if( i < ARRAYLENGTH(sd->skillatk) ) bonus = sd->skillatk[i].val;
- return bonus;
+ return bonus;
}
-int pc_skillheal_bonus(struct map_session_data *sd, int skill_num)
-{
- int i, bonus = sd->bonus.add_heal_rate;
+int pc_skillheal_bonus(struct map_session_data *sd, int skill_num) {
+ int i, bonus = sd->bonus.add_heal_rate;
- if (bonus) {
- switch (skill_num) {
- case AL_HEAL:
- if (!(battle_config.skill_add_heal_rate&1)) bonus = 0;
- break;
- case PR_SANCTUARY:
- if (!(battle_config.skill_add_heal_rate&2)) bonus = 0;
- break;
- case AM_POTIONPITCHER:
- if (!(battle_config.skill_add_heal_rate&4)) bonus = 0;
- break;
- case CR_SLIMPITCHER:
- if (!(battle_config.skill_add_heal_rate&8)) bonus = 0;
- break;
- case BA_APPLEIDUN:
- if (!(battle_config.skill_add_heal_rate&16)) bonus = 0;
- break;
- }
- }
+ if( bonus ) {
+ switch( skill_num ) {
+ case AL_HEAL: if( !(battle_config.skill_add_heal_rate&1) ) bonus = 0; break;
+ case PR_SANCTUARY: if( !(battle_config.skill_add_heal_rate&2) ) bonus = 0; break;
+ case AM_POTIONPITCHER: if( !(battle_config.skill_add_heal_rate&4) ) bonus = 0; break;
+ case CR_SLIMPITCHER: if( !(battle_config.skill_add_heal_rate&8) ) bonus = 0; break;
+ case BA_APPLEIDUN: if( !(battle_config.skill_add_heal_rate&16)) bonus = 0; break;
+ }
+ }
- ARR_FIND(0, ARRAYLENGTH(sd->skillheal), i, sd->skillheal[i].id == skill_num);
+ ARR_FIND(0, ARRAYLENGTH(sd->skillheal), i, sd->skillheal[i].id == skill_num);
- if (i < ARRAYLENGTH(sd->skillheal))
- bonus += sd->skillheal[i].val;
+ if( i < ARRAYLENGTH(sd->skillheal) )
+ bonus += sd->skillheal[i].val;
- return bonus;
+ return bonus;
}
-int pc_skillheal2_bonus(struct map_session_data *sd, int skill_num)
-{
- int i, bonus = sd->bonus.add_heal2_rate;
+int pc_skillheal2_bonus(struct map_session_data *sd, int skill_num) {
+ int i, bonus = sd->bonus.add_heal2_rate;
- ARR_FIND(0, ARRAYLENGTH(sd->skillheal2), i, sd->skillheal2[i].id == skill_num);
+ ARR_FIND(0, ARRAYLENGTH(sd->skillheal2), i, sd->skillheal2[i].id == skill_num);
- if (i < ARRAYLENGTH(sd->skillheal2))
- bonus += sd->skillheal2[i].val;
+ if( i < ARRAYLENGTH(sd->skillheal2) )
+ bonus += sd->skillheal2[i].val;
- return bonus;
+ return bonus;
}
-void pc_respawn(struct map_session_data *sd, clr_type clrtype)
+void pc_respawn(struct map_session_data* sd, clr_type clrtype)
{
- if (!pc_isdead(sd))
- return; // not applicable
- if (sd->bg_id && bg_member_respawn(sd))
- return; // member revived by battleground
+ if( !pc_isdead(sd) )
+ return; // not applicable
+ if( sd->bg_id && bg_member_respawn(sd) )
+ return; // member revived by battleground
- pc_setstand(sd);
- pc_setrestartvalue(sd,3);
- if (pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, clrtype))
- clif_resurrection(&sd->bl, 1); //If warping fails, send a normal stand up packet.
+ pc_setstand(sd);
+ pc_setrestartvalue(sd,3);
+ if( pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, clrtype) )
+ clif_resurrection(&sd->bl, 1); //If warping fails, send a normal stand up packet.
}
static int pc_respawn_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- struct map_session_data *sd = map_id2sd(id);
- if (sd != NULL) {
- sd->pvp_point=0;
- pc_respawn(sd,CLR_OUTSIGHT);
- }
+ struct map_session_data *sd = map_id2sd(id);
+ if( sd != NULL )
+ {
+ sd->pvp_point=0;
+ pc_respawn(sd,CLR_OUTSIGHT);
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -6517,28 +6433,29 @@ static int pc_respawn_timer(int tid, unsigned int tick, int id, intptr_t data)
*------------------------------------------*/
void pc_damage(struct map_session_data *sd,struct block_list *src,unsigned int hp, unsigned int sp)
{
- if (sp) clif_updatestatus(sd,SP_SP);
- if (hp) clif_updatestatus(sd,SP_HP);
- else return;
+ if (sp) clif_updatestatus(sd,SP_SP);
+ if (hp) clif_updatestatus(sd,SP_HP);
+ else return;
- if (!src || src == &sd->bl)
- return;
+ if( !src || src == &sd->bl )
+ return;
- if (pc_issit(sd)) {
- pc_setstand(sd);
- skill_sit(sd,0);
- }
+ if( pc_issit(sd) )
+ {
+ pc_setstand(sd);
+ skill_sit(sd,0);
+ }
- if (sd->progressbar.npc_id)
- clif_progressbar_abort(sd);
+ if( sd->progressbar.npc_id )
+ clif_progressbar_abort(sd);
- if (sd->status.pet_id > 0 && sd->pd && battle_config.pet_damage_support)
- pet_target_check(sd,src,1);
+ if( sd->status.pet_id > 0 && sd->pd && battle_config.pet_damage_support )
+ pet_target_check(sd,src,1);
- if (sd->status.ele_id > 0)
- elemental_set_target(sd,src);
+ if( sd->status.ele_id > 0 )
+ elemental_set_target(sd,src);
- sd->canlog_tick = gettick();
+ sd->canlog_tick = gettick();
}
/*==========================================
@@ -6546,451 +6463,398 @@ void pc_damage(struct map_session_data *sd,struct block_list *src,unsigned int h
*------------------------------------------*/
int pc_dead(struct map_session_data *sd,struct block_list *src)
{
- int i=0,j=0,k=0;
- unsigned int tick = gettick();
-
- for (k = 0; k < 5; k++)
- if (sd->devotion[k]) {
- struct map_session_data *devsd = map_id2sd(sd->devotion[k]);
- if (devsd)
- status_change_end(&devsd->bl, SC_DEVOTION, INVALID_TIMER);
- sd->devotion[k] = 0;
- }
-
- if (sd->status.pet_id > 0 && sd->pd) {
- struct pet_data *pd = sd->pd;
- if (!map[sd->bl.m].flag.noexppenalty) {
- pet_set_intimate(pd, pd->pet.intimate - pd->petDB->die);
- if (pd->pet.intimate < 0)
- pd->pet.intimate = 0;
- clif_send_petdata(sd,sd->pd,1,pd->pet.intimate);
- }
- if (sd->pd->target_id) // Unlock all targets...
- pet_unlocktarget(sd->pd);
- }
-
- if (sd->status.hom_id > 0) {
- if (battle_config.homunculus_auto_vapor && sd->hd && !sd->hd->sc.data[SC_LIGHT_OF_REGENE])
- merc_hom_vaporize(sd, 0);
- }
-
- if (sd->md)
- merc_delete(sd->md, 3); // Your mercenary soldier has ran away.
-
- if (sd->ed)
- elemental_delete(sd->ed, 0);
-
- // Leave duel if you die [LuzZza]
- if (battle_config.duel_autoleave_when_die) {
- if (sd->duel_group > 0)
- duel_leave(sd->duel_group, sd);
- if (sd->duel_invite > 0)
- duel_reject(sd->duel_invite, sd);
- }
-
- pc_setglobalreg(sd,"PC_DIE_COUNTER",sd->die_counter+1);
- pc_setparam(sd, SP_KILLERRID, src?src->id:0);
-
- if (sd->bg_id) {
- struct battleground_data *bg;
- if ((bg = bg_team_search(sd->bg_id)) != NULL && bg->die_event[0])
- npc_event(sd, bg->die_event, 0);
- }
-
- // Clear anything NPC-related when you die and was interacting with one.
- if (sd->npc_id) {
- if (sd->state.using_fake_npc){
- clif_clearunit_single(sd->npc_id, CLR_OUTSIGHT, sd->fd);
- sd->state.using_fake_npc = 0;
- }
- if (sd->state.menu_or_input)
- sd->state.menu_or_input = 0;
- if (sd->npc_menu)
- sd->npc_menu = 0;
- sd->npc_id = 0;
- if(sd->st && sd->st->state != END)
- sd->st->state = END;
- }
-
- npc_script_event(sd,NPCE_DIE);
-
- /* e.g. not killed thru pc_damage */
- if (pc_issit(sd)) {
- clif_status_load(&sd->bl,SI_SIT,0);
- }
-
- pc_setdead(sd);
- //Reset menu skills/item skills
- if (sd->skillitem)
- sd->skillitem = sd->skillitemlv = 0;
- if (sd->menuskill_id)
- sd->menuskill_id = sd->menuskill_val = 0;
- //Reset ticks.
- sd->hp_loss.tick = sd->sp_loss.tick = sd->hp_regen.tick = sd->sp_regen.tick = 0;
-
- if (sd && sd->spiritball)
- pc_delspiritball(sd,sd->spiritball,0);
-
- for (i = 1; i < 5; i++)
- pc_del_talisman(sd, sd->talisman[i], i);
-
- if (src)
- switch (src->type) {
- case BL_MOB: {
- struct mob_data *md=(struct mob_data *)src;
- if (md->target_id==sd->bl.id)
- mob_unlocktarget(md,tick);
- if (battle_config.mobs_level_up && md->status.hp &&
- (unsigned int)md->level < pc_maxbaselv(sd) &&
- !md->guardian_data && !md->special_state.ai// Guardians/summons should not level. [Skotlex]
- ) { // monster level up [Valaris]
- clif_misceffect(&md->bl,0);
- md->level++;
- status_calc_mob(md, 0);
- status_percent_heal(src,10,0);
-
- if (battle_config.show_mob_info&4) {
- // update name with new level
- clif_charnameack(0, &md->bl);
- }
- }
- src = battle_get_master(src); // Maybe Player Summon
- }
- break;
- case BL_PET: //Pass on to master...
- src = &((TBL_PET *)src)->msd->bl;
- break;
- case BL_HOM:
- src = &((TBL_HOM *)src)->master->bl;
- break;
- case BL_MER:
- src = &((TBL_MER *)src)->master->bl;
- break;
- }
-
- if (src && src->type == BL_PC) {
- struct map_session_data *ssd = (struct map_session_data *)src;
- pc_setparam(ssd, SP_KILLEDRID, sd->bl.id);
- npc_script_event(ssd, NPCE_KILLPC);
-
- if (battle_config.pk_mode&2) {
- ssd->status.manner -= 5;
- if (ssd->status.manner < 0)
- sc_start(src,SC_NOCHAT,100,0,0);
+ int i=0,j=0,k=0;
+ unsigned int tick = gettick();
+
+ for(k = 0; k < 5; k++)
+ if (sd->devotion[k]){
+ struct map_session_data *devsd = map_id2sd(sd->devotion[k]);
+ if (devsd)
+ status_change_end(&devsd->bl, SC_DEVOTION, INVALID_TIMER);
+ sd->devotion[k] = 0;
+ }
+
+ if(sd->status.pet_id > 0 && sd->pd) {
+ struct pet_data *pd = sd->pd;
+ if( !map[sd->bl.m].flag.noexppenalty ) {
+ pet_set_intimate(pd, pd->pet.intimate - pd->petDB->die);
+ if( pd->pet.intimate < 0 )
+ pd->pet.intimate = 0;
+ clif_send_petdata(sd,sd->pd,1,pd->pet.intimate);
+ }
+ if( sd->pd->target_id ) // Unlock all targets...
+ pet_unlocktarget(sd->pd);
+ }
+
+ if (sd->status.hom_id > 0){
+ if(battle_config.homunculus_auto_vapor && sd->hd && !sd->hd->sc.data[SC_LIGHT_OF_REGENE])
+ merc_hom_vaporize(sd, 0);
+ }
+
+ if( sd->md )
+ merc_delete(sd->md, 3); // Your mercenary soldier has ran away.
+
+ if( sd->ed )
+ elemental_delete(sd->ed, 0);
+
+ // Leave duel if you die [LuzZza]
+ if(battle_config.duel_autoleave_when_die) {
+ if(sd->duel_group > 0)
+ duel_leave(sd->duel_group, sd);
+ if(sd->duel_invite > 0)
+ duel_reject(sd->duel_invite, sd);
+ }
+
+ pc_setglobalreg(sd,"PC_DIE_COUNTER",sd->die_counter+1);
+ pc_setparam(sd, SP_KILLERRID, src?src->id:0);
+
+ if( sd->bg_id ) {
+ struct battleground_data *bg;
+ if( (bg = bg_team_search(sd->bg_id)) != NULL && bg->die_event[0] )
+ npc_event(sd, bg->die_event, 0);
+ }
+
+ // Clear anything NPC-related when you die and was interacting with one.
+ if (sd->npc_id)
+ {
+ if (sd->state.using_fake_npc)
+ sd->state.using_fake_npc = 0;
+ if (sd->state.menu_or_input)
+ sd->state.menu_or_input = 0;
+ if (sd->npc_menu)
+ sd->npc_menu = 0;
+
+ npc_event_dequeue(sd);
+ }
+
+ npc_script_event(sd,NPCE_DIE);
+
+ /* e.g. not killed thru pc_damage */
+ if( pc_issit(sd) ) {
+ clif_status_load(&sd->bl,SI_SIT,0);
+ }
+
+ pc_setdead(sd);
+ //Reset menu skills/item skills
+ if (sd->skillitem)
+ sd->skillitem = sd->skillitemlv = 0;
+ if (sd->menuskill_id)
+ sd->menuskill_id = sd->menuskill_val = 0;
+ //Reset ticks.
+ sd->hp_loss.tick = sd->sp_loss.tick = sd->hp_regen.tick = sd->sp_regen.tick = 0;
+
+ if ( sd && sd->spiritball )
+ pc_delspiritball(sd,sd->spiritball,0);
+
+ for(i = 1; i < 5; i++)
+ pc_del_talisman(sd, sd->talisman[i], i);
+
+ if (src)
+ switch (src->type) {
+ case BL_MOB:
+ {
+ struct mob_data *md=(struct mob_data *)src;
+ if(md->target_id==sd->bl.id)
+ mob_unlocktarget(md,tick);
+ if(battle_config.mobs_level_up && md->status.hp &&
+ (unsigned int)md->level < pc_maxbaselv(sd) &&
+ !md->guardian_data && !md->special_state.ai// Guardians/summons should not level. [Skotlex]
+ ) { // monster level up [Valaris]
+ clif_misceffect(&md->bl,0);
+ md->level++;
+ status_calc_mob(md, 0);
+ status_percent_heal(src,10,0);
+
+ if( battle_config.show_mob_info&4 )
+ {// update name with new level
+ clif_charnameack(0, &md->bl);
+ }
+ }
+ src = battle_get_master(src); // Maybe Player Summon
+ }
+ break;
+ case BL_PET: //Pass on to master...
+ src = &((TBL_PET*)src)->msd->bl;
+ break;
+ case BL_HOM:
+ src = &((TBL_HOM*)src)->master->bl;
+ break;
+ case BL_MER:
+ src = &((TBL_MER*)src)->master->bl;
+ break;
+ }
+
+ if (src && src->type == BL_PC)
+ {
+ struct map_session_data *ssd = (struct map_session_data *)src;
+ pc_setparam(ssd, SP_KILLEDRID, sd->bl.id);
+ npc_script_event(ssd, NPCE_KILLPC);
+
+ if (battle_config.pk_mode&2) {
+ ssd->status.manner -= 5;
+ if(ssd->status.manner < 0)
+ sc_start(src,SC_NOCHAT,100,0,0);
#if 0
- // PK/Karma system code (not enabled yet) [celest]
- // originally from Kade Online, so i don't know if any of these is correct ^^;
- // note: karma is measured REVERSE, so more karma = more 'evil' / less honourable,
- // karma going down = more 'good' / more honourable.
- // The Karma System way...
+ // PK/Karma system code (not enabled yet) [celest]
+ // originally from Kade Online, so i don't know if any of these is correct ^^;
+ // note: karma is measured REVERSE, so more karma = more 'evil' / less honourable,
+ // karma going down = more 'good' / more honourable.
+ // The Karma System way...
- if (sd->status.karma > ssd->status.karma) { // If player killed was more evil
- sd->status.karma--;
- ssd->status.karma--;
- } else if (sd->status.karma < ssd->status.karma) // If player killed was more good
- ssd->status.karma++;
+ if (sd->status.karma > ssd->status.karma) { // If player killed was more evil
+ sd->status.karma--;
+ ssd->status.karma--;
+ }
+ else if (sd->status.karma < ssd->status.karma) // If player killed was more good
+ ssd->status.karma++;
- // or the PK System way...
+ // or the PK System way...
- if (sd->status.karma > 0) // player killed is dishonourable?
- ssd->status.karma--; // honour points earned
- sd->status.karma++; // honour points lost
+ if (sd->status.karma > 0) // player killed is dishonourable?
+ ssd->status.karma--; // honour points earned
+ sd->status.karma++; // honour points lost
- // To-do: Receive exp on certain occasions
+ // To-do: Receive exp on certain occasions
#endif
- }
- }
-
- if (battle_config.bone_drop==2
- || (battle_config.bone_drop==1 && map[sd->bl.m].flag.pvp)) {
- struct item item_tmp;
- memset(&item_tmp,0,sizeof(item_tmp));
- item_tmp.nameid=ITEMID_SKULL_;
- item_tmp.identify=1;
- item_tmp.card[0]=CARD0_CREATE;
- item_tmp.card[1]=0;
- item_tmp.card[2]=GetWord(sd->status.char_id,0); // CharId
- item_tmp.card[3]=GetWord(sd->status.char_id,1);
- map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
- }
-
- // activate Steel body if a super novice dies at 99+% exp [celest]
- if ((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && !sd->state.snovice_dead_flag) {
- unsigned int next = pc_nextbaseexp(sd);
- if (next == 0) next = pc_thisbaseexp(sd);
- if (get_percentage(sd->status.base_exp,next) >= 99) {
- sd->state.snovice_dead_flag = 1;
- pc_setstand(sd);
- status_percent_heal(&sd->bl, 100, 100);
- clif_resurrection(&sd->bl, 1);
- if (battle_config.pc_invincible_time)
- pc_setinvincibletimer(sd, battle_config.pc_invincible_time);
- sc_start(&sd->bl,status_skill2sc(MO_STEELBODY),100,1,skill_get_time(MO_STEELBODY,1));
- if (map_flag_gvg(sd->bl.m))
- pc_respawn_timer(INVALID_TIMER, gettick(), sd->bl.id, 0);
- return 0;
- }
- }
-
- // changed penalty options, added death by player if pk_mode [Valaris]
- if (battle_config.death_penalty_type
- && (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE // only novices will receive no penalty
- && !map[sd->bl.m].flag.noexppenalty && !map_flag_gvg(sd->bl.m)
- && !sd->sc.data[SC_BABY] && !sd->sc.data[SC_LIFEINSURANCE]) {
- unsigned int base_penalty =0;
- if (battle_config.death_penalty_base > 0) {
- switch (battle_config.death_penalty_type) {
- case 1:
- base_penalty = (unsigned int)((double)pc_nextbaseexp(sd) * (double)battle_config.death_penalty_base/10000);
- break;
- case 2:
- base_penalty = (unsigned int)((double)sd->status.base_exp * (double)battle_config.death_penalty_base/10000);
- break;
- }
- if (base_penalty) {
- if (battle_config.pk_mode && src && src->type==BL_PC)
- base_penalty*=2;
- sd->status.base_exp -= min(sd->status.base_exp, base_penalty);
- clif_updatestatus(sd,SP_BASEEXP);
- }
- }
- if (battle_config.death_penalty_job > 0) {
- base_penalty = 0;
- switch (battle_config.death_penalty_type) {
- case 1:
- base_penalty = (unsigned int)((double)pc_nextjobexp(sd) * (double)battle_config.death_penalty_job/10000);
- break;
- case 2:
- base_penalty = (unsigned int)((double)sd->status.job_exp * (double)battle_config.death_penalty_job/10000);
- break;
- }
- if (base_penalty) {
- if (battle_config.pk_mode && src && src->type==BL_PC)
- base_penalty*=2;
- sd->status.job_exp -= min(sd->status.job_exp, base_penalty);
- clif_updatestatus(sd,SP_JOBEXP);
- }
- }
- if (battle_config.zeny_penalty > 0 && !map[sd->bl.m].flag.nozenypenalty) {
- base_penalty = (unsigned int)((double)sd->status.zeny * (double)battle_config.zeny_penalty / 10000.);
- if (base_penalty)
- pc_payzeny(sd, base_penalty, LOG_TYPE_PICKDROP_PLAYER, NULL);
- }
- }
-
- if (map[sd->bl.m].flag.pvp_nightmaredrop) {
- // Moved this outside so it works when PVP isn't enabled and during pk mode [Ancyker]
- for (j=0; j<MAX_DROP_PER_MAP; j++) {
- int id = map[sd->bl.m].drop_list[j].drop_id;
- int type = map[sd->bl.m].drop_list[j].drop_type;
- int per = map[sd->bl.m].drop_list[j].drop_per;
- if (id == 0)
- continue;
- if (id == -1) {
- int eq_num=0,eq_n[MAX_INVENTORY];
- memset(eq_n,0,sizeof(eq_n));
- for (i=0; i<MAX_INVENTORY; i++) {
- int k;
- if ((type == 1 && !sd->status.inventory[i].equip)
- || (type == 2 && sd->status.inventory[i].equip)
- || type == 3) {
- ARR_FIND(0, MAX_INVENTORY, k, eq_n[k] <= 0);
- if (k < MAX_INVENTORY)
- eq_n[k] = i;
-
- eq_num++;
- }
- }
- if (eq_num > 0) {
- int n = eq_n[rnd()%eq_num];
- if (rnd()%10000 < per) {
- if (sd->status.inventory[n].equip)
- pc_unequipitem(sd,n,3);
- pc_dropitem(sd,n,1);
- }
- }
- } else if (id > 0) {
- for (i=0; i<MAX_INVENTORY; i++) {
- if (sd->status.inventory[i].nameid == id
- && rnd()%10000 < per
- && ((type == 1 && !sd->status.inventory[i].equip)
- || (type == 2 && sd->status.inventory[i].equip)
- || type == 3)) {
- if (sd->status.inventory[i].equip)
- pc_unequipitem(sd,i,3);
- pc_dropitem(sd,i,1);
- break;
- }
- }
- }
- }
- }
- // pvp
- // disable certain pvp functions on pk_mode [Valaris]
- if (map[sd->bl.m].flag.pvp && !battle_config.pk_mode && !map[sd->bl.m].flag.pvp_nocalcrank) {
- sd->pvp_point -= 5;
- sd->pvp_lost++;
- if (src && src->type == BL_PC) {
- struct map_session_data *ssd = (struct map_session_data *)src;
- ssd->pvp_point++;
- ssd->pvp_won++;
- }
- if (sd->pvp_point < 0) {
- add_timer(tick+1000, pc_respawn_timer,sd->bl.id,0);
- return 1|8;
- }
- }
- //GvG
- if (map_flag_gvg(sd->bl.m)) {
- add_timer(tick+1000, pc_respawn_timer, sd->bl.id, 0);
- return 1|8;
- } else if (sd->bg_id) {
- struct battleground_data *bg = bg_team_search(sd->bg_id);
- if (bg && bg->mapindex > 0) {
- // Respawn by BG
- add_timer(tick+1000, pc_respawn_timer, sd->bl.id, 0);
- return 1|8;
- }
- }
-
-
- //Reset "can log out" tick.
- if (battle_config.prevent_logout)
- sd->canlog_tick = gettick() - battle_config.prevent_logout;
- return 1;
-}
-
-void pc_revive(struct map_session_data *sd,unsigned int hp, unsigned int sp)
-{
- if (hp) clif_updatestatus(sd,SP_HP);
- if (sp) clif_updatestatus(sd,SP_SP);
-
- pc_setstand(sd);
- if (battle_config.pc_invincible_time > 0)
- pc_setinvincibletimer(sd, battle_config.pc_invincible_time);
-
- if (sd->state.gmaster_flag) {
- guild_guildaura_refresh(sd,GD_LEADERSHIP,guild_checkskill(sd->state.gmaster_flag,GD_LEADERSHIP));
- guild_guildaura_refresh(sd,GD_GLORYWOUNDS,guild_checkskill(sd->state.gmaster_flag,GD_GLORYWOUNDS));
- guild_guildaura_refresh(sd,GD_SOULCOLD,guild_checkskill(sd->state.gmaster_flag,GD_SOULCOLD));
- guild_guildaura_refresh(sd,GD_HAWKEYES,guild_checkskill(sd->state.gmaster_flag,GD_HAWKEYES));
- }
+ }
+ }
+
+ if(battle_config.bone_drop==2
+ || (battle_config.bone_drop==1 && map[sd->bl.m].flag.pvp))
+ {
+ struct item item_tmp;
+ memset(&item_tmp,0,sizeof(item_tmp));
+ item_tmp.nameid=ITEMID_SKULL_;
+ item_tmp.identify=1;
+ item_tmp.card[0]=CARD0_CREATE;
+ item_tmp.card[1]=0;
+ item_tmp.card[2]=GetWord(sd->status.char_id,0); // CharId
+ item_tmp.card[3]=GetWord(sd->status.char_id,1);
+ map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ }
+
+ // activate Steel body if a super novice dies at 99+% exp [celest]
+ if ((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && !sd->state.snovice_dead_flag)
+ {
+ unsigned int next = pc_nextbaseexp(sd);
+ if( next == 0 ) next = pc_thisbaseexp(sd);
+ if( get_percentage(sd->status.base_exp,next) >= 99 ) {
+ sd->state.snovice_dead_flag = 1;
+ pc_setstand(sd);
+ status_percent_heal(&sd->bl, 100, 100);
+ clif_resurrection(&sd->bl, 1);
+ if(battle_config.pc_invincible_time)
+ pc_setinvincibletimer(sd, battle_config.pc_invincible_time);
+ sc_start(&sd->bl,status_skill2sc(MO_STEELBODY),100,1,skill_get_time(MO_STEELBODY,1));
+ if(map_flag_gvg(sd->bl.m))
+ pc_respawn_timer(INVALID_TIMER, gettick(), sd->bl.id, 0);
+ return 0;
+ }
+ }
+
+ // changed penalty options, added death by player if pk_mode [Valaris]
+ if(battle_config.death_penalty_type
+ && (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE // only novices will receive no penalty
+ && !map[sd->bl.m].flag.noexppenalty && !map_flag_gvg(sd->bl.m)
+ && !sd->sc.data[SC_BABY] && !sd->sc.data[SC_LIFEINSURANCE])
+ {
+ unsigned int base_penalty =0;
+ if (battle_config.death_penalty_base > 0) {
+ switch (battle_config.death_penalty_type) {
+ case 1:
+ base_penalty = (unsigned int) ((double)pc_nextbaseexp(sd) * (double)battle_config.death_penalty_base/10000);
+ break;
+ case 2:
+ base_penalty = (unsigned int) ((double)sd->status.base_exp * (double)battle_config.death_penalty_base/10000);
+ break;
+ }
+ if(base_penalty) {
+ if (battle_config.pk_mode && src && src->type==BL_PC)
+ base_penalty*=2;
+ sd->status.base_exp -= min(sd->status.base_exp, base_penalty);
+ clif_updatestatus(sd,SP_BASEEXP);
+ }
+ }
+ if(battle_config.death_penalty_job > 0)
+ {
+ base_penalty = 0;
+ switch (battle_config.death_penalty_type) {
+ case 1:
+ base_penalty = (unsigned int) ((double)pc_nextjobexp(sd) * (double)battle_config.death_penalty_job/10000);
+ break;
+ case 2:
+ base_penalty = (unsigned int) ((double)sd->status.job_exp * (double)battle_config.death_penalty_job/10000);
+ break;
+ }
+ if(base_penalty) {
+ if (battle_config.pk_mode && src && src->type==BL_PC)
+ base_penalty*=2;
+ sd->status.job_exp -= min(sd->status.job_exp, base_penalty);
+ clif_updatestatus(sd,SP_JOBEXP);
+ }
+ }
+ if(battle_config.zeny_penalty > 0 && !map[sd->bl.m].flag.nozenypenalty)
+ {
+ base_penalty = (unsigned int)((double)sd->status.zeny * (double)battle_config.zeny_penalty / 10000.);
+ if(base_penalty)
+ pc_payzeny(sd, base_penalty, LOG_TYPE_PICKDROP_PLAYER, NULL);
+ }
+ }
+
+ if(map[sd->bl.m].flag.pvp_nightmaredrop)
+ { // Moved this outside so it works when PVP isn't enabled and during pk mode [Ancyker]
+ for(j=0;j<MAX_DROP_PER_MAP;j++){
+ int id = map[sd->bl.m].drop_list[j].drop_id;
+ int type = map[sd->bl.m].drop_list[j].drop_type;
+ int per = map[sd->bl.m].drop_list[j].drop_per;
+ if(id == 0)
+ continue;
+ if(id == -1){
+ int eq_num=0,eq_n[MAX_INVENTORY];
+ memset(eq_n,0,sizeof(eq_n));
+ for(i=0;i<MAX_INVENTORY;i++){
+ int k;
+ if( (type == 1 && !sd->status.inventory[i].equip)
+ || (type == 2 && sd->status.inventory[i].equip)
+ || type == 3)
+ {
+ ARR_FIND( 0, MAX_INVENTORY, k, eq_n[k] <= 0 );
+ if( k < MAX_INVENTORY )
+ eq_n[k] = i;
+
+ eq_num++;
+ }
+ }
+ if(eq_num > 0){
+ int n = eq_n[rnd()%eq_num];
+ if(rnd()%10000 < per){
+ if(sd->status.inventory[n].equip)
+ pc_unequipitem(sd,n,3);
+ pc_dropitem(sd,n,1);
+ }
+ }
+ }
+ else if(id > 0){
+ for(i=0;i<MAX_INVENTORY;i++){
+ if(sd->status.inventory[i].nameid == id
+ && rnd()%10000 < per
+ && ((type == 1 && !sd->status.inventory[i].equip)
+ || (type == 2 && sd->status.inventory[i].equip)
+ || type == 3) ){
+ if(sd->status.inventory[i].equip)
+ pc_unequipitem(sd,i,3);
+ pc_dropitem(sd,i,1);
+ break;
+ }
+ }
+ }
+ }
+ }
+ // pvp
+ // disable certain pvp functions on pk_mode [Valaris]
+ if( map[sd->bl.m].flag.pvp && !battle_config.pk_mode && !map[sd->bl.m].flag.pvp_nocalcrank )
+ {
+ sd->pvp_point -= 5;
+ sd->pvp_lost++;
+ if( src && src->type == BL_PC )
+ {
+ struct map_session_data *ssd = (struct map_session_data *)src;
+ ssd->pvp_point++;
+ ssd->pvp_won++;
+ }
+ if( sd->pvp_point < 0 )
+ {
+ add_timer(tick+1000, pc_respawn_timer,sd->bl.id,0);
+ return 1|8;
+ }
+ }
+ //GvG
+ if( map_flag_gvg(sd->bl.m) )
+ {
+ add_timer(tick+1000, pc_respawn_timer, sd->bl.id, 0);
+ return 1|8;
+ }
+ else if( sd->bg_id )
+ {
+ struct battleground_data *bg = bg_team_search(sd->bg_id);
+ if( bg && bg->mapindex > 0 )
+ { // Respawn by BG
+ add_timer(tick+1000, pc_respawn_timer, sd->bl.id, 0);
+ return 1|8;
+ }
+ }
+
+
+ //Reset "can log out" tick.
+ if( battle_config.prevent_logout )
+ sd->canlog_tick = gettick() - battle_config.prevent_logout;
+ return 1;
+}
+
+void pc_revive(struct map_session_data *sd,unsigned int hp, unsigned int sp) {
+ if(hp) clif_updatestatus(sd,SP_HP);
+ if(sp) clif_updatestatus(sd,SP_SP);
+
+ pc_setstand(sd);
+ if(battle_config.pc_invincible_time > 0)
+ pc_setinvincibletimer(sd, battle_config.pc_invincible_time);
+
+ if( sd->state.gmaster_flag ) {
+ guild_guildaura_refresh(sd,GD_LEADERSHIP,guild_checkskill(sd->state.gmaster_flag,GD_LEADERSHIP));
+ guild_guildaura_refresh(sd,GD_GLORYWOUNDS,guild_checkskill(sd->state.gmaster_flag,GD_GLORYWOUNDS));
+ guild_guildaura_refresh(sd,GD_SOULCOLD,guild_checkskill(sd->state.gmaster_flag,GD_SOULCOLD));
+ guild_guildaura_refresh(sd,GD_HAWKEYES,guild_checkskill(sd->state.gmaster_flag,GD_HAWKEYES));
+ }
}
// script
//
/*==========================================
* script reading pc status registry
*------------------------------------------*/
-int pc_readparam(struct map_session_data *sd,int type)
-{
- int val = 0;
-
- nullpo_ret(sd);
-
- switch (type) {
- case SP_SKILLPOINT:
- val = sd->status.skill_point;
- break;
- case SP_STATUSPOINT:
- val = sd->status.status_point;
- break;
- case SP_ZENY:
- val = sd->status.zeny;
- break;
- case SP_BASELEVEL:
- val = sd->status.base_level;
- break;
- case SP_JOBLEVEL:
- val = sd->status.job_level;
- break;
- case SP_CLASS:
- val = sd->status.class_;
- break;
- case SP_BASEJOB:
- val = pc_mapid2jobid(sd->class_&MAPID_UPPERMASK, sd->status.sex);
- break; //Base job, extracting upper type.
- case SP_UPPER:
- val = sd->class_&JOBL_UPPER?1:(sd->class_&JOBL_BABY?2:0);
- break;
- case SP_BASECLASS:
- val = pc_mapid2jobid(sd->class_&MAPID_BASEMASK, sd->status.sex);
- break; //Extract base class tree. [Skotlex]
- case SP_SEX:
- val = sd->status.sex;
- break;
- case SP_WEIGHT:
- val = sd->weight;
- break;
- case SP_MAXWEIGHT:
- val = sd->max_weight;
- break;
- case SP_BASEEXP:
- val = sd->status.base_exp;
- break;
- case SP_JOBEXP:
- val = sd->status.job_exp;
- break;
- case SP_NEXTBASEEXP:
- val = pc_nextbaseexp(sd);
- break;
- case SP_NEXTJOBEXP:
- val = pc_nextjobexp(sd);
- break;
- case SP_HP:
- val = sd->battle_status.hp;
- break;
- case SP_MAXHP:
- val = sd->battle_status.max_hp;
- break;
- case SP_SP:
- val = sd->battle_status.sp;
- break;
- case SP_MAXSP:
- val = sd->battle_status.max_sp;
- break;
- case SP_STR:
- val = sd->status.str;
- break;
- case SP_AGI:
- val = sd->status.agi;
- break;
- case SP_VIT:
- val = sd->status.vit;
- break;
- case SP_INT:
- val = sd->status.int_;
- break;
- case SP_DEX:
- val = sd->status.dex;
- break;
- case SP_LUK:
- val = sd->status.luk;
- break;
- case SP_KARMA:
- val = sd->status.karma;
- break;
- case SP_MANNER:
- val = sd->status.manner;
- break;
- case SP_FAME:
- val = sd->status.fame;
- break;
- case SP_KILLERRID:
- val = sd->killerrid;
- break;
- case SP_KILLEDRID:
- val = sd->killedrid;
- break;
- case SP_CRITICAL:
- val = sd->battle_status.cri/10;
- break;
- case SP_ASPD:
- val = (2000-sd->battle_status.amotion)/10;
- break;
- }
-
- return val;
+int pc_readparam(struct map_session_data* sd,int type)
+{
+ int val = 0;
+
+ nullpo_ret(sd);
+
+ switch(type) {
+ case SP_SKILLPOINT: val = sd->status.skill_point; break;
+ case SP_STATUSPOINT: val = sd->status.status_point; break;
+ case SP_ZENY: val = sd->status.zeny; break;
+ case SP_BASELEVEL: val = sd->status.base_level; break;
+ case SP_JOBLEVEL: val = sd->status.job_level; break;
+ case SP_CLASS: val = sd->status.class_; break;
+ case SP_BASEJOB: val = pc_mapid2jobid(sd->class_&MAPID_UPPERMASK, sd->status.sex); break; //Base job, extracting upper type.
+ case SP_UPPER: val = sd->class_&JOBL_UPPER?1:(sd->class_&JOBL_BABY?2:0); break;
+ case SP_BASECLASS: val = pc_mapid2jobid(sd->class_&MAPID_BASEMASK, sd->status.sex); break; //Extract base class tree. [Skotlex]
+ case SP_SEX: val = sd->status.sex; break;
+ case SP_WEIGHT: val = sd->weight; break;
+ case SP_MAXWEIGHT: val = sd->max_weight; break;
+ case SP_BASEEXP: val = sd->status.base_exp; break;
+ case SP_JOBEXP: val = sd->status.job_exp; break;
+ case SP_NEXTBASEEXP: val = pc_nextbaseexp(sd); break;
+ case SP_NEXTJOBEXP: val = pc_nextjobexp(sd); break;
+ case SP_HP: val = sd->battle_status.hp; break;
+ case SP_MAXHP: val = sd->battle_status.max_hp; break;
+ case SP_SP: val = sd->battle_status.sp; break;
+ case SP_MAXSP: val = sd->battle_status.max_sp; break;
+ case SP_STR: val = sd->status.str; break;
+ case SP_AGI: val = sd->status.agi; break;
+ case SP_VIT: val = sd->status.vit; break;
+ case SP_INT: val = sd->status.int_; break;
+ case SP_DEX: val = sd->status.dex; break;
+ case SP_LUK: val = sd->status.luk; break;
+ case SP_KARMA: val = sd->status.karma; break;
+ case SP_MANNER: val = sd->status.manner; break;
+ case SP_FAME: val = sd->status.fame; break;
+ case SP_KILLERRID: val = sd->killerrid; break;
+ case SP_KILLEDRID: val = sd->killedrid; break;
+ case SP_CRITICAL: val = sd->battle_status.cri/10; break;
+ case SP_ASPD: val = (2000-sd->battle_status.amotion)/10; break;
+ }
+
+ return val;
}
/*==========================================
@@ -6998,145 +6862,148 @@ int pc_readparam(struct map_session_data *sd,int type)
*------------------------------------------*/
int pc_setparam(struct map_session_data *sd,int type,int val)
{
- int i = 0, statlimit;
-
- nullpo_ret(sd);
-
- switch (type) {
- case SP_BASELEVEL:
- if ((unsigned int)val > pc_maxbaselv(sd)) //Capping to max
- val = pc_maxbaselv(sd);
- if ((unsigned int)val > sd->status.base_level) {
- int stat=0;
- for (i = 0; i < (int)((unsigned int)val - sd->status.base_level); i++)
- stat += pc_gets_status_point(sd->status.base_level + i);
- sd->status.status_point += stat;
- }
- sd->status.base_level = (unsigned int)val;
- sd->status.base_exp = 0;
- // clif_updatestatus(sd, SP_BASELEVEL); // Gets updated at the bottom
- clif_updatestatus(sd, SP_NEXTBASEEXP);
- clif_updatestatus(sd, SP_STATUSPOINT);
- clif_updatestatus(sd, SP_BASEEXP);
- status_calc_pc(sd, 0);
- if (sd->status.party_id) {
- party_send_levelup(sd);
- }
- break;
- case SP_JOBLEVEL:
- if ((unsigned int)val >= sd->status.job_level) {
- if ((unsigned int)val > pc_maxjoblv(sd)) val = pc_maxjoblv(sd);
- sd->status.skill_point += val - sd->status.job_level;
- clif_updatestatus(sd, SP_SKILLPOINT);
- }
- sd->status.job_level = (unsigned int)val;
- sd->status.job_exp = 0;
- // clif_updatestatus(sd, SP_JOBLEVEL); // Gets updated at the bottom
- clif_updatestatus(sd, SP_NEXTJOBEXP);
- clif_updatestatus(sd, SP_JOBEXP);
- status_calc_pc(sd, 0);
- break;
- case SP_SKILLPOINT:
- sd->status.skill_point = val;
- break;
- case SP_STATUSPOINT:
- sd->status.status_point = val;
- break;
- case SP_ZENY:
- if (val < 0)
- return 0;// can't set negative zeny
- log_zeny(sd, LOG_TYPE_SCRIPT, sd, -(sd->status.zeny - cap_value(val, 0, MAX_ZENY)));
- sd->status.zeny = cap_value(val, 0, MAX_ZENY);
- break;
- case SP_BASEEXP:
- if (pc_nextbaseexp(sd) > 0) {
- sd->status.base_exp = val;
- pc_checkbaselevelup(sd);
- }
- break;
- case SP_JOBEXP:
- if (pc_nextjobexp(sd) > 0) {
- sd->status.job_exp = val;
- pc_checkjoblevelup(sd);
- }
- break;
- case SP_SEX:
- sd->status.sex = val ? SEX_MALE : SEX_FEMALE;
- break;
- case SP_WEIGHT:
- sd->weight = val;
- break;
- case SP_MAXWEIGHT:
- sd->max_weight = val;
- break;
- case SP_HP:
- sd->battle_status.hp = cap_value(val, 1, (int)sd->battle_status.max_hp);
- break;
- case SP_MAXHP:
- sd->battle_status.max_hp = cap_value(val, 1, battle_config.max_hp);
-
- if (sd->battle_status.max_hp < sd->battle_status.hp) {
- sd->battle_status.hp = sd->battle_status.max_hp;
- clif_updatestatus(sd, SP_HP);
- }
- break;
- case SP_SP:
- sd->battle_status.sp = cap_value(val, 0, (int)sd->battle_status.max_sp);
- break;
- case SP_MAXSP:
- sd->battle_status.max_sp = cap_value(val, 1, battle_config.max_sp);
-
- if (sd->battle_status.max_sp < sd->battle_status.sp) {
- sd->battle_status.sp = sd->battle_status.max_sp;
- clif_updatestatus(sd, SP_SP);
- }
- break;
- case SP_STR:
- statlimit = pc_maxparameter(sd);
- sd->status.str = cap_value(val, 1, statlimit);
- break;
- case SP_AGI:
- statlimit = pc_maxparameter(sd);
- sd->status.agi = cap_value(val, 1, statlimit);
- break;
- case SP_VIT:
- statlimit = pc_maxparameter(sd);
- sd->status.vit = cap_value(val, 1, statlimit);
- break;
- case SP_INT:
- statlimit = pc_maxparameter(sd);
- sd->status.int_ = cap_value(val, 1, statlimit);
- break;
- case SP_DEX:
- statlimit = pc_maxparameter(sd);
- sd->status.dex = cap_value(val, 1, statlimit);
- break;
- case SP_LUK:
- statlimit = pc_maxparameter(sd);
- sd->status.luk = cap_value(val, 1, statlimit);
- break;
- case SP_KARMA:
- sd->status.karma = val;
- break;
- case SP_MANNER:
- sd->status.manner = val;
- break;
- case SP_FAME:
- sd->status.fame = val;
- break;
- case SP_KILLERRID:
- sd->killerrid = val;
- return 1;
- case SP_KILLEDRID:
- sd->killedrid = val;
- return 1;
- default:
- ShowError("pc_setparam: Attempted to set unknown parameter '%d'.\n", type);
- return 0;
- }
- clif_updatestatus(sd,type);
-
- return 1;
+ int i = 0, statlimit;
+
+ nullpo_ret(sd);
+
+ switch(type){
+ case SP_BASELEVEL:
+ if ((unsigned int)val > pc_maxbaselv(sd)) //Capping to max
+ val = pc_maxbaselv(sd);
+ if ((unsigned int)val > sd->status.base_level) {
+ int stat=0;
+ for (i = 0; i < (int)((unsigned int)val - sd->status.base_level); i++)
+ stat += pc_gets_status_point(sd->status.base_level + i);
+ sd->status.status_point += stat;
+ }
+ sd->status.base_level = (unsigned int)val;
+ sd->status.base_exp = 0;
+ // clif_updatestatus(sd, SP_BASELEVEL); // Gets updated at the bottom
+ clif_updatestatus(sd, SP_NEXTBASEEXP);
+ clif_updatestatus(sd, SP_STATUSPOINT);
+ clif_updatestatus(sd, SP_BASEEXP);
+ status_calc_pc(sd, 0);
+ if(sd->status.party_id)
+ {
+ party_send_levelup(sd);
+ }
+ break;
+ case SP_JOBLEVEL:
+ if ((unsigned int)val >= sd->status.job_level) {
+ if ((unsigned int)val > pc_maxjoblv(sd)) val = pc_maxjoblv(sd);
+ sd->status.skill_point += val - sd->status.job_level;
+ clif_updatestatus(sd, SP_SKILLPOINT);
+ }
+ sd->status.job_level = (unsigned int)val;
+ sd->status.job_exp = 0;
+ // clif_updatestatus(sd, SP_JOBLEVEL); // Gets updated at the bottom
+ clif_updatestatus(sd, SP_NEXTJOBEXP);
+ clif_updatestatus(sd, SP_JOBEXP);
+ status_calc_pc(sd, 0);
+ break;
+ case SP_SKILLPOINT:
+ sd->status.skill_point = val;
+ break;
+ case SP_STATUSPOINT:
+ sd->status.status_point = val;
+ break;
+ case SP_ZENY:
+ if( val < 0 )
+ return 0;// can't set negative zeny
+ log_zeny(sd, LOG_TYPE_SCRIPT, sd, -(sd->status.zeny - cap_value(val, 0, MAX_ZENY)));
+ sd->status.zeny = cap_value(val, 0, MAX_ZENY);
+ break;
+ case SP_BASEEXP:
+ if(pc_nextbaseexp(sd) > 0) {
+ sd->status.base_exp = val;
+ pc_checkbaselevelup(sd);
+ }
+ break;
+ case SP_JOBEXP:
+ if(pc_nextjobexp(sd) > 0) {
+ sd->status.job_exp = val;
+ pc_checkjoblevelup(sd);
+ }
+ break;
+ case SP_SEX:
+ sd->status.sex = val ? SEX_MALE : SEX_FEMALE;
+ break;
+ case SP_WEIGHT:
+ sd->weight = val;
+ break;
+ case SP_MAXWEIGHT:
+ sd->max_weight = val;
+ break;
+ case SP_HP:
+ sd->battle_status.hp = cap_value(val, 1, (int)sd->battle_status.max_hp);
+ break;
+ case SP_MAXHP:
+ sd->battle_status.max_hp = cap_value(val, 1, battle_config.max_hp);
+
+ if( sd->battle_status.max_hp < sd->battle_status.hp )
+ {
+ sd->battle_status.hp = sd->battle_status.max_hp;
+ clif_updatestatus(sd, SP_HP);
+ }
+ break;
+ case SP_SP:
+ sd->battle_status.sp = cap_value(val, 0, (int)sd->battle_status.max_sp);
+ break;
+ case SP_MAXSP:
+ sd->battle_status.max_sp = cap_value(val, 1, battle_config.max_sp);
+
+ if( sd->battle_status.max_sp < sd->battle_status.sp )
+ {
+ sd->battle_status.sp = sd->battle_status.max_sp;
+ clif_updatestatus(sd, SP_SP);
+ }
+ break;
+ case SP_STR:
+ statlimit = pc_maxparameter(sd);
+ sd->status.str = cap_value(val, 1, statlimit);
+ break;
+ case SP_AGI:
+ statlimit = pc_maxparameter(sd);
+ sd->status.agi = cap_value(val, 1, statlimit);
+ break;
+ case SP_VIT:
+ statlimit = pc_maxparameter(sd);
+ sd->status.vit = cap_value(val, 1, statlimit);
+ break;
+ case SP_INT:
+ statlimit = pc_maxparameter(sd);
+ sd->status.int_ = cap_value(val, 1, statlimit);
+ break;
+ case SP_DEX:
+ statlimit = pc_maxparameter(sd);
+ sd->status.dex = cap_value(val, 1, statlimit);
+ break;
+ case SP_LUK:
+ statlimit = pc_maxparameter(sd);
+ sd->status.luk = cap_value(val, 1, statlimit);
+ break;
+ case SP_KARMA:
+ sd->status.karma = val;
+ break;
+ case SP_MANNER:
+ sd->status.manner = val;
+ break;
+ case SP_FAME:
+ sd->status.fame = val;
+ break;
+ case SP_KILLERRID:
+ sd->killerrid = val;
+ return 1;
+ case SP_KILLEDRID:
+ sd->killedrid = val;
+ return 1;
+ default:
+ ShowError("pc_setparam: Attempted to set unknown parameter '%d'.\n", type);
+ return 0;
+ }
+ clif_updatestatus(sd,type);
+
+ return 1;
}
/*==========================================
@@ -7144,18 +7011,18 @@ int pc_setparam(struct map_session_data *sd,int type,int val)
*------------------------------------------*/
void pc_heal(struct map_session_data *sd,unsigned int hp,unsigned int sp, int type)
{
- if (type) {
- if (hp)
- clif_heal(sd->fd,SP_HP,hp);
- if (sp)
- clif_heal(sd->fd,SP_SP,sp);
- } else {
- if (hp)
- clif_updatestatus(sd,SP_HP);
- if (sp)
- clif_updatestatus(sd,SP_SP);
- }
- return;
+ if (type) {
+ if (hp)
+ clif_heal(sd->fd,SP_HP,hp);
+ if (sp)
+ clif_heal(sd->fd,SP_SP,sp);
+ } else {
+ if(hp)
+ clif_updatestatus(sd,SP_HP);
+ if(sp)
+ clif_updatestatus(sd,SP_SP);
+ }
+ return;
}
/*==========================================
@@ -7165,64 +7032,65 @@ void pc_heal(struct map_session_data *sd,unsigned int hp,unsigned int sp, int ty
*------------------------------------------*/
int pc_itemheal(struct map_session_data *sd,int itemid, int hp,int sp)
{
- int i, bonus;
-
- if (hp) {
- bonus = 100 + (sd->battle_status.vit<<1)
- + pc_checkskill(sd,SM_RECOVERY)*10
- + pc_checkskill(sd,AM_LEARNINGPOTION)*5;
- // A potion produced by an Alchemist in the Fame Top 10 gets +50% effect [DracoRPG]
- if (potion_flag > 1)
- bonus += bonus*(potion_flag-1)*50/100;
- //All item bonuses.
- bonus += sd->bonus.itemhealrate2;
- //Item Group bonuses
- bonus += bonus*itemdb_group_bonus(sd, itemid)/100;
- //Individual item bonuses.
- for (i = 0; i < ARRAYLENGTH(sd->itemhealrate) && sd->itemhealrate[i].nameid; i++) {
- if (sd->itemhealrate[i].nameid == itemid) {
- bonus += bonus*sd->itemhealrate[i].rate/100;
- break;
- }
- }
- if (bonus!=100)
- hp = hp * bonus / 100;
-
- // Recovery Potion
- if (sd->sc.data[SC_INCHEALRATE])
- hp += (int)(hp * sd->sc.data[SC_INCHEALRATE]->val1/100.);
- }
- if (sp) {
- bonus = 100 + (sd->battle_status.int_<<1)
- + pc_checkskill(sd,MG_SRECOVERY)*10
- + pc_checkskill(sd,AM_LEARNINGPOTION)*5;
- if (potion_flag > 1)
- bonus += bonus*(potion_flag-1)*50/100;
- if (bonus != 100)
- sp = sp * bonus / 100;
- }
- if (sd->sc.count) {
- if (sd->sc.data[SC_CRITICALWOUND]) {
- hp -= hp * sd->sc.data[SC_CRITICALWOUND]->val2 / 100;
- sp -= sp * sd->sc.data[SC_CRITICALWOUND]->val2 / 100;
- }
-
- if (sd->sc.data[SC_DEATHHURT]) {
- hp -= hp * 20 / 100;
- sp -= sp * 20 / 100;
- }
-
- if (sd->sc.data[SC_WATER_INSIGNIA] && sd->sc.data[SC_WATER_INSIGNIA]->val1 == 2) {
- hp += hp / 10;
- sp += sp / 10;
- }
+ int i, bonus;
+
+ if(hp) {
+ bonus = 100 + (sd->battle_status.vit<<1)
+ + pc_checkskill(sd,SM_RECOVERY)*10
+ + pc_checkskill(sd,AM_LEARNINGPOTION)*5;
+ // A potion produced by an Alchemist in the Fame Top 10 gets +50% effect [DracoRPG]
+ if (potion_flag > 1)
+ bonus += bonus*(potion_flag-1)*50/100;
+ //All item bonuses.
+ bonus += sd->bonus.itemhealrate2;
+ //Item Group bonuses
+ bonus += bonus*itemdb_group_bonus(sd, itemid)/100;
+ //Individual item bonuses.
+ for(i = 0; i < ARRAYLENGTH(sd->itemhealrate) && sd->itemhealrate[i].nameid; i++)
+ {
+ if (sd->itemhealrate[i].nameid == itemid) {
+ bonus += bonus*sd->itemhealrate[i].rate/100;
+ break;
+ }
+ }
+ if(bonus!=100)
+ hp = hp * bonus / 100;
+
+ // Recovery Potion
+ if( sd->sc.data[SC_INCHEALRATE] )
+ hp += (int)(hp * sd->sc.data[SC_INCHEALRATE]->val1/100.);
+ }
+ if(sp) {
+ bonus = 100 + (sd->battle_status.int_<<1)
+ + pc_checkskill(sd,MG_SRECOVERY)*10
+ + pc_checkskill(sd,AM_LEARNINGPOTION)*5;
+ if (potion_flag > 1)
+ bonus += bonus*(potion_flag-1)*50/100;
+ if(bonus != 100)
+ sp = sp * bonus / 100;
+ }
+ if( sd->sc.count ) {
+ if ( sd->sc.data[SC_CRITICALWOUND] ) {
+ hp -= hp * sd->sc.data[SC_CRITICALWOUND]->val2 / 100;
+ sp -= sp * sd->sc.data[SC_CRITICALWOUND]->val2 / 100;
+ }
+
+ if ( sd->sc.data[SC_DEATHHURT] ) {
+ hp -= hp * 20 / 100;
+ sp -= sp * 20 / 100;
+ }
+
+ if( sd->sc.data[SC_WATER_INSIGNIA] && sd->sc.data[SC_WATER_INSIGNIA]->val1 == 2 ) {
+ hp += hp / 10;
+ sp += sp / 10;
+ }
#ifdef RENEWAL
- if (sd->sc.data[SC_EXTREMITYFIST2])
- sp = 0;
+ if( sd->sc.data[SC_EXTREMITYFIST2] )
+ sp = 0;
#endif
- }
+ }
- return status_heal(&sd->bl, hp, sp, 1);
+ return status_heal(&sd->bl, hp, sp, 1);
}
/*==========================================
@@ -7231,48 +7099,37 @@ int pc_itemheal(struct map_session_data *sd,int itemid, int hp,int sp)
*------------------------------------------*/
int pc_percentheal(struct map_session_data *sd,int hp,int sp)
{
- nullpo_ret(sd);
+ nullpo_ret(sd);
- if (hp > 100) hp = 100;
- else if (hp <-100) hp =-100;
+ if(hp > 100) hp = 100;
+ else
+ if(hp <-100) hp =-100;
- if (sp > 100) sp = 100;
- else if (sp <-100) sp =-100;
+ if(sp > 100) sp = 100;
+ else
+ if(sp <-100) sp =-100;
- if (hp >= 0 && sp >= 0) //Heal
- return status_percent_heal(&sd->bl, hp, sp);
+ if(hp >= 0 && sp >= 0) //Heal
+ return status_percent_heal(&sd->bl, hp, sp);
- if (hp <= 0 && sp <= 0) //Damage (negative rates indicate % of max rather than current), and only kill target IF the specified amount is 100%
- return status_percent_damage(NULL, &sd->bl, hp, sp, hp==-100);
+ if(hp <= 0 && sp <= 0) //Damage (negative rates indicate % of max rather than current), and only kill target IF the specified amount is 100%
+ return status_percent_damage(NULL, &sd->bl, hp, sp, hp==-100);
- //Crossed signs
- if (hp) {
- if (hp > 0)
- status_percent_heal(&sd->bl, hp, 0);
- else
- status_percent_damage(NULL, &sd->bl, hp, 0, hp==-100);
- }
+ //Crossed signs
+ if(hp) {
+ if(hp > 0)
+ status_percent_heal(&sd->bl, hp, 0);
+ else
+ status_percent_damage(NULL, &sd->bl, hp, 0, hp==-100);
+ }
- if (sp) {
- if (sp > 0)
- status_percent_heal(&sd->bl, 0, sp);
- else
- status_percent_damage(NULL, &sd->bl, 0, sp, false);
- }
- return 0;
-}
-
-static int jobchange_killclone(struct block_list *bl, va_list ap)
-{
- struct mob_data *md;
- int flag;
- md = (struct mob_data *)bl;
- nullpo_ret(md);
- flag = va_arg(ap, int);
-
- if (md->master_id && md->special_state.clone && md->master_id == flag)
- status_kill(&md->bl);
- return 1;
+ if(sp) {
+ if(sp > 0)
+ status_percent_heal(&sd->bl, 0, sp);
+ else
+ status_percent_damage(NULL, &sd->bl, 0, sp, false);
+ }
+ return 0;
}
/*==========================================
@@ -7281,168 +7138,161 @@ static int jobchange_killclone(struct block_list *bl, va_list ap)
*------------------------------------------*/
int pc_jobchange(struct map_session_data *sd,int job, int upper)
{
- int i, fame_flag=0;
- int b_class;
-
- nullpo_ret(sd);
-
- if (job < 0)
- return 1;
-
- //Normalize job.
- b_class = pc_jobid2mapid(job);
- if (b_class == -1)
- return 1;
- switch (upper) {
- case 1:
- b_class|= JOBL_UPPER;
- break;
- case 2:
- b_class|= JOBL_BABY;
- break;
- }
- //This will automatically adjust bard/dancer classes to the correct gender
- //That is, if you try to jobchange into dancer, it will turn you to bard.
- job = pc_mapid2jobid(b_class, sd->status.sex);
- if (job == -1)
- return 1;
-
- if ((unsigned short)b_class == sd->class_)
- return 1; //Nothing to change.
-
- // changing from 1st to 2nd job
- if ((b_class&JOBL_2) && !(sd->class_&JOBL_2) && (b_class&MAPID_UPPERMASK) != MAPID_SUPER_NOVICE) {
- sd->change_level_2nd = sd->status.job_level;
- pc_setglobalreg(sd, "jobchange_level", sd->change_level_2nd);
- }
- // changing from 2nd to 3rd job
- else if ((b_class&JOBL_THIRD) && !(sd->class_&JOBL_THIRD)) {
- sd->change_level_3rd = sd->status.job_level;
- pc_setglobalreg(sd, "jobchange_level_3rd", sd->change_level_3rd);
- }
-
- if (sd->cloneskill_id) {
- if (sd->status.skill[sd->cloneskill_id].flag == SKILL_FLAG_PLAGIARIZED) {
- sd->status.skill[sd->cloneskill_id].id = 0;
- sd->status.skill[sd->cloneskill_id].lv = 0;
- sd->status.skill[sd->cloneskill_id].flag = 0;
- clif_deleteskill(sd,sd->cloneskill_id);
- }
- sd->cloneskill_id = 0;
- pc_setglobalreg(sd, "CLONE_SKILL", 0);
- pc_setglobalreg(sd, "CLONE_SKILL_LV", 0);
- }
-
- if (sd->reproduceskill_id) {
- if (sd->status.skill[sd->reproduceskill_id].flag == SKILL_FLAG_PLAGIARIZED) {
- sd->status.skill[sd->reproduceskill_id].id = 0;
- sd->status.skill[sd->reproduceskill_id].lv = 0;
- sd->status.skill[sd->reproduceskill_id].flag = 0;
- clif_deleteskill(sd,sd->reproduceskill_id);
- }
- sd->reproduceskill_id = 0;
- pc_setglobalreg(sd, "REPRODUCE_SKILL",0);
- pc_setglobalreg(sd, "REPRODUCE_SKILL_LV",0);
- }
-
- if ((b_class&MAPID_UPPERMASK) != (sd->class_&MAPID_UPPERMASK)) { //Things to remove when changing class tree.
- const int class_ = pc_class2idx(sd->status.class_);
- short id;
- for (i = 0; i < MAX_SKILL_TREE && (id = skill_tree[class_][i].id) > 0; i++) {
- //Remove status specific to your current tree skills.
- enum sc_type sc = status_skill2sc(id);
- if (sc > SC_COMMON_MAX && sd->sc.data[sc])
- status_change_end(&sd->bl, sc, INVALID_TIMER);
- }
- }
-
- sd->status.class_ = job;
- fame_flag = pc_famerank(sd->status.char_id,sd->class_&MAPID_UPPERMASK);
- sd->class_ = (unsigned short)b_class;
- sd->status.job_level=1;
- sd->status.job_exp=0;
- clif_updatestatus(sd,SP_JOBLEVEL);
- clif_updatestatus(sd,SP_JOBEXP);
- clif_updatestatus(sd,SP_NEXTJOBEXP);
-
- for (i=0; i<EQI_MAX; i++) {
- if (sd->equip_index[i] >= 0)
- if (!pc_isequip(sd,sd->equip_index[i]))
- pc_unequipitem(sd,sd->equip_index[i],2); // unequip invalid item for class
- }
-
- //Change look, if disguised, you need to undisguise
- //to correctly calculate new job sprite without
- if (sd->disguise)
- pc_disguise(sd, 0);
-
- status_set_viewdata(&sd->bl, job);
- clif_changelook(&sd->bl,LOOK_BASE,sd->vd.class_); // move sprite update to prevent client crashes with incompatible equipment [Valaris]
- if (sd->vd.cloth_color)
- clif_changelook(&sd->bl,LOOK_CLOTHES_COLOR,sd->vd.cloth_color);
-
- //Update skill tree.
- pc_calc_skilltree(sd);
- clif_skillinfoblock(sd);
-
- if (sd->ed)
- elemental_delete(sd->ed, 0);
- if (sd->state.vending)
- vending_closevending(sd);
-
- map_foreachinmap(jobchange_killclone, sd->bl.m, BL_MOB, sd->bl.id);
-
- //Remove peco/cart/falcon
- i = sd->sc.option;
- if (i&OPTION_RIDING && !pc_checkskill(sd, KN_RIDING))
- i&=~OPTION_RIDING;
- if (i&OPTION_FALCON && !pc_checkskill(sd, HT_FALCON))
- i&=~OPTION_FALCON;
- if (i&OPTION_DRAGON && !pc_checkskill(sd,RK_DRAGONTRAINING))
- i&=~OPTION_DRAGON;
- if (i&OPTION_WUGRIDER && !pc_checkskill(sd,RA_WUGMASTERY))
- i&=~OPTION_WUGRIDER;
- if (i&OPTION_WUG && !pc_checkskill(sd,RA_WUGMASTERY))
- i&=~OPTION_WUG;
- if (i&OPTION_MADOGEAR) //You do not need a skill for this.
- i&=~OPTION_MADOGEAR;
+ int i, fame_flag=0;
+ int b_class;
+
+ nullpo_ret(sd);
+
+ if (job < 0)
+ return 1;
+
+ //Normalize job.
+ b_class = pc_jobid2mapid(job);
+ if (b_class == -1)
+ return 1;
+ switch (upper) {
+ case 1:
+ b_class|= JOBL_UPPER;
+ break;
+ case 2:
+ b_class|= JOBL_BABY;
+ break;
+ }
+ //This will automatically adjust bard/dancer classes to the correct gender
+ //That is, if you try to jobchange into dancer, it will turn you to bard.
+ job = pc_mapid2jobid(b_class, sd->status.sex);
+ if (job == -1)
+ return 1;
+
+ if ((unsigned short)b_class == sd->class_)
+ return 1; //Nothing to change.
+
+ // changing from 1st to 2nd job
+ if ((b_class&JOBL_2) && !(sd->class_&JOBL_2) && (b_class&MAPID_UPPERMASK) != MAPID_SUPER_NOVICE) {
+ sd->change_level_2nd = sd->status.job_level;
+ pc_setglobalreg (sd, "jobchange_level", sd->change_level_2nd);
+ }
+ // changing from 2nd to 3rd job
+ else if((b_class&JOBL_THIRD) && !(sd->class_&JOBL_THIRD)) {
+ sd->change_level_3rd = sd->status.job_level;
+ pc_setglobalreg (sd, "jobchange_level_3rd", sd->change_level_3rd);
+ }
+
+ if(sd->cloneskill_id) {
+ if( sd->status.skill[sd->cloneskill_id].flag == SKILL_FLAG_PLAGIARIZED ) {
+ sd->status.skill[sd->cloneskill_id].id = 0;
+ sd->status.skill[sd->cloneskill_id].lv = 0;
+ sd->status.skill[sd->cloneskill_id].flag = 0;
+ clif_deleteskill(sd,sd->cloneskill_id);
+ }
+ sd->cloneskill_id = 0;
+ pc_setglobalreg(sd, "CLONE_SKILL", 0);
+ pc_setglobalreg(sd, "CLONE_SKILL_LV", 0);
+ }
+
+ if(sd->reproduceskill_id) {
+ if( sd->status.skill[sd->reproduceskill_id].flag == SKILL_FLAG_PLAGIARIZED ) {
+ sd->status.skill[sd->reproduceskill_id].id = 0;
+ sd->status.skill[sd->reproduceskill_id].lv = 0;
+ sd->status.skill[sd->reproduceskill_id].flag = 0;
+ clif_deleteskill(sd,sd->reproduceskill_id);
+ }
+ sd->reproduceskill_id = 0;
+ pc_setglobalreg(sd, "REPRODUCE_SKILL",0);
+ pc_setglobalreg(sd, "REPRODUCE_SKILL_LV",0);
+ }
+
+ if ( (b_class&MAPID_UPPERMASK) != (sd->class_&MAPID_UPPERMASK) ) { //Things to remove when changing class tree.
+ const int class_ = pc_class2idx(sd->status.class_);
+ short id;
+ for(i = 0; i < MAX_SKILL_TREE && (id = skill_tree[class_][i].id) > 0; i++) {
+ //Remove status specific to your current tree skills.
+ enum sc_type sc = status_skill2sc(id);
+ if (sc > SC_COMMON_MAX && sd->sc.data[sc])
+ status_change_end(&sd->bl, sc, INVALID_TIMER);
+ }
+ }
+
+ sd->status.class_ = job;
+ fame_flag = pc_famerank(sd->status.char_id,sd->class_&MAPID_UPPERMASK);
+ sd->class_ = (unsigned short)b_class;
+ sd->status.job_level=1;
+ sd->status.job_exp=0;
+ clif_updatestatus(sd,SP_JOBLEVEL);
+ clif_updatestatus(sd,SP_JOBEXP);
+ clif_updatestatus(sd,SP_NEXTJOBEXP);
+
+ for(i=0;i<EQI_MAX;i++) {
+ if(sd->equip_index[i] >= 0)
+ if(!pc_isequip(sd,sd->equip_index[i]))
+ pc_unequipitem(sd,sd->equip_index[i],2); // unequip invalid item for class
+ }
+
+ //Change look, if disguised, you need to undisguise
+ //to correctly calculate new job sprite without
+ if (sd->disguise)
+ pc_disguise(sd, 0);
+
+ status_set_viewdata(&sd->bl, job);
+ clif_changelook(&sd->bl,LOOK_BASE,sd->vd.class_); // move sprite update to prevent client crashes with incompatible equipment [Valaris]
+ if(sd->vd.cloth_color)
+ clif_changelook(&sd->bl,LOOK_CLOTHES_COLOR,sd->vd.cloth_color);
+
+ //Update skill tree.
+ pc_calc_skilltree(sd);
+ clif_skillinfoblock(sd);
+
+ //Remove peco/cart/falcon
+ i = sd->sc.option;
+ if( i&OPTION_RIDING && !pc_checkskill(sd, KN_RIDING) )
+ i&=~OPTION_RIDING;
+ if( i&OPTION_FALCON && !pc_checkskill(sd, HT_FALCON) )
+ i&=~OPTION_FALCON;
+ if( i&OPTION_DRAGON && !pc_checkskill(sd,RK_DRAGONTRAINING) )
+ i&=~OPTION_DRAGON;
+ if( i&OPTION_WUGRIDER && !pc_checkskill(sd,RA_WUGMASTERY) )
+ i&=~OPTION_WUGRIDER;
+ if( i&OPTION_WUG && !pc_checkskill(sd,RA_WUGMASTERY) )
+ i&=~OPTION_WUG;
+ if( i&OPTION_MADOGEAR ) //You do not need a skill for this.
+ i&=~OPTION_MADOGEAR;
#ifndef NEW_CARTS
- if (i&OPTION_CART && !pc_checkskill(sd, MC_PUSHCART))
- i&=~OPTION_CART;
+ if( i&OPTION_CART && !pc_checkskill(sd, MC_PUSHCART) )
+ i&=~OPTION_CART;
#else
- if (sd->sc.data[SC_PUSH_CART] && !pc_checkskill(sd, MC_PUSHCART))
- pc_setcart(sd, 0);
+ if( sd->sc.data[SC_PUSH_CART] && !pc_checkskill(sd, MC_PUSHCART) )
+ pc_setcart(sd, 0);
#endif
- if (i != sd->sc.option)
- pc_setoption(sd, i);
-
- if (merc_is_hom_active(sd->hd) && !pc_checkskill(sd, AM_CALLHOMUN))
- merc_hom_vaporize(sd, 0);
-
- if (sd->status.manner < 0)
- clif_changestatus(sd,SP_MANNER,sd->status.manner);
-
- status_calc_pc(sd,0);
- pc_checkallowskill(sd);
- pc_equiplookall(sd);
-
- //if you were previously famous, not anymore.
- if (fame_flag) {
- chrif_save(sd,0);
- chrif_buildfamelist();
- } else if (sd->status.fame > 0) {
- //It may be that now they are famous?
- switch (sd->class_&MAPID_UPPERMASK) {
- case MAPID_BLACKSMITH:
- case MAPID_ALCHEMIST:
- case MAPID_TAEKWON:
- chrif_save(sd,0);
- chrif_buildfamelist();
- break;
- }
- }
-
- return 0;
+ if(i != sd->sc.option)
+ pc_setoption(sd, i);
+
+ if(merc_is_hom_active(sd->hd) && !pc_checkskill(sd, AM_CALLHOMUN))
+ merc_hom_vaporize(sd, 0);
+
+ if(sd->status.manner < 0)
+ clif_changestatus(sd,SP_MANNER,sd->status.manner);
+
+ status_calc_pc(sd,0);
+ pc_checkallowskill(sd);
+ pc_equiplookall(sd);
+
+ //if you were previously famous, not anymore.
+ if (fame_flag) {
+ chrif_save(sd,0);
+ chrif_buildfamelist();
+ } else if (sd->status.fame > 0) {
+ //It may be that now they are famous?
+ switch (sd->class_&MAPID_UPPERMASK) {
+ case MAPID_BLACKSMITH:
+ case MAPID_ALCHEMIST:
+ case MAPID_TAEKWON:
+ chrif_save(sd,0);
+ chrif_buildfamelist();
+ break;
+ }
+ }
+
+ return 0;
}
/*==========================================
@@ -7450,16 +7300,16 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper)
*------------------------------------------*/
int pc_equiplookall(struct map_session_data *sd)
{
- nullpo_ret(sd);
+ nullpo_ret(sd);
- clif_changelook(&sd->bl,LOOK_WEAPON,0);
- clif_changelook(&sd->bl,LOOK_SHOES,0);
- 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_changelook(&sd->bl, LOOK_ROBE, sd->status.robe);
+ clif_changelook(&sd->bl,LOOK_WEAPON,0);
+ clif_changelook(&sd->bl,LOOK_SHOES,0);
+ 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_changelook(&sd->bl, LOOK_ROBE, sd->status.robe);
- return 0;
+ return 0;
}
/*==========================================
@@ -7467,57 +7317,59 @@ int pc_equiplookall(struct map_session_data *sd)
*------------------------------------------*/
int pc_changelook(struct map_session_data *sd,int type,int val)
{
- nullpo_ret(sd);
-
- switch (type) {
- case LOOK_HAIR: //Use the battle_config limits! [Skotlex]
- val = cap_value(val, MIN_HAIR_STYLE, MAX_HAIR_STYLE);
-
- if (sd->status.hair != val) {
- sd->status.hair=val;
- if (sd->status.guild_id) //Update Guild Window. [Skotlex]
- intif_guild_change_memberinfo(sd->status.guild_id,sd->status.account_id,sd->status.char_id,
- GMI_HAIR,&sd->status.hair,sizeof(sd->status.hair));
- }
- break;
- case LOOK_WEAPON:
- sd->status.weapon=val;
- break;
- case LOOK_HEAD_BOTTOM:
- sd->status.head_bottom=val;
- break;
- case LOOK_HEAD_TOP:
- sd->status.head_top=val;
- break;
- case LOOK_HEAD_MID:
- sd->status.head_mid=val;
- break;
- case LOOK_HAIR_COLOR: //Use the battle_config limits! [Skotlex]
- val = cap_value(val, MIN_HAIR_COLOR, MAX_HAIR_COLOR);
-
- if (sd->status.hair_color != val) {
- sd->status.hair_color=val;
- if (sd->status.guild_id) //Update Guild Window. [Skotlex]
- intif_guild_change_memberinfo(sd->status.guild_id,sd->status.account_id,sd->status.char_id,
- GMI_HAIR_COLOR,&sd->status.hair_color,sizeof(sd->status.hair_color));
- }
- break;
- case LOOK_CLOTHES_COLOR: //Use the battle_config limits! [Skotlex]
- val = cap_value(val, MIN_CLOTH_COLOR, MAX_CLOTH_COLOR);
-
- sd->status.clothes_color=val;
- break;
- case LOOK_SHIELD:
- sd->status.shield=val;
- break;
- case LOOK_SHOES:
- break;
- case LOOK_ROBE:
- sd->status.robe = val;
- break;
- }
- clif_changelook(&sd->bl,type,val);
- return 0;
+ nullpo_ret(sd);
+
+ switch(type){
+ case LOOK_HAIR: //Use the battle_config limits! [Skotlex]
+ val = cap_value(val, MIN_HAIR_STYLE, MAX_HAIR_STYLE);
+
+ if (sd->status.hair != val)
+ {
+ sd->status.hair=val;
+ if (sd->status.guild_id) //Update Guild Window. [Skotlex]
+ intif_guild_change_memberinfo(sd->status.guild_id,sd->status.account_id,sd->status.char_id,
+ GMI_HAIR,&sd->status.hair,sizeof(sd->status.hair));
+ }
+ break;
+ case LOOK_WEAPON:
+ sd->status.weapon=val;
+ break;
+ case LOOK_HEAD_BOTTOM:
+ sd->status.head_bottom=val;
+ break;
+ case LOOK_HEAD_TOP:
+ sd->status.head_top=val;
+ break;
+ case LOOK_HEAD_MID:
+ sd->status.head_mid=val;
+ break;
+ case LOOK_HAIR_COLOR: //Use the battle_config limits! [Skotlex]
+ val = cap_value(val, MIN_HAIR_COLOR, MAX_HAIR_COLOR);
+
+ if (sd->status.hair_color != val)
+ {
+ sd->status.hair_color=val;
+ if (sd->status.guild_id) //Update Guild Window. [Skotlex]
+ intif_guild_change_memberinfo(sd->status.guild_id,sd->status.account_id,sd->status.char_id,
+ GMI_HAIR_COLOR,&sd->status.hair_color,sizeof(sd->status.hair_color));
+ }
+ break;
+ case LOOK_CLOTHES_COLOR: //Use the battle_config limits! [Skotlex]
+ val = cap_value(val, MIN_CLOTH_COLOR, MAX_CLOTH_COLOR);
+
+ sd->status.clothes_color=val;
+ break;
+ case LOOK_SHIELD:
+ sd->status.shield=val;
+ break;
+ case LOOK_SHOES:
+ break;
+ case LOOK_ROBE:
+ sd->status.robe = val;
+ break;
+ }
+ clif_changelook(&sd->bl,type,val);
+ return 0;
}
/*==========================================
@@ -7525,213 +7377,213 @@ int pc_changelook(struct map_session_data *sd,int type,int val)
*------------------------------------------*/
int pc_setoption(struct map_session_data *sd,int type)
{
- int p_type, new_look=0;
- nullpo_ret(sd);
- p_type = sd->sc.option;
-
- //Option has to be changed client-side before the class sprite or it won't always work (eg: Wedding sprite) [Skotlex]
- sd->sc.option=type;
- clif_changeoption(&sd->bl);
-
- if ((type&OPTION_RIDING && !(p_type&OPTION_RIDING)) || (type&OPTION_DRAGON && !(p_type&OPTION_DRAGON) && pc_checkskill(sd,RK_DRAGONTRAINING) > 0)) {
- // Mounting
- clif_status_load(&sd->bl,SI_RIDING,1);
- status_calc_pc(sd,0);
- } else if ((!(type&OPTION_RIDING) && p_type&OPTION_RIDING) || (!(type&OPTION_DRAGON) && p_type&OPTION_DRAGON && pc_checkskill(sd,RK_DRAGONTRAINING) > 0)) {
- // Dismount
- clif_status_load(&sd->bl,SI_RIDING,0);
- status_calc_pc(sd,0);
- }
+ int p_type, new_look=0;
+ nullpo_ret(sd);
+ p_type = sd->sc.option;
+
+ //Option has to be changed client-side before the class sprite or it won't always work (eg: Wedding sprite) [Skotlex]
+ sd->sc.option=type;
+ clif_changeoption(&sd->bl);
+
+ if( (type&OPTION_RIDING && !(p_type&OPTION_RIDING)) || (type&OPTION_DRAGON && !(p_type&OPTION_DRAGON) && pc_checkskill(sd,RK_DRAGONTRAINING) > 0) )
+ { // Mounting
+ clif_status_load(&sd->bl,SI_RIDING,1);
+ status_calc_pc(sd,0);
+ }
+ else if( (!(type&OPTION_RIDING) && p_type&OPTION_RIDING) || (!(type&OPTION_DRAGON) && p_type&OPTION_DRAGON && pc_checkskill(sd,RK_DRAGONTRAINING) > 0) )
+ { // Dismount
+ clif_status_load(&sd->bl,SI_RIDING,0);
+ status_calc_pc(sd,0);
+ }
#ifndef NEW_CARTS
- if (type&OPTION_CART && !(p_type&OPTION_CART)) { //Cart On
- clif_cartlist(sd);
- clif_updatestatus(sd, SP_CARTINFO);
- if (pc_checkskill(sd, MC_PUSHCART) < 10)
- status_calc_pc(sd,0); //Apply speed penalty.
- } else if (!(type&OPTION_CART) && p_type&OPTION_CART) { //Cart Off
- clif_clearcart(sd->fd);
- if (pc_checkskill(sd, MC_PUSHCART) < 10)
- status_calc_pc(sd,0); //Remove speed penalty.
- }
+ if( type&OPTION_CART && !( p_type&OPTION_CART ) ) { //Cart On
+ clif_cartlist(sd);
+ clif_updatestatus(sd, SP_CARTINFO);
+ if(pc_checkskill(sd, MC_PUSHCART) < 10)
+ status_calc_pc(sd,0); //Apply speed penalty.
+ } else if( !( type&OPTION_CART ) && p_type&OPTION_CART ){ //Cart Off
+ clif_clearcart(sd->fd);
+ if(pc_checkskill(sd, MC_PUSHCART) < 10)
+ status_calc_pc(sd,0); //Remove speed penalty.
+ }
#endif
- if (type&OPTION_MOUNTING && !(p_type&OPTION_MOUNTING)) {
- clif_status_load_notick(&sd->bl,SI_ALL_RIDING,2,1,0,0);
- status_calc_pc(sd,0);
- } else if (!(type&OPTION_MOUNTING) && p_type&OPTION_MOUNTING) {
- clif_status_load_notick(&sd->bl,SI_ALL_RIDING,0,0,0,0);
- status_calc_pc(sd,0);
- }
-
-
- if (type&OPTION_FALCON && !(p_type&OPTION_FALCON)) //Falcon ON
- clif_status_load(&sd->bl,SI_FALCON,1);
- else if (!(type&OPTION_FALCON) && p_type&OPTION_FALCON) //Falcon OFF
- clif_status_load(&sd->bl,SI_FALCON,0);
-
- if ((sd->class_&MAPID_THIRDMASK) == MAPID_RANGER) {
- if (type&OPTION_WUGRIDER && !(p_type&OPTION_WUGRIDER)) { // Mounting
- clif_status_load(&sd->bl,SI_WUGRIDER,1);
- status_calc_pc(sd,0);
- } else if (!(type&OPTION_WUGRIDER) && p_type&OPTION_WUGRIDER) { // Dismount
- clif_status_load(&sd->bl,SI_WUGRIDER,0);
- status_calc_pc(sd,0);
- }
- }
- if ((sd->class_&MAPID_THIRDMASK) == MAPID_MECHANIC) {
- if (type&OPTION_MADOGEAR && !(p_type&OPTION_MADOGEAR)) {
- status_calc_pc(sd, 0);
- status_change_end(&sd->bl,SC_MAXIMIZEPOWER,INVALID_TIMER);
- status_change_end(&sd->bl,SC_OVERTHRUST,INVALID_TIMER);
- status_change_end(&sd->bl,SC_WEAPONPERFECTION,INVALID_TIMER);
- status_change_end(&sd->bl,SC_ADRENALINE,INVALID_TIMER);
- status_change_end(&sd->bl,SC_CARTBOOST,INVALID_TIMER);
- status_change_end(&sd->bl,SC_MELTDOWN,INVALID_TIMER);
- status_change_end(&sd->bl,SC_MAXOVERTHRUST,INVALID_TIMER);
- } else if (!(type&OPTION_MADOGEAR) && p_type&OPTION_MADOGEAR) {
- status_calc_pc(sd, 0);
- status_change_end(&sd->bl,SC_SHAPESHIFT,INVALID_TIMER);
- status_change_end(&sd->bl,SC_HOVERING,INVALID_TIMER);
- status_change_end(&sd->bl,SC_ACCELERATION,INVALID_TIMER);
- status_change_end(&sd->bl,SC_OVERHEAT_LIMITPOINT,INVALID_TIMER);
- status_change_end(&sd->bl,SC_OVERHEAT,INVALID_TIMER);
- }
- }
-
- if (type&OPTION_FLYING && !(p_type&OPTION_FLYING))
- new_look = JOB_STAR_GLADIATOR2;
- else if (!(type&OPTION_FLYING) && p_type&OPTION_FLYING)
- new_look = -1;
-
- if (type&OPTION_WEDDING && !(p_type&OPTION_WEDDING))
- new_look = JOB_WEDDING;
- else if (!(type&OPTION_WEDDING) && p_type&OPTION_WEDDING)
- new_look = -1;
-
- if (type&OPTION_XMAS && !(p_type&OPTION_XMAS))
- new_look = JOB_XMAS;
- else if (!(type&OPTION_XMAS) && p_type&OPTION_XMAS)
- new_look = -1;
-
- if (type&OPTION_SUMMER && !(p_type&OPTION_SUMMER))
- new_look = JOB_SUMMER;
- else if (!(type&OPTION_SUMMER) && p_type&OPTION_SUMMER)
- new_look = -1;
-
- if (sd->disguise || !new_look)
- return 0; //Disguises break sprite changes
-
- if (new_look < 0) { //Restore normal look.
- status_set_viewdata(&sd->bl, sd->status.class_);
- new_look = sd->vd.class_;
- }
-
- pc_stop_attack(sd); //Stop attacking on new view change (to prevent wedding/santa attacks.
- clif_changelook(&sd->bl,LOOK_BASE,new_look);
- if (sd->vd.cloth_color)
- clif_changelook(&sd->bl,LOOK_CLOTHES_COLOR,sd->vd.cloth_color);
- clif_skillinfoblock(sd); // Skill list needs to be updated after base change.
-
- return 0;
+ if (type&OPTION_MOUNTING && !(p_type&OPTION_MOUNTING) ) {
+ clif_status_load_notick(&sd->bl,SI_ALL_RIDING,2,1,0,0);
+ status_calc_pc(sd,0);
+ } else if (!(type&OPTION_MOUNTING) && p_type&OPTION_MOUNTING) {
+ clif_status_load_notick(&sd->bl,SI_ALL_RIDING,0,0,0,0);
+ status_calc_pc(sd,0);
+ }
+
+
+ if (type&OPTION_FALCON && !(p_type&OPTION_FALCON)) //Falcon ON
+ clif_status_load(&sd->bl,SI_FALCON,1);
+ else if (!(type&OPTION_FALCON) && p_type&OPTION_FALCON) //Falcon OFF
+ clif_status_load(&sd->bl,SI_FALCON,0);
+
+ if( (sd->class_&MAPID_THIRDMASK) == MAPID_RANGER ) {
+ if( type&OPTION_WUGRIDER && !(p_type&OPTION_WUGRIDER) ) { // Mounting
+ clif_status_load(&sd->bl,SI_WUGRIDER,1);
+ status_calc_pc(sd,0);
+ } else if( !(type&OPTION_WUGRIDER) && p_type&OPTION_WUGRIDER ) { // Dismount
+ clif_status_load(&sd->bl,SI_WUGRIDER,0);
+ status_calc_pc(sd,0);
+ }
+ }
+ if( (sd->class_&MAPID_THIRDMASK) == MAPID_MECHANIC ) {
+ if( type&OPTION_MADOGEAR && !(p_type&OPTION_MADOGEAR) ) {
+ status_calc_pc(sd, 0);
+ status_change_end(&sd->bl,SC_MAXIMIZEPOWER,INVALID_TIMER);
+ status_change_end(&sd->bl,SC_OVERTHRUST,INVALID_TIMER);
+ status_change_end(&sd->bl,SC_WEAPONPERFECTION,INVALID_TIMER);
+ status_change_end(&sd->bl,SC_ADRENALINE,INVALID_TIMER);
+ status_change_end(&sd->bl,SC_CARTBOOST,INVALID_TIMER);
+ status_change_end(&sd->bl,SC_MELTDOWN,INVALID_TIMER);
+ status_change_end(&sd->bl,SC_MAXOVERTHRUST,INVALID_TIMER);
+ } else if( !(type&OPTION_MADOGEAR) && p_type&OPTION_MADOGEAR ) {
+ status_calc_pc(sd, 0);
+ status_change_end(&sd->bl,SC_SHAPESHIFT,INVALID_TIMER);
+ status_change_end(&sd->bl,SC_HOVERING,INVALID_TIMER);
+ status_change_end(&sd->bl,SC_ACCELERATION,INVALID_TIMER);
+ status_change_end(&sd->bl,SC_OVERHEAT_LIMITPOINT,INVALID_TIMER);
+ status_change_end(&sd->bl,SC_OVERHEAT,INVALID_TIMER);
+ }
+ }
+
+ if (type&OPTION_FLYING && !(p_type&OPTION_FLYING))
+ new_look = JOB_STAR_GLADIATOR2;
+ else if (!(type&OPTION_FLYING) && p_type&OPTION_FLYING)
+ new_look = -1;
+
+ if (type&OPTION_WEDDING && !(p_type&OPTION_WEDDING))
+ new_look = JOB_WEDDING;
+ else if (!(type&OPTION_WEDDING) && p_type&OPTION_WEDDING)
+ new_look = -1;
+
+ if (type&OPTION_XMAS && !(p_type&OPTION_XMAS))
+ new_look = JOB_XMAS;
+ else if (!(type&OPTION_XMAS) && p_type&OPTION_XMAS)
+ new_look = -1;
+
+ if (type&OPTION_SUMMER && !(p_type&OPTION_SUMMER))
+ new_look = JOB_SUMMER;
+ else if (!(type&OPTION_SUMMER) && p_type&OPTION_SUMMER)
+ new_look = -1;
+
+ if (sd->disguise || !new_look)
+ return 0; //Disguises break sprite changes
+
+ if (new_look < 0) { //Restore normal look.
+ status_set_viewdata(&sd->bl, sd->status.class_);
+ new_look = sd->vd.class_;
+ }
+
+ pc_stop_attack(sd); //Stop attacking on new view change (to prevent wedding/santa attacks.
+ clif_changelook(&sd->bl,LOOK_BASE,new_look);
+ if (sd->vd.cloth_color)
+ clif_changelook(&sd->bl,LOOK_CLOTHES_COLOR,sd->vd.cloth_color);
+ clif_skillinfoblock(sd); // Skill list needs to be updated after base change.
+
+ return 0;
}
/*==========================================
* Give player a cart
*------------------------------------------*/
-int pc_setcart(struct map_session_data *sd,int type)
-{
+int pc_setcart(struct map_session_data *sd,int type) {
#ifndef NEW_CARTS
- int cart[6] = {0x0000,OPTION_CART1,OPTION_CART2,OPTION_CART3,OPTION_CART4,OPTION_CART5};
- int option;
+ int cart[6] = {0x0000,OPTION_CART1,OPTION_CART2,OPTION_CART3,OPTION_CART4,OPTION_CART5};
+ int option;
#endif
- nullpo_ret(sd);
+ nullpo_ret(sd);
- if (type < 0 || type > MAX_CARTS)
- return 1;// Never trust the values sent by the client! [Skotlex]
+ if( type < 0 || type > MAX_CARTS )
+ return 1;// Never trust the values sent by the client! [Skotlex]
- if (pc_checkskill(sd,MC_PUSHCART) <= 0 && type != 0)
- return 1;// Push cart is required
+ if( pc_checkskill(sd,MC_PUSHCART) <= 0 && type != 0 )
+ return 1;// Push cart is required
- if (type == 0 && pc_iscarton(sd))
- status_change_end(&sd->bl,SC_GN_CARTBOOST,INVALID_TIMER);
+ if( type == 0 && pc_iscarton(sd) )
+ status_change_end(&sd->bl,SC_GN_CARTBOOST,INVALID_TIMER);
#ifdef NEW_CARTS
- switch (type) {
- case 0:
- if (!sd->sc.data[SC_PUSH_CART])
- return 0;
- status_change_end(&sd->bl,SC_PUSH_CART,INVALID_TIMER);
- clif_clearcart(sd->fd);
- break;
- default:/* everything else is an allowed ID so we can move on */
- if (!sd->sc.data[SC_PUSH_CART]) /* first time, so fill cart data */
- clif_cartlist(sd);
- clif_updatestatus(sd, SP_CARTINFO);
- sc_start(&sd->bl, SC_PUSH_CART, 100, type, 0);
- clif_status_load_notick(&sd->bl, SI_ON_PUSH_CART, 2 , type, 0, 0);
- if (sd->sc.data[SC_PUSH_CART]) /* forcefully update */
- sd->sc.data[SC_PUSH_CART]->val1 = type;
- break;
- }
-
- if (pc_checkskill(sd, MC_PUSHCART) < 10)
- status_calc_pc(sd,0); //Recalc speed penalty.
+ switch( type ) {
+ case 0:
+ if( !sd->sc.data[SC_PUSH_CART] )
+ return 0;
+ status_change_end(&sd->bl,SC_PUSH_CART,INVALID_TIMER);
+ clif_clearcart(sd->fd);
+ break;
+ default:/* everything else is an allowed ID so we can move on */
+ if( !sd->sc.data[SC_PUSH_CART] ) /* first time, so fill cart data */
+ clif_cartlist(sd);
+ clif_updatestatus(sd, SP_CARTINFO);
+ sc_start(&sd->bl, SC_PUSH_CART, 100, type, 0);
+ clif_status_load_notick(&sd->bl, SI_ON_PUSH_CART, 2 , type, 0, 0);
+ if( sd->sc.data[SC_PUSH_CART] )/* forcefully update */
+ sd->sc.data[SC_PUSH_CART]->val1 = type;
+ break;
+ }
+
+ if(pc_checkskill(sd, MC_PUSHCART) < 10)
+ status_calc_pc(sd,0); //Recalc speed penalty.
#else
- // Update option
- option = sd->sc.option;
- option &= ~OPTION_CART;// clear cart bits
- option |= cart[type]; // set cart
- pc_setoption(sd, option);
+ // Update option
+ option = sd->sc.option;
+ option &= ~OPTION_CART;// clear cart bits
+ option |= cart[type]; // set cart
+ pc_setoption(sd, option);
#endif
- return 0;
+ return 0;
}
/*==========================================
* Give player a falcon
*------------------------------------------*/
-int pc_setfalcon(TBL_PC *sd, int flag)
+int pc_setfalcon(TBL_PC* sd, int flag)
{
- if (flag) {
- if (pc_checkskill(sd,HT_FALCON)>0) // add falcon if he have the skill
- pc_setoption(sd,sd->sc.option|OPTION_FALCON);
- } else if (pc_isfalcon(sd)) {
- pc_setoption(sd,sd->sc.option&~OPTION_FALCON); // remove falcon
- }
+ if( flag ){
+ if( pc_checkskill(sd,HT_FALCON)>0 ) // add falcon if he have the skill
+ pc_setoption(sd,sd->sc.option|OPTION_FALCON);
+ } else if( pc_isfalcon(sd) ){
+ pc_setoption(sd,sd->sc.option&~OPTION_FALCON); // remove falcon
+ }
- return 0;
+ return 0;
}
/*==========================================
* Set player riding
*------------------------------------------*/
-int pc_setriding(TBL_PC *sd, int flag)
+int pc_setriding(TBL_PC* sd, int flag)
{
- if (flag) {
- if (pc_checkskill(sd,KN_RIDING) > 0) // add peco
- pc_setoption(sd, sd->sc.option|OPTION_RIDING);
- } else if (pc_isriding(sd)) {
- pc_setoption(sd, sd->sc.option&~OPTION_RIDING);
- }
+ if( flag ){
+ if( pc_checkskill(sd,KN_RIDING) > 0 ) // add peco
+ pc_setoption(sd, sd->sc.option|OPTION_RIDING);
+ } else if( pc_isriding(sd) ){
+ pc_setoption(sd, sd->sc.option&~OPTION_RIDING);
+ }
- return 0;
+ return 0;
}
/*==========================================
* Give player a mado
*------------------------------------------*/
-int pc_setmadogear(TBL_PC *sd, int flag)
+int pc_setmadogear(TBL_PC* sd, int flag)
{
- if (flag) {
- if (pc_checkskill(sd,NC_MADOLICENCE) > 0)
- pc_setoption(sd, sd->sc.option|OPTION_MADOGEAR);
- } else if (pc_ismadogear(sd)) {
- pc_setoption(sd, sd->sc.option&~OPTION_MADOGEAR);
- }
+ if( flag ){
+ if( pc_checkskill(sd,NC_MADOLICENCE) > 0 )
+ pc_setoption(sd, sd->sc.option|OPTION_MADOGEAR);
+ } else if( pc_ismadogear(sd) ){
+ pc_setoption(sd, sd->sc.option&~OPTION_MADOGEAR);
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -7739,333 +7591,347 @@ int pc_setmadogear(TBL_PC *sd, int flag)
*------------------------------------------*/
int pc_candrop(struct map_session_data *sd, struct item *item)
{
- if (item && item->expire_time)
- return 0;
- if (!pc_can_give_items(sd)) //check if this GM level can drop items
- return 0;
- return (itemdb_isdropable(item, pc_get_group_level(sd)));
+ if( item && item->expire_time )
+ return 0;
+ if( !pc_can_give_items(sd) ) //check if this GM level can drop items
+ return 0;
+ return (itemdb_isdropable(item, pc_get_group_level(sd)));
}
/*==========================================
* Read ram register for player sd
* get val (int) from reg for player sd
*------------------------------------------*/
-int pc_readreg(struct map_session_data *sd, int reg)
+int pc_readreg(struct map_session_data* sd, int reg)
{
- int i;
+ int i;
- nullpo_ret(sd);
+ nullpo_ret(sd);
- ARR_FIND(0, sd->reg_num, i, sd->reg[i].index == reg);
- return (i < sd->reg_num) ? sd->reg[i].data : 0;
+ ARR_FIND( 0, sd->reg_num, i, sd->reg[i].index == reg );
+ return ( i < sd->reg_num ) ? sd->reg[i].data : 0;
}
/*==========================================
* Set ram register for player sd
* memo val(int) at reg for player sd
*------------------------------------------*/
-int pc_setreg(struct map_session_data *sd, int reg, int val)
+int pc_setreg(struct map_session_data* sd, int reg, int val)
{
- int i;
+ int i;
- nullpo_ret(sd);
+ nullpo_ret(sd);
- ARR_FIND(0, sd->reg_num, i, sd->reg[i].index == reg);
- if (i < sd->reg_num) {
- // overwrite existing entry
- sd->reg[i].data = val;
- return 1;
- }
+ ARR_FIND( 0, sd->reg_num, i, sd->reg[i].index == reg );
+ if( i < sd->reg_num )
+ {// overwrite existing entry
+ sd->reg[i].data = val;
+ return 1;
+ }
- ARR_FIND(0, sd->reg_num, i, sd->reg[i].data == 0);
- if (i == sd->reg_num) {
- // nothing free, increase size
- sd->reg_num++;
- RECREATE(sd->reg, struct script_reg, sd->reg_num);
- }
- sd->reg[i].index = reg;
- sd->reg[i].data = val;
+ ARR_FIND( 0, sd->reg_num, i, sd->reg[i].data == 0 );
+ if( i == sd->reg_num )
+ {// nothing free, increase size
+ sd->reg_num++;
+ RECREATE(sd->reg, struct script_reg, sd->reg_num);
+ }
+ sd->reg[i].index = reg;
+ sd->reg[i].data = val;
- return 1;
+ return 1;
}
/*==========================================
* Read ram register for player sd
* get val (str) from reg for player sd
*------------------------------------------*/
-char *pc_readregstr(struct map_session_data *sd, int reg)
+char* pc_readregstr(struct map_session_data* sd, int reg)
{
- int i;
+ int i;
- nullpo_ret(sd);
+ nullpo_ret(sd);
- ARR_FIND(0, sd->regstr_num, i, sd->regstr[i].index == reg);
- return (i < sd->regstr_num) ? sd->regstr[i].data : NULL;
+ ARR_FIND( 0, sd->regstr_num, i, sd->regstr[i].index == reg );
+ return ( i < sd->regstr_num ) ? sd->regstr[i].data : NULL;
}
/*==========================================
* Set ram register for player sd
* memo val(str) at reg for player sd
*------------------------------------------*/
-int pc_setregstr(struct map_session_data *sd, int reg, const char *str)
-{
- int i;
-
- nullpo_ret(sd);
-
- ARR_FIND(0, sd->regstr_num, i, sd->regstr[i].index == reg);
- if (i < sd->regstr_num) {
- // found entry, update
- if (str == NULL || *str == '\0') {
- // empty string
- if (sd->regstr[i].data != NULL)
- aFree(sd->regstr[i].data);
- sd->regstr[i].data = NULL;
- } else if (sd->regstr[i].data) {
- // recreate
- size_t len = strlen(str)+1;
- RECREATE(sd->regstr[i].data, char, len);
- memcpy(sd->regstr[i].data, str, len*sizeof(char));
- } else {
- // create
- sd->regstr[i].data = aStrdup(str);
- }
- return 1;
- }
-
- if (str == NULL || *str == '\0')
- return 1;// nothing to add, empty string
-
- ARR_FIND(0, sd->regstr_num, i, sd->regstr[i].data == NULL);
- if (i == sd->regstr_num) {
- // nothing free, increase size
- sd->regstr_num++;
- RECREATE(sd->regstr, struct script_regstr, sd->regstr_num);
- }
- sd->regstr[i].index = reg;
- sd->regstr[i].data = aStrdup(str);
-
- return 1;
+int pc_setregstr(struct map_session_data* sd, int reg, const char* str)
+{
+ int i;
+
+ nullpo_ret(sd);
+
+ ARR_FIND( 0, sd->regstr_num, i, sd->regstr[i].index == reg );
+ if( i < sd->regstr_num )
+ {// found entry, update
+ if( str == NULL || *str == '\0' )
+ {// empty string
+ if( sd->regstr[i].data != NULL )
+ aFree(sd->regstr[i].data);
+ sd->regstr[i].data = NULL;
+ }
+ else if( sd->regstr[i].data )
+ {// recreate
+ size_t len = strlen(str)+1;
+ RECREATE(sd->regstr[i].data, char, len);
+ memcpy(sd->regstr[i].data, str, len*sizeof(char));
+ }
+ else
+ {// create
+ sd->regstr[i].data = aStrdup(str);
+ }
+ return 1;
+ }
+
+ if( str == NULL || *str == '\0' )
+ return 1;// nothing to add, empty string
+
+ ARR_FIND( 0, sd->regstr_num, i, sd->regstr[i].data == NULL );
+ if( i == sd->regstr_num )
+ {// nothing free, increase size
+ sd->regstr_num++;
+ RECREATE(sd->regstr, struct script_regstr, sd->regstr_num);
+ }
+ sd->regstr[i].index = reg;
+ sd->regstr[i].data = aStrdup(str);
+
+ return 1;
}
int pc_readregistry(struct map_session_data *sd,const char *reg,int type)
{
- struct global_reg *sd_reg;
- int i,max;
-
- nullpo_ret(sd);
- switch (type) {
- case 3: //Char reg
- sd_reg = sd->save_reg.global;
- max = sd->save_reg.global_num;
- break;
- case 2: //Account reg
- sd_reg = sd->save_reg.account;
- max = sd->save_reg.account_num;
- break;
- case 1: //Account2 reg
- sd_reg = sd->save_reg.account2;
- max = sd->save_reg.account2_num;
- break;
- default:
- return 0;
- }
- if (max == -1) {
- ShowError("pc_readregistry: Trying to read reg value %s (type %d) before it's been loaded!\n", reg, type);
- //This really shouldn't happen, so it's possible the data was lost somewhere, we should request it again.
- intif_request_registry(sd,type==3?4:type);
- return 0;
- }
-
- ARR_FIND(0, max, i, strcmp(sd_reg[i].str,reg) == 0);
- return (i < max) ? atoi(sd_reg[i].value) : 0;
-}
-
-char *pc_readregistry_str(struct map_session_data *sd,const char *reg,int type)
-{
- struct global_reg *sd_reg;
- int i,max;
-
- nullpo_ret(sd);
- switch (type) {
- case 3: //Char reg
- sd_reg = sd->save_reg.global;
- max = sd->save_reg.global_num;
- break;
- case 2: //Account reg
- sd_reg = sd->save_reg.account;
- max = sd->save_reg.account_num;
- break;
- case 1: //Account2 reg
- sd_reg = sd->save_reg.account2;
- max = sd->save_reg.account2_num;
- break;
- default:
- return NULL;
- }
- if (max == -1) {
- ShowError("pc_readregistry: Trying to read reg value %s (type %d) before it's been loaded!\n", reg, type);
- //This really shouldn't happen, so it's possible the data was lost somewhere, we should request it again.
- intif_request_registry(sd,type==3?4:type);
- return NULL;
- }
-
- ARR_FIND(0, max, i, strcmp(sd_reg[i].str,reg) == 0);
- return (i < max) ? sd_reg[i].value : NULL;
+ struct global_reg *sd_reg;
+ int i,max;
+
+ nullpo_ret(sd);
+ switch (type) {
+ case 3: //Char reg
+ sd_reg = sd->save_reg.global;
+ max = sd->save_reg.global_num;
+ break;
+ case 2: //Account reg
+ sd_reg = sd->save_reg.account;
+ max = sd->save_reg.account_num;
+ break;
+ case 1: //Account2 reg
+ sd_reg = sd->save_reg.account2;
+ max = sd->save_reg.account2_num;
+ break;
+ default:
+ return 0;
+ }
+ if (max == -1) {
+ ShowError("pc_readregistry: Trying to read reg value %s (type %d) before it's been loaded!\n", reg, type);
+ //This really shouldn't happen, so it's possible the data was lost somewhere, we should request it again.
+ intif_request_registry(sd,type==3?4:type);
+ return 0;
+ }
+
+ ARR_FIND( 0, max, i, strcmp(sd_reg[i].str,reg) == 0 );
+ return ( i < max ) ? atoi(sd_reg[i].value) : 0;
+}
+
+char* pc_readregistry_str(struct map_session_data *sd,const char *reg,int type)
+{
+ struct global_reg *sd_reg;
+ int i,max;
+
+ nullpo_ret(sd);
+ switch (type) {
+ case 3: //Char reg
+ sd_reg = sd->save_reg.global;
+ max = sd->save_reg.global_num;
+ break;
+ case 2: //Account reg
+ sd_reg = sd->save_reg.account;
+ max = sd->save_reg.account_num;
+ break;
+ case 1: //Account2 reg
+ sd_reg = sd->save_reg.account2;
+ max = sd->save_reg.account2_num;
+ break;
+ default:
+ return NULL;
+ }
+ if (max == -1) {
+ ShowError("pc_readregistry: Trying to read reg value %s (type %d) before it's been loaded!\n", reg, type);
+ //This really shouldn't happen, so it's possible the data was lost somewhere, we should request it again.
+ intif_request_registry(sd,type==3?4:type);
+ return NULL;
+ }
+
+ ARR_FIND( 0, max, i, strcmp(sd_reg[i].str,reg) == 0 );
+ return ( i < max ) ? sd_reg[i].value : NULL;
}
int pc_setregistry(struct map_session_data *sd,const char *reg,int val,int type)
{
- struct global_reg *sd_reg;
- int i,*max, regmax;
-
- nullpo_ret(sd);
-
- switch (type) {
- case 3: //Char reg
- if (!strcmp(reg,"PC_DIE_COUNTER") && sd->die_counter != val) {
- i = (!sd->die_counter && (sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE);
- sd->die_counter = val;
- if (i)
- status_calc_pc(sd,0); // Lost the bonus.
- } else if (!strcmp(reg,"COOK_MASTERY") && sd->cook_mastery != val) {
- val = cap_value(val, 0, 1999);
- sd->cook_mastery = val;
- }
- sd_reg = sd->save_reg.global;
- max = &sd->save_reg.global_num;
- regmax = GLOBAL_REG_NUM;
- break;
- case 2: //Account reg
- if (!strcmp(reg,"#CASHPOINTS") && sd->cashPoints != val) {
- val = cap_value(val, 0, MAX_ZENY);
- sd->cashPoints = val;
- } else if (!strcmp(reg,"#KAFRAPOINTS") && sd->kafraPoints != val) {
- val = cap_value(val, 0, MAX_ZENY);
- sd->kafraPoints = val;
- }
- sd_reg = sd->save_reg.account;
- max = &sd->save_reg.account_num;
- regmax = ACCOUNT_REG_NUM;
- break;
- case 1: //Account2 reg
- sd_reg = sd->save_reg.account2;
- max = &sd->save_reg.account2_num;
- regmax = ACCOUNT_REG2_NUM;
- break;
- default:
- return 0;
- }
- if (*max == -1) {
- ShowError("pc_setregistry : refusing to set %s (type %d) until vars are received.\n", reg, type);
- return 1;
- }
-
- // delete reg
- if (val == 0) {
- ARR_FIND(0, *max, i, strcmp(sd_reg[i].str, reg) == 0);
- if (i < *max) {
- if (i != *max - 1)
- memcpy(&sd_reg[i], &sd_reg[*max - 1], sizeof(struct global_reg));
- memset(&sd_reg[*max - 1], 0, sizeof(struct global_reg));
- (*max)--;
- sd->state.reg_dirty |= 1<<(type-1); //Mark this registry as "need to be saved"
- }
- return 1;
- }
- // change value if found
- ARR_FIND(0, *max, i, strcmp(sd_reg[i].str, reg) == 0);
- if (i < *max) {
- safesnprintf(sd_reg[i].value, sizeof(sd_reg[i].value), "%d", val);
- sd->state.reg_dirty |= 1<<(type-1);
- return 1;
- }
-
- // add value if not found
- if (i < regmax) {
- memset(&sd_reg[i], 0, sizeof(struct global_reg));
- safestrncpy(sd_reg[i].str, reg, sizeof(sd_reg[i].str));
- safesnprintf(sd_reg[i].value, sizeof(sd_reg[i].value), "%d", val);
- (*max)++;
- sd->state.reg_dirty |= 1<<(type-1);
- return 1;
- }
-
- ShowError("pc_setregistry : couldn't set %s, limit of registries reached (%d)\n", reg, regmax);
-
- return 0;
+ struct global_reg *sd_reg;
+ int i,*max, regmax;
+
+ nullpo_ret(sd);
+
+ switch( type )
+ {
+ case 3: //Char reg
+ if( !strcmp(reg,"PC_DIE_COUNTER") && sd->die_counter != val )
+ {
+ i = (!sd->die_counter && (sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE);
+ sd->die_counter = val;
+ if( i )
+ status_calc_pc(sd,0); // Lost the bonus.
+ }
+ else if( !strcmp(reg,"COOK_MASTERY") && sd->cook_mastery != val )
+ {
+ val = cap_value(val, 0, 1999);
+ sd->cook_mastery = val;
+ }
+ sd_reg = sd->save_reg.global;
+ max = &sd->save_reg.global_num;
+ regmax = GLOBAL_REG_NUM;
+ break;
+ case 2: //Account reg
+ if( !strcmp(reg,"#CASHPOINTS") && sd->cashPoints != val )
+ {
+ val = cap_value(val, 0, MAX_ZENY);
+ sd->cashPoints = val;
+ }
+ else if( !strcmp(reg,"#KAFRAPOINTS") && sd->kafraPoints != val )
+ {
+ val = cap_value(val, 0, MAX_ZENY);
+ sd->kafraPoints = val;
+ }
+ sd_reg = sd->save_reg.account;
+ max = &sd->save_reg.account_num;
+ regmax = ACCOUNT_REG_NUM;
+ break;
+ case 1: //Account2 reg
+ sd_reg = sd->save_reg.account2;
+ max = &sd->save_reg.account2_num;
+ regmax = ACCOUNT_REG2_NUM;
+ break;
+ default:
+ return 0;
+ }
+ if (*max == -1) {
+ ShowError("pc_setregistry : refusing to set %s (type %d) until vars are received.\n", reg, type);
+ return 1;
+ }
+
+ // delete reg
+ if (val == 0) {
+ ARR_FIND( 0, *max, i, strcmp(sd_reg[i].str, reg) == 0 );
+ if( i < *max )
+ {
+ if (i != *max - 1)
+ memcpy(&sd_reg[i], &sd_reg[*max - 1], sizeof(struct global_reg));
+ memset(&sd_reg[*max - 1], 0, sizeof(struct global_reg));
+ (*max)--;
+ sd->state.reg_dirty |= 1<<(type-1); //Mark this registry as "need to be saved"
+ }
+ return 1;
+ }
+ // change value if found
+ ARR_FIND( 0, *max, i, strcmp(sd_reg[i].str, reg) == 0 );
+ if( i < *max )
+ {
+ safesnprintf(sd_reg[i].value, sizeof(sd_reg[i].value), "%d", val);
+ sd->state.reg_dirty |= 1<<(type-1);
+ return 1;
+ }
+
+ // add value if not found
+ if (i < regmax) {
+ memset(&sd_reg[i], 0, sizeof(struct global_reg));
+ safestrncpy(sd_reg[i].str, reg, sizeof(sd_reg[i].str));
+ safesnprintf(sd_reg[i].value, sizeof(sd_reg[i].value), "%d", val);
+ (*max)++;
+ sd->state.reg_dirty |= 1<<(type-1);
+ return 1;
+ }
+
+ ShowError("pc_setregistry : couldn't set %s, limit of registries reached (%d)\n", reg, regmax);
+
+ return 0;
}
int pc_setregistry_str(struct map_session_data *sd,const char *reg,const char *val,int type)
{
- struct global_reg *sd_reg;
- int i,*max, regmax;
-
- nullpo_ret(sd);
- if (reg[strlen(reg)-1] != '$') {
- ShowError("pc_setregistry_str : reg %s must be string (end in '$') to use this!\n", reg);
- return 0;
- }
-
- switch (type) {
- case 3: //Char reg
- sd_reg = sd->save_reg.global;
- max = &sd->save_reg.global_num;
- regmax = GLOBAL_REG_NUM;
- break;
- case 2: //Account reg
- sd_reg = sd->save_reg.account;
- max = &sd->save_reg.account_num;
- regmax = ACCOUNT_REG_NUM;
- break;
- case 1: //Account2 reg
- sd_reg = sd->save_reg.account2;
- max = &sd->save_reg.account2_num;
- regmax = ACCOUNT_REG2_NUM;
- break;
- default:
- return 0;
- }
- if (*max == -1) {
- ShowError("pc_setregistry_str : refusing to set %s (type %d) until vars are received.\n", reg, type);
- return 0;
- }
-
- // delete reg
- if (!val || strcmp(val,"")==0) {
- ARR_FIND(0, *max, i, strcmp(sd_reg[i].str, reg) == 0);
- if (i < *max) {
- if (i != *max - 1)
- memcpy(&sd_reg[i], &sd_reg[*max - 1], sizeof(struct global_reg));
- memset(&sd_reg[*max - 1], 0, sizeof(struct global_reg));
- (*max)--;
- sd->state.reg_dirty |= 1<<(type-1); //Mark this registry as "need to be saved"
- if (type!=3) intif_saveregistry(sd,type);
- }
- return 1;
- }
-
- // change value if found
- ARR_FIND(0, *max, i, strcmp(sd_reg[i].str, reg) == 0);
- if (i < *max) {
- safestrncpy(sd_reg[i].value, val, sizeof(sd_reg[i].value));
- sd->state.reg_dirty |= 1<<(type-1); //Mark this registry as "need to be saved"
- if (type!=3) intif_saveregistry(sd,type);
- return 1;
- }
-
- // add value if not found
- if (i < regmax) {
- memset(&sd_reg[i], 0, sizeof(struct global_reg));
- safestrncpy(sd_reg[i].str, reg, sizeof(sd_reg[i].str));
- safestrncpy(sd_reg[i].value, val, sizeof(sd_reg[i].value));
- (*max)++;
- sd->state.reg_dirty |= 1<<(type-1); //Mark this registry as "need to be saved"
- if (type!=3) intif_saveregistry(sd,type);
- return 1;
- }
-
- ShowError("pc_setregistry : couldn't set %s, limit of registries reached (%d)\n", reg, regmax);
-
- return 0;
+ struct global_reg *sd_reg;
+ int i,*max, regmax;
+
+ nullpo_ret(sd);
+ if (reg[strlen(reg)-1] != '$') {
+ ShowError("pc_setregistry_str : reg %s must be string (end in '$') to use this!\n", reg);
+ return 0;
+ }
+
+ switch (type) {
+ case 3: //Char reg
+ sd_reg = sd->save_reg.global;
+ max = &sd->save_reg.global_num;
+ regmax = GLOBAL_REG_NUM;
+ break;
+ case 2: //Account reg
+ sd_reg = sd->save_reg.account;
+ max = &sd->save_reg.account_num;
+ regmax = ACCOUNT_REG_NUM;
+ break;
+ case 1: //Account2 reg
+ sd_reg = sd->save_reg.account2;
+ max = &sd->save_reg.account2_num;
+ regmax = ACCOUNT_REG2_NUM;
+ break;
+ default:
+ return 0;
+ }
+ if (*max == -1) {
+ ShowError("pc_setregistry_str : refusing to set %s (type %d) until vars are received.\n", reg, type);
+ return 0;
+ }
+
+ // delete reg
+ if (!val || strcmp(val,"")==0)
+ {
+ ARR_FIND( 0, *max, i, strcmp(sd_reg[i].str, reg) == 0 );
+ if( i < *max )
+ {
+ if (i != *max - 1)
+ memcpy(&sd_reg[i], &sd_reg[*max - 1], sizeof(struct global_reg));
+ memset(&sd_reg[*max - 1], 0, sizeof(struct global_reg));
+ (*max)--;
+ sd->state.reg_dirty |= 1<<(type-1); //Mark this registry as "need to be saved"
+ if (type!=3) intif_saveregistry(sd,type);
+ }
+ return 1;
+ }
+
+ // change value if found
+ ARR_FIND( 0, *max, i, strcmp(sd_reg[i].str, reg) == 0 );
+ if( i < *max )
+ {
+ safestrncpy(sd_reg[i].value, val, sizeof(sd_reg[i].value));
+ sd->state.reg_dirty |= 1<<(type-1); //Mark this registry as "need to be saved"
+ if (type!=3) intif_saveregistry(sd,type);
+ return 1;
+ }
+
+ // add value if not found
+ if (i < regmax) {
+ memset(&sd_reg[i], 0, sizeof(struct global_reg));
+ safestrncpy(sd_reg[i].str, reg, sizeof(sd_reg[i].str));
+ safestrncpy(sd_reg[i].value, val, sizeof(sd_reg[i].value));
+ (*max)++;
+ sd->state.reg_dirty |= 1<<(type-1); //Mark this registry as "need to be saved"
+ if (type!=3) intif_saveregistry(sd,type);
+ return 1;
+ }
+
+ ShowError("pc_setregistry : couldn't set %s, limit of registries reached (%d)\n", reg, regmax);
+
+ return 0;
}
/*==========================================
@@ -8073,22 +7939,24 @@ int pc_setregistry_str(struct map_session_data *sd,const char *reg,const char *v
*------------------------------------------*/
static int pc_eventtimer(int tid, unsigned int tick, int id, intptr_t data)
{
- struct map_session_data *sd=map_id2sd(id);
- char *p = (char *)data;
- int i;
- if (sd==NULL)
- return 0;
+ struct map_session_data *sd=map_id2sd(id);
+ char *p = (char *)data;
+ int i;
+ if(sd==NULL)
+ return 0;
- ARR_FIND(0, MAX_EVENTTIMER, i, sd->eventtimer[i] == tid);
- if (i < MAX_EVENTTIMER) {
- sd->eventtimer[i] = INVALID_TIMER;
- sd->eventcount--;
- npc_event(sd,p,0);
- } else
- ShowError("pc_eventtimer: no such event timer\n");
+ ARR_FIND( 0, MAX_EVENTTIMER, i, sd->eventtimer[i] == tid );
+ if( i < MAX_EVENTTIMER )
+ {
+ sd->eventtimer[i] = INVALID_TIMER;
+ sd->eventcount--;
+ npc_event(sd,p,0);
+ }
+ else
+ ShowError("pc_eventtimer: no such event timer\n");
- if (p) aFree(p);
- return 0;
+ if (p) aFree(p);
+ return 0;
}
/*==========================================
@@ -8096,17 +7964,17 @@ static int pc_eventtimer(int tid, unsigned int tick, int id, intptr_t data)
*------------------------------------------*/
int pc_addeventtimer(struct map_session_data *sd,int tick,const char *name)
{
- int i;
- nullpo_ret(sd);
+ int i;
+ nullpo_ret(sd);
- ARR_FIND(0, MAX_EVENTTIMER, i, sd->eventtimer[i] == INVALID_TIMER);
- if (i == MAX_EVENTTIMER)
- return 0;
+ ARR_FIND( 0, MAX_EVENTTIMER, i, sd->eventtimer[i] == INVALID_TIMER );
+ if( i == MAX_EVENTTIMER )
+ return 0;
- sd->eventtimer[i] = add_timer(gettick()+tick, pc_eventtimer, sd->bl.id, (intptr_t)aStrdup(name));
- sd->eventcount++;
+ sd->eventtimer[i] = add_timer(gettick()+tick, pc_eventtimer, sd->bl.id, (intptr_t)aStrdup(name));
+ sd->eventcount++;
- return 1;
+ return 1;
}
/*==========================================
@@ -8114,29 +7982,29 @@ int pc_addeventtimer(struct map_session_data *sd,int tick,const char *name)
*------------------------------------------*/
int pc_deleventtimer(struct map_session_data *sd,const char *name)
{
- char *p = NULL;
- int i;
+ char* p = NULL;
+ int i;
- nullpo_ret(sd);
+ nullpo_ret(sd);
- if (sd->eventcount <= 0)
- return 0;
+ if (sd->eventcount <= 0)
+ return 0;
- // find the named event timer
- ARR_FIND(0, MAX_EVENTTIMER, i,
- sd->eventtimer[i] != INVALID_TIMER &&
- (p = (char *)(get_timer(sd->eventtimer[i])->data)) != NULL &&
- strcmp(p, name) == 0
- );
- if (i == MAX_EVENTTIMER)
- return 0; // not found
+ // find the named event timer
+ ARR_FIND( 0, MAX_EVENTTIMER, i,
+ sd->eventtimer[i] != INVALID_TIMER &&
+ (p = (char *)(get_timer(sd->eventtimer[i])->data)) != NULL &&
+ strcmp(p, name) == 0
+ );
+ if( i == MAX_EVENTTIMER )
+ return 0; // not found
- delete_timer(sd->eventtimer[i],pc_eventtimer);
- sd->eventtimer[i] = INVALID_TIMER;
- sd->eventcount--;
- aFree(p);
+ delete_timer(sd->eventtimer[i],pc_eventtimer);
+ sd->eventtimer[i] = INVALID_TIMER;
+ sd->eventcount--;
+ aFree(p);
- return 1;
+ return 1;
}
/*==========================================
@@ -8144,18 +8012,18 @@ int pc_deleventtimer(struct map_session_data *sd,const char *name)
*------------------------------------------*/
int pc_addeventtimercount(struct map_session_data *sd,const char *name,int tick)
{
- int i;
+ int i;
- nullpo_ret(sd);
+ nullpo_ret(sd);
- for (i=0; i<MAX_EVENTTIMER; i++)
- if (sd->eventtimer[i] != INVALID_TIMER && strcmp(
- (char *)(get_timer(sd->eventtimer[i])->data), name)==0) {
- addtick_timer(sd->eventtimer[i],tick);
- break;
- }
+ for(i=0;i<MAX_EVENTTIMER;i++)
+ if( sd->eventtimer[i] != INVALID_TIMER && strcmp(
+ (char *)(get_timer(sd->eventtimer[i])->data), name)==0 ){
+ addtick_timer(sd->eventtimer[i],tick);
+ break;
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -8163,369 +8031,373 @@ int pc_addeventtimercount(struct map_session_data *sd,const char *name,int tick)
*------------------------------------------*/
int pc_cleareventtimer(struct map_session_data *sd)
{
- int i;
+ int i;
- nullpo_ret(sd);
+ nullpo_ret(sd);
- if (sd->eventcount <= 0)
- return 0;
+ if (sd->eventcount <= 0)
+ return 0;
- for (i=0; i<MAX_EVENTTIMER; i++)
- if (sd->eventtimer[i] != INVALID_TIMER) {
- char *p = (char *)(get_timer(sd->eventtimer[i])->data);
- delete_timer(sd->eventtimer[i],pc_eventtimer);
- sd->eventtimer[i] = INVALID_TIMER;
- sd->eventcount--;
- if (p) aFree(p);
- }
- return 0;
+ for(i=0;i<MAX_EVENTTIMER;i++)
+ if( sd->eventtimer[i] != INVALID_TIMER ){
+ char *p = (char *)(get_timer(sd->eventtimer[i])->data);
+ delete_timer(sd->eventtimer[i],pc_eventtimer);
+ sd->eventtimer[i] = INVALID_TIMER;
+ sd->eventcount--;
+ if (p) aFree(p);
+ }
+ return 0;
}
/* called when a item with combo is worn */
-int pc_checkcombo(struct map_session_data *sd, struct item_data *data)
-{
- int i, j, k, z;
- int index, idx, success = 0;
+int pc_checkcombo(struct map_session_data *sd, struct item_data *data ) {
+ int i, j, k, z;
+ int index, idx, success = 0;
- for (i = 0; i < data->combos_count; i++) {
+ for( i = 0; i < data->combos_count; i++ ) {
- /* ensure this isn't a duplicate combo */
- if (sd->combos.bonus != NULL) {
- int x;
- ARR_FIND(0, sd->combos.count, x, sd->combos.id[x] == data->combos[i]->id);
+ /* ensure this isn't a duplicate combo */
+ if( sd->combos.bonus != NULL ) {
+ int x;
+ ARR_FIND( 0, sd->combos.count, x, sd->combos.id[x] == data->combos[i]->id );
- /* found a match, skip this combo */
- if (x < sd->combos.count)
- continue;
- }
+ /* found a match, skip this combo */
+ if( x < sd->combos.count )
+ continue;
+ }
- for (j = 0; j < data->combos[i]->count; j++) {
- int id = data->combos[i]->nameid[j];
- bool found = false;
+ for( j = 0; j < data->combos[i]->count; j++ ) {
+ int id = data->combos[i]->nameid[j];
+ bool found = false;
- for (k = 0; k < EQI_MAX; k++) {
- index = sd->equip_index[k];
- if (index < 0) continue;
- if (k == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == index) continue;
- if (k == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == index) continue;
- if (k == EQI_HEAD_TOP && (sd->equip_index[EQI_HEAD_MID] == index || sd->equip_index[EQI_HEAD_LOW] == index)) continue;
+ for( k = 0; k < EQI_MAX; k++ ) {
+ index = sd->equip_index[k];
+ if( index < 0 ) continue;
+ if( k == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == index ) continue;
+ if( k == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == index ) continue;
+ if( k == EQI_HEAD_TOP && (sd->equip_index[EQI_HEAD_MID] == index || sd->equip_index[EQI_HEAD_LOW] == index) ) continue;
- if (!sd->inventory_data[index])
- continue;
+ if(!sd->inventory_data[index])
+ continue;
- if (itemdb_type(id) != IT_CARD) {
- if (sd->inventory_data[index]->nameid != id)
- continue;
+ if ( itemdb_type(id) != IT_CARD ) {
+ if ( sd->inventory_data[index]->nameid != id )
+ continue;
- found = true;
- break;
- } else { //Cards
- if (sd->inventory_data[index]->slot == 0 || itemdb_isspecial(sd->status.inventory[index].card[0]))
- continue;
+ found = true;
+ break;
+ } else { //Cards
+ if ( sd->inventory_data[index]->slot == 0 || itemdb_isspecial(sd->status.inventory[index].card[0]) )
+ continue;
- for (z = 0; z < sd->inventory_data[index]->slot; z++) {
+ for (z = 0; z < sd->inventory_data[index]->slot; z++) {
- if (sd->status.inventory[index].card[z] != id)
- continue;
+ if (sd->status.inventory[index].card[z] != id)
+ continue;
- // We have found a match
- found = true;
- break;
- }
- }
+ // We have found a match
+ found = true;
+ break;
+ }
+ }
- }
+ }
- if (!found)
- break;/* we haven't found all the ids for this combo, so we can return */
- }
+ if( !found )
+ break;/* we haven't found all the ids for this combo, so we can return */
+ }
- /* means we broke out of the count loop w/o finding all ids, we can move to the next combo */
- if (j < data->combos[i]->count)
- continue;
+ /* means we broke out of the count loop w/o finding all ids, we can move to the next combo */
+ if( j < data->combos[i]->count )
+ continue;
- /* we got here, means all items in the combo are matching */
+ /* we got here, means all items in the combo are matching */
- idx = sd->combos.count;
+ idx = sd->combos.count;
- if (sd->combos.bonus == NULL) {
- CREATE(sd->combos.bonus, struct script_code *, 1);
- CREATE(sd->combos.id, unsigned short, 1);
- sd->combos.count = 1;
- } else {
- RECREATE(sd->combos.bonus, struct script_code *, ++sd->combos.count);
- RECREATE(sd->combos.id, unsigned short, sd->combos.count);
- }
+ if( sd->combos.bonus == NULL ) {
+ CREATE(sd->combos.bonus, struct script_code *, 1);
+ CREATE(sd->combos.id, unsigned short, 1);
+ sd->combos.count = 1;
+ } else {
+ RECREATE(sd->combos.bonus, struct script_code *, ++sd->combos.count);
+ RECREATE(sd->combos.id, unsigned short, sd->combos.count);
+ }
- /* we simply copy the pointer */
- sd->combos.bonus[idx] = data->combos[i]->script;
- /* save this combo's id */
- sd->combos.id[idx] = data->combos[i]->id;
+ /* we simply copy the pointer */
+ sd->combos.bonus[idx] = data->combos[i]->script;
+ /* save this combo's id */
+ sd->combos.id[idx] = data->combos[i]->id;
- success++;
- }
- return success;
+ success++;
+ }
+ return success;
}
/* called when a item with combo is removed */
-int pc_removecombo(struct map_session_data *sd, struct item_data *data)
-{
- int i, retval = 0;
-
- if (sd->combos.bonus == NULL)
- return 0;/* nothing to do here, player has no combos */
- for (i = 0; i < data->combos_count; i++) {
- /* check if this combo exists in this user */
- int x = 0, cursor = 0, j;
- ARR_FIND(0, sd->combos.count, x, sd->combos.id[x] == data->combos[i]->id);
- /* no match, skip this combo */
- if (!(x < sd->combos.count))
- continue;
-
- sd->combos.bonus[x] = NULL;
- sd->combos.id[x] = 0;
- retval++;
- for (j = 0, cursor = 0; j < sd->combos.count; j++) {
- if (sd->combos.bonus[j] == NULL)
- continue;
-
- if (cursor != j) {
- sd->combos.bonus[cursor] = sd->combos.bonus[j];
- sd->combos.id[cursor] = sd->combos.id[j];
- }
-
- cursor++;
- }
-
- /* it's empty, we can clear all the memory */
- if ((sd->combos.count = cursor) == 0) {
- aFree(sd->combos.bonus);
- aFree(sd->combos.id);
- sd->combos.bonus = NULL;
- sd->combos.id = NULL;
- return retval; /* we also can return at this point for we have no more combos to check */
- }
-
- }
-
- return retval;
-}
-int pc_load_combo(struct map_session_data *sd)
-{
- int i, ret = 0;
- for (i = 0; i < EQI_MAX; i++) {
- struct item_data *id = NULL;
- int idx = sd->equip_index[i];
- if (sd->equip_index[i] < 0 || !(id = sd->inventory_data[idx]))
- continue;
- if (id->combos_count)
- ret += pc_checkcombo(sd,id);
- if (!itemdb_isspecial(sd->status.inventory[idx].card[0])) {
- struct item_data *data;
- int j;
- for (j = 0; j < id->slot; j++) {
- if (!sd->status.inventory[idx].card[j])
- continue;
- if ((data = itemdb_exists(sd->status.inventory[idx].card[j])) != NULL) {
- if (data->combos_count)
- ret += pc_checkcombo(sd,data);
- }
- }
- }
- }
- return ret;
+int pc_removecombo(struct map_session_data *sd, struct item_data *data ) {
+ int i, retval = 0;
+
+ if( sd->combos.bonus == NULL )
+ return 0;/* nothing to do here, player has no combos */
+ for( i = 0; i < data->combos_count; i++ ) {
+ /* check if this combo exists in this user */
+ int x = 0, cursor = 0, j;
+ ARR_FIND( 0, sd->combos.count, x, sd->combos.id[x] == data->combos[i]->id );
+ /* no match, skip this combo */
+ if( !(x < sd->combos.count) )
+ continue;
+
+ sd->combos.bonus[x] = NULL;
+ sd->combos.id[x] = 0;
+ retval++;
+ for( j = 0, cursor = 0; j < sd->combos.count; j++ ) {
+ if( sd->combos.bonus[j] == NULL )
+ continue;
+
+ if( cursor != j ) {
+ sd->combos.bonus[cursor] = sd->combos.bonus[j];
+ sd->combos.id[cursor] = sd->combos.id[j];
+ }
+
+ cursor++;
+ }
+
+ /* it's empty, we can clear all the memory */
+ if( (sd->combos.count = cursor) == 0 ) {
+ aFree(sd->combos.bonus);
+ aFree(sd->combos.id);
+ sd->combos.bonus = NULL;
+ sd->combos.id = NULL;
+ return retval; /* we also can return at this point for we have no more combos to check */
+ }
+
+ }
+
+ return retval;
+}
+int pc_load_combo(struct map_session_data *sd) {
+ int i, ret = 0;
+ for( i = 0; i < EQI_MAX; i++ ) {
+ struct item_data *id = NULL;
+ int idx = sd->equip_index[i];
+ if( sd->equip_index[i] < 0 || !(id = sd->inventory_data[idx] ) )
+ continue;
+ if( id->combos_count )
+ ret += pc_checkcombo(sd,id);
+ if(!itemdb_isspecial(sd->status.inventory[idx].card[0])) {
+ struct item_data *data;
+ int j;
+ for( j = 0; j < id->slot; j++ ) {
+ if (!sd->status.inventory[idx].card[j])
+ continue;
+ if ( ( data = itemdb_exists(sd->status.inventory[idx].card[j]) ) != NULL ) {
+ if( data->combos_count )
+ ret += pc_checkcombo(sd,data);
+ }
+ }
+ }
+ }
+ return ret;
}
/*==========================================
* Equip item on player sd at req_pos from inventory index n
*------------------------------------------*/
int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
{
- int i,pos,flag=0;
- struct item_data *id;
-
- nullpo_ret(sd);
-
- if (n < 0 || n >= MAX_INVENTORY) {
- clif_equipitemack(sd,0,0,0);
- return 0;
- }
-
- if (DIFF_TICK(sd->canequip_tick,gettick()) > 0) {
- clif_equipitemack(sd,n,0,0);
- return 0;
- }
-
- id = sd->inventory_data[n];
- pos = pc_equippoint(sd,n); //With a few exceptions, item should go in all specified slots.
-
- if (battle_config.battle_log)
- ShowInfo("equip %d(%d) %x:%x\n",sd->status.inventory[n].nameid,n,id?id->equip:0,req_pos);
- if (!pc_isequip(sd,n) || !(pos&req_pos) || sd->status.inventory[n].equip != 0 || sd->status.inventory[n].attribute==1) { // [Valaris]
- // FIXME: pc_isequip: equip level failure uses 2 instead of 0
- clif_equipitemack(sd,n,0,0); // fail
- return 0;
- }
-
- if (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_SATURDAYNIGHTFEVER] || sd->sc.data[SC__BLOODYLUST]) {
- clif_equipitemack(sd,n,0,0); // fail
- return 0;
- }
-
- if (pos == EQP_ACC) { //Accesories should only go in one of the two,
- pos = req_pos&EQP_ACC;
- if (pos == EQP_ACC) //User specified both slots..
- pos = sd->equip_index[EQI_ACC_R] >= 0 ? EQP_ACC_L : EQP_ACC_R;
- }
-
- if (pos == EQP_ARMS && id->equip == EQP_HAND_R) {
- //Dual wield capable weapon.
- pos = (req_pos&EQP_ARMS);
- if (pos == EQP_ARMS) //User specified both slots, pick one for them.
- pos = sd->equip_index[EQI_HAND_R] >= 0 ? EQP_HAND_L : EQP_HAND_R;
- }
-
- if (pos&EQP_HAND_R && battle_config.use_weapon_skill_range&BL_PC) {
- //Update skill-block range database when weapon range changes. [Skotlex]
- i = sd->equip_index[EQI_HAND_R];
- if (i < 0 || !sd->inventory_data[i]) //No data, or no weapon equipped
- flag = 1;
- else
- flag = id->range != sd->inventory_data[i]->range;
- }
-
- for (i=0; i<EQI_MAX; i++) {
- if (pos & equip_pos[i]) {
- if (sd->equip_index[i] >= 0) //Slot taken, remove item from there.
- pc_unequipitem(sd,sd->equip_index[i],2);
-
- sd->equip_index[i] = n;
- }
- }
-
- if (pos==EQP_AMMO) {
- clif_arrowequip(sd,n);
- clif_arrow_fail(sd,3);
- } else
- clif_equipitemack(sd,n,pos,1);
-
- sd->status.inventory[n].equip=pos;
-
- if (pos & EQP_HAND_R) {
- if (id)
- sd->weapontype1 = id->look;
- else
- sd->weapontype1 = 0;
- pc_calcweapontype(sd);
- clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
- }
- if (pos & EQP_HAND_L) {
- if (id) {
- if (id->type == IT_WEAPON) {
- sd->status.shield = 0;
- sd->weapontype2 = id->look;
- } else if (id->type == IT_ARMOR) {
- sd->status.shield = id->look;
- sd->weapontype2 = 0;
- }
- } else
- sd->status.shield = sd->weapontype2 = 0;
- pc_calcweapontype(sd);
- clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
- }
- //Added check to prevent sending the same look on multiple slots ->
- //causes client to redraw item on top of itself. (suggested by Lupus)
- if (pos & EQP_HEAD_LOW && pc_checkequip(sd,EQP_COSTUME_HEAD_LOW) == -1) {
- if (id && !(pos&(EQP_HEAD_TOP|EQP_HEAD_MID)))
- sd->status.head_bottom = id->look;
- else
- sd->status.head_bottom = 0;
- clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
- }
- if (pos & EQP_HEAD_TOP && pc_checkequip(sd,EQP_COSTUME_HEAD_TOP) == -1) {
- if (id)
- sd->status.head_top = id->look;
- else
- sd->status.head_top = 0;
- clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
- }
- if (pos & EQP_HEAD_MID && pc_checkequip(sd,EQP_COSTUME_HEAD_MID) == -1) {
- if (id && !(pos&EQP_HEAD_TOP))
- sd->status.head_mid = id->look;
- else
- sd->status.head_mid = 0;
- clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
- }
- if (pos & EQP_COSTUME_HEAD_TOP) {
- if (id) {
- sd->status.head_top = id->look;
- } else
- sd->status.head_top = 0;
- clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
- }
- if (pos & EQP_COSTUME_HEAD_MID) {
- if (id && !(pos&EQP_HEAD_TOP)) {
- sd->status.head_mid = id->look;
- } else
- sd->status.head_mid = 0;
- clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
- }
- if (pos & EQP_COSTUME_HEAD_LOW) {
- if (id && !(pos&(EQP_HEAD_TOP|EQP_HEAD_MID))) {
- sd->status.head_bottom = id->look;
- } else
- sd->status.head_bottom = 0;
- clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
- }
- if (pos & EQP_SHOES)
- clif_changelook(&sd->bl,LOOK_SHOES,0);
- if (pos&EQP_GARMENT) {
- sd->status.robe = id ? id->look : 0;
- clif_changelook(&sd->bl, LOOK_ROBE, sd->status.robe);
- }
-
- pc_checkallowskill(sd); //Check if status changes should be halted.
-
- /* check for combos (MUST be before status_calc_pc) */
- if (id) {
- struct item_data *data;
- if (id->combos_count)
- pc_checkcombo(sd,id);
- if (itemdb_isspecial(sd->status.inventory[n].card[0]))
- ; //No cards
- else {
- for (i = 0; i < id->slot; i++) {
- if (!sd->status.inventory[n].card[i])
- continue;
- if ((data = itemdb_exists(sd->status.inventory[n].card[i])) != NULL) {
- if (data->combos_count)
- pc_checkcombo(sd,data);
- }
- }
- }
- }
-
- status_calc_pc(sd,0);
- if (flag) //Update skill data
- clif_skillinfoblock(sd);
-
- //OnEquip script [Skotlex]
- if (id) {
- struct item_data *data;
- if (id->equip_script)
- run_script(id->equip_script,0,sd->bl.id,fake_nd->bl.id);
- if (itemdb_isspecial(sd->status.inventory[n].card[0]))
- ; //No cards
- else {
- for (i = 0; i < id->slot; i++) {
- if (!sd->status.inventory[n].card[i])
- continue;
- if ((data = itemdb_exists(sd->status.inventory[n].card[i])) != NULL) {
- if (data->equip_script)
- run_script(data->equip_script,0,sd->bl.id,fake_nd->bl.id);
- }
- }
- }
- }
- return 0;
+ int i,pos,flag=0;
+ struct item_data *id;
+
+ nullpo_ret(sd);
+
+ if( n < 0 || n >= MAX_INVENTORY ) {
+ clif_equipitemack(sd,0,0,0);
+ return 0;
+ }
+
+ if( DIFF_TICK(sd->canequip_tick,gettick()) > 0 )
+ {
+ clif_equipitemack(sd,n,0,0);
+ return 0;
+ }
+
+ id = sd->inventory_data[n];
+ pos = pc_equippoint(sd,n); //With a few exceptions, item should go in all specified slots.
+
+ if(battle_config.battle_log)
+ ShowInfo("equip %d(%d) %x:%x\n",sd->status.inventory[n].nameid,n,id?id->equip:0,req_pos);
+ if(!pc_isequip(sd,n) || !(pos&req_pos) || sd->status.inventory[n].equip != 0 || sd->status.inventory[n].attribute==1 ) { // [Valaris]
+ // FIXME: pc_isequip: equip level failure uses 2 instead of 0
+ clif_equipitemack(sd,n,0,0); // fail
+ return 0;
+ }
+
+ if (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_SATURDAYNIGHTFEVER] || sd->sc.data[SC__BLOODYLUST])
+ {
+ clif_equipitemack(sd,n,0,0); // fail
+ return 0;
+ }
+
+ if(pos == EQP_ACC) { //Accesories should only go in one of the two,
+ pos = req_pos&EQP_ACC;
+ if (pos == EQP_ACC) //User specified both slots..
+ pos = sd->equip_index[EQI_ACC_R] >= 0 ? EQP_ACC_L : EQP_ACC_R;
+ }
+
+ if(pos == EQP_ARMS && id->equip == EQP_HAND_R)
+ { //Dual wield capable weapon.
+ pos = (req_pos&EQP_ARMS);
+ if (pos == EQP_ARMS) //User specified both slots, pick one for them.
+ pos = sd->equip_index[EQI_HAND_R] >= 0 ? EQP_HAND_L : EQP_HAND_R;
+ }
+
+ if (pos&EQP_HAND_R && battle_config.use_weapon_skill_range&BL_PC)
+ { //Update skill-block range database when weapon range changes. [Skotlex]
+ i = sd->equip_index[EQI_HAND_R];
+ if (i < 0 || !sd->inventory_data[i]) //No data, or no weapon equipped
+ flag = 1;
+ else
+ flag = id->range != sd->inventory_data[i]->range;
+ }
+
+ for(i=0;i<EQI_MAX;i++) {
+ if(pos & equip_pos[i]) {
+ if(sd->equip_index[i] >= 0) //Slot taken, remove item from there.
+ pc_unequipitem(sd,sd->equip_index[i],2);
+
+ sd->equip_index[i] = n;
+ }
+ }
+
+ if(pos==EQP_AMMO){
+ clif_arrowequip(sd,n);
+ clif_arrow_fail(sd,3);
+ }
+ else
+ clif_equipitemack(sd,n,pos,1);
+
+ sd->status.inventory[n].equip=pos;
+
+ if(pos & EQP_HAND_R) {
+ if(id)
+ sd->weapontype1 = id->look;
+ else
+ sd->weapontype1 = 0;
+ pc_calcweapontype(sd);
+ clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
+ }
+ if(pos & EQP_HAND_L) {
+ if(id) {
+ if(id->type == IT_WEAPON) {
+ sd->status.shield = 0;
+ sd->weapontype2 = id->look;
+ }
+ else
+ if(id->type == IT_ARMOR) {
+ sd->status.shield = id->look;
+ sd->weapontype2 = 0;
+ }
+ }
+ else
+ sd->status.shield = sd->weapontype2 = 0;
+ pc_calcweapontype(sd);
+ clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
+ }
+ //Added check to prevent sending the same look on multiple slots ->
+ //causes client to redraw item on top of itself. (suggested by Lupus)
+ if(pos & EQP_HEAD_LOW && pc_checkequip(sd,EQP_COSTUME_HEAD_LOW) == -1) {
+ if(id && !(pos&(EQP_HEAD_TOP|EQP_HEAD_MID)))
+ sd->status.head_bottom = id->look;
+ else
+ sd->status.head_bottom = 0;
+ clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
+ }
+ if(pos & EQP_HEAD_TOP && pc_checkequip(sd,EQP_COSTUME_HEAD_TOP) == -1) {
+ if(id)
+ sd->status.head_top = id->look;
+ else
+ sd->status.head_top = 0;
+ clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
+ }
+ if(pos & EQP_HEAD_MID && pc_checkequip(sd,EQP_COSTUME_HEAD_MID) == -1) {
+ if(id && !(pos&EQP_HEAD_TOP))
+ sd->status.head_mid = id->look;
+ else
+ sd->status.head_mid = 0;
+ clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
+ }
+ if(pos & EQP_COSTUME_HEAD_TOP) {
+ if(id){
+ sd->status.head_top = id->look;
+ } else
+ sd->status.head_top = 0;
+ clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
+ }
+ if(pos & EQP_COSTUME_HEAD_MID) {
+ if(id && !(pos&EQP_HEAD_TOP)){
+ sd->status.head_mid = id->look;
+ } else
+ sd->status.head_mid = 0;
+ clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
+ }
+ if(pos & EQP_COSTUME_HEAD_LOW) {
+ if(id && !(pos&(EQP_HEAD_TOP|EQP_HEAD_MID))){
+ sd->status.head_bottom = id->look;
+ } else
+ sd->status.head_bottom = 0;
+ clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
+ }
+ if(pos & EQP_SHOES)
+ clif_changelook(&sd->bl,LOOK_SHOES,0);
+ if( pos&EQP_GARMENT )
+ {
+ sd->status.robe = id ? id->look : 0;
+ clif_changelook(&sd->bl, LOOK_ROBE, sd->status.robe);
+ }
+
+ pc_checkallowskill(sd); //Check if status changes should be halted.
+
+ /* check for combos (MUST be before status_calc_pc) */
+ if ( id ) {
+ struct item_data *data;
+ if( id->combos_count )
+ pc_checkcombo(sd,id);
+ if(itemdb_isspecial(sd->status.inventory[n].card[0]))
+ ; //No cards
+ else {
+ for( i = 0; i < id->slot; i++ ) {
+ if (!sd->status.inventory[n].card[i])
+ continue;
+ if ( ( data = itemdb_exists(sd->status.inventory[n].card[i]) ) != NULL ) {
+ if( data->combos_count )
+ pc_checkcombo(sd,data);
+ }
+ }
+ }
+ }
+
+ status_calc_pc(sd,0);
+ if (flag) //Update skill data
+ clif_skillinfoblock(sd);
+
+ //OnEquip script [Skotlex]
+ if (id) {
+ struct item_data *data;
+ if (id->equip_script)
+ run_script(id->equip_script,0,sd->bl.id,fake_nd->bl.id);
+ if(itemdb_isspecial(sd->status.inventory[n].card[0]))
+ ; //No cards
+ else {
+ for( i = 0; i < id->slot; i++ ) {
+ if (!sd->status.inventory[n].card[i])
+ continue;
+ if ( ( data = itemdb_exists(sd->status.inventory[n].card[i]) ) != NULL ) {
+ if( data->equip_script )
+ run_script(data->equip_script,0,sd->bl.id,fake_nd->bl.id);
+ }
+ }
+ }
+ }
+ return 0;
}
/*==========================================
@@ -8535,159 +8407,160 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
* 1 - calculate status after unequipping
* 2 - force unequip
*------------------------------------------*/
-int pc_unequipitem(struct map_session_data *sd,int n,int flag)
-{
- int i;
- bool status_cacl = false;
- nullpo_ret(sd);
-
- if (n < 0 || n >= MAX_INVENTORY) {
- clif_unequipitemack(sd,0,0,0);
- return 0;
- }
-
- // if player is berserk then cannot unequip
- if (!(flag & 2) && sd->sc.count && (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_SATURDAYNIGHTFEVER] || sd->sc.data[SC__BLOODYLUST])) {
- clif_unequipitemack(sd,n,0,0);
- return 0;
- }
-
- if (!(flag&2) && sd->sc.count && sd->sc.data[SC_KYOUGAKU]) {
- clif_unequipitemack(sd,n,0,0);
- return 0;
- }
-
- if (battle_config.battle_log)
- ShowInfo("unequip %d %x:%x\n",n,pc_equippoint(sd,n),sd->status.inventory[n].equip);
-
- if (!sd->status.inventory[n].equip) { //Nothing to unequip
- clif_unequipitemack(sd,n,0,0);
- return 0;
- }
- for (i=0; i<EQI_MAX; i++) {
- if (sd->status.inventory[n].equip & equip_pos[i])
- sd->equip_index[i] = -1;
- }
-
- if (sd->status.inventory[n].equip & EQP_HAND_R) {
- sd->weapontype1 = 0;
- sd->status.weapon = sd->weapontype2;
- pc_calcweapontype(sd);
- clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
- if (!battle_config.dancing_weaponswitch_fix)
- status_change_end(&sd->bl, SC_DANCING, INVALID_TIMER); // Unequipping => stop dancing.
- }
- if (sd->status.inventory[n].equip & EQP_HAND_L) {
- sd->status.shield = sd->weapontype2 = 0;
- pc_calcweapontype(sd);
- clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
- }
- if (sd->status.inventory[n].equip & EQP_HEAD_LOW && pc_checkequip(sd,EQP_COSTUME_HEAD_LOW) == -1) {
- sd->status.head_bottom = 0;
- clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
- }
- if (sd->status.inventory[n].equip & EQP_HEAD_TOP && pc_checkequip(sd,EQP_COSTUME_HEAD_TOP) == -1) {
- sd->status.head_top = 0;
- clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
- }
- if (sd->status.inventory[n].equip & EQP_HEAD_MID && pc_checkequip(sd,EQP_COSTUME_HEAD_MID) == -1) {
- sd->status.head_mid = 0;
- clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
- }
-
- if (sd->status.inventory[n].equip & EQP_COSTUME_HEAD_TOP) {
- sd->status.head_top = (pc_checkequip(sd,EQP_HEAD_TOP) >= 0) ? sd->inventory_data[pc_checkequip(sd,EQP_HEAD_TOP)]->look : 0;
- clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
- }
-
- if (sd->status.inventory[n].equip & EQP_COSTUME_HEAD_MID) {
- sd->status.head_mid = (pc_checkequip(sd,EQP_HEAD_MID) >= 0) ? sd->inventory_data[pc_checkequip(sd,EQP_HEAD_MID)]->look : 0;
- clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
- }
-
- if (sd->status.inventory[n].equip & EQP_COSTUME_HEAD_LOW) {
- sd->status.head_bottom = (pc_checkequip(sd,EQP_HEAD_LOW) >= 0) ? sd->inventory_data[pc_checkequip(sd,EQP_HEAD_LOW)]->look : 0;
- clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
- }
-
- if (sd->status.inventory[n].equip & EQP_SHOES)
- clif_changelook(&sd->bl,LOOK_SHOES,0);
- if (sd->status.inventory[n].equip&EQP_GARMENT) {
- sd->status.robe = 0;
- clif_changelook(&sd->bl, LOOK_ROBE, 0);
- }
-
- clif_unequipitemack(sd,n,sd->status.inventory[n].equip,1);
-
- if ((sd->status.inventory[n].equip & EQP_ARMS) &&
- sd->weapontype1 == 0 && sd->weapontype2 == 0 && (!sd->sc.data[SC_SEVENWIND] || sd->sc.data[SC_ASPERSIO])) //Check for seven wind (but not level seven!)
- skill_enchant_elemental_end(&sd->bl,-1);
-
- if (sd->status.inventory[n].equip & EQP_ARMOR) {
- // On Armor Change...
- status_change_end(&sd->bl, SC_BENEDICTIO, INVALID_TIMER);
- status_change_end(&sd->bl, SC_ARMOR_RESIST, INVALID_TIMER);
- }
-
- if (sd->state.autobonus&sd->status.inventory[n].equip)
- sd->state.autobonus &= ~sd->status.inventory[n].equip; //Check for activated autobonus [Inkfish]
-
- sd->status.inventory[n].equip=0;
-
- /* check for combos (MUST be before status_calc_pc) */
- if (sd->inventory_data[n]) {
- struct item_data *data;
-
- if (sd->inventory_data[n]->combos_count) {
- if (pc_removecombo(sd,sd->inventory_data[n]))
- status_cacl = true;
- }
- if (itemdb_isspecial(sd->status.inventory[n].card[0]))
- ; //No cards
- else {
- for (i = 0; i < sd->inventory_data[n]->slot; i++) {
- if (!sd->status.inventory[n].card[i])
- continue;
- if ((data = itemdb_exists(sd->status.inventory[n].card[i])) != NULL) {
- if (data->combos_count) {
- if (pc_removecombo(sd,data))
- status_cacl = true;
- }
- }
- }
- }
- }
-
- if (flag&1 || status_cacl) {
- pc_checkallowskill(sd);
- status_calc_pc(sd,0);
- }
-
- if (sd->sc.data[SC_SIGNUMCRUCIS] && !battle_check_undead(sd->battle_status.race,sd->battle_status.def_ele))
- status_change_end(&sd->bl, SC_SIGNUMCRUCIS, INVALID_TIMER);
-
- //OnUnEquip script [Skotlex]
- if (sd->inventory_data[n]) {
- struct item_data *data;
- if (sd->inventory_data[n]->unequip_script)
- run_script(sd->inventory_data[n]->unequip_script,0,sd->bl.id,fake_nd->bl.id);
- if (itemdb_isspecial(sd->status.inventory[n].card[0]))
- ; //No cards
- else {
- for (i = 0; i < sd->inventory_data[n]->slot; i++) {
- if (!sd->status.inventory[n].card[i])
- continue;
-
- if ((data = itemdb_exists(sd->status.inventory[n].card[i])) != NULL) {
- if (data->unequip_script)
- run_script(data->unequip_script,0,sd->bl.id,fake_nd->bl.id);
- }
-
- }
- }
- }
-
- return 0;
+int pc_unequipitem(struct map_session_data *sd,int n,int flag) {
+ int i;
+ bool status_cacl = false;
+ nullpo_ret(sd);
+
+ if( n < 0 || n >= MAX_INVENTORY ) {
+ clif_unequipitemack(sd,0,0,0);
+ return 0;
+ }
+
+ // if player is berserk then cannot unequip
+ if (!(flag & 2) && sd->sc.count && (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_SATURDAYNIGHTFEVER] || sd->sc.data[SC__BLOODYLUST]))
+ {
+ clif_unequipitemack(sd,n,0,0);
+ return 0;
+ }
+
+ if( !(flag&2) && sd->sc.count && sd->sc.data[SC_KYOUGAKU] )
+ {
+ clif_unequipitemack(sd,n,0,0);
+ return 0;
+ }
+
+ if(battle_config.battle_log)
+ ShowInfo("unequip %d %x:%x\n",n,pc_equippoint(sd,n),sd->status.inventory[n].equip);
+
+ if(!sd->status.inventory[n].equip){ //Nothing to unequip
+ clif_unequipitemack(sd,n,0,0);
+ return 0;
+ }
+ for(i=0;i<EQI_MAX;i++) {
+ if(sd->status.inventory[n].equip & equip_pos[i])
+ sd->equip_index[i] = -1;
+ }
+
+ if(sd->status.inventory[n].equip & EQP_HAND_R) {
+ sd->weapontype1 = 0;
+ sd->status.weapon = sd->weapontype2;
+ pc_calcweapontype(sd);
+ clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
+ if( !battle_config.dancing_weaponswitch_fix )
+ status_change_end(&sd->bl, SC_DANCING, INVALID_TIMER); // Unequipping => stop dancing.
+ }
+ if(sd->status.inventory[n].equip & EQP_HAND_L) {
+ sd->status.shield = sd->weapontype2 = 0;
+ pc_calcweapontype(sd);
+ clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
+ }
+ if(sd->status.inventory[n].equip & EQP_HEAD_LOW && pc_checkequip(sd,EQP_COSTUME_HEAD_LOW) == -1 ) {
+ sd->status.head_bottom = 0;
+ clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
+ }
+ if(sd->status.inventory[n].equip & EQP_HEAD_TOP && pc_checkequip(sd,EQP_COSTUME_HEAD_TOP) == -1 ) {
+ sd->status.head_top = 0;
+ clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
+ }
+ if(sd->status.inventory[n].equip & EQP_HEAD_MID && pc_checkequip(sd,EQP_COSTUME_HEAD_MID) == -1 ) {
+ sd->status.head_mid = 0;
+ clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
+ }
+
+ if(sd->status.inventory[n].equip & EQP_COSTUME_HEAD_TOP) {
+ sd->status.head_top = ( pc_checkequip(sd,EQP_HEAD_TOP) >= 0 ) ? sd->inventory_data[pc_checkequip(sd,EQP_HEAD_TOP)]->look : 0;
+ clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
+ }
+
+ if(sd->status.inventory[n].equip & EQP_COSTUME_HEAD_MID) {
+ sd->status.head_mid = ( pc_checkequip(sd,EQP_HEAD_MID) >= 0 ) ? sd->inventory_data[pc_checkequip(sd,EQP_HEAD_MID)]->look : 0;
+ clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
+ }
+
+ if(sd->status.inventory[n].equip & EQP_COSTUME_HEAD_LOW) {
+ sd->status.head_bottom = ( pc_checkequip(sd,EQP_HEAD_LOW) >= 0 ) ? sd->inventory_data[pc_checkequip(sd,EQP_HEAD_LOW)]->look : 0;
+ clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
+ }
+
+ if(sd->status.inventory[n].equip & EQP_SHOES)
+ clif_changelook(&sd->bl,LOOK_SHOES,0);
+ if( sd->status.inventory[n].equip&EQP_GARMENT )
+ {
+ sd->status.robe = 0;
+ clif_changelook(&sd->bl, LOOK_ROBE, 0);
+ }
+
+ clif_unequipitemack(sd,n,sd->status.inventory[n].equip,1);
+
+ if((sd->status.inventory[n].equip & EQP_ARMS) &&
+ sd->weapontype1 == 0 && sd->weapontype2 == 0 && (!sd->sc.data[SC_SEVENWIND] || sd->sc.data[SC_ASPERSIO])) //Check for seven wind (but not level seven!)
+ skill_enchant_elemental_end(&sd->bl,-1);
+
+ if(sd->status.inventory[n].equip & EQP_ARMOR) {
+ // On Armor Change...
+ status_change_end(&sd->bl, SC_BENEDICTIO, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_ARMOR_RESIST, INVALID_TIMER);
+ }
+
+ if( sd->state.autobonus&sd->status.inventory[n].equip )
+ sd->state.autobonus &= ~sd->status.inventory[n].equip; //Check for activated autobonus [Inkfish]
+
+ sd->status.inventory[n].equip=0;
+
+ /* check for combos (MUST be before status_calc_pc) */
+ if ( sd->inventory_data[n] ) {
+ struct item_data *data;
+
+ if( sd->inventory_data[n]->combos_count ) {
+ if( pc_removecombo(sd,sd->inventory_data[n]) )
+ status_cacl = true;
+ } if(itemdb_isspecial(sd->status.inventory[n].card[0]))
+ ; //No cards
+ else {
+ for( i = 0; i < sd->inventory_data[n]->slot; i++ ) {
+ if (!sd->status.inventory[n].card[i])
+ continue;
+ if ( ( data = itemdb_exists(sd->status.inventory[n].card[i]) ) != NULL ) {
+ if( data->combos_count ) {
+ if( pc_removecombo(sd,data) )
+ status_cacl = true;
+ }
+ }
+ }
+ }
+ }
+
+ if(flag&1 || status_cacl) {
+ pc_checkallowskill(sd);
+ status_calc_pc(sd,0);
+ }
+
+ if(sd->sc.data[SC_SIGNUMCRUCIS] && !battle_check_undead(sd->battle_status.race,sd->battle_status.def_ele))
+ status_change_end(&sd->bl, SC_SIGNUMCRUCIS, INVALID_TIMER);
+
+ //OnUnEquip script [Skotlex]
+ if (sd->inventory_data[n]) {
+ struct item_data *data;
+ if (sd->inventory_data[n]->unequip_script)
+ run_script(sd->inventory_data[n]->unequip_script,0,sd->bl.id,fake_nd->bl.id);
+ if(itemdb_isspecial(sd->status.inventory[n].card[0]))
+ ; //No cards
+ else {
+ for( i = 0; i < sd->inventory_data[n]->slot; i++ ) {
+ if (!sd->status.inventory[n].card[i])
+ continue;
+
+ if ( ( data = itemdb_exists(sd->status.inventory[n].card[i]) ) != NULL ) {
+ if( data->unequip_script )
+ run_script(data->unequip_script,0,sd->bl.id,fake_nd->bl.id);
+ }
+
+ }
+ }
+ }
+
+ return 0;
}
/*==========================================
@@ -8696,71 +8569,79 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag)
*------------------------------------------*/
int pc_checkitem(struct map_session_data *sd)
{
- int i,id,calc_flag = 0;
- struct item_data *it=NULL;
-
- nullpo_ret(sd);
-
- if (sd->state.vending) //Avoid reorganizing items when we are vending, as that leads to exploits (pointed out by End of Exam)
- return 0;
-
- if (battle_config.item_check) {
- // check for invalid(ated) items
- for (i = 0; i < MAX_INVENTORY; i++) {
- id = sd->status.inventory[i].nameid;
-
- if (id && !itemdb_available(id)) {
- ShowWarning("Removed invalid/disabled item id %d from inventory (amount=%d, char_id=%d).\n", id, sd->status.inventory[i].amount, sd->status.char_id);
- pc_delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_OTHER);
- }
- }
-
- for (i = 0; i < MAX_CART; i++) {
- id = sd->status.cart[i].nameid;
-
- if (id && !itemdb_available(id)) {
- ShowWarning("Removed invalid/disabled item id %d from cart (amount=%d, char_id=%d).\n", id, sd->status.cart[i].amount, sd->status.char_id);
- pc_cart_delitem(sd, i, sd->status.cart[i].amount, 0, LOG_TYPE_OTHER);
- }
- }
- }
-
- for (i = 0; i < MAX_INVENTORY; i++) {
- it = sd->inventory_data[i];
-
- if (sd->status.inventory[i].nameid == 0)
- continue;
-
- if (!sd->status.inventory[i].equip)
- continue;
-
- if (sd->status.inventory[i].equip&~pc_equippoint(sd,i)) {
- pc_unequipitem(sd, i, 2);
- calc_flag = 1;
- continue;
- }
-
- if (it) {
- // check for forbiden items.
- int flag =
- (map[sd->bl.m].flag.restricted?(8*map[sd->bl.m].zone):0)
- | (!map_flag_vs(sd->bl.m)?1:0)
- | (map[sd->bl.m].flag.pvp?2:0)
- | (map_flag_gvg(sd->bl.m)?4:0)
- | (map[sd->bl.m].flag.battleground?8:0);
- if (flag && (it->flag.no_equip&flag || !pc_isAllowedCardOn(sd,it->slot,i,flag))) {
- pc_unequipitem(sd, i, 2);
- calc_flag = 1;
- }
- }
- }
-
- if (calc_flag && sd->state.active) {
- pc_checkallowskill(sd);
- status_calc_pc(sd,0);
- }
-
- return 0;
+ int i,id,calc_flag = 0;
+ struct item_data *it=NULL;
+
+ nullpo_ret(sd);
+
+ if( sd->state.vending ) //Avoid reorganizing items when we are vending, as that leads to exploits (pointed out by End of Exam)
+ return 0;
+
+ if( battle_config.item_check )
+ {// check for invalid(ated) items
+ for( i = 0; i < MAX_INVENTORY; i++ )
+ {
+ id = sd->status.inventory[i].nameid;
+
+ if( id && !itemdb_available(id) )
+ {
+ ShowWarning("Removed invalid/disabled item id %d from inventory (amount=%d, char_id=%d).\n", id, sd->status.inventory[i].amount, sd->status.char_id);
+ pc_delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_OTHER);
+ }
+ }
+
+ for( i = 0; i < MAX_CART; i++ )
+ {
+ id = sd->status.cart[i].nameid;
+
+ if( id && !itemdb_available(id) )
+ {
+ ShowWarning("Removed invalid/disabled item id %d from cart (amount=%d, char_id=%d).\n", id, sd->status.cart[i].amount, sd->status.char_id);
+ pc_cart_delitem(sd, i, sd->status.cart[i].amount, 0, LOG_TYPE_OTHER);
+ }
+ }
+ }
+
+ for( i = 0; i < MAX_INVENTORY; i++)
+ {
+ it = sd->inventory_data[i];
+
+ if( sd->status.inventory[i].nameid == 0 )
+ continue;
+
+ if( !sd->status.inventory[i].equip )
+ continue;
+
+ if( sd->status.inventory[i].equip&~pc_equippoint(sd,i) )
+ {
+ pc_unequipitem(sd, i, 2);
+ calc_flag = 1;
+ continue;
+ }
+
+ if( it )
+ { // check for forbiden items.
+ int flag =
+ (map[sd->bl.m].flag.restricted?(8*map[sd->bl.m].zone):0)
+ | (!map_flag_vs(sd->bl.m)?1:0)
+ | (map[sd->bl.m].flag.pvp?2:0)
+ | (map_flag_gvg(sd->bl.m)?4:0)
+ | (map[sd->bl.m].flag.battleground?8:0);
+ if( flag && (it->flag.no_equip&flag || !pc_isAllowedCardOn(sd,it->slot,i,flag)) )
+ {
+ pc_unequipitem(sd, i, 2);
+ calc_flag = 1;
+ }
+ }
+ }
+
+ if( calc_flag && sd->state.active )
+ {
+ pc_checkallowskill(sd);
+ status_calc_pc(sd,0);
+ }
+
+ return 0;
}
/*==========================================
@@ -8768,19 +8649,19 @@ int pc_checkitem(struct map_session_data *sd)
*------------------------------------------*/
int pc_calc_pvprank_sub(struct block_list *bl,va_list ap)
{
- struct map_session_data *sd1,*sd2=NULL;
+ struct map_session_data *sd1,*sd2=NULL;
- sd1=(struct map_session_data *)bl;
- sd2=va_arg(ap,struct map_session_data *);
+ sd1=(struct map_session_data *)bl;
+ sd2=va_arg(ap,struct map_session_data *);
- if (sd1->sc.option&OPTION_INVISIBLE || sd2->sc.option&OPTION_INVISIBLE) {
- // cannot register pvp rank for hidden GMs
- return 0;
- }
+ if( sd1->sc.option&OPTION_INVISIBLE || sd2->sc.option&OPTION_INVISIBLE )
+ {// cannot register pvp rank for hidden GMs
+ return 0;
+ }
- if (sd1->pvp_point > sd2->pvp_point)
- sd2->pvp_rank++;
- return 0;
+ if( sd1->pvp_point > sd2->pvp_point )
+ sd2->pvp_rank++;
+ return 0;
}
/*==========================================
* Calculate new rank beetween all present players (map_foreachinarea)
@@ -8788,216 +8669,221 @@ int pc_calc_pvprank_sub(struct block_list *bl,va_list ap)
*------------------------------------------*/
int pc_calc_pvprank(struct map_session_data *sd)
{
- int old;
- struct map_data *m;
- m=&map[sd->bl.m];
- old=sd->pvp_rank;
- sd->pvp_rank=1;
- map_foreachinmap(pc_calc_pvprank_sub,sd->bl.m,BL_PC,sd);
- if (old!=sd->pvp_rank || sd->pvp_lastusers!=m->users_pvp)
- clif_pvpset(sd,sd->pvp_rank,sd->pvp_lastusers=m->users_pvp,0);
- return sd->pvp_rank;
+ int old;
+ struct map_data *m;
+ m=&map[sd->bl.m];
+ old=sd->pvp_rank;
+ sd->pvp_rank=1;
+ map_foreachinmap(pc_calc_pvprank_sub,sd->bl.m,BL_PC,sd);
+ if(old!=sd->pvp_rank || sd->pvp_lastusers!=m->users_pvp)
+ clif_pvpset(sd,sd->pvp_rank,sd->pvp_lastusers=m->users_pvp,0);
+ return sd->pvp_rank;
}
/*==========================================
* Calculate next sd ranking calculation from config
*------------------------------------------*/
int pc_calc_pvprank_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- struct map_session_data *sd=NULL;
+ struct map_session_data *sd=NULL;
- sd=map_id2sd(id);
- if (sd==NULL)
- return 0;
- sd->pvp_timer = INVALID_TIMER;
+ sd=map_id2sd(id);
+ if(sd==NULL)
+ return 0;
+ sd->pvp_timer = INVALID_TIMER;
- if (sd->sc.option&OPTION_INVISIBLE) {
- // do not calculate the pvp rank for a hidden GM
- return 0;
- }
+ if( sd->sc.option&OPTION_INVISIBLE )
+ {// do not calculate the pvp rank for a hidden GM
+ return 0;
+ }
- if (pc_calc_pvprank(sd) > 0)
- sd->pvp_timer = add_timer(gettick()+PVP_CALCRANK_INTERVAL,pc_calc_pvprank_timer,id,data);
- return 0;
+ if( pc_calc_pvprank(sd) > 0 )
+ sd->pvp_timer = add_timer(gettick()+PVP_CALCRANK_INTERVAL,pc_calc_pvprank_timer,id,data);
+ return 0;
}
/*==========================================
* Checking if sd is married
* Return:
- * partner_id = yes
- * 0 = no
+ * partner_id = yes
+ * 0 = no
*------------------------------------------*/
int pc_ismarried(struct map_session_data *sd)
{
- if (sd == NULL)
- return -1;
- if (sd->status.partner_id > 0)
- return sd->status.partner_id;
- else
- return 0;
+ if(sd == NULL)
+ return -1;
+ if(sd->status.partner_id > 0)
+ return sd->status.partner_id;
+ else
+ return 0;
}
/*==========================================
* Marry player sd to player dstsd
* Return:
- * -1 = fail
- * 0 = success
+ * -1 = fail
+ * 0 = success
*------------------------------------------*/
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 ||
- (sd->class_&JOBL_BABY) || (dstsd->class_&JOBL_BABY))
- return -1;
- sd->status.partner_id = dstsd->status.char_id;
- dstsd->status.partner_id = sd->status.char_id;
- return 0;
+ if(sd == NULL || dstsd == NULL ||
+ sd->status.partner_id > 0 || dstsd->status.partner_id > 0 ||
+ (sd->class_&JOBL_BABY) || (dstsd->class_&JOBL_BABY))
+ return -1;
+ sd->status.partner_id = dstsd->status.char_id;
+ dstsd->status.partner_id = sd->status.char_id;
+ return 0;
}
/*==========================================
* Divorce sd from its partner
* Return:
- * -1 = fail
- * 0 = success
+ * -1 = fail
+ * 0 = success
*------------------------------------------*/
int pc_divorce(struct map_session_data *sd)
{
- struct map_session_data *p_sd;
- int i;
+ struct map_session_data *p_sd;
+ int i;
- if (sd == NULL || !pc_ismarried(sd))
- return -1;
+ if( sd == NULL || !pc_ismarried(sd) )
+ return -1;
- if (!sd->status.partner_id)
- return -1; // Char is not married
+ if( !sd->status.partner_id )
+ return -1; // Char is not married
- if ((p_sd = map_charid2sd(sd->status.partner_id)) == NULL) {
- // Lets char server do the divorce
- if (chrif_divorce(sd->status.char_id, sd->status.partner_id))
- return -1; // No char server connected
+ if( (p_sd = map_charid2sd(sd->status.partner_id)) == NULL )
+ { // Lets char server do the divorce
+ if( chrif_divorce(sd->status.char_id, sd->status.partner_id) )
+ return -1; // No char server connected
- return 0;
- }
+ return 0;
+ }
- // Both players online, lets do the divorce manually
- sd->status.partner_id = 0;
- p_sd->status.partner_id = 0;
- for (i = 0; i < MAX_INVENTORY; i++) {
- if (sd->status.inventory[i].nameid == WEDDING_RING_M || sd->status.inventory[i].nameid == WEDDING_RING_F)
- pc_delitem(sd, i, 1, 0, 0, LOG_TYPE_OTHER);
- if (p_sd->status.inventory[i].nameid == WEDDING_RING_M || p_sd->status.inventory[i].nameid == WEDDING_RING_F)
- pc_delitem(p_sd, i, 1, 0, 0, LOG_TYPE_OTHER);
- }
+ // Both players online, lets do the divorce manually
+ sd->status.partner_id = 0;
+ p_sd->status.partner_id = 0;
+ for( i = 0; i < MAX_INVENTORY; i++ )
+ {
+ if( sd->status.inventory[i].nameid == WEDDING_RING_M || sd->status.inventory[i].nameid == WEDDING_RING_F )
+ pc_delitem(sd, i, 1, 0, 0, LOG_TYPE_OTHER);
+ if( p_sd->status.inventory[i].nameid == WEDDING_RING_M || p_sd->status.inventory[i].nameid == WEDDING_RING_F )
+ pc_delitem(p_sd, i, 1, 0, 0, LOG_TYPE_OTHER);
+ }
- clif_divorced(sd, p_sd->status.name);
- clif_divorced(p_sd, sd->status.name);
+ clif_divorced(sd, p_sd->status.name);
+ clif_divorced(p_sd, sd->status.name);
- return 0;
+ return 0;
}
/*==========================================
* Get sd partner charid. (Married partner)
*------------------------------------------*/
-struct map_session_data *pc_get_partner(struct map_session_data *sd) {
- if (sd && pc_ismarried(sd))
- // charid2sd returns NULL if not found
- return map_charid2sd(sd->status.partner_id);
+struct map_session_data *pc_get_partner(struct map_session_data *sd)
+{
+ if (sd && pc_ismarried(sd))
+ // charid2sd returns NULL if not found
+ return map_charid2sd(sd->status.partner_id);
- return NULL;
+ return NULL;
}
/*==========================================
* Get sd father charid. (Need to be baby)
*------------------------------------------*/
-struct map_session_data *pc_get_father(struct map_session_data *sd) {
- if (sd && sd->class_&JOBL_BABY && sd->status.father > 0)
- // charid2sd returns NULL if not found
- return map_charid2sd(sd->status.father);
+struct map_session_data *pc_get_father (struct map_session_data *sd)
+{
+ if (sd && sd->class_&JOBL_BABY && sd->status.father > 0)
+ // charid2sd returns NULL if not found
+ return map_charid2sd(sd->status.father);
- return NULL;
+ return NULL;
}
/*==========================================
* Get sd mother charid. (Need to be baby)
*------------------------------------------*/
-struct map_session_data *pc_get_mother(struct map_session_data *sd) {
- if (sd && sd->class_&JOBL_BABY && sd->status.mother > 0)
- // charid2sd returns NULL if not found
- return map_charid2sd(sd->status.mother);
+struct map_session_data *pc_get_mother (struct map_session_data *sd)
+{
+ if (sd && sd->class_&JOBL_BABY && sd->status.mother > 0)
+ // charid2sd returns NULL if not found
+ return map_charid2sd(sd->status.mother);
- return NULL;
+ return NULL;
}
/*==========================================
* Get sd children charid. (Need to be married)
*------------------------------------------*/
-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);
+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;
+ return NULL;
}
/*==========================================
* Set player sd to bleed. (losing hp and/or sp each diff_tick)
*------------------------------------------*/
-void pc_bleeding(struct map_session_data *sd, unsigned int diff_tick)
+void pc_bleeding (struct map_session_data *sd, unsigned int diff_tick)
{
- int hp = 0, sp = 0;
+ int hp = 0, sp = 0;
- if (pc_isdead(sd))
- return;
+ if( pc_isdead(sd) )
+ return;
- if (sd->hp_loss.value) {
- sd->hp_loss.tick += diff_tick;
- while (sd->hp_loss.tick >= sd->hp_loss.rate) {
- hp += sd->hp_loss.value;
- sd->hp_loss.tick -= sd->hp_loss.rate;
- }
- if (hp >= sd->battle_status.hp)
- hp = sd->battle_status.hp-1; //Script drains cannot kill you.
- }
+ if (sd->hp_loss.value) {
+ sd->hp_loss.tick += diff_tick;
+ while (sd->hp_loss.tick >= sd->hp_loss.rate) {
+ hp += sd->hp_loss.value;
+ sd->hp_loss.tick -= sd->hp_loss.rate;
+ }
+ if(hp >= sd->battle_status.hp)
+ hp = sd->battle_status.hp-1; //Script drains cannot kill you.
+ }
- if (sd->sp_loss.value) {
- sd->sp_loss.tick += diff_tick;
- while (sd->sp_loss.tick >= sd->sp_loss.rate) {
- sp += sd->sp_loss.value;
- sd->sp_loss.tick -= sd->sp_loss.rate;
- }
- }
+ if (sd->sp_loss.value) {
+ sd->sp_loss.tick += diff_tick;
+ while (sd->sp_loss.tick >= sd->sp_loss.rate) {
+ sp += sd->sp_loss.value;
+ sd->sp_loss.tick -= sd->sp_loss.rate;
+ }
+ }
- if (hp > 0 || sp > 0)
- status_zap(&sd->bl, hp, sp);
+ if (hp > 0 || sp > 0)
+ status_zap(&sd->bl, hp, sp);
- return;
+ return;
}
//Character regen. Flag is used to know which types of regen can take place.
//&1: HP regen
//&2: SP regen
-void pc_regen(struct map_session_data *sd, unsigned int diff_tick)
+void pc_regen (struct map_session_data *sd, unsigned int diff_tick)
{
- int hp = 0, sp = 0;
+ int hp = 0, sp = 0;
- if (sd->hp_regen.value) {
- sd->hp_regen.tick += diff_tick;
- while (sd->hp_regen.tick >= sd->hp_regen.rate) {
- hp += sd->hp_regen.value;
- sd->hp_regen.tick -= sd->hp_regen.rate;
- }
- }
+ if (sd->hp_regen.value) {
+ sd->hp_regen.tick += diff_tick;
+ while (sd->hp_regen.tick >= sd->hp_regen.rate) {
+ hp += sd->hp_regen.value;
+ sd->hp_regen.tick -= sd->hp_regen.rate;
+ }
+ }
- if (sd->sp_regen.value) {
- sd->sp_regen.tick += diff_tick;
- while (sd->sp_regen.tick >= sd->sp_regen.rate) {
- sp += sd->sp_regen.value;
- sd->sp_regen.tick -= sd->sp_regen.rate;
- }
- }
+ if (sd->sp_regen.value) {
+ sd->sp_regen.tick += diff_tick;
+ while (sd->sp_regen.tick >= sd->sp_regen.rate) {
+ sp += sd->sp_regen.value;
+ sd->sp_regen.tick -= sd->sp_regen.rate;
+ }
+ }
- if (hp > 0 || sp > 0)
- status_heal(&sd->bl, hp, sp, 0);
+ if (hp > 0 || sp > 0)
+ status_heal(&sd->bl, hp, sp, 0);
- return;
+ return;
}
/*==========================================
@@ -9005,13 +8891,13 @@ void pc_regen(struct map_session_data *sd, unsigned int diff_tick)
*------------------------------------------*/
int pc_setsavepoint(struct map_session_data *sd, short mapindex,int x,int y)
{
- nullpo_ret(sd);
+ nullpo_ret(sd);
- sd->status.save_point.map = mapindex;
- sd->status.save_point.x = x;
- sd->status.save_point.y = y;
+ sd->status.save_point.map = mapindex;
+ sd->status.save_point.x = x;
+ sd->status.save_point.y = y;
- return 0;
+ return 0;
}
/*==========================================
@@ -9019,52 +8905,53 @@ int pc_setsavepoint(struct map_session_data *sd, short mapindex,int x,int y)
*------------------------------------------*/
int pc_autosave(int tid, unsigned int tick, int id, intptr_t data)
{
- int interval;
- struct s_mapiterator *iter;
- struct map_session_data *sd;
- static int last_save_id = 0, save_flag = 0;
+ int interval;
+ struct s_mapiterator* iter;
+ struct map_session_data* sd;
+ static int last_save_id = 0, save_flag = 0;
- if (save_flag == 2) //Someone was saved on last call, normal cycle
- save_flag = 0;
- else
- save_flag = 1; //Noone was saved, so save first found char.
+ if(save_flag == 2) //Someone was saved on last call, normal cycle
+ save_flag = 0;
+ else
+ save_flag = 1; //Noone was saved, so save first found char.
- iter = mapit_getallusers();
- for (sd = (TBL_PC *)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC *)mapit_next(iter)) {
- if (sd->bl.id == last_save_id && save_flag != 1) {
- save_flag = 1;
- continue;
- }
+ iter = mapit_getallusers();
+ for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
+ {
+ if(sd->bl.id == last_save_id && save_flag != 1) {
+ save_flag = 1;
+ continue;
+ }
- if (save_flag != 1) //Not our turn to save yet.
- continue;
+ if(save_flag != 1) //Not our turn to save yet.
+ continue;
- //Save char.
- last_save_id = sd->bl.id;
- save_flag = 2;
+ //Save char.
+ last_save_id = sd->bl.id;
+ save_flag = 2;
- chrif_save(sd,0);
- break;
- }
- mapit_free(iter);
+ chrif_save(sd,0);
+ break;
+ }
+ mapit_free(iter);
- interval = autosave_interval/(map_usercount()+1);
- if (interval < minsave_interval)
- interval = minsave_interval;
- add_timer(gettick()+interval,pc_autosave,0,0);
+ interval = autosave_interval/(map_usercount()+1);
+ if(interval < minsave_interval)
+ interval = minsave_interval;
+ add_timer(gettick()+interval,pc_autosave,0,0);
- return 0;
+ return 0;
}
static int pc_daynight_timer_sub(struct map_session_data *sd,va_list ap)
{
- if (sd->state.night != night_flag && map[sd->bl.m].flag.nightenabled) {
- //Night/day state does not match.
- clif_status_load(&sd->bl, SI_NIGHT, night_flag); //New night effect by dynamix [Skotlex]
- sd->state.night = night_flag;
- return 1;
- }
- return 0;
+ if (sd->state.night != night_flag && map[sd->bl.m].flag.nightenabled)
+ { //Night/day state does not match.
+ clif_status_load(&sd->bl, SI_NIGHT, night_flag); //New night effect by dynamix [Skotlex]
+ sd->state.night = night_flag;
+ return 1;
+ }
+ return 0;
}
/*================================================
* timer to do the day [Yor]
@@ -9072,19 +8959,19 @@ static int pc_daynight_timer_sub(struct map_session_data *sd,va_list ap)
*------------------------------------------------*/
int map_day_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- char tmp_soutput[1024];
+ char tmp_soutput[1024];
- if (data == 0 && battle_config.day_duration <= 0) // if we want a day
- return 0;
+ if (data == 0 && battle_config.day_duration <= 0) // if we want a day
+ return 0;
- if (!night_flag)
- return 0; //Already day.
+ if (!night_flag)
+ return 0; //Already day.
- night_flag = 0; // 0=day, 1=night [Yor]
- map_foreachpc(pc_daynight_timer_sub);
- strcpy(tmp_soutput, (data == 0) ? msg_txt(502) : msg_txt(60)); // The day has arrived!
- intif_broadcast(tmp_soutput, strlen(tmp_soutput) + 1, 0);
- return 0;
+ night_flag = 0; // 0=day, 1=night [Yor]
+ map_foreachpc(pc_daynight_timer_sub);
+ strcpy(tmp_soutput, (data == 0) ? msg_txt(502) : msg_txt(60)); // The day has arrived!
+ intif_broadcast(tmp_soutput, strlen(tmp_soutput) + 1, 0);
+ return 0;
}
/*================================================
@@ -9093,56 +8980,54 @@ int map_day_timer(int tid, unsigned int tick, int id, intptr_t data)
*------------------------------------------------*/
int map_night_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- char tmp_soutput[1024];
+ char tmp_soutput[1024];
- if (data == 0 && battle_config.night_duration <= 0) // if we want a night
- return 0;
+ if (data == 0 && battle_config.night_duration <= 0) // if we want a night
+ return 0;
- if (night_flag)
- return 0; //Already nigth.
+ if (night_flag)
+ return 0; //Already nigth.
- night_flag = 1; // 0=day, 1=night [Yor]
- map_foreachpc(pc_daynight_timer_sub);
- strcpy(tmp_soutput, (data == 0) ? msg_txt(503) : msg_txt(59)); // The night has fallen...
- intif_broadcast(tmp_soutput, strlen(tmp_soutput) + 1, 0);
- return 0;
+ night_flag = 1; // 0=day, 1=night [Yor]
+ map_foreachpc(pc_daynight_timer_sub);
+ strcpy(tmp_soutput, (data == 0) ? msg_txt(503) : msg_txt(59)); // The night has fallen...
+ intif_broadcast(tmp_soutput, strlen(tmp_soutput) + 1, 0);
+ return 0;
}
-void pc_setstand(struct map_session_data *sd)
-{
- nullpo_retv(sd);
+void pc_setstand(struct map_session_data *sd){
+ nullpo_retv(sd);
- status_change_end(&sd->bl, SC_TENSIONRELAX, INVALID_TIMER);
- clif_status_load(&sd->bl,SI_SIT,0);
- //Reset sitting tick.
- sd->ssregen.tick.hp = sd->ssregen.tick.sp = 0;
- sd->state.dead_sit = sd->vd.dead_sit = 0;
+ status_change_end(&sd->bl, SC_TENSIONRELAX, INVALID_TIMER);
+ clif_status_load(&sd->bl,SI_SIT,0);
+ //Reset sitting tick.
+ sd->ssregen.tick.hp = sd->ssregen.tick.sp = 0;
+ sd->state.dead_sit = sd->vd.dead_sit = 0;
}
/**
* Mechanic (MADO GEAR)
**/
-void pc_overheat(struct map_session_data *sd, int val)
-{
- int heat = val, skill,
- limit[] = { 10, 20, 28, 46, 66 };
+void pc_overheat(struct map_session_data *sd, int val) {
+ int heat = val, skill,
+ limit[] = { 10, 20, 28, 46, 66 };
- if (!pc_ismadogear(sd) || sd->sc.data[SC_OVERHEAT])
- return; // already burning
+ if( !pc_ismadogear(sd) || sd->sc.data[SC_OVERHEAT] )
+ return; // already burning
- skill = cap_value(pc_checkskill(sd,NC_MAINFRAME),0,4);
- if (sd->sc.data[SC_OVERHEAT_LIMITPOINT]) {
- heat += sd->sc.data[SC_OVERHEAT_LIMITPOINT]->val1;
- status_change_end(&sd->bl,SC_OVERHEAT_LIMITPOINT,INVALID_TIMER);
- }
+ skill = cap_value(pc_checkskill(sd,NC_MAINFRAME),0,4);
+ if( sd->sc.data[SC_OVERHEAT_LIMITPOINT] ) {
+ heat += sd->sc.data[SC_OVERHEAT_LIMITPOINT]->val1;
+ status_change_end(&sd->bl,SC_OVERHEAT_LIMITPOINT,INVALID_TIMER);
+ }
- heat = max(0,heat); // Avoid negative HEAT
- if (heat >= limit[skill])
- sc_start(&sd->bl,SC_OVERHEAT,100,0,1000);
- else
- sc_start(&sd->bl,SC_OVERHEAT_LIMITPOINT,100,heat,30000);
+ heat = max(0,heat); // Avoid negative HEAT
+ if( heat >= limit[skill] )
+ sc_start(&sd->bl,SC_OVERHEAT,100,0,1000);
+ else
+ sc_start(&sd->bl,SC_OVERHEAT_LIMITPOINT,100,heat,30000);
- return;
+ return;
}
/**
@@ -9150,11 +9035,11 @@ void pc_overheat(struct map_session_data *sd, int val)
*/
bool pc_isautolooting(struct map_session_data *sd, int nameid)
{
- int i;
- if (!sd->state.autolooting)
- return false;
- ARR_FIND(0, AUTOLOOTITEM_SIZE, i, sd->state.autolootid[i] == nameid);
- return (i != AUTOLOOTITEM_SIZE);
+ int i;
+ if( !sd->state.autolooting )
+ return false;
+ ARR_FIND(0, AUTOLOOTITEM_SIZE, i, sd->state.autolootid[i] == nameid);
+ return (i != AUTOLOOTITEM_SIZE);
}
/**
@@ -9165,7 +9050,7 @@ bool pc_isautolooting(struct map_session_data *sd, int nameid)
*/
bool pc_can_use_command(struct map_session_data *sd, const char *command, AtCommandType type)
{
- return pc_group_can_use_command(pc_get_group_id(sd), command, type);
+ return pc_group_can_use_command(pc_get_group_id(sd), command, type);
}
/**
@@ -9175,104 +9060,107 @@ bool pc_can_use_command(struct map_session_data *sd, const char *command, AtComm
*/
bool pc_should_log_commands(struct map_session_data *sd)
{
- return pc_group_should_log_commands(pc_get_group_id(sd));
+ return pc_group_should_log_commands(pc_get_group_id(sd));
}
static int pc_talisman_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- struct map_session_data *sd;
- int i, type;
+ struct map_session_data *sd;
+ int i, type;
- if ((sd=(struct map_session_data *)map_id2sd(id)) == NULL || sd->bl.type!=BL_PC)
- return 1;
+ if( (sd=(struct map_session_data *)map_id2sd(id)) == NULL || sd->bl.type!=BL_PC )
+ return 1;
- ARR_FIND(1, 5, type, sd->talisman[type] > 0);
+ ARR_FIND(1, 5, type, sd->talisman[type] > 0);
- if (sd->talisman[type] <= 0) {
- ShowError("pc_talisman_timer: %d talisman's available. (aid=%d cid=%d tid=%d)\n", sd->talisman[type], sd->status.account_id, sd->status.char_id, tid);
- sd->talisman[type] = 0;
- return 0;
- }
+ if( sd->talisman[type] <= 0 )
+ {
+ ShowError("pc_talisman_timer: %d talisman's available. (aid=%d cid=%d tid=%d)\n", sd->talisman[type], sd->status.account_id, sd->status.char_id, tid);
+ sd->talisman[type] = 0;
+ return 0;
+ }
- ARR_FIND(0, sd->talisman[type], i, sd->talisman_timer[type][i] == tid);
- if (i == sd->talisman[type]) {
- ShowError("pc_talisman_timer: timer not found (aid=%d cid=%d tid=%d)\n", sd->status.account_id, sd->status.char_id, tid);
- return 0;
- }
+ ARR_FIND(0, sd->talisman[type], i, sd->talisman_timer[type][i] == tid);
+ if( i == sd->talisman[type] )
+ {
+ ShowError("pc_talisman_timer: timer not found (aid=%d cid=%d tid=%d)\n", sd->status.account_id, sd->status.char_id, tid);
+ return 0;
+ }
- sd->talisman[type]--;
- if (i != sd->talisman[type])
- memmove(sd->talisman_timer[type]+i, sd->talisman_timer[type]+i+1, (sd->talisman[type]-i)*sizeof(int));
- sd->talisman_timer[type][sd->talisman[type]] = INVALID_TIMER;
+ sd->talisman[type]--;
+ if( i != sd->talisman[type] )
+ memmove(sd->talisman_timer[type]+i, sd->talisman_timer[type]+i+1, (sd->talisman[type]-i)*sizeof(int));
+ sd->talisman_timer[type][sd->talisman[type]] = INVALID_TIMER;
- clif_talisman(sd, type);
+ clif_talisman(sd, type);
- return 0;
+ return 0;
}
int pc_add_talisman(struct map_session_data *sd,int interval,int max,int type)
{
- int tid, i;
+ int tid, i;
- nullpo_ret(sd);
+ nullpo_ret(sd);
- if (max > 10)
- max = 10;
- if (sd->talisman[type] < 0)
- sd->talisman[type] = 0;
+ if(max > 10)
+ max = 10;
+ if(sd->talisman[type] < 0)
+ sd->talisman[type] = 0;
- if (sd->talisman[type] && sd->talisman[type] >= max) {
- if (sd->talisman_timer[type][0] != INVALID_TIMER)
- delete_timer(sd->talisman_timer[type][0],pc_talisman_timer);
- sd->talisman[type]--;
- if (sd->talisman[type] != 0)
- memmove(sd->talisman_timer[type]+0, sd->talisman_timer[type]+1, (sd->talisman[type])*sizeof(int));
- sd->talisman_timer[type][sd->talisman[type]] = INVALID_TIMER;
- }
+ if( sd->talisman[type] && sd->talisman[type] >= max )
+ {
+ if(sd->talisman_timer[type][0] != INVALID_TIMER)
+ delete_timer(sd->talisman_timer[type][0],pc_talisman_timer);
+ sd->talisman[type]--;
+ if( sd->talisman[type] != 0 )
+ memmove(sd->talisman_timer[type]+0, sd->talisman_timer[type]+1, (sd->talisman[type])*sizeof(int));
+ sd->talisman_timer[type][sd->talisman[type]] = INVALID_TIMER;
+ }
- tid = add_timer(gettick()+interval, pc_talisman_timer, sd->bl.id, 0);
- ARR_FIND(0, sd->talisman[type], i, sd->talisman_timer[type][i] == INVALID_TIMER || DIFF_TICK(get_timer(tid)->tick, get_timer(sd->talisman_timer[type][i])->tick) < 0);
- if (i != sd->talisman[type])
- memmove(sd->talisman_timer[type]+i+1, sd->talisman_timer[type]+i, (sd->talisman[type]-i)*sizeof(int));
- sd->talisman_timer[type][i] = tid;
- sd->talisman[type]++;
+ tid = add_timer(gettick()+interval, pc_talisman_timer, sd->bl.id, 0);
+ ARR_FIND(0, sd->talisman[type], i, sd->talisman_timer[type][i] == INVALID_TIMER || DIFF_TICK(get_timer(tid)->tick, get_timer(sd->talisman_timer[type][i])->tick) < 0);
+ if( i != sd->talisman[type] )
+ memmove(sd->talisman_timer[type]+i+1, sd->talisman_timer[type]+i, (sd->talisman[type]-i)*sizeof(int));
+ sd->talisman_timer[type][i] = tid;
+ sd->talisman[type]++;
- clif_talisman(sd, type);
- return 0;
+ clif_talisman(sd, type);
+ return 0;
}
int pc_del_talisman(struct map_session_data *sd,int count,int type)
{
- int i;
-
- nullpo_ret(sd);
-
- if (sd->talisman[type] <= 0) {
- sd->talisman[type] = 0;
- return 0;
- }
-
- if (count <= 0)
- return 0;
- if (count > sd->talisman[type])
- count = sd->talisman[type];
- sd->talisman[type] -= count;
- if (count > 10)
- count = 10;
-
- for (i = 0; i < count; i++) {
- if (sd->talisman_timer[type][i] != INVALID_TIMER) {
- delete_timer(sd->talisman_timer[type][i],pc_talisman_timer);
- sd->talisman_timer[type][i] = INVALID_TIMER;
- }
- }
- for (i = count; i < 10; i++) {
- sd->talisman_timer[type][i-count] = sd->talisman_timer[type][i];
- sd->talisman_timer[type][i] = INVALID_TIMER;
- }
-
- clif_talisman(sd, type);
- return 0;
+ int i;
+
+ nullpo_ret(sd);
+
+ if( sd->talisman[type] <= 0 ) {
+ sd->talisman[type] = 0;
+ return 0;
+ }
+
+ if( count <= 0 )
+ return 0;
+ if( count > sd->talisman[type] )
+ count = sd->talisman[type];
+ sd->talisman[type] -= count;
+ if( count > 10 )
+ count = 10;
+
+ for(i = 0; i < count; i++) {
+ if(sd->talisman_timer[type][i] != INVALID_TIMER) {
+ delete_timer(sd->talisman_timer[type][i],pc_talisman_timer);
+ sd->talisman_timer[type][i] = INVALID_TIMER;
+ }
+ }
+ for(i = count; i < 10; i++) {
+ sd->talisman_timer[type][i-count] = sd->talisman_timer[type][i];
+ sd->talisman_timer[type][i] = INVALID_TIMER;
+ }
+
+ clif_talisman(sd, type);
+ return 0;
}
#if defined(RENEWAL_DROP) || defined(RENEWAL_EXP)
/*==========================================
@@ -9281,165 +9169,170 @@ int pc_del_talisman(struct map_session_data *sd,int count,int type)
*------------------------------------------*/
int pc_level_penalty_mod(struct map_session_data *sd, struct mob_data *md, int type)
{
- int diff, rate = 100, i;
+ int diff, rate = 100, i;
- nullpo_ret(sd);
- nullpo_ret(md);
+ nullpo_ret(sd);
+ nullpo_ret(md);
- diff = md->level - sd->status.base_level;
+ diff = md->level - sd->status.base_level;
- if (diff < 0)
- diff = MAX_LEVEL + (~diff + 1);
+ if( diff < 0 )
+ diff = MAX_LEVEL + ( ~diff + 1 );
- for (i=0; i<RC_MAX; i++) {
- int tmp;
+ for(i=0; i<RC_MAX; i++){
+ int tmp;
- if (md->status.race != i) {
- if (md->status.mode&MD_BOSS && i < RC_BOSS)
- i = RC_BOSS;
- else if (i <= RC_BOSS)
- continue;
- }
+ if( md->status.race != i ){
+ if( md->status.mode&MD_BOSS && i < RC_BOSS )
+ i = RC_BOSS;
+ else if( i <= RC_BOSS )
+ continue;
+ }
- if ((tmp=level_penalty[type][i][diff]) > 0) {
- rate = tmp;
- break;
- }
- }
+ if( (tmp=level_penalty[type][i][diff]) > 0 ){
+ rate = tmp;
+ break;
+ }
+ }
- return rate;
+ return rate;
}
#endif
int pc_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 && i<num-1) //Do not remove a trailing comma.
- *str++=0;
- }
- return i;
-}
-
-int pc_split_atoi(char *str, int *val, char sep, int max)
-{
- int i,j;
- for (i=0; i<max; i++) {
- if (!str) break;
- val[i] = atoi(str);
- str = strchr(str,sep);
- if (str)
- *str++=0;
- }
- //Zero up the remaining.
- for (j=i; j < max; j++)
- val[j] = 0;
- return i;
-}
-
-int pc_split_atoui(char *str, unsigned int *val, char sep, int max)
-{
- static int warning=0;
- int i,j;
- double f;
- for (i=0; i<max; i++) {
- if (!str) break;
- f = atof(str);
- if (f < 0)
- val[i] = 0;
- else if (f > UINT_MAX) {
- val[i] = UINT_MAX;
- if (!warning) {
- warning = 1;
- ShowWarning("pc_readdb (exp.txt): Required exp per level is capped to %u\n", UINT_MAX);
- }
- } else
- val[i] = (unsigned int)f;
- str = strchr(str,sep);
- if (str)
- *str++=0;
- }
- //Zero up the remaining.
- for (j=i; j < max; j++)
- val[j] = 0;
- return i;
+ int i;
+
+ for (i=0; i<num && str; i++){
+ val[i] = str;
+ str = strchr(str,',');
+ if (str && i<num-1) //Do not remove a trailing comma.
+ *str++=0;
+ }
+ return i;
+}
+
+int pc_split_atoi(char* str, int* val, char sep, int max)
+{
+ int i,j;
+ for (i=0; i<max; i++) {
+ if (!str) break;
+ val[i] = atoi(str);
+ str = strchr(str,sep);
+ if (str)
+ *str++=0;
+ }
+ //Zero up the remaining.
+ for(j=i; j < max; j++)
+ val[j] = 0;
+ return i;
+}
+
+int pc_split_atoui(char* str, unsigned int* val, char sep, int max)
+{
+ static int warning=0;
+ int i,j;
+ double f;
+ for (i=0; i<max; i++) {
+ if (!str) break;
+ f = atof(str);
+ if (f < 0)
+ val[i] = 0;
+ else if (f > UINT_MAX) {
+ val[i] = UINT_MAX;
+ if (!warning) {
+ warning = 1;
+ ShowWarning("pc_readdb (exp.txt): Required exp per level is capped to %u\n", UINT_MAX);
+ }
+ } else
+ val[i] = (unsigned int)f;
+ str = strchr(str,sep);
+ if (str)
+ *str++=0;
+ }
+ //Zero up the remaining.
+ for(j=i; j < max; j++)
+ val[j] = 0;
+ return i;
}
/*==========================================
* sub DB reading.
* Function used to read skill_tree.txt
*------------------------------------------*/
-static bool pc_readdb_skilltree(char *fields[], int columns, int current)
-{
- unsigned char joblv = 0, skilllv;
- unsigned short skillid;
- int idx, class_;
- unsigned int i, offset = 3, skillidx;
-
- class_ = atoi(fields[0]);
- skillid = (unsigned short)atoi(fields[1]);
- skilllv = (unsigned char)atoi(fields[2]);
-
- if (columns==4+MAX_PC_SKILL_REQUIRE*2) {
- // job level requirement extra column
- joblv = (unsigned char)atoi(fields[3]);
- offset++;
- }
-
- if (!pcdb_checkid(class_)) {
- ShowWarning("pc_readdb_skilltree: Invalid job class %d specified.\n", class_);
- return false;
- }
- idx = pc_class2idx(class_);
-
- //This is to avoid adding two lines for the same skill. [Skotlex]
- ARR_FIND(0, MAX_SKILL_TREE, skillidx, skill_tree[idx][skillidx].id == 0 || skill_tree[idx][skillidx].id == skillid);
- if (skillidx == MAX_SKILL_TREE) {
- ShowWarning("pc_readdb_skilltree: Unable to load skill %hu into job %d's tree. Maximum number of skills per class has been reached.\n", skillid, class_);
- return false;
- } else if (skill_tree[idx][skillidx].id) {
- ShowNotice("pc_readdb_skilltree: Overwriting skill %hu for job class %d.\n", skillid, class_);
- }
-
- skill_tree[idx][skillidx].id = skillid;
- skill_tree[idx][skillidx].max = skilllv;
- skill_tree[idx][skillidx].joblv = joblv;
-
- for (i = 0; i < MAX_PC_SKILL_REQUIRE; i++) {
- skill_tree[idx][skillidx].need[i].id = atoi(fields[i*2+offset]);
- skill_tree[idx][skillidx].need[i].lv = atoi(fields[i*2+offset+1]);
- }
- return true;
+static bool pc_readdb_skilltree(char* fields[], int columns, int current)
+{
+ unsigned char joblv = 0, skilllv;
+ unsigned short skillid;
+ int idx, class_;
+ unsigned int i, offset = 3, skillidx;
+
+ class_ = atoi(fields[0]);
+ skillid = (unsigned short)atoi(fields[1]);
+ skilllv = (unsigned char)atoi(fields[2]);
+
+ if(columns==4+MAX_PC_SKILL_REQUIRE*2)
+ {// job level requirement extra column
+ joblv = (unsigned char)atoi(fields[3]);
+ offset++;
+ }
+
+ if(!pcdb_checkid(class_))
+ {
+ ShowWarning("pc_readdb_skilltree: Invalid job class %d specified.\n", class_);
+ return false;
+ }
+ idx = pc_class2idx(class_);
+
+ //This is to avoid adding two lines for the same skill. [Skotlex]
+ ARR_FIND( 0, MAX_SKILL_TREE, skillidx, skill_tree[idx][skillidx].id == 0 || skill_tree[idx][skillidx].id == skillid );
+ if( skillidx == MAX_SKILL_TREE )
+ {
+ ShowWarning("pc_readdb_skilltree: Unable to load skill %hu into job %d's tree. Maximum number of skills per class has been reached.\n", skillid, class_);
+ return false;
+ }
+ else if(skill_tree[idx][skillidx].id)
+ {
+ ShowNotice("pc_readdb_skilltree: Overwriting skill %hu for job class %d.\n", skillid, class_);
+ }
+
+ skill_tree[idx][skillidx].id = skillid;
+ skill_tree[idx][skillidx].max = skilllv;
+ skill_tree[idx][skillidx].joblv = joblv;
+
+ for(i = 0; i < MAX_PC_SKILL_REQUIRE; i++)
+ {
+ skill_tree[idx][skillidx].need[i].id = atoi(fields[i*2+offset]);
+ skill_tree[idx][skillidx].need[i].lv = atoi(fields[i*2+offset+1]);
+ }
+ return true;
}
#if defined(RENEWAL_DROP) || defined(RENEWAL_EXP)
-static bool pc_readdb_levelpenalty(char *fields[], int columns, int current)
+static bool pc_readdb_levelpenalty(char* fields[], int columns, int current)
{
- int type, race, diff;
+ int type, race, diff;
- type = atoi(fields[0]);
- race = atoi(fields[1]);
- diff = atoi(fields[2]);
+ type = atoi(fields[0]);
+ race = atoi(fields[1]);
+ diff = atoi(fields[2]);
- if (type != 1 && type != 2) {
- ShowWarning("pc_readdb_levelpenalty: Invalid type %d specified.\n", type);
- return false;
- }
+ if( type != 1 && type != 2 ){
+ ShowWarning("pc_readdb_levelpenalty: Invalid type %d specified.\n", type);
+ return false;
+ }
- if (race < 0 && race > RC_MAX) {
- ShowWarning("pc_readdb_levelpenalty: Invalid race %d specified.\n", race);
- return false;
- }
+ if( race < 0 && race > RC_MAX ){
+ ShowWarning("pc_readdb_levelpenalty: Invalid race %d specified.\n", race);
+ return false;
+ }
- diff = min(diff, MAX_LEVEL);
+ diff = min(diff, MAX_LEVEL);
- if (diff < 0)
- diff = min(MAX_LEVEL + (~(diff) + 1), MAX_LEVEL*2);
+ if( diff < 0 )
+ diff = min(MAX_LEVEL + ( ~(diff) + 1 ), MAX_LEVEL*2);
- level_penalty[type][race][diff] = atoi(fields[3]);
+ level_penalty[type][race][diff] = atoi(fields[3]);
- return true;
+ return true;
}
#endif
@@ -9451,336 +9344,343 @@ static bool pc_readdb_levelpenalty(char *fields[], int columns, int current)
*------------------------------------------*/
int pc_readdb(void)
{
- int i,j,k,tmp=0;
- FILE *fp;
- char line[24000],*p;
+ int i,j,k,tmp=0;
+ FILE *fp;
+ char line[24000],*p;
//reset
- memset(exp_table,0,sizeof(exp_table));
- memset(max_level,0,sizeof(max_level));
-
- sprintf(line, "%s/"DBPATH"exp.txt", db_path);
-
- fp=fopen(line, "r");
- if (fp==NULL) {
- ShowError("can't read %s\n", line);
- return 1;
- }
- while (fgets(line, sizeof(line), fp)) {
- int jobs[CLASS_COUNT], job_count, job, job_id;
- int type;
- unsigned int ui,maxlv;
- char *split[4];
- if (line[0]=='/' && line[1]=='/')
- continue;
- if (pc_split_str(line,split,4) < 4)
- continue;
-
- job_count = pc_split_atoi(split[1],jobs,':',CLASS_COUNT);
- if (job_count < 1)
- continue;
- job_id = jobs[0];
- if (!pcdb_checkid(job_id)) {
- ShowError("pc_readdb: Invalid job ID %d.\n", job_id);
- continue;
- }
- type = atoi(split[2]);
- if (type < 0 || type > 1) {
- ShowError("pc_readdb: Invalid type %d (must be 0 for base levels, 1 for job levels).\n", type);
- continue;
- }
- maxlv = atoi(split[0]);
- if (maxlv > MAX_LEVEL) {
- ShowWarning("pc_readdb: Specified max level %u for job %d is beyond server's limit (%u).\n ", maxlv, job_id, MAX_LEVEL);
- maxlv = MAX_LEVEL;
- }
-
- job = jobs[0] = pc_class2idx(job_id);
- //We send one less and then one more because the last entry in the exp array should hold 0.
- max_level[job][type] = pc_split_atoui(split[3], exp_table[job][type],',',maxlv-1)+1;
- //Reverse check in case the array has a bunch of trailing zeros... [Skotlex]
- //The reasoning behind the -2 is this... if the max level is 5, then the array
- //should look like this:
- //0: x, 1: x, 2: x: 3: x 4: 0 <- last valid value is at 3.
- while ((ui = max_level[job][type]) >= 2 && exp_table[job][type][ui-2] <= 0)
- max_level[job][type]--;
- if (max_level[job][type] < maxlv) {
- ShowWarning("pc_readdb: Specified max %u for job %d, but that job's exp table only goes up to level %u.\n", maxlv, job_id, max_level[job][type]);
- ShowInfo("Filling the missing values with the last exp entry.\n");
- //Fill the requested values with the last entry.
- ui = (max_level[job][type] <= 2? 0: max_level[job][type]-2);
- for (; ui+2 < maxlv; ui++)
- exp_table[job][type][ui] = exp_table[job][type][ui-1];
- max_level[job][type] = maxlv;
- }
- // ShowDebug("%s - Class %d: %d\n", type?"Job":"Base", job_id, max_level[job][type]);
- for (i = 1; i < job_count; i++) {
- job_id = jobs[i];
- if (!pcdb_checkid(job_id)) {
- ShowError("pc_readdb: Invalid job ID %d.\n", job_id);
- continue;
- }
- job = pc_class2idx(job_id);
- memcpy(exp_table[job][type], exp_table[jobs[0]][type], sizeof(exp_table[0][0]));
- max_level[job][type] = maxlv;
- // ShowDebug("%s - Class %d: %u\n", type?"Job":"Base", job_id, max_level[job][type]);
- }
- }
- fclose(fp);
- for (i = 0; i < JOB_MAX; i++) {
- if (!pcdb_checkid(i)) continue;
- if (i == JOB_WEDDING || i == JOB_XMAS || i == JOB_SUMMER)
- continue; //Classes that do not need exp tables.
- j = pc_class2idx(i);
- if (!max_level[j][0])
- ShowWarning("Class %s (%d) does not has a base exp table.\n", job_name(i), i);
- if (!max_level[j][1])
- ShowWarning("Class %s (%d) does not has a job exp table.\n", job_name(i), i);
- }
- ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n","exp.txt");
-
- // Reset and read skilltree
- memset(skill_tree,0,sizeof(skill_tree));
- sv_readdb(db_path, DBPATH"skill_tree.txt", ',', 3+MAX_PC_SKILL_REQUIRE*2, 4+MAX_PC_SKILL_REQUIRE*2, -1, &pc_readdb_skilltree);
+ memset(exp_table,0,sizeof(exp_table));
+ memset(max_level,0,sizeof(max_level));
+
+ sprintf(line, "%s/"DBPATH"exp.txt", db_path);
+
+ fp=fopen(line, "r");
+ if(fp==NULL){
+ ShowError("can't read %s\n", line);
+ return 1;
+ }
+ while(fgets(line, sizeof(line), fp))
+ {
+ int jobs[CLASS_COUNT], job_count, job, job_id;
+ int type;
+ unsigned int ui,maxlv;
+ char *split[4];
+ if(line[0]=='/' && line[1]=='/')
+ continue;
+ if (pc_split_str(line,split,4) < 4)
+ continue;
+
+ job_count = pc_split_atoi(split[1],jobs,':',CLASS_COUNT);
+ if (job_count < 1)
+ continue;
+ job_id = jobs[0];
+ if (!pcdb_checkid(job_id)) {
+ ShowError("pc_readdb: Invalid job ID %d.\n", job_id);
+ continue;
+ }
+ type = atoi(split[2]);
+ if (type < 0 || type > 1) {
+ ShowError("pc_readdb: Invalid type %d (must be 0 for base levels, 1 for job levels).\n", type);
+ continue;
+ }
+ maxlv = atoi(split[0]);
+ if (maxlv > MAX_LEVEL) {
+ ShowWarning("pc_readdb: Specified max level %u for job %d is beyond server's limit (%u).\n ", maxlv, job_id, MAX_LEVEL);
+ maxlv = MAX_LEVEL;
+ }
+
+ job = jobs[0] = pc_class2idx(job_id);
+ //We send one less and then one more because the last entry in the exp array should hold 0.
+ max_level[job][type] = pc_split_atoui(split[3], exp_table[job][type],',',maxlv-1)+1;
+ //Reverse check in case the array has a bunch of trailing zeros... [Skotlex]
+ //The reasoning behind the -2 is this... if the max level is 5, then the array
+ //should look like this:
+ //0: x, 1: x, 2: x: 3: x 4: 0 <- last valid value is at 3.
+ while ((ui = max_level[job][type]) >= 2 && exp_table[job][type][ui-2] <= 0)
+ max_level[job][type]--;
+ if (max_level[job][type] < maxlv) {
+ ShowWarning("pc_readdb: Specified max %u for job %d, but that job's exp table only goes up to level %u.\n", maxlv, job_id, max_level[job][type]);
+ ShowInfo("Filling the missing values with the last exp entry.\n");
+ //Fill the requested values with the last entry.
+ ui = (max_level[job][type] <= 2? 0: max_level[job][type]-2);
+ for (; ui+2 < maxlv; ui++)
+ exp_table[job][type][ui] = exp_table[job][type][ui-1];
+ max_level[job][type] = maxlv;
+ }
+// ShowDebug("%s - Class %d: %d\n", type?"Job":"Base", job_id, max_level[job][type]);
+ for (i = 1; i < job_count; i++) {
+ job_id = jobs[i];
+ if (!pcdb_checkid(job_id)) {
+ ShowError("pc_readdb: Invalid job ID %d.\n", job_id);
+ continue;
+ }
+ job = pc_class2idx(job_id);
+ memcpy(exp_table[job][type], exp_table[jobs[0]][type], sizeof(exp_table[0][0]));
+ max_level[job][type] = maxlv;
+// ShowDebug("%s - Class %d: %u\n", type?"Job":"Base", job_id, max_level[job][type]);
+ }
+ }
+ fclose(fp);
+ for (i = 0; i < JOB_MAX; i++) {
+ if (!pcdb_checkid(i)) continue;
+ if (i == JOB_WEDDING || i == JOB_XMAS || i == JOB_SUMMER)
+ continue; //Classes that do not need exp tables.
+ j = pc_class2idx(i);
+ if (!max_level[j][0])
+ ShowWarning("Class %s (%d) does not has a base exp table.\n", job_name(i), i);
+ if (!max_level[j][1])
+ ShowWarning("Class %s (%d) does not has a job exp table.\n", job_name(i), i);
+ }
+ ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n","exp.txt");
+
+ // Reset and read skilltree
+ memset(skill_tree,0,sizeof(skill_tree));
+ sv_readdb(db_path, DBPATH"skill_tree.txt", ',', 3+MAX_PC_SKILL_REQUIRE*2, 4+MAX_PC_SKILL_REQUIRE*2, -1, &pc_readdb_skilltree);
#if defined(RENEWAL_DROP) || defined(RENEWAL_EXP)
- sv_readdb(db_path, "re/level_penalty.txt", ',', 4, 4, -1, &pc_readdb_levelpenalty);
- for (k=1; k < 3; k++) { // fill in the blanks
- for (j = 0; j < RC_MAX; j++) {
- tmp = 0;
- for (i = 0; i < MAX_LEVEL*2; i++) {
- if (i == MAX_LEVEL+1)
- tmp = level_penalty[k][j][0];// reset
- if (level_penalty[k][j][i] > 0)
- tmp = level_penalty[k][j][i];
- else
- level_penalty[k][j][i] = tmp;
- }
- }
- }
+ sv_readdb(db_path, "re/level_penalty.txt", ',', 4, 4, -1, &pc_readdb_levelpenalty);
+ for( k=1; k < 3; k++ ){ // fill in the blanks
+ for( j = 0; j < RC_MAX; j++ ){
+ tmp = 0;
+ for( i = 0; i < MAX_LEVEL*2; i++ ){
+ if( i == MAX_LEVEL+1 )
+ tmp = level_penalty[k][j][0];// reset
+ if( level_penalty[k][j][i] > 0 )
+ tmp = level_penalty[k][j][i];
+ else
+ level_penalty[k][j][i] = tmp;
+ }
+ }
+ }
#endif
- // Reset then read attr_fix
- for (i=0; i<4; i++)
- for (j=0; j<ELE_MAX; j++)
- for (k=0; k<ELE_MAX; k++)
- attr_fix_table[i][j][k]=100;
-
- sprintf(line, "%s/"DBPATH"attr_fix.txt", db_path);
-
- fp=fopen(line,"r");
- if (fp==NULL) {
- ShowError("can't read %s\n", line);
- return 1;
- }
- while (fgets(line, sizeof(line), fp)) {
- char *split[10];
- int lv,n;
- if (line[0]=='/' && line[1]=='/')
- continue;
- for (j=0,p=line; j<3 && p; j++) {
- split[j]=p;
- p=strchr(p,',');
- if (p) *p++=0;
- }
- if (j < 2)
- continue;
-
- lv=atoi(split[0]);
- n=atoi(split[1]);
-
- for (i=0; i<n && i<ELE_MAX;) {
- if (!fgets(line, sizeof(line), fp))
- break;
- if (line[0]=='/' && line[1]=='/')
- continue;
-
- for (j=0,p=line; j<n && j<ELE_MAX && p; j++) {
- while (*p==32 && *p>0)
- p++;
- attr_fix_table[lv-1][i][j]=atoi(p);
- if (battle_config.attr_recover == 0 && attr_fix_table[lv-1][i][j] < 0)
- attr_fix_table[lv-1][i][j] = 0;
- p=strchr(p,',');
- if (p) *p++=0;
- }
-
- i++;
- }
- }
- fclose(fp);
- ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n","attr_fix.txt");
+ // Reset then read attr_fix
+ for(i=0;i<4;i++)
+ for(j=0;j<ELE_MAX;j++)
+ for(k=0;k<ELE_MAX;k++)
+ attr_fix_table[i][j][k]=100;
+
+ sprintf(line, "%s/"DBPATH"attr_fix.txt", db_path);
+
+ fp=fopen(line,"r");
+ if(fp==NULL){
+ ShowError("can't read %s\n", line);
+ return 1;
+ }
+ while(fgets(line, sizeof(line), fp))
+ {
+ char *split[10];
+ int lv,n;
+ if(line[0]=='/' && line[1]=='/')
+ continue;
+ for(j=0,p=line;j<3 && p;j++){
+ split[j]=p;
+ p=strchr(p,',');
+ if(p) *p++=0;
+ }
+ if( j < 2 )
+ continue;
+
+ lv=atoi(split[0]);
+ n=atoi(split[1]);
+
+ for(i=0;i<n && i<ELE_MAX;){
+ if( !fgets(line, sizeof(line), fp) )
+ break;
+ if(line[0]=='/' && line[1]=='/')
+ continue;
+
+ for(j=0,p=line;j<n && j<ELE_MAX && p;j++){
+ while(*p==32 && *p>0)
+ p++;
+ attr_fix_table[lv-1][i][j]=atoi(p);
+ if(battle_config.attr_recover == 0 && attr_fix_table[lv-1][i][j] < 0)
+ attr_fix_table[lv-1][i][j] = 0;
+ p=strchr(p,',');
+ if(p) *p++=0;
+ }
+
+ i++;
+ }
+ }
+ fclose(fp);
+ ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n","attr_fix.txt");
// reset then read statspoint
- memset(statp,0,sizeof(statp));
- i=1;
-
- sprintf(line, "%s/"DBPATH"statpoint.txt", db_path);
- fp=fopen(line,"r");
- if (fp == NULL) {
- ShowWarning("Can't read '"CL_WHITE"%s"CL_RESET"'... Generating DB.\n",line);
- //return 1;
- } else {
- while (fgets(line, sizeof(line), fp)) {
- int stat;
- if (line[0]=='/' && line[1]=='/')
- continue;
- if ((stat=strtoul(line,NULL,10))<0)
- stat=0;
- if (i > MAX_LEVEL)
- break;
- statp[i]=stat;
- i++;
- }
- fclose(fp);
-
- ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n","statpoint.txt");
- }
- // generate the remaining parts of the db if necessary
- k = battle_config.use_statpoint_table; //save setting
- battle_config.use_statpoint_table = 0; //temporarily disable to force pc_gets_status_point use default values
- statp[0] = 45; // seed value
- for (; i <= MAX_LEVEL; i++)
- statp[i] = statp[i-1] + pc_gets_status_point(i-1);
- battle_config.use_statpoint_table = k; //restore setting
-
- return 0;
+ memset(statp,0,sizeof(statp));
+ i=1;
+
+ sprintf(line, "%s/"DBPATH"statpoint.txt", db_path);
+ fp=fopen(line,"r");
+ if(fp == NULL){
+ ShowWarning("Can't read '"CL_WHITE"%s"CL_RESET"'... Generating DB.\n",line);
+ //return 1;
+ } else {
+ while(fgets(line, sizeof(line), fp))
+ {
+ int stat;
+ if(line[0]=='/' && line[1]=='/')
+ continue;
+ if ((stat=strtoul(line,NULL,10))<0)
+ stat=0;
+ if (i > MAX_LEVEL)
+ break;
+ statp[i]=stat;
+ i++;
+ }
+ fclose(fp);
+
+ ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n","statpoint.txt");
+ }
+ // generate the remaining parts of the db if necessary
+ k = battle_config.use_statpoint_table; //save setting
+ battle_config.use_statpoint_table = 0; //temporarily disable to force pc_gets_status_point use default values
+ statp[0] = 45; // seed value
+ for (; i <= MAX_LEVEL; i++)
+ statp[i] = statp[i-1] + pc_gets_status_point(i-1);
+ battle_config.use_statpoint_table = k; //restore setting
+
+ return 0;
}
// Read MOTD on startup. [Valaris]
int pc_read_motd(void)
{
- FILE *fp;
-
- // clear old MOTD
- memset(motd_text, 0, sizeof(motd_text));
-
- // read current MOTD
- if ((fp = fopen(motd_txt, "r")) != NULL) {
- char *buf, * ptr;
- unsigned int lines = 0, entries = 0;
- size_t len;
-
- while (entries < MOTD_LINE_SIZE && fgets(motd_text[entries], sizeof(motd_text[entries]), fp)) {
- lines++;
-
- buf = motd_text[entries];
-
- if (buf[0] == '/' && buf[1] == '/') {
- continue;
- }
-
- len = strlen(buf);
-
- while (len && (buf[len-1] == '\r' || buf[len-1] == '\n')) {
- // strip trailing EOL characters
- len--;
- }
-
- if (len) {
- buf[len] = 0;
-
- if ((ptr = strstr(buf, " :")) != NULL && ptr-buf >= NAME_LENGTH) {
- // crashes newer clients
- ShowWarning("Found sequence '"CL_WHITE" :"CL_RESET"' on line '"CL_WHITE"%u"CL_RESET"' in '"CL_WHITE"%s"CL_RESET"'. This can cause newer clients to crash.\n", lines, motd_txt);
- }
- } else {
- // empty line
- buf[0] = ' ';
- buf[1] = 0;
- }
- entries++;
- }
- fclose(fp);
-
- ShowStatus("Done reading '"CL_WHITE"%u"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", entries, motd_txt);
- } else {
- ShowWarning("File '"CL_WHITE"%s"CL_RESET"' not found.\n", motd_txt);
- }
-
- return 0;
-}
-void pc_itemcd_do(struct map_session_data *sd, bool load)
-{
- int i,cursor = 0;
- struct item_cd *cd = NULL;
-
- if (load) {
- if (!(cd = idb_get(itemcd_db, sd->status.char_id))) {
- // no skill cooldown is associated with this character
- return;
- }
- for (i = 0; i < MAX_ITEMDELAYS; i++) {
- if (cd->nameid[i] && DIFF_TICK(gettick(),cd->tick[i]) < 0) {
- sd->item_delay[cursor].tick = cd->tick[i];
- sd->item_delay[cursor].nameid = cd->nameid[i];
- cursor++;
- }
- }
- idb_remove(itemcd_db,sd->status.char_id);
- } else {
- if (!(cd = idb_get(itemcd_db,sd->status.char_id))) {
- // create a new skill cooldown object for map storage
- CREATE(cd, struct item_cd, 1);
- idb_put(itemcd_db, sd->status.char_id, cd);
- }
- for (i = 0; i < MAX_ITEMDELAYS; i++) {
- if (sd->item_delay[i].nameid && DIFF_TICK(gettick(),sd->item_delay[i].tick) < 0) {
- cd->tick[cursor] = sd->item_delay[i].tick;
- cd->nameid[cursor] = sd->item_delay[i].nameid;
- cursor++;
- }
- }
- }
- return;
+ FILE* fp;
+
+ // clear old MOTD
+ memset(motd_text, 0, sizeof(motd_text));
+
+ // read current MOTD
+ if( ( fp = fopen(motd_txt, "r") ) != NULL )
+ {
+ char* buf, * ptr;
+ unsigned int lines = 0, entries = 0;
+ size_t len;
+
+ while( entries < MOTD_LINE_SIZE && fgets(motd_text[entries], sizeof(motd_text[entries]), fp) )
+ {
+ lines++;
+
+ buf = motd_text[entries];
+
+ if( buf[0] == '/' && buf[1] == '/' )
+ {
+ continue;
+ }
+
+ len = strlen(buf);
+
+ while( len && ( buf[len-1] == '\r' || buf[len-1] == '\n' ) )
+ {// strip trailing EOL characters
+ len--;
+ }
+
+ if( len )
+ {
+ buf[len] = 0;
+
+ if( ( ptr = strstr(buf, " :") ) != NULL && ptr-buf >= NAME_LENGTH )
+ {// crashes newer clients
+ ShowWarning("Found sequence '"CL_WHITE" :"CL_RESET"' on line '"CL_WHITE"%u"CL_RESET"' in '"CL_WHITE"%s"CL_RESET"'. This can cause newer clients to crash.\n", lines, motd_txt);
+ }
+ }
+ else
+ {// empty line
+ buf[0] = ' ';
+ buf[1] = 0;
+ }
+ entries++;
+ }
+ fclose(fp);
+
+ ShowStatus("Done reading '"CL_WHITE"%u"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", entries, motd_txt);
+ }
+ else
+ {
+ ShowWarning("File '"CL_WHITE"%s"CL_RESET"' not found.\n", motd_txt);
+ }
+
+ return 0;
+}
+void pc_itemcd_do(struct map_session_data *sd, bool load) {
+ int i,cursor = 0;
+ struct item_cd* cd = NULL;
+
+ if( load ) {
+ if( !(cd = idb_get(itemcd_db, sd->status.char_id)) ) {
+ // no skill cooldown is associated with this character
+ return;
+ }
+ for(i = 0; i < MAX_ITEMDELAYS; i++) {
+ if( cd->nameid[i] && DIFF_TICK(gettick(),cd->tick[i]) < 0 ) {
+ sd->item_delay[cursor].tick = cd->tick[i];
+ sd->item_delay[cursor].nameid = cd->nameid[i];
+ cursor++;
+ }
+ }
+ idb_remove(itemcd_db,sd->status.char_id);
+ } else {
+ if( !(cd = idb_get(itemcd_db,sd->status.char_id)) ) {
+ // create a new skill cooldown object for map storage
+ CREATE( cd, struct item_cd, 1 );
+ idb_put( itemcd_db, sd->status.char_id, cd );
+ }
+ for(i = 0; i < MAX_ITEMDELAYS; i++) {
+ if( sd->item_delay[i].nameid && DIFF_TICK(gettick(),sd->item_delay[i].tick) < 0 ) {
+ cd->tick[cursor] = sd->item_delay[i].tick;
+ cd->nameid[cursor] = sd->item_delay[i].nameid;
+ cursor++;
+ }
+ }
+ }
+ return;
}
/*==========================================
* pc Init/Terminate
*------------------------------------------*/
-void do_final_pc(void)
-{
+void do_final_pc(void) {
- db_destroy(itemcd_db);
+ db_destroy(itemcd_db);
- do_final_pc_groups();
- return;
+ do_final_pc_groups();
+ return;
}
-int do_init_pc(void)
-{
+int do_init_pc(void) {
- itemcd_db = idb_alloc(DB_OPT_RELEASE_DATA);
+ itemcd_db = idb_alloc(DB_OPT_RELEASE_DATA);
- pc_readdb();
- pc_read_motd(); // Read MOTD [Valaris]
+ pc_readdb();
+ pc_read_motd(); // Read MOTD [Valaris]
- add_timer_func_list(pc_invincible_timer, "pc_invincible_timer");
- add_timer_func_list(pc_eventtimer, "pc_eventtimer");
- add_timer_func_list(pc_inventory_rental_end, "pc_inventory_rental_end");
- add_timer_func_list(pc_calc_pvprank_timer, "pc_calc_pvprank_timer");
- add_timer_func_list(pc_autosave, "pc_autosave");
- add_timer_func_list(pc_spiritball_timer, "pc_spiritball_timer");
- add_timer_func_list(pc_follow_timer, "pc_follow_timer");
- add_timer_func_list(pc_endautobonus, "pc_endautobonus");
- add_timer_func_list(pc_talisman_timer, "pc_talisman_timer");
+ add_timer_func_list(pc_invincible_timer, "pc_invincible_timer");
+ add_timer_func_list(pc_eventtimer, "pc_eventtimer");
+ add_timer_func_list(pc_inventory_rental_end, "pc_inventory_rental_end");
+ add_timer_func_list(pc_calc_pvprank_timer, "pc_calc_pvprank_timer");
+ add_timer_func_list(pc_autosave, "pc_autosave");
+ add_timer_func_list(pc_spiritball_timer, "pc_spiritball_timer");
+ add_timer_func_list(pc_follow_timer, "pc_follow_timer");
+ add_timer_func_list(pc_endautobonus, "pc_endautobonus");
+ add_timer_func_list(pc_talisman_timer, "pc_talisman_timer");
- add_timer(gettick() + autosave_interval, pc_autosave, 0, 0);
+ add_timer(gettick() + autosave_interval, pc_autosave, 0, 0);
- // 0=day, 1=night [Yor]
- night_flag = battle_config.night_at_start ? 1 : 0;
+ // 0=day, 1=night [Yor]
+ night_flag = battle_config.night_at_start ? 1 : 0;
- 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;
- // add night/day timer [Yor]
- add_timer_func_list(map_day_timer, "map_day_timer");
- add_timer_func_list(map_night_timer, "map_night_timer");
+ 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;
+ // add night/day timer [Yor]
+ add_timer_func_list(map_day_timer, "map_day_timer");
+ add_timer_func_list(map_night_timer, "map_night_timer");
- day_timer_tid = add_timer_interval(gettick() + (night_flag ? 0 : day_duration) + night_duration, map_day_timer, 0, 0, day_duration + night_duration);
- night_timer_tid = add_timer_interval(gettick() + day_duration + (night_flag ? night_duration : 0), map_night_timer, 0, 0, day_duration + night_duration);
- }
+ day_timer_tid = add_timer_interval(gettick() + (night_flag ? 0 : day_duration) + night_duration, map_day_timer, 0, 0, day_duration + night_duration);
+ night_timer_tid = add_timer_interval(gettick() + day_duration + (night_flag ? night_duration : 0), map_night_timer, 0, 0, day_duration + night_duration);
+ }
- do_init_pc_groups();
+ do_init_pc_groups();
- return 0;
+ return 0;
}
diff --git a/src/map/pc.h b/src/map/pc.h
index 971fce1d2..bc8a76f2a 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -25,456 +25,456 @@
#define MAX_PC_FEELHATE 3
struct weapon_data {
- int atkmods[3];
- // all the variables except atkmods get zero'ed in each call of status_calc_pc
- // NOTE: if you want to add a non-zeroed variable, you need to update the memset call
- // in status_calc_pc as well! All the following are automatically zero'ed. [Skotlex]
- int overrefine;
- int star;
- int ignore_def_ele;
- int ignore_def_race;
- int def_ratio_atk_ele;
- int def_ratio_atk_race;
- int addele[ELE_MAX];
- int addrace[RC_MAX];
- int addrace2[RC2_MAX];
- int addsize[3];
-
- struct drain_data {
- short rate;
- short per;
- short value;
- unsigned type:1;
- } hp_drain[RC_MAX], sp_drain[RC_MAX];
-
- struct {
- short class_, rate;
- } add_dmg[MAX_PC_BONUS];
-
- struct {
- short flag, rate;
- unsigned char ele;
- } addele2[MAX_PC_BONUS];
+ int atkmods[3];
+ // all the variables except atkmods get zero'ed in each call of status_calc_pc
+ // NOTE: if you want to add a non-zeroed variable, you need to update the memset call
+ // in status_calc_pc as well! All the following are automatically zero'ed. [Skotlex]
+ int overrefine;
+ int star;
+ int ignore_def_ele;
+ int ignore_def_race;
+ int def_ratio_atk_ele;
+ int def_ratio_atk_race;
+ int addele[ELE_MAX];
+ int addrace[RC_MAX];
+ int addrace2[RC2_MAX];
+ int addsize[3];
+
+ struct drain_data {
+ short rate;
+ short per;
+ short value;
+ unsigned type:1;
+ } hp_drain[RC_MAX], sp_drain[RC_MAX];
+
+ struct {
+ short class_, rate;
+ } add_dmg[MAX_PC_BONUS];
+
+ struct {
+ short flag, rate;
+ unsigned char ele;
+ } addele2[MAX_PC_BONUS];
};
struct s_autospell {
- short id, lv, rate, card_id, flag;
- bool lock; // bAutoSpellOnSkill: blocks autospell from triggering again, while being executed
+ short id, lv, rate, card_id, flag;
+ bool lock; // bAutoSpellOnSkill: blocks autospell from triggering again, while being executed
};
struct s_addeffect {
- enum sc_type id;
- short rate, arrow_rate;
- unsigned char flag;
+ enum sc_type id;
+ short rate, arrow_rate;
+ unsigned char flag;
};
struct s_addeffectonskill {
- enum sc_type id;
- short rate, skill;
- unsigned char target;
+ enum sc_type id;
+ short rate, skill;
+ unsigned char target;
};
struct s_add_drop {
- short id, group;
- int race, rate;
+ short id, group;
+ int race, rate;
};
struct s_autobonus {
- short rate,atk_type;
- unsigned int duration;
- char *bonus_script, *other_script;
- int active;
- unsigned short pos;
+ short rate,atk_type;
+ unsigned int duration;
+ char *bonus_script, *other_script;
+ int active;
+ unsigned short pos;
};
struct map_session_data {
- struct block_list bl;
- struct unit_data ud;
- struct view_data vd;
- struct status_data base_status, battle_status;
- struct status_change sc;
- struct regen_data regen;
- struct regen_data_sub sregen, ssregen;
- //NOTE: When deciding to add a flag to state or special_state, take into consideration that state is preserved in
- //status_calc_pc, while special_state is recalculated in each call. [Skotlex]
- struct {
- unsigned int active : 1; //Marks active player (not active is logging in/out, or changing map servers)
- unsigned int menu_or_input : 1;// if a script is waiting for feedback from the player
- unsigned int dead_sit : 2;
- unsigned int lr_flag : 3;//1: left h. weapon; 2: arrow; 3: shield
- unsigned int connect_new : 1;
- unsigned int arrow_atk : 1;
- unsigned int gangsterparadise : 1;
- unsigned int rest : 1;
- unsigned int storage_flag : 2; //0: closed, 1: Normal Storage open, 2: guild storage open [Skotlex]
- unsigned int snovice_dead_flag : 1; //Explosion spirits on death: 0 off, 1 used.
- unsigned int abra_flag : 2; // Abracadabra bugfix by Aru
- unsigned int autocast : 1; // Autospell flag [Inkfish]
- unsigned int autotrade : 1; //By Fantik
- unsigned int reg_dirty : 4; //By Skotlex (marks whether registry variables have been saved or not yet)
- unsigned int showdelay :1;
- unsigned int showexp :1;
- unsigned int showzeny :1;
- unsigned int mainchat :1; //[LuzZza]
- unsigned int noask :1; // [LuzZza]
- unsigned int trading :1; //[Skotlex] is 1 only after a trade has started.
- unsigned int deal_locked :2; //1: Clicked on OK. 2: Clicked on TRADE
- unsigned int monster_ignore :1; // for monsters to ignore a character [Valaris] [zzo]
- unsigned int size :2; // for tiny/large types
- unsigned int night :1; //Holds whether or not the player currently has the SI_NIGHT effect on. [Skotlex]
- unsigned int blockedmove :1;
- unsigned int using_fake_npc :1;
- unsigned int rewarp :1; //Signals that a player should warp as soon as he is done loading a map. [Skotlex]
- unsigned int killer : 1;
- unsigned int killable : 1;
- unsigned int doridori : 1;
- unsigned int ignoreAll : 1;
- unsigned int debug_remove_map : 1; // temporary state to track double remove_map's [FlavioJS]
- unsigned int buyingstore : 1;
- unsigned int lesseffect : 1;
- unsigned int vending : 1;
- unsigned int noks : 3; // [Zeph Kill Steal Protection]
- unsigned int changemap : 1;
- unsigned int callshop : 1; // flag to indicate that a script used callshop; on a shop
- short pmap; // Previous map on Map Change
- unsigned short autoloot;
- unsigned short autolootid[AUTOLOOTITEM_SIZE]; // [Zephyrus]
- unsigned int autolooting : 1; //performance-saver, autolooting state for @alootid
- unsigned short autobonus; //flag to indicate if an autobonus is activated. [Inkfish]
- struct guild *gmaster_flag;
- unsigned int prevend : 1;//used to flag wheather you've spent 40sp to open the vending or not.
- unsigned int warping : 1;//states whether you're in the middle of a warp processing
- } state;
- struct {
- unsigned char no_weapon_damage, no_magic_damage, no_misc_damage;
- unsigned int restart_full_recover : 1;
- unsigned int no_castcancel : 1;
- unsigned int no_castcancel2 : 1;
- unsigned int no_sizefix : 1;
- unsigned int no_gemstone : 1;
- unsigned int intravision : 1; // Maya Purple Card effect [DracoRPG]
- unsigned int perfect_hiding : 1; // [Valaris]
- unsigned int no_knockback : 1;
- unsigned int bonus_coma : 1;
- } special_state;
- int login_id1, login_id2;
- unsigned short class_; //This is the internal job ID used by the map server to simplify comparisons/queries/etc. [Skotlex]
- int group_id, group_pos, group_level;
- unsigned int permissions;/* group permissions */
-
- int packet_ver; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 ... 18
- struct mmo_charstatus status;
- struct registry save_reg;
-
- struct item_data *inventory_data[MAX_INVENTORY]; // direct pointers to itemdb entries (faster than doing item_id lookups)
- short equip_index[14];
- unsigned int weight,max_weight;
- int cart_weight,cart_num,cart_weight_max;
- int fd;
- unsigned short mapindex;
- unsigned char head_dir; //0: Look forward. 1: Look right, 2: Look left.
- unsigned int client_tick;
- int npc_id,areanpc_id,npc_shopid,touching_id; //for script follow scriptoid; ,npcid
- int npc_item_flag; //Marks the npc_id with which you can use items during interactions with said npc (see script command enable_itemuse)
- int npc_menu; // internal variable, used in npc menu handling
- int npc_amount;
- struct script_state *st;
- char npc_str[CHATBOX_SIZE]; // for passing npc input box text to script engine
- int npc_timer_id; //For player attached npc timers. [Skotlex]
- unsigned int chatID;
- time_t idletime;
-
- struct {
- int npc_id;
- unsigned int timeout;
- } progressbar; //Progress Bar [Inkfish]
-
- struct {
- char name[NAME_LENGTH];
- } ignore[MAX_IGNORE_LIST];
-
- int followtimer; // [MouseJstr]
- int followtarget;
-
- time_t emotionlasttime; // to limit flood with emotion packets
-
- short skillitem,skillitemlv;
- short skillid_old,skilllv_old;
- short skillid_dance,skilllv_dance;
- short cook_mastery; // range: [0,1999] [Inkfish]
- unsigned char blockskill[MAX_SKILL];
- int cloneskill_id, reproduceskill_id;
- int menuskill_id, menuskill_val, menuskill_val2;
-
- int invincible_timer;
- unsigned int canlog_tick;
- unsigned int canuseitem_tick; // [Skotlex]
- unsigned int canusecashfood_tick;
- unsigned int canequip_tick; // [Inkfish]
- unsigned int cantalk_tick;
- unsigned int canskill_tick; // used to prevent abuse from no-delay ACT files
- unsigned int cansendmail_tick; // [Mail System Flood Protection]
- unsigned int ks_floodprotect_tick; // [Kill Steal Protection]
+ struct block_list bl;
+ struct unit_data ud;
+ struct view_data vd;
+ struct status_data base_status, battle_status;
+ struct status_change sc;
+ struct regen_data regen;
+ struct regen_data_sub sregen, ssregen;
+ //NOTE: When deciding to add a flag to state or special_state, take into consideration that state is preserved in
+ //status_calc_pc, while special_state is recalculated in each call. [Skotlex]
+ struct {
+ unsigned int active : 1; //Marks active player (not active is logging in/out, or changing map servers)
+ unsigned int menu_or_input : 1;// if a script is waiting for feedback from the player
+ unsigned int dead_sit : 2;
+ unsigned int lr_flag : 3;//1: left h. weapon; 2: arrow; 3: shield
+ unsigned int connect_new : 1;
+ unsigned int arrow_atk : 1;
+ unsigned int gangsterparadise : 1;
+ unsigned int rest : 1;
+ unsigned int storage_flag : 2; //0: closed, 1: Normal Storage open, 2: guild storage open [Skotlex]
+ unsigned int snovice_dead_flag : 1; //Explosion spirits on death: 0 off, 1 used.
+ unsigned int abra_flag : 2; // Abracadabra bugfix by Aru
+ unsigned int autocast : 1; // Autospell flag [Inkfish]
+ unsigned int autotrade : 1; //By Fantik
+ unsigned int reg_dirty : 4; //By Skotlex (marks whether registry variables have been saved or not yet)
+ unsigned int showdelay :1;
+ unsigned int showexp :1;
+ unsigned int showzeny :1;
+ unsigned int mainchat :1; //[LuzZza]
+ unsigned int noask :1; // [LuzZza]
+ unsigned int trading :1; //[Skotlex] is 1 only after a trade has started.
+ unsigned int deal_locked :2; //1: Clicked on OK. 2: Clicked on TRADE
+ unsigned int monster_ignore :1; // for monsters to ignore a character [Valaris] [zzo]
+ unsigned int size :2; // for tiny/large types
+ unsigned int night :1; //Holds whether or not the player currently has the SI_NIGHT effect on. [Skotlex]
+ unsigned int blockedmove :1;
+ unsigned int using_fake_npc :1;
+ unsigned int rewarp :1; //Signals that a player should warp as soon as he is done loading a map. [Skotlex]
+ unsigned int killer : 1;
+ unsigned int killable : 1;
+ unsigned int doridori : 1;
+ unsigned int ignoreAll : 1;
+ unsigned int debug_remove_map : 1; // temporary state to track double remove_map's [FlavioJS]
+ unsigned int buyingstore : 1;
+ unsigned int lesseffect : 1;
+ unsigned int vending : 1;
+ unsigned int noks : 3; // [Zeph Kill Steal Protection]
+ unsigned int changemap : 1;
+ unsigned int callshop : 1; // flag to indicate that a script used callshop; on a shop
+ short pmap; // Previous map on Map Change
+ unsigned short autoloot;
+ unsigned short autolootid[AUTOLOOTITEM_SIZE]; // [Zephyrus]
+ unsigned int autolooting : 1; //performance-saver, autolooting state for @alootid
+ unsigned short autobonus; //flag to indicate if an autobonus is activated. [Inkfish]
+ struct guild *gmaster_flag;
+ unsigned int prevend : 1;//used to flag wheather you've spent 40sp to open the vending or not.
+ unsigned int warping : 1;//states whether you're in the middle of a warp processing
+ } state;
+ struct {
+ unsigned char no_weapon_damage, no_magic_damage, no_misc_damage;
+ unsigned int restart_full_recover : 1;
+ unsigned int no_castcancel : 1;
+ unsigned int no_castcancel2 : 1;
+ unsigned int no_sizefix : 1;
+ unsigned int no_gemstone : 1;
+ unsigned int intravision : 1; // Maya Purple Card effect [DracoRPG]
+ unsigned int perfect_hiding : 1; // [Valaris]
+ unsigned int no_knockback : 1;
+ unsigned int bonus_coma : 1;
+ } special_state;
+ int login_id1, login_id2;
+ unsigned short class_; //This is the internal job ID used by the map server to simplify comparisons/queries/etc. [Skotlex]
+ int group_id, group_pos, group_level;
+ unsigned int permissions;/* group permissions */
+
+ int packet_ver; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 ... 18
+ struct mmo_charstatus status;
+ struct registry save_reg;
+
+ struct item_data* inventory_data[MAX_INVENTORY]; // direct pointers to itemdb entries (faster than doing item_id lookups)
+ short equip_index[14];
+ unsigned int weight,max_weight;
+ int cart_weight,cart_num,cart_weight_max;
+ int fd;
+ unsigned short mapindex;
+ unsigned char head_dir; //0: Look forward. 1: Look right, 2: Look left.
+ unsigned int client_tick;
+ int npc_id,areanpc_id,npc_shopid,touching_id; //for script follow scriptoid; ,npcid
+ int npc_item_flag; //Marks the npc_id with which you can use items during interactions with said npc (see script command enable_itemuse)
+ int npc_menu; // internal variable, used in npc menu handling
+ int npc_amount;
+ struct script_state *st;
+ char npc_str[CHATBOX_SIZE]; // for passing npc input box text to script engine
+ int npc_timer_id; //For player attached npc timers. [Skotlex]
+ unsigned int chatID;
+ time_t idletime;
+
+ struct{
+ int npc_id;
+ unsigned int timeout;
+ } progressbar; //Progress Bar [Inkfish]
+
+ struct{
+ char name[NAME_LENGTH];
+ } ignore[MAX_IGNORE_LIST];
+
+ int followtimer; // [MouseJstr]
+ int followtarget;
+
+ time_t emotionlasttime; // to limit flood with emotion packets
+
+ short skillitem,skillitemlv;
+ short skillid_old,skilllv_old;
+ short skillid_dance,skilllv_dance;
+ short cook_mastery; // range: [0,1999] [Inkfish]
+ unsigned char blockskill[MAX_SKILL];
+ int cloneskill_id, reproduceskill_id;
+ int menuskill_id, menuskill_val, menuskill_val2;
+
+ int invincible_timer;
+ unsigned int canlog_tick;
+ unsigned int canuseitem_tick; // [Skotlex]
+ unsigned int canusecashfood_tick;
+ unsigned int canequip_tick; // [Inkfish]
+ unsigned int cantalk_tick;
+ unsigned int canskill_tick; // used to prevent abuse from no-delay ACT files
+ unsigned int cansendmail_tick; // [Mail System Flood Protection]
+ unsigned int ks_floodprotect_tick; // [Kill Steal Protection]
unsigned int bloodylust_tick; // bloodylust player timer [out/in re full-heal protection]
- struct {
- short nameid;
- unsigned int tick;
- } item_delay[MAX_ITEMDELAYS]; // [Paradox924X]
-
- short weapontype1,weapontype2;
- short disguise; // [Valaris]
-
- struct weapon_data right_weapon, left_weapon;
-
- // here start arrays to be globally zeroed at the beginning of status_calc_pc()
- int param_bonus[6],param_equip[6]; //Stores card/equipment bonuses.
- int subele[ELE_MAX];
- int subrace[RC_MAX];
- int subrace2[RC2_MAX];
- int subsize[3];
- int reseff[SC_COMMON_MAX-SC_COMMON_MIN+1];
- int weapon_coma_ele[ELE_MAX];
- int weapon_coma_race[RC_MAX];
- int weapon_atk[16];
- int weapon_atk_rate[16];
- int arrow_addele[ELE_MAX];
- int arrow_addrace[RC_MAX];
- int arrow_addsize[3];
- int magic_addele[ELE_MAX];
- int magic_addrace[RC_MAX];
- int magic_addsize[3];
- int critaddrace[RC_MAX];
- int expaddrace[RC_MAX];
- int ignore_mdef[RC_MAX];
- int ignore_def[RC_MAX];
- int itemgrouphealrate[MAX_ITEMGROUP];
- short sp_gain_race[RC_MAX];
- short sp_gain_race_attack[RC_MAX];
- short hp_gain_race_attack[RC_MAX];
- // zeroed arrays end here.
- // zeroed structures start here
- struct s_autospell autospell[15], autospell2[15], autospell3[15];
- struct s_addeffect addeff[MAX_PC_BONUS], addeff2[MAX_PC_BONUS];
- struct s_addeffectonskill addeff3[MAX_PC_BONUS];
-
- struct { //skillatk raises bonus dmg% of skills, skillheal increases heal%, skillblown increases bonus blewcount for some skills.
- unsigned short id;
- short val;
- } skillatk[MAX_PC_BONUS], skillusesprate[MAX_PC_BONUS], skillusesp[MAX_PC_BONUS], skillheal[5], skillheal2[5], skillblown[MAX_PC_BONUS], skillcast[MAX_PC_BONUS], skillcooldown[MAX_PC_BONUS], skillfixcast[MAX_PC_BONUS], skillvarcast[MAX_PC_BONUS];
- struct {
- short value;
- int rate;
- int tick;
- } hp_loss, sp_loss, hp_regen, sp_regen;
- struct {
- short class_, rate;
- } add_def[MAX_PC_BONUS], add_mdef[MAX_PC_BONUS], add_mdmg[MAX_PC_BONUS];
- struct s_add_drop add_drop[MAX_PC_BONUS];
- struct {
- int nameid;
- int rate;
- } itemhealrate[MAX_PC_BONUS];
- struct {
- short flag, rate;
- unsigned char ele;
- } subele2[MAX_PC_BONUS];
- // zeroed structures end here
- // manually zeroed structures start here.
- struct s_autobonus autobonus[MAX_PC_BONUS], autobonus2[MAX_PC_BONUS], autobonus3[MAX_PC_BONUS]; //Auto script on attack, when attacked, on skill usage
- // manually zeroed structures end here.
- // zeroed vars start here.
- struct {
- int atk_rate;
- int arrow_atk,arrow_ele,arrow_cri,arrow_hit;
- int nsshealhp,nsshealsp;
- int critical_def,double_rate;
- int long_attack_atk_rate; //Long range atk rate, not weapon based. [Skotlex]
- int near_attack_def_rate,long_attack_def_rate,magic_def_rate,misc_def_rate;
- int ignore_mdef_ele;
- int ignore_mdef_race;
- int perfect_hit;
- int perfect_hit_add;
- int get_zeny_rate;
- int get_zeny_num; //Added Get Zeny Rate [Skotlex]
- int double_add_rate;
- int short_weapon_damage_return,long_weapon_damage_return;
- int magic_damage_return; // AppleGirl Was Here
- int break_weapon_rate,break_armor_rate;
- int crit_atk_rate;
- int classchange; // [Valaris]
- int speed_rate, speed_add_rate, aspd_add;
- int itemhealrate2; // [Epoque] Increase heal rate of all healing items.
- int shieldmdef;//royal guard's
- unsigned int setitem_hash, setitem_hash2; //Split in 2 because shift operations only work on int ranges. [Skotlex]
-
- short splash_range, splash_add_range;
- short add_steal_rate;
- short add_heal_rate, add_heal2_rate;
- short sp_gain_value, hp_gain_value, magic_sp_gain_value, magic_hp_gain_value;
- short sp_vanish_rate;
- short sp_vanish_per;
- unsigned short unbreakable; // chance to prevent ANY equipment breaking [celest]
- unsigned short unbreakable_equip; //100% break resistance on certain equipment
- unsigned short unstripable_equip;
- int fixcastrate,varcastrate;
- int ematk; // matk bonus from equipment
- } bonus;
-
- // zeroed vars end here.
-
- int castrate,delayrate,hprate,sprate,dsprate;
- int hprecov_rate,sprecov_rate;
- int matk_rate;
- int critical_rate,hit_rate,flee_rate,flee2_rate,def_rate,def2_rate,mdef_rate,mdef2_rate;
-
- int itemid;
- short itemindex; //Used item's index in sd->inventory [Skotlex]
-
- short catch_target_class; // pet catching, stores a pet class to catch (short now) [zzo]
-
- short spiritball, spiritball_old;
- int spirit_timer[MAX_SKILL_LEVEL];
- short talisman[ELE_POISON+1]; // There are actually 5 talisman Fire, Ice, Wind, Earth & Poison maybe because its color violet.
- int talisman_timer[ELE_POISON+1][10];
-
- unsigned char potion_success_counter; //Potion successes in row counter
- unsigned char mission_count; //Stores the bounty kill count for TK_MISSION
- short mission_mobid; //Stores the target mob_id for TK_MISSION
- int die_counter; //Total number of times you've died
- int devotion[5]; //Stores the account IDs of chars devoted to.
- int reg_num; //Number of registries (type numeric)
- int regstr_num; //Number of registries (type string)
-
- struct script_reg *reg;
- struct script_regstr *regstr;
-
- int trade_partner;
- struct {
- struct {
- short index, amount;
- } item[10];
- int zeny, weight;
- } deal;
-
- bool party_creating; // whether the char is requesting party creation
- bool party_joining; // whether the char is accepting party invitation
- int party_invite, party_invite_account; // for handling party invitation (holds party id and account id)
- int adopt_invite; // Adoption
-
- int guild_invite,guild_invite_account;
- int guild_emblem_id,guild_alliance,guild_alliance_account;
- short guild_x,guild_y; // For guildmate position display. [Skotlex] should be short [zzo]
- int guildspy; // [Syrus22]
- int partyspy; // [Syrus22]
-
- int vended_id;
- int vender_id;
- int vend_num;
- char message[MESSAGE_SIZE];
- struct s_vending vending[MAX_VENDING];
-
- unsigned int buyer_id; // uid of open buying store
- struct s_buyingstore buyingstore;
-
- struct s_search_store_info searchstore;
-
- struct pet_data *pd;
- struct homun_data *hd; // [blackhole89]
- struct mercenary_data *md;
- struct elemental_data *ed;
-
- struct {
- int m; //-1 - none, other: map index corresponding to map name.
- unsigned short index; //map index
- } feel_map[3]; // 0 - Sun; 1 - Moon; 2 - Stars
- short hate_mob[3];
-
- int pvp_timer;
- short pvp_point;
- unsigned short pvp_rank, pvp_lastusers;
- unsigned short pvp_won, pvp_lost;
-
- char eventqueue[MAX_EVENTQUEUE][EVENT_NAME_LENGTH];
- int eventtimer[MAX_EVENTTIMER];
- unsigned short eventcount; // [celest]
-
- unsigned char change_level_2nd; // job level when changing from 1st to 2nd class [jobchange_level in global_reg_value]
- unsigned char change_level_3rd; // job level when changing from 2nd to 3rd class [jobchange_level_3rd in global_reg_value]
-
- char fakename[NAME_LENGTH]; // fake names [Valaris]
-
- int duel_group; // duel vars [LuzZza]
- int duel_invite;
-
- int killerrid, killedrid;
-
- int cashPoints, kafraPoints;
- int rental_timer;
-
- // Auction System [Zephyrus]
- struct {
- int index, amount;
- } auction;
-
- // Mail System [Zephyrus]
- struct {
- short nameid;
- int index, amount, zeny;
- struct mail_data inbox;
- bool changed; // if true, should sync with charserver on next mailbox request
- } mail;
-
- //Quest log system [Kevin] [Inkfish]
- int num_quests;
- int avail_quests;
- int quest_index[MAX_QUEST_DB];
- struct quest quest_log[MAX_QUEST_DB];
- bool save_quest;
-
- // temporary debug [flaviojs]
- const char *debug_file;
- int debug_line;
- const char *debug_func;
-
- unsigned int bg_id;
- unsigned short user_font;
-
- /**
- * For the Secure NPC Timeout option (check config/Secure.h) [RR]
- **/
+ struct {
+ short nameid;
+ unsigned int tick;
+ } item_delay[MAX_ITEMDELAYS]; // [Paradox924X]
+
+ short weapontype1,weapontype2;
+ short disguise; // [Valaris]
+
+ struct weapon_data right_weapon, left_weapon;
+
+ // here start arrays to be globally zeroed at the beginning of status_calc_pc()
+ int param_bonus[6],param_equip[6]; //Stores card/equipment bonuses.
+ int subele[ELE_MAX];
+ int subrace[RC_MAX];
+ int subrace2[RC2_MAX];
+ int subsize[3];
+ int reseff[SC_COMMON_MAX-SC_COMMON_MIN+1];
+ int weapon_coma_ele[ELE_MAX];
+ int weapon_coma_race[RC_MAX];
+ int weapon_atk[16];
+ int weapon_atk_rate[16];
+ int arrow_addele[ELE_MAX];
+ int arrow_addrace[RC_MAX];
+ int arrow_addsize[3];
+ int magic_addele[ELE_MAX];
+ int magic_addrace[RC_MAX];
+ int magic_addsize[3];
+ int critaddrace[RC_MAX];
+ int expaddrace[RC_MAX];
+ int ignore_mdef[RC_MAX];
+ int ignore_def[RC_MAX];
+ int itemgrouphealrate[MAX_ITEMGROUP];
+ short sp_gain_race[RC_MAX];
+ short sp_gain_race_attack[RC_MAX];
+ short hp_gain_race_attack[RC_MAX];
+ // zeroed arrays end here.
+ // zeroed structures start here
+ struct s_autospell autospell[15], autospell2[15], autospell3[15];
+ struct s_addeffect addeff[MAX_PC_BONUS], addeff2[MAX_PC_BONUS];
+ struct s_addeffectonskill addeff3[MAX_PC_BONUS];
+
+ struct { //skillatk raises bonus dmg% of skills, skillheal increases heal%, skillblown increases bonus blewcount for some skills.
+ unsigned short id;
+ short val;
+ } skillatk[MAX_PC_BONUS], skillusesprate[MAX_PC_BONUS], skillusesp[MAX_PC_BONUS], skillheal[5], skillheal2[5], skillblown[MAX_PC_BONUS], skillcast[MAX_PC_BONUS], skillcooldown[MAX_PC_BONUS], skillfixcast[MAX_PC_BONUS], skillvarcast[MAX_PC_BONUS];
+ struct {
+ short value;
+ int rate;
+ int tick;
+ } hp_loss, sp_loss, hp_regen, sp_regen;
+ struct {
+ short class_, rate;
+ } add_def[MAX_PC_BONUS], add_mdef[MAX_PC_BONUS], add_mdmg[MAX_PC_BONUS];
+ struct s_add_drop add_drop[MAX_PC_BONUS];
+ struct {
+ int nameid;
+ int rate;
+ } itemhealrate[MAX_PC_BONUS];
+ struct {
+ short flag, rate;
+ unsigned char ele;
+ } subele2[MAX_PC_BONUS];
+ // zeroed structures end here
+ // manually zeroed structures start here.
+ struct s_autobonus autobonus[MAX_PC_BONUS], autobonus2[MAX_PC_BONUS], autobonus3[MAX_PC_BONUS]; //Auto script on attack, when attacked, on skill usage
+ // manually zeroed structures end here.
+ // zeroed vars start here.
+ struct {
+ int atk_rate;
+ int arrow_atk,arrow_ele,arrow_cri,arrow_hit;
+ int nsshealhp,nsshealsp;
+ int critical_def,double_rate;
+ int long_attack_atk_rate; //Long range atk rate, not weapon based. [Skotlex]
+ int near_attack_def_rate,long_attack_def_rate,magic_def_rate,misc_def_rate;
+ int ignore_mdef_ele;
+ int ignore_mdef_race;
+ int perfect_hit;
+ int perfect_hit_add;
+ int get_zeny_rate;
+ int get_zeny_num; //Added Get Zeny Rate [Skotlex]
+ int double_add_rate;
+ int short_weapon_damage_return,long_weapon_damage_return;
+ int magic_damage_return; // AppleGirl Was Here
+ int break_weapon_rate,break_armor_rate;
+ int crit_atk_rate;
+ int classchange; // [Valaris]
+ int speed_rate, speed_add_rate, aspd_add;
+ int itemhealrate2; // [Epoque] Increase heal rate of all healing items.
+ int shieldmdef;//royal guard's
+ unsigned int setitem_hash, setitem_hash2; //Split in 2 because shift operations only work on int ranges. [Skotlex]
+
+ short splash_range, splash_add_range;
+ short add_steal_rate;
+ short add_heal_rate, add_heal2_rate;
+ short sp_gain_value, hp_gain_value, magic_sp_gain_value, magic_hp_gain_value;
+ short sp_vanish_rate;
+ short sp_vanish_per;
+ short sp_weapon_matk,sp_base_matk;
+ unsigned short unbreakable; // chance to prevent ANY equipment breaking [celest]
+ unsigned short unbreakable_equip; //100% break resistance on certain equipment
+ unsigned short unstripable_equip;
+ int fixcastrate,varcastrate;
+ } bonus;
+
+ // zeroed vars end here.
+
+ int castrate,delayrate,hprate,sprate,dsprate;
+ int hprecov_rate,sprecov_rate;
+ int matk_rate;
+ int critical_rate,hit_rate,flee_rate,flee2_rate,def_rate,def2_rate,mdef_rate,mdef2_rate;
+
+ int itemid;
+ short itemindex; //Used item's index in sd->inventory [Skotlex]
+
+ short catch_target_class; // pet catching, stores a pet class to catch (short now) [zzo]
+
+ short spiritball, spiritball_old;
+ int spirit_timer[MAX_SKILL_LEVEL];
+ short talisman[ELE_POISON+1]; // There are actually 5 talisman Fire, Ice, Wind, Earth & Poison maybe because its color violet.
+ int talisman_timer[ELE_POISON+1][10];
+
+ unsigned char potion_success_counter; //Potion successes in row counter
+ unsigned char mission_count; //Stores the bounty kill count for TK_MISSION
+ short mission_mobid; //Stores the target mob_id for TK_MISSION
+ int die_counter; //Total number of times you've died
+ int devotion[5]; //Stores the account IDs of chars devoted to.
+ int reg_num; //Number of registries (type numeric)
+ int regstr_num; //Number of registries (type string)
+
+ struct script_reg *reg;
+ struct script_regstr *regstr;
+
+ int trade_partner;
+ struct {
+ struct {
+ short index, amount;
+ } item[10];
+ int zeny, weight;
+ } deal;
+
+ bool party_creating; // whether the char is requesting party creation
+ bool party_joining; // whether the char is accepting party invitation
+ int party_invite, party_invite_account; // for handling party invitation (holds party id and account id)
+ int adopt_invite; // Adoption
+
+ int guild_invite,guild_invite_account;
+ int guild_emblem_id,guild_alliance,guild_alliance_account;
+ short guild_x,guild_y; // For guildmate position display. [Skotlex] should be short [zzo]
+ int guildspy; // [Syrus22]
+ int partyspy; // [Syrus22]
+
+ int vended_id;
+ int vender_id;
+ int vend_num;
+ char message[MESSAGE_SIZE];
+ struct s_vending vending[MAX_VENDING];
+
+ unsigned int buyer_id; // uid of open buying store
+ struct s_buyingstore buyingstore;
+
+ struct s_search_store_info searchstore;
+
+ struct pet_data *pd;
+ struct homun_data *hd; // [blackhole89]
+ struct mercenary_data *md;
+ struct elemental_data *ed;
+
+ struct{
+ int m; //-1 - none, other: map index corresponding to map name.
+ unsigned short index; //map index
+ }feel_map[3];// 0 - Sun; 1 - Moon; 2 - Stars
+ short hate_mob[3];
+
+ int pvp_timer;
+ short pvp_point;
+ unsigned short pvp_rank, pvp_lastusers;
+ unsigned short pvp_won, pvp_lost;
+
+ char eventqueue[MAX_EVENTQUEUE][EVENT_NAME_LENGTH];
+ int eventtimer[MAX_EVENTTIMER];
+ unsigned short eventcount; // [celest]
+
+ unsigned char change_level_2nd; // job level when changing from 1st to 2nd class [jobchange_level in global_reg_value]
+ unsigned char change_level_3rd; // job level when changing from 2nd to 3rd class [jobchange_level_3rd in global_reg_value]
+
+ char fakename[NAME_LENGTH]; // fake names [Valaris]
+
+ int duel_group; // duel vars [LuzZza]
+ int duel_invite;
+
+ int killerrid, killedrid;
+
+ int cashPoints, kafraPoints;
+ int rental_timer;
+
+ // Auction System [Zephyrus]
+ struct {
+ int index, amount;
+ } auction;
+
+ // Mail System [Zephyrus]
+ struct {
+ short nameid;
+ int index, amount, zeny;
+ struct mail_data inbox;
+ bool changed; // if true, should sync with charserver on next mailbox request
+ } mail;
+
+ //Quest log system [Kevin] [Inkfish]
+ int num_quests;
+ int avail_quests;
+ int quest_index[MAX_QUEST_DB];
+ struct quest quest_log[MAX_QUEST_DB];
+ bool save_quest;
+
+ // temporary debug [flaviojs]
+ const char* debug_file;
+ int debug_line;
+ const char* debug_func;
+
+ unsigned int bg_id;
+ unsigned short user_font;
+
+ /**
+ * For the Secure NPC Timeout option (check config/Secure.h) [RR]
+ **/
#if SECURE_NPCTIMEOUT
- /**
- * ID of the timer
- * @info
- * - value is -1 (INVALID_TIMER constant) when not being used
- * - timer is cancelled upon closure of the current npc's instance
- **/
- int npc_idle_timer;
- /**
- * Tick on the last recorded NPC iteration (next/menu/whatever)
- * @info
- * - It is updated on every NPC iteration as mentioned above
- **/
- unsigned int npc_idle_tick;
+ /**
+ * ID of the timer
+ * @info
+ * - value is -1 (INVALID_TIMER constant) when not being used
+ * - timer is cancelled upon closure of the current npc's instance
+ **/
+ int npc_idle_timer;
+ /**
+ * Tick on the last recorded NPC iteration (next/menu/whatever)
+ * @info
+ * - It is updated on every NPC iteration as mentioned above
+ **/
+ unsigned int npc_idle_tick;
#endif
- struct {
- struct script_code **bonus;/* the script */
- unsigned short *id;/* array of combo ids */
- unsigned char count;
- } combos;
+ struct {
+ struct script_code **bonus;/* the script */
+ unsigned short *id;/* array of combo ids */
+ unsigned char count;
+ } combos;
- /**
- * Guarantees your friend request is legit (for bugreport:4629)
- **/
- int friend_req;
+ /**
+ * Guarantees your friend request is legit (for bugreport:4629)
+ **/
+ int friend_req;
- int shadowform_id;
+ int shadowform_id;
- // temporary debugging of bug #3504
- const char *delunit_prevfile;
- int delunit_prevline;
+ // temporary debugging of bug #3504
+ const char* delunit_prevfile;
+ int delunit_prevline;
};
@@ -485,68 +485,68 @@ struct map_session_data {
#define CLASS_COUNT (JOB_MAX - JOB_NOVICE_HIGH + JOB_MAX_BASIC)
enum weapon_type {
- W_FIST, //Bare hands
- W_DAGGER, //1
- W_1HSWORD, //2
- W_2HSWORD, //3
- W_1HSPEAR, //4
- W_2HSPEAR, //5
- W_1HAXE, //6
- W_2HAXE, //7
- W_MACE, //8
- W_2HMACE, //9 (unused)
- W_STAFF, //10
- W_BOW, //11
- W_KNUCKLE, //12
- W_MUSICAL, //13
- W_WHIP, //14
- W_BOOK, //15
- W_KATAR, //16
- W_REVOLVER, //17
- W_RIFLE, //18
- W_GATLING, //19
- W_SHOTGUN, //20
- W_GRENADE, //21
- W_HUUMA, //22
- W_2HSTAFF, //23
- MAX_WEAPON_TYPE,
- // dual-wield constants
- W_DOUBLE_DD, // 2 daggers
- W_DOUBLE_SS, // 2 swords
- W_DOUBLE_AA, // 2 axes
- W_DOUBLE_DS, // dagger + sword
- W_DOUBLE_DA, // dagger + axe
- W_DOUBLE_SA, // sword + axe
+ W_FIST, //Bare hands
+ W_DAGGER, //1
+ W_1HSWORD, //2
+ W_2HSWORD, //3
+ W_1HSPEAR, //4
+ W_2HSPEAR, //5
+ W_1HAXE, //6
+ W_2HAXE, //7
+ W_MACE, //8
+ W_2HMACE, //9 (unused)
+ W_STAFF, //10
+ W_BOW, //11
+ W_KNUCKLE, //12
+ W_MUSICAL, //13
+ W_WHIP, //14
+ W_BOOK, //15
+ W_KATAR, //16
+ W_REVOLVER, //17
+ W_RIFLE, //18
+ W_GATLING, //19
+ W_SHOTGUN, //20
+ W_GRENADE, //21
+ W_HUUMA, //22
+ W_2HSTAFF, //23
+ MAX_WEAPON_TYPE,
+ // dual-wield constants
+ W_DOUBLE_DD, // 2 daggers
+ W_DOUBLE_SS, // 2 swords
+ W_DOUBLE_AA, // 2 axes
+ W_DOUBLE_DS, // dagger + sword
+ W_DOUBLE_DA, // dagger + axe
+ W_DOUBLE_SA, // sword + axe
};
enum ammo_type {
- A_ARROW = 1,
- A_DAGGER, //2
- A_BULLET, //3
- A_SHELL, //4
- A_GRENADE, //5
- A_SHURIKEN, //6
- A_KUNAI, //7
- A_CANNONBALL, //8
- A_THROWWEAPON //9
+ A_ARROW = 1,
+ A_DAGGER, //2
+ A_BULLET, //3
+ A_SHELL, //4
+ A_GRENADE, //5
+ A_SHURIKEN, //6
+ A_KUNAI, //7
+ A_CANNONBALL, //8
+ A_THROWWEAPON //9
};
//Equip position constants
enum equip_pos {
- EQP_HEAD_LOW = 0x0001,
- EQP_HEAD_MID = 0x0200, //512
- EQP_HEAD_TOP = 0x0100, //256
- EQP_HAND_R = 0x0002,
- EQP_HAND_L = 0x0020, //32
- EQP_ARMOR = 0x0010, //16
- EQP_SHOES = 0x0040, //64
- EQP_GARMENT = 0x0004,
- EQP_ACC_L = 0x0008,
- EQP_ACC_R = 0x0080, //128
- EQP_COSTUME_HEAD_TOP = 0x0400,
- EQP_COSTUME_HEAD_MID = 0x0800,
- EQP_COSTUME_HEAD_LOW = 0x1000,
- EQP_AMMO = 0x8000, //32768
+ EQP_HEAD_LOW = 0x0001,
+ EQP_HEAD_MID = 0x0200, //512
+ EQP_HEAD_TOP = 0x0100, //256
+ EQP_HAND_R = 0x0002,
+ EQP_HAND_L = 0x0020, //32
+ EQP_ARMOR = 0x0010, //16
+ EQP_SHOES = 0x0040, //64
+ EQP_GARMENT = 0x0004,
+ EQP_ACC_L = 0x0008,
+ EQP_ACC_R = 0x0080, //128
+ EQP_COSTUME_HEAD_TOP = 0x0400,
+ EQP_COSTUME_HEAD_MID = 0x0800,
+ EQP_COSTUME_HEAD_LOW = 0x1000,
+ EQP_AMMO = 0x8000, //32768
};
#define EQP_WEAPON EQP_HAND_R
@@ -558,29 +558,29 @@ enum equip_pos {
/// Equip positions that use a visible sprite
#if PACKETVER < 20110111
-#define EQP_VISIBLE EQP_HELM
+ #define EQP_VISIBLE EQP_HELM
#else
-#define EQP_VISIBLE (EQP_HELM|EQP_GARMENT|EQP_COSTUME)
+ #define EQP_VISIBLE (EQP_HELM|EQP_GARMENT|EQP_COSTUME)
#endif
//Equip indexes constants. (eg: sd->equip_index[EQI_AMMO] returns the index
//where the arrows are equipped)
enum equip_index {
- EQI_ACC_L = 0,
- EQI_ACC_R,
- EQI_SHOES,
- EQI_GARMENT,
- EQI_HEAD_LOW,
- EQI_HEAD_MID,
- EQI_HEAD_TOP,
- EQI_ARMOR,
- EQI_HAND_L,
- EQI_HAND_R,
- EQI_COSTUME_TOP,
- EQI_COSTUME_MID,
- EQI_COSTUME_LOW,
- EQI_AMMO,
- EQI_MAX
+ EQI_ACC_L = 0,
+ EQI_ACC_R,
+ EQI_SHOES,
+ EQI_GARMENT,
+ EQI_HEAD_LOW,
+ EQI_HEAD_MID,
+ EQI_HEAD_TOP,
+ EQI_ARMOR,
+ EQI_HAND_L,
+ EQI_HAND_R,
+ EQI_COSTUME_TOP,
+ EQI_COSTUME_MID,
+ EQI_COSTUME_LOW,
+ EQI_AMMO,
+ EQI_MAX
};
#define pc_setdead(sd) ( (sd)->state.dead_sit = (sd)->vd.dead_sit = 1 )
@@ -597,9 +597,9 @@ enum equip_index {
#define pc_ischasewalk(sd) ( (sd)->sc.option&OPTION_CHASEWALK )
#ifdef NEW_CARTS
-#define pc_iscarton(sd) ( (sd)->sc.data[SC_PUSH_CART] )
+ #define pc_iscarton(sd) ( (sd)->sc.data[SC_PUSH_CART] )
#else
-#define pc_iscarton(sd) ( (sd)->sc.option&OPTION_CART )
+ #define pc_iscarton(sd) ( (sd)->sc.option&OPTION_CART )
#endif
#define pc_isfalcon(sd) ( (sd)->sc.option&OPTION_FALCON )
@@ -623,49 +623,35 @@ enum equip_index {
//Weapon check considering dual wielding.
#define pc_check_weapontype(sd, type) ((type)&((sd)->status.weapon < MAX_WEAPON_TYPE? \
- 1<<(sd)->status.weapon:(1<<(sd)->weapontype1)|(1<<(sd)->weapontype2)|(1<<(sd)->status.weapon)))
+ 1<<(sd)->status.weapon:(1<<(sd)->weapontype1)|(1<<(sd)->weapontype2)|(1<<(sd)->status.weapon)))
//Checks if the given class value corresponds to a player class. [Skotlex]
//JOB_NOVICE isn't checked for class_ is supposed to be unsigned
#define pcdb_checkid_sub(class_) \
- ( \
- ( (class_) < JOB_MAX_BASIC ) \
- || ( (class_) >= JOB_NOVICE_HIGH && (class_) <= JOB_DARK_COLLECTOR ) \
- || ( (class_) >= JOB_RUNE_KNIGHT && (class_) <= JOB_MECHANIC_T2 ) \
- || ( (class_) >= JOB_BABY_RUNE && (class_) <= JOB_BABY_MECHANIC2 ) \
- || ( (class_) >= JOB_SUPER_NOVICE_E && (class_) <= JOB_SUPER_BABY_E ) \
- || ( (class_) >= JOB_KAGEROU && (class_) < JOB_MAX ) \
- )
+( \
+ ( (class_) < JOB_MAX_BASIC ) \
+|| ( (class_) >= JOB_NOVICE_HIGH && (class_) <= JOB_DARK_COLLECTOR ) \
+|| ( (class_) >= JOB_RUNE_KNIGHT && (class_) <= JOB_MECHANIC_T2 ) \
+|| ( (class_) >= JOB_BABY_RUNE && (class_) <= JOB_BABY_MECHANIC2 ) \
+|| ( (class_) >= JOB_SUPER_NOVICE_E && (class_) <= JOB_SUPER_BABY_E ) \
+|| ( (class_) >= JOB_KAGEROU && (class_) < JOB_MAX ) \
+)
#define pcdb_checkid(class_) pcdb_checkid_sub((unsigned int)class_)
// clientside display macros (values to the left/right of the "+")
#ifdef RENEWAL
-#define pc_leftside_atk(sd) ((sd)->battle_status.batk)
-#define pc_rightside_atk(sd) ((sd)->battle_status.rhw.atk + (sd)->battle_status.lhw.atk + (sd)->battle_status.rhw.atk2 + (sd)->battle_status.lhw.atk2)
-#define pc_leftside_def(sd) ((sd)->battle_status.def2)
-#define pc_rightside_def(sd) ((sd)->battle_status.def)
-#define pc_leftside_mdef(sd) ((sd)->battle_status.mdef2)
-#define pc_rightside_mdef(sd) ((sd)->battle_status.mdef)
-#define pc_leftside_matk(sd) (status_base_matk(status_get_status_data(&(sd)->bl), (sd)->status.base_level))
-#define pc_rightside_matk(sd) ((sd)->battle_status.rhw.matk+(sd)->bonus.ematk)
+ #define pc_leftside_atk(sd) ((sd)->battle_status.batk)
+ #define pc_rightside_atk(sd) ((sd)->battle_status.rhw.atk + (sd)->battle_status.lhw.atk + (sd)->battle_status.rhw.atk2 + (sd)->battle_status.lhw.atk2)
+ #define pc_leftside_def(sd) ((sd)->battle_status.def2)
+ #define pc_rightside_def(sd) ((sd)->battle_status.def)
+ #define pc_leftside_mdef(sd) ((sd)->battle_status.mdef2)
+ #define pc_rightside_mdef(sd) ((sd)->battle_status.mdef)
#else
-#define pc_leftside_atk(sd) ((sd)->battle_status.batk + (sd)->battle_status.rhw.atk + (sd)->battle_status.lhw.atk)
-#define pc_rightside_atk(sd) ((sd)->battle_status.rhw.atk2 + (sd)->battle_status.lhw.atk2)
-#define pc_leftside_def(sd) ((sd)->battle_status.def)
-#define pc_rightside_def(sd) ((sd)->battle_status.def2)
-#define pc_leftside_mdef(sd) ((sd)->battle_status.mdef)
-#define pc_rightside_mdef(sd) ( (sd)->battle_status.mdef2 - ((sd)->battle_status.vit>>1) )
-#define pc_leftside_matk(sd) \
- (\
- ((sd)->sc.data[SC_MAGICPOWER] && (sd)->sc.data[SC_MAGICPOWER]->val4) \
- ?((sd)->battle_status.matk_min * 100 + 50) / ((sd)->sc.data[SC_MAGICPOWER]->val3+100) \
- :(sd)->battle_status.matk_min \
- )
-#define pc_rightside_matk(sd) \
- (\
- ((sd)->sc.data[SC_MAGICPOWER] && (sd)->sc.data[SC_MAGICPOWER]->val4) \
- ?((sd)->battle_status.matk_max * 100 + 50) / ((sd)->sc.data[SC_MAGICPOWER]->val3+100) \
- :(sd)->battle_status.matk_max \
- )
+ #define pc_leftside_atk(sd) ((sd)->battle_status.batk + (sd)->battle_status.rhw.atk + (sd)->battle_status.lhw.atk)
+ #define pc_rightside_atk(sd) ((sd)->battle_status.rhw.atk2 + (sd)->battle_status.lhw.atk2)
+ #define pc_leftside_def(sd) ((sd)->battle_status.def)
+ #define pc_rightside_def(sd) ((sd)->battle_status.def2)
+ #define pc_leftside_mdef(sd) ((sd)->battle_status.mdef)
+ #define pc_rightside_mdef(sd) ( (sd)->battle_status.mdef2 - ((sd)->battle_status.vit>>1) )
#endif
int pc_class2idx(int class_);
@@ -680,8 +666,8 @@ bool pc_should_log_commands(struct map_session_data *sd);
int pc_setrestartvalue(struct map_session_data *sd,int type);
int pc_makesavestatus(struct map_session_data *);
-void pc_respawn(struct map_session_data *sd, clr_type clrtype);
-int pc_setnewpc(struct map_session_data *,int,int,int,unsigned int,int,int);
+void pc_respawn(struct map_session_data* sd, clr_type clrtype);
+int pc_setnewpc(struct map_session_data*,int,int,int,unsigned int,int,int);
bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_time, int group_id, struct mmo_charstatus *st, bool changing_mapservers);
void pc_authfail(struct map_session_data *);
int pc_reg_received(struct map_session_data *sd);
@@ -701,18 +687,18 @@ int pc_clean_skilltree(struct map_session_data *sd);
#define pc_checkoverhp(sd) ((sd)->battle_status.hp == (sd)->battle_status.max_hp)
#define pc_checkoversp(sd) ((sd)->battle_status.sp == (sd)->battle_status.max_sp)
-int pc_setpos(struct map_session_data *sd, unsigned short mapindex, int x, int y, clr_type clrtype);
-int pc_setsavepoint(struct map_session_data *,short,int,int);
+int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y, clr_type clrtype);
+int pc_setsavepoint(struct map_session_data*,short,int,int);
int pc_randomwarp(struct map_session_data *sd,clr_type type);
-int pc_memo(struct map_session_data *sd, int pos);
+int pc_memo(struct map_session_data* sd, int pos);
-int pc_checkadditem(struct map_session_data *,int,int);
-int pc_inventoryblank(struct map_session_data *);
+int pc_checkadditem(struct map_session_data*,int,int);
+int pc_inventoryblank(struct map_session_data*);
int pc_search_inventory(struct map_session_data *sd,int item_id);
-int pc_payzeny(struct map_session_data *,int, enum e_log_pick_type type, struct map_session_data *);
-int pc_additem(struct map_session_data *,struct item *,int,e_log_pick_type);
-int pc_getzeny(struct map_session_data *,int, enum e_log_pick_type, struct map_session_data *);
-int pc_delitem(struct map_session_data *,int,int,int,short,e_log_pick_type);
+int pc_payzeny(struct map_session_data*,int, enum e_log_pick_type type, struct map_session_data*);
+int pc_additem(struct map_session_data*,struct item*,int,e_log_pick_type);
+int pc_getzeny(struct map_session_data*,int, enum e_log_pick_type, struct map_session_data*);
+int pc_delitem(struct map_session_data*,int,int,int,short,e_log_pick_type);
// Special Shop System
int pc_paycash(struct map_session_data *sd, int price, int points);
@@ -724,62 +710,62 @@ int pc_putitemtocart(struct map_session_data *sd,int idx,int amount);
int pc_getitemfromcart(struct map_session_data *sd,int idx,int amount);
int pc_cartitem_amount(struct map_session_data *sd,int idx,int amount);
-int pc_takeitem(struct map_session_data *,struct flooritem_data *);
-int pc_dropitem(struct map_session_data *,int,int);
+int pc_takeitem(struct map_session_data*,struct flooritem_data*);
+int pc_dropitem(struct map_session_data*,int,int);
bool pc_isequipped(struct map_session_data *sd, int nameid);
-bool pc_can_Adopt(struct map_session_data *p1_sd, struct map_session_data *p2_sd, struct map_session_data *b_sd);
+bool pc_can_Adopt(struct map_session_data *p1_sd, struct map_session_data *p2_sd, struct map_session_data *b_sd );
bool pc_adoption(struct map_session_data *p1_sd, struct map_session_data *p2_sd, struct map_session_data *b_sd);
int pc_updateweightstatus(struct map_session_data *sd);
int pc_addautobonus(struct s_autobonus *bonus,char max,const char *script,short rate,unsigned int dur,short atk_type,const char *o_script,unsigned short pos,bool onskill);
-int pc_exeautobonus(struct map_session_data *sd,struct s_autobonus *bonus);
+int pc_exeautobonus(struct map_session_data* sd,struct s_autobonus *bonus);
int pc_endautobonus(int tid, unsigned int tick, int id, intptr_t data);
-int pc_delautobonus(struct map_session_data *sd,struct s_autobonus *bonus,char max,bool restore);
+int pc_delautobonus(struct map_session_data* sd,struct s_autobonus *bonus,char max,bool restore);
-int pc_bonus(struct map_session_data *,int,int);
+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_bonus5(struct map_session_data *sd,int,int,int,int,int,int);
-int pc_skill(struct map_session_data *sd, int id, int level, int flag);
+int pc_skill(struct map_session_data* sd, int id, int level, int flag);
int pc_insert_card(struct map_session_data *sd,int idx_card,int idx_equip);
int pc_steal_item(struct map_session_data *sd,struct block_list *bl, int skilllv);
int pc_steal_coin(struct map_session_data *sd,struct block_list *bl);
-int pc_modifybuyvalue(struct map_session_data *,int);
-int pc_modifysellvalue(struct map_session_data *,int);
+int pc_modifybuyvalue(struct map_session_data*,int);
+int pc_modifysellvalue(struct map_session_data*,int);
-int pc_follow(struct map_session_data *, int); // [MouseJstr]
-int pc_stop_following(struct map_session_data *);
+int pc_follow(struct map_session_data*, int); // [MouseJstr]
+int pc_stop_following(struct map_session_data*);
unsigned int pc_maxbaselv(struct map_session_data *sd);
unsigned int pc_maxjoblv(struct map_session_data *sd);
int pc_checkbaselevelup(struct map_session_data *sd);
int pc_checkjoblevelup(struct map_session_data *sd);
-int pc_gainexp(struct map_session_data *,struct block_list *,unsigned int,unsigned int, bool);
+int pc_gainexp(struct map_session_data*,struct block_list*,unsigned int,unsigned int, bool);
unsigned int pc_nextbaseexp(struct map_session_data *);
unsigned int pc_thisbaseexp(struct map_session_data *);
unsigned int pc_nextjobexp(struct map_session_data *);
unsigned int pc_thisjobexp(struct map_session_data *);
int pc_gets_status_point(int);
int pc_need_status_point(struct map_session_data *,int,int);
-int pc_statusup(struct map_session_data *,int);
-int pc_statusup2(struct map_session_data *,int,int);
-int pc_skillup(struct map_session_data *,int);
-int pc_allskillup(struct map_session_data *);
-int pc_resetlvl(struct map_session_data *,int type);
-int pc_resetstate(struct map_session_data *);
-int pc_resetskill(struct map_session_data *, int);
-int pc_resetfeel(struct map_session_data *);
-int pc_resethate(struct map_session_data *);
-int pc_equipitem(struct map_session_data *,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);
+int pc_statusup(struct map_session_data*,int);
+int pc_statusup2(struct map_session_data*,int,int);
+int pc_skillup(struct map_session_data*,int);
+int pc_allskillup(struct map_session_data*);
+int pc_resetlvl(struct map_session_data*,int type);
+int pc_resetstate(struct map_session_data*);
+int pc_resetskill(struct map_session_data*, int);
+int pc_resetfeel(struct map_session_data*);
+int pc_resethate(struct map_session_data*);
+int pc_equipitem(struct map_session_data*,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);
int pc_skillatk_bonus(struct map_session_data *sd, int skill_num);
int pc_skillheal_bonus(struct map_session_data *sd, int skill_num);
@@ -793,17 +779,17 @@ int pc_itemheal(struct map_session_data *sd,int itemid, int hp,int sp);
int pc_percentheal(struct map_session_data *sd,int,int);
int pc_jobchange(struct map_session_data *,int, int);
int pc_setoption(struct map_session_data *,int);
-int pc_setcart(struct map_session_data *sd, int type);
-int pc_setfalcon(struct map_session_data *sd, int flag);
-int pc_setriding(struct map_session_data *sd, int flag);
-int pc_setmadogear(struct map_session_data *sd, int flag);
+int pc_setcart(struct map_session_data* sd, int type);
+int pc_setfalcon(struct map_session_data* sd, int flag);
+int pc_setriding(struct map_session_data* sd, int flag);
+int pc_setmadogear(struct map_session_data* sd, int flag);
int pc_changelook(struct map_session_data *,int,int);
int pc_equiplookall(struct map_session_data *sd);
-int pc_readparam(struct map_session_data *,int);
-int pc_setparam(struct map_session_data *,int,int);
-int pc_readreg(struct map_session_data *,int);
-int pc_setreg(struct map_session_data *,int,int);
+int pc_readparam(struct map_session_data*,int);
+int pc_setparam(struct map_session_data*,int,int);
+int pc_readreg(struct map_session_data*,int);
+int pc_setreg(struct map_session_data*,int,int);
char *pc_readregstr(struct map_session_data *sd,int reg);
int pc_setregstr(struct map_session_data *sd,int reg,const char *str);
@@ -819,10 +805,10 @@ int pc_setregstr(struct map_session_data *sd,int reg,const char *str);
#define pc_setaccountreg2(sd,reg,val) pc_setregistry(sd,reg,val,1)
#define pc_readaccountreg2str(sd,reg) pc_readregistry_str(sd,reg,1)
#define pc_setaccountreg2str(sd,reg,val) pc_setregistry_str(sd,reg,val,1)
-int pc_readregistry(struct map_session_data *,const char *,int);
-int pc_setregistry(struct map_session_data *,const char *,int,int);
-char *pc_readregistry_str(struct map_session_data *,const char *,int);
-int pc_setregistry_str(struct map_session_data *,const char *,const char *,int);
+int pc_readregistry(struct map_session_data*,const char*,int);
+int pc_setregistry(struct map_session_data*,const char*,int,int);
+char *pc_readregistry_str(struct map_session_data*,const char*,int);
+int pc_setregistry_str(struct map_session_data*,const char*,const char*,int);
int pc_addeventtimer(struct map_session_data *sd,int tick,const char *name);
int pc_deleventtimer(struct map_session_data *sd,const char *name);
@@ -840,40 +826,40 @@ 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);
-void pc_bleeding(struct map_session_data *sd, unsigned int diff_tick);
-void pc_regen(struct map_session_data *sd, unsigned int diff_tick);
+void pc_bleeding (struct map_session_data *sd, unsigned int diff_tick);
+void pc_regen (struct map_session_data *sd, unsigned int diff_tick);
void pc_setstand(struct map_session_data *sd);
int pc_candrop(struct map_session_data *sd,struct item *item);
-int pc_jobid2mapid(unsigned short b_class); // Skotlex
-int pc_mapid2jobid(unsigned short class_, int sex); // Skotlex
+int pc_jobid2mapid(unsigned short b_class); // Skotlex
+int pc_mapid2jobid(unsigned short class_, int sex); // Skotlex
-const char *job_name(int class_);
+const char * job_name(int class_);
struct skill_tree_entry {
- short id;
- unsigned char max;
- unsigned char joblv;
- struct {
- short id;
- unsigned char lv;
- } need[MAX_PC_SKILL_REQUIRE];
+ short id;
+ unsigned char max;
+ unsigned char joblv;
+ struct {
+ short id;
+ unsigned char lv;
+ } need[MAX_PC_SKILL_REQUIRE];
}; // Celest
extern struct skill_tree_entry skill_tree[CLASS_COUNT][MAX_SKILL_TREE];
struct sg_data {
- short anger_id;
- short bless_id;
- short comfort_id;
- char feel_var[NAME_LENGTH];
- char hate_var[NAME_LENGTH];
- int (*day_func)(void);
+ short anger_id;
+ short bless_id;
+ short comfort_id;
+ char feel_var[NAME_LENGTH];
+ char hate_var[NAME_LENGTH];
+ int (*day_func)(void);
};
extern const struct sg_data sg_info[MAX_PC_FEELHATE];
-void pc_setinvincibletimer(struct map_session_data *sd, int val);
-void pc_delinvincibletimer(struct map_session_data *sd);
+void pc_setinvincibletimer(struct map_session_data* sd, int val);
+void 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);
@@ -920,6 +906,6 @@ int pc_del_talisman(struct map_session_data *sd,int count,int type);
void pc_baselevelchanged(struct map_session_data *sd);
#if defined(RENEWAL_DROP) || defined(RENEWAL_EXP)
-int pc_level_penalty_mod(struct map_session_data *sd, struct mob_data *md, int type);
+int pc_level_penalty_mod(struct map_session_data *sd, struct mob_data * md, int type);
#endif
#endif /* _PC_H_ */
diff --git a/src/map/pc_groups.c b/src/map/pc_groups.c
index 76335532d..3111e2788 100644
--- a/src/map/pc_groups.c
+++ b/src/map/pc_groups.c
@@ -18,42 +18,42 @@ typedef struct GroupSettings GroupSettings;
// Cached config settings/pointers for quick lookup
struct GroupSettings {
- unsigned int id; // groups.[].id
- int level; // groups.[].level
- const char *name; // groups.[].name
- config_setting_t *commands; // groups.[].commands
- unsigned int e_permissions; // packed groups.[].permissions
- bool log_commands; // groups.[].log_commands
- /// Following are used only during config reading
- config_setting_t *permissions; // groups.[].permissions
- config_setting_t *inherit; // groups.[].inherit
- bool inheritance_done; // have all inheritance rules been evaluated?
- config_setting_t *root; // groups.[]
- int group_pos;/* pos on load */
+ unsigned int id; // groups.[].id
+ int level; // groups.[].level
+ const char *name; // groups.[].name
+ config_setting_t *commands; // groups.[].commands
+ unsigned int e_permissions; // packed groups.[].permissions
+ bool log_commands; // groups.[].log_commands
+ /// Following are used only during config reading
+ config_setting_t *permissions; // groups.[].permissions
+ config_setting_t *inherit; // groups.[].inherit
+ bool inheritance_done; // have all inheritance rules been evaluated?
+ config_setting_t *root; // groups.[]
+ int group_pos;/* pos on load */
};
int pc_group_max; /* known number of groups */
static config_t pc_group_config;
-static DBMap *pc_group_db; // id -> GroupSettings
-static DBMap *pc_groupname_db; // name -> GroupSettings
+static DBMap* pc_group_db; // id -> GroupSettings
+static DBMap* pc_groupname_db; // name -> GroupSettings
/**
* @retval NULL if not found
* @private
*/
-static inline GroupSettings *id2group(int group_id)
+static inline GroupSettings* id2group(int group_id)
{
- return (GroupSettings *)idb_get(pc_group_db, group_id);
+ return (GroupSettings*)idb_get(pc_group_db, group_id);
}
/**
* @retval NULL if not found
* @private
*/
-static inline GroupSettings *name2group(const char *group_name)
+static inline GroupSettings* name2group(const char* group_name)
{
- return (GroupSettings *)strdb_get(pc_groupname_db, group_name);
+ return (GroupSettings*)strdb_get(pc_groupname_db, group_name);
}
/**
@@ -62,234 +62,234 @@ static inline GroupSettings *name2group(const char *group_name)
*/
static void read_config(void)
{
- config_setting_t *groups = NULL;
- const char *config_filename = "conf/groups.conf"; // FIXME hardcoded name
- int group_count = 0;
-
- if (conf_read_file(&pc_group_config, config_filename))
- return;
-
- groups = config_lookup(&pc_group_config, "groups");
-
- if (groups != NULL) {
- GroupSettings *group_settings = NULL;
- DBIterator *iter = NULL;
- int i, loop = 0;
-
- group_count = config_setting_length(groups);
- for (i = 0; i < group_count; ++i) {
- int id = 0, level = 0;
- const char *groupname = NULL;
- int log_commands = 0;
- config_setting_t *group = config_setting_get_elem(groups, i);
-
- if (!config_setting_lookup_int(group, "id", &id)) {
- ShowConfigWarning(group, "pc_groups:read_config: \"groups\" list member #%d has undefined id, removing...", i);
- config_setting_remove_elem(groups, i);
- --i;
- --group_count;
- continue;
- }
-
- if (id2group(id) != NULL) {
- ShowConfigWarning(group, "pc_groups:read_config: duplicate group id %d, removing...", i);
- config_setting_remove_elem(groups, i);
- --i;
- --group_count;
- continue;
- }
-
- config_setting_lookup_int(group, "level", &level);
- config_setting_lookup_bool(group, "log_commands", &log_commands);
-
- if (!config_setting_lookup_string(group, "name", &groupname)) {
- char temp[20];
- config_setting_t *name = NULL;
- snprintf(temp, sizeof(temp), "Group %d", id);
- if ((name = config_setting_add(group, "name", CONFIG_TYPE_STRING)) == NULL ||
- !config_setting_set_string(name, temp)) {
- ShowError("pc_groups:read_config: failed to set missing group name, id=%d, skipping... (%s:%d)\n",
- id, config_setting_source_file(group), config_setting_source_line(group));
- continue;
- }
- config_setting_lookup_string(group, "name", &groupname); // Retrieve the pointer
- }
-
- if (name2group(groupname) != NULL) {
- ShowConfigWarning(group, "pc_groups:read_config: duplicate group name %s, removing...", groupname);
- config_setting_remove_elem(groups, i);
- --i;
- --group_count;
- continue;
- }
-
- CREATE(group_settings, GroupSettings, 1);
- group_settings->id = id;
- group_settings->level = level;
- group_settings->name = groupname;
- group_settings->log_commands = (bool)log_commands;
- group_settings->inherit = config_setting_get_member(group, "inherit");
- group_settings->commands = config_setting_get_member(group, "commands");
- group_settings->permissions = config_setting_get_member(group, "permissions");
- group_settings->inheritance_done = false;
- group_settings->root = group;
- group_settings->group_pos = i;
-
- strdb_put(pc_groupname_db, groupname, group_settings);
- idb_put(pc_group_db, id, group_settings);
-
- }
- group_count = config_setting_length(groups); // Save number of groups
-
- // Check if all commands and permissions exist
- iter = db_iterator(pc_group_db);
- for (group_settings = dbi_first(iter); dbi_exists(iter); group_settings = dbi_next(iter)) {
- config_setting_t *commands = group_settings->commands, *permissions = group_settings->permissions;
- int count = 0, i;
-
- // Make sure there is "commands" group
- if (commands == NULL)
- commands = group_settings->commands = config_setting_add(group_settings->root, "commands", CONFIG_TYPE_GROUP);
- count = config_setting_length(commands);
-
- for (i = 0; i < count; ++i) {
- config_setting_t *command = config_setting_get_elem(commands, i);
- const char *name = config_setting_name(command);
- if (!atcommand_exists(name)) {
- ShowConfigWarning(command, "pc_groups:read_config: non-existent command name '%s', removing...", name);
- config_setting_remove(commands, name);
- --i;
- --count;
- }
- }
-
- // Make sure there is "permissions" group
- if (permissions == NULL)
- permissions = group_settings->permissions = config_setting_add(group_settings->root, "permissions", CONFIG_TYPE_GROUP);
- count = config_setting_length(permissions);
-
- for (i = 0; i < count; ++i) {
- config_setting_t *permission = config_setting_get_elem(permissions, i);
- const char *name = config_setting_name(permission);
- int j;
-
- ARR_FIND(0, ARRAYLENGTH(pc_g_permission_name), j, strcmp(pc_g_permission_name[j].name, name) == 0);
- if (j == ARRAYLENGTH(pc_g_permission_name)) {
- ShowConfigWarning(permission, "pc_groups:read_config: non-existent permission name '%s', removing...", name);
- config_setting_remove(permissions, name);
- --i;
- --count;
- }
- }
- }
- dbi_destroy(iter);
-
- // Apply inheritance
- i = 0; // counter for processed groups
- while (i < group_count) {
- iter = db_iterator(pc_group_db);
- for (group_settings = dbi_first(iter); dbi_exists(iter); group_settings = dbi_next(iter)) {
- config_setting_t *inherit = NULL,
- *commands = group_settings->commands,
- *permissions = group_settings->permissions;
- int j, inherit_count = 0, done = 0;
-
- if (group_settings->inheritance_done) // group already processed
- continue;
-
- if ((inherit = group_settings->inherit) == NULL ||
- (inherit_count = config_setting_length(inherit)) <= 0) { // this group does not inherit from others
- ++i;
- group_settings->inheritance_done = true;
- continue;
- }
-
- for (j = 0; j < inherit_count; ++j) {
- GroupSettings *inherited_group = NULL;
- const char *groupname = config_setting_get_string_elem(inherit, j);
-
- if (groupname == NULL) {
- ShowConfigWarning(inherit, "pc_groups:read_config: \"inherit\" array member #%d is not a name, removing...", j);
- config_setting_remove_elem(inherit,j);
- continue;
- }
- if ((inherited_group = name2group(groupname)) == NULL) {
- ShowConfigWarning(inherit, "pc_groups:read_config: non-existent group name \"%s\", removing...", groupname);
- config_setting_remove_elem(inherit,j);
- continue;
- }
- if (!inherited_group->inheritance_done)
- continue; // we need to do that group first
-
- // Copy settings (commands/permissions) that are not defined yet
- if (inherited_group->commands != NULL) {
- int i = 0, commands_count = config_setting_length(inherited_group->commands);
- for (i = 0; i < commands_count; ++i)
- config_setting_copy(commands, config_setting_get_elem(inherited_group->commands, i));
- }
-
- if (inherited_group->permissions != NULL) {
- int i = 0, permissions_count = config_setting_length(inherited_group->permissions);
- for (i = 0; i < permissions_count; ++i)
- config_setting_copy(permissions, config_setting_get_elem(inherited_group->permissions, i));
- }
-
- ++done; // copied commands and permissions from one of inherited groups
- }
-
- if (done == inherit_count) { // copied commands from all of inherited groups
- ++i;
- group_settings->inheritance_done = true; // we're done with this group
- }
- }
- dbi_destroy(iter);
-
- if (++loop > group_count) {
- ShowWarning("pc_groups:read_config: Could not process inheritance rules, check your config '%s' for cycles...\n",
- config_filename);
- break;
- }
- } // while(i < group_count)
-
- // Pack permissions into GroupSettings.e_permissions for faster checking
- iter = db_iterator(pc_group_db);
- for (group_settings = dbi_first(iter); dbi_exists(iter); group_settings = dbi_next(iter)) {
- config_setting_t *permissions = group_settings->permissions;
- int i, count = config_setting_length(permissions);
-
- for (i = 0; i < count; ++i) {
- config_setting_t *perm = config_setting_get_elem(permissions, i);
- const char *name = config_setting_name(perm);
- int val = config_setting_get_bool(perm);
- int j;
-
- if (val == 0) // does not have this permission
- continue;
- ARR_FIND(0, ARRAYLENGTH(pc_g_permission_name), j, strcmp(pc_g_permission_name[j].name, name) == 0);
- group_settings->e_permissions |= pc_g_permission_name[j].permission;
- }
- }
- dbi_destroy(iter);
- }
-
- ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' groups in '"CL_WHITE"%s"CL_RESET"'.\n", group_count, config_filename);
-
-
- if ((pc_group_max = group_count)) {
- DBIterator *iter = db_iterator(pc_group_db);
- GroupSettings *group_settings = NULL;
- int *group_ids = aMalloc(pc_group_max * sizeof(int));
- int i = 0;
- for (group_settings = dbi_first(iter); dbi_exists(iter); group_settings = dbi_next(iter)) {
- group_ids[i++] = group_settings->id;
- }
-
- atcommand_db_load_groups(group_ids);
-
- aFree(group_ids);
-
- dbi_destroy(iter);
- }
+ config_setting_t *groups = NULL;
+ const char *config_filename = "conf/groups.conf"; // FIXME hardcoded name
+ int group_count = 0;
+
+ if (conf_read_file(&pc_group_config, config_filename))
+ return;
+
+ groups = config_lookup(&pc_group_config, "groups");
+
+ if (groups != NULL) {
+ GroupSettings *group_settings = NULL;
+ DBIterator *iter = NULL;
+ int i, loop = 0;
+
+ group_count = config_setting_length(groups);
+ for (i = 0; i < group_count; ++i) {
+ int id = 0, level = 0;
+ const char *groupname = NULL;
+ int log_commands = 0;
+ config_setting_t *group = config_setting_get_elem(groups, i);
+
+ if (!config_setting_lookup_int(group, "id", &id)) {
+ ShowConfigWarning(group, "pc_groups:read_config: \"groups\" list member #%d has undefined id, removing...", i);
+ config_setting_remove_elem(groups, i);
+ --i;
+ --group_count;
+ continue;
+ }
+
+ if (id2group(id) != NULL) {
+ ShowConfigWarning(group, "pc_groups:read_config: duplicate group id %d, removing...", i);
+ config_setting_remove_elem(groups, i);
+ --i;
+ --group_count;
+ continue;
+ }
+
+ config_setting_lookup_int(group, "level", &level);
+ config_setting_lookup_bool(group, "log_commands", &log_commands);
+
+ if (!config_setting_lookup_string(group, "name", &groupname)) {
+ char temp[20];
+ config_setting_t *name = NULL;
+ snprintf(temp, sizeof(temp), "Group %d", id);
+ if ((name = config_setting_add(group, "name", CONFIG_TYPE_STRING)) == NULL ||
+ !config_setting_set_string(name, temp)) {
+ ShowError("pc_groups:read_config: failed to set missing group name, id=%d, skipping... (%s:%d)\n",
+ id, config_setting_source_file(group), config_setting_source_line(group));
+ continue;
+ }
+ config_setting_lookup_string(group, "name", &groupname); // Retrieve the pointer
+ }
+
+ if (name2group(groupname) != NULL) {
+ ShowConfigWarning(group, "pc_groups:read_config: duplicate group name %s, removing...", groupname);
+ config_setting_remove_elem(groups, i);
+ --i;
+ --group_count;
+ continue;
+ }
+
+ CREATE(group_settings, GroupSettings, 1);
+ group_settings->id = id;
+ group_settings->level = level;
+ group_settings->name = groupname;
+ group_settings->log_commands = (bool)log_commands;
+ group_settings->inherit = config_setting_get_member(group, "inherit");
+ group_settings->commands = config_setting_get_member(group, "commands");
+ group_settings->permissions = config_setting_get_member(group, "permissions");
+ group_settings->inheritance_done = false;
+ group_settings->root = group;
+ group_settings->group_pos = i;
+
+ strdb_put(pc_groupname_db, groupname, group_settings);
+ idb_put(pc_group_db, id, group_settings);
+
+ }
+ group_count = config_setting_length(groups); // Save number of groups
+
+ // Check if all commands and permissions exist
+ iter = db_iterator(pc_group_db);
+ for (group_settings = dbi_first(iter); dbi_exists(iter); group_settings = dbi_next(iter)) {
+ config_setting_t *commands = group_settings->commands, *permissions = group_settings->permissions;
+ int count = 0, i;
+
+ // Make sure there is "commands" group
+ if (commands == NULL)
+ commands = group_settings->commands = config_setting_add(group_settings->root, "commands", CONFIG_TYPE_GROUP);
+ count = config_setting_length(commands);
+
+ for (i = 0; i < count; ++i) {
+ config_setting_t *command = config_setting_get_elem(commands, i);
+ const char *name = config_setting_name(command);
+ if (!atcommand_exists(name)) {
+ ShowConfigWarning(command, "pc_groups:read_config: non-existent command name '%s', removing...", name);
+ config_setting_remove(commands, name);
+ --i;
+ --count;
+ }
+ }
+
+ // Make sure there is "permissions" group
+ if (permissions == NULL)
+ permissions = group_settings->permissions = config_setting_add(group_settings->root, "permissions", CONFIG_TYPE_GROUP);
+ count = config_setting_length(permissions);
+
+ for(i = 0; i < count; ++i) {
+ config_setting_t *permission = config_setting_get_elem(permissions, i);
+ const char *name = config_setting_name(permission);
+ int j;
+
+ ARR_FIND(0, ARRAYLENGTH(pc_g_permission_name), j, strcmp(pc_g_permission_name[j].name, name) == 0);
+ if (j == ARRAYLENGTH(pc_g_permission_name)) {
+ ShowConfigWarning(permission, "pc_groups:read_config: non-existent permission name '%s', removing...", name);
+ config_setting_remove(permissions, name);
+ --i;
+ --count;
+ }
+ }
+ }
+ dbi_destroy(iter);
+
+ // Apply inheritance
+ i = 0; // counter for processed groups
+ while (i < group_count) {
+ iter = db_iterator(pc_group_db);
+ for (group_settings = dbi_first(iter); dbi_exists(iter); group_settings = dbi_next(iter)) {
+ config_setting_t *inherit = NULL,
+ *commands = group_settings->commands,
+ *permissions = group_settings->permissions;
+ int j, inherit_count = 0, done = 0;
+
+ if (group_settings->inheritance_done) // group already processed
+ continue;
+
+ if ((inherit = group_settings->inherit) == NULL ||
+ (inherit_count = config_setting_length(inherit)) <= 0) { // this group does not inherit from others
+ ++i;
+ group_settings->inheritance_done = true;
+ continue;
+ }
+
+ for (j = 0; j < inherit_count; ++j) {
+ GroupSettings *inherited_group = NULL;
+ const char *groupname = config_setting_get_string_elem(inherit, j);
+
+ if (groupname == NULL) {
+ ShowConfigWarning(inherit, "pc_groups:read_config: \"inherit\" array member #%d is not a name, removing...", j);
+ config_setting_remove_elem(inherit,j);
+ continue;
+ }
+ if ((inherited_group = name2group(groupname)) == NULL) {
+ ShowConfigWarning(inherit, "pc_groups:read_config: non-existent group name \"%s\", removing...", groupname);
+ config_setting_remove_elem(inherit,j);
+ continue;
+ }
+ if (!inherited_group->inheritance_done)
+ continue; // we need to do that group first
+
+ // Copy settings (commands/permissions) that are not defined yet
+ if (inherited_group->commands != NULL) {
+ int i = 0, commands_count = config_setting_length(inherited_group->commands);
+ for (i = 0; i < commands_count; ++i)
+ config_setting_copy(commands, config_setting_get_elem(inherited_group->commands, i));
+ }
+
+ if (inherited_group->permissions != NULL) {
+ int i = 0, permissions_count = config_setting_length(inherited_group->permissions);
+ for (i = 0; i < permissions_count; ++i)
+ config_setting_copy(permissions, config_setting_get_elem(inherited_group->permissions, i));
+ }
+
+ ++done; // copied commands and permissions from one of inherited groups
+ }
+
+ if (done == inherit_count) { // copied commands from all of inherited groups
+ ++i;
+ group_settings->inheritance_done = true; // we're done with this group
+ }
+ }
+ dbi_destroy(iter);
+
+ if (++loop > group_count) {
+ ShowWarning("pc_groups:read_config: Could not process inheritance rules, check your config '%s' for cycles...\n",
+ config_filename);
+ break;
+ }
+ } // while(i < group_count)
+
+ // Pack permissions into GroupSettings.e_permissions for faster checking
+ iter = db_iterator(pc_group_db);
+ for (group_settings = dbi_first(iter); dbi_exists(iter); group_settings = dbi_next(iter)) {
+ config_setting_t *permissions = group_settings->permissions;
+ int i, count = config_setting_length(permissions);
+
+ for (i = 0; i < count; ++i) {
+ config_setting_t *perm = config_setting_get_elem(permissions, i);
+ const char *name = config_setting_name(perm);
+ int val = config_setting_get_bool(perm);
+ int j;
+
+ if (val == 0) // does not have this permission
+ continue;
+ ARR_FIND(0, ARRAYLENGTH(pc_g_permission_name), j, strcmp(pc_g_permission_name[j].name, name) == 0);
+ group_settings->e_permissions |= pc_g_permission_name[j].permission;
+ }
+ }
+ dbi_destroy(iter);
+ }
+
+ ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' groups in '"CL_WHITE"%s"CL_RESET"'.\n", group_count, config_filename);
+
+
+ if( ( pc_group_max = group_count ) ) {
+ DBIterator *iter = db_iterator(pc_group_db);
+ GroupSettings *group_settings = NULL;
+ int* group_ids = aMalloc( pc_group_max * sizeof(int) );
+ int i = 0;
+ for (group_settings = dbi_first(iter); dbi_exists(iter); group_settings = dbi_next(iter)) {
+ group_ids[i++] = group_settings->id;
+ }
+
+ atcommand_db_load_groups(group_ids);
+
+ aFree(group_ids);
+
+ dbi_destroy(iter);
+ }
}
/**
@@ -298,7 +298,7 @@ static void read_config(void)
*/
static void destroy_config(void)
{
- config_destroy(&pc_group_config);
+ config_destroy(&pc_group_config);
}
/**
@@ -309,10 +309,7 @@ static void destroy_config(void)
* COMMAND_ATCOMMAND (1) being index 0, COMMAND_CHARCOMMAND (2) being index 1.
* @private
*/
-static inline int AtCommandType2idx(AtCommandType type)
-{
- return (type-1);
-}
+static inline int AtCommandType2idx(AtCommandType type) { return (type-1); }
/**
* Checks if player group can use @/#command
@@ -322,45 +319,44 @@ static inline int AtCommandType2idx(AtCommandType type)
*/
bool pc_group_can_use_command(int group_id, const char *command, AtCommandType type)
{
- int result = 0;
- config_setting_t *commands = NULL;
- GroupSettings *group = NULL;
-
- if (pc_group_has_permission(group_id, PC_PERM_USE_ALL_COMMANDS))
- return true;
-
- if ((group = id2group(group_id)) == NULL)
- return false;
-
- commands = group->commands;
- if (commands != NULL) {
- config_setting_t *cmd = NULL;
-
- // <commandname> : <bool> (only atcommand)
- if (type == COMMAND_ATCOMMAND && config_setting_lookup_bool(commands, command, &result))
- return (bool)result;
-
- // <commandname> : [ <bool>, <bool> ] ([ atcommand, charcommand ])
- if ((cmd = config_setting_get_member(commands, command)) != NULL &&
- config_setting_is_aggregate(cmd) && config_setting_length(cmd) == 2)
- return (bool)config_setting_get_bool_elem(cmd, AtCommandType2idx(type));
- }
- return false;
+ int result = 0;
+ config_setting_t *commands = NULL;
+ GroupSettings *group = NULL;
+
+ if (pc_group_has_permission(group_id, PC_PERM_USE_ALL_COMMANDS))
+ return true;
+
+ if ((group = id2group(group_id)) == NULL)
+ return false;
+
+ commands = group->commands;
+ if (commands != NULL) {
+ config_setting_t *cmd = NULL;
+
+ // <commandname> : <bool> (only atcommand)
+ if (type == COMMAND_ATCOMMAND && config_setting_lookup_bool(commands, command, &result))
+ return (bool)result;
+
+ // <commandname> : [ <bool>, <bool> ] ([ atcommand, charcommand ])
+ if ((cmd = config_setting_get_member(commands, command)) != NULL &&
+ config_setting_is_aggregate(cmd) && config_setting_length(cmd) == 2)
+ return (bool)config_setting_get_bool_elem(cmd, AtCommandType2idx(type));
+ }
+ return false;
}
-void pc_group_pc_load(struct map_session_data *sd)
-{
- GroupSettings *group = NULL;
- if ((group = id2group(sd->group_id)) == NULL) {
- ShowWarning("pc_group_pc_load: %s (AID:%d) logged in with unknown group id (%d)! kicking...\n",
- sd->status.name,
- sd->status.account_id,
- sd->group_id);
- set_eof(sd->fd);
- return;
- }
- sd->permissions = group->e_permissions;
- sd->group_pos = group->group_pos;
- sd->group_level = group->level;
+void pc_group_pc_load(struct map_session_data * sd) {
+ GroupSettings *group = NULL;
+ if ((group = id2group(sd->group_id)) == NULL) {
+ ShowWarning("pc_group_pc_load: %s (AID:%d) logged in with unknown group id (%d)! kicking...\n",
+ sd->status.name,
+ sd->status.account_id,
+ sd->group_id);
+ set_eof(sd->fd);
+ return;
+ }
+ sd->permissions = group->e_permissions;
+ sd->group_pos = group->group_pos;
+ sd->group_level = group->level;
}
/**
* Checks if player group has a permission
@@ -369,10 +365,10 @@ void pc_group_pc_load(struct map_session_data *sd)
*/
bool pc_group_has_permission(int group_id, int permission)
{
- GroupSettings *group = NULL;
- if ((group = id2group(group_id)) == NULL)
- return false;
- return ((group->e_permissions&permission) != 0);
+ GroupSettings *group = NULL;
+ if ((group = id2group(group_id)) == NULL)
+ return false;
+ return ((group->e_permissions&permission) != 0);
}
/**
@@ -381,10 +377,10 @@ bool pc_group_has_permission(int group_id, int permission)
*/
bool pc_group_should_log_commands(int group_id)
{
- GroupSettings *group = NULL;
- if ((group = id2group(group_id)) == NULL)
- return false;
- return group->log_commands;
+ GroupSettings *group = NULL;
+ if ((group = id2group(group_id)) == NULL)
+ return false;
+ return group->log_commands;
}
/**
@@ -394,7 +390,7 @@ bool pc_group_should_log_commands(int group_id)
*/
bool pc_group_exists(int group_id)
{
- return idb_exists(pc_group_db, group_id);
+ return idb_exists(pc_group_db, group_id);
}
/**
@@ -403,12 +399,12 @@ bool pc_group_exists(int group_id)
* @return group name
* @public
*/
-const char *pc_group_id2name(int group_id)
+const char* pc_group_id2name(int group_id)
{
- GroupSettings *group = id2group(group_id);
- if (group == NULL)
- return "Non-existent group!";
- return group->name;
+ GroupSettings *group = id2group(group_id);
+ if (group == NULL)
+ return "Non-existent group!";
+ return group->name;
}
/**
@@ -419,10 +415,10 @@ const char *pc_group_id2name(int group_id)
*/
int pc_group_id2level(int group_id)
{
- GroupSettings *group = id2group(group_id);
- if (group == NULL)
- return 0;
- return group->level;
+ GroupSettings *group = id2group(group_id);
+ if (group == NULL)
+ return 0;
+ return group->level;
}
/**
@@ -431,9 +427,9 @@ int pc_group_id2level(int group_id)
*/
void do_init_pc_groups(void)
{
- pc_group_db = idb_alloc(DB_OPT_RELEASE_DATA);
- pc_groupname_db = stridb_alloc(DB_OPT_DUP_KEY, 0);
- read_config();
+ pc_group_db = idb_alloc(DB_OPT_RELEASE_DATA);
+ pc_groupname_db = stridb_alloc(DB_OPT_DUP_KEY, 0);
+ read_config();
}
/**
@@ -442,11 +438,11 @@ void do_init_pc_groups(void)
*/
void do_final_pc_groups(void)
{
- if (pc_group_db != NULL)
- db_destroy(pc_group_db);
- if (pc_groupname_db != NULL)
- db_destroy(pc_groupname_db);
- destroy_config();
+ if (pc_group_db != NULL)
+ db_destroy(pc_group_db);
+ if (pc_groupname_db != NULL )
+ db_destroy(pc_groupname_db);
+ destroy_config();
}
/**
@@ -454,20 +450,19 @@ void do_final_pc_groups(void)
* Used in @reloadatcommand
* @public
*/
-void pc_groups_reload(void)
-{
- struct map_session_data *sd = NULL;
- struct s_mapiterator *iter = NULL;
-
- do_final_pc_groups();
- do_init_pc_groups();
-
- /* refresh online users permissions */
- iter = mapit_getallusers();
- for (sd = (TBL_PC *)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC *)mapit_next(iter)) {
- pc_group_pc_load(sd);
- }
- mapit_free(iter);
-
-
+void pc_groups_reload(void) {
+ struct map_session_data* sd = NULL;
+ struct s_mapiterator* iter = NULL;
+
+ do_final_pc_groups();
+ do_init_pc_groups();
+
+ /* refresh online users permissions */
+ iter = mapit_getallusers();
+ for (sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter)) {
+ pc_group_pc_load(sd);
+ }
+ mapit_free(iter);
+
+
}
diff --git a/src/map/pc_groups.h b/src/map/pc_groups.h
index 6bce4fbf8..65c48935a 100644
--- a/src/map/pc_groups.h
+++ b/src/map/pc_groups.h
@@ -12,7 +12,7 @@ bool pc_group_exists(int group_id);
bool pc_group_can_use_command(int group_id, const char *command, AtCommandType type);
bool pc_group_has_permission(int group_id, int permission);
bool pc_group_should_log_commands(int group_id);
-const char *pc_group_id2name(int group_id);
+const char* pc_group_id2name(int group_id);
int pc_group_id2level(int group_id);
void pc_group_pc_load(struct map_session_data *);
@@ -21,55 +21,55 @@ void do_final_pc_groups(void);
void pc_groups_reload(void);
enum e_pc_permission {
- PC_PERM_NONE = 0,
- PC_PERM_TRADE = 0x000001,
- PC_PERM_PARTY = 0x000002,
- PC_PERM_ALL_SKILL = 0x000004,
- PC_PERM_USE_ALL_EQUIPMENT = 0x000008,
- PC_PERM_SKILL_UNCONDITIONAL = 0x000010,
- PC_PERM_JOIN_ALL_CHAT = 0x000020,
- PC_PERM_NO_CHAT_KICK = 0x000040,
- PC_PERM_HIDE_SESSION = 0x000080,
- PC_PERM_WHO_DISPLAY_AID = 0x000100,
- PC_PERM_RECEIVE_HACK_INFO = 0x000200,
- PC_PERM_WARP_ANYWHERE = 0x000400,
- PC_PERM_VIEW_HPMETER = 0x000800,
- PC_PERM_VIEW_EQUIPMENT = 0x001000,
- PC_PERM_USE_CHECK = 0x002000,
- PC_PERM_USE_CHANGEMAPTYPE = 0x004000,
- PC_PERM_USE_ALL_COMMANDS = 0x008000,
- PC_PERM_RECEIVE_REQUESTS = 0x010000,
- PC_PERM_SHOW_BOSS = 0x020000,
- PC_PERM_DISABLE_PVM = 0x040000,
- PC_PERM_DISABLE_PVP = 0x080000,
- PC_PERM_DISABLE_CMD_DEAD = 0x100000,
+ PC_PERM_NONE = 0,
+ PC_PERM_TRADE = 0x000001,
+ PC_PERM_PARTY = 0x000002,
+ PC_PERM_ALL_SKILL = 0x000004,
+ PC_PERM_USE_ALL_EQUIPMENT = 0x000008,
+ PC_PERM_SKILL_UNCONDITIONAL = 0x000010,
+ PC_PERM_JOIN_ALL_CHAT = 0x000020,
+ PC_PERM_NO_CHAT_KICK = 0x000040,
+ PC_PERM_HIDE_SESSION = 0x000080,
+ PC_PERM_WHO_DISPLAY_AID = 0x000100,
+ PC_PERM_RECEIVE_HACK_INFO = 0x000200,
+ PC_PERM_WARP_ANYWHERE = 0x000400,
+ PC_PERM_VIEW_HPMETER = 0x000800,
+ PC_PERM_VIEW_EQUIPMENT = 0x001000,
+ PC_PERM_USE_CHECK = 0x002000,
+ PC_PERM_USE_CHANGEMAPTYPE = 0x004000,
+ PC_PERM_USE_ALL_COMMANDS = 0x008000,
+ PC_PERM_RECEIVE_REQUESTS = 0x010000,
+ PC_PERM_SHOW_BOSS = 0x020000,
+ PC_PERM_DISABLE_PVM = 0x040000,
+ PC_PERM_DISABLE_PVP = 0x080000,
+ PC_PERM_DISABLE_CMD_DEAD = 0x100000,
};
static const struct {
- const char *name;
- unsigned int permission;
+ const char *name;
+ unsigned int permission;
} pc_g_permission_name[] = {
- { "can_trade", PC_PERM_TRADE },
- { "can_party", PC_PERM_PARTY },
- { "all_skill", PC_PERM_ALL_SKILL },
- { "all_equipment", PC_PERM_USE_ALL_EQUIPMENT },
- { "skill_unconditional", PC_PERM_SKILL_UNCONDITIONAL },
- { "join_chat", PC_PERM_JOIN_ALL_CHAT },
- { "kick_chat", PC_PERM_NO_CHAT_KICK },
- { "hide_session", PC_PERM_HIDE_SESSION },
- { "who_display_aid", PC_PERM_WHO_DISPLAY_AID },
- { "hack_info", PC_PERM_RECEIVE_HACK_INFO },
- { "any_warp", PC_PERM_WARP_ANYWHERE },
- { "view_hpmeter", PC_PERM_VIEW_HPMETER },
- { "view_equipment", PC_PERM_VIEW_EQUIPMENT },
- { "use_check", PC_PERM_USE_CHECK },
- { "use_changemaptype", PC_PERM_USE_CHANGEMAPTYPE },
- { "all_commands", PC_PERM_USE_ALL_COMMANDS },
- { "receive_requests", PC_PERM_RECEIVE_REQUESTS },
- { "show_bossmobs", PC_PERM_SHOW_BOSS },
- { "disable_pvm", PC_PERM_DISABLE_PVM },
- { "disable_pvp", PC_PERM_DISABLE_PVP },
- { "disable_commands_when_dead", PC_PERM_DISABLE_CMD_DEAD },
+ { "can_trade", PC_PERM_TRADE },
+ { "can_party", PC_PERM_PARTY },
+ { "all_skill", PC_PERM_ALL_SKILL },
+ { "all_equipment", PC_PERM_USE_ALL_EQUIPMENT },
+ { "skill_unconditional", PC_PERM_SKILL_UNCONDITIONAL },
+ { "join_chat", PC_PERM_JOIN_ALL_CHAT },
+ { "kick_chat", PC_PERM_NO_CHAT_KICK },
+ { "hide_session", PC_PERM_HIDE_SESSION },
+ { "who_display_aid", PC_PERM_WHO_DISPLAY_AID },
+ { "hack_info", PC_PERM_RECEIVE_HACK_INFO },
+ { "any_warp", PC_PERM_WARP_ANYWHERE },
+ { "view_hpmeter", PC_PERM_VIEW_HPMETER },
+ { "view_equipment", PC_PERM_VIEW_EQUIPMENT },
+ { "use_check", PC_PERM_USE_CHECK },
+ { "use_changemaptype", PC_PERM_USE_CHANGEMAPTYPE },
+ { "all_commands", PC_PERM_USE_ALL_COMMANDS },
+ { "receive_requests", PC_PERM_RECEIVE_REQUESTS },
+ { "show_bossmobs", PC_PERM_SHOW_BOSS },
+ { "disable_pvm", PC_PERM_DISABLE_PVM },
+ { "disable_pvp", PC_PERM_DISABLE_PVP },
+ { "disable_commands_when_dead", PC_PERM_DISABLE_CMD_DEAD },
};
#endif // _PC_GROUPS_H_
diff --git a/src/map/pet.c b/src/map/pet.c
index daee6600a..5c7f15151 100644
--- a/src/map/pet.c
+++ b/src/map/pet.c
@@ -43,56 +43,56 @@ static struct eri *item_drop_list_ers;
int pet_hungry_val(struct pet_data *pd)
{
- nullpo_ret(pd);
-
- if (pd->pet.hungry > 90)
- return 4;
- else if (pd->pet.hungry > 75)
- return 3;
- else if (pd->pet.hungry > 25)
- return 2;
- else if (pd->pet.hungry > 10)
- return 1;
- else
- return 0;
+ nullpo_ret(pd);
+
+ if(pd->pet.hungry > 90)
+ return 4;
+ else if(pd->pet.hungry > 75)
+ return 3;
+ else if(pd->pet.hungry > 25)
+ return 2;
+ else if(pd->pet.hungry > 10)
+ return 1;
+ else
+ return 0;
}
void pet_set_intimate(struct pet_data *pd, int value)
{
- int intimate;
- struct map_session_data *sd;
+ int intimate;
+ struct map_session_data *sd;
- nullpo_retv(pd);
- intimate = pd->pet.intimate;
- sd = pd->msd;
+ nullpo_retv(pd);
+ intimate = pd->pet.intimate;
+ sd = pd->msd;
- pd->pet.intimate = value;
- if ((intimate >= battle_config.pet_equip_min_friendly && pd->pet.intimate < battle_config.pet_equip_min_friendly) || (intimate < battle_config.pet_equip_min_friendly && pd->pet.intimate >= battle_config.pet_equip_min_friendly))
- status_calc_pc(sd,0);
+ pd->pet.intimate = value;
+ if( (intimate >= battle_config.pet_equip_min_friendly && pd->pet.intimate < battle_config.pet_equip_min_friendly) || (intimate < battle_config.pet_equip_min_friendly && pd->pet.intimate >= battle_config.pet_equip_min_friendly) )
+ status_calc_pc(sd,0);
}
int pet_create_egg(struct map_session_data *sd, int item_id)
{
- int pet_id = search_petDB_index(item_id, PET_EGG);
- if (pet_id < 0) return 0; //No pet egg here.
- sd->catch_target_class = pet_db[pet_id].class_;
- intif_create_pet(sd->status.account_id, 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);
- return 1;
+ int pet_id = search_petDB_index(item_id, PET_EGG);
+ if (pet_id < 0) return 0; //No pet egg here.
+ sd->catch_target_class = pet_db[pet_id].class_;
+ intif_create_pet(sd->status.account_id, 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);
+ return 1;
}
int pet_unlocktarget(struct pet_data *pd)
{
- nullpo_ret(pd);
+ nullpo_ret(pd);
- pd->target_id=0;
- pet_stop_attack(pd);
- pet_stop_walking(pd,1);
- return 0;
+ pd->target_id=0;
+ pet_stop_attack(pd);
+ pet_stop_walking(pd,1);
+ return 0;
}
/*==========================================
@@ -100,484 +100,480 @@ int pet_unlocktarget(struct pet_data *pd)
*------------------------------------------*/
int pet_attackskill(struct pet_data *pd, int target_id)
{
- struct block_list *bl;
-
- if (!battle_config.pet_status_support || !pd->a_skill ||
- (battle_config.pet_equip_required && !pd->pet.equip))
- return 0;
-
- if (DIFF_TICK(pd->ud.canact_tick, gettick()) > 0)
- return 0;
-
- if (rnd()%100 < (pd->a_skill->rate +pd->pet.intimate*pd->a_skill->bonusrate/1000)) {
- //Skotlex: Use pet's skill
- int inf;
-
- bl=map_id2bl(target_id);
- if (bl == NULL || pd->bl.m != bl->m || bl->prev == NULL || status_isdead(bl) ||
- !check_distance_bl(&pd->bl, bl, pd->db->range3))
- return 0;
-
- inf = skill_get_inf(pd->a_skill->id);
- if (inf & INF_GROUND_SKILL)
- unit_skilluse_pos(&pd->bl, bl->x, bl->y, pd->a_skill->id, pd->a_skill->lv);
- else //Offensive self skill? Could be stuff like GX.
- unit_skilluse_id(&pd->bl,(inf&INF_SELF_SKILL?pd->bl.id:bl->id), pd->a_skill->id, pd->a_skill->lv);
- return 1; //Skill invoked.
- }
- return 0;
+ struct block_list *bl;
+
+ if (!battle_config.pet_status_support || !pd->a_skill ||
+ (battle_config.pet_equip_required && !pd->pet.equip))
+ return 0;
+
+ if (DIFF_TICK(pd->ud.canact_tick, gettick()) > 0)
+ return 0;
+
+ if (rnd()%100 < (pd->a_skill->rate +pd->pet.intimate*pd->a_skill->bonusrate/1000))
+ { //Skotlex: Use pet's skill
+ int inf;
+
+ bl=map_id2bl(target_id);
+ if(bl == NULL || pd->bl.m != bl->m || bl->prev == NULL || status_isdead(bl) ||
+ !check_distance_bl(&pd->bl, bl, pd->db->range3))
+ return 0;
+
+ inf = skill_get_inf(pd->a_skill->id);
+ if (inf & INF_GROUND_SKILL)
+ unit_skilluse_pos(&pd->bl, bl->x, bl->y, pd->a_skill->id, pd->a_skill->lv);
+ else //Offensive self skill? Could be stuff like GX.
+ unit_skilluse_id(&pd->bl,(inf&INF_SELF_SKILL?pd->bl.id:bl->id), pd->a_skill->id, pd->a_skill->lv);
+ return 1; //Skill invoked.
+ }
+ return 0;
}
int pet_target_check(struct map_session_data *sd,struct block_list *bl,int type)
{
- struct pet_data *pd;
- int rate;
-
- pd = sd->pd;
-
- Assert((pd->msd == 0) || (pd->msd->pd == pd));
-
- if (bl == NULL || bl->type != BL_MOB || bl->prev == NULL ||
- pd->pet.intimate < battle_config.pet_support_min_friendly ||
- pd->pet.hungry < 1 ||
- pd->pet.class_ == status_get_class(bl))
- return 0;
-
- if (pd->bl.m != bl->m ||
- !check_distance_bl(&pd->bl, bl, pd->db->range2))
- return 0;
-
- if (!status_check_skilluse(&pd->bl, bl, 0, 0))
- return 0;
-
- if (!type) {
- rate = pd->petDB->attack_rate;
- rate = rate * pd->rate_fix/1000;
- if (pd->petDB->attack_rate > 0 && rate <= 0)
- rate = 1;
- } else {
- rate = pd->petDB->defence_attack_rate;
- rate = rate * pd->rate_fix/1000;
- if (pd->petDB->defence_attack_rate > 0 && rate <= 0)
- rate = 1;
- }
- if (rnd()%10000 < rate) {
- if (pd->target_id == 0 || rnd()%10000 < pd->petDB->change_target_rate)
- pd->target_id = bl->id;
- }
-
- return 0;
+ struct pet_data *pd;
+ int rate;
+
+ pd = sd->pd;
+
+ Assert((pd->msd == 0) || (pd->msd->pd == pd));
+
+ if(bl == NULL || bl->type != BL_MOB || bl->prev == NULL ||
+ pd->pet.intimate < battle_config.pet_support_min_friendly ||
+ pd->pet.hungry < 1 ||
+ pd->pet.class_ == status_get_class(bl))
+ return 0;
+
+ if(pd->bl.m != bl->m ||
+ !check_distance_bl(&pd->bl, bl, pd->db->range2))
+ return 0;
+
+ if (!status_check_skilluse(&pd->bl, bl, 0, 0))
+ return 0;
+
+ if(!type) {
+ rate = pd->petDB->attack_rate;
+ rate = rate * pd->rate_fix/1000;
+ if(pd->petDB->attack_rate > 0 && rate <= 0)
+ rate = 1;
+ } else {
+ rate = pd->petDB->defence_attack_rate;
+ rate = rate * pd->rate_fix/1000;
+ if(pd->petDB->defence_attack_rate > 0 && rate <= 0)
+ rate = 1;
+ }
+ if(rnd()%10000 < rate)
+ {
+ if(pd->target_id == 0 || rnd()%10000 < pd->petDB->change_target_rate)
+ pd->target_id = bl->id;
+ }
+
+ return 0;
}
/*==========================================
* Pet SC Check [Skotlex]
*------------------------------------------*/
int pet_sc_check(struct map_session_data *sd, int type)
{
- struct pet_data *pd;
+ struct pet_data *pd;
- nullpo_ret(sd);
- pd = sd->pd;
+ nullpo_ret(sd);
+ pd = sd->pd;
- if (pd == NULL
- || (battle_config.pet_equip_required && pd->pet.equip == 0)
- || pd->recovery == NULL
- || pd->recovery->timer != INVALID_TIMER
- || pd->recovery->type != type)
- return 1;
+ if( pd == NULL
+ || (battle_config.pet_equip_required && pd->pet.equip == 0)
+ || pd->recovery == NULL
+ || pd->recovery->timer != INVALID_TIMER
+ || pd->recovery->type != type )
+ return 1;
- pd->recovery->timer = add_timer(gettick()+pd->recovery->delay*1000,pet_recovery_timer,sd->bl.id,0);
-
- return 0;
+ pd->recovery->timer = add_timer(gettick()+pd->recovery->delay*1000,pet_recovery_timer,sd->bl.id,0);
+
+ return 0;
}
static int pet_hungry(int tid, unsigned int tick, int id, intptr_t data)
{
- struct map_session_data *sd;
- struct pet_data *pd;
- int interval;
-
- sd=map_id2sd(id);
- if (!sd)
- return 1;
-
- if (!sd->status.pet_id || !sd->pd)
- return 1;
-
- pd = sd->pd;
- if (pd->pet_hungry_timer != tid) {
- ShowError("pet_hungry_timer %d != %d\n",pd->pet_hungry_timer,tid);
- return 0;
- }
- pd->pet_hungry_timer = INVALID_TIMER;
-
- if (pd->pet.intimate <= 0)
- return 1; //You lost the pet already, the rest is irrelevant.
-
- pd->pet.hungry--;
- if (pd->pet.hungry < 0) {
- pet_stop_attack(pd);
- pd->pet.hungry = 0;
- pet_set_intimate(pd, pd->pet.intimate - battle_config.pet_hungry_friendly_decrease);
- if (pd->pet.intimate <= 0) {
- pd->pet.intimate = 0;
- pd->status.speed = pd->db->status.speed;
- }
- status_calc_pet(pd, 0);
- clif_send_petdata(sd,pd,1,pd->pet.intimate);
- }
- clif_send_petdata(sd,pd,2,pd->pet.hungry);
-
- if (battle_config.pet_hungry_delay_rate != 100)
- interval = (pd->petDB->hungry_delay*battle_config.pet_hungry_delay_rate)/100;
- else
- interval = pd->petDB->hungry_delay;
- if (interval <= 0)
- interval = 1;
- pd->pet_hungry_timer = add_timer(tick+interval,pet_hungry,sd->bl.id,0);
-
- return 0;
+ struct map_session_data *sd;
+ struct pet_data *pd;
+ int interval;
+
+ sd=map_id2sd(id);
+ if(!sd)
+ return 1;
+
+ if(!sd->status.pet_id || !sd->pd)
+ return 1;
+
+ pd = sd->pd;
+ if(pd->pet_hungry_timer != tid){
+ ShowError("pet_hungry_timer %d != %d\n",pd->pet_hungry_timer,tid);
+ return 0;
+ }
+ pd->pet_hungry_timer = INVALID_TIMER;
+
+ if (pd->pet.intimate <= 0)
+ return 1; //You lost the pet already, the rest is irrelevant.
+
+ pd->pet.hungry--;
+ if( pd->pet.hungry < 0 )
+ {
+ pet_stop_attack(pd);
+ pd->pet.hungry = 0;
+ pet_set_intimate(pd, pd->pet.intimate - battle_config.pet_hungry_friendly_decrease);
+ if( pd->pet.intimate <= 0 )
+ {
+ pd->pet.intimate = 0;
+ pd->status.speed = pd->db->status.speed;
+ }
+ status_calc_pet(pd, 0);
+ clif_send_petdata(sd,pd,1,pd->pet.intimate);
+ }
+ clif_send_petdata(sd,pd,2,pd->pet.hungry);
+
+ if(battle_config.pet_hungry_delay_rate != 100)
+ interval = (pd->petDB->hungry_delay*battle_config.pet_hungry_delay_rate)/100;
+ else
+ interval = pd->petDB->hungry_delay;
+ if(interval <= 0)
+ interval = 1;
+ pd->pet_hungry_timer = add_timer(tick+interval,pet_hungry,sd->bl.id,0);
+
+ return 0;
}
int search_petDB_index(int key,int type)
{
- int i;
-
- for (i = 0; i < MAX_PET_DB; i++) {
- if (pet_db[i].class_ <= 0)
- continue;
- switch (type) {
- case PET_CLASS:
- if (pet_db[i].class_ == key) return i;
- break;
- case PET_CATCH:
- if (pet_db[i].itemID == key) return i;
- break;
- case PET_EGG:
- if (pet_db[i].EggID == key) return i;
- break;
- case PET_EQUIP:
- if (pet_db[i].AcceID == key) return i;
- break;
- case PET_FOOD:
- if (pet_db[i].FoodID == key) return i;
- break;
- default:
- return -1;
- }
- }
- return -1;
+ int i;
+
+ for( i = 0; i < MAX_PET_DB; i++ )
+ {
+ if(pet_db[i].class_ <= 0)
+ continue;
+ switch(type) {
+ case PET_CLASS: if(pet_db[i].class_ == key) return i; break;
+ case PET_CATCH: if(pet_db[i].itemID == key) return i; break;
+ case PET_EGG: if(pet_db[i].EggID == key) return i; break;
+ case PET_EQUIP: if(pet_db[i].AcceID == key) return i; break;
+ case PET_FOOD: if(pet_db[i].FoodID == key) return i; break;
+ default:
+ return -1;
+ }
+ }
+ return -1;
}
int pet_hungry_timer_delete(struct pet_data *pd)
{
- nullpo_ret(pd);
- if (pd->pet_hungry_timer != INVALID_TIMER) {
- delete_timer(pd->pet_hungry_timer,pet_hungry);
- pd->pet_hungry_timer = INVALID_TIMER;
- }
+ nullpo_ret(pd);
+ if(pd->pet_hungry_timer != INVALID_TIMER) {
+ delete_timer(pd->pet_hungry_timer,pet_hungry);
+ pd->pet_hungry_timer = INVALID_TIMER;
+ }
- return 1;
+ return 1;
}
static int pet_performance(struct map_session_data *sd, struct pet_data *pd)
{
- int val;
-
- if (pd->pet.intimate > 900)
- val = (pd->petDB->s_perfor > 0)? 4:3;
- else if (pd->pet.intimate > 750) //TODO: this is way too high
- val = 2;
- else
- val = 1;
-
- pet_stop_walking(pd,2000<<8);
- clif_pet_performance(pd, rnd()%val + 1);
- pet_lootitem_drop(pd,NULL);
- return 1;
+ int val;
+
+ if (pd->pet.intimate > 900)
+ val = (pd->petDB->s_perfor > 0)? 4:3;
+ else if(pd->pet.intimate > 750) //TODO: this is way too high
+ val = 2;
+ else
+ val = 1;
+
+ pet_stop_walking(pd,2000<<8);
+ clif_pet_performance(pd, rnd()%val + 1);
+ pet_lootitem_drop(pd,NULL);
+ return 1;
}
static int pet_return_egg(struct map_session_data *sd, struct pet_data *pd)
{
- struct item tmp_item;
- int flag;
-
- pet_lootitem_drop(pd,sd);
- memset(&tmp_item,0,sizeof(tmp_item));
- tmp_item.nameid = pd->petDB->EggID;
- tmp_item.identify = 1;
- tmp_item.card[0] = CARD0_PET;
- tmp_item.card[1] = GetWord(pd->pet.pet_id,0);
- tmp_item.card[2] = GetWord(pd->pet.pet_id,1);
- tmp_item.card[3] = pd->pet.rename_flag;
- if ((flag = pc_additem(sd,&tmp_item,1,LOG_TYPE_OTHER))) {
- clif_additem(sd,0,0,flag);
- map_addflooritem(&tmp_item,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
- }
- pd->pet.incuvate = 1;
- unit_free(&pd->bl,CLR_OUTSIGHT);
-
- status_calc_pc(sd,0);
- sd->status.pet_id = 0;
-
- return 1;
+ struct item tmp_item;
+ int flag;
+
+ pet_lootitem_drop(pd,sd);
+ memset(&tmp_item,0,sizeof(tmp_item));
+ tmp_item.nameid = pd->petDB->EggID;
+ tmp_item.identify = 1;
+ tmp_item.card[0] = CARD0_PET;
+ tmp_item.card[1] = GetWord(pd->pet.pet_id,0);
+ tmp_item.card[2] = GetWord(pd->pet.pet_id,1);
+ tmp_item.card[3] = pd->pet.rename_flag;
+ if((flag = pc_additem(sd,&tmp_item,1,LOG_TYPE_OTHER))) {
+ clif_additem(sd,0,0,flag);
+ map_addflooritem(&tmp_item,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ }
+ pd->pet.incuvate = 1;
+ unit_free(&pd->bl,CLR_OUTSIGHT);
+
+ status_calc_pc(sd,0);
+ sd->status.pet_id = 0;
+
+ return 1;
}
int pet_data_init(struct map_session_data *sd, struct s_pet *pet)
{
- struct pet_data *pd;
- int i=0,interval=0;
-
- nullpo_retr(1, sd);
-
- Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd);
-
- if (sd->status.account_id != pet->account_id || sd->status.char_id != pet->char_id) {
- sd->status.pet_id = 0;
- return 1;
- }
- if (sd->status.pet_id != pet->pet_id) {
- if (sd->status.pet_id) {
- //Wrong pet?? Set incuvate to no and send it back for saving.
- pet->incuvate = 1;
- intif_save_petdata(sd->status.account_id,pet);
- sd->status.pet_id = 0;
- return 1;
- }
- //The pet_id value was lost? odd... restore it.
- sd->status.pet_id = pet->pet_id;
- }
-
- i = search_petDB_index(pet->class_,PET_CLASS);
- if (i < 0) {
- sd->status.pet_id = 0;
- return 1;
- }
- sd->pd = pd = (struct pet_data *)aCalloc(1,sizeof(struct pet_data));
- pd->bl.type = BL_PET;
- pd->bl.id = npc_get_new_npc_id();
-
- pd->msd = sd;
- pd->petDB = &pet_db[i];
- pd->db = mob_db(pet->class_);
- memcpy(&pd->pet, pet, sizeof(struct s_pet));
- status_set_viewdata(&pd->bl, pet->class_);
- unit_dataset(&pd->bl);
- pd->ud.dir = sd->ud.dir;
-
- pd->bl.m = sd->bl.m;
- pd->bl.x = sd->bl.x;
- pd->bl.y = sd->bl.y;
- unit_calc_pos(&pd->bl, sd->bl.x, sd->bl.y, sd->ud.dir);
- pd->bl.x = pd->ud.to_x;
- pd->bl.y = pd->ud.to_y;
-
- map_addiddb(&pd->bl);
- status_calc_pet(pd,1);
-
- pd->last_thinktime = gettick();
- pd->state.skillbonus = 0;
- if (battle_config.pet_status_support)
- run_script(pet_db[i].pet_script,0,sd->bl.id,0);
- if (pd->petDB && pd->petDB->equip_script)
- status_calc_pc(sd,0);
-
- if (battle_config.pet_hungry_delay_rate != 100)
- interval = (pd->petDB->hungry_delay*battle_config.pet_hungry_delay_rate)/100;
- else
- interval = pd->petDB->hungry_delay;
- if (interval <= 0)
- interval = 1;
- pd->pet_hungry_timer = add_timer(gettick() + interval, pet_hungry, sd->bl.id, 0);
- return 0;
+ struct pet_data *pd;
+ int i=0,interval=0;
+
+ nullpo_retr(1, sd);
+
+ Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd);
+
+ if(sd->status.account_id != pet->account_id || sd->status.char_id != pet->char_id) {
+ sd->status.pet_id = 0;
+ return 1;
+ }
+ if (sd->status.pet_id != pet->pet_id) {
+ if (sd->status.pet_id) {
+ //Wrong pet?? Set incuvate to no and send it back for saving.
+ pet->incuvate = 1;
+ intif_save_petdata(sd->status.account_id,pet);
+ sd->status.pet_id = 0;
+ return 1;
+ }
+ //The pet_id value was lost? odd... restore it.
+ sd->status.pet_id = pet->pet_id;
+ }
+
+ i = search_petDB_index(pet->class_,PET_CLASS);
+ if(i < 0) {
+ sd->status.pet_id = 0;
+ return 1;
+ }
+ sd->pd = pd = (struct pet_data *)aCalloc(1,sizeof(struct pet_data));
+ pd->bl.type = BL_PET;
+ pd->bl.id = npc_get_new_npc_id();
+
+ pd->msd = sd;
+ pd->petDB = &pet_db[i];
+ pd->db = mob_db(pet->class_);
+ memcpy(&pd->pet, pet, sizeof(struct s_pet));
+ status_set_viewdata(&pd->bl, pet->class_);
+ unit_dataset(&pd->bl);
+ pd->ud.dir = sd->ud.dir;
+
+ pd->bl.m = sd->bl.m;
+ pd->bl.x = sd->bl.x;
+ pd->bl.y = sd->bl.y;
+ unit_calc_pos(&pd->bl, sd->bl.x, sd->bl.y, sd->ud.dir);
+ pd->bl.x = pd->ud.to_x;
+ pd->bl.y = pd->ud.to_y;
+
+ map_addiddb(&pd->bl);
+ status_calc_pet(pd,1);
+
+ pd->last_thinktime = gettick();
+ pd->state.skillbonus = 0;
+ if( battle_config.pet_status_support )
+ run_script(pet_db[i].pet_script,0,sd->bl.id,0);
+ if( pd->petDB && pd->petDB->equip_script )
+ status_calc_pc(sd,0);
+
+ if( battle_config.pet_hungry_delay_rate != 100 )
+ interval = (pd->petDB->hungry_delay*battle_config.pet_hungry_delay_rate)/100;
+ else
+ interval = pd->petDB->hungry_delay;
+ if( interval <= 0 )
+ interval = 1;
+ pd->pet_hungry_timer = add_timer(gettick() + interval, pet_hungry, sd->bl.id, 0);
+ return 0;
}
int pet_birth_process(struct map_session_data *sd, struct s_pet *pet)
{
- nullpo_retr(1, sd);
-
- Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd);
-
- if (sd->status.pet_id && pet->incuvate == 1) {
- sd->status.pet_id = 0;
- return 1;
- }
-
- pet->incuvate = 0;
- pet->account_id = sd->status.account_id;
- pet->char_id = sd->status.char_id;
- sd->status.pet_id = pet->pet_id;
- if (pet_data_init(sd, pet)) {
- sd->status.pet_id = 0;
- return 1;
- }
-
- intif_save_petdata(sd->status.account_id,pet);
- if (save_settings&8)
- chrif_save(sd,0); //is it REALLY Needed to save the char for hatching a pet? [Skotlex]
-
- if (sd->bl.prev != NULL) {
- map_addblock(&sd->pd->bl);
- clif_spawn(&sd->pd->bl);
- clif_send_petdata(sd,sd->pd, 0,0);
- clif_send_petdata(sd,sd->pd, 5,battle_config.pet_hair_style);
- clif_pet_equip_area(sd->pd);
- clif_send_petstatus(sd);
- }
- Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd);
-
- return 0;
+ nullpo_retr(1, sd);
+
+ Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd);
+
+ if(sd->status.pet_id && pet->incuvate == 1) {
+ sd->status.pet_id = 0;
+ return 1;
+ }
+
+ pet->incuvate = 0;
+ pet->account_id = sd->status.account_id;
+ pet->char_id = sd->status.char_id;
+ sd->status.pet_id = pet->pet_id;
+ if(pet_data_init(sd, pet)) {
+ sd->status.pet_id = 0;
+ return 1;
+ }
+
+ intif_save_petdata(sd->status.account_id,pet);
+ if (save_settings&8)
+ chrif_save(sd,0); //is it REALLY Needed to save the char for hatching a pet? [Skotlex]
+
+ if(sd->bl.prev != NULL) {
+ map_addblock(&sd->pd->bl);
+ clif_spawn(&sd->pd->bl);
+ clif_send_petdata(sd,sd->pd, 0,0);
+ clif_send_petdata(sd,sd->pd, 5,battle_config.pet_hair_style);
+ clif_pet_equip_area(sd->pd);
+ clif_send_petstatus(sd);
+ }
+ Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd);
+
+ return 0;
}
int pet_recv_petdata(int account_id,struct s_pet *p,int flag)
{
- struct map_session_data *sd;
-
- sd = map_id2sd(account_id);
- if (sd == NULL)
- return 1;
- if (flag == 1) {
- sd->status.pet_id = 0;
- return 1;
- }
- if (p->incuvate == 1) {
- int i;
- //Delete egg from inventory. [Skotlex]
- for (i = 0; i < MAX_INVENTORY; i++) {
- if (sd->status.inventory[i].card[0] == CARD0_PET &&
- p->pet_id == MakeDWord(sd->status.inventory[i].card[1], sd->status.inventory[i].card[2]))
- break;
- }
- if (i >= MAX_INVENTORY) {
- ShowError("pet_recv_petdata: Hatching pet (%d:%s) aborted, couldn't find egg in inventory for removal!\n",p->pet_id, p->name);
- sd->status.pet_id = 0;
- return 1;
- }
- if (!pet_birth_process(sd,p)) //Pet hatched. Delete egg.
- pc_delitem(sd,i,1,0,0,LOG_TYPE_OTHER);
- } else {
- pet_data_init(sd,p);
- if (sd->pd && sd->bl.prev != NULL) {
- map_addblock(&sd->pd->bl);
- clif_spawn(&sd->pd->bl);
- clif_send_petdata(sd,sd->pd,0,0);
- clif_send_petdata(sd,sd->pd,5,battle_config.pet_hair_style);
- clif_pet_equip_area(sd->pd);
- clif_send_petstatus(sd);
- }
- }
-
- return 0;
+ struct map_session_data *sd;
+
+ sd = map_id2sd(account_id);
+ if(sd == NULL)
+ return 1;
+ if(flag == 1) {
+ sd->status.pet_id = 0;
+ return 1;
+ }
+ if(p->incuvate == 1) {
+ int i;
+ //Delete egg from inventory. [Skotlex]
+ for (i = 0; i < MAX_INVENTORY; i++) {
+ if(sd->status.inventory[i].card[0] == CARD0_PET &&
+ p->pet_id == MakeDWord(sd->status.inventory[i].card[1], sd->status.inventory[i].card[2]))
+ break;
+ }
+ if(i >= MAX_INVENTORY) {
+ ShowError("pet_recv_petdata: Hatching pet (%d:%s) aborted, couldn't find egg in inventory for removal!\n",p->pet_id, p->name);
+ sd->status.pet_id = 0;
+ return 1;
+ }
+ if (!pet_birth_process(sd,p)) //Pet hatched. Delete egg.
+ pc_delitem(sd,i,1,0,0,LOG_TYPE_OTHER);
+ } else {
+ pet_data_init(sd,p);
+ if(sd->pd && sd->bl.prev != NULL) {
+ map_addblock(&sd->pd->bl);
+ clif_spawn(&sd->pd->bl);
+ clif_send_petdata(sd,sd->pd,0,0);
+ clif_send_petdata(sd,sd->pd,5,battle_config.pet_hair_style);
+ clif_pet_equip_area(sd->pd);
+ clif_send_petstatus(sd);
+ }
+ }
+
+ return 0;
}
int pet_select_egg(struct map_session_data *sd,short egg_index)
{
- nullpo_ret(sd);
+ nullpo_ret(sd);
- if (egg_index < 0 || egg_index >= MAX_INVENTORY)
- return 0; //Forged packet!
+ if(egg_index < 0 || egg_index >= MAX_INVENTORY)
+ return 0; //Forged packet!
- if (sd->status.inventory[egg_index].card[0] == CARD0_PET)
- intif_request_petdata(sd->status.account_id, sd->status.char_id, MakeDWord(sd->status.inventory[egg_index].card[1], sd->status.inventory[egg_index].card[2]));
- else
- ShowError("wrong egg item inventory %d\n",egg_index);
+ if(sd->status.inventory[egg_index].card[0] == CARD0_PET)
+ intif_request_petdata(sd->status.account_id, sd->status.char_id, MakeDWord(sd->status.inventory[egg_index].card[1], sd->status.inventory[egg_index].card[2]) );
+ else
+ ShowError("wrong egg item inventory %d\n",egg_index);
- return 0;
+ return 0;
}
int pet_catch_process1(struct map_session_data *sd,int target_class)
{
- nullpo_ret(sd);
+ nullpo_ret(sd);
- sd->catch_target_class = target_class;
- clif_catch_process(sd);
+ sd->catch_target_class = target_class;
+ clif_catch_process(sd);
- return 0;
+ return 0;
}
-int pet_catch_process2(struct map_session_data *sd, int target_id)
+int pet_catch_process2(struct map_session_data* sd, int target_id)
{
- struct mob_data *md;
- int i = 0, pet_catch_rate = 0;
-
- nullpo_retr(1, sd);
-
- md = (struct mob_data *)map_id2bl(target_id);
- if (!md || md->bl.type != BL_MOB || md->bl.prev == NULL) {
- // Invalid inputs/state, abort capture.
- clif_pet_roulette(sd,0);
- sd->catch_target_class = -1;
- sd->itemid = sd->itemindex = -1;
- return 1;
- }
-
- //FIXME: delete taming item here, if this was an item-invoked capture and the item was flagged as delay-consume [ultramage]
-
- i = search_petDB_index(md->class_,PET_CLASS);
- //catch_target_class == 0 is used for universal lures (except bosses for now). [Skotlex]
- if (sd->catch_target_class == 0 && !(md->status.mode&MD_BOSS))
- sd->catch_target_class = md->class_;
- if (i < 0 || sd->catch_target_class != md->class_) {
- clif_emotion(&md->bl, E_AG); //mob will do /ag if wrong lure is used on them.
- clif_pet_roulette(sd,0);
- sd->catch_target_class = -1;
- return 1;
- }
-
- pet_catch_rate = (pet_db[i].capture + (sd->status.base_level - md->level)*30 + sd->battle_status.luk*20)*(200 - get_percentage(md->status.hp, md->status.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 (rnd()%10000 < pet_catch_rate) {
- unit_remove_map(&md->bl,CLR_OUTSIGHT);
- status_kill(&md->bl);
- clif_pet_roulette(sd,1);
- 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 {
- clif_pet_roulette(sd,0);
- sd->catch_target_class = -1;
- }
-
- return 0;
+ struct mob_data* md;
+ int i = 0, pet_catch_rate = 0;
+
+ nullpo_retr(1, sd);
+
+ md = (struct mob_data*)map_id2bl(target_id);
+ if(!md || md->bl.type != BL_MOB || md->bl.prev == NULL)
+ { // Invalid inputs/state, abort capture.
+ clif_pet_roulette(sd,0);
+ sd->catch_target_class = -1;
+ sd->itemid = sd->itemindex = -1;
+ return 1;
+ }
+
+ //FIXME: delete taming item here, if this was an item-invoked capture and the item was flagged as delay-consume [ultramage]
+
+ i = search_petDB_index(md->class_,PET_CLASS);
+ //catch_target_class == 0 is used for universal lures (except bosses for now). [Skotlex]
+ if (sd->catch_target_class == 0 && !(md->status.mode&MD_BOSS))
+ sd->catch_target_class = md->class_;
+ if(i < 0 || sd->catch_target_class != md->class_) {
+ clif_emotion(&md->bl, E_AG); //mob will do /ag if wrong lure is used on them.
+ clif_pet_roulette(sd,0);
+ sd->catch_target_class = -1;
+ return 1;
+ }
+
+ pet_catch_rate = (pet_db[i].capture + (sd->status.base_level - md->level)*30 + sd->battle_status.luk*20)*(200 - get_percentage(md->status.hp, md->status.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(rnd()%10000 < pet_catch_rate)
+ {
+ unit_remove_map(&md->bl,CLR_OUTSIGHT);
+ status_kill(&md->bl);
+ clif_pet_roulette(sd,1);
+ 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
+ {
+ clif_pet_roulette(sd,0);
+ sd->catch_target_class = -1;
+ }
+
+ return 0;
}
int pet_get_egg(int account_id,int pet_id,int flag)
-{
- //This function is invoked when a new pet has been created, and at no other time!
- struct map_session_data *sd;
- struct item tmp_item;
- int i=0,ret=0;
-
- if (flag)
- return 0;
-
- sd = map_id2sd(account_id);
- if (sd == NULL)
- return 0;
-
- i = search_petDB_index(sd->catch_target_class,PET_CLASS);
- sd->catch_target_class = -1;
-
- if (i < 0) {
- intif_delete_petdata(pet_id);
- return 0;
- }
-
- memset(&tmp_item,0,sizeof(tmp_item));
- tmp_item.nameid = pet_db[i].EggID;
- tmp_item.identify = 1;
- tmp_item.card[0] = CARD0_PET;
- tmp_item.card[1] = GetWord(pet_id,0);
- tmp_item.card[2] = GetWord(pet_id,1);
- tmp_item.card[3] = 0; //New pets are not named.
- if ((ret = pc_additem(sd,&tmp_item,1,LOG_TYPE_PICKDROP_PLAYER))) {
- clif_additem(sd,0,0,ret);
- map_addflooritem(&tmp_item,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
- }
-
- return 1;
+{ //This function is invoked when a new pet has been created, and at no other time!
+ struct map_session_data *sd;
+ struct item tmp_item;
+ int i=0,ret=0;
+
+ if(flag)
+ return 0;
+
+ sd = map_id2sd(account_id);
+ if(sd == NULL)
+ return 0;
+
+ i = search_petDB_index(sd->catch_target_class,PET_CLASS);
+ sd->catch_target_class = -1;
+
+ if(i < 0) {
+ intif_delete_petdata(pet_id);
+ return 0;
+ }
+
+ memset(&tmp_item,0,sizeof(tmp_item));
+ tmp_item.nameid = pet_db[i].EggID;
+ tmp_item.identify = 1;
+ tmp_item.card[0] = CARD0_PET;
+ tmp_item.card[1] = GetWord(pet_id,0);
+ tmp_item.card[2] = GetWord(pet_id,1);
+ tmp_item.card[3] = 0; //New pets are not named.
+ if((ret = pc_additem(sd,&tmp_item,1,LOG_TYPE_PICKDROP_PLAYER))) {
+ clif_additem(sd,0,0,ret);
+ map_addflooritem(&tmp_item,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ }
+
+ return 1;
}
static int pet_unequipitem(struct map_session_data *sd, struct pet_data *pd);
@@ -586,743 +582,766 @@ static int pet_ai_sub_hard_lootsearch(struct block_list *bl,va_list ap);
int pet_menu(struct map_session_data *sd,int menunum)
{
- nullpo_ret(sd);
- if (sd->pd == NULL)
- return 1;
-
- //You lost the pet already.
- if (!sd->status.pet_id || sd->pd->pet.intimate <= 0 || sd->pd->pet.incuvate)
- return 1;
-
- switch (menunum) {
- case 0:
- clif_send_petstatus(sd);
- break;
- case 1:
- pet_food(sd, sd->pd);
- break;
- case 2:
- pet_performance(sd, sd->pd);
- break;
- case 3:
- pet_return_egg(sd, sd->pd);
- break;
- case 4:
- pet_unequipitem(sd, sd->pd);
- break;
- }
- return 0;
+ nullpo_ret(sd);
+ if (sd->pd == NULL)
+ return 1;
+
+ //You lost the pet already.
+ if(!sd->status.pet_id || sd->pd->pet.intimate <= 0 || sd->pd->pet.incuvate)
+ return 1;
+
+ switch(menunum) {
+ case 0:
+ clif_send_petstatus(sd);
+ break;
+ case 1:
+ pet_food(sd, sd->pd);
+ break;
+ case 2:
+ pet_performance(sd, sd->pd);
+ break;
+ case 3:
+ pet_return_egg(sd, sd->pd);
+ break;
+ case 4:
+ pet_unequipitem(sd, sd->pd);
+ break;
+ }
+ return 0;
}
int pet_change_name(struct map_session_data *sd,char *name)
{
- int i;
- struct pet_data *pd;
- nullpo_retr(1, sd);
+ int i;
+ struct pet_data *pd;
+ nullpo_retr(1, sd);
- pd = sd->pd;
- if ((pd == NULL) || (pd->pet.rename_flag == 1 && !battle_config.pet_rename))
- return 1;
+ pd = sd->pd;
+ if((pd == NULL) || (pd->pet.rename_flag == 1 && !battle_config.pet_rename))
+ return 1;
- for (i=0; i<NAME_LENGTH && name[i]; i++) {
- if (!(name[i]&0xe0) || name[i]==0x7f)
- return 1;
- }
+ for(i=0;i<NAME_LENGTH && name[i];i++){
+ if( !(name[i]&0xe0) || name[i]==0x7f)
+ return 1;
+ }
- return intif_rename_pet(sd, name);
+ return intif_rename_pet(sd, name);
}
-int pet_change_name_ack(struct map_session_data *sd, char *name, int flag)
+int pet_change_name_ack(struct map_session_data *sd, char* name, int flag)
{
- struct pet_data *pd = sd->pd;
- if (!pd) return 0;
-
- normalize_name(name," ");//bugreport:3032
-
- if (!flag || !strlen(name)) {
- clif_displaymessage(sd->fd, msg_txt(280)); // You cannot use this name for your pet.
- clif_send_petstatus(sd); //Send status so client knows oet name change got rejected.
- return 0;
- }
- memcpy(pd->pet.name, name, NAME_LENGTH);
- clif_charnameack(0,&pd->bl);
- pd->pet.rename_flag = 1;
- clif_pet_equip_area(pd);
- clif_send_petstatus(sd);
- return 1;
+ struct pet_data *pd = sd->pd;
+ if (!pd) return 0;
+
+ normalize_name(name," ");//bugreport:3032
+
+ if ( !flag || !strlen(name) ) {
+ clif_displaymessage(sd->fd, msg_txt(280)); // You cannot use this name for your pet.
+ clif_send_petstatus(sd); //Send status so client knows oet name change got rejected.
+ return 0;
+ }
+ memcpy(pd->pet.name, name, NAME_LENGTH);
+ clif_charnameack (0,&pd->bl);
+ pd->pet.rename_flag = 1;
+ clif_pet_equip_area(pd);
+ clif_send_petstatus(sd);
+ return 1;
}
int pet_equipitem(struct map_session_data *sd,int index)
{
- struct pet_data *pd;
- int nameid;
-
- nullpo_retr(1, sd);
- pd = sd->pd;
- if (!pd) return 1;
-
- nameid = sd->status.inventory[index].nameid;
-
- if (pd->petDB->AcceID == 0 || nameid != pd->petDB->AcceID || pd->pet.equip != 0) {
- clif_equipitemack(sd,0,0,0);
- return 1;
- }
-
- pc_delitem(sd,index,1,0,0,LOG_TYPE_OTHER);
- pd->pet.equip = nameid;
- status_set_viewdata(&pd->bl, pd->pet.class_); //Updates view_data.
- clif_pet_equip_area(pd);
- if (battle_config.pet_equip_required) {
- //Skotlex: start support timers if need
- unsigned int tick = gettick();
- if (pd->s_skill && pd->s_skill->timer == INVALID_TIMER) {
- if (pd->s_skill->id)
- pd->s_skill->timer=add_timer(tick+pd->s_skill->delay*1000, pet_skill_support_timer, sd->bl.id, 0);
- else
- pd->s_skill->timer=add_timer(tick+pd->s_skill->delay*1000, pet_heal_timer, sd->bl.id, 0);
- }
- if (pd->bonus && pd->bonus->timer == INVALID_TIMER)
- pd->bonus->timer=add_timer(tick+pd->bonus->delay*1000, pet_skill_bonus_timer, sd->bl.id, 0);
- }
-
- return 0;
+ struct pet_data *pd;
+ int nameid;
+
+ nullpo_retr(1, sd);
+ pd = sd->pd;
+ if (!pd) return 1;
+
+ nameid = sd->status.inventory[index].nameid;
+
+ if(pd->petDB->AcceID == 0 || nameid != pd->petDB->AcceID || pd->pet.equip != 0) {
+ clif_equipitemack(sd,0,0,0);
+ return 1;
+ }
+
+ pc_delitem(sd,index,1,0,0,LOG_TYPE_OTHER);
+ pd->pet.equip = nameid;
+ status_set_viewdata(&pd->bl, pd->pet.class_); //Updates view_data.
+ clif_pet_equip_area(pd);
+ if (battle_config.pet_equip_required)
+ { //Skotlex: start support timers if need
+ unsigned int tick = gettick();
+ if (pd->s_skill && pd->s_skill->timer == INVALID_TIMER)
+ {
+ if (pd->s_skill->id)
+ pd->s_skill->timer=add_timer(tick+pd->s_skill->delay*1000, pet_skill_support_timer, sd->bl.id, 0);
+ else
+ pd->s_skill->timer=add_timer(tick+pd->s_skill->delay*1000, pet_heal_timer, sd->bl.id, 0);
+ }
+ if (pd->bonus && pd->bonus->timer == INVALID_TIMER)
+ pd->bonus->timer=add_timer(tick+pd->bonus->delay*1000, pet_skill_bonus_timer, sd->bl.id, 0);
+ }
+
+ return 0;
}
static int pet_unequipitem(struct map_session_data *sd, struct pet_data *pd)
{
- struct item tmp_item;
- int nameid,flag;
-
- if (pd->pet.equip == 0)
- return 1;
-
- nameid = pd->pet.equip;
- pd->pet.equip = 0;
- status_set_viewdata(&pd->bl, pd->pet.class_);
- clif_pet_equip_area(pd);
- memset(&tmp_item,0,sizeof(tmp_item));
- tmp_item.nameid = nameid;
- tmp_item.identify = 1;
- if ((flag = pc_additem(sd,&tmp_item,1,LOG_TYPE_OTHER))) {
- clif_additem(sd,0,0,flag);
- map_addflooritem(&tmp_item,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
- }
- if (battle_config.pet_equip_required) {
- // Skotlex: halt support timers if needed
- if (pd->state.skillbonus) {
- pd->state.skillbonus = 0;
- status_calc_pc(sd,0);
- }
- if (pd->s_skill && pd->s_skill->timer != INVALID_TIMER) {
- if (pd->s_skill->id)
- delete_timer(pd->s_skill->timer, pet_skill_support_timer);
- else
- delete_timer(pd->s_skill->timer, pet_heal_timer);
- pd->s_skill->timer = INVALID_TIMER;
- }
- if (pd->bonus && pd->bonus->timer != INVALID_TIMER) {
- delete_timer(pd->bonus->timer, pet_skill_bonus_timer);
- pd->bonus->timer = INVALID_TIMER;
- }
- }
-
- return 0;
+ struct item tmp_item;
+ int nameid,flag;
+
+ if(pd->pet.equip == 0)
+ return 1;
+
+ nameid = pd->pet.equip;
+ pd->pet.equip = 0;
+ status_set_viewdata(&pd->bl, pd->pet.class_);
+ clif_pet_equip_area(pd);
+ memset(&tmp_item,0,sizeof(tmp_item));
+ tmp_item.nameid = nameid;
+ tmp_item.identify = 1;
+ if((flag = pc_additem(sd,&tmp_item,1,LOG_TYPE_OTHER))) {
+ clif_additem(sd,0,0,flag);
+ map_addflooritem(&tmp_item,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ }
+ if( battle_config.pet_equip_required )
+ { // Skotlex: halt support timers if needed
+ if( pd->state.skillbonus )
+ {
+ pd->state.skillbonus = 0;
+ status_calc_pc(sd,0);
+ }
+ if( pd->s_skill && pd->s_skill->timer != INVALID_TIMER )
+ {
+ if( pd->s_skill->id )
+ delete_timer(pd->s_skill->timer, pet_skill_support_timer);
+ else
+ delete_timer(pd->s_skill->timer, pet_heal_timer);
+ pd->s_skill->timer = INVALID_TIMER;
+ }
+ if( pd->bonus && pd->bonus->timer != INVALID_TIMER )
+ {
+ delete_timer(pd->bonus->timer, pet_skill_bonus_timer);
+ pd->bonus->timer = INVALID_TIMER;
+ }
+ }
+
+ return 0;
}
static int pet_food(struct map_session_data *sd, struct pet_data *pd)
{
- int i,k;
-
- k=pd->petDB->FoodID;
- i=pc_search_inventory(sd,k);
- if (i < 0) {
- clif_pet_food(sd,k,0);
- return 1;
- }
- pc_delitem(sd,i,1,0,0,LOG_TYPE_CONSUME);
-
- if (pd->pet.hungry > 90)
- pet_set_intimate(pd, pd->pet.intimate - pd->petDB->r_full);
- else {
- if (battle_config.pet_friendly_rate != 100)
- k = (pd->petDB->r_hungry * battle_config.pet_friendly_rate)/100;
- else
- k = pd->petDB->r_hungry;
- if (pd->pet.hungry > 75) {
- k = k >> 1;
- if (k <= 0)
- k = 1;
- }
- pet_set_intimate(pd, pd->pet.intimate + k);
- }
- if (pd->pet.intimate <= 0) {
- pd->pet.intimate = 0;
- pet_stop_attack(pd);
- pd->status.speed = pd->db->status.speed;
- } else if (pd->pet.intimate > 1000)
- pd->pet.intimate = 1000;
- status_calc_pet(pd, 0);
- pd->pet.hungry += pd->petDB->fullness;
- if (pd->pet.hungry > 100)
- pd->pet.hungry = 100;
-
- clif_send_petdata(sd,pd,2,pd->pet.hungry);
- clif_send_petdata(sd,pd,1,pd->pet.intimate);
- clif_pet_food(sd,pd->petDB->FoodID,1);
-
- return 0;
+ int i,k;
+
+ k=pd->petDB->FoodID;
+ i=pc_search_inventory(sd,k);
+ if(i < 0) {
+ clif_pet_food(sd,k,0);
+ return 1;
+ }
+ pc_delitem(sd,i,1,0,0,LOG_TYPE_CONSUME);
+
+ if( pd->pet.hungry > 90 )
+ pet_set_intimate(pd, pd->pet.intimate - pd->petDB->r_full);
+ else
+ {
+ if( battle_config.pet_friendly_rate != 100 )
+ k = (pd->petDB->r_hungry * battle_config.pet_friendly_rate)/100;
+ else
+ k = pd->petDB->r_hungry;
+ if( pd->pet.hungry > 75 )
+ {
+ k = k >> 1;
+ if( k <= 0 )
+ k = 1;
+ }
+ pet_set_intimate(pd, pd->pet.intimate + k);
+ }
+ if( pd->pet.intimate <= 0 )
+ {
+ pd->pet.intimate = 0;
+ pet_stop_attack(pd);
+ pd->status.speed = pd->db->status.speed;
+ }
+ else if( pd->pet.intimate > 1000 )
+ pd->pet.intimate = 1000;
+ status_calc_pet(pd, 0);
+ pd->pet.hungry += pd->petDB->fullness;
+ if( pd->pet.hungry > 100 )
+ pd->pet.hungry = 100;
+
+ clif_send_petdata(sd,pd,2,pd->pet.hungry);
+ clif_send_petdata(sd,pd,1,pd->pet.intimate);
+ clif_pet_food(sd,pd->petDB->FoodID,1);
+
+ return 0;
}
static int pet_randomwalk(struct pet_data *pd,unsigned int tick)
{
- const int retrycount=20;
-
- nullpo_ret(pd);
-
- Assert((pd->msd == 0) || (pd->msd->pd == pd));
-
- if (DIFF_TICK(pd->next_walktime,tick) < 0 && unit_can_move(&pd->bl)) {
- int i,x,y,c,d=12-pd->move_fail_count;
- if (d<5) d=5;
- for (i=0; i<retrycount; i++) {
- int r=rnd();
- x=pd->bl.x+r%(d*2+1)-d;
- y=pd->bl.y+r/(d*2+1)%(d*2+1)-d;
- if (map_getcell(pd->bl.m,x,y,CELL_CHKPASS) && unit_walktoxy(&pd->bl,x,y,0)) {
- pd->move_fail_count=0;
- break;
- }
- if (i+1>=retrycount) {
- pd->move_fail_count++;
- if (pd->move_fail_count>1000) {
- ShowWarning("PET can't move. hold position %d, class = %d\n",pd->bl.id,pd->pet.class_);
- pd->move_fail_count=0;
- pd->ud.canmove_tick = tick + 60000;
- return 0;
- }
- }
- }
- for (i=c=0; i<pd->ud.walkpath.path_len; i++) {
- if (pd->ud.walkpath.path[i]&1)
- c+=pd->status.speed*14/10;
- else
- c+=pd->status.speed;
- }
- pd->next_walktime = tick+rnd()%3000+3000+c;
-
- return 1;
- }
- return 0;
+ const int retrycount=20;
+
+ nullpo_ret(pd);
+
+ Assert((pd->msd == 0) || (pd->msd->pd == pd));
+
+ if(DIFF_TICK(pd->next_walktime,tick) < 0 && unit_can_move(&pd->bl)) {
+ int i,x,y,c,d=12-pd->move_fail_count;
+ if(d<5) d=5;
+ for(i=0;i<retrycount;i++){
+ int r=rnd();
+ x=pd->bl.x+r%(d*2+1)-d;
+ y=pd->bl.y+r/(d*2+1)%(d*2+1)-d;
+ if(map_getcell(pd->bl.m,x,y,CELL_CHKPASS) && unit_walktoxy(&pd->bl,x,y,0)){
+ pd->move_fail_count=0;
+ break;
+ }
+ if(i+1>=retrycount){
+ pd->move_fail_count++;
+ if(pd->move_fail_count>1000){
+ ShowWarning("PET can't move. hold position %d, class = %d\n",pd->bl.id,pd->pet.class_);
+ pd->move_fail_count=0;
+ pd->ud.canmove_tick = tick + 60000;
+ return 0;
+ }
+ }
+ }
+ for(i=c=0;i<pd->ud.walkpath.path_len;i++){
+ if(pd->ud.walkpath.path[i]&1)
+ c+=pd->status.speed*14/10;
+ else
+ c+=pd->status.speed;
+ }
+ pd->next_walktime = tick+rnd()%3000+3000+c;
+
+ return 1;
+ }
+ return 0;
}
static int pet_ai_sub_hard(struct pet_data *pd, struct map_session_data *sd, unsigned int tick)
{
- struct block_list *target = NULL;
-
- if (pd->bl.prev == NULL || sd == NULL || sd->bl.prev == NULL)
- return 0;
-
- if (DIFF_TICK(tick,pd->last_thinktime) < MIN_PETTHINKTIME)
- return 0;
- pd->last_thinktime=tick;
-
- if (pd->ud.attacktimer != INVALID_TIMER || pd->ud.skilltimer != INVALID_TIMER || pd->bl.m != sd->bl.m)
- return 0;
-
- if (pd->ud.walktimer != INVALID_TIMER && pd->ud.walkpath.path_pos <= 2)
- return 0; //No thinking when you just started to walk.
-
- if (pd->pet.intimate <= 0) {
- //Pet should just... well, random walk.
- pet_randomwalk(pd,tick);
- return 0;
- }
-
- if (!check_distance_bl(&sd->bl, &pd->bl, pd->db->range3)) {
- //Master too far, chase.
- if (pd->target_id)
- pet_unlocktarget(pd);
- if (pd->ud.walktimer != INVALID_TIMER && pd->ud.target == sd->bl.id)
- return 0; //Already walking to him
- if (DIFF_TICK(tick, pd->ud.canmove_tick) < 0)
- return 0; //Can't move yet.
- pd->status.speed = (sd->battle_status.speed>>1);
- if (pd->status.speed <= 0)
- pd->status.speed = 1;
- if (!unit_walktobl(&pd->bl, &sd->bl, 3, 0))
- pet_randomwalk(pd,tick);
- return 0;
- }
-
- //Return speed to normal.
- if (pd->status.speed != pd->petDB->speed) {
- if (pd->ud.walktimer != INVALID_TIMER)
- return 0; //Wait until the pet finishes walking back to master.
- pd->status.speed = pd->petDB->speed;
- pd->ud.state.change_walk_target = pd->ud.state.speed_changed = 1;
- }
-
- if (pd->target_id) {
- target= map_id2bl(pd->target_id);
- if (!target || pd->bl.m != target->m || status_isdead(target) ||
- !check_distance_bl(&pd->bl, target, pd->db->range3)) {
- target = NULL;
- pet_unlocktarget(pd);
- }
- }
-
- if (!target && pd->loot && pd->loot->count < pd->loot->max && DIFF_TICK(tick,pd->ud.canact_tick)>0) {
- //Use half the pet's range of sight.
- map_foreachinrange(pet_ai_sub_hard_lootsearch,&pd->bl,
- pd->db->range2/2, BL_ITEM,pd,&target);
- }
-
- if (!target) {
- //Just walk around.
- if (check_distance_bl(&sd->bl, &pd->bl, 3))
- return 0; //Already next to master.
-
- if (pd->ud.walktimer != INVALID_TIMER && check_distance_blxy(&sd->bl, pd->ud.to_x,pd->ud.to_y, 3))
- return 0; //Already walking to him
-
- unit_calc_pos(&pd->bl, sd->bl.x, sd->bl.y, sd->ud.dir);
- if (!unit_walktoxy(&pd->bl,pd->ud.to_x,pd->ud.to_y,0))
- pet_randomwalk(pd,tick);
-
- return 0;
- }
-
- if (pd->ud.target == target->id &&
- (pd->ud.attacktimer != INVALID_TIMER || pd->ud.walktimer != INVALID_TIMER))
- return 0; //Target already locked.
-
- if (target->type != BL_ITEM) {
- //enemy targetted
- if (!battle_check_range(&pd->bl,target,pd->status.rhw.range)) {
- //Chase
- if (!unit_walktobl(&pd->bl, target, pd->status.rhw.range, 2))
- pet_unlocktarget(pd); //Unreachable target.
- return 0;
- }
- //Continuous attack.
- unit_attack(&pd->bl, pd->target_id, 1);
- } else { //Item Targeted, attempt loot
- if (!check_distance_bl(&pd->bl, target, 1)) {
- //Out of range
- if (!unit_walktobl(&pd->bl, target, 1, 1)) //Unreachable target.
- pet_unlocktarget(pd);
- return 0;
- } else {
- struct flooritem_data *fitem = (struct flooritem_data *)target;
- if (pd->loot->count < pd->loot->max) {
- memcpy(&pd->loot->item[pd->loot->count++],&fitem->item_data,sizeof(pd->loot->item[0]));
- pd->loot->weight += itemdb_weight(fitem->item_data.nameid)*fitem->item_data.amount;
- map_clearflooritem(target);
- }
- //Target is unlocked regardless of whether it was picked or not.
- pet_unlocktarget(pd);
- }
- }
- return 0;
+ struct block_list *target = NULL;
+
+ if(pd->bl.prev == NULL || sd == NULL || sd->bl.prev == NULL)
+ return 0;
+
+ if(DIFF_TICK(tick,pd->last_thinktime) < MIN_PETTHINKTIME)
+ return 0;
+ pd->last_thinktime=tick;
+
+ if(pd->ud.attacktimer != INVALID_TIMER || pd->ud.skilltimer != INVALID_TIMER || pd->bl.m != sd->bl.m)
+ return 0;
+
+ if(pd->ud.walktimer != INVALID_TIMER && pd->ud.walkpath.path_pos <= 2)
+ return 0; //No thinking when you just started to walk.
+
+ if(pd->pet.intimate <= 0) {
+ //Pet should just... well, random walk.
+ pet_randomwalk(pd,tick);
+ return 0;
+ }
+
+ if (!check_distance_bl(&sd->bl, &pd->bl, pd->db->range3)) {
+ //Master too far, chase.
+ if(pd->target_id)
+ pet_unlocktarget(pd);
+ if(pd->ud.walktimer != INVALID_TIMER && pd->ud.target == sd->bl.id)
+ return 0; //Already walking to him
+ if (DIFF_TICK(tick, pd->ud.canmove_tick) < 0)
+ return 0; //Can't move yet.
+ pd->status.speed = (sd->battle_status.speed>>1);
+ if(pd->status.speed <= 0)
+ pd->status.speed = 1;
+ if (!unit_walktobl(&pd->bl, &sd->bl, 3, 0))
+ pet_randomwalk(pd,tick);
+ return 0;
+ }
+
+ //Return speed to normal.
+ if (pd->status.speed != pd->petDB->speed) {
+ if (pd->ud.walktimer != INVALID_TIMER)
+ return 0; //Wait until the pet finishes walking back to master.
+ pd->status.speed = pd->petDB->speed;
+ pd->ud.state.change_walk_target = pd->ud.state.speed_changed = 1;
+ }
+
+ if (pd->target_id) {
+ target= map_id2bl(pd->target_id);
+ if (!target || pd->bl.m != target->m || status_isdead(target) ||
+ !check_distance_bl(&pd->bl, target, pd->db->range3))
+ {
+ target = NULL;
+ pet_unlocktarget(pd);
+ }
+ }
+
+ if(!target && pd->loot && pd->loot->count < pd->loot->max && DIFF_TICK(tick,pd->ud.canact_tick)>0) {
+ //Use half the pet's range of sight.
+ map_foreachinrange(pet_ai_sub_hard_lootsearch,&pd->bl,
+ pd->db->range2/2, BL_ITEM,pd,&target);
+ }
+
+ if (!target) {
+ //Just walk around.
+ if (check_distance_bl(&sd->bl, &pd->bl, 3))
+ return 0; //Already next to master.
+
+ if(pd->ud.walktimer != INVALID_TIMER && check_distance_blxy(&sd->bl, pd->ud.to_x,pd->ud.to_y, 3))
+ return 0; //Already walking to him
+
+ unit_calc_pos(&pd->bl, sd->bl.x, sd->bl.y, sd->ud.dir);
+ if(!unit_walktoxy(&pd->bl,pd->ud.to_x,pd->ud.to_y,0))
+ pet_randomwalk(pd,tick);
+
+ return 0;
+ }
+
+ if(pd->ud.target == target->id &&
+ (pd->ud.attacktimer != INVALID_TIMER || pd->ud.walktimer != INVALID_TIMER))
+ return 0; //Target already locked.
+
+ if (target->type != BL_ITEM)
+ { //enemy targetted
+ if(!battle_check_range(&pd->bl,target,pd->status.rhw.range))
+ { //Chase
+ if(!unit_walktobl(&pd->bl, target, pd->status.rhw.range, 2))
+ pet_unlocktarget(pd); //Unreachable target.
+ return 0;
+ }
+ //Continuous attack.
+ unit_attack(&pd->bl, pd->target_id, 1);
+ } else { //Item Targeted, attempt loot
+ if (!check_distance_bl(&pd->bl, target, 1))
+ { //Out of range
+ if(!unit_walktobl(&pd->bl, target, 1, 1)) //Unreachable target.
+ pet_unlocktarget(pd);
+ return 0;
+ } else{
+ struct flooritem_data *fitem = (struct flooritem_data *)target;
+ if(pd->loot->count < pd->loot->max){
+ memcpy(&pd->loot->item[pd->loot->count++],&fitem->item_data,sizeof(pd->loot->item[0]));
+ pd->loot->weight += itemdb_weight(fitem->item_data.nameid)*fitem->item_data.amount;
+ map_clearflooritem(target);
+ }
+ //Target is unlocked regardless of whether it was picked or not.
+ pet_unlocktarget(pd);
+ }
+ }
+ return 0;
}
static int pet_ai_sub_foreachclient(struct map_session_data *sd,va_list ap)
{
- unsigned int tick = va_arg(ap,unsigned int);
- if (sd->status.pet_id && sd->pd)
- pet_ai_sub_hard(sd->pd,sd,tick);
+ unsigned int tick = va_arg(ap,unsigned int);
+ if(sd->status.pet_id && sd->pd)
+ pet_ai_sub_hard(sd->pd,sd,tick);
- return 0;
+ return 0;
}
static int pet_ai_hard(int tid, unsigned int tick, int id, intptr_t data)
{
- map_foreachpc(pet_ai_sub_foreachclient,tick);
+ map_foreachpc(pet_ai_sub_foreachclient,tick);
- return 0;
+ return 0;
}
static int pet_ai_sub_hard_lootsearch(struct block_list *bl,va_list ap)
{
- struct pet_data *pd;
- struct flooritem_data *fitem = (struct flooritem_data *)bl;
- struct block_list **target;
- int sd_charid =0;
-
- pd=va_arg(ap,struct pet_data *);
- target=va_arg(ap,struct block_list **);
-
- sd_charid = fitem->first_get_charid;
-
- if (sd_charid && sd_charid != pd->msd->status.char_id)
- return 0;
-
- if (unit_can_reach_bl(&pd->bl,bl, pd->db->range2, 1, NULL, NULL) &&
- ((*target) == NULL || //New target closer than previous one.
- !check_distance_bl(&pd->bl, *target, distance_bl(&pd->bl, bl)))) {
- (*target) = bl;
- pd->target_id = bl->id;
- return 1;
- }
-
- return 0;
+ struct pet_data* pd;
+ struct flooritem_data *fitem = (struct flooritem_data *)bl;
+ struct block_list **target;
+ int sd_charid =0;
+
+ pd=va_arg(ap,struct pet_data *);
+ target=va_arg(ap,struct block_list**);
+
+ sd_charid = fitem->first_get_charid;
+
+ if(sd_charid && sd_charid != pd->msd->status.char_id)
+ return 0;
+
+ if(unit_can_reach_bl(&pd->bl,bl, pd->db->range2, 1, NULL, NULL) &&
+ ((*target) == NULL || //New target closer than previous one.
+ !check_distance_bl(&pd->bl, *target, distance_bl(&pd->bl, bl))))
+ {
+ (*target) = bl;
+ pd->target_id = bl->id;
+ return 1;
+ }
+
+ return 0;
}
static int pet_delay_item_drop(int tid, unsigned int tick, int id, intptr_t data)
{
- struct item_drop_list *list;
- struct item_drop *ditem, *ditem_prev;
- list=(struct item_drop_list *)data;
- ditem = list->item;
- while (ditem) {
- map_addflooritem(&ditem->item_data,ditem->item_data.amount,
- list->m,list->x,list->y,
- list->first_charid,list->second_charid,list->third_charid,0);
- ditem_prev = ditem;
- ditem = ditem->next;
- ers_free(item_drop_ers, ditem_prev);
- }
- ers_free(item_drop_list_ers, list);
- return 0;
+ struct item_drop_list *list;
+ struct item_drop *ditem, *ditem_prev;
+ list=(struct item_drop_list *)data;
+ ditem = list->item;
+ while (ditem) {
+ map_addflooritem(&ditem->item_data,ditem->item_data.amount,
+ list->m,list->x,list->y,
+ list->first_charid,list->second_charid,list->third_charid,0);
+ ditem_prev = ditem;
+ ditem = ditem->next;
+ ers_free(item_drop_ers, ditem_prev);
+ }
+ ers_free(item_drop_list_ers, list);
+ return 0;
}
int pet_lootitem_drop(struct pet_data *pd,struct map_session_data *sd)
{
- int i,flag=0;
- struct item_drop_list *dlist;
- struct item_drop *ditem;
- struct item *it;
- if (!pd || !pd->loot || !pd->loot->count)
- return 0;
- dlist = ers_alloc(item_drop_list_ers, struct item_drop_list);
- dlist->m = pd->bl.m;
- dlist->x = pd->bl.x;
- dlist->y = pd->bl.y;
- dlist->first_charid = 0;
- dlist->second_charid = 0;
- dlist->third_charid = 0;
- dlist->item = NULL;
-
- for (i=0; i<pd->loot->count; i++) {
- it = &pd->loot->item[i];
- if (sd) {
- if ((flag = pc_additem(sd,it,it->amount,LOG_TYPE_PICKDROP_PLAYER))) {
- clif_additem(sd,0,0,flag);
- ditem = ers_alloc(item_drop_ers, struct item_drop);
- memcpy(&ditem->item_data, it, sizeof(struct item));
- ditem->next = dlist->item;
- dlist->item = ditem;
- }
- } else {
- ditem = ers_alloc(item_drop_ers, struct item_drop);
- memcpy(&ditem->item_data, it, sizeof(struct item));
- ditem->next = dlist->item;
- dlist->item = ditem;
- }
- }
- //The smart thing to do is use pd->loot->max (thanks for pointing it out, Shinomori)
- memset(pd->loot->item,0,pd->loot->max * sizeof(struct item));
- pd->loot->count = 0;
- pd->loot->weight = 0;
- pd->ud.canact_tick = gettick()+10000; //prevent picked up during 10*1000ms
-
- if (dlist->item)
- add_timer(gettick()+540,pet_delay_item_drop,0,(intptr_t)dlist);
- else
- ers_free(item_drop_list_ers, dlist);
- return 1;
+ int i,flag=0;
+ struct item_drop_list *dlist;
+ struct item_drop *ditem;
+ struct item *it;
+ if(!pd || !pd->loot || !pd->loot->count)
+ return 0;
+ dlist = ers_alloc(item_drop_list_ers, struct item_drop_list);
+ dlist->m = pd->bl.m;
+ dlist->x = pd->bl.x;
+ dlist->y = pd->bl.y;
+ dlist->first_charid = 0;
+ dlist->second_charid = 0;
+ dlist->third_charid = 0;
+ dlist->item = NULL;
+
+ for(i=0;i<pd->loot->count;i++) {
+ it = &pd->loot->item[i];
+ if(sd){
+ if((flag = pc_additem(sd,it,it->amount,LOG_TYPE_PICKDROP_PLAYER))){
+ clif_additem(sd,0,0,flag);
+ ditem = ers_alloc(item_drop_ers, struct item_drop);
+ memcpy(&ditem->item_data, it, sizeof(struct item));
+ ditem->next = dlist->item;
+ dlist->item = ditem;
+ }
+ }
+ else {
+ ditem = ers_alloc(item_drop_ers, struct item_drop);
+ memcpy(&ditem->item_data, it, sizeof(struct item));
+ ditem->next = dlist->item;
+ dlist->item = ditem;
+ }
+ }
+ //The smart thing to do is use pd->loot->max (thanks for pointing it out, Shinomori)
+ memset(pd->loot->item,0,pd->loot->max * sizeof(struct item));
+ pd->loot->count = 0;
+ pd->loot->weight = 0;
+ pd->ud.canact_tick = gettick()+10000; //prevent picked up during 10*1000ms
+
+ if (dlist->item)
+ add_timer(gettick()+540,pet_delay_item_drop,0,(intptr_t)dlist);
+ else
+ ers_free(item_drop_list_ers, dlist);
+ return 1;
}
/*==========================================
* pet bonus giving skills [Valaris] / Rewritten by [Skotlex]
- *------------------------------------------*/
+ *------------------------------------------*/
int pet_skill_bonus_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- struct map_session_data *sd=map_id2sd(id);
- struct pet_data *pd;
- int bonus;
- int timer = 0;
-
- if (sd == NULL || sd->pd==NULL || sd->pd->bonus == NULL)
- return 1;
-
- pd=sd->pd;
-
- if (pd->bonus->timer != tid) {
- ShowError("pet_skill_bonus_timer %d != %d\n",pd->bonus->timer,tid);
- pd->bonus->timer = INVALID_TIMER;
- return 0;
- }
-
- // determine the time for the next timer
- if (pd->state.skillbonus && pd->bonus->delay > 0) {
- bonus = 0;
- timer = pd->bonus->delay*1000; // the duration until pet bonuses will be reactivated again
- } else if (pd->pet.intimate) {
- bonus = 1;
- timer = pd->bonus->duration*1000; // the duration for pet bonuses to be in effect
- } else { //Lost pet...
- pd->bonus->timer = INVALID_TIMER;
- return 0;
- }
-
- if (pd->state.skillbonus != bonus) {
- pd->state.skillbonus = bonus;
- status_calc_pc(sd, 0);
- }
- // wait for the next timer
- pd->bonus->timer=add_timer(tick+timer,pet_skill_bonus_timer,sd->bl.id,0);
- return 0;
+ struct map_session_data *sd=map_id2sd(id);
+ struct pet_data *pd;
+ int bonus;
+ int timer = 0;
+
+ if(sd == NULL || sd->pd==NULL || sd->pd->bonus == NULL)
+ return 1;
+
+ pd=sd->pd;
+
+ if(pd->bonus->timer != tid) {
+ ShowError("pet_skill_bonus_timer %d != %d\n",pd->bonus->timer,tid);
+ pd->bonus->timer = INVALID_TIMER;
+ return 0;
+ }
+
+ // determine the time for the next timer
+ if (pd->state.skillbonus && pd->bonus->delay > 0) {
+ bonus = 0;
+ timer = pd->bonus->delay*1000; // the duration until pet bonuses will be reactivated again
+ } else if (pd->pet.intimate) {
+ bonus = 1;
+ timer = pd->bonus->duration*1000; // the duration for pet bonuses to be in effect
+ } else { //Lost pet...
+ pd->bonus->timer = INVALID_TIMER;
+ return 0;
+ }
+
+ if (pd->state.skillbonus != bonus) {
+ pd->state.skillbonus = bonus;
+ status_calc_pc(sd, 0);
+ }
+ // wait for the next timer
+ pd->bonus->timer=add_timer(tick+timer,pet_skill_bonus_timer,sd->bl.id,0);
+ return 0;
}
/*==========================================
* pet recovery skills [Valaris] / Rewritten by [Skotlex]
- *------------------------------------------*/
+ *------------------------------------------*/
int pet_recovery_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- struct map_session_data *sd=map_id2sd(id);
- struct pet_data *pd;
-
- if (sd==NULL || sd->pd == NULL || sd->pd->recovery == NULL)
- return 1;
-
- pd=sd->pd;
-
- if (pd->recovery->timer != tid) {
- ShowError("pet_recovery_timer %d != %d\n",pd->recovery->timer,tid);
- return 0;
- }
-
- if (sd->sc.data[pd->recovery->type]) {
- //Display a heal animation?
- //Detoxify is chosen for now.
- clif_skill_nodamage(&pd->bl,&sd->bl,TF_DETOXIFY,1,1);
- status_change_end(&sd->bl, pd->recovery->type, INVALID_TIMER);
- clif_emotion(&pd->bl, E_OK);
- }
-
- pd->recovery->timer = INVALID_TIMER;
-
- return 0;
+ struct map_session_data *sd=map_id2sd(id);
+ struct pet_data *pd;
+
+ if(sd==NULL || sd->pd == NULL || sd->pd->recovery == NULL)
+ return 1;
+
+ pd=sd->pd;
+
+ if(pd->recovery->timer != tid) {
+ ShowError("pet_recovery_timer %d != %d\n",pd->recovery->timer,tid);
+ return 0;
+ }
+
+ if(sd->sc.data[pd->recovery->type])
+ { //Display a heal animation?
+ //Detoxify is chosen for now.
+ clif_skill_nodamage(&pd->bl,&sd->bl,TF_DETOXIFY,1,1);
+ status_change_end(&sd->bl, pd->recovery->type, INVALID_TIMER);
+ clif_emotion(&pd->bl, E_OK);
+ }
+
+ pd->recovery->timer = INVALID_TIMER;
+
+ return 0;
}
int pet_heal_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- struct map_session_data *sd=map_id2sd(id);
- struct status_data *status;
- struct pet_data *pd;
- unsigned int rate = 100;
-
- if (sd==NULL || sd->pd == NULL || sd->pd->s_skill == NULL)
- return 1;
-
- pd=sd->pd;
-
- if (pd->s_skill->timer != tid) {
- ShowError("pet_heal_timer %d != %d\n",pd->s_skill->timer,tid);
- return 0;
- }
-
- status = status_get_status_data(&sd->bl);
-
- if (pc_isdead(sd) ||
- (rate = get_percentage(status->sp, status->max_sp)) > pd->s_skill->sp ||
- (rate = get_percentage(status->hp, status->max_hp)) > pd->s_skill->hp ||
- (rate = (pd->ud.skilltimer != INVALID_TIMER)) //Another skill is in effect
- ) { //Wait (how long? 1 sec for every 10% of remaining)
- pd->s_skill->timer=add_timer(gettick()+(rate>10?rate:10)*100,pet_heal_timer,sd->bl.id,0);
- return 0;
- }
- pet_stop_attack(pd);
- pet_stop_walking(pd,1);
- clif_skill_nodamage(&pd->bl,&sd->bl,AL_HEAL,pd->s_skill->lv,1);
- status_heal(&sd->bl, pd->s_skill->lv,0, 0);
- pd->s_skill->timer=add_timer(tick+pd->s_skill->delay*1000,pet_heal_timer,sd->bl.id,0);
- return 0;
+ struct map_session_data *sd=map_id2sd(id);
+ struct status_data *status;
+ struct pet_data *pd;
+ unsigned int rate = 100;
+
+ if(sd==NULL || sd->pd == NULL || sd->pd->s_skill == NULL)
+ return 1;
+
+ pd=sd->pd;
+
+ if(pd->s_skill->timer != tid) {
+ ShowError("pet_heal_timer %d != %d\n",pd->s_skill->timer,tid);
+ return 0;
+ }
+
+ status = status_get_status_data(&sd->bl);
+
+ if(pc_isdead(sd) ||
+ (rate = get_percentage(status->sp, status->max_sp)) > pd->s_skill->sp ||
+ (rate = get_percentage(status->hp, status->max_hp)) > pd->s_skill->hp ||
+ (rate = (pd->ud.skilltimer != INVALID_TIMER)) //Another skill is in effect
+ ) { //Wait (how long? 1 sec for every 10% of remaining)
+ pd->s_skill->timer=add_timer(gettick()+(rate>10?rate:10)*100,pet_heal_timer,sd->bl.id,0);
+ return 0;
+ }
+ pet_stop_attack(pd);
+ pet_stop_walking(pd,1);
+ clif_skill_nodamage(&pd->bl,&sd->bl,AL_HEAL,pd->s_skill->lv,1);
+ status_heal(&sd->bl, pd->s_skill->lv,0, 0);
+ pd->s_skill->timer=add_timer(tick+pd->s_skill->delay*1000,pet_heal_timer,sd->bl.id,0);
+ return 0;
}
/*==========================================
* pet support skills [Skotlex]
- *------------------------------------------*/
+ *------------------------------------------*/
int pet_skill_support_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- struct map_session_data *sd=map_id2sd(id);
- struct pet_data *pd;
- struct status_data *status;
- short rate = 100;
- if (sd==NULL || sd->pd == NULL || sd->pd->s_skill == NULL)
- return 1;
-
- pd=sd->pd;
-
- if (pd->s_skill->timer != tid) {
- ShowError("pet_skill_support_timer %d != %d\n",pd->s_skill->timer,tid);
- return 0;
- }
-
- status = status_get_status_data(&sd->bl);
-
- if (DIFF_TICK(pd->ud.canact_tick, tick) > 0) {
- //Wait until the pet can act again.
- pd->s_skill->timer=add_timer(pd->ud.canact_tick,pet_skill_support_timer,sd->bl.id,0);
- return 0;
- }
-
- if (pc_isdead(sd) ||
- (rate = get_percentage(status->sp, status->max_sp)) > pd->s_skill->sp ||
- (rate = get_percentage(status->hp, status->max_hp)) > pd->s_skill->hp ||
- (rate = (pd->ud.skilltimer != INVALID_TIMER)) //Another skill is in effect
- ) { //Wait (how long? 1 sec for every 10% of remaining)
- pd->s_skill->timer=add_timer(tick+(rate>10?rate:10)*100,pet_skill_support_timer,sd->bl.id,0);
- return 0;
- }
-
- pet_stop_attack(pd);
- pet_stop_walking(pd,1);
- pd->s_skill->timer=add_timer(tick+pd->s_skill->delay*1000,pet_skill_support_timer,sd->bl.id,0);
- if (skill_get_inf(pd->s_skill->id) & INF_GROUND_SKILL)
- unit_skilluse_pos(&pd->bl, sd->bl.x, sd->bl.y, pd->s_skill->id, pd->s_skill->lv);
- else
- unit_skilluse_id(&pd->bl, sd->bl.id, pd->s_skill->id, pd->s_skill->lv);
- return 0;
+ struct map_session_data *sd=map_id2sd(id);
+ struct pet_data *pd;
+ struct status_data *status;
+ short rate = 100;
+ if(sd==NULL || sd->pd == NULL || sd->pd->s_skill == NULL)
+ return 1;
+
+ pd=sd->pd;
+
+ if(pd->s_skill->timer != tid) {
+ ShowError("pet_skill_support_timer %d != %d\n",pd->s_skill->timer,tid);
+ return 0;
+ }
+
+ status = status_get_status_data(&sd->bl);
+
+ if (DIFF_TICK(pd->ud.canact_tick, tick) > 0)
+ { //Wait until the pet can act again.
+ pd->s_skill->timer=add_timer(pd->ud.canact_tick,pet_skill_support_timer,sd->bl.id,0);
+ return 0;
+ }
+
+ if(pc_isdead(sd) ||
+ (rate = get_percentage(status->sp, status->max_sp)) > pd->s_skill->sp ||
+ (rate = get_percentage(status->hp, status->max_hp)) > pd->s_skill->hp ||
+ (rate = (pd->ud.skilltimer != INVALID_TIMER)) //Another skill is in effect
+ ) { //Wait (how long? 1 sec for every 10% of remaining)
+ pd->s_skill->timer=add_timer(tick+(rate>10?rate:10)*100,pet_skill_support_timer,sd->bl.id,0);
+ return 0;
+ }
+
+ pet_stop_attack(pd);
+ pet_stop_walking(pd,1);
+ pd->s_skill->timer=add_timer(tick+pd->s_skill->delay*1000,pet_skill_support_timer,sd->bl.id,0);
+ if (skill_get_inf(pd->s_skill->id) & INF_GROUND_SKILL)
+ unit_skilluse_pos(&pd->bl, sd->bl.x, sd->bl.y, pd->s_skill->id, pd->s_skill->lv);
+ else
+ unit_skilluse_id(&pd->bl, sd->bl.id, pd->s_skill->id, pd->s_skill->lv);
+ return 0;
}
/*==========================================
* Pet read db data
* pet_db.txt
* pet_db2.txt
- *------------------------------------------*/
+ *------------------------------------------*/
int read_petdb()
{
- char *filename[] = {"pet_db.txt","pet_db2.txt"};
- FILE *fp;
- int nameid,i,j,k;
-
- // Remove any previous scripts in case reloaddb was invoked.
- for (j = 0; j < MAX_PET_DB; j++) {
- if (pet_db[j].pet_script) {
- script_free_code(pet_db[j].pet_script);
- pet_db[j].pet_script = NULL;
- }
- if (pet_db[j].equip_script) {
- script_free_code(pet_db[j].equip_script);
- pet_db[j].pet_script = NULL;
- }
- }
-
- // clear database
- memset(pet_db,0,sizeof(pet_db));
-
- j = 0; // entry counter
- for (i = 0; i < ARRAYLENGTH(filename); i++) {
- char line[1024];
- int lines, entries;
-
- sprintf(line, "%s/%s", db_path, filename[i]);
- fp=fopen(line,"r");
- if (fp == NULL) {
- if (i == 0)
- ShowError("can't read %s\n",line);
- continue;
- }
-
- lines = entries = 0;
- while (fgets(line, sizeof(line), fp) && j < MAX_PET_DB) {
- char *str[22], *p;
- lines++;
-
- if (line[0] == '/' && line[1] == '/')
- continue;
- memset(str, 0, sizeof(str));
- p = line;
- while (ISSPACE(*p))
- ++p;
- if (*p == '\0')
- continue; // empty line
- for (k = 0; k < 20; ++k) {
- str[k] = p;
- p = strchr(p,',');
- if (p == NULL)
- break; // comma not found
- *p = '\0';
- ++p;
- }
-
- if (p == NULL) {
- ShowError("read_petdb: Insufficient columns in line %d, skipping.\n", lines);
- continue;
- }
-
- // Pet Script
- if (*p != '{') {
- ShowError("read_petdb: Invalid format (Pet Script column) in line %d, skipping.\n", lines);
- continue;
- }
-
- str[20] = p;
- p = strstr(p+1,"},");
- if (p == NULL) {
- ShowError("read_petdb: Invalid format (Pet Script column) in line %d, skipping.\n", lines);
- continue;
- }
- p[1] = '\0';
- p += 2;
-
- // Equip Script
- if (*p != '{') {
- ShowError("read_petdb: Invalid format (Equip Script column) in line %d, skipping.\n", lines);
- continue;
- }
- str[21] = p;
-
- if ((nameid = atoi(str[0])) <= 0)
- continue;
-
- if (!mobdb_checkid(nameid)) {
- ShowWarning("pet_db reading: Invalid mob-class %d, pet not read.\n", nameid);
- continue;
- }
-
- pet_db[j].class_ = nameid;
- safestrncpy(pet_db[j].name,str[1],NAME_LENGTH);
- safestrncpy(pet_db[j].jname,str[2],NAME_LENGTH);
- pet_db[j].itemID=atoi(str[3]);
- pet_db[j].EggID=atoi(str[4]);
- pet_db[j].AcceID=atoi(str[5]);
- pet_db[j].FoodID=atoi(str[6]);
- pet_db[j].fullness=atoi(str[7]);
- pet_db[j].hungry_delay=atoi(str[8])*1000;
- pet_db[j].r_hungry=atoi(str[9]);
- if (pet_db[j].r_hungry <= 0)
- pet_db[j].r_hungry=1;
- pet_db[j].r_full=atoi(str[10]);
- pet_db[j].intimate=atoi(str[11]);
- pet_db[j].die=atoi(str[12]);
- pet_db[j].capture=atoi(str[13]);
- pet_db[j].speed=atoi(str[14]);
- pet_db[j].s_perfor=(char)atoi(str[15]);
- pet_db[j].talk_convert_class=atoi(str[16]);
- pet_db[j].attack_rate=atoi(str[17]);
- pet_db[j].defence_attack_rate=atoi(str[18]);
- pet_db[j].change_target_rate=atoi(str[19]);
- pet_db[j].pet_script = NULL;
- pet_db[j].equip_script = NULL;
-
- if (*str[20])
- pet_db[j].pet_script = parse_script(str[20], filename[i], lines, 0);
- if (*str[21])
- pet_db[j].equip_script = parse_script(str[21], filename[i], lines, 0);
-
- j++;
- entries++;
- }
-
- if (j >= MAX_PET_DB)
- ShowWarning("read_petdb: Reached max number of pets [%d]. Remaining pets were not read.\n ", MAX_PET_DB);
- fclose(fp);
- ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' pets in '"CL_WHITE"%s"CL_RESET"'.\n", entries, filename[i]);
- }
- return 0;
+ char* filename[] = {"pet_db.txt","pet_db2.txt"};
+ FILE *fp;
+ int nameid,i,j,k;
+
+ // Remove any previous scripts in case reloaddb was invoked.
+ for( j = 0; j < MAX_PET_DB; j++ )
+ {
+ if( pet_db[j].pet_script )
+ {
+ script_free_code(pet_db[j].pet_script);
+ pet_db[j].pet_script = NULL;
+ }
+ if( pet_db[j].equip_script )
+ {
+ script_free_code(pet_db[j].equip_script);
+ pet_db[j].pet_script = NULL;
+ }
+ }
+
+ // clear database
+ memset(pet_db,0,sizeof(pet_db));
+
+ j = 0; // entry counter
+ for( i = 0; i < ARRAYLENGTH(filename); i++ )
+ {
+ char line[1024];
+ int lines, entries;
+
+ sprintf(line, "%s/%s", db_path, filename[i]);
+ fp=fopen(line,"r");
+ if( fp == NULL )
+ {
+ if( i == 0 )
+ ShowError("can't read %s\n",line);
+ continue;
+ }
+
+ lines = entries = 0;
+ while( fgets(line, sizeof(line), fp) && j < MAX_PET_DB )
+ {
+ char *str[22], *p;
+ lines++;
+
+ if(line[0] == '/' && line[1] == '/')
+ continue;
+ memset(str, 0, sizeof(str));
+ p = line;
+ while( ISSPACE(*p) )
+ ++p;
+ if( *p == '\0' )
+ continue; // empty line
+ for( k = 0; k < 20; ++k )
+ {
+ str[k] = p;
+ p = strchr(p,',');
+ if( p == NULL )
+ break; // comma not found
+ *p = '\0';
+ ++p;
+ }
+
+ if( p == NULL )
+ {
+ ShowError("read_petdb: Insufficient columns in line %d, skipping.\n", lines);
+ continue;
+ }
+
+ // Pet Script
+ if( *p != '{' )
+ {
+ ShowError("read_petdb: Invalid format (Pet Script column) in line %d, skipping.\n", lines);
+ continue;
+ }
+
+ str[20] = p;
+ p = strstr(p+1,"},");
+ if( p == NULL )
+ {
+ ShowError("read_petdb: Invalid format (Pet Script column) in line %d, skipping.\n", lines);
+ continue;
+ }
+ p[1] = '\0';
+ p += 2;
+
+ // Equip Script
+ if( *p != '{' )
+ {
+ ShowError("read_petdb: Invalid format (Equip Script column) in line %d, skipping.\n", lines);
+ continue;
+ }
+ str[21] = p;
+
+ if( (nameid = atoi(str[0])) <= 0 )
+ continue;
+
+ if( !mobdb_checkid(nameid) )
+ {
+ ShowWarning("pet_db reading: Invalid mob-class %d, pet not read.\n", nameid);
+ continue;
+ }
+
+ pet_db[j].class_ = nameid;
+ safestrncpy(pet_db[j].name,str[1],NAME_LENGTH);
+ safestrncpy(pet_db[j].jname,str[2],NAME_LENGTH);
+ pet_db[j].itemID=atoi(str[3]);
+ pet_db[j].EggID=atoi(str[4]);
+ pet_db[j].AcceID=atoi(str[5]);
+ pet_db[j].FoodID=atoi(str[6]);
+ pet_db[j].fullness=atoi(str[7]);
+ pet_db[j].hungry_delay=atoi(str[8])*1000;
+ pet_db[j].r_hungry=atoi(str[9]);
+ if( pet_db[j].r_hungry <= 0 )
+ pet_db[j].r_hungry=1;
+ pet_db[j].r_full=atoi(str[10]);
+ pet_db[j].intimate=atoi(str[11]);
+ pet_db[j].die=atoi(str[12]);
+ pet_db[j].capture=atoi(str[13]);
+ pet_db[j].speed=atoi(str[14]);
+ pet_db[j].s_perfor=(char)atoi(str[15]);
+ pet_db[j].talk_convert_class=atoi(str[16]);
+ pet_db[j].attack_rate=atoi(str[17]);
+ pet_db[j].defence_attack_rate=atoi(str[18]);
+ pet_db[j].change_target_rate=atoi(str[19]);
+ pet_db[j].pet_script = NULL;
+ pet_db[j].equip_script = NULL;
+
+ if( *str[20] )
+ pet_db[j].pet_script = parse_script(str[20], filename[i], lines, 0);
+ if( *str[21] )
+ pet_db[j].equip_script = parse_script(str[21], filename[i], lines, 0);
+
+ j++;
+ entries++;
+ }
+
+ if( j >= MAX_PET_DB )
+ ShowWarning("read_petdb: Reached max number of pets [%d]. Remaining pets were not read.\n ", MAX_PET_DB);
+ fclose(fp);
+ ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' pets in '"CL_WHITE"%s"CL_RESET"'.\n", entries, filename[i]);
+ }
+ return 0;
}
/*==========================================
@@ -1330,37 +1349,40 @@ int read_petdb()
*------------------------------------------*/
int do_init_pet(void)
{
- read_petdb();
-
- item_drop_ers = ers_new(sizeof(struct item_drop),"pet.c::item_drop_ers",ERS_OPT_NONE);
- item_drop_list_ers = ers_new(sizeof(struct item_drop_list),"pet.c::item_drop_list_ers",ERS_OPT_NONE);
-
- 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_delay_item_drop,"pet_delay_item_drop");
- add_timer_func_list(pet_skill_support_timer, "pet_skill_support_timer"); // [Skotlex]
- add_timer_func_list(pet_recovery_timer,"pet_recovery_timer"); // [Valaris]
- add_timer_func_list(pet_heal_timer,"pet_heal_timer"); // [Valaris]
- add_timer_interval(gettick()+MIN_PETTHINKTIME,pet_ai_hard,0,0,MIN_PETTHINKTIME);
-
- return 0;
+ read_petdb();
+
+ item_drop_ers = ers_new(sizeof(struct item_drop),"pet.c::item_drop_ers",ERS_OPT_NONE);
+ item_drop_list_ers = ers_new(sizeof(struct item_drop_list),"pet.c::item_drop_list_ers",ERS_OPT_NONE);
+
+ 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_delay_item_drop,"pet_delay_item_drop");
+ add_timer_func_list(pet_skill_support_timer, "pet_skill_support_timer"); // [Skotlex]
+ add_timer_func_list(pet_recovery_timer,"pet_recovery_timer"); // [Valaris]
+ add_timer_func_list(pet_heal_timer,"pet_heal_timer"); // [Valaris]
+ add_timer_interval(gettick()+MIN_PETTHINKTIME,pet_ai_hard,0,0,MIN_PETTHINKTIME);
+
+ return 0;
}
int do_final_pet(void)
{
- int i;
- for (i = 0; i < MAX_PET_DB; i++) {
- if (pet_db[i].pet_script) {
- script_free_code(pet_db[i].pet_script);
- pet_db[i].pet_script = NULL;
- }
- if (pet_db[i].equip_script) {
- script_free_code(pet_db[i].equip_script);
- pet_db[i].equip_script = NULL;
- }
- }
- ers_destroy(item_drop_ers);
- ers_destroy(item_drop_list_ers);
- return 0;
+ int i;
+ for( i = 0; i < MAX_PET_DB; i++ )
+ {
+ if( pet_db[i].pet_script )
+ {
+ script_free_code(pet_db[i].pet_script);
+ pet_db[i].pet_script = NULL;
+ }
+ if( pet_db[i].equip_script )
+ {
+ script_free_code(pet_db[i].equip_script);
+ pet_db[i].equip_script = NULL;
+ }
+ }
+ ers_destroy(item_drop_ers);
+ ers_destroy(item_drop_list_ers);
+ return 0;
}
diff --git a/src/map/pet.h b/src/map/pet.h
index 3ac849111..b46f55229 100644
--- a/src/map/pet.h
+++ b/src/map/pet.h
@@ -4,98 +4,98 @@
#ifndef _PET_H_
#define _PET_H_
-#define MAX_PET_DB 300
-#define MAX_PETLOOT_SIZE 30
+#define MAX_PET_DB 300
+#define MAX_PETLOOT_SIZE 30
struct s_pet_db {
- short class_;
- char name[NAME_LENGTH],jname[NAME_LENGTH];
- short itemID;
- short EggID;
- short AcceID;
- short FoodID;
- int fullness;
- int hungry_delay;
- int r_hungry;
- int r_full;
- int intimate;
- int die;
- int capture;
- int speed;
- char s_perfor;
- int talk_convert_class;
- int attack_rate;
- int defence_attack_rate;
- int change_target_rate;
- struct script_code *equip_script;
- struct script_code *pet_script;
+ short class_;
+ char name[NAME_LENGTH],jname[NAME_LENGTH];
+ short itemID;
+ short EggID;
+ short AcceID;
+ short FoodID;
+ int fullness;
+ int hungry_delay;
+ int r_hungry;
+ int r_full;
+ int intimate;
+ int die;
+ int capture;
+ int speed;
+ char s_perfor;
+ int talk_convert_class;
+ int attack_rate;
+ int defence_attack_rate;
+ int change_target_rate;
+ struct script_code *equip_script;
+ struct script_code *pet_script;
};
extern struct s_pet_db pet_db[MAX_PET_DB];
enum { PET_CLASS,PET_CATCH,PET_EGG,PET_EQUIP,PET_FOOD };
struct pet_recovery { //Stat recovery
- enum sc_type type; //Status Change id
- unsigned short delay; //How long before curing (secs).
- int timer;
+ enum sc_type type; //Status Change id
+ unsigned short delay; //How long before curing (secs).
+ int timer;
};
struct pet_bonus {
- unsigned short type; //bStr, bVit?
- unsigned short val; //Qty
- unsigned short duration; //in secs
- unsigned short delay; //Time before RENEWAL_CAST (secs)
- int timer;
+ unsigned short type; //bStr, bVit?
+ unsigned short val; //Qty
+ unsigned short duration; //in secs
+ unsigned short delay; //Time before RENEWAL_CAST (secs)
+ int timer;
};
struct pet_skill_attack { //Attack Skill
- unsigned short id;
- unsigned short lv;
- unsigned short div_; //0 = Normal skill. >0 = Fixed damage (lv), fixed div_.
- unsigned short rate; //Base chance of skill ocurrance (10 = 10% of attacks)
- unsigned short bonusrate; //How being 100% loyal affects cast rate (10 = At 1000 intimacy->rate+10%
+ unsigned short id;
+ unsigned short lv;
+ unsigned short div_; //0 = Normal skill. >0 = Fixed damage (lv), fixed div_.
+ unsigned short rate; //Base chance of skill ocurrance (10 = 10% of attacks)
+ unsigned short bonusrate; //How being 100% loyal affects cast rate (10 = At 1000 intimacy->rate+10%
};
struct pet_skill_support { //Support Skill
- unsigned short id;
- unsigned short lv;
- unsigned short hp; //Max HP% for skill to trigger (50 -> 50% for Magnificat)
- unsigned short sp; //Max SP% for skill to trigger (100 = no check)
- unsigned short delay; //Time (secs) between being able to recast.
- int timer;
+ unsigned short id;
+ unsigned short lv;
+ unsigned short hp; //Max HP% for skill to trigger (50 -> 50% for Magnificat)
+ unsigned short sp; //Max SP% for skill to trigger (100 = no check)
+ unsigned short delay; //Time (secs) between being able to recast.
+ int timer;
};
struct pet_loot {
- struct item *item;
- unsigned short count;
- unsigned short weight;
- unsigned short max;
+ struct item *item;
+ unsigned short count;
+ unsigned short weight;
+ unsigned short max;
};
struct pet_data {
- struct block_list bl;
- struct unit_data ud;
- struct view_data vd;
- struct s_pet pet;
- struct status_data status;
- struct mob_db *db;
- struct s_pet_db *petDB;
- int pet_hungry_timer;
- int target_id;
- struct {
- unsigned skillbonus : 1;
- } state;
- int move_fail_count;
- unsigned int next_walktime,last_thinktime;
- short rate_fix; //Support rate as modified by intimacy (1000 = 100%) [Skotlex]
-
- struct pet_recovery *recovery;
- struct pet_bonus *bonus;
- struct pet_skill_attack *a_skill;
- struct pet_skill_support *s_skill;
- struct pet_loot *loot;
-
- struct map_session_data *msd;
+ struct block_list bl;
+ struct unit_data ud;
+ struct view_data vd;
+ struct s_pet pet;
+ struct status_data status;
+ struct mob_db *db;
+ struct s_pet_db *petDB;
+ int pet_hungry_timer;
+ int target_id;
+ struct {
+ unsigned skillbonus : 1;
+ } state;
+ int move_fail_count;
+ unsigned int next_walktime,last_thinktime;
+ short rate_fix; //Support rate as modified by intimacy (1000 = 100%) [Skotlex]
+
+ struct pet_recovery* recovery;
+ struct pet_bonus* bonus;
+ struct pet_skill_attack* a_skill;
+ struct pet_skill_support* s_skill;
+ struct pet_loot* loot;
+
+ struct map_session_data *msd;
};
@@ -117,7 +117,7 @@ int pet_catch_process2(struct map_session_data *sd,int target_id);
int pet_get_egg(int account_id,int pet_id,int flag);
int pet_menu(struct map_session_data *sd,int menunum);
int pet_change_name(struct map_session_data *sd,char *name);
-int pet_change_name_ack(struct map_session_data *sd, char *name, int flag);
+int pet_change_name_ack(struct map_session_data *sd, char* name, int flag);
int pet_equipitem(struct map_session_data *sd,int index);
int pet_lootitem_drop(struct pet_data *pd,struct map_session_data *sd);
int pet_attackskill(struct pet_data *pd, int target_id);
diff --git a/src/map/quest.c b/src/map/quest.c
index 07c3097a8..c7ca06514 100644
--- a/src/map/quest.c
+++ b/src/map/quest.c
@@ -38,317 +38,321 @@ struct s_quest_db quest_db[MAX_QUEST_DB];
int quest_search_db(int quest_id)
{
- int i;
+ int i;
- ARR_FIND(0, MAX_QUEST_DB,i,quest_id == quest_db[i].id);
- if (i == MAX_QUEST_DB)
- return -1;
+ ARR_FIND(0, MAX_QUEST_DB,i,quest_id == quest_db[i].id);
+ if( i == MAX_QUEST_DB )
+ return -1;
- return i;
+ return i;
}
//Send quest info on login
-int quest_pc_login(TBL_PC *sd)
+int quest_pc_login(TBL_PC * sd)
{
- if (sd->avail_quests == 0)
- return 1;
+ if(sd->avail_quests == 0)
+ return 1;
- clif_quest_send_list(sd);
- clif_quest_send_mission(sd);
+ clif_quest_send_list(sd);
+ clif_quest_send_mission(sd);
- return 0;
+ return 0;
}
-int quest_add(TBL_PC *sd, int quest_id)
+int quest_add(TBL_PC * sd, int quest_id)
{
- int i, j;
+ int i, j;
- if (sd->num_quests >= MAX_QUEST_DB) {
- ShowError("quest_add: Character %d has got all the quests.(max quests: %d)\n", sd->status.char_id, MAX_QUEST_DB);
- return 1;
- }
+ if( sd->num_quests >= MAX_QUEST_DB )
+ {
+ ShowError("quest_add: Character %d has got all the quests.(max quests: %d)\n", sd->status.char_id, MAX_QUEST_DB);
+ return 1;
+ }
- if (quest_check(sd, quest_id, HAVEQUEST) >= 0) {
- ShowError("quest_add: Character %d already has quest %d.\n", sd->status.char_id, quest_id);
- return -1;
- }
+ if( quest_check(sd, quest_id, HAVEQUEST) >= 0 )
+ {
+ ShowError("quest_add: Character %d already has quest %d.\n", sd->status.char_id, quest_id);
+ return -1;
+ }
- if ((j = quest_search_db(quest_id)) < 0) {
- ShowError("quest_add: quest %d not found in DB.\n", quest_id);
- return -1;
- }
+ if( (j = quest_search_db(quest_id)) < 0 )
+ {
+ ShowError("quest_add: quest %d not found in DB.\n", quest_id);
+ return -1;
+ }
- i = sd->avail_quests;
- memmove(&sd->quest_log[i+1], &sd->quest_log[i], sizeof(struct quest)*(sd->num_quests-sd->avail_quests));
- memmove(sd->quest_index+i+1, sd->quest_index+i, sizeof(int)*(sd->num_quests-sd->avail_quests));
+ i = sd->avail_quests;
+ memmove(&sd->quest_log[i+1], &sd->quest_log[i], sizeof(struct quest)*(sd->num_quests-sd->avail_quests));
+ memmove(sd->quest_index+i+1, sd->quest_index+i, sizeof(int)*(sd->num_quests-sd->avail_quests));
- memset(&sd->quest_log[i], 0, sizeof(struct quest));
- sd->quest_log[i].quest_id = quest_db[j].id;
- if (quest_db[j].time)
- sd->quest_log[i].time = (unsigned int)(time(NULL) + quest_db[j].time);
- sd->quest_log[i].state = Q_ACTIVE;
+ memset(&sd->quest_log[i], 0, sizeof(struct quest));
+ sd->quest_log[i].quest_id = quest_db[j].id;
+ if( quest_db[j].time )
+ sd->quest_log[i].time = (unsigned int)(time(NULL) + quest_db[j].time);
+ sd->quest_log[i].state = Q_ACTIVE;
- sd->quest_index[i] = j;
- sd->num_quests++;
- sd->avail_quests++;
- sd->save_quest = true;
+ sd->quest_index[i] = j;
+ sd->num_quests++;
+ sd->avail_quests++;
+ sd->save_quest = true;
- clif_quest_add(sd, &sd->quest_log[i], sd->quest_index[i]);
+ clif_quest_add(sd, &sd->quest_log[i], sd->quest_index[i]);
- if (save_settings&64)
- chrif_save(sd,0);
+ if( save_settings&64 )
+ chrif_save(sd,0);
- return 0;
+ return 0;
}
-int quest_change(TBL_PC *sd, int qid1, int qid2)
+int quest_change(TBL_PC * sd, int qid1, int qid2)
{
- int i, j;
-
- if (quest_check(sd, qid2, HAVEQUEST) >= 0) {
- ShowError("quest_change: Character %d already has quest %d.\n", sd->status.char_id, qid2);
- return -1;
- }
-
- if (quest_check(sd, qid1, HAVEQUEST) < 0) {
- ShowError("quest_change: Character %d doesn't have quest %d.\n", sd->status.char_id, qid1);
- return -1;
- }
-
- if ((j = quest_search_db(qid2)) < 0) {
- ShowError("quest_change: quest %d not found in DB.\n",qid2);
- return -1;
- }
-
- ARR_FIND(0, sd->avail_quests, i, sd->quest_log[i].quest_id == qid1);
- if (i == sd->avail_quests) {
- ShowError("quest_change: Character %d has completed quests %d.\n", sd->status.char_id, qid1);
- return -1;
- }
-
- memset(&sd->quest_log[i], 0, sizeof(struct quest));
- sd->quest_log[i].quest_id = quest_db[j].id;
- if (quest_db[j].time)
- sd->quest_log[i].time = (unsigned int)(time(NULL) + quest_db[j].time);
- sd->quest_log[i].state = Q_ACTIVE;
-
- sd->quest_index[i] = j;
- sd->save_quest = true;
-
- clif_quest_delete(sd, qid1);
- clif_quest_add(sd, &sd->quest_log[i], sd->quest_index[i]);
-
- if (save_settings&64)
- chrif_save(sd,0);
-
- return 0;
+ int i, j;
+
+ if( quest_check(sd, qid2, HAVEQUEST) >= 0 )
+ {
+ ShowError("quest_change: Character %d already has quest %d.\n", sd->status.char_id, qid2);
+ return -1;
+ }
+
+ if( quest_check(sd, qid1, HAVEQUEST) < 0 )
+ {
+ ShowError("quest_change: Character %d doesn't have quest %d.\n", sd->status.char_id, qid1);
+ return -1;
+ }
+
+ if( (j = quest_search_db(qid2)) < 0 )
+ {
+ ShowError("quest_change: quest %d not found in DB.\n",qid2);
+ return -1;
+ }
+
+ ARR_FIND(0, sd->avail_quests, i, sd->quest_log[i].quest_id == qid1);
+ if(i == sd->avail_quests)
+ {
+ ShowError("quest_change: Character %d has completed quests %d.\n", sd->status.char_id, qid1);
+ return -1;
+ }
+
+ memset(&sd->quest_log[i], 0, sizeof(struct quest));
+ sd->quest_log[i].quest_id = quest_db[j].id;
+ if( quest_db[j].time )
+ sd->quest_log[i].time = (unsigned int)(time(NULL) + quest_db[j].time);
+ sd->quest_log[i].state = Q_ACTIVE;
+
+ sd->quest_index[i] = j;
+ sd->save_quest = true;
+
+ clif_quest_delete(sd, qid1);
+ clif_quest_add(sd, &sd->quest_log[i], sd->quest_index[i]);
+
+ if( save_settings&64 )
+ chrif_save(sd,0);
+
+ return 0;
}
-int quest_delete(TBL_PC *sd, int quest_id)
+int quest_delete(TBL_PC * sd, int quest_id)
{
- int i;
-
- //Search for quest
- ARR_FIND(0, sd->num_quests, i, sd->quest_log[i].quest_id == quest_id);
- if (i == sd->num_quests) {
- ShowError("quest_delete: Character %d doesn't have quest %d.\n", sd->status.char_id, quest_id);
- return -1;
- }
-
- if (sd->quest_log[i].state != Q_COMPLETE)
- sd->avail_quests--;
- if (sd->num_quests-- < MAX_QUEST_DB && sd->quest_log[i+1].quest_id) {
- memmove(&sd->quest_log[i], &sd->quest_log[i+1], sizeof(struct quest)*(sd->num_quests-i));
- memmove(sd->quest_index+i, sd->quest_index+i+1, sizeof(int)*(sd->num_quests-i));
- }
- memset(&sd->quest_log[sd->num_quests], 0, sizeof(struct quest));
- sd->quest_index[sd->num_quests] = 0;
- sd->save_quest = true;
-
- clif_quest_delete(sd, quest_id);
-
- if (save_settings&64)
- chrif_save(sd,0);
-
- return 0;
+ int i;
+
+ //Search for quest
+ ARR_FIND(0, sd->num_quests, i, sd->quest_log[i].quest_id == quest_id);
+ if(i == sd->num_quests)
+ {
+ ShowError("quest_delete: Character %d doesn't have quest %d.\n", sd->status.char_id, quest_id);
+ return -1;
+ }
+
+ if( sd->quest_log[i].state != Q_COMPLETE )
+ sd->avail_quests--;
+ if( sd->num_quests-- < MAX_QUEST_DB && sd->quest_log[i+1].quest_id )
+ {
+ memmove(&sd->quest_log[i], &sd->quest_log[i+1], sizeof(struct quest)*(sd->num_quests-i));
+ memmove(sd->quest_index+i, sd->quest_index+i+1, sizeof(int)*(sd->num_quests-i));
+ }
+ memset(&sd->quest_log[sd->num_quests], 0, sizeof(struct quest));
+ sd->quest_index[sd->num_quests] = 0;
+ sd->save_quest = true;
+
+ clif_quest_delete(sd, quest_id);
+
+ if( save_settings&64 )
+ chrif_save(sd,0);
+
+ return 0;
}
int quest_update_objective_sub(struct block_list *bl, va_list ap)
{
- struct map_session_data *sd;
- int mob, party;
+ struct map_session_data * sd;
+ int mob, party;
- nullpo_ret(bl);
- nullpo_ret(sd = (struct map_session_data *)bl);
+ nullpo_ret(bl);
+ nullpo_ret(sd = (struct map_session_data *)bl);
- party = va_arg(ap,int);
- mob = va_arg(ap,int);
+ party = va_arg(ap,int);
+ mob = va_arg(ap,int);
- if (!sd->avail_quests)
- return 0;
- if (sd->status.party_id != party)
- return 0;
+ if( !sd->avail_quests )
+ return 0;
+ if( sd->status.party_id != party )
+ return 0;
- quest_update_objective(sd, mob);
+ quest_update_objective(sd, mob);
- return 1;
+ return 1;
}
-void quest_update_objective(TBL_PC *sd, int mob)
-{
- int i,j;
-
- for (i = 0; i < sd->avail_quests; i++) {
- if (sd->quest_log[i].state != Q_ACTIVE)
- continue;
-
- for (j = 0; j < MAX_QUEST_OBJECTIVES; j++)
- if (quest_db[sd->quest_index[i]].mob[j] == mob && sd->quest_log[i].count[j] < quest_db[sd->quest_index[i]].count[j]) {
- sd->quest_log[i].count[j]++;
- sd->save_quest = true;
- clif_quest_update_objective(sd,&sd->quest_log[i],sd->quest_index[i]);
- }
- }
+void quest_update_objective(TBL_PC * sd, int mob) {
+ int i,j;
+
+ for( i = 0; i < sd->avail_quests; i++ ) {
+ if( sd->quest_log[i].state != Q_ACTIVE )
+ continue;
+
+ for( j = 0; j < MAX_QUEST_OBJECTIVES; j++ )
+ if( quest_db[sd->quest_index[i]].mob[j] == mob && sd->quest_log[i].count[j] < quest_db[sd->quest_index[i]].count[j] ) {
+ sd->quest_log[i].count[j]++;
+ sd->save_quest = true;
+ clif_quest_update_objective(sd,&sd->quest_log[i],sd->quest_index[i]);
+ }
+ }
}
-int quest_update_status(TBL_PC *sd, int quest_id, quest_state status)
-{
- int i;
+int quest_update_status(TBL_PC * sd, int quest_id, quest_state status) {
+ int i;
- //Only status of active and inactive quests can be updated. Completed quests can't (for now). [Inkfish]
- ARR_FIND(0, sd->avail_quests, i, sd->quest_log[i].quest_id == quest_id);
- if (i == sd->avail_quests) {
- ShowError("quest_update_status: Character %d doesn't have quest %d.\n", sd->status.char_id, quest_id);
- return -1;
- }
+ //Only status of active and inactive quests can be updated. Completed quests can't (for now). [Inkfish]
+ ARR_FIND(0, sd->avail_quests, i, sd->quest_log[i].quest_id == quest_id);
+ if(i == sd->avail_quests) {
+ ShowError("quest_update_status: Character %d doesn't have quest %d.\n", sd->status.char_id, quest_id);
+ return -1;
+ }
- sd->quest_log[i].state = status;
- sd->save_quest = true;
+ sd->quest_log[i].state = status;
+ sd->save_quest = true;
- if (status < Q_COMPLETE) {
- clif_quest_update_status(sd, quest_id, (bool)status);
- return 0;
- }
+ if( status < Q_COMPLETE ) {
+ clif_quest_update_status(sd, quest_id, (bool)status);
+ return 0;
+ }
- if (i != (--sd->avail_quests)) {
- struct quest tmp_quest;
- memcpy(&tmp_quest, &sd->quest_log[i],sizeof(struct quest));
- memcpy(&sd->quest_log[i], &sd->quest_log[sd->avail_quests],sizeof(struct quest));
- memcpy(&sd->quest_log[sd->avail_quests], &tmp_quest,sizeof(struct quest));
- }
+ if( i != (--sd->avail_quests) ) {
+ struct quest tmp_quest;
+ memcpy(&tmp_quest, &sd->quest_log[i],sizeof(struct quest));
+ memcpy(&sd->quest_log[i], &sd->quest_log[sd->avail_quests],sizeof(struct quest));
+ memcpy(&sd->quest_log[sd->avail_quests], &tmp_quest,sizeof(struct quest));
+ }
- clif_quest_delete(sd, quest_id);
+ clif_quest_delete(sd, quest_id);
- if (save_settings&64)
- chrif_save(sd,0);
+ if( save_settings&64 )
+ chrif_save(sd,0);
- return 0;
+ return 0;
}
-int quest_check(TBL_PC *sd, int quest_id, quest_check_type type)
-{
- int i;
-
- ARR_FIND(0, sd->num_quests, i, sd->quest_log[i].quest_id == quest_id);
- if (i == sd->num_quests)
- return -1;
-
- switch (type) {
- case HAVEQUEST:
- return sd->quest_log[i].state;
- case PLAYTIME:
- return (sd->quest_log[i].time < (unsigned int)time(NULL) ? 2 : sd->quest_log[i].state == Q_COMPLETE ? 1 : 0);
- case HUNTING: {
- if (sd->quest_log[i].state == 0 || sd->quest_log[i].state == 1) {
- int j;
- ARR_FIND(0, MAX_QUEST_OBJECTIVES, j, sd->quest_log[i].count[j] < quest_db[sd->quest_index[i]].count[j]);
- if (j == MAX_QUEST_OBJECTIVES)
- return 2;
- if (sd->quest_log[i].time < (unsigned int)time(NULL))
- return 1;
- return 0;
- } else
- return 0;
- }
- default:
- ShowError("quest_check_quest: Unknown parameter %d",type);
- break;
- }
-
- return -1;
+int quest_check(TBL_PC * sd, int quest_id, quest_check_type type) {
+ int i;
+
+ ARR_FIND(0, sd->num_quests, i, sd->quest_log[i].quest_id == quest_id);
+ if( i == sd->num_quests )
+ return -1;
+
+ switch( type ) {
+ case HAVEQUEST:
+ return sd->quest_log[i].state;
+ case PLAYTIME:
+ return (sd->quest_log[i].time < (unsigned int)time(NULL) ? 2 : sd->quest_log[i].state == Q_COMPLETE ? 1 : 0);
+ case HUNTING: {
+ if( sd->quest_log[i].state == 0 || sd->quest_log[i].state == 1 ) {
+ int j;
+ ARR_FIND(0, MAX_QUEST_OBJECTIVES, j, sd->quest_log[i].count[j] < quest_db[sd->quest_index[i]].count[j]);
+ if( j == MAX_QUEST_OBJECTIVES )
+ return 2;
+ if( sd->quest_log[i].time < (unsigned int)time(NULL) )
+ return 1;
+ return 0;
+ } else
+ return 0;
+ }
+ default:
+ ShowError("quest_check_quest: Unknown parameter %d",type);
+ break;
+ }
+
+ return -1;
}
-int quest_read_db(void)
-{
- FILE *fp;
- char line[1024];
- int i,j,k = 0;
- char *str[20],*p,*np;
-
- sprintf(line, "%s/quest_db.txt", db_path);
- if ((fp=fopen(line,"r"))==NULL) {
- ShowError("can't read %s\n", line);
- return -1;
- }
-
- while (fgets(line, sizeof(line), fp)) {
-
- if (k == MAX_QUEST_DB) {
- ShowError("quest_read_db: Too many entries specified in %s/quest_db.txt!\n", db_path);
- break;
- }
-
- if (line[0]=='/' && line[1]=='/')
- continue;
- memset(str,0,sizeof(str));
-
- for (j = 0, p = line; j < 8; j++) {
- if ((np = strchr(p,',')) != NULL) {
- str[j] = p;
- *np = 0;
- p = np + 1;
- } else if (str[0] == NULL)
- continue;
- else {
- ShowError("quest_read_db: insufficient columns in line %s\n", line);
- continue;
- }
- }
- if (str[0]==NULL)
- continue;
-
- memset(&quest_db[k], 0, sizeof(quest_db[0]));
-
- quest_db[k].id = atoi(str[0]);
- quest_db[k].time = atoi(str[1]);
-
- for (i = 0; i < MAX_QUEST_OBJECTIVES; i++) {
- quest_db[k].mob[i] = atoi(str[2*i+2]);
- quest_db[k].count[i] = atoi(str[2*i+3]);
-
- if (!quest_db[k].mob[i] || !quest_db[k].count[i])
- break;
- }
-
- quest_db[k].num_objectives = i;
-
- k++;
- }
- fclose(fp);
- ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", k, "quest_db.txt");
- return 0;
+int quest_read_db(void) {
+ FILE *fp;
+ char line[1024];
+ int i,j,k = 0;
+ char *str[20],*p,*np;
+
+ sprintf(line, "%s/quest_db.txt", db_path);
+ if( (fp=fopen(line,"r"))==NULL ){
+ ShowError("can't read %s\n", line);
+ return -1;
+ }
+
+ while(fgets(line, sizeof(line), fp)) {
+
+ if (k == MAX_QUEST_DB) {
+ ShowError("quest_read_db: Too many entries specified in %s/quest_db.txt!\n", db_path);
+ break;
+ }
+
+ if(line[0]=='/' && line[1]=='/')
+ continue;
+ memset(str,0,sizeof(str));
+
+ for( j = 0, p = line; j < 8; j++ ) {
+ if( ( np = strchr(p,',') ) != NULL ) {
+ str[j] = p;
+ *np = 0;
+ p = np + 1;
+ }
+ else if (str[0] == NULL)
+ continue;
+ else {
+ ShowError("quest_read_db: insufficient columns in line %s\n", line);
+ continue;
+ }
+ }
+ if(str[0]==NULL)
+ continue;
+
+ memset(&quest_db[k], 0, sizeof(quest_db[0]));
+
+ quest_db[k].id = atoi(str[0]);
+ quest_db[k].time = atoi(str[1]);
+
+ for( i = 0; i < MAX_QUEST_OBJECTIVES; i++ ) {
+ quest_db[k].mob[i] = atoi(str[2*i+2]);
+ quest_db[k].count[i] = atoi(str[2*i+3]);
+
+ if( !quest_db[k].mob[i] || !quest_db[k].count[i] )
+ break;
+ }
+
+ quest_db[k].num_objectives = i;
+
+ k++;
+ }
+ fclose(fp);
+ ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", k, "quest_db.txt");
+ return 0;
}
-void do_init_quest(void)
-{
- quest_read_db();
+void do_init_quest(void) {
+ quest_read_db();
}
-void do_reload_quest(void)
-{
- memset(&quest_db, 0, sizeof(quest_db));
- quest_read_db();
+void do_reload_quest(void) {
+ memset(&quest_db, 0, sizeof(quest_db));
+ quest_read_db();
}
diff --git a/src/map/quest.h b/src/map/quest.h
index 239b9f593..7f638a54c 100644
--- a/src/map/quest.h
+++ b/src/map/quest.h
@@ -5,26 +5,26 @@
#define _QUEST_H_
struct s_quest_db {
- int id;
- unsigned int time;
- int mob[MAX_QUEST_OBJECTIVES];
- int count[MAX_QUEST_OBJECTIVES];
- int num_objectives;
- //char name[NAME_LENGTH];
+ int id;
+ unsigned int time;
+ int mob[MAX_QUEST_OBJECTIVES];
+ int count[MAX_QUEST_OBJECTIVES];
+ int num_objectives;
+ //char name[NAME_LENGTH];
};
extern struct s_quest_db quest_db[MAX_QUEST_DB];
typedef enum quest_check_type { HAVEQUEST, PLAYTIME, HUNTING } quest_check_type;
-int quest_pc_login(TBL_PC *sd);
+int quest_pc_login(TBL_PC * sd);
-int quest_add(TBL_PC *sd, int quest_id);
-int quest_delete(TBL_PC *sd, int quest_id);
-int quest_change(TBL_PC *sd, int qid1, int qid2);
+int quest_add(TBL_PC * sd, int quest_id);
+int quest_delete(TBL_PC * sd, int quest_id);
+int quest_change(TBL_PC * sd, int qid1, int qid2);
int quest_update_objective_sub(struct block_list *bl, va_list ap);
-void quest_update_objective(TBL_PC *sd, int mob);
-int quest_update_status(TBL_PC *sd, int quest_id, quest_state status);
-int quest_check(TBL_PC *sd, int quest_id, quest_check_type type);
+void quest_update_objective(TBL_PC * sd, int mob);
+int quest_update_status(TBL_PC * sd, int quest_id, quest_state status);
+int quest_check(TBL_PC * sd, int quest_id, quest_check_type type);
int quest_search_db(int quest_id);
diff --git a/src/map/script.c b/src/map/script.c
index 8ff244538..f1a422b7e 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -13,7 +13,7 @@
#include "../common/nullpo.h"
#include "../common/random.h"
#include "../common/showmsg.h"
-#include "../common/socket.h" // usage: getcharip
+#include "../common/socket.h" // usage: getcharip
#include "../common/strlib.h"
#include "../common/timer.h"
#include "../common/utils.h"
@@ -55,17 +55,17 @@
#include <string.h>
#include <math.h>
#ifndef WIN32
-#include <sys/time.h>
+ #include <sys/time.h>
#endif
#include <time.h>
#include <setjmp.h>
#include <errno.h>
#ifdef BETA_THREAD_TEST
-#include "../common/atomic.h"
-#include "../common/spinlock.h"
-#include "../common/thread.h"
-#include "../common/mutex.h"
+ #include "../common/atomic.h"
+ #include "../common/spinlock.h"
+ #include "../common/thread.h"
+ #include "../common/mutex.h"
#endif
@@ -166,8 +166,8 @@
#define is_string_variable(name) ( (name)[strlen(name) - 1] == '$' )
#define FETCH(n, t) \
- if( script_hasdata(st,n) ) \
- (t)=script_getnum(st,n);
+ if( script_hasdata(st,n) ) \
+ (t)=script_getnum(st,n);
/// Maximum amount of elements in script arrays
#define SCRIPT_MAX_ARRAYSIZE 128
@@ -177,30 +177,30 @@ enum { LABEL_NEXTLINE=1,LABEL_START };
/// temporary buffer for passing around compiled bytecode
/// @see add_scriptb, set_label, parse_script
-static unsigned char *script_buf = NULL;
+static unsigned char* script_buf = NULL;
static int script_pos = 0, script_size = 0;
-static inline int GETVALUE(const unsigned char *buf, int i)
+static inline int GETVALUE(const unsigned char* buf, int i)
{
- return (int)MakeDWord(MakeWord(buf[i], buf[i+1]), MakeWord(buf[i+2], 0));
+ return (int)MakeDWord(MakeWord(buf[i], buf[i+1]), MakeWord(buf[i+2], 0));
}
-static inline void SETVALUE(unsigned char *buf, int i, int n)
+static inline void SETVALUE(unsigned char* buf, int i, int n)
{
- buf[i] = GetByte(n, 0);
- buf[i+1] = GetByte(n, 1);
- buf[i+2] = GetByte(n, 2);
+ buf[i] = GetByte(n, 0);
+ buf[i+1] = GetByte(n, 1);
+ buf[i+2] = GetByte(n, 2);
}
// String buffer structures.
// str_data stores string information
static struct str_data_struct {
- enum c_op type;
- int str;
- int backpatch;
- int label;
- int (*func)(struct script_state *st);
- int val;
- int next;
+ enum c_op type;
+ int str;
+ int backpatch;
+ int label;
+ int (*func)(struct script_state *st);
+ int val;
+ int next;
} *str_data = NULL;
static int str_data_size = 0; // size of the data
static int str_num = LABEL_START; // next id to be assigned
@@ -219,17 +219,11 @@ int str_hash[SCRIPT_HASH_SIZE];
//#define SCRIPT_HASH_SDBM
#define SCRIPT_HASH_ELF
-static DBMap *scriptlabel_db=NULL; // const char* label_name -> int script_pos
-static DBMap *userfunc_db=NULL; // const char* func_name -> struct script_code*
+static DBMap* scriptlabel_db=NULL; // const char* label_name -> int script_pos
+static DBMap* userfunc_db=NULL; // const char* func_name -> struct script_code*
static int parse_options=0;
-DBMap *script_get_label_db(void)
-{
- return scriptlabel_db;
-}
-DBMap *script_get_userfunc_db(void)
-{
- return userfunc_db;
-}
+DBMap* script_get_label_db(void){ return scriptlabel_db; }
+DBMap* script_get_userfunc_db(void){ return userfunc_db; }
// important buildin function references for usage in scripts
static int buildin_set_ref = 0;
@@ -239,64 +233,65 @@ static int buildin_getelementofarray_ref = 0;
// Caches compiled autoscript item code.
// Note: This is not cleared when reloading itemdb.
-static DBMap *autobonus_db=NULL; // char* script -> char* bytecode
+static DBMap* autobonus_db=NULL; // char* script -> char* bytecode
struct Script_Config script_config = {
- 1, // warn_func_mismatch_argtypes
- 1, 65535, 2048, //warn_func_mismatch_paramnum/check_cmdcount/check_gotocount
- 0, INT_MAX, // input_min_value/input_max_value
- "OnPCDieEvent", //die_event_name
- "OnPCKillEvent", //kill_pc_event_name
- "OnNPCKillEvent", //kill_mob_event_name
- "OnPCLoginEvent", //login_event_name
- "OnPCLogoutEvent", //logout_event_name
- "OnPCLoadMapEvent", //loadmap_event_name
- "OnPCBaseLvUpEvent", //baselvup_event_name
- "OnPCJobLvUpEvent", //joblvup_event_name
- "OnTouch_", //ontouch_name (runs on first visible char to enter area, picks another char if the first char leaves)
- "OnTouch", //ontouch2_name (run whenever a char walks into the OnTouch area)
+ 1, // warn_func_mismatch_argtypes
+ 1, 65535, 2048, //warn_func_mismatch_paramnum/check_cmdcount/check_gotocount
+ 0, INT_MAX, // input_min_value/input_max_value
+ "OnPCDieEvent", //die_event_name
+ "OnPCKillEvent", //kill_pc_event_name
+ "OnNPCKillEvent", //kill_mob_event_name
+ "OnPCLoginEvent", //login_event_name
+ "OnPCLogoutEvent", //logout_event_name
+ "OnPCLoadMapEvent", //loadmap_event_name
+ "OnPCBaseLvUpEvent", //baselvup_event_name
+ "OnPCJobLvUpEvent", //joblvup_event_name
+ "OnTouch_", //ontouch_name (runs on first visible char to enter area, picks another char if the first char leaves)
+ "OnTouch", //ontouch2_name (run whenever a char walks into the OnTouch area)
};
static jmp_buf error_jump;
-static char *error_msg;
-static const char *error_pos;
+static char* error_msg;
+static const char* error_pos;
static int error_report; // if the error should produce output
// for advanced scripting support ( nested if, switch, while, for, do-while, function, etc )
// [Eoe / jA 1080, 1081, 1094, 1164]
enum curly_type {
- TYPE_NULL = 0,
- TYPE_IF,
- TYPE_SWITCH,
- TYPE_WHILE,
- TYPE_FOR,
- TYPE_DO,
- TYPE_USERFUNC,
- TYPE_ARGLIST // function argument list
+ TYPE_NULL = 0,
+ TYPE_IF,
+ TYPE_SWITCH,
+ TYPE_WHILE,
+ TYPE_FOR,
+ TYPE_DO,
+ TYPE_USERFUNC,
+ TYPE_ARGLIST // function argument list
};
-enum e_arglist {
- ARGLIST_UNDEFINED = 0,
- ARGLIST_NO_PAREN = 1,
- ARGLIST_PAREN = 2,
+enum e_arglist
+{
+ ARGLIST_UNDEFINED = 0,
+ ARGLIST_NO_PAREN = 1,
+ ARGLIST_PAREN = 2,
};
static struct {
- struct {
- enum curly_type type;
- int index;
- int count;
- int flag;
- struct linkdb_node *case_label;
- } curly[256]; // Information right parenthesis
- int curly_count; // The number of right brackets
- int index; // Number of the syntax used in the script
+ struct {
+ enum curly_type type;
+ int index;
+ int count;
+ int flag;
+ struct linkdb_node *case_label;
+ } curly[256]; // Information right parenthesis
+ int curly_count; // The number of right brackets
+ int index; // Number of the syntax used in the script
} syntax;
-const char *parse_curly_close(const char *p);
-const char *parse_syntax_close(const char *p);
-const char *parse_syntax_close_sub(const char *p,int *flag);
-const char *parse_syntax(const char *p);
+const char* parse_curly_close(const char* p);
+const char* parse_syntax_close(const char* p);
+const char* parse_syntax_close_sub(const char* p,int* flag);
+const char* parse_syntax(const char* p);
static int parse_syntax_for_flag = 0;
extern int current_equip_item_index; //for New CARDS Scripts. It contains Inventory Index of the EQUIP_SCRIPT caller item. [Lupus]
@@ -309,14 +304,14 @@ c_op get_com(unsigned char *script,int *pos);
int get_num(unsigned char *script,int *pos);
typedef struct script_function {
- int (*func)(struct script_state *st);
- const char *name;
- const char *arg;
+ int (*func)(struct script_state *st);
+ const char *name;
+ const char *arg;
} script_function;
extern script_function buildin_func[];
-static struct linkdb_node *sleep_db;// int oid -> struct script_state*
+static struct linkdb_node* sleep_db;// int oid -> struct script_state*
#ifdef BETA_THREAD_TEST
/**
@@ -324,285 +319,301 @@ static struct linkdb_node *sleep_db;// int oid -> struct script_state*
**/
static SPIN_LOCK queryThreadLock;
static rAthread queryThread = NULL;
-static ramutex queryThreadMutex = NULL;
-static racond queryThreadCond = NULL;
+static ramutex queryThreadMutex = NULL;
+static racond queryThreadCond = NULL;
static volatile int32 queryThreadTerminate = 0;
struct queryThreadEntry {
- bool ok;
- bool type; /* main db or log db? */
- struct script_state *st;
+ bool ok;
+ bool type; /* main db or log db? */
+ struct script_state *st;
};
/* Ladies and Gentleman the Manager! */
struct {
- struct queryThreadEntry **entry;/* array of structs */
- int count;
- int timer;/* used to receive processed entries */
+ struct queryThreadEntry **entry;/* array of structs */
+ int count;
+ int timer;/* used to receive processed entries */
} queryThreadData;
#endif
/*==========================================
* (Only those needed) local declaration prototype
*------------------------------------------*/
-const char *parse_subexpr(const char *p,int limit);
+const char* parse_subexpr(const char* p,int limit);
int run_func(struct script_state *st);
enum {
- MF_NOMEMO, //0
- MF_NOTELEPORT,
- MF_NOSAVE,
- MF_NOBRANCH,
- MF_NOPENALTY,
- MF_NOZENYPENALTY,
- MF_PVP,
- MF_PVP_NOPARTY,
- MF_PVP_NOGUILD,
- MF_GVG,
- MF_GVG_NOPARTY, //10
- MF_NOTRADE,
- MF_NOSKILL,
- MF_NOWARP,
- MF_PARTYLOCK,
- MF_NOICEWALL,
- MF_SNOW,
- MF_FOG,
- MF_SAKURA,
- MF_LEAVES,
- /**
- * No longer available, keeping here just in case it's back someday. [Ind]
- **/
- //MF_RAIN, //20
- // 21 free
- MF_NOGO = 22,
- MF_CLOUDS,
- MF_CLOUDS2,
- MF_FIREWORKS,
- MF_GVG_CASTLE,
- MF_GVG_DUNGEON,
- MF_NIGHTENABLED,
- MF_NOBASEEXP,
- MF_NOJOBEXP, //30
- MF_NOMOBLOOT,
- MF_NOMVPLOOT,
- MF_NORETURN,
- MF_NOWARPTO,
- MF_NIGHTMAREDROP,
- MF_RESTRICTED,
- MF_NOCOMMAND,
- MF_NODROP,
- MF_JEXP,
- MF_BEXP, //40
- MF_NOVENDING,
- MF_LOADEVENT,
- MF_NOCHAT,
- MF_NOEXPPENALTY,
- MF_GUILDLOCK,
- MF_TOWN,
- MF_AUTOTRADE,
- MF_ALLOWKS,
- MF_MONSTER_NOTELEPORT,
- MF_PVP_NOCALCRANK, //50
- MF_BATTLEGROUND,
- MF_RESET
+ MF_NOMEMO, //0
+ MF_NOTELEPORT,
+ MF_NOSAVE,
+ MF_NOBRANCH,
+ MF_NOPENALTY,
+ MF_NOZENYPENALTY,
+ MF_PVP,
+ MF_PVP_NOPARTY,
+ MF_PVP_NOGUILD,
+ MF_GVG,
+ MF_GVG_NOPARTY, //10
+ MF_NOTRADE,
+ MF_NOSKILL,
+ MF_NOWARP,
+ MF_PARTYLOCK,
+ MF_NOICEWALL,
+ MF_SNOW,
+ MF_FOG,
+ MF_SAKURA,
+ MF_LEAVES,
+ /**
+ * No longer available, keeping here just in case it's back someday. [Ind]
+ **/
+ //MF_RAIN, //20
+ // 21 free
+ MF_NOGO = 22,
+ MF_CLOUDS,
+ MF_CLOUDS2,
+ MF_FIREWORKS,
+ MF_GVG_CASTLE,
+ MF_GVG_DUNGEON,
+ MF_NIGHTENABLED,
+ MF_NOBASEEXP,
+ MF_NOJOBEXP, //30
+ MF_NOMOBLOOT,
+ MF_NOMVPLOOT,
+ MF_NORETURN,
+ MF_NOWARPTO,
+ MF_NIGHTMAREDROP,
+ MF_RESTRICTED,
+ MF_NOCOMMAND,
+ MF_NODROP,
+ MF_JEXP,
+ MF_BEXP, //40
+ MF_NOVENDING,
+ MF_LOADEVENT,
+ MF_NOCHAT,
+ MF_NOEXPPENALTY,
+ MF_GUILDLOCK,
+ MF_TOWN,
+ MF_AUTOTRADE,
+ MF_ALLOWKS,
+ MF_MONSTER_NOTELEPORT,
+ MF_PVP_NOCALCRANK, //50
+ MF_BATTLEGROUND,
+ MF_RESET
};
-const char *script_op2name(int op)
+const char* script_op2name(int op)
{
#define RETURN_OP_NAME(type) case type: return #type
- switch (op) {
- RETURN_OP_NAME(C_NOP);
- RETURN_OP_NAME(C_POS);
- RETURN_OP_NAME(C_INT);
- RETURN_OP_NAME(C_PARAM);
- RETURN_OP_NAME(C_FUNC);
- RETURN_OP_NAME(C_STR);
- RETURN_OP_NAME(C_CONSTSTR);
- RETURN_OP_NAME(C_ARG);
- RETURN_OP_NAME(C_NAME);
- RETURN_OP_NAME(C_EOL);
- RETURN_OP_NAME(C_RETINFO);
- RETURN_OP_NAME(C_USERFUNC);
- RETURN_OP_NAME(C_USERFUNC_POS);
-
- // operators
- RETURN_OP_NAME(C_OP3);
- RETURN_OP_NAME(C_LOR);
- RETURN_OP_NAME(C_LAND);
- RETURN_OP_NAME(C_LE);
- RETURN_OP_NAME(C_LT);
- RETURN_OP_NAME(C_GE);
- RETURN_OP_NAME(C_GT);
- RETURN_OP_NAME(C_EQ);
- RETURN_OP_NAME(C_NE);
- RETURN_OP_NAME(C_XOR);
- RETURN_OP_NAME(C_OR);
- RETURN_OP_NAME(C_AND);
- RETURN_OP_NAME(C_ADD);
- RETURN_OP_NAME(C_SUB);
- RETURN_OP_NAME(C_MUL);
- RETURN_OP_NAME(C_DIV);
- RETURN_OP_NAME(C_MOD);
- RETURN_OP_NAME(C_NEG);
- RETURN_OP_NAME(C_LNOT);
- RETURN_OP_NAME(C_NOT);
- RETURN_OP_NAME(C_R_SHIFT);
- RETURN_OP_NAME(C_L_SHIFT);
-
- default:
- ShowDebug("script_op2name: unexpected op=%d\n", op);
- return "???";
- }
+ switch( op )
+ {
+ RETURN_OP_NAME(C_NOP);
+ RETURN_OP_NAME(C_POS);
+ RETURN_OP_NAME(C_INT);
+ RETURN_OP_NAME(C_PARAM);
+ RETURN_OP_NAME(C_FUNC);
+ RETURN_OP_NAME(C_STR);
+ RETURN_OP_NAME(C_CONSTSTR);
+ RETURN_OP_NAME(C_ARG);
+ RETURN_OP_NAME(C_NAME);
+ RETURN_OP_NAME(C_EOL);
+ RETURN_OP_NAME(C_RETINFO);
+ RETURN_OP_NAME(C_USERFUNC);
+ RETURN_OP_NAME(C_USERFUNC_POS);
+
+ // operators
+ RETURN_OP_NAME(C_OP3);
+ RETURN_OP_NAME(C_LOR);
+ RETURN_OP_NAME(C_LAND);
+ RETURN_OP_NAME(C_LE);
+ RETURN_OP_NAME(C_LT);
+ RETURN_OP_NAME(C_GE);
+ RETURN_OP_NAME(C_GT);
+ RETURN_OP_NAME(C_EQ);
+ RETURN_OP_NAME(C_NE);
+ RETURN_OP_NAME(C_XOR);
+ RETURN_OP_NAME(C_OR);
+ RETURN_OP_NAME(C_AND);
+ RETURN_OP_NAME(C_ADD);
+ RETURN_OP_NAME(C_SUB);
+ RETURN_OP_NAME(C_MUL);
+ RETURN_OP_NAME(C_DIV);
+ RETURN_OP_NAME(C_MOD);
+ RETURN_OP_NAME(C_NEG);
+ RETURN_OP_NAME(C_LNOT);
+ RETURN_OP_NAME(C_NOT);
+ RETURN_OP_NAME(C_R_SHIFT);
+ RETURN_OP_NAME(C_L_SHIFT);
+
+ default:
+ ShowDebug("script_op2name: unexpected op=%d\n", op);
+ return "???";
+ }
#undef RETURN_OP_NAME
}
#ifdef DEBUG_DUMP_STACK
-static void script_dump_stack(struct script_state *st)
-{
- int i;
- ShowMessage("\tstart = %d\n", st->start);
- ShowMessage("\tend = %d\n", st->end);
- ShowMessage("\tdefsp = %d\n", st->stack->defsp);
- ShowMessage("\tsp = %d\n", st->stack->sp);
- for (i = 0; i < st->stack->sp; ++i) {
- struct script_data *data = &st->stack->stack_data[i];
- ShowMessage("\t[%d] %s", i, script_op2name(data->type));
- switch (data->type) {
- case C_INT:
- case C_POS:
- ShowMessage(" %d\n", data->u.num);
- break;
-
- case C_STR:
- case C_CONSTSTR:
- ShowMessage(" \"%s\"\n", data->u.str);
- break;
-
- case C_NAME:
- ShowMessage(" \"%s\" (id=%d ref=%p subtype=%s)\n", reference_getname(data), data->u.num, data->ref, script_op2name(str_data[data->u.num].type));
- break;
-
- case C_RETINFO: {
- struct script_retinfo *ri = data->u.ri;
- ShowMessage(" %p {var_function=%p, script=%p, pos=%d, nargs=%d, defsp=%d}\n", ri, ri->var_function, ri->script, ri->pos, ri->nargs, ri->defsp);
- }
- break;
- default:
- ShowMessage("\n");
- break;
- }
- }
+static void script_dump_stack(struct script_state* st)
+{
+ int i;
+ ShowMessage("\tstart = %d\n", st->start);
+ ShowMessage("\tend = %d\n", st->end);
+ ShowMessage("\tdefsp = %d\n", st->stack->defsp);
+ ShowMessage("\tsp = %d\n", st->stack->sp);
+ for( i = 0; i < st->stack->sp; ++i )
+ {
+ struct script_data* data = &st->stack->stack_data[i];
+ ShowMessage("\t[%d] %s", i, script_op2name(data->type));
+ switch( data->type )
+ {
+ case C_INT:
+ case C_POS:
+ ShowMessage(" %d\n", data->u.num);
+ break;
+
+ case C_STR:
+ case C_CONSTSTR:
+ ShowMessage(" \"%s\"\n", data->u.str);
+ break;
+
+ case C_NAME:
+ ShowMessage(" \"%s\" (id=%d ref=%p subtype=%s)\n", reference_getname(data), data->u.num, data->ref, script_op2name(str_data[data->u.num].type));
+ break;
+
+ case C_RETINFO:
+ {
+ struct script_retinfo* ri = data->u.ri;
+ ShowMessage(" %p {var_function=%p, script=%p, pos=%d, nargs=%d, defsp=%d}\n", ri, ri->var_function, ri->script, ri->pos, ri->nargs, ri->defsp);
+ }
+ break;
+ default:
+ ShowMessage("\n");
+ break;
+ }
+ }
}
#endif
/// Reports on the console the src of a script error.
static void script_reportsrc(struct script_state *st)
{
- struct block_list *bl;
-
- if (st->oid == 0)
- return; //Can't report source.
-
- bl = map_id2bl(st->oid);
- if (bl == NULL)
- return;
-
- switch (bl->type) {
- case BL_NPC:
- if (bl->m >= 0)
- ShowDebug("Source (NPC): %s at %s (%d,%d)\n", ((struct npc_data *)bl)->name, map[bl->m].name, bl->x, bl->y);
- else
- ShowDebug("Source (NPC): %s (invisible/not on a map)\n", ((struct npc_data *)bl)->name);
- break;
- default:
- if (bl->m >= 0)
- ShowDebug("Source (Non-NPC type %d): name %s at %s (%d,%d)\n", bl->type, status_get_name(bl), map[bl->m].name, bl->x, bl->y);
- else
- ShowDebug("Source (Non-NPC type %d): name %s (invisible/not on a map)\n", bl->type, status_get_name(bl));
- break;
- }
+ struct block_list* bl;
+
+ if( st->oid == 0 )
+ return; //Can't report source.
+
+ bl = map_id2bl(st->oid);
+ if( bl == NULL )
+ return;
+
+ switch( bl->type )
+ {
+ case BL_NPC:
+ if( bl->m >= 0 )
+ ShowDebug("Source (NPC): %s at %s (%d,%d)\n", ((struct npc_data *)bl)->name, map[bl->m].name, bl->x, bl->y);
+ else
+ ShowDebug("Source (NPC): %s (invisible/not on a map)\n", ((struct npc_data *)bl)->name);
+ break;
+ default:
+ if( bl->m >= 0 )
+ ShowDebug("Source (Non-NPC type %d): name %s at %s (%d,%d)\n", bl->type, status_get_name(bl), map[bl->m].name, bl->x, bl->y);
+ else
+ ShowDebug("Source (Non-NPC type %d): name %s (invisible/not on a map)\n", bl->type, status_get_name(bl));
+ break;
+ }
}
/// Reports on the console information about the script data.
-static void script_reportdata(struct script_data *data)
-{
- if (data == NULL)
- return;
- switch (data->type) {
- case C_NOP:// no value
- ShowDebug("Data: nothing (nil)\n");
- break;
- case C_INT:// number
- ShowDebug("Data: number value=%d\n", data->u.num);
- break;
- case C_STR:
- case C_CONSTSTR:// string
- if (data->u.str) {
- ShowDebug("Data: string value=\"%s\"\n", data->u.str);
- } else {
- ShowDebug("Data: string value=NULL\n");
- }
- break;
- case C_NAME:// reference
- if (reference_tovariable(data)) {
- // variable
- const char *name = reference_getname(data);
- if (not_array_variable(*name))
- ShowDebug("Data: variable name='%s'\n", name);
- else
- ShowDebug("Data: variable name='%s' index=%d\n", name, reference_getindex(data));
- } else if (reference_toconstant(data)) {
- // constant
- ShowDebug("Data: constant name='%s' value=%d\n", reference_getname(data), reference_getconstant(data));
- } else if (reference_toparam(data)) {
- // param
- ShowDebug("Data: param name='%s' type=%d\n", reference_getname(data), reference_getparamtype(data));
- } else {
- // ???
- ShowDebug("Data: reference name='%s' type=%s\n", reference_getname(data), script_op2name(data->type));
- ShowDebug("Please report this!!! - str_data.type=%s\n", script_op2name(str_data[reference_getid(data)].type));
- }
- break;
- case C_POS:// label
- ShowDebug("Data: label pos=%d\n", data->u.num);
- break;
- default:
- ShowDebug("Data: %s\n", script_op2name(data->type));
- break;
- }
+static void script_reportdata(struct script_data* data)
+{
+ if( data == NULL )
+ return;
+ switch( data->type )
+ {
+ case C_NOP:// no value
+ ShowDebug("Data: nothing (nil)\n");
+ break;
+ case C_INT:// number
+ ShowDebug("Data: number value=%d\n", data->u.num);
+ break;
+ case C_STR:
+ case C_CONSTSTR:// string
+ if( data->u.str )
+ {
+ ShowDebug("Data: string value=\"%s\"\n", data->u.str);
+ }
+ else
+ {
+ ShowDebug("Data: string value=NULL\n");
+ }
+ break;
+ case C_NAME:// reference
+ if( reference_tovariable(data) )
+ {// variable
+ const char* name = reference_getname(data);
+ if( not_array_variable(*name) )
+ ShowDebug("Data: variable name='%s'\n", name);
+ else
+ ShowDebug("Data: variable name='%s' index=%d\n", name, reference_getindex(data));
+ }
+ else if( reference_toconstant(data) )
+ {// constant
+ ShowDebug("Data: constant name='%s' value=%d\n", reference_getname(data), reference_getconstant(data));
+ }
+ else if( reference_toparam(data) )
+ {// param
+ ShowDebug("Data: param name='%s' type=%d\n", reference_getname(data), reference_getparamtype(data));
+ }
+ else
+ {// ???
+ ShowDebug("Data: reference name='%s' type=%s\n", reference_getname(data), script_op2name(data->type));
+ ShowDebug("Please report this!!! - str_data.type=%s\n", script_op2name(str_data[reference_getid(data)].type));
+ }
+ break;
+ case C_POS:// label
+ ShowDebug("Data: label pos=%d\n", data->u.num);
+ break;
+ default:
+ ShowDebug("Data: %s\n", script_op2name(data->type));
+ break;
+ }
}
/// Reports on the console information about the current built-in function.
-static void script_reportfunc(struct script_state *st)
+static void script_reportfunc(struct script_state* st)
{
- int i, params, id;
- struct script_data *data;
+ int i, params, id;
+ struct script_data* data;
- if (!script_hasdata(st,0)) {
- // no stack
- return;
- }
+ if( !script_hasdata(st,0) )
+ {// no stack
+ return;
+ }
- data = script_getdata(st,0);
+ data = script_getdata(st,0);
- if (!data_isreference(data) || str_data[reference_getid(data)].type != C_FUNC) {
- // script currently not executing a built-in function or corrupt stack
- return;
- }
+ if( !data_isreference(data) || str_data[reference_getid(data)].type != C_FUNC )
+ {// script currently not executing a built-in function or corrupt stack
+ return;
+ }
- id = reference_getid(data);
- params = script_lastdata(st)-1;
+ id = reference_getid(data);
+ params = script_lastdata(st)-1;
- if (params > 0) {
- ShowDebug("Function: %s (%d parameter%s):\n", get_str(id), params, (params == 1) ? "" : "s");
+ if( params > 0 )
+ {
+ ShowDebug("Function: %s (%d parameter%s):\n", get_str(id), params, ( params == 1 ) ? "" : "s");
- for (i = 2; i <= script_lastdata(st); i++) {
- script_reportdata(script_getdata(st,i));
- }
- } else {
- ShowDebug("Function: %s (no parameters)\n", get_str(id));
- }
+ for( i = 2; i <= script_lastdata(st); i++ )
+ {
+ script_reportdata(script_getdata(st,i));
+ }
+ }
+ else
+ {
+ ShowDebug("Function: %s (no parameters)\n", get_str(id));
+ }
}
@@ -611,55 +622,57 @@ static void script_reportfunc(struct script_state *st)
*------------------------------------------*/
static void disp_error_message2(const char *mes,const char *pos,int report)
{
- error_msg = aStrdup(mes);
- error_pos = pos;
- error_report = report;
- longjmp(error_jump, 1);
+ error_msg = aStrdup(mes);
+ error_pos = pos;
+ error_report = report;
+ longjmp( error_jump, 1 );
}
#define disp_error_message(mes,pos) disp_error_message2(mes,pos,1)
/// Checks event parameter validity
static void check_event(struct script_state *st, const char *evt)
{
- if (evt && evt[0] && !stristr(evt, "::On")) {
- ShowWarning("NPC event parameter deprecated! Please use 'NPCNAME::OnEVENT' instead of '%s'.\n", evt);
- script_reportsrc(st);
- }
+ if( evt && evt[0] && !stristr(evt, "::On") )
+ {
+ ShowWarning("NPC event parameter deprecated! Please use 'NPCNAME::OnEVENT' instead of '%s'.\n", evt);
+ script_reportsrc(st);
+ }
}
/*==========================================
* Hashes the input string
*------------------------------------------*/
-static unsigned int calc_hash(const char *p)
+static unsigned int calc_hash(const char* p)
{
- unsigned int h;
+ unsigned int h;
#if defined(SCRIPT_HASH_DJB2)
- h = 5381;
- while (*p) // hash*33 + c
- h = (h << 5) + h + ((unsigned char)TOLOWER(*p++));
+ h = 5381;
+ while( *p ) // hash*33 + c
+ h = ( h << 5 ) + h + ((unsigned char)TOLOWER(*p++));
#elif defined(SCRIPT_HASH_SDBM)
- h = 0;
- while (*p) // hash*65599 + c
- h = (h << 6) + (h << 16) - h + ((unsigned char)TOLOWER(*p++));
+ h = 0;
+ while( *p ) // hash*65599 + c
+ h = ( h << 6 ) + ( h << 16 ) - h + ((unsigned char)TOLOWER(*p++));
#elif defined(SCRIPT_HASH_ELF) // UNIX ELF hash
- h = 0;
- while (*p) {
- unsigned int g;
- h = (h << 4) + ((unsigned char)TOLOWER(*p++));
- g = h & 0xF0000000;
- if (g) {
- h ^= g >> 24;
- h &= ~g;
- }
- }
+ h = 0;
+ while( *p ){
+ unsigned int g;
+ h = ( h << 4 ) + ((unsigned char)TOLOWER(*p++));
+ g = h & 0xF0000000;
+ if( g )
+ {
+ h ^= g >> 24;
+ h &= ~g;
+ }
+ }
#else // athena hash
- h = 0;
- while (*p)
- h = (h << 1) + (h >> 3) + (h >> 5) + (h >> 8) + (unsigned char)TOLOWER(*p++);
+ h = 0;
+ while( *p )
+ h = ( h << 1 ) + ( h >> 3 ) + ( h >> 5 ) + ( h >> 8 ) + (unsigned char)TOLOWER(*p++);
#endif
- return h % SCRIPT_HASH_SIZE;
+ return h % SCRIPT_HASH_SIZE;
}
@@ -668,86 +681,91 @@ static unsigned int calc_hash(const char *p)
*------------------------------------------*/
/// Looks up string using the provided id.
-const char *get_str(int id)
+const char* get_str(int id)
{
- Assert(id >= LABEL_START && id < str_size);
- return str_buf+str_data[id].str;
+ Assert( id >= LABEL_START && id < str_size );
+ return str_buf+str_data[id].str;
}
/// Returns the uid of the string, or -1.
-static int search_str(const char *p)
+static int search_str(const char* p)
{
- int i;
+ int i;
- for (i = str_hash[calc_hash(p)]; i != 0; i = str_data[i].next)
- if (strcasecmp(get_str(i),p) == 0)
- return i;
+ for( i = str_hash[calc_hash(p)]; i != 0; i = str_data[i].next )
+ if( strcasecmp(get_str(i),p) == 0 )
+ return i;
- return -1;
+ return -1;
}
/// Stores a copy of the string and returns its id.
/// If an identical string is already present, returns its id instead.
-int add_str(const char *p)
-{
- int i, h;
- int len;
-
- h = calc_hash(p);
-
- if (str_hash[h] == 0) {
- // empty bucket, add new node here
- str_hash[h] = str_num;
- } else {
- // scan for end of list, or occurence of identical string
- for (i = str_hash[h]; ; i = str_data[i].next) {
- if (strcasecmp(get_str(i),p) == 0)
- return i; // string already in list
- if (str_data[i].next == 0)
- break; // reached the end
- }
-
- // append node to end of list
- str_data[i].next = str_num;
- }
-
- // grow list if neccessary
- if (str_num >= str_data_size) {
- str_data_size += 128;
- RECREATE(str_data,struct str_data_struct,str_data_size);
- memset(str_data + (str_data_size - 128), '\0', 128);
- }
-
- len=(int)strlen(p);
-
- // grow string buffer if neccessary
- while (str_pos+len+1 >= str_size) {
- str_size += 256;
- RECREATE(str_buf,char,str_size);
- memset(str_buf + (str_size - 256), '\0', 256);
- }
-
- safestrncpy(str_buf+str_pos, p, len+1);
- 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 += len+1;
-
- return str_num++;
+int add_str(const char* p)
+{
+ int i, h;
+ int len;
+
+ h = calc_hash(p);
+
+ if( str_hash[h] == 0 )
+ {// empty bucket, add new node here
+ str_hash[h] = str_num;
+ }
+ else
+ {// scan for end of list, or occurence of identical string
+ for( i = str_hash[h]; ; i = str_data[i].next )
+ {
+ if( strcasecmp(get_str(i),p) == 0 )
+ return i; // string already in list
+ if( str_data[i].next == 0 )
+ break; // reached the end
+ }
+
+ // append node to end of list
+ str_data[i].next = str_num;
+ }
+
+ // grow list if neccessary
+ if( str_num >= str_data_size )
+ {
+ str_data_size += 128;
+ RECREATE(str_data,struct str_data_struct,str_data_size);
+ memset(str_data + (str_data_size - 128), '\0', 128);
+ }
+
+ len=(int)strlen(p);
+
+ // grow string buffer if neccessary
+ while( str_pos+len+1 >= str_size )
+ {
+ str_size += 256;
+ RECREATE(str_buf,char,str_size);
+ memset(str_buf + (str_size - 256), '\0', 256);
+ }
+
+ safestrncpy(str_buf+str_pos, p, len+1);
+ 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 += len+1;
+
+ return str_num++;
}
/// Appends 1 byte to the script buffer.
static void add_scriptb(int a)
{
- if (script_pos+1 >= script_size) {
- script_size += SCRIPT_BLOCK_SIZE;
- RECREATE(script_buf,unsigned char,script_size);
- }
- script_buf[script_pos++] = (uint8)(a);
+ if( script_pos+1 >= script_size )
+ {
+ script_size += SCRIPT_BLOCK_SIZE;
+ RECREATE(script_buf,unsigned char,script_size);
+ }
+ script_buf[script_pos++] = (uint8)(a);
}
/// Appends a c_op value to the script buffer.
@@ -756,12 +774,13 @@ static void add_scriptb(int a)
/// All blocks but the last hold 7 bits of data, topmost bit is always 1 (carries).
static void add_scriptc(int a)
{
- while (a >= 0x40) {
- add_scriptb((a&0x3f)|0x40);
- a = (a - 0x40) >> 6;
- }
+ while( a >= 0x40 )
+ {
+ add_scriptb((a&0x3f)|0x40);
+ a = (a - 0x40) >> 6;
+ }
- add_scriptb(a);
+ add_scriptb(a);
}
/// Appends an integer value to the script buffer.
@@ -770,11 +789,12 @@ static void add_scriptc(int a)
/// All blocks but the last hold 7 bits of data, topmost bit is always 1 (carries).
static void add_scripti(int a)
{
- while (a >= 0x40) {
- add_scriptb((a&0x3f)|0xc0);
- a = (a - 0x40) >> 6;
- }
- add_scriptb(a|0x80);
+ while( a >= 0x40 )
+ {
+ add_scriptb((a&0x3f)|0xc0);
+ a = (a - 0x40) >> 6;
+ }
+ add_scriptb(a|0x80);
}
/// Appends a str_data object (label/function/variable/integer) to the script buffer.
@@ -784,1319 +804,1321 @@ static void add_scripti(int a)
// Maximum up to 16M
static void add_scriptl(int l)
{
- int backpatch = str_data[l].backpatch;
-
- switch (str_data[l].type) {
- case C_POS:
- case C_USERFUNC_POS:
- add_scriptc(C_POS);
- add_scriptb(str_data[l].label);
- add_scriptb(str_data[l].label>>8);
- add_scriptb(str_data[l].label>>16);
- break;
- case C_NOP:
- case C_USERFUNC:
- // Embedded data backpatch there is a possibility of label
- add_scriptc(C_NAME);
- str_data[l].backpatch = script_pos;
- add_scriptb(backpatch);
- add_scriptb(backpatch>>8);
- add_scriptb(backpatch>>16);
- break;
- case C_INT:
- add_scripti(abs(str_data[l].val));
- if (str_data[l].val < 0) //Notice that this is negative, from jA (Rayce)
- add_scriptc(C_NEG);
- break;
- default: // assume C_NAME
- add_scriptc(C_NAME);
- add_scriptb(l);
- add_scriptb(l>>8);
- add_scriptb(l>>16);
- break;
- }
+ int backpatch = str_data[l].backpatch;
+
+ switch(str_data[l].type){
+ case C_POS:
+ case C_USERFUNC_POS:
+ add_scriptc(C_POS);
+ add_scriptb(str_data[l].label);
+ add_scriptb(str_data[l].label>>8);
+ add_scriptb(str_data[l].label>>16);
+ break;
+ case C_NOP:
+ case C_USERFUNC:
+ // Embedded data backpatch there is a possibility of label
+ add_scriptc(C_NAME);
+ str_data[l].backpatch = script_pos;
+ add_scriptb(backpatch);
+ add_scriptb(backpatch>>8);
+ add_scriptb(backpatch>>16);
+ break;
+ case C_INT:
+ add_scripti(abs(str_data[l].val));
+ if( str_data[l].val < 0 ) //Notice that this is negative, from jA (Rayce)
+ add_scriptc(C_NEG);
+ break;
+ default: // assume C_NAME
+ add_scriptc(C_NAME);
+ add_scriptb(l);
+ add_scriptb(l>>8);
+ add_scriptb(l>>16);
+ break;
+ }
}
/*==========================================
* Resolve the label
*------------------------------------------*/
-void set_label(int l,int pos, const char *script_pos)
-{
- int i,next;
-
- if (str_data[l].type==C_INT || str_data[l].type==C_PARAM || str_data[l].type==C_FUNC) {
- //Prevent overwriting constants values, parameters and built-in functions [Skotlex]
- disp_error_message("set_label: invalid label name",script_pos);
- return;
- }
- if (str_data[l].label!=-1) {
- disp_error_message("set_label: dup label ",script_pos);
- return;
- }
- str_data[l].type=(str_data[l].type == C_USERFUNC ? C_USERFUNC_POS : C_POS);
- str_data[l].label=pos;
- for (i=str_data[l].backpatch; i>=0 && i!=0x00ffffff;) {
- next=GETVALUE(script_buf,i);
- script_buf[i-1]=(str_data[l].type == C_USERFUNC ? C_USERFUNC_POS : C_POS);
- SETVALUE(script_buf,i,pos);
- i=next;
- }
+void set_label(int l,int pos, const char* script_pos)
+{
+ int i,next;
+
+ if(str_data[l].type==C_INT || str_data[l].type==C_PARAM || str_data[l].type==C_FUNC)
+ { //Prevent overwriting constants values, parameters and built-in functions [Skotlex]
+ disp_error_message("set_label: invalid label name",script_pos);
+ return;
+ }
+ if(str_data[l].label!=-1){
+ disp_error_message("set_label: dup label ",script_pos);
+ return;
+ }
+ str_data[l].type=(str_data[l].type == C_USERFUNC ? C_USERFUNC_POS : C_POS);
+ str_data[l].label=pos;
+ for(i=str_data[l].backpatch;i>=0 && i!=0x00ffffff;){
+ next=GETVALUE(script_buf,i);
+ script_buf[i-1]=(str_data[l].type == C_USERFUNC ? C_USERFUNC_POS : C_POS);
+ SETVALUE(script_buf,i,pos);
+ i=next;
+ }
}
/// Skips spaces and/or comments.
-const char *skip_space(const char *p)
-{
- if (p == NULL)
- return NULL;
- for (;;) {
- while (ISSPACE(*p))
- ++p;
- if (*p == '/' && p[1] == '/') {
- // line comment
- while (*p && *p!='\n')
- ++p;
- } else if (*p == '/' && p[1] == '*') {
- // block comment
- p += 2;
- for (;;) {
- if (*p == '\0')
- return p;//disp_error_message("script:skip_space: end of file while parsing block comment. expected "CL_BOLD"*/"CL_NORM, p);
- if (*p == '*' && p[1] == '/') {
- // end of block comment
- p += 2;
- break;
- }
- ++p;
- }
- } else
- break;
- }
- return p;
+const char* skip_space(const char* p)
+{
+ if( p == NULL )
+ return NULL;
+ for(;;)
+ {
+ while( ISSPACE(*p) )
+ ++p;
+ if( *p == '/' && p[1] == '/' )
+ {// line comment
+ while(*p && *p!='\n')
+ ++p;
+ }
+ else if( *p == '/' && p[1] == '*' )
+ {// block comment
+ p += 2;
+ for(;;)
+ {
+ if( *p == '\0' )
+ return p;//disp_error_message("script:skip_space: end of file while parsing block comment. expected "CL_BOLD"*/"CL_NORM, p);
+ if( *p == '*' && p[1] == '/' )
+ {// end of block comment
+ p += 2;
+ break;
+ }
+ ++p;
+ }
+ }
+ else
+ break;
+ }
+ return p;
}
/// Skips a word.
/// A word consists of undercores and/or alfanumeric characters,
/// and valid variable prefixes/postfixes.
static
-const char *skip_word(const char *p)
-{
- // prefix
- switch (*p) {
- case '@':// temporary char variable
- ++p;
- break;
- case '#':// account variable
- p += (p[1] == '#' ? 2 : 1);
- break;
- case '\'':// instance variable
- ++p;
- break;
- case '.':// npc variable
- p += (p[1] == '@' ? 2 : 1);
- break;
- case '$':// global variable
- p += (p[1] == '@' ? 2 : 1);
- break;
- }
+const char* skip_word(const char* p)
+{
+ // prefix
+ switch( *p )
+ {
+ case '@':// temporary char variable
+ ++p; break;
+ case '#':// account variable
+ p += ( p[1] == '#' ? 2 : 1 ); break;
+ case '\'':// instance variable
+ ++p; break;
+ case '.':// npc variable
+ p += ( p[1] == '@' ? 2 : 1 ); break;
+ case '$':// global variable
+ p += ( p[1] == '@' ? 2 : 1 ); break;
+ }
- while (ISALNUM(*p) || *p == '_')
- ++p;
+ while( ISALNUM(*p) || *p == '_' )
+ ++p;
- // postfix
- if (*p == '$') // string
- p++;
+ // postfix
+ if( *p == '$' )// string
+ p++;
- return p;
+ return p;
}
/// Adds a word to str_data.
/// @see skip_word
/// @see add_str
static
-int add_word(const char *p)
+int add_word(const char* p)
{
- char *word;
- int len;
- int i;
+ char* word;
+ int len;
+ int i;
- // Check for a word
- len = skip_word(p) - p;
- if (len == 0)
- disp_error_message("script:add_word: invalid word. A word consists of undercores and/or alfanumeric characters, and valid variable prefixes/postfixes.", p);
+ // Check for a word
+ len = skip_word(p) - p;
+ if( len == 0 )
+ disp_error_message("script:add_word: invalid word. A word consists of undercores and/or alfanumeric characters, and valid variable prefixes/postfixes.", p);
- // Duplicate the word
- word = (char *)aMalloc(len+1);
- memcpy(word, p, len);
- word[len] = 0;
+ // Duplicate the word
+ word = (char*)aMalloc(len+1);
+ memcpy(word, p, len);
+ word[len] = 0;
- // add the word
- i = add_str(word);
- aFree(word);
- return i;
+ // add the word
+ i = add_str(word);
+ aFree(word);
+ return i;
}
/// Parses a function call.
/// The argument list can have parenthesis or not.
/// The number of arguments is checked.
static
-const char *parse_callfunc(const char *p, int require_paren, int is_custom)
-{
- const char *p2;
- const char *arg=NULL;
- int func;
-
- func = add_word(p);
- if (str_data[func].type == C_FUNC) {
- // buildin function
- add_scriptl(func);
- add_scriptc(C_ARG);
- arg = buildin_func[str_data[func].val].arg;
- } else if (str_data[func].type == C_USERFUNC || str_data[func].type == C_USERFUNC_POS) {
- // script defined function
- add_scriptl(buildin_callsub_ref);
- add_scriptc(C_ARG);
- add_scriptl(func);
- arg = buildin_func[str_data[buildin_callsub_ref].val].arg;
- if (*arg == 0)
- disp_error_message("parse_callfunc: callsub has no arguments, please review it's definition",p);
- if (*arg != '*')
- ++arg; // count func as argument
- } else {
+const char* parse_callfunc(const char* p, int require_paren, int is_custom)
+{
+ const char* p2;
+ const char* arg=NULL;
+ int func;
+
+ func = add_word(p);
+ if( str_data[func].type == C_FUNC ){
+ // buildin function
+ add_scriptl(func);
+ add_scriptc(C_ARG);
+ arg = buildin_func[str_data[func].val].arg;
+ } else if( str_data[func].type == C_USERFUNC || str_data[func].type == C_USERFUNC_POS ){
+ // script defined function
+ add_scriptl(buildin_callsub_ref);
+ add_scriptc(C_ARG);
+ add_scriptl(func);
+ arg = buildin_func[str_data[buildin_callsub_ref].val].arg;
+ if( *arg == 0 )
+ disp_error_message("parse_callfunc: callsub has no arguments, please review it's definition",p);
+ if( *arg != '*' )
+ ++arg; // count func as argument
+ } else {
#ifdef SCRIPT_CALLFUNC_CHECK
- const char *name = get_str(func);
- if (!is_custom && strdb_get(userfunc_db, name) == NULL) {
+ const char* name = get_str(func);
+ if( !is_custom && strdb_get(userfunc_db, name) == NULL ) {
#endif
- disp_error_message("parse_line: expect command, missing function name or calling undeclared function",p);
+ disp_error_message("parse_line: expect command, missing function name or calling undeclared function",p);
#ifdef SCRIPT_CALLFUNC_CHECK
- } else {
- ;
- add_scriptl(buildin_callfunc_ref);
- add_scriptc(C_ARG);
- add_scriptc(C_STR);
- while (*name) add_scriptb(*name ++);
- add_scriptb(0);
- arg = buildin_func[str_data[buildin_callfunc_ref].val].arg;
- if (*arg != '*') ++ arg;
- }
+ } else {;
+ add_scriptl(buildin_callfunc_ref);
+ add_scriptc(C_ARG);
+ add_scriptc(C_STR);
+ while( *name ) add_scriptb(*name ++);
+ add_scriptb(0);
+ arg = buildin_func[str_data[buildin_callfunc_ref].val].arg;
+ if( *arg != '*' ) ++ arg;
+ }
#endif
- }
-
- p = skip_word(p);
- p = skip_space(p);
- syntax.curly[syntax.curly_count].type = TYPE_ARGLIST;
- syntax.curly[syntax.curly_count].count = 0;
- if (*p == ';') {
- // <func name> ';'
- syntax.curly[syntax.curly_count].flag = ARGLIST_NO_PAREN;
- } else if (*p == '(' && *(p2=skip_space(p+1)) == ')') {
- // <func name> '(' ')'
- syntax.curly[syntax.curly_count].flag = ARGLIST_PAREN;
- p = p2;
- /*
- } else if( 0 && require_paren && *p != '(' )
- {// <func name>
- syntax.curly[syntax.curly_count].flag = ARGLIST_NO_PAREN;
- */
- } else {
- // <func name> <arg list>
- if (require_paren) {
- if (*p != '(')
- disp_error_message("need '('",p);
- ++p; // skip '('
- syntax.curly[syntax.curly_count].flag = ARGLIST_PAREN;
- } else if (*p == '(') {
- syntax.curly[syntax.curly_count].flag = ARGLIST_UNDEFINED;
- } else {
- syntax.curly[syntax.curly_count].flag = ARGLIST_NO_PAREN;
- }
- ++syntax.curly_count;
- while (*arg) {
- p2=parse_subexpr(p,-1);
- if (p == p2)
- break; // not an argument
- if (*arg != '*')
- ++arg; // next argument
-
- p=skip_space(p2);
- if (*arg == 0 || *p != ',')
- break; // no more arguments
- ++p; // skip comma
- }
- --syntax.curly_count;
- }
- if (*arg && *arg != '?' && *arg != '*')
- disp_error_message2("parse_callfunc: not enough arguments, expected ','", p, script_config.warn_func_mismatch_paramnum);
- if (syntax.curly[syntax.curly_count].type != TYPE_ARGLIST)
- disp_error_message("parse_callfunc: DEBUG last curly is not an argument list",p);
- if (syntax.curly[syntax.curly_count].flag == ARGLIST_PAREN) {
- if (*p != ')')
- disp_error_message("parse_callfunc: expected ')' to close argument list",p);
- ++p;
- }
- add_scriptc(C_FUNC);
- return p;
+ }
+
+ p = skip_word(p);
+ p = skip_space(p);
+ syntax.curly[syntax.curly_count].type = TYPE_ARGLIST;
+ syntax.curly[syntax.curly_count].count = 0;
+ if( *p == ';' )
+ {// <func name> ';'
+ syntax.curly[syntax.curly_count].flag = ARGLIST_NO_PAREN;
+ } else if( *p == '(' && *(p2=skip_space(p+1)) == ')' )
+ {// <func name> '(' ')'
+ syntax.curly[syntax.curly_count].flag = ARGLIST_PAREN;
+ p = p2;
+ /*
+ } else if( 0 && require_paren && *p != '(' )
+ {// <func name>
+ syntax.curly[syntax.curly_count].flag = ARGLIST_NO_PAREN;
+ */
+ } else
+ {// <func name> <arg list>
+ if( require_paren ){
+ if( *p != '(' )
+ disp_error_message("need '('",p);
+ ++p; // skip '('
+ syntax.curly[syntax.curly_count].flag = ARGLIST_PAREN;
+ } else if( *p == '(' ){
+ syntax.curly[syntax.curly_count].flag = ARGLIST_UNDEFINED;
+ } else {
+ syntax.curly[syntax.curly_count].flag = ARGLIST_NO_PAREN;
+ }
+ ++syntax.curly_count;
+ while( *arg ) {
+ p2=parse_subexpr(p,-1);
+ if( p == p2 )
+ break; // not an argument
+ if( *arg != '*' )
+ ++arg; // next argument
+
+ p=skip_space(p2);
+ if( *arg == 0 || *p != ',' )
+ break; // no more arguments
+ ++p; // skip comma
+ }
+ --syntax.curly_count;
+ }
+ if( *arg && *arg != '?' && *arg != '*' )
+ disp_error_message2("parse_callfunc: not enough arguments, expected ','", p, script_config.warn_func_mismatch_paramnum);
+ if( syntax.curly[syntax.curly_count].type != TYPE_ARGLIST )
+ disp_error_message("parse_callfunc: DEBUG last curly is not an argument list",p);
+ if( syntax.curly[syntax.curly_count].flag == ARGLIST_PAREN ){
+ if( *p != ')' )
+ disp_error_message("parse_callfunc: expected ')' to close argument list",p);
+ ++p;
+ }
+ add_scriptc(C_FUNC);
+ return p;
}
/// Processes end of logical script line.
/// @param first When true, only fix up scheduling data is initialized
/// @param p Script position for error reporting in set_label
-static void parse_nextline(bool first, const char *p)
+static void parse_nextline(bool first, const char* p)
{
- if (!first) {
- add_scriptc(C_EOL); // mark end of line for stack cleanup
- set_label(LABEL_NEXTLINE, script_pos, p); // fix up '-' labels
- }
+ if( !first )
+ {
+ add_scriptc(C_EOL); // mark end of line for stack cleanup
+ set_label(LABEL_NEXTLINE, script_pos, p); // fix up '-' labels
+ }
- // initialize data for new '-' label fix up scheduling
- str_data[LABEL_NEXTLINE].type = C_NOP;
- str_data[LABEL_NEXTLINE].backpatch = -1;
- str_data[LABEL_NEXTLINE].label = -1;
+ // initialize data for new '-' label fix up scheduling
+ str_data[LABEL_NEXTLINE].type = C_NOP;
+ str_data[LABEL_NEXTLINE].backpatch = -1;
+ str_data[LABEL_NEXTLINE].label = -1;
}
/// Parse a variable assignment using the direct equals operator
/// @param p script position where the function should run from
/// @return NULL if not a variable assignment, the new position otherwise
-const char *parse_variable(const char *p)
-{
- int i, j, word;
- c_op type = C_NOP;
- const char *p2 = NULL;
- const char *var = p;
-
- // skip the variable where applicable
- p = skip_word(p);
- p = skip_space(p);
-
- if (p == NULL) { // end of the line or invalid buffer
- return NULL;
- }
-
- if (*p == '[') { // array variable so process the array as appropriate
- for (p2 = p, i = 0, j = 1; p; ++ i) {
- if (*p ++ == ']' && --(j) == 0) break;
- if (*p == '[') ++ j;
- }
-
- if (!(p = skip_space(p))) { // end of line or invalid characters remaining
- disp_error_message("Missing right expression or closing bracket for variable.", p);
- }
- }
-
- if (type == C_NOP &&
- !((p[0] == '=' && p[1] != '=' && (type = C_EQ)) // =
- || (p[0] == '+' && p[1] == '=' && (type = C_ADD)) // +=
- || (p[0] == '-' && p[1] == '=' && (type = C_SUB)) // -=
- || (p[0] == '^' && p[1] == '=' && (type = C_XOR)) // ^=
- || (p[0] == '|' && p[1] == '=' && (type = C_OR)) // |=
- || (p[0] == '&' && p[1] == '=' && (type = C_AND)) // &=
- || (p[0] == '*' && p[1] == '=' && (type = C_MUL)) // *=
- || (p[0] == '/' && p[1] == '=' && (type = C_DIV)) // /=
- || (p[0] == '%' && p[1] == '=' && (type = C_MOD)) // %=
- || (p[0] == '~' && p[1] == '=' && (type = C_NOT)) // ~=
- || (p[0] == '+' && p[1] == '+' && (type = C_ADD_PP)) // ++
- || (p[0] == '-' && p[1] == '-' && (type = C_SUB_PP)) // --
- || (p[0] == '<' && p[1] == '<' && p[2] == '=' && (type = C_L_SHIFT)) // <<=
- || (p[0] == '>' && p[1] == '>' && p[2] == '=' && (type = C_R_SHIFT)) // >>=
- )) {
- // failed to find a matching operator combination so invalid
- return NULL;
- }
-
- switch (type) {
- case C_EQ: {// incremental modifier
- p = skip_space(&p[1]);
- }
- break;
-
- case C_L_SHIFT:
- case C_R_SHIFT: {// left or right shift modifier
- p = skip_space(&p[3]);
- }
- break;
-
- default: {// normal incremental command
- p = skip_space(&p[2]);
- }
- }
-
- if (p == NULL) { // end of line or invalid buffer
- return NULL;
- }
-
- // push the set function onto the stack
- add_scriptl(buildin_set_ref);
- add_scriptc(C_ARG);
-
- // always append parenthesis to avoid errors
- syntax.curly[syntax.curly_count].type = TYPE_ARGLIST;
- syntax.curly[syntax.curly_count].count = 0;
- syntax.curly[syntax.curly_count].flag = ARGLIST_PAREN;
-
- // increment the total curly count for the position in the script
- ++ syntax.curly_count;
-
- // parse the variable currently being modified
- word = add_word(var);
-
- if (str_data[word].type == C_FUNC || str_data[word].type == C_USERFUNC || str_data[word].type == C_USERFUNC_POS) {
- // cannot assign a variable which exists as a function or label
- disp_error_message("Cannot modify a variable which has the same name as a function or label.", p);
- }
-
- if (p2) { // process the variable index
- const char *p3 = NULL;
-
- // push the getelementofarray method into the stack
- add_scriptl(buildin_getelementofarray_ref);
- add_scriptc(C_ARG);
- add_scriptl(word);
-
- // process the sub-expression for this assignment
- p3 = parse_subexpr(p2 + 1, 1);
- p3 = skip_space(p3);
-
- if (*p3 != ']') { // closing parenthesis is required for this script
- disp_error_message("Missing closing ']' parenthesis for the variable assignment.", p3);
- }
-
- // push the closing function stack operator onto the stack
- add_scriptc(C_FUNC);
- p3 ++;
- } else {// simply push the variable or value onto the stack
- add_scriptl(word);
- }
-
- if (type != C_EQ)
- add_scriptc(C_REF);
-
- if (type == C_ADD_PP || type == C_SUB_PP) { // incremental operator for the method
- add_scripti(1);
- add_scriptc(type == C_ADD_PP ? C_ADD : C_SUB);
- } else {// process the value as an expression
- p = parse_subexpr(p, -1);
-
- if (type != C_EQ) {
- // push the type of modifier onto the stack
- add_scriptc(type);
- }
- }
-
- // decrement the curly count for the position within the script
- -- syntax.curly_count;
-
- // close the script by appending the function operator
- add_scriptc(C_FUNC);
-
- // push the buffer from the method
- return p;
+const char* parse_variable(const char* p) {
+ int i, j, word;
+ c_op type = C_NOP;
+ const char *p2 = NULL;
+ const char *var = p;
+
+ // skip the variable where applicable
+ p = skip_word(p);
+ p = skip_space(p);
+
+ if( p == NULL ) {// end of the line or invalid buffer
+ return NULL;
+ }
+
+ if( *p == '[' ) {// array variable so process the array as appropriate
+ for( p2 = p, i = 0, j = 1; p; ++ i ) {
+ if( *p ++ == ']' && --(j) == 0 ) break;
+ if( *p == '[' ) ++ j;
+ }
+
+ if( !(p = skip_space(p)) ) {// end of line or invalid characters remaining
+ disp_error_message("Missing right expression or closing bracket for variable.", p);
+ }
+ }
+
+ if( type == C_NOP &&
+ !( ( p[0] == '=' && p[1] != '=' && (type = C_EQ) ) // =
+ || ( p[0] == '+' && p[1] == '=' && (type = C_ADD) ) // +=
+ || ( p[0] == '-' && p[1] == '=' && (type = C_SUB) ) // -=
+ || ( p[0] == '^' && p[1] == '=' && (type = C_XOR) ) // ^=
+ || ( p[0] == '|' && p[1] == '=' && (type = C_OR ) ) // |=
+ || ( p[0] == '&' && p[1] == '=' && (type = C_AND) ) // &=
+ || ( p[0] == '*' && p[1] == '=' && (type = C_MUL) ) // *=
+ || ( p[0] == '/' && p[1] == '=' && (type = C_DIV) ) // /=
+ || ( p[0] == '%' && p[1] == '=' && (type = C_MOD) ) // %=
+ || ( p[0] == '~' && p[1] == '=' && (type = C_NOT) ) // ~=
+ || ( p[0] == '+' && p[1] == '+' && (type = C_ADD_PP) ) // ++
+ || ( p[0] == '-' && p[1] == '-' && (type = C_SUB_PP) ) // --
+ || ( p[0] == '<' && p[1] == '<' && p[2] == '=' && (type = C_L_SHIFT) ) // <<=
+ || ( p[0] == '>' && p[1] == '>' && p[2] == '=' && (type = C_R_SHIFT) ) // >>=
+ ) )
+ {// failed to find a matching operator combination so invalid
+ return NULL;
+ }
+
+ switch( type ) {
+ case C_EQ: {// incremental modifier
+ p = skip_space( &p[1] );
+ }
+ break;
+
+ case C_L_SHIFT:
+ case C_R_SHIFT: {// left or right shift modifier
+ p = skip_space( &p[3] );
+ }
+ break;
+
+ default: {// normal incremental command
+ p = skip_space( &p[2] );
+ }
+ }
+
+ if( p == NULL ) {// end of line or invalid buffer
+ return NULL;
+ }
+
+ // push the set function onto the stack
+ add_scriptl(buildin_set_ref);
+ add_scriptc(C_ARG);
+
+ // always append parenthesis to avoid errors
+ syntax.curly[syntax.curly_count].type = TYPE_ARGLIST;
+ syntax.curly[syntax.curly_count].count = 0;
+ syntax.curly[syntax.curly_count].flag = ARGLIST_PAREN;
+
+ // increment the total curly count for the position in the script
+ ++ syntax.curly_count;
+
+ // parse the variable currently being modified
+ word = add_word(var);
+
+ if( str_data[word].type == C_FUNC || str_data[word].type == C_USERFUNC || str_data[word].type == C_USERFUNC_POS )
+ {// cannot assign a variable which exists as a function or label
+ disp_error_message("Cannot modify a variable which has the same name as a function or label.", p);
+ }
+
+ if( p2 ) {// process the variable index
+ const char* p3 = NULL;
+
+ // push the getelementofarray method into the stack
+ add_scriptl(buildin_getelementofarray_ref);
+ add_scriptc(C_ARG);
+ add_scriptl(word);
+
+ // process the sub-expression for this assignment
+ p3 = parse_subexpr(p2 + 1, 1);
+ p3 = skip_space(p3);
+
+ if( *p3 != ']' ) {// closing parenthesis is required for this script
+ disp_error_message("Missing closing ']' parenthesis for the variable assignment.", p3);
+ }
+
+ // push the closing function stack operator onto the stack
+ add_scriptc(C_FUNC);
+ p3 ++;
+ } else {// simply push the variable or value onto the stack
+ add_scriptl(word);
+ }
+
+ if( type != C_EQ )
+ add_scriptc(C_REF);
+
+ if( type == C_ADD_PP || type == C_SUB_PP ) {// incremental operator for the method
+ add_scripti(1);
+ add_scriptc(type == C_ADD_PP ? C_ADD : C_SUB);
+ } else {// process the value as an expression
+ p = parse_subexpr(p, -1);
+
+ if( type != C_EQ )
+ {// push the type of modifier onto the stack
+ add_scriptc(type);
+ }
+ }
+
+ // decrement the curly count for the position within the script
+ -- syntax.curly_count;
+
+ // close the script by appending the function operator
+ add_scriptc(C_FUNC);
+
+ // push the buffer from the method
+ return p;
}
/*==========================================
* Analysis section
*------------------------------------------*/
-const char *parse_simpleexpr(const char *p)
-{
- int i;
- p=skip_space(p);
-
- if (*p==';' || *p==',')
- disp_error_message("parse_simpleexpr: unexpected expr end",p);
- if (*p=='(') {
- if ((i=syntax.curly_count-1) >= 0 && syntax.curly[i].type == TYPE_ARGLIST)
- ++syntax.curly[i].count;
- p=parse_subexpr(p+1,-1);
- p=skip_space(p);
- if ((i=syntax.curly_count-1) >= 0 && syntax.curly[i].type == TYPE_ARGLIST &&
- syntax.curly[i].flag == ARGLIST_UNDEFINED && --syntax.curly[i].count == 0
- ) {
- if (*p == ',') {
- syntax.curly[i].flag = ARGLIST_PAREN;
- return p;
- } else
- syntax.curly[i].flag = ARGLIST_NO_PAREN;
- }
- if (*p != ')')
- disp_error_message("parse_simpleexpr: unmatch ')'",p);
- ++p;
- } else if (ISDIGIT(*p) || ((*p=='-' || *p=='+') && ISDIGIT(p[1]))) {
- char *np;
- while (*p == '0' && ISDIGIT(p[1])) p++;
- i=strtoul(p,&np,0);
- add_scripti(i);
- p=np;
- } else if (*p=='"') {
- add_scriptc(C_STR);
- p++;
- while (*p && *p != '"') {
- if ((unsigned char)p[-1] <= 0x7e && *p == '\\') {
- char buf[8];
- size_t len = skip_escaped_c(p) - p;
- size_t n = sv_unescape_c(buf, p, len);
- if (n != 1)
- ShowDebug("parse_simpleexpr: unexpected length %d after unescape (\"%.*s\" -> %.*s)\n", (int)n, (int)len, p, (int)n, buf);
- p += len;
- add_scriptb(*buf);
- continue;
- } else if (*p == '\n')
- disp_error_message("parse_simpleexpr: unexpected newline @ string",p);
- add_scriptb(*p++);
- }
- if (!*p)
- disp_error_message("parse_simpleexpr: unexpected eof @ string",p);
- add_scriptb(0);
- p++; //'"'
- } else {
- int l;
- const char *pv;
-
- // label , register , function etc
- if (skip_word(p)==p)
- disp_error_message("parse_simpleexpr: unexpected character",p);
-
- l=add_word(p);
- if (str_data[l].type == C_FUNC || str_data[l].type == C_USERFUNC || str_data[l].type == C_USERFUNC_POS)
- return parse_callfunc(p,1,0);
+const char* parse_simpleexpr(const char *p)
+{
+ int i;
+ p=skip_space(p);
+
+ if(*p==';' || *p==',')
+ disp_error_message("parse_simpleexpr: unexpected expr end",p);
+ if(*p=='('){
+ if( (i=syntax.curly_count-1) >= 0 && syntax.curly[i].type == TYPE_ARGLIST )
+ ++syntax.curly[i].count;
+ p=parse_subexpr(p+1,-1);
+ p=skip_space(p);
+ if( (i=syntax.curly_count-1) >= 0 && syntax.curly[i].type == TYPE_ARGLIST &&
+ syntax.curly[i].flag == ARGLIST_UNDEFINED && --syntax.curly[i].count == 0
+ ){
+ if( *p == ',' ){
+ syntax.curly[i].flag = ARGLIST_PAREN;
+ return p;
+ } else
+ syntax.curly[i].flag = ARGLIST_NO_PAREN;
+ }
+ if( *p != ')' )
+ disp_error_message("parse_simpleexpr: unmatch ')'",p);
+ ++p;
+ } else if(ISDIGIT(*p) || ((*p=='-' || *p=='+') && ISDIGIT(p[1]))){
+ char *np;
+ while(*p == '0' && ISDIGIT(p[1])) p++;
+ i=strtoul(p,&np,0);
+ add_scripti(i);
+ p=np;
+ } else if(*p=='"'){
+ add_scriptc(C_STR);
+ p++;
+ while( *p && *p != '"' ){
+ if( (unsigned char)p[-1] <= 0x7e && *p == '\\' )
+ {
+ char buf[8];
+ size_t len = skip_escaped_c(p) - p;
+ size_t n = sv_unescape_c(buf, p, len);
+ if( n != 1 )
+ ShowDebug("parse_simpleexpr: unexpected length %d after unescape (\"%.*s\" -> %.*s)\n", (int)n, (int)len, p, (int)n, buf);
+ p += len;
+ add_scriptb(*buf);
+ continue;
+ }
+ else if( *p == '\n' )
+ disp_error_message("parse_simpleexpr: unexpected newline @ string",p);
+ add_scriptb(*p++);
+ }
+ if(!*p)
+ disp_error_message("parse_simpleexpr: unexpected eof @ string",p);
+ add_scriptb(0);
+ p++; //'"'
+ } else {
+ int l;
+ const char* pv;
+
+ // label , register , function etc
+ if(skip_word(p)==p)
+ disp_error_message("parse_simpleexpr: unexpected character",p);
+
+ l=add_word(p);
+ if( str_data[l].type == C_FUNC || str_data[l].type == C_USERFUNC || str_data[l].type == C_USERFUNC_POS)
+ return parse_callfunc(p,1,0);
#ifdef SCRIPT_CALLFUNC_CHECK
- else {
- const char *name = get_str(l);
- if (strdb_get(userfunc_db,name) != NULL) {
- return parse_callfunc(p,1,1);
- }
- }
+ else {
+ const char* name = get_str(l);
+ if( strdb_get(userfunc_db,name) != NULL ) {
+ return parse_callfunc(p,1,1);
+ }
+ }
#endif
- if ((pv = parse_variable(p))) {
- // successfully processed a variable assignment
- return pv;
- }
+ if( (pv = parse_variable(p)) )
+ {// successfully processed a variable assignment
+ return pv;
+ }
- p=skip_word(p);
- if (*p == '[') {
- // array(name[i] => getelementofarray(name,i) )
- add_scriptl(buildin_getelementofarray_ref);
- add_scriptc(C_ARG);
- add_scriptl(l);
-
- p=parse_subexpr(p+1,-1);
- p=skip_space(p);
- if (*p != ']')
- disp_error_message("parse_simpleexpr: unmatch ']'",p);
- ++p;
- add_scriptc(C_FUNC);
- } else
- add_scriptl(l);
+ p=skip_word(p);
+ if( *p == '[' ){
+ // array(name[i] => getelementofarray(name,i) )
+ add_scriptl(buildin_getelementofarray_ref);
+ add_scriptc(C_ARG);
+ add_scriptl(l);
- }
+ p=parse_subexpr(p+1,-1);
+ p=skip_space(p);
+ if( *p != ']' )
+ disp_error_message("parse_simpleexpr: unmatch ']'",p);
+ ++p;
+ add_scriptc(C_FUNC);
+ }else
+ add_scriptl(l);
- return p;
+ }
+
+ return p;
}
/*==========================================
* Analysis of the expression
*------------------------------------------*/
-const char *parse_subexpr(const char *p,int limit)
-{
- int op,opl,len;
- const char *tmpp;
-
- p=skip_space(p);
-
- if (*p == '-') {
- tmpp = skip_space(p+1);
- if (*tmpp == ';' || *tmpp == ',') {
- add_scriptl(LABEL_NEXTLINE);
- p++;
- return p;
- }
- }
-
- if ((op=C_NEG,*p=='-') || (op=C_LNOT,*p=='!') || (op=C_NOT,*p=='~')) {
- p=parse_subexpr(p+1,10);
- add_scriptc(op);
- } else
- p=parse_simpleexpr(p);
- p=skip_space(p);
- while ((
- (op=C_OP3,opl=0,len=1,*p=='?') ||
- (op=C_ADD,opl=8,len=1,*p=='+') ||
- (op=C_SUB,opl=8,len=1,*p=='-') ||
- (op=C_MUL,opl=9,len=1,*p=='*') ||
- (op=C_DIV,opl=9,len=1,*p=='/') ||
- (op=C_MOD,opl=9,len=1,*p=='%') ||
- (op=C_LAND,opl=2,len=2,*p=='&' && p[1]=='&') ||
- (op=C_AND,opl=6,len=1,*p=='&') ||
- (op=C_LOR,opl=1,len=2,*p=='|' && p[1]=='|') ||
- (op=C_OR,opl=5,len=1,*p=='|') ||
- (op=C_XOR,opl=4,len=1,*p=='^') ||
- (op=C_EQ,opl=3,len=2,*p=='=' && p[1]=='=') ||
- (op=C_NE,opl=3,len=2,*p=='!' && p[1]=='=') ||
- (op=C_R_SHIFT,opl=7,len=2,*p=='>' && p[1]=='>') ||
- (op=C_GE,opl=3,len=2,*p=='>' && p[1]=='=') ||
- (op=C_GT,opl=3,len=1,*p=='>') ||
- (op=C_L_SHIFT,opl=7,len=2,*p=='<' && p[1]=='<') ||
- (op=C_LE,opl=3,len=2,*p=='<' && p[1]=='=') ||
- (op=C_LT,opl=3,len=1,*p=='<')) && opl>limit) {
- p+=len;
- if (op == C_OP3) {
- p=parse_subexpr(p,-1);
- p=skip_space(p);
- if (*(p++) != ':')
- disp_error_message("parse_subexpr: need ':'", p-1);
- p=parse_subexpr(p,-1);
- } else {
- p=parse_subexpr(p,opl);
- }
- add_scriptc(op);
- p=skip_space(p);
- }
-
- return p; /* return first untreated operator */
+const char* parse_subexpr(const char* p,int limit)
+{
+ int op,opl,len;
+ const char* tmpp;
+
+ p=skip_space(p);
+
+ if( *p == '-' ){
+ tmpp = skip_space(p+1);
+ if( *tmpp == ';' || *tmpp == ',' ){
+ add_scriptl(LABEL_NEXTLINE);
+ p++;
+ return p;
+ }
+ }
+
+ if((op=C_NEG,*p=='-') || (op=C_LNOT,*p=='!') || (op=C_NOT,*p=='~')){
+ p=parse_subexpr(p+1,10);
+ add_scriptc(op);
+ } else
+ p=parse_simpleexpr(p);
+ p=skip_space(p);
+ while((
+ (op=C_OP3,opl=0,len=1,*p=='?') ||
+ (op=C_ADD,opl=8,len=1,*p=='+') ||
+ (op=C_SUB,opl=8,len=1,*p=='-') ||
+ (op=C_MUL,opl=9,len=1,*p=='*') ||
+ (op=C_DIV,opl=9,len=1,*p=='/') ||
+ (op=C_MOD,opl=9,len=1,*p=='%') ||
+ (op=C_LAND,opl=2,len=2,*p=='&' && p[1]=='&') ||
+ (op=C_AND,opl=6,len=1,*p=='&') ||
+ (op=C_LOR,opl=1,len=2,*p=='|' && p[1]=='|') ||
+ (op=C_OR,opl=5,len=1,*p=='|') ||
+ (op=C_XOR,opl=4,len=1,*p=='^') ||
+ (op=C_EQ,opl=3,len=2,*p=='=' && p[1]=='=') ||
+ (op=C_NE,opl=3,len=2,*p=='!' && p[1]=='=') ||
+ (op=C_R_SHIFT,opl=7,len=2,*p=='>' && p[1]=='>') ||
+ (op=C_GE,opl=3,len=2,*p=='>' && p[1]=='=') ||
+ (op=C_GT,opl=3,len=1,*p=='>') ||
+ (op=C_L_SHIFT,opl=7,len=2,*p=='<' && p[1]=='<') ||
+ (op=C_LE,opl=3,len=2,*p=='<' && p[1]=='=') ||
+ (op=C_LT,opl=3,len=1,*p=='<')) && opl>limit){
+ p+=len;
+ if(op == C_OP3) {
+ p=parse_subexpr(p,-1);
+ p=skip_space(p);
+ if( *(p++) != ':')
+ disp_error_message("parse_subexpr: need ':'", p-1);
+ p=parse_subexpr(p,-1);
+ } else {
+ p=parse_subexpr(p,opl);
+ }
+ add_scriptc(op);
+ p=skip_space(p);
+ }
+
+ return p; /* return first untreated operator */
}
/*==========================================
* Evaluation of the expression
*------------------------------------------*/
-const char *parse_expr(const char *p)
-{
- switch (*p) {
- case ')':
- case ';':
- case ':':
- case '[':
- case ']':
- case '}':
- disp_error_message("parse_expr: unexpected char",p);
- }
- p=parse_subexpr(p,-1);
- return p;
+const char* parse_expr(const char *p)
+{
+ switch(*p){
+ case ')': case ';': case ':': case '[': case ']':
+ case '}':
+ disp_error_message("parse_expr: unexpected char",p);
+ }
+ p=parse_subexpr(p,-1);
+ return p;
}
/*==========================================
* Analysis of the line
*------------------------------------------*/
-const char *parse_line(const char *p)
-{
- const char *p2;
-
- p=skip_space(p);
- if (*p==';') {
- //Close decision for if(); for(); while();
- p = parse_syntax_close(p + 1);
- return p;
- }
- if (*p==')' && parse_syntax_for_flag)
- return p+1;
-
- p = skip_space(p);
- if (p[0] == '{') {
- syntax.curly[syntax.curly_count].type = TYPE_NULL;
- syntax.curly[syntax.curly_count].count = -1;
- syntax.curly[syntax.curly_count].index = -1;
- syntax.curly_count++;
- return p + 1;
- } else if (p[0] == '}') {
- return parse_curly_close(p);
- }
-
- // Syntax-related processing
- p2 = parse_syntax(p);
- if (p2 != NULL)
- return p2;
-
- // attempt to process a variable assignment
- p2 = parse_variable(p);
-
- if (p2 != NULL) {
- // variable assignment processed so leave the method
- return parse_syntax_close(p2 + 1);
- }
-
- p = parse_callfunc(p,0,0);
- p = skip_space(p);
-
- if (parse_syntax_for_flag) {
- if (*p != ')')
- disp_error_message("parse_line: need ')'",p);
- } else {
- if (*p != ';')
- disp_error_message("parse_line: need ';'",p);
- }
-
- //Binding decision for if(), for(), while()
- p = parse_syntax_close(p+1);
-
- return p;
+const char* parse_line(const char* p)
+{
+ const char* p2;
+
+ p=skip_space(p);
+ if(*p==';') {
+ //Close decision for if(); for(); while();
+ p = parse_syntax_close(p + 1);
+ return p;
+ }
+ if(*p==')' && parse_syntax_for_flag)
+ return p+1;
+
+ p = skip_space(p);
+ if(p[0] == '{') {
+ syntax.curly[syntax.curly_count].type = TYPE_NULL;
+ syntax.curly[syntax.curly_count].count = -1;
+ syntax.curly[syntax.curly_count].index = -1;
+ syntax.curly_count++;
+ return p + 1;
+ } else if(p[0] == '}') {
+ return parse_curly_close(p);
+ }
+
+ // Syntax-related processing
+ p2 = parse_syntax(p);
+ if(p2 != NULL)
+ return p2;
+
+ // attempt to process a variable assignment
+ p2 = parse_variable(p);
+
+ if( p2 != NULL )
+ {// variable assignment processed so leave the method
+ return parse_syntax_close(p2 + 1);
+ }
+
+ p = parse_callfunc(p,0,0);
+ p = skip_space(p);
+
+ if(parse_syntax_for_flag) {
+ if( *p != ')' )
+ disp_error_message("parse_line: need ')'",p);
+ } else {
+ if( *p != ';' )
+ disp_error_message("parse_line: need ';'",p);
+ }
+
+ //Binding decision for if(), for(), while()
+ p = parse_syntax_close(p+1);
+
+ return p;
}
// { ... } Closing process
-const char *parse_curly_close(const char *p)
-{
- if (syntax.curly_count <= 0) {
- disp_error_message("parse_curly_close: unexpected string",p);
- return p + 1;
- } else if (syntax.curly[syntax.curly_count-1].type == TYPE_NULL) {
- syntax.curly_count--;
- //Close decision if, for , while
- p = parse_syntax_close(p + 1);
- return p;
- } else if (syntax.curly[syntax.curly_count-1].type == TYPE_SWITCH) {
- //Closing switch()
- int pos = syntax.curly_count-1;
- char label[256];
- int l;
- // Remove temporary variables
- sprintf(label,"set $@__SW%x_VAL,0;",syntax.curly[pos].index);
- syntax.curly[syntax.curly_count++].type = TYPE_NULL;
- parse_line(label);
- syntax.curly_count--;
-
- // Go to the end pointer unconditionally
- sprintf(label,"goto __SW%x_FIN;",syntax.curly[pos].index);
- syntax.curly[syntax.curly_count++].type = TYPE_NULL;
- parse_line(label);
- syntax.curly_count--;
-
- // You are here labeled
- sprintf(label,"__SW%x_%x",syntax.curly[pos].index,syntax.curly[pos].count);
- l=add_str(label);
- set_label(l,script_pos, p);
-
- if (syntax.curly[pos].flag) {
- //Exists default
- sprintf(label,"goto __SW%x_DEF;",syntax.curly[pos].index);
- syntax.curly[syntax.curly_count++].type = TYPE_NULL;
- parse_line(label);
- syntax.curly_count--;
- }
-
- // Label end
- sprintf(label,"__SW%x_FIN",syntax.curly[pos].index);
- l=add_str(label);
- set_label(l,script_pos, p);
- linkdb_final(&syntax.curly[pos].case_label); // free the list of case label
- syntax.curly_count--;
- //Closing decision if, for , while
- p = parse_syntax_close(p + 1);
- return p;
- } else {
- disp_error_message("parse_curly_close: unexpected string",p);
- return p + 1;
- }
+const char* parse_curly_close(const char* p)
+{
+ if(syntax.curly_count <= 0) {
+ disp_error_message("parse_curly_close: unexpected string",p);
+ return p + 1;
+ } else if(syntax.curly[syntax.curly_count-1].type == TYPE_NULL) {
+ syntax.curly_count--;
+ //Close decision if, for , while
+ p = parse_syntax_close(p + 1);
+ return p;
+ } else if(syntax.curly[syntax.curly_count-1].type == TYPE_SWITCH) {
+ //Closing switch()
+ int pos = syntax.curly_count-1;
+ char label[256];
+ int l;
+ // Remove temporary variables
+ sprintf(label,"set $@__SW%x_VAL,0;",syntax.curly[pos].index);
+ syntax.curly[syntax.curly_count++].type = TYPE_NULL;
+ parse_line(label);
+ syntax.curly_count--;
+
+ // Go to the end pointer unconditionally
+ sprintf(label,"goto __SW%x_FIN;",syntax.curly[pos].index);
+ syntax.curly[syntax.curly_count++].type = TYPE_NULL;
+ parse_line(label);
+ syntax.curly_count--;
+
+ // You are here labeled
+ sprintf(label,"__SW%x_%x",syntax.curly[pos].index,syntax.curly[pos].count);
+ l=add_str(label);
+ set_label(l,script_pos, p);
+
+ if(syntax.curly[pos].flag) {
+ //Exists default
+ sprintf(label,"goto __SW%x_DEF;",syntax.curly[pos].index);
+ syntax.curly[syntax.curly_count++].type = TYPE_NULL;
+ parse_line(label);
+ syntax.curly_count--;
+ }
+
+ // Label end
+ sprintf(label,"__SW%x_FIN",syntax.curly[pos].index);
+ l=add_str(label);
+ set_label(l,script_pos, p);
+ linkdb_final(&syntax.curly[pos].case_label); // free the list of case label
+ syntax.curly_count--;
+ //Closing decision if, for , while
+ p = parse_syntax_close(p + 1);
+ return p;
+ } else {
+ disp_error_message("parse_curly_close: unexpected string",p);
+ return p + 1;
+ }
}
// Syntax-related processing
-// break, case, continue, default, do, for, function,
-// if, switch, while ? will handle this internally.
-const char *parse_syntax(const char *p)
-{
- const char *p2 = skip_word(p);
-
- switch (*p) {
- case 'B':
- case 'b':
- if (p2 - p == 5 && !strncasecmp(p,"break",5)) {
- // break Processing
- char label[256];
- int pos = syntax.curly_count - 1;
- while (pos >= 0) {
- if (syntax.curly[pos].type == TYPE_DO) {
- sprintf(label,"goto __DO%x_FIN;",syntax.curly[pos].index);
- break;
- } else if (syntax.curly[pos].type == TYPE_FOR) {
- sprintf(label,"goto __FR%x_FIN;",syntax.curly[pos].index);
- break;
- } else if (syntax.curly[pos].type == TYPE_WHILE) {
- sprintf(label,"goto __WL%x_FIN;",syntax.curly[pos].index);
- break;
- } else if (syntax.curly[pos].type == TYPE_SWITCH) {
- sprintf(label,"goto __SW%x_FIN;",syntax.curly[pos].index);
- break;
- }
- pos--;
- }
- if (pos < 0) {
- disp_error_message("parse_syntax: unexpected 'break'",p);
- } else {
- syntax.curly[syntax.curly_count++].type = TYPE_NULL;
- parse_line(label);
- syntax.curly_count--;
- }
- p = skip_space(p2);
- if (*p != ';')
- disp_error_message("parse_syntax: need ';'",p);
- // Closing decision if, for , while
- p = parse_syntax_close(p + 1);
- return p;
- }
- break;
- case 'c':
- case 'C':
- if (p2 - p == 4 && !strncasecmp(p,"case",4)) {
- //Processing case
- int pos = syntax.curly_count-1;
- if (pos < 0 || syntax.curly[pos].type != TYPE_SWITCH) {
- disp_error_message("parse_syntax: unexpected 'case' ",p);
- return p+1;
- } else {
- char label[256];
- int l,v;
- char *np;
- if (syntax.curly[pos].count != 1) {
- //Jump for FALLTHRU
- sprintf(label,"goto __SW%x_%xJ;",syntax.curly[pos].index,syntax.curly[pos].count);
- syntax.curly[syntax.curly_count++].type = TYPE_NULL;
- parse_line(label);
- syntax.curly_count--;
-
- // You are here labeled
- sprintf(label,"__SW%x_%x",syntax.curly[pos].index,syntax.curly[pos].count);
- l=add_str(label);
- set_label(l,script_pos, p);
- }
- //Decision statement switch
- p = skip_space(p2);
- if (p == p2) {
- disp_error_message("parse_syntax: expect space ' '",p);
- }
- // check whether case label is integer or not
- v = strtol(p,&np,0);
- if (np == p) { //Check for constants
- p2 = skip_word(p);
- v = p2-p; // length of word at p2
- memcpy(label,p,v);
- label[v]='\0';
- if (!script_get_constant(label, &v))
- disp_error_message("parse_syntax: 'case' label not integer",p);
- p = skip_word(p);
- } else { //Numeric value
- if ((*p == '-' || *p == '+') && ISDIGIT(p[1])) // pre-skip because '-' can not skip_word
- p++;
- p = skip_word(p);
- if (np != p)
- disp_error_message("parse_syntax: 'case' label not integer",np);
- }
- p = skip_space(p);
- if (*p != ':')
- disp_error_message("parse_syntax: expect ':'",p);
- sprintf(label,"if(%d != $@__SW%x_VAL) goto __SW%x_%x;",
- v,syntax.curly[pos].index,syntax.curly[pos].index,syntax.curly[pos].count+1);
- syntax.curly[syntax.curly_count++].type = TYPE_NULL;
- // Bad I do not parse twice
- p2 = parse_line(label);
- parse_line(p2);
- syntax.curly_count--;
- if (syntax.curly[pos].count != 1) {
- // Label after the completion of FALLTHRU
- sprintf(label,"__SW%x_%xJ",syntax.curly[pos].index,syntax.curly[pos].count);
- l=add_str(label);
- set_label(l,script_pos,p);
- }
- // check duplication of case label [Rayce]
- if (linkdb_search(&syntax.curly[pos].case_label, (void *)__64BPRTSIZE(v)) != NULL)
- disp_error_message("parse_syntax: dup 'case'",p);
- linkdb_insert(&syntax.curly[pos].case_label, (void *)__64BPRTSIZE(v), (void *)1);
-
- sprintf(label,"set $@__SW%x_VAL,0;",syntax.curly[pos].index);
- syntax.curly[syntax.curly_count++].type = TYPE_NULL;
-
- parse_line(label);
- syntax.curly_count--;
- syntax.curly[pos].count++;
- }
- return p + 1;
- } else if (p2 - p == 8 && !strncasecmp(p,"continue",8)) {
- // Processing continue
- char label[256];
- int pos = syntax.curly_count - 1;
- while (pos >= 0) {
- if (syntax.curly[pos].type == TYPE_DO) {
- sprintf(label,"goto __DO%x_NXT;",syntax.curly[pos].index);
- syntax.curly[pos].flag = 1; //Flag put the link for continue
- break;
- } else if (syntax.curly[pos].type == TYPE_FOR) {
- sprintf(label,"goto __FR%x_NXT;",syntax.curly[pos].index);
- break;
- } else if (syntax.curly[pos].type == TYPE_WHILE) {
- sprintf(label,"goto __WL%x_NXT;",syntax.curly[pos].index);
- break;
- }
- pos--;
- }
- if (pos < 0) {
- disp_error_message("parse_syntax: unexpected 'continue'",p);
- } else {
- syntax.curly[syntax.curly_count++].type = TYPE_NULL;
- parse_line(label);
- syntax.curly_count--;
- }
- p = skip_space(p2);
- if (*p != ';')
- disp_error_message("parse_syntax: need ';'",p);
- //Closing decision if, for , while
- p = parse_syntax_close(p + 1);
- return p;
- }
- break;
- case 'd':
- case 'D':
- if (p2 - p == 7 && !strncasecmp(p,"default",7)) {
- // Switch - default processing
- int pos = syntax.curly_count-1;
- if (pos < 0 || syntax.curly[pos].type != TYPE_SWITCH) {
- disp_error_message("parse_syntax: unexpected 'default'",p);
- } else if (syntax.curly[pos].flag) {
- disp_error_message("parse_syntax: dup 'default'",p);
- } else {
- char label[256];
- int l;
- // Put the label location
- p = skip_space(p2);
- if (*p != ':') {
- disp_error_message("parse_syntax: need ':'",p);
- }
- sprintf(label,"__SW%x_%x",syntax.curly[pos].index,syntax.curly[pos].count);
- l=add_str(label);
- set_label(l,script_pos,p);
-
- // Skip to the next link w/o condition
- sprintf(label,"goto __SW%x_%x;",syntax.curly[pos].index,syntax.curly[pos].count+1);
- syntax.curly[syntax.curly_count++].type = TYPE_NULL;
- parse_line(label);
- syntax.curly_count--;
-
- // The default label
- sprintf(label,"__SW%x_DEF",syntax.curly[pos].index);
- l=add_str(label);
- set_label(l,script_pos,p);
-
- syntax.curly[syntax.curly_count - 1].flag = 1;
- syntax.curly[pos].count++;
- }
- return p + 1;
- } else if (p2 - p == 2 && !strncasecmp(p,"do",2)) {
- int l;
- char label[256];
- p=skip_space(p2);
-
- syntax.curly[syntax.curly_count].type = TYPE_DO;
- syntax.curly[syntax.curly_count].count = 1;
- syntax.curly[syntax.curly_count].index = syntax.index++;
- syntax.curly[syntax.curly_count].flag = 0;
- // Label of the (do) form here
- sprintf(label,"__DO%x_BGN",syntax.curly[syntax.curly_count].index);
- l=add_str(label);
- set_label(l,script_pos,p);
- syntax.curly_count++;
- return p;
- }
- break;
- case 'f':
- case 'F':
- if (p2 - p == 3 && !strncasecmp(p,"for",3)) {
- int l;
- char label[256];
- int pos = syntax.curly_count;
- syntax.curly[syntax.curly_count].type = TYPE_FOR;
- syntax.curly[syntax.curly_count].count = 1;
- syntax.curly[syntax.curly_count].index = syntax.index++;
- syntax.curly[syntax.curly_count].flag = 0;
- syntax.curly_count++;
-
- p=skip_space(p2);
-
- if (*p != '(')
- disp_error_message("parse_syntax: need '('",p);
- p++;
-
- // Execute the initialization statement
- syntax.curly[syntax.curly_count++].type = TYPE_NULL;
- p=parse_line(p);
- syntax.curly_count--;
-
- // Form the start of label decision
- sprintf(label,"__FR%x_J",syntax.curly[pos].index);
- l=add_str(label);
- set_label(l,script_pos,p);
-
- p=skip_space(p);
- if (*p == ';') {
- // For (; Because the pattern of always true ;)
- ;
- } else {
- // Skip to the end point if the condition is false
- sprintf(label,"__FR%x_FIN",syntax.curly[pos].index);
- add_scriptl(add_str("jump_zero"));
- add_scriptc(C_ARG);
- p=parse_expr(p);
- p=skip_space(p);
- add_scriptl(add_str(label));
- add_scriptc(C_FUNC);
- }
- if (*p != ';')
- disp_error_message("parse_syntax: need ';'",p);
- p++;
-
- // Skip to the beginning of the loop
- sprintf(label,"goto __FR%x_BGN;",syntax.curly[pos].index);
- syntax.curly[syntax.curly_count++].type = TYPE_NULL;
- parse_line(label);
- syntax.curly_count--;
-
- // Labels to form the next loop
- sprintf(label,"__FR%x_NXT",syntax.curly[pos].index);
- l=add_str(label);
- set_label(l,script_pos,p);
-
- // Process the next time you enter the loop
- // A ')' last for; flag to be treated as'
- parse_syntax_for_flag = 1;
- syntax.curly[syntax.curly_count++].type = TYPE_NULL;
- p=parse_line(p);
- syntax.curly_count--;
- parse_syntax_for_flag = 0;
-
- // Skip to the determination process conditions
- sprintf(label,"goto __FR%x_J;",syntax.curly[pos].index);
- syntax.curly[syntax.curly_count++].type = TYPE_NULL;
- parse_line(label);
- syntax.curly_count--;
-
- // Loop start labeling
- sprintf(label,"__FR%x_BGN",syntax.curly[pos].index);
- l=add_str(label);
- set_label(l,script_pos,p);
- return p;
- } else if (p2 - p == 8 && strncasecmp(p,"function",8) == 0) {
- // internal script function
- const char *func_name;
-
- func_name = skip_space(p2);
- p = skip_word(func_name);
- if (p == func_name)
- disp_error_message("parse_syntax:function: function name is missing or invalid", p);
- p2 = skip_space(p);
- if (*p2 == ';') {
- // function <name> ;
- // function declaration - just register the name
- int l;
- l = add_word(func_name);
- if (str_data[l].type == C_NOP) // register only, if the name was not used by something else
- str_data[l].type = C_USERFUNC;
- else if (str_data[l].type == C_USERFUNC)
- ; // already registered
- else
- disp_error_message("parse_syntax:function: function name is invalid", func_name);
-
- // Close condition of if, for, while
- p = parse_syntax_close(p2 + 1);
- return p;
- } else if (*p2 == '{') {
- // function <name> <line/block of code>
- char label[256];
- int l;
-
- syntax.curly[syntax.curly_count].type = TYPE_USERFUNC;
- syntax.curly[syntax.curly_count].count = 1;
- syntax.curly[syntax.curly_count].index = syntax.index++;
- syntax.curly[syntax.curly_count].flag = 0;
- ++syntax.curly_count;
-
- // Jump over the function code
- sprintf(label, "goto __FN%x_FIN;", syntax.curly[syntax.curly_count-1].index);
- syntax.curly[syntax.curly_count].type = TYPE_NULL;
- ++syntax.curly_count;
- parse_line(label);
- --syntax.curly_count;
-
- // Set the position of the function (label)
- l=add_word(func_name);
- if (str_data[l].type == C_NOP || str_data[l].type == C_USERFUNC) { // register only, if the name was not used by something else
- str_data[l].type = C_USERFUNC;
- set_label(l, script_pos, p);
- if (parse_options&SCRIPT_USE_LABEL_DB)
- strdb_iput(scriptlabel_db, get_str(l), script_pos);
- } else
- disp_error_message("parse_syntax:function: function name is invalid", func_name);
-
- return skip_space(p);
- } else {
- disp_error_message("expect ';' or '{' at function syntax",p);
- }
- }
- break;
- case 'i':
- case 'I':
- if (p2 - p == 2 && !strncasecmp(p,"if",2)) {
- // If process
- char label[256];
- p=skip_space(p2);
- if (*p != '(') { //Prevent if this {} non-c syntax. from Rayce (jA)
- disp_error_message("need '('",p);
- }
- syntax.curly[syntax.curly_count].type = TYPE_IF;
- syntax.curly[syntax.curly_count].count = 1;
- syntax.curly[syntax.curly_count].index = syntax.index++;
- syntax.curly[syntax.curly_count].flag = 0;
- sprintf(label,"__IF%x_%x",syntax.curly[syntax.curly_count].index,syntax.curly[syntax.curly_count].count);
- syntax.curly_count++;
- add_scriptl(add_str("jump_zero"));
- add_scriptc(C_ARG);
- p=parse_expr(p);
- p=skip_space(p);
- add_scriptl(add_str(label));
- add_scriptc(C_FUNC);
- return p;
- }
- break;
- case 's':
- case 'S':
- if (p2 - p == 6 && !strncasecmp(p,"switch",6)) {
- // Processing of switch ()
- char label[256];
- p=skip_space(p2);
- if (*p != '(') {
- disp_error_message("need '('",p);
- }
- syntax.curly[syntax.curly_count].type = TYPE_SWITCH;
- syntax.curly[syntax.curly_count].count = 1;
- syntax.curly[syntax.curly_count].index = syntax.index++;
- syntax.curly[syntax.curly_count].flag = 0;
- sprintf(label,"$@__SW%x_VAL",syntax.curly[syntax.curly_count].index);
- syntax.curly_count++;
- add_scriptl(add_str("set"));
- add_scriptc(C_ARG);
- add_scriptl(add_str(label));
- p=parse_expr(p);
- p=skip_space(p);
- if (*p != '{') {
- disp_error_message("parse_syntax: need '{'",p);
- }
- add_scriptc(C_FUNC);
- return p + 1;
- }
- break;
- case 'w':
- case 'W':
- if (p2 - p == 5 && !strncasecmp(p,"while",5)) {
- int l;
- char label[256];
- p=skip_space(p2);
- if (*p != '(') {
- disp_error_message("need '('",p);
- }
- syntax.curly[syntax.curly_count].type = TYPE_WHILE;
- syntax.curly[syntax.curly_count].count = 1;
- syntax.curly[syntax.curly_count].index = syntax.index++;
- syntax.curly[syntax.curly_count].flag = 0;
- // Form the start of label decision
- sprintf(label,"__WL%x_NXT",syntax.curly[syntax.curly_count].index);
- l=add_str(label);
- set_label(l,script_pos,p);
-
- // Skip to the end point if the condition is false
- sprintf(label,"__WL%x_FIN",syntax.curly[syntax.curly_count].index);
- syntax.curly_count++;
- add_scriptl(add_str("jump_zero"));
- add_scriptc(C_ARG);
- p=parse_expr(p);
- p=skip_space(p);
- add_scriptl(add_str(label));
- add_scriptc(C_FUNC);
- return p;
- }
- break;
- }
- return NULL;
-}
-
-const char *parse_syntax_close(const char *p)
-{
- // If (...) for (...) hoge (); as to make sure closed closed once again
- int flag;
-
- do {
- p = parse_syntax_close_sub(p,&flag);
- } while (flag);
- return p;
+// break, case, continue, default, do, for, function,
+// if, switch, while ? will handle this internally.
+const char* parse_syntax(const char* p)
+{
+ const char *p2 = skip_word(p);
+
+ switch(*p) {
+ case 'B':
+ case 'b':
+ if(p2 - p == 5 && !strncasecmp(p,"break",5)) {
+ // break Processing
+ char label[256];
+ int pos = syntax.curly_count - 1;
+ while(pos >= 0) {
+ if(syntax.curly[pos].type == TYPE_DO) {
+ sprintf(label,"goto __DO%x_FIN;",syntax.curly[pos].index);
+ break;
+ } else if(syntax.curly[pos].type == TYPE_FOR) {
+ sprintf(label,"goto __FR%x_FIN;",syntax.curly[pos].index);
+ break;
+ } else if(syntax.curly[pos].type == TYPE_WHILE) {
+ sprintf(label,"goto __WL%x_FIN;",syntax.curly[pos].index);
+ break;
+ } else if(syntax.curly[pos].type == TYPE_SWITCH) {
+ sprintf(label,"goto __SW%x_FIN;",syntax.curly[pos].index);
+ break;
+ }
+ pos--;
+ }
+ if(pos < 0) {
+ disp_error_message("parse_syntax: unexpected 'break'",p);
+ } else {
+ syntax.curly[syntax.curly_count++].type = TYPE_NULL;
+ parse_line(label);
+ syntax.curly_count--;
+ }
+ p = skip_space(p2);
+ if(*p != ';')
+ disp_error_message("parse_syntax: need ';'",p);
+ // Closing decision if, for , while
+ p = parse_syntax_close(p + 1);
+ return p;
+ }
+ break;
+ case 'c':
+ case 'C':
+ if(p2 - p == 4 && !strncasecmp(p,"case",4)) {
+ //Processing case
+ int pos = syntax.curly_count-1;
+ if(pos < 0 || syntax.curly[pos].type != TYPE_SWITCH) {
+ disp_error_message("parse_syntax: unexpected 'case' ",p);
+ return p+1;
+ } else {
+ char label[256];
+ int l,v;
+ char *np;
+ if(syntax.curly[pos].count != 1) {
+ //Jump for FALLTHRU
+ sprintf(label,"goto __SW%x_%xJ;",syntax.curly[pos].index,syntax.curly[pos].count);
+ syntax.curly[syntax.curly_count++].type = TYPE_NULL;
+ parse_line(label);
+ syntax.curly_count--;
+
+ // You are here labeled
+ sprintf(label,"__SW%x_%x",syntax.curly[pos].index,syntax.curly[pos].count);
+ l=add_str(label);
+ set_label(l,script_pos, p);
+ }
+ //Decision statement switch
+ p = skip_space(p2);
+ if(p == p2) {
+ disp_error_message("parse_syntax: expect space ' '",p);
+ }
+ // check whether case label is integer or not
+ v = strtol(p,&np,0);
+ if(np == p) { //Check for constants
+ p2 = skip_word(p);
+ v = p2-p; // length of word at p2
+ memcpy(label,p,v);
+ label[v]='\0';
+ if( !script_get_constant(label, &v) )
+ disp_error_message("parse_syntax: 'case' label not integer",p);
+ p = skip_word(p);
+ } else { //Numeric value
+ if((*p == '-' || *p == '+') && ISDIGIT(p[1])) // pre-skip because '-' can not skip_word
+ p++;
+ p = skip_word(p);
+ if(np != p)
+ disp_error_message("parse_syntax: 'case' label not integer",np);
+ }
+ p = skip_space(p);
+ if(*p != ':')
+ disp_error_message("parse_syntax: expect ':'",p);
+ sprintf(label,"if(%d != $@__SW%x_VAL) goto __SW%x_%x;",
+ v,syntax.curly[pos].index,syntax.curly[pos].index,syntax.curly[pos].count+1);
+ syntax.curly[syntax.curly_count++].type = TYPE_NULL;
+ // Bad I do not parse twice
+ p2 = parse_line(label);
+ parse_line(p2);
+ syntax.curly_count--;
+ if(syntax.curly[pos].count != 1) {
+ // Label after the completion of FALLTHRU
+ sprintf(label,"__SW%x_%xJ",syntax.curly[pos].index,syntax.curly[pos].count);
+ l=add_str(label);
+ set_label(l,script_pos,p);
+ }
+ // check duplication of case label [Rayce]
+ if(linkdb_search(&syntax.curly[pos].case_label, (void*)__64BPRTSIZE(v)) != NULL)
+ disp_error_message("parse_syntax: dup 'case'",p);
+ linkdb_insert(&syntax.curly[pos].case_label, (void*)__64BPRTSIZE(v), (void*)1);
+
+ sprintf(label,"set $@__SW%x_VAL,0;",syntax.curly[pos].index);
+ syntax.curly[syntax.curly_count++].type = TYPE_NULL;
+
+ parse_line(label);
+ syntax.curly_count--;
+ syntax.curly[pos].count++;
+ }
+ return p + 1;
+ } else if(p2 - p == 8 && !strncasecmp(p,"continue",8)) {
+ // Processing continue
+ char label[256];
+ int pos = syntax.curly_count - 1;
+ while(pos >= 0) {
+ if(syntax.curly[pos].type == TYPE_DO) {
+ sprintf(label,"goto __DO%x_NXT;",syntax.curly[pos].index);
+ syntax.curly[pos].flag = 1; //Flag put the link for continue
+ break;
+ } else if(syntax.curly[pos].type == TYPE_FOR) {
+ sprintf(label,"goto __FR%x_NXT;",syntax.curly[pos].index);
+ break;
+ } else if(syntax.curly[pos].type == TYPE_WHILE) {
+ sprintf(label,"goto __WL%x_NXT;",syntax.curly[pos].index);
+ break;
+ }
+ pos--;
+ }
+ if(pos < 0) {
+ disp_error_message("parse_syntax: unexpected 'continue'",p);
+ } else {
+ syntax.curly[syntax.curly_count++].type = TYPE_NULL;
+ parse_line(label);
+ syntax.curly_count--;
+ }
+ p = skip_space(p2);
+ if(*p != ';')
+ disp_error_message("parse_syntax: need ';'",p);
+ //Closing decision if, for , while
+ p = parse_syntax_close(p + 1);
+ return p;
+ }
+ break;
+ case 'd':
+ case 'D':
+ if(p2 - p == 7 && !strncasecmp(p,"default",7)) {
+ // Switch - default processing
+ int pos = syntax.curly_count-1;
+ if(pos < 0 || syntax.curly[pos].type != TYPE_SWITCH) {
+ disp_error_message("parse_syntax: unexpected 'default'",p);
+ } else if(syntax.curly[pos].flag) {
+ disp_error_message("parse_syntax: dup 'default'",p);
+ } else {
+ char label[256];
+ int l;
+ // Put the label location
+ p = skip_space(p2);
+ if(*p != ':') {
+ disp_error_message("parse_syntax: need ':'",p);
+ }
+ sprintf(label,"__SW%x_%x",syntax.curly[pos].index,syntax.curly[pos].count);
+ l=add_str(label);
+ set_label(l,script_pos,p);
+
+ // Skip to the next link w/o condition
+ sprintf(label,"goto __SW%x_%x;",syntax.curly[pos].index,syntax.curly[pos].count+1);
+ syntax.curly[syntax.curly_count++].type = TYPE_NULL;
+ parse_line(label);
+ syntax.curly_count--;
+
+ // The default label
+ sprintf(label,"__SW%x_DEF",syntax.curly[pos].index);
+ l=add_str(label);
+ set_label(l,script_pos,p);
+
+ syntax.curly[syntax.curly_count - 1].flag = 1;
+ syntax.curly[pos].count++;
+ }
+ return p + 1;
+ } else if(p2 - p == 2 && !strncasecmp(p,"do",2)) {
+ int l;
+ char label[256];
+ p=skip_space(p2);
+
+ syntax.curly[syntax.curly_count].type = TYPE_DO;
+ syntax.curly[syntax.curly_count].count = 1;
+ syntax.curly[syntax.curly_count].index = syntax.index++;
+ syntax.curly[syntax.curly_count].flag = 0;
+ // Label of the (do) form here
+ sprintf(label,"__DO%x_BGN",syntax.curly[syntax.curly_count].index);
+ l=add_str(label);
+ set_label(l,script_pos,p);
+ syntax.curly_count++;
+ return p;
+ }
+ break;
+ case 'f':
+ case 'F':
+ if(p2 - p == 3 && !strncasecmp(p,"for",3)) {
+ int l;
+ char label[256];
+ int pos = syntax.curly_count;
+ syntax.curly[syntax.curly_count].type = TYPE_FOR;
+ syntax.curly[syntax.curly_count].count = 1;
+ syntax.curly[syntax.curly_count].index = syntax.index++;
+ syntax.curly[syntax.curly_count].flag = 0;
+ syntax.curly_count++;
+
+ p=skip_space(p2);
+
+ if(*p != '(')
+ disp_error_message("parse_syntax: need '('",p);
+ p++;
+
+ // Execute the initialization statement
+ syntax.curly[syntax.curly_count++].type = TYPE_NULL;
+ p=parse_line(p);
+ syntax.curly_count--;
+
+ // Form the start of label decision
+ sprintf(label,"__FR%x_J",syntax.curly[pos].index);
+ l=add_str(label);
+ set_label(l,script_pos,p);
+
+ p=skip_space(p);
+ if(*p == ';') {
+ // For (; Because the pattern of always true ;)
+ ;
+ } else {
+ // Skip to the end point if the condition is false
+ sprintf(label,"__FR%x_FIN",syntax.curly[pos].index);
+ add_scriptl(add_str("jump_zero"));
+ add_scriptc(C_ARG);
+ p=parse_expr(p);
+ p=skip_space(p);
+ add_scriptl(add_str(label));
+ add_scriptc(C_FUNC);
+ }
+ if(*p != ';')
+ disp_error_message("parse_syntax: need ';'",p);
+ p++;
+
+ // Skip to the beginning of the loop
+ sprintf(label,"goto __FR%x_BGN;",syntax.curly[pos].index);
+ syntax.curly[syntax.curly_count++].type = TYPE_NULL;
+ parse_line(label);
+ syntax.curly_count--;
+
+ // Labels to form the next loop
+ sprintf(label,"__FR%x_NXT",syntax.curly[pos].index);
+ l=add_str(label);
+ set_label(l,script_pos,p);
+
+ // Process the next time you enter the loop
+ // A ')' last for; flag to be treated as'
+ parse_syntax_for_flag = 1;
+ syntax.curly[syntax.curly_count++].type = TYPE_NULL;
+ p=parse_line(p);
+ syntax.curly_count--;
+ parse_syntax_for_flag = 0;
+
+ // Skip to the determination process conditions
+ sprintf(label,"goto __FR%x_J;",syntax.curly[pos].index);
+ syntax.curly[syntax.curly_count++].type = TYPE_NULL;
+ parse_line(label);
+ syntax.curly_count--;
+
+ // Loop start labeling
+ sprintf(label,"__FR%x_BGN",syntax.curly[pos].index);
+ l=add_str(label);
+ set_label(l,script_pos,p);
+ return p;
+ }
+ else if( p2 - p == 8 && strncasecmp(p,"function",8) == 0 )
+ {// internal script function
+ const char *func_name;
+
+ func_name = skip_space(p2);
+ p = skip_word(func_name);
+ if( p == func_name )
+ disp_error_message("parse_syntax:function: function name is missing or invalid", p);
+ p2 = skip_space(p);
+ if( *p2 == ';' )
+ {// function <name> ;
+ // function declaration - just register the name
+ int l;
+ l = add_word(func_name);
+ if( str_data[l].type == C_NOP )// register only, if the name was not used by something else
+ str_data[l].type = C_USERFUNC;
+ else if( str_data[l].type == C_USERFUNC )
+ ; // already registered
+ else
+ disp_error_message("parse_syntax:function: function name is invalid", func_name);
+
+ // Close condition of if, for, while
+ p = parse_syntax_close(p2 + 1);
+ return p;
+ }
+ else if(*p2 == '{')
+ {// function <name> <line/block of code>
+ char label[256];
+ int l;
+
+ syntax.curly[syntax.curly_count].type = TYPE_USERFUNC;
+ syntax.curly[syntax.curly_count].count = 1;
+ syntax.curly[syntax.curly_count].index = syntax.index++;
+ syntax.curly[syntax.curly_count].flag = 0;
+ ++syntax.curly_count;
+
+ // Jump over the function code
+ sprintf(label, "goto __FN%x_FIN;", syntax.curly[syntax.curly_count-1].index);
+ syntax.curly[syntax.curly_count].type = TYPE_NULL;
+ ++syntax.curly_count;
+ parse_line(label);
+ --syntax.curly_count;
+
+ // Set the position of the function (label)
+ l=add_word(func_name);
+ if( str_data[l].type == C_NOP || str_data[l].type == C_USERFUNC )// register only, if the name was not used by something else
+ {
+ str_data[l].type = C_USERFUNC;
+ set_label(l, script_pos, p);
+ if( parse_options&SCRIPT_USE_LABEL_DB )
+ strdb_iput(scriptlabel_db, get_str(l), script_pos);
+ }
+ else
+ disp_error_message("parse_syntax:function: function name is invalid", func_name);
+
+ return skip_space(p);
+ }
+ else
+ {
+ disp_error_message("expect ';' or '{' at function syntax",p);
+ }
+ }
+ break;
+ case 'i':
+ case 'I':
+ if(p2 - p == 2 && !strncasecmp(p,"if",2)) {
+ // If process
+ char label[256];
+ p=skip_space(p2);
+ if(*p != '(') { //Prevent if this {} non-c syntax. from Rayce (jA)
+ disp_error_message("need '('",p);
+ }
+ syntax.curly[syntax.curly_count].type = TYPE_IF;
+ syntax.curly[syntax.curly_count].count = 1;
+ syntax.curly[syntax.curly_count].index = syntax.index++;
+ syntax.curly[syntax.curly_count].flag = 0;
+ sprintf(label,"__IF%x_%x",syntax.curly[syntax.curly_count].index,syntax.curly[syntax.curly_count].count);
+ syntax.curly_count++;
+ add_scriptl(add_str("jump_zero"));
+ add_scriptc(C_ARG);
+ p=parse_expr(p);
+ p=skip_space(p);
+ add_scriptl(add_str(label));
+ add_scriptc(C_FUNC);
+ return p;
+ }
+ break;
+ case 's':
+ case 'S':
+ if(p2 - p == 6 && !strncasecmp(p,"switch",6)) {
+ // Processing of switch ()
+ char label[256];
+ p=skip_space(p2);
+ if(*p != '(') {
+ disp_error_message("need '('",p);
+ }
+ syntax.curly[syntax.curly_count].type = TYPE_SWITCH;
+ syntax.curly[syntax.curly_count].count = 1;
+ syntax.curly[syntax.curly_count].index = syntax.index++;
+ syntax.curly[syntax.curly_count].flag = 0;
+ sprintf(label,"$@__SW%x_VAL",syntax.curly[syntax.curly_count].index);
+ syntax.curly_count++;
+ add_scriptl(add_str("set"));
+ add_scriptc(C_ARG);
+ add_scriptl(add_str(label));
+ p=parse_expr(p);
+ p=skip_space(p);
+ if(*p != '{') {
+ disp_error_message("parse_syntax: need '{'",p);
+ }
+ add_scriptc(C_FUNC);
+ return p + 1;
+ }
+ break;
+ case 'w':
+ case 'W':
+ if(p2 - p == 5 && !strncasecmp(p,"while",5)) {
+ int l;
+ char label[256];
+ p=skip_space(p2);
+ if(*p != '(') {
+ disp_error_message("need '('",p);
+ }
+ syntax.curly[syntax.curly_count].type = TYPE_WHILE;
+ syntax.curly[syntax.curly_count].count = 1;
+ syntax.curly[syntax.curly_count].index = syntax.index++;
+ syntax.curly[syntax.curly_count].flag = 0;
+ // Form the start of label decision
+ sprintf(label,"__WL%x_NXT",syntax.curly[syntax.curly_count].index);
+ l=add_str(label);
+ set_label(l,script_pos,p);
+
+ // Skip to the end point if the condition is false
+ sprintf(label,"__WL%x_FIN",syntax.curly[syntax.curly_count].index);
+ syntax.curly_count++;
+ add_scriptl(add_str("jump_zero"));
+ add_scriptc(C_ARG);
+ p=parse_expr(p);
+ p=skip_space(p);
+ add_scriptl(add_str(label));
+ add_scriptc(C_FUNC);
+ return p;
+ }
+ break;
+ }
+ return NULL;
+}
+
+const char* parse_syntax_close(const char *p) {
+ // If (...) for (...) hoge (); as to make sure closed closed once again
+ int flag;
+
+ do {
+ p = parse_syntax_close_sub(p,&flag);
+ } while(flag);
+ return p;
}
// Close judgment if, for, while, of do
-// flag == 1 : closed
-// flag == 0 : not closed
-const char *parse_syntax_close_sub(const char *p,int *flag)
-{
- char label[256];
- int pos = syntax.curly_count - 1;
- int l;
- *flag = 1;
-
- if (syntax.curly_count <= 0) {
- *flag = 0;
- return p;
- } else if (syntax.curly[pos].type == TYPE_IF) {
- const char *bp = p;
- const char *p2;
-
- // if-block and else-block end is a new line
- parse_nextline(false, p);
-
- // Skip to the last location if
- sprintf(label,"goto __IF%x_FIN;",syntax.curly[pos].index);
- syntax.curly[syntax.curly_count++].type = TYPE_NULL;
- parse_line(label);
- syntax.curly_count--;
-
- // Put the label of the location
- sprintf(label,"__IF%x_%x",syntax.curly[pos].index,syntax.curly[pos].count);
- l=add_str(label);
- set_label(l,script_pos,p);
-
- syntax.curly[pos].count++;
- p = skip_space(p);
- p2 = skip_word(p);
- if (!syntax.curly[pos].flag && p2 - p == 4 && !strncasecmp(p,"else",4)) {
- // else or else - if
- p = skip_space(p2);
- p2 = skip_word(p);
- if (p2 - p == 2 && !strncasecmp(p,"if",2)) {
- // else - if
- p=skip_space(p2);
- if (*p != '(') {
- disp_error_message("need '('",p);
- }
- sprintf(label,"__IF%x_%x",syntax.curly[pos].index,syntax.curly[pos].count);
- add_scriptl(add_str("jump_zero"));
- add_scriptc(C_ARG);
- p=parse_expr(p);
- p=skip_space(p);
- add_scriptl(add_str(label));
- add_scriptc(C_FUNC);
- *flag = 0;
- return p;
- } else {
- // else
- if (!syntax.curly[pos].flag) {
- syntax.curly[pos].flag = 1;
- *flag = 0;
- return p;
- }
- }
- }
- // Close if
- syntax.curly_count--;
- // Put the label of the final location
- sprintf(label,"__IF%x_FIN",syntax.curly[pos].index);
- l=add_str(label);
- set_label(l,script_pos,p);
- if (syntax.curly[pos].flag == 1) {
- // Because the position of the pointer is the same if not else for this
- return bp;
- }
- return p;
- } else if (syntax.curly[pos].type == TYPE_DO) {
- int l;
- char label[256];
- const char *p2;
-
- if (syntax.curly[pos].flag) {
- // (Come here continue) to form the label here
- sprintf(label,"__DO%x_NXT",syntax.curly[pos].index);
- l=add_str(label);
- set_label(l,script_pos,p);
- }
-
- // Skip to the end point if the condition is false
- p = skip_space(p);
- p2 = skip_word(p);
- if (p2 - p != 5 || strncasecmp(p,"while",5))
- disp_error_message("parse_syntax: need 'while'",p);
-
- p = skip_space(p2);
- if (*p != '(') {
- disp_error_message("need '('",p);
- }
-
- // do-block end is a new line
- parse_nextline(false, p);
-
- sprintf(label,"__DO%x_FIN",syntax.curly[pos].index);
- add_scriptl(add_str("jump_zero"));
- add_scriptc(C_ARG);
- p=parse_expr(p);
- p=skip_space(p);
- add_scriptl(add_str(label));
- add_scriptc(C_FUNC);
-
- // Skip to the starting point
- sprintf(label,"goto __DO%x_BGN;",syntax.curly[pos].index);
- syntax.curly[syntax.curly_count++].type = TYPE_NULL;
- parse_line(label);
- syntax.curly_count--;
-
- // Form label of the end point conditions
- sprintf(label,"__DO%x_FIN",syntax.curly[pos].index);
- l=add_str(label);
- set_label(l,script_pos,p);
- p = skip_space(p);
- if (*p != ';') {
- disp_error_message("parse_syntax: need ';'",p);
- return p+1;
- }
- p++;
- syntax.curly_count--;
- return p;
- } else if (syntax.curly[pos].type == TYPE_FOR) {
- // for-block end is a new line
- parse_nextline(false, p);
-
- // Skip to the next loop
- sprintf(label,"goto __FR%x_NXT;",syntax.curly[pos].index);
- syntax.curly[syntax.curly_count++].type = TYPE_NULL;
- parse_line(label);
- syntax.curly_count--;
-
- // End for labeling
- sprintf(label,"__FR%x_FIN",syntax.curly[pos].index);
- l=add_str(label);
- set_label(l,script_pos,p);
- syntax.curly_count--;
- return p;
- } else if (syntax.curly[pos].type == TYPE_WHILE) {
- // while-block end is a new line
- parse_nextline(false, p);
-
- // Skip to the decision while
- sprintf(label,"goto __WL%x_NXT;",syntax.curly[pos].index);
- syntax.curly[syntax.curly_count++].type = TYPE_NULL;
- parse_line(label);
- syntax.curly_count--;
-
- // End while labeling
- sprintf(label,"__WL%x_FIN",syntax.curly[pos].index);
- l=add_str(label);
- set_label(l,script_pos,p);
- syntax.curly_count--;
- return p;
- } else if (syntax.curly[syntax.curly_count-1].type == TYPE_USERFUNC) {
- int pos = syntax.curly_count-1;
- char label[256];
- int l;
- // Back
- sprintf(label,"return;");
- syntax.curly[syntax.curly_count++].type = TYPE_NULL;
- parse_line(label);
- syntax.curly_count--;
-
- // Put the label of the location
- sprintf(label,"__FN%x_FIN",syntax.curly[pos].index);
- l=add_str(label);
- set_label(l,script_pos,p);
- syntax.curly_count--;
- return p;
- } else {
- *flag = 0;
- return p;
- }
+// flag == 1 : closed
+// flag == 0 : not closed
+const char* parse_syntax_close_sub(const char* p,int* flag)
+{
+ char label[256];
+ int pos = syntax.curly_count - 1;
+ int l;
+ *flag = 1;
+
+ if(syntax.curly_count <= 0) {
+ *flag = 0;
+ return p;
+ } else if(syntax.curly[pos].type == TYPE_IF) {
+ const char *bp = p;
+ const char *p2;
+
+ // if-block and else-block end is a new line
+ parse_nextline(false, p);
+
+ // Skip to the last location if
+ sprintf(label,"goto __IF%x_FIN;",syntax.curly[pos].index);
+ syntax.curly[syntax.curly_count++].type = TYPE_NULL;
+ parse_line(label);
+ syntax.curly_count--;
+
+ // Put the label of the location
+ sprintf(label,"__IF%x_%x",syntax.curly[pos].index,syntax.curly[pos].count);
+ l=add_str(label);
+ set_label(l,script_pos,p);
+
+ syntax.curly[pos].count++;
+ p = skip_space(p);
+ p2 = skip_word(p);
+ if(!syntax.curly[pos].flag && p2 - p == 4 && !strncasecmp(p,"else",4)) {
+ // else or else - if
+ p = skip_space(p2);
+ p2 = skip_word(p);
+ if(p2 - p == 2 && !strncasecmp(p,"if",2)) {
+ // else - if
+ p=skip_space(p2);
+ if(*p != '(') {
+ disp_error_message("need '('",p);
+ }
+ sprintf(label,"__IF%x_%x",syntax.curly[pos].index,syntax.curly[pos].count);
+ add_scriptl(add_str("jump_zero"));
+ add_scriptc(C_ARG);
+ p=parse_expr(p);
+ p=skip_space(p);
+ add_scriptl(add_str(label));
+ add_scriptc(C_FUNC);
+ *flag = 0;
+ return p;
+ } else {
+ // else
+ if(!syntax.curly[pos].flag) {
+ syntax.curly[pos].flag = 1;
+ *flag = 0;
+ return p;
+ }
+ }
+ }
+ // Close if
+ syntax.curly_count--;
+ // Put the label of the final location
+ sprintf(label,"__IF%x_FIN",syntax.curly[pos].index);
+ l=add_str(label);
+ set_label(l,script_pos,p);
+ if(syntax.curly[pos].flag == 1) {
+ // Because the position of the pointer is the same if not else for this
+ return bp;
+ }
+ return p;
+ } else if(syntax.curly[pos].type == TYPE_DO) {
+ int l;
+ char label[256];
+ const char *p2;
+
+ if(syntax.curly[pos].flag) {
+ // (Come here continue) to form the label here
+ sprintf(label,"__DO%x_NXT",syntax.curly[pos].index);
+ l=add_str(label);
+ set_label(l,script_pos,p);
+ }
+
+ // Skip to the end point if the condition is false
+ p = skip_space(p);
+ p2 = skip_word(p);
+ if(p2 - p != 5 || strncasecmp(p,"while",5))
+ disp_error_message("parse_syntax: need 'while'",p);
+
+ p = skip_space(p2);
+ if(*p != '(') {
+ disp_error_message("need '('",p);
+ }
+
+ // do-block end is a new line
+ parse_nextline(false, p);
+
+ sprintf(label,"__DO%x_FIN",syntax.curly[pos].index);
+ add_scriptl(add_str("jump_zero"));
+ add_scriptc(C_ARG);
+ p=parse_expr(p);
+ p=skip_space(p);
+ add_scriptl(add_str(label));
+ add_scriptc(C_FUNC);
+
+ // Skip to the starting point
+ sprintf(label,"goto __DO%x_BGN;",syntax.curly[pos].index);
+ syntax.curly[syntax.curly_count++].type = TYPE_NULL;
+ parse_line(label);
+ syntax.curly_count--;
+
+ // Form label of the end point conditions
+ sprintf(label,"__DO%x_FIN",syntax.curly[pos].index);
+ l=add_str(label);
+ set_label(l,script_pos,p);
+ p = skip_space(p);
+ if(*p != ';') {
+ disp_error_message("parse_syntax: need ';'",p);
+ return p+1;
+ }
+ p++;
+ syntax.curly_count--;
+ return p;
+ } else if(syntax.curly[pos].type == TYPE_FOR) {
+ // for-block end is a new line
+ parse_nextline(false, p);
+
+ // Skip to the next loop
+ sprintf(label,"goto __FR%x_NXT;",syntax.curly[pos].index);
+ syntax.curly[syntax.curly_count++].type = TYPE_NULL;
+ parse_line(label);
+ syntax.curly_count--;
+
+ // End for labeling
+ sprintf(label,"__FR%x_FIN",syntax.curly[pos].index);
+ l=add_str(label);
+ set_label(l,script_pos,p);
+ syntax.curly_count--;
+ return p;
+ } else if(syntax.curly[pos].type == TYPE_WHILE) {
+ // while-block end is a new line
+ parse_nextline(false, p);
+
+ // Skip to the decision while
+ sprintf(label,"goto __WL%x_NXT;",syntax.curly[pos].index);
+ syntax.curly[syntax.curly_count++].type = TYPE_NULL;
+ parse_line(label);
+ syntax.curly_count--;
+
+ // End while labeling
+ sprintf(label,"__WL%x_FIN",syntax.curly[pos].index);
+ l=add_str(label);
+ set_label(l,script_pos,p);
+ syntax.curly_count--;
+ return p;
+ } else if(syntax.curly[syntax.curly_count-1].type == TYPE_USERFUNC) {
+ int pos = syntax.curly_count-1;
+ char label[256];
+ int l;
+ // Back
+ sprintf(label,"return;");
+ syntax.curly[syntax.curly_count++].type = TYPE_NULL;
+ parse_line(label);
+ syntax.curly_count--;
+
+ // Put the label of the location
+ sprintf(label,"__FN%x_FIN",syntax.curly[pos].index);
+ l=add_str(label);
+ set_label(l,script_pos,p);
+ syntax.curly_count--;
+ return p;
+ } else {
+ *flag = 0;
+ return p;
+ }
}
/*==========================================
@@ -2104,69 +2126,72 @@ const char *parse_syntax_close_sub(const char *p,int *flag)
*------------------------------------------*/
static void add_buildin_func(void)
{
- int i,n;
- const char *p;
- for (i = 0; buildin_func[i].func; i++) {
- // arg must follow the pattern: (v|s|i|r|l)*\?*\*?
- // 'v' - value (either string or int or reference)
- // 's' - string
- // 'i' - int
- // 'r' - reference (of a variable)
- // 'l' - label
- // '?' - one optional parameter
- // '*' - unknown number of optional parameters
- p = buildin_func[i].arg;
- while (*p == 'v' || *p == 's' || *p == 'i' || *p == 'r' || *p == 'l') ++p;
- while (*p == '?') ++p;
- if (*p == '*') ++p;
- if (*p != 0) {
- ShowWarning("add_buildin_func: ignoring function \"%s\" with invalid arg \"%s\".\n", buildin_func[i].name, buildin_func[i].arg);
- } else if (*skip_word(buildin_func[i].name) != 0) {
- ShowWarning("add_buildin_func: ignoring function with invalid name \"%s\" (must be a word).\n", buildin_func[i].name);
- } else {
- n = add_str(buildin_func[i].name);
- str_data[n].type = C_FUNC;
- str_data[n].val = i;
- str_data[n].func = buildin_func[i].func;
+ int i,n;
+ const char* p;
+ for( i = 0; buildin_func[i].func; i++ )
+ {
+ // arg must follow the pattern: (v|s|i|r|l)*\?*\*?
+ // 'v' - value (either string or int or reference)
+ // 's' - string
+ // 'i' - int
+ // 'r' - reference (of a variable)
+ // 'l' - label
+ // '?' - one optional parameter
+ // '*' - unknown number of optional parameters
+ p = buildin_func[i].arg;
+ while( *p == 'v' || *p == 's' || *p == 'i' || *p == 'r' || *p == 'l' ) ++p;
+ while( *p == '?' ) ++p;
+ if( *p == '*' ) ++p;
+ if( *p != 0){
+ ShowWarning("add_buildin_func: ignoring function \"%s\" with invalid arg \"%s\".\n", buildin_func[i].name, buildin_func[i].arg);
+ } else if( *skip_word(buildin_func[i].name) != 0 ){
+ ShowWarning("add_buildin_func: ignoring function with invalid name \"%s\" (must be a word).\n", buildin_func[i].name);
+ } else {
+ n = add_str(buildin_func[i].name);
+ str_data[n].type = C_FUNC;
+ str_data[n].val = i;
+ str_data[n].func = buildin_func[i].func;
if (!strcmp(buildin_func[i].name, "set")) buildin_set_ref = n;
else if (!strcmp(buildin_func[i].name, "callsub")) buildin_callsub_ref = n;
else if (!strcmp(buildin_func[i].name, "callfunc")) buildin_callfunc_ref = n;
- else if (!strcmp(buildin_func[i].name, "getelementofarray")) buildin_getelementofarray_ref = n;
- }
- }
+ else if( !strcmp(buildin_func[i].name, "getelementofarray") ) buildin_getelementofarray_ref = n;
+ }
+ }
}
/// Retrieves the value of a constant.
-bool script_get_constant(const char *name, int *value)
+bool script_get_constant(const char* name, int* value)
{
- int n = search_str(name);
+ int n = search_str(name);
- if (n == -1 || str_data[n].type != C_INT) {
- // not found or not a constant
- return false;
- }
- value[0] = str_data[n].val;
+ if( n == -1 || str_data[n].type != C_INT )
+ {// not found or not a constant
+ return false;
+ }
+ value[0] = str_data[n].val;
- return true;
+ return true;
}
/// Creates new constant or parameter with given value.
-void script_set_constant(const char *name, int value, bool isparameter)
-{
- int n = add_str(name);
-
- if (str_data[n].type == C_NOP) {
- // new
- str_data[n].type = isparameter ? C_PARAM : C_INT;
- str_data[n].val = value;
- } else if (str_data[n].type == C_PARAM || str_data[n].type == C_INT) {
- // existing parameter or constant
- ShowError("script_set_constant: Attempted to overwrite existing %s '%s' (old value=%d, new value=%d).\n", (str_data[n].type == C_PARAM) ? "parameter" : "constant", name, str_data[n].val, value);
- } else {
- // existing name
- ShowError("script_set_constant: Invalid name for %s '%s' (already defined as %s).\n", isparameter ? "parameter" : "constant", name, script_op2name(str_data[n].type));
- }
+void script_set_constant(const char* name, int value, bool isparameter)
+{
+ int n = add_str(name);
+
+ if( str_data[n].type == C_NOP )
+ {// new
+ str_data[n].type = isparameter ? C_PARAM : C_INT;
+ str_data[n].val = value;
+ }
+ else if( str_data[n].type == C_PARAM || str_data[n].type == C_INT )
+ {// existing parameter or constant
+ ShowError("script_set_constant: Attempted to overwrite existing %s '%s' (old value=%d, new value=%d).\n", ( str_data[n].type == C_PARAM ) ? "parameter" : "constant", name, str_data[n].val, value);
+ }
+ else
+ {// existing name
+ ShowError("script_set_constant: Invalid name for %s '%s' (already defined as %s).\n", isparameter ? "parameter" : "constant", name, script_op2name(str_data[n].type));
+ }
}
/*==========================================
@@ -2175,615 +2200,647 @@ void script_set_constant(const char *name, int value, bool isparameter)
*------------------------------------------*/
static void read_constdb(void)
{
- FILE *fp;
- char line[1024],name[1024],val[1024];
- int type;
-
- sprintf(line, "%s/const.txt", db_path);
- fp=fopen(line, "r");
- if (fp==NULL) {
- ShowError("can't read %s\n", line);
- return ;
- }
- while (fgets(line, sizeof(line), fp)) {
- if (line[0]=='/' && line[1]=='/')
- continue;
- type=0;
- if (sscanf(line,"%[A-Za-z0-9_],%[-0-9xXA-Fa-f],%d",name,val,&type)>=2 ||
- sscanf(line,"%[A-Za-z0-9_] %[-0-9xXA-Fa-f] %d",name,val,&type)>=2) {
- script_set_constant(name, (int)strtol(val, NULL, 0), (bool)type);
- }
- }
- fclose(fp);
+ FILE *fp;
+ char line[1024],name[1024],val[1024];
+ int type;
+
+ sprintf(line, "%s/const.txt", db_path);
+ fp=fopen(line, "r");
+ if(fp==NULL){
+ ShowError("can't read %s\n", line);
+ return ;
+ }
+ while(fgets(line, sizeof(line), fp))
+ {
+ if(line[0]=='/' && line[1]=='/')
+ continue;
+ type=0;
+ if(sscanf(line,"%[A-Za-z0-9_],%[-0-9xXA-Fa-f],%d",name,val,&type)>=2 ||
+ sscanf(line,"%[A-Za-z0-9_] %[-0-9xXA-Fa-f] %d",name,val,&type)>=2){
+ script_set_constant(name, (int)strtol(val, NULL, 0), (bool)type);
+ }
+ }
+ fclose(fp);
}
/*==========================================
* Display emplacement line of script
*------------------------------------------*/
-static const char *script_print_line(StringBuf *buf, const char *p, const char *mark, int line)
-{
- int i;
- if (p == NULL || !p[0]) return NULL;
- if (line < 0)
- StringBuf_Printf(buf, "*% 5d : ", -line);
- else
- StringBuf_Printf(buf, " % 5d : ", line);
- for (i=0; p[i] && p[i] != '\n'; i++) {
- if (p + i != mark)
- StringBuf_Printf(buf, "%c", p[i]);
- else
- StringBuf_Printf(buf, "\'%c\'", p[i]);
- }
- StringBuf_AppendStr(buf, "\n");
- return p+i+(p[i] == '\n' ? 1 : 0);
-}
-
-void script_error(const char *src, const char *file, int start_line, const char *error_msg, const char *error_pos)
-{
- // Find the line where the error occurred
- int j;
- int line = start_line;
- const char *p;
- const char *linestart[5] = { NULL, NULL, NULL, NULL, NULL };
- StringBuf buf;
-
- for (p=src; p && *p; line++) {
- const char *lineend=strchr(p,'\n');
- if (lineend==NULL || error_pos<lineend) {
- break;
- }
- for (j = 0; j < 4; j++) {
- linestart[j] = linestart[j+1];
- }
- linestart[4] = p;
- p=lineend+1;
- }
-
- StringBuf_Init(&buf);
- StringBuf_AppendStr(&buf, "\a\n");
- StringBuf_Printf(&buf, "script error on %s line %d\n", file, line);
- StringBuf_Printf(&buf, " %s\n", error_msg);
- for (j = 0; j < 5; j++) {
- script_print_line(&buf, linestart[j], NULL, line + j - 5);
- }
- p = script_print_line(&buf, p, error_pos, -line);
- for (j = 0; j < 5; j++) {
- p = script_print_line(&buf, p, NULL, line + j + 1);
- }
- ShowError("%s", StringBuf_Value(&buf));
- StringBuf_Destroy(&buf);
+static const char* script_print_line(StringBuf* buf, const char* p, const char* mark, int line)
+{
+ int i;
+ if( p == NULL || !p[0] ) return NULL;
+ if( line < 0 )
+ StringBuf_Printf(buf, "*% 5d : ", -line);
+ else
+ StringBuf_Printf(buf, " % 5d : ", line);
+ for(i=0;p[i] && p[i] != '\n';i++){
+ if(p + i != mark)
+ StringBuf_Printf(buf, "%c", p[i]);
+ else
+ StringBuf_Printf(buf, "\'%c\'", p[i]);
+ }
+ StringBuf_AppendStr(buf, "\n");
+ return p+i+(p[i] == '\n' ? 1 : 0);
+}
+
+void script_error(const char* src, const char* file, int start_line, const char* error_msg, const char* error_pos)
+{
+ // Find the line where the error occurred
+ int j;
+ int line = start_line;
+ const char *p;
+ const char *linestart[5] = { NULL, NULL, NULL, NULL, NULL };
+ StringBuf buf;
+
+ for(p=src;p && *p;line++){
+ const char *lineend=strchr(p,'\n');
+ if(lineend==NULL || error_pos<lineend){
+ break;
+ }
+ for( j = 0; j < 4; j++ ) {
+ linestart[j] = linestart[j+1];
+ }
+ linestart[4] = p;
+ p=lineend+1;
+ }
+
+ StringBuf_Init(&buf);
+ StringBuf_AppendStr(&buf, "\a\n");
+ StringBuf_Printf(&buf, "script error on %s line %d\n", file, line);
+ StringBuf_Printf(&buf, " %s\n", error_msg);
+ for(j = 0; j < 5; j++ ) {
+ script_print_line(&buf, linestart[j], NULL, line + j - 5);
+ }
+ p = script_print_line(&buf, p, error_pos, -line);
+ for(j = 0; j < 5; j++) {
+ p = script_print_line(&buf, p, NULL, line + j + 1 );
+ }
+ ShowError("%s", StringBuf_Value(&buf));
+ StringBuf_Destroy(&buf);
}
/*==========================================
* Analysis of the script
*------------------------------------------*/
-struct script_code *parse_script(const char *src,const char *file,int line,int options) {
- const char *p,*tmpp;
- int i;
- struct script_code *code = NULL;
- static int first=1;
- char end;
- bool unresolved_names = false;
-
- if (src == NULL)
- return NULL;// empty script
-
- memset(&syntax,0,sizeof(syntax));
- if (first) {
- add_buildin_func();
- read_constdb();
- first=0;
- }
-
- script_buf=(unsigned char *)aMalloc(SCRIPT_BLOCK_SIZE *sizeof(unsigned char));
- script_pos=0;
- script_size=SCRIPT_BLOCK_SIZE;
- parse_nextline(true, NULL);
-
- // who called parse_script is responsible for clearing the database after using it, but just in case... lets clear it here
- if (options &SCRIPT_USE_LABEL_DB)
- db_clear(scriptlabel_db);
- parse_options = options;
-
- if (setjmp(error_jump) != 0) {
- //Restore program state when script has problems. [from jA]
- int i;
- const int size = ARRAYLENGTH(syntax.curly);
- if (error_report)
- script_error(src,file,line,error_msg,error_pos);
- aFree(error_msg);
- aFree(script_buf);
- script_pos = 0;
- script_size = 0;
- script_buf = NULL;
- for (i=LABEL_START; i<str_num; i++)
- if (str_data[i].type == C_NOP) str_data[i].type = C_NAME;
- for (i=0; i<size; i++)
- linkdb_final(&syntax.curly[i].case_label);
- return NULL;
- }
-
- parse_syntax_for_flag=0;
- p=src;
- p=skip_space(p);
- if (options &SCRIPT_IGNORE_EXTERNAL_BRACKETS) {
- // does not require brackets around the script
- if (*p == '\0' && !(options&SCRIPT_RETURN_EMPTY_SCRIPT)) {
- // empty script and can return NULL
- aFree(script_buf);
- script_pos = 0;
- script_size = 0;
- script_buf = NULL;
- return NULL;
- }
- end = '\0';
- } else {
- // requires brackets around the script
- if (*p != '{')
- disp_error_message("not found '{'",p);
- p = skip_space(p+1);
- if (*p == '}' && !(options&SCRIPT_RETURN_EMPTY_SCRIPT)) {
- // empty script and can return NULL
- aFree(script_buf);
- script_pos = 0;
- script_size = 0;
- script_buf = NULL;
- return NULL;
- }
- end = '}';
- }
-
- // clear references of labels, variables and internal functions
- for (i=LABEL_START; i<str_num; i++) {
- if (
- str_data[i].type==C_POS || str_data[i].type==C_NAME ||
- str_data[i].type==C_USERFUNC || str_data[i].type == C_USERFUNC_POS
- ) {
- str_data[i].type=C_NOP;
- str_data[i].backpatch=-1;
- str_data[i].label=-1;
- }
- }
-
- while (syntax.curly_count != 0 || *p != end) {
- if (*p == '\0')
- disp_error_message("unexpected end of script",p);
- // Special handling only label
- tmpp=skip_space(skip_word(p));
- if (*tmpp==':' && !(!strncasecmp(p,"default:",8) && p + 7 == tmpp)) {
- i=add_word(p);
- set_label(i,script_pos,p);
- if (parse_options&SCRIPT_USE_LABEL_DB)
- strdb_iput(scriptlabel_db, get_str(i), script_pos);
- p=tmpp+1;
- p=skip_space(p);
- continue;
- }
-
- // All other lumped
- p=parse_line(p);
- p=skip_space(p);
-
- parse_nextline(false, p);
- }
-
- add_scriptc(C_NOP);
-
- // trim code to size
- script_size = script_pos;
- RECREATE(script_buf,unsigned char,script_pos);
-
- // default unknown references to variables
- for (i=LABEL_START; i<str_num; i++) {
- if (str_data[i].type==C_NOP) {
- int j,next;
- str_data[i].type=C_NAME;
- str_data[i].label=i;
- for (j=str_data[i].backpatch; j>=0 && j!=0x00ffffff;) {
- next=GETVALUE(script_buf,j);
- SETVALUE(script_buf,j,i);
- j=next;
- }
- } else if (str_data[i].type == C_USERFUNC) {
- // 'function name;' without follow-up code
- ShowError("parse_script: function '%s' declared but not defined.\n", str_buf+str_data[i].str);
- unresolved_names = true;
- }
- }
-
- if (unresolved_names) {
- disp_error_message("parse_script: unresolved function references", p);
- }
+struct script_code* parse_script(const char *src,const char *file,int line,int options)
+{
+ const char *p,*tmpp;
+ int i;
+ struct script_code* code = NULL;
+ static int first=1;
+ char end;
+ bool unresolved_names = false;
+
+ if( src == NULL )
+ return NULL;// empty script
+
+ memset(&syntax,0,sizeof(syntax));
+ if(first){
+ add_buildin_func();
+ read_constdb();
+ first=0;
+ }
+
+ script_buf=(unsigned char *)aMalloc(SCRIPT_BLOCK_SIZE*sizeof(unsigned char));
+ script_pos=0;
+ script_size=SCRIPT_BLOCK_SIZE;
+ parse_nextline(true, NULL);
+
+ // who called parse_script is responsible for clearing the database after using it, but just in case... lets clear it here
+ if( options&SCRIPT_USE_LABEL_DB )
+ db_clear(scriptlabel_db);
+ parse_options = options;
+
+ if( setjmp( error_jump ) != 0 ) {
+ //Restore program state when script has problems. [from jA]
+ int i;
+ const int size = ARRAYLENGTH(syntax.curly);
+ if( error_report )
+ script_error(src,file,line,error_msg,error_pos);
+ aFree( error_msg );
+ aFree( script_buf );
+ script_pos = 0;
+ script_size = 0;
+ script_buf = NULL;
+ for(i=LABEL_START;i<str_num;i++)
+ if(str_data[i].type == C_NOP) str_data[i].type = C_NAME;
+ for(i=0; i<size; i++)
+ linkdb_final(&syntax.curly[i].case_label);
+ return NULL;
+ }
+
+ parse_syntax_for_flag=0;
+ p=src;
+ p=skip_space(p);
+ if( options&SCRIPT_IGNORE_EXTERNAL_BRACKETS )
+ {// does not require brackets around the script
+ if( *p == '\0' && !(options&SCRIPT_RETURN_EMPTY_SCRIPT) )
+ {// empty script and can return NULL
+ aFree( script_buf );
+ script_pos = 0;
+ script_size = 0;
+ script_buf = NULL;
+ return NULL;
+ }
+ end = '\0';
+ }
+ else
+ {// requires brackets around the script
+ if( *p != '{' )
+ disp_error_message("not found '{'",p);
+ p = skip_space(p+1);
+ if( *p == '}' && !(options&SCRIPT_RETURN_EMPTY_SCRIPT) )
+ {// empty script and can return NULL
+ aFree( script_buf );
+ script_pos = 0;
+ script_size = 0;
+ script_buf = NULL;
+ return NULL;
+ }
+ end = '}';
+ }
+
+ // clear references of labels, variables and internal functions
+ for(i=LABEL_START;i<str_num;i++){
+ if(
+ str_data[i].type==C_POS || str_data[i].type==C_NAME ||
+ str_data[i].type==C_USERFUNC || str_data[i].type == C_USERFUNC_POS
+ ){
+ str_data[i].type=C_NOP;
+ str_data[i].backpatch=-1;
+ str_data[i].label=-1;
+ }
+ }
+
+ while( syntax.curly_count != 0 || *p != end )
+ {
+ if( *p == '\0' )
+ disp_error_message("unexpected end of script",p);
+ // Special handling only label
+ tmpp=skip_space(skip_word(p));
+ if(*tmpp==':' && !(!strncasecmp(p,"default:",8) && p + 7 == tmpp)){
+ i=add_word(p);
+ set_label(i,script_pos,p);
+ if( parse_options&SCRIPT_USE_LABEL_DB )
+ strdb_iput(scriptlabel_db, get_str(i), script_pos);
+ p=tmpp+1;
+ p=skip_space(p);
+ continue;
+ }
+
+ // All other lumped
+ p=parse_line(p);
+ p=skip_space(p);
+
+ parse_nextline(false, p);
+ }
+
+ add_scriptc(C_NOP);
+
+ // trim code to size
+ script_size = script_pos;
+ RECREATE(script_buf,unsigned char,script_pos);
+
+ // default unknown references to variables
+ for(i=LABEL_START;i<str_num;i++){
+ if(str_data[i].type==C_NOP){
+ int j,next;
+ str_data[i].type=C_NAME;
+ str_data[i].label=i;
+ for(j=str_data[i].backpatch;j>=0 && j!=0x00ffffff;){
+ next=GETVALUE(script_buf,j);
+ SETVALUE(script_buf,j,i);
+ j=next;
+ }
+ }
+ else if( str_data[i].type == C_USERFUNC )
+ {// 'function name;' without follow-up code
+ ShowError("parse_script: function '%s' declared but not defined.\n", str_buf+str_data[i].str);
+ unresolved_names = true;
+ }
+ }
+
+ if( unresolved_names )
+ {
+ disp_error_message("parse_script: unresolved function references", p);
+ }
#ifdef DEBUG_DISP
- for (i=0; i<script_pos; i++) {
- if ((i&15)==0) ShowMessage("%04x : ",i);
- ShowMessage("%02x ",script_buf[i]);
- if ((i&15)==15) ShowMessage("\n");
- }
- ShowMessage("\n");
+ for(i=0;i<script_pos;i++){
+ if((i&15)==0) ShowMessage("%04x : ",i);
+ ShowMessage("%02x ",script_buf[i]);
+ if((i&15)==15) ShowMessage("\n");
+ }
+ ShowMessage("\n");
#endif
#ifdef DEBUG_DISASM
- {
- int i = 0,j;
- while (i < script_pos) {
- c_op op = get_com(script_buf,&i);
-
- ShowMessage("%06x %s", i, script_op2name(op));
- j = i;
- switch (op) {
- case C_INT:
- ShowMessage(" %d", get_num(script_buf,&i));
- break;
- case C_POS:
- ShowMessage(" 0x%06x", *(int *)(script_buf+i)&0xffffff);
- i += 3;
- break;
- case C_NAME:
- j = (*(int *)(script_buf+i)&0xffffff);
- ShowMessage(" %s", (j == 0xffffff) ? "?? unknown ??" : get_str(j));
- i += 3;
- break;
- case C_STR:
- j = strlen(script_buf + i);
- ShowMessage(" %s", script_buf + i);
- i += j+1;
- break;
- }
- ShowMessage(CL_CLL"\n");
- }
- }
+ {
+ int i = 0,j;
+ while(i < script_pos) {
+ c_op op = get_com(script_buf,&i);
+
+ ShowMessage("%06x %s", i, script_op2name(op));
+ j = i;
+ switch(op) {
+ case C_INT:
+ ShowMessage(" %d", get_num(script_buf,&i));
+ break;
+ case C_POS:
+ ShowMessage(" 0x%06x", *(int*)(script_buf+i)&0xffffff);
+ i += 3;
+ break;
+ case C_NAME:
+ j = (*(int*)(script_buf+i)&0xffffff);
+ ShowMessage(" %s", ( j == 0xffffff ) ? "?? unknown ??" : get_str(j));
+ i += 3;
+ break;
+ case C_STR:
+ j = strlen(script_buf + i);
+ ShowMessage(" %s", script_buf + i);
+ i += j+1;
+ break;
+ }
+ ShowMessage(CL_CLL"\n");
+ }
+ }
#endif
- CREATE(code,struct script_code,1);
- code->script_buf = script_buf;
- code->script_size = script_size;
- code->script_vars = idb_alloc(DB_OPT_RELEASE_DATA);
- return code;
+ CREATE(code,struct script_code,1);
+ code->script_buf = script_buf;
+ code->script_size = script_size;
+ code->script_vars = idb_alloc(DB_OPT_RELEASE_DATA);
+ return code;
}
/// Returns the player attached to this script, identified by the rid.
/// If there is no player attached, the script is terminated.
TBL_PC *script_rid2sd(struct script_state *st)
{
- TBL_PC *sd=map_id2sd(st->rid);
- if (!sd) {
- ShowError("script_rid2sd: fatal error ! player not attached!\n");
- script_reportfunc(st);
- script_reportsrc(st);
- st->state = END;
- }
- return sd;
+ TBL_PC *sd=map_id2sd(st->rid);
+ if(!sd){
+ ShowError("script_rid2sd: fatal error ! player not attached!\n");
+ script_reportfunc(st);
+ script_reportsrc(st);
+ st->state = END;
+ }
+ return sd;
}
/// Dereferences a variable/constant, replacing it with a copy of the value.
///
/// @param st Script state
/// @param data Variable/constant
-void get_val(struct script_state *st, struct script_data *data)
-{
- const char *name;
- char prefix;
- char postfix;
- TBL_PC *sd = NULL;
-
- if (!data_isreference(data))
- return;// not a variable/constant
-
- name = reference_getname(data);
- prefix = name[0];
- postfix = name[strlen(name) - 1];
-
- //##TODO use reference_tovariable(data) when it's confirmed that it works [FlavioJS]
- if (!reference_toconstant(data) && not_server_variable(prefix)) {
- sd = script_rid2sd(st);
- if (sd == NULL) {
- // needs player attached
- if (postfix == '$') {
- // string variable
- ShowWarning("script:get_val: cannot access player variable '%s', defaulting to \"\"\n", name);
- data->type = C_CONSTSTR;
- data->u.str = "";
- } else {
- // integer variable
- ShowWarning("script:get_val: cannot access player variable '%s', defaulting to 0\n", name);
- data->type = C_INT;
- data->u.num = 0;
- }
- return;
- }
- }
-
- if (postfix == '$') {
- // string variable
-
- switch (prefix) {
- case '@':
- data->u.str = pc_readregstr(sd, data->u.num);
- break;
- case '$':
- data->u.str = mapreg_readregstr(data->u.num);
- break;
- case '#':
- if (name[1] == '#')
- data->u.str = pc_readaccountreg2str(sd, name);// global
- else
- data->u.str = pc_readaccountregstr(sd, name);// local
- break;
- case '.': {
- struct DBMap *n =
- data->ref ? *data->ref:
- name[1] == '@' ? st->stack->var_function:// instance/scope variable
- st->script->script_vars;// npc variable
- if (n)
- data->u.str = (char *)idb_get(n,reference_getuid(data));
- else
- data->u.str = NULL;
- }
- break;
- case '\'':
- if (st->instance_id) {
- data->u.str = (char *)idb_get(instance[st->instance_id].vars,reference_getuid(data));
- } else {
- ShowWarning("script:get_val: cannot access instance variable '%s', defaulting to \"\"\n", name);
- data->u.str = NULL;
- }
- break;
- default:
- data->u.str = pc_readglobalreg_str(sd, name);
- break;
- }
-
- if (data->u.str == NULL || data->u.str[0] == '\0') {
- // empty string
- data->type = C_CONSTSTR;
- data->u.str = "";
- } else {
- // duplicate string
- data->type = C_STR;
- data->u.str = aStrdup(data->u.str);
- }
-
- } else {
- // integer variable
-
- data->type = C_INT;
-
- if (reference_toconstant(data)) {
- data->u.num = reference_getconstant(data);
- } else if (reference_toparam(data)) {
- data->u.num = pc_readparam(sd, reference_getparamtype(data));
- } else
- switch (prefix) {
- case '@':
- data->u.num = pc_readreg(sd, data->u.num);
- break;
- case '$':
- data->u.num = mapreg_readreg(data->u.num);
- break;
- case '#':
- if (name[1] == '#')
- data->u.num = pc_readaccountreg2(sd, name);// global
- else
- data->u.num = pc_readaccountreg(sd, name);// local
- break;
- case '.': {
- struct DBMap *n =
- data->ref ? *data->ref:
- name[1] == '@' ? st->stack->var_function:// instance/scope variable
- st->script->script_vars;// npc variable
- if (n)
- data->u.num = (int)idb_iget(n,reference_getuid(data));
- else
- data->u.num = 0;
- }
- break;
- case '\'':
- if (st->instance_id)
- data->u.num = (int)idb_iget(instance[st->instance_id].vars,reference_getuid(data));
- else {
- ShowWarning("script:get_val: cannot access instance variable '%s', defaulting to 0\n", name);
- data->u.num = 0;
- }
- break;
- default:
- data->u.num = pc_readglobalreg(sd, name);
- break;
- }
-
- }
-
- return;
-}
-
-struct script_data *push_val2(struct script_stack *stack, enum c_op type, int val, struct DBMap **ref);
+void get_val(struct script_state* st, struct script_data* data)
+{
+ const char* name;
+ char prefix;
+ char postfix;
+ TBL_PC* sd = NULL;
+
+ if( !data_isreference(data) )
+ return;// not a variable/constant
+
+ name = reference_getname(data);
+ prefix = name[0];
+ postfix = name[strlen(name) - 1];
+
+ //##TODO use reference_tovariable(data) when it's confirmed that it works [FlavioJS]
+ if( !reference_toconstant(data) && not_server_variable(prefix) )
+ {
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ {// needs player attached
+ if( postfix == '$' )
+ {// string variable
+ ShowWarning("script:get_val: cannot access player variable '%s', defaulting to \"\"\n", name);
+ data->type = C_CONSTSTR;
+ data->u.str = "";
+ }
+ else
+ {// integer variable
+ ShowWarning("script:get_val: cannot access player variable '%s', defaulting to 0\n", name);
+ data->type = C_INT;
+ data->u.num = 0;
+ }
+ return;
+ }
+ }
+
+ if( postfix == '$' )
+ {// string variable
+
+ switch( prefix )
+ {
+ case '@':
+ data->u.str = pc_readregstr(sd, data->u.num);
+ break;
+ case '$':
+ data->u.str = mapreg_readregstr(data->u.num);
+ break;
+ case '#':
+ if( name[1] == '#' )
+ data->u.str = pc_readaccountreg2str(sd, name);// global
+ else
+ data->u.str = pc_readaccountregstr(sd, name);// local
+ break;
+ case '.':
+ {
+ struct DBMap* n =
+ data->ref ? *data->ref:
+ name[1] == '@' ? st->stack->var_function:// instance/scope variable
+ st->script->script_vars;// npc variable
+ if( n )
+ data->u.str = (char*)idb_get(n,reference_getuid(data));
+ else
+ data->u.str = NULL;
+ }
+ break;
+ case '\'':
+ if (st->instance_id) {
+ data->u.str = (char*)idb_get(instance[st->instance_id].vars,reference_getuid(data));
+ } else {
+ ShowWarning("script:get_val: cannot access instance variable '%s', defaulting to \"\"\n", name);
+ data->u.str = NULL;
+ }
+ break;
+ default:
+ data->u.str = pc_readglobalreg_str(sd, name);
+ break;
+ }
+
+ if( data->u.str == NULL || data->u.str[0] == '\0' )
+ {// empty string
+ data->type = C_CONSTSTR;
+ data->u.str = "";
+ }
+ else
+ {// duplicate string
+ data->type = C_STR;
+ data->u.str = aStrdup(data->u.str);
+ }
+
+ }
+ else
+ {// integer variable
+
+ data->type = C_INT;
+
+ if( reference_toconstant(data) )
+ {
+ data->u.num = reference_getconstant(data);
+ }
+ else if( reference_toparam(data) )
+ {
+ data->u.num = pc_readparam(sd, reference_getparamtype(data));
+ }
+ else
+ switch( prefix )
+ {
+ case '@':
+ data->u.num = pc_readreg(sd, data->u.num);
+ break;
+ case '$':
+ data->u.num = mapreg_readreg(data->u.num);
+ break;
+ case '#':
+ if( name[1] == '#' )
+ data->u.num = pc_readaccountreg2(sd, name);// global
+ else
+ data->u.num = pc_readaccountreg(sd, name);// local
+ break;
+ case '.':
+ {
+ struct DBMap* n =
+ data->ref ? *data->ref:
+ name[1] == '@' ? st->stack->var_function:// instance/scope variable
+ st->script->script_vars;// npc variable
+ if( n )
+ data->u.num = (int)idb_iget(n,reference_getuid(data));
+ else
+ data->u.num = 0;
+ }
+ break;
+ case '\'':
+ if( st->instance_id )
+ data->u.num = (int)idb_iget(instance[st->instance_id].vars,reference_getuid(data));
+ else {
+ ShowWarning("script:get_val: cannot access instance variable '%s', defaulting to 0\n", name);
+ data->u.num = 0;
+ }
+ break;
+ default:
+ data->u.num = pc_readglobalreg(sd, name);
+ break;
+ }
+
+ }
+
+ return;
+}
+
+struct script_data* push_val2(struct script_stack* stack, enum c_op type, int val, struct DBMap** ref);
/// Retrieves the value of a reference identified by uid (variable, constant, param)
/// The value is left in the top of the stack and needs to be removed manually.
-void *get_val2(struct script_state *st, int uid, struct DBMap **ref)
+void* get_val2(struct script_state* st, int uid, struct DBMap** ref)
{
- struct script_data *data;
- push_val2(st->stack, C_NAME, uid, ref);
- data = script_getdatatop(st, -1);
- get_val(st, data);
- return (data->type == C_INT ? (void *)__64BPRTSIZE(data->u.num) : (void *)__64BPRTSIZE(data->u.str));
+ struct script_data* data;
+ push_val2(st->stack, C_NAME, uid, ref);
+ data = script_getdatatop(st, -1);
+ get_val(st, data);
+ return (data->type == C_INT ? (void*)__64BPRTSIZE(data->u.num) : (void*)__64BPRTSIZE(data->u.str));
}
/*==========================================
* Stores the value of a script variable
* Return value is 0 on fail, 1 on success.
*------------------------------------------*/
-static int set_reg(struct script_state *st, TBL_PC *sd, int num, const char *name, const void *value, struct DBMap **ref)
-{
- char prefix = name[0];
-
- if (is_string_variable(name)) {
- // string variable
- const char *str = (const char *)value;
- switch (prefix) {
- case '@':
- return pc_setregstr(sd, num, str);
- case '$':
- return mapreg_setregstr(num, str);
- case '#':
- return (name[1] == '#') ?
- pc_setaccountreg2str(sd, name, str) :
- pc_setaccountregstr(sd, name, str);
- case '.': {
- struct DBMap *n;
- n = (ref) ? *ref : (name[1] == '@') ? st->stack->var_function : st->script->script_vars;
- if (n) {
- idb_remove(n, num);
- if (str[0]) idb_put(n, num, aStrdup(str));
- }
- }
- return 1;
- case '\'':
- if (st->instance_id) {
- idb_remove(instance[st->instance_id].vars, num);
- if (str[0]) idb_put(instance[st->instance_id].vars, num, aStrdup(str));
- }
- return 1;
- default:
- return pc_setglobalreg_str(sd, name, str);
- }
- } else {
- // integer variable
- int val = (int)__64BPRTSIZE(value);
- if (str_data[num&0x00ffffff].type == C_PARAM) {
- if (pc_setparam(sd, str_data[num&0x00ffffff].val, val) == 0) {
- if (st != NULL) {
- ShowError("script:set_reg: failed to set param '%s' to %d.\n", name, val);
- script_reportsrc(st);
- st->state = END;
- }
- return 0;
- }
- return 1;
- }
-
- switch (prefix) {
- case '@':
- return pc_setreg(sd, num, val);
- case '$':
- return mapreg_setreg(num, val);
- case '#':
- return (name[1] == '#') ?
- pc_setaccountreg2(sd, name, val) :
- pc_setaccountreg(sd, name, val);
- case '.': {
- struct DBMap *n;
- n = (ref) ? *ref : (name[1] == '@') ? st->stack->var_function : st->script->script_vars;
- if (n) {
- idb_remove(n, num);
- if (val != 0)
- idb_iput(n, num, val);
- }
- }
- return 1;
- case '\'':
- if (st->instance_id) {
- idb_remove(instance[st->instance_id].vars, num);
- if (val != 0)
- idb_iput(instance[st->instance_id].vars, num, val);
- }
- return 1;
- default:
- return pc_setglobalreg(sd, name, val);
- }
- }
-}
-
-int set_var(TBL_PC *sd, char *name, void *val)
+static int set_reg(struct script_state* st, TBL_PC* sd, int num, const char* name, const void* value, struct DBMap** ref)
+{
+ char prefix = name[0];
+
+ if( is_string_variable(name) )
+ {// string variable
+ const char* str = (const char*)value;
+ switch (prefix) {
+ case '@':
+ return pc_setregstr(sd, num, str);
+ case '$':
+ return mapreg_setregstr(num, str);
+ case '#':
+ return (name[1] == '#') ?
+ pc_setaccountreg2str(sd, name, str) :
+ pc_setaccountregstr(sd, name, str);
+ case '.':
+ {
+ struct DBMap* n;
+ n = (ref) ? *ref : (name[1] == '@') ? st->stack->var_function : st->script->script_vars;
+ if( n ) {
+ idb_remove(n, num);
+ if (str[0]) idb_put(n, num, aStrdup(str));
+ }
+ }
+ return 1;
+ case '\'':
+ if( st->instance_id ) {
+ idb_remove(instance[st->instance_id].vars, num);
+ if( str[0] ) idb_put(instance[st->instance_id].vars, num, aStrdup(str));
+ }
+ return 1;
+ default:
+ return pc_setglobalreg_str(sd, name, str);
+ }
+ }
+ else
+ {// integer variable
+ int val = (int)__64BPRTSIZE(value);
+ if(str_data[num&0x00ffffff].type == C_PARAM)
+ {
+ if( pc_setparam(sd, str_data[num&0x00ffffff].val, val) == 0 )
+ {
+ if( st != NULL )
+ {
+ ShowError("script:set_reg: failed to set param '%s' to %d.\n", name, val);
+ script_reportsrc(st);
+ st->state = END;
+ }
+ return 0;
+ }
+ return 1;
+ }
+
+ switch (prefix) {
+ case '@':
+ return pc_setreg(sd, num, val);
+ case '$':
+ return mapreg_setreg(num, val);
+ case '#':
+ return (name[1] == '#') ?
+ pc_setaccountreg2(sd, name, val) :
+ pc_setaccountreg(sd, name, val);
+ case '.':
+ {
+ struct DBMap* n;
+ n = (ref) ? *ref : (name[1] == '@') ? st->stack->var_function : st->script->script_vars;
+ if( n ) {
+ idb_remove(n, num);
+ if( val != 0 )
+ idb_iput(n, num, val);
+ }
+ }
+ return 1;
+ case '\'':
+ if( st->instance_id ) {
+ idb_remove(instance[st->instance_id].vars, num);
+ if( val != 0 )
+ idb_iput(instance[st->instance_id].vars, num, val);
+ }
+ return 1;
+ default:
+ return pc_setglobalreg(sd, name, val);
+ }
+ }
+}
+
+int set_var(TBL_PC* sd, char* name, void* val)
{
return set_reg(NULL, sd, reference_uid(add_str(name),0), name, val, NULL);
}
void setd_sub(struct script_state *st, TBL_PC *sd, const char *varname, int elem, void *value, struct DBMap **ref)
{
- set_reg(st, sd, reference_uid(add_str(varname),elem), varname, value, ref);
+ set_reg(st, sd, reference_uid(add_str(varname),elem), varname, value, ref);
}
/// Converts the data to a string
-const char *conv_str(struct script_state *st, struct script_data *data)
-{
- char *p;
-
- get_val(st, data);
- if (data_isstring(data)) {
- // nothing to convert
- } else if (data_isint(data)) {
- // int -> string
- CREATE(p, char, ITEM_NAME_LENGTH);
- snprintf(p, ITEM_NAME_LENGTH, "%d", data->u.num);
- p[ITEM_NAME_LENGTH-1] = '\0';
- data->type = C_STR;
- data->u.str = p;
- } else if (data_isreference(data)) {
- // reference -> string
- //##TODO when does this happen (check get_val) [FlavioJS]
- data->type = C_CONSTSTR;
- data->u.str = reference_getname(data);
- } else {
- // unsupported data type
- ShowError("script:conv_str: cannot convert to string, defaulting to \"\"\n");
- script_reportdata(data);
- script_reportsrc(st);
- data->type = C_CONSTSTR;
- data->u.str = "";
- }
- return data->u.str;
+const char* conv_str(struct script_state* st, struct script_data* data)
+{
+ char* p;
+
+ get_val(st, data);
+ if( data_isstring(data) )
+ {// nothing to convert
+ }
+ else if( data_isint(data) )
+ {// int -> string
+ CREATE(p, char, ITEM_NAME_LENGTH);
+ snprintf(p, ITEM_NAME_LENGTH, "%d", data->u.num);
+ p[ITEM_NAME_LENGTH-1] = '\0';
+ data->type = C_STR;
+ data->u.str = p;
+ }
+ else if( data_isreference(data) )
+ {// reference -> string
+ //##TODO when does this happen (check get_val) [FlavioJS]
+ data->type = C_CONSTSTR;
+ data->u.str = reference_getname(data);
+ }
+ else
+ {// unsupported data type
+ ShowError("script:conv_str: cannot convert to string, defaulting to \"\"\n");
+ script_reportdata(data);
+ script_reportsrc(st);
+ data->type = C_CONSTSTR;
+ data->u.str = "";
+ }
+ return data->u.str;
}
/// Converts the data to an int
-int conv_num(struct script_state *st, struct script_data *data)
-{
- char *p;
- long num;
-
- get_val(st, data);
- if (data_isint(data)) {
- // nothing to convert
- } else if (data_isstring(data)) {
- // string -> int
- // the result does not overflow or underflow, it is capped instead
- // ex: 999999999999 is capped to INT_MAX (2147483647)
- p = data->u.str;
- errno = 0;
- num = strtol(data->u.str, NULL, 10);// change radix to 0 to support octal numbers "o377" and hex numbers "0xFF"
- if (errno == ERANGE
+int conv_num(struct script_state* st, struct script_data* data)
+{
+ char* p;
+ long num;
+
+ get_val(st, data);
+ if( data_isint(data) )
+ {// nothing to convert
+ }
+ else if( data_isstring(data) )
+ {// string -> int
+ // the result does not overflow or underflow, it is capped instead
+ // ex: 999999999999 is capped to INT_MAX (2147483647)
+ p = data->u.str;
+ errno = 0;
+ num = strtol(data->u.str, NULL, 10);// change radix to 0 to support octal numbers "o377" and hex numbers "0xFF"
+ if( errno == ERANGE
#if LONG_MAX > INT_MAX
- || num < INT_MIN || num > INT_MAX
+ || num < INT_MIN || num > INT_MAX
#endif
- ) {
- if (num <= INT_MIN) {
- num = INT_MIN;
- ShowError("script:conv_num: underflow detected, capping to %ld\n", num);
- } else { //if( num >= INT_MAX )
- num = INT_MAX;
- ShowError("script:conv_num: overflow detected, capping to %ld\n", num);
- }
- script_reportdata(data);
- script_reportsrc(st);
- }
- if (data->type == C_STR)
- aFree(p);
- data->type = C_INT;
- data->u.num = (int)num;
- }
+ )
+ {
+ if( num <= INT_MIN )
+ {
+ num = INT_MIN;
+ ShowError("script:conv_num: underflow detected, capping to %ld\n", num);
+ }
+ else//if( num >= INT_MAX )
+ {
+ num = INT_MAX;
+ ShowError("script:conv_num: overflow detected, capping to %ld\n", num);
+ }
+ script_reportdata(data);
+ script_reportsrc(st);
+ }
+ if( data->type == C_STR )
+ aFree(p);
+ data->type = C_INT;
+ data->u.num = (int)num;
+ }
#if 0
- // FIXME this function is being used to retrieve the position of labels and
- // probably other stuff [FlavioJS]
- else {
- // unsupported data type
- ShowError("script:conv_num: cannot convert to number, defaulting to 0\n");
- script_reportdata(data);
- script_reportsrc(st);
- data->type = C_INT;
- data->u.num = 0;
- }
+ // FIXME this function is being used to retrieve the position of labels and
+ // probably other stuff [FlavioJS]
+ else
+ {// unsupported data type
+ ShowError("script:conv_num: cannot convert to number, defaulting to 0\n");
+ script_reportdata(data);
+ script_reportsrc(st);
+ data->type = C_INT;
+ data->u.num = 0;
+ }
#endif
- return data->u.num;
+ return data->u.num;
}
//
@@ -2791,118 +2848,126 @@ int conv_num(struct script_state *st, struct script_data *data)
//
/// Increases the size of the stack
-void stack_expand(struct script_stack *stack)
+void stack_expand(struct script_stack* stack)
{
- stack->sp_max += 64;
- stack->stack_data = (struct script_data *)aRealloc(stack->stack_data,
- stack->sp_max * sizeof(stack->stack_data[0]));
- memset(stack->stack_data + (stack->sp_max - 64), 0,
- 64 * sizeof(stack->stack_data[0]));
+ stack->sp_max += 64;
+ stack->stack_data = (struct script_data*)aRealloc(stack->stack_data,
+ stack->sp_max * sizeof(stack->stack_data[0]) );
+ memset(stack->stack_data + (stack->sp_max - 64), 0,
+ 64 * sizeof(stack->stack_data[0]) );
}
/// Pushes a value into the stack
#define push_val(stack,type,val) push_val2(stack, type, val, NULL)
/// Pushes a value into the stack (with reference)
-struct script_data *push_val2(struct script_stack *stack, enum c_op type, int val, struct DBMap **ref) {
- if (stack->sp >= stack->sp_max)
- stack_expand(stack);
- stack->stack_data[stack->sp].type = type;
- stack->stack_data[stack->sp].u.num = val;
- stack->stack_data[stack->sp].ref = ref;
- stack->sp++;
- return &stack->stack_data[stack->sp-1];
+struct script_data* push_val2(struct script_stack* stack, enum c_op type, int val, struct DBMap** ref)
+{
+ if( stack->sp >= stack->sp_max )
+ stack_expand(stack);
+ stack->stack_data[stack->sp].type = type;
+ stack->stack_data[stack->sp].u.num = val;
+ stack->stack_data[stack->sp].ref = ref;
+ stack->sp++;
+ return &stack->stack_data[stack->sp-1];
}
/// Pushes a string into the stack
-struct script_data *push_str(struct script_stack *stack, enum c_op type, char *str) {
- if (stack->sp >= stack->sp_max)
- stack_expand(stack);
- stack->stack_data[stack->sp].type = type;
- stack->stack_data[stack->sp].u.str = str;
- stack->stack_data[stack->sp].ref = NULL;
- stack->sp++;
- return &stack->stack_data[stack->sp-1];
+struct script_data* push_str(struct script_stack* stack, enum c_op type, char* str)
+{
+ if( stack->sp >= stack->sp_max )
+ stack_expand(stack);
+ stack->stack_data[stack->sp].type = type;
+ stack->stack_data[stack->sp].u.str = str;
+ stack->stack_data[stack->sp].ref = NULL;
+ stack->sp++;
+ return &stack->stack_data[stack->sp-1];
}
/// Pushes a retinfo into the stack
-struct script_data *push_retinfo(struct script_stack *stack, struct script_retinfo *ri, DBMap **ref) {
- if (stack->sp >= stack->sp_max)
- stack_expand(stack);
- stack->stack_data[stack->sp].type = C_RETINFO;
- stack->stack_data[stack->sp].u.ri = ri;
- stack->stack_data[stack->sp].ref = ref;
- stack->sp++;
- return &stack->stack_data[stack->sp-1];
+struct script_data* push_retinfo(struct script_stack* stack, struct script_retinfo* ri, DBMap **ref)
+{
+ if( stack->sp >= stack->sp_max )
+ stack_expand(stack);
+ stack->stack_data[stack->sp].type = C_RETINFO;
+ stack->stack_data[stack->sp].u.ri = ri;
+ stack->stack_data[stack->sp].ref = ref;
+ stack->sp++;
+ return &stack->stack_data[stack->sp-1];
}
/// Pushes a copy of the target position into the stack
-struct script_data *push_copy(struct script_stack *stack, int pos) {
- switch (stack->stack_data[pos].type) {
- case C_CONSTSTR:
- return push_str(stack, C_CONSTSTR, stack->stack_data[pos].u.str);
- break;
- case C_STR:
- return push_str(stack, C_STR, aStrdup(stack->stack_data[pos].u.str));
- break;
- case C_RETINFO:
- ShowFatalError("script:push_copy: can't create copies of C_RETINFO. Exiting...\n");
- exit(1);
- break;
- default:
- return push_val2(
- stack,stack->stack_data[pos].type,
- stack->stack_data[pos].u.num,
- stack->stack_data[pos].ref
- );
- break;
- }
+struct script_data* push_copy(struct script_stack* stack, int pos)
+{
+ switch( stack->stack_data[pos].type )
+ {
+ case C_CONSTSTR:
+ return push_str(stack, C_CONSTSTR, stack->stack_data[pos].u.str);
+ break;
+ case C_STR:
+ return push_str(stack, C_STR, aStrdup(stack->stack_data[pos].u.str));
+ break;
+ case C_RETINFO:
+ ShowFatalError("script:push_copy: can't create copies of C_RETINFO. Exiting...\n");
+ exit(1);
+ break;
+ default:
+ return push_val2(
+ stack,stack->stack_data[pos].type,
+ stack->stack_data[pos].u.num,
+ stack->stack_data[pos].ref
+ );
+ break;
+ }
}
/// Removes the values in indexes [start,end[ from the stack.
/// Adjusts all stack pointers.
-void pop_stack(struct script_state *st, int start, int end)
-{
- struct script_stack *stack = st->stack;
- struct script_data *data;
- int i;
-
- if (start < 0)
- start = 0;
- if (end > stack->sp)
- end = stack->sp;
- if (start >= end)
- return;// nothing to pop
-
- // free stack elements
- for (i = start; i < end; i++) {
- data = &stack->stack_data[i];
- if (data->type == C_STR)
- aFree(data->u.str);
- if (data->type == C_RETINFO) {
- struct script_retinfo *ri = data->u.ri;
- if (ri->var_function)
- script_free_vars(ri->var_function);
- if (data->ref)
- aFree(data->ref);
- aFree(ri);
- }
- data->type = C_NOP;
- }
- // move the rest of the elements
- if (stack->sp > end) {
- memmove(&stack->stack_data[start], &stack->stack_data[end], sizeof(stack->stack_data[0])*(stack->sp - end));
- for (i = start + stack->sp - end; i < stack->sp; ++i)
- stack->stack_data[i].type = C_NOP;
- }
- // adjust stack pointers
- if (st->start > end) st->start -= end - start;
- else if (st->start > start) st->start = start;
- if (st->end > end) st->end -= end - start;
- else if (st->end > start) st->end = start;
- if (stack->defsp > end) stack->defsp -= end - start;
- else if (stack->defsp > start) stack->defsp = start;
- stack->sp -= end - start;
+void pop_stack(struct script_state* st, int start, int end)
+{
+ struct script_stack* stack = st->stack;
+ struct script_data* data;
+ int i;
+
+ if( start < 0 )
+ start = 0;
+ if( end > stack->sp )
+ end = stack->sp;
+ if( start >= end )
+ return;// nothing to pop
+
+ // free stack elements
+ for( i = start; i < end; i++ )
+ {
+ data = &stack->stack_data[i];
+ if( data->type == C_STR )
+ aFree(data->u.str);
+ if( data->type == C_RETINFO )
+ {
+ struct script_retinfo* ri = data->u.ri;
+ if( ri->var_function )
+ script_free_vars(ri->var_function);
+ if( data->ref )
+ aFree(data->ref);
+ aFree(ri);
+ }
+ data->type = C_NOP;
+ }
+ // move the rest of the elements
+ if( stack->sp > end )
+ {
+ memmove(&stack->stack_data[start], &stack->stack_data[end], sizeof(stack->stack_data[0])*(stack->sp - end));
+ for( i = start + stack->sp - end; i < stack->sp; ++i )
+ stack->stack_data[i].type = C_NOP;
+ }
+ // adjust stack pointers
+ if( st->start > end ) st->start -= end - start;
+ else if( st->start > start ) st->start = start;
+ if( st->end > end ) st->end -= end - start;
+ else if( st->end > start ) st->end = start;
+ if( stack->defsp > end ) stack->defsp -= end - start;
+ else if( stack->defsp > start ) stack->defsp = start;
+ stack->sp -= end - start;
}
///
@@ -2912,19 +2977,19 @@ void pop_stack(struct script_state *st, int start, int end)
/*==========================================
* Release script dependent variable, dependent variable of function
*------------------------------------------*/
-void script_free_vars(struct DBMap *storage)
+void script_free_vars(struct DBMap* storage)
{
- if (storage) {
- // destroy the storage construct containing the variables
- db_destroy(storage);
- }
+ if( storage )
+ {// destroy the storage construct containing the variables
+ db_destroy(storage);
+ }
}
-void script_free_code(struct script_code *code)
+void script_free_code(struct script_code* code)
{
- script_free_vars(code->script_vars);
- aFree(code->script_buf);
- aFree(code);
+ script_free_vars( code->script_vars );
+ aFree( code->script_buf );
+ aFree( code );
}
/// Creates a new script state.
@@ -2934,43 +2999,44 @@ void script_free_code(struct script_code *code)
/// @param rid Who is running the script (attached player)
/// @param oid Where the code is being run (npc 'object')
/// @return Script state
-struct script_state *script_alloc_state(struct script_code *script, int pos, int rid, int oid) {
- struct script_state *st;
- CREATE(st, struct script_state, 1);
- st->stack = (struct script_stack *)aMalloc(sizeof(struct script_stack));
- st->stack->sp = 0;
- st->stack->sp_max = 64;
- CREATE(st->stack->stack_data, struct script_data, st->stack->sp_max);
- st->stack->defsp = st->stack->sp;
- st->stack->var_function = idb_alloc(DB_OPT_RELEASE_DATA);
- st->state = RUN;
- st->script = script;
- //st->scriptroot = script;
- st->pos = pos;
- st->rid = rid;
- st->oid = oid;
- st->sleep.timer = INVALID_TIMER;
- return st;
+struct script_state* script_alloc_state(struct script_code* script, int pos, int rid, int oid)
+{
+ struct script_state* st;
+ CREATE(st, struct script_state, 1);
+ st->stack = (struct script_stack*)aMalloc(sizeof(struct script_stack));
+ st->stack->sp = 0;
+ st->stack->sp_max = 64;
+ CREATE(st->stack->stack_data, struct script_data, st->stack->sp_max);
+ st->stack->defsp = st->stack->sp;
+ st->stack->var_function = idb_alloc(DB_OPT_RELEASE_DATA);
+ st->state = RUN;
+ st->script = script;
+ //st->scriptroot = script;
+ st->pos = pos;
+ st->rid = rid;
+ st->oid = oid;
+ st->sleep.timer = INVALID_TIMER;
+ return st;
}
/// Frees a script state.
///
/// @param st Script state
-void script_free_state(struct script_state *st)
-{
- if (st->bk_st) {
- // backup was not restored
- ShowDebug("script_free_state: Previous script state lost (rid=%d, oid=%d, state=%d, bk_npcid=%d).\n", st->bk_st->rid, st->bk_st->oid, st->bk_st->state, st->bk_npcid);
- }
- if (st->sleep.timer != INVALID_TIMER)
- delete_timer(st->sleep.timer, run_script_timer);
- script_free_vars(st->stack->var_function);
- pop_stack(st, 0, st->stack->sp);
- aFree(st->stack->stack_data);
- aFree(st->stack);
- st->stack = NULL;
- st->pos = -1;
- aFree(st);
+void script_free_state(struct script_state* st)
+{
+ if(st->bk_st)
+ {// backup was not restored
+ ShowDebug("script_free_state: Previous script state lost (rid=%d, oid=%d, state=%d, bk_npcid=%d).\n", st->bk_st->rid, st->bk_st->oid, st->bk_st->state, st->bk_npcid);
+ }
+ if( st->sleep.timer != INVALID_TIMER )
+ delete_timer(st->sleep.timer, run_script_timer);
+ script_free_vars(st->stack->var_function);
+ pop_stack(st, 0, st->stack->sp);
+ aFree(st->stack->stack_data);
+ aFree(st->stack);
+ st->stack = NULL;
+ st->pos = -1;
+ aFree(st);
}
//
@@ -2981,16 +3047,16 @@ void script_free_state(struct script_state *st)
*------------------------------------------*/
c_op get_com(unsigned char *script,int *pos)
{
- int i = 0, j = 0;
+ int i = 0, j = 0;
- if (script[*pos]>=0x80) {
- return C_INT;
- }
- while (script[*pos]>=0x40) {
- i=script[(*pos)++]<<j;
- j+=6;
- }
- return (c_op)(i+(script[(*pos)++]<<j));
+ if(script[*pos]>=0x80){
+ return C_INT;
+ }
+ while(script[*pos]>=0x40){
+ i=script[(*pos)++]<<j;
+ j+=6;
+ }
+ return (c_op)(i+(script[(*pos)++]<<j));
}
/*==========================================
@@ -2998,57 +3064,57 @@ c_op get_com(unsigned char *script,int *pos)
*------------------------------------------*/
int get_num(unsigned char *script,int *pos)
{
- int i,j;
- i=0;
- j=0;
- while (script[*pos]>=0xc0) {
- i+=(script[(*pos)++]&0x7f)<<j;
- j+=6;
- }
- return i+((script[(*pos)++]&0x7f)<<j);
+ int i,j;
+ i=0; j=0;
+ while(script[*pos]>=0xc0){
+ i+=(script[(*pos)++]&0x7f)<<j;
+ j+=6;
+ }
+ return i+((script[(*pos)++]&0x7f)<<j);
}
/*==========================================
* Remove the value from the stack
*------------------------------------------*/
-int pop_val(struct script_state *st)
+int pop_val(struct script_state* st)
{
- if (st->stack->sp<=0)
- return 0;
- st->stack->sp--;
- get_val(st,&(st->stack->stack_data[st->stack->sp]));
- if (st->stack->stack_data[st->stack->sp].type==C_INT)
- return st->stack->stack_data[st->stack->sp].u.num;
- return 0;
+ if(st->stack->sp<=0)
+ return 0;
+ st->stack->sp--;
+ get_val(st,&(st->stack->stack_data[st->stack->sp]));
+ if(st->stack->stack_data[st->stack->sp].type==C_INT)
+ return st->stack->stack_data[st->stack->sp].u.num;
+ return 0;
}
/// Ternary operators
/// test ? if_true : if_false
-void op_3(struct script_state *st, int op)
-{
- struct script_data *data;
- int flag = 0;
-
- data = script_getdatatop(st, -3);
- get_val(st, data);
-
- if (data_isstring(data))
- flag = data->u.str[0];// "" -> false
- else if (data_isint(data))
- flag = data->u.num;// 0 -> false
- else {
- ShowError("script:op_3: invalid data for the ternary operator test\n");
- script_reportdata(data);
- script_reportsrc(st);
- script_removetop(st, -3, 0);
- script_pushnil(st);
- return;
- }
- if (flag)
- script_pushcopytop(st, -2);
- else
- script_pushcopytop(st, -1);
- script_removetop(st, -4, -1);
+void op_3(struct script_state* st, int op)
+{
+ struct script_data* data;
+ int flag = 0;
+
+ data = script_getdatatop(st, -3);
+ get_val(st, data);
+
+ if( data_isstring(data) )
+ flag = data->u.str[0];// "" -> false
+ else if( data_isint(data) )
+ flag = data->u.num;// 0 -> false
+ else
+ {
+ ShowError("script:op_3: invalid data for the ternary operator test\n");
+ script_reportdata(data);
+ script_reportsrc(st);
+ script_removetop(st, -3, 0);
+ script_pushnil(st);
+ return;
+ }
+ if( flag )
+ script_pushcopytop(st, -2);
+ else
+ script_pushcopytop(st, -1);
+ script_removetop(st, -4, -1);
}
/// Binary string operators
@@ -3059,249 +3125,209 @@ void op_3(struct script_state *st, int op)
/// s1 LT s2 -> i
/// s1 LE s2 -> i
/// s1 ADD s2 -> s
-void op_2str(struct script_state *st, int op, const char *s1, const char *s2)
-{
- int a = 0;
-
- switch (op) {
- case C_EQ:
- a = (strcmp(s1,s2) == 0);
- break;
- case C_NE:
- a = (strcmp(s1,s2) != 0);
- break;
- case C_GT:
- a = (strcmp(s1,s2) > 0);
- break;
- case C_GE:
- a = (strcmp(s1,s2) >= 0);
- break;
- case C_LT:
- a = (strcmp(s1,s2) < 0);
- break;
- case C_LE:
- a = (strcmp(s1,s2) <= 0);
- break;
- case C_ADD: {
- char *buf = (char *)aMalloc((strlen(s1)+strlen(s2)+1)*sizeof(char));
- strcpy(buf, s1);
- strcat(buf, s2);
- script_pushstr(st, buf);
- return;
- }
- default:
- ShowError("script:op2_str: unexpected string operator %s\n", script_op2name(op));
- script_reportsrc(st);
- script_pushnil(st);
- st->state = END;
- return;
- }
-
- script_pushint(st,a);
+void op_2str(struct script_state* st, int op, const char* s1, const char* s2)
+{
+ int a = 0;
+
+ switch(op){
+ case C_EQ: a = (strcmp(s1,s2) == 0); break;
+ case C_NE: a = (strcmp(s1,s2) != 0); break;
+ case C_GT: a = (strcmp(s1,s2) > 0); break;
+ case C_GE: a = (strcmp(s1,s2) >= 0); break;
+ case C_LT: a = (strcmp(s1,s2) < 0); break;
+ case C_LE: a = (strcmp(s1,s2) <= 0); break;
+ case C_ADD:
+ {
+ char* buf = (char *)aMalloc((strlen(s1)+strlen(s2)+1)*sizeof(char));
+ strcpy(buf, s1);
+ strcat(buf, s2);
+ script_pushstr(st, buf);
+ return;
+ }
+ default:
+ ShowError("script:op2_str: unexpected string operator %s\n", script_op2name(op));
+ script_reportsrc(st);
+ script_pushnil(st);
+ st->state = END;
+ return;
+ }
+
+ script_pushint(st,a);
}
/// Binary number operators
/// i OP i -> i
-void op_2num(struct script_state *st, int op, int i1, int i2)
-{
- int ret;
- double ret_double;
-
- switch (op) {
- case C_AND:
- ret = i1 & i2;
- break;
- case C_OR:
- ret = i1 | i2;
- break;
- case C_XOR:
- ret = i1 ^ i2;
- break;
- case C_LAND:
- ret = (i1 && i2);
- break;
- case C_LOR:
- ret = (i1 || i2);
- break;
- case C_EQ:
- ret = (i1 == i2);
- break;
- case C_NE:
- ret = (i1 != i2);
- break;
- case C_GT:
- ret = (i1 > i2);
- break;
- case C_GE:
- ret = (i1 >= i2);
- break;
- case C_LT:
- ret = (i1 < i2);
- break;
- case C_LE:
- ret = (i1 <= i2);
- break;
- case C_R_SHIFT:
- ret = i1>>i2;
- break;
- case C_L_SHIFT:
- ret = i1<<i2;
- break;
- case C_DIV:
- case C_MOD:
- if (i2 == 0) {
- ShowError("script:op_2num: division by zero detected op=%s i1=%d i2=%d\n", script_op2name(op), i1, i2);
- script_reportsrc(st);
- script_pushnil(st);
- st->state = END;
- return;
- } else if (op == C_DIV)
- ret = i1 / i2;
- else//if( op == C_MOD )
- ret = i1 % i2;
- break;
- default:
- switch (op) {
- // operators that can overflow/underflow
- case C_ADD:
- ret = i1 + i2;
- ret_double = (double)i1 + (double)i2;
- break;
- case C_SUB:
- ret = i1 - i2;
- ret_double = (double)i1 - (double)i2;
- break;
- case C_MUL:
- ret = i1 * i2;
- ret_double = (double)i1 * (double)i2;
- break;
- default:
- ShowError("script:op_2num: unexpected number operator %s i1=%d i2=%d\n", script_op2name(op), i1, i2);
- script_reportsrc(st);
- script_pushnil(st);
- return;
- }
- if (ret_double < (double)INT_MIN) {
- ShowWarning("script:op_2num: underflow detected op=%s i1=%d i2=%d\n", script_op2name(op), i1, i2);
- script_reportsrc(st);
- ret = INT_MIN;
- } else if (ret_double > (double)INT_MAX) {
- ShowWarning("script:op_2num: overflow detected op=%s i1=%d i2=%d\n", script_op2name(op), i1, i2);
- script_reportsrc(st);
- ret = INT_MAX;
- }
- }
- script_pushint(st, ret);
+void op_2num(struct script_state* st, int op, int i1, int i2)
+{
+ int ret;
+ double ret_double;
+
+ switch( op )
+ {
+ case C_AND: ret = i1 & i2; break;
+ case C_OR: ret = i1 | i2; break;
+ case C_XOR: ret = i1 ^ i2; break;
+ case C_LAND: ret = (i1 && i2); break;
+ case C_LOR: ret = (i1 || i2); break;
+ case C_EQ: ret = (i1 == i2); break;
+ case C_NE: ret = (i1 != i2); break;
+ case C_GT: ret = (i1 > i2); break;
+ case C_GE: ret = (i1 >= i2); break;
+ case C_LT: ret = (i1 < i2); break;
+ case C_LE: ret = (i1 <= i2); break;
+ case C_R_SHIFT: ret = i1>>i2; break;
+ case C_L_SHIFT: ret = i1<<i2; break;
+ case C_DIV:
+ case C_MOD:
+ if( i2 == 0 )
+ {
+ ShowError("script:op_2num: division by zero detected op=%s i1=%d i2=%d\n", script_op2name(op), i1, i2);
+ script_reportsrc(st);
+ script_pushnil(st);
+ st->state = END;
+ return;
+ }
+ else if( op == C_DIV )
+ ret = i1 / i2;
+ else//if( op == C_MOD )
+ ret = i1 % i2;
+ break;
+ default:
+ switch( op )
+ {// operators that can overflow/underflow
+ case C_ADD: ret = i1 + i2; ret_double = (double)i1 + (double)i2; break;
+ case C_SUB: ret = i1 - i2; ret_double = (double)i1 - (double)i2; break;
+ case C_MUL: ret = i1 * i2; ret_double = (double)i1 * (double)i2; break;
+ default:
+ ShowError("script:op_2num: unexpected number operator %s i1=%d i2=%d\n", script_op2name(op), i1, i2);
+ script_reportsrc(st);
+ script_pushnil(st);
+ return;
+ }
+ if( ret_double < (double)INT_MIN )
+ {
+ ShowWarning("script:op_2num: underflow detected op=%s i1=%d i2=%d\n", script_op2name(op), i1, i2);
+ script_reportsrc(st);
+ ret = INT_MIN;
+ }
+ else if( ret_double > (double)INT_MAX )
+ {
+ ShowWarning("script:op_2num: overflow detected op=%s i1=%d i2=%d\n", script_op2name(op), i1, i2);
+ script_reportsrc(st);
+ ret = INT_MAX;
+ }
+ }
+ script_pushint(st, ret);
}
/// Binary operators
void op_2(struct script_state *st, int op)
{
- struct script_data *left, leftref;
- struct script_data *right;
-
- leftref.type = C_NOP;
-
- left = script_getdatatop(st, -2);
- right = script_getdatatop(st, -1);
-
- if (st->op2ref) {
- if (data_isreference(left)) {
- leftref = *left;
- }
-
- st->op2ref = 0;
- }
-
- get_val(st, left);
- get_val(st, right);
-
- // automatic conversions
- switch (op) {
- case C_ADD:
- if (data_isint(left) && data_isstring(right)) {
- // convert int-string to string-string
- conv_str(st, left);
- } else if (data_isstring(left) && data_isint(right)) {
- // convert string-int to string-string
- conv_str(st, right);
- }
- break;
- }
-
- if (data_isstring(left) && data_isstring(right)) {
- // ss => op_2str
- op_2str(st, op, left->u.str, right->u.str);
- script_removetop(st, leftref.type == C_NOP ? -3 : -2, -1);// pop the two values before the top one
-
- if (leftref.type != C_NOP) {
- aFree(left->u.str);
- *left = leftref;
- }
- } else if (data_isint(left) && data_isint(right)) {
- // ii => op_2num
- int i1 = left->u.num;
- int i2 = right->u.num;
-
- script_removetop(st, leftref.type == C_NOP ? -2 : -1, 0);
- op_2num(st, op, i1, i2);
-
- if (leftref.type != C_NOP)
- *left = leftref;
- } else {
- // invalid argument
- ShowError("script:op_2: invalid data for operator %s\n", script_op2name(op));
- script_reportdata(left);
- script_reportdata(right);
- script_reportsrc(st);
- script_removetop(st, -2, 0);
- script_pushnil(st);
- st->state = END;
- }
+ struct script_data* left, leftref;
+ struct script_data* right;
+
+ leftref.type = C_NOP;
+
+ left = script_getdatatop(st, -2);
+ right = script_getdatatop(st, -1);
+
+ if (st->op2ref) {
+ if (data_isreference(left)) {
+ leftref = *left;
+ }
+
+ st->op2ref = 0;
+ }
+
+ get_val(st, left);
+ get_val(st, right);
+
+ // automatic conversions
+ switch( op )
+ {
+ case C_ADD:
+ if( data_isint(left) && data_isstring(right) )
+ {// convert int-string to string-string
+ conv_str(st, left);
+ }
+ else if( data_isstring(left) && data_isint(right) )
+ {// convert string-int to string-string
+ conv_str(st, right);
+ }
+ break;
+ }
+
+ if( data_isstring(left) && data_isstring(right) )
+ {// ss => op_2str
+ op_2str(st, op, left->u.str, right->u.str);
+ script_removetop(st, leftref.type == C_NOP ? -3 : -2, -1);// pop the two values before the top one
+
+ if (leftref.type != C_NOP)
+ {
+ aFree(left->u.str);
+ *left = leftref;
+ }
+ }
+ else if( data_isint(left) && data_isint(right) )
+ {// ii => op_2num
+ int i1 = left->u.num;
+ int i2 = right->u.num;
+
+ script_removetop(st, leftref.type == C_NOP ? -2 : -1, 0);
+ op_2num(st, op, i1, i2);
+
+ if (leftref.type != C_NOP)
+ *left = leftref;
+ }
+ else
+ {// invalid argument
+ ShowError("script:op_2: invalid data for operator %s\n", script_op2name(op));
+ script_reportdata(left);
+ script_reportdata(right);
+ script_reportsrc(st);
+ script_removetop(st, -2, 0);
+ script_pushnil(st);
+ st->state = END;
+ }
}
/// Unary operators
/// NEG i -> i
/// NOT i -> i
/// LNOT i -> i
-void op_1(struct script_state *st, int op)
-{
- struct script_data *data;
- int i1;
-
- data = script_getdatatop(st, -1);
- get_val(st, data);
-
- if (!data_isint(data)) {
- // not a number
- ShowError("script:op_1: argument is not a number (op=%s)\n", script_op2name(op));
- script_reportdata(data);
- script_reportsrc(st);
- script_pushnil(st);
- st->state = END;
- return;
- }
-
- i1 = data->u.num;
- script_removetop(st, -1, 0);
- switch (op) {
- case C_NEG:
- i1 = -i1;
- break;
- case C_NOT:
- i1 = ~i1;
- break;
- case C_LNOT:
- i1 = !i1;
- break;
- default:
- ShowError("script:op_1: unexpected operator %s i1=%d\n", script_op2name(op), i1);
- script_reportsrc(st);
- script_pushnil(st);
- st->state = END;
- return;
- }
- script_pushint(st, i1);
+void op_1(struct script_state* st, int op)
+{
+ struct script_data* data;
+ int i1;
+
+ data = script_getdatatop(st, -1);
+ get_val(st, data);
+
+ if( !data_isint(data) )
+ {// not a number
+ ShowError("script:op_1: argument is not a number (op=%s)\n", script_op2name(op));
+ script_reportdata(data);
+ script_reportsrc(st);
+ script_pushnil(st);
+ st->state = END;
+ return;
+ }
+
+ i1 = data->u.num;
+ script_removetop(st, -1, 0);
+ switch( op )
+ {
+ case C_NEG: i1 = -i1; break;
+ case C_NOT: i1 = ~i1; break;
+ case C_LNOT: i1 = !i1; break;
+ default:
+ ShowError("script:op_1: unexpected operator %s i1=%d\n", script_op2name(op), i1);
+ script_reportsrc(st);
+ script_pushnil(st);
+ st->state = END;
+ return;
+ }
+ script_pushint(st, i1);
}
@@ -3309,82 +3335,88 @@ void op_1(struct script_state *st, int op)
///
/// @param st Script state whose stack arguments should be inspected.
/// @param func Built-in function for which the arguments are intended.
-static void script_check_buildin_argtype(struct script_state *st, int func)
-{
- char type;
- int idx, invalid = 0;
- script_function *sf = &buildin_func[str_data[func].val];
-
- for (idx = 2; script_hasdata(st, idx); idx++) {
- struct script_data *data = script_getdata(st, idx);
-
- type = sf->arg[idx-2];
-
- if (type == '?' || type == '*') {
- // optional argument or unknown number of optional parameters ( no types are after this )
- break;
- } else if (type == 0) {
- // more arguments than necessary ( should not happen, as it is checked before )
- ShowWarning("Found more arguments than necessary. unexpected arg type %s\n",script_op2name(data->type));
- invalid++;
- break;
- } else {
- const char *name = NULL;
-
- if (data_isreference(data)) {
- // get name for variables to determine the type they refer to
- name = reference_getname(data);
- }
-
- switch (type) {
- case 'v':
- if (!data_isstring(data) && !data_isint(data) && !data_isreference(data)) {
- // variant
- ShowWarning("Unexpected type for argument %d. Expected string, number or variable.\n", idx-1);
- script_reportdata(data);
- invalid++;
- }
- break;
- case 's':
- if (!data_isstring(data) && !(data_isreference(data) && is_string_variable(name))) {
- // string
- ShowWarning("Unexpected type for argument %d. Expected string.\n", idx-1);
- script_reportdata(data);
- invalid++;
- }
- break;
- case 'i':
- if (!data_isint(data) && !(data_isreference(data) && (reference_toparam(data) || reference_toconstant(data) || !is_string_variable(name)))) {
- // int ( params and constants are always int )
- ShowWarning("Unexpected type for argument %d. Expected number.\n", idx-1);
- script_reportdata(data);
- invalid++;
- }
- break;
- case 'r':
- if (!data_isreference(data)) {
- // variables
- ShowWarning("Unexpected type for argument %d. Expected variable, got %s.\n", idx-1,script_op2name(data->type));
- script_reportdata(data);
- invalid++;
- }
- break;
- case 'l':
- if (!data_islabel(data) && !data_isfunclabel(data)) {
- // label
- ShowWarning("Unexpected type for argument %d. Expected label, got %s\n", idx-1,script_op2name(data->type));
- script_reportdata(data);
- invalid++;
- }
- break;
- }
- }
- }
-
- if (invalid) {
- ShowDebug("Function: %s\n", get_str(func));
- script_reportsrc(st);
- }
+static void script_check_buildin_argtype(struct script_state* st, int func)
+{
+ char type;
+ int idx, invalid = 0;
+ script_function* sf = &buildin_func[str_data[func].val];
+
+ for( idx = 2; script_hasdata(st, idx); idx++ )
+ {
+ struct script_data* data = script_getdata(st, idx);
+
+ type = sf->arg[idx-2];
+
+ if( type == '?' || type == '*' )
+ {// optional argument or unknown number of optional parameters ( no types are after this )
+ break;
+ }
+ else if( type == 0 )
+ {// more arguments than necessary ( should not happen, as it is checked before )
+ ShowWarning("Found more arguments than necessary. unexpected arg type %s\n",script_op2name(data->type));
+ invalid++;
+ break;
+ }
+ else
+ {
+ const char* name = NULL;
+
+ if( data_isreference(data) )
+ {// get name for variables to determine the type they refer to
+ name = reference_getname(data);
+ }
+
+ switch( type )
+ {
+ case 'v':
+ if( !data_isstring(data) && !data_isint(data) && !data_isreference(data) )
+ {// variant
+ ShowWarning("Unexpected type for argument %d. Expected string, number or variable.\n", idx-1);
+ script_reportdata(data);
+ invalid++;
+ }
+ break;
+ case 's':
+ if( !data_isstring(data) && !( data_isreference(data) && is_string_variable(name) ) )
+ {// string
+ ShowWarning("Unexpected type for argument %d. Expected string.\n", idx-1);
+ script_reportdata(data);
+ invalid++;
+ }
+ break;
+ case 'i':
+ if( !data_isint(data) && !( data_isreference(data) && ( reference_toparam(data) || reference_toconstant(data) || !is_string_variable(name) ) ) )
+ {// int ( params and constants are always int )
+ ShowWarning("Unexpected type for argument %d. Expected number.\n", idx-1);
+ script_reportdata(data);
+ invalid++;
+ }
+ break;
+ case 'r':
+ if( !data_isreference(data) )
+ {// variables
+ ShowWarning("Unexpected type for argument %d. Expected variable, got %s.\n", idx-1,script_op2name(data->type));
+ script_reportdata(data);
+ invalid++;
+ }
+ break;
+ case 'l':
+ if( !data_islabel(data) && !data_isfunclabel(data) )
+ {// label
+ ShowWarning("Unexpected type for argument %d. Expected label, got %s\n", idx-1,script_op2name(data->type));
+ script_reportdata(data);
+ invalid++;
+ }
+ break;
+ }
+ }
+ }
+
+ if(invalid)
+ {
+ ShowDebug("Function: %s\n", get_str(func));
+ script_reportsrc(st);
+ }
}
@@ -3392,81 +3424,85 @@ static void script_check_buildin_argtype(struct script_state *st, int func)
/// Stack: C_NAME(<command>) C_ARG <arg0> <arg1> ... <argN>
int run_func(struct script_state *st)
{
- struct script_data *data;
- int i,start_sp,end_sp,func;
-
- end_sp = st->stack->sp;// position after the last argument
- for (i = end_sp-1; i > 0 ; --i)
- if (st->stack->stack_data[i].type == C_ARG)
- break;
- if (i == 0) {
- ShowError("script:run_func: C_ARG not found. please report this!!!\n");
- st->state = END;
- script_reportsrc(st);
- return 1;
- }
- start_sp = i-1;// C_NAME of the command
- st->start = start_sp;
- st->end = end_sp;
-
- data = &st->stack->stack_data[st->start];
- if (data->type == C_NAME && str_data[data->u.num].type == C_FUNC)
- func = data->u.num;
- else {
- ShowError("script:run_func: not a buildin command.\n");
- script_reportdata(data);
- script_reportsrc(st);
- st->state = END;
- return 1;
- }
-
- if (script_config.warn_func_mismatch_argtypes) {
- script_check_buildin_argtype(st, func);
- }
-
- if (str_data[func].func) {
- if (str_data[func].func(st)) //Report error
- script_reportsrc(st);
- } else {
- ShowError("script:run_func: '%s' (id=%d type=%s) has no C function. please report this!!!\n", get_str(func), func, script_op2name(str_data[func].type));
- script_reportsrc(st);
- st->state = END;
- }
-
- // Stack's datum are used when re-running functions [Eoe]
- if (st->state == RERUNLINE)
- return 0;
-
- pop_stack(st, st->start, st->end);
- if (st->state == RETFUNC) {
- // return from a user-defined function
- struct script_retinfo *ri;
- int olddefsp = st->stack->defsp;
- int nargs;
-
- pop_stack(st, st->stack->defsp, st->start);// pop distractions from the stack
- if (st->stack->defsp < 1 || st->stack->stack_data[st->stack->defsp-1].type != C_RETINFO) {
- ShowWarning("script:run_func: return without callfunc or callsub!\n");
- script_reportsrc(st);
- st->state = END;
- return 1;
- }
- script_free_vars(st->stack->var_function);
-
- ri = st->stack->stack_data[st->stack->defsp-1].u.ri;
- nargs = ri->nargs;
- st->pos = ri->pos;
- st->script = ri->script;
- st->stack->var_function = ri->var_function;
- st->stack->defsp = ri->defsp;
- memset(ri, 0, sizeof(struct script_retinfo));
-
- pop_stack(st, olddefsp-nargs-1, olddefsp);// pop arguments and retinfo
-
- st->state = GOTO;
- }
-
- return 0;
+ struct script_data* data;
+ int i,start_sp,end_sp,func;
+
+ end_sp = st->stack->sp;// position after the last argument
+ for( i = end_sp-1; i > 0 ; --i )
+ if( st->stack->stack_data[i].type == C_ARG )
+ break;
+ if( i == 0 )
+ {
+ ShowError("script:run_func: C_ARG not found. please report this!!!\n");
+ st->state = END;
+ script_reportsrc(st);
+ return 1;
+ }
+ start_sp = i-1;// C_NAME of the command
+ st->start = start_sp;
+ st->end = end_sp;
+
+ data = &st->stack->stack_data[st->start];
+ if( data->type == C_NAME && str_data[data->u.num].type == C_FUNC )
+ func = data->u.num;
+ else
+ {
+ ShowError("script:run_func: not a buildin command.\n");
+ script_reportdata(data);
+ script_reportsrc(st);
+ st->state = END;
+ return 1;
+ }
+
+ if( script_config.warn_func_mismatch_argtypes )
+ {
+ script_check_buildin_argtype(st, func);
+ }
+
+ if(str_data[func].func){
+ if (str_data[func].func(st)) //Report error
+ script_reportsrc(st);
+ } else {
+ ShowError("script:run_func: '%s' (id=%d type=%s) has no C function. please report this!!!\n", get_str(func), func, script_op2name(str_data[func].type));
+ script_reportsrc(st);
+ st->state = END;
+ }
+
+ // Stack's datum are used when re-running functions [Eoe]
+ if( st->state == RERUNLINE )
+ return 0;
+
+ pop_stack(st, st->start, st->end);
+ if( st->state == RETFUNC )
+ {// return from a user-defined function
+ struct script_retinfo* ri;
+ int olddefsp = st->stack->defsp;
+ int nargs;
+
+ pop_stack(st, st->stack->defsp, st->start);// pop distractions from the stack
+ if( st->stack->defsp < 1 || st->stack->stack_data[st->stack->defsp-1].type != C_RETINFO )
+ {
+ ShowWarning("script:run_func: return without callfunc or callsub!\n");
+ script_reportsrc(st);
+ st->state = END;
+ return 1;
+ }
+ script_free_vars( st->stack->var_function );
+
+ ri = st->stack->stack_data[st->stack->defsp-1].u.ri;
+ nargs = ri->nargs;
+ st->pos = ri->pos;
+ st->script = ri->script;
+ st->stack->var_function = ri->var_function;
+ st->stack->defsp = ri->defsp;
+ memset(ri, 0, sizeof(struct script_retinfo));
+
+ pop_stack(st, olddefsp-nargs-1, olddefsp);// pop arguments and retinfo
+
+ st->state = GOTO;
+ }
+
+ return 0;
}
/*==========================================
@@ -3474,46 +3510,48 @@ int run_func(struct script_state *st)
*------------------------------------------*/
void run_script(struct script_code *rootscript,int pos,int rid,int oid)
{
- struct script_state *st;
+ struct script_state *st;
- if (rootscript == NULL || pos < 0)
- return;
+ if( rootscript == NULL || pos < 0 )
+ return;
- // TODO In jAthena, this function can take over the pending script in the player. [FlavioJS]
- // It is unclear how that can be triggered, so it needs the be traced/checked in more detail.
- // NOTE At the time of this change, this function wasn't capable of taking over the script state because st->scriptroot was never set.
- st = script_alloc_state(rootscript, pos, rid, oid);
- run_script_main(st);
+ // TODO In jAthena, this function can take over the pending script in the player. [FlavioJS]
+ // It is unclear how that can be triggered, so it needs the be traced/checked in more detail.
+ // NOTE At the time of this change, this function wasn't capable of taking over the script state because st->scriptroot was never set.
+ st = script_alloc_state(rootscript, pos, rid, oid);
+ run_script_main(st);
}
void script_stop_sleeptimers(int id)
{
- struct script_state *st;
- for (;;) {
- st = (struct script_state *)linkdb_erase(&sleep_db,(void *)__64BPRTSIZE(id));
- if (st == NULL)
- break; // no more sleep timers
- script_free_state(st);
- }
+ struct script_state* st;
+ for(;;)
+ {
+ st = (struct script_state*)linkdb_erase(&sleep_db,(void*)__64BPRTSIZE(id));
+ if( st == NULL )
+ break; // no more sleep timers
+ script_free_state(st);
+ }
}
/*==========================================
* Delete the specified node from sleep_db
*------------------------------------------*/
-struct linkdb_node *script_erase_sleepdb(struct linkdb_node *n) {
- struct linkdb_node *retnode;
-
- if (n == NULL)
- return NULL;
- if (n->prev == NULL)
- sleep_db = n->next;
- else
- n->prev->next = n->next;
- if (n->next)
- n->next->prev = n->prev;
- retnode = n->next;
- aFree(n);
- return retnode; // The following; return retnode
+struct linkdb_node* script_erase_sleepdb(struct linkdb_node *n)
+{
+ struct linkdb_node *retnode;
+
+ if( n == NULL)
+ return NULL;
+ if( n->prev == NULL )
+ sleep_db = n->next;
+ else
+ n->prev->next = n->next;
+ if( n->next )
+ n->next->prev = n->prev;
+ retnode = n->next;
+ aFree( n );
+ return retnode; // The following; return retnode
}
/*==========================================
@@ -3521,96 +3559,103 @@ struct linkdb_node *script_erase_sleepdb(struct linkdb_node *n) {
*------------------------------------------*/
int run_script_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- struct script_state *st = (struct script_state *)data;
- struct linkdb_node *node = (struct linkdb_node *)sleep_db;
- TBL_PC *sd = map_id2sd(st->rid);
-
- if ((sd && sd->status.char_id != id) || (st->rid && !sd)) {
- //Character mismatch. Cancel execution.
- st->rid = 0;
- st->state = END;
- }
- while (node && st->sleep.timer != INVALID_TIMER) {
- if ((int)__64BPRTSIZE(node->key) == st->oid && ((struct script_state *)node->data)->sleep.timer == st->sleep.timer) {
- script_erase_sleepdb(node);
- st->sleep.timer = INVALID_TIMER;
- break;
- }
- node = node->next;
- }
- if (st->state != RERUNLINE)
- st->sleep.tick = 0;
- run_script_main(st);
- return 0;
+ struct script_state *st = (struct script_state *)data;
+ struct linkdb_node *node = (struct linkdb_node *)sleep_db;
+ TBL_PC *sd = map_id2sd(st->rid);
+
+ if((sd && sd->status.char_id != id) || (st->rid && !sd))
+ { //Character mismatch. Cancel execution.
+ st->rid = 0;
+ st->state = END;
+ }
+ while( node && st->sleep.timer != INVALID_TIMER ) {
+ if( (int)__64BPRTSIZE(node->key) == st->oid && ((struct script_state *)node->data)->sleep.timer == st->sleep.timer ) {
+ script_erase_sleepdb(node);
+ st->sleep.timer = INVALID_TIMER;
+ break;
+ }
+ node = node->next;
+ }
+ if(st->state != RERUNLINE)
+ st->sleep.tick = 0;
+ run_script_main(st);
+ return 0;
}
/// Detaches script state from possibly attached character and restores it's previous script if any.
///
/// @param st Script state to detach.
/// @param dequeue_event Whether to schedule any queued events, when there was no previous script.
-static void script_detach_state(struct script_state *st, bool dequeue_event)
-{
- struct map_session_data *sd;
-
- if (st->rid && (sd = map_id2sd(st->rid))!=NULL) {
- sd->st = st->bk_st;
- sd->npc_id = st->bk_npcid;
- /**
- * For the Secure NPC Timeout option (check config/Secure.h) [RR]
- **/
-#if SECURE_NPCTIMEOUT
- /**
- * We're done with this NPC session, so we cancel the timer (if existent) and move on
- **/
- if (sd->npc_idle_timer != INVALID_TIMER) {
- delete_timer(sd->npc_idle_timer,npc_rr_secure_timeout_timer);
- sd->npc_idle_timer = INVALID_TIMER;
- }
-#endif
- if (st->bk_st) {
- //Remove tag for removal.
- st->bk_st = NULL;
- st->bk_npcid = 0;
- } else if (dequeue_event) {
- npc_event_dequeue(sd);
- }
- } else if (st->bk_st) {
- // rid was set to 0, before detaching the script state
- ShowError("script_detach_state: Found previous script state without attached player (rid=%d, oid=%d, state=%d, bk_npcid=%d)\n", st->bk_st->rid, st->bk_st->oid, st->bk_st->state, st->bk_npcid);
- script_reportsrc(st->bk_st);
-
- script_free_state(st->bk_st);
- st->bk_st = NULL;
- }
+static void script_detach_state(struct script_state* st, bool dequeue_event)
+{
+ struct map_session_data* sd;
+
+ if(st->rid && (sd = map_id2sd(st->rid))!=NULL)
+ {
+ sd->st = st->bk_st;
+ sd->npc_id = st->bk_npcid;
+ /**
+ * For the Secure NPC Timeout option (check config/Secure.h) [RR]
+ **/
+ #if SECURE_NPCTIMEOUT
+ /**
+ * We're done with this NPC session, so we cancel the timer (if existent) and move on
+ **/
+ if( sd->npc_idle_timer != INVALID_TIMER ) {
+ delete_timer(sd->npc_idle_timer,npc_rr_secure_timeout_timer);
+ sd->npc_idle_timer = INVALID_TIMER;
+ }
+ #endif
+ if(st->bk_st)
+ {
+ //Remove tag for removal.
+ st->bk_st = NULL;
+ st->bk_npcid = 0;
+ }
+ else if(dequeue_event)
+ {
+ npc_event_dequeue(sd);
+ }
+ }
+ else if(st->bk_st)
+ {// rid was set to 0, before detaching the script state
+ ShowError("script_detach_state: Found previous script state without attached player (rid=%d, oid=%d, state=%d, bk_npcid=%d)\n", st->bk_st->rid, st->bk_st->oid, st->bk_st->state, st->bk_npcid);
+ script_reportsrc(st->bk_st);
+
+ script_free_state(st->bk_st);
+ st->bk_st = NULL;
+ }
}
/// Attaches script state to possibly attached character and backups it's previous script, if any.
///
/// @param st Script state to attach.
-static void script_attach_state(struct script_state *st)
-{
- struct map_session_data *sd;
-
- if (st->rid && (sd = map_id2sd(st->rid))!=NULL) {
- if (st!=sd->st) {
- if (st->bk_st) {
- // there is already a backup
- ShowDebug("script_free_state: Previous script state lost (rid=%d, oid=%d, state=%d, bk_npcid=%d).\n", st->bk_st->rid, st->bk_st->oid, st->bk_st->state, st->bk_npcid);
- }
- st->bk_st = sd->st;
- st->bk_npcid = sd->npc_id;
- }
- sd->st = st;
- sd->npc_id = st->oid;
- /**
- * For the Secure NPC Timeout option (check config/Secure.h) [RR]
- **/
+static void script_attach_state(struct script_state* st)
+{
+ struct map_session_data* sd;
+
+ if(st->rid && (sd = map_id2sd(st->rid))!=NULL)
+ {
+ if(st!=sd->st)
+ {
+ if(st->bk_st)
+ {// there is already a backup
+ ShowDebug("script_free_state: Previous script state lost (rid=%d, oid=%d, state=%d, bk_npcid=%d).\n", st->bk_st->rid, st->bk_st->oid, st->bk_st->state, st->bk_npcid);
+ }
+ st->bk_st = sd->st;
+ st->bk_npcid = sd->npc_id;
+ }
+ sd->st = st;
+ sd->npc_id = st->oid;
+/**
+ * For the Secure NPC Timeout option (check config/Secure.h) [RR]
+ **/
#if SECURE_NPCTIMEOUT
- if (sd->npc_idle_timer == INVALID_TIMER)
- sd->npc_idle_timer = add_timer(gettick() + (SECURE_NPCTIMEOUT_INTERVAL*1000),npc_rr_secure_timeout_timer,sd->bl.id,0);
- sd->npc_idle_tick = gettick();
+ if( sd->npc_idle_timer == INVALID_TIMER )
+ sd->npc_idle_timer = add_timer(gettick() + (SECURE_NPCTIMEOUT_INTERVAL*1000),npc_rr_secure_timeout_timer,sd->bl.id,0);
+ sd->npc_idle_tick = gettick();
#endif
- }
+ }
}
/*==========================================
@@ -3618,194 +3663,204 @@ static void script_attach_state(struct script_state *st)
*------------------------------------------*/
void run_script_main(struct script_state *st)
{
- int cmdcount = script_config.check_cmdcount;
- int gotocount = script_config.check_gotocount;
- TBL_PC *sd;
- struct script_stack *stack=st->stack;
- struct npc_data *nd;
-
- script_attach_state(st);
-
- nd = map_id2nd(st->oid);
- if (nd && map[nd->bl.m].instance_id > 0)
- st->instance_id = map[nd->bl.m].instance_id;
-
- if (st->state == RERUNLINE) {
- run_func(st);
- if (st->state == GOTO)
- st->state = RUN;
- } else if (st->state != END)
- st->state = RUN;
-
- while (st->state == RUN) {
- enum c_op c = get_com(st->script->script_buf,&st->pos);
- switch (c) {
- case C_EOL:
- if (stack->defsp > stack->sp)
- ShowError("script:run_script_main: unexpected stack position (defsp=%d sp=%d). please report this!!!\n", stack->defsp, stack->sp);
- else
- pop_stack(st, stack->defsp, stack->sp);// pop unused stack data. (unused return value)
- break;
- case C_INT:
- push_val(stack,C_INT,get_num(st->script->script_buf,&st->pos));
- break;
- case C_POS:
- case C_NAME:
- push_val(stack,c,GETVALUE(st->script->script_buf,st->pos));
- st->pos+=3;
- break;
- case C_ARG:
- push_val(stack,c,0);
- break;
- case C_STR:
- push_str(stack,C_CONSTSTR,(char *)(st->script->script_buf+st->pos));
- while (st->script->script_buf[st->pos++]);
- break;
- case C_FUNC:
- run_func(st);
- if (st->state==GOTO) {
- st->state = RUN;
- if (!st->freeloop && gotocount>0 && (--gotocount)<=0) {
- ShowError("run_script: infinity loop !\n");
- script_reportsrc(st);
- st->state=END;
- }
- }
- break;
-
- case C_REF:
- st->op2ref = 1;
- break;
-
- case C_NEG:
- case C_NOT:
- case C_LNOT:
- op_1(st ,c);
- break;
-
- case C_ADD:
- case C_SUB:
- case C_MUL:
- case C_DIV:
- case C_MOD:
- case C_EQ:
- case C_NE:
- case C_GT:
- case C_GE:
- case C_LT:
- case C_LE:
- case C_AND:
- case C_OR:
- case C_XOR:
- case C_LAND:
- case C_LOR:
- case C_R_SHIFT:
- case C_L_SHIFT:
- op_2(st, c);
- break;
-
- case C_OP3:
- op_3(st, c);
- break;
-
- case C_NOP:
- st->state=END;
- break;
-
- default:
- ShowError("unknown command : %d @ %d\n",c,st->pos);
- st->state=END;
- break;
- }
- if (!st->freeloop && cmdcount>0 && (--cmdcount)<=0) {
- ShowError("run_script: infinity loop !\n");
- script_reportsrc(st);
- st->state=END;
- }
- }
-
- if (st->sleep.tick > 0) {
- //Restore previous script
- script_detach_state(st, false);
- //Delay execution
- sd = map_id2sd(st->rid); // Get sd since script might have attached someone while running. [Inkfish]
- st->sleep.charid = sd?sd->status.char_id:0;
- st->sleep.timer = add_timer(gettick()+st->sleep.tick,
- run_script_timer, st->sleep.charid, (intptr_t)st);
- linkdb_insert(&sleep_db, (void *)__64BPRTSIZE(st->oid), st);
- } else if (st->state != END && st->rid) {
- //Resume later (st is already attached to player).
- if (st->bk_st) {
- ShowWarning("Unable to restore stack! Double continuation!\n");
- //Report BOTH scripts to see if that can help somehow.
- ShowDebug("Previous script (lost):\n");
- script_reportsrc(st->bk_st);
- ShowDebug("Current script:\n");
- script_reportsrc(st);
-
- script_free_state(st->bk_st);
- st->bk_st = NULL;
- }
- } else {
- //Dispose of script.
- if ((sd = map_id2sd(st->rid))!=NULL) {
- //Restore previous stack and save char.
- if (sd->state.using_fake_npc) {
- clif_clearunit_single(sd->npc_id, CLR_OUTSIGHT, sd->fd);
- sd->state.using_fake_npc = 0;
- }
- //Restore previous script if any.
- script_detach_state(st, true);
- if (sd->state.reg_dirty&2)
- intif_saveregistry(sd,2);
- if (sd->state.reg_dirty&1)
- intif_saveregistry(sd,1);
- }
- script_free_state(st);
- st = NULL;
- }
+ int cmdcount = script_config.check_cmdcount;
+ int gotocount = script_config.check_gotocount;
+ TBL_PC *sd;
+ struct script_stack *stack=st->stack;
+ struct npc_data *nd;
+
+ script_attach_state(st);
+
+ nd = map_id2nd(st->oid);
+ if( nd && map[nd->bl.m].instance_id > 0 )
+ st->instance_id = map[nd->bl.m].instance_id;
+
+ if(st->state == RERUNLINE) {
+ run_func(st);
+ if(st->state == GOTO)
+ st->state = RUN;
+ } else if(st->state != END)
+ st->state = RUN;
+
+ while(st->state == RUN)
+ {
+ enum c_op c = get_com(st->script->script_buf,&st->pos);
+ switch(c){
+ case C_EOL:
+ if( stack->defsp > stack->sp )
+ ShowError("script:run_script_main: unexpected stack position (defsp=%d sp=%d). please report this!!!\n", stack->defsp, stack->sp);
+ else
+ pop_stack(st, stack->defsp, stack->sp);// pop unused stack data. (unused return value)
+ break;
+ case C_INT:
+ push_val(stack,C_INT,get_num(st->script->script_buf,&st->pos));
+ break;
+ case C_POS:
+ case C_NAME:
+ push_val(stack,c,GETVALUE(st->script->script_buf,st->pos));
+ st->pos+=3;
+ break;
+ case C_ARG:
+ push_val(stack,c,0);
+ break;
+ case C_STR:
+ push_str(stack,C_CONSTSTR,(char*)(st->script->script_buf+st->pos));
+ while(st->script->script_buf[st->pos++]);
+ break;
+ case C_FUNC:
+ run_func(st);
+ if(st->state==GOTO){
+ st->state = RUN;
+ if( !st->freeloop && gotocount>0 && (--gotocount)<=0 ){
+ ShowError("run_script: infinity loop !\n");
+ script_reportsrc(st);
+ st->state=END;
+ }
+ }
+ break;
+
+ case C_REF:
+ st->op2ref = 1;
+ break;
+
+ case C_NEG:
+ case C_NOT:
+ case C_LNOT:
+ op_1(st ,c);
+ break;
+
+ case C_ADD:
+ case C_SUB:
+ case C_MUL:
+ case C_DIV:
+ case C_MOD:
+ case C_EQ:
+ case C_NE:
+ case C_GT:
+ case C_GE:
+ case C_LT:
+ case C_LE:
+ case C_AND:
+ case C_OR:
+ case C_XOR:
+ case C_LAND:
+ case C_LOR:
+ case C_R_SHIFT:
+ case C_L_SHIFT:
+ op_2(st, c);
+ break;
+
+ case C_OP3:
+ op_3(st, c);
+ break;
+
+ case C_NOP:
+ st->state=END;
+ break;
+
+ default:
+ ShowError("unknown command : %d @ %d\n",c,st->pos);
+ st->state=END;
+ break;
+ }
+ if( !st->freeloop && cmdcount>0 && (--cmdcount)<=0 ){
+ ShowError("run_script: infinity loop !\n");
+ script_reportsrc(st);
+ st->state=END;
+ }
+ }
+
+ if(st->sleep.tick > 0) {
+ //Restore previous script
+ script_detach_state(st, false);
+ //Delay execution
+ sd = map_id2sd(st->rid); // Get sd since script might have attached someone while running. [Inkfish]
+ st->sleep.charid = sd?sd->status.char_id:0;
+ st->sleep.timer = add_timer(gettick()+st->sleep.tick,
+ run_script_timer, st->sleep.charid, (intptr_t)st);
+ linkdb_insert(&sleep_db, (void*)__64BPRTSIZE(st->oid), st);
+ }
+ else if(st->state != END && st->rid){
+ //Resume later (st is already attached to player).
+ if(st->bk_st) {
+ ShowWarning("Unable to restore stack! Double continuation!\n");
+ //Report BOTH scripts to see if that can help somehow.
+ ShowDebug("Previous script (lost):\n");
+ script_reportsrc(st->bk_st);
+ ShowDebug("Current script:\n");
+ script_reportsrc(st);
+
+ script_free_state(st->bk_st);
+ st->bk_st = NULL;
+ }
+ } else {
+ //Dispose of script.
+ if ((sd = map_id2sd(st->rid))!=NULL)
+ { //Restore previous stack and save char.
+ if(sd->state.using_fake_npc){
+ clif_clearunit_single(sd->npc_id, CLR_OUTSIGHT, sd->fd);
+ sd->state.using_fake_npc = 0;
+ }
+ //Restore previous script if any.
+ script_detach_state(st, true);
+ if (sd->state.reg_dirty&2)
+ intif_saveregistry(sd,2);
+ if (sd->state.reg_dirty&1)
+ intif_saveregistry(sd,1);
+ }
+ script_free_state(st);
+ st = NULL;
+ }
}
int script_config_read(char *cfgName)
{
- int i;
- char line[1024],w1[1024],w2[1024];
- FILE *fp;
-
-
- fp=fopen(cfgName,"r");
- if (fp==NULL) {
- ShowError("File not found: %s\n", cfgName);
- return 1;
- }
- while (fgets(line, sizeof(line), fp)) {
- if (line[0] == '/' && line[1] == '/')
- continue;
- i=sscanf(line,"%[^:]: %[^\r\n]",w1,w2);
- if (i!=2)
- continue;
-
- if (strcmpi(w1,"warn_func_mismatch_paramnum")==0) {
- script_config.warn_func_mismatch_paramnum = config_switch(w2);
- } else if (strcmpi(w1,"check_cmdcount")==0) {
- script_config.check_cmdcount = config_switch(w2);
- } else if (strcmpi(w1,"check_gotocount")==0) {
- script_config.check_gotocount = config_switch(w2);
- } else if (strcmpi(w1,"input_min_value")==0) {
- script_config.input_min_value = config_switch(w2);
- } else if (strcmpi(w1,"input_max_value")==0) {
- script_config.input_max_value = config_switch(w2);
- } else if (strcmpi(w1,"warn_func_mismatch_argtypes")==0) {
- script_config.warn_func_mismatch_argtypes = config_switch(w2);
- } else if (strcmpi(w1,"import")==0) {
- script_config_read(w2);
- } else {
- ShowWarning("Unknown setting '%s' in file %s\n", w1, cfgName);
- }
- }
- fclose(fp);
-
- return 0;
+ int i;
+ char line[1024],w1[1024],w2[1024];
+ FILE *fp;
+
+
+ fp=fopen(cfgName,"r");
+ if(fp==NULL){
+ ShowError("File not found: %s\n", cfgName);
+ return 1;
+ }
+ while(fgets(line, sizeof(line), fp))
+ {
+ if(line[0] == '/' && line[1] == '/')
+ continue;
+ i=sscanf(line,"%[^:]: %[^\r\n]",w1,w2);
+ if(i!=2)
+ continue;
+
+ if(strcmpi(w1,"warn_func_mismatch_paramnum")==0) {
+ script_config.warn_func_mismatch_paramnum = config_switch(w2);
+ }
+ else if(strcmpi(w1,"check_cmdcount")==0) {
+ script_config.check_cmdcount = config_switch(w2);
+ }
+ else if(strcmpi(w1,"check_gotocount")==0) {
+ script_config.check_gotocount = config_switch(w2);
+ }
+ else if(strcmpi(w1,"input_min_value")==0) {
+ script_config.input_min_value = config_switch(w2);
+ }
+ else if(strcmpi(w1,"input_max_value")==0) {
+ script_config.input_max_value = config_switch(w2);
+ }
+ else if(strcmpi(w1,"warn_func_mismatch_argtypes")==0) {
+ script_config.warn_func_mismatch_argtypes = config_switch(w2);
+ }
+ else if(strcmpi(w1,"import")==0){
+ script_config_read(w2);
+ }
+ else {
+ ShowWarning("Unknown setting '%s' in file %s\n", w1, cfgName);
+ }
+ }
+ fclose(fp);
+
+ return 0;
}
/**
@@ -3813,454 +3868,462 @@ int script_config_read(char *cfgName)
*/
static int db_script_free_code_sub(DBKey key, DBData *data, va_list ap)
{
- struct script_code *code = db_data2ptr(data);
- if (code)
- script_free_code(code);
- return 0;
+ struct script_code *code = db_data2ptr(data);
+ if (code)
+ script_free_code(code);
+ return 0;
}
void script_run_autobonus(const char *autobonus, int id, int pos)
{
- struct script_code *script = (struct script_code *)strdb_get(autobonus_db, autobonus);
+ struct script_code *script = (struct script_code *)strdb_get(autobonus_db, autobonus);
- if (script) {
- current_equip_item_index = pos;
- run_script(script,0,id,0);
- }
+ if( script )
+ {
+ current_equip_item_index = pos;
+ run_script(script,0,id,0);
+ }
}
void script_add_autobonus(const char *autobonus)
{
- if (strdb_get(autobonus_db, autobonus) == NULL) {
- struct script_code *script = parse_script(autobonus, "autobonus", 0, 0);
+ if( strdb_get(autobonus_db, autobonus) == NULL )
+ {
+ struct script_code *script = parse_script(autobonus, "autobonus", 0, 0);
- if (script)
- strdb_put(autobonus_db, autobonus, script);
- }
+ if( script )
+ strdb_put(autobonus_db, autobonus, script);
+ }
}
/// resets a temporary character array variable to given value
-void script_cleararray_pc(struct map_session_data *sd, const char *varname, void *value)
+void script_cleararray_pc(struct map_session_data* sd, const char* varname, void* value)
{
- int key;
- uint8 idx;
+ int key;
+ uint8 idx;
- if (not_array_variable(varname[0]) || !not_server_variable(varname[0])) {
- ShowError("script_cleararray_pc: Variable '%s' has invalid scope (char_id=%d).\n", varname, sd->status.char_id);
- return;
- }
+ if( not_array_variable(varname[0]) || !not_server_variable(varname[0]) )
+ {
+ ShowError("script_cleararray_pc: Variable '%s' has invalid scope (char_id=%d).\n", varname, sd->status.char_id);
+ return;
+ }
- key = add_str(varname);
+ key = add_str(varname);
- if (is_string_variable(varname)) {
- for (idx = 0; idx < SCRIPT_MAX_ARRAYSIZE; idx++) {
- pc_setregstr(sd, reference_uid(key, idx), (const char *)value);
- }
- } else {
- for (idx = 0; idx < SCRIPT_MAX_ARRAYSIZE; idx++) {
- pc_setreg(sd, reference_uid(key, idx), (int)__64BPRTSIZE(value));
- }
- }
+ if( is_string_variable(varname) )
+ {
+ for( idx = 0; idx < SCRIPT_MAX_ARRAYSIZE; idx++ )
+ {
+ pc_setregstr(sd, reference_uid(key, idx), (const char*)value);
+ }
+ }
+ else
+ {
+ for( idx = 0; idx < SCRIPT_MAX_ARRAYSIZE; idx++ )
+ {
+ pc_setreg(sd, reference_uid(key, idx), (int)__64BPRTSIZE(value));
+ }
+ }
}
/// sets a temporary character array variable element idx to given value
/// @param refcache Pointer to an int variable, which keeps a copy of the reference to varname and must be initialized to 0. Can be NULL if only one element is set.
-void script_setarray_pc(struct map_session_data *sd, const char *varname, uint8 idx, void *value, int *refcache)
-{
- int key;
-
- if (not_array_variable(varname[0]) || !not_server_variable(varname[0])) {
- ShowError("script_setarray_pc: Variable '%s' has invalid scope (char_id=%d).\n", varname, sd->status.char_id);
- return;
- }
-
- if (idx >= SCRIPT_MAX_ARRAYSIZE) {
- ShowError("script_setarray_pc: Variable '%s' has invalid index '%d' (char_id=%d).\n", varname, (int)idx, sd->status.char_id);
- return;
- }
-
- key = (refcache && refcache[0]) ? refcache[0] : add_str(varname);
-
- if (is_string_variable(varname)) {
- pc_setregstr(sd, reference_uid(key, idx), (const char *)value);
- } else {
- pc_setreg(sd, reference_uid(key, idx), (int)__64BPRTSIZE(value));
- }
-
- if (refcache) {
- // save to avoid repeated add_str calls
- refcache[0] = key;
- }
+void script_setarray_pc(struct map_session_data* sd, const char* varname, uint8 idx, void* value, int* refcache)
+{
+ int key;
+
+ if( not_array_variable(varname[0]) || !not_server_variable(varname[0]) )
+ {
+ ShowError("script_setarray_pc: Variable '%s' has invalid scope (char_id=%d).\n", varname, sd->status.char_id);
+ return;
+ }
+
+ if( idx >= SCRIPT_MAX_ARRAYSIZE )
+ {
+ ShowError("script_setarray_pc: Variable '%s' has invalid index '%d' (char_id=%d).\n", varname, (int)idx, sd->status.char_id);
+ return;
+ }
+
+ key = ( refcache && refcache[0] ) ? refcache[0] : add_str(varname);
+
+ if( is_string_variable(varname) )
+ {
+ pc_setregstr(sd, reference_uid(key, idx), (const char*)value);
+ }
+ else
+ {
+ pc_setreg(sd, reference_uid(key, idx), (int)__64BPRTSIZE(value));
+ }
+
+ if( refcache )
+ {// save to avoid repeated add_str calls
+ refcache[0] = key;
+ }
}
#ifdef BETA_THREAD_TEST
-int buildin_query_sql_sub(struct script_state *st, Sql *handle);
+int buildin_query_sql_sub(struct script_state* st, Sql* handle);
/* used to receive items the queryThread has already processed */
-int queryThread_timer(int tid, unsigned int tick, int id, intptr_t data)
-{
- int i, cursor = 0;
- bool allOk = true;
+int queryThread_timer(int tid, unsigned int tick, int id, intptr_t data) {
+ int i, cursor = 0;
+ bool allOk = true;
- EnterSpinLock(&queryThreadLock);
+ EnterSpinLock(&queryThreadLock);
- for (i = 0; i < queryThreadData.count; i++) {
- struct queryThreadEntry *entry = queryThreadData.entry[i];
+ for( i = 0; i < queryThreadData.count; i++ ) {
+ struct queryThreadEntry *entry = queryThreadData.entry[i];
- if (!entry->ok) {
- allOk = false;
- continue;
- }
+ if( !entry->ok ) {
+ allOk = false;
+ continue;
+ }
- run_script_main(entry->st);
+ run_script_main(entry->st);
- entry->st = NULL;/* empty entries */
- aFree(entry);
- queryThreadData.entry[i] = NULL;
- }
+ entry->st = NULL;/* empty entries */
+ aFree(entry);
+ queryThreadData.entry[i] = NULL;
+ }
- if (allOk) {
- /* cancel the repeating timer -- it'll re-create itself when necessary, dont need to remain looping */
- delete_timer(queryThreadData.timer, queryThread_timer);
- queryThreadData.timer = INVALID_TIMER;
- }
+ if( allOk ) {
+ /* cancel the repeating timer -- it'll re-create itself when necessary, dont need to remain looping */
+ delete_timer(queryThreadData.timer, queryThread_timer);
+ queryThreadData.timer = INVALID_TIMER;
+ }
- /* now lets clear the mess. */
- for (i = 0; i < queryThreadData.count; i++) {
- struct queryThreadEntry *entry = queryThreadData.entry[i];
- if (entry == NULL)
- continue;/* entry on hold */
+ /* now lets clear the mess. */
+ for( i = 0; i < queryThreadData.count; i++ ) {
+ struct queryThreadEntry *entry = queryThreadData.entry[i];
+ if( entry == NULL )
+ continue;/* entry on hold */
- /* move */
- memmove(&queryThreadData.entry[cursor], &queryThreadData.entry[i], sizeof(struct queryThreadEntry *));
+ /* move */
+ memmove(&queryThreadData.entry[cursor], &queryThreadData.entry[i], sizeof(struct queryThreadEntry*));
- cursor++;
- }
+ cursor++;
+ }
- queryThreadData.count = cursor;
+ queryThreadData.count = cursor;
- LeaveSpinLock(&queryThreadLock);
+ LeaveSpinLock(&queryThreadLock);
- return 0;
+ return 0;
}
-void queryThread_add(struct script_state *st, bool type)
-{
- int idx = 0;
- struct queryThreadEntry *entry = NULL;
+void queryThread_add(struct script_state *st, bool type) {
+ int idx = 0;
+ struct queryThreadEntry* entry = NULL;
- EnterSpinLock(&queryThreadLock);
+ EnterSpinLock(&queryThreadLock);
- if (queryThreadData.count++ != 0)
- RECREATE(queryThreadData.entry, struct queryThreadEntry * , queryThreadData.count);
+ if( queryThreadData.count++ != 0 )
+ RECREATE(queryThreadData.entry, struct queryThreadEntry* , queryThreadData.count);
- idx = queryThreadData.count-1;
+ idx = queryThreadData.count-1;
- CREATE(queryThreadData.entry[idx],struct queryThreadEntry,1);
+ CREATE(queryThreadData.entry[idx],struct queryThreadEntry,1);
- entry = queryThreadData.entry[idx];
+ entry = queryThreadData.entry[idx];
- entry->st = st;
- entry->ok = false;
- entry->type = type;
- if (queryThreadData.timer == INVALID_TIMER) { /* start the receiver timer */
- queryThreadData.timer = add_timer_interval(gettick() + 100, queryThread_timer, 0, 0, 100);
- }
+ entry->st = st;
+ entry->ok = false;
+ entry->type = type;
+ if( queryThreadData.timer == INVALID_TIMER ) { /* start the receiver timer */
+ queryThreadData.timer = add_timer_interval(gettick() + 100, queryThread_timer, 0, 0, 100);
+ }
- LeaveSpinLock(&queryThreadLock);
+ LeaveSpinLock(&queryThreadLock);
- /* unlock the queryThread */
- racond_signal(queryThreadCond);
+ /* unlock the queryThread */
+ racond_signal(queryThreadCond);
}
/* adds a new log to the queue */
-void queryThread_log(char *entry, int length)
-{
- int idx = logThreadData.count;
+void queryThread_log(char * entry, int length) {
+ int idx = logThreadData.count;
- EnterSpinLock(&queryThreadLock);
+ EnterSpinLock(&queryThreadLock);
- if (logThreadData.count++ != 0)
- RECREATE(logThreadData.entry, char * , logThreadData.count);
+ if( logThreadData.count++ != 0 )
+ RECREATE(logThreadData.entry, char* , logThreadData.count);
- CREATE(logThreadData.entry[idx], char, length + 1);
- safestrncpy(logThreadData.entry[idx], entry, length + 1);
+ CREATE(logThreadData.entry[idx], char, length + 1 );
+ safestrncpy(logThreadData.entry[idx], entry, length + 1 );
- LeaveSpinLock(&queryThreadLock);
+ LeaveSpinLock(&queryThreadLock);
- /* unlock the queryThread */
- racond_signal(queryThreadCond);
+ /* unlock the queryThread */
+ racond_signal(queryThreadCond);
}
/* queryThread_main */
-static void *queryThread_main(void *x)
-{
- Sql *queryThread_handle = Sql_Malloc();
- int i;
+static void *queryThread_main(void *x) {
+ Sql *queryThread_handle = Sql_Malloc();
+ int i;
- if (SQL_ERROR == Sql_Connect(queryThread_handle, map_server_id, map_server_pw, map_server_ip, map_server_port, map_server_db))
- exit(EXIT_FAILURE);
+ if ( SQL_ERROR == Sql_Connect(queryThread_handle, map_server_id, map_server_pw, map_server_ip, map_server_port, map_server_db) )
+ exit(EXIT_FAILURE);
- if (strlen(default_codepage) > 0)
- if (SQL_ERROR == Sql_SetEncoding(queryThread_handle, default_codepage))
- Sql_ShowDebug(queryThread_handle);
+ if( strlen(default_codepage) > 0 )
+ if ( SQL_ERROR == Sql_SetEncoding(queryThread_handle, default_codepage) )
+ Sql_ShowDebug(queryThread_handle);
- if (log_config.sql_logs) {
- logmysql_handle = Sql_Malloc();
+ if( log_config.sql_logs ) {
+ logmysql_handle = Sql_Malloc();
- if (SQL_ERROR == Sql_Connect(logmysql_handle, log_db_id, log_db_pw, log_db_ip, log_db_port, log_db_db))
- exit(EXIT_FAILURE);
+ if ( SQL_ERROR == Sql_Connect(logmysql_handle, log_db_id, log_db_pw, log_db_ip, log_db_port, log_db_db) )
+ exit(EXIT_FAILURE);
- if (strlen(default_codepage) > 0)
- if (SQL_ERROR == Sql_SetEncoding(logmysql_handle, default_codepage))
- Sql_ShowDebug(logmysql_handle);
- }
+ if( strlen(default_codepage) > 0 )
+ if ( SQL_ERROR == Sql_SetEncoding(logmysql_handle, default_codepage) )
+ Sql_ShowDebug(logmysql_handle);
+ }
- while (1) {
+ while( 1 ) {
- if (queryThreadTerminate > 0)
- break;
+ if(queryThreadTerminate > 0)
+ break;
- EnterSpinLock(&queryThreadLock);
+ EnterSpinLock(&queryThreadLock);
- /* mess with queryThreadData within the lock */
- for (i = 0; i < queryThreadData.count; i++) {
- struct queryThreadEntry *entry = queryThreadData.entry[i];
+ /* mess with queryThreadData within the lock */
+ for( i = 0; i < queryThreadData.count; i++ ) {
+ struct queryThreadEntry *entry = queryThreadData.entry[i];
- if (entry->ok)
- continue;
- else if (!entry->st || !entry->st->stack) {
- entry->ok = true;/* dispose */
- continue;
- }
+ if( entry->ok )
+ continue;
+ else if ( !entry->st || !entry->st->stack ) {
+ entry->ok = true;/* dispose */
+ continue;
+ }
- buildin_query_sql_sub(entry->st, entry->type ? logmysql_handle : queryThread_handle);
+ buildin_query_sql_sub(entry->st, entry->type ? logmysql_handle : queryThread_handle);
- entry->ok = true;/* we're done with this */
- }
+ entry->ok = true;/* we're done with this */
+ }
- /* also check for any logs in need to be sent */
- if (log_config.sql_logs) {
- for (i = 0; i < logThreadData.count; i++) {
- if (SQL_ERROR == Sql_Query(logmysql_handle, logThreadData.entry[i]))
- Sql_ShowDebug(logmysql_handle);
- aFree(logThreadData.entry[i]);
- }
- logThreadData.count = 0;
- }
+ /* also check for any logs in need to be sent */
+ if( log_config.sql_logs ) {
+ for( i = 0; i < logThreadData.count; i++ ) {
+ if( SQL_ERROR == Sql_Query(logmysql_handle, logThreadData.entry[i]) )
+ Sql_ShowDebug(logmysql_handle);
+ aFree(logThreadData.entry[i]);
+ }
+ logThreadData.count = 0;
+ }
- LeaveSpinLock(&queryThreadLock);
+ LeaveSpinLock(&queryThreadLock);
- ramutex_lock(queryThreadMutex);
- racond_wait(queryThreadCond, queryThreadMutex, -1);
- ramutex_unlock(queryThreadMutex);
+ ramutex_lock( queryThreadMutex );
+ racond_wait( queryThreadCond, queryThreadMutex, -1 );
+ ramutex_unlock( queryThreadMutex );
- }
+ }
- Sql_Free(queryThread_handle);
+ Sql_Free(queryThread_handle);
- if (log_config.sql_logs) {
- Sql_Free(logmysql_handle);
- }
+ if( log_config.sql_logs ) {
+ Sql_Free(logmysql_handle);
+ }
- return NULL;
+ return NULL;
}
#endif
/*==========================================
* Destructor
*------------------------------------------*/
-int do_final_script()
-{
- int i;
+int do_final_script() {
+ int i;
#ifdef DEBUG_HASH
- if (battle_config.etc_log) {
- FILE *fp = fopen("hash_dump.txt","wt");
- if (fp) {
- int count[SCRIPT_HASH_SIZE];
- int count2[SCRIPT_HASH_SIZE]; // number of buckets with a certain number of items
- int n=0;
- int min=INT_MAX,max=0,zero=0;
- double mean=0.0f;
- double median=0.0f;
-
- ShowNotice("Dumping script str hash information to hash_dump.txt\n");
- memset(count, 0, sizeof(count));
- fprintf(fp,"num : hash : data_name\n");
- fprintf(fp,"---------------------------------------------------------------\n");
- for (i=LABEL_START; i<str_num; i++) {
- unsigned int h = calc_hash(get_str(i));
- fprintf(fp,"%04d : %4u : %s\n",i,h, get_str(i));
- ++count[h];
- }
- fprintf(fp,"--------------------\n\n");
- memset(count2, 0, sizeof(count2));
- for (i=0; i<SCRIPT_HASH_SIZE; i++) {
- fprintf(fp," hash %3d = %d\n",i,count[i]);
- if (min > count[i])
- min = count[i]; // minimun count of collision
- if (max < count[i])
- max = count[i]; // maximun count of collision
- if (count[i] == 0)
- zero++;
- ++count2[count[i]];
- }
- fprintf(fp,"\n--------------------\n items : buckets\n--------------------\n");
- for (i=min; i <= max; ++i) {
- fprintf(fp," %5d : %7d\n",i,count2[i]);
- mean += 1.0f*i*count2[i]/SCRIPT_HASH_SIZE; // Note: this will always result in <nr labels>/<nr buckets>
- }
- for (i=min; i <= max; ++i) {
- n += count2[i];
- if (n*2 >= SCRIPT_HASH_SIZE) {
- if (SCRIPT_HASH_SIZE%2 == 0 && SCRIPT_HASH_SIZE/2 == n)
- median = (i+i+1)/2.0f;
- else
- median = i;
- break;
- }
- }
- fprintf(fp,"--------------------\n min = %d, max = %d, zero = %d\n mean = %lf, median = %lf\n",min,max,zero,mean,median);
- fclose(fp);
- }
- }
+ if (battle_config.etc_log)
+ {
+ FILE *fp = fopen("hash_dump.txt","wt");
+ if(fp) {
+ int count[SCRIPT_HASH_SIZE];
+ int count2[SCRIPT_HASH_SIZE]; // number of buckets with a certain number of items
+ int n=0;
+ int min=INT_MAX,max=0,zero=0;
+ double mean=0.0f;
+ double median=0.0f;
+
+ ShowNotice("Dumping script str hash information to hash_dump.txt\n");
+ memset(count, 0, sizeof(count));
+ fprintf(fp,"num : hash : data_name\n");
+ fprintf(fp,"---------------------------------------------------------------\n");
+ for(i=LABEL_START; i<str_num; i++) {
+ unsigned int h = calc_hash(get_str(i));
+ fprintf(fp,"%04d : %4u : %s\n",i,h, get_str(i));
+ ++count[h];
+ }
+ fprintf(fp,"--------------------\n\n");
+ memset(count2, 0, sizeof(count2));
+ for(i=0; i<SCRIPT_HASH_SIZE; i++) {
+ fprintf(fp," hash %3d = %d\n",i,count[i]);
+ if(min > count[i])
+ min = count[i]; // minimun count of collision
+ if(max < count[i])
+ max = count[i]; // maximun count of collision
+ if(count[i] == 0)
+ zero++;
+ ++count2[count[i]];
+ }
+ fprintf(fp,"\n--------------------\n items : buckets\n--------------------\n");
+ for( i=min; i <= max; ++i ){
+ fprintf(fp," %5d : %7d\n",i,count2[i]);
+ mean += 1.0f*i*count2[i]/SCRIPT_HASH_SIZE; // Note: this will always result in <nr labels>/<nr buckets>
+ }
+ for( i=min; i <= max; ++i ){
+ n += count2[i];
+ if( n*2 >= SCRIPT_HASH_SIZE )
+ {
+ if( SCRIPT_HASH_SIZE%2 == 0 && SCRIPT_HASH_SIZE/2 == n )
+ median = (i+i+1)/2.0f;
+ else
+ median = i;
+ break;
+ }
+ }
+ fprintf(fp,"--------------------\n min = %d, max = %d, zero = %d\n mean = %lf, median = %lf\n",min,max,zero,mean,median);
+ fclose(fp);
+ }
+ }
#endif
- mapreg_final();
-
- db_destroy(scriptlabel_db);
- userfunc_db->destroy(userfunc_db, db_script_free_code_sub);
- autobonus_db->destroy(autobonus_db, db_script_free_code_sub);
- if (sleep_db) {
- struct linkdb_node *n = (struct linkdb_node *)sleep_db;
- while (n) {
- struct script_state *st = (struct script_state *)n->data;
- script_free_state(st);
- n = n->next;
- }
- linkdb_final(&sleep_db);
- }
+ mapreg_final();
+
+ db_destroy(scriptlabel_db);
+ userfunc_db->destroy(userfunc_db, db_script_free_code_sub);
+ autobonus_db->destroy(autobonus_db, db_script_free_code_sub);
+ if(sleep_db) {
+ struct linkdb_node *n = (struct linkdb_node *)sleep_db;
+ while(n) {
+ struct script_state *st = (struct script_state *)n->data;
+ script_free_state(st);
+ n = n->next;
+ }
+ linkdb_final(&sleep_db);
+ }
+
+ if (str_data)
+ aFree(str_data);
+ if (str_buf)
+ aFree(str_buf);
+
+ for( i = 0; i < atcmd_binding_count; i++ ) {
+ aFree(atcmd_binding[i]);
+ }
+
+ if( atcmd_binding_count != 0 )
+ aFree(atcmd_binding);
+#ifdef BETA_THREAD_TEST
+ /* QueryThread */
+ InterlockedIncrement(&queryThreadTerminate);
+ racond_signal(queryThreadCond);
+ rathread_wait(queryThread, NULL);
- if (str_data)
- aFree(str_data);
- if (str_buf)
- aFree(str_buf);
+ // Destroy cond var and mutex.
+ racond_destroy( queryThreadCond );
+ ramutex_destroy( queryThreadMutex );
- for (i = 0; i < atcmd_binding_count; i++) {
- aFree(atcmd_binding[i]);
- }
-
- if (atcmd_binding_count != 0)
- aFree(atcmd_binding);
-#ifdef BETA_THREAD_TEST
- /* QueryThread */
- InterlockedIncrement(&queryThreadTerminate);
- racond_signal(queryThreadCond);
- rathread_wait(queryThread, NULL);
-
- // Destroy cond var and mutex.
- racond_destroy(queryThreadCond);
- ramutex_destroy(queryThreadMutex);
-
- /* Clear missing vars */
- for (i = 0; i < queryThreadData.count; i++) {
- aFree(queryThreadData.entry[i]);
- }
+ /* Clear missing vars */
+ for( i = 0; i < queryThreadData.count; i++ ) {
+ aFree(queryThreadData.entry[i]);
+ }
- aFree(queryThreadData.entry);
+ aFree(queryThreadData.entry);
- for (i = 0; i < logThreadData.count; i++) {
- aFree(logThreadData.entry[i]);
- }
+ for( i = 0; i < logThreadData.count; i++ ) {
+ aFree(logThreadData.entry[i]);
+ }
- aFree(logThreadData.entry);
+ aFree(logThreadData.entry);
#endif
- return 0;
+ return 0;
}
/*==========================================
* Initialization
*------------------------------------------*/
-int do_init_script()
-{
- userfunc_db=strdb_alloc(DB_OPT_DUP_KEY,0);
- scriptlabel_db=strdb_alloc(DB_OPT_DUP_KEY,50);
- autobonus_db = strdb_alloc(DB_OPT_DUP_KEY,0);
+int do_init_script() {
+ userfunc_db=strdb_alloc(DB_OPT_DUP_KEY,0);
+ scriptlabel_db=strdb_alloc(DB_OPT_DUP_KEY,50);
+ autobonus_db = strdb_alloc(DB_OPT_DUP_KEY,0);
- mapreg_init();
+ mapreg_init();
#ifdef BETA_THREAD_TEST
- CREATE(queryThreadData.entry, struct queryThreadEntry *, 1);
- queryThreadData.count = 0;
- CREATE(logThreadData.entry, char *, 1);
- logThreadData.count = 0;
- /* QueryThread Start */
+ CREATE(queryThreadData.entry, struct queryThreadEntry*, 1);
+ queryThreadData.count = 0;
+ CREATE(logThreadData.entry, char *, 1);
+ logThreadData.count = 0;
+ /* QueryThread Start */
- InitializeSpinLock(&queryThreadLock);
+ InitializeSpinLock(&queryThreadLock);
- queryThreadData.timer = INVALID_TIMER;
- queryThreadTerminate = 0;
- queryThreadMutex = ramutex_create();
- queryThreadCond = racond_create();
+ queryThreadData.timer = INVALID_TIMER;
+ queryThreadTerminate = 0;
+ queryThreadMutex = ramutex_create();
+ queryThreadCond = racond_create();
- queryThread = rathread_create(queryThread_main, NULL);
+ queryThread = rathread_create(queryThread_main, NULL);
- if (queryThread == NULL) {
- ShowFatalError("do_init_script: cannot spawn Query Thread.\n");
- exit(EXIT_FAILURE);
- }
+ if(queryThread == NULL){
+ ShowFatalError("do_init_script: cannot spawn Query Thread.\n");
+ exit(EXIT_FAILURE);
+ }
- add_timer_func_list(queryThread_timer, "queryThread_timer");
+ add_timer_func_list(queryThread_timer, "queryThread_timer");
#endif
- return 0;
+ return 0;
}
-int script_reload()
-{
- int i;
+int script_reload() {
+ int i;
#ifdef BETA_THREAD_TEST
- /* we're reloading so any queries undergoing should be...exterminated. */
- EnterSpinLock(&queryThreadLock);
+ /* we're reloading so any queries undergoing should be...exterminated. */
+ EnterSpinLock(&queryThreadLock);
- for (i = 0; i < queryThreadData.count; i++) {
- aFree(queryThreadData.entry[i]);
- }
- queryThreadData.count = 0;
+ for( i = 0; i < queryThreadData.count; i++ ) {
+ aFree(queryThreadData.entry[i]);
+ }
+ queryThreadData.count = 0;
- if (queryThreadData.timer != INVALID_TIMER) {
- delete_timer(queryThreadData.timer, queryThread_timer);
- queryThreadData.timer = INVALID_TIMER;
- }
+ if( queryThreadData.timer != INVALID_TIMER ) {
+ delete_timer(queryThreadData.timer, queryThread_timer);
+ queryThreadData.timer = INVALID_TIMER;
+ }
- LeaveSpinLock(&queryThreadLock);
+ LeaveSpinLock(&queryThreadLock);
#endif
- userfunc_db->clear(userfunc_db, db_script_free_code_sub);
- db_clear(scriptlabel_db);
+ userfunc_db->clear(userfunc_db, db_script_free_code_sub);
+ db_clear(scriptlabel_db);
- // @commands (script based)
- // Clear bindings
- for (i = 0; i < atcmd_binding_count; i++) {
- aFree(atcmd_binding[i]);
- }
+ // @commands (script based)
+ // Clear bindings
+ for( i = 0; i < atcmd_binding_count; i++ ) {
+ aFree(atcmd_binding[i]);
+ }
- if (atcmd_binding_count != 0)
- aFree(atcmd_binding);
+ if( atcmd_binding_count != 0 )
+ aFree(atcmd_binding);
- atcmd_binding_count = 0;
+ atcmd_binding_count = 0;
- if (sleep_db) {
- struct linkdb_node *n = (struct linkdb_node *)sleep_db;
- while (n) {
- struct script_state *st = (struct script_state *)n->data;
- script_free_state(st);
- n = n->next;
- }
- linkdb_final(&sleep_db);
- }
- mapreg_reload();
- return 0;
+ if(sleep_db) {
+ struct linkdb_node *n = (struct linkdb_node *)sleep_db;
+ while(n) {
+ struct script_state *st = (struct script_state *)n->data;
+ script_free_state(st);
+ n = n->next;
+ }
+ linkdb_final(&sleep_db);
+ }
+ mapreg_reload();
+ return 0;
}
//-----------------------------------------------------------------------------
@@ -4281,24 +4344,26 @@ int script_reload()
/// mes "<message>";
BUILDIN_FUNC(mes)
{
- TBL_PC *sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ TBL_PC* sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- if (!script_hasdata(st, 3)) {
- // only a single line detected in the script
- clif_scriptmes(sd, st->oid, script_getstr(st, 2));
- } else {
- // parse multiple lines as they exist
- int i;
+ if( !script_hasdata(st, 3) )
+ {// only a single line detected in the script
+ clif_scriptmes(sd, st->oid, script_getstr(st, 2));
+ }
+ else
+ {// parse multiple lines as they exist
+ int i;
- for (i = 2; script_hasdata(st, i); i++) {
- // send the message to the client
- clif_scriptmes(sd, st->oid, script_getstr(st, i));
- }
- }
+ for( i = 2; script_hasdata(st, i); i++ )
+ {
+ // send the message to the client
+ clif_scriptmes(sd, st->oid, script_getstr(st, i));
+ }
+ }
- return 0;
+ return 0;
}
/// Displays the button 'next' in the npc dialog.
@@ -4307,15 +4372,15 @@ BUILDIN_FUNC(mes)
/// next;
BUILDIN_FUNC(next)
{
- TBL_PC *sd;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- st->state = STOP;
- clif_scriptnext(sd, st->oid);
- return 0;
+ st->state = STOP;
+ clif_scriptnext(sd, st->oid);
+ return 0;
}
/// Ends the script and displays the button 'close' on the npc dialog.
@@ -4324,15 +4389,15 @@ BUILDIN_FUNC(next)
/// close;
BUILDIN_FUNC(close)
{
- TBL_PC *sd;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- st->state = END;
- clif_scriptclose(sd, st->oid);
- return 0;
+ st->state = END;
+ clif_scriptclose(sd, st->oid);
+ return 0;
}
/// Displays the button 'close' on the npc dialog.
@@ -4341,48 +4406,51 @@ BUILDIN_FUNC(close)
/// close2;
BUILDIN_FUNC(close2)
{
- TBL_PC *sd;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- st->state = STOP;
- clif_scriptclose(sd, st->oid);
- return 0;
+ st->state = STOP;
+ clif_scriptclose(sd, st->oid);
+ return 0;
}
/// Counts the number of valid and total number of options in 'str'
/// If max_count > 0 the counting stops when that valid option is reached
/// total is incremented for each option (NULL is supported)
-static int menu_countoptions(const char *str, int max_count, int *total)
-{
- int count = 0;
- int bogus_total;
-
- if (total == NULL)
- total = &bogus_total;
- ++(*total);
-
- // initial empty options
- while (*str == ':') {
- ++str;
- ++(*total);
- }
- // count menu options
- while (*str != '\0') {
- ++count;
- --max_count;
- if (max_count == 0)
- break;
- while (*str != ':' && *str != '\0')
- ++str;
- while (*str == ':') {
- ++str;
- ++(*total);
- }
- }
- return count;
+static int menu_countoptions(const char* str, int max_count, int* total)
+{
+ int count = 0;
+ int bogus_total;
+
+ if( total == NULL )
+ total = &bogus_total;
+ ++(*total);
+
+ // initial empty options
+ while( *str == ':' )
+ {
+ ++str;
+ ++(*total);
+ }
+ // count menu options
+ while( *str != '\0' )
+ {
+ ++count;
+ --max_count;
+ if( max_count == 0 )
+ break;
+ while( *str != ':' && *str != '\0' )
+ ++str;
+ while( *str == ':' )
+ {
+ ++str;
+ ++(*total);
+ }
+ }
+ return count;
}
/// Displays a menu with options and goes to the target label.
@@ -4403,115 +4471,121 @@ static int menu_countoptions(const char *str, int max_count, int *total)
/// menu "<option_text>",<target_label>{,"<option_text>",<target_label>,...};
BUILDIN_FUNC(menu)
{
- int i;
- const char *text;
- TBL_PC *sd;
-
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
-
- // TODO detect multiple scripts waiting for input at the same time, and what to do when that happens
- if (sd->state.menu_or_input == 0) {
- struct StringBuf buf;
- struct script_data *data;
-
- if (script_lastdata(st) % 2 == 0) {
- // argument count is not even (1st argument is at index 2)
- ShowError("script:menu: illegal number of arguments (%d).\n", (script_lastdata(st) - 1));
- st->state = END;
- return 1;
- }
-
- StringBuf_Init(&buf);
- sd->npc_menu = 0;
- for (i = 2; i < script_lastdata(st); i += 2) {
- // menu options
- text = script_getstr(st, i);
-
- // target label
- data = script_getdata(st, i+1);
- if (!data_islabel(data)) {
- // not a label
- StringBuf_Destroy(&buf);
- ShowError("script:menu: argument #%d (from 1) is not a label or label not found.\n", i);
- script_reportdata(data);
- st->state = END;
- return 1;
- }
-
- // append option(s)
- if (text[0] == '\0')
- continue;// empty string, ignore
- if (sd->npc_menu > 0)
- StringBuf_AppendStr(&buf, ":");
- StringBuf_AppendStr(&buf, text);
- sd->npc_menu += menu_countoptions(text, 0, NULL);
- }
- st->state = RERUNLINE;
- sd->state.menu_or_input = 1;
-
- /**
- * menus beyond this length crash the client (see bugreport:6402)
- **/
- if (StringBuf_Length(&buf) >= 2047) {
- struct npc_data *nd = map_id2nd(st->oid);
- char *menu;
- CREATE(menu, char, 2048);
- safestrncpy(menu, StringBuf_Value(&buf), 2047);
- ShowWarning("NPC Menu too long! (source:%s / length:%d)\n",nd?nd->name:"Unknown",StringBuf_Length(&buf));
- clif_scriptmenu(sd, st->oid, menu);
- aFree(menu);
- } else
- clif_scriptmenu(sd, st->oid, StringBuf_Value(&buf));
-
- StringBuf_Destroy(&buf);
-
- if (sd->npc_menu >= 0xff) {
- // client supports only up to 254 entries; 0 is not used and 255 is reserved for cancel; excess entries are displayed but cause 'uint8' overflow
- ShowWarning("buildin_menu: Too many options specified (current=%d, max=254).\n", sd->npc_menu);
- script_reportsrc(st);
- }
- } else if (sd->npc_menu == 0xff) {
- // Cancel was pressed
- sd->state.menu_or_input = 0;
- st->state = END;
- } else {
- // goto target label
- int menu = 0;
-
- sd->state.menu_or_input = 0;
- if (sd->npc_menu <= 0) {
- ShowDebug("script:menu: unexpected selection (%d)\n", sd->npc_menu);
- st->state = END;
- return 1;
- }
-
- // get target label
- for (i = 2; i < script_lastdata(st); i += 2) {
- text = script_getstr(st, i);
- sd->npc_menu -= menu_countoptions(text, sd->npc_menu, &menu);
- if (sd->npc_menu <= 0)
- break;// entry found
- }
- if (sd->npc_menu > 0) {
- // Invalid selection
- ShowDebug("script:menu: selection is out of range (%d pairs are missing?) - please report this\n", sd->npc_menu);
- st->state = END;
- return 1;
- }
- if (!data_islabel(script_getdata(st, i + 1))) {
- // TODO remove this temporary crash-prevention code (fallback for multiple scripts requesting user input)
- ShowError("script:menu: unexpected data in label argument\n");
- script_reportdata(script_getdata(st, i + 1));
- st->state = END;
- return 1;
- }
- pc_setreg(sd, add_str("@menu"), menu);
- st->pos = script_getnum(st, i + 1);
- st->state = GOTO;
- }
- return 0;
+ int i;
+ const char* text;
+ TBL_PC* sd;
+
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
+
+ // TODO detect multiple scripts waiting for input at the same time, and what to do when that happens
+ if( sd->state.menu_or_input == 0 )
+ {
+ struct StringBuf buf;
+ struct script_data* data;
+
+ if( script_lastdata(st) % 2 == 0 )
+ {// argument count is not even (1st argument is at index 2)
+ ShowError("script:menu: illegal number of arguments (%d).\n", (script_lastdata(st) - 1));
+ st->state = END;
+ return 1;
+ }
+
+ StringBuf_Init(&buf);
+ sd->npc_menu = 0;
+ for( i = 2; i < script_lastdata(st); i += 2 )
+ {
+ // menu options
+ text = script_getstr(st, i);
+
+ // target label
+ data = script_getdata(st, i+1);
+ if( !data_islabel(data) )
+ {// not a label
+ StringBuf_Destroy(&buf);
+ ShowError("script:menu: argument #%d (from 1) is not a label or label not found.\n", i);
+ script_reportdata(data);
+ st->state = END;
+ return 1;
+ }
+
+ // append option(s)
+ if( text[0] == '\0' )
+ continue;// empty string, ignore
+ if( sd->npc_menu > 0 )
+ StringBuf_AppendStr(&buf, ":");
+ StringBuf_AppendStr(&buf, text);
+ sd->npc_menu += menu_countoptions(text, 0, NULL);
+ }
+ st->state = RERUNLINE;
+ sd->state.menu_or_input = 1;
+
+ /**
+ * menus beyond this length crash the client (see bugreport:6402)
+ **/
+ if( StringBuf_Length(&buf) >= 2047 ) {
+ struct npc_data * nd = map_id2nd(st->oid);
+ char* menu;
+ CREATE(menu, char, 2048);
+ safestrncpy(menu, StringBuf_Value(&buf), 2047);
+ ShowWarning("NPC Menu too long! (source:%s / length:%d)\n",nd?nd->name:"Unknown",StringBuf_Length(&buf));
+ clif_scriptmenu(sd, st->oid, menu);
+ aFree(menu);
+ } else
+ clif_scriptmenu(sd, st->oid, StringBuf_Value(&buf));
+
+ StringBuf_Destroy(&buf);
+
+ if( sd->npc_menu >= 0xff )
+ {// client supports only up to 254 entries; 0 is not used and 255 is reserved for cancel; excess entries are displayed but cause 'uint8' overflow
+ ShowWarning("buildin_menu: Too many options specified (current=%d, max=254).\n", sd->npc_menu);
+ script_reportsrc(st);
+ }
+ }
+ else if( sd->npc_menu == 0xff )
+ {// Cancel was pressed
+ sd->state.menu_or_input = 0;
+ st->state = END;
+ }
+ else
+ {// goto target label
+ int menu = 0;
+
+ sd->state.menu_or_input = 0;
+ if( sd->npc_menu <= 0 )
+ {
+ ShowDebug("script:menu: unexpected selection (%d)\n", sd->npc_menu);
+ st->state = END;
+ return 1;
+ }
+
+ // get target label
+ for( i = 2; i < script_lastdata(st); i += 2 )
+ {
+ text = script_getstr(st, i);
+ sd->npc_menu -= menu_countoptions(text, sd->npc_menu, &menu);
+ if( sd->npc_menu <= 0 )
+ break;// entry found
+ }
+ if( sd->npc_menu > 0 )
+ {// Invalid selection
+ ShowDebug("script:menu: selection is out of range (%d pairs are missing?) - please report this\n", sd->npc_menu);
+ st->state = END;
+ return 1;
+ }
+ if( !data_islabel(script_getdata(st, i + 1)) )
+ {// TODO remove this temporary crash-prevention code (fallback for multiple scripts requesting user input)
+ ShowError("script:menu: unexpected data in label argument\n");
+ script_reportdata(script_getdata(st, i + 1));
+ st->state = END;
+ return 1;
+ }
+ pc_setreg(sd, add_str("@menu"), menu);
+ st->pos = script_getnum(st, i + 1);
+ st->state = GOTO;
+ }
+ return 0;
}
/// Displays a menu with options and returns the selected option.
@@ -4522,69 +4596,69 @@ BUILDIN_FUNC(menu)
/// @see menu
BUILDIN_FUNC(select)
{
- int i;
- const char *text;
- TBL_PC *sd;
-
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
-
- if (sd->state.menu_or_input == 0) {
- struct StringBuf buf;
-
- StringBuf_Init(&buf);
- sd->npc_menu = 0;
- for (i = 2; i <= script_lastdata(st); ++i) {
- text = script_getstr(st, i);
-
- if (sd->npc_menu > 0)
- StringBuf_AppendStr(&buf, ":");
-
- StringBuf_AppendStr(&buf, text);
- sd->npc_menu += menu_countoptions(text, 0, NULL);
- }
-
- st->state = RERUNLINE;
- sd->state.menu_or_input = 1;
-
- /**
- * menus beyond this length crash the client (see bugreport:6402)
- **/
- if (StringBuf_Length(&buf) >= 2047) {
- struct npc_data *nd = map_id2nd(st->oid);
- char *menu;
- CREATE(menu, char, 2048);
- safestrncpy(menu, StringBuf_Value(&buf), 2047);
- ShowWarning("NPC Menu too long! (source:%s / length:%d)\n",nd?nd->name:"Unknown",StringBuf_Length(&buf));
- clif_scriptmenu(sd, st->oid, menu);
- aFree(menu);
- } else
- clif_scriptmenu(sd, st->oid, StringBuf_Value(&buf));
- StringBuf_Destroy(&buf);
-
- if (sd->npc_menu >= 0xff) {
- ShowWarning("buildin_select: Too many options specified (current=%d, max=254).\n", sd->npc_menu);
- script_reportsrc(st);
- }
- } else if (sd->npc_menu == 0xff) { // Cancel was pressed
- sd->state.menu_or_input = 0;
- st->state = END;
- } else {// return selected option
- int menu = 0;
-
- sd->state.menu_or_input = 0;
- for (i = 2; i <= script_lastdata(st); ++i) {
- text = script_getstr(st, i);
- sd->npc_menu -= menu_countoptions(text, sd->npc_menu, &menu);
- if (sd->npc_menu <= 0)
- break;// entry found
- }
- pc_setreg(sd, add_str("@menu"), menu);
- script_pushint(st, menu);
- st->state = RUN;
- }
- return 0;
+ int i;
+ const char* text;
+ TBL_PC* sd;
+
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
+
+ if( sd->state.menu_or_input == 0 ) {
+ struct StringBuf buf;
+
+ StringBuf_Init(&buf);
+ sd->npc_menu = 0;
+ for( i = 2; i <= script_lastdata(st); ++i ) {
+ text = script_getstr(st, i);
+
+ if( sd->npc_menu > 0 )
+ StringBuf_AppendStr(&buf, ":");
+
+ StringBuf_AppendStr(&buf, text);
+ sd->npc_menu += menu_countoptions(text, 0, NULL);
+ }
+
+ st->state = RERUNLINE;
+ sd->state.menu_or_input = 1;
+
+ /**
+ * menus beyond this length crash the client (see bugreport:6402)
+ **/
+ if( StringBuf_Length(&buf) >= 2047 ) {
+ struct npc_data * nd = map_id2nd(st->oid);
+ char* menu;
+ CREATE(menu, char, 2048);
+ safestrncpy(menu, StringBuf_Value(&buf), 2047);
+ ShowWarning("NPC Menu too long! (source:%s / length:%d)\n",nd?nd->name:"Unknown",StringBuf_Length(&buf));
+ clif_scriptmenu(sd, st->oid, menu);
+ aFree(menu);
+ } else
+ clif_scriptmenu(sd, st->oid, StringBuf_Value(&buf));
+ StringBuf_Destroy(&buf);
+
+ if( sd->npc_menu >= 0xff ) {
+ ShowWarning("buildin_select: Too many options specified (current=%d, max=254).\n", sd->npc_menu);
+ script_reportsrc(st);
+ }
+ } else if( sd->npc_menu == 0xff ) {// Cancel was pressed
+ sd->state.menu_or_input = 0;
+ st->state = END;
+ } else {// return selected option
+ int menu = 0;
+
+ sd->state.menu_or_input = 0;
+ for( i = 2; i <= script_lastdata(st); ++i ) {
+ text = script_getstr(st, i);
+ sd->npc_menu -= menu_countoptions(text, sd->npc_menu, &menu);
+ if( sd->npc_menu <= 0 )
+ break;// entry found
+ }
+ pc_setreg(sd, add_str("@menu"), menu);
+ script_pushint(st, menu);
+ st->state = RUN;
+ }
+ return 0;
}
/// Displays a menu with options and returns the selected option.
@@ -4597,71 +4671,77 @@ BUILDIN_FUNC(select)
/// @see menu
BUILDIN_FUNC(prompt)
{
- int i;
- const char *text;
- TBL_PC *sd;
-
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
-
- if (sd->state.menu_or_input == 0) {
- struct StringBuf buf;
-
- StringBuf_Init(&buf);
- sd->npc_menu = 0;
- for (i = 2; i <= script_lastdata(st); ++i) {
- text = script_getstr(st, i);
- if (sd->npc_menu > 0)
- StringBuf_AppendStr(&buf, ":");
- StringBuf_AppendStr(&buf, text);
- sd->npc_menu += menu_countoptions(text, 0, NULL);
- }
-
- st->state = RERUNLINE;
- sd->state.menu_or_input = 1;
-
- /**
- * menus beyond this length crash the client (see bugreport:6402)
- **/
- if (StringBuf_Length(&buf) >= 2047) {
- struct npc_data *nd = map_id2nd(st->oid);
- char *menu;
- CREATE(menu, char, 2048);
- safestrncpy(menu, StringBuf_Value(&buf), 2047);
- ShowWarning("NPC Menu too long! (source:%s / length:%d)\n",nd?nd->name:"Unknown",StringBuf_Length(&buf));
- clif_scriptmenu(sd, st->oid, menu);
- aFree(menu);
- } else
- clif_scriptmenu(sd, st->oid, StringBuf_Value(&buf));
- StringBuf_Destroy(&buf);
-
- if (sd->npc_menu >= 0xff) {
- ShowWarning("buildin_prompt: Too many options specified (current=%d, max=254).\n", sd->npc_menu);
- script_reportsrc(st);
- }
- } else if (sd->npc_menu == 0xff) {
- // Cancel was pressed
- sd->state.menu_or_input = 0;
- pc_setreg(sd, add_str("@menu"), 0xff);
- script_pushint(st, 0xff);
- st->state = RUN;
- } else {
- // return selected option
- int menu = 0;
-
- sd->state.menu_or_input = 0;
- for (i = 2; i <= script_lastdata(st); ++i) {
- text = script_getstr(st, i);
- sd->npc_menu -= menu_countoptions(text, sd->npc_menu, &menu);
- if (sd->npc_menu <= 0)
- break;// entry found
- }
- pc_setreg(sd, add_str("@menu"), menu);
- script_pushint(st, menu);
- st->state = RUN;
- }
- return 0;
+ int i;
+ const char *text;
+ TBL_PC* sd;
+
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
+
+ if( sd->state.menu_or_input == 0 )
+ {
+ struct StringBuf buf;
+
+ StringBuf_Init(&buf);
+ sd->npc_menu = 0;
+ for( i = 2; i <= script_lastdata(st); ++i )
+ {
+ text = script_getstr(st, i);
+ if( sd->npc_menu > 0 )
+ StringBuf_AppendStr(&buf, ":");
+ StringBuf_AppendStr(&buf, text);
+ sd->npc_menu += menu_countoptions(text, 0, NULL);
+ }
+
+ st->state = RERUNLINE;
+ sd->state.menu_or_input = 1;
+
+ /**
+ * menus beyond this length crash the client (see bugreport:6402)
+ **/
+ if( StringBuf_Length(&buf) >= 2047 ) {
+ struct npc_data * nd = map_id2nd(st->oid);
+ char* menu;
+ CREATE(menu, char, 2048);
+ safestrncpy(menu, StringBuf_Value(&buf), 2047);
+ ShowWarning("NPC Menu too long! (source:%s / length:%d)\n",nd?nd->name:"Unknown",StringBuf_Length(&buf));
+ clif_scriptmenu(sd, st->oid, menu);
+ aFree(menu);
+ } else
+ clif_scriptmenu(sd, st->oid, StringBuf_Value(&buf));
+ StringBuf_Destroy(&buf);
+
+ if( sd->npc_menu >= 0xff )
+ {
+ ShowWarning("buildin_prompt: Too many options specified (current=%d, max=254).\n", sd->npc_menu);
+ script_reportsrc(st);
+ }
+ }
+ else if( sd->npc_menu == 0xff )
+ {// Cancel was pressed
+ sd->state.menu_or_input = 0;
+ pc_setreg(sd, add_str("@menu"), 0xff);
+ script_pushint(st, 0xff);
+ st->state = RUN;
+ }
+ else
+ {// return selected option
+ int menu = 0;
+
+ sd->state.menu_or_input = 0;
+ for( i = 2; i <= script_lastdata(st); ++i )
+ {
+ text = script_getstr(st, i);
+ sd->npc_menu -= menu_countoptions(text, sd->npc_menu, &menu);
+ if( sd->npc_menu <= 0 )
+ break;// entry found
+ }
+ pc_setreg(sd, add_str("@menu"), menu);
+ script_pushint(st, menu);
+ st->state = RUN;
+ }
+ return 0;
}
/////////////////////////////////////////////////////////////////////
@@ -4673,16 +4753,17 @@ BUILDIN_FUNC(prompt)
/// goto <label>;
BUILDIN_FUNC(goto)
{
- if (!data_islabel(script_getdata(st,2))) {
- ShowError("script:goto: not a label\n");
- script_reportdata(script_getdata(st,2));
- st->state = END;
- return 1;
- }
+ if( !data_islabel(script_getdata(st,2)) )
+ {
+ ShowError("script:goto: not a label\n");
+ script_reportdata(script_getdata(st,2));
+ st->state = END;
+ return 1;
+ }
- st->pos = script_getnum(st,2);
- st->state = GOTO;
- return 0;
+ st->pos = script_getnum(st,2);
+ st->state = GOTO;
+ return 0;
}
/*==========================================
@@ -4690,94 +4771,100 @@ BUILDIN_FUNC(goto)
*------------------------------------------*/
BUILDIN_FUNC(callfunc)
{
- int i, j;
- struct script_retinfo *ri;
- struct script_code *scr;
- const char *str = script_getstr(st,2);
- DBMap **ref = NULL;
-
- scr = (struct script_code *)strdb_get(userfunc_db, str);
- if (!scr) {
- ShowError("script:callfunc: function not found! [%s]\n", str);
- st->state = END;
- return 1;
- }
-
- for (i = st->start+3, j = 0; i < st->end; i++, j++) {
- struct script_data *data = push_copy(st->stack,i);
- if (data_isreference(data) && !data->ref) {
- const char *name = reference_getname(data);
- if (name[0] == '.') {
- if (!ref) {
- ref = (struct DBMap **)aCalloc(sizeof(struct DBMap *), 1);
- ref[0] = (name[1] == '@' ? st->stack->var_function : st->script->script_vars);
- }
- data->ref = ref;
- }
- }
- }
-
- CREATE(ri, struct script_retinfo, 1);
- ri->script = st->script;// script code
- ri->var_function = st->stack->var_function;// scope variables
- ri->pos = st->pos;// script location
- ri->nargs = j;// argument count
- ri->defsp = st->stack->defsp;// default stack pointer
- push_retinfo(st->stack, ri, ref);
-
- st->pos = 0;
- st->script = scr;
- st->stack->defsp = st->stack->sp;
- st->state = GOTO;
- st->stack->var_function = idb_alloc(DB_OPT_RELEASE_DATA);
-
- return 0;
+ int i, j;
+ struct script_retinfo* ri;
+ struct script_code* scr;
+ const char* str = script_getstr(st,2);
+ DBMap **ref = NULL;
+
+ scr = (struct script_code*)strdb_get(userfunc_db, str);
+ if( !scr )
+ {
+ ShowError("script:callfunc: function not found! [%s]\n", str);
+ st->state = END;
+ return 1;
+ }
+
+ for( i = st->start+3, j = 0; i < st->end; i++, j++ )
+ {
+ struct script_data* data = push_copy(st->stack,i);
+ if( data_isreference(data) && !data->ref )
+ {
+ const char* name = reference_getname(data);
+ if( name[0] == '.' ) {
+ if ( !ref ) {
+ ref = (struct DBMap**)aCalloc(sizeof(struct DBMap*), 1);
+ ref[0] = (name[1] == '@' ? st->stack->var_function : st->script->script_vars);
+ }
+ data->ref = ref;
+ }
+ }
+ }
+
+ CREATE(ri, struct script_retinfo, 1);
+ ri->script = st->script;// script code
+ ri->var_function = st->stack->var_function;// scope variables
+ ri->pos = st->pos;// script location
+ ri->nargs = j;// argument count
+ ri->defsp = st->stack->defsp;// default stack pointer
+ push_retinfo(st->stack, ri, ref);
+
+ st->pos = 0;
+ st->script = scr;
+ st->stack->defsp = st->stack->sp;
+ st->state = GOTO;
+ st->stack->var_function = idb_alloc(DB_OPT_RELEASE_DATA);
+
+ return 0;
}
/*==========================================
* subroutine call
*------------------------------------------*/
BUILDIN_FUNC(callsub)
{
- int i,j;
- struct script_retinfo *ri;
- int pos = script_getnum(st,2);
- DBMap **ref = NULL;
-
- if (!data_islabel(script_getdata(st,2)) && !data_isfunclabel(script_getdata(st,2))) {
- ShowError("script:callsub: argument is not a label\n");
- script_reportdata(script_getdata(st,2));
- st->state = END;
- return 1;
- }
-
- for (i = st->start+3, j = 0; i < st->end; i++, j++) {
- struct script_data *data = push_copy(st->stack,i);
- if (data_isreference(data) && !data->ref) {
- const char *name = reference_getname(data);
- if (name[0] == '.' && name[1] == '@') {
- if (!ref) {
- ref = (struct DBMap **)aCalloc(sizeof(struct DBMap *), 1);
- ref[0] = st->stack->var_function;
- }
- data->ref = ref;
- }
- }
- }
-
- CREATE(ri, struct script_retinfo, 1);
- ri->script = st->script;// script code
- ri->var_function = st->stack->var_function;// scope variables
- ri->pos = st->pos;// script location
- ri->nargs = j;// argument count
- ri->defsp = st->stack->defsp;// default stack pointer
- push_retinfo(st->stack, ri, ref);
-
- st->pos = pos;
- st->stack->defsp = st->stack->sp;
- st->state = GOTO;
- st->stack->var_function = idb_alloc(DB_OPT_RELEASE_DATA);
-
- return 0;
+ int i,j;
+ struct script_retinfo* ri;
+ int pos = script_getnum(st,2);
+ DBMap **ref = NULL;
+
+ if( !data_islabel(script_getdata(st,2)) && !data_isfunclabel(script_getdata(st,2)) )
+ {
+ ShowError("script:callsub: argument is not a label\n");
+ script_reportdata(script_getdata(st,2));
+ st->state = END;
+ return 1;
+ }
+
+ for( i = st->start+3, j = 0; i < st->end; i++, j++ )
+ {
+ struct script_data* data = push_copy(st->stack,i);
+ if( data_isreference(data) && !data->ref )
+ {
+ const char* name = reference_getname(data);
+ if( name[0] == '.' && name[1] == '@' ) {
+ if ( !ref ) {
+ ref = (struct DBMap**)aCalloc(sizeof(struct DBMap*), 1);
+ ref[0] = st->stack->var_function;
+ }
+ data->ref = ref;
+ }
+ }
+ }
+
+ CREATE(ri, struct script_retinfo, 1);
+ ri->script = st->script;// script code
+ ri->var_function = st->stack->var_function;// scope variables
+ ri->pos = st->pos;// script location
+ ri->nargs = j;// argument count
+ ri->defsp = st->stack->defsp;// default stack pointer
+ push_retinfo(st->stack, ri, ref);
+
+ st->pos = pos;
+ st->stack->defsp = st->stack->sp;
+ st->state = GOTO;
+ st->stack->var_function = idb_alloc(DB_OPT_RELEASE_DATA);
+
+ return 0;
}
/// Retrieves an argument provided to callfunc/callsub.
@@ -4786,29 +4873,31 @@ BUILDIN_FUNC(callsub)
/// getarg(<index>{,<default_value>}) -> <value>
BUILDIN_FUNC(getarg)
{
- struct script_retinfo *ri;
- int idx;
+ struct script_retinfo* ri;
+ int idx;
- if (st->stack->defsp < 1 || st->stack->stack_data[st->stack->defsp - 1].type != C_RETINFO) {
- ShowError("script:getarg: no callfunc or callsub!\n");
- st->state = END;
- return 1;
- }
- ri = st->stack->stack_data[st->stack->defsp - 1].u.ri;
-
- idx = script_getnum(st,2);
-
- if (idx >= 0 && idx < ri->nargs)
- push_copy(st->stack, st->stack->defsp - 1 - ri->nargs + idx);
- else if (script_hasdata(st,3))
- script_pushcopy(st, 3);
- else {
- ShowError("script:getarg: index (idx=%d) out of range (nargs=%d) and no default value found\n", idx, ri->nargs);
- st->state = END;
- return 1;
- }
+ if( st->stack->defsp < 1 || st->stack->stack_data[st->stack->defsp - 1].type != C_RETINFO )
+ {
+ ShowError("script:getarg: no callfunc or callsub!\n");
+ st->state = END;
+ return 1;
+ }
+ ri = st->stack->stack_data[st->stack->defsp - 1].u.ri;
- return 0;
+ idx = script_getnum(st,2);
+
+ if( idx >= 0 && idx < ri->nargs )
+ push_copy(st->stack, st->stack->defsp - 1 - ri->nargs + idx);
+ else if( script_hasdata(st,3) )
+ script_pushcopy(st, 3);
+ else
+ {
+ ShowError("script:getarg: index (idx=%d) out of range (nargs=%d) and no default value found\n", idx, ri->nargs);
+ st->state = END;
+ return 1;
+ }
+
+ return 0;
}
/// Returns from the current function, optionaly returning a value from the functions.
@@ -4818,28 +4907,31 @@ BUILDIN_FUNC(getarg)
/// return <value>;
BUILDIN_FUNC(return)
{
- if (script_hasdata(st,2)) {
- // return value
- struct script_data *data;
- script_pushcopy(st, 2);
- data = script_getdatatop(st, -1);
- if (data_isreference(data)) {
- const char *name = reference_getname(data);
- if (name[0] == '.' && name[1] == '@') {
- // scope variable
- if (!data->ref || data->ref == (DBMap **)&st->stack->var_function)
- get_val(st, data);// current scope, convert to value
- } else if (name[0] == '.' && !data->ref) {
- // script variable, link to current script
- data->ref = &st->script->script_vars;
- }
- }
- } else {
- // no return value
- script_pushnil(st);
- }
- st->state = RETFUNC;
- return 0;
+ if( script_hasdata(st,2) )
+ {// return value
+ struct script_data* data;
+ script_pushcopy(st, 2);
+ data = script_getdatatop(st, -1);
+ if( data_isreference(data) )
+ {
+ const char* name = reference_getname(data);
+ if( name[0] == '.' && name[1] == '@' )
+ {// scope variable
+ if( !data->ref || data->ref == (DBMap**)&st->stack->var_function )
+ get_val(st, data);// current scope, convert to value
+ }
+ else if( name[0] == '.' && !data->ref )
+ {// script variable, link to current script
+ data->ref = &st->script->script_vars;
+ }
+ }
+ }
+ else
+ {// no return value
+ script_pushnil(st);
+ }
+ st->state = RETFUNC;
+ return 0;
}
/// Returns a random number from 0 to <range>-1.
@@ -4849,28 +4941,29 @@ BUILDIN_FUNC(return)
/// rand(<min>,<max>) -> <int>
BUILDIN_FUNC(rand)
{
- int range;
- int min;
- int max;
-
- if (script_hasdata(st,3)) {
- // min,max
- min = script_getnum(st,2);
- max = script_getnum(st,3);
- if (max < min)
- swap(min, max);
- range = max - min + 1;
- } else {
- // range
- min = 0;
- range = script_getnum(st,2);
- }
- if (range <= 1)
- script_pushint(st, min);
- else
- script_pushint(st, rnd()%range + min);
-
- return 0;
+ int range;
+ int min;
+ int max;
+
+ if( script_hasdata(st,3) )
+ {// min,max
+ min = script_getnum(st,2);
+ max = script_getnum(st,3);
+ if( max < min )
+ swap(min, max);
+ range = max - min + 1;
+ }
+ else
+ {// range
+ min = 0;
+ range = script_getnum(st,2);
+ }
+ if( range <= 1 )
+ script_pushint(st, min);
+ else
+ script_pushint(st, rnd()%range + min);
+
+ return 0;
}
/*==========================================
@@ -4878,105 +4971,106 @@ BUILDIN_FUNC(rand)
*------------------------------------------*/
BUILDIN_FUNC(warp)
{
- int ret;
- int x,y;
- const char *str;
- TBL_PC *sd;
+ int ret;
+ int x,y;
+ const char* str;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- str = script_getstr(st,2);
- x = script_getnum(st,3);
- y = script_getnum(st,4);
+ str = script_getstr(st,2);
+ x = script_getnum(st,3);
+ y = script_getnum(st,4);
- if (strcmp(str,"Random")==0)
- ret = pc_randomwarp(sd,CLR_TELEPORT);
- else if (strcmp(str,"SavePoint")==0 || strcmp(str,"Save")==0)
- ret = pc_setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT);
- else
- ret = pc_setpos(sd,mapindex_name2id(str),x,y,CLR_OUTSIGHT);
+ if(strcmp(str,"Random")==0)
+ ret = pc_randomwarp(sd,CLR_TELEPORT);
+ else if(strcmp(str,"SavePoint")==0 || strcmp(str,"Save")==0)
+ ret = pc_setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT);
+ else
+ ret = pc_setpos(sd,mapindex_name2id(str),x,y,CLR_OUTSIGHT);
- if (ret) {
- ShowError("buildin_warp: moving player '%s' to \"%s\",%d,%d failed.\n", sd->status.name, str, x, y);
- script_reportsrc(st);
- }
+ if( ret ) {
+ ShowError("buildin_warp: moving player '%s' to \"%s\",%d,%d failed.\n", sd->status.name, str, x, y);
+ script_reportsrc(st);
+ }
- return 0;
+ return 0;
}
/*==========================================
* Warp a specified area
*------------------------------------------*/
static int buildin_areawarp_sub(struct block_list *bl,va_list ap)
{
- int x2,y2,x3,y3;
- unsigned int index;
-
- index = va_arg(ap,unsigned int);
- x2 = va_arg(ap,int);
- y2 = va_arg(ap,int);
- x3 = va_arg(ap,int);
- y3 = va_arg(ap,int);
-
- if (index == 0)
- pc_randomwarp((TBL_PC *)bl,CLR_TELEPORT);
- else if (x3 && y3) {
- int max, tx, ty, j = 0;
-
- // choose a suitable max number of attempts
- if ((max = (y3-y2+1)*(x3-x2+1)*3) > 1000)
- max = 1000;
-
- // find a suitable map cell
- do {
- tx = rnd()%(x3-x2+1)+x2;
- ty = rnd()%(y3-y2+1)+y2;
- j++;
- } while (map_getcell(index,tx,ty,CELL_CHKNOPASS) && j < max);
-
- pc_setpos((TBL_PC *)bl,index,tx,ty,CLR_OUTSIGHT);
- } else
- pc_setpos((TBL_PC *)bl,index,x2,y2,CLR_OUTSIGHT);
- return 0;
+ int x2,y2,x3,y3;
+ unsigned int index;
+
+ index = va_arg(ap,unsigned int);
+ x2 = va_arg(ap,int);
+ y2 = va_arg(ap,int);
+ x3 = va_arg(ap,int);
+ y3 = va_arg(ap,int);
+
+ if(index == 0)
+ pc_randomwarp((TBL_PC *)bl,CLR_TELEPORT);
+ else if(x3 && y3) {
+ int max, tx, ty, j = 0;
+
+ // choose a suitable max number of attempts
+ if( (max = (y3-y2+1)*(x3-x2+1)*3) > 1000 )
+ max = 1000;
+
+ // find a suitable map cell
+ do {
+ tx = rnd()%(x3-x2+1)+x2;
+ ty = rnd()%(y3-y2+1)+y2;
+ j++;
+ } while( map_getcell(index,tx,ty,CELL_CHKNOPASS) && j < max );
+
+ pc_setpos((TBL_PC *)bl,index,tx,ty,CLR_OUTSIGHT);
+ }
+ else
+ pc_setpos((TBL_PC *)bl,index,x2,y2,CLR_OUTSIGHT);
+ return 0;
}
BUILDIN_FUNC(areawarp)
{
- int m, x0,y0,x1,y1, x2,y2,x3=0,y3=0;
- unsigned int index;
- const char *str;
- const char *mapname;
-
- mapname = script_getstr(st,2);
- x0 = script_getnum(st,3);
- y0 = script_getnum(st,4);
- x1 = script_getnum(st,5);
- y1 = script_getnum(st,6);
- str = script_getstr(st,7);
- x2 = script_getnum(st,8);
- y2 = script_getnum(st,9);
-
- if (script_hasdata(st,10) && script_hasdata(st,11)) { // Warp area to area
- if ((x3 = script_getnum(st,10)) < 0 || (y3 = script_getnum(st,11)) < 0) {
- x3 = 0;
- y3 = 0;
- } else if (x3 && y3) {
- // normalize x3/y3 coordinates
- if (x3 < x2) swap(x3,x2);
- if (y3 < y2) swap(y3,y2);
- }
- }
-
- if ((m = map_mapname2mapid(mapname)) < 0)
- return 0;
-
- if (strcmp(str,"Random") == 0)
- index = 0;
- else if (!(index=mapindex_name2id(str)))
- return 0;
-
- map_foreachinarea(buildin_areawarp_sub, m,x0,y0,x1,y1, BL_PC, index,x2,y2,x3,y3);
- return 0;
+ int m, x0,y0,x1,y1, x2,y2,x3=0,y3=0;
+ unsigned int index;
+ const char *str;
+ const char *mapname;
+
+ mapname = script_getstr(st,2);
+ x0 = script_getnum(st,3);
+ y0 = script_getnum(st,4);
+ x1 = script_getnum(st,5);
+ y1 = script_getnum(st,6);
+ str = script_getstr(st,7);
+ x2 = script_getnum(st,8);
+ y2 = script_getnum(st,9);
+
+ if( script_hasdata(st,10) && script_hasdata(st,11) ) { // Warp area to area
+ if( (x3 = script_getnum(st,10)) < 0 || (y3 = script_getnum(st,11)) < 0 ){
+ x3 = 0;
+ y3 = 0;
+ } else if( x3 && y3 ) {
+ // normalize x3/y3 coordinates
+ if( x3 < x2 ) swap(x3,x2);
+ if( y3 < y2 ) swap(y3,y2);
+ }
+ }
+
+ if( (m = map_mapname2mapid(mapname)) < 0 )
+ return 0;
+
+ if( strcmp(str,"Random") == 0 )
+ index = 0;
+ else if( !(index=mapindex_name2id(str)) )
+ return 0;
+
+ map_foreachinarea(buildin_areawarp_sub, m,x0,y0,x1,y1, BL_PC, index,x2,y2,x3,y3);
+ return 0;
}
/*==========================================
@@ -4984,31 +5078,31 @@ BUILDIN_FUNC(areawarp)
*------------------------------------------*/
static int buildin_areapercentheal_sub(struct block_list *bl,va_list ap)
{
- int hp, sp;
- hp = va_arg(ap, int);
- sp = va_arg(ap, int);
- pc_percentheal((TBL_PC *)bl,hp,sp);
- return 0;
+ int hp, sp;
+ hp = va_arg(ap, int);
+ sp = va_arg(ap, int);
+ pc_percentheal((TBL_PC *)bl,hp,sp);
+ return 0;
}
BUILDIN_FUNC(areapercentheal)
{
- int hp,sp,m;
- const char *mapname;
- int x0,y0,x1,y1;
+ int hp,sp,m;
+ const char *mapname;
+ int x0,y0,x1,y1;
- mapname=script_getstr(st,2);
- x0=script_getnum(st,3);
- y0=script_getnum(st,4);
- x1=script_getnum(st,5);
- y1=script_getnum(st,6);
- hp=script_getnum(st,7);
- sp=script_getnum(st,8);
+ mapname=script_getstr(st,2);
+ x0=script_getnum(st,3);
+ y0=script_getnum(st,4);
+ x1=script_getnum(st,5);
+ y1=script_getnum(st,6);
+ hp=script_getnum(st,7);
+ sp=script_getnum(st,8);
- if ((m=map_mapname2mapid(mapname))< 0)
- return 0;
+ if( (m=map_mapname2mapid(mapname))< 0)
+ return 0;
- map_foreachinarea(buildin_areapercentheal_sub,m,x0,y0,x1,y1,BL_PC,hp,sp);
- return 0;
+ map_foreachinarea(buildin_areapercentheal_sub,m,x0,y0,x1,y1,BL_PC,hp,sp);
+ return 0;
}
/*==========================================
@@ -5019,27 +5113,28 @@ BUILDIN_FUNC(areapercentheal)
*------------------------------------------*/
BUILDIN_FUNC(warpchar)
{
- int x,y,a;
- const char *str;
- TBL_PC *sd;
+ int x,y,a;
+ const char *str;
+ TBL_PC *sd;
- str=script_getstr(st,2);
- x=script_getnum(st,3);
- y=script_getnum(st,4);
- a=script_getnum(st,5);
+ str=script_getstr(st,2);
+ x=script_getnum(st,3);
+ y=script_getnum(st,4);
+ a=script_getnum(st,5);
- sd = map_charid2sd(a);
- if (sd == NULL)
- return 0;
+ sd = map_charid2sd(a);
+ if( sd == NULL )
+ return 0;
- if (strcmp(str, "Random") == 0)
- pc_randomwarp(sd, CLR_TELEPORT);
- else if (strcmp(str, "SavePoint") == 0)
- pc_setpos(sd, sd->status.save_point.map,sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT);
- else
- pc_setpos(sd, mapindex_name2id(str), x, y, CLR_TELEPORT);
+ if(strcmp(str, "Random") == 0)
+ pc_randomwarp(sd, CLR_TELEPORT);
+ else
+ if(strcmp(str, "SavePoint") == 0)
+ pc_setpos(sd, sd->status.save_point.map,sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT);
+ else
+ pc_setpos(sd, mapindex_name2id(str), x, y, CLR_TELEPORT);
- return 0;
+ return 0;
}
/*==========================================
* Warpparty - [Fredzilla] [Paradox924X]
@@ -5048,85 +5143,88 @@ BUILDIN_FUNC(warpchar)
*------------------------------------------*/
BUILDIN_FUNC(warpparty)
{
- TBL_PC *sd = NULL;
- TBL_PC *pl_sd;
- struct party_data *p;
- int type;
- int mapindex;
- int i;
-
- const char *str = script_getstr(st,2);
- int x = script_getnum(st,3);
- int y = script_getnum(st,4);
- int p_id = script_getnum(st,5);
- const char *str2 = NULL;
- if (script_hasdata(st,6))
- str2 = script_getstr(st,6);
-
- p = party_search(p_id);
- if (!p)
- return 0;
-
- type = (strcmp(str,"Random")==0) ? 0
- : (strcmp(str,"SavePointAll")==0) ? 1
- : (strcmp(str,"SavePoint")==0) ? 2
- : (strcmp(str,"Leader")==0) ? 3
- : 4;
-
- switch (type) {
- case 3:
- for (i = 0; i < MAX_PARTY && !p->party.member[i].leader; i++);
- if (i == MAX_PARTY || !p->data[i].sd) //Leader not found / not online
- return 0;
- pl_sd = p->data[i].sd;
- mapindex = pl_sd->mapindex;
- x = pl_sd->bl.x;
- y = pl_sd->bl.y;
- break;
- case 4:
- mapindex = mapindex_name2id(str);
- break;
- case 2:
- //"SavePoint" uses save point of the currently attached player
- if ((sd = script_rid2sd(st)) == NULL)
- return 0;
- default:
- mapindex = 0;
- break;
- }
-
- for (i = 0; i < MAX_PARTY; i++) {
- if (!(pl_sd = p->data[i].sd) || pl_sd->status.party_id != p_id)
- continue;
-
- if (str2 && strcmp(str2, map[pl_sd->bl.m].name) != 0)
- continue;
-
- if (pc_isdead(pl_sd))
- continue;
-
- switch (type) {
- case 0: // Random
- if (!map[pl_sd->bl.m].flag.nowarp)
- pc_randomwarp(pl_sd,CLR_TELEPORT);
- break;
- case 1: // SavePointAll
- if (!map[pl_sd->bl.m].flag.noreturn)
- pc_setpos(pl_sd,pl_sd->status.save_point.map,pl_sd->status.save_point.x,pl_sd->status.save_point.y,CLR_TELEPORT);
- break;
- case 2: // SavePoint
- if (!map[pl_sd->bl.m].flag.noreturn)
- pc_setpos(pl_sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT);
- break;
- case 3: // Leader
- case 4: // m,x,y
- if (!map[pl_sd->bl.m].flag.noreturn && !map[pl_sd->bl.m].flag.nowarp)
- pc_setpos(pl_sd,mapindex,x,y,CLR_TELEPORT);
- break;
- }
- }
-
- return 0;
+ TBL_PC *sd = NULL;
+ TBL_PC *pl_sd;
+ struct party_data* p;
+ int type;
+ int mapindex;
+ int i;
+
+ const char* str = script_getstr(st,2);
+ int x = script_getnum(st,3);
+ int y = script_getnum(st,4);
+ int p_id = script_getnum(st,5);
+ const char* str2 = NULL;
+ if ( script_hasdata(st,6) )
+ str2 = script_getstr(st,6);
+
+ p = party_search(p_id);
+ if(!p)
+ return 0;
+
+ type = ( strcmp(str,"Random")==0 ) ? 0
+ : ( strcmp(str,"SavePointAll")==0 ) ? 1
+ : ( strcmp(str,"SavePoint")==0 ) ? 2
+ : ( strcmp(str,"Leader")==0 ) ? 3
+ : 4;
+
+ switch (type)
+ {
+ case 3:
+ for(i = 0; i < MAX_PARTY && !p->party.member[i].leader; i++);
+ if (i == MAX_PARTY || !p->data[i].sd) //Leader not found / not online
+ return 0;
+ pl_sd = p->data[i].sd;
+ mapindex = pl_sd->mapindex;
+ x = pl_sd->bl.x;
+ y = pl_sd->bl.y;
+ break;
+ case 4:
+ mapindex = mapindex_name2id(str);
+ break;
+ case 2:
+ //"SavePoint" uses save point of the currently attached player
+ if (( sd = script_rid2sd(st) ) == NULL )
+ return 0;
+ default:
+ mapindex = 0;
+ break;
+ }
+
+ for (i = 0; i < MAX_PARTY; i++)
+ {
+ if( !(pl_sd = p->data[i].sd) || pl_sd->status.party_id != p_id )
+ continue;
+
+ if( str2 && strcmp(str2, map[pl_sd->bl.m].name) != 0 )
+ continue;
+
+ if( pc_isdead(pl_sd) )
+ continue;
+
+ switch( type )
+ {
+ case 0: // Random
+ if(!map[pl_sd->bl.m].flag.nowarp)
+ pc_randomwarp(pl_sd,CLR_TELEPORT);
+ break;
+ case 1: // SavePointAll
+ if(!map[pl_sd->bl.m].flag.noreturn)
+ pc_setpos(pl_sd,pl_sd->status.save_point.map,pl_sd->status.save_point.x,pl_sd->status.save_point.y,CLR_TELEPORT);
+ break;
+ case 2: // SavePoint
+ if(!map[pl_sd->bl.m].flag.noreturn)
+ pc_setpos(pl_sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT);
+ break;
+ case 3: // Leader
+ case 4: // m,x,y
+ if(!map[pl_sd->bl.m].flag.noreturn && !map[pl_sd->bl.m].flag.nowarp)
+ pc_setpos(pl_sd,mapindex,x,y,CLR_TELEPORT);
+ break;
+ }
+ }
+
+ return 0;
}
/*==========================================
* Warpguild - [Fredzilla]
@@ -5134,123 +5232,125 @@ BUILDIN_FUNC(warpparty)
*------------------------------------------*/
BUILDIN_FUNC(warpguild)
{
- TBL_PC *sd = NULL;
- TBL_PC *pl_sd;
- struct guild *g;
- struct s_mapiterator *iter;
- int type;
-
- const char *str = script_getstr(st,2);
- int x = script_getnum(st,3);
- int y = script_getnum(st,4);
- int gid = script_getnum(st,5);
-
- g = guild_search(gid);
- if (g == NULL)
- return 0;
-
- type = (strcmp(str,"Random")==0) ? 0
- : (strcmp(str,"SavePointAll")==0) ? 1
- : (strcmp(str,"SavePoint")==0) ? 2
- : 3;
-
- if (type == 2 && (sd = script_rid2sd(st)) == NULL) {
- // "SavePoint" uses save point of the currently attached player
- return 0;
- }
-
- iter = mapit_getallusers();
- for (pl_sd = (TBL_PC *)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC *)mapit_next(iter)) {
- if (pl_sd->status.guild_id != gid)
- continue;
-
- switch (type) {
- case 0: // Random
- if (!map[pl_sd->bl.m].flag.nowarp)
- pc_randomwarp(pl_sd,CLR_TELEPORT);
- break;
- case 1: // SavePointAll
- if (!map[pl_sd->bl.m].flag.noreturn)
- pc_setpos(pl_sd,pl_sd->status.save_point.map,pl_sd->status.save_point.x,pl_sd->status.save_point.y,CLR_TELEPORT);
- break;
- case 2: // SavePoint
- if (!map[pl_sd->bl.m].flag.noreturn)
- pc_setpos(pl_sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT);
- break;
- case 3: // m,x,y
- if (!map[pl_sd->bl.m].flag.noreturn && !map[pl_sd->bl.m].flag.nowarp)
- pc_setpos(pl_sd,mapindex_name2id(str),x,y,CLR_TELEPORT);
- break;
- }
- }
- mapit_free(iter);
-
- return 0;
+ TBL_PC *sd = NULL;
+ TBL_PC *pl_sd;
+ struct guild* g;
+ struct s_mapiterator* iter;
+ int type;
+
+ const char* str = script_getstr(st,2);
+ int x = script_getnum(st,3);
+ int y = script_getnum(st,4);
+ int gid = script_getnum(st,5);
+
+ g = guild_search(gid);
+ if( g == NULL )
+ return 0;
+
+ type = ( strcmp(str,"Random")==0 ) ? 0
+ : ( strcmp(str,"SavePointAll")==0 ) ? 1
+ : ( strcmp(str,"SavePoint")==0 ) ? 2
+ : 3;
+
+ if( type == 2 && ( sd = script_rid2sd(st) ) == NULL )
+ {// "SavePoint" uses save point of the currently attached player
+ return 0;
+ }
+
+ iter = mapit_getallusers();
+ for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
+ {
+ if( pl_sd->status.guild_id != gid )
+ continue;
+
+ switch( type )
+ {
+ case 0: // Random
+ if(!map[pl_sd->bl.m].flag.nowarp)
+ pc_randomwarp(pl_sd,CLR_TELEPORT);
+ break;
+ case 1: // SavePointAll
+ if(!map[pl_sd->bl.m].flag.noreturn)
+ pc_setpos(pl_sd,pl_sd->status.save_point.map,pl_sd->status.save_point.x,pl_sd->status.save_point.y,CLR_TELEPORT);
+ break;
+ case 2: // SavePoint
+ if(!map[pl_sd->bl.m].flag.noreturn)
+ pc_setpos(pl_sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT);
+ break;
+ case 3: // m,x,y
+ if(!map[pl_sd->bl.m].flag.noreturn && !map[pl_sd->bl.m].flag.nowarp)
+ pc_setpos(pl_sd,mapindex_name2id(str),x,y,CLR_TELEPORT);
+ break;
+ }
+ }
+ mapit_free(iter);
+
+ return 0;
}
/*==========================================
* Force Heal a player (hp and sp)
*------------------------------------------*/
BUILDIN_FUNC(heal)
{
- TBL_PC *sd;
- int hp,sp;
+ TBL_PC *sd;
+ int hp,sp;
- sd = script_rid2sd(st);
- if (!sd) return 0;
+ sd = script_rid2sd(st);
+ if (!sd) return 0;
- hp=script_getnum(st,2);
- sp=script_getnum(st,3);
- status_heal(&sd->bl, hp, sp, 1);
- return 0;
+ hp=script_getnum(st,2);
+ sp=script_getnum(st,3);
+ status_heal(&sd->bl, hp, sp, 1);
+ return 0;
}
/*==========================================
* Heal a player by item (get vit bonus etc)
*------------------------------------------*/
BUILDIN_FUNC(itemheal)
{
- TBL_PC *sd;
- int hp,sp;
+ TBL_PC *sd;
+ int hp,sp;
- hp=script_getnum(st,2);
- sp=script_getnum(st,3);
+ hp=script_getnum(st,2);
+ sp=script_getnum(st,3);
- if (potion_flag==1) {
- potion_hp = hp;
- potion_sp = sp;
- return 0;
- }
+ if(potion_flag==1) {
+ potion_hp = hp;
+ potion_sp = sp;
+ return 0;
+ }
- sd = script_rid2sd(st);
- if (!sd) return 0;
- pc_itemheal(sd,sd->itemid,hp,sp);
- return 0;
+ sd = script_rid2sd(st);
+ if (!sd) return 0;
+ pc_itemheal(sd,sd->itemid,hp,sp);
+ return 0;
}
/*==========================================
*
*------------------------------------------*/
BUILDIN_FUNC(percentheal)
{
- int hp,sp;
- TBL_PC *sd;
+ int hp,sp;
+ TBL_PC* sd;
- hp=script_getnum(st,2);
- sp=script_getnum(st,3);
+ hp=script_getnum(st,2);
+ sp=script_getnum(st,3);
- if (potion_flag==1) {
- potion_per_hp = hp;
- potion_per_sp = sp;
- return 0;
- }
+ if(potion_flag==1) {
+ potion_per_hp = hp;
+ potion_per_sp = sp;
+ return 0;
+ }
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
#ifdef RENEWAL
- if (sd->sc.data[SC_EXTREMITYFIST2])
- sp = 0;
+ if( sd->sc.data[SC_EXTREMITYFIST2] )
+ sp = 0;
#endif
- pc_percentheal(sd,hp,sp);
- return 0;
+ pc_percentheal(sd,hp,sp);
+ return 0;
}
/*==========================================
@@ -5258,23 +5358,24 @@ BUILDIN_FUNC(percentheal)
*------------------------------------------*/
BUILDIN_FUNC(jobchange)
{
- int job, upper=-1;
+ int job, upper=-1;
- job=script_getnum(st,2);
- if (script_hasdata(st,3))
- upper=script_getnum(st,3);
+ job=script_getnum(st,2);
+ if( script_hasdata(st,3) )
+ upper=script_getnum(st,3);
- if (pcdb_checkid(job)) {
- TBL_PC *sd;
+ if (pcdb_checkid(job))
+ {
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- pc_jobchange(sd, job, upper);
- }
+ pc_jobchange(sd, job, upper);
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -5282,9 +5383,9 @@ BUILDIN_FUNC(jobchange)
*------------------------------------------*/
BUILDIN_FUNC(jobname)
{
- int class_=script_getnum(st,2);
- script_pushconststr(st, (char *)job_name(class_));
- return 0;
+ int class_=script_getnum(st,2);
+ script_pushconststr(st, (char*)job_name(class_));
+ return 0;
}
/// Get input from the player.
@@ -5296,52 +5397,56 @@ BUILDIN_FUNC(jobname)
/// input(<var>{,<min>{,<max>}}) -> <int>
BUILDIN_FUNC(input)
{
- TBL_PC *sd;
- struct script_data *data;
- int uid;
- const char *name;
- int min;
- int max;
-
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
-
- data = script_getdata(st,2);
- if (!data_isreference(data)) {
- ShowError("script:input: not a variable\n");
- script_reportdata(data);
- st->state = END;
- return 1;
- }
- uid = reference_getuid(data);
- name = reference_getname(data);
- min = (script_hasdata(st,3) ? script_getnum(st,3) : script_config.input_min_value);
- max = (script_hasdata(st,4) ? script_getnum(st,4) : script_config.input_max_value);
-
- if (!sd->state.menu_or_input) {
- // first invocation, display npc input box
- sd->state.menu_or_input = 1;
- st->state = RERUNLINE;
- if (is_string_variable(name))
- clif_scriptinputstr(sd,st->oid);
- else
- clif_scriptinput(sd,st->oid);
- } else {
- // take received text/value and store it in the designated variable
- sd->state.menu_or_input = 0;
- if (is_string_variable(name)) {
- int len = (int)strlen(sd->npc_str);
- set_reg(st, sd, uid, name, (void *)sd->npc_str, script_getref(st,2));
- script_pushint(st, (len > max ? 1 : len < min ? -1 : 0));
- } else {
- int amount = sd->npc_amount;
- set_reg(st, sd, uid, name, (void *)__64BPRTSIZE(cap_value(amount,min,max)), script_getref(st,2));
- script_pushint(st, (amount > max ? 1 : amount < min ? -1 : 0));
- }
- st->state = RUN;
- }
- return 0;
+ TBL_PC* sd;
+ struct script_data* data;
+ int uid;
+ const char* name;
+ int min;
+ int max;
+
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
+
+ data = script_getdata(st,2);
+ if( !data_isreference(data) ){
+ ShowError("script:input: not a variable\n");
+ script_reportdata(data);
+ st->state = END;
+ return 1;
+ }
+ uid = reference_getuid(data);
+ name = reference_getname(data);
+ min = (script_hasdata(st,3) ? script_getnum(st,3) : script_config.input_min_value);
+ max = (script_hasdata(st,4) ? script_getnum(st,4) : script_config.input_max_value);
+
+ if( !sd->state.menu_or_input )
+ { // first invocation, display npc input box
+ sd->state.menu_or_input = 1;
+ st->state = RERUNLINE;
+ if( is_string_variable(name) )
+ clif_scriptinputstr(sd,st->oid);
+ else
+ clif_scriptinput(sd,st->oid);
+ }
+ else
+ { // take received text/value and store it in the designated variable
+ sd->state.menu_or_input = 0;
+ if( is_string_variable(name) )
+ {
+ int len = (int)strlen(sd->npc_str);
+ set_reg(st, sd, uid, name, (void*)sd->npc_str, script_getref(st,2));
+ script_pushint(st, (len > max ? 1 : len < min ? -1 : 0));
+ }
+ else
+ {
+ int amount = sd->npc_amount;
+ set_reg(st, sd, uid, name, (void*)__64BPRTSIZE(cap_value(amount,min,max)), script_getref(st,2));
+ script_pushint(st, (amount > max ? 1 : amount < min ? -1 : 0));
+ }
+ st->state = RUN;
+ }
+ return 0;
}
// declare the copyarray method here for future reference
@@ -5353,71 +5458,74 @@ BUILDIN_FUNC(copyarray);
/// set(<variable>,<value>) -> <variable>
BUILDIN_FUNC(set)
{
- TBL_PC *sd = NULL;
- struct script_data *data;
- //struct script_data* datavalue;
- int num;
- const char *name;
- char prefix;
-
- data = script_getdata(st,2);
- //datavalue = script_getdata(st,3);
- if (!data_isreference(data)) {
- ShowError("script:set: not a variable\n");
- script_reportdata(script_getdata(st,2));
- st->state = END;
- return 1;
- }
-
- num = reference_getuid(data);
- name = reference_getname(data);
- prefix = *name;
-
- if (not_server_variable(prefix)) {
- sd = script_rid2sd(st);
- if (sd == NULL) {
- ShowError("script:set: no player attached for player variable '%s'\n", name);
- return 0;
- }
- }
+ TBL_PC* sd = NULL;
+ struct script_data* data;
+ //struct script_data* datavalue;
+ int num;
+ const char* name;
+ char prefix;
+
+ data = script_getdata(st,2);
+ //datavalue = script_getdata(st,3);
+ if( !data_isreference(data) )
+ {
+ ShowError("script:set: not a variable\n");
+ script_reportdata(script_getdata(st,2));
+ st->state = END;
+ return 1;
+ }
+
+ num = reference_getuid(data);
+ name = reference_getname(data);
+ prefix = *name;
+
+ if( not_server_variable(prefix) )
+ {
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ {
+ ShowError("script:set: no player attached for player variable '%s'\n", name);
+ return 0;
+ }
+ }
#if 0
- if (data_isreference(datavalue)) {
- // the value being referenced is a variable
- const char *namevalue = reference_getname(datavalue);
-
- if (!not_array_variable(*namevalue)) {
- // array variable being copied into another array variable
- if (sd == NULL && not_server_variable(*namevalue) && !(sd = script_rid2sd(st))) {
- // player must be attached in order to copy a player variable
- ShowError("script:set: no player attached for player variable '%s'\n", namevalue);
- return 0;
- }
-
- if (is_string_variable(namevalue) != is_string_variable(name)) {
- // non-matching array value types
- ShowWarning("script:set: two array variables do not match in type.\n");
- return 0;
- }
-
- // push the maximum number of array values to the stack
- push_val(st->stack, C_INT, SCRIPT_MAX_ARRAYSIZE);
-
- // call the copy array method directly
- return buildin_copyarray(st);
- }
- }
+ if( data_isreference(datavalue) )
+ {// the value being referenced is a variable
+ const char* namevalue = reference_getname(datavalue);
+
+ if( !not_array_variable(*namevalue) )
+ {// array variable being copied into another array variable
+ if( sd == NULL && not_server_variable(*namevalue) && !(sd = script_rid2sd(st)) )
+ {// player must be attached in order to copy a player variable
+ ShowError("script:set: no player attached for player variable '%s'\n", namevalue);
+ return 0;
+ }
+
+ if( is_string_variable(namevalue) != is_string_variable(name) )
+ {// non-matching array value types
+ ShowWarning("script:set: two array variables do not match in type.\n");
+ return 0;
+ }
+
+ // push the maximum number of array values to the stack
+ push_val(st->stack, C_INT, SCRIPT_MAX_ARRAYSIZE);
+
+ // call the copy array method directly
+ return buildin_copyarray(st);
+ }
+ }
#endif
- if (is_string_variable(name))
- set_reg(st,sd,num,name,(void *)script_getstr(st,3),script_getref(st,2));
- else
- set_reg(st,sd,num,name,(void *)__64BPRTSIZE(script_getnum(st,3)),script_getref(st,2));
+ if( is_string_variable(name) )
+ set_reg(st,sd,num,name,(void*)script_getstr(st,3),script_getref(st,2));
+ else
+ set_reg(st,sd,num,name,(void*)__64BPRTSIZE(script_getnum(st,3)),script_getref(st,2));
- // return a copy of the variable reference
- script_pushcopy(st,2);
+ // return a copy of the variable reference
+ script_pushcopy(st,2);
- return 0;
+ return 0;
}
/////////////////////////////////////////////////////////////////////
@@ -5425,26 +5533,31 @@ BUILDIN_FUNC(set)
///
/// Returns the size of the specified array
-static int32 getarraysize(struct script_state *st, int32 id, int32 idx, int isstring, struct DBMap **ref)
-{
- int32 ret = idx;
-
- if (isstring) {
- for (; idx < SCRIPT_MAX_ARRAYSIZE; ++idx) {
- char *str = (char *)get_val2(st, reference_uid(id, idx), ref);
- if (str && *str)
- ret = idx + 1;
- script_removetop(st, -1, 0);
- }
- } else {
- for (; idx < SCRIPT_MAX_ARRAYSIZE; ++idx) {
- int32 num = (int32)__64BPRTSIZE(get_val2(st, reference_uid(id, idx), ref));
- if (num)
- ret = idx + 1;
- script_removetop(st, -1, 0);
- }
- }
- return ret;
+static int32 getarraysize(struct script_state* st, int32 id, int32 idx, int isstring, struct DBMap** ref)
+{
+ int32 ret = idx;
+
+ if( isstring )
+ {
+ for( ; idx < SCRIPT_MAX_ARRAYSIZE; ++idx )
+ {
+ char* str = (char*)get_val2(st, reference_uid(id, idx), ref);
+ if( str && *str )
+ ret = idx + 1;
+ script_removetop(st, -1, 0);
+ }
+ }
+ else
+ {
+ for( ; idx < SCRIPT_MAX_ARRAYSIZE; ++idx )
+ {
+ int32 num = (int32)__64BPRTSIZE(get_val2(st, reference_uid(id, idx), ref));
+ if( num )
+ ret = idx + 1;
+ script_removetop(st, -1, 0);
+ }
+ }
+ return ret;
}
/// Sets values of an array, from the starting index.
@@ -5453,52 +5566,56 @@ static int32 getarraysize(struct script_state *st, int32 id, int32 idx, int isst
/// setarray <array variable>,<value1>{,<value2>...};
BUILDIN_FUNC(setarray)
{
- struct script_data *data;
- const char *name;
- int32 start;
- int32 end;
- int32 id;
- int32 i;
- TBL_PC *sd = NULL;
-
- data = script_getdata(st, 2);
- if (!data_isreference(data)) {
- ShowError("script:setarray: not a variable\n");
- script_reportdata(data);
- st->state = END;
- return 1;// not a variable
- }
-
- id = reference_getid(data);
- start = reference_getindex(data);
- name = reference_getname(data);
- if (not_array_variable(*name)) {
- ShowError("script:setarray: illegal scope\n");
- script_reportdata(data);
- st->state = END;
- return 1;// not supported
- }
-
- if (not_server_variable(*name)) {
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;// no player attached
- }
-
- end = start + script_lastdata(st) - 2;
- if (end > SCRIPT_MAX_ARRAYSIZE)
- end = SCRIPT_MAX_ARRAYSIZE;
-
- if (is_string_variable(name)) {
- // string array
- for (i = 3; start < end; ++start, ++i)
- set_reg(st, sd, reference_uid(id, start), name, (void *)script_getstr(st,i), reference_getref(data));
- } else {
- // int array
- for (i = 3; start < end; ++start, ++i)
- set_reg(st, sd, reference_uid(id, start), name, (void *)__64BPRTSIZE(script_getnum(st,i)), reference_getref(data));
- }
- return 0;
+ struct script_data* data;
+ const char* name;
+ int32 start;
+ int32 end;
+ int32 id;
+ int32 i;
+ TBL_PC* sd = NULL;
+
+ data = script_getdata(st, 2);
+ if( !data_isreference(data) )
+ {
+ ShowError("script:setarray: not a variable\n");
+ script_reportdata(data);
+ st->state = END;
+ return 1;// not a variable
+ }
+
+ id = reference_getid(data);
+ start = reference_getindex(data);
+ name = reference_getname(data);
+ if( not_array_variable(*name) )
+ {
+ ShowError("script:setarray: illegal scope\n");
+ script_reportdata(data);
+ st->state = END;
+ return 1;// not supported
+ }
+
+ if( not_server_variable(*name) )
+ {
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;// no player attached
+ }
+
+ end = start + script_lastdata(st) - 2;
+ if( end > SCRIPT_MAX_ARRAYSIZE )
+ end = SCRIPT_MAX_ARRAYSIZE;
+
+ if( is_string_variable(name) )
+ {// string array
+ for( i = 3; start < end; ++start, ++i )
+ set_reg(st, sd, reference_uid(id, start), name, (void*)script_getstr(st,i), reference_getref(data));
+ }
+ else
+ {// int array
+ for( i = 3; start < end; ++start, ++i )
+ set_reg(st, sd, reference_uid(id, start), name, (void*)__64BPRTSIZE(script_getnum(st,i)), reference_getref(data));
+ }
+ return 0;
}
/// Sets count values of an array, from the starting index.
@@ -5507,50 +5624,53 @@ BUILDIN_FUNC(setarray)
/// cleararray <array variable>,<value>,<count>;
BUILDIN_FUNC(cleararray)
{
- struct script_data *data;
- const char *name;
- int32 start;
- int32 end;
- int32 id;
- void *v;
- TBL_PC *sd = NULL;
-
- data = script_getdata(st, 2);
- if (!data_isreference(data)) {
- ShowError("script:cleararray: not a variable\n");
- script_reportdata(data);
- st->state = END;
- return 1;// not a variable
- }
-
- id = reference_getid(data);
- start = reference_getindex(data);
- name = reference_getname(data);
- if (not_array_variable(*name)) {
- ShowError("script:cleararray: illegal scope\n");
- script_reportdata(data);
- st->state = END;
- return 1;// not supported
- }
-
- if (not_server_variable(*name)) {
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;// no player attached
- }
-
- if (is_string_variable(name))
- v = (void *)script_getstr(st, 3);
- else
- v = (void *)__64BPRTSIZE(script_getnum(st, 3));
-
- end = start + script_getnum(st, 4);
- if (end > SCRIPT_MAX_ARRAYSIZE)
- end = SCRIPT_MAX_ARRAYSIZE;
-
- for (; start < end; ++start)
- set_reg(st, sd, reference_uid(id, start), name, v, script_getref(st,2));
- return 0;
+ struct script_data* data;
+ const char* name;
+ int32 start;
+ int32 end;
+ int32 id;
+ void* v;
+ TBL_PC* sd = NULL;
+
+ data = script_getdata(st, 2);
+ if( !data_isreference(data) )
+ {
+ ShowError("script:cleararray: not a variable\n");
+ script_reportdata(data);
+ st->state = END;
+ return 1;// not a variable
+ }
+
+ id = reference_getid(data);
+ start = reference_getindex(data);
+ name = reference_getname(data);
+ if( not_array_variable(*name) )
+ {
+ ShowError("script:cleararray: illegal scope\n");
+ script_reportdata(data);
+ st->state = END;
+ return 1;// not supported
+ }
+
+ if( not_server_variable(*name) )
+ {
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;// no player attached
+ }
+
+ if( is_string_variable(name) )
+ v = (void*)script_getstr(st, 3);
+ else
+ v = (void*)__64BPRTSIZE(script_getnum(st, 3));
+
+ end = start + script_getnum(st, 4);
+ if( end > SCRIPT_MAX_ARRAYSIZE )
+ end = SCRIPT_MAX_ARRAYSIZE;
+
+ for( ; start < end; ++start )
+ set_reg(st, sd, reference_uid(id, start), name, v, script_getref(st,2));
+ return 0;
}
/// Copies data from one array to another.
@@ -5559,82 +5679,91 @@ BUILDIN_FUNC(cleararray)
/// copyarray <destination array variable>,<source array variable>,<count>;
BUILDIN_FUNC(copyarray)
{
- struct script_data *data1;
- struct script_data *data2;
- const char *name1;
- const char *name2;
- int32 idx1;
- int32 idx2;
- int32 id1;
- int32 id2;
- void *v;
- int32 i;
- int32 count;
- TBL_PC *sd = NULL;
-
- data1 = script_getdata(st, 2);
- data2 = script_getdata(st, 3);
- if (!data_isreference(data1) || !data_isreference(data2)) {
- ShowError("script:copyarray: not a variable\n");
- script_reportdata(data1);
- script_reportdata(data2);
- st->state = END;
- return 1;// not a variable
- }
-
- id1 = reference_getid(data1);
- id2 = reference_getid(data2);
- idx1 = reference_getindex(data1);
- idx2 = reference_getindex(data2);
- name1 = reference_getname(data1);
- name2 = reference_getname(data2);
- if (not_array_variable(*name1) || not_array_variable(*name2)) {
- ShowError("script:copyarray: illegal scope\n");
- script_reportdata(data1);
- script_reportdata(data2);
- st->state = END;
- return 1;// not supported
- }
-
- if (is_string_variable(name1) != is_string_variable(name2)) {
- ShowError("script:copyarray: type mismatch\n");
- script_reportdata(data1);
- script_reportdata(data2);
- st->state = END;
- return 1;// data type mismatch
- }
-
- if (not_server_variable(*name1) || not_server_variable(*name2)) {
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;// no player attached
- }
-
- count = script_getnum(st, 4);
- if (count > SCRIPT_MAX_ARRAYSIZE - idx1)
- count = SCRIPT_MAX_ARRAYSIZE - idx1;
- if (count <= 0 || (id1 == id2 && idx1 == idx2))
- return 0;// nothing to copy
-
- if (id1 == id2 && idx1 > idx2) {
- // destination might be overlapping the source - copy in reverse order
- for (i = count - 1; i >= 0; --i) {
- v = get_val2(st, reference_uid(id2, idx2 + i), reference_getref(data2));
- set_reg(st, sd, reference_uid(id1, idx1 + i), name1, v, reference_getref(data1));
- script_removetop(st, -1, 0);
- }
- } else {
- // normal copy
- for (i = 0; i < count; ++i) {
- if (idx2 + i < SCRIPT_MAX_ARRAYSIZE) {
- v = get_val2(st, reference_uid(id2, idx2 + i), reference_getref(data2));
- set_reg(st, sd, reference_uid(id1, idx1 + i), name1, v, reference_getref(data1));
- script_removetop(st, -1, 0);
- } else // out of range - assume ""/0
- set_reg(st, sd, reference_uid(id1, idx1 + i), name1, (is_string_variable(name1)?(void *)"":(void *)0), reference_getref(data1));
- }
- }
- return 0;
+ struct script_data* data1;
+ struct script_data* data2;
+ const char* name1;
+ const char* name2;
+ int32 idx1;
+ int32 idx2;
+ int32 id1;
+ int32 id2;
+ void* v;
+ int32 i;
+ int32 count;
+ TBL_PC* sd = NULL;
+
+ data1 = script_getdata(st, 2);
+ data2 = script_getdata(st, 3);
+ if( !data_isreference(data1) || !data_isreference(data2) )
+ {
+ ShowError("script:copyarray: not a variable\n");
+ script_reportdata(data1);
+ script_reportdata(data2);
+ st->state = END;
+ return 1;// not a variable
+ }
+
+ id1 = reference_getid(data1);
+ id2 = reference_getid(data2);
+ idx1 = reference_getindex(data1);
+ idx2 = reference_getindex(data2);
+ name1 = reference_getname(data1);
+ name2 = reference_getname(data2);
+ if( not_array_variable(*name1) || not_array_variable(*name2) )
+ {
+ ShowError("script:copyarray: illegal scope\n");
+ script_reportdata(data1);
+ script_reportdata(data2);
+ st->state = END;
+ return 1;// not supported
+ }
+
+ if( is_string_variable(name1) != is_string_variable(name2) )
+ {
+ ShowError("script:copyarray: type mismatch\n");
+ script_reportdata(data1);
+ script_reportdata(data2);
+ st->state = END;
+ return 1;// data type mismatch
+ }
+
+ if( not_server_variable(*name1) || not_server_variable(*name2) )
+ {
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;// no player attached
+ }
+
+ count = script_getnum(st, 4);
+ if( count > SCRIPT_MAX_ARRAYSIZE - idx1 )
+ count = SCRIPT_MAX_ARRAYSIZE - idx1;
+ if( count <= 0 || (id1 == id2 && idx1 == idx2) )
+ return 0;// nothing to copy
+
+ if( id1 == id2 && idx1 > idx2 )
+ {// destination might be overlapping the source - copy in reverse order
+ for( i = count - 1; i >= 0; --i )
+ {
+ v = get_val2(st, reference_uid(id2, idx2 + i), reference_getref(data2));
+ set_reg(st, sd, reference_uid(id1, idx1 + i), name1, v, reference_getref(data1));
+ script_removetop(st, -1, 0);
+ }
+ }
+ else
+ {// normal copy
+ for( i = 0; i < count; ++i )
+ {
+ if( idx2 + i < SCRIPT_MAX_ARRAYSIZE )
+ {
+ v = get_val2(st, reference_uid(id2, idx2 + i), reference_getref(data2));
+ set_reg(st, sd, reference_uid(id1, idx1 + i), name1, v, reference_getref(data1));
+ script_removetop(st, -1, 0);
+ }
+ else// out of range - assume ""/0
+ set_reg(st, sd, reference_uid(id1, idx1 + i), name1, (is_string_variable(name1)?(void*)"":(void*)0), reference_getref(data1));
+ }
+ }
+ return 0;
}
/// Returns the size of the array.
@@ -5644,29 +5773,31 @@ BUILDIN_FUNC(copyarray)
/// getarraysize(<array variable>) -> <int>
BUILDIN_FUNC(getarraysize)
{
- struct script_data *data;
- const char *name;
-
- data = script_getdata(st, 2);
- if (!data_isreference(data)) {
- ShowError("script:getarraysize: not a variable\n");
- script_reportdata(data);
- script_pushnil(st);
- st->state = END;
- return 1;// not a variable
- }
-
- name = reference_getname(data);
- if (not_array_variable(*name)) {
- ShowError("script:getarraysize: illegal scope\n");
- script_reportdata(data);
- script_pushnil(st);
- st->state = END;
- return 1;// not supported
- }
-
- script_pushint(st, getarraysize(st, reference_getid(data), reference_getindex(data), is_string_variable(name), reference_getref(data)));
- return 0;
+ struct script_data* data;
+ const char* name;
+
+ data = script_getdata(st, 2);
+ if( !data_isreference(data) )
+ {
+ ShowError("script:getarraysize: not a variable\n");
+ script_reportdata(data);
+ script_pushnil(st);
+ st->state = END;
+ return 1;// not a variable
+ }
+
+ name = reference_getname(data);
+ if( not_array_variable(*name) )
+ {
+ ShowError("script:getarraysize: illegal scope\n");
+ script_reportdata(data);
+ script_pushnil(st);
+ st->state = END;
+ return 1;// not supported
+ }
+
+ script_pushint(st, getarraysize(st, reference_getid(data), reference_getindex(data), is_string_variable(name), reference_getref(data)));
+ return 0;
}
/// Deletes count or all the elements in an array, from the starting index.
@@ -5676,66 +5807,74 @@ BUILDIN_FUNC(getarraysize)
/// deletearray <array variable>,<count>;
BUILDIN_FUNC(deletearray)
{
- struct script_data *data;
- const char *name;
- int start;
- int end;
- int id;
- TBL_PC *sd = NULL;
-
- data = script_getdata(st, 2);
- if (!data_isreference(data)) {
- ShowError("script:deletearray: not a variable\n");
- script_reportdata(data);
- st->state = END;
- return 1;// not a variable
- }
-
- id = reference_getid(data);
- start = reference_getindex(data);
- name = reference_getname(data);
- if (not_array_variable(*name)) {
- ShowError("script:deletearray: illegal scope\n");
- script_reportdata(data);
- st->state = END;
- return 1;// not supported
- }
-
- if (not_server_variable(*name)) {
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;// no player attached
- }
-
- end = SCRIPT_MAX_ARRAYSIZE;
-
- if (start >= end)
- return 0;// nothing to free
-
- if (script_hasdata(st,3)) {
- int count = script_getnum(st, 3);
- if (count > end - start)
- count = end - start;
- if (count <= 0)
- return 0;// nothing to free
-
- // move rest of the elements backward
- for (; start + count < end; ++start) {
- void *v = get_val2(st, reference_uid(id, start + count), reference_getref(data));
- set_reg(st, sd, reference_uid(id, start), name, v, reference_getref(data));
- script_removetop(st, -1, 0);
- }
- }
-
- // clear the rest of the array
- if (is_string_variable(name)) {
- for (; start < end; ++start)
- set_reg(st, sd, reference_uid(id, start), name, (void *)"", reference_getref(data));
- } else {
- for (; start < end; ++start)
- set_reg(st, sd, reference_uid(id, start), name, (void *)0, reference_getref(data));
- }
- return 0;
+ struct script_data* data;
+ const char* name;
+ int start;
+ int end;
+ int id;
+ TBL_PC *sd = NULL;
+
+ data = script_getdata(st, 2);
+ if( !data_isreference(data) )
+ {
+ ShowError("script:deletearray: not a variable\n");
+ script_reportdata(data);
+ st->state = END;
+ return 1;// not a variable
+ }
+
+ id = reference_getid(data);
+ start = reference_getindex(data);
+ name = reference_getname(data);
+ if( not_array_variable(*name) )
+ {
+ ShowError("script:deletearray: illegal scope\n");
+ script_reportdata(data);
+ st->state = END;
+ return 1;// not supported
+ }
+
+ if( not_server_variable(*name) )
+ {
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;// no player attached
+ }
+
+ end = SCRIPT_MAX_ARRAYSIZE;
+
+ if( start >= end )
+ return 0;// nothing to free
+
+ if( script_hasdata(st,3) )
+ {
+ int count = script_getnum(st, 3);
+ if( count > end - start )
+ count = end - start;
+ if( count <= 0 )
+ return 0;// nothing to free
+
+ // move rest of the elements backward
+ for( ; start + count < end; ++start )
+ {
+ void* v = get_val2(st, reference_uid(id, start + count), reference_getref(data));
+ set_reg(st, sd, reference_uid(id, start), name, v, reference_getref(data));
+ script_removetop(st, -1, 0);
+ }
+ }
+
+ // clear the rest of the array
+ if( is_string_variable(name) )
+ {
+ for( ; start < end; ++start )
+ set_reg(st, sd, reference_uid(id, start), name, (void *)"", reference_getref(data));
+ }
+ else
+ {
+ for( ; start < end; ++start )
+ set_reg(st, sd, reference_uid(id, start), name, (void*)0, reference_getref(data));
+ }
+ return 0;
}
/// Returns a reference to the target index of the array variable.
@@ -5744,41 +5883,44 @@ BUILDIN_FUNC(deletearray)
/// getelementofarray(<array variable>,<index>) -> <variable reference>
BUILDIN_FUNC(getelementofarray)
{
- struct script_data *data;
- const char *name;
- int32 id;
- int i;
-
- data = script_getdata(st, 2);
- if (!data_isreference(data)) {
- ShowError("script:getelementofarray: not a variable\n");
- script_reportdata(data);
- script_pushnil(st);
- st->state = END;
- return 1;// not a variable
- }
-
- id = reference_getid(data);
- name = reference_getname(data);
- if (not_array_variable(*name)) {
- ShowError("script:getelementofarray: illegal scope\n");
- script_reportdata(data);
- script_pushnil(st);
- st->state = END;
- return 1;// not supported
- }
-
- i = script_getnum(st, 3);
- if (i < 0 || i >= SCRIPT_MAX_ARRAYSIZE) {
- ShowWarning("script:getelementofarray: index out of range (%d)\n", i);
- script_reportdata(data);
- script_pushnil(st);
- st->state = END;
- return 1;// out of range
- }
-
- push_val2(st->stack, C_NAME, reference_uid(id, i), reference_getref(data));
- return 0;
+ struct script_data* data;
+ const char* name;
+ int32 id;
+ int i;
+
+ data = script_getdata(st, 2);
+ if( !data_isreference(data) )
+ {
+ ShowError("script:getelementofarray: not a variable\n");
+ script_reportdata(data);
+ script_pushnil(st);
+ st->state = END;
+ return 1;// not a variable
+ }
+
+ id = reference_getid(data);
+ name = reference_getname(data);
+ if( not_array_variable(*name) )
+ {
+ ShowError("script:getelementofarray: illegal scope\n");
+ script_reportdata(data);
+ script_pushnil(st);
+ st->state = END;
+ return 1;// not supported
+ }
+
+ i = script_getnum(st, 3);
+ if( i < 0 || i >= SCRIPT_MAX_ARRAYSIZE )
+ {
+ ShowWarning("script:getelementofarray: index out of range (%d)\n", i);
+ script_reportdata(data);
+ script_pushnil(st);
+ st->state = END;
+ return 1;// out of range
+ }
+
+ push_val2(st->stack, C_NAME, reference_uid(id, i), reference_getref(data));
+ return 0;
}
/////////////////////////////////////////////////////////////////////
@@ -5790,37 +5932,36 @@ BUILDIN_FUNC(getelementofarray)
*------------------------------------------*/
BUILDIN_FUNC(setlook)
{
- int type,val;
- TBL_PC *sd;
+ int type,val;
+ TBL_PC* sd;
- type=script_getnum(st,2);
- val=script_getnum(st,3);
+ type=script_getnum(st,2);
+ val=script_getnum(st,3);
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- pc_changelook(sd,type,val);
+ pc_changelook(sd,type,val);
- return 0;
+ return 0;
}
BUILDIN_FUNC(changelook)
-{
- // As setlook but only client side
- int type,val;
- TBL_PC *sd;
+{ // As setlook but only client side
+ int type,val;
+ TBL_PC* sd;
- type=script_getnum(st,2);
- val=script_getnum(st,3);
+ type=script_getnum(st,2);
+ val=script_getnum(st,3);
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- clif_changelook(&sd->bl,type,val);
+ clif_changelook(&sd->bl,type,val);
- return 0;
+ return 0;
}
/*==========================================
@@ -5828,14 +5969,14 @@ BUILDIN_FUNC(changelook)
*------------------------------------------*/
BUILDIN_FUNC(cutin)
{
- TBL_PC *sd;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- clif_cutin(sd,script_getstr(st,2),script_getnum(st,3));
- return 0;
+ clif_cutin(sd,script_getstr(st,2),script_getnum(st,3));
+ return 0;
}
/*==========================================
@@ -5843,22 +5984,22 @@ BUILDIN_FUNC(cutin)
*------------------------------------------*/
BUILDIN_FUNC(viewpoint)
{
- int type,x,y,id,color;
- TBL_PC *sd;
+ int type,x,y,id,color;
+ TBL_PC* sd;
- type=script_getnum(st,2);
- x=script_getnum(st,3);
- y=script_getnum(st,4);
- id=script_getnum(st,5);
- color=script_getnum(st,6);
+ type=script_getnum(st,2);
+ x=script_getnum(st,3);
+ y=script_getnum(st,4);
+ id=script_getnum(st,5);
+ color=script_getnum(st,6);
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- clif_viewpoint(sd,st->oid,type,x,y,id,color);
+ clif_viewpoint(sd,st->oid,type,x,y,id,color);
- return 0;
+ return 0;
}
/*==========================================
@@ -5866,282 +6007,291 @@ BUILDIN_FUNC(viewpoint)
*------------------------------------------*/
BUILDIN_FUNC(countitem)
{
- int nameid, i;
- int count = 0;
- struct item_data *id = NULL;
- struct script_data *data;
+ int nameid, i;
+ int count = 0;
+ struct item_data* id = NULL;
+ struct script_data* data;
- TBL_PC *sd = script_rid2sd(st);
- if (!sd) {
- script_pushint(st,0);
- return 0;
- }
+ TBL_PC* sd = script_rid2sd(st);
+ if (!sd) {
+ script_pushint(st,0);
+ return 0;
+ }
- data = script_getdata(st,2);
- get_val(st, data); // convert into value in case of a variable
+ data = script_getdata(st,2);
+ get_val(st, data); // convert into value in case of a variable
- if (data_isstring(data)) {
- // item name
- id = itemdb_searchname(conv_str(st, data));
- } else {
- // item id
- id = itemdb_exists(conv_num(st, data));
- }
+ if( data_isstring(data) )
+ {// item name
+ id = itemdb_searchname(conv_str(st, data));
+ }
+ else
+ {// item id
+ id = itemdb_exists(conv_num(st, data));
+ }
- if (id == NULL) {
- ShowError("buildin_countitem: Invalid item '%s'.\n", script_getstr(st,2)); // returns string, regardless of what it was
- script_pushint(st,0);
- return 1;
- }
+ if( id == NULL )
+ {
+ ShowError("buildin_countitem: Invalid item '%s'.\n", script_getstr(st,2)); // returns string, regardless of what it was
+ script_pushint(st,0);
+ return 1;
+ }
- nameid = id->nameid;
+ nameid = id->nameid;
- for (i = 0; i < MAX_INVENTORY; i++)
- if (sd->status.inventory[i].nameid == nameid)
- count += sd->status.inventory[i].amount;
+ for(i = 0; i < MAX_INVENTORY; i++)
+ if(sd->status.inventory[i].nameid == nameid)
+ count += sd->status.inventory[i].amount;
- script_pushint(st,count);
- return 0;
+ script_pushint(st,count);
+ return 0;
}
/*==========================================
- * countitem2(nameID,Identified,Refine,Attribute,Card0,Card1,Card2,Card3) [Lupus]
- * returns number of items that meet the conditions
+ * countitem2(nameID,Identified,Refine,Attribute,Card0,Card1,Card2,Card3) [Lupus]
+ * returns number of items that meet the conditions
*------------------------------------------*/
BUILDIN_FUNC(countitem2)
{
- int nameid, iden, ref, attr, c1, c2, c3, c4;
- int count = 0;
- int i;
- struct item_data *id = NULL;
- struct script_data *data;
-
- TBL_PC *sd = script_rid2sd(st);
- if (!sd) {
- script_pushint(st,0);
- return 0;
- }
-
- data = script_getdata(st,2);
- get_val(st, data); // convert into value in case of a variable
-
- if (data_isstring(data)) {
- // item name
- id = itemdb_searchname(conv_str(st, data));
- } else {
- // item id
- id = itemdb_exists(conv_num(st, data));
- }
-
- if (id == NULL) {
- ShowError("buildin_countitem2: Invalid item '%s'.\n", script_getstr(st,2)); // returns string, regardless of what it was
- script_pushint(st,0);
- return 1;
- }
-
- nameid = id->nameid;
- iden = script_getnum(st,3);
- ref = script_getnum(st,4);
- attr = script_getnum(st,5);
- c1 = (short)script_getnum(st,6);
- c2 = (short)script_getnum(st,7);
- c3 = (short)script_getnum(st,8);
- c4 = (short)script_getnum(st,9);
-
- for (i = 0; i < MAX_INVENTORY; i++)
- if (sd->status.inventory[i].nameid > 0 && sd->inventory_data[i] != NULL &&
- sd->status.inventory[i].amount > 0 && sd->status.inventory[i].nameid == nameid &&
- sd->status.inventory[i].identify == iden && sd->status.inventory[i].refine == ref &&
- sd->status.inventory[i].attribute == attr && sd->status.inventory[i].card[0] == c1 &&
- sd->status.inventory[i].card[1] == c2 && sd->status.inventory[i].card[2] == c3 &&
- sd->status.inventory[i].card[3] == c4
- )
- count += sd->status.inventory[i].amount;
-
- script_pushint(st,count);
- return 0;
+ int nameid, iden, ref, attr, c1, c2, c3, c4;
+ int count = 0;
+ int i;
+ struct item_data* id = NULL;
+ struct script_data* data;
+
+ TBL_PC* sd = script_rid2sd(st);
+ if (!sd) {
+ script_pushint(st,0);
+ return 0;
+ }
+
+ data = script_getdata(st,2);
+ get_val(st, data); // convert into value in case of a variable
+
+ if( data_isstring(data) )
+ {// item name
+ id = itemdb_searchname(conv_str(st, data));
+ }
+ else
+ {// item id
+ id = itemdb_exists(conv_num(st, data));
+ }
+
+ if( id == NULL )
+ {
+ ShowError("buildin_countitem2: Invalid item '%s'.\n", script_getstr(st,2)); // returns string, regardless of what it was
+ script_pushint(st,0);
+ return 1;
+ }
+
+ nameid = id->nameid;
+ iden = script_getnum(st,3);
+ ref = script_getnum(st,4);
+ attr = script_getnum(st,5);
+ c1 = (short)script_getnum(st,6);
+ c2 = (short)script_getnum(st,7);
+ c3 = (short)script_getnum(st,8);
+ c4 = (short)script_getnum(st,9);
+
+ for(i = 0; i < MAX_INVENTORY; i++)
+ if (sd->status.inventory[i].nameid > 0 && sd->inventory_data[i] != NULL &&
+ sd->status.inventory[i].amount > 0 && sd->status.inventory[i].nameid == nameid &&
+ sd->status.inventory[i].identify == iden && sd->status.inventory[i].refine == ref &&
+ sd->status.inventory[i].attribute == attr && sd->status.inventory[i].card[0] == c1 &&
+ sd->status.inventory[i].card[1] == c2 && sd->status.inventory[i].card[2] == c3 &&
+ sd->status.inventory[i].card[3] == c4
+ )
+ count += sd->status.inventory[i].amount;
+
+ script_pushint(st,count);
+ return 0;
}
/*==========================================
* Check if item with this amount can fit in inventory
* Checking : weight, stack amount >32k, slots amount >(MAX_INVENTORY)
* Return
- * 0 : fail
- * 1 : success (npc side only)
+ * 0 : fail
+ * 1 : success (npc side only)
*------------------------------------------*/
BUILDIN_FUNC(checkweight)
{
- int nameid, amount, slots, amount2=0;
- unsigned int weight=0, i, nbargs;
- struct item_data *id = NULL;
- struct map_session_data *sd;
- struct script_data *data;
-
- if ((sd = script_rid2sd(st)) == NULL) {
- return 0;
- }
- nbargs = script_lastdata(st)+1;
- if (nbargs%2) {
- ShowError("buildin_checkweight: Invalid nb of args should be a multiple of 2.\n");
- script_pushint(st,0);
- return 1;
- }
- slots = pc_inventoryblank(sd); //nb of empty slot
-
- for (i=2; i<nbargs; i=i+2) {
- data = script_getdata(st,i);
- get_val(st, data); // convert into value in case of a variable
- if (data_isstring(data)) {// item name
- id = itemdb_searchname(conv_str(st, data));
- } else {// item id
- id = itemdb_exists(conv_num(st, data));
- }
- if (id == NULL) {
- ShowError("buildin_checkweight: Invalid item '%s'.\n", script_getstr(st,i)); // returns string, regardless of what it was
- script_pushint(st,0);
- return 1;
- }
- nameid = id->nameid;
-
- amount = script_getnum(st,i+1);
- if (amount < 1) {
- ShowError("buildin_checkweight: Invalid amount '%d'.\n", amount);
- script_pushint(st,0);
- return 1;
- }
-
- weight += itemdb_weight(nameid)*amount; //total weight for all chk
- if (weight + sd->weight > sd->max_weight) {
- // too heavy
- script_pushint(st,0);
- return 0;
- }
-
- switch (pc_checkadditem(sd, nameid, amount)) {
- case ADDITEM_EXIST:
- // item is already in inventory, but there is still space for the requested amount
- break;
- case ADDITEM_NEW:
- if (itemdb_isstackable(nameid)) { // stackable
- amount2++;
- if (slots < amount2) {
- script_pushint(st,0);
- return 0;
- }
- } else { // non-stackable
- amount2 += amount;
- if (slots < amount2) {
- script_pushint(st,0);
- return 0;
- }
- }
- break;
- case ADDITEM_OVERAMOUNT:
- script_pushint(st,0);
- return 0;
- }
- }
- script_pushint(st,1);
- return 0;
+ int nameid, amount, slots, amount2=0;
+ unsigned int weight=0, i, nbargs;
+ struct item_data* id = NULL;
+ struct map_session_data* sd;
+ struct script_data* data;
+
+ if( ( sd = script_rid2sd(st) ) == NULL ){
+ return 0;
+ }
+ nbargs = script_lastdata(st)+1;
+ if(nbargs%2){
+ ShowError("buildin_checkweight: Invalid nb of args should be a multiple of 2.\n");
+ script_pushint(st,0);
+ return 1;
+ }
+ slots = pc_inventoryblank(sd); //nb of empty slot
+
+ for(i=2; i<nbargs; i=i+2){
+ data = script_getdata(st,i);
+ get_val(st, data); // convert into value in case of a variable
+ if( data_isstring(data) ){// item name
+ id = itemdb_searchname(conv_str(st, data));
+ } else {// item id
+ id = itemdb_exists(conv_num(st, data));
+ }
+ if( id == NULL ) {
+ ShowError("buildin_checkweight: Invalid item '%s'.\n", script_getstr(st,i)); // returns string, regardless of what it was
+ script_pushint(st,0);
+ return 1;
+ }
+ nameid = id->nameid;
+
+ amount = script_getnum(st,i+1);
+ if( amount < 1 ) {
+ ShowError("buildin_checkweight: Invalid amount '%d'.\n", amount);
+ script_pushint(st,0);
+ return 1;
+ }
+
+ weight += itemdb_weight(nameid)*amount; //total weight for all chk
+ if( weight + sd->weight > sd->max_weight )
+ {// too heavy
+ script_pushint(st,0);
+ return 0;
+ }
+
+ switch( pc_checkadditem(sd, nameid, amount) )
+ {
+ case ADDITEM_EXIST:
+ // item is already in inventory, but there is still space for the requested amount
+ break;
+ case ADDITEM_NEW:
+ if( itemdb_isstackable(nameid) ) {// stackable
+ amount2++;
+ if( slots < amount2 ) {
+ script_pushint(st,0);
+ return 0;
+ }
+ }
+ else {// non-stackable
+ amount2 += amount;
+ if( slots < amount2){
+ script_pushint(st,0);
+ return 0;
+ }
+ }
+ break;
+ case ADDITEM_OVERAMOUNT:
+ script_pushint(st,0);
+ return 0;
+ }
+ }
+ script_pushint(st,1);
+ return 0;
}
BUILDIN_FUNC(checkweight2)
{
- //variable sub checkweight
- int32 nameid=-1, amount=-1;
- int i=0, amount2=0, slots=0, weight=0;
- short fail=0;
+ //variable sub checkweight
+ int32 nameid=-1, amount=-1;
+ int i=0, amount2=0, slots=0, weight=0;
+ short fail=0;
- //variable for array parsing
- struct script_data *data_it;
- struct script_data *data_nb;
- const char *name_it;
- const char *name_nb;
- int32 id_it, id_nb;
- int32 idx_it, idx_nb;
- int nb_it, nb_nb; //array size
+ //variable for array parsing
+ struct script_data* data_it;
+ struct script_data* data_nb;
+ const char* name_it;
+ const char* name_nb;
+ int32 id_it, id_nb;
+ int32 idx_it, idx_nb;
+ int nb_it, nb_nb; //array size
- TBL_PC *sd = script_rid2sd(st);
- nullpo_retr(1,sd);
+ TBL_PC *sd = script_rid2sd(st);
+ nullpo_retr(1,sd);
- data_it = script_getdata(st, 2);
- data_nb = script_getdata(st, 3);
+ data_it = script_getdata(st, 2);
+ data_nb = script_getdata(st, 3);
- if (!data_isreference(data_it) || !data_isreference(data_nb)) {
- ShowError("script:checkweight2: parameter not a variable\n");
- script_pushint(st,0);
- return 1;// not a variable
- }
- id_it = reference_getid(data_it);
- id_nb = reference_getid(data_nb);
- idx_it = reference_getindex(data_it);
- idx_nb = reference_getindex(data_nb);
- name_it = reference_getname(data_it);
- name_nb = reference_getname(data_nb);
-
- if (not_array_variable(*name_it) || not_array_variable(*name_nb)) {
- ShowError("script:checkweight2: illegal scope\n");
- script_pushint(st,0);
- return 1;// not supported
- }
- if (is_string_variable(name_it) || is_string_variable(name_nb)) {
- ShowError("script:checkweight2: illegal type, need int\n");
- script_pushint(st,0);
- return 1;// not supported
- }
- nb_it = getarraysize(st, id_it, idx_it, 0, reference_getref(data_it));
- nb_nb = getarraysize(st, id_nb, idx_nb, 0, reference_getref(data_nb));
- if (nb_it != nb_nb) {
- ShowError("Size mistmatch: nb_it=%d, nb_nb=%d\n",nb_it,nb_nb);
- fail = 1;
- }
-
- slots = pc_inventoryblank(sd);
- for (i=0; i<nb_it; i++) {
- nameid = (int32)__64BPRTSIZE(get_val2(st,reference_uid(id_it,idx_it+i),reference_getref(data_it)));
- script_removetop(st, -1, 0);
- amount = (int32)__64BPRTSIZE(get_val2(st,reference_uid(id_nb,idx_nb+i),reference_getref(data_nb)));
- script_removetop(st, -1, 0);
- if (fail) continue; //cpntonie to depop rest
-
- if (itemdb_exists(nameid) == NULL) {
- ShowError("buildin_checkweight2: Invalid item '%d'.\n", nameid);
- fail=1;
- continue;
+ if( !data_isreference(data_it) || !data_isreference(data_nb))
+ {
+ ShowError("script:checkweight2: parameter not a variable\n");
+ script_pushint(st,0);
+ return 1;// not a variable
}
- if (amount < 0) {
- ShowError("buildin_checkweight2: Invalid amount '%d'.\n", amount);
- fail = 1;
- continue;
+ id_it = reference_getid(data_it);
+ id_nb = reference_getid(data_nb);
+ idx_it = reference_getindex(data_it);
+ idx_nb = reference_getindex(data_nb);
+ name_it = reference_getname(data_it);
+ name_nb = reference_getname(data_nb);
+
+ if( not_array_variable(*name_it) || not_array_variable(*name_nb))
+ {
+ ShowError("script:checkweight2: illegal scope\n");
+ script_pushint(st,0);
+ return 1;// not supported
}
- weight += itemdb_weight(nameid)*amount;
- if (weight + sd->weight > sd->max_weight) {
- fail = 1;
- continue;
+ if(is_string_variable(name_it) || is_string_variable(name_nb)){
+ ShowError("script:checkweight2: illegal type, need int\n");
+ script_pushint(st,0);
+ return 1;// not supported
+ }
+ nb_it = getarraysize(st, id_it, idx_it, 0, reference_getref(data_it));
+ nb_nb = getarraysize(st, id_nb, idx_nb, 0, reference_getref(data_nb));
+ if(nb_it != nb_nb){
+ ShowError("Size mistmatch: nb_it=%d, nb_nb=%d\n",nb_it,nb_nb);
+ fail = 1;
}
- switch (pc_checkadditem(sd, nameid, amount)) {
- case ADDITEM_EXIST:
- // item is already in inventory, but there is still space for the requested amount
- break;
- case ADDITEM_NEW:
- if (itemdb_isstackable(nameid)) {// stackable
- amount2++;
- if (slots < amount2)
- fail = 1;
- } else { // non-stackable
- amount2 += amount;
- if (slots < amount2) {
- fail = 1;
- }
- }
- break;
- case ADDITEM_OVERAMOUNT:
- fail = 1;
- } //end switch
- } //end loop DO NOT break it prematurly we need to depop all stack
- fail?script_pushint(st,0):script_pushint(st,1);
- return 0;
+ slots = pc_inventoryblank(sd);
+ for(i=0; i<nb_it; i++){
+ nameid = (int32)__64BPRTSIZE(get_val2(st,reference_uid(id_it,idx_it+i),reference_getref(data_it)));
+ script_removetop(st, -1, 0);
+ amount = (int32)__64BPRTSIZE(get_val2(st,reference_uid(id_nb,idx_nb+i),reference_getref(data_nb)));
+ script_removetop(st, -1, 0);
+ if(fail) continue; //cpntonie to depop rest
+
+ if(itemdb_exists(nameid) == NULL ){
+ ShowError("buildin_checkweight2: Invalid item '%d'.\n", nameid);
+ fail=1;
+ continue;
+ }
+ if(amount < 0 ){
+ ShowError("buildin_checkweight2: Invalid amount '%d'.\n", amount);
+ fail = 1;
+ continue;
+ }
+ weight += itemdb_weight(nameid)*amount;
+ if( weight + sd->weight > sd->max_weight ){
+ fail = 1;
+ continue;
+ }
+ switch( pc_checkadditem(sd, nameid, amount) ) {
+ case ADDITEM_EXIST:
+ // item is already in inventory, but there is still space for the requested amount
+ break;
+ case ADDITEM_NEW:
+ if( itemdb_isstackable(nameid) ){// stackable
+ amount2++;
+ if( slots < amount2 )
+ fail = 1;
+ }
+ else {// non-stackable
+ amount2 += amount;
+ if( slots < amount2 ){
+ fail = 1;
+ }
+ }
+ break;
+ case ADDITEM_OVERAMOUNT:
+ fail = 1;
+ } //end switch
+ } //end loop DO NOT break it prematurly we need to depop all stack
+
+ fail?script_pushint(st,0):script_pushint(st,1);
+ return 0;
}
/*==========================================
@@ -6150,76 +6300,79 @@ BUILDIN_FUNC(checkweight2)
*------------------------------------------*/
BUILDIN_FUNC(getitem)
{
- int nameid,amount,get_count,i,flag = 0;
- struct item it;
- TBL_PC *sd;
- struct script_data *data;
-
- data=script_getdata(st,2);
- get_val(st,data);
- if (data_isstring(data)) {
- // "<item name>"
- const char *name=conv_str(st,data);
- struct item_data *item_data = itemdb_searchname(name);
- if (item_data == NULL) {
- ShowError("buildin_getitem: Nonexistant item %s requested.\n", name);
- return 1; //No item created.
- }
- nameid=item_data->nameid;
- } else if (data_isint(data)) {
- // <item id>
- nameid=conv_num(st,data);
- //Violet Box, Blue Box, etc - random item pick
- if (nameid < 0) {
- nameid = -nameid;
- flag = 1;
- }
- if (nameid <= 0 || !itemdb_exists(nameid)) {
- ShowError("buildin_getitem: Nonexistant item %d requested.\n", nameid);
- return 1; //No item created.
- }
- } else {
- ShowError("buildin_getitem: invalid data type for argument #1 (%d).", data->type);
- return 1;
- }
-
- // <amount>
- if ((amount=script_getnum(st,3)) <= 0)
- return 0; //return if amount <=0, skip the useles iteration
-
- memset(&it,0,sizeof(it));
- it.nameid=nameid;
- if (!flag)
- it.identify=1;
- else
- it.identify=itemdb_isidentified(nameid);
-
- if (script_hasdata(st,4))
- sd=map_id2sd(script_getnum(st,4)); // <Account ID>
- else
- sd=script_rid2sd(st); // Attached player
-
- if (sd == NULL) // no target
- return 0;
-
- //Check if it's stackable.
- if (!itemdb_isstackable(nameid))
- get_count = 1;
- else
- get_count = amount;
-
- for (i = 0; i < amount; i += get_count) {
- // if not pet egg
- if (!pet_create_egg(sd, nameid)) {
- if ((flag = pc_additem(sd, &it, get_count, LOG_TYPE_SCRIPT))) {
- clif_additem(sd, 0, 0, flag);
- if (pc_candrop(sd,&it))
- map_addflooritem(&it,get_count,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
- }
- }
- }
-
- return 0;
+ int nameid,amount,get_count,i,flag = 0;
+ struct item it;
+ TBL_PC *sd;
+ struct script_data *data;
+
+ data=script_getdata(st,2);
+ get_val(st,data);
+ if( data_isstring(data) )
+ {// "<item name>"
+ const char *name=conv_str(st,data);
+ struct item_data *item_data = itemdb_searchname(name);
+ if( item_data == NULL ){
+ ShowError("buildin_getitem: Nonexistant item %s requested.\n", name);
+ return 1; //No item created.
+ }
+ nameid=item_data->nameid;
+ } else if( data_isint(data) )
+ {// <item id>
+ nameid=conv_num(st,data);
+ //Violet Box, Blue Box, etc - random item pick
+ if( nameid < 0 ) {
+ nameid = -nameid;
+ flag = 1;
+ }
+ if( nameid <= 0 || !itemdb_exists(nameid) ){
+ ShowError("buildin_getitem: Nonexistant item %d requested.\n", nameid);
+ return 1; //No item created.
+ }
+ } else {
+ ShowError("buildin_getitem: invalid data type for argument #1 (%d).", data->type);
+ return 1;
+ }
+
+ // <amount>
+ if( (amount=script_getnum(st,3)) <= 0)
+ return 0; //return if amount <=0, skip the useles iteration
+
+ memset(&it,0,sizeof(it));
+ it.nameid=nameid;
+ if(!flag)
+ it.identify=1;
+ else
+ it.identify=itemdb_isidentified(nameid);
+
+ if( script_hasdata(st,4) )
+ sd=map_id2sd(script_getnum(st,4)); // <Account ID>
+ else
+ sd=script_rid2sd(st); // Attached player
+
+ if( sd == NULL ) // no target
+ return 0;
+
+ //Check if it's stackable.
+ if (!itemdb_isstackable(nameid))
+ get_count = 1;
+ else
+ get_count = amount;
+
+ for (i = 0; i < amount; i += get_count)
+ {
+ // if not pet egg
+ if (!pet_create_egg(sd, nameid))
+ {
+ if ((flag = pc_additem(sd, &it, get_count, LOG_TYPE_SCRIPT)))
+ {
+ clif_additem(sd, 0, 0, flag);
+ if( pc_candrop(sd,&it) )
+ map_addflooritem(&it,get_count,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ }
+ }
+ }
+
+ return 0;
}
/*==========================================
@@ -6227,93 +6380,98 @@ BUILDIN_FUNC(getitem)
*------------------------------------------*/
BUILDIN_FUNC(getitem2)
{
- int nameid,amount,get_count,i,flag = 0;
- int iden,ref,attr,c1,c2,c3,c4;
- struct item_data *item_data;
- struct item item_tmp;
- TBL_PC *sd;
- struct script_data *data;
-
- if (script_hasdata(st,11))
- sd=map_id2sd(script_getnum(st,11)); // <Account ID>
- else
- sd=script_rid2sd(st); // Attached player
-
- if (sd == NULL) // no target
- return 0;
-
- data=script_getdata(st,2);
- get_val(st,data);
- if (data_isstring(data)) {
- const char *name=conv_str(st,data);
- struct item_data *item_data = itemdb_searchname(name);
- if (item_data)
- nameid=item_data->nameid;
- else
- nameid=UNKNOWN_ITEM_ID;
- } else
- nameid=conv_num(st,data);
-
- amount=script_getnum(st,3);
- iden=script_getnum(st,4);
- ref=script_getnum(st,5);
- attr=script_getnum(st,6);
- c1=(short)script_getnum(st,7);
- c2=(short)script_getnum(st,8);
- c3=(short)script_getnum(st,9);
- c4=(short)script_getnum(st,10);
-
- if (nameid<0) { // Invalide nameid
- nameid = -nameid;
- flag = 1;
- }
-
- if (nameid > 0) {
- memset(&item_tmp,0,sizeof(item_tmp));
- item_data=itemdb_exists(nameid);
- if (item_data == NULL)
- return -1;
- if (item_data->type==IT_WEAPON || item_data->type==IT_ARMOR) {
- if (ref > MAX_REFINE) ref = MAX_REFINE;
- } else if (item_data->type==IT_PETEGG) {
- iden = 1;
- ref = 0;
- } else {
- iden = 1;
- ref = attr = 0;
- }
-
- item_tmp.nameid=nameid;
- if (!flag)
- item_tmp.identify=iden;
- else if (item_data->type==IT_WEAPON || item_data->type==IT_ARMOR)
- item_tmp.identify=0;
- item_tmp.refine=ref;
- item_tmp.attribute=attr;
- item_tmp.card[0]=(short)c1;
- item_tmp.card[1]=(short)c2;
- item_tmp.card[2]=(short)c3;
- item_tmp.card[3]=(short)c4;
-
- //Check if it's stackable.
- if (!itemdb_isstackable(nameid))
- get_count = 1;
- else
- get_count = amount;
-
- for (i = 0; i < amount; i += get_count) {
- // if not pet egg
- if (!pet_create_egg(sd, nameid)) {
- if ((flag = pc_additem(sd, &item_tmp, get_count, LOG_TYPE_SCRIPT))) {
- clif_additem(sd, 0, 0, flag);
- if (pc_candrop(sd,&item_tmp))
- map_addflooritem(&item_tmp,get_count,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
- }
- }
- }
- }
-
- return 0;
+ int nameid,amount,get_count,i,flag = 0;
+ int iden,ref,attr,c1,c2,c3,c4;
+ struct item_data *item_data;
+ struct item item_tmp;
+ TBL_PC *sd;
+ struct script_data *data;
+
+ if( script_hasdata(st,11) )
+ sd=map_id2sd(script_getnum(st,11)); // <Account ID>
+ else
+ sd=script_rid2sd(st); // Attached player
+
+ if( sd == NULL ) // no target
+ return 0;
+
+ data=script_getdata(st,2);
+ get_val(st,data);
+ if( data_isstring(data) ){
+ const char *name=conv_str(st,data);
+ struct item_data *item_data = itemdb_searchname(name);
+ if( item_data )
+ nameid=item_data->nameid;
+ else
+ nameid=UNKNOWN_ITEM_ID;
+ }else
+ nameid=conv_num(st,data);
+
+ amount=script_getnum(st,3);
+ iden=script_getnum(st,4);
+ ref=script_getnum(st,5);
+ attr=script_getnum(st,6);
+ c1=(short)script_getnum(st,7);
+ c2=(short)script_getnum(st,8);
+ c3=(short)script_getnum(st,9);
+ c4=(short)script_getnum(st,10);
+
+ if(nameid<0) { // Invalide nameid
+ nameid = -nameid;
+ flag = 1;
+ }
+
+ if(nameid > 0) {
+ memset(&item_tmp,0,sizeof(item_tmp));
+ item_data=itemdb_exists(nameid);
+ if (item_data == NULL)
+ return -1;
+ if(item_data->type==IT_WEAPON || item_data->type==IT_ARMOR){
+ if(ref > MAX_REFINE) ref = MAX_REFINE;
+ }
+ else if(item_data->type==IT_PETEGG) {
+ iden = 1;
+ ref = 0;
+ }
+ else {
+ iden = 1;
+ ref = attr = 0;
+ }
+
+ item_tmp.nameid=nameid;
+ if(!flag)
+ item_tmp.identify=iden;
+ else if(item_data->type==IT_WEAPON || item_data->type==IT_ARMOR)
+ item_tmp.identify=0;
+ item_tmp.refine=ref;
+ item_tmp.attribute=attr;
+ item_tmp.card[0]=(short)c1;
+ item_tmp.card[1]=(short)c2;
+ item_tmp.card[2]=(short)c3;
+ item_tmp.card[3]=(short)c4;
+
+ //Check if it's stackable.
+ if (!itemdb_isstackable(nameid))
+ get_count = 1;
+ else
+ get_count = amount;
+
+ for (i = 0; i < amount; i += get_count)
+ {
+ // if not pet egg
+ if (!pet_create_egg(sd, nameid))
+ {
+ if ((flag = pc_additem(sd, &item_tmp, get_count, LOG_TYPE_SCRIPT)))
+ {
+ clif_additem(sd, 0, 0, flag);
+ if( pc_candrop(sd,&item_tmp) )
+ map_addflooritem(&item_tmp,get_count,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ }
+ }
+ }
+ }
+
+ return 0;
}
/*==========================================
@@ -6322,49 +6480,57 @@ BUILDIN_FUNC(getitem2)
*------------------------------------------*/
BUILDIN_FUNC(rentitem)
{
- struct map_session_data *sd;
- struct script_data *data;
- struct item it;
- int seconds;
- int nameid = 0, flag;
-
- data = script_getdata(st,2);
- get_val(st,data);
-
- if ((sd = script_rid2sd(st)) == NULL)
- return 0;
-
- if (data_isstring(data)) {
- const char *name = conv_str(st,data);
- struct item_data *itd = itemdb_searchname(name);
- if (itd == NULL) {
- ShowError("buildin_rentitem: Nonexistant item %s requested.\n", name);
- return 1;
- }
- nameid = itd->nameid;
- } else if (data_isint(data)) {
- nameid = conv_num(st,data);
- if (nameid <= 0 || !itemdb_exists(nameid)) {
- ShowError("buildin_rentitem: Nonexistant item %d requested.\n", nameid);
- return 1;
- }
- } else {
- ShowError("buildin_rentitem: invalid data type for argument #1 (%d).\n", data->type);
- return 1;
- }
-
- seconds = script_getnum(st,3);
- memset(&it, 0, sizeof(it));
- it.nameid = nameid;
- it.identify = 1;
- it.expire_time = (unsigned int)(time(NULL) + seconds);
-
- if ((flag = pc_additem(sd, &it, 1, LOG_TYPE_SCRIPT))) {
- clif_additem(sd, 0, 0, flag);
- return 1;
- }
-
- return 0;
+ struct map_session_data *sd;
+ struct script_data *data;
+ struct item it;
+ int seconds;
+ int nameid = 0, flag;
+
+ data = script_getdata(st,2);
+ get_val(st,data);
+
+ if( (sd = script_rid2sd(st)) == NULL )
+ return 0;
+
+ if( data_isstring(data) )
+ {
+ const char *name = conv_str(st,data);
+ struct item_data *itd = itemdb_searchname(name);
+ if( itd == NULL )
+ {
+ ShowError("buildin_rentitem: Nonexistant item %s requested.\n", name);
+ return 1;
+ }
+ nameid = itd->nameid;
+ }
+ else if( data_isint(data) )
+ {
+ nameid = conv_num(st,data);
+ if( nameid <= 0 || !itemdb_exists(nameid) )
+ {
+ ShowError("buildin_rentitem: Nonexistant item %d requested.\n", nameid);
+ return 1;
+ }
+ }
+ else
+ {
+ ShowError("buildin_rentitem: invalid data type for argument #1 (%d).\n", data->type);
+ return 1;
+ }
+
+ seconds = script_getnum(st,3);
+ memset(&it, 0, sizeof(it));
+ it.nameid = nameid;
+ it.identify = 1;
+ it.expire_time = (unsigned int)(time(NULL) + seconds);
+
+ if( (flag = pc_additem(sd, &it, 1, LOG_TYPE_SCRIPT)) )
+ {
+ clif_additem(sd, 0, 0, flag);
+ return 1;
+ }
+
+ return 0;
}
/*==========================================
@@ -6375,65 +6541,65 @@ BUILDIN_FUNC(rentitem)
*------------------------------------------*/
BUILDIN_FUNC(getnameditem)
{
- int nameid;
- struct item item_tmp;
- TBL_PC *sd, *tsd;
- struct script_data *data;
-
- sd = script_rid2sd(st);
- if (sd == NULL) {
- //Player not attached!
- script_pushint(st,0);
- return 0;
- }
-
- data=script_getdata(st,2);
- get_val(st,data);
- if (data_isstring(data)) {
- const char *name=conv_str(st,data);
- struct item_data *item_data = itemdb_searchname(name);
- if (item_data == NULL) {
- //Failed
- script_pushint(st,0);
- return 0;
- }
- nameid = item_data->nameid;
- } else
- nameid = conv_num(st,data);
-
- if (!itemdb_exists(nameid)/* || itemdb_isstackable(nameid)*/) {
- //Even though named stackable items "could" be risky, they are required for certain quests.
- script_pushint(st,0);
- return 0;
- }
-
- data=script_getdata(st,3);
- get_val(st,data);
- if (data_isstring(data)) //Char Name
- tsd=map_nick2sd(conv_str(st,data));
- else //Char Id was given
- tsd=map_charid2sd(conv_num(st,data));
-
- if (tsd == NULL) {
- //Failed
- script_pushint(st,0);
- return 0;
- }
-
- memset(&item_tmp,0,sizeof(item_tmp));
- item_tmp.nameid=nameid;
- item_tmp.amount=1;
- item_tmp.identify=1;
- item_tmp.card[0]=CARD0_CREATE; //we don't use 255! because for example SIGNED WEAPON shouldn't get TOP10 BS Fame bonus [Lupus]
- item_tmp.card[2]=tsd->status.char_id;
- item_tmp.card[3]=tsd->status.char_id >> 16;
- if (pc_additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT)) {
- script_pushint(st,0);
- return 0; //Failed to add item, we will not drop if they don't fit
- }
-
- script_pushint(st,1);
- return 0;
+ int nameid;
+ struct item item_tmp;
+ TBL_PC *sd, *tsd;
+ struct script_data *data;
+
+ sd = script_rid2sd(st);
+ if (sd == NULL)
+ { //Player not attached!
+ script_pushint(st,0);
+ return 0;
+ }
+
+ data=script_getdata(st,2);
+ get_val(st,data);
+ if( data_isstring(data) ){
+ const char *name=conv_str(st,data);
+ struct item_data *item_data = itemdb_searchname(name);
+ if( item_data == NULL)
+ { //Failed
+ script_pushint(st,0);
+ return 0;
+ }
+ nameid = item_data->nameid;
+ }else
+ nameid = conv_num(st,data);
+
+ if(!itemdb_exists(nameid)/* || itemdb_isstackable(nameid)*/)
+ { //Even though named stackable items "could" be risky, they are required for certain quests.
+ script_pushint(st,0);
+ return 0;
+ }
+
+ data=script_getdata(st,3);
+ get_val(st,data);
+ if( data_isstring(data) ) //Char Name
+ tsd=map_nick2sd(conv_str(st,data));
+ else //Char Id was given
+ tsd=map_charid2sd(conv_num(st,data));
+
+ if( tsd == NULL )
+ { //Failed
+ script_pushint(st,0);
+ return 0;
+ }
+
+ memset(&item_tmp,0,sizeof(item_tmp));
+ item_tmp.nameid=nameid;
+ item_tmp.amount=1;
+ item_tmp.identify=1;
+ item_tmp.card[0]=CARD0_CREATE; //we don't use 255! because for example SIGNED WEAPON shouldn't get TOP10 BS Fame bonus [Lupus]
+ item_tmp.card[2]=tsd->status.char_id;
+ item_tmp.card[3]=tsd->status.char_id >> 16;
+ if(pc_additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT)) {
+ script_pushint(st,0);
+ return 0; //Failed to add item, we will not drop if they don't fit
+ }
+
+ script_pushint(st,1);
+ return 0;
}
/*==========================================
@@ -6442,11 +6608,11 @@ BUILDIN_FUNC(getnameditem)
*------------------------------------------*/
BUILDIN_FUNC(grouprandomitem)
{
- int group;
+ int group;
- group = script_getnum(st,2);
- script_pushint(st,itemdb_searchrandomid(group));
- return 0;
+ group = script_getnum(st,2);
+ script_pushint(st,itemdb_searchrandomid(group));
+ return 0;
}
/*==========================================
@@ -6454,76 +6620,78 @@ BUILDIN_FUNC(grouprandomitem)
*------------------------------------------*/
BUILDIN_FUNC(makeitem)
{
- int nameid,amount,flag = 0;
- int x,y,m;
- const char *mapname;
- struct item item_tmp;
- struct script_data *data;
-
- data=script_getdata(st,2);
- get_val(st,data);
- if (data_isstring(data)) {
- const char *name=conv_str(st,data);
- struct item_data *item_data = itemdb_searchname(name);
- if (item_data)
- nameid=item_data->nameid;
- else
- nameid=UNKNOWN_ITEM_ID;
- } else
- nameid=conv_num(st,data);
-
- amount=script_getnum(st,3);
- mapname =script_getstr(st,4);
- x =script_getnum(st,5);
- y =script_getnum(st,6);
-
- if (strcmp(mapname,"this")==0) {
- TBL_PC *sd;
- sd = script_rid2sd(st);
- if (!sd) return 0; //Failed...
- m=sd->bl.m;
- } else
- m=map_mapname2mapid(mapname);
-
- if (nameid<0) {
- nameid = -nameid;
- flag = 1;
- }
-
- if (nameid > 0) {
- memset(&item_tmp,0,sizeof(item_tmp));
- item_tmp.nameid=nameid;
- if (!flag)
- item_tmp.identify=1;
- else
- item_tmp.identify=itemdb_isidentified(nameid);
-
- map_addflooritem(&item_tmp,amount,m,x,y,0,0,0,0);
- }
-
- return 0;
+ int nameid,amount,flag = 0;
+ int x,y,m;
+ const char *mapname;
+ struct item item_tmp;
+ struct script_data *data;
+
+ data=script_getdata(st,2);
+ get_val(st,data);
+ if( data_isstring(data) ){
+ const char *name=conv_str(st,data);
+ struct item_data *item_data = itemdb_searchname(name);
+ if( item_data )
+ nameid=item_data->nameid;
+ else
+ nameid=UNKNOWN_ITEM_ID;
+ }else
+ nameid=conv_num(st,data);
+
+ amount=script_getnum(st,3);
+ mapname =script_getstr(st,4);
+ x =script_getnum(st,5);
+ y =script_getnum(st,6);
+
+ if(strcmp(mapname,"this")==0)
+ {
+ TBL_PC *sd;
+ sd = script_rid2sd(st);
+ if (!sd) return 0; //Failed...
+ m=sd->bl.m;
+ } else
+ m=map_mapname2mapid(mapname);
+
+ if(nameid<0) {
+ nameid = -nameid;
+ flag = 1;
+ }
+
+ if(nameid > 0) {
+ memset(&item_tmp,0,sizeof(item_tmp));
+ item_tmp.nameid=nameid;
+ if(!flag)
+ item_tmp.identify=1;
+ else
+ item_tmp.identify=itemdb_isidentified(nameid);
+
+ map_addflooritem(&item_tmp,amount,m,x,y,0,0,0,0);
+ }
+
+ return 0;
}
/// Counts / deletes the current item given by idx.
/// Used by buildin_delitem_search
/// Relies on all input data being already fully valid.
-static void buildin_delitem_delete(struct map_session_data *sd, int idx, int *amount, bool delete_items)
+static void buildin_delitem_delete(struct map_session_data* sd, int idx, int* amount, bool delete_items)
{
- int delamount;
- struct item *inv = &sd->status.inventory[idx];
+ int delamount;
+ struct item* inv = &sd->status.inventory[idx];
- delamount = (amount[0] < inv->amount) ? amount[0] : inv->amount;
+ delamount = ( amount[0] < inv->amount ) ? amount[0] : inv->amount;
- if (delete_items) {
- if (sd->inventory_data[idx]->type == IT_PETEGG && inv->card[0] == CARD0_PET) {
- // delete associated pet
- intif_delete_petdata(MakeDWord(inv->card[1], inv->card[2]));
- }
- pc_delitem(sd, idx, delamount, 0, 0, LOG_TYPE_SCRIPT);
- }
+ if( delete_items )
+ {
+ if( sd->inventory_data[idx]->type == IT_PETEGG && inv->card[0] == CARD0_PET )
+ {// delete associated pet
+ intif_delete_petdata(MakeDWord(inv->card[1], inv->card[2]));
+ }
+ pc_delitem(sd, idx, delamount, 0, 0, LOG_TYPE_SCRIPT);
+ }
- amount[0]-= delamount;
+ amount[0]-= delamount;
}
@@ -6532,103 +6700,116 @@ static void buildin_delitem_delete(struct map_session_data *sd, int idx, int *am
/// Relies on all input data being already fully valid.
/// @param exact_match will also match item attributes and cards, not just name id
/// @return true when all items could be deleted, false when there were not enough items to delete
-static bool buildin_delitem_search(struct map_session_data *sd, struct item *it, bool exact_match)
-{
- bool delete_items = false;
- int i, amount, important;
- struct item *inv;
-
- // prefer always non-equipped items
- it->equip = 0;
-
- // when searching for nameid only, prefer additionally
- if (!exact_match) {
- // non-refined items
- it->refine = 0;
- // card-less items
- memset(it->card, 0, sizeof(it->card));
- }
-
- for (;;) {
- amount = it->amount;
- important = 0;
-
- // 1st pass -- less important items / exact match
- for (i = 0; amount && i < ARRAYLENGTH(sd->status.inventory); i++) {
- inv = &sd->status.inventory[i];
-
- if (!inv->nameid || !sd->inventory_data[i] || inv->nameid != it->nameid) {
- // wrong/invalid item
- continue;
- }
-
- if (inv->equip != it->equip || inv->refine != it->refine) {
- // not matching attributes
- important++;
- continue;
- }
-
- if (exact_match) {
- if (inv->identify != it->identify || inv->attribute != it->attribute || memcmp(inv->card, it->card, sizeof(inv->card))) {
- // not matching exact attributes
- continue;
- }
- } else {
- if (sd->inventory_data[i]->type == IT_PETEGG) {
- if (inv->card[0] == CARD0_PET && CheckForCharServer()) {
- // pet which cannot be deleted
- continue;
- }
- } else if (memcmp(inv->card, it->card, sizeof(inv->card))) {
- // named/carded item
- important++;
- continue;
- }
- }
-
- // count / delete item
- buildin_delitem_delete(sd, i, &amount, delete_items);
- }
-
- // 2nd pass -- any matching item
- if (amount == 0 || important == 0) {
- // either everything was already consumed or no items were skipped
- ;
- } else for (i = 0; amount && i < ARRAYLENGTH(sd->status.inventory); i++) {
- inv = &sd->status.inventory[i];
-
- if (!inv->nameid || !sd->inventory_data[i] || inv->nameid != it->nameid) {
- // wrong/invalid item
- continue;
- }
-
- if (sd->inventory_data[i]->type == IT_PETEGG && inv->card[0] == CARD0_PET && CheckForCharServer()) {
- // pet which cannot be deleted
- continue;
- }
-
- if (exact_match) {
- if (inv->refine != it->refine || inv->identify != it->identify || inv->attribute != it->attribute || memcmp(inv->card, it->card, sizeof(inv->card))) {
- // not matching attributes
- continue;
- }
- }
-
- // count / delete item
- buildin_delitem_delete(sd, i, &amount, delete_items);
- }
-
- if (amount) {
- // not enough items
- return false;
- } else if (delete_items) {
- // we are done with the work
- return true;
- } else {
- // get rid of the items now
- delete_items = true;
- }
- }
+static bool buildin_delitem_search(struct map_session_data* sd, struct item* it, bool exact_match)
+{
+ bool delete_items = false;
+ int i, amount, important;
+ struct item* inv;
+
+ // prefer always non-equipped items
+ it->equip = 0;
+
+ // when searching for nameid only, prefer additionally
+ if( !exact_match )
+ {
+ // non-refined items
+ it->refine = 0;
+ // card-less items
+ memset(it->card, 0, sizeof(it->card));
+ }
+
+ for(;;)
+ {
+ amount = it->amount;
+ important = 0;
+
+ // 1st pass -- less important items / exact match
+ for( i = 0; amount && i < ARRAYLENGTH(sd->status.inventory); i++ )
+ {
+ inv = &sd->status.inventory[i];
+
+ if( !inv->nameid || !sd->inventory_data[i] || inv->nameid != it->nameid )
+ {// wrong/invalid item
+ continue;
+ }
+
+ if( inv->equip != it->equip || inv->refine != it->refine )
+ {// not matching attributes
+ important++;
+ continue;
+ }
+
+ if( exact_match )
+ {
+ if( inv->identify != it->identify || inv->attribute != it->attribute || memcmp(inv->card, it->card, sizeof(inv->card)) )
+ {// not matching exact attributes
+ continue;
+ }
+ }
+ else
+ {
+ if( sd->inventory_data[i]->type == IT_PETEGG )
+ {
+ if( inv->card[0] == CARD0_PET && CheckForCharServer() )
+ {// pet which cannot be deleted
+ continue;
+ }
+ }
+ else if( memcmp(inv->card, it->card, sizeof(inv->card)) )
+ {// named/carded item
+ important++;
+ continue;
+ }
+ }
+
+ // count / delete item
+ buildin_delitem_delete(sd, i, &amount, delete_items);
+ }
+
+ // 2nd pass -- any matching item
+ if( amount == 0 || important == 0 )
+ {// either everything was already consumed or no items were skipped
+ ;
+ }
+ else for( i = 0; amount && i < ARRAYLENGTH(sd->status.inventory); i++ )
+ {
+ inv = &sd->status.inventory[i];
+
+ if( !inv->nameid || !sd->inventory_data[i] || inv->nameid != it->nameid )
+ {// wrong/invalid item
+ continue;
+ }
+
+ if( sd->inventory_data[i]->type == IT_PETEGG && inv->card[0] == CARD0_PET && CheckForCharServer() )
+ {// pet which cannot be deleted
+ continue;
+ }
+
+ if( exact_match )
+ {
+ if( inv->refine != it->refine || inv->identify != it->identify || inv->attribute != it->attribute || memcmp(inv->card, it->card, sizeof(inv->card)) )
+ {// not matching attributes
+ continue;
+ }
+ }
+
+ // count / delete item
+ buildin_delitem_delete(sd, i, &amount, delete_items);
+ }
+
+ if( amount )
+ {// not enough items
+ return false;
+ }
+ else if( delete_items )
+ {// we are done with the work
+ return true;
+ }
+ else
+ {// get rid of the items now
+ delete_items = true;
+ }
+ }
}
@@ -6639,58 +6820,67 @@ static bool buildin_delitem_search(struct map_session_data *sd, struct item *it,
/// delitem "<item name>",<amount>{,<account id>}
BUILDIN_FUNC(delitem)
{
- TBL_PC *sd;
- struct item it;
- struct script_data *data;
-
- if (script_hasdata(st,4)) {
- int account_id = script_getnum(st,4);
- sd = map_id2sd(account_id); // <account id>
- if (sd == NULL) {
- ShowError("script:delitem: player not found (AID=%d).\n", account_id);
- st->state = END;
- return 1;
- }
- } else {
- sd = script_rid2sd(st);// attached player
- if (sd == NULL)
- return 0;
- }
-
- data = script_getdata(st,2);
- get_val(st,data);
- if (data_isstring(data)) {
- const char *item_name = conv_str(st,data);
- struct item_data *id = itemdb_searchname(item_name);
- if (id == NULL) {
- ShowError("script:delitem: unknown item \"%s\".\n", item_name);
- st->state = END;
- return 1;
- }
- it.nameid = id->nameid;// "<item name>"
- } else {
- it.nameid = conv_num(st,data);// <item id>
- if (!itemdb_exists(it.nameid)) {
- ShowError("script:delitem: unknown item \"%d\".\n", it.nameid);
- st->state = END;
- return 1;
- }
- }
-
- it.amount=script_getnum(st,3);
-
- if (it.amount <= 0)
- return 0;// nothing to do
-
- if (buildin_delitem_search(sd, &it, false)) {
- // success
- return 0;
- }
-
- ShowError("script:delitem: failed to delete %d items (AID=%d item_id=%d).\n", it.amount, sd->status.account_id, it.nameid);
- st->state = END;
- clif_scriptclose(sd, st->oid);
- return 1;
+ TBL_PC *sd;
+ struct item it;
+ struct script_data *data;
+
+ if( script_hasdata(st,4) )
+ {
+ int account_id = script_getnum(st,4);
+ sd = map_id2sd(account_id); // <account id>
+ if( sd == NULL )
+ {
+ ShowError("script:delitem: player not found (AID=%d).\n", account_id);
+ st->state = END;
+ return 1;
+ }
+ }
+ else
+ {
+ sd = script_rid2sd(st);// attached player
+ if( sd == NULL )
+ return 0;
+ }
+
+ data = script_getdata(st,2);
+ get_val(st,data);
+ if( data_isstring(data) )
+ {
+ const char* item_name = conv_str(st,data);
+ struct item_data* id = itemdb_searchname(item_name);
+ if( id == NULL )
+ {
+ ShowError("script:delitem: unknown item \"%s\".\n", item_name);
+ st->state = END;
+ return 1;
+ }
+ it.nameid = id->nameid;// "<item name>"
+ }
+ else
+ {
+ it.nameid = conv_num(st,data);// <item id>
+ if( !itemdb_exists( it.nameid ) )
+ {
+ ShowError("script:delitem: unknown item \"%d\".\n", it.nameid);
+ st->state = END;
+ return 1;
+ }
+ }
+
+ it.amount=script_getnum(st,3);
+
+ if( it.amount <= 0 )
+ return 0;// nothing to do
+
+ if( buildin_delitem_search(sd, &it, false) )
+ {// success
+ return 0;
+ }
+
+ ShowError("script:delitem: failed to delete %d items (AID=%d item_id=%d).\n", it.amount, sd->status.account_id, it.nameid);
+ st->state = END;
+ clif_scriptclose(sd, st->oid);
+ return 1;
}
/// Deletes items from the target/attached player.
@@ -6699,65 +6889,74 @@ BUILDIN_FUNC(delitem)
/// delitem2 "<Item name>",<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>}
BUILDIN_FUNC(delitem2)
{
- TBL_PC *sd;
- struct item it;
- struct script_data *data;
-
- if (script_hasdata(st,11)) {
- int account_id = script_getnum(st,11);
- sd = map_id2sd(account_id); // <account id>
- if (sd == NULL) {
- ShowError("script:delitem2: player not found (AID=%d).\n", account_id);
- st->state = END;
- return 1;
- }
- } else {
- sd = script_rid2sd(st);// attached player
- if (sd == NULL)
- return 0;
- }
-
- data = script_getdata(st,2);
- get_val(st,data);
- if (data_isstring(data)) {
- const char *item_name = conv_str(st,data);
- struct item_data *id = itemdb_searchname(item_name);
- if (id == NULL) {
- ShowError("script:delitem2: unknown item \"%s\".\n", item_name);
- st->state = END;
- return 1;
- }
- it.nameid = id->nameid;// "<item name>"
- } else {
- it.nameid = conv_num(st,data);// <item id>
- if (!itemdb_exists(it.nameid)) {
- ShowError("script:delitem: unknown item \"%d\".\n", it.nameid);
- st->state = END;
- return 1;
- }
- }
-
- it.amount=script_getnum(st,3);
- it.identify=script_getnum(st,4);
- it.refine=script_getnum(st,5);
- it.attribute=script_getnum(st,6);
- it.card[0]=(short)script_getnum(st,7);
- it.card[1]=(short)script_getnum(st,8);
- it.card[2]=(short)script_getnum(st,9);
- it.card[3]=(short)script_getnum(st,10);
-
- if (it.amount <= 0)
- return 0;// nothing to do
-
- if (buildin_delitem_search(sd, &it, true)) {
- // success
- return 0;
- }
-
- ShowError("script:delitem2: failed to delete %d items (AID=%d item_id=%d).\n", it.amount, sd->status.account_id, it.nameid);
- st->state = END;
- clif_scriptclose(sd, st->oid);
- return 1;
+ TBL_PC *sd;
+ struct item it;
+ struct script_data *data;
+
+ if( script_hasdata(st,11) )
+ {
+ int account_id = script_getnum(st,11);
+ sd = map_id2sd(account_id); // <account id>
+ if( sd == NULL )
+ {
+ ShowError("script:delitem2: player not found (AID=%d).\n", account_id);
+ st->state = END;
+ return 1;
+ }
+ }
+ else
+ {
+ sd = script_rid2sd(st);// attached player
+ if( sd == NULL )
+ return 0;
+ }
+
+ data = script_getdata(st,2);
+ get_val(st,data);
+ if( data_isstring(data) )
+ {
+ const char* item_name = conv_str(st,data);
+ struct item_data* id = itemdb_searchname(item_name);
+ if( id == NULL )
+ {
+ ShowError("script:delitem2: unknown item \"%s\".\n", item_name);
+ st->state = END;
+ return 1;
+ }
+ it.nameid = id->nameid;// "<item name>"
+ }
+ else
+ {
+ it.nameid = conv_num(st,data);// <item id>
+ if( !itemdb_exists( it.nameid ) )
+ {
+ ShowError("script:delitem: unknown item \"%d\".\n", it.nameid);
+ st->state = END;
+ return 1;
+ }
+ }
+
+ it.amount=script_getnum(st,3);
+ it.identify=script_getnum(st,4);
+ it.refine=script_getnum(st,5);
+ it.attribute=script_getnum(st,6);
+ it.card[0]=(short)script_getnum(st,7);
+ it.card[1]=(short)script_getnum(st,8);
+ it.card[2]=(short)script_getnum(st,9);
+ it.card[3]=(short)script_getnum(st,10);
+
+ if( it.amount <= 0 )
+ return 0;// nothing to do
+
+ if( buildin_delitem_search(sd, &it, true) )
+ {// success
+ return 0;
+ }
+
+ ShowError("script:delitem2: failed to delete %d items (AID=%d item_id=%d).\n", it.amount, sd->status.account_id, it.nameid);
+ st->state = END;
+ clif_scriptclose(sd, st->oid);
+ return 1;
}
/*==========================================
@@ -6765,20 +6964,20 @@ BUILDIN_FUNC(delitem2)
*------------------------------------------*/
BUILDIN_FUNC(enableitemuse)
{
- TBL_PC *sd;
- sd=script_rid2sd(st);
- if (sd)
- sd->npc_item_flag = st->oid;
- return 0;
+ TBL_PC *sd;
+ sd=script_rid2sd(st);
+ if (sd)
+ sd->npc_item_flag = st->oid;
+ return 0;
}
BUILDIN_FUNC(disableitemuse)
{
- TBL_PC *sd;
- sd=script_rid2sd(st);
- if (sd)
- sd->npc_item_flag = 0;
- return 0;
+ TBL_PC *sd;
+ sd=script_rid2sd(st);
+ if (sd)
+ sd->npc_item_flag = 0;
+ return 0;
}
/*==========================================
@@ -6787,102 +6986,93 @@ BUILDIN_FUNC(disableitemuse)
*------------------------------------------*/
BUILDIN_FUNC(readparam)
{
- int type;
- TBL_PC *sd;
+ int type;
+ TBL_PC *sd;
- type=script_getnum(st,2);
- if (script_hasdata(st,3))
- sd=map_nick2sd(script_getstr(st,3));
- else
- sd=script_rid2sd(st);
+ type=script_getnum(st,2);
+ if( script_hasdata(st,3) )
+ sd=map_nick2sd(script_getstr(st,3));
+ else
+ sd=script_rid2sd(st);
- if (sd==NULL) {
- script_pushint(st,-1);
- return 0;
- }
+ if(sd==NULL){
+ script_pushint(st,-1);
+ return 0;
+ }
- script_pushint(st,pc_readparam(sd,type));
+ script_pushint(st,pc_readparam(sd,type));
- return 0;
+ return 0;
}
/*==========================================
* Return charid identification
* return by @num :
- * 0 : char_id
- * 1 : party_id
- * 2 : guild_id
- * 3 : account_id
- * 4 : bg_id
+ * 0 : char_id
+ * 1 : party_id
+ * 2 : guild_id
+ * 3 : account_id
+ * 4 : bg_id
*------------------------------------------*/
BUILDIN_FUNC(getcharid)
{
- int num;
- TBL_PC *sd;
-
- num = script_getnum(st,2);
- if (script_hasdata(st,3))
- sd=map_nick2sd(script_getstr(st,3));
- else
- sd=script_rid2sd(st);
-
- if (sd==NULL) {
- script_pushint(st,0); //return 0, according docs
- return 0;
- }
-
- switch (num) {
- case 0:
- script_pushint(st,sd->status.char_id);
- break;
- case 1:
- script_pushint(st,sd->status.party_id);
- break;
- case 2:
- script_pushint(st,sd->status.guild_id);
- break;
- case 3:
- script_pushint(st,sd->status.account_id);
- break;
- case 4:
- script_pushint(st,sd->bg_id);
- break;
- default:
- ShowError("buildin_getcharid: invalid parameter (%d).\n", num);
- script_pushint(st,0);
- break;
- }
-
- return 0;
+ int num;
+ TBL_PC *sd;
+
+ num = script_getnum(st,2);
+ if( script_hasdata(st,3) )
+ sd=map_nick2sd(script_getstr(st,3));
+ else
+ sd=script_rid2sd(st);
+
+ if(sd==NULL){
+ script_pushint(st,0); //return 0, according docs
+ return 0;
+ }
+
+ switch( num ) {
+ case 0: script_pushint(st,sd->status.char_id); break;
+ case 1: script_pushint(st,sd->status.party_id); break;
+ case 2: script_pushint(st,sd->status.guild_id); break;
+ case 3: script_pushint(st,sd->status.account_id); break;
+ case 4: script_pushint(st,sd->bg_id); break;
+ default:
+ ShowError("buildin_getcharid: invalid parameter (%d).\n", num);
+ script_pushint(st,0);
+ break;
+ }
+
+ return 0;
}
/*==========================================
* returns the GID of an NPC
*------------------------------------------*/
BUILDIN_FUNC(getnpcid)
{
- int num = script_getnum(st,2);
- struct npc_data *nd = NULL;
+ int num = script_getnum(st,2);
+ struct npc_data* nd = NULL;
- if (script_hasdata(st,3)) {
- // unique npc name
- if ((nd = npc_name2id(script_getstr(st,3))) == NULL) {
- ShowError("buildin_getnpcid: No such NPC '%s'.\n", script_getstr(st,3));
- script_pushint(st,0);
- return 1;
- }
- }
+ if( script_hasdata(st,3) )
+ {// unique npc name
+ if( ( nd = npc_name2id(script_getstr(st,3)) ) == NULL )
+ {
+ ShowError("buildin_getnpcid: No such NPC '%s'.\n", script_getstr(st,3));
+ script_pushint(st,0);
+ return 1;
+ }
+ }
- switch (num) {
- case 0:
- script_pushint(st,nd ? nd->bl.id : st->oid);
- break;
- default:
- ShowError("buildin_getnpcid: invalid parameter (%d).\n", num);
- script_pushint(st,0);
- return 1;
- }
+ switch (num) {
+ case 0:
+ script_pushint(st,nd ? nd->bl.id : st->oid);
+ break;
+ default:
+ ShowError("buildin_getnpcid: invalid parameter (%d).\n", num);
+ script_pushint(st,0);
+ return 1;
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -6891,57 +7081,60 @@ BUILDIN_FUNC(getnpcid)
*------------------------------------------*/
BUILDIN_FUNC(getpartyname)
{
- int party_id;
- struct party_data *p;
+ int party_id;
+ struct party_data* p;
- party_id = script_getnum(st,2);
+ party_id = script_getnum(st,2);
- if ((p = party_search(party_id)) != NULL) {
- script_pushstrcopy(st,p->party.name);
- } else {
- script_pushconststr(st,"null");
- }
- return 0;
+ if( ( p = party_search(party_id) ) != NULL )
+ {
+ script_pushstrcopy(st,p->party.name);
+ }
+ else
+ {
+ script_pushconststr(st,"null");
+ }
+ return 0;
}
/*==========================================
* Get the information of the members of a party by type
* @party_id, @type
* return by @type :
- * - : nom des membres
- * 1 : char_id des membres
- * 2 : account_id des membres
+ * - : nom des membres
+ * 1 : char_id des membres
+ * 2 : account_id des membres
*------------------------------------------*/
BUILDIN_FUNC(getpartymember)
{
- struct party_data *p;
- int i,j=0,type=0;
-
- p=party_search(script_getnum(st,2));
-
- if (script_hasdata(st,3))
- type=script_getnum(st,3);
-
- if (p!=NULL) {
- for (i=0; i<MAX_PARTY; i++) {
- if (p->party.member[i].account_id) {
- switch (type) {
- case 2:
- mapreg_setreg(reference_uid(add_str("$@partymemberaid"), j),p->party.member[i].account_id);
- break;
- case 1:
- mapreg_setreg(reference_uid(add_str("$@partymembercid"), j),p->party.member[i].char_id);
- break;
- default:
- mapreg_setregstr(reference_uid(add_str("$@partymembername$"), j),p->party.member[i].name);
- }
- j++;
- }
- }
- }
- mapreg_setreg(add_str("$@partymembercount"),j);
+ struct party_data *p;
+ int i,j=0,type=0;
- return 0;
+ p=party_search(script_getnum(st,2));
+
+ if( script_hasdata(st,3) )
+ type=script_getnum(st,3);
+
+ if(p!=NULL){
+ for(i=0;i<MAX_PARTY;i++){
+ if(p->party.member[i].account_id){
+ switch (type) {
+ case 2:
+ mapreg_setreg(reference_uid(add_str("$@partymemberaid"), j),p->party.member[i].account_id);
+ break;
+ case 1:
+ mapreg_setreg(reference_uid(add_str("$@partymembercid"), j),p->party.member[i].char_id);
+ break;
+ default:
+ mapreg_setregstr(reference_uid(add_str("$@partymembername$"), j),p->party.member[i].name);
+ }
+ j++;
+ }
+ }
+ }
+ mapreg_setreg(add_str("$@partymembercount"),j);
+
+ return 0;
}
/*==========================================
@@ -6950,47 +7143,35 @@ BUILDIN_FUNC(getpartymember)
*------------------------------------------*/
BUILDIN_FUNC(getpartyleader)
{
- int party_id, type = 0, i=0;
- struct party_data *p;
+ int party_id, type = 0, i=0;
+ struct party_data *p;
- party_id=script_getnum(st,2);
- if (script_hasdata(st,3))
- type=script_getnum(st,3);
+ party_id=script_getnum(st,2);
+ if( script_hasdata(st,3) )
+ type=script_getnum(st,3);
- p=party_search(party_id);
+ p=party_search(party_id);
- if (p) //Search leader
- for (i = 0; i < MAX_PARTY && !p->party.member[i].leader; i++);
+ if (p) //Search leader
+ for(i = 0; i < MAX_PARTY && !p->party.member[i].leader; i++);
- if (!p || i == MAX_PARTY) { //leader not found
- if (type)
- script_pushint(st,-1);
- else
- script_pushconststr(st,"null");
- return 0;
- }
+ if (!p || i == MAX_PARTY) { //leader not found
+ if (type)
+ script_pushint(st,-1);
+ else
+ script_pushconststr(st,"null");
+ return 0;
+ }
- switch (type) {
- case 1:
- script_pushint(st,p->party.member[i].account_id);
- break;
- case 2:
- script_pushint(st,p->party.member[i].char_id);
- break;
- case 3:
- script_pushint(st,p->party.member[i].class_);
- break;
- case 4:
- script_pushstrcopy(st,mapindex_id2name(p->party.member[i].map));
- break;
- case 5:
- script_pushint(st,p->party.member[i].lv);
- break;
- default:
- script_pushstrcopy(st,p->party.member[i].name);
- break;
- }
- return 0;
+ switch (type) {
+ case 1: script_pushint(st,p->party.member[i].account_id); break;
+ case 2: script_pushint(st,p->party.member[i].char_id); break;
+ case 3: script_pushint(st,p->party.member[i].class_); break;
+ case 4: script_pushstrcopy(st,mapindex_id2name(p->party.member[i].map)); break;
+ case 5: script_pushint(st,p->party.member[i].lv); break;
+ default: script_pushstrcopy(st,p->party.member[i].name); break;
+ }
+ return 0;
}
/*==========================================
@@ -6999,17 +7180,20 @@ BUILDIN_FUNC(getpartyleader)
*------------------------------------------*/
BUILDIN_FUNC(getguildname)
{
- int guild_id;
- struct guild *g;
+ int guild_id;
+ struct guild* g;
- guild_id = script_getnum(st,2);
+ guild_id = script_getnum(st,2);
- if ((g = guild_search(guild_id)) != NULL) {
- script_pushstrcopy(st,g->name);
- } else {
- script_pushconststr(st,"null");
- }
- return 0;
+ if( ( g = guild_search(guild_id) ) != NULL )
+ {
+ script_pushstrcopy(st,g->name);
+ }
+ else
+ {
+ script_pushconststr(st,"null");
+ }
+ return 0;
}
/*==========================================
@@ -7018,137 +7202,150 @@ BUILDIN_FUNC(getguildname)
*------------------------------------------*/
BUILDIN_FUNC(getguildmaster)
{
- int guild_id;
- struct guild *g;
+ int guild_id;
+ struct guild* g;
- guild_id = script_getnum(st,2);
+ guild_id = script_getnum(st,2);
- if ((g = guild_search(guild_id)) != NULL) {
- script_pushstrcopy(st,g->member[0].name);
- } else {
- script_pushconststr(st,"null");
- }
- return 0;
+ if( ( g = guild_search(guild_id) ) != NULL )
+ {
+ script_pushstrcopy(st,g->member[0].name);
+ }
+ else
+ {
+ script_pushconststr(st,"null");
+ }
+ return 0;
}
BUILDIN_FUNC(getguildmasterid)
{
- int guild_id;
- struct guild *g;
+ int guild_id;
+ struct guild* g;
- guild_id = script_getnum(st,2);
+ guild_id = script_getnum(st,2);
- if ((g = guild_search(guild_id)) != NULL) {
- script_pushint(st,g->member[0].char_id);
- } else {
- script_pushint(st,0);
- }
- return 0;
+ if( ( g = guild_search(guild_id) ) != NULL )
+ {
+ script_pushint(st,g->member[0].char_id);
+ }
+ else
+ {
+ script_pushint(st,0);
+ }
+ return 0;
}
/*==========================================
* Get char string information by type :
* Return by @type :
- * 0 : char_name
- * 1 : party_name or ""
- * 2 : guild_name or ""
- * 3 : map_name
- * - : ""
+ * 0 : char_name
+ * 1 : party_name or ""
+ * 2 : guild_name or ""
+ * 3 : map_name
+ * - : ""
*------------------------------------------*/
BUILDIN_FUNC(strcharinfo)
{
- TBL_PC *sd;
- int num;
- struct guild *g;
- struct party_data *p;
-
- sd=script_rid2sd(st);
- if (!sd) { //Avoid crashing....
- script_pushconststr(st,"");
- return 0;
- }
- num=script_getnum(st,2);
- switch (num) {
- case 0:
- script_pushstrcopy(st,sd->status.name);
- break;
- case 1:
- if ((p = party_search(sd->status.party_id)) != NULL) {
- script_pushstrcopy(st,p->party.name);
- } else {
- script_pushconststr(st,"");
- }
- break;
- case 2:
- if ((g = guild_search(sd->status.guild_id)) != NULL) {
- script_pushstrcopy(st,g->name);
- } else {
- script_pushconststr(st,"");
- }
- break;
- case 3:
- script_pushconststr(st,map[sd->bl.m].name);
- break;
- default:
- ShowWarning("buildin_strcharinfo: unknown parameter.\n");
- script_pushconststr(st,"");
- break;
- }
-
- return 0;
+ TBL_PC *sd;
+ int num;
+ struct guild* g;
+ struct party_data* p;
+
+ sd=script_rid2sd(st);
+ if (!sd) { //Avoid crashing....
+ script_pushconststr(st,"");
+ return 0;
+ }
+ num=script_getnum(st,2);
+ switch(num){
+ case 0:
+ script_pushstrcopy(st,sd->status.name);
+ break;
+ case 1:
+ if( ( p = party_search(sd->status.party_id) ) != NULL )
+ {
+ script_pushstrcopy(st,p->party.name);
+ }
+ else
+ {
+ script_pushconststr(st,"");
+ }
+ break;
+ case 2:
+ if( ( g = guild_search(sd->status.guild_id) ) != NULL )
+ {
+ script_pushstrcopy(st,g->name);
+ }
+ else
+ {
+ script_pushconststr(st,"");
+ }
+ break;
+ case 3:
+ script_pushconststr(st,map[sd->bl.m].name);
+ break;
+ default:
+ ShowWarning("buildin_strcharinfo: unknown parameter.\n");
+ script_pushconststr(st,"");
+ break;
+ }
+
+ return 0;
}
/*==========================================
* Get npc string information by type
* return by @type:
- * 0 : name
- * 1 : str#
- * 2 : #str
- * 3 : ::str
- * 4 : map name
+ * 0 : name
+ * 1 : str#
+ * 2 : #str
+ * 3 : ::str
+ * 4 : map name
*------------------------------------------*/
BUILDIN_FUNC(strnpcinfo)
{
- TBL_NPC *nd;
- int num;
- char *buf,*name=NULL;
-
- nd = map_id2nd(st->oid);
- if (!nd) {
- script_pushconststr(st, "");
- return 0;
- }
-
- num = script_getnum(st,2);
- switch (num) {
- case 0: // display name
- name = aStrdup(nd->name);
- break;
- case 1: // visible part of display name
- if ((buf = strchr(nd->name,'#')) != NULL) {
- name = aStrdup(nd->name);
- name[buf - nd->name] = 0;
- } else // Return the name, there is no '#' present
- name = aStrdup(nd->name);
- break;
- case 2: // # fragment
- if ((buf = strchr(nd->name,'#')) != NULL)
- name = aStrdup(buf+1);
- break;
- case 3: // unique name
- name = aStrdup(nd->exname);
- break;
- case 4: // map name
- name = aStrdup(map[nd->bl.m].name);
- break;
- }
-
- if (name)
- script_pushstr(st, name);
- else
- script_pushconststr(st, "");
-
- return 0;
+ TBL_NPC* nd;
+ int num;
+ char *buf,*name=NULL;
+
+ nd = map_id2nd(st->oid);
+ if (!nd) {
+ script_pushconststr(st, "");
+ return 0;
+ }
+
+ num = script_getnum(st,2);
+ switch(num){
+ case 0: // display name
+ name = aStrdup(nd->name);
+ break;
+ case 1: // visible part of display name
+ if((buf = strchr(nd->name,'#')) != NULL)
+ {
+ name = aStrdup(nd->name);
+ name[buf - nd->name] = 0;
+ } else // Return the name, there is no '#' present
+ name = aStrdup(nd->name);
+ break;
+ case 2: // # fragment
+ if((buf = strchr(nd->name,'#')) != NULL)
+ name = aStrdup(buf+1);
+ break;
+ case 3: // unique name
+ name = aStrdup(nd->exname);
+ break;
+ case 4: // map name
+ name = aStrdup(map[nd->bl.m].name);
+ break;
+ }
+
+ if(name)
+ script_pushstr(st, name);
+ else
+ script_pushconststr(st, "");
+
+ return 0;
}
@@ -7160,34 +7357,36 @@ static unsigned int equip[] = {EQP_HEAD_TOP,EQP_ARMOR,EQP_HAND_L,EQP_HAND_R,EQP_
*------------------------------------------*/
BUILDIN_FUNC(getequipid)
{
- int i, num;
- TBL_PC *sd;
- struct item_data *item;
+ int i, num;
+ TBL_PC* sd;
+ struct item_data* item;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- num = script_getnum(st,2) - 1;
- if (num < 0 || num >= ARRAYLENGTH(equip)) {
- script_pushint(st,-1);
- return 0;
- }
+ num = script_getnum(st,2) - 1;
+ if( num < 0 || num >= ARRAYLENGTH(equip) )
+ {
+ script_pushint(st,-1);
+ return 0;
+ }
- // get inventory position of item
- i = pc_checkequip(sd,equip[num]);
- if (i < 0) {
- script_pushint(st,-1);
- return 0;
- }
+ // get inventory position of item
+ i = pc_checkequip(sd,equip[num]);
+ if( i < 0 )
+ {
+ script_pushint(st,-1);
+ return 0;
+ }
- item = sd->inventory_data[i];
- if (item != 0)
- script_pushint(st,item->nameid);
- else
- script_pushint(st,0);
+ item = sd->inventory_data[i];
+ if( item != 0 )
+ script_pushint(st,item->nameid);
+ else
+ script_pushint(st,0);
- return 0;
+ return 0;
}
/*==========================================
@@ -7196,34 +7395,36 @@ BUILDIN_FUNC(getequipid)
*------------------------------------------*/
BUILDIN_FUNC(getequipname)
{
- int i, num;
- TBL_PC *sd;
- struct item_data *item;
+ int i, num;
+ TBL_PC* sd;
+ struct item_data* item;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- num = script_getnum(st,2) - 1;
- if (num < 0 || num >= ARRAYLENGTH(equip)) {
- script_pushconststr(st,"");
- return 0;
- }
+ num = script_getnum(st,2) - 1;
+ if( num < 0 || num >= ARRAYLENGTH(equip) )
+ {
+ script_pushconststr(st,"");
+ return 0;
+ }
- // get inventory position of item
- i = pc_checkequip(sd,equip[num]);
- if (i < 0) {
- script_pushint(st,-1);
- return 0;
- }
+ // get inventory position of item
+ i = pc_checkequip(sd,equip[num]);
+ if( i < 0 )
+ {
+ script_pushint(st,-1);
+ return 0;
+ }
- item = sd->inventory_data[i];
- if (item != 0)
- script_pushstrcopy(st,item->jname);
- else
- script_pushconststr(st,"");
+ item = sd->inventory_data[i];
+ if( item != 0 )
+ script_pushstrcopy(st,item->jname);
+ else
+ script_pushconststr(st,"");
- return 0;
+ return 0;
}
/*==========================================
@@ -7231,27 +7432,27 @@ BUILDIN_FUNC(getequipname)
*------------------------------------------*/
BUILDIN_FUNC(getbrokenid)
{
- int i,num,id=0,brokencounter=0;
- TBL_PC *sd;
+ int i,num,id=0,brokencounter=0;
+ TBL_PC *sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- num=script_getnum(st,2);
- for (i=0; i<MAX_INVENTORY; i++) {
- if (sd->status.inventory[i].attribute) {
- brokencounter++;
- if (num==brokencounter) {
- id=sd->status.inventory[i].nameid;
- break;
- }
- }
- }
+ num=script_getnum(st,2);
+ for(i=0; i<MAX_INVENTORY; i++) {
+ if(sd->status.inventory[i].attribute){
+ brokencounter++;
+ if(num==brokencounter){
+ id=sd->status.inventory[i].nameid;
+ break;
+ }
+ }
+ }
- script_pushint(st,id);
+ script_pushint(st,id);
- return 0;
+ return 0;
}
/*==========================================
@@ -7259,29 +7460,29 @@ BUILDIN_FUNC(getbrokenid)
*------------------------------------------*/
BUILDIN_FUNC(repair)
{
- int i,num;
- int repaircounter=0;
- TBL_PC *sd;
+ int i,num;
+ int repaircounter=0;
+ TBL_PC *sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- num=script_getnum(st,2);
- for (i=0; i<MAX_INVENTORY; i++) {
- if (sd->status.inventory[i].attribute) {
- repaircounter++;
- if (num==repaircounter) {
- sd->status.inventory[i].attribute=0;
- clif_equiplist(sd);
- clif_produceeffect(sd, 0, sd->status.inventory[i].nameid);
- clif_misceffect(&sd->bl, 3);
- break;
- }
- }
- }
+ num=script_getnum(st,2);
+ for(i=0; i<MAX_INVENTORY; i++) {
+ if(sd->status.inventory[i].attribute){
+ repaircounter++;
+ if(num==repaircounter){
+ sd->status.inventory[i].attribute=0;
+ clif_equiplist(sd);
+ clif_produceeffect(sd, 0, sd->status.inventory[i].nameid);
+ clif_misceffect(&sd->bl, 3);
+ break;
+ }
+ }
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -7289,27 +7490,30 @@ BUILDIN_FUNC(repair)
*------------------------------------------*/
BUILDIN_FUNC(repairall)
{
- int i, repaircounter = 0;
- TBL_PC *sd;
+ int i, repaircounter = 0;
+ TBL_PC *sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ sd = script_rid2sd(st);
+ if(sd == NULL)
+ return 0;
- for (i = 0; i < MAX_INVENTORY; i++) {
- if (sd->status.inventory[i].nameid && sd->status.inventory[i].attribute) {
- sd->status.inventory[i].attribute = 0;
- clif_produceeffect(sd,0,sd->status.inventory[i].nameid);
- repaircounter++;
- }
- }
+ for(i = 0; i < MAX_INVENTORY; i++)
+ {
+ if(sd->status.inventory[i].nameid && sd->status.inventory[i].attribute)
+ {
+ sd->status.inventory[i].attribute = 0;
+ clif_produceeffect(sd,0,sd->status.inventory[i].nameid);
+ repaircounter++;
+ }
+ }
- if (repaircounter) {
- clif_misceffect(&sd->bl, 3);
- clif_equiplist(sd);
- }
+ if(repaircounter)
+ {
+ clif_misceffect(&sd->bl, 3);
+ clif_equiplist(sd);
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -7317,154 +7521,154 @@ BUILDIN_FUNC(repairall)
*------------------------------------------*/
BUILDIN_FUNC(getequipisequiped)
{
- int i = -1,num;
- TBL_PC *sd;
+ int i = -1,num;
+ TBL_PC *sd;
- num = script_getnum(st,2);
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ num = script_getnum(st,2);
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- if (num > 0 && num <= ARRAYLENGTH(equip))
- i=pc_checkequip(sd,equip[num-1]);
+ if (num > 0 && num <= ARRAYLENGTH(equip))
+ i=pc_checkequip(sd,equip[num-1]);
- if (i >= 0)
- script_pushint(st,1);
- else
- script_pushint(st,0);
- return 0;
+ if(i >= 0)
+ script_pushint(st,1);
+ else
+ script_pushint(st,0);
+ return 0;
}
/*==========================================
* Chk if the player have something equiped at pos
* if so chk if this item ain't marked not refinable or rental
* return (npc)
- * 1 : true
- * 0 : false
+ * 1 : true
+ * 0 : false
*------------------------------------------*/
BUILDIN_FUNC(getequipisenableref)
{
- int i = -1,num;
- TBL_PC *sd;
+ int i = -1,num;
+ TBL_PC *sd;
- num = script_getnum(st,2);
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ num = script_getnum(st,2);
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- if (num > 0 && num <= ARRAYLENGTH(equip))
- i = pc_checkequip(sd,equip[num-1]);
- if (i >= 0 && sd->inventory_data[i] && !sd->inventory_data[i]->flag.no_refine && !sd->status.inventory[i].expire_time)
- script_pushint(st,1);
- else
- script_pushint(st,0);
+ if( num > 0 && num <= ARRAYLENGTH(equip) )
+ i = pc_checkequip(sd,equip[num-1]);
+ if( i >= 0 && sd->inventory_data[i] && !sd->inventory_data[i]->flag.no_refine && !sd->status.inventory[i].expire_time )
+ script_pushint(st,1);
+ else
+ script_pushint(st,0);
- return 0;
+ return 0;
}
/*==========================================
* Chk if the item equiped at pos is identify (huh ?)
* return (npc)
- * 1 : true
- * 0 : false
+ * 1 : true
+ * 0 : false
*------------------------------------------*/
BUILDIN_FUNC(getequipisidentify)
{
- int i = -1,num;
- TBL_PC *sd;
+ int i = -1,num;
+ TBL_PC *sd;
- num = script_getnum(st,2);
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ num = script_getnum(st,2);
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- if (num > 0 && num <= ARRAYLENGTH(equip))
- i=pc_checkequip(sd,equip[num-1]);
- if (i >= 0)
- script_pushint(st,sd->status.inventory[i].identify);
- else
- script_pushint(st,0);
+ if (num > 0 && num <= ARRAYLENGTH(equip))
+ i=pc_checkequip(sd,equip[num-1]);
+ if(i >= 0)
+ script_pushint(st,sd->status.inventory[i].identify);
+ else
+ script_pushint(st,0);
- return 0;
+ return 0;
}
/*==========================================
* Get the item refined value at pos
* return (npc)
- * x : refine amount
- * 0 : false (not refined)
+ * x : refine amount
+ * 0 : false (not refined)
*------------------------------------------*/
BUILDIN_FUNC(getequiprefinerycnt)
{
- int i = -1,num;
- TBL_PC *sd;
+ int i = -1,num;
+ TBL_PC *sd;
- num = script_getnum(st,2);
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ num = script_getnum(st,2);
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- if (num > 0 && num <= ARRAYLENGTH(equip))
- i=pc_checkequip(sd,equip[num-1]);
- if (i >= 0)
- script_pushint(st,sd->status.inventory[i].refine);
- else
- script_pushint(st,0);
+ if (num > 0 && num <= ARRAYLENGTH(equip))
+ i=pc_checkequip(sd,equip[num-1]);
+ if(i >= 0)
+ script_pushint(st,sd->status.inventory[i].refine);
+ else
+ script_pushint(st,0);
- return 0;
+ return 0;
}
/*==========================================
* Get the weapon level value at pos
* (pos should normally only be EQI_HAND_L or EQI_HAND_R)
* return (npc)
- * x : weapon level
- * 0 : false
+ * x : weapon level
+ * 0 : false
*------------------------------------------*/
BUILDIN_FUNC(getequipweaponlv)
{
- int i = -1,num;
- TBL_PC *sd;
+ int i = -1,num;
+ TBL_PC *sd;
- num = script_getnum(st,2);
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ num = script_getnum(st,2);
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- if (num > 0 && num <= ARRAYLENGTH(equip))
- i=pc_checkequip(sd,equip[num-1]);
- if (i >= 0 && sd->inventory_data[i])
- script_pushint(st,sd->inventory_data[i]->wlv);
- else
- script_pushint(st,0);
+ if (num > 0 && num <= ARRAYLENGTH(equip))
+ i=pc_checkequip(sd,equip[num-1]);
+ if(i >= 0 && sd->inventory_data[i])
+ script_pushint(st,sd->inventory_data[i]->wlv);
+ else
+ script_pushint(st,0);
- return 0;
+ return 0;
}
/*==========================================
* Get the item refine chance (from refine.txt) for item at pos
* return (npc)
- * x : refine chance
- * 0 : false (max refine level or unequip..)
+ * x : refine chance
+ * 0 : false (max refine level or unequip..)
*------------------------------------------*/
BUILDIN_FUNC(getequippercentrefinery)
{
- int i = -1,num;
- TBL_PC *sd;
+ int i = -1,num;
+ TBL_PC *sd;
- num = script_getnum(st,2);
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ num = script_getnum(st,2);
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- if (num > 0 && num <= ARRAYLENGTH(equip))
- i=pc_checkequip(sd,equip[num-1]);
- if (i >= 0 && sd->status.inventory[i].nameid && sd->status.inventory[i].refine < MAX_REFINE)
- script_pushint(st,status_get_refine_chance(itemdb_wlv(sd->status.inventory[i].nameid), (int)sd->status.inventory[i].refine));
- else
- script_pushint(st,0);
+ if (num > 0 && num <= ARRAYLENGTH(equip))
+ i=pc_checkequip(sd,equip[num-1]);
+ if(i >= 0 && sd->status.inventory[i].nameid && sd->status.inventory[i].refine < MAX_REFINE)
+ script_pushint(st,status_get_refine_chance(itemdb_wlv(sd->status.inventory[i].nameid), (int)sd->status.inventory[i].refine));
+ else
+ script_pushint(st,0);
- return 0;
+ return 0;
}
/*==========================================
@@ -7472,53 +7676,53 @@ BUILDIN_FUNC(getequippercentrefinery)
*------------------------------------------*/
BUILDIN_FUNC(successrefitem)
{
- int i=-1,num,ep;
- TBL_PC *sd;
-
- num = script_getnum(st,2);
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
-
- if (num > 0 && num <= ARRAYLENGTH(equip))
- i=pc_checkequip(sd,equip[num-1]);
- if (i >= 0) {
- ep=sd->status.inventory[i].equip;
-
- //Logs items, got from (N)PC scripts [Lupus]
- log_pick_pc(sd, LOG_TYPE_SCRIPT, -1, &sd->status.inventory[i]);
-
- sd->status.inventory[i].refine++;
- pc_unequipitem(sd,i,2); // status calc will happen in pc_equipitem() below
-
- clif_refine(sd->fd,0,i,sd->status.inventory[i].refine);
- clif_delitem(sd,i,1,3);
-
- //Logs items, got from (N)PC scripts [Lupus]
- log_pick_pc(sd, LOG_TYPE_SCRIPT, 1, &sd->status.inventory[i]);
-
- clif_additem(sd,i,1,0);
- pc_equipitem(sd,i,ep);
- clif_misceffect(&sd->bl,3);
- if (sd->status.inventory[i].refine == MAX_REFINE &&
- sd->status.inventory[i].card[0] == CARD0_FORGE &&
- sd->status.char_id == (int)MakeDWord(sd->status.inventory[i].card[2],sd->status.inventory[i].card[3])
- ) { // Fame point system [DracoRPG]
- switch (sd->inventory_data[i]->wlv) {
- case 1:
- pc_addfame(sd,1); // Success to refine to +10 a lv1 weapon you forged = +1 fame point
- break;
- case 2:
- pc_addfame(sd,25); // Success to refine to +10 a lv2 weapon you forged = +25 fame point
- break;
- case 3:
- pc_addfame(sd,1000); // Success to refine to +10 a lv3 weapon you forged = +1000 fame point
- break;
- }
- }
- }
-
- return 0;
+ int i=-1,num,ep;
+ TBL_PC *sd;
+
+ num = script_getnum(st,2);
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
+
+ if (num > 0 && num <= ARRAYLENGTH(equip))
+ i=pc_checkequip(sd,equip[num-1]);
+ if(i >= 0) {
+ ep=sd->status.inventory[i].equip;
+
+ //Logs items, got from (N)PC scripts [Lupus]
+ log_pick_pc(sd, LOG_TYPE_SCRIPT, -1, &sd->status.inventory[i]);
+
+ sd->status.inventory[i].refine++;
+ pc_unequipitem(sd,i,2); // status calc will happen in pc_equipitem() below
+
+ clif_refine(sd->fd,0,i,sd->status.inventory[i].refine);
+ clif_delitem(sd,i,1,3);
+
+ //Logs items, got from (N)PC scripts [Lupus]
+ log_pick_pc(sd, LOG_TYPE_SCRIPT, 1, &sd->status.inventory[i]);
+
+ clif_additem(sd,i,1,0);
+ pc_equipitem(sd,i,ep);
+ clif_misceffect(&sd->bl,3);
+ if(sd->status.inventory[i].refine == MAX_REFINE &&
+ sd->status.inventory[i].card[0] == CARD0_FORGE &&
+ sd->status.char_id == (int)MakeDWord(sd->status.inventory[i].card[2],sd->status.inventory[i].card[3])
+ ){ // Fame point system [DracoRPG]
+ switch (sd->inventory_data[i]->wlv){
+ case 1:
+ pc_addfame(sd,1); // Success to refine to +10 a lv1 weapon you forged = +1 fame point
+ break;
+ case 2:
+ pc_addfame(sd,25); // Success to refine to +10 a lv2 weapon you forged = +25 fame point
+ break;
+ case 3:
+ pc_addfame(sd,1000); // Success to refine to +10 a lv3 weapon you forged = +1000 fame point
+ break;
+ }
+ }
+ }
+
+ return 0;
}
/*==========================================
@@ -7526,27 +7730,27 @@ BUILDIN_FUNC(successrefitem)
*------------------------------------------*/
BUILDIN_FUNC(failedrefitem)
{
- int i=-1,num;
- TBL_PC *sd;
+ int i=-1,num;
+ TBL_PC *sd;
- num = script_getnum(st,2);
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ num = script_getnum(st,2);
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- if (num > 0 && num <= ARRAYLENGTH(equip))
- i=pc_checkequip(sd,equip[num-1]);
- if (i >= 0) {
- sd->status.inventory[i].refine = 0;
- pc_unequipitem(sd,i,3); //recalculate bonus
- clif_refine(sd->fd,1,i,sd->status.inventory[i].refine); //notify client of failure
+ if (num > 0 && num <= ARRAYLENGTH(equip))
+ i=pc_checkequip(sd,equip[num-1]);
+ if(i >= 0) {
+ sd->status.inventory[i].refine = 0;
+ pc_unequipitem(sd,i,3); //recalculate bonus
+ clif_refine(sd->fd,1,i,sd->status.inventory[i].refine); //notify client of failure
- pc_delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT);
+ pc_delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT);
- clif_misceffect(&sd->bl,2); // display failure effect
- }
+ clif_misceffect(&sd->bl,2); // display failure effect
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -7554,37 +7758,37 @@ BUILDIN_FUNC(failedrefitem)
*------------------------------------------*/
BUILDIN_FUNC(downrefitem)
{
- int i = -1,num,ep;
- TBL_PC *sd;
+ int i = -1,num,ep;
+ TBL_PC *sd;
- num = script_getnum(st,2);
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ num = script_getnum(st,2);
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- if (num > 0 && num <= ARRAYLENGTH(equip))
- i = pc_checkequip(sd,equip[num-1]);
- if (i >= 0) {
- ep = sd->status.inventory[i].equip;
+ if (num > 0 && num <= ARRAYLENGTH(equip))
+ i = pc_checkequip(sd,equip[num-1]);
+ if(i >= 0) {
+ ep = sd->status.inventory[i].equip;
- //Logs items, got from (N)PC scripts [Lupus]
- log_pick_pc(sd, LOG_TYPE_SCRIPT, -1, &sd->status.inventory[i]);
+ //Logs items, got from (N)PC scripts [Lupus]
+ log_pick_pc(sd, LOG_TYPE_SCRIPT, -1, &sd->status.inventory[i]);
- sd->status.inventory[i].refine++;
- pc_unequipitem(sd,i,2); // status calc will happen in pc_equipitem() below
+ sd->status.inventory[i].refine++;
+ pc_unequipitem(sd,i,2); // status calc will happen in pc_equipitem() below
- clif_refine(sd->fd,2,i,sd->status.inventory[i].refine = sd->status.inventory[i].refine - 2);
- clif_delitem(sd,i,1,3);
+ clif_refine(sd->fd,2,i,sd->status.inventory[i].refine = sd->status.inventory[i].refine - 2);
+ clif_delitem(sd,i,1,3);
- //Logs items, got from (N)PC scripts [Lupus]
- log_pick_pc(sd, LOG_TYPE_SCRIPT, 1, &sd->status.inventory[i]);
+ //Logs items, got from (N)PC scripts [Lupus]
+ log_pick_pc(sd, LOG_TYPE_SCRIPT, 1, &sd->status.inventory[i]);
- clif_additem(sd,i,1,0);
- pc_equipitem(sd,i,ep);
- clif_misceffect(&sd->bl,2);
- }
+ clif_additem(sd,i,1,0);
+ pc_equipitem(sd,i,ep);
+ clif_misceffect(&sd->bl,2);
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -7592,35 +7796,35 @@ BUILDIN_FUNC(downrefitem)
*------------------------------------------*/
BUILDIN_FUNC(statusup)
{
- int type;
- TBL_PC *sd;
+ int type;
+ TBL_PC *sd;
- type=script_getnum(st,2);
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ type=script_getnum(st,2);
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- pc_statusup(sd,type);
+ pc_statusup(sd,type);
- return 0;
+ return 0;
}
/*==========================================
*
*------------------------------------------*/
BUILDIN_FUNC(statusup2)
{
- int type,val;
- TBL_PC *sd;
+ int type,val;
+ TBL_PC *sd;
- type=script_getnum(st,2);
- val=script_getnum(st,3);
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ type=script_getnum(st,2);
+ val=script_getnum(st,3);
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- pc_statusup2(sd,type,val);
+ pc_statusup2(sd,type,val);
- return 0;
+ return 0;
}
/// See 'doc/item_bonus.txt'
@@ -7632,189 +7836,192 @@ BUILDIN_FUNC(statusup2)
/// bonus5 <bonus type>,<val1>,<val2>,<val3>,<val4>,<val5>;
BUILDIN_FUNC(bonus)
{
- int type;
- int val1;
- int val2 = 0;
- int val3 = 0;
- int val4 = 0;
- int val5 = 0;
- TBL_PC *sd;
-
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0; // no player attached
-
- type = script_getnum(st,2);
- switch (type) {
- case SP_AUTOSPELL:
- case SP_AUTOSPELL_WHENHIT:
- case SP_AUTOSPELL_ONSKILL:
- case SP_SKILL_ATK:
- case SP_SKILL_HEAL:
- case SP_SKILL_HEAL2:
- case SP_ADD_SKILL_BLOW:
- case SP_CASTRATE:
- case SP_ADDEFF_ONSKILL:
- case SP_SKILL_USE_SP_RATE:
- case SP_SKILL_COOLDOWN:
- case SP_SKILL_FIXEDCAST:
- case SP_SKILL_VARIABLECAST:
- case SP_VARCASTRATE:
- case SP_SKILL_USE_SP:
- // these bonuses support skill names
- val1 = (script_isstring(st,3) ? skill_name2id(script_getstr(st,3)) : script_getnum(st,3));
- break;
- default:
- val1 = script_getnum(st,3);
- break;
- }
-
- switch (script_lastdata(st)-2) {
- case 1:
- pc_bonus(sd, type, val1);
- break;
- case 2:
- val2 = script_getnum(st,4);
- pc_bonus2(sd, type, val1, val2);
- break;
- case 3:
- val2 = script_getnum(st,4);
- val3 = script_getnum(st,5);
- pc_bonus3(sd, type, val1, val2, val3);
- break;
- case 4:
- if (type == SP_AUTOSPELL_ONSKILL && script_isstring(st,4))
- val2 = skill_name2id(script_getstr(st,4)); // 2nd value can be skill name
- else
- val2 = script_getnum(st,4);
-
- val3 = script_getnum(st,5);
- val4 = script_getnum(st,6);
- pc_bonus4(sd, type, val1, val2, val3, val4);
- break;
- case 5:
- if (type == SP_AUTOSPELL_ONSKILL && script_isstring(st,4))
- val2 = skill_name2id(script_getstr(st,4)); // 2nd value can be skill name
- else
- val2 = script_getnum(st,4);
-
- val3 = script_getnum(st,5);
- val4 = script_getnum(st,6);
- val5 = script_getnum(st,7);
- pc_bonus5(sd, type, val1, val2, val3, val4, val5);
- break;
- default:
- ShowDebug("buildin_bonus: unexpected number of arguments (%d)\n", (script_lastdata(st) - 1));
- break;
- }
-
- return 0;
+ int type;
+ int val1;
+ int val2 = 0;
+ int val3 = 0;
+ int val4 = 0;
+ int val5 = 0;
+ TBL_PC* sd;
+
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0; // no player attached
+
+ type = script_getnum(st,2);
+ switch( type ) {
+ case SP_AUTOSPELL:
+ case SP_AUTOSPELL_WHENHIT:
+ case SP_AUTOSPELL_ONSKILL:
+ case SP_SKILL_ATK:
+ case SP_SKILL_HEAL:
+ case SP_SKILL_HEAL2:
+ case SP_ADD_SKILL_BLOW:
+ case SP_CASTRATE:
+ case SP_ADDEFF_ONSKILL:
+ case SP_SKILL_USE_SP_RATE:
+ case SP_SKILL_COOLDOWN:
+ case SP_SKILL_FIXEDCAST:
+ case SP_SKILL_VARIABLECAST:
+ case SP_VARCASTRATE:
+ case SP_SKILL_USE_SP:
+ // these bonuses support skill names
+ val1 = ( script_isstring(st,3) ? skill_name2id(script_getstr(st,3)) : script_getnum(st,3) );
+ break;
+ default:
+ val1 = script_getnum(st,3);
+ break;
+ }
+
+ switch( script_lastdata(st)-2 ) {
+ case 1:
+ pc_bonus(sd, type, val1);
+ break;
+ case 2:
+ val2 = script_getnum(st,4);
+ pc_bonus2(sd, type, val1, val2);
+ break;
+ case 3:
+ val2 = script_getnum(st,4);
+ val3 = script_getnum(st,5);
+ pc_bonus3(sd, type, val1, val2, val3);
+ break;
+ case 4:
+ if( type == SP_AUTOSPELL_ONSKILL && script_isstring(st,4) )
+ val2 = skill_name2id(script_getstr(st,4)); // 2nd value can be skill name
+ else
+ val2 = script_getnum(st,4);
+
+ val3 = script_getnum(st,5);
+ val4 = script_getnum(st,6);
+ pc_bonus4(sd, type, val1, val2, val3, val4);
+ break;
+ case 5:
+ if( type == SP_AUTOSPELL_ONSKILL && script_isstring(st,4) )
+ val2 = skill_name2id(script_getstr(st,4)); // 2nd value can be skill name
+ else
+ val2 = script_getnum(st,4);
+
+ val3 = script_getnum(st,5);
+ val4 = script_getnum(st,6);
+ val5 = script_getnum(st,7);
+ pc_bonus5(sd, type, val1, val2, val3, val4, val5);
+ break;
+ default:
+ ShowDebug("buildin_bonus: unexpected number of arguments (%d)\n", (script_lastdata(st) - 1));
+ break;
+ }
+
+ return 0;
}
BUILDIN_FUNC(autobonus)
{
- unsigned int dur;
- short rate;
- short atk_type = 0;
- TBL_PC *sd;
- const char *bonus_script, *other_script = NULL;
+ unsigned int dur;
+ short rate;
+ short atk_type = 0;
+ TBL_PC* sd;
+ const char *bonus_script, *other_script = NULL;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0; // no player attached
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0; // no player attached
- if (sd->state.autobonus&sd->status.inventory[current_equip_item_index].equip)
- return 0;
+ if( sd->state.autobonus&sd->status.inventory[current_equip_item_index].equip )
+ return 0;
- rate = script_getnum(st,3);
- dur = script_getnum(st,4);
- bonus_script = script_getstr(st,2);
- if (!rate || !dur || !bonus_script)
- return 0;
+ rate = script_getnum(st,3);
+ dur = script_getnum(st,4);
+ bonus_script = script_getstr(st,2);
+ if( !rate || !dur || !bonus_script )
+ return 0;
- if (script_hasdata(st,5))
- atk_type = script_getnum(st,5);
- if (script_hasdata(st,6))
- other_script = script_getstr(st,6);
+ if( script_hasdata(st,5) )
+ atk_type = script_getnum(st,5);
+ if( script_hasdata(st,6) )
+ other_script = script_getstr(st,6);
- if (pc_addautobonus(sd->autobonus,ARRAYLENGTH(sd->autobonus),
- bonus_script,rate,dur,atk_type,other_script,sd->status.inventory[current_equip_item_index].equip,false)) {
- script_add_autobonus(bonus_script);
- if (other_script)
- script_add_autobonus(other_script);
- }
+ if( pc_addautobonus(sd->autobonus,ARRAYLENGTH(sd->autobonus),
+ bonus_script,rate,dur,atk_type,other_script,sd->status.inventory[current_equip_item_index].equip,false) )
+ {
+ script_add_autobonus(bonus_script);
+ if( other_script )
+ script_add_autobonus(other_script);
+ }
- return 0;
+ return 0;
}
BUILDIN_FUNC(autobonus2)
{
- unsigned int dur;
- short rate;
- short atk_type = 0;
- TBL_PC *sd;
- const char *bonus_script, *other_script = NULL;
+ unsigned int dur;
+ short rate;
+ short atk_type = 0;
+ TBL_PC* sd;
+ const char *bonus_script, *other_script = NULL;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0; // no player attached
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0; // no player attached
- if (sd->state.autobonus&sd->status.inventory[current_equip_item_index].equip)
- return 0;
+ if( sd->state.autobonus&sd->status.inventory[current_equip_item_index].equip )
+ return 0;
- rate = script_getnum(st,3);
- dur = script_getnum(st,4);
- bonus_script = script_getstr(st,2);
- if (!rate || !dur || !bonus_script)
- return 0;
+ rate = script_getnum(st,3);
+ dur = script_getnum(st,4);
+ bonus_script = script_getstr(st,2);
+ if( !rate || !dur || !bonus_script )
+ return 0;
- if (script_hasdata(st,5))
- atk_type = script_getnum(st,5);
- if (script_hasdata(st,6))
- other_script = script_getstr(st,6);
+ if( script_hasdata(st,5) )
+ atk_type = script_getnum(st,5);
+ if( script_hasdata(st,6) )
+ other_script = script_getstr(st,6);
- if (pc_addautobonus(sd->autobonus2,ARRAYLENGTH(sd->autobonus2),
- bonus_script,rate,dur,atk_type,other_script,sd->status.inventory[current_equip_item_index].equip,false)) {
- script_add_autobonus(bonus_script);
- if (other_script)
- script_add_autobonus(other_script);
- }
+ if( pc_addautobonus(sd->autobonus2,ARRAYLENGTH(sd->autobonus2),
+ bonus_script,rate,dur,atk_type,other_script,sd->status.inventory[current_equip_item_index].equip,false) )
+ {
+ script_add_autobonus(bonus_script);
+ if( other_script )
+ script_add_autobonus(other_script);
+ }
- return 0;
+ return 0;
}
BUILDIN_FUNC(autobonus3)
{
- unsigned int dur;
- short rate,atk_type;
- TBL_PC *sd;
- const char *bonus_script, *other_script = NULL;
+ unsigned int dur;
+ short rate,atk_type;
+ TBL_PC* sd;
+ const char *bonus_script, *other_script = NULL;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0; // no player attached
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0; // no player attached
- if (sd->state.autobonus&sd->status.inventory[current_equip_item_index].equip)
- return 0;
+ if( sd->state.autobonus&sd->status.inventory[current_equip_item_index].equip )
+ return 0;
- rate = script_getnum(st,3);
- dur = script_getnum(st,4);
- atk_type = (script_isstring(st,5) ? skill_name2id(script_getstr(st,5)) : script_getnum(st,5));
- bonus_script = script_getstr(st,2);
- if (!rate || !dur || !atk_type || !bonus_script)
- return 0;
+ rate = script_getnum(st,3);
+ dur = script_getnum(st,4);
+ atk_type = ( script_isstring(st,5) ? skill_name2id(script_getstr(st,5)) : script_getnum(st,5) );
+ bonus_script = script_getstr(st,2);
+ if( !rate || !dur || !atk_type || !bonus_script )
+ return 0;
- if (script_hasdata(st,6))
- other_script = script_getstr(st,6);
+ if( script_hasdata(st,6) )
+ other_script = script_getstr(st,6);
- if (pc_addautobonus(sd->autobonus3,ARRAYLENGTH(sd->autobonus3),
- bonus_script,rate,dur,atk_type,other_script,sd->status.inventory[current_equip_item_index].equip,true)) {
- script_add_autobonus(bonus_script);
- if (other_script)
- script_add_autobonus(other_script);
- }
+ if( pc_addautobonus(sd->autobonus3,ARRAYLENGTH(sd->autobonus3),
+ bonus_script,rate,dur,atk_type,other_script,sd->status.inventory[current_equip_item_index].equip,true) )
+ {
+ script_add_autobonus(bonus_script);
+ if( other_script )
+ script_add_autobonus(other_script);
+ }
- return 0;
+ return 0;
}
/// Changes the level of a player skill.
@@ -7829,22 +8036,22 @@ BUILDIN_FUNC(autobonus3)
/// skill "<skill name>",<level>
BUILDIN_FUNC(skill)
{
- int id;
- int level;
- int flag = 1;
- TBL_PC *sd;
+ int id;
+ int level;
+ int flag = 1;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;// no player attached, report source
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;// no player attached, report source
- id = (script_isstring(st,2) ? skill_name2id(script_getstr(st,2)) : script_getnum(st,2));
- level = script_getnum(st,3);
- if (script_hasdata(st,4))
- flag = script_getnum(st,4);
- pc_skill(sd, id, level, flag);
+ id = ( script_isstring(st,2) ? skill_name2id(script_getstr(st,2)) : script_getnum(st,2) );
+ level = script_getnum(st,3);
+ if( script_hasdata(st,4) )
+ flag = script_getnum(st,4);
+ pc_skill(sd, id, level, flag);
- return 0;
+ return 0;
}
/// Changes the level of a player skill.
@@ -7858,22 +8065,22 @@ BUILDIN_FUNC(skill)
/// @see skill
BUILDIN_FUNC(addtoskill)
{
- int id;
- int level;
- int flag = 2;
- TBL_PC *sd;
+ int id;
+ int level;
+ int flag = 2;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;// no player attached, report source
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;// no player attached, report source
- id = (script_isstring(st,2) ? skill_name2id(script_getstr(st,2)) : script_getnum(st,2));
- level = script_getnum(st,3);
- if (script_hasdata(st,4))
- flag = script_getnum(st,4);
- pc_skill(sd, id, level, flag);
+ id = ( script_isstring(st,2) ? skill_name2id(script_getstr(st,2)) : script_getnum(st,2) );
+ level = script_getnum(st,3);
+ if( script_hasdata(st,4) )
+ flag = script_getnum(st,4);
+ pc_skill(sd, id, level, flag);
- return 0;
+ return 0;
}
/// Increases the level of a guild skill.
@@ -7882,21 +8089,21 @@ BUILDIN_FUNC(addtoskill)
/// guildskill "<skill name>",<amount>;
BUILDIN_FUNC(guildskill)
{
- int id;
- int level;
- TBL_PC *sd;
- int i;
+ int id;
+ int level;
+ TBL_PC* sd;
+ int i;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;// no player attached, report source
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;// no player attached, report source
- id = (script_isstring(st,2) ? skill_name2id(script_getstr(st,2)) : script_getnum(st,2));
- level = script_getnum(st,3);
- for (i=0; i < level; i++)
- guild_skillup(sd, id);
+ id = ( script_isstring(st,2) ? skill_name2id(script_getstr(st,2)) : script_getnum(st,2) );
+ level = script_getnum(st,3);
+ for( i=0; i < level; i++ )
+ guild_skillup(sd, id);
- return 0;
+ return 0;
}
/// Returns the level of the player skill.
@@ -7905,17 +8112,17 @@ BUILDIN_FUNC(guildskill)
/// getskilllv("<skill name>") -> <level>
BUILDIN_FUNC(getskilllv)
{
- int id;
- TBL_PC *sd;
+ int id;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;// no player attached, report source
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;// no player attached, report source
- id = (script_isstring(st,2) ? skill_name2id(script_getstr(st,2)) : script_getnum(st,2));
- script_pushint(st, pc_checkskill(sd,id));
+ id = ( script_isstring(st,2) ? skill_name2id(script_getstr(st,2)) : script_getnum(st,2) );
+ script_pushint(st, pc_checkskill(sd,id));
- return 0;
+ return 0;
}
/// Returns the level of the guild skill.
@@ -7924,19 +8131,19 @@ BUILDIN_FUNC(getskilllv)
/// getgdskilllv(<guild id>,"<skill name>") -> <level>
BUILDIN_FUNC(getgdskilllv)
{
- int guild_id;
- int skill_id;
- struct guild *g;
+ int guild_id;
+ int skill_id;
+ struct guild* g;
- guild_id = script_getnum(st,2);
- skill_id = (script_isstring(st,3) ? skill_name2id(script_getstr(st,3)) : script_getnum(st,3));
- g = guild_search(guild_id);
- if (g == NULL)
- script_pushint(st, -1);
- else
- script_pushint(st, guild_checkskill(g,skill_id));
+ guild_id = script_getnum(st,2);
+ skill_id = ( script_isstring(st,3) ? skill_name2id(script_getstr(st,3)) : script_getnum(st,3) );
+ g = guild_search(guild_id);
+ if( g == NULL )
+ script_pushint(st, -1);
+ else
+ script_pushint(st, guild_checkskill(g,skill_id));
- return 0;
+ return 0;
}
/// Returns the 'basic_skill_check' setting.
@@ -7946,8 +8153,8 @@ BUILDIN_FUNC(getgdskilllv)
/// basicskillcheck() -> <bool>
BUILDIN_FUNC(basicskillcheck)
{
- script_pushint(st, battle_config.basic_skill_check);
- return 0;
+ script_pushint(st, battle_config.basic_skill_check);
+ return 0;
}
/// Returns the GM level of the player.
@@ -7955,15 +8162,15 @@ BUILDIN_FUNC(basicskillcheck)
/// getgmlevel() -> <level>
BUILDIN_FUNC(getgmlevel)
{
- TBL_PC *sd;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;// no player attached, report source
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;// no player attached, report source
- script_pushint(st, pc_get_group_level(sd));
+ script_pushint(st, pc_get_group_level(sd));
- return 0;
+ return 0;
}
/// Returns the group ID of the player.
@@ -7971,14 +8178,14 @@ BUILDIN_FUNC(getgmlevel)
/// getgroupid() -> <int>
BUILDIN_FUNC(getgroupid)
{
- TBL_PC *sd;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 1; // no player attached, report source
- script_pushint(st, pc_get_group_id(sd));
+ sd = script_rid2sd(st);
+ if (sd == NULL)
+ return 1; // no player attached, report source
+ script_pushint(st, pc_get_group_id(sd));
- return 0;
+ return 0;
}
/// Terminates the execution of this script instance.
@@ -7986,8 +8193,8 @@ BUILDIN_FUNC(getgroupid)
/// end
BUILDIN_FUNC(end)
{
- st->state = END;
- return 0;
+ st->state = END;
+ return 0;
}
/// Checks if the player has that effect state (option).
@@ -7995,20 +8202,20 @@ BUILDIN_FUNC(end)
/// checkoption(<option>) -> <bool>
BUILDIN_FUNC(checkoption)
{
- int option;
- TBL_PC *sd;
+ int option;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;// no player attached, report source
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;// no player attached, report source
- option = script_getnum(st,2);
- if (sd->sc.option&option)
- script_pushint(st, 1);
- else
- script_pushint(st, 0);
+ option = script_getnum(st,2);
+ if( sd->sc.option&option )
+ script_pushint(st, 1);
+ else
+ script_pushint(st, 0);
- return 0;
+ return 0;
}
/// Checks if the player is in that body state (opt1).
@@ -8016,20 +8223,20 @@ BUILDIN_FUNC(checkoption)
/// checkoption1(<opt1>) -> <bool>
BUILDIN_FUNC(checkoption1)
{
- int opt1;
- TBL_PC *sd;
+ int opt1;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;// no player attached, report source
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;// no player attached, report source
- opt1 = script_getnum(st,2);
- if (sd->sc.opt1 == opt1)
- script_pushint(st, 1);
- else
- script_pushint(st, 0);
+ opt1 = script_getnum(st,2);
+ if( sd->sc.opt1 == opt1 )
+ script_pushint(st, 1);
+ else
+ script_pushint(st, 0);
- return 0;
+ return 0;
}
/// Checks if the player has that health state (opt2).
@@ -8037,20 +8244,20 @@ BUILDIN_FUNC(checkoption1)
/// checkoption2(<opt2>) -> <bool>
BUILDIN_FUNC(checkoption2)
{
- int opt2;
- TBL_PC *sd;
+ int opt2;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;// no player attached, report source
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;// no player attached, report source
- opt2 = script_getnum(st,2);
- if (sd->sc.opt2&opt2)
- script_pushint(st, 1);
- else
- script_pushint(st, 0);
+ opt2 = script_getnum(st,2);
+ if( sd->sc.opt2&opt2 )
+ script_pushint(st, 1);
+ else
+ script_pushint(st, 0);
- return 0;
+ return 0;
}
/// Changes the effect state (option) of the player.
@@ -8062,32 +8269,32 @@ BUILDIN_FUNC(checkoption2)
/// setoption <option>;
BUILDIN_FUNC(setoption)
{
- int option;
- int flag = 1;
- TBL_PC *sd;
+ int option;
+ int flag = 1;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;// no player attached, report source
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;// no player attached, report source
- option = script_getnum(st,2);
- if (script_hasdata(st,3))
- flag = script_getnum(st,3);
- else if (!option) {// Request to remove everything.
- flag = 0;
- option = OPTION_FALCON|OPTION_RIDING;
+ option = script_getnum(st,2);
+ if( script_hasdata(st,3) )
+ flag = script_getnum(st,3);
+ else if( !option ){// Request to remove everything.
+ flag = 0;
+ option = OPTION_FALCON|OPTION_RIDING;
#ifndef NEW_CARTS
- option |= OPTION_CART;
+ option |= OPTION_CART;
#endif
- }
- if (flag) {// Add option
- if (option&OPTION_WEDDING && !battle_config.wedding_modifydisplay)
- option &= ~OPTION_WEDDING;// Do not show the wedding sprites
- pc_setoption(sd, sd->sc.option|option);
- } else// Remove option
- pc_setoption(sd, sd->sc.option&~option);
+ }
+ if( flag ){// Add option
+ if( option&OPTION_WEDDING && !battle_config.wedding_modifydisplay )
+ option &= ~OPTION_WEDDING;// Do not show the wedding sprites
+ pc_setoption(sd, sd->sc.option|option);
+ } else// Remove option
+ pc_setoption(sd, sd->sc.option&~option);
- return 0;
+ return 0;
}
/// Returns if the player has a cart.
@@ -8097,18 +8304,18 @@ BUILDIN_FUNC(setoption)
/// @author Valaris
BUILDIN_FUNC(checkcart)
{
- TBL_PC *sd;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;// no player attached, report source
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;// no player attached, report source
- if (pc_iscarton(sd))
- script_pushint(st, 1);
- else
- script_pushint(st, 0);
+ if( pc_iscarton(sd) )
+ script_pushint(st, 1);
+ else
+ script_pushint(st, 0);
- return 0;
+ return 0;
}
/// Sets the cart of the player.
@@ -8124,18 +8331,18 @@ BUILDIN_FUNC(checkcart)
/// setcart;
BUILDIN_FUNC(setcart)
{
- int type = 1;
- TBL_PC *sd;
+ int type = 1;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;// no player attached, report source
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;// no player attached, report source
- if (script_hasdata(st,2))
- type = script_getnum(st,2);
- pc_setcart(sd, type);
+ if( script_hasdata(st,2) )
+ type = script_getnum(st,2);
+ pc_setcart(sd, type);
- return 0;
+ return 0;
}
/// Returns if the player has a falcon.
@@ -8145,18 +8352,18 @@ BUILDIN_FUNC(setcart)
/// @author Valaris
BUILDIN_FUNC(checkfalcon)
{
- TBL_PC *sd;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;// no player attached, report source
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;// no player attached, report source
- if (pc_isfalcon(sd))
- script_pushint(st, 1);
- else
- script_pushint(st, 0);
+ if( pc_isfalcon(sd) )
+ script_pushint(st, 1);
+ else
+ script_pushint(st, 0);
- return 0;
+ return 0;
}
/// Sets if the player has a falcon or not.
@@ -8166,19 +8373,19 @@ BUILDIN_FUNC(checkfalcon)
/// setfalcon;
BUILDIN_FUNC(setfalcon)
{
- int flag = 1;
- TBL_PC *sd;
+ int flag = 1;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;// no player attached, report source
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;// no player attached, report source
- if (script_hasdata(st,2))
- flag = script_getnum(st,2);
+ if( script_hasdata(st,2) )
+ flag = script_getnum(st,2);
- pc_setfalcon(sd, flag);
+ pc_setfalcon(sd, flag);
- return 0;
+ return 0;
}
/// Returns if the player is riding.
@@ -8188,18 +8395,18 @@ BUILDIN_FUNC(setfalcon)
/// @author Valaris
BUILDIN_FUNC(checkriding)
{
- TBL_PC *sd;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;// no player attached, report source
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;// no player attached, report source
- if (pc_isriding(sd) || pc_isridingwug(sd) || pc_isridingdragon(sd))
- script_pushint(st, 1);
- else
- script_pushint(st, 0);
+ if( pc_isriding(sd) || pc_isridingwug(sd) || pc_isridingdragon(sd) )
+ script_pushint(st, 1);
+ else
+ script_pushint(st, 0);
- return 0;
+ return 0;
}
/// Sets if the player is riding.
@@ -8209,18 +8416,18 @@ BUILDIN_FUNC(checkriding)
/// setriding;
BUILDIN_FUNC(setriding)
{
- int flag = 1;
- TBL_PC *sd;
+ int flag = 1;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;// no player attached, report source
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;// no player attached, report source
- if (script_hasdata(st,2))
- flag = script_getnum(st,2);
- pc_setriding(sd, flag);
+ if( script_hasdata(st,2) )
+ flag = script_getnum(st,2);
+ pc_setriding(sd, flag);
- return 0;
+ return 0;
}
/// Returns if the player has a warg.
@@ -8229,18 +8436,18 @@ BUILDIN_FUNC(setriding)
///
BUILDIN_FUNC(checkwug)
{
- TBL_PC *sd;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;// no player attached, report source
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;// no player attached, report source
- if (pc_iswug(sd))
- script_pushint(st, 1);
- else
- script_pushint(st, 0);
+ if( pc_iswug(sd) )
+ script_pushint(st, 1);
+ else
+ script_pushint(st, 0);
- return 0;
+ return 0;
}
/// Returns if the player is wearing MADO Gear.
@@ -8249,18 +8456,18 @@ BUILDIN_FUNC(checkwug)
///
BUILDIN_FUNC(checkmadogear)
{
- TBL_PC *sd;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;// no player attached, report source
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;// no player attached, report source
- if (pc_ismadogear(sd))
- script_pushint(st, 1);
- else
- script_pushint(st, 0);
+ if( pc_ismadogear(sd) )
+ script_pushint(st, 1);
+ else
+ script_pushint(st, 0);
- return 0;
+ return 0;
}
/// Sets if the player is riding MADO Gear.
@@ -8270,18 +8477,18 @@ BUILDIN_FUNC(checkmadogear)
/// setmadogear;
BUILDIN_FUNC(setmadogear)
{
- int flag = 1;
- TBL_PC *sd;
+ int flag = 1;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;// no player attached, report source
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;// no player attached, report source
- if (script_hasdata(st,2))
- flag = script_getnum(st,2);
- pc_setmadogear(sd, flag);
+ if( script_hasdata(st,2) )
+ flag = script_getnum(st,2);
+ pc_setmadogear(sd, flag);
- return 0;
+ return 0;
}
/// Sets the save point of the player.
@@ -8290,56 +8497,56 @@ BUILDIN_FUNC(setmadogear)
/// savepoint "<map name>",<x>,<y>
BUILDIN_FUNC(savepoint)
{
- int x;
- int y;
- short map;
- const char *str;
- TBL_PC *sd;
+ int x;
+ int y;
+ short map;
+ const char* str;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;// no player attached, report source
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;// no player attached, report source
- str = script_getstr(st, 2);
- x = script_getnum(st,3);
- y = script_getnum(st,4);
- map = mapindex_name2id(str);
- if (map)
- pc_setsavepoint(sd, map, x, y);
+ str = script_getstr(st, 2);
+ x = script_getnum(st,3);
+ y = script_getnum(st,4);
+ map = mapindex_name2id(str);
+ if( map )
+ pc_setsavepoint(sd, map, x, y);
- return 0;
+ return 0;
}
/*==========================================
* GetTimeTick(0: System Tick, 1: Time Second Tick)
*------------------------------------------*/
-BUILDIN_FUNC(gettimetick) /* Asgard Version */
-{
- int type;
- time_t timer;
- struct tm *t;
-
- type=script_getnum(st,2);
-
- switch (type) {
- case 2:
- //type 2:(Get the number of seconds elapsed since 00:00 hours, Jan 1, 1970 UTC
- // from the system clock.)
- script_pushint(st,(int)time(NULL));
- break;
- case 1:
- //type 1:(Second Ticks: 0-86399, 00:00:00-23:59:59)
- time(&timer);
- t=localtime(&timer);
- script_pushint(st,((t->tm_hour)*3600+(t->tm_min)*60+t->tm_sec));
- break;
- case 0:
- default:
- //type 0:(System Ticks)
- script_pushint(st,gettick());
- break;
- }
- return 0;
+BUILDIN_FUNC(gettimetick) /* Asgard Version */
+{
+ int type;
+ time_t timer;
+ struct tm *t;
+
+ type=script_getnum(st,2);
+
+ switch(type){
+ case 2:
+ //type 2:(Get the number of seconds elapsed since 00:00 hours, Jan 1, 1970 UTC
+ // from the system clock.)
+ script_pushint(st,(int)time(NULL));
+ break;
+ case 1:
+ //type 1:(Second Ticks: 0-86399, 00:00:00-23:59:59)
+ time(&timer);
+ t=localtime(&timer);
+ script_pushint(st,((t->tm_hour)*3600+(t->tm_min)*60+t->tm_sec));
+ break;
+ case 0:
+ default:
+ //type 0:(System Ticks)
+ script_pushint(st,gettick());
+ break;
+ }
+ return 0;
}
/*==========================================
@@ -8348,47 +8555,47 @@ BUILDIN_FUNC(gettimetick) /* Asgard Version */
* 4: WeekDay 5: MonthDay 6: Month
* 7: Year
*------------------------------------------*/
-BUILDIN_FUNC(gettime) /* Asgard Version */
-{
- int type;
- time_t timer;
- struct tm *t;
-
- type=script_getnum(st,2);
-
- time(&timer);
- t=localtime(&timer);
-
- switch (type) {
- case 1://Sec(0~59)
- script_pushint(st,t->tm_sec);
- break;
- case 2://Min(0~59)
- script_pushint(st,t->tm_min);
- break;
- case 3://Hour(0~23)
- script_pushint(st,t->tm_hour);
- break;
- case 4://WeekDay(0~6)
- script_pushint(st,t->tm_wday);
- break;
- case 5://MonthDay(01~31)
- script_pushint(st,t->tm_mday);
- break;
- case 6://Month(01~12)
- script_pushint(st,t->tm_mon+1);
- break;
- case 7://Year(20xx)
- script_pushint(st,t->tm_year+1900);
- break;
- case 8://Year Day(01~366)
- script_pushint(st,t->tm_yday+1);
- break;
- default://(format error)
- script_pushint(st,-1);
- break;
- }
- return 0;
+BUILDIN_FUNC(gettime) /* Asgard Version */
+{
+ int type;
+ time_t timer;
+ struct tm *t;
+
+ type=script_getnum(st,2);
+
+ time(&timer);
+ t=localtime(&timer);
+
+ switch(type){
+ case 1://Sec(0~59)
+ script_pushint(st,t->tm_sec);
+ break;
+ case 2://Min(0~59)
+ script_pushint(st,t->tm_min);
+ break;
+ case 3://Hour(0~23)
+ script_pushint(st,t->tm_hour);
+ break;
+ case 4://WeekDay(0~6)
+ script_pushint(st,t->tm_wday);
+ break;
+ case 5://MonthDay(01~31)
+ script_pushint(st,t->tm_mday);
+ break;
+ case 6://Month(01~12)
+ script_pushint(st,t->tm_mon+1);
+ break;
+ case 7://Year(20xx)
+ script_pushint(st,t->tm_year+1900);
+ break;
+ case 8://Year Day(01~366)
+ script_pushint(st,t->tm_yday+1);
+ break;
+ default://(format error)
+ script_pushint(st,-1);
+ break;
+ }
+ return 0;
}
/*==========================================
@@ -8396,20 +8603,20 @@ BUILDIN_FUNC(gettime) /* Asgard Version */
*------------------------------------------*/
BUILDIN_FUNC(gettimestr)
{
- char *tmpstr;
- const char *fmtstr;
- int maxlen;
- time_t now = time(NULL);
+ char *tmpstr;
+ const char *fmtstr;
+ int maxlen;
+ time_t now = time(NULL);
- fmtstr=script_getstr(st,2);
- maxlen=script_getnum(st,3);
+ fmtstr=script_getstr(st,2);
+ maxlen=script_getnum(st,3);
- tmpstr=(char *)aMalloc((maxlen+1)*sizeof(char));
- strftime(tmpstr,maxlen,fmtstr,localtime(&now));
- tmpstr[maxlen]='\0';
+ tmpstr=(char *)aMalloc((maxlen+1)*sizeof(char));
+ strftime(tmpstr,maxlen,fmtstr,localtime(&now));
+ tmpstr[maxlen]='\0';
- script_pushstr(st,tmpstr);
- return 0;
+ script_pushstr(st,tmpstr);
+ return 0;
}
/*==========================================
@@ -8417,28 +8624,28 @@ BUILDIN_FUNC(gettimestr)
*------------------------------------------*/
BUILDIN_FUNC(openstorage)
{
- TBL_PC *sd;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- storage_storageopen(sd);
- return 0;
+ storage_storageopen(sd);
+ return 0;
}
BUILDIN_FUNC(guildopenstorage)
{
- TBL_PC *sd;
- int ret;
+ TBL_PC* sd;
+ int ret;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- ret = storage_guild_storageopen(sd);
- script_pushint(st,ret);
- return 0;
+ ret = storage_guild_storageopen(sd);
+ script_pushint(st,ret);
+ return 0;
}
/*==========================================
@@ -8448,108 +8655,108 @@ BUILDIN_FUNC(guildopenstorage)
/// itemskill "<skill name>",<level>
BUILDIN_FUNC(itemskill)
{
- int id;
- int lv;
- TBL_PC *sd;
+ int id;
+ int lv;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL || sd->ud.skilltimer != INVALID_TIMER)
- return 0;
+ sd = script_rid2sd(st);
+ if( sd == NULL || sd->ud.skilltimer != INVALID_TIMER )
+ return 0;
- id = (script_isstring(st,2) ? skill_name2id(script_getstr(st,2)) : script_getnum(st,2));
- lv = script_getnum(st,3);
+ id = ( script_isstring(st,2) ? skill_name2id(script_getstr(st,2)) : script_getnum(st,2) );
+ lv = script_getnum(st,3);
- sd->skillitem=id;
- sd->skillitemlv=lv;
- clif_item_skill(sd,id,lv);
- return 0;
+ sd->skillitem=id;
+ sd->skillitemlv=lv;
+ clif_item_skill(sd,id,lv);
+ return 0;
}
/*==========================================
* Attempt to create an item
*------------------------------------------*/
BUILDIN_FUNC(produce)
{
- int trigger;
- TBL_PC *sd;
+ int trigger;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- trigger=script_getnum(st,2);
- clif_skill_produce_mix_list(sd, -1, trigger);
- return 0;
+ trigger=script_getnum(st,2);
+ clif_skill_produce_mix_list(sd, -1, trigger);
+ return 0;
}
/*==========================================
*
*------------------------------------------*/
BUILDIN_FUNC(cooking)
{
- int trigger;
- TBL_PC *sd;
+ int trigger;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- trigger=script_getnum(st,2);
- clif_cooking_list(sd, trigger, AM_PHARMACY, 1, 1);
- return 0;
+ trigger=script_getnum(st,2);
+ clif_cooking_list(sd, trigger, AM_PHARMACY, 1, 1);
+ return 0;
}
/*==========================================
* Create a pet
*------------------------------------------*/
BUILDIN_FUNC(makepet)
{
- TBL_PC *sd;
- int id,pet_id;
+ TBL_PC* sd;
+ int id,pet_id;
- id=script_getnum(st,2);
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ id=script_getnum(st,2);
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- pet_id = search_petDB_index(id, PET_CLASS);
-
- 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_;
- intif_create_pet(
- sd->status.account_id, 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);
- }
+ pet_id = search_petDB_index(id, PET_CLASS);
- return 0;
+ 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_;
+ intif_create_pet(
+ sd->status.account_id, 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);
+ }
+
+ return 0;
}
/*==========================================
* Give player exp base,job * quest_exp_rate/100
*------------------------------------------*/
BUILDIN_FUNC(getexp)
{
- TBL_PC *sd;
- int base=0,job=0;
- double bonus;
+ TBL_PC* sd;
+ int base=0,job=0;
+ double bonus;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- base=script_getnum(st,2);
- job =script_getnum(st,3);
- if (base<0 || job<0)
- return 0;
+ base=script_getnum(st,2);
+ job =script_getnum(st,3);
+ if(base<0 || job<0)
+ return 0;
- // bonus for npc-given exp
- bonus = battle_config.quest_exp_rate / 100.;
- base = (int) cap_value(base * bonus, 0, INT_MAX);
- job = (int) cap_value(job * bonus, 0, INT_MAX);
+ // bonus for npc-given exp
+ bonus = battle_config.quest_exp_rate / 100.;
+ base = (int) cap_value(base * bonus, 0, INT_MAX);
+ job = (int) cap_value(job * bonus, 0, INT_MAX);
- pc_gainexp(sd, NULL, base, job, true);
+ pc_gainexp(sd, NULL, base, job, true);
- return 0;
+ return 0;
}
/*==========================================
@@ -8557,20 +8764,20 @@ BUILDIN_FUNC(getexp)
*------------------------------------------*/
BUILDIN_FUNC(guildgetexp)
{
- TBL_PC *sd;
- int exp;
+ TBL_PC* sd;
+ int exp;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- exp = script_getnum(st,2);
- if (exp < 0)
- return 0;
- if (sd && sd->status.guild_id > 0)
- guild_getexp(sd, exp);
+ exp = script_getnum(st,2);
+ if(exp < 0)
+ return 0;
+ if(sd && sd->status.guild_id > 0)
+ guild_getexp (sd, exp);
- return 0;
+ return 0;
}
/*==========================================
@@ -8578,20 +8785,20 @@ BUILDIN_FUNC(guildgetexp)
*------------------------------------------*/
BUILDIN_FUNC(guildchangegm)
{
- TBL_PC *sd;
- int guild_id;
- const char *name;
+ TBL_PC *sd;
+ int guild_id;
+ const char *name;
- guild_id = script_getnum(st,2);
- name = script_getstr(st,3);
- sd=map_nick2sd(name);
+ guild_id = script_getnum(st,2);
+ name = script_getstr(st,3);
+ sd=map_nick2sd(name);
- if (!sd)
- script_pushint(st,0);
- else
- script_pushint(st,guild_gm_change(guild_id, sd));
+ if (!sd)
+ script_pushint(st,0);
+ else
+ script_pushint(st,guild_gm_change(guild_id, sd));
- return 0;
+ return 0;
}
/*==========================================
@@ -8604,260 +8811,275 @@ BUILDIN_FUNC(guildchangegm)
*------------------------------------------*/
BUILDIN_FUNC(monster)
{
- const char *mapn = script_getstr(st,2);
- int x = script_getnum(st,3);
- int y = script_getnum(st,4);
- const char *str = script_getstr(st,5);
- int class_ = script_getnum(st,6);
- int amount = script_getnum(st,7);
- const char *event = "";
- unsigned int size = SZ_SMALL;
- unsigned int ai = AI_NONE;
-
- struct map_session_data *sd;
- int m;
-
- if (script_hasdata(st, 8)) {
- event = script_getstr(st, 8);
- check_event(st, event);
- }
-
- if (script_hasdata(st, 9)) {
- size = script_getnum(st, 9);
- if (size > 3) {
- ShowWarning("buildin_monster: Attempted to spawn non-existing size %d for monster class %d\n", size, class_);
- return 1;
- }
- }
-
- if (script_hasdata(st, 10)) {
- ai = script_getnum(st, 10);
- if (ai > 4) {
- ShowWarning("buildin_monster: Attempted to spawn non-existing ai %d for monster class %d\n", ai, class_);
- return 1;
- }
- }
-
- if (class_ >= 0 && !mobdb_checkid(class_)) {
- ShowWarning("buildin_monster: Attempted to spawn non-existing monster class %d\n", class_);
- return 1;
- }
-
- sd = map_id2sd(st->rid);
-
- if (sd && strcmp(mapn, "this") == 0)
- m = sd->bl.m;
- else {
- m = map_mapname2mapid(mapn);
- if (map[m].flag.src4instance && st->instance_id) {
- // Try to redirect to the instance map, not the src map
- if ((m = instance_mapid2imapid(m, st->instance_id)) < 0) {
- ShowError("buildin_monster: Trying to spawn monster (%d) on instance map (%s) without instance attached.\n", class_, mapn);
- return 1;
- }
- }
- }
-
- mob_once_spawn(sd, m, x, y, str, class_, amount, event, size, ai);
- return 0;
+ const char* mapn = script_getstr(st,2);
+ int x = script_getnum(st,3);
+ int y = script_getnum(st,4);
+ const char* str = script_getstr(st,5);
+ int class_ = script_getnum(st,6);
+ int amount = script_getnum(st,7);
+ const char* event = "";
+ unsigned int size = SZ_SMALL;
+ unsigned int ai = AI_NONE;
+
+ struct map_session_data* sd;
+ int m;
+
+ if (script_hasdata(st, 8))
+ {
+ event = script_getstr(st, 8);
+ check_event(st, event);
+ }
+
+ if (script_hasdata(st, 9))
+ {
+ size = script_getnum(st, 9);
+ if (size > 3)
+ {
+ ShowWarning("buildin_monster: Attempted to spawn non-existing size %d for monster class %d\n", size, class_);
+ return 1;
+ }
+ }
+
+ if (script_hasdata(st, 10))
+ {
+ ai = script_getnum(st, 10);
+ if (ai > 4)
+ {
+ ShowWarning("buildin_monster: Attempted to spawn non-existing ai %d for monster class %d\n", ai, class_);
+ return 1;
+ }
+ }
+
+ if (class_ >= 0 && !mobdb_checkid(class_))
+ {
+ ShowWarning("buildin_monster: Attempted to spawn non-existing monster class %d\n", class_);
+ return 1;
+ }
+
+ sd = map_id2sd(st->rid);
+
+ if (sd && strcmp(mapn, "this") == 0)
+ m = sd->bl.m;
+ else
+ {
+ m = map_mapname2mapid(mapn);
+ if (map[m].flag.src4instance && st->instance_id)
+ { // Try to redirect to the instance map, not the src map
+ if ((m = instance_mapid2imapid(m, st->instance_id)) < 0)
+ {
+ ShowError("buildin_monster: Trying to spawn monster (%d) on instance map (%s) without instance attached.\n", class_, mapn);
+ return 1;
+ }
+ }
+ }
+
+ mob_once_spawn(sd, m, x, y, str, class_, amount, event, size, ai);
+ return 0;
}
/*==========================================
* Request List of Monster Drops
*------------------------------------------*/
BUILDIN_FUNC(getmobdrops)
{
- int class_ = script_getnum(st,2);
- int i, j = 0;
- struct mob_db *mob;
+ int class_ = script_getnum(st,2);
+ int i, j = 0;
+ struct mob_db *mob;
- if (!mobdb_checkid(class_)) {
- script_pushint(st, 0);
- return 0;
- }
+ if( !mobdb_checkid(class_) )
+ {
+ script_pushint(st, 0);
+ return 0;
+ }
- mob = mob_db(class_);
+ mob = mob_db(class_);
- for (i = 0; i < MAX_MOB_DROP; i++) {
- if (mob->dropitem[i].nameid < 1)
- continue;
- if (itemdb_exists(mob->dropitem[i].nameid) == NULL)
- continue;
+ for( i = 0; i < MAX_MOB_DROP; i++ )
+ {
+ if( mob->dropitem[i].nameid < 1 )
+ continue;
+ if( itemdb_exists(mob->dropitem[i].nameid) == NULL )
+ continue;
- mapreg_setreg(reference_uid(add_str("$@MobDrop_item"), j), mob->dropitem[i].nameid);
- mapreg_setreg(reference_uid(add_str("$@MobDrop_rate"), j), mob->dropitem[i].p);
+ mapreg_setreg(reference_uid(add_str("$@MobDrop_item"), j), mob->dropitem[i].nameid);
+ mapreg_setreg(reference_uid(add_str("$@MobDrop_rate"), j), mob->dropitem[i].p);
- j++;
- }
+ j++;
+ }
- mapreg_setreg(add_str("$@MobDrop_count"), j);
- script_pushint(st, 1);
+ mapreg_setreg(add_str("$@MobDrop_count"), j);
+ script_pushint(st, 1);
- return 0;
+ return 0;
}
/*==========================================
* Same as monster but randomize location in x0,x1,y0,y1 area
*------------------------------------------*/
BUILDIN_FUNC(areamonster)
{
- const char *mapn = script_getstr(st,2);
- int x0 = script_getnum(st,3);
- int y0 = script_getnum(st,4);
- int x1 = script_getnum(st,5);
- int y1 = script_getnum(st,6);
- const char *str = script_getstr(st,7);
- int class_ = script_getnum(st,8);
- int amount = script_getnum(st,9);
- const char *event = "";
- unsigned int size = SZ_SMALL;
- unsigned int ai = AI_NONE;
-
- struct map_session_data *sd;
- int m;
-
- if (script_hasdata(st,10)) {
- event = script_getstr(st, 10);
- check_event(st, event);
- }
-
- if (script_hasdata(st, 11)) {
- size = script_getnum(st, 11);
- if (size > 3) {
- ShowWarning("buildin_monster: Attempted to spawn non-existing size %d for monster class %d\n", size, class_);
- return 1;
- }
- }
-
- if (script_hasdata(st, 12)) {
- ai = script_getnum(st, 12);
- if (ai > 4) {
- ShowWarning("buildin_monster: Attempted to spawn non-existing ai %d for monster class %d\n", ai, class_);
- return 1;
- }
- }
-
- sd = map_id2sd(st->rid);
-
- if (sd && strcmp(mapn, "this") == 0)
- m = sd->bl.m;
- else {
- m = map_mapname2mapid(mapn);
- if (map[m].flag.src4instance && st->instance_id) {
- // Try to redirect to the instance map, not the src map
- if ((m = instance_mapid2imapid(m, st->instance_id)) < 0) {
- ShowError("buildin_areamonster: Trying to spawn monster (%d) on instance map (%s) without instance attached.\n", class_, mapn);
- return 1;
- }
- }
- }
-
- mob_once_spawn_area(sd, m, x0, y0, x1, y1, str, class_, amount, event, size, ai);
- return 0;
+ const char* mapn = script_getstr(st,2);
+ int x0 = script_getnum(st,3);
+ int y0 = script_getnum(st,4);
+ int x1 = script_getnum(st,5);
+ int y1 = script_getnum(st,6);
+ const char* str = script_getstr(st,7);
+ int class_ = script_getnum(st,8);
+ int amount = script_getnum(st,9);
+ const char* event = "";
+ unsigned int size = SZ_SMALL;
+ unsigned int ai = AI_NONE;
+
+ struct map_session_data* sd;
+ int m;
+
+ if (script_hasdata(st,10))
+ {
+ event = script_getstr(st, 10);
+ check_event(st, event);
+ }
+
+ if (script_hasdata(st, 11))
+ {
+ size = script_getnum(st, 11);
+ if (size > 3)
+ {
+ ShowWarning("buildin_monster: Attempted to spawn non-existing size %d for monster class %d\n", size, class_);
+ return 1;
+ }
+ }
+
+ if (script_hasdata(st, 12))
+ {
+ ai = script_getnum(st, 12);
+ if (ai > 4)
+ {
+ ShowWarning("buildin_monster: Attempted to spawn non-existing ai %d for monster class %d\n", ai, class_);
+ return 1;
+ }
+ }
+
+ sd = map_id2sd(st->rid);
+
+ if (sd && strcmp(mapn, "this") == 0)
+ m = sd->bl.m;
+ else
+ {
+ m = map_mapname2mapid(mapn);
+ if (map[m].flag.src4instance && st->instance_id)
+ { // Try to redirect to the instance map, not the src map
+ if ((m = instance_mapid2imapid(m, st->instance_id)) < 0)
+ {
+ ShowError("buildin_areamonster: Trying to spawn monster (%d) on instance map (%s) without instance attached.\n", class_, mapn);
+ return 1;
+ }
+ }
+ }
+
+ mob_once_spawn_area(sd, m, x0, y0, x1, y1, str, class_, amount, event, size, ai);
+ return 0;
}
/*==========================================
* KillMonster subcheck, verify if mob to kill ain't got an even to handle, could be force kill by allflag
*------------------------------------------*/
-static int buildin_killmonster_sub_strip(struct block_list *bl,va_list ap)
-{
- //same fix but with killmonster instead - stripping events from mobs.
- TBL_MOB *md = (TBL_MOB *)bl;
- char *event=va_arg(ap,char *);
- int allflag=va_arg(ap,int);
-
- md->state.npc_killmonster = 1;
-
- if (!allflag) {
- if (strcmp(event,md->npc_event)==0)
- status_kill(bl);
- } else {
- if (!md->spawn)
- status_kill(bl);
- }
- md->state.npc_killmonster = 0;
- return 0;
+ static int buildin_killmonster_sub_strip(struct block_list *bl,va_list ap)
+{ //same fix but with killmonster instead - stripping events from mobs.
+ TBL_MOB* md = (TBL_MOB*)bl;
+ char *event=va_arg(ap,char *);
+ int allflag=va_arg(ap,int);
+
+ md->state.npc_killmonster = 1;
+
+ if(!allflag){
+ if(strcmp(event,md->npc_event)==0)
+ status_kill(bl);
+ }else{
+ if(!md->spawn)
+ status_kill(bl);
+ }
+ md->state.npc_killmonster = 0;
+ return 0;
}
static int buildin_killmonster_sub(struct block_list *bl,va_list ap)
{
- TBL_MOB *md = (TBL_MOB *)bl;
- char *event=va_arg(ap,char *);
- int allflag=va_arg(ap,int);
+ TBL_MOB* md = (TBL_MOB*)bl;
+ char *event=va_arg(ap,char *);
+ int allflag=va_arg(ap,int);
- if (!allflag) {
- if (strcmp(event,md->npc_event)==0)
- status_kill(bl);
- } else {
- if (!md->spawn)
- status_kill(bl);
- }
- return 0;
+ if(!allflag){
+ if(strcmp(event,md->npc_event)==0)
+ status_kill(bl);
+ }else{
+ if(!md->spawn)
+ status_kill(bl);
+ }
+ return 0;
}
BUILDIN_FUNC(killmonster)
{
- const char *mapname,*event;
- int m,allflag=0;
- mapname=script_getstr(st,2);
- event=script_getstr(st,3);
- if (strcmp(event,"All")==0)
- allflag = 1;
- else
- check_event(st, event);
+ const char *mapname,*event;
+ int m,allflag=0;
+ mapname=script_getstr(st,2);
+ event=script_getstr(st,3);
+ if(strcmp(event,"All")==0)
+ allflag = 1;
+ else
+ check_event(st, event);
- if ((m=map_mapname2mapid(mapname))<0)
- return 0;
+ if( (m=map_mapname2mapid(mapname))<0 )
+ return 0;
- if (map[m].flag.src4instance && st->instance_id && (m = instance_mapid2imapid(m, st->instance_id)) < 0)
- return 0;
+ if( map[m].flag.src4instance && st->instance_id && (m = instance_mapid2imapid(m, st->instance_id)) < 0 )
+ return 0;
- if (script_hasdata(st,4)) {
- if (script_getnum(st,4) == 1) {
- map_foreachinmap(buildin_killmonster_sub, m, BL_MOB, event ,allflag);
- return 0;
- }
- }
+ if( script_hasdata(st,4) ) {
+ if ( script_getnum(st,4) == 1 ) {
+ map_foreachinmap(buildin_killmonster_sub, m, BL_MOB, event ,allflag);
+ return 0;
+ }
+ }
- map_freeblock_lock();
- map_foreachinmap(buildin_killmonster_sub_strip, m, BL_MOB, event ,allflag);
- map_freeblock_unlock();
- return 0;
+ map_freeblock_lock();
+ map_foreachinmap(buildin_killmonster_sub_strip, m, BL_MOB, event ,allflag);
+ map_freeblock_unlock();
+ return 0;
}
static int buildin_killmonsterall_sub_strip(struct block_list *bl,va_list ap)
-{
- //Strips the event from the mob if it's killed the old method.
- struct mob_data *md;
+{ //Strips the event from the mob if it's killed the old method.
+ struct mob_data *md;
- md = BL_CAST(BL_MOB, bl);
- if (md->npc_event[0])
- md->npc_event[0] = 0;
+ md = BL_CAST(BL_MOB, bl);
+ if (md->npc_event[0])
+ md->npc_event[0] = 0;
- status_kill(bl);
- return 0;
+ status_kill(bl);
+ return 0;
}
static int buildin_killmonsterall_sub(struct block_list *bl,va_list ap)
{
- status_kill(bl);
- return 0;
+ status_kill(bl);
+ return 0;
}
BUILDIN_FUNC(killmonsterall)
{
- const char *mapname;
- int m;
- mapname=script_getstr(st,2);
+ const char *mapname;
+ int m;
+ mapname=script_getstr(st,2);
- if ((m = map_mapname2mapid(mapname))<0)
- return 0;
+ if( (m = map_mapname2mapid(mapname))<0 )
+ return 0;
- if (map[m].flag.src4instance && st->instance_id && (m = instance_mapid2imapid(m, st->instance_id)) < 0)
- return 0;
+ if( map[m].flag.src4instance && st->instance_id && (m = instance_mapid2imapid(m, st->instance_id)) < 0 )
+ return 0;
- if (script_hasdata(st,3)) {
- if (script_getnum(st,3) == 1) {
- map_foreachinmap(buildin_killmonsterall_sub,m,BL_MOB);
- return 0;
- }
- }
+ if( script_hasdata(st,3) ) {
+ if ( script_getnum(st,3) == 1 ) {
+ map_foreachinmap(buildin_killmonsterall_sub,m,BL_MOB);
+ return 0;
+ }
+ }
- map_foreachinmap(buildin_killmonsterall_sub_strip,m,BL_MOB);
- return 0;
+ map_foreachinmap(buildin_killmonsterall_sub_strip,m,BL_MOB);
+ return 0;
}
/*==========================================
@@ -8866,327 +9088,347 @@ BUILDIN_FUNC(killmonsterall)
*------------------------------------------*/
BUILDIN_FUNC(clone)
{
- TBL_PC *sd, *msd=NULL;
- int char_id,master_id=0,x,y, mode = 0, flag = 0, m;
- unsigned int duration = 0;
- const char *map,*event="";
+ TBL_PC *sd, *msd=NULL;
+ int char_id,master_id=0,x,y, mode = 0, flag = 0, m;
+ unsigned int duration = 0;
+ const char *map,*event="";
- map=script_getstr(st,2);
- x=script_getnum(st,3);
- y=script_getnum(st,4);
- event=script_getstr(st,5);
- char_id=script_getnum(st,6);
+ map=script_getstr(st,2);
+ x=script_getnum(st,3);
+ y=script_getnum(st,4);
+ event=script_getstr(st,5);
+ char_id=script_getnum(st,6);
- if (script_hasdata(st,7))
- master_id=script_getnum(st,7);
+ if( script_hasdata(st,7) )
+ master_id=script_getnum(st,7);
- if (script_hasdata(st,8))
- mode=script_getnum(st,8);
+ if( script_hasdata(st,8) )
+ mode=script_getnum(st,8);
- if (script_hasdata(st,9))
- flag=script_getnum(st,9);
+ if( script_hasdata(st,9) )
+ flag=script_getnum(st,9);
- if (script_hasdata(st,10))
- duration=script_getnum(st,10);
+ if( script_hasdata(st,10) )
+ duration=script_getnum(st,10);
- check_event(st, event);
+ check_event(st, event);
- m = map_mapname2mapid(map);
- if (m < 0) return 0;
+ m = map_mapname2mapid(map);
+ if (m < 0) return 0;
- sd = map_charid2sd(char_id);
+ sd = map_charid2sd(char_id);
- if (master_id) {
- msd = map_charid2sd(master_id);
- if (msd)
- master_id = msd->bl.id;
- else
- master_id = 0;
- }
- if (sd) //Return ID of newly crafted clone.
- script_pushint(st,mob_clone_spawn(sd, m, x, y, event, master_id, mode, flag, 1000*duration));
- else //Failed to create clone.
- script_pushint(st,0);
+ if (master_id) {
+ msd = map_charid2sd(master_id);
+ if (msd)
+ master_id = msd->bl.id;
+ else
+ master_id = 0;
+ }
+ if (sd) //Return ID of newly crafted clone.
+ script_pushint(st,mob_clone_spawn(sd, m, x, y, event, master_id, mode, flag, 1000*duration));
+ else //Failed to create clone.
+ script_pushint(st,0);
- return 0;
+ return 0;
}
/*==========================================
*------------------------------------------*/
BUILDIN_FUNC(doevent)
{
- const char *event = script_getstr(st,2);
- struct map_session_data *sd;
+ const char* event = script_getstr(st,2);
+ struct map_session_data* sd;
- if ((sd = script_rid2sd(st)) == NULL) {
- return 0;
- }
+ if( ( sd = script_rid2sd(st) ) == NULL )
+ {
+ return 0;
+ }
- check_event(st, event);
- npc_event(sd, event, 0);
- return 0;
+ check_event(st, event);
+ npc_event(sd, event, 0);
+ return 0;
}
/*==========================================
*------------------------------------------*/
BUILDIN_FUNC(donpcevent)
{
- const char *event = script_getstr(st,2);
- check_event(st, event);
- if (!npc_event_do(event)) {
- struct npc_data *nd = map_id2nd(st->oid);
- ShowDebug("NPCEvent '%s' not found! (source: %s)\n",event,nd?nd->name:"Unknown");
- script_pushint(st, 0);
- } else
- script_pushint(st, 1);
- return 0;
+ const char* event = script_getstr(st,2);
+ check_event(st, event);
+ if( !npc_event_do(event) ) {
+ struct npc_data * nd = map_id2nd(st->oid);
+ ShowDebug("NPCEvent '%s' not found! (source: %s)\n",event,nd?nd->name:"Unknown");
+ script_pushint(st, 0);
+ } else
+ script_pushint(st, 1);
+ return 0;
}
/// for Aegis compatibility
/// basically a specialized 'donpcevent', with the event specified as two arguments instead of one
-BUILDIN_FUNC(cmdothernpc) // Added by RoVeRT
-{
- const char *npc = script_getstr(st,2);
- const char *command = script_getstr(st,3);
- char event[EVENT_NAME_LENGTH];
- snprintf(event, sizeof(event), "%s::OnCommand%s", npc, command);
- check_event(st, event);
- npc_event_do(event);
- return 0;
+BUILDIN_FUNC(cmdothernpc) // Added by RoVeRT
+{
+ const char* npc = script_getstr(st,2);
+ const char* command = script_getstr(st,3);
+ char event[EVENT_NAME_LENGTH];
+ snprintf(event, sizeof(event), "%s::OnCommand%s", npc, command);
+ check_event(st, event);
+ npc_event_do(event);
+ return 0;
}
/*==========================================
*------------------------------------------*/
BUILDIN_FUNC(addtimer)
{
- int tick = script_getnum(st,2);
- const char *event = script_getstr(st, 3);
- TBL_PC *sd;
+ int tick = script_getnum(st,2);
+ const char* event = script_getstr(st, 3);
+ TBL_PC* sd;
- check_event(st, event);
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ check_event(st, event);
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- pc_addeventtimer(sd,tick,event);
- return 0;
+ pc_addeventtimer(sd,tick,event);
+ return 0;
}
/*==========================================
*------------------------------------------*/
BUILDIN_FUNC(deltimer)
{
- const char *event;
- TBL_PC *sd;
+ const char *event;
+ TBL_PC* sd;
- event=script_getstr(st, 2);
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ event=script_getstr(st, 2);
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- check_event(st, event);
- pc_deleventtimer(sd,event);
- return 0;
+ check_event(st, event);
+ pc_deleventtimer(sd,event);
+ return 0;
}
/*==========================================
*------------------------------------------*/
BUILDIN_FUNC(addtimercount)
{
- const char *event;
- int tick;
- TBL_PC *sd;
+ const char *event;
+ int tick;
+ TBL_PC* sd;
- event=script_getstr(st, 2);
- tick=script_getnum(st,3);
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ event=script_getstr(st, 2);
+ tick=script_getnum(st,3);
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- check_event(st, event);
- pc_addeventtimercount(sd,event,tick);
- return 0;
+ check_event(st, event);
+ pc_addeventtimercount(sd,event,tick);
+ return 0;
}
/*==========================================
*------------------------------------------*/
BUILDIN_FUNC(initnpctimer)
{
- struct npc_data *nd;
- int flag = 0;
-
- if (script_hasdata(st,3)) {
- //Two arguments: NPC name and attach flag.
- nd = npc_name2id(script_getstr(st, 2));
- flag = script_getnum(st,3);
- } else if (script_hasdata(st,2)) {
- //Check if argument is numeric (flag) or string (npc name)
- struct script_data *data;
- data = script_getdata(st,2);
- get_val(st,data);
- if (data_isstring(data)) //NPC name
- nd = npc_name2id(conv_str(st, data));
- else if (data_isint(data)) { //Flag
- nd = (struct npc_data *)map_id2bl(st->oid);
- flag = conv_num(st,data);
- } else {
- ShowError("initnpctimer: invalid argument type #1 (needs be int or string)).\n");
- return 1;
- }
- } else
- nd = (struct npc_data *)map_id2bl(st->oid);
-
- if (!nd)
- return 0;
- if (flag) { //Attach
- TBL_PC *sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
- nd->u.scr.rid = sd->bl.id;
- }
-
- nd->u.scr.timertick = 0;
- npc_settimerevent_tick(nd,0);
- npc_timerevent_start(nd, st->rid);
- return 0;
+ struct npc_data *nd;
+ int flag = 0;
+
+ if( script_hasdata(st,3) )
+ { //Two arguments: NPC name and attach flag.
+ nd = npc_name2id(script_getstr(st, 2));
+ flag = script_getnum(st,3);
+ }
+ else if( script_hasdata(st,2) )
+ { //Check if argument is numeric (flag) or string (npc name)
+ struct script_data *data;
+ data = script_getdata(st,2);
+ get_val(st,data);
+ if( data_isstring(data) ) //NPC name
+ nd = npc_name2id(conv_str(st, data));
+ else if( data_isint(data) ) //Flag
+ {
+ nd = (struct npc_data *)map_id2bl(st->oid);
+ flag = conv_num(st,data);
+ }
+ else
+ {
+ ShowError("initnpctimer: invalid argument type #1 (needs be int or string)).\n");
+ return 1;
+ }
+ }
+ else
+ nd = (struct npc_data *)map_id2bl(st->oid);
+
+ if( !nd )
+ return 0;
+ if( flag ) //Attach
+ {
+ TBL_PC* sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
+ nd->u.scr.rid = sd->bl.id;
+ }
+
+ nd->u.scr.timertick = 0;
+ npc_settimerevent_tick(nd,0);
+ npc_timerevent_start(nd, st->rid);
+ return 0;
}
/*==========================================
*------------------------------------------*/
BUILDIN_FUNC(startnpctimer)
{
- struct npc_data *nd;
- int flag = 0;
-
- if (script_hasdata(st,3)) {
- //Two arguments: NPC name and attach flag.
- nd = npc_name2id(script_getstr(st, 2));
- flag = script_getnum(st,3);
- } else if (script_hasdata(st,2)) {
- //Check if argument is numeric (flag) or string (npc name)
- struct script_data *data;
- data = script_getdata(st,2);
- get_val(st,data);
- if (data_isstring(data)) //NPC name
- nd = npc_name2id(conv_str(st, data));
- else if (data_isint(data)) { //Flag
- nd = (struct npc_data *)map_id2bl(st->oid);
- flag = conv_num(st,data);
- } else {
- ShowError("initnpctimer: invalid argument type #1 (needs be int or string)).\n");
- return 1;
- }
- } else
- nd=(struct npc_data *)map_id2bl(st->oid);
-
- if (!nd)
- return 0;
- if (flag) { //Attach
- TBL_PC *sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
- nd->u.scr.rid = sd->bl.id;
- }
-
- npc_timerevent_start(nd, st->rid);
- return 0;
+ struct npc_data *nd;
+ int flag = 0;
+
+ if( script_hasdata(st,3) )
+ { //Two arguments: NPC name and attach flag.
+ nd = npc_name2id(script_getstr(st, 2));
+ flag = script_getnum(st,3);
+ }
+ else if( script_hasdata(st,2) )
+ { //Check if argument is numeric (flag) or string (npc name)
+ struct script_data *data;
+ data = script_getdata(st,2);
+ get_val(st,data);
+ if( data_isstring(data) ) //NPC name
+ nd = npc_name2id(conv_str(st, data));
+ else if( data_isint(data) ) //Flag
+ {
+ nd = (struct npc_data *)map_id2bl(st->oid);
+ flag = conv_num(st,data);
+ }
+ else
+ {
+ ShowError("initnpctimer: invalid argument type #1 (needs be int or string)).\n");
+ return 1;
+ }
+ }
+ else
+ nd=(struct npc_data *)map_id2bl(st->oid);
+
+ if( !nd )
+ return 0;
+ if( flag ) //Attach
+ {
+ TBL_PC* sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
+ nd->u.scr.rid = sd->bl.id;
+ }
+
+ npc_timerevent_start(nd, st->rid);
+ return 0;
}
/*==========================================
*------------------------------------------*/
BUILDIN_FUNC(stopnpctimer)
{
- struct npc_data *nd;
- int flag = 0;
-
- if (script_hasdata(st,3)) {
- //Two arguments: NPC name and attach flag.
- nd = npc_name2id(script_getstr(st, 2));
- flag = script_getnum(st,3);
- } else if (script_hasdata(st,2)) {
- //Check if argument is numeric (flag) or string (npc name)
- struct script_data *data;
- data = script_getdata(st,2);
- get_val(st,data);
- if (data_isstring(data)) //NPC name
- nd = npc_name2id(conv_str(st, data));
- else if (data_isint(data)) { //Flag
- nd = (struct npc_data *)map_id2bl(st->oid);
- flag = conv_num(st,data);
- } else {
- ShowError("initnpctimer: invalid argument type #1 (needs be int or string)).\n");
- return 1;
- }
- } else
- nd=(struct npc_data *)map_id2bl(st->oid);
-
- if (!nd)
- return 0;
- if (flag) //Detach
- nd->u.scr.rid = 0;
-
- npc_timerevent_stop(nd);
- return 0;
+ struct npc_data *nd;
+ int flag = 0;
+
+ if( script_hasdata(st,3) )
+ { //Two arguments: NPC name and attach flag.
+ nd = npc_name2id(script_getstr(st, 2));
+ flag = script_getnum(st,3);
+ }
+ else if( script_hasdata(st,2) )
+ { //Check if argument is numeric (flag) or string (npc name)
+ struct script_data *data;
+ data = script_getdata(st,2);
+ get_val(st,data);
+ if( data_isstring(data) ) //NPC name
+ nd = npc_name2id(conv_str(st, data));
+ else if( data_isint(data) ) //Flag
+ {
+ nd = (struct npc_data *)map_id2bl(st->oid);
+ flag = conv_num(st,data);
+ }
+ else
+ {
+ ShowError("initnpctimer: invalid argument type #1 (needs be int or string)).\n");
+ return 1;
+ }
+ }
+ else
+ nd=(struct npc_data *)map_id2bl(st->oid);
+
+ if( !nd )
+ return 0;
+ if( flag ) //Detach
+ nd->u.scr.rid = 0;
+
+ npc_timerevent_stop(nd);
+ return 0;
}
/*==========================================
*------------------------------------------*/
BUILDIN_FUNC(getnpctimer)
{
- struct npc_data *nd;
- TBL_PC *sd;
- int type = script_getnum(st,2);
- int val = 0;
-
- if (script_hasdata(st,3))
- nd = npc_name2id(script_getstr(st,3));
- else
- nd = (struct npc_data *)map_id2bl(st->oid);
-
- if (!nd || nd->bl.type != BL_NPC) {
- script_pushint(st,0);
- ShowError("getnpctimer: Invalid NPC.\n");
- return 1;
- }
-
- switch (type) {
- case 0:
- val = npc_gettimerevent_tick(nd);
- break;
- case 1:
- if (nd->u.scr.rid) {
- sd = map_id2sd(nd->u.scr.rid);
- if (!sd) {
- ShowError("buildin_getnpctimer: Attached player not found!\n");
- break;
- }
- val = (sd->npc_timer_id != INVALID_TIMER);
- } else
- val = (nd->u.scr.timerid != INVALID_TIMER);
- break;
- case 2:
- val = nd->u.scr.timeramount;
- break;
- }
-
- script_pushint(st,val);
- return 0;
+ struct npc_data *nd;
+ TBL_PC *sd;
+ int type = script_getnum(st,2);
+ int val = 0;
+
+ if( script_hasdata(st,3) )
+ nd = npc_name2id(script_getstr(st,3));
+ else
+ nd = (struct npc_data *)map_id2bl(st->oid);
+
+ if( !nd || nd->bl.type != BL_NPC )
+ {
+ script_pushint(st,0);
+ ShowError("getnpctimer: Invalid NPC.\n");
+ return 1;
+ }
+
+ switch( type )
+ {
+ case 0: val = npc_gettimerevent_tick(nd); break;
+ case 1:
+ if( nd->u.scr.rid )
+ {
+ sd = map_id2sd(nd->u.scr.rid);
+ if( !sd )
+ {
+ ShowError("buildin_getnpctimer: Attached player not found!\n");
+ break;
+ }
+ val = (sd->npc_timer_id != INVALID_TIMER);
+ }
+ else
+ val = (nd->u.scr.timerid != INVALID_TIMER);
+ break;
+ case 2: val = nd->u.scr.timeramount; break;
+ }
+
+ script_pushint(st,val);
+ return 0;
}
/*==========================================
*------------------------------------------*/
BUILDIN_FUNC(setnpctimer)
{
- int tick;
- struct npc_data *nd;
+ int tick;
+ struct npc_data *nd;
- tick = script_getnum(st,2);
- if (script_hasdata(st,3))
- nd = npc_name2id(script_getstr(st,3));
- else
- nd = (struct npc_data *)map_id2bl(st->oid);
+ tick = script_getnum(st,2);
+ if( script_hasdata(st,3) )
+ nd = npc_name2id(script_getstr(st,3));
+ else
+ nd = (struct npc_data *)map_id2bl(st->oid);
- if (!nd || nd->bl.type != BL_NPC) {
- script_pushint(st,1);
- ShowError("setnpctimer: Invalid NPC.\n");
- return 1;
- }
+ if( !nd || nd->bl.type != BL_NPC )
+ {
+ script_pushint(st,1);
+ ShowError("setnpctimer: Invalid NPC.\n");
+ return 1;
+ }
- npc_settimerevent_tick(nd,tick);
- script_pushint(st,0);
- return 0;
+ npc_settimerevent_tick(nd,tick);
+ script_pushint(st,0);
+ return 0;
}
/*==========================================
@@ -9194,29 +9436,31 @@ BUILDIN_FUNC(setnpctimer)
*------------------------------------------*/
BUILDIN_FUNC(attachnpctimer)
{
- TBL_PC *sd;
- struct npc_data *nd = (struct npc_data *)map_id2bl(st->oid);
+ TBL_PC *sd;
+ struct npc_data *nd = (struct npc_data *)map_id2bl(st->oid);
- if (!nd || nd->bl.type != BL_NPC) {
- script_pushint(st,1);
- ShowError("setnpctimer: Invalid NPC.\n");
- return 1;
- }
+ if( !nd || nd->bl.type != BL_NPC )
+ {
+ script_pushint(st,1);
+ ShowError("setnpctimer: Invalid NPC.\n");
+ return 1;
+ }
- if (script_hasdata(st,2))
- sd = map_nick2sd(script_getstr(st,2));
- else
- sd = script_rid2sd(st);
+ if( script_hasdata(st,2) )
+ sd = map_nick2sd(script_getstr(st,2));
+ else
+ sd = script_rid2sd(st);
- if (!sd) {
- script_pushint(st,1);
- ShowWarning("attachnpctimer: Invalid player.\n");
- return 1;
- }
+ if( !sd )
+ {
+ script_pushint(st,1);
+ ShowWarning("attachnpctimer: Invalid player.\n");
+ return 1;
+ }
- nd->u.scr.rid = sd->bl.id;
- script_pushint(st,0);
- return 0;
+ nd->u.scr.rid = sd->bl.id;
+ script_pushint(st,0);
+ return 0;
}
/*==========================================
@@ -9224,22 +9468,23 @@ BUILDIN_FUNC(attachnpctimer)
*------------------------------------------*/
BUILDIN_FUNC(detachnpctimer)
{
- struct npc_data *nd;
+ struct npc_data *nd;
- if (script_hasdata(st,2))
- nd = npc_name2id(script_getstr(st,2));
- else
- nd = (struct npc_data *)map_id2bl(st->oid);
+ if( script_hasdata(st,2) )
+ nd = npc_name2id(script_getstr(st,2));
+ else
+ nd = (struct npc_data *)map_id2bl(st->oid);
- if (!nd || nd->bl.type != BL_NPC) {
- script_pushint(st,1);
- ShowError("detachnpctimer: Invalid NPC.\n");
- return 1;
- }
+ if( !nd || nd->bl.type != BL_NPC )
+ {
+ script_pushint(st,1);
+ ShowError("detachnpctimer: Invalid NPC.\n");
+ return 1;
+ }
- nd->u.scr.rid = 0;
- script_pushint(st,0);
- return 0;
+ nd->u.scr.rid = 0;
+ script_pushint(st,0);
+ return 0;
}
/*==========================================
@@ -9249,325 +9494,333 @@ BUILDIN_FUNC(detachnpctimer)
*------------------------------------------*/
BUILDIN_FUNC(playerattached)
{
- if (st->rid == 0 || map_id2sd(st->rid) == NULL)
- script_pushint(st,0);
- else
- script_pushint(st,st->rid);
- return 0;
+ if(st->rid == 0 || map_id2sd(st->rid) == NULL)
+ script_pushint(st,0);
+ else
+ script_pushint(st,st->rid);
+ return 0;
}
/*==========================================
*------------------------------------------*/
BUILDIN_FUNC(announce)
{
- const char *mes = script_getstr(st,2);
- int flag = script_getnum(st,3);
- const char *fontColor = script_hasdata(st,4) ? script_getstr(st,4) : NULL;
- int fontType = script_hasdata(st,5) ? script_getnum(st,5) : 0x190; // default fontType (FW_NORMAL)
- int fontSize = script_hasdata(st,6) ? script_getnum(st,6) : 12; // default fontSize
- int fontAlign = script_hasdata(st,7) ? script_getnum(st,7) : 0; // default fontAlign
- int fontY = script_hasdata(st,8) ? script_getnum(st,8) : 0; // default fontY
-
- if (flag&0x0f) { // Broadcast source or broadcast region defined
- send_target target;
- struct block_list *bl = (flag&0x08) ? map_id2bl(st->oid) : (struct block_list *)script_rid2sd(st); // If bc_npc flag is set, use NPC as broadcast source
- if (bl == NULL)
- return 0;
-
- flag &= 0x07;
- target = (flag == 1) ? ALL_SAMEMAP :
- (flag == 2) ? AREA :
- (flag == 3) ? SELF :
- ALL_CLIENT;
- if (fontColor)
- clif_broadcast2(bl, mes, (int)strlen(mes)+1, strtol(fontColor, (char **)NULL, 0), fontType, fontSize, fontAlign, fontY, target);
- else
- clif_broadcast(bl, mes, (int)strlen(mes)+1, flag&0xf0, target);
- } else {
- if (fontColor)
- intif_broadcast2(mes, (int)strlen(mes)+1, strtol(fontColor, (char **)NULL, 0), fontType, fontSize, fontAlign, fontY);
- else
- intif_broadcast(mes, (int)strlen(mes)+1, flag&0xf0);
- }
- return 0;
+ const char *mes = script_getstr(st,2);
+ int flag = script_getnum(st,3);
+ const char *fontColor = script_hasdata(st,4) ? script_getstr(st,4) : NULL;
+ int fontType = script_hasdata(st,5) ? script_getnum(st,5) : 0x190; // default fontType (FW_NORMAL)
+ int fontSize = script_hasdata(st,6) ? script_getnum(st,6) : 12; // default fontSize
+ int fontAlign = script_hasdata(st,7) ? script_getnum(st,7) : 0; // default fontAlign
+ int fontY = script_hasdata(st,8) ? script_getnum(st,8) : 0; // default fontY
+
+ if (flag&0x0f) // Broadcast source or broadcast region defined
+ {
+ send_target target;
+ struct block_list *bl = (flag&0x08) ? map_id2bl(st->oid) : (struct block_list *)script_rid2sd(st); // If bc_npc flag is set, use NPC as broadcast source
+ if (bl == NULL)
+ return 0;
+
+ flag &= 0x07;
+ target = (flag == 1) ? ALL_SAMEMAP :
+ (flag == 2) ? AREA :
+ (flag == 3) ? SELF :
+ ALL_CLIENT;
+ if (fontColor)
+ clif_broadcast2(bl, mes, (int)strlen(mes)+1, strtol(fontColor, (char **)NULL, 0), fontType, fontSize, fontAlign, fontY, target);
+ else
+ clif_broadcast(bl, mes, (int)strlen(mes)+1, flag&0xf0, target);
+ }
+ else
+ {
+ if (fontColor)
+ intif_broadcast2(mes, (int)strlen(mes)+1, strtol(fontColor, (char **)NULL, 0), fontType, fontSize, fontAlign, fontY);
+ else
+ intif_broadcast(mes, (int)strlen(mes)+1, flag&0xf0);
+ }
+ return 0;
}
/*==========================================
*------------------------------------------*/
static int buildin_announce_sub(struct block_list *bl, va_list ap)
{
- char *mes = va_arg(ap, char *);
- int len = va_arg(ap, int);
- int type = va_arg(ap, int);
- char *fontColor = va_arg(ap, char *);
- short fontType = (short)va_arg(ap, int);
- short fontSize = (short)va_arg(ap, int);
- short fontAlign = (short)va_arg(ap, int);
- short fontY = (short)va_arg(ap, int);
- if (fontColor)
- clif_broadcast2(bl, mes, len, strtol(fontColor, (char **)NULL, 0), fontType, fontSize, fontAlign, fontY, SELF);
- else
- clif_broadcast(bl, mes, len, type, SELF);
- return 0;
+ char *mes = va_arg(ap, char *);
+ int len = va_arg(ap, int);
+ int type = va_arg(ap, int);
+ char *fontColor = va_arg(ap, char *);
+ short fontType = (short)va_arg(ap, int);
+ short fontSize = (short)va_arg(ap, int);
+ short fontAlign = (short)va_arg(ap, int);
+ short fontY = (short)va_arg(ap, int);
+ if (fontColor)
+ clif_broadcast2(bl, mes, len, strtol(fontColor, (char **)NULL, 0), fontType, fontSize, fontAlign, fontY, SELF);
+ else
+ clif_broadcast(bl, mes, len, type, SELF);
+ return 0;
}
BUILDIN_FUNC(mapannounce)
{
- const char *mapname = script_getstr(st,2);
- const char *mes = script_getstr(st,3);
- int flag = script_getnum(st,4);
- const char *fontColor = script_hasdata(st,5) ? script_getstr(st,5) : NULL;
- int fontType = script_hasdata(st,6) ? script_getnum(st,6) : 0x190; // default fontType (FW_NORMAL)
- int fontSize = script_hasdata(st,7) ? script_getnum(st,7) : 12; // default fontSize
- int fontAlign = script_hasdata(st,8) ? script_getnum(st,8) : 0; // default fontAlign
- int fontY = script_hasdata(st,9) ? script_getnum(st,9) : 0; // default fontY
- int m;
-
- if ((m = map_mapname2mapid(mapname)) < 0)
- return 0;
+ const char *mapname = script_getstr(st,2);
+ const char *mes = script_getstr(st,3);
+ int flag = script_getnum(st,4);
+ const char *fontColor = script_hasdata(st,5) ? script_getstr(st,5) : NULL;
+ int fontType = script_hasdata(st,6) ? script_getnum(st,6) : 0x190; // default fontType (FW_NORMAL)
+ int fontSize = script_hasdata(st,7) ? script_getnum(st,7) : 12; // default fontSize
+ int fontAlign = script_hasdata(st,8) ? script_getnum(st,8) : 0; // default fontAlign
+ int fontY = script_hasdata(st,9) ? script_getnum(st,9) : 0; // default fontY
+ int m;
- map_foreachinmap(buildin_announce_sub, m, BL_PC,
- mes, strlen(mes)+1, flag&0xf0, fontColor, fontType, fontSize, fontAlign, fontY);
- return 0;
+ if ((m = map_mapname2mapid(mapname)) < 0)
+ return 0;
+
+ map_foreachinmap(buildin_announce_sub, m, BL_PC,
+ mes, strlen(mes)+1, flag&0xf0, fontColor, fontType, fontSize, fontAlign, fontY);
+ return 0;
}
/*==========================================
*------------------------------------------*/
BUILDIN_FUNC(areaannounce)
{
- const char *mapname = script_getstr(st,2);
- int x0 = script_getnum(st,3);
- int y0 = script_getnum(st,4);
- int x1 = script_getnum(st,5);
- int y1 = script_getnum(st,6);
- const char *mes = script_getstr(st,7);
- int flag = script_getnum(st,8);
- const char *fontColor = script_hasdata(st,9) ? script_getstr(st,9) : NULL;
- int fontType = script_hasdata(st,10) ? script_getnum(st,10) : 0x190; // default fontType (FW_NORMAL)
- int fontSize = script_hasdata(st,11) ? script_getnum(st,11) : 12; // default fontSize
- int fontAlign = script_hasdata(st,12) ? script_getnum(st,12) : 0; // default fontAlign
- int fontY = script_hasdata(st,13) ? script_getnum(st,13) : 0; // default fontY
- int m;
-
- if ((m = map_mapname2mapid(mapname)) < 0)
- return 0;
+ const char *mapname = script_getstr(st,2);
+ int x0 = script_getnum(st,3);
+ int y0 = script_getnum(st,4);
+ int x1 = script_getnum(st,5);
+ int y1 = script_getnum(st,6);
+ const char *mes = script_getstr(st,7);
+ int flag = script_getnum(st,8);
+ const char *fontColor = script_hasdata(st,9) ? script_getstr(st,9) : NULL;
+ int fontType = script_hasdata(st,10) ? script_getnum(st,10) : 0x190; // default fontType (FW_NORMAL)
+ int fontSize = script_hasdata(st,11) ? script_getnum(st,11) : 12; // default fontSize
+ int fontAlign = script_hasdata(st,12) ? script_getnum(st,12) : 0; // default fontAlign
+ int fontY = script_hasdata(st,13) ? script_getnum(st,13) : 0; // default fontY
+ int m;
- map_foreachinarea(buildin_announce_sub, m, x0, y0, x1, y1, BL_PC,
- mes, strlen(mes)+1, flag&0xf0, fontColor, fontType, fontSize, fontAlign, fontY);
- return 0;
+ if ((m = map_mapname2mapid(mapname)) < 0)
+ return 0;
+
+ map_foreachinarea(buildin_announce_sub, m, x0, y0, x1, y1, BL_PC,
+ mes, strlen(mes)+1, flag&0xf0, fontColor, fontType, fontSize, fontAlign, fontY);
+ return 0;
}
/*==========================================
*------------------------------------------*/
BUILDIN_FUNC(getusers)
{
- int flag, val = 0;
- struct map_session_data *sd;
- struct block_list *bl = NULL;
-
- flag = script_getnum(st,2);
-
- switch (flag&0x07) {
- case 0:
- if (flag&0x8) {
- // npc
- bl = map_id2bl(st->oid);
- } else if ((sd = script_rid2sd(st))!=NULL) {
- // pc
- bl = &sd->bl;
- }
-
- if (bl) {
- val = map[bl->m].users;
- }
- break;
- case 1:
- val = map_getusers();
- break;
- default:
- ShowWarning("buildin_getusers: Unknown type %d.\n", flag);
- script_pushint(st,0);
- return 1;
- }
-
- script_pushint(st,val);
- return 0;
+ int flag, val = 0;
+ struct map_session_data* sd;
+ struct block_list* bl = NULL;
+
+ flag = script_getnum(st,2);
+
+ switch(flag&0x07)
+ {
+ case 0:
+ if(flag&0x8)
+ {// npc
+ bl = map_id2bl(st->oid);
+ }
+ else if((sd = script_rid2sd(st))!=NULL)
+ {// pc
+ bl = &sd->bl;
+ }
+
+ if(bl)
+ {
+ val = map[bl->m].users;
+ }
+ break;
+ case 1:
+ val = map_getusers();
+ break;
+ default:
+ ShowWarning("buildin_getusers: Unknown type %d.\n", flag);
+ script_pushint(st,0);
+ return 1;
+ }
+
+ script_pushint(st,val);
+ return 0;
}
/*==========================================
* Works like @WHO - displays all online users names in window
*------------------------------------------*/
BUILDIN_FUNC(getusersname)
{
- TBL_PC *sd, *pl_sd;
- int /*disp_num=1,*/ group_level = 0;
- struct s_mapiterator *iter;
+ TBL_PC *sd, *pl_sd;
+ int /*disp_num=1,*/ group_level = 0;
+ struct s_mapiterator* iter;
- sd = script_rid2sd(st);
- if (!sd) return 0;
+ sd = script_rid2sd(st);
+ if (!sd) return 0;
- group_level = pc_get_group_level(sd);
- iter = mapit_getallusers();
- for (pl_sd = (TBL_PC *)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC *)mapit_next(iter)) {
- if (pc_has_permission(pl_sd, PC_PERM_HIDE_SESSION) && pc_get_group_level(pl_sd) > group_level)
- continue; // skip hidden sessions
+ group_level = pc_get_group_level(sd);
+ iter = mapit_getallusers();
+ for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
+ {
+ if (pc_has_permission(pl_sd, PC_PERM_HIDE_SESSION) && pc_get_group_level(pl_sd) > group_level)
+ continue; // skip hidden sessions
- /* Temporary fix for bugreport:1023.
- * Do not uncomment unless you want thousands of 'next' buttons.
- if((disp_num++)%10==0)
- clif_scriptnext(sd,st->oid);*/
- clif_scriptmes(sd,st->oid,pl_sd->status.name);
- }
- mapit_free(iter);
+ /* Temporary fix for bugreport:1023.
+ * Do not uncomment unless you want thousands of 'next' buttons.
+ if((disp_num++)%10==0)
+ clif_scriptnext(sd,st->oid);*/
+ clif_scriptmes(sd,st->oid,pl_sd->status.name);
+ }
+ mapit_free(iter);
- return 0;
+ return 0;
}
/*==========================================
* getmapguildusers("mapname",guild ID) Returns the number guild members present on a map [Reddozen]
*------------------------------------------*/
BUILDIN_FUNC(getmapguildusers)
{
- const char *str;
- int m, gid;
- int i=0,c=0;
- struct guild *g = NULL;
- str=script_getstr(st,2);
- gid=script_getnum(st,3);
- if ((m = map_mapname2mapid(str)) < 0) { // map id on this server (m == -1 if not in actual map-server)
- script_pushint(st,-1);
- return 0;
- }
- g = guild_search(gid);
-
- if (g) {
- for (i = 0; i < g->max_member; i++) {
- if (g->member[i].sd && g->member[i].sd->bl.m == m)
- c++;
- }
- }
-
- script_pushint(st,c);
- return 0;
+ const char *str;
+ int m, gid;
+ int i=0,c=0;
+ struct guild *g = NULL;
+ str=script_getstr(st,2);
+ gid=script_getnum(st,3);
+ if ((m = map_mapname2mapid(str)) < 0) { // map id on this server (m == -1 if not in actual map-server)
+ script_pushint(st,-1);
+ return 0;
+ }
+ g = guild_search(gid);
+
+ if (g){
+ for(i = 0; i < g->max_member; i++)
+ {
+ if (g->member[i].sd && g->member[i].sd->bl.m == m)
+ c++;
+ }
+ }
+
+ script_pushint(st,c);
+ return 0;
}
/*==========================================
*------------------------------------------*/
BUILDIN_FUNC(getmapusers)
{
- const char *str;
- int m;
- str=script_getstr(st,2);
- if ((m=map_mapname2mapid(str))< 0) {
- script_pushint(st,-1);
- return 0;
- }
- script_pushint(st,map[m].users);
- return 0;
+ const char *str;
+ int m;
+ str=script_getstr(st,2);
+ if( (m=map_mapname2mapid(str))< 0){
+ script_pushint(st,-1);
+ return 0;
+ }
+ script_pushint(st,map[m].users);
+ return 0;
}
/*==========================================
*------------------------------------------*/
static int buildin_getareausers_sub(struct block_list *bl,va_list ap)
{
- int *users=va_arg(ap,int *);
- (*users)++;
- return 0;
+ int *users=va_arg(ap,int *);
+ (*users)++;
+ return 0;
}
BUILDIN_FUNC(getareausers)
{
- const char *str;
- int m,x0,y0,x1,y1,users=0;
- str=script_getstr(st,2);
- x0=script_getnum(st,3);
- y0=script_getnum(st,4);
- x1=script_getnum(st,5);
- y1=script_getnum(st,6);
- if ((m=map_mapname2mapid(str))< 0) {
- script_pushint(st,-1);
- return 0;
- }
- map_foreachinarea(buildin_getareausers_sub,
- m,x0,y0,x1,y1,BL_PC,&users);
- script_pushint(st,users);
- return 0;
+ const char *str;
+ int m,x0,y0,x1,y1,users=0;
+ str=script_getstr(st,2);
+ x0=script_getnum(st,3);
+ y0=script_getnum(st,4);
+ x1=script_getnum(st,5);
+ y1=script_getnum(st,6);
+ if( (m=map_mapname2mapid(str))< 0){
+ script_pushint(st,-1);
+ return 0;
+ }
+ map_foreachinarea(buildin_getareausers_sub,
+ m,x0,y0,x1,y1,BL_PC,&users);
+ script_pushint(st,users);
+ return 0;
}
/*==========================================
*------------------------------------------*/
static int buildin_getareadropitem_sub(struct block_list *bl,va_list ap)
{
- int item=va_arg(ap,int);
- int *amount=va_arg(ap,int *);
- struct flooritem_data *drop=(struct flooritem_data *)bl;
+ int item=va_arg(ap,int);
+ int *amount=va_arg(ap,int *);
+ struct flooritem_data *drop=(struct flooritem_data *)bl;
- if (drop->item_data.nameid==item)
- (*amount)+=drop->item_data.amount;
+ if(drop->item_data.nameid==item)
+ (*amount)+=drop->item_data.amount;
- return 0;
+ return 0;
}
BUILDIN_FUNC(getareadropitem)
{
- const char *str;
- int m,x0,y0,x1,y1,item,amount=0;
- struct script_data *data;
-
- str=script_getstr(st,2);
- x0=script_getnum(st,3);
- y0=script_getnum(st,4);
- x1=script_getnum(st,5);
- y1=script_getnum(st,6);
-
- data=script_getdata(st,7);
- get_val(st,data);
- if (data_isstring(data)) {
- const char *name=conv_str(st,data);
- struct item_data *item_data = itemdb_searchname(name);
- item=UNKNOWN_ITEM_ID;
- if (item_data)
- item=item_data->nameid;
- } else
- item=conv_num(st,data);
-
- if ((m=map_mapname2mapid(str))< 0) {
- script_pushint(st,-1);
- return 0;
- }
- map_foreachinarea(buildin_getareadropitem_sub,
- m,x0,y0,x1,y1,BL_ITEM,item,&amount);
- script_pushint(st,amount);
- return 0;
+ const char *str;
+ int m,x0,y0,x1,y1,item,amount=0;
+ struct script_data *data;
+
+ str=script_getstr(st,2);
+ x0=script_getnum(st,3);
+ y0=script_getnum(st,4);
+ x1=script_getnum(st,5);
+ y1=script_getnum(st,6);
+
+ data=script_getdata(st,7);
+ get_val(st,data);
+ if( data_isstring(data) ){
+ const char *name=conv_str(st,data);
+ struct item_data *item_data = itemdb_searchname(name);
+ item=UNKNOWN_ITEM_ID;
+ if( item_data )
+ item=item_data->nameid;
+ }else
+ item=conv_num(st,data);
+
+ if( (m=map_mapname2mapid(str))< 0){
+ script_pushint(st,-1);
+ return 0;
+ }
+ map_foreachinarea(buildin_getareadropitem_sub,
+ m,x0,y0,x1,y1,BL_ITEM,item,&amount);
+ script_pushint(st,amount);
+ return 0;
}
/*==========================================
*------------------------------------------*/
BUILDIN_FUNC(enablenpc)
{
- const char *str;
- str=script_getstr(st,2);
- npc_enable(str,1);
- return 0;
+ const char *str;
+ str=script_getstr(st,2);
+ npc_enable(str,1);
+ return 0;
}
/*==========================================
*------------------------------------------*/
BUILDIN_FUNC(disablenpc)
{
- const char *str;
- str=script_getstr(st,2);
- npc_enable(str,0);
- return 0;
+ const char *str;
+ str=script_getstr(st,2);
+ npc_enable(str,0);
+ return 0;
}
/*==========================================
*------------------------------------------*/
BUILDIN_FUNC(hideoffnpc)
{
- const char *str;
- str=script_getstr(st,2);
- npc_enable(str,2);
- return 0;
+ const char *str;
+ str=script_getstr(st,2);
+ npc_enable(str,2);
+ return 0;
}
/*==========================================
*------------------------------------------*/
BUILDIN_FUNC(hideonnpc)
{
- const char *str;
- str=script_getstr(st,2);
- npc_enable(str,4);
- return 0;
+ const char *str;
+ str=script_getstr(st,2);
+ npc_enable(str,4);
+ return 0;
}
/// Starts a status effect on the target unit or on the attached player.
@@ -9575,36 +9828,36 @@ BUILDIN_FUNC(hideonnpc)
/// sc_start <effect_id>,<duration>,<val1>{,<unit_id>};
BUILDIN_FUNC(sc_start)
{
- struct block_list *bl;
- enum sc_type type;
- int tick;
- int val1;
- int val4 = 0;
-
- type = (sc_type)script_getnum(st,2);
- tick = script_getnum(st,3);
- val1 = script_getnum(st,4);
- if (script_hasdata(st,5))
- bl = map_id2bl(script_getnum(st,5));
- else
- bl = map_id2bl(st->rid);
-
- if (tick == 0 && val1 > 0 && type > SC_NONE && type < SC_MAX && status_sc2skill(type) != 0) {
- // When there isn't a duration specified, try to get it from the skill_db
- tick = skill_get_time(status_sc2skill(type), val1);
- }
+ struct block_list* bl;
+ enum sc_type type;
+ int tick;
+ int val1;
+ int val4 = 0;
- if (potion_flag == 1 && potion_target) {
- //skill.c set the flags before running the script, this must be a potion-pitched effect.
- bl = map_id2bl(potion_target);
- tick /= 2;// Thrown potions only last half.
- val4 = 1;// Mark that this was a thrown sc_effect
- }
+ type = (sc_type)script_getnum(st,2);
+ tick = script_getnum(st,3);
+ val1 = script_getnum(st,4);
+ if( script_hasdata(st,5) )
+ bl = map_id2bl(script_getnum(st,5));
+ else
+ bl = map_id2bl(st->rid);
- if (bl)
- status_change_start(bl, type, 10000, val1, 0, 0, val4, tick, 2);
+ if( tick == 0 && val1 > 0 && type > SC_NONE && type < SC_MAX && status_sc2skill(type) != 0 )
+ {// When there isn't a duration specified, try to get it from the skill_db
+ tick = skill_get_time(status_sc2skill(type), val1);
+ }
- return 0;
+ if( potion_flag == 1 && potion_target )
+ { //skill.c set the flags before running the script, this must be a potion-pitched effect.
+ bl = map_id2bl(potion_target);
+ tick /= 2;// Thrown potions only last half.
+ val4 = 1;// Mark that this was a thrown sc_effect
+ }
+
+ if( bl )
+ status_change_start(bl, type, 10000, val1, 0, 0, val4, tick, 2);
+
+ return 0;
}
/// Starts a status effect on the target unit or on the attached player.
@@ -9612,38 +9865,38 @@ BUILDIN_FUNC(sc_start)
/// sc_start2 <effect_id>,<duration>,<val1>,<percent chance>{,<unit_id>};
BUILDIN_FUNC(sc_start2)
{
- struct block_list *bl;
- enum sc_type type;
- int tick;
- int val1;
- int val4 = 0;
- int rate;
-
- type = (sc_type)script_getnum(st,2);
- tick = script_getnum(st,3);
- val1 = script_getnum(st,4);
- rate = script_getnum(st,5);
- if (script_hasdata(st,6))
- bl = map_id2bl(script_getnum(st,6));
- else
- bl = map_id2bl(st->rid);
-
- if (tick == 0 && val1 > 0 && type > SC_NONE && type < SC_MAX && status_sc2skill(type) != 0) {
- // When there isn't a duration specified, try to get it from the skill_db
- tick = skill_get_time(status_sc2skill(type), val1);
- }
+ struct block_list* bl;
+ enum sc_type type;
+ int tick;
+ int val1;
+ int val4 = 0;
+ int rate;
- if (potion_flag == 1 && potion_target) {
- //skill.c set the flags before running the script, this must be a potion-pitched effect.
- bl = map_id2bl(potion_target);
- tick /= 2;// Thrown potions only last half.
- val4 = 1;// Mark that this was a thrown sc_effect
- }
+ type = (sc_type)script_getnum(st,2);
+ tick = script_getnum(st,3);
+ val1 = script_getnum(st,4);
+ rate = script_getnum(st,5);
+ if( script_hasdata(st,6) )
+ bl = map_id2bl(script_getnum(st,6));
+ else
+ bl = map_id2bl(st->rid);
- if (bl)
- status_change_start(bl, type, rate, val1, 0, 0, val4, tick, 2);
+ if( tick == 0 && val1 > 0 && type > SC_NONE && type < SC_MAX && status_sc2skill(type) != 0 )
+ {// When there isn't a duration specified, try to get it from the skill_db
+ tick = skill_get_time(status_sc2skill(type), val1);
+ }
- return 0;
+ if( potion_flag == 1 && potion_target )
+ { //skill.c set the flags before running the script, this must be a potion-pitched effect.
+ bl = map_id2bl(potion_target);
+ tick /= 2;// Thrown potions only last half.
+ val4 = 1;// Mark that this was a thrown sc_effect
+ }
+
+ if( bl )
+ status_change_start(bl, type, rate, val1, 0, 0, val4, tick, 2);
+
+ return 0;
}
/// Starts a status effect on the target unit or on the attached player.
@@ -9651,40 +9904,40 @@ BUILDIN_FUNC(sc_start2)
/// sc_start4 <effect_id>,<duration>,<val1>,<val2>,<val3>,<val4>{,<unit_id>};
BUILDIN_FUNC(sc_start4)
{
- struct block_list *bl;
- enum sc_type type;
- int tick;
- int val1;
- int val2;
- int val3;
- int val4;
-
- type = (sc_type)script_getnum(st,2);
- tick = script_getnum(st,3);
- val1 = script_getnum(st,4);
- val2 = script_getnum(st,5);
- val3 = script_getnum(st,6);
- val4 = script_getnum(st,7);
- if (script_hasdata(st,8))
- bl = map_id2bl(script_getnum(st,8));
- else
- bl = map_id2bl(st->rid);
-
- if (tick == 0 && val1 > 0 && type > SC_NONE && type < SC_MAX && status_sc2skill(type) != 0) {
- // When there isn't a duration specified, try to get it from the skill_db
- tick = skill_get_time(status_sc2skill(type), val1);
- }
-
- if (potion_flag == 1 && potion_target) {
- //skill.c set the flags before running the script, this must be a potion-pitched effect.
- bl = map_id2bl(potion_target);
- tick /= 2;// Thrown potions only last half.
- }
-
- if (bl)
- status_change_start(bl, type, 10000, val1, val2, val3, val4, tick, 2);
-
- return 0;
+ struct block_list* bl;
+ enum sc_type type;
+ int tick;
+ int val1;
+ int val2;
+ int val3;
+ int val4;
+
+ type = (sc_type)script_getnum(st,2);
+ tick = script_getnum(st,3);
+ val1 = script_getnum(st,4);
+ val2 = script_getnum(st,5);
+ val3 = script_getnum(st,6);
+ val4 = script_getnum(st,7);
+ if( script_hasdata(st,8) )
+ bl = map_id2bl(script_getnum(st,8));
+ else
+ bl = map_id2bl(st->rid);
+
+ if( tick == 0 && val1 > 0 && type > SC_NONE && type < SC_MAX && status_sc2skill(type) != 0 )
+ {// When there isn't a duration specified, try to get it from the skill_db
+ tick = skill_get_time(status_sc2skill(type), val1);
+ }
+
+ if( potion_flag == 1 && potion_target )
+ { //skill.c set the flags before running the script, this must be a potion-pitched effect.
+ bl = map_id2bl(potion_target);
+ tick /= 2;// Thrown potions only last half.
+ }
+
+ if( bl )
+ status_change_start(bl, type, 10000, val1, val2, val3, val4, tick, 2);
+
+ return 0;
}
/// Ends one or all status effects on the target unit or on the attached player.
@@ -9692,47 +9945,50 @@ BUILDIN_FUNC(sc_start4)
/// sc_end <effect_id>{,<unit_id>};
BUILDIN_FUNC(sc_end)
{
- struct block_list *bl;
- int type;
+ struct block_list* bl;
+ int type;
- type = script_getnum(st, 2);
- if (script_hasdata(st, 3))
- bl = map_id2bl(script_getnum(st, 3));
- else
- bl = map_id2bl(st->rid);
+ type = script_getnum(st, 2);
+ if (script_hasdata(st, 3))
+ bl = map_id2bl(script_getnum(st, 3));
+ else
+ bl = map_id2bl(st->rid);
- if (potion_flag == 1 && potion_target) //##TODO how does this work [FlavioJS]
- bl = map_id2bl(potion_target);
+ if (potion_flag == 1 && potion_target) //##TODO how does this work [FlavioJS]
+ bl = map_id2bl(potion_target);
- if (!bl)
- return 0;
+ if (!bl)
+ return 0;
- if (type >= 0 && type < SC_MAX) {
- struct status_change *sc = status_get_sc(bl);
- struct status_change_entry *sce = sc ? sc->data[type] : NULL;
+ if (type >= 0 && type < SC_MAX)
+ {
+ struct status_change *sc = status_get_sc(bl);
+ struct status_change_entry *sce = sc ? sc->data[type] : NULL;
- if (!sce)
- return 0;
+ if (!sce)
+ return 0;
- switch (type) {
- case SC_WEIGHT50:
- case SC_WEIGHT90:
- case SC_NOCHAT:
- case SC_PUSH_CART:
- return 0;
+ switch (type)
+ {
+ case SC_WEIGHT50:
+ case SC_WEIGHT90:
+ case SC_NOCHAT:
+ case SC_PUSH_CART:
+ return 0;
- default:
- break;
- }
+ default:
+ break;
+ }
- //This should help status_change_end force disabling the SC in case it has no limit.
- sce->val1 = sce->val2 = sce->val3 = sce->val4 = 0;
- status_change_end(bl, (sc_type)type, INVALID_TIMER);
- } else
- status_change_clear(bl, 3); // remove all effects
+ //This should help status_change_end force disabling the SC in case it has no limit.
+ sce->val1 = sce->val2 = sce->val3 = sce->val4 = 0;
+ status_change_end(bl, (sc_type)type, INVALID_TIMER);
+ }
+ else
+ status_change_clear(bl, 3); // remove all effects
- return 0;
+ return 0;
}
/*==========================================
@@ -9740,21 +9996,21 @@ BUILDIN_FUNC(sc_end)
*------------------------------------------*/
BUILDIN_FUNC(getscrate)
{
- struct block_list *bl;
- int type,rate;
+ struct block_list *bl;
+ int type,rate;
- type=script_getnum(st,2);
- rate=script_getnum(st,3);
- if (script_hasdata(st,4)) //get for the bl assigned
- bl = map_id2bl(script_getnum(st,4));
- else
- bl = map_id2bl(st->rid);
+ type=script_getnum(st,2);
+ rate=script_getnum(st,3);
+ if( script_hasdata(st,4) ) //get for the bl assigned
+ bl = map_id2bl(script_getnum(st,4));
+ else
+ bl = map_id2bl(st->rid);
- if (bl)
- rate = status_get_sc_def(bl, (sc_type)type, 10000, 10000, 0);
+ if (bl)
+ rate = status_get_sc_def(bl, (sc_type)type, 10000, 10000, 0);
- script_pushint(st,rate);
- return 0;
+ script_pushint(st,rate);
+ return 0;
}
/*==========================================
@@ -9762,57 +10018,49 @@ BUILDIN_FUNC(getscrate)
*------------------------------------------*/
BUILDIN_FUNC(getstatus)
{
- int id, type;
- struct map_session_data *sd = script_rid2sd(st);
-
- if (sd == NULL) {
- // no player attached
- return 0;
- }
-
- id = script_getnum(st, 2);
- type = script_hasdata(st, 3) ? script_getnum(st, 3) : 0;
-
- if (id <= SC_NONE || id >= SC_MAX) {
- // invalid status type given
- ShowWarning("script.c:getstatus: Invalid status type given (%d).\n", id);
- return 0;
- }
-
- if (sd->sc.count == 0 || !sd->sc.data[id]) {
- // no status is active
- script_pushint(st, 0);
- return 0;
- }
-
- switch (type) {
- case 1:
- script_pushint(st, sd->sc.data[id]->val1);
- break;
- case 2:
- script_pushint(st, sd->sc.data[id]->val2);
- break;
- case 3:
- script_pushint(st, sd->sc.data[id]->val3);
- break;
- case 4:
- script_pushint(st, sd->sc.data[id]->val4);
- break;
- case 5: {
- struct TimerData *timer = (struct TimerData *)get_timer(sd->sc.data[id]->timer);
-
- if (timer) {
- // return the amount of time remaining
- script_pushint(st, timer->tick - gettick());
- }
- }
- break;
- default:
- script_pushint(st, 1);
- break;
- }
-
- return 0;
+ int id, type;
+ struct map_session_data* sd = script_rid2sd(st);
+
+ if( sd == NULL )
+ {// no player attached
+ return 0;
+ }
+
+ id = script_getnum(st, 2);
+ type = script_hasdata(st, 3) ? script_getnum(st, 3) : 0;
+
+ if( id <= SC_NONE || id >= SC_MAX )
+ {// invalid status type given
+ ShowWarning("script.c:getstatus: Invalid status type given (%d).\n", id);
+ return 0;
+ }
+
+ if( sd->sc.count == 0 || !sd->sc.data[id] )
+ {// no status is active
+ script_pushint(st, 0);
+ return 0;
+ }
+
+ switch( type )
+ {
+ case 1: script_pushint(st, sd->sc.data[id]->val1); break;
+ case 2: script_pushint(st, sd->sc.data[id]->val2); break;
+ case 3: script_pushint(st, sd->sc.data[id]->val3); break;
+ case 4: script_pushint(st, sd->sc.data[id]->val4); break;
+ case 5:
+ {
+ struct TimerData* timer = (struct TimerData*)get_timer(sd->sc.data[id]->timer);
+
+ if( timer )
+ {// return the amount of time remaining
+ script_pushint(st, timer->tick - gettick());
+ }
+ }
+ break;
+ default: script_pushint(st, 1); break;
+ }
+
+ return 0;
}
/*==========================================
@@ -9820,26 +10068,26 @@ BUILDIN_FUNC(getstatus)
*------------------------------------------*/
BUILDIN_FUNC(debugmes)
{
- const char *str;
- str=script_getstr(st,2);
- ShowDebug("script debug : %d %d : %s\n",st->rid,st->oid,str);
- return 0;
+ const char *str;
+ str=script_getstr(st,2);
+ ShowDebug("script debug : %d %d : %s\n",st->rid,st->oid,str);
+ return 0;
}
/*==========================================
*------------------------------------------*/
BUILDIN_FUNC(catchpet)
{
- int pet_id;
- TBL_PC *sd;
+ int pet_id;
+ TBL_PC *sd;
- pet_id= script_getnum(st,2);
- sd=script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ pet_id= script_getnum(st,2);
+ sd=script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- pet_catch_process1(sd,pet_id);
- return 0;
+ pet_catch_process1(sd,pet_id);
+ return 0;
}
/*==========================================
@@ -9847,19 +10095,20 @@ BUILDIN_FUNC(catchpet)
*------------------------------------------*/
BUILDIN_FUNC(homunculus_evolution)
{
- TBL_PC *sd;
+ TBL_PC *sd;
- sd=script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ sd=script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- if (merc_is_hom_active(sd->hd)) {
- if (sd->hd->homunculus.intimacy > 91000)
- merc_hom_evolution(sd->hd);
- else
- clif_emotion(&sd->hd->bl, E_SWT);
- }
- return 0;
+ if(merc_is_hom_active(sd->hd))
+ {
+ if (sd->hd->homunculus.intimacy > 91000)
+ merc_hom_evolution(sd->hd);
+ else
+ clif_emotion(&sd->hd->bl, E_SWT);
+ }
+ return 0;
}
/*==========================================
@@ -9867,80 +10116,80 @@ BUILDIN_FUNC(homunculus_evolution)
*------------------------------------------*/
BUILDIN_FUNC(homunculus_mutate)
{
- int homun_id, m_class, m_id;
- int homun_array[5] = {6048,6049,6050,6051,6052};
- TBL_PC *sd;
+ int homun_id, m_class, m_id;
+ int homun_array[5] = {6048,6049,6050,6051,6052};
+ TBL_PC *sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- if (script_hasdata(st,2))
- homun_id = script_getnum(st,2);
- else
- homun_id = homun_array[rnd() % 5];
+ if(script_hasdata(st,2))
+ homun_id = script_getnum(st,2);
+ else
+ homun_id = homun_array[rnd() % 5];
- if (merc_is_hom_active(sd->hd)) {
- m_class = hom_class2mapid(sd->hd->homunculus.class_);
- m_id = hom_class2mapid(homun_id);
+ if(merc_is_hom_active(sd->hd)) {
+ m_class = hom_class2mapid(sd->hd->homunculus.class_);
+ m_id = hom_class2mapid(homun_id);
- if (m_class != -1 && m_id != -1 && m_class&HOM_EVO && m_id&HOM_S && sd->hd->homunculus.level >= 99)
- hom_mutate(sd->hd, homun_id);
- else
- clif_emotion(&sd->hd->bl, E_SWT);
- }
- return 0;
+ if ( m_class != -1 && m_id != -1 && m_class&HOM_EVO && m_id&HOM_S && sd->hd->homunculus.level >= 99 )
+ hom_mutate(sd->hd, homun_id);
+ else
+ clif_emotion(&sd->hd->bl, E_SWT);
+ }
+ return 0;
}
// [Zephyrus]
BUILDIN_FUNC(homunculus_shuffle)
{
- TBL_PC *sd;
+ TBL_PC *sd;
- sd=script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ sd=script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- if (merc_is_hom_active(sd->hd))
- merc_hom_shuffle(sd->hd);
+ if(merc_is_hom_active(sd->hd))
+ merc_hom_shuffle(sd->hd);
- return 0;
+ return 0;
}
//These two functions bring the eA MAPID_* class functionality to scripts.
BUILDIN_FUNC(eaclass)
{
- int class_;
- if (script_hasdata(st,2))
- class_ = script_getnum(st,2);
- else {
- TBL_PC *sd;
- sd=script_rid2sd(st);
- if (!sd) {
- script_pushint(st,-1);
- return 0;
- }
- class_ = sd->status.class_;
- }
- script_pushint(st,pc_jobid2mapid(class_));
- return 0;
+ int class_;
+ if( script_hasdata(st,2) )
+ class_ = script_getnum(st,2);
+ else {
+ TBL_PC *sd;
+ sd=script_rid2sd(st);
+ if (!sd) {
+ script_pushint(st,-1);
+ return 0;
+ }
+ class_ = sd->status.class_;
+ }
+ script_pushint(st,pc_jobid2mapid(class_));
+ return 0;
}
BUILDIN_FUNC(roclass)
{
- int class_ =script_getnum(st,2);
- int sex;
- if (script_hasdata(st,3))
- sex = script_getnum(st,3);
- else {
- TBL_PC *sd;
- if (st->rid && (sd=script_rid2sd(st)))
- sex = sd->status.sex;
- else
- sex = 1; //Just use male when not found.
- }
- script_pushint(st,pc_mapid2jobid(class_, sex));
- return 0;
+ int class_ =script_getnum(st,2);
+ int sex;
+ if( script_hasdata(st,3) )
+ sex = script_getnum(st,3);
+ else {
+ TBL_PC *sd;
+ if (st->rid && (sd=script_rid2sd(st)))
+ sex = sd->status.sex;
+ else
+ sex = 1; //Just use male when not found.
+ }
+ script_pushint(st,pc_mapid2jobid(class_, sex));
+ return 0;
}
/*==========================================
@@ -9948,50 +10197,50 @@ BUILDIN_FUNC(roclass)
*------------------------------------------*/
BUILDIN_FUNC(birthpet)
{
- TBL_PC *sd;
- sd=script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ TBL_PC *sd;
+ sd=script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- if (sd->status.pet_id) {
- // do not send egg list, when you already have a pet
- return 0;
- }
+ if( sd->status.pet_id )
+ {// do not send egg list, when you already have a pet
+ return 0;
+ }
- clif_sendegg(sd);
- return 0;
+ clif_sendegg(sd);
+ return 0;
}
/*==========================================
* Added - AppleGirl For Advanced Classes, (Updated for Cleaner Script Purposes)
* @type
- * 1 : make like after rebirth
- * 2 : blvl,jlvl=1, skillpoint=0
- * 3 : don't reset skill, blvl=1
- * 4 : jlvl=0
+ * 1 : make like after rebirth
+ * 2 : blvl,jlvl=1, skillpoint=0
+ * 3 : don't reset skill, blvl=1
+ * 4 : jlvl=0
*------------------------------------------*/
BUILDIN_FUNC(resetlvl)
{
- TBL_PC *sd;
+ TBL_PC *sd;
- int type=script_getnum(st,2);
+ int type=script_getnum(st,2);
- sd=script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ sd=script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- pc_resetlvl(sd,type);
- return 0;
+ pc_resetlvl(sd,type);
+ return 0;
}
/*==========================================
* Reset a player status point
*------------------------------------------*/
BUILDIN_FUNC(resetstatus)
{
- TBL_PC *sd;
- sd=script_rid2sd(st);
- pc_resetstate(sd);
- return 0;
+ TBL_PC *sd;
+ sd=script_rid2sd(st);
+ pc_resetstate(sd);
+ return 0;
}
/*==========================================
@@ -9999,10 +10248,10 @@ BUILDIN_FUNC(resetstatus)
*------------------------------------------*/
BUILDIN_FUNC(resetskill)
{
- TBL_PC *sd;
- sd=script_rid2sd(st);
- pc_resetskill(sd,1);
- return 0;
+ TBL_PC *sd;
+ sd=script_rid2sd(st);
+ pc_resetskill(sd,1);
+ return 0;
}
/*==========================================
@@ -10010,10 +10259,10 @@ BUILDIN_FUNC(resetskill)
*------------------------------------------*/
BUILDIN_FUNC(skillpointcount)
{
- TBL_PC *sd;
- sd=script_rid2sd(st);
- script_pushint(st,sd->status.skill_point + pc_resetskill(sd,2));
- return 0;
+ TBL_PC *sd;
+ sd=script_rid2sd(st);
+ script_pushint(st,sd->status.skill_point + pc_resetskill(sd,2));
+ return 0;
}
/*==========================================
@@ -10021,36 +10270,37 @@ BUILDIN_FUNC(skillpointcount)
*------------------------------------------*/
BUILDIN_FUNC(changebase)
{
- TBL_PC *sd=NULL;
- int vclass;
+ TBL_PC *sd=NULL;
+ int vclass;
- if (script_hasdata(st,3))
- sd=map_id2sd(script_getnum(st,3));
- else
- sd=script_rid2sd(st);
+ if( script_hasdata(st,3) )
+ sd=map_id2sd(script_getnum(st,3));
+ else
+ sd=script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ if(sd == NULL)
+ return 0;
- vclass = script_getnum(st,2);
- if (vclass == JOB_WEDDING) {
- if (!battle_config.wedding_modifydisplay || //Do not show the wedding sprites
- sd->class_&JOBL_BABY //Baby classes screw up when showing wedding sprites. [Skotlex] They don't seem to anymore.
- )
- return 0;
- }
+ vclass = script_getnum(st,2);
+ if(vclass == JOB_WEDDING)
+ {
+ if (!battle_config.wedding_modifydisplay || //Do not show the wedding sprites
+ sd->class_&JOBL_BABY //Baby classes screw up when showing wedding sprites. [Skotlex] They don't seem to anymore.
+ )
+ return 0;
+ }
- if (!sd->disguise && vclass != sd->vd.class_) {
- status_set_viewdata(&sd->bl, vclass);
- //Updated client view. Base, Weapon and Cloth Colors.
- clif_changelook(&sd->bl,LOOK_BASE,sd->vd.class_);
- clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
- if (sd->vd.cloth_color)
- clif_changelook(&sd->bl,LOOK_CLOTHES_COLOR,sd->vd.cloth_color);
- clif_skillinfoblock(sd);
- }
+ if(!sd->disguise && vclass != sd->vd.class_) {
+ status_set_viewdata(&sd->bl, vclass);
+ //Updated client view. Base, Weapon and Cloth Colors.
+ clif_changelook(&sd->bl,LOOK_BASE,sd->vd.class_);
+ clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
+ if (sd->vd.cloth_color)
+ clif_changelook(&sd->bl,LOOK_CLOTHES_COLOR,sd->vd.cloth_color);
+ clif_skillinfoblock(sd);
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -10058,16 +10308,16 @@ BUILDIN_FUNC(changebase)
*------------------------------------------*/
BUILDIN_FUNC(changesex)
{
- int i;
- TBL_PC *sd = NULL;
- sd = script_rid2sd(st);
+ int i;
+ TBL_PC *sd = NULL;
+ sd = script_rid2sd(st);
- pc_resetskill(sd,4);
- // to avoid any problem with equipment and invalid sex, equipment is unequiped.
- for (i=0; i<EQI_MAX; i++)
- if (sd->equip_index[i] >= 0) pc_unequipitem(sd, sd->equip_index[i], 3);
- chrif_changesex(sd);
- return 0;
+ pc_resetskill(sd,4);
+ // to avoid any problem with equipment and invalid sex, equipment is unequiped.
+ for( i=0; i<EQI_MAX; i++ )
+ if( sd->equip_index[i] >= 0 ) pc_unequipitem(sd, sd->equip_index[i], 3);
+ chrif_changesex(sd);
+ return 0;
}
/*==========================================
@@ -10075,22 +10325,22 @@ BUILDIN_FUNC(changesex)
*------------------------------------------*/
BUILDIN_FUNC(globalmes)
{
- struct block_list *bl = map_id2bl(st->oid);
- struct npc_data *nd = (struct npc_data *)bl;
- const char *name=NULL,*mes;
+ struct block_list *bl = map_id2bl(st->oid);
+ struct npc_data *nd = (struct npc_data *)bl;
+ const char *name=NULL,*mes;
- mes=script_getstr(st,2);
- if (mes==NULL) return 0;
+ mes=script_getstr(st,2);
+ if(mes==NULL) return 0;
- if (script_hasdata(st,3)) { // npc name to display
- name=script_getstr(st,3);
- } else {
- name=nd->name; //use current npc name
- }
+ if(script_hasdata(st,3)){ // npc name to display
+ name=script_getstr(st,3);
+ } else {
+ name=nd->name; //use current npc name
+ }
- npc_globalmessage(name,mes); // broadcast to all players connected
+ npc_globalmessage(name,mes); // broadcast to all players connected
- return 0;
+ return 0;
}
/////////////////////////////////////////////////////////////////////
@@ -10102,21 +10352,21 @@ BUILDIN_FUNC(globalmes)
/// waitingroom "<title>",<limit>{,"<event>"{,<trigger>{,<zeny>{,<minlvl>{,<maxlvl>}}}}};
BUILDIN_FUNC(waitingroom)
{
- struct npc_data *nd;
- int pub = 1;
- const char *title = script_getstr(st, 2);
- int limit = script_getnum(st, 3);
- const char *ev = script_hasdata(st,4) ? script_getstr(st,4) : "";
- int trigger = script_hasdata(st,5) ? script_getnum(st,5) : limit;
- int zeny = script_hasdata(st,6) ? script_getnum(st,6) : 0;
- int minLvl = script_hasdata(st,7) ? script_getnum(st,7) : 1;
- int maxLvl = script_hasdata(st,8) ? script_getnum(st,8) : MAX_LEVEL;
+ struct npc_data* nd;
+ int pub = 1;
+ const char* title = script_getstr(st, 2);
+ int limit = script_getnum(st, 3);
+ const char* ev = script_hasdata(st,4) ? script_getstr(st,4) : "";
+ int trigger = script_hasdata(st,5) ? script_getnum(st,5) : limit;
+ int zeny = script_hasdata(st,6) ? script_getnum(st,6) : 0;
+ int minLvl = script_hasdata(st,7) ? script_getnum(st,7) : 1;
+ int maxLvl = script_hasdata(st,8) ? script_getnum(st,8) : MAX_LEVEL;
- nd = (struct npc_data *)map_id2bl(st->oid);
- if (nd != NULL)
- chat_createnpcchat(nd, title, limit, pub, trigger, ev, zeny, minLvl, maxLvl);
+ nd = (struct npc_data *)map_id2bl(st->oid);
+ if( nd != NULL )
+ chat_createnpcchat(nd, title, limit, pub, trigger, ev, zeny, minLvl, maxLvl);
- return 0;
+ return 0;
}
/// Removes the waiting room of the current or target npc.
@@ -10125,14 +10375,14 @@ BUILDIN_FUNC(waitingroom)
/// delwaitingroom;
BUILDIN_FUNC(delwaitingroom)
{
- struct npc_data *nd;
- if (script_hasdata(st,2))
- nd = npc_name2id(script_getstr(st, 2));
- else
- nd = (struct npc_data *)map_id2bl(st->oid);
- if (nd != NULL)
- chat_deletenpcchat(nd);
- return 0;
+ struct npc_data* nd;
+ if( script_hasdata(st,2) )
+ nd = npc_name2id(script_getstr(st, 2));
+ else
+ nd = (struct npc_data *)map_id2bl(st->oid);
+ if( nd != NULL )
+ chat_deletenpcchat(nd);
+ return 0;
}
/// Kicks all the players from the waiting room of the current or target npc.
@@ -10141,17 +10391,17 @@ BUILDIN_FUNC(delwaitingroom)
/// kickwaitingroomall;
BUILDIN_FUNC(waitingroomkickall)
{
- struct npc_data *nd;
- struct chat_data *cd;
+ struct npc_data* nd;
+ struct chat_data* cd;
- if (script_hasdata(st,2))
- nd = npc_name2id(script_getstr(st,2));
- else
- nd = (struct npc_data *)map_id2bl(st->oid);
+ if( script_hasdata(st,2) )
+ nd = npc_name2id(script_getstr(st,2));
+ else
+ nd = (struct npc_data *)map_id2bl(st->oid);
- if (nd != NULL && (cd=(struct chat_data *)map_id2bl(nd->chat_id)) != NULL)
- chat_npckickall(cd);
- return 0;
+ if( nd != NULL && (cd=(struct chat_data *)map_id2bl(nd->chat_id)) != NULL )
+ chat_npckickall(cd);
+ return 0;
}
/// Enables the waiting room event of the current or target npc.
@@ -10160,17 +10410,17 @@ BUILDIN_FUNC(waitingroomkickall)
/// enablewaitingroomevent;
BUILDIN_FUNC(enablewaitingroomevent)
{
- struct npc_data *nd;
- struct chat_data *cd;
+ struct npc_data* nd;
+ struct chat_data* cd;
- if (script_hasdata(st,2))
- nd = npc_name2id(script_getstr(st, 2));
- else
- nd = (struct npc_data *)map_id2bl(st->oid);
+ if( script_hasdata(st,2) )
+ nd = npc_name2id(script_getstr(st, 2));
+ else
+ nd = (struct npc_data *)map_id2bl(st->oid);
- if (nd != NULL && (cd=(struct chat_data *)map_id2bl(nd->chat_id)) != NULL)
- chat_enableevent(cd);
- return 0;
+ if( nd != NULL && (cd=(struct chat_data *)map_id2bl(nd->chat_id)) != NULL )
+ chat_enableevent(cd);
+ return 0;
}
/// Disables the waiting room event of the current or target npc.
@@ -10179,17 +10429,17 @@ BUILDIN_FUNC(enablewaitingroomevent)
/// disablewaitingroomevent;
BUILDIN_FUNC(disablewaitingroomevent)
{
- struct npc_data *nd;
- struct chat_data *cd;
+ struct npc_data *nd;
+ struct chat_data *cd;
- if (script_hasdata(st,2))
- nd = npc_name2id(script_getstr(st, 2));
- else
- nd = (struct npc_data *)map_id2bl(st->oid);
+ if( script_hasdata(st,2) )
+ nd = npc_name2id(script_getstr(st, 2));
+ else
+ nd = (struct npc_data *)map_id2bl(st->oid);
- if (nd != NULL && (cd=(struct chat_data *)map_id2bl(nd->chat_id)) != NULL)
- chat_disableevent(cd);
- return 0;
+ if( nd != NULL && (cd=(struct chat_data *)map_id2bl(nd->chat_id)) != NULL )
+ chat_disableevent(cd);
+ return 0;
}
/// Returns info on the waiting room of the current or target npc.
@@ -10208,54 +10458,36 @@ BUILDIN_FUNC(disablewaitingroomevent)
/// getwaitingroomstate(<type>) -> <info>
BUILDIN_FUNC(getwaitingroomstate)
{
- struct npc_data *nd;
- struct chat_data *cd;
- int type;
-
- type = script_getnum(st,2);
- if (script_hasdata(st,3))
- nd = npc_name2id(script_getstr(st, 3));
- else
- nd = (struct npc_data *)map_id2bl(st->oid);
-
- if (nd == NULL || (cd=(struct chat_data *)map_id2bl(nd->chat_id)) == NULL) {
- script_pushint(st, -1);
- return 0;
- }
-
- switch (type) {
- case 0:
- script_pushint(st, cd->users);
- break;
- case 1:
- script_pushint(st, cd->limit);
- break;
- case 2:
- script_pushint(st, cd->trigger&0x7f);
- break;
- case 3:
- script_pushint(st, ((cd->trigger&0x80)!=0));
- break;
- case 4:
- script_pushstrcopy(st, cd->title);
- break;
- case 5:
- script_pushstrcopy(st, cd->pass);
- break;
- case 16:
- script_pushstrcopy(st, cd->npc_event);
- break;
- case 32:
- script_pushint(st, (cd->users >= cd->limit));
- break;
- case 33:
- script_pushint(st, (cd->users >= cd->trigger));
- break;
- default:
- script_pushint(st, -1);
- break;
- }
- return 0;
+ struct npc_data *nd;
+ struct chat_data *cd;
+ int type;
+
+ type = script_getnum(st,2);
+ if( script_hasdata(st,3) )
+ nd = npc_name2id(script_getstr(st, 3));
+ else
+ nd = (struct npc_data *)map_id2bl(st->oid);
+
+ if( nd == NULL || (cd=(struct chat_data *)map_id2bl(nd->chat_id)) == NULL )
+ {
+ script_pushint(st, -1);
+ return 0;
+ }
+
+ switch(type)
+ {
+ case 0: script_pushint(st, cd->users); break;
+ case 1: script_pushint(st, cd->limit); break;
+ case 2: script_pushint(st, cd->trigger&0x7f); break;
+ case 3: script_pushint(st, ((cd->trigger&0x80)!=0)); break;
+ case 4: script_pushstrcopy(st, cd->title); break;
+ case 5: script_pushstrcopy(st, cd->pass); break;
+ case 16: script_pushstrcopy(st, cd->npc_event);break;
+ case 32: script_pushint(st, (cd->users >= cd->limit)); break;
+ case 33: script_pushint(st, (cd->users >= cd->trigger)); break;
+ default: script_pushint(st, -1); break;
+ }
+ return 0;
}
/// Warps the trigger or target amount of players to the target map and position.
@@ -10272,55 +10504,56 @@ BUILDIN_FUNC(getwaitingroomstate)
/// warpwaitingpc "<map name>",<x>,<y>;
BUILDIN_FUNC(warpwaitingpc)
{
- int x;
- int y;
- int i;
- int n;
- const char *map_name;
- struct npc_data *nd;
- struct chat_data *cd;
- TBL_PC *sd;
-
- nd = (struct npc_data *)map_id2bl(st->oid);
- if (nd == NULL || (cd=(struct chat_data *)map_id2bl(nd->chat_id)) == NULL)
- return 0;
-
- map_name = script_getstr(st,2);
- x = script_getnum(st,3);
- y = script_getnum(st,4);
- n = cd->trigger&0x7f;
-
- if (script_hasdata(st,5))
- n = script_getnum(st,5);
-
- for (i = 0; i < n && cd->users > 0; i++) {
- sd = cd->usersd[0];
-
- if (strcmp(map_name,"SavePoint") == 0 && map[sd->bl.m].flag.noteleport) {
- // can't teleport on this map
- break;
- }
-
- if (cd->zeny) {
- // fee set
- if ((uint32)sd->status.zeny < cd->zeny) {
- // no zeny to cover set fee
- break;
- }
- pc_payzeny(sd, cd->zeny, LOG_TYPE_NPC, NULL);
- }
-
- mapreg_setreg(reference_uid(add_str("$@warpwaitingpc"), i), sd->bl.id);
-
- if (strcmp(map_name,"Random") == 0)
- pc_randomwarp(sd,CLR_TELEPORT);
- else if (strcmp(map_name,"SavePoint") == 0)
- pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT);
- else
- pc_setpos(sd, mapindex_name2id(map_name), x, y, CLR_OUTSIGHT);
- }
- mapreg_setreg(add_str("$@warpwaitingpcnum"), i);
- return 0;
+ int x;
+ int y;
+ int i;
+ int n;
+ const char* map_name;
+ struct npc_data* nd;
+ struct chat_data* cd;
+ TBL_PC* sd;
+
+ nd = (struct npc_data *)map_id2bl(st->oid);
+ if( nd == NULL || (cd=(struct chat_data *)map_id2bl(nd->chat_id)) == NULL )
+ return 0;
+
+ map_name = script_getstr(st,2);
+ x = script_getnum(st,3);
+ y = script_getnum(st,4);
+ n = cd->trigger&0x7f;
+
+ if( script_hasdata(st,5) )
+ n = script_getnum(st,5);
+
+ for( i = 0; i < n && cd->users > 0; i++ )
+ {
+ sd = cd->usersd[0];
+
+ if( strcmp(map_name,"SavePoint") == 0 && map[sd->bl.m].flag.noteleport )
+ {// can't teleport on this map
+ break;
+ }
+
+ if( cd->zeny )
+ {// fee set
+ if( (uint32)sd->status.zeny < cd->zeny )
+ {// no zeny to cover set fee
+ break;
+ }
+ pc_payzeny(sd, cd->zeny, LOG_TYPE_NPC, NULL);
+ }
+
+ mapreg_setreg(reference_uid(add_str("$@warpwaitingpc"), i), sd->bl.id);
+
+ if( strcmp(map_name,"Random") == 0 )
+ pc_randomwarp(sd,CLR_TELEPORT);
+ else if( strcmp(map_name,"SavePoint") == 0 )
+ pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT);
+ else
+ pc_setpos(sd, mapindex_name2id(map_name), x, y, CLR_OUTSIGHT);
+ }
+ mapreg_setreg(add_str("$@warpwaitingpcnum"), i);
+ return 0;
}
/////////////////////////////////////////////////////////////////////
@@ -10330,12 +10563,13 @@ BUILDIN_FUNC(warpwaitingpc)
/// Detaches a character from a script.
///
/// @param st Script state to detach the character from.
-static void script_detach_rid(struct script_state *st)
+static void script_detach_rid(struct script_state* st)
{
- if (st->rid) {
- script_detach_state(st, false);
- st->rid = 0;
- }
+ if(st->rid)
+ {
+ script_detach_state(st, false);
+ st->rid = 0;
+ }
}
/*==========================================
@@ -10343,38 +10577,38 @@ static void script_detach_rid(struct script_state *st)
*------------------------------------------*/
BUILDIN_FUNC(attachrid)
{
- int rid = script_getnum(st,2);
- struct map_session_data *sd;
+ int rid = script_getnum(st,2);
+ struct map_session_data* sd;
- if ((sd = map_id2sd(rid))!=NULL) {
- script_detach_rid(st);
+ if ((sd = map_id2sd(rid))!=NULL) {
+ script_detach_rid(st);
- st->rid = rid;
- script_attach_state(st);
- script_pushint(st,1);
- } else
- script_pushint(st,0);
- return 0;
+ st->rid = rid;
+ script_attach_state(st);
+ script_pushint(st,1);
+ } else
+ script_pushint(st,0);
+ return 0;
}
/*==========================================
* Detach script to rid
*------------------------------------------*/
BUILDIN_FUNC(detachrid)
{
- script_detach_rid(st);
- return 0;
+ script_detach_rid(st);
+ return 0;
}
/*==========================================
* Chk if account connected, (and charid from account if specified)
*------------------------------------------*/
BUILDIN_FUNC(isloggedin)
{
- TBL_PC *sd = map_id2sd(script_getnum(st,2));
- if (script_hasdata(st,3) && sd &&
- sd->status.char_id != script_getnum(st,3))
- sd = NULL;
- push_val(st->stack,C_INT,sd!=NULL);
- return 0;
+ TBL_PC* sd = map_id2sd(script_getnum(st,2));
+ if (script_hasdata(st,3) && sd &&
+ sd->status.char_id != script_getnum(st,3))
+ sd = NULL;
+ push_val(st->stack,C_INT,sd!=NULL);
+ return 0;
}
@@ -10383,802 +10617,509 @@ BUILDIN_FUNC(isloggedin)
*------------------------------------------*/
BUILDIN_FUNC(setmapflagnosave)
{
- int m,x,y;
- unsigned short mapindex;
- const char *str,*str2;
-
- str=script_getstr(st,2);
- str2=script_getstr(st,3);
- x=script_getnum(st,4);
- y=script_getnum(st,5);
- m = map_mapname2mapid(str);
- mapindex = mapindex_name2id(str2);
-
- if (m >= 0 && mapindex) {
- map[m].flag.nosave=1;
- map[m].save.map=mapindex;
- map[m].save.x=x;
- map[m].save.y=y;
- }
+ int m,x,y;
+ unsigned short mapindex;
+ const char *str,*str2;
- return 0;
+ str=script_getstr(st,2);
+ str2=script_getstr(st,3);
+ x=script_getnum(st,4);
+ y=script_getnum(st,5);
+ m = map_mapname2mapid(str);
+ mapindex = mapindex_name2id(str2);
+
+ if(m >= 0 && mapindex) {
+ map[m].flag.nosave=1;
+ map[m].save.map=mapindex;
+ map[m].save.x=x;
+ map[m].save.y=y;
+ }
+
+ return 0;
}
BUILDIN_FUNC(getmapflag)
{
- int m,i;
- const char *str;
-
- str=script_getstr(st,2);
- i=script_getnum(st,3);
-
- m = map_mapname2mapid(str);
- if (m >= 0) {
- switch (i) {
- case MF_NOMEMO:
- script_pushint(st,map[m].flag.nomemo);
- break;
- case MF_NOTELEPORT:
- script_pushint(st,map[m].flag.noteleport);
- break;
- case MF_NOSAVE:
- script_pushint(st,map[m].flag.nosave);
- break;
- case MF_NOBRANCH:
- script_pushint(st,map[m].flag.nobranch);
- break;
- case MF_NOPENALTY:
- script_pushint(st,map[m].flag.noexppenalty);
- break;
- case MF_NOZENYPENALTY:
- script_pushint(st,map[m].flag.nozenypenalty);
- break;
- case MF_PVP:
- script_pushint(st,map[m].flag.pvp);
- break;
- case MF_PVP_NOPARTY:
- script_pushint(st,map[m].flag.pvp_noparty);
- break;
- case MF_PVP_NOGUILD:
- script_pushint(st,map[m].flag.pvp_noguild);
- break;
- case MF_GVG:
- script_pushint(st,map[m].flag.gvg);
- break;
- case MF_GVG_NOPARTY:
- script_pushint(st,map[m].flag.gvg_noparty);
- break;
- case MF_NOTRADE:
- script_pushint(st,map[m].flag.notrade);
- break;
- case MF_NOSKILL:
- script_pushint(st,map[m].flag.noskill);
- break;
- case MF_NOWARP:
- script_pushint(st,map[m].flag.nowarp);
- break;
- case MF_PARTYLOCK:
- script_pushint(st,map[m].flag.partylock);
- break;
- case MF_NOICEWALL:
- script_pushint(st,map[m].flag.noicewall);
- break;
- case MF_SNOW:
- script_pushint(st,map[m].flag.snow);
- break;
- case MF_FOG:
- script_pushint(st,map[m].flag.fog);
- break;
- case MF_SAKURA:
- script_pushint(st,map[m].flag.sakura);
- break;
- case MF_LEAVES:
- script_pushint(st,map[m].flag.leaves);
- break;
- /**
- * No longer available, keeping here just in case it's back someday. [Ind]
- **/
- //case MF_RAIN: script_pushint(st,map[m].flag.rain); break;
- case MF_NOGO:
- script_pushint(st,map[m].flag.nogo);
- break;
- case MF_CLOUDS:
- script_pushint(st,map[m].flag.clouds);
- break;
- case MF_CLOUDS2:
- script_pushint(st,map[m].flag.clouds2);
- break;
- case MF_FIREWORKS:
- script_pushint(st,map[m].flag.fireworks);
- break;
- case MF_GVG_CASTLE:
- script_pushint(st,map[m].flag.gvg_castle);
- break;
- case MF_GVG_DUNGEON:
- script_pushint(st,map[m].flag.gvg_dungeon);
- break;
- case MF_NIGHTENABLED:
- script_pushint(st,map[m].flag.nightenabled);
- break;
- case MF_NOBASEEXP:
- script_pushint(st,map[m].flag.nobaseexp);
- break;
- case MF_NOJOBEXP:
- script_pushint(st,map[m].flag.nojobexp);
- break;
- case MF_NOMOBLOOT:
- script_pushint(st,map[m].flag.nomobloot);
- break;
- case MF_NOMVPLOOT:
- script_pushint(st,map[m].flag.nomvploot);
- break;
- case MF_NORETURN:
- script_pushint(st,map[m].flag.noreturn);
- break;
- case MF_NOWARPTO:
- script_pushint(st,map[m].flag.nowarpto);
- break;
- case MF_NIGHTMAREDROP:
- script_pushint(st,map[m].flag.pvp_nightmaredrop);
- break;
- case MF_RESTRICTED:
- script_pushint(st,map[m].flag.restricted);
- break;
- case MF_NOCOMMAND:
- script_pushint(st,map[m].nocommand);
- break;
- case MF_NODROP:
- script_pushint(st,map[m].flag.nodrop);
- break;
- case MF_JEXP:
- script_pushint(st,map[m].jexp);
- break;
- case MF_BEXP:
- script_pushint(st,map[m].bexp);
- break;
- case MF_NOVENDING:
- script_pushint(st,map[m].flag.novending);
- break;
- case MF_LOADEVENT:
- script_pushint(st,map[m].flag.loadevent);
- break;
- case MF_NOCHAT:
- script_pushint(st,map[m].flag.nochat);
- break;
- case MF_NOEXPPENALTY:
- script_pushint(st,map[m].flag.noexppenalty);
- break;
- case MF_GUILDLOCK:
- script_pushint(st,map[m].flag.guildlock);
- break;
- case MF_TOWN:
- script_pushint(st,map[m].flag.town);
- break;
- case MF_AUTOTRADE:
- script_pushint(st,map[m].flag.autotrade);
- break;
- case MF_ALLOWKS:
- script_pushint(st,map[m].flag.allowks);
- break;
- case MF_MONSTER_NOTELEPORT:
- script_pushint(st,map[m].flag.monster_noteleport);
- break;
- case MF_PVP_NOCALCRANK:
- script_pushint(st,map[m].flag.pvp_nocalcrank);
- break;
- case MF_BATTLEGROUND:
- script_pushint(st,map[m].flag.battleground);
- break;
- case MF_RESET:
- script_pushint(st,map[m].flag.reset);
- break;
- }
- }
-
- return 0;
+ int m,i;
+ const char *str;
+
+ str=script_getstr(st,2);
+ i=script_getnum(st,3);
+
+ m = map_mapname2mapid(str);
+ if(m >= 0) {
+ switch(i) {
+ case MF_NOMEMO: script_pushint(st,map[m].flag.nomemo); break;
+ case MF_NOTELEPORT: script_pushint(st,map[m].flag.noteleport); break;
+ case MF_NOSAVE: script_pushint(st,map[m].flag.nosave); break;
+ case MF_NOBRANCH: script_pushint(st,map[m].flag.nobranch); break;
+ case MF_NOPENALTY: script_pushint(st,map[m].flag.noexppenalty); break;
+ case MF_NOZENYPENALTY: script_pushint(st,map[m].flag.nozenypenalty); break;
+ case MF_PVP: script_pushint(st,map[m].flag.pvp); break;
+ case MF_PVP_NOPARTY: script_pushint(st,map[m].flag.pvp_noparty); break;
+ case MF_PVP_NOGUILD: script_pushint(st,map[m].flag.pvp_noguild); break;
+ case MF_GVG: script_pushint(st,map[m].flag.gvg); break;
+ case MF_GVG_NOPARTY: script_pushint(st,map[m].flag.gvg_noparty); break;
+ case MF_NOTRADE: script_pushint(st,map[m].flag.notrade); break;
+ case MF_NOSKILL: script_pushint(st,map[m].flag.noskill); break;
+ case MF_NOWARP: script_pushint(st,map[m].flag.nowarp); break;
+ case MF_PARTYLOCK: script_pushint(st,map[m].flag.partylock); break;
+ case MF_NOICEWALL: script_pushint(st,map[m].flag.noicewall); break;
+ case MF_SNOW: script_pushint(st,map[m].flag.snow); break;
+ case MF_FOG: script_pushint(st,map[m].flag.fog); break;
+ case MF_SAKURA: script_pushint(st,map[m].flag.sakura); break;
+ case MF_LEAVES: script_pushint(st,map[m].flag.leaves); break;
+ /**
+ * No longer available, keeping here just in case it's back someday. [Ind]
+ **/
+ //case MF_RAIN: script_pushint(st,map[m].flag.rain); break;
+ case MF_NOGO: script_pushint(st,map[m].flag.nogo); break;
+ case MF_CLOUDS: script_pushint(st,map[m].flag.clouds); break;
+ case MF_CLOUDS2: script_pushint(st,map[m].flag.clouds2); break;
+ case MF_FIREWORKS: script_pushint(st,map[m].flag.fireworks); break;
+ case MF_GVG_CASTLE: script_pushint(st,map[m].flag.gvg_castle); break;
+ case MF_GVG_DUNGEON: script_pushint(st,map[m].flag.gvg_dungeon); break;
+ case MF_NIGHTENABLED: script_pushint(st,map[m].flag.nightenabled); break;
+ case MF_NOBASEEXP: script_pushint(st,map[m].flag.nobaseexp); break;
+ case MF_NOJOBEXP: script_pushint(st,map[m].flag.nojobexp); break;
+ case MF_NOMOBLOOT: script_pushint(st,map[m].flag.nomobloot); break;
+ case MF_NOMVPLOOT: script_pushint(st,map[m].flag.nomvploot); break;
+ case MF_NORETURN: script_pushint(st,map[m].flag.noreturn); break;
+ case MF_NOWARPTO: script_pushint(st,map[m].flag.nowarpto); break;
+ case MF_NIGHTMAREDROP: script_pushint(st,map[m].flag.pvp_nightmaredrop); break;
+ case MF_RESTRICTED: script_pushint(st,map[m].flag.restricted); break;
+ case MF_NOCOMMAND: script_pushint(st,map[m].nocommand); break;
+ case MF_NODROP: script_pushint(st,map[m].flag.nodrop); break;
+ case MF_JEXP: script_pushint(st,map[m].jexp); break;
+ case MF_BEXP: script_pushint(st,map[m].bexp); break;
+ case MF_NOVENDING: script_pushint(st,map[m].flag.novending); break;
+ case MF_LOADEVENT: script_pushint(st,map[m].flag.loadevent); break;
+ case MF_NOCHAT: script_pushint(st,map[m].flag.nochat); break;
+ case MF_NOEXPPENALTY: script_pushint(st,map[m].flag.noexppenalty ); break;
+ case MF_GUILDLOCK: script_pushint(st,map[m].flag.guildlock); break;
+ case MF_TOWN: script_pushint(st,map[m].flag.town); break;
+ case MF_AUTOTRADE: script_pushint(st,map[m].flag.autotrade); break;
+ case MF_ALLOWKS: script_pushint(st,map[m].flag.allowks); break;
+ case MF_MONSTER_NOTELEPORT: script_pushint(st,map[m].flag.monster_noteleport); break;
+ case MF_PVP_NOCALCRANK: script_pushint(st,map[m].flag.pvp_nocalcrank); break;
+ case MF_BATTLEGROUND: script_pushint(st,map[m].flag.battleground); break;
+ case MF_RESET: script_pushint(st,map[m].flag.reset); break;
+ }
+ }
+
+ return 0;
}
/* pvp timer handling */
-static int script_mapflag_pvp_sub(struct block_list *bl,va_list ap)
-{
- TBL_PC *sd = (TBL_PC *)bl;
- if (sd->pvp_timer == INVALID_TIMER) {
- sd->pvp_timer = add_timer(gettick() + 200, pc_calc_pvprank_timer, sd->bl.id, 0);
- sd->pvp_rank = 0;
- sd->pvp_lastusers = 0;
- sd->pvp_point = 5;
- sd->pvp_won = 0;
- sd->pvp_lost = 0;
- }
- clif_map_property(sd, MAPPROPERTY_FREEPVPZONE);
- return 0;
+static int script_mapflag_pvp_sub(struct block_list *bl,va_list ap) {
+ TBL_PC* sd = (TBL_PC*)bl;
+ if (sd->pvp_timer == INVALID_TIMER) {
+ sd->pvp_timer = add_timer(gettick() + 200, pc_calc_pvprank_timer, sd->bl.id, 0);
+ sd->pvp_rank = 0;
+ sd->pvp_lastusers = 0;
+ sd->pvp_point = 5;
+ sd->pvp_won = 0;
+ sd->pvp_lost = 0;
+ }
+ clif_map_property(sd, MAPPROPERTY_FREEPVPZONE);
+ return 0;
}
BUILDIN_FUNC(setmapflag)
{
- int m,i;
- const char *str;
- int val=0;
-
- str=script_getstr(st,2);
- i=script_getnum(st,3);
- if (script_hasdata(st,4)) {
- val=script_getnum(st,4);
- }
- m = map_mapname2mapid(str);
- if (m >= 0) {
- switch (i) {
- case MF_NOMEMO:
- map[m].flag.nomemo = 1;
- break;
- case MF_NOTELEPORT:
- map[m].flag.noteleport = 1;
- break;
- case MF_NOSAVE:
- map[m].flag.nosave = 1;
- break;
- case MF_NOBRANCH:
- map[m].flag.nobranch = 1;
- break;
- case MF_NOPENALTY:
- map[m].flag.noexppenalty = 1;
- map[m].flag.nozenypenalty = 1;
- break;
- case MF_NOZENYPENALTY:
- map[m].flag.nozenypenalty = 1;
- break;
- case MF_PVP:
- map[m].flag.pvp = 1;
- if (!battle_config.pk_mode) {
- map_foreachinmap(script_mapflag_pvp_sub,m,BL_PC);
- }
- break;
- case MF_PVP_NOPARTY:
- map[m].flag.pvp_noparty = 1;
- break;
- case MF_PVP_NOGUILD:
- map[m].flag.pvp_noguild = 1;
- break;
- case MF_GVG:
- map[m].flag.gvg = 1;
- clif_map_property_mapall(m, MAPPROPERTY_AGITZONE);
- break;
- case MF_GVG_NOPARTY:
- map[m].flag.gvg_noparty = 1;
- break;
- case MF_NOTRADE:
- map[m].flag.notrade = 1;
- break;
- case MF_NOSKILL:
- map[m].flag.noskill = 1;
- break;
- case MF_NOWARP:
- map[m].flag.nowarp = 1;
- break;
- case MF_PARTYLOCK:
- map[m].flag.partylock = 1;
- break;
- case MF_NOICEWALL:
- map[m].flag.noicewall = 1;
- break;
- case MF_SNOW:
- map[m].flag.snow = 1;
- break;
- case MF_FOG:
- map[m].flag.fog = 1;
- break;
- case MF_SAKURA:
- map[m].flag.sakura = 1;
- break;
- case MF_LEAVES:
- map[m].flag.leaves = 1;
- break;
- /**
- * No longer available, keeping here just in case it's back someday. [Ind]
- **/
- //case MF_RAIN: map[m].flag.rain = 1; break;
- case MF_NOGO:
- map[m].flag.nogo = 1;
- break;
- case MF_CLOUDS:
- map[m].flag.clouds = 1;
- break;
- case MF_CLOUDS2:
- map[m].flag.clouds2 = 1;
- break;
- case MF_FIREWORKS:
- map[m].flag.fireworks = 1;
- break;
- case MF_GVG_CASTLE:
- map[m].flag.gvg_castle = 1;
- break;
- case MF_GVG_DUNGEON:
- map[m].flag.gvg_dungeon = 1;
- break;
- case MF_NIGHTENABLED:
- map[m].flag.nightenabled = 1;
- break;
- case MF_NOBASEEXP:
- map[m].flag.nobaseexp = 1;
- break;
- case MF_NOJOBEXP:
- map[m].flag.nojobexp = 1;
- break;
- case MF_NOMOBLOOT:
- map[m].flag.nomobloot = 1;
- break;
- case MF_NOMVPLOOT:
- map[m].flag.nomvploot = 1;
- break;
- case MF_NORETURN:
- map[m].flag.noreturn = 1;
- break;
- case MF_NOWARPTO:
- map[m].flag.nowarpto = 1;
- break;
- case MF_NIGHTMAREDROP:
- map[m].flag.pvp_nightmaredrop = 1;
- break;
- case MF_RESTRICTED:
- map[m].zone |= 1<<(val+1);
- map[m].flag.restricted=1;
- break;
- case MF_NOCOMMAND:
- map[m].nocommand = (val <= 0) ? 100 : val;
- break;
- case MF_NODROP:
- map[m].flag.nodrop = 1;
- break;
- case MF_JEXP:
- map[m].jexp = (val <= 0) ? 100 : val;
- break;
- case MF_BEXP:
- map[m].bexp = (val <= 0) ? 100 : val;
- break;
- case MF_NOVENDING:
- map[m].flag.novending = 1;
- break;
- case MF_LOADEVENT:
- map[m].flag.loadevent = 1;
- break;
- case MF_NOCHAT:
- map[m].flag.nochat = 1;
- break;
- case MF_NOEXPPENALTY:
- map[m].flag.noexppenalty = 1;
- break;
- case MF_GUILDLOCK:
- map[m].flag.guildlock = 1;
- break;
- case MF_TOWN:
- map[m].flag.town = 1;
- break;
- case MF_AUTOTRADE:
- map[m].flag.autotrade = 1;
- break;
- case MF_ALLOWKS:
- map[m].flag.allowks = 1;
- break;
- case MF_MONSTER_NOTELEPORT:
- map[m].flag.monster_noteleport = 1;
- break;
- case MF_PVP_NOCALCRANK:
- map[m].flag.pvp_nocalcrank = 1;
- break;
- case MF_BATTLEGROUND:
- map[m].flag.battleground = (val <= 0 || val > 2) ? 1 : val;
- break;
- case MF_RESET:
- map[m].flag.reset = 1;
- break;
- }
- }
-
- return 0;
+ int m,i;
+ const char *str;
+ int val=0;
+
+ str=script_getstr(st,2);
+ i=script_getnum(st,3);
+ if(script_hasdata(st,4)){
+ val=script_getnum(st,4);
+ }
+ m = map_mapname2mapid(str);
+ if(m >= 0) {
+ switch(i) {
+ case MF_NOMEMO: map[m].flag.nomemo = 1; break;
+ case MF_NOTELEPORT: map[m].flag.noteleport = 1; break;
+ case MF_NOSAVE: map[m].flag.nosave = 1; break;
+ case MF_NOBRANCH: map[m].flag.nobranch = 1; break;
+ case MF_NOPENALTY: map[m].flag.noexppenalty = 1; map[m].flag.nozenypenalty = 1; break;
+ case MF_NOZENYPENALTY: map[m].flag.nozenypenalty = 1; break;
+ case MF_PVP:
+ map[m].flag.pvp = 1;
+ if( !battle_config.pk_mode ) {
+ map_foreachinmap(script_mapflag_pvp_sub,m,BL_PC);
+ }
+ break;
+ case MF_PVP_NOPARTY: map[m].flag.pvp_noparty = 1; break;
+ case MF_PVP_NOGUILD: map[m].flag.pvp_noguild = 1; break;
+ case MF_GVG:
+ map[m].flag.gvg = 1;
+ clif_map_property_mapall(m, MAPPROPERTY_AGITZONE);
+ break;
+ case MF_GVG_NOPARTY: map[m].flag.gvg_noparty = 1; break;
+ case MF_NOTRADE: map[m].flag.notrade = 1; break;
+ case MF_NOSKILL: map[m].flag.noskill = 1; break;
+ case MF_NOWARP: map[m].flag.nowarp = 1; break;
+ case MF_PARTYLOCK: map[m].flag.partylock = 1; break;
+ case MF_NOICEWALL: map[m].flag.noicewall = 1; break;
+ case MF_SNOW: map[m].flag.snow = 1; break;
+ case MF_FOG: map[m].flag.fog = 1; break;
+ case MF_SAKURA: map[m].flag.sakura = 1; break;
+ case MF_LEAVES: map[m].flag.leaves = 1; break;
+ /**
+ * No longer available, keeping here just in case it's back someday. [Ind]
+ **/
+ //case MF_RAIN: map[m].flag.rain = 1; break;
+ case MF_NOGO: map[m].flag.nogo = 1; break;
+ case MF_CLOUDS: map[m].flag.clouds = 1; break;
+ case MF_CLOUDS2: map[m].flag.clouds2 = 1; break;
+ case MF_FIREWORKS: map[m].flag.fireworks = 1; break;
+ case MF_GVG_CASTLE: map[m].flag.gvg_castle = 1; break;
+ case MF_GVG_DUNGEON: map[m].flag.gvg_dungeon = 1; break;
+ case MF_NIGHTENABLED: map[m].flag.nightenabled = 1; break;
+ case MF_NOBASEEXP: map[m].flag.nobaseexp = 1; break;
+ case MF_NOJOBEXP: map[m].flag.nojobexp = 1; break;
+ case MF_NOMOBLOOT: map[m].flag.nomobloot = 1; break;
+ case MF_NOMVPLOOT: map[m].flag.nomvploot = 1; break;
+ case MF_NORETURN: map[m].flag.noreturn = 1; break;
+ case MF_NOWARPTO: map[m].flag.nowarpto = 1; break;
+ case MF_NIGHTMAREDROP: map[m].flag.pvp_nightmaredrop = 1; break;
+ case MF_RESTRICTED:
+ map[m].zone |= 1<<(val+1);
+ map[m].flag.restricted=1;
+ break;
+ case MF_NOCOMMAND: map[m].nocommand = (val <= 0) ? 100 : val; break;
+ case MF_NODROP: map[m].flag.nodrop = 1; break;
+ case MF_JEXP: map[m].jexp = (val <= 0) ? 100 : val; break;
+ case MF_BEXP: map[m].bexp = (val <= 0) ? 100 : val; break;
+ case MF_NOVENDING: map[m].flag.novending = 1; break;
+ case MF_LOADEVENT: map[m].flag.loadevent = 1; break;
+ case MF_NOCHAT: map[m].flag.nochat = 1; break;
+ case MF_NOEXPPENALTY: map[m].flag.noexppenalty = 1; break;
+ case MF_GUILDLOCK: map[m].flag.guildlock = 1; break;
+ case MF_TOWN: map[m].flag.town = 1; break;
+ case MF_AUTOTRADE: map[m].flag.autotrade = 1; break;
+ case MF_ALLOWKS: map[m].flag.allowks = 1; break;
+ case MF_MONSTER_NOTELEPORT: map[m].flag.monster_noteleport = 1; break;
+ case MF_PVP_NOCALCRANK: map[m].flag.pvp_nocalcrank = 1; break;
+ case MF_BATTLEGROUND: map[m].flag.battleground = (val <= 0 || val > 2) ? 1 : val; break;
+ case MF_RESET: map[m].flag.reset = 1; break;
+ }
+ }
+
+ return 0;
}
BUILDIN_FUNC(removemapflag)
{
- int m,i;
- const char *str;
- int val=0;
-
- str=script_getstr(st,2);
- i=script_getnum(st,3);
- if (script_hasdata(st,4)) {
- val=script_getnum(st,4);
- }
- m = map_mapname2mapid(str);
- if (m >= 0) {
- switch (i) {
- case MF_NOMEMO:
- map[m].flag.nomemo = 0;
- break;
- case MF_NOTELEPORT:
- map[m].flag.noteleport = 0;
- break;
- case MF_NOSAVE:
- map[m].flag.nosave = 0;
- break;
- case MF_NOBRANCH:
- map[m].flag.nobranch = 0;
- break;
- case MF_NOPENALTY:
- map[m].flag.noexppenalty = 0;
- map[m].flag.nozenypenalty = 0;
- break;
- case MF_NOZENYPENALTY:
- map[m].flag.nozenypenalty = 0;
- break;
- case MF_PVP:
- map[m].flag.pvp = 0;
- clif_map_property_mapall(m, MAPPROPERTY_NOTHING);
- break;
- case MF_PVP_NOPARTY:
- map[m].flag.pvp_noparty = 0;
- break;
- case MF_PVP_NOGUILD:
- map[m].flag.pvp_noguild = 0;
- break;
- case MF_GVG:
- map[m].flag.gvg = 0;
- clif_map_property_mapall(m, MAPPROPERTY_NOTHING);
- break;
- case MF_GVG_NOPARTY:
- map[m].flag.gvg_noparty = 0;
- break;
- case MF_NOTRADE:
- map[m].flag.notrade = 0;
- break;
- case MF_NOSKILL:
- map[m].flag.noskill = 0;
- break;
- case MF_NOWARP:
- map[m].flag.nowarp = 0;
- break;
- case MF_PARTYLOCK:
- map[m].flag.partylock = 0;
- break;
- case MF_NOICEWALL:
- map[m].flag.noicewall = 0;
- break;
- case MF_SNOW:
- map[m].flag.snow = 0;
- break;
- case MF_FOG:
- map[m].flag.fog = 0;
- break;
- case MF_SAKURA:
- map[m].flag.sakura = 0;
- break;
- case MF_LEAVES:
- map[m].flag.leaves = 0;
- break;
- /**
- * No longer available, keeping here just in case it's back someday. [Ind]
- **/
- //case MF_RAIN: map[m].flag.rain = 0; break;
- case MF_NOGO:
- map[m].flag.nogo = 0;
- break;
- case MF_CLOUDS:
- map[m].flag.clouds = 0;
- break;
- case MF_CLOUDS2:
- map[m].flag.clouds2 = 0;
- break;
- case MF_FIREWORKS:
- map[m].flag.fireworks = 0;
- break;
- case MF_GVG_CASTLE:
- map[m].flag.gvg_castle = 0;
- break;
- case MF_GVG_DUNGEON:
- map[m].flag.gvg_dungeon = 0;
- break;
- case MF_NIGHTENABLED:
- map[m].flag.nightenabled = 0;
- break;
- case MF_NOBASEEXP:
- map[m].flag.nobaseexp = 0;
- break;
- case MF_NOJOBEXP:
- map[m].flag.nojobexp = 0;
- break;
- case MF_NOMOBLOOT:
- map[m].flag.nomobloot = 0;
- break;
- case MF_NOMVPLOOT:
- map[m].flag.nomvploot = 0;
- break;
- case MF_NORETURN:
- map[m].flag.noreturn = 0;
- break;
- case MF_NOWARPTO:
- map[m].flag.nowarpto = 0;
- break;
- case MF_NIGHTMAREDROP:
- map[m].flag.pvp_nightmaredrop = 0;
- break;
- case MF_RESTRICTED:
- map[m].zone ^= 1<<(val+1);
- if (map[m].zone == 0) {
- map[m].flag.restricted=0;
- }
- break;
- case MF_NOCOMMAND:
- map[m].nocommand = 0;
- break;
- case MF_NODROP:
- map[m].flag.nodrop = 0;
- break;
- case MF_JEXP:
- map[m].jexp = 0;
- break;
- case MF_BEXP:
- map[m].bexp = 0;
- break;
- case MF_NOVENDING:
- map[m].flag.novending = 0;
- break;
- case MF_LOADEVENT:
- map[m].flag.loadevent = 0;
- break;
- case MF_NOCHAT:
- map[m].flag.nochat = 0;
- break;
- case MF_NOEXPPENALTY:
- map[m].flag.noexppenalty = 0;
- break;
- case MF_GUILDLOCK:
- map[m].flag.guildlock = 0;
- break;
- case MF_TOWN:
- map[m].flag.town = 0;
- break;
- case MF_AUTOTRADE:
- map[m].flag.autotrade = 0;
- break;
- case MF_ALLOWKS:
- map[m].flag.allowks = 0;
- break;
- case MF_MONSTER_NOTELEPORT:
- map[m].flag.monster_noteleport = 0;
- break;
- case MF_PVP_NOCALCRANK:
- map[m].flag.pvp_nocalcrank = 0;
- break;
- case MF_BATTLEGROUND:
- map[m].flag.battleground = 0;
- break;
- case MF_RESET:
- map[m].flag.reset = 0;
- break;
- }
- }
-
- return 0;
+ int m,i;
+ const char *str;
+ int val=0;
+
+ str=script_getstr(st,2);
+ i=script_getnum(st,3);
+ if(script_hasdata(st,4)){
+ val=script_getnum(st,4);
+ }
+ m = map_mapname2mapid(str);
+ if(m >= 0) {
+ switch(i) {
+ case MF_NOMEMO: map[m].flag.nomemo = 0; break;
+ case MF_NOTELEPORT: map[m].flag.noteleport = 0; break;
+ case MF_NOSAVE: map[m].flag.nosave = 0; break;
+ case MF_NOBRANCH: map[m].flag.nobranch = 0; break;
+ case MF_NOPENALTY: map[m].flag.noexppenalty = 0; map[m].flag.nozenypenalty = 0; break;
+ case MF_NOZENYPENALTY: map[m].flag.nozenypenalty = 0; break;
+ case MF_PVP:
+ map[m].flag.pvp = 0;
+ clif_map_property_mapall(m, MAPPROPERTY_NOTHING);
+ break;
+ case MF_PVP_NOPARTY: map[m].flag.pvp_noparty = 0; break;
+ case MF_PVP_NOGUILD: map[m].flag.pvp_noguild = 0; break;
+ case MF_GVG:
+ map[m].flag.gvg = 0;
+ clif_map_property_mapall(m, MAPPROPERTY_NOTHING);
+ break;
+ case MF_GVG_NOPARTY: map[m].flag.gvg_noparty = 0; break;
+ case MF_NOTRADE: map[m].flag.notrade = 0; break;
+ case MF_NOSKILL: map[m].flag.noskill = 0; break;
+ case MF_NOWARP: map[m].flag.nowarp = 0; break;
+ case MF_PARTYLOCK: map[m].flag.partylock = 0; break;
+ case MF_NOICEWALL: map[m].flag.noicewall = 0; break;
+ case MF_SNOW: map[m].flag.snow = 0; break;
+ case MF_FOG: map[m].flag.fog = 0; break;
+ case MF_SAKURA: map[m].flag.sakura = 0; break;
+ case MF_LEAVES: map[m].flag.leaves = 0; break;
+ /**
+ * No longer available, keeping here just in case it's back someday. [Ind]
+ **/
+ //case MF_RAIN: map[m].flag.rain = 0; break;
+ case MF_NOGO: map[m].flag.nogo = 0; break;
+ case MF_CLOUDS: map[m].flag.clouds = 0; break;
+ case MF_CLOUDS2: map[m].flag.clouds2 = 0; break;
+ case MF_FIREWORKS: map[m].flag.fireworks = 0; break;
+ case MF_GVG_CASTLE: map[m].flag.gvg_castle = 0; break;
+ case MF_GVG_DUNGEON: map[m].flag.gvg_dungeon = 0; break;
+ case MF_NIGHTENABLED: map[m].flag.nightenabled = 0; break;
+ case MF_NOBASEEXP: map[m].flag.nobaseexp = 0; break;
+ case MF_NOJOBEXP: map[m].flag.nojobexp = 0; break;
+ case MF_NOMOBLOOT: map[m].flag.nomobloot = 0; break;
+ case MF_NOMVPLOOT: map[m].flag.nomvploot = 0; break;
+ case MF_NORETURN: map[m].flag.noreturn = 0; break;
+ case MF_NOWARPTO: map[m].flag.nowarpto = 0; break;
+ case MF_NIGHTMAREDROP: map[m].flag.pvp_nightmaredrop = 0; break;
+ case MF_RESTRICTED:
+ map[m].zone ^= 1<<(val+1);
+ if (map[m].zone == 0){
+ map[m].flag.restricted=0;
+ }
+ break;
+ case MF_NOCOMMAND: map[m].nocommand = 0; break;
+ case MF_NODROP: map[m].flag.nodrop = 0; break;
+ case MF_JEXP: map[m].jexp = 0; break;
+ case MF_BEXP: map[m].bexp = 0; break;
+ case MF_NOVENDING: map[m].flag.novending = 0; break;
+ case MF_LOADEVENT: map[m].flag.loadevent = 0; break;
+ case MF_NOCHAT: map[m].flag.nochat = 0; break;
+ case MF_NOEXPPENALTY: map[m].flag.noexppenalty = 0; break;
+ case MF_GUILDLOCK: map[m].flag.guildlock = 0; break;
+ case MF_TOWN: map[m].flag.town = 0; break;
+ case MF_AUTOTRADE: map[m].flag.autotrade = 0; break;
+ case MF_ALLOWKS: map[m].flag.allowks = 0; break;
+ case MF_MONSTER_NOTELEPORT: map[m].flag.monster_noteleport = 0; break;
+ case MF_PVP_NOCALCRANK: map[m].flag.pvp_nocalcrank = 0; break;
+ case MF_BATTLEGROUND: map[m].flag.battleground = 0; break;
+ case MF_RESET: map[m].flag.reset = 0; break;
+ }
+ }
+
+ return 0;
}
BUILDIN_FUNC(pvpon)
{
- int m;
- const char *str;
- TBL_PC *sd = NULL;
- struct s_mapiterator *iter;
+ int m;
+ const char *str;
+ TBL_PC* sd = NULL;
+ struct s_mapiterator* iter;
- str = script_getstr(st,2);
- m = map_mapname2mapid(str);
- if (m < 0 || map[m].flag.pvp)
- return 0; // nothing to do
+ str = script_getstr(st,2);
+ m = map_mapname2mapid(str);
+ if( m < 0 || map[m].flag.pvp )
+ return 0; // nothing to do
- map[m].flag.pvp = 1;
- clif_map_property_mapall(m, MAPPROPERTY_FREEPVPZONE);
+ map[m].flag.pvp = 1;
+ clif_map_property_mapall(m, MAPPROPERTY_FREEPVPZONE);
- if (battle_config.pk_mode) // disable ranking functions if pk_mode is on [Valaris]
- return 0;
+ if(battle_config.pk_mode) // disable ranking functions if pk_mode is on [Valaris]
+ return 0;
- iter = mapit_getallusers();
- for (sd = (TBL_PC *)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC *)mapit_next(iter)) {
- if (sd->bl.m != m || sd->pvp_timer != INVALID_TIMER)
- continue; // not applicable
-
- sd->pvp_timer = add_timer(gettick()+200,pc_calc_pvprank_timer,sd->bl.id,0);
- sd->pvp_rank = 0;
- sd->pvp_lastusers = 0;
- sd->pvp_point = 5;
- sd->pvp_won = 0;
- sd->pvp_lost = 0;
- }
- mapit_free(iter);
+ iter = mapit_getallusers();
+ for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
+ {
+ if( sd->bl.m != m || sd->pvp_timer != INVALID_TIMER )
+ continue; // not applicable
- return 0;
+ sd->pvp_timer = add_timer(gettick()+200,pc_calc_pvprank_timer,sd->bl.id,0);
+ sd->pvp_rank = 0;
+ sd->pvp_lastusers = 0;
+ sd->pvp_point = 5;
+ sd->pvp_won = 0;
+ sd->pvp_lost = 0;
+ }
+ mapit_free(iter);
+
+ return 0;
}
static int buildin_pvpoff_sub(struct block_list *bl,va_list ap)
{
- TBL_PC *sd = (TBL_PC *)bl;
- clif_pvpset(sd, 0, 0, 2);
- if (sd->pvp_timer != INVALID_TIMER) {
- delete_timer(sd->pvp_timer, pc_calc_pvprank_timer);
- sd->pvp_timer = INVALID_TIMER;
- }
- return 0;
+ TBL_PC* sd = (TBL_PC*)bl;
+ clif_pvpset(sd, 0, 0, 2);
+ if (sd->pvp_timer != INVALID_TIMER) {
+ delete_timer(sd->pvp_timer, pc_calc_pvprank_timer);
+ sd->pvp_timer = INVALID_TIMER;
+ }
+ return 0;
}
BUILDIN_FUNC(pvpoff)
{
- int m;
- const char *str;
+ int m;
+ const char *str;
- str=script_getstr(st,2);
- m = map_mapname2mapid(str);
- if (m < 0 || !map[m].flag.pvp)
- return 0; //fixed Lupus
+ str=script_getstr(st,2);
+ m = map_mapname2mapid(str);
+ if(m < 0 || !map[m].flag.pvp)
+ return 0; //fixed Lupus
- map[m].flag.pvp = 0;
- clif_map_property_mapall(m, MAPPROPERTY_NOTHING);
+ map[m].flag.pvp = 0;
+ clif_map_property_mapall(m, MAPPROPERTY_NOTHING);
- if (battle_config.pk_mode) // disable ranking options if pk_mode is on [Valaris]
- return 0;
+ if(battle_config.pk_mode) // disable ranking options if pk_mode is on [Valaris]
+ return 0;
- map_foreachinmap(buildin_pvpoff_sub, m, BL_PC);
- return 0;
+ map_foreachinmap(buildin_pvpoff_sub, m, BL_PC);
+ return 0;
}
BUILDIN_FUNC(gvgon)
{
- int m;
- const char *str;
+ int m;
+ const char *str;
- str=script_getstr(st,2);
- m = map_mapname2mapid(str);
- if (m >= 0 && !map[m].flag.gvg) {
- map[m].flag.gvg = 1;
- clif_map_property_mapall(m, MAPPROPERTY_AGITZONE);
- }
+ str=script_getstr(st,2);
+ m = map_mapname2mapid(str);
+ if(m >= 0 && !map[m].flag.gvg) {
+ map[m].flag.gvg = 1;
+ clif_map_property_mapall(m, MAPPROPERTY_AGITZONE);
+ }
- return 0;
+ return 0;
}
BUILDIN_FUNC(gvgoff)
{
- int m;
- const char *str;
+ int m;
+ const char *str;
- str=script_getstr(st,2);
- m = map_mapname2mapid(str);
- if (m >= 0 && map[m].flag.gvg) {
- map[m].flag.gvg = 0;
- clif_map_property_mapall(m, MAPPROPERTY_NOTHING);
- }
+ str=script_getstr(st,2);
+ m = map_mapname2mapid(str);
+ if(m >= 0 && map[m].flag.gvg) {
+ map[m].flag.gvg = 0;
+ clif_map_property_mapall(m, MAPPROPERTY_NOTHING);
+ }
- return 0;
+ return 0;
}
/*==========================================
- * Shows an emoticon on top of the player/npc
- * emotion emotion#, <target: 0 - NPC, 1 - PC>, <NPC/PC name>
+ * Shows an emoticon on top of the player/npc
+ * emotion emotion#, <target: 0 - NPC, 1 - PC>, <NPC/PC name>
*------------------------------------------*/
//Optional second parameter added by [Skotlex]
BUILDIN_FUNC(emotion)
{
- int type;
- int player=0;
-
- type=script_getnum(st,2);
- if (type < 0 || type > 100)
- return 0;
-
- if (script_hasdata(st,3))
- player=script_getnum(st,3);
-
- if (player) {
- TBL_PC *sd = NULL;
- if (script_hasdata(st,4))
- sd = map_nick2sd(script_getstr(st,4));
- else
- sd = script_rid2sd(st);
- if (sd)
- clif_emotion(&sd->bl,type);
- } else if (script_hasdata(st,4)) {
- TBL_NPC *nd = npc_name2id(script_getstr(st,4));
- if (nd)
- clif_emotion(&nd->bl,type);
- } else
- clif_emotion(map_id2bl(st->oid),type);
- return 0;
-}
-
-static int buildin_maprespawnguildid_sub_pc(struct map_session_data *sd, va_list ap)
-{
- int m=va_arg(ap,int);
- int g_id=va_arg(ap,int);
- int flag=va_arg(ap,int);
-
- if (!sd || sd->bl.m != m)
- return 0;
- if (
- (sd->status.guild_id == g_id && flag&1) || //Warp out owners
- (sd->status.guild_id != g_id && flag&2) || //Warp out outsiders
- (sd->status.guild_id == 0) // Warp out players not in guild [Valaris]
- )
- pc_setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT);
- return 1;
+ int type;
+ int player=0;
+
+ type=script_getnum(st,2);
+ if(type < 0 || type > 100)
+ return 0;
+
+ if( script_hasdata(st,3) )
+ player=script_getnum(st,3);
+
+ if (player) {
+ TBL_PC *sd = NULL;
+ if( script_hasdata(st,4) )
+ sd = map_nick2sd(script_getstr(st,4));
+ else
+ sd = script_rid2sd(st);
+ if (sd)
+ clif_emotion(&sd->bl,type);
+ } else
+ if( script_hasdata(st,4) )
+ {
+ TBL_NPC *nd = npc_name2id(script_getstr(st,4));
+ if(nd)
+ clif_emotion(&nd->bl,type);
+ }
+ else
+ clif_emotion(map_id2bl(st->oid),type);
+ return 0;
+}
+
+static int buildin_maprespawnguildid_sub_pc(struct map_session_data* sd, va_list ap)
+{
+ int m=va_arg(ap,int);
+ int g_id=va_arg(ap,int);
+ int flag=va_arg(ap,int);
+
+ if(!sd || sd->bl.m != m)
+ return 0;
+ if(
+ (sd->status.guild_id == g_id && flag&1) || //Warp out owners
+ (sd->status.guild_id != g_id && flag&2) || //Warp out outsiders
+ (sd->status.guild_id == 0) // Warp out players not in guild [Valaris]
+ )
+ pc_setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT);
+ return 1;
}
static int buildin_maprespawnguildid_sub_mob(struct block_list *bl,va_list ap)
{
- struct mob_data *md=(struct mob_data *)bl;
+ struct mob_data *md=(struct mob_data *)bl;
- if (!md->guardian_data && md->class_ != MOBID_EMPERIUM)
- status_kill(bl);
+ if(!md->guardian_data && md->class_ != MOBID_EMPERIUM)
+ status_kill(bl);
- return 0;
+ return 0;
}
BUILDIN_FUNC(maprespawnguildid)
{
- const char *mapname=script_getstr(st,2);
- int g_id=script_getnum(st,3);
- int flag=script_getnum(st,4);
+ const char *mapname=script_getstr(st,2);
+ int g_id=script_getnum(st,3);
+ int flag=script_getnum(st,4);
- int m=map_mapname2mapid(mapname);
+ int m=map_mapname2mapid(mapname);
- if (m == -1)
- return 0;
+ if(m == -1)
+ return 0;
- //Catch ALL players (in case some are 'between maps' on execution time)
- map_foreachpc(buildin_maprespawnguildid_sub_pc,m,g_id,flag);
- if (flag&4) //Remove script mobs.
- map_foreachinmap(buildin_maprespawnguildid_sub_mob,m,BL_MOB);
- return 0;
+ //Catch ALL players (in case some are 'between maps' on execution time)
+ map_foreachpc(buildin_maprespawnguildid_sub_pc,m,g_id,flag);
+ if (flag&4) //Remove script mobs.
+ map_foreachinmap(buildin_maprespawnguildid_sub_mob,m,BL_MOB);
+ return 0;
}
BUILDIN_FUNC(agitstart)
{
- if (agit_flag==1) return 0; // Agit already Start.
- agit_flag=1;
- guild_agit_start();
- return 0;
+ if(agit_flag==1) return 0; // Agit already Start.
+ agit_flag=1;
+ guild_agit_start();
+ return 0;
}
BUILDIN_FUNC(agitend)
{
- if (agit_flag==0) return 0; // Agit already End.
- agit_flag=0;
- guild_agit_end();
- return 0;
+ if(agit_flag==0) return 0; // Agit already End.
+ agit_flag=0;
+ guild_agit_end();
+ return 0;
}
BUILDIN_FUNC(agitstart2)
{
- if (agit2_flag==1) return 0; // Agit2 already Start.
- agit2_flag=1;
- guild_agit2_start();
- return 0;
+ if(agit2_flag==1) return 0; // Agit2 already Start.
+ agit2_flag=1;
+ guild_agit2_start();
+ return 0;
}
BUILDIN_FUNC(agitend2)
{
- if (agit2_flag==0) return 0; // Agit2 already End.
- agit2_flag=0;
- guild_agit2_end();
- return 0;
+ if(agit2_flag==0) return 0; // Agit2 already End.
+ agit2_flag=0;
+ guild_agit2_end();
+ return 0;
}
/*==========================================
- * Returns whether woe is on or off. // choice script
+ * Returns whether woe is on or off. // choice script
*------------------------------------------*/
BUILDIN_FUNC(agitcheck)
{
- script_pushint(st,agit_flag);
- return 0;
+ script_pushint(st,agit_flag);
+ return 0;
}
/*==========================================
- * Returns whether woese is on or off. // choice script
+ * Returns whether woese is on or off. // choice script
*------------------------------------------*/
BUILDIN_FUNC(agitcheck2)
{
- script_pushint(st,agit2_flag);
- return 0;
+ script_pushint(st,agit2_flag);
+ return 0;
}
/// Sets the guild_id of this npc.
@@ -11186,219 +11127,210 @@ BUILDIN_FUNC(agitcheck2)
/// flagemblem <guild_id>;
BUILDIN_FUNC(flagemblem)
{
- TBL_NPC *nd;
- int g_id = script_getnum(st,2);
-
- if (g_id < 0) return 0;
-
- nd = (TBL_NPC *)map_id2nd(st->oid);
- if (nd == NULL) {
- ShowError("script:flagemblem: npc %d not found\n", st->oid);
- } else if (nd->subtype != SCRIPT) {
- ShowError("script:flagemblem: unexpected subtype %d for npc %d '%s'\n", nd->subtype, st->oid, nd->exname);
- } else {
- bool changed = (nd->u.scr.guild_id != g_id)?true:false;
- nd->u.scr.guild_id = g_id;
- clif_guild_emblem_area(&nd->bl);
- /* guild flag caching */
- if (g_id) /* adding a id */
- guild_flag_add(nd);
- else if (changed) /* removing a flag */
- guild_flag_remove(nd);
- }
- return 0;
+ TBL_NPC* nd;
+ int g_id = script_getnum(st,2);
+
+ if(g_id < 0) return 0;
+
+ nd = (TBL_NPC*)map_id2nd(st->oid);
+ if( nd == NULL ) {
+ ShowError("script:flagemblem: npc %d not found\n", st->oid);
+ } else if( nd->subtype != SCRIPT ) {
+ ShowError("script:flagemblem: unexpected subtype %d for npc %d '%s'\n", nd->subtype, st->oid, nd->exname);
+ } else {
+ bool changed = ( nd->u.scr.guild_id != g_id )?true:false;
+ nd->u.scr.guild_id = g_id;
+ clif_guild_emblem_area(&nd->bl);
+ /* guild flag caching */
+ if( g_id ) /* adding a id */
+ guild_flag_add(nd);
+ else if( changed ) /* removing a flag */
+ guild_flag_remove(nd);
+ }
+ return 0;
}
BUILDIN_FUNC(getcastlename)
{
- const char *mapname = mapindex_getmapname(script_getstr(st,2),NULL);
- struct guild_castle *gc = guild_mapname2gc(mapname);
- const char *name = (gc) ? gc->castle_name : "";
- script_pushstrcopy(st,name);
- return 0;
+ const char* mapname = mapindex_getmapname(script_getstr(st,2),NULL);
+ struct guild_castle* gc = guild_mapname2gc(mapname);
+ const char* name = (gc) ? gc->castle_name : "";
+ script_pushstrcopy(st,name);
+ return 0;
}
BUILDIN_FUNC(getcastledata)
{
- const char *mapname = mapindex_getmapname(script_getstr(st,2),NULL);
- int index = script_getnum(st,3);
- struct guild_castle *gc = guild_mapname2gc(mapname);
-
- if (gc == NULL) {
- script_pushint(st,0);
- ShowWarning("buildin_setcastledata: guild castle for map '%s' not found\n", mapname);
- return 1;
- }
-
- switch (index) {
- case 1:
- script_pushint(st,gc->guild_id);
- break;
- case 2:
- script_pushint(st,gc->economy);
- break;
- case 3:
- script_pushint(st,gc->defense);
- break;
- case 4:
- script_pushint(st,gc->triggerE);
- break;
- case 5:
- script_pushint(st,gc->triggerD);
- break;
- case 6:
- script_pushint(st,gc->nextTime);
- break;
- case 7:
- script_pushint(st,gc->payTime);
- break;
- case 8:
- script_pushint(st,gc->createTime);
- break;
- case 9:
- script_pushint(st,gc->visibleC);
- break;
- default:
- if (index > 9 && index <= 9+MAX_GUARDIANS) {
- script_pushint(st,gc->guardian[index-10].visible);
- break;
- }
- script_pushint(st,0);
- ShowWarning("buildin_setcastledata: index = '%d' is out of allowed range\n", index);
- return 1;
- }
- return 0;
+ const char *mapname = mapindex_getmapname(script_getstr(st,2),NULL);
+ int index = script_getnum(st,3);
+ struct guild_castle *gc = guild_mapname2gc(mapname);
+
+ if (gc == NULL) {
+ script_pushint(st,0);
+ ShowWarning("buildin_setcastledata: guild castle for map '%s' not found\n", mapname);
+ return 1;
+ }
+
+ switch (index) {
+ case 1:
+ script_pushint(st,gc->guild_id); break;
+ case 2:
+ script_pushint(st,gc->economy); break;
+ case 3:
+ script_pushint(st,gc->defense); break;
+ case 4:
+ script_pushint(st,gc->triggerE); break;
+ case 5:
+ script_pushint(st,gc->triggerD); break;
+ case 6:
+ script_pushint(st,gc->nextTime); break;
+ case 7:
+ script_pushint(st,gc->payTime); break;
+ case 8:
+ script_pushint(st,gc->createTime); break;
+ case 9:
+ script_pushint(st,gc->visibleC); break;
+ default:
+ if (index > 9 && index <= 9+MAX_GUARDIANS) {
+ script_pushint(st,gc->guardian[index-10].visible);
+ break;
+ }
+ script_pushint(st,0);
+ ShowWarning("buildin_setcastledata: index = '%d' is out of allowed range\n", index);
+ return 1;
+ }
+ return 0;
}
BUILDIN_FUNC(setcastledata)
{
- const char *mapname = mapindex_getmapname(script_getstr(st,2),NULL);
- int index = script_getnum(st,3);
- int value = script_getnum(st,4);
- struct guild_castle *gc = guild_mapname2gc(mapname);
+ const char *mapname = mapindex_getmapname(script_getstr(st,2),NULL);
+ int index = script_getnum(st,3);
+ int value = script_getnum(st,4);
+ struct guild_castle *gc = guild_mapname2gc(mapname);
- if (gc == NULL) {
- ShowWarning("buildin_setcastledata: guild castle for map '%s' not found\n", mapname);
- return 1;
- }
+ if (gc == NULL) {
+ ShowWarning("buildin_setcastledata: guild castle for map '%s' not found\n", mapname);
+ return 1;
+ }
- if (index <= 0 || index > 9+MAX_GUARDIANS) {
- ShowWarning("buildin_setcastledata: index = '%d' is out of allowed range\n", index);
- return 1;
- }
+ if (index <= 0 || index > 9+MAX_GUARDIANS) {
+ ShowWarning("buildin_setcastledata: index = '%d' is out of allowed range\n", index);
+ return 1;
+ }
- guild_castledatasave(gc->castle_id, index, value);
- return 0;
+ guild_castledatasave(gc->castle_id, index, value);
+ return 0;
}
/* =====================================================================
* ---------------------------------------------------------------------*/
BUILDIN_FUNC(requestguildinfo)
{
- int guild_id=script_getnum(st,2);
- const char *event=NULL;
+ int guild_id=script_getnum(st,2);
+ const char *event=NULL;
- if (script_hasdata(st,3)) {
- event=script_getstr(st,3);
- check_event(st, event);
- }
+ if( script_hasdata(st,3) ){
+ event=script_getstr(st,3);
+ check_event(st, event);
+ }
- if (guild_id>0)
- guild_npc_request_info(guild_id,event);
- return 0;
+ if(guild_id>0)
+ guild_npc_request_info(guild_id,event);
+ return 0;
}
/// Returns the number of cards that have been compounded onto the specified equipped item.
/// getequipcardcnt(<equipment slot>);
BUILDIN_FUNC(getequipcardcnt)
{
- int i=-1,j,num;
- TBL_PC *sd;
- int count;
+ int i=-1,j,num;
+ TBL_PC *sd;
+ int count;
- num=script_getnum(st,2);
- sd=script_rid2sd(st);
- if (num > 0 && num <= ARRAYLENGTH(equip))
- i=pc_checkequip(sd,equip[num-1]);
+ num=script_getnum(st,2);
+ sd=script_rid2sd(st);
+ if (num > 0 && num <= ARRAYLENGTH(equip))
+ i=pc_checkequip(sd,equip[num-1]);
- if (i < 0 || !sd->inventory_data[i]) {
- script_pushint(st,0);
- return 0;
- }
+ if (i < 0 || !sd->inventory_data[i]) {
+ script_pushint(st,0);
+ return 0;
+ }
- if (itemdb_isspecial(sd->status.inventory[i].card[0])) {
- script_pushint(st,0);
- return 0;
- }
+ if(itemdb_isspecial(sd->status.inventory[i].card[0]))
+ {
+ script_pushint(st,0);
+ return 0;
+ }
- count = 0;
- for (j = 0; j < sd->inventory_data[i]->slot; j++)
- if (sd->status.inventory[i].card[j] && itemdb_type(sd->status.inventory[i].card[j]) == IT_CARD)
- count++;
+ count = 0;
+ for( j = 0; j < sd->inventory_data[i]->slot; j++ )
+ if( sd->status.inventory[i].card[j] && itemdb_type(sd->status.inventory[i].card[j]) == IT_CARD )
+ count++;
- script_pushint(st,count);
- return 0;
+ script_pushint(st,count);
+ return 0;
}
/// Removes all cards from the item found in the specified equipment slot of the invoking character,
/// and give them to the character. If any cards were removed in this manner, it will also show a success effect.
/// successremovecards <slot>;
-BUILDIN_FUNC(successremovecards)
-{
- int i=-1,j,c,cardflag=0;
-
- TBL_PC *sd = script_rid2sd(st);
- int num = script_getnum(st,2);
-
- if (num > 0 && num <= ARRAYLENGTH(equip))
- i=pc_checkequip(sd,equip[num-1]);
-
- if (i < 0 || !sd->inventory_data[i]) {
- return 0;
- }
-
- if (itemdb_isspecial(sd->status.inventory[i].card[0]))
- return 0;
-
- for (c = sd->inventory_data[i]->slot - 1; c >= 0; --c) {
- if (sd->status.inventory[i].card[c] && itemdb_type(sd->status.inventory[i].card[c]) == IT_CARD) { // extract this card from the item
- int flag;
- struct item item_tmp;
- memset(&item_tmp,0,sizeof(item_tmp));
- cardflag = 1;
- item_tmp.nameid = sd->status.inventory[i].card[c];
- item_tmp.identify = 1;
-
- if ((flag=pc_additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))) { // get back the cart in inventory
- clif_additem(sd,0,0,flag);
- map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
- }
- }
- }
-
- if (cardflag == 1) { //if card was remove remplace item with no card
- int flag;
- struct item item_tmp;
- memset(&item_tmp,0,sizeof(item_tmp));
-
- item_tmp.nameid = sd->status.inventory[i].nameid;
- item_tmp.identify = 1;
- item_tmp.refine = sd->status.inventory[i].refine;
- item_tmp.attribute = sd->status.inventory[i].attribute;
- item_tmp.expire_time = sd->status.inventory[i].expire_time;
-
- for (j = sd->inventory_data[i]->slot; j < MAX_SLOTS; j++)
- item_tmp.card[j]=sd->status.inventory[i].card[j];
-
- pc_delitem(sd,i,1,0,3,LOG_TYPE_SCRIPT);
- if ((flag=pc_additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))) { //chk if can be spawn in inventory otherwise put on floor
- clif_additem(sd,0,0,flag);
- map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
- }
-
- clif_misceffect(&sd->bl,3);
- }
- return 0;
+BUILDIN_FUNC(successremovecards) {
+ int i=-1,j,c,cardflag=0;
+
+ TBL_PC* sd = script_rid2sd(st);
+ int num = script_getnum(st,2);
+
+ if (num > 0 && num <= ARRAYLENGTH(equip))
+ i=pc_checkequip(sd,equip[num-1]);
+
+ if (i < 0 || !sd->inventory_data[i]) {
+ return 0;
+ }
+
+ if(itemdb_isspecial(sd->status.inventory[i].card[0]))
+ return 0;
+
+ for( c = sd->inventory_data[i]->slot - 1; c >= 0; --c ) {
+ if( sd->status.inventory[i].card[c] && itemdb_type(sd->status.inventory[i].card[c]) == IT_CARD ) {// extract this card from the item
+ int flag;
+ struct item item_tmp;
+ memset(&item_tmp,0,sizeof(item_tmp));
+ cardflag = 1;
+ item_tmp.nameid = sd->status.inventory[i].card[c];
+ item_tmp.identify = 1;
+
+ if((flag=pc_additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))){ // get back the cart in inventory
+ clif_additem(sd,0,0,flag);
+ map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ }
+ }
+ }
+
+ if(cardflag == 1) {//if card was remove remplace item with no card
+ int flag;
+ struct item item_tmp;
+ memset(&item_tmp,0,sizeof(item_tmp));
+
+ item_tmp.nameid = sd->status.inventory[i].nameid;
+ item_tmp.identify = 1;
+ item_tmp.refine = sd->status.inventory[i].refine;
+ item_tmp.attribute = sd->status.inventory[i].attribute;
+ item_tmp.expire_time = sd->status.inventory[i].expire_time;
+
+ for (j = sd->inventory_data[i]->slot; j < MAX_SLOTS; j++)
+ item_tmp.card[j]=sd->status.inventory[i].card[j];
+
+ pc_delitem(sd,i,1,0,3,LOG_TYPE_SCRIPT);
+ if((flag=pc_additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))){ //chk if can be spawn in inventory otherwise put on floor
+ clif_additem(sd,0,0,flag);
+ map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ }
+
+ clif_misceffect(&sd->bl,3);
+ }
+ return 0;
}
/// Removes all cards from the item found in the specified equipment slot of the invoking character.
@@ -11407,225 +11339,227 @@ BUILDIN_FUNC(successremovecards)
/// <type>=1 : will keep the item, but destroy the cards.
/// <type>=2 : will keep the cards, but destroy the item.
/// <type>=? : will just display the failure effect.
-BUILDIN_FUNC(failedremovecards)
-{
- int i=-1,j,c,cardflag=0;
+BUILDIN_FUNC(failedremovecards) {
+ int i=-1,j,c,cardflag=0;
- TBL_PC *sd = script_rid2sd(st);
- int num = script_getnum(st,2);
- int typefail = script_getnum(st,3);
+ TBL_PC* sd = script_rid2sd(st);
+ int num = script_getnum(st,2);
+ int typefail = script_getnum(st,3);
- if (num > 0 && num <= ARRAYLENGTH(equip))
- i=pc_checkequip(sd,equip[num-1]);
+ if (num > 0 && num <= ARRAYLENGTH(equip))
+ i=pc_checkequip(sd,equip[num-1]);
- if (i < 0 || !sd->inventory_data[i])
- return 0;
+ if (i < 0 || !sd->inventory_data[i])
+ return 0;
- if (itemdb_isspecial(sd->status.inventory[i].card[0]))
- return 0;
+ if(itemdb_isspecial(sd->status.inventory[i].card[0]))
+ return 0;
- for (c = sd->inventory_data[i]->slot - 1; c >= 0; --c) {
- if (sd->status.inventory[i].card[c] && itemdb_type(sd->status.inventory[i].card[c]) == IT_CARD) {
- cardflag = 1;
+ for( c = sd->inventory_data[i]->slot - 1; c >= 0; --c ) {
+ if( sd->status.inventory[i].card[c] && itemdb_type(sd->status.inventory[i].card[c]) == IT_CARD ) {
+ cardflag = 1;
- if (typefail == 2) { // add cards to inventory, clear
- int flag;
- struct item item_tmp;
+ if(typefail == 2) {// add cards to inventory, clear
+ int flag;
+ struct item item_tmp;
- memset(&item_tmp,0,sizeof(item_tmp));
+ memset(&item_tmp,0,sizeof(item_tmp));
- item_tmp.nameid = sd->status.inventory[i].card[c];
- item_tmp.identify = 1;
+ item_tmp.nameid = sd->status.inventory[i].card[c];
+ item_tmp.identify = 1;
- if ((flag=pc_additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))) {
- clif_additem(sd,0,0,flag);
- map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
- }
- }
- }
- }
+ if((flag=pc_additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))){
+ clif_additem(sd,0,0,flag);
+ map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ }
+ }
+ }
+ }
- if (cardflag == 1) {
- if (typefail == 0 || typefail == 2) { // destroy the item
- pc_delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT);
- }
- if (typefail == 1) { // destroy the card
- int flag;
- struct item item_tmp;
+ if(cardflag == 1) {
+ if(typefail == 0 || typefail == 2){ // destroy the item
+ pc_delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT);
+ }
+ if(typefail == 1){ // destroy the card
+ int flag;
+ struct item item_tmp;
- memset(&item_tmp,0,sizeof(item_tmp));
+ memset(&item_tmp,0,sizeof(item_tmp));
- item_tmp.nameid = sd->status.inventory[i].nameid;
- item_tmp.identify = 1;
- item_tmp.refine = sd->status.inventory[i].refine;
- item_tmp.attribute = sd->status.inventory[i].attribute;
- item_tmp.expire_time = sd->status.inventory[i].expire_time;
+ item_tmp.nameid = sd->status.inventory[i].nameid;
+ item_tmp.identify = 1;
+ item_tmp.refine = sd->status.inventory[i].refine;
+ item_tmp.attribute = sd->status.inventory[i].attribute;
+ item_tmp.expire_time = sd->status.inventory[i].expire_time;
- for (j = sd->inventory_data[i]->slot; j < MAX_SLOTS; j++)
- item_tmp.card[j]=sd->status.inventory[i].card[j];
+ for (j = sd->inventory_data[i]->slot; j < MAX_SLOTS; j++)
+ item_tmp.card[j]=sd->status.inventory[i].card[j];
- pc_delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT);
+ pc_delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT);
- if ((flag=pc_additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))) {
- clif_additem(sd,0,0,flag);
- map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
- }
- }
- clif_misceffect(&sd->bl,2);
- }
+ if((flag=pc_additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))){
+ clif_additem(sd,0,0,flag);
+ map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ }
+ }
+ clif_misceffect(&sd->bl,2);
+ }
- return 0;
+ return 0;
}
/* ================================================================
* mapwarp "<from map>","<to map>",<x>,<y>,<type>,<ID for Type>;
- * type: 0=everyone, 1=guild, 2=party; [Reddozen]
+ * type: 0=everyone, 1=guild, 2=party; [Reddozen]
* improved by [Lance]
* ================================================================*/
-BUILDIN_FUNC(mapwarp) // Added by RoVeRT
-{
- int x,y,m,check_val=0,check_ID=0,i=0;
- struct guild *g = NULL;
- struct party_data *p = NULL;
- const char *str;
- const char *mapname;
- unsigned int index;
- mapname=script_getstr(st,2);
- str=script_getstr(st,3);
- x=script_getnum(st,4);
- y=script_getnum(st,5);
- if (script_hasdata(st,7)) {
- check_val=script_getnum(st,6);
- check_ID=script_getnum(st,7);
- }
-
- if ((m=map_mapname2mapid(mapname))< 0)
- return 0;
-
- if (!(index=mapindex_name2id(str)))
- return 0;
-
- switch (check_val) {
- case 1:
- g = guild_search(check_ID);
- if (g) {
- for (i=0; i < g->max_member; i++) {
- if (g->member[i].sd && g->member[i].sd->bl.m==m) {
- pc_setpos(g->member[i].sd,index,x,y,CLR_TELEPORT);
- }
- }
- }
- break;
- case 2:
- p = party_search(check_ID);
- if (p) {
- for (i=0; i<MAX_PARTY; i++) {
- if (p->data[i].sd && p->data[i].sd->bl.m == m) {
- pc_setpos(p->data[i].sd,index,x,y,CLR_TELEPORT);
- }
- }
- }
- break;
- default:
- map_foreachinmap(buildin_areawarp_sub,m,BL_PC,index,x,y,0,0);
- break;
- }
-
- return 0;
-}
-
-static int buildin_mobcount_sub(struct block_list *bl,va_list ap) // Added by RoVeRT
-{
- char *event=va_arg(ap,char *);
- struct mob_data *md = ((struct mob_data *)bl);
- if (md->status.hp > 0 && (!event || strcmp(event,md->npc_event) == 0))
- return 1;
- return 0;
-}
-
-BUILDIN_FUNC(mobcount) // Added by RoVeRT
-{
- const char *mapname,*event;
- int m;
- mapname=script_getstr(st,2);
- event=script_getstr(st,3);
-
- if (strcmp(event, "all") == 0)
- event = NULL;
- else
- check_event(st, event);
-
- if (strcmp(mapname, "this") == 0) {
- struct map_session_data *sd = script_rid2sd(st);
- if (sd)
- m = sd->bl.m;
- else {
- script_pushint(st,-1);
- return 0;
- }
- } else if ((m = map_mapname2mapid(mapname)) < 0) {
- script_pushint(st,-1);
- return 0;
- }
-
- if (map[m].flag.src4instance && map[m].instance_id == 0 && st->instance_id && (m = instance_mapid2imapid(m, st->instance_id)) < 0) {
- script_pushint(st,-1);
- return 0;
- }
-
- script_pushint(st,map_foreachinmap(buildin_mobcount_sub, m, BL_MOB, event));
-
- return 0;
+BUILDIN_FUNC(mapwarp) // Added by RoVeRT
+{
+ int x,y,m,check_val=0,check_ID=0,i=0;
+ struct guild *g = NULL;
+ struct party_data *p = NULL;
+ const char *str;
+ const char *mapname;
+ unsigned int index;
+ mapname=script_getstr(st,2);
+ str=script_getstr(st,3);
+ x=script_getnum(st,4);
+ y=script_getnum(st,5);
+ if(script_hasdata(st,7)){
+ check_val=script_getnum(st,6);
+ check_ID=script_getnum(st,7);
+ }
+
+ if((m=map_mapname2mapid(mapname))< 0)
+ return 0;
+
+ if(!(index=mapindex_name2id(str)))
+ return 0;
+
+ switch(check_val){
+ case 1:
+ g = guild_search(check_ID);
+ if (g){
+ for( i=0; i < g->max_member; i++)
+ {
+ if(g->member[i].sd && g->member[i].sd->bl.m==m){
+ pc_setpos(g->member[i].sd,index,x,y,CLR_TELEPORT);
+ }
+ }
+ }
+ break;
+ case 2:
+ p = party_search(check_ID);
+ if(p){
+ for(i=0;i<MAX_PARTY; i++){
+ if(p->data[i].sd && p->data[i].sd->bl.m == m){
+ pc_setpos(p->data[i].sd,index,x,y,CLR_TELEPORT);
+ }
+ }
+ }
+ break;
+ default:
+ map_foreachinmap(buildin_areawarp_sub,m,BL_PC,index,x,y,0,0);
+ break;
+ }
+
+ return 0;
+}
+
+static int buildin_mobcount_sub(struct block_list *bl,va_list ap) // Added by RoVeRT
+{
+ char *event=va_arg(ap,char *);
+ struct mob_data *md = ((struct mob_data *)bl);
+ if( md->status.hp > 0 && (!event || strcmp(event,md->npc_event) == 0) )
+ return 1;
+ return 0;
+}
+
+BUILDIN_FUNC(mobcount) // Added by RoVeRT
+{
+ const char *mapname,*event;
+ int m;
+ mapname=script_getstr(st,2);
+ event=script_getstr(st,3);
+
+ if( strcmp(event, "all") == 0 )
+ event = NULL;
+ else
+ check_event(st, event);
+
+ if( strcmp(mapname, "this") == 0 ) {
+ struct map_session_data *sd = script_rid2sd(st);
+ if( sd )
+ m = sd->bl.m;
+ else {
+ script_pushint(st,-1);
+ return 0;
+ }
+ }
+ else if( (m = map_mapname2mapid(mapname)) < 0 ) {
+ script_pushint(st,-1);
+ return 0;
+ }
+
+ if( map[m].flag.src4instance && map[m].instance_id == 0 && st->instance_id && (m = instance_mapid2imapid(m, st->instance_id)) < 0 )
+ {
+ script_pushint(st,-1);
+ return 0;
+ }
+
+ script_pushint(st,map_foreachinmap(buildin_mobcount_sub, m, BL_MOB, event));
+
+ return 0;
}
BUILDIN_FUNC(marriage)
{
- const char *partner=script_getstr(st,2);
- TBL_PC *sd=script_rid2sd(st);
- TBL_PC *p_sd=map_nick2sd(partner);
+ const char *partner=script_getstr(st,2);
+ TBL_PC *sd=script_rid2sd(st);
+ TBL_PC *p_sd=map_nick2sd(partner);
- if (sd==NULL || p_sd==NULL || pc_marriage(sd,p_sd) < 0) {
- script_pushint(st,0);
- return 0;
- }
- script_pushint(st,1);
- return 0;
+ if(sd==NULL || p_sd==NULL || pc_marriage(sd,p_sd) < 0){
+ script_pushint(st,0);
+ return 0;
+ }
+ script_pushint(st,1);
+ return 0;
}
BUILDIN_FUNC(wedding_effect)
{
- TBL_PC *sd=script_rid2sd(st);
- struct block_list *bl;
+ TBL_PC *sd=script_rid2sd(st);
+ struct block_list *bl;
- if (sd==NULL) {
- bl=map_id2bl(st->oid);
- } else
- bl=&sd->bl;
- clif_wedding_effect(bl);
- return 0;
+ if(sd==NULL) {
+ bl=map_id2bl(st->oid);
+ } else
+ bl=&sd->bl;
+ clif_wedding_effect(bl);
+ return 0;
}
BUILDIN_FUNC(divorce)
{
- TBL_PC *sd=script_rid2sd(st);
- if (sd==NULL || pc_divorce(sd) < 0) {
- script_pushint(st,0);
- return 0;
- }
- script_pushint(st,1);
- return 0;
+ TBL_PC *sd=script_rid2sd(st);
+ if(sd==NULL || pc_divorce(sd) < 0){
+ script_pushint(st,0);
+ return 0;
+ }
+ script_pushint(st,1);
+ return 0;
}
BUILDIN_FUNC(ispartneron)
{
- TBL_PC *sd=script_rid2sd(st);
+ TBL_PC *sd=script_rid2sd(st);
- if (sd==NULL || !pc_ismarried(sd) ||
- map_charid2sd(sd->status.partner_id) == NULL) {
- script_pushint(st,0);
- return 0;
- }
+ if(sd==NULL || !pc_ismarried(sd) ||
+ map_charid2sd(sd->status.partner_id) == NULL) {
+ script_pushint(st,0);
+ return 0;
+ }
- script_pushint(st,1);
- return 0;
+ script_pushint(st,1);
+ return 0;
}
BUILDIN_FUNC(getpartnerid)
@@ -11678,29 +11612,29 @@ BUILDIN_FUNC(getfatherid)
BUILDIN_FUNC(warppartner)
{
- int x,y;
- unsigned short mapindex;
- const char *str;
- TBL_PC *sd=script_rid2sd(st);
- TBL_PC *p_sd=NULL;
+ int x,y;
+ unsigned short mapindex;
+ const char *str;
+ TBL_PC *sd=script_rid2sd(st);
+ TBL_PC *p_sd=NULL;
- if (sd==NULL || !pc_ismarried(sd) ||
- (p_sd=map_charid2sd(sd->status.partner_id)) == NULL) {
- script_pushint(st,0);
- return 0;
- }
+ if(sd==NULL || !pc_ismarried(sd) ||
+ (p_sd=map_charid2sd(sd->status.partner_id)) == NULL) {
+ script_pushint(st,0);
+ return 0;
+ }
- str=script_getstr(st,2);
- x=script_getnum(st,3);
- y=script_getnum(st,4);
+ str=script_getstr(st,2);
+ x=script_getnum(st,3);
+ y=script_getnum(st,4);
- mapindex = mapindex_name2id(str);
- if (mapindex) {
- pc_setpos(p_sd,mapindex,x,y,CLR_OUTSIGHT);
- script_pushint(st,1);
- } else
- script_pushint(st,0);
- return 0;
+ mapindex = mapindex_name2id(str);
+ if (mapindex) {
+ pc_setpos(p_sd,mapindex,x,y,CLR_OUTSIGHT);
+ script_pushint(st,1);
+ } else
+ script_pushint(st,0);
+ return 0;
}
/*================================================
@@ -11709,41 +11643,28 @@ BUILDIN_FUNC(warppartner)
BUILDIN_FUNC(strmobinfo)
{
- int num=script_getnum(st,2);
- int class_=script_getnum(st,3);
+ int num=script_getnum(st,2);
+ int class_=script_getnum(st,3);
- if (!mobdb_checkid(class_)) {
- script_pushint(st,0);
- return 0;
- }
+ if(!mobdb_checkid(class_))
+ {
+ script_pushint(st,0);
+ return 0;
+ }
- switch (num) {
- case 1:
- script_pushstrcopy(st,mob_db(class_)->name);
- break;
- case 2:
- script_pushstrcopy(st,mob_db(class_)->jname);
- break;
- case 3:
- script_pushint(st,mob_db(class_)->lv);
- break;
- case 4:
- script_pushint(st,mob_db(class_)->status.max_hp);
- break;
- case 5:
- script_pushint(st,mob_db(class_)->status.max_sp);
- break;
- case 6:
- script_pushint(st,mob_db(class_)->base_exp);
- break;
- case 7:
- script_pushint(st,mob_db(class_)->job_exp);
- break;
- default:
- script_pushint(st,0);
- break;
- }
- return 0;
+ switch (num) {
+ case 1: script_pushstrcopy(st,mob_db(class_)->name); break;
+ case 2: script_pushstrcopy(st,mob_db(class_)->jname); break;
+ case 3: script_pushint(st,mob_db(class_)->lv); break;
+ case 4: script_pushint(st,mob_db(class_)->status.max_hp); break;
+ case 5: script_pushint(st,mob_db(class_)->status.max_sp); break;
+ case 6: script_pushint(st,mob_db(class_)->base_exp); break;
+ case 7: script_pushint(st,mob_db(class_)->job_exp); break;
+ default:
+ script_pushint(st,0);
+ break;
+ }
+ return 0;
}
/*==========================================
@@ -11752,73 +11673,73 @@ BUILDIN_FUNC(strmobinfo)
*------------------------------------------*/
BUILDIN_FUNC(guardian)
{
- int class_=0,x=0,y=0,guardian=0;
- const char *str,*map,*evt="";
- struct script_data *data;
- bool has_index = false;
-
- map =script_getstr(st,2);
- x =script_getnum(st,3);
- y =script_getnum(st,4);
- str =script_getstr(st,5);
- class_=script_getnum(st,6);
-
- if (script_hasdata(st,8)) {
- // "<event label>",<guardian index>
- evt=script_getstr(st,7);
- guardian=script_getnum(st,8);
- has_index = true;
- } else if (script_hasdata(st,7)) {
- data=script_getdata(st,7);
- get_val(st,data);
- if (data_isstring(data)) {
- // "<event label>"
- evt=script_getstr(st,7);
- } else if (data_isint(data)) {
- // <guardian index>
- guardian=script_getnum(st,7);
- has_index = true;
- } else {
- ShowError("script:guardian: invalid data type for argument #6 (from 1)\n");
- script_reportdata(data);
- return 1;
- }
- }
-
- check_event(st, evt);
- script_pushint(st, mob_spawn_guardian(map,x,y,str,class_,evt,guardian,has_index));
-
- return 0;
+ int class_=0,x=0,y=0,guardian=0;
+ const char *str,*map,*evt="";
+ struct script_data *data;
+ bool has_index = false;
+
+ map =script_getstr(st,2);
+ x =script_getnum(st,3);
+ y =script_getnum(st,4);
+ str =script_getstr(st,5);
+ class_=script_getnum(st,6);
+
+ if( script_hasdata(st,8) )
+ {// "<event label>",<guardian index>
+ evt=script_getstr(st,7);
+ guardian=script_getnum(st,8);
+ has_index = true;
+ } else if( script_hasdata(st,7) ){
+ data=script_getdata(st,7);
+ get_val(st,data);
+ if( data_isstring(data) )
+ {// "<event label>"
+ evt=script_getstr(st,7);
+ } else if( data_isint(data) )
+ {// <guardian index>
+ guardian=script_getnum(st,7);
+ has_index = true;
+ } else {
+ ShowError("script:guardian: invalid data type for argument #6 (from 1)\n");
+ script_reportdata(data);
+ return 1;
+ }
+ }
+
+ check_event(st, evt);
+ script_pushint(st, mob_spawn_guardian(map,x,y,str,class_,evt,guardian,has_index));
+
+ return 0;
}
/*==========================================
* Invisible Walls [Zephyrus]
*------------------------------------------*/
BUILDIN_FUNC(setwall)
{
- const char *map, *name;
- int x, y, m, size, dir;
- bool shootable;
+ const char *map, *name;
+ int x, y, m, size, dir;
+ bool shootable;
- map = script_getstr(st,2);
- x = script_getnum(st,3);
- y = script_getnum(st,4);
- size = script_getnum(st,5);
- dir = script_getnum(st,6);
- shootable = script_getnum(st,7);
- name = script_getstr(st,8);
+ map = script_getstr(st,2);
+ x = script_getnum(st,3);
+ y = script_getnum(st,4);
+ size = script_getnum(st,5);
+ dir = script_getnum(st,6);
+ shootable = script_getnum(st,7);
+ name = script_getstr(st,8);
- if ((m = map_mapname2mapid(map)) < 0)
- return 0; // Invalid Map
+ if( (m = map_mapname2mapid(map)) < 0 )
+ return 0; // Invalid Map
- map_iwall_set(m, x, y, size, dir, shootable, name);
- return 0;
+ map_iwall_set(m, x, y, size, dir, shootable, name);
+ return 0;
}
BUILDIN_FUNC(delwall)
{
- const char *name = script_getstr(st,2);
- map_iwall_remove(name);
+ const char *name = script_getstr(st,2);
+ map_iwall_remove(name);
- return 0;
+ return 0;
}
/// Retrieves various information about the specified guardian.
@@ -11830,32 +11751,36 @@ BUILDIN_FUNC(delwall)
///
BUILDIN_FUNC(guardianinfo)
{
- const char *mapname = mapindex_getmapname(script_getstr(st,2),NULL);
- int id = script_getnum(st,3);
- int type = script_getnum(st,4);
-
- struct guild_castle *gc = guild_mapname2gc(mapname);
- struct mob_data *gd;
-
- if (gc == NULL || id < 0 || id >= MAX_GUARDIANS) {
- script_pushint(st,-1);
- return 0;
- }
-
- if (type == 0)
- script_pushint(st, gc->guardian[id].visible);
- else if (!gc->guardian[id].visible)
- script_pushint(st,-1);
- else if ((gd = map_id2md(gc->guardian[id].id)) == NULL)
- script_pushint(st,-1);
- else {
- if (type == 1) script_pushint(st,gd->status.max_hp);
- else if (type == 2) script_pushint(st,gd->status.hp);
- else
- script_pushint(st,-1);
- }
-
- return 0;
+ const char* mapname = mapindex_getmapname(script_getstr(st,2),NULL);
+ int id = script_getnum(st,3);
+ int type = script_getnum(st,4);
+
+ struct guild_castle* gc = guild_mapname2gc(mapname);
+ struct mob_data* gd;
+
+ if( gc == NULL || id < 0 || id >= MAX_GUARDIANS )
+ {
+ script_pushint(st,-1);
+ return 0;
+ }
+
+ if( type == 0 )
+ script_pushint(st, gc->guardian[id].visible);
+ else
+ if( !gc->guardian[id].visible )
+ script_pushint(st,-1);
+ else
+ if( (gd = map_id2md(gc->guardian[id].id)) == NULL )
+ script_pushint(st,-1);
+ else
+ {
+ if ( type == 1 ) script_pushint(st,gd->status.max_hp);
+ else if( type == 2 ) script_pushint(st,gd->status.hp);
+ else
+ script_pushint(st,-1);
+ }
+
+ return 0;
}
/*==========================================
@@ -11863,50 +11788,51 @@ BUILDIN_FUNC(guardianinfo)
*------------------------------------------*/
BUILDIN_FUNC(getitemname)
{
- int item_id=0;
- struct item_data *i_data;
- char *item_name;
- struct script_data *data;
-
- data=script_getdata(st,2);
- get_val(st,data);
-
- if (data_isstring(data)) {
- const char *name=conv_str(st,data);
- struct item_data *item_data = itemdb_searchname(name);
- if (item_data)
- item_id=item_data->nameid;
- } else
- item_id=conv_num(st,data);
-
- i_data = itemdb_exists(item_id);
- if (i_data == NULL) {
- script_pushconststr(st,"null");
- return 0;
- }
- item_name=(char *)aMalloc(ITEM_NAME_LENGTH*sizeof(char));
-
- memcpy(item_name, i_data->jname, ITEM_NAME_LENGTH);
- script_pushstr(st,item_name);
- return 0;
+ int item_id=0;
+ struct item_data *i_data;
+ char *item_name;
+ struct script_data *data;
+
+ data=script_getdata(st,2);
+ get_val(st,data);
+
+ if( data_isstring(data) ){
+ const char *name=conv_str(st,data);
+ struct item_data *item_data = itemdb_searchname(name);
+ if( item_data )
+ item_id=item_data->nameid;
+ }else
+ item_id=conv_num(st,data);
+
+ i_data = itemdb_exists(item_id);
+ if (i_data == NULL)
+ {
+ script_pushconststr(st,"null");
+ return 0;
+ }
+ item_name=(char *)aMalloc(ITEM_NAME_LENGTH*sizeof(char));
+
+ memcpy(item_name, i_data->jname, ITEM_NAME_LENGTH);
+ script_pushstr(st,item_name);
+ return 0;
}
/*==========================================
* Returns number of slots an item has. [Skotlex]
*------------------------------------------*/
BUILDIN_FUNC(getitemslots)
{
- int item_id;
- struct item_data *i_data;
+ int item_id;
+ struct item_data *i_data;
- item_id=script_getnum(st,2);
+ item_id=script_getnum(st,2);
- i_data = itemdb_exists(item_id);
+ i_data = itemdb_exists(item_id);
- if (i_data)
- script_pushint(st,i_data->slot);
- else
- script_pushint(st,-1);
- return 0;
+ if (i_data)
+ script_pushint(st,i_data->slot);
+ else
+ script_pushint(st,-1);
+ return 0;
}
// TODO: add matk here if needed/once we get rid of RENEWAL
@@ -11914,114 +11840,114 @@ BUILDIN_FUNC(getitemslots)
/*==========================================
* Returns some values of an item [Lupus]
* Price, Weight, etc...
- getiteminfo(itemID,n), where n
- 0 value_buy;
- 1 value_sell;
- 2 type;
- 3 maxchance = Max drop chance of this item e.g. 1 = 0.01% , etc..
- if = 0, then monsters don't drop it at all (rare or a quest item)
- if = -1, then this item is sold in NPC shops only
- 4 sex;
- 5 equip;
- 6 weight;
- 7 atk;
- 8 def;
- 9 range;
- 10 slot;
- 11 look;
- 12 elv;
- 13 wlv;
- 14 view id
+ getiteminfo(itemID,n), where n
+ 0 value_buy;
+ 1 value_sell;
+ 2 type;
+ 3 maxchance = Max drop chance of this item e.g. 1 = 0.01% , etc..
+ if = 0, then monsters don't drop it at all (rare or a quest item)
+ if = -1, then this item is sold in NPC shops only
+ 4 sex;
+ 5 equip;
+ 6 weight;
+ 7 atk;
+ 8 def;
+ 9 range;
+ 10 slot;
+ 11 look;
+ 12 elv;
+ 13 wlv;
+ 14 view id
*------------------------------------------*/
BUILDIN_FUNC(getiteminfo)
{
- int item_id,n;
- int *item_arr;
- struct item_data *i_data;
+ int item_id,n;
+ int *item_arr;
+ struct item_data *i_data;
- item_id = script_getnum(st,2);
- n = script_getnum(st,3);
- i_data = itemdb_exists(item_id);
+ item_id = script_getnum(st,2);
+ n = script_getnum(st,3);
+ i_data = itemdb_exists(item_id);
- if (i_data && n>=0 && n<=14) {
- item_arr = (int *)&i_data->value_buy;
- script_pushint(st,item_arr[n]);
- } else
- script_pushint(st,-1);
- return 0;
+ if (i_data && n>=0 && n<=14) {
+ item_arr = (int*)&i_data->value_buy;
+ script_pushint(st,item_arr[n]);
+ } else
+ script_pushint(st,-1);
+ return 0;
}
/*==========================================
* Set some values of an item [Lupus]
* Price, Weight, etc...
- setiteminfo(itemID,n,Value), where n
- 0 value_buy;
- 1 value_sell;
- 2 type;
- 3 maxchance = Max drop chance of this item e.g. 1 = 0.01% , etc..
- if = 0, then monsters don't drop it at all (rare or a quest item)
- if = -1, then this item is sold in NPC shops only
- 4 sex;
- 5 equip;
- 6 weight;
- 7 atk;
- 8 def;
- 9 range;
- 10 slot;
- 11 look;
- 12 elv;
- 13 wlv;
- 14 view id
+ setiteminfo(itemID,n,Value), where n
+ 0 value_buy;
+ 1 value_sell;
+ 2 type;
+ 3 maxchance = Max drop chance of this item e.g. 1 = 0.01% , etc..
+ if = 0, then monsters don't drop it at all (rare or a quest item)
+ if = -1, then this item is sold in NPC shops only
+ 4 sex;
+ 5 equip;
+ 6 weight;
+ 7 atk;
+ 8 def;
+ 9 range;
+ 10 slot;
+ 11 look;
+ 12 elv;
+ 13 wlv;
+ 14 view id
* Returns Value or -1 if the wrong field's been set
*------------------------------------------*/
BUILDIN_FUNC(setiteminfo)
{
- int item_id,n,value;
- int *item_arr;
- struct item_data *i_data;
-
- item_id = script_getnum(st,2);
- n = script_getnum(st,3);
- value = script_getnum(st,4);
- i_data = itemdb_exists(item_id);
-
- if (i_data && n>=0 && n<=14) {
- item_arr = (int *)&i_data->value_buy;
- item_arr[n] = value;
- script_pushint(st,value);
- } else
- script_pushint(st,-1);
- return 0;
+ int item_id,n,value;
+ int *item_arr;
+ struct item_data *i_data;
+
+ item_id = script_getnum(st,2);
+ n = script_getnum(st,3);
+ value = script_getnum(st,4);
+ i_data = itemdb_exists(item_id);
+
+ if (i_data && n>=0 && n<=14) {
+ item_arr = (int*)&i_data->value_buy;
+ item_arr[n] = value;
+ script_pushint(st,value);
+ } else
+ script_pushint(st,-1);
+ return 0;
}
/*==========================================
* Returns value from equipped item slot n [Lupus]
- getequipcardid(num,slot)
- where
- num = eqip position slot
- slot = 0,1,2,3 (Card Slot N)
-
- This func returns CARD ID, 255,254,-255 (for card 0, if the item is produced)
- it's useful when you want to check item cards or if it's signed
- Useful for such quests as "Sign this refined item with players name" etc
- Hat[0] +4 -> Player's Hat[0] +4
+ getequipcardid(num,slot)
+ where
+ num = eqip position slot
+ slot = 0,1,2,3 (Card Slot N)
+
+ This func returns CARD ID, 255,254,-255 (for card 0, if the item is produced)
+ it's useful when you want to check item cards or if it's signed
+ Useful for such quests as "Sign this refined item with players name" etc
+ Hat[0] +4 -> Player's Hat[0] +4
*------------------------------------------*/
BUILDIN_FUNC(getequipcardid)
{
- int i=-1,num,slot;
- TBL_PC *sd;
-
- num=script_getnum(st,2);
- slot=script_getnum(st,3);
- sd=script_rid2sd(st);
- if (num > 0 && num <= ARRAYLENGTH(equip))
- i=pc_checkequip(sd,equip[num-1]);
- if (i >= 0 && slot>=0 && slot<4)
- script_pushint(st,sd->status.inventory[i].card[slot]);
- else
- script_pushint(st,0);
+ int i=-1,num,slot;
+ TBL_PC *sd;
- return 0;
+ num=script_getnum(st,2);
+ slot=script_getnum(st,3);
+ sd=script_rid2sd(st);
+ if (num > 0 && num <= ARRAYLENGTH(equip))
+ i=pc_checkequip(sd,equip[num-1]);
+ if(i >= 0 && slot>=0 && slot<4)
+ script_pushint(st,sd->status.inventory[i].card[slot]);
+ else
+ script_pushint(st,0);
+
+ return 0;
}
/*==========================================
@@ -12029,36 +11955,36 @@ BUILDIN_FUNC(getequipcardid)
*------------------------------------------*/
BUILDIN_FUNC(petskillbonus)
{
- struct pet_data *pd;
+ struct pet_data *pd;
- TBL_PC *sd=script_rid2sd(st);
+ TBL_PC *sd=script_rid2sd(st);
- if (sd==NULL || sd->pd==NULL)
- return 0;
+ if(sd==NULL || sd->pd==NULL)
+ return 0;
- pd=sd->pd;
- if (pd->bonus) {
- //Clear previous bonus
- if (pd->bonus->timer != INVALID_TIMER)
- delete_timer(pd->bonus->timer, pet_skill_bonus_timer);
- } else //init
- pd->bonus = (struct pet_bonus *) aMalloc(sizeof(struct pet_bonus));
+ pd=sd->pd;
+ if (pd->bonus)
+ { //Clear previous bonus
+ if (pd->bonus->timer != INVALID_TIMER)
+ delete_timer(pd->bonus->timer, pet_skill_bonus_timer);
+ } else //init
+ pd->bonus = (struct pet_bonus *) aMalloc(sizeof(struct pet_bonus));
- pd->bonus->type=script_getnum(st,2);
- pd->bonus->val=script_getnum(st,3);
- pd->bonus->duration=script_getnum(st,4);
- pd->bonus->delay=script_getnum(st,5);
+ pd->bonus->type=script_getnum(st,2);
+ pd->bonus->val=script_getnum(st,3);
+ pd->bonus->duration=script_getnum(st,4);
+ pd->bonus->delay=script_getnum(st,5);
- if (pd->state.skillbonus == 1)
- pd->state.skillbonus=0; // waiting state
+ if (pd->state.skillbonus == 1)
+ pd->state.skillbonus=0; // waiting state
- // wait for timer to start
- if (battle_config.pet_equip_required && pd->pet.equip == 0)
- pd->bonus->timer = INVALID_TIMER;
- else
- pd->bonus->timer = add_timer(gettick()+pd->bonus->delay*1000, pet_skill_bonus_timer, sd->bl.id, 0);
+ // wait for timer to start
+ if (battle_config.pet_equip_required && pd->pet.equip == 0)
+ pd->bonus->timer = INVALID_TIMER;
+ else
+ pd->bonus->timer = add_timer(gettick()+pd->bonus->delay*1000, pet_skill_bonus_timer, sd->bl.id, 0);
- return 0;
+ return 0;
}
/*==========================================
@@ -12066,35 +11992,36 @@ BUILDIN_FUNC(petskillbonus)
*------------------------------------------*/
BUILDIN_FUNC(petloot)
{
- int max;
- struct pet_data *pd;
- TBL_PC *sd=script_rid2sd(st);
+ int max;
+ struct pet_data *pd;
+ TBL_PC *sd=script_rid2sd(st);
- if (sd==NULL || sd->pd==NULL)
- return 0;
+ if(sd==NULL || sd->pd==NULL)
+ return 0;
- max=script_getnum(st,2);
+ max=script_getnum(st,2);
- if (max < 1)
- max = 1; //Let'em loot at least 1 item.
- else if (max > MAX_PETLOOT_SIZE)
- max = MAX_PETLOOT_SIZE;
+ if(max < 1)
+ max = 1; //Let'em loot at least 1 item.
+ else if (max > MAX_PETLOOT_SIZE)
+ max = MAX_PETLOOT_SIZE;
- pd = sd->pd;
- if (pd->loot != NULL) {
- //Release whatever was there already and reallocate memory
- pet_lootitem_drop(pd, pd->msd);
- aFree(pd->loot->item);
- } else
- pd->loot = (struct pet_loot *)aMalloc(sizeof(struct pet_loot));
+ pd = sd->pd;
+ if (pd->loot != NULL)
+ { //Release whatever was there already and reallocate memory
+ pet_lootitem_drop(pd, pd->msd);
+ aFree(pd->loot->item);
+ }
+ else
+ pd->loot = (struct pet_loot *)aMalloc(sizeof(struct pet_loot));
- pd->loot->item = (struct item *)aCalloc(max,sizeof(struct item));
+ pd->loot->item = (struct item *)aCalloc(max,sizeof(struct item));
- pd->loot->max=max;
- pd->loot->count = 0;
- pd->loot->weight = 0;
+ pd->loot->max=max;
+ pd->loot->count = 0;
+ pd->loot->weight = 0;
- return 0;
+ return 0;
}
/*==========================================
* Set arrays with info of all sd inventory :
@@ -12105,59 +12032,60 @@ BUILDIN_FUNC(petloot)
*------------------------------------------*/
BUILDIN_FUNC(getinventorylist)
{
- TBL_PC *sd=script_rid2sd(st);
- char card_var[NAME_LENGTH];
-
- int i,j=0,k;
- 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,reference_uid(add_str("@inventorylist_id"), j),sd->status.inventory[i].nameid);
- pc_setreg(sd,reference_uid(add_str("@inventorylist_amount"), j),sd->status.inventory[i].amount);
- pc_setreg(sd,reference_uid(add_str("@inventorylist_equip"), j),sd->status.inventory[i].equip);
- pc_setreg(sd,reference_uid(add_str("@inventorylist_refine"), j),sd->status.inventory[i].refine);
- pc_setreg(sd,reference_uid(add_str("@inventorylist_identify"), j),sd->status.inventory[i].identify);
- pc_setreg(sd,reference_uid(add_str("@inventorylist_attribute"), j),sd->status.inventory[i].attribute);
- for (k = 0; k < MAX_SLOTS; k++) {
- sprintf(card_var, "@inventorylist_card%d",k+1);
- pc_setreg(sd,reference_uid(add_str(card_var), j),sd->status.inventory[i].card[k]);
- }
- pc_setreg(sd,reference_uid(add_str("@inventorylist_expire"), j),sd->status.inventory[i].expire_time);
- j++;
- }
- }
- pc_setreg(sd,add_str("@inventorylist_count"),j);
- return 0;
+ TBL_PC *sd=script_rid2sd(st);
+ char card_var[NAME_LENGTH];
+
+ int i,j=0,k;
+ 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,reference_uid(add_str("@inventorylist_id"), j),sd->status.inventory[i].nameid);
+ pc_setreg(sd,reference_uid(add_str("@inventorylist_amount"), j),sd->status.inventory[i].amount);
+ pc_setreg(sd,reference_uid(add_str("@inventorylist_equip"), j),sd->status.inventory[i].equip);
+ pc_setreg(sd,reference_uid(add_str("@inventorylist_refine"), j),sd->status.inventory[i].refine);
+ pc_setreg(sd,reference_uid(add_str("@inventorylist_identify"), j),sd->status.inventory[i].identify);
+ pc_setreg(sd,reference_uid(add_str("@inventorylist_attribute"), j),sd->status.inventory[i].attribute);
+ for (k = 0; k < MAX_SLOTS; k++)
+ {
+ sprintf(card_var, "@inventorylist_card%d",k+1);
+ pc_setreg(sd,reference_uid(add_str(card_var), j),sd->status.inventory[i].card[k]);
+ }
+ pc_setreg(sd,reference_uid(add_str("@inventorylist_expire"), j),sd->status.inventory[i].expire_time);
+ j++;
+ }
+ }
+ pc_setreg(sd,add_str("@inventorylist_count"),j);
+ return 0;
}
BUILDIN_FUNC(getskilllist)
{
- TBL_PC *sd=script_rid2sd(st);
- int i,j=0;
- 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,reference_uid(add_str("@skilllist_id"), j),sd->status.skill[i].id);
- pc_setreg(sd,reference_uid(add_str("@skilllist_lv"), j),sd->status.skill[i].lv);
- pc_setreg(sd,reference_uid(add_str("@skilllist_flag"), j),sd->status.skill[i].flag);
- j++;
- }
- }
- pc_setreg(sd,add_str("@skilllist_count"),j);
- return 0;
+ TBL_PC *sd=script_rid2sd(st);
+ int i,j=0;
+ 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,reference_uid(add_str("@skilllist_id"), j),sd->status.skill[i].id);
+ pc_setreg(sd,reference_uid(add_str("@skilllist_lv"), j),sd->status.skill[i].lv);
+ pc_setreg(sd,reference_uid(add_str("@skilllist_flag"), j),sd->status.skill[i].flag);
+ j++;
+ }
+ }
+ pc_setreg(sd,add_str("@skilllist_count"),j);
+ return 0;
}
BUILDIN_FUNC(clearitem)
{
- TBL_PC *sd=script_rid2sd(st);
- int i;
- if (sd==NULL) return 0;
- for (i=0; i<MAX_INVENTORY; i++) {
- if (sd->status.inventory[i].amount) {
- pc_delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_SCRIPT);
- }
- }
- return 0;
+ TBL_PC *sd=script_rid2sd(st);
+ int i;
+ if(sd==NULL) return 0;
+ for (i=0; i<MAX_INVENTORY; i++) {
+ if (sd->status.inventory[i].amount) {
+ pc_delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_SCRIPT);
+ }
+ }
+ return 0;
}
/*==========================================
@@ -12165,19 +12093,19 @@ BUILDIN_FUNC(clearitem)
*------------------------------------------*/
BUILDIN_FUNC(disguise)
{
- int id;
- TBL_PC *sd = script_rid2sd(st);
- if (sd == NULL) return 0;
+ int id;
+ TBL_PC* sd = script_rid2sd(st);
+ if (sd == NULL) return 0;
- id = script_getnum(st,2);
+ id = script_getnum(st,2);
- if (mobdb_checkid(id) || npcdb_checkid(id)) {
- pc_disguise(sd, id);
- script_pushint(st,id);
- } else
- script_pushint(st,0);
+ if (mobdb_checkid(id) || npcdb_checkid(id)) {
+ pc_disguise(sd, id);
+ script_pushint(st,id);
+ } else
+ script_pushint(st,0);
- return 0;
+ return 0;
}
/*==========================================
@@ -12185,16 +12113,16 @@ BUILDIN_FUNC(disguise)
*------------------------------------------*/
BUILDIN_FUNC(undisguise)
{
- TBL_PC *sd = script_rid2sd(st);
- if (sd == NULL) return 0;
+ TBL_PC* sd = script_rid2sd(st);
+ if (sd == NULL) return 0;
- if (sd->disguise) {
- pc_disguise(sd, 0);
- script_pushint(st,0);
- } else {
- script_pushint(st,1);
- }
- return 0;
+ if (sd->disguise) {
+ pc_disguise(sd, 0);
+ script_pushint(st,0);
+ } else {
+ script_pushint(st,1);
+ }
+ return 0;
}
/*==========================================
@@ -12203,15 +12131,15 @@ BUILDIN_FUNC(undisguise)
*------------------------------------------*/
BUILDIN_FUNC(classchange)
{
- int _class,type;
- struct block_list *bl=map_id2bl(st->oid);
+ int _class,type;
+ struct block_list *bl=map_id2bl(st->oid);
- if (bl==NULL) return 0;
+ if(bl==NULL) return 0;
- _class=script_getnum(st,2);
- type=script_getnum(st,3);
- clif_class_change(bl,_class,type);
- return 0;
+ _class=script_getnum(st,2);
+ type=script_getnum(st,3);
+ clif_class_change(bl,_class,type);
+ return 0;
}
/*==========================================
@@ -12219,52 +12147,53 @@ BUILDIN_FUNC(classchange)
*------------------------------------------*/
BUILDIN_FUNC(misceffect)
{
- int type;
-
- type=script_getnum(st,2);
- if (st->oid && st->oid != fake_nd->bl.id) {
- struct block_list *bl = map_id2bl(st->oid);
- if (bl)
- clif_specialeffect(bl,type,AREA);
- } else {
- TBL_PC *sd=script_rid2sd(st);
- if (sd)
- clif_specialeffect(&sd->bl,type,AREA);
- }
- return 0;
+ int type;
+
+ type=script_getnum(st,2);
+ if(st->oid && st->oid != fake_nd->bl.id) {
+ struct block_list *bl = map_id2bl(st->oid);
+ if (bl)
+ clif_specialeffect(bl,type,AREA);
+ } else{
+ TBL_PC *sd=script_rid2sd(st);
+ if(sd)
+ clif_specialeffect(&sd->bl,type,AREA);
+ }
+ return 0;
}
/*==========================================
* Play a BGM on a single client [Rikter/Yommy]
*------------------------------------------*/
BUILDIN_FUNC(playBGM)
{
- const char *name;
- struct map_session_data *sd;
+ const char* name;
+ struct map_session_data* sd;
- if ((sd = script_rid2sd(st)) != NULL) {
- name = script_getstr(st,2);
+ if( ( sd = script_rid2sd(st) ) != NULL )
+ {
+ name = script_getstr(st,2);
- clif_playBGM(sd, name);
- }
+ clif_playBGM(sd, name);
+ }
- return 0;
+ return 0;
}
-static int playBGM_sub(struct block_list *bl,va_list ap)
+static int playBGM_sub(struct block_list* bl,va_list ap)
{
- const char *name = va_arg(ap,const char *);
+ const char* name = va_arg(ap,const char*);
- clif_playBGM(BL_CAST(BL_PC, bl), name);
+ clif_playBGM(BL_CAST(BL_PC, bl), name);
- return 0;
+ return 0;
}
-static int playBGM_foreachpc_sub(struct map_session_data *sd, va_list args)
+static int playBGM_foreachpc_sub(struct map_session_data* sd, va_list args)
{
- const char *name = va_arg(args, const char *);
+ const char* name = va_arg(args, const char*);
- clif_playBGM(sd, name);
- return 0;
+ clif_playBGM(sd, name);
+ return 0;
}
/*==========================================
@@ -12272,30 +12201,32 @@ static int playBGM_foreachpc_sub(struct map_session_data *sd, va_list args)
*------------------------------------------*/
BUILDIN_FUNC(playBGMall)
{
- const char *name;
+ const char* name;
- name = script_getstr(st,2);
+ name = script_getstr(st,2);
- if (script_hasdata(st,7)) {
- // specified part of map
- const char *map = script_getstr(st,3);
- int x0 = script_getnum(st,4);
- int y0 = script_getnum(st,5);
- int x1 = script_getnum(st,6);
- int y1 = script_getnum(st,7);
+ if( script_hasdata(st,7) )
+ {// specified part of map
+ const char* map = script_getstr(st,3);
+ int x0 = script_getnum(st,4);
+ int y0 = script_getnum(st,5);
+ int x1 = script_getnum(st,6);
+ int y1 = script_getnum(st,7);
- map_foreachinarea(playBGM_sub, map_mapname2mapid(map), x0, y0, x1, y1, BL_PC, name);
- } else if (script_hasdata(st,3)) {
- // entire map
- const char *map = script_getstr(st,3);
+ map_foreachinarea(playBGM_sub, map_mapname2mapid(map), x0, y0, x1, y1, BL_PC, name);
+ }
+ else if( script_hasdata(st,3) )
+ {// entire map
+ const char* map = script_getstr(st,3);
- map_foreachinmap(playBGM_sub, map_mapname2mapid(map), BL_PC, name);
- } else {
- // entire server
- map_foreachpc(&playBGM_foreachpc_sub, name);
- }
+ map_foreachinmap(playBGM_sub, map_mapname2mapid(map), BL_PC, name);
+ }
+ else
+ {// entire server
+ map_foreachpc(&playBGM_foreachpc_sub, name);
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -12303,24 +12234,25 @@ BUILDIN_FUNC(playBGMall)
*------------------------------------------*/
BUILDIN_FUNC(soundeffect)
{
- TBL_PC *sd = script_rid2sd(st);
- const char *name = script_getstr(st,2);
- int type = script_getnum(st,3);
+ TBL_PC* sd = script_rid2sd(st);
+ const char* name = script_getstr(st,2);
+ int type = script_getnum(st,3);
- if (sd) {
- clif_soundeffect(sd,&sd->bl,name,type);
- }
- return 0;
+ if(sd)
+ {
+ clif_soundeffect(sd,&sd->bl,name,type);
+ }
+ return 0;
}
-int soundeffect_sub(struct block_list *bl,va_list ap)
+int soundeffect_sub(struct block_list* bl,va_list ap)
{
- char *name = va_arg(ap,char *);
- int type = va_arg(ap,int);
+ char* name = va_arg(ap,char*);
+ int type = va_arg(ap,int);
- clif_soundeffect((TBL_PC *)bl, bl, name, type);
+ clif_soundeffect((TBL_PC *)bl, bl, name, type);
- return 0;
+ return 0;
}
/*==========================================
@@ -12329,65 +12261,71 @@ int soundeffect_sub(struct block_list *bl,va_list ap)
*------------------------------------------*/
BUILDIN_FUNC(soundeffectall)
{
- struct block_list *bl;
- const char *name;
- int type;
-
- bl = (st->rid) ? &(script_rid2sd(st)->bl) : map_id2bl(st->oid);
- if (!bl)
- return 0;
-
- name = script_getstr(st,2);
- type = script_getnum(st,3);
-
- //FIXME: enumerating map squares (map_foreach) is slower than enumerating the list of online players (map_foreachpc?) [ultramage]
-
- if (!script_hasdata(st,4)) {
- // area around
- clif_soundeffectall(bl, name, type, AREA);
- } else if (!script_hasdata(st,5)) {
- // entire map
- const char *map = script_getstr(st,4);
- map_foreachinmap(soundeffect_sub, map_mapname2mapid(map), BL_PC, name, type);
- } else if (script_hasdata(st,8)) {
- // specified part of map
- const char *map = script_getstr(st,4);
- int x0 = script_getnum(st,5);
- int y0 = script_getnum(st,6);
- int x1 = script_getnum(st,7);
- int y1 = script_getnum(st,8);
- map_foreachinarea(soundeffect_sub, map_mapname2mapid(map), x0, y0, x1, y1, BL_PC, name, type);
- } else {
- ShowError("buildin_soundeffectall: insufficient arguments for specific area broadcast.\n");
- }
-
- return 0;
+ struct block_list* bl;
+ const char* name;
+ int type;
+
+ bl = (st->rid) ? &(script_rid2sd(st)->bl) : map_id2bl(st->oid);
+ if (!bl)
+ return 0;
+
+ name = script_getstr(st,2);
+ type = script_getnum(st,3);
+
+ //FIXME: enumerating map squares (map_foreach) is slower than enumerating the list of online players (map_foreachpc?) [ultramage]
+
+ if(!script_hasdata(st,4))
+ { // area around
+ clif_soundeffectall(bl, name, type, AREA);
+ }
+ else
+ if(!script_hasdata(st,5))
+ { // entire map
+ const char* map = script_getstr(st,4);
+ map_foreachinmap(soundeffect_sub, map_mapname2mapid(map), BL_PC, name, type);
+ }
+ else
+ if(script_hasdata(st,8))
+ { // specified part of map
+ const char* map = script_getstr(st,4);
+ int x0 = script_getnum(st,5);
+ int y0 = script_getnum(st,6);
+ int x1 = script_getnum(st,7);
+ int y1 = script_getnum(st,8);
+ map_foreachinarea(soundeffect_sub, map_mapname2mapid(map), x0, y0, x1, y1, BL_PC, name, type);
+ }
+ else
+ {
+ ShowError("buildin_soundeffectall: insufficient arguments for specific area broadcast.\n");
+ }
+
+ return 0;
}
/*==========================================
* pet status recovery [Valaris] / Rewritten by [Skotlex]
*------------------------------------------*/
BUILDIN_FUNC(petrecovery)
{
- struct pet_data *pd;
- TBL_PC *sd=script_rid2sd(st);
+ struct pet_data *pd;
+ TBL_PC *sd=script_rid2sd(st);
- if (sd==NULL || sd->pd==NULL)
- return 0;
+ if(sd==NULL || sd->pd==NULL)
+ return 0;
- pd=sd->pd;
+ pd=sd->pd;
- if (pd->recovery) {
- //Halt previous bonus
- if (pd->recovery->timer != INVALID_TIMER)
- delete_timer(pd->recovery->timer, pet_recovery_timer);
- } else //Init
- pd->recovery = (struct pet_recovery *)aMalloc(sizeof(struct pet_recovery));
+ if (pd->recovery)
+ { //Halt previous bonus
+ if (pd->recovery->timer != INVALID_TIMER)
+ delete_timer(pd->recovery->timer, pet_recovery_timer);
+ } else //Init
+ pd->recovery = (struct pet_recovery *)aMalloc(sizeof(struct pet_recovery));
- pd->recovery->type = (sc_type)script_getnum(st,2);
- pd->recovery->delay = script_getnum(st,3);
- pd->recovery->timer = INVALID_TIMER;
+ pd->recovery->type = (sc_type)script_getnum(st,2);
+ pd->recovery->delay = script_getnum(st,3);
+ pd->recovery->timer = INVALID_TIMER;
- return 0;
+ return 0;
}
/*==========================================
@@ -12395,38 +12333,39 @@ BUILDIN_FUNC(petrecovery)
*------------------------------------------*/
BUILDIN_FUNC(petheal)
{
- struct pet_data *pd;
- TBL_PC *sd=script_rid2sd(st);
-
- if (sd==NULL || sd->pd==NULL)
- return 0;
-
- pd=sd->pd;
- if (pd->s_skill) {
- //Clear previous skill
- if (pd->s_skill->timer != INVALID_TIMER) {
- if (pd->s_skill->id)
- delete_timer(pd->s_skill->timer, pet_skill_support_timer);
- else
- delete_timer(pd->s_skill->timer, pet_heal_timer);
- }
- } else //init memory
- pd->s_skill = (struct pet_skill_support *) aMalloc(sizeof(struct pet_skill_support));
-
- pd->s_skill->id=0; //This id identifies that it IS petheal rather than pet_skillsupport
- //Use the lv as the amount to heal
- pd->s_skill->lv=script_getnum(st,2);
- pd->s_skill->delay=script_getnum(st,3);
- pd->s_skill->hp=script_getnum(st,4);
- pd->s_skill->sp=script_getnum(st,5);
-
- //Use delay as initial offset to avoid skill/heal exploits
- if (battle_config.pet_equip_required && pd->pet.equip == 0)
- pd->s_skill->timer = INVALID_TIMER;
- else
- pd->s_skill->timer = add_timer(gettick()+pd->s_skill->delay*1000,pet_heal_timer,sd->bl.id,0);
-
- return 0;
+ struct pet_data *pd;
+ TBL_PC *sd=script_rid2sd(st);
+
+ if(sd==NULL || sd->pd==NULL)
+ return 0;
+
+ pd=sd->pd;
+ if (pd->s_skill)
+ { //Clear previous skill
+ if (pd->s_skill->timer != INVALID_TIMER)
+ {
+ if (pd->s_skill->id)
+ delete_timer(pd->s_skill->timer, pet_skill_support_timer);
+ else
+ delete_timer(pd->s_skill->timer, pet_heal_timer);
+ }
+ } else //init memory
+ pd->s_skill = (struct pet_skill_support *) aMalloc(sizeof(struct pet_skill_support));
+
+ pd->s_skill->id=0; //This id identifies that it IS petheal rather than pet_skillsupport
+ //Use the lv as the amount to heal
+ pd->s_skill->lv=script_getnum(st,2);
+ pd->s_skill->delay=script_getnum(st,3);
+ pd->s_skill->hp=script_getnum(st,4);
+ pd->s_skill->sp=script_getnum(st,5);
+
+ //Use delay as initial offset to avoid skill/heal exploits
+ if (battle_config.pet_equip_required && pd->pet.equip == 0)
+ pd->s_skill->timer = INVALID_TIMER;
+ else
+ pd->s_skill->timer = add_timer(gettick()+pd->s_skill->delay*1000,pet_heal_timer,sd->bl.id,0);
+
+ return 0;
}
/*==========================================
@@ -12436,23 +12375,23 @@ BUILDIN_FUNC(petheal)
/// petskillattack "<skill name>",<level>,<rate>,<bonusrate>
BUILDIN_FUNC(petskillattack)
{
- struct pet_data *pd;
- TBL_PC *sd=script_rid2sd(st);
+ struct pet_data *pd;
+ TBL_PC *sd=script_rid2sd(st);
- if (sd==NULL || sd->pd==NULL)
- return 0;
+ if(sd==NULL || sd->pd==NULL)
+ return 0;
- pd=sd->pd;
- if (pd->a_skill == NULL)
- pd->a_skill = (struct pet_skill_attack *)aMalloc(sizeof(struct pet_skill_attack));
+ pd=sd->pd;
+ if (pd->a_skill == NULL)
+ pd->a_skill = (struct pet_skill_attack *)aMalloc(sizeof(struct pet_skill_attack));
- pd->a_skill->id=(script_isstring(st,2) ? skill_name2id(script_getstr(st,2)) : script_getnum(st,2));
- pd->a_skill->lv=script_getnum(st,3);
- pd->a_skill->div_ = 0;
- pd->a_skill->rate=script_getnum(st,4);
- pd->a_skill->bonusrate=script_getnum(st,5);
+ pd->a_skill->id=( script_isstring(st,2) ? skill_name2id(script_getstr(st,2)) : script_getnum(st,2) );
+ pd->a_skill->lv=script_getnum(st,3);
+ pd->a_skill->div_ = 0;
+ pd->a_skill->rate=script_getnum(st,4);
+ pd->a_skill->bonusrate=script_getnum(st,5);
- return 0;
+ return 0;
}
/*==========================================
@@ -12462,23 +12401,23 @@ BUILDIN_FUNC(petskillattack)
/// petskillattack2 "<skill name>",<level>,<div>,<rate>,<bonusrate>
BUILDIN_FUNC(petskillattack2)
{
- struct pet_data *pd;
- TBL_PC *sd=script_rid2sd(st);
+ struct pet_data *pd;
+ TBL_PC *sd=script_rid2sd(st);
- if (sd==NULL || sd->pd==NULL)
- return 0;
+ if(sd==NULL || sd->pd==NULL)
+ return 0;
- pd=sd->pd;
- if (pd->a_skill == NULL)
- pd->a_skill = (struct pet_skill_attack *)aMalloc(sizeof(struct pet_skill_attack));
+ pd=sd->pd;
+ if (pd->a_skill == NULL)
+ pd->a_skill = (struct pet_skill_attack *)aMalloc(sizeof(struct pet_skill_attack));
- pd->a_skill->id=(script_isstring(st,2) ? skill_name2id(script_getstr(st,2)) : script_getnum(st,2));
- pd->a_skill->lv=script_getnum(st,3);
- pd->a_skill->div_ = script_getnum(st,4);
- pd->a_skill->rate=script_getnum(st,5);
- pd->a_skill->bonusrate=script_getnum(st,6);
+ pd->a_skill->id=( script_isstring(st,2) ? skill_name2id(script_getstr(st,2)) : script_getnum(st,2) );
+ pd->a_skill->lv=script_getnum(st,3);
+ pd->a_skill->div_ = script_getnum(st,4);
+ pd->a_skill->rate=script_getnum(st,5);
+ pd->a_skill->bonusrate=script_getnum(st,6);
- return 0;
+ return 0;
}
/*==========================================
@@ -12488,37 +12427,38 @@ BUILDIN_FUNC(petskillattack2)
/// petskillsupport "<skill name>",<level>,<delay>,<hp>,<sp>
BUILDIN_FUNC(petskillsupport)
{
- struct pet_data *pd;
- TBL_PC *sd=script_rid2sd(st);
+ struct pet_data *pd;
+ TBL_PC *sd=script_rid2sd(st);
- if (sd==NULL || sd->pd==NULL)
- return 0;
+ if(sd==NULL || sd->pd==NULL)
+ return 0;
- pd=sd->pd;
- if (pd->s_skill) {
- //Clear previous skill
- if (pd->s_skill->timer != INVALID_TIMER) {
- if (pd->s_skill->id)
- delete_timer(pd->s_skill->timer, pet_skill_support_timer);
- else
- delete_timer(pd->s_skill->timer, pet_heal_timer);
- }
- } else //init memory
- pd->s_skill = (struct pet_skill_support *) aMalloc(sizeof(struct pet_skill_support));
+ pd=sd->pd;
+ if (pd->s_skill)
+ { //Clear previous skill
+ if (pd->s_skill->timer != INVALID_TIMER)
+ {
+ if (pd->s_skill->id)
+ delete_timer(pd->s_skill->timer, pet_skill_support_timer);
+ else
+ delete_timer(pd->s_skill->timer, pet_heal_timer);
+ }
+ } else //init memory
+ pd->s_skill = (struct pet_skill_support *) aMalloc(sizeof(struct pet_skill_support));
- pd->s_skill->id=(script_isstring(st,2) ? skill_name2id(script_getstr(st,2)) : script_getnum(st,2));
- pd->s_skill->lv=script_getnum(st,3);
- pd->s_skill->delay=script_getnum(st,4);
- pd->s_skill->hp=script_getnum(st,5);
- pd->s_skill->sp=script_getnum(st,6);
+ pd->s_skill->id=( script_isstring(st,2) ? skill_name2id(script_getstr(st,2)) : script_getnum(st,2) );
+ pd->s_skill->lv=script_getnum(st,3);
+ pd->s_skill->delay=script_getnum(st,4);
+ pd->s_skill->hp=script_getnum(st,5);
+ pd->s_skill->sp=script_getnum(st,6);
- //Use delay as initial offset to avoid skill/heal exploits
- if (battle_config.pet_equip_required && pd->pet.equip == 0)
- pd->s_skill->timer = INVALID_TIMER;
- else
- pd->s_skill->timer = add_timer(gettick()+pd->s_skill->delay*1000,pet_skill_support_timer,sd->bl.id,0);
+ //Use delay as initial offset to avoid skill/heal exploits
+ if (battle_config.pet_equip_required && pd->pet.equip == 0)
+ pd->s_skill->timer = INVALID_TIMER;
+ else
+ pd->s_skill->timer = add_timer(gettick()+pd->s_skill->delay*1000,pet_skill_support_timer,sd->bl.id,0);
- return 0;
+ return 0;
}
/*==========================================
@@ -12528,15 +12468,15 @@ BUILDIN_FUNC(petskillsupport)
/// skilleffect "<skill name>",<level>
BUILDIN_FUNC(skilleffect)
{
- TBL_PC *sd;
+ TBL_PC *sd;
- int skillid=(script_isstring(st,2) ? skill_name2id(script_getstr(st,2)) : script_getnum(st,2));
- int skilllv=script_getnum(st,3);
- sd=script_rid2sd(st);
+ int skillid=( script_isstring(st,2) ? skill_name2id(script_getstr(st,2)) : script_getnum(st,2) );
+ int skilllv=script_getnum(st,3);
+ sd=script_rid2sd(st);
- clif_skill_nodamage(&sd->bl,&sd->bl,skillid,skilllv,1);
+ clif_skill_nodamage(&sd->bl,&sd->bl,skillid,skilllv,1);
- return 0;
+ return 0;
}
/*==========================================
@@ -12546,17 +12486,17 @@ BUILDIN_FUNC(skilleffect)
/// npcskilleffect "<skill name>",<level>,<x>,<y>
BUILDIN_FUNC(npcskilleffect)
{
- struct block_list *bl= map_id2bl(st->oid);
+ struct block_list *bl= map_id2bl(st->oid);
- int skillid=(script_isstring(st,2) ? skill_name2id(script_getstr(st,2)) : script_getnum(st,2));
- int skilllv=script_getnum(st,3);
- int x=script_getnum(st,4);
- int y=script_getnum(st,5);
+ int skillid=( script_isstring(st,2) ? skill_name2id(script_getstr(st,2)) : script_getnum(st,2) );
+ int skilllv=script_getnum(st,3);
+ int x=script_getnum(st,4);
+ int y=script_getnum(st,5);
- if (bl)
- clif_skill_poseffect(bl,skillid,skilllv,x,y,gettick());
+ if (bl)
+ clif_skill_poseffect(bl,skillid,skilllv,x,y,gettick());
- return 0;
+ return 0;
}
/*==========================================
@@ -12564,43 +12504,46 @@ BUILDIN_FUNC(npcskilleffect)
*------------------------------------------*/
BUILDIN_FUNC(specialeffect)
{
- struct block_list *bl=map_id2bl(st->oid);
- int type = script_getnum(st,2);
- enum send_target target = script_hasdata(st,3) ? (send_target)script_getnum(st,3) : AREA;
-
- if (bl==NULL)
- return 0;
-
- if (script_hasdata(st,4)) {
- TBL_NPC *nd = npc_name2id(script_getstr(st,4));
- if (nd)
- clif_specialeffect(&nd->bl, type, target);
- } else {
- if (target == SELF) {
- TBL_PC *sd=script_rid2sd(st);
- if (sd)
- clif_specialeffect_single(bl,type,sd->fd);
- } else {
- clif_specialeffect(bl, type, target);
- }
- }
-
- return 0;
+ struct block_list *bl=map_id2bl(st->oid);
+ int type = script_getnum(st,2);
+ enum send_target target = script_hasdata(st,3) ? (send_target)script_getnum(st,3) : AREA;
+
+ if(bl==NULL)
+ return 0;
+
+ if( script_hasdata(st,4) )
+ {
+ TBL_NPC *nd = npc_name2id(script_getstr(st,4));
+ if(nd)
+ clif_specialeffect(&nd->bl, type, target);
+ }
+ else
+ {
+ if (target == SELF) {
+ TBL_PC *sd=script_rid2sd(st);
+ if (sd)
+ clif_specialeffect_single(bl,type,sd->fd);
+ } else {
+ clif_specialeffect(bl, type, target);
+ }
+ }
+
+ return 0;
}
BUILDIN_FUNC(specialeffect2)
{
- TBL_PC *sd=script_rid2sd(st);
- int type = script_getnum(st,2);
- enum send_target target = script_hasdata(st,3) ? (send_target)script_getnum(st,3) : AREA;
+ TBL_PC *sd=script_rid2sd(st);
+ int type = script_getnum(st,2);
+ enum send_target target = script_hasdata(st,3) ? (send_target)script_getnum(st,3) : AREA;
- if (script_hasdata(st,4))
- sd = map_nick2sd(script_getstr(st,4));
+ if( script_hasdata(st,4) )
+ sd = map_nick2sd(script_getstr(st,4));
- if (sd)
- clif_specialeffect(&sd->bl, type, target);
+ if (sd)
+ clif_specialeffect(&sd->bl, type, target);
- return 0;
+ return 0;
}
/*==========================================
@@ -12608,24 +12551,24 @@ BUILDIN_FUNC(specialeffect2)
*------------------------------------------*/
BUILDIN_FUNC(nude)
{
- TBL_PC *sd = script_rid2sd(st);
- int i, calcflag = 0;
+ TBL_PC *sd = script_rid2sd(st);
+ int i, calcflag = 0;
- if (sd == NULL)
- return 0;
+ if( sd == NULL )
+ return 0;
- for (i = 0 ; i < EQI_MAX; i++) {
- if (sd->equip_index[ i ] >= 0) {
- if (!calcflag)
- calcflag = 1;
- pc_unequipitem(sd , sd->equip_index[ i ] , 2);
- }
- }
+ for( i = 0 ; i < EQI_MAX; i++ ) {
+ if( sd->equip_index[ i ] >= 0 ) {
+ if( !calcflag )
+ calcflag = 1;
+ pc_unequipitem( sd , sd->equip_index[ i ] , 2);
+ }
+ }
- if (calcflag)
- status_calc_pc(sd,0);
+ if( calcflag )
+ status_calc_pc(sd,0);
- return 0;
+ return 0;
}
/*==========================================
@@ -12633,36 +12576,37 @@ BUILDIN_FUNC(nude)
*------------------------------------------*/
BUILDIN_FUNC(atcommand)
{
- TBL_PC dummy_sd;
- TBL_PC *sd;
- int fd;
- const char *cmd;
-
- cmd = script_getstr(st,2);
-
- if (st->rid) {
- sd = script_rid2sd(st);
- fd = sd->fd;
- } else { //Use a dummy character.
- sd = &dummy_sd;
- fd = 0;
-
- memset(&dummy_sd, 0, sizeof(TBL_PC));
- if (st->oid) {
- struct block_list *bl = map_id2bl(st->oid);
- memcpy(&dummy_sd.bl, bl, sizeof(struct block_list));
- if (bl->type == BL_NPC)
- safestrncpy(dummy_sd.status.name, ((TBL_NPC *)bl)->name, NAME_LENGTH);
- }
- }
+ TBL_PC dummy_sd;
+ TBL_PC* sd;
+ int fd;
+ const char* cmd;
- if (!is_atcommand(fd, sd, cmd, 0)) {
- ShowWarning("script: buildin_atcommand: failed to execute command '%s'\n", cmd);
- script_reportsrc(st);
- return 1;
- }
+ cmd = script_getstr(st,2);
- return 0;
+ if (st->rid) {
+ sd = script_rid2sd(st);
+ fd = sd->fd;
+ } else { //Use a dummy character.
+ sd = &dummy_sd;
+ fd = 0;
+
+ memset(&dummy_sd, 0, sizeof(TBL_PC));
+ if (st->oid)
+ {
+ struct block_list* bl = map_id2bl(st->oid);
+ memcpy(&dummy_sd.bl, bl, sizeof(struct block_list));
+ if (bl->type == BL_NPC)
+ safestrncpy(dummy_sd.status.name, ((TBL_NPC*)bl)->name, NAME_LENGTH);
+ }
+ }
+
+ if (!is_atcommand(fd, sd, cmd, 0)) {
+ ShowWarning("script: buildin_atcommand: failed to execute command '%s'\n", cmd);
+ script_reportsrc(st);
+ return 1;
+ }
+
+ return 0;
}
/*==========================================
@@ -12670,12 +12614,12 @@ BUILDIN_FUNC(atcommand)
*------------------------------------------*/
BUILDIN_FUNC(dispbottom)
{
- TBL_PC *sd=script_rid2sd(st);
- const char *message;
- message=script_getstr(st,2);
- if (sd)
- clif_disp_onlyself(sd,message,(int)strlen(message));
- return 0;
+ TBL_PC *sd=script_rid2sd(st);
+ const char *message;
+ message=script_getstr(st,2);
+ if(sd)
+ clif_disp_onlyself(sd,message,(int)strlen(message));
+ return 0;
}
/*==========================================
@@ -12684,19 +12628,20 @@ BUILDIN_FUNC(dispbottom)
*------------------------------------------*/
BUILDIN_FUNC(recovery)
{
- TBL_PC *sd;
- struct s_mapiterator *iter;
-
- iter = mapit_getallusers();
- for (sd = (TBL_PC *)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC *)mapit_next(iter)) {
- if (pc_isdead(sd))
- status_revive(&sd->bl, 100, 100);
- else
- status_percent_heal(&sd->bl, 100, 100);
- clif_displaymessage(sd->fd,msg_txt(680));
- }
- mapit_free(iter);
- return 0;
+ TBL_PC* sd;
+ struct s_mapiterator* iter;
+
+ iter = mapit_getallusers();
+ for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
+ {
+ if(pc_isdead(sd))
+ status_revive(&sd->bl, 100, 100);
+ else
+ status_percent_heal(&sd->bl, 100, 100);
+ clif_displaymessage(sd->fd,msg_txt(680));
+ }
+ mapit_free(iter);
+ return 0;
}
/*==========================================
* Get your pet info: getpetinfo(n)
@@ -12705,42 +12650,30 @@ BUILDIN_FUNC(recovery)
*------------------------------------------*/
BUILDIN_FUNC(getpetinfo)
{
- TBL_PC *sd=script_rid2sd(st);
- TBL_PET *pd;
- int type=script_getnum(st,2);
-
- if (!sd || !sd->pd) {
- if (type == 2)
- script_pushconststr(st,"null");
- else
- script_pushint(st,0);
- return 0;
- }
- pd = sd->pd;
- switch (type) {
- case 0:
- script_pushint(st,pd->pet.pet_id);
- break;
- case 1:
- script_pushint(st,pd->pet.class_);
- break;
- case 2:
- script_pushstrcopy(st,pd->pet.name);
- break;
- case 3:
- script_pushint(st,pd->pet.intimate);
- break;
- case 4:
- script_pushint(st,pd->pet.hungry);
- break;
- case 5:
- script_pushint(st,pd->pet.rename_flag);
- break;
- default:
- script_pushint(st,0);
- break;
- }
- return 0;
+ TBL_PC *sd=script_rid2sd(st);
+ TBL_PET *pd;
+ int type=script_getnum(st,2);
+
+ if(!sd || !sd->pd) {
+ if (type == 2)
+ script_pushconststr(st,"null");
+ else
+ script_pushint(st,0);
+ return 0;
+ }
+ pd = sd->pd;
+ switch(type){
+ case 0: script_pushint(st,pd->pet.pet_id); break;
+ case 1: script_pushint(st,pd->pet.class_); break;
+ case 2: script_pushstrcopy(st,pd->pet.name); break;
+ case 3: script_pushint(st,pd->pet.intimate); break;
+ case 4: script_pushint(st,pd->pet.hungry); break;
+ case 5: script_pushint(st,pd->pet.rename_flag); break;
+ default:
+ script_pushint(st,0);
+ break;
+ }
+ return 0;
}
/*==========================================
@@ -12751,159 +12684,138 @@ BUILDIN_FUNC(getpetinfo)
*------------------------------------------*/
BUILDIN_FUNC(gethominfo)
{
- TBL_PC *sd=script_rid2sd(st);
- TBL_HOM *hd;
- int type=script_getnum(st,2);
-
- hd = sd?sd->hd:NULL;
- if (!merc_is_hom_active(hd)) {
- if (type == 2)
- script_pushconststr(st,"null");
- else
- script_pushint(st,0);
- return 0;
- }
-
- switch (type) {
- case 0:
- script_pushint(st,hd->homunculus.hom_id);
- break;
- case 1:
- script_pushint(st,hd->homunculus.class_);
- break;
- case 2:
- script_pushstrcopy(st,hd->homunculus.name);
- break;
- case 3:
- script_pushint(st,hd->homunculus.intimacy);
- break;
- case 4:
- script_pushint(st,hd->homunculus.hunger);
- break;
- case 5:
- script_pushint(st,hd->homunculus.rename_flag);
- break;
- case 6:
- script_pushint(st,hd->homunculus.level);
- break;
- default:
- script_pushint(st,0);
- break;
- }
- return 0;
+ TBL_PC *sd=script_rid2sd(st);
+ TBL_HOM *hd;
+ int type=script_getnum(st,2);
+
+ hd = sd?sd->hd:NULL;
+ if(!merc_is_hom_active(hd))
+ {
+ if (type == 2)
+ script_pushconststr(st,"null");
+ else
+ script_pushint(st,0);
+ return 0;
+ }
+
+ switch(type){
+ case 0: script_pushint(st,hd->homunculus.hom_id); break;
+ case 1: script_pushint(st,hd->homunculus.class_); break;
+ case 2: script_pushstrcopy(st,hd->homunculus.name); break;
+ case 3: script_pushint(st,hd->homunculus.intimacy); break;
+ case 4: script_pushint(st,hd->homunculus.hunger); break;
+ case 5: script_pushint(st,hd->homunculus.rename_flag); break;
+ case 6: script_pushint(st,hd->homunculus.level); break;
+ default:
+ script_pushint(st,0);
+ break;
+ }
+ return 0;
}
/// Retrieves information about character's mercenary
/// getmercinfo <type>[,<char id>];
BUILDIN_FUNC(getmercinfo)
{
- int type, char_id;
- struct map_session_data *sd;
- struct mercenary_data *md;
-
- type = script_getnum(st,2);
-
- if (script_hasdata(st,3)) {
- char_id = script_getnum(st,3);
-
- if ((sd = map_charid2sd(char_id)) == NULL) {
- ShowError("buildin_getmercinfo: No such character (char_id=%d).\n", char_id);
- script_pushnil(st);
- return 1;
- }
- } else {
- if ((sd = script_rid2sd(st)) == NULL) {
- script_pushnil(st);
- return 0;
- }
- }
-
- md = (sd->status.mer_id && sd->md) ? sd->md : NULL;
-
- switch (type) {
- case 0:
- script_pushint(st,md ? md->mercenary.mercenary_id : 0);
- break;
- case 1:
- script_pushint(st,md ? md->mercenary.class_ : 0);
- break;
- case 2:
- if (md)
- script_pushstrcopy(st,md->db->name);
- else
- script_pushconststr(st,"");
- break;
- case 3:
- script_pushint(st,md ? mercenary_get_faith(md) : 0);
- break;
- case 4:
- script_pushint(st,md ? mercenary_get_calls(md) : 0);
- break;
- case 5:
- script_pushint(st,md ? md->mercenary.kill_count : 0);
- break;
- case 6:
- script_pushint(st,md ? mercenary_get_lifetime(md) : 0);
- break;
- case 7:
- script_pushint(st,md ? md->db->lv : 0);
- break;
- default:
- ShowError("buildin_getmercinfo: Invalid type %d (char_id=%d).\n", type, sd->status.char_id);
- script_pushnil(st);
- return 1;
- }
-
- return 0;
+ int type, char_id;
+ struct map_session_data* sd;
+ struct mercenary_data* md;
+
+ type = script_getnum(st,2);
+
+ if( script_hasdata(st,3) )
+ {
+ char_id = script_getnum(st,3);
+
+ if( ( sd = map_charid2sd(char_id) ) == NULL )
+ {
+ ShowError("buildin_getmercinfo: No such character (char_id=%d).\n", char_id);
+ script_pushnil(st);
+ return 1;
+ }
+ }
+ else
+ {
+ if( ( sd = script_rid2sd(st) ) == NULL )
+ {
+ script_pushnil(st);
+ return 0;
+ }
+ }
+
+ md = ( sd->status.mer_id && sd->md ) ? sd->md : NULL;
+
+ switch( type )
+ {
+ case 0: script_pushint(st,md ? md->mercenary.mercenary_id : 0); break;
+ case 1: script_pushint(st,md ? md->mercenary.class_ : 0); break;
+ case 2:
+ if( md )
+ script_pushstrcopy(st,md->db->name);
+ else
+ script_pushconststr(st,"");
+ break;
+ case 3: script_pushint(st,md ? mercenary_get_faith(md) : 0); break;
+ case 4: script_pushint(st,md ? mercenary_get_calls(md) : 0); break;
+ case 5: script_pushint(st,md ? md->mercenary.kill_count : 0); break;
+ case 6: script_pushint(st,md ? mercenary_get_lifetime(md) : 0); break;
+ case 7: script_pushint(st,md ? md->db->lv : 0); break;
+ default:
+ ShowError("buildin_getmercinfo: Invalid type %d (char_id=%d).\n", type, sd->status.char_id);
+ script_pushnil(st);
+ return 1;
+ }
+
+ return 0;
}
/*==========================================
* Shows wether your inventory(and equips) contain
selected card or not.
- checkequipedcard(4001);
+ checkequipedcard(4001);
*------------------------------------------*/
BUILDIN_FUNC(checkequipedcard)
{
- TBL_PC *sd=script_rid2sd(st);
-
- if (sd) {
- int n,i,c=0;
- c=script_getnum(st,2);
-
- for (i=0; i<MAX_INVENTORY; i++) {
- if (sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].amount && sd->inventory_data[i]) {
- if (itemdb_isspecial(sd->status.inventory[i].card[0]))
- continue;
- for (n=0; n<sd->inventory_data[i]->slot; n++) {
- if (sd->status.inventory[i].card[n]==c) {
- script_pushint(st,1);
- return 0;
- }
- }
- }
- }
- }
- script_pushint(st,0);
- return 0;
+ TBL_PC *sd=script_rid2sd(st);
+
+ if(sd){
+ int n,i,c=0;
+ c=script_getnum(st,2);
+
+ for(i=0;i<MAX_INVENTORY;i++){
+ if(sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].amount && sd->inventory_data[i]){
+ if (itemdb_isspecial(sd->status.inventory[i].card[0]))
+ continue;
+ for(n=0;n<sd->inventory_data[i]->slot;n++){
+ if(sd->status.inventory[i].card[n]==c){
+ script_pushint(st,1);
+ return 0;
+ }
+ }
+ }
+ }
+ }
+ script_pushint(st,0);
+ return 0;
}
BUILDIN_FUNC(jump_zero)
{
- int sel;
- sel=script_getnum(st,2);
- if (!sel) {
- int pos;
- if (!data_islabel(script_getdata(st,3))) {
- ShowError("script: jump_zero: not label !\n");
- st->state=END;
- return 1;
- }
+ int sel;
+ sel=script_getnum(st,2);
+ if(!sel) {
+ int pos;
+ if( !data_islabel(script_getdata(st,3)) ){
+ ShowError("script: jump_zero: not label !\n");
+ st->state=END;
+ return 1;
+ }
- pos=script_getnum(st,3);
- st->pos=pos;
- st->state=GOTO;
- }
- return 0;
+ pos=script_getnum(st,3);
+ st->pos=pos;
+ st->state=GOTO;
+ }
+ return 0;
}
/*==========================================
@@ -12911,21 +12823,21 @@ BUILDIN_FUNC(jump_zero)
*------------------------------------------*/
BUILDIN_FUNC(movenpc)
{
- TBL_NPC *nd = NULL;
- const char *npc;
- int x,y;
+ TBL_NPC *nd = NULL;
+ const char *npc;
+ int x,y;
- npc = script_getstr(st,2);
- x = script_getnum(st,3);
- y = script_getnum(st,4);
+ npc = script_getstr(st,2);
+ x = script_getnum(st,3);
+ y = script_getnum(st,4);
- if ((nd = npc_name2id(npc)) == NULL)
- return -1;
+ if ((nd = npc_name2id(npc)) == NULL)
+ return -1;
- if (script_hasdata(st,5))
- nd->ud.dir = script_getnum(st,5) % 8;
- npc_movenpc(nd, x, y);
- return 0;
+ if (script_hasdata(st,5))
+ nd->ud.dir = script_getnum(st,5) % 8;
+ npc_movenpc(nd, x, y);
+ return 0;
}
/*==========================================
@@ -12933,17 +12845,17 @@ BUILDIN_FUNC(movenpc)
*------------------------------------------*/
BUILDIN_FUNC(message)
{
- const char *msg,*player;
- TBL_PC *pl_sd = NULL;
+ const char *msg,*player;
+ TBL_PC *pl_sd = NULL;
- player = script_getstr(st,2);
- msg = script_getstr(st,3);
+ player = script_getstr(st,2);
+ msg = script_getstr(st,3);
- if ((pl_sd=map_nick2sd((char *) player)) == NULL)
- return 0;
- clif_displaymessage(pl_sd->fd, msg);
+ if((pl_sd=map_nick2sd((char *) player)) == NULL)
+ return 0;
+ clif_displaymessage(pl_sd->fd, msg);
- return 0;
+ return 0;
}
/*==========================================
@@ -12951,63 +12863,65 @@ BUILDIN_FUNC(message)
*------------------------------------------*/
BUILDIN_FUNC(npctalk)
{
- const char *str;
- char name[NAME_LENGTH], message[256];
+ const char* str;
+ char name[NAME_LENGTH], message[256];
- struct npc_data *nd = (struct npc_data *)map_id2bl(st->oid);
- str = script_getstr(st,2);
+ struct npc_data* nd = (struct npc_data *)map_id2bl(st->oid);
+ str = script_getstr(st,2);
- if (nd) {
- safestrncpy(name, nd->name, sizeof(name));
- strtok(name, "#"); // discard extra name identifier if present
- safesnprintf(message, sizeof(message), "%s : %s", name, str);
- clif_message(&nd->bl, message);
- }
+ if(nd)
+ {
+ safestrncpy(name, nd->name, sizeof(name));
+ strtok(name, "#"); // discard extra name identifier if present
+ safesnprintf(message, sizeof(message), "%s : %s", name, str);
+ clif_message(&nd->bl, message);
+ }
- return 0;
+ return 0;
}
// change npc walkspeed [Valaris]
BUILDIN_FUNC(npcspeed)
{
- struct npc_data *nd;
- int speed;
+ struct npc_data* nd;
+ int speed;
- speed = script_getnum(st,2);
- nd =(struct npc_data *)map_id2bl(st->oid);
+ speed = script_getnum(st,2);
+ nd =(struct npc_data *)map_id2bl(st->oid);
- if (nd) {
- nd->speed = speed;
- nd->ud.state.speed_changed = 1;
- }
+ if( nd )
+ {
+ nd->speed = speed;
+ nd->ud.state.speed_changed = 1;
+ }
- return 0;
+ return 0;
}
// make an npc walk to a position [Valaris]
BUILDIN_FUNC(npcwalkto)
{
- struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid);
- int x=0,y=0;
+ struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid);
+ int x=0,y=0;
- x=script_getnum(st,2);
- y=script_getnum(st,3);
+ x=script_getnum(st,2);
+ y=script_getnum(st,3);
- if (nd) {
- unit_walktoxy(&nd->bl,x,y,0);
- }
+ if(nd) {
+ unit_walktoxy(&nd->bl,x,y,0);
+ }
- return 0;
+ return 0;
}
// stop an npc's movement [Valaris]
BUILDIN_FUNC(npcstop)
{
- struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid);
+ struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid);
- if (nd) {
- unit_stop_walking(&nd->bl,1|4);
- }
+ if(nd) {
+ unit_stop_walking(&nd->bl,1|4);
+ }
- return 0;
+ return 0;
}
@@ -13016,43 +12930,26 @@ BUILDIN_FUNC(npcstop)
*------------------------------------------*/
BUILDIN_FUNC(getlook)
{
- int type,val;
- TBL_PC *sd;
- sd=script_rid2sd(st);
-
- type=script_getnum(st,2);
- val=-1;
- switch (type) {
- case LOOK_HAIR:
- val=sd->status.hair;
- break; //1
- case LOOK_WEAPON:
- val=sd->status.weapon;
- break; //2
- case LOOK_HEAD_BOTTOM:
- val=sd->status.head_bottom;
- break; //3
- case LOOK_HEAD_TOP:
- val=sd->status.head_top;
- break; //4
- case LOOK_HEAD_MID:
- val=sd->status.head_mid;
- break; //5
- case LOOK_HAIR_COLOR:
- val=sd->status.hair_color;
- break; //6
- case LOOK_CLOTHES_COLOR:
- val=sd->status.clothes_color;
- break; //7
- case LOOK_SHIELD:
- val=sd->status.shield;
- break; //8
- case LOOK_SHOES:
- break; //9
- }
+ int type,val;
+ TBL_PC *sd;
+ sd=script_rid2sd(st);
- script_pushint(st,val);
- return 0;
+ type=script_getnum(st,2);
+ val=-1;
+ switch(type) {
+ case LOOK_HAIR: val=sd->status.hair; break; //1
+ case LOOK_WEAPON: val=sd->status.weapon; break; //2
+ case LOOK_HEAD_BOTTOM: val=sd->status.head_bottom; break; //3
+ case LOOK_HEAD_TOP: val=sd->status.head_top; break; //4
+ case LOOK_HEAD_MID: val=sd->status.head_mid; break; //5
+ case LOOK_HAIR_COLOR: val=sd->status.hair_color; break; //6
+ case LOOK_CLOTHES_COLOR: val=sd->status.clothes_color; break; //7
+ case LOOK_SHIELD: val=sd->status.shield; break; //8
+ case LOOK_SHOES: break; //9
+ }
+
+ script_pushint(st,val);
+ return 0;
}
/*==========================================
@@ -13060,32 +12957,26 @@ BUILDIN_FUNC(getlook)
*------------------------------------------*/
BUILDIN_FUNC(getsavepoint)
{
- TBL_PC *sd;
- int type;
+ TBL_PC* sd;
+ int type;
- sd = script_rid2sd(st);
- if (sd == NULL) {
- script_pushint(st,0);
- return 0;
- }
+ sd = script_rid2sd(st);
+ if (sd == NULL) {
+ script_pushint(st,0);
+ return 0;
+ }
- type = script_getnum(st,2);
-
- switch (type) {
- case 0:
- script_pushstrcopy(st,mapindex_id2name(sd->status.save_point.map));
- break;
- case 1:
- script_pushint(st,sd->status.save_point.x);
- break;
- case 2:
- script_pushint(st,sd->status.save_point.y);
- break;
- default:
- script_pushint(st,0);
- break;
- }
- return 0;
+ type = script_getnum(st,2);
+
+ switch(type) {
+ case 0: script_pushstrcopy(st,mapindex_id2name(sd->status.save_point.map)); break;
+ case 1: script_pushint(st,sd->status.save_point.x); break;
+ case 2: script_pushint(st,sd->status.save_point.y); break;
+ default:
+ script_pushint(st,0);
+ break;
+ }
+ return 0;
}
/*==========================================
@@ -13112,142 +13003,143 @@ BUILDIN_FUNC(getsavepoint)
*------------------------------------------*/
BUILDIN_FUNC(getmapxy)
{
- struct block_list *bl = NULL;
- TBL_PC *sd=NULL;
-
- int num;
- const char *name;
- char prefix;
-
- int x,y,type;
- char mapname[MAP_NAME_LENGTH];
-
- if (!data_isreference(script_getdata(st,2))) {
- ShowWarning("script: buildin_getmapxy: not mapname variable\n");
- script_pushint(st,-1);
- return 1;
- }
- if (!data_isreference(script_getdata(st,3))) {
- ShowWarning("script: buildin_getmapxy: not mapx variable\n");
- script_pushint(st,-1);
- return 1;
- }
- if (!data_isreference(script_getdata(st,4))) {
- ShowWarning("script: buildin_getmapxy: not mapy variable\n");
- script_pushint(st,-1);
- return 1;
- }
-
- // Possible needly check function parameters on C_STR,C_INT,C_INT
- type=script_getnum(st,5);
-
- switch (type) {
- case 0: //Get Character Position
- if (script_hasdata(st,6))
- sd=map_nick2sd(script_getstr(st,6));
- else
- sd=script_rid2sd(st);
-
- if (sd)
- bl = &sd->bl;
- break;
- case 1: //Get NPC Position
- if (script_hasdata(st,6)) {
- struct npc_data *nd;
- nd=npc_name2id(script_getstr(st,6));
- if (nd)
- bl = &nd->bl;
- } else //In case the origin is not an npc?
- bl=map_id2bl(st->oid);
- break;
- case 2: //Get Pet Position
- if (script_hasdata(st,6))
- sd=map_nick2sd(script_getstr(st,6));
- else
- sd=script_rid2sd(st);
-
- if (sd && sd->pd)
- bl = &sd->pd->bl;
- break;
- case 3: //Get Mob Position
- break; //Not supported?
- case 4: //Get Homun Position
- if (script_hasdata(st,6))
- sd=map_nick2sd(script_getstr(st,6));
- else
- sd=script_rid2sd(st);
-
- if (sd && sd->hd)
- bl = &sd->hd->bl;
- break;
- case 5: //Get Mercenary Position
- if (script_hasdata(st,6))
- sd=map_nick2sd(script_getstr(st,6));
- else
- sd=script_rid2sd(st);
-
- if (sd && sd->md)
- bl = &sd->md->bl;
- break;
- case 6: //Get Elemental Position
- if (script_hasdata(st,6))
- sd=map_nick2sd(script_getstr(st,6));
- else
- sd=script_rid2sd(st);
-
- if (sd && sd->ed)
- bl = &sd->ed->bl;
- break;
- default:
- ShowWarning("script: buildin_getmapxy: Invalid type %d\n", type);
- script_pushint(st,-1);
- return 1;
- }
- if (!bl) { //No object found.
- script_pushint(st,-1);
- return 0;
- }
-
- x= bl->x;
- y= bl->y;
- safestrncpy(mapname, map[bl->m].name, MAP_NAME_LENGTH);
-
- //Set MapName$
- num=st->stack->stack_data[st->start+2].u.num;
- name=get_str(num&0x00ffffff);
- prefix=*name;
-
- if (not_server_variable(prefix))
- sd=script_rid2sd(st);
- else
- sd=NULL;
- set_reg(st,sd,num,name,(void *)mapname,script_getref(st,2));
-
- //Set MapX
- num=st->stack->stack_data[st->start+3].u.num;
- name=get_str(num&0x00ffffff);
- prefix=*name;
-
- if (not_server_variable(prefix))
- sd=script_rid2sd(st);
- else
- sd=NULL;
- set_reg(st,sd,num,name,(void *)__64BPRTSIZE(x),script_getref(st,3));
-
- //Set MapY
- num=st->stack->stack_data[st->start+4].u.num;
- name=get_str(num&0x00ffffff);
- prefix=*name;
-
- if (not_server_variable(prefix))
- sd=script_rid2sd(st);
- else
- sd=NULL;
- set_reg(st,sd,num,name,(void *)__64BPRTSIZE(y),script_getref(st,4));
-
- //Return Success value
- script_pushint(st,0);
- return 0;
+ struct block_list *bl = NULL;
+ TBL_PC *sd=NULL;
+
+ int num;
+ const char *name;
+ char prefix;
+
+ int x,y,type;
+ char mapname[MAP_NAME_LENGTH];
+
+ if( !data_isreference(script_getdata(st,2)) ){
+ ShowWarning("script: buildin_getmapxy: not mapname variable\n");
+ script_pushint(st,-1);
+ return 1;
+ }
+ if( !data_isreference(script_getdata(st,3)) ){
+ ShowWarning("script: buildin_getmapxy: not mapx variable\n");
+ script_pushint(st,-1);
+ return 1;
+ }
+ if( !data_isreference(script_getdata(st,4)) ){
+ ShowWarning("script: buildin_getmapxy: not mapy variable\n");
+ script_pushint(st,-1);
+ return 1;
+ }
+
+ // Possible needly check function parameters on C_STR,C_INT,C_INT
+ type=script_getnum(st,5);
+
+ switch (type){
+ case 0: //Get Character Position
+ if( script_hasdata(st,6) )
+ sd=map_nick2sd(script_getstr(st,6));
+ else
+ sd=script_rid2sd(st);
+
+ if (sd)
+ bl = &sd->bl;
+ break;
+ case 1: //Get NPC Position
+ if( script_hasdata(st,6) )
+ {
+ struct npc_data *nd;
+ nd=npc_name2id(script_getstr(st,6));
+ if (nd)
+ bl = &nd->bl;
+ } else //In case the origin is not an npc?
+ bl=map_id2bl(st->oid);
+ break;
+ case 2: //Get Pet Position
+ if(script_hasdata(st,6))
+ sd=map_nick2sd(script_getstr(st,6));
+ else
+ sd=script_rid2sd(st);
+
+ if (sd && sd->pd)
+ bl = &sd->pd->bl;
+ break;
+ case 3: //Get Mob Position
+ break; //Not supported?
+ case 4: //Get Homun Position
+ if(script_hasdata(st,6))
+ sd=map_nick2sd(script_getstr(st,6));
+ else
+ sd=script_rid2sd(st);
+
+ if (sd && sd->hd)
+ bl = &sd->hd->bl;
+ break;
+ case 5: //Get Mercenary Position
+ if(script_hasdata(st,6))
+ sd=map_nick2sd(script_getstr(st,6));
+ else
+ sd=script_rid2sd(st);
+
+ if (sd && sd->md)
+ bl = &sd->md->bl;
+ break;
+ case 6: //Get Elemental Position
+ if(script_hasdata(st,6))
+ sd=map_nick2sd(script_getstr(st,6));
+ else
+ sd=script_rid2sd(st);
+
+ if (sd && sd->ed)
+ bl = &sd->ed->bl;
+ break;
+ default:
+ ShowWarning("script: buildin_getmapxy: Invalid type %d\n", type);
+ script_pushint(st,-1);
+ return 1;
+ }
+ if (!bl) { //No object found.
+ script_pushint(st,-1);
+ return 0;
+ }
+
+ x= bl->x;
+ y= bl->y;
+ safestrncpy(mapname, map[bl->m].name, MAP_NAME_LENGTH);
+
+ //Set MapName$
+ num=st->stack->stack_data[st->start+2].u.num;
+ name=get_str(num&0x00ffffff);
+ prefix=*name;
+
+ if(not_server_variable(prefix))
+ sd=script_rid2sd(st);
+ else
+ sd=NULL;
+ set_reg(st,sd,num,name,(void*)mapname,script_getref(st,2));
+
+ //Set MapX
+ num=st->stack->stack_data[st->start+3].u.num;
+ name=get_str(num&0x00ffffff);
+ prefix=*name;
+
+ if(not_server_variable(prefix))
+ sd=script_rid2sd(st);
+ else
+ sd=NULL;
+ set_reg(st,sd,num,name,(void*)__64BPRTSIZE(x),script_getref(st,3));
+
+ //Set MapY
+ num=st->stack->stack_data[st->start+4].u.num;
+ name=get_str(num&0x00ffffff);
+ prefix=*name;
+
+ if(not_server_variable(prefix))
+ sd=script_rid2sd(st);
+ else
+ sd=NULL;
+ set_reg(st,sd,num,name,(void*)__64BPRTSIZE(y),script_getref(st,4));
+
+ //Return Success value
+ script_pushint(st,0);
+ return 0;
}
/*==========================================
@@ -13255,52 +13147,52 @@ BUILDIN_FUNC(getmapxy)
*------------------------------------------*/
BUILDIN_FUNC(logmes)
{
- const char *str;
- TBL_PC *sd;
+ const char *str;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 1;
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 1;
- str = script_getstr(st,2);
- log_npc(sd,str);
- return 0;
+ str = script_getstr(st,2);
+ log_npc(sd,str);
+ return 0;
}
BUILDIN_FUNC(summon)
{
- int _class, timeout=0;
- const char *str,*event="";
- TBL_PC *sd;
- struct mob_data *md;
- int tick = gettick();
-
- sd=script_rid2sd(st);
- if (!sd) return 0;
-
- str =script_getstr(st,2);
- _class=script_getnum(st,3);
- if (script_hasdata(st,4))
- timeout=script_getnum(st,4);
- if (script_hasdata(st,5)) {
- event=script_getstr(st,5);
- check_event(st, event);
- }
-
- clif_skill_poseffect(&sd->bl,AM_CALLHOMUN,1,sd->bl.x,sd->bl.y,tick);
-
- md = mob_once_spawn_sub(&sd->bl, sd->bl.m, sd->bl.x, sd->bl.y, str, _class, event, SZ_SMALL, AI_NONE);
- if (md) {
- md->master_id=sd->bl.id;
- md->special_state.ai = AI_ATTACK;
- if (md->deletetimer != INVALID_TIMER)
- delete_timer(md->deletetimer, mob_timer_delete);
- md->deletetimer = add_timer(tick+(timeout>0?timeout*1000:60000),mob_timer_delete,md->bl.id,0);
- mob_spawn(md); //Now it is ready for spawning.
- clif_specialeffect(&md->bl,344,AREA);
- sc_start4(&md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE, 0, 60000);
- }
- return 0;
+ int _class, timeout=0;
+ const char *str,*event="";
+ TBL_PC *sd;
+ struct mob_data *md;
+ int tick = gettick();
+
+ sd=script_rid2sd(st);
+ if (!sd) return 0;
+
+ str =script_getstr(st,2);
+ _class=script_getnum(st,3);
+ if( script_hasdata(st,4) )
+ timeout=script_getnum(st,4);
+ if( script_hasdata(st,5) ){
+ event=script_getstr(st,5);
+ check_event(st, event);
+ }
+
+ clif_skill_poseffect(&sd->bl,AM_CALLHOMUN,1,sd->bl.x,sd->bl.y,tick);
+
+ md = mob_once_spawn_sub(&sd->bl, sd->bl.m, sd->bl.x, sd->bl.y, str, _class, event, SZ_SMALL, AI_NONE);
+ if (md) {
+ md->master_id=sd->bl.id;
+ md->special_state.ai = AI_ATTACK;
+ if( md->deletetimer != INVALID_TIMER )
+ delete_timer(md->deletetimer, mob_timer_delete);
+ md->deletetimer = add_timer(tick+(timeout>0?timeout*1000:60000),mob_timer_delete,md->bl.id,0);
+ mob_spawn (md); //Now it is ready for spawning.
+ clif_specialeffect(&md->bl,344,AREA);
+ sc_start4(&md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE, 0, 60000);
+ }
+ return 0;
}
/*==========================================
@@ -13308,14 +13200,14 @@ BUILDIN_FUNC(summon)
*------------------------------------------*/
BUILDIN_FUNC(isnight)
{
- script_pushint(st,(night_flag == 1));
- return 0;
+ script_pushint(st,(night_flag == 1));
+ return 0;
}
BUILDIN_FUNC(isday)
{
- script_pushint(st,(night_flag == 0));
- return 0;
+ script_pushint(st,(night_flag == 0));
+ return 0;
}
/*================================================
@@ -13324,48 +13216,48 @@ BUILDIN_FUNC(isday)
*------------------------------------------------*/
BUILDIN_FUNC(isequippedcnt)
{
- TBL_PC *sd;
- int i, j, k, id = 1;
- int ret = 0;
-
- sd = script_rid2sd(st);
- if (!sd) { //If the player is not attached it is a script error anyway... but better prevent the map server from crashing...
- script_pushint(st,0);
- return 0;
- }
-
- for (i=0; id!=0; i++) {
- FETCH(i+2, id) else id = 0;
- if (id <= 0)
- continue;
-
- for (j=0; j<EQI_MAX; j++) {
- int index;
- index = sd->equip_index[j];
- if (index < 0) continue;
- if (j == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == index) continue;
- if (j == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == index) continue;
- if (j == EQI_HEAD_TOP && (sd->equip_index[EQI_HEAD_MID] == index || sd->equip_index[EQI_HEAD_LOW] == index)) continue;
-
- if (!sd->inventory_data[index])
- continue;
-
- if (itemdb_type(id) != IT_CARD) { //No card. Count amount in inventory.
- if (sd->inventory_data[index]->nameid == id)
- ret+= sd->status.inventory[index].amount;
- } else { //Count cards.
- if (itemdb_isspecial(sd->status.inventory[index].card[0]))
- continue; //No cards
- for (k=0; k<sd->inventory_data[index]->slot; k++) {
- if (sd->status.inventory[index].card[k] == id)
- ret++; //[Lupus]
- }
- }
- }
- }
-
- script_pushint(st,ret);
- return 0;
+ TBL_PC *sd;
+ int i, j, k, id = 1;
+ int ret = 0;
+
+ sd = script_rid2sd(st);
+ if (!sd) { //If the player is not attached it is a script error anyway... but better prevent the map server from crashing...
+ script_pushint(st,0);
+ return 0;
+ }
+
+ for (i=0; id!=0; i++) {
+ FETCH (i+2, id) else id = 0;
+ if (id <= 0)
+ continue;
+
+ for (j=0; j<EQI_MAX; j++) {
+ int index;
+ index = sd->equip_index[j];
+ if(index < 0) continue;
+ if(j == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == index) continue;
+ if(j == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == index) continue;
+ if(j == EQI_HEAD_TOP && (sd->equip_index[EQI_HEAD_MID] == index || sd->equip_index[EQI_HEAD_LOW] == index)) continue;
+
+ if(!sd->inventory_data[index])
+ continue;
+
+ if (itemdb_type(id) != IT_CARD) { //No card. Count amount in inventory.
+ if (sd->inventory_data[index]->nameid == id)
+ ret+= sd->status.inventory[index].amount;
+ } else { //Count cards.
+ if (itemdb_isspecial(sd->status.inventory[index].card[0]))
+ continue; //No cards
+ for(k=0; k<sd->inventory_data[index]->slot; k++) {
+ if (sd->status.inventory[index].card[k] == id)
+ ret++; //[Lupus]
+ }
+ }
+ }
+ }
+
+ script_pushint(st,ret);
+ return 0;
}
/*================================================
@@ -13376,82 +13268,82 @@ BUILDIN_FUNC(isequippedcnt)
*------------------------------------------------*/
BUILDIN_FUNC(isequipped)
{
- TBL_PC *sd;
- int i, j, k, id = 1;
- int index, flag;
- int ret = -1;
- //Original hash to reverse it when full check fails.
- unsigned int setitem_hash = 0, setitem_hash2 = 0;
-
- sd = script_rid2sd(st);
-
- if (!sd) { //If the player is not attached it is a script error anyway... but better prevent the map server from crashing...
- script_pushint(st,0);
- return 0;
- }
-
- setitem_hash = sd->bonus.setitem_hash;
- setitem_hash2 = sd->bonus.setitem_hash2;
- for (i=0; id!=0; i++) {
- FETCH(i+2, id) else id = 0;
- if (id <= 0)
- continue;
- flag = 0;
- for (j=0; j<EQI_MAX; j++) {
- index = sd->equip_index[j];
- if (index < 0) continue;
- if (j == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == index) continue;
- if (j == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == index) continue;
- if (j == EQI_HEAD_TOP && (sd->equip_index[EQI_HEAD_MID] == index || sd->equip_index[EQI_HEAD_LOW] == index)) continue;
-
- if (!sd->inventory_data[index])
- continue;
-
- if (itemdb_type(id) != IT_CARD) {
- if (sd->inventory_data[index]->nameid != id)
- continue;
- flag = 1;
- break;
- } else { //Cards
- if (sd->inventory_data[index]->slot == 0 ||
- itemdb_isspecial(sd->status.inventory[index].card[0]))
- continue;
-
- for (k = 0; k < sd->inventory_data[index]->slot; k++) {
- //New hash system which should support up to 4 slots on any equipment. [Skotlex]
- unsigned int hash = 0;
- if (sd->status.inventory[index].card[k] != id)
- continue;
-
- hash = 1<<((j<5?j:j-5)*4 + k);
- // check if card is already used by another set
- if ((j < 5 ? sd->bonus.setitem_hash : sd->bonus.setitem_hash2) & hash)
- continue;
-
- // We have found a match
- flag = 1;
- // Set hash so this card cannot be used by another
- if (j<5)
- sd->bonus.setitem_hash |= hash;
- else
- sd->bonus.setitem_hash2 |= hash;
- break;
- }
- }
- if (flag) break; //Card found
- }
- if (ret == -1)
- ret = flag;
- else
- ret &= flag;
- if (!ret) break;
- }
- if (!ret) {//When check fails, restore original hash values. [Skotlex]
- sd->bonus.setitem_hash = setitem_hash;
- sd->bonus.setitem_hash2 = setitem_hash2;
- }
- script_pushint(st,ret);
- return 0;
+ TBL_PC *sd;
+ int i, j, k, id = 1;
+ int index, flag;
+ int ret = -1;
+ //Original hash to reverse it when full check fails.
+ unsigned int setitem_hash = 0, setitem_hash2 = 0;
+
+ sd = script_rid2sd(st);
+
+ if (!sd) { //If the player is not attached it is a script error anyway... but better prevent the map server from crashing...
+ script_pushint(st,0);
+ return 0;
+ }
+
+ setitem_hash = sd->bonus.setitem_hash;
+ setitem_hash2 = sd->bonus.setitem_hash2;
+ for (i=0; id!=0; i++) {
+ FETCH (i+2, id) else id = 0;
+ if (id <= 0)
+ continue;
+ flag = 0;
+ for (j=0; j<EQI_MAX; j++) {
+ index = sd->equip_index[j];
+ if(index < 0) continue;
+ if(j == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == index) continue;
+ if(j == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == index) continue;
+ if(j == EQI_HEAD_TOP && (sd->equip_index[EQI_HEAD_MID] == index || sd->equip_index[EQI_HEAD_LOW] == index)) continue;
+
+ if(!sd->inventory_data[index])
+ continue;
+
+ if (itemdb_type(id) != IT_CARD) {
+ if (sd->inventory_data[index]->nameid != id)
+ continue;
+ flag = 1;
+ break;
+ } else { //Cards
+ if (sd->inventory_data[index]->slot == 0 ||
+ itemdb_isspecial(sd->status.inventory[index].card[0]))
+ continue;
+
+ for (k = 0; k < sd->inventory_data[index]->slot; k++)
+ { //New hash system which should support up to 4 slots on any equipment. [Skotlex]
+ unsigned int hash = 0;
+ if (sd->status.inventory[index].card[k] != id)
+ continue;
+
+ hash = 1<<((j<5?j:j-5)*4 + k);
+ // check if card is already used by another set
+ if ( ( j < 5 ? sd->bonus.setitem_hash : sd->bonus.setitem_hash2 ) & hash)
+ continue;
+
+ // We have found a match
+ flag = 1;
+ // Set hash so this card cannot be used by another
+ if (j<5)
+ sd->bonus.setitem_hash |= hash;
+ else
+ sd->bonus.setitem_hash2 |= hash;
+ break;
+ }
+ }
+ if (flag) break; //Card found
+ }
+ if (ret == -1)
+ ret = flag;
+ else
+ ret &= flag;
+ if (!ret) break;
+ }
+ if (!ret) {//When check fails, restore original hash values. [Skotlex]
+ sd->bonus.setitem_hash = setitem_hash;
+ sd->bonus.setitem_hash2 = setitem_hash2;
+ }
+ script_pushint(st,ret);
+ return 0;
}
/*================================================
@@ -13460,39 +13352,39 @@ BUILDIN_FUNC(isequipped)
*------------------------------------------------*/
BUILDIN_FUNC(cardscnt)
{
- TBL_PC *sd;
- int i, k, id = 1;
- int ret = 0;
- int index;
-
- 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;
-
- if (!sd->inventory_data[index])
- continue;
-
- if (itemdb_type(id) != IT_CARD) {
- if (sd->inventory_data[index]->nameid == id)
- ret+= sd->status.inventory[index].amount;
- } else {
- if (itemdb_isspecial(sd->status.inventory[index].card[0]))
- continue;
- for (k=0; k<sd->inventory_data[index]->slot; k++) {
- if (sd->status.inventory[index].card[k] == id)
- ret++;
- }
- }
- }
- script_pushint(st,ret);
- // script_pushint(st,current_equip_item_index);
- return 0;
+ TBL_PC *sd;
+ int i, k, id = 1;
+ int ret = 0;
+ int index;
+
+ 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;
+
+ if(!sd->inventory_data[index])
+ continue;
+
+ if(itemdb_type(id) != IT_CARD) {
+ if (sd->inventory_data[index]->nameid == id)
+ ret+= sd->status.inventory[index].amount;
+ } else {
+ if (itemdb_isspecial(sd->status.inventory[index].card[0]))
+ continue;
+ for(k=0; k<sd->inventory_data[index]->slot; k++) {
+ if (sd->status.inventory[index].card[k] == id)
+ ret++;
+ }
+ }
+ }
+ script_pushint(st,ret);
+// script_pushint(st,current_equip_item_index);
+ return 0;
}
/*=======================================================
@@ -13501,12 +13393,12 @@ BUILDIN_FUNC(cardscnt)
*-------------------------------------------------------*/
BUILDIN_FUNC(getrefine)
{
- TBL_PC *sd;
- if ((sd = script_rid2sd(st))!= NULL)
- script_pushint(st,sd->status.inventory[current_equip_item_index].refine);
- else
- script_pushint(st,0);
- return 0;
+ TBL_PC *sd;
+ if ((sd = script_rid2sd(st))!= NULL)
+ script_pushint(st,sd->status.inventory[current_equip_item_index].refine);
+ else
+ script_pushint(st,0);
+ return 0;
}
/*=======================================================
@@ -13514,13 +13406,13 @@ BUILDIN_FUNC(getrefine)
*-------------------------------------------------------*/
BUILDIN_FUNC(night)
{
- if (night_flag != 1) map_night_timer(night_timer_tid, 0, 0, 1);
- return 0;
+ if (night_flag != 1) map_night_timer(night_timer_tid, 0, 0, 1);
+ return 0;
}
BUILDIN_FUNC(day)
{
- if (night_flag != 0) map_day_timer(day_timer_tid, 0, 0, 1);
- return 0;
+ if (night_flag != 0) map_day_timer(day_timer_tid, 0, 0, 1);
+ return 0;
}
//=======================================================
@@ -13528,82 +13420,86 @@ BUILDIN_FUNC(day)
//-------------------------------------------------------
BUILDIN_FUNC(unequip)
{
- int i;
- size_t num;
- TBL_PC *sd;
+ int i;
+ size_t num;
+ TBL_PC *sd;
- num = script_getnum(st,2);
- sd = script_rid2sd(st);
- if (sd != NULL && num >= 1 && num <= ARRAYLENGTH(equip)) {
- i = pc_checkequip(sd,equip[num-1]);
- if (i >= 0)
- pc_unequipitem(sd,i,1|2);
- }
- return 0;
+ num = script_getnum(st,2);
+ sd = script_rid2sd(st);
+ if( sd != NULL && num >= 1 && num <= ARRAYLENGTH(equip) )
+ {
+ i = pc_checkequip(sd,equip[num-1]);
+ if (i >= 0)
+ pc_unequipitem(sd,i,1|2);
+ }
+ return 0;
}
BUILDIN_FUNC(equip)
{
- int nameid=0,i;
- TBL_PC *sd;
- struct item_data *item_data;
+ int nameid=0,i;
+ TBL_PC *sd;
+ struct item_data *item_data;
- sd = script_rid2sd(st);
+ sd = script_rid2sd(st);
- nameid=script_getnum(st,2);
- if ((item_data = itemdb_exists(nameid)) == NULL) {
- ShowError("wrong item ID : equipitem(%i)\n",nameid);
- return 1;
- }
- ARR_FIND(0, MAX_INVENTORY, i, sd->status.inventory[i].nameid == nameid);
- if (i < MAX_INVENTORY)
- pc_equipitem(sd,i,item_data->equip);
+ nameid=script_getnum(st,2);
+ if((item_data = itemdb_exists(nameid)) == NULL)
+ {
+ ShowError("wrong item ID : equipitem(%i)\n",nameid);
+ return 1;
+ }
+ ARR_FIND( 0, MAX_INVENTORY, i, sd->status.inventory[i].nameid == nameid );
+ if( i < MAX_INVENTORY )
+ pc_equipitem(sd,i,item_data->equip);
- return 0;
+ return 0;
}
BUILDIN_FUNC(autoequip)
{
- int nameid, flag;
- struct item_data *item_data;
- nameid=script_getnum(st,2);
- flag=script_getnum(st,3);
+ int nameid, flag;
+ struct item_data *item_data;
+ nameid=script_getnum(st,2);
+ flag=script_getnum(st,3);
- if ((item_data = itemdb_exists(nameid)) == NULL) {
- ShowError("buildin_autoequip: Invalid item '%d'.\n", nameid);
- return 1;
- }
+ if( ( item_data = itemdb_exists(nameid) ) == NULL )
+ {
+ ShowError("buildin_autoequip: Invalid item '%d'.\n", nameid);
+ return 1;
+ }
- if (!itemdb_isequip2(item_data)) {
- ShowError("buildin_autoequip: Item '%d' cannot be equipped.\n", nameid);
- return 1;
- }
+ if( !itemdb_isequip2(item_data) )
+ {
+ ShowError("buildin_autoequip: Item '%d' cannot be equipped.\n", nameid);
+ return 1;
+ }
- item_data->flag.autoequip = flag>0?1:0;
- return 0;
+ item_data->flag.autoequip = flag>0?1:0;
+ return 0;
}
BUILDIN_FUNC(setbattleflag)
{
- const char *flag, *value;
+ const char *flag, *value;
- flag = script_getstr(st,2);
- value = script_getstr(st,3); // HACK: Retrieve number as string (auto-converted) for battle_set_value
+ flag = script_getstr(st,2);
+ value = script_getstr(st,3); // HACK: Retrieve number as string (auto-converted) for battle_set_value
- if (battle_set_value(flag, value) == 0)
- ShowWarning("buildin_setbattleflag: unknown battle_config flag '%s'\n",flag);
- else
- ShowInfo("buildin_setbattleflag: battle_config flag '%s' is now set to '%s'.\n",flag,value);
+ if (battle_set_value(flag, value) == 0)
+ ShowWarning("buildin_setbattleflag: unknown battle_config flag '%s'\n",flag);
+ else
+ ShowInfo("buildin_setbattleflag: battle_config flag '%s' is now set to '%s'.\n",flag,value);
- return 0;
+ return 0;
}
BUILDIN_FUNC(getbattleflag)
{
- const char *flag;
- flag = script_getstr(st,2);
- script_pushint(st,battle_get_value(flag));
- return 0;
+ const char *flag;
+ flag = script_getstr(st,2);
+ script_pushint(st,battle_get_value(flag));
+ return 0;
}
//=======================================================
@@ -13612,11 +13508,11 @@ BUILDIN_FUNC(getbattleflag)
BUILDIN_FUNC(getstrlen)
{
- const char *str = script_getstr(st,2);
- int len = (str) ? (int)strlen(str) : 0;
+ const char *str = script_getstr(st,2);
+ int len = (str) ? (int)strlen(str) : 0;
- script_pushint(st,len);
- return 0;
+ script_pushint(st,len);
+ return 0;
}
//=======================================================
@@ -13624,13 +13520,13 @@ BUILDIN_FUNC(getstrlen)
//-------------------------------------------------------
BUILDIN_FUNC(charisalpha)
{
- const char *str=script_getstr(st,2);
- int pos=script_getnum(st,3);
+ const char *str=script_getstr(st,2);
+ int pos=script_getnum(st,3);
- int val = (str && pos >= 0 && (unsigned int)pos < strlen(str)) ? ISALPHA(str[pos]) != 0 : 0;
+ int val = ( str && pos >= 0 && (unsigned int)pos < strlen(str) ) ? ISALPHA( str[pos] ) != 0 : 0;
- script_pushint(st,val);
- return 0;
+ script_pushint(st,val);
+ return 0;
}
//=======================================================
@@ -13638,13 +13534,13 @@ BUILDIN_FUNC(charisalpha)
//-------------------------------------------------------
BUILDIN_FUNC(charisupper)
{
- const char *str = script_getstr(st,2);
- int pos = script_getnum(st,3);
+ const char *str = script_getstr(st,2);
+ int pos = script_getnum(st,3);
- int val = (str && pos >= 0 && (unsigned int)pos < strlen(str)) ? ISUPPER(str[pos]) : 0;
+ int val = ( str && pos >= 0 && (unsigned int)pos < strlen(str) ) ? ISUPPER( str[pos] ) : 0;
- script_pushint(st,val);
- return 0;
+ script_pushint(st,val);
+ return 0;
}
//=======================================================
@@ -13652,31 +13548,30 @@ BUILDIN_FUNC(charisupper)
//-------------------------------------------------------
BUILDIN_FUNC(charislower)
{
- const char *str = script_getstr(st,2);
- int pos = script_getnum(st,3);
+ const char *str = script_getstr(st,2);
+ int pos = script_getnum(st,3);
- int val = (str && pos >= 0 && (unsigned int)pos < strlen(str)) ? ISLOWER(str[pos]) : 0;
+ int val = ( str && pos >= 0 && (unsigned int)pos < strlen(str) ) ? ISLOWER( str[pos] ) : 0;
- script_pushint(st,val);
- return 0;
+ script_pushint(st,val);
+ return 0;
}
//=======================================================
// charat <str>, <index>
//-------------------------------------------------------
-BUILDIN_FUNC(charat)
-{
- const char *str = script_getstr(st,2);
- int pos = script_getnum(st,3);
-
- if (pos >= 0 && (unsigned int)pos < strlen(str)) {
- char output[2];
- output[0] = str[pos];
- output[1] = '\0';
- script_pushstrcopy(st, output);
- } else
- script_pushconststr(st, "");
- return 0;
+BUILDIN_FUNC(charat) {
+ const char *str = script_getstr(st,2);
+ int pos = script_getnum(st,3);
+
+ if( pos >= 0 && (unsigned int)pos < strlen(str) ) {
+ char output[2];
+ output[0] = str[pos];
+ output[1] = '\0';
+ script_pushstrcopy(st, output);
+ } else
+ script_pushconststr(st, "");
+ return 0;
}
//=======================================================
@@ -13684,16 +13579,16 @@ BUILDIN_FUNC(charat)
//-------------------------------------------------------
BUILDIN_FUNC(setchar)
{
- const char *str = script_getstr(st,2);
- const char *c = script_getstr(st,3);
- int index = script_getnum(st,4);
- char *output = aStrdup(str);
+ const char *str = script_getstr(st,2);
+ const char *c = script_getstr(st,3);
+ int index = script_getnum(st,4);
+ char *output = aStrdup(str);
- if (index >= 0 && index < strlen(output))
- output[index] = *c;
+ if(index >= 0 && index < strlen(output))
+ output[index] = *c;
- script_pushstr(st, output);
- return 0;
+ script_pushstr(st, output);
+ return 0;
}
//=======================================================
@@ -13701,26 +13596,26 @@ BUILDIN_FUNC(setchar)
//-------------------------------------------------------
BUILDIN_FUNC(insertchar)
{
- const char *str = script_getstr(st,2);
- const char *c = script_getstr(st,3);
- int index = script_getnum(st,4);
- char *output;
- size_t len = strlen(str);
+ const char *str = script_getstr(st,2);
+ const char *c = script_getstr(st,3);
+ int index = script_getnum(st,4);
+ char *output;
+ size_t len = strlen(str);
- if (index < 0)
- index = 0;
- else if (index > len)
- index = len;
+ if(index < 0)
+ index = 0;
+ else if(index > len)
+ index = len;
- output = (char *)aMalloc(len + 2);
+ output = (char*)aMalloc(len + 2);
- memcpy(output, str, index);
- output[index] = c[0];
- memcpy(&output[index+1], &str[index], len - index);
- output[len+1] = '\0';
+ memcpy(output, str, index);
+ output[index] = c[0];
+ memcpy(&output[index+1], &str[index], len - index);
+ output[len+1] = '\0';
- script_pushstr(st, output);
- return 0;
+ script_pushstr(st, output);
+ return 0;
}
//=======================================================
@@ -13728,25 +13623,25 @@ BUILDIN_FUNC(insertchar)
//-------------------------------------------------------
BUILDIN_FUNC(delchar)
{
- const char *str = script_getstr(st,2);
- int index = script_getnum(st,3);
- char *output;
- size_t len = strlen(str);
+ const char *str = script_getstr(st,2);
+ int index = script_getnum(st,3);
+ char *output;
+ size_t len = strlen(str);
- if (index < 0 || index > len) {
- //return original
- output = aStrdup(str);
- script_pushstr(st, output);
- return 0;
- }
+ if(index < 0 || index > len) {
+ //return original
+ output = aStrdup(str);
+ script_pushstr(st, output);
+ return 0;
+ }
- output = (char *)aMalloc(len);
+ output = (char*)aMalloc(len);
- memcpy(output, str, index);
- memcpy(&output[index], &str[index+1], len - index);
+ memcpy(output, str, index);
+ memcpy(&output[index], &str[index+1], len - index);
- script_pushstr(st, output);
- return 0;
+ script_pushstr(st, output);
+ return 0;
}
//=======================================================
@@ -13754,17 +13649,17 @@ BUILDIN_FUNC(delchar)
//-------------------------------------------------------
BUILDIN_FUNC(strtoupper)
{
- const char *str = script_getstr(st,2);
- char *output = aStrdup(str);
- char *cursor = output;
+ const char *str = script_getstr(st,2);
+ char *output = aStrdup(str);
+ char *cursor = output;
- while (*cursor != '\0') {
- *cursor = TOUPPER(*cursor);
- cursor++;
- }
+ while (*cursor != '\0') {
+ *cursor = TOUPPER(*cursor);
+ cursor++;
+ }
- script_pushstr(st, output);
- return 0;
+ script_pushstr(st, output);
+ return 0;
}
//=======================================================
@@ -13772,17 +13667,17 @@ BUILDIN_FUNC(strtoupper)
//-------------------------------------------------------
BUILDIN_FUNC(strtolower)
{
- const char *str = script_getstr(st,2);
- char *output = aStrdup(str);
- char *cursor = output;
+ const char *str = script_getstr(st,2);
+ char *output = aStrdup(str);
+ char *cursor = output;
- while (*cursor != '\0') {
- *cursor = TOLOWER(*cursor);
- cursor++;
- }
+ while (*cursor != '\0') {
+ *cursor = TOLOWER(*cursor);
+ cursor++;
+ }
- script_pushstr(st, output);
- return 0;
+ script_pushstr(st, output);
+ return 0;
}
//=======================================================
@@ -13790,24 +13685,24 @@ BUILDIN_FUNC(strtolower)
//-------------------------------------------------------
BUILDIN_FUNC(substr)
{
- const char *str = script_getstr(st,2);
- char *output;
- int start = script_getnum(st,3);
- int end = script_getnum(st,4);
+ const char *str = script_getstr(st,2);
+ char *output;
+ int start = script_getnum(st,3);
+ int end = script_getnum(st,4);
- int len = 0;
+ int len = 0;
- if (start >= 0 && end < strlen(str) && start <= end) {
- len = end - start + 1;
- output = (char *)aMalloc(len + 1);
- memcpy(output, &str[start], len);
- } else
- output = (char *)aMalloc(1);
+ if(start >= 0 && end < strlen(str) && start <= end) {
+ len = end - start + 1;
+ output = (char*)aMalloc(len + 1);
+ memcpy(output, &str[start], len);
+ } else
+ output = (char*)aMalloc(1);
- output[len] = '\0';
+ output[len] = '\0';
- script_pushstr(st, output);
- return 0;
+ script_pushstr(st, output);
+ return 0;
}
//=======================================================
@@ -13816,69 +13711,73 @@ BUILDIN_FUNC(substr)
//-------------------------------------------------------
BUILDIN_FUNC(explode)
{
- struct script_data *data = script_getdata(st, 2);
- const char *str = script_getstr(st,3);
- const char delimiter = script_getstr(st, 4)[0];
- int32 id;
- size_t len = strlen(str);
- int i = 0, j = 0;
- int start;
-
-
- char *temp;
- const char *name;
-
- TBL_PC *sd = NULL;
-
- temp = (char *)aMalloc(len + 1);
-
- if (!data_isreference(data)) {
- ShowError("script:explode: not a variable\n");
- script_reportdata(data);
- st->state = END;
- return 1;// not a variable
- }
-
- id = reference_getid(data);
- start = reference_getindex(data);
- name = reference_getname(data);
-
- if (not_array_variable(*name)) {
- ShowError("script:explode: illegal scope\n");
- script_reportdata(data);
- st->state = END;
- return 1;// not supported
- }
-
- if (!is_string_variable(name)) {
- ShowError("script:explode: not string array\n");
- script_reportdata(data);
- st->state = END;
- return 1;// data type mismatch
- }
-
- if (not_server_variable(*name)) {
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;// no player attached
- }
-
- while (str[i] != '\0') {
- if (str[i] == delimiter && start < 127) { //break at delimiter but ignore after reaching last array index
- temp[j] = '\0';
- set_reg(st, sd, reference_uid(id, start++), name, (void *)temp, reference_getref(data));
- j = 0;
- ++i;
- } else {
- temp[j++] = str[i++];
- }
- }
- //set last string
- temp[j] = '\0';
- set_reg(st, sd, reference_uid(id, start), name, (void *)temp, reference_getref(data));
-
- aFree(temp);
- return 0;
+ struct script_data* data = script_getdata(st, 2);
+ const char *str = script_getstr(st,3);
+ const char delimiter = script_getstr(st, 4)[0];
+ int32 id;
+ size_t len = strlen(str);
+ int i = 0, j = 0;
+ int start;
+
+
+ char *temp;
+ const char* name;
+
+ TBL_PC* sd = NULL;
+
+ temp = (char*)aMalloc(len + 1);
+
+ if( !data_isreference(data) )
+ {
+ ShowError("script:explode: not a variable\n");
+ script_reportdata(data);
+ st->state = END;
+ return 1;// not a variable
+ }
+
+ id = reference_getid(data);
+ start = reference_getindex(data);
+ name = reference_getname(data);
+
+ if( not_array_variable(*name) )
+ {
+ ShowError("script:explode: illegal scope\n");
+ script_reportdata(data);
+ st->state = END;
+ return 1;// not supported
+ }
+
+ if( !is_string_variable(name) )
+ {
+ ShowError("script:explode: not string array\n");
+ script_reportdata(data);
+ st->state = END;
+ return 1;// data type mismatch
+ }
+
+ if( not_server_variable(*name) )
+ {
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;// no player attached
+ }
+
+ while(str[i] != '\0') {
+ if(str[i] == delimiter && start < 127) { //break at delimiter but ignore after reaching last array index
+ temp[j] = '\0';
+ set_reg(st, sd, reference_uid(id, start++), name, (void*)temp, reference_getref(data));
+ j = 0;
+ ++i;
+ } else {
+ temp[j++] = str[i++];
+ }
+ }
+ //set last string
+ temp[j] = '\0';
+ set_reg(st, sd, reference_uid(id, start), name, (void*)temp, reference_getref(data));
+
+ aFree(temp);
+ return 0;
}
//=======================================================
@@ -13887,91 +13786,96 @@ BUILDIN_FUNC(explode)
//-------------------------------------------------------
BUILDIN_FUNC(implode)
{
- struct script_data *data = script_getdata(st, 2);
- const char *glue = NULL, *name, *temp;
- int32 glue_len = 0, array_size, id;
- size_t len = 0;
- int i, k = 0;
-
- TBL_PC *sd = NULL;
-
- char *output;
-
- if (!data_isreference(data)) {
- ShowError("script:implode: not a variable\n");
- script_reportdata(data);
- st->state = END;
- return 1;// not a variable
- }
-
- id = reference_getid(data);
- name = reference_getname(data);
-
- if (not_array_variable(*name)) {
- ShowError("script:implode: illegal scope\n");
- script_reportdata(data);
- st->state = END;
- return 1;// not supported
- }
-
- if (!is_string_variable(name)) {
- ShowError("script:implode: not string array\n");
- script_reportdata(data);
- st->state = END;
- return 1;// data type mismatch
- }
-
- if (not_server_variable(*name)) {
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;// no player attached
- }
-
- //count chars
- array_size = getarraysize(st, id, reference_getindex(data), is_string_variable(name), reference_getref(data)) - 1;
-
- if (array_size == -1) { //empty array check (AmsTaff)
+ struct script_data* data = script_getdata(st, 2);
+ const char *glue = NULL, *name, *temp;
+ int32 glue_len = 0, array_size, id;
+ size_t len = 0;
+ int i, k = 0;
+
+ TBL_PC* sd = NULL;
+
+ char *output;
+
+ if( !data_isreference(data) )
+ {
+ ShowError("script:implode: not a variable\n");
+ script_reportdata(data);
+ st->state = END;
+ return 1;// not a variable
+ }
+
+ id = reference_getid(data);
+ name = reference_getname(data);
+
+ if( not_array_variable(*name) )
+ {
+ ShowError("script:implode: illegal scope\n");
+ script_reportdata(data);
+ st->state = END;
+ return 1;// not supported
+ }
+
+ if( !is_string_variable(name) )
+ {
+ ShowError("script:implode: not string array\n");
+ script_reportdata(data);
+ st->state = END;
+ return 1;// data type mismatch
+ }
+
+ if( not_server_variable(*name) )
+ {
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;// no player attached
+ }
+
+ //count chars
+ array_size = getarraysize(st, id, reference_getindex(data), is_string_variable(name), reference_getref(data)) - 1;
+
+ if(array_size == -1) //empty array check (AmsTaff)
+ {
ShowWarning("script:implode: array length = 0\n");
- output = (char *)aMalloc(sizeof(char)*5);
+ output = (char*)aMalloc(sizeof(char)*5);
sprintf(output,"%s","NULL");
- } else {
- for (i = 0; i <= array_size; ++i) {
- temp = (char *) get_val2(st, reference_uid(id, i), reference_getref(data));
- len += strlen(temp);
- script_removetop(st, -1, 0);
- }
-
- //allocate mem
- if (script_hasdata(st,3)) {
- glue = script_getstr(st,3);
- glue_len = strlen(glue);
- len += glue_len * (array_size);
- }
- output = (char *)aMalloc(len + 1);
-
- //build output
- for (i = 0; i < array_size; ++i) {
- temp = (char *) get_val2(st, reference_uid(id, i), reference_getref(data));
- len = strlen(temp);
- memcpy(&output[k], temp, len);
- k += len;
- if (glue_len != 0) {
- memcpy(&output[k], glue, glue_len);
- k += glue_len;
- }
- script_removetop(st, -1, 0);
- }
- temp = (char *) get_val2(st, reference_uid(id, array_size), reference_getref(data));
- len = strlen(temp);
- memcpy(&output[k], temp, len);
- k += len;
- script_removetop(st, -1, 0);
-
- output[k] = '\0';
- }
-
- script_pushstr(st, output);
- return 0;
+ } else {
+ for(i = 0; i <= array_size; ++i) {
+ temp = (char*) get_val2(st, reference_uid(id, i), reference_getref(data));
+ len += strlen(temp);
+ script_removetop(st, -1, 0);
+ }
+
+ //allocate mem
+ if( script_hasdata(st,3) ) {
+ glue = script_getstr(st,3);
+ glue_len = strlen(glue);
+ len += glue_len * (array_size);
+ }
+ output = (char*)aMalloc(len + 1);
+
+ //build output
+ for(i = 0; i < array_size; ++i) {
+ temp = (char*) get_val2(st, reference_uid(id, i), reference_getref(data));
+ len = strlen(temp);
+ memcpy(&output[k], temp, len);
+ k += len;
+ if(glue_len != 0) {
+ memcpy(&output[k], glue, glue_len);
+ k += glue_len;
+ }
+ script_removetop(st, -1, 0);
+ }
+ temp = (char*) get_val2(st, reference_uid(id, array_size), reference_getref(data));
+ len = strlen(temp);
+ memcpy(&output[k], temp, len);
+ k += len;
+ script_removetop(st, -1, 0);
+
+ output[k] = '\0';
+ }
+
+ script_pushstr(st, output);
+ return 0;
}
//=======================================================
@@ -13982,12 +13886,12 @@ BUILDIN_FUNC(implode)
BUILDIN_FUNC(sprintf)
{
unsigned int len, argc = 0, arg = 0, buf2_len = 0;
- const char *format;
- char *p;
- char *q;
- char *buf = NULL;
- char *buf2 = NULL;
- struct script_data *data;
+ const char* format;
+ char* p;
+ char* q;
+ char* buf = NULL;
+ char* buf2 = NULL;
+ struct script_data* data;
StringBuf final_buf;
// Fetch init data
@@ -13996,7 +13900,7 @@ BUILDIN_FUNC(sprintf)
len = strlen(format);
// Skip parsing, where no parsing is required.
- if (len==0) {
+ if(len==0){
script_pushconststr(st,"");
return 0;
}
@@ -14005,8 +13909,8 @@ BUILDIN_FUNC(sprintf)
CREATE(buf, char, len+1);
// Need not be parsed, just solve stuff like %%.
- if (argc==0) {
- memcpy(buf,format,len+1);
+ if(argc==0){
+ memcpy(buf,format,len+1);
script_pushstrcopy(st, buf);
aFree(buf);
return 0;
@@ -14017,10 +13921,10 @@ BUILDIN_FUNC(sprintf)
// Issue sprintf for each parameter
StringBuf_Init(&final_buf);
q = buf;
- while ((p = strchr(q, '%'))!=NULL) {
- if (p!=q) {
+ while((p = strchr(q, '%'))!=NULL){
+ if(p!=q){
len = p-q+1;
- if (buf2_len<len) {
+ if(buf2_len<len){
RECREATE(buf2, char, len);
buf2_len = len;
}
@@ -14029,30 +13933,30 @@ BUILDIN_FUNC(sprintf)
q = p;
}
p = q+1;
- if (*p=='%') { // %%
+ if(*p=='%'){ // %%
StringBuf_AppendStr(&final_buf, "%");
q+=2;
continue;
}
- if (*p=='n') { // %n
+ if(*p=='n'){ // %n
ShowWarning("buildin_sprintf: Format %%n not supported! Skipping...\n");
script_reportsrc(st);
q+=2;
continue;
}
- if (arg>=argc) {
+ if(arg>=argc){
ShowError("buildin_sprintf: Not enough arguments passed!\n");
- if (buf) aFree(buf);
- if (buf2) aFree(buf2);
+ if(buf) aFree(buf);
+ if(buf2) aFree(buf2);
StringBuf_Destroy(&final_buf);
script_pushconststr(st,"");
return 1;
}
- if ((p = strchr(q+1, '%'))==NULL) {
+ if((p = strchr(q+1, '%'))==NULL){
p = strchr(q, 0); // EOS
}
len = p-q+1;
- if (buf2_len<len) {
+ if(buf2_len<len){
RECREATE(buf2, char, len);
buf2_len = len;
}
@@ -14065,21 +13969,21 @@ BUILDIN_FUNC(sprintf)
// but it would behave in normal code the same way so it's
// the scripter's responsibility.
data = script_getdata(st, arg+3);
- if (data_isstring(data)) { // String
+ if(data_isstring(data)){ // String
StringBuf_Printf(&final_buf, buf2, script_getstr(st, arg+3));
- } else if (data_isint(data)) { // Number
+ }else if(data_isint(data)){ // Number
StringBuf_Printf(&final_buf, buf2, script_getnum(st, arg+3));
- } else if (data_isreference(data)) { // Variable
- char *name = reference_getname(data);
- if (name[strlen(name)-1]=='$') { // var Str
+ }else if(data_isreference(data)){ // Variable
+ char* name = reference_getname(data);
+ if(name[strlen(name)-1]=='$'){ // var Str
StringBuf_Printf(&final_buf, buf2, script_getstr(st, arg+3));
- } else { // var Int
+ }else{ // var Int
StringBuf_Printf(&final_buf, buf2, script_getnum(st, arg+3));
}
- } else { // Unsupported type
+ }else{ // Unsupported type
ShowError("buildin_sprintf: Unknown argument type!\n");
- if (buf) aFree(buf);
- if (buf2) aFree(buf2);
+ if(buf) aFree(buf);
+ if(buf2) aFree(buf2);
StringBuf_Destroy(&final_buf);
script_pushconststr(st,"");
return 1;
@@ -14088,20 +13992,20 @@ BUILDIN_FUNC(sprintf)
}
// Append anything left
- if (*q) {
+ if(*q){
StringBuf_AppendStr(&final_buf, q);
}
// Passed more, than needed
- if (arg<argc) {
+ if(arg<argc){
ShowWarning("buildin_sprintf: Unused arguments passed.\n");
script_reportsrc(st);
}
script_pushstrcopy(st, StringBuf_Value(&final_buf));
- if (buf) aFree(buf);
- if (buf2) aFree(buf2);
+ if(buf) aFree(buf);
+ if(buf2) aFree(buf2);
StringBuf_Destroy(&final_buf);
return 0;
@@ -14111,18 +14015,17 @@ BUILDIN_FUNC(sprintf)
// sscanf(<str>, <format>, ...);
// Implements C sscanf.
//-------------------------------------------------------
-BUILDIN_FUNC(sscanf)
-{
+BUILDIN_FUNC(sscanf){
unsigned int argc, arg = 0, len;
- struct script_data *data;
- struct map_session_data *sd = NULL;
- const char *str;
- const char *format;
- const char *p;
- const char *q;
- char *buf = NULL;
- char *buf_p;
- char *ref_str = NULL;
+ struct script_data* data;
+ struct map_session_data* sd = NULL;
+ const char* str;
+ const char* format;
+ const char* p;
+ const char* q;
+ char* buf = NULL;
+ char* buf_p;
+ char* ref_str = NULL;
int ref_int;
// Get data
@@ -14136,25 +14039,25 @@ BUILDIN_FUNC(sscanf)
// Issue sscanf for each parameter
*buf = 0;
q = format;
- while ((p = strchr(q, '%'))) {
- if (p!=q) {
+ while((p = strchr(q, '%'))){
+ if(p!=q){
strncat(buf, q, (size_t)(p-q));
q = p;
}
p = q+1;
- if (*p=='*' || *p=='%') { // Skip
+ if(*p=='*' || *p=='%'){ // Skip
strncat(buf, q, 2);
q+=2;
continue;
}
- if (arg>=argc) {
+ if(arg>=argc){
ShowError("buildin_sscanf: Not enough arguments passed!\n");
script_pushint(st, -1);
- if (buf) aFree(buf);
- if (ref_str) aFree(ref_str);
+ if(buf) aFree(buf);
+ if(ref_str) aFree(ref_str);
return 1;
}
- if ((p = strchr(q+1, '%'))==NULL) {
+ if((p = strchr(q+1, '%'))==NULL){
p = strchr(q, 0); // EOS
}
len = p-q;
@@ -14163,32 +14066,32 @@ BUILDIN_FUNC(sscanf)
// Validate output
data = script_getdata(st, arg+4);
- if (!data_isreference(data) || !reference_tovariable(data)) {
+ if(!data_isreference(data) || !reference_tovariable(data)){
ShowError("buildin_sscanf: Target argument is not a variable!\n");
script_pushint(st, -1);
- if (buf) aFree(buf);
- if (ref_str) aFree(ref_str);
+ if(buf) aFree(buf);
+ if(ref_str) aFree(ref_str);
return 1;
}
buf_p = reference_getname(data);
- if (not_server_variable(*buf_p) && (sd = script_rid2sd(st))==NULL) {
+ if(not_server_variable(*buf_p) && (sd = script_rid2sd(st))==NULL){
script_pushint(st, -1);
- if (buf) aFree(buf);
- if (ref_str) aFree(ref_str);
+ if(buf) aFree(buf);
+ if(ref_str) aFree(ref_str);
return 0;
}
// Save value if any
- if (buf_p[strlen(buf_p)-1]=='$') { // String
- if (ref_str==NULL) {
+ if(buf_p[strlen(buf_p)-1]=='$'){ // String
+ if(ref_str==NULL){
CREATE(ref_str, char, strlen(str)+1);
}
- if (sscanf(str, buf, ref_str)==0) {
+ if(sscanf(str, buf, ref_str)==0){
break;
}
set_reg(st, sd, add_str(buf_p), buf_p, (void *)(ref_str), reference_getref(data));
- } else { // Number
- if (sscanf(str, buf, &ref_int)==0) {
+ }else{ // Number
+ if(sscanf(str, buf, &ref_int)==0){
break;
}
set_reg(st, sd, add_str(buf_p), buf_p, (void *)__64BPRTSIZE(ref_int), reference_getref(data));
@@ -14202,14 +14105,14 @@ BUILDIN_FUNC(sscanf)
}
// Passed more, than needed
- if (arg<argc) {
+ if(arg<argc){
ShowWarning("buildin_sscanf: Unused arguments passed.\n");
script_reportsrc(st);
}
script_pushint(st, arg);
- if (buf) aFree(buf);
- if (ref_str) aFree(ref_str);
+ if(buf) aFree(buf);
+ if(ref_str) aFree(ref_str);
return 0;
}
@@ -14221,41 +14124,40 @@ BUILDIN_FUNC(sscanf)
// Implements PHP style strpos. Adapted from code from
// http://www.daniweb.com/code/snippet313.html, Dave Sinkula
//-------------------------------------------------------
-BUILDIN_FUNC(strpos)
-{
- const char *haystack = script_getstr(st,2);
- const char *needle = script_getstr(st,3);
- int i;
- size_t len;
-
- if (script_hasdata(st,4))
- i = script_getnum(st,4);
- else
- i = 0;
-
- if (needle[0] == '\0') {
- script_pushint(st, -1);
- return 0;
- }
-
- len = strlen(haystack);
- for (; i < len; ++i) {
- if (haystack[i] == *needle) {
- // matched starting char -- loop through remaining chars
- const char *h, *n;
- for (h = &haystack[i], n = needle; *h && *n; ++h, ++n) {
- if (*h != *n) {
- break;
- }
- }
- if (!*n) { // matched all of 'needle' to null termination
- script_pushint(st, i);
- return 0;
- }
- }
- }
- script_pushint(st, -1);
- return 0;
+BUILDIN_FUNC(strpos) {
+ const char *haystack = script_getstr(st,2);
+ const char *needle = script_getstr(st,3);
+ int i;
+ size_t len;
+
+ if( script_hasdata(st,4) )
+ i = script_getnum(st,4);
+ else
+ i = 0;
+
+ if ( strlen(needle) == 0 ) {
+ script_pushint(st, -1);
+ return 0;
+ }
+
+ len = strlen(haystack);
+ for ( ; i < len; ++i ) {
+ if ( haystack[i] == *needle ) {
+ // matched starting char -- loop through remaining chars
+ const char *h, *n;
+ for ( h = &haystack[i], n = needle; *h && *n; ++h, ++n ) {
+ if ( *h != *n ) {
+ break;
+ }
+ }
+ if ( !*n ) { // matched all of 'needle' to null termination
+ script_pushint(st, i);
+ return 0;
+ }
+ }
+ }
+ script_pushint(st, -1);
+ return 0;
}
//===============================================================
@@ -14268,80 +14170,80 @@ BUILDIN_FUNC(strpos)
//---------------------------------------------------------------
BUILDIN_FUNC(replacestr)
{
- const char *input = script_getstr(st, 2);
- const char *find = script_getstr(st, 3);
- const char *replace = script_getstr(st, 4);
- size_t inputlen = strlen(input);
- size_t findlen = strlen(find);
- struct StringBuf output;
- bool usecase = true;
-
- int count = 0;
- int numFinds = 0;
- int i = 0, f = 0;
-
- if (findlen == 0) {
- ShowError("script:replacestr: Invalid search length.\n");
- st->state = END;
- return 1;
- }
-
- if (script_hasdata(st, 5)) {
- if (!script_isstring(st,5))
- usecase = script_getnum(st, 5) != 0;
- else {
- ShowError("script:replacestr: Invalid usecase value. Expected int got string\n");
- st->state = END;
- return 1;
- }
- }
-
- if (script_hasdata(st, 6)) {
- count = script_getnum(st, 6);
- if (count == 0) {
- ShowError("script:replacestr: Invalid count value. Expected int got string\n");
- st->state = END;
- return 1;
- }
- }
-
- StringBuf_Init(&output);
-
- for (; i < inputlen; i++) {
- if (count && count == numFinds) { //found enough, stop looking
- break;
- }
-
- for (f = 0; f <= findlen; f++) {
- if (f == findlen) { //complete match
- numFinds++;
- StringBuf_AppendStr(&output, replace);
-
- i += findlen - 1;
- break;
- } else {
- if (usecase) {
- if ((i + f) > inputlen || input[i + f] != find[f]) {
- StringBuf_Printf(&output, "%c", input[i]);
- break;
- }
- } else {
- if (((i + f) > inputlen || input[i + f] != find[f]) && TOUPPER(input[i+f]) != TOUPPER(find[f])) {
- StringBuf_Printf(&output, "%c", input[i]);
- break;
- }
- }
- }
- }
- }
-
- //append excess after enough found
- if (i < inputlen)
- StringBuf_AppendStr(&output, &(input[i]));
-
- script_pushstrcopy(st, StringBuf_Value(&output));
- StringBuf_Destroy(&output);
- return 0;
+ const char *input = script_getstr(st, 2);
+ const char *find = script_getstr(st, 3);
+ const char *replace = script_getstr(st, 4);
+ size_t inputlen = strlen(input);
+ size_t findlen = strlen(find);
+ struct StringBuf output;
+ bool usecase = true;
+
+ int count = 0;
+ int numFinds = 0;
+ int i = 0, f = 0;
+
+ if(findlen == 0) {
+ ShowError("script:replacestr: Invalid search length.\n");
+ st->state = END;
+ return 1;
+ }
+
+ if(script_hasdata(st, 5)) {
+ if( !script_isstring(st,5) )
+ usecase = script_getnum(st, 5) != 0;
+ else {
+ ShowError("script:replacestr: Invalid usecase value. Expected int got string\n");
+ st->state = END;
+ return 1;
+ }
+ }
+
+ if(script_hasdata(st, 6)) {
+ count = script_getnum(st, 6);
+ if(count == 0) {
+ ShowError("script:replacestr: Invalid count value. Expected int got string\n");
+ st->state = END;
+ return 1;
+ }
+ }
+
+ StringBuf_Init(&output);
+
+ for(; i < inputlen; i++) {
+ if(count && count == numFinds) { //found enough, stop looking
+ break;
+ }
+
+ for(f = 0; f <= findlen; f++) {
+ if(f == findlen) { //complete match
+ numFinds++;
+ StringBuf_AppendStr(&output, replace);
+
+ i += findlen - 1;
+ break;
+ } else {
+ if(usecase) {
+ if((i + f) > inputlen || input[i + f] != find[f]) {
+ StringBuf_Printf(&output, "%c", input[i]);
+ break;
+ }
+ } else {
+ if(((i + f) > inputlen || input[i + f] != find[f]) && TOUPPER(input[i+f]) != TOUPPER(find[f])) {
+ StringBuf_Printf(&output, "%c", input[i]);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ //append excess after enough found
+ if(i < inputlen)
+ StringBuf_AppendStr(&output, &(input[i]));
+
+ script_pushstrcopy(st, StringBuf_Value(&output));
+ StringBuf_Destroy(&output);
+ return 0;
}
//========================================================
@@ -14352,52 +14254,52 @@ BUILDIN_FUNC(replacestr)
//--------------------------------------------------------
BUILDIN_FUNC(countstr)
{
- const char *input = script_getstr(st, 2);
- const char *find = script_getstr(st, 3);
- size_t inputlen = strlen(input);
- size_t findlen = strlen(find);
- bool usecase = true;
-
- int numFinds = 0;
- int i = 0, f = 0;
-
- if (findlen == 0) {
- ShowError("script:countstr: Invalid search length.\n");
- st->state = END;
- return 1;
- }
-
- if (script_hasdata(st, 4)) {
- if (!script_isstring(st,4))
- usecase = script_getnum(st, 4) != 0;
- else {
- ShowError("script:countstr: Invalid usecase value. Expected int got string\n");
- st->state = END;
- return 1;
- }
- }
-
- for (; i < inputlen; i++) {
- for (f = 0; f <= findlen; f++) {
- if (f == findlen) { //complete match
- numFinds++;
- i += findlen - 1;
- break;
- } else {
- if (usecase) {
- if ((i + f) > inputlen || input[i + f] != find[f]) {
- break;
- }
- } else {
- if (((i + f) > inputlen || input[i + f] != find[f]) && TOUPPER(input[i+f]) != TOUPPER(find[f])) {
- break;
- }
- }
- }
- }
- }
- script_pushint(st, numFinds);
- return 0;
+ const char *input = script_getstr(st, 2);
+ const char *find = script_getstr(st, 3);
+ size_t inputlen = strlen(input);
+ size_t findlen = strlen(find);
+ bool usecase = true;
+
+ int numFinds = 0;
+ int i = 0, f = 0;
+
+ if(findlen == 0) {
+ ShowError("script:countstr: Invalid search length.\n");
+ st->state = END;
+ return 1;
+ }
+
+ if(script_hasdata(st, 4)) {
+ if( !script_isstring(st,4) )
+ usecase = script_getnum(st, 4) != 0;
+ else {
+ ShowError("script:countstr: Invalid usecase value. Expected int got string\n");
+ st->state = END;
+ return 1;
+ }
+ }
+
+ for(; i < inputlen; i++) {
+ for(f = 0; f <= findlen; f++) {
+ if(f == findlen) { //complete match
+ numFinds++;
+ i += findlen - 1;
+ break;
+ } else {
+ if(usecase) {
+ if((i + f) > inputlen || input[i + f] != find[f]) {
+ break;
+ }
+ } else {
+ if(((i + f) > inputlen || input[i + f] != find[f]) && TOUPPER(input[i+f]) != TOUPPER(find[f])) {
+ break;
+ }
+ }
+ }
+ }
+ }
+ script_pushint(st, numFinds);
+ return 0;
}
@@ -14410,915 +14312,853 @@ BUILDIN_FUNC(countstr)
/// setnpcdisplay("<npc name>", <new class id>) -> <int>
BUILDIN_FUNC(setnpcdisplay)
{
- const char *name;
- const char *newname = NULL;
- int class_ = -1, size = -1;
- struct script_data *data;
- struct npc_data *nd;
-
- name = script_getstr(st,2);
- data = script_getdata(st,3);
-
- if (script_hasdata(st,4))
- class_ = script_getnum(st,4);
- if (script_hasdata(st,5))
- size = script_getnum(st,5);
-
- get_val(st, data);
- if (data_isstring(data))
- newname = conv_str(st,data);
- else if (data_isint(data))
- class_ = conv_num(st,data);
- else {
- ShowError("script:setnpcdisplay: expected a string or number\n");
- script_reportdata(data);
- return 1;
- }
-
- nd = npc_name2id(name);
- if (nd == NULL) {
- // not found
- script_pushint(st,1);
- return 0;
- }
-
- // update npc
- if (newname)
- npc_setdisplayname(nd, newname);
-
- if (size != -1 && size != (int)nd->size)
- nd->size = size;
- else
- size = -1;
-
- if (class_ != -1 && nd->class_ != class_)
- npc_setclass(nd, class_);
- else if (size != -1) {
- // Required to update the visual size
- clif_clearunit_area(&nd->bl, CLR_OUTSIGHT);
- clif_spawn(&nd->bl);
- }
-
- script_pushint(st,0);
- return 0;
+ const char* name;
+ const char* newname = NULL;
+ int class_ = -1, size = -1;
+ struct script_data* data;
+ struct npc_data* nd;
+
+ name = script_getstr(st,2);
+ data = script_getdata(st,3);
+
+ if( script_hasdata(st,4) )
+ class_ = script_getnum(st,4);
+ if( script_hasdata(st,5) )
+ size = script_getnum(st,5);
+
+ get_val(st, data);
+ if( data_isstring(data) )
+ newname = conv_str(st,data);
+ else if( data_isint(data) )
+ class_ = conv_num(st,data);
+ else
+ {
+ ShowError("script:setnpcdisplay: expected a string or number\n");
+ script_reportdata(data);
+ return 1;
+ }
+
+ nd = npc_name2id(name);
+ if( nd == NULL )
+ {// not found
+ script_pushint(st,1);
+ return 0;
+ }
+
+ // update npc
+ if( newname )
+ npc_setdisplayname(nd, newname);
+
+ if( size != -1 && size != (int)nd->size )
+ nd->size = size;
+ else
+ size = -1;
+
+ if( class_ != -1 && nd->class_ != class_ )
+ npc_setclass(nd, class_);
+ else if( size != -1 )
+ { // Required to update the visual size
+ clif_clearunit_area(&nd->bl, CLR_OUTSIGHT);
+ clif_spawn(&nd->bl);
+ }
+
+ script_pushint(st,0);
+ return 0;
}
BUILDIN_FUNC(atoi)
{
- const char *value;
- value = script_getstr(st,2);
- script_pushint(st,atoi(value));
- return 0;
+ const char *value;
+ value = script_getstr(st,2);
+ script_pushint(st,atoi(value));
+ return 0;
}
// case-insensitive substring search [lordalfa]
BUILDIN_FUNC(compare)
{
- const char *message;
- const char *cmpstring;
- message = script_getstr(st,2);
- cmpstring = script_getstr(st,3);
- script_pushint(st,(stristr(message,cmpstring) != NULL));
- return 0;
+ const char *message;
+ const char *cmpstring;
+ message = script_getstr(st,2);
+ cmpstring = script_getstr(st,3);
+ script_pushint(st,(stristr(message,cmpstring) != NULL));
+ return 0;
}
// [zBuffer] List of mathematics commands --->
BUILDIN_FUNC(sqrt)
{
- double i, a;
- i = script_getnum(st,2);
- a = sqrt(i);
- script_pushint(st,(int)a);
- return 0;
+ double i, a;
+ i = script_getnum(st,2);
+ a = sqrt(i);
+ script_pushint(st,(int)a);
+ return 0;
}
BUILDIN_FUNC(pow)
{
- double i, a, b;
- a = script_getnum(st,2);
- b = script_getnum(st,3);
- i = pow(a,b);
- script_pushint(st,(int)i);
- return 0;
+ double i, a, b;
+ a = script_getnum(st,2);
+ b = script_getnum(st,3);
+ i = pow(a,b);
+ script_pushint(st,(int)i);
+ return 0;
}
BUILDIN_FUNC(distance)
{
- int x0, y0, x1, y1;
+ int x0, y0, x1, y1;
- x0 = script_getnum(st,2);
- y0 = script_getnum(st,3);
- x1 = script_getnum(st,4);
- y1 = script_getnum(st,5);
+ x0 = script_getnum(st,2);
+ y0 = script_getnum(st,3);
+ x1 = script_getnum(st,4);
+ y1 = script_getnum(st,5);
- script_pushint(st,distance_xy(x0,y0,x1,y1));
- return 0;
+ script_pushint(st,distance_xy(x0,y0,x1,y1));
+ return 0;
}
// <--- [zBuffer] List of mathematics commands
BUILDIN_FUNC(md5)
{
- const char *tmpstr;
- char *md5str;
+ const char *tmpstr;
+ char *md5str;
- tmpstr = script_getstr(st,2);
- md5str = (char *)aMalloc((32+1)*sizeof(char));
- MD5_String(tmpstr, md5str);
- script_pushstr(st, md5str);
- return 0;
+ tmpstr = script_getstr(st,2);
+ md5str = (char *)aMalloc((32+1)*sizeof(char));
+ MD5_String(tmpstr, md5str);
+ script_pushstr(st, md5str);
+ return 0;
}
// [zBuffer] List of dynamic var commands --->
BUILDIN_FUNC(setd)
{
- TBL_PC *sd=NULL;
- char varname[100];
- const char *buffer;
- int elem;
- buffer = script_getstr(st, 2);
-
- if (sscanf(buffer, "%99[^[][%d]", varname, &elem) < 2)
- elem = 0;
-
- if (not_server_variable(*varname)) {
- sd = script_rid2sd(st);
- if (sd == NULL) {
- ShowError("script:setd: no player attached for player variable '%s'\n", buffer);
- return 0;
- }
- }
-
- if (is_string_variable(varname)) {
- setd_sub(st, sd, varname, elem, (void *)script_getstr(st, 3), NULL);
- } else {
- setd_sub(st, sd, varname, elem, (void *)__64BPRTSIZE(script_getnum(st, 3)), NULL);
- }
-
- return 0;
-}
-
-int buildin_query_sql_sub(struct script_state *st, Sql *handle)
-{
- int i, j;
- TBL_PC *sd = NULL;
- const char *query;
- struct script_data *data;
- const char *name;
- int max_rows = SCRIPT_MAX_ARRAYSIZE; // maximum number of rows
- int num_vars;
- int num_cols;
-
- // check target variables
- for (i = 3; script_hasdata(st,i); ++i) {
- data = script_getdata(st, i);
- if (data_isreference(data)) { // it's a variable
- name = reference_getname(data);
- if (not_server_variable(*name) && sd == NULL) { // requires a player
- sd = script_rid2sd(st);
- if (sd == NULL) { // no player attached
- script_reportdata(data);
- st->state = END;
- return 1;
- }
- }
- if (not_array_variable(*name))
- max_rows = 1;// not an array, limit to one row
- } else {
- ShowError("script:query_sql: not a variable\n");
- script_reportdata(data);
- st->state = END;
- return 1;
- }
- }
- num_vars = i - 3;
-
- // Execute the query
- query = script_getstr(st,2);
-
- if (SQL_ERROR == Sql_QueryStr(handle, query)) {
- Sql_ShowDebug(handle);
- script_pushint(st, 0);
- return 1;
- }
-
- if (Sql_NumRows(handle) == 0) { // No data received
- Sql_FreeResult(handle);
- script_pushint(st, 0);
- return 0;
- }
-
- // Count the number of columns to store
- num_cols = Sql_NumColumns(handle);
- if (num_vars < num_cols) {
- ShowWarning("script:query_sql: Too many columns, discarding last %u columns.\n", (unsigned int)(num_cols-num_vars));
- script_reportsrc(st);
- } else if (num_vars > num_cols) {
- ShowWarning("script:query_sql: Too many variables (%u extra).\n", (unsigned int)(num_vars-num_cols));
- script_reportsrc(st);
- }
-
- // Store data
- for (i = 0; i < max_rows && SQL_SUCCESS == Sql_NextRow(handle); ++i) {
- for (j = 0; j < num_vars; ++j) {
- char *str = NULL;
-
- if (j < num_cols)
- Sql_GetData(handle, j, &str, NULL);
-
- data = script_getdata(st, j+3);
- name = reference_getname(data);
- if (is_string_variable(name))
- setd_sub(st, sd, name, i, (void *)(str?str:""), reference_getref(data));
- else
- setd_sub(st, sd, name, i, (void *)__64BPRTSIZE((str?atoi(str):0)), reference_getref(data));
- }
- }
- if (i == max_rows && max_rows < Sql_NumRows(handle)) {
- ShowWarning("script:query_sql: Only %d/%u rows have been stored.\n", max_rows, (unsigned int)Sql_NumRows(handle));
- script_reportsrc(st);
- }
-
- // Free data
- Sql_FreeResult(handle);
- script_pushint(st, i);
-
- return 0;
-}
-
-BUILDIN_FUNC(query_sql)
-{
+ TBL_PC *sd=NULL;
+ char varname[100];
+ const char *buffer;
+ int elem;
+ buffer = script_getstr(st, 2);
+
+ if(sscanf(buffer, "%99[^[][%d]", varname, &elem) < 2)
+ elem = 0;
+
+ if( not_server_variable(*varname) )
+ {
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ {
+ ShowError("script:setd: no player attached for player variable '%s'\n", buffer);
+ return 0;
+ }
+ }
+
+ if( is_string_variable(varname) ) {
+ setd_sub(st, sd, varname, elem, (void *)script_getstr(st, 3), NULL);
+ } else {
+ setd_sub(st, sd, varname, elem, (void *)__64BPRTSIZE(script_getnum(st, 3)), NULL);
+ }
+
+ return 0;
+}
+
+int buildin_query_sql_sub(struct script_state* st, Sql* handle)
+{
+ int i, j;
+ TBL_PC* sd = NULL;
+ const char* query;
+ struct script_data* data;
+ const char* name;
+ int max_rows = SCRIPT_MAX_ARRAYSIZE; // maximum number of rows
+ int num_vars;
+ int num_cols;
+
+ // check target variables
+ for( i = 3; script_hasdata(st,i); ++i ) {
+ data = script_getdata(st, i);
+ if( data_isreference(data) ) { // it's a variable
+ name = reference_getname(data);
+ if( not_server_variable(*name) && sd == NULL ) { // requires a player
+ sd = script_rid2sd(st);
+ if( sd == NULL ) { // no player attached
+ script_reportdata(data);
+ st->state = END;
+ return 1;
+ }
+ }
+ if( not_array_variable(*name) )
+ max_rows = 1;// not an array, limit to one row
+ } else {
+ ShowError("script:query_sql: not a variable\n");
+ script_reportdata(data);
+ st->state = END;
+ return 1;
+ }
+ }
+ num_vars = i - 3;
+
+ // Execute the query
+ query = script_getstr(st,2);
+
+ if( SQL_ERROR == Sql_QueryStr(handle, query) ) {
+ Sql_ShowDebug(handle);
+ script_pushint(st, 0);
+ return 1;
+ }
+
+ if( Sql_NumRows(handle) == 0 ) { // No data received
+ Sql_FreeResult(handle);
+ script_pushint(st, 0);
+ return 0;
+ }
+
+ // Count the number of columns to store
+ num_cols = Sql_NumColumns(handle);
+ if( num_vars < num_cols ) {
+ ShowWarning("script:query_sql: Too many columns, discarding last %u columns.\n", (unsigned int)(num_cols-num_vars));
+ script_reportsrc(st);
+ } else if( num_vars > num_cols ) {
+ ShowWarning("script:query_sql: Too many variables (%u extra).\n", (unsigned int)(num_vars-num_cols));
+ script_reportsrc(st);
+ }
+
+ // Store data
+ for( i = 0; i < max_rows && SQL_SUCCESS == Sql_NextRow(handle); ++i ) {
+ for( j = 0; j < num_vars; ++j ) {
+ char* str = NULL;
+
+ if( j < num_cols )
+ Sql_GetData(handle, j, &str, NULL);
+
+ data = script_getdata(st, j+3);
+ name = reference_getname(data);
+ if( is_string_variable(name) )
+ setd_sub(st, sd, name, i, (void *)(str?str:""), reference_getref(data));
+ else
+ setd_sub(st, sd, name, i, (void *)__64BPRTSIZE((str?atoi(str):0)), reference_getref(data));
+ }
+ }
+ if( i == max_rows && max_rows < Sql_NumRows(handle) ) {
+ ShowWarning("script:query_sql: Only %d/%u rows have been stored.\n", max_rows, (unsigned int)Sql_NumRows(handle));
+ script_reportsrc(st);
+ }
+
+ // Free data
+ Sql_FreeResult(handle);
+ script_pushint(st, i);
+
+ return 0;
+}
+
+BUILDIN_FUNC(query_sql) {
#ifdef BETA_THREAD_TEST
- if (st->state != RERUNLINE) {
- queryThread_add(st,false);
+ if( st->state != RERUNLINE ) {
+ queryThread_add(st,false);
- st->state = RERUNLINE;/* will continue when the query is finished running. */
- } else
- st->state = RUN;
+ st->state = RERUNLINE;/* will continue when the query is finished running. */
+ } else
+ st->state = RUN;
- return 0;
+ return 0;
#else
- return buildin_query_sql_sub(st, mmysql_handle);
+ return buildin_query_sql_sub(st, mmysql_handle);
#endif
}
-BUILDIN_FUNC(query_logsql)
-{
- if (!log_config.sql_logs) { // logmysql_handle == NULL
- ShowWarning("buildin_query_logsql: SQL logs are disabled, query '%s' will not be executed.\n", script_getstr(st,2));
- script_pushint(st,-1);
- return 1;
- }
+BUILDIN_FUNC(query_logsql) {
+ if( !log_config.sql_logs ) {// logmysql_handle == NULL
+ ShowWarning("buildin_query_logsql: SQL logs are disabled, query '%s' will not be executed.\n", script_getstr(st,2));
+ script_pushint(st,-1);
+ return 1;
+ }
#ifdef BETA_THREAD_TEST
- if (st->state != RERUNLINE) {
- queryThread_add(st,true);
+ if( st->state != RERUNLINE ) {
+ queryThread_add(st,true);
- st->state = RERUNLINE;/* will continue when the query is finished running. */
- } else
- st->state = RUN;
+ st->state = RERUNLINE;/* will continue when the query is finished running. */
+ } else
+ st->state = RUN;
- return 0;
+ return 0;
#else
- return buildin_query_sql_sub(st, logmysql_handle);
+ return buildin_query_sql_sub(st, logmysql_handle);
#endif
}
//Allows escaping of a given string.
BUILDIN_FUNC(escape_sql)
{
- const char *str;
- char *esc_str;
- size_t len;
+ const char *str;
+ char *esc_str;
+ size_t len;
- str = script_getstr(st,2);
- len = strlen(str);
- esc_str = (char *)aMalloc(len*2+1);
- Sql_EscapeStringLen(mmysql_handle, esc_str, str, len);
- script_pushstr(st, esc_str);
- return 0;
+ str = script_getstr(st,2);
+ len = strlen(str);
+ esc_str = (char*)aMalloc(len*2+1);
+ Sql_EscapeStringLen(mmysql_handle, esc_str, str, len);
+ script_pushstr(st, esc_str);
+ return 0;
}
BUILDIN_FUNC(getd)
{
- char varname[100];
- const char *buffer;
- int elem;
+ char varname[100];
+ const char *buffer;
+ int elem;
- buffer = script_getstr(st, 2);
+ buffer = script_getstr(st, 2);
- if (sscanf(buffer, "%[^[][%d]", varname, &elem) < 2)
- elem = 0;
+ if(sscanf(buffer, "%[^[][%d]", varname, &elem) < 2)
+ elem = 0;
- // Push the 'pointer' so it's more flexible [Lance]
- push_val(st->stack, C_NAME, reference_uid(add_str(varname), elem));
+ // Push the 'pointer' so it's more flexible [Lance]
+ push_val(st->stack, C_NAME, reference_uid(add_str(varname), elem));
- return 0;
+ return 0;
}
// <--- [zBuffer] List of dynamic var commands
// Pet stat [Lance]
BUILDIN_FUNC(petstat)
{
- TBL_PC *sd = NULL;
- struct pet_data *pd;
- int flag = script_getnum(st,2);
- sd = script_rid2sd(st);
- if (!sd || !sd->status.pet_id || !sd->pd) {
- if (flag == 2)
- script_pushconststr(st, "");
- else
- script_pushint(st,0);
- return 0;
- }
- pd = sd->pd;
- switch (flag) {
- case 1:
- script_pushint(st,(int)pd->pet.class_);
- break;
- case 2:
- script_pushstrcopy(st, pd->pet.name);
- break;
- case 3:
- script_pushint(st,(int)pd->pet.level);
- break;
- case 4:
- script_pushint(st,(int)pd->pet.hungry);
- break;
- case 5:
- script_pushint(st,(int)pd->pet.intimate);
- break;
- default:
- script_pushint(st,0);
- break;
- }
- return 0;
+ TBL_PC *sd = NULL;
+ struct pet_data *pd;
+ int flag = script_getnum(st,2);
+ sd = script_rid2sd(st);
+ if(!sd || !sd->status.pet_id || !sd->pd){
+ if(flag == 2)
+ script_pushconststr(st, "");
+ else
+ script_pushint(st,0);
+ return 0;
+ }
+ pd = sd->pd;
+ switch(flag){
+ case 1: script_pushint(st,(int)pd->pet.class_); break;
+ case 2: script_pushstrcopy(st, pd->pet.name); break;
+ case 3: script_pushint(st,(int)pd->pet.level); break;
+ case 4: script_pushint(st,(int)pd->pet.hungry); break;
+ case 5: script_pushint(st,(int)pd->pet.intimate); break;
+ default:
+ script_pushint(st,0);
+ break;
+ }
+ return 0;
}
BUILDIN_FUNC(callshop)
{
- TBL_PC *sd = NULL;
- struct npc_data *nd;
- const char *shopname;
- int flag = 0;
- sd = script_rid2sd(st);
- if (!sd) {
- script_pushint(st,0);
- return 0;
- }
- shopname = script_getstr(st, 2);
- if (script_hasdata(st,3))
- flag = script_getnum(st,3);
- nd = npc_name2id(shopname);
- if (!nd || nd->bl.type != BL_NPC || (nd->subtype != SHOP && nd->subtype != CASHSHOP)) {
- ShowError("buildin_callshop: Shop [%s] not found (or NPC is not shop type)\n", shopname);
- script_pushint(st,0);
- return 1;
- }
-
- if (nd->subtype == SHOP) {
- // flag the user as using a valid script call for opening the shop (for floating NPCs)
- sd->state.callshop = 1;
-
- switch (flag) {
- case 1:
- npc_buysellsel(sd,nd->bl.id,0);
- break; //Buy window
- case 2:
- npc_buysellsel(sd,nd->bl.id,1);
- break; //Sell window
- default:
- clif_npcbuysell(sd,nd->bl.id);
- break; //Show menu
- }
- } else
- clif_cashshop_show(sd, nd);
-
- sd->npc_shopid = nd->bl.id;
- script_pushint(st,1);
- return 0;
+ TBL_PC *sd = NULL;
+ struct npc_data *nd;
+ const char *shopname;
+ int flag = 0;
+ sd = script_rid2sd(st);
+ if (!sd) {
+ script_pushint(st,0);
+ return 0;
+ }
+ shopname = script_getstr(st, 2);
+ if( script_hasdata(st,3) )
+ flag = script_getnum(st,3);
+ nd = npc_name2id(shopname);
+ if( !nd || nd->bl.type != BL_NPC || (nd->subtype != SHOP && nd->subtype != CASHSHOP) )
+ {
+ ShowError("buildin_callshop: Shop [%s] not found (or NPC is not shop type)\n", shopname);
+ script_pushint(st,0);
+ return 1;
+ }
+
+ if( nd->subtype == SHOP )
+ {
+ // flag the user as using a valid script call for opening the shop (for floating NPCs)
+ sd->state.callshop = 1;
+
+ switch( flag )
+ {
+ case 1: npc_buysellsel(sd,nd->bl.id,0); break; //Buy window
+ case 2: npc_buysellsel(sd,nd->bl.id,1); break; //Sell window
+ default: clif_npcbuysell(sd,nd->bl.id); break; //Show menu
+ }
+ }
+ else
+ clif_cashshop_show(sd, nd);
+
+ sd->npc_shopid = nd->bl.id;
+ script_pushint(st,1);
+ return 0;
}
BUILDIN_FUNC(npcshopitem)
{
- const char *npcname = script_getstr(st, 2);
- struct npc_data *nd = npc_name2id(npcname);
- int n, i;
- int amount;
+ const char* npcname = script_getstr(st, 2);
+ struct npc_data* nd = npc_name2id(npcname);
+ int n, i;
+ int amount;
- if (!nd || (nd->subtype != SHOP && nd->subtype != CASHSHOP)) {
- //Not found.
- script_pushint(st,0);
- return 0;
- }
+ if( !nd || ( nd->subtype != SHOP && nd->subtype != CASHSHOP ) )
+ { //Not found.
+ script_pushint(st,0);
+ return 0;
+ }
- // get the count of new entries
- amount = (script_lastdata(st)-2)/2;
+ // get the count of new entries
+ amount = (script_lastdata(st)-2)/2;
- // generate new shop item list
- RECREATE(nd->u.shop.shop_item, struct npc_item_list, amount);
- for (n = 0, i = 3; n < amount; n++, i+=2) {
- nd->u.shop.shop_item[n].nameid = script_getnum(st,i);
- nd->u.shop.shop_item[n].value = script_getnum(st,i+1);
- }
- nd->u.shop.count = n;
+ // generate new shop item list
+ RECREATE(nd->u.shop.shop_item, struct npc_item_list, amount);
+ for( n = 0, i = 3; n < amount; n++, i+=2 )
+ {
+ nd->u.shop.shop_item[n].nameid = script_getnum(st,i);
+ nd->u.shop.shop_item[n].value = script_getnum(st,i+1);
+ }
+ nd->u.shop.count = n;
- script_pushint(st,1);
- return 0;
+ script_pushint(st,1);
+ return 0;
}
BUILDIN_FUNC(npcshopadditem)
{
- const char *npcname = script_getstr(st,2);
- struct npc_data *nd = npc_name2id(npcname);
- int n, i;
- int amount;
+ const char* npcname = script_getstr(st,2);
+ struct npc_data* nd = npc_name2id(npcname);
+ int n, i;
+ int amount;
- if (!nd || (nd->subtype != SHOP && nd->subtype != CASHSHOP)) {
- //Not found.
- script_pushint(st,0);
- return 0;
- }
+ if( !nd || ( nd->subtype != SHOP && nd->subtype != CASHSHOP ) )
+ { //Not found.
+ script_pushint(st,0);
+ return 0;
+ }
- // get the count of new entries
- amount = (script_lastdata(st)-2)/2;
+ // get the count of new entries
+ amount = (script_lastdata(st)-2)/2;
- // append new items to existing shop item list
- RECREATE(nd->u.shop.shop_item, struct npc_item_list, nd->u.shop.count+amount);
- for (n = nd->u.shop.count, i = 3; n < nd->u.shop.count+amount; n++, i+=2) {
- nd->u.shop.shop_item[n].nameid = script_getnum(st,i);
- nd->u.shop.shop_item[n].value = script_getnum(st,i+1);
- }
- nd->u.shop.count = n;
+ // append new items to existing shop item list
+ RECREATE(nd->u.shop.shop_item, struct npc_item_list, nd->u.shop.count+amount);
+ for( n = nd->u.shop.count, i = 3; n < nd->u.shop.count+amount; n++, i+=2 )
+ {
+ nd->u.shop.shop_item[n].nameid = script_getnum(st,i);
+ nd->u.shop.shop_item[n].value = script_getnum(st,i+1);
+ }
+ nd->u.shop.count = n;
- script_pushint(st,1);
- return 0;
+ script_pushint(st,1);
+ return 0;
}
BUILDIN_FUNC(npcshopdelitem)
{
- const char *npcname = script_getstr(st,2);
- struct npc_data *nd = npc_name2id(npcname);
- unsigned int nameid;
- int n, i;
- int amount;
- int size;
+ const char* npcname = script_getstr(st,2);
+ struct npc_data* nd = npc_name2id(npcname);
+ unsigned int nameid;
+ int n, i;
+ int amount;
+ int size;
- if (!nd || (nd->subtype != SHOP && nd->subtype != CASHSHOP)) {
- //Not found.
- script_pushint(st,0);
- return 0;
- }
+ if( !nd || ( nd->subtype != SHOP && nd->subtype != CASHSHOP ) )
+ { //Not found.
+ script_pushint(st,0);
+ return 0;
+ }
- amount = script_lastdata(st)-2;
- size = nd->u.shop.count;
+ amount = script_lastdata(st)-2;
+ size = nd->u.shop.count;
- // remove specified items from the shop item list
- for (i = 3; i < 3 + amount; i++) {
- nameid = script_getnum(st,i);
+ // remove specified items from the shop item list
+ for( i = 3; i < 3 + amount; i++ )
+ {
+ nameid = script_getnum(st,i);
- ARR_FIND(0, size, n, nd->u.shop.shop_item[n].nameid == nameid);
- if (n < size) {
- memmove(&nd->u.shop.shop_item[n], &nd->u.shop.shop_item[n+1], sizeof(nd->u.shop.shop_item[0])*(size-n));
- size--;
- }
- }
+ ARR_FIND( 0, size, n, nd->u.shop.shop_item[n].nameid == nameid );
+ if( n < size )
+ {
+ memmove(&nd->u.shop.shop_item[n], &nd->u.shop.shop_item[n+1], sizeof(nd->u.shop.shop_item[0])*(size-n));
+ size--;
+ }
+ }
- RECREATE(nd->u.shop.shop_item, struct npc_item_list, size);
- nd->u.shop.count = size;
+ RECREATE(nd->u.shop.shop_item, struct npc_item_list, size);
+ nd->u.shop.count = size;
- script_pushint(st,1);
- return 0;
+ script_pushint(st,1);
+ return 0;
}
//Sets a script to attach to a shop npc.
BUILDIN_FUNC(npcshopattach)
{
- const char *npcname = script_getstr(st,2);
- struct npc_data *nd = npc_name2id(npcname);
- int flag = 1;
+ const char* npcname = script_getstr(st,2);
+ struct npc_data* nd = npc_name2id(npcname);
+ int flag = 1;
- if (script_hasdata(st,3))
- flag = script_getnum(st,3);
+ if( script_hasdata(st,3) )
+ flag = script_getnum(st,3);
- if (!nd || nd->subtype != SHOP) {
- //Not found.
- script_pushint(st,0);
- return 0;
- }
+ if( !nd || nd->subtype != SHOP )
+ { //Not found.
+ script_pushint(st,0);
+ return 0;
+ }
- if (flag)
- nd->master_nd = ((struct npc_data *)map_id2bl(st->oid));
- else
- nd->master_nd = NULL;
+ if (flag)
+ nd->master_nd = ((struct npc_data *)map_id2bl(st->oid));
+ else
+ nd->master_nd = NULL;
- script_pushint(st,1);
- return 0;
+ script_pushint(st,1);
+ return 0;
}
/*==========================================
* Returns some values of an item [Lupus]
* Price, Weight, etc...
- setitemscript(itemID,"{new item bonus script}",[n]);
+ setitemscript(itemID,"{new item bonus script}",[n]);
Where n:
- 0 - script
- 1 - Equip script
- 2 - Unequip script
+ 0 - script
+ 1 - Equip script
+ 2 - Unequip script
*------------------------------------------*/
BUILDIN_FUNC(setitemscript)
{
- int item_id,n=0;
- const char *script;
- struct item_data *i_data;
- struct script_code **dstscript;
-
- item_id = script_getnum(st,2);
- script = script_getstr(st,3);
- if (script_hasdata(st,4))
- n=script_getnum(st,4);
- i_data = itemdb_exists(item_id);
-
- if (!i_data || script==NULL || (script[0] && script[0]!='{')) {
- script_pushint(st,0);
- return 0;
- }
- switch (n) {
- case 2:
- dstscript = &i_data->unequip_script;
- break;
- case 1:
- dstscript = &i_data->equip_script;
- break;
- default:
- dstscript = &i_data->script;
- break;
- }
- if (*dstscript)
- script_free_code(*dstscript);
-
- *dstscript = script[0] ? parse_script(script, "script_setitemscript", 0, 0) : NULL;
- script_pushint(st,1);
- return 0;
+ int item_id,n=0;
+ const char *script;
+ struct item_data *i_data;
+ struct script_code **dstscript;
+
+ item_id = script_getnum(st,2);
+ script = script_getstr(st,3);
+ if( script_hasdata(st,4) )
+ n=script_getnum(st,4);
+ i_data = itemdb_exists(item_id);
+
+ if (!i_data || script==NULL || ( script[0] && script[0]!='{' )) {
+ script_pushint(st,0);
+ return 0;
+ }
+ switch (n) {
+ case 2:
+ dstscript = &i_data->unequip_script;
+ break;
+ case 1:
+ dstscript = &i_data->equip_script;
+ break;
+ default:
+ dstscript = &i_data->script;
+ break;
+ }
+ if(*dstscript)
+ script_free_code(*dstscript);
+
+ *dstscript = script[0] ? parse_script(script, "script_setitemscript", 0, 0) : NULL;
+ script_pushint(st,1);
+ return 0;
}
/* Work In Progress [Lupus]
BUILDIN_FUNC(addmonsterdrop)
{
- int class_,item_id,chance;
- class_=script_getnum(st,2);
- item_id=script_getnum(st,3);
- chance=script_getnum(st,4);
- if(class_>1000 && item_id>500 && chance>0) {
- script_pushint(st,1);
- } else {
- script_pushint(st,0);
- }
+ int class_,item_id,chance;
+ class_=script_getnum(st,2);
+ item_id=script_getnum(st,3);
+ chance=script_getnum(st,4);
+ if(class_>1000 && item_id>500 && chance>0) {
+ script_pushint(st,1);
+ } else {
+ script_pushint(st,0);
+ }
}
BUILDIN_FUNC(delmonsterdrop)
{
- int class_,item_id;
- class_=script_getnum(st,2);
- item_id=script_getnum(st,3);
- if(class_>1000 && item_id>500) {
- script_pushint(st,1);
- } else {
- script_pushint(st,0);
- }
+ int class_,item_id;
+ class_=script_getnum(st,2);
+ item_id=script_getnum(st,3);
+ if(class_>1000 && item_id>500) {
+ script_pushint(st,1);
+ } else {
+ script_pushint(st,0);
+ }
}
*/
/*==========================================
* Returns some values of a monster [Lupus]
* Name, Level, race, size, etc...
- getmonsterinfo(monsterID,queryIndex);
+ getmonsterinfo(monsterID,queryIndex);
*------------------------------------------*/
BUILDIN_FUNC(getmonsterinfo)
{
- struct mob_db *mob;
- int mob_id;
-
- mob_id = script_getnum(st,2);
- if (!mobdb_checkid(mob_id)) {
- ShowError("buildin_getmonsterinfo: Wrong Monster ID: %i\n", mob_id);
- if (!script_getnum(st,3)) //requested a string
- script_pushconststr(st,"null");
- else
- script_pushint(st,-1);
- return -1;
- }
- mob = mob_db(mob_id);
- switch (script_getnum(st,3)) {
- case 0:
- script_pushstrcopy(st,mob->jname);
- break;
- case 1:
- script_pushint(st,mob->lv);
- break;
- case 2:
- script_pushint(st,mob->status.max_hp);
- break;
- case 3:
- script_pushint(st,mob->base_exp);
- break;
- case 4:
- script_pushint(st,mob->job_exp);
- break;
- case 5:
- script_pushint(st,mob->status.rhw.atk);
- break;
- case 6:
- script_pushint(st,mob->status.rhw.atk2);
- break;
- case 7:
- script_pushint(st,mob->status.def);
- break;
- case 8:
- script_pushint(st,mob->status.mdef);
- break;
- case 9:
- script_pushint(st,mob->status.str);
- break;
- case 10:
- script_pushint(st,mob->status.agi);
- break;
- case 11:
- script_pushint(st,mob->status.vit);
- break;
- case 12:
- script_pushint(st,mob->status.int_);
- break;
- case 13:
- script_pushint(st,mob->status.dex);
- break;
- case 14:
- script_pushint(st,mob->status.luk);
- break;
- case 15:
- script_pushint(st,mob->status.rhw.range);
- break;
- case 16:
- script_pushint(st,mob->range2);
- break;
- case 17:
- script_pushint(st,mob->range3);
- break;
- case 18:
- script_pushint(st,mob->status.size);
- break;
- case 19:
- script_pushint(st,mob->status.race);
- break;
- case 20:
- script_pushint(st,mob->status.def_ele);
- break;
- case 21:
- script_pushint(st,mob->status.mode);
- break;
- case 22:
- script_pushint(st,mob->mexp);
- break;
- default:
- script_pushint(st,-1); //wrong Index
- }
- return 0;
+ struct mob_db *mob;
+ int mob_id;
+
+ mob_id = script_getnum(st,2);
+ if (!mobdb_checkid(mob_id)) {
+ ShowError("buildin_getmonsterinfo: Wrong Monster ID: %i\n", mob_id);
+ if ( !script_getnum(st,3) ) //requested a string
+ script_pushconststr(st,"null");
+ else
+ script_pushint(st,-1);
+ return -1;
+ }
+ mob = mob_db(mob_id);
+ switch ( script_getnum(st,3) ) {
+ case 0: script_pushstrcopy(st,mob->jname); break;
+ case 1: script_pushint(st,mob->lv); break;
+ case 2: script_pushint(st,mob->status.max_hp); break;
+ case 3: script_pushint(st,mob->base_exp); break;
+ case 4: script_pushint(st,mob->job_exp); break;
+ case 5: script_pushint(st,mob->status.rhw.atk); break;
+ case 6: script_pushint(st,mob->status.rhw.atk2); break;
+ case 7: script_pushint(st,mob->status.def); break;
+ case 8: script_pushint(st,mob->status.mdef); break;
+ case 9: script_pushint(st,mob->status.str); break;
+ case 10: script_pushint(st,mob->status.agi); break;
+ case 11: script_pushint(st,mob->status.vit); break;
+ case 12: script_pushint(st,mob->status.int_); break;
+ case 13: script_pushint(st,mob->status.dex); break;
+ case 14: script_pushint(st,mob->status.luk); break;
+ case 15: script_pushint(st,mob->status.rhw.range); break;
+ case 16: script_pushint(st,mob->range2); break;
+ case 17: script_pushint(st,mob->range3); break;
+ case 18: script_pushint(st,mob->status.size); break;
+ case 19: script_pushint(st,mob->status.race); break;
+ case 20: script_pushint(st,mob->status.def_ele); break;
+ case 21: script_pushint(st,mob->status.mode); break;
+ case 22: script_pushint(st,mob->mexp); break;
+ default: script_pushint(st,-1); //wrong Index
+ }
+ return 0;
}
BUILDIN_FUNC(checkvending) // check vending [Nab4]
{
- TBL_PC *sd = NULL;
+ TBL_PC *sd = NULL;
- if (script_hasdata(st,2))
- sd = map_nick2sd(script_getstr(st,2));
- else
- sd = script_rid2sd(st);
+ if(script_hasdata(st,2))
+ sd = map_nick2sd(script_getstr(st,2));
+ else
+ sd = script_rid2sd(st);
- if (sd)
- script_pushint(st, sd->state.autotrade ? 2 : sd->state.vending);
- else
- script_pushint(st,0);
+ if(sd)
+ script_pushint(st, sd->state.autotrade ? 2 : sd->state.vending);
+ else
+ script_pushint(st,0);
- return 0;
+ return 0;
}
BUILDIN_FUNC(checkchatting) // check chatting [Marka]
{
- TBL_PC *sd = NULL;
+ TBL_PC *sd = NULL;
- if (script_hasdata(st,2))
- sd = map_nick2sd(script_getstr(st,2));
- else
- sd = script_rid2sd(st);
+ if(script_hasdata(st,2))
+ sd = map_nick2sd(script_getstr(st,2));
+ else
+ sd = script_rid2sd(st);
- if (sd)
- script_pushint(st,(sd->chatID != 0));
- else
- script_pushint(st,0);
+ if(sd)
+ script_pushint(st,(sd->chatID != 0));
+ else
+ script_pushint(st,0);
- return 0;
+ return 0;
}
BUILDIN_FUNC(searchitem)
{
- struct script_data *data = script_getdata(st, 2);
- const char *itemname = script_getstr(st,3);
- struct item_data *items[MAX_SEARCH];
- int count;
-
- char *name;
- int32 start;
- int32 id;
- int32 i;
- TBL_PC *sd = NULL;
-
- if ((items[0] = itemdb_exists(atoi(itemname))))
- count = 1;
- else {
- count = itemdb_searchname_array(items, ARRAYLENGTH(items), itemname);
- if (count > MAX_SEARCH) count = MAX_SEARCH;
- }
-
- if (!count) {
- script_pushint(st, 0);
- return 0;
- }
-
- if (!data_isreference(data)) {
- ShowError("script:searchitem: not a variable\n");
- script_reportdata(data);
- st->state = END;
- return 1;// not a variable
- }
-
- id = reference_getid(data);
- start = reference_getindex(data);
- name = reference_getname(data);
- if (not_array_variable(*name)) {
- ShowError("script:searchitem: illegal scope\n");
- script_reportdata(data);
- st->state = END;
- return 1;// not supported
- }
-
- if (not_server_variable(*name)) {
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;// no player attached
- }
-
- if (is_string_variable(name)) {
- // string array
- ShowError("script:searchitem: not an integer array reference\n");
- script_reportdata(data);
- st->state = END;
- return 1;// not supported
- }
-
- for (i = 0; i < count; ++start, ++i) {
- // Set array
- void *v = (void *)__64BPRTSIZE(items[i]->nameid);
- set_reg(st, sd, reference_uid(id, start), name, v, reference_getref(data));
- }
-
- script_pushint(st, count);
- return 0;
+ struct script_data* data = script_getdata(st, 2);
+ const char *itemname = script_getstr(st,3);
+ struct item_data *items[MAX_SEARCH];
+ int count;
+
+ char* name;
+ int32 start;
+ int32 id;
+ int32 i;
+ TBL_PC* sd = NULL;
+
+ if ((items[0] = itemdb_exists(atoi(itemname))))
+ count = 1;
+ else {
+ count = itemdb_searchname_array(items, ARRAYLENGTH(items), itemname);
+ if (count > MAX_SEARCH) count = MAX_SEARCH;
+ }
+
+ if (!count) {
+ script_pushint(st, 0);
+ return 0;
+ }
+
+ if( !data_isreference(data) )
+ {
+ ShowError("script:searchitem: not a variable\n");
+ script_reportdata(data);
+ st->state = END;
+ return 1;// not a variable
+ }
+
+ id = reference_getid(data);
+ start = reference_getindex(data);
+ name = reference_getname(data);
+ if( not_array_variable(*name) )
+ {
+ ShowError("script:searchitem: illegal scope\n");
+ script_reportdata(data);
+ st->state = END;
+ return 1;// not supported
+ }
+
+ if( not_server_variable(*name) )
+ {
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;// no player attached
+ }
+
+ if( is_string_variable(name) )
+ {// string array
+ ShowError("script:searchitem: not an integer array reference\n");
+ script_reportdata(data);
+ st->state = END;
+ return 1;// not supported
+ }
+
+ for( i = 0; i < count; ++start, ++i )
+ {// Set array
+ void* v = (void*)__64BPRTSIZE(items[i]->nameid);
+ set_reg(st, sd, reference_uid(id, start), name, v, reference_getref(data));
+ }
+
+ script_pushint(st, count);
+ return 0;
}
int axtoi(const char *hexStg)
{
- int n = 0; // position in string
- int m = 0; // position in digit[] to shift
- int count; // loop index
- int intValue = 0; // integer value of hex string
- int digit[11]; // hold values to convert
- while (n < 10) {
- if (hexStg[n]=='\0')
- break;
- if (hexStg[n] > 0x29 && hexStg[n] < 0x40) //if 0 to 9
- digit[n] = hexStg[n] & 0x0f; //convert to int
- else if (hexStg[n] >='a' && hexStg[n] <= 'f') //if a to f
- digit[n] = (hexStg[n] & 0x0f) + 9; //convert to int
- else if (hexStg[n] >='A' && hexStg[n] <= 'F') //if A to F
- digit[n] = (hexStg[n] & 0x0f) + 9; //convert to int
- else break;
- n++;
- }
- count = n;
- m = n - 1;
- n = 0;
- while (n < count) {
- // digit[n] is value of hex digit at position n
- // (m << 2) is the number of positions to shift
- // OR the bits into return value
- intValue = intValue | (digit[n] << (m << 2));
- m--; // adjust the position to set
- n++; // next digit to process
- }
- return (intValue);
+ int n = 0; // position in string
+ int m = 0; // position in digit[] to shift
+ int count; // loop index
+ int intValue = 0; // integer value of hex string
+ int digit[11]; // hold values to convert
+ while (n < 10) {
+ if (hexStg[n]=='\0')
+ break;
+ if (hexStg[n] > 0x29 && hexStg[n] < 0x40 ) //if 0 to 9
+ digit[n] = hexStg[n] & 0x0f; //convert to int
+ else if (hexStg[n] >='a' && hexStg[n] <= 'f') //if a to f
+ digit[n] = (hexStg[n] & 0x0f) + 9; //convert to int
+ else if (hexStg[n] >='A' && hexStg[n] <= 'F') //if A to F
+ digit[n] = (hexStg[n] & 0x0f) + 9; //convert to int
+ else break;
+ n++;
+ }
+ count = n;
+ m = n - 1;
+ n = 0;
+ while(n < count) {
+ // digit[n] is value of hex digit at position n
+ // (m << 2) is the number of positions to shift
+ // OR the bits into return value
+ intValue = intValue | (digit[n] << (m << 2));
+ m--; // adjust the position to set
+ n++; // next digit to process
+ }
+ return (intValue);
}
// [Lance] Hex string to integer converter
BUILDIN_FUNC(axtoi)
{
- const char *hex = script_getstr(st,2);
- script_pushint(st,axtoi(hex));
- return 0;
+ const char *hex = script_getstr(st,2);
+ script_pushint(st,axtoi(hex));
+ return 0;
}
// [zBuffer] List of player cont commands --->
BUILDIN_FUNC(rid2name)
{
- struct block_list *bl = NULL;
- int rid = script_getnum(st,2);
- if ((bl = map_id2bl(rid))) {
- switch (bl->type) {
- case BL_MOB:
- script_pushstrcopy(st,((TBL_MOB *)bl)->name);
- break;
- case BL_PC:
- script_pushstrcopy(st,((TBL_PC *)bl)->status.name);
- break;
- case BL_NPC:
- script_pushstrcopy(st,((TBL_NPC *)bl)->exname);
- break;
- case BL_PET:
- script_pushstrcopy(st,((TBL_PET *)bl)->pet.name);
- break;
- case BL_HOM:
- script_pushstrcopy(st,((TBL_HOM *)bl)->homunculus.name);
- break;
- case BL_MER:
- script_pushstrcopy(st,((TBL_MER *)bl)->db->name);
- break;
- default:
- ShowError("buildin_rid2name: BL type unknown.\n");
- script_pushconststr(st,"");
- break;
- }
- } else {
- ShowError("buildin_rid2name: invalid RID\n");
- script_pushconststr(st,"(null)");
- }
- return 0;
+ struct block_list *bl = NULL;
+ int rid = script_getnum(st,2);
+ if((bl = map_id2bl(rid)))
+ {
+ switch(bl->type) {
+ case BL_MOB: script_pushstrcopy(st,((TBL_MOB*)bl)->name); break;
+ case BL_PC: script_pushstrcopy(st,((TBL_PC*)bl)->status.name); break;
+ case BL_NPC: script_pushstrcopy(st,((TBL_NPC*)bl)->exname); break;
+ case BL_PET: script_pushstrcopy(st,((TBL_PET*)bl)->pet.name); break;
+ case BL_HOM: script_pushstrcopy(st,((TBL_HOM*)bl)->homunculus.name); break;
+ case BL_MER: script_pushstrcopy(st,((TBL_MER*)bl)->db->name); break;
+ default:
+ ShowError("buildin_rid2name: BL type unknown.\n");
+ script_pushconststr(st,"");
+ break;
+ }
+ } else {
+ ShowError("buildin_rid2name: invalid RID\n");
+ script_pushconststr(st,"(null)");
+ }
+ return 0;
}
BUILDIN_FUNC(pcblockmove)
{
- int id, flag;
- TBL_PC *sd = NULL;
+ int id, flag;
+ TBL_PC *sd = NULL;
- id = script_getnum(st,2);
- flag = script_getnum(st,3);
+ id = script_getnum(st,2);
+ flag = script_getnum(st,3);
- if (id)
- sd = map_id2sd(id);
- else
- sd = script_rid2sd(st);
+ if(id)
+ sd = map_id2sd(id);
+ else
+ sd = script_rid2sd(st);
- if (sd)
- sd->state.blockedmove = flag > 0;
+ if(sd)
+ sd->state.blockedmove = flag > 0;
- return 0;
+ return 0;
}
BUILDIN_FUNC(pcfollow)
{
- int id, targetid;
- TBL_PC *sd = NULL;
+ int id, targetid;
+ TBL_PC *sd = NULL;
- id = script_getnum(st,2);
- targetid = script_getnum(st,3);
+ id = script_getnum(st,2);
+ targetid = script_getnum(st,3);
- if (id)
- sd = map_id2sd(id);
- else
- sd = script_rid2sd(st);
+ if(id)
+ sd = map_id2sd(id);
+ else
+ sd = script_rid2sd(st);
- if (sd)
- pc_follow(sd, targetid);
+ if(sd)
+ pc_follow(sd, targetid);
return 0;
}
BUILDIN_FUNC(pcstopfollow)
{
- int id;
- TBL_PC *sd = NULL;
+ int id;
+ TBL_PC *sd = NULL;
- id = script_getnum(st,2);
+ id = script_getnum(st,2);
- if (id)
- sd = map_id2sd(id);
- else
- sd = script_rid2sd(st);
+ if(id)
+ sd = map_id2sd(id);
+ else
+ sd = script_rid2sd(st);
- if (sd)
- pc_stop_following(sd);
+ if(sd)
+ pc_stop_following(sd);
- return 0;
+ return 0;
}
// <--- [zBuffer] List of player cont commands
// [zBuffer] List of mob control commands --->
@@ -15331,21 +15171,26 @@ BUILDIN_FUNC(pcstopfollow)
/// unitwalk(<unit_id>,<map_id>) -> <bool>
BUILDIN_FUNC(unitwalk)
{
- struct block_list *bl;
-
- bl = map_id2bl(script_getnum(st,2));
- if (bl == NULL) {
- script_pushint(st, 0);
- } else if (script_hasdata(st,4)) {
- int x = script_getnum(st,3);
- int y = script_getnum(st,4);
- script_pushint(st, unit_walktoxy(bl,x,y,0));// We'll use harder calculations.
- } else {
- int map_id = script_getnum(st,3);
- script_pushint(st, unit_walktobl(bl,map_id2bl(map_id),65025,1));
- }
+ struct block_list* bl;
- return 0;
+ bl = map_id2bl(script_getnum(st,2));
+ if( bl == NULL )
+ {
+ script_pushint(st, 0);
+ }
+ else if( script_hasdata(st,4) )
+ {
+ int x = script_getnum(st,3);
+ int y = script_getnum(st,4);
+ script_pushint(st, unit_walktoxy(bl,x,y,0));// We'll use harder calculations.
+ }
+ else
+ {
+ int map_id = script_getnum(st,3);
+ script_pushint(st, unit_walktobl(bl,map_id2bl(map_id),65025,1));
+ }
+
+ return 0;
}
/// Kills the unit
@@ -15353,11 +15198,11 @@ BUILDIN_FUNC(unitwalk)
/// unitkill <unit_id>;
BUILDIN_FUNC(unitkill)
{
- struct block_list *bl = map_id2bl(script_getnum(st,2));
- if (bl != NULL)
- status_kill(bl);
+ struct block_list* bl = map_id2bl(script_getnum(st,2));
+ if( bl != NULL )
+ status_kill(bl);
- return 0;
+ return 0;
}
/// Warps the unit to the target position in the target map
@@ -15366,34 +15211,34 @@ BUILDIN_FUNC(unitkill)
/// unitwarp(<unit_id>,"<map name>",<x>,<y>) -> <bool>
BUILDIN_FUNC(unitwarp)
{
- int unit_id;
- int map;
- short x;
- short y;
- struct block_list *bl;
- const char *mapname;
-
- unit_id = script_getnum(st,2);
- mapname = script_getstr(st, 3);
- x = (short)script_getnum(st,4);
- y = (short)script_getnum(st,5);
-
- if (!unit_id) //Warp the script's runner
- bl = map_id2bl(st->rid);
- else
- bl = map_id2bl(unit_id);
-
- if (strcmp(mapname,"this") == 0)
- map = bl?bl->m:-1;
- else
- map = map_mapname2mapid(mapname);
-
- if (map >= 0 && bl != NULL)
- script_pushint(st, unit_warp(bl,map,x,y,CLR_OUTSIGHT));
- else
- script_pushint(st, 0);
+ int unit_id;
+ int map;
+ short x;
+ short y;
+ struct block_list* bl;
+ const char *mapname;
- return 0;
+ unit_id = script_getnum(st,2);
+ mapname = script_getstr(st, 3);
+ x = (short)script_getnum(st,4);
+ y = (short)script_getnum(st,5);
+
+ if (!unit_id) //Warp the script's runner
+ bl = map_id2bl(st->rid);
+ else
+ bl = map_id2bl(unit_id);
+
+ if( strcmp(mapname,"this") == 0 )
+ map = bl?bl->m:-1;
+ else
+ map = map_mapname2mapid(mapname);
+
+ if( map >= 0 && bl != NULL )
+ script_pushint(st, unit_warp(bl,map,x,y,CLR_OUTSIGHT));
+ else
+ script_pushint(st, 0);
+
+ return 0;
}
/// Makes the unit attack the target.
@@ -15405,54 +15250,57 @@ BUILDIN_FUNC(unitwarp)
/// unitattack(<unit_id>,<target_id>{,<action type>}) -> <bool>
BUILDIN_FUNC(unitattack)
{
- struct block_list *unit_bl;
- struct block_list *target_bl = NULL;
- struct script_data *data;
- int actiontype = 0;
-
- // get unit
- unit_bl = map_id2bl(script_getnum(st,2));
- if (unit_bl == NULL) {
- script_pushint(st, 0);
- return 0;
- }
-
- data = script_getdata(st, 3);
- get_val(st, data);
- if (data_isstring(data)) {
- TBL_PC *sd = map_nick2sd(conv_str(st, data));
- if (sd != NULL)
- target_bl = &sd->bl;
- } else
- target_bl = map_id2bl(conv_num(st, data));
- // request the attack
- if (target_bl == NULL) {
- script_pushint(st, 0);
- return 0;
- }
-
- // get actiontype
- if (script_hasdata(st,4))
- actiontype = script_getnum(st,4);
-
- switch (unit_bl->type) {
- case BL_PC:
- clif_parse_ActionRequest_sub(((TBL_PC *)unit_bl), actiontype > 0 ? 0x07 : 0x00, target_bl->id, gettick());
- script_pushint(st, 1);
- return 0;
- case BL_MOB:
- ((TBL_MOB *)unit_bl)->target_id = target_bl->id;
- break;
- case BL_PET:
- ((TBL_PET *)unit_bl)->target_id = target_bl->id;
- break;
- default:
- ShowError("script:unitattack: unsupported source unit type %d\n", unit_bl->type);
- script_pushint(st, 0);
- return 1;
- }
- script_pushint(st, unit_walktobl(unit_bl, target_bl, 65025, 2));
- return 0;
+ struct block_list* unit_bl;
+ struct block_list* target_bl = NULL;
+ struct script_data* data;
+ int actiontype = 0;
+
+ // get unit
+ unit_bl = map_id2bl(script_getnum(st,2));
+ if( unit_bl == NULL ) {
+ script_pushint(st, 0);
+ return 0;
+ }
+
+ data = script_getdata(st, 3);
+ get_val(st, data);
+ if( data_isstring(data) )
+ {
+ TBL_PC* sd = map_nick2sd(conv_str(st, data));
+ if( sd != NULL )
+ target_bl = &sd->bl;
+ } else
+ target_bl = map_id2bl(conv_num(st, data));
+ // request the attack
+ if( target_bl == NULL )
+ {
+ script_pushint(st, 0);
+ return 0;
+ }
+
+ // get actiontype
+ if( script_hasdata(st,4) )
+ actiontype = script_getnum(st,4);
+
+ switch( unit_bl->type )
+ {
+ case BL_PC:
+ clif_parse_ActionRequest_sub(((TBL_PC *)unit_bl), actiontype > 0 ? 0x07 : 0x00, target_bl->id, gettick());
+ script_pushint(st, 1);
+ return 0;
+ case BL_MOB:
+ ((TBL_MOB *)unit_bl)->target_id = target_bl->id;
+ break;
+ case BL_PET:
+ ((TBL_PET *)unit_bl)->target_id = target_bl->id;
+ break;
+ default:
+ ShowError("script:unitattack: unsupported source unit type %d\n", unit_bl->type);
+ script_pushint(st, 0);
+ return 1;
+ }
+ script_pushint(st, unit_walktobl(unit_bl, target_bl, 65025, 2));
+ return 0;
}
/// Makes the unit stop attacking and moving
@@ -15460,20 +15308,21 @@ BUILDIN_FUNC(unitattack)
/// unitstop <unit_id>;
BUILDIN_FUNC(unitstop)
{
- int unit_id;
- struct block_list *bl;
+ int unit_id;
+ struct block_list* bl;
- unit_id = script_getnum(st,2);
+ unit_id = script_getnum(st,2);
- bl = map_id2bl(unit_id);
- if (bl != NULL) {
- unit_stop_attack(bl);
- unit_stop_walking(bl,4);
- if (bl->type == BL_MOB)
- ((TBL_MOB *)bl)->target_id = 0;
- }
+ bl = map_id2bl(unit_id);
+ if( bl != NULL )
+ {
+ unit_stop_attack(bl);
+ unit_stop_walking(bl,4);
+ if( bl->type == BL_MOB )
+ ((TBL_MOB*)bl)->target_id = 0;
+ }
- return 0;
+ return 0;
}
/// Makes the unit say the message
@@ -15481,25 +15330,26 @@ BUILDIN_FUNC(unitstop)
/// unittalk <unit_id>,"<message>";
BUILDIN_FUNC(unittalk)
{
- int unit_id;
- const char *message;
- struct block_list *bl;
-
- unit_id = script_getnum(st,2);
- message = script_getstr(st, 3);
-
- bl = map_id2bl(unit_id);
- if (bl != NULL) {
- struct StringBuf sbuf;
- StringBuf_Init(&sbuf);
- StringBuf_Printf(&sbuf, "%s : %s", status_get_name(bl), message);
- clif_message(bl, StringBuf_Value(&sbuf));
- if (bl->type == BL_PC)
- clif_displaymessage(((TBL_PC *)bl)->fd, StringBuf_Value(&sbuf));
- StringBuf_Destroy(&sbuf);
- }
+ int unit_id;
+ const char* message;
+ struct block_list* bl;
- return 0;
+ unit_id = script_getnum(st,2);
+ message = script_getstr(st, 3);
+
+ bl = map_id2bl(unit_id);
+ if( bl != NULL )
+ {
+ struct StringBuf sbuf;
+ StringBuf_Init(&sbuf);
+ StringBuf_Printf(&sbuf, "%s : %s", status_get_name(bl), message);
+ clif_message(bl, StringBuf_Value(&sbuf));
+ if( bl->type == BL_PC )
+ clif_displaymessage(((TBL_PC*)bl)->fd, StringBuf_Value(&sbuf));
+ StringBuf_Destroy(&sbuf);
+ }
+
+ return 0;
}
/// Makes the unit do an emotion
@@ -15509,17 +15359,17 @@ BUILDIN_FUNC(unittalk)
/// @see e_* in const.txt
BUILDIN_FUNC(unitemote)
{
- int unit_id;
- int emotion;
- struct block_list *bl;
+ int unit_id;
+ int emotion;
+ struct block_list* bl;
- unit_id = script_getnum(st,2);
- emotion = script_getnum(st,3);
- bl = map_id2bl(unit_id);
- if (bl != NULL)
- clif_emotion(bl, emotion);
+ unit_id = script_getnum(st,2);
+ emotion = script_getnum(st,3);
+ bl = map_id2bl(unit_id);
+ if( bl != NULL )
+ clif_emotion(bl, emotion);
- return 0;
+ return 0;
}
/// Makes the unit cast the skill on the target or self if no target is specified
@@ -15528,22 +15378,22 @@ BUILDIN_FUNC(unitemote)
/// unitskilluseid <unit_id>,"<skill name>",<skill_lv>{,<target_id>};
BUILDIN_FUNC(unitskilluseid)
{
- int unit_id;
- int skill_id;
- int skill_lv;
- int target_id;
- struct block_list *bl;
+ int unit_id;
+ int skill_id;
+ int skill_lv;
+ int target_id;
+ struct block_list* bl;
- unit_id = script_getnum(st,2);
- skill_id = (script_isstring(st,3) ? skill_name2id(script_getstr(st,3)) : script_getnum(st,3));
- skill_lv = script_getnum(st,4);
- target_id = (script_hasdata(st,5) ? script_getnum(st,5) : unit_id);
+ unit_id = script_getnum(st,2);
+ skill_id = ( script_isstring(st,3) ? skill_name2id(script_getstr(st,3)) : script_getnum(st,3) );
+ skill_lv = script_getnum(st,4);
+ target_id = ( script_hasdata(st,5) ? script_getnum(st,5) : unit_id );
- bl = map_id2bl(unit_id);
- if (bl != NULL)
- unit_skilluse_id(bl, target_id, skill_id, skill_lv);
+ bl = map_id2bl(unit_id);
+ if( bl != NULL )
+ unit_skilluse_id(bl, target_id, skill_id, skill_lv);
- return 0;
+ return 0;
}
/// Makes the unit cast the skill on the target position.
@@ -15552,24 +15402,24 @@ BUILDIN_FUNC(unitskilluseid)
/// unitskillusepos <unit_id>,"<skill name>",<skill_lv>,<target_x>,<target_y>;
BUILDIN_FUNC(unitskillusepos)
{
- int unit_id;
- int skill_id;
- int skill_lv;
- int skill_x;
- int skill_y;
- struct block_list *bl;
+ int unit_id;
+ int skill_id;
+ int skill_lv;
+ int skill_x;
+ int skill_y;
+ struct block_list* bl;
- unit_id = script_getnum(st,2);
- skill_id = (script_isstring(st,3) ? skill_name2id(script_getstr(st,3)) : script_getnum(st,3));
- skill_lv = script_getnum(st,4);
- skill_x = script_getnum(st,5);
- skill_y = script_getnum(st,6);
+ unit_id = script_getnum(st,2);
+ skill_id = ( script_isstring(st,3) ? skill_name2id(script_getstr(st,3)) : script_getnum(st,3) );
+ skill_lv = script_getnum(st,4);
+ skill_x = script_getnum(st,5);
+ skill_y = script_getnum(st,6);
- bl = map_id2bl(unit_id);
- if (bl != NULL)
- unit_skilluse_pos(bl, skill_x, skill_y, skill_id, skill_lv);
+ bl = map_id2bl(unit_id);
+ if( bl != NULL )
+ unit_skilluse_pos(bl, skill_x, skill_y, skill_id, skill_lv);
- return 0;
+ return 0;
}
// <--- [zBuffer] List of mob control commands
@@ -15579,25 +15429,27 @@ BUILDIN_FUNC(unitskillusepos)
/// sleep <mili seconds>;
BUILDIN_FUNC(sleep)
{
- int ticks;
+ int ticks;
- ticks = script_getnum(st,2);
+ ticks = script_getnum(st,2);
- // detach the player
- script_detach_rid(st);
+ // detach the player
+ script_detach_rid(st);
- if (ticks <= 0) {
- // do nothing
- } else if (st->sleep.tick == 0) {
- // sleep for the target amount of time
- st->state = RERUNLINE;
- st->sleep.tick = ticks;
- } else {
- // sleep time is over
- st->state = RUN;
- st->sleep.tick = 0;
- }
- return 0;
+ if( ticks <= 0 )
+ {// do nothing
+ }
+ else if( st->sleep.tick == 0 )
+ {// sleep for the target amount of time
+ st->state = RERUNLINE;
+ st->sleep.tick = ticks;
+ }
+ else
+ {// sleep time is over
+ st->state = RUN;
+ st->sleep.tick = 0;
+ }
+ return 0;
}
/// Pauses the execution of the script, keeping the player attached
@@ -15606,24 +15458,26 @@ BUILDIN_FUNC(sleep)
/// sleep2(<mili secconds>) -> <bool>
BUILDIN_FUNC(sleep2)
{
- int ticks;
-
- ticks = script_getnum(st,2);
-
- if (ticks <= 0) {
- // do nothing
- script_pushint(st, (map_id2sd(st->rid)!=NULL));
- } else if (!st->sleep.tick) {
- // sleep for the target amount of time
- st->state = RERUNLINE;
- st->sleep.tick = ticks;
- } else {
- // sleep time is over
- st->state = RUN;
- st->sleep.tick = 0;
- script_pushint(st, (map_id2sd(st->rid)!=NULL));
- }
- return 0;
+ int ticks;
+
+ ticks = script_getnum(st,2);
+
+ if( ticks <= 0 )
+ {// do nothing
+ script_pushint(st, (map_id2sd(st->rid)!=NULL));
+ }
+ else if( !st->sleep.tick )
+ {// sleep for the target amount of time
+ st->state = RERUNLINE;
+ st->sleep.tick = ticks;
+ }
+ else
+ {// sleep time is over
+ st->state = RUN;
+ st->sleep.tick = 0;
+ script_pushint(st, (map_id2sd(st->rid)!=NULL));
+ }
+ return 0;
}
/// Awakes all the sleep timers of the target npc
@@ -15631,43 +15485,46 @@ BUILDIN_FUNC(sleep2)
/// awake "<npc name>";
BUILDIN_FUNC(awake)
{
- struct npc_data *nd;
- struct linkdb_node *node = (struct linkdb_node *)sleep_db;
-
- nd = npc_name2id(script_getstr(st, 2));
- if (nd == NULL) {
- ShowError("awake: NPC \"%s\" not found\n", script_getstr(st, 2));
- return 1;
- }
-
- while (node) {
- if ((int)__64BPRTSIZE(node->key) == nd->bl.id) {
- // sleep timer for the npc
- struct script_state *tst = (struct script_state *)node->data;
- TBL_PC *sd = map_id2sd(tst->rid);
-
- if (tst->sleep.timer == INVALID_TIMER) {
- // already awake ???
- node = node->next;
- continue;
- }
- if ((sd && sd->status.char_id != tst->sleep.charid) || (tst->rid && !sd)) {
- // char not online anymore / another char of the same account is online - Cancel execution
- tst->state = END;
- tst->rid = 0;
- }
-
- delete_timer(tst->sleep.timer, run_script_timer);
- node = script_erase_sleepdb(node);
- tst->sleep.timer = INVALID_TIMER;
- if (tst->state != RERUNLINE)
- tst->sleep.tick = 0;
- run_script_main(tst);
- } else {
- node = node->next;
- }
- }
- return 0;
+ struct npc_data* nd;
+ struct linkdb_node *node = (struct linkdb_node *)sleep_db;
+
+ nd = npc_name2id(script_getstr(st, 2));
+ if( nd == NULL ) {
+ ShowError("awake: NPC \"%s\" not found\n", script_getstr(st, 2));
+ return 1;
+ }
+
+ while( node )
+ {
+ if( (int)__64BPRTSIZE(node->key) == nd->bl.id )
+ {// sleep timer for the npc
+ struct script_state* tst = (struct script_state*)node->data;
+ TBL_PC* sd = map_id2sd(tst->rid);
+
+ if( tst->sleep.timer == INVALID_TIMER )
+ {// already awake ???
+ node = node->next;
+ continue;
+ }
+ if( (sd && sd->status.char_id != tst->sleep.charid) || (tst->rid && !sd))
+ {// char not online anymore / another char of the same account is online - Cancel execution
+ tst->state = END;
+ tst->rid = 0;
+ }
+
+ delete_timer(tst->sleep.timer, run_script_timer);
+ node = script_erase_sleepdb(node);
+ tst->sleep.timer = INVALID_TIMER;
+ if(tst->state != RERUNLINE)
+ tst->sleep.tick = 0;
+ run_script_main(tst);
+ }
+ else
+ {
+ node = node->next;
+ }
+ }
+ return 0;
}
/// Returns a reference to a variable of the target NPC.
@@ -15676,41 +15533,41 @@ BUILDIN_FUNC(awake)
/// getvariableofnpc(<variable>, "<npc name>") -> <reference>
BUILDIN_FUNC(getvariableofnpc)
{
- struct script_data *data;
- const char *name;
- struct npc_data *nd;
-
- data = script_getdata(st,2);
- if (!data_isreference(data)) {
- // Not a reference (aka varaible name)
- ShowError("script:getvariableofnpc: not a variable\n");
- script_reportdata(data);
- script_pushnil(st);
- st->state = END;
- return 1;
- }
-
- name = reference_getname(data);
- if (*name != '.' || name[1] == '@') {
- // not a npc variable
- ShowError("script:getvariableofnpc: invalid scope (not npc variable)\n");
- script_reportdata(data);
- script_pushnil(st);
- st->state = END;
- return 1;
- }
-
- nd = npc_name2id(script_getstr(st,3));
- if (nd == NULL || nd->subtype != SCRIPT || nd->u.scr.script == NULL) {
- // NPC not found or has no script
- ShowError("script:getvariableofnpc: can't find npc %s\n", script_getstr(st,3));
- script_pushnil(st);
- st->state = END;
- return 1;
- }
-
- push_val2(st->stack, C_NAME, reference_getuid(data), &nd->u.scr.script->script_vars);
- return 0;
+ struct script_data* data;
+ const char* name;
+ struct npc_data* nd;
+
+ data = script_getdata(st,2);
+ if( !data_isreference(data) )
+ {// Not a reference (aka varaible name)
+ ShowError("script:getvariableofnpc: not a variable\n");
+ script_reportdata(data);
+ script_pushnil(st);
+ st->state = END;
+ return 1;
+ }
+
+ name = reference_getname(data);
+ if( *name != '.' || name[1] == '@' )
+ {// not a npc variable
+ ShowError("script:getvariableofnpc: invalid scope (not npc variable)\n");
+ script_reportdata(data);
+ script_pushnil(st);
+ st->state = END;
+ return 1;
+ }
+
+ nd = npc_name2id(script_getstr(st,3));
+ if( nd == NULL || nd->subtype != SCRIPT || nd->u.scr.script == NULL )
+ {// NPC not found or has no script
+ ShowError("script:getvariableofnpc: can't find npc %s\n", script_getstr(st,3));
+ script_pushnil(st);
+ st->state = END;
+ return 1;
+ }
+
+ push_val2(st->stack, C_NAME, reference_getuid(data), &nd->u.scr.script->script_vars );
+ return 0;
}
/// Opens a warp portal.
@@ -15721,62 +15578,63 @@ BUILDIN_FUNC(getvariableofnpc)
/// @author blackhole89
BUILDIN_FUNC(warpportal)
{
- int spx;
- int spy;
- unsigned short mapindex;
- int tpx;
- int tpy;
- struct skill_unit_group *group;
- struct block_list *bl;
-
- bl = map_id2bl(st->oid);
- if (bl == NULL) {
- ShowError("script:warpportal: npc is needed\n");
- return 1;
- }
+ int spx;
+ int spy;
+ unsigned short mapindex;
+ int tpx;
+ int tpy;
+ struct skill_unit_group* group;
+ struct block_list* bl;
- spx = script_getnum(st,2);
- spy = script_getnum(st,3);
- mapindex = mapindex_name2id(script_getstr(st, 4));
- tpx = script_getnum(st,5);
- tpy = script_getnum(st,6);
+ bl = map_id2bl(st->oid);
+ if( bl == NULL )
+ {
+ ShowError("script:warpportal: npc is needed\n");
+ return 1;
+ }
- if (mapindex == 0)
- return 0;// map not found
+ spx = script_getnum(st,2);
+ spy = script_getnum(st,3);
+ mapindex = mapindex_name2id(script_getstr(st, 4));
+ tpx = script_getnum(st,5);
+ tpy = script_getnum(st,6);
- group = skill_unitsetting(bl, AL_WARP, 4, spx, spy, 0);
- if (group == NULL)
- return 0;// failed
- group->val2 = (tpx<<16) | tpy;
- group->val3 = mapindex;
+ if( mapindex == 0 )
+ return 0;// map not found
- return 0;
+ group = skill_unitsetting(bl, AL_WARP, 4, spx, spy, 0);
+ if( group == NULL )
+ return 0;// failed
+ group->val2 = (tpx<<16) | tpy;
+ group->val3 = mapindex;
+
+ return 0;
}
BUILDIN_FUNC(openmail)
{
- TBL_PC *sd;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- mail_openmail(sd);
+ mail_openmail(sd);
- return 0;
+ return 0;
}
BUILDIN_FUNC(openauction)
{
- TBL_PC *sd;
+ TBL_PC* sd;
- sd = script_rid2sd(st);
- if (sd == NULL)
- return 0;
+ sd = script_rid2sd(st);
+ if( sd == NULL )
+ return 0;
- clif_Auction_openwindow(sd);
+ clif_Auction_openwindow(sd);
- return 0;
+ return 0;
}
/// Retrieves the value of the specified flag of the specified cell.
@@ -15786,14 +15644,14 @@ BUILDIN_FUNC(openauction)
/// @see cell_chk* constants in const.txt for the types
BUILDIN_FUNC(checkcell)
{
- int m = map_mapname2mapid(script_getstr(st,2));
- int x = script_getnum(st,3);
- int y = script_getnum(st,4);
- cell_chk type = (cell_chk)script_getnum(st,5);
+ int m = map_mapname2mapid(script_getstr(st,2));
+ int x = script_getnum(st,3);
+ int y = script_getnum(st,4);
+ cell_chk type = (cell_chk)script_getnum(st,5);
- script_pushint(st, map_getcell(m, x, y, type));
+ script_pushint(st, map_getcell(m, x, y, type));
- return 0;
+ return 0;
}
/// Modifies flags of cells in the specified area.
@@ -15803,24 +15661,24 @@ BUILDIN_FUNC(checkcell)
/// @see cell_* constants in const.txt for the types
BUILDIN_FUNC(setcell)
{
- int m = map_mapname2mapid(script_getstr(st,2));
- int x1 = script_getnum(st,3);
- int y1 = script_getnum(st,4);
- int x2 = script_getnum(st,5);
- int y2 = script_getnum(st,6);
- cell_t type = (cell_t)script_getnum(st,7);
- bool flag = (bool)script_getnum(st,8);
+ int m = map_mapname2mapid(script_getstr(st,2));
+ int x1 = script_getnum(st,3);
+ int y1 = script_getnum(st,4);
+ int x2 = script_getnum(st,5);
+ int y2 = script_getnum(st,6);
+ cell_t type = (cell_t)script_getnum(st,7);
+ bool flag = (bool)script_getnum(st,8);
- int x,y;
+ int x,y;
- if (x1 > x2) swap(x1,x2);
- if (y1 > y2) swap(y1,y2);
+ if( x1 > x2 ) swap(x1,x2);
+ if( y1 > y2 ) swap(y1,y2);
- for (y = y1; y <= y2; ++y)
- for (x = x1; x <= x2; ++x)
- map_setcell(m, x, y, type, flag);
+ for( y = y1; y <= y2; ++y )
+ for( x = x1; x <= x2; ++x )
+ map_setcell(m, x, y, type, flag);
- return 0;
+ return 0;
}
/*==========================================
@@ -15828,169 +15686,173 @@ BUILDIN_FUNC(setcell)
*------------------------------------------*/
BUILDIN_FUNC(mercenary_create)
{
- struct map_session_data *sd;
- int class_, contract_time;
+ struct map_session_data *sd;
+ int class_, contract_time;
- if ((sd = script_rid2sd(st)) == NULL || sd->md || sd->status.mer_id != 0)
- return 0;
+ if( (sd = script_rid2sd(st)) == NULL || sd->md || sd->status.mer_id != 0 )
+ return 0;
- class_ = script_getnum(st,2);
+ class_ = script_getnum(st,2);
- if (!merc_class(class_))
- return 0;
+ if( !merc_class(class_) )
+ return 0;
- contract_time = script_getnum(st,3);
- merc_create(sd, class_, contract_time);
- return 0;
+ contract_time = script_getnum(st,3);
+ merc_create(sd, class_, contract_time);
+ return 0;
}
BUILDIN_FUNC(mercenary_heal)
{
- struct map_session_data *sd = script_rid2sd(st);
- int hp, sp;
+ struct map_session_data *sd = script_rid2sd(st);
+ int hp, sp;
- if (sd == NULL || sd->md == NULL)
- return 0;
- hp = script_getnum(st,2);
- sp = script_getnum(st,3);
+ if( sd == NULL || sd->md == NULL )
+ return 0;
+ hp = script_getnum(st,2);
+ sp = script_getnum(st,3);
- status_heal(&sd->md->bl, hp, sp, 0);
- return 0;
+ status_heal(&sd->md->bl, hp, sp, 0);
+ return 0;
}
BUILDIN_FUNC(mercenary_sc_start)
{
- struct map_session_data *sd = script_rid2sd(st);
- enum sc_type type;
- int tick, val1;
+ struct map_session_data *sd = script_rid2sd(st);
+ enum sc_type type;
+ int tick, val1;
- if (sd == NULL || sd->md == NULL)
- return 0;
+ if( sd == NULL || sd->md == NULL )
+ return 0;
- type = (sc_type)script_getnum(st,2);
- tick = script_getnum(st,3);
- val1 = script_getnum(st,4);
+ type = (sc_type)script_getnum(st,2);
+ tick = script_getnum(st,3);
+ val1 = script_getnum(st,4);
- status_change_start(&sd->md->bl, type, 10000, val1, 0, 0, 0, tick, 2);
- return 0;
+ status_change_start(&sd->md->bl, type, 10000, val1, 0, 0, 0, tick, 2);
+ return 0;
}
BUILDIN_FUNC(mercenary_get_calls)
{
- struct map_session_data *sd = script_rid2sd(st);
- int guild;
+ struct map_session_data *sd = script_rid2sd(st);
+ int guild;
- if (sd == NULL)
- return 0;
+ if( sd == NULL )
+ return 0;
- guild = script_getnum(st,2);
- switch (guild) {
- case ARCH_MERC_GUILD:
- script_pushint(st,sd->status.arch_calls);
- break;
- case SPEAR_MERC_GUILD:
- script_pushint(st,sd->status.spear_calls);
- break;
- case SWORD_MERC_GUILD:
- script_pushint(st,sd->status.sword_calls);
- break;
- default:
- script_pushint(st,0);
- break;
- }
+ guild = script_getnum(st,2);
+ switch( guild )
+ {
+ case ARCH_MERC_GUILD:
+ script_pushint(st,sd->status.arch_calls);
+ break;
+ case SPEAR_MERC_GUILD:
+ script_pushint(st,sd->status.spear_calls);
+ break;
+ case SWORD_MERC_GUILD:
+ script_pushint(st,sd->status.sword_calls);
+ break;
+ default:
+ script_pushint(st,0);
+ break;
+ }
- return 0;
+ return 0;
}
BUILDIN_FUNC(mercenary_set_calls)
{
- struct map_session_data *sd = script_rid2sd(st);
- int guild, value, *calls;
+ struct map_session_data *sd = script_rid2sd(st);
+ int guild, value, *calls;
- if (sd == NULL)
- return 0;
+ if( sd == NULL )
+ return 0;
- guild = script_getnum(st,2);
- value = script_getnum(st,3);
-
- switch (guild) {
- case ARCH_MERC_GUILD:
- calls = &sd->status.arch_calls;
- break;
- case SPEAR_MERC_GUILD:
- calls = &sd->status.spear_calls;
- break;
- case SWORD_MERC_GUILD:
- calls = &sd->status.sword_calls;
- break;
- default:
- return 0; // Invalid Guild
- }
+ guild = script_getnum(st,2);
+ value = script_getnum(st,3);
- *calls += value;
- *calls = cap_value(*calls, 0, INT_MAX);
+ switch( guild )
+ {
+ case ARCH_MERC_GUILD:
+ calls = &sd->status.arch_calls;
+ break;
+ case SPEAR_MERC_GUILD:
+ calls = &sd->status.spear_calls;
+ break;
+ case SWORD_MERC_GUILD:
+ calls = &sd->status.sword_calls;
+ break;
+ default:
+ return 0; // Invalid Guild
+ }
- return 0;
+ *calls += value;
+ *calls = cap_value(*calls, 0, INT_MAX);
+
+ return 0;
}
BUILDIN_FUNC(mercenary_get_faith)
{
- struct map_session_data *sd = script_rid2sd(st);
- int guild;
+ struct map_session_data *sd = script_rid2sd(st);
+ int guild;
- if (sd == NULL)
- return 0;
+ if( sd == NULL )
+ return 0;
- guild = script_getnum(st,2);
- switch (guild) {
- case ARCH_MERC_GUILD:
- script_pushint(st,sd->status.arch_faith);
- break;
- case SPEAR_MERC_GUILD:
- script_pushint(st,sd->status.spear_faith);
- break;
- case SWORD_MERC_GUILD:
- script_pushint(st,sd->status.sword_faith);
- break;
- default:
- script_pushint(st,0);
- break;
- }
+ guild = script_getnum(st,2);
+ switch( guild )
+ {
+ case ARCH_MERC_GUILD:
+ script_pushint(st,sd->status.arch_faith);
+ break;
+ case SPEAR_MERC_GUILD:
+ script_pushint(st,sd->status.spear_faith);
+ break;
+ case SWORD_MERC_GUILD:
+ script_pushint(st,sd->status.sword_faith);
+ break;
+ default:
+ script_pushint(st,0);
+ break;
+ }
- return 0;
+ return 0;
}
BUILDIN_FUNC(mercenary_set_faith)
{
- struct map_session_data *sd = script_rid2sd(st);
- int guild, value, *calls;
+ struct map_session_data *sd = script_rid2sd(st);
+ int guild, value, *calls;
- if (sd == NULL)
- return 0;
+ if( sd == NULL )
+ return 0;
- guild = script_getnum(st,2);
- value = script_getnum(st,3);
-
- switch (guild) {
- case ARCH_MERC_GUILD:
- calls = &sd->status.arch_faith;
- break;
- case SPEAR_MERC_GUILD:
- calls = &sd->status.spear_faith;
- break;
- case SWORD_MERC_GUILD:
- calls = &sd->status.sword_faith;
- break;
- default:
- return 0; // Invalid Guild
- }
+ guild = script_getnum(st,2);
+ value = script_getnum(st,3);
- *calls += value;
- *calls = cap_value(*calls, 0, INT_MAX);
- if (mercenary_get_guild(sd->md) == guild)
- clif_mercenary_updatestatus(sd,SP_MERCFAITH);
+ switch( guild )
+ {
+ case ARCH_MERC_GUILD:
+ calls = &sd->status.arch_faith;
+ break;
+ case SPEAR_MERC_GUILD:
+ calls = &sd->status.spear_faith;
+ break;
+ case SWORD_MERC_GUILD:
+ calls = &sd->status.sword_faith;
+ break;
+ default:
+ return 0; // Invalid Guild
+ }
- return 0;
+ *calls += value;
+ *calls = cap_value(*calls, 0, INT_MAX);
+ if( mercenary_get_guild(sd->md) == guild )
+ clif_mercenary_updatestatus(sd,SP_MERCFAITH);
+
+ return 0;
}
/*------------------------------------------
@@ -15998,17 +15860,17 @@ BUILDIN_FUNC(mercenary_set_faith)
*------------------------------------------*/
BUILDIN_FUNC(readbook)
{
- struct map_session_data *sd;
- int book_id, page;
+ struct map_session_data *sd;
+ int book_id, page;
- if ((sd = script_rid2sd(st)) == NULL)
- return 0;
+ if( (sd = script_rid2sd(st)) == NULL )
+ return 0;
- book_id = script_getnum(st,2);
- page = script_getnum(st,3);
+ book_id = script_getnum(st,2);
+ page = script_getnum(st,3);
- clif_readbook(sd->fd, book_id, page);
- return 0;
+ clif_readbook(sd->fd, book_id, page);
+ return 0;
}
/******************
@@ -16017,71 +15879,71 @@ Questlog script commands
BUILDIN_FUNC(setquest)
{
- struct map_session_data *sd = script_rid2sd(st);
- nullpo_ret(sd);
+ struct map_session_data *sd = script_rid2sd(st);
+ nullpo_ret(sd);
- quest_add(sd, script_getnum(st, 2));
- return 0;
+ quest_add(sd, script_getnum(st, 2));
+ return 0;
}
BUILDIN_FUNC(erasequest)
{
- struct map_session_data *sd = script_rid2sd(st);
- nullpo_ret(sd);
+ struct map_session_data *sd = script_rid2sd(st);
+ nullpo_ret(sd);
- quest_delete(sd, script_getnum(st, 2));
- return 0;
+ quest_delete(sd, script_getnum(st, 2));
+ return 0;
}
BUILDIN_FUNC(completequest)
{
- struct map_session_data *sd = script_rid2sd(st);
- nullpo_ret(sd);
+ struct map_session_data *sd = script_rid2sd(st);
+ nullpo_ret(sd);
- quest_update_status(sd, script_getnum(st, 2), Q_COMPLETE);
- return 0;
+ quest_update_status(sd, script_getnum(st, 2), Q_COMPLETE);
+ return 0;
}
BUILDIN_FUNC(changequest)
{
- struct map_session_data *sd = script_rid2sd(st);
- nullpo_ret(sd);
+ struct map_session_data *sd = script_rid2sd(st);
+ nullpo_ret(sd);
- quest_change(sd, script_getnum(st, 2),script_getnum(st, 3));
- return 0;
+ quest_change(sd, script_getnum(st, 2),script_getnum(st, 3));
+ return 0;
}
BUILDIN_FUNC(checkquest)
{
- struct map_session_data *sd = script_rid2sd(st);
- quest_check_type type = HAVEQUEST;
+ struct map_session_data *sd = script_rid2sd(st);
+ quest_check_type type = HAVEQUEST;
- nullpo_ret(sd);
+ nullpo_ret(sd);
- if (script_hasdata(st, 3))
- type = (quest_check_type)script_getnum(st, 3);
+ if( script_hasdata(st, 3) )
+ type = (quest_check_type)script_getnum(st, 3);
- script_pushint(st, quest_check(sd, script_getnum(st, 2), type));
+ script_pushint(st, quest_check(sd, script_getnum(st, 2), type));
- return 0;
+ return 0;
}
BUILDIN_FUNC(showevent)
{
- TBL_PC *sd = script_rid2sd(st);
- struct npc_data *nd = map_id2nd(st->oid);
- int state, color;
+ TBL_PC *sd = script_rid2sd(st);
+ struct npc_data *nd = map_id2nd(st->oid);
+ int state, color;
- if (sd == NULL || nd == NULL)
- return 0;
- state = script_getnum(st, 2);
- color = script_getnum(st, 3);
+ if( sd == NULL || nd == NULL )
+ return 0;
+ state = script_getnum(st, 2);
+ color = script_getnum(st, 3);
- if (color < 0 || color > 3)
- color = 0; // set default color
+ if( color < 0 || color > 3 )
+ color = 0; // set default color
- clif_quest_show_event(sd, &nd->bl, state, color);
- return 0;
+ clif_quest_show_event(sd, &nd->bl, state, color);
+ return 0;
}
/*==========================================
@@ -16089,241 +15951,248 @@ BUILDIN_FUNC(showevent)
*------------------------------------------*/
BUILDIN_FUNC(waitingroom2bg)
{
- struct npc_data *nd;
- struct chat_data *cd;
- const char *map_name, *ev = "", *dev = "";
- int x, y, i, mapindex = 0, bg_id, n;
- struct map_session_data *sd;
-
- if (script_hasdata(st,7))
- nd = npc_name2id(script_getstr(st,7));
- else
- nd = (struct npc_data *)map_id2bl(st->oid);
-
- if (nd == NULL || (cd = (struct chat_data *)map_id2bl(nd->chat_id)) == NULL) {
- script_pushint(st,0);
- return 0;
- }
-
- map_name = script_getstr(st,2);
- if (strcmp(map_name,"-") != 0) {
- mapindex = mapindex_name2id(map_name);
- if (mapindex == 0) {
- // Invalid Map
- script_pushint(st,0);
- return 0;
- }
- }
-
- x = script_getnum(st,3);
- y = script_getnum(st,4);
- ev = script_getstr(st,5); // Logout Event
- dev = script_getstr(st,6); // Die Event
-
- if ((bg_id = bg_create(mapindex, x, y, ev, dev)) == 0) {
- // Creation failed
- script_pushint(st,0);
- return 0;
- }
-
- n = cd->users;
- for (i = 0; i < n && i < MAX_BG_MEMBERS; i++) {
- if ((sd = cd->usersd[i]) != NULL && bg_team_join(bg_id, sd))
- mapreg_setreg(reference_uid(add_str("$@arenamembers"), i), sd->bl.id);
- else
- mapreg_setreg(reference_uid(add_str("$@arenamembers"), i), 0);
- }
-
- mapreg_setreg(add_str("$@arenamembersnum"), i);
- script_pushint(st,bg_id);
- return 0;
+ struct npc_data *nd;
+ struct chat_data *cd;
+ const char *map_name, *ev = "", *dev = "";
+ int x, y, i, mapindex = 0, bg_id, n;
+ struct map_session_data *sd;
+
+ if( script_hasdata(st,7) )
+ nd = npc_name2id(script_getstr(st,7));
+ else
+ nd = (struct npc_data *)map_id2bl(st->oid);
+
+ if( nd == NULL || (cd = (struct chat_data *)map_id2bl(nd->chat_id)) == NULL )
+ {
+ script_pushint(st,0);
+ return 0;
+ }
+
+ map_name = script_getstr(st,2);
+ if( strcmp(map_name,"-") != 0 )
+ {
+ mapindex = mapindex_name2id(map_name);
+ if( mapindex == 0 )
+ { // Invalid Map
+ script_pushint(st,0);
+ return 0;
+ }
+ }
+
+ x = script_getnum(st,3);
+ y = script_getnum(st,4);
+ ev = script_getstr(st,5); // Logout Event
+ dev = script_getstr(st,6); // Die Event
+
+ if( (bg_id = bg_create(mapindex, x, y, ev, dev)) == 0 )
+ { // Creation failed
+ script_pushint(st,0);
+ return 0;
+ }
+
+ n = cd->users;
+ for( i = 0; i < n && i < MAX_BG_MEMBERS; i++ )
+ {
+ if( (sd = cd->usersd[i]) != NULL && bg_team_join(bg_id, sd) )
+ mapreg_setreg(reference_uid(add_str("$@arenamembers"), i), sd->bl.id);
+ else
+ mapreg_setreg(reference_uid(add_str("$@arenamembers"), i), 0);
+ }
+
+ mapreg_setreg(add_str("$@arenamembersnum"), i);
+ script_pushint(st,bg_id);
+ return 0;
}
BUILDIN_FUNC(waitingroom2bg_single)
{
- const char *map_name;
- struct npc_data *nd;
- struct chat_data *cd;
- struct map_session_data *sd;
- int x, y, mapindex, bg_id;
+ const char* map_name;
+ struct npc_data *nd;
+ struct chat_data *cd;
+ struct map_session_data *sd;
+ int x, y, mapindex, bg_id;
- bg_id = script_getnum(st,2);
- map_name = script_getstr(st,3);
- if ((mapindex = mapindex_name2id(map_name)) == 0)
- return 0; // Invalid Map
+ bg_id = script_getnum(st,2);
+ map_name = script_getstr(st,3);
+ if( (mapindex = mapindex_name2id(map_name)) == 0 )
+ return 0; // Invalid Map
- x = script_getnum(st,4);
- y = script_getnum(st,5);
- nd = npc_name2id(script_getstr(st,6));
+ x = script_getnum(st,4);
+ y = script_getnum(st,5);
+ nd = npc_name2id(script_getstr(st,6));
- if (nd == NULL || (cd = (struct chat_data *)map_id2bl(nd->chat_id)) == NULL || cd->users <= 0)
- return 0;
+ if( nd == NULL || (cd = (struct chat_data *)map_id2bl(nd->chat_id)) == NULL || cd->users <= 0 )
+ return 0;
- if ((sd = cd->usersd[0]) == NULL)
- return 0;
+ if( (sd = cd->usersd[0]) == NULL )
+ return 0;
- if (bg_team_join(bg_id, sd)) {
- pc_setpos(sd, mapindex, x, y, CLR_TELEPORT);
- script_pushint(st,1);
- } else
- script_pushint(st,0);
+ if( bg_team_join(bg_id, sd) )
+ {
+ pc_setpos(sd, mapindex, x, y, CLR_TELEPORT);
+ script_pushint(st,1);
+ }
+ else
+ script_pushint(st,0);
- return 0;
+ return 0;
}
BUILDIN_FUNC(bg_team_setxy)
{
- struct battleground_data *bg;
- int bg_id;
+ struct battleground_data *bg;
+ int bg_id;
- bg_id = script_getnum(st,2);
- if ((bg = bg_team_search(bg_id)) == NULL)
- return 0;
+ bg_id = script_getnum(st,2);
+ if( (bg = bg_team_search(bg_id)) == NULL )
+ return 0;
- bg->x = script_getnum(st,3);
- bg->y = script_getnum(st,4);
- return 0;
+ bg->x = script_getnum(st,3);
+ bg->y = script_getnum(st,4);
+ return 0;
}
BUILDIN_FUNC(bg_warp)
{
- int x, y, mapindex, bg_id;
- const char *map_name;
+ int x, y, mapindex, bg_id;
+ const char* map_name;
- bg_id = script_getnum(st,2);
- map_name = script_getstr(st,3);
- if ((mapindex = mapindex_name2id(map_name)) == 0)
- return 0; // Invalid Map
- x = script_getnum(st,4);
- y = script_getnum(st,5);
- bg_team_warp(bg_id, mapindex, x, y);
- return 0;
+ bg_id = script_getnum(st,2);
+ map_name = script_getstr(st,3);
+ if( (mapindex = mapindex_name2id(map_name)) == 0 )
+ return 0; // Invalid Map
+ x = script_getnum(st,4);
+ y = script_getnum(st,5);
+ bg_team_warp(bg_id, mapindex, x, y);
+ return 0;
}
BUILDIN_FUNC(bg_monster)
{
- int class_ = 0, x = 0, y = 0, bg_id = 0;
- const char *str,*map, *evt="";
-
- bg_id = script_getnum(st,2);
- map = script_getstr(st,3);
- x = script_getnum(st,4);
- y = script_getnum(st,5);
- str = script_getstr(st,6);
- class_ = script_getnum(st,7);
- if (script_hasdata(st,8)) evt = script_getstr(st,8);
- check_event(st, evt);
- script_pushint(st, mob_spawn_bg(map,x,y,str,class_,evt,bg_id));
- return 0;
+ int class_ = 0, x = 0, y = 0, bg_id = 0;
+ const char *str,*map, *evt="";
+
+ bg_id = script_getnum(st,2);
+ map = script_getstr(st,3);
+ x = script_getnum(st,4);
+ y = script_getnum(st,5);
+ str = script_getstr(st,6);
+ class_ = script_getnum(st,7);
+ if( script_hasdata(st,8) ) evt = script_getstr(st,8);
+ check_event(st, evt);
+ script_pushint(st, mob_spawn_bg(map,x,y,str,class_,evt,bg_id));
+ return 0;
}
BUILDIN_FUNC(bg_monster_set_team)
{
- struct mob_data *md;
- struct block_list *mbl;
- int id = script_getnum(st,2),
- bg_id = script_getnum(st,3);
+ struct mob_data *md;
+ struct block_list *mbl;
+ int id = script_getnum(st,2),
+ bg_id = script_getnum(st,3);
- if ((mbl = map_id2bl(id)) == NULL || mbl->type != BL_MOB)
- return 0;
- md = (TBL_MOB *)mbl;
- md->bg_id = bg_id;
+ if( (mbl = map_id2bl(id)) == NULL || mbl->type != BL_MOB )
+ return 0;
+ md = (TBL_MOB *)mbl;
+ md->bg_id = bg_id;
- mob_stop_attack(md);
- mob_stop_walking(md, 0);
- md->target_id = md->attacked_id = 0;
- clif_charnameack(0, &md->bl);
+ mob_stop_attack(md);
+ mob_stop_walking(md, 0);
+ md->target_id = md->attacked_id = 0;
+ clif_charnameack(0, &md->bl);
- return 0;
+ return 0;
}
BUILDIN_FUNC(bg_leave)
{
- struct map_session_data *sd = script_rid2sd(st);
- if (sd == NULL || !sd->bg_id)
- return 0;
+ struct map_session_data *sd = script_rid2sd(st);
+ if( sd == NULL || !sd->bg_id )
+ return 0;
- bg_team_leave(sd,0);
- return 0;
+ bg_team_leave(sd,0);
+ return 0;
}
BUILDIN_FUNC(bg_destroy)
{
- int bg_id = script_getnum(st,2);
- bg_team_delete(bg_id);
- return 0;
+ int bg_id = script_getnum(st,2);
+ bg_team_delete(bg_id);
+ return 0;
}
BUILDIN_FUNC(bg_getareausers)
{
- const char *str;
- int m, x0, y0, x1, y1, bg_id;
- int i = 0, c = 0;
- struct battleground_data *bg = NULL;
- struct map_session_data *sd;
+ const char *str;
+ int m, x0, y0, x1, y1, bg_id;
+ int i = 0, c = 0;
+ struct battleground_data *bg = NULL;
+ struct map_session_data *sd;
- bg_id = script_getnum(st,2);
- str = script_getstr(st,3);
+ bg_id = script_getnum(st,2);
+ str = script_getstr(st,3);
- if ((bg = bg_team_search(bg_id)) == NULL || (m = map_mapname2mapid(str)) < 0) {
- script_pushint(st,0);
- return 0;
- }
+ if( (bg = bg_team_search(bg_id)) == NULL || (m = map_mapname2mapid(str)) < 0 )
+ {
+ script_pushint(st,0);
+ return 0;
+ }
- x0 = script_getnum(st,4);
- y0 = script_getnum(st,5);
- x1 = script_getnum(st,6);
- y1 = script_getnum(st,7);
+ x0 = script_getnum(st,4);
+ y0 = script_getnum(st,5);
+ x1 = script_getnum(st,6);
+ y1 = script_getnum(st,7);
- for (i = 0; i < MAX_BG_MEMBERS; i++) {
- if ((sd = bg->members[i].sd) == NULL)
- continue;
- if (sd->bl.m != m || sd->bl.x < x0 || sd->bl.y < y0 || sd->bl.x > x1 || sd->bl.y > y1)
- continue;
- c++;
- }
+ for( i = 0; i < MAX_BG_MEMBERS; i++ )
+ {
+ if( (sd = bg->members[i].sd) == NULL )
+ continue;
+ if( sd->bl.m != m || sd->bl.x < x0 || sd->bl.y < y0 || sd->bl.x > x1 || sd->bl.y > y1 )
+ continue;
+ c++;
+ }
- script_pushint(st,c);
- return 0;
+ script_pushint(st,c);
+ return 0;
}
BUILDIN_FUNC(bg_updatescore)
{
- const char *str;
- int m;
+ const char *str;
+ int m;
- str = script_getstr(st,2);
- if ((m = map_mapname2mapid(str)) < 0)
- return 0;
+ str = script_getstr(st,2);
+ if( (m = map_mapname2mapid(str)) < 0 )
+ return 0;
- map[m].bgscore_lion = script_getnum(st,3);
- map[m].bgscore_eagle = script_getnum(st,4);
+ map[m].bgscore_lion = script_getnum(st,3);
+ map[m].bgscore_eagle = script_getnum(st,4);
- clif_bg_updatescore(m);
- return 0;
+ clif_bg_updatescore(m);
+ return 0;
}
BUILDIN_FUNC(bg_get_data)
{
- struct battleground_data *bg;
- int bg_id = script_getnum(st,2),
- type = script_getnum(st,3);
+ struct battleground_data *bg;
+ int bg_id = script_getnum(st,2),
+ type = script_getnum(st,3);
- if ((bg = bg_team_search(bg_id)) == NULL) {
- script_pushint(st,0);
- return 0;
- }
+ if( (bg = bg_team_search(bg_id)) == NULL )
+ {
+ script_pushint(st,0);
+ return 0;
+ }
- switch (type) {
- case 0:
- script_pushint(st, bg->count);
- break;
- default:
- ShowError("script:bg_get_data: unknown data identifier %d\n", type);
- break;
- }
+ switch( type )
+ {
+ case 0: script_pushint(st, bg->count); break;
+ default:
+ ShowError("script:bg_get_data: unknown data identifier %d\n", type);
+ break;
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -16332,299 +16201,306 @@ BUILDIN_FUNC(bg_get_data)
BUILDIN_FUNC(instance_create)
{
- const char *name;
- int party_id, res;
-
- name = script_getstr(st, 2);
- party_id = script_getnum(st, 3);
-
- res = instance_create(party_id, name);
- if (res == -4) { // Already exists
- script_pushint(st, -1);
- return 0;
- } else if (res < 0) {
- const char *err;
- switch (res) {
- case -3:
- err = "No free instances";
- break;
- case -2:
- err = "Invalid party ID";
- break;
- case -1:
- err = "Invalid type";
- break;
- default:
- err = "Unknown";
- break;
- }
- ShowError("buildin_instance_create: %s [%d].\n", err, res);
- script_pushint(st, -2);
- return 0;
- }
-
- script_pushint(st, res);
- return 0;
+ const char *name;
+ int party_id, res;
+
+ name = script_getstr(st, 2);
+ party_id = script_getnum(st, 3);
+
+ res = instance_create(party_id, name);
+ if( res == -4 ) // Already exists
+ {
+ script_pushint(st, -1);
+ return 0;
+ }
+ else if( res < 0 )
+ {
+ const char *err;
+ switch(res)
+ {
+ case -3: err = "No free instances"; break;
+ case -2: err = "Invalid party ID"; break;
+ case -1: err = "Invalid type"; break;
+ default: err = "Unknown"; break;
+ }
+ ShowError("buildin_instance_create: %s [%d].\n", err, res);
+ script_pushint(st, -2);
+ return 0;
+ }
+
+ script_pushint(st, res);
+ return 0;
}
BUILDIN_FUNC(instance_destroy)
{
- int instance_id;
- struct map_session_data *sd;
- struct party_data *p;
+ int instance_id;
+ struct map_session_data *sd;
+ struct party_data *p;
- if (script_hasdata(st, 2))
- instance_id = script_getnum(st, 2);
- else if (st->instance_id)
- instance_id = st->instance_id;
- else if ((sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id)
- instance_id = p->instance_id;
- else return 0;
+ if( script_hasdata(st, 2) )
+ instance_id = script_getnum(st, 2);
+ else if( st->instance_id )
+ instance_id = st->instance_id;
+ else if( (sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id )
+ instance_id = p->instance_id;
+ else return 0;
- if (instance_id <= 0 || instance_id >= MAX_INSTANCE) {
- ShowError("buildin_instance_destroy: Trying to destroy invalid instance %d.\n", instance_id);
- return 0;
- }
+ if( instance_id <= 0 || instance_id >= MAX_INSTANCE )
+ {
+ ShowError("buildin_instance_destroy: Trying to destroy invalid instance %d.\n", instance_id);
+ return 0;
+ }
- instance_destroy(instance_id);
- return 0;
+ instance_destroy(instance_id);
+ return 0;
}
BUILDIN_FUNC(instance_attachmap)
{
- const char *name;
- int m;
- int instance_id;
- bool usebasename = false;
+ const char *name;
+ int m;
+ int instance_id;
+ bool usebasename = false;
- name = script_getstr(st,2);
- instance_id = script_getnum(st,3);
- if (script_hasdata(st,4) && script_getnum(st,4) > 0)
- usebasename = true;
+ name = script_getstr(st,2);
+ instance_id = script_getnum(st,3);
+ if( script_hasdata(st,4) && script_getnum(st,4) > 0)
+ usebasename = true;
- if ((m = instance_add_map(name, instance_id, usebasename)) < 0) { // [Saithis]
- ShowError("buildin_instance_attachmap: instance creation failed (%s): %d\n", name, m);
- script_pushconststr(st, "");
- return 0;
- }
- script_pushconststr(st, map[m].name);
+ if( (m = instance_add_map(name, instance_id, usebasename)) < 0 ) // [Saithis]
+ {
+ ShowError("buildin_instance_attachmap: instance creation failed (%s): %d\n", name, m);
+ script_pushconststr(st, "");
+ return 0;
+ }
+ script_pushconststr(st, map[m].name);
- return 0;
+ return 0;
}
BUILDIN_FUNC(instance_detachmap)
{
- struct map_session_data *sd;
- struct party_data *p;
- const char *str;
- int m, instance_id;
+ struct map_session_data *sd;
+ struct party_data *p;
+ const char *str;
+ int m, instance_id;
- str = script_getstr(st, 2);
- if (script_hasdata(st, 3))
- instance_id = script_getnum(st, 3);
- else if (st->instance_id)
- instance_id = st->instance_id;
- else if ((sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id)
- instance_id = p->instance_id;
- else return 0;
-
- if ((m = map_mapname2mapid(str)) < 0 || (m = instance_map2imap(m,instance_id)) < 0) {
- ShowError("buildin_instance_detachmap: Trying to detach invalid map %s\n", str);
- return 0;
- }
+ str = script_getstr(st, 2);
+ if( script_hasdata(st, 3) )
+ instance_id = script_getnum(st, 3);
+ else if( st->instance_id )
+ instance_id = st->instance_id;
+ else if( (sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id )
+ instance_id = p->instance_id;
+ else return 0;
- instance_del_map(m);
- return 0;
+ if( (m = map_mapname2mapid(str)) < 0 || (m = instance_map2imap(m,instance_id)) < 0 )
+ {
+ ShowError("buildin_instance_detachmap: Trying to detach invalid map %s\n", str);
+ return 0;
+ }
+
+ instance_del_map(m);
+ return 0;
}
BUILDIN_FUNC(instance_attach)
{
- int instance_id;
+ int instance_id;
- instance_id = script_getnum(st, 2);
- if (instance_id <= 0 || instance_id >= MAX_INSTANCE)
- return 0;
+ instance_id = script_getnum(st, 2);
+ if( instance_id <= 0 || instance_id >= MAX_INSTANCE )
+ return 0;
- st->instance_id = instance_id;
- return 0;
+ st->instance_id = instance_id;
+ return 0;
}
BUILDIN_FUNC(instance_id)
{
- int type, instance_id;
- struct map_session_data *sd;
- struct party_data *p;
-
- if (script_hasdata(st, 2)) {
- type = script_getnum(st, 2);
- if (type == 0)
- instance_id = st->instance_id;
- else if (type == 1 && (sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL)
- instance_id = p->instance_id;
- else
- instance_id = 0;
- } else
- instance_id = st->instance_id;
-
- script_pushint(st, instance_id);
- return 0;
+ int type, instance_id;
+ struct map_session_data *sd;
+ struct party_data *p;
+
+ if( script_hasdata(st, 2) )
+ {
+ type = script_getnum(st, 2);
+ if( type == 0 )
+ instance_id = st->instance_id;
+ else if( type == 1 && (sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL )
+ instance_id = p->instance_id;
+ else
+ instance_id = 0;
+ }
+ else
+ instance_id = st->instance_id;
+
+ script_pushint(st, instance_id);
+ return 0;
}
BUILDIN_FUNC(instance_set_timeout)
{
- int progress_timeout, idle_timeout;
- int instance_id;
- struct map_session_data *sd;
- struct party_data *p;
+ int progress_timeout, idle_timeout;
+ int instance_id;
+ struct map_session_data *sd;
+ struct party_data *p;
- progress_timeout = script_getnum(st, 2);
- idle_timeout = script_getnum(st, 3);
+ progress_timeout = script_getnum(st, 2);
+ idle_timeout = script_getnum(st, 3);
- if (script_hasdata(st, 4))
- instance_id = script_getnum(st, 4);
- else if (st->instance_id)
- instance_id = st->instance_id;
- else if ((sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id)
- instance_id = p->instance_id;
- else return 0;
+ if( script_hasdata(st, 4) )
+ instance_id = script_getnum(st, 4);
+ else if( st->instance_id )
+ instance_id = st->instance_id;
+ else if( (sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id )
+ instance_id = p->instance_id;
+ else return 0;
- if (instance_id > 0)
- instance_set_timeout(instance_id, progress_timeout, idle_timeout);
+ if( instance_id > 0 )
+ instance_set_timeout(instance_id, progress_timeout, idle_timeout);
- return 0;
+ return 0;
}
BUILDIN_FUNC(instance_init)
{
- int instance_id = script_getnum(st, 2);
+ int instance_id = script_getnum(st, 2);
- if (instance[instance_id].state != INSTANCE_IDLE) {
- ShowError("instance_init: instance already initialized.\n");
- return 0;
- }
+ if( instance[instance_id].state != INSTANCE_IDLE )
+ {
+ ShowError("instance_init: instance already initialized.\n");
+ return 0;
+ }
- instance_init(instance_id);
- return 0;
+ instance_init(instance_id);
+ return 0;
}
BUILDIN_FUNC(instance_announce)
{
- int instance_id = script_getnum(st,2);
- const char *mes = script_getstr(st,3);
- int flag = script_getnum(st,4);
- const char *fontColor = script_hasdata(st,5) ? script_getstr(st,5) : NULL;
- int fontType = script_hasdata(st,6) ? script_getnum(st,6) : 0x190; // default fontType (FW_NORMAL)
- int fontSize = script_hasdata(st,7) ? script_getnum(st,7) : 12; // default fontSize
- int fontAlign = script_hasdata(st,8) ? script_getnum(st,8) : 0; // default fontAlign
- int fontY = script_hasdata(st,9) ? script_getnum(st,9) : 0; // default fontY
-
- int i;
- struct map_session_data *sd;
- struct party_data *p;
-
- if (instance_id == 0) {
- if (st->instance_id)
- instance_id = st->instance_id;
- else if ((sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id)
- instance_id = p->instance_id;
- else return 0;
- }
+ int instance_id = script_getnum(st,2);
+ const char *mes = script_getstr(st,3);
+ int flag = script_getnum(st,4);
+ const char *fontColor = script_hasdata(st,5) ? script_getstr(st,5) : NULL;
+ int fontType = script_hasdata(st,6) ? script_getnum(st,6) : 0x190; // default fontType (FW_NORMAL)
+ int fontSize = script_hasdata(st,7) ? script_getnum(st,7) : 12; // default fontSize
+ int fontAlign = script_hasdata(st,8) ? script_getnum(st,8) : 0; // default fontAlign
+ int fontY = script_hasdata(st,9) ? script_getnum(st,9) : 0; // default fontY
- if (instance_id <= 0 || instance_id >= MAX_INSTANCE)
- return 0;
+ int i;
+ struct map_session_data *sd;
+ struct party_data *p;
- for (i = 0; i < instance[instance_id].num_map; i++)
- map_foreachinmap(buildin_announce_sub, instance[instance_id].map[i], BL_PC,
- mes, strlen(mes)+1, flag&0xf0, fontColor, fontType, fontSize, fontAlign, fontY);
+ if( instance_id == 0 )
+ {
+ if( st->instance_id )
+ instance_id = st->instance_id;
+ else if( (sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id )
+ instance_id = p->instance_id;
+ else return 0;
+ }
- return 0;
+ if( instance_id <= 0 || instance_id >= MAX_INSTANCE )
+ return 0;
+
+ for( i = 0; i < instance[instance_id].num_map; i++ )
+ map_foreachinmap(buildin_announce_sub, instance[instance_id].map[i], BL_PC,
+ mes, strlen(mes)+1, flag&0xf0, fontColor, fontType, fontSize, fontAlign, fontY);
+
+ return 0;
}
BUILDIN_FUNC(instance_npcname)
{
- const char *str;
- int instance_id = 0;
-
- struct map_session_data *sd;
- struct party_data *p;
- struct npc_data *nd;
-
- str = script_getstr(st, 2);
- if (script_hasdata(st, 3))
- instance_id = script_getnum(st, 3);
- else if (st->instance_id)
- instance_id = st->instance_id;
- else if ((sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id)
- instance_id = p->instance_id;
-
- if (instance_id && (nd = npc_name2id(str)) != NULL) {
- static char npcname[NAME_LENGTH];
- snprintf(npcname, sizeof(npcname), "dup_%d_%d", instance_id, nd->bl.id);
- script_pushconststr(st,npcname);
- } else {
- ShowError("script:instance_npcname: invalid instance NPC (instance_id: %d, NPC name: \"%s\".)\n", instance_id, str);
- st->state = END;
- return 1;
- }
-
- return 0;
+ const char *str;
+ int instance_id = 0;
+
+ struct map_session_data *sd;
+ struct party_data *p;
+ struct npc_data *nd;
+
+ str = script_getstr(st, 2);
+ if( script_hasdata(st, 3) )
+ instance_id = script_getnum(st, 3);
+ else if( st->instance_id )
+ instance_id = st->instance_id;
+ else if( (sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id )
+ instance_id = p->instance_id;
+
+ if( instance_id && (nd = npc_name2id(str)) != NULL )
+ {
+ static char npcname[NAME_LENGTH];
+ snprintf(npcname, sizeof(npcname), "dup_%d_%d", instance_id, nd->bl.id);
+ script_pushconststr(st,npcname);
+ }
+ else
+ {
+ ShowError("script:instance_npcname: invalid instance NPC (instance_id: %d, NPC name: \"%s\".)\n", instance_id, str);
+ st->state = END;
+ return 1;
+ }
+
+ return 0;
}
BUILDIN_FUNC(has_instance)
{
- struct map_session_data *sd;
- struct party_data *p;
- const char *str;
- int m, instance_id = 0;
+ struct map_session_data *sd;
+ struct party_data *p;
+ const char *str;
+ int m, instance_id = 0;
- str = script_getstr(st, 2);
- if (script_hasdata(st, 3))
- instance_id = script_getnum(st, 3);
- else if (st->instance_id)
- instance_id = st->instance_id;
- else if ((sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id)
- instance_id = p->instance_id;
-
- if (!instance_id || (m = map_mapname2mapid(str)) < 0 || (m = instance_map2imap(m, instance_id)) < 0) {
- script_pushconststr(st, "");
- return 0;
- }
+ str = script_getstr(st, 2);
+ if( script_hasdata(st, 3) )
+ instance_id = script_getnum(st, 3);
+ else if( st->instance_id )
+ instance_id = st->instance_id;
+ else if( (sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id )
+ instance_id = p->instance_id;
- script_pushconststr(st, map[m].name);
- return 0;
+ if( !instance_id || (m = map_mapname2mapid(str)) < 0 || (m = instance_map2imap(m, instance_id)) < 0 )
+ {
+ script_pushconststr(st, "");
+ return 0;
+ }
+
+ script_pushconststr(st, map[m].name);
+ return 0;
}
BUILDIN_FUNC(instance_warpall)
{
- struct map_session_data *pl_sd;
- int m, i, instance_id;
- const char *mapn;
- int x, y;
- unsigned short mapindex;
- struct party_data *p = NULL;
-
- mapn = script_getstr(st,2);
- x = script_getnum(st,3);
- y = script_getnum(st,4);
- if (script_hasdata(st,5))
- instance_id = script_getnum(st,5);
- else if (st->instance_id)
- instance_id = st->instance_id;
- else if ((pl_sd = script_rid2sd(st)) != NULL && pl_sd->status.party_id && (p = party_search(pl_sd->status.party_id)) != NULL && p->instance_id)
- instance_id = p->instance_id;
- else return 0;
-
- if ((m = map_mapname2mapid(mapn)) < 0 || (map[m].flag.src4instance && (m = instance_mapid2imapid(m, instance_id)) < 0))
- return 0;
+ struct map_session_data *pl_sd;
+ int m, i, instance_id;
+ const char *mapn;
+ int x, y;
+ unsigned short mapindex;
+ struct party_data *p = NULL;
- if (!(p = party_search(instance[instance_id].party_id)))
- return 0;
+ mapn = script_getstr(st,2);
+ x = script_getnum(st,3);
+ y = script_getnum(st,4);
+ if( script_hasdata(st,5) )
+ instance_id = script_getnum(st,5);
+ else if( st->instance_id )
+ instance_id = st->instance_id;
+ else if( (pl_sd = script_rid2sd(st)) != NULL && pl_sd->status.party_id && (p = party_search(pl_sd->status.party_id)) != NULL && p->instance_id )
+ instance_id = p->instance_id;
+ else return 0;
- mapindex = map_id2index(m);
- for (i = 0; i < MAX_PARTY; i++)
- if ((pl_sd = p->data[i].sd) && map[pl_sd->bl.m].instance_id == st->instance_id) pc_setpos(pl_sd,mapindex,x,y,CLR_TELEPORT);
+ if( (m = map_mapname2mapid(mapn)) < 0 || (map[m].flag.src4instance && (m = instance_mapid2imapid(m, instance_id)) < 0) )
+ return 0;
- return 0;
+ if( !(p = party_search(instance[instance_id].party_id)) )
+ return 0;
+
+ mapindex = map_id2index(m);
+ for( i = 0; i < MAX_PARTY; i++ )
+ if( (pl_sd = p->data[i].sd) && map[pl_sd->bl.m].instance_id == st->instance_id ) pc_setpos(pl_sd,mapindex,x,y,CLR_TELEPORT);
+
+ return 0;
}
/*==========================================
@@ -16639,50 +16515,50 @@ BUILDIN_FUNC(instance_warpall)
*------------------------------------------*/
BUILDIN_FUNC(instance_check_party)
{
- struct map_session_data *pl_sd;
- int amount, min, max, i, party_id, c = 0;
- struct party_data *p = NULL;
-
- amount = script_hasdata(st,3) ? script_getnum(st,3) : 1; // Amount of needed Partymembers for the Instance.
- min = script_hasdata(st,4) ? script_getnum(st,4) : 1; // Minimum Level needed to join the Instance.
- max = script_hasdata(st,5) ? script_getnum(st,5) : MAX_LEVEL; // Maxium Level allowed to join the Instance.
-
- if (min < 1 || min > MAX_LEVEL) {
- ShowError("instance_check_party: Invalid min level, %d\n", min);
- return 0;
- } else if (max < 1 || max > MAX_LEVEL) {
- ShowError("instance_check_party: Invalid max level, %d\n", max);
- return 0;
- }
-
- if (script_hasdata(st,2))
- party_id = script_getnum(st,2);
- else return 0;
-
- if (!(p = party_search(party_id))) {
- script_pushint(st, 0); // Returns false if party does not exist.
- return 0;
- }
-
- for (i = 0; i < MAX_PARTY; i++)
- if ((pl_sd = p->data[i].sd))
- if (map_id2bl(pl_sd->bl.id)) {
- if (pl_sd->status.base_level < min) {
- script_pushint(st, 0);
- return 0;
- } else if (pl_sd->status.base_level > max) {
- script_pushint(st, 0);
- return 0;
- }
- c++;
- }
-
- if (c < amount) {
- script_pushint(st, 0); // Not enough Members in the Party to join Instance.
- } else
- script_pushint(st, 1);
-
- return 0;
+ struct map_session_data *pl_sd;
+ int amount, min, max, i, party_id, c = 0;
+ struct party_data *p = NULL;
+
+ amount = script_hasdata(st,3) ? script_getnum(st,3) : 1; // Amount of needed Partymembers for the Instance.
+ min = script_hasdata(st,4) ? script_getnum(st,4) : 1; // Minimum Level needed to join the Instance.
+ max = script_hasdata(st,5) ? script_getnum(st,5) : MAX_LEVEL; // Maxium Level allowed to join the Instance.
+
+ if( min < 1 || min > MAX_LEVEL){
+ ShowError("instance_check_party: Invalid min level, %d\n", min);
+ return 0;
+ }else if( max < 1 || max > MAX_LEVEL){
+ ShowError("instance_check_party: Invalid max level, %d\n", max);
+ return 0;
+ }
+
+ if( script_hasdata(st,2) )
+ party_id = script_getnum(st,2);
+ else return 0;
+
+ if( !(p = party_search(party_id)) ){
+ script_pushint(st, 0); // Returns false if party does not exist.
+ return 0;
+ }
+
+ for( i = 0; i < MAX_PARTY; i++ )
+ if( (pl_sd = p->data[i].sd) )
+ if(map_id2bl(pl_sd->bl.id)){
+ if(pl_sd->status.base_level < min){
+ script_pushint(st, 0);
+ return 0;
+ }else if(pl_sd->status.base_level > max){
+ script_pushint(st, 0);
+ return 0;
+ }
+ c++;
+ }
+
+ if(c < amount){
+ script_pushint(st, 0); // Not enough Members in the Party to join Instance.
+ }else
+ script_pushint(st, 1);
+
+ return 0;
}
/*==========================================
@@ -16690,155 +16566,152 @@ BUILDIN_FUNC(instance_check_party)
*------------------------------------------*/
BUILDIN_FUNC(setfont)
{
- struct map_session_data *sd = script_rid2sd(st);
- int font = script_getnum(st,2);
- if (sd == NULL)
- return 0;
+ struct map_session_data *sd = script_rid2sd(st);
+ int font = script_getnum(st,2);
+ if( sd == NULL )
+ return 0;
- if (sd->user_font != font)
- sd->user_font = font;
- else
- sd->user_font = 0;
+ if( sd->user_font != font )
+ sd->user_font = font;
+ else
+ sd->user_font = 0;
- clif_font(sd);
- return 0;
+ clif_font(sd);
+ return 0;
}
static int buildin_mobuseskill_sub(struct block_list *bl,va_list ap)
{
- TBL_MOB *md = (TBL_MOB *)bl;
- struct block_list *tbl;
- int mobid = va_arg(ap,int);
- int skillid = va_arg(ap,int);
- int skilllv = va_arg(ap,int);
- int casttime = va_arg(ap,int);
- int cancel = va_arg(ap,int);
- int emotion = va_arg(ap,int);
- int target = va_arg(ap,int);
-
- if (md->class_ != mobid)
- return 0;
+ TBL_MOB* md = (TBL_MOB*)bl;
+ struct block_list *tbl;
+ int mobid = va_arg(ap,int);
+ int skillid = va_arg(ap,int);
+ int skilllv = va_arg(ap,int);
+ int casttime = va_arg(ap,int);
+ int cancel = va_arg(ap,int);
+ int emotion = va_arg(ap,int);
+ int target = va_arg(ap,int);
- // 0:self, 1:target, 2:master, default:random
- switch (target) {
- case 0:
- tbl = map_id2bl(md->bl.id);
- break;
- case 1:
- tbl = map_id2bl(md->target_id);
- break;
- case 2:
- tbl = map_id2bl(md->master_id);
- break;
- default:
- tbl = battle_getenemy(&md->bl, DEFAULT_ENEMY_TYPE(md),skill_get_range2(&md->bl, skillid, skilllv));
- break;
- }
+ if( md->class_ != mobid )
+ return 0;
- if (!tbl)
- return 0;
+ // 0:self, 1:target, 2:master, default:random
+ switch( target )
+ {
+ case 0: tbl = map_id2bl(md->bl.id); break;
+ case 1: tbl = map_id2bl(md->target_id); break;
+ case 2: tbl = map_id2bl(md->master_id); break;
+ default:tbl = battle_getenemy(&md->bl, DEFAULT_ENEMY_TYPE(md),skill_get_range2(&md->bl, skillid, skilllv)); break;
+ }
- if (md->ud.skilltimer != INVALID_TIMER) // Cancel the casting skill.
- unit_skillcastcancel(bl,0);
+ if( !tbl )
+ return 0;
- if (skill_get_casttype(skillid) == CAST_GROUND)
- unit_skilluse_pos2(&md->bl, tbl->x, tbl->y, skillid, skilllv, casttime, cancel);
- else
- unit_skilluse_id2(&md->bl, tbl->id, skillid, skilllv, casttime, cancel);
+ if( md->ud.skilltimer != INVALID_TIMER ) // Cancel the casting skill.
+ unit_skillcastcancel(bl,0);
- clif_emotion(&md->bl, emotion);
+ if( skill_get_casttype(skillid) == CAST_GROUND )
+ unit_skilluse_pos2(&md->bl, tbl->x, tbl->y, skillid, skilllv, casttime, cancel);
+ else
+ unit_skilluse_id2(&md->bl, tbl->id, skillid, skilllv, casttime, cancel);
- return 0;
+ clif_emotion(&md->bl, emotion);
+
+ return 0;
}
/*==========================================
* areamobuseskill "Map Name",<x>,<y>,<range>,<Mob ID>,"Skill Name"/<Skill ID>,<Skill Lv>,<Cast Time>,<Cancelable>,<Emotion>,<Target Type>;
*------------------------------------------*/
BUILDIN_FUNC(areamobuseskill)
{
- struct block_list center;
- int m,range,mobid,skillid,skilllv,casttime,emotion,target,cancel;
+ struct block_list center;
+ int m,range,mobid,skillid,skilllv,casttime,emotion,target,cancel;
- if ((m = map_mapname2mapid(script_getstr(st,2))) < 0) {
- ShowError("areamobuseskill: invalid map name.\n");
- return 0;
- }
+ if( (m = map_mapname2mapid(script_getstr(st,2))) < 0 )
+ {
+ ShowError("areamobuseskill: invalid map name.\n");
+ return 0;
+ }
- if (map[m].flag.src4instance && st->instance_id && (m = instance_mapid2imapid(m, st->instance_id)) < 0)
- return 0;
+ if( map[m].flag.src4instance && st->instance_id && (m = instance_mapid2imapid(m, st->instance_id)) < 0 )
+ return 0;
- center.m = m;
- center.x = script_getnum(st,3);
- center.y = script_getnum(st,4);
- range = script_getnum(st,5);
- mobid = script_getnum(st,6);
- skillid = (script_isstring(st,7) ? skill_name2id(script_getstr(st,7)) : script_getnum(st,7));
- if ((skilllv = script_getnum(st,8)) > battle_config.mob_max_skilllvl)
- skilllv = battle_config.mob_max_skilllvl;
-
- casttime = script_getnum(st,9);
- cancel = script_getnum(st,10);
- emotion = script_getnum(st,11);
- target = script_getnum(st,12);
-
- map_foreachinrange(buildin_mobuseskill_sub, &center, range, BL_MOB, mobid, skillid, skilllv, casttime, cancel, emotion, target);
- return 0;
+ center.m = m;
+ center.x = script_getnum(st,3);
+ center.y = script_getnum(st,4);
+ range = script_getnum(st,5);
+ mobid = script_getnum(st,6);
+ skillid = ( script_isstring(st,7) ? skill_name2id(script_getstr(st,7)) : script_getnum(st,7) );
+ if( (skilllv = script_getnum(st,8)) > battle_config.mob_max_skilllvl )
+ skilllv = battle_config.mob_max_skilllvl;
+
+ casttime = script_getnum(st,9);
+ cancel = script_getnum(st,10);
+ emotion = script_getnum(st,11);
+ target = script_getnum(st,12);
+
+ map_foreachinrange(buildin_mobuseskill_sub, &center, range, BL_MOB, mobid, skillid, skilllv, casttime, cancel, emotion, target);
+ return 0;
}
BUILDIN_FUNC(progressbar)
{
- struct map_session_data *sd = script_rid2sd(st);
- const char *color;
- unsigned int second;
+ struct map_session_data * sd = script_rid2sd(st);
+ const char * color;
+ unsigned int second;
- if (!st || !sd)
- return 0;
+ if( !st || !sd )
+ return 0;
- st->state = STOP;
+ st->state = STOP;
- color = script_getstr(st,2);
- second = script_getnum(st,3);
+ color = script_getstr(st,2);
+ second = script_getnum(st,3);
- sd->progressbar.npc_id = st->oid;
- sd->progressbar.timeout = gettick() + second*1000;
+ sd->progressbar.npc_id = st->oid;
+ sd->progressbar.timeout = gettick() + second*1000;
- clif_progressbar(sd, strtol(color, (char **)NULL, 0), second);
+ clif_progressbar(sd, strtol(color, (char **)NULL, 0), second);
return 0;
}
BUILDIN_FUNC(pushpc)
{
- int direction, cells, dx, dy;
- struct map_session_data *sd;
+ int direction, cells, dx, dy;
+ struct map_session_data* sd;
- if ((sd = script_rid2sd(st))==NULL) {
- return 0;
- }
+ if((sd = script_rid2sd(st))==NULL)
+ {
+ return 0;
+ }
- direction = script_getnum(st,2);
- cells = script_getnum(st,3);
+ direction = script_getnum(st,2);
+ cells = script_getnum(st,3);
- if (direction<0 || direction>7) {
- ShowWarning("buildin_pushpc: Invalid direction %d specified.\n", direction);
- script_reportsrc(st);
+ if(direction<0 || direction>7)
+ {
+ ShowWarning("buildin_pushpc: Invalid direction %d specified.\n", direction);
+ script_reportsrc(st);
- direction%= 8; // trim spin-over
- }
+ direction%= 8; // trim spin-over
+ }
- if (!cells) {
- // zero distance
- return 0;
- } else if (cells<0) {
- // pushing backwards
- direction = (direction+4)%8; // turn around
- cells = -cells;
- }
+ if(!cells)
+ {// zero distance
+ return 0;
+ }
+ else if(cells<0)
+ {// pushing backwards
+ direction = (direction+4)%8; // turn around
+ cells = -cells;
+ }
- dx = dirx[direction];
- dy = diry[direction];
+ dx = dirx[direction];
+ dy = diry[direction];
- unit_blown(&sd->bl, dx, dy, cells, 0);
- return 0;
+ unit_blown(&sd->bl, dx, dy, cells, 0);
+ return 0;
}
@@ -16846,14 +16719,15 @@ BUILDIN_FUNC(pushpc)
/// buyingstore <slots>;
BUILDIN_FUNC(buyingstore)
{
- struct map_session_data *sd;
+ struct map_session_data* sd;
- if ((sd = script_rid2sd(st)) == NULL) {
- return 0;
- }
+ if( ( sd = script_rid2sd(st) ) == NULL )
+ {
+ return 0;
+ }
- buyingstore_setup(sd, script_getnum(st,2));
- return 0;
+ buyingstore_setup(sd, script_getnum(st,2));
+ return 0;
}
@@ -16861,81 +16735,85 @@ BUILDIN_FUNC(buyingstore)
/// searchstores <uses>,<effect>;
BUILDIN_FUNC(searchstores)
{
- unsigned short effect;
- unsigned int uses;
- struct map_session_data *sd;
+ unsigned short effect;
+ unsigned int uses;
+ struct map_session_data* sd;
- if ((sd = script_rid2sd(st)) == NULL) {
- return 0;
- }
+ if( ( sd = script_rid2sd(st) ) == NULL )
+ {
+ return 0;
+ }
- uses = script_getnum(st,2);
- effect = script_getnum(st,3);
+ uses = script_getnum(st,2);
+ effect = script_getnum(st,3);
- if (!uses) {
- ShowError("buildin_searchstores: Amount of uses cannot be zero.\n");
- return 1;
- }
+ if( !uses )
+ {
+ ShowError("buildin_searchstores: Amount of uses cannot be zero.\n");
+ return 1;
+ }
- if (effect > 1) {
- ShowError("buildin_searchstores: Invalid effect id %hu, specified.\n", effect);
- return 1;
- }
+ if( effect > 1 )
+ {
+ ShowError("buildin_searchstores: Invalid effect id %hu, specified.\n", effect);
+ return 1;
+ }
- searchstore_open(sd, uses, effect);
- return 0;
+ searchstore_open(sd, uses, effect);
+ return 0;
}
/// Displays a number as large digital clock.
/// showdigit <value>[,<type>];
BUILDIN_FUNC(showdigit)
{
- unsigned int type = 0;
- int value;
- struct map_session_data *sd;
+ unsigned int type = 0;
+ int value;
+ struct map_session_data* sd;
- if ((sd = script_rid2sd(st)) == NULL) {
- return 0;
- }
+ if( ( sd = script_rid2sd(st) ) == NULL )
+ {
+ return 0;
+ }
- value = script_getnum(st,2);
+ value = script_getnum(st,2);
- if (script_hasdata(st,3)) {
- type = script_getnum(st,3);
+ if( script_hasdata(st,3) )
+ {
+ type = script_getnum(st,3);
- if (type > 3) {
- ShowError("buildin_showdigit: Invalid type %u.\n", type);
- return 1;
- }
- }
+ if( type > 3 )
+ {
+ ShowError("buildin_showdigit: Invalid type %u.\n", type);
+ return 1;
+ }
+ }
- clif_showdigit(sd, (unsigned char)type, value);
- return 0;
+ clif_showdigit(sd, (unsigned char)type, value);
+ return 0;
}
/**
* Rune Knight
**/
-BUILDIN_FUNC(makerune)
-{
- TBL_PC *sd;
- if ((sd = script_rid2sd(st)) == NULL)
- return 0;
- clif_skill_produce_mix_list(sd,RK_RUNEMASTERY,24);
- sd->itemid = script_getnum(st,2);
- return 0;
+BUILDIN_FUNC(makerune) {
+ TBL_PC* sd;
+ if( (sd = script_rid2sd(st)) == NULL )
+ return 0;
+ clif_skill_produce_mix_list(sd,RK_RUNEMASTERY,24);
+ sd->itemid = script_getnum(st,2);
+ return 0;
}
/**
* checkdragon() returns 1 if mounting a dragon or 0 otherwise.
**/
-BUILDIN_FUNC(checkdragon)
-{
- TBL_PC *sd;
- if ((sd = script_rid2sd(st)) == NULL)
- return 0;
- if (pc_isridingdragon(sd))
- script_pushint(st,1);
- else
- script_pushint(st,0);
- return 0;
+BUILDIN_FUNC(checkdragon) {
+ TBL_PC* sd;
+ if( (sd = script_rid2sd(st)) == NULL )
+ return 0;
+ if( pc_isridingdragon(sd) )
+ script_pushint(st,1);
+ else
+ script_pushint(st,0);
+ return 0;
}
/**
* setdragon({optional Color}) returns 1 on success or 0 otherwise
@@ -16947,49 +16825,47 @@ BUILDIN_FUNC(checkdragon)
* - 4 : Blue Dragon
* - 5 : Red Dragon
**/
-BUILDIN_FUNC(setdragon)
-{
- TBL_PC *sd;
- int color = script_hasdata(st,2) ? script_getnum(st,2) : 0;
- unsigned int option = OPTION_DRAGON1;
- if ((sd = script_rid2sd(st)) == NULL)
- return 0;
- if (!pc_checkskill(sd,RK_DRAGONTRAINING) || (sd->class_&MAPID_THIRDMASK) != MAPID_RUNE_KNIGHT)
- script_pushint(st,0);//Doesn't have the skill or it's not a Rune Knight
- else if (pc_isridingdragon(sd)) { //Is mounted; release
- pc_setoption(sd, sd->sc.option&~OPTION_DRAGON);
- script_pushint(st,1);
- } else {//Not mounted; Mount now.
- if (color) {
- option = (color == 1 ? OPTION_DRAGON1 :
- color == 2 ? OPTION_DRAGON2 :
- color == 3 ? OPTION_DRAGON3 :
- color == 4 ? OPTION_DRAGON4 :
- color == 5 ? OPTION_DRAGON5 : 0);
- if (!option) {
- ShowWarning("script_setdragon: Unknown Color %d used; changing to green (1)\n",color);
- option = OPTION_DRAGON1;
- }
- }
- pc_setoption(sd, sd->sc.option|option);
- script_pushint(st,1);
- }
- return 0;
+BUILDIN_FUNC(setdragon) {
+ TBL_PC* sd;
+ int color = script_hasdata(st,2) ? script_getnum(st,2) : 0;
+ unsigned int option = OPTION_DRAGON1;
+ if( (sd = script_rid2sd(st)) == NULL )
+ return 0;
+ if( !pc_checkskill(sd,RK_DRAGONTRAINING) || (sd->class_&MAPID_THIRDMASK) != MAPID_RUNE_KNIGHT )
+ script_pushint(st,0);//Doesn't have the skill or it's not a Rune Knight
+ else if ( pc_isridingdragon(sd) ) {//Is mounted; release
+ pc_setoption(sd, sd->sc.option&~OPTION_DRAGON);
+ script_pushint(st,1);
+ } else {//Not mounted; Mount now.
+ if( color ) {
+ option = ( color == 1 ? OPTION_DRAGON1 :
+ color == 2 ? OPTION_DRAGON2 :
+ color == 3 ? OPTION_DRAGON3 :
+ color == 4 ? OPTION_DRAGON4 :
+ color == 5 ? OPTION_DRAGON5 : 0);
+ if( !option ) {
+ ShowWarning("script_setdragon: Unknown Color %d used; changing to green (1)\n",color);
+ option = OPTION_DRAGON1;
+ }
+ }
+ pc_setoption(sd, sd->sc.option|option);
+ script_pushint(st,1);
+ }
+ return 0;
}
/**
* ismounting() returns 1 if mounting a new mount or 0 otherwise
**/
-BUILDIN_FUNC(ismounting)
-{
- TBL_PC *sd;
- if ((sd = script_rid2sd(st)) == NULL)
- return 0;
- if (sd->sc.option&OPTION_MOUNTING)
- script_pushint(st,1);
- else
- script_pushint(st,0);
- return 0;
+BUILDIN_FUNC(ismounting) {
+ TBL_PC* sd;
+ if( (sd = script_rid2sd(st)) == NULL )
+ return 0;
+ if( sd->sc.option&OPTION_MOUNTING )
+ script_pushint(st,1);
+ else
+ script_pushint(st,0);
+ return 0;
}
/**
@@ -16998,398 +16874,357 @@ BUILDIN_FUNC(ismounting)
* - Will fail if the player is mounting a non-new mount, e.g. dragon, peco, wug, etc.
* - Will unmount the player is he is already mounting
**/
-BUILDIN_FUNC(setmounting)
-{
- TBL_PC *sd;
- if ((sd = script_rid2sd(st)) == NULL)
- return 0;
- if (sd->sc.option&(OPTION_WUGRIDER|OPTION_RIDING|OPTION_DRAGON|OPTION_MADOGEAR))
- script_pushint(st,0);//can't mount with one of these
- else {
- if (sd->sc.option&OPTION_MOUNTING)
- pc_setoption(sd, sd->sc.option&~OPTION_MOUNTING);//release mount
- else
- pc_setoption(sd, sd->sc.option|OPTION_MOUNTING);//mount
- script_pushint(st,1);//in both cases, return 1.
- }
- return 0;
+BUILDIN_FUNC(setmounting) {
+ TBL_PC* sd;
+ if( (sd = script_rid2sd(st)) == NULL )
+ return 0;
+ if( sd->sc.option&(OPTION_WUGRIDER|OPTION_RIDING|OPTION_DRAGON|OPTION_MADOGEAR) )
+ script_pushint(st,0);//can't mount with one of these
+ else {
+ if( sd->sc.option&OPTION_MOUNTING )
+ pc_setoption(sd, sd->sc.option&~OPTION_MOUNTING);//release mount
+ else
+ pc_setoption(sd, sd->sc.option|OPTION_MOUNTING);//mount
+ script_pushint(st,1);//in both cases, return 1.
+ }
+ return 0;
}
/**
* Retrieves quantity of arguments provided to callfunc/callsub.
* getargcount() -> amount of arguments received in a function
**/
-BUILDIN_FUNC(getargcount)
-{
- struct script_retinfo *ri;
+BUILDIN_FUNC(getargcount) {
+ struct script_retinfo* ri;
- if (st->stack->defsp < 1 || st->stack->stack_data[st->stack->defsp - 1].type != C_RETINFO) {
- ShowError("script:getargcount: used out of function or callsub label!\n");
- st->state = END;
- return 1;
- }
- ri = st->stack->stack_data[st->stack->defsp - 1].u.ri;
+ if( st->stack->defsp < 1 || st->stack->stack_data[st->stack->defsp - 1].type != C_RETINFO ) {
+ ShowError("script:getargcount: used out of function or callsub label!\n");
+ st->state = END;
+ return 1;
+ }
+ ri = st->stack->stack_data[st->stack->defsp - 1].u.ri;
- script_pushint(st, ri->nargs);
+ script_pushint(st, ri->nargs);
- return 0;
+ return 0;
}
/**
* getcharip(<account ID>/<character ID>/<character name>)
**/
BUILDIN_FUNC(getcharip)
{
- struct map_session_data *sd = NULL;
- int id = 0;
-
- /* check if a character name is specified */
- if (script_hasdata(st, 2)) {
- if (script_isstring(st, 2))
- sd = map_nick2sd(script_getstr(st, 2));
- else if (script_isint(st, 2) || script_getnum(st, 2)) {
- id = script_getnum(st, 2);
- sd = (map_id2sd(id) ? map_id2sd(id) : map_charid2sd(id));
- }
- } else
- sd = script_rid2sd(st);
-
- /* check for sd and IP */
- if (!sd || !session[sd->fd]->client_addr) {
- script_pushconststr(st, "");
- return 0;
- }
-
- /* return the client ip_addr converted for output */
- if (sd && sd->fd && session[sd->fd]) {
- /* initiliaze */
- const char *ip_addr = NULL;
- uint32 ip;
-
- /* set ip, ip_addr and convert to ip and push str */
- ip = session[sd->fd]->client_addr;
- ip_addr = ip2str(ip, NULL);
- script_pushstrcopy(st, ip_addr);
- }
-
- return 0;
+ struct map_session_data* sd = NULL;
+ int id = 0;
+
+ /* check if a character name is specified */
+ if( script_hasdata(st, 2) )
+ {
+ if (script_isstring(st, 2))
+ sd = map_nick2sd(script_getstr(st, 2));
+ else if (script_isint(st, 2) || script_getnum(st, 2))
+ {
+ id = script_getnum(st, 2);
+ sd = (map_id2sd(id) ? map_id2sd(id) : map_charid2sd(id));
+ }
+ }
+ else
+ sd = script_rid2sd(st);
+
+ /* check for sd and IP */
+ if (!sd || !session[sd->fd]->client_addr)
+ {
+ script_pushconststr(st, "");
+ return 0;
+ }
+
+ /* return the client ip_addr converted for output */
+ if (sd && sd->fd && session[sd->fd])
+ {
+ /* initiliaze */
+ const char *ip_addr = NULL;
+ uint32 ip;
+
+ /* set ip, ip_addr and convert to ip and push str */
+ ip = session[sd->fd]->client_addr;
+ ip_addr = ip2str(ip, NULL);
+ script_pushstrcopy(st, ip_addr);
+ }
+
+ return 0;
}
/**
* is_function(<function name>) -> 1 if function exists, 0 otherwise
**/
-BUILDIN_FUNC(is_function)
-{
- const char *str = script_getstr(st,2);
+BUILDIN_FUNC(is_function) {
+ const char* str = script_getstr(st,2);
- if (strdb_exists(userfunc_db, str))
- script_pushint(st,1);
- else
- script_pushint(st,0);
+ if( strdb_exists(userfunc_db, str) )
+ script_pushint(st,1);
+ else
+ script_pushint(st,0);
- return 0;
+ return 0;
}
/**
* get_revision() -> retrieves the current svn revision (if available)
**/
-BUILDIN_FUNC(get_revision)
-{
- const char *revision;
+BUILDIN_FUNC(get_revision) {
+ const char * revision;
- if ((revision = get_svn_revision()) != 0)
- script_pushint(st,atoi(revision));
- else
- script_pushint(st,-1);//unknown
+ if ( (revision = get_svn_revision()) != 0 )
+ script_pushint(st,atoi(revision));
+ else
+ script_pushint(st,-1);//unknown
- return 0;
+ return 0;
}
/**
* freeloop(<toggle>) -> toggles this script instance's looping-check ability
**/
-BUILDIN_FUNC(freeloop)
-{
+BUILDIN_FUNC(freeloop) {
- if (script_getnum(st,2))
- st->freeloop = 1;
- else
- st->freeloop = 0;
+ if( script_getnum(st,2) )
+ st->freeloop = 1;
+ else
+ st->freeloop = 0;
- script_pushint(st, st->freeloop);
+ script_pushint(st, st->freeloop);
- return 0;
+ return 0;
}
/**
* @commands (script based)
**/
-BUILDIN_FUNC(bindatcmd)
-{
- const char *atcmd;
- const char *eventName;
- int i, level = 0, level2 = 0;
- bool create = false;
-
- atcmd = script_getstr(st,2);
- eventName = script_getstr(st,3);
-
- if (*atcmd == atcommand_symbol || *atcmd == charcommand_symbol)
- atcmd++;
-
- if (script_hasdata(st,4)) level = script_getnum(st,4);
- if (script_hasdata(st,5)) level2 = script_getnum(st,5);
-
- if (atcmd_binding_count == 0) {
- CREATE(atcmd_binding,struct atcmd_binding_data *,1);
-
- create = true;
- } else {
- ARR_FIND(0, atcmd_binding_count, i, strcmp(atcmd_binding[i]->command,atcmd) == 0);
- if (i < atcmd_binding_count) { /* update existent entry */
- safestrncpy(atcmd_binding[i]->npc_event, eventName, 50);
- atcmd_binding[i]->level = level;
- atcmd_binding[i]->level2 = level2;
- } else
- create = true;
- }
+BUILDIN_FUNC(bindatcmd) {
+ const char* atcmd;
+ const char* eventName;
+ int i, level = 0, level2 = 0;
+ bool create = false;
- if (create) {
- i = atcmd_binding_count;
+ atcmd = script_getstr(st,2);
+ eventName = script_getstr(st,3);
- if (atcmd_binding_count++ != 0)
- RECREATE(atcmd_binding,struct atcmd_binding_data *,atcmd_binding_count);
+ if( *atcmd == atcommand_symbol || *atcmd == charcommand_symbol )
+ atcmd++;
- CREATE(atcmd_binding[i],struct atcmd_binding_data,1);
+ if( script_hasdata(st,4) ) level = script_getnum(st,4);
+ if( script_hasdata(st,5) ) level2 = script_getnum(st,5);
- safestrncpy(atcmd_binding[i]->command, atcmd, 50);
- safestrncpy(atcmd_binding[i]->npc_event, eventName, 50);
- atcmd_binding[i]->level = level;
- atcmd_binding[i]->level2 = level2;
- }
+ if( atcmd_binding_count == 0 ) {
+ CREATE(atcmd_binding,struct atcmd_binding_data*,1);
- return 0;
+ create = true;
+ } else {
+ ARR_FIND(0, atcmd_binding_count, i, strcmp(atcmd_binding[i]->command,atcmd) == 0);
+ if( i < atcmd_binding_count ) {/* update existent entry */
+ safestrncpy(atcmd_binding[i]->npc_event, eventName, 50);
+ atcmd_binding[i]->level = level;
+ atcmd_binding[i]->level2 = level2;
+ } else
+ create = true;
+ }
+
+ if( create ) {
+ i = atcmd_binding_count;
+
+ if( atcmd_binding_count++ != 0 )
+ RECREATE(atcmd_binding,struct atcmd_binding_data*,atcmd_binding_count);
+
+ CREATE(atcmd_binding[i],struct atcmd_binding_data,1);
+
+ safestrncpy(atcmd_binding[i]->command, atcmd, 50);
+ safestrncpy(atcmd_binding[i]->npc_event, eventName, 50);
+ atcmd_binding[i]->level = level;
+ atcmd_binding[i]->level2 = level2;
+ }
+
+ return 0;
}
-BUILDIN_FUNC(unbindatcmd)
-{
- const char *atcmd;
- int i = 0;
+BUILDIN_FUNC(unbindatcmd) {
+ const char* atcmd;
+ int i = 0;
- atcmd = script_getstr(st, 2);
+ atcmd = script_getstr(st, 2);
- if (*atcmd == atcommand_symbol || *atcmd == charcommand_symbol)
- atcmd++;
+ if( *atcmd == atcommand_symbol || *atcmd == charcommand_symbol )
+ atcmd++;
- if (atcmd_binding_count == 0) {
- script_pushint(st, 0);
- return 0;
- }
+ if( atcmd_binding_count == 0 ) {
+ script_pushint(st, 0);
+ return 0;
+ }
- ARR_FIND(0, atcmd_binding_count, i, strcmp(atcmd_binding[i]->command, atcmd) == 0);
- if (i < atcmd_binding_count) {
- int cursor = 0;
- aFree(atcmd_binding[i]);
- atcmd_binding[i] = NULL;
- /* compact the list now that we freed a slot somewhere */
- for (i = 0, cursor = 0; i < atcmd_binding_count; i++) {
- if (atcmd_binding[i] == NULL)
- continue;
-
- if (cursor != i) {
- memmove(&atcmd_binding[cursor], &atcmd_binding[i], sizeof(struct atcmd_binding_data *));
- }
+ ARR_FIND(0, atcmd_binding_count, i, strcmp(atcmd_binding[i]->command, atcmd) == 0);
+ if( i < atcmd_binding_count ) {
+ int cursor = 0;
+ aFree(atcmd_binding[i]);
+ atcmd_binding[i] = NULL;
+ /* compact the list now that we freed a slot somewhere */
+ for( i = 0, cursor = 0; i < atcmd_binding_count; i++ ) {
+ if( atcmd_binding[i] == NULL )
+ continue;
- cursor++;
- }
+ if( cursor != i ) {
+ memmove(&atcmd_binding[cursor], &atcmd_binding[i], sizeof(struct atcmd_binding_data*));
+ }
- if ((atcmd_binding_count = cursor) == 0)
- aFree(atcmd_binding);
+ cursor++;
+ }
- script_pushint(st, 1);
- } else
- script_pushint(st, 0);/* not found */
+ if( (atcmd_binding_count = cursor) == 0 )
+ aFree(atcmd_binding);
- return 0;
+ script_pushint(st, 1);
+ } else
+ script_pushint(st, 0);/* not found */
+
+ return 0;
}
BUILDIN_FUNC(useatcmd)
{
- TBL_PC dummy_sd;
- TBL_PC *sd;
- int fd;
- const char *cmd;
-
- cmd = script_getstr(st,2);
-
- if (st->rid) {
- sd = script_rid2sd(st);
- fd = sd->fd;
- } else {
- // Use a dummy character.
- sd = &dummy_sd;
- fd = 0;
-
- memset(&dummy_sd, 0, sizeof(TBL_PC));
- if (st->oid) {
- struct block_list *bl = map_id2bl(st->oid);
- memcpy(&dummy_sd.bl, bl, sizeof(struct block_list));
- if (bl->type == BL_NPC)
- safestrncpy(dummy_sd.status.name, ((TBL_NPC *)bl)->name, NAME_LENGTH);
- }
- }
-
- // compatibility with previous implementation (deprecated!)
- if (cmd[0] != atcommand_symbol) {
- cmd += strlen(sd->status.name);
- while (*cmd != atcommand_symbol && *cmd != 0)
- cmd++;
- }
-
- is_atcommand(fd, sd, cmd, 1);
- return 0;
+ TBL_PC dummy_sd;
+ TBL_PC* sd;
+ int fd;
+ const char* cmd;
+
+ cmd = script_getstr(st,2);
+
+ if( st->rid )
+ {
+ sd = script_rid2sd(st);
+ fd = sd->fd;
+ }
+ else
+ { // Use a dummy character.
+ sd = &dummy_sd;
+ fd = 0;
+
+ memset(&dummy_sd, 0, sizeof(TBL_PC));
+ if( st->oid )
+ {
+ struct block_list* bl = map_id2bl(st->oid);
+ memcpy(&dummy_sd.bl, bl, sizeof(struct block_list));
+ if( bl->type == BL_NPC )
+ safestrncpy(dummy_sd.status.name, ((TBL_NPC*)bl)->name, NAME_LENGTH);
+ }
+ }
+
+ // compatibility with previous implementation (deprecated!)
+ if( cmd[0] != atcommand_symbol )
+ {
+ cmd += strlen(sd->status.name);
+ while( *cmd != atcommand_symbol && *cmd != 0 )
+ cmd++;
+ }
+
+ is_atcommand(fd, sd, cmd, 1);
+ return 0;
}
BUILDIN_FUNC(checkre)
{
- int num;
-
- num=script_getnum(st,2);
- switch (num) {
- case 0:
-#ifdef RENEWAL
- script_pushint(st, 1);
-#else
- script_pushint(st, 0);
-#endif
- break;
- case 1:
-#ifdef RENEWAL_CAST
- script_pushint(st, 1);
-#else
- script_pushint(st, 0);
-#endif
- break;
- case 2:
-#ifdef RENEWAL_DROP
- script_pushint(st, 1);
-#else
- script_pushint(st, 0);
-#endif
- break;
- case 3:
-#ifdef RENEWAL_EXP
- script_pushint(st, 1);
-#else
- script_pushint(st, 0);
-#endif
- break;
- case 4:
-#ifdef RENEWAL_LVDMG
- script_pushint(st, 1);
-#else
- script_pushint(st, 0);
-#endif
- break;
- case 5:
-#ifdef RENEWAL_EDP
- script_pushint(st, 1);
-#else
- script_pushint(st, 0);
-#endif
- break;
- case 6:
-#ifdef RENEWAL_ASPD
- script_pushint(st, 1);
-#else
- script_pushint(st, 0);
-#endif
- break;
- default:
- ShowWarning("buildin_checkre: unknown parameter.\n");
- break;
- }
- return 0;
+ int num;
+
+ num=script_getnum(st,2);
+ switch(num){
+ case 0:
+ #ifdef RENEWAL
+ script_pushint(st, 1);
+ #else
+ script_pushint(st, 0);
+ #endif
+ break;
+ case 1:
+ #ifdef RENEWAL_CAST
+ script_pushint(st, 1);
+ #else
+ script_pushint(st, 0);
+ #endif
+ break;
+ case 2:
+ #ifdef RENEWAL_DROP
+ script_pushint(st, 1);
+ #else
+ script_pushint(st, 0);
+ #endif
+ break;
+ case 3:
+ #ifdef RENEWAL_EXP
+ script_pushint(st, 1);
+ #else
+ script_pushint(st, 0);
+ #endif
+ break;
+ case 4:
+ #ifdef RENEWAL_LVDMG
+ script_pushint(st, 1);
+ #else
+ script_pushint(st, 0);
+ #endif
+ break;
+ case 5:
+ #ifdef RENEWAL_EDP
+ script_pushint(st, 1);
+ #else
+ script_pushint(st, 0);
+ #endif
+ break;
+ case 6:
+ #ifdef RENEWAL_ASPD
+ script_pushint(st, 1);
+ #else
+ script_pushint(st, 0);
+ #endif
+ break;
+ default:
+ ShowWarning("buildin_checkre: unknown parameter.\n");
+ break;
+ }
+ return 0;
}
/* getrandgroupitem <group_id>,<quantity> */
-BUILDIN_FUNC(getrandgroupitem)
-{
- TBL_PC *sd;
- int i, get_count = 0, flag, nameid, group = script_getnum(st, 2), qty = script_getnum(st,3);
- struct item item_tmp;
+BUILDIN_FUNC(getrandgroupitem) {
+ TBL_PC* sd;
+ int i, get_count = 0, flag, nameid, group = script_getnum(st, 2), qty = script_getnum(st,3);
+ struct item item_tmp;
- if (!(sd = script_rid2sd(st)))
- return 0;
+ if( !( sd = script_rid2sd(st) ) )
+ return 0;
- if (qty <= 0) {
- ShowError("getrandgroupitem: qty is <= 0!\n");
- return 1;
- }
- if ((nameid = itemdb_searchrandomid(group)) == UNKNOWN_ITEM_ID) {
- return 1;/* itemdb_searchrandomid will already scream a error */
- }
+ if( qty <= 0 ) {
+ ShowError("getrandgroupitem: qty is <= 0!\n");
+ return 1;
+ }
+ if( (nameid = itemdb_searchrandomid(group)) == UNKNOWN_ITEM_ID ) {
+ return 1;/* itemdb_searchrandomid will already scream a error */
+ }
- memset(&item_tmp,0,sizeof(item_tmp));
+ memset(&item_tmp,0,sizeof(item_tmp));
- item_tmp.nameid = nameid;
- item_tmp.identify = itemdb_isidentified(nameid);
+ item_tmp.nameid = nameid;
+ item_tmp.identify = itemdb_isidentified(nameid);
- //Check if it's stackable.
- if (!itemdb_isstackable(nameid))
- get_count = 1;
- else
- get_count = qty;
+ //Check if it's stackable.
+ if (!itemdb_isstackable(nameid))
+ get_count = 1;
+ else
+ get_count = qty;
- for (i = 0; i < qty; i += get_count) {
- // if not pet egg
- if (!pet_create_egg(sd, nameid)) {
- if ((flag = pc_additem(sd, &item_tmp, get_count, LOG_TYPE_SCRIPT))) {
- clif_additem(sd, 0, 0, flag);
- if (pc_candrop(sd,&item_tmp))
- map_addflooritem(&item_tmp,get_count,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
- }
- }
- }
+ for (i = 0; i < qty; i += get_count) {
+ // if not pet egg
+ if (!pet_create_egg(sd, nameid)) {
+ if ((flag = pc_additem(sd, &item_tmp, get_count, LOG_TYPE_SCRIPT))) {
+ clif_additem(sd, 0, 0, flag);
+ if( pc_candrop(sd,&item_tmp) )
+ map_addflooritem(&item_tmp,get_count,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ }
+ }
+ }
- return 0;
-}
-
-/* cleanmap <map_name>;
- * cleanfloor <map_name, <x0>, <y0>, <x1>, <y1>; */
-static int atcommand_cleanfloor_sub(struct block_list *bl, va_list ap)
-{
- nullpo_ret(bl);
- map_clearflooritem(bl);
-
- return 0;
-}
-
-BUILDIN_FUNC(cleanmap)
-{
- const char *map;
- int m = -1, index = -1;
- short x0 = 0, y0 = 0, x1 = 0, y1 = 0;
-
- map = script_getstr(st, 2);
- index = mapindex_name2id(map);
- if (index)
- m = map_mapindex2mapid(index);
-
- if (!m)
- return 1;
-
- if ((script_lastdata(st) - 2) < 4) {
- map_foreachinmap(atcommand_cleanfloor_sub, m, BL_ITEM);
- } else {
- x0 = script_getnum(st, 3);
- y0 = script_getnum(st, 4);
- x1 = script_getnum(st, 5);
- y1 = script_getnum(st, 6);
- if (x0 > 0 && y0 > 0 && x1 > 0 && y1 > 0) {
- map_foreachinarea(atcommand_cleanfloor_sub, m, x0, y0, x1, y1, BL_ITEM);
- } else {
- ShowError("cleanarea: invalid coordinate defined!\n");
- return 1;
- }
- }
-
- return 0;
+ return 0;
}
@@ -17404,450 +17239,448 @@ BUILDIN_FUNC(deletepset);
/// script command definitions
/// for an explanation on args, see add_buildin_func
struct script_function buildin_func[] = {
- // NPC interaction
- BUILDIN_DEF(mes,"s*"),
- BUILDIN_DEF(next,""),
- BUILDIN_DEF(close,""),
- BUILDIN_DEF(close2,""),
- BUILDIN_DEF(menu,"sl*"),
- BUILDIN_DEF(select,"s*"), //for future jA script compatibility
- BUILDIN_DEF(prompt,"s*"),
- //
- BUILDIN_DEF(goto,"l"),
- BUILDIN_DEF(callsub,"l*"),
- BUILDIN_DEF(callfunc,"s*"),
- BUILDIN_DEF(return,"?"),
- BUILDIN_DEF(getarg,"i?"),
- BUILDIN_DEF(jobchange,"i?"),
- BUILDIN_DEF(jobname,"i"),
- BUILDIN_DEF(input,"r??"),
- BUILDIN_DEF(warp,"sii"),
- BUILDIN_DEF(areawarp,"siiiisii??"),
- BUILDIN_DEF(warpchar,"siii"), // [LuzZza]
- BUILDIN_DEF(warpparty,"siii?"), // [Fredzilla] [Paradox924X]
- BUILDIN_DEF(warpguild,"siii"), // [Fredzilla]
- BUILDIN_DEF(setlook,"ii"),
- BUILDIN_DEF(changelook,"ii"), // Simulates but don't Store it
- BUILDIN_DEF(set,"rv"),
- BUILDIN_DEF(setarray,"rv*"),
- BUILDIN_DEF(cleararray,"rvi"),
- BUILDIN_DEF(copyarray,"rri"),
- BUILDIN_DEF(getarraysize,"r"),
- BUILDIN_DEF(deletearray,"r?"),
- BUILDIN_DEF(getelementofarray,"ri"),
- BUILDIN_DEF(getitem,"vi?"),
- BUILDIN_DEF(rentitem,"vi"),
- BUILDIN_DEF(getitem2,"viiiiiiii?"),
- BUILDIN_DEF(getnameditem,"vv"),
- BUILDIN_DEF2(grouprandomitem,"groupranditem","i"),
- BUILDIN_DEF(makeitem,"visii"),
- BUILDIN_DEF(delitem,"vi?"),
- BUILDIN_DEF(delitem2,"viiiiiiii?"),
- BUILDIN_DEF2(enableitemuse,"enable_items",""),
- BUILDIN_DEF2(disableitemuse,"disable_items",""),
- BUILDIN_DEF(cutin,"si"),
- BUILDIN_DEF(viewpoint,"iiiii"),
- BUILDIN_DEF(heal,"ii"),
- BUILDIN_DEF(itemheal,"ii"),
- BUILDIN_DEF(percentheal,"ii"),
- BUILDIN_DEF(rand,"i?"),
- BUILDIN_DEF(countitem,"v"),
- BUILDIN_DEF(countitem2,"viiiiiii"),
- BUILDIN_DEF(checkweight,"vi*"),
- BUILDIN_DEF(checkweight2,"rr"),
- BUILDIN_DEF(readparam,"i?"),
- BUILDIN_DEF(getcharid,"i?"),
- BUILDIN_DEF(getnpcid,"i?"),
- BUILDIN_DEF(getpartyname,"i"),
- BUILDIN_DEF(getpartymember,"i?"),
- BUILDIN_DEF(getpartyleader,"i?"),
- BUILDIN_DEF(getguildname,"i"),
- BUILDIN_DEF(getguildmaster,"i"),
- BUILDIN_DEF(getguildmasterid,"i"),
- BUILDIN_DEF(strcharinfo,"i"),
- BUILDIN_DEF(strnpcinfo,"i"),
- BUILDIN_DEF(getequipid,"i"),
- BUILDIN_DEF(getequipname,"i"),
- BUILDIN_DEF(getbrokenid,"i"), // [Valaris]
- BUILDIN_DEF(repair,"i"), // [Valaris]
- BUILDIN_DEF(repairall,""),
- BUILDIN_DEF(getequipisequiped,"i"),
- BUILDIN_DEF(getequipisenableref,"i"),
- BUILDIN_DEF(getequipisidentify,"i"),
- BUILDIN_DEF(getequiprefinerycnt,"i"),
- BUILDIN_DEF(getequipweaponlv,"i"),
- BUILDIN_DEF(getequippercentrefinery,"i"),
- BUILDIN_DEF(successrefitem,"i"),
- BUILDIN_DEF(failedrefitem,"i"),
- BUILDIN_DEF(downrefitem,"i"),
- BUILDIN_DEF(statusup,"i"),
- BUILDIN_DEF(statusup2,"ii"),
- BUILDIN_DEF(bonus,"iv"),
- BUILDIN_DEF2(bonus,"bonus2","ivi"),
- BUILDIN_DEF2(bonus,"bonus3","ivii"),
- BUILDIN_DEF2(bonus,"bonus4","ivvii"),
- BUILDIN_DEF2(bonus,"bonus5","ivviii"),
- BUILDIN_DEF(autobonus,"sii??"),
- BUILDIN_DEF(autobonus2,"sii??"),
- BUILDIN_DEF(autobonus3,"siiv?"),
- BUILDIN_DEF(skill,"vi?"),
- BUILDIN_DEF(addtoskill,"vi?"), // [Valaris]
- BUILDIN_DEF(guildskill,"vi"),
- BUILDIN_DEF(getskilllv,"v"),
- BUILDIN_DEF(getgdskilllv,"iv"),
- BUILDIN_DEF(basicskillcheck,""),
- BUILDIN_DEF(getgmlevel,""),
- BUILDIN_DEF(getgroupid,""),
- BUILDIN_DEF(end,""),
- BUILDIN_DEF(checkoption,"i"),
- BUILDIN_DEF(setoption,"i?"),
- BUILDIN_DEF(setcart,"?"),
- BUILDIN_DEF(checkcart,""),
- BUILDIN_DEF(setfalcon,"?"),
- BUILDIN_DEF(checkfalcon,""),
- BUILDIN_DEF(setriding,"?"),
- BUILDIN_DEF(checkriding,""),
- BUILDIN_DEF(checkwug,""),
- BUILDIN_DEF(checkmadogear,""),
- BUILDIN_DEF(setmadogear,"?"),
- BUILDIN_DEF2(savepoint,"save","sii"),
- BUILDIN_DEF(savepoint,"sii"),
- BUILDIN_DEF(gettimetick,"i"),
- BUILDIN_DEF(gettime,"i"),
- BUILDIN_DEF(gettimestr,"si"),
- BUILDIN_DEF(openstorage,""),
- BUILDIN_DEF(guildopenstorage,""),
- BUILDIN_DEF(itemskill,"vi"),
- BUILDIN_DEF(produce,"i"),
- BUILDIN_DEF(cooking,"i"),
- BUILDIN_DEF(monster,"siisii???"),
- BUILDIN_DEF(getmobdrops,"i"),
- BUILDIN_DEF(areamonster,"siiiisii???"),
- BUILDIN_DEF(killmonster,"ss?"),
- BUILDIN_DEF(killmonsterall,"s?"),
- BUILDIN_DEF(clone,"siisi????"),
- BUILDIN_DEF(doevent,"s"),
- BUILDIN_DEF(donpcevent,"s"),
- BUILDIN_DEF(cmdothernpc,"ss"),
- BUILDIN_DEF(addtimer,"is"),
- BUILDIN_DEF(deltimer,"s"),
- BUILDIN_DEF(addtimercount,"si"),
- BUILDIN_DEF(initnpctimer,"??"),
- BUILDIN_DEF(stopnpctimer,"??"),
- BUILDIN_DEF(startnpctimer,"??"),
- BUILDIN_DEF(setnpctimer,"i?"),
- BUILDIN_DEF(getnpctimer,"i?"),
- BUILDIN_DEF(attachnpctimer,"?"), // attached the player id to the npc timer [Celest]
- BUILDIN_DEF(detachnpctimer,"?"), // detached the player id from the npc timer [Celest]
- BUILDIN_DEF(playerattached,""), // returns id of the current attached player. [Skotlex]
- BUILDIN_DEF(announce,"si?????"),
- BUILDIN_DEF(mapannounce,"ssi?????"),
- BUILDIN_DEF(areaannounce,"siiiisi?????"),
- BUILDIN_DEF(getusers,"i"),
- BUILDIN_DEF(getmapguildusers,"si"),
- BUILDIN_DEF(getmapusers,"s"),
- BUILDIN_DEF(getareausers,"siiii"),
- BUILDIN_DEF(getareadropitem,"siiiiv"),
- BUILDIN_DEF(enablenpc,"s"),
- BUILDIN_DEF(disablenpc,"s"),
- BUILDIN_DEF(hideoffnpc,"s"),
- BUILDIN_DEF(hideonnpc,"s"),
- BUILDIN_DEF(sc_start,"iii?"),
- BUILDIN_DEF(sc_start2,"iiii?"),
- BUILDIN_DEF(sc_start4,"iiiiii?"),
- BUILDIN_DEF(sc_end,"i?"),
- BUILDIN_DEF(getstatus, "i?"),
- BUILDIN_DEF(getscrate,"ii?"),
- BUILDIN_DEF(debugmes,"s"),
- BUILDIN_DEF2(catchpet,"pet","i"),
- BUILDIN_DEF2(birthpet,"bpet",""),
- BUILDIN_DEF(resetlvl,"i"),
- BUILDIN_DEF(resetstatus,""),
- BUILDIN_DEF(resetskill,""),
- BUILDIN_DEF(skillpointcount,""),
- BUILDIN_DEF(changebase,"i?"),
- BUILDIN_DEF(changesex,""),
- BUILDIN_DEF(waitingroom,"si?????"),
- BUILDIN_DEF(delwaitingroom,"?"),
- BUILDIN_DEF2(waitingroomkickall,"kickwaitingroomall","?"),
- BUILDIN_DEF(enablewaitingroomevent,"?"),
- BUILDIN_DEF(disablewaitingroomevent,"?"),
- BUILDIN_DEF2(enablewaitingroomevent,"enablearena",""), // Added by RoVeRT
- BUILDIN_DEF2(disablewaitingroomevent,"disablearena",""), // Added by RoVeRT
- BUILDIN_DEF(getwaitingroomstate,"i?"),
- BUILDIN_DEF(warpwaitingpc,"sii?"),
- BUILDIN_DEF(attachrid,"i"),
- BUILDIN_DEF(detachrid,""),
- BUILDIN_DEF(isloggedin,"i?"),
- BUILDIN_DEF(setmapflagnosave,"ssii"),
- BUILDIN_DEF(getmapflag,"si"),
- BUILDIN_DEF(setmapflag,"si?"),
- BUILDIN_DEF(removemapflag,"si?"),
- BUILDIN_DEF(pvpon,"s"),
- BUILDIN_DEF(pvpoff,"s"),
- BUILDIN_DEF(gvgon,"s"),
- BUILDIN_DEF(gvgoff,"s"),
- BUILDIN_DEF(emotion,"i??"),
- BUILDIN_DEF(maprespawnguildid,"sii"),
- BUILDIN_DEF(agitstart,""), // <Agit>
- BUILDIN_DEF(agitend,""),
- BUILDIN_DEF(agitcheck,""), // <Agitcheck>
- BUILDIN_DEF(flagemblem,"i"), // Flag Emblem
- BUILDIN_DEF(getcastlename,"s"),
- BUILDIN_DEF(getcastledata,"si"),
- BUILDIN_DEF(setcastledata,"sii"),
- BUILDIN_DEF(requestguildinfo,"i?"),
- BUILDIN_DEF(getequipcardcnt,"i"),
- BUILDIN_DEF(successremovecards,"i"),
- BUILDIN_DEF(failedremovecards,"ii"),
- BUILDIN_DEF(marriage,"s"),
- BUILDIN_DEF2(wedding_effect,"wedding",""),
- BUILDIN_DEF(divorce,""),
- BUILDIN_DEF(ispartneron,""),
- BUILDIN_DEF(getpartnerid,""),
- BUILDIN_DEF(getchildid,""),
- BUILDIN_DEF(getmotherid,""),
- BUILDIN_DEF(getfatherid,""),
- BUILDIN_DEF(warppartner,"sii"),
- BUILDIN_DEF(getitemname,"v"),
- BUILDIN_DEF(getitemslots,"i"),
- BUILDIN_DEF(makepet,"i"),
- BUILDIN_DEF(getexp,"ii"),
- BUILDIN_DEF(getinventorylist,""),
- BUILDIN_DEF(getskilllist,""),
- BUILDIN_DEF(clearitem,""),
- BUILDIN_DEF(classchange,"ii"),
- BUILDIN_DEF(misceffect,"i"),
- BUILDIN_DEF(playBGM,"s"),
- BUILDIN_DEF(playBGMall,"s?????"),
- BUILDIN_DEF(soundeffect,"si"),
- BUILDIN_DEF(soundeffectall,"si?????"), // SoundEffectAll [Codemaster]
- BUILDIN_DEF(strmobinfo,"ii"), // display mob data [Valaris]
- BUILDIN_DEF(guardian,"siisi??"), // summon guardians
- BUILDIN_DEF(guardianinfo,"sii"), // display guardian data [Valaris]
- BUILDIN_DEF(petskillbonus,"iiii"), // [Valaris]
- BUILDIN_DEF(petrecovery,"ii"), // [Valaris]
- BUILDIN_DEF(petloot,"i"), // [Valaris]
- BUILDIN_DEF(petheal,"iiii"), // [Valaris]
- BUILDIN_DEF(petskillattack,"viii"), // [Skotlex]
- BUILDIN_DEF(petskillattack2,"viiii"), // [Valaris]
- BUILDIN_DEF(petskillsupport,"viiii"), // [Skotlex]
- BUILDIN_DEF(skilleffect,"vi"), // skill effect [Celest]
- BUILDIN_DEF(npcskilleffect,"viii"), // npc skill effect [Valaris]
- BUILDIN_DEF(specialeffect,"i??"), // npc skill effect [Valaris]
- BUILDIN_DEF(specialeffect2,"i??"), // skill effect on players[Valaris]
- BUILDIN_DEF(nude,""), // nude command [Valaris]
- BUILDIN_DEF(mapwarp,"ssii??"), // Added by RoVeRT
- BUILDIN_DEF(atcommand,"s"), // [MouseJstr]
- BUILDIN_DEF2(atcommand,"charcommand","s"), // [MouseJstr]
- BUILDIN_DEF(movenpc,"sii?"), // [MouseJstr]
- BUILDIN_DEF(message,"ss"), // [MouseJstr]
- BUILDIN_DEF(npctalk,"s"), // [Valaris]
- BUILDIN_DEF(mobcount,"ss"),
- BUILDIN_DEF(getlook,"i"),
- BUILDIN_DEF(getsavepoint,"i"),
- BUILDIN_DEF(npcspeed,"i"), // [Valaris]
- BUILDIN_DEF(npcwalkto,"ii"), // [Valaris]
- BUILDIN_DEF(npcstop,""), // [Valaris]
- BUILDIN_DEF(getmapxy,"rrri?"), //by Lorky [Lupus]
- BUILDIN_DEF(checkoption1,"i"),
- BUILDIN_DEF(checkoption2,"i"),
- BUILDIN_DEF(guildgetexp,"i"),
- BUILDIN_DEF(guildchangegm,"is"),
- BUILDIN_DEF(logmes,"s"), //this command actls as MES but rints info into LOG file either SQL/TXT [Lupus]
- BUILDIN_DEF(summon,"si??"), // summons a slave monster [Celest]
- BUILDIN_DEF(isnight,""), // check whether it is night time [Celest]
- BUILDIN_DEF(isday,""), // check whether it is day time [Celest]
- BUILDIN_DEF(isequipped,"i*"), // check whether another item/card has been equipped [Celest]
- BUILDIN_DEF(isequippedcnt,"i*"), // check how many items/cards are being equipped [Celest]
- BUILDIN_DEF(cardscnt,"i*"), // check how many items/cards are being equipped in the same arm [Lupus]
- BUILDIN_DEF(getrefine,""), // returns the refined number of the current item, or an item with index specified [celest]
- BUILDIN_DEF(night,""), // sets the server to night time
- BUILDIN_DEF(day,""), // sets the server to day time
+ // NPC interaction
+ BUILDIN_DEF(mes,"s*"),
+ BUILDIN_DEF(next,""),
+ BUILDIN_DEF(close,""),
+ BUILDIN_DEF(close2,""),
+ BUILDIN_DEF(menu,"sl*"),
+ BUILDIN_DEF(select,"s*"), //for future jA script compatibility
+ BUILDIN_DEF(prompt,"s*"),
+ //
+ BUILDIN_DEF(goto,"l"),
+ BUILDIN_DEF(callsub,"l*"),
+ BUILDIN_DEF(callfunc,"s*"),
+ BUILDIN_DEF(return,"?"),
+ BUILDIN_DEF(getarg,"i?"),
+ BUILDIN_DEF(jobchange,"i?"),
+ BUILDIN_DEF(jobname,"i"),
+ BUILDIN_DEF(input,"r??"),
+ BUILDIN_DEF(warp,"sii"),
+ BUILDIN_DEF(areawarp,"siiiisii??"),
+ BUILDIN_DEF(warpchar,"siii"), // [LuzZza]
+ BUILDIN_DEF(warpparty,"siii?"), // [Fredzilla] [Paradox924X]
+ BUILDIN_DEF(warpguild,"siii"), // [Fredzilla]
+ BUILDIN_DEF(setlook,"ii"),
+ BUILDIN_DEF(changelook,"ii"), // Simulates but don't Store it
+ BUILDIN_DEF(set,"rv"),
+ BUILDIN_DEF(setarray,"rv*"),
+ BUILDIN_DEF(cleararray,"rvi"),
+ BUILDIN_DEF(copyarray,"rri"),
+ BUILDIN_DEF(getarraysize,"r"),
+ BUILDIN_DEF(deletearray,"r?"),
+ BUILDIN_DEF(getelementofarray,"ri"),
+ BUILDIN_DEF(getitem,"vi?"),
+ BUILDIN_DEF(rentitem,"vi"),
+ BUILDIN_DEF(getitem2,"viiiiiiii?"),
+ BUILDIN_DEF(getnameditem,"vv"),
+ BUILDIN_DEF2(grouprandomitem,"groupranditem","i"),
+ BUILDIN_DEF(makeitem,"visii"),
+ BUILDIN_DEF(delitem,"vi?"),
+ BUILDIN_DEF(delitem2,"viiiiiiii?"),
+ BUILDIN_DEF2(enableitemuse,"enable_items",""),
+ BUILDIN_DEF2(disableitemuse,"disable_items",""),
+ BUILDIN_DEF(cutin,"si"),
+ BUILDIN_DEF(viewpoint,"iiiii"),
+ BUILDIN_DEF(heal,"ii"),
+ BUILDIN_DEF(itemheal,"ii"),
+ BUILDIN_DEF(percentheal,"ii"),
+ BUILDIN_DEF(rand,"i?"),
+ BUILDIN_DEF(countitem,"v"),
+ BUILDIN_DEF(countitem2,"viiiiiii"),
+ BUILDIN_DEF(checkweight,"vi*"),
+ BUILDIN_DEF(checkweight2,"rr"),
+ BUILDIN_DEF(readparam,"i?"),
+ BUILDIN_DEF(getcharid,"i?"),
+ BUILDIN_DEF(getnpcid,"i?"),
+ BUILDIN_DEF(getpartyname,"i"),
+ BUILDIN_DEF(getpartymember,"i?"),
+ BUILDIN_DEF(getpartyleader,"i?"),
+ BUILDIN_DEF(getguildname,"i"),
+ BUILDIN_DEF(getguildmaster,"i"),
+ BUILDIN_DEF(getguildmasterid,"i"),
+ BUILDIN_DEF(strcharinfo,"i"),
+ BUILDIN_DEF(strnpcinfo,"i"),
+ BUILDIN_DEF(getequipid,"i"),
+ BUILDIN_DEF(getequipname,"i"),
+ BUILDIN_DEF(getbrokenid,"i"), // [Valaris]
+ BUILDIN_DEF(repair,"i"), // [Valaris]
+ BUILDIN_DEF(repairall,""),
+ BUILDIN_DEF(getequipisequiped,"i"),
+ BUILDIN_DEF(getequipisenableref,"i"),
+ BUILDIN_DEF(getequipisidentify,"i"),
+ BUILDIN_DEF(getequiprefinerycnt,"i"),
+ BUILDIN_DEF(getequipweaponlv,"i"),
+ BUILDIN_DEF(getequippercentrefinery,"i"),
+ BUILDIN_DEF(successrefitem,"i"),
+ BUILDIN_DEF(failedrefitem,"i"),
+ BUILDIN_DEF(downrefitem,"i"),
+ BUILDIN_DEF(statusup,"i"),
+ BUILDIN_DEF(statusup2,"ii"),
+ BUILDIN_DEF(bonus,"iv"),
+ BUILDIN_DEF2(bonus,"bonus2","ivi"),
+ BUILDIN_DEF2(bonus,"bonus3","ivii"),
+ BUILDIN_DEF2(bonus,"bonus4","ivvii"),
+ BUILDIN_DEF2(bonus,"bonus5","ivviii"),
+ BUILDIN_DEF(autobonus,"sii??"),
+ BUILDIN_DEF(autobonus2,"sii??"),
+ BUILDIN_DEF(autobonus3,"siiv?"),
+ BUILDIN_DEF(skill,"vi?"),
+ BUILDIN_DEF(addtoskill,"vi?"), // [Valaris]
+ BUILDIN_DEF(guildskill,"vi"),
+ BUILDIN_DEF(getskilllv,"v"),
+ BUILDIN_DEF(getgdskilllv,"iv"),
+ BUILDIN_DEF(basicskillcheck,""),
+ BUILDIN_DEF(getgmlevel,""),
+ BUILDIN_DEF(getgroupid,""),
+ BUILDIN_DEF(end,""),
+ BUILDIN_DEF(checkoption,"i"),
+ BUILDIN_DEF(setoption,"i?"),
+ BUILDIN_DEF(setcart,"?"),
+ BUILDIN_DEF(checkcart,""),
+ BUILDIN_DEF(setfalcon,"?"),
+ BUILDIN_DEF(checkfalcon,""),
+ BUILDIN_DEF(setriding,"?"),
+ BUILDIN_DEF(checkriding,""),
+ BUILDIN_DEF(checkwug,""),
+ BUILDIN_DEF(checkmadogear,""),
+ BUILDIN_DEF(setmadogear,"?"),
+ BUILDIN_DEF2(savepoint,"save","sii"),
+ BUILDIN_DEF(savepoint,"sii"),
+ BUILDIN_DEF(gettimetick,"i"),
+ BUILDIN_DEF(gettime,"i"),
+ BUILDIN_DEF(gettimestr,"si"),
+ BUILDIN_DEF(openstorage,""),
+ BUILDIN_DEF(guildopenstorage,""),
+ BUILDIN_DEF(itemskill,"vi"),
+ BUILDIN_DEF(produce,"i"),
+ BUILDIN_DEF(cooking,"i"),
+ BUILDIN_DEF(monster,"siisii???"),
+ BUILDIN_DEF(getmobdrops,"i"),
+ BUILDIN_DEF(areamonster,"siiiisii???"),
+ BUILDIN_DEF(killmonster,"ss?"),
+ BUILDIN_DEF(killmonsterall,"s?"),
+ BUILDIN_DEF(clone,"siisi????"),
+ BUILDIN_DEF(doevent,"s"),
+ BUILDIN_DEF(donpcevent,"s"),
+ BUILDIN_DEF(cmdothernpc,"ss"),
+ BUILDIN_DEF(addtimer,"is"),
+ BUILDIN_DEF(deltimer,"s"),
+ BUILDIN_DEF(addtimercount,"si"),
+ BUILDIN_DEF(initnpctimer,"??"),
+ BUILDIN_DEF(stopnpctimer,"??"),
+ BUILDIN_DEF(startnpctimer,"??"),
+ BUILDIN_DEF(setnpctimer,"i?"),
+ BUILDIN_DEF(getnpctimer,"i?"),
+ BUILDIN_DEF(attachnpctimer,"?"), // attached the player id to the npc timer [Celest]
+ BUILDIN_DEF(detachnpctimer,"?"), // detached the player id from the npc timer [Celest]
+ BUILDIN_DEF(playerattached,""), // returns id of the current attached player. [Skotlex]
+ BUILDIN_DEF(announce,"si?????"),
+ BUILDIN_DEF(mapannounce,"ssi?????"),
+ BUILDIN_DEF(areaannounce,"siiiisi?????"),
+ BUILDIN_DEF(getusers,"i"),
+ BUILDIN_DEF(getmapguildusers,"si"),
+ BUILDIN_DEF(getmapusers,"s"),
+ BUILDIN_DEF(getareausers,"siiii"),
+ BUILDIN_DEF(getareadropitem,"siiiiv"),
+ BUILDIN_DEF(enablenpc,"s"),
+ BUILDIN_DEF(disablenpc,"s"),
+ BUILDIN_DEF(hideoffnpc,"s"),
+ BUILDIN_DEF(hideonnpc,"s"),
+ BUILDIN_DEF(sc_start,"iii?"),
+ BUILDIN_DEF(sc_start2,"iiii?"),
+ BUILDIN_DEF(sc_start4,"iiiiii?"),
+ BUILDIN_DEF(sc_end,"i?"),
+ BUILDIN_DEF(getstatus, "i?"),
+ BUILDIN_DEF(getscrate,"ii?"),
+ BUILDIN_DEF(debugmes,"s"),
+ BUILDIN_DEF2(catchpet,"pet","i"),
+ BUILDIN_DEF2(birthpet,"bpet",""),
+ BUILDIN_DEF(resetlvl,"i"),
+ BUILDIN_DEF(resetstatus,""),
+ BUILDIN_DEF(resetskill,""),
+ BUILDIN_DEF(skillpointcount,""),
+ BUILDIN_DEF(changebase,"i?"),
+ BUILDIN_DEF(changesex,""),
+ BUILDIN_DEF(waitingroom,"si?????"),
+ BUILDIN_DEF(delwaitingroom,"?"),
+ BUILDIN_DEF2(waitingroomkickall,"kickwaitingroomall","?"),
+ BUILDIN_DEF(enablewaitingroomevent,"?"),
+ BUILDIN_DEF(disablewaitingroomevent,"?"),
+ BUILDIN_DEF2(enablewaitingroomevent,"enablearena",""), // Added by RoVeRT
+ BUILDIN_DEF2(disablewaitingroomevent,"disablearena",""), // Added by RoVeRT
+ BUILDIN_DEF(getwaitingroomstate,"i?"),
+ BUILDIN_DEF(warpwaitingpc,"sii?"),
+ BUILDIN_DEF(attachrid,"i"),
+ BUILDIN_DEF(detachrid,""),
+ BUILDIN_DEF(isloggedin,"i?"),
+ BUILDIN_DEF(setmapflagnosave,"ssii"),
+ BUILDIN_DEF(getmapflag,"si"),
+ BUILDIN_DEF(setmapflag,"si?"),
+ BUILDIN_DEF(removemapflag,"si?"),
+ BUILDIN_DEF(pvpon,"s"),
+ BUILDIN_DEF(pvpoff,"s"),
+ BUILDIN_DEF(gvgon,"s"),
+ BUILDIN_DEF(gvgoff,"s"),
+ BUILDIN_DEF(emotion,"i??"),
+ BUILDIN_DEF(maprespawnguildid,"sii"),
+ BUILDIN_DEF(agitstart,""), // <Agit>
+ BUILDIN_DEF(agitend,""),
+ BUILDIN_DEF(agitcheck,""), // <Agitcheck>
+ BUILDIN_DEF(flagemblem,"i"), // Flag Emblem
+ BUILDIN_DEF(getcastlename,"s"),
+ BUILDIN_DEF(getcastledata,"si"),
+ BUILDIN_DEF(setcastledata,"sii"),
+ BUILDIN_DEF(requestguildinfo,"i?"),
+ BUILDIN_DEF(getequipcardcnt,"i"),
+ BUILDIN_DEF(successremovecards,"i"),
+ BUILDIN_DEF(failedremovecards,"ii"),
+ BUILDIN_DEF(marriage,"s"),
+ BUILDIN_DEF2(wedding_effect,"wedding",""),
+ BUILDIN_DEF(divorce,""),
+ BUILDIN_DEF(ispartneron,""),
+ BUILDIN_DEF(getpartnerid,""),
+ BUILDIN_DEF(getchildid,""),
+ BUILDIN_DEF(getmotherid,""),
+ BUILDIN_DEF(getfatherid,""),
+ BUILDIN_DEF(warppartner,"sii"),
+ BUILDIN_DEF(getitemname,"v"),
+ BUILDIN_DEF(getitemslots,"i"),
+ BUILDIN_DEF(makepet,"i"),
+ BUILDIN_DEF(getexp,"ii"),
+ BUILDIN_DEF(getinventorylist,""),
+ BUILDIN_DEF(getskilllist,""),
+ BUILDIN_DEF(clearitem,""),
+ BUILDIN_DEF(classchange,"ii"),
+ BUILDIN_DEF(misceffect,"i"),
+ BUILDIN_DEF(playBGM,"s"),
+ BUILDIN_DEF(playBGMall,"s?????"),
+ BUILDIN_DEF(soundeffect,"si"),
+ BUILDIN_DEF(soundeffectall,"si?????"), // SoundEffectAll [Codemaster]
+ BUILDIN_DEF(strmobinfo,"ii"), // display mob data [Valaris]
+ BUILDIN_DEF(guardian,"siisi??"), // summon guardians
+ BUILDIN_DEF(guardianinfo,"sii"), // display guardian data [Valaris]
+ BUILDIN_DEF(petskillbonus,"iiii"), // [Valaris]
+ BUILDIN_DEF(petrecovery,"ii"), // [Valaris]
+ BUILDIN_DEF(petloot,"i"), // [Valaris]
+ BUILDIN_DEF(petheal,"iiii"), // [Valaris]
+ BUILDIN_DEF(petskillattack,"viii"), // [Skotlex]
+ BUILDIN_DEF(petskillattack2,"viiii"), // [Valaris]
+ BUILDIN_DEF(petskillsupport,"viiii"), // [Skotlex]
+ BUILDIN_DEF(skilleffect,"vi"), // skill effect [Celest]
+ BUILDIN_DEF(npcskilleffect,"viii"), // npc skill effect [Valaris]
+ BUILDIN_DEF(specialeffect,"i??"), // npc skill effect [Valaris]
+ BUILDIN_DEF(specialeffect2,"i??"), // skill effect on players[Valaris]
+ BUILDIN_DEF(nude,""), // nude command [Valaris]
+ BUILDIN_DEF(mapwarp,"ssii??"), // Added by RoVeRT
+ BUILDIN_DEF(atcommand,"s"), // [MouseJstr]
+ BUILDIN_DEF2(atcommand,"charcommand","s"), // [MouseJstr]
+ BUILDIN_DEF(movenpc,"sii?"), // [MouseJstr]
+ BUILDIN_DEF(message,"ss"), // [MouseJstr]
+ BUILDIN_DEF(npctalk,"s"), // [Valaris]
+ BUILDIN_DEF(mobcount,"ss"),
+ BUILDIN_DEF(getlook,"i"),
+ BUILDIN_DEF(getsavepoint,"i"),
+ BUILDIN_DEF(npcspeed,"i"), // [Valaris]
+ BUILDIN_DEF(npcwalkto,"ii"), // [Valaris]
+ BUILDIN_DEF(npcstop,""), // [Valaris]
+ BUILDIN_DEF(getmapxy,"rrri?"), //by Lorky [Lupus]
+ BUILDIN_DEF(checkoption1,"i"),
+ BUILDIN_DEF(checkoption2,"i"),
+ BUILDIN_DEF(guildgetexp,"i"),
+ BUILDIN_DEF(guildchangegm,"is"),
+ BUILDIN_DEF(logmes,"s"), //this command actls as MES but rints info into LOG file either SQL/TXT [Lupus]
+ BUILDIN_DEF(summon,"si??"), // summons a slave monster [Celest]
+ BUILDIN_DEF(isnight,""), // check whether it is night time [Celest]
+ BUILDIN_DEF(isday,""), // check whether it is day time [Celest]
+ BUILDIN_DEF(isequipped,"i*"), // check whether another item/card has been equipped [Celest]
+ BUILDIN_DEF(isequippedcnt,"i*"), // check how many items/cards are being equipped [Celest]
+ BUILDIN_DEF(cardscnt,"i*"), // check how many items/cards are being equipped in the same arm [Lupus]
+ BUILDIN_DEF(getrefine,""), // returns the refined number of the current item, or an item with index specified [celest]
+ BUILDIN_DEF(night,""), // sets the server to night time
+ BUILDIN_DEF(day,""), // sets the server to day time
#ifdef PCRE_SUPPORT
- BUILDIN_DEF(defpattern,"iss"), // Define pattern to listen for [MouseJstr]
- BUILDIN_DEF(activatepset,"i"), // Activate a pattern set [MouseJstr]
- BUILDIN_DEF(deactivatepset,"i"), // Deactive a pattern set [MouseJstr]
- BUILDIN_DEF(deletepset,"i"), // Delete a pattern set [MouseJstr]
+ BUILDIN_DEF(defpattern,"iss"), // Define pattern to listen for [MouseJstr]
+ BUILDIN_DEF(activatepset,"i"), // Activate a pattern set [MouseJstr]
+ BUILDIN_DEF(deactivatepset,"i"), // Deactive a pattern set [MouseJstr]
+ BUILDIN_DEF(deletepset,"i"), // Delete a pattern set [MouseJstr]
#endif
- BUILDIN_DEF(dispbottom,"s"), //added from jA [Lupus]
- BUILDIN_DEF(getusersname,""),
- BUILDIN_DEF(recovery,""),
- BUILDIN_DEF(getpetinfo,"i"),
- BUILDIN_DEF(gethominfo,"i"),
- BUILDIN_DEF(getmercinfo,"i?"),
- BUILDIN_DEF(checkequipedcard,"i"),
- BUILDIN_DEF(jump_zero,"il"), //for future jA script compatibility
- BUILDIN_DEF(globalmes,"s?"), //end jA addition
- BUILDIN_DEF(unequip,"i"), // unequip command [Spectre]
- BUILDIN_DEF(getstrlen,"s"), //strlen [Valaris]
- BUILDIN_DEF(charisalpha,"si"), //isalpha [Valaris]
- BUILDIN_DEF(charat,"si"),
- BUILDIN_DEF(setchar,"ssi"),
- BUILDIN_DEF(insertchar,"ssi"),
- BUILDIN_DEF(delchar,"si"),
- BUILDIN_DEF(strtoupper,"s"),
- BUILDIN_DEF(strtolower,"s"),
- BUILDIN_DEF(charisupper, "si"),
- BUILDIN_DEF(charislower, "si"),
- BUILDIN_DEF(substr,"sii"),
- BUILDIN_DEF(explode, "rss"),
- BUILDIN_DEF(implode, "r?"),
- BUILDIN_DEF(sprintf,"s*"), // [Mirei]
- BUILDIN_DEF(sscanf,"ss*"), // [Mirei]
- BUILDIN_DEF(strpos,"ss?"),
- BUILDIN_DEF(replacestr,"sss??"),
- BUILDIN_DEF(countstr,"ss?"),
- BUILDIN_DEF(setnpcdisplay,"sv??"),
- BUILDIN_DEF(compare,"ss"), // Lordalfa - To bring strstr to scripting Engine.
- BUILDIN_DEF(getiteminfo,"ii"), //[Lupus] returns Items Buy / sell Price, etc info
- BUILDIN_DEF(setiteminfo,"iii"), //[Lupus] set Items Buy / sell Price, etc info
- BUILDIN_DEF(getequipcardid,"ii"), //[Lupus] returns CARD ID or other info from CARD slot N of equipped item
- // [zBuffer] List of mathematics commands --->
- BUILDIN_DEF(sqrt,"i"),
- BUILDIN_DEF(pow,"ii"),
- BUILDIN_DEF(distance,"iiii"),
- // <--- [zBuffer] List of mathematics commands
- BUILDIN_DEF(md5,"s"),
- // [zBuffer] List of dynamic var commands --->
- BUILDIN_DEF(getd,"s"),
- BUILDIN_DEF(setd,"sv"),
- // <--- [zBuffer] List of dynamic var commands
- BUILDIN_DEF(petstat,"i"),
- BUILDIN_DEF(callshop,"s?"), // [Skotlex]
- BUILDIN_DEF(npcshopitem,"sii*"), // [Lance]
- BUILDIN_DEF(npcshopadditem,"sii*"),
- BUILDIN_DEF(npcshopdelitem,"si*"),
- BUILDIN_DEF(npcshopattach,"s?"),
- BUILDIN_DEF(equip,"i"),
- BUILDIN_DEF(autoequip,"ii"),
- BUILDIN_DEF(setbattleflag,"si"),
- BUILDIN_DEF(getbattleflag,"s"),
- BUILDIN_DEF(setitemscript,"is?"), //Set NEW item bonus script. Lupus
- BUILDIN_DEF(disguise,"i"), //disguise player. Lupus
- BUILDIN_DEF(undisguise,""), //undisguise player. Lupus
- BUILDIN_DEF(getmonsterinfo,"ii"), //Lupus
- BUILDIN_DEF(axtoi,"s"),
- BUILDIN_DEF(query_sql,"s*"),
- BUILDIN_DEF(query_logsql,"s*"),
- BUILDIN_DEF(escape_sql,"v"),
- BUILDIN_DEF(atoi,"s"),
- // [zBuffer] List of player cont commands --->
- BUILDIN_DEF(rid2name,"i"),
- BUILDIN_DEF(pcfollow,"ii"),
- BUILDIN_DEF(pcstopfollow,"i"),
- BUILDIN_DEF(pcblockmove,"ii"),
- // <--- [zBuffer] List of player cont commands
- // [zBuffer] List of mob control commands --->
- BUILDIN_DEF(unitwalk,"ii?"),
- BUILDIN_DEF(unitkill,"i"),
- BUILDIN_DEF(unitwarp,"isii"),
- BUILDIN_DEF(unitattack,"iv?"),
- BUILDIN_DEF(unitstop,"i"),
- BUILDIN_DEF(unittalk,"is"),
- BUILDIN_DEF(unitemote,"ii"),
- BUILDIN_DEF(unitskilluseid,"ivi?"), // originally by Qamera [Celest]
- BUILDIN_DEF(unitskillusepos,"iviii"), // [Celest]
- // <--- [zBuffer] List of mob control commands
- BUILDIN_DEF(sleep,"i"),
- BUILDIN_DEF(sleep2,"i"),
- BUILDIN_DEF(awake,"s"),
- BUILDIN_DEF(getvariableofnpc,"rs"),
- BUILDIN_DEF(warpportal,"iisii"),
- BUILDIN_DEF2(homunculus_evolution,"homevolution",""), //[orn]
- BUILDIN_DEF2(homunculus_mutate,"hommutate","?"),
- BUILDIN_DEF2(homunculus_shuffle,"homshuffle",""), //[Zephyrus]
- BUILDIN_DEF(eaclass,"?"), //[Skotlex]
- BUILDIN_DEF(roclass,"i?"), //[Skotlex]
- BUILDIN_DEF(checkvending,"?"),
- BUILDIN_DEF(checkchatting,"?"),
- BUILDIN_DEF(openmail,""),
- BUILDIN_DEF(openauction,""),
- BUILDIN_DEF(checkcell,"siii"),
- BUILDIN_DEF(setcell,"siiiiii"),
- BUILDIN_DEF(setwall,"siiiiis"),
- BUILDIN_DEF(delwall,"s"),
- BUILDIN_DEF(searchitem,"rs"),
- BUILDIN_DEF(mercenary_create,"ii"),
- BUILDIN_DEF(mercenary_heal,"ii"),
- BUILDIN_DEF(mercenary_sc_start,"iii"),
- BUILDIN_DEF(mercenary_get_calls,"i"),
- BUILDIN_DEF(mercenary_get_faith,"i"),
- BUILDIN_DEF(mercenary_set_calls,"ii"),
- BUILDIN_DEF(mercenary_set_faith,"ii"),
- BUILDIN_DEF(readbook,"ii"),
- BUILDIN_DEF(setfont,"i"),
- BUILDIN_DEF(areamobuseskill,"siiiiviiiii"),
- BUILDIN_DEF(progressbar,"si"),
- BUILDIN_DEF(pushpc,"ii"),
- BUILDIN_DEF(buyingstore,"i"),
- BUILDIN_DEF(searchstores,"ii"),
- BUILDIN_DEF(showdigit,"i?"),
- // WoE SE
- BUILDIN_DEF(agitstart2,""),
- BUILDIN_DEF(agitend2,""),
- BUILDIN_DEF(agitcheck2,""),
- // BattleGround
- BUILDIN_DEF(waitingroom2bg,"siiss?"),
- BUILDIN_DEF(waitingroom2bg_single,"isiis"),
- BUILDIN_DEF(bg_team_setxy,"iii"),
- BUILDIN_DEF(bg_warp,"isii"),
- BUILDIN_DEF(bg_monster,"isiisi?"),
- BUILDIN_DEF(bg_monster_set_team,"ii"),
- BUILDIN_DEF(bg_leave,""),
- BUILDIN_DEF(bg_destroy,"i"),
- BUILDIN_DEF(areapercentheal,"siiiiii"),
- BUILDIN_DEF(bg_get_data,"ii"),
- BUILDIN_DEF(bg_getareausers,"isiiii"),
- BUILDIN_DEF(bg_updatescore,"sii"),
-
- // Instancing
- BUILDIN_DEF(instance_create,"si"),
- BUILDIN_DEF(instance_destroy,"?"),
- BUILDIN_DEF(instance_attachmap,"si?"),
- BUILDIN_DEF(instance_detachmap,"s?"),
- BUILDIN_DEF(instance_attach,"i"),
- BUILDIN_DEF(instance_id,"?"),
- BUILDIN_DEF(instance_set_timeout,"ii?"),
- BUILDIN_DEF(instance_init,"i"),
- BUILDIN_DEF(instance_announce,"isi?????"),
- BUILDIN_DEF(instance_npcname,"s?"),
- BUILDIN_DEF(has_instance,"s?"),
- BUILDIN_DEF(instance_warpall,"sii?"),
- BUILDIN_DEF(instance_check_party,"i???"),
- /**
- * 3rd-related
- **/
- BUILDIN_DEF(makerune,"i"),
- BUILDIN_DEF(checkdragon,""),//[Ind]
- BUILDIN_DEF(setdragon,"?"),//[Ind]
- BUILDIN_DEF(ismounting,""),//[Ind]
- BUILDIN_DEF(setmounting,""),//[Ind]
- BUILDIN_DEF(checkre,"i"),
- /**
- * rAthena and beyond!
- **/
- BUILDIN_DEF(getargcount,""),
- BUILDIN_DEF(getcharip,"?"),
- BUILDIN_DEF(is_function,"s"),
- BUILDIN_DEF(get_revision,""),
- BUILDIN_DEF(freeloop,"i"),
- BUILDIN_DEF(getrandgroupitem, "ii"),
- BUILDIN_DEF(cleanmap, "s"),
- BUILDIN_DEF2(cleanmap, "cleanarea", "siiii"),
- /**
- * @commands (script based)
- **/
- BUILDIN_DEF(bindatcmd, "ss??"),
- BUILDIN_DEF(unbindatcmd, "s"),
- BUILDIN_DEF(useatcmd, "s"),
-
- //Quest Log System [Inkfish]
- BUILDIN_DEF(setquest, "i"),
- BUILDIN_DEF(erasequest, "i"),
- BUILDIN_DEF(completequest, "i"),
- BUILDIN_DEF(checkquest, "i?"),
- BUILDIN_DEF(changequest, "ii"),
- BUILDIN_DEF(showevent, "ii"),
- {NULL,NULL,NULL},
+ BUILDIN_DEF(dispbottom,"s"), //added from jA [Lupus]
+ BUILDIN_DEF(getusersname,""),
+ BUILDIN_DEF(recovery,""),
+ BUILDIN_DEF(getpetinfo,"i"),
+ BUILDIN_DEF(gethominfo,"i"),
+ BUILDIN_DEF(getmercinfo,"i?"),
+ BUILDIN_DEF(checkequipedcard,"i"),
+ BUILDIN_DEF(jump_zero,"il"), //for future jA script compatibility
+ BUILDIN_DEF(globalmes,"s?"), //end jA addition
+ BUILDIN_DEF(unequip,"i"), // unequip command [Spectre]
+ BUILDIN_DEF(getstrlen,"s"), //strlen [Valaris]
+ BUILDIN_DEF(charisalpha,"si"), //isalpha [Valaris]
+ BUILDIN_DEF(charat,"si"),
+ BUILDIN_DEF(setchar,"ssi"),
+ BUILDIN_DEF(insertchar,"ssi"),
+ BUILDIN_DEF(delchar,"si"),
+ BUILDIN_DEF(strtoupper,"s"),
+ BUILDIN_DEF(strtolower,"s"),
+ BUILDIN_DEF(charisupper, "si"),
+ BUILDIN_DEF(charislower, "si"),
+ BUILDIN_DEF(substr,"sii"),
+ BUILDIN_DEF(explode, "rss"),
+ BUILDIN_DEF(implode, "r?"),
+ BUILDIN_DEF(sprintf,"s*"), // [Mirei]
+ BUILDIN_DEF(sscanf,"ss*"), // [Mirei]
+ BUILDIN_DEF(strpos,"ss?"),
+ BUILDIN_DEF(replacestr,"sss??"),
+ BUILDIN_DEF(countstr,"ss?"),
+ BUILDIN_DEF(setnpcdisplay,"sv??"),
+ BUILDIN_DEF(compare,"ss"), // Lordalfa - To bring strstr to scripting Engine.
+ BUILDIN_DEF(getiteminfo,"ii"), //[Lupus] returns Items Buy / sell Price, etc info
+ BUILDIN_DEF(setiteminfo,"iii"), //[Lupus] set Items Buy / sell Price, etc info
+ BUILDIN_DEF(getequipcardid,"ii"), //[Lupus] returns CARD ID or other info from CARD slot N of equipped item
+ // [zBuffer] List of mathematics commands --->
+ BUILDIN_DEF(sqrt,"i"),
+ BUILDIN_DEF(pow,"ii"),
+ BUILDIN_DEF(distance,"iiii"),
+ // <--- [zBuffer] List of mathematics commands
+ BUILDIN_DEF(md5,"s"),
+ // [zBuffer] List of dynamic var commands --->
+ BUILDIN_DEF(getd,"s"),
+ BUILDIN_DEF(setd,"sv"),
+ // <--- [zBuffer] List of dynamic var commands
+ BUILDIN_DEF(petstat,"i"),
+ BUILDIN_DEF(callshop,"s?"), // [Skotlex]
+ BUILDIN_DEF(npcshopitem,"sii*"), // [Lance]
+ BUILDIN_DEF(npcshopadditem,"sii*"),
+ BUILDIN_DEF(npcshopdelitem,"si*"),
+ BUILDIN_DEF(npcshopattach,"s?"),
+ BUILDIN_DEF(equip,"i"),
+ BUILDIN_DEF(autoequip,"ii"),
+ BUILDIN_DEF(setbattleflag,"si"),
+ BUILDIN_DEF(getbattleflag,"s"),
+ BUILDIN_DEF(setitemscript,"is?"), //Set NEW item bonus script. Lupus
+ BUILDIN_DEF(disguise,"i"), //disguise player. Lupus
+ BUILDIN_DEF(undisguise,""), //undisguise player. Lupus
+ BUILDIN_DEF(getmonsterinfo,"ii"), //Lupus
+ BUILDIN_DEF(axtoi,"s"),
+ BUILDIN_DEF(query_sql,"s*"),
+ BUILDIN_DEF(query_logsql,"s*"),
+ BUILDIN_DEF(escape_sql,"v"),
+ BUILDIN_DEF(atoi,"s"),
+ // [zBuffer] List of player cont commands --->
+ BUILDIN_DEF(rid2name,"i"),
+ BUILDIN_DEF(pcfollow,"ii"),
+ BUILDIN_DEF(pcstopfollow,"i"),
+ BUILDIN_DEF(pcblockmove,"ii"),
+ // <--- [zBuffer] List of player cont commands
+ // [zBuffer] List of mob control commands --->
+ BUILDIN_DEF(unitwalk,"ii?"),
+ BUILDIN_DEF(unitkill,"i"),
+ BUILDIN_DEF(unitwarp,"isii"),
+ BUILDIN_DEF(unitattack,"iv?"),
+ BUILDIN_DEF(unitstop,"i"),
+ BUILDIN_DEF(unittalk,"is"),
+ BUILDIN_DEF(unitemote,"ii"),
+ BUILDIN_DEF(unitskilluseid,"ivi?"), // originally by Qamera [Celest]
+ BUILDIN_DEF(unitskillusepos,"iviii"), // [Celest]
+// <--- [zBuffer] List of mob control commands
+ BUILDIN_DEF(sleep,"i"),
+ BUILDIN_DEF(sleep2,"i"),
+ BUILDIN_DEF(awake,"s"),
+ BUILDIN_DEF(getvariableofnpc,"rs"),
+ BUILDIN_DEF(warpportal,"iisii"),
+ BUILDIN_DEF2(homunculus_evolution,"homevolution",""), //[orn]
+ BUILDIN_DEF2(homunculus_mutate,"hommutate","?"),
+ BUILDIN_DEF2(homunculus_shuffle,"homshuffle",""), //[Zephyrus]
+ BUILDIN_DEF(eaclass,"?"), //[Skotlex]
+ BUILDIN_DEF(roclass,"i?"), //[Skotlex]
+ BUILDIN_DEF(checkvending,"?"),
+ BUILDIN_DEF(checkchatting,"?"),
+ BUILDIN_DEF(openmail,""),
+ BUILDIN_DEF(openauction,""),
+ BUILDIN_DEF(checkcell,"siii"),
+ BUILDIN_DEF(setcell,"siiiiii"),
+ BUILDIN_DEF(setwall,"siiiiis"),
+ BUILDIN_DEF(delwall,"s"),
+ BUILDIN_DEF(searchitem,"rs"),
+ BUILDIN_DEF(mercenary_create,"ii"),
+ BUILDIN_DEF(mercenary_heal,"ii"),
+ BUILDIN_DEF(mercenary_sc_start,"iii"),
+ BUILDIN_DEF(mercenary_get_calls,"i"),
+ BUILDIN_DEF(mercenary_get_faith,"i"),
+ BUILDIN_DEF(mercenary_set_calls,"ii"),
+ BUILDIN_DEF(mercenary_set_faith,"ii"),
+ BUILDIN_DEF(readbook,"ii"),
+ BUILDIN_DEF(setfont,"i"),
+ BUILDIN_DEF(areamobuseskill,"siiiiviiiii"),
+ BUILDIN_DEF(progressbar,"si"),
+ BUILDIN_DEF(pushpc,"ii"),
+ BUILDIN_DEF(buyingstore,"i"),
+ BUILDIN_DEF(searchstores,"ii"),
+ BUILDIN_DEF(showdigit,"i?"),
+ // WoE SE
+ BUILDIN_DEF(agitstart2,""),
+ BUILDIN_DEF(agitend2,""),
+ BUILDIN_DEF(agitcheck2,""),
+ // BattleGround
+ BUILDIN_DEF(waitingroom2bg,"siiss?"),
+ BUILDIN_DEF(waitingroom2bg_single,"isiis"),
+ BUILDIN_DEF(bg_team_setxy,"iii"),
+ BUILDIN_DEF(bg_warp,"isii"),
+ BUILDIN_DEF(bg_monster,"isiisi?"),
+ BUILDIN_DEF(bg_monster_set_team,"ii"),
+ BUILDIN_DEF(bg_leave,""),
+ BUILDIN_DEF(bg_destroy,"i"),
+ BUILDIN_DEF(areapercentheal,"siiiiii"),
+ BUILDIN_DEF(bg_get_data,"ii"),
+ BUILDIN_DEF(bg_getareausers,"isiiii"),
+ BUILDIN_DEF(bg_updatescore,"sii"),
+
+ // Instancing
+ BUILDIN_DEF(instance_create,"si"),
+ BUILDIN_DEF(instance_destroy,"?"),
+ BUILDIN_DEF(instance_attachmap,"si?"),
+ BUILDIN_DEF(instance_detachmap,"s?"),
+ BUILDIN_DEF(instance_attach,"i"),
+ BUILDIN_DEF(instance_id,"?"),
+ BUILDIN_DEF(instance_set_timeout,"ii?"),
+ BUILDIN_DEF(instance_init,"i"),
+ BUILDIN_DEF(instance_announce,"isi?????"),
+ BUILDIN_DEF(instance_npcname,"s?"),
+ BUILDIN_DEF(has_instance,"s?"),
+ BUILDIN_DEF(instance_warpall,"sii?"),
+ BUILDIN_DEF(instance_check_party,"i???"),
+ /**
+ * 3rd-related
+ **/
+ BUILDIN_DEF(makerune,"i"),
+ BUILDIN_DEF(checkdragon,""),//[Ind]
+ BUILDIN_DEF(setdragon,"?"),//[Ind]
+ BUILDIN_DEF(ismounting,""),//[Ind]
+ BUILDIN_DEF(setmounting,""),//[Ind]
+ BUILDIN_DEF(checkre,"i"),
+ /**
+ * rAthena and beyond!
+ **/
+ BUILDIN_DEF(getargcount,""),
+ BUILDIN_DEF(getcharip,"?"),
+ BUILDIN_DEF(is_function,"s"),
+ BUILDIN_DEF(get_revision,""),
+ BUILDIN_DEF(freeloop,"i"),
+ BUILDIN_DEF(getrandgroupitem, "ii"),
+ /**
+ * @commands (script based)
+ **/
+ BUILDIN_DEF(bindatcmd, "ss??"),
+ BUILDIN_DEF(unbindatcmd, "s"),
+ BUILDIN_DEF(useatcmd, "s"),
+
+ //Quest Log System [Inkfish]
+ BUILDIN_DEF(setquest, "i"),
+ BUILDIN_DEF(erasequest, "i"),
+ BUILDIN_DEF(completequest, "i"),
+ BUILDIN_DEF(checkquest, "i?"),
+ BUILDIN_DEF(changequest, "ii"),
+ BUILDIN_DEF(showevent, "ii"),
+ {NULL,NULL,NULL},
};
diff --git a/src/map/script.h b/src/map/script.h
index e4c12de28..ed56b8ebe 100644
--- a/src/map/script.h
+++ b/src/map/script.h
@@ -13,101 +13,101 @@ extern int potion_hp, potion_per_hp, potion_sp, potion_per_sp;
extern int potion_target;
extern struct Script_Config {
- unsigned warn_func_mismatch_argtypes : 1;
- unsigned warn_func_mismatch_paramnum : 1;
- int check_cmdcount;
- int check_gotocount;
- int input_min_value;
- int input_max_value;
-
- const char *die_event_name;
- const char *kill_pc_event_name;
- const char *kill_mob_event_name;
- const char *login_event_name;
- const char *logout_event_name;
- const char *loadmap_event_name;
- const char *baselvup_event_name;
- const char *joblvup_event_name;
-
- const char *ontouch_name;
- const char *ontouch2_name;
+ unsigned warn_func_mismatch_argtypes : 1;
+ unsigned warn_func_mismatch_paramnum : 1;
+ int check_cmdcount;
+ int check_gotocount;
+ int input_min_value;
+ int input_max_value;
+
+ const char *die_event_name;
+ const char *kill_pc_event_name;
+ const char *kill_mob_event_name;
+ const char *login_event_name;
+ const char *logout_event_name;
+ const char *loadmap_event_name;
+ const char *baselvup_event_name;
+ const char *joblvup_event_name;
+
+ const char* ontouch_name;
+ const char* ontouch2_name;
} script_config;
typedef enum c_op {
- C_NOP, // end of script/no value (nil)
- C_POS,
- C_INT, // number
- C_PARAM, // parameter variable (see pc_readparam/pc_setparam)
- C_FUNC, // buildin function call
- C_STR, // string (free'd automatically)
- C_CONSTSTR, // string (not free'd)
- C_ARG, // start of argument list
- C_NAME,
- C_EOL, // end of line (extra stack values are cleared)
- C_RETINFO,
- C_USERFUNC, // internal script function
- C_USERFUNC_POS, // internal script function label
- C_REF, // the next call to c_op2 should push back a ref to the left operand
-
- // operators
- C_OP3, // a ? b : c
- C_LOR, // a || b
- C_LAND, // a && b
- C_LE, // a <= b
- C_LT, // a < b
- C_GE, // a >= b
- C_GT, // a > b
- C_EQ, // a == b
- C_NE, // a != b
- C_XOR, // a ^ b
- C_OR, // a | b
- C_AND, // a & b
- C_ADD, // a + b
- C_SUB, // a - b
- C_MUL, // a * b
- C_DIV, // a / b
- C_MOD, // a % b
- C_NEG, // - a
- C_LNOT, // ! a
- C_NOT, // ~ a
- C_R_SHIFT, // a >> b
- C_L_SHIFT, // a << b
- C_ADD_PP, // ++a
- C_SUB_PP, // --a
+ C_NOP, // end of script/no value (nil)
+ C_POS,
+ C_INT, // number
+ C_PARAM, // parameter variable (see pc_readparam/pc_setparam)
+ C_FUNC, // buildin function call
+ C_STR, // string (free'd automatically)
+ C_CONSTSTR, // string (not free'd)
+ C_ARG, // start of argument list
+ C_NAME,
+ C_EOL, // end of line (extra stack values are cleared)
+ C_RETINFO,
+ C_USERFUNC, // internal script function
+ C_USERFUNC_POS, // internal script function label
+ C_REF, // the next call to c_op2 should push back a ref to the left operand
+
+ // operators
+ C_OP3, // a ? b : c
+ C_LOR, // a || b
+ C_LAND, // a && b
+ C_LE, // a <= b
+ C_LT, // a < b
+ C_GE, // a >= b
+ C_GT, // a > b
+ C_EQ, // a == b
+ C_NE, // a != b
+ C_XOR, // a ^ b
+ C_OR, // a | b
+ C_AND, // a & b
+ C_ADD, // a + b
+ C_SUB, // a - b
+ C_MUL, // a * b
+ C_DIV, // a / b
+ C_MOD, // a % b
+ C_NEG, // - a
+ C_LNOT, // ! a
+ C_NOT, // ~ a
+ C_R_SHIFT, // a >> b
+ C_L_SHIFT, // a << b
+ C_ADD_PP, // ++a
+ C_SUB_PP, // --a
} c_op;
struct script_retinfo {
- struct DBMap *var_function;// scope variables
- struct script_code *script;// script code
- int pos;// script location
- int nargs;// argument count
- int defsp;// default stack pointer
+ struct DBMap* var_function;// scope variables
+ struct script_code* script;// script code
+ int pos;// script location
+ int nargs;// argument count
+ int defsp;// default stack pointer
};
struct script_data {
- enum c_op type;
- union script_data_val {
- int num;
- char *str;
- struct script_retinfo *ri;
- } u;
- struct DBMap **ref;
+ enum c_op type;
+ union script_data_val {
+ int num;
+ char *str;
+ struct script_retinfo* ri;
+ } u;
+ struct DBMap** ref;
};
// Moved defsp from script_state to script_stack since
// it must be saved when script state is RERUNLINE. [Eoe / jA 1094]
struct script_code {
- int script_size;
- unsigned char *script_buf;
- struct DBMap *script_vars;
+ int script_size;
+ unsigned char* script_buf;
+ struct DBMap* script_vars;
};
struct script_stack {
- int sp;// number of entries in the stack
- int sp_max;// capacity of the stack
- int defsp;
- struct script_data *stack_data;// stack
- struct DBMap *var_function;// scope variables
+ int sp;// number of entries in the stack
+ int sp_max;// capacity of the stack
+ int defsp;
+ struct script_data *stack_data;// stack
+ struct DBMap* var_function;// scope variables
};
@@ -117,81 +117,81 @@ struct script_stack {
enum e_script_state { RUN,STOP,END,RERUNLINE,GOTO,RETFUNC };
struct script_state {
- struct script_stack *stack;
- int start,end;
- int pos;
- enum e_script_state state;
- int rid,oid;
- struct script_code *script, *scriptroot;
- struct sleep_data {
- int tick,timer,charid;
- } sleep;
- int instance_id;
- //For backing up purposes
- struct script_state *bk_st;
- int bk_npcid;
- unsigned freeloop : 1;// used by buildin_freeloop
- unsigned op2ref : 1;// used by op_2
+ struct script_stack* stack;
+ int start,end;
+ int pos;
+ enum e_script_state state;
+ int rid,oid;
+ struct script_code *script, *scriptroot;
+ struct sleep_data {
+ int tick,timer,charid;
+ } sleep;
+ int instance_id;
+ //For backing up purposes
+ struct script_state *bk_st;
+ int bk_npcid;
+ unsigned freeloop : 1;// used by buildin_freeloop
+ unsigned op2ref : 1;// used by op_2
};
struct script_reg {
- int index;
- int data;
+ int index;
+ int data;
};
struct script_regstr {
- int index;
- char *data;
+ int index;
+ char* data;
};
enum script_parse_options {
- SCRIPT_USE_LABEL_DB = 0x1,// records labels in scriptlabel_db
- SCRIPT_IGNORE_EXTERNAL_BRACKETS = 0x2,// ignores the check for {} brackets around the script
- SCRIPT_RETURN_EMPTY_SCRIPT = 0x4// returns the script object instead of NULL for empty scripts
+ SCRIPT_USE_LABEL_DB = 0x1,// records labels in scriptlabel_db
+ SCRIPT_IGNORE_EXTERNAL_BRACKETS = 0x2,// ignores the check for {} brackets around the script
+ SCRIPT_RETURN_EMPTY_SCRIPT = 0x4// returns the script object instead of NULL for empty scripts
};
-const char *skip_space(const char *p);
-void script_error(const char *src, const char *file, int start_line, const char *error_msg, const char *error_pos);
+const char* skip_space(const char* p);
+void script_error(const char* src, const char* file, int start_line, const char* error_msg, const char* error_pos);
-struct script_code *parse_script(const char *src,const char *file,int line,int options);
-void run_script_sub(struct script_code *rootscript,int pos,int rid,int oid, char *file, int lineno);
-void run_script(struct script_code *,int,int,int);
+struct script_code* parse_script(const char* src,const char* file,int line,int options);
+void run_script_sub(struct script_code *rootscript,int pos,int rid,int oid, char* file, int lineno);
+void run_script(struct script_code*,int,int,int);
int set_var(struct map_session_data *sd, char *name, void *val);
int conv_num(struct script_state *st,struct script_data *data);
-const char *conv_str(struct script_state *st,struct script_data *data);
+const char* conv_str(struct script_state *st,struct script_data *data);
int run_script_timer(int tid, unsigned int tick, int id, intptr_t data);
void run_script_main(struct script_state *st);
void script_stop_sleeptimers(int id);
-struct linkdb_node *script_erase_sleepdb(struct linkdb_node *n);
-void script_free_code(struct script_code *code);
+struct linkdb_node* script_erase_sleepdb(struct linkdb_node *n);
+void script_free_code(struct script_code* code);
void script_free_vars(struct DBMap *storage);
-struct script_state *script_alloc_state(struct script_code *script, int pos, int rid, int oid);
-void script_free_state(struct script_state *st);
+struct script_state* script_alloc_state(struct script_code* script, int pos, int rid, int oid);
+void script_free_state(struct script_state* st);
-struct DBMap *script_get_label_db(void);
-struct DBMap *script_get_userfunc_db(void);
+struct DBMap* script_get_label_db(void);
+struct DBMap* script_get_userfunc_db(void);
void script_run_autobonus(const char *autobonus,int id, int pos);
-bool script_get_constant(const char *name, int *value);
-void script_set_constant(const char *name, int value, bool isparameter);
+bool script_get_constant(const char* name, int* value);
+void script_set_constant(const char* name, int value, bool isparameter);
-void script_cleararray_pc(struct map_session_data *sd, const char *varname, void *value);
-void script_setarray_pc(struct map_session_data *sd, const char *varname, uint8 idx, void *value, int *refcache);
+void script_cleararray_pc(struct map_session_data* sd, const char* varname, void* value);
+void script_setarray_pc(struct map_session_data* sd, const char* varname, uint8 idx, void* value, int* refcache);
int script_config_read(char *cfgName);
int do_init_script(void);
int do_final_script(void);
-int add_str(const char *p);
-const char *get_str(int id);
+int add_str(const char* p);
+const char* get_str(int id);
int script_reload(void);
// @commands (script based)
void setd_sub(struct script_state *st, TBL_PC *sd, const char *varname, int elem, void *value, struct DBMap **ref);
#ifdef BETA_THREAD_TEST
-void queryThread_log(char *entry, int length);
+void queryThread_log(char * entry, int length);
#endif
#endif /* _SCRIPT_H_ */
diff --git a/src/map/searchstore.c b/src/map/searchstore.c
index 041376260..c59c13bed 100644
--- a/src/map/searchstore.c
+++ b/src/map/searchstore.c
@@ -12,377 +12,394 @@
/// failure constants for clif functions
-enum e_searchstore_failure {
- SSI_FAILED_NOTHING_SEARCH_ITEM = 0, // "No matching stores were found."
- SSI_FAILED_OVER_MAXCOUNT = 1, // "There are too many results. Please enter more detailed search term."
- SSI_FAILED_SEARCH_CNT = 2, // "You cannot search anymore."
- SSI_FAILED_LIMIT_SEARCH_TIME = 3, // "You cannot search yet."
- SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE = 4, // "No sale (purchase) information available."
+enum e_searchstore_failure
+{
+ SSI_FAILED_NOTHING_SEARCH_ITEM = 0, // "No matching stores were found."
+ SSI_FAILED_OVER_MAXCOUNT = 1, // "There are too many results. Please enter more detailed search term."
+ SSI_FAILED_SEARCH_CNT = 2, // "You cannot search anymore."
+ SSI_FAILED_LIMIT_SEARCH_TIME = 3, // "You cannot search yet."
+ SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE = 4, // "No sale (purchase) information available."
};
-enum e_searchstore_searchtype {
- SEARCHTYPE_VENDING = 0,
- SEARCHTYPE_BUYING_STORE = 1,
+enum e_searchstore_searchtype
+{
+ SEARCHTYPE_VENDING = 0,
+ SEARCHTYPE_BUYING_STORE = 1,
};
-enum e_searchstore_effecttype {
- EFFECTTYPE_NORMAL = 0,
- EFFECTTYPE_CASH = 1,
- EFFECTTYPE_MAX
+enum e_searchstore_effecttype
+{
+ EFFECTTYPE_NORMAL = 0,
+ EFFECTTYPE_CASH = 1,
+ EFFECTTYPE_MAX
};
/// type for shop search function
-typedef bool (*searchstore_search_t)(struct map_session_data *sd, unsigned short nameid);
-typedef bool (*searchstore_searchall_t)(struct map_session_data *sd, const struct s_search_store_search *s);
+typedef bool (*searchstore_search_t)(struct map_session_data* sd, unsigned short nameid);
+typedef bool (*searchstore_searchall_t)(struct map_session_data* sd, const struct s_search_store_search* s);
/// retrieves search function by type
static searchstore_search_t searchstore_getsearchfunc(unsigned char type)
{
- switch (type) {
- case SEARCHTYPE_VENDING:
- return &vending_search;
- case SEARCHTYPE_BUYING_STORE:
- return &buyingstore_search;
- }
- return NULL;
+ switch( type )
+ {
+ case SEARCHTYPE_VENDING: return &vending_search;
+ case SEARCHTYPE_BUYING_STORE: return &buyingstore_search;
+ }
+ return NULL;
}
/// retrieves search-all function by type
static searchstore_searchall_t searchstore_getsearchallfunc(unsigned char type)
{
- switch (type) {
- case SEARCHTYPE_VENDING:
- return &vending_searchall;
- case SEARCHTYPE_BUYING_STORE:
- return &buyingstore_searchall;
- }
- return NULL;
+ switch( type )
+ {
+ case SEARCHTYPE_VENDING: return &vending_searchall;
+ case SEARCHTYPE_BUYING_STORE: return &buyingstore_searchall;
+ }
+ return NULL;
}
/// checks if the player has a store by type
-static bool searchstore_hasstore(struct map_session_data *sd, unsigned char type)
+static bool searchstore_hasstore(struct map_session_data* sd, unsigned char type)
{
- switch (type) {
- case SEARCHTYPE_VENDING:
- return sd->state.vending;
- case SEARCHTYPE_BUYING_STORE:
- return sd->state.buyingstore;
- }
- return false;
+ switch( type )
+ {
+ case SEARCHTYPE_VENDING: return sd->state.vending;
+ case SEARCHTYPE_BUYING_STORE: return sd->state.buyingstore;
+ }
+ return false;
}
/// returns player's store id by type
-static int searchstore_getstoreid(struct map_session_data *sd, unsigned char type)
+static int searchstore_getstoreid(struct map_session_data* sd, unsigned char type)
{
- switch (type) {
- case SEARCHTYPE_VENDING:
- return sd->vender_id;
- case SEARCHTYPE_BUYING_STORE:
- return sd->buyer_id;
- }
- return 0;
+ switch( type )
+ {
+ case SEARCHTYPE_VENDING: return sd->vender_id;
+ case SEARCHTYPE_BUYING_STORE: return sd->buyer_id;
+ }
+ return 0;
}
-bool searchstore_open(struct map_session_data *sd, unsigned int uses, unsigned short effect)
+bool searchstore_open(struct map_session_data* sd, unsigned int uses, unsigned short effect)
{
- if (!battle_config.feature_search_stores || sd->searchstore.open) {
- return false;
- }
+ if( !battle_config.feature_search_stores || sd->searchstore.open )
+ {
+ return false;
+ }
- if (!uses || effect >= EFFECTTYPE_MAX) {
- // invalid input
- return false;
- }
+ if( !uses || effect >= EFFECTTYPE_MAX )
+ {// invalid input
+ return false;
+ }
- sd->searchstore.open = true;
- sd->searchstore.uses = uses;
- sd->searchstore.effect = effect;
+ sd->searchstore.open = true;
+ sd->searchstore.uses = uses;
+ sd->searchstore.effect = effect;
- clif_open_search_store_info(sd);
+ clif_open_search_store_info(sd);
- return true;
+ return true;
}
-void searchstore_query(struct map_session_data *sd, unsigned char type, unsigned int min_price, unsigned int max_price, const unsigned short *itemlist, unsigned int item_count, const unsigned short *cardlist, unsigned int card_count)
+void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned int min_price, unsigned int max_price, const unsigned short* itemlist, unsigned int item_count, const unsigned short* cardlist, unsigned int card_count)
{
- unsigned int i;
- struct map_session_data *pl_sd;
- struct s_mapiterator *iter;
- struct s_search_store_search s;
- searchstore_searchall_t store_searchall;
- time_t querytime;
-
- if (!battle_config.feature_search_stores) {
- return;
- }
-
- if (!sd->searchstore.open) {
- return;
- }
-
- if ((store_searchall = searchstore_getsearchallfunc(type)) == NULL) {
- ShowError("searchstore_query: Unknown search type %u (account_id=%d).\n", (unsigned int)type, sd->bl.id);
- return;
- }
-
- time(&querytime);
-
- if (sd->searchstore.nextquerytime > querytime) {
- clif_search_store_info_failed(sd, SSI_FAILED_LIMIT_SEARCH_TIME);
- return;
- }
-
- if (!sd->searchstore.uses) {
- clif_search_store_info_failed(sd, SSI_FAILED_SEARCH_CNT);
- return;
- }
-
- // validate lists
- for (i = 0; i < item_count; i++) {
- if (!itemdb_exists(itemlist[i])) {
- ShowWarning("searchstore_query: Client resolved item %hu is not known.\n", itemlist[i]);
- clif_search_store_info_failed(sd, SSI_FAILED_NOTHING_SEARCH_ITEM);
- return;
- }
- }
- for (i = 0; i < card_count; i++) {
- if (!itemdb_exists(cardlist[i])) {
- ShowWarning("searchstore_query: Client resolved card %hu is not known.\n", cardlist[i]);
- clif_search_store_info_failed(sd, SSI_FAILED_NOTHING_SEARCH_ITEM);
- return;
- }
- }
-
- if (max_price < min_price) {
- swap(min_price, max_price);
- }
-
- sd->searchstore.uses--;
- sd->searchstore.type = type;
- sd->searchstore.nextquerytime = querytime+battle_config.searchstore_querydelay;
-
- // drop previous results
- searchstore_clear(sd);
-
- // allocate max. amount of results
- sd->searchstore.items = (struct s_search_store_info_item *)aMalloc(sizeof(struct s_search_store_info_item)*battle_config.searchstore_maxresults);
-
- // search
- s.search_sd = sd;
- s.itemlist = itemlist;
- s.cardlist = cardlist;
- s.item_count = item_count;
- s.card_count = card_count;
- s.min_price = min_price;
- s.max_price = max_price;
- iter = mapit_geteachpc();
-
- for (pl_sd = (struct map_session_data *)mapit_first(iter); mapit_exists(iter); pl_sd = (struct map_session_data *)mapit_next(iter)) {
- if (sd == pl_sd) {
- // skip own shop, if any
- continue;
- }
-
- if (!store_searchall(pl_sd, &s)) {
- // exceeded result size
- clif_search_store_info_failed(sd, SSI_FAILED_OVER_MAXCOUNT);
- break;
- }
- }
-
- mapit_free(iter);
-
- if (sd->searchstore.count) {
- // reclaim unused memory
- sd->searchstore.items = (struct s_search_store_info_item *)aRealloc(sd->searchstore.items, sizeof(struct s_search_store_info_item)*sd->searchstore.count);
-
- // present results
- clif_search_store_info_ack(sd);
-
- // one page displayed
- sd->searchstore.pages++;
- } else {
- // cleanup
- searchstore_clear(sd);
-
- // update uses
- clif_search_store_info_ack(sd);
-
- // notify of failure
- clif_search_store_info_failed(sd, SSI_FAILED_NOTHING_SEARCH_ITEM);
- }
+ unsigned int i;
+ struct map_session_data* pl_sd;
+ struct s_mapiterator* iter;
+ struct s_search_store_search s;
+ searchstore_searchall_t store_searchall;
+ time_t querytime;
+
+ if( !battle_config.feature_search_stores )
+ {
+ return;
+ }
+
+ if( !sd->searchstore.open )
+ {
+ return;
+ }
+
+ if( ( store_searchall = searchstore_getsearchallfunc(type) ) == NULL )
+ {
+ ShowError("searchstore_query: Unknown search type %u (account_id=%d).\n", (unsigned int)type, sd->bl.id);
+ return;
+ }
+
+ time(&querytime);
+
+ if( sd->searchstore.nextquerytime > querytime )
+ {
+ clif_search_store_info_failed(sd, SSI_FAILED_LIMIT_SEARCH_TIME);
+ return;
+ }
+
+ if( !sd->searchstore.uses )
+ {
+ clif_search_store_info_failed(sd, SSI_FAILED_SEARCH_CNT);
+ return;
+ }
+
+ // validate lists
+ for( i = 0; i < item_count; i++ )
+ {
+ if( !itemdb_exists(itemlist[i]) )
+ {
+ ShowWarning("searchstore_query: Client resolved item %hu is not known.\n", itemlist[i]);
+ clif_search_store_info_failed(sd, SSI_FAILED_NOTHING_SEARCH_ITEM);
+ return;
+ }
+ }
+ for( i = 0; i < card_count; i++ )
+ {
+ if( !itemdb_exists(cardlist[i]) )
+ {
+ ShowWarning("searchstore_query: Client resolved card %hu is not known.\n", cardlist[i]);
+ clif_search_store_info_failed(sd, SSI_FAILED_NOTHING_SEARCH_ITEM);
+ return;
+ }
+ }
+
+ if( max_price < min_price )
+ {
+ swap(min_price, max_price);
+ }
+
+ sd->searchstore.uses--;
+ sd->searchstore.type = type;
+ sd->searchstore.nextquerytime = querytime+battle_config.searchstore_querydelay;
+
+ // drop previous results
+ searchstore_clear(sd);
+
+ // allocate max. amount of results
+ sd->searchstore.items = (struct s_search_store_info_item*)aMalloc(sizeof(struct s_search_store_info_item)*battle_config.searchstore_maxresults);
+
+ // search
+ s.search_sd = sd;
+ s.itemlist = itemlist;
+ s.cardlist = cardlist;
+ s.item_count = item_count;
+ s.card_count = card_count;
+ s.min_price = min_price;
+ s.max_price = max_price;
+ iter = mapit_geteachpc();
+
+ for( pl_sd = (struct map_session_data*)mapit_first(iter); mapit_exists(iter); pl_sd = (struct map_session_data*)mapit_next(iter) )
+ {
+ if( sd == pl_sd )
+ {// skip own shop, if any
+ continue;
+ }
+
+ if( !store_searchall(pl_sd, &s) )
+ {// exceeded result size
+ clif_search_store_info_failed(sd, SSI_FAILED_OVER_MAXCOUNT);
+ break;
+ }
+ }
+
+ mapit_free(iter);
+
+ if( sd->searchstore.count )
+ {
+ // reclaim unused memory
+ sd->searchstore.items = (struct s_search_store_info_item*)aRealloc(sd->searchstore.items, sizeof(struct s_search_store_info_item)*sd->searchstore.count);
+
+ // present results
+ clif_search_store_info_ack(sd);
+
+ // one page displayed
+ sd->searchstore.pages++;
+ }
+ else
+ {
+ // cleanup
+ searchstore_clear(sd);
+
+ // update uses
+ clif_search_store_info_ack(sd);
+
+ // notify of failure
+ clif_search_store_info_failed(sd, SSI_FAILED_NOTHING_SEARCH_ITEM);
+ }
}
/// checks whether or not more results are available for the client
-bool searchstore_querynext(struct map_session_data *sd)
+bool searchstore_querynext(struct map_session_data* sd)
{
- if (sd->searchstore.count && (sd->searchstore.count-1)/SEARCHSTORE_RESULTS_PER_PAGE < sd->searchstore.pages) {
- return true;
- }
+ if( sd->searchstore.count && ( sd->searchstore.count-1 )/SEARCHSTORE_RESULTS_PER_PAGE < sd->searchstore.pages )
+ {
+ return true;
+ }
- return false;
+ return false;
}
-void searchstore_next(struct map_session_data *sd)
+void searchstore_next(struct map_session_data* sd)
{
- if (!battle_config.feature_search_stores || !sd->searchstore.open || sd->searchstore.count <= sd->searchstore.pages*SEARCHSTORE_RESULTS_PER_PAGE) {
- // nothing (more) to display
- return;
- }
+ if( !battle_config.feature_search_stores || !sd->searchstore.open || sd->searchstore.count <= sd->searchstore.pages*SEARCHSTORE_RESULTS_PER_PAGE )
+ {// nothing (more) to display
+ return;
+ }
- // present results
- clif_search_store_info_ack(sd);
+ // present results
+ clif_search_store_info_ack(sd);
- // one more page displayed
- sd->searchstore.pages++;
+ // one more page displayed
+ sd->searchstore.pages++;
}
-void searchstore_clear(struct map_session_data *sd)
+void searchstore_clear(struct map_session_data* sd)
{
- searchstore_clearremote(sd);
+ searchstore_clearremote(sd);
- if (sd->searchstore.items) {
- // release results
- aFree(sd->searchstore.items);
- sd->searchstore.items = NULL;
- }
+ if( sd->searchstore.items )
+ {// release results
+ aFree(sd->searchstore.items);
+ sd->searchstore.items = NULL;
+ }
- sd->searchstore.count = 0;
- sd->searchstore.pages = 0;
+ sd->searchstore.count = 0;
+ sd->searchstore.pages = 0;
}
-void searchstore_close(struct map_session_data *sd)
+void searchstore_close(struct map_session_data* sd)
{
- if (sd->searchstore.open) {
- searchstore_clear(sd);
+ if( sd->searchstore.open )
+ {
+ searchstore_clear(sd);
- sd->searchstore.uses = 0;
- sd->searchstore.open = false;
- }
+ sd->searchstore.uses = 0;
+ sd->searchstore.open = false;
+ }
}
-void searchstore_click(struct map_session_data *sd, int account_id, int store_id, unsigned short nameid)
+void searchstore_click(struct map_session_data* sd, int account_id, int store_id, unsigned short nameid)
{
- unsigned int i;
- struct map_session_data *pl_sd;
- searchstore_search_t store_search;
-
- if (!battle_config.feature_search_stores || !sd->searchstore.open || !sd->searchstore.count) {
- return;
- }
-
- searchstore_clearremote(sd);
-
- ARR_FIND(0, sd->searchstore.count, i, sd->searchstore.items[i].store_id == store_id && sd->searchstore.items[i].account_id == account_id && sd->searchstore.items[i].nameid == nameid);
- if (i == sd->searchstore.count) {
- // no such result, crafted
- ShowWarning("searchstore_click: Received request with item %hu of account %d, which is not part of current result set (account_id=%d, char_id=%d).\n", nameid, account_id, sd->bl.id, sd->status.char_id);
- clif_search_store_info_failed(sd, SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE);
- return;
- }
-
- if ((pl_sd = map_id2sd(account_id)) == NULL) {
- // no longer online
- clif_search_store_info_failed(sd, SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE);
- return;
- }
-
- if (!searchstore_hasstore(pl_sd, sd->searchstore.type) || searchstore_getstoreid(pl_sd, sd->searchstore.type) != store_id) {
- // no longer vending/buying or not same shop
- clif_search_store_info_failed(sd, SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE);
- return;
- }
-
- store_search = searchstore_getsearchfunc(sd->searchstore.type);
-
- if (!store_search(pl_sd, nameid)) {
- // item no longer being sold/bought
- clif_search_store_info_failed(sd, SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE);
- return;
- }
-
- switch (sd->searchstore.effect) {
- case EFFECTTYPE_NORMAL:
- // display coords
-
- if (sd->bl.m != pl_sd->bl.m) {
- // not on same map, wipe previous marker
- clif_search_store_info_click_ack(sd, -1, -1);
- } else {
- clif_search_store_info_click_ack(sd, pl_sd->bl.x, pl_sd->bl.y);
- }
-
- break;
- case EFFECTTYPE_CASH:
- // open remotely
-
- // to bypass range checks
- sd->searchstore.remote_id = account_id;
-
- switch (sd->searchstore.type) {
- case SEARCHTYPE_VENDING:
- vending_vendinglistreq(sd, account_id);
- break;
- case SEARCHTYPE_BUYING_STORE:
- buyingstore_open(sd, account_id);
- break;
- }
-
- break;
- default:
- // unknown
- ShowError("searchstore_click: Unknown search store effect %u (account_id=%d).\n", (unsigned int)sd->searchstore.effect, sd->bl.id);
- }
+ unsigned int i;
+ struct map_session_data* pl_sd;
+ searchstore_search_t store_search;
+
+ if( !battle_config.feature_search_stores || !sd->searchstore.open || !sd->searchstore.count )
+ {
+ return;
+ }
+
+ searchstore_clearremote(sd);
+
+ ARR_FIND( 0, sd->searchstore.count, i, sd->searchstore.items[i].store_id == store_id && sd->searchstore.items[i].account_id == account_id && sd->searchstore.items[i].nameid == nameid );
+ if( i == sd->searchstore.count )
+ {// no such result, crafted
+ ShowWarning("searchstore_click: Received request with item %hu of account %d, which is not part of current result set (account_id=%d, char_id=%d).\n", nameid, account_id, sd->bl.id, sd->status.char_id);
+ clif_search_store_info_failed(sd, SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE);
+ return;
+ }
+
+ if( ( pl_sd = map_id2sd(account_id) ) == NULL )
+ {// no longer online
+ clif_search_store_info_failed(sd, SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE);
+ return;
+ }
+
+ if( !searchstore_hasstore(pl_sd, sd->searchstore.type) || searchstore_getstoreid(pl_sd, sd->searchstore.type) != store_id )
+ {// no longer vending/buying or not same shop
+ clif_search_store_info_failed(sd, SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE);
+ return;
+ }
+
+ store_search = searchstore_getsearchfunc(sd->searchstore.type);
+
+ if( !store_search(pl_sd, nameid) )
+ {// item no longer being sold/bought
+ clif_search_store_info_failed(sd, SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE);
+ return;
+ }
+
+ switch( sd->searchstore.effect )
+ {
+ case EFFECTTYPE_NORMAL:
+ // display coords
+
+ if( sd->bl.m != pl_sd->bl.m )
+ {// not on same map, wipe previous marker
+ clif_search_store_info_click_ack(sd, -1, -1);
+ }
+ else
+ {
+ clif_search_store_info_click_ack(sd, pl_sd->bl.x, pl_sd->bl.y);
+ }
+
+ break;
+ case EFFECTTYPE_CASH:
+ // open remotely
+
+ // to bypass range checks
+ sd->searchstore.remote_id = account_id;
+
+ switch( sd->searchstore.type )
+ {
+ case SEARCHTYPE_VENDING: vending_vendinglistreq(sd, account_id); break;
+ case SEARCHTYPE_BUYING_STORE: buyingstore_open(sd, account_id); break;
+ }
+
+ break;
+ default:
+ // unknown
+ ShowError("searchstore_click: Unknown search store effect %u (account_id=%d).\n", (unsigned int)sd->searchstore.effect, sd->bl.id);
+ }
}
/// checks whether or not sd has opened account_id's shop remotely
-bool searchstore_queryremote(struct map_session_data *sd, int account_id)
+bool searchstore_queryremote(struct map_session_data* sd, int account_id)
{
- return (bool)(sd->searchstore.open && sd->searchstore.count && sd->searchstore.remote_id == account_id);
+ return (bool)( sd->searchstore.open && sd->searchstore.count && sd->searchstore.remote_id == account_id );
}
/// removes range-check bypassing for remotely opened stores
-void searchstore_clearremote(struct map_session_data *sd)
+void searchstore_clearremote(struct map_session_data* sd)
{
- sd->searchstore.remote_id = 0;
+ sd->searchstore.remote_id = 0;
}
/// receives results from a store-specific callback
-bool searchstore_result(struct map_session_data *sd, int store_id, int account_id, const char *store_name, unsigned short nameid, unsigned short amount, unsigned int price, const short *card, unsigned char refine)
+bool searchstore_result(struct map_session_data* sd, int store_id, int account_id, const char* store_name, unsigned short nameid, unsigned short amount, unsigned int price, const short* card, unsigned char refine)
{
- struct s_search_store_info_item *ssitem;
-
- if (sd->searchstore.count >= (unsigned int)battle_config.searchstore_maxresults) {
- // no more
- return false;
- }
-
- ssitem = &sd->searchstore.items[sd->searchstore.count++];
- ssitem->store_id = store_id;
- ssitem->account_id = account_id;
- safestrncpy(ssitem->store_name, store_name, sizeof(ssitem->store_name));
- ssitem->nameid = nameid;
- ssitem->amount = amount;
- ssitem->price = price;
- memcpy(ssitem->card, card, sizeof(ssitem->card));
- ssitem->refine = refine;
-
- return true;
+ struct s_search_store_info_item* ssitem;
+
+ if( sd->searchstore.count >= (unsigned int)battle_config.searchstore_maxresults )
+ {// no more
+ return false;
+ }
+
+ ssitem = &sd->searchstore.items[sd->searchstore.count++];
+ ssitem->store_id = store_id;
+ ssitem->account_id = account_id;
+ safestrncpy(ssitem->store_name, store_name, sizeof(ssitem->store_name));
+ ssitem->nameid = nameid;
+ ssitem->amount = amount;
+ ssitem->price = price;
+ memcpy(ssitem->card, card, sizeof(ssitem->card));
+ ssitem->refine = refine;
+
+ return true;
}
diff --git a/src/map/searchstore.h b/src/map/searchstore.h
index 0ac7c8d66..ffa8e9784 100644
--- a/src/map/searchstore.h
+++ b/src/map/searchstore.h
@@ -7,48 +7,51 @@
#define SEARCHSTORE_RESULTS_PER_PAGE 10
/// information about the search being performed
-struct s_search_store_search {
- struct map_session_data *search_sd; // sd of the searching player
- const unsigned short *itemlist;
- const unsigned short *cardlist;
- unsigned int item_count;
- unsigned int card_count;
- unsigned int min_price;
- unsigned int max_price;
+struct s_search_store_search
+{
+ struct map_session_data* search_sd; // sd of the searching player
+ const unsigned short* itemlist;
+ const unsigned short* cardlist;
+ unsigned int item_count;
+ unsigned int card_count;
+ unsigned int min_price;
+ unsigned int max_price;
};
-struct s_search_store_info_item {
- int store_id;
- int account_id;
- char store_name[MESSAGE_SIZE];
- unsigned short nameid;
- unsigned short amount;
- unsigned int price;
- short card[MAX_SLOTS];
- unsigned char refine;
+struct s_search_store_info_item
+{
+ int store_id;
+ int account_id;
+ char store_name[MESSAGE_SIZE];
+ unsigned short nameid;
+ unsigned short amount;
+ unsigned int price;
+ short card[MAX_SLOTS];
+ unsigned char refine;
};
-struct s_search_store_info {
- unsigned int count;
- struct s_search_store_info_item *items;
- unsigned int pages; // amount of pages already sent to client
- unsigned int uses;
- int remote_id;
- time_t nextquerytime;
- unsigned short effect; // 0 = Normal (display coords), 1 = Cash (remote open store)
- unsigned char type; // 0 = Vending, 1 = Buying Store
- bool open;
+struct s_search_store_info
+{
+ unsigned int count;
+ struct s_search_store_info_item* items;
+ unsigned int pages; // amount of pages already sent to client
+ unsigned int uses;
+ int remote_id;
+ time_t nextquerytime;
+ unsigned short effect; // 0 = Normal (display coords), 1 = Cash (remote open store)
+ unsigned char type; // 0 = Vending, 1 = Buying Store
+ bool open;
};
-bool searchstore_open(struct map_session_data *sd, unsigned int uses, unsigned short effect);
-void searchstore_query(struct map_session_data *sd, unsigned char type, unsigned int min_price, unsigned int max_price, const unsigned short *itemlist, unsigned int item_count, const unsigned short *cardlist, unsigned int card_count);
-bool searchstore_querynext(struct map_session_data *sd);
-void searchstore_next(struct map_session_data *sd);
-void searchstore_clear(struct map_session_data *sd);
-void searchstore_close(struct map_session_data *sd);
-void searchstore_click(struct map_session_data *sd, int account_id, int store_id, unsigned short nameid);
-bool searchstore_queryremote(struct map_session_data *sd, int account_id);
-void searchstore_clearremote(struct map_session_data *sd);
-bool searchstore_result(struct map_session_data *sd, int store_id, int account_id, const char *store_name, unsigned short nameid, unsigned short amount, unsigned int price, const short *card, unsigned char refine);
+bool searchstore_open(struct map_session_data* sd, unsigned int uses, unsigned short effect);
+void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned int min_price, unsigned int max_price, const unsigned short* itemlist, unsigned int item_count, const unsigned short* cardlist, unsigned int card_count);
+bool searchstore_querynext(struct map_session_data* sd);
+void searchstore_next(struct map_session_data* sd);
+void searchstore_clear(struct map_session_data* sd);
+void searchstore_close(struct map_session_data* sd);
+void searchstore_click(struct map_session_data* sd, int account_id, int store_id, unsigned short nameid);
+bool searchstore_queryremote(struct map_session_data* sd, int account_id);
+void searchstore_clearremote(struct map_session_data* sd);
+bool searchstore_result(struct map_session_data* sd, int store_id, int account_id, const char* store_name, unsigned short nameid, unsigned short amount, unsigned int price, const short* card, unsigned char refine);
#endif // _SEARCHSTORE_H_
diff --git a/src/map/skill.c b/src/map/skill.c
index f599ed63d..82b502420 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -42,7 +42,7 @@
#include <math.h>
-#define SKILLUNITTIMER_INTERVAL 100
+#define SKILLUNITTIMER_INTERVAL 100
// ranges reserved for mapping skill ids to skilldb offsets
#define HM_SKILLRANGEMIN 700
@@ -55,14 +55,14 @@
#define GD_SKILLRANGEMAX GD_SKILLRANGEMIN + MAX_GUILDSKILL
#if GD_SKILLRANGEMAX > 999
-#error GD_SKILLRANGEMAX is greater than 999
+ #error GD_SKILLRANGEMAX is greater than 999
#endif
static struct eri *skill_unit_ers = NULL; //For handling skill_unit's [Skotlex]
static struct eri *skill_timer_ers = NULL; //For handling skill_timerskills [Skotlex]
-DBMap *skillunit_db = NULL; // int id -> struct skill_unit*
+DBMap* skillunit_db = NULL; // int id -> struct skill_unit*
-DBMap *skilldb_name2id = NULL;
+DBMap* skilldb_name2id = NULL;
/**
* Skill Cool Down Delay Saving
@@ -70,20 +70,20 @@ DBMap *skilldb_name2id = NULL;
* to keep cooldowns in memory between player log-ins.
* All cooldowns are reset when server is restarted.
**/
-DBMap *skillcd_db = NULL; // char_id -> struct skill_cd
+DBMap* skillcd_db = NULL; // char_id -> struct skill_cd
struct skill_cd {
- int duration[MAX_SKILL_TREE];//milliseconds
- short skidx[MAX_SKILL_TREE];//the skill index entries belong to
- short nameid[MAX_SKILL_TREE];//skill id
- unsigned char cursor;
+ int duration[MAX_SKILL_TREE];//milliseconds
+ short skidx[MAX_SKILL_TREE];//the skill index entries belong to
+ short nameid[MAX_SKILL_TREE];//skill id
+ unsigned char cursor;
};
/**
* Skill Unit Persistency during endack routes (mostly for songs see bugreport:4574)
**/
-DBMap *skillusave_db = NULL; // char_id -> struct skill_usave
+DBMap* skillusave_db = NULL; // char_id -> struct skill_usave
struct skill_usave {
- int skill_num, skill_lv;
+ int skill_num, skill_lv;
};
struct s_skill_db skill_db[MAX_SKILL_DB];
@@ -91,24 +91,24 @@ struct s_skill_produce_db skill_produce_db[MAX_SKILL_PRODUCE_DB];
struct s_skill_arrow_db skill_arrow_db[MAX_SKILL_ARROW_DB];
struct s_skill_abra_db skill_abra_db[MAX_SKILL_ABRA_DB];
struct s_skill_improvise_db {
- int skillid;
- short per;//1-10000
+ int skillid;
+ short per;//1-10000
};
struct s_skill_improvise_db skill_improvise_db[MAX_SKILL_IMPROVISE_DB];
bool skill_reproduce_db[MAX_SKILL_DB];
struct s_skill_changematerial_db {
- int itemid;
- short rate;
- int qty[5];
- short qty_rate[5];
+ int itemid;
+ short rate;
+ int qty[5];
+ short qty_rate[5];
};
struct s_skill_changematerial_db skill_changematerial_db[MAX_SKILL_PRODUCE_DB];
//Warlock
struct s_skill_spellbook_db {
- int nameid;
- int skillid;
- int point;
+ int nameid;
+ int skillid;
+ int point;
};
struct s_skill_spellbook_db skill_spellbook_db[MAX_SKILL_SPELLBOOK_DB];
@@ -121,265 +121,132 @@ int icewall_unit_pos;
int earthstrain_unit_pos;
//early declaration
int skill_block_check(struct block_list *bl, enum sc_type type, int skillid);
-static int skill_check_unit_range(struct block_list *bl, int x, int y, int skillid, int skilllv);
-static int skill_check_unit_range2(struct block_list *bl, int x, int y, int skillid, int skilllv);
-static int skill_destroy_trap(struct block_list *bl, va_list ap);
+static int skill_check_unit_range (struct block_list *bl, int x, int y, int skillid, int skilllv);
+static int skill_check_unit_range2 (struct block_list *bl, int x, int y, int skillid, int skilllv);
+static int skill_destroy_trap( struct block_list *bl, va_list ap );
//Since only mob-casted splash skills can hit ice-walls
-static inline int splash_target(struct block_list *bl)
+static inline int splash_target(struct block_list* bl)
{
#ifndef RENEWAL
- return (bl->type == BL_MOB) ? BL_SKILL|BL_CHAR : BL_CHAR;
+ return ( bl->type == BL_MOB ) ? BL_SKILL|BL_CHAR : BL_CHAR;
#else // Some skills can now hit ground skills(traps, ice wall & etc.)
- return BL_SKILL|BL_CHAR;
+ return BL_SKILL|BL_CHAR;
#endif
}
/// Returns the id of the skill, or 0 if not found.
-int skill_name2id(const char *name)
+int skill_name2id(const char* name)
{
- if (name == NULL)
- return 0;
+ if( name == NULL )
+ return 0;
- return strdb_iget(skilldb_name2id, name);
+ return strdb_iget(skilldb_name2id, name);
}
/// Maps skill ids to skill db offsets.
/// Returns the skill's array index, or 0 (Unknown Skill).
-int skill_get_index(int id)
+int skill_get_index( int id )
{
- // avoid ranges reserved for mapping guild/homun/mercenary skills
- if ((id >= GD_SKILLRANGEMIN && id <= GD_SKILLRANGEMAX)
- || (id >= HM_SKILLRANGEMIN && id <= HM_SKILLRANGEMAX)
- || (id >= MC_SKILLRANGEMIN && id <= MC_SKILLRANGEMAX)
- || (id >= EL_SKILLRANGEMIN && id <= EL_SKILLRANGEMAX))
- return 0;
-
- // map skill id to skill db index
- if (id >= GD_SKILLBASE)
- id = GD_SKILLRANGEMIN + id - GD_SKILLBASE;
- else if (id >= EL_SKILLBASE)
- id = EL_SKILLRANGEMIN + id - EL_SKILLBASE;
- else if (id >= MC_SKILLBASE)
- id = MC_SKILLRANGEMIN + id - MC_SKILLBASE;
- else if (id >= HM_SKILLBASE)
- id = HM_SKILLRANGEMIN + id - HM_SKILLBASE;
-
- // validate result
- if (id <= 0 || id >= MAX_SKILL_DB)
- return 0;
-
- return id;
+ // avoid ranges reserved for mapping guild/homun/mercenary skills
+ if( (id >= GD_SKILLRANGEMIN && id <= GD_SKILLRANGEMAX)
+ || (id >= HM_SKILLRANGEMIN && id <= HM_SKILLRANGEMAX)
+ || (id >= MC_SKILLRANGEMIN && id <= MC_SKILLRANGEMAX)
+ || (id >= EL_SKILLRANGEMIN && id <= EL_SKILLRANGEMAX) )
+ return 0;
+
+ // map skill id to skill db index
+ if( id >= GD_SKILLBASE )
+ id = GD_SKILLRANGEMIN + id - GD_SKILLBASE;
+ else if( id >= EL_SKILLBASE )
+ id = EL_SKILLRANGEMIN + id - EL_SKILLBASE;
+ else if( id >= MC_SKILLBASE )
+ id = MC_SKILLRANGEMIN + id - MC_SKILLBASE;
+ else if( id >= HM_SKILLBASE )
+ id = HM_SKILLRANGEMIN + id - HM_SKILLBASE;
+
+ // validate result
+ if( id <= 0 || id >= MAX_SKILL_DB )
+ return 0;
+
+ return id;
}
-const char *skill_get_name(int id)
+const char* skill_get_name( int id )
{
- return skill_db[skill_get_index(id)].name;
+ return skill_db[skill_get_index(id)].name;
}
-const char *skill_get_desc(int id)
+const char* skill_get_desc( int id )
{
- return skill_db[skill_get_index(id)].desc;
+ return skill_db[skill_get_index(id)].desc;
}
// out of bounds error checking [celest]
-static void skill_chk(int *id, int lv)
+static void skill_chk(int* id, int lv)
{
- *id = skill_get_index(*id); // checks/adjusts id
- if (lv <= 0 || lv > MAX_SKILL_LEVEL) *id = 0;
+ *id = skill_get_index(*id); // checks/adjusts id
+ if( lv <= 0 || lv > MAX_SKILL_LEVEL ) *id = 0;
}
#define skill_get(var,id,lv) { skill_chk(&id,lv); if(!id) return 0; 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_get(skill_db[id].inf, id, 1);
-}
-int skill_get_ele(int id , int lv)
-{
- skill_get(skill_db[id].element[lv-1], id, lv);
-}
-int skill_get_nk(int id)
-{
- skill_get(skill_db[id].nk, id, 1);
-}
-int skill_get_max(int id)
-{
- skill_get(skill_db[id].max, id, 1);
-}
-int skill_get_range(int id , int lv)
-{
- skill_get(skill_db[id].range[lv-1], id, lv);
-}
-int skill_get_splash(int id , int lv)
-{
- skill_chk(&id, lv);
- return (skill_db[id].splash[lv-1]>=0?skill_db[id].splash[lv-1]:AREA_SIZE);
-}
-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_hp_rate(int id, int lv)
-{
- skill_get(skill_db[id].hp_rate[lv-1], id, lv);
-}
-int skill_get_sp_rate(int id, int lv)
-{
- skill_get(skill_db[id].sp_rate[lv-1], id, lv);
-}
-int skill_get_state(int id)
-{
- skill_get(skill_db[id].state, id, 1);
-}
-int skill_get_spiritball(int id, int lv)
-{
- skill_get(skill_db[id].spiritball[lv-1], id, lv);
-}
-int skill_get_itemid(int id, int idx)
-{
- skill_get(skill_db[id].itemid[idx], id, 1);
-}
-int skill_get_itemqty(int id, int idx)
-{
- skill_get(skill_db[id].amount[idx], id, 1);
-}
-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_walkdelay(int id ,int lv)
-{
- skill_get(skill_db[id].walkdelay[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_ammotype(int id)
-{
- skill_get(skill_db[id].ammo, id, 1);
-}
-int skill_get_ammo_qty(int id, int lv)
-{
- skill_get(skill_db[id].ammo_qty[lv-1], id, lv);
-}
-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 ,int lv)
-{
- skill_get(skill_db[id].maxcount[lv-1], id, lv);
-}
-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_type(int id)
-{
- skill_get(skill_db[id].skill_type, 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_interval(int id)
-{
- skill_get(skill_db[id].unit_interval, id, 1);
-}
-int skill_get_unit_range(int id, int lv)
-{
- skill_get(skill_db[id].unit_range[lv-1], id, lv);
-}
-int skill_get_unit_target(int id)
-{
- skill_get(skill_db[id].unit_target&BCT_ALL, id, 1);
-}
-int skill_get_unit_bl_target(int id)
-{
- skill_get(skill_db[id].unit_target&BL_ALL, id, 1);
-}
-int skill_get_unit_flag(int id)
-{
- skill_get(skill_db[id].unit_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_cooldown(int id ,int lv)
-{
- skill_get(skill_db[id].cooldown[lv-1], id, lv);
-}
+int skill_get_hit( int id ) { skill_get (skill_db[id].hit, id, 1); }
+int skill_get_inf( int id ) { skill_get (skill_db[id].inf, id, 1); }
+int skill_get_ele( int id , int lv ) { skill_get (skill_db[id].element[lv-1], id, lv); }
+int skill_get_nk( int id ) { skill_get (skill_db[id].nk, id, 1); }
+int skill_get_max( int id ) { skill_get (skill_db[id].max, id, 1); }
+int skill_get_range( int id , int lv ) { skill_get (skill_db[id].range[lv-1], id, lv); }
+int skill_get_splash( int id , int lv ) { skill_chk (&id, lv); return (skill_db[id].splash[lv-1]>=0?skill_db[id].splash[lv-1]:AREA_SIZE); }
+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_hp_rate(int id, int lv ) { skill_get (skill_db[id].hp_rate[lv-1], id, lv); }
+int skill_get_sp_rate(int id, int lv ) { skill_get (skill_db[id].sp_rate[lv-1], id, lv); }
+int skill_get_state(int id) { skill_get (skill_db[id].state, id, 1); }
+int skill_get_spiritball(int id, int lv) { skill_get (skill_db[id].spiritball[lv-1], id, lv); }
+int skill_get_itemid(int id, int idx) { skill_get (skill_db[id].itemid[idx], id, 1); }
+int skill_get_itemqty(int id, int idx) { skill_get (skill_db[id].amount[idx], id, 1); }
+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_walkdelay( int id ,int lv ) { skill_get (skill_db[id].walkdelay[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_ammotype( int id ) { skill_get (skill_db[id].ammo, id, 1); }
+int skill_get_ammo_qty( int id, int lv ) { skill_get (skill_db[id].ammo_qty[lv-1], id, lv); }
+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 ,int lv ) { skill_get (skill_db[id].maxcount[lv-1], id, lv); }
+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_type( int id ) { skill_get (skill_db[id].skill_type, 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_interval( int id ) { skill_get (skill_db[id].unit_interval, id, 1); }
+int skill_get_unit_range( int id, int lv ){ skill_get (skill_db[id].unit_range[lv-1], id, lv); }
+int skill_get_unit_target( int id ) { skill_get (skill_db[id].unit_target&BCT_ALL, id, 1); }
+int skill_get_unit_bl_target( int id ) { skill_get (skill_db[id].unit_target&BL_ALL, id, 1); }
+int skill_get_unit_flag( int id ) { skill_get (skill_db[id].unit_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_cooldown( int id ,int lv ) { skill_get (skill_db[id].cooldown[lv-1], id, lv); }
#ifdef RENEWAL_CAST
-int skill_get_fixed_cast(int id ,int lv)
-{
- skill_get(skill_db[id].fixed_cast[lv-1], id, lv);
-}
+int skill_get_fixed_cast( int id ,int lv ){ skill_get (skill_db[id].fixed_cast[lv-1], id, lv); }
#endif
int skill_tree_get_max(int id, int b_class)
{
- int i;
- b_class = pc_class2idx(b_class);
-
- ARR_FIND(0, MAX_SKILL_TREE, i, skill_tree[b_class][i].id == 0 || skill_tree[b_class][i].id == id);
- if (i < MAX_SKILL_TREE && skill_tree[b_class][i].id == id)
- return skill_tree[b_class][i].max;
- else
- return skill_get_max(id);
+ int i;
+ b_class = pc_class2idx(b_class);
+
+ ARR_FIND( 0, MAX_SKILL_TREE, i, skill_tree[b_class][i].id == 0 || skill_tree[b_class][i].id == id );
+ if( i < MAX_SKILL_TREE && skill_tree[b_class][i].id == id )
+ return skill_tree[b_class][i].max;
+ else
+ return skill_get_max(id);
}
int skill_frostjoke_scream(struct block_list *bl,va_list ap);
@@ -398,1654 +265,1634 @@ static 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 };
-int skill_get_casttype(int id)
+int skill_get_casttype (int id)
{
- int inf = skill_get_inf(id);
- if (inf&(INF_GROUND_SKILL))
- return CAST_GROUND;
- if (inf&INF_SUPPORT_SKILL)
- return CAST_NODAMAGE;
- if (inf&INF_SELF_SKILL) {
- if (skill_get_inf2(id)&INF2_NO_TARGET_SELF)
- return CAST_DAMAGE; //Combo skill.
- return CAST_NODAMAGE;
- }
- if (skill_get_nk(id)&NK_NO_DAMAGE)
- return CAST_NODAMAGE;
- return CAST_DAMAGE;
+ int inf = skill_get_inf(id);
+ if (inf&(INF_GROUND_SKILL))
+ return CAST_GROUND;
+ if (inf&INF_SUPPORT_SKILL)
+ return CAST_NODAMAGE;
+ if (inf&INF_SELF_SKILL) {
+ if(skill_get_inf2(id)&INF2_NO_TARGET_SELF)
+ return CAST_DAMAGE; //Combo skill.
+ return CAST_NODAMAGE;
+ }
+ if (skill_get_nk(id)&NK_NO_DAMAGE)
+ return CAST_NODAMAGE;
+ return CAST_DAMAGE;
}
//Returns actual skill range taking into account attack range and AC_OWL [Skotlex]
-int skill_get_range2(struct block_list *bl, int id, int lv)
+int skill_get_range2 (struct block_list *bl, int id, int lv)
{
- int range;
- if (bl->type == BL_MOB && battle_config.mob_ai&0x400)
- return 9; //Mobs have a range of 9 regardless of skill used.
-
- range = skill_get_range(id, lv);
-
- if (range < 0) {
- if (battle_config.use_weapon_skill_range&bl->type)
- return status_get_range(bl);
- range *=-1;
- }
-
- //TODO: Find a way better than hardcoding the list of skills affected by AC_VULTURE
- switch (id) {
- case AC_SHOWER:
- case MA_SHOWER:
- case AC_DOUBLE:
- case MA_DOUBLE:
- case HT_BLITZBEAT:
- case AC_CHARGEARROW:
- case MA_CHARGEARROW:
- case SN_FALCONASSAULT:
- case HT_POWER:
- /**
- * Ranger
- **/
- case RA_ARROWSTORM:
- case RA_AIMEDBOLT:
- case RA_WUGBITE:
- if (bl->type == BL_PC)
- range += pc_checkskill((TBL_PC *)bl, AC_VULTURE);
- else
- range += 10; //Assume level 10?
- break;
- // added to allow GS skills to be effected by the range of Snake Eyes [Reddozen]
- case GS_RAPIDSHOWER:
- case GS_PIERCINGSHOT:
- case GS_FULLBUSTER:
- case GS_SPREADATTACK:
- case GS_GROUNDDRIFT:
- if (bl->type == BL_PC)
- range += pc_checkskill((TBL_PC *)bl, GS_SNAKEEYE);
- else
- range += 10; //Assume level 10?
- break;
- case NJ_KIRIKAGE:
- if (bl->type == BL_PC)
- range = skill_get_range(NJ_SHADOWJUMP,pc_checkskill((TBL_PC *)bl,NJ_SHADOWJUMP));
- break;
- /**
- * Warlock
- **/
- case WL_WHITEIMPRISON:
- case WL_SOULEXPANSION:
- case WL_FROSTMISTY:
- case WL_MARSHOFABYSS:
- case WL_SIENNAEXECRATE:
- case WL_DRAINLIFE:
- case WL_CRIMSONROCK:
- case WL_HELLINFERNO:
- case WL_COMET:
- case WL_CHAINLIGHTNING:
- case WL_TETRAVORTEX:
- case WL_RELEASE:
- if (bl->type == BL_PC)
- range += pc_checkskill((TBL_PC *)bl, WL_RADIUS);
- break;
- /**
- * Ranger Bonus
- **/
- case HT_LANDMINE:
- case HT_FREEZINGTRAP:
- case HT_BLASTMINE:
- case HT_CLAYMORETRAP:
- case RA_CLUSTERBOMB:
- case RA_FIRINGTRAP:
- case RA_ICEBOUNDTRAP:
- if (bl->type == BL_PC)
- range += (1 + pc_checkskill((TBL_PC *)bl, RA_RESEARCHTRAP))/2;
- }
-
- if (!range && bl->type != BL_PC)
- return 9; // Enable non players to use self skills on others. [Skotlex]
- return range;
+ int range;
+ if( bl->type == BL_MOB && battle_config.mob_ai&0x400 )
+ return 9; //Mobs have a range of 9 regardless of skill used.
+
+ range = skill_get_range(id, lv);
+
+ if( range < 0 )
+ {
+ if( battle_config.use_weapon_skill_range&bl->type )
+ return status_get_range(bl);
+ range *=-1;
+ }
+
+ //TODO: Find a way better than hardcoding the list of skills affected by AC_VULTURE
+ switch( id )
+ {
+ case AC_SHOWER: case MA_SHOWER:
+ case AC_DOUBLE: case MA_DOUBLE:
+ case HT_BLITZBEAT:
+ case AC_CHARGEARROW:
+ case MA_CHARGEARROW:
+ case SN_FALCONASSAULT:
+ case HT_POWER:
+ /**
+ * Ranger
+ **/
+ case RA_ARROWSTORM:
+ case RA_AIMEDBOLT:
+ case RA_WUGBITE:
+ if( bl->type == BL_PC )
+ range += pc_checkskill((TBL_PC*)bl, AC_VULTURE);
+ else
+ range += 10; //Assume level 10?
+ break;
+ // added to allow GS skills to be effected by the range of Snake Eyes [Reddozen]
+ case GS_RAPIDSHOWER:
+ case GS_PIERCINGSHOT:
+ case GS_FULLBUSTER:
+ case GS_SPREADATTACK:
+ case GS_GROUNDDRIFT:
+ if (bl->type == BL_PC)
+ range += pc_checkskill((TBL_PC*)bl, GS_SNAKEEYE);
+ else
+ range += 10; //Assume level 10?
+ break;
+ case NJ_KIRIKAGE:
+ if (bl->type == BL_PC)
+ range = skill_get_range(NJ_SHADOWJUMP,pc_checkskill((TBL_PC*)bl,NJ_SHADOWJUMP));
+ break;
+ /**
+ * Warlock
+ **/
+ case WL_WHITEIMPRISON:
+ case WL_SOULEXPANSION:
+ case WL_FROSTMISTY:
+ case WL_MARSHOFABYSS:
+ case WL_SIENNAEXECRATE:
+ case WL_DRAINLIFE:
+ case WL_CRIMSONROCK:
+ case WL_HELLINFERNO:
+ case WL_COMET:
+ case WL_CHAINLIGHTNING:
+ case WL_TETRAVORTEX:
+ case WL_RELEASE:
+ if( bl->type == BL_PC )
+ range += pc_checkskill((TBL_PC*)bl, WL_RADIUS);
+ break;
+ /**
+ * Ranger Bonus
+ **/
+ case HT_LANDMINE:
+ case HT_FREEZINGTRAP:
+ case HT_BLASTMINE:
+ case HT_CLAYMORETRAP:
+ case RA_CLUSTERBOMB:
+ case RA_FIRINGTRAP:
+ case RA_ICEBOUNDTRAP:
+ if( bl->type == BL_PC )
+ range += (1 + pc_checkskill((TBL_PC*)bl, RA_RESEARCHTRAP))/2;
+ }
+
+ if( !range && bl->type != BL_PC )
+ return 9; // Enable non players to use self skills on others. [Skotlex]
+ return range;
}
-int skill_calc_heal(struct block_list *src, struct block_list *target, int skill_id, int skill_lv, bool heal)
-{
- int skill, hp;
- struct map_session_data *sd = BL_CAST(BL_PC, src);
- struct map_session_data *tsd = BL_CAST(BL_PC, target);
- struct status_change *sc;
+int skill_calc_heal(struct block_list *src, struct block_list *target, int skill_id, int skill_lv, bool heal) {
+ int skill, hp;
+ struct map_session_data *sd = BL_CAST(BL_PC, src);
+ struct map_session_data *tsd = BL_CAST(BL_PC, target);
+ struct status_change* sc;
- switch (skill_id) {
- case BA_APPLEIDUN:
-#ifdef RENEWAL
- hp = 100+5*skill_lv+5*(status_get_vit(src)/10); // HP recovery
-#else
- hp = 30+5*skill_lv+5*(status_get_vit(src)/10); // HP recovery
-#endif
- if (sd)
- hp += 5*pc_checkskill(sd,BA_MUSICALLESSON);
- break;
- case PR_SANCTUARY:
- hp = (skill_lv>6)?777:skill_lv*100;
- break;
- case NPC_EVILLAND:
- hp = (skill_lv>6)?666:skill_lv*100;
- break;
- default:
- if (skill_lv >= battle_config.max_heal_lv)
- return battle_config.max_heal;
-#ifdef RENEWAL
- /**
- * Renewal Heal Formula
- * Formula: ( [(Base Level + INT) / 5] × 30 ) × (Heal Level / 10) × (Modifiers) + MATK
- **/
- hp = (status_get_lv(src) + status_get_int(src)) / 5 * 30 * skill_lv / 10;
-#else
- hp = (status_get_lv(src) + status_get_int(src)) / 8 * (4 + (skill_id == AB_HIGHNESSHEAL ? (sd ? pc_checkskill(sd,AL_HEAL) : 10) : skill_lv) * 8);
-#endif
- if (sd && ((skill = pc_checkskill(sd, HP_MEDITATIO)) > 0))
- hp += hp * skill * 2 / 100;
- else if (src->type == BL_HOM && (skill = merc_hom_checkskill(((TBL_HOM *)src), HLIF_BRAIN)) > 0)
- hp += hp * skill * 2 / 100;
- break;
- }
-
- if (((target && target->type == BL_MER) || !heal) && skill_id != NPC_EVILLAND)
- hp >>= 1;
-
- if (sd && (skill = pc_skillheal_bonus(sd, skill_id)))
- hp += hp*skill/100;
-
- if (tsd && (skill = pc_skillheal2_bonus(tsd, skill_id)))
- hp += hp*skill/100;
-
- sc = status_get_sc(target);
- if (sc && sc->count) {
- if (sc->data[SC_CRITICALWOUND] && heal) // Critical Wound has no effect on offensive heal. [Inkfish]
- hp -= hp * sc->data[SC_CRITICALWOUND]->val2/100;
- if (sc->data[SC_DEATHHURT] && heal)
- hp -= hp * 20/100;
- if (sc->data[SC_INCHEALRATE] && skill_id != NPC_EVILLAND && skill_id != BA_APPLEIDUN)
- hp += hp * sc->data[SC_INCHEALRATE]->val1/100; // Only affects Heal, Sanctuary and PotionPitcher.(like bHealPower) [Inkfish]
- if (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 2)
- hp += hp / 10;
- }
-
-#ifdef RENEWAL
- // MATK part of the RE heal formula [malufett]
- // Note: in this part matk bonuses from items or skills are not applied
switch( skill_id ) {
- case BA_APPLEIDUN: case PR_SANCTUARY:
- case NPC_EVILLAND: break;
+ case BA_APPLEIDUN:
+ #ifdef RENEWAL
+ hp = 100+5*skill_lv+5*(status_get_vit(src)/10); // HP recovery
+ #else
+ hp = 30+5*skill_lv+5*(status_get_vit(src)/10); // HP recovery
+ #endif
+ if( sd )
+ hp += 5*pc_checkskill(sd,BA_MUSICALLESSON);
+ break;
+ case PR_SANCTUARY:
+ hp = (skill_lv>6)?777:skill_lv*100;
+ break;
+ case NPC_EVILLAND:
+ hp = (skill_lv>6)?666:skill_lv*100;
+ break;
default:
- {
- struct status_data *status = status_get_status_data(src);
- int min, max, wMatk, variance;
-
- min = max = status_base_matk(status, status_get_lv(src));
- if( status->rhw.matk > 0 ){
- wMatk = status->rhw.matk;
- variance = wMatk * status->rhw.wlv / 10;
- min += wMatk - variance;
- max += wMatk + variance;
- }
-
- if( sc && sc->data[SC_RECOGNIZEDSPELL] )
- min = max;
-
- if( sd && sd->right_weapon.overrefine > 0 ){
- min++;
- max += sd->right_weapon.overrefine - 1;
- }
+ if (skill_lv >= battle_config.max_heal_lv)
+ return battle_config.max_heal;
+ #ifdef RENEWAL
+ /**
+ * Renewal Heal Formula (from Doddler)
+ * TODO: whats that( 1+ %Modifier / 100 ) ? currently using 'x1' (100/100) until found out
+ * - Min = ( [ ( BaseLvl + INT ) / 5 ] * 30 ) * (1+( %Modifier / 100)) * (HealLvl * 0.1) + StatusMATK + EquipMATK - [(WeaponMATK * WeaponLvl) / 10]
+ * - Max = ( [ ( BaseLvl + INT ) / 5 ] * 30 ) * (1+( %Modifier / 100)) * (HealLvl * 0.1) + StatusMATK + EquipMATK + [(WeaponMATK * WeaponLvl) / 10]
+ **/
+ hp = ( ( ( ( status_get_lv(src) + status_get_int(src) ) / 5 ) * 3 ) * skill_lv + status_get_matk_min(src) + status_get_matk_max(src) - ( ( status_get_matk_max(src) * status_get_wlv(src) ) / 10 ) ) + rnd()%( ( ( ( status_get_lv(src) + status_get_int(src) ) / 5 ) * 3 ) * skill_lv + status_get_matk_min(src) + status_get_matk_max(src) + ( ( status_get_matk_max(src) * status_get_wlv(src) ) / 10 ) );
+ #else
+ hp = ( status_get_lv(src) + status_get_int(src) ) / 8 * (4 + ( skill_id == AB_HIGHNESSHEAL ? ( sd ? pc_checkskill(sd,AL_HEAL) : 10 ) : skill_lv ) * 8);
+ #endif
+ if( sd && ((skill = pc_checkskill(sd, HP_MEDITATIO)) > 0) )
+ hp += hp * skill * 2 / 100;
+ else if( src->type == BL_HOM && (skill = merc_hom_checkskill(((TBL_HOM*)src), HLIF_BRAIN)) > 0 )
+ hp += hp * skill * 2 / 100;
+ break;
+ }
- if(max > min)
- hp += min+rnd()%(max-min);
- else
- hp += min;
- }
+ if( ( (target && target->type == BL_MER) || !heal ) && skill_id != NPC_EVILLAND )
+ hp >>= 1;
+
+ if( sd && (skill = pc_skillheal_bonus(sd, skill_id)) )
+ hp += hp*skill/100;
+
+ if( tsd && (skill = pc_skillheal2_bonus(tsd, skill_id)) )
+ hp += hp*skill/100;
+
+ sc = status_get_sc(target);
+ if( sc && sc->count ) {
+ if( sc->data[SC_CRITICALWOUND] && heal ) // Critical Wound has no effect on offensive heal. [Inkfish]
+ hp -= hp * sc->data[SC_CRITICALWOUND]->val2/100;
+ if( sc->data[SC_DEATHHURT] && heal )
+ hp -= hp * 20/100;
+ if( sc->data[SC_INCHEALRATE] && skill_id != NPC_EVILLAND && skill_id != BA_APPLEIDUN )
+ hp += hp * sc->data[SC_INCHEALRATE]->val1/100; // Only affects Heal, Sanctuary and PotionPitcher.(like bHealPower) [Inkfish]
+ if( sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 2)
+ hp += hp / 10;
}
-#endif
- return hp;
+
+ return hp;
}
// Making plagiarize check its own function [Aru]
-int can_copy(struct map_session_data *sd, int skillid, struct block_list *bl)
+int can_copy (struct map_session_data *sd, int skillid, struct block_list* bl)
{
- // Never copy NPC/Wedding Skills
- if (skill_get_inf2(skillid)&(INF2_NPC_SKILL|INF2_WEDDING_SKILL))
- return 0;
-
- // High-class skills
- if ((skillid >= LK_AURABLADE && skillid <= ASC_CDP) || (skillid >= ST_PRESERVE && skillid <= CR_CULTIVATION)) {
- if (battle_config.copyskill_restrict == 2)
- return 0;
- else if (battle_config.copyskill_restrict)
- return (sd->status.class_ == JOB_STALKER);
- }
-
- //Added so plagarize can't copy agi/bless if you're undead since it damages you
- if ((skillid == AL_INCAGI || skillid == AL_BLESSING ||
- skillid == CASH_BLESSING || skillid == CASH_INCAGI ||
- skillid == MER_INCAGI || skillid == MER_BLESSING))
- return 0;
-
- // Couldn't preserve 3rd Class skills except only when using Reproduce skill. [Jobbie]
- if (!(sd->sc.data[SC__REPRODUCE]) && (skillid >= RK_ENCHANTBLADE && skillid <= SR_RIDEINLIGHTNING))
- return 0;
- // Reproduce will only copy skills according on the list. [Jobbie]
- else if (sd->sc.data[SC__REPRODUCE] && !skill_reproduce_db[skillid])
- return 0;
-
- return 1;
+ // Never copy NPC/Wedding Skills
+ if (skill_get_inf2(skillid)&(INF2_NPC_SKILL|INF2_WEDDING_SKILL))
+ return 0;
+
+ // High-class skills
+ if((skillid >= LK_AURABLADE && skillid <= ASC_CDP) || (skillid >= ST_PRESERVE && skillid <= CR_CULTIVATION))
+ {
+ if(battle_config.copyskill_restrict == 2)
+ return 0;
+ else if(battle_config.copyskill_restrict)
+ return (sd->status.class_ == JOB_STALKER);
+ }
+
+ //Added so plagarize can't copy agi/bless if you're undead since it damages you
+ if ((skillid == AL_INCAGI || skillid == AL_BLESSING ||
+ skillid == CASH_BLESSING || skillid == CASH_INCAGI ||
+ skillid == MER_INCAGI || skillid == MER_BLESSING))
+ return 0;
+
+ // Couldn't preserve 3rd Class skills except only when using Reproduce skill. [Jobbie]
+ if( !(sd->sc.data[SC__REPRODUCE]) && (skillid >= RK_ENCHANTBLADE && skillid <= SR_RIDEINLIGHTNING) )
+ return 0;
+ // Reproduce will only copy skills according on the list. [Jobbie]
+ else if( sd->sc.data[SC__REPRODUCE] && !skill_reproduce_db[skillid] )
+ return 0;
+
+ return 1;
}
// [MouseJstr] - skill ok to cast? and when?
-int skillnotok(int skillid, struct map_session_data *sd)
+int skillnotok (int skillid, struct map_session_data *sd)
{
- int i,m;
- nullpo_retr(1, sd);
- m = sd->bl.m;
- i = skill_get_index(skillid);
-
- if (i == 0)
- return 1; // invalid skill id
-
- if (pc_has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL))
- return 0; // can do any damn thing they want
-
- if (skillid == AL_TELEPORT && sd->skillitem == skillid && sd->skillitemlv > 2)
- return 0; // Teleport lv 3 bypasses this check.[Inkfish]
-
- // Epoque:
- // This code will compare the player's attack motion value which is influenced by ASPD before
- // allowing a skill to be cast. This is to prevent no-delay ACT files from spamming skills such as
- // AC_DOUBLE which do not have a skill delay and are not regarded in terms of attack motion.
- if (!sd->state.autocast && sd->skillitem != skillid && sd->canskill_tick &&
- DIFF_TICK(gettick(), sd->canskill_tick) < (sd->battle_status.amotion * (100 + battle_config.skill_amotion_leniency) / 100)) {
- // attempted to cast a skill before the attack motion has finished
- return 1;
- }
-
- if (sd->blockskill[i] > 0) {
- clif_skill_fail(sd, skillid, USESKILL_FAIL_SKILLINTERVAL, 0);
- return 1;
- }
- /**
- * It has been confirmed on a official server (thanks to Yommy) that item-cast skills bypass all the restrictions above
- * Also, without this check, an exploit where an item casting + healing (or any other kind buff) isn't deleted after used on a restricted map
- **/
- if (sd->skillitem == skillid)
- return 0;
- // Check skill restrictions [Celest]
- if ((!map_flag_vs(m) && skill_get_nocast(skillid) & 1) ||
- (map[m].flag.pvp && skill_get_nocast(skillid) & 2) ||
- (map_flag_gvg(m) && skill_get_nocast(skillid) & 4) ||
- (map[m].flag.battleground && skill_get_nocast(skillid) & 8) ||
- (map[m].flag.restricted && map[m].zone && skill_get_nocast(skillid) & (8*map[m].zone))) {
- clif_msg(sd, 0x536); // This skill cannot be used within this area
- return 1;
- }
-
- if (sd->sc.option&OPTION_MOUNTING)
- return 1;//You can't use skills while in the new mounts (The client doesn't let you, this is to make cheat-safe)
-
- switch (skillid) {
- case AL_WARP:
- case RETURN_TO_ELDICASTES:
- case ALL_GUARDIAN_RECALL:
- if (map[m].flag.nowarp) {
- clif_skill_teleportmessage(sd,0);
- return 1;
- }
- return 0;
- case AL_TELEPORT:
- case SC_FATALMENACE:
- case SC_DIMENSIONDOOR:
- if (map[m].flag.noteleport) {
- clif_skill_teleportmessage(sd,0);
- return 1;
- }
- return 0; // gonna be checked in 'skill_castend_nodamage_id'
- case WE_CALLPARTNER:
- case WE_CALLPARENT:
- case WE_CALLBABY:
- if (map[m].flag.nomemo) {
- clif_skill_teleportmessage(sd,1);
- return 1;
- }
- break;
- case MC_VENDING:
- case MC_IDENTIFY:
- case ALL_BUYING_STORE:
- return 0; // always allowed
- case WZ_ICEWALL:
- // noicewall flag [Valaris]
- if (map[m].flag.noicewall) {
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- return 1;
- }
- break;
- case GC_DARKILLUSION:
- if (map_flag_gvg(m)) {
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- return 1;
- }
- break;
- case GD_EMERGENCYCALL:
- if (
- !(battle_config.emergency_call&((agit_flag || agit2_flag)?2:1)) ||
- !(battle_config.emergency_call&(map[m].flag.gvg || map[m].flag.gvg_castle?8:4)) ||
- (battle_config.emergency_call&16 && map[m].flag.nowarpto && !map[m].flag.gvg_castle)
- ) {
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- return 1;
- }
- break;
- case BS_GREED:
- case WS_CARTBOOST:
- case BS_HAMMERFALL:
- case BS_ADRENALINE:
- case MC_CARTREVOLUTION:
- case MC_MAMMONITE:
- case WS_MELTDOWN:
- case MG_SIGHT:
- case TF_HIDING:
- /**
- * These skills cannot be used while in mado gear (credits to Xantara)
- **/
- if (pc_ismadogear(sd)) {
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- return 1;
- }
- break;
+ int i,m;
+ nullpo_retr (1, sd);
+ m = sd->bl.m;
+ i = skill_get_index(skillid);
+
+ if (i == 0)
+ return 1; // invalid skill id
+
+ if (pc_has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL))
+ return 0; // can do any damn thing they want
+
+ if( skillid == AL_TELEPORT && sd->skillitem == skillid && sd->skillitemlv > 2 )
+ return 0; // Teleport lv 3 bypasses this check.[Inkfish]
+
+ // Epoque:
+ // This code will compare the player's attack motion value which is influenced by ASPD before
+ // allowing a skill to be cast. This is to prevent no-delay ACT files from spamming skills such as
+ // AC_DOUBLE which do not have a skill delay and are not regarded in terms of attack motion.
+ if( !sd->state.autocast && sd->skillitem != skillid && sd->canskill_tick &&
+ DIFF_TICK(gettick(), sd->canskill_tick) < (sd->battle_status.amotion * (100 + battle_config.skill_amotion_leniency) / 100) )
+ {// attempted to cast a skill before the attack motion has finished
+ return 1;
+ }
- case WM_SIRCLEOFNATURE:
- case WM_SOUND_OF_DESTRUCTION:
- case SC_MANHOLE:
- case WM_LULLABY_DEEPSLEEP:
- case WM_SATURDAY_NIGHT_FEVER:
- if (!map_flag_vs(m)) {
- clif_skill_teleportmessage(sd,2); // This skill uses this msg instead of skill fails.
- return 1;
- }
- break;
+ if (sd->blockskill[i] > 0){
+ clif_skill_fail(sd, skillid, USESKILL_FAIL_SKILLINTERVAL, 0);
+ return 1;
+ }
+ /**
+ * It has been confirmed on a official server (thanks to Yommy) that item-cast skills bypass all the restrictions above
+ * Also, without this check, an exploit where an item casting + healing (or any other kind buff) isn't deleted after used on a restricted map
+ **/
+ if( sd->skillitem == skillid )
+ return 0;
+ // Check skill restrictions [Celest]
+ if( (!map_flag_vs(m) && skill_get_nocast (skillid) & 1) ||
+ (map[m].flag.pvp && skill_get_nocast (skillid) & 2) ||
+ (map_flag_gvg(m) && skill_get_nocast (skillid) & 4) ||
+ (map[m].flag.battleground && skill_get_nocast (skillid) & 8) ||
+ (map[m].flag.restricted && map[m].zone && skill_get_nocast (skillid) & (8*map[m].zone)) ){
+ clif_msg(sd, 0x536); // This skill cannot be used within this area
+ return 1;
+ }
+
+ if( sd->sc.option&OPTION_MOUNTING )
+ return 1;//You can't use skills while in the new mounts (The client doesn't let you, this is to make cheat-safe)
- }
- return (map[m].flag.noskill);
+ switch (skillid) {
+ case AL_WARP:
+ case RETURN_TO_ELDICASTES:
+ case ALL_GUARDIAN_RECALL:
+ if(map[m].flag.nowarp) {
+ clif_skill_teleportmessage(sd,0);
+ return 1;
+ }
+ return 0;
+ case AL_TELEPORT:
+ case SC_FATALMENACE:
+ case SC_DIMENSIONDOOR:
+ if(map[m].flag.noteleport) {
+ clif_skill_teleportmessage(sd,0);
+ return 1;
+ }
+ return 0; // gonna be checked in 'skill_castend_nodamage_id'
+ case WE_CALLPARTNER:
+ case WE_CALLPARENT:
+ case WE_CALLBABY:
+ if (map[m].flag.nomemo) {
+ clif_skill_teleportmessage(sd,1);
+ return 1;
+ }
+ break;
+ case MC_VENDING:
+ case MC_IDENTIFY:
+ case ALL_BUYING_STORE:
+ return 0; // always allowed
+ case WZ_ICEWALL:
+ // noicewall flag [Valaris]
+ if (map[m].flag.noicewall) {
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ return 1;
+ }
+ break;
+ case GC_DARKILLUSION:
+ if( map_flag_gvg(m) ) {
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ return 1;
+ }
+ break;
+ case GD_EMERGENCYCALL:
+ if (
+ !(battle_config.emergency_call&((agit_flag || agit2_flag)?2:1)) ||
+ !(battle_config.emergency_call&(map[m].flag.gvg || map[m].flag.gvg_castle?8:4)) ||
+ (battle_config.emergency_call&16 && map[m].flag.nowarpto && !map[m].flag.gvg_castle)
+ ) {
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ return 1;
+ }
+ break;
+ case BS_GREED:
+ case WS_CARTBOOST:
+ case BS_HAMMERFALL:
+ case BS_ADRENALINE:
+ case MC_CARTREVOLUTION:
+ case MC_MAMMONITE:
+ case WS_MELTDOWN:
+ case MG_SIGHT:
+ case TF_HIDING:
+ /**
+ * These skills cannot be used while in mado gear (credits to Xantara)
+ **/
+ if( pc_ismadogear(sd) ) {
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ return 1;
+ }
+ break;
+
+ case WM_SIRCLEOFNATURE:
+ case WM_SOUND_OF_DESTRUCTION:
+ case SC_MANHOLE:
+ case WM_LULLABY_DEEPSLEEP:
+ case WM_SATURDAY_NIGHT_FEVER:
+ if( !map_flag_vs(m) ) {
+ clif_skill_teleportmessage(sd,2); // This skill uses this msg instead of skill fails.
+ return 1;
+ }
+ break;
+
+ }
+ return (map[m].flag.noskill);
}
int skillnotok_hom(int skillid, struct homun_data *hd)
{
- int i = skill_get_index(skillid);
- nullpo_retr(1,hd);
-
- if (i == 0)
- return 1; // invalid skill id
-
- if (hd->blockskill[i] > 0)
- return 1;
- switch (skillid) {
- case MH_LIGHT_OF_REGENE:
- if (hd->homunculus.intimacy <= 750) //if not cordial
- return 1;
- break;
- case MH_OVERED_BOOST:
- if (hd->homunculus.hunger <= 1) //if we starving
- return 1;
- case MH_GOLDENE_FERSE: //can be used with angriff
- if (hd->sc.data[SC_ANGRIFFS_MODUS])
- return 1;
- case MH_ANGRIFFS_MODUS:
- if (hd->sc.data[SC_GOLDENE_FERSE])
- return 1;
- break;
- }
+ int i = skill_get_index(skillid);
+ nullpo_retr(1,hd);
+
+ if (i == 0)
+ return 1; // invalid skill id
+
+ if (hd->blockskill[i] > 0)
+ return 1;
+ switch(skillid){
+ case MH_LIGHT_OF_REGENE:
+ if(hd->homunculus.intimacy <= 750) //if not cordial
+ return 1;
+ break;
+ case MH_OVERED_BOOST:
+ if(hd->homunculus.hunger <= 1) //if we starving
+ return 1;
+ case MH_GOLDENE_FERSE: //can be used with angriff
+ if(hd->sc.data[SC_ANGRIFFS_MODUS])
+ return 1;
+ case MH_ANGRIFFS_MODUS:
+ if(hd->sc.data[SC_GOLDENE_FERSE])
+ return 1;
+ break;
+ }
- //Use master's criteria.
- return skillnotok(skillid, hd->master);
+ //Use master's criteria.
+ return skillnotok(skillid, hd->master);
}
int skillnotok_mercenary(int skillid, struct mercenary_data *md)
{
- int i = skill_get_index(skillid);
- nullpo_retr(1,md);
+ int i = skill_get_index(skillid);
+ nullpo_retr(1,md);
- if (i == 0)
- return 1; // Invalid Skill ID
- if (md->blockskill[i] > 0)
- return 1;
+ if( i == 0 )
+ return 1; // Invalid Skill ID
+ if( md->blockskill[i] > 0 )
+ return 1;
- return skillnotok(skillid, md->master);
+ return skillnotok(skillid, md->master);
}
-struct s_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;
+struct s_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 || pos >= MAX_SKILL_UNIT_LAYOUT) {
- ShowError("skill_get_unit_layout: unsupported layout type %d for skill %d (level %d)\n", pos, skillid, skilllv);
- pos = cap_value(pos, 0, MAX_SQUARE_LAYOUT); // cap to nearest square layout
- }
+ if (pos < -1 || pos >= MAX_SKILL_UNIT_LAYOUT) {
+ ShowError("skill_get_unit_layout: unsupported layout type %d for skill %d (level %d)\n", pos, skillid, skilllv);
+ pos = cap_value(pos, 0, MAX_SQUARE_LAYOUT); // cap to nearest square layout
+ }
- if (pos != -1) // simple single-definition layout
- return &skill_unit_layout[pos];
+ if (pos != -1) // simple single-definition layout
+ return &skill_unit_layout[pos];
- dir = (src->x == x && src->y == y) ? 6 : map_calc_dir(src,x,y); // 6 - default aegis direction
+ dir = (src->x == x && src->y == y) ? 6 : map_calc_dir(src,x,y); // 6 - default aegis direction
- 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];
- else if (skillid == WL_EARTHSTRAIN) //Warlock
- return &skill_unit_layout [earthstrain_unit_pos + dir];
+ 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];
+ else if( skillid == WL_EARTHSTRAIN ) //Warlock
+ return &skill_unit_layout [earthstrain_unit_pos + dir];
- ShowError("skill_get_unit_layout: unknown unit layout for skill %d (level %d)\n", skillid, skilllv);
- return &skill_unit_layout[0]; // default 1x1 layout
+ ShowError("skill_get_unit_layout: unknown unit layout for skill %d (level %d)\n", skillid, skilllv);
+ return &skill_unit_layout[0]; // default 1x1 layout
}
/*==========================================
*
*------------------------------------------*/
-int skill_additional_effect(struct block_list *src, struct block_list *bl, int skillid, int skilllv, int attack_type, int dmg_lv, unsigned int tick)
+int skill_additional_effect (struct block_list* src, struct block_list *bl, int skillid, int skilllv, int attack_type, int dmg_lv, unsigned int tick)
{
- struct map_session_data *sd, *dstsd;
- struct mob_data *md, *dstmd;
- struct status_data *sstatus, *tstatus;
- struct status_change *sc, *tsc;
-
- enum sc_type status;
- int skill;
- int rate;
-
- nullpo_ret(src);
- nullpo_ret(bl);
-
- if (skillid < 0) return 0;
- if (skillid > 0 && skilllv <= 0) return 0; // don't forget auto attacks! - celest
-
- if (dmg_lv < ATK_BLOCK) // Don't apply effect if miss.
- return 0;
-
- sd = BL_CAST(BL_PC, src);
- md = BL_CAST(BL_MOB, src);
- dstsd = BL_CAST(BL_PC, bl);
- dstmd = BL_CAST(BL_MOB, bl);
-
- sc = status_get_sc(src);
- tsc = status_get_sc(bl);
- sstatus = status_get_status_data(src);
- tstatus = status_get_status_data(bl);
- if (!tsc) //skill additional effect is about adding effects to the target...
- //So if the target can't be inflicted with statuses, this is pointless.
- return 0;
-
- if (sd) {
- // These statuses would be applied anyway even if the damage was blocked by some skills. [Inkfish]
- if (skillid != WS_CARTTERMINATION && skillid != AM_DEMONSTRATION && skillid != CR_REFLECTSHIELD && skillid != MS_REFLECTSHIELD && skillid != ASC_BREAKER) {
- // Trigger status effects
- enum sc_type type;
- int i;
- for (i = 0; i < ARRAYLENGTH(sd->addeff) && sd->addeff[i].flag; i++) {
- rate = sd->addeff[i].rate;
- if (attack_type&BF_LONG) // Any ranged physical attack takes status arrows into account (Grimtooth...) [DracoRPG]
- rate += sd->addeff[i].arrow_rate;
- if (!rate) continue;
-
- if ((sd->addeff[i].flag&(ATF_WEAPON|ATF_MAGIC|ATF_MISC)) != (ATF_WEAPON|ATF_MAGIC|ATF_MISC)) {
- // Trigger has attack type consideration.
- if ((sd->addeff[i].flag&ATF_WEAPON && attack_type&BF_WEAPON) ||
- (sd->addeff[i].flag&ATF_MAGIC && attack_type&BF_MAGIC) ||
- (sd->addeff[i].flag&ATF_MISC && attack_type&BF_MISC)) ;
- else
- continue;
- }
-
- if ((sd->addeff[i].flag&(ATF_LONG|ATF_SHORT)) != (ATF_LONG|ATF_SHORT)) {
- // Trigger has range consideration.
- if ((sd->addeff[i].flag&ATF_LONG && !(attack_type&BF_LONG)) ||
- (sd->addeff[i].flag&ATF_SHORT && !(attack_type&BF_SHORT)))
- continue; //Range Failed.
- }
-
- type = sd->addeff[i].id;
- skill = skill_get_time2(status_sc2skill(type),7);
-
- if (sd->addeff[i].flag&ATF_TARGET)
- status_change_start(bl,type,rate,7,0,0,0,skill,0);
-
- if (sd->addeff[i].flag&ATF_SELF)
- status_change_start(src,type,rate,7,0,0,0,skill,0);
- }
- }
-
- if (skillid) {
- // Trigger status effects on skills
- enum sc_type type;
- int i;
- for (i = 0; i < ARRAYLENGTH(sd->addeff3) && sd->addeff3[i].skill; i++) {
- if (skillid != sd->addeff3[i].skill || !sd->addeff3[i].rate)
- continue;
- type = sd->addeff3[i].id;
- skill = skill_get_time2(status_sc2skill(type),7);
-
- if (sd->addeff3[i].target&ATF_TARGET)
- status_change_start(bl,type,sd->addeff3[i].rate,7,0,0,0,skill,0);
- if (sd->addeff3[i].target&ATF_SELF)
- status_change_start(src,type,sd->addeff3[i].rate,7,0,0,0,skill,0);
- }
- }
- }
-
- if (dmg_lv < ATK_DEF) // no damage, return;
- return 0;
-
- switch (skillid) {
- case 0: { // Normal attacks (no skill used)
- if (attack_type&BF_SKILL)
- break; // If a normal attack is a skill, it's splash damage. [Inkfish]
- if (sd) {
- // Automatic trigger of Blitz Beat
- if (pc_isfalcon(sd) && sd->status.weapon == W_BOW && (skill=pc_checkskill(sd,HT_BLITZBEAT))>0 &&
- rnd()%1000 <= sstatus->luk*10/3+1) {
- rate=(sd->status.job_level+9)/10;
- skill_castend_damage_id(src,bl,HT_BLITZBEAT,(skill<rate)?skill:rate,tick,SD_LEVEL);
- }
- // Automatic trigger of Warg Strike [Jobbie]
- if (pc_iswug(sd) && (sd->status.weapon == W_BOW || sd->status.weapon == W_FIST) && (skill=pc_checkskill(sd,RA_WUGSTRIKE)) > 0 && rnd()%1000 <= sstatus->luk*10/3+1)
- skill_castend_damage_id(src,bl,RA_WUGSTRIKE,skill,tick,0);
- // Gank
- if (dstmd && sd->status.weapon != W_BOW &&
- (skill=pc_checkskill(sd,RG_SNATCHER)) > 0 &&
- (skill*15 + 55) + pc_checkskill(sd,TF_STEAL)*10 > rnd()%1000) {
- if (pc_steal_item(sd,bl,pc_checkskill(sd,TF_STEAL)))
- clif_skill_nodamage(src,bl,TF_STEAL,skill,1);
- else
- clif_skill_fail(sd,RG_SNATCHER,USESKILL_FAIL_LEVEL,0);
- }
- // Chance to trigger Taekwon kicks [Dralnu]
- if (sc && !sc->data[SC_COMBO]) {
- if (sc->data[SC_READYSTORM] &&
- sc_start(src,SC_COMBO, 15, TK_STORMKICK,
- (2000 - 4*sstatus->agi - 2*sstatus->dex)))
- ; //Stance triggered
- else if (sc->data[SC_READYDOWN] &&
- sc_start(src,SC_COMBO, 15, TK_DOWNKICK,
- (2000 - 4*sstatus->agi - 2*sstatus->dex)))
- ; //Stance triggered
- else if (sc->data[SC_READYTURN] &&
- sc_start(src,SC_COMBO, 15, TK_TURNKICK,
- (2000 - 4*sstatus->agi - 2*sstatus->dex)))
- ; //Stance triggered
- else if (sc->data[SC_READYCOUNTER]) { //additional chance from SG_FRIEND [Komurka]
- rate = 20;
- if (sc->data[SC_SKILLRATE_UP] && sc->data[SC_SKILLRATE_UP]->val1 == TK_COUNTER) {
- rate += rate*sc->data[SC_SKILLRATE_UP]->val2/100;
- status_change_end(src, SC_SKILLRATE_UP, INVALID_TIMER);
- }
- sc_start2(src, SC_COMBO, rate, TK_COUNTER, bl->id,
- (2000 - 4*sstatus->agi - 2*sstatus->dex));
- }
- }
- if (sc && sc->data[SC_PYROCLASTIC] && (rnd() % 1000 <= sstatus->luk * 10 / 3 + 1))
- skill_castend_pos2(src, bl->x, bl->y, BS_HAMMERFALL,sc->data[SC_PYROCLASTIC]->val1, tick, 0);
- }
-
- if (sc) {
- struct status_change_entry *sce;
- // Enchant Poison gives a chance to poison attacked enemies
- if ((sce=sc->data[SC_ENCPOISON])) //Don't use sc_start since chance comes in 1/10000 rate.
- status_change_start(bl,SC_POISON,sce->val2, sce->val1,src->id,0,0,
- skill_get_time2(AS_ENCHANTPOISON,sce->val1),0);
- // Enchant Deadly Poison gives a chance to deadly poison attacked enemies
- if ((sce=sc->data[SC_EDP]))
- sc_start4(bl,SC_DPOISON,sce->val2, sce->val1,src->id,0,0,
- skill_get_time2(ASC_EDP,sce->val1));
- }
- }
- break;
+ struct map_session_data *sd, *dstsd;
+ struct mob_data *md, *dstmd;
+ struct status_data *sstatus, *tstatus;
+ struct status_change *sc, *tsc;
+
+ enum sc_type status;
+ int skill;
+ int rate;
+
+ nullpo_ret(src);
+ nullpo_ret(bl);
+
+ if(skillid < 0) return 0;
+ if(skillid > 0 && skilllv <= 0) return 0; // don't forget auto attacks! - celest
+
+ if( dmg_lv < ATK_BLOCK ) // Don't apply effect if miss.
+ return 0;
+
+ sd = BL_CAST(BL_PC, src);
+ md = BL_CAST(BL_MOB, src);
+ dstsd = BL_CAST(BL_PC, bl);
+ dstmd = BL_CAST(BL_MOB, bl);
+
+ sc = status_get_sc(src);
+ tsc = status_get_sc(bl);
+ sstatus = status_get_status_data(src);
+ tstatus = status_get_status_data(bl);
+ if (!tsc) //skill additional effect is about adding effects to the target...
+ //So if the target can't be inflicted with statuses, this is pointless.
+ return 0;
+
+ if( sd )
+ { // These statuses would be applied anyway even if the damage was blocked by some skills. [Inkfish]
+ if( skillid != WS_CARTTERMINATION && skillid != AM_DEMONSTRATION && skillid != CR_REFLECTSHIELD && skillid != MS_REFLECTSHIELD && skillid != ASC_BREAKER )
+ { // Trigger status effects
+ enum sc_type type;
+ int i;
+ for( i = 0; i < ARRAYLENGTH(sd->addeff) && sd->addeff[i].flag; i++ )
+ {
+ rate = sd->addeff[i].rate;
+ if( attack_type&BF_LONG ) // Any ranged physical attack takes status arrows into account (Grimtooth...) [DracoRPG]
+ rate += sd->addeff[i].arrow_rate;
+ if( !rate ) continue;
+
+ if( (sd->addeff[i].flag&(ATF_WEAPON|ATF_MAGIC|ATF_MISC)) != (ATF_WEAPON|ATF_MAGIC|ATF_MISC) )
+ { // Trigger has attack type consideration.
+ if( (sd->addeff[i].flag&ATF_WEAPON && attack_type&BF_WEAPON) ||
+ (sd->addeff[i].flag&ATF_MAGIC && attack_type&BF_MAGIC) ||
+ (sd->addeff[i].flag&ATF_MISC && attack_type&BF_MISC) ) ;
+ else
+ continue;
+ }
- case SM_BASH:
- if (sd && skilllv > 5 && pc_checkskill(sd,SM_FATALBLOW)>0) {
- //TODO: How much % per base level it actually is?
- sc_start(bl,SC_STUN,(5*(skilllv-5)+(int)sd->status.base_level/10),
- skilllv,skill_get_time2(SM_FATALBLOW,skilllv));
- }
- break;
+ if( (sd->addeff[i].flag&(ATF_LONG|ATF_SHORT)) != (ATF_LONG|ATF_SHORT) )
+ { // Trigger has range consideration.
+ if((sd->addeff[i].flag&ATF_LONG && !(attack_type&BF_LONG)) ||
+ (sd->addeff[i].flag&ATF_SHORT && !(attack_type&BF_SHORT)))
+ continue; //Range Failed.
+ }
- case MER_CRASH:
- sc_start(bl,SC_STUN,(6*skilllv),skilllv,skill_get_time2(skillid,skilllv));
- break;
+ type = sd->addeff[i].id;
+ skill = skill_get_time2(status_sc2skill(type),7);
- case AS_VENOMKNIFE:
- if (sd) //Poison chance must be that of Envenom. [Skotlex]
- skilllv = pc_checkskill(sd, TF_POISON);
- case TF_POISON:
- case AS_SPLASHER:
- if (!sc_start2(bl,SC_POISON,(4*skilllv+10),skilllv,src->id,skill_get_time2(skillid,skilllv))
- && sd && skillid==TF_POISON
- )
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
+ if (sd->addeff[i].flag&ATF_TARGET)
+ status_change_start(bl,type,rate,7,0,0,0,skill,0);
- case AS_SONICBLOW:
- sc_start(bl,SC_STUN,(2*skilllv+10),skilllv,skill_get_time2(skillid,skilllv));
- break;
+ if (sd->addeff[i].flag&ATF_SELF)
+ status_change_start(src,type,rate,7,0,0,0,skill,0);
+ }
+ }
- case WZ_FIREPILLAR:
- unit_set_walkdelay(bl, tick, skill_get_time2(skillid, skilllv), 1);
- break;
+ if( skillid )
+ { // Trigger status effects on skills
+ enum sc_type type;
+ int i;
+ for( i = 0; i < ARRAYLENGTH(sd->addeff3) && sd->addeff3[i].skill; i++ )
+ {
+ if( skillid != sd->addeff3[i].skill || !sd->addeff3[i].rate )
+ continue;
+ type = sd->addeff3[i].id;
+ skill = skill_get_time2(status_sc2skill(type),7);
+
+ if( sd->addeff3[i].target&ATF_TARGET )
+ status_change_start(bl,type,sd->addeff3[i].rate,7,0,0,0,skill,0);
+ if( sd->addeff3[i].target&ATF_SELF )
+ status_change_start(src,type,sd->addeff3[i].rate,7,0,0,0,skill,0);
+ }
+ }
+ }
- case MG_FROSTDIVER:
+ if( dmg_lv < ATK_DEF ) // no damage, return;
+ return 0;
+
+ switch(skillid)
+ {
+ case 0: // Normal attacks (no skill used)
+ {
+ if( attack_type&BF_SKILL )
+ break; // If a normal attack is a skill, it's splash damage. [Inkfish]
+ if(sd) {
+ // Automatic trigger of Blitz Beat
+ if (pc_isfalcon(sd) && sd->status.weapon == W_BOW && (skill=pc_checkskill(sd,HT_BLITZBEAT))>0 &&
+ rnd()%1000 <= sstatus->luk*10/3+1 ) {
+ rate=(sd->status.job_level+9)/10;
+ skill_castend_damage_id(src,bl,HT_BLITZBEAT,(skill<rate)?skill:rate,tick,SD_LEVEL);
+ }
+ // Automatic trigger of Warg Strike [Jobbie]
+ if( pc_iswug(sd) && (sd->status.weapon == W_BOW || sd->status.weapon == W_FIST) && (skill=pc_checkskill(sd,RA_WUGSTRIKE)) > 0 && rnd()%1000 <= sstatus->luk*10/3+1 )
+ skill_castend_damage_id(src,bl,RA_WUGSTRIKE,skill,tick,0);
+ // Gank
+ if(dstmd && sd->status.weapon != W_BOW &&
+ (skill=pc_checkskill(sd,RG_SNATCHER)) > 0 &&
+ (skill*15 + 55) + pc_checkskill(sd,TF_STEAL)*10 > rnd()%1000) {
+ if(pc_steal_item(sd,bl,pc_checkskill(sd,TF_STEAL)))
+ clif_skill_nodamage(src,bl,TF_STEAL,skill,1);
+ else
+ clif_skill_fail(sd,RG_SNATCHER,USESKILL_FAIL_LEVEL,0);
+ }
+ // Chance to trigger Taekwon kicks [Dralnu]
+ if(sc && !sc->data[SC_COMBO]) {
+ if(sc->data[SC_READYSTORM] &&
+ sc_start(src,SC_COMBO, 15, TK_STORMKICK,
+ (2000 - 4*sstatus->agi - 2*sstatus->dex)))
+ ; //Stance triggered
+ else if(sc->data[SC_READYDOWN] &&
+ sc_start(src,SC_COMBO, 15, TK_DOWNKICK,
+ (2000 - 4*sstatus->agi - 2*sstatus->dex)))
+ ; //Stance triggered
+ else if(sc->data[SC_READYTURN] &&
+ sc_start(src,SC_COMBO, 15, TK_TURNKICK,
+ (2000 - 4*sstatus->agi - 2*sstatus->dex)))
+ ; //Stance triggered
+ else if (sc->data[SC_READYCOUNTER]) { //additional chance from SG_FRIEND [Komurka]
+ rate = 20;
+ if (sc->data[SC_SKILLRATE_UP] && sc->data[SC_SKILLRATE_UP]->val1 == TK_COUNTER) {
+ rate += rate*sc->data[SC_SKILLRATE_UP]->val2/100;
+ status_change_end(src, SC_SKILLRATE_UP, INVALID_TIMER);
+ }
+ sc_start2(src, SC_COMBO, rate, TK_COUNTER, bl->id,
+ (2000 - 4*sstatus->agi - 2*sstatus->dex));
+ }
+ }
+ if(sc && sc->data[SC_PYROCLASTIC] && (rnd() % 1000 <= sstatus->luk * 10 / 3 + 1) )
+ skill_castend_pos2(src, bl->x, bl->y, BS_HAMMERFALL,sc->data[SC_PYROCLASTIC]->val1, tick, 0);
+ }
+
+ if (sc) {
+ struct status_change_entry *sce;
+ // Enchant Poison gives a chance to poison attacked enemies
+ if((sce=sc->data[SC_ENCPOISON])) //Don't use sc_start since chance comes in 1/10000 rate.
+ status_change_start(bl,SC_POISON,sce->val2, sce->val1,src->id,0,0,
+ skill_get_time2(AS_ENCHANTPOISON,sce->val1),0);
+ // Enchant Deadly Poison gives a chance to deadly poison attacked enemies
+ if((sce=sc->data[SC_EDP]))
+ sc_start4(bl,SC_DPOISON,sce->val2, sce->val1,src->id,0,0,
+ skill_get_time2(ASC_EDP,sce->val1));
+ }
+ }
+ break;
+
+ case SM_BASH:
+ if( sd && skilllv > 5 && pc_checkskill(sd,SM_FATALBLOW)>0 ){
+ //TODO: How much % per base level it actually is?
+ sc_start(bl,SC_STUN,(5*(skilllv-5)+(int)sd->status.base_level/10),
+ skilllv,skill_get_time2(SM_FATALBLOW,skilllv));
+ }
+ break;
+
+ case MER_CRASH:
+ sc_start(bl,SC_STUN,(6*skilllv),skilllv,skill_get_time2(skillid,skilllv));
+ break;
+
+ case AS_VENOMKNIFE:
+ if (sd) //Poison chance must be that of Envenom. [Skotlex]
+ skilllv = pc_checkskill(sd, TF_POISON);
+ case TF_POISON:
+ case AS_SPLASHER:
+ if(!sc_start2(bl,SC_POISON,(4*skilllv+10),skilllv,src->id,skill_get_time2(skillid,skilllv))
+ && sd && skillid==TF_POISON
+ )
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+
+ case AS_SONICBLOW:
+ sc_start(bl,SC_STUN,(2*skilllv+10),skilllv,skill_get_time2(skillid,skilllv));
+ break;
+
+ case WZ_FIREPILLAR:
+ unit_set_walkdelay(bl, tick, skill_get_time2(skillid, skilllv), 1);
+ break;
+
+ case MG_FROSTDIVER:
#ifndef RENEWAL
- case WZ_FROSTNOVA:
+ case WZ_FROSTNOVA:
#endif
- sc_start(bl,SC_FREEZE,skilllv*3+35,skilllv,skill_get_time2(skillid,skilllv));
- break;
+ sc_start(bl,SC_FREEZE,skilllv*3+35,skilllv,skill_get_time2(skillid,skilllv));
+ break;
#ifdef RENEWAL
- case WZ_FROSTNOVA:
- sc_start(bl,SC_FREEZE,skilllv*5+33,skilllv,skill_get_time2(skillid,skilllv));
- break;
+ case WZ_FROSTNOVA:
+ sc_start(bl,SC_FREEZE,skilllv*5+33,skilllv,skill_get_time2(skillid,skilllv));
+ break;
#endif
- case WZ_STORMGUST:
- /**
- * Storm Gust counter was dropped in renewal
- **/
-#ifdef RENEWAL
- sc_start(bl,SC_FREEZE,65-(5*skilllv),skilllv,skill_get_time2(skillid,skilllv));
-#else
- //Tharis pointed out that this is normal freeze chance with a base of 300%
- if (tsc->sg_counter >= 3 &&
- sc_start(bl,SC_FREEZE,300,skilllv,skill_get_time2(skillid,skilllv)))
- tsc->sg_counter = 0;
- /**
- * being it only resets on success it'd keep stacking and eventually overflowing on mvps, so we reset at a high value
- **/
- else if (tsc->sg_counter > 250)
- tsc->sg_counter = 0;
-#endif
- break;
+ case WZ_STORMGUST:
+ /**
+ * Storm Gust counter was dropped in renewal
+ **/
+ #ifdef RENEWAL
+ sc_start(bl,SC_FREEZE,65-(5*skilllv),skilllv,skill_get_time2(skillid,skilllv));
+ #else
+ //Tharis pointed out that this is normal freeze chance with a base of 300%
+ if(tsc->sg_counter >= 3 &&
+ sc_start(bl,SC_FREEZE,300,skilllv,skill_get_time2(skillid,skilllv)))
+ tsc->sg_counter = 0;
+ /**
+ * being it only resets on success it'd keep stacking and eventually overflowing on mvps, so we reset at a high value
+ **/
+ else if( tsc->sg_counter > 250 )
+ tsc->sg_counter = 0;
+ #endif
+ break;
+
+ case WZ_METEOR:
+ sc_start(bl,SC_STUN,3*skilllv,skilllv,skill_get_time2(skillid,skilllv));
+ break;
+
+ case WZ_VERMILION:
+ sc_start(bl,SC_BLIND,4*skilllv,skilllv,skill_get_time2(skillid,skilllv));
+ break;
+
+ case HT_FREEZINGTRAP:
+ case MA_FREEZINGTRAP:
+ sc_start(bl,SC_FREEZE,(3*skilllv+35),skilllv,skill_get_time2(skillid,skilllv));
+ break;
+
+ case HT_FLASHER:
+ sc_start(bl,SC_BLIND,(10*skilllv+30),skilllv,skill_get_time2(skillid,skilllv));
+ break;
+
+ case HT_LANDMINE:
+ case MA_LANDMINE:
+ sc_start(bl,SC_STUN,(5*skilllv+30),skilllv,skill_get_time2(skillid,skilllv));
+ break;
+
+ case HT_SHOCKWAVE:
+ status_percent_damage(src, bl, 0, 15*skilllv+5, false);
+ break;
+
+ case HT_SANDMAN:
+ case MA_SANDMAN:
+ sc_start(bl,SC_SLEEP,(10*skilllv+40),skilllv,skill_get_time2(skillid,skilllv));
+ break;
+
+ case TF_SPRINKLESAND:
+ sc_start(bl,SC_BLIND,20,skilllv,skill_get_time2(skillid,skilllv));
+ break;
+
+ case TF_THROWSTONE:
+ sc_start(bl,SC_STUN,3,skilllv,skill_get_time(skillid,skilllv));
+ sc_start(bl,SC_BLIND,3,skilllv,skill_get_time2(skillid,skilllv));
+ break;
+
+ case NPC_DARKCROSS:
+ case CR_HOLYCROSS:
+ sc_start(bl,SC_BLIND,3*skilllv,skilllv,skill_get_time2(skillid,skilllv));
+ break;
+
+ case CR_GRANDCROSS:
+ case NPC_GRANDDARKNESS:
+ //Chance to cause blind status vs demon and undead element, but not against players
+ if(!dstsd && (battle_check_undead(tstatus->race,tstatus->def_ele) || tstatus->race == RC_DEMON))
+ sc_start(bl,SC_BLIND,100,skilllv,skill_get_time2(skillid,skilllv));
+ attack_type |= BF_WEAPON;
+ break;
+
+ case AM_ACIDTERROR:
+ sc_start(bl,SC_BLEEDING,(skilllv*3),skilllv,skill_get_time2(skillid,skilllv));
+ if (skill_break_equip(bl, EQP_ARMOR, 100*skill_get_time(skillid,skilllv), BCT_ENEMY))
+ clif_emotion(bl,E_OMG);
+ break;
+
+ case AM_DEMONSTRATION:
+ skill_break_equip(bl, EQP_WEAPON, 100*skilllv, BCT_ENEMY);
+ break;
+
+ case CR_SHIELDCHARGE:
+ sc_start(bl,SC_STUN,(15+skilllv*5),skilllv,skill_get_time2(skillid,skilllv));
+ break;
+
+ case PA_PRESSURE:
+ status_percent_damage(src, bl, 0, 15+5*skilllv, false);
+ break;
+
+ case RG_RAID:
+ sc_start(bl,SC_STUN,(10+3*skilllv),skilllv,skill_get_time(skillid,skilllv));
+ sc_start(bl,SC_BLIND,(10+3*skilllv),skilllv,skill_get_time2(skillid,skilllv));
- case WZ_METEOR:
- sc_start(bl,SC_STUN,3*skilllv,skilllv,skill_get_time2(skillid,skilllv));
- break;
+#ifdef RENEWAL
+ sc_start(bl,SC_RAID,100,7,5000);
+ break;
- case WZ_VERMILION:
- sc_start(bl,SC_BLIND,4*skilllv,skilllv,skill_get_time2(skillid,skilllv));
- break;
+ case RG_BACKSTAP:
+ sc_start(bl,SC_STUN,(5+2*skilllv),skilllv,skill_get_time(skillid,skilllv));
+#endif
+ break;
+
+ case BA_FROSTJOKER:
+ sc_start(bl,SC_FREEZE,(15+5*skilllv),skilllv,skill_get_time2(skillid,skilllv));
+ break;
+
+ case DC_SCREAM:
+ sc_start(bl,SC_STUN,(25+5*skilllv),skilllv,skill_get_time2(skillid,skilllv));
+ break;
+
+ case BD_LULLABY:
+ sc_start(bl,SC_SLEEP,15,skilllv,skill_get_time2(skillid,skilllv));
+ break;
+
+ case DC_UGLYDANCE:
+ rate = 5+5*skilllv;
+ if(sd && (skill=pc_checkskill(sd,DC_DANCINGLESSON)))
+ rate += 5+skill;
+ status_zap(bl, 0, rate);
+ break;
+ case SL_STUN:
+ if (tstatus->size==SZ_MEDIUM) //Only stuns mid-sized mobs.
+ sc_start(bl,SC_STUN,(30+10*skilllv),skilllv,skill_get_time(skillid,skilllv));
+ break;
+
+ case NPC_PETRIFYATTACK:
+ sc_start4(bl,status_skill2sc(skillid),50+10*skilllv,
+ skilllv,0,0,skill_get_time(skillid,skilllv),
+ skill_get_time2(skillid,skilllv));
+ break;
+ case NPC_CURSEATTACK:
+ case NPC_SLEEPATTACK:
+ case NPC_BLINDATTACK:
+ case NPC_POISON:
+ case NPC_SILENCEATTACK:
+ case NPC_STUNATTACK:
+ case NPC_HELLPOWER:
+ sc_start(bl,status_skill2sc(skillid),50+10*skilllv,skilllv,skill_get_time2(skillid,skilllv));
+ break;
+ case NPC_ACIDBREATH:
+ case NPC_ICEBREATH:
+ sc_start(bl,status_skill2sc(skillid),70,skilllv,skill_get_time2(skillid,skilllv));
+ break;
+ case NPC_BLEEDING:
+ sc_start(bl,SC_BLEEDING,(20*skilllv),skilllv,skill_get_time2(skillid,skilllv));
+ break;
+ case NPC_MENTALBREAKER:
+ { //Based on observations by Tharis, Mental Breaker should do SP damage
+ //equal to Matk*skLevel.
+ rate = sstatus->matk_min;
+ if (rate < sstatus->matk_max)
+ rate += rnd()%(sstatus->matk_max - sstatus->matk_min);
+ rate*=skilllv;
+ status_zap(bl, 0, rate);
+ break;
+ }
+ // Equipment breaking monster skills [Celest]
+ case NPC_WEAPONBRAKER:
+ skill_break_equip(bl, EQP_WEAPON, 150*skilllv, BCT_ENEMY);
+ break;
+ case NPC_ARMORBRAKE:
+ skill_break_equip(bl, EQP_ARMOR, 150*skilllv, BCT_ENEMY);
+ break;
+ case NPC_HELMBRAKE:
+ skill_break_equip(bl, EQP_HELM, 150*skilllv, BCT_ENEMY);
+ break;
+ case NPC_SHIELDBRAKE:
+ skill_break_equip(bl, EQP_SHIELD, 150*skilllv, BCT_ENEMY);
+ break;
+
+ case CH_TIGERFIST:
+ sc_start(bl,SC_STOP,(10+skilllv*10),0,skill_get_time2(skillid,skilllv));
+ break;
+
+ case LK_SPIRALPIERCE:
+ case ML_SPIRALPIERCE:
+ sc_start(bl,SC_STOP,(15+skilllv*5),0,skill_get_time2(skillid,skilllv));
+ break;
+
+ case ST_REJECTSWORD:
+ sc_start(bl,SC_AUTOCOUNTER,(skilllv*15),skilllv,skill_get_time(skillid,skilllv));
+ break;
+
+ case PF_FOGWALL:
+ if (src != bl && !tsc->data[SC_DELUGE])
+ status_change_start(bl,SC_BLIND,10000,skilllv,0,0,0,skill_get_time2(skillid,skilllv),8);
+ break;
+
+ case LK_HEADCRUSH: //Headcrush has chance of causing Bleeding status, except on demon and undead element
+ if (!(battle_check_undead(tstatus->race, tstatus->def_ele) || tstatus->race == RC_DEMON))
+ sc_start(bl, SC_BLEEDING,50, skilllv, skill_get_time2(skillid,skilllv));
+ break;
+
+ case LK_JOINTBEAT:
+ status = status_skill2sc(skillid);
+ if (tsc->jb_flag) {
+ sc_start2(bl,status,(5*skilllv+5),skilllv,tsc->jb_flag&BREAK_FLAGS,skill_get_time2(skillid,skilllv));
+ tsc->jb_flag = 0;
+ }
+ break;
+ case ASC_METEORASSAULT:
+ //Any enemies hit by this skill will receive Stun, Darkness, or external bleeding status ailment with a 5%+5*SkillLV% chance.
+ switch(rnd()%3) {
+ case 0:
+ sc_start(bl,SC_BLIND,(5+skilllv*5),skilllv,skill_get_time2(skillid,1));
+ break;
+ case 1:
+ sc_start(bl,SC_STUN,(5+skilllv*5),skilllv,skill_get_time2(skillid,2));
+ break;
+ default:
+ sc_start(bl,SC_BLEEDING,(5+skilllv*5),skilllv,skill_get_time2(skillid,3));
+ }
+ break;
+
+ case HW_NAPALMVULCAN:
+ sc_start(bl,SC_CURSE,5*skilllv,skilllv,skill_get_time2(skillid,skilllv));
+ break;
+
+ case WS_CARTTERMINATION: // Cart termination
+ sc_start(bl,SC_STUN,5*skilllv,skilllv,skill_get_time2(skillid,skilllv));
+ break;
+
+ case CR_ACIDDEMONSTRATION:
+ skill_break_equip(bl, EQP_WEAPON|EQP_ARMOR, 100*skilllv, BCT_ENEMY);
+ break;
+
+ case TK_DOWNKICK:
+ sc_start(bl,SC_STUN,100,skilllv,skill_get_time2(skillid,skilllv));
+ break;
+
+ case TK_JUMPKICK:
+ if( dstsd && dstsd->class_ != MAPID_SOUL_LINKER && !tsc->data[SC_PRESERVE] )
+ {// debuff the following statuses
+ status_change_end(bl, SC_SPIRIT, INVALID_TIMER);
+ status_change_end(bl, SC_ADRENALINE2, INVALID_TIMER);
+ status_change_end(bl, SC_KAITE, INVALID_TIMER);
+ status_change_end(bl, SC_KAAHI, INVALID_TIMER);
+ status_change_end(bl, SC_ONEHAND, INVALID_TIMER);
+ status_change_end(bl, SC_ASPDPOTION2, INVALID_TIMER);
+ }
+ break;
+ case TK_TURNKICK:
+ case MO_BALKYOUNG: //Note: attack_type is passed as BF_WEAPON for the actual target, BF_MISC for the splash-affected mobs.
+ if(attack_type&BF_MISC) //70% base stun chance...
+ sc_start(bl,SC_STUN,70,skilllv,skill_get_time2(skillid,skilllv));
+ break;
+ case GS_BULLSEYE: //0.1% coma rate.
+ if(tstatus->race == RC_BRUTE || tstatus->race == RC_DEMIHUMAN)
+ status_change_start(bl,SC_COMA,10,skilllv,0,src->id,0,0,0);
+ break;
+ case GS_PIERCINGSHOT:
+ sc_start(bl,SC_BLEEDING,(skilllv*3),skilllv,skill_get_time2(skillid,skilllv));
+ break;
+ case NJ_HYOUSYOURAKU:
+ sc_start(bl,SC_FREEZE,(10+10*skilllv),skilllv,skill_get_time2(skillid,skilllv));
+ break;
+ case GS_FLING:
+ sc_start(bl,SC_FLING,100, sd?sd->spiritball_old:5,skill_get_time(skillid,skilllv));
+ break;
+ case GS_DISARM:
+ rate = 3*skilllv;
+ if (sstatus->dex > tstatus->dex)
+ rate += (sstatus->dex - tstatus->dex)/5; //TODO: Made up formula
+ skill_strip_equip(bl, EQP_WEAPON, rate, skilllv, skill_get_time(skillid,skilllv));
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ break;
+ case NPC_EVILLAND:
+ sc_start(bl,SC_BLIND,5*skilllv,skilllv,skill_get_time2(skillid,skilllv));
+ break;
+ case NPC_HELLJUDGEMENT:
+ sc_start(bl,SC_CURSE,100,skilllv,skill_get_time2(skillid,skilllv));
+ break;
+ case NPC_CRITICALWOUND:
+ sc_start(bl,SC_CRITICALWOUND,100,skilllv,skill_get_time2(skillid,skilllv));
+ break;
+ case RK_HUNDREDSPEAR:
+ if( !sd || pc_checkskill(sd,KN_SPEARBOOMERANG) == 0 )
+ break; // Spear Boomerang auto cast chance only works if you have mastered Spear Boomerang.
+ rate = 10 + 3 * skilllv;
+ if( rnd()%100 < rate )
+ skill_castend_damage_id(src,bl,KN_SPEARBOOMERANG,1,tick,0);
+ break;
+ case RK_WINDCUTTER:
+ sc_start(bl,SC_FEAR,3+2*skilllv,skilllv,skill_get_time(skillid,skilllv));
+ break;
+ case RK_DRAGONBREATH:
+ sc_start4(bl,SC_BURNING,5+5*skilllv,skilllv,1000,src->id,0,skill_get_time(skillid,skilllv));
+ break;
+ case AB_ADORAMUS:
+ if( tsc && !tsc->data[SC_DECREASEAGI] ) //Prevent duplicate agi-down effect.
+ sc_start(bl, SC_ADORAMUS, 100, skilllv, skill_get_time(skillid, skilllv));
+ break;
+ case WL_CRIMSONROCK:
+ sc_start(bl, SC_STUN, 40, skilllv, skill_get_time(skillid, skilllv));
+ break;
+ case WL_COMET:
+ sc_start4(bl,SC_BURNING,100,skilllv,1000,src->id,0,skill_get_time(skillid,skilllv));
+ break;
+ case WL_EARTHSTRAIN:
+ {
+ int rate = 0, i;
+ const int pos[5] = { EQP_WEAPON, EQP_HELM, EQP_SHIELD, EQP_ARMOR, EQP_ACC };
+ rate = 6 * skilllv + sstatus->dex / 10 + (sd? sd->status.job_level / 4 : 0) - tstatus->dex /5;// The tstatus->dex / 5 part is unofficial, but players gotta have some kind of way to have resistance. [Rytech]
+ //rate -= rate * tstatus->dex / 200; // Disabled until official resistance is found.
+
+ for( i = 0; i < skilllv; i++ )
+ skill_strip_equip(bl,pos[i],rate,skilllv,skill_get_time2(skillid,skilllv));
+ }
+ break;
+ case WL_JACKFROST:
+ sc_start(bl,SC_FREEZE,100,skilllv,skill_get_time(skillid,skilllv));
+ break;
+ case RA_WUGBITE:
+ sc_start(bl, SC_BITE, (sd ? pc_checkskill(sd,RA_TOOTHOFWUG)*2 : 0), skilllv, (skill_get_time(skillid,skilllv) + (sd ? pc_checkskill(sd,RA_TOOTHOFWUG)*500 : 0)) );
+ break;
+ case RA_SENSITIVEKEEN:
+ if( rnd()%100 < 8 * skilllv )
+ skill_castend_damage_id(src, bl, RA_WUGBITE, sd ? pc_checkskill(sd, RA_WUGBITE):skilllv, tick, SD_ANIMATION);
+ break;
+ case RA_FIRINGTRAP:
+ case RA_ICEBOUNDTRAP:
+ sc_start(bl, (skillid == RA_FIRINGTRAP) ? SC_BURNING:SC_FREEZING, 40 + 10 * skilllv, skilllv, skill_get_time2(skillid, skilllv));
+ break;
+ case NC_PILEBUNKER:
+ if( rnd()%100 < 5 + 15*skilllv )
+ { //Deactivatable Statuses: Kyrie Eleison, Auto Guard, Steel Body, Assumptio, and Millennium Shield
+ status_change_end(bl, SC_KYRIE, INVALID_TIMER);
+ status_change_end(bl, SC_AUTOGUARD, INVALID_TIMER);
+ status_change_end(bl, SC_STEELBODY, INVALID_TIMER);
+ status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
+ status_change_end(bl, SC_MILLENNIUMSHIELD, INVALID_TIMER);
+ }
+ break;
+ case NC_FLAMELAUNCHER:
+ sc_start4(bl, SC_BURNING, 50 + 10 * skilllv, skilllv, 1000, src->id, 0, skill_get_time2(skillid, skilllv));
+ break;
+ case NC_COLDSLOWER:
+ sc_start(bl, SC_FREEZE, 10 * skilllv, skilllv, skill_get_time(skillid, skilllv));
+ sc_start(bl, SC_FREEZING, 20 + 10 * skilllv, skilllv, skill_get_time(skillid, skilllv));
+ break;
+ case NC_POWERSWING:
+ sc_start(bl, SC_STUN, 5*skilllv, skilllv, skill_get_time(skillid, skilllv));
+ if( rnd()%100 < 5*skilllv )
+ skill_castend_damage_id(src, bl, NC_AXEBOOMERANG, pc_checkskill(sd, NC_AXEBOOMERANG), tick, 1);
+ break;
+ case GC_WEAPONCRUSH:
+ skill_castend_nodamage_id(src,bl,skillid,skilllv,tick,BCT_ENEMY);
+ break;
+ case LG_SHIELDPRESS:
+ sc_start(bl, SC_STUN, 30 + 8 * skilllv, skilllv, skill_get_time(skillid,skilllv));
+ break;
+ case LG_PINPOINTATTACK:
+ rate = 30 + (((5 * (sd?pc_checkskill(sd,LG_PINPOINTATTACK):skilllv)) + (sstatus->agi + status_get_lv(src))) / 10);
+ switch( skilllv ) {
+ case 1:
+ sc_start(bl,SC_BLEEDING,rate,skilllv,skill_get_time(skillid,skilllv));
+ break;
+ case 2:
+ if( dstsd && dstsd->spiritball && rnd()%100 < rate )
+ pc_delspiritball(dstsd, dstsd->spiritball, 0);
+ break;
+ default:
+ skill_break_equip(bl,(skilllv == 3) ? EQP_SHIELD : (skilllv == 4) ? EQP_ARMOR : EQP_WEAPON,rate * 100,BCT_ENEMY);
+ break;
+ }
+ break;
+ case LG_MOONSLASHER:
+ rate = 32 + 8 * skilllv;
+ if( rnd()%100 < rate && dstsd ) // Uses skill_addtimerskill to avoid damage and setsit packet overlaping. Officially clif_setsit is received about 500 ms after damage packet.
+ skill_addtimerskill(src,tick+500,bl->id,0,0,skillid,skilllv,BF_WEAPON,0);
+ else if( dstmd && !is_boss(bl) )
+ sc_start(bl,SC_STOP,100,skilllv,skill_get_time(skillid,skilllv));
+ break;
+ case LG_RAYOFGENESIS: // 50% chance to cause Blind on Undead and Demon monsters.
+ if ( battle_check_undead(tstatus->race, tstatus->def_ele) || tstatus->race == RC_DEMON )
+ sc_start(bl, SC_BLIND,50, skilllv, skill_get_time(skillid,skilllv));
+ break;
+ case LG_EARTHDRIVE:
+ skill_break_equip(src, EQP_SHIELD, 500, BCT_SELF);
+ sc_start(bl, SC_EARTHDRIVE, 100, skilllv, skill_get_time(skillid, skilllv));
+ break;
+ case SR_DRAGONCOMBO:
+ sc_start(bl, SC_STUN, 1 + skilllv, skilllv, skill_get_time(skillid, skilllv));
+ break;
+ case SR_FALLENEMPIRE:
+ sc_start(bl, SC_STOP, 100, skilllv, skill_get_time(skillid, skilllv));
+ break;
+ case SR_WINDMILL:
+ if( dstsd )
+ skill_addtimerskill(src,tick+status_get_amotion(src),bl->id,0,0,skillid,skilllv,BF_WEAPON,0);
+ else if( dstmd && !is_boss(bl) )
+ sc_start(bl, SC_STUN, 100, skilllv, 1000 + 1000 * (rnd() %3));
+ break;
+ case SR_GENTLETOUCH_QUIET: // [(Skill Level x 5) + (Caster?s DEX + Caster?s Base Level) / 10]
+ sc_start(bl, SC_SILENCE, 5 * skilllv + (sstatus->dex + status_get_lv(src)) / 10, skilllv, skill_get_time(skillid, skilllv));
+ break;
+ case SR_EARTHSHAKER:
+ sc_start(bl,SC_STUN, 25 + 5 * skilllv,skilllv,skill_get_time(skillid,skilllv));
+ break;
+ case SR_HOWLINGOFLION:
+ sc_start(bl, SC_FEAR, 5 + 5 * skilllv, skilllv, skill_get_time(skillid, skilllv));
+ break;
+ case WM_SOUND_OF_DESTRUCTION:
+ if( rnd()%100 < 5 + 5 * skilllv ) { // Temporarly Check Until We Get the Official Formula
+ status_change_end(bl, SC_DANCING, INVALID_TIMER);
+ status_change_end(bl, SC_RICHMANKIM, INVALID_TIMER);
+ status_change_end(bl, SC_ETERNALCHAOS, INVALID_TIMER);
+ status_change_end(bl, SC_DRUMBATTLE, INVALID_TIMER);
+ status_change_end(bl, SC_NIBELUNGEN, INVALID_TIMER);
+ status_change_end(bl, SC_INTOABYSS, INVALID_TIMER);
+ status_change_end(bl, SC_SIEGFRIED, INVALID_TIMER);
+ status_change_end(bl, SC_WHISTLE, INVALID_TIMER);
+ status_change_end(bl, SC_ASSNCROS, INVALID_TIMER);
+ status_change_end(bl, SC_POEMBRAGI, INVALID_TIMER);
+ status_change_end(bl, SC_APPLEIDUN, INVALID_TIMER);
+ status_change_end(bl, SC_HUMMING, INVALID_TIMER);
+ status_change_end(bl, SC_FORTUNE, INVALID_TIMER);
+ status_change_end(bl, SC_SERVICE4U, INVALID_TIMER);
+ status_change_end(bl, SC_LONGING, INVALID_TIMER);
+ status_change_end(bl, SC_SWINGDANCE, INVALID_TIMER);
+ status_change_end(bl, SC_SYMPHONYOFLOVER, INVALID_TIMER);
+ status_change_end(bl, SC_MOONLITSERENADE, INVALID_TIMER);
+ status_change_end(bl, SC_RUSHWINDMILL, INVALID_TIMER);
+ status_change_end(bl, SC_ECHOSONG, INVALID_TIMER);
+ status_change_end(bl, SC_HARMONIZE, INVALID_TIMER);
+ status_change_end(bl, SC_WINKCHARM, INVALID_TIMER);
+ status_change_end(bl, SC_SONGOFMANA, INVALID_TIMER);
+ status_change_end(bl, SC_DANCEWITHWUG, INVALID_TIMER);
+ status_change_end(bl, SC_LERADSDEW, INVALID_TIMER);
+ status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER);
+ status_change_end(bl, SC_BEYONDOFWARCRY, INVALID_TIMER);
+ status_change_end(bl, SC_UNLIMITEDHUMMINGVOICE, INVALID_TIMER);
+ }
+ break;
+ case SO_EARTHGRAVE:
+ sc_start(bl, SC_BLEEDING, 5 * skilllv, skilllv, skill_get_time2(skillid, skilllv)); // Need official rate. [LimitLine]
+ break;
+ case SO_DIAMONDDUST:
+ rate = 5 + 5 * skilllv;
+ if( sc && sc->data[SC_COOLER_OPTION] )
+ rate += rate * sc->data[SC_COOLER_OPTION]->val2 / 100;
+ sc_start(bl, SC_CRYSTALIZE, rate, skilllv, skill_get_time2(skillid, skilllv));
+ break;
+ case SO_VARETYR_SPEAR:
+ sc_start(bl, SC_STUN, 5 + 5 * skilllv, skilllv, skill_get_time2(skillid, skilllv));
+ break;
+ case GN_SLINGITEM_RANGEMELEEATK:
+ if( sd ) {
+ switch( sd->itemid ) { // Starting SCs here instead of do it in skill_additional_effect to simplify the code.
+ case 13261:
+ sc_start(bl, SC_STUN, 100, skilllv, skill_get_time2(GN_SLINGITEM, skilllv));
+ sc_start(bl, SC_BLEEDING, 100, skilllv, skill_get_time2(GN_SLINGITEM, skilllv));
+ break;
+ case 13262:
+ sc_start(bl, SC_MELON_BOMB, 100, skilllv, skill_get_time(GN_SLINGITEM, skilllv)); // Reduces ASPD and moviment speed
+ break;
+ case 13264:
+ sc_start(bl, SC_BANANA_BOMB, 100, skilllv, skill_get_time(GN_SLINGITEM, skilllv)); // Reduces LUK ??Needed confirm it, may be it's bugged in kRORE?
+ sc_start(bl, SC_BANANA_BOMB_SITDOWN, 75, skilllv, skill_get_time(GN_SLINGITEM_RANGEMELEEATK,skilllv)); // Sitdown for 3 seconds.
+ break;
+ }
+ sd->itemid = -1;
+ }
+ break;
+ case GN_HELLS_PLANT_ATK:
+ sc_start(bl, SC_STUN, 5 + 5 * skilllv, skilllv, skill_get_time2(skillid, skilllv));
+ sc_start(bl, SC_BLEEDING, 20 + 10 * skilllv, skilllv, skill_get_time2(skillid, skilllv));
+ break;
+ case EL_WIND_SLASH: // Non confirmed rate.
+ sc_start(bl, SC_BLEEDING, 25, skilllv, skill_get_time(skillid,skilllv));
+ break;
+ case EL_STONE_HAMMER:
+ rate = 10 * skilllv;
+ sc_start(bl, SC_STUN, rate, skilllv, skill_get_time(skillid,skilllv));
+ break;
+ case EL_ROCK_CRUSHER:
+ case EL_ROCK_CRUSHER_ATK:
+ sc_start(bl,status_skill2sc(skillid),50,skilllv,skill_get_time(EL_ROCK_CRUSHER,skilllv));
+ break;
+ case EL_TYPOON_MIS:
+ sc_start(bl,SC_SILENCE,10*skilllv,skilllv,skill_get_time(skillid,skilllv));
+ break;
+ case KO_JYUMONJIKIRI: // needs more info
+ sc_start(bl,SC_JYUMONJIKIRI,25,skilllv,skill_get_time(skillid,skilllv));
+ break;
+ case KO_MAKIBISHI:
+ sc_start(bl, SC_STUN, 100, skilllv, skill_get_time2(skillid,skilllv));
+ break;
+ case MH_LAVA_SLIDE:
+ if (tsc && !tsc->data[SC_BURNING]) sc_start4(bl, SC_BURNING, 10 * skilllv, skilllv, 1000, src->id, 0, skill_get_time(skillid, skilllv));
+ break;
+ case MH_STAHL_HORN:
+ sc_start(bl, SC_STUN, (20 + 4 * (skilllv-1)), skilllv, skill_get_time(skillid, skilllv));
+ break;
+ case MH_NEEDLE_OF_PARALYZE:
+ sc_start(bl, SC_PARALYSIS, 40 + (5*skilllv), skilllv, skill_get_time(skillid, skilllv));
+ break;
+ }
- case HT_FREEZINGTRAP:
- case MA_FREEZINGTRAP:
- sc_start(bl,SC_FREEZE,(3*skilllv+35),skilllv,skill_get_time2(skillid,skilllv));
- break;
+ if (md && battle_config.summons_trigger_autospells && md->master_id && md->special_state.ai)
+ { //Pass heritage to Master for status causing effects. [Skotlex]
+ sd = map_id2sd(md->master_id);
+ src = sd?&sd->bl:src;
+ }
- case HT_FLASHER:
- sc_start(bl,SC_BLIND,(10*skilllv+30),skilllv,skill_get_time2(skillid,skilllv));
- break;
+ if( attack_type&BF_WEAPON )
+ { // Coma, Breaking Equipment
+ if( sd && sd->special_state.bonus_coma )
+ {
+ rate = sd->weapon_coma_ele[tstatus->def_ele];
+ rate += sd->weapon_coma_race[tstatus->race];
+ rate += sd->weapon_coma_race[tstatus->mode&MD_BOSS?RC_BOSS:RC_NONBOSS];
+ if (rate)
+ status_change_start(bl, SC_COMA, rate, 0, 0, src->id, 0, 0, 0);
+ }
+ if( sd && battle_config.equip_self_break_rate )
+ { // Self weapon breaking
+ rate = battle_config.equip_natural_break_rate;
+ if( sc )
+ {
+ if(sc->data[SC_OVERTHRUST])
+ rate += 10;
+ if(sc->data[SC_MAXOVERTHRUST])
+ rate += 10;
+ }
+ if( rate )
+ skill_break_equip(src, EQP_WEAPON, rate, BCT_SELF);
+ }
+ if( battle_config.equip_skill_break_rate && skillid != WS_CARTTERMINATION && skillid != ITM_TOMAHAWK )
+ { // Cart Termination/Tomahawk won't trigger breaking data. Why? No idea, go ask Gravity.
+ // Target weapon breaking
+ rate = 0;
+ if( sd )
+ rate += sd->bonus.break_weapon_rate;
+ if( sc && sc->data[SC_MELTDOWN] )
+ rate += sc->data[SC_MELTDOWN]->val2;
+ if( rate )
+ skill_break_equip(bl, EQP_WEAPON, rate, BCT_ENEMY);
+
+ // Target armor breaking
+ rate = 0;
+ if( sd )
+ rate += sd->bonus.break_armor_rate;
+ if( sc && sc->data[SC_MELTDOWN] )
+ rate += sc->data[SC_MELTDOWN]->val3;
+ if( rate )
+ skill_break_equip(bl, EQP_ARMOR, rate, BCT_ENEMY);
+ }
+ }
- case HT_LANDMINE:
- case MA_LANDMINE:
- sc_start(bl,SC_STUN,(5*skilllv+30),skilllv,skill_get_time2(skillid,skilllv));
- break;
+ // Autospell when attacking
+ if( sd && !status_isdead(bl) && sd->autospell[0].id )
+ {
+ struct block_list *tbl;
+ struct unit_data *ud;
+ int i, skilllv, type, notok;
- case HT_SHOCKWAVE:
- status_percent_damage(src, bl, 0, 15*skilllv+5, false);
- break;
+ for (i = 0; i < ARRAYLENGTH(sd->autospell) && sd->autospell[i].id; i++) {
- case HT_SANDMAN:
- case MA_SANDMAN:
- sc_start(bl,SC_SLEEP,(10*skilllv+40),skilllv,skill_get_time2(skillid,skilllv));
- break;
+ if(!(sd->autospell[i].flag&attack_type&BF_WEAPONMASK &&
+ sd->autospell[i].flag&attack_type&BF_RANGEMASK &&
+ sd->autospell[i].flag&attack_type&BF_SKILLMASK))
+ continue; // one or more trigger conditions were not fulfilled
- case TF_SPRINKLESAND:
- sc_start(bl,SC_BLIND,20,skilllv,skill_get_time2(skillid,skilllv));
- break;
+ skill = (sd->autospell[i].id > 0) ? sd->autospell[i].id : -sd->autospell[i].id;
- case TF_THROWSTONE:
- sc_start(bl,SC_STUN,3,skilllv,skill_get_time(skillid,skilllv));
- sc_start(bl,SC_BLIND,3,skilllv,skill_get_time2(skillid,skilllv));
- break;
+ sd->state.autocast = 1;
+ notok = skillnotok(skill, sd);
+ sd->state.autocast = 0;
- case NPC_DARKCROSS:
- case CR_HOLYCROSS:
- sc_start(bl,SC_BLIND,3*skilllv,skilllv,skill_get_time2(skillid,skilllv));
- break;
+ if ( notok )
+ continue;
- case CR_GRANDCROSS:
- case NPC_GRANDDARKNESS:
- //Chance to cause blind status vs demon and undead element, but not against players
- if (!dstsd && (battle_check_undead(tstatus->race,tstatus->def_ele) || tstatus->race == RC_DEMON))
- sc_start(bl,SC_BLIND,100,skilllv,skill_get_time2(skillid,skilllv));
- attack_type |= BF_WEAPON;
- break;
+ skilllv = sd->autospell[i].lv?sd->autospell[i].lv:1;
+ if (skilllv < 0) skilllv = 1+rnd()%(-skilllv);
- case AM_ACIDTERROR:
- sc_start(bl,SC_BLEEDING,(skilllv*3),skilllv,skill_get_time2(skillid,skilllv));
- if (skill_break_equip(bl, EQP_ARMOR, 100*skill_get_time(skillid,skilllv), BCT_ENEMY))
- clif_emotion(bl,E_OMG);
- break;
+ rate = (!sd->state.arrow_atk) ? sd->autospell[i].rate : sd->autospell[i].rate / 2;
- case AM_DEMONSTRATION:
- skill_break_equip(bl, EQP_WEAPON, 100*skilllv, BCT_ENEMY);
- break;
+ if (rnd()%1000 >= rate)
+ continue;
- case CR_SHIELDCHARGE:
- sc_start(bl,SC_STUN,(15+skilllv*5),skilllv,skill_get_time2(skillid,skilllv));
- break;
+ tbl = (sd->autospell[i].id < 0) ? src : bl;
- case PA_PRESSURE:
- status_percent_damage(src, bl, 0, 15+5*skilllv, false);
- break;
+ if( (type = skill_get_casttype(skill)) == CAST_GROUND ) {
+ int maxcount = 0;
+ if( !(BL_PC&battle_config.skill_reiteration) &&
+ skill_get_unit_flag(skill)&UF_NOREITERATION &&
+ skill_check_unit_range(src,tbl->x,tbl->y,skill,skilllv)
+ ) {
+ continue;
+ }
+ if( BL_PC&battle_config.skill_nofootset &&
+ skill_get_unit_flag(skill)&UF_NOFOOTSET &&
+ skill_check_unit_range2(src,tbl->x,tbl->y,skill,skilllv)
+ ) {
+ continue;
+ }
+ if( BL_PC&battle_config.land_skill_limit &&
+ (maxcount = skill_get_maxcount(skill, skilllv)) > 0
+ ) {
+ int v;
+ for(v=0;v<MAX_SKILLUNITGROUP && sd->ud.skillunit[v] && maxcount;v++) {
+ if(sd->ud.skillunit[v]->skill_id == skill)
+ maxcount--;
+ }
+ if( maxcount == 0 ) {
+ continue;
+ }
+ }
+ }
+ if( battle_config.autospell_check_range &&
+ !battle_check_range(src, tbl, skill_get_range2(src, skill,skilllv) + (skill == RG_CLOSECONFINE?0:1)) )
+ continue;
+
+ if (skill == AS_SONICBLOW)
+ pc_stop_attack(sd); //Special case, Sonic Blow autospell should stop the player attacking.
+ if (skill == PF_SPIDERWEB) //Special case, due to its nature of coding.
+ type = CAST_GROUND;
+
+ sd->state.autocast = 1;
+ skill_consume_requirement(sd,skill,skilllv,1);
+ skill_toggle_magicpower(src, skill);
+ switch (type) {
+ case CAST_GROUND:
+ skill_castend_pos2(src, tbl->x, tbl->y, skill, skilllv, tick, 0);
+ break;
+ case CAST_NODAMAGE:
+ skill_castend_nodamage_id(src, tbl, skill, skilllv, tick, 0);
+ break;
+ case CAST_DAMAGE:
+ skill_castend_damage_id(src, tbl, skill, skilllv, tick, 0);
+ break;
+ }
+ sd->state.autocast = 0;
+ //Set canact delay. [Skotlex]
+ ud = unit_bl2ud(src);
+ if (ud) {
+ rate = skill_delayfix(src, skill, skilllv);
+ if (DIFF_TICK(ud->canact_tick, tick + rate) < 0){
+ ud->canact_tick = tick+rate;
+ if ( battle_config.display_status_timers && sd )
+ clif_status_change(src, SI_ACTIONDELAY, 1, rate, 0, 0, 0);
+ }
+ }
+ }
+ }
- case RG_RAID:
- sc_start(bl,SC_STUN,(10+3*skilllv),skilllv,skill_get_time(skillid,skilllv));
- sc_start(bl,SC_BLIND,(10+3*skilllv),skilllv,skill_get_time2(skillid,skilllv));
+ //Autobonus when attacking
+ if( sd && sd->autobonus[0].rate )
+ {
+ int i;
+ for( i = 0; i < ARRAYLENGTH(sd->autobonus); i++ )
+ {
+ if( rnd()%1000 >= sd->autobonus[i].rate )
+ continue;
+ if( sd->autobonus[i].active != INVALID_TIMER )
+ continue;
+ if(!(sd->autobonus[i].atk_type&attack_type&BF_WEAPONMASK &&
+ sd->autobonus[i].atk_type&attack_type&BF_RANGEMASK &&
+ sd->autobonus[i].atk_type&attack_type&BF_SKILLMASK))
+ continue; // one or more trigger conditions were not fulfilled
+ pc_exeautobonus(sd,&sd->autobonus[i]);
+ }
+ }
-#ifdef RENEWAL
- sc_start(bl,SC_RAID,100,7,5000);
- break;
+ //Polymorph
+ if(sd && sd->bonus.classchange && attack_type&BF_WEAPON &&
+ dstmd && !(tstatus->mode&MD_BOSS) &&
+ (rnd()%10000 < sd->bonus.classchange))
+ {
+ struct mob_db *mob;
+ int class_;
+ skill = 0;
+ do {
+ do {
+ class_ = rnd() % MAX_MOB_DB;
+ } while (!mobdb_checkid(class_));
+
+ rate = rnd() % 1000000;
+ mob = mob_db(class_);
+ } while (
+ (mob->status.mode&(MD_BOSS|MD_PLANT) || mob->summonper[0] <= rate) &&
+ (skill++) < 2000);
+ if (skill < 2000)
+ mob_class_change(dstmd,class_);
+ }
- case RG_BACKSTAP:
- sc_start(bl,SC_STUN,(5+2*skilllv),skilllv,skill_get_time(skillid,skilllv));
-#endif
- break;
+ return 0;
+}
- case BA_FROSTJOKER:
- sc_start(bl,SC_FREEZE,(15+5*skilllv),skilllv,skill_get_time2(skillid,skilllv));
- break;
+int skill_onskillusage(struct map_session_data *sd, struct block_list *bl, int skillid, unsigned int tick) {
+ int skill, skilllv, i, type, notok;
+ struct block_list *tbl;
- case DC_SCREAM:
- sc_start(bl,SC_STUN,(25+5*skilllv),skilllv,skill_get_time2(skillid,skilllv));
- break;
+ if( sd == NULL || skillid <= 0 )
+ return 0;
- case BD_LULLABY:
- sc_start(bl,SC_SLEEP,15,skilllv,skill_get_time2(skillid,skilllv));
- break;
+ for( i = 0; i < ARRAYLENGTH(sd->autospell3) && sd->autospell3[i].flag; i++ ) {
+ if( sd->autospell3[i].flag != skillid )
+ continue;
- case DC_UGLYDANCE:
- rate = 5+5*skilllv;
- if (sd && (skill=pc_checkskill(sd,DC_DANCINGLESSON)))
- rate += 5+skill;
- status_zap(bl, 0, rate);
- break;
- case SL_STUN:
- if (tstatus->size==SZ_MEDIUM) //Only stuns mid-sized mobs.
- sc_start(bl,SC_STUN,(30+10*skilllv),skilllv,skill_get_time(skillid,skilllv));
- break;
+ if( sd->autospell3[i].lock )
+ continue; // autospell already being executed
- case NPC_PETRIFYATTACK:
- sc_start4(bl,status_skill2sc(skillid),50+10*skilllv,
- skilllv,0,0,skill_get_time(skillid,skilllv),
- skill_get_time2(skillid,skilllv));
- break;
- case NPC_CURSEATTACK:
- case NPC_SLEEPATTACK:
- case NPC_BLINDATTACK:
- case NPC_POISON:
- case NPC_SILENCEATTACK:
- case NPC_STUNATTACK:
- case NPC_HELLPOWER:
- sc_start(bl,status_skill2sc(skillid),50+10*skilllv,skilllv,skill_get_time2(skillid,skilllv));
- break;
- case NPC_ACIDBREATH:
- case NPC_ICEBREATH:
- sc_start(bl,status_skill2sc(skillid),70,skilllv,skill_get_time2(skillid,skilllv));
- break;
- case NPC_BLEEDING:
- sc_start(bl,SC_BLEEDING,(20*skilllv),skilllv,skill_get_time2(skillid,skilllv));
- break;
- case NPC_MENTALBREAKER: {
- //Based on observations by Tharis, Mental Breaker should do SP damage
- //equal to Matk*skLevel.
- rate = sstatus->matk_min;
- if (rate < sstatus->matk_max)
- rate += rnd()%(sstatus->matk_max - sstatus->matk_min);
- rate*=skilllv;
- status_zap(bl, 0, rate);
- break;
- }
- // Equipment breaking monster skills [Celest]
- case NPC_WEAPONBRAKER:
- skill_break_equip(bl, EQP_WEAPON, 150*skilllv, BCT_ENEMY);
- break;
- case NPC_ARMORBRAKE:
- skill_break_equip(bl, EQP_ARMOR, 150*skilllv, BCT_ENEMY);
- break;
- case NPC_HELMBRAKE:
- skill_break_equip(bl, EQP_HELM, 150*skilllv, BCT_ENEMY);
- break;
- case NPC_SHIELDBRAKE:
- skill_break_equip(bl, EQP_SHIELD, 150*skilllv, BCT_ENEMY);
- break;
+ skill = (sd->autospell3[i].id > 0) ? sd->autospell3[i].id : -sd->autospell3[i].id;
- case CH_TIGERFIST:
- sc_start(bl,SC_STOP,(10+skilllv*10),0,skill_get_time2(skillid,skilllv));
- break;
+ sd->state.autocast = 1;
+ notok = skillnotok(skill, sd);
+ sd->state.autocast = 0;
- case LK_SPIRALPIERCE:
- case ML_SPIRALPIERCE:
- sc_start(bl,SC_STOP,(15+skilllv*5),0,skill_get_time2(skillid,skilllv));
- break;
+ if ( notok )
+ continue;
- case ST_REJECTSWORD:
- sc_start(bl,SC_AUTOCOUNTER,(skilllv*15),skilllv,skill_get_time(skillid,skilllv));
- break;
+ skilllv = sd->autospell3[i].lv ? sd->autospell3[i].lv : 1;
+ if( skilllv < 0 ) skilllv = 1 + rnd()%(-skilllv);
- case PF_FOGWALL:
- if (src != bl && !tsc->data[SC_DELUGE])
- status_change_start(bl,SC_BLIND,10000,skilllv,0,0,0,skill_get_time2(skillid,skilllv),8);
- break;
+ if( sd->autospell3[i].id >= 0 && bl == NULL )
+ continue; // No target
+ if( rnd()%1000 >= sd->autospell3[i].rate )
+ continue;
- case LK_HEADCRUSH: //Headcrush has chance of causing Bleeding status, except on demon and undead element
- if (!(battle_check_undead(tstatus->race, tstatus->def_ele) || tstatus->race == RC_DEMON))
- sc_start(bl, SC_BLEEDING,50, skilllv, skill_get_time2(skillid,skilllv));
- break;
+ tbl = (sd->autospell3[i].id < 0) ? &sd->bl : bl;
- case LK_JOINTBEAT:
- status = status_skill2sc(skillid);
- if (tsc->jb_flag) {
- sc_start2(bl,status,(5*skilllv+5),skilllv,tsc->jb_flag&BREAK_FLAGS,skill_get_time2(skillid,skilllv));
- tsc->jb_flag = 0;
- }
- break;
- case ASC_METEORASSAULT:
- //Any enemies hit by this skill will receive Stun, Darkness, or external bleeding status ailment with a 5%+5*SkillLV% chance.
- switch (rnd()%3) {
- case 0:
- sc_start(bl,SC_BLIND,(5+skilllv*5),skilllv,skill_get_time2(skillid,1));
- break;
- case 1:
- sc_start(bl,SC_STUN,(5+skilllv*5),skilllv,skill_get_time2(skillid,2));
- break;
- default:
- sc_start(bl,SC_BLEEDING,(5+skilllv*5),skilllv,skill_get_time2(skillid,3));
- }
- break;
+ if( (type = skill_get_casttype(skill)) == CAST_GROUND ) {
+ int maxcount = 0;
+ if( !(BL_PC&battle_config.skill_reiteration) &&
+ skill_get_unit_flag(skill)&UF_NOREITERATION &&
+ skill_check_unit_range(&sd->bl,tbl->x,tbl->y,skill,skilllv)
+ ) {
+ continue;
+ }
+ if( BL_PC&battle_config.skill_nofootset &&
+ skill_get_unit_flag(skill)&UF_NOFOOTSET &&
+ skill_check_unit_range2(&sd->bl,tbl->x,tbl->y,skill,skilllv)
+ ) {
+ continue;
+ }
+ if( BL_PC&battle_config.land_skill_limit &&
+ (maxcount = skill_get_maxcount(skill, skilllv)) > 0
+ ) {
+ int v;
+ for(v=0;v<MAX_SKILLUNITGROUP && sd->ud.skillunit[v] && maxcount;v++) {
+ if(sd->ud.skillunit[v]->skill_id == skill)
+ maxcount--;
+ }
+ if( maxcount == 0 ) {
+ continue;
+ }
+ }
+ }
+ if( battle_config.autospell_check_range &&
+ !battle_check_range(&sd->bl, tbl, skill_get_range2(&sd->bl, skill,skilllv) + (skill == RG_CLOSECONFINE?0:1)) )
+ continue;
+
+ sd->state.autocast = 1;
+ sd->autospell3[i].lock = true;
+ skill_consume_requirement(sd,skill,skilllv,1);
+ switch( type )
+ {
+ case CAST_GROUND: skill_castend_pos2(&sd->bl, tbl->x, tbl->y, skill, skilllv, tick, 0); break;
+ case CAST_NODAMAGE: skill_castend_nodamage_id(&sd->bl, tbl, skill, skilllv, tick, 0); break;
+ case CAST_DAMAGE: skill_castend_damage_id(&sd->bl, tbl, skill, skilllv, tick, 0); break;
+ }
+ sd->autospell3[i].lock = false;
+ sd->state.autocast = 0;
+ }
- case HW_NAPALMVULCAN:
- sc_start(bl,SC_CURSE,5*skilllv,skilllv,skill_get_time2(skillid,skilllv));
- break;
+ if( sd && sd->autobonus3[0].rate )
+ {
+ for( i = 0; i < ARRAYLENGTH(sd->autobonus3); i++ )
+ {
+ if( rnd()%1000 >= sd->autobonus3[i].rate )
+ continue;
+ if( sd->autobonus3[i].active != INVALID_TIMER )
+ continue;
+ if( sd->autobonus3[i].atk_type != skillid )
+ continue;
+ pc_exeautobonus(sd,&sd->autobonus3[i]);
+ }
+ }
- case WS_CARTTERMINATION: // Cart termination
- sc_start(bl,SC_STUN,5*skilllv,skilllv,skill_get_time2(skillid,skilllv));
- break;
+ return 1;
+}
- case CR_ACIDDEMONSTRATION:
- skill_break_equip(bl, EQP_WEAPON|EQP_ARMOR, 100*skilllv, BCT_ENEMY);
- break;
+/* Splitted off from skill_additional_effect, which is never called when the
+ * attack skill kills the enemy. Place in this function counter status effects
+ * when using skills (eg: Asura's sp regen penalty, or counter-status effects
+ * from cards) that will take effect on the source, not the target. [Skotlex]
+ * Note: Currently this function only applies to Extremity Fist and BF_WEAPON
+ * type of skills, so not every instance of skill_additional_effect needs a call
+ * to this one.
+ */
+int skill_counter_additional_effect (struct block_list* src, struct block_list *bl, int skillid, int skilllv, int attack_type, unsigned int tick)
+{
+ int rate;
+ struct map_session_data *sd=NULL;
+ struct map_session_data *dstsd=NULL;
+
+ nullpo_ret(src);
+ nullpo_ret(bl);
+
+ if(skillid < 0) return 0;
+ if(skillid > 0 && skilllv <= 0) return 0; // don't forget auto attacks! - celest
+
+ sd = BL_CAST(BL_PC, src);
+ dstsd = BL_CAST(BL_PC, bl);
+
+ if(dstsd && attack_type&BF_WEAPON)
+ { //Counter effects.
+ enum sc_type type;
+ int i, time;
+ for(i=0; i < ARRAYLENGTH(dstsd->addeff2) && dstsd->addeff2[i].flag; i++)
+ {
+ rate = dstsd->addeff2[i].rate;
+ if (attack_type&BF_LONG)
+ rate+=dstsd->addeff2[i].arrow_rate;
+ if (!rate) continue;
+
+ if ((dstsd->addeff2[i].flag&(ATF_LONG|ATF_SHORT)) != (ATF_LONG|ATF_SHORT))
+ { //Trigger has range consideration.
+ if((dstsd->addeff2[i].flag&ATF_LONG && !(attack_type&BF_LONG)) ||
+ (dstsd->addeff2[i].flag&ATF_SHORT && !(attack_type&BF_SHORT)))
+ continue; //Range Failed.
+ }
+ type = dstsd->addeff2[i].id;
+ time = skill_get_time2(status_sc2skill(type),7);
- case TK_DOWNKICK:
- sc_start(bl,SC_STUN,100,skilllv,skill_get_time2(skillid,skilllv));
- break;
+ if (dstsd->addeff2[i].flag&ATF_TARGET)
+ status_change_start(src,type,rate,7,0,0,0,time,0);
- case TK_JUMPKICK:
- if (dstsd && dstsd->class_ != MAPID_SOUL_LINKER && !tsc->data[SC_PRESERVE]) {
- // debuff the following statuses
- status_change_end(bl, SC_SPIRIT, INVALID_TIMER);
- status_change_end(bl, SC_ADRENALINE2, INVALID_TIMER);
- status_change_end(bl, SC_KAITE, INVALID_TIMER);
- status_change_end(bl, SC_KAAHI, INVALID_TIMER);
- status_change_end(bl, SC_ONEHAND, INVALID_TIMER);
- status_change_end(bl, SC_ASPDPOTION2, INVALID_TIMER);
- }
- break;
- case TK_TURNKICK:
- case MO_BALKYOUNG: //Note: attack_type is passed as BF_WEAPON for the actual target, BF_MISC for the splash-affected mobs.
- if (attack_type&BF_MISC) //70% base stun chance...
- sc_start(bl,SC_STUN,70,skilllv,skill_get_time2(skillid,skilllv));
- break;
- case GS_BULLSEYE: //0.1% coma rate.
- if (tstatus->race == RC_BRUTE || tstatus->race == RC_DEMIHUMAN)
- status_change_start(bl,SC_COMA,10,skilllv,0,src->id,0,0,0);
- break;
- case GS_PIERCINGSHOT:
- sc_start(bl,SC_BLEEDING,(skilllv*3),skilllv,skill_get_time2(skillid,skilllv));
- break;
- case NJ_HYOUSYOURAKU:
- sc_start(bl,SC_FREEZE,(10+10*skilllv),skilllv,skill_get_time2(skillid,skilllv));
- break;
- case GS_FLING:
- sc_start(bl,SC_FLING,100, sd?sd->spiritball_old:5,skill_get_time(skillid,skilllv));
- break;
- case GS_DISARM:
- rate = 3*skilllv;
- if (sstatus->dex > tstatus->dex)
- rate += (sstatus->dex - tstatus->dex)/5; //TODO: Made up formula
- skill_strip_equip(bl, EQP_WEAPON, rate, skilllv, skill_get_time(skillid,skilllv));
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- break;
- case NPC_EVILLAND:
- sc_start(bl,SC_BLIND,5*skilllv,skilllv,skill_get_time2(skillid,skilllv));
- break;
- case NPC_HELLJUDGEMENT:
- sc_start(bl,SC_CURSE,100,skilllv,skill_get_time2(skillid,skilllv));
- break;
- case NPC_CRITICALWOUND:
- sc_start(bl,SC_CRITICALWOUND,100,skilllv,skill_get_time2(skillid,skilllv));
- break;
- case RK_HUNDREDSPEAR:
- if (!sd || pc_checkskill(sd,KN_SPEARBOOMERANG) == 0)
- break; // Spear Boomerang auto cast chance only works if you have mastered Spear Boomerang.
- rate = 10 + 3 * skilllv;
- if (rnd()%100 < rate)
- skill_castend_damage_id(src,bl,KN_SPEARBOOMERANG,1,tick,0);
- break;
- case RK_WINDCUTTER:
- sc_start(bl,SC_FEAR,3+2*skilllv,skilllv,skill_get_time(skillid,skilllv));
- break;
- case RK_DRAGONBREATH:
- sc_start4(bl,SC_BURNING,5+5*skilllv,skilllv,1000,src->id,0,skill_get_time(skillid,skilllv));
- break;
- case AB_ADORAMUS:
- if (tsc && !tsc->data[SC_DECREASEAGI]) //Prevent duplicate agi-down effect.
- sc_start(bl, SC_ADORAMUS, 100, skilllv, skill_get_time(skillid, skilllv));
- break;
- case WL_CRIMSONROCK:
- sc_start(bl, SC_STUN, 40, skilllv, skill_get_time(skillid, skilllv));
- break;
- case WL_COMET:
- sc_start4(bl,SC_BURNING,100,skilllv,1000,src->id,0,skill_get_time(skillid,skilllv));
- break;
- case WL_EARTHSTRAIN: {
- int rate = 0, i;
- const int pos[5] = { EQP_WEAPON, EQP_HELM, EQP_SHIELD, EQP_ARMOR, EQP_ACC };
- rate = 6 * skilllv + sstatus->dex / 10 + (sd? sd->status.job_level / 4 : 0) - tstatus->dex /5;// The tstatus->dex / 5 part is unofficial, but players gotta have some kind of way to have resistance. [Rytech]
- //rate -= rate * tstatus->dex / 200; // Disabled until official resistance is found.
-
- for (i = 0; i < skilllv; i++)
- skill_strip_equip(bl,pos[i],rate,skilllv,skill_get_time2(skillid,skilllv));
- }
- break;
- case WL_JACKFROST:
- sc_start(bl,SC_FREEZE,100,skilllv,skill_get_time(skillid,skilllv));
- break;
- case RA_WUGBITE:
- sc_start(bl, SC_BITE, (sd ? pc_checkskill(sd,RA_TOOTHOFWUG)*2 : 0), skilllv, (skill_get_time(skillid,skilllv) + (sd ? pc_checkskill(sd,RA_TOOTHOFWUG)*500 : 0)));
- break;
- case RA_SENSITIVEKEEN:
- if (rnd()%100 < 8 * skilllv)
- skill_castend_damage_id(src, bl, RA_WUGBITE, sd ? pc_checkskill(sd, RA_WUGBITE):skilllv, tick, SD_ANIMATION);
- break;
- case RA_FIRINGTRAP:
- case RA_ICEBOUNDTRAP:
- sc_start(bl, (skillid == RA_FIRINGTRAP) ? SC_BURNING:SC_FREEZING, 40 + 10 * skilllv, skilllv, skill_get_time2(skillid, skilllv));
- break;
- case NC_PILEBUNKER:
- if (rnd()%100 < 5 + 15*skilllv) {
- //Deactivatable Statuses: Kyrie Eleison, Auto Guard, Steel Body, Assumptio, and Millennium Shield
- status_change_end(bl, SC_KYRIE, INVALID_TIMER);
- status_change_end(bl, SC_AUTOGUARD, INVALID_TIMER);
- status_change_end(bl, SC_STEELBODY, INVALID_TIMER);
- status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
- status_change_end(bl, SC_MILLENNIUMSHIELD, INVALID_TIMER);
- }
- break;
- case NC_FLAMELAUNCHER:
- sc_start4(bl, SC_BURNING, 50 + 10 * skilllv, skilllv, 1000, src->id, 0, skill_get_time2(skillid, skilllv));
- break;
- case NC_COLDSLOWER:
- sc_start(bl, SC_FREEZE, 10 * skilllv, skilllv, skill_get_time(skillid, skilllv));
- sc_start(bl, SC_FREEZING, 20 + 10 * skilllv, skilllv, skill_get_time(skillid, skilllv));
- break;
- case NC_POWERSWING:
- sc_start(bl, SC_STUN, 5*skilllv, skilllv, skill_get_time(skillid, skilllv));
- if (rnd()%100 < 5*skilllv)
- skill_castend_damage_id(src, bl, NC_AXEBOOMERANG, pc_checkskill(sd, NC_AXEBOOMERANG), tick, 1);
- break;
- case GC_WEAPONCRUSH:
- skill_castend_nodamage_id(src,bl,skillid,skilllv,tick,BCT_ENEMY);
- break;
- case LG_SHIELDPRESS:
- sc_start(bl, SC_STUN, 30 + 8 * skilllv, skilllv, skill_get_time(skillid,skilllv));
- break;
- case LG_PINPOINTATTACK:
- rate = 30 + (((5 * (sd?pc_checkskill(sd,LG_PINPOINTATTACK):skilllv)) + (sstatus->agi + status_get_lv(src))) / 10);
- switch (skilllv) {
- case 1:
- sc_start(bl,SC_BLEEDING,rate,skilllv,skill_get_time(skillid,skilllv));
- break;
- case 2:
- if (dstsd && dstsd->spiritball && rnd()%100 < rate)
- pc_delspiritball(dstsd, dstsd->spiritball, 0);
- break;
- default:
- skill_break_equip(bl,(skilllv == 3) ? EQP_SHIELD : (skilllv == 4) ? EQP_ARMOR : EQP_WEAPON,rate * 100,BCT_ENEMY);
- break;
- }
- break;
- case LG_MOONSLASHER:
- rate = 32 + 8 * skilllv;
- if (rnd()%100 < rate && dstsd) // Uses skill_addtimerskill to avoid damage and setsit packet overlaping. Officially clif_setsit is received about 500 ms after damage packet.
- skill_addtimerskill(src,tick+500,bl->id,0,0,skillid,skilllv,BF_WEAPON,0);
- else if (dstmd && !is_boss(bl))
- sc_start(bl,SC_STOP,100,skilllv,skill_get_time(skillid,skilllv));
- break;
- case LG_RAYOFGENESIS: // 50% chance to cause Blind on Undead and Demon monsters.
- if (battle_check_undead(tstatus->race, tstatus->def_ele) || tstatus->race == RC_DEMON)
- sc_start(bl, SC_BLIND,50, skilllv, skill_get_time(skillid,skilllv));
- break;
- case LG_EARTHDRIVE:
- skill_break_equip(src, EQP_SHIELD, 500, BCT_SELF);
- sc_start(bl, SC_EARTHDRIVE, 100, skilllv, skill_get_time(skillid, skilllv));
- break;
- case SR_DRAGONCOMBO:
- sc_start(bl, SC_STUN, 1 + skilllv, skilllv, skill_get_time(skillid, skilllv));
- break;
- case SR_FALLENEMPIRE:
- sc_start(bl, SC_STOP, 100, skilllv, skill_get_time(skillid, skilllv));
- break;
- case SR_WINDMILL:
- if (dstsd)
- skill_addtimerskill(src,tick+status_get_amotion(src),bl->id,0,0,skillid,skilllv,BF_WEAPON,0);
- else if (dstmd && !is_boss(bl))
- sc_start(bl, SC_STUN, 100, skilllv, 1000 + 1000 * (rnd() %3));
- break;
- case SR_GENTLETOUCH_QUIET: // [(Skill Level x 5) + (Caster?s DEX + Caster?s Base Level) / 10]
- sc_start(bl, SC_SILENCE, 5 * skilllv + (sstatus->dex + status_get_lv(src)) / 10, skilllv, skill_get_time(skillid, skilllv));
- break;
- case SR_EARTHSHAKER:
- sc_start(bl,SC_STUN, 25 + 5 * skilllv,skilllv,skill_get_time(skillid,skilllv));
- break;
- case SR_HOWLINGOFLION:
- sc_start(bl, SC_FEAR, 5 + 5 * skilllv, skilllv, skill_get_time(skillid, skilllv));
- break;
- case WM_SOUND_OF_DESTRUCTION:
- if (rnd()%100 < 5 + 5 * skilllv) { // Temporarly Check Until We Get the Official Formula
- status_change_end(bl, SC_DANCING, INVALID_TIMER);
- status_change_end(bl, SC_RICHMANKIM, INVALID_TIMER);
- status_change_end(bl, SC_ETERNALCHAOS, INVALID_TIMER);
- status_change_end(bl, SC_DRUMBATTLE, INVALID_TIMER);
- status_change_end(bl, SC_NIBELUNGEN, INVALID_TIMER);
- status_change_end(bl, SC_INTOABYSS, INVALID_TIMER);
- status_change_end(bl, SC_SIEGFRIED, INVALID_TIMER);
- status_change_end(bl, SC_WHISTLE, INVALID_TIMER);
- status_change_end(bl, SC_ASSNCROS, INVALID_TIMER);
- status_change_end(bl, SC_POEMBRAGI, INVALID_TIMER);
- status_change_end(bl, SC_APPLEIDUN, INVALID_TIMER);
- status_change_end(bl, SC_HUMMING, INVALID_TIMER);
- status_change_end(bl, SC_FORTUNE, INVALID_TIMER);
- status_change_end(bl, SC_SERVICE4U, INVALID_TIMER);
- status_change_end(bl, SC_LONGING, INVALID_TIMER);
- status_change_end(bl, SC_SWINGDANCE, INVALID_TIMER);
- status_change_end(bl, SC_SYMPHONYOFLOVER, INVALID_TIMER);
- status_change_end(bl, SC_MOONLITSERENADE, INVALID_TIMER);
- status_change_end(bl, SC_RUSHWINDMILL, INVALID_TIMER);
- status_change_end(bl, SC_ECHOSONG, INVALID_TIMER);
- status_change_end(bl, SC_HARMONIZE, INVALID_TIMER);
- status_change_end(bl, SC_WINKCHARM, INVALID_TIMER);
- status_change_end(bl, SC_SONGOFMANA, INVALID_TIMER);
- status_change_end(bl, SC_DANCEWITHWUG, INVALID_TIMER);
- status_change_end(bl, SC_LERADSDEW, INVALID_TIMER);
- status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER);
- status_change_end(bl, SC_BEYONDOFWARCRY, INVALID_TIMER);
- status_change_end(bl, SC_UNLIMITEDHUMMINGVOICE, INVALID_TIMER);
- }
- break;
- case SO_EARTHGRAVE:
- sc_start(bl, SC_BLEEDING, 5 * skilllv, skilllv, skill_get_time2(skillid, skilllv)); // Need official rate. [LimitLine]
- break;
- case SO_DIAMONDDUST:
- rate = 5 + 5 * skilllv;
- if (sc && sc->data[SC_COOLER_OPTION])
- rate += rate * sc->data[SC_COOLER_OPTION]->val2 / 100;
- sc_start(bl, SC_CRYSTALIZE, rate, skilllv, skill_get_time2(skillid, skilllv));
- break;
- case SO_VARETYR_SPEAR:
- sc_start(bl, SC_STUN, 5 + 5 * skilllv, skilllv, skill_get_time2(skillid, skilllv));
- break;
- case GN_SLINGITEM_RANGEMELEEATK:
- if (sd) {
- switch (sd->itemid) { // Starting SCs here instead of do it in skill_additional_effect to simplify the code.
- case 13261:
- sc_start(bl, SC_STUN, 100, skilllv, skill_get_time2(GN_SLINGITEM, skilllv));
- sc_start(bl, SC_BLEEDING, 100, skilllv, skill_get_time2(GN_SLINGITEM, skilllv));
- break;
- case 13262:
- sc_start(bl, SC_MELON_BOMB, 100, skilllv, skill_get_time(GN_SLINGITEM, skilllv)); // Reduces ASPD and moviment speed
- break;
- case 13264:
- sc_start(bl, SC_BANANA_BOMB, 100, skilllv, skill_get_time(GN_SLINGITEM, skilllv)); // Reduces LUK ??Needed confirm it, may be it's bugged in kRORE?
- sc_start(bl, SC_BANANA_BOMB_SITDOWN, 75, skilllv, skill_get_time(GN_SLINGITEM_RANGEMELEEATK,skilllv)); // Sitdown for 3 seconds.
- break;
- }
- sd->itemid = -1;
- }
- break;
- case GN_HELLS_PLANT_ATK:
- sc_start(bl, SC_STUN, 5 + 5 * skilllv, skilllv, skill_get_time2(skillid, skilllv));
- sc_start(bl, SC_BLEEDING, 20 + 10 * skilllv, skilllv, skill_get_time2(skillid, skilllv));
- break;
- case EL_WIND_SLASH: // Non confirmed rate.
- sc_start(bl, SC_BLEEDING, 25, skilllv, skill_get_time(skillid,skilllv));
- break;
- case EL_STONE_HAMMER:
- rate = 10 * skilllv;
- sc_start(bl, SC_STUN, rate, skilllv, skill_get_time(skillid,skilllv));
- break;
- case EL_ROCK_CRUSHER:
- case EL_ROCK_CRUSHER_ATK:
- sc_start(bl,status_skill2sc(skillid),50,skilllv,skill_get_time(EL_ROCK_CRUSHER,skilllv));
- break;
- case EL_TYPOON_MIS:
- sc_start(bl,SC_SILENCE,10*skilllv,skilllv,skill_get_time(skillid,skilllv));
- break;
- case KO_JYUMONJIKIRI: // needs more info
- sc_start(bl,SC_JYUMONJIKIRI,25,skilllv,skill_get_time(skillid,skilllv));
- break;
- case KO_MAKIBISHI:
- sc_start(bl, SC_STUN, 100, skilllv, skill_get_time2(skillid,skilllv));
- break;
- case MH_LAVA_SLIDE:
- if (tsc && !tsc->data[SC_BURNING]) sc_start4(bl, SC_BURNING, 10 * skilllv, skilllv, 1000, src->id, 0, skill_get_time(skillid, skilllv));
- break;
- case MH_STAHL_HORN:
- sc_start(bl, SC_STUN, (20 + 4 * (skilllv-1)), skilllv, skill_get_time(skillid, skilllv));
- break;
- case MH_NEEDLE_OF_PARALYZE:
- sc_start(bl, SC_PARALYSIS, 40 + (5*skilllv), skilllv, skill_get_time(skillid, skilllv));
- break;
- }
-
- if (md && battle_config.summons_trigger_autospells && md->master_id && md->special_state.ai) {
- //Pass heritage to Master for status causing effects. [Skotlex]
- sd = map_id2sd(md->master_id);
- src = sd?&sd->bl:src;
- }
-
- if (attack_type&BF_WEAPON) {
- // Coma, Breaking Equipment
- if (sd && sd->special_state.bonus_coma) {
- rate = sd->weapon_coma_ele[tstatus->def_ele];
- rate += sd->weapon_coma_race[tstatus->race];
- rate += sd->weapon_coma_race[tstatus->mode&MD_BOSS?RC_BOSS:RC_NONBOSS];
- if (rate)
- status_change_start(bl, SC_COMA, rate, 0, 0, src->id, 0, 0, 0);
- }
- if (sd && battle_config.equip_self_break_rate) {
- // Self weapon breaking
- rate = battle_config.equip_natural_break_rate;
- if (sc) {
- if (sc->data[SC_OVERTHRUST])
- rate += 10;
- if (sc->data[SC_MAXOVERTHRUST])
- rate += 10;
- }
- if (rate)
- skill_break_equip(src, EQP_WEAPON, rate, BCT_SELF);
- }
- if (battle_config.equip_skill_break_rate && skillid != WS_CARTTERMINATION && skillid != ITM_TOMAHAWK) {
- // Cart Termination/Tomahawk won't trigger breaking data. Why? No idea, go ask Gravity.
- // Target weapon breaking
- rate = 0;
- if (sd)
- rate += sd->bonus.break_weapon_rate;
- if (sc && sc->data[SC_MELTDOWN])
- rate += sc->data[SC_MELTDOWN]->val2;
- if (rate)
- skill_break_equip(bl, EQP_WEAPON, rate, BCT_ENEMY);
-
- // Target armor breaking
- rate = 0;
- if (sd)
- rate += sd->bonus.break_armor_rate;
- if (sc && sc->data[SC_MELTDOWN])
- rate += sc->data[SC_MELTDOWN]->val3;
- if (rate)
- skill_break_equip(bl, EQP_ARMOR, rate, BCT_ENEMY);
- }
- }
-
- // Autospell when attacking
- if (sd && !status_isdead(bl) && sd->autospell[0].id) {
- struct block_list *tbl;
- struct unit_data *ud;
- int i, skilllv, type, notok;
-
- for (i = 0; i < ARRAYLENGTH(sd->autospell) && sd->autospell[i].id; i++) {
-
- if (!(sd->autospell[i].flag&attack_type&BF_WEAPONMASK &&
- sd->autospell[i].flag&attack_type&BF_RANGEMASK &&
- sd->autospell[i].flag&attack_type&BF_SKILLMASK))
- continue; // one or more trigger conditions were not fulfilled
-
- skill = (sd->autospell[i].id > 0) ? sd->autospell[i].id : -sd->autospell[i].id;
-
- sd->state.autocast = 1;
- notok = skillnotok(skill, sd);
- sd->state.autocast = 0;
-
- if (notok)
- continue;
-
- skilllv = sd->autospell[i].lv?sd->autospell[i].lv:1;
- if (skilllv < 0) skilllv = 1+rnd()%(-skilllv);
-
- rate = (!sd->state.arrow_atk) ? sd->autospell[i].rate : sd->autospell[i].rate / 2;
-
- if (rnd()%1000 >= rate)
- continue;
-
- tbl = (sd->autospell[i].id < 0) ? src : bl;
-
- if ((type = skill_get_casttype(skill)) == CAST_GROUND) {
- int maxcount = 0;
- if (!(BL_PC&battle_config.skill_reiteration) &&
- skill_get_unit_flag(skill)&UF_NOREITERATION &&
- skill_check_unit_range(src,tbl->x,tbl->y,skill,skilllv)
- ) {
- continue;
- }
- if (BL_PC&battle_config.skill_nofootset &&
- skill_get_unit_flag(skill)&UF_NOFOOTSET &&
- skill_check_unit_range2(src,tbl->x,tbl->y,skill,skilllv)
- ) {
- continue;
- }
- if (BL_PC&battle_config.land_skill_limit &&
- (maxcount = skill_get_maxcount(skill, skilllv)) > 0
- ) {
- int v;
- for (v=0; v<MAX_SKILLUNITGROUP && sd->ud.skillunit[v] && maxcount; v++) {
- if (sd->ud.skillunit[v]->skill_id == skill)
- maxcount--;
- }
- if (maxcount == 0) {
- continue;
- }
- }
- }
- if (battle_config.autospell_check_range &&
- !battle_check_range(src, tbl, skill_get_range2(src, skill,skilllv) + (skill == RG_CLOSECONFINE?0:1)))
- continue;
-
- if (skill == AS_SONICBLOW)
- pc_stop_attack(sd); //Special case, Sonic Blow autospell should stop the player attacking.
- if (skill == PF_SPIDERWEB) //Special case, due to its nature of coding.
- type = CAST_GROUND;
-
- sd->state.autocast = 1;
- skill_consume_requirement(sd,skill,skilllv,1);
- skill_toggle_magicpower(src, skill);
- switch (type) {
- case CAST_GROUND:
- skill_castend_pos2(src, tbl->x, tbl->y, skill, skilllv, tick, 0);
- break;
- case CAST_NODAMAGE:
- skill_castend_nodamage_id(src, tbl, skill, skilllv, tick, 0);
- break;
- case CAST_DAMAGE:
- skill_castend_damage_id(src, tbl, skill, skilllv, tick, 0);
- break;
- }
- sd->state.autocast = 0;
- //Set canact delay. [Skotlex]
- ud = unit_bl2ud(src);
- if (ud) {
- rate = skill_delayfix(src, skill, skilllv);
- if (DIFF_TICK(ud->canact_tick, tick + rate) < 0) {
- ud->canact_tick = tick+rate;
- if (battle_config.display_status_timers && sd)
- clif_status_change(src, SI_ACTIONDELAY, 1, rate, 0, 0, 0);
- }
- }
- }
- }
-
- //Autobonus when attacking
- if (sd && sd->autobonus[0].rate) {
- int i;
- for (i = 0; i < ARRAYLENGTH(sd->autobonus); i++) {
- if (rnd()%1000 >= sd->autobonus[i].rate)
- continue;
- if (sd->autobonus[i].active != INVALID_TIMER)
- continue;
- if (!(sd->autobonus[i].atk_type&attack_type&BF_WEAPONMASK &&
- sd->autobonus[i].atk_type&attack_type&BF_RANGEMASK &&
- sd->autobonus[i].atk_type&attack_type&BF_SKILLMASK))
- continue; // one or more trigger conditions were not fulfilled
- pc_exeautobonus(sd,&sd->autobonus[i]);
- }
- }
-
- //Polymorph
- if (sd && sd->bonus.classchange && attack_type&BF_WEAPON &&
- dstmd && !(tstatus->mode&MD_BOSS) &&
- (rnd()%10000 < sd->bonus.classchange)) {
- struct mob_db *mob;
- int class_;
- skill = 0;
- do {
- do {
- class_ = rnd() % MAX_MOB_DB;
- } while (!mobdb_checkid(class_));
-
- rate = rnd() % 1000000;
- mob = mob_db(class_);
- } while (
- (mob->status.mode&(MD_BOSS|MD_PLANT) || mob->summonper[0] <= rate) &&
- (skill++) < 2000);
- if (skill < 2000)
- mob_class_change(dstmd,class_);
- }
-
- return 0;
-}
+ if (dstsd->addeff2[i].flag&ATF_SELF && !status_isdead(bl))
+ status_change_start(bl,type,rate,7,0,0,0,time,0);
+ }
+ }
-int skill_onskillusage(struct map_session_data *sd, struct block_list *bl, int skillid, unsigned int tick)
-{
- int skill, skilllv, i, type, notok;
- struct block_list *tbl;
+ switch(skillid){
+ case MO_EXTREMITYFIST:
+ sc_start(src,SC_EXTREMITYFIST,100,skilllv,skill_get_time2(skillid,skilllv));
+ break;
+ case GS_FULLBUSTER:
+ sc_start(src,SC_BLIND,2*skilllv,skilllv,skill_get_time2(skillid,skilllv));
+ break;
+ case HFLI_SBR44: //[orn]
+ case HVAN_EXPLOSION:
+ if(src->type == BL_HOM){
+ TBL_HOM *hd = (TBL_HOM*)src;
+ hd->homunculus.intimacy = 200;
+ if (hd->master)
+ clif_send_homdata(hd->master,SP_INTIMATE,hd->homunculus.intimacy/100);
+ }
+ break;
+ case CR_GRANDCROSS:
+ case NPC_GRANDDARKNESS:
+ attack_type |= BF_WEAPON;
+ break;
+ }
- if (sd == NULL || skillid <= 0)
- return 0;
+ if(sd && (sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR &&
+ rnd()%10000 < battle_config.sg_miracle_skill_ratio) //SG_MIRACLE [Komurka]
+ sc_start(src,SC_MIRACLE,100,1,battle_config.sg_miracle_skill_duration);
+
+ if(sd && skillid && attack_type&BF_MAGIC && status_isdead(bl) &&
+ !(skill_get_inf(skillid)&(INF_GROUND_SKILL|INF_SELF_SKILL)) &&
+ (rate=pc_checkskill(sd,HW_SOULDRAIN))>0
+ ){ //Soul Drain should only work on targetted spells [Skotlex]
+ if (pc_issit(sd)) pc_setstand(sd); //Character stuck in attacking animation while 'sitting' fix. [Skotlex]
+ clif_skill_nodamage(src,bl,HW_SOULDRAIN,rate,1);
+ status_heal(src, 0, status_get_lv(bl)*(95+15*rate)/100, 2);
+ }
- for (i = 0; i < ARRAYLENGTH(sd->autospell3) && sd->autospell3[i].flag; i++) {
- if (sd->autospell3[i].flag != skillid)
- continue;
+ if( sd && status_isdead(bl) ) {
+ int sp = 0, hp = 0;
+ if( attack_type&BF_WEAPON ) {
+ sp += sd->bonus.sp_gain_value;
+ sp += sd->sp_gain_race[status_get_race(bl)];
+ sp += sd->sp_gain_race[is_boss(bl)?RC_BOSS:RC_NONBOSS];
+ hp += sd->bonus.hp_gain_value;
+ }
+ if( attack_type&BF_MAGIC ) {
+ sp += sd->bonus.magic_sp_gain_value;
+ hp += sd->bonus.magic_hp_gain_value;
+ if( skillid == WZ_WATERBALL ) {//(bugreport:5303)
+ struct status_change *sc = NULL;
+ if( ( sc = status_get_sc(src) ) ) {
+ if(sc->data[SC_SPIRIT] &&
+ sc->data[SC_SPIRIT]->val2 == SL_WIZARD &&
+ sc->data[SC_SPIRIT]->val3 == WZ_WATERBALL)
+ sc->data[SC_SPIRIT]->val3 = 0; //Clear bounced spell check.
+ }
+ }
+ }
+ if( hp || sp ) { // updated to force healing to allow healing through berserk
+ status_heal(src, hp, sp, battle_config.show_hp_sp_gain ? 3 : 1);
+ }
+ }
- if (sd->autospell3[i].lock)
- continue; // autospell already being executed
+ // Trigger counter-spells to retaliate against damage causing skills.
+ if(dstsd && !status_isdead(bl) && dstsd->autospell2[0].id &&
+ !(skillid && skill_get_nk(skillid)&NK_NO_DAMAGE))
+ {
+ struct block_list *tbl;
+ struct unit_data *ud;
+ int i, skillid, skilllv, rate, type, notok;
- skill = (sd->autospell3[i].id > 0) ? sd->autospell3[i].id : -sd->autospell3[i].id;
+ for (i = 0; i < ARRAYLENGTH(dstsd->autospell2) && dstsd->autospell2[i].id; i++) {
- sd->state.autocast = 1;
- notok = skillnotok(skill, sd);
- sd->state.autocast = 0;
+ if(!(dstsd->autospell2[i].flag&attack_type&BF_WEAPONMASK &&
+ dstsd->autospell2[i].flag&attack_type&BF_RANGEMASK &&
+ dstsd->autospell2[i].flag&attack_type&BF_SKILLMASK))
+ continue; // one or more trigger conditions were not fulfilled
- if (notok)
- continue;
+ skillid = (dstsd->autospell2[i].id > 0) ? dstsd->autospell2[i].id : -dstsd->autospell2[i].id;
+ skilllv = dstsd->autospell2[i].lv?dstsd->autospell2[i].lv:1;
+ if (skilllv < 0) skilllv = 1+rnd()%(-skilllv);
- skilllv = sd->autospell3[i].lv ? sd->autospell3[i].lv : 1;
- if (skilllv < 0) skilllv = 1 + rnd()%(-skilllv);
+ rate = dstsd->autospell2[i].rate;
+ if (attack_type&BF_LONG)
+ rate>>=1;
- if (sd->autospell3[i].id >= 0 && bl == NULL)
- continue; // No target
- if (rnd()%1000 >= sd->autospell3[i].rate)
- continue;
+ dstsd->state.autocast = 1;
+ notok = skillnotok(skillid, dstsd);
+ dstsd->state.autocast = 0;
- tbl = (sd->autospell3[i].id < 0) ? &sd->bl : bl;
+ if ( notok )
+ continue;
- if ((type = skill_get_casttype(skill)) == CAST_GROUND) {
- int maxcount = 0;
- if (!(BL_PC&battle_config.skill_reiteration) &&
- skill_get_unit_flag(skill)&UF_NOREITERATION &&
- skill_check_unit_range(&sd->bl,tbl->x,tbl->y,skill,skilllv)
- ) {
- continue;
- }
- if (BL_PC&battle_config.skill_nofootset &&
- skill_get_unit_flag(skill)&UF_NOFOOTSET &&
- skill_check_unit_range2(&sd->bl,tbl->x,tbl->y,skill,skilllv)
- ) {
- continue;
- }
- if (BL_PC&battle_config.land_skill_limit &&
- (maxcount = skill_get_maxcount(skill, skilllv)) > 0
- ) {
- int v;
- for (v=0; v<MAX_SKILLUNITGROUP && sd->ud.skillunit[v] && maxcount; v++) {
- if (sd->ud.skillunit[v]->skill_id == skill)
- maxcount--;
- }
- if (maxcount == 0) {
- continue;
- }
- }
- }
- if (battle_config.autospell_check_range &&
- !battle_check_range(&sd->bl, tbl, skill_get_range2(&sd->bl, skill,skilllv) + (skill == RG_CLOSECONFINE?0:1)))
- continue;
-
- sd->state.autocast = 1;
- sd->autospell3[i].lock = true;
- skill_consume_requirement(sd,skill,skilllv,1);
- switch (type) {
- case CAST_GROUND:
- skill_castend_pos2(&sd->bl, tbl->x, tbl->y, skill, skilllv, tick, 0);
- break;
- case CAST_NODAMAGE:
- skill_castend_nodamage_id(&sd->bl, tbl, skill, skilllv, tick, 0);
- break;
- case CAST_DAMAGE:
- skill_castend_damage_id(&sd->bl, tbl, skill, skilllv, tick, 0);
- break;
- }
- sd->autospell3[i].lock = false;
- sd->state.autocast = 0;
- }
-
- if (sd && sd->autobonus3[0].rate) {
- for (i = 0; i < ARRAYLENGTH(sd->autobonus3); i++) {
- if (rnd()%1000 >= sd->autobonus3[i].rate)
- continue;
- if (sd->autobonus3[i].active != INVALID_TIMER)
- continue;
- if (sd->autobonus3[i].atk_type != skillid)
- continue;
- pc_exeautobonus(sd,&sd->autobonus3[i]);
- }
- }
-
- return 1;
-}
+ if (rnd()%1000 >= rate)
+ continue;
-/* Splitted off from skill_additional_effect, which is never called when the
- * attack skill kills the enemy. Place in this function counter status effects
- * when using skills (eg: Asura's sp regen penalty, or counter-status effects
- * from cards) that will take effect on the source, not the target. [Skotlex]
- * Note: Currently this function only applies to Extremity Fist and BF_WEAPON
- * type of skills, so not every instance of skill_additional_effect needs a call
- * to this one.
- */
-int skill_counter_additional_effect(struct block_list *src, struct block_list *bl, int skillid, int skilllv, int attack_type, unsigned int tick)
-{
- int rate;
- struct map_session_data *sd=NULL;
- struct map_session_data *dstsd=NULL;
-
- nullpo_ret(src);
- nullpo_ret(bl);
-
- if (skillid < 0) return 0;
- if (skillid > 0 && skilllv <= 0) return 0; // don't forget auto attacks! - celest
-
- sd = BL_CAST(BL_PC, src);
- dstsd = BL_CAST(BL_PC, bl);
-
- if (dstsd && attack_type&BF_WEAPON) {
- //Counter effects.
- enum sc_type type;
- int i, time;
- for (i=0; i < ARRAYLENGTH(dstsd->addeff2) && dstsd->addeff2[i].flag; i++) {
- rate = dstsd->addeff2[i].rate;
- if (attack_type&BF_LONG)
- rate+=dstsd->addeff2[i].arrow_rate;
- if (!rate) continue;
-
- if ((dstsd->addeff2[i].flag&(ATF_LONG|ATF_SHORT)) != (ATF_LONG|ATF_SHORT)) {
- //Trigger has range consideration.
- if ((dstsd->addeff2[i].flag&ATF_LONG && !(attack_type&BF_LONG)) ||
- (dstsd->addeff2[i].flag&ATF_SHORT && !(attack_type&BF_SHORT)))
- continue; //Range Failed.
- }
- type = dstsd->addeff2[i].id;
- time = skill_get_time2(status_sc2skill(type),7);
+ tbl = (dstsd->autospell2[i].id < 0) ? bl : src;
- if (dstsd->addeff2[i].flag&ATF_TARGET)
- status_change_start(src,type,rate,7,0,0,0,time,0);
+ if( (type = skill_get_casttype(skillid)) == CAST_GROUND ) {
+ int maxcount = 0;
+ if( !(BL_PC&battle_config.skill_reiteration) &&
+ skill_get_unit_flag(skillid)&UF_NOREITERATION &&
+ skill_check_unit_range(bl,tbl->x,tbl->y,skillid,skilllv)
+ ) {
+ continue;
+ }
+ if( BL_PC&battle_config.skill_nofootset &&
+ skill_get_unit_flag(skillid)&UF_NOFOOTSET &&
+ skill_check_unit_range2(bl,tbl->x,tbl->y,skillid,skilllv)
+ ) {
+ continue;
+ }
+ if( BL_PC&battle_config.land_skill_limit &&
+ (maxcount = skill_get_maxcount(skillid, skilllv)) > 0
+ ) {
+ int v;
+ for(v=0;v<MAX_SKILLUNITGROUP && dstsd->ud.skillunit[v] && maxcount;v++) {
+ if(dstsd->ud.skillunit[v]->skill_id == skillid)
+ maxcount--;
+ }
+ if( maxcount == 0 ) {
+ continue;
+ }
+ }
+ }
- if (dstsd->addeff2[i].flag&ATF_SELF && !status_isdead(bl))
- status_change_start(bl,type,rate,7,0,0,0,time,0);
- }
- }
+ if( !battle_check_range(src, tbl, skill_get_range2(src, skillid,skilllv) + (skillid == RG_CLOSECONFINE?0:1)) && battle_config.autospell_check_range )
+ continue;
+
+ dstsd->state.autocast = 1;
+ skill_consume_requirement(dstsd,skillid,skilllv,1);
+ switch (type) {
+ case CAST_GROUND:
+ skill_castend_pos2(bl, tbl->x, tbl->y, skillid, skilllv, tick, 0);
+ break;
+ case CAST_NODAMAGE:
+ skill_castend_nodamage_id(bl, tbl, skillid, skilllv, tick, 0);
+ break;
+ case CAST_DAMAGE:
+ skill_castend_damage_id(bl, tbl, skillid, skilllv, tick, 0);
+ break;
+ }
+ dstsd->state.autocast = 0;
+ //Set canact delay. [Skotlex]
+ ud = unit_bl2ud(bl);
+ if (ud) {
+ rate = skill_delayfix(bl, skillid, skilllv);
+ if (DIFF_TICK(ud->canact_tick, tick + rate) < 0){
+ ud->canact_tick = tick+rate;
+ if ( battle_config.display_status_timers && dstsd )
+ clif_status_change(bl, SI_ACTIONDELAY, 1, rate, 0, 0, 0);
+ }
+ }
+ }
+ }
- switch (skillid) {
- case MO_EXTREMITYFIST:
- sc_start(src,SC_EXTREMITYFIST,100,skilllv,skill_get_time2(skillid,skilllv));
- break;
- case GS_FULLBUSTER:
- sc_start(src,SC_BLIND,2*skilllv,skilllv,skill_get_time2(skillid,skilllv));
- break;
- case HFLI_SBR44: //[orn]
- case HVAN_EXPLOSION:
- if (src->type == BL_HOM) {
- TBL_HOM *hd = (TBL_HOM *)src;
- hd->homunculus.intimacy = 200;
- if (hd->master)
- clif_send_homdata(hd->master,SP_INTIMATE,hd->homunculus.intimacy/100);
- }
- break;
- case CR_GRANDCROSS:
- case NPC_GRANDDARKNESS:
- attack_type |= BF_WEAPON;
- break;
- }
-
- if (sd && (sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR &&
- rnd()%10000 < battle_config.sg_miracle_skill_ratio) //SG_MIRACLE [Komurka]
- sc_start(src,SC_MIRACLE,100,1,battle_config.sg_miracle_skill_duration);
-
- if (sd && skillid && attack_type&BF_MAGIC && status_isdead(bl) &&
- !(skill_get_inf(skillid)&(INF_GROUND_SKILL|INF_SELF_SKILL)) &&
- (rate=pc_checkskill(sd,HW_SOULDRAIN))>0
- ) { //Soul Drain should only work on targetted spells [Skotlex]
- if (pc_issit(sd)) pc_setstand(sd); //Character stuck in attacking animation while 'sitting' fix. [Skotlex]
- clif_skill_nodamage(src,bl,HW_SOULDRAIN,rate,1);
- status_heal(src, 0, status_get_lv(bl)*(95+15*rate)/100, 2);
- }
-
- if (sd && status_isdead(bl)) {
- int sp = 0, hp = 0;
- if (attack_type&BF_WEAPON) {
- sp += sd->bonus.sp_gain_value;
- sp += sd->sp_gain_race[status_get_race(bl)];
- sp += sd->sp_gain_race[is_boss(bl)?RC_BOSS:RC_NONBOSS];
- hp += sd->bonus.hp_gain_value;
- }
- if (attack_type&BF_MAGIC) {
- sp += sd->bonus.magic_sp_gain_value;
- hp += sd->bonus.magic_hp_gain_value;
- if (skillid == WZ_WATERBALL) { //(bugreport:5303)
- struct status_change *sc = NULL;
- if ((sc = status_get_sc(src))) {
- if (sc->data[SC_SPIRIT] &&
- sc->data[SC_SPIRIT]->val2 == SL_WIZARD &&
- sc->data[SC_SPIRIT]->val3 == WZ_WATERBALL)
- sc->data[SC_SPIRIT]->val3 = 0; //Clear bounced spell check.
- }
- }
- }
- if (hp || sp) { // updated to force healing to allow healing through berserk
- status_heal(src, hp, sp, battle_config.show_hp_sp_gain ? 3 : 1);
- }
- }
-
- // Trigger counter-spells to retaliate against damage causing skills.
- if (dstsd && !status_isdead(bl) && dstsd->autospell2[0].id &&
- !(skillid && skill_get_nk(skillid)&NK_NO_DAMAGE)) {
- struct block_list *tbl;
- struct unit_data *ud;
- int i, skillid, skilllv, rate, type, notok;
-
- for (i = 0; i < ARRAYLENGTH(dstsd->autospell2) && dstsd->autospell2[i].id; i++) {
-
- if (!(dstsd->autospell2[i].flag&attack_type&BF_WEAPONMASK &&
- dstsd->autospell2[i].flag&attack_type&BF_RANGEMASK &&
- dstsd->autospell2[i].flag&attack_type&BF_SKILLMASK))
- continue; // one or more trigger conditions were not fulfilled
-
- skillid = (dstsd->autospell2[i].id > 0) ? dstsd->autospell2[i].id : -dstsd->autospell2[i].id;
- skilllv = dstsd->autospell2[i].lv?dstsd->autospell2[i].lv:1;
- if (skilllv < 0) skilllv = 1+rnd()%(-skilllv);
-
- rate = dstsd->autospell2[i].rate;
- if (attack_type&BF_LONG)
- rate>>=1;
-
- dstsd->state.autocast = 1;
- notok = skillnotok(skillid, dstsd);
- dstsd->state.autocast = 0;
-
- if (notok)
- continue;
-
- if (rnd()%1000 >= rate)
- continue;
-
- tbl = (dstsd->autospell2[i].id < 0) ? bl : src;
-
- if ((type = skill_get_casttype(skillid)) == CAST_GROUND) {
- int maxcount = 0;
- if (!(BL_PC&battle_config.skill_reiteration) &&
- skill_get_unit_flag(skillid)&UF_NOREITERATION &&
- skill_check_unit_range(bl,tbl->x,tbl->y,skillid,skilllv)
- ) {
- continue;
- }
- if (BL_PC&battle_config.skill_nofootset &&
- skill_get_unit_flag(skillid)&UF_NOFOOTSET &&
- skill_check_unit_range2(bl,tbl->x,tbl->y,skillid,skilllv)
- ) {
- continue;
- }
- if (BL_PC&battle_config.land_skill_limit &&
- (maxcount = skill_get_maxcount(skillid, skilllv)) > 0
- ) {
- int v;
- for (v=0; v<MAX_SKILLUNITGROUP && dstsd->ud.skillunit[v] && maxcount; v++) {
- if (dstsd->ud.skillunit[v]->skill_id == skillid)
- maxcount--;
- }
- if (maxcount == 0) {
- continue;
- }
- }
- }
+ //Autobonus when attacked
+ if( dstsd && !status_isdead(bl) && dstsd->autobonus2[0].rate && !(skillid && skill_get_nk(skillid)&NK_NO_DAMAGE) )
+ {
+ int i;
+ for( i = 0; i < ARRAYLENGTH(dstsd->autobonus2); i++ )
+ {
+ if( rnd()%1000 >= dstsd->autobonus2[i].rate )
+ continue;
+ if( dstsd->autobonus2[i].active != INVALID_TIMER )
+ continue;
+ if(!(dstsd->autobonus2[i].atk_type&attack_type&BF_WEAPONMASK &&
+ dstsd->autobonus2[i].atk_type&attack_type&BF_RANGEMASK &&
+ dstsd->autobonus2[i].atk_type&attack_type&BF_SKILLMASK))
+ continue; // one or more trigger conditions were not fulfilled
+ pc_exeautobonus(dstsd,&dstsd->autobonus2[i]);
+ }
+ }
- if (!battle_check_range(src, tbl, skill_get_range2(src, skillid,skilllv) + (skillid == RG_CLOSECONFINE?0:1)) && battle_config.autospell_check_range)
- continue;
-
- dstsd->state.autocast = 1;
- skill_consume_requirement(dstsd,skillid,skilllv,1);
- switch (type) {
- case CAST_GROUND:
- skill_castend_pos2(bl, tbl->x, tbl->y, skillid, skilllv, tick, 0);
- break;
- case CAST_NODAMAGE:
- skill_castend_nodamage_id(bl, tbl, skillid, skilllv, tick, 0);
- break;
- case CAST_DAMAGE:
- skill_castend_damage_id(bl, tbl, skillid, skilllv, tick, 0);
- break;
- }
- dstsd->state.autocast = 0;
- //Set canact delay. [Skotlex]
- ud = unit_bl2ud(bl);
- if (ud) {
- rate = skill_delayfix(bl, skillid, skilllv);
- if (DIFF_TICK(ud->canact_tick, tick + rate) < 0) {
- ud->canact_tick = tick+rate;
- if (battle_config.display_status_timers && dstsd)
- clif_status_change(bl, SI_ACTIONDELAY, 1, rate, 0, 0, 0);
- }
- }
- }
- }
-
- //Autobonus when attacked
- if (dstsd && !status_isdead(bl) && dstsd->autobonus2[0].rate && !(skillid && skill_get_nk(skillid)&NK_NO_DAMAGE)) {
- int i;
- for (i = 0; i < ARRAYLENGTH(dstsd->autobonus2); i++) {
- if (rnd()%1000 >= dstsd->autobonus2[i].rate)
- continue;
- if (dstsd->autobonus2[i].active != INVALID_TIMER)
- continue;
- if (!(dstsd->autobonus2[i].atk_type&attack_type&BF_WEAPONMASK &&
- dstsd->autobonus2[i].atk_type&attack_type&BF_RANGEMASK &&
- dstsd->autobonus2[i].atk_type&attack_type&BF_SKILLMASK))
- continue; // one or more trigger conditions were not fulfilled
- pc_exeautobonus(dstsd,&dstsd->autobonus2[i]);
- }
- }
-
- return 0;
+ return 0;
}
/*=========================================================================
Breaks equipment. On-non players causes the corresponding strip effect.
@@ -2053,123 +1900,123 @@ int skill_counter_additional_effect(struct block_list *src, struct block_list *b
- flag is a BCT_ flag to indicate which type of adjustment should be used
(BCT_ENEMY/BCT_PARTY/BCT_SELF) are the valid values.
--------------------------------------------------------------------------*/
-int skill_break_equip(struct block_list *bl, unsigned short where, int rate, int flag)
+int skill_break_equip (struct block_list *bl, unsigned short where, int rate, int flag)
{
- const int where_list[4] = {EQP_WEAPON, EQP_ARMOR, EQP_SHIELD, EQP_HELM};
- const enum sc_type scatk[4] = {SC_STRIPWEAPON, SC_STRIPARMOR, SC_STRIPSHIELD, SC_STRIPHELM};
- const enum sc_type scdef[4] = {SC_CP_WEAPON, SC_CP_ARMOR, SC_CP_SHIELD, SC_CP_HELM};
- struct status_change *sc = status_get_sc(bl);
- int i,j;
- TBL_PC *sd;
- sd = BL_CAST(BL_PC, bl);
- if (sc && !sc->count)
- sc = NULL;
-
- if (sd) {
- if (sd->bonus.unbreakable_equip)
- where &= ~sd->bonus.unbreakable_equip;
- if (sd->bonus.unbreakable)
- rate -= rate*sd->bonus.unbreakable/100;
- if (where&EQP_WEAPON) {
- switch (sd->status.weapon) {
- case W_FIST: //Bare fists should not break :P
- case W_1HAXE:
- case W_2HAXE:
- case W_MACE: // Axes and Maces can't be broken [DracoRPG]
- case W_2HMACE:
- case W_STAFF:
- case W_2HSTAFF:
- case W_BOOK: //Rods and Books can't be broken [Skotlex]
- case W_HUUMA:
- where &= ~EQP_WEAPON;
- }
- }
- }
- if (flag&BCT_ENEMY) {
- if (battle_config.equip_skill_break_rate != 100)
- rate = rate*battle_config.equip_skill_break_rate/100;
- } else if (flag&(BCT_PARTY|BCT_SELF)) {
- if (battle_config.equip_self_break_rate != 100)
- rate = rate*battle_config.equip_self_break_rate/100;
- }
-
- for (i = 0; i < 4; i++) {
- if (where&where_list[i]) {
- if (sc && sc->count && sc->data[scdef[i]])
- where&=~where_list[i];
- else if (rnd()%10000 >= rate)
- where&=~where_list[i];
- else if (!sd && !(status_get_mode(bl)&MD_BOSS)) //Cause Strip effect.
- sc_start(bl,scatk[i],100,0,skill_get_time(status_sc2skill(scatk[i]),1));
- }
- }
- if (!where) //Nothing to break.
- return 0;
- if (sd) {
- for (i = 0; i < EQI_MAX; i++) {
- j = sd->equip_index[i];
- if (j < 0 || sd->status.inventory[j].attribute == 1 || !sd->inventory_data[j])
- continue;
-
- switch (i) {
- case EQI_HEAD_TOP: //Upper Head
- flag = (where&EQP_HELM);
- break;
- case EQI_ARMOR: //Body
- flag = (where&EQP_ARMOR);
- break;
- case EQI_HAND_R: //Left/Right hands
- case EQI_HAND_L:
- flag = (
- (where&EQP_WEAPON && sd->inventory_data[j]->type == IT_WEAPON) ||
- (where&EQP_SHIELD && sd->inventory_data[j]->type == IT_ARMOR));
- break;
- case EQI_SHOES:
- flag = (where&EQP_SHOES);
- break;
- case EQI_GARMENT:
- flag = (where&EQP_GARMENT);
- break;
- default:
- continue;
- }
- if (flag) {
- sd->status.inventory[j].attribute = 1;
- pc_unequipitem(sd, j, 3);
- }
- }
- clif_equiplist(sd);
- }
+ const int where_list[4] = {EQP_WEAPON, EQP_ARMOR, EQP_SHIELD, EQP_HELM};
+ const enum sc_type scatk[4] = {SC_STRIPWEAPON, SC_STRIPARMOR, SC_STRIPSHIELD, SC_STRIPHELM};
+ const enum sc_type scdef[4] = {SC_CP_WEAPON, SC_CP_ARMOR, SC_CP_SHIELD, SC_CP_HELM};
+ struct status_change *sc = status_get_sc(bl);
+ int i,j;
+ TBL_PC *sd;
+ sd = BL_CAST(BL_PC, bl);
+ if (sc && !sc->count)
+ sc = NULL;
+
+ if (sd) {
+ if (sd->bonus.unbreakable_equip)
+ where &= ~sd->bonus.unbreakable_equip;
+ if (sd->bonus.unbreakable)
+ rate -= rate*sd->bonus.unbreakable/100;
+ if (where&EQP_WEAPON) {
+ switch (sd->status.weapon) {
+ case W_FIST: //Bare fists should not break :P
+ case W_1HAXE:
+ case W_2HAXE:
+ case W_MACE: // Axes and Maces can't be broken [DracoRPG]
+ case W_2HMACE:
+ case W_STAFF:
+ case W_2HSTAFF:
+ case W_BOOK: //Rods and Books can't be broken [Skotlex]
+ case W_HUUMA:
+ where &= ~EQP_WEAPON;
+ }
+ }
+ }
+ if (flag&BCT_ENEMY) {
+ if (battle_config.equip_skill_break_rate != 100)
+ rate = rate*battle_config.equip_skill_break_rate/100;
+ } else if (flag&(BCT_PARTY|BCT_SELF)) {
+ if (battle_config.equip_self_break_rate != 100)
+ rate = rate*battle_config.equip_self_break_rate/100;
+ }
+
+ for (i = 0; i < 4; i++) {
+ if (where&where_list[i]) {
+ if (sc && sc->count && sc->data[scdef[i]])
+ where&=~where_list[i];
+ else if (rnd()%10000 >= rate)
+ where&=~where_list[i];
+ else if (!sd && !(status_get_mode(bl)&MD_BOSS)) //Cause Strip effect.
+ sc_start(bl,scatk[i],100,0,skill_get_time(status_sc2skill(scatk[i]),1));
+ }
+ }
+ if (!where) //Nothing to break.
+ return 0;
+ if (sd) {
+ for (i = 0; i < EQI_MAX; i++) {
+ j = sd->equip_index[i];
+ if (j < 0 || sd->status.inventory[j].attribute == 1 || !sd->inventory_data[j])
+ continue;
+
+ switch(i) {
+ case EQI_HEAD_TOP: //Upper Head
+ flag = (where&EQP_HELM);
+ break;
+ case EQI_ARMOR: //Body
+ flag = (where&EQP_ARMOR);
+ break;
+ case EQI_HAND_R: //Left/Right hands
+ case EQI_HAND_L:
+ flag = (
+ (where&EQP_WEAPON && sd->inventory_data[j]->type == IT_WEAPON) ||
+ (where&EQP_SHIELD && sd->inventory_data[j]->type == IT_ARMOR));
+ break;
+ case EQI_SHOES:
+ flag = (where&EQP_SHOES);
+ break;
+ case EQI_GARMENT:
+ flag = (where&EQP_GARMENT);
+ break;
+ default:
+ continue;
+ }
+ if (flag) {
+ sd->status.inventory[j].attribute = 1;
+ pc_unequipitem(sd, j, 3);
+ }
+ }
+ clif_equiplist(sd);
+ }
- return where; //Return list of pieces broken.
+ return where; //Return list of pieces broken.
}
int skill_strip_equip(struct block_list *bl, unsigned short where, int rate, int lv, int time)
{
- struct status_change *sc;
- const int pos[5] = {EQP_WEAPON, EQP_SHIELD, EQP_ARMOR, EQP_HELM, EQP_ACC};
- const enum sc_type sc_atk[5] = {SC_STRIPWEAPON, SC_STRIPSHIELD, SC_STRIPARMOR, SC_STRIPHELM, SC__STRIPACCESSORY};
- const enum sc_type sc_def[5] = {SC_CP_WEAPON, SC_CP_SHIELD, SC_CP_ARMOR, SC_CP_HELM, 0};
- int i;
-
- if (rnd()%100 >= rate)
- return 0;
-
- sc = status_get_sc(bl);
- if (!sc || sc->option&OPTION_MADOGEAR) //Mado Gear cannot be divested [Ind]
- return 0;
-
- for (i = 0; i < ARRAYLENGTH(pos); i++) {
- if (where&pos[i] && sc->data[sc_def[i]])
- where&=~pos[i];
- }
- if (!where) return 0;
-
- for (i = 0; i < ARRAYLENGTH(pos); i++) {
- if (where&pos[i] && !sc_start(bl, sc_atk[i], 100, lv, time))
- where&=~pos[i];
- }
- return where?1:0;
+ struct status_change *sc;
+ const int pos[5] = {EQP_WEAPON, EQP_SHIELD, EQP_ARMOR, EQP_HELM, EQP_ACC};
+ const enum sc_type sc_atk[5] = {SC_STRIPWEAPON, SC_STRIPSHIELD, SC_STRIPARMOR, SC_STRIPHELM, SC__STRIPACCESSORY};
+ const enum sc_type sc_def[5] = {SC_CP_WEAPON, SC_CP_SHIELD, SC_CP_ARMOR, SC_CP_HELM, 0};
+ int i;
+
+ if (rnd()%100 >= rate)
+ return 0;
+
+ sc = status_get_sc(bl);
+ if (!sc || sc->option&OPTION_MADOGEAR ) //Mado Gear cannot be divested [Ind]
+ return 0;
+
+ for (i = 0; i < ARRAYLENGTH(pos); i++) {
+ if (where&pos[i] && sc->data[sc_def[i]])
+ where&=~pos[i];
+ }
+ if (!where) return 0;
+
+ for (i = 0; i < ARRAYLENGTH(pos); i++) {
+ if (where&pos[i] && !sc_start(bl, sc_atk[i], 100, lv, time))
+ where&=~pos[i];
+ }
+ return where?1:0;
}
//Early declaration
static int skill_area_temp[8];
@@ -2180,88 +2027,88 @@ static int skill_area_temp[8];
- if 'flag&0x1', position update packets must not be sent.
- if 'flag&0x2', skill blown ignores players' special_state.no_knockback
-------------------------------------------------------------------------*/
-int skill_blown(struct block_list *src, struct block_list *target, int count, int direction, int flag)
+int skill_blown(struct block_list* src, struct block_list* target, int count, int direction, int flag)
{
- int dx = 0, dy = 0;
- struct skill_unit *su = NULL;
-
- nullpo_ret(src);
-
- if (src != target && (map_flag_gvg(target->m) || map[target->m].flag.battleground))
- return 0; //No knocking back in WoE
- if (count == 0)
- return 0; //Actual knockback distance is 0.
-
- switch (target->type) {
- case BL_MOB: {
- struct mob_data *md = BL_CAST(BL_MOB, target);
- if (md->class_ == MOBID_EMPERIUM)
- return 0;
- if (src != target && is_boss(target)) //Bosses can't be knocked-back
- return 0;
- }
- break;
- case BL_PC: {
- struct map_session_data *sd = BL_CAST(BL_PC, target);
- if (sd->sc.data[SC_BASILICA] && sd->sc.data[SC_BASILICA]->val4 == sd->bl.id && !is_boss(src))
- return 0; // Basilica caster can't be knocked-back by normal monsters.
- if (!(flag&0x2) && src != target && sd->special_state.no_knockback)
- return 0;
- }
- break;
- case BL_SKILL:
- su = (struct skill_unit *)target;
- if (su && su->group && su->group->unit_id == UNT_ANKLESNARE)
- return 0; // ankle snare cannot be knocked back
- break;
- }
+ int dx = 0, dy = 0;
+ struct skill_unit* su = NULL;
+
+ nullpo_ret(src);
+
+ if (src != target && (map_flag_gvg(target->m) || map[target->m].flag.battleground))
+ return 0; //No knocking back in WoE
+ if (count == 0)
+ return 0; //Actual knockback distance is 0.
+
+ switch (target->type) {
+ case BL_MOB: {
+ struct mob_data* md = BL_CAST(BL_MOB, target);
+ if( md->class_ == MOBID_EMPERIUM )
+ return 0;
+ if(src != target && is_boss(target)) //Bosses can't be knocked-back
+ return 0;
+ }
+ break;
+ case BL_PC: {
+ struct map_session_data *sd = BL_CAST(BL_PC, target);
+ if( sd->sc.data[SC_BASILICA] && sd->sc.data[SC_BASILICA]->val4 == sd->bl.id && !is_boss(src))
+ return 0; // Basilica caster can't be knocked-back by normal monsters.
+ if( !(flag&0x2) && src != target && sd->special_state.no_knockback )
+ return 0;
+ }
+ break;
+ case BL_SKILL:
+ su = (struct skill_unit *)target;
+ if( su && su->group && su->group->unit_id == UNT_ANKLESNARE )
+ return 0; // ankle snare cannot be knocked back
+ break;
+ }
- if (direction == -1) // <optimized>: do the computation here instead of outside
- direction = map_calc_dir(target, src->x, src->y); // direction from src to target, reversed
+ if (direction == -1) // <optimized>: do the computation here instead of outside
+ direction = map_calc_dir(target, src->x, src->y); // direction from src to target, reversed
- if (direction >= 0 && direction < 8) {
- // take the reversed 'direction' and reverse it
- dx = -dirx[direction];
- dy = -diry[direction];
- }
+ if (direction >= 0 && direction < 8)
+ { // take the reversed 'direction' and reverse it
+ dx = -dirx[direction];
+ dy = -diry[direction];
+ }
- return unit_blown(target, dx, dy, count, flag); // send over the proper flag
+ return unit_blown(target, dx, dy, count, flag); // send over the proper flag
}
//Checks if 'bl' should reflect back a spell cast by 'src'.
//type is the type of magic attack: 0: indirect (aoe), 1: direct (targetted)
-static int skill_magic_reflect(struct block_list *src, struct block_list *bl, int type)
+static int skill_magic_reflect(struct block_list* src, struct block_list* bl, int type)
{
- struct status_change *sc = status_get_sc(bl);
- struct map_session_data *sd = BL_CAST(BL_PC, bl);
+ struct status_change *sc = status_get_sc(bl);
+ struct map_session_data* sd = BL_CAST(BL_PC, bl);
- if (sc && sc->data[SC_KYOMU]) // Nullify reflecting ability
- return 0;
+ if( sc && sc->data[SC_KYOMU] ) // Nullify reflecting ability
+ return 0;
- // item-based reflection
- if (sd && sd->bonus.magic_damage_return && type && rnd()%100 < sd->bonus.magic_damage_return)
- return 1;
+ // item-based reflection
+ if( sd && sd->bonus.magic_damage_return && type && rnd()%100 < sd->bonus.magic_damage_return )
+ return 1;
- if (is_boss(src))
- return 0;
+ if( is_boss(src) )
+ return 0;
- // status-based reflection
- if (!sc || sc->count == 0)
- return 0;
+ // status-based reflection
+ if( !sc || sc->count == 0 )
+ return 0;
- if (sc->data[SC_MAGICMIRROR] && rnd()%100 < sc->data[SC_MAGICMIRROR]->val2)
- return 1;
+ if( sc->data[SC_MAGICMIRROR] && rnd()%100 < sc->data[SC_MAGICMIRROR]->val2 )
+ return 1;
- if (sc->data[SC_KAITE] && (src->type == BL_PC || status_get_lv(src) <= 80)) {
- // Kaite only works against non-players if they are low-level.
- clif_specialeffect(bl, 438, AREA);
- if (--sc->data[SC_KAITE]->val2 <= 0)
- status_change_end(bl, SC_KAITE, INVALID_TIMER);
- return 2;
- }
+ if( sc->data[SC_KAITE] && (src->type == BL_PC || status_get_lv(src) <= 80) )
+ {// Kaite only works against non-players if they are low-level.
+ clif_specialeffect(bl, 438, AREA);
+ if( --sc->data[SC_KAITE]->val2 <= 0 )
+ status_change_end(bl, SC_KAITE, INVALID_TIMER);
+ return 2;
+ }
- return 0;
+ return 0;
}
/*
@@ -2278,623 +2125,633 @@ static int skill_magic_reflect(struct block_list *src, struct block_list *bl, in
* flag&0x2000 is used to signal that the skilllv should be passed as -1 to the
* client (causes player characters to not scream skill name)
*-------------------------------------------------------------------------*/
-int skill_attack(int attack_type, struct block_list *src, struct block_list *dsrc, struct block_list *bl, int skillid, int skilllv, unsigned int tick, int flag)
+int skill_attack (int attack_type, struct block_list* src, struct block_list *dsrc, struct block_list *bl, int skillid, int skilllv, unsigned int tick, int flag)
{
- struct Damage dmg;
- struct status_data *sstatus, *tstatus;
- struct status_change *sc;
- struct map_session_data *sd, *tsd;
- int type,damage,rdamage=0;
-
- if (skillid > 0 && skilllv <= 0) return 0;
-
- nullpo_ret(src); //Source is the master behind the attack (player/mob/pet)
- nullpo_ret(dsrc); //dsrc is the actual originator of the damage, can be the same as src, or a skill casted by src.
- nullpo_ret(bl); //Target to be attacked.
-
- if (src != dsrc) {
- //When caster is not the src of attack, this is a ground skill, and as such, do the relevant target checking. [Skotlex]
- if (!status_check_skilluse(battle_config.skill_caster_check?src:NULL, bl, skillid, 2))
- return 0;
- } else if ((flag&SD_ANIMATION) && skill_get_nk(skillid)&NK_SPLASH) {
- //Note that splash attacks often only check versus the targetted mob, those around the splash area normally don't get checked for being hidden/cloaked/etc. [Skotlex]
- if (!status_check_skilluse(src, bl, skillid, 2))
- return 0;
- }
-
- sd = BL_CAST(BL_PC, src);
- tsd = BL_CAST(BL_PC, bl);
-
- sstatus = status_get_status_data(src);
- tstatus = status_get_status_data(bl);
- sc= status_get_sc(bl);
- if (sc && !sc->count) sc = NULL; //Don't need it.
-
- // Is this check really needed? FrostNova won't hurt you if you step right where the caster is?
- if (skillid == WZ_FROSTNOVA && dsrc->x == bl->x && dsrc->y == bl->y)
- return 0;
- //Trick Dead protects you from damage, but not from buffs and the like, hence it's placed here.
- if (sc && sc->data[SC_TRICKDEAD] && !(sstatus->mode&MD_BOSS))
- return 0;
-
- dmg = battle_calc_attack(attack_type,src,bl,skillid,skilllv,flag&0xFFF);
-
- //Skotlex: Adjusted to the new system
- if (src->type==BL_PET) {
- // [Valaris]
- struct pet_data *pd = (TBL_PET *)src;
- if (pd->a_skill && pd->a_skill->div_ && pd->a_skill->id == skillid) {
- int element = skill_get_ele(skillid, skilllv);
- if (skillid == -1)
- element = sstatus->rhw.ele;
- if (element != ELE_NEUTRAL || !(battle_config.attack_attr_none&BL_PET))
- dmg.damage=battle_attr_fix(src, bl, skilllv, element, tstatus->def_ele, tstatus->ele_lv);
- else
- dmg.damage= skilllv;
- dmg.damage2=0;
- dmg.div_= pd->a_skill->div_;
- }
- }
-
- if (dmg.flag&BF_MAGIC && (skillid != NPC_EARTHQUAKE || (battle_config.eq_single_target_reflectable && (flag&0xFFF) == 1))) {
- // Earthquake on multiple targets is not counted as a target skill. [Inkfish]
- if ((dmg.damage || dmg.damage2) && (type = skill_magic_reflect(src, bl, src==dsrc))) {
- //Magic reflection, switch caster/target
- struct block_list *tbl = bl;
- bl = src;
- src = tbl;
- sd = BL_CAST(BL_PC, src);
- tsd = BL_CAST(BL_PC, bl);
- sc = status_get_sc(bl);
- if (sc && !sc->count)
- sc = NULL; //Don't need it.
- /* bugreport:2564 flag&2 disables double casting trigger */
- flag |= 2;
-
- //Spirit of Wizard blocks Kaite's reflection
- if (type == 2 && sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_WIZARD) {
- //Consume one Fragment per hit of the casted skill? [Skotlex]
- type = tsd?pc_search_inventory(tsd, 7321):0;
- if (type >= 0) {
- if (tsd) pc_delitem(tsd, type, 1, 0, 1, LOG_TYPE_CONSUME);
- dmg.damage = dmg.damage2 = 0;
- dmg.dmg_lv = ATK_MISS;
- sc->data[SC_SPIRIT]->val3 = skillid;
- sc->data[SC_SPIRIT]->val4 = dsrc->id;
- }
- }
- /**
- * Official Magic Reflection Behavior : damage reflected depends on gears caster wears, not target
- **/
-#if MAGIC_REFLECTION_TYPE
- if (dmg.dmg_lv != ATK_MISS) //Wiz SL cancelled and consumed fragment
- dmg = battle_calc_attack(BF_MAGIC,bl,bl,skillid,skilllv,flag&0xFFF);
-#endif
- }
- if (sc && sc->data[SC_MAGICROD] && src == dsrc) {
- int sp = skill_get_sp(skillid,skilllv);
- dmg.damage = dmg.damage2 = 0;
- dmg.dmg_lv = ATK_MISS; //This will prevent skill additional effect from taking effect. [Skotlex]
- sp = sp * sc->data[SC_MAGICROD]->val2 / 100;
- if (skillid == WZ_WATERBALL && skilllv > 1)
- sp = sp/((skilllv|1)*(skilllv|1)); //Estimate SP cost of a single water-ball
- status_heal(bl, 0, sp, 2);
- }
- }
-
- damage = dmg.damage + dmg.damage2;
-
- if ((skillid == AL_INCAGI || skillid == AL_BLESSING ||
- skillid == CASH_BLESSING || skillid == CASH_INCAGI ||
- skillid == MER_INCAGI || skillid == MER_BLESSING) && tsd->sc.data[SC_CHANGEUNDEAD])
- damage = 1;
-
- if (damage > 0 && ((dmg.flag&BF_WEAPON && src != bl && (src == dsrc || (dsrc->type == BL_SKILL && (skillid == SG_SUN_WARM || skillid == SG_MOON_WARM || skillid == SG_STAR_WARM))))
- || (sc && sc->data[SC_REFLECTDAMAGE])))
- rdamage = battle_calc_return_damage(bl,src, &damage, dmg.flag, skillid);
-
- if (damage && sc && sc->data[SC_GENSOU] && dmg.flag&BF_MAGIC) {
- struct block_list *nbl = NULL;
- nbl = battle_getenemyarea(bl,bl->x,bl->y,2,BL_CHAR,bl->id);
- if (nbl) { // Only one target is chosen.
- damage = damage / 2; // Deflect half of the damage to a target nearby
- clif_skill_damage(bl, nbl, tick, status_get_amotion(src), 0, status_fix_damage(bl,nbl,damage,0), dmg.div_, OB_OBOROGENSOU_TRANSITION_ATK, -1, 6);
- }
- }
-
- //Skill hit type
- type=(skillid==0)?5:skill_get_hit(skillid);
-
- if (damage < dmg.div_
- //Only skills that knockback even when they miss. [Skotlex]
- && skillid != CH_PALMSTRIKE)
- dmg.blewcount = 0;
-
- if (skillid == CR_GRANDCROSS||skillid == NPC_GRANDDARKNESS) {
- if (battle_config.gx_disptype) dsrc = src;
- if (src == bl) type = 4;
- else flag|=SD_ANIMATION;
- }
- if (skillid == NJ_TATAMIGAESHI) {
- dsrc = src; //For correct knockback.
- flag|=SD_ANIMATION;
- }
-
- if (sd) {
- int flag = 0; //Used to signal if this skill can be combo'ed later on.
- struct status_change_entry *sce;
- if ((sce = sd->sc.data[SC_COMBO])) {//End combo state after skill is invoked. [Skotlex]
- switch (skillid) {
- case TK_TURNKICK:
- case TK_STORMKICK:
- case TK_DOWNKICK:
- case TK_COUNTER:
- if (pc_famerank(sd->status.char_id,MAPID_TAEKWON)) {//Extend combo time.
- sce->val1 = skillid; //Update combo-skill
- sce->val3 = skillid;
- if (sce->timer != INVALID_TIMER)
- delete_timer(sce->timer, status_change_timer);
- sce->timer = add_timer(tick+sce->val4, status_change_timer, src->id, SC_COMBO);
- break;
- }
- unit_cancel_combo(src); // Cancel combo wait
- break;
- default:
- if (src == dsrc) // Ground skills are exceptions. [Inkfish]
- status_change_end(src, SC_COMBO, INVALID_TIMER);
- }
- }
- switch (skillid) {
- case MO_TRIPLEATTACK:
- if (pc_checkskill(sd, MO_CHAINCOMBO) > 0 || pc_checkskill(sd, SR_DRAGONCOMBO) > 0)
- flag=1;
- break;
- case MO_CHAINCOMBO:
- if (pc_checkskill(sd, MO_COMBOFINISH) > 0 && sd->spiritball > 0)
- flag=1;
- break;
- case MO_COMBOFINISH:
- if (sd->status.party_id>0) //bonus from SG_FRIEND [Komurka]
- party_skill_check(sd, sd->status.party_id, MO_COMBOFINISH, skilllv);
- if (pc_checkskill(sd, CH_TIGERFIST) > 0 && sd->spiritball > 0)
- flag=1;
- case CH_TIGERFIST:
- if (!flag && pc_checkskill(sd, CH_CHAINCRUSH) > 0 && sd->spiritball > 1)
- flag=1;
- case CH_CHAINCRUSH:
- if (!flag && pc_checkskill(sd, MO_EXTREMITYFIST) > 0 && sd->spiritball > 0 && sd->sc.data[SC_EXPLOSIONSPIRITS])
- flag=1;
- break;
- case AC_DOUBLE:
- if ((tstatus->race == RC_BRUTE || tstatus->race == RC_INSECT) && pc_checkskill(sd, HT_POWER)) {
- //TODO: This code was taken from Triple Blows, is this even how it should be? [Skotlex]
- sc_start2(src,SC_COMBO,100,HT_POWER,bl->id,2000);
- clif_combo_delay(src,2000);
- }
- break;
- case TK_COUNTER: {
- //bonus from SG_FRIEND [Komurka]
- int level;
- if (sd->status.party_id>0 && (level = pc_checkskill(sd,SG_FRIEND)))
- party_skill_check(sd, sd->status.party_id, TK_COUNTER,level);
- }
- break;
- case SL_STIN:
- case SL_STUN:
- if (skilllv >= 7 && !sd->sc.data[SC_SMA])
- sc_start(src,SC_SMA,100,skilllv,skill_get_time(SL_SMA, skilllv));
- break;
- case GS_FULLBUSTER:
- //Can't attack nor use items until skill's delay expires. [Skotlex]
- sd->ud.attackabletime = sd->canuseitem_tick = sd->ud.canact_tick;
- break;
- case SR_DRAGONCOMBO:
- if (pc_checkskill(sd, SR_FALLENEMPIRE) > 0)
- flag = 1;
- break;
- case SR_FALLENEMPIRE:
- if (pc_checkskill(sd, SR_TIGERCANNON) > 0 || pc_checkskill(sd, SR_GATEOFHELL) > 0)
- flag = 1;
- break;
- } //Switch End
- if (flag) { //Possible to chain
- flag = DIFF_TICK(sd->ud.canact_tick, tick);
- if (flag < 1) flag = 1;
- sc_start2(src,SC_COMBO,100,skillid,bl->id,flag);
- clif_combo_delay(src, flag);
- }
- }
-
- //Display damage.
- switch (skillid) {
- case PA_GOSPEL: //Should look like Holy Cross [Skotlex]
- dmg.dmotion = clif_skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, CR_HOLYCROSS, -1, 5);
- break;
- //Skills that need be passed as a normal attack for the client to display correctly.
- case HVAN_EXPLOSION:
- case NPC_SELFDESTRUCTION:
- if (src->type==BL_PC)
- dmg.blewcount = 10;
- dmg.amotion = 0; //Disable delay or attack will do no damage since source is dead by the time it takes effect. [Skotlex]
- // fall through
- case KN_AUTOCOUNTER:
- case NPC_CRITICALSLASH:
- case TF_DOUBLE:
- case GS_CHAINACTION:
- dmg.dmotion = clif_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,dmg.type,dmg.damage2);
- break;
+ struct Damage dmg;
+ struct status_data *sstatus, *tstatus;
+ struct status_change *sc;
+ struct map_session_data *sd, *tsd;
+ int type,damage,rdamage=0;
+
+ if(skillid > 0 && skilllv <= 0) return 0;
+
+ nullpo_ret(src); //Source is the master behind the attack (player/mob/pet)
+ nullpo_ret(dsrc); //dsrc is the actual originator of the damage, can be the same as src, or a skill casted by src.
+ nullpo_ret(bl); //Target to be attacked.
+
+ if (src != dsrc) {
+ //When caster is not the src of attack, this is a ground skill, and as such, do the relevant target checking. [Skotlex]
+ if (!status_check_skilluse(battle_config.skill_caster_check?src:NULL, bl, skillid, 2))
+ return 0;
+ } else if ((flag&SD_ANIMATION) && skill_get_nk(skillid)&NK_SPLASH) {
+ //Note that splash attacks often only check versus the targetted mob, those around the splash area normally don't get checked for being hidden/cloaked/etc. [Skotlex]
+ if (!status_check_skilluse(src, bl, skillid, 2))
+ return 0;
+ }
- case AS_SPLASHER:
- if (flag&SD_ANIMATION) // the surrounding targets
- dmg.dmotion = clif_skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skillid, -1, 5); // needs -1 as skill level
- else // the central target doesn't display an animation
- dmg.dmotion = clif_skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skillid, -2, 5); // needs -2(!) as skill level
- break;
- case WL_HELLINFERNO:
- case SR_EARTHSHAKER:
- dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,skillid,-2,6);
- break;
- case WL_SOULEXPANSION:
- case WL_COMET:
- case KO_MUCHANAGE:
- case NJ_HUUMA:
- dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skillid,skilllv,8);
- break;
- case WL_CHAINLIGHTNING_ATK:
- dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,WL_CHAINLIGHTNING,-2,6);
- break;
- case LG_OVERBRAND_BRANDISH:
- case LG_OVERBRAND_PLUSATK:
- case EL_FIRE_BOMB:
- case EL_FIRE_BOMB_ATK:
- case EL_FIRE_WAVE:
- case EL_FIRE_WAVE_ATK:
- case EL_FIRE_MANTLE:
- case EL_CIRCLE_OF_FIRE:
- case EL_FIRE_ARROW:
- case EL_ICE_NEEDLE:
- case EL_WATER_SCREW:
- case EL_WATER_SCREW_ATK:
- case EL_WIND_SLASH:
- case EL_TIDAL_WEAPON:
- case EL_ROCK_CRUSHER:
- case EL_ROCK_CRUSHER_ATK:
- case EL_HURRICANE:
- case EL_HURRICANE_ATK:
- case EL_TYPOON_MIS:
- case EL_TYPOON_MIS_ATK:
- case KO_BAKURETSU:
- case GN_CRAZYWEED_ATK:
- dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skillid,-1,5);
- break;
- case GN_SLINGITEM_RANGEMELEEATK:
- dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,GN_SLINGITEM,-2,6);
- break;
- case EL_STONE_RAIN:
- dmg.dmotion = clif_skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skillid,-1,(flag&1)?8:5);
- break;
- case WM_SEVERE_RAINSTORM_MELEE:
- dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,WM_SEVERE_RAINSTORM,skilllv,5);
- break;
- case WM_REVERBERATION_MELEE:
- case WM_REVERBERATION_MAGIC:
- dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,WM_REVERBERATION,-2,6);
- break;
- case HT_CLAYMORETRAP:
- case HT_BLASTMINE:
- case HT_FLASHER:
- case HT_FREEZINGTRAP:
- case RA_CLUSTERBOMB:
- case RA_FIRINGTRAP:
- case RA_ICEBOUNDTRAP:
- dmg.dmotion = clif_skill_damage(src,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skillid,flag&SD_LEVEL?-1:skilllv, 5);
- if (dsrc != src) // avoid damage display redundancy
- break;
- case HT_LANDMINE:
- dmg.dmotion = clif_skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skillid, -1, type);
- break;
- case AB_DUPLELIGHT_MELEE:
- case AB_DUPLELIGHT_MAGIC:
- dmg.amotion = 300;/* makes the damage value not overlap with previous damage (when displayed by the client) */
- default:
- if (flag&SD_ANIMATION && dmg.div_ < 2) //Disabling skill animation doesn't works on multi-hit.
- type = 5;
- if (bl->type == BL_SKILL) {
- TBL_SKILL *su = (TBL_SKILL *)bl;
- if (su->group && skill_get_inf2(su->group->skill_id)&INF2_TRAP) // show damage on trap targets
- clif_skill_damage(src,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skillid, flag&SD_LEVEL?-1:skilllv, 5);
- }
- dmg.dmotion = clif_skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skillid, flag&SD_LEVEL?-1:skilllv, type);
- break;
- }
-
- map_freeblock_lock();
-
- if (damage > 0 && dmg.flag&BF_SKILL && tsd
- && pc_checkskill(tsd,RG_PLAGIARISM)
- && (!sc || !sc->data[SC_PRESERVE])
- && damage < tsd->battle_status.hp) {
- //Updated to not be able to copy skills if the blow will kill you. [Skotlex]
- int copy_skill = skillid;
- /**
- * Copy Referal: dummy skills should point to their source upon copying
- **/
- switch (skillid) {
- case AB_DUPLELIGHT_MELEE:
- case AB_DUPLELIGHT_MAGIC:
- copy_skill = AB_DUPLELIGHT;
- break;
- case WL_CHAINLIGHTNING_ATK:
- copy_skill = WL_CHAINLIGHTNING;
- break;
- case WM_REVERBERATION_MELEE:
- case WM_REVERBERATION_MAGIC:
- copy_skill = WM_REVERBERATION;
- break;
- case WM_SEVERE_RAINSTORM_MELEE:
- copy_skill = WM_SEVERE_RAINSTORM;
- break;
- case GN_CRAZYWEED_ATK:
- copy_skill = GN_CRAZYWEED;
- break;
- case GN_HELLS_PLANT_ATK:
- copy_skill = GN_HELLS_PLANT;
- break;
- case LG_OVERBRAND_BRANDISH:
- case LG_OVERBRAND_PLUSATK:
- copy_skill = LG_OVERBRAND;
- break;
- }
-
- if ((tsd->status.skill[copy_skill].id == 0 || tsd->status.skill[copy_skill].flag == SKILL_FLAG_PLAGIARIZED) &&
- can_copy(tsd,copy_skill,bl)) { // Split all the check into their own function [Aru]
- int lv;
- if (sc && sc->data[SC__REPRODUCE] && (lv = sc->data[SC__REPRODUCE]->val1)) {
- //Level dependent and limitation.
- lv = min(lv,skill_get_max(copy_skill));
- if (tsd->reproduceskill_id && tsd->status.skill[tsd->reproduceskill_id].flag == SKILL_FLAG_PLAGIARIZED) {
- tsd->status.skill[tsd->reproduceskill_id].id = 0;
- tsd->status.skill[tsd->reproduceskill_id].lv = 0;
- tsd->status.skill[tsd->reproduceskill_id].flag = 0;
- clif_deleteskill(tsd,tsd->reproduceskill_id);
- }
+ sd = BL_CAST(BL_PC, src);
+ tsd = BL_CAST(BL_PC, bl);
+
+ sstatus = status_get_status_data(src);
+ tstatus = status_get_status_data(bl);
+ sc= status_get_sc(bl);
+ if (sc && !sc->count) sc = NULL; //Don't need it.
+
+ // Is this check really needed? FrostNova won't hurt you if you step right where the caster is?
+ if(skillid == WZ_FROSTNOVA && dsrc->x == bl->x && dsrc->y == bl->y)
+ return 0;
+ //Trick Dead protects you from damage, but not from buffs and the like, hence it's placed here.
+ if (sc && sc->data[SC_TRICKDEAD] && !(sstatus->mode&MD_BOSS))
+ return 0;
+
+ dmg = battle_calc_attack(attack_type,src,bl,skillid,skilllv,flag&0xFFF);
+
+ //Skotlex: Adjusted to the new system
+ if(src->type==BL_PET)
+ { // [Valaris]
+ struct pet_data *pd = (TBL_PET*)src;
+ if (pd->a_skill && pd->a_skill->div_ && pd->a_skill->id == skillid)
+ {
+ int element = skill_get_ele(skillid, skilllv);
+ if (skillid == -1)
+ element = sstatus->rhw.ele;
+ if (element != ELE_NEUTRAL || !(battle_config.attack_attr_none&BL_PET))
+ dmg.damage=battle_attr_fix(src, bl, skilllv, element, tstatus->def_ele, tstatus->ele_lv);
+ else
+ dmg.damage= skilllv;
+ dmg.damage2=0;
+ dmg.div_= pd->a_skill->div_;
+ }
+ }
- tsd->reproduceskill_id = copy_skill;
- pc_setglobalreg(tsd, "REPRODUCE_SKILL", copy_skill);
- pc_setglobalreg(tsd, "REPRODUCE_SKILL_LV", lv);
-
- tsd->status.skill[copy_skill].id = copy_skill;
- tsd->status.skill[copy_skill].lv = lv;
- tsd->status.skill[copy_skill].flag = SKILL_FLAG_PLAGIARIZED;
- clif_addskill(tsd,copy_skill);
- } else {
- lv = skilllv;
- if (tsd->cloneskill_id && tsd->status.skill[tsd->cloneskill_id].flag == SKILL_FLAG_PLAGIARIZED) {
- tsd->status.skill[tsd->cloneskill_id].id = 0;
- tsd->status.skill[tsd->cloneskill_id].lv = 0;
- tsd->status.skill[tsd->cloneskill_id].flag = 0;
- clif_deleteskill(tsd,tsd->cloneskill_id);
- }
+ if( dmg.flag&BF_MAGIC && ( skillid != NPC_EARTHQUAKE || (battle_config.eq_single_target_reflectable && (flag&0xFFF) == 1) ) )
+ { // Earthquake on multiple targets is not counted as a target skill. [Inkfish]
+ if( (dmg.damage || dmg.damage2) && (type = skill_magic_reflect(src, bl, src==dsrc)) )
+ { //Magic reflection, switch caster/target
+ struct block_list *tbl = bl;
+ bl = src;
+ src = tbl;
+ sd = BL_CAST(BL_PC, src);
+ tsd = BL_CAST(BL_PC, bl);
+ sc = status_get_sc(bl);
+ if (sc && !sc->count)
+ sc = NULL; //Don't need it.
+ /* bugreport:2564 flag&2 disables double casting trigger */
+ flag |= 2;
+
+ //Spirit of Wizard blocks Kaite's reflection
+ if( type == 2 && sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_WIZARD )
+ { //Consume one Fragment per hit of the casted skill? [Skotlex]
+ type = tsd?pc_search_inventory (tsd, 7321):0;
+ if (type >= 0) {
+ if ( tsd ) pc_delitem(tsd, type, 1, 0, 1, LOG_TYPE_CONSUME);
+ dmg.damage = dmg.damage2 = 0;
+ dmg.dmg_lv = ATK_MISS;
+ sc->data[SC_SPIRIT]->val3 = skillid;
+ sc->data[SC_SPIRIT]->val4 = dsrc->id;
+ }
+ }
+ /**
+ * Official Magic Reflection Behavior : damage reflected depends on gears caster wears, not target
+ **/
+ #if MAGIC_REFLECTION_TYPE
+ if( dmg.dmg_lv != ATK_MISS )//Wiz SL cancelled and consumed fragment
+ dmg = battle_calc_attack(BF_MAGIC,bl,bl,skillid,skilllv,flag&0xFFF);
+ #endif
+ }
+ if(sc && sc->data[SC_MAGICROD] && src == dsrc) {
+ int sp = skill_get_sp(skillid,skilllv);
+ dmg.damage = dmg.damage2 = 0;
+ dmg.dmg_lv = ATK_MISS; //This will prevent skill additional effect from taking effect. [Skotlex]
+ sp = sp * sc->data[SC_MAGICROD]->val2 / 100;
+ if(skillid == WZ_WATERBALL && skilllv > 1)
+ sp = sp/((skilllv|1)*(skilllv|1)); //Estimate SP cost of a single water-ball
+ status_heal(bl, 0, sp, 2);
+ }
+ }
- if ((type = pc_checkskill(tsd,RG_PLAGIARISM)) < lv)
- lv = type;
+ damage = dmg.damage + dmg.damage2;
- tsd->cloneskill_id = copy_skill;
- pc_setglobalreg(tsd, "CLONE_SKILL", copy_skill);
- pc_setglobalreg(tsd, "CLONE_SKILL_LV", lv);
+ if( (skillid == AL_INCAGI || skillid == AL_BLESSING ||
+ skillid == CASH_BLESSING || skillid == CASH_INCAGI ||
+ skillid == MER_INCAGI || skillid == MER_BLESSING) && tsd->sc.data[SC_CHANGEUNDEAD] )
+ damage = 1;
- tsd->status.skill[skillid].id = copy_skill;
- tsd->status.skill[skillid].lv = lv;
- tsd->status.skill[skillid].flag = SKILL_FLAG_PLAGIARIZED;
- clif_addskill(tsd,skillid);
- }
- }
- }
-
- if (dmg.dmg_lv >= ATK_MISS && (type = skill_get_walkdelay(skillid, skilllv)) > 0) {
- //Skills with can't walk delay also stop normal attacking for that
- //duration when the attack connects. [Skotlex]
- struct unit_data *ud = unit_bl2ud(src);
- if (ud && DIFF_TICK(ud->attackabletime, tick + type) < 0)
- ud->attackabletime = tick + type;
- }
-
- if (!dmg.amotion) {
- //Instant damage
- if (!sc || (!sc->data[SC_DEVOTION] && skillid != CR_REFLECTSHIELD))
- status_fix_damage(src,bl,damage,dmg.dmotion); //Deal damage before knockback to allow stuff like firewall+storm gust combo.
- if (!status_isdead(bl))
- skill_additional_effect(src,bl,skillid,skilllv,dmg.flag,dmg.dmg_lv,tick);
- if (damage > 0) //Counter status effects [Skotlex]
- skill_counter_additional_effect(src,bl,skillid,skilllv,dmg.flag,tick);
- }
- // Hell Inferno burning status only starts if Fire part hits.
- if (skillid == WL_HELLINFERNO && dmg.damage > 0)
- sc_start4(bl,SC_BURNING,55+5*skilllv,skilllv,1000,src->id,0,skill_get_time(skillid,skilllv));
- // Apply knock back chance in SC_TRIANGLESHOT skill.
- else if (skillid == SC_TRIANGLESHOT && rnd()%100 > (1 + skilllv))
- dmg.blewcount = 0;
-
- //Only knockback if it's still alive, otherwise a "ghost" is left behind. [Skotlex]
- //Reflected spells do not bounce back (bl == dsrc since it only happens for direct skills)
- if (dmg.blewcount > 0 && bl!=dsrc && !status_isdead(bl)) {
- int direction = -1; // default
- switch (skillid) { //direction
- case MG_FIREWALL:
- case PR_SANCTUARY:
- case SC_TRIANGLESHOT:
- case LG_OVERBRAND:
- case SR_KNUCKLEARROW:
- case GN_WALLOFTHORN:
- case EL_FIRE_MANTLE:
- direction = unit_getdir(bl);// backwards
- break;
- // This ensures the storm randomly pushes instead of exactly a cell backwards per official mechanics.
- case WZ_STORMGUST:
- direction = rand()%8;
- break;
- case WL_CRIMSONROCK:
- direction = map_calc_dir(bl,skill_area_temp[4],skill_area_temp[5]);
- break;
-
- }
- //blown-specific handling
- switch (skillid) {
- case LG_OVERBRAND:
- if (skill_blown(dsrc,bl,dmg.blewcount,direction,0)) {
- short dir_x, dir_y;
- dir_x = dirx[(direction+4)%8];
- dir_y = diry[(direction+4)%8];
- if (map_getcell(bl->m, bl->x+dir_x, bl->y+dir_y, CELL_CHKNOPASS) != 0)
- skill_addtimerskill(src, tick + status_get_amotion(src), bl->id, 0, 0, LG_OVERBRAND_PLUSATK, skilllv, BF_WEAPON, flag);
- } else
- skill_addtimerskill(src, tick + status_get_amotion(src), bl->id, 0, 0, LG_OVERBRAND_PLUSATK, skilllv, BF_WEAPON, flag);
- break;
- case SR_KNUCKLEARROW:
- if (skill_blown(dsrc,bl,dmg.blewcount,direction,0) && !(flag&4)) {
- short dir_x, dir_y;
- dir_x = dirx[(direction+4)%8];
- dir_y = diry[(direction+4)%8];
- if (map_getcell(bl->m, bl->x+dir_x, bl->y+dir_y, CELL_CHKNOPASS) != 0)
- skill_addtimerskill(src, tick + 300 * ((flag&2) ? 1 : 2), bl->id, 0, 0, skillid, skilllv, BF_WEAPON, flag|4);
- }
- break;
- case GN_WALLOFTHORN:
- unit_stop_walking(bl,1);
- skill_blown(dsrc,bl,dmg.blewcount,direction, 0x2);
- clif_fixpos(bl);
- break;
- default:
- skill_blown(dsrc,bl,dmg.blewcount,direction, 0x0);
- if (!dmg.blewcount && bl->type == BL_SKILL && damage > 0) {
- TBL_SKILL *su = (TBL_SKILL *)bl;
- if (su->group && su->group->skill_id == HT_BLASTMINE)
- skill_blown(src, bl, 3, -1, 0);
- }
- break;
- }
- }
-
- //Delayed damage must be dealt after the knockback (it needs to know actual position of target)
- if (dmg.amotion)
- battle_delay_damage(tick, dmg.amotion,src,bl,dmg.flag,skillid,skilllv,damage,dmg.dmg_lv,dmg.dmotion);
-
- if (sc && sc->data[SC_DEVOTION] && skillid != PA_PRESSURE) {
- struct status_change_entry *sce = sc->data[SC_DEVOTION];
- struct block_list *d_bl = map_id2bl(sce->val1);
-
- if (d_bl && (
- (d_bl->type == BL_MER && ((TBL_MER *)d_bl)->master && ((TBL_MER *)d_bl)->master->bl.id == bl->id) ||
- (d_bl->type == BL_PC && ((TBL_PC *)d_bl)->devotion[sce->val2] == bl->id)
- ) && check_distance_bl(bl, d_bl, sce->val3)) {
- /**
- * Check for devotion and change targetted dmg.
- * [d_bl = paladin; bl = player; src = source of dmg]
- **/
- bool devo_flag = false; /* false = paladin devoing; true = player */
- if (src) {
- struct status_change *tsc;
- tsc = status_get_sc(src);
-
- /* Per official standards, following skills should reflect at the bl */
- if ((tsc->data[SC_KAITE] && attack_type == BF_MAGIC) ||
- (tsc->data[SC_REFLECTDAMAGE] && attack_type != BF_MAGIC)
- )
- devo_flag = true;
- }
+ if( damage > 0 && (( dmg.flag&BF_WEAPON && src != bl && ( src == dsrc || ( dsrc->type == BL_SKILL && ( skillid == SG_SUN_WARM || skillid == SG_MOON_WARM || skillid == SG_STAR_WARM ) ) ))
+ || (sc && sc->data[SC_REFLECTDAMAGE])) )
+ rdamage = battle_calc_return_damage(bl,src, &damage, dmg.flag, skillid);
- clif_damage(
- ((devo_flag) ? bl:d_bl),
- ((devo_flag) ? bl:d_bl), gettick(), 0, 0, damage, 0, 0, 0);
- status_fix_damage(
- ((devo_flag) ? bl:NULL),
- ((devo_flag) ? bl:d_bl), damage, 0);
- } else {
- status_change_end(bl, SC_DEVOTION, INVALID_TIMER);
- if (!dmg.amotion)
- status_fix_damage(src,bl,damage,dmg.dmotion);
- }
- }
-
- if (damage > 0 && !(tstatus->mode&MD_BOSS)) {
- if (skillid == RG_INTIMIDATE) {
- int rate = 50 + skilllv * 5;
- rate = rate + (status_get_lv(src) - status_get_lv(bl));
- if (rnd()%100 < rate)
- skill_addtimerskill(src,tick + 800,bl->id,0,0,skillid,skilllv,0,flag);
- } else if (skillid == SC_FATALMENACE)
- skill_addtimerskill(src,tick + 800,bl->id,skill_area_temp[4],skill_area_temp[5],skillid,skilllv,0,flag);
- }
-
- if (skillid == CR_GRANDCROSS || skillid == NPC_GRANDDARKNESS)
- dmg.flag |= BF_WEAPON;
-
- if (sd && src != bl && damage > 0 && (dmg.flag&BF_WEAPON ||
- (dmg.flag&BF_MISC && (skillid == RA_CLUSTERBOMB || skillid == RA_FIRINGTRAP || skillid == RA_ICEBOUNDTRAP || skillid == RK_DRAGONBREATH)))) {
- if (battle_config.left_cardfix_to_right)
- battle_drain(sd, bl, dmg.damage, dmg.damage, tstatus->race, tstatus->mode&MD_BOSS);
- else
- battle_drain(sd, bl, dmg.damage, dmg.damage2, tstatus->race, tstatus->mode&MD_BOSS);
- }
-
- if (rdamage > 0) {
- if (sc && sc->data[SC_REFLECTDAMAGE]) {
- if (src != bl) // Don't reflect your own damage (Grand Cross)
- map_foreachinshootrange(battle_damage_area,bl,skill_get_splash(LG_REFLECTDAMAGE,1),BL_CHAR,tick,bl,dmg.amotion,sstatus->dmotion,rdamage,tstatus->race);
- } else {
- if (dmg.amotion)
- battle_delay_damage(tick, dmg.amotion,bl,src,0,CR_REFLECTSHIELD,0,rdamage,ATK_DEF,0);
- else
- status_fix_damage(bl,src,rdamage,0);
- clif_damage(src,src,tick, dmg.amotion,0,rdamage,1,4,0); // in aegis damage reflected is shown in single hit.
- //Use Reflect Shield to signal this kind of skill trigger. [Skotlex]
- if (tsd && src != bl)
- battle_drain(tsd, src, rdamage, rdamage, sstatus->race, is_boss(src));
- skill_additional_effect(bl, src, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick);
- }
- }
- if (damage > 0) {
- /**
- * Post-damage effects
- **/
- switch (skillid) {
- case RK_CRUSHSTRIKE:
- skill_break_equip(src,EQP_WEAPON,2000,BCT_SELF); // 20% chance to destroy the weapon.
- break;
- case GC_VENOMPRESSURE: {
- struct status_change *ssc = status_get_sc(src);
- if (ssc && ssc->data[SC_POISONINGWEAPON] && rnd()%100 < 70 + 5*skilllv) {
- sc_start(bl,ssc->data[SC_POISONINGWEAPON]->val2,100,ssc->data[SC_POISONINGWEAPON]->val1,skill_get_time2(GC_POISONINGWEAPON, 1));
- status_change_end(src,SC_POISONINGWEAPON,INVALID_TIMER);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- }
- }
- break;
- case WM_METALICSOUND:
- status_zap(bl, 0, damage*100/(100*(110-pc_checkskill(sd,WM_LESSON)*10)));
- break;
- case SR_TIGERCANNON:
- status_zap(bl, 0, damage/10); // 10% of damage dealt
- break;
- }
- if (sd)
- skill_onskillusage(sd, bl, skillid, tick);
- }
-
- if (!(flag&2) &&
- (
- skillid == MG_COLDBOLT || skillid == MG_FIREBOLT || skillid == MG_LIGHTNINGBOLT
- ) &&
- (sc = status_get_sc(src)) &&
- sc->data[SC_DOUBLECAST] &&
- rnd() % 100 < sc->data[SC_DOUBLECAST]->val2) {
- // skill_addtimerskill(src, tick + dmg.div_*dmg.amotion, bl->id, 0, 0, skillid, skilllv, BF_MAGIC, flag|2);
- skill_addtimerskill(src, tick + dmg.amotion, bl->id, 0, 0, skillid, skilllv, BF_MAGIC, flag|2);
- }
-
- map_freeblock_unlock();
-
- return damage;
+ if( damage && sc && sc->data[SC_GENSOU] && dmg.flag&BF_MAGIC ){
+ struct block_list *nbl = NULL;
+ nbl = battle_getenemyarea(bl,bl->x,bl->y,2,BL_CHAR,bl->id);
+ if( nbl ){ // Only one target is chosen.
+ damage = damage / 2; // Deflect half of the damage to a target nearby
+ clif_skill_damage(bl, nbl, tick, status_get_amotion(src), 0, status_fix_damage(bl,nbl,damage,0), dmg.div_, OB_OBOROGENSOU_TRANSITION_ATK, -1, 6);
+ }
+ }
+
+ //Skill hit type
+ type=(skillid==0)?5:skill_get_hit(skillid);
+
+ if(damage < dmg.div_
+ //Only skills that knockback even when they miss. [Skotlex]
+ && skillid != CH_PALMSTRIKE)
+ dmg.blewcount = 0;
+
+ if(skillid == CR_GRANDCROSS||skillid == NPC_GRANDDARKNESS) {
+ if(battle_config.gx_disptype) dsrc = src;
+ if(src == bl) type = 4;
+ else flag|=SD_ANIMATION;
+ }
+ if(skillid == NJ_TATAMIGAESHI) {
+ dsrc = src; //For correct knockback.
+ flag|=SD_ANIMATION;
+ }
+
+ if(sd) {
+ int flag = 0; //Used to signal if this skill can be combo'ed later on.
+ struct status_change_entry *sce;
+ if ((sce = sd->sc.data[SC_COMBO])) {//End combo state after skill is invoked. [Skotlex]
+ switch (skillid) {
+ case TK_TURNKICK:
+ case TK_STORMKICK:
+ case TK_DOWNKICK:
+ case TK_COUNTER:
+ if (pc_famerank(sd->status.char_id,MAPID_TAEKWON)) {//Extend combo time.
+ sce->val1 = skillid; //Update combo-skill
+ sce->val3 = skillid;
+ if( sce->timer != INVALID_TIMER )
+ delete_timer(sce->timer, status_change_timer);
+ sce->timer = add_timer(tick+sce->val4, status_change_timer, src->id, SC_COMBO);
+ break;
+ }
+ unit_cancel_combo(src); // Cancel combo wait
+ break;
+ default:
+ if( src == dsrc ) // Ground skills are exceptions. [Inkfish]
+ status_change_end(src, SC_COMBO, INVALID_TIMER);
+ }
+ }
+ switch(skillid) {
+ case MO_TRIPLEATTACK:
+ if (pc_checkskill(sd, MO_CHAINCOMBO) > 0 || pc_checkskill(sd, SR_DRAGONCOMBO) > 0)
+ flag=1;
+ break;
+ case MO_CHAINCOMBO:
+ if(pc_checkskill(sd, MO_COMBOFINISH) > 0 && sd->spiritball > 0)
+ flag=1;
+ break;
+ case MO_COMBOFINISH:
+ if (sd->status.party_id>0) //bonus from SG_FRIEND [Komurka]
+ party_skill_check(sd, sd->status.party_id, MO_COMBOFINISH, skilllv);
+ if (pc_checkskill(sd, CH_TIGERFIST) > 0 && sd->spiritball > 0)
+ flag=1;
+ case CH_TIGERFIST:
+ if (!flag && pc_checkskill(sd, CH_CHAINCRUSH) > 0 && sd->spiritball > 1)
+ flag=1;
+ case CH_CHAINCRUSH:
+ if (!flag && pc_checkskill(sd, MO_EXTREMITYFIST) > 0 && sd->spiritball > 0 && sd->sc.data[SC_EXPLOSIONSPIRITS])
+ flag=1;
+ break;
+ case AC_DOUBLE:
+ if( (tstatus->race == RC_BRUTE || tstatus->race == RC_INSECT) && pc_checkskill(sd, HT_POWER))
+ {
+ //TODO: This code was taken from Triple Blows, is this even how it should be? [Skotlex]
+ sc_start2(src,SC_COMBO,100,HT_POWER,bl->id,2000);
+ clif_combo_delay(src,2000);
+ }
+ break;
+ case TK_COUNTER:
+ { //bonus from SG_FRIEND [Komurka]
+ int level;
+ if(sd->status.party_id>0 && (level = pc_checkskill(sd,SG_FRIEND)))
+ party_skill_check(sd, sd->status.party_id, TK_COUNTER,level);
+ }
+ break;
+ case SL_STIN:
+ case SL_STUN:
+ if (skilllv >= 7 && !sd->sc.data[SC_SMA])
+ sc_start(src,SC_SMA,100,skilllv,skill_get_time(SL_SMA, skilllv));
+ break;
+ case GS_FULLBUSTER:
+ //Can't attack nor use items until skill's delay expires. [Skotlex]
+ sd->ud.attackabletime = sd->canuseitem_tick = sd->ud.canact_tick;
+ break;
+ case SR_DRAGONCOMBO:
+ if( pc_checkskill(sd, SR_FALLENEMPIRE) > 0 )
+ flag = 1;
+ break;
+ case SR_FALLENEMPIRE:
+ if( pc_checkskill(sd, SR_TIGERCANNON) > 0 || pc_checkskill(sd, SR_GATEOFHELL) > 0 )
+ flag = 1;
+ break;
+ } //Switch End
+ if (flag) { //Possible to chain
+ flag = DIFF_TICK(sd->ud.canact_tick, tick);
+ if (flag < 1) flag = 1;
+ sc_start2(src,SC_COMBO,100,skillid,bl->id,flag);
+ clif_combo_delay(src, flag);
+ }
+ }
+
+ //Display damage.
+ switch( skillid )
+ {
+ case PA_GOSPEL: //Should look like Holy Cross [Skotlex]
+ dmg.dmotion = clif_skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, CR_HOLYCROSS, -1, 5);
+ break;
+ //Skills that need be passed as a normal attack for the client to display correctly.
+ case HVAN_EXPLOSION:
+ case NPC_SELFDESTRUCTION:
+ if(src->type==BL_PC)
+ dmg.blewcount = 10;
+ dmg.amotion = 0; //Disable delay or attack will do no damage since source is dead by the time it takes effect. [Skotlex]
+ // fall through
+ case KN_AUTOCOUNTER:
+ case NPC_CRITICALSLASH:
+ case TF_DOUBLE:
+ case GS_CHAINACTION:
+ dmg.dmotion = clif_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,dmg.type,dmg.damage2);
+ break;
+
+ case AS_SPLASHER:
+ if( flag&SD_ANIMATION ) // the surrounding targets
+ dmg.dmotion = clif_skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skillid, -1, 5); // needs -1 as skill level
+ else // the central target doesn't display an animation
+ dmg.dmotion = clif_skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skillid, -2, 5); // needs -2(!) as skill level
+ break;
+ case WL_HELLINFERNO:
+ case SR_EARTHSHAKER:
+ dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,skillid,-2,6);
+ break;
+ case WL_SOULEXPANSION:
+ case WL_COMET:
+ case KO_MUCHANAGE:
+ case NJ_HUUMA:
+ dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skillid,skilllv,8);
+ break;
+ case WL_CHAINLIGHTNING_ATK:
+ dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,WL_CHAINLIGHTNING,-2,6);
+ break;
+ case LG_OVERBRAND_BRANDISH:
+ case LG_OVERBRAND_PLUSATK:
+ case EL_FIRE_BOMB:
+ case EL_FIRE_BOMB_ATK:
+ case EL_FIRE_WAVE:
+ case EL_FIRE_WAVE_ATK:
+ case EL_FIRE_MANTLE:
+ case EL_CIRCLE_OF_FIRE:
+ case EL_FIRE_ARROW:
+ case EL_ICE_NEEDLE:
+ case EL_WATER_SCREW:
+ case EL_WATER_SCREW_ATK:
+ case EL_WIND_SLASH:
+ case EL_TIDAL_WEAPON:
+ case EL_ROCK_CRUSHER:
+ case EL_ROCK_CRUSHER_ATK:
+ case EL_HURRICANE:
+ case EL_HURRICANE_ATK:
+ case EL_TYPOON_MIS:
+ case EL_TYPOON_MIS_ATK:
+ case KO_BAKURETSU:
+ case GN_CRAZYWEED_ATK:
+ dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skillid,-1,5);
+ break;
+ case GN_SLINGITEM_RANGEMELEEATK:
+ dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,GN_SLINGITEM,-2,6);
+ break;
+ case EL_STONE_RAIN:
+ dmg.dmotion = clif_skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skillid,-1,(flag&1)?8:5);
+ break;
+ case WM_SEVERE_RAINSTORM_MELEE:
+ dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,WM_SEVERE_RAINSTORM,skilllv,5);
+ break;
+ case WM_REVERBERATION_MELEE:
+ case WM_REVERBERATION_MAGIC:
+ dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,WM_REVERBERATION,-2,6);
+ break;
+ case HT_CLAYMORETRAP:
+ case HT_BLASTMINE:
+ case HT_FLASHER:
+ case HT_FREEZINGTRAP:
+ case RA_CLUSTERBOMB:
+ case RA_FIRINGTRAP:
+ case RA_ICEBOUNDTRAP:
+ dmg.dmotion = clif_skill_damage(src,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skillid,flag&SD_LEVEL?-1:skilllv, 5);
+ if( dsrc != src ) // avoid damage display redundancy
+ break;
+ case HT_LANDMINE:
+ dmg.dmotion = clif_skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skillid, -1, type);
+ break;
+ case AB_DUPLELIGHT_MELEE:
+ case AB_DUPLELIGHT_MAGIC:
+ dmg.amotion = 300;/* makes the damage value not overlap with previous damage (when displayed by the client) */
+ default:
+ if( flag&SD_ANIMATION && dmg.div_ < 2 ) //Disabling skill animation doesn't works on multi-hit.
+ type = 5;
+ if( bl->type == BL_SKILL ){
+ TBL_SKILL *su = (TBL_SKILL*)bl;
+ if( su->group && skill_get_inf2(su->group->skill_id)&INF2_TRAP )// show damage on trap targets
+ clif_skill_damage(src,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skillid, flag&SD_LEVEL?-1:skilllv, 5);
+ }
+ dmg.dmotion = clif_skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skillid, flag&SD_LEVEL?-1:skilllv, type);
+ break;
+ }
+
+ map_freeblock_lock();
+
+ if(damage > 0 && dmg.flag&BF_SKILL && tsd
+ && pc_checkskill(tsd,RG_PLAGIARISM)
+ && (!sc || !sc->data[SC_PRESERVE])
+ && damage < tsd->battle_status.hp)
+ { //Updated to not be able to copy skills if the blow will kill you. [Skotlex]
+ int copy_skill = skillid;
+ /**
+ * Copy Referal: dummy skills should point to their source upon copying
+ **/
+ switch( skillid ) {
+ case AB_DUPLELIGHT_MELEE:
+ case AB_DUPLELIGHT_MAGIC:
+ copy_skill = AB_DUPLELIGHT;
+ break;
+ case WL_CHAINLIGHTNING_ATK:
+ copy_skill = WL_CHAINLIGHTNING;
+ break;
+ case WM_REVERBERATION_MELEE:
+ case WM_REVERBERATION_MAGIC:
+ copy_skill = WM_REVERBERATION;
+ break;
+ case WM_SEVERE_RAINSTORM_MELEE:
+ copy_skill = WM_SEVERE_RAINSTORM;
+ break;
+ case GN_CRAZYWEED_ATK:
+ copy_skill = GN_CRAZYWEED;
+ break;
+ case GN_HELLS_PLANT_ATK:
+ copy_skill = GN_HELLS_PLANT;
+ break;
+ case LG_OVERBRAND_BRANDISH:
+ case LG_OVERBRAND_PLUSATK:
+ copy_skill = LG_OVERBRAND;
+ break;
+ }
+
+ if ((tsd->status.skill[copy_skill].id == 0 || tsd->status.skill[copy_skill].flag == SKILL_FLAG_PLAGIARIZED) &&
+ can_copy(tsd,copy_skill,bl)) // Split all the check into their own function [Aru]
+ {
+ int lv;
+ if( sc && sc->data[SC__REPRODUCE] && (lv = sc->data[SC__REPRODUCE]->val1) ) {
+ //Level dependent and limitation.
+ lv = min(lv,skill_get_max(copy_skill));
+ if( tsd->reproduceskill_id && tsd->status.skill[tsd->reproduceskill_id].flag == SKILL_FLAG_PLAGIARIZED ) {
+ tsd->status.skill[tsd->reproduceskill_id].id = 0;
+ tsd->status.skill[tsd->reproduceskill_id].lv = 0;
+ tsd->status.skill[tsd->reproduceskill_id].flag = 0;
+ clif_deleteskill(tsd,tsd->reproduceskill_id);
+ }
+
+ tsd->reproduceskill_id = copy_skill;
+ pc_setglobalreg(tsd, "REPRODUCE_SKILL", copy_skill);
+ pc_setglobalreg(tsd, "REPRODUCE_SKILL_LV", lv);
+
+ tsd->status.skill[copy_skill].id = copy_skill;
+ tsd->status.skill[copy_skill].lv = lv;
+ tsd->status.skill[copy_skill].flag = SKILL_FLAG_PLAGIARIZED;
+ clif_addskill(tsd,copy_skill);
+ } else {
+ lv = skilllv;
+ if (tsd->cloneskill_id && tsd->status.skill[tsd->cloneskill_id].flag == SKILL_FLAG_PLAGIARIZED){
+ tsd->status.skill[tsd->cloneskill_id].id = 0;
+ tsd->status.skill[tsd->cloneskill_id].lv = 0;
+ tsd->status.skill[tsd->cloneskill_id].flag = 0;
+ clif_deleteskill(tsd,tsd->cloneskill_id);
+ }
+
+ if ((type = pc_checkskill(tsd,RG_PLAGIARISM)) < lv)
+ lv = type;
+
+ tsd->cloneskill_id = copy_skill;
+ pc_setglobalreg(tsd, "CLONE_SKILL", copy_skill);
+ pc_setglobalreg(tsd, "CLONE_SKILL_LV", lv);
+
+ tsd->status.skill[skillid].id = copy_skill;
+ tsd->status.skill[skillid].lv = lv;
+ tsd->status.skill[skillid].flag = SKILL_FLAG_PLAGIARIZED;
+ clif_addskill(tsd,skillid);
+ }
+ }
+ }
+
+ if (dmg.dmg_lv >= ATK_MISS && (type = skill_get_walkdelay(skillid, skilllv)) > 0)
+ { //Skills with can't walk delay also stop normal attacking for that
+ //duration when the attack connects. [Skotlex]
+ struct unit_data *ud = unit_bl2ud(src);
+ if (ud && DIFF_TICK(ud->attackabletime, tick + type) < 0)
+ ud->attackabletime = tick + type;
+ }
+
+ if( !dmg.amotion )
+ { //Instant damage
+ if( !sc || (!sc->data[SC_DEVOTION] && skillid != CR_REFLECTSHIELD) )
+ status_fix_damage(src,bl,damage,dmg.dmotion); //Deal damage before knockback to allow stuff like firewall+storm gust combo.
+ if( !status_isdead(bl) )
+ skill_additional_effect(src,bl,skillid,skilllv,dmg.flag,dmg.dmg_lv,tick);
+ if( damage > 0 ) //Counter status effects [Skotlex]
+ skill_counter_additional_effect(src,bl,skillid,skilllv,dmg.flag,tick);
+ }
+ // Hell Inferno burning status only starts if Fire part hits.
+ if( skillid == WL_HELLINFERNO && dmg.damage > 0 )
+ sc_start4(bl,SC_BURNING,55+5*skilllv,skilllv,1000,src->id,0,skill_get_time(skillid,skilllv));
+ // Apply knock back chance in SC_TRIANGLESHOT skill.
+ else if( skillid == SC_TRIANGLESHOT && rnd()%100 > (1 + skilllv) )
+ dmg.blewcount = 0;
+
+ //Only knockback if it's still alive, otherwise a "ghost" is left behind. [Skotlex]
+ //Reflected spells do not bounce back (bl == dsrc since it only happens for direct skills)
+ if (dmg.blewcount > 0 && bl!=dsrc && !status_isdead(bl)) {
+ int direction = -1; // default
+ switch(skillid) {//direction
+ case MG_FIREWALL:
+ case PR_SANCTUARY:
+ case SC_TRIANGLESHOT:
+ case LG_OVERBRAND:
+ case SR_KNUCKLEARROW:
+ case GN_WALLOFTHORN:
+ case EL_FIRE_MANTLE:
+ direction = unit_getdir(bl);// backwards
+ break;
+ // This ensures the storm randomly pushes instead of exactly a cell backwards per official mechanics.
+ case WZ_STORMGUST:
+ direction = rand()%8;
+ break;
+ case WL_CRIMSONROCK:
+ direction = map_calc_dir(bl,skill_area_temp[4],skill_area_temp[5]);
+ break;
+
+ }
+ //blown-specific handling
+ switch( skillid ) {
+ case LG_OVERBRAND:
+ if( skill_blown(dsrc,bl,dmg.blewcount,direction,0) ) {
+ short dir_x, dir_y;
+ dir_x = dirx[(direction+4)%8];
+ dir_y = diry[(direction+4)%8];
+ if( map_getcell(bl->m, bl->x+dir_x, bl->y+dir_y, CELL_CHKNOPASS) != 0 )
+ skill_addtimerskill(src, tick + status_get_amotion(src), bl->id, 0, 0, LG_OVERBRAND_PLUSATK, skilllv, BF_WEAPON, flag );
+ } else
+ skill_addtimerskill(src, tick + status_get_amotion(src), bl->id, 0, 0, LG_OVERBRAND_PLUSATK, skilllv, BF_WEAPON, flag );
+ break;
+ case SR_KNUCKLEARROW:
+ if( skill_blown(dsrc,bl,dmg.blewcount,direction,0) && !(flag&4) ) {
+ short dir_x, dir_y;
+ dir_x = dirx[(direction+4)%8];
+ dir_y = diry[(direction+4)%8];
+ if( map_getcell(bl->m, bl->x+dir_x, bl->y+dir_y, CELL_CHKNOPASS) != 0 )
+ skill_addtimerskill(src, tick + 300 * ((flag&2) ? 1 : 2), bl->id, 0, 0, skillid, skilllv, BF_WEAPON, flag|4);
+ }
+ break;
+ case GN_WALLOFTHORN:
+ unit_stop_walking(bl,1);
+ skill_blown(dsrc,bl,dmg.blewcount,direction, 0x2 );
+ clif_fixpos(bl);
+ break;
+ default:
+ skill_blown(dsrc,bl,dmg.blewcount,direction, 0x0 );
+ if ( !dmg.blewcount && bl->type == BL_SKILL && damage > 0 ){
+ TBL_SKILL *su = (TBL_SKILL*)bl;
+ if( su->group && su->group->skill_id == HT_BLASTMINE)
+ skill_blown(src, bl, 3, -1, 0);
+ }
+ break;
+ }
+ }
+
+ //Delayed damage must be dealt after the knockback (it needs to know actual position of target)
+ if (dmg.amotion)
+ battle_delay_damage(tick, dmg.amotion,src,bl,dmg.flag,skillid,skilllv,damage,dmg.dmg_lv,dmg.dmotion);
+
+ if( sc && sc->data[SC_DEVOTION] && skillid != PA_PRESSURE )
+ {
+ struct status_change_entry *sce = sc->data[SC_DEVOTION];
+ struct block_list *d_bl = map_id2bl(sce->val1);
+
+ if( d_bl && (
+ (d_bl->type == BL_MER && ((TBL_MER*)d_bl)->master && ((TBL_MER*)d_bl)->master->bl.id == bl->id) ||
+ (d_bl->type == BL_PC && ((TBL_PC*)d_bl)->devotion[sce->val2] == bl->id)
+ ) && check_distance_bl(bl, d_bl, sce->val3) )
+ {
+ /**
+ * Check for devotion and change targetted dmg.
+ * [d_bl = paladin; bl = player; src = source of dmg]
+ **/
+ bool devo_flag = false; /* false = paladin devoing; true = player */
+ if ( src )
+ {
+ struct status_change *tsc;
+ tsc = status_get_sc(src);
+
+ /* Per official standards, following skills should reflect at the bl */
+ if( (tsc->data[SC_KAITE] && attack_type == BF_MAGIC) ||
+ (tsc->data[SC_REFLECTDAMAGE] && attack_type != BF_MAGIC)
+ )
+ devo_flag = true;
+ }
+
+ clif_damage(
+ ( (devo_flag) ? bl:d_bl),
+ ( (devo_flag) ? bl:d_bl), gettick(), 0, 0, damage, 0, 0, 0);
+ status_fix_damage(
+ ( (devo_flag) ? bl:NULL),
+ ( (devo_flag) ? bl:d_bl), damage, 0);
+ }
+ else {
+ status_change_end(bl, SC_DEVOTION, INVALID_TIMER);
+ if( !dmg.amotion )
+ status_fix_damage(src,bl,damage,dmg.dmotion);
+ }
+ }
+
+ if(damage > 0 && !(tstatus->mode&MD_BOSS)) {
+ if( skillid == RG_INTIMIDATE ) {
+ int rate = 50 + skilllv * 5;
+ rate = rate + (status_get_lv(src) - status_get_lv(bl));
+ if(rnd()%100 < rate)
+ skill_addtimerskill(src,tick + 800,bl->id,0,0,skillid,skilllv,0,flag);
+ } else if( skillid == SC_FATALMENACE )
+ skill_addtimerskill(src,tick + 800,bl->id,skill_area_temp[4],skill_area_temp[5],skillid,skilllv,0,flag);
+ }
+
+ if(skillid == CR_GRANDCROSS || skillid == NPC_GRANDDARKNESS)
+ dmg.flag |= BF_WEAPON;
+
+ if( sd && src != bl && damage > 0 && ( dmg.flag&BF_WEAPON ||
+ (dmg.flag&BF_MISC && (skillid == RA_CLUSTERBOMB || skillid == RA_FIRINGTRAP || skillid == RA_ICEBOUNDTRAP || skillid == RK_DRAGONBREATH)) ) )
+ {
+ if (battle_config.left_cardfix_to_right)
+ battle_drain(sd, bl, dmg.damage, dmg.damage, tstatus->race, tstatus->mode&MD_BOSS);
+ else
+ battle_drain(sd, bl, dmg.damage, dmg.damage2, tstatus->race, tstatus->mode&MD_BOSS);
+ }
+
+ if( rdamage > 0 ) {
+ if( sc && sc->data[SC_REFLECTDAMAGE] ) {
+ if( src != bl )// Don't reflect your own damage (Grand Cross)
+ map_foreachinshootrange(battle_damage_area,bl,skill_get_splash(LG_REFLECTDAMAGE,1),BL_CHAR,tick,bl,dmg.amotion,sstatus->dmotion,rdamage,tstatus->race);
+ } else {
+ if( dmg.amotion )
+ battle_delay_damage(tick, dmg.amotion,bl,src,0,CR_REFLECTSHIELD,0,rdamage,ATK_DEF,0);
+ else
+ status_fix_damage(bl,src,rdamage,0);
+ clif_damage(src,src,tick, dmg.amotion,0,rdamage,1,4,0); // in aegis damage reflected is shown in single hit.
+ //Use Reflect Shield to signal this kind of skill trigger. [Skotlex]
+ if( tsd && src != bl )
+ battle_drain(tsd, src, rdamage, rdamage, sstatus->race, is_boss(src));
+ skill_additional_effect(bl, src, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick);
+ }
+ }
+ if( damage > 0 ) {
+ /**
+ * Post-damage effects
+ **/
+ switch( skillid ) {
+ case RK_CRUSHSTRIKE:
+ skill_break_equip(src,EQP_WEAPON,2000,BCT_SELF); // 20% chance to destroy the weapon.
+ break;
+ case GC_VENOMPRESSURE: {
+ struct status_change *ssc = status_get_sc(src);
+ if( ssc && ssc->data[SC_POISONINGWEAPON] && rnd()%100 < 70 + 5*skilllv ) {
+ sc_start(bl,ssc->data[SC_POISONINGWEAPON]->val2,100,ssc->data[SC_POISONINGWEAPON]->val1,skill_get_time2(GC_POISONINGWEAPON, 1));
+ status_change_end(src,SC_POISONINGWEAPON,INVALID_TIMER);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ }
+ }
+ break;
+ case WM_METALICSOUND:
+ status_zap(bl, 0, damage*100/(100*(110-pc_checkskill(sd,WM_LESSON)*10)));
+ break;
+ case SR_TIGERCANNON:
+ status_zap(bl, 0, damage/10); // 10% of damage dealt
+ break;
+ }
+ if( sd )
+ skill_onskillusage(sd, bl, skillid, tick);
+ }
+
+ if (!(flag&2) &&
+ (
+ skillid == MG_COLDBOLT || skillid == MG_FIREBOLT || skillid == MG_LIGHTNINGBOLT
+ ) &&
+ (sc = status_get_sc(src)) &&
+ sc->data[SC_DOUBLECAST] &&
+ rnd() % 100 < sc->data[SC_DOUBLECAST]->val2)
+ {
+// skill_addtimerskill(src, tick + dmg.div_*dmg.amotion, bl->id, 0, 0, skillid, skilllv, BF_MAGIC, flag|2);
+ skill_addtimerskill(src, tick + dmg.amotion, bl->id, 0, 0, skillid, skilllv, BF_MAGIC, flag|2);
+ }
+
+ map_freeblock_unlock();
+
+ return damage;
}
/*==========================================
@@ -2903,179 +2760,181 @@ int skill_attack(int attack_type, struct block_list *src, struct block_list *dsr
* then call func with source,target,skillid,skilllv,tick,flag
*------------------------------------------*/
typedef int (*SkillFunc)(struct block_list *, struct block_list *, int, int, unsigned int, int);
-int skill_area_sub(struct block_list *bl, va_list ap)
+int skill_area_sub (struct block_list *bl, va_list ap)
{
- struct block_list *src;
- int skill_id,skill_lv,flag;
- unsigned int tick;
- SkillFunc func;
-
- nullpo_ret(bl);
-
- src=va_arg(ap,struct block_list *);
- skill_id=va_arg(ap,int);
- skill_lv=va_arg(ap,int);
- tick=va_arg(ap,unsigned int);
- flag=va_arg(ap,int);
- func=va_arg(ap,SkillFunc);
-
- if (battle_check_target(src,bl,flag) > 0) {
- // several splash skills need this initial dummy packet to display correctly
- if (flag&SD_PREAMBLE && skill_area_temp[2] == 0)
- clif_skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
-
- if (flag&(SD_SPLASH|SD_PREAMBLE))
- skill_area_temp[2]++;
-
- return func(src,bl,skill_id,skill_lv,tick,flag);
- }
- return 0;
+ struct block_list *src;
+ int skill_id,skill_lv,flag;
+ unsigned int tick;
+ SkillFunc func;
+
+ nullpo_ret(bl);
+
+ src=va_arg(ap,struct block_list *);
+ skill_id=va_arg(ap,int);
+ skill_lv=va_arg(ap,int);
+ tick=va_arg(ap,unsigned int);
+ flag=va_arg(ap,int);
+ func=va_arg(ap,SkillFunc);
+
+ if(battle_check_target(src,bl,flag) > 0)
+ {
+ // several splash skills need this initial dummy packet to display correctly
+ if (flag&SD_PREAMBLE && skill_area_temp[2] == 0)
+ clif_skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+
+ if (flag&(SD_SPLASH|SD_PREAMBLE))
+ skill_area_temp[2]++;
+
+ return func(src,bl,skill_id,skill_lv,tick,flag);
+ }
+ return 0;
}
-static int skill_check_unit_range_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 skillid,g_skillid;
-
- unit = (struct skill_unit *)bl;
-
- if (bl->prev == NULL || bl->type != BL_SKILL)
- return 0;
-
- if (!unit->alive)
- return 0;
-
- skillid = va_arg(ap,int);
- g_skillid = unit->group->skill_id;
-
- switch (skillid) {
- case MH_STEINWAND:
- case MG_SAFETYWALL:
- case AL_PNEUMA:
- case SC_MAELSTROM:
- if (g_skillid != MH_STEINWAND && g_skillid != MG_SAFETYWALL && g_skillid != AL_PNEUMA && g_skillid != SC_MAELSTROM)
- return 0;
- break;
- case AL_WARP:
- case HT_SKIDTRAP:
- case MA_SKIDTRAP:
- case HT_LANDMINE:
- case MA_LANDMINE:
- case HT_ANKLESNARE:
- case HT_SHOCKWAVE:
- case HT_SANDMAN:
- case MA_SANDMAN:
- case HT_FLASHER:
- case HT_FREEZINGTRAP:
- case MA_FREEZINGTRAP:
- case HT_BLASTMINE:
- case HT_CLAYMORETRAP:
- case HT_TALKIEBOX:
- case HP_BASILICA:
- case RA_ELECTRICSHOCKER:
- case RA_CLUSTERBOMB:
- case RA_MAGENTATRAP:
- case RA_COBALTTRAP:
- case RA_MAIZETRAP:
- case RA_VERDURETRAP:
- case RA_FIRINGTRAP:
- case RA_ICEBOUNDTRAP:
- case SC_DIMENSIONDOOR:
- case SC_BLOODYLUST:
- //Non stackable on themselves and traps (including venom dust which does not has the trap inf2 set)
- if (skillid != g_skillid && !(skill_get_inf2(g_skillid)&INF2_TRAP) && g_skillid != AS_VENOMDUST && g_skillid != MH_POISON_MIST)
- return 0;
- break;
- default: //Avoid stacking with same kind of trap. [Skotlex]
- if (g_skillid != skillid)
- return 0;
- break;
- }
+ struct skill_unit *unit;
+ int skillid,g_skillid;
+
+ unit = (struct skill_unit *)bl;
+
+ if(bl->prev == NULL || bl->type != BL_SKILL)
+ return 0;
+
+ if(!unit->alive)
+ return 0;
+
+ skillid = va_arg(ap,int);
+ g_skillid = unit->group->skill_id;
+
+ switch (skillid) {
+ case MH_STEINWAND:
+ case MG_SAFETYWALL:
+ case AL_PNEUMA:
+ case SC_MAELSTROM:
+ if(g_skillid != MH_STEINWAND && g_skillid != MG_SAFETYWALL && g_skillid != AL_PNEUMA && g_skillid != SC_MAELSTROM)
+ return 0;
+ break;
+ case AL_WARP:
+ case HT_SKIDTRAP:
+ case MA_SKIDTRAP:
+ case HT_LANDMINE:
+ case MA_LANDMINE:
+ case HT_ANKLESNARE:
+ case HT_SHOCKWAVE:
+ case HT_SANDMAN:
+ case MA_SANDMAN:
+ case HT_FLASHER:
+ case HT_FREEZINGTRAP:
+ case MA_FREEZINGTRAP:
+ case HT_BLASTMINE:
+ case HT_CLAYMORETRAP:
+ case HT_TALKIEBOX:
+ case HP_BASILICA:
+ case RA_ELECTRICSHOCKER:
+ case RA_CLUSTERBOMB:
+ case RA_MAGENTATRAP:
+ case RA_COBALTTRAP:
+ case RA_MAIZETRAP:
+ case RA_VERDURETRAP:
+ case RA_FIRINGTRAP:
+ case RA_ICEBOUNDTRAP:
+ case SC_DIMENSIONDOOR:
+ case SC_BLOODYLUST:
+ //Non stackable on themselves and traps (including venom dust which does not has the trap inf2 set)
+ if (skillid != g_skillid && !(skill_get_inf2(g_skillid)&INF2_TRAP) && g_skillid != AS_VENOMDUST && g_skillid != MH_POISON_MIST)
+ return 0;
+ break;
+ default: //Avoid stacking with same kind of trap. [Skotlex]
+ if (g_skillid != skillid)
+ return 0;
+ break;
+ }
- return 1;
+ return 1;
}
-static int skill_check_unit_range(struct block_list *bl, int x, int y, int skillid, int skilllv)
+static int skill_check_unit_range (struct block_list *bl, int x, int y, int skillid, int skilllv)
{
- //Non players do not check for the skill's splash-trigger area.
- int range = bl->type==BL_PC?skill_get_unit_range(skillid, skilllv):0;
- int layout_type = skill_get_unit_layout_type(skillid,skilllv);
- if (layout_type==-1 || layout_type>MAX_SQUARE_LAYOUT) {
- ShowError("skill_check_unit_range: unsupported layout type %d for skill %d\n",layout_type,skillid);
- return 0;
- }
-
- range += layout_type;
- return map_foreachinarea(skill_check_unit_range_sub,bl->m,x-range,y-range,x+range,y+range,BL_SKILL,skillid);
+ //Non players do not check for the skill's splash-trigger area.
+ int range = bl->type==BL_PC?skill_get_unit_range(skillid, skilllv):0;
+ int layout_type = skill_get_unit_layout_type(skillid,skilllv);
+ if (layout_type==-1 || layout_type>MAX_SQUARE_LAYOUT) {
+ ShowError("skill_check_unit_range: unsupported layout type %d for skill %d\n",layout_type,skillid);
+ return 0;
+ }
+
+ range += layout_type;
+ return map_foreachinarea(skill_check_unit_range_sub,bl->m,x-range,y-range,x+range,y+range,BL_SKILL,skillid);
}
-static int skill_check_unit_range2_sub(struct block_list *bl, va_list ap)
+static int skill_check_unit_range2_sub (struct block_list *bl, va_list ap)
{
- int skillid;
+ int skillid;
- if (bl->prev == NULL)
- return 0;
+ if(bl->prev == NULL)
+ return 0;
- skillid = va_arg(ap,int);
+ skillid = va_arg(ap,int);
- if (status_isdead(bl) && skillid != AL_WARP)
- return 0;
+ if( status_isdead(bl) && skillid != AL_WARP )
+ return 0;
- if (skillid == HP_BASILICA && bl->type == BL_PC)
- return 0;
+ if( skillid == HP_BASILICA && bl->type == BL_PC )
+ return 0;
- if (skillid == AM_DEMONSTRATION && bl->type == BL_MOB && ((TBL_MOB *)bl)->class_ == MOBID_EMPERIUM)
- return 0; //Allow casting Bomb/Demonstration Right under emperium [Skotlex]
- return 1;
+ if( skillid == AM_DEMONSTRATION && bl->type == BL_MOB && ((TBL_MOB*)bl)->class_ == MOBID_EMPERIUM )
+ return 0; //Allow casting Bomb/Demonstration Right under emperium [Skotlex]
+ return 1;
}
-static int skill_check_unit_range2(struct block_list *bl, int x, int y, int skillid, int skilllv)
+static int skill_check_unit_range2 (struct block_list *bl, int x, int y, int skillid, int skilllv)
{
- int range, type;
+ int 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) {
+ ShowError("skill_check_unit_range2: unsupported layout type %d for skill %d\n",layout_type,skillid);
+ return 0;
+ }
+ range = skill_get_unit_range(skillid,skilllv) + layout_type;
+ }
+ break;
+ }
- 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) {
- ShowError("skill_check_unit_range2: unsupported layout type %d for skill %d\n",layout_type,skillid);
- return 0;
- }
- range = skill_get_unit_range(skillid,skilllv) + layout_type;
- }
- break;
- }
-
- // if the caster is a monster/NPC, only check for players
- // otherwise just check characters
- if (bl->type == BL_PC)
- type = BL_CHAR;
- else
- type = BL_PC;
-
- return map_foreachinarea(skill_check_unit_range2_sub, bl->m,
- x - range, y - range, x + range, y + range,
- type, skillid);
+ // if the caster is a monster/NPC, only check for players
+ // otherwise just check characters
+ if (bl->type == BL_PC)
+ type = BL_CHAR;
+ else
+ type = BL_PC;
+
+ return map_foreachinarea(skill_check_unit_range2_sub, bl->m,
+ x - range, y - range, x + range, y + range,
+ type, skillid);
}
-int skill_guildaura_sub(struct map_session_data *sd, int id, int strvit, int agidex)
+int skill_guildaura_sub (struct map_session_data* sd, int id, int strvit, int agidex)
{
- if (id == sd->bl.id && battle_config.guild_aura&16)
- return 0; // Do not affect guild leader
-
- if (sd->sc.data[SC_GUILDAURA]) {
- struct status_change_entry *sce = sd->sc.data[SC_GUILDAURA];
- if (sce->val3 != strvit || sce->val4 != agidex) {
- sce->val3 = strvit;
- sce->val4 = agidex;
- status_calc_bl(&sd->bl, status_sc2scb_flag(SC_GUILDAURA));
- }
- return 0;
- }
- sc_start4(&sd->bl, SC_GUILDAURA,100, 1, id, strvit, agidex, 1000);
- return 1;
+ if(id == sd->bl.id && battle_config.guild_aura&16)
+ return 0; // Do not affect guild leader
+
+ if (sd->sc.data[SC_GUILDAURA]) {
+ struct status_change_entry *sce = sd->sc.data[SC_GUILDAURA];
+ if( sce->val3 != strvit || sce->val4 != agidex ) {
+ sce->val3 = strvit;
+ sce->val4 = agidex;
+ status_calc_bl(&sd->bl, status_sc2scb_flag(SC_GUILDAURA));
+ }
+ return 0;
+ }
+ sc_start4(&sd->bl, SC_GUILDAURA,100, 1, id, strvit, agidex, 1000);
+ return 1;
}
/*==========================================
@@ -3086,118 +2945,125 @@ int skill_guildaura_sub(struct map_session_data *sd, int id, int strvit, int agi
*------------------------------------------*/
static int skill_check_condition_mercenary(struct block_list *bl, int skill, int lv, int type)
{
- struct status_data *status;
- struct map_session_data *sd = NULL;
- int i, j, hp, sp, hp_rate, sp_rate, state, mhp;
- int itemid[MAX_SKILL_ITEM_REQUIRE],amount[ARRAYLENGTH(itemid)],index[ARRAYLENGTH(itemid)];
-
- if (lv < 1 || lv > MAX_SKILL_LEVEL)
- return 0;
- nullpo_ret(bl);
-
- switch (bl->type) {
- case BL_HOM:
- sd = ((TBL_HOM *)bl)->master;
- break;
- case BL_MER:
- sd = ((TBL_MER *)bl)->master;
- break;
- }
-
- status = status_get_status_data(bl);
- if ((j = skill_get_index(skill)) == 0)
- return 0;
-
- // Requeriments
- for (i = 0; i < ARRAYLENGTH(itemid); i++) {
- itemid[i] = skill_db[j].itemid[i];
- amount[i] = skill_db[j].amount[i];
- }
- hp = skill_db[j].hp[lv-1];
- sp = skill_db[j].sp[lv-1];
- hp_rate = skill_db[j].hp_rate[lv-1];
- sp_rate = skill_db[j].sp_rate[lv-1];
- state = skill_db[j].state;
- if ((mhp = skill_db[j].mhp[lv-1]) > 0)
- hp += (status->max_hp * mhp) / 100;
- if (hp_rate > 0)
- hp += (status->hp * hp_rate) / 100;
- else
- hp += (status->max_hp * (-hp_rate)) / 100;
- if (sp_rate > 0)
- sp += (status->sp * sp_rate) / 100;
- else
- sp += (status->max_sp * (-sp_rate)) / 100;
-
- if (bl->type == BL_HOM) {
- // Intimacy Requeriments
- struct homun_data *hd = BL_CAST(BL_HOM, bl);
- switch (skill) {
- case HFLI_SBR44:
- if (hd->homunculus.intimacy <= 200)
- return 0;
- break;
- case HVAN_EXPLOSION:
- if (hd->homunculus.intimacy < (unsigned int)battle_config.hvan_explosion_intimate)
- return 0;
- break;
- }
- }
-
- if (!(type&2)) {
- if (hp > 0 && status->hp <= (unsigned int)hp) {
- clif_skill_fail(sd, skill, USESKILL_FAIL_HP_INSUFFICIENT, 0);
- return 0;
- }
- if (sp > 0 && status->sp <= (unsigned int)sp) {
- clif_skill_fail(sd, skill, USESKILL_FAIL_SP_INSUFFICIENT, 0);
- return 0;
- }
- }
-
- if (!type)
- switch (state) {
- case ST_MOVE_ENABLE:
- if (!unit_can_move(bl)) {
- clif_skill_fail(sd, skill, USESKILL_FAIL_LEVEL, 0);
- return 0;
- }
- break;
- }
- if (!(type&1))
- return 1;
-
- // Check item existences
- for (i = 0; i < ARRAYLENGTH(itemid); i++) {
- index[i] = -1;
- if (itemid[i] < 1) continue; // No item
- index[i] = pc_search_inventory(sd, itemid[i]);
- if (index[i] < 0 || sd->status.inventory[index[i]].amount < amount[i]) {
- clif_skill_fail(sd, skill, USESKILL_FAIL_LEVEL, 0);
- return 0;
- }
- }
-
- // Consume items
- for (i = 0; i < ARRAYLENGTH(itemid); i++) {
- if (index[i] >= 0) pc_delitem(sd, index[i], amount[i], 0, 1, LOG_TYPE_CONSUME);
- }
-
- if (type&2)
- return 1;
-
- if (sp || hp)
- status_zap(bl, hp, sp);
-
- return 1;
+ struct status_data *status;
+ struct map_session_data *sd = NULL;
+ int i, j, hp, sp, hp_rate, sp_rate, state, mhp;
+ int itemid[MAX_SKILL_ITEM_REQUIRE],amount[ARRAYLENGTH(itemid)],index[ARRAYLENGTH(itemid)];
+
+ if( lv < 1 || lv > MAX_SKILL_LEVEL )
+ return 0;
+ nullpo_ret(bl);
+
+ switch( bl->type )
+ {
+ case BL_HOM: sd = ((TBL_HOM*)bl)->master; break;
+ case BL_MER: sd = ((TBL_MER*)bl)->master; break;
+ }
+
+ status = status_get_status_data(bl);
+ if( (j = skill_get_index(skill)) == 0 )
+ return 0;
+
+ // Requeriments
+ for( i = 0; i < ARRAYLENGTH(itemid); i++ )
+ {
+ itemid[i] = skill_db[j].itemid[i];
+ amount[i] = skill_db[j].amount[i];
+ }
+ hp = skill_db[j].hp[lv-1];
+ sp = skill_db[j].sp[lv-1];
+ hp_rate = skill_db[j].hp_rate[lv-1];
+ sp_rate = skill_db[j].sp_rate[lv-1];
+ state = skill_db[j].state;
+ if( (mhp = skill_db[j].mhp[lv-1]) > 0 )
+ hp += (status->max_hp * mhp) / 100;
+ if( hp_rate > 0 )
+ hp += (status->hp * hp_rate) / 100;
+ else
+ hp += (status->max_hp * (-hp_rate)) / 100;
+ if( sp_rate > 0 )
+ sp += (status->sp * sp_rate) / 100;
+ else
+ sp += (status->max_sp * (-sp_rate)) / 100;
+
+ if( bl->type == BL_HOM )
+ { // Intimacy Requeriments
+ struct homun_data *hd = BL_CAST(BL_HOM, bl);
+ switch( skill )
+ {
+ case HFLI_SBR44:
+ if( hd->homunculus.intimacy <= 200 )
+ return 0;
+ break;
+ case HVAN_EXPLOSION:
+ if( hd->homunculus.intimacy < (unsigned int)battle_config.hvan_explosion_intimate )
+ return 0;
+ break;
+ }
+ }
+
+ if( !(type&2) )
+ {
+ if( hp > 0 && status->hp <= (unsigned int)hp )
+ {
+ clif_skill_fail(sd, skill, USESKILL_FAIL_HP_INSUFFICIENT, 0);
+ return 0;
+ }
+ if( sp > 0 && status->sp <= (unsigned int)sp )
+ {
+ clif_skill_fail(sd, skill, USESKILL_FAIL_SP_INSUFFICIENT, 0);
+ return 0;
+ }
+ }
+
+ if( !type )
+ switch( state )
+ {
+ case ST_MOVE_ENABLE:
+ if( !unit_can_move(bl) )
+ {
+ clif_skill_fail(sd, skill, USESKILL_FAIL_LEVEL, 0);
+ return 0;
+ }
+ break;
+ }
+ if( !(type&1) )
+ return 1;
+
+ // Check item existences
+ for( i = 0; i < ARRAYLENGTH(itemid); i++ )
+ {
+ index[i] = -1;
+ if( itemid[i] < 1 ) continue; // No item
+ index[i] = pc_search_inventory(sd, itemid[i]);
+ if( index[i] < 0 || sd->status.inventory[index[i]].amount < amount[i] )
+ {
+ clif_skill_fail(sd, skill, USESKILL_FAIL_LEVEL, 0);
+ return 0;
+ }
+ }
+
+ // Consume items
+ for( i = 0; i < ARRAYLENGTH(itemid); i++ )
+ {
+ if( index[i] >= 0 ) pc_delitem(sd, index[i], amount[i], 0, 1, LOG_TYPE_CONSUME);
+ }
+
+ if( type&2 )
+ return 1;
+
+ if( sp || hp )
+ status_zap(bl, hp, sp);
+
+ return 1;
}
/*==========================================
*
*------------------------------------------*/
-int skill_area_sub_count(struct block_list *src, struct block_list *target, int skillid, int skilllv, unsigned int tick, int flag)
+int skill_area_sub_count (struct block_list *src, struct block_list *target, int skillid, int skilllv, unsigned int tick, int flag)
{
- return 1;
+ return 1;
}
/*==========================================
@@ -3205,5922 +3071,5877 @@ int skill_area_sub_count(struct block_list *src, struct block_list *target, int
*------------------------------------------*/
static int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data)
{
- struct block_list *src = map_id2bl(id),*target;
- struct unit_data *ud = unit_bl2ud(src);
- struct skill_timerskill *skl = NULL;
- int range;
-
- nullpo_ret(src);
- nullpo_ret(ud);
- skl = ud->skilltimerskill[data];
- nullpo_ret(skl);
- ud->skilltimerskill[data] = NULL;
-
- do {
- if (src->prev == NULL)
- break; // Source not on Map
- if (skl->target_id) {
- target = map_id2bl(skl->target_id);
- if ((skl->skill_id == RG_INTIMIDATE || skl->skill_id == SC_FATALMENACE) && (!target || target->prev == NULL || !check_distance_bl(src,target,AREA_SIZE)))
- target = src; //Required since it has to warp.
- if (target == NULL)
- break; // Target offline?
- if (target->prev == NULL)
- break; // Target not on Map
- if (src->m != target->m)
- break; // Different Maps
- if (status_isdead(src))
- break; // Caster is Dead
- if (status_isdead(target) && skl->skill_id != RG_INTIMIDATE && skl->skill_id != WZ_WATERBALL)
- break;
-
- switch (skl->skill_id) {
- case RG_INTIMIDATE:
- if (unit_warp(src,-1,-1,-1,CLR_TELEPORT) == 0) {
- short x,y;
- map_search_freecell(src, 0, &x, &y, 1, 1, 0);
- if (target != src && !status_isdead(target))
- unit_warp(target, -1, x, y, CLR_TELEPORT);
- }
- break;
- case BA_FROSTJOKER:
- case DC_SCREAM:
- range= skill_get_splash(skl->skill_id, skl->skill_lv);
- map_foreachinarea(skill_frostjoke_scream,skl->map,skl->x-range,skl->y-range,
- skl->x+range,skl->y+range,BL_CHAR,src,skl->skill_id,skl->skill_lv,tick);
- break;
- case NPC_EARTHQUAKE:
- if (skl->type > 1)
- skill_addtimerskill(src,tick+250,src->id,0,0,skl->skill_id,skl->skill_lv,skl->type-1,skl->flag);
- skill_area_temp[0] = map_foreachinrange(skill_area_sub, src, skill_get_splash(skl->skill_id, skl->skill_lv), BL_CHAR, src, skl->skill_id, skl->skill_lv, tick, BCT_ENEMY, skill_area_sub_count);
- skill_area_temp[1] = src->id;
- skill_area_temp[2] = 0;
- map_foreachinrange(skill_area_sub, src, skill_get_splash(skl->skill_id, skl->skill_lv), splash_target(src), src, skl->skill_id, skl->skill_lv, tick, skl->flag, skill_castend_damage_id);
- break;
- case WZ_WATERBALL:
- skill_toggle_magicpower(src, skl->skill_id); // only the first hit will be amplify
- if (!status_isdead(target))
- skill_attack(BF_MAGIC,src,src,target,skl->skill_id,skl->skill_lv,tick,skl->flag);
- if (skl->type>1 && !status_isdead(target) && !status_isdead(src)) {
- skill_addtimerskill(src,tick+125,target->id,0,0,skl->skill_id,skl->skill_lv,skl->type-1,skl->flag);
- } else {
- struct status_change *sc = status_get_sc(src);
- if (sc) {
- if (sc->data[SC_SPIRIT] &&
- sc->data[SC_SPIRIT]->val2 == SL_WIZARD &&
- sc->data[SC_SPIRIT]->val3 == skl->skill_id)
- sc->data[SC_SPIRIT]->val3 = 0; //Clear bounced spell check.
- }
- }
- break;
- /**
- * Warlock
- **/
- case WL_CHAINLIGHTNING_ATK: {
- struct block_list *nbl = NULL; // Next Target of Chain
- skill_attack(BF_MAGIC,src,src,target,skl->skill_id,skl->skill_lv,tick,skl->flag); // Hit a Lightning on the current Target
- skill_toggle_magicpower(src, skl->skill_id); // only the first hit will be amplify
- if (skl->type > 1) {
- // Remaining Chains Hit
- nbl = battle_getenemyarea(src,target->x,target->y,2,BL_CHAR|BL_SKILL,target->id); // Search for a new Target around current one...
- if (nbl == NULL && skl->x > 1) {
- nbl = target;
- skl->x--;
- } else skl->x = 3;
- }
-
- if (nbl)
- skill_addtimerskill(src,tick+status_get_adelay(src),nbl->id,skl->x,0,WL_CHAINLIGHTNING_ATK,skl->skill_lv,skl->type-1,skl->flag);
- }
- break;
- case WL_TETRAVORTEX_FIRE:
- case WL_TETRAVORTEX_WATER:
- case WL_TETRAVORTEX_WIND:
- case WL_TETRAVORTEX_GROUND:
- skill_attack(BF_MAGIC,src,src,target,skl->skill_id,skl->skill_lv,tick,skl->flag|SD_ANIMATION);
- skill_toggle_magicpower(src, skl->skill_id); // only the first hit will be amplify
- if (skl->type >= 3) {
- // Final Hit
- if (!status_isdead(target)) {
- // Final Status Effect
- int effects[4] = { SC_BURNING, SC_FREEZING, SC_BLEEDING, SC_STUN },
- applyeffects[4] = { 0, 0, 0, 0 },
- i, j = 0, k = 0;
- for (i = 1; i <= 8; i = i + i) {
- if (skl->x&i) {
- applyeffects[j] = effects[k];
- j++;
- }
- k++;
- }
- if (j) {
- i = applyeffects[rnd()%j];
- status_change_start(target, i, 10000, skl->skill_lv,
- (i == SC_BURNING ? 1000 : 0),
- (i == SC_BURNING ? src->id : 0),
- 0, skill_get_time(WL_TETRAVORTEX,skl->skill_lv), 0);
- }
- }
- }
- break;
- case WM_REVERBERATION_MELEE:
- case WM_REVERBERATION_MAGIC:
- skill_castend_damage_id(src, target, skl->skill_id, skl->skill_lv, tick, skl->flag|SD_LEVEL); // damage should split among targets
- break;
- case SC_FATALMENACE:
- if (src == target) // Casters Part
- unit_warp(src, -1, skl->x, skl->y, 3);
- else { // Target's Part
- short x = skl->x, y = skl->y;
- map_search_freecell(NULL, target->m, &x, &y, 2, 2, 1);
- unit_warp(target,-1,x,y,3);
- }
- break;
- case LG_MOONSLASHER:
- case SR_WINDMILL:
- if (target->type == BL_PC) {
- struct map_session_data *tsd = NULL;
- if ((tsd = ((TBL_PC *)target)) && !pc_issit(tsd)) {
- pc_setsit(tsd);
- skill_sit(tsd,1);
- clif_sitting(&tsd->bl);
- }
- }
- break;
- case LG_OVERBRAND_BRANDISH:
- case LG_OVERBRAND_PLUSATK:
- case SR_KNUCKLEARROW:
- skill_attack(BF_WEAPON, src, src, target, skl->skill_id, skl->skill_lv, tick, skl->flag|SD_LEVEL);
- break;
- case GN_SPORE_EXPLOSION:
- map_foreachinrange(skill_area_sub, target, skill_get_splash(skl->skill_id, skl->skill_lv), BL_CHAR,
- src, skl->skill_id, skl->skill_lv, 0, skl->flag|1|BCT_ENEMY, skill_castend_damage_id);
- break;
- case CH_PALMSTRIKE: {
- struct status_change *tsc = status_get_sc(target);
- if (tsc && tsc->option&OPTION_HIDE) {
- skill_blown(src,target,skill_get_blewcount(skl->skill_id, skl->skill_lv), -1, 0x0);
- break;
- }
- }
- default:
- skill_attack(skl->type,src,src,target,skl->skill_id,skl->skill_lv,tick,skl->flag);
- break;
- }
- } else {
- if (src->m != skl->map)
- break;
- switch (skl->skill_id) {
- case WZ_METEOR:
- if (skl->type >= 0) {
- int x = skl->type>>16, y = skl->type&0xFFFF;
- if (path_search_long(NULL, src->m, src->x, src->y, x, y, CELL_CHKWALL))
- skill_unitsetting(src,skl->skill_id,skl->skill_lv,x,y,skl->flag);
- if (path_search_long(NULL, src->m, src->x, src->y, skl->x, skl->y, CELL_CHKWALL))
- clif_skill_poseffect(src,skl->skill_id,skl->skill_lv,skl->x,skl->y,tick);
- } else if (path_search_long(NULL, src->m, src->x, src->y, skl->x, skl->y, CELL_CHKWALL))
- skill_unitsetting(src,skl->skill_id,skl->skill_lv,skl->x,skl->y,skl->flag);
- break;
- case GN_CRAZYWEED_ATK: {
- int dummy = 1, i = skill_get_unit_range(skl->skill_id,skl->skill_lv);
- map_foreachinarea(skill_cell_overlap, src->m, skl->x-i, skl->y-i, skl->x+i, skl->y+i, BL_SKILL, skl->skill_id, &dummy, src);
- }
- case WL_EARTHSTRAIN:
- skill_unitsetting(src,skl->skill_id,skl->skill_lv,skl->x,skl->y,(skl->type<<16)|skl->flag);
- break;
+ struct block_list *src = map_id2bl(id),*target;
+ struct unit_data *ud = unit_bl2ud(src);
+ struct skill_timerskill *skl = NULL;
+ int range;
+
+ nullpo_ret(src);
+ nullpo_ret(ud);
+ skl = ud->skilltimerskill[data];
+ nullpo_ret(skl);
+ ud->skilltimerskill[data] = NULL;
+
+ do {
+ if(src->prev == NULL)
+ break; // Source not on Map
+ if(skl->target_id) {
+ target = map_id2bl(skl->target_id);
+ if( ( skl->skill_id == RG_INTIMIDATE || skl->skill_id == SC_FATALMENACE ) && (!target || target->prev == NULL || !check_distance_bl(src,target,AREA_SIZE)) )
+ target = src; //Required since it has to warp.
+ if(target == NULL)
+ break; // Target offline?
+ if(target->prev == NULL)
+ break; // Target not on Map
+ if(src->m != target->m)
+ break; // Different Maps
+ if(status_isdead(src))
+ break; // Caster is Dead
+ if(status_isdead(target) && skl->skill_id != RG_INTIMIDATE && skl->skill_id != WZ_WATERBALL)
+ break;
+
+ switch(skl->skill_id) {
+ case RG_INTIMIDATE:
+ if (unit_warp(src,-1,-1,-1,CLR_TELEPORT) == 0) {
+ short x,y;
+ map_search_freecell(src, 0, &x, &y, 1, 1, 0);
+ if (target != src && !status_isdead(target))
+ unit_warp(target, -1, x, y, CLR_TELEPORT);
+ }
+ break;
+ case BA_FROSTJOKER:
+ case DC_SCREAM:
+ range= skill_get_splash(skl->skill_id, skl->skill_lv);
+ map_foreachinarea(skill_frostjoke_scream,skl->map,skl->x-range,skl->y-range,
+ skl->x+range,skl->y+range,BL_CHAR,src,skl->skill_id,skl->skill_lv,tick);
+ break;
+ case NPC_EARTHQUAKE:
+ if( skl->type > 1 )
+ skill_addtimerskill(src,tick+250,src->id,0,0,skl->skill_id,skl->skill_lv,skl->type-1,skl->flag);
+ skill_area_temp[0] = map_foreachinrange(skill_area_sub, src, skill_get_splash(skl->skill_id, skl->skill_lv), BL_CHAR, src, skl->skill_id, skl->skill_lv, tick, BCT_ENEMY, skill_area_sub_count);
+ skill_area_temp[1] = src->id;
+ skill_area_temp[2] = 0;
+ map_foreachinrange(skill_area_sub, src, skill_get_splash(skl->skill_id, skl->skill_lv), splash_target(src), src, skl->skill_id, skl->skill_lv, tick, skl->flag, skill_castend_damage_id);
+ break;
+ case WZ_WATERBALL:
+ skill_toggle_magicpower(src, skl->skill_id); // only the first hit will be amplify
+ if (!status_isdead(target))
+ skill_attack(BF_MAGIC,src,src,target,skl->skill_id,skl->skill_lv,tick,skl->flag);
+ if (skl->type>1 && !status_isdead(target) && !status_isdead(src)) {
+ skill_addtimerskill(src,tick+125,target->id,0,0,skl->skill_id,skl->skill_lv,skl->type-1,skl->flag);
+ } else {
+ struct status_change *sc = status_get_sc(src);
+ if(sc) {
+ if(sc->data[SC_SPIRIT] &&
+ sc->data[SC_SPIRIT]->val2 == SL_WIZARD &&
+ sc->data[SC_SPIRIT]->val3 == skl->skill_id)
+ sc->data[SC_SPIRIT]->val3 = 0; //Clear bounced spell check.
+ }
+ }
+ break;
+ /**
+ * Warlock
+ **/
+ case WL_CHAINLIGHTNING_ATK:
+ {
+ struct block_list *nbl = NULL; // Next Target of Chain
+ skill_attack(BF_MAGIC,src,src,target,skl->skill_id,skl->skill_lv,tick,skl->flag); // Hit a Lightning on the current Target
+ skill_toggle_magicpower(src, skl->skill_id); // only the first hit will be amplify
+ if( skl->type > 1 )
+ { // Remaining Chains Hit
+ nbl = battle_getenemyarea(src,target->x,target->y,2,BL_CHAR|BL_SKILL,target->id); // Search for a new Target around current one...
+ if( nbl == NULL && skl->x > 1 )
+ {
+ nbl = target;
+ skl->x--;
+ }
+ else skl->x = 3;
+ }
+
+ if( nbl )
+ skill_addtimerskill(src,tick+status_get_adelay(src),nbl->id,skl->x,0,WL_CHAINLIGHTNING_ATK,skl->skill_lv,skl->type-1,skl->flag);
+ }
+ break;
+ case WL_TETRAVORTEX_FIRE:
+ case WL_TETRAVORTEX_WATER:
+ case WL_TETRAVORTEX_WIND:
+ case WL_TETRAVORTEX_GROUND:
+ skill_attack(BF_MAGIC,src,src,target,skl->skill_id,skl->skill_lv,tick,skl->flag|SD_ANIMATION);
+ skill_toggle_magicpower(src, skl->skill_id); // only the first hit will be amplify
+ if( skl->type >= 3 )
+ { // Final Hit
+ if( !status_isdead(target) )
+ { // Final Status Effect
+ int effects[4] = { SC_BURNING, SC_FREEZING, SC_BLEEDING, SC_STUN },
+ applyeffects[4] = { 0, 0, 0, 0 },
+ i, j = 0, k = 0;
+ for( i = 1; i <= 8; i = i + i )
+ {
+ if( skl->x&i )
+ {
+ applyeffects[j] = effects[k];
+ j++;
+ }
+ k++;
+ }
+ if( j )
+ {
+ i = applyeffects[rnd()%j];
+ status_change_start(target, i, 10000, skl->skill_lv,
+ (i == SC_BURNING ? 1000 : 0),
+ (i == SC_BURNING ? src->id : 0),
+ 0, skill_get_time(WL_TETRAVORTEX,skl->skill_lv), 0);
+ }
+ }
+ }
+ break;
+ case WM_REVERBERATION_MELEE:
+ case WM_REVERBERATION_MAGIC:
+ skill_castend_damage_id(src, target, skl->skill_id, skl->skill_lv, tick, skl->flag|SD_LEVEL); // damage should split among targets
+ break;
+ case SC_FATALMENACE:
+ if( src == target ) // Casters Part
+ unit_warp(src, -1, skl->x, skl->y, 3);
+ else { // Target's Part
+ short x = skl->x, y = skl->y;
+ map_search_freecell(NULL, target->m, &x, &y, 2, 2, 1);
+ unit_warp(target,-1,x,y,3);
+ }
+ break;
+ case LG_MOONSLASHER:
+ case SR_WINDMILL:
+ if( target->type == BL_PC ) {
+ struct map_session_data *tsd = NULL;
+ if( (tsd = ((TBL_PC*)target)) && !pc_issit(tsd) ) {
+ pc_setsit(tsd);
+ skill_sit(tsd,1);
+ clif_sitting(&tsd->bl);
+ }
+ }
+ break;
+ case LG_OVERBRAND_BRANDISH:
+ case LG_OVERBRAND_PLUSATK:
+ case SR_KNUCKLEARROW:
+ skill_attack(BF_WEAPON, src, src, target, skl->skill_id, skl->skill_lv, tick, skl->flag|SD_LEVEL);
+ break;
+ case GN_SPORE_EXPLOSION:
+ map_foreachinrange(skill_area_sub, target, skill_get_splash(skl->skill_id, skl->skill_lv), BL_CHAR,
+ src, skl->skill_id, skl->skill_lv, 0, skl->flag|1|BCT_ENEMY, skill_castend_damage_id);
+ break;
+ case CH_PALMSTRIKE:
+ {
+ struct status_change* tsc = status_get_sc(target);
+ if( tsc && tsc->option&OPTION_HIDE ){
+ skill_blown(src,target,skill_get_blewcount(skl->skill_id, skl->skill_lv), -1, 0x0 );
+ break;
+ }
+ }
+ default:
+ skill_attack(skl->type,src,src,target,skl->skill_id,skl->skill_lv,tick,skl->flag);
+ break;
+ }
+ }
+ else {
+ if(src->m != skl->map)
+ break;
+ switch( skl->skill_id )
+ {
+ case WZ_METEOR:
+ if( skl->type >= 0 )
+ {
+ int x = skl->type>>16, y = skl->type&0xFFFF;
+ if( path_search_long(NULL, src->m, src->x, src->y, x, y, CELL_CHKWALL) )
+ skill_unitsetting(src,skl->skill_id,skl->skill_lv,x,y,skl->flag);
+ if( path_search_long(NULL, src->m, src->x, src->y, skl->x, skl->y, CELL_CHKWALL) )
+ clif_skill_poseffect(src,skl->skill_id,skl->skill_lv,skl->x,skl->y,tick);
+ }
+ else if( path_search_long(NULL, src->m, src->x, src->y, skl->x, skl->y, CELL_CHKWALL) )
+ skill_unitsetting(src,skl->skill_id,skl->skill_lv,skl->x,skl->y,skl->flag);
+ break;
+ case GN_CRAZYWEED_ATK:
+ {
+ int dummy = 1, i = skill_get_unit_range(skl->skill_id,skl->skill_lv);
+ map_foreachinarea(skill_cell_overlap, src->m, skl->x-i, skl->y-i, skl->x+i, skl->y+i, BL_SKILL, skl->skill_id, &dummy, src);
+ }
+ case WL_EARTHSTRAIN:
+ skill_unitsetting(src,skl->skill_id,skl->skill_lv,skl->x,skl->y,(skl->type<<16)|skl->flag);
+ break;
- }
- }
- } while (0);
- //Free skl now that it is no longer needed.
- ers_free(skill_timer_ers, skl);
- return 0;
+ }
+ }
+ } while (0);
+ //Free skl now that it is no longer needed.
+ ers_free(skill_timer_ers, skl);
+ return 0;
}
/*==========================================
*
*------------------------------------------*/
-int skill_addtimerskill(struct block_list *src, unsigned int tick, int target, int x,int y, int skill_id, int skill_lv, int type, int flag)
+int skill_addtimerskill (struct block_list *src, unsigned int tick, int target, int x,int y, int skill_id, int skill_lv, int type, int flag)
{
- int i;
- struct unit_data *ud;
- nullpo_retr(1, src);
- if (src->prev == NULL)
- return 0;
- ud = unit_bl2ud(src);
- nullpo_retr(1, ud);
-
- ARR_FIND(0, MAX_SKILLTIMERSKILL, i, ud->skilltimerskill[i] == 0);
- if (i == MAX_SKILLTIMERSKILL) return 1;
-
- ud->skilltimerskill[i] = ers_alloc(skill_timer_ers, struct skill_timerskill);
- ud->skilltimerskill[i]->timer = add_timer(tick, skill_timerskill, src->id, i);
- ud->skilltimerskill[i]->src_id = src->id;
- ud->skilltimerskill[i]->target_id = target;
- ud->skilltimerskill[i]->skill_id = skill_id;
- ud->skilltimerskill[i]->skill_lv = skill_lv;
- ud->skilltimerskill[i]->map = src->m;
- ud->skilltimerskill[i]->x = x;
- ud->skilltimerskill[i]->y = y;
- ud->skilltimerskill[i]->type = type;
- ud->skilltimerskill[i]->flag = flag;
- return 0;
+ int i;
+ struct unit_data *ud;
+ nullpo_retr(1, src);
+ if (src->prev == NULL)
+ return 0;
+ ud = unit_bl2ud(src);
+ nullpo_retr(1, ud);
+
+ ARR_FIND( 0, MAX_SKILLTIMERSKILL, i, ud->skilltimerskill[i] == 0 );
+ if( i == MAX_SKILLTIMERSKILL ) return 1;
+
+ ud->skilltimerskill[i] = ers_alloc(skill_timer_ers, struct skill_timerskill);
+ ud->skilltimerskill[i]->timer = add_timer(tick, skill_timerskill, src->id, i);
+ ud->skilltimerskill[i]->src_id = src->id;
+ ud->skilltimerskill[i]->target_id = target;
+ ud->skilltimerskill[i]->skill_id = skill_id;
+ ud->skilltimerskill[i]->skill_lv = skill_lv;
+ ud->skilltimerskill[i]->map = src->m;
+ ud->skilltimerskill[i]->x = x;
+ ud->skilltimerskill[i]->y = y;
+ ud->skilltimerskill[i]->type = type;
+ ud->skilltimerskill[i]->flag = flag;
+ return 0;
}
/*==========================================
*
*------------------------------------------*/
-int skill_cleartimerskill(struct block_list *src)
+int skill_cleartimerskill (struct block_list *src)
{
- int i;
- struct unit_data *ud;
- nullpo_ret(src);
- ud = unit_bl2ud(src);
- nullpo_ret(ud);
-
- for (i=0; i<MAX_SKILLTIMERSKILL; i++) {
- if (ud->skilltimerskill[i]) {
- delete_timer(ud->skilltimerskill[i]->timer, skill_timerskill);
- ers_free(skill_timer_ers, ud->skilltimerskill[i]);
- ud->skilltimerskill[i]=NULL;
- }
- }
- return 1;
+ int i;
+ struct unit_data *ud;
+ nullpo_ret(src);
+ ud = unit_bl2ud(src);
+ nullpo_ret(ud);
+
+ for(i=0;i<MAX_SKILLTIMERSKILL;i++) {
+ if(ud->skilltimerskill[i]) {
+ delete_timer(ud->skilltimerskill[i]->timer, skill_timerskill);
+ ers_free(skill_timer_ers, ud->skilltimerskill[i]);
+ ud->skilltimerskill[i]=NULL;
+ }
+ }
+ return 1;
}
-static int skill_ative_reverberation(struct block_list *bl, va_list ap)
-{
- struct skill_unit *su = (TBL_SKILL *)bl;
- struct skill_unit_group *sg;
- if (bl->type != BL_SKILL)
- return 0;
- if (su->alive && (sg = su->group) && sg->skill_id == WM_REVERBERATION) {
- map_foreachinrange(skill_trap_splash, bl, skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, bl, gettick());
- su->limit=DIFF_TICK(gettick(),sg->tick);
- sg->unit_id = UNT_USED_TRAPS;
- }
- return 0;
+static int skill_ative_reverberation( struct block_list *bl, va_list ap) {
+ struct skill_unit *su = (TBL_SKILL*)bl;
+ struct skill_unit_group *sg;
+ if( bl->type != BL_SKILL )
+ return 0;
+ if( su->alive && (sg = su->group) && sg->skill_id == WM_REVERBERATION ) {
+ map_foreachinrange(skill_trap_splash, bl, skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, bl, gettick());
+ su->limit=DIFF_TICK(gettick(),sg->tick);
+ sg->unit_id = UNT_USED_TRAPS;
+ }
+ return 0;
}
-static int skill_reveal_trap(struct block_list *bl, va_list ap)
+static int skill_reveal_trap (struct block_list *bl, va_list ap)
{
- TBL_SKILL *su = (TBL_SKILL *)bl;
- if (su->alive && su->group && skill_get_inf2(su->group->skill_id)&INF2_TRAP) {
- //Reveal trap.
- //Change look is not good enough, the client ignores it as an actual trap still. [Skotlex]
- //clif_changetraplook(bl, su->group->unit_id);
- clif_skill_setunit(su);
- return 1;
- }
- return 0;
+ TBL_SKILL *su = (TBL_SKILL*)bl;
+ if (su->alive && su->group && skill_get_inf2(su->group->skill_id)&INF2_TRAP)
+ { //Reveal trap.
+ //Change look is not good enough, the client ignores it as an actual trap still. [Skotlex]
+ //clif_changetraplook(bl, su->group->unit_id);
+ clif_skill_setunit(su);
+ return 1;
+ }
+ return 0;
}
/*==========================================
*
*
*------------------------------------------*/
-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_data *tstatus;
- struct status_change *sc;
-
- if (skillid > 0 && skilllv <= 0) return 0;
-
- nullpo_retr(1, src);
- nullpo_retr(1, bl);
-
- if (src->m != bl->m)
- return 1;
-
- if (bl->prev == NULL)
- return 1;
-
- sd = BL_CAST(BL_PC, src);
-
- if (status_isdead(bl))
- return 1;
-
- if (skillid && skill_get_type(skillid) == BF_MAGIC && status_isimmune(bl) == 100) {
- //GTB makes all targetted magic display miss with a single bolt.
- sc_type sct = status_skill2sc(skillid);
- if (sct != SC_NONE)
- status_change_end(bl, sct, INVALID_TIMER);
- clif_skill_damage(src, bl, tick, status_get_amotion(src), status_get_dmotion(bl), 0, 1, skillid, skilllv, skill_get_hit(skillid));
- return 1;
- }
-
- sc = status_get_sc(src);
- if (sc && !sc->count)
- sc = NULL; //Unneeded
-
- tstatus = status_get_status_data(bl);
-
- map_freeblock_lock();
-
- switch (skillid) {
- case MER_CRASH:
- case SM_BASH:
- case MS_BASH:
- case MC_MAMMONITE:
- case TF_DOUBLE:
- case AC_DOUBLE:
- case MA_DOUBLE:
- case AS_SONICBLOW:
- case KN_PIERCE:
- case ML_PIERCE:
- case KN_SPEARBOOMERANG:
- case TF_POISON:
- case TF_SPRINKLESAND:
- case AC_CHARGEARROW:
- case MA_CHARGEARROW:
- case RG_INTIMIDATE:
- case AM_ACIDTERROR:
- case BA_MUSICALSTRIKE:
- case DC_THROWARROW:
- case BA_DISSONANCE:
- case CR_HOLYCROSS:
- case NPC_DARKCROSS:
- case CR_SHIELDCHARGE:
- case CR_SHIELDBOOMERANG:
- case NPC_PIERCINGATT:
- case NPC_MENTALBREAKER:
- case NPC_RANGEATTACK:
- case NPC_CRITICALSLASH:
- case NPC_COMBOATTACK:
- case NPC_GUIDEDATTACK:
- case NPC_POISON:
- case NPC_RANDOMATTACK:
- case NPC_WATERATTACK:
- case NPC_GROUNDATTACK:
- case NPC_FIREATTACK:
- case NPC_WINDATTACK:
- case NPC_POISONATTACK:
- case NPC_HOLYATTACK:
- case NPC_DARKNESSATTACK:
- case NPC_TELEKINESISATTACK:
- case NPC_UNDEADATTACK:
- case NPC_ARMORBRAKE:
- case NPC_WEAPONBRAKER:
- case NPC_HELMBRAKE:
- case NPC_SHIELDBRAKE:
- case NPC_BLINDATTACK:
- case NPC_SILENCEATTACK:
- case NPC_STUNATTACK:
- case NPC_PETRIFYATTACK:
- case NPC_CURSEATTACK:
- case NPC_SLEEPATTACK:
- case LK_AURABLADE:
- case LK_SPIRALPIERCE:
- case ML_SPIRALPIERCE:
- case LK_HEADCRUSH:
- case CG_ARROWVULCAN:
- case HW_MAGICCRASHER:
- case ITM_TOMAHAWK:
- case MO_TRIPLEATTACK:
- case CH_CHAINCRUSH:
- case CH_TIGERFIST:
- case PA_SHIELDCHAIN: // Shield Chain
- case PA_SACRIFICE:
- case WS_CARTTERMINATION: // Cart Termination
- case AS_VENOMKNIFE:
- case HT_PHANTASMIC:
- case HT_POWER:
- case TK_DOWNKICK:
- case TK_COUNTER:
- case GS_CHAINACTION:
- case GS_TRIPLEACTION:
- case GS_MAGICALBULLET:
- case GS_TRACKING:
- case GS_PIERCINGSHOT:
- case GS_RAPIDSHOWER:
- case GS_DUST:
- case GS_DISARM: // Added disarm. [Reddozen]
- case GS_FULLBUSTER:
- case NJ_SYURIKEN:
- case NJ_KUNAI:
- case ASC_BREAKER:
- case HFLI_MOON: //[orn]
- case HFLI_SBR44: //[orn]
- case NPC_BLEEDING:
- case NPC_CRITICALWOUND:
- case NPC_HELLPOWER:
- case RK_SONICWAVE:
- case RK_HUNDREDSPEAR:
- case AB_DUPLELIGHT_MELEE:
- case RA_AIMEDBOLT:
- case NC_AXEBOOMERANG:
- case NC_POWERSWING:
- case GC_CROSSIMPACT:
- case GC_VENOMPRESSURE:
- case SC_TRIANGLESHOT:
- case SC_FEINTBOMB:
- case LG_BANISHINGPOINT:
- case LG_SHIELDPRESS:
- case LG_RAGEBURST:
- case LG_RAYOFGENESIS:
- case LG_HESPERUSLIT:
- case SR_FALLENEMPIRE:
- case SR_CRESCENTELBOW_AUTOSPELL:
- case SR_GATEOFHELL:
- case SR_GENTLETOUCH_QUIET:
- case WM_SEVERE_RAINSTORM_MELEE:
- case WM_GREAT_ECHO:
- case GN_SLINGITEM_RANGEMELEEATK:
- case KO_JYUMONJIKIRI:
- case KO_SETSUDAN:
- case KO_KAIHOU:
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- break;
-
- /**
- * Mechanic (MADO GEAR)
- **/
- case NC_BOOSTKNUCKLE:
- case NC_PILEBUNKER:
- case NC_VULCANARM:
- case NC_COLDSLOWER:
- case NC_ARMSCANNON:
- if (sd) pc_overheat(sd,1);
- case RK_WINDCUTTER:
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag|SD_ANIMATION);
- break;
-
- case LK_JOINTBEAT: // decide the ailment first (affects attack damage and effect)
- switch (rnd()%6) {
- case 0:
- flag |= BREAK_ANKLE;
- break;
- case 1:
- flag |= BREAK_WRIST;
- break;
- case 2:
- flag |= BREAK_KNEE;
- break;
- case 3:
- flag |= BREAK_SHOULDER;
- break;
- case 4:
- flag |= BREAK_WAIST;
- break;
- case 5:
- flag |= BREAK_NECK;
- break;
- }
- //TODO: is there really no cleaner way to do this?
- sc = status_get_sc(bl);
- if (sc) sc->jb_flag = flag;
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- break;
+ struct map_session_data *sd = NULL;
+ struct status_data *tstatus;
+ struct status_change *sc;
- case MO_COMBOFINISH:
- if (!(flag&1) && sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_MONK) {
- //Becomes a splash attack when Soul Linked.
- map_foreachinrange(skill_area_sub, bl,
- skill_get_splash(skillid, skilllv),splash_target(src),
- src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
- skill_castend_damage_id);
- } else
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- break;
+ if (skillid > 0 && skilllv <= 0) return 0;
- case TK_STORMKICK: // Taekwon kicks [Dralnu]
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- skill_area_temp[1] = 0;
- map_foreachinrange(skill_attack_area, src,
- skill_get_splash(skillid, skilllv), splash_target(src),
- BF_WEAPON, src, src, skillid, skilllv, tick, flag, BCT_ENEMY);
- break;
+ nullpo_retr(1, src);
+ nullpo_retr(1, bl);
- case KN_CHARGEATK: {
- bool path = path_search_long(NULL, src->m, src->x, src->y, bl->x, bl->y,CELL_CHKWALL);
- unsigned int dist = distance_bl(src, bl);
- unsigned int dir = map_calc_dir(bl, src->x, src->y);
-
- // teleport to target (if not on WoE grounds)
- if (!map_flag_gvg(src->m) && !map[src->m].flag.battleground && unit_movepos(src, bl->x, bl->y, 0, 1))
- clif_slide(src, bl->x, bl->y);
-
- // cause damage and knockback if the path to target was a straight one
- if (path) {
- skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, dist);
- skill_blown(src, bl, dist, dir, 0);
- //HACK: since knockback officially defaults to the left, the client also turns to the left... therefore,
- // make the caster look in the direction of the target
- unit_setdir(src, (dir+4)%8);
- }
+ if (src->m != bl->m)
+ return 1;
- }
- break;
-
- case NC_FLAMELAUNCHER:
- if (sd) pc_overheat(sd,1);
- case SN_SHARPSHOOTING:
- case MA_SHARPSHOOTING:
- case NJ_KAMAITACHI:
- case LG_CANNONSPEAR:
- //It won't shoot through walls since on castend there has to be a direct
- //line of sight between caster and target.
- skill_area_temp[1] = bl->id;
- map_foreachinpath(skill_attack_area,src->m,src->x,src->y,bl->x,bl->y,
- skill_get_splash(skillid, skilllv),skill_get_maxcount(skillid,skilllv), splash_target(src),
- skill_get_type(skillid),src,src,skillid,skilllv,tick,flag,BCT_ENEMY);
- break;
+ if (bl->prev == NULL)
+ return 1;
- case NPC_ACIDBREATH:
- case NPC_DARKNESSBREATH:
- case NPC_FIREBREATH:
- case NPC_ICEBREATH:
- case NPC_THUNDERBREATH:
- skill_area_temp[1] = bl->id;
- map_foreachinpath(skill_attack_area,src->m,src->x,src->y,bl->x,bl->y,
- skill_get_splash(skillid, skilllv),skill_get_maxcount(skillid,skilllv), splash_target(src),
- skill_get_type(skillid),src,src,skillid,skilllv,tick,flag,BCT_ENEMY);
- break;
-
- case MO_INVESTIGATE:
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- status_change_end(src, SC_BLADESTOP, INVALID_TIMER);
- break;
-
- case RG_BACKSTAP: {
- int dir = map_calc_dir(src, bl->x, bl->y), t_dir = unit_getdir(bl);
- if ((!check_distance_bl(src, bl, 0) && !map_check_dir(dir, t_dir)) || bl->type == BL_SKILL) {
- status_change_end(src, SC_HIDING, INVALID_TIMER);
- skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag);
- dir = dir < 4 ? dir+4 : dir-4; // change direction [Celest]
- unit_setdir(bl,dir);
- } else if (sd)
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- }
- break;
+ sd = BL_CAST(BL_PC, src);
- case MO_FINGEROFFENSIVE:
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- if (battle_config.finger_offensive_type && sd) {
- int i;
- for (i = 1; i < sd->spiritball_old; i++)
- skill_addtimerskill(src, tick + i * 200, bl->id, 0, 0, skillid, skilllv, BF_WEAPON, flag);
- }
- status_change_end(src, SC_BLADESTOP, INVALID_TIMER);
- break;
+ if (status_isdead(bl))
+ return 1;
- case MO_CHAINCOMBO:
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- status_change_end(src, SC_BLADESTOP, INVALID_TIMER);
- break;
+ if (skillid && skill_get_type(skillid) == BF_MAGIC && status_isimmune(bl) == 100)
+ { //GTB makes all targetted magic display miss with a single bolt.
+ sc_type sct = status_skill2sc(skillid);
+ if(sct != SC_NONE)
+ status_change_end(bl, sct, INVALID_TIMER);
+ clif_skill_damage(src, bl, tick, status_get_amotion(src), status_get_dmotion(bl), 0, 1, skillid, skilllv, skill_get_hit(skillid));
+ return 1;
+ }
- case NJ_ISSEN:
- status_change_end(src, SC_NEN, INVALID_TIMER);
- status_change_end(src, SC_HIDING, INVALID_TIMER);
- // fall through
- case MO_EXTREMITYFIST:
- if (skillid == MO_EXTREMITYFIST) {
- status_change_end(src, SC_EXPLOSIONSPIRITS, INVALID_TIMER);
- status_change_end(src, SC_BLADESTOP, INVALID_TIMER);
+ sc = status_get_sc(src);
+ if (sc && !sc->count)
+ sc = NULL; //Unneeded
+
+ tstatus = status_get_status_data(bl);
+
+ map_freeblock_lock();
+
+ switch(skillid)
+ {
+ case MER_CRASH:
+ case SM_BASH:
+ case MS_BASH:
+ case MC_MAMMONITE:
+ case TF_DOUBLE:
+ case AC_DOUBLE:
+ case MA_DOUBLE:
+ case AS_SONICBLOW:
+ case KN_PIERCE:
+ case ML_PIERCE:
+ case KN_SPEARBOOMERANG:
+ case TF_POISON:
+ case TF_SPRINKLESAND:
+ case AC_CHARGEARROW:
+ case MA_CHARGEARROW:
+ case RG_INTIMIDATE:
+ case AM_ACIDTERROR:
+ case BA_MUSICALSTRIKE:
+ case DC_THROWARROW:
+ case BA_DISSONANCE:
+ case CR_HOLYCROSS:
+ case NPC_DARKCROSS:
+ case CR_SHIELDCHARGE:
+ case CR_SHIELDBOOMERANG:
+ case NPC_PIERCINGATT:
+ case NPC_MENTALBREAKER:
+ case NPC_RANGEATTACK:
+ case NPC_CRITICALSLASH:
+ case NPC_COMBOATTACK:
+ case NPC_GUIDEDATTACK:
+ case NPC_POISON:
+ case NPC_RANDOMATTACK:
+ case NPC_WATERATTACK:
+ case NPC_GROUNDATTACK:
+ case NPC_FIREATTACK:
+ case NPC_WINDATTACK:
+ case NPC_POISONATTACK:
+ case NPC_HOLYATTACK:
+ case NPC_DARKNESSATTACK:
+ case NPC_TELEKINESISATTACK:
+ case NPC_UNDEADATTACK:
+ case NPC_ARMORBRAKE:
+ case NPC_WEAPONBRAKER:
+ case NPC_HELMBRAKE:
+ case NPC_SHIELDBRAKE:
+ case NPC_BLINDATTACK:
+ case NPC_SILENCEATTACK:
+ case NPC_STUNATTACK:
+ case NPC_PETRIFYATTACK:
+ case NPC_CURSEATTACK:
+ case NPC_SLEEPATTACK:
+ case LK_AURABLADE:
+ case LK_SPIRALPIERCE:
+ case ML_SPIRALPIERCE:
+ case LK_HEADCRUSH:
+ case CG_ARROWVULCAN:
+ case HW_MAGICCRASHER:
+ case ITM_TOMAHAWK:
+ case MO_TRIPLEATTACK:
+ case CH_CHAINCRUSH:
+ case CH_TIGERFIST:
+ case PA_SHIELDCHAIN: // Shield Chain
+ case PA_SACRIFICE:
+ case WS_CARTTERMINATION: // Cart Termination
+ case AS_VENOMKNIFE:
+ case HT_PHANTASMIC:
+ case HT_POWER:
+ case TK_DOWNKICK:
+ case TK_COUNTER:
+ case GS_CHAINACTION:
+ case GS_TRIPLEACTION:
+ case GS_MAGICALBULLET:
+ case GS_TRACKING:
+ case GS_PIERCINGSHOT:
+ case GS_RAPIDSHOWER:
+ case GS_DUST:
+ case GS_DISARM: // Added disarm. [Reddozen]
+ case GS_FULLBUSTER:
+ case NJ_SYURIKEN:
+ case NJ_KUNAI:
+ case ASC_BREAKER:
+ case HFLI_MOON: //[orn]
+ case HFLI_SBR44: //[orn]
+ case NPC_BLEEDING:
+ case NPC_CRITICALWOUND:
+ case NPC_HELLPOWER:
+ case RK_SONICWAVE:
+ case RK_HUNDREDSPEAR:
+ case AB_DUPLELIGHT_MELEE:
+ case RA_AIMEDBOLT:
+ case NC_AXEBOOMERANG:
+ case NC_POWERSWING:
+ case GC_CROSSIMPACT:
+ case GC_VENOMPRESSURE:
+ case SC_TRIANGLESHOT:
+ case SC_FEINTBOMB:
+ case LG_BANISHINGPOINT:
+ case LG_SHIELDPRESS:
+ case LG_RAGEBURST:
+ case LG_RAYOFGENESIS:
+ case LG_HESPERUSLIT:
+ case SR_FALLENEMPIRE:
+ case SR_CRESCENTELBOW_AUTOSPELL:
+ case SR_GATEOFHELL:
+ case SR_GENTLETOUCH_QUIET:
+ case WM_SEVERE_RAINSTORM_MELEE:
+ case WM_GREAT_ECHO:
+ case GN_SLINGITEM_RANGEMELEEATK:
+ case KO_JYUMONJIKIRI:
+ case KO_SETSUDAN:
+ case KO_KAIHOU:
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+ break;
+
+ /**
+ * Mechanic (MADO GEAR)
+ **/
+ case NC_BOOSTKNUCKLE:
+ case NC_PILEBUNKER:
+ case NC_VULCANARM:
+ case NC_COLDSLOWER:
+ case NC_ARMSCANNON:
+ if (sd) pc_overheat(sd,1);
+ case RK_WINDCUTTER:
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag|SD_ANIMATION);
+ break;
+
+ case LK_JOINTBEAT: // decide the ailment first (affects attack damage and effect)
+ switch( rnd()%6 ){
+ case 0: flag |= BREAK_ANKLE; break;
+ case 1: flag |= BREAK_WRIST; break;
+ case 2: flag |= BREAK_KNEE; break;
+ case 3: flag |= BREAK_SHOULDER; break;
+ case 4: flag |= BREAK_WAIST; break;
+ case 5: flag |= BREAK_NECK; break;
+ }
+ //TODO: is there really no cleaner way to do this?
+ sc = status_get_sc(bl);
+ if (sc) sc->jb_flag = flag;
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+ break;
+
+ case MO_COMBOFINISH:
+ if (!(flag&1) && sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_MONK)
+ { //Becomes a splash attack when Soul Linked.
+ map_foreachinrange(skill_area_sub, bl,
+ skill_get_splash(skillid, skilllv),splash_target(src),
+ src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
+ skill_castend_damage_id);
+ } else
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+ break;
+
+ case TK_STORMKICK: // Taekwon kicks [Dralnu]
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ skill_area_temp[1] = 0;
+ map_foreachinrange(skill_attack_area, src,
+ skill_get_splash(skillid, skilllv), splash_target(src),
+ BF_WEAPON, src, src, skillid, skilllv, tick, flag, BCT_ENEMY);
+ break;
+
+ case KN_CHARGEATK:
+ {
+ bool path = path_search_long(NULL, src->m, src->x, src->y, bl->x, bl->y,CELL_CHKWALL);
+ unsigned int dist = distance_bl(src, bl);
+ unsigned int dir = map_calc_dir(bl, src->x, src->y);
+
+ // teleport to target (if not on WoE grounds)
+ if( !map_flag_gvg(src->m) && !map[src->m].flag.battleground && unit_movepos(src, bl->x, bl->y, 0, 1) )
+ clif_slide(src, bl->x, bl->y);
+
+ // cause damage and knockback if the path to target was a straight one
+ if( path )
+ {
+ skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, dist);
+ skill_blown(src, bl, dist, dir, 0);
+ //HACK: since knockback officially defaults to the left, the client also turns to the left... therefore,
+ // make the caster look in the direction of the target
+ unit_setdir(src, (dir+4)%8);
+ }
+
+ }
+ break;
+
+ case NC_FLAMELAUNCHER:
+ if (sd) pc_overheat(sd,1);
+ case SN_SHARPSHOOTING:
+ case MA_SHARPSHOOTING:
+ case NJ_KAMAITACHI:
+ case LG_CANNONSPEAR:
+ //It won't shoot through walls since on castend there has to be a direct
+ //line of sight between caster and target.
+ skill_area_temp[1] = bl->id;
+ map_foreachinpath (skill_attack_area,src->m,src->x,src->y,bl->x,bl->y,
+ skill_get_splash(skillid, skilllv),skill_get_maxcount(skillid,skilllv), splash_target(src),
+ skill_get_type(skillid),src,src,skillid,skilllv,tick,flag,BCT_ENEMY);
+ break;
+
+ case NPC_ACIDBREATH:
+ case NPC_DARKNESSBREATH:
+ case NPC_FIREBREATH:
+ case NPC_ICEBREATH:
+ case NPC_THUNDERBREATH:
+ skill_area_temp[1] = bl->id;
+ map_foreachinpath(skill_attack_area,src->m,src->x,src->y,bl->x,bl->y,
+ skill_get_splash(skillid, skilllv),skill_get_maxcount(skillid,skilllv), splash_target(src),
+ skill_get_type(skillid),src,src,skillid,skilllv,tick,flag,BCT_ENEMY);
+ break;
+
+ case MO_INVESTIGATE:
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+ status_change_end(src, SC_BLADESTOP, INVALID_TIMER);
+ break;
+
+ case RG_BACKSTAP:
+ {
+ int dir = map_calc_dir(src, bl->x, bl->y), t_dir = unit_getdir(bl);
+ if ((!check_distance_bl(src, bl, 0) && !map_check_dir(dir, t_dir)) || bl->type == BL_SKILL) {
+ status_change_end(src, SC_HIDING, INVALID_TIMER);
+ skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag);
+ dir = dir < 4 ? dir+4 : dir-4; // change direction [Celest]
+ unit_setdir(bl,dir);
+ }
+ else if (sd)
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ }
+ break;
+
+ case MO_FINGEROFFENSIVE:
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+ if (battle_config.finger_offensive_type && sd) {
+ int i;
+ for (i = 1; i < sd->spiritball_old; i++)
+ skill_addtimerskill(src, tick + i * 200, bl->id, 0, 0, skillid, skilllv, BF_WEAPON, flag);
+ }
+ status_change_end(src, SC_BLADESTOP, INVALID_TIMER);
+ break;
+
+ case MO_CHAINCOMBO:
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+ status_change_end(src, SC_BLADESTOP, INVALID_TIMER);
+ break;
+
+ case NJ_ISSEN:
+ status_change_end(src, SC_NEN, INVALID_TIMER);
+ status_change_end(src, SC_HIDING, INVALID_TIMER);
+ // fall through
+ case MO_EXTREMITYFIST:
+ if( skillid == MO_EXTREMITYFIST )
+ {
+ status_change_end(src, SC_EXPLOSIONSPIRITS, INVALID_TIMER);
+ status_change_end(src, SC_BLADESTOP, INVALID_TIMER);
#ifdef RENEWAL
- sc_start(src,SC_EXTREMITYFIST2,100,skilllv,skill_get_time(skillid,skilllv));
+ sc_start(src,SC_EXTREMITYFIST2,100,skilllv,skill_get_time(skillid,skilllv));
#endif
- }
- //Client expects you to move to target regardless of distance
- {
- struct unit_data *ud = unit_bl2ud(src);
- short dx,dy;
- int i,speed;
- i = skillid == MO_EXTREMITYFIST?1:2; //Move 2 cells for Issen, 1 for Asura
- dx = bl->x - src->x;
- dy = bl->y - src->y;
- if (dx < 0) dx-=i;
- else if (dx > 0) dx+=i;
- if (dy < 0) dy-=i;
- else if (dy > 0) dy+=i;
- if (!dx && !dy) dy++;
- if (map_getcell(src->m, src->x+dx, src->y+dy, CELL_CHKNOPASS)) {
- dx = bl->x;
- dy = bl->y;
- } else {
- dx = src->x + dx;
- dy = src->y + dy;
- }
-
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
-
- if (unit_walktoxy(src, dx, dy, 2) && ud) {
- //Increase can't walk delay to not alter your walk path
- ud->canmove_tick = tick;
- speed = status_get_speed(src);
- for (i = 0; i < ud->walkpath.path_len; i ++) {
- if (ud->walkpath.path[i]&1)
- ud->canmove_tick+=7*speed/5;
- else
- ud->canmove_tick+=speed;
- }
- }
- }
- break;
-
- //Splash attack skills.
- case AS_GRIMTOOTH:
- case MC_CARTREVOLUTION:
- case NPC_SPLASHATTACK:
- flag |= SD_PREAMBLE; // a fake packet will be sent for the first target to be hit
- case AS_SPLASHER:
- case SM_MAGNUM:
- case MS_MAGNUM:
- case HT_BLITZBEAT:
- case AC_SHOWER:
- case MA_SHOWER:
- case MG_NAPALMBEAT:
- case MG_FIREBALL:
- case RG_RAID:
- case HW_NAPALMVULCAN:
- case NJ_HUUMA:
- case NJ_BAKUENRYU:
- case ASC_METEORASSAULT:
- case GS_DESPERADO:
- case GS_SPREADATTACK:
- case NPC_EARTHQUAKE:
- case NPC_PULSESTRIKE:
- case NPC_HELLJUDGEMENT:
- case NPC_VAMPIRE_GIFT:
- case RK_IGNITIONBREAK:
- case AB_JUDEX:
- case WL_SOULEXPANSION:
- case WL_CRIMSONROCK:
- case WL_COMET:
- case WL_JACKFROST:
- case RA_ARROWSTORM:
- case RA_WUGDASH:
- case NC_SELFDESTRUCTION:
- case NC_AXETORNADO:
- case GC_ROLLINGCUTTER:
- case GC_COUNTERSLASH:
- case LG_MOONSLASHER:
- case LG_EARTHDRIVE:
- case SR_TIGERCANNON:
- case SR_RAMPAGEBLASTER:
- case SR_SKYNETBLOW:
- case SR_WINDMILL:
- case SR_RIDEINLIGHTNING:
- case WM_SOUND_OF_DESTRUCTION:
- case WM_REVERBERATION_MELEE:
- case WM_REVERBERATION_MAGIC:
- case SO_VARETYR_SPEAR:
- case GN_CART_TORNADO:
- case GN_CARTCANNON:
- case KO_HAPPOKUNAI:
- case KO_HUUMARANKA:
- case KO_MUCHANAGE:
- case KO_BAKURETSU:
- if (flag&1) { //Recursive invocation
- // skill_area_temp[0] holds number of targets in area
- // skill_area_temp[1] holds the id of the original target
- // skill_area_temp[2] counts how many targets have already been processed
- int sflag = skill_area_temp[0] & 0xFFF, heal;
- if (flag&SD_LEVEL)
- sflag |= SD_LEVEL; // -1 will be used in packets instead of the skill level
- if (skill_area_temp[1] != bl->id && !(skill_get_inf2(skillid)&INF2_NPC_SKILL))
- sflag |= SD_ANIMATION; // original target gets no animation (as well as all NPC skills)
-
- heal = skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, sflag);
- if (skillid == NPC_VAMPIRE_GIFT && heal > 0) {
- clif_skill_nodamage(NULL, src, AL_HEAL, heal, 1);
- status_heal(src,heal,0,0);
- }
- } else {
- switch (skillid) {
- case NJ_BAKUENRYU:
- case LG_EARTHDRIVE:
- case GN_CARTCANNON:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- break;
- case LG_MOONSLASHER:
- clif_skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
- break;
- case NPC_EARTHQUAKE://FIXME: Isn't EarthQuake a ground skill after all?
- skill_addtimerskill(src,tick+250,src->id,0,0,skillid,skilllv,2,flag|BCT_ENEMY|SD_SPLASH|1);
- default:
- break;
- }
-
- skill_area_temp[0] = 0;
- skill_area_temp[1] = bl->id;
- skill_area_temp[2] = 0;
- if (skillid == WL_CRIMSONROCK) {
- skill_area_temp[4] = bl->x;
- skill_area_temp[5] = bl->y;
- }
- if (skillid == WM_REVERBERATION_MELEE || skillid == WM_REVERBERATION_MAGIC)
- skill_area_temp[1] = 0;
- // if skill damage should be split among targets, count them
- //SD_LEVEL -> Forced splash damage for Auto Blitz-Beat -> count targets
- //special case: Venom Splasher uses a different range for searching than for splashing
- if (flag&SD_LEVEL || skill_get_nk(skillid)&NK_SPLASHSPLIT)
- skill_area_temp[0] = map_foreachinrange(skill_area_sub, bl, (skillid == AS_SPLASHER)?1:skill_get_splash(skillid, skilllv), BL_CHAR, src, skillid, skilllv, tick, BCT_ENEMY, skill_area_sub_count);
-
- // recursive invocation of skill_castend_damage_id() with flag|1
- map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), (skillid == WM_REVERBERATION_MELEE || skillid == WM_REVERBERATION_MAGIC)?BL_CHAR:splash_target(src), src, skillid, skilllv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill_castend_damage_id);
- }
- break;
-
- case KN_BRANDISHSPEAR:
- case ML_BRANDISH:
- //Coded apart for it needs the flag passed to the damage calculation.
- if (skill_area_temp[1] != bl->id)
- skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, flag|SD_ANIMATION);
- else
- skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, flag);
- break;
-
- case KN_BOWLINGBASH:
- case MS_BOWLINGBASH:
- if (flag&1) {
- if (bl->id==skill_area_temp[1])
- break;
- //two hits for 500%
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,SD_ANIMATION);
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,SD_ANIMATION);
- } else {
- int i,c;
- c = skill_get_blewcount(skillid,skilllv);
- // keep moving target in the direction that src is looking, square by square
- for (i=0; i<c; i++) {
- if (!skill_blown(src,bl,1,(unit_getdir(src)+4)%8,0x1))
- break; //Can't knockback
- skill_area_temp[0] = map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), BL_CHAR, src, skillid, skilllv, tick, flag|BCT_ENEMY, skill_area_sub_count);
- if (skill_area_temp[0] > 1) break; // collision
- }
- clif_blown(bl); //Update target pos.
- if (i!=c) { //Splash
- skill_area_temp[1] = bl->id;
- map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), splash_target(src), src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_damage_id);
- }
- //Weirdo dual-hit property, two attacks for 500%
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,0);
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,0);
- }
- break;
-
- case KN_SPEARSTAB:
- if (flag&1) {
- if (bl->id==skill_area_temp[1])
- break;
- if (skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,SD_ANIMATION))
- skill_blown(src,bl,skill_area_temp[2],-1,0);
- } else {
- int x=bl->x,y=bl->y,i,dir;
- dir = map_calc_dir(bl,src->x,src->y);
- skill_area_temp[1] = bl->id;
- skill_area_temp[2] = skill_get_blewcount(skillid,skilllv);
- // all the enemies between the caster and the target are hit, as well as the target
- if (skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,0))
- skill_blown(src,bl,skill_area_temp[2],-1,0);
- for (i=0; i<4; i++) {
- map_foreachincell(skill_area_sub,bl->m,x,y,BL_CHAR,
- src,skillid,skilllv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
- x += dirx[dir];
- y += diry[dir];
- }
- }
- break;
-
- case TK_TURNKICK:
- case MO_BALKYOUNG: { //Active part of the attack. Skill-attack [Skotlex]
- skill_area_temp[1] = bl->id; //NOTE: This is used in skill_castend_nodamage_id to avoid affecting the target.
- if (skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag))
- map_foreachinrange(skill_area_sub,bl,
- skill_get_splash(skillid, skilllv),BL_CHAR,
- src,skillid,skilllv,tick,flag|BCT_ENEMY|1,
- skill_castend_nodamage_id);
- }
- break;
- case CH_PALMSTRIKE: // Palm Strike takes effect 1sec after casting. [Skotlex]
- // clif_skill_nodamage(src,bl,skillid,skilllv,0); //Can't make this one display the correct attack animation delay :/
- clif_damage(src,bl,tick,status_get_amotion(src),0,-1,1,4,0); //Display an absorbed damage attack.
- skill_addtimerskill(src, tick + 1000, bl->id, 0, 0, skillid, skilllv, BF_WEAPON, flag);
- break;
-
- case PR_TURNUNDEAD:
- case ALL_RESURRECTION:
- if (!battle_check_undead(tstatus->race, tstatus->def_ele))
- break;
- skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag);
- break;
-
- case MG_SOULSTRIKE:
- case NPC_DARKSTRIKE:
- case MG_COLDBOLT:
- case MG_FIREBOLT:
- case MG_LIGHTNINGBOLT:
- case WZ_EARTHSPIKE:
- case AL_HEAL:
- case AL_HOLYLIGHT:
- case WZ_JUPITEL:
- case NPC_DARKTHUNDER:
- case PR_ASPERSIO:
- case MG_FROSTDIVER:
- case WZ_SIGHTBLASTER:
- case WZ_SIGHTRASHER:
- case NJ_KOUENKA:
- case NJ_HYOUSENSOU:
- case NJ_HUUJIN:
- case AB_ADORAMUS:
- case AB_RENOVATIO:
- case AB_HIGHNESSHEAL:
- case AB_DUPLELIGHT_MAGIC:
- case WM_METALICSOUND:
- case MH_ERASER_CUTTER:
- skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag);
- break;
-
- case NPC_MAGICALATTACK:
- skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag);
- sc_start(src,status_skill2sc(skillid),100,skilllv,skill_get_time(skillid,skilllv));
- break;
-
- case HVAN_CAPRICE: { //[blackhole89]
- int ran=rnd()%4;
- int sid = 0;
- switch (ran) {
- case 0:
- sid=MG_COLDBOLT;
- break;
- case 1:
- sid=MG_FIREBOLT;
- break;
- case 2:
- sid=MG_LIGHTNINGBOLT;
- break;
- case 3:
- sid=WZ_EARTHSPIKE;
- break;
- }
- skill_attack(BF_MAGIC,src,src,bl,sid,skilllv,tick,flag|SD_LEVEL);
- }
- break;
- case WZ_WATERBALL: {
- int range = skilllv / 2;
- int maxlv = skill_get_max(skillid); // learnable level
- int count = 0;
- int x, y;
- struct skill_unit *unit;
-
- if (skilllv > maxlv) {
- if (src->type == BL_MOB && skilllv == 10)
- range = 4;
- else
- range = maxlv / 2;
- }
-
- for (y = src->y - range; y <= src->y + range; ++y)
- for (x = src->x - range; x <= src->x + range; ++x) {
- if (!map_find_skill_unit_oncell(src,x,y,SA_LANDPROTECTOR,NULL,1)) {
- if (src->type != BL_PC || map_getcell(src->m,x,y,CELL_CHKWATER)) // non-players bypass the water requirement
- count++; // natural water cell
- else if ((unit = map_find_skill_unit_oncell(src,x,y,SA_DELUGE,NULL,1)) != NULL || (unit = map_find_skill_unit_oncell(src,x,y,NJ_SUITON,NULL,1)) != NULL) {
- count++; // skill-induced water cell
- skill_delunit(unit); // consume cell
- }
- }
- }
-
- if (count > 1) // queue the remaining count - 1 timerskill Waterballs
- skill_addtimerskill(src,tick+150,bl->id,0,0,skillid,skilllv,count-1,flag);
- }
- skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag);
- break;
-
- case PR_BENEDICTIO:
- //Should attack undead and demons. [Skotlex]
- if (battle_check_undead(tstatus->race, tstatus->def_ele) || tstatus->race == RC_DEMON)
- skill_attack(BF_MAGIC, src, src, bl, skillid, skilllv, tick, flag);
- break;
-
- case SL_SMA:
- status_change_end(src, SC_SMA, INVALID_TIMER);
- case SL_STIN:
- case SL_STUN:
- if (sd && !battle_config.allow_es_magic_pc && bl->type != BL_MOB) {
- status_change_start(src,SC_STUN,10000,skilllv,0,0,0,500,10);
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
- skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag);
- break;
-
- case NPC_DARKBREATH:
- clif_emotion(src,E_AG);
- case SN_FALCONASSAULT:
- case PA_PRESSURE:
- case CR_ACIDDEMONSTRATION:
- case TF_THROWSTONE:
- case NPC_SMOKING:
- case GS_FLING:
- case NJ_ZENYNAGE:
- case GN_THORNS_TRAP:
- case GN_HELLS_PLANT_ATK:
- skill_attack(BF_MISC,src,src,bl,skillid,skilllv,tick,flag);
- break;
- /**
- * Rune Knight
- **/
- case RK_DRAGONBREATH: {
- struct status_change *tsc = NULL;
- if ((tsc = status_get_sc(bl)) && (tsc->data[SC_HIDING])) {
- clif_skill_nodamage(src,src,skillid,skilllv,1);
- } else
- skill_attack(BF_MISC,src,src,bl,skillid,skilllv,tick,flag);
- }
- break;
-
- case NPC_SELFDESTRUCTION: {
- struct status_change *tsc = NULL;
- if ((tsc = status_get_sc(bl)) && tsc->data[SC_HIDING])
- break;
- }
- case HVAN_EXPLOSION:
- if (src != bl)
- skill_attack(BF_MISC,src,src,bl,skillid,skilllv,tick,flag);
- break;
-
- // Celest
- case PF_SOULBURN:
- if (rnd()%100 < (skilllv < 5 ? 30 + skilllv * 10 : 70)) {
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if (skilllv == 5)
- skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag);
- status_percent_damage(src, bl, 0, 100, false);
- } else {
- clif_skill_nodamage(src,src,skillid,skilllv,1);
- if (skilllv == 5)
- skill_attack(BF_MAGIC,src,src,src,skillid,skilllv,tick,flag);
- status_percent_damage(src, src, 0, 100, false);
- }
- break;
-
- case NPC_BLOODDRAIN:
- case NPC_ENERGYDRAIN: {
- int heal = skill_attack((skillid == NPC_BLOODDRAIN) ? BF_WEAPON : BF_MAGIC,
- src, src, bl, skillid, skilllv, tick, flag);
- if (heal > 0) {
- clif_skill_nodamage(NULL, src, AL_HEAL, heal, 1);
- status_heal(src, heal, 0, 0);
- }
- }
- break;
-
- case GS_BULLSEYE:
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- break;
-
- case NJ_KASUMIKIRI:
- if (skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag) > 0)
- sc_start(src,SC_HIDING,100,skilllv,skill_get_time(skillid,skilllv));
- break;
- case NJ_KIRIKAGE:
- if (!map_flag_gvg(src->m) && !map[src->m].flag.battleground) {
- //You don't move on GVG grounds.
- short x, y;
- map_search_freecell(bl, 0, &x, &y, 1, 1, 0);
- if (unit_movepos(src, x, y, 0, 0))
- clif_slide(src,src->x,src->y);
- }
- status_change_end(src, SC_HIDING, INVALID_TIMER);
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- break;
- case RK_PHANTOMTHRUST:
- unit_setdir(src,map_calc_dir(src, bl->x, bl->y));
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
-
- skill_blown(src,bl,distance_bl(src,bl)-1,unit_getdir(src),0);
- if (battle_check_target(src,bl,BCT_ENEMY))
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- break;
-
- case RK_STORMBLAST:
- case RK_CRUSHSTRIKE:
- if (sd) {
- if (pc_checkskill(sd,RK_RUNEMASTERY) >= (skillid == RK_CRUSHSTRIKE ? 7 : 3))
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- else
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- } else //non-sd support
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- break;
- case GC_DARKILLUSION: {
- short x, y;
- short dir = map_calc_dir(src,bl->x,bl->y);
-
- if (dir > 4) x = -1;
- else if (dir > 0 && dir < 4) x = 1;
- else x = 0;
- if (dir < 3 || dir > 5) y = -1;
- else if (dir > 3 && dir < 5) y = 1;
- else y = 0;
-
- if (unit_movepos(src, bl->x+x, bl->y+y, 1, 1)) {
- clif_slide(src,bl->x+x,bl->y+y);
- clif_fixpos(src); // the official server send these two packts.
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- if (rnd()%100 < 4 * skilllv)
- skill_castend_damage_id(src,bl,GC_CROSSIMPACT,skilllv,tick,flag);
- }
-
- }
- break;
-
- case GC_WEAPONCRUSH:
- if (sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == GC_WEAPONBLOCKING)
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- else if (sd)
- clif_skill_fail(sd,skillid,USESKILL_FAIL_GC_WEAPONBLOCKING,0);
- break;
-
- case GC_CROSSRIPPERSLASHER:
- if (sd && !(sc && sc->data[SC_ROLLINGCUTTER]))
- clif_skill_fail(sd,skillid,USESKILL_FAIL_CONDITION,0);
- else {
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- status_change_end(src,SC_ROLLINGCUTTER,INVALID_TIMER);
- }
- break;
-
- case GC_PHANTOMMENACE:
- if (flag&1) {
- // Only Hits Invisible Targets
- struct status_change *tsc = status_get_sc(bl);
- if (tsc && (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC__INVISIBILITY]))
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- }
- break;
- case WL_CHAINLIGHTNING:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- skill_addtimerskill(src,tick + 150,bl->id,3,0,WL_CHAINLIGHTNING_ATK,skilllv,4+skilllv,flag);
- break;
- case WL_DRAINLIFE: {
- int heal = skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, flag);
- int rate = 70 + 5 * skilllv;
-
- heal = heal * (5 + 5 * skilllv) / 100;
-
- if (bl->type == BL_SKILL)
- heal = 0; // Don't absorb heal from Ice Walls or other skill units.
-
- if (heal && rnd()%100 < rate) {
- status_heal(src, heal, 0, 0);
- clif_skill_nodamage(NULL, src, AL_HEAL, heal, 1);
- }
- }
- break;
-
- case WL_TETRAVORTEX:
- if (sd) {
- int spheres[5] = { 0, 0, 0, 0, 0 },
- positions[5] = {-1,-1,-1,-1,-1 },
- i, j = 0, k, subskill = 0;
-
- for (i = SC_SPHERE_1; i <= SC_SPHERE_5; i++)
- if (sc && sc->data[i]) {
- spheres[j] = i;
- positions[j] = sc->data[i]->val2;
- j++; //
- }
-
- if (j < 4) {
- // Need 4 spheres minimum
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
-
- // Sphere Sort, this time from new to old
- for (i = 0; i <= j - 2; i++)
- for (k = i + 1; k <= j - 1; k++)
- if (positions[i] < positions[k]) {
- swap(positions[i],positions[k]);
- swap(spheres[i],spheres[k]);
- }
-
- k = 0;
- for (i = 0; i < 4; i++) {
- switch (sc->data[spheres[i]]->val1) {
- case WLS_FIRE:
- subskill = WL_TETRAVORTEX_FIRE;
- k |= 1;
- break;
- case WLS_WIND:
- subskill = WL_TETRAVORTEX_WIND;
- k |= 4;
- break;
- case WLS_WATER:
- subskill = WL_TETRAVORTEX_WATER;
- k |= 2;
- break;
- case WLS_STONE:
- subskill = WL_TETRAVORTEX_GROUND;
- k |= 8;
- break;
- }
- skill_addtimerskill(src, tick + i * 200, bl->id, k, 0, subskill, skilllv, i, flag);
- clif_skill_nodamage(src, bl, subskill, skilllv, 1);
- status_change_end(src, spheres[i], INVALID_TIMER);
- }
- }
- break;
-
- case WL_RELEASE:
- if (sd) {
- int i;
- // Priority is to release SpellBook
- if (sc && sc->data[SC_READING_SB]) {
- // SpellBook
- int skill_id, skill_lv, point, s = 0;
- int spell[SC_MAXSPELLBOOK-SC_SPELLBOOK1 + 1];
-
- for (i = SC_MAXSPELLBOOK; i >= SC_SPELLBOOK1; i--) // List all available spell to be released
- if (sc->data[i]) spell[s++] = i;
-
- if (s == 0)
- break;
-
- i = spell[s==1?0:rand()%s];// Random select of spell to be released.
- if (s && sc->data[i]) {// Now extract the data from the preserved spell
- skill_id = sc->data[i]->val1;
- skill_lv = sc->data[i]->val2;
- point = sc->data[i]->val3;
- status_change_end(src, (sc_type)i, INVALID_TIMER);
- } else //something went wrong :(
- break;
-
- if (sc->data[SC_READING_SB]->val2 > point)
- sc->data[SC_READING_SB]->val2 -= point;
- else // Last spell to be released
- status_change_end(src, SC_READING_SB, INVALID_TIMER);
-
- clif_skill_nodamage(src, bl, skillid, skilllv, 1);
- if (!skill_check_condition_castbegin(sd, skill_id, skill_lv))
- break;
-
- switch (skill_get_casttype(skill_id)) {
- case CAST_GROUND:
- skill_castend_pos2(src, bl->x, bl->y, skill_id, skill_lv, tick, 0);
- break;
- case CAST_NODAMAGE:
- skill_castend_nodamage_id(src, bl, skill_id, skill_lv, tick, 0);
- break;
- case CAST_DAMAGE:
- skill_castend_damage_id(src, bl, skill_id, skill_lv, tick, 0);
- break;
- }
-
- sd->ud.canact_tick = tick + skill_delayfix(src, skill_id, skill_lv);
- clif_status_change(src, SI_ACTIONDELAY, 1, skill_delayfix(src, skill_id, skill_lv), 0, 0, 0);
- } else {
- // Summon Balls
- int j = 0, k, skele;
- int spheres[5] = { 0, 0, 0, 0, 0 },
- positions[5] = {-1,-1,-1,-1,-1 };
-
- for (i = SC_SPHERE_1; i <= SC_SPHERE_5; i++)
- if (sc && sc->data[i]) {
- spheres[j] = i;
- positions[j] = sc->data[i]->val2;
- sc->data[i]->val2--; // Prepares for next position
- j++;
- }
-
- if (j == 0) {
- // No Spheres
- clif_skill_fail(sd,skillid,USESKILL_FAIL_SUMMON_NONE,0);
- break;
- }
-
- // Sphere Sort
- for (i = 0; i <= j - 2; i++)
- for (k = i + 1; k <= j - 1; k++)
- if (positions[i] > positions[k]) {
- swap(positions[i],positions[k]);
- swap(spheres[i],spheres[k]);
- }
-
- if (skilllv == 1) j = 1; // Limit only to one ball
- for (i = 0; i < j; i++) {
- skele = WL_RELEASE - 5 + sc->data[spheres[i]]->val1 - WLS_FIRE; // Convert Ball Element into Skill ATK for balls
- // WL_SUMMON_ATK_FIRE, WL_SUMMON_ATK_WIND, WL_SUMMON_ATK_WATER, WL_SUMMON_ATK_GROUND
- skill_addtimerskill(src,tick+status_get_adelay(src)*i,bl->id,0,0,skele,sc->data[spheres[i]]->val3,BF_MAGIC,flag|SD_LEVEL);
- status_change_end(src, spheres[i], INVALID_TIMER); // Eliminate ball
- }
- clif_skill_nodamage(src,bl,skillid,0,1);
- }
- }
- break;
- case WL_FROSTMISTY:
- // Causes Freezing status through walls.
- sc_start(bl,status_skill2sc(skillid),20+12*skilllv+(sd ? sd->status.job_level : 50)/5,skilllv,skill_get_time(skillid,skilllv));
- // Doesn't deal damage through non-shootable walls.
- if (path_search(NULL,src->m,src->x,src->y,bl->x,bl->y,1,CELL_CHKWALL))
- skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag|SD_ANIMATION);
- break;
- case WL_HELLINFERNO:
- skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag);
- skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag|ELE_DARK);
- break;
- case RA_WUGSTRIKE:
- if (sd && pc_isridingwug(sd)) {
- short x[8]= {0,-1,-1,-1,0,1,1,1};
- short y[8]= {1,1,0,-1,-1,-1,0,1};
- int dir = map_calc_dir(bl, src->x, src->y);
-
- if (unit_movepos(src, bl->x+x[dir], bl->y+y[dir], 1, 1)) {
- clif_slide(src, bl->x+x[dir], bl->y+y[dir]);
- clif_fixpos(src);
- skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag);
- }
- break;
- }
- case RA_WUGBITE:
- if (path_search(NULL,src->m,src->x,src->y,bl->x,bl->y,1,CELL_CHKNOREACH)) {
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- } else if (sd && skillid == RA_WUGBITE) // Only RA_WUGBITE has the skill fail message.
- clif_skill_fail(sd, skillid, USESKILL_FAIL_LEVEL, 0);
-
- break;
-
- case RA_SENSITIVEKEEN:
- if (bl->type != BL_SKILL) { // Only Hits Invisible Targets
- struct status_change *tsc = status_get_sc(bl);
- if (tsc && tsc->option&(OPTION_HIDE|OPTION_CLOAK)) {
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
- }
- } else {
- struct skill_unit *su = BL_CAST(BL_SKILL,bl);
- struct skill_unit_group *sg;
-
- if (su && (sg=su->group) && skill_get_inf2(sg->skill_id)&INF2_TRAP) {
- if (!(sg->unit_id == UNT_USED_TRAPS || (sg->unit_id == UNT_ANKLESNARE && sg->val2 != 0))) {
- struct item item_tmp;
- memset(&item_tmp,0,sizeof(item_tmp));
- item_tmp.nameid = sg->item_id?sg->item_id:ITEMID_TRAP;
- item_tmp.identify = 1;
- if (item_tmp.nameid)
- map_addflooritem(&item_tmp,1,bl->m,bl->x,bl->y,0,0,0,0);
- }
- skill_delunit(su);
- }
- }
- break;
- case NC_INFRAREDSCAN:
- if (flag&1) {
- //TODO: Need a confirmation if the other type of hidden status is included to be scanned. [Jobbie]
- if (rnd()%100 < 50)
- sc_start(bl, SC_INFRAREDSCAN, 10000, skilllv, skill_get_time(skillid, skilllv));
- status_change_end(bl, SC_HIDING, INVALID_TIMER);
- status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
- status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER); // Need confirm it.
- } else {
- map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), splash_target(src), src, skillid, skilllv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill_castend_damage_id);
- clif_skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
- if (sd) pc_overheat(sd,1);
- }
- break;
-
- case NC_MAGNETICFIELD:
- sc_start2(bl,SC_MAGNETICFIELD,100,skilllv,src->id,skill_get_time(skillid,skilllv));
- break;
- case SC_FATALMENACE:
- if (flag&1)
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- else {
- short x, y;
- map_search_freecell(src, 0, &x, &y, -1, -1, 0);
- // Destination area
- skill_area_temp[4] = x;
- skill_area_temp[5] = y;
- map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), splash_target(src), src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_damage_id);
- skill_addtimerskill(src,tick + 800,src->id,x,y,skillid,skilllv,0,flag); // To teleport Self
- clif_skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skillid,skilllv,6);
- }
- break;
- case LG_PINPOINTATTACK:
- if (!map_flag_gvg(src->m) && !map[src->m].flag.battleground && unit_movepos(src, bl->x, bl->y, 1, 1))
- clif_slide(src,bl->x,bl->y);
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- break;
-
- case LG_SHIELDSPELL:
- // flag&1: Phisycal Attack, flag&2: Magic Attack.
- skill_attack((flag&1)?BF_WEAPON:BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag);
- break;
-
- case LG_OVERBRAND:
- skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag|SD_LEVEL);
- break;
-
- case LG_OVERBRAND_BRANDISH:
- skill_addtimerskill(src, tick + status_get_amotion(src)*8/10, bl->id, 0, 0, skillid, skilllv, BF_WEAPON, flag|SD_LEVEL);
- break;
- case SR_DRAGONCOMBO:
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- break;
-
- case SR_KNUCKLEARROW:
- if (!map_flag_gvg(src->m) && !map[src->m].flag.battleground && unit_movepos(src, bl->x, bl->y, 1, 1)) {
- clif_slide(src,bl->x,bl->y);
- clif_fixpos(src); // Aegis send this packet too.
- }
-
- if (flag&1)
- skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag|SD_LEVEL);
- else
- skill_addtimerskill(src, tick + 300, bl->id, 0, 0, skillid, skilllv, BF_WEAPON, flag|SD_LEVEL|2);
- break;
-
- case SR_HOWLINGOFLION:
- status_change_end(bl, SC_SWINGDANCE, INVALID_TIMER);
- status_change_end(bl, SC_SYMPHONYOFLOVER, INVALID_TIMER);
- status_change_end(bl, SC_MOONLITSERENADE, INVALID_TIMER);
- status_change_end(bl, SC_RUSHWINDMILL, INVALID_TIMER);
- status_change_end(bl, SC_ECHOSONG, INVALID_TIMER);
- status_change_end(bl, SC_HARMONIZE, INVALID_TIMER);
- status_change_end(bl, SC_SIRCLEOFNATURE, INVALID_TIMER);
- status_change_end(bl, SC_SATURDAYNIGHTFEVER, INVALID_TIMER);
- status_change_end(bl, SC_DANCEWITHWUG, INVALID_TIMER);
- status_change_end(bl, SC_LERADSDEW, INVALID_TIMER);
- status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER);
- status_change_end(bl, SC_BEYONDOFWARCRY, INVALID_TIMER);
- status_change_end(bl, SC_UNLIMITEDHUMMINGVOICE, INVALID_TIMER);
- skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag|SD_ANIMATION);
- break;
-
- case SR_EARTHSHAKER:
- if (flag&1) { //by default cloaking skills are remove by aoe skills so no more checking/removing except hiding and cloaking exceed.
- skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag);
- status_change_end(bl, SC_HIDING, INVALID_TIMER);
- status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
- } else {
- map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), splash_target(src), src, skillid, skilllv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill_castend_damage_id);
- clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
- }
- break;
-
- case WM_LULLABY_DEEPSLEEP:
- if (bl != src && rnd()%100 < 88 + 2 * skilllv)
- sc_start(bl,status_skill2sc(skillid),100,skilllv,skill_get_time(skillid,skilllv));
- break;
+ }
+ //Client expects you to move to target regardless of distance
+ {
+ struct unit_data *ud = unit_bl2ud(src);
+ short dx,dy;
+ int i,speed;
+ i = skillid == MO_EXTREMITYFIST?1:2; //Move 2 cells for Issen, 1 for Asura
+ dx = bl->x - src->x;
+ dy = bl->y - src->y;
+ if (dx < 0) dx-=i;
+ else if (dx > 0) dx+=i;
+ if (dy < 0) dy-=i;
+ else if (dy > 0) dy+=i;
+ if (!dx && !dy) dy++;
+ if (map_getcell(src->m, src->x+dx, src->y+dy, CELL_CHKNOPASS))
+ {
+ dx = bl->x;
+ dy = bl->y;
+ } else {
+ dx = src->x + dx;
+ dy = src->y + dy;
+ }
- case SO_POISON_BUSTER: {
- struct status_change *tsc = status_get_sc(bl);
- if (tsc && tsc->data[SC_POISON]) {
- skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, flag);
- status_change_end(bl, SC_POISON, INVALID_TIMER);
- } else if (sd)
- clif_skill_fail(sd, skillid, USESKILL_FAIL_LEVEL, 0);
- }
- break;
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+
+ if(unit_walktoxy(src, dx, dy, 2) && ud) {
+ //Increase can't walk delay to not alter your walk path
+ ud->canmove_tick = tick;
+ speed = status_get_speed(src);
+ for (i = 0; i < ud->walkpath.path_len; i ++)
+ {
+ if(ud->walkpath.path[i]&1)
+ ud->canmove_tick+=7*speed/5;
+ else
+ ud->canmove_tick+=speed;
+ }
+ }
+ }
+ break;
+
+ //Splash attack skills.
+ case AS_GRIMTOOTH:
+ case MC_CARTREVOLUTION:
+ case NPC_SPLASHATTACK:
+ flag |= SD_PREAMBLE; // a fake packet will be sent for the first target to be hit
+ case AS_SPLASHER:
+ case SM_MAGNUM:
+ case MS_MAGNUM:
+ case HT_BLITZBEAT:
+ case AC_SHOWER:
+ case MA_SHOWER:
+ case MG_NAPALMBEAT:
+ case MG_FIREBALL:
+ case RG_RAID:
+ case HW_NAPALMVULCAN:
+ case NJ_HUUMA:
+ case NJ_BAKUENRYU:
+ case ASC_METEORASSAULT:
+ case GS_DESPERADO:
+ case GS_SPREADATTACK:
+ case NPC_EARTHQUAKE:
+ case NPC_PULSESTRIKE:
+ case NPC_HELLJUDGEMENT:
+ case NPC_VAMPIRE_GIFT:
+ case RK_IGNITIONBREAK:
+ case AB_JUDEX:
+ case WL_SOULEXPANSION:
+ case WL_CRIMSONROCK:
+ case WL_COMET:
+ case WL_JACKFROST:
+ case RA_ARROWSTORM:
+ case RA_WUGDASH:
+ case NC_SELFDESTRUCTION:
+ case NC_AXETORNADO:
+ case GC_ROLLINGCUTTER:
+ case GC_COUNTERSLASH:
+ case LG_MOONSLASHER:
+ case LG_EARTHDRIVE:
+ case SR_TIGERCANNON:
+ case SR_RAMPAGEBLASTER:
+ case SR_SKYNETBLOW:
+ case SR_WINDMILL:
+ case SR_RIDEINLIGHTNING:
+ case WM_SOUND_OF_DESTRUCTION:
+ case WM_REVERBERATION_MELEE:
+ case WM_REVERBERATION_MAGIC:
+ case SO_VARETYR_SPEAR:
+ case GN_CART_TORNADO:
+ case GN_CARTCANNON:
+ case KO_HAPPOKUNAI:
+ case KO_HUUMARANKA:
+ case KO_MUCHANAGE:
+ case KO_BAKURETSU:
+ if( flag&1 ) {//Recursive invocation
+ // skill_area_temp[0] holds number of targets in area
+ // skill_area_temp[1] holds the id of the original target
+ // skill_area_temp[2] counts how many targets have already been processed
+ int sflag = skill_area_temp[0] & 0xFFF, heal;
+ if( flag&SD_LEVEL )
+ sflag |= SD_LEVEL; // -1 will be used in packets instead of the skill level
+ if( skill_area_temp[1] != bl->id && !(skill_get_inf2(skillid)&INF2_NPC_SKILL) )
+ sflag |= SD_ANIMATION; // original target gets no animation (as well as all NPC skills)
+
+ heal = skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, sflag);
+ if( skillid == NPC_VAMPIRE_GIFT && heal > 0 ) {
+ clif_skill_nodamage(NULL, src, AL_HEAL, heal, 1);
+ status_heal(src,heal,0,0);
+ }
+ } else {
+ switch ( skillid ) {
+ case NJ_BAKUENRYU:
+ case LG_EARTHDRIVE:
+ case GN_CARTCANNON:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ break;
+ case LG_MOONSLASHER:
+ clif_skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+ break;
+ case NPC_EARTHQUAKE://FIXME: Isn't EarthQuake a ground skill after all?
+ skill_addtimerskill(src,tick+250,src->id,0,0,skillid,skilllv,2,flag|BCT_ENEMY|SD_SPLASH|1);
+ default:
+ break;
+ }
- case GN_SPORE_EXPLOSION:
- if (flag&1)
- skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, flag);
- else {
- clif_skill_nodamage(src, bl, skillid, 0, 1);
- skill_addtimerskill(src, gettick() + skill_get_time(skillid, skilllv) - 1000, bl->id, 0, 0, skillid, skilllv, 0, 0);
- }
- break;
+ skill_area_temp[0] = 0;
+ skill_area_temp[1] = bl->id;
+ skill_area_temp[2] = 0;
+ if( skillid == WL_CRIMSONROCK ) {
+ skill_area_temp[4] = bl->x;
+ skill_area_temp[5] = bl->y;
+ }
+ if( skillid == WM_REVERBERATION_MELEE || skillid == WM_REVERBERATION_MAGIC )
+ skill_area_temp[1] = 0;
+ // if skill damage should be split among targets, count them
+ //SD_LEVEL -> Forced splash damage for Auto Blitz-Beat -> count targets
+ //special case: Venom Splasher uses a different range for searching than for splashing
+ if( flag&SD_LEVEL || skill_get_nk(skillid)&NK_SPLASHSPLIT )
+ skill_area_temp[0] = map_foreachinrange(skill_area_sub, bl, (skillid == AS_SPLASHER)?1:skill_get_splash(skillid, skilllv), BL_CHAR, src, skillid, skilllv, tick, BCT_ENEMY, skill_area_sub_count);
+
+ // recursive invocation of skill_castend_damage_id() with flag|1
+ map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), ( skillid == WM_REVERBERATION_MELEE || skillid == WM_REVERBERATION_MAGIC )?BL_CHAR:splash_target(src), src, skillid, skilllv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill_castend_damage_id);
+ }
+ break;
+
+ case KN_BRANDISHSPEAR:
+ case ML_BRANDISH:
+ //Coded apart for it needs the flag passed to the damage calculation.
+ if (skill_area_temp[1] != bl->id)
+ skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, flag|SD_ANIMATION);
+ else
+ skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, flag);
+ break;
+
+ case KN_BOWLINGBASH:
+ case MS_BOWLINGBASH:
+ if(flag&1){
+ if(bl->id==skill_area_temp[1])
+ break;
+ //two hits for 500%
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,SD_ANIMATION);
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,SD_ANIMATION);
+ } else {
+ int i,c;
+ c = skill_get_blewcount(skillid,skilllv);
+ // keep moving target in the direction that src is looking, square by square
+ for(i=0;i<c;i++){
+ if (!skill_blown(src,bl,1,(unit_getdir(src)+4)%8,0x1))
+ break; //Can't knockback
+ skill_area_temp[0] = map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), BL_CHAR, src, skillid, skilllv, tick, flag|BCT_ENEMY, skill_area_sub_count);
+ if( skill_area_temp[0] > 1 ) break; // collision
+ }
+ clif_blown(bl); //Update target pos.
+ if (i!=c) { //Splash
+ skill_area_temp[1] = bl->id;
+ map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), splash_target(src), src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_damage_id);
+ }
+ //Weirdo dual-hit property, two attacks for 500%
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,0);
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,0);
+ }
+ break;
+
+ case KN_SPEARSTAB:
+ if(flag&1) {
+ if (bl->id==skill_area_temp[1])
+ break;
+ if (skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,SD_ANIMATION))
+ skill_blown(src,bl,skill_area_temp[2],-1,0);
+ } else {
+ int x=bl->x,y=bl->y,i,dir;
+ dir = map_calc_dir(bl,src->x,src->y);
+ skill_area_temp[1] = bl->id;
+ skill_area_temp[2] = skill_get_blewcount(skillid,skilllv);
+ // all the enemies between the caster and the target are hit, as well as the target
+ if (skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,0))
+ skill_blown(src,bl,skill_area_temp[2],-1,0);
+ for (i=0;i<4;i++) {
+ map_foreachincell(skill_area_sub,bl->m,x,y,BL_CHAR,
+ src,skillid,skilllv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
+ x += dirx[dir];
+ y += diry[dir];
+ }
+ }
+ break;
+
+ case TK_TURNKICK:
+ case MO_BALKYOUNG: //Active part of the attack. Skill-attack [Skotlex]
+ {
+ skill_area_temp[1] = bl->id; //NOTE: This is used in skill_castend_nodamage_id to avoid affecting the target.
+ if (skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag))
+ map_foreachinrange(skill_area_sub,bl,
+ skill_get_splash(skillid, skilllv),BL_CHAR,
+ src,skillid,skilllv,tick,flag|BCT_ENEMY|1,
+ skill_castend_nodamage_id);
+ }
+ break;
+ case CH_PALMSTRIKE: // Palm Strike takes effect 1sec after casting. [Skotlex]
+ // clif_skill_nodamage(src,bl,skillid,skilllv,0); //Can't make this one display the correct attack animation delay :/
+ clif_damage(src,bl,tick,status_get_amotion(src),0,-1,1,4,0); //Display an absorbed damage attack.
+ skill_addtimerskill(src, tick + 1000, bl->id, 0, 0, skillid, skilllv, BF_WEAPON, flag);
+ break;
+
+ case PR_TURNUNDEAD:
+ case ALL_RESURRECTION:
+ if (!battle_check_undead(tstatus->race, tstatus->def_ele))
+ break;
+ skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag);
+ break;
+
+ case MG_SOULSTRIKE:
+ case NPC_DARKSTRIKE:
+ case MG_COLDBOLT:
+ case MG_FIREBOLT:
+ case MG_LIGHTNINGBOLT:
+ case WZ_EARTHSPIKE:
+ case AL_HEAL:
+ case AL_HOLYLIGHT:
+ case WZ_JUPITEL:
+ case NPC_DARKTHUNDER:
+ case PR_ASPERSIO:
+ case MG_FROSTDIVER:
+ case WZ_SIGHTBLASTER:
+ case WZ_SIGHTRASHER:
+ case NJ_KOUENKA:
+ case NJ_HYOUSENSOU:
+ case NJ_HUUJIN:
+ case AB_ADORAMUS:
+ case AB_RENOVATIO:
+ case AB_HIGHNESSHEAL:
+ case AB_DUPLELIGHT_MAGIC:
+ case WM_METALICSOUND:
+ case MH_ERASER_CUTTER:
+ skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag);
+ break;
+
+ case NPC_MAGICALATTACK:
+ skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag);
+ sc_start(src,status_skill2sc(skillid),100,skilllv,skill_get_time(skillid,skilllv));
+ break;
+
+ case HVAN_CAPRICE: //[blackhole89]
+ {
+ int ran=rnd()%4;
+ int sid = 0;
+ switch(ran)
+ {
+ case 0: sid=MG_COLDBOLT; break;
+ case 1: sid=MG_FIREBOLT; break;
+ case 2: sid=MG_LIGHTNINGBOLT; break;
+ case 3: sid=WZ_EARTHSPIKE; break;
+ }
+ skill_attack(BF_MAGIC,src,src,bl,sid,skilllv,tick,flag|SD_LEVEL);
+ }
+ break;
+ case WZ_WATERBALL:
+ {
+ int range = skilllv / 2;
+ int maxlv = skill_get_max(skillid); // learnable level
+ int count = 0;
+ int x, y;
+ struct skill_unit* unit;
+
+ if( skilllv > maxlv )
+ {
+ if( src->type == BL_MOB && skilllv == 10 )
+ range = 4;
+ else
+ range = maxlv / 2;
+ }
- case EL_FIRE_BOMB:
- case EL_FIRE_WAVE:
- case EL_WATER_SCREW:
- case EL_HURRICANE:
- case EL_TYPOON_MIS:
- if (flag&1)
- skill_attack(skill_get_type(skillid+1),src,src,bl,skillid+1,skilllv,tick,flag);
- else {
- int i = skill_get_splash(skillid,skilllv);
- clif_skill_nodamage(src,battle_get_master(src),skillid,skilllv,1);
- clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
- if (rnd()%100 < 30)
- map_foreachinrange(skill_area_sub,bl,i,BL_CHAR,src,skillid,skilllv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
- else
- skill_attack(skill_get_type(skillid),src,src,bl,skillid,skilllv,tick,flag);
- }
- break;
+ for( y = src->y - range; y <= src->y + range; ++y )
+ for( x = src->x - range; x <= src->x + range; ++x )
+ {
+ if( !map_find_skill_unit_oncell(src,x,y,SA_LANDPROTECTOR,NULL,1) )
+ {
+ if( src->type != BL_PC || map_getcell(src->m,x,y,CELL_CHKWATER) ) // non-players bypass the water requirement
+ count++; // natural water cell
+ else if( (unit = map_find_skill_unit_oncell(src,x,y,SA_DELUGE,NULL,1)) != NULL || (unit = map_find_skill_unit_oncell(src,x,y,NJ_SUITON,NULL,1)) != NULL )
+ {
+ count++; // skill-induced water cell
+ skill_delunit(unit); // consume cell
+ }
+ }
+ }
- case EL_ROCK_CRUSHER:
- clif_skill_nodamage(src,battle_get_master(src),skillid,skilllv,1);
- clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
- if (rnd()%100 < 50)
- skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag);
- else
- skill_attack(BF_WEAPON,src,src,bl,EL_ROCK_CRUSHER_ATK,skilllv,tick,flag);
- break;
+ if( count > 1 ) // queue the remaining count - 1 timerskill Waterballs
+ skill_addtimerskill(src,tick+150,bl->id,0,0,skillid,skilllv,count-1,flag);
+ }
+ skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag);
+ break;
+
+ case PR_BENEDICTIO:
+ //Should attack undead and demons. [Skotlex]
+ if (battle_check_undead(tstatus->race, tstatus->def_ele) || tstatus->race == RC_DEMON)
+ skill_attack(BF_MAGIC, src, src, bl, skillid, skilllv, tick, flag);
+ break;
+
+ case SL_SMA:
+ status_change_end(src, SC_SMA, INVALID_TIMER);
+ case SL_STIN:
+ case SL_STUN:
+ if (sd && !battle_config.allow_es_magic_pc && bl->type != BL_MOB) {
+ status_change_start(src,SC_STUN,10000,skilllv,0,0,0,500,10);
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+ skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag);
+ break;
+
+ case NPC_DARKBREATH:
+ clif_emotion(src,E_AG);
+ case SN_FALCONASSAULT:
+ case PA_PRESSURE:
+ case CR_ACIDDEMONSTRATION:
+ case TF_THROWSTONE:
+ case NPC_SMOKING:
+ case GS_FLING:
+ case NJ_ZENYNAGE:
+ case GN_THORNS_TRAP:
+ case GN_HELLS_PLANT_ATK:
+ skill_attack(BF_MISC,src,src,bl,skillid,skilllv,tick,flag);
+ break;
+ /**
+ * Rune Knight
+ **/
+ case RK_DRAGONBREATH: {
+ struct status_change *tsc = NULL;
+ if( (tsc = status_get_sc(bl)) && (tsc->data[SC_HIDING] )) {
+ clif_skill_nodamage(src,src,skillid,skilllv,1);
+ } else
+ skill_attack(BF_MISC,src,src,bl,skillid,skilllv,tick,flag);
+ }
+ break;
+
+ case NPC_SELFDESTRUCTION: {
+ struct status_change *tsc = NULL;
+ if( (tsc = status_get_sc(bl)) && tsc->data[SC_HIDING] )
+ break;
+ }
+ case HVAN_EXPLOSION:
+ if (src != bl)
+ skill_attack(BF_MISC,src,src,bl,skillid,skilllv,tick,flag);
+ break;
+
+ // Celest
+ case PF_SOULBURN:
+ if (rnd()%100 < (skilllv < 5 ? 30 + skilllv * 10 : 70)) {
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ if (skilllv == 5)
+ skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag);
+ status_percent_damage(src, bl, 0, 100, false);
+ } else {
+ clif_skill_nodamage(src,src,skillid,skilllv,1);
+ if (skilllv == 5)
+ skill_attack(BF_MAGIC,src,src,src,skillid,skilllv,tick,flag);
+ status_percent_damage(src, src, 0, 100, false);
+ }
+ break;
+
+ case NPC_BLOODDRAIN:
+ case NPC_ENERGYDRAIN:
+ {
+ int heal = skill_attack( (skillid == NPC_BLOODDRAIN) ? BF_WEAPON : BF_MAGIC,
+ src, src, bl, skillid, skilllv, tick, flag);
+ if (heal > 0){
+ clif_skill_nodamage(NULL, src, AL_HEAL, heal, 1);
+ status_heal(src, heal, 0, 0);
+ }
+ }
+ break;
+
+ case GS_BULLSEYE:
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+ break;
+
+ case NJ_KASUMIKIRI:
+ if (skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag) > 0)
+ sc_start(src,SC_HIDING,100,skilllv,skill_get_time(skillid,skilllv));
+ break;
+ case NJ_KIRIKAGE:
+ if( !map_flag_gvg(src->m) && !map[src->m].flag.battleground )
+ { //You don't move on GVG grounds.
+ short x, y;
+ map_search_freecell(bl, 0, &x, &y, 1, 1, 0);
+ if (unit_movepos(src, x, y, 0, 0))
+ clif_slide(src,src->x,src->y);
+ }
+ status_change_end(src, SC_HIDING, INVALID_TIMER);
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+ break;
+ case RK_PHANTOMTHRUST:
+ unit_setdir(src,map_calc_dir(src, bl->x, bl->y));
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+
+ skill_blown(src,bl,distance_bl(src,bl)-1,unit_getdir(src),0);
+ if( battle_check_target(src,bl,BCT_ENEMY) )
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+ break;
+
+ case RK_STORMBLAST:
+ case RK_CRUSHSTRIKE:
+ if( sd ) {
+ if( pc_checkskill(sd,RK_RUNEMASTERY) >= ( skillid == RK_CRUSHSTRIKE ? 7 : 3 ) )
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+ else
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ } else //non-sd support
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+ break;
+ case GC_DARKILLUSION:
+ {
+ short x, y;
+ short dir = map_calc_dir(src,bl->x,bl->y);
+
+ if( dir > 4 ) x = -1;
+ else if( dir > 0 && dir < 4 ) x = 1;
+ else x = 0;
+ if( dir < 3 || dir > 5 ) y = -1;
+ else if( dir > 3 && dir < 5 ) y = 1;
+ else y = 0;
+
+ if( unit_movepos(src, bl->x+x, bl->y+y, 1, 1) )
+ {
+ clif_slide(src,bl->x+x,bl->y+y);
+ clif_fixpos(src); // the official server send these two packts.
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+ if( rnd()%100 < 4 * skilllv )
+ skill_castend_damage_id(src,bl,GC_CROSSIMPACT,skilllv,tick,flag);
+ }
- case EL_STONE_RAIN:
- if (flag&1)
- skill_attack(skill_get_type(skillid),src,src,bl,skillid,skilllv,tick,flag);
- else {
- int i = skill_get_splash(skillid,skilllv);
- clif_skill_nodamage(src,battle_get_master(src),skillid,skilllv,1);
- clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
- if (rnd()%100 < 30)
- map_foreachinrange(skill_area_sub,bl,i,BL_CHAR,src,skillid,skilllv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
- else
- skill_attack(skill_get_type(skillid),src,src,bl,skillid,skilllv,tick,flag);
- }
- break;
+ }
+ break;
+
+ case GC_WEAPONCRUSH:
+ if( sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == GC_WEAPONBLOCKING )
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+ else if( sd )
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_GC_WEAPONBLOCKING,0);
+ break;
+
+ case GC_CROSSRIPPERSLASHER:
+ if( sd && !(sc && sc->data[SC_ROLLINGCUTTER]) )
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_CONDITION,0);
+ else
+ {
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+ status_change_end(src,SC_ROLLINGCUTTER,INVALID_TIMER);
+ }
+ break;
+
+ case GC_PHANTOMMENACE:
+ if( flag&1 )
+ { // Only Hits Invisible Targets
+ struct status_change *tsc = status_get_sc(bl);
+ if(tsc && (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC__INVISIBILITY]) )
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+ }
+ break;
+ case WL_CHAINLIGHTNING:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ skill_addtimerskill(src,tick + 150,bl->id,3,0,WL_CHAINLIGHTNING_ATK,skilllv,4+skilllv,flag);
+ break;
+ case WL_DRAINLIFE:
+ {
+ int heal = skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, flag);
+ int rate = 70 + 5 * skilllv;
+
+ heal = heal * (5 + 5 * skilllv) / 100;
+
+ if( bl->type == BL_SKILL )
+ heal = 0; // Don't absorb heal from Ice Walls or other skill units.
+
+ if( heal && rnd()%100 < rate )
+ {
+ status_heal(src, heal, 0, 0);
+ clif_skill_nodamage(NULL, src, AL_HEAL, heal, 1);
+ }
+ }
+ break;
+
+ case WL_TETRAVORTEX:
+ if( sd )
+ {
+ int spheres[5] = { 0, 0, 0, 0, 0 },
+ positions[5] = {-1,-1,-1,-1,-1 },
+ i, j = 0, k, subskill = 0;
+
+ for( i = SC_SPHERE_1; i <= SC_SPHERE_5; i++ )
+ if( sc && sc->data[i] )
+ {
+ spheres[j] = i;
+ positions[j] = sc->data[i]->val2;
+ j++; //
+ }
- case EL_FIRE_ARROW:
- case EL_ICE_NEEDLE:
- case EL_WIND_SLASH:
- case EL_STONE_HAMMER:
- clif_skill_nodamage(src,battle_get_master(src),skillid,skilllv,1);
- clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
- skill_attack(skill_get_type(skillid),src,src,bl,skillid,skilllv,tick,flag);
- break;
+ if( j < 4 )
+ { // Need 4 spheres minimum
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
- case EL_TIDAL_WEAPON:
- if (src->type == BL_ELEM) {
- struct elemental_data *ele = BL_CAST(BL_ELEM,src);
- struct status_change *sc = status_get_sc(&ele->bl);
- struct status_change *tsc = status_get_sc(bl);
- sc_type type = status_skill2sc(skillid), type2;
- type2 = type-1;
-
- clif_skill_nodamage(src,battle_get_master(src),skillid,skilllv,1);
- clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
- if ((sc && sc->data[type2]) || (tsc && tsc->data[type])) {
- elemental_clean_single_effect(ele, skillid);
- }
- if (rnd()%100 < 50)
- skill_attack(skill_get_type(skillid),src,src,bl,skillid,skilllv,tick,flag);
- else {
- sc_start(src,type2,100,skilllv,skill_get_time(skillid,skilllv));
- sc_start(battle_get_master(src),type,100,ele->bl.id,skill_get_time(skillid,skilllv));
- }
- clif_skill_nodamage(src,src,skillid,skilllv,1);
- }
- break;
+ // Sphere Sort, this time from new to old
+ for( i = 0; i <= j - 2; i++ )
+ for( k = i + 1; k <= j - 1; k++ )
+ if( positions[i] < positions[k] )
+ {
+ swap(positions[i],positions[k]);
+ swap(spheres[i],spheres[k]);
+ }
+
+ k = 0;
+ for( i = 0; i < 4; i++ )
+ {
+ switch( sc->data[spheres[i]]->val1 )
+ {
+ case WLS_FIRE: subskill = WL_TETRAVORTEX_FIRE; k |= 1; break;
+ case WLS_WIND: subskill = WL_TETRAVORTEX_WIND; k |= 4; break;
+ case WLS_WATER: subskill = WL_TETRAVORTEX_WATER; k |= 2; break;
+ case WLS_STONE: subskill = WL_TETRAVORTEX_GROUND; k |= 8; break;
+ }
+ skill_addtimerskill(src, tick + i * 200, bl->id, k, 0, subskill, skilllv, i, flag);
+ clif_skill_nodamage(src, bl, subskill, skilllv, 1);
+ status_change_end(src, spheres[i], INVALID_TIMER);
+ }
+ }
+ break;
+
+ case WL_RELEASE:
+ if( sd )
+ {
+ int i;
+ // Priority is to release SpellBook
+ if( sc && sc->data[SC_READING_SB] )
+ { // SpellBook
+ int skill_id, skill_lv, point, s = 0;
+ int spell[SC_MAXSPELLBOOK-SC_SPELLBOOK1 + 1];
+
+ for(i = SC_MAXSPELLBOOK; i >= SC_SPELLBOOK1; i--) // List all available spell to be released
+ if( sc->data[i] ) spell[s++] = i;
+
+ if ( s == 0 )
+ break;
+
+ i = spell[s==1?0:rand()%s];// Random select of spell to be released.
+ if( s && sc->data[i] ){// Now extract the data from the preserved spell
+ skill_id = sc->data[i]->val1;
+ skill_lv = sc->data[i]->val2;
+ point = sc->data[i]->val3;
+ status_change_end(src, (sc_type)i, INVALID_TIMER);
+ }else //something went wrong :(
+ break;
+
+ if( sc->data[SC_READING_SB]->val2 > point )
+ sc->data[SC_READING_SB]->val2 -= point;
+ else // Last spell to be released
+ status_change_end(src, SC_READING_SB, INVALID_TIMER);
+
+ clif_skill_nodamage(src, bl, skillid, skilllv, 1);
+ if( !skill_check_condition_castbegin(sd, skill_id, skill_lv) )
+ break;
+
+ switch( skill_get_casttype(skill_id) )
+ {
+ case CAST_GROUND:
+ skill_castend_pos2(src, bl->x, bl->y, skill_id, skill_lv, tick, 0);
+ break;
+ case CAST_NODAMAGE:
+ skill_castend_nodamage_id(src, bl, skill_id, skill_lv, tick, 0);
+ break;
+ case CAST_DAMAGE:
+ skill_castend_damage_id(src, bl, skill_id, skill_lv, tick, 0);
+ break;
+ }
+ sd->ud.canact_tick = tick + skill_delayfix(src, skill_id, skill_lv);
+ clif_status_change(src, SI_ACTIONDELAY, 1, skill_delayfix(src, skill_id, skill_lv), 0, 0, 0);
+ }
+ else
+ { // Summon Balls
+ int j = 0, k, skele;
+ int spheres[5] = { 0, 0, 0, 0, 0 },
+ positions[5] = {-1,-1,-1,-1,-1 };
+
+ for( i = SC_SPHERE_1; i <= SC_SPHERE_5; i++ )
+ if( sc && sc->data[i] )
+ {
+ spheres[j] = i;
+ positions[j] = sc->data[i]->val2;
+ sc->data[i]->val2--; // Prepares for next position
+ j++;
+ }
+
+ if( j == 0 )
+ { // No Spheres
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_SUMMON_NONE,0);
+ break;
+ }
- //recursive homon skill
- case MH_MAGMA_FLOW:
- case MH_XENO_SLASHER:
- case MH_HEILIGE_STANGE:
- if (flag & 1)
- skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, flag);
- else {
- map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), splash_target(src), src, skillid, skilllv, tick, flag | BCT_ENEMY | SD_SPLASH | 1, skill_castend_damage_id);
- }
- break;
- case MH_STAHL_HORN:
- case MH_NEEDLE_OF_PARALYZE:
- skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag);
- break;
+ // Sphere Sort
+ for( i = 0; i <= j - 2; i++ )
+ for( k = i + 1; k <= j - 1; k++ )
+ if( positions[i] > positions[k] )
+ {
+ swap(positions[i],positions[k]);
+ swap(spheres[i],spheres[k]);
+ }
+
+ if( skilllv == 1 ) j = 1; // Limit only to one ball
+ for( i = 0; i < j; i++ )
+ {
+ skele = WL_RELEASE - 5 + sc->data[spheres[i]]->val1 - WLS_FIRE; // Convert Ball Element into Skill ATK for balls
+ // WL_SUMMON_ATK_FIRE, WL_SUMMON_ATK_WIND, WL_SUMMON_ATK_WATER, WL_SUMMON_ATK_GROUND
+ skill_addtimerskill(src,tick+status_get_adelay(src)*i,bl->id,0,0,skele,sc->data[spheres[i]]->val3,BF_MAGIC,flag|SD_LEVEL);
+ status_change_end(src, spheres[i], INVALID_TIMER); // Eliminate ball
+ }
+ clif_skill_nodamage(src,bl,skillid,0,1);
+ }
+ }
+ break;
+ case WL_FROSTMISTY:
+ // Causes Freezing status through walls.
+ sc_start(bl,status_skill2sc(skillid),20+12*skilllv+(sd ? sd->status.job_level : 50)/5,skilllv,skill_get_time(skillid,skilllv));
+ // Doesn't deal damage through non-shootable walls.
+ if( path_search(NULL,src->m,src->x,src->y,bl->x,bl->y,1,CELL_CHKWALL) )
+ skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag|SD_ANIMATION);
+ break;
+ case WL_HELLINFERNO:
+ skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag);
+ skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag|ELE_DARK);
+ break;
+ case RA_WUGSTRIKE:
+ if( sd && pc_isridingwug(sd) ){
+ short x[8]={0,-1,-1,-1,0,1,1,1};
+ short y[8]={1,1,0,-1,-1,-1,0,1};
+ int dir = map_calc_dir(bl, src->x, src->y);
+
+ if( unit_movepos(src, bl->x+x[dir], bl->y+y[dir], 1, 1) )
+ {
+ clif_slide(src, bl->x+x[dir], bl->y+y[dir]);
+ clif_fixpos(src);
+ skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag);
+ }
+ break;
+ }
+ case RA_WUGBITE:
+ if( path_search(NULL,src->m,src->x,src->y,bl->x,bl->y,1,CELL_CHKNOREACH) ) {
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+ }else if( sd && skillid == RA_WUGBITE ) // Only RA_WUGBITE has the skill fail message.
+ clif_skill_fail(sd, skillid, USESKILL_FAIL_LEVEL, 0);
+
+ break;
+
+ case RA_SENSITIVEKEEN:
+ if( bl->type != BL_SKILL ) { // Only Hits Invisible Targets
+ struct status_change * tsc = status_get_sc(bl);
+ if( tsc && tsc->option&(OPTION_HIDE|OPTION_CLOAK) ){
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+ status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
+ }
+ }
+ else
+ {
+ struct skill_unit *su = BL_CAST(BL_SKILL,bl);
+ struct skill_unit_group* sg;
- case 0:/* no skill - basic/normal attack */
- if (sd) {
- if (flag & 3) {
- if (bl->id != skill_area_temp[1])
- skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, SD_LEVEL|flag);
- } else {
- skill_area_temp[1] = bl->id;
- map_foreachinrange(skill_area_sub, bl,
- sd->bonus.splash_range, BL_CHAR,
- src, skillid, skilllv, tick, flag | BCT_ENEMY | 1,
- skill_castend_damage_id);
- flag|=1; //Set flag to 1 so ammo is not double-consumed. [Skotlex]
- }
- }
- break;
+ if( su && (sg=su->group) && skill_get_inf2(sg->skill_id)&INF2_TRAP )
+ {
+ if( !(sg->unit_id == UNT_USED_TRAPS || (sg->unit_id == UNT_ANKLESNARE && sg->val2 != 0 )) )
+ {
+ struct item item_tmp;
+ memset(&item_tmp,0,sizeof(item_tmp));
+ item_tmp.nameid = sg->item_id?sg->item_id:ITEMID_TRAP;
+ item_tmp.identify = 1;
+ if( item_tmp.nameid )
+ map_addflooritem(&item_tmp,1,bl->m,bl->x,bl->y,0,0,0,0);
+ }
+ skill_delunit(su);
+ }
+ }
+ break;
+ case NC_INFRAREDSCAN:
+ if( flag&1 )
+ { //TODO: Need a confirmation if the other type of hidden status is included to be scanned. [Jobbie]
+ if( rnd()%100 < 50 )
+ sc_start(bl, SC_INFRAREDSCAN, 10000, skilllv, skill_get_time(skillid, skilllv));
+ status_change_end(bl, SC_HIDING, INVALID_TIMER);
+ status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
+ status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER); // Need confirm it.
+ }
+ else
+ {
+ map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), splash_target(src), src, skillid, skilllv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill_castend_damage_id);
+ clif_skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+ if( sd ) pc_overheat(sd,1);
+ }
+ break;
+
+ case NC_MAGNETICFIELD:
+ sc_start2(bl,SC_MAGNETICFIELD,100,skilllv,src->id,skill_get_time(skillid,skilllv));
+ break;
+ case SC_FATALMENACE:
+ if( flag&1 )
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+ else
+ {
+ short x, y;
+ map_search_freecell(src, 0, &x, &y, -1, -1, 0);
+ // Destination area
+ skill_area_temp[4] = x;
+ skill_area_temp[5] = y;
+ map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), splash_target(src), src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_damage_id);
+ skill_addtimerskill(src,tick + 800,src->id,x,y,skillid,skilllv,0,flag); // To teleport Self
+ clif_skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skillid,skilllv,6);
+ }
+ break;
+ case LG_PINPOINTATTACK:
+ if( !map_flag_gvg(src->m) && !map[src->m].flag.battleground && unit_movepos(src, bl->x, bl->y, 1, 1) )
+ clif_slide(src,bl->x,bl->y);
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+ break;
+
+ case LG_SHIELDSPELL:
+ // flag&1: Phisycal Attack, flag&2: Magic Attack.
+ skill_attack((flag&1)?BF_WEAPON:BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag);
+ break;
+
+ case LG_OVERBRAND:
+ skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag|SD_LEVEL);
+ break;
+
+ case LG_OVERBRAND_BRANDISH:
+ skill_addtimerskill(src, tick + status_get_amotion(src)*8/10, bl->id, 0, 0, skillid, skilllv, BF_WEAPON, flag|SD_LEVEL);
+ break;
+ case SR_DRAGONCOMBO:
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+ break;
+
+ case SR_KNUCKLEARROW:
+ if( !map_flag_gvg(src->m) && !map[src->m].flag.battleground && unit_movepos(src, bl->x, bl->y, 1, 1) ) {
+ clif_slide(src,bl->x,bl->y);
+ clif_fixpos(src); // Aegis send this packet too.
+ }
- default:
- ShowWarning("skill_castend_damage_id: Unknown skill used:%d\n",skillid);
- clif_skill_damage(src, bl, tick, status_get_amotion(src), tstatus->dmotion,
- 0, abs(skill_get_num(skillid, skilllv)),
- skillid, skilllv, skill_get_hit(skillid));
- map_freeblock_unlock();
- return 1;
- }
+ if( flag&1 )
+ skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag|SD_LEVEL);
+ else
+ skill_addtimerskill(src, tick + 300, bl->id, 0, 0, skillid, skilllv, BF_WEAPON, flag|SD_LEVEL|2);
+ break;
+
+ case SR_HOWLINGOFLION:
+ status_change_end(bl, SC_SWINGDANCE, INVALID_TIMER);
+ status_change_end(bl, SC_SYMPHONYOFLOVER, INVALID_TIMER);
+ status_change_end(bl, SC_MOONLITSERENADE, INVALID_TIMER);
+ status_change_end(bl, SC_RUSHWINDMILL, INVALID_TIMER);
+ status_change_end(bl, SC_ECHOSONG, INVALID_TIMER);
+ status_change_end(bl, SC_HARMONIZE, INVALID_TIMER);
+ status_change_end(bl, SC_SIRCLEOFNATURE, INVALID_TIMER);
+ status_change_end(bl, SC_SATURDAYNIGHTFEVER, INVALID_TIMER);
+ status_change_end(bl, SC_DANCEWITHWUG, INVALID_TIMER);
+ status_change_end(bl, SC_LERADSDEW, INVALID_TIMER);
+ status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER);
+ status_change_end(bl, SC_BEYONDOFWARCRY, INVALID_TIMER);
+ status_change_end(bl, SC_UNLIMITEDHUMMINGVOICE, INVALID_TIMER);
+ skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag|SD_ANIMATION);
+ break;
+
+ case SR_EARTHSHAKER:
+ if( flag&1 ) { //by default cloaking skills are remove by aoe skills so no more checking/removing except hiding and cloaking exceed.
+ skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag);
+ status_change_end(bl, SC_HIDING, INVALID_TIMER);
+ status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
+ } else{
+ map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), splash_target(src), src, skillid, skilllv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill_castend_damage_id);
+ clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+ }
+ break;
+
+ case WM_LULLABY_DEEPSLEEP:
+ if( bl != src && rnd()%100 < 88 + 2 * skilllv )
+ sc_start(bl,status_skill2sc(skillid),100,skilllv,skill_get_time(skillid,skilllv));
+ break;
+
+ case SO_POISON_BUSTER: {
+ struct status_change *tsc = status_get_sc(bl);
+ if( tsc && tsc->data[SC_POISON] ) {
+ skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, flag);
+ status_change_end(bl, SC_POISON, INVALID_TIMER);
+ }
+ else if( sd )
+ clif_skill_fail(sd, skillid, USESKILL_FAIL_LEVEL, 0);
+ }
+ break;
+
+ case GN_SPORE_EXPLOSION:
+ if( flag&1 )
+ skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, flag);
+ else {
+ clif_skill_nodamage(src, bl, skillid, 0, 1);
+ skill_addtimerskill(src, gettick() + skill_get_time(skillid, skilllv) - 1000, bl->id, 0, 0, skillid, skilllv, 0, 0);
+ }
+ break;
+
+ case EL_FIRE_BOMB:
+ case EL_FIRE_WAVE:
+ case EL_WATER_SCREW:
+ case EL_HURRICANE:
+ case EL_TYPOON_MIS:
+ if( flag&1 )
+ skill_attack(skill_get_type(skillid+1),src,src,bl,skillid+1,skilllv,tick,flag);
+ else {
+ int i = skill_get_splash(skillid,skilllv);
+ clif_skill_nodamage(src,battle_get_master(src),skillid,skilllv,1);
+ clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+ if( rnd()%100 < 30 )
+ map_foreachinrange(skill_area_sub,bl,i,BL_CHAR,src,skillid,skilllv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
+ else
+ skill_attack(skill_get_type(skillid),src,src,bl,skillid,skilllv,tick,flag);
+ }
+ break;
+
+ case EL_ROCK_CRUSHER:
+ clif_skill_nodamage(src,battle_get_master(src),skillid,skilllv,1);
+ clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+ if( rnd()%100 < 50 )
+ skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag);
+ else
+ skill_attack(BF_WEAPON,src,src,bl,EL_ROCK_CRUSHER_ATK,skilllv,tick,flag);
+ break;
+
+ case EL_STONE_RAIN:
+ if( flag&1 )
+ skill_attack(skill_get_type(skillid),src,src,bl,skillid,skilllv,tick,flag);
+ else {
+ int i = skill_get_splash(skillid,skilllv);
+ clif_skill_nodamage(src,battle_get_master(src),skillid,skilllv,1);
+ clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+ if( rnd()%100 < 30 )
+ map_foreachinrange(skill_area_sub,bl,i,BL_CHAR,src,skillid,skilllv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
+ else
+ skill_attack(skill_get_type(skillid),src,src,bl,skillid,skilllv,tick,flag);
+ }
+ break;
+
+ case EL_FIRE_ARROW:
+ case EL_ICE_NEEDLE:
+ case EL_WIND_SLASH:
+ case EL_STONE_HAMMER:
+ clif_skill_nodamage(src,battle_get_master(src),skillid,skilllv,1);
+ clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+ skill_attack(skill_get_type(skillid),src,src,bl,skillid,skilllv,tick,flag);
+ break;
+
+ case EL_TIDAL_WEAPON:
+ if( src->type == BL_ELEM ) {
+ struct elemental_data *ele = BL_CAST(BL_ELEM,src);
+ struct status_change *sc = status_get_sc(&ele->bl);
+ struct status_change *tsc = status_get_sc(bl);
+ sc_type type = status_skill2sc(skillid), type2;
+ type2 = type-1;
+
+ clif_skill_nodamage(src,battle_get_master(src),skillid,skilllv,1);
+ clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+ if( (sc && sc->data[type2]) || (tsc && tsc->data[type]) ) {
+ elemental_clean_single_effect(ele, skillid);
+ }
+ if( rnd()%100 < 50 )
+ skill_attack(skill_get_type(skillid),src,src,bl,skillid,skilllv,tick,flag);
+ else {
+ sc_start(src,type2,100,skilllv,skill_get_time(skillid,skilllv));
+ sc_start(battle_get_master(src),type,100,ele->bl.id,skill_get_time(skillid,skilllv));
+ }
+ clif_skill_nodamage(src,src,skillid,skilllv,1);
+ }
+ break;
+
+
+ //recursive homon skill
+ case MH_MAGMA_FLOW:
+ case MH_XENO_SLASHER:
+ case MH_HEILIGE_STANGE:
+ if(flag & 1)
+ skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, flag);
+ else {
+ map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), splash_target(src), src, skillid, skilllv, tick, flag | BCT_ENEMY | SD_SPLASH | 1, skill_castend_damage_id);
+ }
+ break;
+ case MH_STAHL_HORN:
+ case MH_NEEDLE_OF_PARALYZE:
+ skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag);
+ break;
+
+ case 0:/* no skill - basic/normal attack */
+ if(sd) {
+ if (flag & 3){
+ if (bl->id != skill_area_temp[1])
+ skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, SD_LEVEL|flag);
+ } else {
+ skill_area_temp[1] = bl->id;
+ map_foreachinrange(skill_area_sub, bl,
+ sd->bonus.splash_range, BL_CHAR,
+ src, skillid, skilllv, tick, flag | BCT_ENEMY | 1,
+ skill_castend_damage_id);
+ flag|=1; //Set flag to 1 so ammo is not double-consumed. [Skotlex]
+ }
+ }
+ break;
+
+ default:
+ ShowWarning("skill_castend_damage_id: Unknown skill used:%d\n",skillid);
+ clif_skill_damage(src, bl, tick, status_get_amotion(src), tstatus->dmotion,
+ 0, abs(skill_get_num(skillid, skilllv)),
+ skillid, skilllv, skill_get_hit(skillid));
+ map_freeblock_unlock();
+ return 1;
+ }
- if (sc && sc->data[SC_CURSEDCIRCLE_ATKER]) //Should only remove after the skill has been casted.
- status_change_end(src,SC_CURSEDCIRCLE_ATKER,INVALID_TIMER);
+ if( sc && sc->data[SC_CURSEDCIRCLE_ATKER] ) //Should only remove after the skill has been casted.
+ status_change_end(src,SC_CURSEDCIRCLE_ATKER,INVALID_TIMER);
- map_freeblock_unlock();
+ map_freeblock_unlock();
- if (sd && !(flag&1)) {
- // ensure that the skill last-cast tick is recorded
- sd->canskill_tick = gettick();
+ if( sd && !(flag&1) )
+ {// ensure that the skill last-cast tick is recorded
+ sd->canskill_tick = gettick();
- if (sd->state.arrow_atk) {
- // consume arrow on last invocation to this skill.
- battle_consume_ammo(sd, skillid, skilllv);
- }
+ if( sd->state.arrow_atk )
+ {// consume arrow on last invocation to this skill.
+ battle_consume_ammo(sd, skillid, skilllv);
+ }
- // perform skill requirement consumption
- skill_consume_requirement(sd,skillid,skilllv,2);
- }
+ // perform skill requirement consumption
+ skill_consume_requirement(sd,skillid,skilllv,2);
+ }
- return 0;
+ return 0;
}
/*==========================================
*
*------------------------------------------*/
-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, *dstsd;
- struct mob_data *md, *dstmd;
- struct homun_data *hd;
- struct mercenary_data *mer;
- struct status_data *sstatus, *tstatus;
- struct status_change *tsc;
- struct status_change_entry *tsce;
-
- int i = 0;
- enum sc_type type;
-
- if (skillid > 0 && skilllv <= 0) return 0; // celest
-
- nullpo_retr(1, src);
- nullpo_retr(1, bl);
-
- if (src->m != bl->m)
- return 1;
-
- sd = BL_CAST(BL_PC, src);
- hd = BL_CAST(BL_HOM, src);
- md = BL_CAST(BL_MOB, src);
- mer = BL_CAST(BL_MER, src);
-
- dstsd = BL_CAST(BL_PC, bl);
- dstmd = BL_CAST(BL_MOB, bl);
-
- if (bl->prev == NULL)
- return 1;
- if (status_isdead(src))
- return 1;
-
- if (src != bl && status_isdead(bl)) {
- /**
- * Skills that may be cast on dead targets
- **/
- switch (skillid) {
- case NPC_WIDESOULDRAIN:
- case PR_REDEMPTIO:
- case ALL_RESURRECTION:
- case WM_DEADHILLHERE:
- break;
- default:
- return 1;
- }
- }
-
- tstatus = status_get_status_data(bl);
- sstatus = status_get_status_data(src);
-
- //Check for undead skills that convert a no-damage skill into a damage one. [Skotlex]
- switch (skillid) {
- case HLIF_HEAL: //[orn]
- if (bl->type != BL_HOM) {
- if (sd) clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0) ;
- break ;
- }
- case AL_HEAL:
- case ALL_RESURRECTION:
- case PR_ASPERSIO:
- /**
- * Arch Bishop
- **/
- case AB_RENOVATIO:
- case AB_HIGHNESSHEAL:
- //Apparently only player casted skills can be offensive like this.
- if (sd && battle_check_undead(tstatus->race,tstatus->def_ele)) {
- if (battle_check_target(src, bl, BCT_ENEMY) < 1) {
- //Offensive heal does not works on non-enemies. [Skotlex]
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- return skill_castend_damage_id(src, bl, skillid, skilllv, tick, flag);
- }
- break;
- case NPC_SMOKING: //Since it is a self skill, this one ends here rather than in damage_id. [Skotlex]
- return skill_castend_damage_id(src, bl, skillid, skilllv, tick, flag);
- case MH_STEINWAND: {
- struct block_list *s_src = battle_get_master(src);
- short ret = 0;
- if (!skill_check_unit_range(src, src->x, src->y, skillid, skilllv)) //prevent reiteration
- ret = skill_castend_pos2(src,src->x,src->y,skillid,skilllv,tick,flag); //cast on homon
- if (s_src && !skill_check_unit_range(s_src, s_src->x, s_src->y, skillid, skilllv))
- ret |= skill_castend_pos2(s_src,s_src->x,s_src->y,skillid,skilllv,tick,flag); //cast on master
- if (hd)
- skill_blockhomun_start(hd, skillid, skill_get_cooldown(skillid, skilllv));
- return ret;
- }
- break;
- default:
- //Skill is actually ground placed.
- if (src == bl && skill_get_unit_id(skillid,0))
- return skill_castend_pos2(src,bl->x,bl->y,skillid,skilllv,tick,0);
- }
-
- type = status_skill2sc(skillid);
- tsc = status_get_sc(bl);
- tsce = (tsc && type != -1)?tsc->data[type]:NULL;
-
- if (src!=bl && type > -1 &&
- (i = skill_get_ele(skillid, skilllv)) > ELE_NEUTRAL &&
- skill_get_inf(skillid) != INF_SUPPORT_SKILL &&
- battle_attr_fix(NULL, NULL, 100, i, tstatus->def_ele, tstatus->ele_lv) <= 0)
- return 1; //Skills that cause an status should be blocked if the target element blocks its element.
-
- map_freeblock_lock();
- switch (skillid) {
- case HLIF_HEAL: //[orn]
- case AL_HEAL:
- /**
- * Arch Bishop
- **/
- case AB_HIGHNESSHEAL: {
- int heal = skill_calc_heal(src, bl, (skillid == AB_HIGHNESSHEAL)?AL_HEAL:skillid, (skillid == AB_HIGHNESSHEAL)?10:skilllv, true);
- int heal_get_jobexp;
- //Highness Heal: starts at 1.5 boost + 0.5 for each level
- if (skillid == AB_HIGHNESSHEAL) {
- heal = heal * (15 + 5 * skilllv) / 10;
- }
- if (status_isimmune(bl) ||
- (dstmd && (dstmd->class_ == MOBID_EMPERIUM || mob_is_battleground(dstmd))) ||
- (dstsd && pc_ismadogear(dstsd))) //Mado is immune to heal
- heal=0;
-
- if (sd && dstsd && sd->status.partner_id == dstsd->status.char_id && (sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->status.sex == 0)
- heal = heal*2;
-
- if (tsc && tsc->count) {
- if (tsc->data[SC_KAITE] && !(sstatus->mode&MD_BOSS)) {
- //Bounce back heal
- if (--tsc->data[SC_KAITE]->val2 <= 0)
- status_change_end(bl, SC_KAITE, INVALID_TIMER);
- if (src == bl)
- heal=0; //When you try to heal yourself under Kaite, the heal is voided.
- else {
- bl = src;
- dstsd = sd;
- }
- } else if (tsc->data[SC_BERSERK] || tsc->data[SC_SATURDAYNIGHTFEVER] || tsc->data[SC__BLOODYLUST])
- heal = 0; //Needed so that it actually displays 0 when healing.
- }
- clif_skill_nodamage(src, bl, skillid, heal, 1);
- if (tsc && tsc->data[SC_AKAITSUKI] && heal && skillid != HLIF_HEAL)
- heal = ~heal + 1;
- heal_get_jobexp = status_heal(bl,heal,0,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)
- heal_get_jobexp = 1;
- pc_gainexp(sd, bl, 0, heal_get_jobexp, false);
- }
- }
- break;
-
- case PR_REDEMPTIO:
- if (sd && !(flag&1)) {
- if (sd->status.party_id == 0) {
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
- skill_area_temp[0] = 0;
- party_foreachsamemap(skill_area_sub,
- sd,skill_get_splash(skillid, skilllv),
- src,skillid,skilllv,tick, flag|BCT_PARTY|1,
- skill_castend_nodamage_id);
- if (skill_area_temp[0] == 0) {
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
- skill_area_temp[0] = 5 - skill_area_temp[0]; // The actual penalty...
- if (skill_area_temp[0] > 0 && !map[src->m].flag.noexppenalty) { //Apply penalty
- sd->status.base_exp -= min(sd->status.base_exp, pc_nextbaseexp(sd) * skill_area_temp[0] * 2/1000); //0.2% penalty per each.
- sd->status.job_exp -= min(sd->status.job_exp, pc_nextjobexp(sd) * skill_area_temp[0] * 2/1000);
- clif_updatestatus(sd,SP_BASEEXP);
- clif_updatestatus(sd,SP_JOBEXP);
- }
- status_set_hp(src, 1, 0);
- status_set_sp(src, 0, 0);
- break;
- } else if (status_isdead(bl) && flag&1) { //Revive
- skill_area_temp[0]++; //Count it in, then fall-through to the Resurrection code.
- skilllv = 3; //Resurrection level 3 is used
- } else //Invalid target, skip resurrection.
- break;
-
- case ALL_RESURRECTION:
- if (sd && (map_flag_gvg(bl->m) || map[bl->m].flag.battleground)) {
- //No reviving in WoE grounds!
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
- if (!status_isdead(bl))
- break;
- {
- int per = 0, sper = 0;
- if (tsc && tsc->data[SC_HELLPOWER])
- break;
-
- if (map[bl->m].flag.pvp && dstsd && dstsd->pvp_point < 0)
- break;
-
- switch (skilllv) {
- case 1:
- per=10;
- break;
- case 2:
- per=30;
- break;
- case 3:
- per=50;
- break;
- case 4:
- per=80;
- break;
- }
- if (dstsd && dstsd->special_state.restart_full_recover)
- per = sper = 100;
- if (status_revive(bl, per, sper)) {
- clif_skill_nodamage(src,bl,ALL_RESURRECTION,skilllv,1); //Both Redemptio and Res show this skill-animation.
- if (sd && dstsd && battle_config.resurrection_exp > 0) {
- int exp = 0,jexp = 0;
- int lv = dstsd->status.base_level - sd->status.base_level, jlv = dstsd->status.job_level - sd->status.job_level;
- if (lv > 0 && pc_nextbaseexp(dstsd)) {
- exp = (int)((double)dstsd->status.base_exp * (double)lv * (double)battle_config.resurrection_exp / 1000000.);
- if (exp < 1) exp = 1;
- }
- if (jlv > 0 && pc_nextjobexp(dstsd)) {
- 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, bl, exp, jexp, false);
- }
- }
- }
- break;
-
- case AL_DECAGI:
- case MER_DECAGI:
- clif_skill_nodamage(src, bl, skillid, skilllv,
- sc_start(bl, type, (40 + skilllv * 2 + (status_get_lv(src) + sstatus->int_)/5), skilllv, skill_get_time(skillid,skilllv)));
- break;
-
- case AL_CRUCIS:
- if (flag&1)
- sc_start(bl,type, 23+skilllv*4 +status_get_lv(src) -status_get_lv(bl), skilllv,skill_get_time(skillid,skilllv));
- else {
- map_foreachinrange(skill_area_sub, src, skill_get_splash(skillid, skilllv), BL_CHAR,
- src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_nodamage_id);
- clif_skill_nodamage(src, bl, skillid, skilllv, 1);
- }
- break;
-
- case PR_LEXDIVINA:
- case MER_LEXDIVINA:
- if (tsce)
- status_change_end(bl,type, INVALID_TIMER);
- else
- sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv));
- clif_skill_nodamage(src, bl, skillid, skilllv, 1);
- break;
-
- case SA_ABRACADABRA: {
- int abra_skillid = 0, abra_skilllv;
- do {
- i = rnd() % MAX_SKILL_ABRA_DB;
- abra_skillid = skill_abra_db[i].skillid;
- } while (abra_skillid == 0 ||
- skill_abra_db[i].req_lv > skilllv || //Required lv for it to appear
- rnd()%10000 >= skill_abra_db[i].per
- );
- abra_skilllv = min(skilllv, skill_get_max(abra_skillid));
- clif_skill_nodamage(src, bl, skillid, skilllv, 1);
-
- if (sd) {
- // player-casted
- sd->state.abra_flag = 1;
- sd->skillitem = abra_skillid;
- sd->skillitemlv = abra_skilllv;
- clif_item_skill(sd, abra_skillid, abra_skilllv);
- } else {
- // mob-casted
- struct unit_data *ud = unit_bl2ud(src);
- int inf = skill_get_inf(abra_skillid);
- int target_id = 0;
- if (!ud) break;
- if (inf&INF_SELF_SKILL || inf&INF_SUPPORT_SKILL) {
- if (src->type == BL_PET)
- bl = (struct block_list *)((TBL_PET *)src)->msd;
- if (!bl) bl = src;
- unit_skilluse_id(src, bl->id, abra_skillid, abra_skilllv);
- } else { //Assume offensive skills
- if (ud->target)
- target_id = ud->target;
- else switch (src->type) {
- case BL_MOB:
- target_id = ((TBL_MOB *)src)->target_id;
- break;
- case BL_PET:
- target_id = ((TBL_PET *)src)->target_id;
- break;
- }
- if (!target_id)
- break;
- if (skill_get_casttype(abra_skillid) == CAST_GROUND) {
- bl = map_id2bl(target_id);
- if (!bl) bl = src;
- unit_skilluse_pos(src, bl->x, bl->y, abra_skillid, abra_skilllv);
- } else
- unit_skilluse_id(src, target_id, abra_skillid, abra_skilllv);
- }
- }
- }
- break;
-
- case SA_COMA:
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start(bl,type,100,skilllv,skill_get_time2(skillid,skilllv)));
- break;
- case SA_FULLRECOVERY:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if (status_isimmune(bl))
- break;
- status_percent_heal(bl, 100, 100);
- break;
- case NPC_ALLHEAL: {
- int heal;
- if (status_isimmune(bl))
- break;
- heal = status_percent_heal(bl, 100, 0);
- clif_skill_nodamage(NULL, bl, AL_HEAL, heal, 1);
- if (dstmd) {
- // Reset Damage Logs
- memset(dstmd->dmglog, 0, sizeof(dstmd->dmglog));
- dstmd->tdmg = 0;
- }
- }
- break;
- case SA_SUMMONMONSTER:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if (sd) mob_once_spawn(sd, src->m, src->x, src->y," --ja--", -1, 1, "", SZ_SMALL, AI_NONE);
- break;
- case SA_LEVELUP:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if (sd && pc_nextbaseexp(sd)) pc_gainexp(sd, NULL, pc_nextbaseexp(sd) * 10 / 100, 0, false);
- break;
- case SA_INSTANTDEATH:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- status_set_hp(bl,1,0);
- break;
- case SA_QUESTION:
- case SA_GRAVITY:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- break;
- case SA_CLASSCHANGE:
- case SA_MONOCELL:
- if (dstmd) {
- int class_;
- if (sd && dstmd->status.mode&MD_BOSS) {
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
- class_ = skillid==SA_MONOCELL?1002:mob_get_random_id(4, 1, 0);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- mob_class_change(dstmd,class_);
- if (tsc && dstmd->status.mode&MD_BOSS) {
- const enum sc_type scs[] = { SC_QUAGMIRE, SC_PROVOKE, SC_ROKISWEIL, SC_GRAVITATION, SC_SUITON, SC_STRIPWEAPON, SC_STRIPSHIELD, SC_STRIPARMOR, SC_STRIPHELM, SC_BLADESTOP };
- for (i = SC_COMMON_MIN; i <= SC_COMMON_MAX; i++)
- if (tsc->data[i]) status_change_end(bl, (sc_type)i, INVALID_TIMER);
- for (i = 0; i < ARRAYLENGTH(scs); i++)
- if (tsc->data[scs[i]]) status_change_end(bl, scs[i], INVALID_TIMER);
- }
- }
- break;
- case SA_DEATH:
- if (sd && dstmd && dstmd->status.mode&MD_BOSS) {
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- status_kill(bl);
- break;
- case SA_REVERSEORCISH:
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start(bl,type,100,skilllv,skill_get_time(skillid, skilllv)));
- break;
- case SA_FORTUNE:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if (sd) pc_getzeny(sd,status_get_lv(bl)*100,LOG_TYPE_STEAL,NULL);
- break;
- case SA_TAMINGMONSTER:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if (sd && dstmd) {
- ARR_FIND(0, MAX_PET_DB, i, dstmd->class_ == pet_db[i].class_);
- if (i < MAX_PET_DB)
- pet_catch_process1(sd, dstmd->class_);
- }
- break;
-
- case CR_PROVIDENCE:
- if (sd && dstsd) { //Check they are not another crusader [Skotlex]
- if ((dstsd->class_&MAPID_UPPERMASK) == MAPID_CRUSADER) {
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- map_freeblock_unlock();
- return 1;
- }
- }
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
- break;
-
- case CG_MARIONETTE: {
- struct status_change *sc = status_get_sc(src);
-
- if (sd && dstsd && (dstsd->class_&MAPID_UPPERMASK) == MAPID_BARDDANCER && dstsd->status.sex == sd->status.sex) {
- // Cannot cast on another bard/dancer-type class of the same gender as caster
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- map_freeblock_unlock();
- return 1;
- }
-
- if (sc && tsc) {
- if (!sc->data[SC_MARIONETTE] && !tsc->data[SC_MARIONETTE2]) {
- sc_start(src,SC_MARIONETTE,100,bl->id,skill_get_time(skillid,skilllv));
- sc_start(bl,SC_MARIONETTE2,100,src->id,skill_get_time(skillid,skilllv));
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- } else if (sc->data[SC_MARIONETTE ] && sc->data[SC_MARIONETTE ]->val1 == bl->id &&
- tsc->data[SC_MARIONETTE2] && tsc->data[SC_MARIONETTE2]->val1 == src->id) {
- status_change_end(src, SC_MARIONETTE, INVALID_TIMER);
- status_change_end(bl, SC_MARIONETTE2, INVALID_TIMER);
- } else {
- if (sd)
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
-
- map_freeblock_unlock();
- return 1;
- }
- }
- }
- break;
-
- case RG_CLOSECONFINE:
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start4(bl,type,100,skilllv,src->id,0,0,skill_get_time(skillid,skilllv)));
- 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 (dstsd) {
- if (dstsd->status.weapon == W_FIST ||
- (dstsd->sc.count && !dstsd->sc.data[type] &&
- ( //Allow re-enchanting to lenghten time. [Skotlex]
- dstsd->sc.data[SC_FIREWEAPON] ||
- dstsd->sc.data[SC_WATERWEAPON] ||
- dstsd->sc.data[SC_WINDWEAPON] ||
- dstsd->sc.data[SC_EARTHWEAPON] ||
- dstsd->sc.data[SC_SHADOWWEAPON] ||
- dstsd->sc.data[SC_GHOSTWEAPON] ||
- dstsd->sc.data[SC_ENCPOISON]
- ))
- ) {
- if (sd) clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- clif_skill_nodamage(src,bl,skillid,skilllv,0);
- break;
- }
- }
- // 100% success rate at lv4 & 5, but lasts longer at lv5
- if (!clif_skill_nodamage(src,bl,skillid,skilllv, sc_start(bl,type,(60+skilllv*10),skilllv, skill_get_time(skillid,skilllv)))) {
- if (sd)
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- if (skill_break_equip(bl, EQP_WEAPON, 10000, BCT_PARTY) && sd && sd != dstsd)
- clif_displaymessage(sd->fd, msg_txt(669));
- }
- break;
-
- case PR_ASPERSIO:
- if (sd && dstmd) {
- clif_skill_nodamage(src,bl,skillid,skilllv,0);
- break;
- }
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
- break;
-
- case ITEM_ENCHANTARMS:
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start2(bl,type,100,skilllv,
- skill_get_ele(skillid,skilllv), skill_get_time(skillid,skilllv)));
- break;
-
- case TK_SEVENWIND:
- switch (skill_get_ele(skillid,skilllv)) {
- case ELE_EARTH :
- type = SC_EARTHWEAPON;
- break;
- case ELE_WIND :
- type = SC_WINDWEAPON;
- break;
- case ELE_WATER :
- type = SC_WATERWEAPON;
- break;
- case ELE_FIRE :
- type = SC_FIREWEAPON;
- break;
- case ELE_GHOST :
- type = SC_GHOSTWEAPON;
- break;
- case ELE_DARK :
- type = SC_SHADOWWEAPON;
- break;
- case ELE_HOLY :
- type = SC_ASPERSIO;
- break;
- }
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
-
- sc_start(bl,SC_SEVENWIND,100,skilllv,skill_get_time(skillid,skilllv));
-
- break;
-
- case PR_KYRIE:
- case MER_KYRIE:
- clif_skill_nodamage(bl,bl,skillid,skilllv,
- sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
- break;
- //Passive Magnum, should had been casted on yourself.
- case SM_MAGNUM:
- case MS_MAGNUM:
- skill_area_temp[1] = 0;
- map_foreachinrange(skill_area_sub, src, skill_get_splash(skillid, skilllv), BL_SKILL|BL_CHAR,
- src,skillid,skilllv,tick, flag|BCT_ENEMY|1, skill_castend_damage_id);
- clif_skill_nodamage(src,src,skillid,skilllv,1);
- // Initiate 10% of your damage becomes fire element.
- sc_start4(src,SC_WATK_ELEMENT,100,3,20,0,0,skill_get_time2(skillid, skilllv));
- if (sd)
- skill_blockpc_start(sd, skillid, skill_get_time(skillid, skilllv));
- else if (bl->type == BL_MER)
- skill_blockmerc_start((TBL_MER *)bl, skillid, skill_get_time(skillid, skilllv));
- break;
-
- case TK_JUMPKICK:
- /* Check if the target is an enemy; if not, skill should fail so the character doesn't unit_movepos (exploitable) */
- if (battle_check_target(src, bl, BCT_ENEMY) > 0) {
- if (unit_movepos(src, bl->x, bl->y, 1, 1)) {
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- clif_slide(src,bl->x,bl->y);
- }
- } else
- clif_skill_fail(sd,skillid,USESKILL_FAIL,0);
- break;
-
- case AL_INCAGI:
- case AL_BLESSING:
- case MER_INCAGI:
- case MER_BLESSING:
- if (dstsd != NULL && tsc->data[SC_CHANGEUNDEAD]) {
- skill_attack(BF_MISC,src,src,bl,skillid,skilllv,tick,flag);
- break;
- }
- case PR_SLOWPOISON:
- case PR_IMPOSITIO:
- case PR_LEXAETERNA:
- case PR_SUFFRAGIUM:
- case PR_BENEDICTIO:
- case LK_BERSERK:
- case MS_BERSERK:
- case KN_AUTOCOUNTER:
- case KN_TWOHANDQUICKEN:
- case KN_ONEHAND:
- case MER_QUICKEN:
- case CR_SPEARQUICKEN:
- case CR_REFLECTSHIELD:
- case MS_REFLECTSHIELD:
- case AS_POISONREACT:
- case MC_LOUD:
- case MG_ENERGYCOAT:
- case MO_EXPLOSIONSPIRITS:
- case MO_STEELBODY:
- case MO_BLADESTOP:
- case LK_AURABLADE:
- case LK_PARRYING:
- case MS_PARRYING:
- case LK_CONCENTRATION:
- case WS_CARTBOOST:
- case SN_SIGHT:
- case WS_MELTDOWN:
- case WS_OVERTHRUSTMAX:
- case ST_REJECTSWORD:
- case HW_MAGICPOWER:
- case PF_MEMORIZE:
- case PA_SACRIFICE:
- case ASC_EDP:
- case PF_DOUBLECASTING:
- case SG_SUN_COMFORT:
- case SG_MOON_COMFORT:
- case SG_STAR_COMFORT:
- case NPC_HALLUCINATION:
- case GS_MADNESSCANCEL:
- case GS_ADJUSTMENT:
- case GS_INCREASING:
- case NJ_KASUMIKIRI:
- case NJ_UTSUSEMI:
- case NJ_NEN:
- case NPC_DEFENDER:
- case NPC_MAGICMIRROR:
- case ST_PRESERVE:
- case NPC_INVINCIBLE:
- case NPC_INVINCIBLEOFF:
- case RK_DEATHBOUND:
- case AB_RENOVATIO:
- case AB_EXPIATIO:
- case AB_DUPLELIGHT:
- case AB_SECRAMENT:
- case NC_ACCELERATION:
- case NC_HOVERING:
- case NC_SHAPESHIFT:
- case WL_RECOGNIZEDSPELL:
- case GC_VENOMIMPRESS:
- case SC_DEADLYINFECT:
- case LG_EXEEDBREAK:
- case LG_PRESTIGE:
- case SR_CRESCENTELBOW:
- case SR_LIGHTNINGWALK:
- case SR_GENTLETOUCH_ENERGYGAIN:
- case GN_CARTBOOST:
- case KO_MEIKYOUSISUI:
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
- break;
-
- case SO_STRIKING:
- if (sd) {
- int bonus = 25 + 10 * skilllv;
- bonus += (pc_checkskill(sd, SA_FLAMELAUNCHER)+pc_checkskill(sd, SA_FROSTWEAPON)+pc_checkskill(sd, SA_LIGHTNINGLOADER)+pc_checkskill(sd, SA_SEISMICWEAPON))*5;
- clif_skill_nodamage(src, bl, skillid, skilllv,
- battle_check_target(src,bl,BCT_PARTY) ?
- sc_start2(bl, type, 100, skilllv, bonus, skill_get_time(skillid,skilllv)) :
- 0
- );
- }
- break;
-
- case NPC_STOP:
- if (clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start2(bl,type,100,skilllv,src->id,skill_get_time(skillid,skilllv))))
- sc_start2(src,type,100,skilllv,bl->id,skill_get_time(skillid,skilllv));
- break;
- case HP_ASSUMPTIO:
- if (sd && dstmd)
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- else
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
- break;
- case MG_SIGHT:
- case MER_SIGHT:
- case AL_RUWACH:
- case WZ_SIGHTBLASTER:
- case NPC_WIDESIGHT:
- case NPC_STONESKIN:
- case NPC_ANTIMAGIC:
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start2(bl,type,100,skilllv,skillid,skill_get_time(skillid,skilllv)));
- break;
- case HLIF_AVOID:
- case HAMI_DEFENCE:
- i = skill_get_time(skillid,skilllv);
- clif_skill_nodamage(bl,bl,skillid,skilllv,sc_start(bl,type,100,skilllv,i)); // Master
- clif_skill_nodamage(src,src,skillid,skilllv,sc_start(src,type,100,skilllv,i)); // Homunc
- break;
- case NJ_BUNSINJYUTSU:
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
- status_change_end(bl, SC_NEN, INVALID_TIMER);
- break;
- /* Was modified to only affect targetted char. [Skotlex]
- case HP_ASSUMPTIO:
- if (flag&1)
- sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv));
- else
- {
- map_foreachinrange(skill_area_sub, bl,
- skill_get_splash(skillid, skilllv), BL_PC,
- src, skillid, skilllv, tick, flag|BCT_ALL|1,
- skill_castend_nodamage_id);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- }
- break;
- */
- case SM_ENDURE:
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
- if (sd)
- skill_blockpc_start(sd, skillid, skill_get_time2(skillid,skilllv));
- break;
-
- case AS_ENCHANTPOISON: // Prevent spamming [Valaris]
- if (sd && dstsd && dstsd->sc.count) {
- if (dstsd->sc.data[SC_FIREWEAPON] ||
- dstsd->sc.data[SC_WATERWEAPON] ||
- dstsd->sc.data[SC_WINDWEAPON] ||
- dstsd->sc.data[SC_EARTHWEAPON] ||
- dstsd->sc.data[SC_SHADOWWEAPON] ||
- dstsd->sc.data[SC_GHOSTWEAPON]
- // dstsd->sc.data[SC_ENCPOISON] //People say you should be able to recast to lengthen the timer. [Skotlex]
- ) {
- clif_skill_nodamage(src,bl,skillid,skilllv,0);
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
- }
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
- break;
-
- case LK_TENSIONRELAX:
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start4(bl,type,100,skilllv,0,0,skill_get_time2(skillid,skilllv),
- skill_get_time(skillid,skilllv)));
- break;
-
- case MC_CHANGECART:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- break;
-
- case TK_MISSION:
- if (sd) {
- int id;
- if (sd->mission_mobid && (sd->mission_count || rnd()%100)) { //Cannot change target when already have one
- clif_mission_info(sd, sd->mission_mobid, sd->mission_count);
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
- id = mob_get_random_id(0,0xF, sd->status.base_level);
- if (!id) {
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
- sd->mission_mobid = id;
- sd->mission_count = 0;
- pc_setglobalreg(sd,"TK_MISSION_ID", id);
- clif_mission_info(sd, id, 0);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- }
- break;
-
- case AC_CONCENTRATION: {
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
- map_foreachinrange(status_change_timer_sub, src,
- skill_get_splash(skillid, skilllv), BL_CHAR,
- src,NULL,type,tick);
- }
- break;
-
- case SM_PROVOKE:
- case SM_SELFPROVOKE:
- case MER_PROVOKE:
- if ((tstatus->mode&MD_BOSS) || battle_check_undead(tstatus->race,tstatus->def_ele)) {
- map_freeblock_unlock();
- return 1;
- }
- //TODO: How much does base level affects? Dummy value of 1% per level difference used. [Skotlex]
- clif_skill_nodamage(src,bl,skillid == SM_SELFPROVOKE ? SM_PROVOKE : skillid,skilllv,
- (i = sc_start(bl,type, skillid == SM_SELFPROVOKE ? 100:(50 + 3*skilllv + status_get_lv(src) - status_get_lv(bl)), skilllv, skill_get_time(skillid,skilllv))));
- if (!i) {
- if (sd)
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- map_freeblock_unlock();
- return 0;
- }
- unit_skillcastcancel(bl, 2);
-
- if (tsc && tsc->count) {
- status_change_end(bl, SC_FREEZE, INVALID_TIMER);
- if (tsc->data[SC_STONE] && tsc->opt1 == OPT1_STONE)
- status_change_end(bl, SC_STONE, INVALID_TIMER);
- status_change_end(bl, SC_SLEEP, INVALID_TIMER);
- status_change_end(bl, SC_TRICKDEAD, INVALID_TIMER);
- }
-
- if (dstmd) {
- dstmd->state.provoke_flag = src->id;
- mob_target(dstmd, src, skill_get_range2(src,skillid,skilllv));
- }
- break;
-
- case ML_DEVOTION:
- case CR_DEVOTION: {
- int count, lv;
- if (!dstsd || (!sd && !mer)) {
- // Only players can be devoted
- if (sd)
- clif_skill_fail(sd, skillid, USESKILL_FAIL_LEVEL, 0);
- break;
- }
-
- if ((lv = status_get_lv(src) - dstsd->status.base_level) < 0)
- lv = -lv;
- if (lv > battle_config.devotion_level_difference || // Level difference requeriments
- (dstsd->sc.data[type] && dstsd->sc.data[type]->val1 != src->id) || // Cannot Devote a player devoted from another source
- (skillid == ML_DEVOTION && (!mer || mer != dstsd->md)) || // Mercenary only can devote owner
- (dstsd->class_&MAPID_UPPERMASK) == MAPID_CRUSADER || // Crusader Cannot be devoted
- (dstsd->sc.data[SC_HELLPOWER])) { // Players affected by SC_HELLPOWERR cannot be devoted.
- if (sd)
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- map_freeblock_unlock();
- return 1;
- }
-
- i = 0;
- count = (sd)? min(skilllv,5) : 1; // Mercenary only can Devote owner
- if (sd) {
- // Player Devoting Player
- ARR_FIND(0, count, i, sd->devotion[i] == bl->id);
- if (i == count) {
- ARR_FIND(0, count, i, sd->devotion[i] == 0);
- if (i == count) {
- // No free slots, skill Fail
- clif_skill_fail(sd, skillid, USESKILL_FAIL_LEVEL, 0);
- map_freeblock_unlock();
- return 1;
- }
- }
-
- sd->devotion[i] = bl->id;
- } else
- mer->devotion_flag = 1; // Mercenary Devoting Owner
-
- clif_skill_nodamage(src, bl, skillid, skilllv,
- sc_start4(bl, type, 100, src->id, i, skill_get_range2(src,skillid,skilllv),0, skill_get_time2(skillid, skilllv)));
- clif_devotion(src, NULL);
- }
- break;
-
- case MO_CALLSPIRITS:
- if (sd) {
- int limit = skilllv;
- if (sd->sc.data[SC_RAISINGDRAGON])
- limit += sd->sc.data[SC_RAISINGDRAGON]->val1;
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- pc_addspiritball(sd,skill_get_time(skillid,skilllv),limit);
- }
- break;
-
- case CH_SOULCOLLECT:
- if (sd) {
- int limit = 5;
- if (sd->sc.data[SC_RAISINGDRAGON])
- limit += sd->sc.data[SC_RAISINGDRAGON]->val1;
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- for (i = 0; i < limit; i++)
- pc_addspiritball(sd,skill_get_time(skillid,skilllv),limit);
- }
- break;
-
- case MO_KITRANSLATION:
- if (dstsd && (dstsd->class_&MAPID_BASEMASK)!=MAPID_GUNSLINGER) {
- pc_addspiritball(dstsd,skill_get_time(skillid,skilllv),5);
- }
- break;
-
- case TK_TURNKICK:
- case MO_BALKYOUNG: //Passive part of the attack. Splash knock-back+stun. [Skotlex]
- if (skill_area_temp[1] != bl->id) {
- skill_blown(src,bl,skill_get_blewcount(skillid,skilllv),-1,0);
- skill_additional_effect(src,bl,skillid,skilllv,BF_MISC,ATK_DEF,tick); //Use Misc rather than weapon to signal passive pushback
- }
- break;
-
- case MO_ABSORBSPIRITS:
- i = 0;
- if (dstsd && dstsd->spiritball && (sd == dstsd || map_flag_vs(src->m)) && (dstsd->class_&MAPID_BASEMASK)!=MAPID_GUNSLINGER) {
- // split the if for readability, and included gunslingers in the check so that their coins cannot be removed [Reddozen]
- i = dstsd->spiritball * 7;
- pc_delspiritball(dstsd,dstsd->spiritball,0);
- } else if (dstmd && !(tstatus->mode&MD_BOSS) && rnd() % 100 < 20) {
- // check if target is a monster and not a Boss, for the 20% chance to absorb 2 SP per monster's level [Reddozen]
- i = 2 * dstmd->level;
- mob_target(dstmd,src,0);
- }
- if (i) status_heal(src, 0, i, 3);
- clif_skill_nodamage(src,bl,skillid,skilllv,i?1:0);
- break;
-
- case AC_MAKINGARROW:
- if (sd) {
- clif_arrow_create_list(sd);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- }
- break;
-
- case AM_PHARMACY:
- if (sd) {
- clif_skill_produce_mix_list(sd,skillid,22);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- }
- break;
-
- case SA_CREATECON:
- if (sd) {
- clif_elementalconverter_list(sd);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- }
- break;
-
- case BS_HAMMERFALL:
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start(bl,SC_STUN,(20 + 10 * skilllv),skilllv,skill_get_time2(skillid,skilllv)));
- break;
- case RG_RAID:
- skill_area_temp[1] = 0;
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- map_foreachinrange(skill_area_sub, bl,
- skill_get_splash(skillid, skilllv), splash_target(src),
- src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
- skill_castend_damage_id);
- status_change_end(src, SC_HIDING, INVALID_TIMER);
- break;
-
- case ASC_METEORASSAULT:
- case GS_SPREADATTACK:
- case RK_STORMBLAST:
- case NC_AXETORNADO:
- case GC_COUNTERSLASH:
- case SR_SKYNETBLOW:
- case SR_RAMPAGEBLASTER:
- case SR_HOWLINGOFLION:
- case KO_HAPPOKUNAI:
- skill_area_temp[1] = 0;
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- i = map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), splash_target(src),
- src, skillid, skilllv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill_castend_damage_id);
- if (!i && (skillid == NC_AXETORNADO || skillid == SR_SKYNETBLOW || skillid == KO_HAPPOKUNAI))
- clif_skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
- break;
-
- case NC_EMERGENCYCOOL:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- status_change_end(src,SC_OVERHEAT_LIMITPOINT,INVALID_TIMER);
- status_change_end(src,SC_OVERHEAT,INVALID_TIMER);
- break;
- case SR_WINDMILL:
- case GN_CART_TORNADO:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- case SR_EARTHSHAKER:
- case NC_INFRAREDSCAN:
- case NPC_EARTHQUAKE:
- case NPC_VAMPIRE_GIFT:
- case NPC_HELLJUDGEMENT:
- case NPC_PULSESTRIKE:
- case LG_MOONSLASHER:
- skill_castend_damage_id(src, src, skillid, skilllv, tick, flag);
- break;
-
- case KN_BRANDISHSPEAR:
- case ML_BRANDISH:
- skill_brandishspear(src, bl, skillid, skilllv, tick, flag);
- break;
-
- case WZ_SIGHTRASHER:
- //Passive side of the attack.
- status_change_end(src, SC_SIGHT, INVALID_TIMER);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- map_foreachinrange(skill_area_sub,src,
- skill_get_splash(skillid, skilllv),BL_CHAR|BL_SKILL,
- src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
- skill_castend_damage_id);
- break;
-
- case NJ_HYOUSYOURAKU:
- case NJ_RAIGEKISAI:
- case WZ_FROSTNOVA:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- skill_area_temp[1] = 0;
- map_foreachinrange(skill_attack_area, src,
- skill_get_splash(skillid, skilllv), splash_target(src),
- BF_MAGIC, src, src, skillid, skilllv, tick, flag, BCT_ENEMY);
- break;
-
- case HVAN_EXPLOSION: //[orn]
- case NPC_SELFDESTRUCTION:
- //Self Destruction hits everyone in range (allies+enemies)
- //Except for Summoned Marine spheres on non-versus maps, where it's just enemy.
- i = ((!md || md->special_state.ai == 2) && !map_flag_vs(src->m))?
- BCT_ENEMY:BCT_ALL;
- clif_skill_nodamage(src, src, skillid, -1, 1);
- map_delblock(src); //Required to prevent chain-self-destructions hitting back.
- map_foreachinrange(skill_area_sub, bl,
- skill_get_splash(skillid, skilllv), splash_target(src),
- src, skillid, skilllv, tick, flag|i,
- skill_castend_damage_id);
- map_addblock(src);
- status_damage(src, src, sstatus->max_hp,0,0,1);
- break;
-
- case AL_ANGELUS:
- case PR_MAGNIFICAT:
- case PR_GLORIA:
- case SN_WINDWALK:
- case CASH_BLESSING:
- case CASH_INCAGI:
- case CASH_ASSUMPTIO:
- if (sd == NULL || sd->status.party_id == 0 || (flag & 1))
- clif_skill_nodamage(bl, bl, skillid, skilllv, sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
- else if (sd)
- party_foreachsamemap(skill_area_sub, sd, skill_get_splash(skillid, skilllv), src, skillid, skilllv, tick, flag|BCT_PARTY|1, skill_castend_nodamage_id);
- break;
- case MER_MAGNIFICAT:
- if (mer != NULL) {
- clif_skill_nodamage(bl, bl, skillid, skilllv, sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
- if (mer->master && mer->master->status.party_id != 0 && !(flag&1))
- party_foreachsamemap(skill_area_sub, mer->master, skill_get_splash(skillid, skilllv), src, skillid, skilllv, tick, flag|BCT_PARTY|1, skill_castend_nodamage_id);
- else if (mer->master && !(flag&1))
- clif_skill_nodamage(src, &mer->master->bl, skillid, skilllv, sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
- }
- break;
-
- case BS_ADRENALINE:
- case BS_ADRENALINE2:
- case BS_WEAPONPERFECT:
- case BS_OVERTHRUST:
- if (sd == NULL || sd->status.party_id == 0 || (flag & 1)) {
- clif_skill_nodamage(bl,bl,skillid,skilllv,
- sc_start2(bl,type,100,skilllv,(src == bl)? 1:0,skill_get_time(skillid,skilllv)));
- } else if (sd) {
- party_foreachsamemap(skill_area_sub,
- sd,skill_get_splash(skillid, skilllv),
- src,skillid,skilllv,tick, flag|BCT_PARTY|1,
- skill_castend_nodamage_id);
- }
- break;
-
- case BS_MAXIMIZE:
- case NV_TRICKDEAD:
- case CR_DEFENDER:
- case ML_DEFENDER:
- case CR_AUTOGUARD:
- case ML_AUTOGUARD:
- case TK_READYSTORM:
- case TK_READYDOWN:
- case TK_READYTURN:
- case TK_READYCOUNTER:
- case TK_DODGE:
- case CR_SHRINK:
- case SG_FUSION:
- case GS_GATLINGFEVER:
- if (tsce) {
- clif_skill_nodamage(src,bl,skillid,skilllv,status_change_end(bl, type, INVALID_TIMER));
- map_freeblock_unlock();
- return 0;
- }
- clif_skill_nodamage(src,bl,skillid,skilllv,sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
- break;
- case SL_KAITE:
- case SL_KAAHI:
- case SL_KAIZEL:
- case SL_KAUPE:
- if (sd) {
- if (!dstsd || !(
- (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_SOULLINKER) ||
- (dstsd->class_&MAPID_UPPERMASK) == MAPID_SOUL_LINKER ||
- dstsd->status.char_id == sd->status.char_id ||
- dstsd->status.char_id == sd->status.partner_id ||
- dstsd->status.char_id == sd->status.child
- )) {
- status_change_start(src,SC_STUN,10000,skilllv,0,0,0,500,8);
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
- }
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start(bl,type,100,skilllv,skill_get_time(skillid, skilllv)));
- break;
- case SM_AUTOBERSERK:
- case MER_AUTOBERSERK:
- if (tsce)
- i = status_change_end(bl, type, INVALID_TIMER);
- else
- i = sc_start(bl,type,100,skilllv,60000);
- clif_skill_nodamage(src,bl,skillid,skilllv,i);
- break;
- case TF_HIDING:
- case ST_CHASEWALK:
- case KO_YAMIKUMO:
- if (tsce) {
- clif_skill_nodamage(src,bl,skillid,-1,status_change_end(bl, type, INVALID_TIMER)); //Hide skill-scream animation.
- map_freeblock_unlock();
- return 0;
- } else if (tsc && tsc->option&OPTION_MADOGEAR) {
- //Mado Gear cannot hide
- if (sd) clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- map_freeblock_unlock();
- return 0;
- }
- clif_skill_nodamage(src,bl,skillid,-1,sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
- break;
- case TK_RUN:
- if (tsce) {
- clif_skill_nodamage(src,bl,skillid,skilllv,status_change_end(bl, type, INVALID_TIMER));
- map_freeblock_unlock();
- return 0;
- }
- clif_skill_nodamage(src,bl,skillid,skilllv,sc_start4(bl,type,100,skilllv,unit_getdir(bl),0,0,0));
- if (sd) // If the client receives a skill-use packet inmediately before a walkok packet, it will discard the walk packet! [Skotlex]
- clif_walkok(sd); // So aegis has to resend the walk ok.
- break;
- case AS_CLOAKING:
- case GC_CLOAKINGEXCEED:
- case LG_FORCEOFVANGUARD:
- case SC_REPRODUCE:
- case SC_INVISIBILITY:
- if (tsce) {
- i = status_change_end(bl, type, INVALID_TIMER);
- if (i)
- clif_skill_nodamage(src,bl,skillid,(skillid == LG_FORCEOFVANGUARD) ? skilllv : -1,i);
- else if (sd)
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- map_freeblock_unlock();
- return 0;
- }
- case RA_CAMOUFLAGE:
- i = sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv));
- if (i)
- clif_skill_nodamage(src,bl,skillid,(skillid == LG_FORCEOFVANGUARD) ? skilllv : -1,i);
- else if (sd)
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
-
- case BD_ADAPTATION:
- if (tsc && tsc->data[SC_DANCING]) {
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- status_change_end(bl, SC_DANCING, INVALID_TIMER);
- }
- break;
-
- case BA_FROSTJOKER:
- case DC_SCREAM:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- skill_addtimerskill(src,tick+2000,bl->id,src->x,src->y,skillid,skilllv,0,flag);
-
- if (md) {
- // custom hack to make the mob display the skill, because these skills don't show the skill use text themselves
- //NOTE: mobs don't have the sprite animation that is used when performing this skill (will cause glitches)
- char temp[70];
- snprintf(temp, sizeof(temp), "%s : %s !!",md->name,skill_db[skillid].desc);
- clif_message(&md->bl,temp);
- }
- break;
-
- case BA_PANGVOICE:
- clif_skill_nodamage(src,bl,skillid,skilllv, sc_start(bl,SC_CONFUSION,50,7,skill_get_time(skillid,skilllv)));
- break;
-
- case DC_WINKCHARM:
- if (dstsd)
- clif_skill_nodamage(src,bl,skillid,skilllv, sc_start(bl,SC_CONFUSION,30,7,skill_get_time2(skillid,skilllv)));
- else if (dstmd) {
- if (status_get_lv(src) > status_get_lv(bl)
- && (tstatus->race == RC_DEMON || tstatus->race == RC_DEMIHUMAN || tstatus->race == RC_ANGEL)
- && !(tstatus->mode&MD_BOSS))
- clif_skill_nodamage(src,bl,skillid,skilllv, sc_start2(bl,type,70,skilllv,src->id,skill_get_time(skillid,skilllv)));
- else {
- clif_skill_nodamage(src,bl,skillid,skilllv,0);
- if (sd) clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- }
- }
- break;
-
- case TF_STEAL:
- if (sd) {
- if (pc_steal_item(sd,bl,skilllv))
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- else
- clif_skill_fail(sd,skillid,USESKILL_FAIL,0);
- }
- break;
-
- case RG_STEALCOIN:
- if (sd) {
- if (pc_steal_coin(sd,bl)) {
- dstmd->state.provoke_flag = src->id;
- mob_target(dstmd, src, skill_get_range2(src,skillid,skilllv));
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
-
- } else
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- }
- break;
-
- case MG_STONECURSE: {
- if (tstatus->mode&MD_BOSS) {
- if (sd) clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
- if (status_isimmune(bl) || !tsc)
- break;
-
- if (tsc->data[SC_STONE]) {
- status_change_end(bl, SC_STONE, INVALID_TIMER);
- if (sd) clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
- if (sc_start4(bl,SC_STONE,(skilllv*4+20),
- skilllv, 0, 0, skill_get_time(skillid, skilllv),
- skill_get_time2(skillid,skilllv)))
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- else if (sd) {
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- // Level 6-10 doesn't consume a red gem if it fails [celest]
- if (skilllv > 5) {
- // not to consume items
- map_freeblock_unlock();
- return 0;
- }
- }
- }
- break;
-
- case NV_FIRSTAID:
- clif_skill_nodamage(src,bl,skillid,5,1);
- status_heal(bl,5,0,0);
- break;
-
- case AL_CURE:
- if (status_isimmune(bl)) {
- clif_skill_nodamage(src,bl,skillid,skilllv,0);
- break;
- }
- status_change_end(bl, SC_SILENCE, INVALID_TIMER);
- status_change_end(bl, SC_BLIND, INVALID_TIMER);
- status_change_end(bl, SC_CONFUSION, INVALID_TIMER);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- break;
-
- case TF_DETOXIFY:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- status_change_end(bl, SC_POISON, INVALID_TIMER);
- status_change_end(bl, SC_DPOISON, INVALID_TIMER);
- break;
-
- case PR_STRECOVERY:
- if (status_isimmune(bl)) {
- clif_skill_nodamage(src,bl,skillid,skilllv,0);
- break;
- }
- if (tsc && tsc->opt1) {
- status_change_end(bl, SC_FREEZE, INVALID_TIMER);
- status_change_end(bl, SC_STONE, INVALID_TIMER);
- status_change_end(bl, SC_SLEEP, INVALID_TIMER);
- status_change_end(bl, SC_STUN, INVALID_TIMER);
- status_change_end(bl, SC_WHITEIMPRISON, INVALID_TIMER);
- }
- //Is this equation really right? It looks so... special.
- if (battle_check_undead(tstatus->race,tstatus->def_ele)) {
- status_change_start(bl, SC_BLIND,
- 100*(100-(tstatus->int_/2+tstatus->vit/3+tstatus->luk/10)),
- 1,0,0,0,
- skill_get_time2(skillid, skilllv) * (100-(tstatus->int_+tstatus->vit)/2)/100,0);
- }
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if (dstmd)
- mob_unlocktarget(dstmd,tick);
- break;
-
- // Mercenary Supportive Skills
- case MER_BENEDICTION:
- status_change_end(bl, SC_CURSE, INVALID_TIMER);
- status_change_end(bl, SC_BLIND, INVALID_TIMER);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- break;
- case MER_COMPRESS:
- status_change_end(bl, SC_BLEEDING, INVALID_TIMER);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- break;
- case MER_MENTALCURE:
- status_change_end(bl, SC_CONFUSION, INVALID_TIMER);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- break;
- case MER_RECUPERATE:
- status_change_end(bl, SC_POISON, INVALID_TIMER);
- status_change_end(bl, SC_SILENCE, INVALID_TIMER);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- break;
- case MER_REGAIN:
- status_change_end(bl, SC_SLEEP, INVALID_TIMER);
- status_change_end(bl, SC_STUN, INVALID_TIMER);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- break;
- case MER_TENDER:
- status_change_end(bl, SC_FREEZE, INVALID_TIMER);
- status_change_end(bl, SC_STONE, INVALID_TIMER);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- break;
-
- case MER_SCAPEGOAT:
- if (mer && mer->master) {
- status_heal(&mer->master->bl, mer->battle_status.hp, 0, 2);
- status_damage(src, src, mer->battle_status.max_hp, 0, 0, 1);
- }
- break;
-
- case MER_ESTIMATION:
- if (!mer)
- break;
- sd = mer->master;
- case WZ_ESTIMATION:
- if (sd == NULL)
- break;
- if (dstsd) {
- // Fail on Players
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
- if (dstmd && dstmd->class_ == MOBID_EMPERIUM)
- break; // Cannot be Used on Emperium
-
- clif_skill_nodamage(src, bl, skillid, skilllv, 1);
- clif_skill_estimation(sd, bl);
- if (skillid == MER_ESTIMATION)
- sd = NULL;
- break;
-
- case BS_REPAIRWEAPON:
- if (sd && dstsd)
- clif_item_repair_list(sd,dstsd,skilllv);
- break;
+ struct map_session_data *sd, *dstsd;
+ struct mob_data *md, *dstmd;
+ struct homun_data *hd;
+ struct mercenary_data *mer;
+ struct status_data *sstatus, *tstatus;
+ struct status_change *tsc;
+ struct status_change_entry *tsce;
+
+ int i = 0;
+ enum sc_type type;
+
+ if(skillid > 0 && skilllv <= 0) return 0; // celest
+
+ nullpo_retr(1, src);
+ nullpo_retr(1, bl);
+
+ if (src->m != bl->m)
+ return 1;
+
+ sd = BL_CAST(BL_PC, src);
+ hd = BL_CAST(BL_HOM, src);
+ md = BL_CAST(BL_MOB, src);
+ mer = BL_CAST(BL_MER, src);
+
+ dstsd = BL_CAST(BL_PC, bl);
+ dstmd = BL_CAST(BL_MOB, bl);
+
+ if(bl->prev == NULL)
+ return 1;
+ if(status_isdead(src))
+ return 1;
+
+ if( src != bl && status_isdead(bl) ) {
+ /**
+ * Skills that may be cast on dead targets
+ **/
+ switch( skillid ) {
+ case NPC_WIDESOULDRAIN:
+ case PR_REDEMPTIO:
+ case ALL_RESURRECTION:
+ case WM_DEADHILLHERE:
+ break;
+ default:
+ return 1;
+ }
+ }
- case MC_IDENTIFY:
- if (sd)
- clif_item_identify_list(sd);
- break;
+ tstatus = status_get_status_data(bl);
+ sstatus = status_get_status_data(src);
- // Weapon Refining [Celest]
- case WS_WEAPONREFINE:
- if (sd)
- clif_item_refine_list(sd);
- break;
+ //Check for undead skills that convert a no-damage skill into a damage one. [Skotlex]
+ switch (skillid) {
+ case HLIF_HEAL: //[orn]
+ if (bl->type != BL_HOM) {
+ if (sd) clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0) ;
+ break ;
+ }
+ case AL_HEAL:
+ case ALL_RESURRECTION:
+ case PR_ASPERSIO:
+ /**
+ * Arch Bishop
+ **/
+ case AB_RENOVATIO:
+ case AB_HIGHNESSHEAL:
+ //Apparently only player casted skills can be offensive like this.
+ if (sd && battle_check_undead(tstatus->race,tstatus->def_ele)) {
+ if (battle_check_target(src, bl, BCT_ENEMY) < 1) {
+ //Offensive heal does not works on non-enemies. [Skotlex]
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ return skill_castend_damage_id (src, bl, skillid, skilllv, tick, flag);
+ }
+ break;
+ case NPC_SMOKING: //Since it is a self skill, this one ends here rather than in damage_id. [Skotlex]
+ return skill_castend_damage_id (src, bl, skillid, skilllv, tick, flag);
+ case MH_STEINWAND: {
+ struct block_list *s_src = battle_get_master(src);
+ short ret = 0;
+ if(!skill_check_unit_range(src, src->x, src->y, skillid, skilllv)) //prevent reiteration
+ ret = skill_castend_pos2(src,src->x,src->y,skillid,skilllv,tick,flag); //cast on homon
+ if(s_src && !skill_check_unit_range(s_src, s_src->x, s_src->y, skillid, skilllv))
+ ret |= skill_castend_pos2(s_src,s_src->x,s_src->y,skillid,skilllv,tick,flag); //cast on master
+ if (hd)
+ skill_blockhomun_start(hd, skillid, skill_get_cooldown(skillid, skilllv));
+ return ret;
+ }
+ break;
+ default:
+ //Skill is actually ground placed.
+ if (src == bl && skill_get_unit_id(skillid,0))
+ return skill_castend_pos2(src,bl->x,bl->y,skillid,skilllv,tick,0);
+ }
- case MC_VENDING:
- if (sd) {
- //Prevent vending of GMs with unnecessary Level to trade/drop. [Skotlex]
- if (!pc_can_give_items(sd))
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- else {
- sd->state.prevend = 1;
- clif_openvendingreq(sd,2+skilllv);
- }
- }
- break;
+ type = status_skill2sc(skillid);
+ tsc = status_get_sc(bl);
+ tsce = (tsc && type != -1)?tsc->data[type]:NULL;
+
+ if (src!=bl && type > -1 &&
+ (i = skill_get_ele(skillid, skilllv)) > ELE_NEUTRAL &&
+ skill_get_inf(skillid) != INF_SUPPORT_SKILL &&
+ battle_attr_fix(NULL, NULL, 100, i, tstatus->def_ele, tstatus->ele_lv) <= 0)
+ return 1; //Skills that cause an status should be blocked if the target element blocks its element.
+
+ map_freeblock_lock();
+ switch(skillid)
+ {
+ case HLIF_HEAL: //[orn]
+ case AL_HEAL:
+ /**
+ * Arch Bishop
+ **/
+ case AB_HIGHNESSHEAL:
+ {
+ int heal = skill_calc_heal(src, bl, (skillid == AB_HIGHNESSHEAL)?AL_HEAL:skillid, (skillid == AB_HIGHNESSHEAL)?10:skilllv, true);
+ int heal_get_jobexp;
+ //Highness Heal: starts at 1.5 boost + 0.5 for each level
+ if( skillid == AB_HIGHNESSHEAL ) {
+ heal = heal * ( 15 + 5 * skilllv ) / 10;
+ }
+ if( status_isimmune(bl) ||
+ (dstmd && (dstmd->class_ == MOBID_EMPERIUM || mob_is_battleground(dstmd))) ||
+ (dstsd && pc_ismadogear(dstsd)) )//Mado is immune to heal
+ heal=0;
- case AL_TELEPORT:
- if (sd) {
- if (map[bl->m].flag.noteleport && skilllv <= 2) {
- clif_skill_teleportmessage(sd,0);
- break;
- }
- if (!battle_config.duel_allow_teleport && sd->duel_group && skilllv <= 2) { // duel restriction [LuzZza]
- char output[128];
- sprintf(output, msg_txt(365), skill_get_name(AL_TELEPORT));
- clif_displaymessage(sd->fd, output); //"Duel: Can't use %s in duel."
- break;
- }
+ if( sd && dstsd && sd->status.partner_id == dstsd->status.char_id && (sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->status.sex == 0 )
+ heal = heal*2;
- if (sd->state.autocast || ((sd->skillitem == AL_TELEPORT || battle_config.skip_teleport_lv1_menu) && skilllv == 1) || skilllv == 3) {
- if (skilllv == 1)
- pc_randomwarp(sd,CLR_TELEPORT);
- else
- pc_setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT);
- break;
- }
+ if( tsc && tsc->count )
+ {
+ if( tsc->data[SC_KAITE] && !(sstatus->mode&MD_BOSS) )
+ { //Bounce back heal
+ if (--tsc->data[SC_KAITE]->val2 <= 0)
+ status_change_end(bl, SC_KAITE, INVALID_TIMER);
+ if (src == bl)
+ heal=0; //When you try to heal yourself under Kaite, the heal is voided.
+ else {
+ bl = src;
+ dstsd = sd;
+ }
+ }
+ else if (tsc->data[SC_BERSERK] || tsc->data[SC_SATURDAYNIGHTFEVER] || tsc->data[SC__BLOODYLUST])
+ heal = 0; //Needed so that it actually displays 0 when healing.
+ }
+ clif_skill_nodamage (src, bl, skillid, heal, 1);
+ if( tsc && tsc->data[SC_AKAITSUKI] && heal && skillid != HLIF_HEAL )
+ heal = ~heal + 1;
+ heal_get_jobexp = status_heal(bl,heal,0,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)
+ heal_get_jobexp = 1;
+ pc_gainexp (sd, bl, 0, heal_get_jobexp, false);
+ }
+ }
+ break;
+
+ case PR_REDEMPTIO:
+ if (sd && !(flag&1)) {
+ if (sd->status.party_id == 0) {
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+ skill_area_temp[0] = 0;
+ party_foreachsamemap(skill_area_sub,
+ sd,skill_get_splash(skillid, skilllv),
+ src,skillid,skilllv,tick, flag|BCT_PARTY|1,
+ skill_castend_nodamage_id);
+ if (skill_area_temp[0] == 0) {
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+ skill_area_temp[0] = 5 - skill_area_temp[0]; // The actual penalty...
+ if (skill_area_temp[0] > 0 && !map[src->m].flag.noexppenalty) { //Apply penalty
+ sd->status.base_exp -= min(sd->status.base_exp, pc_nextbaseexp(sd) * skill_area_temp[0] * 2/1000); //0.2% penalty per each.
+ sd->status.job_exp -= min(sd->status.job_exp, pc_nextjobexp(sd) * skill_area_temp[0] * 2/1000);
+ clif_updatestatus(sd,SP_BASEEXP);
+ clif_updatestatus(sd,SP_JOBEXP);
+ }
+ status_set_hp(src, 1, 0);
+ status_set_sp(src, 0, 0);
+ break;
+ } else if (status_isdead(bl) && flag&1) { //Revive
+ skill_area_temp[0]++; //Count it in, then fall-through to the Resurrection code.
+ skilllv = 3; //Resurrection level 3 is used
+ } else //Invalid target, skip resurrection.
+ break;
+
+ case ALL_RESURRECTION:
+ if(sd && (map_flag_gvg(bl->m) || map[bl->m].flag.battleground))
+ { //No reviving in WoE grounds!
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+ if (!status_isdead(bl))
+ break;
+ {
+ int per = 0, sper = 0;
+ if (tsc && tsc->data[SC_HELLPOWER])
+ break;
+
+ if (map[bl->m].flag.pvp && dstsd && dstsd->pvp_point < 0)
+ break;
+
+ switch(skilllv){
+ case 1: per=10; break;
+ case 2: per=30; break;
+ case 3: per=50; break;
+ case 4: per=80; break;
+ }
+ if(dstsd && dstsd->special_state.restart_full_recover)
+ per = sper = 100;
+ if (status_revive(bl, per, sper))
+ {
+ clif_skill_nodamage(src,bl,ALL_RESURRECTION,skilllv,1); //Both Redemptio and Res show this skill-animation.
+ if(sd && dstsd && battle_config.resurrection_exp > 0)
+ {
+ int exp = 0,jexp = 0;
+ int lv = dstsd->status.base_level - sd->status.base_level, jlv = dstsd->status.job_level - sd->status.job_level;
+ if(lv > 0 && pc_nextbaseexp(dstsd)) {
+ exp = (int)((double)dstsd->status.base_exp * (double)lv * (double)battle_config.resurrection_exp / 1000000.);
+ if (exp < 1) exp = 1;
+ }
+ if(jlv > 0 && pc_nextjobexp(dstsd)) {
+ 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, bl, exp, jexp, false);
+ }
+ }
+ }
+ break;
+
+ case AL_DECAGI:
+ case MER_DECAGI:
+ clif_skill_nodamage (src, bl, skillid, skilllv,
+ sc_start(bl, type, (40 + skilllv * 2 + (status_get_lv(src) + sstatus->int_)/5), skilllv, skill_get_time(skillid,skilllv)));
+ break;
+
+ case AL_CRUCIS:
+ if (flag&1)
+ sc_start(bl,type, 23+skilllv*4 +status_get_lv(src) -status_get_lv(bl), skilllv,skill_get_time(skillid,skilllv));
+ else {
+ map_foreachinrange(skill_area_sub, src, skill_get_splash(skillid, skilllv), BL_CHAR,
+ src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_nodamage_id);
+ clif_skill_nodamage(src, bl, skillid, skilllv, 1);
+ }
+ break;
+
+ case PR_LEXDIVINA:
+ case MER_LEXDIVINA:
+ if( tsce )
+ status_change_end(bl,type, INVALID_TIMER);
+ else
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv));
+ clif_skill_nodamage (src, bl, skillid, skilllv, 1);
+ break;
+
+ case SA_ABRACADABRA:
+ {
+ int abra_skillid = 0, abra_skilllv;
+ do {
+ i = rnd() % MAX_SKILL_ABRA_DB;
+ abra_skillid = skill_abra_db[i].skillid;
+ } while (abra_skillid == 0 ||
+ skill_abra_db[i].req_lv > skilllv || //Required lv for it to appear
+ rnd()%10000 >= skill_abra_db[i].per
+ );
+ abra_skilllv = min(skilllv, skill_get_max(abra_skillid));
+ clif_skill_nodamage (src, bl, skillid, skilllv, 1);
+
+ if( sd )
+ {// player-casted
+ sd->state.abra_flag = 1;
+ sd->skillitem = abra_skillid;
+ sd->skillitemlv = abra_skilllv;
+ clif_item_skill(sd, abra_skillid, abra_skilllv);
+ }
+ else
+ {// mob-casted
+ struct unit_data *ud = unit_bl2ud(src);
+ int inf = skill_get_inf(abra_skillid);
+ int target_id = 0;
+ if (!ud) break;
+ if (inf&INF_SELF_SKILL || inf&INF_SUPPORT_SKILL) {
+ if (src->type == BL_PET)
+ bl = (struct block_list*)((TBL_PET*)src)->msd;
+ if (!bl) bl = src;
+ unit_skilluse_id(src, bl->id, abra_skillid, abra_skilllv);
+ } else { //Assume offensive skills
+ if (ud->target)
+ target_id = ud->target;
+ else switch (src->type) {
+ case BL_MOB: target_id = ((TBL_MOB*)src)->target_id; break;
+ case BL_PET: target_id = ((TBL_PET*)src)->target_id; break;
+ }
+ if (!target_id)
+ break;
+ if (skill_get_casttype(abra_skillid) == CAST_GROUND) {
+ bl = map_id2bl(target_id);
+ if (!bl) bl = src;
+ unit_skilluse_pos(src, bl->x, bl->y, abra_skillid, abra_skilllv);
+ } else
+ unit_skilluse_id(src, target_id, abra_skillid, abra_skilllv);
+ }
+ }
+ }
+ break;
+
+ case SA_COMA:
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start(bl,type,100,skilllv,skill_get_time2(skillid,skilllv)));
+ break;
+ case SA_FULLRECOVERY:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ if (status_isimmune(bl))
+ break;
+ status_percent_heal(bl, 100, 100);
+ break;
+ case NPC_ALLHEAL:
+ {
+ int heal;
+ if( status_isimmune(bl) )
+ break;
+ heal = status_percent_heal(bl, 100, 0);
+ clif_skill_nodamage(NULL, bl, AL_HEAL, heal, 1);
+ if( dstmd )
+ { // Reset Damage Logs
+ memset(dstmd->dmglog, 0, sizeof(dstmd->dmglog));
+ dstmd->tdmg = 0;
+ }
+ }
+ break;
+ case SA_SUMMONMONSTER:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ if (sd) mob_once_spawn(sd, src->m, src->x, src->y," --ja--", -1, 1, "", SZ_SMALL, AI_NONE);
+ break;
+ case SA_LEVELUP:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ if (sd && pc_nextbaseexp(sd)) pc_gainexp(sd, NULL, pc_nextbaseexp(sd) * 10 / 100, 0, false);
+ break;
+ case SA_INSTANTDEATH:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ status_set_hp(bl,1,0);
+ break;
+ case SA_QUESTION:
+ case SA_GRAVITY:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ break;
+ case SA_CLASSCHANGE:
+ case SA_MONOCELL:
+ if (dstmd)
+ {
+ int class_;
+ if ( sd && dstmd->status.mode&MD_BOSS )
+ {
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+ class_ = skillid==SA_MONOCELL?1002:mob_get_random_id(4, 1, 0);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ mob_class_change(dstmd,class_);
+ if( tsc && dstmd->status.mode&MD_BOSS )
+ {
+ const enum sc_type scs[] = { SC_QUAGMIRE, SC_PROVOKE, SC_ROKISWEIL, SC_GRAVITATION, SC_SUITON, SC_STRIPWEAPON, SC_STRIPSHIELD, SC_STRIPARMOR, SC_STRIPHELM, SC_BLADESTOP };
+ for (i = SC_COMMON_MIN; i <= SC_COMMON_MAX; i++)
+ if (tsc->data[i]) status_change_end(bl, (sc_type)i, INVALID_TIMER);
+ for (i = 0; i < ARRAYLENGTH(scs); i++)
+ if (tsc->data[scs[i]]) status_change_end(bl, scs[i], INVALID_TIMER);
+ }
+ }
+ break;
+ case SA_DEATH:
+ if ( sd && dstmd && dstmd->status.mode&MD_BOSS )
+ {
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ status_kill(bl);
+ break;
+ case SA_REVERSEORCISH:
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid, skilllv)));
+ break;
+ case SA_FORTUNE:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ if(sd) pc_getzeny(sd,status_get_lv(bl)*100,LOG_TYPE_STEAL,NULL);
+ break;
+ case SA_TAMINGMONSTER:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ if (sd && dstmd) {
+ ARR_FIND( 0, MAX_PET_DB, i, dstmd->class_ == pet_db[i].class_ );
+ if( i < MAX_PET_DB )
+ pet_catch_process1(sd, dstmd->class_);
+ }
+ break;
+
+ case CR_PROVIDENCE:
+ if(sd && dstsd){ //Check they are not another crusader [Skotlex]
+ if ((dstsd->class_&MAPID_UPPERMASK) == MAPID_CRUSADER) {
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ map_freeblock_unlock();
+ return 1;
+ }
+ }
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
+ break;
+
+ case CG_MARIONETTE:
+ {
+ struct status_change* sc = status_get_sc(src);
+
+ if( sd && dstsd && (dstsd->class_&MAPID_UPPERMASK) == MAPID_BARDDANCER && dstsd->status.sex == sd->status.sex )
+ {// Cannot cast on another bard/dancer-type class of the same gender as caster
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ map_freeblock_unlock();
+ return 1;
+ }
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if (skilllv == 1)
- clif_skill_warppoint(sd,skillid,skilllv, (unsigned short)-1,0,0,0);
- else
- clif_skill_warppoint(sd,skillid,skilllv, (unsigned short)-1,sd->status.save_point.map,0,0);
- } else
- unit_warp(bl,-1,-1,-1,CLR_TELEPORT);
- break;
+ if( sc && tsc )
+ {
+ if( !sc->data[SC_MARIONETTE] && !tsc->data[SC_MARIONETTE2] )
+ {
+ sc_start(src,SC_MARIONETTE,100,bl->id,skill_get_time(skillid,skilllv));
+ sc_start(bl,SC_MARIONETTE2,100,src->id,skill_get_time(skillid,skilllv));
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ }
+ else
+ if( sc->data[SC_MARIONETTE ] && sc->data[SC_MARIONETTE ]->val1 == bl->id &&
+ tsc->data[SC_MARIONETTE2] && tsc->data[SC_MARIONETTE2]->val1 == src->id )
+ {
+ status_change_end(src, SC_MARIONETTE, INVALID_TIMER);
+ status_change_end(bl, SC_MARIONETTE2, INVALID_TIMER);
+ }
+ else
+ {
+ if( sd )
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- case NPC_EXPULSION:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- unit_warp(bl,-1,-1,-1,CLR_TELEPORT);
- break;
+ map_freeblock_unlock();
+ return 1;
+ }
+ }
+ }
+ break;
+
+ case RG_CLOSECONFINE:
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start4(bl,type,100,skilllv,src->id,0,0,skill_get_time(skillid,skilllv)));
+ 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 (dstsd) {
+ if(dstsd->status.weapon == W_FIST ||
+ (dstsd->sc.count && !dstsd->sc.data[type] &&
+ ( //Allow re-enchanting to lenghten time. [Skotlex]
+ dstsd->sc.data[SC_FIREWEAPON] ||
+ dstsd->sc.data[SC_WATERWEAPON] ||
+ dstsd->sc.data[SC_WINDWEAPON] ||
+ dstsd->sc.data[SC_EARTHWEAPON] ||
+ dstsd->sc.data[SC_SHADOWWEAPON] ||
+ dstsd->sc.data[SC_GHOSTWEAPON] ||
+ dstsd->sc.data[SC_ENCPOISON]
+ ))
+ ) {
+ if (sd) clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ clif_skill_nodamage(src,bl,skillid,skilllv,0);
+ break;
+ }
+ }
+ // 100% success rate at lv4 & 5, but lasts longer at lv5
+ if(!clif_skill_nodamage(src,bl,skillid,skilllv, sc_start(bl,type,(60+skilllv*10),skilllv, skill_get_time(skillid,skilllv)))) {
+ if (sd)
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ if (skill_break_equip(bl, EQP_WEAPON, 10000, BCT_PARTY) && sd && sd != dstsd)
+ clif_displaymessage(sd->fd, msg_txt(669));
+ }
+ break;
+
+ case PR_ASPERSIO:
+ if (sd && dstmd) {
+ clif_skill_nodamage(src,bl,skillid,skilllv,0);
+ break;
+ }
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
+ break;
+
+ case ITEM_ENCHANTARMS:
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start2(bl,type,100,skilllv,
+ skill_get_ele(skillid,skilllv), skill_get_time(skillid,skilllv)));
+ break;
+
+ case TK_SEVENWIND:
+ switch(skill_get_ele(skillid,skilllv)) {
+ case ELE_EARTH : type = SC_EARTHWEAPON; break;
+ case ELE_WIND : type = SC_WINDWEAPON; break;
+ case ELE_WATER : type = SC_WATERWEAPON; break;
+ case ELE_FIRE : type = SC_FIREWEAPON; break;
+ case ELE_GHOST : type = SC_GHOSTWEAPON; break;
+ case ELE_DARK : type = SC_SHADOWWEAPON; break;
+ case ELE_HOLY : type = SC_ASPERSIO; break;
+ }
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
+
+ sc_start(bl,SC_SEVENWIND,100,skilllv,skill_get_time(skillid,skilllv));
+
+ break;
+
+ case PR_KYRIE:
+ case MER_KYRIE:
+ clif_skill_nodamage(bl,bl,skillid,skilllv,
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
+ break;
+ //Passive Magnum, should had been casted on yourself.
+ case SM_MAGNUM:
+ case MS_MAGNUM:
+ skill_area_temp[1] = 0;
+ map_foreachinrange(skill_area_sub, src, skill_get_splash(skillid, skilllv), BL_SKILL|BL_CHAR,
+ src,skillid,skilllv,tick, flag|BCT_ENEMY|1, skill_castend_damage_id);
+ clif_skill_nodamage (src,src,skillid,skilllv,1);
+ // Initiate 10% of your damage becomes fire element.
+ sc_start4(src,SC_WATK_ELEMENT,100,3,20,0,0,skill_get_time2(skillid, skilllv));
+ if( sd )
+ skill_blockpc_start(sd, skillid, skill_get_time(skillid, skilllv));
+ else if( bl->type == BL_MER )
+ skill_blockmerc_start((TBL_MER*)bl, skillid, skill_get_time(skillid, skilllv));
+ break;
+
+ case TK_JUMPKICK:
+ /* Check if the target is an enemy; if not, skill should fail so the character doesn't unit_movepos (exploitable) */
+ if( battle_check_target(src, bl, BCT_ENEMY) > 0 )
+ {
+ if( unit_movepos(src, bl->x, bl->y, 1, 1) )
+ {
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+ clif_slide(src,bl->x,bl->y);
+ }
+ }
+ else
+ clif_skill_fail(sd,skillid,USESKILL_FAIL,0);
+ break;
+
+ case AL_INCAGI:
+ case AL_BLESSING:
+ case MER_INCAGI:
+ case MER_BLESSING:
+ if (dstsd != NULL && tsc->data[SC_CHANGEUNDEAD]) {
+ skill_attack(BF_MISC,src,src,bl,skillid,skilllv,tick,flag);
+ break;
+ }
+ case PR_SLOWPOISON:
+ case PR_IMPOSITIO:
+ case PR_LEXAETERNA:
+ case PR_SUFFRAGIUM:
+ case PR_BENEDICTIO:
+ case LK_BERSERK:
+ case MS_BERSERK:
+ case KN_AUTOCOUNTER:
+ case KN_TWOHANDQUICKEN:
+ case KN_ONEHAND:
+ case MER_QUICKEN:
+ case CR_SPEARQUICKEN:
+ case CR_REFLECTSHIELD:
+ case MS_REFLECTSHIELD:
+ case AS_POISONREACT:
+ case MC_LOUD:
+ case MG_ENERGYCOAT:
+ case MO_EXPLOSIONSPIRITS:
+ case MO_STEELBODY:
+ case MO_BLADESTOP:
+ case LK_AURABLADE:
+ case LK_PARRYING:
+ case MS_PARRYING:
+ case LK_CONCENTRATION:
+ case WS_CARTBOOST:
+ case SN_SIGHT:
+ case WS_MELTDOWN:
+ case WS_OVERTHRUSTMAX:
+ case ST_REJECTSWORD:
+ case HW_MAGICPOWER:
+ case PF_MEMORIZE:
+ case PA_SACRIFICE:
+ case ASC_EDP:
+ case PF_DOUBLECASTING:
+ case SG_SUN_COMFORT:
+ case SG_MOON_COMFORT:
+ case SG_STAR_COMFORT:
+ case NPC_HALLUCINATION:
+ case GS_MADNESSCANCEL:
+ case GS_ADJUSTMENT:
+ case GS_INCREASING:
+ case NJ_KASUMIKIRI:
+ case NJ_UTSUSEMI:
+ case NJ_NEN:
+ case NPC_DEFENDER:
+ case NPC_MAGICMIRROR:
+ case ST_PRESERVE:
+ case NPC_INVINCIBLE:
+ case NPC_INVINCIBLEOFF:
+ case RK_DEATHBOUND:
+ case AB_RENOVATIO:
+ case AB_EXPIATIO:
+ case AB_DUPLELIGHT:
+ case AB_SECRAMENT:
+ case NC_ACCELERATION:
+ case NC_HOVERING:
+ case NC_SHAPESHIFT:
+ case WL_RECOGNIZEDSPELL:
+ case GC_VENOMIMPRESS:
+ case SC_DEADLYINFECT:
+ case LG_EXEEDBREAK:
+ case LG_PRESTIGE:
+ case SR_CRESCENTELBOW:
+ case SR_LIGHTNINGWALK:
+ case SR_GENTLETOUCH_ENERGYGAIN:
+ case GN_CARTBOOST:
+ case KO_MEIKYOUSISUI:
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
+ break;
+
+ case SO_STRIKING:
+ if (sd) {
+ int bonus = 25 + 10 * skilllv;
+ bonus += (pc_checkskill(sd, SA_FLAMELAUNCHER)+pc_checkskill(sd, SA_FROSTWEAPON)+pc_checkskill(sd, SA_LIGHTNINGLOADER)+pc_checkskill(sd, SA_SEISMICWEAPON))*5;
+ clif_skill_nodamage( src, bl, skillid, skilllv,
+ battle_check_target(src,bl,BCT_PARTY) ?
+ sc_start2(bl, type, 100, skilllv, bonus, skill_get_time(skillid,skilllv)) :
+ 0
+ );
+ }
+ break;
+
+ case NPC_STOP:
+ if( clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start2(bl,type,100,skilllv,src->id,skill_get_time(skillid,skilllv)) ) )
+ sc_start2(src,type,100,skilllv,bl->id,skill_get_time(skillid,skilllv));
+ break;
+ case HP_ASSUMPTIO:
+ if( sd && dstmd )
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ else
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
+ break;
+ case MG_SIGHT:
+ case MER_SIGHT:
+ case AL_RUWACH:
+ case WZ_SIGHTBLASTER:
+ case NPC_WIDESIGHT:
+ case NPC_STONESKIN:
+ case NPC_ANTIMAGIC:
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start2(bl,type,100,skilllv,skillid,skill_get_time(skillid,skilllv)));
+ break;
+ case HLIF_AVOID:
+ case HAMI_DEFENCE:
+ i = skill_get_time(skillid,skilllv);
+ clif_skill_nodamage(bl,bl,skillid,skilllv,sc_start(bl,type,100,skilllv,i)); // Master
+ clif_skill_nodamage(src,src,skillid,skilllv,sc_start(src,type,100,skilllv,i)); // Homunc
+ break;
+ case NJ_BUNSINJYUTSU:
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
+ status_change_end(bl, SC_NEN, INVALID_TIMER);
+ break;
+/* Was modified to only affect targetted char. [Skotlex]
+ case HP_ASSUMPTIO:
+ if (flag&1)
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv));
+ else
+ {
+ map_foreachinrange(skill_area_sub, bl,
+ skill_get_splash(skillid, skilllv), BL_PC,
+ src, skillid, skilllv, tick, flag|BCT_ALL|1,
+ skill_castend_nodamage_id);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ }
+ break;
+*/
+ case SM_ENDURE:
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
+ if (sd)
+ skill_blockpc_start (sd, skillid, skill_get_time2(skillid,skilllv));
+ break;
+
+ case AS_ENCHANTPOISON: // Prevent spamming [Valaris]
+ if (sd && dstsd && dstsd->sc.count) {
+ if (dstsd->sc.data[SC_FIREWEAPON] ||
+ dstsd->sc.data[SC_WATERWEAPON] ||
+ dstsd->sc.data[SC_WINDWEAPON] ||
+ dstsd->sc.data[SC_EARTHWEAPON] ||
+ dstsd->sc.data[SC_SHADOWWEAPON] ||
+ dstsd->sc.data[SC_GHOSTWEAPON]
+ // dstsd->sc.data[SC_ENCPOISON] //People say you should be able to recast to lengthen the timer. [Skotlex]
+ ) {
+ clif_skill_nodamage(src,bl,skillid,skilllv,0);
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+ }
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
+ break;
+
+ case LK_TENSIONRELAX:
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start4(bl,type,100,skilllv,0,0,skill_get_time2(skillid,skilllv),
+ skill_get_time(skillid,skilllv)));
+ break;
+
+ case MC_CHANGECART:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ break;
+
+ case TK_MISSION:
+ if (sd) {
+ int id;
+ if (sd->mission_mobid && (sd->mission_count || rnd()%100)) { //Cannot change target when already have one
+ clif_mission_info(sd, sd->mission_mobid, sd->mission_count);
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+ id = mob_get_random_id(0,0xF, sd->status.base_level);
+ if (!id) {
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+ sd->mission_mobid = id;
+ sd->mission_count = 0;
+ pc_setglobalreg(sd,"TK_MISSION_ID", id);
+ clif_mission_info(sd, id, 0);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ }
+ break;
+
+ case AC_CONCENTRATION:
+ {
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
+ map_foreachinrange( status_change_timer_sub, src,
+ skill_get_splash(skillid, skilllv), BL_CHAR,
+ src,NULL,type,tick);
+ }
+ break;
+
+ case SM_PROVOKE:
+ case SM_SELFPROVOKE:
+ case MER_PROVOKE:
+ if( (tstatus->mode&MD_BOSS) || battle_check_undead(tstatus->race,tstatus->def_ele) )
+ {
+ map_freeblock_unlock();
+ return 1;
+ }
+ //TODO: How much does base level affects? Dummy value of 1% per level difference used. [Skotlex]
+ clif_skill_nodamage(src,bl,skillid == SM_SELFPROVOKE ? SM_PROVOKE : skillid,skilllv,
+ (i = sc_start(bl,type, skillid == SM_SELFPROVOKE ? 100:( 50 + 3*skilllv + status_get_lv(src) - status_get_lv(bl)), skilllv, skill_get_time(skillid,skilllv))));
+ if( !i )
+ {
+ if( sd )
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ map_freeblock_unlock();
+ return 0;
+ }
+ unit_skillcastcancel(bl, 2);
+
+ if( tsc && tsc->count )
+ {
+ status_change_end(bl, SC_FREEZE, INVALID_TIMER);
+ if( tsc->data[SC_STONE] && tsc->opt1 == OPT1_STONE )
+ status_change_end(bl, SC_STONE, INVALID_TIMER);
+ status_change_end(bl, SC_SLEEP, INVALID_TIMER);
+ status_change_end(bl, SC_TRICKDEAD, INVALID_TIMER);
+ }
+
+ if( dstmd )
+ {
+ dstmd->state.provoke_flag = src->id;
+ mob_target(dstmd, src, skill_get_range2(src,skillid,skilllv));
+ }
+ break;
+
+ case ML_DEVOTION:
+ case CR_DEVOTION:
+ {
+ int count, lv;
+ if( !dstsd || (!sd && !mer) )
+ { // Only players can be devoted
+ if( sd )
+ clif_skill_fail(sd, skillid, USESKILL_FAIL_LEVEL, 0);
+ break;
+ }
- case AL_HOLYWATER:
- if (sd) {
- if (skill_produce_mix(sd, skillid, 523, 0, 0, 0, 1))
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- else
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- }
- break;
+ if( (lv = status_get_lv(src) - dstsd->status.base_level) < 0 )
+ lv = -lv;
+ if( lv > battle_config.devotion_level_difference || // Level difference requeriments
+ (dstsd->sc.data[type] && dstsd->sc.data[type]->val1 != src->id) || // Cannot Devote a player devoted from another source
+ (skillid == ML_DEVOTION && (!mer || mer != dstsd->md)) || // Mercenary only can devote owner
+ (dstsd->class_&MAPID_UPPERMASK) == MAPID_CRUSADER || // Crusader Cannot be devoted
+ (dstsd->sc.data[SC_HELLPOWER])) // Players affected by SC_HELLPOWERR cannot be devoted.
+ {
+ if( sd )
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ map_freeblock_unlock();
+ return 1;
+ }
- case TF_PICKSTONE:
- if (sd) {
- int eflag;
- struct item item_tmp;
- struct block_list tbl;
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- memset(&item_tmp,0,sizeof(item_tmp));
- memset(&tbl,0,sizeof(tbl)); // [MouseJstr]
- item_tmp.nameid = ITEMID_STONE;
- item_tmp.identify = 1;
- tbl.id = 0;
- clif_takeitem(&sd->bl,&tbl);
- eflag = pc_additem(sd,&item_tmp,1,LOG_TYPE_PRODUCE);
- if (eflag) {
- clif_additem(sd,0,0,eflag);
- map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
- }
- }
- break;
- case ASC_CDP:
- if (sd) {
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- skill_produce_mix(sd, skillid, 678, 0, 0, 0, 1); //Produce a Deadly Poison Bottle.
- }
- break;
+ i = 0;
+ count = (sd)? min(skilllv,5) : 1; // Mercenary only can Devote owner
+ if( sd )
+ { // Player Devoting Player
+ ARR_FIND(0, count, i, sd->devotion[i] == bl->id );
+ if( i == count )
+ {
+ ARR_FIND(0, count, i, sd->devotion[i] == 0 );
+ if( i == count )
+ { // No free slots, skill Fail
+ clif_skill_fail(sd, skillid, USESKILL_FAIL_LEVEL, 0);
+ map_freeblock_unlock();
+ return 1;
+ }
+ }
- case RG_STRIPWEAPON:
- case RG_STRIPSHIELD:
- case RG_STRIPARMOR:
- case RG_STRIPHELM:
- case ST_FULLSTRIP:
- case GC_WEAPONCRUSH:
- case SC_STRIPACCESSARY: {
- unsigned short location = 0;
- int d = 0;
-
- //Rate in percent
- if (skillid == ST_FULLSTRIP) {
- i = 5 + 2*skilllv + (sstatus->dex - tstatus->dex)/5;
- } else if (skillid == SC_STRIPACCESSARY) {
- i = 12 + 2 * skilllv + (sstatus->dex - tstatus->dex)/5;
- } else {
- i = 5 + 5*skilllv + (sstatus->dex - tstatus->dex)/5;
- }
+ sd->devotion[i] = bl->id;
+ }
+ else
+ mer->devotion_flag = 1; // Mercenary Devoting Owner
+
+ clif_skill_nodamage(src, bl, skillid, skilllv,
+ sc_start4(bl, type, 100, src->id, i, skill_get_range2(src,skillid,skilllv),0, skill_get_time2(skillid, skilllv)));
+ clif_devotion(src, NULL);
+ }
+ break;
+
+ case MO_CALLSPIRITS:
+ if(sd) {
+ int limit = skilllv;
+ if( sd->sc.data[SC_RAISINGDRAGON] )
+ limit += sd->sc.data[SC_RAISINGDRAGON]->val1;
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ pc_addspiritball(sd,skill_get_time(skillid,skilllv),limit);
+ }
+ break;
+
+ case CH_SOULCOLLECT:
+ if(sd) {
+ int limit = 5;
+ if( sd->sc.data[SC_RAISINGDRAGON] )
+ limit += sd->sc.data[SC_RAISINGDRAGON]->val1;
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ for (i = 0; i < limit; i++)
+ pc_addspiritball(sd,skill_get_time(skillid,skilllv),limit);
+ }
+ break;
+
+ case MO_KITRANSLATION:
+ if(dstsd && (dstsd->class_&MAPID_BASEMASK)!=MAPID_GUNSLINGER) {
+ pc_addspiritball(dstsd,skill_get_time(skillid,skilllv),5);
+ }
+ break;
+
+ case TK_TURNKICK:
+ case MO_BALKYOUNG: //Passive part of the attack. Splash knock-back+stun. [Skotlex]
+ if (skill_area_temp[1] != bl->id) {
+ skill_blown(src,bl,skill_get_blewcount(skillid,skilllv),-1,0);
+ skill_additional_effect(src,bl,skillid,skilllv,BF_MISC,ATK_DEF,tick); //Use Misc rather than weapon to signal passive pushback
+ }
+ break;
+
+ case MO_ABSORBSPIRITS:
+ i = 0;
+ if (dstsd && dstsd->spiritball && (sd == dstsd || map_flag_vs(src->m)) && (dstsd->class_&MAPID_BASEMASK)!=MAPID_GUNSLINGER)
+ { // split the if for readability, and included gunslingers in the check so that their coins cannot be removed [Reddozen]
+ i = dstsd->spiritball * 7;
+ pc_delspiritball(dstsd,dstsd->spiritball,0);
+ } else if (dstmd && !(tstatus->mode&MD_BOSS) && rnd() % 100 < 20)
+ { // check if target is a monster and not a Boss, for the 20% chance to absorb 2 SP per monster's level [Reddozen]
+ i = 2 * dstmd->level;
+ mob_target(dstmd,src,0);
+ }
+ if (i) status_heal(src, 0, i, 3);
+ clif_skill_nodamage(src,bl,skillid,skilllv,i?1:0);
+ break;
+
+ case AC_MAKINGARROW:
+ if(sd) {
+ clif_arrow_create_list(sd);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ }
+ break;
+
+ case AM_PHARMACY:
+ if(sd) {
+ clif_skill_produce_mix_list(sd,skillid,22);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ }
+ break;
+
+ case SA_CREATECON:
+ if(sd) {
+ clif_elementalconverter_list(sd);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ }
+ break;
+
+ case BS_HAMMERFALL:
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start(bl,SC_STUN,(20 + 10 * skilllv),skilllv,skill_get_time2(skillid,skilllv)));
+ break;
+ case RG_RAID:
+ skill_area_temp[1] = 0;
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ map_foreachinrange(skill_area_sub, bl,
+ skill_get_splash(skillid, skilllv), splash_target(src),
+ src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
+ skill_castend_damage_id);
+ status_change_end(src, SC_HIDING, INVALID_TIMER);
+ break;
+
+ case ASC_METEORASSAULT:
+ case GS_SPREADATTACK:
+ case RK_STORMBLAST:
+ case NC_AXETORNADO:
+ case GC_COUNTERSLASH:
+ case SR_SKYNETBLOW:
+ case SR_RAMPAGEBLASTER:
+ case SR_HOWLINGOFLION:
+ case KO_HAPPOKUNAI:
+ skill_area_temp[1] = 0;
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ i = map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), splash_target(src),
+ src, skillid, skilllv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill_castend_damage_id);
+ if( !i && ( skillid == NC_AXETORNADO || skillid == SR_SKYNETBLOW || skillid == KO_HAPPOKUNAI ) )
+ clif_skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+ break;
+
+ case NC_EMERGENCYCOOL:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ status_change_end(src,SC_OVERHEAT_LIMITPOINT,INVALID_TIMER);
+ status_change_end(src,SC_OVERHEAT,INVALID_TIMER);
+ break;
+ case SR_WINDMILL:
+ case GN_CART_TORNADO:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ case SR_EARTHSHAKER:
+ case NC_INFRAREDSCAN:
+ case NPC_EARTHQUAKE:
+ case NPC_VAMPIRE_GIFT:
+ case NPC_HELLJUDGEMENT:
+ case NPC_PULSESTRIKE:
+ case LG_MOONSLASHER:
+ skill_castend_damage_id(src, src, skillid, skilllv, tick, flag);
+ break;
+
+ case KN_BRANDISHSPEAR:
+ case ML_BRANDISH:
+ skill_brandishspear(src, bl, skillid, skilllv, tick, flag);
+ break;
+
+ case WZ_SIGHTRASHER:
+ //Passive side of the attack.
+ status_change_end(src, SC_SIGHT, INVALID_TIMER);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ map_foreachinrange(skill_area_sub,src,
+ skill_get_splash(skillid, skilllv),BL_CHAR|BL_SKILL,
+ src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
+ skill_castend_damage_id);
+ break;
+
+ case NJ_HYOUSYOURAKU:
+ case NJ_RAIGEKISAI:
+ case WZ_FROSTNOVA:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ skill_area_temp[1] = 0;
+ map_foreachinrange(skill_attack_area, src,
+ skill_get_splash(skillid, skilllv), splash_target(src),
+ BF_MAGIC, src, src, skillid, skilllv, tick, flag, BCT_ENEMY);
+ break;
+
+ case HVAN_EXPLOSION: //[orn]
+ case NPC_SELFDESTRUCTION:
+ //Self Destruction hits everyone in range (allies+enemies)
+ //Except for Summoned Marine spheres on non-versus maps, where it's just enemy.
+ i = ((!md || md->special_state.ai == 2) && !map_flag_vs(src->m))?
+ BCT_ENEMY:BCT_ALL;
+ clif_skill_nodamage(src, src, skillid, -1, 1);
+ map_delblock(src); //Required to prevent chain-self-destructions hitting back.
+ map_foreachinrange(skill_area_sub, bl,
+ skill_get_splash(skillid, skilllv), splash_target(src),
+ src, skillid, skilllv, tick, flag|i,
+ skill_castend_damage_id);
+ map_addblock(src);
+ status_damage(src, src, sstatus->max_hp,0,0,1);
+ break;
+
+ case AL_ANGELUS:
+ case PR_MAGNIFICAT:
+ case PR_GLORIA:
+ case SN_WINDWALK:
+ case CASH_BLESSING:
+ case CASH_INCAGI:
+ case CASH_ASSUMPTIO:
+ if( sd == NULL || sd->status.party_id == 0 || (flag & 1) )
+ clif_skill_nodamage(bl, bl, skillid, skilllv, sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
+ else if( sd )
+ party_foreachsamemap(skill_area_sub, sd, skill_get_splash(skillid, skilllv), src, skillid, skilllv, tick, flag|BCT_PARTY|1, skill_castend_nodamage_id);
+ break;
+ case MER_MAGNIFICAT:
+ if( mer != NULL )
+ {
+ clif_skill_nodamage(bl, bl, skillid, skilllv, sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
+ if( mer->master && mer->master->status.party_id != 0 && !(flag&1) )
+ party_foreachsamemap(skill_area_sub, mer->master, skill_get_splash(skillid, skilllv), src, skillid, skilllv, tick, flag|BCT_PARTY|1, skill_castend_nodamage_id);
+ else if( mer->master && !(flag&1) )
+ clif_skill_nodamage(src, &mer->master->bl, skillid, skilllv, sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
+ }
+ break;
+
+ case BS_ADRENALINE:
+ case BS_ADRENALINE2:
+ case BS_WEAPONPERFECT:
+ case BS_OVERTHRUST:
+ if (sd == NULL || sd->status.party_id == 0 || (flag & 1)) {
+ clif_skill_nodamage(bl,bl,skillid,skilllv,
+ sc_start2(bl,type,100,skilllv,(src == bl)? 1:0,skill_get_time(skillid,skilllv)));
+ } else if (sd) {
+ party_foreachsamemap(skill_area_sub,
+ sd,skill_get_splash(skillid, skilllv),
+ src,skillid,skilllv,tick, flag|BCT_PARTY|1,
+ skill_castend_nodamage_id);
+ }
+ break;
+
+ case BS_MAXIMIZE:
+ case NV_TRICKDEAD:
+ case CR_DEFENDER:
+ case ML_DEFENDER:
+ case CR_AUTOGUARD:
+ case ML_AUTOGUARD:
+ case TK_READYSTORM:
+ case TK_READYDOWN:
+ case TK_READYTURN:
+ case TK_READYCOUNTER:
+ case TK_DODGE:
+ case CR_SHRINK:
+ case SG_FUSION:
+ case GS_GATLINGFEVER:
+ if( tsce )
+ {
+ clif_skill_nodamage(src,bl,skillid,skilllv,status_change_end(bl, type, INVALID_TIMER));
+ map_freeblock_unlock();
+ return 0;
+ }
+ clif_skill_nodamage(src,bl,skillid,skilllv,sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
+ break;
+ case SL_KAITE:
+ case SL_KAAHI:
+ case SL_KAIZEL:
+ case SL_KAUPE:
+ if (sd) {
+ if (!dstsd || !(
+ (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_SOULLINKER) ||
+ (dstsd->class_&MAPID_UPPERMASK) == MAPID_SOUL_LINKER ||
+ dstsd->status.char_id == sd->status.char_id ||
+ dstsd->status.char_id == sd->status.partner_id ||
+ dstsd->status.char_id == sd->status.child
+ )) {
+ status_change_start(src,SC_STUN,10000,skilllv,0,0,0,500,8);
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+ }
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid, skilllv)));
+ break;
+ case SM_AUTOBERSERK:
+ case MER_AUTOBERSERK:
+ if( tsce )
+ i = status_change_end(bl, type, INVALID_TIMER);
+ else
+ i = sc_start(bl,type,100,skilllv,60000);
+ clif_skill_nodamage(src,bl,skillid,skilllv,i);
+ break;
+ case TF_HIDING:
+ case ST_CHASEWALK:
+ case KO_YAMIKUMO:
+ if (tsce)
+ {
+ clif_skill_nodamage(src,bl,skillid,-1,status_change_end(bl, type, INVALID_TIMER)); //Hide skill-scream animation.
+ map_freeblock_unlock();
+ return 0;
+ } else if( tsc && tsc->option&OPTION_MADOGEAR ) {
+ //Mado Gear cannot hide
+ if( sd ) clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ map_freeblock_unlock();
+ return 0;
+ }
+ clif_skill_nodamage(src,bl,skillid,-1,sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
+ break;
+ case TK_RUN:
+ if (tsce)
+ {
+ clif_skill_nodamage(src,bl,skillid,skilllv,status_change_end(bl, type, INVALID_TIMER));
+ map_freeblock_unlock();
+ return 0;
+ }
+ clif_skill_nodamage(src,bl,skillid,skilllv,sc_start4(bl,type,100,skilllv,unit_getdir(bl),0,0,0));
+ if (sd) // If the client receives a skill-use packet inmediately before a walkok packet, it will discard the walk packet! [Skotlex]
+ clif_walkok(sd); // So aegis has to resend the walk ok.
+ break;
+ case AS_CLOAKING:
+ case GC_CLOAKINGEXCEED:
+ case LG_FORCEOFVANGUARD:
+ case SC_REPRODUCE:
+ case SC_INVISIBILITY:
+ if (tsce) {
+ i = status_change_end(bl, type, INVALID_TIMER);
+ if( i )
+ clif_skill_nodamage(src,bl,skillid,( skillid == LG_FORCEOFVANGUARD ) ? skilllv : -1,i);
+ else if( sd )
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ map_freeblock_unlock();
+ return 0;
+ }
+ case RA_CAMOUFLAGE:
+ i = sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv));
+ if( i )
+ clif_skill_nodamage(src,bl,skillid,( skillid == LG_FORCEOFVANGUARD ) ? skilllv : -1,i);
+ else if( sd )
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+
+ case BD_ADAPTATION:
+ if(tsc && tsc->data[SC_DANCING]){
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ status_change_end(bl, SC_DANCING, INVALID_TIMER);
+ }
+ break;
+
+ case BA_FROSTJOKER:
+ case DC_SCREAM:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ skill_addtimerskill(src,tick+2000,bl->id,src->x,src->y,skillid,skilllv,0,flag);
+
+ if (md) {
+ // custom hack to make the mob display the skill, because these skills don't show the skill use text themselves
+ //NOTE: mobs don't have the sprite animation that is used when performing this skill (will cause glitches)
+ char temp[70];
+ snprintf(temp, sizeof(temp), "%s : %s !!",md->name,skill_db[skillid].desc);
+ clif_message(&md->bl,temp);
+ }
+ break;
+
+ case BA_PANGVOICE:
+ clif_skill_nodamage(src,bl,skillid,skilllv, sc_start(bl,SC_CONFUSION,50,7,skill_get_time(skillid,skilllv)));
+ break;
+
+ case DC_WINKCHARM:
+ if( dstsd )
+ clif_skill_nodamage(src,bl,skillid,skilllv, sc_start(bl,SC_CONFUSION,30,7,skill_get_time2(skillid,skilllv)));
+ else
+ if( dstmd )
+ {
+ if( status_get_lv(src) > status_get_lv(bl)
+ && (tstatus->race == RC_DEMON || tstatus->race == RC_DEMIHUMAN || tstatus->race == RC_ANGEL)
+ && !(tstatus->mode&MD_BOSS) )
+ clif_skill_nodamage(src,bl,skillid,skilllv, sc_start2(bl,type,70,skilllv,src->id,skill_get_time(skillid,skilllv)));
+ else
+ {
+ clif_skill_nodamage(src,bl,skillid,skilllv,0);
+ if(sd) clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ }
+ }
+ break;
+
+ case TF_STEAL:
+ if(sd) {
+ if(pc_steal_item(sd,bl,skilllv))
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ else
+ clif_skill_fail(sd,skillid,USESKILL_FAIL,0);
+ }
+ break;
+
+ case RG_STEALCOIN:
+ if(sd) {
+ if(pc_steal_coin(sd,bl))
+ {
+ dstmd->state.provoke_flag = src->id;
+ mob_target(dstmd, src, skill_get_range2(src,skillid,skilllv));
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if (i < 5) i = 5; //Minimum rate 5%
-
- //Duration in ms
- if (skillid == GC_WEAPONCRUSH) {
- d = skill_get_time(skillid,skilllv);
- if (bl->type == BL_PC)
- d += skilllv * 15 + (sstatus->dex - tstatus->dex);
- else
- d += skilllv * 30 + (sstatus->dex - tstatus->dex) / 2;
- } else
- d = skill_get_time(skillid,skilllv) + (sstatus->dex - tstatus->dex)*500;
-
- if (d < 0) d = 0; //Minimum duration 0ms
-
- switch (skillid) {
- case RG_STRIPWEAPON:
- case GC_WEAPONCRUSH:
- location = EQP_WEAPON;
- break;
- case RG_STRIPSHIELD:
- location = EQP_SHIELD;
- break;
- case RG_STRIPARMOR:
- location = EQP_ARMOR;
- break;
- case RG_STRIPHELM:
- location = EQP_HELM;
- break;
- case ST_FULLSTRIP:
- location = EQP_WEAPON|EQP_SHIELD|EQP_ARMOR|EQP_HELM;
- break;
- case SC_STRIPACCESSARY:
- location = EQP_ACC;
- break;
- }
+ }
+ else
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ }
+ break;
+
+ case MG_STONECURSE:
+ {
+ if (tstatus->mode&MD_BOSS) {
+ if (sd) clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+ if(status_isimmune(bl) || !tsc)
+ break;
- //Special message when trying to use strip on FCP [Jobbie]
- if (sd && skillid == ST_FULLSTRIP && tsc && tsc->data[SC_CP_WEAPON] && tsc->data[SC_CP_HELM] && tsc->data[SC_CP_ARMOR] && tsc->data[SC_CP_SHIELD]) {
- clif_gospel_info(sd, 0x28);
- break;
- }
+ if (tsc->data[SC_STONE]) {
+ status_change_end(bl, SC_STONE, INVALID_TIMER);
+ if (sd) clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+ if (sc_start4(bl,SC_STONE,(skilllv*4+20),
+ skilllv, 0, 0, skill_get_time(skillid, skilllv),
+ skill_get_time2(skillid,skilllv)))
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ else if(sd) {
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ // Level 6-10 doesn't consume a red gem if it fails [celest]
+ if (skilllv > 5)
+ { // not to consume items
+ map_freeblock_unlock();
+ return 0;
+ }
+ }
+ }
+ break;
+
+ case NV_FIRSTAID:
+ clif_skill_nodamage(src,bl,skillid,5,1);
+ status_heal(bl,5,0,0);
+ break;
+
+ case AL_CURE:
+ if(status_isimmune(bl)) {
+ clif_skill_nodamage(src,bl,skillid,skilllv,0);
+ break;
+ }
+ status_change_end(bl, SC_SILENCE, INVALID_TIMER);
+ status_change_end(bl, SC_BLIND, INVALID_TIMER);
+ status_change_end(bl, SC_CONFUSION, INVALID_TIMER);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ break;
+
+ case TF_DETOXIFY:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ status_change_end(bl, SC_POISON, INVALID_TIMER);
+ status_change_end(bl, SC_DPOISON, INVALID_TIMER);
+ break;
+
+ case PR_STRECOVERY:
+ if(status_isimmune(bl)) {
+ clif_skill_nodamage(src,bl,skillid,skilllv,0);
+ break;
+ }
+ if (tsc && tsc->opt1) {
+ status_change_end(bl, SC_FREEZE, INVALID_TIMER);
+ status_change_end(bl, SC_STONE, INVALID_TIMER);
+ status_change_end(bl, SC_SLEEP, INVALID_TIMER);
+ status_change_end(bl, SC_STUN, INVALID_TIMER);
+ status_change_end(bl, SC_WHITEIMPRISON, INVALID_TIMER);
+ }
+ //Is this equation really right? It looks so... special.
+ if(battle_check_undead(tstatus->race,tstatus->def_ele))
+ {
+ status_change_start(bl, SC_BLIND,
+ 100*(100-(tstatus->int_/2+tstatus->vit/3+tstatus->luk/10)),
+ 1,0,0,0,
+ skill_get_time2(skillid, skilllv) * (100-(tstatus->int_+tstatus->vit)/2)/100,0);
+ }
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ if(dstmd)
+ mob_unlocktarget(dstmd,tick);
+ break;
+
+ // Mercenary Supportive Skills
+ case MER_BENEDICTION:
+ status_change_end(bl, SC_CURSE, INVALID_TIMER);
+ status_change_end(bl, SC_BLIND, INVALID_TIMER);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ break;
+ case MER_COMPRESS:
+ status_change_end(bl, SC_BLEEDING, INVALID_TIMER);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ break;
+ case MER_MENTALCURE:
+ status_change_end(bl, SC_CONFUSION, INVALID_TIMER);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ break;
+ case MER_RECUPERATE:
+ status_change_end(bl, SC_POISON, INVALID_TIMER);
+ status_change_end(bl, SC_SILENCE, INVALID_TIMER);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ break;
+ case MER_REGAIN:
+ status_change_end(bl, SC_SLEEP, INVALID_TIMER);
+ status_change_end(bl, SC_STUN, INVALID_TIMER);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ break;
+ case MER_TENDER:
+ status_change_end(bl, SC_FREEZE, INVALID_TIMER);
+ status_change_end(bl, SC_STONE, INVALID_TIMER);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ break;
+
+ case MER_SCAPEGOAT:
+ if( mer && mer->master )
+ {
+ status_heal(&mer->master->bl, mer->battle_status.hp, 0, 2);
+ status_damage(src, src, mer->battle_status.max_hp, 0, 0, 1);
+ }
+ break;
+
+ case MER_ESTIMATION:
+ if( !mer )
+ break;
+ sd = mer->master;
+ case WZ_ESTIMATION:
+ if( sd == NULL )
+ break;
+ if( dstsd )
+ { // Fail on Players
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+ if( dstmd && dstmd->class_ == MOBID_EMPERIUM )
+ break; // Cannot be Used on Emperium
+
+ clif_skill_nodamage(src, bl, skillid, skilllv, 1);
+ clif_skill_estimation(sd, bl);
+ if( skillid == MER_ESTIMATION )
+ sd = NULL;
+ break;
+
+ case BS_REPAIRWEAPON:
+ if(sd && dstsd)
+ clif_item_repair_list(sd,dstsd,skilllv);
+ break;
+
+ case MC_IDENTIFY:
+ if(sd)
+ clif_item_identify_list(sd);
+ break;
+
+ // Weapon Refining [Celest]
+ case WS_WEAPONREFINE:
+ if(sd)
+ clif_item_refine_list(sd);
+ break;
+
+ case MC_VENDING:
+ if(sd)
+ { //Prevent vending of GMs with unnecessary Level to trade/drop. [Skotlex]
+ if ( !pc_can_give_items(sd) )
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ else {
+ sd->state.prevend = 1;
+ clif_openvendingreq(sd,2+skilllv);
+ }
+ }
+ break;
+
+ case AL_TELEPORT:
+ if(sd)
+ {
+ if (map[bl->m].flag.noteleport && skilllv <= 2) {
+ clif_skill_teleportmessage(sd,0);
+ break;
+ }
+ if(!battle_config.duel_allow_teleport && sd->duel_group && skilllv <= 2) { // duel restriction [LuzZza]
+ char output[128]; sprintf(output, msg_txt(365), skill_get_name(AL_TELEPORT));
+ clif_displaymessage(sd->fd, output); //"Duel: Can't use %s in duel."
+ break;
+ }
- //Attempts to strip at rate i and duration d
- if ((i = skill_strip_equip(bl, location, i, skilllv, d)) || (skillid != ST_FULLSTRIP && skillid != GC_WEAPONCRUSH))
- clif_skill_nodamage(src,bl,skillid,skilllv,i);
+ if( sd->state.autocast || ( (sd->skillitem == AL_TELEPORT || battle_config.skip_teleport_lv1_menu) && skilllv == 1 ) || skilllv == 3 )
+ {
+ if( skilllv == 1 )
+ pc_randomwarp(sd,CLR_TELEPORT);
+ else
+ pc_setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT);
+ break;
+ }
- //Nothing stripped.
- if (sd && !i)
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ if( skilllv == 1 )
+ clif_skill_warppoint(sd,skillid,skilllv, (unsigned short)-1,0,0,0);
+ else
+ clif_skill_warppoint(sd,skillid,skilllv, (unsigned short)-1,sd->status.save_point.map,0,0);
+ } else
+ unit_warp(bl,-1,-1,-1,CLR_TELEPORT);
+ break;
+
+ case NPC_EXPULSION:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ unit_warp(bl,-1,-1,-1,CLR_TELEPORT);
+ break;
+
+ case AL_HOLYWATER:
+ if(sd) {
+ if (skill_produce_mix(sd, skillid, 523, 0, 0, 0, 1))
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ else
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ }
+ break;
+
+ case TF_PICKSTONE:
+ if(sd) {
+ int eflag;
+ struct item item_tmp;
+ struct block_list tbl;
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ memset(&item_tmp,0,sizeof(item_tmp));
+ memset(&tbl,0,sizeof(tbl)); // [MouseJstr]
+ item_tmp.nameid = ITEMID_STONE;
+ item_tmp.identify = 1;
+ tbl.id = 0;
+ clif_takeitem(&sd->bl,&tbl);
+ eflag = pc_additem(sd,&item_tmp,1,LOG_TYPE_PRODUCE);
+ if(eflag) {
+ clif_additem(sd,0,0,eflag);
+ map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ }
+ }
+ break;
+ case ASC_CDP:
+ if(sd) {
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ skill_produce_mix(sd, skillid, 678, 0, 0, 0, 1); //Produce a Deadly Poison Bottle.
+ }
+ break;
+
+ case RG_STRIPWEAPON:
+ case RG_STRIPSHIELD:
+ case RG_STRIPARMOR:
+ case RG_STRIPHELM:
+ case ST_FULLSTRIP:
+ case GC_WEAPONCRUSH:
+ case SC_STRIPACCESSARY: {
+ unsigned short location = 0;
+ int d = 0;
+
+ //Rate in percent
+ if ( skillid == ST_FULLSTRIP ) {
+ i = 5 + 2*skilllv + (sstatus->dex - tstatus->dex)/5;
+ } else if( skillid == SC_STRIPACCESSARY ) {
+ i = 12 + 2 * skilllv + (sstatus->dex - tstatus->dex)/5;
+ } else {
+ i = 5 + 5*skilllv + (sstatus->dex - tstatus->dex)/5;
+ }
+
+ if (i < 5) i = 5; //Minimum rate 5%
+
+ //Duration in ms
+ if( skillid == GC_WEAPONCRUSH){
+ d = skill_get_time(skillid,skilllv);
+ if(bl->type == BL_PC)
+ d += skilllv * 15 + (sstatus->dex - tstatus->dex);
+ else
+ d += skilllv * 30 + (sstatus->dex - tstatus->dex) / 2;
+ }else
+ d = skill_get_time(skillid,skilllv) + (sstatus->dex - tstatus->dex)*500;
+
+ if (d < 0) d = 0; //Minimum duration 0ms
+
+ switch (skillid) {
+ case RG_STRIPWEAPON:
+ case GC_WEAPONCRUSH:
+ location = EQP_WEAPON;
+ break;
+ case RG_STRIPSHIELD:
+ location = EQP_SHIELD;
+ break;
+ case RG_STRIPARMOR:
+ location = EQP_ARMOR;
+ break;
+ case RG_STRIPHELM:
+ location = EQP_HELM;
+ break;
+ case ST_FULLSTRIP:
+ location = EQP_WEAPON|EQP_SHIELD|EQP_ARMOR|EQP_HELM;
+ break;
+ case SC_STRIPACCESSARY:
+ location = EQP_ACC;
+ break;
+ }
+
+ //Special message when trying to use strip on FCP [Jobbie]
+ if( sd && skillid == ST_FULLSTRIP && tsc && tsc->data[SC_CP_WEAPON] && tsc->data[SC_CP_HELM] && tsc->data[SC_CP_ARMOR] && tsc->data[SC_CP_SHIELD])
+ {
+ clif_gospel_info(sd, 0x28);
+ break;
+ }
+
+ //Attempts to strip at rate i and duration d
+ if( (i = skill_strip_equip(bl, location, i, skilllv, d)) || (skillid != ST_FULLSTRIP && skillid != GC_WEAPONCRUSH ) )
+ clif_skill_nodamage(src,bl,skillid,skilllv,i);
+
+ //Nothing stripped.
+ if( sd && !i )
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
- case AM_BERSERKPITCHER:
- case AM_POTIONPITCHER: {
- int i,x,hp = 0,sp = 0,bonus=100;
- if (dstmd && dstmd->class_ == MOBID_EMPERIUM) {
- map_freeblock_unlock();
- return 1;
- }
- if (sd) {
- x = skilllv%11 - 1;
- i = pc_search_inventory(sd,skill_db[skillid].itemid[x]);
- if (i < 0 || skill_db[skillid].itemid[x] <= 0) {
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- map_freeblock_unlock();
- return 1;
- }
- if (sd->inventory_data[i] == NULL || sd->status.inventory[i].amount < skill_db[skillid].amount[x]) {
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- map_freeblock_unlock();
- return 1;
- }
- if (skillid == AM_BERSERKPITCHER) {
- if (dstsd && dstsd->status.base_level < (unsigned int)sd->inventory_data[i]->elv) {
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- map_freeblock_unlock();
- return 1;
- }
- }
- potion_flag = 1;
- potion_hp = potion_sp = potion_per_hp = potion_per_sp = 0;
- potion_target = bl->id;
- run_script(sd->inventory_data[i]->script,0,sd->bl.id,0);
- potion_flag = potion_target = 0;
- if (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_ALCHEMIST)
- bonus += sd->status.base_level;
- if (potion_per_hp > 0 || potion_per_sp > 0) {
- hp = tstatus->max_hp * potion_per_hp / 100;
- hp = hp * (100 + pc_checkskill(sd,AM_POTIONPITCHER)*10 + pc_checkskill(sd,AM_LEARNINGPOTION)*5)*bonus/10000;
- if (dstsd) {
- sp = dstsd->status.max_sp * potion_per_sp / 100;
- sp = sp * (100 + pc_checkskill(sd,AM_POTIONPITCHER)*10 + pc_checkskill(sd,AM_LEARNINGPOTION)*5)*bonus/10000;
- }
- } else {
- if (potion_hp > 0) {
- hp = potion_hp * (100 + pc_checkskill(sd,AM_POTIONPITCHER)*10 + pc_checkskill(sd,AM_LEARNINGPOTION)*5)*bonus/10000;
- hp = hp * (100 + (tstatus->vit<<1)) / 100;
- if (dstsd)
- hp = hp * (100 + pc_checkskill(dstsd,SM_RECOVERY)*10) / 100;
- }
- if (potion_sp > 0) {
- sp = potion_sp * (100 + pc_checkskill(sd,AM_POTIONPITCHER)*10 + pc_checkskill(sd,AM_LEARNINGPOTION)*5)*bonus/10000;
- sp = sp * (100 + (tstatus->int_<<1)) / 100;
- if (dstsd)
- sp = sp * (100 + pc_checkskill(dstsd,MG_SRECOVERY)*10) / 100;
- }
- }
+ case AM_BERSERKPITCHER:
+ case AM_POTIONPITCHER: {
+ int i,x,hp = 0,sp = 0,bonus=100;
+ if( dstmd && dstmd->class_ == MOBID_EMPERIUM ) {
+ map_freeblock_unlock();
+ return 1;
+ }
+ if( sd ) {
+ x = skilllv%11 - 1;
+ i = pc_search_inventory(sd,skill_db[skillid].itemid[x]);
+ if( i < 0 || skill_db[skillid].itemid[x] <= 0 ) {
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ map_freeblock_unlock();
+ return 1;
+ }
+ if(sd->inventory_data[i] == NULL || sd->status.inventory[i].amount < skill_db[skillid].amount[x]) {
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ map_freeblock_unlock();
+ return 1;
+ }
+ if( skillid == AM_BERSERKPITCHER ) {
+ if( dstsd && dstsd->status.base_level < (unsigned int)sd->inventory_data[i]->elv ) {
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ map_freeblock_unlock();
+ return 1;
+ }
+ }
+ potion_flag = 1;
+ potion_hp = potion_sp = potion_per_hp = potion_per_sp = 0;
+ potion_target = bl->id;
+ run_script(sd->inventory_data[i]->script,0,sd->bl.id,0);
+ potion_flag = potion_target = 0;
+ if( sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_ALCHEMIST )
+ bonus += sd->status.base_level;
+ if( potion_per_hp > 0 || potion_per_sp > 0 ) {
+ hp = tstatus->max_hp * potion_per_hp / 100;
+ hp = hp * (100 + pc_checkskill(sd,AM_POTIONPITCHER)*10 + pc_checkskill(sd,AM_LEARNINGPOTION)*5)*bonus/10000;
+ if( dstsd ) {
+ sp = dstsd->status.max_sp * potion_per_sp / 100;
+ sp = sp * (100 + pc_checkskill(sd,AM_POTIONPITCHER)*10 + pc_checkskill(sd,AM_LEARNINGPOTION)*5)*bonus/10000;
+ }
+ } else {
+ if( potion_hp > 0 ) {
+ hp = potion_hp * (100 + pc_checkskill(sd,AM_POTIONPITCHER)*10 + pc_checkskill(sd,AM_LEARNINGPOTION)*5)*bonus/10000;
+ hp = hp * (100 + (tstatus->vit<<1)) / 100;
+ if( dstsd )
+ hp = hp * (100 + pc_checkskill(dstsd,SM_RECOVERY)*10) / 100;
+ }
+ if( potion_sp > 0 ) {
+ sp = potion_sp * (100 + pc_checkskill(sd,AM_POTIONPITCHER)*10 + pc_checkskill(sd,AM_LEARNINGPOTION)*5)*bonus/10000;
+ sp = sp * (100 + (tstatus->int_<<1)) / 100;
+ if( dstsd )
+ sp = sp * (100 + pc_checkskill(dstsd,MG_SRECOVERY)*10) / 100;
+ }
+ }
- if (sd->itemgrouphealrate[IG_POTION]>0) {
- hp += hp * sd->itemgrouphealrate[IG_POTION] / 100;
- sp += sp * sd->itemgrouphealrate[IG_POTION] / 100;
- }
+ if (sd->itemgrouphealrate[IG_POTION]>0) {
+ hp += hp * sd->itemgrouphealrate[IG_POTION] / 100;
+ sp += sp * sd->itemgrouphealrate[IG_POTION] / 100;
+ }
- if ((i = pc_skillheal_bonus(sd, skillid))) {
- hp += hp * i / 100;
- sp += sp * i / 100;
- }
- } else {
- hp = (1 + rnd()%400) * (100 + skilllv*10) / 100;
- hp = hp * (100 + (tstatus->vit<<1)) / 100;
- if (dstsd)
- hp = hp * (100 + pc_checkskill(dstsd,SM_RECOVERY)*10) / 100;
- }
- if (dstsd && (i = pc_skillheal2_bonus(dstsd, skillid))) {
- hp += hp * i / 100;
- sp += sp * i / 100;
- }
- if (tsc && tsc->count) {
- if (tsc->data[SC_CRITICALWOUND]) {
- hp -= hp * tsc->data[SC_CRITICALWOUND]->val2 / 100;
- sp -= sp * tsc->data[SC_CRITICALWOUND]->val2 / 100;
- }
- if (tsc->data[SC_DEATHHURT]) {
- hp -= hp * 20 / 100;
- sp -= sp * 20 / 100;
- }
- if (tsc->data[SC_WATER_INSIGNIA] && tsc->data[SC_WATER_INSIGNIA]->val1 == 2) {
- hp += hp / 10;
- sp += sp / 10;
- }
- }
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if (hp > 0 || (skillid == AM_POTIONPITCHER && sp <= 0))
- clif_skill_nodamage(NULL,bl,AL_HEAL,hp,1);
- if (sp > 0)
- clif_skill_nodamage(NULL,bl,MG_SRECOVERY,sp,1);
+ if( (i = pc_skillheal_bonus(sd, skillid)) ) {
+ hp += hp * i / 100;
+ sp += sp * i / 100;
+ }
+ } else {
+ hp = (1 + rnd()%400) * (100 + skilllv*10) / 100;
+ hp = hp * (100 + (tstatus->vit<<1)) / 100;
+ if( dstsd )
+ hp = hp * (100 + pc_checkskill(dstsd,SM_RECOVERY)*10) / 100;
+ }
+ if( dstsd && (i = pc_skillheal2_bonus(dstsd, skillid)) ) {
+ hp += hp * i / 100;
+ sp += sp * i / 100;
+ }
+ if( tsc && tsc->count ) {
+ if( tsc->data[SC_CRITICALWOUND] ) {
+ hp -= hp * tsc->data[SC_CRITICALWOUND]->val2 / 100;
+ sp -= sp * tsc->data[SC_CRITICALWOUND]->val2 / 100;
+ }
+ if( tsc->data[SC_DEATHHURT] ) {
+ hp -= hp * 20 / 100;
+ sp -= sp * 20 / 100;
+ }
+ if( tsc->data[SC_WATER_INSIGNIA] && tsc->data[SC_WATER_INSIGNIA]->val1 == 2 ) {
+ hp += hp / 10;
+ sp += sp / 10;
+ }
+ }
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ if( hp > 0 || (skillid == AM_POTIONPITCHER && sp <= 0) )
+ clif_skill_nodamage(NULL,bl,AL_HEAL,hp,1);
+ if( sp > 0 )
+ clif_skill_nodamage(NULL,bl,MG_SRECOVERY,sp,1);
#ifdef RENEWAL
- if (tsc && tsc->data[SC_EXTREMITYFIST2])
- sp = 0;
+ if( tsc && tsc->data[SC_EXTREMITYFIST2] )
+ sp = 0;
#endif
- status_heal(bl,hp,sp,0);
- }
- break;
- case AM_CP_WEAPON:
- case AM_CP_SHIELD:
- case AM_CP_ARMOR:
- case AM_CP_HELM: {
- unsigned int equip[] = {EQP_WEAPON, EQP_SHIELD, EQP_ARMOR, EQP_HEAD_TOP};
-
- if (sd && (bl->type != BL_PC || (dstsd && pc_checkequip(dstsd,equip[skillid - AM_CP_WEAPON]) < 0))) {
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- map_freeblock_unlock(); // Don't consume item requirements
- return 0;
- }
+ status_heal(bl,hp,sp,0);
+ }
+ break;
+ case AM_CP_WEAPON:
+ case AM_CP_SHIELD:
+ case AM_CP_ARMOR:
+ case AM_CP_HELM:
+ {
+ unsigned int equip[] = {EQP_WEAPON, EQP_SHIELD, EQP_ARMOR, EQP_HEAD_TOP};
+
+ if( sd && ( bl->type != BL_PC || ( dstsd && pc_checkequip(dstsd,equip[skillid - AM_CP_WEAPON]) < 0 ) ) ){
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ map_freeblock_unlock(); // Don't consume item requirements
+ return 0;
+ }
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
- }
- break;
- case AM_TWILIGHT1:
- if (sd) {
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- //Prepare 200 White Potions.
- if (!skill_produce_mix(sd, skillid, 504, 0, 0, 0, 200))
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- }
- break;
- case AM_TWILIGHT2:
- if (sd) {
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- //Prepare 200 Slim White Potions.
- if (!skill_produce_mix(sd, skillid, 547, 0, 0, 0, 200))
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- }
- break;
- case AM_TWILIGHT3:
- if (sd) {
- int ebottle = pc_search_inventory(sd,713);
- if (ebottle >= 0)
- ebottle = sd->status.inventory[ebottle].amount;
- //check if you can produce all three, if not, then fail:
- if (!skill_can_produce_mix(sd,970,-1, 100) //100 Alcohol
- || !skill_can_produce_mix(sd,7136,-1, 50) //50 Acid Bottle
- || !skill_can_produce_mix(sd,7135,-1, 50) //50 Flame Bottle
- || ebottle < 200 //200 empty bottle are required at total.
- ) {
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- skill_produce_mix(sd, skillid, 970, 0, 0, 0, 100);
- skill_produce_mix(sd, skillid, 7136, 0, 0, 0, 50);
- skill_produce_mix(sd, skillid, 7135, 0, 0, 0, 50);
- }
- break;
- case SA_DISPELL:
- if (flag&1 || (i = skill_get_splash(skillid, skilllv)) < 1) {
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if ((dstsd && (dstsd->class_&MAPID_UPPERMASK) == MAPID_SOUL_LINKER)
- || (tsc && tsc->data[SC_SPIRIT] && tsc->data[SC_SPIRIT]->val2 == SL_ROGUE) //Rogue's spirit defends againt dispel.
- || rnd()%100 >= 50+10*skilllv
- || (tsc && tsc->option&OPTION_MADOGEAR)) { //Mado Gear is immune to dispell according to bug report 49 [Ind]
- if (sd)
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
- if (status_isimmune(bl) || !tsc || !tsc->count)
- break;
- for (i=0; i<SC_MAX; i++) {
- if (!tsc->data[i])
- continue;
- switch (i) {
- case SC_WEIGHT50:
- case SC_WEIGHT90:
- case SC_HALLUCINATION:
- 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:
- case SC_COMBO:
- case SC_STRFOOD:
- case SC_AGIFOOD:
- case SC_VITFOOD:
- case SC_INTFOOD:
- case SC_DEXFOOD:
- case SC_LUKFOOD:
- case SC_HITFOOD:
- case SC_FLEEFOOD:
- case SC_BATKFOOD:
- case SC_WATKFOOD:
- case SC_MATKFOOD:
- case SC_DANCING:
- case SC_EDP:
- case SC_AUTOBERSERK:
- case SC_CARTBOOST:
- case SC_MELTDOWN:
- case SC_SAFETYWALL:
- case SC_SMA:
- case SC_SPEEDUP0:
- case SC_NOCHAT:
- case SC_ANKLE:
- case SC_SPIDERWEB:
- case SC_JAILED:
- case SC_ITEMBOOST:
- case SC_EXPBOOST:
- case SC_LIFEINSURANCE:
- case SC_BOSSMAPINFO:
- case SC_PNEUMA:
- case SC_AUTOSPELL:
- case SC_INCHITRATE:
- case SC_INCATKRATE:
- case SC_NEN:
- case SC_READYSTORM:
- case SC_READYDOWN:
- case SC_READYTURN:
- case SC_READYCOUNTER:
- case SC_DODGE:
- case SC_WARM:
- case SC_SPEEDUP1:
- case SC_AUTOTRADE:
- case SC_CRITICALWOUND:
- case SC_JEXPBOOST:
- case SC_INVINCIBLE:
- case SC_INVINCIBLEOFF:
- case SC_HELLPOWER:
- case SC_MANU_ATK:
- case SC_MANU_DEF:
- case SC_SPL_ATK:
- case SC_SPL_DEF:
- case SC_MANU_MATK:
- case SC_SPL_MATK:
- case SC_RICHMANKIM:
- case SC_ETERNALCHAOS:
- case SC_DRUMBATTLE:
- case SC_NIBELUNGEN:
- case SC_ROKISWEIL:
- case SC_INTOABYSS:
- case SC_SIEGFRIED:
- case SC_FOOD_STR_CASH:
- case SC_FOOD_AGI_CASH:
- case SC_FOOD_VIT_CASH:
- case SC_FOOD_DEX_CASH:
- case SC_FOOD_INT_CASH:
- case SC_FOOD_LUK_CASH:
- case SC_SEVENWIND:
- case SC_MIRACLE:
- case SC_S_LIFEPOTION:
- case SC_L_LIFEPOTION:
- case SC_INCHEALRATE:
- case SC_ELECTRICSHOCKER:
- case SC__STRIPACCESSORY:
- //case SC_SAVAGE_STEAK: case SC_COCKTAIL_WARG_BLOOD: case SC_MINOR_BBQ:
- //case SC_SIROMA_ICE_TEA: case SC_DROCERA_HERB_STEAMED: case SC_PUTTI_TAILS_NOODLES:
- case SC_NEUTRALBARRIER_MASTER:
- case SC_NEUTRALBARRIER:
- case SC_STEALTHFIELD_MASTER:
- case SC_STEALTHFIELD:
- case SC_GIANTGROWTH:
- case SC_MILLENNIUMSHIELD:
- case SC_REFRESH:
- case SC_STONEHARDSKIN:
- case SC_VITALITYACTIVATION:
- case SC_FIGHTINGSPIRIT:
- case SC_ABUNDANCE:
- case SC__SHADOWFORM:
- case SC_LEADERSHIP:
- case SC_GLORYWOUNDS:
- case SC_SOULCOLD:
- case SC_HAWKEYES:
- case SC_GUILDAURA:
- case SC_PUSH_CART:
- case SC_RAISINGDRAGON:
- case SC_GT_ENERGYGAIN:
- case SC_GT_CHANGE:
- case SC_GT_REVITALIZE:
- case SC_REFLECTDAMAGE:
- case SC_INSPIRATION:
- case SC_EXEEDBREAK:
- case SC_FORCEOFVANGUARD:
- case SC_BANDING:
- case SC_DUPLELIGHT:
- case SC_EXPIATIO:
- case SC_LAUDAAGNUS:
- case SC_LAUDARAMUS:
- case SC_GATLINGFEVER:
- case SC_INCREASING:
- case SC_ADJUSTMENT:
- case SC_MADNESSCANCEL:
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
+ }
+ break;
+ case AM_TWILIGHT1:
+ if (sd) {
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ //Prepare 200 White Potions.
+ if (!skill_produce_mix(sd, skillid, 504, 0, 0, 0, 200))
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ }
+ break;
+ case AM_TWILIGHT2:
+ if (sd) {
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ //Prepare 200 Slim White Potions.
+ if (!skill_produce_mix(sd, skillid, 547, 0, 0, 0, 200))
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ }
+ break;
+ case AM_TWILIGHT3:
+ if (sd) {
+ int ebottle = pc_search_inventory(sd,713);
+ if( ebottle >= 0 )
+ ebottle = sd->status.inventory[ebottle].amount;
+ //check if you can produce all three, if not, then fail:
+ if (!skill_can_produce_mix(sd,970,-1, 100) //100 Alcohol
+ || !skill_can_produce_mix(sd,7136,-1, 50) //50 Acid Bottle
+ || !skill_can_produce_mix(sd,7135,-1, 50) //50 Flame Bottle
+ || ebottle < 200 //200 empty bottle are required at total.
+ ) {
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ skill_produce_mix(sd, skillid, 970, 0, 0, 0, 100);
+ skill_produce_mix(sd, skillid, 7136, 0, 0, 0, 50);
+ skill_produce_mix(sd, skillid, 7135, 0, 0, 0, 50);
+ }
+ break;
+ case SA_DISPELL:
+ if (flag&1 || (i = skill_get_splash(skillid, skilllv)) < 1)
+ {
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ if((dstsd && (dstsd->class_&MAPID_UPPERMASK) == MAPID_SOUL_LINKER)
+ || (tsc && tsc->data[SC_SPIRIT] && tsc->data[SC_SPIRIT]->val2 == SL_ROGUE) //Rogue's spirit defends againt dispel.
+ || rnd()%100 >= 50+10*skilllv
+ || ( tsc && tsc->option&OPTION_MADOGEAR ) )//Mado Gear is immune to dispell according to bug report 49 [Ind]
+ {
+ if (sd)
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+ if(status_isimmune(bl) || !tsc || !tsc->count)
+ break;
+ for(i=0;i<SC_MAX;i++)
+ {
+ if (!tsc->data[i])
+ continue;
+ switch (i) {
+ case SC_WEIGHT50: case SC_WEIGHT90: case SC_HALLUCINATION:
+ 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: case SC_COMBO:
+ case SC_STRFOOD: case SC_AGIFOOD: case SC_VITFOOD:
+ case SC_INTFOOD: case SC_DEXFOOD: case SC_LUKFOOD:
+ case SC_HITFOOD: case SC_FLEEFOOD: case SC_BATKFOOD:
+ case SC_WATKFOOD: case SC_MATKFOOD: case SC_DANCING:
+ case SC_EDP: case SC_AUTOBERSERK:
+ case SC_CARTBOOST: case SC_MELTDOWN: case SC_SAFETYWALL:
+ case SC_SMA: case SC_SPEEDUP0: case SC_NOCHAT:
+ case SC_ANKLE: case SC_SPIDERWEB: case SC_JAILED:
+ case SC_ITEMBOOST: case SC_EXPBOOST: case SC_LIFEINSURANCE:
+ case SC_BOSSMAPINFO: case SC_PNEUMA: case SC_AUTOSPELL:
+ case SC_INCHITRATE: case SC_INCATKRATE: case SC_NEN:
+ case SC_READYSTORM: case SC_READYDOWN: case SC_READYTURN:
+ case SC_READYCOUNTER: case SC_DODGE: case SC_WARM:
+ case SC_SPEEDUP1: case SC_AUTOTRADE: case SC_CRITICALWOUND:
+ case SC_JEXPBOOST: case SC_INVINCIBLE: case SC_INVINCIBLEOFF:
+ case SC_HELLPOWER: case SC_MANU_ATK: case SC_MANU_DEF:
+ case SC_SPL_ATK: case SC_SPL_DEF: case SC_MANU_MATK:
+ case SC_SPL_MATK: case SC_RICHMANKIM: case SC_ETERNALCHAOS:
+ case SC_DRUMBATTLE: case SC_NIBELUNGEN: case SC_ROKISWEIL:
+ case SC_INTOABYSS: case SC_SIEGFRIED: case SC_FOOD_STR_CASH:
+ case SC_FOOD_AGI_CASH: case SC_FOOD_VIT_CASH: case SC_FOOD_DEX_CASH:
+ case SC_FOOD_INT_CASH: case SC_FOOD_LUK_CASH: case SC_SEVENWIND:
+ case SC_MIRACLE: case SC_S_LIFEPOTION: case SC_L_LIFEPOTION:
+ case SC_INCHEALRATE: case SC_ELECTRICSHOCKER: case SC__STRIPACCESSORY:
+ //case SC_SAVAGE_STEAK: case SC_COCKTAIL_WARG_BLOOD: case SC_MINOR_BBQ:
+ //case SC_SIROMA_ICE_TEA: case SC_DROCERA_HERB_STEAMED: case SC_PUTTI_TAILS_NOODLES:
+ case SC_NEUTRALBARRIER_MASTER: case SC_NEUTRALBARRIER: case SC_STEALTHFIELD_MASTER:
+ case SC_STEALTHFIELD: case SC_GIANTGROWTH: case SC_MILLENNIUMSHIELD:
+ case SC_REFRESH: case SC_STONEHARDSKIN: case SC_VITALITYACTIVATION:
+ case SC_FIGHTINGSPIRIT: case SC_ABUNDANCE: case SC__SHADOWFORM:
+ case SC_LEADERSHIP: case SC_GLORYWOUNDS: case SC_SOULCOLD:
+ case SC_HAWKEYES: case SC_GUILDAURA: case SC_PUSH_CART:
+ case SC_RAISINGDRAGON: case SC_GT_ENERGYGAIN: case SC_GT_CHANGE:
+ case SC_GT_REVITALIZE: case SC_REFLECTDAMAGE: case SC_INSPIRATION:
+ case SC_EXEEDBREAK: case SC_FORCEOFVANGUARD: case SC_BANDING:
+ case SC_DUPLELIGHT: case SC_EXPIATIO: case SC_LAUDAAGNUS:
+ case SC_LAUDARAMUS: case SC_GATLINGFEVER: case SC_INCREASING:
+ case SC_ADJUSTMENT: case SC_MADNESSCANCEL:
#ifdef RENEWAL
- case SC_EXTREMITYFIST2:
-#endif
- continue;
- /**
- * bugreport:4888 these songs may only be dispelled if you're not in their song area anymore
- **/
- case SC_WHISTLE:
- case SC_ASSNCROS:
- case SC_POEMBRAGI:
- case SC_APPLEIDUN:
- case SC_HUMMING:
- case SC_DONTFORGETME:
- case SC_FORTUNE:
- case SC_SERVICE4U:
- if (tsc->data[i]->val4) //val4 = out-of-song-area
- continue;
- break;
- case SC_ASSUMPTIO:
- if (bl->type == BL_MOB)
- continue;
- break;
- }
- if (i==SC_BERSERK || i==SC_SATURDAYNIGHTFEVER) tsc->data[i]->val2=0; //Mark a dispelled berserk to avoid setting hp to 100 by setting hp penalty to 0.
- status_change_end(bl, (sc_type)i, INVALID_TIMER);
- }
- break;
- }
- //Affect all targets on splash area.
- map_foreachinrange(skill_area_sub, bl, i, BL_CHAR,
- src, skillid, skilllv, tick, flag|1,
- skill_castend_damage_id);
- break;
-
- case TF_BACKSLIDING: //This is the correct implementation as per packet logging information. [Skotlex]
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- skill_blown(src,bl,skill_get_blewcount(skillid,skilllv),unit_getdir(bl),0);
- break;
-
- case TK_HIGHJUMP: {
- int x,y, dir = unit_getdir(src);
-
- //Fails on noteleport maps, except for GvG and BG maps [Skotlex]
- if (map[src->m].flag.noteleport &&
- !(map[src->m].flag.battleground || map_flag_gvg2(src->m))
- ) {
- x = src->x;
- y = src->y;
- } else {
- x = src->x + dirx[dir]*skilllv*2;
- y = src->y + diry[dir]*skilllv*2;
- }
-
- clif_skill_nodamage(src,bl,TK_HIGHJUMP,skilllv,1);
- if (!map_count_oncell(src->m,x,y,BL_PC|BL_NPC|BL_MOB) && map_getcell(src->m,x,y,CELL_CHKREACH)) {
- clif_slide(src,x,y);
- unit_movepos(src, x, y, 1, 0);
- }
- }
- break;
-
- case SA_CASTCANCEL:
- case SO_SPELLFIST:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- unit_skillcastcancel(src,1);
- if (sd) {
- int sp = skill_get_sp(sd->skillid_old,sd->skilllv_old);
- if (skillid == SO_SPELLFIST) {
- sc_start4(src,type,100,skilllv+1,skilllv,sd->skillid_old,sd->skilllv_old,skill_get_time(skillid,skilllv));
- sd->skillid_old = sd->skilllv_old = 0;
- break;
- }
- sp = sp * (90 - (skilllv-1)*20) / 100;
- if (sp < 0) sp = 0;
- status_zap(src, 0, sp);
- }
- break;
- case SA_SPELLBREAKER: {
- int sp;
- if (tsc && tsc->data[SC_MAGICROD]) {
- sp = skill_get_sp(skillid,skilllv);
- sp = sp * tsc->data[SC_MAGICROD]->val2 / 100;
- if (sp < 1) sp = 1;
- status_heal(bl,0,sp,2);
- status_percent_damage(bl, src, 0, -20, false); //20% max SP damage.
- } else {
- struct unit_data *ud = unit_bl2ud(bl);
- int bl_skillid=0,bl_skilllv=0,hp = 0;
- if (!ud || ud->skilltimer == INVALID_TIMER)
- break; //Nothing to cancel.
- bl_skillid = ud->skillid;
- bl_skilllv = ud->skilllv;
- if (tstatus->mode & MD_BOSS) {
- //Only 10% success chance against bosses. [Skotlex]
- if (rnd()%100 < 90) {
- if (sd) clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
- } else if (!dstsd || map_flag_vs(bl->m)) //HP damage only on pvp-maps when against players.
- hp = tstatus->max_hp/50; //Recover 2% HP [Skotlex]
-
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- unit_skillcastcancel(bl,0);
- sp = skill_get_sp(bl_skillid,bl_skilllv);
- status_zap(bl, hp, sp);
-
- if (hp && skilllv >= 5)
- hp>>=1; //Recover half damaged HP at level 5 [Skotlex]
- else
- hp = 0;
-
- if (sp) //Recover some of the SP used
- sp = sp*(25*(skilllv-1))/100;
-
- if (hp || sp)
- status_heal(src, hp, sp, 2);
- }
- }
- break;
- case SA_MAGICROD:
- clif_skill_nodamage(src,src,SA_MAGICROD,skilllv,1);
- sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv));
- break;
- case SA_AUTOSPELL:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if (sd)
- clif_autospell(sd,skilllv);
- else {
- int maxlv=1,spellid=0;
- static const int spellarray[3] = { MG_COLDBOLT,MG_FIREBOLT,MG_LIGHTNINGBOLT };
- if (skilllv >= 10) {
- spellid = MG_FROSTDIVER;
- // if (tsc && tsc->data[SC_SPIRIT] && tsc->data[SC_SPIRIT]->val2 == SA_SAGE)
- // maxlv = 10;
- // else
- maxlv = skilllv - 9;
- } else if (skilllv >=8) {
- spellid = MG_FIREBALL;
- maxlv = skilllv - 7;
- } else if (skilllv >=5) {
- spellid = MG_SOULSTRIKE;
- maxlv = skilllv - 4;
- } else if (skilllv >=2) {
- int i = rnd()%3;
- spellid = spellarray[i];
- maxlv = skilllv - 1;
- } else if (skilllv > 0) {
- spellid = MG_NAPALMBEAT;
- maxlv = 3;
- }
- if (spellid > 0)
- sc_start4(src,SC_AUTOSPELL,100,skilllv,spellid,maxlv,0,
- skill_get_time(SA_AUTOSPELL,skilllv));
- }
- break;
-
- case BS_GREED:
- if (sd) {
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- map_foreachinrange(skill_greed,bl,
- skill_get_splash(skillid, skilllv),BL_ITEM,bl);
- }
- break;
-
- case SA_ELEMENTWATER:
- case SA_ELEMENTFIRE:
- case SA_ELEMENTGROUND:
- case SA_ELEMENTWIND:
- if (sd && !dstmd) //Only works on monsters.
- break;
- if (tstatus->mode&MD_BOSS)
- break;
- case NPC_ATTRICHANGE:
- case NPC_CHANGEWATER:
- case NPC_CHANGEGROUND:
- case NPC_CHANGEFIRE:
- case NPC_CHANGEWIND:
- case NPC_CHANGEPOISON:
- case NPC_CHANGEHOLY:
- case NPC_CHANGEDARKNESS:
- case NPC_CHANGETELEKINESIS:
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start2(bl, type, 100, skilllv, skill_get_ele(skillid,skilllv),
- skill_get_time(skillid, skilllv)));
- break;
- case NPC_CHANGEUNDEAD:
- //This skill should fail if target is wearing bathory/evil druid card [Brainstorm]
- //TO-DO This is ugly, fix it
- if (tstatus->def_ele==ELE_UNDEAD || tstatus->def_ele==ELE_DARK) break;
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start2(bl, type, 100, skilllv, skill_get_ele(skillid,skilllv),
- skill_get_time(skillid, skilllv)));
- break;
-
- case NPC_PROVOCATION:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if (md) mob_unlocktarget(md, tick);
- break;
-
- case NPC_KEEPING:
- case NPC_BARRIER: {
- int skill_time = skill_get_time(skillid,skilllv);
- struct unit_data *ud = unit_bl2ud(bl);
- if (clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start(bl,type,100,skilllv,skill_time))
- && ud) { //Disable attacking/acting/moving for skill's duration.
- ud->attackabletime =
- ud->canact_tick =
- ud->canmove_tick = tick + skill_time;
- }
- }
- break;
-
- case NPC_REBIRTH:
- if (md && md->state.rebirth)
- break; // only works once
- sc_start(bl,type,100,skilllv,-1);
- break;
-
- case NPC_DARKBLESSING:
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start2(bl,type,(50+skilllv*5),skilllv,skilllv,skill_get_time2(skillid,skilllv)));
- break;
-
- case NPC_LICK:
- status_zap(bl, 0, 100);
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start(bl,type,(skilllv*5),skilllv,skill_get_time2(skillid,skilllv)));
- break;
-
- case NPC_SUICIDE:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- status_kill(src); //When suiciding, neither exp nor drops is given.
- break;
-
- case NPC_SUMMONSLAVE:
- case NPC_SUMMONMONSTER:
- if (md && md->skillidx >= 0)
- mob_summonslave(md,md->db->skill[md->skillidx].val,skilllv,skillid);
- break;
-
- case NPC_CALLSLAVE:
- mob_warpslave(src,MOB_SLAVEDISTANCE);
- break;
-
- case NPC_RANDOMMOVE:
- if (md) {
- md->next_walktime = tick - 1;
- mob_randomwalk(md,tick);
- }
- break;
-
- case NPC_SPEEDUP: {
- // or does it increase casting rate? just a guess xD
- int i = SC_ASPDPOTION0 + skilllv - 1;
- if (i > SC_ASPDPOTION3)
- i = SC_ASPDPOTION3;
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start(bl,(sc_type)i,100,skilllv,skilllv * 60000));
- }
- break;
-
- case NPC_REVENGE:
- // not really needed... but adding here anyway ^^
- if (md && md->master_id > 0) {
- struct block_list *mbl, *tbl;
- if ((mbl = map_id2bl(md->master_id)) == NULL ||
- (tbl = battle_gettargeted(mbl)) == NULL)
- break;
- md->state.provoke_flag = tbl->id;
- mob_target(md, tbl, sstatus->rhw.range);
- }
- break;
-
- case NPC_RUN: {
- const int mask[8][2] = {{0,-1},{1,-1},{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1}};
- int dir = (bl == src)?unit_getdir(src):map_calc_dir(src,bl->x,bl->y); //If cast on self, run forward, else run away.
- unit_stop_attack(src);
- //Run skillv tiles overriding the can-move check.
- if (unit_walktoxy(src, src->x + skilllv * mask[dir][0], src->y + skilllv * mask[dir][1], 2) && md)
- md->state.skillstate = MSS_WALK; //Otherwise it isn't updated in the ai.
- }
- break;
-
- case NPC_TRANSFORMATION:
- case NPC_METAMORPHOSIS:
- if (md && md->skillidx >= 0) {
- int class_ = mob_random_class(md->db->skill[md->skillidx].val,0);
- if (skilllv > 1) //Multiply the rest of mobs. [Skotlex]
- mob_summonslave(md,md->db->skill[md->skillidx].val,skilllv-1,skillid);
- if (class_) mob_class_change(md, class_);
- }
- break;
-
- case NPC_EMOTION_ON:
- case NPC_EMOTION:
- //va[0] is the emotion to use.
- //NPC_EMOTION & NPC_EMOTION_ON can change a mob's mode 'permanently' [Skotlex]
- //val[1] 'sets' the mode
- //val[2] adds to the current mode
- //val[3] removes from the current mode
- //val[4] if set, asks to delete the previous mode change.
- if (md && md->skillidx >= 0 && tsc) {
- clif_emotion(bl, md->db->skill[md->skillidx].val[0]);
- if (md->db->skill[md->skillidx].val[4] && tsce)
- status_change_end(bl, type, INVALID_TIMER);
-
- if (md->db->skill[md->skillidx].val[1] || md->db->skill[md->skillidx].val[2])
- sc_start4(src, type, 100, skilllv,
- md->db->skill[md->skillidx].val[1],
- md->db->skill[md->skillidx].val[2],
- md->db->skill[md->skillidx].val[3],
- skill_get_time(skillid, skilllv));
- }
- break;
-
- case NPC_POWERUP:
- sc_start(bl,SC_INCATKRATE,100,200,skill_get_time(skillid, skilllv));
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start(bl,type,100,100,skill_get_time(skillid, skilllv)));
- break;
-
- case NPC_AGIUP:
- sc_start(bl,SC_SPEEDUP1,100,skilllv,skill_get_time(skillid, skilllv));
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start(bl,type,100,100,skill_get_time(skillid, skilllv)));
- break;
-
- case NPC_INVISIBLE:
- //Have val4 passed as 6 is for "infinite cloak" (do not end on attack/skill use).
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start4(bl,type,100,skilllv,0,0,6,skill_get_time(skillid,skilllv)));
- break;
-
- case NPC_SIEGEMODE:
- // not sure what it does
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- break;
-
- case WE_MALE: {
- int hp_rate=(skilllv <= 0)? 0:skill_db[skillid].hp_rate[skilllv-1];
- int gain_hp= tstatus->max_hp*abs(hp_rate)/100; // The earned is the same % of the target HP than it costed the caster. [Skotlex]
- clif_skill_nodamage(src,bl,skillid,status_heal(bl, gain_hp, 0, 0),1);
- }
- break;
- case WE_FEMALE: {
- int sp_rate=(skilllv <= 0)? 0:skill_db[skillid].sp_rate[skilllv-1];
- int gain_sp=tstatus->max_sp*abs(sp_rate)/100;// The earned is the same % of the target SP than it costed the caster. [Skotlex]
- clif_skill_nodamage(src,bl,skillid,status_heal(bl, 0, gain_sp, 0),1);
- }
- break;
-
- // parent-baby skills
- case WE_BABY:
- if (sd) {
- 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,USESKILL_FAIL_LEVEL,0);
- map_freeblock_unlock();
- return 0;
- }
- status_change_start(bl,SC_STUN,10000,skilllv,0,0,0,skill_get_time2(skillid,skilllv),8);
- if (f_sd) sc_start(&f_sd->bl,type,100,skilllv,skill_get_time(skillid,skilllv));
- if (m_sd) sc_start(&m_sd->bl,type,100,skilllv,skill_get_time(skillid,skilllv));
- }
- break;
-
- case PF_HPCONVERSION: {
- int hp, sp;
- hp = sstatus->max_hp/10;
- sp = hp * 10 * skilllv / 100;
- if (!status_charge(src,hp,0)) {
- if (sd) clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
- clif_skill_nodamage(src, bl, skillid, skilllv, 1);
- status_heal(bl,0,sp,2);
- }
- break;
-
- case MA_REMOVETRAP:
- case HT_REMOVETRAP: {
- struct skill_unit *su;
- struct skill_unit_group *sg;
- su = BL_CAST(BL_SKILL, bl);
-
- // Mercenaries can remove any trap
- // Players can only remove their own traps or traps on Vs maps.
- if (su && (sg = su->group) && (src->type == BL_MER || sg->src_id == src->id || map_flag_vs(bl->m)) && (skill_get_inf2(sg->skill_id)&INF2_TRAP)) {
- clif_skill_nodamage(src, bl, skillid, skilllv, 1);
- if (sd && !(sg->unit_id == UNT_USED_TRAPS || (sg->unit_id == UNT_ANKLESNARE && sg->val2 != 0))) {
- // prevent picking up expired traps
- if (battle_config.skill_removetrap_type) {
- // get back all items used to deploy the trap
- for (i = 0; i < 10; i++) {
- if (skill_db[su->group->skill_id].itemid[i] > 0) {
- int flag;
- struct item item_tmp;
- 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],LOG_TYPE_OTHER))) {
- 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,0,0,0,0);
- }
- }
- }
- } else {
- // get back 1 trap
- struct item item_tmp;
- memset(&item_tmp,0,sizeof(item_tmp));
- item_tmp.nameid = su->group->item_id?su->group->item_id:ITEMID_TRAP;
- item_tmp.identify = 1;
- if (item_tmp.nameid && (flag=pc_additem(sd,&item_tmp,1,LOG_TYPE_OTHER))) {
- clif_additem(sd,0,0,flag);
- map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
- }
- }
- }
- skill_delunit(su);
- } else if (sd)
- clif_skill_fail(sd, skillid, USESKILL_FAIL_LEVEL, 0);
-
- }
- break;
- case HT_SPRINGTRAP:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- {
- struct skill_unit *su=NULL;
- if ((bl->type==BL_SKILL) && (su=(struct skill_unit *)bl) && (su->group)) {
- switch (su->group->unit_id) {
- case UNT_ANKLESNARE: // 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 UNT_BLASTMINE:
- case UNT_SKIDTRAP:
- case UNT_LANDMINE:
- case UNT_SHOCKWAVE:
- case UNT_SANDMAN:
- case UNT_FLASHER:
- case UNT_FREEZINGTRAP:
- case UNT_CLAYMORETRAP:
- case UNT_TALKIEBOX:
- su->group->unit_id = UNT_USED_TRAPS;
- clif_changetraplook(bl, UNT_USED_TRAPS);
- su->group->limit=DIFF_TICK(tick+1500,su->group->tick);
- su->limit=DIFF_TICK(tick+1500,su->group->tick);
- }
- }
- }
- break;
- case BD_ENCORE:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if (sd)
- unit_skilluse_id(src,src->id,sd->skillid_dance,sd->skilllv_dance);
- break;
-
- case AS_SPLASHER:
- if (tstatus->mode&MD_BOSS
- /**
- * Renewal dropped the 3/4 hp requirement
- **/
-#ifndef RENEWAL
- || tstatus-> hp > tstatus->max_hp*3/4
-#endif
- ) {
- if (sd) clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- map_freeblock_unlock();
- return 1;
- }
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start4(bl,type,100,skilllv,skillid,src->id,skill_get_time(skillid,skilllv),1000));
- if (sd) skill_blockpc_start(sd, skillid, skill_get_time(skillid, skilllv)+3000);
- break;
-
- case PF_MINDBREAKER: {
- if (tstatus->mode&MD_BOSS || battle_check_undead(tstatus->race,tstatus->def_ele)) {
- map_freeblock_unlock();
- return 1;
- }
-
- if (tsce) {
- //HelloKitty2 (?) explained that this silently fails when target is
- //already inflicted. [Skotlex]
- map_freeblock_unlock();
- return 1;
- }
-
- //Has a 55% + skilllv*5% success chance.
- if (!clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start(bl,type,55+5*skilllv,skilllv,skill_get_time(skillid,skilllv)))) {
- if (sd) clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- map_freeblock_unlock();
- return 0;
- }
-
- unit_skillcastcancel(bl,0);
-
- if (tsc && tsc->count) {
- status_change_end(bl, SC_FREEZE, INVALID_TIMER);
- if (tsc->data[SC_STONE] && tsc->opt1 == OPT1_STONE)
- status_change_end(bl, SC_STONE, INVALID_TIMER);
- status_change_end(bl, SC_SLEEP, INVALID_TIMER);
- }
-
- if (dstmd)
- mob_target(dstmd,src,skill_get_range2(src,skillid,skilllv));
- }
- break;
-
- case PF_SOULCHANGE: {
- unsigned int sp1 = 0, sp2 = 0;
- if (dstmd) {
- if (dstmd->state.soul_change_flag) {
- if (sd) clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
- dstmd->state.soul_change_flag = 1;
- sp2 = sstatus->max_sp * 3 /100;
- status_heal(src, 0, sp2, 2);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- break;
- }
- sp1 = sstatus->sp;
- sp2 = tstatus->sp;
-#ifdef RENEWAL
- sp1 = sp1 / 2;
- sp2 = sp2 / 2;
- if (tsc && tsc->data[SC_EXTREMITYFIST2])
- sp1 = tstatus->sp;
+ case SC_EXTREMITYFIST2:
#endif
- status_set_sp(src, sp2, 3);
- status_set_sp(bl, sp1, 3);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- }
- break;
-
- // Slim Pitcher
- case CR_SLIMPITCHER:
- // Updated to block Slim Pitcher from working on barricades and guardian stones.
- if (dstmd && (dstmd->class_ == MOBID_EMPERIUM || (dstmd->class_ >= MOBID_BARRICADE1 && dstmd->class_ <= MOBID_GUARIDAN_STONE2)))
- break;
- if (potion_hp || potion_sp) {
- int hp = potion_hp, sp = potion_sp;
- hp = hp * (100 + (tstatus->vit<<1))/100;
- sp = sp * (100 + (tstatus->int_<<1))/100;
- if (dstsd) {
- if (hp)
- hp = hp * (100 + pc_checkskill(dstsd,SM_RECOVERY)*10 + pc_skillheal2_bonus(dstsd, skillid))/100;
- if (sp)
- sp = sp * (100 + pc_checkskill(dstsd,MG_SRECOVERY)*10 + pc_skillheal2_bonus(dstsd, skillid))/100;
- }
- if (tsc && tsc->count) {
- if (tsc->data[SC_CRITICALWOUND]) {
- hp -= hp * tsc->data[SC_CRITICALWOUND]->val2 / 100;
- sp -= sp * tsc->data[SC_CRITICALWOUND]->val2 / 100;
- }
- if (tsc->data[SC_DEATHHURT]) {
- hp -= hp * 20 / 100;
- sp -= sp * 20 / 100;
- }
- if (tsc->data[SC_WATER_INSIGNIA] && tsc->data[SC_WATER_INSIGNIA]->val1 == 2) {
- hp += hp / 10;
- sp += sp / 10;
- }
- }
- if (hp > 0)
- clif_skill_nodamage(NULL,bl,AL_HEAL,hp,1);
- if (sp > 0)
- clif_skill_nodamage(NULL,bl,MG_SRECOVERY,sp,1);
- status_heal(bl,hp,sp,0);
- }
- break;
- // Full Chemical Protection
- case CR_FULLPROTECTION: {
- unsigned int equip[] = {EQP_WEAPON, EQP_SHIELD, EQP_ARMOR, EQP_HEAD_TOP};
- int i, s = 0, skilltime = skill_get_time(skillid,skilllv);
-
- for (i=0 ; i<4; i++) {
- if (bl->type != BL_PC || (dstsd && pc_checkequip(dstsd,equip[i]) < 0))
- continue;
- sc_start(bl,(sc_type)(SC_CP_WEAPON + i),100,skilllv,skilltime);
- s++;
- }
- if (sd && !s) {
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- map_freeblock_unlock(); // Don't consume item requirements
- return 0;
- }
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- }
- break;
-
- case RG_CLEANER: //AppleGirl
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- break;
-
- case CG_LONGINGFREEDOM: {
- if (tsc && !tsce && (tsce=tsc->data[SC_DANCING]) && tsce->val4
- && (tsce->val1&0xFFFF) != CG_MOONLIT) { //Can't use Longing for Freedom while under Moonlight Petals. [Skotlex]
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
- }
- }
- break;
-
- case CG_TAROTCARD: {
- int eff, count = -1;
- if (rnd() % 100 > skilllv * 8 || (dstmd && ((dstmd->guardian_data && dstmd->class_ == MOBID_EMPERIUM) || mob_is_battleground(dstmd)))) {
- if (sd)
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
-
- map_freeblock_unlock();
- return 0;
- }
- status_zap(src,0,skill_db[skill_get_index(skillid)].sp[skilllv]); // consume sp only if succeeded [Inkfish]
- do {
- eff = rnd() % 14;
- clif_specialeffect(bl, 523 + eff, AREA);
- switch (eff) {
- case 0: // heals SP to 0
- status_percent_damage(src, bl, 0, 100, false);
- break;
- case 1: // matk halved
- sc_start(bl,SC_INCMATKRATE,100,-50,skill_get_time2(skillid,skilllv));
- break;
- case 2: // all buffs removed
- status_change_clear_buffs(bl,1);
- break;
- case 3: { // 1000 damage, random armor destroyed
- int where[] = { EQP_ARMOR, EQP_SHIELD, EQP_HELM, EQP_SHOES, EQP_GARMENT };
- status_fix_damage(src, bl, 1000, 0);
- clif_damage(src,bl,tick,0,0,1000,0,0,0);
- if (!status_isdead(bl))
- skill_break_equip(bl, where[rnd()%5], 10000, BCT_ENEMY);
- }
- break;
- case 4: // atk halved
- sc_start(bl,SC_INCATKRATE,100,-50,skill_get_time2(skillid,skilllv));
- break;
- case 5: // 2000HP heal, random teleported
- status_heal(src, 2000, 0, 0);
- if (!map_flag_vs(bl->m))
- unit_warp(bl, -1,-1,-1, CLR_TELEPORT);
- break;
- case 6: // random 2 other effects
- if (count == -1)
- count = 3;
- else
- count++; //Should not retrigger this one.
- break;
- case 7: { // stop freeze or stoned
- enum sc_type sc[] = { SC_STOP, SC_FREEZE, SC_STONE };
- sc_start(bl,sc[rnd()%3],100,skilllv,skill_get_time2(skillid,skilllv));
- }
- break;
- case 8: // curse coma and poison
- sc_start(bl,SC_COMA,100,skilllv,skill_get_time2(skillid,skilllv));
- sc_start(bl,SC_CURSE,100,skilllv,skill_get_time2(skillid,skilllv));
- sc_start(bl,SC_POISON,100,skilllv,skill_get_time2(skillid,skilllv));
- break;
- case 9: // confusion
- sc_start(bl,SC_CONFUSION,100,skilllv,skill_get_time2(skillid,skilllv));
- break;
- case 10: // 6666 damage, atk matk halved, cursed
- status_fix_damage(src, bl, 6666, 0);
- clif_damage(src,bl,tick,0,0,6666,0,0,0);
- sc_start(bl,SC_INCATKRATE,100,-50,skill_get_time2(skillid,skilllv));
- sc_start(bl,SC_INCMATKRATE,100,-50,skill_get_time2(skillid,skilllv));
- sc_start(bl,SC_CURSE,skilllv,100,skill_get_time2(skillid,skilllv));
- break;
- case 11: // 4444 damage
- status_fix_damage(src, bl, 4444, 0);
- clif_damage(src,bl,tick,0,0,4444,0,0,0);
- break;
- case 12: // stun
- sc_start(bl,SC_STUN,100,skilllv,5000);
- break;
- case 13: // atk,matk,hit,flee,def reduced
- sc_start(bl,SC_INCATKRATE,100,-20,skill_get_time2(skillid,skilllv));
- sc_start(bl,SC_INCMATKRATE,100,-20,skill_get_time2(skillid,skilllv));
- sc_start(bl,SC_INCHITRATE,100,-20,skill_get_time2(skillid,skilllv));
- sc_start(bl,SC_INCFLEERATE,100,-20,skill_get_time2(skillid,skilllv));
- sc_start(bl,SC_INCDEFRATE,100,-20,skill_get_time2(skillid,skilllv));
- break;
- default:
- break;
- }
- } while ((--count) > 0);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- }
- break;
-
- case SL_ALCHEMIST:
- case SL_ASSASIN:
- case SL_BARDDANCER:
- case SL_BLACKSMITH:
- case SL_CRUSADER:
- case SL_HUNTER:
- case SL_KNIGHT:
- case SL_MONK:
- case SL_PRIEST:
- case SL_ROGUE:
- case SL_SAGE:
- case SL_SOULLINKER:
- case SL_STAR:
- case SL_SUPERNOVICE:
- case SL_WIZARD:
- //NOTE: here, 'type' has the value of the associated MAPID, not of the SC_SPIRIT constant.
- if (sd && !(dstsd && (dstsd->class_&MAPID_UPPERMASK) == type)) {
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
- if (skillid == SL_SUPERNOVICE && dstsd && dstsd->die_counter && !(rnd()%100)) {
- //Erase death count 1% of the casts
- dstsd->die_counter = 0;
- pc_setglobalreg(dstsd,"PC_DIE_COUNTER", 0);
- clif_specialeffect(bl, 0x152, AREA);
- //SC_SPIRIT invokes status_calc_pc for us.
- }
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start4(bl,SC_SPIRIT,100,skilllv,skillid,0,0,skill_get_time(skillid,skilllv)));
- sc_start(src,SC_SMA,100,skilllv,skill_get_time(SL_SMA,skilllv));
- break;
- case SL_HIGH:
- if (sd && !(dstsd && (dstsd->class_&JOBL_UPPER) && !(dstsd->class_&JOBL_2) && dstsd->status.base_level < 70)) {
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start4(bl,type,100,skilllv,skillid,0,0,skill_get_time(skillid,skilllv)));
- sc_start(src,SC_SMA,100,skilllv,skill_get_time(SL_SMA,skilllv));
- break;
-
- case SL_SWOO:
- if (tsce) {
- sc_start(src,SC_STUN,100,skilllv,10000);
- break;
- }
- case SL_SKA: // [marquis007]
- case SL_SKE:
- if (sd && !battle_config.allow_es_magic_pc && bl->type != BL_MOB) {
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- status_change_start(src,SC_STUN,10000,skilllv,0,0,0,500,10);
- break;
- }
- clif_skill_nodamage(src,bl,skillid,skilllv,sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
- if (skillid == SL_SKE)
- sc_start(src,SC_SMA,100,skilllv,skill_get_time(SL_SMA,skilllv));
- break;
-
- // New guild skills [Celest]
- case GD_BATTLEORDER:
- if (flag&1) {
- if (status_get_guild_id(src) == status_get_guild_id(bl))
- sc_start(bl,type,100,skilllv,skill_get_time(skillid, skilllv));
- } else if (status_get_guild_id(src)) {
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- map_foreachinrange(skill_area_sub, src,
- skill_get_splash(skillid, skilllv), BL_PC,
- src,skillid,skilllv,tick, flag|BCT_GUILD|1,
- skill_castend_nodamage_id);
- if (sd)
- guild_block_skill(sd,skill_get_time2(skillid,skilllv));
- }
- break;
- case GD_REGENERATION:
- if (flag&1) {
- if (status_get_guild_id(src) == status_get_guild_id(bl))
- sc_start(bl,type,100,skilllv,skill_get_time(skillid, skilllv));
- } else if (status_get_guild_id(src)) {
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- map_foreachinrange(skill_area_sub, src,
- skill_get_splash(skillid, skilllv), BL_PC,
- src,skillid,skilllv,tick, flag|BCT_GUILD|1,
- skill_castend_nodamage_id);
- if (sd)
- guild_block_skill(sd,skill_get_time2(skillid,skilllv));
- }
- break;
- case GD_RESTORE:
- if (flag&1) {
- if (status_get_guild_id(src) == status_get_guild_id(bl))
- clif_skill_nodamage(src,bl,AL_HEAL,status_percent_heal(bl,90,90),1);
- } else if (status_get_guild_id(src)) {
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- map_foreachinrange(skill_area_sub, src,
- skill_get_splash(skillid, skilllv), BL_PC,
- src,skillid,skilllv,tick, flag|BCT_GUILD|1,
- skill_castend_nodamage_id);
- if (sd)
- guild_block_skill(sd,skill_get_time2(skillid,skilllv));
- }
- break;
- case GD_EMERGENCYCALL: {
- 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 j = 0;
- struct guild *g = NULL;
- // i don't know if it actually summons in a circle, but oh well. ;P
- g = sd?sd->state.gmaster_flag:guild_search(status_get_guild_id(src));
- if (!g)
- break;
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- for (i = 0; i < g->max_member; i++, j++) {
- if (j>8) j=0;
- if ((dstsd = g->member[i].sd) != NULL && sd != dstsd && !dstsd->state.autotrade && !pc_isdead(dstsd)) {
- if (map[dstsd->bl.m].flag.nowarp && !map_flag_gvg2(dstsd->bl.m))
- continue;
- if (map_getcell(src->m,src->x+dx[j],src->y+dy[j],CELL_CHKNOREACH))
- dx[j] = dy[j] = 0;
- pc_setpos(dstsd, map_id2index(src->m), src->x+dx[j], src->y+dy[j], CLR_RESPAWN);
- }
- }
- if (sd)
- guild_block_skill(sd,skill_get_time2(skillid,skilllv));
- }
- break;
-
- case SG_FEEL:
- //AuronX reported you CAN memorize the same map as all three. [Skotlex]
- if (sd) {
- if (!sd->feel_map[skilllv-1].index)
- clif_feel_req(sd->fd,sd, skilllv);
- else
- clif_feel_info(sd, skilllv-1, 1);
- }
- break;
-
- case SG_HATE:
- if (sd) {
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if (!pc_set_hate_mob(sd, skilllv-1, bl))
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- }
- break;
-
- case GS_GLITTERING:
- if (sd) {
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if (rnd()%100 < (20+10*skilllv))
- pc_addspiritball(sd,skill_get_time(skillid,skilllv),10);
- else if (sd->spiritball > 0)
- pc_delspiritball(sd,1,0);
- }
- break;
-
- case GS_CRACKER:
- /* per official standards, this skill works on players and mobs. */
- if (sd && (dstsd || dstmd)) {
- i =65 -5*distance_bl(src,bl); //Base rate
- if (i < 30) i = 30;
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- sc_start(bl,SC_STUN, i,skilllv,skill_get_time2(skillid,skilllv));
- }
- break;
-
- case AM_CALLHOMUN: //[orn]
- if (sd && !merc_call_homunculus(sd))
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
-
- case AM_REST:
- if (sd) {
- if (merc_hom_vaporize(sd,1))
- clif_skill_nodamage(src, bl, skillid, skilllv, 1);
- else
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- }
- break;
-
- case HAMI_CASTLE: //[orn]
- if (rnd()%100 < 20*skilllv && src != bl) {
- int x,y;
- x = src->x;
- y = src->y;
- if (hd)
- skill_blockhomun_start(hd, skillid, skill_get_time2(skillid,skilllv));
-
- if (unit_movepos(src,bl->x,bl->y,0,0)) {
- clif_skill_nodamage(src,src,skillid,skilllv,1); // Homunc
- clif_slide(src,bl->x,bl->y) ;
- if (unit_movepos(bl,x,y,0,0)) {
- clif_skill_nodamage(bl,bl,skillid,skilllv,1); // Master
- clif_slide(bl,x,y) ;
- }
-
- //TODO: Shouldn't also players and the like switch targets?
- map_foreachinrange(skill_chastle_mob_changetarget,src,
- AREA_SIZE, BL_MOB, bl, src);
- }
- }
- // Failed
- else if (hd && hd->master)
- clif_skill_fail(hd->master, skillid, USESKILL_FAIL_LEVEL, 0);
- else if (sd)
- clif_skill_fail(sd, skillid, USESKILL_FAIL_LEVEL, 0);
- break;
- case HVAN_CHAOTIC: { //[orn]
- static const int per[5][2]= {{20,50},{50,60},{25,75},{60,64},{34,67}};
- int r = rnd()%100;
- i = (skilllv-1)%5;
- if (r<per[i][0]) //Self
- bl = src;
- else if (r<per[i][1]) //Master
- bl = battle_get_master(src);
- else //Enemy
- bl = map_id2bl(battle_gettarget(src));
-
- if (!bl) bl = src;
- i = skill_calc_heal(src, bl, skillid, 1+rnd()%skilllv, true);
- //Eh? why double skill packet?
- clif_skill_nodamage(src,bl,AL_HEAL,i,1);
- clif_skill_nodamage(src,bl,skillid,i,1);
- status_heal(bl, i, 0, 0);
- }
- break;
- //Homun single-target support skills [orn]
- case HAMI_BLOODLUST:
- case HFLI_FLEET:
- case HFLI_SPEED:
- case HLIF_CHANGE:
- case MH_ANGRIFFS_MODUS:
- case MH_GOLDENE_FERSE:
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
- if (hd)
- skill_blockhomun_start(hd, skillid, skill_get_time2(skillid,skilllv));
- break;
-
- case NPC_DRAGONFEAR:
- if (flag&1) {
- const enum sc_type sc[] = { SC_STUN, SC_SILENCE, SC_CONFUSION, SC_BLEEDING };
- int j;
- j = i = rnd()%ARRAYLENGTH(sc);
- while (!sc_start(bl,sc[i],100,skilllv,skill_get_time2(skillid,i+1))) {
- i++;
- if (i == ARRAYLENGTH(sc))
- i = 0;
- if (i == j)
- break;
- }
- break;
- }
- case NPC_WIDEBLEEDING:
- case NPC_WIDECONFUSE:
- case NPC_WIDECURSE:
- case NPC_WIDEFREEZE:
- case NPC_WIDESLEEP:
- case NPC_WIDESILENCE:
- case NPC_WIDESTONE:
- case NPC_WIDESTUN:
- case NPC_SLOWCAST:
- case NPC_WIDEHELLDIGNITY:
- if (flag&1)
- sc_start(bl,type,100,skilllv,skill_get_time2(skillid,skilllv));
- else {
- skill_area_temp[2] = 0; //For SD_PREAMBLE
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- map_foreachinrange(skill_area_sub, bl,
- skill_get_splash(skillid, skilllv),BL_CHAR,
- src,skillid,skilllv,tick, flag|BCT_ENEMY|SD_PREAMBLE|1,
- skill_castend_nodamage_id);
- }
- break;
- case NPC_WIDESOULDRAIN:
- if (flag&1)
- status_percent_damage(src,bl,0,((skilllv-1)%5+1)*20,false);
- else {
- skill_area_temp[2] = 0; //For SD_PREAMBLE
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- map_foreachinrange(skill_area_sub, bl,
- skill_get_splash(skillid, skilllv),BL_CHAR,
- src,skillid,skilllv,tick, flag|BCT_ENEMY|SD_PREAMBLE|1,
- skill_castend_nodamage_id);
- }
- break;
- case ALL_PARTYFLEE:
- if (sd && !(flag&1)) {
- if (!sd->status.party_id) {
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
- party_foreachsamemap(skill_area_sub, sd, skill_get_splash(skillid, skilllv), src, skillid, skilllv, tick, flag|BCT_PARTY|1, skill_castend_nodamage_id);
- } else
- clif_skill_nodamage(src,bl,skillid,skilllv,sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
- break;
- case NPC_TALK:
- case ALL_WEWISH:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- break;
- case ALL_BUYING_STORE:
- if (sd) {
- // players only, skill allows 5 buying slots
- clif_skill_nodamage(src, bl, skillid, skilllv, buyingstore_setup(sd, MAX_BUYINGSTORE_SLOTS));
- }
- break;
- case RK_ENCHANTBLADE:
- clif_skill_nodamage(src,bl,skillid,skilllv,// formula not confirmed
- sc_start2(bl,type,100,skilllv,100+20*skilllv/*+sstatus->int_/2+status_get_lv(bl)/10*/,skill_get_time(skillid,skilllv)));
- break;
- case RK_DRAGONHOWLING:
- if (flag&1)
- sc_start(bl,type,50 + 6 * skilllv,skilllv,skill_get_time(skillid,skilllv));
- else {
- skill_area_temp[2] = 0;
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- map_foreachinrange(skill_area_sub, src,
- skill_get_splash(skillid,skilllv),BL_CHAR,
- src,skillid,skilllv,tick,flag|BCT_ENEMY|SD_PREAMBLE|1,
- skill_castend_nodamage_id);
- }
- break;
- case RK_IGNITIONBREAK:
- case LG_EARTHDRIVE:
- clif_skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
- i = skill_get_splash(skillid,skilllv);
- if (skillid == LG_EARTHDRIVE) {
- int dummy = 1;
- map_foreachinarea(skill_cell_overlap, src->m, src->x-i, src->y-i, src->x+i, src->y+i, BL_SKILL, LG_EARTHDRIVE, &dummy, src);
- }
- map_foreachinrange(skill_area_sub, bl,i,BL_CHAR,
- src,skillid,skilllv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
- break;
- case RK_STONEHARDSKIN:
- if (sd && pc_checkskill(sd,RK_RUNEMASTERY) >= 4) {
- int heal = sstatus->hp / 4; // 25% HP
- if (status_charge(bl,heal,0))
- clif_skill_nodamage(src,bl,skillid,skilllv,sc_start2(bl,type,100,skilllv,heal,skill_get_time(skillid,skilllv)));
- else
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- }
- break;
- case RK_REFRESH:
- if (sd && pc_checkskill(sd,RK_RUNEMASTERY) >= 8) {
- int heal = status_get_max_hp(bl) * 25 / 100;
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
- status_heal(bl,heal,0,1);
- status_change_clear_buffs(bl,4);
- }
- break;
-
- case RK_MILLENNIUMSHIELD:
- if (sd && pc_checkskill(sd,RK_RUNEMASTERY) >= 9) {
- short shields = (rnd()%100<50) ? 4 : ((rnd()%100<80) ? 3 : 2);
- sc_start4(bl,type,100,skilllv,shields,1000,0,skill_get_time(skillid,skilllv));
- clif_millenniumshield(sd,shields);
- clif_skill_nodamage(src,bl,skillid,1,1);
- }
- break;
-
- case RK_GIANTGROWTH:
- case RK_VITALITYACTIVATION:
- case RK_ABUNDANCE:
- if (sd) {
- int lv = 1; // RK_GIANTGROWTH
- if (skillid == RK_VITALITYACTIVATION)
- lv = 2;
- else if (skillid == RK_ABUNDANCE)
- lv = 6;
- if (pc_checkskill(sd,RK_RUNEMASTERY) >= lv)
- clif_skill_nodamage(src,bl,skillid,skilllv,sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
- }
- break;
-
- case RK_FIGHTINGSPIRIT:
- if (flag&1) {
- if (src == bl)
- sc_start2(bl,type,100,skill_area_temp[5],10*(sd?pc_checkskill(sd,RK_RUNEMASTERY):10),skill_get_time(skillid,skilllv));
- else
- sc_start(bl,type,100,skill_area_temp[5]/4,skill_get_time(skillid,skilllv));
- } else if (sd && pc_checkskill(sd,RK_RUNEMASTERY) >= 5) {
- if (sd->status.party_id) {
- i = party_foreachsamemap(skill_area_sub,sd,skill_get_splash(skillid,skilllv),src,skillid,skilllv,tick,BCT_PARTY,skill_area_sub_count);
- skill_area_temp[5] = 7 * i; // ATK
- party_foreachsamemap(skill_area_sub,sd,skill_get_splash(skillid,skilllv),src,skillid,skilllv,tick,flag|BCT_PARTY|1,skill_castend_nodamage_id);
- } else
- sc_start2(bl,type,100,7,5,skill_get_time(skillid,skilllv));
- }
- clif_skill_nodamage(src,bl,skillid,1,1);
- break;
- /**
- * Guilotine Cross
- **/
- case GC_ROLLINGCUTTER: {
- short count = 1;
- skill_area_temp[2] = 0;
- map_foreachinrange(skill_area_sub,src,skill_get_splash(skillid,skilllv),BL_CHAR,src,skillid,skilllv,tick,flag|BCT_ENEMY|SD_PREAMBLE|SD_SPLASH|1,skill_castend_damage_id);
- if (tsc && tsc->data[SC_ROLLINGCUTTER]) {
- // Every time the skill is casted the status change is reseted adding a counter.
- count += (short)tsc->data[SC_ROLLINGCUTTER]->val1;
- if (count > 10)
- count = 10; // Max coounter
- status_change_end(bl, SC_ROLLINGCUTTER, INVALID_TIMER);
- }
- sc_start(bl,SC_ROLLINGCUTTER,100,count,skill_get_time(skillid,skilllv));
- clif_skill_nodamage(src,src,skillid,skilllv,1);
- }
- break;
+ continue;
+ /**
+ * bugreport:4888 these songs may only be dispelled if you're not in their song area anymore
+ **/
+ case SC_WHISTLE:
+ case SC_ASSNCROS:
+ case SC_POEMBRAGI:
+ case SC_APPLEIDUN:
+ case SC_HUMMING:
+ case SC_DONTFORGETME:
+ case SC_FORTUNE:
+ case SC_SERVICE4U:
+ if( tsc->data[i]->val4 ) //val4 = out-of-song-area
+ continue;
+ break;
+ case SC_ASSUMPTIO:
+ if( bl->type == BL_MOB )
+ continue;
+ break;
+ }
+ if(i==SC_BERSERK || i==SC_SATURDAYNIGHTFEVER) tsc->data[i]->val2=0; //Mark a dispelled berserk to avoid setting hp to 100 by setting hp penalty to 0.
+ status_change_end(bl, (sc_type)i, INVALID_TIMER);
+ }
+ break;
+ }
+ //Affect all targets on splash area.
+ map_foreachinrange(skill_area_sub, bl, i, BL_CHAR,
+ src, skillid, skilllv, tick, flag|1,
+ skill_castend_damage_id);
+ break;
+
+ case TF_BACKSLIDING: //This is the correct implementation as per packet logging information. [Skotlex]
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ skill_blown(src,bl,skill_get_blewcount(skillid,skilllv),unit_getdir(bl),0);
+ break;
+
+ case TK_HIGHJUMP:
+ {
+ int x,y, dir = unit_getdir(src);
+
+ //Fails on noteleport maps, except for GvG and BG maps [Skotlex]
+ if( map[src->m].flag.noteleport &&
+ !(map[src->m].flag.battleground || map_flag_gvg2(src->m) )
+ ) {
+ x = src->x;
+ y = src->y;
+ } else {
+ x = src->x + dirx[dir]*skilllv*2;
+ y = src->y + diry[dir]*skilllv*2;
+ }
- case GC_WEAPONBLOCKING:
- if (tsc && tsc->data[SC_WEAPONBLOCKING])
- status_change_end(bl, SC_WEAPONBLOCKING, INVALID_TIMER);
- else
- sc_start(bl,SC_WEAPONBLOCKING,100,skilllv,skill_get_time(skillid,skilllv));
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- break;
+ clif_skill_nodamage(src,bl,TK_HIGHJUMP,skilllv,1);
+ if(!map_count_oncell(src->m,x,y,BL_PC|BL_NPC|BL_MOB) && map_getcell(src->m,x,y,CELL_CHKREACH)) {
+ clif_slide(src,x,y);
+ unit_movepos(src, x, y, 1, 0);
+ }
+ }
+ break;
+
+ case SA_CASTCANCEL:
+ case SO_SPELLFIST:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ unit_skillcastcancel(src,1);
+ if(sd) {
+ int sp = skill_get_sp(sd->skillid_old,sd->skilllv_old);
+ if( skillid == SO_SPELLFIST ){
+ sc_start4(src,type,100,skilllv+1,skilllv,sd->skillid_old,sd->skilllv_old,skill_get_time(skillid,skilllv));
+ sd->skillid_old = sd->skilllv_old = 0;
+ break;
+ }
+ sp = sp * (90 - (skilllv-1)*20) / 100;
+ if(sp < 0) sp = 0;
+ status_zap(src, 0, sp);
+ }
+ break;
+ case SA_SPELLBREAKER:
+ {
+ int sp;
+ if(tsc && tsc->data[SC_MAGICROD]) {
+ sp = skill_get_sp(skillid,skilllv);
+ sp = sp * tsc->data[SC_MAGICROD]->val2 / 100;
+ if(sp < 1) sp = 1;
+ status_heal(bl,0,sp,2);
+ status_percent_damage(bl, src, 0, -20, false); //20% max SP damage.
+ } else {
+ struct unit_data *ud = unit_bl2ud(bl);
+ int bl_skillid=0,bl_skilllv=0,hp = 0;
+ if (!ud || ud->skilltimer == INVALID_TIMER)
+ break; //Nothing to cancel.
+ bl_skillid = ud->skillid;
+ bl_skilllv = ud->skilllv;
+ if (tstatus->mode & MD_BOSS)
+ { //Only 10% success chance against bosses. [Skotlex]
+ if (rnd()%100 < 90)
+ {
+ if (sd) clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+ } else if (!dstsd || map_flag_vs(bl->m)) //HP damage only on pvp-maps when against players.
+ hp = tstatus->max_hp/50; //Recover 2% HP [Skotlex]
- case GC_CREATENEWPOISON:
- if (sd) {
- clif_skill_produce_mix_list(sd,skillid,25);
- clif_skill_nodamage(src, bl, skillid, skilllv, 1);
- }
- break;
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ unit_skillcastcancel(bl,0);
+ sp = skill_get_sp(bl_skillid,bl_skilllv);
+ status_zap(bl, hp, sp);
- case GC_POISONINGWEAPON:
- if (sd) {
- clif_poison_list(sd,skilllv);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- }
- break;
+ if (hp && skilllv >= 5)
+ hp>>=1; //Recover half damaged HP at level 5 [Skotlex]
+ else
+ hp = 0;
- case GC_ANTIDOTE:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if (tsc) {
- status_change_end(bl, SC_PARALYSE, INVALID_TIMER);
- status_change_end(bl, SC_PYREXIA, INVALID_TIMER);
- status_change_end(bl, SC_DEATHHURT, INVALID_TIMER);
- status_change_end(bl, SC_LEECHESEND, INVALID_TIMER);
- status_change_end(bl, SC_VENOMBLEED, INVALID_TIMER);
- status_change_end(bl, SC_MAGICMUSHROOM, INVALID_TIMER);
- status_change_end(bl, SC_TOXIN, INVALID_TIMER);
- status_change_end(bl, SC_OBLIVIONCURSE, INVALID_TIMER);
- }
- break;
+ if (sp) //Recover some of the SP used
+ sp = sp*(25*(skilllv-1))/100;
- case GC_PHANTOMMENACE:
- clif_skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- map_foreachinrange(skill_area_sub,src,skill_get_splash(skillid,skilllv),BL_CHAR,
- src,skillid,skilllv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
- break;
+ if(hp || sp)
+ status_heal(src, hp, sp, 2);
+ }
+ }
+ break;
+ case SA_MAGICROD:
+ clif_skill_nodamage(src,src,SA_MAGICROD,skilllv,1);
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv));
+ break;
+ case SA_AUTOSPELL:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ if(sd)
+ clif_autospell(sd,skilllv);
+ else {
+ int maxlv=1,spellid=0;
+ static const int spellarray[3] = { MG_COLDBOLT,MG_FIREBOLT,MG_LIGHTNINGBOLT };
+ if(skilllv >= 10) {
+ spellid = MG_FROSTDIVER;
+// if (tsc && tsc->data[SC_SPIRIT] && tsc->data[SC_SPIRIT]->val2 == SA_SAGE)
+// maxlv = 10;
+// else
+ maxlv = skilllv - 9;
+ }
+ else if(skilllv >=8) {
+ spellid = MG_FIREBALL;
+ maxlv = skilllv - 7;
+ }
+ else if(skilllv >=5) {
+ spellid = MG_SOULSTRIKE;
+ maxlv = skilllv - 4;
+ }
+ else if(skilllv >=2) {
+ int i = rnd()%3;
+ spellid = spellarray[i];
+ maxlv = skilllv - 1;
+ }
+ else if(skilllv > 0) {
+ spellid = MG_NAPALMBEAT;
+ maxlv = 3;
+ }
+ if(spellid > 0)
+ sc_start4(src,SC_AUTOSPELL,100,skilllv,spellid,maxlv,0,
+ skill_get_time(SA_AUTOSPELL,skilllv));
+ }
+ break;
+
+ case BS_GREED:
+ if(sd){
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ map_foreachinrange(skill_greed,bl,
+ skill_get_splash(skillid, skilllv),BL_ITEM,bl);
+ }
+ break;
+
+ case SA_ELEMENTWATER:
+ case SA_ELEMENTFIRE:
+ case SA_ELEMENTGROUND:
+ case SA_ELEMENTWIND:
+ if(sd && !dstmd) //Only works on monsters.
+ break;
+ if(tstatus->mode&MD_BOSS)
+ break;
+ case NPC_ATTRICHANGE:
+ case NPC_CHANGEWATER:
+ case NPC_CHANGEGROUND:
+ case NPC_CHANGEFIRE:
+ case NPC_CHANGEWIND:
+ case NPC_CHANGEPOISON:
+ case NPC_CHANGEHOLY:
+ case NPC_CHANGEDARKNESS:
+ case NPC_CHANGETELEKINESIS:
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start2(bl, type, 100, skilllv, skill_get_ele(skillid,skilllv),
+ skill_get_time(skillid, skilllv)));
+ break;
+ case NPC_CHANGEUNDEAD:
+ //This skill should fail if target is wearing bathory/evil druid card [Brainstorm]
+ //TO-DO This is ugly, fix it
+ if(tstatus->def_ele==ELE_UNDEAD || tstatus->def_ele==ELE_DARK) break;
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start2(bl, type, 100, skilllv, skill_get_ele(skillid,skilllv),
+ skill_get_time(skillid, skilllv)));
+ break;
+
+ case NPC_PROVOCATION:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ if (md) mob_unlocktarget(md, tick);
+ break;
+
+ case NPC_KEEPING:
+ case NPC_BARRIER:
+ {
+ int skill_time = skill_get_time(skillid,skilllv);
+ struct unit_data *ud = unit_bl2ud(bl);
+ if (clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start(bl,type,100,skilllv,skill_time))
+ && ud) { //Disable attacking/acting/moving for skill's duration.
+ ud->attackabletime =
+ ud->canact_tick =
+ ud->canmove_tick = tick + skill_time;
+ }
+ }
+ break;
+
+ case NPC_REBIRTH:
+ if( md && md->state.rebirth )
+ break; // only works once
+ sc_start(bl,type,100,skilllv,-1);
+ break;
+
+ case NPC_DARKBLESSING:
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start2(bl,type,(50+skilllv*5),skilllv,skilllv,skill_get_time2(skillid,skilllv)));
+ break;
+
+ case NPC_LICK:
+ status_zap(bl, 0, 100);
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start(bl,type,(skilllv*5),skilllv,skill_get_time2(skillid,skilllv)));
+ break;
+
+ case NPC_SUICIDE:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ status_kill(src); //When suiciding, neither exp nor drops is given.
+ break;
+
+ case NPC_SUMMONSLAVE:
+ case NPC_SUMMONMONSTER:
+ if(md && md->skillidx >= 0)
+ mob_summonslave(md,md->db->skill[md->skillidx].val,skilllv,skillid);
+ break;
+
+ case NPC_CALLSLAVE:
+ mob_warpslave(src,MOB_SLAVEDISTANCE);
+ break;
+
+ case NPC_RANDOMMOVE:
+ if (md) {
+ md->next_walktime = tick - 1;
+ mob_randomwalk(md,tick);
+ }
+ break;
+
+ case NPC_SPEEDUP:
+ {
+ // or does it increase casting rate? just a guess xD
+ int i = SC_ASPDPOTION0 + skilllv - 1;
+ if (i > SC_ASPDPOTION3)
+ i = SC_ASPDPOTION3;
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start(bl,(sc_type)i,100,skilllv,skilllv * 60000));
+ }
+ break;
+
+ case NPC_REVENGE:
+ // not really needed... but adding here anyway ^^
+ if (md && md->master_id > 0) {
+ struct block_list *mbl, *tbl;
+ if ((mbl = map_id2bl(md->master_id)) == NULL ||
+ (tbl = battle_gettargeted(mbl)) == NULL)
+ break;
+ md->state.provoke_flag = tbl->id;
+ mob_target(md, tbl, sstatus->rhw.range);
+ }
+ break;
+
+ case NPC_RUN:
+ {
+ const int mask[8][2] = {{0,-1},{1,-1},{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1}};
+ int dir = (bl == src)?unit_getdir(src):map_calc_dir(src,bl->x,bl->y); //If cast on self, run forward, else run away.
+ unit_stop_attack(src);
+ //Run skillv tiles overriding the can-move check.
+ if (unit_walktoxy(src, src->x + skilllv * mask[dir][0], src->y + skilllv * mask[dir][1], 2) && md)
+ md->state.skillstate = MSS_WALK; //Otherwise it isn't updated in the ai.
+ }
+ break;
+
+ case NPC_TRANSFORMATION:
+ case NPC_METAMORPHOSIS:
+ if(md && md->skillidx >= 0) {
+ int class_ = mob_random_class (md->db->skill[md->skillidx].val,0);
+ if (skilllv > 1) //Multiply the rest of mobs. [Skotlex]
+ mob_summonslave(md,md->db->skill[md->skillidx].val,skilllv-1,skillid);
+ if (class_) mob_class_change(md, class_);
+ }
+ break;
+
+ case NPC_EMOTION_ON:
+ case NPC_EMOTION:
+ //va[0] is the emotion to use.
+ //NPC_EMOTION & NPC_EMOTION_ON can change a mob's mode 'permanently' [Skotlex]
+ //val[1] 'sets' the mode
+ //val[2] adds to the current mode
+ //val[3] removes from the current mode
+ //val[4] if set, asks to delete the previous mode change.
+ if(md && md->skillidx >= 0 && tsc)
+ {
+ clif_emotion(bl, md->db->skill[md->skillidx].val[0]);
+ if(md->db->skill[md->skillidx].val[4] && tsce)
+ status_change_end(bl, type, INVALID_TIMER);
+
+ if(md->db->skill[md->skillidx].val[1] || md->db->skill[md->skillidx].val[2])
+ sc_start4(src, type, 100, skilllv,
+ md->db->skill[md->skillidx].val[1],
+ md->db->skill[md->skillidx].val[2],
+ md->db->skill[md->skillidx].val[3],
+ skill_get_time(skillid, skilllv));
+ }
+ break;
+
+ case NPC_POWERUP:
+ sc_start(bl,SC_INCATKRATE,100,200,skill_get_time(skillid, skilllv));
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start(bl,type,100,100,skill_get_time(skillid, skilllv)));
+ break;
+
+ case NPC_AGIUP:
+ sc_start(bl,SC_SPEEDUP1,100,skilllv,skill_get_time(skillid, skilllv));
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start(bl,type,100,100,skill_get_time(skillid, skilllv)));
+ break;
+
+ case NPC_INVISIBLE:
+ //Have val4 passed as 6 is for "infinite cloak" (do not end on attack/skill use).
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start4(bl,type,100,skilllv,0,0,6,skill_get_time(skillid,skilllv)));
+ break;
+
+ case NPC_SIEGEMODE:
+ // not sure what it does
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ break;
+
+ case WE_MALE:
+ {
+ int hp_rate=(skilllv <= 0)? 0:skill_db[skillid].hp_rate[skilllv-1];
+ int gain_hp= tstatus->max_hp*abs(hp_rate)/100; // The earned is the same % of the target HP than it costed the caster. [Skotlex]
+ clif_skill_nodamage(src,bl,skillid,status_heal(bl, gain_hp, 0, 0),1);
+ }
+ break;
+ case WE_FEMALE:
+ {
+ int sp_rate=(skilllv <= 0)? 0:skill_db[skillid].sp_rate[skilllv-1];
+ int gain_sp=tstatus->max_sp*abs(sp_rate)/100;// The earned is the same % of the target SP than it costed the caster. [Skotlex]
+ clif_skill_nodamage(src,bl,skillid,status_heal(bl, 0, gain_sp, 0),1);
+ }
+ break;
+
+ // parent-baby skills
+ case WE_BABY:
+ if(sd){
+ 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,USESKILL_FAIL_LEVEL,0);
+ map_freeblock_unlock();
+ return 0;
+ }
+ status_change_start(bl,SC_STUN,10000,skilllv,0,0,0,skill_get_time2(skillid,skilllv),8);
+ if (f_sd) sc_start(&f_sd->bl,type,100,skilllv,skill_get_time(skillid,skilllv));
+ if (m_sd) sc_start(&m_sd->bl,type,100,skilllv,skill_get_time(skillid,skilllv));
+ }
+ break;
+
+ case PF_HPCONVERSION:
+ {
+ int hp, sp;
+ hp = sstatus->max_hp/10;
+ sp = hp * 10 * skilllv / 100;
+ if (!status_charge(src,hp,0)) {
+ if (sd) clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+ clif_skill_nodamage(src, bl, skillid, skilllv, 1);
+ status_heal(bl,0,sp,2);
+ }
+ break;
+
+ case MA_REMOVETRAP:
+ case HT_REMOVETRAP:
+ {
+ struct skill_unit* su;
+ struct skill_unit_group* sg;
+ su = BL_CAST(BL_SKILL, bl);
+
+ // Mercenaries can remove any trap
+ // Players can only remove their own traps or traps on Vs maps.
+ if( su && (sg = su->group) && (src->type == BL_MER || sg->src_id == src->id || map_flag_vs(bl->m)) && (skill_get_inf2(sg->skill_id)&INF2_TRAP) )
+ {
+ clif_skill_nodamage(src, bl, skillid, skilllv, 1);
+ if( sd && !(sg->unit_id == UNT_USED_TRAPS || (sg->unit_id == UNT_ANKLESNARE && sg->val2 != 0 )) )
+ { // prevent picking up expired traps
+ if( battle_config.skill_removetrap_type )
+ { // get back all items used to deploy the trap
+ for( i = 0; i < 10; i++ )
+ {
+ if( skill_db[su->group->skill_id].itemid[i] > 0 )
+ {
+ int flag;
+ struct item item_tmp;
+ 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],LOG_TYPE_OTHER)) )
+ {
+ 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,0,0,0,0);
+ }
+ }
+ }
+ }
+ else
+ { // get back 1 trap
+ struct item item_tmp;
+ memset(&item_tmp,0,sizeof(item_tmp));
+ item_tmp.nameid = su->group->item_id?su->group->item_id:ITEMID_TRAP;
+ item_tmp.identify = 1;
+ if( item_tmp.nameid && (flag=pc_additem(sd,&item_tmp,1,LOG_TYPE_OTHER)) )
+ {
+ clif_additem(sd,0,0,flag);
+ map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ }
+ }
+ }
+ skill_delunit(su);
+ }else if(sd)
+ clif_skill_fail(sd, skillid, USESKILL_FAIL_LEVEL, 0);
+
+ }
+ break;
+ case HT_SPRINGTRAP:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ {
+ struct skill_unit *su=NULL;
+ if((bl->type==BL_SKILL) && (su=(struct skill_unit *)bl) && (su->group) ){
+ switch(su->group->unit_id){
+ case UNT_ANKLESNARE: // 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 UNT_BLASTMINE:
+ case UNT_SKIDTRAP:
+ case UNT_LANDMINE:
+ case UNT_SHOCKWAVE:
+ case UNT_SANDMAN:
+ case UNT_FLASHER:
+ case UNT_FREEZINGTRAP:
+ case UNT_CLAYMORETRAP:
+ case UNT_TALKIEBOX:
+ su->group->unit_id = UNT_USED_TRAPS;
+ clif_changetraplook(bl, UNT_USED_TRAPS);
+ su->group->limit=DIFF_TICK(tick+1500,su->group->tick);
+ su->limit=DIFF_TICK(tick+1500,su->group->tick);
+ }
+ }
+ }
+ break;
+ case BD_ENCORE:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ if(sd)
+ unit_skilluse_id(src,src->id,sd->skillid_dance,sd->skilllv_dance);
+ break;
+
+ case AS_SPLASHER:
+ if(tstatus->mode&MD_BOSS
+ /**
+ * Renewal dropped the 3/4 hp requirement
+ **/
+ #ifndef RENEWAL
+ || tstatus-> hp > tstatus->max_hp*3/4
+ #endif
+ ) {
+ if (sd) clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ map_freeblock_unlock();
+ return 1;
+ }
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start4(bl,type,100,skilllv,skillid,src->id,skill_get_time(skillid,skilllv),1000));
+ if (sd) skill_blockpc_start (sd, skillid, skill_get_time(skillid, skilllv)+3000);
+ break;
+
+ case PF_MINDBREAKER:
+ {
+ if(tstatus->mode&MD_BOSS || battle_check_undead(tstatus->race,tstatus->def_ele))
+ {
+ map_freeblock_unlock();
+ return 1;
+ }
- case GC_HALLUCINATIONWALK: {
- int heal = status_get_max_hp(bl) / 10;
- if (status_get_hp(bl) < heal) { // if you haven't enough HP skill fails.
- if (sd) clif_skill_fail(sd,skillid,USESKILL_FAIL_HP_INSUFFICIENT,0);
- break;
- }
- if (!status_charge(bl,heal,0)) {
- if (sd) clif_skill_fail(sd,skillid,USESKILL_FAIL_HP_INSUFFICIENT,0);
- break;
- }
- clif_skill_nodamage(src,bl,skillid,skilllv,sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
- }
- break;
- /**
- * Arch Bishop
- **/
- case AB_ANCILLA:
- if (sd) {
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- skill_produce_mix(sd, skillid, ITEMID_ANCILLA, 0, 0, 0, 1);
- }
- break;
+ if (tsce)
+ { //HelloKitty2 (?) explained that this silently fails when target is
+ //already inflicted. [Skotlex]
+ map_freeblock_unlock();
+ return 1;
+ }
- case AB_CLEMENTIA:
- case AB_CANTO: {
- int bless_lv = pc_checkskill(sd,AL_BLESSING);
- int agi_lv = pc_checkskill(sd,AL_INCAGI);
- if (sd == NULL || sd->status.party_id == 0 || flag&1)
- clif_skill_nodamage(bl, bl, skillid, skilllv, sc_start(bl,type,100,
- (skillid == AB_CLEMENTIA)? bless_lv : (skillid == AB_CANTO)? agi_lv : skilllv, skill_get_time(skillid,skilllv)));
- else if (sd)
- party_foreachsamemap(skill_area_sub, sd, skill_get_splash(skillid, skilllv), src, skillid, skilllv, tick, flag|BCT_PARTY|1, skill_castend_nodamage_id);
- }
- break;
+ //Has a 55% + skilllv*5% success chance.
+ if (!clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start(bl,type,55+5*skilllv,skilllv,skill_get_time(skillid,skilllv))))
+ {
+ if (sd) clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ map_freeblock_unlock();
+ return 0;
+ }
- case AB_PRAEFATIO:
- if (sd == NULL || sd->status.party_id == 0 || flag&1)
- clif_skill_nodamage(bl, bl, skillid, skilllv, sc_start4(bl, type, 100, skilllv, 0, 0, 1, skill_get_time(skillid, skilllv)));
- else if (sd)
- party_foreachsamemap(skill_area_sub, sd, skill_get_splash(skillid, skilllv), src, skillid, skilllv, tick, flag|BCT_PARTY|1, skill_castend_nodamage_id);
- break;
+ unit_skillcastcancel(bl,0);
- case AB_CHEAL:
- if (sd == NULL || sd->status.party_id == 0 || flag&1) {
- if (sd && tstatus && !battle_check_undead(tstatus->race, tstatus->def_ele)) {
- i = skill_calc_heal(src, bl, AL_HEAL, pc_checkskill(sd, AL_HEAL), true);
+ if(tsc && tsc->count){
+ status_change_end(bl, SC_FREEZE, INVALID_TIMER);
+ if(tsc->data[SC_STONE] && tsc->opt1 == OPT1_STONE)
+ status_change_end(bl, SC_STONE, INVALID_TIMER);
+ status_change_end(bl, SC_SLEEP, INVALID_TIMER);
+ }
- if ((dstsd && pc_ismadogear(dstsd)) || status_isimmune(bl))
- i = 0; // Should heal by 0 or won't do anything?? in iRO it breaks the healing to members.. [malufett]
+ if(dstmd)
+ mob_target(dstmd,src,skill_get_range2(src,skillid,skilllv));
+ }
+ break;
+
+ case PF_SOULCHANGE:
+ {
+ unsigned int sp1 = 0, sp2 = 0;
+ if (dstmd) {
+ if (dstmd->state.soul_change_flag) {
+ if(sd) clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+ dstmd->state.soul_change_flag = 1;
+ sp2 = sstatus->max_sp * 3 /100;
+ status_heal(src, 0, sp2, 2);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ break;
+ }
+ sp1 = sstatus->sp;
+ sp2 = tstatus->sp;
+ #ifdef RENEWAL
+ sp1 = sp1 / 2;
+ sp2 = sp2 / 2;
+ if( tsc && tsc->data[SC_EXTREMITYFIST2] )
+ sp1 = tstatus->sp;
+ #endif
+ status_set_sp(src, sp2, 3);
+ status_set_sp(bl, sp1, 3);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ }
+ break;
+
+ // Slim Pitcher
+ case CR_SLIMPITCHER:
+ // Updated to block Slim Pitcher from working on barricades and guardian stones.
+ if( dstmd && (dstmd->class_ == MOBID_EMPERIUM || (dstmd->class_ >= MOBID_BARRICADE1 && dstmd->class_ <= MOBID_GUARIDAN_STONE2)) )
+ break;
+ if (potion_hp || potion_sp) {
+ int hp = potion_hp, sp = potion_sp;
+ hp = hp * (100 + (tstatus->vit<<1))/100;
+ sp = sp * (100 + (tstatus->int_<<1))/100;
+ if (dstsd) {
+ if (hp)
+ hp = hp * (100 + pc_checkskill(dstsd,SM_RECOVERY)*10 + pc_skillheal2_bonus(dstsd, skillid))/100;
+ if (sp)
+ sp = sp * (100 + pc_checkskill(dstsd,MG_SRECOVERY)*10 + pc_skillheal2_bonus(dstsd, skillid))/100;
+ }
+ if( tsc && tsc->count ) {
+ if (tsc->data[SC_CRITICALWOUND]) {
+ hp -= hp * tsc->data[SC_CRITICALWOUND]->val2 / 100;
+ sp -= sp * tsc->data[SC_CRITICALWOUND]->val2 / 100;
+ }
+ if (tsc->data[SC_DEATHHURT]) {
+ hp -= hp * 20 / 100;
+ sp -= sp * 20 / 100;
+ }
+ if( tsc->data[SC_WATER_INSIGNIA] && tsc->data[SC_WATER_INSIGNIA]->val1 == 2) {
+ hp += hp / 10;
+ sp += sp / 10;
+ }
+ }
+ if(hp > 0)
+ clif_skill_nodamage(NULL,bl,AL_HEAL,hp,1);
+ if(sp > 0)
+ clif_skill_nodamage(NULL,bl,MG_SRECOVERY,sp,1);
+ status_heal(bl,hp,sp,0);
+ }
+ break;
+ // Full Chemical Protection
+ case CR_FULLPROTECTION:
+ {
+ unsigned int equip[] = {EQP_WEAPON, EQP_SHIELD, EQP_ARMOR, EQP_HEAD_TOP};
+ int i, s = 0, skilltime = skill_get_time(skillid,skilllv);
+
+ for (i=0 ; i<4; i++) {
+ if( bl->type != BL_PC || ( dstsd && pc_checkequip(dstsd,equip[i]) < 0 ) )
+ continue;
+ sc_start(bl,(sc_type)(SC_CP_WEAPON + i),100,skilllv,skilltime);
+ s++;
+ }
+ if( sd && !s ){
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ map_freeblock_unlock(); // Don't consume item requirements
+ return 0;
+ }
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ }
+ break;
+
+ case RG_CLEANER: //AppleGirl
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ break;
+
+ case CG_LONGINGFREEDOM:
+ {
+ if (tsc && !tsce && (tsce=tsc->data[SC_DANCING]) && tsce->val4
+ && (tsce->val1&0xFFFF) != CG_MOONLIT) //Can't use Longing for Freedom while under Moonlight Petals. [Skotlex]
+ {
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
+ }
+ }
+ break;
- clif_skill_nodamage(bl, bl, skillid, i, 1);
- if (tsc && tsc->data[SC_AKAITSUKI] && i)
- i = ~i + 1;
- status_heal(bl, i, 0, 0);
- }
- } else if (sd)
- party_foreachsamemap(skill_area_sub, sd, skill_get_splash(skillid, skilllv), src, skillid, skilllv, tick, flag|BCT_PARTY|1, skill_castend_nodamage_id);
- break;
+ case CG_TAROTCARD:
+ {
+ int eff, count = -1;
+ if( rnd() % 100 > skilllv * 8 || (dstmd && ((dstmd->guardian_data && dstmd->class_ == MOBID_EMPERIUM) || mob_is_battleground(dstmd))) )
+ {
+ if( sd )
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- case AB_ORATIO:
- if (flag&1)
- sc_start(bl, type, 40 + 5 * skilllv, skilllv, skill_get_time(skillid, skilllv));
- else {
- map_foreachinrange(skill_area_sub, src, skill_get_splash(skillid, skilllv), BL_CHAR,
- src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_nodamage_id);
- clif_skill_nodamage(src, bl, skillid, skilllv, 1);
- }
- break;
+ map_freeblock_unlock();
+ return 0;
+ }
+ status_zap(src,0,skill_db[skill_get_index(skillid)].sp[skilllv]); // consume sp only if succeeded [Inkfish]
+ do {
+ eff = rnd() % 14;
+ clif_specialeffect(bl, 523 + eff, AREA);
+ switch (eff)
+ {
+ case 0: // heals SP to 0
+ status_percent_damage(src, bl, 0, 100, false);
+ break;
+ case 1: // matk halved
+ sc_start(bl,SC_INCMATKRATE,100,-50,skill_get_time2(skillid,skilllv));
+ break;
+ case 2: // all buffs removed
+ status_change_clear_buffs(bl,1);
+ break;
+ case 3: // 1000 damage, random armor destroyed
+ {
+ int where[] = { EQP_ARMOR, EQP_SHIELD, EQP_HELM, EQP_SHOES, EQP_GARMENT };
+ status_fix_damage(src, bl, 1000, 0);
+ clif_damage(src,bl,tick,0,0,1000,0,0,0);
+ if( !status_isdead(bl) )
+ skill_break_equip(bl, where[rnd()%5], 10000, BCT_ENEMY);
+ }
+ break;
+ case 4: // atk halved
+ sc_start(bl,SC_INCATKRATE,100,-50,skill_get_time2(skillid,skilllv));
+ break;
+ case 5: // 2000HP heal, random teleported
+ status_heal(src, 2000, 0, 0);
+ if( !map_flag_vs(bl->m) )
+ unit_warp(bl, -1,-1,-1, CLR_TELEPORT);
+ break;
+ case 6: // random 2 other effects
+ if (count == -1)
+ count = 3;
+ else
+ count++; //Should not retrigger this one.
+ break;
+ case 7: // stop freeze or stoned
+ {
+ enum sc_type sc[] = { SC_STOP, SC_FREEZE, SC_STONE };
+ sc_start(bl,sc[rnd()%3],100,skilllv,skill_get_time2(skillid,skilllv));
+ }
+ break;
+ case 8: // curse coma and poison
+ sc_start(bl,SC_COMA,100,skilllv,skill_get_time2(skillid,skilllv));
+ sc_start(bl,SC_CURSE,100,skilllv,skill_get_time2(skillid,skilllv));
+ sc_start(bl,SC_POISON,100,skilllv,skill_get_time2(skillid,skilllv));
+ break;
+ case 9: // confusion
+ sc_start(bl,SC_CONFUSION,100,skilllv,skill_get_time2(skillid,skilllv));
+ break;
+ case 10: // 6666 damage, atk matk halved, cursed
+ status_fix_damage(src, bl, 6666, 0);
+ clif_damage(src,bl,tick,0,0,6666,0,0,0);
+ sc_start(bl,SC_INCATKRATE,100,-50,skill_get_time2(skillid,skilllv));
+ sc_start(bl,SC_INCMATKRATE,100,-50,skill_get_time2(skillid,skilllv));
+ sc_start(bl,SC_CURSE,skilllv,100,skill_get_time2(skillid,skilllv));
+ break;
+ case 11: // 4444 damage
+ status_fix_damage(src, bl, 4444, 0);
+ clif_damage(src,bl,tick,0,0,4444,0,0,0);
+ break;
+ case 12: // stun
+ sc_start(bl,SC_STUN,100,skilllv,5000);
+ break;
+ case 13: // atk,matk,hit,flee,def reduced
+ sc_start(bl,SC_INCATKRATE,100,-20,skill_get_time2(skillid,skilllv));
+ sc_start(bl,SC_INCMATKRATE,100,-20,skill_get_time2(skillid,skilllv));
+ sc_start(bl,SC_INCHITRATE,100,-20,skill_get_time2(skillid,skilllv));
+ sc_start(bl,SC_INCFLEERATE,100,-20,skill_get_time2(skillid,skilllv));
+ sc_start(bl,SC_INCDEFRATE,100,-20,skill_get_time2(skillid,skilllv));
+ break;
+ default:
+ break;
+ }
+ } while ((--count) > 0);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ }
+ break;
+
+ case SL_ALCHEMIST:
+ case SL_ASSASIN:
+ case SL_BARDDANCER:
+ case SL_BLACKSMITH:
+ case SL_CRUSADER:
+ case SL_HUNTER:
+ case SL_KNIGHT:
+ case SL_MONK:
+ case SL_PRIEST:
+ case SL_ROGUE:
+ case SL_SAGE:
+ case SL_SOULLINKER:
+ case SL_STAR:
+ case SL_SUPERNOVICE:
+ case SL_WIZARD:
+ //NOTE: here, 'type' has the value of the associated MAPID, not of the SC_SPIRIT constant.
+ if (sd && !(dstsd && (dstsd->class_&MAPID_UPPERMASK) == type)) {
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+ if (skillid == SL_SUPERNOVICE && dstsd && dstsd->die_counter && !(rnd()%100))
+ { //Erase death count 1% of the casts
+ dstsd->die_counter = 0;
+ pc_setglobalreg(dstsd,"PC_DIE_COUNTER", 0);
+ clif_specialeffect(bl, 0x152, AREA);
+ //SC_SPIRIT invokes status_calc_pc for us.
+ }
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start4(bl,SC_SPIRIT,100,skilllv,skillid,0,0,skill_get_time(skillid,skilllv)));
+ sc_start(src,SC_SMA,100,skilllv,skill_get_time(SL_SMA,skilllv));
+ break;
+ case SL_HIGH:
+ if (sd && !(dstsd && (dstsd->class_&JOBL_UPPER) && !(dstsd->class_&JOBL_2) && dstsd->status.base_level < 70)) {
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start4(bl,type,100,skilllv,skillid,0,0,skill_get_time(skillid,skilllv)));
+ sc_start(src,SC_SMA,100,skilllv,skill_get_time(SL_SMA,skilllv));
+ break;
+
+ case SL_SWOO:
+ if (tsce) {
+ sc_start(src,SC_STUN,100,skilllv,10000);
+ break;
+ }
+ case SL_SKA: // [marquis007]
+ case SL_SKE:
+ if (sd && !battle_config.allow_es_magic_pc && bl->type != BL_MOB) {
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ status_change_start(src,SC_STUN,10000,skilllv,0,0,0,500,10);
+ break;
+ }
+ clif_skill_nodamage(src,bl,skillid,skilllv,sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
+ if (skillid == SL_SKE)
+ sc_start(src,SC_SMA,100,skilllv,skill_get_time(SL_SMA,skilllv));
+ break;
+
+ // New guild skills [Celest]
+ case GD_BATTLEORDER:
+ if(flag&1) {
+ if (status_get_guild_id(src) == status_get_guild_id(bl))
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid, skilllv));
+ } else if (status_get_guild_id(src)) {
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ map_foreachinrange(skill_area_sub, src,
+ skill_get_splash(skillid, skilllv), BL_PC,
+ src,skillid,skilllv,tick, flag|BCT_GUILD|1,
+ skill_castend_nodamage_id);
+ if (sd)
+ guild_block_skill(sd,skill_get_time2(skillid,skilllv));
+ }
+ break;
+ case GD_REGENERATION:
+ if(flag&1) {
+ if (status_get_guild_id(src) == status_get_guild_id(bl))
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid, skilllv));
+ } else if (status_get_guild_id(src)) {
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ map_foreachinrange(skill_area_sub, src,
+ skill_get_splash(skillid, skilllv), BL_PC,
+ src,skillid,skilllv,tick, flag|BCT_GUILD|1,
+ skill_castend_nodamage_id);
+ if (sd)
+ guild_block_skill(sd,skill_get_time2(skillid,skilllv));
+ }
+ break;
+ case GD_RESTORE:
+ if(flag&1) {
+ if (status_get_guild_id(src) == status_get_guild_id(bl))
+ clif_skill_nodamage(src,bl,AL_HEAL,status_percent_heal(bl,90,90),1);
+ } else if (status_get_guild_id(src)) {
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ map_foreachinrange(skill_area_sub, src,
+ skill_get_splash(skillid, skilllv), BL_PC,
+ src,skillid,skilllv,tick, flag|BCT_GUILD|1,
+ skill_castend_nodamage_id);
+ if (sd)
+ guild_block_skill(sd,skill_get_time2(skillid,skilllv));
+ }
+ break;
+ case GD_EMERGENCYCALL:
+ {
+ 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 j = 0;
+ struct guild *g = NULL;
+ // i don't know if it actually summons in a circle, but oh well. ;P
+ g = sd?sd->state.gmaster_flag:guild_search(status_get_guild_id(src));
+ if (!g)
+ break;
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ for(i = 0; i < g->max_member; i++, j++) {
+ if (j>8) j=0;
+ if ((dstsd = g->member[i].sd) != NULL && sd != dstsd && !dstsd->state.autotrade && !pc_isdead(dstsd)) {
+ if (map[dstsd->bl.m].flag.nowarp && !map_flag_gvg2(dstsd->bl.m))
+ continue;
+ if(map_getcell(src->m,src->x+dx[j],src->y+dy[j],CELL_CHKNOREACH))
+ dx[j] = dy[j] = 0;
+ pc_setpos(dstsd, map_id2index(src->m), src->x+dx[j], src->y+dy[j], CLR_RESPAWN);
+ }
+ }
+ if (sd)
+ guild_block_skill(sd,skill_get_time2(skillid,skilllv));
+ }
+ break;
+
+ case SG_FEEL:
+ //AuronX reported you CAN memorize the same map as all three. [Skotlex]
+ if (sd) {
+ if(!sd->feel_map[skilllv-1].index)
+ clif_feel_req(sd->fd,sd, skilllv);
+ else
+ clif_feel_info(sd, skilllv-1, 1);
+ }
+ break;
+
+ case SG_HATE:
+ if (sd) {
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ if (!pc_set_hate_mob(sd, skilllv-1, bl))
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ }
+ break;
+
+ case GS_GLITTERING:
+ if(sd) {
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ if(rnd()%100 < (20+10*skilllv))
+ pc_addspiritball(sd,skill_get_time(skillid,skilllv),10);
+ else if(sd->spiritball > 0)
+ pc_delspiritball(sd,1,0);
+ }
+ break;
+
+ case GS_CRACKER:
+ /* per official standards, this skill works on players and mobs. */
+ if (sd && (dstsd || dstmd))
+ {
+ i =65 -5*distance_bl(src,bl); //Base rate
+ if (i < 30) i = 30;
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ sc_start(bl,SC_STUN, i,skilllv,skill_get_time2(skillid,skilllv));
+ }
+ break;
+
+ case AM_CALLHOMUN: //[orn]
+ if (sd && !merc_call_homunculus(sd))
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+
+ case AM_REST:
+ if (sd) {
+ if (merc_hom_vaporize(sd,1))
+ clif_skill_nodamage(src, bl, skillid, skilllv, 1);
+ else
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ }
+ break;
+
+ case HAMI_CASTLE: //[orn]
+ if(rnd()%100 < 20*skilllv && src != bl)
+ {
+ int x,y;
+ x = src->x;
+ y = src->y;
+ if (hd)
+ skill_blockhomun_start(hd, skillid, skill_get_time2(skillid,skilllv));
+
+ if (unit_movepos(src,bl->x,bl->y,0,0)) {
+ clif_skill_nodamage(src,src,skillid,skilllv,1); // Homunc
+ clif_slide(src,bl->x,bl->y) ;
+ if (unit_movepos(bl,x,y,0,0))
+ {
+ clif_skill_nodamage(bl,bl,skillid,skilllv,1); // Master
+ clif_slide(bl,x,y) ;
+ }
- case AB_LAUDAAGNUS:
- if (flag&1 || sd == NULL) {
- if (tsc && (tsc->data[SC_FREEZE] || tsc->data[SC_STONE] || tsc->data[SC_BLIND] ||
- tsc->data[SC_BURNING] || tsc->data[SC_FREEZING] || tsc->data[SC_CRYSTALIZE])) {
- // Success Chance: (40 + 10 * Skill Level) %
- if (rnd()%100 > 40+10*skilllv) break;
- status_change_end(bl, SC_FREEZE, INVALID_TIMER);
- status_change_end(bl, SC_STONE, INVALID_TIMER);
- status_change_end(bl, SC_BLIND, INVALID_TIMER);
- status_change_end(bl, SC_BURNING, INVALID_TIMER);
- status_change_end(bl, SC_FREEZING, INVALID_TIMER);
- status_change_end(bl, SC_CRYSTALIZE, INVALID_TIMER);
- } else //Success rate only applies to the curing effect and not stat bonus. Bonus status only applies to non infected targets
- clif_skill_nodamage(bl, bl, skillid, skilllv,
- sc_start(bl, type, 100, skilllv, skill_get_time(skillid, skilllv)));
- } else if (sd)
- party_foreachsamemap(skill_area_sub, sd, skill_get_splash(skillid, skilllv),
- src, skillid, skilllv, tick, flag|BCT_PARTY|1, skill_castend_nodamage_id);
- break;
+ //TODO: Shouldn't also players and the like switch targets?
+ map_foreachinrange(skill_chastle_mob_changetarget,src,
+ AREA_SIZE, BL_MOB, bl, src);
+ }
+ }
+ // Failed
+ else if (hd && hd->master)
+ clif_skill_fail(hd->master, skillid, USESKILL_FAIL_LEVEL, 0);
+ else if (sd)
+ clif_skill_fail(sd, skillid, USESKILL_FAIL_LEVEL, 0);
+ break;
+ case HVAN_CHAOTIC: //[orn]
+ {
+ static const int per[5][2]={{20,50},{50,60},{25,75},{60,64},{34,67}};
+ int r = rnd()%100;
+ i = (skilllv-1)%5;
+ if(r<per[i][0]) //Self
+ bl = src;
+ else if(r<per[i][1]) //Master
+ bl = battle_get_master(src);
+ else //Enemy
+ bl = map_id2bl(battle_gettarget(src));
+
+ if (!bl) bl = src;
+ i = skill_calc_heal(src, bl, skillid, 1+rnd()%skilllv, true);
+ //Eh? why double skill packet?
+ clif_skill_nodamage(src,bl,AL_HEAL,i,1);
+ clif_skill_nodamage(src,bl,skillid,i,1);
+ status_heal(bl, i, 0, 0);
+ }
+ break;
+ //Homun single-target support skills [orn]
+ case HAMI_BLOODLUST:
+ case HFLI_FLEET:
+ case HFLI_SPEED:
+ case HLIF_CHANGE:
+ case MH_ANGRIFFS_MODUS:
+ case MH_GOLDENE_FERSE:
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
+ if (hd)
+ skill_blockhomun_start(hd, skillid, skill_get_time2(skillid,skilllv));
+ break;
+
+ case NPC_DRAGONFEAR:
+ if (flag&1) {
+ const enum sc_type sc[] = { SC_STUN, SC_SILENCE, SC_CONFUSION, SC_BLEEDING };
+ int j;
+ j = i = rnd()%ARRAYLENGTH(sc);
+ while ( !sc_start(bl,sc[i],100,skilllv,skill_get_time2(skillid,i+1)) ) {
+ i++;
+ if ( i == ARRAYLENGTH(sc) )
+ i = 0;
+ if (i == j)
+ break;
+ }
+ break;
+ }
+ case NPC_WIDEBLEEDING:
+ case NPC_WIDECONFUSE:
+ case NPC_WIDECURSE:
+ case NPC_WIDEFREEZE:
+ case NPC_WIDESLEEP:
+ case NPC_WIDESILENCE:
+ case NPC_WIDESTONE:
+ case NPC_WIDESTUN:
+ case NPC_SLOWCAST:
+ case NPC_WIDEHELLDIGNITY:
+ if (flag&1)
+ sc_start(bl,type,100,skilllv,skill_get_time2(skillid,skilllv));
+ else {
+ skill_area_temp[2] = 0; //For SD_PREAMBLE
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ map_foreachinrange(skill_area_sub, bl,
+ skill_get_splash(skillid, skilllv),BL_CHAR,
+ src,skillid,skilllv,tick, flag|BCT_ENEMY|SD_PREAMBLE|1,
+ skill_castend_nodamage_id);
+ }
+ break;
+ case NPC_WIDESOULDRAIN:
+ if (flag&1)
+ status_percent_damage(src,bl,0,((skilllv-1)%5+1)*20,false);
+ else {
+ skill_area_temp[2] = 0; //For SD_PREAMBLE
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ map_foreachinrange(skill_area_sub, bl,
+ skill_get_splash(skillid, skilllv),BL_CHAR,
+ src,skillid,skilllv,tick, flag|BCT_ENEMY|SD_PREAMBLE|1,
+ skill_castend_nodamage_id);
+ }
+ break;
+ case ALL_PARTYFLEE:
+ if( sd && !(flag&1) )
+ {
+ if( !sd->status.party_id )
+ {
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+ party_foreachsamemap(skill_area_sub, sd, skill_get_splash(skillid, skilllv), src, skillid, skilllv, tick, flag|BCT_PARTY|1, skill_castend_nodamage_id);
+ }
+ else
+ clif_skill_nodamage(src,bl,skillid,skilllv,sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
+ break;
+ case NPC_TALK:
+ case ALL_WEWISH:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ break;
+ case ALL_BUYING_STORE:
+ if( sd )
+ {// players only, skill allows 5 buying slots
+ clif_skill_nodamage(src, bl, skillid, skilllv, buyingstore_setup(sd, MAX_BUYINGSTORE_SLOTS));
+ }
+ break;
+ case RK_ENCHANTBLADE:
+ clif_skill_nodamage(src,bl,skillid,skilllv,// formula not confirmed
+ sc_start2(bl,type,100,skilllv,100+20*skilllv/*+sstatus->int_/2+status_get_lv(bl)/10*/,skill_get_time(skillid,skilllv)));
+ break;
+ case RK_DRAGONHOWLING:
+ if( flag&1)
+ sc_start(bl,type,50 + 6 * skilllv,skilllv,skill_get_time(skillid,skilllv));
+ else
+ {
+ skill_area_temp[2] = 0;
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ map_foreachinrange(skill_area_sub, src,
+ skill_get_splash(skillid,skilllv),BL_CHAR,
+ src,skillid,skilllv,tick,flag|BCT_ENEMY|SD_PREAMBLE|1,
+ skill_castend_nodamage_id);
+ }
+ break;
+ case RK_IGNITIONBREAK:
+ case LG_EARTHDRIVE:
+ clif_skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+ i = skill_get_splash(skillid,skilllv);
+ if( skillid == LG_EARTHDRIVE ) {
+ int dummy = 1;
+ map_foreachinarea(skill_cell_overlap, src->m, src->x-i, src->y-i, src->x+i, src->y+i, BL_SKILL, LG_EARTHDRIVE, &dummy, src);
+ }
+ map_foreachinrange(skill_area_sub, bl,i,BL_CHAR,
+ src,skillid,skilllv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
+ break;
+ case RK_STONEHARDSKIN:
+ if( sd && pc_checkskill(sd,RK_RUNEMASTERY) >= 4 )
+ {
+ int heal = sstatus->hp / 4; // 25% HP
+ if( status_charge(bl,heal,0) )
+ clif_skill_nodamage(src,bl,skillid,skilllv,sc_start2(bl,type,100,skilllv,heal,skill_get_time(skillid,skilllv)));
+ else
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ }
+ break;
+ case RK_REFRESH:
+ if( sd && pc_checkskill(sd,RK_RUNEMASTERY) >= 8 )
+ {
+ int heal = status_get_max_hp(bl) * 25 / 100;
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
+ status_heal(bl,heal,0,1);
+ status_change_clear_buffs(bl,2);
+ }
+ break;
+
+ case RK_MILLENNIUMSHIELD:
+ if( sd && pc_checkskill(sd,RK_RUNEMASTERY) >= 9 )
+ {
+ short shields = (rnd()%100<50) ? 4 : ((rnd()%100<80) ? 3 : 2);
+ sc_start4(bl,type,100,skilllv,shields,1000,0,skill_get_time(skillid,skilllv));
+ clif_millenniumshield(sd,shields);
+ clif_skill_nodamage(src,bl,skillid,1,1);
+ }
+ break;
+
+ case RK_GIANTGROWTH:
+ case RK_VITALITYACTIVATION:
+ case RK_ABUNDANCE:
+ if( sd )
+ {
+ int lv = 1; // RK_GIANTGROWTH
+ if( skillid == RK_VITALITYACTIVATION )
+ lv = 2;
+ else if( skillid == RK_ABUNDANCE )
+ lv = 6;
+ if( pc_checkskill(sd,RK_RUNEMASTERY) >= lv )
+ clif_skill_nodamage(src,bl,skillid,skilllv,sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
+ }
+ break;
+
+ case RK_FIGHTINGSPIRIT:
+ if( flag&1 ) {
+ if( src == bl )
+ sc_start2(bl,type,100,skill_area_temp[5],10*(sd?pc_checkskill(sd,RK_RUNEMASTERY):10),skill_get_time(skillid,skilllv));
+ else
+ sc_start(bl,type,100,skill_area_temp[5]/4,skill_get_time(skillid,skilllv));
+ } else if( sd && pc_checkskill(sd,RK_RUNEMASTERY) >= 5 ) {
+ if( sd->status.party_id ) {
+ i = party_foreachsamemap(skill_area_sub,sd,skill_get_splash(skillid,skilllv),src,skillid,skilllv,tick,BCT_PARTY,skill_area_sub_count);
+ skill_area_temp[5] = 7 * i; // ATK
+ party_foreachsamemap(skill_area_sub,sd,skill_get_splash(skillid,skilllv),src,skillid,skilllv,tick,flag|BCT_PARTY|1,skill_castend_nodamage_id);
+ } else
+ sc_start2(bl,type,100,7,5,skill_get_time(skillid,skilllv));
+ }
+ clif_skill_nodamage(src,bl,skillid,1,1);
+ break;
+ /**
+ * Guilotine Cross
+ **/
+ case GC_ROLLINGCUTTER:
+ {
+ short count = 1;
+ skill_area_temp[2] = 0;
+ map_foreachinrange(skill_area_sub,src,skill_get_splash(skillid,skilllv),BL_CHAR,src,skillid,skilllv,tick,flag|BCT_ENEMY|SD_PREAMBLE|SD_SPLASH|1,skill_castend_damage_id);
+ if( tsc && tsc->data[SC_ROLLINGCUTTER] )
+ { // Every time the skill is casted the status change is reseted adding a counter.
+ count += (short)tsc->data[SC_ROLLINGCUTTER]->val1;
+ if( count > 10 )
+ count = 10; // Max coounter
+ status_change_end(bl, SC_ROLLINGCUTTER, INVALID_TIMER);
+ }
+ sc_start(bl,SC_ROLLINGCUTTER,100,count,skill_get_time(skillid,skilllv));
+ clif_skill_nodamage(src,src,skillid,skilllv,1);
+ }
+ break;
+
+ case GC_WEAPONBLOCKING:
+ if( tsc && tsc->data[SC_WEAPONBLOCKING] )
+ status_change_end(bl, SC_WEAPONBLOCKING, INVALID_TIMER);
+ else
+ sc_start(bl,SC_WEAPONBLOCKING,100,skilllv,skill_get_time(skillid,skilllv));
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ break;
+
+ case GC_CREATENEWPOISON:
+ if( sd )
+ {
+ clif_skill_produce_mix_list(sd,skillid,25);
+ clif_skill_nodamage(src, bl, skillid, skilllv, 1);
+ }
+ break;
+
+ case GC_POISONINGWEAPON:
+ if( sd ) {
+ clif_poison_list(sd,skilllv);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ }
+ break;
+
+ case GC_ANTIDOTE:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ if( tsc )
+ {
+ status_change_end(bl, SC_PARALYSE, INVALID_TIMER);
+ status_change_end(bl, SC_PYREXIA, INVALID_TIMER);
+ status_change_end(bl, SC_DEATHHURT, INVALID_TIMER);
+ status_change_end(bl, SC_LEECHESEND, INVALID_TIMER);
+ status_change_end(bl, SC_VENOMBLEED, INVALID_TIMER);
+ status_change_end(bl, SC_MAGICMUSHROOM, INVALID_TIMER);
+ status_change_end(bl, SC_TOXIN, INVALID_TIMER);
+ status_change_end(bl, SC_OBLIVIONCURSE, INVALID_TIMER);
+ }
+ break;
+
+ case GC_PHANTOMMENACE:
+ clif_skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ map_foreachinrange(skill_area_sub,src,skill_get_splash(skillid,skilllv),BL_CHAR,
+ src,skillid,skilllv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
+ break;
+
+ case GC_HALLUCINATIONWALK:
+ {
+ int heal = status_get_max_hp(bl) / 10;
+ if( status_get_hp(bl) < heal ) { // if you haven't enough HP skill fails.
+ if( sd ) clif_skill_fail(sd,skillid,USESKILL_FAIL_HP_INSUFFICIENT,0);
+ break;
+ }
+ if( !status_charge(bl,heal,0) )
+ {
+ if( sd ) clif_skill_fail(sd,skillid,USESKILL_FAIL_HP_INSUFFICIENT,0);
+ break;
+ }
+ clif_skill_nodamage(src,bl,skillid,skilllv,sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
+ }
+ break;
+ /**
+ * Arch Bishop
+ **/
+ case AB_ANCILLA:
+ if( sd ) {
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ skill_produce_mix(sd, skillid, ITEMID_ANCILLA, 0, 0, 0, 1);
+ }
+ break;
+
+ case AB_CLEMENTIA:
+ case AB_CANTO:
+ {
+ int bless_lv = pc_checkskill(sd,AL_BLESSING);
+ int agi_lv = pc_checkskill(sd,AL_INCAGI);
+ if( sd == NULL || sd->status.party_id == 0 || flag&1 )
+ clif_skill_nodamage(bl, bl, skillid, skilllv, sc_start(bl,type,100,
+ (skillid == AB_CLEMENTIA)? bless_lv : (skillid == AB_CANTO)? agi_lv : skilllv, skill_get_time(skillid,skilllv)));
+ else if( sd )
+ party_foreachsamemap(skill_area_sub, sd, skill_get_splash(skillid, skilllv), src, skillid, skilllv, tick, flag|BCT_PARTY|1, skill_castend_nodamage_id);
+ }
+ break;
+
+ case AB_PRAEFATIO:
+ if( sd == NULL || sd->status.party_id == 0 || flag&1 )
+ clif_skill_nodamage(bl, bl, skillid, skilllv, sc_start4(bl, type, 100, skilllv, 0, 0, 1, skill_get_time(skillid, skilllv)));
+ else if( sd )
+ party_foreachsamemap(skill_area_sub, sd, skill_get_splash(skillid, skilllv), src, skillid, skilllv, tick, flag|BCT_PARTY|1, skill_castend_nodamage_id);
+ break;
+
+ case AB_CHEAL:
+ if( sd == NULL || sd->status.party_id == 0 || flag&1 )
+ {
+ if( sd && tstatus && !battle_check_undead(tstatus->race, tstatus->def_ele) )
+ {
+ i = skill_calc_heal(src, bl, AL_HEAL, pc_checkskill(sd, AL_HEAL), true);
- case AB_LAUDARAMUS:
- if (flag&1 || sd == NULL) {
- if (tsc && (tsc->data[SC_SLEEP] || tsc->data[SC_STUN] || tsc->data[SC_MANDRAGORA] || tsc->data[SC_SILENCE])) {
- // Success Chance: (40 + 10 * Skill Level) %
- if (rnd()%100 > 40+10*skilllv) break;
- status_change_end(bl, SC_SLEEP, INVALID_TIMER);
- status_change_end(bl, SC_STUN, INVALID_TIMER);
- status_change_end(bl, SC_MANDRAGORA, INVALID_TIMER);
- status_change_end(bl, SC_SILENCE, INVALID_TIMER);
- } else // Success rate only applies to the curing effect and not stat bonus. Bonus status only applies to non infected targets
- clif_skill_nodamage(bl, bl, skillid, skilllv,
- sc_start(bl, type, 100, skilllv, skill_get_time(skillid, skilllv)));
- } else if (sd)
- party_foreachsamemap(skill_area_sub, sd, skill_get_splash(skillid, skilllv),
- src, skillid, skilllv, tick, flag|BCT_PARTY|1, skill_castend_nodamage_id);
- break;
+ if( (dstsd && pc_ismadogear(dstsd)) || status_isimmune(bl))
+ i = 0; // Should heal by 0 or won't do anything?? in iRO it breaks the healing to members.. [malufett]
- case AB_CLEARANCE:
- if (flag&1 || (i = skill_get_splash(skillid, skilllv)) < 1) {
- //As of the behavior in official server Clearance is just a super version of Dispell skill. [Jobbie]
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if ((dstsd && (dstsd->class_&MAPID_UPPERMASK) == MAPID_SOUL_LINKER) || rnd()%100 >= 30 + 10 * skilllv) {
- if (sd)
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
- if (status_isimmune(bl) || !tsc || !tsc->count)
- break;
- for (i=0; i<SC_MAX; i++) {
- if (!tsc->data[i])
- continue;
- switch (i) {
- case SC_WEIGHT50:
- case SC_WEIGHT90:
- case SC_HALLUCINATION:
- 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:
- case SC_COMBO:
- case SC_STRFOOD:
- case SC_AGIFOOD:
- case SC_VITFOOD:
- case SC_INTFOOD:
- case SC_DEXFOOD:
- case SC_LUKFOOD:
- case SC_HITFOOD:
- case SC_FLEEFOOD:
- case SC_BATKFOOD:
- case SC_WATKFOOD:
- case SC_MATKFOOD:
- case SC_DANCING:
- case SC_SPIRIT:
- case SC_AUTOBERSERK:
- case SC_CARTBOOST:
- case SC_MELTDOWN:
- case SC_SAFETYWALL:
- case SC_SMA:
- case SC_SPEEDUP0:
- case SC_NOCHAT:
- case SC_ANKLE:
- case SC_SPIDERWEB:
- case SC_JAILED:
- case SC_ITEMBOOST:
- case SC_EXPBOOST:
- case SC_LIFEINSURANCE:
- case SC_BOSSMAPINFO:
- case SC_PNEUMA:
- case SC_AUTOSPELL:
- case SC_INCHITRATE:
- case SC_INCATKRATE:
- case SC_NEN:
- case SC_READYSTORM:
- case SC_READYDOWN:
- case SC_READYTURN:
- case SC_READYCOUNTER:
- case SC_DODGE:
- case SC_WARM:
- case SC_SPEEDUP1:
- case SC_AUTOTRADE:
- case SC_CRITICALWOUND:
- case SC_JEXPBOOST:
- case SC_INVINCIBLE:
- case SC_INVINCIBLEOFF:
- case SC_HELLPOWER:
- case SC_MANU_ATK:
- case SC_MANU_DEF:
- case SC_SPL_ATK:
- case SC_SPL_DEF:
- case SC_MANU_MATK:
- case SC_SPL_MATK:
- case SC_RICHMANKIM:
- case SC_ETERNALCHAOS:
- case SC_DRUMBATTLE:
- case SC_NIBELUNGEN:
- case SC_ROKISWEIL:
- case SC_INTOABYSS:
- case SC_SIEGFRIED:
- case SC_WHISTLE:
- case SC_ASSNCROS:
- case SC_POEMBRAGI:
- case SC_APPLEIDUN:
- case SC_HUMMING:
- case SC_DONTFORGETME:
- case SC_FORTUNE:
- case SC_SERVICE4U:
- case SC_FOOD_STR_CASH:
- case SC_FOOD_AGI_CASH:
- case SC_FOOD_VIT_CASH:
- case SC_FOOD_DEX_CASH:
- case SC_FOOD_INT_CASH:
- case SC_FOOD_LUK_CASH:
- case SC_ELECTRICSHOCKER:
- case SC_BITE:
- case SC__STRIPACCESSORY:
- case SC__ENERVATION:
- case SC__GROOMY:
- case SC__IGNORANCE:
- case SC__LAZINESS:
- case SC__UNLUCKY:
- case SC__WEAKNESS: //case SC_SAVAGE_STEAK: case SC_COCKTAIL_WARG_BLOOD:
- case SC_MAGNETICFIELD://case SC_MINOR_BBQ: case SC_SIROMA_ICE_TEA:
- //case SC_DROCERA_HERB_STEAMED: case SC_PUTTI_TAILS_NOODLES:
- case SC_NEUTRALBARRIER_MASTER:
- case SC_NEUTRALBARRIER:
- case SC_STEALTHFIELD_MASTER:
- case SC_STEALTHFIELD:
- case SC_LEADERSHIP:
- case SC_GLORYWOUNDS:
- case SC_SOULCOLD:
- case SC_HAWKEYES:
- case SC_GUILDAURA:
- case SC_PUSH_CART:
- case SC_PARTYFLEE:
- case SC_GT_REVITALIZE:
- case SC_RAISINGDRAGON:
- case SC_GT_ENERGYGAIN:
- case SC_GT_CHANGE:
+ clif_skill_nodamage(bl, bl, skillid, i, 1);
+ if( tsc && tsc->data[SC_AKAITSUKI] && i )
+ i = ~i + 1;
+ status_heal(bl, i, 0, 0);
+ }
+ }
+ else if( sd )
+ party_foreachsamemap(skill_area_sub, sd, skill_get_splash(skillid, skilllv), src, skillid, skilllv, tick, flag|BCT_PARTY|1, skill_castend_nodamage_id);
+ break;
+
+ case AB_ORATIO:
+ if( flag&1 )
+ sc_start(bl, type, 40 + 5 * skilllv, skilllv, skill_get_time(skillid, skilllv));
+ else
+ {
+ map_foreachinrange(skill_area_sub, src, skill_get_splash(skillid, skilllv), BL_CHAR,
+ src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_nodamage_id);
+ clif_skill_nodamage(src, bl, skillid, skilllv, 1);
+ }
+ break;
+
+ case AB_LAUDAAGNUS:
+ if( flag&1 || sd == NULL ) {
+ if( tsc && (tsc->data[SC_FREEZE] || tsc->data[SC_STONE] || tsc->data[SC_BLIND] ||
+ tsc->data[SC_BURNING] || tsc->data[SC_FREEZING] || tsc->data[SC_CRYSTALIZE])) {
+ // Success Chance: (40 + 10 * Skill Level) %
+ if( rnd()%100 > 40+10*skilllv ) break;
+ status_change_end(bl, SC_FREEZE, INVALID_TIMER);
+ status_change_end(bl, SC_STONE, INVALID_TIMER);
+ status_change_end(bl, SC_BLIND, INVALID_TIMER);
+ status_change_end(bl, SC_BURNING, INVALID_TIMER);
+ status_change_end(bl, SC_FREEZING, INVALID_TIMER);
+ status_change_end(bl, SC_CRYSTALIZE, INVALID_TIMER);
+ }else //Success rate only applies to the curing effect and not stat bonus. Bonus status only applies to non infected targets
+ clif_skill_nodamage(bl, bl, skillid, skilllv,
+ sc_start(bl, type, 100, skilllv, skill_get_time(skillid, skilllv)));
+ } else if( sd )
+ party_foreachsamemap(skill_area_sub, sd, skill_get_splash(skillid, skilllv),
+ src, skillid, skilllv, tick, flag|BCT_PARTY|1, skill_castend_nodamage_id);
+ break;
+
+ case AB_LAUDARAMUS:
+ if( flag&1 || sd == NULL ) {
+ if( tsc && (tsc->data[SC_SLEEP] || tsc->data[SC_STUN] || tsc->data[SC_MANDRAGORA] || tsc->data[SC_SILENCE]) ){
+ // Success Chance: (40 + 10 * Skill Level) %
+ if( rnd()%100 > 40+10*skilllv ) break;
+ status_change_end(bl, SC_SLEEP, INVALID_TIMER);
+ status_change_end(bl, SC_STUN, INVALID_TIMER);
+ status_change_end(bl, SC_MANDRAGORA, INVALID_TIMER);
+ status_change_end(bl, SC_SILENCE, INVALID_TIMER);
+ }else // Success rate only applies to the curing effect and not stat bonus. Bonus status only applies to non infected targets
+ clif_skill_nodamage(bl, bl, skillid, skilllv,
+ sc_start(bl, type, 100, skilllv, skill_get_time(skillid, skilllv)));
+ } else if( sd )
+ party_foreachsamemap(skill_area_sub, sd, skill_get_splash(skillid, skilllv),
+ src, skillid, skilllv, tick, flag|BCT_PARTY|1, skill_castend_nodamage_id);
+ break;
+
+ case AB_CLEARANCE:
+ if( flag&1 || (i = skill_get_splash(skillid, skilllv)) < 1 )
+ { //As of the behavior in official server Clearance is just a super version of Dispell skill. [Jobbie]
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ if((dstsd && (dstsd->class_&MAPID_UPPERMASK) == MAPID_SOUL_LINKER) || rnd()%100 >= 30 + 10 * skilllv)
+ {
+ if (sd)
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+ if(status_isimmune(bl) || !tsc || !tsc->count)
+ break;
+ for(i=0;i<SC_MAX;i++)
+ {
+ if (!tsc->data[i])
+ continue;
+ switch (i) {
+ case SC_WEIGHT50: case SC_WEIGHT90: case SC_HALLUCINATION:
+ 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: case SC_COMBO:
+ case SC_STRFOOD: case SC_AGIFOOD: case SC_VITFOOD:
+ case SC_INTFOOD: case SC_DEXFOOD: case SC_LUKFOOD:
+ case SC_HITFOOD: case SC_FLEEFOOD: case SC_BATKFOOD:
+ case SC_WATKFOOD: case SC_MATKFOOD: case SC_DANCING:
+ case SC_SPIRIT: case SC_AUTOBERSERK:
+ case SC_CARTBOOST: case SC_MELTDOWN: case SC_SAFETYWALL:
+ case SC_SMA: case SC_SPEEDUP0: case SC_NOCHAT:
+ case SC_ANKLE: case SC_SPIDERWEB: case SC_JAILED:
+ case SC_ITEMBOOST: case SC_EXPBOOST: case SC_LIFEINSURANCE:
+ case SC_BOSSMAPINFO: case SC_PNEUMA: case SC_AUTOSPELL:
+ case SC_INCHITRATE: case SC_INCATKRATE: case SC_NEN:
+ case SC_READYSTORM: case SC_READYDOWN: case SC_READYTURN:
+ case SC_READYCOUNTER:case SC_DODGE: case SC_WARM:
+ case SC_SPEEDUP1: case SC_AUTOTRADE: case SC_CRITICALWOUND:
+ case SC_JEXPBOOST: case SC_INVINCIBLE: case SC_INVINCIBLEOFF:
+ case SC_HELLPOWER: case SC_MANU_ATK: case SC_MANU_DEF:
+ case SC_SPL_ATK: case SC_SPL_DEF: case SC_MANU_MATK:
+ case SC_SPL_MATK: case SC_RICHMANKIM: case SC_ETERNALCHAOS:
+ case SC_DRUMBATTLE: case SC_NIBELUNGEN: case SC_ROKISWEIL:
+ case SC_INTOABYSS: case SC_SIEGFRIED: case SC_WHISTLE:
+ case SC_ASSNCROS: case SC_POEMBRAGI: case SC_APPLEIDUN:
+ case SC_HUMMING: case SC_DONTFORGETME: case SC_FORTUNE:
+ case SC_SERVICE4U: case SC_FOOD_STR_CASH: case SC_FOOD_AGI_CASH:
+ case SC_FOOD_VIT_CASH: case SC_FOOD_DEX_CASH: case SC_FOOD_INT_CASH:
+ case SC_FOOD_LUK_CASH: case SC_ELECTRICSHOCKER: case SC_BITE:
+ case SC__STRIPACCESSORY: case SC__ENERVATION: case SC__GROOMY:
+ case SC__IGNORANCE: case SC__LAZINESS: case SC__UNLUCKY:
+ case SC__WEAKNESS: //case SC_SAVAGE_STEAK: case SC_COCKTAIL_WARG_BLOOD:
+ case SC_MAGNETICFIELD://case SC_MINOR_BBQ: case SC_SIROMA_ICE_TEA:
+ //case SC_DROCERA_HERB_STEAMED: case SC_PUTTI_TAILS_NOODLES:
+ case SC_NEUTRALBARRIER_MASTER: case SC_NEUTRALBARRIER:
+ case SC_STEALTHFIELD_MASTER: case SC_STEALTHFIELD:
+ case SC_LEADERSHIP: case SC_GLORYWOUNDS: case SC_SOULCOLD:
+ case SC_HAWKEYES: case SC_GUILDAURA: case SC_PUSH_CART:
+ case SC_PARTYFLEE: case SC_GT_REVITALIZE:
+ case SC_RAISINGDRAGON: case SC_GT_ENERGYGAIN: case SC_GT_CHANGE:
#ifdef RENEWAL
- case SC_EXTREMITYFIST2:
+ case SC_EXTREMITYFIST2:
#endif
- continue;
- case SC_ASSUMPTIO:
- if (bl->type == BL_MOB)
- continue;
- break;
- }
- if (i==SC_BERSERK || i==SC_SATURDAYNIGHTFEVER) tsc->data[i]->val2=0; //Mark a dispelled berserk to avoid setting hp to 100 by setting hp penalty to 0.
- status_change_end(bl,(sc_type)i,INVALID_TIMER);
- }
- break;
- }
- map_foreachinrange(skill_area_sub, bl, i, BL_CHAR, src, skillid, skilllv, tick, flag|1, skill_castend_damage_id);
- break;
-
- case AB_SILENTIUM:
- // Should the level of Lex Divina be equivalent to the level of Silentium or should the highest level learned be used? [LimitLine]
- map_foreachinrange(skill_area_sub, src, skill_get_splash(skillid, skilllv), BL_CHAR,
- src, PR_LEXDIVINA, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_nodamage_id);
- clif_skill_nodamage(src, bl, skillid, skilllv, 1);
- break;
- /**
- * Warlock
- **/
- case WL_STASIS:
- if (flag&1)
- sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv));
- else {
- map_foreachinrange(skill_area_sub,src,skill_get_splash(skillid, skilllv),BL_CHAR,src,skillid,skilllv,tick,(map_flag_vs(src->m)?BCT_ALL:BCT_ENEMY|BCT_SELF)|flag|1,skill_castend_nodamage_id);
- clif_skill_nodamage(src, bl, skillid, skilllv, 1);
- }
- break;
-
- case WL_WHITEIMPRISON:
- if ((src == bl || battle_check_target(src, bl, BCT_ENEMY)) && !is_boss(bl)) { // Should not work with bosses.
- int rate = (sd? sd->status.job_level : 50) / 4;
-
- if (src == bl) rate = 100; // Success Chance: On self, 100%
- else if (bl->type == BL_PC) rate += 20 + 10 * skilllv; // On Players, (20 + 10 * Skill Level) %
- else rate += 40 + 10 * skilllv; // On Monsters, (40 + 10 * Skill Level) %
-
- if (!(tsc && tsc->data[type])) {
- i = sc_start2(bl,type,rate,skilllv,src->id,(src == bl)?5000:(bl->type == BL_PC)?skill_get_time(skillid,skilllv):skill_get_time2(skillid, skilllv));
- clif_skill_nodamage(src,bl,skillid,skilllv,i);
- }
-
- if (sd && i)
- skill_blockpc_start(sd,skillid,4000); // Reuse Delay only activated on success
- else if (sd)
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- } else if (sd)
- clif_skill_fail(sd,skillid,USESKILL_FAIL_TOTARGET,0);
- break;
-
- case WL_FROSTMISTY:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- map_foreachinrange(skill_area_sub,bl,skill_get_splash(skillid,skilllv),BL_CHAR|BL_SKILL,src,skillid,skilllv,tick,flag|BCT_ENEMY,skill_castend_damage_id);
- break;
-
- case WL_JACKFROST:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- map_foreachinshootrange(skill_area_sub,bl,skill_get_splash(skillid,skilllv),BL_CHAR|BL_SKILL,src,skillid,skilllv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
- break;
-
- case WL_MARSHOFABYSS:
- // Should marsh of abyss still apply half reduction to players after the 28/10 patch? [LimitLine]
- clif_skill_nodamage(src, bl, skillid, skilllv,
- sc_start4(bl, type, 100, skilllv, status_get_int(src), sd ? sd->status.job_level : 50, 0,
- skill_get_time(skillid, skilllv)));
- break;
-
- case WL_SIENNAEXECRATE:
- if (status_isimmune(bl) || !tsc)
- break;
-
- if (flag&1) {
- if (bl->id == skill_area_temp[1])
- break; // Already work on this target
-
- if (tsc && tsc->data[SC_STONE])
- status_change_end(bl,SC_STONE,INVALID_TIMER);
- else
- status_change_start(bl,SC_STONE,10000,skilllv,0,0,1000,skill_get_time(skillid, skilllv),2);
- } else {
- int rate = 40 + 8 * skilllv + (sd? sd->status.job_level : 50) / 4;
- // IroWiki says Rate should be reduced by target stats, but currently unknown
- if (rnd()%100 < rate) { // Success on First Target
- if (!tsc->data[SC_STONE])
- rate = status_change_start(bl,SC_STONE,10000,skilllv,0,0,1000,skill_get_time(skillid, skilllv),2);
- else {
- rate = 1;
- status_change_end(bl,SC_STONE,INVALID_TIMER);
- }
-
- if (rate) {
- skill_area_temp[1] = bl->id;
- map_foreachinrange(skill_area_sub,bl,skill_get_splash(skillid,skilllv),BL_CHAR,src,skillid,skilllv,tick,flag|BCT_ENEMY|1,skill_castend_nodamage_id);
- }
- // Doesn't send failure packet if it fails on defense.
- } else if (sd) // Failure on Rate
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- }
- break;
-
- case WL_SUMMONFB:
- case WL_SUMMONBL:
- case WL_SUMMONWB:
- case WL_SUMMONSTONE: {
- short element = 0, sctype = 0, pos = -1;
- struct status_change *sc = status_get_sc(src);
- if (!sc) break;
-
- for (i = SC_SPHERE_1; i <= SC_SPHERE_5; i++) {
- if (!sctype && !sc->data[i])
- sctype = i; // Take the free SC
- if (sc->data[i])
- pos = max(sc->data[i]->val2,pos);
- }
-
- if (!sctype) {
- if (sd) // No free slots to put SC
- clif_skill_fail(sd,skillid,USESKILL_FAIL_SUMMON,0);
- break;
- }
-
- pos++; // Used in val2 for SC. Indicates the order of this ball
- switch (skillid) {
- // Set val1. The SC element for this ball
- case WL_SUMMONFB:
- element = WLS_FIRE;
- break;
- case WL_SUMMONBL:
- element = WLS_WIND;
- break;
- case WL_SUMMONWB:
- element = WLS_WATER;
- break;
- case WL_SUMMONSTONE:
- element = WLS_STONE;
- break;
- }
-
- sc_start4(src,sctype,100,element,pos,skilllv,0,skill_get_time(skillid,skilllv));
- clif_skill_nodamage(src,bl,skillid,0,0);
- }
- break;
-
- case WL_READING_SB:
- if (sd) {
- struct status_change *sc = status_get_sc(bl);
-
- for (i = SC_SPELLBOOK1; i <= SC_MAXSPELLBOOK; i++)
- if (sc && !sc->data[i])
- break;
- if (i == SC_MAXSPELLBOOK) {
- clif_skill_fail(sd, WL_READING_SB, USESKILL_FAIL_SPELLBOOK_READING, 0);
- break;
- }
-
- sc_start(bl, SC_STOP, 100, skilllv, INVALID_TIMER); //Can't move while selecting a spellbook.
- clif_spellbook_list(sd);
- clif_skill_nodamage(src, bl, skillid, skilllv, 1);
- }
- break;
- /**
- * Ranger
- **/
- case RA_FEARBREEZE:
- clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
- clif_skill_nodamage(src, bl, skillid, skilllv, sc_start(bl, type, 100, skilllv, skill_get_time(skillid, skilllv)));
- break;
-
- case RA_WUGMASTERY:
- if (sd) {
- if (!pc_iswug(sd))
- pc_setoption(sd,sd->sc.option|OPTION_WUG);
- else
- pc_setoption(sd,sd->sc.option&~OPTION_WUG);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- }
- break;
-
- case RA_WUGRIDER:
- if (sd) {
- if (!pc_isridingwug(sd) && pc_iswug(sd)) {
- pc_setoption(sd,sd->sc.option&~OPTION_WUG);
- pc_setoption(sd,sd->sc.option|OPTION_WUGRIDER);
- } else if (pc_isridingwug(sd)) {
- pc_setoption(sd,sd->sc.option&~OPTION_WUGRIDER);
- pc_setoption(sd,sd->sc.option|OPTION_WUG);
- }
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- }
- break;
-
- case RA_WUGDASH:
- if (tsce) {
- clif_skill_nodamage(src,bl,skillid,skilllv,status_change_end(bl, type, INVALID_TIMER));
- map_freeblock_unlock();
- return 0;
- }
- if (sd && pc_isridingwug(sd)) {
- clif_skill_nodamage(src,bl,skillid,skilllv,sc_start4(bl,type,100,skilllv,unit_getdir(bl),0,0,1));
- clif_walkok(sd);
- }
- break;
-
- case RA_SENSITIVEKEEN:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- clif_skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
- map_foreachinrange(skill_area_sub,src,skill_get_splash(skillid,skilllv),BL_CHAR|BL_SKILL,src,skillid,skilllv,tick,flag|BCT_ENEMY,skill_castend_damage_id);
- break;
- /**
- * Mechanic
- **/
- case NC_F_SIDESLIDE:
- case NC_B_SIDESLIDE: {
- int dir = (skillid == NC_F_SIDESLIDE) ? (unit_getdir(src)+4)%8 : unit_getdir(src);
- skill_blown(src,bl,skill_get_blewcount(skillid,skilllv),dir,0x1);
- clif_slide(src,src->x,src->y);
- clif_fixpos(src); //Aegis sent this packet
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- }
- break;
-
- case NC_SELFDESTRUCTION:
- if (sd) {
- if (pc_ismadogear(sd))
- pc_setmadogear(sd, 0);
- clif_skill_nodamage(src, bl, skillid, skilllv, 1);
- skill_castend_damage_id(src, src, skillid, skilllv, tick, flag);
- status_set_sp(src, 0, 0);
- }
- break;
-
- case NC_ANALYZE:
- clif_skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
- clif_skill_nodamage(src, bl, skillid, skilllv,
- sc_start(bl,type, 30 + 12 * skilllv,skilllv,skill_get_time(skillid,skilllv)));
- if (sd) pc_overheat(sd,1);
- break;
-
- case NC_MAGNETICFIELD:
- if ((i = sc_start2(bl,type,100,skilllv,src->id,skill_get_time(skillid,skilllv)))) {
- map_foreachinrange(skill_area_sub,src,skill_get_splash(skillid,skilllv),splash_target(src),src,skillid,skilllv,tick,flag|BCT_ENEMY|SD_SPLASH|1,skill_castend_damage_id);;
- clif_skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skillid,skilllv,6);
- if (sd) pc_overheat(sd,1);
- }
- clif_skill_nodamage(src,src,skillid,skilllv,i);
- break;
-
- case NC_REPAIR:
- if (sd) {
- int heal;
- if (dstsd && pc_ismadogear(dstsd)) {
- heal = dstsd->status.max_hp * (3+3*skilllv) / 100;
- status_heal(bl,heal,0,2);
- } else {
- heal = sd->status.max_hp * (3+3*skilllv) / 100;
- status_heal(src,heal,0,2);
- }
-
- clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
- clif_skill_nodamage(src, bl, skillid, skilllv, heal);
- }
- break;
-
- case NC_DISJOINT: {
- if (bl->type != BL_MOB) break;
- md = map_id2md(bl->id);
- if (md && md->class_ >= MOBID_SILVERSNIPER && md->class_ <= MOBID_MAGICDECOY_WIND)
- status_kill(bl);
- clif_skill_nodamage(src, bl, skillid, skilllv, 1);
- }
- break;
- case SC_AUTOSHADOWSPELL:
- if (sd) {
- if (sd->status.skill[sd->reproduceskill_id].id || sd->status.skill[sd->cloneskill_id].id) {
- sc_start(src,SC_STOP,100,skilllv,-1);// The skilllv is stored in val1 used in skill_select_menu to determine the used skill lvl [Xazax]
- clif_autoshadowspell_list(sd);
- clif_skill_nodamage(src,bl,skillid,1,1);
- } else
- clif_skill_fail(sd,skillid,USESKILL_FAIL_IMITATION_SKILL_NONE,0);
- }
- break;
-
- case SC_SHADOWFORM:
- if (sd && dstsd && src != bl && !dstsd->shadowform_id) {
- if (clif_skill_nodamage(src,bl,skillid,skilllv,sc_start4(src,type,100,skilllv,bl->id,4+skilllv,0,skill_get_time(skillid, skilllv))))
- dstsd->shadowform_id = src->id;
- } else if (sd)
- clif_skill_fail(sd, skillid, USESKILL_FAIL_LEVEL, 0);
- break;
-
- case SC_BODYPAINT:
- if (flag&1) {
- if (tsc && (tsc->data[SC_HIDING] || tsc->data[SC_CLOAKING] ||
- tsc->data[SC_CHASEWALK] || tsc->data[SC_CLOAKINGEXCEED] ||
- tsc->data[SC__INVISIBILITY])) {
- status_change_end(bl, SC_HIDING, INVALID_TIMER);
- status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
- status_change_end(bl, SC_CHASEWALK, INVALID_TIMER);
- status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
- status_change_end(bl, SC__INVISIBILITY, INVALID_TIMER);
-
- sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv));
- sc_start(bl,SC_BLIND,53 + 2 * skilllv,skilllv,skill_get_time(skillid,skilllv));
- }
- } else {
- clif_skill_nodamage(src, bl, skillid, 0, 1);
- map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), BL_CHAR,
- src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_nodamage_id);
- }
- break;
-
- case SC_ENERVATION:
- case SC_GROOMY:
- case SC_LAZINESS:
- case SC_UNLUCKY:
- case SC_WEAKNESS:
- if (!(tsc && tsc->data[type])) {
- //((rand(myDEX / 12, myDEX / 4) + myJobLevel + 10 * skLevel) + myLevel / 10) - (targetLevel / 10 + targetLUK / 10 + (targetMaxWeight - targetWeight) / 1000 + rand(targetAGI / 6, targetAGI / 3))
- int rate = rnd_value(sstatus->dex/12,sstatus->dex/4) + 10*skilllv + (sd?sd->status.job_level:0) + status_get_lv(src)/10
- - status_get_lv(bl)/10 - tstatus->luk/10 - (dstsd?(dstsd->max_weight-dstsd->weight)/10000:0) - rnd_value(tstatus->agi/6,tstatus->agi/3);
- rate = cap_value(rate, skilllv+sstatus->dex/20, 100);
- clif_skill_nodamage(src,bl,skillid,0,sc_start(bl,type,rate,skilllv,skill_get_time(skillid,skilllv)));
- } else if (sd)
- clif_skill_fail(sd,skillid,0,0);
- break;
-
- case SC_IGNORANCE:
- if (!(tsc && tsc->data[type])) {
- int rate = rnd_value(sstatus->dex/12,sstatus->dex/4) + 10*skilllv + (sd?sd->status.job_level:0) + status_get_lv(src)/10
- - status_get_lv(bl)/10 - tstatus->luk/10 - (dstsd?(dstsd->max_weight-dstsd->weight)/10000:0) - rnd_value(tstatus->agi/6,tstatus->agi/3);
- rate = cap_value(rate, skilllv+sstatus->dex/20, 100);
- if (clif_skill_nodamage(src,bl,skillid,0,sc_start(bl,type,rate,skilllv,skill_get_time(skillid,skilllv)))) {
- int sp = 200 * skilllv;
- if (dstmd) sp = dstmd->level * 2;
- if (status_zap(bl,0,sp))
- status_heal(src,0,sp/2,3);
- } else if (sd) clif_skill_fail(sd,skillid,0,0);
- } else if (sd)
- clif_skill_fail(sd,skillid,0,0);
- break;
-
- case LG_TRAMPLE:
- clif_skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
- map_foreachinrange(skill_destroy_trap,bl,skill_get_splash(skillid,skilllv),BL_SKILL,tick);
- break;
-
- case LG_REFLECTDAMAGE:
- if (tsc && tsc->data[type])
- status_change_end(bl,type,INVALID_TIMER);
- else
- sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv));
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- break;
-
- case LG_SHIELDSPELL:
- if (flag&1) {
- int duration = (sd) ? sd->bonus.shieldmdef * 2000 : 10000;
- sc_start(bl,SC_SILENCE,100,skilllv,duration);
- } else if (sd) {
- int opt = skilllv;
- int rate = rnd()%100;
- int val, brate;
- switch (skilllv) {
- case 1: {
- struct item_data *shield_data = sd->inventory_data[sd->equip_index[EQI_HAND_L]];
- if (!shield_data || shield_data->type != IT_ARMOR) { // No shield?
- clif_skill_fail(sd, skillid, USESKILL_FAIL_LEVEL, 0);
- break;
- }
- brate = shield_data->def * 10;
- if (rate < 50)
- opt = 1;
- else if (rate < 75)
- opt = 2;
- else
- opt = 3;
-
- switch (opt) {
- case 1:
- sc_start(bl,SC_SHIELDSPELL_DEF,100,opt,-1);
- clif_skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
- if (rate < brate)
- map_foreachinrange(skill_area_sub,src,skill_get_splash(skillid,skilllv),BL_CHAR,src,skillid,skilllv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
- status_change_end(bl,SC_SHIELDSPELL_DEF,INVALID_TIMER);
- break;
- case 2:
- val = shield_data->def / 10; // % Reflected damage.
- sc_start2(bl,SC_SHIELDSPELL_DEF,brate,opt,val,shield_data->def * 1000);
- break;
- case 3:
- val = shield_data->def; // Attack increase.
- sc_start2(bl,SC_SHIELDSPELL_DEF,brate,opt,val,shield_data->def * 3000);
- break;
- }
- }
- break;
-
- case 2:
- brate = sd->bonus.shieldmdef * 20;
- if (rate < 30)
- opt = 1;
- else if (rate < 60)
- opt = 2;
- else
- opt = 3;
- switch (opt) {
- case 1:
- sc_start(bl,SC_SHIELDSPELL_MDEF,100,opt,-1);
- clif_skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
- if (rate < brate)
- map_foreachinrange(skill_area_sub,src,skill_get_splash(skillid,skilllv),BL_CHAR,src,skillid,skilllv,tick,flag|BCT_ENEMY|2,skill_castend_damage_id);
- status_change_end(bl,SC_SHIELDSPELL_MDEF,INVALID_TIMER);
- break;
- case 2:
- sc_start(bl,SC_SHIELDSPELL_MDEF,100,opt,-1);
- clif_skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
- if (rate < brate)
- map_foreachinrange(skill_area_sub,src,skill_get_splash(skillid,skilllv),BL_CHAR,src,skillid,skilllv,tick,flag|BCT_ENEMY|1,skill_castend_nodamage_id);
- break;
- case 3:
- if (sc_start(bl,SC_SHIELDSPELL_MDEF,brate,opt,sd->bonus.shieldmdef * 30000))
- clif_skill_nodamage(src,bl,PR_MAGNIFICAT,skilllv,
- sc_start(bl,SC_MAGNIFICAT,100,1,sd->bonus.shieldmdef * 30000));
- break;
- }
- break;
-
- case 3: {
- struct item *it = &sd->status.inventory[sd->equip_index[EQI_HAND_L]];
- if (!it) { // No shield?
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
- brate = it->refine * 5;
- if (rate < 25)
- opt = 1;
- else if (rate < 50)
- opt = 2;
- else
- opt = 3;
- switch (opt) {
- case 1:
- val = 105 * it->refine / 10;
- sc_start2(bl,SC_SHIELDSPELL_REF,brate,opt,val,skill_get_time(skillid,skilllv));
- break;
- case 2:
- case 3:
- if (rate < brate) {
- val = sstatus->max_hp * (11 + it->refine) / 100;
- status_heal(bl, val, 0, 3);
- }
- break;
- /*case 3:
- // Full protection. I need confirm what effect should be here. Moved to case 2 to until we got it.
- break;*/
- }
- }
- break;
- }
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- }
- break;
-
- case LG_PIETY:
- if (flag&1)
- sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv));
- else {
- skill_area_temp[2] = 0;
- map_foreachinrange(skill_area_sub,bl,skill_get_splash(skillid,skilllv),BL_PC,src,skillid,skilllv,tick,flag|SD_PREAMBLE|BCT_PARTY|BCT_SELF|1,skill_castend_nodamage_id);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- }
- break;
-
- case LG_INSPIRATION:
- if (sd && !map[sd->bl.m].flag.noexppenalty && sd->status.base_level != MAX_LEVEL) {
- sd->status.base_exp -= min(sd->status.base_exp, pc_nextbaseexp(sd) * 1 / 100); // 1% penalty.
- sd->status.job_exp -= min(sd->status.job_exp, pc_nextjobexp(sd) * 1 / 100);
- clif_updatestatus(sd,SP_BASEEXP);
- clif_updatestatus(sd,SP_JOBEXP);
- }
- clif_skill_nodamage(bl,src,skillid,skilllv,
- sc_start(bl, type, 100, skilllv, skill_get_time(skillid, skilllv)));
- break;
- case SR_CURSEDCIRCLE:
- if (flag&1) {
- if (is_boss(bl)) break;
- if (sc_start2(bl, type, 100, skilllv, src->id, skill_get_time(skillid, skilllv))) {
- if (bl->type == BL_MOB)
- mob_unlocktarget((TBL_MOB *)bl,gettick());
- unit_stop_attack(bl);
- clif_bladestop(src, bl->id, 1);
- map_freeblock_unlock();
- return 1;
- }
- } else {
- int count = 0;
- clif_skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
- count = map_forcountinrange(skill_area_sub, src, skill_get_splash(skillid,skilllv), (sd)?sd->spiritball_old:15, // Assume 15 spiritballs in non-charactors
- BL_CHAR, src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_nodamage_id);
- if (sd) pc_delspiritball(sd, count, 0);
- clif_skill_nodamage(src, src, skillid, skilllv,
- sc_start2(src, SC_CURSEDCIRCLE_ATKER, 100, skilllv, count, skill_get_time(skillid,skilllv)));
- }
- break;
-
- case SR_RAISINGDRAGON:
- if (sd) {
- short max = 5 + skilllv;
- sc_start(bl, SC_EXPLOSIONSPIRITS, 100, skilllv, skill_get_time(skillid, skilllv));
- for (i = 0; i < max; i++) // Don't call more than max available spheres.
- pc_addspiritball(sd, skill_get_time(skillid, skilllv), max);
- clif_skill_nodamage(src, bl, skillid, skilllv, sc_start(bl, type, 100, skilllv,skill_get_time(skillid, skilllv)));
- }
- break;
-
- case SR_ASSIMILATEPOWER:
- if (flag&1) {
- i = 0;
- if (dstsd && dstsd->spiritball && (sd == dstsd || map_flag_vs(src->m)) && (dstsd->class_&MAPID_BASEMASK)!=MAPID_GUNSLINGER) {
- i = dstsd->spiritball; //1%sp per spiritball.
- pc_delspiritball(dstsd, dstsd->spiritball, 0);
- }
- if (i) status_percent_heal(src, 0, i);
- clif_skill_nodamage(src, bl, skillid, skilllv, i ? 1:0);
- } else {
- clif_skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
- map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), splash_target(src), src, skillid, skilllv, tick, flag|BCT_ENEMY|BCT_SELF|SD_SPLASH|1, skill_castend_nodamage_id);
- }
- break;
-
- case SR_POWERVELOCITY:
- if (!dstsd)
- break;
- if (sd && dstsd->spiritball <= 5) {
- for (i = 0; i <= 5; i++) {
- pc_addspiritball(dstsd, skill_get_time(MO_CALLSPIRITS, pc_checkskill(sd,MO_CALLSPIRITS)), i);
- pc_delspiritball(sd, sd->spiritball, 0);
- }
- }
- clif_skill_nodamage(src, bl, skillid, skilllv, 1);
- break;
-
- case SR_GENTLETOUCH_CURE: {
- int heal;
-
- if (status_isimmune(bl)) {
- clif_skill_nodamage(src,bl,skillid,skilllv,0);
- break;
- }
-
- heal = 120 * skilllv + status_get_max_hp(bl) * (2 + skilllv) / 100;
- status_heal(bl, heal, 0, 0);
-
- if ((tsc && tsc->opt1) && (rnd()%100 < ((skilllv * 5) + (status_get_dex(src) + status_get_lv(src)) / 4) - (1 + (rnd() % 10)))) {
- status_change_end(bl, SC_STONE, INVALID_TIMER);
- status_change_end(bl, SC_FREEZE, INVALID_TIMER);
- status_change_end(bl, SC_STUN, INVALID_TIMER);
- status_change_end(bl, SC_POISON, INVALID_TIMER);
- status_change_end(bl, SC_SILENCE, INVALID_TIMER);
- status_change_end(bl, SC_BLIND, INVALID_TIMER);
- status_change_end(bl, SC_HALLUCINATION, INVALID_TIMER);
- status_change_end(bl, SC_BURNING, INVALID_TIMER);
- status_change_end(bl, SC_FREEZING, INVALID_TIMER);
- }
-
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- }
- break;
- case SR_GENTLETOUCH_CHANGE:
- case SR_GENTLETOUCH_REVITALIZE:
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start2(bl,type,100,skilllv,src->id,skill_get_time(skillid,skilllv)));
- break;
- case WA_SWING_DANCE:
- case WA_MOONLIT_SERENADE:
- if (sd == NULL || sd->status.party_id == 0 || (flag & 1))
- sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv));
- else if (sd) { // Only shows effects on caster.
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- party_foreachsamemap(skill_area_sub, sd, skill_get_splash(skillid, skilllv), src, skillid, skilllv, tick, flag|BCT_PARTY|1, skill_castend_nodamage_id);
- }
- break;
-
- case WA_SYMPHONY_OF_LOVER:
- case MI_RUSH_WINDMILL:
- case MI_ECHOSONG:
- if (sd == NULL || sd->status.party_id == 0 || (flag & 1))
- sc_start4(bl,type,100,skilllv,6*skilllv,(sd?pc_checkskill(sd,WM_LESSON):0),(sd?sd->status.job_level:0),skill_get_time(skillid,skilllv));
- else if (sd) { // Only shows effects on caster.
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- party_foreachsamemap(skill_area_sub, sd, skill_get_splash(skillid, skilllv), src, skillid, skilllv, tick, flag|BCT_PARTY|1, skill_castend_nodamage_id);
- }
- break;
-
- case MI_HARMONIZE:
- if (src != bl)
- clif_skill_nodamage(src, src, skillid, skilllv, sc_start(src, type, 100, skilllv, skill_get_time(skillid,skilllv)));
- clif_skill_nodamage(src, bl, skillid, skilllv, sc_start(bl, type, 100, skilllv, skill_get_time(skillid,skilllv)));
- break;
-
- case WM_DEADHILLHERE:
- if (bl->type == BL_PC) {
- if (!status_isdead(bl))
- break;
-
- if (rnd()%100 < 88 + 2 * skilllv) {
- int heal = tstatus->sp;
- if (heal <= 0)
- heal = 1;
- tstatus->hp = heal;
- tstatus->sp -= tstatus->sp * (120 - 20 * skilllv) / 100;
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- pc_revive((TBL_PC *)bl,heal,0);
- clif_resurrection(bl,1);
- }
- }
- break;
-
- case WM_SIRCLEOFNATURE:
- flag |= BCT_SELF|BCT_PARTY|BCT_GUILD;
- case WM_VOICEOFSIREN:
- if (skillid != WM_SIRCLEOFNATURE)
- flag &= ~BCT_SELF;
- if (flag&1) {
- sc_start2(bl,type,(skillid==WM_VOICEOFSIREN)?20+10*skilllv:100,skilllv,(skillid==WM_VOICEOFSIREN)?src->id:0,skill_get_time(skillid,skilllv));
- } else {
- map_foreachinrange(skill_area_sub, src, skill_get_splash(skillid,skilllv),(skillid==WM_VOICEOFSIREN)?BL_CHAR|BL_SKILL:BL_PC, src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_nodamage_id);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- }
- break;
-
- case WM_GLOOMYDAY:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if (dstsd && (pc_checkskill(dstsd,KN_BRANDISHSPEAR) || pc_checkskill(dstsd,LK_SPIRALPIERCE) ||
- pc_checkskill(dstsd,CR_SHIELDCHARGE) || pc_checkskill(dstsd,CR_SHIELDBOOMERANG) ||
- pc_checkskill(dstsd,PA_SHIELDCHAIN) || pc_checkskill(dstsd,LG_SHIELDPRESS))) {
- sc_start(bl,SC_GLOOMYDAY_SK,100,skilllv,skill_get_time(skillid,skilllv));
- break;
- }
- sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv));
- break;
-
- case WM_SATURDAY_NIGHT_FEVER:
- if (flag&1) { // Affect to all targets arround the caster and caster too.
- if (!(tsc && tsc->data[type]))
- sc_start(bl, type, 100, skilllv,skill_get_time(skillid, skilllv));
- } else if (flag&2) {
- if (src->id != bl->id && battle_check_target(src,bl,BCT_ENEMY) > 0)
- status_fix_damage(src,bl,9999,clif_damage(src,bl,tick,0,0,9999,0,0,0));
- } else if (sd) {
- short chance = sstatus->int_/6 + sd->status.job_level/5 + skilllv*4;
- if (!sd->status.party_id || (rnd()%100 > chance)) {
- clif_skill_fail(sd,skillid,USESKILL_FAIL_NEED_HELPER,0);
- break;
- }
- if (map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid,skilllv),
- BL_PC, src, skillid, skilllv, tick, BCT_ENEMY, skill_area_sub_count) > 7)
- flag |= 2;
- else
- flag |= 1;
- map_foreachinrange(skill_area_sub, src, skill_get_splash(skillid,skilllv),BL_PC, src, skillid, skilllv, tick, flag|BCT_ENEMY|BCT_SELF, skill_castend_nodamage_id);
- clif_skill_nodamage(src, bl, skillid, skilllv,
- sc_start(src,SC_STOP,100,skilllv,skill_get_time2(skillid,skilllv)));
- if (flag&2) // Dealed here to prevent conflicts
- status_fix_damage(src,bl,9999,clif_damage(src,bl,tick,0,0,9999,0,0,0));
- }
- break;
-
- case WM_SONG_OF_MANA:
- case WM_DANCE_WITH_WUG:
- case WM_LERADS_DEW:
- if (flag&1) { // These affect to to all party members near the caster.
- struct status_change *sc = status_get_sc(src);
- if (sc && sc->data[type]) {
- sc_start2(bl,type,100,skilllv,sc->data[type]->val2,skill_get_time(skillid,skilllv));
- }
- } else if (sd) {
- short lv = (short)skilllv;
- int count = skill_check_pc_partner(sd,skillid,&lv,skill_get_splash(skillid,skilllv),1);
- if (sc_start2(bl,type,100,skilllv,count,skill_get_time(skillid,skilllv)))
- party_foreachsamemap(skill_area_sub,sd,skill_get_splash(skillid,skilllv),src,skillid,skilllv,tick,flag|BCT_PARTY|1,skill_castend_nodamage_id);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
-
- }
- break;
-
- case WM_MELODYOFSINK:
- case WM_BEYOND_OF_WARCRY:
- case WM_UNLIMITED_HUMMING_VOICE:
- if (flag&1) {
- sc_start2(bl,type,100,skilllv,skill_area_temp[0],skill_get_time(skillid,skilllv));
- } else { // These affect to all targets arround the caster.
- short lv = (short)skilllv;
- skill_area_temp[0] = (sd) ? skill_check_pc_partner(sd,skillid,&lv,skill_get_splash(skillid,skilllv),1) : 50; // 50% chance in non BL_PC (clones).
- map_foreachinrange(skill_area_sub, src, skill_get_splash(skillid,skilllv),BL_PC, src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_nodamage_id);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- }
- break;
-
- case WM_RANDOMIZESPELL: {
- int improv_skillid = 0, improv_skilllv;
- do {
- i = rnd() % MAX_SKILL_IMPROVISE_DB;
- improv_skillid = skill_improvise_db[i].skillid;
- } while (improv_skillid == 0 || rnd()%10000 >= skill_improvise_db[i].per);
- improv_skilllv = 4 + skilllv;
- clif_skill_nodamage(src, bl, skillid, skilllv, 1);
-
- if (sd) {
- sd->state.abra_flag = 2;
- sd->skillitem = improv_skillid;
- sd->skillitemlv = improv_skilllv;
- clif_item_skill(sd, improv_skillid, improv_skilllv);
- } else {
- struct unit_data *ud = unit_bl2ud(src);
- int inf = skill_get_inf(improv_skillid);
- int target_id = 0;
- if (!ud) break;
- if (inf&INF_SELF_SKILL || inf&INF_SUPPORT_SKILL) {
- if (src->type == BL_PET)
- bl = (struct block_list *)((TBL_PET *)src)->msd;
- if (!bl) bl = src;
- unit_skilluse_id(src, bl->id, improv_skillid, improv_skilllv);
- } else {
- if (ud->target)
- target_id = ud->target;
- else switch (src->type) {
- case BL_MOB:
- target_id = ((TBL_MOB *)src)->target_id;
- break;
- case BL_PET:
- target_id = ((TBL_PET *)src)->target_id;
- break;
- }
- if (!target_id)
- break;
- if (skill_get_casttype(improv_skillid) == CAST_GROUND) {
- bl = map_id2bl(target_id);
- if (!bl) bl = src;
- unit_skilluse_pos(src, bl->x, bl->y, improv_skillid, improv_skilllv);
- } else
- unit_skilluse_id(src, target_id, improv_skillid, improv_skilllv);
- }
- }
- }
- break;
-
+ continue;
+ case SC_ASSUMPTIO:
+ if( bl->type == BL_MOB )
+ continue;
+ break;
+ }
+ if(i==SC_BERSERK || i==SC_SATURDAYNIGHTFEVER) tsc->data[i]->val2=0; //Mark a dispelled berserk to avoid setting hp to 100 by setting hp penalty to 0.
+ status_change_end(bl,(sc_type)i,INVALID_TIMER);
+ }
+ break;
+ }
+ map_foreachinrange(skill_area_sub, bl, i, BL_CHAR, src, skillid, skilllv, tick, flag|1, skill_castend_damage_id);
+ break;
+
+ case AB_SILENTIUM:
+ // Should the level of Lex Divina be equivalent to the level of Silentium or should the highest level learned be used? [LimitLine]
+ map_foreachinrange(skill_area_sub, src, skill_get_splash(skillid, skilllv), BL_CHAR,
+ src, PR_LEXDIVINA, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_nodamage_id);
+ clif_skill_nodamage(src, bl, skillid, skilllv, 1);
+ break;
+ /**
+ * Warlock
+ **/
+ case WL_STASIS:
+ if( flag&1 )
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv));
+ else
+ {
+ map_foreachinrange(skill_area_sub,src,skill_get_splash(skillid, skilllv),BL_CHAR,src,skillid,skilllv,tick,(map_flag_vs(src->m)?BCT_ALL:BCT_ENEMY|BCT_SELF)|flag|1,skill_castend_nodamage_id);
+ clif_skill_nodamage(src, bl, skillid, skilllv, 1);
+ }
+ break;
+
+ case WL_WHITEIMPRISON:
+ if( (src == bl || battle_check_target(src, bl, BCT_ENEMY)) && !is_boss(bl) )// Should not work with bosses.
+ {
+ int rate = ( sd? sd->status.job_level : 50 ) / 4;
+
+ if(src == bl ) rate = 100; // Success Chance: On self, 100%
+ else if(bl->type == BL_PC) rate += 20 + 10 * skilllv; // On Players, (20 + 10 * Skill Level) %
+ else rate += 40 + 10 * skilllv; // On Monsters, (40 + 10 * Skill Level) %
+
+ if( !(tsc && tsc->data[type]) ){
+ i = sc_start2(bl,type,rate,skilllv,src->id,(src == bl)?5000:(bl->type == BL_PC)?skill_get_time(skillid,skilllv):skill_get_time2(skillid, skilllv));
+ clif_skill_nodamage(src,bl,skillid,skilllv,i);
+ }
- case RETURN_TO_ELDICASTES:
- case ALL_GUARDIAN_RECALL:
- if (sd) {
- short x, y; // Destiny position.
- unsigned short mapindex;
-
- if (skillid == RETURN_TO_ELDICASTES) {
- x = 198;
- y = 187;
- mapindex = mapindex_name2id(MAP_DICASTES);
- } else {
- x = 44;
- y = 151;
- mapindex = mapindex_name2id(MAP_MORA);
- }
+ if( sd && i )
+ skill_blockpc_start(sd,skillid,4000); // Reuse Delay only activated on success
+ else if(sd)
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ }else if( sd )
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_TOTARGET,0);
+ break;
+
+ case WL_FROSTMISTY:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ map_foreachinrange(skill_area_sub,bl,skill_get_splash(skillid,skilllv),BL_CHAR|BL_SKILL,src,skillid,skilllv,tick,flag|BCT_ENEMY,skill_castend_damage_id);
+ break;
+
+ case WL_JACKFROST:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ map_foreachinshootrange(skill_area_sub,bl,skill_get_splash(skillid,skilllv),BL_CHAR|BL_SKILL,src,skillid,skilllv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
+ break;
+
+ case WL_MARSHOFABYSS:
+ // Should marsh of abyss still apply half reduction to players after the 28/10 patch? [LimitLine]
+ clif_skill_nodamage(src, bl, skillid, skilllv,
+ sc_start4(bl, type, 100, skilllv, status_get_int(src), sd ? sd->status.job_level : 50, 0,
+ skill_get_time(skillid, skilllv)));
+ break;
+
+ case WL_SIENNAEXECRATE:
+ if( status_isimmune(bl) || !tsc )
+ break;
+
+ if( flag&1 ) {
+ if( bl->id == skill_area_temp[1] )
+ break; // Already work on this target
+
+ if( tsc && tsc->data[SC_STONE] )
+ status_change_end(bl,SC_STONE,INVALID_TIMER);
+ else
+ status_change_start(bl,SC_STONE,10000,skilllv,0,0,1000,skill_get_time(skillid, skilllv),2);
+ } else {
+ int rate = 40 + 8 * skilllv + ( sd? sd->status.job_level : 50 ) / 4;
+ // IroWiki says Rate should be reduced by target stats, but currently unknown
+ if( rnd()%100 < rate ) { // Success on First Target
+ if( !tsc->data[SC_STONE] )
+ rate = status_change_start(bl,SC_STONE,10000,skilllv,0,0,1000,skill_get_time(skillid, skilllv),2);
+ else {
+ rate = 1;
+ status_change_end(bl,SC_STONE,INVALID_TIMER);
+ }
- if (!mapindex) {
- //Given map not found?
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- map_freeblock_unlock();
- return 0;
- }
- pc_setpos(sd, mapindex, x, y, CLR_TELEPORT);
- }
- break;
+ if( rate ) {
+ skill_area_temp[1] = bl->id;
+ map_foreachinrange(skill_area_sub,bl,skill_get_splash(skillid,skilllv),BL_CHAR,src,skillid,skilllv,tick,flag|BCT_ENEMY|1,skill_castend_nodamage_id);
+ }
+ // Doesn't send failure packet if it fails on defense.
+ }
+ else if( sd ) // Failure on Rate
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ }
+ break;
+
+ case WL_SUMMONFB:
+ case WL_SUMMONBL:
+ case WL_SUMMONWB:
+ case WL_SUMMONSTONE:
+ {
+ short element = 0, sctype = 0, pos = -1;
+ struct status_change *sc = status_get_sc(src);
+ if( !sc ) break;
+
+ for( i = SC_SPHERE_1; i <= SC_SPHERE_5; i++ )
+ {
+ if( !sctype && !sc->data[i] )
+ sctype = i; // Take the free SC
+ if( sc->data[i] )
+ pos = max(sc->data[i]->val2,pos);
+ }
- case GM_SANDMAN:
- if (tsc) {
- if (tsc->opt1 == OPT1_SLEEP)
- tsc->opt1 = 0;
- else
- tsc->opt1 = OPT1_SLEEP;
- clif_changeoption(bl);
- clif_skill_nodamage(src, bl, skillid, skilllv, 1);
- }
- break;
+ if( !sctype )
+ {
+ if( sd ) // No free slots to put SC
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_SUMMON,0);
+ break;
+ }
- case SO_ARRULLO:
- if (flag&1)
- sc_start2(bl, type, 88 + 2 * skilllv, skilllv, 1, skill_get_time(skillid, skilllv));
- else {
- clif_skill_nodamage(src, bl, skillid, 0, 1);
- map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), BL_CHAR,
- src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_nodamage_id);
- }
- break;
+ pos++; // Used in val2 for SC. Indicates the order of this ball
+ switch( skillid )
+ { // Set val1. The SC element for this ball
+ case WL_SUMMONFB: element = WLS_FIRE; break;
+ case WL_SUMMONBL: element = WLS_WIND; break;
+ case WL_SUMMONWB: element = WLS_WATER; break;
+ case WL_SUMMONSTONE: element = WLS_STONE; break;
+ }
- case SO_SUMMON_AGNI:
- case SO_SUMMON_AQUA:
- case SO_SUMMON_VENTUS:
- case SO_SUMMON_TERA:
- if (sd) {
- int elemental_class = skill_get_elemental_type(skillid,skilllv);
-
- // Remove previous elemental fisrt.
- if (sd->ed && elemental_delete(sd->ed,0)) {
- clif_skill_fail(sd,skillid,0,0);
- break;
- }
- // Summoning the new one.
- if (!elemental_create(sd,elemental_class,skill_get_time(skillid,skilllv))) {
- clif_skill_fail(sd,skillid,0,0);
- break;
- }
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- }
- break;
+ sc_start4(src,sctype,100,element,pos,skilllv,0,skill_get_time(skillid,skilllv));
+ clif_skill_nodamage(src,bl,skillid,0,0);
+ }
+ break;
+
+ case WL_READING_SB:
+ if( sd ) {
+ struct status_change *sc = status_get_sc(bl);
+
+ for( i = SC_SPELLBOOK1; i <= SC_MAXSPELLBOOK; i++)
+ if( sc && !sc->data[i] )
+ break;
+ if( i == SC_MAXSPELLBOOK ) {
+ clif_skill_fail(sd, WL_READING_SB, USESKILL_FAIL_SPELLBOOK_READING, 0);
+ break;
+ }
- case SO_EL_CONTROL:
- if (sd) {
- int mode = EL_MODE_PASSIVE; // Standard mode.
- if (!sd->ed) {
- clif_skill_fail(sd,skillid,0,0);
- break;
- }
- if (skilllv == 4) { // At level 4 delete elementals.
- if (elemental_delete(sd->ed, 0))
- clif_skill_fail(sd,skillid,0,0);
- break;
- }
- switch (skilllv) { // Select mode bassed on skill level used.
- case 1:
- mode = EL_MODE_PASSIVE;
- break;
- case 2:
- mode = EL_MODE_ASSIST;
- break;
- case 3:
- mode = EL_MODE_AGGRESSIVE;
- break;
- }
- if (!elemental_change_mode(sd->ed,mode)) {
- clif_skill_fail(sd,skillid,0,0);
- break;
- }
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- }
- break;
+ sc_start(bl, SC_STOP, 100, skilllv, INVALID_TIMER); //Can't move while selecting a spellbook.
+ clif_spellbook_list(sd);
+ clif_skill_nodamage(src, bl, skillid, skilllv, 1);
+ }
+ break;
+ /**
+ * Ranger
+ **/
+ case RA_FEARBREEZE:
+ clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+ clif_skill_nodamage(src, bl, skillid, skilllv, sc_start(bl, type, 100, skilllv, skill_get_time(skillid, skilllv)));
+ break;
+
+ case RA_WUGMASTERY:
+ if( sd ) {
+ if( !pc_iswug(sd) )
+ pc_setoption(sd,sd->sc.option|OPTION_WUG);
+ else
+ pc_setoption(sd,sd->sc.option&~OPTION_WUG);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ }
+ break;
+
+ case RA_WUGRIDER:
+ if( sd ) {
+ if( !pc_isridingwug(sd) && pc_iswug(sd) ) {
+ pc_setoption(sd,sd->sc.option&~OPTION_WUG);
+ pc_setoption(sd,sd->sc.option|OPTION_WUGRIDER);
+ } else if( pc_isridingwug(sd) ) {
+ pc_setoption(sd,sd->sc.option&~OPTION_WUGRIDER);
+ pc_setoption(sd,sd->sc.option|OPTION_WUG);
+ }
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ }
+ break;
+
+ case RA_WUGDASH:
+ if( tsce ) {
+ clif_skill_nodamage(src,bl,skillid,skilllv,status_change_end(bl, type, INVALID_TIMER));
+ map_freeblock_unlock();
+ return 0;
+ }
+ if( sd && pc_isridingwug(sd) ) {
+ clif_skill_nodamage(src,bl,skillid,skilllv,sc_start4(bl,type,100,skilllv,unit_getdir(bl),0,0,1));
+ clif_walkok(sd);
+ }
+ break;
+
+ case RA_SENSITIVEKEEN:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ clif_skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+ map_foreachinrange(skill_area_sub,src,skill_get_splash(skillid,skilllv),BL_CHAR|BL_SKILL,src,skillid,skilllv,tick,flag|BCT_ENEMY,skill_castend_damage_id);
+ break;
+ /**
+ * Mechanic
+ **/
+ case NC_F_SIDESLIDE:
+ case NC_B_SIDESLIDE:
+ {
+ int dir = (skillid == NC_F_SIDESLIDE) ? (unit_getdir(src)+4)%8 : unit_getdir(src);
+ skill_blown(src,bl,skill_get_blewcount(skillid,skilllv),dir,0x1);
+ clif_slide(src,src->x,src->y);
+ clif_fixpos(src); //Aegis sent this packet
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ }
+ break;
+
+ case NC_SELFDESTRUCTION:
+ if( sd ) {
+ if( pc_ismadogear(sd) )
+ pc_setmadogear(sd, 0);
+ clif_skill_nodamage(src, bl, skillid, skilllv, 1);
+ skill_castend_damage_id(src, src, skillid, skilllv, tick, flag);
+ status_set_sp(src, 0, 0);
+ }
+ break;
+
+ case NC_ANALYZE:
+ clif_skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+ clif_skill_nodamage(src, bl, skillid, skilllv,
+ sc_start(bl,type, 30 + 12 * skilllv,skilllv,skill_get_time(skillid,skilllv)));
+ if( sd ) pc_overheat(sd,1);
+ break;
+
+ case NC_MAGNETICFIELD:
+ if( (i = sc_start2(bl,type,100,skilllv,src->id,skill_get_time(skillid,skilllv))) )
+ {
+ map_foreachinrange(skill_area_sub,src,skill_get_splash(skillid,skilllv),splash_target(src),src,skillid,skilllv,tick,flag|BCT_ENEMY|SD_SPLASH|1,skill_castend_damage_id);;
+ clif_skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skillid,skilllv,6);
+ if (sd) pc_overheat(sd,1);
+ }
+ clif_skill_nodamage(src,src,skillid,skilllv,i);
+ break;
+
+ case NC_REPAIR:
+ if( sd )
+ {
+ int heal;
+ if( dstsd && pc_ismadogear(dstsd) )
+ {
+ heal = dstsd->status.max_hp * (3+3*skilllv) / 100;
+ status_heal(bl,heal,0,2);
+ } else {
+ heal = sd->status.max_hp * (3+3*skilllv) / 100;
+ status_heal(src,heal,0,2);
+ }
- case SO_EL_ACTION:
- if (sd) {
- int duration = 3000;
- if (!sd->ed)
- break;
- elemental_action(sd->ed, bl, tick);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- switch(sd->ed->db->class_){
- case 2115:case 2124:
- case 2118:case 2121:
- duration = 6000;
- break;
- case 2116:case 2119:
- case 2122:case 2125:
- duration = 9000;
+ clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+ clif_skill_nodamage(src, bl, skillid, skilllv, heal);
+ }
+ break;
+
+ case NC_DISJOINT:
+ {
+ if( bl->type != BL_MOB ) break;
+ md = map_id2md(bl->id);
+ if( md && md->class_ >= MOBID_SILVERSNIPER && md->class_ <= MOBID_MAGICDECOY_WIND )
+ status_kill(bl);
+ clif_skill_nodamage(src, bl, skillid, skilllv, 1);
+ }
+ break;
+ case SC_AUTOSHADOWSPELL:
+ if( sd ) {
+ if( sd->status.skill[sd->reproduceskill_id].id || sd->status.skill[sd->cloneskill_id].id ) {
+ sc_start(src,SC_STOP,100,skilllv,-1);// The skilllv is stored in val1 used in skill_select_menu to determine the used skill lvl [Xazax]
+ clif_autoshadowspell_list(sd);
+ clif_skill_nodamage(src,bl,skillid,1,1);
+ }
+ else
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_IMITATION_SKILL_NONE,0);
+ }
+ break;
+
+ case SC_SHADOWFORM:
+ if( sd && dstsd && src != bl && !dstsd->shadowform_id ) {
+ if( clif_skill_nodamage(src,bl,skillid,skilllv,sc_start4(src,type,100,skilllv,bl->id,4+skilllv,0,skill_get_time(skillid, skilllv))) )
+ dstsd->shadowform_id = src->id;
+ }
+ else if( sd )
+ clif_skill_fail(sd, skillid, USESKILL_FAIL_LEVEL, 0);
+ break;
+
+ case SC_BODYPAINT:
+ if( flag&1 ) {
+ if( tsc && (tsc->data[SC_HIDING] || tsc->data[SC_CLOAKING] ||
+ tsc->data[SC_CHASEWALK] || tsc->data[SC_CLOAKINGEXCEED] ||
+ tsc->data[SC__INVISIBILITY]) ) {
+ status_change_end(bl, SC_HIDING, INVALID_TIMER);
+ status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
+ status_change_end(bl, SC_CHASEWALK, INVALID_TIMER);
+ status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
+ status_change_end(bl, SC__INVISIBILITY, INVALID_TIMER);
+
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv));
+ sc_start(bl,SC_BLIND,53 + 2 * skilllv,skilllv,skill_get_time(skillid,skilllv));
+ }
+ } else {
+ clif_skill_nodamage(src, bl, skillid, 0, 1);
+ map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), BL_CHAR,
+ src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_nodamage_id);
+ }
+ break;
+
+ case SC_ENERVATION:
+ case SC_GROOMY:
+ case SC_LAZINESS:
+ case SC_UNLUCKY:
+ case SC_WEAKNESS:
+ if( !(tsc && tsc->data[type]) ) {
+ //((rand(myDEX / 12, myDEX / 4) + myJobLevel + 10 * skLevel) + myLevel / 10) - (targetLevel / 10 + targetLUK / 10 + (targetMaxWeight - targetWeight) / 1000 + rand(targetAGI / 6, targetAGI / 3))
+ int rate = rnd_value(sstatus->dex/12,sstatus->dex/4) + 10*skilllv + (sd?sd->status.job_level:0) + status_get_lv(src)/10
+ - status_get_lv(bl)/10 - tstatus->luk/10 - (dstsd?(dstsd->max_weight-dstsd->weight)/10000:0) - rnd_value(tstatus->agi/6,tstatus->agi/3);
+ rate = cap_value(rate, skilllv+sstatus->dex/20, 100);
+ clif_skill_nodamage(src,bl,skillid,0,sc_start(bl,type,rate,skilllv,skill_get_time(skillid,skilllv)));
+ } else if( sd )
+ clif_skill_fail(sd,skillid,0,0);
+ break;
+
+ case SC_IGNORANCE:
+ if( !(tsc && tsc->data[type]) ) {
+ int rate = rnd_value(sstatus->dex/12,sstatus->dex/4) + 10*skilllv + (sd?sd->status.job_level:0) + status_get_lv(src)/10
+ - status_get_lv(bl)/10 - tstatus->luk/10 - (dstsd?(dstsd->max_weight-dstsd->weight)/10000:0) - rnd_value(tstatus->agi/6,tstatus->agi/3);
+ rate = cap_value(rate, skilllv+sstatus->dex/20, 100);
+ if (clif_skill_nodamage(src,bl,skillid,0,sc_start(bl,type,rate,skilllv,skill_get_time(skillid,skilllv)))) {
+ int sp = 200 * skilllv;
+ if( dstmd ) sp = dstmd->level * 2;
+ if( status_zap(bl,0,sp) )
+ status_heal(src,0,sp/2,3);
+ }
+ else if( sd ) clif_skill_fail(sd,skillid,0,0);
+ } else if( sd )
+ clif_skill_fail(sd,skillid,0,0);
+ break;
+
+ case LG_TRAMPLE:
+ clif_skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+ map_foreachinrange(skill_destroy_trap,bl,skill_get_splash(skillid,skilllv),BL_SKILL,tick);
+ break;
+
+ case LG_REFLECTDAMAGE:
+ if( tsc && tsc->data[type] )
+ status_change_end(bl,type,INVALID_TIMER);
+ else
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv));
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ break;
+
+ case LG_SHIELDSPELL:
+ if( flag&1 ) {
+ int duration = (sd) ? sd->bonus.shieldmdef * 2000 : 10000;
+ sc_start(bl,SC_SILENCE,100,skilllv,duration);
+ } else if( sd ) {
+ int opt = skilllv;
+ int rate = rnd()%100;
+ int val, brate;
+ switch( skilllv ) {
+ case 1:
+ {
+ struct item_data *shield_data = sd->inventory_data[sd->equip_index[EQI_HAND_L]];
+ if( !shield_data || shield_data->type != IT_ARMOR ) { // No shield?
+ clif_skill_fail(sd, skillid, USESKILL_FAIL_LEVEL, 0);
+ break;
+ }
+ brate = shield_data->def * 10;
+ if( rate < 50 )
+ opt = 1;
+ else if( rate < 75 )
+ opt = 2;
+ else
+ opt = 3;
+
+ switch( opt ) {
+ case 1:
+ sc_start(bl,SC_SHIELDSPELL_DEF,100,opt,-1);
+ clif_skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+ if( rate < brate )
+ map_foreachinrange(skill_area_sub,src,skill_get_splash(skillid,skilllv),BL_CHAR,src,skillid,skilllv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
+ status_change_end(bl,SC_SHIELDSPELL_DEF,INVALID_TIMER);
+ break;
+ case 2:
+ val = shield_data->def / 10; // % Reflected damage.
+ sc_start2(bl,SC_SHIELDSPELL_DEF,brate,opt,val,shield_data->def * 1000);
+ break;
+ case 3:
+ val = shield_data->def; // Attack increase.
+ sc_start2(bl,SC_SHIELDSPELL_DEF,brate,opt,val,shield_data->def * 3000);
+ break;
+ }
+ }
+ break;
+
+ case 2:
+ brate = sd->bonus.shieldmdef * 20;
+ if( rate < 30 )
+ opt = 1;
+ else if( rate < 60 )
+ opt = 2;
+ else
+ opt = 3;
+ switch( opt ) {
+ case 1:
+ sc_start(bl,SC_SHIELDSPELL_MDEF,100,opt,-1);
+ clif_skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+ if( rate < brate )
+ map_foreachinrange(skill_area_sub,src,skill_get_splash(skillid,skilllv),BL_CHAR,src,skillid,skilllv,tick,flag|BCT_ENEMY|2,skill_castend_damage_id);
+ status_change_end(bl,SC_SHIELDSPELL_MDEF,INVALID_TIMER);
+ break;
+ case 2:
+ sc_start(bl,SC_SHIELDSPELL_MDEF,100,opt,-1);
+ clif_skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+ if( rate < brate )
+ map_foreachinrange(skill_area_sub,src,skill_get_splash(skillid,skilllv),BL_CHAR,src,skillid,skilllv,tick,flag|BCT_ENEMY|1,skill_castend_nodamage_id);
+ break;
+ case 3:
+ if( sc_start(bl,SC_SHIELDSPELL_MDEF,brate,opt,sd->bonus.shieldmdef * 30000) )
+ clif_skill_nodamage(src,bl,PR_MAGNIFICAT,skilllv,
+ sc_start(bl,SC_MAGNIFICAT,100,1,sd->bonus.shieldmdef * 30000));
+ break;
+ }
+ break;
+
+ case 3:
+ {
+ struct item *it = &sd->status.inventory[sd->equip_index[EQI_HAND_L]];
+ if( !it ) { // No shield?
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
break;
+ }
+ brate = it->refine * 5;
+ if( rate < 25 )
+ opt = 1;
+ else if( rate < 50 )
+ opt = 2;
+ else
+ opt = 3;
+ switch( opt ) {
+ case 1:
+ val = 105 * it->refine / 10;
+ sc_start2(bl,SC_SHIELDSPELL_REF,brate,opt,val,skill_get_time(skillid,skilllv));
+ break;
+ case 2: case 3:
+ if( rate < brate )
+ {
+ val = sstatus->max_hp * (11 + it->refine) / 100;
+ status_heal(bl, val, 0, 3);
+ }
+ break;
+ /*case 3:
+ // Full protection. I need confirm what effect should be here. Moved to case 2 to until we got it.
+ break;*/
+ }
}
- skill_blockpc_start(sd, skillid, duration);
- }
- break;
-
- case SO_EL_CURE:
- if (sd) {
- struct elemental_data *ed = sd->ed;
- int s_hp = sd->battle_status.hp * 10 / 100, s_sp = sd->battle_status.sp * 10 / 100;
- int e_hp, e_sp;
- if (!ed) {
- clif_skill_fail(sd,skillid,0,0);
- break;
- }
- if (!status_charge(&sd->bl,s_hp,s_sp)) {
- clif_skill_fail(sd,skillid,0,0);
- break;
- }
- e_hp = ed->battle_status.max_hp * 10 / 100;
- e_sp = ed->battle_status.max_sp * 10 / 100;
- status_heal(&ed->bl,e_hp,e_sp,3);
- clif_skill_nodamage(src,&ed->bl,skillid,skilllv,1);
- }
- break;
-
- case GN_CHANGEMATERIAL:
- case SO_EL_ANALYSIS:
- if (sd) {
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- clif_skill_itemlistwindow(sd,skillid,skilllv);
- }
- break;
-
- case GN_BLOOD_SUCKER: {
- struct status_change *sc = status_get_sc(src);
-
- if (sc && sc->bs_counter < skill_get_maxcount(skillid , skilllv)) {
- if (tsc && tsc->data[type]) {
- (sc->bs_counter)--;
- status_change_end(src, type, INVALID_TIMER); // the first one cancels and the last one will take effect resetting the timer
- }
- clif_skill_nodamage(src, bl, skillid, skilllv, 1);
- sc_start2(bl, type, 100, skilllv, src->id, skill_get_time(skillid,skilllv));
- (sc->bs_counter)++;
- } else if (sd) {
- clif_skill_fail(sd, skillid, USESKILL_FAIL_LEVEL, 0);
- break;
- }
- }
- break;
-
- case GN_MANDRAGORA:
- if (flag&1) {
- if (clif_skill_nodamage(bl, src, skillid, skilllv,
- sc_start(bl, type, 25 + 10 * skilllv, skilllv, skill_get_time(skillid, skilllv))))
- status_zap(bl, 0, status_get_max_sp(bl) * (25 + 5 * skilllv) / 100);
- } else
- map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), BL_CHAR,
- src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_nodamage_id);
- break;
-
- case GN_SLINGITEM:
- if (sd) {
- short ammo_id;
- i = sd->equip_index[EQI_AMMO];
- if (i <= 0)
- break; // No ammo.
- ammo_id = sd->inventory_data[i]->nameid;
- if (ammo_id <= 0)
- break;
- sd->itemid = ammo_id;
- if (itemdb_is_GNbomb(ammo_id)) {
- if (battle_check_target(src,bl,BCT_ENEMY) > 0) { // Only attack if the target is an enemy.
- if (ammo_id == 13263)
- map_foreachincell(skill_area_sub,bl->m,bl->x,bl->y,BL_CHAR,src,GN_SLINGITEM_RANGEMELEEATK,skilllv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
- else
- skill_attack(BF_WEAPON,src,src,bl,GN_SLINGITEM_RANGEMELEEATK,skilllv,tick,flag);
- } else //Otherwise, it fails, shows animation and removes items.
- clif_skill_fail(sd,GN_SLINGITEM_RANGEMELEEATK,0xa,0);
- } else if (itemdb_is_GNthrowable(ammo_id)) {
- struct script_code *script = sd->inventory_data[i]->script;
- if (!script)
- break;
- if (dstsd)
- run_script(script,0,dstsd->bl.id,fake_nd->bl.id);
- else
- run_script(script,0,src->id,0);
- }
- }
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);// This packet is received twice actually, I think it is to show the animation.
- break;
-
- case GN_MIX_COOKING:
- case GN_MAKEBOMB:
- case GN_S_PHARMACY:
- if (sd) {
- int qty = 1;
- sd->skillid_old = skillid;
- sd->skilllv_old = skilllv;
- if (skillid != GN_S_PHARMACY && skilllv > 1)
- qty = 10;
- clif_cooking_list(sd,(skillid - GN_MIX_COOKING) + 27,skillid,qty,skillid==GN_MAKEBOMB?5:6);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- }
- break;
- case EL_CIRCLE_OF_FIRE:
- case EL_PYROTECHNIC:
- case EL_HEATER:
- case EL_TROPIC:
- case EL_AQUAPLAY:
- case EL_COOLER:
- case EL_CHILLY_AIR:
- case EL_GUST:
- case EL_BLAST:
- case EL_WILD_STORM:
- case EL_PETROLOGY:
- case EL_CURSED_SOIL:
- case EL_UPHEAVAL:
- case EL_FIRE_CLOAK:
- case EL_WATER_DROP:
- case EL_WIND_CURTAIN:
- case EL_SOLID_SKIN:
- case EL_STONE_SHIELD:
- case EL_WIND_STEP: {
- struct elemental_data *ele = BL_CAST(BL_ELEM, src);
- if (ele) {
- sc_type type2 = type-1;
- struct status_change *sc = status_get_sc(&ele->bl);
-
- if ((sc && sc->data[type2]) || (tsc && tsc->data[type])) {
- elemental_clean_single_effect(ele, skillid);
- } else {
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
- if (skillid == EL_WIND_STEP) // There aren't telemport, just push to the master.
- skill_blown(src,bl,skill_get_blewcount(skillid,skilllv),(map_calc_dir(src,bl->x,bl->y)+4)%8,0);
- sc_start(src,type2,100,skilllv,skill_get_time(skillid,skilllv));
- sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv));
- }
- }
- }
- break;
-
- case EL_FIRE_MANTLE:
- case EL_WATER_BARRIER:
- case EL_ZEPHYR:
- case EL_POWER_OF_GAIA:
- clif_skill_nodamage(src,src,skillid,skilllv,1);
- clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
- skill_unitsetting(src,skillid,skilllv,bl->x,bl->y,0);
- break;
-
- case EL_WATER_SCREEN: {
- struct elemental_data *ele = BL_CAST(BL_ELEM, src);
- if (ele) {
- struct status_change *sc = status_get_sc(&ele->bl);
- sc_type type2 = type-1;
-
- clif_skill_nodamage(src,src,skillid,skilllv,1);
- if ((sc && sc->data[type2]) || (tsc && tsc->data[type])) {
- elemental_clean_single_effect(ele, skillid);
- } else {
- // This not heals at the end.
- clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
- sc_start(src,type2,100,skilllv,skill_get_time(skillid,skilllv));
- sc_start(bl,type,100,src->id,skill_get_time(skillid,skilllv));
- }
- }
- }
- break;
+ break;
+ }
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ }
+ break;
+
+ case LG_PIETY:
+ if( flag&1 )
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv));
+ else {
+ skill_area_temp[2] = 0;
+ map_foreachinrange(skill_area_sub,bl,skill_get_splash(skillid,skilllv),BL_PC,src,skillid,skilllv,tick,flag|SD_PREAMBLE|BCT_PARTY|BCT_SELF|1,skill_castend_nodamage_id);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ }
+ break;
+
+ case LG_INSPIRATION:
+ if( sd && !map[sd->bl.m].flag.noexppenalty && sd->status.base_level != MAX_LEVEL ) {
+ sd->status.base_exp -= min(sd->status.base_exp, pc_nextbaseexp(sd) * 1 / 100); // 1% penalty.
+ sd->status.job_exp -= min(sd->status.job_exp, pc_nextjobexp(sd) * 1 / 100);
+ clif_updatestatus(sd,SP_BASEEXP);
+ clif_updatestatus(sd,SP_JOBEXP);
+ }
+ clif_skill_nodamage(bl,src,skillid,skilllv,
+ sc_start(bl, type, 100, skilllv, skill_get_time(skillid, skilllv)));
+ break;
+ case SR_CURSEDCIRCLE:
+ if( flag&1 ) {
+ if( is_boss(bl) ) break;
+ if( sc_start2(bl, type, 100, skilllv, src->id, skill_get_time(skillid, skilllv))) {
+ if( bl->type == BL_MOB )
+ mob_unlocktarget((TBL_MOB*)bl,gettick());
+ unit_stop_attack(bl);
+ clif_bladestop(src, bl->id, 1);
+ map_freeblock_unlock();
+ return 1;
+ }
+ } else {
+ int count = 0;
+ clif_skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+ count = map_forcountinrange(skill_area_sub, src, skill_get_splash(skillid,skilllv), (sd)?sd->spiritball_old:15, // Assume 15 spiritballs in non-charactors
+ BL_CHAR, src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_nodamage_id);
+ if( sd ) pc_delspiritball(sd, count, 0);
+ clif_skill_nodamage(src, src, skillid, skilllv,
+ sc_start2(src, SC_CURSEDCIRCLE_ATKER, 100, skilllv, count, skill_get_time(skillid,skilllv)));
+ }
+ break;
+
+ case SR_RAISINGDRAGON:
+ if( sd ) {
+ short max = 5 + skilllv;
+ sc_start(bl, SC_EXPLOSIONSPIRITS, 100, skilllv, skill_get_time(skillid, skilllv));
+ for( i = 0; i < max; i++ ) // Don't call more than max available spheres.
+ pc_addspiritball(sd, skill_get_time(skillid, skilllv), max);
+ clif_skill_nodamage(src, bl, skillid, skilllv, sc_start(bl, type, 100, skilllv,skill_get_time(skillid, skilllv)));
+ }
+ break;
+
+ case SR_ASSIMILATEPOWER:
+ if( flag&1 ) {
+ i = 0;
+ if( dstsd && dstsd->spiritball && (sd == dstsd || map_flag_vs(src->m)) && (dstsd->class_&MAPID_BASEMASK)!=MAPID_GUNSLINGER )
+ {
+ i = dstsd->spiritball; //1%sp per spiritball.
+ pc_delspiritball(dstsd, dstsd->spiritball, 0);
+ }
+ if( i ) status_percent_heal(src, 0, i);
+ clif_skill_nodamage(src, bl, skillid, skilllv, i ? 1:0);
+ } else {
+ clif_skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+ map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), splash_target(src), src, skillid, skilllv, tick, flag|BCT_ENEMY|BCT_SELF|SD_SPLASH|1, skill_castend_nodamage_id);
+ }
+ break;
+
+ case SR_POWERVELOCITY:
+ if( !dstsd )
+ break;
+ if( sd && dstsd->spiritball <= 5 ) {
+ for(i = 0; i <= 5; i++) {
+ pc_addspiritball(dstsd, skill_get_time(MO_CALLSPIRITS, pc_checkskill(sd,MO_CALLSPIRITS)), i);
+ pc_delspiritball(sd, sd->spiritball, 0);
+ }
+ }
+ clif_skill_nodamage(src, bl, skillid, skilllv, 1);
+ break;
- case KO_KAHU_ENTEN:
- case KO_HYOUHU_HUBUKI:
- case KO_KAZEHU_SEIRAN:
- case KO_DOHU_KOUKAI:
- if (sd) {
- int ttype = skill_get_ele(skillid, skilllv);
- clif_skill_nodamage(src, bl, skillid, skilllv, 1);
- pc_add_talisman(sd, skill_get_time(skillid, skilllv), 10, ttype);
- }
- break;
+ case SR_GENTLETOUCH_CURE:
+ {
+ int heal;
- case KO_ZANZOU:
- if (sd) {
- struct mob_data *md;
-
- md = mob_once_spawn_sub(src, src->m, src->x, src->y, status_get_name(src), 2308, "", SZ_SMALL, AI_NONE);
- if (md) {
- md->master_id = src->id;
- md->special_state.ai = AI_ZANZOU;
- if (md->deletetimer != INVALID_TIMER)
- delete_timer(md->deletetimer, mob_timer_delete);
- md->deletetimer = add_timer(gettick() + skill_get_time(skillid, skilllv), mob_timer_delete, md->bl.id, 0);
- mob_spawn(md);
- pc_setinvincibletimer(sd,500);// unlock target lock
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- skill_blown(src,bl,skill_get_blewcount(skillid,skilllv),unit_getdir(bl),0);
- }
- }
- break;
+ if( status_isimmune(bl) )
+ {
+ clif_skill_nodamage(src,bl,skillid,skilllv,0);
+ break;
+ }
- case KO_KYOUGAKU:
- if (dstsd && tsc && !tsc->data[type] && rand()%100 < tstatus->int_/2) {
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
- } else if (sd)
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
+ heal = 120 * skilllv + status_get_max_hp(bl) * (2 + skilllv) / 100;
+ status_heal(bl, heal, 0, 0);
- case KO_JYUSATSU:
- if (dstsd && tsc && !tsc->data[type] &&
- rand()%100 < ((45+5*skilllv) + skilllv*5 - status_get_int(bl)/2)) {//[(Base chance of success) + (Skill Level x 5) - (int / 2)]%.
- clif_skill_nodamage(src,bl,skillid,skilllv,
- status_change_start(bl,type,10000,skilllv,0,0,0,skill_get_time(skillid,skilllv),1));
- status_zap(bl, tstatus->max_hp*skilllv*5/100 , 0);
- if (status_get_lv(bl) <= status_get_lv(src))
- status_change_start(bl,SC_COMA,10,skilllv,0,src->id,0,0,0);
- } else if (sd)
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
+ if( (tsc && tsc->opt1) && (rnd()%100 < ((skilllv * 5) + (status_get_dex(src) + status_get_lv(src)) / 4) - (1 + (rnd() % 10))) )
+ {
+ status_change_end(bl, SC_STONE, INVALID_TIMER);
+ status_change_end(bl, SC_FREEZE, INVALID_TIMER);
+ status_change_end(bl, SC_STUN, INVALID_TIMER);
+ status_change_end(bl, SC_POISON, INVALID_TIMER);
+ status_change_end(bl, SC_SILENCE, INVALID_TIMER);
+ status_change_end(bl, SC_BLIND, INVALID_TIMER);
+ status_change_end(bl, SC_HALLUCINATION, INVALID_TIMER);
+ status_change_end(bl, SC_BURNING, INVALID_TIMER);
+ status_change_end(bl, SC_FREEZING, INVALID_TIMER);
+ }
- case KO_GENWAKU:
- if (!map_flag_gvg(src->m) && (dstsd || dstmd) && battle_check_target(src,bl,BCT_ENEMY) > 0) {
- int x = src->x, y = src->y;
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ }
+ break;
+ case SR_GENTLETOUCH_CHANGE:
+ case SR_GENTLETOUCH_REVITALIZE:
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start2(bl,type,100,skilllv,src->id,skill_get_time(skillid,skilllv)));
+ break;
+ case WA_SWING_DANCE:
+ case WA_MOONLIT_SERENADE:
+ if( sd == NULL || sd->status.party_id == 0 || (flag & 1) )
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv));
+ else if( sd ) { // Only shows effects on caster.
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ party_foreachsamemap(skill_area_sub, sd, skill_get_splash(skillid, skilllv), src, skillid, skilllv, tick, flag|BCT_PARTY|1, skill_castend_nodamage_id);
+ }
+ break;
+
+ case WA_SYMPHONY_OF_LOVER:
+ case MI_RUSH_WINDMILL:
+ case MI_ECHOSONG:
+ if( sd == NULL || sd->status.party_id == 0 || (flag & 1) )
+ sc_start4(bl,type,100,skilllv,6*skilllv,(sd?pc_checkskill(sd,WM_LESSON):0),(sd?sd->status.job_level:0),skill_get_time(skillid,skilllv));
+ else if( sd ) { // Only shows effects on caster.
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ party_foreachsamemap(skill_area_sub, sd, skill_get_splash(skillid, skilllv), src, skillid, skilllv, tick, flag|BCT_PARTY|1, skill_castend_nodamage_id);
+ }
+ break;
+
+ case MI_HARMONIZE:
+ if( src != bl )
+ clif_skill_nodamage(src, src, skillid, skilllv, sc_start(src, type, 100, skilllv, skill_get_time(skillid,skilllv)));
+ clif_skill_nodamage(src, bl, skillid, skilllv, sc_start(bl, type, 100, skilllv, skill_get_time(skillid,skilllv)));
+ break;
+
+ case WM_DEADHILLHERE:
+ if( bl->type == BL_PC ) {
+ if( !status_isdead(bl) )
+ break;
+
+ if( rnd()%100 < 88 + 2 * skilllv ) {
+ int heal = tstatus->sp;
+ if( heal <= 0 )
+ heal = 1;
+ tstatus->hp = heal;
+ tstatus->sp -= tstatus->sp * ( 120 - 20 * skilllv ) / 100;
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ pc_revive((TBL_PC*)bl,heal,0);
+ clif_resurrection(bl,1);
+ }
+ }
+ break;
+
+ case WM_SIRCLEOFNATURE:
+ flag |= BCT_SELF|BCT_PARTY|BCT_GUILD;
+ case WM_VOICEOFSIREN:
+ if( skillid != WM_SIRCLEOFNATURE )
+ flag &= ~BCT_SELF;
+ if( flag&1 ) {
+ sc_start2(bl,type,(skillid==WM_VOICEOFSIREN)?20+10*skilllv:100,skilllv,(skillid==WM_VOICEOFSIREN)?src->id:0,skill_get_time(skillid,skilllv));
+ } else {
+ map_foreachinrange(skill_area_sub, src, skill_get_splash(skillid,skilllv),(skillid==WM_VOICEOFSIREN)?BL_CHAR|BL_SKILL:BL_PC, src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_nodamage_id);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ }
+ break;
+
+ case WM_GLOOMYDAY:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ if( dstsd && ( pc_checkskill(dstsd,KN_BRANDISHSPEAR) || pc_checkskill(dstsd,LK_SPIRALPIERCE) ||
+ pc_checkskill(dstsd,CR_SHIELDCHARGE) || pc_checkskill(dstsd,CR_SHIELDBOOMERANG) ||
+ pc_checkskill(dstsd,PA_SHIELDCHAIN) || pc_checkskill(dstsd,LG_SHIELDPRESS) ) )
+ {
+ sc_start(bl,SC_GLOOMYDAY_SK,100,skilllv,skill_get_time(skillid,skilllv));
+ break;
+ }
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv));
+ break;
+
+ case WM_SATURDAY_NIGHT_FEVER:
+ if( flag&1 ) { // Affect to all targets arround the caster and caster too.
+ if( !(tsc && tsc->data[type]) )
+ sc_start(bl, type, 100, skilllv,skill_get_time(skillid, skilllv));
+ } else if( flag&2 ) {
+ if( src->id != bl->id && battle_check_target(src,bl,BCT_ENEMY) > 0 )
+ status_fix_damage(src,bl,9999,clif_damage(src,bl,tick,0,0,9999,0,0,0));
+ } else if( sd ) {
+ short chance = sstatus->int_/6 + sd->status.job_level/5 + skilllv*4;
+ if( !sd->status.party_id || (rnd()%100 > chance)) {
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_NEED_HELPER,0);
+ break;
+ }
+ if( map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid,skilllv),
+ BL_PC, src, skillid, skilllv, tick, BCT_ENEMY, skill_area_sub_count) > 7 )
+ flag |= 2;
+ else
+ flag |= 1;
+ map_foreachinrange(skill_area_sub, src, skill_get_splash(skillid,skilllv),BL_PC, src, skillid, skilllv, tick, flag|BCT_ENEMY|BCT_SELF, skill_castend_nodamage_id);
+ clif_skill_nodamage(src, bl, skillid, skilllv,
+ sc_start(src,SC_STOP,100,skilllv,skill_get_time2(skillid,skilllv)));
+ if( flag&2 ) // Dealed here to prevent conflicts
+ status_fix_damage(src,bl,9999,clif_damage(src,bl,tick,0,0,9999,0,0,0));
+ }
+ break;
+
+ case WM_SONG_OF_MANA:
+ case WM_DANCE_WITH_WUG:
+ case WM_LERADS_DEW:
+ if( flag&1 ) { // These affect to to all party members near the caster.
+ struct status_change *sc = status_get_sc(src);
+ if( sc && sc->data[type] ) {
+ sc_start2(bl,type,100,skilllv,sc->data[type]->val2,skill_get_time(skillid,skilllv));
+ }
+ } else if( sd ) {
+ short lv = (short)skilllv;
+ int count = skill_check_pc_partner(sd,skillid,&lv,skill_get_splash(skillid,skilllv),1);
+ if( sc_start2(bl,type,100,skilllv,count,skill_get_time(skillid,skilllv)) )
+ party_foreachsamemap(skill_area_sub,sd,skill_get_splash(skillid,skilllv),src,skillid,skilllv,tick,flag|BCT_PARTY|1,skill_castend_nodamage_id);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+
+ }
+ break;
+
+ case WM_MELODYOFSINK:
+ case WM_BEYOND_OF_WARCRY:
+ case WM_UNLIMITED_HUMMING_VOICE:
+ if( flag&1 ) {
+ sc_start2(bl,type,100,skilllv,skill_area_temp[0],skill_get_time(skillid,skilllv));
+ } else { // These affect to all targets arround the caster.
+ short lv = (short)skilllv;
+ skill_area_temp[0] = (sd) ? skill_check_pc_partner(sd,skillid,&lv,skill_get_splash(skillid,skilllv),1) : 50; // 50% chance in non BL_PC (clones).
+ map_foreachinrange(skill_area_sub, src, skill_get_splash(skillid,skilllv),BL_PC, src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_nodamage_id);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ }
+ break;
+
+ case WM_RANDOMIZESPELL: {
+ int improv_skillid = 0, improv_skilllv;
+ do {
+ i = rnd() % MAX_SKILL_IMPROVISE_DB;
+ improv_skillid = skill_improvise_db[i].skillid;
+ } while( improv_skillid == 0 || rnd()%10000 >= skill_improvise_db[i].per );
+ improv_skilllv = 4 + skilllv;
+ clif_skill_nodamage (src, bl, skillid, skilllv, 1);
+
+ if( sd ) {
+ sd->state.abra_flag = 2;
+ sd->skillitem = improv_skillid;
+ sd->skillitemlv = improv_skilllv;
+ clif_item_skill(sd, improv_skillid, improv_skilllv);
+ } else {
+ struct unit_data *ud = unit_bl2ud(src);
+ int inf = skill_get_inf(improv_skillid);
+ int target_id = 0;
+ if (!ud) break;
+ if (inf&INF_SELF_SKILL || inf&INF_SUPPORT_SKILL) {
+ if (src->type == BL_PET)
+ bl = (struct block_list*)((TBL_PET*)src)->msd;
+ if (!bl) bl = src;
+ unit_skilluse_id(src, bl->id, improv_skillid, improv_skilllv);
+ } else {
+ if (ud->target)
+ target_id = ud->target;
+ else switch (src->type) {
+ case BL_MOB: target_id = ((TBL_MOB*)src)->target_id; break;
+ case BL_PET: target_id = ((TBL_PET*)src)->target_id; break;
+ }
+ if (!target_id)
+ break;
+ if (skill_get_casttype(improv_skillid) == CAST_GROUND) {
+ bl = map_id2bl(target_id);
+ if (!bl) bl = src;
+ unit_skilluse_pos(src, bl->x, bl->y, improv_skillid, improv_skilllv);
+ } else
+ unit_skilluse_id(src, target_id, improv_skillid, improv_skilllv);
+ }
+ }
+ }
+ break;
- if (sd && rnd()%100 > ((45+5*skilllv) - status_get_int(bl)/10)) {//[(Base chance of success) - (Intelligence Objectives / 10)]%.
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
- if (unit_movepos(src,bl->x,bl->y,0,0)) {
- clif_skill_nodamage(src,src,skillid,skilllv,1);
- clif_slide(src,bl->x,bl->y) ;
- sc_start(src,SC_CONFUSION,80,skilllv,skill_get_time(skillid,skilllv));
- if (unit_movepos(bl,x,y,0,0)) {
- clif_skill_damage(bl,bl,tick, status_get_amotion(src), 0, -30000, 1, skillid, -1, 6);
- if (bl->type == BL_PC && pc_issit((TBL_PC *)bl))
- clif_sitting(bl); //Avoid sitting sync problem
- clif_slide(bl,x,y) ;
- sc_start(bl,SC_CONFUSION,80,skilllv,skill_get_time(skillid,skilllv));
- }
- }
- }
- break;
+ case RETURN_TO_ELDICASTES:
+ case ALL_GUARDIAN_RECALL:
+ if( sd )
+ {
+ short x, y; // Destiny position.
+ unsigned short mapindex;
- case OB_AKAITSUKI:
- case OB_OBOROGENSOU:
- if (sd && ((skillid == OB_OBOROGENSOU && bl->type == BL_MOB) // This skill does not work on monsters.
- || is_boss(bl))) { // Does not work on Boss monsters.
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
- case KO_IZAYOI:
- case OB_ZANGETSU:
- case KG_KYOMU:
- case KG_KAGEMUSYA:
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
- clif_skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
- break;
+ if( skillid == RETURN_TO_ELDICASTES)
+ {
+ x = 198;
+ y = 187;
+ mapindex = mapindex_name2id(MAP_DICASTES);
+ }
+ else
+ {
+ x = 44;
+ y = 151;
+ mapindex = mapindex_name2id(MAP_MORA);
+ }
- case KG_KAGEHUMI:
- if (flag&1) {
- if (tsc && (tsc->option&(OPTION_CLOAK|OPTION_HIDE) ||
- tsc->data[SC_CAMOUFLAGE] || tsc->data[SC__SHADOWFORM] ||
- tsc->data[SC_MARIONETTE] || tsc->data[SC_HARMONIZE])) {
- sc_start(src, type, 100, skilllv, skill_get_time(skillid, skilllv));
- sc_start(bl, type, 100, skilllv, skill_get_time(skillid, skilllv));
- status_change_end(bl, SC_HIDING, INVALID_TIMER);
- status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
- status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
- status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER);
- status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
- status_change_end(bl, SC_MARIONETTE, INVALID_TIMER);
- status_change_end(bl, SC_HARMONIZE, INVALID_TIMER);
- }
- if (skill_area_temp[2] == 1) {
- clif_skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
- sc_start(src, SC_STOP, 100, skilllv, skill_get_time(skillid, skilllv));
- }
- } else {
- skill_area_temp[2] = 0;
- map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), splash_target(src), src, skillid, skilllv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill_castend_nodamage_id);
- }
- break;
+ if(!mapindex)
+ { //Given map not found?
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ map_freeblock_unlock();
+ return 0;
+ }
+ pc_setpos(sd, mapindex, x, y, CLR_TELEPORT);
+ }
+ break;
+
+ case GM_SANDMAN:
+ if( tsc ) {
+ if( tsc->opt1 == OPT1_SLEEP )
+ tsc->opt1 = 0;
+ else
+ tsc->opt1 = OPT1_SLEEP;
+ clif_changeoption(bl);
+ clif_skill_nodamage (src, bl, skillid, skilllv, 1);
+ }
+ break;
+
+ case SO_ARRULLO:
+ if( flag&1 )
+ sc_start2(bl, type, 88 + 2 * skilllv, skilllv, 1, skill_get_time(skillid, skilllv));
+ else {
+ clif_skill_nodamage(src, bl, skillid, 0, 1);
+ map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), BL_CHAR,
+ src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_nodamage_id);
+ }
+ break;
+
+ case SO_SUMMON_AGNI:
+ case SO_SUMMON_AQUA:
+ case SO_SUMMON_VENTUS:
+ case SO_SUMMON_TERA:
+ if( sd ) {
+ int elemental_class = skill_get_elemental_type(skillid,skilllv);
+
+ // Remove previous elemental fisrt.
+ if( sd->ed && elemental_delete(sd->ed,0) ) {
+ clif_skill_fail(sd,skillid,0,0);
+ break;
+ }
+ // Summoning the new one.
+ if( !elemental_create(sd,elemental_class,skill_get_time(skillid,skilllv)) ) {
+ clif_skill_fail(sd,skillid,0,0);
+ break;
+ }
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ }
+ break;
+
+ case SO_EL_CONTROL:
+ if( sd ) {
+ int mode = EL_MODE_PASSIVE; // Standard mode.
+ if( !sd->ed ) {
+ clif_skill_fail(sd,skillid,0,0);
+ break;
+ }
+ if( skilllv == 4 ) {// At level 4 delete elementals.
+ if( elemental_delete(sd->ed, 0) )
+ clif_skill_fail(sd,skillid,0,0);
+ break;
+ }
+ switch( skilllv ) {// Select mode bassed on skill level used.
+ case 1: mode = EL_MODE_PASSIVE; break;
+ case 2: mode = EL_MODE_ASSIST; break;
+ case 3: mode = EL_MODE_AGGRESSIVE; break;
+ }
+ if( !elemental_change_mode(sd->ed,mode) ) {
+ clif_skill_fail(sd,skillid,0,0);
+ break;
+ }
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ }
+ break;
+
+ case SO_EL_ACTION:
+ if( sd ) {
+ if( !sd->ed )
+ break;
+ elemental_action(sd->ed, bl, tick);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ }
+ break;
+
+ case SO_EL_CURE:
+ if( sd ) {
+ struct elemental_data *ed = sd->ed;
+ int s_hp = sd->battle_status.hp * 10 / 100, s_sp = sd->battle_status.sp * 10 / 100;
+ int e_hp, e_sp;
+ if( !ed ) {
+ clif_skill_fail(sd,skillid,0,0);
+ break;
+ }
+ if( !status_charge(&sd->bl,s_hp,s_sp) ) {
+ clif_skill_fail(sd,skillid,0,0);
+ break;
+ }
+ e_hp = ed->battle_status.max_hp * 10 / 100;
+ e_sp = ed->battle_status.max_sp * 10 / 100;
+ status_heal(&ed->bl,e_hp,e_sp,3);
+ clif_skill_nodamage(src,&ed->bl,skillid,skilllv,1);
+ }
+ break;
+
+ case GN_CHANGEMATERIAL:
+ case SO_EL_ANALYSIS:
+ if( sd ) {
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ clif_skill_itemlistwindow(sd,skillid,skilllv);
+ }
+ break;
+
+ case GN_BLOOD_SUCKER:
+ {
+ struct status_change *sc = status_get_sc(src);
+
+ if( sc && sc->bs_counter < skill_get_maxcount( skillid , skilllv) ) {
+ if( tsc && tsc->data[type] ){
+ (sc->bs_counter)--;
+ status_change_end(src, type, INVALID_TIMER); // the first one cancels and the last one will take effect resetting the timer
+ }
+ clif_skill_nodamage(src, bl, skillid, skilllv, 1);
+ sc_start2(bl, type, 100, skilllv, src->id, skill_get_time(skillid,skilllv));
+ (sc->bs_counter)++;
+ } else if( sd ) {
+ clif_skill_fail(sd, skillid, USESKILL_FAIL_LEVEL, 0);
+ break;
+ }
+ }
+ break;
+
+ case GN_MANDRAGORA:
+ if( flag&1 ) {
+ if ( clif_skill_nodamage(bl, src, skillid, skilllv,
+ sc_start(bl, type, 25 + 10 * skilllv, skilllv, skill_get_time(skillid, skilllv))) )
+ status_zap(bl, 0, status_get_max_sp(bl) * (25 + 5 * skilllv) / 100);
+ } else
+ map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), BL_CHAR,
+ src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_nodamage_id);
+ break;
+
+ case GN_SLINGITEM:
+ if( sd ) {
+ short ammo_id;
+ i = sd->equip_index[EQI_AMMO];
+ if( i <= 0 )
+ break; // No ammo.
+ ammo_id = sd->inventory_data[i]->nameid;
+ if( ammo_id <= 0 )
+ break;
+ sd->itemid = ammo_id;
+ if( itemdb_is_GNbomb(ammo_id) ) {
+ if(battle_check_target(src,bl,BCT_ENEMY) > 0) {// Only attack if the target is an enemy.
+ if( ammo_id == 13263 )
+ map_foreachincell(skill_area_sub,bl->m,bl->x,bl->y,BL_CHAR,src,GN_SLINGITEM_RANGEMELEEATK,skilllv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
+ else
+ skill_attack(BF_WEAPON,src,src,bl,GN_SLINGITEM_RANGEMELEEATK,skilllv,tick,flag);
+ } else //Otherwise, it fails, shows animation and removes items.
+ clif_skill_fail(sd,GN_SLINGITEM_RANGEMELEEATK,0xa,0);
+ } else if( itemdb_is_GNthrowable(ammo_id) ){
+ struct script_code *script = sd->inventory_data[i]->script;
+ if( !script )
+ break;
+ if( dstsd )
+ run_script(script,0,dstsd->bl.id,fake_nd->bl.id);
+ else
+ run_script(script,0,src->id,0);
+ }
+ }
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);// This packet is received twice actually, I think it is to show the animation.
+ break;
+
+ case GN_MIX_COOKING:
+ case GN_MAKEBOMB:
+ case GN_S_PHARMACY:
+ if( sd ) {
+ int qty = 1;
+ sd->skillid_old = skillid;
+ sd->skilllv_old = skilllv;
+ if( skillid != GN_S_PHARMACY && skilllv > 1 )
+ qty = 10;
+ clif_cooking_list(sd,(skillid - GN_MIX_COOKING) + 27,skillid,qty,skillid==GN_MAKEBOMB?5:6);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ }
+ break;
+ case EL_CIRCLE_OF_FIRE:
+ case EL_PYROTECHNIC:
+ case EL_HEATER:
+ case EL_TROPIC:
+ case EL_AQUAPLAY:
+ case EL_COOLER:
+ case EL_CHILLY_AIR:
+ case EL_GUST:
+ case EL_BLAST:
+ case EL_WILD_STORM:
+ case EL_PETROLOGY:
+ case EL_CURSED_SOIL:
+ case EL_UPHEAVAL:
+ case EL_FIRE_CLOAK:
+ case EL_WATER_DROP:
+ case EL_WIND_CURTAIN:
+ case EL_SOLID_SKIN:
+ case EL_STONE_SHIELD:
+ case EL_WIND_STEP: {
+ struct elemental_data *ele = BL_CAST(BL_ELEM, src);
+ if( ele ) {
+ sc_type type2 = type-1;
+ struct status_change *sc = status_get_sc(&ele->bl);
+
+ if( (sc && sc->data[type2]) || (tsc && tsc->data[type]) ) {
+ elemental_clean_single_effect(ele, skillid);
+ } else {
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+ if( skillid == EL_WIND_STEP ) // There aren't telemport, just push to the master.
+ skill_blown(src,bl,skill_get_blewcount(skillid,skilllv),(map_calc_dir(src,bl->x,bl->y)+4)%8,0);
+ sc_start(src,type2,100,skilllv,skill_get_time(skillid,skilllv));
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv));
+ }
+ }
+ }
+ break;
+
+ case EL_FIRE_MANTLE:
+ case EL_WATER_BARRIER:
+ case EL_ZEPHYR:
+ case EL_POWER_OF_GAIA:
+ clif_skill_nodamage(src,src,skillid,skilllv,1);
+ clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+ skill_unitsetting(src,skillid,skilllv,bl->x,bl->y,0);
+ break;
+
+ case EL_WATER_SCREEN: {
+ struct elemental_data *ele = BL_CAST(BL_ELEM, src);
+ if( ele ) {
+ struct status_change *sc = status_get_sc(&ele->bl);
+ sc_type type2 = type-1;
+
+ clif_skill_nodamage(src,src,skillid,skilllv,1);
+ if( (sc && sc->data[type2]) || (tsc && tsc->data[type]) ) {
+ elemental_clean_single_effect(ele, skillid);
+ } else {
+ // This not heals at the end.
+ clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+ sc_start(src,type2,100,skilllv,skill_get_time(skillid,skilllv));
+ sc_start(bl,type,100,src->id,skill_get_time(skillid,skilllv));
+ }
+ }
+ }
+ break;
+
+ case KO_KAHU_ENTEN:
+ case KO_HYOUHU_HUBUKI:
+ case KO_KAZEHU_SEIRAN:
+ case KO_DOHU_KOUKAI:
+ if(sd) {
+ int ttype = skill_get_ele(skillid, skilllv);
+ clif_skill_nodamage(src, bl, skillid, skilllv, 1);
+ pc_add_talisman(sd, skill_get_time(skillid, skilllv), 10, ttype);
+ }
+ break;
+
+ case KO_ZANZOU:
+ if(sd){
+ struct mob_data *md;
+
+ md = mob_once_spawn_sub(src, src->m, src->x, src->y, status_get_name(src), 2308, "", SZ_SMALL, AI_NONE);
+ if( md )
+ {
+ md->master_id = src->id;
+ md->special_state.ai = AI_ZANZOU;
+ if( md->deletetimer != INVALID_TIMER )
+ delete_timer(md->deletetimer, mob_timer_delete);
+ md->deletetimer = add_timer (gettick() + skill_get_time(skillid, skilllv), mob_timer_delete, md->bl.id, 0);
+ mob_spawn( md );
+ pc_setinvincibletimer(sd,500);// unlock target lock
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ skill_blown(src,bl,skill_get_blewcount(skillid,skilllv),unit_getdir(bl),0);
+ }
+ }
+ break;
+
+ case KO_KYOUGAKU:
+ if( dstsd && tsc && !tsc->data[type] && rand()%100 < tstatus->int_/2 ){
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
+ }else if( sd )
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+
+ case KO_JYUSATSU:
+ if( dstsd && tsc && !tsc->data[type] &&
+ rand()%100 < ((45+5*skilllv) + skilllv*5 - status_get_int(bl)/2) ){//[(Base chance of success) + (Skill Level x 5) - (int / 2)]%.
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ status_change_start(bl,type,10000,skilllv,0,0,0,skill_get_time(skillid,skilllv),1));
+ status_zap(bl, tstatus->max_hp*skilllv*5/100 , 0);
+ if( status_get_lv(bl) <= status_get_lv(src) )
+ status_change_start(bl,SC_COMA,10,skilllv,0,src->id,0,0,0);
+ }else if( sd )
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+
+ case KO_GENWAKU:
+ if ( !map_flag_gvg(src->m) && ( dstsd || dstmd ) && battle_check_target(src,bl,BCT_ENEMY) > 0 ) {
+ int x = src->x, y = src->y;
+
+ if( sd && rnd()%100 > ((45+5*skilllv) - status_get_int(bl)/10) ){//[(Base chance of success) - (Intelligence Objectives / 10)]%.
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
- case MH_SILENT_BREEZE: {
- struct status_change *ssc = status_get_sc(src);
- struct block_list *m_bl = battle_get_master(src);
- const enum sc_type scs[] = {
- SC_MANDRAGORA, SC_HARMONIZE, SC_DEEPSLEEP, SC_VOICEOFSIREN, SC_SLEEP, SC_CONFUSION, SC_HALLUCINATION
- };
- int heal;
- if (tsc) {
- for (i = 0; i < ARRAYLENGTH(scs); i++) {
- if (tsc->data[scs[i]]) status_change_end(bl, scs[i], INVALID_TIMER);
- }
- if (!tsc->data[SC_SILENCE]) //put inavoidable silence on target
+ if (unit_movepos(src,bl->x,bl->y,0,0)) {
+ clif_skill_nodamage(src,src,skillid,skilllv,1);
+ clif_slide(src,bl->x,bl->y) ;
+ sc_start(src,SC_CONFUSION,80,skilllv,skill_get_time(skillid,skilllv));
+ if (unit_movepos(bl,x,y,0,0))
+ {
+ clif_skill_damage(bl,bl,tick, status_get_amotion(src), 0, -30000, 1, skillid, -1, 6);
+ if( bl->type == BL_PC && pc_issit((TBL_PC*)bl))
+ clif_sitting(bl); //Avoid sitting sync problem
+ clif_slide(bl,x,y) ;
+ sc_start(bl,SC_CONFUSION,80,skilllv,skill_get_time(skillid,skilllv));
+ }
+ }
+ }
+ break;
+
+ case OB_AKAITSUKI:
+ case OB_OBOROGENSOU:
+ if( sd && ( (skillid == OB_OBOROGENSOU && bl->type == BL_MOB) // This skill does not work on monsters.
+ || is_boss(bl) ) ){ // Does not work on Boss monsters.
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+ case KO_IZAYOI:
+ case OB_ZANGETSU:
+ case KG_KYOMU:
+ case KG_KAGEMUSYA:
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
+ clif_skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+ break;
+
+ case KG_KAGEHUMI:
+ if( flag&1 ){
+ if(tsc && ( tsc->option&(OPTION_CLOAK|OPTION_HIDE) ||
+ tsc->data[SC_CAMOUFLAGE] || tsc->data[SC__SHADOWFORM] ||
+ tsc->data[SC_MARIONETTE] || tsc->data[SC_HARMONIZE])){
+ sc_start(src, type, 100, skilllv, skill_get_time(skillid, skilllv));
+ sc_start(bl, type, 100, skilllv, skill_get_time(skillid, skilllv));
+ status_change_end(bl, SC_HIDING, INVALID_TIMER);
+ status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
+ status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
+ status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER);
+ status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
+ status_change_end(bl, SC_MARIONETTE, INVALID_TIMER);
+ status_change_end(bl, SC_HARMONIZE, INVALID_TIMER);
+ }
+ if( skill_area_temp[2] == 1 ){
+ clif_skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+ sc_start(src, SC_STOP, 100, skilllv, skill_get_time(skillid, skilllv));
+ }
+ }else{
+ skill_area_temp[2] = 0;
+ map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), splash_target(src), src, skillid, skilllv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill_castend_nodamage_id);
+ }
+ break;
+
+ case MH_SILENT_BREEZE: {
+ struct status_change *ssc = status_get_sc(src);
+ struct block_list *m_bl = battle_get_master(src);
+ const enum sc_type scs[] = {
+ SC_MANDRAGORA, SC_HARMONIZE, SC_DEEPSLEEP, SC_VOICEOFSIREN, SC_SLEEP, SC_CONFUSION, SC_HALLUCINATION
+ };
+ int heal;
+ if(tsc){
+ for (i = 0; i < ARRAYLENGTH(scs); i++) {
+ if (tsc->data[scs[i]]) status_change_end(bl, scs[i], INVALID_TIMER);
+ }
+ if (!tsc->data[SC_SILENCE]) //put inavoidable silence on target
status_change_start(bl, SC_SILENCE, 100, skilllv, 0,0,0, skill_get_time(skillid, skilllv),1|2|8);
- }
- heal = status_get_matk_min(src)*4;
- status_heal(bl, heal, 0, 7);
-
- //now inflict silence on everyone
- if (ssc && !ssc->data[SC_SILENCE]) //put inavoidable silence on homun
- status_change_start(src, SC_SILENCE, 100, skilllv, 0,0,0, skill_get_time(skillid, skilllv),1|2|8);
- if (m_bl) {
- struct status_change *msc = status_get_sc(m_bl);
- if (msc && !msc->data[SC_SILENCE]) //put inavoidable silence on master
- status_change_start(m_bl, SC_SILENCE, 100, skilllv, 0,0,0, skill_get_time(skillid, skilllv),1|2|8);
- }
- if (hd)
- skill_blockhomun_start(hd, skillid, skill_get_cooldown(skillid, skilllv));
- }
- break;
- case MH_OVERED_BOOST:
- if (hd) {
+ }
+ heal = status_get_matk_min(src)*4;
+ status_heal(bl, heal, 0, 7);
+
+ //now inflict silence on everyone
+ if(ssc && !ssc->data[SC_SILENCE]) //put inavoidable silence on homun
+ status_change_start(src, SC_SILENCE, 100, skilllv, 0,0,0, skill_get_time(skillid, skilllv),1|2|8);
+ if(m_bl){
+ struct status_change *msc = status_get_sc(m_bl);
+ if(msc && !msc->data[SC_SILENCE]) //put inavoidable silence on master
+ status_change_start(m_bl, SC_SILENCE, 100, skilllv, 0,0,0, skill_get_time(skillid, skilllv),1|2|8);
+ }
+ if (hd)
+ skill_blockhomun_start(hd, skillid, skill_get_cooldown(skillid, skilllv));
+ }
+ break;
+ case MH_OVERED_BOOST:
+ if (hd){
struct block_list *s_bl = battle_get_master(src);
- if (hd->homunculus.hunger>50) //reduce hunger
+ if(hd->homunculus.hunger>50) //reduce hunger
hd->homunculus.hunger = hd->homunculus.hunger/2;
else
hd->homunculus.hunger = min(1,hd->homunculus.hunger);
- if (s_bl && s_bl->type==BL_PC) {
+ if(s_bl && s_bl->type==BL_PC){
status_set_sp(s_bl,status_get_max_sp(s_bl)/2,0); //master drain 50% sp
clif_send_homdata(((TBL_PC *)s_bl), SP_HUNGRY, hd->homunculus.hunger); //refresh hunger info
sc_start(s_bl, type, 100, skilllv, skill_get_time(skillid, skilllv)); //gene bonus
}
sc_start(bl, type, 100, skilllv, skill_get_time(skillid, skilllv));
- skill_blockhomun_start(hd, skillid, skill_get_cooldown(skillid, skilllv));
+ skill_blockhomun_start(hd, skillid, skill_get_cooldown(skillid, skilllv));
}
break;
- case MH_GRANITIC_ARMOR:
- case MH_PYROCLASTIC: {
+ case MH_GRANITIC_ARMOR:
+ case MH_PYROCLASTIC: {
struct block_list *s_bl = battle_get_master(src);
- if (s_bl) sc_start2(s_bl, type, 100, skilllv, hd->homunculus.level, skill_get_time(skillid, skilllv)); //start on master
+ if(s_bl) sc_start2(s_bl, type, 100, skilllv, hd->homunculus.level, skill_get_time(skillid, skilllv)); //start on master
sc_start2(bl, type, 100, skilllv, hd->homunculus.level, skill_get_time(skillid, skilllv));
- if (hd) skill_blockhomun_start(hd, skillid, skill_get_cooldown(skillid, skilllv));
+ if (hd) skill_blockhomun_start(hd, skillid, skill_get_cooldown(skillid, skilllv));
}
break;
case MH_LIGHT_OF_REGENE:
- if (hd) {
- hd->homunculus.intimacy = 251; //change to neutral (can't be cast if < 750)
- if (sd) clif_send_homdata(sd, SP_INTIMATE, hd->homunculus.intimacy); //refresh intimacy info
- }
- //don't break need to start status and start block timer
- case MH_STYLE_CHANGE:
+ if(hd){
+ hd->homunculus.intimacy = 251; //change to neutral (can't be cast if < 750)
+ if(sd) clif_send_homdata(sd, SP_INTIMATE, hd->homunculus.intimacy); //refresh intimacy info
+ }
+ //don't break need to start status and start block timer
+ case MH_STYLE_CHANGE:
case MH_MAGMA_FLOW:
case MH_PAIN_KILLER:
- sc_start(bl, type, 100, skilllv, skill_get_time(skillid, skilllv));
- if (hd)
+ sc_start(bl, type, 100, skilllv, skill_get_time(skillid, skilllv));
+ if (hd)
skill_blockhomun_start(hd, skillid, skill_get_cooldown(skillid, skilllv));
- break;
- case MH_SUMMON_LEGION: {
+ break;
+ case MH_SUMMON_LEGION:
+ {
int summons[5] = {1004, 1303, 1303, 1994, 1994};
int qty[5] = {3 , 3 , 4 , 4 , 5};
struct mob_data *md;
int i;
- for (i=0; i<qty[skilllv - 1]; i++) { //easy way
+ for(i=0; i<qty[skilllv - 1]; i++){ //easy way
md = mob_once_spawn_sub(src, src->m, src->x, src->y, status_get_name(src), summons[skilllv - 1], "", SZ_SMALL, AI_ATTACK);
if (md) {
md->master_id = src->id;
@@ -9131,43 +8952,43 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, int
sc_start4(&md->bl, SC_MODECHANGE, 100, 1, 0, MD_ASSIST, 0, 60000);
}
}
- if (hd)
- skill_blockhomun_start(hd, skillid, skill_get_cooldown(skillid, skilllv));
+ if (hd)
+ skill_blockhomun_start(hd, skillid, skill_get_cooldown(skillid, skilllv));
}
break;
- default:
- ShowWarning("skill_castend_nodamage_id: Unknown skill used:%d\n",skillid);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- map_freeblock_unlock();
- return 1;
- }
-
- if (skillid != SR_CURSEDCIRCLE) {
- struct status_change *sc = status_get_sc(src);
- if (sc && sc->data[SC_CURSEDCIRCLE_ATKER]) //Should only remove after the skill had been casted.
- status_change_end(src,SC_CURSEDCIRCLE_ATKER,INVALID_TIMER);
- }
-
- if (dstmd) { //Mob skill event for no damage skills (damage ones are handled in battle_calc_damage) [Skotlex]
- mob_log_damage(dstmd, src, 0); //Log interaction (counts as 'attacker' for the exp bonus)
- mobskill_event(dstmd, src, tick, MSC_SKILLUSED|(skillid<<16));
- }
-
- if (sd && !(flag&1)) {
- // ensure that the skill last-cast tick is recorded
- sd->canskill_tick = gettick();
-
- if (sd->state.arrow_atk) {
- // consume arrow on last invocation to this skill.
- battle_consume_ammo(sd, skillid, skilllv);
- }
- skill_onskillusage(sd, bl, skillid, tick);
- // perform skill requirement consumption
- skill_consume_requirement(sd,skillid,skilllv,2);
- }
-
- map_freeblock_unlock();
- return 0;
+ default:
+ ShowWarning("skill_castend_nodamage_id: Unknown skill used:%d\n",skillid);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ map_freeblock_unlock();
+ return 1;
+ }
+
+ if(skillid != SR_CURSEDCIRCLE){
+ struct status_change *sc = status_get_sc(src);
+ if( sc && sc->data[SC_CURSEDCIRCLE_ATKER] )//Should only remove after the skill had been casted.
+ status_change_end(src,SC_CURSEDCIRCLE_ATKER,INVALID_TIMER);
+ }
+
+ if (dstmd) { //Mob skill event for no damage skills (damage ones are handled in battle_calc_damage) [Skotlex]
+ mob_log_damage(dstmd, src, 0); //Log interaction (counts as 'attacker' for the exp bonus)
+ mobskill_event(dstmd, src, tick, MSC_SKILLUSED|(skillid<<16));
+ }
+
+ if( sd && !(flag&1) )
+ {// ensure that the skill last-cast tick is recorded
+ sd->canskill_tick = gettick();
+
+ if( sd->state.arrow_atk )
+ {// consume arrow on last invocation to this skill.
+ battle_consume_ammo(sd, skillid, skilllv);
+ }
+ skill_onskillusage(sd, bl, skillid, tick);
+ // perform skill requirement consumption
+ skill_consume_requirement(sd,skillid,skilllv,2);
+ }
+
+ map_freeblock_unlock();
+ return 0;
}
/*==========================================
@@ -9175,309 +8996,322 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, int
*------------------------------------------*/
int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data)
{
- struct block_list *target, *src;
- struct map_session_data *sd;
- struct mob_data *md;
- struct unit_data *ud;
- struct status_change *sc = NULL;
- int inf,inf2,flag = 0;
-
- src = map_id2bl(id);
- if (src == NULL) {
- ShowDebug("skill_castend_id: src == NULL (tid=%d, id=%d)\n", tid, id);
- return 0;// not found
- }
-
- ud = unit_bl2ud(src);
- if (ud == NULL) {
- ShowDebug("skill_castend_id: ud == NULL (tid=%d, id=%d)\n", tid, id);
- return 0;// ???
- }
-
- sd = BL_CAST(BL_PC, src);
- md = BL_CAST(BL_MOB, src);
-
- if (src->prev == NULL) {
- ud->skilltimer = INVALID_TIMER;
- return 0;
- }
-
- if (ud->skillid != SA_CASTCANCEL && ud->skillid != SO_SPELLFIST) { // otherwise handled in unit_skillcastcancel()
- if (ud->skilltimer != tid) {
- ShowError("skill_castend_id: Timer mismatch %d!=%d!\n", ud->skilltimer, tid);
- ud->skilltimer = INVALID_TIMER;
- return 0;
- }
-
- if (sd && ud->skilltimer != INVALID_TIMER && (pc_checkskill(sd,SA_FREECAST) > 0 || ud->skillid == LG_EXEEDBREAK)) {
- // restore original walk speed
- ud->skilltimer = INVALID_TIMER;
- status_calc_bl(&sd->bl, SCB_SPEED);
- }
-
- ud->skilltimer = INVALID_TIMER;
- }
-
- if (ud->skilltarget == id)
- target = src;
- else
- target = map_id2bl(ud->skilltarget);
-
- // Use a do so that you can break out of it when the skill fails.
- do {
- if (!target || target->prev==NULL) break;
-
- if (src->m != target->m || status_isdead(src)) break;
-
- switch (ud->skillid) {
- //These should become skill_castend_pos
- case WE_CALLPARTNER:
- if (sd) clif_callpartner(sd);
- case WE_CALLPARENT:
- case WE_CALLBABY:
- case AM_RESURRECTHOMUN:
- case PF_SPIDERWEB:
- //Find a random spot to place the skill. [Skotlex]
- inf2 = skill_get_splash(ud->skillid, ud->skilllv);
- ud->skillx = target->x + inf2;
- ud->skilly = target->y + inf2;
- if (inf2 && !map_random_dir(target, &ud->skillx, &ud->skilly)) {
- ud->skillx = target->x;
- ud->skilly = target->y;
- }
- ud->skilltimer=tid;
- return skill_castend_pos(tid,tick,id,data);
- case GN_WALLOFTHORN:
- ud->skillx = target->x;
- ud->skilly = target->y;
- ud->skilltimer = tid;
- return skill_castend_pos(tid,tick,id,data);
- }
-
- if (ud->skillid == RG_BACKSTAP) {
- int dir = map_calc_dir(src,target->x,target->y),t_dir = unit_getdir(target);
- if (check_distance_bl(src, target, 0) || map_check_dir(dir,t_dir)) {
- break;
- }
- }
-
- if (ud->skillid == PR_TURNUNDEAD) {
- struct status_data *tstatus = status_get_status_data(target);
- if (!battle_check_undead(tstatus->race, tstatus->def_ele))
- break;
- }
-
- if (ud->skillid == RA_WUGSTRIKE) {
- if (!path_search(NULL,src->m,src->x,src->y,target->x,target->y,1,CELL_CHKNOREACH))
- break;
- }
-
- if (ud->skillid == PR_LEXDIVINA || ud->skillid == MER_LEXDIVINA) {
- sc = status_get_sc(target);
- if (battle_check_target(src,target, BCT_ENEMY) <= 0 && (!sc || !sc->data[SC_SILENCE])) {
- //If it's not an enemy, and not silenced, you can't use the skill on them. [Skotlex]
- clif_skill_nodamage(src, target, ud->skillid, ud->skilllv, 0);
- break;
- }
- } else {
- // Check target validity.
- inf = skill_get_inf(ud->skillid);
- inf2 = skill_get_inf2(ud->skillid);
-
- if (inf&INF_ATTACK_SKILL ||
- (inf&INF_SELF_SKILL && inf2&INF2_NO_TARGET_SELF) //Combo skills
- ) // Casted through combo.
- inf = BCT_ENEMY; //Offensive skill.
- else if (inf2&INF2_NO_ENEMY)
- inf = BCT_NOENEMY;
- else
- inf = 0;
-
- if (inf2 & (INF2_PARTY_ONLY|INF2_GUILD_ONLY) && src != target) {
- inf |=
- (inf2&INF2_PARTY_ONLY?BCT_PARTY:0)|
- (inf2&INF2_GUILD_ONLY?BCT_GUILD:0);
- //Remove neutral targets (but allow enemy if skill is designed to be so)
- inf &= ~BCT_NEUTRAL;
- }
+ struct block_list *target, *src;
+ struct map_session_data *sd;
+ struct mob_data *md;
+ struct unit_data *ud;
+ struct status_change *sc = NULL;
+ int inf,inf2,flag = 0;
+
+ src = map_id2bl(id);
+ if( src == NULL )
+ {
+ ShowDebug("skill_castend_id: src == NULL (tid=%d, id=%d)\n", tid, id);
+ return 0;// not found
+ }
- if (ud->skillid >= SL_SKE && ud->skillid <= SL_SKA && target->type == BL_MOB) {
- if (((TBL_MOB *)target)->class_ == MOBID_EMPERIUM)
- break;
- } else if (inf && battle_check_target(src, target, inf) <= 0) {
- if (sd) clif_skill_fail(sd,ud->skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
+ ud = unit_bl2ud(src);
+ if( ud == NULL )
+ {
+ ShowDebug("skill_castend_id: ud == NULL (tid=%d, id=%d)\n", tid, id);
+ return 0;// ???
+ }
- if (inf&BCT_ENEMY && (sc = status_get_sc(target)) &&
- sc->data[SC_FOGWALL] &&
- rnd() % 100 < 75) { //Fogwall makes all offensive-type targetted skills fail at 75%
- if (sd) clif_skill_fail(sd, ud->skillid, USESKILL_FAIL_LEVEL, 0);
- break;
- }
- }
+ sd = BL_CAST(BL_PC, src);
+ md = BL_CAST(BL_MOB, src);
- //Avoid doing double checks for instant-cast skills.
- if (tid != INVALID_TIMER && !status_check_skilluse(src, target, ud->skillid, 1))
- break;
+ if( src->prev == NULL ) {
+ ud->skilltimer = INVALID_TIMER;
+ return 0;
+ }
- if (md) {
- md->last_thinktime=tick +MIN_MOBTHINKTIME;
- if (md->skillidx >= 0 && md->db->skill[md->skillidx].emotion >= 0)
- clif_emotion(src, md->db->skill[md->skillidx].emotion);
- }
-
- if (src != target && battle_config.skill_add_range &&
- !check_distance_bl(src, target, skill_get_range2(src,ud->skillid,ud->skilllv)+battle_config.skill_add_range)) {
- if (sd) {
- clif_skill_fail(sd,ud->skillid,USESKILL_FAIL_LEVEL,0);
- if (battle_config.skill_out_range_consume) //Consume items anyway. [Skotlex]
- skill_consume_requirement(sd,ud->skillid,ud->skilllv,3);
- }
- break;
- }
-
- if (sd) {
- if (!skill_check_condition_castend(sd, ud->skillid, ud->skilllv))
- break;
- else
- skill_consume_requirement(sd,ud->skillid,ud->skilllv,1);
- }
+ if(ud->skillid != SA_CASTCANCEL && ud->skillid != SO_SPELLFIST) {// otherwise handled in unit_skillcastcancel()
+ if( ud->skilltimer != tid ) {
+ ShowError("skill_castend_id: Timer mismatch %d!=%d!\n", ud->skilltimer, tid);
+ ud->skilltimer = INVALID_TIMER;
+ return 0;
+ }
+
+ if( sd && ud->skilltimer != INVALID_TIMER && (pc_checkskill(sd,SA_FREECAST) > 0 || ud->skillid == LG_EXEEDBREAK) )
+ {// restore original walk speed
+ ud->skilltimer = INVALID_TIMER;
+ status_calc_bl(&sd->bl, SCB_SPEED);
+ }
+
+ ud->skilltimer = INVALID_TIMER;
+ }
+
+ if (ud->skilltarget == id)
+ target = src;
+ else
+ target = map_id2bl(ud->skilltarget);
+
+ // Use a do so that you can break out of it when the skill fails.
+ do {
+ if(!target || target->prev==NULL) break;
+
+ if(src->m != target->m || status_isdead(src)) break;
+
+ switch (ud->skillid) {
+ //These should become skill_castend_pos
+ case WE_CALLPARTNER:
+ if(sd) clif_callpartner(sd);
+ case WE_CALLPARENT:
+ case WE_CALLBABY:
+ case AM_RESURRECTHOMUN:
+ case PF_SPIDERWEB:
+ //Find a random spot to place the skill. [Skotlex]
+ inf2 = skill_get_splash(ud->skillid, ud->skilllv);
+ ud->skillx = target->x + inf2;
+ ud->skilly = target->y + inf2;
+ if (inf2 && !map_random_dir(target, &ud->skillx, &ud->skilly)) {
+ ud->skillx = target->x;
+ ud->skilly = target->y;
+ }
+ ud->skilltimer=tid;
+ return skill_castend_pos(tid,tick,id,data);
+ case GN_WALLOFTHORN:
+ ud->skillx = target->x;
+ ud->skilly = target->y;
+ ud->skilltimer = tid;
+ return skill_castend_pos(tid,tick,id,data);
+ }
+
+ if(ud->skillid == RG_BACKSTAP) {
+ int dir = map_calc_dir(src,target->x,target->y),t_dir = unit_getdir(target);
+ if(check_distance_bl(src, target, 0) || map_check_dir(dir,t_dir)) {
+ break;
+ }
+ }
+
+ if( ud->skillid == PR_TURNUNDEAD )
+ {
+ struct status_data *tstatus = status_get_status_data(target);
+ if( !battle_check_undead(tstatus->race, tstatus->def_ele) )
+ break;
+ }
+
+ if( ud->skillid == RA_WUGSTRIKE ){
+ if( !path_search(NULL,src->m,src->x,src->y,target->x,target->y,1,CELL_CHKNOREACH))
+ break;
+ }
+
+ if( ud->skillid == PR_LEXDIVINA || ud->skillid == MER_LEXDIVINA )
+ {
+ sc = status_get_sc(target);
+ if( battle_check_target(src,target, BCT_ENEMY) <= 0 && (!sc || !sc->data[SC_SILENCE]) )
+ { //If it's not an enemy, and not silenced, you can't use the skill on them. [Skotlex]
+ clif_skill_nodamage (src, target, ud->skillid, ud->skilllv, 0);
+ break;
+ }
+ }
+ else
+ { // Check target validity.
+ inf = skill_get_inf(ud->skillid);
+ inf2 = skill_get_inf2(ud->skillid);
+
+ if(inf&INF_ATTACK_SKILL ||
+ (inf&INF_SELF_SKILL && inf2&INF2_NO_TARGET_SELF) //Combo skills
+ ) // Casted through combo.
+ inf = BCT_ENEMY; //Offensive skill.
+ else if(inf2&INF2_NO_ENEMY)
+ inf = BCT_NOENEMY;
+ else
+ inf = 0;
+
+ if(inf2 & (INF2_PARTY_ONLY|INF2_GUILD_ONLY) && src != target)
+ {
+ inf |=
+ (inf2&INF2_PARTY_ONLY?BCT_PARTY:0)|
+ (inf2&INF2_GUILD_ONLY?BCT_GUILD:0);
+ //Remove neutral targets (but allow enemy if skill is designed to be so)
+ inf &= ~BCT_NEUTRAL;
+ }
+
+ if( ud->skillid >= SL_SKE && ud->skillid <= SL_SKA && target->type == BL_MOB )
+ {
+ if( ((TBL_MOB*)target)->class_ == MOBID_EMPERIUM )
+ break;
+ }
+ else if (inf && battle_check_target(src, target, inf) <= 0){
+ if (sd) clif_skill_fail(sd,ud->skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+
+ if(inf&BCT_ENEMY && (sc = status_get_sc(target)) &&
+ sc->data[SC_FOGWALL] &&
+ rnd() % 100 < 75) { //Fogwall makes all offensive-type targetted skills fail at 75%
+ if (sd) clif_skill_fail(sd, ud->skillid, USESKILL_FAIL_LEVEL, 0);
+ break;
+ }
+ }
+
+ //Avoid doing double checks for instant-cast skills.
+ if (tid != INVALID_TIMER && !status_check_skilluse(src, target, ud->skillid, 1))
+ break;
+
+ if(md) {
+ md->last_thinktime=tick +MIN_MOBTHINKTIME;
+ if(md->skillidx >= 0 && md->db->skill[md->skillidx].emotion >= 0)
+ clif_emotion(src, md->db->skill[md->skillidx].emotion);
+ }
+
+ if(src != target && battle_config.skill_add_range &&
+ !check_distance_bl(src, target, skill_get_range2(src,ud->skillid,ud->skilllv)+battle_config.skill_add_range))
+ {
+ if (sd) {
+ clif_skill_fail(sd,ud->skillid,USESKILL_FAIL_LEVEL,0);
+ if(battle_config.skill_out_range_consume) //Consume items anyway. [Skotlex]
+ skill_consume_requirement(sd,ud->skillid,ud->skilllv,3);
+ }
+ break;
+ }
+
+ if( sd )
+ {
+ if( !skill_check_condition_castend(sd, ud->skillid, ud->skilllv) )
+ break;
+ else
+ skill_consume_requirement(sd,ud->skillid,ud->skilllv,1);
+ }
#ifdef OFFICIAL_WALKPATH
- if (!path_search_long(NULL, src->m, src->x, src->y, target->x, target->y, CELL_CHKWALL))
- break;
+ if( !path_search_long(NULL, src->m, src->x, src->y, target->x, target->y, CELL_CHKWALL) )
+ break;
#endif
- if ((src->type == BL_MER || src->type == BL_HOM) && !skill_check_condition_mercenary(src, ud->skillid, ud->skilllv, 1))
- break;
+ if( (src->type == BL_MER || src->type == BL_HOM) && !skill_check_condition_mercenary(src, ud->skillid, ud->skilllv, 1) )
+ break;
- if (ud->state.running && ud->skillid == TK_JUMPKICK) {
+ if (ud->state.running && ud->skillid == TK_JUMPKICK)
+ {
ud->state.running = 0;
status_change_end(src, SC_RUN, INVALID_TIMER);
- flag = 1;
- }
-
- if (ud->walktimer != INVALID_TIMER && ud->skillid != TK_RUN && ud->skillid != RA_WUGDASH)
- unit_stop_walking(src,1);
-
- if (!sd || sd->skillitem != ud->skillid || skill_get_delay(ud->skillid,ud->skilllv))
- ud->canact_tick = tick + skill_delayfix(src, ud->skillid, ud->skilllv); //Tests show wings don't overwrite the delay but skill scrolls do. [Inkfish]
- if (sd) { //Cooldown application
- int i, cooldown = skill_get_cooldown(ud->skillid, ud->skilllv);
- for (i = 0; i < ARRAYLENGTH(sd->skillcooldown) && sd->skillcooldown[i].id; i++) { // Increases/Decreases cooldown of a skill by item/card bonuses.
- if (sd->skillcooldown[i].id == ud->skillid) {
- cooldown += sd->skillcooldown[i].val;
- break;
- }
- }
- if(cooldown)
- skill_blockpc_start(sd, ud->skillid, cooldown);
- }
- if (battle_config.display_status_timers && sd)
- clif_status_change(src, SI_ACTIONDELAY, 1, skill_delayfix(src, ud->skillid, ud->skilllv), 0, 0, 0);
- if (sd) {
- switch (ud->skillid) {
- case GS_DESPERADO:
- sd->canequip_tick = tick + skill_get_time(ud->skillid, ud->skilllv);
- break;
- case CR_GRANDCROSS:
- case NPC_GRANDDARKNESS:
- if ((sc = status_get_sc(src)) && sc->data[SC_STRIPSHIELD]) {
- const struct TimerData *timer = get_timer(sc->data[SC_STRIPSHIELD]->timer);
- if (timer && timer->func == status_change_timer && DIFF_TICK(timer->tick,gettick()+skill_get_time(ud->skillid, ud->skilllv)) > 0)
- break;
- }
- sc_start2(src, SC_STRIPSHIELD, 100, 0, 1, skill_get_time(ud->skillid, ud->skilllv));
- break;
- }
- }
- if (skill_get_state(ud->skillid) != ST_MOVE_ENABLE)
- unit_set_walkdelay(src, tick, battle_config.default_walk_delay+skill_get_walkdelay(ud->skillid, ud->skilllv), 1);
-
- if (battle_config.skill_log && battle_config.skill_log&src->type)
- ShowInfo("Type %d, ID %d skill castend id [id =%d, lv=%d, target ID %d]\n",
- src->type, src->id, ud->skillid, ud->skilllv, target->id);
-
- map_freeblock_lock();
-
- // SC_MAGICPOWER needs to switch states before any damage is actually dealt
- skill_toggle_magicpower(src, ud->skillid);
- if (ud->skillid != RA_CAMOUFLAGE) // only normal attack and auto cast skills benefit from its bonuses
- status_change_end(src,SC_CAMOUFLAGE, INVALID_TIMER);
-
- if (skill_get_casttype(ud->skillid) == CAST_NODAMAGE)
- skill_castend_nodamage_id(src,target,ud->skillid,ud->skilllv,tick,flag);
- else
- skill_castend_damage_id(src,target,ud->skillid,ud->skilllv,tick,flag);
-
- sc = status_get_sc(src);
- if (sc && sc->count) {
- if (sc->data[SC_SPIRIT] &&
- sc->data[SC_SPIRIT]->val2 == SL_WIZARD &&
- sc->data[SC_SPIRIT]->val3 == ud->skillid &&
- ud->skillid != WZ_WATERBALL)
- sc->data[SC_SPIRIT]->val3 = 0; //Clear bounced spell check.
-
- if (sc->data[SC_DANCING] && skill_get_inf2(ud->skillid)&INF2_SONG_DANCE && sd)
- skill_blockpc_start(sd,BD_ADAPTATION,3000);
- }
-
- if (sd && ud->skillid != SA_ABRACADABRA && ud->skillid != WM_RANDOMIZESPELL) // they just set the data so leave it as it is.[Inkfish]
- sd->skillitem = sd->skillitemlv = 0;
-
- if (ud->skilltimer == INVALID_TIMER) {
- if (md) md->skillidx = -1;
- else ud->skillid = 0; //mobs can't clear this one as it is used for skill condition 'afterskill'
- ud->skilllv = ud->skilltarget = 0;
- }
- map_freeblock_unlock();
- return 1;
- } while (0);
-
- //Skill failed.
- if (ud->skillid == MO_EXTREMITYFIST && sd && !(sc && sc->data[SC_FOGWALL])) {
- //When Asura fails... (except when it fails from Fog of Wall)
- //Consume SP/spheres
- skill_consume_requirement(sd,ud->skillid, ud->skilllv,1);
- status_set_sp(src, 0, 0);
- sc = &sd->sc;
- if (sc->count) {
- //End states
- status_change_end(src, SC_EXPLOSIONSPIRITS, INVALID_TIMER);
- status_change_end(src, SC_BLADESTOP, INVALID_TIMER);
+ flag = 1;
+ }
+
+ if (ud->walktimer != INVALID_TIMER && ud->skillid != TK_RUN && ud->skillid != RA_WUGDASH)
+ unit_stop_walking(src,1);
+
+ if( !sd || sd->skillitem != ud->skillid || skill_get_delay(ud->skillid,ud->skilllv) )
+ ud->canact_tick = tick + skill_delayfix(src, ud->skillid, ud->skilllv); //Tests show wings don't overwrite the delay but skill scrolls do. [Inkfish]
+ if( sd && skill_get_cooldown(ud->skillid,ud->skilllv) > 0 ){
+ int i, cooldown = skill_get_cooldown(ud->skillid, ud->skilllv);
+ for (i = 0; i < ARRAYLENGTH(sd->skillcooldown) && sd->skillcooldown[i].id; i++) { // Increases/Decreases cooldown of a skill by item/card bonuses.
+ if (sd->skillcooldown[i].id == ud->skillid){
+ cooldown += sd->skillcooldown[i].val;
+ break;
+ }
+ }
+ skill_blockpc_start(sd, ud->skillid, cooldown);
+ }
+ if( battle_config.display_status_timers && sd )
+ clif_status_change(src, SI_ACTIONDELAY, 1, skill_delayfix(src, ud->skillid, ud->skilllv), 0, 0, 0);
+ if( sd )
+ {
+ switch( ud->skillid )
+ {
+ case GS_DESPERADO:
+ sd->canequip_tick = tick + skill_get_time(ud->skillid, ud->skilllv);
+ break;
+ case CR_GRANDCROSS:
+ case NPC_GRANDDARKNESS:
+ if( (sc = status_get_sc(src)) && sc->data[SC_STRIPSHIELD] )
+ {
+ const struct TimerData *timer = get_timer(sc->data[SC_STRIPSHIELD]->timer);
+ if( timer && timer->func == status_change_timer && DIFF_TICK(timer->tick,gettick()+skill_get_time(ud->skillid, ud->skilllv)) > 0 )
+ break;
+ }
+ sc_start2(src, SC_STRIPSHIELD, 100, 0, 1, skill_get_time(ud->skillid, ud->skilllv));
+ break;
+ }
+ }
+ if (skill_get_state(ud->skillid) != ST_MOVE_ENABLE)
+ unit_set_walkdelay(src, tick, battle_config.default_walk_delay+skill_get_walkdelay(ud->skillid, ud->skilllv), 1);
+
+ if(battle_config.skill_log && battle_config.skill_log&src->type)
+ ShowInfo("Type %d, ID %d skill castend id [id =%d, lv=%d, target ID %d]\n",
+ src->type, src->id, ud->skillid, ud->skilllv, target->id);
+
+ map_freeblock_lock();
+
+ // SC_MAGICPOWER needs to switch states before any damage is actually dealt
+ skill_toggle_magicpower(src, ud->skillid);
+ if( ud->skillid != RA_CAMOUFLAGE ) // only normal attack and auto cast skills benefit from its bonuses
+ status_change_end(src,SC_CAMOUFLAGE, INVALID_TIMER);
+
+ if (skill_get_casttype(ud->skillid) == CAST_NODAMAGE)
+ skill_castend_nodamage_id(src,target,ud->skillid,ud->skilllv,tick,flag);
+ else
+ skill_castend_damage_id(src,target,ud->skillid,ud->skilllv,tick,flag);
+
+ sc = status_get_sc(src);
+ if(sc && sc->count) {
+ if(sc->data[SC_SPIRIT] &&
+ sc->data[SC_SPIRIT]->val2 == SL_WIZARD &&
+ sc->data[SC_SPIRIT]->val3 == ud->skillid &&
+ ud->skillid != WZ_WATERBALL)
+ sc->data[SC_SPIRIT]->val3 = 0; //Clear bounced spell check.
+
+ if( sc->data[SC_DANCING] && skill_get_inf2(ud->skillid)&INF2_SONG_DANCE && sd )
+ skill_blockpc_start(sd,BD_ADAPTATION,3000);
+ }
+
+ if( sd && ud->skillid != SA_ABRACADABRA && ud->skillid != WM_RANDOMIZESPELL ) // they just set the data so leave it as it is.[Inkfish]
+ sd->skillitem = sd->skillitemlv = 0;
+
+ if (ud->skilltimer == INVALID_TIMER) {
+ if(md) md->skillidx = -1;
+ else ud->skillid = 0; //mobs can't clear this one as it is used for skill condition 'afterskill'
+ ud->skilllv = ud->skilltarget = 0;
+ }
+ map_freeblock_unlock();
+ return 1;
+ } while(0);
+
+ //Skill failed.
+ if (ud->skillid == MO_EXTREMITYFIST && sd && !(sc && sc->data[SC_FOGWALL]))
+ { //When Asura fails... (except when it fails from Fog of Wall)
+ //Consume SP/spheres
+ skill_consume_requirement(sd,ud->skillid, ud->skilllv,1);
+ status_set_sp(src, 0, 0);
+ sc = &sd->sc;
+ if (sc->count)
+ { //End states
+ status_change_end(src, SC_EXPLOSIONSPIRITS, INVALID_TIMER);
+ status_change_end(src, SC_BLADESTOP, INVALID_TIMER);
#ifdef RENEWAL
- sc_start(src, SC_EXTREMITYFIST2, 100, ud->skilllv, skill_get_time(ud->skillid, ud->skilllv));
+ sc_start(src, SC_EXTREMITYFIST2, 100, ud->skilllv, skill_get_time(ud->skillid, ud->skilllv));
#endif
- }
- if (target && target->m == src->m) {
- //Move character to target anyway.
- int dx,dy;
- dx = target->x - src->x;
- dy = target->y - src->y;
- if (dx > 0) dx++;
- else if (dx < 0) dx--;
- if (dy > 0) dy++;
- else if (dy < 0) dy--;
-
- if (unit_movepos(src, src->x+dx, src->y+dy, 1, 1)) {
- //Display movement + animation.
- clif_slide(src,src->x,src->y);
- clif_skill_damage(src,target,tick,sd->battle_status.amotion,0,0,1,ud->skillid, ud->skilllv, 5);
- }
- clif_skill_fail(sd,ud->skillid,USESKILL_FAIL_LEVEL,0);
- }
- }
-
- ud->skillid = ud->skilllv = ud->skilltarget = 0;
- if (!sd || sd->skillitem != ud->skillid || skill_get_delay(ud->skillid,ud->skilllv))
- ud->canact_tick = tick;
- //You can't place a skill failed packet here because it would be
- //sent in ALL cases, even cases where skill_check_condition fails
- //which would lead to double 'skill failed' messages u.u [Skotlex]
- if (sd)
- sd->skillitem = sd->skillitemlv = 0;
- else if (md)
- md->skillidx = -1;
- return 0;
+ }
+ if (target && target->m == src->m)
+ { //Move character to target anyway.
+ int dx,dy;
+ dx = target->x - src->x;
+ dy = target->y - src->y;
+ if(dx > 0) dx++;
+ else if(dx < 0) dx--;
+ if (dy > 0) dy++;
+ else if(dy < 0) dy--;
+
+ if (unit_movepos(src, src->x+dx, src->y+dy, 1, 1))
+ { //Display movement + animation.
+ clif_slide(src,src->x,src->y);
+ clif_skill_damage(src,target,tick,sd->battle_status.amotion,0,0,1,ud->skillid, ud->skilllv, 5);
+ }
+ clif_skill_fail(sd,ud->skillid,USESKILL_FAIL_LEVEL,0);
+ }
+ }
+
+ ud->skillid = ud->skilllv = ud->skilltarget = 0;
+ if( !sd || sd->skillitem != ud->skillid || skill_get_delay(ud->skillid,ud->skilllv) )
+ ud->canact_tick = tick;
+ //You can't place a skill failed packet here because it would be
+ //sent in ALL cases, even cases where skill_check_condition fails
+ //which would lead to double 'skill failed' messages u.u [Skotlex]
+ if(sd)
+ sd->skillitem = sd->skillitemlv = 0;
+ else if(md)
+ md->skillidx = -1;
+ return 0;
}
/*==========================================
@@ -9485,2675 +9319,2709 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data)
*------------------------------------------*/
int skill_castend_pos(int tid, unsigned int tick, int id, intptr_t data)
{
- struct block_list *src = map_id2bl(id);
- int maxcount;
- struct map_session_data *sd;
- struct unit_data *ud = unit_bl2ud(src);
- struct mob_data *md;
-
- nullpo_ret(ud);
-
- sd = BL_CAST(BL_PC , src);
- md = BL_CAST(BL_MOB, src);
-
- if (src->prev == NULL) {
- ud->skilltimer = INVALID_TIMER;
- return 0;
- }
-
- if (ud->skilltimer != tid) {
- ShowError("skill_castend_pos: Timer mismatch %d!=%d\n", ud->skilltimer, tid);
- ud->skilltimer = INVALID_TIMER;
- return 0;
- }
-
- if (sd && ud->skilltimer != INVALID_TIMER && (pc_checkskill(sd,SA_FREECAST) > 0 || ud->skillid == LG_EXEEDBREAK)) {
- // restore original walk speed
- ud->skilltimer = INVALID_TIMER;
- status_calc_bl(&sd->bl, SCB_SPEED);
- }
- ud->skilltimer = INVALID_TIMER;
-
- do {
- if (status_isdead(src))
- break;
+ struct block_list* src = map_id2bl(id);
+ int maxcount;
+ struct map_session_data *sd;
+ struct unit_data *ud = unit_bl2ud(src);
+ struct mob_data *md;
- if (!(src->type&battle_config.skill_reiteration) &&
- skill_get_unit_flag(ud->skillid)&UF_NOREITERATION &&
- skill_check_unit_range(src,ud->skillx,ud->skilly,ud->skillid,ud->skilllv)
- ) {
- if (sd) clif_skill_fail(sd,ud->skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
- if (src->type&battle_config.skill_nofootset &&
- skill_get_unit_flag(ud->skillid)&UF_NOFOOTSET &&
- skill_check_unit_range2(src,ud->skillx,ud->skilly,ud->skillid,ud->skilllv)
- ) {
- if (sd) clif_skill_fail(sd,ud->skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
- if (src->type&battle_config.land_skill_limit &&
- (maxcount = skill_get_maxcount(ud->skillid, ud->skilllv)) > 0
- ) {
- int i;
- for (i=0; i<MAX_SKILLUNITGROUP && ud->skillunit[i] && maxcount; i++) {
- if (ud->skillunit[i]->skill_id == ud->skillid)
- maxcount--;
- }
- if (maxcount == 0) {
- if (sd) clif_skill_fail(sd,ud->skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
- }
-
- if (tid != INVALID_TIMER) {
- //Avoid double checks on instant cast skills. [Skotlex]
- if (!status_check_skilluse(src, NULL, ud->skillid, 1))
- break;
- if (battle_config.skill_add_range &&
- !check_distance_blxy(src, ud->skillx, ud->skilly, skill_get_range2(src,ud->skillid,ud->skilllv)+battle_config.skill_add_range)) {
- if (sd && battle_config.skill_out_range_consume) //Consume items anyway.
- skill_consume_requirement(sd,ud->skillid,ud->skilllv,3);
- break;
- }
- }
+ nullpo_ret(ud);
- if (sd) {
- if (!skill_check_condition_castend(sd, ud->skillid, ud->skilllv))
- break;
- else
- skill_consume_requirement(sd,ud->skillid,ud->skilllv,1);
- }
+ sd = BL_CAST(BL_PC , src);
+ md = BL_CAST(BL_MOB, src);
- if ((src->type == BL_MER || src->type == BL_HOM) && !skill_check_condition_mercenary(src, ud->skillid, ud->skilllv, 1))
- break;
+ if( src->prev == NULL ) {
+ ud->skilltimer = INVALID_TIMER;
+ return 0;
+ }
- if (md) {
- md->last_thinktime=tick +MIN_MOBTHINKTIME;
- if (md->skillidx >= 0 && md->db->skill[md->skillidx].emotion >= 0)
- clif_emotion(src, md->db->skill[md->skillidx].emotion);
- }
-
- if (battle_config.skill_log && battle_config.skill_log&src->type)
- ShowInfo("Type %d, ID %d skill castend pos [id =%d, lv=%d, (%d,%d)]\n",
- src->type, src->id, ud->skillid, ud->skilllv, ud->skillx, ud->skilly);
-
- if (ud->walktimer != INVALID_TIMER)
- unit_stop_walking(src,1);
-
- if (!sd || sd->skillitem != ud->skillid || skill_get_delay(ud->skillid,ud->skilllv))
- ud->canact_tick = tick + skill_delayfix(src, ud->skillid, ud->skilllv);
- if (sd) { //Cooldown application
- int i, cooldown = skill_get_cooldown(ud->skillid, ud->skilllv);
- for (i = 0; i < ARRAYLENGTH(sd->skillcooldown) && sd->skillcooldown[i].id; i++) { // Increases/Decreases cooldown of a skill by item/card bonuses.
- if (sd->skillcooldown[i].id == ud->skillid) {
- cooldown += sd->skillcooldown[i].val;
- break;
- }
- }
- if(cooldown)
- skill_blockpc_start(sd, ud->skillid, cooldown);
- }
- if (battle_config.display_status_timers && sd)
- clif_status_change(src, SI_ACTIONDELAY, 1, skill_delayfix(src, ud->skillid, ud->skilllv), 0, 0, 0);
- // if( sd )
- // {
- // switch( ud->skillid )
- // {
- // case ????:
- // sd->canequip_tick = tick + ????;
- // break;
- // }
- // }
- unit_set_walkdelay(src, tick, battle_config.default_walk_delay+skill_get_walkdelay(ud->skillid, ud->skilllv), 1);
- status_change_end(src,SC_CAMOUFLAGE, INVALID_TIMER);// only normal attack and auto cast skills benefit from its bonuses
- map_freeblock_lock();
- skill_castend_pos2(src,ud->skillx,ud->skilly,ud->skillid,ud->skilllv,tick,0);
-
- if (sd && sd->skillitem != AL_WARP) // Warp-Portal thru items will clear data in skill_castend_map. [Inkfish]
- sd->skillitem = sd->skillitemlv = 0;
-
- if (ud->skilltimer == INVALID_TIMER) {
- if (md) md->skillidx = -1;
- else ud->skillid = 0; //Non mobs can't clear this one as it is used for skill condition 'afterskill'
- ud->skilllv = ud->skillx = ud->skilly = 0;
- }
-
- map_freeblock_unlock();
- return 1;
- } while (0);
-
- if (!sd || sd->skillitem != ud->skillid || skill_get_delay(ud->skillid,ud->skilllv))
- ud->canact_tick = tick;
- ud->skillid = ud->skilllv = 0;
- if (sd)
- sd->skillitem = sd->skillitemlv = 0;
- else if (md)
- md->skillidx = -1;
- return 0;
+ if( ud->skilltimer != tid )
+ {
+ ShowError("skill_castend_pos: Timer mismatch %d!=%d\n", ud->skilltimer, tid);
+ ud->skilltimer = INVALID_TIMER;
+ return 0;
+ }
+
+ if( sd && ud->skilltimer != INVALID_TIMER && ( pc_checkskill(sd,SA_FREECAST) > 0 || ud->skillid == LG_EXEEDBREAK ) )
+ {// restore original walk speed
+ ud->skilltimer = INVALID_TIMER;
+ status_calc_bl(&sd->bl, SCB_SPEED);
+ }
+ ud->skilltimer = INVALID_TIMER;
+
+ do {
+ if( status_isdead(src) )
+ break;
+
+ if( !(src->type&battle_config.skill_reiteration) &&
+ skill_get_unit_flag(ud->skillid)&UF_NOREITERATION &&
+ skill_check_unit_range(src,ud->skillx,ud->skilly,ud->skillid,ud->skilllv)
+ )
+ {
+ if (sd) clif_skill_fail(sd,ud->skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+ if( src->type&battle_config.skill_nofootset &&
+ skill_get_unit_flag(ud->skillid)&UF_NOFOOTSET &&
+ skill_check_unit_range2(src,ud->skillx,ud->skilly,ud->skillid,ud->skilllv)
+ )
+ {
+ if (sd) clif_skill_fail(sd,ud->skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+ if( src->type&battle_config.land_skill_limit &&
+ (maxcount = skill_get_maxcount(ud->skillid, ud->skilllv)) > 0
+ ) {
+ int i;
+ for(i=0;i<MAX_SKILLUNITGROUP && ud->skillunit[i] && maxcount;i++) {
+ if(ud->skillunit[i]->skill_id == ud->skillid)
+ maxcount--;
+ }
+ if( maxcount == 0 )
+ {
+ if (sd) clif_skill_fail(sd,ud->skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+ }
+
+ if(tid != INVALID_TIMER)
+ { //Avoid double checks on instant cast skills. [Skotlex]
+ if (!status_check_skilluse(src, NULL, ud->skillid, 1))
+ break;
+ if(battle_config.skill_add_range &&
+ !check_distance_blxy(src, ud->skillx, ud->skilly, skill_get_range2(src,ud->skillid,ud->skilllv)+battle_config.skill_add_range)) {
+ if (sd && battle_config.skill_out_range_consume) //Consume items anyway.
+ skill_consume_requirement(sd,ud->skillid,ud->skilllv,3);
+ break;
+ }
+ }
+
+ if( sd )
+ {
+ if( !skill_check_condition_castend(sd, ud->skillid, ud->skilllv) )
+ break;
+ else
+ skill_consume_requirement(sd,ud->skillid,ud->skilllv,1);
+ }
+
+ if( (src->type == BL_MER || src->type == BL_HOM) && !skill_check_condition_mercenary(src, ud->skillid, ud->skilllv, 1) )
+ break;
+
+ if(md) {
+ md->last_thinktime=tick +MIN_MOBTHINKTIME;
+ if(md->skillidx >= 0 && md->db->skill[md->skillidx].emotion >= 0)
+ clif_emotion(src, md->db->skill[md->skillidx].emotion);
+ }
+
+ if(battle_config.skill_log && battle_config.skill_log&src->type)
+ ShowInfo("Type %d, ID %d skill castend pos [id =%d, lv=%d, (%d,%d)]\n",
+ src->type, src->id, ud->skillid, ud->skilllv, ud->skillx, ud->skilly);
+
+ if (ud->walktimer != INVALID_TIMER)
+ unit_stop_walking(src,1);
+
+ if( !sd || sd->skillitem != ud->skillid || skill_get_delay(ud->skillid,ud->skilllv) )
+ ud->canact_tick = tick + skill_delayfix(src, ud->skillid, ud->skilllv);
+ if( sd && skill_get_cooldown(ud->skillid,ud->skilllv) > 0 ){
+ int i, cooldown = skill_get_cooldown(ud->skillid, ud->skilllv);
+ for (i = 0; i < ARRAYLENGTH(sd->skillcooldown) && sd->skillcooldown[i].id; i++) { // Increases/Decreases cooldown of a skill by item/card bonuses.
+ if (sd->skillcooldown[i].id == ud->skillid){
+ cooldown += sd->skillcooldown[i].val;
+ break;
+ }
+ }
+ skill_blockpc_start(sd, ud->skillid, cooldown);
+ }
+ if( battle_config.display_status_timers && sd )
+ clif_status_change(src, SI_ACTIONDELAY, 1, skill_delayfix(src, ud->skillid, ud->skilllv), 0, 0, 0);
+// if( sd )
+// {
+// switch( ud->skillid )
+// {
+// case ????:
+// sd->canequip_tick = tick + ????;
+// break;
+// }
+// }
+ unit_set_walkdelay(src, tick, battle_config.default_walk_delay+skill_get_walkdelay(ud->skillid, ud->skilllv), 1);
+ status_change_end(src,SC_CAMOUFLAGE, INVALID_TIMER);// only normal attack and auto cast skills benefit from its bonuses
+ map_freeblock_lock();
+ skill_castend_pos2(src,ud->skillx,ud->skilly,ud->skillid,ud->skilllv,tick,0);
+
+ if( sd && sd->skillitem != AL_WARP ) // Warp-Portal thru items will clear data in skill_castend_map. [Inkfish]
+ sd->skillitem = sd->skillitemlv = 0;
+
+ if (ud->skilltimer == INVALID_TIMER) {
+ if (md) md->skillidx = -1;
+ else ud->skillid = 0; //Non mobs can't clear this one as it is used for skill condition 'afterskill'
+ ud->skilllv = ud->skillx = ud->skilly = 0;
+ }
+
+ map_freeblock_unlock();
+ return 1;
+ } while(0);
+
+ if( !sd || sd->skillitem != ud->skillid || skill_get_delay(ud->skillid,ud->skilllv) )
+ ud->canact_tick = tick;
+ ud->skillid = ud->skilllv = 0;
+ if(sd)
+ sd->skillitem = sd->skillitemlv = 0;
+ else if(md)
+ md->skillidx = -1;
+ return 0;
}
/*==========================================
*
*------------------------------------------*/
-int skill_castend_pos2(struct block_list *src, int x, int y, int skillid, int skilllv, unsigned int tick, int flag)
+int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int skilllv, unsigned int tick, int flag)
{
- struct map_session_data *sd;
- struct status_change *sc;
- struct status_change_entry *sce;
- struct skill_unit_group *sg;
- enum sc_type type;
- int i;
-
- //if(skilllv <= 0) return 0;
- if (skillid > 0 && skilllv <= 0) return 0; // celest
-
- nullpo_ret(src);
-
- if (status_isdead(src))
- return 0;
-
- sd = BL_CAST(BL_PC, src);
-
- sc = status_get_sc(src);
- type = status_skill2sc(skillid);
- sce = (sc && type != -1)?sc->data[type]:NULL;
-
- switch (skillid) { //Skill effect.
- case WZ_METEOR:
- case MO_BODYRELOCATION:
- case CR_CULTIVATION:
- case HW_GANBANTEIN:
- case LG_EARTHDRIVE:
- break; //Effect is displayed on respective switch case.
- default:
- if (skill_get_inf(skillid)&INF_SELF_SKILL)
- clif_skill_nodamage(src,src,skillid,skilllv,1);
- else
- clif_skill_poseffect(src,skillid,skilllv,x,y,tick);
- }
-
- // SC_MAGICPOWER needs to switch states before any damage is actually dealt
- skill_toggle_magicpower(src, skillid);
-
- switch (skillid) {
- case PR_BENEDICTIO:
- skill_area_temp[1] = src->id;
- i = skill_get_splash(skillid, skilllv);
- map_foreachinarea(skill_area_sub,
- src->m, x-i, y-i, x+i, y+i, BL_PC,
- src, skillid, skilllv, tick, flag|BCT_ALL|1,
- skill_castend_nodamage_id);
- map_foreachinarea(skill_area_sub,
- src->m, x-i, y-i, x+i, y+i, BL_CHAR,
- src, skillid, skilllv, tick, flag|BCT_ENEMY|1,
- skill_castend_damage_id);
- break;
-
- case BS_HAMMERFALL:
- i = skill_get_splash(skillid, skilllv);
- map_foreachinarea(skill_area_sub,
- src->m, x-i, y-i, x+i, y+i, BL_CHAR,
- src, skillid, skilllv, tick, flag|BCT_ENEMY|2,
- skill_castend_nodamage_id);
- break;
-
- case HT_DETECTING:
- i = skill_get_splash(skillid, skilllv);
- map_foreachinarea(status_change_timer_sub,
- src->m, x-i, y-i, x+i,y+i,BL_CHAR,
- src,NULL,SC_SIGHT,tick);
- if (battle_config.traps_setting&1)
- map_foreachinarea(skill_reveal_trap,
- src->m, x-i, y-i, x+i,y+i,BL_SKILL);
- break;
-
- case SR_RIDEINLIGHTNING:
- i = skill_get_splash(skillid, skilllv);
- map_foreachinarea(skill_area_sub, src->m, x-i, y-i, x+i, y+i, BL_CHAR,
- src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_damage_id);
- break;
+ struct map_session_data* sd;
+ struct status_change* sc;
+ struct status_change_entry *sce;
+ struct skill_unit_group* sg;
+ enum sc_type type;
+ int i;
+
+ //if(skilllv <= 0) return 0;
+ if(skillid > 0 && skilllv <= 0) return 0; // celest
+
+ nullpo_ret(src);
+
+ if(status_isdead(src))
+ return 0;
+
+ sd = BL_CAST(BL_PC, src);
+
+ sc = status_get_sc(src);
+ type = status_skill2sc(skillid);
+ sce = (sc && type != -1)?sc->data[type]:NULL;
+
+ switch (skillid) { //Skill effect.
+ case WZ_METEOR:
+ case MO_BODYRELOCATION:
+ case CR_CULTIVATION:
+ case HW_GANBANTEIN:
+ case LG_EARTHDRIVE:
+ break; //Effect is displayed on respective switch case.
+ default:
+ if(skill_get_inf(skillid)&INF_SELF_SKILL)
+ clif_skill_nodamage(src,src,skillid,skilllv,1);
+ else
+ clif_skill_poseffect(src,skillid,skilllv,x,y,tick);
+ }
- case SA_VOLCANO:
- case SA_DELUGE:
- case SA_VIOLENTGALE: {
- //Does not consumes if the skill is already active. [Skotlex]
- struct skill_unit_group *sg;
- if ((sg= skill_locate_element_field(src)) != NULL && (sg->skill_id == SA_VOLCANO || sg->skill_id == SA_DELUGE || sg->skill_id == SA_VIOLENTGALE)) {
- if (sg->limit - DIFF_TICK(gettick(), sg->tick) > 0) {
- skill_unitsetting(src,skillid,skilllv,x,y,0);
- return 0; // not to consume items
- } else
- sg->limit = 0; //Disable it.
- }
- skill_unitsetting(src,skillid,skilllv,x,y,0);
- break;
- }
- case MG_SAFETYWALL:
- case MG_FIREWALL:
- case MG_THUNDERSTORM:
-
- case AL_PNEUMA:
- case WZ_ICEWALL:
- case WZ_FIREPILLAR:
- case WZ_QUAGMIRE:
- case WZ_VERMILION:
- case WZ_STORMGUST:
- case WZ_HEAVENDRIVE:
- case PR_SANCTUARY:
- case PR_MAGNUS:
- case CR_GRANDCROSS:
- case NPC_GRANDDARKNESS:
- case HT_SKIDTRAP:
- case MA_SKIDTRAP:
- case HT_LANDMINE:
- case MA_LANDMINE:
- case HT_ANKLESNARE:
- case HT_SHOCKWAVE:
- case HT_SANDMAN:
- case MA_SANDMAN:
- case HT_FLASHER:
- case HT_FREEZINGTRAP:
- case MA_FREEZINGTRAP:
- case HT_BLASTMINE:
- case HT_CLAYMORETRAP:
- case AS_VENOMDUST:
- case AM_DEMONSTRATION:
- case PF_FOGWALL:
- case PF_SPIDERWEB:
- case HT_TALKIEBOX:
- case WE_CALLPARTNER:
- case WE_CALLPARENT:
- case WE_CALLBABY:
- case AC_SHOWER: //Ground-placed skill implementation.
- case MA_SHOWER:
- case SA_LANDPROTECTOR:
- case BD_LULLABY:
- case BD_RICHMANKIM:
- case BD_ETERNALCHAOS:
- case BD_DRUMBATTLEFIELD:
- case BD_RINGNIBELUNGEN:
- case BD_ROKISWEIL:
- case BD_INTOABYSS:
- case BD_SIEGFRIED:
- case BA_DISSONANCE:
- case BA_POEMBRAGI:
- case BA_WHISTLE:
- case BA_ASSASSINCROSS:
- case BA_APPLEIDUN:
- case DC_UGLYDANCE:
- case DC_HUMMING:
- case DC_DONTFORGETME:
- case DC_FORTUNEKISS:
- case DC_SERVICEFORYOU:
- case CG_MOONLIT:
- case GS_DESPERADO:
- case NJ_KAENSIN:
- case NJ_BAKUENRYU:
- case NJ_SUITON:
- case NJ_HYOUSYOURAKU:
- case NJ_RAIGEKISAI:
- case NJ_KAMAITACHI:
+ // SC_MAGICPOWER needs to switch states before any damage is actually dealt
+ skill_toggle_magicpower(src, skillid);
+
+ switch(skillid)
+ {
+ case PR_BENEDICTIO:
+ skill_area_temp[1] = src->id;
+ i = skill_get_splash(skillid, skilllv);
+ map_foreachinarea(skill_area_sub,
+ src->m, x-i, y-i, x+i, y+i, BL_PC,
+ src, skillid, skilllv, tick, flag|BCT_ALL|1,
+ skill_castend_nodamage_id);
+ map_foreachinarea(skill_area_sub,
+ src->m, x-i, y-i, x+i, y+i, BL_CHAR,
+ src, skillid, skilllv, tick, flag|BCT_ENEMY|1,
+ skill_castend_damage_id);
+ break;
+
+ case BS_HAMMERFALL:
+ i = skill_get_splash(skillid, skilllv);
+ map_foreachinarea (skill_area_sub,
+ src->m, x-i, y-i, x+i, y+i, BL_CHAR,
+ src, skillid, skilllv, tick, flag|BCT_ENEMY|2,
+ skill_castend_nodamage_id);
+ break;
+
+ case HT_DETECTING:
+ i = skill_get_splash(skillid, skilllv);
+ map_foreachinarea( status_change_timer_sub,
+ src->m, x-i, y-i, x+i,y+i,BL_CHAR,
+ src,NULL,SC_SIGHT,tick);
+ if(battle_config.traps_setting&1)
+ map_foreachinarea( skill_reveal_trap,
+ src->m, x-i, y-i, x+i,y+i,BL_SKILL);
+ break;
+
+ case SR_RIDEINLIGHTNING:
+ i = skill_get_splash(skillid, skilllv);
+ map_foreachinarea(skill_area_sub, src->m, x-i, y-i, x+i, y+i, BL_CHAR,
+ src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_damage_id);
+ break;
+
+ case SA_VOLCANO:
+ case SA_DELUGE:
+ case SA_VIOLENTGALE:
+ { //Does not consumes if the skill is already active. [Skotlex]
+ struct skill_unit_group *sg;
+ if ((sg= skill_locate_element_field(src)) != NULL && ( sg->skill_id == SA_VOLCANO || sg->skill_id == SA_DELUGE || sg->skill_id == SA_VIOLENTGALE ))
+ {
+ if (sg->limit - DIFF_TICK(gettick(), sg->tick) > 0)
+ {
+ skill_unitsetting(src,skillid,skilllv,x,y,0);
+ return 0; // not to consume items
+ }
+ else
+ sg->limit = 0; //Disable it.
+ }
+ skill_unitsetting(src,skillid,skilllv,x,y,0);
+ break;
+ }
+ case MG_SAFETYWALL:
+ case MG_FIREWALL:
+ case MG_THUNDERSTORM:
+
+ case AL_PNEUMA:
+ case WZ_ICEWALL:
+ case WZ_FIREPILLAR:
+ case WZ_QUAGMIRE:
+ case WZ_VERMILION:
+ case WZ_STORMGUST:
+ case WZ_HEAVENDRIVE:
+ case PR_SANCTUARY:
+ case PR_MAGNUS:
+ case CR_GRANDCROSS:
+ case NPC_GRANDDARKNESS:
+ case HT_SKIDTRAP:
+ case MA_SKIDTRAP:
+ case HT_LANDMINE:
+ case MA_LANDMINE:
+ case HT_ANKLESNARE:
+ case HT_SHOCKWAVE:
+ case HT_SANDMAN:
+ case MA_SANDMAN:
+ case HT_FLASHER:
+ case HT_FREEZINGTRAP:
+ case MA_FREEZINGTRAP:
+ case HT_BLASTMINE:
+ case HT_CLAYMORETRAP:
+ case AS_VENOMDUST:
+ case AM_DEMONSTRATION:
+ case PF_FOGWALL:
+ case PF_SPIDERWEB:
+ case HT_TALKIEBOX:
+ case WE_CALLPARTNER:
+ case WE_CALLPARENT:
+ case WE_CALLBABY:
+ case AC_SHOWER: //Ground-placed skill implementation.
+ case MA_SHOWER:
+ case SA_LANDPROTECTOR:
+ case BD_LULLABY:
+ case BD_RICHMANKIM:
+ case BD_ETERNALCHAOS:
+ case BD_DRUMBATTLEFIELD:
+ case BD_RINGNIBELUNGEN:
+ case BD_ROKISWEIL:
+ case BD_INTOABYSS:
+ case BD_SIEGFRIED:
+ case BA_DISSONANCE:
+ case BA_POEMBRAGI:
+ case BA_WHISTLE:
+ case BA_ASSASSINCROSS:
+ case BA_APPLEIDUN:
+ case DC_UGLYDANCE:
+ case DC_HUMMING:
+ case DC_DONTFORGETME:
+ case DC_FORTUNEKISS:
+ case DC_SERVICEFORYOU:
+ case CG_MOONLIT:
+ case GS_DESPERADO:
+ case NJ_KAENSIN:
+ case NJ_BAKUENRYU:
+ case NJ_SUITON:
+ case NJ_HYOUSYOURAKU:
+ case NJ_RAIGEKISAI:
+ case NJ_KAMAITACHI:
#ifdef RENEWAL
- case NJ_HUUMA:
+ case NJ_HUUMA:
#endif
- case NPC_EVILLAND:
- case RA_ELECTRICSHOCKER:
- case RA_CLUSTERBOMB:
- case RA_MAGENTATRAP:
- case RA_COBALTTRAP:
- case RA_MAIZETRAP:
- case RA_VERDURETRAP:
- case RA_FIRINGTRAP:
- case RA_ICEBOUNDTRAP:
- case SC_MANHOLE:
- case SC_DIMENSIONDOOR:
- case SC_CHAOSPANIC:
- case SC_MAELSTROM:
- case WM_REVERBERATION:
- case WM_SEVERE_RAINSTORM:
- case WM_POEMOFNETHERWORLD:
- case SO_PSYCHIC_WAVE:
- case SO_VACUUM_EXTREME:
- case GN_WALLOFTHORN:
- case GN_THORNS_TRAP:
- case GN_DEMONIC_FIRE:
- case GN_HELLS_PLANT:
- case SO_EARTHGRAVE:
- case SO_DIAMONDDUST:
- case SO_FIRE_INSIGNIA:
- case SO_WATER_INSIGNIA:
- case SO_WIND_INSIGNIA:
- case SO_EARTH_INSIGNIA:
- case KO_HUUMARANKA:
- case KO_MUCHANAGE:
- case KO_BAKURETSU:
- case KO_ZENKAI:
- case MH_LAVA_SLIDE:
- case MH_VOLCANIC_ASH:
- case MH_POISON_MIST:
- case MH_STEINWAND:
- case MH_XENO_SLASHER:
- flag|=1;//Set flag to 1 to prevent deleting ammo (it will be deleted on group-delete).
- case GS_GROUNDDRIFT: //Ammo should be deleted right away.
- 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);
- flag|=1;
- break;
- case HP_BASILICA:
- if (sc->data[SC_BASILICA])
- status_change_end(src, SC_BASILICA, INVALID_TIMER); // Cancel Basilica
- else {
- // Create Basilica. Start SC on caster. Unit timer start SC on others.
- skill_clear_unitgroup(src);
- if (skill_unitsetting(src,skillid,skilllv,x,y,0))
- sc_start4(src,type,100,skilllv,0,0,src->id,skill_get_time(skillid,skilllv));
- flag|=1;
- }
- break;
- case CG_HERMODE:
- skill_clear_unitgroup(src);
- if ((sg = skill_unitsetting(src,skillid,skilllv,x,y,0)))
- sc_start4(src,SC_DANCING,100,
- skillid,0,skilllv,sg->group_id,skill_get_time(skillid,skilllv));
- flag|=1;
- break;
- case RG_CLEANER: // [Valaris]
- i = skill_get_splash(skillid, skilllv);
- map_foreachinarea(skill_graffitiremover,src->m,x-i,y-i,x+i,y+i,BL_SKILL);
- break;
-
- case SO_WARMER:
- flag|= 8;
- case SO_CLOUD_KILL:
- skill_unitsetting(src,skillid,skilllv,x,y,0);
- break;
-
- case WZ_METEOR: {
- int area = skill_get_splash(skillid, skilllv);
- short tmpx = 0, tmpy = 0, x1 = 0, y1 = 0;
-
- for (i = 0; i < 2 + (skilllv>>1); i++) {
- // Creates a random Cell in the Splash Area
- tmpx = x - area + rnd()%(area * 2 + 1);
- tmpy = y - area + rnd()%(area * 2 + 1);
-
- if (i == 0 && path_search_long(NULL, src->m, src->x, src->y, tmpx, tmpy, CELL_CHKWALL))
- clif_skill_poseffect(src,skillid,skilllv,tmpx,tmpy,tick);
-
- if (i > 0)
- skill_addtimerskill(src,tick+i*1000,0,tmpx,tmpy,skillid,skilllv,(x1<<16)|y1,0);
-
- x1 = tmpx;
- y1 = tmpy;
- }
-
- skill_addtimerskill(src,tick+i*1000,0,tmpx,tmpy,skillid,skilllv,-1,0);
- }
- break;
-
- case AL_WARP:
- if (sd) {
- clif_skill_warppoint(sd, skillid, skilllv, sd->status.save_point.map,
- (skilllv >= 2) ? sd->status.memo_point[0].map : 0,
- (skilllv >= 3) ? sd->status.memo_point[1].map : 0,
- (skilllv >= 4) ? sd->status.memo_point[2].map : 0
- );
- }
- return 0; // not to consume item.
+ case NPC_EVILLAND:
+ case RA_ELECTRICSHOCKER:
+ case RA_CLUSTERBOMB:
+ case RA_MAGENTATRAP:
+ case RA_COBALTTRAP:
+ case RA_MAIZETRAP:
+ case RA_VERDURETRAP:
+ case RA_FIRINGTRAP:
+ case RA_ICEBOUNDTRAP:
+ case SC_MANHOLE:
+ case SC_DIMENSIONDOOR:
+ case SC_CHAOSPANIC:
+ case SC_MAELSTROM:
+ case WM_REVERBERATION:
+ case WM_SEVERE_RAINSTORM:
+ case WM_POEMOFNETHERWORLD:
+ case SO_PSYCHIC_WAVE:
+ case SO_VACUUM_EXTREME:
+ case GN_WALLOFTHORN:
+ case GN_THORNS_TRAP:
+ case GN_DEMONIC_FIRE:
+ case GN_HELLS_PLANT:
+ case SO_EARTHGRAVE:
+ case SO_DIAMONDDUST:
+ case SO_FIRE_INSIGNIA:
+ case SO_WATER_INSIGNIA:
+ case SO_WIND_INSIGNIA:
+ case SO_EARTH_INSIGNIA:
+ case KO_HUUMARANKA:
+ case KO_MUCHANAGE:
+ case KO_BAKURETSU:
+ case KO_ZENKAI:
+ case MH_LAVA_SLIDE:
+ case MH_VOLCANIC_ASH:
+ case MH_POISON_MIST:
+ case MH_STEINWAND:
+ case MH_XENO_SLASHER:
+ flag|=1;//Set flag to 1 to prevent deleting ammo (it will be deleted on group-delete).
+ case GS_GROUNDDRIFT: //Ammo should be deleted right away.
+ 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);
+ flag|=1;
+ break;
+ case HP_BASILICA:
+ if( sc->data[SC_BASILICA] )
+ status_change_end(src, SC_BASILICA, INVALID_TIMER); // Cancel Basilica
+ else
+ { // Create Basilica. Start SC on caster. Unit timer start SC on others.
+ skill_clear_unitgroup(src);
+ if( skill_unitsetting(src,skillid,skilllv,x,y,0) )
+ sc_start4(src,type,100,skilllv,0,0,src->id,skill_get_time(skillid,skilllv));
+ flag|=1;
+ }
+ break;
+ case CG_HERMODE:
+ skill_clear_unitgroup(src);
+ if ((sg = skill_unitsetting(src,skillid,skilllv,x,y,0)))
+ sc_start4(src,SC_DANCING,100,
+ skillid,0,skilllv,sg->group_id,skill_get_time(skillid,skilllv));
+ flag|=1;
+ break;
+ case RG_CLEANER: // [Valaris]
+ i = skill_get_splash(skillid, skilllv);
+ map_foreachinarea(skill_graffitiremover,src->m,x-i,y-i,x+i,y+i,BL_SKILL);
+ break;
+
+ case SO_WARMER:
+ flag|= 8;
+ case SO_CLOUD_KILL:
+ skill_unitsetting(src,skillid,skilllv,x,y,0);
+ break;
+
+ case WZ_METEOR: {
+ int area = skill_get_splash(skillid, skilllv);
+ short tmpx = 0, tmpy = 0, x1 = 0, y1 = 0;
+
+ for( i = 0; i < 2 + (skilllv>>1); i++ ) {
+ // Creates a random Cell in the Splash Area
+ tmpx = x - area + rnd()%(area * 2 + 1);
+ tmpy = y - area + rnd()%(area * 2 + 1);
+
+ if( i == 0 && path_search_long(NULL, src->m, src->x, src->y, tmpx, tmpy, CELL_CHKWALL) )
+ clif_skill_poseffect(src,skillid,skilllv,tmpx,tmpy,tick);
+
+ if( i > 0 )
+ skill_addtimerskill(src,tick+i*1000,0,tmpx,tmpy,skillid,skilllv,(x1<<16)|y1,0);
+
+ x1 = tmpx;
+ y1 = tmpy;
+ }
- case MO_BODYRELOCATION:
- if (unit_movepos(src, x, y, 1, 1)) {
+ skill_addtimerskill(src,tick+i*1000,0,tmpx,tmpy,skillid,skilllv,-1,0);
+ }
+ break;
+
+ case AL_WARP:
+ if(sd)
+ {
+ clif_skill_warppoint(sd, skillid, skilllv, sd->status.save_point.map,
+ (skilllv >= 2) ? sd->status.memo_point[0].map : 0,
+ (skilllv >= 3) ? sd->status.memo_point[1].map : 0,
+ (skilllv >= 4) ? sd->status.memo_point[2].map : 0
+ );
+ }
+ return 0; // not to consume item.
+
+ case MO_BODYRELOCATION:
+ if (unit_movepos(src, x, y, 1, 1)) {
#if PACKETVER >= 20111005
- clif_snap(src, src->x, src->y);
+ clif_snap(src, src->x, src->y);
#else
- clif_skill_poseffect(src,skillid,skilllv,src->x,src->y,tick);
+ clif_skill_poseffect(src,skillid,skilllv,src->x,src->y,tick);
#endif
- if (sd)
- skill_blockpc_start(sd, MO_EXTREMITYFIST, 2000);
- }
- break;
- case NJ_SHADOWJUMP:
- if (!map_flag_gvg(src->m) && !map[src->m].flag.battleground) { //You don't move on GVG grounds.
- unit_movepos(src, x, y, 1, 0);
- clif_slide(src,x,y);
- }
- status_change_end(src, SC_HIDING, INVALID_TIMER);
- break;
- case AM_SPHEREMINE:
- case AM_CANNIBALIZE: {
- int summons[5] = { 1589, 1579, 1575, 1555, 1590 };
- //int summons[5] = { 1020, 1068, 1118, 1500, 1368 };
- int class_ = skillid==AM_SPHEREMINE?1142:summons[skilllv-1];
- struct mob_data *md;
-
- // Correct info, don't change any of this! [celest]
- md = mob_once_spawn_sub(src, src->m, x, y, status_get_name(src), class_, "", SZ_SMALL, AI_NONE);
- if (md) {
- md->master_id = src->id;
- md->special_state.ai = (skillid == AM_SPHEREMINE) ? AI_SPHERE : AI_FLORA;
- if (md->deletetimer != INVALID_TIMER)
- delete_timer(md->deletetimer, mob_timer_delete);
- md->deletetimer = add_timer(gettick() + skill_get_time(skillid,skilllv), mob_timer_delete, md->bl.id, 0);
- mob_spawn(md); //Now it is ready for spawning.
- }
- }
- break;
-
- // Slim Pitcher [Celest]
- case CR_SLIMPITCHER:
- if (sd) {
- 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,USESKILL_FAIL_LEVEL,0);
- return 1;
- }
- potion_flag = 1;
- potion_hp = 0;
- potion_sp = 0;
- run_script(sd->inventory_data[j]->script,0,sd->bl.id,0);
- potion_flag = 0;
- //Apply skill bonuses
- i = pc_checkskill(sd,CR_SLIMPITCHER)*10
- + pc_checkskill(sd,AM_POTIONPITCHER)*10
- + pc_checkskill(sd,AM_LEARNINGPOTION)*5
- + pc_skillheal_bonus(sd, skillid);
-
- potion_hp = potion_hp * (100+i)/100;
- potion_sp = potion_sp * (100+i)/100;
-
- if (potion_hp > 0 || potion_sp > 0) {
- i = skill_get_splash(skillid, skilllv);
- map_foreachinarea(skill_area_sub,
- src->m,x-i,y-i,x+i,y+i,BL_CHAR,
- src,skillid,skilllv,tick,flag|BCT_PARTY|BCT_GUILD|1,
- skill_castend_nodamage_id);
- }
- } else {
- int i = skilllv%11 - 1;
- struct item_data *item;
- i = skill_db[skillid].itemid[i];
- item = itemdb_search(i);
- potion_flag = 1;
- potion_hp = 0;
- potion_sp = 0;
- run_script(item->script,0,src->id,0);
- potion_flag = 0;
- i = skill_get_max(CR_SLIMPITCHER)*10;
-
- potion_hp = potion_hp * (100+i)/100;
- potion_sp = potion_sp * (100+i)/100;
-
- if (potion_hp > 0 || potion_sp > 0) {
- i = skill_get_splash(skillid, skilllv);
- map_foreachinarea(skill_area_sub,
- src->m,x-i,y-i,x+i,y+i,BL_CHAR,
- src,skillid,skilllv,tick,flag|BCT_PARTY|BCT_GUILD|1,
- skill_castend_nodamage_id);
- }
- }
- break;
-
- case HW_GANBANTEIN:
- if (rnd()%100 < 80) {
- int dummy = 1;
- clif_skill_poseffect(src,skillid,skilllv,x,y,tick);
- i = skill_get_splash(skillid, skilllv);
- map_foreachinarea(skill_cell_overlap, src->m, x-i, y-i, x+i, y+i, BL_SKILL, HW_GANBANTEIN, &dummy, src);
- } else {
- if (sd) clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- return 1;
- }
- break;
-
- case HW_GRAVITATION:
- if ((sg = skill_unitsetting(src,skillid,skilllv,x,y,0)))
- sc_start4(src,type,100,skilllv,0,BCT_SELF,sg->group_id,skill_get_time(skillid,skilllv));
- flag|=1;
- break;
-
- // Plant Cultivation [Celest]
- case CR_CULTIVATION:
- if (sd) {
- if (map_count_oncell(src->m,x,y,BL_CHAR) > 0) {
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- return 1;
- }
- clif_skill_poseffect(src,skillid,skilllv,x,y,tick);
- if (rnd()%100 < 50) {
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- } else {
- TBL_MOB *md = mob_once_spawn_sub(src, src->m, x, y, "--ja--",(skilllv < 2 ? 1084+rnd()%2 : 1078+rnd()%6),"", SZ_SMALL, AI_NONE);
- int i;
- if (!md) break;
- if ((i = skill_get_time(skillid, skilllv)) > 0) {
- if (md->deletetimer != INVALID_TIMER)
- delete_timer(md->deletetimer, mob_timer_delete);
- md->deletetimer = add_timer(tick + i, mob_timer_delete, md->bl.id, 0);
- }
- mob_spawn(md);
- }
- }
- break;
-
- case SG_SUN_WARM:
- case SG_MOON_WARM:
- case SG_STAR_WARM:
- skill_clear_unitgroup(src);
- if ((sg = skill_unitsetting(src,skillid,skilllv,src->x,src->y,0)))
- sc_start4(src,type,100,skilllv,0,0,sg->group_id,skill_get_time(skillid,skilllv));
- flag|=1;
- break;
-
- case PA_GOSPEL:
- if (sce && sce->val4 == BCT_SELF) {
- status_change_end(src, SC_GOSPEL, INVALID_TIMER);
- return 0;
- } else {
- sg = skill_unitsetting(src,skillid,skilllv,src->x,src->y,0);
- if (!sg) break;
- if (sce)
- status_change_end(src, type, INVALID_TIMER); //Was under someone else's Gospel. [Skotlex]
- sc_start4(src,type,100,skilllv,0,sg->group_id,BCT_SELF,skill_get_time(skillid,skilllv));
- clif_skill_poseffect(src, skillid, skilllv, 0, 0, tick); // PA_GOSPEL music packet
- }
- break;
- case NJ_TATAMIGAESHI:
- if (skill_unitsetting(src,skillid,skilllv,src->x,src->y,0))
- sc_start(src,type,100,skilllv,skill_get_time2(skillid,skilllv));
- break;
-
- case AM_RESURRECTHOMUN: //[orn]
- if (sd) {
- if (!merc_resurrect_homunculus(sd, 20*skilllv, x, y)) {
- clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
- break;
- }
- }
- break;
-
- case NC_COLDSLOWER:
- case NC_ARMSCANNON:
- case RK_DRAGONBREATH:
- case RK_WINDCUTTER:
- case WM_LULLABY_DEEPSLEEP:
- i = skill_get_splash(skillid,skilllv);
- map_foreachinarea(skill_area_sub,src->m,x-i,y-i,x+i,y+i,splash_target(src),
- src,skillid,skilllv,tick,flag|(skillid==WM_LULLABY_DEEPSLEEP?BCT_ALL:BCT_ENEMY)|1,skill_castend_damage_id);
- break;
- /**
- * Guilotine Cross
- **/
- case GC_POISONSMOKE:
- if (!(sc && sc->data[SC_POISONINGWEAPON])) {
- if (sd)
- clif_skill_fail(sd,skillid,USESKILL_FAIL_GC_POISONINGWEAPON,0);
- return 0;
- }
- clif_skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skillid,skilllv,6);
- skill_unitsetting(src, skillid, skilllv, x, y, flag);
- //status_change_end(src,SC_POISONINGWEAPON,INVALID_TIMER); // 08/31/2011 - When using poison smoke, you no longer lose the poisoning weapon effect.
- break;
- /**
- * Arch Bishop
- **/
- case AB_EPICLESIS:
- if ((sg = skill_unitsetting(src, skillid, skilllv, x, y, 0))) {
- i = sg->unit->range;
- map_foreachinarea(skill_area_sub, src->m, x - i, y - i, x + i, y + i, BL_CHAR, src, ALL_RESURRECTION, 1, tick, flag|BCT_NOENEMY|1,skill_castend_nodamage_id);
- }
- break;
- /**
- * Warlock
- **/
- case WL_COMET:
- if (sc) {
- sc->comet_x = x;
- sc->comet_y = y;
- }
- i = skill_get_splash(skillid,skilllv);
- map_foreachinarea(skill_area_sub,src->m,x-i,y-i,x+i,y+i,splash_target(src),src,skillid,skilllv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
- break;
-
- case WL_EARTHSTRAIN: {
- int i, wave = skilllv + 4, dir = map_calc_dir(src,x,y);
- int sx = x = src->x, sy = y = src->y; // Store first caster's location to avoid glitch on unit setting
-
- for (i = 1; i <= wave; i++) {
- switch (dir) {
- case 0:
- case 1:
- case 7:
- sy = y + i;
- break;
- case 3:
- case 4:
- case 5:
- sy = y - i;
- break;
- case 2:
- sx = x - i;
- break;
- case 6:
- sx = x + i;
- break;
- }
- skill_addtimerskill(src,gettick() + (150 * i),0,sx,sy,skillid,skilllv,dir,flag&2);
- }
- }
- break;
- /**
- * Ranger
- **/
- case RA_DETONATOR:
- i = skill_get_splash(skillid, skilllv);
- map_foreachinarea(skill_detonator, src->m, x-i, y-i, x+i, y+i, BL_SKILL, src);
- clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
- break;
- /**
- * Mechanic
- **/
- case NC_NEUTRALBARRIER:
- case NC_STEALTHFIELD:
- skill_clear_unitgroup(src); // To remove previous skills - cannot used combined
- if ((sg = skill_unitsetting(src,skillid,skilllv,src->x,src->y,0)) != NULL) {
- sc_start2(src,skillid == NC_NEUTRALBARRIER ? SC_NEUTRALBARRIER_MASTER : SC_STEALTHFIELD_MASTER,100,skilllv,sg->group_id,skill_get_time(skillid,skilllv));
- if (sd) pc_overheat(sd,1);
- }
- break;
-
- case NC_SILVERSNIPER: {
- int class_ = 2042;
- struct mob_data *md;
-
- md = mob_once_spawn_sub(src, src->m, x, y, status_get_name(src), class_, "", SZ_SMALL, AI_NONE);
- if (md) {
- md->master_id = src->id;
- md->special_state.ai = AI_FLORA;
- if (md->deletetimer != INVALID_TIMER)
- delete_timer(md->deletetimer, mob_timer_delete);
- md->deletetimer = add_timer(gettick() + skill_get_time(skillid, skilllv), mob_timer_delete, md->bl.id, 0);
- mob_spawn(md);
- }
- }
- break;
-
- case NC_MAGICDECOY:
- if (sd) clif_magicdecoy_list(sd,skilllv,x,y);
- break;
-
- case SC_FEINTBOMB:
- clif_skill_nodamage(src,src,skillid,skilllv,1);
- skill_unitsetting(src,skillid,skilllv,x,y,0); // Set bomb on current Position
- if (skill_blown(src,src,6,unit_getdir(src),0))
- skill_castend_nodamage_id(src,src,TF_HIDING,1,tick,0);
- break;
-
- case LG_OVERBRAND: {
- int width;//according to data from irowiki it actually is a square
- for (width = 0; width < 7; width++)
- for (i = 0; i < 7; i++)
- map_foreachincell(skill_area_sub, src->m, x-2+i, y-2+width, splash_target(src), src, LG_OVERBRAND_BRANDISH, skilllv, tick, flag|BCT_ENEMY,skill_castend_damage_id);
- for (width = 0; width < 7; width++)
- for (i = 0; i < 7; i++)
- map_foreachincell(skill_area_sub, src->m, x-2+i, y-2+width, splash_target(src), src, skillid, skilllv, tick, flag|BCT_ENEMY,skill_castend_damage_id);
- }
- break;
-
- case LG_BANDING:
- if (sc && sc->data[SC_BANDING])
- status_change_end(src,SC_BANDING,INVALID_TIMER);
- else if ((sg = skill_unitsetting(src,skillid,skilllv,src->x,src->y,0)) != NULL) {
- sc_start4(src,SC_BANDING,100,skilllv,0,0,sg->group_id,skill_get_time(skillid,skilllv));
- if (sd) pc_banding(sd,skilllv);
- }
- clif_skill_nodamage(src,src,skillid,skilllv,1);
- break;
-
- case LG_RAYOFGENESIS:
- if (status_charge(src,status_get_max_hp(src)*3*skilllv / 100,0)) {
- i = skill_get_splash(skillid,skilllv);
- map_foreachinarea(skill_area_sub,src->m,x-i,y-i,x+i,y+i,splash_target(src),
- src,skillid,skilllv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
- } else if (sd)
- clif_skill_fail(sd,skillid,USESKILL_FAIL,0);
- break;
-
- case WM_DOMINION_IMPULSE:
- i = skill_get_splash(skillid, skilllv);
- map_foreachinarea(skill_ative_reverberation,
- src->m, x-i, y-i, x+i,y+i,BL_SKILL);
- break;
-
- case WM_GREAT_ECHO:
- flag|=1; // Should counsume 1 item per skill usage.
- map_foreachinrange(skill_area_sub, src, skill_get_splash(skillid,skilllv),splash_target(src), src, skillid, skilllv, tick, flag|BCT_ENEMY, skill_castend_damage_id);
- break;
- case GN_CRAZYWEED: {
- int area = skill_get_splash(GN_CRAZYWEED_ATK, skilllv);
- short x1 = 0, y1 = 0;
-
- for (i = 0; i < 3 + (skilllv/2); i++) {
- x1 = x - area + rnd()%(area * 2 + 1);
- y1 = y - area + rnd()%(area * 2 + 1);
- skill_addtimerskill(src,tick+i*150,0,x1,y1,GN_CRAZYWEED_ATK,skilllv,-1,0);
- }
- }
- break;
- case GN_FIRE_EXPANSION: {
- int i;
- struct unit_data *ud = unit_bl2ud(src);
-
- if (!ud) break;
-
- for (i = 0; i < MAX_SKILLUNITGROUP && ud->skillunit[i]; i ++) {
- if (ud->skillunit[i]->skill_id == GN_DEMONIC_FIRE &&
- distance_xy(x, y, ud->skillunit[i]->unit->bl.x, ud->skillunit[i]->unit->bl.y) < 4) {
- switch (skilllv) {
- case 3:
- ud->skillunit[i]->unit_id = UNT_FIRE_EXPANSION_SMOKE_POWDER;
- clif_changetraplook(&ud->skillunit[i]->unit->bl, UNT_FIRE_EXPANSION_SMOKE_POWDER);
- break;
- case 4:
- ud->skillunit[i]->unit_id = UNT_FIRE_EXPANSION_TEAR_GAS;
- clif_changetraplook(&ud->skillunit[i]->unit->bl, UNT_FIRE_EXPANSION_TEAR_GAS);
- break;
- case 5:
- map_foreachinarea(skill_area_sub, src->m,
- ud->skillunit[i]->unit->bl.x - 3, ud->skillunit[i]->unit->bl.y - 3,
- ud->skillunit[i]->unit->bl.x + 3, ud->skillunit[i]->unit->bl.y + 3, BL_CHAR,
- src, CR_ACIDDEMONSTRATION, sd ? pc_checkskill(sd, CR_ACIDDEMONSTRATION) : skilllv, tick, flag|BCT_ENEMY|1|SD_LEVEL, skill_castend_damage_id);
- skill_delunit(ud->skillunit[i]->unit);
- break;
- default:
- ud->skillunit[i]->unit->val2 = skilllv;
- ud->skillunit[i]->unit->group->val2 = skilllv;
- break;
- }
- }
- }
- }
- break;
-
- case SO_FIREWALK:
- case SO_ELECTRICWALK:
- if (sc && sc->data[type])
- status_change_end(src,type,INVALID_TIMER);
- clif_skill_nodamage(src, src ,skillid, skilllv,
- sc_start2(src, type, 100, skillid, skilllv, skill_get_time(skillid, skilllv)));
- break;
-
- case SC_BLOODYLUST: //set in another group so instance will move if recasted
+ if (sd)
+ skill_blockpc_start (sd, MO_EXTREMITYFIST, 2000);
+ }
+ break;
+ case NJ_SHADOWJUMP:
+ if( !map_flag_gvg(src->m) && !map[src->m].flag.battleground ) { //You don't move on GVG grounds.
+ unit_movepos(src, x, y, 1, 0);
+ clif_slide(src,x,y);
+ }
+ status_change_end(src, SC_HIDING, INVALID_TIMER);
+ break;
+ case AM_SPHEREMINE:
+ case AM_CANNIBALIZE:
+ {
+ int summons[5] = { 1589, 1579, 1575, 1555, 1590 };
+ //int summons[5] = { 1020, 1068, 1118, 1500, 1368 };
+ int class_ = skillid==AM_SPHEREMINE?1142:summons[skilllv-1];
+ struct mob_data *md;
+
+ // Correct info, don't change any of this! [celest]
+ md = mob_once_spawn_sub(src, src->m, x, y, status_get_name(src), class_, "", SZ_SMALL, AI_NONE);
+ if (md) {
+ md->master_id = src->id;
+ md->special_state.ai = (skillid == AM_SPHEREMINE) ? AI_SPHERE : AI_FLORA;
+ if( md->deletetimer != INVALID_TIMER )
+ delete_timer(md->deletetimer, mob_timer_delete);
+ md->deletetimer = add_timer (gettick() + skill_get_time(skillid,skilllv), mob_timer_delete, md->bl.id, 0);
+ mob_spawn (md); //Now it is ready for spawning.
+ }
+ }
+ break;
+
+ // Slim Pitcher [Celest]
+ case CR_SLIMPITCHER:
+ if (sd) {
+ 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,USESKILL_FAIL_LEVEL,0);
+ return 1;
+ }
+ potion_flag = 1;
+ potion_hp = 0;
+ potion_sp = 0;
+ run_script(sd->inventory_data[j]->script,0,sd->bl.id,0);
+ potion_flag = 0;
+ //Apply skill bonuses
+ i = pc_checkskill(sd,CR_SLIMPITCHER)*10
+ + pc_checkskill(sd,AM_POTIONPITCHER)*10
+ + pc_checkskill(sd,AM_LEARNINGPOTION)*5
+ + pc_skillheal_bonus(sd, skillid);
+
+ potion_hp = potion_hp * (100+i)/100;
+ potion_sp = potion_sp * (100+i)/100;
+
+ if(potion_hp > 0 || potion_sp > 0) {
+ i = skill_get_splash(skillid, skilllv);
+ map_foreachinarea(skill_area_sub,
+ src->m,x-i,y-i,x+i,y+i,BL_CHAR,
+ src,skillid,skilllv,tick,flag|BCT_PARTY|BCT_GUILD|1,
+ skill_castend_nodamage_id);
+ }
+ } else {
+ int i = skilllv%11 - 1;
+ struct item_data *item;
+ i = skill_db[skillid].itemid[i];
+ item = itemdb_search(i);
+ potion_flag = 1;
+ potion_hp = 0;
+ potion_sp = 0;
+ run_script(item->script,0,src->id,0);
+ potion_flag = 0;
+ i = skill_get_max(CR_SLIMPITCHER)*10;
+
+ potion_hp = potion_hp * (100+i)/100;
+ potion_sp = potion_sp * (100+i)/100;
+
+ if(potion_hp > 0 || potion_sp > 0) {
+ i = skill_get_splash(skillid, skilllv);
+ map_foreachinarea(skill_area_sub,
+ src->m,x-i,y-i,x+i,y+i,BL_CHAR,
+ src,skillid,skilllv,tick,flag|BCT_PARTY|BCT_GUILD|1,
+ skill_castend_nodamage_id);
+ }
+ }
+ break;
+
+ case HW_GANBANTEIN:
+ if (rnd()%100 < 80) {
+ int dummy = 1;
+ clif_skill_poseffect(src,skillid,skilllv,x,y,tick);
+ i = skill_get_splash(skillid, skilllv);
+ map_foreachinarea(skill_cell_overlap, src->m, x-i, y-i, x+i, y+i, BL_SKILL, HW_GANBANTEIN, &dummy, src);
+ } else {
+ if (sd) clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ return 1;
+ }
+ break;
+
+ case HW_GRAVITATION:
+ if ((sg = skill_unitsetting(src,skillid,skilllv,x,y,0)))
+ sc_start4(src,type,100,skilllv,0,BCT_SELF,sg->group_id,skill_get_time(skillid,skilllv));
+ flag|=1;
+ break;
+
+ // Plant Cultivation [Celest]
+ case CR_CULTIVATION:
+ if (sd) {
+ if( map_count_oncell(src->m,x,y,BL_CHAR) > 0 )
+ {
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ return 1;
+ }
+ clif_skill_poseffect(src,skillid,skilllv,x,y,tick);
+ if (rnd()%100 < 50) {
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ } else {
+ TBL_MOB* md = mob_once_spawn_sub(src, src->m, x, y, "--ja--",(skilllv < 2 ? 1084+rnd()%2 : 1078+rnd()%6),"", SZ_SMALL, AI_NONE);
+ int i;
+ if (!md) break;
+ if ((i = skill_get_time(skillid, skilllv)) > 0)
+ {
+ if( md->deletetimer != INVALID_TIMER )
+ delete_timer(md->deletetimer, mob_timer_delete);
+ md->deletetimer = add_timer (tick + i, mob_timer_delete, md->bl.id, 0);
+ }
+ mob_spawn (md);
+ }
+ }
+ break;
+
+ case SG_SUN_WARM:
+ case SG_MOON_WARM:
+ case SG_STAR_WARM:
+ skill_clear_unitgroup(src);
+ if ((sg = skill_unitsetting(src,skillid,skilllv,src->x,src->y,0)))
+ sc_start4(src,type,100,skilllv,0,0,sg->group_id,skill_get_time(skillid,skilllv));
+ flag|=1;
+ break;
+
+ case PA_GOSPEL:
+ if (sce && sce->val4 == BCT_SELF)
+ {
+ status_change_end(src, SC_GOSPEL, INVALID_TIMER);
+ return 0;
+ }
+ else
+ {
+ sg = skill_unitsetting(src,skillid,skilllv,src->x,src->y,0);
+ if (!sg) break;
+ if (sce)
+ status_change_end(src, type, INVALID_TIMER); //Was under someone else's Gospel. [Skotlex]
+ sc_start4(src,type,100,skilllv,0,sg->group_id,BCT_SELF,skill_get_time(skillid,skilllv));
+ clif_skill_poseffect(src, skillid, skilllv, 0, 0, tick); // PA_GOSPEL music packet
+ }
+ break;
+ case NJ_TATAMIGAESHI:
+ if (skill_unitsetting(src,skillid,skilllv,src->x,src->y,0))
+ sc_start(src,type,100,skilllv,skill_get_time2(skillid,skilllv));
+ break;
+
+ case AM_RESURRECTHOMUN: //[orn]
+ if (sd)
+ {
+ if (!merc_resurrect_homunculus(sd, 20*skilllv, x, y))
+ {
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+ }
+ break;
+
+ case NC_COLDSLOWER:
+ case NC_ARMSCANNON:
+ case RK_DRAGONBREATH:
+ case RK_WINDCUTTER:
+ case WM_LULLABY_DEEPSLEEP:
+ i = skill_get_splash(skillid,skilllv);
+ map_foreachinarea(skill_area_sub,src->m,x-i,y-i,x+i,y+i,splash_target(src),
+ src,skillid,skilllv,tick,flag|(skillid==WM_LULLABY_DEEPSLEEP?BCT_ALL:BCT_ENEMY)|1,skill_castend_damage_id);
+ break;
+ /**
+ * Guilotine Cross
+ **/
+ case GC_POISONSMOKE:
+ if( !(sc && sc->data[SC_POISONINGWEAPON]) ) {
+ if( sd )
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_GC_POISONINGWEAPON,0);
+ return 0;
+ }
+ clif_skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skillid,skilllv,6);
+ skill_unitsetting(src, skillid, skilllv, x, y, flag);
+ //status_change_end(src,SC_POISONINGWEAPON,INVALID_TIMER); // 08/31/2011 - When using poison smoke, you no longer lose the poisoning weapon effect.
+ break;
+ /**
+ * Arch Bishop
+ **/
+ case AB_EPICLESIS:
+ if( (sg = skill_unitsetting(src, skillid, skilllv, x, y, 0)) ) {
+ i = sg->unit->range;
+ map_foreachinarea(skill_area_sub, src->m, x - i, y - i, x + i, y + i, BL_CHAR, src, ALL_RESURRECTION, 1, tick, flag|BCT_NOENEMY|1,skill_castend_nodamage_id);
+ }
+ break;
+ /**
+ * Warlock
+ **/
+ case WL_COMET:
+ if( sc ) {
+ sc->comet_x = x;
+ sc->comet_y = y;
+ }
+ i = skill_get_splash(skillid,skilllv);
+ map_foreachinarea(skill_area_sub,src->m,x-i,y-i,x+i,y+i,splash_target(src),src,skillid,skilllv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
+ break;
+
+ case WL_EARTHSTRAIN:
+ {
+ int i, wave = skilllv + 4, dir = map_calc_dir(src,x,y);
+ int sx = x = src->x, sy = y = src->y; // Store first caster's location to avoid glitch on unit setting
+
+ for( i = 1; i <= wave; i++ )
+ {
+ switch( dir ){
+ case 0: case 1: case 7: sy = y + i; break;
+ case 3: case 4: case 5: sy = y - i; break;
+ case 2: sx = x - i; break;
+ case 6: sx = x + i; break;
+ }
+ skill_addtimerskill(src,gettick() + (150 * i),0,sx,sy,skillid,skilllv,dir,flag&2);
+ }
+ }
+ break;
+ /**
+ * Ranger
+ **/
+ case RA_DETONATOR:
+ i = skill_get_splash(skillid, skilllv);
+ map_foreachinarea(skill_detonator, src->m, x-i, y-i, x+i, y+i, BL_SKILL, src);
+ clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+ break;
+ /**
+ * Mechanic
+ **/
+ case NC_NEUTRALBARRIER:
+ case NC_STEALTHFIELD:
+ skill_clear_unitgroup(src); // To remove previous skills - cannot used combined
+ if( (sg = skill_unitsetting(src,skillid,skilllv,src->x,src->y,0)) != NULL ) {
+ sc_start2(src,skillid == NC_NEUTRALBARRIER ? SC_NEUTRALBARRIER_MASTER : SC_STEALTHFIELD_MASTER,100,skilllv,sg->group_id,skill_get_time(skillid,skilllv));
+ if( sd ) pc_overheat(sd,1);
+ }
+ break;
+
+ case NC_SILVERSNIPER:
+ {
+ int class_ = 2042;
+ struct mob_data *md;
+
+ md = mob_once_spawn_sub(src, src->m, x, y, status_get_name(src), class_, "", SZ_SMALL, AI_NONE);
+ if( md )
+ {
+ md->master_id = src->id;
+ md->special_state.ai = AI_FLORA;
+ if( md->deletetimer != INVALID_TIMER )
+ delete_timer(md->deletetimer, mob_timer_delete);
+ md->deletetimer = add_timer (gettick() + skill_get_time(skillid, skilllv), mob_timer_delete, md->bl.id, 0);
+ mob_spawn( md );
+ }
+ }
+ break;
+
+ case NC_MAGICDECOY:
+ if( sd ) clif_magicdecoy_list(sd,skilllv,x,y);
+ break;
+
+ case SC_FEINTBOMB:
+ clif_skill_nodamage(src,src,skillid,skilllv,1);
+ skill_unitsetting(src,skillid,skilllv,x,y,0); // Set bomb on current Position
+ if( skill_blown(src,src,6,unit_getdir(src),0) )
+ skill_castend_nodamage_id(src,src,TF_HIDING,1,tick,0);
+ break;
+
+ case LG_OVERBRAND:
+ {
+ int width;//according to data from irowiki it actually is a square
+ for( width = 0; width < 7; width++ )
+ for( i = 0; i < 7; i++ )
+ map_foreachincell(skill_area_sub, src->m, x-2+i, y-2+width, splash_target(src), src, LG_OVERBRAND_BRANDISH, skilllv, tick, flag|BCT_ENEMY,skill_castend_damage_id);
+ for( width = 0; width < 7; width++ )
+ for( i = 0; i < 7; i++ )
+ map_foreachincell(skill_area_sub, src->m, x-2+i, y-2+width, splash_target(src), src, skillid, skilllv, tick, flag|BCT_ENEMY,skill_castend_damage_id);
+ }
+ break;
+
+ case LG_BANDING:
+ if( sc && sc->data[SC_BANDING] )
+ status_change_end(src,SC_BANDING,INVALID_TIMER);
+ else if( (sg = skill_unitsetting(src,skillid,skilllv,src->x,src->y,0)) != NULL ) {
+ sc_start4(src,SC_BANDING,100,skilllv,0,0,sg->group_id,skill_get_time(skillid,skilllv));
+ if( sd ) pc_banding(sd,skilllv);
+ }
+ clif_skill_nodamage(src,src,skillid,skilllv,1);
+ break;
+
+ case LG_RAYOFGENESIS:
+ if( status_charge(src,status_get_max_hp(src)*3*skilllv / 100,0) ) {
+ i = skill_get_splash(skillid,skilllv);
+ map_foreachinarea(skill_area_sub,src->m,x-i,y-i,x+i,y+i,splash_target(src),
+ src,skillid,skilllv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
+ } else if( sd )
+ clif_skill_fail(sd,skillid,USESKILL_FAIL,0);
+ break;
+
+ case WM_DOMINION_IMPULSE:
+ i = skill_get_splash(skillid, skilllv);
+ map_foreachinarea( skill_ative_reverberation,
+ src->m, x-i, y-i, x+i,y+i,BL_SKILL);
+ break;
+
+ case WM_GREAT_ECHO:
+ flag|=1; // Should counsume 1 item per skill usage.
+ map_foreachinrange(skill_area_sub, src, skill_get_splash(skillid,skilllv),splash_target(src), src, skillid, skilllv, tick, flag|BCT_ENEMY, skill_castend_damage_id);
+ break;
+ case GN_CRAZYWEED: {
+ int area = skill_get_splash(GN_CRAZYWEED_ATK, skilllv);
+ short x1 = 0, y1 = 0;
+
+ for( i = 0; i < 3 + (skilllv/2); i++ ) {
+ x1 = x - area + rnd()%(area * 2 + 1);
+ y1 = y - area + rnd()%(area * 2 + 1);
+ skill_addtimerskill(src,tick+i*150,0,x1,y1,GN_CRAZYWEED_ATK,skilllv,-1,0);
+ }
+ }
+ break;
+ case GN_FIRE_EXPANSION: {
+ int i;
+ struct unit_data *ud = unit_bl2ud(src);
+
+ if( !ud ) break;
+
+ for( i = 0; i < MAX_SKILLUNITGROUP && ud->skillunit[i]; i ++ ) {
+ if( ud->skillunit[i]->skill_id == GN_DEMONIC_FIRE &&
+ distance_xy(x, y, ud->skillunit[i]->unit->bl.x, ud->skillunit[i]->unit->bl.y) < 4 ) {
+ switch( skilllv ) {
+ case 3:
+ ud->skillunit[i]->unit_id = UNT_FIRE_EXPANSION_SMOKE_POWDER;
+ clif_changetraplook(&ud->skillunit[i]->unit->bl, UNT_FIRE_EXPANSION_SMOKE_POWDER);
+ break;
+ case 4:
+ ud->skillunit[i]->unit_id = UNT_FIRE_EXPANSION_TEAR_GAS;
+ clif_changetraplook(&ud->skillunit[i]->unit->bl, UNT_FIRE_EXPANSION_TEAR_GAS);
+ break;
+ case 5:
+ map_foreachinarea(skill_area_sub, src->m,
+ ud->skillunit[i]->unit->bl.x - 3, ud->skillunit[i]->unit->bl.y - 3,
+ ud->skillunit[i]->unit->bl.x + 3, ud->skillunit[i]->unit->bl.y + 3, BL_CHAR,
+ src, CR_ACIDDEMONSTRATION, sd ? pc_checkskill(sd, CR_ACIDDEMONSTRATION) : skilllv, tick, flag|BCT_ENEMY|1|SD_LEVEL, skill_castend_damage_id);
+ skill_delunit(ud->skillunit[i]->unit);
+ break;
+ default:
+ ud->skillunit[i]->unit->val2 = skilllv;
+ ud->skillunit[i]->unit->group->val2 = skilllv;
+ break;
+ }
+ }
+ }
+ }
+ break;
+
+ case SO_FIREWALK:
+ case SO_ELECTRICWALK:
+ if( sc && sc->data[type] )
+ status_change_end(src,type,INVALID_TIMER);
+ clif_skill_nodamage(src, src ,skillid, skilllv,
+ sc_start2(src, type, 100, skillid, skilllv, skill_get_time(skillid, skilllv)));
+ break;
+
+ case SC_BLOODYLUST: //set in another group so instance will move if recasted
flag |= 33;
skill_unitsetting(src, skillid, skilllv, x, y, 0);
break;
- case KO_MAKIBISHI:
- for (i = 0; i < (skilllv+2); i++) {
- x = src->x - 1 + rnd()%3;
- y = src->y - 1 + rnd()%3;
- skill_unitsetting(src,skillid,skilllv,x,y,0);
- }
- break;
+ case KO_MAKIBISHI:
+ for( i = 0; i < (skilllv+2); i++ ) {
+ x = src->x - 1 + rnd()%3;
+ y = src->y - 1 + rnd()%3;
+ skill_unitsetting(src,skillid,skilllv,x,y,0);
+ }
+ break;
- default:
- ShowWarning("skill_castend_pos2: Unknown skill used:%d\n",skillid);
- return 1;
- }
+ default:
+ ShowWarning("skill_castend_pos2: Unknown skill used:%d\n",skillid);
+ return 1;
+ }
- if (sc && sc->data[SC_CURSEDCIRCLE_ATKER]) //Should only remove after the skill has been casted.
- status_change_end(src,SC_CURSEDCIRCLE_ATKER,INVALID_TIMER);
+ if( sc && sc->data[SC_CURSEDCIRCLE_ATKER] ) //Should only remove after the skill has been casted.
+ status_change_end(src,SC_CURSEDCIRCLE_ATKER,INVALID_TIMER);
- if (sd) {
- // ensure that the skill last-cast tick is recorded
- sd->canskill_tick = gettick();
+ if( sd )
+ {// ensure that the skill last-cast tick is recorded
+ sd->canskill_tick = gettick();
- if (sd->state.arrow_atk && !(flag&1)) {
- // consume arrow if this is a ground skill
- battle_consume_ammo(sd, skillid, skilllv);
- }
+ if( sd->state.arrow_atk && !(flag&1) )
+ {// consume arrow if this is a ground skill
+ battle_consume_ammo(sd, skillid, skilllv);
+ }
- // perform skill requirement consumption
- skill_consume_requirement(sd,skillid,skilllv,2);
- }
+ // perform skill requirement consumption
+ skill_consume_requirement(sd,skillid,skilllv,2);
+ }
- return 0;
+ return 0;
}
/*==========================================
*
*------------------------------------------*/
-int skill_castend_map(struct map_session_data *sd, short skill_num, const char *map)
+int skill_castend_map (struct map_session_data *sd, short skill_num, const char *map)
{
- nullpo_ret(sd);
+ nullpo_ret(sd);
- //Simplify skill_failed code.
+//Simplify skill_failed code.
#define skill_failed(sd) { sd->menuskill_id = sd->menuskill_val = 0; }
- if (skill_num != sd->menuskill_id)
- return 0;
-
- if (sd->bl.prev == NULL || pc_isdead(sd)) {
- skill_failed(sd);
- return 0;
- }
-
- if ((sd->sc.opt1 && sd->sc.opt1 != OPT1_BURNING) || sd->sc.option&OPTION_HIDE) {
- skill_failed(sd);
- return 0;
- }
- if (sd->sc.count && (
- sd->sc.data[SC_SILENCE] ||
- sd->sc.data[SC_ROKISWEIL] ||
- sd->sc.data[SC_AUTOCOUNTER] ||
- sd->sc.data[SC_STEELBODY] ||
- (sd->sc.data[SC_DANCING] && skill_num < RK_ENCHANTBLADE && !pc_checkskill(sd, WM_LESSON)) ||
- sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] ||
- sd->sc.data[SC_BASILICA] ||
- sd->sc.data[SC_MARIONETTE] ||
- sd->sc.data[SC_WHITEIMPRISON] ||
- (sd->sc.data[SC_STASIS] && skill_block_check(&sd->bl, SC_STASIS, skill_num)) ||
- (sd->sc.data[SC_KAGEHUMI] && skill_block_check(&sd->bl, SC_KAGEHUMI, skill_num)) ||
- sd->sc.data[SC_OBLIVIONCURSE] ||
- sd->sc.data[SC__MANHOLE] ||
- (sd->sc.data[SC_ASH] && rnd()%2) //50% fail chance under ASH
- )) {
- skill_failed(sd);
- return 0;
- }
-
- pc_stop_attack(sd);
- pc_stop_walking(sd,0);
-
- if (battle_config.skill_log && battle_config.skill_log&BL_PC)
- ShowInfo("PC %d skill castend skill =%d map=%s\n",sd->bl.id,skill_num,map);
-
- if (strcmp(map,"cancel")==0) {
- skill_failed(sd);
- return 0;
- }
-
- switch (skill_num) {
- case AL_TELEPORT:
- if (strcmp(map,"Random")==0)
- pc_randomwarp(sd,CLR_TELEPORT);
- else if (sd->menuskill_val > 1) //Need lv2 to be able to warp here.
- pc_setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT);
- break;
+ if(skill_num != sd->menuskill_id)
+ return 0;
- case AL_WARP: {
- const struct point *p[4];
- struct skill_unit_group *group;
- int i, lv, wx, wy;
- int maxcount=0;
- int x,y;
- unsigned short mapindex;
-
- mapindex = mapindex_name2id((char *)map);
- if (!mapindex) { //Given map not found?
- clif_skill_fail(sd,skill_num,USESKILL_FAIL_LEVEL,0);
- skill_failed(sd);
- return 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(skill_num, sd->menuskill_val)) > 0) {
- for (i=0; i<MAX_SKILLUNITGROUP && sd->ud.skillunit[i] && maxcount; i++) {
- if (sd->ud.skillunit[i]->skill_id == skill_num)
- maxcount--;
- }
- if (!maxcount) {
- clif_skill_fail(sd,skill_num,USESKILL_FAIL_LEVEL,0);
- skill_failed(sd);
- return 0;
- }
- }
+ if( sd->bl.prev == NULL || pc_isdead(sd) ) {
+ skill_failed(sd);
+ return 0;
+ }
- lv = sd->skillitem==skill_num?sd->skillitemlv:pc_checkskill(sd,skill_num);
- wx = sd->menuskill_val>>16;
- wy = sd->menuskill_val&0xffff;
-
- if (lv <= 0) return 0;
- if (lv > 4) lv = 4; // crash prevention
-
- // check if the chosen map exists in the memo list
- ARR_FIND(0, lv, i, mapindex == p[i]->map);
- if (i < lv) {
- x=p[i]->x;
- y=p[i]->y;
- } else {
- skill_failed(sd);
- return 0;
- }
+ if( ( sd->sc.opt1 && sd->sc.opt1 != OPT1_BURNING ) || sd->sc.option&OPTION_HIDE ) {
+ skill_failed(sd);
+ return 0;
+ }
+ if(sd->sc.count && (
+ sd->sc.data[SC_SILENCE] ||
+ sd->sc.data[SC_ROKISWEIL] ||
+ sd->sc.data[SC_AUTOCOUNTER] ||
+ sd->sc.data[SC_STEELBODY] ||
+ (sd->sc.data[SC_DANCING] && skill_num < RK_ENCHANTBLADE && !pc_checkskill(sd, WM_LESSON)) ||
+ sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] ||
+ sd->sc.data[SC_BASILICA] ||
+ sd->sc.data[SC_MARIONETTE] ||
+ sd->sc.data[SC_WHITEIMPRISON] ||
+ (sd->sc.data[SC_STASIS] && skill_block_check(&sd->bl, SC_STASIS, skill_num)) ||
+ (sd->sc.data[SC_KAGEHUMI] && skill_block_check(&sd->bl, SC_KAGEHUMI, skill_num)) ||
+ sd->sc.data[SC_OBLIVIONCURSE] ||
+ sd->sc.data[SC__MANHOLE] ||
+ (sd->sc.data[SC_ASH] && rnd()%2) //50% fail chance under ASH
+ )) {
+ skill_failed(sd);
+ return 0;
+ }
- if (!skill_check_condition_castend(sd, sd->menuskill_id, lv)) {
- // This checks versus skillid/skilllv...
- skill_failed(sd);
- return 0;
- }
+ pc_stop_attack(sd);
+ pc_stop_walking(sd,0);
- skill_consume_requirement(sd,sd->menuskill_id,lv,2);
- sd->skillitem = sd->skillitemlv = 0; // Clear data that's skipped in 'skill_castend_pos' [Inkfish]
+ if(battle_config.skill_log && battle_config.skill_log&BL_PC)
+ ShowInfo("PC %d skill castend skill =%d map=%s\n",sd->bl.id,skill_num,map);
- if ((group=skill_unitsetting(&sd->bl,skill_num,lv,wx,wy,0))==NULL) {
- skill_failed(sd);
- return 0;
- }
+ if(strcmp(map,"cancel")==0) {
+ skill_failed(sd);
+ return 0;
+ }
- group->val1 = (group->val1<<16)|(short)0;
- // record the destination coordinates
- group->val2 = (x<<16)|y;
- group->val3 = mapindex;
- }
- break;
- }
+ switch(skill_num)
+ {
+ case AL_TELEPORT:
+ if(strcmp(map,"Random")==0)
+ pc_randomwarp(sd,CLR_TELEPORT);
+ else if (sd->menuskill_val > 1) //Need lv2 to be able to warp here.
+ pc_setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT);
+ break;
+
+ case AL_WARP:
+ {
+ const struct point *p[4];
+ struct skill_unit_group *group;
+ int i, lv, wx, wy;
+ int maxcount=0;
+ int x,y;
+ unsigned short mapindex;
+
+ mapindex = mapindex_name2id((char*)map);
+ if(!mapindex) { //Given map not found?
+ clif_skill_fail(sd,skill_num,USESKILL_FAIL_LEVEL,0);
+ skill_failed(sd);
+ return 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(skill_num, sd->menuskill_val)) > 0) {
+ for(i=0;i<MAX_SKILLUNITGROUP && sd->ud.skillunit[i] && maxcount;i++) {
+ if(sd->ud.skillunit[i]->skill_id == skill_num)
+ maxcount--;
+ }
+ if(!maxcount) {
+ clif_skill_fail(sd,skill_num,USESKILL_FAIL_LEVEL,0);
+ skill_failed(sd);
+ return 0;
+ }
+ }
+
+ lv = sd->skillitem==skill_num?sd->skillitemlv:pc_checkskill(sd,skill_num);
+ wx = sd->menuskill_val>>16;
+ wy = sd->menuskill_val&0xffff;
+
+ if( lv <= 0 ) return 0;
+ if( lv > 4 ) lv = 4; // crash prevention
+
+ // check if the chosen map exists in the memo list
+ ARR_FIND( 0, lv, i, mapindex == p[i]->map );
+ if( i < lv ) {
+ x=p[i]->x;
+ y=p[i]->y;
+ } else {
+ skill_failed(sd);
+ return 0;
+ }
+
+ if(!skill_check_condition_castend(sd, sd->menuskill_id, lv))
+ { // This checks versus skillid/skilllv...
+ skill_failed(sd);
+ return 0;
+ }
- sd->menuskill_id = sd->menuskill_val = 0;
- return 0;
+ skill_consume_requirement(sd,sd->menuskill_id,lv,2);
+ sd->skillitem = sd->skillitemlv = 0; // Clear data that's skipped in 'skill_castend_pos' [Inkfish]
+
+ if((group=skill_unitsetting(&sd->bl,skill_num,lv,wx,wy,0))==NULL) {
+ skill_failed(sd);
+ return 0;
+ }
+
+ group->val1 = (group->val1<<16)|(short)0;
+ // record the destination coordinates
+ group->val2 = (x<<16)|y;
+ group->val3 = mapindex;
+ }
+ break;
+ }
+
+ sd->menuskill_id = sd->menuskill_val = 0;
+ return 0;
#undef skill_failed
}
/// transforms 'target' skill unit into dissonance (if conditions are met)
-static int skill_dance_overlap_sub(struct block_list *bl, va_list ap)
+static int skill_dance_overlap_sub(struct block_list* bl, va_list ap)
{
- struct skill_unit *target = (struct skill_unit *)bl;
- struct skill_unit *src = va_arg(ap, struct skill_unit *);
- int flag = va_arg(ap, int);
+ struct skill_unit* target = (struct skill_unit*)bl;
+ struct skill_unit* src = va_arg(ap, struct skill_unit*);
+ int flag = va_arg(ap, int);
- if (src == target)
- return 0;
- if (!target->group || !(target->group->state.song_dance&0x1))
- return 0;
- if (!(target->val2 & src->val2 & ~UF_ENSEMBLE)) //They don't match (song + dance) is valid.
- return 0;
+ if (src == target)
+ return 0;
+ if (!target->group || !(target->group->state.song_dance&0x1))
+ return 0;
+ if (!(target->val2 & src->val2 & ~UF_ENSEMBLE)) //They don't match (song + dance) is valid.
+ return 0;
- if (flag) //Set dissonance
- target->val2 |= UF_ENSEMBLE; //Add ensemble to signal this unit is overlapping.
- else //Remove dissonance
- target->val2 &= ~UF_ENSEMBLE;
+ if (flag) //Set dissonance
+ target->val2 |= UF_ENSEMBLE; //Add ensemble to signal this unit is overlapping.
+ else //Remove dissonance
+ target->val2 &= ~UF_ENSEMBLE;
- clif_skill_setunit(target); //Update look of affected cell.
+ clif_skill_setunit(target); //Update look of affected cell.
- return 1;
+ return 1;
}
//Does the song/dance overlapping -> dissonance check. [Skotlex]
//When flag is 0, this unit is about to be removed, cancel the dissonance effect
//When 1, this unit has been positioned, so start the cancel effect.
-int skill_dance_overlap(struct skill_unit *unit, int flag)
+int skill_dance_overlap(struct skill_unit* unit, int flag)
{
- if (!unit || !unit->group || !(unit->group->state.song_dance&0x1))
- return 0;
- if (!flag && !(unit->val2&UF_ENSEMBLE))
- return 0; //Nothing to remove, this unit is not overlapped.
-
- if (unit->val1 != unit->group->skill_id) {
- //Reset state
- unit->val1 = unit->group->skill_id;
- unit->val2 &= ~UF_ENSEMBLE;
- }
-
- return map_foreachincell(skill_dance_overlap_sub, unit->bl.m,unit->bl.x,unit->bl.y,BL_SKILL, unit,flag);
+ if (!unit || !unit->group || !(unit->group->state.song_dance&0x1))
+ return 0;
+ if (!flag && !(unit->val2&UF_ENSEMBLE))
+ return 0; //Nothing to remove, this unit is not overlapped.
+
+ if (unit->val1 != unit->group->skill_id)
+ { //Reset state
+ unit->val1 = unit->group->skill_id;
+ unit->val2 &= ~UF_ENSEMBLE;
+ }
+
+ return map_foreachincell(skill_dance_overlap_sub, unit->bl.m,unit->bl.x,unit->bl.y,BL_SKILL, unit,flag);
}
/*==========================================
* Converts this group information so that it is handled as a Dissonance or Ugly Dance cell.
* Flag: 0 - Convert, 1 - Revert.
*------------------------------------------*/
-static bool skill_dance_switch(struct skill_unit *unit, int flag)
+static bool skill_dance_switch(struct skill_unit* unit, int flag)
{
- static int prevflag = 1; // by default the backup is empty
- static struct skill_unit_group backup;
- struct skill_unit_group *group = unit->group;
-
- // val2&UF_ENSEMBLE is a hack to indicate dissonance
- if (!(group->state.song_dance&0x1 && unit->val2&UF_ENSEMBLE))
- return false;
-
- if (flag == prevflag) {
- // protection against attempts to read an empty backup / write to a full backup
- ShowError("skill_dance_switch: Attempted to %s (skill_id=%d, skill_lv=%d, src_id=%d).\n",
- flag ? "read an empty backup" : "write to a full backup",
- group->skill_id, group->skill_lv, group->src_id);
- return false;
- }
- prevflag = flag;
-
- if (!flag) {
- //Transform
- int skillid = unit->val2&UF_SONG ? BA_DISSONANCE : DC_UGLYDANCE;
-
- // backup
- backup.skill_id = group->skill_id;
- backup.skill_lv = group->skill_lv;
- backup.unit_id = group->unit_id;
- backup.target_flag = group->target_flag;
- backup.bl_flag = group->bl_flag;
- backup.interval = group->interval;
-
- // replace
- group->skill_id = skillid;
- group->skill_lv = 1;
- group->unit_id = skill_get_unit_id(skillid,0);
- group->target_flag = skill_get_unit_target(skillid);
- group->bl_flag = skill_get_unit_bl_target(skillid);
- group->interval = skill_get_unit_interval(skillid);
- } else {
- //Restore
- group->skill_id = backup.skill_id;
- group->skill_lv = backup.skill_lv;
- group->unit_id = backup.unit_id;
- group->target_flag = backup.target_flag;
- group->bl_flag = backup.bl_flag;
- group->interval = backup.interval;
- }
-
- return true;
+ static int prevflag = 1; // by default the backup is empty
+ static struct skill_unit_group backup;
+ struct skill_unit_group* group = unit->group;
+
+ // val2&UF_ENSEMBLE is a hack to indicate dissonance
+ if ( !(group->state.song_dance&0x1 && unit->val2&UF_ENSEMBLE) )
+ return false;
+
+ if( flag == prevflag )
+ {// protection against attempts to read an empty backup / write to a full backup
+ ShowError("skill_dance_switch: Attempted to %s (skill_id=%d, skill_lv=%d, src_id=%d).\n",
+ flag ? "read an empty backup" : "write to a full backup",
+ group->skill_id, group->skill_lv, group->src_id);
+ return false;
+ }
+ prevflag = flag;
+
+ if( !flag )
+ { //Transform
+ int skillid = unit->val2&UF_SONG ? BA_DISSONANCE : DC_UGLYDANCE;
+
+ // backup
+ backup.skill_id = group->skill_id;
+ backup.skill_lv = group->skill_lv;
+ backup.unit_id = group->unit_id;
+ backup.target_flag = group->target_flag;
+ backup.bl_flag = group->bl_flag;
+ backup.interval = group->interval;
+
+ // replace
+ group->skill_id = skillid;
+ group->skill_lv = 1;
+ group->unit_id = skill_get_unit_id(skillid,0);
+ group->target_flag = skill_get_unit_target(skillid);
+ group->bl_flag = skill_get_unit_bl_target(skillid);
+ group->interval = skill_get_unit_interval(skillid);
+ }
+ else
+ { //Restore
+ group->skill_id = backup.skill_id;
+ group->skill_lv = backup.skill_lv;
+ group->unit_id = backup.unit_id;
+ group->target_flag = backup.target_flag;
+ group->bl_flag = backup.bl_flag;
+ group->interval = backup.interval;
+ }
+
+ return true;
}
/**
* Upon Ice Wall cast it checks all nearby mobs to find any who may be blocked by the IW
**/
-static int skill_icewall_block(struct block_list *bl,va_list ap)
-{
- struct block_list *target = NULL;
- struct mob_data *md = ((TBL_MOB *)bl);
+static int skill_icewall_block(struct block_list *bl,va_list ap) {
+ struct block_list *target = NULL;
+ struct mob_data *md = ((TBL_MOB*)bl);
- nullpo_ret(bl);
- nullpo_ret(md);
- if (!md->target_id || (target = map_id2bl(md->target_id)) == NULL)
- return 0;
+ nullpo_ret(bl);
+ nullpo_ret(md);
+ if( !md->target_id || ( target = map_id2bl(md->target_id) ) == NULL )
+ return 0;
- if (path_search_long(NULL,bl->m,bl->x,bl->y,target->x,target->y,CELL_CHKICEWALL))
- return 0;
+ if( path_search_long(NULL,bl->m,bl->x,bl->y,target->x,target->y,CELL_CHKICEWALL) )
+ return 0;
- if (!check_distance_bl(bl, target, status_get_range(bl))) {
- mob_unlocktarget(md,gettick());
- mob_stop_walking(md,1);
- }
+ if( !check_distance_bl(bl, target, status_get_range(bl) ) ) {
+ mob_unlocktarget(md,gettick());
+ mob_stop_walking(md,1);
+ }
- return 0;
+ return 0;
}
/*==========================================
* Initializes and sets a ground skill.
* flag&1 is used to determine when the skill 'morphs' (Warp portal becomes active, or Fire Pillar becomes active)
*------------------------------------------*/
-struct skill_unit_group *skill_unitsetting(struct block_list *src, short skillid, short skilllv, short x, short y, int flag) {
- struct skill_unit_group *group;
- int i,limit,val1=0,val2=0,val3=0;
- int target,interval,range,unit_flag,req_item=0;
- struct s_skill_unit_layout *layout;
- struct map_session_data *sd;
- struct status_data *status;
- struct status_change *sc;
- int active_flag=1;
- int subunt=0;
-
- nullpo_retr(NULL, src);
-
- limit = skill_get_time(skillid,skilllv);
- range = skill_get_unit_range(skillid,skilllv);
- 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);
-
- sd = BL_CAST(BL_PC, src);
- status = status_get_status_data(src);
- sc = status_get_sc(src); // for traps, firewall and fogwall - celest
-
- switch (skillid) {
- case MH_STEINWAND:
- val2 = 4 + skilllv; //nb of attack blocked
- break;
- case MG_SAFETYWALL:
-#ifdef RENEWAL
- /**
- * According to data provided in RE, SW life is equal to 3 times caster's health
- **/
- val2 = status_get_max_hp(src) * 3;
-#else
- val2 = skilllv+1;
-#endif
- break;
- case MG_FIREWALL:
- if (sc && sc->data[SC_VIOLENTGALE])
- limit = limit*3/2;
- val2=4+skilllv;
- break;
-
- case AL_WARP:
- val1=skilllv+6;
- if (!(flag&1))
- limit=2000;
- else { // previous implementation (not used anymore)
- //Warp Portal morphing to active mode, extract relevant data from src. [Skotlex]
- if (src->type != BL_SKILL) return NULL;
- group = ((TBL_SKILL *)src)->group;
- src = map_id2bl(group->src_id);
- if (!src) return NULL;
- val2 = group->val2; //Copy the (x,y) position you warp to
- val3 = group->val3; //as well as the mapindex to warp to.
- }
- break;
- case HP_BASILICA:
- val1 = src->id; // Store caster id.
- break;
-
- case PR_SANCTUARY:
- case NPC_EVILLAND:
- val1=(skilllv+3)*2;
- break;
+struct skill_unit_group* skill_unitsetting (struct block_list *src, short skillid, short skilllv, short x, short y, int flag)
+{
+ struct skill_unit_group *group;
+ int i,limit,val1=0,val2=0,val3=0;
+ int target,interval,range,unit_flag,req_item=0;
+ struct s_skill_unit_layout *layout;
+ struct map_session_data *sd;
+ struct status_data *status;
+ struct status_change *sc;
+ int active_flag=1;
+ int subunt=0;
+
+ nullpo_retr(NULL, src);
+
+ limit = skill_get_time(skillid,skilllv);
+ range = skill_get_unit_range(skillid,skilllv);
+ 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);
+
+ sd = BL_CAST(BL_PC, src);
+ status = status_get_status_data(src);
+ sc = status_get_sc(src); // for traps, firewall and fogwall - celest
+
+ switch( skillid ) {
+ case MH_STEINWAND:
+ val2 = 4 + skilllv; //nb of attack blocked
+ break;
+ case MG_SAFETYWALL:
+ #ifdef RENEWAL
+ /**
+ * According to data provided in RE, SW life is equal to 3 times caster's health
+ **/
+ val2 = status_get_max_hp(src) * 3;
+ #else
+ val2 = skilllv+1;
+ #endif
+ break;
+ case MG_FIREWALL:
+ if(sc && sc->data[SC_VIOLENTGALE])
+ limit = limit*3/2;
+ val2=4+skilllv;
+ break;
+
+ case AL_WARP:
+ val1=skilllv+6;
+ if(!(flag&1))
+ limit=2000;
+ else // previous implementation (not used anymore)
+ { //Warp Portal morphing to active mode, extract relevant data from src. [Skotlex]
+ if( src->type != BL_SKILL ) return NULL;
+ group = ((TBL_SKILL*)src)->group;
+ src = map_id2bl(group->src_id);
+ if( !src ) return NULL;
+ val2 = group->val2; //Copy the (x,y) position you warp to
+ val3 = group->val3; //as well as the mapindex to warp to.
+ }
+ break;
+ case HP_BASILICA:
+ val1 = src->id; // Store caster id.
+ break;
+
+ case PR_SANCTUARY:
+ case NPC_EVILLAND:
+ val1=(skilllv+3)*2;
+ break;
+
+ case WZ_FIREPILLAR:
+ if((flag&1)!=0)
+ limit=1000;
+ val1=skilllv+2;
+ break;
+ case WZ_QUAGMIRE: //The target changes to "all" if used in a gvg map. [Skotlex]
+ case AM_DEMONSTRATION:
+ case GN_HELLS_PLANT:
+ if (map_flag_vs(src->m) && battle_config.vs_traps_bctall
+ && (src->type&battle_config.vs_traps_bctall))
+ target = BCT_ALL;
+ break;
+ case HT_SHOCKWAVE:
+ val1=skilllv*15+10;
+ case HT_SANDMAN:
+ case MA_SANDMAN:
+ case HT_CLAYMORETRAP:
+ case HT_SKIDTRAP:
+ case MA_SKIDTRAP:
+ case HT_LANDMINE:
+ case MA_LANDMINE:
+ case HT_ANKLESNARE:
+ case HT_FLASHER:
+ case HT_FREEZINGTRAP:
+ case MA_FREEZINGTRAP:
+ case HT_BLASTMINE:
+ /**
+ * Ranger
+ **/
+ case RA_ELECTRICSHOCKER:
+ case RA_CLUSTERBOMB:
+ case RA_MAGENTATRAP:
+ case RA_COBALTTRAP:
+ case RA_MAIZETRAP:
+ case RA_VERDURETRAP:
+ case RA_FIRINGTRAP:
+ case RA_ICEBOUNDTRAP:
+ {
+ struct skill_condition req = skill_get_requirement(sd,skillid,skilllv);
+ ARR_FIND(0, MAX_SKILL_ITEM_REQUIRE, i, req.itemid[i] && (req.itemid[i] == ITEMID_TRAP || req.itemid[i] == ITEMID_TRAP_ALLOY));
+ if( req.itemid[i] )
+ req_item = req.itemid[i];
+ if( map_flag_gvg(src->m) || map[src->m].flag.battleground )
+ limit *= 4; // longer trap times in WOE [celest]
+ if( battle_config.vs_traps_bctall && map_flag_vs(src->m) && (src->type&battle_config.vs_traps_bctall) )
+ target = BCT_ALL;
+ }
+ break;
+
+ case SA_LANDPROTECTOR:
+ case SA_VOLCANO:
+ case SA_DELUGE:
+ case SA_VIOLENTGALE:
+ {
+ struct skill_unit_group *old_sg;
+ if ((old_sg = skill_locate_element_field(src)) != NULL)
+ { //HelloKitty confirmed that these are interchangeable,
+ //so you can change element and not consume gemstones.
+ if ((
+ old_sg->skill_id == SA_VOLCANO ||
+ old_sg->skill_id == SA_DELUGE ||
+ old_sg->skill_id == SA_VIOLENTGALE
+ ) && old_sg->limit > 0)
+ { //Use the previous limit (minus the elapsed time) [Skotlex]
+ limit = old_sg->limit - DIFF_TICK(gettick(), old_sg->tick);
+ if (limit < 0) //This can happen...
+ limit = skill_get_time(skillid,skilllv);
+ }
+ skill_clear_group(src,1);
+ }
+ break;
+ }
- case WZ_FIREPILLAR:
- if ((flag&1)!=0)
- limit=1000;
- val1=skilllv+2;
- break;
- case WZ_QUAGMIRE: //The target changes to "all" if used in a gvg map. [Skotlex]
- case AM_DEMONSTRATION:
- case GN_HELLS_PLANT:
- if (map_flag_vs(src->m) && battle_config.vs_traps_bctall
- && (src->type&battle_config.vs_traps_bctall))
- target = BCT_ALL;
- break;
- case HT_SHOCKWAVE:
- val1=skilllv*15+10;
- case HT_SANDMAN:
- case MA_SANDMAN:
- case HT_CLAYMORETRAP:
- case HT_SKIDTRAP:
- case MA_SKIDTRAP:
- case HT_LANDMINE:
- case MA_LANDMINE:
- case HT_ANKLESNARE:
- case HT_FLASHER:
- case HT_FREEZINGTRAP:
- case MA_FREEZINGTRAP:
- case HT_BLASTMINE:
- /**
- * Ranger
- **/
- case RA_ELECTRICSHOCKER:
- case RA_CLUSTERBOMB:
- case RA_MAGENTATRAP:
- case RA_COBALTTRAP:
- case RA_MAIZETRAP:
- case RA_VERDURETRAP:
- case RA_FIRINGTRAP:
- case RA_ICEBOUNDTRAP: {
- struct skill_condition req = skill_get_requirement(sd,skillid,skilllv);
- ARR_FIND(0, MAX_SKILL_ITEM_REQUIRE, i, req.itemid[i] && (req.itemid[i] == ITEMID_TRAP || req.itemid[i] == ITEMID_TRAP_ALLOY));
- if (req.itemid[i])
- req_item = req.itemid[i];
- if (map_flag_gvg(src->m) || map[src->m].flag.battleground)
- limit *= 4; // longer trap times in WOE [celest]
- if (battle_config.vs_traps_bctall && map_flag_vs(src->m) && (src->type&battle_config.vs_traps_bctall))
- target = BCT_ALL;
- }
- break;
+ case BA_DISSONANCE:
+ case DC_UGLYDANCE:
+ val1 = 10; //FIXME: This value is not used anywhere, what is it for? [Skotlex]
+ break;
+ case BA_WHISTLE:
+ val1 = skilllv +status->agi/10; // Flee increase
+ val2 = ((skilllv+1)/2)+status->luk/10; // Perfect dodge increase
+ if(sd){
+ val1 += pc_checkskill(sd,BA_MUSICALLESSON);
+ val2 += pc_checkskill(sd,BA_MUSICALLESSON);
+ }
+ break;
+ case DC_HUMMING:
+ val1 = 2*skilllv+status->dex/10; // Hit increase
+ #ifdef RENEWAL
+ val1 *= 2;
+ #endif
+ if(sd)
+ val1 += pc_checkskill(sd,DC_DANCINGLESSON);
+ break;
+ case BA_POEMBRAGI:
+ val1 = 3*skilllv+status->dex/10; // Casting time reduction
+ //For some reason at level 10 the base delay reduction is 50%.
+ val2 = (skilllv<10?3*skilllv:50)+status->int_/5; // After-cast delay reduction
+ if(sd){
+ val1 += 2*pc_checkskill(sd,BA_MUSICALLESSON);
+ val2 += 2*pc_checkskill(sd,BA_MUSICALLESSON);
+ }
+ break;
+ case DC_DONTFORGETME:
+ val1 = status->dex/10 + 3*skilllv + 5; // ASPD decrease
+ val2 = status->agi/10 + 3*skilllv + 5; // Movement speed adjustment.
+ if(sd){
+ val1 += pc_checkskill(sd,DC_DANCINGLESSON);
+ val2 += pc_checkskill(sd,DC_DANCINGLESSON);
+ }
+ break;
+ case BA_APPLEIDUN:
+ val1 = 5+2*skilllv+status->vit/10; // MaxHP percent increase
+ if(sd)
+ val1 += pc_checkskill(sd,BA_MUSICALLESSON);
+ break;
+ case DC_SERVICEFORYOU:
+ val1 = 15+skilllv+(status->int_/10); // MaxSP percent increase TO-DO: this INT bonus value is guessed
+ val2 = 20+3*skilllv+(status->int_/10); // SP cost reduction
+ if(sd){
+ val1 += pc_checkskill(sd,DC_DANCINGLESSON); //TO-DO This bonus value is guessed
+ val2 += pc_checkskill(sd,DC_DANCINGLESSON); //TO-DO Should be half this value
+ }
+ break;
+ case BA_ASSASSINCROSS:
+ val1 = 100+(10*skilllv)+(status->agi/10); // ASPD increase
+ if(sd)
+ val1 += 5*pc_checkskill(sd,BA_MUSICALLESSON);
+ break;
+ case DC_FORTUNEKISS:
+ val1 = 10+skilllv+(status->luk/10); // Critical increase
+ if(sd)
+ val1 += pc_checkskill(sd,DC_DANCINGLESSON);
+ val1*=10; //Because every 10 crit is an actual cri point.
+ break;
+ case BD_DRUMBATTLEFIELD:
+ #ifdef RENEWAL
+ val1 = (skilllv+5)*25; //Watk increase
+ val2 = skilllv*10; //Def increase
+ #else
+ val1 = (skilllv+1)*25; //Watk increase
+ val2 = (skilllv+1)*2; //Def increase
+ #endif
+ break;
+ case BD_RINGNIBELUNGEN:
+ val1 = (skilllv+2)*25; //Watk increase
+ break;
+ case BD_RICHMANKIM:
+ val1 = 25 + 11*skilllv; //Exp increase bonus.
+ break;
+ case BD_SIEGFRIED:
+ val1 = 55 + skilllv*5; //Elemental Resistance
+ val2 = skilllv*10; //Status ailment resistance
+ break;
+ case WE_CALLPARTNER:
+ if (sd) val1 = sd->status.partner_id;
+ break;
+ case WE_CALLPARENT:
+ if (sd) {
+ val1 = sd->status.father;
+ val2 = sd->status.mother;
+ }
+ break;
+ case WE_CALLBABY:
+ if (sd) val1 = sd->status.child;
+ break;
+ case NJ_KAENSIN:
+ skill_clear_group(src, 1); //Delete previous Kaensins/Suitons
+ val2 = (skilllv+1)/2 + 4;
+ break;
+ case NJ_SUITON:
+ skill_clear_group(src, 1);
+ break;
+
+ case GS_GROUNDDRIFT:
+ {
+ int element[5]={ELE_WIND,ELE_DARK,ELE_POISON,ELE_WATER,ELE_FIRE};
+
+ val1 = status->rhw.ele;
+ if (!val1)
+ val1=element[rnd()%5];
+
+ switch (val1)
+ {
+ case ELE_FIRE:
+ subunt++;
+ case ELE_WATER:
+ subunt++;
+ case ELE_POISON:
+ subunt++;
+ case ELE_DARK:
+ subunt++;
+ case ELE_WIND:
+ break;
+ default:
+ subunt=rnd()%5;
+ break;
+ }
+
+ break;
+ }
+ case GC_POISONSMOKE:
+ if( !(sc && sc->data[SC_POISONINGWEAPON]) )
+ return NULL;
+ val2 = sc->data[SC_POISONINGWEAPON]->val2; // Type of Poison
+ val3 = sc->data[SC_POISONINGWEAPON]->val1;
+ limit = 4000 + 2000 * skilllv;
+ break;
+ case GD_LEADERSHIP:
+ case GD_GLORYWOUNDS:
+ case GD_SOULCOLD:
+ case GD_HAWKEYES:
+ limit = 1000000;//it doesn't matter
+ break;
+ case LG_BANDING:
+ limit = -1;
+ break;
+ case WM_REVERBERATION:
+ interval = limit;
+ val2 = 1;
+ case WM_POEMOFNETHERWORLD: // Can't be placed on top of Land Protector.
+ if( map_getcell(src->m, x, y, CELL_CHKLANDPROTECTOR) )
+ return NULL;
+ break;
+ case SO_CLOUD_KILL:
+ skill_clear_group(src, 4);
+ break;
+ case SO_WARMER:
+ skill_clear_group(src, 8);
+ break;
+ case SO_VACUUM_EXTREME:
+ range++;
+
+ break;
+ case SC_BLOODYLUST:
+ skill_clear_group(src, 32);
+ break;
+ case GN_WALLOFTHORN:
+ if( flag&1 )
+ limit = 3000;
+ val3 = (x<<16)|y;
+ break;
+ case KO_ZENKAI:
+ if( sd ){
+ ARR_FIND(1, 6, i, sd->talisman[i] > 0);
+ if( i < 5 ){
+ val1 = sd->talisman[i]; // no. of aura
+ val2 = i; // aura type
+ limit += val1 * 1000;
+ subunt = i - 1;
+ pc_del_talisman(sd, sd->talisman[i], i);
+ }
+ }
+ break;
+ }
- case SA_LANDPROTECTOR:
- case SA_VOLCANO:
- case SA_DELUGE:
- case SA_VIOLENTGALE: {
- struct skill_unit_group *old_sg;
- if ((old_sg = skill_locate_element_field(src)) != NULL) {
- //HelloKitty confirmed that these are interchangeable,
- //so you can change element and not consume gemstones.
- if ((
- old_sg->skill_id == SA_VOLCANO ||
- old_sg->skill_id == SA_DELUGE ||
- old_sg->skill_id == SA_VIOLENTGALE
- ) && old_sg->limit > 0) {
- //Use the previous limit (minus the elapsed time) [Skotlex]
- limit = old_sg->limit - DIFF_TICK(gettick(), old_sg->tick);
- if (limit < 0) //This can happen...
- limit = skill_get_time(skillid,skilllv);
- }
- skill_clear_group(src,1);
- }
- break;
- }
+ nullpo_retr(NULL, group=skill_initunitgroup(src,layout->count,skillid,skilllv,skill_get_unit_id(skillid,flag&1)+subunt, limit, interval));
+ group->val1=val1;
+ group->val2=val2;
+ group->val3=val3;
+ group->target_flag=target;
+ group->bl_flag= skill_get_unit_bl_target(skillid);
+ group->state.ammo_consume = (sd && sd->state.arrow_atk && skillid != GS_GROUNDDRIFT); //Store if this skill needs to consume ammo.
+ group->state.song_dance = (unit_flag&(UF_DANCE|UF_SONG)?1:0)|(unit_flag&UF_ENSEMBLE?2:0); //Signals if this is a song/dance/duet
+ group->state.guildaura = ( skillid >= GD_LEADERSHIP && skillid <= GD_HAWKEYES )?1:0;
+ group->item_id = req_item;
+ //if tick is greater than current, do not invoke onplace function just yet. [Skotlex]
+ if (DIFF_TICK(group->tick, gettick()) > SKILLUNITTIMER_INTERVAL)
+ active_flag = 0;
+
+ if(skillid==HT_TALKIEBOX || skillid==RG_GRAFFITI){
+ group->valstr=(char *) aMalloc(MESSAGE_SIZE*sizeof(char));
+ if (sd)
+ safestrncpy(group->valstr, sd->message, MESSAGE_SIZE);
+ else //Eh... we have to write something here... even though mobs shouldn't use this. [Skotlex]
+ safestrncpy(group->valstr, "Boo!", MESSAGE_SIZE);
+ }
- case BA_DISSONANCE:
- case DC_UGLYDANCE:
- val1 = 10; //FIXME: This value is not used anywhere, what is it for? [Skotlex]
- break;
- case BA_WHISTLE:
- val1 = skilllv +status->agi/10; // Flee increase
- val2 = ((skilllv+1)/2)+status->luk/10; // Perfect dodge increase
- if (sd) {
- val1 += pc_checkskill(sd,BA_MUSICALLESSON);
- val2 += pc_checkskill(sd,BA_MUSICALLESSON);
- }
- break;
- case DC_HUMMING:
- val1 = 2*skilllv+status->dex/10; // Hit increase
-#ifdef RENEWAL
- val1 *= 2;
-#endif
- if (sd)
- val1 += pc_checkskill(sd,DC_DANCINGLESSON);
- break;
- case BA_POEMBRAGI:
- val1 = 3*skilllv+status->dex/10; // Casting time reduction
- //For some reason at level 10 the base delay reduction is 50%.
- val2 = (skilllv<10?3*skilllv:50)+status->int_/5; // After-cast delay reduction
- if (sd) {
- val1 += 2*pc_checkskill(sd,BA_MUSICALLESSON);
- val2 += 2*pc_checkskill(sd,BA_MUSICALLESSON);
- }
- break;
- case DC_DONTFORGETME:
- val1 = status->dex/10 + 3*skilllv + 5; // ASPD decrease
- val2 = status->agi/10 + 3*skilllv + 5; // Movement speed adjustment.
- if (sd) {
- val1 += pc_checkskill(sd,DC_DANCINGLESSON);
- val2 += pc_checkskill(sd,DC_DANCINGLESSON);
- }
- break;
- case BA_APPLEIDUN:
- val1 = 5+2*skilllv+status->vit/10; // MaxHP percent increase
- if (sd)
- val1 += pc_checkskill(sd,BA_MUSICALLESSON);
- break;
- case DC_SERVICEFORYOU:
- val1 = 15+skilllv+(status->int_/10); // MaxSP percent increase TO-DO: this INT bonus value is guessed
- val2 = 20+3*skilllv+(status->int_/10); // SP cost reduction
- if (sd) {
- val1 += pc_checkskill(sd,DC_DANCINGLESSON); //TO-DO This bonus value is guessed
- val2 += pc_checkskill(sd,DC_DANCINGLESSON); //TO-DO Should be half this value
- }
- break;
- case BA_ASSASSINCROSS:
- val1 = 100+(10*skilllv)+(status->agi/10); // ASPD increase
- if (sd)
- val1 += 5*pc_checkskill(sd,BA_MUSICALLESSON);
- break;
- case DC_FORTUNEKISS:
- val1 = 10+skilllv+(status->luk/10); // Critical increase
- if (sd)
- val1 += pc_checkskill(sd,DC_DANCINGLESSON);
- val1*=10; //Because every 10 crit is an actual cri point.
- break;
- case BD_DRUMBATTLEFIELD:
-#ifdef RENEWAL
- val1 = (skilllv+5)*25; //Watk increase
- val2 = skilllv*10; //Def increase
-#else
- val1 = (skilllv+1)*25; //Watk increase
- val2 = (skilllv+1)*2; //Def increase
-#endif
- break;
- case BD_RINGNIBELUNGEN:
- val1 = (skilllv+2)*25; //Watk increase
- break;
- case BD_RICHMANKIM:
- val1 = 25 + 11*skilllv; //Exp increase bonus.
- break;
- case BD_SIEGFRIED:
- val1 = 55 + skilllv*5; //Elemental Resistance
- val2 = skilllv*10; //Status ailment resistance
- break;
- case WE_CALLPARTNER:
- if (sd) val1 = sd->status.partner_id;
- break;
- case WE_CALLPARENT:
- if (sd) {
- val1 = sd->status.father;
- val2 = sd->status.mother;
- }
- break;
- case WE_CALLBABY:
- if (sd) val1 = sd->status.child;
- break;
- case NJ_KAENSIN:
- skill_clear_group(src, 1); //Delete previous Kaensins/Suitons
- val2 = (skilllv+1)/2 + 4;
- break;
- case NJ_SUITON:
- skill_clear_group(src, 1);
- break;
+ if (group->state.song_dance) {
+ if(sd){
+ sd->skillid_dance = skillid;
+ sd->skilllv_dance = skilllv;
+ }
+ if (
+ sc_start4(src, SC_DANCING, 100, skillid, group->group_id, skilllv,
+ (group->state.song_dance&2?BCT_SELF:0), limit+1000) &&
+ sd && group->state.song_dance&2 && skillid != CG_HERMODE //Hermod is a encore with a warp!
+ )
+ skill_check_pc_partner(sd, skillid, &skilllv, 1, 1);
+ }
- case GS_GROUNDDRIFT: {
- int element[5]= {ELE_WIND,ELE_DARK,ELE_POISON,ELE_WATER,ELE_FIRE};
-
- val1 = status->rhw.ele;
- if (!val1)
- val1=element[rnd()%5];
-
- switch (val1) {
- case ELE_FIRE:
- subunt++;
- case ELE_WATER:
- subunt++;
- case ELE_POISON:
- subunt++;
- case ELE_DARK:
- subunt++;
- case ELE_WIND:
- break;
- default:
- subunt=rnd()%5;
- break;
- }
+ limit = group->limit;
+ for( i = 0; i < layout->count; i++ )
+ {
+ struct skill_unit *unit;
+ int ux = x + layout->dx[i];
+ int uy = y + layout->dy[i];
+ int val1 = skilllv;
+ int val2 = 0;
+ int alive = 1;
+
+ if( !group->state.song_dance && !map_getcell(src->m,ux,uy,CELL_CHKREACH) )
+ continue; // don't place skill units on walls (except for songs/dances/encores)
+ if( battle_config.skill_wall_check && skill_get_unit_flag(skillid)&UF_PATHCHECK && !path_search_long(NULL,src->m,ux,uy,x,y,CELL_CHKWALL) )
+ continue; // no path between cell and center of casting.
+
+ switch( skillid )
+ {
+ case MG_FIREWALL:
+ case NJ_KAENSIN:
+ val2=group->val2;
+ break;
+ case WZ_ICEWALL:
+ val1 = (skilllv <= 1) ? 500 : 200 + 200*skilllv;
+ val2 = map_getcell(src->m, ux, uy, CELL_GETTYPE);
+ break;
+ case HT_LANDMINE:
+ case MA_LANDMINE:
+ case HT_ANKLESNARE:
+ case HT_SHOCKWAVE:
+ case HT_SANDMAN:
+ case MA_SANDMAN:
+ case HT_FLASHER:
+ case HT_FREEZINGTRAP:
+ case MA_FREEZINGTRAP:
+ case HT_TALKIEBOX:
+ case HT_SKIDTRAP:
+ case MA_SKIDTRAP:
+ case HT_CLAYMORETRAP:
+ case HT_BLASTMINE:
+ /**
+ * Ranger
+ **/
+ case RA_ELECTRICSHOCKER:
+ case RA_CLUSTERBOMB:
+ case RA_MAGENTATRAP:
+ case RA_COBALTTRAP:
+ case RA_MAIZETRAP:
+ case RA_VERDURETRAP:
+ case RA_FIRINGTRAP:
+ case RA_ICEBOUNDTRAP:
+ val1 = 3500;
+ break;
+ case GS_DESPERADO:
+ val1 = abs(layout->dx[i]);
+ val2 = abs(layout->dy[i]);
+ if (val1 < 2 || val2 < 2) { //Nearby cross, linear decrease with no diagonals
+ if (val2 > val1) val1 = val2;
+ if (val1) val1--;
+ val1 = 36 -12*val1;
+ } else //Diagonal edges
+ val1 = 28 -4*val1 -4*val2;
+ if (val1 < 1) val1 = 1;
+ val2 = 0;
+ break;
+ case WM_REVERBERATION:
+ val1 = 1 + skilllv;
+ break;
+ case GN_WALLOFTHORN:
+ val1 = 1000 * skilllv; // Need official value. [LimitLine]
+ break;
+ default:
+ if (group->state.song_dance&0x1)
+ val2 = unit_flag&(UF_DANCE|UF_SONG); //Store whether this is a song/dance
+ break;
+ }
+ if (skill_get_unit_flag(skillid) & UF_RANGEDSINGLEUNIT && i == (layout->count / 2))
+ val2 |= UF_RANGEDSINGLEUNIT; // center.
+
+ if( range <= 0 )
+ map_foreachincell(skill_cell_overlap,src->m,ux,uy,BL_SKILL,skillid, &alive, src);
+ if( !alive )
+ continue;
+
+ nullpo_retr(NULL, unit=skill_initunit(group,i,ux,uy,val1,val2));
+ unit->limit=limit;
+ unit->range=range;
+
+ if (skillid == PF_FOGWALL && alive == 2)
+ { //Double duration of cells on top of Deluge/Suiton
+ unit->limit *= 2;
+ group->limit = unit->limit;
+ }
+
+ // execute on all targets standing on this cell
+ if (range==0 && active_flag)
+ map_foreachincell(skill_unit_effect,unit->bl.m,unit->bl.x,unit->bl.y,group->bl_flag,&unit->bl,gettick(),1);
+ }
- break;
- }
- case GC_POISONSMOKE:
- if (!(sc && sc->data[SC_POISONINGWEAPON]))
- return NULL;
- val2 = sc->data[SC_POISONINGWEAPON]->val2; // Type of Poison
- val3 = sc->data[SC_POISONINGWEAPON]->val1;
- limit = 4000 + 2000 * skilllv;
- break;
- case GD_LEADERSHIP:
- case GD_GLORYWOUNDS:
- case GD_SOULCOLD:
- case GD_HAWKEYES:
- limit = 1000000;//it doesn't matter
- break;
- case LG_BANDING:
- limit = -1;
- break;
- case WM_REVERBERATION:
- interval = limit;
- val2 = 1;
- case WM_POEMOFNETHERWORLD: // Can't be placed on top of Land Protector.
- if (map_getcell(src->m, x, y, CELL_CHKLANDPROTECTOR))
- return NULL;
- break;
- case SO_CLOUD_KILL:
- skill_clear_group(src, 4);
- break;
- case SO_WARMER:
- skill_clear_group(src, 8);
- break;
- case SO_VACUUM_EXTREME:
- range++;
+ if (!group->alive_count)
+ { //No cells? Something that was blocked completely by Land Protector?
+ skill_delunitgroup(group);
+ return NULL;
+ }
- break;
- case SC_BLOODYLUST:
- skill_clear_group(src, 32);
- break;
- case GN_WALLOFTHORN:
- if (flag&1)
- limit = 3000;
- val3 = (x<<16)|y;
- break;
- case KO_ZENKAI:
- if (sd) {
- ARR_FIND(1, 6, i, sd->talisman[i] > 0);
- if (i < 5) {
- val1 = sd->talisman[i]; // no. of aura
- val2 = i; // aura type
- limit += val1 * 1000;
- subunt = i - 1;
- pc_del_talisman(sd, sd->talisman[i], i);
- }
- }
- break;
- }
-
- nullpo_retr(NULL, group=skill_initunitgroup(src,layout->count,skillid,skilllv,skill_get_unit_id(skillid,flag&1)+subunt, limit, interval));
- group->val1=val1;
- group->val2=val2;
- group->val3=val3;
- group->target_flag=target;
- group->bl_flag= skill_get_unit_bl_target(skillid);
- group->state.ammo_consume = (sd && sd->state.arrow_atk && skillid != GS_GROUNDDRIFT); //Store if this skill needs to consume ammo.
- group->state.song_dance = (unit_flag&(UF_DANCE|UF_SONG)?1:0)|(unit_flag&UF_ENSEMBLE?2:0); //Signals if this is a song/dance/duet
- group->state.guildaura = (skillid >= GD_LEADERSHIP && skillid <= GD_HAWKEYES)?1:0;
- group->item_id = req_item;
- //if tick is greater than current, do not invoke onplace function just yet. [Skotlex]
- if (DIFF_TICK(group->tick, gettick()) > SKILLUNITTIMER_INTERVAL)
- active_flag = 0;
-
- if (skillid==HT_TALKIEBOX || skillid==RG_GRAFFITI) {
- group->valstr=(char *) aMalloc(MESSAGE_SIZE*sizeof(char));
- if (sd)
- safestrncpy(group->valstr, sd->message, MESSAGE_SIZE);
- else //Eh... we have to write something here... even though mobs shouldn't use this. [Skotlex]
- safestrncpy(group->valstr, "Boo!", MESSAGE_SIZE);
- }
-
- if (group->state.song_dance) {
- if (sd) {
- sd->skillid_dance = skillid;
- sd->skilllv_dance = skilllv;
- }
- if (
- sc_start4(src, SC_DANCING, 100, skillid, group->group_id, skilllv,
- (group->state.song_dance&2?BCT_SELF:0), limit+1000) &&
- sd && group->state.song_dance&2 && skillid != CG_HERMODE //Hermod is a encore with a warp!
- )
- skill_check_pc_partner(sd, skillid, &skilllv, 1, 1);
- }
-
- limit = group->limit;
- for (i = 0; i < layout->count; i++) {
- struct skill_unit *unit;
- int ux = x + layout->dx[i];
- int uy = y + layout->dy[i];
- int val1 = skilllv;
- int val2 = 0;
- int alive = 1;
-
- if (!group->state.song_dance && !map_getcell(src->m,ux,uy,CELL_CHKREACH))
- continue; // don't place skill units on walls (except for songs/dances/encores)
- if (battle_config.skill_wall_check && skill_get_unit_flag(skillid)&UF_PATHCHECK && !path_search_long(NULL,src->m,ux,uy,x,y,CELL_CHKWALL))
- continue; // no path between cell and center of casting.
-
- switch (skillid) {
- case MG_FIREWALL:
- case NJ_KAENSIN:
- val2=group->val2;
- break;
- case WZ_ICEWALL:
- val1 = (skilllv <= 1) ? 500 : 200 + 200*skilllv;
- val2 = map_getcell(src->m, ux, uy, CELL_GETTYPE);
- break;
- case HT_LANDMINE:
- case MA_LANDMINE:
- case HT_ANKLESNARE:
- case HT_SHOCKWAVE:
- case HT_SANDMAN:
- case MA_SANDMAN:
- case HT_FLASHER:
- case HT_FREEZINGTRAP:
- case MA_FREEZINGTRAP:
- case HT_TALKIEBOX:
- case HT_SKIDTRAP:
- case MA_SKIDTRAP:
- case HT_CLAYMORETRAP:
- case HT_BLASTMINE:
- /**
- * Ranger
- **/
- case RA_ELECTRICSHOCKER:
- case RA_CLUSTERBOMB:
- case RA_MAGENTATRAP:
- case RA_COBALTTRAP:
- case RA_MAIZETRAP:
- case RA_VERDURETRAP:
- case RA_FIRINGTRAP:
- case RA_ICEBOUNDTRAP:
- val1 = 3500;
- break;
- case GS_DESPERADO:
- val1 = abs(layout->dx[i]);
- val2 = abs(layout->dy[i]);
- if (val1 < 2 || val2 < 2) { //Nearby cross, linear decrease with no diagonals
- if (val2 > val1) val1 = val2;
- if (val1) val1--;
- val1 = 36 -12*val1;
- } else //Diagonal edges
- val1 = 28 -4*val1 -4*val2;
- if (val1 < 1) val1 = 1;
- val2 = 0;
- break;
- case WM_REVERBERATION:
- val1 = 1 + skilllv;
- break;
- case GN_WALLOFTHORN:
- val1 = 1000 * skilllv; // Need official value. [LimitLine]
- break;
- default:
- if (group->state.song_dance&0x1)
- val2 = unit_flag&(UF_DANCE|UF_SONG); //Store whether this is a song/dance
- break;
- }
- if (skill_get_unit_flag(skillid) & UF_RANGEDSINGLEUNIT && i == (layout->count / 2))
- val2 |= UF_RANGEDSINGLEUNIT; // center.
-
- if (range <= 0)
- map_foreachincell(skill_cell_overlap,src->m,ux,uy,BL_SKILL,skillid, &alive, src);
- if (!alive)
- continue;
-
- nullpo_retr(NULL, unit=skill_initunit(group,i,ux,uy,val1,val2));
- unit->limit=limit;
- unit->range=range;
-
- if (skillid == PF_FOGWALL && alive == 2) {
- //Double duration of cells on top of Deluge/Suiton
- unit->limit *= 2;
- group->limit = unit->limit;
- }
-
- // execute on all targets standing on this cell
- if (range==0 && active_flag)
- map_foreachincell(skill_unit_effect,unit->bl.m,unit->bl.x,unit->bl.y,group->bl_flag,&unit->bl,gettick(),1);
- }
-
- if (!group->alive_count) {
- //No cells? Something that was blocked completely by Land Protector?
- skill_delunitgroup(group);
- return NULL;
- }
-
- //success, unit created.
- switch (skillid) {
- case WZ_ICEWALL:
- map_foreachinrange(skill_icewall_block, src, AREA_SIZE, BL_MOB);
- break;
- case NJ_TATAMIGAESHI: //Store number of tiles.
- group->val1 = group->alive_count;
- break;
- }
+ //success, unit created.
+ switch( skillid ) {
+ case WZ_ICEWALL:
+ map_foreachinrange(skill_icewall_block, src, AREA_SIZE, BL_MOB);
+ break;
+ case NJ_TATAMIGAESHI: //Store number of tiles.
+ group->val1 = group->alive_count;
+ break;
+ }
- return group;
+ return group;
}
/*==========================================
*
*------------------------------------------*/
-void ext_skill_unit_onplace(struct skill_unit *src, struct block_list *bl, unsigned int tick)
-{
- skill_unit_onplace(src, bl, tick);
-}
-static int skill_unit_onplace(struct skill_unit *src, struct block_list *bl, unsigned int tick)
+void ext_skill_unit_onplace(struct skill_unit *src, struct block_list *bl, unsigned int tick){skill_unit_onplace(src, bl, tick);}
+static int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned int tick)
{
- struct skill_unit_group *sg;
- struct block_list *ss;
- struct status_change *sc;
- struct status_change_entry *sce;
- enum sc_type type;
- int skillid;
-
- nullpo_ret(src);
- nullpo_ret(bl);
-
- if (bl->prev==NULL || !src->alive || status_isdead(bl))
- return 0;
-
- nullpo_ret(sg=src->group);
- nullpo_ret(ss=map_id2bl(sg->src_id));
-
- if (skill_get_type(sg->skill_id) == BF_MAGIC && map_getcell(bl->m, bl->x, bl->y, CELL_CHKLANDPROTECTOR) && sg->skill_id != SA_LANDPROTECTOR)
- return 0; //AoE skills are ineffective. [Skotlex]
-
- sc = status_get_sc(bl);
-
- if (sc && sc->option&OPTION_HIDE && sg->skill_id != WZ_HEAVENDRIVE && sg->skill_id != WL_EARTHSTRAIN)
- return 0; //Hidden characters are immune to AoE skills except to these. [Skotlex]
-
- type = status_skill2sc(sg->skill_id);
- sce = (sc && type != -1)?sc->data[type]:NULL;
- skillid = sg->skill_id; //In case the group is deleted, we need to return the correct skill id, still.
- switch (sg->unit_id) {
- case UNT_SPIDERWEB:
- if (sc && sc->data[SC_SPIDERWEB] && sc->data[SC_SPIDERWEB]->val1 > 0) {
- // If you are fiberlocked and can't move, it will only increase your fireweakness level. [Inkfish]
- sc->data[SC_SPIDERWEB]->val2++;
- break;
- } else if (sc) {
- int sec = skill_get_time2(sg->skill_id,sg->skill_lv);
- if (status_change_start(bl,type,10000,sg->skill_lv,1,sg->group_id,0,sec,8)) {
- const struct TimerData *td = sc->data[type]?get_timer(sc->data[type]->timer):NULL;
- if (td)
- sec = DIFF_TICK(td->tick, tick);
- map_moveblock(bl, src->bl.x, src->bl.y, tick);
- clif_fixpos(bl);
- sg->val2 = bl->id;
- } else
- sec = 3000; //Couldn't trap it?
- sg->limit = DIFF_TICK(tick,sg->tick)+sec;
- }
- break;
- case UNT_SAFETYWALL:
- if (!sce)
- sc_start4(bl,type,100,sg->skill_lv,sg->skill_id,sg->group_id,0,sg->limit);
- break;
-
- case UNT_PNEUMA:
- case UNT_CHAOSPANIC:
- case UNT_MAELSTROM:
- if (!sce)
- sc_start4(bl,type,100,sg->skill_lv,sg->group_id,0,0,sg->limit);
- break;
- case UNT_BLOODYLUST:
- if (sg->src_id == bl->id)
- break; //Does not affect the caster.
- if (!sce) {
- TBL_PC *sd = BL_CAST(BL_PC, bl); //prevent fullheal exploit
- if (sd && sd->bloodylust_tick && DIFF_TICK(gettick(), sd->bloodylust_tick) < skill_get_time2(SC_BLOODYLUST, 1))
- clif_skill_nodamage(&src->bl,bl,sg->skill_id,sg->skill_lv,
- sc_start4(bl, type, 100, sg->skill_lv, 1, 0, 0, skill_get_time(LK_BERSERK, sg->skill_lv)));
- else {
- if (sd) sd->bloodylust_tick = gettick();
- clif_skill_nodamage(&src->bl,bl,sg->skill_id,sg->skill_lv,
- sc_start4(bl, type, 100, sg->skill_lv, 0, 0, 0, skill_get_time(LK_BERSERK, sg->skill_lv)));
- }
- }
- break;
-
- case UNT_WARP_WAITING: {
- int working = sg->val1&0xffff;
-
- if (bl->type==BL_PC && !working) {
- struct map_session_data *sd = (struct map_session_data *)bl;
- if ((!sd->chatID || battle_config.chat_warpportal)
- && sd->ud.to_x == src->bl.x && sd->ud.to_y == src->bl.y) {
- int x = sg->val2>>16;
- int y = sg->val2&0xffff;
- int count = sg->val1>>16;
- unsigned short m = sg->val3;
-
- if (--count <= 0)
- skill_delunitgroup(sg);
-
- if (map_mapindex2mapid(sg->val3) == sd->bl.m && x == sd->bl.x && y == sd->bl.y)
- working = 1;/* we break it because officials break it, lovely stuff. */
-
- sg->val1 = (count<<16)|working;
-
- pc_setpos(sd,m,x,y,CLR_TELEPORT);
- }
- } else if (bl->type == BL_MOB && battle_config.mob_warp&2) {
- int m = map_mapindex2mapid(sg->val3);
- if (m < 0) break; //Map not available on this map-server.
- unit_warp(bl,m,sg->val2>>16,sg->val2&0xffff,CLR_TELEPORT);
- }
- }
- break;
-
- case UNT_QUAGMIRE:
- if (!sce && battle_check_target(&sg->unit->bl,bl,sg->target_flag) > 0)
- sc_start4(bl,type,100,sg->skill_lv,sg->group_id,0,0,sg->limit);
- break;
-
- case UNT_VOLCANO:
- case UNT_DELUGE:
- case UNT_VIOLENTGALE:
- if (!sce)
- sc_start(bl,type,100,sg->skill_lv,sg->limit);
- break;
-
- case UNT_SUITON:
- if (!sce)
- sc_start4(bl,type,100,sg->skill_lv,
- map_flag_vs(bl->m) || battle_check_target(&src->bl,bl,BCT_ENEMY)>0?1:0, //Send val3 =1 to reduce agi.
- 0,0,sg->limit);
- break;
+ struct skill_unit_group *sg;
+ struct block_list *ss;
+ struct status_change *sc;
+ struct status_change_entry *sce;
+ enum sc_type type;
+ int skillid;
+
+ nullpo_ret(src);
+ nullpo_ret(bl);
+
+ if(bl->prev==NULL || !src->alive || status_isdead(bl))
+ return 0;
+
+ nullpo_ret(sg=src->group);
+ nullpo_ret(ss=map_id2bl(sg->src_id));
+
+ if( skill_get_type(sg->skill_id) == BF_MAGIC && map_getcell(bl->m, bl->x, bl->y, CELL_CHKLANDPROTECTOR) && sg->skill_id != SA_LANDPROTECTOR )
+ return 0; //AoE skills are ineffective. [Skotlex]
+
+ sc = status_get_sc(bl);
+
+ if (sc && sc->option&OPTION_HIDE && sg->skill_id != WZ_HEAVENDRIVE && sg->skill_id != WL_EARTHSTRAIN )
+ return 0; //Hidden characters are immune to AoE skills except to these. [Skotlex]
+
+ type = status_skill2sc(sg->skill_id);
+ sce = (sc && type != -1)?sc->data[type]:NULL;
+ skillid = sg->skill_id; //In case the group is deleted, we need to return the correct skill id, still.
+ switch (sg->unit_id)
+ {
+ case UNT_SPIDERWEB:
+ if( sc && sc->data[SC_SPIDERWEB] && sc->data[SC_SPIDERWEB]->val1 > 0 )
+ { // If you are fiberlocked and can't move, it will only increase your fireweakness level. [Inkfish]
+ sc->data[SC_SPIDERWEB]->val2++;
+ break;
+ }
+ else if( sc )
+ {
+ int sec = skill_get_time2(sg->skill_id,sg->skill_lv);
+ if( status_change_start(bl,type,10000,sg->skill_lv,1,sg->group_id,0,sec,8) )
+ {
+ const struct TimerData* td = sc->data[type]?get_timer(sc->data[type]->timer):NULL;
+ if( td )
+ sec = DIFF_TICK(td->tick, tick);
+ map_moveblock(bl, src->bl.x, src->bl.y, tick);
+ clif_fixpos(bl);
+ sg->val2 = bl->id;
+ }
+ else
+ sec = 3000; //Couldn't trap it?
+ sg->limit = DIFF_TICK(tick,sg->tick)+sec;
+ }
+ break;
+ case UNT_SAFETYWALL:
+ if (!sce)
+ sc_start4(bl,type,100,sg->skill_lv,sg->skill_id,sg->group_id,0,sg->limit);
+ break;
+
+ case UNT_PNEUMA:
+ case UNT_CHAOSPANIC:
+ case UNT_MAELSTROM:
+ if (!sce)
+ sc_start4(bl,type,100,sg->skill_lv,sg->group_id,0,0,sg->limit);
+ break;
+ case UNT_BLOODYLUST:
+ if (sg->src_id == bl->id)
+ break; //Does not affect the caster.
+ if (!sce) {
+ TBL_PC *sd = BL_CAST(BL_PC, bl); //prevent fullheal exploit
+ if (sd && sd->bloodylust_tick && DIFF_TICK(gettick(), sd->bloodylust_tick) < skill_get_time2(SC_BLOODYLUST, 1))
+ clif_skill_nodamage(&src->bl,bl,sg->skill_id,sg->skill_lv,
+ sc_start4(bl, type, 100, sg->skill_lv, 1, 0, 0, skill_get_time(LK_BERSERK, sg->skill_lv)));
+ else {
+ if (sd) sd->bloodylust_tick = gettick();
+ clif_skill_nodamage(&src->bl,bl,sg->skill_id,sg->skill_lv,
+ sc_start4(bl, type, 100, sg->skill_lv, 0, 0, 0, skill_get_time(LK_BERSERK, sg->skill_lv)));
+ }
+ }
+ break;
- case UNT_HERMODE:
- if (sg->src_id!=bl->id && battle_check_target(&src->bl,bl,BCT_PARTY|BCT_GUILD) > 0)
- status_change_clear_buffs(bl,1); //Should dispell only allies.
- case UNT_RICHMANKIM:
- case UNT_ETERNALCHAOS:
- case UNT_DRUMBATTLEFIELD:
- case UNT_RINGNIBELUNGEN:
- case UNT_ROKISWEIL:
- case UNT_INTOABYSS:
- case UNT_SIEGFRIED:
- //Needed to check when a dancer/bard leaves their ensemble area.
- if (sg->src_id==bl->id && !(sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_BARDDANCER))
- return skillid;
- if (!sce)
- sc_start4(bl,type,100,sg->skill_lv,sg->val1,sg->val2,0,sg->limit);
- break;
- case UNT_WHISTLE:
- case UNT_ASSASSINCROSS:
- case UNT_POEMBRAGI:
- case UNT_APPLEIDUN:
- case UNT_HUMMING:
- case UNT_DONTFORGETME:
- case UNT_FORTUNEKISS:
- case UNT_SERVICEFORYOU:
- if (sg->src_id==bl->id && !(sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_BARDDANCER)) {
- if (sce) /* We have the status but we're not elegible for it, so we take it away. (bugreport:4591) */
- sce->val4 = 2;
- return 0;
- }
- if (!sc) return 0;
- if (!sce)
- sc_start4(bl,type,100,sg->skill_lv,sg->val1,sg->val2,0,sg->limit);
- else if (sce->val4 == 1) {
- //Readjust timers since the effect will not last long.
- sce->val4 = 0;
- delete_timer(sce->timer, status_change_timer);
- sce->timer = add_timer(tick+sg->limit, status_change_timer, bl->id, type);
- }
- break;
+ case UNT_WARP_WAITING: {
+ int working = sg->val1&0xffff;
- case UNT_FOGWALL:
- if (!sce) {
- sc_start4(bl, type, 100, sg->skill_lv, sg->val1, sg->val2, sg->group_id, sg->limit);
- if (battle_check_target(&src->bl,bl,BCT_ENEMY)>0)
- skill_additional_effect(ss, bl, sg->skill_id, sg->skill_lv, BF_MISC, ATK_DEF, tick);
- }
- break;
+ if(bl->type==BL_PC && !working){
+ struct map_session_data *sd = (struct map_session_data *)bl;
+ if((!sd->chatID || battle_config.chat_warpportal)
+ && sd->ud.to_x == src->bl.x && sd->ud.to_y == src->bl.y)
+ {
+ int x = sg->val2>>16;
+ int y = sg->val2&0xffff;
+ int count = sg->val1>>16;
+ unsigned short m = sg->val3;
- case UNT_GRAVITATION:
- if (!sce)
- sc_start4(bl,type,100,sg->skill_lv,0,BCT_ENEMY,sg->group_id,sg->limit);
- break;
+ if( --count <= 0 )
+ skill_delunitgroup(sg);
- // officially, icewall has no problems existing on occupied cells [ultramage]
- // case UNT_ICEWALL: //Destroy the cell. [Skotlex]
- // src->val1 = 0;
- // if(src->limit + sg->tick > tick + 700)
- // src->limit = DIFF_TICK(tick+700,sg->tick);
- // break;
-
- case UNT_MOONLIT:
- //Knockback out of area if affected char isn't in Moonlit effect
- if (sc && sc->data[SC_DANCING] && (sc->data[SC_DANCING]->val1&0xFFFF) == CG_MOONLIT)
- break;
- if (ss == bl) //Also needed to prevent infinite loop crash.
- break;
- skill_blown(ss,bl,skill_get_blewcount(sg->skill_id,sg->skill_lv),unit_getdir(bl),0);
- break;
+ if ( map_mapindex2mapid(sg->val3) == sd->bl.m && x == sd->bl.x && y == sd->bl.y )
+ working = 1;/* we break it because officials break it, lovely stuff. */
- case UNT_WALLOFTHORN:
- if (status_get_mode(bl)&MD_BOSS)
- break; // iRO Wiki says that this skill don't affect to Boss monsters.
- if (map_flag_vs(bl->m) || bl->id == src->bl.id || battle_check_target(&src->bl,bl, BCT_ENEMY) == 1)
- skill_attack(skill_get_type(sg->skill_id), ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0);
- break;
+ sg->val1 = (count<<16)|working;
- case UNT_VOLCANIC_ASH:
- if (!sce)
- sc_start(bl, SC_ASH, 100, sg->skill_lv, skill_get_time(MH_VOLCANIC_ASH, sg->skill_lv));
- break;
-
- case UNT_GD_LEADERSHIP:
- case UNT_GD_GLORYWOUNDS:
- case UNT_GD_SOULCOLD:
- case UNT_GD_HAWKEYES:
- if (!sce)
- sc_start4(bl,type,100,sg->skill_lv,0,0,0,1000);
- break;
- }
- return skillid;
+ pc_setpos(sd,m,x,y,CLR_TELEPORT);
+ }
+ } else if(bl->type == BL_MOB && battle_config.mob_warp&2) {
+ int m = map_mapindex2mapid(sg->val3);
+ if (m < 0) break; //Map not available on this map-server.
+ unit_warp(bl,m,sg->val2>>16,sg->val2&0xffff,CLR_TELEPORT);
+ }
+ }
+ break;
+
+ case UNT_QUAGMIRE:
+ if( !sce && battle_check_target(&sg->unit->bl,bl,sg->target_flag) > 0 )
+ sc_start4(bl,type,100,sg->skill_lv,sg->group_id,0,0,sg->limit);
+ break;
+
+ case UNT_VOLCANO:
+ case UNT_DELUGE:
+ case UNT_VIOLENTGALE:
+ if(!sce)
+ sc_start(bl,type,100,sg->skill_lv,sg->limit);
+ break;
+
+ case UNT_SUITON:
+ if(!sce)
+ sc_start4(bl,type,100,sg->skill_lv,
+ map_flag_vs(bl->m) || battle_check_target(&src->bl,bl,BCT_ENEMY)>0?1:0, //Send val3 =1 to reduce agi.
+ 0,0,sg->limit);
+ break;
+
+ case UNT_HERMODE:
+ if (sg->src_id!=bl->id && battle_check_target(&src->bl,bl,BCT_PARTY|BCT_GUILD) > 0)
+ status_change_clear_buffs(bl,1); //Should dispell only allies.
+ case UNT_RICHMANKIM:
+ case UNT_ETERNALCHAOS:
+ case UNT_DRUMBATTLEFIELD:
+ case UNT_RINGNIBELUNGEN:
+ case UNT_ROKISWEIL:
+ case UNT_INTOABYSS:
+ case UNT_SIEGFRIED:
+ //Needed to check when a dancer/bard leaves their ensemble area.
+ if (sg->src_id==bl->id && !(sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_BARDDANCER))
+ return skillid;
+ if (!sce)
+ sc_start4(bl,type,100,sg->skill_lv,sg->val1,sg->val2,0,sg->limit);
+ break;
+ case UNT_WHISTLE:
+ case UNT_ASSASSINCROSS:
+ case UNT_POEMBRAGI:
+ case UNT_APPLEIDUN:
+ case UNT_HUMMING:
+ case UNT_DONTFORGETME:
+ case UNT_FORTUNEKISS:
+ case UNT_SERVICEFORYOU:
+ if (sg->src_id==bl->id && !(sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_BARDDANCER)) {
+ if( sce )/* We have the status but we're not elegible for it, so we take it away. (bugreport:4591) */
+ sce->val4 = 2;
+ return 0;
+ }
+ if (!sc) return 0;
+ if (!sce)
+ sc_start4(bl,type,100,sg->skill_lv,sg->val1,sg->val2,0,sg->limit);
+ else if (sce->val4 == 1) {
+ //Readjust timers since the effect will not last long.
+ sce->val4 = 0;
+ delete_timer(sce->timer, status_change_timer);
+ sce->timer = add_timer(tick+sg->limit, status_change_timer, bl->id, type);
+ }
+ break;
+
+ case UNT_FOGWALL:
+ if (!sce)
+ {
+ sc_start4(bl, type, 100, sg->skill_lv, sg->val1, sg->val2, sg->group_id, sg->limit);
+ if (battle_check_target(&src->bl,bl,BCT_ENEMY)>0)
+ skill_additional_effect (ss, bl, sg->skill_id, sg->skill_lv, BF_MISC, ATK_DEF, tick);
+ }
+ break;
+
+ case UNT_GRAVITATION:
+ if (!sce)
+ sc_start4(bl,type,100,sg->skill_lv,0,BCT_ENEMY,sg->group_id,sg->limit);
+ break;
+
+// officially, icewall has no problems existing on occupied cells [ultramage]
+// case UNT_ICEWALL: //Destroy the cell. [Skotlex]
+// src->val1 = 0;
+// if(src->limit + sg->tick > tick + 700)
+// src->limit = DIFF_TICK(tick+700,sg->tick);
+// break;
+
+ case UNT_MOONLIT:
+ //Knockback out of area if affected char isn't in Moonlit effect
+ if (sc && sc->data[SC_DANCING] && (sc->data[SC_DANCING]->val1&0xFFFF) == CG_MOONLIT)
+ break;
+ if (ss == bl) //Also needed to prevent infinite loop crash.
+ break;
+ skill_blown(ss,bl,skill_get_blewcount(sg->skill_id,sg->skill_lv),unit_getdir(bl),0);
+ break;
+
+ case UNT_WALLOFTHORN:
+ if( status_get_mode(bl)&MD_BOSS )
+ break; // iRO Wiki says that this skill don't affect to Boss monsters.
+ if( map_flag_vs(bl->m) || bl->id == src->bl.id || battle_check_target(&src->bl,bl, BCT_ENEMY) == 1 )
+ skill_attack(skill_get_type(sg->skill_id), ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0);
+ break;
+
+ case UNT_VOLCANIC_ASH:
+ if (!sce)
+ sc_start(bl, SC_ASH, 100, sg->skill_lv, skill_get_time(MH_VOLCANIC_ASH, sg->skill_lv));
+ break;
+
+ case UNT_GD_LEADERSHIP:
+ case UNT_GD_GLORYWOUNDS:
+ case UNT_GD_SOULCOLD:
+ case UNT_GD_HAWKEYES:
+ if ( !sce )
+ sc_start4(bl,type,100,sg->skill_lv,0,0,0,1000);
+ break;
+ }
+ return skillid;
}
/*==========================================
*
*------------------------------------------*/
-int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, unsigned int tick)
+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;
- TBL_PC *tsd;
- struct status_data *tstatus;
- struct status_change *tsc;
- struct skill_unit_group_tickset *ts;
- enum sc_type type;
- int skillid;
- int diff=0;
-
- nullpo_ret(src);
- nullpo_ret(bl);
-
- if (bl->prev==NULL || !src->alive || status_isdead(bl))
- return 0;
-
- nullpo_ret(sg=src->group);
- nullpo_ret(ss=map_id2bl(sg->src_id));
- tsd = BL_CAST(BL_PC, bl);
- tsc = status_get_sc(bl);
-
- if (tsc && tsc->data[SC_HOVERING])
- return 0; //Under hovering characters are immune to trap and ground target skills.
-
- tstatus = status_get_status_data(bl);
- type = status_skill2sc(sg->skill_id);
- skillid = sg->skill_id;
-
- if (sg->interval == -1) {
- switch (sg->unit_id) {
- case UNT_ANKLESNARE: //These happen when a trap is splash-triggered by multiple targets on the same cell.
- case UNT_FIREPILLAR_ACTIVE:
- case UNT_ELECTRICSHOCKER:
- case UNT_MANHOLE:
- return 0;
- default:
- ShowError("skill_unit_onplace_timer: interval error (unit id %x)\n", sg->unit_id);
- return 0;
- }
- }
-
- if ((ts = skill_unitgrouptickset_search(bl,sg,tick))) {
- //Not all have it, eg: Traps don't have it even though they can be hit by Heaven's Drive [Skotlex]
- diff = DIFF_TICK(tick,ts->tick);
- if (diff < 0)
- return 0;
- ts->tick = tick+sg->interval;
-
- if ((skillid==CR_GRANDCROSS || skillid==NPC_GRANDDARKNESS) && !battle_config.gx_allhit)
- ts->tick += sg->interval*(map_count_oncell(bl->m,bl->x,bl->y,BL_CHAR)-1);
- }
-
- switch (sg->unit_id) {
- case UNT_FIREWALL:
- case UNT_KAEN: {
- int count=0;
- const int x = bl->x, y = bl->y;
-
- if (sg->skill_id == GN_WALLOFTHORN && !map_flag_vs(bl->m))
- break;
-
- //Take into account these hit more times than the timer interval can handle.
- do
- skill_attack(BF_MAGIC,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick+count*sg->interval,0);
- while (--src->val2 && x == bl->x && y == bl->y &&
- ++count < SKILLUNITTIMER_INTERVAL/sg->interval && !status_isdead(bl));
-
- if (src->val2<=0)
- skill_delunit(src);
- }
- break;
-
- case UNT_SANCTUARY:
- if (battle_check_undead(tstatus->race, tstatus->def_ele) || tstatus->race==RC_DEMON) {
- //Only damage enemies with offensive Sanctuary. [Skotlex]
- if (battle_check_target(&src->bl,bl,BCT_ENEMY) > 0 && skill_attack(BF_MAGIC, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0))
- sg->val1 -= 2; // reduce healing count if this was meant for damaging [hekate]
- } else {
- int heal = skill_calc_heal(ss,bl,sg->skill_id,sg->skill_lv,true);
- struct mob_data *md = BL_CAST(BL_MOB, bl);
-#ifdef RENEWAL
- if (md && md->class_ == MOBID_EMPERIUM)
- break;
-#endif
- if (md && mob_is_battleground(md))
- break;
- if (tstatus->hp >= tstatus->max_hp)
- break;
- if (status_isimmune(bl))
- heal = 0;
- clif_skill_nodamage(&src->bl, bl, AL_HEAL, heal, 1);
- if (tsc && tsc->data[SC_AKAITSUKI] && heal)
- heal = ~heal + 1;
- status_heal(bl, heal, 0, 0);
- if (diff >= 500)
- sg->val1--;
- }
- if (sg->val1 <= 0)
- skill_delunitgroup(sg);
- break;
+ struct skill_unit_group *sg;
+ struct block_list *ss;
+ TBL_PC* tsd;
+ struct status_data *tstatus;
+ struct status_change *tsc;
+ struct skill_unit_group_tickset *ts;
+ enum sc_type type;
+ int skillid;
+ int diff=0;
+
+ nullpo_ret(src);
+ nullpo_ret(bl);
+
+ if (bl->prev==NULL || !src->alive || status_isdead(bl))
+ return 0;
+
+ nullpo_ret(sg=src->group);
+ nullpo_ret(ss=map_id2bl(sg->src_id));
+ tsd = BL_CAST(BL_PC, bl);
+ tsc = status_get_sc(bl);
+
+ if ( tsc && tsc->data[SC_HOVERING] )
+ return 0; //Under hovering characters are immune to trap and ground target skills.
+
+ tstatus = status_get_status_data(bl);
+ type = status_skill2sc(sg->skill_id);
+ skillid = sg->skill_id;
+
+ if (sg->interval == -1) {
+ switch (sg->unit_id) {
+ case UNT_ANKLESNARE: //These happen when a trap is splash-triggered by multiple targets on the same cell.
+ case UNT_FIREPILLAR_ACTIVE:
+ case UNT_ELECTRICSHOCKER:
+ case UNT_MANHOLE:
+ return 0;
+ default:
+ ShowError("skill_unit_onplace_timer: interval error (unit id %x)\n", sg->unit_id);
+ return 0;
+ }
+ }
- case UNT_EVILLAND:
- //Will heal demon and undead element monsters, but not players.
- if ((bl->type == BL_PC) || (!battle_check_undead(tstatus->race, tstatus->def_ele) && tstatus->race!=RC_DEMON)) {
- //Damage enemies
- if (battle_check_target(&src->bl,bl,BCT_ENEMY)>0)
- skill_attack(BF_MISC, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0);
- } else {
- int heal = skill_calc_heal(ss,bl,sg->skill_id,sg->skill_lv,true);
- if (tstatus->hp >= tstatus->max_hp)
- break;
- if (status_isimmune(bl))
- heal = 0;
- clif_skill_nodamage(&src->bl, bl, AL_HEAL, heal, 1);
- status_heal(bl, heal, 0, 0);
- }
- break;
+ if ((ts = skill_unitgrouptickset_search(bl,sg,tick)))
+ { //Not all have it, eg: Traps don't have it even though they can be hit by Heaven's Drive [Skotlex]
+ diff = DIFF_TICK(tick,ts->tick);
+ if (diff < 0)
+ return 0;
+ ts->tick = tick+sg->interval;
- case UNT_MAGNUS:
- if (!battle_check_undead(tstatus->race,tstatus->def_ele) && tstatus->race!=RC_DEMON)
- break;
- skill_attack(BF_MAGIC,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
- break;
+ if ((skillid==CR_GRANDCROSS || skillid==NPC_GRANDDARKNESS) && !battle_config.gx_allhit)
+ ts->tick += sg->interval*(map_count_oncell(bl->m,bl->x,bl->y,BL_CHAR)-1);
+ }
- case UNT_DUMMYSKILL:
- switch (sg->skill_id) {
- case SG_SUN_WARM: //SG skills [Komurka]
- case SG_MOON_WARM:
- case SG_STAR_WARM: {
- int count = 0;
- const int x = bl->x, y = bl->y;
-
- //If target isn't knocked back it should hit every "interval" ms [Playtester]
- do {
- if (bl->type == BL_PC)
- status_zap(bl, 0, 15); // sp damage to players
- else // mobs
- if (status_charge(ss, 0, 2)) { // costs 2 SP per hit
- if (!skill_attack(BF_WEAPON,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick+count*sg->interval,0))
- status_charge(ss, 0, 8); //costs additional 8 SP if miss
- } else {
- //should end when out of sp.
- sg->limit = DIFF_TICK(tick,sg->tick);
- break;
- }
- } while (x == bl->x && y == bl->y &&
- ++count < SKILLUNITTIMER_INTERVAL/sg->interval && !status_isdead(bl));
- }
- break;
- /**
- * The storm gust counter was dropped in renewal
- **/
-#ifndef RENEWAL
- case WZ_STORMGUST: //SG counter does not reset per stormgust. IE: One hit from a SG and two hits from another will freeze you.
- if (tsc)
- tsc->sg_counter++; //SG hit counter.
- if (skill_attack(skill_get_type(sg->skill_id),ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0) <= 0 && tsc)
- tsc->sg_counter=0; //Attack absorbed.
- break;
+ switch (sg->unit_id)
+ {
+ case UNT_FIREWALL:
+ case UNT_KAEN:
+ {
+ int count=0;
+ const int x = bl->x, y = bl->y;
+
+ if( sg->skill_id == GN_WALLOFTHORN && !map_flag_vs(bl->m) )
+ break;
+
+ //Take into account these hit more times than the timer interval can handle.
+ do
+ skill_attack(BF_MAGIC,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick+count*sg->interval,0);
+ while(--src->val2 && x == bl->x && y == bl->y &&
+ ++count < SKILLUNITTIMER_INTERVAL/sg->interval && !status_isdead(bl));
+
+ if (src->val2<=0)
+ skill_delunit(src);
+ }
+ break;
+
+ case UNT_SANCTUARY:
+ if( battle_check_undead(tstatus->race, tstatus->def_ele) || tstatus->race==RC_DEMON )
+ { //Only damage enemies with offensive Sanctuary. [Skotlex]
+ if( battle_check_target(&src->bl,bl,BCT_ENEMY) > 0 && skill_attack(BF_MAGIC, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0) )
+ sg->val1 -= 2; // reduce healing count if this was meant for damaging [hekate]
+ }
+ else
+ {
+ int heal = skill_calc_heal(ss,bl,sg->skill_id,sg->skill_lv,true);
+ struct mob_data *md = BL_CAST(BL_MOB, bl);
+#ifdef RENEWAL
+ if( md && md->class_ == MOBID_EMPERIUM )
+ break;
#endif
- case GS_DESPERADO:
- if (rnd()%100 < src->val1)
- skill_attack(BF_WEAPON,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
- break;
- case GN_CRAZYWEED_ATK:
- if (bl->type == BL_SKILL) {
- struct skill_unit *su = (struct skill_unit *)bl;
- if (su && !(skill_get_inf2(su->group->skill_id)&INF2_TRAP))
- break;
- }
- default:
- skill_attack(skill_get_type(sg->skill_id),ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
- }
- break;
-
- case UNT_FIREPILLAR_WAITING:
- skill_unitsetting(ss,sg->skill_id,sg->skill_lv,src->bl.x,src->bl.y,1);
- skill_delunit(src);
- break;
-
- case UNT_SKIDTRAP: {
- skill_blown(&src->bl,bl,skill_get_blewcount(sg->skill_id,sg->skill_lv),unit_getdir(bl),0);
- sg->unit_id = UNT_USED_TRAPS;
- clif_changetraplook(&src->bl, UNT_USED_TRAPS);
- sg->limit=DIFF_TICK(tick,sg->tick)+1500;
- }
- break;
-
- case UNT_ANKLESNARE:
- case UNT_MANHOLE:
- if (sg->val2 == 0 && tsc && (sg->unit_id == UNT_ANKLESNARE || bl->id != sg->src_id)) {
- int sec = skill_get_time2(sg->skill_id,sg->skill_lv);
- if (status_change_start(bl,type,10000,sg->skill_lv,sg->group_id,0,0,sec, 8)) {
- const struct TimerData *td = tsc->data[type]?get_timer(tsc->data[type]->timer):NULL;
- if (td)
- sec = DIFF_TICK(td->tick, tick);
- unit_movepos(bl, src->bl.x, src->bl.y, 0, 0);
- clif_fixpos(bl);
- sg->val2 = bl->id;
- } else
- sec = 3000; //Couldn't trap it?
- if (sg->unit_id == UNT_ANKLESNARE) {
- clif_skillunit_update(&src->bl);
- /**
- * If you're snared from a trap that was invisible this makes the trap be
- * visible again -- being you stepped on it (w/o this the trap remains invisible and you go "WTF WHY I CANT MOVE")
- * bugreport:3961
- **/
- clif_changetraplook(&src->bl, UNT_ANKLESNARE);
- }
- sg->limit = DIFF_TICK(tick,sg->tick)+sec;
- sg->interval = -1;
- src->range = 0;
- }
- break;
-
- case UNT_ELECTRICSHOCKER:
- if (bl->id != ss->id) {
- if (status_get_mode(bl)&MD_BOSS)
- break;
- if (status_change_start(bl,type,10000,sg->skill_lv,sg->group_id,0,0,skill_get_time2(sg->skill_id, sg->skill_lv), 8)) {
-
- map_moveblock(bl, src->bl.x, src->bl.y, tick);
- clif_fixpos(bl);
-
- }
-
- map_foreachinrange(skill_trap_splash, &src->bl, skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &src->bl, tick);
- sg->unit_id = UNT_USED_TRAPS; //Changed ID so it does not invoke a for each in area again.
- }
- break;
+ if( md && mob_is_battleground(md) )
+ break;
+ if( tstatus->hp >= tstatus->max_hp )
+ break;
+ if( status_isimmune(bl) )
+ heal = 0;
+ clif_skill_nodamage(&src->bl, bl, AL_HEAL, heal, 1);
+ if( tsc && tsc->data[SC_AKAITSUKI] && heal )
+ heal = ~heal + 1;
+ status_heal(bl, heal, 0, 0);
+ if( diff >= 500 )
+ sg->val1--;
+ }
+ if( sg->val1 <= 0 )
+ skill_delunitgroup(sg);
+ break;
+
+ case UNT_EVILLAND:
+ //Will heal demon and undead element monsters, but not players.
+ if ((bl->type == BL_PC) || (!battle_check_undead(tstatus->race, tstatus->def_ele) && tstatus->race!=RC_DEMON))
+ { //Damage enemies
+ if(battle_check_target(&src->bl,bl,BCT_ENEMY)>0)
+ skill_attack(BF_MISC, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0);
+ } else {
+ int heal = skill_calc_heal(ss,bl,sg->skill_id,sg->skill_lv,true);
+ if (tstatus->hp >= tstatus->max_hp)
+ break;
+ if (status_isimmune(bl))
+ heal = 0;
+ clif_skill_nodamage(&src->bl, bl, AL_HEAL, heal, 1);
+ status_heal(bl, heal, 0, 0);
+ }
+ break;
- case UNT_VENOMDUST:
- if (tsc && !tsc->data[type])
- status_change_start(bl,type,10000,sg->skill_lv,sg->group_id,0,0,skill_get_time2(sg->skill_id,sg->skill_lv),0);
- break;
+ case UNT_MAGNUS:
+ if (!battle_check_undead(tstatus->race,tstatus->def_ele) && tstatus->race!=RC_DEMON)
+ break;
+ skill_attack(BF_MAGIC,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
+ break;
+ case UNT_DUMMYSKILL:
+ switch (sg->skill_id)
+ {
+ case SG_SUN_WARM: //SG skills [Komurka]
+ case SG_MOON_WARM:
+ case SG_STAR_WARM:
+ {
+ int count = 0;
+ const int x = bl->x, y = bl->y;
+
+ //If target isn't knocked back it should hit every "interval" ms [Playtester]
+ do
+ {
+ if( bl->type == BL_PC )
+ status_zap(bl, 0, 15); // sp damage to players
+ else // mobs
+ if( status_charge(ss, 0, 2) ) // costs 2 SP per hit
+ {
+ if( !skill_attack(BF_WEAPON,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick+count*sg->interval,0) )
+ status_charge(ss, 0, 8); //costs additional 8 SP if miss
+ }
+ else
+ { //should end when out of sp.
+ sg->limit = DIFF_TICK(tick,sg->tick);
+ break;
+ }
+ } while( x == bl->x && y == bl->y &&
+ ++count < SKILLUNITTIMER_INTERVAL/sg->interval && !status_isdead(bl) );
+ }
+ break;
+ /**
+ * The storm gust counter was dropped in renewal
+ **/
+ #ifndef RENEWAL
+ case WZ_STORMGUST: //SG counter does not reset per stormgust. IE: One hit from a SG and two hits from another will freeze you.
+ if (tsc)
+ tsc->sg_counter++; //SG hit counter.
+ if (skill_attack(skill_get_type(sg->skill_id),ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0) <= 0 && tsc)
+ tsc->sg_counter=0; //Attack absorbed.
+ break;
+ #endif
+ case GS_DESPERADO:
+ if (rnd()%100 < src->val1)
+ skill_attack(BF_WEAPON,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
+ break;
+ case GN_CRAZYWEED_ATK:
+ if( bl->type == BL_SKILL ){
+ struct skill_unit *su = (struct skill_unit *)bl;
+ if( su && !(skill_get_inf2(su->group->skill_id)&INF2_TRAP) )
+ break;
+ }
+ default:
+ skill_attack(skill_get_type(sg->skill_id),ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
+ }
+ break;
- case UNT_MAGENTATRAP:
- case UNT_COBALTTRAP:
- case UNT_MAIZETRAP:
- case UNT_VERDURETRAP:
- if (bl->type == BL_PC) // it won't work on players
- break;
- case UNT_FIRINGTRAP:
- case UNT_ICEBOUNDTRAP:
- case UNT_CLUSTERBOMB:
- if (bl->id == ss->id) // it won't trigger on caster
- break;
- case UNT_LANDMINE:
- case UNT_CLAYMORETRAP:
- case UNT_BLASTMINE:
- case UNT_SHOCKWAVE:
- case UNT_SANDMAN:
- case UNT_FLASHER:
- case UNT_FREEZINGTRAP:
- case UNT_FIREPILLAR_ACTIVE:
- map_foreachinrange(skill_trap_splash,&src->bl, skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &src->bl,tick);
- if (sg->unit_id != UNT_FIREPILLAR_ACTIVE)
- clif_changetraplook(&src->bl, sg->unit_id==UNT_LANDMINE?UNT_FIREPILLAR_ACTIVE:UNT_USED_TRAPS);
- sg->limit=DIFF_TICK(tick,sg->tick)+1500 +
- (sg->unit_id== UNT_CLUSTERBOMB || sg->unit_id== UNT_ICEBOUNDTRAP?1000:0);// Cluster Bomb/Icebound has 1s to disappear once activated.
- sg->unit_id = UNT_USED_TRAPS; //Changed ID so it does not invoke a for each in area again.
- break;
+ case UNT_FIREPILLAR_WAITING:
+ skill_unitsetting(ss,sg->skill_id,sg->skill_lv,src->bl.x,src->bl.y,1);
+ skill_delunit(src);
+ break;
- case UNT_TALKIEBOX:
- if (sg->src_id == bl->id)
- break;
- if (sg->val2 == 0) {
- clif_talkiebox(&src->bl, sg->valstr);
- sg->unit_id = UNT_USED_TRAPS;
- clif_changetraplook(&src->bl, UNT_USED_TRAPS);
- sg->limit = DIFF_TICK(tick, sg->tick) + 5000;
- sg->val2 = -1;
- }
- break;
+ case UNT_SKIDTRAP:
+ {
+ skill_blown(&src->bl,bl,skill_get_blewcount(sg->skill_id,sg->skill_lv),unit_getdir(bl),0);
+ sg->unit_id = UNT_USED_TRAPS;
+ clif_changetraplook(&src->bl, UNT_USED_TRAPS);
+ sg->limit=DIFF_TICK(tick,sg->tick)+1500;
+ }
+ break;
+
+ case UNT_ANKLESNARE:
+ case UNT_MANHOLE:
+ if( sg->val2 == 0 && tsc && (sg->unit_id == UNT_ANKLESNARE || bl->id != sg->src_id) ) {
+ int sec = skill_get_time2(sg->skill_id,sg->skill_lv);
+ if( status_change_start(bl,type,10000,sg->skill_lv,sg->group_id,0,0,sec, 8) ) {
+ const struct TimerData* td = tsc->data[type]?get_timer(tsc->data[type]->timer):NULL;
+ if( td )
+ sec = DIFF_TICK(td->tick, tick);
+ unit_movepos(bl, src->bl.x, src->bl.y, 0, 0);
+ clif_fixpos(bl);
+ sg->val2 = bl->id;
+ } else
+ sec = 3000; //Couldn't trap it?
+ if( sg->unit_id == UNT_ANKLESNARE ) {
+ clif_skillunit_update(&src->bl);
+ /**
+ * If you're snared from a trap that was invisible this makes the trap be
+ * visible again -- being you stepped on it (w/o this the trap remains invisible and you go "WTF WHY I CANT MOVE")
+ * bugreport:3961
+ **/
+ clif_changetraplook(&src->bl, UNT_ANKLESNARE);
+ }
+ sg->limit = DIFF_TICK(tick,sg->tick)+sec;
+ sg->interval = -1;
+ src->range = 0;
+ }
+ break;
- case UNT_LULLABY:
- if (ss->id == bl->id)
- break;
- skill_additional_effect(ss, bl, sg->skill_id, sg->skill_lv, BF_LONG|BF_SKILL|BF_MISC, ATK_DEF, tick);
- break;
+ case UNT_ELECTRICSHOCKER:
+ if( bl->id != ss->id ) {
+ if( status_get_mode(bl)&MD_BOSS )
+ break;
+ if( status_change_start(bl,type,10000,sg->skill_lv,sg->group_id,0,0,skill_get_time2(sg->skill_id, sg->skill_lv), 8) ) {
- case UNT_UGLYDANCE: //Ugly Dance [Skotlex]
- if (ss->id != bl->id)
- skill_additional_effect(ss, bl, sg->skill_id, sg->skill_lv, BF_LONG|BF_SKILL|BF_MISC, ATK_DEF, tick);
- break;
+ map_moveblock(bl, src->bl.x, src->bl.y, tick);
+ clif_fixpos(bl);
- case UNT_DISSONANCE:
- skill_attack(BF_MISC, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0);
- break;
+ }
- case UNT_APPLEIDUN: { //Apple of Idun [Skotlex]
- int heal;
+ map_foreachinrange(skill_trap_splash, &src->bl, skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &src->bl, tick);
+ sg->unit_id = UNT_USED_TRAPS; //Changed ID so it does not invoke a for each in area again.
+ }
+ break;
+
+ case UNT_VENOMDUST:
+ if(tsc && !tsc->data[type])
+ status_change_start(bl,type,10000,sg->skill_lv,sg->group_id,0,0,skill_get_time2(sg->skill_id,sg->skill_lv),0);
+ break;
+
+
+ case UNT_MAGENTATRAP:
+ case UNT_COBALTTRAP:
+ case UNT_MAIZETRAP:
+ case UNT_VERDURETRAP:
+ if( bl->type == BL_PC )// it won't work on players
+ break;
+ case UNT_FIRINGTRAP:
+ case UNT_ICEBOUNDTRAP:
+ case UNT_CLUSTERBOMB:
+ if( bl->id == ss->id )// it won't trigger on caster
+ break;
+ case UNT_LANDMINE:
+ case UNT_CLAYMORETRAP:
+ case UNT_BLASTMINE:
+ case UNT_SHOCKWAVE:
+ case UNT_SANDMAN:
+ case UNT_FLASHER:
+ case UNT_FREEZINGTRAP:
+ case UNT_FIREPILLAR_ACTIVE:
+ map_foreachinrange(skill_trap_splash,&src->bl, skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &src->bl,tick);
+ if (sg->unit_id != UNT_FIREPILLAR_ACTIVE)
+ clif_changetraplook(&src->bl, sg->unit_id==UNT_LANDMINE?UNT_FIREPILLAR_ACTIVE:UNT_USED_TRAPS);
+ sg->limit=DIFF_TICK(tick,sg->tick)+1500 +
+ (sg->unit_id== UNT_CLUSTERBOMB || sg->unit_id== UNT_ICEBOUNDTRAP?1000:0);// Cluster Bomb/Icebound has 1s to disappear once activated.
+ sg->unit_id = UNT_USED_TRAPS; //Changed ID so it does not invoke a for each in area again.
+ break;
+
+ case UNT_TALKIEBOX:
+ if (sg->src_id == bl->id)
+ break;
+ if (sg->val2 == 0){
+ clif_talkiebox(&src->bl, sg->valstr);
+ sg->unit_id = UNT_USED_TRAPS;
+ clif_changetraplook(&src->bl, UNT_USED_TRAPS);
+ sg->limit = DIFF_TICK(tick, sg->tick) + 5000;
+ sg->val2 = -1;
+ }
+ break;
+
+ case UNT_LULLABY:
+ if (ss->id == bl->id)
+ break;
+ skill_additional_effect(ss, bl, sg->skill_id, sg->skill_lv, BF_LONG|BF_SKILL|BF_MISC, ATK_DEF, tick);
+ break;
+
+ case UNT_UGLYDANCE: //Ugly Dance [Skotlex]
+ if (ss->id != bl->id)
+ skill_additional_effect(ss, bl, sg->skill_id, sg->skill_lv, BF_LONG|BF_SKILL|BF_MISC, ATK_DEF, tick);
+ break;
+
+ case UNT_DISSONANCE:
+ skill_attack(BF_MISC, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0);
+ break;
+
+ case UNT_APPLEIDUN: //Apple of Idun [Skotlex]
+ {
+ int heal;
#ifdef RENEWAL
- struct mob_data *md = BL_CAST(BL_MOB, bl);
- if (md && md->class_ == MOBID_EMPERIUM)
- break;
+ struct mob_data *md = BL_CAST(BL_MOB, bl);
+ if( md && md->class_ == MOBID_EMPERIUM )
+ break;
#endif
- if (sg->src_id == bl->id && !(tsc && tsc->data[SC_SPIRIT] && tsc->data[SC_SPIRIT]->val2 == SL_BARDDANCER))
- break; // affects self only when soullinked
- heal = skill_calc_heal(ss,bl,sg->skill_id, sg->skill_lv, true);
- if (tsc->data[SC_AKAITSUKI] && heal)
- heal = ~heal + 1;
- clif_skill_nodamage(&src->bl, bl, AL_HEAL, heal, 1);
- status_heal(bl, heal, 0, 0);
- break;
- }
-
- case UNT_TATAMIGAESHI:
- case UNT_DEMONSTRATION:
- skill_attack(BF_WEAPON,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
- break;
-
- case UNT_GOSPEL:
- if (rnd()%100 > sg->skill_lv*10 || ss == bl)
- break;
- if (battle_check_target(ss,bl,BCT_PARTY)>0) {
- // Support Effect only on party, not guild
- int heal;
- int i = rnd()%13; // Positive buff count
- int time = skill_get_time2(sg->skill_id, sg->skill_lv); //Duration
- switch (i) {
- case 0: // Heal 1~9999 HP
- heal = rnd() %9999+1;
- clif_skill_nodamage(ss,bl,AL_HEAL,heal,1);
- status_heal(bl,heal,0,0);
- break;
- case 1: // End all negative status
- status_change_clear_buffs(bl,6);
- if (tsd) clif_gospel_info(tsd, 0x15);
- break;
- case 2: // Immunity to all status
- sc_start(bl,SC_SCRESIST,100,100,time);
- if (tsd) clif_gospel_info(tsd, 0x16);
- break;
- case 3: // MaxHP +100%
- sc_start(bl,SC_INCMHPRATE,100,100,time);
- if (tsd) clif_gospel_info(tsd, 0x17);
- break;
- case 4: // MaxSP +100%
- sc_start(bl,SC_INCMSPRATE,100,100,time);
- if (tsd) clif_gospel_info(tsd, 0x18);
- break;
- case 5: // All stats +20
- sc_start(bl,SC_INCALLSTATUS,100,20,time);
- if (tsd) clif_gospel_info(tsd, 0x19);
- break;
- case 6: // Level 10 Blessing
- sc_start(bl,SC_BLESSING,100,10,time);
- break;
- case 7: // Level 10 Increase AGI
- sc_start(bl,SC_INCREASEAGI,100,10,time);
- break;
- case 8: // Enchant weapon with Holy element
- sc_start(bl,SC_ASPERSIO,100,1,time);
- if (tsd) clif_gospel_info(tsd, 0x1c);
- break;
- case 9: // Enchant armor with Holy element
- sc_start(bl,SC_BENEDICTIO,100,1,time);
- if (tsd) clif_gospel_info(tsd, 0x1d);
- break;
- case 10: // DEF +25%
- sc_start(bl,SC_INCDEFRATE,100,25,time);
- if (tsd) clif_gospel_info(tsd, 0x1e);
- break;
- case 11: // ATK +100%
- sc_start(bl,SC_INCATKRATE,100,100,time);
- if (tsd) clif_gospel_info(tsd, 0x1f);
- break;
- case 12: // HIT/Flee +50
- sc_start(bl,SC_INCHIT,100,50,time);
- sc_start(bl,SC_INCFLEE,100,50,time);
- if (tsd) clif_gospel_info(tsd, 0x20);
- break;
- }
- } else if (battle_check_target(&src->bl,bl,BCT_ENEMY)>0) {
- // Offensive Effect
- int i = rnd()%9; // Negative buff count
- int time = skill_get_time2(sg->skill_id, sg->skill_lv);
- switch (i) {
- case 0: // Deal 1~9999 damage
- skill_attack(BF_MISC,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
- break;
- case 1: // Curse
- sc_start(bl,SC_CURSE,100,1,time);
- break;
- case 2: // Blind
- sc_start(bl,SC_BLIND,100,1,time);
- break;
- case 3: // Poison
- sc_start(bl,SC_POISON,100,1,time);
- break;
- case 4: // Level 10 Provoke
- sc_start(bl,SC_PROVOKE,100,10,time);
- break;
- case 5: // DEF -100%
- sc_start(bl,SC_INCDEFRATE,100,-100,time);
- break;
- case 6: // ATK -100%
- sc_start(bl,SC_INCATKRATE,100,-100,time);
- break;
- case 7: // Flee -100%
- sc_start(bl,SC_INCFLEERATE,100,-100,time);
- break;
- case 8: // Speed/ASPD -25%
- sc_start4(bl,SC_GOSPEL,100,1,0,0,BCT_ENEMY,time);
- break;
- }
- }
- break;
-
- case UNT_BASILICA: {
- int i = battle_check_target(&src->bl, bl, BCT_ENEMY);
- if (i > 0 && !(status_get_mode(bl)&MD_BOSS)) {
- // knock-back any enemy except Boss
- skill_blown(&src->bl, bl, 2, unit_getdir(bl), 0);
- clif_fixpos(bl);
- }
-
- if (sg->src_id != bl->id && i <= 0)
- sc_start4(bl, type, 100, 0, 0, 0, src->bl.id, sg->interval + 100);
- }
- break;
-
- case UNT_GRAVITATION:
- case UNT_EARTHSTRAIN:
- case UNT_FIREWALK:
- case UNT_ELECTRICWALK:
- case UNT_PSYCHIC_WAVE:
- skill_attack(skill_get_type(sg->skill_id),ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
- break;
-
- case UNT_GROUNDDRIFT_WIND:
- case UNT_GROUNDDRIFT_DARK:
- case UNT_GROUNDDRIFT_POISON:
- case UNT_GROUNDDRIFT_WATER:
- case UNT_GROUNDDRIFT_FIRE:
- map_foreachinrange(skill_trap_splash,&src->bl,
- skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag,
- &src->bl,tick);
- sg->unit_id = UNT_USED_TRAPS;
- //clif_changetraplook(&src->bl, UNT_FIREPILLAR_ACTIVE);
- sg->limit=DIFF_TICK(tick,sg->tick)+1500;
- break;
- /**
- * 3rd stuff
- **/
- case UNT_POISONSMOKE:
- if (battle_check_target(ss,bl,BCT_ENEMY) > 0 && !(tsc && tsc->data[sg->val2]) && rnd()%100 < 20)
- sc_start(bl,sg->val2,100,sg->val3,skill_get_time2(GC_POISONINGWEAPON, 1));
- break;
-
- case UNT_EPICLESIS:
- if (bl->type == BL_PC && !battle_check_undead(tstatus->race, tstatus->def_ele) && tstatus->race != RC_DEMON) {
- if (++sg->val2 % 3 == 0) {
- int hp, sp;
- switch (sg->skill_lv) {
- case 1:
- case 2:
- hp = 3;
- sp = 2;
- break;
- case 3:
- case 4:
- hp = 4;
- sp = 3;
- break;
- case 5:
- default:
- hp = 5;
- sp = 4;
- break;
- }
- hp = tstatus->max_hp * hp / 100;
- sp = tstatus->max_sp * sp / 100;
- status_heal(bl, hp, sp, 2);
- sc_start(bl, type, 100, sg->skill_lv, (sg->interval * 3) + 100);
- }
- // Reveal hidden players every 5 seconds.
- if (sg->val2 % 5 == 0) {
- // TODO: check if other hidden status can be removed.
- status_change_end(bl,SC_HIDING,INVALID_TIMER);
- status_change_end(bl,SC_CLOAKING,INVALID_TIMER);
- }
- }
- /* Enable this if kRO fix the current skill. Currently no damage on undead and demon monster. [Jobbie]
- else if( battle_check_target(ss, bl, BCT_ENEMY) > 0 && battle_check_undead(tstatus->race, tstatus->def_ele) )
- skill_castend_damage_id(&src->bl, bl, sg->skill_id, sg->skill_lv, 0, 0);*/
- break;
-
- case UNT_STEALTHFIELD:
- if (bl->id == sg->src_id)
- break; // Dont work on Self (video shows that)
- case UNT_NEUTRALBARRIER:
- sc_start(bl,type,100,sg->skill_lv,sg->interval + 100);
- break;
-
- case UNT_DIMENSIONDOOR:
- if (tsd && !map[bl->m].flag.noteleport)
- pc_randomwarp(tsd,3);
- else if (bl->type == BL_MOB && battle_config.mob_warp&8)
- unit_warp(bl,-1,-1,-1,3);
- break;
-
- case UNT_REVERBERATION:
- clif_changetraplook(&src->bl,UNT_USED_TRAPS);
- map_foreachinrange(skill_trap_splash,&src->bl, skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &src->bl,tick);
- sg->limit = DIFF_TICK(tick,sg->tick)+1000;
- sg->unit_id = UNT_USED_TRAPS;
- break;
-
- case UNT_SEVERE_RAINSTORM:
- if (battle_check_target(&src->bl, bl, BCT_ENEMY))
- skill_attack(BF_WEAPON,ss,&src->bl,bl,WM_SEVERE_RAINSTORM_MELEE,sg->skill_lv,tick,0);
- break;
- case UNT_NETHERWORLD:
- if (!(status_get_mode(bl)&MD_BOSS) && ss != bl && battle_check_target(&src->bl, bl, BCT_PARTY)) {
- if (!(tsc && tsc->data[type])) {
- sc_start(bl, type, 100, sg->skill_lv, skill_get_time2(sg->skill_id,sg->skill_lv));
- sg->limit = DIFF_TICK(tick,sg->tick);
- sg->unit_id = UNT_USED_TRAPS;
- }
- }
- break;
- case UNT_THORNS_TRAP:
- if (tsc) {
- if (!sg->val2) {
- int sec = skill_get_time2(sg->skill_id, sg->skill_lv);
- if (sc_start(bl, type, 100, sg->skill_lv, sec)) {
- const struct TimerData *td = tsc->data[type]?get_timer(tsc->data[type]->timer):NULL;
- if (td)
- sec = DIFF_TICK(td->tick, tick);
- ///map_moveblock(bl, src->bl.x, src->bl.y, tick); // in official server it doesn't behave like this. [malufett]
- clif_fixpos(bl);
- sg->val2 = bl->id;
- } else
- sec = 3000; // Couldn't trap it?
- sg->limit = DIFF_TICK(tick, sg->tick) + sec;
- } else if (tsc->data[SC_THORNSTRAP] && bl->id == sg->val2)
- skill_attack(skill_get_type(GN_THORNS_TRAP), ss, ss, bl, sg->skill_id, sg->skill_lv, tick, SD_LEVEL|SD_ANIMATION);
- }
- break;
-
- case UNT_DEMONIC_FIRE: {
- TBL_PC *sd = BL_CAST(BL_PC, ss);
- switch (sg->val2) {
- case 1:
- case 2:
- default:
- sc_start(bl, SC_BURNING, 4 + 4 * sg->skill_lv, sg->skill_lv,
- skill_get_time2(sg->skill_id, sg->skill_lv));
- skill_attack(skill_get_type(sg->skill_id), ss, &src->bl, bl,
- sg->skill_id, sg->skill_lv + 10 * sg->val2, tick, 0);
- break;
- case 3:
- skill_attack(skill_get_type(CR_ACIDDEMONSTRATION), ss, &src->bl, bl,
- CR_ACIDDEMONSTRATION, sd ? pc_checkskill(sd, CR_ACIDDEMONSTRATION) : sg->skill_lv, tick, 0);
- break;
-
- }
- }
- break;
-
- case UNT_FIRE_EXPANSION_SMOKE_POWDER:
- sc_start(bl, status_skill2sc(GN_FIRE_EXPANSION_SMOKE_POWDER), 100, sg->skill_lv, 1000);
- break;
-
- case UNT_FIRE_EXPANSION_TEAR_GAS:
- sc_start(bl, status_skill2sc(GN_FIRE_EXPANSION_TEAR_GAS), 100, sg->skill_lv, 1000);
- break;
-
- case UNT_HELLS_PLANT:
- if (battle_check_target(&src->bl,bl,BCT_ENEMY) > 0)
- skill_attack(skill_get_type(GN_HELLS_PLANT_ATK), ss, &src->bl, bl, GN_HELLS_PLANT_ATK, sg->skill_lv, tick, 0);
- if (ss != bl) //The caster is the only one who can step on the Plants, without destroying them
- sg->limit = DIFF_TICK(tick, sg->tick) + 100;
- break;
-
- case UNT_CLOUD_KILL:
- if (tsc && !tsc->data[type])
- status_change_start(bl,type,10000,sg->skill_lv,sg->group_id,0,0,skill_get_time2(sg->skill_id,sg->skill_lv),8);
- skill_attack(skill_get_type(sg->skill_id),ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
- break;
-
- case UNT_WARMER:
- if (bl->type == BL_PC && !battle_check_undead(tstatus->race, tstatus->def_ele) && tstatus->race != RC_DEMON) {
- int hp = 125 * sg->skill_lv; // Officially is 125 * skill_lv.
- struct status_change *ssc = status_get_sc(ss);
- if (ssc && ssc->data[SC_HEATER_OPTION])
- hp += hp * ssc->data[SC_HEATER_OPTION]->val3 / 100;
- if (tstatus->hp != tstatus->max_hp)
- clif_skill_nodamage(&src->bl, bl, AL_HEAL, hp, 0);
- if (tsc && tsc->data[SC_AKAITSUKI] && hp)
- hp = ~hp + 1;
- status_heal(bl, hp, 0, 0);
- sc_start(bl, SC_WARMER, 100, sg->skill_lv, skill_get_time2(sg->skill_id,sg->skill_lv));
- }
- break;
-
- case UNT_FIRE_INSIGNIA:
- case UNT_WATER_INSIGNIA:
- case UNT_WIND_INSIGNIA:
- case UNT_EARTH_INSIGNIA:
- case UNT_ZEPHYR:
- sc_start(bl,type, 100, sg->skill_lv, sg->interval);
- if (sg->unit_id != UNT_ZEPHYR && !battle_check_undead(tstatus->race, tstatus->def_ele)) {
- int hp = tstatus->max_hp / 100; //+1% each 5s
- if ((sg->val3) % 5) { //each 5s
- if (tstatus->def_ele == skill_get_ele(sg->skill_id,sg->skill_lv)) {
- status_heal(bl, hp, 0, 2);
- } else if ((sg->unit_id == UNT_FIRE_INSIGNIA && tstatus->def_ele == ELE_EARTH)
- ||(sg->unit_id == UNT_WATER_INSIGNIA && tstatus->def_ele == ELE_FIRE)
- ||(sg->unit_id == UNT_WIND_INSIGNIA && tstatus->def_ele == ELE_WATER)
- ||(sg->unit_id == UNT_EARTH_INSIGNIA && tstatus->def_ele == ELE_WIND)
- ) {
- status_heal(bl, -hp, 0, 0);
- }
- }
- sg->val3++; //timer
- if (sg->val3 > 5) sg->val3 = 0;
- }
- break;
-
- case UNT_VACUUM_EXTREME: {
- // TODO: official behavior in gvg area. [malufett]
- int sec = sg->limit - DIFF_TICK(tick, sg->tick);
- int range = skill_get_unit_range(sg->skill_id, sg->skill_lv);
+ if( sg->src_id == bl->id && !(tsc && tsc->data[SC_SPIRIT] && tsc->data[SC_SPIRIT]->val2 == SL_BARDDANCER) )
+ break; // affects self only when soullinked
+ heal = skill_calc_heal(ss,bl,sg->skill_id, sg->skill_lv, true);
+ if( tsc->data[SC_AKAITSUKI] && heal )
+ heal = ~heal + 1;
+ clif_skill_nodamage(&src->bl, bl, AL_HEAL, heal, 1);
+ status_heal(bl, heal, 0, 0);
+ break;
+ }
+
+ case UNT_TATAMIGAESHI:
+ case UNT_DEMONSTRATION:
+ skill_attack(BF_WEAPON,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
+ break;
+
+ case UNT_GOSPEL:
+ if (rnd()%100 > sg->skill_lv*10 || ss == bl)
+ break;
+ if (battle_check_target(ss,bl,BCT_PARTY)>0)
+ { // Support Effect only on party, not guild
+ int heal;
+ int i = rnd()%13; // Positive buff count
+ int time = skill_get_time2(sg->skill_id, sg->skill_lv); //Duration
+ switch (i)
+ {
+ case 0: // Heal 1~9999 HP
+ heal = rnd() %9999+1;
+ clif_skill_nodamage(ss,bl,AL_HEAL,heal,1);
+ status_heal(bl,heal,0,0);
+ break;
+ case 1: // End all negative status
+ status_change_clear_buffs(bl,2);
+ if (tsd) clif_gospel_info(tsd, 0x15);
+ break;
+ case 2: // Immunity to all status
+ sc_start(bl,SC_SCRESIST,100,100,time);
+ if (tsd) clif_gospel_info(tsd, 0x16);
+ break;
+ case 3: // MaxHP +100%
+ sc_start(bl,SC_INCMHPRATE,100,100,time);
+ if (tsd) clif_gospel_info(tsd, 0x17);
+ break;
+ case 4: // MaxSP +100%
+ sc_start(bl,SC_INCMSPRATE,100,100,time);
+ if (tsd) clif_gospel_info(tsd, 0x18);
+ break;
+ case 5: // All stats +20
+ sc_start(bl,SC_INCALLSTATUS,100,20,time);
+ if (tsd) clif_gospel_info(tsd, 0x19);
+ break;
+ case 6: // Level 10 Blessing
+ sc_start(bl,SC_BLESSING,100,10,time);
+ break;
+ case 7: // Level 10 Increase AGI
+ sc_start(bl,SC_INCREASEAGI,100,10,time);
+ break;
+ case 8: // Enchant weapon with Holy element
+ sc_start(bl,SC_ASPERSIO,100,1,time);
+ if (tsd) clif_gospel_info(tsd, 0x1c);
+ break;
+ case 9: // Enchant armor with Holy element
+ sc_start(bl,SC_BENEDICTIO,100,1,time);
+ if (tsd) clif_gospel_info(tsd, 0x1d);
+ break;
+ case 10: // DEF +25%
+ sc_start(bl,SC_INCDEFRATE,100,25,time);
+ if (tsd) clif_gospel_info(tsd, 0x1e);
+ break;
+ case 11: // ATK +100%
+ sc_start(bl,SC_INCATKRATE,100,100,time);
+ if (tsd) clif_gospel_info(tsd, 0x1f);
+ break;
+ case 12: // HIT/Flee +50
+ sc_start(bl,SC_INCHIT,100,50,time);
+ sc_start(bl,SC_INCFLEE,100,50,time);
+ if (tsd) clif_gospel_info(tsd, 0x20);
+ break;
+ }
+ }
+ else if (battle_check_target(&src->bl,bl,BCT_ENEMY)>0)
+ { // Offensive Effect
+ int i = rnd()%9; // Negative buff count
+ int time = skill_get_time2(sg->skill_id, sg->skill_lv);
+ switch (i)
+ {
+ case 0: // Deal 1~9999 damage
+ skill_attack(BF_MISC,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
+ break;
+ case 1: // Curse
+ sc_start(bl,SC_CURSE,100,1,time);
+ break;
+ case 2: // Blind
+ sc_start(bl,SC_BLIND,100,1,time);
+ break;
+ case 3: // Poison
+ sc_start(bl,SC_POISON,100,1,time);
+ break;
+ case 4: // Level 10 Provoke
+ sc_start(bl,SC_PROVOKE,100,10,time);
+ break;
+ case 5: // DEF -100%
+ sc_start(bl,SC_INCDEFRATE,100,-100,time);
+ break;
+ case 6: // ATK -100%
+ sc_start(bl,SC_INCATKRATE,100,-100,time);
+ break;
+ case 7: // Flee -100%
+ sc_start(bl,SC_INCFLEERATE,100,-100,time);
+ break;
+ case 8: // Speed/ASPD -25%
+ sc_start4(bl,SC_GOSPEL,100,1,0,0,BCT_ENEMY,time);
+ break;
+ }
+ }
+ break;
- if (tsc && !tsc->data[type] &&
- distance_xy(src->bl.x, src->bl.y, bl->x, bl->y) <= range)// don't consider outer bounderies
- sc_start(bl, type, 100, sg->skill_lv, sec);
+ case UNT_BASILICA:
+ {
+ int i = battle_check_target(&src->bl, bl, BCT_ENEMY);
+ if( i > 0 && !(status_get_mode(bl)&MD_BOSS) )
+ { // knock-back any enemy except Boss
+ skill_blown(&src->bl, bl, 2, unit_getdir(bl), 0);
+ clif_fixpos(bl);
+ }
- if (unit_is_walking(bl) && // wait until target stop walking
- (tsc && tsc->data[type] && tsc->data[type]->val4 >= tsc->data[type]->val3-range))
- break;
+ if( sg->src_id != bl->id && i <= 0 )
+ sc_start4(bl, type, 100, 0, 0, 0, src->bl.id, sg->interval + 100);
+ }
+ break;
+
+ case UNT_GRAVITATION:
+ case UNT_EARTHSTRAIN:
+ case UNT_FIREWALK:
+ case UNT_ELECTRICWALK:
+ case UNT_PSYCHIC_WAVE:
+ skill_attack(skill_get_type(sg->skill_id),ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
+ break;
+
+ case UNT_GROUNDDRIFT_WIND:
+ case UNT_GROUNDDRIFT_DARK:
+ case UNT_GROUNDDRIFT_POISON:
+ case UNT_GROUNDDRIFT_WATER:
+ case UNT_GROUNDDRIFT_FIRE:
+ map_foreachinrange(skill_trap_splash,&src->bl,
+ skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag,
+ &src->bl,tick);
+ sg->unit_id = UNT_USED_TRAPS;
+ //clif_changetraplook(&src->bl, UNT_FIREPILLAR_ACTIVE);
+ sg->limit=DIFF_TICK(tick,sg->tick)+1500;
+ break;
+ /**
+ * 3rd stuff
+ **/
+ case UNT_POISONSMOKE:
+ if( battle_check_target(ss,bl,BCT_ENEMY) > 0 && !(tsc && tsc->data[sg->val2]) && rnd()%100 < 20 )
+ sc_start(bl,sg->val2,100,sg->val3,skill_get_time2(GC_POISONINGWEAPON, 1));
+ break;
+
+ case UNT_EPICLESIS:
+ if( bl->type == BL_PC && !battle_check_undead(tstatus->race, tstatus->def_ele) && tstatus->race != RC_DEMON )
+ {
+ if( ++sg->val2 % 3 == 0 ) {
+ int hp, sp;
+ switch( sg->skill_lv )
+ {
+ case 1: case 2: hp = 3; sp = 2; break;
+ case 3: case 4: hp = 4; sp = 3; break;
+ case 5: default: hp = 5; sp = 4; break;
+ }
+ hp = tstatus->max_hp * hp / 100;
+ sp = tstatus->max_sp * sp / 100;
+ status_heal(bl, hp, sp, 2);
+ sc_start(bl, type, 100, sg->skill_lv, (sg->interval * 3) + 100);
+ }
+ // Reveal hidden players every 5 seconds.
+ if( sg->val2 % 5 == 0 ) {
+ // TODO: check if other hidden status can be removed.
+ status_change_end(bl,SC_HIDING,INVALID_TIMER);
+ status_change_end(bl,SC_CLOAKING,INVALID_TIMER);
+ }
+ }
+ /* Enable this if kRO fix the current skill. Currently no damage on undead and demon monster. [Jobbie]
+ else if( battle_check_target(ss, bl, BCT_ENEMY) > 0 && battle_check_undead(tstatus->race, tstatus->def_ele) )
+ skill_castend_damage_id(&src->bl, bl, sg->skill_id, sg->skill_lv, 0, 0);*/
+ break;
+
+ case UNT_STEALTHFIELD:
+ if( bl->id == sg->src_id )
+ break; // Dont work on Self (video shows that)
+ case UNT_NEUTRALBARRIER:
+ sc_start(bl,type,100,sg->skill_lv,sg->interval + 100);
+ break;
+
+ case UNT_DIMENSIONDOOR:
+ if( tsd && !map[bl->m].flag.noteleport )
+ pc_randomwarp(tsd,3);
+ else if( bl->type == BL_MOB && battle_config.mob_warp&8 )
+ unit_warp(bl,-1,-1,-1,3);
+ break;
+
+ case UNT_REVERBERATION:
+ clif_changetraplook(&src->bl,UNT_USED_TRAPS);
+ map_foreachinrange(skill_trap_splash,&src->bl, skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &src->bl,tick);
+ sg->limit = DIFF_TICK(tick,sg->tick)+1000;
+ sg->unit_id = UNT_USED_TRAPS;
+ break;
+
+ case UNT_SEVERE_RAINSTORM:
+ if( battle_check_target(&src->bl, bl, BCT_ENEMY) )
+ skill_attack(BF_WEAPON,ss,&src->bl,bl,WM_SEVERE_RAINSTORM_MELEE,sg->skill_lv,tick,0);
+ break;
+ case UNT_NETHERWORLD:
+ if( !(status_get_mode(bl)&MD_BOSS) && ss != bl && battle_check_target(&src->bl, bl, BCT_PARTY) ) {
+ if( !(tsc && tsc->data[type]) ){
+ sc_start(bl, type, 100, sg->skill_lv, skill_get_time2(sg->skill_id,sg->skill_lv));
+ sg->limit = DIFF_TICK(tick,sg->tick);
+ sg->unit_id = UNT_USED_TRAPS;
+ }
+ }
+ break;
+ case UNT_THORNS_TRAP:
+ if( tsc ) {
+ if( !sg->val2 ) {
+ int sec = skill_get_time2(sg->skill_id, sg->skill_lv);
+ if( sc_start(bl, type, 100, sg->skill_lv, sec) ) {
+ const struct TimerData* td = tsc->data[type]?get_timer(tsc->data[type]->timer):NULL;
+ if( td )
+ sec = DIFF_TICK(td->tick, tick);
+ ///map_moveblock(bl, src->bl.x, src->bl.y, tick); // in official server it doesn't behave like this. [malufett]
+ clif_fixpos(bl);
+ sg->val2 = bl->id;
+ } else
+ sec = 3000; // Couldn't trap it?
+ sg->limit = DIFF_TICK(tick, sg->tick) + sec;
+ } else if( tsc->data[SC_THORNSTRAP] && bl->id == sg->val2 )
+ skill_attack(skill_get_type(GN_THORNS_TRAP), ss, ss, bl, sg->skill_id, sg->skill_lv, tick, SD_LEVEL|SD_ANIMATION);
+ }
+ break;
+
+ case UNT_DEMONIC_FIRE: {
+ TBL_PC* sd = BL_CAST(BL_PC, ss);
+ switch( sg->val2 ) {
+ case 1:
+ case 2:
+ default:
+ sc_start(bl, SC_BURNING, 4 + 4 * sg->skill_lv, sg->skill_lv,
+ skill_get_time2(sg->skill_id, sg->skill_lv));
+ skill_attack(skill_get_type(sg->skill_id), ss, &src->bl, bl,
+ sg->skill_id, sg->skill_lv + 10 * sg->val2, tick, 0);
+ break;
+ case 3:
+ skill_attack(skill_get_type(CR_ACIDDEMONSTRATION), ss, &src->bl, bl,
+ CR_ACIDDEMONSTRATION, sd ? pc_checkskill(sd, CR_ACIDDEMONSTRATION) : sg->skill_lv, tick, 0);
+ break;
- if (tsc && (!tsc->data[type] || (tsc->data[type] && tsc->data[type]->val4 < 1)))
- break;
+ }
+ }
+ break;
+
+ case UNT_FIRE_EXPANSION_SMOKE_POWDER:
+ sc_start(bl, status_skill2sc(GN_FIRE_EXPANSION_SMOKE_POWDER), 100, sg->skill_lv, 1000);
+ break;
+
+ case UNT_FIRE_EXPANSION_TEAR_GAS:
+ sc_start(bl, status_skill2sc(GN_FIRE_EXPANSION_TEAR_GAS), 100, sg->skill_lv, 1000);
+ break;
+
+ case UNT_HELLS_PLANT:
+ if( battle_check_target(&src->bl,bl,BCT_ENEMY) > 0 )
+ skill_attack(skill_get_type(GN_HELLS_PLANT_ATK), ss, &src->bl, bl, GN_HELLS_PLANT_ATK, sg->skill_lv, tick, 0);
+ if( ss != bl) //The caster is the only one who can step on the Plants, without destroying them
+ sg->limit = DIFF_TICK(tick, sg->tick) + 100;
+ break;
+
+ case UNT_CLOUD_KILL:
+ if(tsc && !tsc->data[type])
+ status_change_start(bl,type,10000,sg->skill_lv,sg->group_id,0,0,skill_get_time2(sg->skill_id,sg->skill_lv),8);
+ skill_attack(skill_get_type(sg->skill_id),ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
+ break;
+
+ case UNT_WARMER:
+ if( bl->type == BL_PC && !battle_check_undead(tstatus->race, tstatus->def_ele) && tstatus->race != RC_DEMON ) {
+ int hp = 125 * sg->skill_lv; // Officially is 125 * skill_lv.
+ struct status_change *ssc = status_get_sc(ss);
+ if( ssc && ssc->data[SC_HEATER_OPTION] )
+ hp += hp * ssc->data[SC_HEATER_OPTION]->val3 / 100;
+ if( tstatus->hp != tstatus->max_hp )
+ clif_skill_nodamage(&src->bl, bl, AL_HEAL, hp, 0);
+ if( tsc && tsc->data[SC_AKAITSUKI] && hp )
+ hp = ~hp + 1;
+ status_heal(bl, hp, 0, 0);
+ sc_start(bl, SC_WARMER, 100, sg->skill_lv, skill_get_time2(sg->skill_id,sg->skill_lv));
+ }
+ break;
+
+ case UNT_FIRE_INSIGNIA:
+ case UNT_WATER_INSIGNIA:
+ case UNT_WIND_INSIGNIA:
+ case UNT_EARTH_INSIGNIA:
+ case UNT_ZEPHYR:
+ sc_start(bl,type, 100, sg->skill_lv, sg->interval);
+ if (sg->unit_id != UNT_ZEPHYR && !battle_check_undead(tstatus->race, tstatus->def_ele)) {
+ int hp = tstatus->max_hp / 100; //+1% each 5s
+ if ((sg->val3) % 5) { //each 5s
+ if (tstatus->def_ele == skill_get_ele(sg->skill_id,sg->skill_lv)){
+ status_heal(bl, hp, 0, 2);
+ } else if((sg->unit_id == UNT_FIRE_INSIGNIA && tstatus->def_ele == ELE_EARTH)
+ ||(sg->unit_id == UNT_WATER_INSIGNIA && tstatus->def_ele == ELE_FIRE)
+ ||(sg->unit_id == UNT_WIND_INSIGNIA && tstatus->def_ele == ELE_WATER)
+ ||(sg->unit_id == UNT_EARTH_INSIGNIA && tstatus->def_ele == ELE_WIND)
+ ){
+ status_heal(bl, -hp, 0, 0);
+ }
+ }
+ sg->val3++; //timer
+ if (sg->val3 > 5) sg->val3 = 0;
+ }
+ break;
- if (unit_is_walking(bl) &&
- distance_xy(src->bl.x, src->bl.y, bl->x, bl->y) > range) // going outside of boundaries? then force it to stop
- unit_stop_walking(bl,1);
+ case UNT_VACUUM_EXTREME:
+ {// TODO: official behavior in gvg area. [malufett]
+ int sec = sg->limit - DIFF_TICK(tick, sg->tick);
+ int range = skill_get_unit_range(sg->skill_id, sg->skill_lv);
- if (!unit_is_walking(bl) &&
- distance_xy(src->bl.x, src->bl.y, bl->x, bl->y) <= range && // only snap if the target is inside the range or
- src->bl.x != bl->x && src->bl.y != bl->y) { // diagonal position parallel to VE's center
- unit_movepos(bl, src->bl.x, src->bl.y, 0, 0);
- clif_fixpos(bl);
- }
- }
- break;
+ if( tsc && !tsc->data[type] &&
+ distance_xy(src->bl.x, src->bl.y, bl->x, bl->y) <= range)// don't consider outer bounderies
+ sc_start(bl, type, 100, sg->skill_lv, sec);
- case UNT_FIRE_MANTLE:
- if (battle_check_target(&src->bl, bl, BCT_ENEMY))
- skill_attack(BF_MAGIC,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
- break;
+ if( unit_is_walking(bl) && // wait until target stop walking
+ ( tsc && tsc->data[type] && tsc->data[type]->val4 >= tsc->data[type]->val3-range ))
+ break;
- case UNT_ZENKAI_WATER:
- case UNT_ZENKAI_LAND:
- case UNT_ZENKAI_FIRE:
- case UNT_ZENKAI_WIND:
- if (battle_check_target(&src->bl,bl,BCT_ENEMY) > 0) {
- switch (sg->unit_id) {
- case UNT_ZENKAI_WATER:
- sc_start(bl, SC_CRYSTALIZE, sg->val1*5, sg->skill_lv, skill_get_time2(sg->skill_id, sg->skill_lv));
- sc_start(bl, SC_FREEZE, sg->val1*5, sg->skill_lv, skill_get_time2(sg->skill_id, sg->skill_lv));
- sc_start(bl, SC_FREEZING, sg->val1*5, sg->skill_lv, skill_get_time2(sg->skill_id, sg->skill_lv));
- break;
- case UNT_ZENKAI_LAND:
- sc_start(bl, SC_STONE, sg->val1*5, sg->skill_lv, skill_get_time2(sg->skill_id, sg->skill_lv));
- sc_start(bl, SC_POISON, sg->val1*5, sg->skill_lv, skill_get_time2(sg->skill_id, sg->skill_lv));
- break;
- case UNT_ZENKAI_FIRE:
- sc_start(bl, SC_BURNING, sg->val1*5, sg->skill_lv, skill_get_time2(sg->skill_id, sg->skill_lv));
- break;
- case UNT_ZENKAI_WIND:
- sc_start(bl, SC_SILENCE, sg->val1*5, sg->skill_lv, skill_get_time2(sg->skill_id, sg->skill_lv));
- sc_start(bl, SC_SLEEP, sg->val1*5, sg->skill_lv, skill_get_time2(sg->skill_id, sg->skill_lv));
- sc_start(bl, SC_DEEPSLEEP, sg->val1*5, sg->skill_lv, skill_get_time2(sg->skill_id, sg->skill_lv));
- break;
- }
- } else
- sc_start2(bl,type,100,sg->val1,sg->val2,skill_get_time2(sg->skill_id, sg->skill_lv));
- break;
+ if( tsc && ( !tsc->data[type] || (tsc->data[type] && tsc->data[type]->val4 < 1 ) ) )
+ break;
- case UNT_MAKIBISHI:
- skill_attack(BF_MISC, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0);
- sg->limit = DIFF_TICK(tick, sg->tick);
- sg->unit_id = UNT_USED_TRAPS;
- break;
+ if( unit_is_walking(bl) &&
+ distance_xy(src->bl.x, src->bl.y, bl->x, bl->y) > range )// going outside of boundaries? then force it to stop
+ unit_stop_walking(bl,1);
- case UNT_LAVA_SLIDE:
- skill_attack(BF_WEAPON, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0);
- if (++sg->val1 > 4) //after 5 stop hit and destroy me
- sg->limit = DIFF_TICK(tick, sg->tick);
- break;
- case UNT_POISON_MIST:
- skill_attack(BF_MAGIC, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0);
- status_change_start(bl, SC_BLIND, rnd() % 100 > sg->skill_lv * 10, sg->skill_lv, sg->skill_id, 0, 0, skill_get_time2(sg->skill_id, sg->skill_lv), 2|8);
- break;
- }
+ if( !unit_is_walking(bl) &&
+ distance_xy(src->bl.x, src->bl.y, bl->x, bl->y) <= range && // only snap if the target is inside the range or
+ src->bl.x != bl->x && src->bl.y != bl->y){// diagonal position parallel to VE's center
+ unit_movepos(bl, src->bl.x, src->bl.y, 0, 0);
+ clif_fixpos(bl);
+ }
+ }
+ break;
+
+ case UNT_FIRE_MANTLE:
+ if( battle_check_target(&src->bl, bl, BCT_ENEMY) )
+ skill_attack(BF_MAGIC,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
+ break;
+
+ case UNT_ZENKAI_WATER:
+ case UNT_ZENKAI_LAND:
+ case UNT_ZENKAI_FIRE:
+ case UNT_ZENKAI_WIND:
+ if( battle_check_target(&src->bl,bl,BCT_ENEMY) > 0 ){
+ switch( sg->unit_id ){
+ case UNT_ZENKAI_WATER:
+ sc_start(bl, SC_CRYSTALIZE, sg->val1*5, sg->skill_lv, skill_get_time2(sg->skill_id, sg->skill_lv));
+ sc_start(bl, SC_FREEZE, sg->val1*5, sg->skill_lv, skill_get_time2(sg->skill_id, sg->skill_lv));
+ sc_start(bl, SC_FREEZING, sg->val1*5, sg->skill_lv, skill_get_time2(sg->skill_id, sg->skill_lv));
+ break;
+ case UNT_ZENKAI_LAND:
+ sc_start(bl, SC_STONE, sg->val1*5, sg->skill_lv, skill_get_time2(sg->skill_id, sg->skill_lv));
+ sc_start(bl, SC_POISON, sg->val1*5, sg->skill_lv, skill_get_time2(sg->skill_id, sg->skill_lv));
+ break;
+ case UNT_ZENKAI_FIRE:
+ sc_start(bl, SC_BURNING, sg->val1*5, sg->skill_lv, skill_get_time2(sg->skill_id, sg->skill_lv));
+ break;
+ case UNT_ZENKAI_WIND:
+ sc_start(bl, SC_SILENCE, sg->val1*5, sg->skill_lv, skill_get_time2(sg->skill_id, sg->skill_lv));
+ sc_start(bl, SC_SLEEP, sg->val1*5, sg->skill_lv, skill_get_time2(sg->skill_id, sg->skill_lv));
+ sc_start(bl, SC_DEEPSLEEP, sg->val1*5, sg->skill_lv, skill_get_time2(sg->skill_id, sg->skill_lv));
+ break;
+ }
+ }else
+ sc_start2(bl,type,100,sg->val1,sg->val2,skill_get_time2(sg->skill_id, sg->skill_lv));
+ break;
+
+ case UNT_MAKIBISHI:
+ skill_attack(BF_MISC, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0);
+ sg->limit = DIFF_TICK(tick, sg->tick);
+ sg->unit_id = UNT_USED_TRAPS;
+ break;
+
+ case UNT_LAVA_SLIDE:
+ skill_attack(BF_WEAPON, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0);
+ if(++sg->val1 > 4) //after 5 stop hit and destroy me
+ sg->limit = DIFF_TICK(tick, sg->tick);
+ break;
+ case UNT_POISON_MIST:
+ skill_attack(BF_MAGIC, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0);
+ status_change_start(bl, SC_BLIND, rnd() % 100 > sg->skill_lv * 10, sg->skill_lv, sg->skill_id, 0, 0, skill_get_time2(sg->skill_id, sg->skill_lv), 2|8);
+ break;
+ }
- if (bl->type == BL_MOB && ss != bl)
- mobskill_event((TBL_MOB *)bl, ss, tick, MSC_SKILLUSED|(skillid<<16));
+ if (bl->type == BL_MOB && ss != bl)
+ mobskill_event((TBL_MOB*)bl, ss, tick, MSC_SKILLUSED|(skillid<<16));
- return skillid;
+ return skillid;
}
/*==========================================
* Triggered when a char steps out of a skill cell
*------------------------------------------*/
-int skill_unit_onout(struct skill_unit *src, struct block_list *bl, unsigned int tick)
+int skill_unit_onout (struct skill_unit *src, struct block_list *bl, unsigned int tick)
{
- struct skill_unit_group *sg;
- struct status_change *sc;
- struct status_change_entry *sce;
- enum sc_type type;
-
- nullpo_ret(src);
- nullpo_ret(bl);
- nullpo_ret(sg=src->group);
- sc = status_get_sc(bl);
- type = status_skill2sc(sg->skill_id);
- sce = (sc && type != -1)?sc->data[type]:NULL;
-
- if (bl->prev==NULL ||
- (status_isdead(bl) && sg->unit_id != UNT_ANKLESNARE && sg->unit_id != UNT_SPIDERWEB)) //Need to delete the trap if the source died.
- return 0;
-
- switch (sg->unit_id) {
- case UNT_SAFETYWALL:
- case UNT_PNEUMA:
- case UNT_EPICLESIS://Arch Bishop
- case UNT_NEUTRALBARRIER:
- case UNT_STEALTHFIELD:
- if (sce)
- status_change_end(bl, type, INVALID_TIMER);
- break;
-
- case UNT_BASILICA:
- if (sce && sce->val4 == src->bl.id)
- status_change_end(bl, type, INVALID_TIMER);
- break;
- case UNT_HERMODE: //Clear Hermode if the owner moved.
- if (sce && sce->val3 == BCT_SELF && sce->val4 == sg->group_id)
- status_change_end(bl, type, INVALID_TIMER);
- break;
-
- case UNT_SPIDERWEB: {
- struct block_list *target = map_id2bl(sg->val2);
- if (target && target==bl) {
- if (sce && sce->val3 == sg->group_id)
- status_change_end(bl, type, INVALID_TIMER);
- sg->limit = DIFF_TICK(tick,sg->tick)+1000;
- }
- break;
- }
- }
- return sg->skill_id;
+ struct skill_unit_group *sg;
+ struct status_change *sc;
+ struct status_change_entry *sce;
+ enum sc_type type;
+
+ nullpo_ret(src);
+ nullpo_ret(bl);
+ nullpo_ret(sg=src->group);
+ sc = status_get_sc(bl);
+ type = status_skill2sc(sg->skill_id);
+ sce = (sc && type != -1)?sc->data[type]:NULL;
+
+ if( bl->prev==NULL ||
+ (status_isdead(bl) && sg->unit_id != UNT_ANKLESNARE && sg->unit_id != UNT_SPIDERWEB) ) //Need to delete the trap if the source died.
+ return 0;
+
+ switch(sg->unit_id){
+ case UNT_SAFETYWALL:
+ case UNT_PNEUMA:
+ case UNT_EPICLESIS://Arch Bishop
+ case UNT_NEUTRALBARRIER:
+ case UNT_STEALTHFIELD:
+ if (sce)
+ status_change_end(bl, type, INVALID_TIMER);
+ break;
+
+ case UNT_BASILICA:
+ if( sce && sce->val4 == src->bl.id )
+ status_change_end(bl, type, INVALID_TIMER);
+ break;
+ case UNT_HERMODE: //Clear Hermode if the owner moved.
+ if (sce && sce->val3 == BCT_SELF && sce->val4 == sg->group_id)
+ status_change_end(bl, type, INVALID_TIMER);
+ break;
+
+ case UNT_SPIDERWEB:
+ {
+ struct block_list *target = map_id2bl(sg->val2);
+ if (target && target==bl)
+ {
+ if (sce && sce->val3 == sg->group_id)
+ status_change_end(bl, type, INVALID_TIMER);
+ sg->limit = DIFF_TICK(tick,sg->tick)+1000;
+ }
+ break;
+ }
+ }
+ return sg->skill_id;
}
/*==========================================
* Triggered when a char steps out of a skill group (entirely) [Skotlex]
*------------------------------------------*/
-static int skill_unit_onleft(int skill_id, struct block_list *bl, unsigned int tick)
+static int skill_unit_onleft (int skill_id, struct block_list *bl, unsigned int tick)
{
- struct status_change *sc;
- struct status_change_entry *sce;
- enum sc_type type;
-
- sc = status_get_sc(bl);
- if (sc && !sc->count)
- sc = NULL;
-
- type = status_skill2sc(skill_id);
- sce = (sc && type != -1)?sc->data[type]:NULL;
-
- switch (skill_id) {
- case WZ_QUAGMIRE:
- if (bl->type==BL_MOB)
- break;
- if (sce)
- status_change_end(bl, type, INVALID_TIMER);
- break;
-
- case BD_LULLABY:
- case BD_RICHMANKIM:
- case BD_ETERNALCHAOS:
- case BD_DRUMBATTLEFIELD:
- case BD_RINGNIBELUNGEN:
- case BD_ROKISWEIL:
- case BD_INTOABYSS:
- case BD_SIEGFRIED:
- if (sc && sc->data[SC_DANCING] && (sc->data[SC_DANCING]->val1&0xFFFF) == skill_id) {
- //Check if you just stepped out of your ensemble skill to cancel dancing. [Skotlex]
- //We don't check for SC_LONGING because someone could always have knocked you back and out of the song/dance.
- //FIXME: This code is not perfect, it doesn't checks for the real ensemble's owner,
- //it only checks if you are doing the same ensemble. So if there's two chars doing an ensemble
- //which overlaps, by stepping outside of the other parther's ensemble will cause you to cancel
- //your own. Let's pray that scenario is pretty unlikely and noone will complain too much about it.
- status_change_end(bl, SC_DANCING, INVALID_TIMER);
- }
- case MH_STEINWAND:
- case MG_SAFETYWALL:
- case AL_PNEUMA:
- case SA_VOLCANO:
- case SA_DELUGE:
- case SA_VIOLENTGALE:
- case CG_HERMODE:
- case HW_GRAVITATION:
- case NJ_SUITON:
- case SC_MAELSTROM:
- case EL_WATER_BARRIER:
- case EL_ZEPHYR:
- case EL_POWER_OF_GAIA:
- case SO_FIRE_INSIGNIA:
- case SO_WATER_INSIGNIA:
- case SO_WIND_INSIGNIA:
- case SO_EARTH_INSIGNIA:
- if (sce)
- status_change_end(bl, type, INVALID_TIMER);
- break;
- case SC_BLOODYLUST:
- if (sce) {
- status_change_end(bl, type, INVALID_TIMER);
- status_set_sp(bl, 0, 0); //set sp to 0 when quitting zone
- }
- break;
-
- case BA_POEMBRAGI:
- case BA_WHISTLE:
- case BA_ASSASSINCROSS:
- case BA_APPLEIDUN:
- case DC_HUMMING:
- case DC_DONTFORGETME:
- case DC_FORTUNEKISS:
- case DC_SERVICEFORYOU:
- if (sce) {
- if (sce->val4 == 2) { /* We have the status but we're not elegible for it, so we take it away. (bugreport:4591) */
- if (!(sc && sc->data[SC_DANCING] && sc->data[SC_DANCING]->val2)) /* check if we're still in the skill */
- status_change_end(bl,type,INVALID_TIMER);
- } else {
- delete_timer(sce->timer, status_change_timer);
- //NOTE: It'd be nice if we could get the skill_lv for a more accurate extra time, but alas...
- //not possible on our current implementation.
- sce->val4 = 1; //Store the fact that this is a "reduced" duration effect.
- sce->timer = add_timer(tick+skill_get_time2(skill_id,1), status_change_timer, bl->id, type);
- }
- }
- break;
- case PF_FOGWALL:
- if (sce) {
- status_change_end(bl, type, INVALID_TIMER);
- if ((sce=sc->data[SC_BLIND])) {
- if (bl->type == BL_PC) //Players get blind ended inmediately, others have it still for 30 secs. [Skotlex]
- status_change_end(bl, SC_BLIND, INVALID_TIMER);
- else {
- delete_timer(sce->timer, status_change_timer);
- sce->timer = add_timer(30000+tick, status_change_timer, bl->id, SC_BLIND);
- }
- }
- }
- break;
- case GD_LEADERSHIP:
- case GD_GLORYWOUNDS:
- case GD_SOULCOLD:
- case GD_HAWKEYES:
- if (!(sce && sce->val4))
- status_change_end(bl, type, INVALID_TIMER);
- break;
- }
+ struct status_change *sc;
+ struct status_change_entry *sce;
+ enum sc_type type;
+
+ sc = status_get_sc(bl);
+ if (sc && !sc->count)
+ sc = NULL;
+
+ type = status_skill2sc(skill_id);
+ sce = (sc && type != -1)?sc->data[type]:NULL;
+
+ switch (skill_id)
+ {
+ case WZ_QUAGMIRE:
+ if (bl->type==BL_MOB)
+ break;
+ if (sce)
+ status_change_end(bl, type, INVALID_TIMER);
+ break;
+
+ case BD_LULLABY:
+ case BD_RICHMANKIM:
+ case BD_ETERNALCHAOS:
+ case BD_DRUMBATTLEFIELD:
+ case BD_RINGNIBELUNGEN:
+ case BD_ROKISWEIL:
+ case BD_INTOABYSS:
+ case BD_SIEGFRIED:
+ if(sc && sc->data[SC_DANCING] && (sc->data[SC_DANCING]->val1&0xFFFF) == skill_id)
+ { //Check if you just stepped out of your ensemble skill to cancel dancing. [Skotlex]
+ //We don't check for SC_LONGING because someone could always have knocked you back and out of the song/dance.
+ //FIXME: This code is not perfect, it doesn't checks for the real ensemble's owner,
+ //it only checks if you are doing the same ensemble. So if there's two chars doing an ensemble
+ //which overlaps, by stepping outside of the other parther's ensemble will cause you to cancel
+ //your own. Let's pray that scenario is pretty unlikely and noone will complain too much about it.
+ status_change_end(bl, SC_DANCING, INVALID_TIMER);
+ }
+ case MH_STEINWAND:
+ case MG_SAFETYWALL:
+ case AL_PNEUMA:
+ case SA_VOLCANO:
+ case SA_DELUGE:
+ case SA_VIOLENTGALE:
+ case CG_HERMODE:
+ case HW_GRAVITATION:
+ case NJ_SUITON:
+ case SC_MAELSTROM:
+ case EL_WATER_BARRIER:
+ case EL_ZEPHYR:
+ case EL_POWER_OF_GAIA:
+ case SO_FIRE_INSIGNIA:
+ case SO_WATER_INSIGNIA:
+ case SO_WIND_INSIGNIA:
+ case SO_EARTH_INSIGNIA:
+ if (sce)
+ status_change_end(bl, type, INVALID_TIMER);
+ break;
+ case SC_BLOODYLUST:
+ if (sce) {
+ status_change_end(bl, type, INVALID_TIMER);
+ status_set_sp(bl, 0, 0); //set sp to 0 when quitting zone
+ }
+ break;
+
+ case BA_POEMBRAGI:
+ case BA_WHISTLE:
+ case BA_ASSASSINCROSS:
+ case BA_APPLEIDUN:
+ case DC_HUMMING:
+ case DC_DONTFORGETME:
+ case DC_FORTUNEKISS:
+ case DC_SERVICEFORYOU:
+ if (sce) {
+ if( sce->val4 == 2 ) {/* We have the status but we're not elegible for it, so we take it away. (bugreport:4591) */
+ if( !( sc && sc->data[SC_DANCING] && sc->data[SC_DANCING]->val2 ) )/* check if we're still in the skill */
+ status_change_end(bl,type,INVALID_TIMER);
+ } else {
+ delete_timer(sce->timer, status_change_timer);
+ //NOTE: It'd be nice if we could get the skill_lv for a more accurate extra time, but alas...
+ //not possible on our current implementation.
+ sce->val4 = 1; //Store the fact that this is a "reduced" duration effect.
+ sce->timer = add_timer(tick+skill_get_time2(skill_id,1), status_change_timer, bl->id, type);
+ }
+ }
+ break;
+ case PF_FOGWALL:
+ if (sce)
+ {
+ status_change_end(bl, type, INVALID_TIMER);
+ if ((sce=sc->data[SC_BLIND]))
+ {
+ if (bl->type == BL_PC) //Players get blind ended inmediately, others have it still for 30 secs. [Skotlex]
+ status_change_end(bl, SC_BLIND, INVALID_TIMER);
+ else {
+ delete_timer(sce->timer, status_change_timer);
+ sce->timer = add_timer(30000+tick, status_change_timer, bl->id, SC_BLIND);
+ }
+ }
+ }
+ break;
+ case GD_LEADERSHIP:
+ case GD_GLORYWOUNDS:
+ case GD_SOULCOLD:
+ case GD_HAWKEYES:
+ if( !(sce && sce->val4) )
+ status_change_end(bl, type, INVALID_TIMER);
+ break;
+ }
- return skill_id;
+ return skill_id;
}
/*==========================================
@@ -12162,1059 +12030,1040 @@ static int skill_unit_onleft(int skill_id, struct block_list *bl, unsigned int t
* flag&1: Invoke onplace function (otherwise invoke onout)
* flag&4: Invoke a onleft call (the unit might be scheduled for deletion)
*------------------------------------------*/
-static int skill_unit_effect(struct block_list *bl, va_list ap)
+static int skill_unit_effect (struct block_list* bl, va_list ap)
{
- struct skill_unit *unit = va_arg(ap,struct skill_unit *);
- struct skill_unit_group *group = unit->group;
- unsigned int tick = va_arg(ap,unsigned int);
- unsigned int flag = va_arg(ap,unsigned int);
- int skill_id;
- bool dissonance;
-
- if ((!unit->alive && !(flag&4)) || bl->prev == NULL)
- return 0;
-
- nullpo_ret(group);
-
- dissonance = skill_dance_switch(unit, 0);
-
- //Necessary in case the group is deleted after calling on_place/on_out [Skotlex]
- skill_id = group->skill_id;
-
- //Target-type check.
- if (!(group->bl_flag&bl->type && battle_check_target(&unit->bl,bl,group->target_flag)>0)) {
- if (flag&4 && ((group->src_id == bl->id && group->state.song_dance&0x2) || skill_get_inf2(skill_id)&INF2_SONG_DANCE))
- skill_unit_onleft(skill_id, bl, tick);//Ensemble check to terminate it.
- } else {
- if (flag&1)
- skill_unit_onplace(unit,bl,tick);
- else
- skill_unit_onout(unit,bl,tick);
-
- if (flag&4)
- skill_unit_onleft(skill_id, bl, tick);
- }
+ struct skill_unit* unit = va_arg(ap,struct skill_unit*);
+ struct skill_unit_group* group = unit->group;
+ unsigned int tick = va_arg(ap,unsigned int);
+ unsigned int flag = va_arg(ap,unsigned int);
+ int skill_id;
+ bool dissonance;
+
+ if( (!unit->alive && !(flag&4)) || bl->prev == NULL )
+ return 0;
+
+ nullpo_ret(group);
+
+ dissonance = skill_dance_switch(unit, 0);
+
+ //Necessary in case the group is deleted after calling on_place/on_out [Skotlex]
+ skill_id = group->skill_id;
+
+ //Target-type check.
+ if( !(group->bl_flag&bl->type && battle_check_target(&unit->bl,bl,group->target_flag)>0) ) {
+ if( flag&4 && ((group->src_id == bl->id && group->state.song_dance&0x2) || skill_get_inf2(skill_id)&INF2_SONG_DANCE) )
+ skill_unit_onleft(skill_id, bl, tick);//Ensemble check to terminate it.
+ } else {
+ if( flag&1 )
+ skill_unit_onplace(unit,bl,tick);
+ else
+ skill_unit_onout(unit,bl,tick);
+
+ if( flag&4 )
+ skill_unit_onleft(skill_id, bl, tick);
+ }
- if (dissonance) skill_dance_switch(unit, 1);
+ if( dissonance ) skill_dance_switch(unit, 1);
- return 0;
+ return 0;
}
/*==========================================
*
*------------------------------------------*/
-int skill_unit_ondamaged(struct skill_unit *src, struct block_list *bl, int damage, unsigned int tick)
+int skill_unit_ondamaged (struct skill_unit *src, struct block_list *bl, int damage, unsigned int tick)
{
- struct skill_unit_group *sg;
-
- nullpo_ret(src);
- nullpo_ret(sg=src->group);
-
- switch (sg->unit_id) {
- case UNT_BLASTMINE:
- case UNT_SKIDTRAP:
- case UNT_LANDMINE:
- case UNT_SHOCKWAVE:
- case UNT_SANDMAN:
- case UNT_FLASHER:
- case UNT_CLAYMORETRAP:
- case UNT_FREEZINGTRAP:
- case UNT_TALKIEBOX:
- case UNT_ANKLESNARE:
- case UNT_ICEWALL:
- case UNT_REVERBERATION:
- case UNT_WALLOFTHORN:
- src->val1-=damage;
- break;
- default:
- damage = 0;
- break;
- }
- return damage;
+ struct skill_unit_group *sg;
+
+ nullpo_ret(src);
+ nullpo_ret(sg=src->group);
+
+ switch( sg->unit_id ) {
+ case UNT_BLASTMINE:
+ case UNT_SKIDTRAP:
+ case UNT_LANDMINE:
+ case UNT_SHOCKWAVE:
+ case UNT_SANDMAN:
+ case UNT_FLASHER:
+ case UNT_CLAYMORETRAP:
+ case UNT_FREEZINGTRAP:
+ case UNT_TALKIEBOX:
+ case UNT_ANKLESNARE:
+ case UNT_ICEWALL:
+ case UNT_REVERBERATION:
+ case UNT_WALLOFTHORN:
+ src->val1-=damage;
+ break;
+ default:
+ damage = 0;
+ break;
+ }
+ return damage;
}
/*==========================================
*
*------------------------------------------*/
-static int skill_check_condition_char_sub(struct block_list *bl, va_list ap)
+static int skill_check_condition_char_sub (struct block_list *bl, va_list ap)
{
- int *c, skillid;
- struct block_list *src;
- struct map_session_data *sd;
- struct map_session_data *tsd;
- int *p_sd; //Contains the list of characters found.
-
- nullpo_ret(bl);
- nullpo_ret(tsd=(struct map_session_data *)bl);
- nullpo_ret(src=va_arg(ap,struct block_list *));
- nullpo_ret(sd=(struct map_session_data *)src);
-
- c=va_arg(ap,int *);
- p_sd = va_arg(ap, int *);
- skillid = va_arg(ap,int);
-
- if (((skillid != PR_BENEDICTIO && *c >=1) || *c >=2) && !(skill_get_inf2(skillid)&INF2_CHORUS_SKILL))
- return 0; //Partner found for ensembles, or the two companions for Benedictio. [Skotlex]
-
- if (bl == src)
- return 0;
-
- if (pc_isdead(tsd))
- return 0;
-
- if (tsd->sc.data[SC_SILENCE] || (tsd->sc.opt1 && tsd->sc.opt1 != OPT1_BURNING))
- return 0;
-
- if (skill_get_inf2(skillid)&INF2_CHORUS_SKILL) {
- if (tsd->status.party_id == sd->status.party_id && (tsd->class_&MAPID_THIRDMASK) == MAPID_MINSTRELWANDERER)
- p_sd[(*c)++] = tsd->bl.id;
- return 1;
- } else {
-
- switch (skillid) {
- case PR_BENEDICTIO: {
- int dir = map_calc_dir(&sd->bl,tsd->bl.x,tsd->bl.y);
- dir = (unit_getdir(&sd->bl) + dir)%8; //This adjusts dir to account for the direction the sd is facing.
- if ((tsd->class_&MAPID_BASEMASK) == MAPID_ACOLYTE && (dir == 2 || dir == 6) //Must be standing to the left/right of Priest.
- && sd->status.sp >= 10)
- p_sd[(*c)++]=tsd->bl.id;
- return 1;
- }
- case AB_ADORAMUS:
- // Adoramus does not consume Blue Gemstone when there is at least 1 Priest class next to the caster
- if ((tsd->class_&MAPID_UPPERMASK) == MAPID_PRIEST)
- p_sd[(*c)++] = tsd->bl.id;
- return 1;
- case WL_COMET:
- // Comet does not consume Red Gemstones when there is at least 1 Warlock class next to the caster
- if ((sd->class_&MAPID_THIRDMASK) == MAPID_WARLOCK)
- p_sd[(*c)++] = tsd->bl.id;
- return 1;
- case LG_RAYOFGENESIS:
- if (tsd->status.party_id == sd->status.party_id && (tsd->class_&MAPID_THIRDMASK) == MAPID_ROYAL_GUARD &&
- tsd->sc.data[SC_BANDING])
- p_sd[(*c)++] = tsd->bl.id;
- return 1;
- default: { //Warning: Assuming Ensemble Dance/Songs for code speed. [Skotlex]
- int skilllv;
- if (pc_issit(tsd) || !unit_can_move(&tsd->bl))
- return 0;
- if (sd->status.sex != tsd->status.sex &&
- (tsd->class_&MAPID_UPPERMASK) == MAPID_BARDDANCER &&
- (skilllv = pc_checkskill(tsd, skillid)) > 0 &&
- (tsd->weapontype1==W_MUSICAL || tsd->weapontype1==W_WHIP) &&
- sd->status.party_id && tsd->status.party_id &&
- sd->status.party_id == tsd->status.party_id &&
- !tsd->sc.data[SC_DANCING]) {
- p_sd[(*c)++]=tsd->bl.id;
- return skilllv;
- } else {
- return 0;
- }
- }
- break;
- }
+ int *c, skillid;
+ struct block_list *src;
+ struct map_session_data *sd;
+ struct map_session_data *tsd;
+ int *p_sd; //Contains the list of characters found.
+
+ nullpo_ret(bl);
+ nullpo_ret(tsd=(struct map_session_data*)bl);
+ nullpo_ret(src=va_arg(ap,struct block_list *));
+ nullpo_ret(sd=(struct map_session_data*)src);
+
+ c=va_arg(ap,int *);
+ p_sd = va_arg(ap, int *);
+ skillid = va_arg(ap,int);
+
+ if ( ((skillid != PR_BENEDICTIO && *c >=1) || *c >=2) && !(skill_get_inf2(skillid)&INF2_CHORUS_SKILL) )
+ return 0; //Partner found for ensembles, or the two companions for Benedictio. [Skotlex]
+
+ if (bl == src)
+ return 0;
+
+ if(pc_isdead(tsd))
+ return 0;
+
+ if (tsd->sc.data[SC_SILENCE] || ( tsd->sc.opt1 && tsd->sc.opt1 != OPT1_BURNING ))
+ return 0;
+
+ if( skill_get_inf2(skillid)&INF2_CHORUS_SKILL ) {
+ if( tsd->status.party_id == sd->status.party_id && (tsd->class_&MAPID_THIRDMASK) == MAPID_MINSTRELWANDERER )
+ p_sd[(*c)++] = tsd->bl.id;
+ return 1;
+ } else {
+
+ switch(skillid) {
+ case PR_BENEDICTIO: {
+ int dir = map_calc_dir(&sd->bl,tsd->bl.x,tsd->bl.y);
+ dir = (unit_getdir(&sd->bl) + dir)%8; //This adjusts dir to account for the direction the sd is facing.
+ if ((tsd->class_&MAPID_BASEMASK) == MAPID_ACOLYTE && (dir == 2 || dir == 6) //Must be standing to the left/right of Priest.
+ && sd->status.sp >= 10)
+ p_sd[(*c)++]=tsd->bl.id;
+ return 1;
+ }
+ case AB_ADORAMUS:
+ // Adoramus does not consume Blue Gemstone when there is at least 1 Priest class next to the caster
+ if( (tsd->class_&MAPID_UPPERMASK) == MAPID_PRIEST )
+ p_sd[(*c)++] = tsd->bl.id;
+ return 1;
+ case WL_COMET:
+ // Comet does not consume Red Gemstones when there is at least 1 Warlock class next to the caster
+ if( ( sd->class_&MAPID_THIRDMASK ) == MAPID_WARLOCK )
+ p_sd[(*c)++] = tsd->bl.id;
+ return 1;
+ case LG_RAYOFGENESIS:
+ if( tsd->status.party_id == sd->status.party_id && (tsd->class_&MAPID_THIRDMASK) == MAPID_ROYAL_GUARD &&
+ tsd->sc.data[SC_BANDING] )
+ p_sd[(*c)++] = tsd->bl.id;
+ return 1;
+ default: //Warning: Assuming Ensemble Dance/Songs for code speed. [Skotlex]
+ {
+ int skilllv;
+ if(pc_issit(tsd) || !unit_can_move(&tsd->bl))
+ return 0;
+ if (sd->status.sex != tsd->status.sex &&
+ (tsd->class_&MAPID_UPPERMASK) == MAPID_BARDDANCER &&
+ (skilllv = pc_checkskill(tsd, skillid)) > 0 &&
+ (tsd->weapontype1==W_MUSICAL || tsd->weapontype1==W_WHIP) &&
+ sd->status.party_id && tsd->status.party_id &&
+ sd->status.party_id == tsd->status.party_id &&
+ !tsd->sc.data[SC_DANCING])
+ {
+ p_sd[(*c)++]=tsd->bl.id;
+ return skilllv;
+ } else {
+ return 0;
+ }
+ }
+ break;
+ }
- }
- return 0;
+ }
+ return 0;
}
/*==========================================
* Checks and stores partners for ensemble skills [Skotlex]
*------------------------------------------*/
-int skill_check_pc_partner(struct map_session_data *sd, short skill_id, short *skill_lv, int range, int cast_flag)
+int skill_check_pc_partner (struct map_session_data *sd, short skill_id, short* skill_lv, int range, int cast_flag)
{
- static int c=0;
- static int p_sd[2] = { 0, 0 };
- int i;
- bool is_chorus = (skill_get_inf2(skill_id)&INF2_CHORUS_SKILL);
-
- if (!battle_config.player_skill_partner_check || pc_has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL))
- return is_chorus ? MAX_PARTY : 99; //As if there were infinite partners.
-
- if (cast_flag) { //Execute the skill on the partners.
- struct map_session_data *tsd;
- switch (skill_id) {
- case PR_BENEDICTIO:
- for (i = 0; i < c; i++) {
- if ((tsd = map_id2sd(p_sd[i])) != NULL)
- status_charge(&tsd->bl, 0, 10);
- }
- return c;
- case AB_ADORAMUS:
- if (c > 0 && (tsd = map_id2sd(p_sd[0])) != NULL) {
- i = 2 * (*skill_lv);
- status_charge(&tsd->bl, 0, i);
- }
- break;
- case WM_GREAT_ECHO:
- for (i = 0; i < c; i++) {
- if ((tsd = map_id2sd(p_sd[i])) != NULL)
- status_zap(&tsd->bl,0,skill_get_sp(skill_id,*skill_lv)/c);
- }
- break;
- default: //Warning: Assuming Ensemble skills here (for speed)
- if (is_chorus)
- break;//Chorus skills are not to be parsed as ensambles
- if (c > 0 && sd->sc.data[SC_DANCING] && (tsd = map_id2sd(p_sd[0])) != NULL) {
- sd->sc.data[SC_DANCING]->val4 = tsd->bl.id;
- sc_start4(&tsd->bl,SC_DANCING,100,skill_id,sd->sc.data[SC_DANCING]->val2,*skill_lv,sd->bl.id,skill_get_time(skill_id,*skill_lv)+1000);
- clif_skill_nodamage(&tsd->bl, &sd->bl, skill_id, *skill_lv, 1);
- tsd->skillid_dance = skill_id;
- tsd->skilllv_dance = *skill_lv;
- }
- return c;
- }
- }
-
- //Else: new search for partners.
- c = 0;
- memset(p_sd, 0, sizeof(p_sd));
- if (is_chorus)
- i = party_foreachsamemap(skill_check_condition_char_sub,sd,AREA_SIZE,&sd->bl, &c, &p_sd, skill_id, *skill_lv);
- else
- i = map_foreachinrange(skill_check_condition_char_sub, &sd->bl, range, BL_PC, &sd->bl, &c, &p_sd, skill_id);
-
- if (skill_id != PR_BENEDICTIO && skill_id != AB_ADORAMUS && skill_id != WL_COMET) //Apply the average lv to encore skills.
- *skill_lv = (i+(*skill_lv))/(c+1); //I know c should be one, but this shows how it could be used for the average of n partners.
- return c;
+ static int c=0;
+ static int p_sd[2] = { 0, 0 };
+ int i;
+ bool is_chorus = ( skill_get_inf2(skill_id)&INF2_CHORUS_SKILL );
+
+ if (!battle_config.player_skill_partner_check || pc_has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL))
+ return is_chorus ? MAX_PARTY : 99; //As if there were infinite partners.
+
+ if (cast_flag) { //Execute the skill on the partners.
+ struct map_session_data* tsd;
+ switch (skill_id) {
+ case PR_BENEDICTIO:
+ for (i = 0; i < c; i++) {
+ if ((tsd = map_id2sd(p_sd[i])) != NULL)
+ status_charge(&tsd->bl, 0, 10);
+ }
+ return c;
+ case AB_ADORAMUS:
+ if( c > 0 && (tsd = map_id2sd(p_sd[0])) != NULL ) {
+ i = 2 * (*skill_lv);
+ status_charge(&tsd->bl, 0, i);
+ }
+ break;
+ case WM_GREAT_ECHO:
+ for( i = 0; i < c; i++ ) {
+ if( (tsd = map_id2sd(p_sd[i])) != NULL )
+ status_zap(&tsd->bl,0,skill_get_sp(skill_id,*skill_lv)/c);
+ }
+ break;
+ default: //Warning: Assuming Ensemble skills here (for speed)
+ if( is_chorus )
+ break;//Chorus skills are not to be parsed as ensambles
+ if (c > 0 && sd->sc.data[SC_DANCING] && (tsd = map_id2sd(p_sd[0])) != NULL) {
+ sd->sc.data[SC_DANCING]->val4 = tsd->bl.id;
+ sc_start4(&tsd->bl,SC_DANCING,100,skill_id,sd->sc.data[SC_DANCING]->val2,*skill_lv,sd->bl.id,skill_get_time(skill_id,*skill_lv)+1000);
+ clif_skill_nodamage(&tsd->bl, &sd->bl, skill_id, *skill_lv, 1);
+ tsd->skillid_dance = skill_id;
+ tsd->skilllv_dance = *skill_lv;
+ }
+ return c;
+ }
+ }
+
+ //Else: new search for partners.
+ c = 0;
+ memset (p_sd, 0, sizeof(p_sd));
+ if( is_chorus )
+ i = party_foreachsamemap(skill_check_condition_char_sub,sd,AREA_SIZE,&sd->bl, &c, &p_sd, skill_id, *skill_lv);
+ else
+ i = map_foreachinrange(skill_check_condition_char_sub, &sd->bl, range, BL_PC, &sd->bl, &c, &p_sd, skill_id);
+
+ if ( skill_id != PR_BENEDICTIO && skill_id != AB_ADORAMUS && skill_id != WL_COMET ) //Apply the average lv to encore skills.
+ *skill_lv = (i+(*skill_lv))/(c+1); //I know c should be one, but this shows how it could be used for the average of n partners.
+ return c;
}
/*==========================================
*
*------------------------------------------*/
-static int skill_check_condition_mob_master_sub(struct block_list *bl, va_list ap)
+static int skill_check_condition_mob_master_sub (struct block_list *bl, va_list ap)
{
- int *c,src_id,mob_class,skill;
- struct mob_data *md;
+ int *c,src_id,mob_class,skill;
+ struct mob_data *md;
- md=(struct mob_data *)bl;
- src_id=va_arg(ap,int);
- mob_class=va_arg(ap,int);
- skill=va_arg(ap,int);
- c=va_arg(ap,int *);
+ md=(struct mob_data*)bl;
+ src_id=va_arg(ap,int);
+ mob_class=va_arg(ap,int);
+ skill=va_arg(ap,int);
+ c=va_arg(ap,int *);
- if (md->master_id != src_id || md->special_state.ai != (unsigned)(skill == AM_SPHEREMINE?2:skill == KO_ZANZOU?4:3))
- return 0; //Non alchemist summoned mobs have nothing to do here.
+ if( md->master_id != src_id || md->special_state.ai != (unsigned)(skill == AM_SPHEREMINE?2:skill == KO_ZANZOU?4:3) )
+ return 0; //Non alchemist summoned mobs have nothing to do here.
- if (md->class_==mob_class)
- (*c)++;
+ if(md->class_==mob_class)
+ (*c)++;
- return 1;
+ return 1;
}
/*==========================================
* Determines if a given skill should be made to consume ammo
* when used by the player. [Skotlex]
*------------------------------------------*/
-int skill_isammotype(struct map_session_data *sd, int skill)
+int skill_isammotype (struct map_session_data *sd, int skill)
{
- return (
- battle_config.arrow_decrement==2 &&
- (sd->status.weapon == W_BOW || (sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE)) &&
- skill != HT_PHANTASMIC &&
- skill_get_type(skill) == BF_WEAPON &&
- !(skill_get_nk(skill)&NK_NO_DAMAGE) &&
- !skill_get_spiritball(skill,1) //Assume spirit spheres are used as ammo instead.
- );
+ return (
+ battle_config.arrow_decrement==2 &&
+ (sd->status.weapon == W_BOW || (sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE)) &&
+ skill != HT_PHANTASMIC &&
+ skill_get_type(skill) == BF_WEAPON &&
+ !(skill_get_nk(skill)&NK_NO_DAMAGE) &&
+ !skill_get_spiritball(skill,1) //Assume spirit spheres are used as ammo instead.
+ );
}
-int skill_check_condition_castbegin(struct map_session_data *sd, short skill, short lv)
-{
- struct status_data *status;
- struct status_change *sc;
- struct skill_condition require;
- int i;
-
- nullpo_ret(sd);
-
- if (lv <= 0 || sd->chatID) return 0;
-
- if (pc_has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL) && sd->skillitem != skill) {
- //GMs don't override the skillItem check, otherwise they can use items without them being consumed! [Skotlex]
- sd->state.arrow_atk = skill_get_ammotype(skill)?1:0; //Need to do arrow state check.
- sd->spiritball_old = sd->spiritball; //Need to do Spiritball check.
- return 1;
- }
-
- switch (sd->menuskill_id) {
- case AM_PHARMACY:
- switch (skill) {
- case AM_PHARMACY:
- case AC_MAKINGARROW:
- case BS_REPAIRWEAPON:
- case AM_TWILIGHT1:
- case AM_TWILIGHT2:
- case AM_TWILIGHT3:
- return 0;
- }
- break;
- case GN_MIX_COOKING:
- case GN_MAKEBOMB:
- case GN_S_PHARMACY:
- case GN_CHANGEMATERIAL:
- if (sd->menuskill_id != skill)
- return 0;
- break;
- }
- status = &sd->battle_status;
- sc = &sd->sc;
- if (!sc->count)
- sc = NULL;
-
- if (sd->skillitem == skill) {
- if (sd->state.abra_flag) // Hocus-Pocus was used. [Inkfish]
- sd->state.abra_flag = 0;
- else {
- // When a target was selected, consume items that were skipped in pc_use_item [Skotlex]
- if ((i = sd->itemindex) == -1 ||
- sd->status.inventory[i].nameid != sd->itemid ||
- sd->inventory_data[i] == NULL ||
- !sd->inventory_data[i]->flag.delay_consume ||
- sd->status.inventory[i].amount < 1
- ) {
- //Something went wrong, item exploit?
- sd->itemid = sd->itemindex = -1;
- return 0;
- }
- //Consume
- sd->itemid = sd->itemindex = -1;
- if (skill == WZ_EARTHSPIKE && sc && sc->data[SC_EARTHSCROLL] && rnd()%100 > sc->data[SC_EARTHSCROLL]->val2) // [marquis007]
- ; //Do not consume item.
- else if (sd->status.inventory[i].expire_time == 0)
- pc_delitem(sd,i,1,0,0,LOG_TYPE_CONSUME); // Rental usable items are not consumed until expiration
- }
- return 1;
- }
-
- if (pc_is90overweight(sd)) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_WEIGHTOVER,0);
- return 0;
- }
-
- if (sc && (sc->data[SC__SHADOWFORM] || sc->data[SC__IGNORANCE]))
- return 0;
-
- switch (skill) { // Turn off check.
- case BS_MAXIMIZE:
- case NV_TRICKDEAD:
- case TF_HIDING:
- case AS_CLOAKING:
- case CR_AUTOGUARD:
- case ML_AUTOGUARD:
- case CR_DEFENDER:
- case ML_DEFENDER:
- case ST_CHASEWALK:
- case PA_GOSPEL:
- case CR_SHRINK:
- case TK_RUN:
- case GS_GATLINGFEVER:
- case TK_READYCOUNTER:
- case TK_READYDOWN:
- case TK_READYSTORM:
- case TK_READYTURN:
- case SG_FUSION:
- case RA_WUGDASH:
- case KO_YAMIKUMO:
- if (sc && sc->data[status_skill2sc(skill)])
- return 1;
- }
-
- // Check the skills that can be used while mounted on a warg
- if (pc_isridingwug(sd)) {
- switch (skill) {
- 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 HT_SPRINGTRAP:
- case RA_DETONATOR:
- case RA_CLUSTERBOMB:
- case HT_TALKIEBOX:
- case RA_FIRINGTRAP:
- case RA_ICEBOUNDTRAP:
- case RA_WUGDASH:
- case RA_WUGRIDER:
- case RA_WUGSTRIKE:
- break;
- default: // in official there is no message.
- return 0;
- }
-
- }
- if (pc_ismadogear(sd)) {
- switch (skill) { //None Mado skills are unusable when Mado is equipped. [Jobbie]
- case BS_REPAIRWEAPON:
- case WS_MELTDOWN:
- case BS_HAMMERFALL:
- case WS_CARTBOOST:
- case BS_ADRENALINE:
- case WS_WEAPONREFINE:
- case BS_WEAPONPERFECT:
- case WS_CARTTERMINATION:
- case BS_OVERTHRUST:
- case WS_OVERTHRUSTMAX:
- case BS_MAXIMIZE:
- case NC_AXEBOOMERANG:
- case BS_ADRENALINE2:
- case NC_POWERSWING:
- case BS_UNFAIRLYTRICK:
- case NC_AXETORNADO:
- case BS_GREED:
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- default: //Only Mechanic exlcusive skill can be used.
- break;
- }
- }
- if (lv < 1 || lv > MAX_SKILL_LEVEL)
- return 0;
-
- require = skill_get_requirement(sd,skill,lv);
-
- //Can only update state when weapon/arrow info is checked.
- sd->state.arrow_atk = require.ammo?1:0;
-
- // perform skill-specific checks (and actions)
- switch (skill) {
- case SO_SPELLFIST:
- if (sd->skillid_old != MG_FIREBOLT && sd->skillid_old != MG_COLDBOLT && sd->skillid_old != MG_LIGHTNINGBOLT) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- case SA_CASTCANCEL:
- if (sd->ud.skilltimer == INVALID_TIMER) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- case AL_WARP:
- if (!battle_config.duel_allow_teleport && sd->duel_group) { // duel restriction [LuzZza]
- char output[128];
- sprintf(output, msg_txt(365), skill_get_name(AL_WARP));
- clif_displaymessage(sd->fd, output); //"Duel: Can't use %s in duel."
- return 0;
- }
- break;
- case MO_CALLSPIRITS:
- if (sc && sc->data[SC_RAISINGDRAGON])
- lv += sc->data[SC_RAISINGDRAGON]->val1;
- if (sd->spiritball >= lv) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- case MO_FINGEROFFENSIVE:
- case GS_FLING:
- case SR_RAMPAGEBLASTER:
- case SR_RIDEINLIGHTNING:
- if (sd->spiritball > 0 && sd->spiritball < require.spiritball)
- sd->spiritball_old = require.spiritball = sd->spiritball;
- else
- sd->spiritball_old = require.spiritball;
- break;
- case MO_CHAINCOMBO:
- if (!sc)
- return 0;
- if (sc->data[SC_BLADESTOP])
- break;
- if (sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == MO_TRIPLEATTACK)
- break;
- return 0;
- case MO_COMBOFINISH:
- if (!(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == MO_CHAINCOMBO))
- return 0;
- break;
- case CH_TIGERFIST:
- if (!(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == MO_COMBOFINISH))
- return 0;
- break;
- case CH_CHAINCRUSH:
- if (!(sc && sc->data[SC_COMBO]))
- return 0;
- if (sc->data[SC_COMBO]->val1 != MO_COMBOFINISH && sc->data[SC_COMBO]->val1 != CH_TIGERFIST)
- return 0;
- break;
- case MO_EXTREMITYFIST:
- // if(sc && sc->data[SC_EXTREMITYFIST]) //To disable Asura during the 5 min skill block uncomment this...
- // return 0;
- if (sc && (sc->data[SC_BLADESTOP] || sc->data[SC_CURSEDCIRCLE_ATKER]))
- break;
- if (sc && sc->data[SC_COMBO]) {
- switch (sc->data[SC_COMBO]->val1) {
- case MO_COMBOFINISH:
- case CH_TIGERFIST:
- case CH_CHAINCRUSH:
- break;
- default:
- return 0;
- }
- } else if (!unit_can_move(&sd->bl)) {
- //Placed here as ST_MOVE_ENABLE should not apply if rooted or on a combo. [Skotlex]
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
+int skill_check_condition_castbegin(struct map_session_data* sd, short skill, short lv) {
+ struct status_data *status;
+ struct status_change *sc;
+ struct skill_condition require;
+ int i;
- case TK_MISSION:
- if ((sd->class_&MAPID_UPPERMASK) != MAPID_TAEKWON) {
- // Cannot be used by Non-Taekwon classes
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
+ nullpo_ret(sd);
- case TK_READYCOUNTER:
- case TK_READYDOWN:
- case TK_READYSTORM:
- case TK_READYTURN:
- case TK_JUMPKICK:
- if ((sd->class_&MAPID_UPPERMASK) == MAPID_SOUL_LINKER) {
- // Soul Linkers cannot use this skill
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
+ if (lv <= 0 || sd->chatID) return 0;
- case TK_TURNKICK:
- case TK_STORMKICK:
- case TK_DOWNKICK:
- case TK_COUNTER:
- if ((sd->class_&MAPID_UPPERMASK) == MAPID_SOUL_LINKER)
- return 0; //Anti-Soul Linker check in case you job-changed with Stances active.
- if (!(sc && sc->data[SC_COMBO]) || sc->data[SC_COMBO]->val1 == TK_JUMPKICK)
- return 0; //Combo needs to be ready
-
- if (sc->data[SC_COMBO]->val3) { //Kick chain
- //Do not repeat a kick.
- if (sc->data[SC_COMBO]->val3 != skill)
- break;
- status_change_end(&sd->bl, SC_COMBO, INVALID_TIMER);
- return 0;
- }
- if (sc->data[SC_COMBO]->val1 != skill && !(sd && sd->status.base_level >= 90 && pc_famerank(sd->status.char_id, MAPID_TAEKWON))) { //Cancel combo wait.
- unit_cancel_combo(&sd->bl);
- return 0;
- }
- break; //Combo ready.
- case BD_ADAPTATION: {
- int time;
- if (!(sc && sc->data[SC_DANCING])) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- time = 1000*(sc->data[SC_DANCING]->val3>>16);
- if (skill_get_time(
- (sc->data[SC_DANCING]->val1&0xFFFF), //Dance Skill ID
- (sc->data[SC_DANCING]->val1>>16)) //Dance Skill LV
- - time < skill_get_time2(skill,lv)) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- }
- break;
+ if( pc_has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL) && sd->skillitem != skill )
+ { //GMs don't override the skillItem check, otherwise they can use items without them being consumed! [Skotlex]
+ sd->state.arrow_atk = skill_get_ammotype(skill)?1:0; //Need to do arrow state check.
+ sd->spiritball_old = sd->spiritball; //Need to do Spiritball check.
+ return 1;
+ }
- case PR_BENEDICTIO:
- if (skill_check_pc_partner(sd, skill, &lv, 1, 0) < 2) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
+ switch( sd->menuskill_id ) {
+ case AM_PHARMACY:
+ switch( skill ) {
+ case AM_PHARMACY:
+ case AC_MAKINGARROW:
+ case BS_REPAIRWEAPON:
+ case AM_TWILIGHT1:
+ case AM_TWILIGHT2:
+ case AM_TWILIGHT3:
+ return 0;
+ }
+ break;
+ case GN_MIX_COOKING:
+ case GN_MAKEBOMB:
+ case GN_S_PHARMACY:
+ case GN_CHANGEMATERIAL:
+ if( sd->menuskill_id != skill )
+ return 0;
+ break;
+ }
+ status = &sd->battle_status;
+ sc = &sd->sc;
+ if( !sc->count )
+ sc = NULL;
+
+ if( sd->skillitem == skill )
+ {
+ if( sd->state.abra_flag ) // Hocus-Pocus was used. [Inkfish]
+ sd->state.abra_flag = 0;
+ else
+ { // When a target was selected, consume items that were skipped in pc_use_item [Skotlex]
+ if( (i = sd->itemindex) == -1 ||
+ sd->status.inventory[i].nameid != sd->itemid ||
+ sd->inventory_data[i] == NULL ||
+ !sd->inventory_data[i]->flag.delay_consume ||
+ sd->status.inventory[i].amount < 1
+ )
+ { //Something went wrong, item exploit?
+ sd->itemid = sd->itemindex = -1;
+ return 0;
+ }
+ //Consume
+ sd->itemid = sd->itemindex = -1;
+ if( skill == WZ_EARTHSPIKE && sc && sc->data[SC_EARTHSCROLL] && rnd()%100 > sc->data[SC_EARTHSCROLL]->val2 ) // [marquis007]
+ ; //Do not consume item.
+ else if( sd->status.inventory[i].expire_time == 0 )
+ pc_delitem(sd,i,1,0,0,LOG_TYPE_CONSUME); // Rental usable items are not consumed until expiration
+ }
+ return 1;
+ }
- case SL_SMA:
- if (!(sc && sc->data[SC_SMA]))
- return 0;
- break;
+ if( pc_is90overweight(sd) )
+ {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_WEIGHTOVER,0);
+ return 0;
+ }
- case HT_POWER:
- if (!(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == skill))
- return 0;
- break;
+ if( sc && ( sc->data[SC__SHADOWFORM] || sc->data[SC__IGNORANCE] ) )
+ return 0;
- case CG_HERMODE:
- if (!npc_check_areanpc(1,sd->bl.m,sd->bl.x,sd->bl.y,skill_get_splash(skill, lv))) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- case CG_MOONLIT: { //Check there's no wall in the range+1 area around the caster. [Skotlex]
- int i,x,y,range = skill_get_splash(skill, lv)+1;
- int size = range*2+1;
- for (i=0; i<size*size; i++) {
- x = sd->bl.x+(i%size-range);
- y = sd->bl.y+(i/size-range);
- if (map_getcell(sd->bl.m,x,y,CELL_CHKWALL)) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- }
- }
- break;
- case PR_REDEMPTIO: {
- int exp;
- if (((exp = pc_nextbaseexp(sd)) > 0 && get_percentage(sd->status.base_exp, exp) < 1) ||
- ((exp = pc_nextjobexp(sd)) > 0 && get_percentage(sd->status.job_exp, exp) < 1)) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0); //Not enough exp.
- return 0;
- }
- break;
- }
- case AM_TWILIGHT2:
- case AM_TWILIGHT3:
- if (!party_skill_check(sd, sd->status.party_id, skill, lv)) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- case SG_SUN_WARM:
- case SG_MOON_WARM:
- case SG_STAR_WARM:
- if (sc && sc->data[SC_MIRACLE])
- break;
- i = skill-SG_SUN_WARM;
- if (sd->bl.m == sd->feel_map[i].m)
- break;
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- break;
- case SG_SUN_COMFORT:
- case SG_MOON_COMFORT:
- case SG_STAR_COMFORT:
- if (sc && sc->data[SC_MIRACLE])
- break;
- i = skill-SG_SUN_COMFORT;
- if (sd->bl.m == sd->feel_map[i].m &&
- (battle_config.allow_skill_without_day || sg_info[i].day_func()))
- break;
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- case SG_FUSION:
- if (sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_STAR)
- break;
- //Auron insists we should implement SP consumption when you are not Soul Linked. [Skotlex]
- //Only invoke on skill begin cast (instant cast skill). [Kevin]
- if (require.sp > 0) {
- if (status->sp < (unsigned int)require.sp)
- clif_skill_fail(sd,skill,USESKILL_FAIL_SP_INSUFFICIENT,0);
- else
- status_zap(&sd->bl, 0, require.sp);
- }
- return 0;
- case GD_BATTLEORDER:
- case GD_REGENERATION:
- case GD_RESTORE:
- if (!map_flag_gvg2(sd->bl.m)) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- case GD_EMERGENCYCALL:
- // other checks were already done in skillnotok()
- if (!sd->status.guild_id || !sd->state.gmaster_flag)
- return 0;
- break;
+ switch( skill ) { // Turn off check.
+ case BS_MAXIMIZE: case NV_TRICKDEAD: case TF_HIDING: case AS_CLOAKING: case CR_AUTOGUARD:
+ case ML_AUTOGUARD: case CR_DEFENDER: case ML_DEFENDER: case ST_CHASEWALK: case PA_GOSPEL:
+ case CR_SHRINK: case TK_RUN: case GS_GATLINGFEVER: case TK_READYCOUNTER: case TK_READYDOWN:
+ case TK_READYSTORM: case TK_READYTURN: case SG_FUSION: case RA_WUGDASH: case KO_YAMIKUMO:
+ if( sc && sc->data[status_skill2sc(skill)] )
+ return 1;
+ }
- case GS_GLITTERING:
- if (sd->spiritball >= 10) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
+ // Check the skills that can be used while mounted on a warg
+ if( pc_isridingwug(sd) ) {
+ switch( skill ) {
+ 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 HT_SPRINGTRAP: case RA_DETONATOR: case RA_CLUSTERBOMB:
+ case HT_TALKIEBOX: case RA_FIRINGTRAP: case RA_ICEBOUNDTRAP:
+ case RA_WUGDASH: case RA_WUGRIDER: case RA_WUGSTRIKE:
+ break;
+ default: // in official there is no message.
+ return 0;
+ }
- case NJ_ISSEN:
- if (status->hp < 2) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- case NJ_BUNSINJYUTSU:
- if (!(sc && sc->data[SC_NEN])) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
+ }
+ if( pc_ismadogear(sd) ) {
+ switch( skill ) { //None Mado skills are unusable when Mado is equipped. [Jobbie]
+ case BS_REPAIRWEAPON: case WS_MELTDOWN:
+ case BS_HAMMERFALL: case WS_CARTBOOST:
+ case BS_ADRENALINE: case WS_WEAPONREFINE:
+ case BS_WEAPONPERFECT: case WS_CARTTERMINATION:
+ case BS_OVERTHRUST: case WS_OVERTHRUSTMAX:
+ case BS_MAXIMIZE: case NC_AXEBOOMERANG:
+ case BS_ADRENALINE2: case NC_POWERSWING:
+ case BS_UNFAIRLYTRICK: case NC_AXETORNADO:
+ case BS_GREED:
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ default: //Only Mechanic exlcusive skill can be used.
+ break;
+ }
+ }
+ if( lv < 1 || lv > MAX_SKILL_LEVEL )
+ return 0;
- case NJ_ZENYNAGE:
- case KO_MUCHANAGE:
- if (sd->status.zeny < require.zeny) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_MONEY,0);
- return 0;
- }
- break;
- case PF_HPCONVERSION:
- if (status->sp == status->max_sp)
- return 0; //Unusable when at full SP.
- break;
- case AM_CALLHOMUN: //Can't summon if a hom is already out
- if (sd->status.hom_id && sd->hd && !sd->hd->homunculus.vaporize) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- case AM_REST: //Can't vapo homun if you don't have an active homunc or it's hp is < 80%
- if (!merc_is_hom_active(sd->hd) || sd->hd->battle_status.hp < (sd->hd->battle_status.max_hp*80/100)) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- /**
- * Arch Bishop
- **/
- case AB_ANCILLA: {
- int count = 0;
- for (i = 0; i < MAX_INVENTORY; i ++)
- if (sd->status.inventory[i].nameid == ITEMID_ANCILLA)
- count += sd->status.inventory[i].amount;
- if (count >= 3) {
- clif_skill_fail(sd, skill, USESKILL_FAIL_ANCILLA_NUMOVER, 0);
- return 0;
- }
- }
- break;
- /**
- * Keeping as a note:
- * Bug Report #17 provides a link to a sep-2011 changelog that shows this requirement was removed
- **/
- //case AB_LAUDAAGNUS:
- //case AB_LAUDARAMUS:
- // if( !sd->status.party_id ) {
- // clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- // return 0;
- // }
- // break;
-
- case AB_ADORAMUS:
- /**
- * Warlock
- **/
- case WL_COMET:
- if (skill_check_pc_partner(sd,skill,&lv,1,0) <= 0 && ((i = pc_search_inventory(sd,require.itemid[0])) < 0 || sd->status.inventory[i].amount < require.amount[0])) {
- //clif_skill_fail(sd,skill,USESKILL_FAIL_NEED_ITEM,require.amount[0],require.itemid[0]);
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- case WL_SUMMONFB:
- case WL_SUMMONBL:
- case WL_SUMMONWB:
- case WL_SUMMONSTONE:
- if (sc) {
- ARR_FIND(SC_SPHERE_1,SC_SPHERE_5+1,i,!sc->data[i]);
- if (i == SC_SPHERE_5+1) {
- // No more free slots
- clif_skill_fail(sd,skill,USESKILL_FAIL_SUMMON,0);
- return 0;
- }
- }
- break;
- /**
- * Guilotine Cross
- **/
- case GC_HALLUCINATIONWALK:
- if (sc && (sc->data[SC_HALLUCINATIONWALK] || sc->data[SC_HALLUCINATIONWALK_POSTDELAY])) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- case GC_COUNTERSLASH:
- case GC_WEAPONCRUSH:
- if (!(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == GC_WEAPONBLOCKING)) {
- clif_skill_fail(sd, skill, USESKILL_FAIL_GC_WEAPONBLOCKING, 0);
- return 0;
- }
- break;
- /**
- * Ranger
- **/
- case RA_WUGMASTERY:
- if (pc_isfalcon(sd) || pc_isridingwug(sd) || sd->sc.data[SC__GROOMY]) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- case RA_WUGSTRIKE:
- if (!pc_iswug(sd) && !pc_isridingwug(sd)) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- case RA_WUGRIDER:
- if (pc_isfalcon(sd) || (!pc_isridingwug(sd) && !pc_iswug(sd))) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- case RA_WUGDASH:
- if (!pc_isridingwug(sd)) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- /**
- * Royal Guard
- **/
- case LG_BANDING:
- if (sc && sc->data[SC_INSPIRATION]) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- case LG_PRESTIGE:
- if (sc && (sc->data[SC_BANDING] || sc->data[SC_INSPIRATION])) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- case LG_RAGEBURST:
- if (sd->spiritball == 0) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_SKILLINTERVAL,0);
- return 0;
- }
- sd->spiritball_old = require.spiritball = sd->spiritball;
- break;
- case LG_RAYOFGENESIS:
- if (sc && sc->data[SC_INSPIRATION])
- return 1; // Don't check for partner.
- if (!(sc && sc->data[SC_BANDING])) {
- clif_skill_fail(sd,skill,USESKILL_FAIL,0);
- return 0;
- } else if (skill_check_pc_partner(sd,skill,&lv,skill_get_range(skill,lv),0) < 1)
- return 0; // Just fails, no msg here.
- break;
- case LG_HESPERUSLIT:
- if (!sc || !sc->data[SC_BANDING]) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- case SR_FALLENEMPIRE:
- if (!(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_DRAGONCOMBO))
- return 0;
- break;
+ require = skill_get_requirement(sd,skill,lv);
- case SR_CRESCENTELBOW:
- if (sc && sc->data[SC_CRESCENTELBOW]) {
- clif_skill_fail(sd, skill, USESKILL_FAIL_DUPLICATE, 0);
- return 0;
- }
- break;
- case SR_CURSEDCIRCLE:
- if (map_flag_gvg(sd->bl.m)) {
- if (map_foreachinrange(mob_count_sub, &sd->bl, skill_get_splash(skill, lv), BL_MOB,
- MOBID_EMPERIUM, MOBID_GUARIDAN_STONE1, MOBID_GUARIDAN_STONE2)) {
- char output[128];
- sprintf(output, "You're too close to a stone or emperium to do this skill");
- clif_colormes(sd, COLOR_RED, output);
- return 0;
- }
- }
- if (sd->spiritball > 0)
- sd->spiritball_old = require.spiritball = sd->spiritball;
- else {
- clif_skill_fail(sd,skill,0,0);
- return 0;
- }
- break;
- case SR_GATEOFHELL:
- if (sd->spiritball > 0)
- sd->spiritball_old = require.spiritball;
- break;
- case SC_MANHOLE:
- case SC_DIMENSIONDOOR:
- if (sc && sc->data[SC_MAGNETICFIELD]) {
- clif_skill_fail(sd,skill,0,0);
- return 0;
- }
- break;
- case WM_GREAT_ECHO: {
- int count;
- count = skill_check_pc_partner(sd, skill, &lv, skill_get_splash(skill,lv), 0);
- if (count < 1) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_NEED_HELPER,0);
- return 0;
- } else
- require.sp -= require.sp * 20 * count / 100; // -20% each W/M in the party.
- }
- break;
- case SO_FIREWALK:
- case SO_ELECTRICWALK: // Can't be casted until you've walked all cells.
- if (sc && sc->data[SC_PROPERTYWALK] &&
- sc->data[SC_PROPERTYWALK]->val3 < skill_get_maxcount(sc->data[SC_PROPERTYWALK]->val1,sc->data[SC_PROPERTYWALK]->val2)) {
- clif_skill_fail(sd,skill,0x0,0);
- return 0;
- }
- break;
- case SO_EL_CONTROL:
- if (!sd->status.ele_id || !sd->ed) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- case RETURN_TO_ELDICASTES:
- if (pc_ismadogear(sd)) { //Cannot be used if Mado is equipped.
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- case LG_REFLECTDAMAGE:
- case CR_REFLECTSHIELD:
- if (sc && sc->data[SC_KYOMU] && rand()%100 < 30) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- case KO_KAHU_ENTEN:
- case KO_HYOUHU_HUBUKI:
- case KO_KAZEHU_SEIRAN:
- case KO_DOHU_KOUKAI: {
- int ttype = skill_get_ele(skill, lv);
- ARR_FIND(1, 5, i, sd->talisman[i] > 0 && i != ttype);
- if ((i < 5 && i != ttype) || sd->talisman[ttype] >= 10) {
- clif_skill_fail(sd, skill, USESKILL_FAIL_LEVEL, 0);
- return 0;
- }
- }
- break;
- case KO_KAIHOU:
- case KO_ZENKAI:
- ARR_FIND(1, 6, i, sd->talisman[i] > 0);
- if (i > 4) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- }
+ //Can only update state when weapon/arrow info is checked.
+ sd->state.arrow_atk = require.ammo?1:0;
- switch (require.state) {
- case ST_HIDING:
- if (!(sc && sc->option&OPTION_HIDE)) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- case ST_CLOAKING:
- if (!pc_iscloaking(sd)) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- case ST_HIDDEN:
- if (!pc_ishiding(sd)) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- case ST_RIDING:
- if (!pc_isriding(sd)) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- case ST_FALCON:
- if (!pc_isfalcon(sd)) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- case ST_CARTBOOST:
- if (!(sc && sc->data[SC_CARTBOOST])) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- case ST_CART:
- if (!pc_iscarton(sd)) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- case ST_SHIELD:
- if (sd->status.shield <= 0) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- case ST_SIGHT:
- if (!(sc && sc->data[SC_SIGHT])) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- case ST_EXPLOSIONSPIRITS:
- if (!(sc && sc->data[SC_EXPLOSIONSPIRITS])) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- case ST_RECOV_WEIGHT_RATE:
- if (battle_config.natural_heal_weight_rate <= 100 && sd->weight*100/sd->max_weight >= (unsigned int)battle_config.natural_heal_weight_rate) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- case ST_MOVE_ENABLE:
- if (sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == skill)
- sd->ud.canmove_tick = gettick(); //When using a combo, cancel the can't move delay to enable the skill. [Skotlex]
+ // perform skill-specific checks (and actions)
+ switch( skill ) {
+ case SO_SPELLFIST:
+ if(sd->skillid_old != MG_FIREBOLT && sd->skillid_old != MG_COLDBOLT && sd->skillid_old != MG_LIGHTNINGBOLT){
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ case SA_CASTCANCEL:
+ if(sd->ud.skilltimer == INVALID_TIMER) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ case AL_WARP:
+ if(!battle_config.duel_allow_teleport && sd->duel_group) { // duel restriction [LuzZza]
+ char output[128]; sprintf(output, msg_txt(365), skill_get_name(AL_WARP));
+ clif_displaymessage(sd->fd, output); //"Duel: Can't use %s in duel."
+ return 0;
+ }
+ break;
+ case MO_CALLSPIRITS:
+ if(sc && sc->data[SC_RAISINGDRAGON])
+ lv += sc->data[SC_RAISINGDRAGON]->val1;
+ if(sd->spiritball >= lv) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ case MO_FINGEROFFENSIVE:
+ case GS_FLING:
+ case SR_RAMPAGEBLASTER:
+ case SR_RIDEINLIGHTNING:
+ if( sd->spiritball > 0 && sd->spiritball < require.spiritball )
+ sd->spiritball_old = require.spiritball = sd->spiritball;
+ else
+ sd->spiritball_old = require.spiritball;
+ break;
+ case MO_CHAINCOMBO:
+ if(!sc)
+ return 0;
+ if(sc->data[SC_BLADESTOP])
+ break;
+ if(sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == MO_TRIPLEATTACK)
+ break;
+ return 0;
+ case MO_COMBOFINISH:
+ if(!(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == MO_CHAINCOMBO))
+ return 0;
+ break;
+ case CH_TIGERFIST:
+ if(!(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == MO_COMBOFINISH))
+ return 0;
+ break;
+ case CH_CHAINCRUSH:
+ if(!(sc && sc->data[SC_COMBO]))
+ return 0;
+ if(sc->data[SC_COMBO]->val1 != MO_COMBOFINISH && sc->data[SC_COMBO]->val1 != CH_TIGERFIST)
+ return 0;
+ break;
+ case MO_EXTREMITYFIST:
+ // if(sc && sc->data[SC_EXTREMITYFIST]) //To disable Asura during the 5 min skill block uncomment this...
+ // return 0;
+ if( sc && (sc->data[SC_BLADESTOP] || sc->data[SC_CURSEDCIRCLE_ATKER]) )
+ break;
+ if( sc && sc->data[SC_COMBO] )
+ {
+ switch(sc->data[SC_COMBO]->val1) {
+ case MO_COMBOFINISH:
+ case CH_TIGERFIST:
+ case CH_CHAINCRUSH:
+ break;
+ default:
+ return 0;
+ }
+ }
+ else if( !unit_can_move(&sd->bl) )
+ { //Placed here as ST_MOVE_ENABLE should not apply if rooted or on a combo. [Skotlex]
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
- if (!unit_can_move(&sd->bl)) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- case ST_WATER:
- if (sc && (sc->data[SC_DELUGE] || sc->data[SC_SUITON]))
- break;
- if (map_getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKWATER))
- break;
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- /**
- * Rune Knight
- **/
- case ST_RIDINGDRAGON:
- if (!pc_isridingdragon(sd)) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- /**
- * Wug
- **/
- case ST_WUG:
- if (!pc_iswug(sd)) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- /**
- * Riding Wug
- **/
- case ST_RIDINGWUG:
- if (!pc_isridingwug(sd)) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- /**
- * Mechanic
- **/
- case ST_MADO:
- if (!pc_ismadogear(sd)) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- /**
- * Sorcerer
- **/
- case ST_ELEMENTALSPIRIT:
- if (!sd->ed) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_EL_SUMMON,0);
- return 0;
- }
- break;
+ case TK_MISSION:
+ if( (sd->class_&MAPID_UPPERMASK) != MAPID_TAEKWON )
+ {// Cannot be used by Non-Taekwon classes
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+
+ case TK_READYCOUNTER:
+ case TK_READYDOWN:
+ case TK_READYSTORM:
+ case TK_READYTURN:
+ case TK_JUMPKICK:
+ if( (sd->class_&MAPID_UPPERMASK) == MAPID_SOUL_LINKER )
+ {// Soul Linkers cannot use this skill
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+
+ case TK_TURNKICK:
+ case TK_STORMKICK:
+ case TK_DOWNKICK:
+ case TK_COUNTER:
+ if ((sd->class_&MAPID_UPPERMASK) == MAPID_SOUL_LINKER)
+ return 0; //Anti-Soul Linker check in case you job-changed with Stances active.
+ if(!(sc && sc->data[SC_COMBO]) || sc->data[SC_COMBO]->val1 == TK_JUMPKICK)
+ return 0; //Combo needs to be ready
+
+ if (sc->data[SC_COMBO]->val3) { //Kick chain
+ //Do not repeat a kick.
+ if (sc->data[SC_COMBO]->val3 != skill)
+ break;
+ status_change_end(&sd->bl, SC_COMBO, INVALID_TIMER);
+ return 0;
+ }
+ if(sc->data[SC_COMBO]->val1 != skill && !( sd && sd->status.base_level >= 90 && pc_famerank(sd->status.char_id, MAPID_TAEKWON) )) { //Cancel combo wait.
+ unit_cancel_combo(&sd->bl);
+ return 0;
+ }
+ break; //Combo ready.
+ case BD_ADAPTATION:
+ {
+ int time;
+ if(!(sc && sc->data[SC_DANCING]))
+ {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ time = 1000*(sc->data[SC_DANCING]->val3>>16);
+ if (skill_get_time(
+ (sc->data[SC_DANCING]->val1&0xFFFF), //Dance Skill ID
+ (sc->data[SC_DANCING]->val1>>16)) //Dance Skill LV
+ - time < skill_get_time2(skill,lv))
+ {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ }
+ break;
+
+ case PR_BENEDICTIO:
+ if (skill_check_pc_partner(sd, skill, &lv, 1, 0) < 2)
+ {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+
+ case SL_SMA:
+ if(!(sc && sc->data[SC_SMA]))
+ return 0;
+ break;
+
+ case HT_POWER:
+ if(!(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == skill))
+ return 0;
+ break;
+
+ case CG_HERMODE:
+ if(!npc_check_areanpc(1,sd->bl.m,sd->bl.x,sd->bl.y,skill_get_splash(skill, lv)))
+ {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ case CG_MOONLIT: //Check there's no wall in the range+1 area around the caster. [Skotlex]
+ {
+ int i,x,y,range = skill_get_splash(skill, lv)+1;
+ int size = range*2+1;
+ for (i=0;i<size*size;i++) {
+ x = sd->bl.x+(i%size-range);
+ y = sd->bl.y+(i/size-range);
+ if (map_getcell(sd->bl.m,x,y,CELL_CHKWALL)) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ }
+ }
+ break;
+ case PR_REDEMPTIO:
+ {
+ int exp;
+ if( ((exp = pc_nextbaseexp(sd)) > 0 && get_percentage(sd->status.base_exp, exp) < 1) ||
+ ((exp = pc_nextjobexp(sd)) > 0 && get_percentage(sd->status.job_exp, exp) < 1)) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0); //Not enough exp.
+ return 0;
+ }
+ break;
+ }
+ case AM_TWILIGHT2:
+ case AM_TWILIGHT3:
+ if (!party_skill_check(sd, sd->status.party_id, skill, lv))
+ {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ case SG_SUN_WARM:
+ case SG_MOON_WARM:
+ case SG_STAR_WARM:
+ if (sc && sc->data[SC_MIRACLE])
+ break;
+ i = skill-SG_SUN_WARM;
+ if (sd->bl.m == sd->feel_map[i].m)
+ break;
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ break;
+ case SG_SUN_COMFORT:
+ case SG_MOON_COMFORT:
+ case SG_STAR_COMFORT:
+ if (sc && sc->data[SC_MIRACLE])
+ break;
+ i = skill-SG_SUN_COMFORT;
+ if (sd->bl.m == sd->feel_map[i].m &&
+ (battle_config.allow_skill_without_day || sg_info[i].day_func()))
+ break;
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ case SG_FUSION:
+ if (sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_STAR)
+ break;
+ //Auron insists we should implement SP consumption when you are not Soul Linked. [Skotlex]
+ //Only invoke on skill begin cast (instant cast skill). [Kevin]
+ if( require.sp > 0 )
+ {
+ if (status->sp < (unsigned int)require.sp)
+ clif_skill_fail(sd,skill,USESKILL_FAIL_SP_INSUFFICIENT,0);
+ else
+ status_zap(&sd->bl, 0, require.sp);
+ }
+ return 0;
+ case GD_BATTLEORDER:
+ case GD_REGENERATION:
+ case GD_RESTORE:
+ if (!map_flag_gvg2(sd->bl.m)) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ case GD_EMERGENCYCALL:
+ // other checks were already done in skillnotok()
+ if (!sd->status.guild_id || !sd->state.gmaster_flag)
+ return 0;
+ break;
+
+ case GS_GLITTERING:
+ if(sd->spiritball >= 10) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+
+ case NJ_ISSEN:
+ if (status->hp < 2) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ case NJ_BUNSINJYUTSU:
+ if (!(sc && sc->data[SC_NEN])) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+
+ case NJ_ZENYNAGE:
+ case KO_MUCHANAGE:
+ if(sd->status.zeny < require.zeny) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_MONEY,0);
+ return 0;
+ }
+ break;
+ case PF_HPCONVERSION:
+ if (status->sp == status->max_sp)
+ return 0; //Unusable when at full SP.
+ break;
+ case AM_CALLHOMUN: //Can't summon if a hom is already out
+ if (sd->status.hom_id && sd->hd && !sd->hd->homunculus.vaporize) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ case AM_REST: //Can't vapo homun if you don't have an active homunc or it's hp is < 80%
+ if (!merc_is_hom_active(sd->hd) || sd->hd->battle_status.hp < (sd->hd->battle_status.max_hp*80/100))
+ {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ /**
+ * Arch Bishop
+ **/
+ case AB_ANCILLA:
+ {
+ int count = 0;
+ for( i = 0; i < MAX_INVENTORY; i ++ )
+ if( sd->status.inventory[i].nameid == ITEMID_ANCILLA )
+ count += sd->status.inventory[i].amount;
+ if( count >= 3 ) {
+ clif_skill_fail(sd, skill, USESKILL_FAIL_ANCILLA_NUMOVER, 0);
+ return 0;
+ }
+ }
+ break;
+ /**
+ * Keeping as a note:
+ * Bug Report #17 provides a link to a sep-2011 changelog that shows this requirement was removed
+ **/
+ //case AB_LAUDAAGNUS:
+ //case AB_LAUDARAMUS:
+ // if( !sd->status.party_id ) {
+ // clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ // return 0;
+ // }
+ // break;
+
+ case AB_ADORAMUS:
+ /**
+ * Warlock
+ **/
+ case WL_COMET:
+ if( skill_check_pc_partner(sd,skill,&lv,1,0) <= 0 && ((i = pc_search_inventory(sd,require.itemid[0])) < 0 || sd->status.inventory[i].amount < require.amount[0]) )
+ {
+ //clif_skill_fail(sd,skill,USESKILL_FAIL_NEED_ITEM,require.amount[0],require.itemid[0]);
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ case WL_SUMMONFB:
+ case WL_SUMMONBL:
+ case WL_SUMMONWB:
+ case WL_SUMMONSTONE:
+ if( sc )
+ {
+ ARR_FIND(SC_SPHERE_1,SC_SPHERE_5+1,i,!sc->data[i]);
+ if( i == SC_SPHERE_5+1 )
+ { // No more free slots
+ clif_skill_fail(sd,skill,USESKILL_FAIL_SUMMON,0);
+ return 0;
+ }
+ }
+ break;
+ /**
+ * Guilotine Cross
+ **/
+ case GC_HALLUCINATIONWALK:
+ if( sc && (sc->data[SC_HALLUCINATIONWALK] || sc->data[SC_HALLUCINATIONWALK_POSTDELAY]) ) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ case GC_COUNTERSLASH:
+ case GC_WEAPONCRUSH:
+ if( !(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == GC_WEAPONBLOCKING) ) {
+ clif_skill_fail(sd, skill, USESKILL_FAIL_GC_WEAPONBLOCKING, 0);
+ return 0;
+ }
+ break;
+ /**
+ * Ranger
+ **/
+ case RA_WUGMASTERY:
+ if( pc_isfalcon(sd) || pc_isridingwug(sd) || sd->sc.data[SC__GROOMY]) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ case RA_WUGSTRIKE:
+ if( !pc_iswug(sd) && !pc_isridingwug(sd) ) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ case RA_WUGRIDER:
+ if( pc_isfalcon(sd) || ( !pc_isridingwug(sd) && !pc_iswug(sd) ) ) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ case RA_WUGDASH:
+ if(!pc_isridingwug(sd)) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ /**
+ * Royal Guard
+ **/
+ case LG_BANDING:
+ if( sc && sc->data[SC_INSPIRATION] ) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ case LG_PRESTIGE:
+ if( sc && (sc->data[SC_BANDING] || sc->data[SC_INSPIRATION]) ) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ case LG_RAGEBURST:
+ if( sd->spiritball == 0 ) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_SKILLINTERVAL,0);
+ return 0;
+ }
+ sd->spiritball_old = require.spiritball = sd->spiritball;
+ break;
+ case LG_RAYOFGENESIS:
+ if( sc && sc->data[SC_INSPIRATION] )
+ return 1; // Don't check for partner.
+ if( !(sc && sc->data[SC_BANDING]) ) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL,0);
+ return 0;
+ } else if( skill_check_pc_partner(sd,skill,&lv,skill_get_range(skill,lv),0) < 1 )
+ return 0; // Just fails, no msg here.
+ break;
+ case LG_HESPERUSLIT:
+ if( !sc || !sc->data[SC_BANDING] ) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ case SR_FALLENEMPIRE:
+ if( !(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_DRAGONCOMBO) )
+ return 0;
+ break;
+
+ case SR_CRESCENTELBOW:
+ if( sc && sc->data[SC_CRESCENTELBOW] ) {
+ clif_skill_fail(sd, skill, USESKILL_FAIL_DUPLICATE, 0);
+ return 0;
+ }
+ break;
+ case SR_CURSEDCIRCLE:
+ if (map_flag_gvg(sd->bl.m)) {
+ if (map_foreachinrange(mob_count_sub, &sd->bl, skill_get_splash(skill, lv), BL_MOB,
+ MOBID_EMPERIUM, MOBID_GUARIDAN_STONE1, MOBID_GUARIDAN_STONE2)) {
+ char output[128];
+ sprintf(output, "You're too close to a stone or emperium to do this skill");
+ clif_colormes(sd, COLOR_RED, output);
+ return 0;
+ }
+ }
+ if( sd->spiritball > 0 )
+ sd->spiritball_old = require.spiritball = sd->spiritball;
+ else {
+ clif_skill_fail(sd,skill,0,0);
+ return 0;
+ }
+ break;
+ case SR_GATEOFHELL:
+ if( sd->spiritball > 0 )
+ sd->spiritball_old = require.spiritball;
+ break;
+ case SC_MANHOLE:
+ case SC_DIMENSIONDOOR:
+ if( sc && sc->data[SC_MAGNETICFIELD] ) {
+ clif_skill_fail(sd,skill,0,0);
+ return 0;
+ }
+ break;
+ case WM_GREAT_ECHO: {
+ int count;
+ count = skill_check_pc_partner(sd, skill, &lv, skill_get_splash(skill,lv), 0);
+ if( count < 1 ) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_NEED_HELPER,0);
+ return 0;
+ } else
+ require.sp -= require.sp * 20 * count / 100; // -20% each W/M in the party.
+ }
+ break;
+ case SO_FIREWALK:
+ case SO_ELECTRICWALK: // Can't be casted until you've walked all cells.
+ if( sc && sc->data[SC_PROPERTYWALK] &&
+ sc->data[SC_PROPERTYWALK]->val3 < skill_get_maxcount(sc->data[SC_PROPERTYWALK]->val1,sc->data[SC_PROPERTYWALK]->val2) ) {
+ clif_skill_fail(sd,skill,0x0,0);
+ return 0;
+ }
+ break;
+ case SO_EL_CONTROL:
+ if( !sd->status.ele_id || !sd->ed ) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ case RETURN_TO_ELDICASTES:
+ if( pc_ismadogear(sd) ) { //Cannot be used if Mado is equipped.
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ case LG_REFLECTDAMAGE:
+ case CR_REFLECTSHIELD:
+ if( sc && sc->data[SC_KYOMU] && rand()%100 < 30){
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ case KO_KAHU_ENTEN:
+ case KO_HYOUHU_HUBUKI:
+ case KO_KAZEHU_SEIRAN:
+ case KO_DOHU_KOUKAI:
+ {
+ int ttype = skill_get_ele(skill, lv);
+ ARR_FIND(1, 5, i, sd->talisman[i] > 0 && i != ttype);
+ if( (i < 5 && i != ttype) || sd->talisman[ttype] >= 10 ){
+ clif_skill_fail(sd, skill, USESKILL_FAIL_LEVEL, 0);
+ return 0;
+ }
+ }
+ break;
+ case KO_KAIHOU:
+ case KO_ZENKAI:
+ ARR_FIND(1, 6, i, sd->talisman[i] > 0);
+ if( i > 4 ) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ }
+
+ switch(require.state) {
+ case ST_HIDING:
+ if(!(sc && sc->option&OPTION_HIDE)) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ case ST_CLOAKING:
+ if(!pc_iscloaking(sd)) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ case ST_HIDDEN:
+ if(!pc_ishiding(sd)) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ case ST_RIDING:
+ if(!pc_isriding(sd)) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ case ST_FALCON:
+ if(!pc_isfalcon(sd)) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ case ST_CARTBOOST:
+ if(!(sc && sc->data[SC_CARTBOOST])) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ case ST_CART:
+ if(!pc_iscarton(sd)) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ case ST_SHIELD:
+ if(sd->status.shield <= 0) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ case ST_SIGHT:
+ if(!(sc && sc->data[SC_SIGHT])) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ case ST_EXPLOSIONSPIRITS:
+ if(!(sc && sc->data[SC_EXPLOSIONSPIRITS])) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ case ST_RECOV_WEIGHT_RATE:
+ if(battle_config.natural_heal_weight_rate <= 100 && sd->weight*100/sd->max_weight >= (unsigned int)battle_config.natural_heal_weight_rate) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ case ST_MOVE_ENABLE:
+ if (sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == skill)
+ sd->ud.canmove_tick = gettick(); //When using a combo, cancel the can't move delay to enable the skill. [Skotlex]
+
+ if (!unit_can_move(&sd->bl)) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ case ST_WATER:
+ if (sc && (sc->data[SC_DELUGE] || sc->data[SC_SUITON]))
+ break;
+ if (map_getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKWATER))
+ break;
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ /**
+ * Rune Knight
+ **/
+ case ST_RIDINGDRAGON:
+ if( !pc_isridingdragon(sd) ) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ /**
+ * Wug
+ **/
+ case ST_WUG:
+ if( !pc_iswug(sd) ) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ /**
+ * Riding Wug
+ **/
+ case ST_RIDINGWUG:
+ if( !pc_isridingwug(sd) ){
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ /**
+ * Mechanic
+ **/
+ case ST_MADO:
+ if( !pc_ismadogear(sd) ) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ /**
+ * Sorcerer
+ **/
+ case ST_ELEMENTALSPIRIT:
+ if(!sd->ed) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_EL_SUMMON,0);
+ return 0;
+ }
+ break;
case ST_POISONINGWEAPON:
if (!(sc && sc->data[SC_POISONINGWEAPON])) {
clif_skill_fail(sd, skill, USESKILL_FAIL_GC_POISONINGWEAPON, 0);
@@ -13227,1470 +13076,1470 @@ int skill_check_condition_castbegin(struct map_session_data *sd, short skill, sh
return 0;
}
break;
- }
-
- if (require.mhp > 0 && get_percentage(status->hp, status->max_hp) > require.mhp) {
- //mhp is the max-hp-requirement, that is,
- //you must have this % or less of HP to cast it.
- clif_skill_fail(sd,skill,USESKILL_FAIL_HP_INSUFFICIENT,0);
- return 0;
- }
-
- if (require.weapon && !pc_check_weapontype(sd,require.weapon)) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_THIS_WEAPON,0);
- return 0;
- }
-
- if (require.sp > 0 && status->sp < (unsigned int)require.sp) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_SP_INSUFFICIENT,0);
- return 0;
- }
-
- if (require.zeny > 0 && sd->status.zeny < require.zeny) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_MONEY,0);
- return 0;
- }
-
- if (require.spiritball > 0 && sd->spiritball < require.spiritball) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_SPIRITS,require.spiritball);
- return 0;
- }
-
- return 1;
+ }
+
+ if(require.mhp > 0 && get_percentage(status->hp, status->max_hp) > require.mhp) {
+ //mhp is the max-hp-requirement, that is,
+ //you must have this % or less of HP to cast it.
+ clif_skill_fail(sd,skill,USESKILL_FAIL_HP_INSUFFICIENT,0);
+ return 0;
+ }
+
+ if( require.weapon && !pc_check_weapontype(sd,require.weapon) ) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_THIS_WEAPON,0);
+ return 0;
+ }
+
+ if( require.sp > 0 && status->sp < (unsigned int)require.sp) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_SP_INSUFFICIENT,0);
+ return 0;
+ }
+
+ if( require.zeny > 0 && sd->status.zeny < require.zeny ) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_MONEY,0);
+ return 0;
+ }
+
+ if( require.spiritball > 0 && sd->spiritball < require.spiritball) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_SPIRITS,require.spiritball);
+ return 0;
+ }
+
+ return 1;
}
-int skill_check_condition_castend(struct map_session_data *sd, short skill, short lv)
+int skill_check_condition_castend(struct map_session_data* sd, short skill, short lv)
{
- struct skill_condition require;
- struct status_data *status;
- int i;
- int index[MAX_SKILL_ITEM_REQUIRE];
-
- nullpo_ret(sd);
-
- if (lv <= 0 || sd->chatID)
- return 0;
-
- if (pc_has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL) && sd->skillitem != skill) {
- //GMs don't override the skillItem check, otherwise they can use items without them being consumed! [Skotlex]
- sd->state.arrow_atk = skill_get_ammotype(skill)?1:0; //Need to do arrow state check.
- sd->spiritball_old = sd->spiritball; //Need to do Spiritball check.
- return 1;
- }
-
- switch (sd->menuskill_id) { // Cast start or cast end??
- case AM_PHARMACY:
- switch (skill) {
- case AM_PHARMACY:
- case AC_MAKINGARROW:
- case BS_REPAIRWEAPON:
- case AM_TWILIGHT1:
- case AM_TWILIGHT2:
- case AM_TWILIGHT3:
- return 0;
- }
- break;
- case GN_MIX_COOKING:
- case GN_MAKEBOMB:
- case GN_S_PHARMACY:
- case GN_CHANGEMATERIAL:
- if (sd->menuskill_id != skill)
- return 0;
- break;
- }
+ struct skill_condition require;
+ struct status_data *status;
+ int i;
+ int index[MAX_SKILL_ITEM_REQUIRE];
- if (sd->skillitem == skill) // Casting finished (Item skill or Hocus-Pocus)
- return 1;
+ nullpo_ret(sd);
- if (pc_is90overweight(sd)) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_WEIGHTOVER,0);
- return 0;
- }
+ if( lv <= 0 || sd->chatID )
+ return 0;
- // perform skill-specific checks (and actions)
- switch (skill) {
- case PR_BENEDICTIO:
- skill_check_pc_partner(sd, skill, &lv, 1, 1);
- break;
- case AM_CANNIBALIZE:
- case AM_SPHEREMINE: {
- int c=0;
- int summons[5] = { 1589, 1579, 1575, 1555, 1590 };
- //int summons[5] = { 1020, 1068, 1118, 1500, 1368 };
- int maxcount = (skill==AM_CANNIBALIZE)? 6-lv : skill_get_maxcount(skill,lv);
- int mob_class = (skill==AM_CANNIBALIZE)? summons[lv-1] :1142;
- if (battle_config.land_skill_limit && maxcount>0 && (battle_config.land_skill_limit&BL_PC)) {
- i = map_foreachinmap(skill_check_condition_mob_master_sub ,sd->bl.m, BL_MOB, sd->bl.id, mob_class, skill, &c);
- if (c >= maxcount ||
- (skill==AM_CANNIBALIZE && c != i && battle_config.summon_flora&2)) {
- //Fails when: exceed max limit. There are other plant types already out.
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- }
- break;
- }
- case NC_SILVERSNIPER:
- case NC_MAGICDECOY: {
- int c = 0, j;
- int maxcount = skill_get_maxcount(skill,lv);
- int mob_class = 2042;
- if (skill == NC_MAGICDECOY)
- mob_class = 2043;
-
- if (battle_config.land_skill_limit && maxcount > 0 && (battle_config.land_skill_limit&BL_PC)) {
- if (skill == NC_MAGICDECOY) {
- for (j = mob_class; j <= 2046; j++)
- map_foreachinmap(skill_check_condition_mob_master_sub, sd->bl.m, BL_MOB, sd->bl.id, j, skill, &c);
- } else
- map_foreachinmap(skill_check_condition_mob_master_sub, sd->bl.m, BL_MOB, sd->bl.id, mob_class, skill, &c);
- if (c >= maxcount) {
- clif_skill_fail(sd , skill, USESKILL_FAIL_LEVEL, 0);
- return 0;
- }
- }
- }
- break;
- case KO_ZANZOU: {
- int c = 0;
- i = map_foreachinmap(skill_check_condition_mob_master_sub, sd->bl.m, BL_MOB, sd->bl.id, 2308, skill, &c);
- if (c >= skill_get_maxcount(skill,lv) || c != i) {
- clif_skill_fail(sd , skill, USESKILL_FAIL_LEVEL, 0);
- return 0;
- }
- }
- break;
- }
-
- status = &sd->battle_status;
-
- require = skill_get_requirement(sd,skill,lv);
-
- if (require.hp > 0 && status->hp <= (unsigned int)require.hp) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_HP_INSUFFICIENT,0);
- return 0;
- }
-
- if (require.weapon && !pc_check_weapontype(sd,require.weapon)) {
- clif_skill_fail(sd,skill,USESKILL_FAIL_THIS_WEAPON,0);
- return 0;
- }
-
- if (require.ammo) { //Skill requires stuff equipped in the arrow slot.
- if ((i=sd->equip_index[EQI_AMMO]) < 0 || !sd->inventory_data[i]) {
- clif_arrow_fail(sd,0);
- return 0;
- } else if (sd->status.inventory[i].amount < require.ammo_qty) {
- char e_msg[100];
- sprintf(e_msg,"Skill Failed. [%s] requires %dx %s.",
- skill_get_desc(skill),
- require.ammo_qty,
- itemdb_jname(sd->status.inventory[i].nameid));
- clif_colormes(sd,COLOR_RED,e_msg);
- return 0;
- }
- if (!(require.ammo&1<<sd->inventory_data[i]->look)) { //Ammo type check. Send the "wrong weapon type" message
- //which is the closest we have to wrong ammo type. [Skotlex]
- clif_arrow_fail(sd,0); //Haplo suggested we just send the equip-arrows message instead. [Skotlex]
- //clif_skill_fail(sd,skill,USESKILL_FAIL_THIS_WEAPON,0);
- return 0;
- }
- }
-
- for (i = 0; i < MAX_SKILL_ITEM_REQUIRE; ++i) {
- if (!require.itemid[i])
- continue;
- index[i] = pc_search_inventory(sd,require.itemid[i]);
- if (index[i] < 0 || sd->status.inventory[index[i]].amount < require.amount[i]) {
- if (require.itemid[i] == ITEMID_RED_GEMSTONE)
- clif_skill_fail(sd,skill,USESKILL_FAIL_REDJAMSTONE,0);// red gemstone required
- else if (require.itemid[i] == ITEMID_BLUE_GEMSTONE)
- clif_skill_fail(sd,skill,USESKILL_FAIL_BLUEJAMSTONE,0);// blue gemstone required
- else
- clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- }
-
- return 1;
+ if( pc_has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL) && sd->skillitem != skill ) {
+ //GMs don't override the skillItem check, otherwise they can use items without them being consumed! [Skotlex]
+ sd->state.arrow_atk = skill_get_ammotype(skill)?1:0; //Need to do arrow state check.
+ sd->spiritball_old = sd->spiritball; //Need to do Spiritball check.
+ return 1;
+ }
+
+ switch( sd->menuskill_id ) { // Cast start or cast end??
+ case AM_PHARMACY:
+ switch( skill ) {
+ case AM_PHARMACY:
+ case AC_MAKINGARROW:
+ case BS_REPAIRWEAPON:
+ case AM_TWILIGHT1:
+ case AM_TWILIGHT2:
+ case AM_TWILIGHT3:
+ return 0;
+ }
+ break;
+ case GN_MIX_COOKING:
+ case GN_MAKEBOMB:
+ case GN_S_PHARMACY:
+ case GN_CHANGEMATERIAL:
+ if( sd->menuskill_id != skill )
+ return 0;
+ break;
+ }
+
+ if( sd->skillitem == skill ) // Casting finished (Item skill or Hocus-Pocus)
+ return 1;
+
+ if( pc_is90overweight(sd) ) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_WEIGHTOVER,0);
+ return 0;
+ }
+
+ // perform skill-specific checks (and actions)
+ switch( skill ) {
+ case PR_BENEDICTIO:
+ skill_check_pc_partner(sd, skill, &lv, 1, 1);
+ break;
+ case AM_CANNIBALIZE:
+ case AM_SPHEREMINE: {
+ int c=0;
+ int summons[5] = { 1589, 1579, 1575, 1555, 1590 };
+ //int summons[5] = { 1020, 1068, 1118, 1500, 1368 };
+ int maxcount = (skill==AM_CANNIBALIZE)? 6-lv : skill_get_maxcount(skill,lv);
+ int mob_class = (skill==AM_CANNIBALIZE)? summons[lv-1] :1142;
+ if(battle_config.land_skill_limit && maxcount>0 && (battle_config.land_skill_limit&BL_PC)) {
+ i = map_foreachinmap(skill_check_condition_mob_master_sub ,sd->bl.m, BL_MOB, sd->bl.id, mob_class, skill, &c);
+ if(c >= maxcount ||
+ (skill==AM_CANNIBALIZE && c != i && battle_config.summon_flora&2))
+ { //Fails when: exceed max limit. There are other plant types already out.
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ }
+ break;
+ }
+ case NC_SILVERSNIPER:
+ case NC_MAGICDECOY: {
+ int c = 0, j;
+ int maxcount = skill_get_maxcount(skill,lv);
+ int mob_class = 2042;
+ if( skill == NC_MAGICDECOY )
+ mob_class = 2043;
+
+ if( battle_config.land_skill_limit && maxcount > 0 && ( battle_config.land_skill_limit&BL_PC ) ) {
+ if( skill == NC_MAGICDECOY ) {
+ for( j = mob_class; j <= 2046; j++ )
+ map_foreachinmap(skill_check_condition_mob_master_sub, sd->bl.m, BL_MOB, sd->bl.id, j, skill, &c);
+ } else
+ map_foreachinmap(skill_check_condition_mob_master_sub, sd->bl.m, BL_MOB, sd->bl.id, mob_class, skill, &c);
+ if( c >= maxcount ) {
+ clif_skill_fail(sd , skill, USESKILL_FAIL_LEVEL, 0);
+ return 0;
+ }
+ }
+ }
+ break;
+ case KO_ZANZOU: {
+ int c = 0;
+ i = map_foreachinmap(skill_check_condition_mob_master_sub, sd->bl.m, BL_MOB, sd->bl.id, 2308, skill, &c);
+ if( c >= skill_get_maxcount(skill,lv) || c != i)
+ {
+ clif_skill_fail(sd , skill, USESKILL_FAIL_LEVEL, 0);
+ return 0;
+ }
+ }
+ break;
+ }
+
+ status = &sd->battle_status;
+
+ require = skill_get_requirement(sd,skill,lv);
+
+ if( require.hp > 0 && status->hp <= (unsigned int)require.hp) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_HP_INSUFFICIENT,0);
+ return 0;
+ }
+
+ if( require.weapon && !pc_check_weapontype(sd,require.weapon) ) {
+ clif_skill_fail(sd,skill,USESKILL_FAIL_THIS_WEAPON,0);
+ return 0;
+ }
+
+ if( require.ammo ) { //Skill requires stuff equipped in the arrow slot.
+ if((i=sd->equip_index[EQI_AMMO]) < 0 || !sd->inventory_data[i] ) {
+ clif_arrow_fail(sd,0);
+ return 0;
+ } else if( sd->status.inventory[i].amount < require.ammo_qty ) {
+ char e_msg[100];
+ sprintf(e_msg,"Skill Failed. [%s] requires %dx %s.",
+ skill_get_desc(skill),
+ require.ammo_qty,
+ itemdb_jname(sd->status.inventory[i].nameid));
+ clif_colormes(sd,COLOR_RED,e_msg);
+ return 0;
+ }
+ if (!(require.ammo&1<<sd->inventory_data[i]->look)) { //Ammo type check. Send the "wrong weapon type" message
+ //which is the closest we have to wrong ammo type. [Skotlex]
+ clif_arrow_fail(sd,0); //Haplo suggested we just send the equip-arrows message instead. [Skotlex]
+ //clif_skill_fail(sd,skill,USESKILL_FAIL_THIS_WEAPON,0);
+ return 0;
+ }
+ }
+
+ for( i = 0; i < MAX_SKILL_ITEM_REQUIRE; ++i ) {
+ if( !require.itemid[i] )
+ continue;
+ index[i] = pc_search_inventory(sd,require.itemid[i]);
+ if( index[i] < 0 || sd->status.inventory[index[i]].amount < require.amount[i] ) {
+ if( require.itemid[i] == ITEMID_RED_GEMSTONE )
+ clif_skill_fail(sd,skill,USESKILL_FAIL_REDJAMSTONE,0);// red gemstone required
+ else if( require.itemid[i] == ITEMID_BLUE_GEMSTONE )
+ clif_skill_fail(sd,skill,USESKILL_FAIL_BLUEJAMSTONE,0);// blue gemstone required
+ else
+ clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ }
+
+ return 1;
}
// type&2: consume items (after skill was used)
// type&1: consume the others (before skill was used)
-int skill_consume_requirement(struct map_session_data *sd, short skill, short lv, short type)
+int skill_consume_requirement( struct map_session_data *sd, short skill, short lv, short type)
{
- struct skill_condition req;
+ struct skill_condition req;
+
+ nullpo_ret(sd);
+
+ req = skill_get_requirement(sd,skill,lv);
+
+ if( type&1 )
+ {
+ if( skill == CG_TAROTCARD || sd->state.autocast )
+ req.sp = 0; // TarotCard will consume sp in skill_cast_nodamage_id [Inkfish]
+ if(req.hp || req.sp)
+ status_zap(&sd->bl, req.hp, req.sp);
+
+ if(req.spiritball > 0)
+ pc_delspiritball(sd,req.spiritball,0);
+
+ if(req.zeny > 0)
+ {
+ if( skill == NJ_ZENYNAGE )
+ req.zeny = 0; //Zeny is reduced on skill_attack.
+ if( sd->status.zeny < req.zeny )
+ req.zeny = sd->status.zeny;
+ pc_payzeny(sd,req.zeny,LOG_TYPE_CONSUME,NULL);
+ }
+ }
- nullpo_ret(sd);
+ if( type&2 )
+ {
+ struct status_change *sc = &sd->sc;
+ int n,i;
- req = skill_get_requirement(sd,skill,lv);
+ if( !sc->count )
+ sc = NULL;
- if (type&1) {
- if (skill == CG_TAROTCARD || sd->state.autocast)
- req.sp = 0; // TarotCard will consume sp in skill_cast_nodamage_id [Inkfish]
- if (req.hp || req.sp)
- status_zap(&sd->bl, req.hp, req.sp);
+ for( i = 0; i < MAX_SKILL_ITEM_REQUIRE; ++i )
+ {
+ if( !req.itemid[i] )
+ continue;
- if (req.spiritball > 0)
- pc_delspiritball(sd,req.spiritball,0);
+ if( itemid_isgemstone(req.itemid[i]) && skill != HW_GANBANTEIN && sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_WIZARD )
+ continue; //Gemstones are checked, but not substracted from inventory.
- if (req.zeny > 0) {
- if (skill == NJ_ZENYNAGE)
- req.zeny = 0; //Zeny is reduced on skill_attack.
- if (sd->status.zeny < req.zeny)
- req.zeny = sd->status.zeny;
- pc_payzeny(sd,req.zeny,LOG_TYPE_CONSUME,NULL);
- }
- }
+ if( (n = pc_search_inventory(sd,req.itemid[i])) >= 0 )
+ pc_delitem(sd,n,req.amount[i],0,1,LOG_TYPE_CONSUME);
+ }
+ }
- if (type&2) {
- struct status_change *sc = &sd->sc;
- int n,i;
+ return 1;
+}
- if (!sc->count)
- sc = NULL;
+struct skill_condition skill_get_requirement(struct map_session_data* sd, short skill, short lv)
+{
+ struct skill_condition req;
+ struct status_data *status;
+ struct status_change *sc;
+ int i,j,hp_rate,sp_rate, sp_skill_rate_bonus = 100;
+
+ memset(&req,0,sizeof(req));
+
+ if( !sd )
+ return req;
+
+ if( sd->skillitem == skill )
+ return req; // Item skills and Hocus-Pocus don't have requirements.[Inkfish]
+
+ sc = &sd->sc;
+ if( !sc->count )
+ sc = NULL;
+
+ switch( skill )
+ { // Turn off check.
+ case BS_MAXIMIZE: case NV_TRICKDEAD: case TF_HIDING: case AS_CLOAKING: case CR_AUTOGUARD:
+ case ML_AUTOGUARD: case CR_DEFENDER: case ML_DEFENDER: case ST_CHASEWALK: case PA_GOSPEL:
+ case CR_SHRINK: case TK_RUN: case GS_GATLINGFEVER: case TK_READYCOUNTER: case TK_READYDOWN:
+ case TK_READYSTORM: case TK_READYTURN: case SG_FUSION: case KO_YAMIKUMO:
+ if( sc && sc->data[status_skill2sc(skill)] )
+ return req;
+ }
- for (i = 0; i < MAX_SKILL_ITEM_REQUIRE; ++i) {
- if (!req.itemid[i])
- continue;
+ j = skill_get_index(skill);
+ if( j == 0 ) // invalid skill id
+ return req;
+ if( lv < 1 || lv > MAX_SKILL_LEVEL )
+ return req;
+
+ status = &sd->battle_status;
+
+ req.hp = skill_db[j].hp[lv-1];
+ hp_rate = skill_db[j].hp_rate[lv-1];
+ if(hp_rate > 0)
+ req.hp += (status->hp * hp_rate)/100;
+ else
+ req.hp += (status->max_hp * (-hp_rate))/100;
+
+ req.sp = skill_db[j].sp[lv-1];
+ if((sd->skillid_old == BD_ENCORE) && skill == sd->skillid_dance)
+ req.sp /= 2;
+ sp_rate = skill_db[j].sp_rate[lv-1];
+ if(sp_rate > 0)
+ req.sp += (status->sp * sp_rate)/100;
+ else
+ req.sp += (status->max_sp * (-sp_rate))/100;
+ if( sd->dsprate != 100 )
+ req.sp = req.sp * sd->dsprate / 100;
+
+ ARR_FIND(0, ARRAYLENGTH(sd->skillusesprate), i, sd->skillusesprate[i].id == skill);
+ if( i < ARRAYLENGTH(sd->skillusesprate) )
+ sp_skill_rate_bonus += sd->skillusesprate[i].val;
+ ARR_FIND(0, ARRAYLENGTH(sd->skillusesp), i, sd->skillusesp[i].id == skill);
+ if( i < ARRAYLENGTH(sd->skillusesp) )
+ req.sp -= sd->skillusesp[i].val;
+
+ req.sp = cap_value(req.sp * sp_skill_rate_bonus / 100, 0, SHRT_MAX);
+
+ if( sc ) {
+ if( sc->data[SC__LAZINESS] )
+ req.sp += req.sp + sc->data[SC__LAZINESS]->val1 * 10;
+ if (sc->data[SC_UNLIMITEDHUMMINGVOICE])
+ req.sp += req.sp * sc->data[SC_UNLIMITEDHUMMINGVOICE]->val2 / 100;
+ if( sc->data[SC_RECOGNIZEDSPELL] )
+ req.sp += req.sp / 4;
+ }
- if (itemid_isgemstone(req.itemid[i]) && skill != HW_GANBANTEIN && sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_WIZARD)
- continue; //Gemstones are checked, but not substracted from inventory.
+ req.zeny = skill_db[j].zeny[lv-1];
- if ((n = pc_search_inventory(sd,req.itemid[i])) >= 0)
- pc_delitem(sd,n,req.amount[i],0,1,LOG_TYPE_CONSUME);
- }
- }
+ if( sc && sc->data[SC__UNLUCKY] )
+ req.zeny += sc->data[SC__UNLUCKY]->val1 * 500;
- return 1;
-}
+ req.spiritball = skill_db[j].spiritball[lv-1];
-struct skill_condition skill_get_requirement(struct map_session_data *sd, short skill, short lv) {
- struct skill_condition req;
- struct status_data *status;
- struct status_change *sc;
- int i,j,hp_rate,sp_rate, sp_skill_rate_bonus = 100;
-
- memset(&req,0,sizeof(req));
-
- if (!sd)
- return req;
-
- if (sd->skillitem == skill)
- return req; // Item skills and Hocus-Pocus don't have requirements.[Inkfish]
-
- sc = &sd->sc;
- if (!sc->count)
- sc = NULL;
-
- switch (skill) {
- // Turn off check.
- case BS_MAXIMIZE:
- case NV_TRICKDEAD:
- case TF_HIDING:
- case AS_CLOAKING:
- case CR_AUTOGUARD:
- case ML_AUTOGUARD:
- case CR_DEFENDER:
- case ML_DEFENDER:
- case ST_CHASEWALK:
- case PA_GOSPEL:
- case CR_SHRINK:
- case TK_RUN:
- case GS_GATLINGFEVER:
- case TK_READYCOUNTER:
- case TK_READYDOWN:
- case TK_READYSTORM:
- case TK_READYTURN:
- case SG_FUSION:
- case KO_YAMIKUMO:
- if (sc && sc->data[status_skill2sc(skill)])
- return req;
- }
-
- j = skill_get_index(skill);
- if (j == 0) // invalid skill id
- return req;
- if (lv < 1 || lv > MAX_SKILL_LEVEL)
- return req;
-
- status = &sd->battle_status;
-
- req.hp = skill_db[j].hp[lv-1];
- hp_rate = skill_db[j].hp_rate[lv-1];
- if (hp_rate > 0)
- req.hp += (status->hp *hp_rate)/100;
- else
- req.hp += (status->max_hp * (-hp_rate))/100;
-
- req.sp = skill_db[j].sp[lv-1];
- if ((sd->skillid_old == BD_ENCORE) && skill == sd->skillid_dance)
- req.sp /= 2;
- sp_rate = skill_db[j].sp_rate[lv-1];
- if (sp_rate > 0)
- req.sp += (status->sp *sp_rate)/100;
- else
- req.sp += (status->max_sp * (-sp_rate))/100;
- if (sd->dsprate != 100)
- req.sp = req.sp *sd->dsprate / 100;
-
- ARR_FIND(0, ARRAYLENGTH(sd->skillusesprate), i, sd->skillusesprate[i].id == skill);
- if (i < ARRAYLENGTH(sd->skillusesprate))
- sp_skill_rate_bonus += sd->skillusesprate[i].val;
- ARR_FIND(0, ARRAYLENGTH(sd->skillusesp), i, sd->skillusesp[i].id == skill);
- if (i < ARRAYLENGTH(sd->skillusesp))
- req.sp -= sd->skillusesp[i].val;
-
- req.sp = cap_value(req.sp *sp_skill_rate_bonus / 100, 0, SHRT_MAX);
-
- if (sc) {
- if (sc->data[SC__LAZINESS])
- req.sp += req.sp + sc->data[SC__LAZINESS]->val1 * 10;
- if (sc->data[SC_UNLIMITEDHUMMINGVOICE])
- req.sp += req.sp * sc->data[SC_UNLIMITEDHUMMINGVOICE]->val2 / 100;
- if (sc->data[SC_RECOGNIZEDSPELL])
- req.sp += req.sp / 4;
- }
-
- req.zeny = skill_db[j].zeny[lv-1];
-
- if (sc && sc->data[SC__UNLUCKY])
- req.zeny += sc->data[SC__UNLUCKY]->val1 * 500;
-
- req.spiritball = skill_db[j].spiritball[lv-1];
-
- req.state = skill_db[j].state;
-
- req.mhp = skill_db[j].mhp[lv-1];
-
- req.weapon = skill_db[j].weapon;
-
- req.ammo_qty = skill_db[j].ammo_qty[lv-1];
- if (req.ammo_qty)
- req.ammo = skill_db[j].ammo;
-
- if (!req.ammo && skill && skill_isammotype(sd, skill)) {
- //Assume this skill is using the weapon, therefore it requires arrows.
- req.ammo = 0xFFFFFFFF; //Enable use on all ammo types.
- req.ammo_qty = 1;
- }
-
- for (i = 0; i < MAX_SKILL_ITEM_REQUIRE; i++) {
- if ((skill == AM_POTIONPITCHER || skill == CR_SLIMPITCHER || skill == CR_CULTIVATION) && i != lv%11 - 1)
- continue;
-
- switch (skill) {
- case AM_CALLHOMUN:
- if (sd->status.hom_id) //Don't delete items when hom is already out.
- continue;
- break;
- case NC_SHAPESHIFT:
- if (i < 4)
- continue;
- break;
- case WZ_FIREPILLAR: // celest
- if (lv <= 5) // no gems required at level 1-5
- continue;
- break;
- case AB_ADORAMUS:
- if (itemid_isgemstone(skill_db[j].itemid[i]) && skill_check_pc_partner(sd,skill,&lv, 1, 2))
- continue;
- break;
- case WL_COMET:
- if (itemid_isgemstone(skill_db[j].itemid[i]) && skill_check_pc_partner(sd,skill,&lv, 1, 0))
- continue;
- break;
- case GN_FIRE_EXPANSION:
- if (i < 5)
- continue;
- break;
- case SO_SUMMON_AGNI:
- case SO_SUMMON_AQUA:
- case SO_SUMMON_VENTUS:
- case SO_SUMMON_TERA:
- case SO_WATER_INSIGNIA:
- case SO_FIRE_INSIGNIA:
- case SO_WIND_INSIGNIA:
- case SO_EARTH_INSIGNIA:
- if (i < 3)
- continue;
- break;
- }
-
- req.itemid[i] = skill_db[j].itemid[i];
- req.amount[i] = skill_db[j].amount[i];
-
- if (itemid_isgemstone(req.itemid[i]) && skill != HW_GANBANTEIN) {
- if (sd->special_state.no_gemstone) {
- //Make it substract 1 gem rather than skipping the cost.
- if (--req.amount[i] < 1)
- req.itemid[i] = 0;
- }
- if (sc && sc->data[SC_INTOABYSS]) {
- if (skill != SA_ABRACADABRA)
- req.itemid[i] = req.amount[i] = 0;
- else if (--req.amount[i] < 1)
- req.amount[i] = 1; // Hocus Pocus allways use at least 1 gem
- }
- }
- if (skill >= HT_SKIDTRAP && skill <= HT_TALKIEBOX && pc_checkskill(sd, RA_RESEARCHTRAP) > 0) {
- if ((j=pc_search_inventory(sd,req.itemid[i])) < 0 || (j >= 0 && sd->status.inventory[j].amount < req.amount[i])) {
- req.itemid[i] = ITEMID_TRAP_ALLOY;
- req.amount[i] = 1;
- }
- break;
- }
- }
-
- /* requirements are level-dependent */
- switch (skill) {
- case NC_SHAPESHIFT:
- case GN_FIRE_EXPANSION:
- case SO_SUMMON_AGNI:
- case SO_SUMMON_AQUA:
- case SO_SUMMON_VENTUS:
- case SO_SUMMON_TERA:
- case SO_WATER_INSIGNIA:
- case SO_FIRE_INSIGNIA:
- case SO_WIND_INSIGNIA:
- case SO_EARTH_INSIGNIA:
- req.itemid[lv-1] = skill_db[j].itemid[lv-1];
- req.amount[lv-1] = skill_db[j].amount[lv-1];
- break;
- }
+ req.state = skill_db[j].state;
- // Check for cost reductions due to skills & SCs
- switch (skill) {
- case MC_MAMMONITE:
- if (pc_checkskill(sd,BS_UNFAIRLYTRICK)>0)
- req.zeny -= req.zeny*10/100;
- break;
- case AL_HOLYLIGHT:
- if (sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_PRIEST)
- req.sp *= 5;
- break;
- case SL_SMA:
- case SL_STUN:
- case SL_STIN: {
- int kaina_lv = pc_checkskill(sd,SL_KAINA);
-
- if (kaina_lv==0 || sd->status.base_level<70)
- break;
- if (sd->status.base_level>=90)
- req.sp -= req.sp*7*kaina_lv/100;
- else if (sd->status.base_level>=80)
- req.sp -= req.sp*5*kaina_lv/100;
- else if (sd->status.base_level>=70)
- req.sp -= req.sp*3*kaina_lv/100;
- }
- break;
- case MO_TRIPLEATTACK:
- case MO_CHAINCOMBO:
- case MO_COMBOFINISH:
- case CH_TIGERFIST:
- case CH_CHAINCRUSH:
- if (sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_MONK)
- req.sp -= req.sp*25/100; //FIXME: Need real data. this is a custom value.
- break;
- case MO_BODYRELOCATION:
- if (sc && sc->data[SC_EXPLOSIONSPIRITS])
- req.spiritball = 0;
- break;
- case MO_EXTREMITYFIST:
- if (sc) {
- if (sc->data[SC_BLADESTOP])
- req.spiritball--;
- else if (sc->data[SC_COMBO]) {
- switch (sc->data[SC_COMBO]->val1) {
- case MO_COMBOFINISH:
- req.spiritball = 4;
- break;
- case CH_TIGERFIST:
- req.spiritball = 3;
- break;
- case CH_CHAINCRUSH: //It should consume whatever is left as long as it's at least 1.
- req.spiritball = sd->spiritball?sd->spiritball:1;
- break;
- }
- } else if (sc->data[SC_RAISINGDRAGON] && sd->spiritball > 5)
- req.spiritball = sd->spiritball; // must consume all regardless of the amount required
- }
- break;
- case SR_RAMPAGEBLASTER:
- req.spiritball = sd->spiritball?sd->spiritball:15;
- break;
- case SR_GATEOFHELL:
- if (sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE)
- req.sp -= req.sp * 10 / 100;
- break;
- case SO_SUMMON_AGNI:
- case SO_SUMMON_AQUA:
- case SO_SUMMON_VENTUS:
- case SO_SUMMON_TERA:
- req.sp -= req.sp * (5 + 5 * pc_checkskill(sd,SO_EL_SYMPATHY)) / 100;
- break;
- }
+ req.mhp = skill_db[j].mhp[lv-1];
+
+ req.weapon = skill_db[j].weapon;
+
+ req.ammo_qty = skill_db[j].ammo_qty[lv-1];
+ if (req.ammo_qty)
+ req.ammo = skill_db[j].ammo;
- return req;
+ if (!req.ammo && skill && skill_isammotype(sd, skill))
+ { //Assume this skill is using the weapon, therefore it requires arrows.
+ req.ammo = 0xFFFFFFFF; //Enable use on all ammo types.
+ req.ammo_qty = 1;
+ }
+
+ for( i = 0; i < MAX_SKILL_ITEM_REQUIRE; i++ ) {
+ if( (skill == AM_POTIONPITCHER || skill == CR_SLIMPITCHER || skill == CR_CULTIVATION) && i != lv%11 - 1 )
+ continue;
+
+ switch( skill ) {
+ case AM_CALLHOMUN:
+ if (sd->status.hom_id) //Don't delete items when hom is already out.
+ continue;
+ break;
+ case NC_SHAPESHIFT:
+ if( i < 4 )
+ continue;
+ break;
+ case WZ_FIREPILLAR: // celest
+ if (lv <= 5) // no gems required at level 1-5
+ continue;
+ break;
+ case AB_ADORAMUS:
+ if( itemid_isgemstone(skill_db[j].itemid[i]) && skill_check_pc_partner(sd,skill,&lv, 1, 2) )
+ continue;
+ break;
+ case WL_COMET:
+ if( itemid_isgemstone(skill_db[j].itemid[i]) && skill_check_pc_partner(sd,skill,&lv, 1, 0) )
+ continue;
+ break;
+ case GN_FIRE_EXPANSION:
+ if( i < 5 )
+ continue;
+ break;
+ case SO_SUMMON_AGNI:
+ case SO_SUMMON_AQUA:
+ case SO_SUMMON_VENTUS:
+ case SO_SUMMON_TERA:
+ case SO_WATER_INSIGNIA:
+ case SO_FIRE_INSIGNIA:
+ case SO_WIND_INSIGNIA:
+ case SO_EARTH_INSIGNIA:
+ if( i < 3 )
+ continue;
+ break;
+ }
+
+ req.itemid[i] = skill_db[j].itemid[i];
+ req.amount[i] = skill_db[j].amount[i];
+
+ if( itemid_isgemstone(req.itemid[i]) && skill != HW_GANBANTEIN )
+ {
+ if( sd->special_state.no_gemstone )
+ { //Make it substract 1 gem rather than skipping the cost.
+ if( --req.amount[i] < 1 )
+ req.itemid[i] = 0;
+ }
+ if(sc && sc->data[SC_INTOABYSS])
+ {
+ if( skill != SA_ABRACADABRA )
+ req.itemid[i] = req.amount[i] = 0;
+ else if( --req.amount[i] < 1 )
+ req.amount[i] = 1; // Hocus Pocus allways use at least 1 gem
+ }
+ }
+ if( skill >= HT_SKIDTRAP && skill <= HT_TALKIEBOX && pc_checkskill(sd, RA_RESEARCHTRAP) > 0){
+ if( (j=pc_search_inventory(sd,req.itemid[i])) < 0 || ( j >= 0 && sd->status.inventory[j].amount < req.amount[i] ) ){
+ req.itemid[i] = ITEMID_TRAP_ALLOY;
+ req.amount[i] = 1;
+ }
+ break;
+ }
+ }
+
+ /* requirements are level-dependent */
+ switch( skill ) {
+ case NC_SHAPESHIFT:
+ case GN_FIRE_EXPANSION:
+ case SO_SUMMON_AGNI:
+ case SO_SUMMON_AQUA:
+ case SO_SUMMON_VENTUS:
+ case SO_SUMMON_TERA:
+ case SO_WATER_INSIGNIA:
+ case SO_FIRE_INSIGNIA:
+ case SO_WIND_INSIGNIA:
+ case SO_EARTH_INSIGNIA:
+ req.itemid[lv-1] = skill_db[j].itemid[lv-1];
+ req.amount[lv-1] = skill_db[j].amount[lv-1];
+ break;
+ }
+
+ // Check for cost reductions due to skills & SCs
+ switch(skill) {
+ case MC_MAMMONITE:
+ if(pc_checkskill(sd,BS_UNFAIRLYTRICK)>0)
+ req.zeny -= req.zeny*10/100;
+ break;
+ case AL_HOLYLIGHT:
+ if(sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_PRIEST)
+ req.sp *= 5;
+ break;
+ case SL_SMA:
+ case SL_STUN:
+ case SL_STIN:
+ {
+ int kaina_lv = pc_checkskill(sd,SL_KAINA);
+
+ if(kaina_lv==0 || sd->status.base_level<70)
+ break;
+ if(sd->status.base_level>=90)
+ req.sp -= req.sp*7*kaina_lv/100;
+ else if(sd->status.base_level>=80)
+ req.sp -= req.sp*5*kaina_lv/100;
+ else if(sd->status.base_level>=70)
+ req.sp -= req.sp*3*kaina_lv/100;
+ }
+ break;
+ case MO_TRIPLEATTACK:
+ case MO_CHAINCOMBO:
+ case MO_COMBOFINISH:
+ case CH_TIGERFIST:
+ case CH_CHAINCRUSH:
+ if(sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_MONK)
+ req.sp -= req.sp*25/100; //FIXME: Need real data. this is a custom value.
+ break;
+ case MO_BODYRELOCATION:
+ if( sc && sc->data[SC_EXPLOSIONSPIRITS] )
+ req.spiritball = 0;
+ break;
+ case MO_EXTREMITYFIST:
+ if( sc )
+ {
+ if( sc->data[SC_BLADESTOP] )
+ req.spiritball--;
+ else if( sc->data[SC_COMBO] )
+ {
+ switch( sc->data[SC_COMBO]->val1 )
+ {
+ case MO_COMBOFINISH:
+ req.spiritball = 4;
+ break;
+ case CH_TIGERFIST:
+ req.spiritball = 3;
+ break;
+ case CH_CHAINCRUSH: //It should consume whatever is left as long as it's at least 1.
+ req.spiritball = sd->spiritball?sd->spiritball:1;
+ break;
+ }
+ }else if( sc->data[SC_RAISINGDRAGON] && sd->spiritball > 5)
+ req.spiritball = sd->spiritball; // must consume all regardless of the amount required
+ }
+ break;
+ case SR_RAMPAGEBLASTER:
+ req.spiritball = sd->spiritball?sd->spiritball:15;
+ break;
+ case SR_GATEOFHELL:
+ if( sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE )
+ req.sp -= req.sp * 10 / 100;
+ break;
+ case SO_SUMMON_AGNI:
+ case SO_SUMMON_AQUA:
+ case SO_SUMMON_VENTUS:
+ case SO_SUMMON_TERA:
+ req.sp -= req.sp * (5 + 5 * pc_checkskill(sd,SO_EL_SYMPATHY)) / 100;
+ break;
+ }
+
+ return req;
}
/*==========================================
* Does cast-time reductions based on dex, item bonuses and config setting
*------------------------------------------*/
-int skill_castfix(struct block_list *bl, int skill_id, int skill_lv)
-{
- int time = skill_get_cast(skill_id, skill_lv);
+int skill_castfix (struct block_list *bl, int skill_id, int skill_lv) {
+ int time = skill_get_cast(skill_id, skill_lv);
- nullpo_ret(bl);
+ nullpo_ret(bl);
#ifndef RENEWAL_CAST
- {
- struct map_session_data *sd;
-
- sd = BL_CAST(BL_PC, bl);
-
- // calculate base cast time (reduced by dex)
- if (!(skill_get_castnodex(skill_id, skill_lv)&1)) {
- int scale = battle_config.castrate_dex_scale - status_get_dex(bl);
- if (scale > 0) // not instant cast
- time = time * scale / battle_config.castrate_dex_scale;
- else
- return 0; // instant cast
- }
-
- // calculate cast time reduced by item/card bonuses
- if (!(skill_get_castnodex(skill_id, skill_lv)&4) && sd) {
- int i;
- if (sd->castrate != 100)
- time = time * sd->castrate / 100;
- for (i = 0; i < ARRAYLENGTH(sd->skillcast) && sd->skillcast[i].id; i++) {
- if (sd->skillcast[i].id == skill_id) {
- time+= time * sd->skillcast[i].val / 100;
- break;
- }
- }
- }
+ {
+ struct map_session_data *sd;
+
+ sd = BL_CAST(BL_PC, bl);
+
+ // calculate base cast time (reduced by dex)
+ if( !(skill_get_castnodex(skill_id, skill_lv)&1) ) {
+ int scale = battle_config.castrate_dex_scale - status_get_dex(bl);
+ if( scale > 0 ) // not instant cast
+ time = time * scale / battle_config.castrate_dex_scale;
+ else
+ return 0; // instant cast
+ }
+
+ // calculate cast time reduced by item/card bonuses
+ if( !(skill_get_castnodex(skill_id, skill_lv)&4) && sd )
+ {
+ int i;
+ if( sd->castrate != 100 )
+ time = time * sd->castrate / 100;
+ for( i = 0; i < ARRAYLENGTH(sd->skillcast) && sd->skillcast[i].id; i++ )
+ {
+ if( sd->skillcast[i].id == skill_id )
+ {
+ time+= time * sd->skillcast[i].val / 100;
+ break;
+ }
+ }
+ }
- }
+ }
#endif
- // config cast time multiplier
- if (battle_config.cast_rate != 100)
- time = time * battle_config.cast_rate / 100;
- // return final cast time
- time = max(time, 0);
-
- // ShowInfo("Castime castfix = %d\n",time);
- return time;
+ // config cast time multiplier
+ if (battle_config.cast_rate != 100)
+ time = time * battle_config.cast_rate / 100;
+ // return final cast time
+ time = max(time, 0);
+
+// ShowInfo("Castime castfix = %d\n",time);
+ return time;
}
/*==========================================
* Does cast-time reductions based on sc data.
*------------------------------------------*/
-int skill_castfix_sc(struct block_list *bl, int time)
+int skill_castfix_sc (struct block_list *bl, int time)
{
- struct status_change *sc = status_get_sc(bl);
+ struct status_change *sc = status_get_sc(bl);
- if (time < 0)
- return 0;
+ if( time < 0 )
+ return 0;
- if (sc && sc->count) {
- if (sc->data[SC_SLOWCAST])
- time += time * sc->data[SC_SLOWCAST]->val2 / 100;
+ if (sc && sc->count) {
+ if (sc->data[SC_SLOWCAST])
+ time += time * sc->data[SC_SLOWCAST]->val2 / 100;
if (sc->data[SC_PARALYSIS])
time += sc->data[SC_PARALYSIS]->val3;
- if (sc->data[SC_SUFFRAGIUM]) {
- time -= time * sc->data[SC_SUFFRAGIUM]->val2 / 100;
- status_change_end(bl, SC_SUFFRAGIUM, INVALID_TIMER);
- }
- if (sc->data[SC_MEMORIZE]) {
- time>>=1;
- if ((--sc->data[SC_MEMORIZE]->val2) <= 0)
- status_change_end(bl, SC_MEMORIZE, INVALID_TIMER);
- }
- if (sc->data[SC_POEMBRAGI])
- time -= time * sc->data[SC_POEMBRAGI]->val2 / 100;
- if (sc->data[SC_IZAYOI])
- time -= time * 50 / 100;
- }
- time = max(time, 0);
-
- // ShowInfo("Castime castfix_sc = %d\n",time);
- return time;
+ if (sc->data[SC_SUFFRAGIUM]) {
+ time -= time * sc->data[SC_SUFFRAGIUM]->val2 / 100;
+ status_change_end(bl, SC_SUFFRAGIUM, INVALID_TIMER);
+ }
+ if (sc->data[SC_MEMORIZE]) {
+ time>>=1;
+ if ((--sc->data[SC_MEMORIZE]->val2) <= 0)
+ status_change_end(bl, SC_MEMORIZE, INVALID_TIMER);
+ }
+ if (sc->data[SC_POEMBRAGI])
+ time -= time * sc->data[SC_POEMBRAGI]->val2 / 100;
+ if (sc->data[SC_IZAYOI])
+ time -= time * 50 / 100;
+ }
+ time = max(time, 0);
+
+// ShowInfo("Castime castfix_sc = %d\n",time);
+ return time;
}
#ifdef RENEWAL_CAST
-int skill_vfcastfix(struct block_list *bl, double time, int skill_id, int skill_lv)
+int skill_vfcastfix (struct block_list *bl, double time, int skill_id, int skill_lv)
{
- struct status_change *sc = status_get_sc(bl);
- struct map_session_data *sd = BL_CAST(BL_PC,bl);
- int fixed = skill_get_fixed_cast(skill_id, skill_lv), fixcast_r = 0, varcast_r = 0, i = 0;
-
- if (time < 0)
- return 0;
-
- if (fixed == 0) {
- fixed = (int)time * 20 / 100; // fixed time
- time = time * 80 / 100; // variable time
- } else if (fixed < 0) // no fixed cast time
- fixed = 0;
-
- if (sd && !(skill_get_castnodex(skill_id, skill_lv)&4)) { // Increases/Decreases fixed/variable cast time of a skill by item/card bonuses.
- if (sd->bonus.varcastrate < 0)
- VARCAST_REDUCTION(sd->bonus.varcastrate);
- for (i = 0; i < ARRAYLENGTH(sd->skillfixcast) && sd->skillfixcast[i].id; i++)
- if (sd->skillfixcast[i].id == skill_id) { // bonus2 bSkillFixedCast
- fixed += sd->skillfixcast[i].val;
- break;
- }
- for (i = 0; i < ARRAYLENGTH(sd->skillvarcast) && sd->skillvarcast[i].id; i++)
- if (sd->skillvarcast[i].id == skill_id) { // bonus2 bSkillVariableCast
- time += sd->skillvarcast[i].val;
- break;
- }
- for (i = 0; i < ARRAYLENGTH(sd->skillcast) && sd->skillcast[i].id; i++)
- if (sd->skillcast[i].id == skill_id) { // bonus2 bVariableCastrate
- if ((i=sd->skillcast[i].val) < 0)
- VARCAST_REDUCTION(i);
- break;
- }
- }
-
- if (sc && sc->count && !(skill_get_castnodex(skill_id, skill_lv)&2)) {
- // All variable cast additive bonuses must come first
- if (sc->data[SC_SLOWCAST])
- VARCAST_REDUCTION(-sc->data[SC_SLOWCAST]->val2);
-
- // Variable cast reduction bonuses
- if (sc->data[SC_SUFFRAGIUM]) {
- VARCAST_REDUCTION(sc->data[SC_SUFFRAGIUM]->val2);
- status_change_end(bl, SC_SUFFRAGIUM, INVALID_TIMER);
- }
- if (sc->data[SC_MEMORIZE]) {
- VARCAST_REDUCTION(50);
- if ((--sc->data[SC_MEMORIZE]->val2) <= 0)
- status_change_end(bl, SC_MEMORIZE, INVALID_TIMER);
- }
- if (sc->data[SC_POEMBRAGI])
- VARCAST_REDUCTION(sc->data[SC_POEMBRAGI]->val2);
- if (sc->data[SC_IZAYOI])
- VARCAST_REDUCTION(50);
- if (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 3 && (skill_get_ele(skill_id, skill_lv) == ELE_WATER))
- VARCAST_REDUCTION(30); //Reduces 30% Variable Cast Time of Water spells.
- // Fixed cast reduction bonuses
- if (sc->data[SC__LAZINESS])
- fixcast_r = max(fixcast_r, sc->data[SC__LAZINESS]->val2);
- if (sc->data[SC_SECRAMENT])
- fixcast_r = max(fixcast_r, sc->data[SC_SECRAMENT]->val2);
- if (sd && (skill_lv = pc_checkskill(sd, WL_RADIUS)) && skill_id >= WL_WHITEIMPRISON && skill_id <= WL_FREEZE_SP)
- fixcast_r = max(fixcast_r, 5 + skill_lv * 5);
- // Fixed cast non percentage bonuses
- if (sc->data[SC_MANDRAGORA] && (skill_id >= SM_BASH && skill_id <= RETURN_TO_ELDICASTES))
- fixed += sc->data[SC_MANDRAGORA]->val1 * 1000 / 2;
- if (sc->data[SC_IZAYOI] && (skill_id >= NJ_TOBIDOUGU && skill_id <= NJ_ISSEN))
- fixed = 0;
- }
-
- if (sd && !(skill_get_castnodex(skill_id, skill_lv)&4)) {
- VARCAST_REDUCTION(max(sd->bonus.varcastrate, 0) + max(i, 0));
- fixcast_r = max(fixcast_r, sd->bonus.fixcastrate) + min(sd->bonus.fixcastrate,0);
- }
-
- if (varcast_r < 0) // now compute overall factors
- time = time * (1 - (float)varcast_r / 100);
- if (!(skill_get_castnodex(skill_id, skill_lv)&1)) // reduction from status point
- time = (1 - sqrt(((float)(status_get_dex(bl)*2 + status_get_int(bl)) / battle_config.vcast_stat_scale))) * time;
- // underflow checking/capping
- time = max(time, 0) + (1 - (float)min(fixcast_r, 100) / 100) * fixed;
-
- // ShowInfo("Casttime vfcastfix = %d\n",time);
- return (int)time;
+ struct status_change *sc = status_get_sc(bl);
+ struct map_session_data *sd = BL_CAST(BL_PC,bl);
+ int fixed = skill_get_fixed_cast(skill_id, skill_lv), fixcast_r = 0, varcast_r = 0, i = 0;
+
+ if( time < 0 )
+ return 0;
+
+ if( fixed == 0 ){
+ fixed = (int)time * 20 / 100; // fixed time
+ time = time * 80 / 100; // variable time
+ }else if( fixed < 0 ) // no fixed cast time
+ fixed = 0;
+
+ if(sd && !(skill_get_castnodex(skill_id, skill_lv)&4) ){ // Increases/Decreases fixed/variable cast time of a skill by item/card bonuses.
+ if( sd->bonus.varcastrate < 0 )
+ VARCAST_REDUCTION(sd->bonus.varcastrate);
+ for (i = 0; i < ARRAYLENGTH(sd->skillfixcast) && sd->skillfixcast[i].id; i++)
+ if (sd->skillfixcast[i].id == skill_id){ // bonus2 bSkillFixedCast
+ fixed += sd->skillfixcast[i].val;
+ break;
+ }
+ for( i = 0; i < ARRAYLENGTH(sd->skillvarcast) && sd->skillvarcast[i].id; i++ )
+ if( sd->skillvarcast[i].id == skill_id ){ // bonus2 bSkillVariableCast
+ time += sd->skillvarcast[i].val;
+ break;
+ }
+ for( i = 0; i < ARRAYLENGTH(sd->skillcast) && sd->skillcast[i].id; i++ )
+ if( sd->skillcast[i].id == skill_id ){ // bonus2 bVariableCastrate
+ if( (i=sd->skillcast[i].val) < 0)
+ VARCAST_REDUCTION(i);
+ break;
+ }
+ }
+
+ if (sc && sc->count && !(skill_get_castnodex(skill_id, skill_lv)&2) ) {
+ // All variable cast additive bonuses must come first
+ if (sc->data[SC_SLOWCAST])
+ VARCAST_REDUCTION(-sc->data[SC_SLOWCAST]->val2);
+
+ // Variable cast reduction bonuses
+ if (sc->data[SC_SUFFRAGIUM]) {
+ VARCAST_REDUCTION(sc->data[SC_SUFFRAGIUM]->val2);
+ status_change_end(bl, SC_SUFFRAGIUM, INVALID_TIMER);
+ }
+ if (sc->data[SC_MEMORIZE]) {
+ VARCAST_REDUCTION(50);
+ if ((--sc->data[SC_MEMORIZE]->val2) <= 0)
+ status_change_end(bl, SC_MEMORIZE, INVALID_TIMER);
+ }
+ if (sc->data[SC_POEMBRAGI])
+ VARCAST_REDUCTION(sc->data[SC_POEMBRAGI]->val2);
+ if (sc->data[SC_IZAYOI])
+ VARCAST_REDUCTION(50);
+ if (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 3 && (skill_get_ele(skill_id, skill_lv) == ELE_WATER))
+ VARCAST_REDUCTION(30); //Reduces 30% Variable Cast Time of Water spells.
+ // Fixed cast reduction bonuses
+ if( sc->data[SC__LAZINESS] )
+ fixcast_r = max(fixcast_r, sc->data[SC__LAZINESS]->val2);
+ if( sc->data[SC_SECRAMENT] )
+ fixcast_r = max(fixcast_r, sc->data[SC_SECRAMENT]->val2);
+ if( sd && ( skill_lv = pc_checkskill(sd, WL_RADIUS) ) && skill_id >= WL_WHITEIMPRISON && skill_id <= WL_FREEZE_SP )
+ fixcast_r = max(fixcast_r, 5 + skill_lv * 5);
+ // Fixed cast non percentage bonuses
+ if( sc->data[SC_MANDRAGORA] && (skill_id >= SM_BASH && skill_id <= RETURN_TO_ELDICASTES) )
+ fixed += sc->data[SC_MANDRAGORA]->val1 * 1000 / 2;
+ if (sc->data[SC_IZAYOI] && (skill_id >= NJ_TOBIDOUGU && skill_id <= NJ_ISSEN))
+ fixed = 0;
+ }
+
+ if( sd && !(skill_get_castnodex(skill_id, skill_lv)&4) ){
+ VARCAST_REDUCTION( max(sd->bonus.varcastrate, 0) + max(i, 0) );
+ fixcast_r = max(fixcast_r, sd->bonus.fixcastrate) + min(sd->bonus.fixcastrate,0);
+ }
+
+ if( varcast_r < 0 ) // now compute overall factors
+ time = time * (1 - (float)varcast_r / 100);
+ if( !(skill_get_castnodex(skill_id, skill_lv)&1) )// reduction from status point
+ time = (1 - sqrt( ((float)(status_get_dex(bl)*2 + status_get_int(bl)) / battle_config.vcast_stat_scale) )) * time;
+ // underflow checking/capping
+ time = max(time, 0) + (1 - (float)min(fixcast_r, 100) / 100) * fixed;
+
+ // ShowInfo("Casttime vfcastfix = %d\n",time);
+ return (int)time;
}
#endif
/*==========================================
* Does delay reductions based on dex/agi, sc data, item bonuses, ...
*------------------------------------------*/
-int skill_delayfix(struct block_list *bl, int skill_id, int skill_lv)
+int skill_delayfix (struct block_list *bl, int skill_id, int skill_lv)
{
- int delaynodex = skill_get_delaynodex(skill_id, skill_lv);
- int time = skill_get_delay(skill_id, skill_lv);
- struct map_session_data *sd;
- struct status_change *sc = status_get_sc(bl);
-
- nullpo_ret(bl);
- sd = BL_CAST(BL_PC, bl);
-
- if (skill_id == SA_ABRACADABRA || skill_id == WM_RANDOMIZESPELL)
- return 0; //Will use picked skill's delay.
-
- if (bl->type&battle_config.no_skill_delay)
- return battle_config.min_skill_delay_limit;
-
- if (time < 0)
- time = -time + status_get_amotion(bl); // If set to <0, add to attack motion.
-
- // Delay reductions
- switch (skill_id) { //Monk combo skills have their delay reduced by agi/dex.
- case MO_TRIPLEATTACK:
- case MO_CHAINCOMBO:
- case MO_COMBOFINISH:
- case CH_TIGERFIST:
- case CH_CHAINCRUSH:
- case SR_DRAGONCOMBO:
- case SR_FALLENEMPIRE:
- time -= 4*status_get_agi(bl) - 2*status_get_dex(bl);
- break;
- case HP_BASILICA:
- if (sc && !sc->data[SC_BASILICA])
- time = 0; // There is no Delay on Basilica creation, only on cancel
- break;
- default:
- if (battle_config.delay_dependon_dex && !(delaynodex&1)) {
- // if skill delay is allowed to be reduced by dex
- int scale = battle_config.castrate_dex_scale - status_get_dex(bl);
- if (scale > 0)
- time = time * scale / battle_config.castrate_dex_scale;
- else //To be capped later to minimum.
- time = 0;
- }
- if (battle_config.delay_dependon_agi && !(delaynodex&1)) {
- // if skill delay is allowed to be reduced by agi
- int scale = battle_config.castrate_dex_scale - status_get_agi(bl);
- if (scale > 0)
- time = time * scale / battle_config.castrate_dex_scale;
- else //To be capped later to minimum.
- time = 0;
- }
- }
-
- if (sc && sc->data[SC_SPIRIT]) {
- switch (skill_id) {
- case CR_SHIELDBOOMERANG:
- if (sc->data[SC_SPIRIT]->val2 == SL_CRUSADER)
- time /= 2;
- break;
- case AS_SONICBLOW:
- if (!map_flag_gvg(bl->m) && !map[bl->m].flag.battleground && sc->data[SC_SPIRIT]->val2 == SL_ASSASIN)
- time /= 2;
- break;
- }
- }
-
- if (!(delaynodex&2)) {
- if (sc && sc->count) {
- if (sc->data[SC_POEMBRAGI])
- time -= time * sc->data[SC_POEMBRAGI]->val3 / 100;
- if (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 3 && (skill_get_ele(skill_id, skill_lv) == ELE_WIND))
- time /= 2; // After Delay of Wind element spells reduced by 50%.
- }
-
- }
-
- if (!(delaynodex&4) && sd && sd->delayrate != 100)
- time = time * sd->delayrate / 100;
-
- if (battle_config.delay_rate != 100)
- time = time * battle_config.delay_rate / 100;
-
- //min delay
- time = max(time, status_get_amotion(bl)); // Delay can never be below amotion [Playtester]
- time = max(time, battle_config.min_skill_delay_limit);
-
- // ShowInfo("Delay delayfix = %d\n",time);
- return time;
+ int delaynodex = skill_get_delaynodex(skill_id, skill_lv);
+ int time = skill_get_delay(skill_id, skill_lv);
+ struct map_session_data *sd;
+ struct status_change *sc = status_get_sc(bl);
+
+ nullpo_ret(bl);
+ sd = BL_CAST(BL_PC, bl);
+
+ if (skill_id == SA_ABRACADABRA || skill_id == WM_RANDOMIZESPELL)
+ return 0; //Will use picked skill's delay.
+
+ if (bl->type&battle_config.no_skill_delay)
+ return battle_config.min_skill_delay_limit;
+
+ if (time < 0)
+ time = -time + status_get_amotion(bl); // If set to <0, add to attack motion.
+
+ // Delay reductions
+ switch (skill_id) { //Monk combo skills have their delay reduced by agi/dex.
+ case MO_TRIPLEATTACK:
+ case MO_CHAINCOMBO:
+ case MO_COMBOFINISH:
+ case CH_TIGERFIST:
+ case CH_CHAINCRUSH:
+ case SR_DRAGONCOMBO:
+ case SR_FALLENEMPIRE:
+ time -= 4*status_get_agi(bl) - 2*status_get_dex(bl);
+ break;
+ case HP_BASILICA:
+ if( sc && !sc->data[SC_BASILICA] )
+ time = 0; // There is no Delay on Basilica creation, only on cancel
+ break;
+ default:
+ if (battle_config.delay_dependon_dex && !(delaynodex&1))
+ { // if skill delay is allowed to be reduced by dex
+ int scale = battle_config.castrate_dex_scale - status_get_dex(bl);
+ if (scale > 0)
+ time = time * scale / battle_config.castrate_dex_scale;
+ else //To be capped later to minimum.
+ time = 0;
+ }
+ if (battle_config.delay_dependon_agi && !(delaynodex&1))
+ { // if skill delay is allowed to be reduced by agi
+ int scale = battle_config.castrate_dex_scale - status_get_agi(bl);
+ if (scale > 0)
+ time = time * scale / battle_config.castrate_dex_scale;
+ else //To be capped later to minimum.
+ time = 0;
+ }
+ }
+
+ if ( sc && sc->data[SC_SPIRIT] )
+ {
+ switch (skill_id) {
+ case CR_SHIELDBOOMERANG:
+ if (sc->data[SC_SPIRIT]->val2 == SL_CRUSADER)
+ time /= 2;
+ break;
+ case AS_SONICBLOW:
+ if (!map_flag_gvg(bl->m) && !map[bl->m].flag.battleground && sc->data[SC_SPIRIT]->val2 == SL_ASSASIN)
+ time /= 2;
+ break;
+ }
+ }
+
+ if (!(delaynodex&2))
+ {
+ if (sc && sc->count) {
+ if (sc->data[SC_POEMBRAGI])
+ time -= time * sc->data[SC_POEMBRAGI]->val3 / 100;
+ if (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 3 && (skill_get_ele(skill_id, skill_lv) == ELE_WIND))
+ time /= 2; // After Delay of Wind element spells reduced by 50%.
+ }
+
+ }
+
+ if( !(delaynodex&4) && sd && sd->delayrate != 100 )
+ time = time * sd->delayrate / 100;
+
+ if (battle_config.delay_rate != 100)
+ time = time * battle_config.delay_rate / 100;
+
+ //min delay
+ time = max(time, status_get_amotion(bl)); // Delay can never be below amotion [Playtester]
+ time = max(time, battle_config.min_skill_delay_limit);
+
+// ShowInfo("Delay delayfix = %d\n",time);
+ return time;
}
/*=========================================
*
*-----------------------------------------*/
struct square {
- int val1[5];
- int val2[5];
+ int val1[5];
+ int val2[5];
};
-static void skill_brandishspear_first(struct square *tc, int dir, int x, int y)
+static void skill_brandishspear_first (struct square *tc, int dir, int x, int y)
{
- nullpo_retv(tc);
-
- if (dir == 0) {
- tc->val1[0]=x-2;
- tc->val1[1]=x-1;
- tc->val1[2]=x;
- tc->val1[3]=x+1;
- tc->val1[4]=x+2;
- tc->val2[0]=
- tc->val2[1]=
- tc->val2[2]=
- tc->val2[3]=
- tc->val2[4]=y-1;
- } else if (dir==2) {
- tc->val1[0]=
- tc->val1[1]=
- tc->val1[2]=
- tc->val1[3]=
- tc->val1[4]=x+1;
- tc->val2[0]=y+2;
- tc->val2[1]=y+1;
- tc->val2[2]=y;
- tc->val2[3]=y-1;
- tc->val2[4]=y-2;
- } else if (dir==4) {
- tc->val1[0]=x-2;
- tc->val1[1]=x-1;
- tc->val1[2]=x;
- tc->val1[3]=x+1;
- tc->val1[4]=x+2;
- tc->val2[0]=
- tc->val2[1]=
- tc->val2[2]=
- tc->val2[3]=
- tc->val2[4]=y+1;
- } else if (dir==6) {
- tc->val1[0]=
- tc->val1[1]=
- tc->val1[2]=
- tc->val1[3]=
- tc->val1[4]=x-1;
- tc->val2[0]=y+2;
- tc->val2[1]=y+1;
- tc->val2[2]=y;
- tc->val2[3]=y-1;
- tc->val2[4]=y-2;
- } else if (dir==1) {
- tc->val1[0]=x-1;
- tc->val1[1]=x;
- tc->val1[2]=x+1;
- tc->val1[3]=x+2;
- tc->val1[4]=x+3;
- tc->val2[0]=y-4;
- tc->val2[1]=y-3;
- tc->val2[2]=y-1;
- tc->val2[3]=y;
- tc->val2[4]=y+1;
- } else if (dir==3) {
- tc->val1[0]=x+3;
- tc->val1[1]=x+2;
- tc->val1[2]=x+1;
- tc->val1[3]=x;
- tc->val1[4]=x-1;
- tc->val2[0]=y-1;
- tc->val2[1]=y;
- tc->val2[2]=y+1;
- tc->val2[3]=y+2;
- tc->val2[4]=y+3;
- } else if (dir==5) {
- tc->val1[0]=x+1;
- tc->val1[1]=x;
- tc->val1[2]=x-1;
- tc->val1[3]=x-2;
- tc->val1[4]=x-3;
- tc->val2[0]=y+3;
- tc->val2[1]=y+2;
- tc->val2[2]=y+1;
- tc->val2[3]=y;
- tc->val2[4]=y-1;
- } else if (dir==7) {
- tc->val1[0]=x-3;
- tc->val1[1]=x-2;
- tc->val1[2]=x-1;
- tc->val1[3]=x;
- tc->val1[4]=x+1;
- tc->val2[1]=y;
- tc->val2[0]=y+1;
- tc->val2[2]=y-1;
- tc->val2[3]=y-2;
- tc->val2[4]=y-3;
- }
+ nullpo_retv(tc);
+
+ if(dir == 0){
+ tc->val1[0]=x-2;
+ tc->val1[1]=x-1;
+ tc->val1[2]=x;
+ tc->val1[3]=x+1;
+ tc->val1[4]=x+2;
+ tc->val2[0]=
+ tc->val2[1]=
+ tc->val2[2]=
+ tc->val2[3]=
+ tc->val2[4]=y-1;
+ }
+ else if(dir==2){
+ tc->val1[0]=
+ tc->val1[1]=
+ tc->val1[2]=
+ tc->val1[3]=
+ tc->val1[4]=x+1;
+ tc->val2[0]=y+2;
+ tc->val2[1]=y+1;
+ tc->val2[2]=y;
+ tc->val2[3]=y-1;
+ tc->val2[4]=y-2;
+ }
+ else if(dir==4){
+ tc->val1[0]=x-2;
+ tc->val1[1]=x-1;
+ tc->val1[2]=x;
+ tc->val1[3]=x+1;
+ tc->val1[4]=x+2;
+ tc->val2[0]=
+ tc->val2[1]=
+ tc->val2[2]=
+ tc->val2[3]=
+ tc->val2[4]=y+1;
+ }
+ else if(dir==6){
+ tc->val1[0]=
+ tc->val1[1]=
+ tc->val1[2]=
+ tc->val1[3]=
+ tc->val1[4]=x-1;
+ tc->val2[0]=y+2;
+ tc->val2[1]=y+1;
+ tc->val2[2]=y;
+ tc->val2[3]=y-1;
+ tc->val2[4]=y-2;
+ }
+ else if(dir==1){
+ tc->val1[0]=x-1;
+ tc->val1[1]=x;
+ tc->val1[2]=x+1;
+ tc->val1[3]=x+2;
+ tc->val1[4]=x+3;
+ tc->val2[0]=y-4;
+ tc->val2[1]=y-3;
+ tc->val2[2]=y-1;
+ tc->val2[3]=y;
+ tc->val2[4]=y+1;
+ }
+ else if(dir==3){
+ tc->val1[0]=x+3;
+ tc->val1[1]=x+2;
+ tc->val1[2]=x+1;
+ tc->val1[3]=x;
+ tc->val1[4]=x-1;
+ tc->val2[0]=y-1;
+ tc->val2[1]=y;
+ tc->val2[2]=y+1;
+ tc->val2[3]=y+2;
+ tc->val2[4]=y+3;
+ }
+ else if(dir==5){
+ tc->val1[0]=x+1;
+ tc->val1[1]=x;
+ tc->val1[2]=x-1;
+ tc->val1[3]=x-2;
+ tc->val1[4]=x-3;
+ tc->val2[0]=y+3;
+ tc->val2[1]=y+2;
+ tc->val2[2]=y+1;
+ tc->val2[3]=y;
+ tc->val2[4]=y-1;
+ }
+ else if(dir==7){
+ tc->val1[0]=x-3;
+ tc->val1[1]=x-2;
+ tc->val1[2]=x-1;
+ tc->val1[3]=x;
+ tc->val1[4]=x+1;
+ tc->val2[1]=y;
+ tc->val2[0]=y+1;
+ tc->val2[2]=y-1;
+ tc->val2[3]=y-2;
+ tc->val2[4]=y-3;
+ }
}
-static void skill_brandishspear_dir(struct square *tc, int dir, int are)
+static void skill_brandishspear_dir (struct square* tc, int dir, int are)
{
- int c;
- nullpo_retv(tc);
-
- for (c = 0; c < 5; c++) {
- switch (dir) {
- case 0:
- tc->val2[c]+=are;
- break;
- case 1:
- tc->val1[c]-=are;
- tc->val2[c]+=are;
- break;
- case 2:
- tc->val1[c]-=are;
- break;
- case 3:
- tc->val1[c]-=are;
- tc->val2[c]-=are;
- break;
- case 4:
- tc->val2[c]-=are;
- break;
- case 5:
- tc->val1[c]+=are;
- tc->val2[c]-=are;
- break;
- case 6:
- tc->val1[c]+=are;
- break;
- case 7:
- tc->val1[c]+=are;
- tc->val2[c]+=are;
- break;
- }
- }
+ int c;
+ nullpo_retv(tc);
+
+ for( c = 0; c < 5; c++ )
+ {
+ switch( dir )
+ {
+ case 0: tc->val2[c]+=are; break;
+ case 1: tc->val1[c]-=are; tc->val2[c]+=are; break;
+ case 2: tc->val1[c]-=are; break;
+ case 3: tc->val1[c]-=are; tc->val2[c]-=are; break;
+ case 4: tc->val2[c]-=are; break;
+ case 5: tc->val1[c]+=are; tc->val2[c]-=are; break;
+ case 6: tc->val1[c]+=are; break;
+ case 7: tc->val1[c]+=are; tc->val2[c]+=are; break;
+ }
+ }
}
-void skill_brandishspear(struct block_list *src, struct block_list *bl, int skillid, int skilllv, unsigned int tick, int flag)
+void skill_brandishspear(struct block_list* src, struct block_list* bl, int skillid, int skilllv, unsigned int tick, int flag)
{
- int c,n=4;
- int dir = map_calc_dir(src,bl->x,bl->y);
- struct square tc;
- int x=bl->x,y=bl->y;
- skill_brandishspear_first(&tc,dir,x,y);
- skill_brandishspear_dir(&tc,dir,4);
- skill_area_temp[1] = bl->id;
-
- if (skilllv > 9) {
- for (c=1; c<4; c++) {
- map_foreachincell(skill_area_sub,
- bl->m,tc.val1[c],tc.val2[c],BL_CHAR,
- src,skillid,skilllv,tick, flag|BCT_ENEMY|n,
- skill_castend_damage_id);
- }
- }
- if (skilllv > 6) {
- skill_brandishspear_dir(&tc,dir,-1);
- n--;
- } else {
- skill_brandishspear_dir(&tc,dir,-2);
- n-=2;
- }
-
- if (skilllv > 3) {
- for (c=0; c<5; c++) {
- map_foreachincell(skill_area_sub,
- bl->m,tc.val1[c],tc.val2[c],BL_CHAR,
- src,skillid,skilllv,tick, flag|BCT_ENEMY|n,
- skill_castend_damage_id);
- if (skilllv > 6 && n==3 && c==4) {
- skill_brandishspear_dir(&tc,dir,-1);
- n--;
- c=-1;
- }
- }
- }
- for (c=0; c<10; c++) {
- if (c==0||c==5) skill_brandishspear_dir(&tc,dir,-1);
- map_foreachincell(skill_area_sub,
- bl->m,tc.val1[c%5],tc.val2[c%5],BL_CHAR,
- src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
- skill_castend_damage_id);
- }
+ int c,n=4;
+ int dir = map_calc_dir(src,bl->x,bl->y);
+ struct square tc;
+ int x=bl->x,y=bl->y;
+ skill_brandishspear_first(&tc,dir,x,y);
+ skill_brandishspear_dir(&tc,dir,4);
+ skill_area_temp[1] = bl->id;
+
+ if(skilllv > 9){
+ for(c=1;c<4;c++){
+ map_foreachincell(skill_area_sub,
+ bl->m,tc.val1[c],tc.val2[c],BL_CHAR,
+ src,skillid,skilllv,tick, flag|BCT_ENEMY|n,
+ skill_castend_damage_id);
+ }
+ }
+ if(skilllv > 6){
+ skill_brandishspear_dir(&tc,dir,-1);
+ n--;
+ }else{
+ skill_brandishspear_dir(&tc,dir,-2);
+ n-=2;
+ }
+
+ if(skilllv > 3){
+ for(c=0;c<5;c++){
+ map_foreachincell(skill_area_sub,
+ bl->m,tc.val1[c],tc.val2[c],BL_CHAR,
+ src,skillid,skilllv,tick, flag|BCT_ENEMY|n,
+ skill_castend_damage_id);
+ if(skilllv > 6 && n==3 && c==4){
+ skill_brandishspear_dir(&tc,dir,-1);
+ n--;c=-1;
+ }
+ }
+ }
+ for(c=0;c<10;c++){
+ if(c==0||c==5) skill_brandishspear_dir(&tc,dir,-1);
+ map_foreachincell(skill_area_sub,
+ bl->m,tc.val1[c%5],tc.val2[c%5],BL_CHAR,
+ src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
+ skill_castend_damage_id);
+ }
}
/*==========================================
* Weapon Repair [Celest/DracoRPG]
*------------------------------------------*/
-void skill_repairweapon(struct map_session_data *sd, int idx)
-{
- int material;
- int materials[4] = { 1002, 998, 999, 756 };
- struct item *item;
- struct map_session_data *target_sd;
+void skill_repairweapon (struct map_session_data *sd, int idx) {
+ int material;
+ int materials[4] = { 1002, 998, 999, 756 };
+ struct item *item;
+ struct map_session_data *target_sd;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- if (!(target_sd = map_id2sd(sd->menuskill_val))) //Failed....
- return;
+ if ( !( target_sd = map_id2sd(sd->menuskill_val) ) ) //Failed....
+ return;
- if (idx == 0xFFFF) // No item selected ('Cancel' clicked)
- return;
- if (idx < 0 || idx >= MAX_INVENTORY)
- return; //Invalid index??
+ if( idx == 0xFFFF ) // No item selected ('Cancel' clicked)
+ return;
+ if( idx < 0 || idx >= MAX_INVENTORY )
+ return; //Invalid index??
- item = &target_sd->status.inventory[idx];
- if (item->nameid <= 0 || item->attribute == 0)
- return; //Again invalid item....
+ item = &target_sd->status.inventory[idx];
+ if( item->nameid <= 0 || item->attribute == 0 )
+ return; //Again invalid item....
- if (sd != target_sd && !battle_check_range(&sd->bl,&target_sd->bl, skill_get_range2(&sd->bl, sd->menuskill_id,sd->menuskill_val2))) {
- clif_item_repaireffect(sd,idx,1);
- return;
- }
+ if( sd != target_sd && !battle_check_range(&sd->bl,&target_sd->bl, skill_get_range2(&sd->bl, sd->menuskill_id,sd->menuskill_val2) ) ){
+ clif_item_repaireffect(sd,idx,1);
+ return;
+ }
- if (target_sd->inventory_data[idx]->type == IT_WEAPON)
- material = materials [ target_sd->inventory_data[idx]->wlv - 1 ]; // Lv1/2/3/4 weapons consume 1 Iron Ore/Iron/Steel/Rough Oridecon
- else
- material = materials [2]; // Armors consume 1 Steel
- if (pc_search_inventory(sd,material) < 0) {
- clif_skill_fail(sd,sd->menuskill_id,USESKILL_FAIL_LEVEL,0);
- return;
- }
+ if ( target_sd->inventory_data[idx]->type == IT_WEAPON )
+ material = materials [ target_sd->inventory_data[idx]->wlv - 1 ]; // Lv1/2/3/4 weapons consume 1 Iron Ore/Iron/Steel/Rough Oridecon
+ else
+ material = materials [2]; // Armors consume 1 Steel
+ if ( pc_search_inventory(sd,material) < 0 ) {
+ clif_skill_fail(sd,sd->menuskill_id,USESKILL_FAIL_LEVEL,0);
+ return;
+ }
- clif_skill_nodamage(&sd->bl,&target_sd->bl,sd->menuskill_id,1,1);
+ clif_skill_nodamage(&sd->bl,&target_sd->bl,sd->menuskill_id,1,1);
- item->attribute = 0;/* clear broken state */
+ item->attribute = 0;/* clear broken state */
- clif_equiplist(target_sd);
+ clif_equiplist(target_sd);
- pc_delitem(sd,pc_search_inventory(sd,material),1,0,0,LOG_TYPE_CONSUME);
+ pc_delitem(sd,pc_search_inventory(sd,material),1,0,0,LOG_TYPE_CONSUME);
- clif_item_repaireffect(sd,idx,0);
+ clif_item_repaireffect(sd,idx,0);
- if (sd != target_sd)
- clif_item_repaireffect(target_sd,idx,0);
+ if( sd != target_sd )
+ clif_item_repaireffect(target_sd,idx,0);
}
/*==========================================
* Item Appraisal
*------------------------------------------*/
-void skill_identify(struct map_session_data *sd, int idx)
+void skill_identify (struct map_session_data *sd, int idx)
{
- int flag=1;
+ int flag=1;
- nullpo_retv(sd);
+ nullpo_retv(sd);
- if (idx >= 0 && idx < MAX_INVENTORY) {
- if (sd->status.inventory[idx].nameid > 0 && sd->status.inventory[idx].identify == 0) {
- flag=0;
- sd->status.inventory[idx].identify=1;
- }
- }
- clif_item_identified(sd,idx,flag);
+ if(idx >= 0 && idx < MAX_INVENTORY) {
+ if(sd->status.inventory[idx].nameid > 0 && sd->status.inventory[idx].identify == 0 ){
+ flag=0;
+ sd->status.inventory[idx].identify=1;
+ }
+ }
+ clif_item_identified(sd,idx,flag);
}
/*==========================================
* Weapon Refine [Celest]
*------------------------------------------*/
-void skill_weaponrefine(struct map_session_data *sd, int idx)
+void skill_weaponrefine (struct map_session_data *sd, int idx)
{
- nullpo_retv(sd);
-
- if (idx >= 0 && idx < MAX_INVENTORY) {
- int i = 0, ep = 0, per;
- int material[5] = { 0, 1010, 1011, 984, 984 };
- struct item *item;
- struct item_data *ditem = sd->inventory_data[idx];
- item = &sd->status.inventory[idx];
-
- if (item->nameid > 0 && ditem->type == IT_WEAPON) {
- if (item->refine >= sd->menuskill_val
- || item->refine >= 10 // if it's no longer refineable
- || ditem->flag.no_refine // if the item isn't refinable
- || (i = pc_search_inventory(sd, material [ditem->wlv])) < 0) {
- clif_skill_fail(sd,sd->menuskill_id,USESKILL_FAIL_LEVEL,0);
- return;
- }
+ nullpo_retv(sd);
+
+ if (idx >= 0 && idx < MAX_INVENTORY)
+ {
+ int i = 0, ep = 0, per;
+ int material[5] = { 0, 1010, 1011, 984, 984 };
+ struct item *item;
+ struct item_data *ditem = sd->inventory_data[idx];
+ item = &sd->status.inventory[idx];
+
+ if(item->nameid > 0 && ditem->type == IT_WEAPON)
+ {
+ if( item->refine >= sd->menuskill_val
+ || item->refine >= 10 // if it's no longer refineable
+ || ditem->flag.no_refine // if the item isn't refinable
+ || (i = pc_search_inventory(sd, material [ditem->wlv])) < 0 )
+ {
+ clif_skill_fail(sd,sd->menuskill_id,USESKILL_FAIL_LEVEL,0);
+ return;
+ }
- per = status_get_refine_chance(ditem->wlv, (int)item->refine);
- per += (((signed int)sd->status.job_level)-50)/2; //Updated per the new kro descriptions. [Skotlex]
-
- pc_delitem(sd, i, 1, 0, 0, LOG_TYPE_OTHER);
- if (per > rnd() % 100) {
- log_pick_pc(sd, LOG_TYPE_OTHER, -1, item);
- item->refine++;
- log_pick_pc(sd, LOG_TYPE_OTHER, 1, item);
- if (item->equip) {
- ep = item->equip;
- pc_unequipitem(sd,idx,3);
- }
- clif_refine(sd->fd,0,idx,item->refine);
- clif_delitem(sd,idx,1,3);
- clif_additem(sd,idx,1,0);
- if (ep)
- pc_equipitem(sd,idx,ep);
- clif_misceffect(&sd->bl,3);
- if (item->refine == 10 &&
- item->card[0] == CARD0_FORGE &&
- (int)MakeDWord(item->card[2],item->card[3]) == sd->status.char_id) {
- // Fame point system [DracoRPG]
- switch (ditem->wlv) {
- case 1:
- pc_addfame(sd,1); // Success to refine to +10 a lv1 weapon you forged = +1 fame point
- break;
- case 2:
- pc_addfame(sd,25); // Success to refine to +10 a lv2 weapon you forged = +25 fame point
- break;
- case 3:
- pc_addfame(sd,1000); // Success to refine to +10 a lv3 weapon you forged = +1000 fame point
- break;
- }
- }
- } else {
- item->refine = 0;
- if (item->equip)
- pc_unequipitem(sd,idx,3);
- clif_refine(sd->fd,1,idx,item->refine);
- pc_delitem(sd,idx,1,0,2, LOG_TYPE_OTHER);
- clif_misceffect(&sd->bl,2);
- clif_emotion(&sd->bl, E_OMG);
- }
- }
- }
+ per = status_get_refine_chance(ditem->wlv, (int)item->refine);
+ per += (((signed int)sd->status.job_level)-50)/2; //Updated per the new kro descriptions. [Skotlex]
+
+ pc_delitem(sd, i, 1, 0, 0, LOG_TYPE_OTHER);
+ if (per > rnd() % 100) {
+ log_pick_pc(sd, LOG_TYPE_OTHER, -1, item);
+ item->refine++;
+ log_pick_pc(sd, LOG_TYPE_OTHER, 1, item);
+ if(item->equip) {
+ ep = item->equip;
+ pc_unequipitem(sd,idx,3);
+ }
+ clif_refine(sd->fd,0,idx,item->refine);
+ clif_delitem(sd,idx,1,3);
+ clif_additem(sd,idx,1,0);
+ if (ep)
+ pc_equipitem(sd,idx,ep);
+ clif_misceffect(&sd->bl,3);
+ if(item->refine == 10 &&
+ item->card[0] == CARD0_FORGE &&
+ (int)MakeDWord(item->card[2],item->card[3]) == sd->status.char_id)
+ { // Fame point system [DracoRPG]
+ switch(ditem->wlv){
+ case 1:
+ pc_addfame(sd,1); // Success to refine to +10 a lv1 weapon you forged = +1 fame point
+ break;
+ case 2:
+ pc_addfame(sd,25); // Success to refine to +10 a lv2 weapon you forged = +25 fame point
+ break;
+ case 3:
+ pc_addfame(sd,1000); // Success to refine to +10 a lv3 weapon you forged = +1000 fame point
+ break;
+ }
+ }
+ } else {
+ item->refine = 0;
+ if(item->equip)
+ pc_unequipitem(sd,idx,3);
+ clif_refine(sd->fd,1,idx,item->refine);
+ pc_delitem(sd,idx,1,0,2, LOG_TYPE_OTHER);
+ clif_misceffect(&sd->bl,2);
+ clif_emotion(&sd->bl, E_OMG);
+ }
+ }
+ }
}
/*==========================================
*
*------------------------------------------*/
-int skill_autospell(struct map_session_data *sd, int skillid)
+int skill_autospell (struct map_session_data *sd, int skillid)
{
- int skilllv;
- int maxlv=1,lv;
-
- nullpo_ret(sd);
-
- skilllv = sd->menuskill_val;
- lv=pc_checkskill(sd,skillid);
-
- if (skilllv <= 0 || !lv) return 0; // Player must learn the skill before doing auto-spell [Lance]
-
- if (skillid==MG_NAPALMBEAT) maxlv=3;
- else if (skillid==MG_COLDBOLT || skillid==MG_FIREBOLT || skillid==MG_LIGHTNINGBOLT) {
- if (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_SAGE)
- maxlv =10; //Soul Linker bonus. [Skotlex]
- else if (skilllv==2) maxlv=1;
- else if (skilllv==3) maxlv=2;
- else if (skilllv>=4) maxlv=3;
- } else if (skillid==MG_SOULSTRIKE) {
- if (skilllv==5) maxlv=1;
- else if (skilllv==6) maxlv=2;
- else if (skilllv>=7) maxlv=3;
- } else if (skillid==MG_FIREBALL) {
- if (skilllv==8) maxlv=1;
- else if (skilllv>=9) maxlv=2;
- } else if (skillid==MG_FROSTDIVER) maxlv=1;
- else return 0;
-
- if (maxlv > lv)
- maxlv = lv;
-
- sc_start4(&sd->bl,SC_AUTOSPELL,100,skilllv,skillid,maxlv,0,
- skill_get_time(SA_AUTOSPELL,skilllv));
- return 0;
+ int skilllv;
+ int maxlv=1,lv;
+
+ nullpo_ret(sd);
+
+ skilllv = sd->menuskill_val;
+ lv=pc_checkskill(sd,skillid);
+
+ if(skilllv <= 0 || !lv) return 0; // Player must learn the skill before doing auto-spell [Lance]
+
+ if(skillid==MG_NAPALMBEAT) maxlv=3;
+ else if(skillid==MG_COLDBOLT || skillid==MG_FIREBOLT || skillid==MG_LIGHTNINGBOLT){
+ if (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_SAGE)
+ maxlv =10; //Soul Linker bonus. [Skotlex]
+ else if(skilllv==2) maxlv=1;
+ else if(skilllv==3) maxlv=2;
+ else if(skilllv>=4) maxlv=3;
+ }
+ else if(skillid==MG_SOULSTRIKE){
+ if(skilllv==5) maxlv=1;
+ else if(skilllv==6) maxlv=2;
+ else if(skilllv>=7) maxlv=3;
+ }
+ else if(skillid==MG_FIREBALL){
+ if(skilllv==8) maxlv=1;
+ else if(skilllv>=9) maxlv=2;
+ }
+ else if(skillid==MG_FROSTDIVER) maxlv=1;
+ else return 0;
+
+ if(maxlv > lv)
+ maxlv = lv;
+
+ sc_start4(&sd->bl,SC_AUTOSPELL,100,skilllv,skillid,maxlv,0,
+ skill_get_time(SA_AUTOSPELL,skilllv));
+ return 0;
}
/*==========================================
* Sitting skills functions.
*------------------------------------------*/
-static int skill_sit_count(struct block_list *bl, va_list ap)
+static int skill_sit_count (struct block_list *bl, va_list ap)
{
- struct map_session_data *sd;
- int type =va_arg(ap,int);
- sd=(struct map_session_data *)bl;
+ struct map_session_data *sd;
+ int type =va_arg(ap,int);
+ sd=(struct map_session_data*)bl;
- if (!pc_issit(sd))
- return 0;
+ if(!pc_issit(sd))
+ return 0;
- if (type&1 && pc_checkskill(sd,RG_GANGSTER) > 0)
- return 1;
+ if(type&1 && pc_checkskill(sd,RG_GANGSTER) > 0)
+ return 1;
- if (type&2 && (pc_checkskill(sd,TK_HPTIME) > 0 || pc_checkskill(sd,TK_SPTIME) > 0))
- return 1;
+ if(type&2 && (pc_checkskill(sd,TK_HPTIME) > 0 || pc_checkskill(sd,TK_SPTIME) > 0))
+ return 1;
- return 0;
+ return 0;
}
-static int skill_sit_in(struct block_list *bl, va_list ap)
+static int skill_sit_in (struct block_list *bl, va_list ap)
{
- struct map_session_data *sd;
- int type =va_arg(ap,int);
+ struct map_session_data *sd;
+ int type =va_arg(ap,int);
- sd=(struct map_session_data *)bl;
+ sd=(struct map_session_data*)bl;
- if (!pc_issit(sd))
- return 0;
+ if(!pc_issit(sd))
+ return 0;
- if (type&1 && pc_checkskill(sd,RG_GANGSTER) > 0)
- sd->state.gangsterparadise=1;
+ if(type&1 && pc_checkskill(sd,RG_GANGSTER) > 0)
+ sd->state.gangsterparadise=1;
- if (type&2 && (pc_checkskill(sd,TK_HPTIME) > 0 || pc_checkskill(sd,TK_SPTIME) > 0)) {
- sd->state.rest=1;
- status_calc_regen(bl, &sd->battle_status, &sd->regen);
- status_calc_regen_rate(bl, &sd->regen, &sd->sc);
- }
+ if(type&2 && (pc_checkskill(sd,TK_HPTIME) > 0 || pc_checkskill(sd,TK_SPTIME) > 0 ))
+ {
+ sd->state.rest=1;
+ status_calc_regen(bl, &sd->battle_status, &sd->regen);
+ status_calc_regen_rate(bl, &sd->regen, &sd->sc);
+ }
- return 0;
+ return 0;
}
-static int skill_sit_out(struct block_list *bl, va_list ap)
+static int skill_sit_out (struct block_list *bl, va_list ap)
{
- struct map_session_data *sd;
- int type =va_arg(ap,int);
- sd=(struct map_session_data *)bl;
- if (sd->state.gangsterparadise && type&1)
- sd->state.gangsterparadise=0;
- if (sd->state.rest && type&2) {
- sd->state.rest=0;
- status_calc_regen(bl, &sd->battle_status, &sd->regen);
- status_calc_regen_rate(bl, &sd->regen, &sd->sc);
- }
- return 0;
+ struct map_session_data *sd;
+ int type =va_arg(ap,int);
+ sd=(struct map_session_data*)bl;
+ if(sd->state.gangsterparadise && type&1)
+ sd->state.gangsterparadise=0;
+ if(sd->state.rest && type&2) {
+ sd->state.rest=0;
+ status_calc_regen(bl, &sd->battle_status, &sd->regen);
+ status_calc_regen_rate(bl, &sd->regen, &sd->sc);
+ }
+ return 0;
}
-int skill_sit(struct map_session_data *sd, int type)
+int skill_sit (struct map_session_data *sd, int type)
{
- int flag = 0;
- int range = 0, lv;
- nullpo_ret(sd);
-
-
- if ((lv = pc_checkskill(sd,RG_GANGSTER)) > 0) {
- flag|=1;
- range = skill_get_splash(RG_GANGSTER, lv);
- }
- if ((lv = pc_checkskill(sd,TK_HPTIME)) > 0) {
- flag|=2;
- range = skill_get_splash(TK_HPTIME, lv);
- } else if ((lv = pc_checkskill(sd,TK_SPTIME)) > 0) {
- flag|=2;
- range = skill_get_splash(TK_SPTIME, lv);
- }
-
- if (type) {
- clif_status_load(&sd->bl,SI_SIT,1);
- } else {
- clif_status_load(&sd->bl,SI_SIT,0);
- }
-
- if (!flag) return 0;
-
- if (type) {
- if (map_foreachinrange(skill_sit_count,&sd->bl, range, BL_PC, flag) > 1)
- map_foreachinrange(skill_sit_in,&sd->bl, range, BL_PC, flag);
- } else {
- if (map_foreachinrange(skill_sit_count,&sd->bl, range, BL_PC, flag) < 2)
- map_foreachinrange(skill_sit_out,&sd->bl, range, BL_PC, flag);
- }
- return 0;
+ int flag = 0;
+ int range = 0, lv;
+ nullpo_ret(sd);
+
+
+ if((lv = pc_checkskill(sd,RG_GANGSTER)) > 0) {
+ flag|=1;
+ range = skill_get_splash(RG_GANGSTER, lv);
+ }
+ if((lv = pc_checkskill(sd,TK_HPTIME)) > 0) {
+ flag|=2;
+ range = skill_get_splash(TK_HPTIME, lv);
+ }
+ else if ((lv = pc_checkskill(sd,TK_SPTIME)) > 0) {
+ flag|=2;
+ range = skill_get_splash(TK_SPTIME, lv);
+ }
+
+ if( type ) {
+ clif_status_load(&sd->bl,SI_SIT,1);
+ } else {
+ clif_status_load(&sd->bl,SI_SIT,0);
+ }
+
+ if (!flag) return 0;
+
+ if(type) {
+ if (map_foreachinrange(skill_sit_count,&sd->bl, range, BL_PC, flag) > 1)
+ map_foreachinrange(skill_sit_in,&sd->bl, range, BL_PC, flag);
+ } else {
+ if (map_foreachinrange(skill_sit_count,&sd->bl, range, BL_PC, flag) < 2)
+ map_foreachinrange(skill_sit_out,&sd->bl, range, BL_PC, flag);
+ }
+ return 0;
}
/*==========================================
*
*------------------------------------------*/
-int skill_frostjoke_scream(struct block_list *bl, va_list ap)
+int skill_frostjoke_scream (struct block_list *bl, va_list ap)
{
- struct block_list *src;
- int skillnum,skilllv;
- unsigned int tick;
-
- nullpo_ret(bl);
- nullpo_ret(src=va_arg(ap,struct block_list *));
-
- skillnum=va_arg(ap,int);
- skilllv=va_arg(ap,int);
- if (skilllv <= 0) return 0;
- tick=va_arg(ap,unsigned int);
-
- if (src == bl || status_isdead(bl))
- return 0;
- if (bl->type == BL_PC) {
- struct map_session_data *sd = (struct map_session_data *)bl;
- if (sd && sd->sc.option&(OPTION_INVISIBLE|OPTION_MADOGEAR))
- return 0;//Frost Joke / Scream cannot target invisible or MADO Gear characters [Ind]
- }
- //It has been reported that Scream/Joke works the same regardless of woe-setting. [Skotlex]
- if (battle_check_target(src,bl,BCT_ENEMY) > 0)
- skill_additional_effect(src,bl,skillnum,skilllv,BF_MISC,ATK_DEF,tick);
- else if (battle_check_target(src,bl,BCT_PARTY) > 0 && rnd()%100 < 10)
- skill_additional_effect(src,bl,skillnum,skilllv,BF_MISC,ATK_DEF,tick);
-
- return 0;
+ struct block_list *src;
+ int skillnum,skilllv;
+ unsigned int tick;
+
+ nullpo_ret(bl);
+ nullpo_ret(src=va_arg(ap,struct block_list*));
+
+ skillnum=va_arg(ap,int);
+ skilllv=va_arg(ap,int);
+ if(skilllv <= 0) return 0;
+ tick=va_arg(ap,unsigned int);
+
+ if (src == bl || status_isdead(bl))
+ return 0;
+ if (bl->type == BL_PC) {
+ struct map_session_data *sd = (struct map_session_data *)bl;
+ if ( sd && sd->sc.option&(OPTION_INVISIBLE|OPTION_MADOGEAR) )
+ return 0;//Frost Joke / Scream cannot target invisible or MADO Gear characters [Ind]
+ }
+ //It has been reported that Scream/Joke works the same regardless of woe-setting. [Skotlex]
+ if(battle_check_target(src,bl,BCT_ENEMY) > 0)
+ skill_additional_effect(src,bl,skillnum,skilllv,BF_MISC,ATK_DEF,tick);
+ else if(battle_check_target(src,bl,BCT_PARTY) > 0 && rnd()%100 < 10)
+ skill_additional_effect(src,bl,skillnum,skilllv,BF_MISC,ATK_DEF,tick);
+
+ return 0;
}
/*==========================================
*
*------------------------------------------*/
-static void skill_unitsetmapcell(struct skill_unit *src, int skill_num, int skill_lv, cell_t cell, bool flag)
+static void skill_unitsetmapcell (struct skill_unit *src, int skill_num, int skill_lv, cell_t cell, bool flag)
{
- int range = skill_get_unit_range(skill_num,skill_lv);
- int x,y;
+ int range = skill_get_unit_range(skill_num,skill_lv);
+ int x,y;
- for (y = src->bl.y - range; y <= src->bl.y + range; ++y)
- for (x = src->bl.x - range; x <= src->bl.x + range; ++x)
- map_setcell(src->bl.m, x, y, cell, flag);
+ for( y = src->bl.y - range; y <= src->bl.y + range; ++y )
+ for( x = src->bl.x - range; x <= src->bl.x + range; ++x )
+ map_setcell(src->bl.m, x, y, cell, flag);
}
/*==========================================
*
*------------------------------------------*/
-int skill_attack_area(struct block_list *bl, va_list ap)
+int skill_attack_area (struct block_list *bl, va_list ap)
{
- struct block_list *src,*dsrc;
- int atk_type,skillid,skilllv,flag,type;
- unsigned int tick;
-
- if (status_isdead(bl))
- return 0;
-
- atk_type = va_arg(ap,int);
- src=va_arg(ap,struct block_list *);
- dsrc=va_arg(ap,struct block_list *);
- skillid=va_arg(ap,int);
- skilllv=va_arg(ap,int);
- tick=va_arg(ap,unsigned int);
- flag=va_arg(ap,int);
- type=va_arg(ap,int);
-
-
- if (skill_area_temp[1] == bl->id) //This is the target of the skill, do a full attack and skip target checks.
- return skill_attack(atk_type,src,dsrc,bl,skillid,skilllv,tick,flag);
-
- if (battle_check_target(dsrc,bl,type) <= 0 ||
- !status_check_skilluse(NULL, bl, skillid, 2))
- return 0;
-
-
- switch (skillid) {
- case WZ_FROSTNOVA: //Skills that don't require the animation to be removed
- case NPC_ACIDBREATH:
- case NPC_DARKNESSBREATH:
- case NPC_FIREBREATH:
- case NPC_ICEBREATH:
- case NPC_THUNDERBREATH:
- return skill_attack(atk_type,src,dsrc,bl,skillid,skilllv,tick,flag);
- default:
- //Area-splash, disable skill animation.
- return skill_attack(atk_type,src,dsrc,bl,skillid,skilllv,tick,flag|SD_ANIMATION);
- }
+ struct block_list *src,*dsrc;
+ int atk_type,skillid,skilllv,flag,type;
+ unsigned int tick;
+
+ if(status_isdead(bl))
+ return 0;
+
+ atk_type = va_arg(ap,int);
+ src=va_arg(ap,struct block_list*);
+ dsrc=va_arg(ap,struct block_list*);
+ skillid=va_arg(ap,int);
+ skilllv=va_arg(ap,int);
+ tick=va_arg(ap,unsigned int);
+ flag=va_arg(ap,int);
+ type=va_arg(ap,int);
+
+
+ if (skill_area_temp[1] == bl->id) //This is the target of the skill, do a full attack and skip target checks.
+ return skill_attack(atk_type,src,dsrc,bl,skillid,skilllv,tick,flag);
+
+ if(battle_check_target(dsrc,bl,type) <= 0 ||
+ !status_check_skilluse(NULL, bl, skillid, 2))
+ return 0;
+
+
+ switch (skillid) {
+ case WZ_FROSTNOVA: //Skills that don't require the animation to be removed
+ case NPC_ACIDBREATH:
+ case NPC_DARKNESSBREATH:
+ case NPC_FIREBREATH:
+ case NPC_ICEBREATH:
+ case NPC_THUNDERBREATH:
+ return skill_attack(atk_type,src,dsrc,bl,skillid,skilllv,tick,flag);
+ default:
+ //Area-splash, disable skill animation.
+ return skill_attack(atk_type,src,dsrc,bl,skillid,skilllv,tick,flag|SD_ANIMATION);
+ }
}
/*==========================================
*
*------------------------------------------*/
-int skill_clear_group(struct block_list *bl, int flag)
+int skill_clear_group (struct block_list *bl, int flag)
{
- struct unit_data *ud = unit_bl2ud(bl);
- struct skill_unit_group *group[MAX_SKILLUNITGROUP];
- int i, count=0;
-
- nullpo_ret(bl);
- if (!ud) return 0;
-
- //All groups to be deleted are first stored on an array since the array elements shift around when you delete them. [Skotlex]
- for (i=0; i<MAX_SKILLUNITGROUP && ud->skillunit[i]; i++) {
- switch (ud->skillunit[i]->skill_id) {
- case SA_DELUGE:
- case SA_VOLCANO:
- case SA_VIOLENTGALE:
- case SA_LANDPROTECTOR:
- case NJ_SUITON:
- case NJ_KAENSIN:
- if (flag&1)
- group[count++]= ud->skillunit[i];
- break;
- case SO_WARMER:
- if (flag&8)
- group[count++]= ud->skillunit[i];
- break;
- case SC_BLOODYLUST:
- if (flag & 32)
- group[count++] = ud->skillunit[i];
- break;
- default:
- if (flag&2 && skill_get_inf2(ud->skillunit[i]->skill_id)&INF2_TRAP)
- group[count++]= ud->skillunit[i];
- break;
- }
-
- }
- for (i=0; i<count; i++)
- skill_delunitgroup(group[i]);
- return count;
+ struct unit_data *ud = unit_bl2ud(bl);
+ struct skill_unit_group *group[MAX_SKILLUNITGROUP];
+ int i, count=0;
+
+ nullpo_ret(bl);
+ if (!ud) return 0;
+
+ //All groups to be deleted are first stored on an array since the array elements shift around when you delete them. [Skotlex]
+ for (i=0;i<MAX_SKILLUNITGROUP && ud->skillunit[i];i++)
+ {
+ switch (ud->skillunit[i]->skill_id) {
+ case SA_DELUGE:
+ case SA_VOLCANO:
+ case SA_VIOLENTGALE:
+ case SA_LANDPROTECTOR:
+ case NJ_SUITON:
+ case NJ_KAENSIN:
+ if (flag&1)
+ group[count++]= ud->skillunit[i];
+ break;
+ case SO_WARMER:
+ if( flag&8 )
+ group[count++]= ud->skillunit[i];
+ break;
+ case SC_BLOODYLUST:
+ if (flag & 32)
+ group[count++] = ud->skillunit[i];
+ break;
+ default:
+ if (flag&2 && skill_get_inf2(ud->skillunit[i]->skill_id)&INF2_TRAP)
+ group[count++]= ud->skillunit[i];
+ break;
+ }
+
+ }
+ for (i=0;i<count;i++)
+ skill_delunitgroup(group[i]);
+ return count;
}
/*==========================================
* Returns the first element field found [Skotlex]
*------------------------------------------*/
-struct skill_unit_group *skill_locate_element_field(struct block_list *bl) {
- struct unit_data *ud = unit_bl2ud(bl);
- int i;
- nullpo_ret(bl);
- if (!ud) return NULL;
-
- for (i=0; i<MAX_SKILLUNITGROUP && ud->skillunit[i]; i++) {
- switch (ud->skillunit[i]->skill_id) {
- case SA_DELUGE:
- case SA_VOLCANO:
- case SA_VIOLENTGALE:
- case SA_LANDPROTECTOR:
- case NJ_SUITON:
- case SO_WARMER:
- case SC_BLOODYLUST:
- return ud->skillunit[i];
- }
- }
- return NULL;
+struct skill_unit_group *skill_locate_element_field(struct block_list *bl)
+{
+ struct unit_data *ud = unit_bl2ud(bl);
+ int i;
+ nullpo_ret(bl);
+ if (!ud) return NULL;
+
+ for (i=0;i<MAX_SKILLUNITGROUP && ud->skillunit[i];i++) {
+ switch (ud->skillunit[i]->skill_id) {
+ case SA_DELUGE:
+ case SA_VOLCANO:
+ case SA_VIOLENTGALE:
+ case SA_LANDPROTECTOR:
+ case NJ_SUITON:
+ case SO_WARMER:
+ case SC_BLOODYLUST:
+ return ud->skillunit[i];
+ }
+ }
+ return NULL;
}
// for graffiti cleaner [Valaris]
-int skill_graffitiremover(struct block_list *bl, va_list ap)
+int skill_graffitiremover (struct block_list *bl, va_list ap)
{
- struct skill_unit *unit=NULL;
+ struct skill_unit *unit=NULL;
- nullpo_ret(bl);
- nullpo_ret(ap);
+ nullpo_ret(bl);
+ nullpo_ret(ap);
- if (bl->type!=BL_SKILL || (unit=(struct skill_unit *)bl) == NULL)
- return 0;
+ if(bl->type!=BL_SKILL || (unit=(struct skill_unit *)bl) == NULL)
+ return 0;
- if ((unit->group) && (unit->group->unit_id == UNT_GRAFFITI))
- skill_delunit(unit);
+ if((unit->group) && (unit->group->unit_id == UNT_GRAFFITI))
+ skill_delunit(unit);
- return 0;
+ return 0;
}
-int skill_greed(struct block_list *bl, va_list ap)
+int skill_greed (struct block_list *bl, va_list ap)
{
- struct block_list *src;
- struct map_session_data *sd=NULL;
- struct flooritem_data *fitem=NULL;
+ struct block_list *src;
+ struct map_session_data *sd=NULL;
+ struct flooritem_data *fitem=NULL;
- nullpo_ret(bl);
- nullpo_ret(src = va_arg(ap, struct block_list *));
+ nullpo_ret(bl);
+ nullpo_ret(src = va_arg(ap, struct block_list *));
- if (src->type == BL_PC && (sd=(struct map_session_data *)src) && bl->type==BL_ITEM && (fitem=(struct flooritem_data *)bl))
- pc_takeitem(sd, fitem);
+ if(src->type == BL_PC && (sd=(struct map_session_data *)src) && bl->type==BL_ITEM && (fitem=(struct flooritem_data *)bl))
+ pc_takeitem(sd, fitem);
- return 0;
+ return 0;
}
//For Ranger's Detonator [Jobbie/3CeAM]
int skill_detonator(struct block_list *bl, va_list ap)
{
- struct skill_unit *unit=NULL;
- struct block_list *src;
- int unit_id;
-
- nullpo_ret(bl);
- nullpo_ret(ap);
- src = va_arg(ap,struct block_list *);
-
- if (bl->type != BL_SKILL || (unit = (struct skill_unit *)bl) == NULL || !unit->group)
- return 0;
- if (unit->group->src_id != src->id)
- return 0;
-
- unit_id = unit->group->unit_id;
- switch (unit_id) {
- //List of Hunter and Ranger Traps that can be detonate.
- case UNT_BLASTMINE:
- case UNT_SANDMAN:
- case UNT_CLAYMORETRAP:
- case UNT_TALKIEBOX:
- case UNT_CLUSTERBOMB:
- case UNT_FIRINGTRAP:
- case UNT_ICEBOUNDTRAP:
- if (unit_id == UNT_TALKIEBOX) {
- clif_talkiebox(bl,unit->group->valstr);
- unit->group->val2 = -1;
- } else
- map_foreachinrange(skill_trap_splash,bl,skill_get_splash(unit->group->skill_id,unit->group->skill_lv),unit->group->bl_flag,bl,unit->group->tick);
-
- clif_changetraplook(bl,unit_id == UNT_FIRINGTRAP ? UNT_DUMMYSKILL : UNT_USED_TRAPS);
- unit->group->unit_id = UNT_USED_TRAPS;
- unit->group->limit = DIFF_TICK(gettick(),unit->group->tick) +
- (unit_id == UNT_TALKIEBOX ? 5000 : (unit_id == UNT_CLUSTERBOMB || unit_id == UNT_ICEBOUNDTRAP? 2500 : 1500));
- break;
- }
- return 0;
+ struct skill_unit *unit=NULL;
+ struct block_list *src;
+ int unit_id;
+
+ nullpo_ret(bl);
+ nullpo_ret(ap);
+ src = va_arg(ap,struct block_list *);
+
+ if( bl->type != BL_SKILL || (unit = (struct skill_unit *)bl) == NULL || !unit->group )
+ return 0;
+ if( unit->group->src_id != src->id )
+ return 0;
+
+ unit_id = unit->group->unit_id;
+ switch( unit_id )
+ { //List of Hunter and Ranger Traps that can be detonate.
+ case UNT_BLASTMINE:
+ case UNT_SANDMAN:
+ case UNT_CLAYMORETRAP:
+ case UNT_TALKIEBOX:
+ case UNT_CLUSTERBOMB:
+ case UNT_FIRINGTRAP:
+ case UNT_ICEBOUNDTRAP:
+ if( unit_id == UNT_TALKIEBOX )
+ {
+ clif_talkiebox(bl,unit->group->valstr);
+ unit->group->val2 = -1;
+ }
+ else
+ map_foreachinrange(skill_trap_splash,bl,skill_get_splash(unit->group->skill_id,unit->group->skill_lv),unit->group->bl_flag,bl,unit->group->tick);
+
+ clif_changetraplook(bl,unit_id == UNT_FIRINGTRAP ? UNT_DUMMYSKILL : UNT_USED_TRAPS);
+ unit->group->unit_id = UNT_USED_TRAPS;
+ unit->group->limit = DIFF_TICK(gettick(),unit->group->tick) +
+ (unit_id == UNT_TALKIEBOX ? 5000 : (unit_id == UNT_CLUSTERBOMB || unit_id == UNT_ICEBOUNDTRAP? 2500 : 1500) );
+ break;
+ }
+ return 0;
}
/*==========================================
@@ -14698,103 +14547,104 @@ int skill_detonator(struct block_list *bl, va_list ap)
*------------------------------------------*/
static int skill_cell_overlap(struct block_list *bl, va_list ap)
{
- int skillid;
- int *alive;
- struct skill_unit *unit;
-
- skillid = va_arg(ap,int);
- alive = va_arg(ap,int *);
- unit = (struct skill_unit *)bl;
-
- if (unit == NULL || unit->group == NULL || (*alive) == 0)
- return 0;
-
- switch (skillid) {
- case SA_LANDPROTECTOR:
- if (unit->group->skill_id == SA_LANDPROTECTOR) { //Check for offensive Land Protector to delete both. [Skotlex]
- (*alive) = 0;
- skill_delunit(unit);
- return 1;
- }
- if (!(skill_get_inf2(unit->group->skill_id)&(INF2_SONG_DANCE|INF2_TRAP))) { //It deletes everything except songs/dances and traps
- skill_delunit(unit);
- return 1;
- }
- break;
- case HW_GANBANTEIN:
- case LG_EARTHDRIVE:
- if (!(unit->group->state.song_dance&0x1)) { // Don't touch song/dance.
- skill_delunit(unit);
- return 1;
- }
- break;
- case SA_VOLCANO:
- case SA_DELUGE:
- case SA_VIOLENTGALE:
- // The official implementation makes them fail to appear when casted on top of ANYTHING
- // but I wonder if they didn't actually meant to fail when casted on top of each other?
- // hence, I leave the alternate implementation here, commented. [Skotlex]
- if (unit->range <= 0) {
- (*alive) = 0;
- return 1;
- }
- /*
- switch (unit->group->skill_id)
- { //These cannot override each other.
- case SA_VOLCANO:
- case SA_DELUGE:
- case SA_VIOLENTGALE:
- (*alive) = 0;
- return 1;
- }
- */
- break;
- case PF_FOGWALL:
- switch (unit->group->skill_id) {
- case SA_VOLCANO: //Can't be placed on top of these
- case SA_VIOLENTGALE:
- (*alive) = 0;
- return 1;
- case SA_DELUGE:
- case NJ_SUITON:
- //Cheap 'hack' to notify the calling function that duration should be doubled [Skotlex]
- (*alive) = 2;
- break;
- }
- break;
- case HP_BASILICA:
- if (unit->group->skill_id == HP_BASILICA) {
- //Basilica can't be placed on top of itself to avoid map-cell stacking problems. [Skotlex]
- (*alive) = 0;
- return 1;
- }
- break;
- case GN_CRAZYWEED_ATK:
- switch (unit->group->unit_id) { //TODO: look for other ground skills that are affected.
- case UNT_WALLOFTHORN:
- case UNT_THORNS_TRAP:
- case UNT_BLOODYLUST:
- case UNT_CHAOSPANIC:
- case UNT_MAELSTROM:
- case UNT_FIREPILLAR_ACTIVE:
- case UNT_LANDPROTECTOR:
- case UNT_VOLCANO:
- case UNT_DELUGE:
- case UNT_VIOLENTGALE:
- case UNT_SAFETYWALL:
- case UNT_PNEUMA:
- skill_delunit(unit);
- return 1;
- }
- break;
- }
+ int skillid;
+ int *alive;
+ struct skill_unit *unit;
+
+ skillid = va_arg(ap,int);
+ alive = va_arg(ap,int *);
+ unit = (struct skill_unit *)bl;
+
+ if (unit == NULL || unit->group == NULL || (*alive) == 0)
+ return 0;
+
+ switch (skillid) {
+ case SA_LANDPROTECTOR:
+ if( unit->group->skill_id == SA_LANDPROTECTOR ) {//Check for offensive Land Protector to delete both. [Skotlex]
+ (*alive) = 0;
+ skill_delunit(unit);
+ return 1;
+ }
+ if( !(skill_get_inf2(unit->group->skill_id)&(INF2_SONG_DANCE|INF2_TRAP)) ) { //It deletes everything except songs/dances and traps
+ skill_delunit(unit);
+ return 1;
+ }
+ break;
+ case HW_GANBANTEIN:
+ case LG_EARTHDRIVE:
+ if( !(unit->group->state.song_dance&0x1) ) {// Don't touch song/dance.
+ skill_delunit(unit);
+ return 1;
+ }
+ break;
+ case SA_VOLCANO:
+ case SA_DELUGE:
+ case SA_VIOLENTGALE:
+// The official implementation makes them fail to appear when casted on top of ANYTHING
+// but I wonder if they didn't actually meant to fail when casted on top of each other?
+// hence, I leave the alternate implementation here, commented. [Skotlex]
+ if (unit->range <= 0)
+ {
+ (*alive) = 0;
+ return 1;
+ }
+/*
+ switch (unit->group->skill_id)
+ { //These cannot override each other.
+ case SA_VOLCANO:
+ case SA_DELUGE:
+ case SA_VIOLENTGALE:
+ (*alive) = 0;
+ return 1;
+ }
+*/
+ break;
+ case PF_FOGWALL:
+ switch(unit->group->skill_id) {
+ case SA_VOLCANO: //Can't be placed on top of these
+ case SA_VIOLENTGALE:
+ (*alive) = 0;
+ return 1;
+ case SA_DELUGE:
+ case NJ_SUITON:
+ //Cheap 'hack' to notify the calling function that duration should be doubled [Skotlex]
+ (*alive) = 2;
+ break;
+ }
+ break;
+ case HP_BASILICA:
+ if (unit->group->skill_id == HP_BASILICA)
+ { //Basilica can't be placed on top of itself to avoid map-cell stacking problems. [Skotlex]
+ (*alive) = 0;
+ return 1;
+ }
+ break;
+ case GN_CRAZYWEED_ATK:
+ switch(unit->group->unit_id){ //TODO: look for other ground skills that are affected.
+ case UNT_WALLOFTHORN:
+ case UNT_THORNS_TRAP:
+ case UNT_BLOODYLUST:
+ case UNT_CHAOSPANIC:
+ case UNT_MAELSTROM:
+ case UNT_FIREPILLAR_ACTIVE:
+ case UNT_LANDPROTECTOR:
+ case UNT_VOLCANO:
+ case UNT_DELUGE:
+ case UNT_VIOLENTGALE:
+ case UNT_SAFETYWALL:
+ case UNT_PNEUMA:
+ skill_delunit(unit);
+ return 1;
+ }
+ break;
+ }
- if (unit->group->skill_id == SA_LANDPROTECTOR && !(skill_get_inf2(skillid)&(INF2_SONG_DANCE|INF2_TRAP))) { //It deletes everything except songs/dances/traps
- (*alive) = 0;
- return 1;
- }
+ if (unit->group->skill_id == SA_LANDPROTECTOR && !(skill_get_inf2(skillid)&(INF2_SONG_DANCE|INF2_TRAP))) { //It deletes everything except songs/dances/traps
+ (*alive) = 0;
+ return 1;
+ }
- return 0;
+ return 0;
}
/*==========================================
@@ -14802,315 +14652,325 @@ static int skill_cell_overlap(struct block_list *bl, va_list ap)
*------------------------------------------*/
int skill_chastle_mob_changetarget(struct block_list *bl,va_list ap)
{
- struct mob_data *md;
- struct unit_data *ud = unit_bl2ud(bl);
- struct block_list *from_bl;
- struct block_list *to_bl;
- md = (struct mob_data *)bl;
- from_bl = va_arg(ap,struct block_list *);
- to_bl = va_arg(ap,struct block_list *);
-
- if (ud && ud->target == from_bl->id)
- ud->target = to_bl->id;
-
- if (md->bl.type == BL_MOB && md->target_id == from_bl->id)
- md->target_id = to_bl->id;
- return 0;
+ struct mob_data* md;
+ struct unit_data*ud = unit_bl2ud(bl);
+ struct block_list *from_bl;
+ struct block_list *to_bl;
+ md = (struct mob_data*)bl;
+ from_bl = va_arg(ap,struct block_list *);
+ to_bl = va_arg(ap,struct block_list *);
+
+ if(ud && ud->target == from_bl->id)
+ ud->target = to_bl->id;
+
+ if(md->bl.type == BL_MOB && md->target_id == from_bl->id)
+ md->target_id = to_bl->id;
+ return 0;
}
/*==========================================
*
*------------------------------------------*/
-static int skill_trap_splash(struct block_list *bl, va_list ap)
+static int skill_trap_splash (struct block_list *bl, va_list ap)
{
- struct block_list *src;
- int tick;
- struct skill_unit *unit;
- struct skill_unit_group *sg;
- struct block_list *ss;
- src = va_arg(ap,struct block_list *);
- unit = (struct skill_unit *)src;
- tick = va_arg(ap,int);
-
- if (!unit->alive || bl->prev == NULL)
- return 0;
-
- nullpo_ret(sg = unit->group);
- nullpo_ret(ss = map_id2bl(sg->src_id));
-
- if (battle_check_target(src,bl,sg->target_flag) <= 0)
- return 0;
-
- switch (sg->unit_id) {
- case UNT_SHOCKWAVE:
- case UNT_SANDMAN:
- case UNT_FLASHER:
- skill_additional_effect(ss,bl,sg->skill_id,sg->skill_lv,BF_MISC,ATK_DEF,tick);
- break;
- case UNT_GROUNDDRIFT_WIND:
- if (skill_attack(BF_WEAPON,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1))
- sc_start(bl,SC_STUN,5,sg->skill_lv,skill_get_time2(sg->skill_id, sg->skill_lv));
- break;
- case UNT_GROUNDDRIFT_DARK:
- if (skill_attack(BF_WEAPON,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1))
- sc_start(bl,SC_BLIND,5,sg->skill_lv,skill_get_time2(sg->skill_id, sg->skill_lv));
- break;
- case UNT_GROUNDDRIFT_POISON:
- if (skill_attack(BF_WEAPON,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1))
- sc_start(bl,SC_POISON,5,sg->skill_lv,skill_get_time2(sg->skill_id, sg->skill_lv));
- break;
- case UNT_GROUNDDRIFT_WATER:
- if (skill_attack(BF_WEAPON,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1))
- sc_start(bl,SC_FREEZE,5,sg->skill_lv,skill_get_time2(sg->skill_id, sg->skill_lv));
- break;
- case UNT_GROUNDDRIFT_FIRE:
- if (skill_attack(BF_WEAPON,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1))
- skill_blown(src,bl,skill_get_blewcount(sg->skill_id,sg->skill_lv),-1,0);
- break;
- case UNT_ELECTRICSHOCKER:
- clif_skill_damage(src,bl,tick,0,0,-30000,1,sg->skill_id,sg->skill_lv,5);
- break;
- case UNT_FIRINGTRAP:
- case UNT_ICEBOUNDTRAP:
- case UNT_CLUSTERBOMB:
- if (ss != bl)
- skill_attack(BF_MISC,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1|SD_LEVEL);
- break;
- case UNT_MAGENTATRAP:
- case UNT_COBALTTRAP:
- case UNT_MAIZETRAP:
- case UNT_VERDURETRAP:
- if (bl->type != BL_PC && !is_boss(bl))
- sc_start2(bl,SC_ELEMENTALCHANGE,100,sg->skill_lv,skill_get_ele(sg->skill_id,sg->skill_lv),skill_get_time2(sg->skill_id,sg->skill_lv));
- break;
- case UNT_REVERBERATION:
- skill_addtimerskill(ss,tick+50,bl->id,0,0,WM_REVERBERATION_MELEE,sg->skill_lv,BF_WEAPON,0); // for proper skill delay animation when use with Dominion Impulse
- skill_addtimerskill(ss,tick+250,bl->id,0,0,WM_REVERBERATION_MAGIC,sg->skill_lv,BF_MAGIC,0);
- break;
- default:
- skill_attack(skill_get_type(sg->skill_id),ss,src,bl,sg->skill_id,sg->skill_lv,tick,0);
- break;
- }
- return 1;
+ struct block_list *src;
+ int tick;
+ struct skill_unit *unit;
+ struct skill_unit_group *sg;
+ struct block_list *ss;
+ src = va_arg(ap,struct block_list *);
+ unit = (struct skill_unit *)src;
+ tick = va_arg(ap,int);
+
+ if( !unit->alive || bl->prev == NULL )
+ return 0;
+
+ nullpo_ret(sg = unit->group);
+ nullpo_ret(ss = map_id2bl(sg->src_id));
+
+ if(battle_check_target(src,bl,sg->target_flag) <= 0)
+ return 0;
+
+ switch(sg->unit_id){
+ case UNT_SHOCKWAVE:
+ case UNT_SANDMAN:
+ case UNT_FLASHER:
+ skill_additional_effect(ss,bl,sg->skill_id,sg->skill_lv,BF_MISC,ATK_DEF,tick);
+ break;
+ case UNT_GROUNDDRIFT_WIND:
+ if(skill_attack(BF_WEAPON,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1))
+ sc_start(bl,SC_STUN,5,sg->skill_lv,skill_get_time2(sg->skill_id, sg->skill_lv));
+ break;
+ case UNT_GROUNDDRIFT_DARK:
+ if(skill_attack(BF_WEAPON,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1))
+ sc_start(bl,SC_BLIND,5,sg->skill_lv,skill_get_time2(sg->skill_id, sg->skill_lv));
+ break;
+ case UNT_GROUNDDRIFT_POISON:
+ if(skill_attack(BF_WEAPON,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1))
+ sc_start(bl,SC_POISON,5,sg->skill_lv,skill_get_time2(sg->skill_id, sg->skill_lv));
+ break;
+ case UNT_GROUNDDRIFT_WATER:
+ if(skill_attack(BF_WEAPON,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1))
+ sc_start(bl,SC_FREEZE,5,sg->skill_lv,skill_get_time2(sg->skill_id, sg->skill_lv));
+ break;
+ case UNT_GROUNDDRIFT_FIRE:
+ if(skill_attack(BF_WEAPON,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1))
+ skill_blown(src,bl,skill_get_blewcount(sg->skill_id,sg->skill_lv),-1,0);
+ break;
+ case UNT_ELECTRICSHOCKER:
+ clif_skill_damage(src,bl,tick,0,0,-30000,1,sg->skill_id,sg->skill_lv,5);
+ break;
+ case UNT_FIRINGTRAP:
+ case UNT_ICEBOUNDTRAP:
+ case UNT_CLUSTERBOMB:
+ if( ss != bl )
+ skill_attack(BF_MISC,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1|SD_LEVEL);
+ break;
+ case UNT_MAGENTATRAP:
+ case UNT_COBALTTRAP:
+ case UNT_MAIZETRAP:
+ case UNT_VERDURETRAP:
+ if( bl->type != BL_PC && !is_boss(bl) )
+ sc_start2(bl,SC_ELEMENTALCHANGE,100,sg->skill_lv,skill_get_ele(sg->skill_id,sg->skill_lv),skill_get_time2(sg->skill_id,sg->skill_lv));
+ break;
+ case UNT_REVERBERATION:
+ skill_addtimerskill(ss,tick+50,bl->id,0,0,WM_REVERBERATION_MELEE,sg->skill_lv,BF_WEAPON,0); // for proper skill delay animation when use with Dominion Impulse
+ skill_addtimerskill(ss,tick+250,bl->id,0,0,WM_REVERBERATION_MAGIC,sg->skill_lv,BF_MAGIC,0);
+ break;
+ default:
+ skill_attack(skill_get_type(sg->skill_id),ss,src,bl,sg->skill_id,sg->skill_lv,tick,0);
+ break;
+ }
+ return 1;
}
/*==========================================
*
*------------------------------------------*/
-int skill_enchant_elemental_end(struct block_list *bl, int type)
+int skill_enchant_elemental_end (struct block_list *bl, int type)
{
- struct status_change *sc;
- const enum sc_type scs[] = { SC_ENCPOISON, SC_ASPERSIO, SC_FIREWEAPON, SC_WATERWEAPON, SC_WINDWEAPON, SC_EARTHWEAPON, SC_SHADOWWEAPON, SC_GHOSTWEAPON, SC_ENCHANTARMS, SC_EXEEDBREAK };
- int i;
- nullpo_ret(bl);
- nullpo_ret(sc= status_get_sc(bl));
+ struct status_change *sc;
+ const enum sc_type scs[] = { SC_ENCPOISON, SC_ASPERSIO, SC_FIREWEAPON, SC_WATERWEAPON, SC_WINDWEAPON, SC_EARTHWEAPON, SC_SHADOWWEAPON, SC_GHOSTWEAPON, SC_ENCHANTARMS, SC_EXEEDBREAK };
+ int i;
+ nullpo_ret(bl);
+ nullpo_ret(sc= status_get_sc(bl));
- if (!sc->count) return 0;
+ if (!sc->count) return 0;
- for (i = 0; i < ARRAYLENGTH(scs); i++)
- if (type != scs[i] && sc->data[scs[i]])
- status_change_end(bl, scs[i], INVALID_TIMER);
+ for (i = 0; i < ARRAYLENGTH(scs); i++)
+ if (type != scs[i] && sc->data[scs[i]])
+ status_change_end(bl, scs[i], INVALID_TIMER);
- return 0;
+ return 0;
}
bool skill_check_cloaking(struct block_list *bl, struct status_change_entry *sce)
{
- static int dx[] = { 0, 1, 0, -1, -1, 1, 1, -1};
- static int dy[] = {-1, 0, 1, 0, -1, -1, 1, 1};
- bool wall = true;
-
- if ((bl->type == BL_PC && battle_config.pc_cloak_check_type&1)
- || (bl->type != BL_PC && battle_config.monster_cloak_check_type&1)) {
- //Check for walls.
- int i;
- ARR_FIND(0, 8, i, map_getcell(bl->m, bl->x+dx[i], bl->y+dy[i], CELL_CHKNOPASS) != 0);
- if (i == 8)
- wall = false;
- }
-
- if (sce) {
- if (!wall) {
- if (sce->val1 < 3) //End cloaking.
- status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
- else if (sce->val4&1) {
- //Remove wall bonus
- sce->val4&=~1;
- status_calc_bl(bl,SCB_SPEED);
- }
- } else {
- if (!(sce->val4&1)) {
- //Add wall speed bonus
- sce->val4|=1;
- status_calc_bl(bl,SCB_SPEED);
- }
- }
- }
+ static int dx[] = { 0, 1, 0, -1, -1, 1, 1, -1};
+ static int dy[] = {-1, 0, 1, 0, -1, -1, 1, 1};
+ bool wall = true;
+
+ if( (bl->type == BL_PC && battle_config.pc_cloak_check_type&1)
+ || (bl->type != BL_PC && battle_config.monster_cloak_check_type&1) )
+ { //Check for walls.
+ int i;
+ ARR_FIND( 0, 8, i, map_getcell(bl->m, bl->x+dx[i], bl->y+dy[i], CELL_CHKNOPASS) != 0 );
+ if( i == 8 )
+ wall = false;
+ }
+
+ if( sce )
+ {
+ if( !wall )
+ {
+ if( sce->val1 < 3 ) //End cloaking.
+ status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
+ else
+ if( sce->val4&1 )
+ { //Remove wall bonus
+ sce->val4&=~1;
+ status_calc_bl(bl,SCB_SPEED);
+ }
+ }
+ else
+ {
+ if( !(sce->val4&1) )
+ { //Add wall speed bonus
+ sce->val4|=1;
+ status_calc_bl(bl,SCB_SPEED);
+ }
+ }
+ }
- return wall;
+ return wall;
}
bool skill_check_camouflage(struct block_list *bl, struct status_change_entry *sce)
{
- static int dx[] = { 0, 1, 0, -1, -1, 1, 1, -1};
- static int dy[] = {-1, 0, 1, 0, -1, -1, 1, 1};
- bool wall = true;
-
- if (bl->type == BL_PC) {
- //Check for walls.
- int i;
- ARR_FIND(0, 8, i, map_getcell(bl->m, bl->x+dx[i], bl->y+dy[i], CELL_CHKNOPASS) != 0);
- if (i == 8)
- wall = false;
- }
-
- if (sce) {
- if (!wall) {
- if (sce->val1 < 3) //End camouflage.
- status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER);
- else if (sce->val3&1) {
- //Remove wall bonus
- sce->val3&=~1;
- status_calc_bl(bl,SCB_SPEED);
- }
- }
- }
+ static int dx[] = { 0, 1, 0, -1, -1, 1, 1, -1};
+ static int dy[] = {-1, 0, 1, 0, -1, -1, 1, 1};
+ bool wall = true;
+
+ if( bl->type == BL_PC )
+ { //Check for walls.
+ int i;
+ ARR_FIND( 0, 8, i, map_getcell(bl->m, bl->x+dx[i], bl->y+dy[i], CELL_CHKNOPASS) != 0 );
+ if( i == 8 )
+ wall = false;
+ }
+
+ if( sce )
+ {
+ if( !wall )
+ {
+ if( sce->val1 < 3 ) //End camouflage.
+ status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER);
+ else
+ if( sce->val3&1 )
+ { //Remove wall bonus
+ sce->val3&=~1;
+ status_calc_bl(bl,SCB_SPEED);
+ }
+ }
+ }
- return wall;
+ return wall;
}
/*==========================================
*
*------------------------------------------*/
-struct skill_unit *skill_initunit(struct skill_unit_group *group, int idx, int x, int y, int val1, int val2) {
- struct skill_unit *unit;
-
- nullpo_retr(NULL, group);
- nullpo_retr(NULL, group->unit); // crash-protection against poor coding
- nullpo_retr(NULL, unit=&group->unit[idx]);
-
- if (!unit->alive)
- group->alive_count++;
-
- unit->bl.id=map_get_new_object_id();
- unit->bl.type=BL_SKILL;
- unit->bl.m=group->map;
- unit->bl.x=x;
- unit->bl.y=y;
- unit->group=group;
- unit->alive=1;
- unit->val1=val1;
- unit->val2=val2;
-
- idb_put(skillunit_db, unit->bl.id, unit);
- map_addiddb(&unit->bl);
- map_addblock(&unit->bl);
-
- // perform oninit actions
- switch (group->skill_id) {
- case WZ_ICEWALL:
- map_setgatcell(unit->bl.m,unit->bl.x,unit->bl.y,5);
- clif_changemapcell(0,unit->bl.m,unit->bl.x,unit->bl.y,5,AREA);
- skill_unitsetmapcell(unit,WZ_ICEWALL,group->skill_lv,CELL_ICEWALL,true);
- map[unit->bl.m].icewall_num++;
- break;
- case SA_LANDPROTECTOR:
- skill_unitsetmapcell(unit,SA_LANDPROTECTOR,group->skill_lv,CELL_LANDPROTECTOR,true);
- break;
- case HP_BASILICA:
- skill_unitsetmapcell(unit,HP_BASILICA,group->skill_lv,CELL_BASILICA,true);
- break;
- case SC_MAELSTROM:
- skill_unitsetmapcell(unit,SC_MAELSTROM,group->skill_lv,CELL_MAELSTROM,true);
- break;
- default:
- if (group->state.song_dance&0x1) //Check for dissonance.
- skill_dance_overlap(unit, 1);
- break;
- }
+struct skill_unit *skill_initunit (struct skill_unit_group *group, int idx, int x, int y, int val1, int val2)
+{
+ struct skill_unit *unit;
+
+ nullpo_retr(NULL, group);
+ nullpo_retr(NULL, group->unit); // crash-protection against poor coding
+ nullpo_retr(NULL, unit=&group->unit[idx]);
+
+ if(!unit->alive)
+ group->alive_count++;
+
+ unit->bl.id=map_get_new_object_id();
+ unit->bl.type=BL_SKILL;
+ unit->bl.m=group->map;
+ unit->bl.x=x;
+ unit->bl.y=y;
+ unit->group=group;
+ unit->alive=1;
+ unit->val1=val1;
+ unit->val2=val2;
+
+ idb_put(skillunit_db, unit->bl.id, unit);
+ map_addiddb(&unit->bl);
+ map_addblock(&unit->bl);
+
+ // perform oninit actions
+ switch (group->skill_id) {
+ case WZ_ICEWALL:
+ map_setgatcell(unit->bl.m,unit->bl.x,unit->bl.y,5);
+ clif_changemapcell(0,unit->bl.m,unit->bl.x,unit->bl.y,5,AREA);
+ skill_unitsetmapcell(unit,WZ_ICEWALL,group->skill_lv,CELL_ICEWALL,true);
+ map[unit->bl.m].icewall_num++;
+ break;
+ case SA_LANDPROTECTOR:
+ skill_unitsetmapcell(unit,SA_LANDPROTECTOR,group->skill_lv,CELL_LANDPROTECTOR,true);
+ break;
+ case HP_BASILICA:
+ skill_unitsetmapcell(unit,HP_BASILICA,group->skill_lv,CELL_BASILICA,true);
+ break;
+ case SC_MAELSTROM:
+ skill_unitsetmapcell(unit,SC_MAELSTROM,group->skill_lv,CELL_MAELSTROM,true);
+ break;
+ default:
+ if (group->state.song_dance&0x1) //Check for dissonance.
+ skill_dance_overlap(unit, 1);
+ break;
+ }
- clif_skill_setunit(unit);
+ clif_skill_setunit(unit);
- return unit;
+ return unit;
}
/*==========================================
*
*------------------------------------------*/
-int skill_delunit(struct skill_unit *unit)
+int skill_delunit (struct skill_unit* unit)
{
- struct skill_unit_group *group;
+ struct skill_unit_group *group;
- nullpo_ret(unit);
- if (!unit->alive)
- return 0;
- unit->alive=0;
+ nullpo_ret(unit);
+ if( !unit->alive )
+ return 0;
+ unit->alive=0;
- nullpo_ret(group=unit->group);
+ nullpo_ret(group=unit->group);
- if (group->state.song_dance&0x1) //Cancel dissonance effect.
- skill_dance_overlap(unit, 0);
+ if( group->state.song_dance&0x1 ) //Cancel dissonance effect.
+ skill_dance_overlap(unit, 0);
- // invoke onout event
- if (!unit->range)
- map_foreachincell(skill_unit_effect,unit->bl.m,unit->bl.x,unit->bl.y,group->bl_flag,&unit->bl,gettick(),4);
+ // invoke onout event
+ if( !unit->range )
+ map_foreachincell(skill_unit_effect,unit->bl.m,unit->bl.x,unit->bl.y,group->bl_flag,&unit->bl,gettick(),4);
- // perform ondelete actions
- switch (group->skill_id) {
- case HT_ANKLESNARE: {
- struct block_list *target = map_id2bl(group->val2);
- if (target)
- status_change_end(target, SC_ANKLE, INVALID_TIMER);
- }
- break;
- case WZ_ICEWALL:
- map_setgatcell(unit->bl.m,unit->bl.x,unit->bl.y,unit->val2);
- clif_changemapcell(0,unit->bl.m,unit->bl.x,unit->bl.y,unit->val2,ALL_SAMEMAP); // hack to avoid clientside cell bug
- skill_unitsetmapcell(unit,WZ_ICEWALL,group->skill_lv,CELL_ICEWALL,false);
- map[unit->bl.m].icewall_num--;
- break;
- case SA_LANDPROTECTOR:
- skill_unitsetmapcell(unit,SA_LANDPROTECTOR,group->skill_lv,CELL_LANDPROTECTOR,false);
- break;
- case HP_BASILICA:
- skill_unitsetmapcell(unit,HP_BASILICA,group->skill_lv,CELL_BASILICA,false);
- break;
- case RA_ELECTRICSHOCKER: {
- struct block_list *target = map_id2bl(group->val2);
- if (target)
- status_change_end(target, SC_ELECTRICSHOCKER, INVALID_TIMER);
- }
- break;
- case SC_MAELSTROM:
- skill_unitsetmapcell(unit,SC_MAELSTROM,group->skill_lv,CELL_MAELSTROM,false);
- break;
- case SC_MANHOLE: // Note : Removing the unit don't remove the status (official info)
- if (group->val2) { // Someone Traped
- struct status_change *tsc = status_get_sc(map_id2bl(group->val2));
- if (tsc && tsc->data[SC__MANHOLE])
- tsc->data[SC__MANHOLE]->val4 = 0; // Remove the Unit ID
- }
- break;
- }
+ // perform ondelete actions
+ switch (group->skill_id) {
+ case HT_ANKLESNARE: {
+ struct block_list* target = map_id2bl(group->val2);
+ if( target )
+ status_change_end(target, SC_ANKLE, INVALID_TIMER);
+ }
+ break;
+ case WZ_ICEWALL:
+ map_setgatcell(unit->bl.m,unit->bl.x,unit->bl.y,unit->val2);
+ clif_changemapcell(0,unit->bl.m,unit->bl.x,unit->bl.y,unit->val2,ALL_SAMEMAP); // hack to avoid clientside cell bug
+ skill_unitsetmapcell(unit,WZ_ICEWALL,group->skill_lv,CELL_ICEWALL,false);
+ map[unit->bl.m].icewall_num--;
+ break;
+ case SA_LANDPROTECTOR:
+ skill_unitsetmapcell(unit,SA_LANDPROTECTOR,group->skill_lv,CELL_LANDPROTECTOR,false);
+ break;
+ case HP_BASILICA:
+ skill_unitsetmapcell(unit,HP_BASILICA,group->skill_lv,CELL_BASILICA,false);
+ break;
+ case RA_ELECTRICSHOCKER: {
+ struct block_list* target = map_id2bl(group->val2);
+ if( target )
+ status_change_end(target, SC_ELECTRICSHOCKER, INVALID_TIMER);
+ }
+ break;
+ case SC_MAELSTROM:
+ skill_unitsetmapcell(unit,SC_MAELSTROM,group->skill_lv,CELL_MAELSTROM,false);
+ break;
+ case SC_MANHOLE: // Note : Removing the unit don't remove the status (official info)
+ if( group->val2 ) { // Someone Traped
+ struct status_change *tsc = status_get_sc( map_id2bl(group->val2));
+ if( tsc && tsc->data[SC__MANHOLE] )
+ tsc->data[SC__MANHOLE]->val4 = 0; // Remove the Unit ID
+ }
+ break;
+ }
- clif_skill_delunit(unit);
+ clif_skill_delunit(unit);
- unit->group=NULL;
- map_delblock(&unit->bl); // don't free yet
- map_deliddb(&unit->bl);
- idb_remove(skillunit_db, unit->bl.id);
- if (--group->alive_count==0)
- skill_delunitgroup(group);
+ unit->group=NULL;
+ map_delblock(&unit->bl); // don't free yet
+ map_deliddb(&unit->bl);
+ idb_remove(skillunit_db, unit->bl.id);
+ if(--group->alive_count==0)
+ skill_delunitgroup(group);
- return 0;
+ return 0;
}
/*==========================================
*
*------------------------------------------*/
-static DBMap *group_db = NULL;// int group_id -> struct skill_unit_group*
+static DBMap* group_db = NULL;// int group_id -> struct skill_unit_group*
/// Returns the target skill_unit_group or NULL if not found.
-struct skill_unit_group *skill_id2group(int group_id) {
- return (struct skill_unit_group *)idb_get(group_db, group_id);
+struct skill_unit_group* skill_id2group(int group_id)
+{
+ return (struct skill_unit_group*)idb_get(group_db, group_id);
}
@@ -15120,286 +14980,298 @@ static int skill_unit_group_newid = MAX_SKILL_DB;
/// Fatal error if nothing is available.
static int skill_get_new_group_id(void)
{
- if (skill_unit_group_newid >= MAX_SKILL_DB && skill_id2group(skill_unit_group_newid) == NULL)
- return skill_unit_group_newid++;// available
- {
- // find next id
- int base_id = skill_unit_group_newid;
- while (base_id != ++skill_unit_group_newid) {
- if (skill_unit_group_newid < MAX_SKILL_DB)
- skill_unit_group_newid = MAX_SKILL_DB;
- if (skill_id2group(skill_unit_group_newid) == NULL)
- return skill_unit_group_newid++;// available
- }
- // full loop, nothing available
- ShowFatalError("skill_get_new_group_id: All ids are taken. Exiting...");
- exit(1);
- }
+ if( skill_unit_group_newid >= MAX_SKILL_DB && skill_id2group(skill_unit_group_newid) == NULL )
+ return skill_unit_group_newid++;// available
+ {// find next id
+ int base_id = skill_unit_group_newid;
+ while( base_id != ++skill_unit_group_newid )
+ {
+ if( skill_unit_group_newid < MAX_SKILL_DB )
+ skill_unit_group_newid = MAX_SKILL_DB;
+ if( skill_id2group(skill_unit_group_newid) == NULL )
+ return skill_unit_group_newid++;// available
+ }
+ // full loop, nothing available
+ ShowFatalError("skill_get_new_group_id: All ids are taken. Exiting...");
+ exit(1);
+ }
}
-struct skill_unit_group *skill_initunitgroup(struct block_list *src, int count, short skillid, short skilllv, int unit_id, int limit, int interval) {
- struct unit_data *ud = unit_bl2ud(src);
- struct skill_unit_group *group;
- int i;
-
- if (skillid <= 0 || skilllv <= 0) return 0;
-
- nullpo_retr(NULL, src);
- nullpo_retr(NULL, ud);
-
- // find a free spot to store the new unit group
- ARR_FIND(0, MAX_SKILLUNITGROUP, i, ud->skillunit[i] == NULL);
- if (i == MAX_SKILLUNITGROUP) {
- // array is full, make room by discarding oldest group
- int j=0;
- unsigned maxdiff=0,x,tick=gettick();
- for (i=0; i<MAX_SKILLUNITGROUP && ud->skillunit[i]; i++)
- if ((x=DIFF_TICK(tick,ud->skillunit[i]->tick))>maxdiff) {
- maxdiff=x;
- j=i;
- }
- skill_delunitgroup(ud->skillunit[j]);
- //Since elements must have shifted, we use the last slot.
- i = MAX_SKILLUNITGROUP-1;
- }
-
- group = ers_alloc(skill_unit_ers, struct skill_unit_group);
- group->src_id = src->id;
- group->party_id = status_get_party_id(src);
- group->guild_id = status_get_guild_id(src);
- group->bg_id = bg_team_get_id(src);
- group->group_id = skill_get_new_group_id();
- group->unit = (struct skill_unit *)aCalloc(count,sizeof(struct skill_unit));
- group->unit_count = count;
- group->alive_count = 0;
- group->val1 = 0;
- group->val2 = 0;
- group->val3 = 0;
- group->skill_id = skillid;
- group->skill_lv = skilllv;
- group->unit_id = unit_id;
- group->map = src->m;
- group->limit = limit;
- group->interval = interval;
- group->tick = gettick();
- group->valstr = NULL;
-
- ud->skillunit[i] = group;
-
- if (skillid == PR_SANCTUARY) //Sanctuary starts healing +1500ms after casted. [Skotlex]
- group->tick += 1500;
-
- idb_put(group_db, group->group_id, group);
- return group;
+struct skill_unit_group* skill_initunitgroup (struct block_list* src, int count, short skillid, short skilllv, int unit_id, int limit, int interval)
+{
+ struct unit_data* ud = unit_bl2ud( src );
+ struct skill_unit_group* group;
+ int i;
+
+ if(skillid <= 0 || skilllv <= 0) return 0;
+
+ nullpo_retr(NULL, src);
+ nullpo_retr(NULL, ud);
+
+ // find a free spot to store the new unit group
+ ARR_FIND( 0, MAX_SKILLUNITGROUP, i, ud->skillunit[i] == NULL );
+ if(i == MAX_SKILLUNITGROUP)
+ {
+ // array is full, make room by discarding oldest group
+ int j=0;
+ unsigned maxdiff=0,x,tick=gettick();
+ for(i=0;i<MAX_SKILLUNITGROUP && ud->skillunit[i];i++)
+ if((x=DIFF_TICK(tick,ud->skillunit[i]->tick))>maxdiff){
+ maxdiff=x;
+ j=i;
+ }
+ skill_delunitgroup(ud->skillunit[j]);
+ //Since elements must have shifted, we use the last slot.
+ i = MAX_SKILLUNITGROUP-1;
+ }
+
+ group = ers_alloc(skill_unit_ers, struct skill_unit_group);
+ group->src_id = src->id;
+ group->party_id = status_get_party_id(src);
+ group->guild_id = status_get_guild_id(src);
+ group->bg_id = bg_team_get_id(src);
+ group->group_id = skill_get_new_group_id();
+ group->unit = (struct skill_unit *)aCalloc(count,sizeof(struct skill_unit));
+ group->unit_count = count;
+ group->alive_count = 0;
+ group->val1 = 0;
+ group->val2 = 0;
+ group->val3 = 0;
+ group->skill_id = skillid;
+ group->skill_lv = skilllv;
+ group->unit_id = unit_id;
+ group->map = src->m;
+ group->limit = limit;
+ group->interval = interval;
+ group->tick = gettick();
+ group->valstr = NULL;
+
+ ud->skillunit[i] = group;
+
+ if (skillid == PR_SANCTUARY) //Sanctuary starts healing +1500ms after casted. [Skotlex]
+ group->tick += 1500;
+
+ idb_put(group_db, group->group_id, group);
+ return group;
}
/*==========================================
*
*------------------------------------------*/
-int skill_delunitgroup_(struct skill_unit_group *group, const char *file, int line, const char *func)
+int skill_delunitgroup_(struct skill_unit_group *group, const char* file, int line, const char* func)
{
- struct block_list *src;
- struct unit_data *ud;
- int i,j;
-
- if (group == NULL) {
- ShowDebug("skill_delunitgroup: group is NULL (source=%s:%d, %s)! Please report this! (#3504)\n", file, line, func);
- return 0;
- }
-
- src=map_id2bl(group->src_id);
- ud = unit_bl2ud(src);
- if (!src || !ud) {
- ShowError("skill_delunitgroup: Group's source not found! (src_id: %d skill_id: %d)\n", group->src_id, group->skill_id);
- return 0;
- }
-
- if (!status_isdead(src) && ((TBL_PC *)src)->state.warping && !((TBL_PC *)src)->state.changemap) {
- switch (group->skill_id) {
- case BA_DISSONANCE:
- case BA_POEMBRAGI:
- case BA_WHISTLE:
- case BA_ASSASSINCROSS:
- case BA_APPLEIDUN:
- case DC_UGLYDANCE:
- case DC_HUMMING:
- case DC_DONTFORGETME:
- case DC_FORTUNEKISS:
- case DC_SERVICEFORYOU:
- skill_usave_add(((TBL_PC *)src), group->skill_id, group->skill_lv);
- break;
- }
- }
-
- if (skill_get_unit_flag(group->skill_id)&(UF_DANCE|UF_SONG|UF_ENSEMBLE)) {
- struct status_change *sc = status_get_sc(src);
- if (sc && sc->data[SC_DANCING]) {
- sc->data[SC_DANCING]->val2 = 0 ; //This prevents status_change_end attempting to redelete the group. [Skotlex]
- status_change_end(src, SC_DANCING, INVALID_TIMER);
- }
- }
-
- // end Gospel's status change on 'src'
- // (needs to be done when the group is deleted by other means than skill deactivation)
- if (group->unit_id == UNT_GOSPEL) {
- struct status_change *sc = status_get_sc(src);
- if (sc && sc->data[SC_GOSPEL]) {
- sc->data[SC_GOSPEL]->val3 = 0; //Remove reference to this group. [Skotlex]
- status_change_end(src, SC_GOSPEL, INVALID_TIMER);
- }
- }
-
- switch (group->skill_id) {
- case SG_SUN_WARM:
- case SG_MOON_WARM:
- case SG_STAR_WARM: {
- struct status_change *sc = NULL;
- if ((sc = status_get_sc(src)) != NULL && sc->data[SC_WARM]) {
- sc->data[SC_WARM]->val4 = 0;
- status_change_end(src, SC_WARM, INVALID_TIMER);
- }
- }
- break;
- case NC_NEUTRALBARRIER: {
- struct status_change *sc = NULL;
- if ((sc = status_get_sc(src)) != NULL && sc->data[SC_NEUTRALBARRIER_MASTER]) {
- sc->data[SC_NEUTRALBARRIER_MASTER]->val2 = 0;
- status_change_end(src,SC_NEUTRALBARRIER_MASTER,INVALID_TIMER);
- }
- }
- break;
- case NC_STEALTHFIELD: {
- struct status_change *sc = NULL;
- if ((sc = status_get_sc(src)) != NULL && sc->data[SC_STEALTHFIELD_MASTER]) {
- sc->data[SC_STEALTHFIELD_MASTER]->val2 = 0;
- status_change_end(src,SC_STEALTHFIELD_MASTER,INVALID_TIMER);
- }
- }
- break;
- case LG_BANDING: {
- struct status_change *sc = NULL;
- if ((sc = status_get_sc(src)) && sc->data[SC_BANDING]) {
- sc->data[SC_BANDING]->val4 = 0;
- status_change_end(src,SC_BANDING,INVALID_TIMER);
- }
- }
- break;
- }
-
- if (src->type==BL_PC && group->state.ammo_consume)
- battle_consume_ammo((TBL_PC *)src, group->skill_id, group->skill_lv);
-
- group->alive_count=0;
-
- // remove all unit cells
- if (group->unit != NULL)
- for (i = 0; i < group->unit_count; i++)
- skill_delunit(&group->unit[i]);
-
- // clear Talkie-box string
- if (group->valstr != NULL) {
- aFree(group->valstr);
- group->valstr = NULL;
- }
-
- idb_remove(group_db, group->group_id);
- map_freeblock(&group->unit->bl); // schedules deallocation of whole array (HACK)
- group->unit=NULL;
- group->group_id=0;
- group->unit_count=0;
-
- // locate this group, swap with the last entry and delete it
- ARR_FIND(0, MAX_SKILLUNITGROUP, i, ud->skillunit[i] == group);
- ARR_FIND(i, MAX_SKILLUNITGROUP, j, ud->skillunit[j] == NULL);
- j--;
- if (i < MAX_SKILLUNITGROUP) {
- ud->skillunit[i] = ud->skillunit[j];
- ud->skillunit[j] = NULL;
- ers_free(skill_unit_ers, group);
- } else
- ShowError("skill_delunitgroup: Group not found! (src_id: %d skill_id: %d)\n", group->src_id, group->skill_id);
-
- return 1;
+ struct block_list* src;
+ struct unit_data *ud;
+ int i,j;
+
+ if( group == NULL )
+ {
+ ShowDebug("skill_delunitgroup: group is NULL (source=%s:%d, %s)! Please report this! (#3504)\n", file, line, func);
+ return 0;
+ }
+
+ src=map_id2bl(group->src_id);
+ ud = unit_bl2ud(src);
+ if(!src || !ud) {
+ ShowError("skill_delunitgroup: Group's source not found! (src_id: %d skill_id: %d)\n", group->src_id, group->skill_id);
+ return 0;
+ }
+
+ if( !status_isdead(src) && ((TBL_PC*)src)->state.warping && !((TBL_PC*)src)->state.changemap ) {
+ switch( group->skill_id ) {
+ case BA_DISSONANCE:
+ case BA_POEMBRAGI:
+ case BA_WHISTLE:
+ case BA_ASSASSINCROSS:
+ case BA_APPLEIDUN:
+ case DC_UGLYDANCE:
+ case DC_HUMMING:
+ case DC_DONTFORGETME:
+ case DC_FORTUNEKISS:
+ case DC_SERVICEFORYOU:
+ skill_usave_add(((TBL_PC*)src), group->skill_id, group->skill_lv);
+ break;
+ }
+ }
+
+ if (skill_get_unit_flag(group->skill_id)&(UF_DANCE|UF_SONG|UF_ENSEMBLE))
+ {
+ struct status_change* sc = status_get_sc(src);
+ if (sc && sc->data[SC_DANCING])
+ {
+ sc->data[SC_DANCING]->val2 = 0 ; //This prevents status_change_end attempting to redelete the group. [Skotlex]
+ status_change_end(src, SC_DANCING, INVALID_TIMER);
+ }
+ }
+
+ // end Gospel's status change on 'src'
+ // (needs to be done when the group is deleted by other means than skill deactivation)
+ if (group->unit_id == UNT_GOSPEL) {
+ struct status_change *sc = status_get_sc(src);
+ if(sc && sc->data[SC_GOSPEL]) {
+ sc->data[SC_GOSPEL]->val3 = 0; //Remove reference to this group. [Skotlex]
+ status_change_end(src, SC_GOSPEL, INVALID_TIMER);
+ }
+ }
+
+ switch( group->skill_id ) {
+ case SG_SUN_WARM:
+ case SG_MOON_WARM:
+ case SG_STAR_WARM:
+ {
+ struct status_change *sc = NULL;
+ if( (sc = status_get_sc(src)) != NULL && sc->data[SC_WARM] ) {
+ sc->data[SC_WARM]->val4 = 0;
+ status_change_end(src, SC_WARM, INVALID_TIMER);
+ }
+ }
+ break;
+ case NC_NEUTRALBARRIER:
+ {
+ struct status_change *sc = NULL;
+ if( (sc = status_get_sc(src)) != NULL && sc->data[SC_NEUTRALBARRIER_MASTER] ) {
+ sc->data[SC_NEUTRALBARRIER_MASTER]->val2 = 0;
+ status_change_end(src,SC_NEUTRALBARRIER_MASTER,INVALID_TIMER);
+ }
+ }
+ break;
+ case NC_STEALTHFIELD:
+ {
+ struct status_change *sc = NULL;
+ if( (sc = status_get_sc(src)) != NULL && sc->data[SC_STEALTHFIELD_MASTER] ) {
+ sc->data[SC_STEALTHFIELD_MASTER]->val2 = 0;
+ status_change_end(src,SC_STEALTHFIELD_MASTER,INVALID_TIMER);
+ }
+ }
+ break;
+ case LG_BANDING:
+ {
+ struct status_change *sc = NULL;
+ if( (sc = status_get_sc(src)) && sc->data[SC_BANDING] ) {
+ sc->data[SC_BANDING]->val4 = 0;
+ status_change_end(src,SC_BANDING,INVALID_TIMER);
+ }
+ }
+ break;
+ }
+
+ if (src->type==BL_PC && group->state.ammo_consume)
+ battle_consume_ammo((TBL_PC*)src, group->skill_id, group->skill_lv);
+
+ group->alive_count=0;
+
+ // remove all unit cells
+ if(group->unit != NULL)
+ for( i = 0; i < group->unit_count; i++ )
+ skill_delunit(&group->unit[i]);
+
+ // clear Talkie-box string
+ if( group->valstr != NULL )
+ {
+ aFree(group->valstr);
+ group->valstr = NULL;
+ }
+
+ idb_remove(group_db, group->group_id);
+ map_freeblock(&group->unit->bl); // schedules deallocation of whole array (HACK)
+ group->unit=NULL;
+ group->group_id=0;
+ group->unit_count=0;
+
+ // locate this group, swap with the last entry and delete it
+ ARR_FIND( 0, MAX_SKILLUNITGROUP, i, ud->skillunit[i] == group );
+ ARR_FIND( i, MAX_SKILLUNITGROUP, j, ud->skillunit[j] == NULL ); j--;
+ if( i < MAX_SKILLUNITGROUP )
+ {
+ ud->skillunit[i] = ud->skillunit[j];
+ ud->skillunit[j] = NULL;
+ ers_free(skill_unit_ers, group);
+ }
+ else
+ ShowError("skill_delunitgroup: Group not found! (src_id: %d skill_id: %d)\n", group->src_id, group->skill_id);
+
+ return 1;
}
/*==========================================
*
*------------------------------------------*/
-int skill_clear_unitgroup(struct block_list *src)
+int skill_clear_unitgroup (struct block_list *src)
{
- struct unit_data *ud = unit_bl2ud(src);
+ struct unit_data *ud = unit_bl2ud(src);
- nullpo_ret(ud);
+ nullpo_ret(ud);
- while (ud->skillunit[0])
- skill_delunitgroup(ud->skillunit[0]);
+ while (ud->skillunit[0])
+ skill_delunitgroup(ud->skillunit[0]);
- return 1;
+ return 1;
}
/*==========================================
*
*------------------------------------------*/
-struct skill_unit_group_tickset *skill_unitgrouptickset_search(struct block_list *bl, struct skill_unit_group *group, int tick) {
- int i,j=-1,k,s,id;
- struct unit_data *ud;
- struct skill_unit_group_tickset *set;
-
- nullpo_ret(bl);
- if (group->interval==-1)
- return NULL;
-
- ud = unit_bl2ud(bl);
- if (!ud) return NULL;
-
- set = ud->skillunittick;
-
- if (skill_get_unit_flag(group->skill_id)&UF_NOOVERLAP)
- id = s = group->skill_id;
- else
- id = s = group->group_id;
-
- 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 (j == -1) {
- ShowWarning("skill_unitgrouptickset_search: tickset is full\n");
- j = id % MAX_SKILLUNITGROUPTICKSET;
- }
-
- set[j].id = id;
- set[j].tick = tick;
- return &set[j];
+struct skill_unit_group_tickset *skill_unitgrouptickset_search (struct block_list *bl, struct skill_unit_group *group, int tick)
+{
+ int i,j=-1,k,s,id;
+ struct unit_data *ud;
+ struct skill_unit_group_tickset *set;
+
+ nullpo_ret(bl);
+ if (group->interval==-1)
+ return NULL;
+
+ ud = unit_bl2ud(bl);
+ if (!ud) return NULL;
+
+ set = ud->skillunittick;
+
+ if (skill_get_unit_flag(group->skill_id)&UF_NOOVERLAP)
+ id = s = group->skill_id;
+ else
+ id = s = group->group_id;
+
+ 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 (j == -1) {
+ ShowWarning ("skill_unitgrouptickset_search: tickset is full\n");
+ j = id % MAX_SKILLUNITGROUPTICKSET;
+ }
+
+ set[j].id = id;
+ set[j].tick = tick;
+ return &set[j];
}
/*==========================================
*
*------------------------------------------*/
-int skill_unit_timer_sub_onplace(struct block_list *bl, va_list ap)
+int skill_unit_timer_sub_onplace (struct block_list* bl, va_list ap)
{
- struct skill_unit *unit = va_arg(ap,struct skill_unit *);
- struct skill_unit_group *group = unit->group;
- unsigned int tick = va_arg(ap,unsigned int);
+ struct skill_unit* unit = va_arg(ap,struct skill_unit *);
+ struct skill_unit_group* group = unit->group;
+ unsigned int tick = va_arg(ap,unsigned int);
- if (!unit->alive || bl->prev == NULL)
- return 0;
+ if( !unit->alive || bl->prev == NULL )
+ return 0;
- nullpo_ret(group);
+ nullpo_ret(group);
- if (!(skill_get_inf2(group->skill_id)&(INF2_SONG_DANCE|INF2_TRAP|INF2_NOLP)) && map_getcell(bl->m, bl->x, bl->y, CELL_CHKLANDPROTECTOR))
- return 0; //AoE skills are ineffective. [Skotlex]
+ if( !(skill_get_inf2(group->skill_id)&(INF2_SONG_DANCE|INF2_TRAP|INF2_NOLP)) && map_getcell(bl->m, bl->x, bl->y, CELL_CHKLANDPROTECTOR) )
+ return 0; //AoE skills are ineffective. [Skotlex]
- if (battle_check_target(&unit->bl,bl,group->target_flag) <= 0)
- return 0;
+ if( battle_check_target(&unit->bl,bl,group->target_flag) <= 0 )
+ return 0;
- skill_unit_onplace_timer(unit,bl,tick);
+ skill_unit_onplace_timer(unit,bl,tick);
- return 1;
+ return 1;
}
/**
@@ -15407,327 +15279,344 @@ int skill_unit_timer_sub_onplace(struct block_list *bl, va_list ap)
*/
static int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap)
{
- struct skill_unit *unit = db_data2ptr(data);
- struct skill_unit_group *group = unit->group;
- unsigned int tick = va_arg(ap,unsigned int);
- bool dissonance;
- struct block_list *bl = &unit->bl;
-
- if (!unit->alive)
- return 0;
-
- nullpo_ret(group);
-
- // check for expiration
- if (!group->state.guildaura && (DIFF_TICK(tick,group->tick) >= group->limit || DIFF_TICK(tick,group->tick) >= unit->limit)) {
- // skill unit expired (inlined from skill_unit_onlimit())
- switch (group->unit_id) {
- case UNT_BLASTMINE:
+ struct skill_unit* unit = db_data2ptr(data);
+ struct skill_unit_group* group = unit->group;
+ unsigned int tick = va_arg(ap,unsigned int);
+ bool dissonance;
+ struct block_list* bl = &unit->bl;
+
+ if( !unit->alive )
+ return 0;
+
+ nullpo_ret(group);
+
+ // check for expiration
+ if( !group->state.guildaura && (DIFF_TICK(tick,group->tick) >= group->limit || DIFF_TICK(tick,group->tick) >= unit->limit) )
+ {// skill unit expired (inlined from skill_unit_onlimit())
+ switch( group->unit_id )
+ {
+ case UNT_BLASTMINE:
#ifdef RENEWAL
- case UNT_CLAYMORETRAP:
+ case UNT_CLAYMORETRAP:
#endif
- case UNT_GROUNDDRIFT_WIND:
- case UNT_GROUNDDRIFT_DARK:
- case UNT_GROUNDDRIFT_POISON:
- case UNT_GROUNDDRIFT_WATER:
- case UNT_GROUNDDRIFT_FIRE:
- group->unit_id = UNT_USED_TRAPS;
- //clif_changetraplook(bl, UNT_FIREPILLAR_ACTIVE);
- group->limit=DIFF_TICK(tick+1500,group->tick);
- unit->limit=DIFF_TICK(tick+1500,group->tick);
- break;
-
- case UNT_ANKLESNARE:
- case UNT_ELECTRICSHOCKER:
- if (group->val2 > 0) {
- // Used Trap don't returns back to item
- skill_delunit(unit);
- break;
- }
- case UNT_SKIDTRAP:
- case UNT_LANDMINE:
- case UNT_SHOCKWAVE:
- case UNT_SANDMAN:
- case UNT_FLASHER:
- case UNT_FREEZINGTRAP:
+ case UNT_GROUNDDRIFT_WIND:
+ case UNT_GROUNDDRIFT_DARK:
+ case UNT_GROUNDDRIFT_POISON:
+ case UNT_GROUNDDRIFT_WATER:
+ case UNT_GROUNDDRIFT_FIRE:
+ group->unit_id = UNT_USED_TRAPS;
+ //clif_changetraplook(bl, UNT_FIREPILLAR_ACTIVE);
+ group->limit=DIFF_TICK(tick+1500,group->tick);
+ unit->limit=DIFF_TICK(tick+1500,group->tick);
+ break;
+
+ case UNT_ANKLESNARE:
+ case UNT_ELECTRICSHOCKER:
+ if( group->val2 > 0 ) {
+ // Used Trap don't returns back to item
+ skill_delunit(unit);
+ break;
+ }
+ case UNT_SKIDTRAP:
+ case UNT_LANDMINE:
+ case UNT_SHOCKWAVE:
+ case UNT_SANDMAN:
+ case UNT_FLASHER:
+ case UNT_FREEZINGTRAP:
#ifndef RENEWAL
- case UNT_CLAYMORETRAP:
+ case UNT_CLAYMORETRAP:
#endif
- case UNT_TALKIEBOX:
- case UNT_CLUSTERBOMB:
- case UNT_MAGENTATRAP:
- case UNT_COBALTTRAP:
- case UNT_MAIZETRAP:
- case UNT_VERDURETRAP:
- case UNT_FIRINGTRAP:
- case UNT_ICEBOUNDTRAP:
-
- {
- struct block_list *src;
- if (unit->val1 > 0 && (src = map_id2bl(group->src_id)) != NULL && src->type == BL_PC) {
- // revert unit back into a trap
- struct item item_tmp;
- memset(&item_tmp,0,sizeof(item_tmp));
- item_tmp.nameid = group->item_id?group->item_id:ITEMID_TRAP;
- item_tmp.identify = 1;
- map_addflooritem(&item_tmp,1,bl->m,bl->x,bl->y,0,0,0,0);
- }
- skill_delunit(unit);
- }
- break;
-
- case UNT_WARP_ACTIVE:
- // warp portal opens (morph to a UNT_WARP_WAITING cell)
- group->unit_id = skill_get_unit_id(group->skill_id, 1); // UNT_WARP_WAITING
- clif_changelook(&unit->bl, LOOK_BASE, group->unit_id);
- // restart timers
- group->limit = skill_get_time(group->skill_id,group->skill_lv);
- unit->limit = skill_get_time(group->skill_id,group->skill_lv);
- // apply effect to all units standing on it
- map_foreachincell(skill_unit_effect,unit->bl.m,unit->bl.x,unit->bl.y,group->bl_flag,&unit->bl,gettick(),1);
- break;
-
- case UNT_CALLFAMILY: {
- struct map_session_data *sd = NULL;
- if (group->val1) {
- sd = map_charid2sd(group->val1);
- group->val1 = 0;
- if (sd && !map[sd->bl.m].flag.nowarp)
- pc_setpos(sd,map_id2index(unit->bl.m),unit->bl.x,unit->bl.y,CLR_TELEPORT);
- }
- if (group->val2) {
- sd = map_charid2sd(group->val2);
- group->val2 = 0;
- if (sd && !map[sd->bl.m].flag.nowarp)
- pc_setpos(sd,map_id2index(unit->bl.m),unit->bl.x,unit->bl.y,CLR_TELEPORT);
- }
- skill_delunit(unit);
- }
- break;
+ case UNT_TALKIEBOX:
+ case UNT_CLUSTERBOMB:
+ case UNT_MAGENTATRAP:
+ case UNT_COBALTTRAP:
+ case UNT_MAIZETRAP:
+ case UNT_VERDURETRAP:
+ case UNT_FIRINGTRAP:
+ case UNT_ICEBOUNDTRAP:
- case UNT_REVERBERATION:
- if (unit->val1 <= 0) { // If it was deactivated.
- skill_delunit(unit);
- break;
- }
- clif_changetraplook(bl,UNT_USED_TRAPS);
- map_foreachinrange(skill_trap_splash, bl, skill_get_splash(group->skill_id, group->skill_lv), group->bl_flag, bl, tick);
- group->limit = DIFF_TICK(tick,group->tick)+1000;
- unit->limit = DIFF_TICK(tick,group->tick)+1000;
- group->unit_id = UNT_USED_TRAPS;
- break;
-
- case UNT_FEINTBOMB: {
- struct block_list *src = map_id2bl(group->src_id);
- if (src)
- map_foreachinrange(skill_area_sub, &group->unit->bl, unit->range, splash_target(src), src, SC_FEINTBOMB, group->skill_lv, tick, BCT_ENEMY|SD_ANIMATION|1, skill_castend_damage_id);
- skill_delunit(unit);
- break;
- }
+ {
+ struct block_list* src;
+ if( unit->val1 > 0 && (src = map_id2bl(group->src_id)) != NULL && src->type == BL_PC )
+ { // revert unit back into a trap
+ struct item item_tmp;
+ memset(&item_tmp,0,sizeof(item_tmp));
+ item_tmp.nameid = group->item_id?group->item_id:ITEMID_TRAP;
+ item_tmp.identify = 1;
+ map_addflooritem(&item_tmp,1,bl->m,bl->x,bl->y,0,0,0,0);
+ }
+ skill_delunit(unit);
+ }
+ break;
+
+ case UNT_WARP_ACTIVE:
+ // warp portal opens (morph to a UNT_WARP_WAITING cell)
+ group->unit_id = skill_get_unit_id(group->skill_id, 1); // UNT_WARP_WAITING
+ clif_changelook(&unit->bl, LOOK_BASE, group->unit_id);
+ // restart timers
+ group->limit = skill_get_time(group->skill_id,group->skill_lv);
+ unit->limit = skill_get_time(group->skill_id,group->skill_lv);
+ // apply effect to all units standing on it
+ map_foreachincell(skill_unit_effect,unit->bl.m,unit->bl.x,unit->bl.y,group->bl_flag,&unit->bl,gettick(),1);
+ break;
+
+ case UNT_CALLFAMILY:
+ {
+ struct map_session_data *sd = NULL;
+ if(group->val1) {
+ sd = map_charid2sd(group->val1);
+ group->val1 = 0;
+ if (sd && !map[sd->bl.m].flag.nowarp)
+ pc_setpos(sd,map_id2index(unit->bl.m),unit->bl.x,unit->bl.y,CLR_TELEPORT);
+ }
+ if(group->val2) {
+ sd = map_charid2sd(group->val2);
+ group->val2 = 0;
+ if (sd && !map[sd->bl.m].flag.nowarp)
+ pc_setpos(sd,map_id2index(unit->bl.m),unit->bl.x,unit->bl.y,CLR_TELEPORT);
+ }
+ skill_delunit(unit);
+ }
+ break;
- case UNT_BANDING: {
- struct block_list *src = map_id2bl(group->src_id);
- struct status_change *sc;
- if (!src || (sc = status_get_sc(src)) == NULL || !sc->data[SC_BANDING]) {
- skill_delunit(unit);
- break;
- }
- // This unit isn't removed while SC_BANDING is active.
- group->limit = DIFF_TICK(tick+group->interval,group->tick);
- unit->limit = DIFF_TICK(tick+group->interval,group->tick);
- }
- break;
-
- default:
- skill_delunit(unit);
- }
- } else {
- // skill unit is still active
- switch (group->unit_id) {
- case UNT_ICEWALL:
- // icewall loses 50 hp every second
- unit->val1 -= SKILLUNITTIMER_INTERVAL/20; // trap's hp
- if (unit->val1 <= 0 && unit->limit + group->tick > tick + 700)
- unit->limit = DIFF_TICK(tick+700,group->tick);
- break;
- case UNT_BLASTMINE:
- case UNT_SKIDTRAP:
- case UNT_LANDMINE:
- case UNT_SHOCKWAVE:
- case UNT_SANDMAN:
- case UNT_FLASHER:
- case UNT_CLAYMORETRAP:
- case UNT_FREEZINGTRAP:
- case UNT_TALKIEBOX:
- case UNT_ANKLESNARE:
- if (unit->val1 <= 0) {
- if (group->unit_id == UNT_ANKLESNARE && group->val2 > 0)
- skill_delunit(unit);
- else {
- clif_changetraplook(bl, group->unit_id==UNT_LANDMINE?UNT_FIREPILLAR_ACTIVE:UNT_USED_TRAPS);
- group->limit = DIFF_TICK(tick, group->tick) + 1500;
- group->unit_id = UNT_USED_TRAPS;
- }
- }
- break;
- case UNT_REVERBERATION:
- if (unit->val1 <= 0) {
- clif_changetraplook(bl,UNT_USED_TRAPS);
- map_foreachinrange(skill_trap_splash, bl, skill_get_splash(group->skill_id, group->skill_lv), group->bl_flag, bl, tick);
- group->limit = DIFF_TICK(tick,group->tick)+1000;
- unit->limit = DIFF_TICK(tick,group->tick)+1000;
- group->unit_id = UNT_USED_TRAPS;
- }
- break;
- case UNT_WALLOFTHORN:
- if (unit->val1 <= 0) {
- group->unit_id = UNT_USED_TRAPS;
- group->limit = DIFF_TICK(tick, group->tick) + 1500;
- }
- break;
- }
- }
-
- //Don't continue if unit or even group is expired and has been deleted.
- if (!group || !unit->alive)
- return 0;
-
- dissonance = skill_dance_switch(unit, 0);
-
- if (unit->range >= 0 && group->interval != -1) {
- if (battle_config.skill_wall_check)
- map_foreachinshootrange(skill_unit_timer_sub_onplace, bl, unit->range, group->bl_flag, bl,tick);
- else
- map_foreachinrange(skill_unit_timer_sub_onplace, bl, unit->range, group->bl_flag, bl,tick);
-
- if (unit->range == -1) //Unit disabled, but it should not be deleted yet.
- group->unit_id = UNT_USED_TRAPS;
-
- if (group->unit_id == UNT_TATAMIGAESHI) {
- unit->range = -1; //Disable processed cell.
- if (--group->val1 <= 0) { // number of live cells
- //All tiles were processed, disable skill.
- group->target_flag=BCT_NOONE;
- group->bl_flag= BL_NUL;
- }
- }
- }
+ case UNT_REVERBERATION:
+ if( unit->val1 <= 0 ) { // If it was deactivated.
+ skill_delunit(unit);
+ break;
+ }
+ clif_changetraplook(bl,UNT_USED_TRAPS);
+ map_foreachinrange(skill_trap_splash, bl, skill_get_splash(group->skill_id, group->skill_lv), group->bl_flag, bl, tick);
+ group->limit = DIFF_TICK(tick,group->tick)+1000;
+ unit->limit = DIFF_TICK(tick,group->tick)+1000;
+ group->unit_id = UNT_USED_TRAPS;
+ break;
+
+ case UNT_FEINTBOMB: {
+ struct block_list *src = map_id2bl(group->src_id);
+ if( src )
+ map_foreachinrange(skill_area_sub, &group->unit->bl, unit->range, splash_target(src), src, SC_FEINTBOMB, group->skill_lv, tick, BCT_ENEMY|SD_ANIMATION|1, skill_castend_damage_id);
+ skill_delunit(unit);
+ break;
+ }
- if (dissonance) skill_dance_switch(unit, 1);
+ case UNT_BANDING:
+ {
+ struct block_list *src = map_id2bl(group->src_id);
+ struct status_change *sc;
+ if( !src || (sc = status_get_sc(src)) == NULL || !sc->data[SC_BANDING] )
+ {
+ skill_delunit(unit);
+ break;
+ }
+ // This unit isn't removed while SC_BANDING is active.
+ group->limit = DIFF_TICK(tick+group->interval,group->tick);
+ unit->limit = DIFF_TICK(tick+group->interval,group->tick);
+ }
+ break;
+
+ default:
+ skill_delunit(unit);
+ }
+ }
+ else
+ {// skill unit is still active
+ switch( group->unit_id )
+ {
+ case UNT_ICEWALL:
+ // icewall loses 50 hp every second
+ unit->val1 -= SKILLUNITTIMER_INTERVAL/20; // trap's hp
+ if( unit->val1 <= 0 && unit->limit + group->tick > tick + 700 )
+ unit->limit = DIFF_TICK(tick+700,group->tick);
+ break;
+ case UNT_BLASTMINE:
+ case UNT_SKIDTRAP:
+ case UNT_LANDMINE:
+ case UNT_SHOCKWAVE:
+ case UNT_SANDMAN:
+ case UNT_FLASHER:
+ case UNT_CLAYMORETRAP:
+ case UNT_FREEZINGTRAP:
+ case UNT_TALKIEBOX:
+ case UNT_ANKLESNARE:
+ if( unit->val1 <= 0 ) {
+ if( group->unit_id == UNT_ANKLESNARE && group->val2 > 0 )
+ skill_delunit(unit);
+ else {
+ clif_changetraplook(bl, group->unit_id==UNT_LANDMINE?UNT_FIREPILLAR_ACTIVE:UNT_USED_TRAPS);
+ group->limit = DIFF_TICK(tick, group->tick) + 1500;
+ group->unit_id = UNT_USED_TRAPS;
+ }
+ }
+ break;
+ case UNT_REVERBERATION:
+ if( unit->val1 <= 0 ){
+ clif_changetraplook(bl,UNT_USED_TRAPS);
+ map_foreachinrange(skill_trap_splash, bl, skill_get_splash(group->skill_id, group->skill_lv), group->bl_flag, bl, tick);
+ group->limit = DIFF_TICK(tick,group->tick)+1000;
+ unit->limit = DIFF_TICK(tick,group->tick)+1000;
+ group->unit_id = UNT_USED_TRAPS;
+ }
+ break;
+ case UNT_WALLOFTHORN:
+ if( unit->val1 <= 0 ) {
+ group->unit_id = UNT_USED_TRAPS;
+ group->limit = DIFF_TICK(tick, group->tick) + 1500;
+ }
+ break;
+ }
+ }
+
+ //Don't continue if unit or even group is expired and has been deleted.
+ if( !group || !unit->alive )
+ return 0;
+
+ dissonance = skill_dance_switch(unit, 0);
+
+ if( unit->range >= 0 && group->interval != -1 )
+ {
+ if( battle_config.skill_wall_check )
+ map_foreachinshootrange(skill_unit_timer_sub_onplace, bl, unit->range, group->bl_flag, bl,tick);
+ else
+ map_foreachinrange(skill_unit_timer_sub_onplace, bl, unit->range, group->bl_flag, bl,tick);
+
+ if(unit->range == -1) //Unit disabled, but it should not be deleted yet.
+ group->unit_id = UNT_USED_TRAPS;
+
+ if( group->unit_id == UNT_TATAMIGAESHI )
+ {
+ unit->range = -1; //Disable processed cell.
+ if (--group->val1 <= 0) // number of live cells
+ { //All tiles were processed, disable skill.
+ group->target_flag=BCT_NOONE;
+ group->bl_flag= BL_NUL;
+ }
+ }
+ }
- return 0;
+ if( dissonance ) skill_dance_switch(unit, 1);
+
+ return 0;
}
/*==========================================
* Executes on all skill units every SKILLUNITTIMER_INTERVAL miliseconds.
*------------------------------------------*/
int skill_unit_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- map_freeblock_lock();
+ map_freeblock_lock();
- skillunit_db->foreach(skillunit_db, skill_unit_timer_sub, tick);
+ skillunit_db->foreach(skillunit_db, skill_unit_timer_sub, tick);
- map_freeblock_unlock();
+ map_freeblock_unlock();
- return 0;
+ return 0;
}
static int skill_unit_temp[20]; // temporary storage for tracking skill unit skill ids as players move in/out of them
/*==========================================
*
*------------------------------------------*/
-int skill_unit_move_sub(struct block_list *bl, va_list ap)
+int skill_unit_move_sub (struct block_list* bl, va_list ap)
{
- struct skill_unit *unit = (struct skill_unit *)bl;
- struct skill_unit_group *group = unit->group;
-
- struct block_list *target = va_arg(ap,struct block_list *);
- unsigned int tick = va_arg(ap,unsigned int);
- int flag = va_arg(ap,int);
-
- bool dissonance;
- int skill_id;
- int i;
-
- nullpo_ret(group);
-
- if (!unit->alive || target->prev == NULL)
- return 0;
-
- if (flag&1 && (unit->group->skill_id == PF_SPIDERWEB || unit->group->skill_id == GN_THORNS_TRAP))
- return 0; // Fiberlock is never supposed to trigger on skill_unit_move. [Inkfish]
-
- dissonance = skill_dance_switch(unit, 0);
-
- //Necessary in case the group is deleted after calling on_place/on_out [Skotlex]
- skill_id = unit->group->skill_id;
-
- if (unit->group->interval != -1 && !(skill_get_unit_flag(skill_id)&UF_DUALMODE) && skill_id != BD_LULLABY) { //Lullaby is the exception, bugreport:411
- //Non-dualmode unit skills with a timer don't trigger when walking, so just return
- if (dissonance) skill_dance_switch(unit, 1);
- return 0;
- }
-
- //Target-type check.
- if (!(group->bl_flag&target->type && battle_check_target(&unit->bl,target,group->target_flag) > 0)) {
- if (group->src_id == target->id && group->state.song_dance&0x2) {
- //Ensemble check to see if they went out/in of the area [Skotlex]
- if (flag&1) {
- if (flag&2) {
- //Clear this skill id.
- ARR_FIND(0, ARRAYLENGTH(skill_unit_temp), i, skill_unit_temp[i] == skill_id);
- if (i < ARRAYLENGTH(skill_unit_temp))
- skill_unit_temp[i] = 0;
- }
- } else {
- if (flag&2) {
- //Store this skill id.
- ARR_FIND(0, ARRAYLENGTH(skill_unit_temp), i, skill_unit_temp[i] == 0);
- if (i < ARRAYLENGTH(skill_unit_temp))
- skill_unit_temp[i] = skill_id;
- else
- ShowError("skill_unit_move_sub: Reached limit of unit objects per cell!\n");
- }
+ struct skill_unit* unit = (struct skill_unit *)bl;
+ struct skill_unit_group* group = unit->group;
- }
+ struct block_list* target = va_arg(ap,struct block_list*);
+ unsigned int tick = va_arg(ap,unsigned int);
+ int flag = va_arg(ap,int);
- if (flag&4)
- skill_unit_onleft(skill_id,target,tick);
- }
-
- if (dissonance) skill_dance_switch(unit, 1);
-
- return 0;
- } else {
- if (flag&1) {
- int result = skill_unit_onplace(unit,target,tick);
- if (flag&2 && result) {
- //Clear skill ids we have stored in onout.
- ARR_FIND(0, ARRAYLENGTH(skill_unit_temp), i, skill_unit_temp[i] == result);
- if (i < ARRAYLENGTH(skill_unit_temp))
- skill_unit_temp[i] = 0;
- }
- } else {
- int result = skill_unit_onout(unit,target,tick);
- if (flag&2 && result) {
- //Store this unit id.
- ARR_FIND(0, ARRAYLENGTH(skill_unit_temp), i, skill_unit_temp[i] == 0);
- if (i < ARRAYLENGTH(skill_unit_temp))
- skill_unit_temp[i] = skill_id;
- else
- ShowError("skill_unit_move_sub: Reached limit of unit objects per cell!\n");
- }
- }
+ bool dissonance;
+ int skill_id;
+ int i;
+
+ nullpo_ret(group);
+
+ if( !unit->alive || target->prev == NULL )
+ return 0;
+
+ if( flag&1 && ( unit->group->skill_id == PF_SPIDERWEB || unit->group->skill_id == GN_THORNS_TRAP ) )
+ return 0; // Fiberlock is never supposed to trigger on skill_unit_move. [Inkfish]
- //TODO: Normally, this is dangerous since the unit and group could be freed
- //inside the onout/onplace functions. Currently it is safe because we know song/dance
- //cells do not get deleted within them. [Skotlex]
- if (dissonance) skill_dance_switch(unit, 1);
+ dissonance = skill_dance_switch(unit, 0);
- if (flag&4)
- skill_unit_onleft(skill_id,target,tick);
+ //Necessary in case the group is deleted after calling on_place/on_out [Skotlex]
+ skill_id = unit->group->skill_id;
- return 1;
- }
+ if( unit->group->interval != -1 && !(skill_get_unit_flag(skill_id)&UF_DUALMODE) && skill_id != BD_LULLABY ) //Lullaby is the exception, bugreport:411
+ { //Non-dualmode unit skills with a timer don't trigger when walking, so just return
+ if( dissonance ) skill_dance_switch(unit, 1);
+ return 0;
+ }
+
+ //Target-type check.
+ if( !(group->bl_flag&target->type && battle_check_target(&unit->bl,target,group->target_flag) > 0) )
+ {
+ if( group->src_id == target->id && group->state.song_dance&0x2 )
+ { //Ensemble check to see if they went out/in of the area [Skotlex]
+ if( flag&1 )
+ {
+ if( flag&2 )
+ { //Clear this skill id.
+ ARR_FIND( 0, ARRAYLENGTH(skill_unit_temp), i, skill_unit_temp[i] == skill_id );
+ if( i < ARRAYLENGTH(skill_unit_temp) )
+ skill_unit_temp[i] = 0;
+ }
+ }
+ else
+ {
+ if( flag&2 )
+ { //Store this skill id.
+ ARR_FIND( 0, ARRAYLENGTH(skill_unit_temp), i, skill_unit_temp[i] == 0 );
+ if( i < ARRAYLENGTH(skill_unit_temp) )
+ skill_unit_temp[i] = skill_id;
+ else
+ ShowError("skill_unit_move_sub: Reached limit of unit objects per cell!\n");
+ }
+
+ }
+
+ if( flag&4 )
+ skill_unit_onleft(skill_id,target,tick);
+ }
+
+ if( dissonance ) skill_dance_switch(unit, 1);
+
+ return 0;
+ }
+ else
+ {
+ if( flag&1 )
+ {
+ int result = skill_unit_onplace(unit,target,tick);
+ if( flag&2 && result )
+ { //Clear skill ids we have stored in onout.
+ ARR_FIND( 0, ARRAYLENGTH(skill_unit_temp), i, skill_unit_temp[i] == result );
+ if( i < ARRAYLENGTH(skill_unit_temp) )
+ skill_unit_temp[i] = 0;
+ }
+ }
+ else
+ {
+ int result = skill_unit_onout(unit,target,tick);
+ if( flag&2 && result )
+ { //Store this unit id.
+ ARR_FIND( 0, ARRAYLENGTH(skill_unit_temp), i, skill_unit_temp[i] == 0 );
+ if( i < ARRAYLENGTH(skill_unit_temp) )
+ skill_unit_temp[i] = skill_id;
+ else
+ ShowError("skill_unit_move_sub: Reached limit of unit objects per cell!\n");
+ }
+ }
+
+ //TODO: Normally, this is dangerous since the unit and group could be freed
+ //inside the onout/onplace functions. Currently it is safe because we know song/dance
+ //cells do not get deleted within them. [Skotlex]
+ if( dissonance ) skill_dance_switch(unit, 1);
+
+ if( flag&4 )
+ skill_unit_onleft(skill_id,target,tick);
+
+ return 1;
+ }
}
/*==========================================
@@ -15738,1199 +15627,1156 @@ int skill_unit_move_sub(struct block_list *bl, va_list ap)
* units to figure out when they have left a group.
* flag&4: Force a onleft event (triggered when the bl is killed, for example)
*------------------------------------------*/
-int skill_unit_move(struct block_list *bl, unsigned int tick, int flag)
+int skill_unit_move (struct block_list *bl, unsigned int tick, int flag)
{
- nullpo_ret(bl);
+ nullpo_ret(bl);
- if (bl->prev == NULL)
- return 0;
+ if( bl->prev == NULL )
+ return 0;
- if (flag&2 && !(flag&1)) {
- //Onout, clear data
- memset(skill_unit_temp, 0, sizeof(skill_unit_temp));
- }
+ if( flag&2 && !(flag&1) )
+ { //Onout, clear data
+ memset(skill_unit_temp, 0, sizeof(skill_unit_temp));
+ }
- map_foreachincell(skill_unit_move_sub,bl->m,bl->x,bl->y,BL_SKILL,bl,tick,flag);
+ map_foreachincell(skill_unit_move_sub,bl->m,bl->x,bl->y,BL_SKILL,bl,tick,flag);
- if (flag&2 && flag&1) {
- //Onplace, check any skill units you have left.
- int i;
- for (i = 0; i < ARRAYLENGTH(skill_unit_temp); i++)
- if (skill_unit_temp[i])
- skill_unit_onleft(skill_unit_temp[i], bl, tick);
- }
+ if( flag&2 && flag&1 )
+ { //Onplace, check any skill units you have left.
+ int i;
+ for( i = 0; i < ARRAYLENGTH(skill_unit_temp); i++ )
+ if( skill_unit_temp[i] )
+ skill_unit_onleft(skill_unit_temp[i], bl, tick);
+ }
- return 0;
+ return 0;
}
/*==========================================
*
*------------------------------------------*/
-int skill_unit_move_unit_group(struct skill_unit_group *group, int m, int dx, int dy)
+int skill_unit_move_unit_group (struct skill_unit_group *group, int m, int dx, int dy)
{
- int i,j;
- unsigned int tick = gettick();
- int *m_flag;
- struct skill_unit *unit1;
- struct skill_unit *unit2;
-
- if (group == NULL)
- return 0;
- if (group->unit_count<=0)
- return 0;
- if (group->unit==NULL)
- return 0;
-
- if (skill_get_unit_flag(group->skill_id)&UF_ENSEMBLE)
- return 0; //Ensembles may not be moved around.
-
- if (group->unit_id == UNT_ICEWALL || group->unit_id == UNT_WALLOFTHORN)
- return 0; //Icewalls and Wall of Thorns don't get knocked back
-
- m_flag = (int *) aCalloc(group->unit_count, sizeof(int));
- // m_flag
- // 0: Neither of the following (skill_unit_onplace & skill_unit_onout are needed)
- // 1: Unit will move to a slot that had another unit of the same group (skill_unit_onplace not needed)
- // 2: Another unit from same group will end up positioned on this unit (skill_unit_onout not needed)
- // 3: Both 1+2.
- 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) {
- m_flag[i] |= 0x1;
- }
- if (unit1->bl.x-dx==unit2->bl.x && unit1->bl.y-dy==unit2->bl.y) {
- m_flag[i] |= 0x2;
- }
- }
- }
- j = 0;
- for (i=0; i<group->unit_count; i++) {
- unit1=&group->unit[i];
- if (!unit1->alive)
- continue;
- if (!(m_flag[i]&0x2)) {
- if (group->state.song_dance&0x1) //Cancel dissonance effect.
- skill_dance_overlap(unit1, 0);
- map_foreachincell(skill_unit_effect,unit1->bl.m,unit1->bl.x,unit1->bl.y,group->bl_flag,&unit1->bl,tick,4);
- }
- //Move Cell using "smart" criteria (avoid useless moving around)
- switch (m_flag[i]) {
- case 0:
- //Cell moves independently, safely move it.
- map_moveblock(&unit1->bl, unit1->bl.x+dx, unit1->bl.y+dy, tick);
- break;
- case 1:
- //Cell moves unto another cell, look for a replacement cell that won't collide
- //and has no cell moving into it (flag == 2)
- for (; j<group->unit_count; j++) {
- if (m_flag[j]!=2 || !group->unit[j].alive)
- continue;
- //Move to where this cell would had moved.
- unit2 = &group->unit[j];
- map_moveblock(&unit1->bl, unit2->bl.x+dx, unit2->bl.y+dy, tick);
- j++; //Skip this cell as we have used it.
- break;
- }
- break;
- case 2:
- case 3:
- break; //Don't move the cell as a cell will end on this tile anyway.
- }
- if (!(m_flag[i]&0x2)) { //We only moved the cell in 0-1
- if (group->state.song_dance&0x1) //Check for dissonance effect.
- skill_dance_overlap(unit1, 1);
- clif_skill_setunit(unit1);
- map_foreachincell(skill_unit_effect,unit1->bl.m,unit1->bl.x,unit1->bl.y,group->bl_flag,&unit1->bl,tick,1);
- }
- }
- aFree(m_flag);
- return 0;
+ int i,j;
+ unsigned int tick = gettick();
+ int *m_flag;
+ struct skill_unit *unit1;
+ struct skill_unit *unit2;
+
+ if (group == NULL)
+ return 0;
+ if (group->unit_count<=0)
+ return 0;
+ if (group->unit==NULL)
+ return 0;
+
+ if (skill_get_unit_flag(group->skill_id)&UF_ENSEMBLE)
+ return 0; //Ensembles may not be moved around.
+
+ if( group->unit_id == UNT_ICEWALL || group->unit_id == UNT_WALLOFTHORN )
+ return 0; //Icewalls and Wall of Thorns don't get knocked back
+
+ m_flag = (int *) aCalloc(group->unit_count, sizeof(int));
+ // m_flag
+ // 0: Neither of the following (skill_unit_onplace & skill_unit_onout are needed)
+ // 1: Unit will move to a slot that had another unit of the same group (skill_unit_onplace not needed)
+ // 2: Another unit from same group will end up positioned on this unit (skill_unit_onout not needed)
+ // 3: Both 1+2.
+ 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){
+ m_flag[i] |= 0x1;
+ }
+ if (unit1->bl.x-dx==unit2->bl.x && unit1->bl.y-dy==unit2->bl.y){
+ m_flag[i] |= 0x2;
+ }
+ }
+ }
+ j = 0;
+ for (i=0;i<group->unit_count;i++) {
+ unit1=&group->unit[i];
+ if (!unit1->alive)
+ continue;
+ if (!(m_flag[i]&0x2)) {
+ if (group->state.song_dance&0x1) //Cancel dissonance effect.
+ skill_dance_overlap(unit1, 0);
+ map_foreachincell(skill_unit_effect,unit1->bl.m,unit1->bl.x,unit1->bl.y,group->bl_flag,&unit1->bl,tick,4);
+ }
+ //Move Cell using "smart" criteria (avoid useless moving around)
+ switch(m_flag[i])
+ {
+ case 0:
+ //Cell moves independently, safely move it.
+ map_moveblock(&unit1->bl, unit1->bl.x+dx, unit1->bl.y+dy, tick);
+ break;
+ case 1:
+ //Cell moves unto another cell, look for a replacement cell that won't collide
+ //and has no cell moving into it (flag == 2)
+ for(;j<group->unit_count;j++)
+ {
+ if(m_flag[j]!=2 || !group->unit[j].alive)
+ continue;
+ //Move to where this cell would had moved.
+ unit2 = &group->unit[j];
+ map_moveblock(&unit1->bl, unit2->bl.x+dx, unit2->bl.y+dy, tick);
+ j++; //Skip this cell as we have used it.
+ break;
+ }
+ break;
+ case 2:
+ case 3:
+ break; //Don't move the cell as a cell will end on this tile anyway.
+ }
+ if (!(m_flag[i]&0x2)) { //We only moved the cell in 0-1
+ if (group->state.song_dance&0x1) //Check for dissonance effect.
+ skill_dance_overlap(unit1, 1);
+ clif_skill_setunit(unit1);
+ map_foreachincell(skill_unit_effect,unit1->bl.m,unit1->bl.x,unit1->bl.y,group->bl_flag,&unit1->bl,tick,1);
+ }
+ }
+ aFree(m_flag);
+ return 0;
}
/*==========================================
*
*------------------------------------------*/
-int skill_can_produce_mix(struct map_session_data *sd, int nameid, int trigger, int qty)
+int skill_can_produce_mix (struct map_session_data *sd, int nameid, int trigger, int qty)
{
- int i,j;
-
- nullpo_ret(sd);
-
- if (nameid<=0)
- return 0;
+ int i,j;
+
+ nullpo_ret(sd);
+
+ if(nameid<=0)
+ return 0;
+
+ for(i=0;i<MAX_SKILL_PRODUCE_DB;i++){
+ if(skill_produce_db[i].nameid == nameid ){
+ if((j=skill_produce_db[i].req_skill)>0 &&
+ pc_checkskill(sd,j) < skill_produce_db[i].req_skill_lv)
+ continue; // must iterate again to check other skills that produce it. [malufett]
+ if( j > 0 && sd->menuskill_id > 0 && sd->menuskill_id != j )
+ continue; // special case
+ break;
+ }
+ }
- for (i=0; i<MAX_SKILL_PRODUCE_DB; i++) {
- if (skill_produce_db[i].nameid == nameid) {
- if ((j=skill_produce_db[i].req_skill)>0 &&
- pc_checkskill(sd,j) < skill_produce_db[i].req_skill_lv)
- continue; // must iterate again to check other skills that produce it. [malufett]
- if (j > 0 && sd->menuskill_id > 0 && sd->menuskill_id != j)
- continue; // special case
- break;
- }
- }
+ if( i >= MAX_SKILL_PRODUCE_DB )
+ return 0;
- if (i >= MAX_SKILL_PRODUCE_DB)
- return 0;
+ if( pc_checkadditem(sd, nameid, qty) == ADDITEM_OVERAMOUNT )
+ {// cannot carry the produced stuff
+ return 0;
+ }
- if (pc_checkadditem(sd, nameid, qty) == ADDITEM_OVERAMOUNT) {
- // cannot carry the produced stuff
- return 0;
- }
+ if(trigger>=0){
+ if(trigger>20) { // Non-weapon, non-food item (itemlv must match)
+ if(skill_produce_db[i].itemlv!=trigger)
+ return 0;
+ } else if(trigger>10) { // Food (any item level between 10 and 20 will do)
+ if(skill_produce_db[i].itemlv<=10 || skill_produce_db[i].itemlv>20)
+ return 0;
+ } else { // Weapon (itemlv must be higher or equal)
+ if(skill_produce_db[i].itemlv>trigger)
+ return 0;
+ }
+ }
- if (trigger>=0) {
- if (trigger>20) { // Non-weapon, non-food item (itemlv must match)
- if (skill_produce_db[i].itemlv!=trigger)
- return 0;
- } else if (trigger>10) { // Food (any item level between 10 and 20 will do)
- if (skill_produce_db[i].itemlv<=10 || skill_produce_db[i].itemlv>20)
- return 0;
- } else { // Weapon (itemlv must be higher or equal)
- if (skill_produce_db[i].itemlv>trigger)
- return 0;
- }
- }
-
- for (j=0; j<MAX_PRODUCE_RESOURCE; j++) {
- int id,x,y;
- if ((id=skill_produce_db[i].mat_id[j]) <= 0)
- continue;
- if (skill_produce_db[i].mat_amount[j] <= 0) {
- if (pc_search_inventory(sd,id) < 0)
- return 0;
- } else {
- for (y=0,x=0; y<MAX_INVENTORY; y++)
- if (sd->status.inventory[y].nameid == id)
- x+=sd->status.inventory[y].amount;
- if (x<qty*skill_produce_db[i].mat_amount[j])
- return 0;
- }
- }
- return i+1;
+ for(j=0;j<MAX_PRODUCE_RESOURCE;j++){
+ int id,x,y;
+ if( (id=skill_produce_db[i].mat_id[j]) <= 0 )
+ continue;
+ if(skill_produce_db[i].mat_amount[j] <= 0) {
+ if(pc_search_inventory(sd,id) < 0)
+ return 0;
+ }
+ else {
+ for(y=0,x=0;y<MAX_INVENTORY;y++)
+ if( sd->status.inventory[y].nameid == id )
+ x+=sd->status.inventory[y].amount;
+ if(x<qty*skill_produce_db[i].mat_amount[j])
+ return 0;
+ }
+ }
+ return i+1;
}
/*==========================================
*
*------------------------------------------*/
-int skill_produce_mix(struct map_session_data *sd, int skill_id, int nameid, int slot1, int slot2, int slot3, int qty)
+int skill_produce_mix (struct map_session_data *sd, int skill_id, int nameid, int slot1, int slot2, int slot3, int qty)
{
- int slot[3];
- int i,sc,ele,idx,equip,wlv,make_per = 0,flag = 0,skilllv = 0;
- int num = -1; // exclude the recipe
- struct status_data *status;
- struct item_data *data;
-
- nullpo_ret(sd);
- status = status_get_status_data(&sd->bl);
-
- if (sd->skillid_old == skill_id)
- skilllv = sd->skilllv_old;
-
- if (!(idx=skill_can_produce_mix(sd,nameid,-1, qty)))
- return 0;
- idx--;
-
- if (qty < 1)
- qty = 1;
-
- if (!skill_id) //A skill can be specified for some override cases.
- skill_id = skill_produce_db[idx].req_skill;
-
- if (skill_id == GC_RESEARCHNEWPOISON)
- skill_id = GC_CREATENEWPOISON;
-
- slot[0]=slot1;
- slot[1]=slot2;
- slot[2]=slot3;
-
- for (i=0,sc=0,ele=0; i<3; i++) { //Note that qty should always be one if you are using these!
- int j;
- if (slot[i]<=0)
- continue;
- j = pc_search_inventory(sd,slot[i]);
- if (j < 0)
- continue;
- if (slot[i]==1000) { /* Star Crumb */
- pc_delitem(sd,j,1,1,0,LOG_TYPE_PRODUCE);
- sc++;
- }
- if (slot[i]>=994 && slot[i]<=997 && ele==0) { /* Flame Heart . . . Great Nature */
- static const int ele_table[4]= {3,1,4,2};
- pc_delitem(sd,j,1,1,0,LOG_TYPE_PRODUCE);
- ele=ele_table[slot[i]-994];
- }
- }
-
- if (skill_id == RK_RUNEMASTERY) {
- int temp_qty, skill_lv = pc_checkskill(sd,skill_id);
- data = itemdb_search(nameid);
-
- if (skill_lv == 10) temp_qty = 1 + rnd()%3;
- else if (skill_lv > 5) temp_qty = 1 + rnd()%2;
- else temp_qty = 1;
-
- if (data->stack.inventory) {
- for (i = 0; i < MAX_INVENTORY; i++) {
- if (sd->status.inventory[i].nameid == nameid) {
- if (sd->status.inventory[i].amount >= data->stack.amount) {
- clif_msgtable(sd->fd,0x61b);
- return 0;
- } else {
- /**
- * the amount fits, say we got temp_qty 4 and 19 runes, we trim temp_qty to 1.
- **/
- if (temp_qty + sd->status.inventory[i].amount >= data->stack.amount)
- temp_qty = data->stack.amount - sd->status.inventory[i].amount;
- }
- break;
- }
- }
- }
- qty = temp_qty;
- }
-
- for (i=0; i<MAX_PRODUCE_RESOURCE; i++) {
- int j,id,x;
- if ((id=skill_produce_db[idx].mat_id[i]) <= 0)
- continue;
- num++;
- x=(skill_id == RK_RUNEMASTERY ? 1 : qty)*skill_produce_db[idx].mat_amount[i];
- do {
- int y=0;
- j = pc_search_inventory(sd,id);
-
- if (j >= 0) {
- y = sd->status.inventory[j].amount;
- if (y>x)y=x;
- pc_delitem(sd,j,y,0,0,LOG_TYPE_PRODUCE);
- } else
- ShowError("skill_produce_mix: material item error\n");
-
- x-=y;
- } while (j>=0 && x>0);
- }
-
- if ((equip = (itemdb_isequip(nameid) && skill_id != GN_CHANGEMATERIAL && skill_id != GN_MAKEBOMB)))
- wlv = itemdb_wlv(nameid);
- if (!equip) {
- switch (skill_id) {
- case BS_IRON:
- case BS_STEEL:
- case BS_ENCHANTEDSTONE:
- // Ores & Metals Refining - skill bonuses are straight from kRO website [DracoRPG]
- i = pc_checkskill(sd,skill_id);
- make_per = sd->status.job_level*20 + status->dex*10 + status->luk*10; //Base chance
- switch (nameid) {
- case 998: // Iron
- make_per += 4000+i*500; // Temper Iron bonus: +26/+32/+38/+44/+50
- break;
- case 999: // Steel
- make_per += 3000+i*500; // Temper Steel bonus: +35/+40/+45/+50/+55
- break;
- case 1000: //Star Crumb
- make_per = 100000; // Star Crumbs are 100% success crafting rate? (made 1000% so it succeeds even after penalties) [Skotlex]
- break;
- default: // Enchanted Stones
- make_per += 1000+i*500; // Enchantedstone Craft bonus: +15/+20/+25/+30/+35
- break;
- }
- break;
- case ASC_CDP:
- make_per = (2000 + 40*status->dex + 20*status->luk);
- break;
- case AL_HOLYWATER:
- /**
- * Arch Bishop
- **/
- case AB_ANCILLA:
- make_per = 100000; //100% success
- break;
- case AM_PHARMACY: // Potion Preparation - reviewed with the help of various Ragnainfo sources [DracoRPG]
- case AM_TWILIGHT1:
- case AM_TWILIGHT2:
- case AM_TWILIGHT3:
- make_per = pc_checkskill(sd,AM_LEARNINGPOTION)*50
- + pc_checkskill(sd,AM_PHARMACY)*300 + sd->status.job_level*20
- + (status->int_/2)*10 + status->dex*10+status->luk*10;
- if (merc_is_hom_active(sd->hd)) { //Player got a homun
- int skill;
- if ((skill=merc_hom_checkskill(sd->hd,HVAN_INSTRUCT)) > 0) //His homun is a vanil with instruction change
- make_per += skill*100; //+1% bonus per level
- }
- switch (nameid) {
- case 501: // Red Potion
- case 503: // Yellow Potion
- case 504: // White Potion
- make_per += (1+rnd()%100)*10 + 2000;
- break;
- case 970: // Alcohol
- make_per += (1+rnd()%100)*10 + 1000;
- break;
- case 7135: // Bottle Grenade
- case 7136: // Acid Bottle
- case 7137: // Plant Bottle
- case 7138: // Marine Sphere Bottle
- make_per += (1+rnd()%100)*10;
- break;
- case 546: // Condensed Yellow Potion
- make_per -= (1+rnd()%50)*10;
- break;
- case 547: // Condensed White Potion
- case 7139: // Glistening Coat
- make_per -= (1+rnd()%100)*10;
- break;
- //Common items, recieve no bonus or penalty, listed just because they are commonly produced
- case 505: // Blue Potion
- case 545: // Condensed Red Potion
- case 605: // Anodyne
- case 606: // Aloevera
- default:
- break;
- }
- if (battle_config.pp_rate != 100)
- make_per = make_per * battle_config.pp_rate / 100;
- break;
- case SA_CREATECON: // Elemental Converter Creation
- make_per = 100000; // should be 100% success rate
- break;
- /**
- * Rune Knight
- **/
- case RK_RUNEMASTERY: {
- int A = 100 * (51 + 2 * pc_checkskill(sd, skill_id));
- int B = 100 * status->dex / 30 + 10 * (status->luk + sd->status.job_level);
- int C = 100 * cap_value(sd->itemid,0,100); //itemid depend on makerune()
- int D = 0;
- switch (nameid) { //rune rank it_diff 9 craftable rune
- case ITEMID_BERKANA:
- D = -2000;
- break; //Rank S
- case ITEMID_NAUTHIZ:
- case ITEMID_URUZ:
- D = -1500;
- break; //Rank A
- case ITEMID_ISA:
- case ITEMID_WYRD:
- D = -1000;
- break; //Rank B
- case ITEMID_RAIDO:
- case ITEMID_THURISAZ:
- case ITEMID_HAGALAZ:
- case ITEMID_OTHILA:
- D = -500;
- break; //Rank C
- default:
- D = -1500;
- break; //not specified =-15%
- }
- make_per = A + B + C + D;
- break;
- }
- /**
- * Guilotine Cross
- **/
- case GC_CREATENEWPOISON:
- make_per = 3000 + 500 * pc_checkskill(sd,GC_RESEARCHNEWPOISON);
- qty = 1+rnd()%pc_checkskill(sd,GC_RESEARCHNEWPOISON);
- break;
- case GN_CHANGEMATERIAL:
- for (i=0; i<MAX_SKILL_PRODUCE_DB; i++)
- if (skill_changematerial_db[i].itemid == nameid) {
- make_per = skill_changematerial_db[i].rate * 10;
- break;
- }
- break;
- case GN_S_PHARMACY: {
- int difficulty = 0;
-
- difficulty = (620 - 20 * skilllv);// (620 - 20 * Skill Level)
-
- make_per = status->int_ + status->dex/2 + status->luk + sd->status.job_level + (30+rnd()%120) + // (Caster?s INT) + (Caster?s DEX / 2) + (Caster?s LUK) + (Caster?s Job Level) + Random number between (30 ~ 150) +
- (sd->status.base_level-100) + pc_checkskill(sd, AM_LEARNINGPOTION) + pc_checkskill(sd, CR_FULLPROTECTION)*(4+rnd()%6); // (Caster?s Base Level - 100) + (Potion Research x 5) + (Full Chemical Protection Skill Level) x (Random number between 4 ~ 10)
-
- switch (nameid) { // difficulty factor
- case 12422:
- case 12425:
- case 12428:
- difficulty += 10;
- break;
- case 6212:
- case 12426:
- difficulty += 15;
- break;
- case 13264:
- case 12423:
- case 12427:
- case 12436:
- difficulty += 20;
- break;
- case 6210:
- case 6211:
- case 12437:
- difficulty += 30;
- break;
- case 12424:
- case 12475:
- difficulty += 40;
- break;
- }
+ int slot[3];
+ int i,sc,ele,idx,equip,wlv,make_per = 0,flag = 0,skilllv = 0;
+ int num = -1; // exclude the recipe
+ struct status_data *status;
+ struct item_data* data;
+
+ nullpo_ret(sd);
+ status = status_get_status_data(&sd->bl);
+
+ if( sd->skillid_old == skill_id )
+ skilllv = sd->skilllv_old;
+
+ if( !(idx=skill_can_produce_mix(sd,nameid,-1, qty)) )
+ return 0;
+ idx--;
+
+ if (qty < 1)
+ qty = 1;
+
+ if (!skill_id) //A skill can be specified for some override cases.
+ skill_id = skill_produce_db[idx].req_skill;
+
+ if( skill_id == GC_RESEARCHNEWPOISON )
+ skill_id = GC_CREATENEWPOISON;
+
+ slot[0]=slot1;
+ slot[1]=slot2;
+ slot[2]=slot3;
+
+ for(i=0,sc=0,ele=0;i<3;i++){ //Note that qty should always be one if you are using these!
+ int j;
+ if( slot[i]<=0 )
+ continue;
+ j = pc_search_inventory(sd,slot[i]);
+ if(j < 0)
+ continue;
+ if(slot[i]==1000){ /* Star Crumb */
+ pc_delitem(sd,j,1,1,0,LOG_TYPE_PRODUCE);
+ sc++;
+ }
+ if(slot[i]>=994 && slot[i]<=997 && ele==0){ /* Flame Heart . . . Great Nature */
+ static const int ele_table[4]={3,1,4,2};
+ pc_delitem(sd,j,1,1,0,LOG_TYPE_PRODUCE);
+ ele=ele_table[slot[i]-994];
+ }
+ }
- if (make_per >= 400 && make_per > difficulty)
- qty = 10;
- else if (make_per >= 300 && make_per > difficulty)
- qty = 7;
- else if (make_per >= 100 && make_per > difficulty)
- qty = 6;
- else if (make_per >= 1 && make_per > difficulty)
- qty = 5;
- else
- qty = 4;
- make_per = 10000;
- }
- break;
- case GN_MAKEBOMB:
- case GN_MIX_COOKING: {
- int difficulty = 30 + rnd()%120; // Random number between (30 ~ 150)
-
- make_per = sd->status.job_level / 4 + status->luk / 2 + status->dex / 3; // (Caster?s Job Level / 4) + (Caster?s LUK / 2) + (Caster?s DEX / 3)
- qty = ~(5 + rnd()%5) + 1;
-
- switch (nameid) { // difficulty factor
- case 13260:
- difficulty += 5;
- break;
- case 13261:
- case 13262:
- difficulty += 10;
- break;
- case 12429:
- case 12430:
- case 12431:
- case 12432:
- case 12433:
- case 12434:
- case 13263:
- difficulty += 15;
- break;
- case 13264:
- difficulty += 20;
- break;
- }
+ if( skill_id == RK_RUNEMASTERY ) {
+ int temp_qty, skill_lv = pc_checkskill(sd,skill_id);
+ data = itemdb_search(nameid);
+
+ if( skill_lv == 10 ) temp_qty = 1 + rnd()%3;
+ else if( skill_lv > 5 ) temp_qty = 1 + rnd()%2;
+ else temp_qty = 1;
+
+ if (data->stack.inventory) {
+ for( i = 0; i < MAX_INVENTORY; i++ ) {
+ if( sd->status.inventory[i].nameid == nameid ) {
+ if( sd->status.inventory[i].amount >= data->stack.amount ) {
+ clif_msgtable(sd->fd,0x61b);
+ return 0;
+ } else {
+ /**
+ * the amount fits, say we got temp_qty 4 and 19 runes, we trim temp_qty to 1.
+ **/
+ if( temp_qty + sd->status.inventory[i].amount >= data->stack.amount )
+ temp_qty = data->stack.amount - sd->status.inventory[i].amount;
+ }
+ break;
+ }
+ }
+ }
+ qty = temp_qty;
+ }
- if (make_per >= 30 && make_per > difficulty)
- qty = 10 + rnd()%2;
- else if (make_per >= 10 && make_per > difficulty)
- qty = 10;
- else if (make_per == 10 && make_per > difficulty)
- qty = 8;
- else if ((make_per >= 50 || make_per < 30) && make_per < difficulty)
- ;// Food/Bomb creation fails.
- else if (make_per >= 30 && make_per < difficulty)
- qty = 5;
-
- if (qty < 0 || (skilllv == 1 && make_per < difficulty)) {
- qty = ~qty + 1;
- make_per = 0;
- } else
- make_per = 10000;
- qty = (skilllv > 1 ? qty : 1);
- }
- break;
- default:
- if (sd->menuskill_id == AM_PHARMACY &&
- sd->menuskill_val > 10 && sd->menuskill_val <= 20) {
- //Assume Cooking Dish
- if (sd->menuskill_val >= 15) //Legendary Cooking Set.
- make_per = 10000; //100% Success
- else
- make_per = 1200 * (sd->menuskill_val - 10)
- + 20 * (sd->status.base_level + 1)
- + 20 * (status->dex + 1)
- + 100 * (rnd()%(30+5*(sd->cook_mastery/400) - (6+sd->cook_mastery/80)) + (6+sd->cook_mastery/80))
- - 400 * (skill_produce_db[idx].itemlv - 11 + 1)
- - 10 * (100 - status->luk + 1)
- - 500 * (num - 1)
- - 100 * (rnd()%4 + 1);
- break;
- }
- make_per = 5000;
- break;
- }
- } else { // Weapon Forging - skill bonuses are straight from kRO website, other things from a jRO calculator [DracoRPG]
- make_per = 5000 + sd->status.job_level*20 + status->dex*10 + status->luk*10; // Base
- make_per += pc_checkskill(sd,skill_id)*500; // Smithing skills bonus: +5/+10/+15
- make_per += pc_checkskill(sd,BS_WEAPONRESEARCH)*100 +((wlv >= 3)? pc_checkskill(sd,BS_ORIDEOCON)*100:0); // Weaponry Research bonus: +1/+2/+3/+4/+5/+6/+7/+8/+9/+10, Oridecon Research bonus (custom): +1/+2/+3/+4/+5
- make_per -= (ele?2000:0) + sc*1500 + (wlv>1?wlv*1000:0); // Element Stone: -20%, Star Crumb: -15% each, Weapon level malus: -0/-20/-30
- if (pc_search_inventory(sd,989) > 0) make_per+= 1000; // Emperium Anvil: +10
- else if (pc_search_inventory(sd,988) > 0) make_per+= 500; // Golden Anvil: +5
- else if (pc_search_inventory(sd,987) > 0) make_per+= 300; // Oridecon Anvil: +3
- else if (pc_search_inventory(sd,986) > 0) make_per+= 0; // Anvil: +0?
- if (battle_config.wp_rate != 100)
- make_per = make_per * battle_config.wp_rate / 100;
- }
-
- if (sd->class_&JOBL_BABY) //if it's a Baby Class
- make_per = (make_per * 50) / 100; //Baby penalty is 50% (bugreport:4847)
-
- if (make_per < 1) make_per = 1;
-
-
- if (rnd()%10000 < make_per || qty > 1) { //Success, or crafting multiple items.
- struct item tmp_item;
- memset(&tmp_item,0,sizeof(tmp_item));
- tmp_item.nameid=nameid;
- tmp_item.amount=1;
- tmp_item.identify=1;
- if (equip) {
- tmp_item.card[0]=CARD0_FORGE;
- tmp_item.card[1]=((sc*5)<<8)+ele;
- tmp_item.card[2]=GetWord(sd->status.char_id,0); // CharId
- tmp_item.card[3]=GetWord(sd->status.char_id,1);
- } else {
- //Flag is only used on the end, so it can be used here. [Skotlex]
- switch (skill_id) {
- case BS_DAGGER:
- case BS_SWORD:
- case BS_TWOHANDSWORD:
- case BS_AXE:
- case BS_MACE:
- case BS_KNUCKLE:
- case BS_SPEAR:
- flag = battle_config.produce_item_name_input&0x1;
- break;
- case AM_PHARMACY:
- case AM_TWILIGHT1:
- case AM_TWILIGHT2:
- case AM_TWILIGHT3:
- flag = battle_config.produce_item_name_input&0x2;
- break;
- case AL_HOLYWATER:
- /**
- * Arch Bishop
- **/
- case AB_ANCILLA:
- flag = battle_config.produce_item_name_input&0x8;
- break;
- case ASC_CDP:
- flag = battle_config.produce_item_name_input&0x10;
- break;
- default:
- flag = battle_config.produce_item_name_input&0x80;
- break;
- }
- if (flag) {
- tmp_item.card[0]=CARD0_CREATE;
- tmp_item.card[1]=0;
- tmp_item.card[2]=GetWord(sd->status.char_id,0); // CharId
- tmp_item.card[3]=GetWord(sd->status.char_id,1);
- }
- }
-
- // if(log_config.produce > 0)
- // log_produce(sd,nameid,slot1,slot2,slot3,1);
- //TODO update PICKLOG
-
- if (equip) {
- clif_produceeffect(sd,0,nameid);
- clif_misceffect(&sd->bl,3);
- if (itemdb_wlv(nameid) >= 3 && ((ele? 1 : 0) + sc) >= 3) // Fame point system [DracoRPG]
- pc_addfame(sd,10); // Success to forge a lv3 weapon with 3 additional ingredients = +10 fame point
- } else {
- int fame = 0;
- tmp_item.amount = 0;
-
- for (i=0; i< qty; i++) { //Apply quantity modifiers.
- if ((skill_id == GN_MIX_COOKING || skill_id == GN_MAKEBOMB || skill_id == GN_S_PHARMACY) && make_per > 1) {
- tmp_item.amount = qty;
- break;
- }
- if (rnd()%10000 < make_per || qty == 1) { //Success
- tmp_item.amount++;
- if (nameid < 545 || nameid > 547)
- continue;
- if (skill_id != AM_PHARMACY &&
- skill_id != AM_TWILIGHT1 &&
- skill_id != AM_TWILIGHT2 &&
- skill_id != AM_TWILIGHT3)
- continue;
- //Add fame as needed.
- switch (++sd->potion_success_counter) {
- case 3:
- fame+=1; // Success to prepare 3 Condensed Potions in a row
- break;
- case 5:
- fame+=3; // Success to prepare 5 Condensed Potions in a row
- break;
- case 7:
- fame+=10; // Success to prepare 7 Condensed Potions in a row
- break;
- case 10:
- fame+=50; // Success to prepare 10 Condensed Potions in a row
- sd->potion_success_counter = 0;
- break;
- }
- } else //Failure
- sd->potion_success_counter = 0;
- }
+ for(i=0;i<MAX_PRODUCE_RESOURCE;i++){
+ int j,id,x;
+ if( (id=skill_produce_db[idx].mat_id[i]) <= 0 )
+ continue;
+ num++;
+ x=( skill_id == RK_RUNEMASTERY ? 1 : qty)*skill_produce_db[idx].mat_amount[i];
+ do{
+ int y=0;
+ j = pc_search_inventory(sd,id);
+
+ if(j >= 0){
+ y = sd->status.inventory[j].amount;
+ if(y>x)y=x;
+ pc_delitem(sd,j,y,0,0,LOG_TYPE_PRODUCE);
+ } else
+ ShowError("skill_produce_mix: material item error\n");
+
+ x-=y;
+ }while( j>=0 && x>0 );
+ }
- if (fame)
- pc_addfame(sd,fame);
- //Visual effects and the like.
- switch (skill_id) {
- case AM_PHARMACY:
- case AM_TWILIGHT1:
- case AM_TWILIGHT2:
- case AM_TWILIGHT3:
- case ASC_CDP:
- clif_produceeffect(sd,2,nameid);
- clif_misceffect(&sd->bl,5);
- break;
- case BS_IRON:
- case BS_STEEL:
- case BS_ENCHANTEDSTONE:
- clif_produceeffect(sd,0,nameid);
- clif_misceffect(&sd->bl,3);
- break;
- case RK_RUNEMASTERY:
- case GC_CREATENEWPOISON:
- clif_produceeffect(sd,2,nameid);
- clif_misceffect(&sd->bl,5);
- break;
- default: //Those that don't require a skill?
- if (skill_produce_db[idx].itemlv > 10 && skill_produce_db[idx].itemlv <= 20) {
- //Cooking items.
- clif_specialeffect(&sd->bl, 608, AREA);
- if (sd->cook_mastery < 1999)
- pc_setglobalreg(sd, "COOK_MASTERY",sd->cook_mastery + (1 << ((skill_produce_db[idx].itemlv - 11) / 2)) * 5);
- }
- break;
- }
- }
- if (skill_id == GN_CHANGEMATERIAL && tmp_item.amount) { //Success
- int j, k = 0;
- for (i=0; i<MAX_SKILL_PRODUCE_DB; i++)
- if (skill_changematerial_db[i].itemid == nameid) {
- for (j=0; j<5; j++) {
- if (rnd()%1000 < skill_changematerial_db[i].qty_rate[j]) {
- tmp_item.amount = qty * skill_changematerial_db[i].qty[j];
- if ((flag = pc_additem(sd,&tmp_item,tmp_item.amount,LOG_TYPE_PRODUCE))) {
- clif_additem(sd,0,0,flag);
- map_addflooritem(&tmp_item,tmp_item.amount,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
- }
- k++;
- }
- }
- break;
- }
- if (k) {
- clif_msg_skill(sd,skill_id,0x627);
- return 1;
- }
- } else if (tmp_item.amount) { //Success
- if ((flag = pc_additem(sd,&tmp_item,tmp_item.amount,LOG_TYPE_PRODUCE))) {
- clif_additem(sd,0,0,flag);
- map_addflooritem(&tmp_item,tmp_item.amount,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
- }
- if (skill_id == GN_MIX_COOKING || skill_id == GN_MAKEBOMB || skill_id == GN_S_PHARMACY)
- clif_msg_skill(sd,skill_id,0x627);
- return 1;
- }
- }
- //Failure
- // if(log_config.produce)
- // log_produce(sd,nameid,slot1,slot2,slot3,0);
- //TODO update PICKLOG
-
- if (equip) {
- clif_produceeffect(sd,1,nameid);
- clif_misceffect(&sd->bl,2);
- } else {
- switch (skill_id) {
- case ASC_CDP: //25% Damage yourself, and display same effect as failed potion.
- status_percent_damage(NULL, &sd->bl, -25, 0, true);
- case AM_PHARMACY:
- case AM_TWILIGHT1:
- case AM_TWILIGHT2:
- case AM_TWILIGHT3:
- clif_produceeffect(sd,3,nameid);
- clif_misceffect(&sd->bl,6);
- sd->potion_success_counter = 0; // Fame point system [DracoRPG]
- break;
- case BS_IRON:
- case BS_STEEL:
- case BS_ENCHANTEDSTONE:
- clif_produceeffect(sd,1,nameid);
- clif_misceffect(&sd->bl,2);
- break;
- case RK_RUNEMASTERY:
- case GC_CREATENEWPOISON:
- clif_produceeffect(sd,3,nameid);
- clif_misceffect(&sd->bl,6);
- break;
- case GN_MIX_COOKING: {
- struct item tmp_item;
- const int compensation[5] = {13265, 13266, 13267, 12435, 13268};
- int rate = rnd()%500;
- memset(&tmp_item,0,sizeof(tmp_item));
- if (rate < 50) i = 4;
- else if (rate < 100) i = 2+rnd()%1;
- else if (rate < 250) i = 1;
- else if (rate < 500) i = 0;
- tmp_item.nameid = compensation[i];
- tmp_item.amount = qty;
- tmp_item.identify = 1;
- if (pc_additem(sd,&tmp_item,tmp_item.amount,LOG_TYPE_PRODUCE)) {
- clif_additem(sd,0,0,flag);
- map_addflooritem(&tmp_item,tmp_item.amount,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
- }
- clif_msg_skill(sd,skill_id,0x628);
- }
- break;
- case GN_MAKEBOMB:
- case GN_S_PHARMACY:
- case GN_CHANGEMATERIAL:
- clif_msg_skill(sd,skill_id,0x628);
- break;
- default:
- if (skill_produce_db[idx].itemlv > 10 && skill_produce_db[idx].itemlv <= 20) {
- //Cooking items.
- clif_specialeffect(&sd->bl, 609, AREA);
- if (sd->cook_mastery > 0)
- pc_setglobalreg(sd, "COOK_MASTERY", sd->cook_mastery - (1 << ((skill_produce_db[idx].itemlv - 11) / 2)) - (((1 << ((skill_produce_db[idx].itemlv - 11) / 2)) >> 1) * 3));
- }
- }
- }
- return 0;
-}
+ if( (equip = (itemdb_isequip(nameid) && skill_id != GN_CHANGEMATERIAL && skill_id != GN_MAKEBOMB )) )
+ wlv = itemdb_wlv(nameid);
+ if(!equip) {
+ switch(skill_id){
+ case BS_IRON:
+ case BS_STEEL:
+ case BS_ENCHANTEDSTONE:
+ // Ores & Metals Refining - skill bonuses are straight from kRO website [DracoRPG]
+ i = pc_checkskill(sd,skill_id);
+ make_per = sd->status.job_level*20 + status->dex*10 + status->luk*10; //Base chance
+ switch(nameid){
+ case 998: // Iron
+ make_per += 4000+i*500; // Temper Iron bonus: +26/+32/+38/+44/+50
+ break;
+ case 999: // Steel
+ make_per += 3000+i*500; // Temper Steel bonus: +35/+40/+45/+50/+55
+ break;
+ case 1000: //Star Crumb
+ make_per = 100000; // Star Crumbs are 100% success crafting rate? (made 1000% so it succeeds even after penalties) [Skotlex]
+ break;
+ default: // Enchanted Stones
+ make_per += 1000+i*500; // Enchantedstone Craft bonus: +15/+20/+25/+30/+35
+ break;
+ }
+ break;
+ case ASC_CDP:
+ make_per = (2000 + 40*status->dex + 20*status->luk);
+ break;
+ case AL_HOLYWATER:
+ /**
+ * Arch Bishop
+ **/
+ case AB_ANCILLA:
+ make_per = 100000; //100% success
+ break;
+ case AM_PHARMACY: // Potion Preparation - reviewed with the help of various Ragnainfo sources [DracoRPG]
+ case AM_TWILIGHT1:
+ case AM_TWILIGHT2:
+ case AM_TWILIGHT3:
+ make_per = pc_checkskill(sd,AM_LEARNINGPOTION)*50
+ + pc_checkskill(sd,AM_PHARMACY)*300 + sd->status.job_level*20
+ + (status->int_/2)*10 + status->dex*10+status->luk*10;
+ if(merc_is_hom_active(sd->hd)) {//Player got a homun
+ int skill;
+ if((skill=merc_hom_checkskill(sd->hd,HVAN_INSTRUCT)) > 0) //His homun is a vanil with instruction change
+ make_per += skill*100; //+1% bonus per level
+ }
+ switch(nameid){
+ case 501: // Red Potion
+ case 503: // Yellow Potion
+ case 504: // White Potion
+ make_per += (1+rnd()%100)*10 + 2000;
+ break;
+ case 970: // Alcohol
+ make_per += (1+rnd()%100)*10 + 1000;
+ break;
+ case 7135: // Bottle Grenade
+ case 7136: // Acid Bottle
+ case 7137: // Plant Bottle
+ case 7138: // Marine Sphere Bottle
+ make_per += (1+rnd()%100)*10;
+ break;
+ case 546: // Condensed Yellow Potion
+ make_per -= (1+rnd()%50)*10;
+ break;
+ case 547: // Condensed White Potion
+ case 7139: // Glistening Coat
+ make_per -= (1+rnd()%100)*10;
+ break;
+ //Common items, recieve no bonus or penalty, listed just because they are commonly produced
+ case 505: // Blue Potion
+ case 545: // Condensed Red Potion
+ case 605: // Anodyne
+ case 606: // Aloevera
+ default:
+ break;
+ }
+ if(battle_config.pp_rate != 100)
+ make_per = make_per * battle_config.pp_rate / 100;
+ break;
+ case SA_CREATECON: // Elemental Converter Creation
+ make_per = 100000; // should be 100% success rate
+ break;
+ /**
+ * Rune Knight
+ **/
+ case RK_RUNEMASTERY:
+ {
+ int A = 100 * (51 + 2 * pc_checkskill(sd, skill_id));
+ int B = 100 * status->dex / 30 + 10 * (status->luk + sd->status.job_level);
+ int C = 100 * cap_value(sd->itemid,0,100); //itemid depend on makerune()
+ int D = 0;
+ switch (nameid) { //rune rank it_diff 9 craftable rune
+ case ITEMID_BERKANA:
+ D = -2000;
+ break; //Rank S
+ case ITEMID_NAUTHIZ:
+ case ITEMID_URUZ:
+ D = -1500;
+ break; //Rank A
+ case ITEMID_ISA:
+ case ITEMID_WYRD:
+ D = -1000;
+ break; //Rank B
+ case ITEMID_RAIDO:
+ case ITEMID_THURISAZ:
+ case ITEMID_HAGALAZ:
+ case ITEMID_OTHILA:
+ D = -500;
+ break; //Rank C
+ default: D = -1500;
+ break; //not specified =-15%
+ }
+ make_per = A + B + C + D;
+ break;
+ }
+ /**
+ * Guilotine Cross
+ **/
+ case GC_CREATENEWPOISON:
+ make_per = 3000 + 500 * pc_checkskill(sd,GC_RESEARCHNEWPOISON);
+ qty = 1+rnd()%pc_checkskill(sd,GC_RESEARCHNEWPOISON);
+ break;
+ case GN_CHANGEMATERIAL:
+ for(i=0; i<MAX_SKILL_PRODUCE_DB; i++)
+ if( skill_changematerial_db[i].itemid == nameid ){
+ make_per = skill_changematerial_db[i].rate * 10;
+ break;
+ }
+ break;
+ case GN_S_PHARMACY:
+ {
+ int difficulty = 0;
+
+ difficulty = (620 - 20 * skilllv);// (620 - 20 * Skill Level)
+
+ make_per = status->int_ + status->dex/2 + status->luk + sd->status.job_level + (30+rnd()%120) + // (Caster?s INT) + (Caster?s DEX / 2) + (Caster?s LUK) + (Caster?s Job Level) + Random number between (30 ~ 150) +
+ (sd->status.base_level-100) + pc_checkskill(sd, AM_LEARNINGPOTION) + pc_checkskill(sd, CR_FULLPROTECTION)*(4+rnd()%6); // (Caster?s Base Level - 100) + (Potion Research x 5) + (Full Chemical Protection Skill Level) x (Random number between 4 ~ 10)
+
+ switch(nameid){// difficulty factor
+ case 12422: case 12425:
+ case 12428:
+ difficulty += 10;
+ break;
+ case 6212: case 12426:
+ difficulty += 15;
+ break;
+ case 13264: case 12423:
+ case 12427: case 12436:
+ difficulty += 20;
+ break;
+ case 6210: case 6211:
+ case 12437:
+ difficulty += 30;
+ break;
+ case 12424: case 12475:
+ difficulty += 40;
+ break;
+ }
+
+ if( make_per >= 400 && make_per > difficulty)
+ qty = 10;
+ else if( make_per >= 300 && make_per > difficulty)
+ qty = 7;
+ else if( make_per >= 100 && make_per > difficulty)
+ qty = 6;
+ else if( make_per >= 1 && make_per > difficulty)
+ qty = 5;
+ else
+ qty = 4;
+ make_per = 10000;
+ }
+ break;
+ case GN_MAKEBOMB:
+ case GN_MIX_COOKING:
+ {
+ int difficulty = 30 + rnd()%120; // Random number between (30 ~ 150)
+
+ make_per = sd->status.job_level / 4 + status->luk / 2 + status->dex / 3; // (Caster?s Job Level / 4) + (Caster?s LUK / 2) + (Caster?s DEX / 3)
+ qty = ~(5 + rnd()%5) + 1;
+
+ switch(nameid){// difficulty factor
+ case 13260:
+ difficulty += 5;
+ break;
+ case 13261: case 13262:
+ difficulty += 10;
+ break;
+ case 12429: case 12430: case 12431:
+ case 12432: case 12433: case 12434:
+ case 13263:
+ difficulty += 15;
+ break;
+ case 13264:
+ difficulty += 20;
+ break;
+ }
+
+ if( make_per >= 30 && make_per > difficulty)
+ qty = 10 + rnd()%2;
+ else if( make_per >= 10 && make_per > difficulty)
+ qty = 10;
+ else if( make_per == 10 && make_per > difficulty)
+ qty = 8;
+ else if( (make_per >= 50 || make_per < 30) && make_per < difficulty)
+ ;// Food/Bomb creation fails.
+ else if( make_per >= 30 && make_per < difficulty)
+ qty = 5;
+
+ if( qty < 0 || (skilllv == 1 && make_per < difficulty)){
+ qty = ~qty + 1;
+ make_per = 0;
+ }else
+ make_per = 10000;
+ qty = (skilllv > 1 ? qty : 1);
+ }
+ break;
+ default:
+ if (sd->menuskill_id == AM_PHARMACY &&
+ sd->menuskill_val > 10 && sd->menuskill_val <= 20)
+ { //Assume Cooking Dish
+ if (sd->menuskill_val >= 15) //Legendary Cooking Set.
+ make_per = 10000; //100% Success
+ else
+ make_per = 1200 * (sd->menuskill_val - 10)
+ + 20 * (sd->status.base_level + 1)
+ + 20 * (status->dex + 1)
+ + 100 * (rnd()%(30+5*(sd->cook_mastery/400) - (6+sd->cook_mastery/80)) + (6+sd->cook_mastery/80))
+ - 400 * (skill_produce_db[idx].itemlv - 11 + 1)
+ - 10 * (100 - status->luk + 1)
+ - 500 * (num - 1)
+ - 100 * (rnd()%4 + 1);
+ break;
+ }
+ make_per = 5000;
+ break;
+ }
+ } else { // Weapon Forging - skill bonuses are straight from kRO website, other things from a jRO calculator [DracoRPG]
+ make_per = 5000 + sd->status.job_level*20 + status->dex*10 + status->luk*10; // Base
+ make_per += pc_checkskill(sd,skill_id)*500; // Smithing skills bonus: +5/+10/+15
+ make_per += pc_checkskill(sd,BS_WEAPONRESEARCH)*100 +((wlv >= 3)? pc_checkskill(sd,BS_ORIDEOCON)*100:0); // Weaponry Research bonus: +1/+2/+3/+4/+5/+6/+7/+8/+9/+10, Oridecon Research bonus (custom): +1/+2/+3/+4/+5
+ make_per -= (ele?2000:0) + sc*1500 + (wlv>1?wlv*1000:0); // Element Stone: -20%, Star Crumb: -15% each, Weapon level malus: -0/-20/-30
+ if(pc_search_inventory(sd,989) > 0) make_per+= 1000; // Emperium Anvil: +10
+ else if(pc_search_inventory(sd,988) > 0) make_per+= 500; // Golden Anvil: +5
+ else if(pc_search_inventory(sd,987) > 0) make_per+= 300; // Oridecon Anvil: +3
+ else if(pc_search_inventory(sd,986) > 0) make_per+= 0; // Anvil: +0?
+ if(battle_config.wp_rate != 100)
+ make_per = make_per * battle_config.wp_rate / 100;
+ }
-int skill_arrow_create(struct map_session_data *sd, int nameid)
-{
- int i,j,flag,index=-1;
- struct item tmp_item;
+ if (sd->class_&JOBL_BABY) //if it's a Baby Class
+ make_per = (make_per * 50) / 100; //Baby penalty is 50% (bugreport:4847)
+
+ if(make_per < 1) make_per = 1;
+
+
+ if(rnd()%10000 < make_per || qty > 1){ //Success, or crafting multiple items.
+ struct item tmp_item;
+ memset(&tmp_item,0,sizeof(tmp_item));
+ tmp_item.nameid=nameid;
+ tmp_item.amount=1;
+ tmp_item.identify=1;
+ if(equip){
+ tmp_item.card[0]=CARD0_FORGE;
+ tmp_item.card[1]=((sc*5)<<8)+ele;
+ tmp_item.card[2]=GetWord(sd->status.char_id,0); // CharId
+ tmp_item.card[3]=GetWord(sd->status.char_id,1);
+ } else {
+ //Flag is only used on the end, so it can be used here. [Skotlex]
+ switch (skill_id) {
+ case BS_DAGGER:
+ case BS_SWORD:
+ case BS_TWOHANDSWORD:
+ case BS_AXE:
+ case BS_MACE:
+ case BS_KNUCKLE:
+ case BS_SPEAR:
+ flag = battle_config.produce_item_name_input&0x1;
+ break;
+ case AM_PHARMACY:
+ case AM_TWILIGHT1:
+ case AM_TWILIGHT2:
+ case AM_TWILIGHT3:
+ flag = battle_config.produce_item_name_input&0x2;
+ break;
+ case AL_HOLYWATER:
+ /**
+ * Arch Bishop
+ **/
+ case AB_ANCILLA:
+ flag = battle_config.produce_item_name_input&0x8;
+ break;
+ case ASC_CDP:
+ flag = battle_config.produce_item_name_input&0x10;
+ break;
+ default:
+ flag = battle_config.produce_item_name_input&0x80;
+ break;
+ }
+ if (flag) {
+ tmp_item.card[0]=CARD0_CREATE;
+ tmp_item.card[1]=0;
+ tmp_item.card[2]=GetWord(sd->status.char_id,0); // CharId
+ tmp_item.card[3]=GetWord(sd->status.char_id,1);
+ }
+ }
+
+// if(log_config.produce > 0)
+// log_produce(sd,nameid,slot1,slot2,slot3,1);
+//TODO update PICKLOG
+
+ if(equip){
+ clif_produceeffect(sd,0,nameid);
+ clif_misceffect(&sd->bl,3);
+ if(itemdb_wlv(nameid) >= 3 && ((ele? 1 : 0) + sc) >= 3) // Fame point system [DracoRPG]
+ pc_addfame(sd,10); // Success to forge a lv3 weapon with 3 additional ingredients = +10 fame point
+ } else {
+ int fame = 0;
+ tmp_item.amount = 0;
+
+ for (i=0; i< qty; i++) { //Apply quantity modifiers.
+ if( (skill_id == GN_MIX_COOKING || skill_id == GN_MAKEBOMB || skill_id == GN_S_PHARMACY) && make_per > 1){
+ tmp_item.amount = qty;
+ break;
+ }
+ if (rnd()%10000 < make_per || qty == 1) { //Success
+ tmp_item.amount++;
+ if(nameid < 545 || nameid > 547)
+ continue;
+ if( skill_id != AM_PHARMACY &&
+ skill_id != AM_TWILIGHT1 &&
+ skill_id != AM_TWILIGHT2 &&
+ skill_id != AM_TWILIGHT3 )
+ continue;
+ //Add fame as needed.
+ switch(++sd->potion_success_counter) {
+ case 3:
+ fame+=1; // Success to prepare 3 Condensed Potions in a row
+ break;
+ case 5:
+ fame+=3; // Success to prepare 5 Condensed Potions in a row
+ break;
+ case 7:
+ fame+=10; // Success to prepare 7 Condensed Potions in a row
+ break;
+ case 10:
+ fame+=50; // Success to prepare 10 Condensed Potions in a row
+ sd->potion_success_counter = 0;
+ break;
+ }
+ } else //Failure
+ sd->potion_success_counter = 0;
+ }
- nullpo_ret(sd);
+ if (fame)
+ pc_addfame(sd,fame);
+ //Visual effects and the like.
+ switch (skill_id) {
+ case AM_PHARMACY:
+ case AM_TWILIGHT1:
+ case AM_TWILIGHT2:
+ case AM_TWILIGHT3:
+ case ASC_CDP:
+ clif_produceeffect(sd,2,nameid);
+ clif_misceffect(&sd->bl,5);
+ break;
+ case BS_IRON:
+ case BS_STEEL:
+ case BS_ENCHANTEDSTONE:
+ clif_produceeffect(sd,0,nameid);
+ clif_misceffect(&sd->bl,3);
+ break;
+ case RK_RUNEMASTERY:
+ case GC_CREATENEWPOISON:
+ clif_produceeffect(sd,2,nameid);
+ clif_misceffect(&sd->bl,5);
+ break;
+ default: //Those that don't require a skill?
+ if( skill_produce_db[idx].itemlv > 10 && skill_produce_db[idx].itemlv <= 20)
+ { //Cooking items.
+ clif_specialeffect(&sd->bl, 608, AREA);
+ if( sd->cook_mastery < 1999 )
+ pc_setglobalreg(sd, "COOK_MASTERY",sd->cook_mastery + ( 1 << ( (skill_produce_db[idx].itemlv - 11) / 2 ) ) * 5);
+ }
+ break;
+ }
+ }
+ if ( skill_id == GN_CHANGEMATERIAL && tmp_item.amount) { //Success
+ int j, k = 0;
+ for(i=0; i<MAX_SKILL_PRODUCE_DB; i++)
+ if( skill_changematerial_db[i].itemid == nameid ){
+ for(j=0; j<5; j++){
+ if( rnd()%1000 < skill_changematerial_db[i].qty_rate[j] ){
+ tmp_item.amount = qty * skill_changematerial_db[i].qty[j];
+ if((flag = pc_additem(sd,&tmp_item,tmp_item.amount,LOG_TYPE_PRODUCE))) {
+ clif_additem(sd,0,0,flag);
+ map_addflooritem(&tmp_item,tmp_item.amount,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ }
+ k++;
+ }
+ }
+ break;
+ }
+ if( k ){
+ clif_msg_skill(sd,skill_id,0x627);
+ return 1;
+ }
+ } else if (tmp_item.amount) { //Success
+ if((flag = pc_additem(sd,&tmp_item,tmp_item.amount,LOG_TYPE_PRODUCE))) {
+ clif_additem(sd,0,0,flag);
+ map_addflooritem(&tmp_item,tmp_item.amount,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ }
+ if( skill_id == GN_MIX_COOKING || skill_id == GN_MAKEBOMB || skill_id == GN_S_PHARMACY )
+ clif_msg_skill(sd,skill_id,0x627);
+ return 1;
+ }
+ }
+ //Failure
+// if(log_config.produce)
+// log_produce(sd,nameid,slot1,slot2,slot3,0);
+//TODO update PICKLOG
+
+ if(equip){
+ clif_produceeffect(sd,1,nameid);
+ clif_misceffect(&sd->bl,2);
+ } else {
+ switch (skill_id) {
+ case ASC_CDP: //25% Damage yourself, and display same effect as failed potion.
+ status_percent_damage(NULL, &sd->bl, -25, 0, true);
+ case AM_PHARMACY:
+ case AM_TWILIGHT1:
+ case AM_TWILIGHT2:
+ case AM_TWILIGHT3:
+ clif_produceeffect(sd,3,nameid);
+ clif_misceffect(&sd->bl,6);
+ sd->potion_success_counter = 0; // Fame point system [DracoRPG]
+ break;
+ case BS_IRON:
+ case BS_STEEL:
+ case BS_ENCHANTEDSTONE:
+ clif_produceeffect(sd,1,nameid);
+ clif_misceffect(&sd->bl,2);
+ break;
+ case RK_RUNEMASTERY:
+ case GC_CREATENEWPOISON:
+ clif_produceeffect(sd,3,nameid);
+ clif_misceffect(&sd->bl,6);
+ break;
+ case GN_MIX_COOKING: {
+ struct item tmp_item;
+ const int compensation[5] = {13265, 13266, 13267, 12435, 13268};
+ int rate = rnd()%500;
+ memset(&tmp_item,0,sizeof(tmp_item));
+ if( rate < 50) i = 4;
+ else if( rate < 100) i = 2+rnd()%1;
+ else if( rate < 250 ) i = 1;
+ else if( rate < 500 ) i = 0;
+ tmp_item.nameid = compensation[i];
+ tmp_item.amount = qty;
+ tmp_item.identify = 1;
+ if( pc_additem(sd,&tmp_item,tmp_item.amount,LOG_TYPE_PRODUCE) ) {
+ clif_additem(sd,0,0,flag);
+ map_addflooritem(&tmp_item,tmp_item.amount,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ }
+ clif_msg_skill(sd,skill_id,0x628);
+ }
+ break;
+ case GN_MAKEBOMB:
+ case GN_S_PHARMACY:
+ case GN_CHANGEMATERIAL:
+ clif_msg_skill(sd,skill_id,0x628);
+ break;
+ default:
+ if( skill_produce_db[idx].itemlv > 10 && skill_produce_db[idx].itemlv <= 20 )
+ { //Cooking items.
+ clif_specialeffect(&sd->bl, 609, AREA);
+ if( sd->cook_mastery > 0 )
+ pc_setglobalreg(sd, "COOK_MASTERY", sd->cook_mastery - ( 1 << ((skill_produce_db[idx].itemlv - 11) / 2) ) - ( ( ( 1 << ((skill_produce_db[idx].itemlv - 11) / 2) ) >> 1 ) * 3 ));
+ }
+ }
+ }
+ return 0;
+}
- if (nameid <= 0)
- return 1;
+int skill_arrow_create (struct map_session_data *sd, int nameid)
+{
+ int i,j,flag,index=-1;
+ struct item tmp_item;
+
+ nullpo_ret(sd);
+
+ if(nameid <= 0)
+ return 1;
+
+ for(i=0;i<MAX_SKILL_ARROW_DB;i++)
+ if(nameid == skill_arrow_db[i].nameid) {
+ index = i;
+ break;
+ }
+
+ if(index < 0 || (j = pc_search_inventory(sd,nameid)) < 0)
+ return 1;
+
+ pc_delitem(sd,j,1,0,0,LOG_TYPE_PRODUCE);
+ for(i=0;i<MAX_ARROW_RESOURCE;i++) {
+ memset(&tmp_item,0,sizeof(tmp_item));
+ tmp_item.identify = 1;
+ tmp_item.nameid = skill_arrow_db[index].cre_id[i];
+ tmp_item.amount = skill_arrow_db[index].cre_amount[i];
+ if(battle_config.produce_item_name_input&0x4) {
+ tmp_item.card[0]=CARD0_CREATE;
+ tmp_item.card[1]=0;
+ tmp_item.card[2]=GetWord(sd->status.char_id,0); // CharId
+ tmp_item.card[3]=GetWord(sd->status.char_id,1);
+ }
+ if(tmp_item.nameid <= 0 || tmp_item.amount <= 0)
+ continue;
+ if((flag = pc_additem(sd,&tmp_item,tmp_item.amount,LOG_TYPE_PRODUCE))) {
+ clif_additem(sd,0,0,flag);
+ map_addflooritem(&tmp_item,tmp_item.amount,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ }
+ }
- for (i=0; i<MAX_SKILL_ARROW_DB; i++)
- if (nameid == skill_arrow_db[i].nameid) {
- index = i;
- break;
- }
-
- if (index < 0 || (j = pc_search_inventory(sd,nameid)) < 0)
- return 1;
-
- pc_delitem(sd,j,1,0,0,LOG_TYPE_PRODUCE);
- for (i=0; i<MAX_ARROW_RESOURCE; i++) {
- memset(&tmp_item,0,sizeof(tmp_item));
- tmp_item.identify = 1;
- tmp_item.nameid = skill_arrow_db[index].cre_id[i];
- tmp_item.amount = skill_arrow_db[index].cre_amount[i];
- if (battle_config.produce_item_name_input&0x4) {
- tmp_item.card[0]=CARD0_CREATE;
- tmp_item.card[1]=0;
- tmp_item.card[2]=GetWord(sd->status.char_id,0); // CharId
- tmp_item.card[3]=GetWord(sd->status.char_id,1);
- }
- if (tmp_item.nameid <= 0 || tmp_item.amount <= 0)
- continue;
- if ((flag = pc_additem(sd,&tmp_item,tmp_item.amount,LOG_TYPE_PRODUCE))) {
- clif_additem(sd,0,0,flag);
- map_addflooritem(&tmp_item,tmp_item.amount,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
- }
- }
-
- return 0;
+ return 0;
}
-int skill_poisoningweapon(struct map_session_data *sd, int nameid)
-{
- sc_type type;
- int chance, i;
- nullpo_ret(sd);
- if (nameid <= 0 || (i = pc_search_inventory(sd,nameid)) < 0 || pc_delitem(sd,i,1,0,0,LOG_TYPE_CONSUME)) {
- clif_skill_fail(sd,GC_POISONINGWEAPON,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- switch (nameid) {
- // t_lv used to take duration from skill_get_time2
- case PO_PARALYSE:
- type = SC_PARALYSE;
- break;
- case PO_PYREXIA:
- type = SC_PYREXIA;
- break;
- case PO_DEATHHURT:
- type = SC_DEATHHURT;
- break;
- case PO_LEECHESEND:
- type = SC_LEECHESEND;
- break;
- case PO_VENOMBLEED:
- type = SC_VENOMBLEED;
- break;
- case PO_TOXIN:
- type = SC_TOXIN;
- break;
- case PO_MAGICMUSHROOM:
- type = SC_MAGICMUSHROOM;
- break;
- case PO_OBLIVIONCURSE:
- type = SC_OBLIVIONCURSE;
- break;
- default:
- clif_skill_fail(sd,GC_POISONINGWEAPON,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
+int skill_poisoningweapon( struct map_session_data *sd, int nameid) {
+ sc_type type;
+ int chance, i;
+ nullpo_ret(sd);
+ if( nameid <= 0 || (i = pc_search_inventory(sd,nameid)) < 0 || pc_delitem(sd,i,1,0,0,LOG_TYPE_CONSUME) ) {
+ clif_skill_fail(sd,GC_POISONINGWEAPON,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ switch( nameid )
+ { // t_lv used to take duration from skill_get_time2
+ case PO_PARALYSE: type = SC_PARALYSE; break;
+ case PO_PYREXIA: type = SC_PYREXIA; break;
+ case PO_DEATHHURT: type = SC_DEATHHURT; break;
+ case PO_LEECHESEND: type = SC_LEECHESEND; break;
+ case PO_VENOMBLEED: type = SC_VENOMBLEED; break;
+ case PO_TOXIN: type = SC_TOXIN; break;
+ case PO_MAGICMUSHROOM: type = SC_MAGICMUSHROOM; break;
+ case PO_OBLIVIONCURSE: type = SC_OBLIVIONCURSE; break;
+ default:
+ clif_skill_fail(sd,GC_POISONINGWEAPON,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
- chance = 2 + 2 * sd->menuskill_val; // 2 + 2 * skill_lv
- sc_start4(&sd->bl, SC_POISONINGWEAPON, 100, pc_checkskill(sd, GC_RESEARCHNEWPOISON), //in Aegis it store the level of GC_RESEARCHNEWPOISON in val1
- type, chance, 0, skill_get_time(GC_POISONINGWEAPON, sd->menuskill_val));
+ chance = 2 + 2 * sd->menuskill_val; // 2 + 2 * skill_lv
+ sc_start4(&sd->bl, SC_POISONINGWEAPON, 100, pc_checkskill(sd, GC_RESEARCHNEWPOISON), //in Aegis it store the level of GC_RESEARCHNEWPOISON in val1
+ type, chance, 0, skill_get_time(GC_POISONINGWEAPON, sd->menuskill_val));
- return 0;
+ return 0;
}
static void skill_toggle_magicpower(struct block_list *bl, short skillid)
{
- struct status_change *sc = status_get_sc(bl);
-
- // non-offensive and non-magic skills do not affect the status
- if (skill_get_nk(skillid)&NK_NO_DAMAGE || !(skill_get_type(skillid)&BF_MAGIC))
- return;
-
- if (sc && sc->count && sc->data[SC_MAGICPOWER]) {
- if (sc->data[SC_MAGICPOWER]->val4) {
- status_change_end(bl, SC_MAGICPOWER, INVALID_TIMER);
- } else {
- sc->data[SC_MAGICPOWER]->val4 = 1;
- status_calc_bl(bl, status_sc2scb_flag(SC_MAGICPOWER));
-#ifndef RENEWAL
- if(bl->type == BL_PC){// update current display.
- clif_updatestatus(((TBL_PC *)bl),SP_MATK1);
- clif_updatestatus(((TBL_PC *)bl),SP_MATK2);
- }
-#endif
- }
- }
+ struct status_change *sc = status_get_sc(bl);
+
+ // non-offensive and non-magic skills do not affect the status
+ if (skill_get_nk(skillid)&NK_NO_DAMAGE || !(skill_get_type(skillid)&BF_MAGIC))
+ return;
+
+ if (sc && sc->count && sc->data[SC_MAGICPOWER])
+ {
+ if (sc->data[SC_MAGICPOWER]->val4)
+ {
+ status_change_end(bl, SC_MAGICPOWER, INVALID_TIMER);
+ }
+ else
+ {
+ sc->data[SC_MAGICPOWER]->val4 = 1;
+ status_calc_bl(bl, status_sc2scb_flag(SC_MAGICPOWER));
+ }
+ }
}
-int skill_magicdecoy(struct map_session_data *sd, int nameid)
-{
- int x, y, i, class_, skill;
- struct mob_data *md;
- nullpo_ret(sd);
- skill = sd->menuskill_val;
-
- if (nameid <= 0 || !itemdb_is_element(nameid) || (i = pc_search_inventory(sd,nameid)) < 0 || !skill || pc_delitem(sd,i,1,0,0,LOG_TYPE_CONSUME)) {
- clif_skill_fail(sd,NC_MAGICDECOY,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
-
- // Spawn Position
- pc_delitem(sd,i,1,0,0,LOG_TYPE_CONSUME);
- x = sd->sc.comet_x;
- y = sd->sc.comet_y;
- sd->sc.comet_x = sd->sc.comet_y = 0;
- sd->menuskill_val = 0;
-
- class_ = (nameid == 990 || nameid == 991) ? 2043 + nameid - 990 : (nameid == 992) ? 2046 : 2045;
-
-
- md = mob_once_spawn_sub(&sd->bl, sd->bl.m, x, y, sd->status.name, class_, "", SZ_SMALL, AI_NONE);
- if (md) {
- md->master_id = sd->bl.id;
- md->special_state.ai = AI_FLORA;
- if (md->deletetimer != INVALID_TIMER)
- delete_timer(md->deletetimer, mob_timer_delete);
- md->deletetimer = add_timer(gettick() + skill_get_time(NC_MAGICDECOY,skill), mob_timer_delete, md->bl.id, 0);
- mob_spawn(md);
- md->status.matk_min = md->status.matk_max = 250 + (50 * skill);
- }
-
- return 0;
+int skill_magicdecoy(struct map_session_data *sd, int nameid) {
+ int x, y, i, class_, skill;
+ struct mob_data *md;
+ nullpo_ret(sd);
+ skill = sd->menuskill_val;
+
+ if( nameid <= 0 || !itemdb_is_element(nameid) || (i = pc_search_inventory(sd,nameid)) < 0 || !skill || pc_delitem(sd,i,1,0,0,LOG_TYPE_CONSUME) )
+ {
+ clif_skill_fail(sd,NC_MAGICDECOY,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+
+ // Spawn Position
+ pc_delitem(sd,i,1,0,0,LOG_TYPE_CONSUME);
+ x = sd->sc.comet_x;
+ y = sd->sc.comet_y;
+ sd->sc.comet_x = sd->sc.comet_y = 0;
+ sd->menuskill_val = 0;
+
+ class_ = (nameid == 990 || nameid == 991) ? 2043 + nameid - 990 : (nameid == 992) ? 2046 : 2045;
+
+
+ md = mob_once_spawn_sub(&sd->bl, sd->bl.m, x, y, sd->status.name, class_, "", SZ_SMALL, AI_NONE);
+ if( md ) {
+ md->master_id = sd->bl.id;
+ md->special_state.ai = AI_FLORA;
+ if( md->deletetimer != INVALID_TIMER )
+ delete_timer(md->deletetimer, mob_timer_delete);
+ md->deletetimer = add_timer (gettick() + skill_get_time(NC_MAGICDECOY,skill), mob_timer_delete, md->bl.id, 0);
+ mob_spawn(md);
+ md->status.matk_min = md->status.matk_max = 250 + (50 * skill);
+ }
+
+ return 0;
}
// Warlock Spellbooks. [LimitLine/3CeAM]
-int skill_spellbook(struct map_session_data *sd, int nameid)
-{
- int i, max_preserve, skill_id, point;
- struct status_change *sc;
-
- nullpo_ret(sd);
-
- sc = status_get_sc(&sd->bl);
- status_change_end(&sd->bl, SC_STOP, INVALID_TIMER);
-
- for (i=SC_SPELLBOOK1; i <= SC_MAXSPELLBOOK; i++) if (sc && !sc->data[i]) break;
- if (i > SC_MAXSPELLBOOK) {
- clif_skill_fail(sd, WL_READING_SB, USESKILL_FAIL_SPELLBOOK_READING, 0);
- return 0;
- }
-
- ARR_FIND(0,MAX_SKILL_SPELLBOOK_DB,i,skill_spellbook_db[i].nameid == nameid); // Search for information of this item
- if (i == MAX_SKILL_SPELLBOOK_DB) return 0;
-
- if (!pc_checkskill(sd, (skill_id = skill_spellbook_db[i].skillid))) {
- // User don't know the skill
- sc_start(&sd->bl, SC_SLEEP, 100, 1, skill_get_time(WL_READING_SB, pc_checkskill(sd,WL_READING_SB)));
- clif_skill_fail(sd, WL_READING_SB, USESKILL_FAIL_SPELLBOOK_DIFFICULT_SLEEP, 0);
- return 0;
- }
-
- max_preserve = 4 * pc_checkskill(sd, WL_FREEZE_SP) + status_get_int(&sd->bl) / 10 + sd->status.base_level / 10;
- point = skill_spellbook_db[i].point;
-
- if (sc && sc->data[SC_READING_SB]) {
- if ((sc->data[SC_READING_SB]->val2 + point) > max_preserve) {
- clif_skill_fail(sd, WL_READING_SB, USESKILL_FAIL_SPELLBOOK_PRESERVATION_POINT, 0);
- return 0;
- }
- for (i = SC_MAXSPELLBOOK; i >= SC_SPELLBOOK1; i--) { // This is how official saves spellbook. [malufett]
- if (!sc->data[i]) {
- sc->data[SC_READING_SB]->val2 += point; // increase points
- sc_start4(&sd->bl, (sc_type)i, 100, skill_id, pc_checkskill(sd,skill_id), point, 0, INVALID_TIMER);
- break;
- }
- }
- } else {
- sc_start2(&sd->bl, SC_READING_SB, 100, 0, point, INVALID_TIMER);
- sc_start4(&sd->bl, SC_MAXSPELLBOOK, 100, skill_id, pc_checkskill(sd,skill_id), point, 0, INVALID_TIMER);
- }
+int skill_spellbook (struct map_session_data *sd, int nameid) {
+ int i, max_preserve, skill_id, point;
+ struct status_change *sc;
+
+ nullpo_ret(sd);
+
+ sc = status_get_sc(&sd->bl);
+ status_change_end(&sd->bl, SC_STOP, INVALID_TIMER);
+
+ for(i=SC_SPELLBOOK1; i <= SC_MAXSPELLBOOK; i++) if( sc && !sc->data[i] ) break;
+ if( i > SC_MAXSPELLBOOK )
+ {
+ clif_skill_fail(sd, WL_READING_SB, USESKILL_FAIL_SPELLBOOK_READING, 0);
+ return 0;
+ }
+
+ ARR_FIND(0,MAX_SKILL_SPELLBOOK_DB,i,skill_spellbook_db[i].nameid == nameid); // Search for information of this item
+ if( i == MAX_SKILL_SPELLBOOK_DB ) return 0;
- return 1;
+ if( !pc_checkskill(sd, (skill_id = skill_spellbook_db[i].skillid)) )
+ { // User don't know the skill
+ sc_start(&sd->bl, SC_SLEEP, 100, 1, skill_get_time(WL_READING_SB, pc_checkskill(sd,WL_READING_SB)));
+ clif_skill_fail(sd, WL_READING_SB, USESKILL_FAIL_SPELLBOOK_DIFFICULT_SLEEP, 0);
+ return 0;
+ }
+
+ max_preserve = 4 * pc_checkskill(sd, WL_FREEZE_SP) + status_get_int(&sd->bl) / 10 + sd->status.base_level / 10;
+ point = skill_spellbook_db[i].point;
+
+ if( sc && sc->data[SC_READING_SB] ){
+ if( (sc->data[SC_READING_SB]->val2 + point) > max_preserve )
+ {
+ clif_skill_fail(sd, WL_READING_SB, USESKILL_FAIL_SPELLBOOK_PRESERVATION_POINT, 0);
+ return 0;
+ }
+ for(i = SC_MAXSPELLBOOK; i >= SC_SPELLBOOK1; i--){ // This is how official saves spellbook. [malufett]
+ if( !sc->data[i] ){
+ sc->data[SC_READING_SB]->val2 += point; // increase points
+ sc_start4(&sd->bl, (sc_type)i, 100, skill_id, pc_checkskill(sd,skill_id), point, 0, INVALID_TIMER);
+ break;
+ }
+ }
+ }else{
+ sc_start2(&sd->bl, SC_READING_SB, 100, 0, point, INVALID_TIMER);
+ sc_start4(&sd->bl, SC_MAXSPELLBOOK, 100, skill_id, pc_checkskill(sd,skill_id), point, 0, INVALID_TIMER);
+ }
+
+ return 1;
}
-int skill_select_menu(struct map_session_data *sd,int skill_id)
-{
- int id, lv, prob, aslvl = 0;
- nullpo_ret(sd);
-
- if (sd->sc.data[SC_STOP]) {
- aslvl = sd->sc.data[SC_STOP]->val1;
- status_change_end(&sd->bl,SC_STOP,INVALID_TIMER);
- }
-
- if (skill_id >= GS_GLITTERING || skill_get_type(skill_id) != BF_MAGIC ||
- (id = sd->status.skill[skill_id].id) == 0 || sd->status.skill[skill_id].flag != SKILL_FLAG_PLAGIARIZED) {
- clif_skill_fail(sd,SC_AUTOSHADOWSPELL,0,0);
- return 0;
- }
-
- lv = (aslvl + 1) / 2; // The level the skill will be autocasted
- lv = min(lv,sd->status.skill[skill_id].lv);
- prob = (aslvl == 10) ? 15 : (32 - 2 * aslvl); // Probability at level 10 was increased to 15.
- sc_start4(&sd->bl,SC__AUTOSHADOWSPELL,100,id,lv,prob,0,skill_get_time(SC_AUTOSHADOWSPELL,aslvl));
- return 0;
+int skill_select_menu(struct map_session_data *sd,int skill_id) {
+ int id, lv, prob, aslvl = 0;
+ nullpo_ret(sd);
+
+ if (sd->sc.data[SC_STOP]) {
+ aslvl = sd->sc.data[SC_STOP]->val1;
+ status_change_end(&sd->bl,SC_STOP,INVALID_TIMER);
+ }
+
+ if( skill_id >= GS_GLITTERING || skill_get_type(skill_id) != BF_MAGIC ||
+ (id = sd->status.skill[skill_id].id) == 0 || sd->status.skill[skill_id].flag != SKILL_FLAG_PLAGIARIZED ) {
+ clif_skill_fail(sd,SC_AUTOSHADOWSPELL,0,0);
+ return 0;
+ }
+
+ lv = (aslvl + 1) / 2; // The level the skill will be autocasted
+ lv = min(lv,sd->status.skill[skill_id].lv);
+ prob = (aslvl == 10) ? 15 : (32 - 2 * aslvl); // Probability at level 10 was increased to 15.
+ sc_start4(&sd->bl,SC__AUTOSHADOWSPELL,100,id,lv,prob,0,skill_get_time(SC_AUTOSHADOWSPELL,aslvl));
+ return 0;
}
-int skill_elementalanalysis(struct map_session_data *sd, int n, int skill_lv, unsigned short *item_list)
-{
- int i;
-
- nullpo_ret(sd);
- nullpo_ret(item_list);
-
- if (n <= 0)
- return 1;
-
- for (i = 0; i < n; i++) {
- int nameid, add_amount, del_amount, idx, product, flag;
- struct item tmp_item;
-
- idx = item_list[i*2+0]-2;
- del_amount = item_list[i*2+1];
-
- if (skill_lv == 2)
- del_amount -= (del_amount % 10);
- add_amount = (skill_lv == 1) ? del_amount * (5 + rnd()%5) : del_amount / 10 ;
-
- if ((nameid = sd->status.inventory[idx].nameid) <= 0 || del_amount > sd->status.inventory[idx].amount) {
- clif_skill_fail(sd,SO_EL_ANALYSIS,USESKILL_FAIL_LEVEL,0);
- return 1;
- }
-
- switch (nameid) {
- // Level 1
- case 994:
- product = 990;
- break; // Flame Heart -> Red Blood.
- case 995:
- product = 991;
- break; // Mystic Frozen -> Crystal Blue.
- case 996:
- product = 992;
- break; // Rough Wind -> Wind of Verdure.
- case 997:
- product = 993;
- break; // Great Nature -> Green Live.
- // Level 2
- case 990:
- product = 994;
- break; // Red Blood -> Flame Heart.
- case 991:
- product = 995;
- break; // Crystal Blue -> Mystic Frozen.
- case 992:
- product = 996;
- break; // Wind of Verdure -> Rough Wind.
- case 993:
- product = 997;
- break; // Green Live -> Great Nature.
- default:
- clif_skill_fail(sd,SO_EL_ANALYSIS,USESKILL_FAIL_LEVEL,0);
- return 1;
- }
-
- if (pc_delitem(sd,idx,del_amount,0,1,LOG_TYPE_CONSUME)) {
- clif_skill_fail(sd,SO_EL_ANALYSIS,USESKILL_FAIL_LEVEL,0);
- return 1;
- }
-
- if (skill_lv == 2 && rnd()%100 < 25) { // At level 2 have a fail chance. You loose your items if it fails.
- clif_skill_fail(sd,SO_EL_ANALYSIS,USESKILL_FAIL_LEVEL,0);
- return 1;
- }
-
-
- memset(&tmp_item,0,sizeof(tmp_item));
- tmp_item.nameid = product;
- tmp_item.amount = add_amount;
- tmp_item.identify = 1;
-
- if (tmp_item.amount) {
- if ((flag = pc_additem(sd,&tmp_item,tmp_item.amount,LOG_TYPE_CONSUME))) {
- clif_additem(sd,0,0,flag);
- map_addflooritem(&tmp_item,tmp_item.amount,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
- }
- }
+int skill_elementalanalysis(struct map_session_data* sd, int n, int skill_lv, unsigned short* item_list) {
+ int i;
+
+ nullpo_ret(sd);
+ nullpo_ret(item_list);
+
+ if( n <= 0 )
+ return 1;
+
+ for( i = 0; i < n; i++ ) {
+ int nameid, add_amount, del_amount, idx, product, flag;
+ struct item tmp_item;
+
+ idx = item_list[i*2+0]-2;
+ del_amount = item_list[i*2+1];
+
+ if( skill_lv == 2 )
+ del_amount -= (del_amount % 10);
+ add_amount = (skill_lv == 1) ? del_amount * (5 + rnd()%5) : del_amount / 10 ;
+
+ if( (nameid = sd->status.inventory[idx].nameid) <= 0 || del_amount > sd->status.inventory[idx].amount ) {
+ clif_skill_fail(sd,SO_EL_ANALYSIS,USESKILL_FAIL_LEVEL,0);
+ return 1;
+ }
+
+ switch( nameid ) {
+ // Level 1
+ case 994: product = 990; break; // Flame Heart -> Red Blood.
+ case 995: product = 991; break; // Mystic Frozen -> Crystal Blue.
+ case 996: product = 992; break; // Rough Wind -> Wind of Verdure.
+ case 997: product = 993; break; // Great Nature -> Green Live.
+ // Level 2
+ case 990: product = 994; break; // Red Blood -> Flame Heart.
+ case 991: product = 995; break; // Crystal Blue -> Mystic Frozen.
+ case 992: product = 996; break; // Wind of Verdure -> Rough Wind.
+ case 993: product = 997; break; // Green Live -> Great Nature.
+ default:
+ clif_skill_fail(sd,SO_EL_ANALYSIS,USESKILL_FAIL_LEVEL,0);
+ return 1;
+ }
+
+ if( pc_delitem(sd,idx,del_amount,0,1,LOG_TYPE_CONSUME) ) {
+ clif_skill_fail(sd,SO_EL_ANALYSIS,USESKILL_FAIL_LEVEL,0);
+ return 1;
+ }
+
+ if( skill_lv == 2 && rnd()%100 < 25 ) { // At level 2 have a fail chance. You loose your items if it fails.
+ clif_skill_fail(sd,SO_EL_ANALYSIS,USESKILL_FAIL_LEVEL,0);
+ return 1;
+ }
+
+
+ memset(&tmp_item,0,sizeof(tmp_item));
+ tmp_item.nameid = product;
+ tmp_item.amount = add_amount;
+ tmp_item.identify = 1;
+
+ if( tmp_item.amount ) {
+ if( (flag = pc_additem(sd,&tmp_item,tmp_item.amount,LOG_TYPE_CONSUME)) ) {
+ clif_additem(sd,0,0,flag);
+ map_addflooritem(&tmp_item,tmp_item.amount,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ }
+ }
- }
+ }
- return 0;
+ return 0;
}
-int skill_changematerial(struct map_session_data *sd, int n, unsigned short *item_list)
-{
- int i, j, k, c, p = 0, nameid, amount;
-
- nullpo_ret(sd);
- nullpo_ret(item_list);
-
- // Search for objects that can be created.
- for (i = 0; i < MAX_SKILL_PRODUCE_DB; i++) {
- if (skill_produce_db[i].itemlv == 26) {
- p = 0;
- do {
- c = 0;
- // Verification of overlap between the objects required and the list submitted.
- for (j = 0; j < MAX_PRODUCE_RESOURCE; j++) {
- if (skill_produce_db[i].mat_id[j] > 0) {
- for (k = 0; k < n; k++) {
- int idx = item_list[k*2+0]-2;
- nameid = sd->status.inventory[idx].nameid;
- amount = item_list[k*2+1];
- if (nameid > 0 && sd->status.inventory[idx].identify == 0) {
- clif_msg_skill(sd,GN_CHANGEMATERIAL,0x62D);
- return 0;
- }
- if (nameid == skill_produce_db[i].mat_id[j] && (amount-p*skill_produce_db[i].mat_amount[j]) >= skill_produce_db[i].mat_amount[j]
- && (amount-p*skill_produce_db[i].mat_amount[j])%skill_produce_db[i].mat_amount[j] == 0) // must be in exact amount
- c++; // match
- }
- } else
- break; // No more items required
- }
- p++;
- } while (n == j && c == n);
- p--;
- if (p > 0) {
- skill_produce_mix(sd,GN_CHANGEMATERIAL,skill_produce_db[i].nameid,0,0,0,p);
- return 1;
- }
- }
- }
+int skill_changematerial(struct map_session_data *sd, int n, unsigned short *item_list) {
+ int i, j, k, c, p = 0, nameid, amount;
+
+ nullpo_ret(sd);
+ nullpo_ret(item_list);
+
+ // Search for objects that can be created.
+ for( i = 0; i < MAX_SKILL_PRODUCE_DB; i++ ) {
+ if( skill_produce_db[i].itemlv == 26 ) {
+ p = 0;
+ do {
+ c = 0;
+ // Verification of overlap between the objects required and the list submitted.
+ for( j = 0; j < MAX_PRODUCE_RESOURCE; j++ ) {
+ if( skill_produce_db[i].mat_id[j] > 0 ) {
+ for( k = 0; k < n; k++ ) {
+ int idx = item_list[k*2+0]-2;
+ nameid = sd->status.inventory[idx].nameid;
+ amount = item_list[k*2+1];
+ if( nameid > 0 && sd->status.inventory[idx].identify == 0 ){
+ clif_msg_skill(sd,GN_CHANGEMATERIAL,0x62D);
+ return 0;
+ }
+ if( nameid == skill_produce_db[i].mat_id[j] && (amount-p*skill_produce_db[i].mat_amount[j]) >= skill_produce_db[i].mat_amount[j]
+ && (amount-p*skill_produce_db[i].mat_amount[j])%skill_produce_db[i].mat_amount[j] == 0 ) // must be in exact amount
+ c++; // match
+ }
+ }
+ else
+ break; // No more items required
+ }
+ p++;
+ } while(n == j && c == n);
+ p--;
+ if ( p > 0 ) {
+ skill_produce_mix(sd,GN_CHANGEMATERIAL,skill_produce_db[i].nameid,0,0,0,p);
+ return 1;
+ }
+ }
+ }
- if (p == 0)
- clif_msg_skill(sd,GN_CHANGEMATERIAL,0x623);
+ if( p == 0)
+ clif_msg_skill(sd,GN_CHANGEMATERIAL,0x623);
- return 0;
+ return 0;
}
/**
* for Royal Guard's LG_TRAMPLE
**/
-static int skill_destroy_trap(struct block_list *bl, va_list ap)
-{
- struct skill_unit *su = (struct skill_unit *)bl;
- struct skill_unit_group *sg;
- unsigned int tick;
-
- nullpo_ret(su);
- tick = va_arg(ap, unsigned int);
-
- if (su->alive && (sg = su->group) && skill_get_inf2(sg->skill_id)&INF2_TRAP) {
- switch (sg->unit_id) {
- case UNT_LANDMINE:
- case UNT_CLAYMORETRAP:
- case UNT_BLASTMINE:
- case UNT_SHOCKWAVE:
- case UNT_SANDMAN:
- case UNT_FLASHER:
- case UNT_FREEZINGTRAP:
- case UNT_CLUSTERBOMB:
- case UNT_FIRINGTRAP:
- case UNT_ICEBOUNDTRAP:
- map_foreachinrange(skill_trap_splash,&su->bl, skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &su->bl,tick);
- break;
- }
- // Traps aren't recovered.
- skill_delunit(su);
- }
- return 0;
+static int skill_destroy_trap( struct block_list *bl, va_list ap ) {
+ struct skill_unit *su = (struct skill_unit *)bl;
+ struct skill_unit_group *sg;
+ unsigned int tick;
+
+ nullpo_ret(su);
+ tick = va_arg(ap, unsigned int);
+
+ if (su->alive && (sg = su->group) && skill_get_inf2(sg->skill_id)&INF2_TRAP) {
+ switch( sg->unit_id ) {
+ case UNT_LANDMINE:
+ case UNT_CLAYMORETRAP:
+ case UNT_BLASTMINE:
+ case UNT_SHOCKWAVE:
+ case UNT_SANDMAN:
+ case UNT_FLASHER:
+ case UNT_FREEZINGTRAP:
+ case UNT_CLUSTERBOMB:
+ case UNT_FIRINGTRAP:
+ case UNT_ICEBOUNDTRAP:
+ map_foreachinrange(skill_trap_splash,&su->bl, skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &su->bl,tick);
+ break;
+ }
+ // Traps aren't recovered.
+ skill_delunit(su);
+ }
+ return 0;
}
/*==========================================
*
*------------------------------------------*/
int skill_blockpc_end(int tid, unsigned int tick, int id, intptr_t data)
{
- struct map_session_data *sd = map_id2sd(id);
- struct skill_cd *cd = NULL;
-
- if (data <= 0 || data >= MAX_SKILL)
- return 0;
- if (!sd) return 0;
- if (sd->blockskill[data] != (0x1|(tid&0xFE))) return 0;
-
- if ((cd = idb_get(skillcd_db,sd->status.char_id))) {
- int i,cursor;
- ARR_FIND(0, cd->cursor+1, cursor, cd->skidx[cursor] == data);
- cd->duration[cursor] = 0;
- cd->skidx[cursor] = 0;
- cd->nameid[cursor] = 0;
- // compact the cool down list
- for (i = 0, cursor = 0; i < cd->cursor; i++) {
- if (cd->duration[i] == 0)
- continue;
- if (cursor != i) {
- cd->duration[cursor] = cd->duration[i];
- cd->skidx[cursor] = cd->skidx[i];
- cd->nameid[cursor] = cd->nameid[i];
- }
- cursor++;
- }
- if (cursor == 0)
- idb_remove(skillcd_db,sd->status.char_id);
- else
- cd->cursor = cursor;
- }
-
- sd->blockskill[data] = 0;
- return 1;
+ struct map_session_data *sd = map_id2sd(id);
+ struct skill_cd * cd = NULL;
+
+ if (data <= 0 || data >= MAX_SKILL)
+ return 0;
+ if (!sd) return 0;
+ if (sd->blockskill[data] != (0x1|(tid&0xFE))) return 0;
+
+ if( ( cd = idb_get(skillcd_db,sd->status.char_id) ) ) {
+ int i,cursor;
+ ARR_FIND( 0, cd->cursor+1, cursor, cd->skidx[cursor] == data );
+ cd->duration[cursor] = 0;
+ cd->skidx[cursor] = 0;
+ cd->nameid[cursor] = 0;
+ // compact the cool down list
+ for( i = 0, cursor = 0; i < cd->cursor; i++ ) {
+ if( cd->duration[i] == 0 )
+ continue;
+ if( cursor != i ) {
+ cd->duration[cursor] = cd->duration[i];
+ cd->skidx[cursor] = cd->skidx[i];
+ cd->nameid[cursor] = cd->nameid[i];
+ }
+ cursor++;
+ }
+ if( cursor == 0 )
+ idb_remove(skillcd_db,sd->status.char_id);
+ else
+ cd->cursor = cursor;
+ }
+
+ sd->blockskill[data] = 0;
+ return 1;
}
/**
@@ -16943,675 +16789,565 @@ int skill_blockpc_end(int tid, unsigned int tick, int id, intptr_t data)
*/
int skill_blockpc_start_(struct map_session_data *sd, int skillid, int tick, bool load)
{
- int oskillid = skillid;
- struct skill_cd *cd = NULL;
-
- nullpo_retr(-1, sd);
-
- skillid = skill_get_index(skillid);
- if (skillid == 0)
- return -1;
-
- if (tick < 1) {
- sd->blockskill[skillid] = 0;
- return -1;
- }
-
- if (battle_config.display_status_timers)
- clif_skill_cooldown(sd, skillid, tick);
-
- if (!load) {
- // not being loaded initially so ensure the skill delay is recorded
- if (!(cd = idb_get(skillcd_db,sd->status.char_id))) {
- // create a new skill cooldown object for map storage
- CREATE(cd, struct skill_cd, 1);
- idb_put(skillcd_db, sd->status.char_id, cd);
- }
-
- // record the skill duration in the database map
- cd->duration[cd->cursor] = tick;
- cd->skidx[cd->cursor] = skillid;
- cd->nameid[cd->cursor] = oskillid;
- cd->cursor++;
- }
-
- sd->blockskill[skillid] = 0x1|(0xFE&add_timer(gettick()+tick,skill_blockpc_end,sd->bl.id,skillid));
- return 0;
+ int oskillid = skillid;
+ struct skill_cd* cd = NULL;
+
+ nullpo_retr (-1, sd);
+
+ skillid = skill_get_index(skillid);
+ if (skillid == 0)
+ return -1;
+
+ if (tick < 1) {
+ sd->blockskill[skillid] = 0;
+ return -1;
+ }
+
+ if( battle_config.display_status_timers )
+ clif_skill_cooldown(sd, skillid, tick);
+
+ if( !load )
+ {// not being loaded initially so ensure the skill delay is recorded
+ if( !(cd = idb_get(skillcd_db,sd->status.char_id)) )
+ {// create a new skill cooldown object for map storage
+ CREATE( cd, struct skill_cd, 1 );
+ idb_put( skillcd_db, sd->status.char_id, cd );
+ }
+
+ // record the skill duration in the database map
+ cd->duration[cd->cursor] = tick;
+ cd->skidx[cd->cursor] = skillid;
+ cd->nameid[cd->cursor] = oskillid;
+ cd->cursor++;
+ }
+
+ sd->blockskill[skillid] = 0x1|(0xFE&add_timer(gettick()+tick,skill_blockpc_end,sd->bl.id,skillid));
+ return 0;
}
-int skill_blockhomun_end(int tid, unsigned int tick, int id, intptr_t data) //[orn]
+int skill_blockhomun_end(int tid, unsigned int tick, int id, intptr_t data) //[orn]
{
- struct homun_data *hd = (TBL_HOM *) map_id2bl(id);
- if (data <= 0 || data >= MAX_SKILL)
- return 0;
- if (hd) hd->blockskill[data] = 0;
+ struct homun_data *hd = (TBL_HOM*) map_id2bl(id);
+ if (data <= 0 || data >= MAX_SKILL)
+ return 0;
+ if (hd) hd->blockskill[data] = 0;
- return 1;
+ return 1;
}
-int skill_blockhomun_start(struct homun_data *hd, int skillid, int tick) //[orn]
+int skill_blockhomun_start(struct homun_data *hd, int skillid, int tick) //[orn]
{
- nullpo_retr(-1, hd);
-
- skillid = skill_get_index(skillid);
- if (skillid == 0)
- return -1;
-
- if (tick < 1) {
- hd->blockskill[skillid] = 0;
- return -1;
- }
- hd->blockskill[skillid] = 1;
- return add_timer(gettick() + tick, skill_blockhomun_end, hd->bl.id, skillid);
+ nullpo_retr (-1, hd);
+
+ skillid = skill_get_index(skillid);
+ if (skillid == 0)
+ return -1;
+
+ if (tick < 1) {
+ hd->blockskill[skillid] = 0;
+ return -1;
+ }
+ hd->blockskill[skillid] = 1;
+ return add_timer(gettick() + tick, skill_blockhomun_end, hd->bl.id, skillid);
}
-int skill_blockmerc_end(int tid, unsigned int tick, int id, intptr_t data) //[orn]
+int skill_blockmerc_end(int tid, unsigned int tick, int id, intptr_t data) //[orn]
{
- struct mercenary_data *md = (TBL_MER *)map_id2bl(id);
- if (data <= 0 || data >= MAX_SKILL)
- return 0;
- if (md) md->blockskill[data] = 0;
+ struct mercenary_data *md = (TBL_MER*)map_id2bl(id);
+ if( data <= 0 || data >= MAX_SKILL )
+ return 0;
+ if( md ) md->blockskill[data] = 0;
- return 1;
+ return 1;
}
int skill_blockmerc_start(struct mercenary_data *md, int skillid, int tick)
{
- nullpo_retr(-1, md);
-
- if ((skillid = skill_get_index(skillid)) == 0)
- return -1;
- if (tick < 1) {
- md->blockskill[skillid] = 0;
- return -1;
- }
- md->blockskill[skillid] = 1;
- return add_timer(gettick() + tick, skill_blockmerc_end, md->bl.id, skillid);
+ nullpo_retr (-1, md);
+
+ if( (skillid = skill_get_index(skillid)) == 0 )
+ return -1;
+ if( tick < 1 )
+ {
+ md->blockskill[skillid] = 0;
+ return -1;
+ }
+ md->blockskill[skillid] = 1;
+ return add_timer(gettick() + tick, skill_blockmerc_end, md->bl.id, skillid);
}
/**
* Adds a new skill unit entry for this player to recast after map load
**/
-void skill_usave_add(struct map_session_data *sd, int skill_num, int skill_lv)
-{
- struct skill_usave *sus = NULL;
+void skill_usave_add(struct map_session_data * sd, int skill_num, int skill_lv) {
+ struct skill_usave * sus = NULL;
- if (idb_exists(skillusave_db,sd->status.char_id)) {
- idb_remove(skillusave_db,sd->status.char_id);
- }
+ if( idb_exists(skillusave_db,sd->status.char_id) ) {
+ idb_remove(skillusave_db,sd->status.char_id);
+ }
- CREATE(sus, struct skill_usave, 1);
- idb_put(skillusave_db, sd->status.char_id, sus);
+ CREATE( sus, struct skill_usave, 1 );
+ idb_put( skillusave_db, sd->status.char_id, sus );
- sus->skill_num = skill_num;
- sus->skill_lv = skill_lv;
+ sus->skill_num = skill_num;
+ sus->skill_lv = skill_lv;
- return;
+ return;
}
-void skill_usave_trigger(struct map_session_data *sd)
-{
- struct skill_usave *sus = NULL;
+void skill_usave_trigger(struct map_session_data *sd) {
+ struct skill_usave * sus = NULL;
- if (!(sus = idb_get(skillusave_db,sd->status.char_id))) {
- return;
- }
+ if( ! (sus = idb_get(skillusave_db,sd->status.char_id)) ) {
+ return;
+ }
- skill_unitsetting(&sd->bl,sus->skill_num,sus->skill_lv,sd->bl.x,sd->bl.y,0);
+ skill_unitsetting(&sd->bl,sus->skill_num,sus->skill_lv,sd->bl.x,sd->bl.y,0);
- idb_remove(skillusave_db,sd->status.char_id);
+ idb_remove(skillusave_db,sd->status.char_id);
- return;
+ return;
}
/*
*
*/
-int skill_split_str(char *str, char **val, int num)
+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;
- }
+ int i;
+
+ for( i = 0; i < num && str; i++ )
+ {
+ val[i] = str;
+ str = strchr(str,',');
+ if( str )
+ *str++=0;
+ }
- return i;
+ return i;
}
/*
*
*/
-int skill_split_atoi(char *str, int *val)
+int skill_split_atoi (char *str, int *val)
{
- int i, j, diff, step = 1;
-
- for (i=0; i<MAX_SKILL_LEVEL; i++) {
- if (!str) break;
- val[i] = atoi(str);
- str = strchr(str,':');
- if (str)
- *str++=0;
- }
- if (i==0) //No data found.
- return 0;
- if (i==1) {
- //Single value, have the whole range have the same value.
- for (; i < MAX_SKILL_LEVEL; i++)
- val[i] = val[i-1];
- return i;
- }
- //Check for linear change with increasing steps until we reach half of the data acquired.
- for (step = 1; step <= i/2; step++) {
- diff = val[i-1] - val[i-step-1];
- for (j = i-1; j >= step; j--)
- if ((val[j]-val[j-step]) != diff)
- break;
-
- if (j>=step) //No match, try next step.
- continue;
-
- for (; i < MAX_SKILL_LEVEL; i++) {
- //Apply linear increase
- val[i] = val[i-step]+diff;
- if (val[i] < 1 && val[i-1] >=0) { //Check if we have switched from + to -, cap the decrease to 0 in said cases.
- val[i] = 1;
- diff = 0;
- step = 1;
- }
- }
- return i;
- }
- //Okay.. we can't figure this one out, just fill out the stuff with the previous value.
- for (; i<MAX_SKILL_LEVEL; i++)
- val[i] = val[i-1];
- return i;
+ int i, j, diff, step = 1;
+
+ for (i=0; i<MAX_SKILL_LEVEL; i++) {
+ if (!str) break;
+ val[i] = atoi(str);
+ str = strchr(str,':');
+ if (str)
+ *str++=0;
+ }
+ if(i==0) //No data found.
+ return 0;
+ if(i==1)
+ { //Single value, have the whole range have the same value.
+ for (; i < MAX_SKILL_LEVEL; i++)
+ val[i] = val[i-1];
+ return i;
+ }
+ //Check for linear change with increasing steps until we reach half of the data acquired.
+ for (step = 1; step <= i/2; step++)
+ {
+ diff = val[i-1] - val[i-step-1];
+ for(j = i-1; j >= step; j--)
+ if ((val[j]-val[j-step]) != diff)
+ break;
+
+ if (j>=step) //No match, try next step.
+ continue;
+
+ for(; i < MAX_SKILL_LEVEL; i++)
+ { //Apply linear increase
+ val[i] = val[i-step]+diff;
+ if (val[i] < 1 && val[i-1] >=0) //Check if we have switched from + to -, cap the decrease to 0 in said cases.
+ { val[i] = 1; diff = 0; step = 1; }
+ }
+ return i;
+ }
+ //Okay.. we can't figure this one out, just fill out the stuff with the previous value.
+ for (;i<MAX_SKILL_LEVEL; i++)
+ val[i] = val[i-1];
+ return i;
}
/*
*
*/
-void skill_init_unit_layout(void)
+void skill_init_unit_layout (void)
{
- int i,j,size,pos = 0;
-
- memset(skill_unit_layout,0,sizeof(skill_unit_layout));
-
- // standard square layouts go first
- 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);
- }
- }
-
- // afterwards add special ones
- pos = i;
- for (i=0; i<MAX_SKILL_DB; i++) {
- if (!skill_db[i].unit_id[0] || skill_db[i].unit_layout_type[0] != -1)
- continue;
- if (i >= HM_SKILLRANGEMIN && i <= EL_SKILLRANGEMAX) {
- int skill = i;
-
- if (i >= EL_SKILLRANGEMIN && i <= EL_SKILLRANGEMAX) {
- skill -= EL_SKILLRANGEMIN;
- skill += EL_SKILLBASE;
- }
- if (skill == EL_FIRE_MANTLE) {
- static const int dx[] = {-1, 0, 1, 1, 1, 0,-1,-1};
- static const int dy[] = { 1, 1, 1, 0,-1,-1,-1, 0};
- skill_unit_layout[pos].count = 8;
- memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx));
- memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy));
- }
- } else {
- switch (i) {
- case MG_FIREWALL:
- case WZ_ICEWALL:
- case WL_EARTHSTRAIN://Warlock
- // these will be handled later
- break;
- case PR_SANCTUARY:
- case NPC_EVILLAND: {
- 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 MH_POISON_MIST:
- 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_GRANDDARKNESS: {
- 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;
- case NJ_KAENSIN: {
- static const int dx[] = {-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2};
- static const int dy[] = { 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0,-1,-1,-1,-1,-1,-2,-2,-2,-2,-2};
- skill_unit_layout[pos].count = 24;
- memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx));
- memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy));
- }
- break;
- case NJ_TATAMIGAESHI: {
- //Level 1 (count 4, cross of 3x3)
- static const int dx1[] = {-1, 1, 0, 0};
- static const int dy1[] = { 0, 0,-1, 1};
- //Level 2-3 (count 8, cross of 5x5)
- static const int dx2[] = {-2,-1, 1, 2, 0, 0, 0, 0};
- static const int dy2[] = { 0, 0, 0, 0,-2,-1, 1, 2};
- //Level 4-5 (count 12, cross of 7x7
- static const int dx3[] = {-3,-2,-1, 1, 2, 3, 0, 0, 0, 0, 0, 0};
- static const int dy3[] = { 0, 0, 0, 0, 0, 0,-3,-2,-1, 1, 2, 3};
- //lv1
- j = 0;
- skill_unit_layout[pos].count = 4;
- memcpy(skill_unit_layout[pos].dx,dx1,sizeof(dx1));
- memcpy(skill_unit_layout[pos].dy,dy1,sizeof(dy1));
- skill_db[i].unit_layout_type[j] = pos;
- //lv2/3
- j++;
- pos++;
- skill_unit_layout[pos].count = 8;
- memcpy(skill_unit_layout[pos].dx,dx2,sizeof(dx2));
- memcpy(skill_unit_layout[pos].dy,dy2,sizeof(dy2));
- skill_db[i].unit_layout_type[j] = pos;
- skill_db[i].unit_layout_type[++j] = pos;
- //lv4/5
- j++;
- pos++;
- skill_unit_layout[pos].count = 12;
- memcpy(skill_unit_layout[pos].dx,dx3,sizeof(dx3));
- memcpy(skill_unit_layout[pos].dy,dy3,sizeof(dy3));
- skill_db[i].unit_layout_type[j] = pos;
- skill_db[i].unit_layout_type[++j] = pos;
- //Fill in the rest using lv 5.
- for (; j<MAX_SKILL_LEVEL; j++)
- skill_db[i].unit_layout_type[j] = pos;
- //Skip, this way the check below will fail and continue to the next skill.
- pos++;
- }
- break;
- case GN_WALLOFTHORN: {
- static const int dx[] = {-1,-2,-2,-2,-2,-2,-1, 0, 1, 2, 2, 2, 2, 2, 1, 0};
- static const int dy[] = { 2, 2, 1, 0,-1,-2,-2,-2,-2,-2,-1, 0, 1, 2, 2, 2};
- skill_unit_layout[pos].count = 16;
- memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx));
- memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy));
- }
- break;
- default:
- ShowError("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++;
- }
-
- // firewall and icewall have 8 layouts (direction-dependent)
- firewall_unit_pos = pos;
- for (i=0; i<8; i++) {
- if (i&1) {
- 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 {
- 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 {
- 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++;
- }
- icewall_unit_pos = pos;
- for (i=0; i<8; i++) {
- skill_unit_layout[pos].count = 5;
- if (i&1) {
- 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 {
- 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 {
- 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++;
- }
- earthstrain_unit_pos = pos;
- for (i = 0; i < 8; i++) {
- // For each Direction
- skill_unit_layout[pos].count = 15;
- switch (i) {
- case 0:
- case 1:
- case 3:
- case 4:
- case 5:
- case 7: {
- int dx[] = {-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7};
- int dy[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx));
- memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy));
- }
- break;
- case 2:
- case 6: {
- int dx[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- int dy[] = {-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7};
- memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx));
- memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy));
- }
- break;
- }
- pos++;
- }
+ int i,j,size,pos = 0;
+
+ memset(skill_unit_layout,0,sizeof(skill_unit_layout));
+
+ // standard square layouts go first
+ 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);
+ }
+ }
+
+ // afterwards add special ones
+ pos = i;
+ for (i=0;i<MAX_SKILL_DB;i++) {
+ if (!skill_db[i].unit_id[0] || skill_db[i].unit_layout_type[0] != -1)
+ continue;
+ if( i >= HM_SKILLRANGEMIN && i <= EL_SKILLRANGEMAX ) {
+ int skill = i;
+
+ if( i >= EL_SKILLRANGEMIN && i <= EL_SKILLRANGEMAX ) {
+ skill -= EL_SKILLRANGEMIN;
+ skill += EL_SKILLBASE;
+ }
+ if( skill == EL_FIRE_MANTLE ) {
+ static const int dx[] = {-1, 0, 1, 1, 1, 0,-1,-1};
+ static const int dy[] = { 1, 1, 1, 0,-1,-1,-1, 0};
+ skill_unit_layout[pos].count = 8;
+ memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy));
+ }
+ } else {
+ switch (i) {
+ case MG_FIREWALL:
+ case WZ_ICEWALL:
+ case WL_EARTHSTRAIN://Warlock
+ // these will be handled later
+ break;
+ case PR_SANCTUARY:
+ case NPC_EVILLAND: {
+ 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 MH_POISON_MIST:
+ 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_GRANDDARKNESS: {
+ 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;
+ case NJ_KAENSIN: {
+ static const int dx[] = {-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2};
+ static const int dy[] = { 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0,-1,-1,-1,-1,-1,-2,-2,-2,-2,-2};
+ skill_unit_layout[pos].count = 24;
+ memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy));
+ }
+ break;
+ case NJ_TATAMIGAESHI: {
+ //Level 1 (count 4, cross of 3x3)
+ static const int dx1[] = {-1, 1, 0, 0};
+ static const int dy1[] = { 0, 0,-1, 1};
+ //Level 2-3 (count 8, cross of 5x5)
+ static const int dx2[] = {-2,-1, 1, 2, 0, 0, 0, 0};
+ static const int dy2[] = { 0, 0, 0, 0,-2,-1, 1, 2};
+ //Level 4-5 (count 12, cross of 7x7
+ static const int dx3[] = {-3,-2,-1, 1, 2, 3, 0, 0, 0, 0, 0, 0};
+ static const int dy3[] = { 0, 0, 0, 0, 0, 0,-3,-2,-1, 1, 2, 3};
+ //lv1
+ j = 0;
+ skill_unit_layout[pos].count = 4;
+ memcpy(skill_unit_layout[pos].dx,dx1,sizeof(dx1));
+ memcpy(skill_unit_layout[pos].dy,dy1,sizeof(dy1));
+ skill_db[i].unit_layout_type[j] = pos;
+ //lv2/3
+ j++;
+ pos++;
+ skill_unit_layout[pos].count = 8;
+ memcpy(skill_unit_layout[pos].dx,dx2,sizeof(dx2));
+ memcpy(skill_unit_layout[pos].dy,dy2,sizeof(dy2));
+ skill_db[i].unit_layout_type[j] = pos;
+ skill_db[i].unit_layout_type[++j] = pos;
+ //lv4/5
+ j++;
+ pos++;
+ skill_unit_layout[pos].count = 12;
+ memcpy(skill_unit_layout[pos].dx,dx3,sizeof(dx3));
+ memcpy(skill_unit_layout[pos].dy,dy3,sizeof(dy3));
+ skill_db[i].unit_layout_type[j] = pos;
+ skill_db[i].unit_layout_type[++j] = pos;
+ //Fill in the rest using lv 5.
+ for (;j<MAX_SKILL_LEVEL;j++)
+ skill_db[i].unit_layout_type[j] = pos;
+ //Skip, this way the check below will fail and continue to the next skill.
+ pos++;
+ }
+ break;
+ case GN_WALLOFTHORN: {
+ static const int dx[] = {-1,-2,-2,-2,-2,-2,-1, 0, 1, 2, 2, 2, 2, 2, 1, 0};
+ static const int dy[] = { 2, 2, 1, 0,-1,-2,-2,-2,-2,-2,-1, 0, 1, 2, 2, 2};
+ skill_unit_layout[pos].count = 16;
+ memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy));
+ }
+ break;
+ default:
+ ShowError("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++;
+ }
+
+ // firewall and icewall have 8 layouts (direction-dependent)
+ firewall_unit_pos = pos;
+ for (i=0;i<8;i++) {
+ if (i&1) {
+ 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 {
+ 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 {
+ 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++;
+ }
+ icewall_unit_pos = pos;
+ for (i=0;i<8;i++) {
+ skill_unit_layout[pos].count = 5;
+ if (i&1) {
+ 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 {
+ 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 {
+ 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++;
+ }
+ earthstrain_unit_pos = pos;
+ for( i = 0; i < 8; i++ )
+ { // For each Direction
+ skill_unit_layout[pos].count = 15;
+ switch( i )
+ {
+ case 0: case 1: case 3: case 4: case 5: case 7:
+ {
+ int dx[] = {-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7};
+ int dy[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy));
+ }
+ break;
+ case 2:
+ case 6:
+ {
+ int dx[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ int dy[] = {-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7};
+ memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy));
+ }
+ break;
+ }
+ pos++;
+ }
}
-int skill_block_check(struct block_list *bl, sc_type type , int skillid)
-{
- int inf = 0;
- struct status_change *sc = status_get_sc(bl);
-
- if (!sc || !bl || skillid < 1)
- return 0; // Can do it
-
- switch (type) {
- case SC_STASIS:
- inf = skill_get_inf2(skillid);
- if (inf == INF2_SONG_DANCE || /*skill_get_inf2(skillid) == INF2_CHORUS_SKILL ||*/ inf == INF2_SPIRIT_SKILL)
- return 1; // Can't do it.
- switch (skillid) {
- case NV_FIRSTAID:
- case TF_HIDING:
- case AS_CLOAKING:
- case WZ_SIGHTRASHER:
- case RG_STRIPWEAPON:
- case RG_STRIPSHIELD:
- case RG_STRIPARMOR:
- case WZ_METEOR:
- case RG_STRIPHELM:
- case SC_STRIPACCESSARY:
- case ST_FULLSTRIP:
- case WZ_SIGHTBLASTER:
- case ST_CHASEWALK:
- case SC_ENERVATION:
- case SC_GROOMY:
- case WZ_ICEWALL:
- case SC_IGNORANCE:
- case SC_LAZINESS:
- case SC_UNLUCKY:
- case WZ_STORMGUST:
- case SC_WEAKNESS:
- case AL_RUWACH:
- case AL_PNEUMA:
- case WZ_JUPITEL:
- case AL_HEAL:
- case AL_BLESSING:
- case AL_INCAGI:
- case WZ_VERMILION:
- case AL_TELEPORT:
- case AL_WARP:
- case AL_HOLYWATER:
- case WZ_EARTHSPIKE:
- case AL_HOLYLIGHT:
- case PR_IMPOSITIO:
- case PR_ASPERSIO:
- case WZ_HEAVENDRIVE:
- case PR_SANCTUARY:
- case PR_STRECOVERY:
- case PR_MAGNIFICAT:
- case WZ_QUAGMIRE:
- case ALL_RESURRECTION:
- case PR_LEXDIVINA:
- case PR_LEXAETERNA:
- case HW_GRAVITATION:
- case PR_MAGNUS:
- case PR_TURNUNDEAD:
- case MG_SRECOVERY:
- case HW_MAGICPOWER:
- case MG_SIGHT:
- case MG_NAPALMBEAT:
- case MG_SAFETYWALL:
- case HW_GANBANTEIN:
- case MG_SOULSTRIKE:
- case MG_COLDBOLT:
- case MG_FROSTDIVER:
- case WL_DRAINLIFE:
- case MG_STONECURSE:
- case MG_FIREBALL:
- case MG_FIREWALL:
- case WL_SOULEXPANSION:
- case MG_FIREBOLT:
- case MG_LIGHTNINGBOLT:
- case MG_THUNDERSTORM:
- case MG_ENERGYCOAT:
- case WL_WHITEIMPRISON:
- case WL_SUMMONFB:
- case WL_SUMMONBL:
- case WL_SUMMONWB:
- case WL_SUMMONSTONE:
- case WL_SIENNAEXECRATE:
- case WL_RELEASE:
- case WL_EARTHSTRAIN:
- case WL_RECOGNIZEDSPELL:
- case WL_READING_SB:
- case SA_MAGICROD:
- case SA_SPELLBREAKER:
- case SA_DISPELL:
- case SA_FLAMELAUNCHER:
- case SA_FROSTWEAPON:
- case SA_LIGHTNINGLOADER:
- case SA_SEISMICWEAPON:
- case SA_VOLCANO:
- case SA_DELUGE:
- case SA_VIOLENTGALE:
- case SA_LANDPROTECTOR:
- case PF_HPCONVERSION:
- case PF_SOULCHANGE:
- case PF_SPIDERWEB:
- case PF_FOGWALL:
- case TK_RUN:
- case TK_HIGHJUMP:
- case TK_SEVENWIND:
- case SL_KAAHI:
- case SL_KAUPE:
- case SL_KAITE:
-
- // Skills that need to be confirmed.
- case SO_FIREWALK:
- case SO_ELECTRICWALK:
- case SO_SPELLFIST:
- case SO_EARTHGRAVE:
- case SO_DIAMONDDUST:
- case SO_POISON_BUSTER:
- case SO_PSYCHIC_WAVE:
- case SO_CLOUD_KILL:
- case SO_STRIKING:
- case SO_WARMER:
- case SO_VACUUM_EXTREME:
- case SO_VARETYR_SPEAR:
- case SO_ARRULLO:
- return 1; // Can't do it.
- }
- break;
- case SC_KAGEHUMI:
- switch (skillid) {
- case TF_HIDING:
- case AS_CLOAKING:
- case GC_CLOAKINGEXCEED:
- case SC_SHADOWFORM:
- case MI_HARMONIZE:
- case CG_MARIONETTE:
- case AL_TELEPORT:
- case TF_BACKSLIDING:
- case RA_CAMOUFLAGE:
- case ST_CHASEWALK:
- case GD_EMERGENCYCALL:
- return 1; // needs more info
- }
- break;
- }
+int skill_block_check(struct block_list *bl, sc_type type , int skillid) {
+ int inf = 0;
+ struct status_change *sc = status_get_sc(bl);
+
+ if( !sc || !bl || skillid < 1 )
+ return 0; // Can do it
+
+ switch(type){
+ case SC_STASIS:
+ inf = skill_get_inf2(skillid);
+ if( inf == INF2_SONG_DANCE || /*skill_get_inf2(skillid) == INF2_CHORUS_SKILL ||*/ inf == INF2_SPIRIT_SKILL )
+ return 1; // Can't do it.
+ switch( skillid )
+ {
+ case NV_FIRSTAID: case TF_HIDING: case AS_CLOAKING: case WZ_SIGHTRASHER:
+ case RG_STRIPWEAPON: case RG_STRIPSHIELD: case RG_STRIPARMOR: case WZ_METEOR:
+ case RG_STRIPHELM: case SC_STRIPACCESSARY: case ST_FULLSTRIP: case WZ_SIGHTBLASTER:
+ case ST_CHASEWALK: case SC_ENERVATION: case SC_GROOMY: case WZ_ICEWALL:
+ case SC_IGNORANCE: case SC_LAZINESS: case SC_UNLUCKY: case WZ_STORMGUST:
+ case SC_WEAKNESS: case AL_RUWACH: case AL_PNEUMA: case WZ_JUPITEL:
+ case AL_HEAL: case AL_BLESSING: case AL_INCAGI: case WZ_VERMILION:
+ case AL_TELEPORT: case AL_WARP: case AL_HOLYWATER: case WZ_EARTHSPIKE:
+ case AL_HOLYLIGHT: case PR_IMPOSITIO: case PR_ASPERSIO: case WZ_HEAVENDRIVE:
+ case PR_SANCTUARY: case PR_STRECOVERY: case PR_MAGNIFICAT: case WZ_QUAGMIRE:
+ case ALL_RESURRECTION: case PR_LEXDIVINA: case PR_LEXAETERNA: case HW_GRAVITATION:
+ case PR_MAGNUS: case PR_TURNUNDEAD: case MG_SRECOVERY: case HW_MAGICPOWER:
+ case MG_SIGHT: case MG_NAPALMBEAT: case MG_SAFETYWALL: case HW_GANBANTEIN:
+ case MG_SOULSTRIKE: case MG_COLDBOLT: case MG_FROSTDIVER: case WL_DRAINLIFE:
+ case MG_STONECURSE: case MG_FIREBALL: case MG_FIREWALL: case WL_SOULEXPANSION:
+ case MG_FIREBOLT: case MG_LIGHTNINGBOLT: case MG_THUNDERSTORM: case MG_ENERGYCOAT:
+ case WL_WHITEIMPRISON: case WL_SUMMONFB: case WL_SUMMONBL: case WL_SUMMONWB:
+ case WL_SUMMONSTONE: case WL_SIENNAEXECRATE: case WL_RELEASE: case WL_EARTHSTRAIN:
+ case WL_RECOGNIZEDSPELL: case WL_READING_SB: case SA_MAGICROD: case SA_SPELLBREAKER:
+ case SA_DISPELL: case SA_FLAMELAUNCHER: case SA_FROSTWEAPON: case SA_LIGHTNINGLOADER:
+ case SA_SEISMICWEAPON: case SA_VOLCANO: case SA_DELUGE: case SA_VIOLENTGALE:
+ case SA_LANDPROTECTOR: case PF_HPCONVERSION: case PF_SOULCHANGE: case PF_SPIDERWEB:
+ case PF_FOGWALL: case TK_RUN: case TK_HIGHJUMP: case TK_SEVENWIND:
+ case SL_KAAHI: case SL_KAUPE: case SL_KAITE:
+
+ // Skills that need to be confirmed.
+ case SO_FIREWALK: case SO_ELECTRICWALK: case SO_SPELLFIST: case SO_EARTHGRAVE:
+ case SO_DIAMONDDUST: case SO_POISON_BUSTER: case SO_PSYCHIC_WAVE: case SO_CLOUD_KILL:
+ case SO_STRIKING: case SO_WARMER: case SO_VACUUM_EXTREME: case SO_VARETYR_SPEAR:
+ case SO_ARRULLO:
+ return 1; // Can't do it.
+ }
+ break;
+ case SC_KAGEHUMI:
+ switch(skillid){
+ case TF_HIDING: case AS_CLOAKING: case GC_CLOAKINGEXCEED: case SC_SHADOWFORM:
+ case MI_HARMONIZE: case CG_MARIONETTE: case AL_TELEPORT: case TF_BACKSLIDING:
+ case RA_CAMOUFLAGE: case ST_CHASEWALK: case GD_EMERGENCYCALL:
+ return 1; // needs more info
+ }
+ break;
+ }
- return 0;
+ return 0;
}
-int skill_get_elemental_type(int skill_id , int skill_lv)
-{
- int type = 0;
+int skill_get_elemental_type( int skill_id , int skill_lv ) {
+ int type = 0;
- switch (skill_id) {
- case SO_SUMMON_AGNI:
- type = 2114;
- break;
- case SO_SUMMON_AQUA:
- type = 2117;
- break;
- case SO_SUMMON_VENTUS:
- type = 2120;
- break;
- case SO_SUMMON_TERA:
- type = 2123;
- break;
- }
+ switch( skill_id ) {
+ case SO_SUMMON_AGNI: type = 2114; break;
+ case SO_SUMMON_AQUA: type = 2117; break;
+ case SO_SUMMON_VENTUS: type = 2120; break;
+ case SO_SUMMON_TERA: type = 2123; break;
+ }
- type += skill_lv - 1;
+ type += skill_lv - 1;
- return type;
+ return type;
}
/**
* reload stored skill cooldowns when a player logs in.
* @param sd the affected player structure
*/
-void skill_cooldown_load(struct map_session_data *sd)
+void skill_cooldown_load(struct map_session_data * sd)
{
- int i;
- struct skill_cd *cd = NULL;
-
- // always check to make sure the session properly exists
- nullpo_retv(sd);
-
- if (!(cd = idb_get(skillcd_db, sd->status.char_id))) {
- // no skill cooldown is associated with this character
- return;
- }
-
- // process each individual cooldown associated with the character
- for (i = 0; i < cd->cursor; i++) {
- // block the skill from usage but ensure it is not recorded (load = true)
- skill_blockpc_start_(sd, cd->nameid[i], cd->duration[i], true);
- }
+ int i;
+ struct skill_cd* cd = NULL;
+
+ // always check to make sure the session properly exists
+ nullpo_retv(sd);
+
+ if( !(cd = idb_get(skillcd_db, sd->status.char_id)) )
+ {// no skill cooldown is associated with this character
+ return;
+ }
+
+ // process each individual cooldown associated with the character
+ for( i = 0; i < cd->cursor; i++ )
+ {
+ // block the skill from usage but ensure it is not recorded (load = true)
+ skill_blockpc_start_( sd, cd->nameid[i], cd->duration[i], true );
+ }
}
/*==========================================
@@ -17619,405 +17355,406 @@ void skill_cooldown_load(struct map_session_data *sd)
* skill_db.txt
*------------------------------------------*/
-static bool skill_parse_row_skilldb(char *split[], int columns, int current)
-{
- // id,range,hit,inf,element,nk,splash,max,list_num,castcancel,cast_defence_rate,inf2,maxcount,skill_type,blow_count,name,description
- int id = atoi(split[0]);
- int i;
- if ((id >= GD_SKILLRANGEMIN && id <= GD_SKILLRANGEMAX)
- || (id >= HM_SKILLRANGEMIN && id <= HM_SKILLRANGEMAX)
- || (id >= MC_SKILLRANGEMIN && id <= MC_SKILLRANGEMAX)
- || (id >= EL_SKILLRANGEMIN && id <= EL_SKILLRANGEMAX)) {
- ShowWarning("skill_parse_row_skilldb: Skill id %d is forbidden (interferes with guild/homun/mercenary skill mapping)!\n", id);
- return false;
- }
-
- i = skill_get_index(id);
- if (!i) // invalid skill id
- return false;
-
- skill_split_atoi(split[1],skill_db[i].range);
- skill_db[i].hit = atoi(split[2]);
- skill_db[i].inf = atoi(split[3]);
- skill_split_atoi(split[4],skill_db[i].element);
- skill_db[i].nk = (int)strtol(split[5], NULL, 0);
- skill_split_atoi(split[6],skill_db[i].splash);
- skill_db[i].max = atoi(split[7]);
- skill_split_atoi(split[8],skill_db[i].num);
-
- if (strcmpi(split[9],"yes") == 0)
- skill_db[i].castcancel = 1;
- else
- skill_db[i].castcancel = 0;
- skill_db[i].cast_def_rate = atoi(split[10]);
- skill_db[i].inf2 = (int)strtol(split[11], NULL, 0);
- skill_split_atoi(split[12],skill_db[i].maxcount);
- if (strcmpi(split[13],"weapon") == 0)
- skill_db[i].skill_type = BF_WEAPON;
- else if (strcmpi(split[13],"magic") == 0)
- skill_db[i].skill_type = BF_MAGIC;
- else if (strcmpi(split[13],"misc") == 0)
- skill_db[i].skill_type = BF_MISC;
- else
- skill_db[i].skill_type = 0;
- skill_split_atoi(split[14],skill_db[i].blewcount);
- safestrncpy(skill_db[i].name, trim(split[15]), sizeof(skill_db[i].name));
- safestrncpy(skill_db[i].desc, trim(split[16]), sizeof(skill_db[i].desc));
- strdb_iput(skilldb_name2id, skill_db[i].name, id);
-
- return true;
+static bool skill_parse_row_skilldb(char* split[], int columns, int current)
+{// id,range,hit,inf,element,nk,splash,max,list_num,castcancel,cast_defence_rate,inf2,maxcount,skill_type,blow_count,name,description
+ int id = atoi(split[0]);
+ int i;
+ if( (id >= GD_SKILLRANGEMIN && id <= GD_SKILLRANGEMAX)
+ || (id >= HM_SKILLRANGEMIN && id <= HM_SKILLRANGEMAX)
+ || (id >= MC_SKILLRANGEMIN && id <= MC_SKILLRANGEMAX)
+ || (id >= EL_SKILLRANGEMIN && id <= EL_SKILLRANGEMAX) ) {
+ ShowWarning("skill_parse_row_skilldb: Skill id %d is forbidden (interferes with guild/homun/mercenary skill mapping)!\n", id);
+ return false;
+ }
+
+ i = skill_get_index(id);
+ if( !i ) // invalid skill id
+ return false;
+
+ skill_split_atoi(split[1],skill_db[i].range);
+ skill_db[i].hit = atoi(split[2]);
+ skill_db[i].inf = atoi(split[3]);
+ skill_split_atoi(split[4],skill_db[i].element);
+ skill_db[i].nk = (int)strtol(split[5], NULL, 0);
+ skill_split_atoi(split[6],skill_db[i].splash);
+ skill_db[i].max = atoi(split[7]);
+ skill_split_atoi(split[8],skill_db[i].num);
+
+ if( strcmpi(split[9],"yes") == 0 )
+ skill_db[i].castcancel = 1;
+ else
+ skill_db[i].castcancel = 0;
+ skill_db[i].cast_def_rate = atoi(split[10]);
+ skill_db[i].inf2 = (int)strtol(split[11], NULL, 0);
+ skill_split_atoi(split[12],skill_db[i].maxcount);
+ if( strcmpi(split[13],"weapon") == 0 )
+ skill_db[i].skill_type = BF_WEAPON;
+ else if( strcmpi(split[13],"magic") == 0 )
+ skill_db[i].skill_type = BF_MAGIC;
+ else if( strcmpi(split[13],"misc") == 0 )
+ skill_db[i].skill_type = BF_MISC;
+ else
+ skill_db[i].skill_type = 0;
+ skill_split_atoi(split[14],skill_db[i].blewcount);
+ safestrncpy(skill_db[i].name, trim(split[15]), sizeof(skill_db[i].name));
+ safestrncpy(skill_db[i].desc, trim(split[16]), sizeof(skill_db[i].desc));
+ strdb_iput(skilldb_name2id, skill_db[i].name, id);
+
+ return true;
}
-static bool skill_parse_row_requiredb(char *split[], int columns, int current)
-{
- // SkillID,HPCost,MaxHPTrigger,SPCost,HPRateCost,SPRateCost,ZenyCost,RequiredWeapons,RequiredAmmoTypes,RequiredAmmoAmount,RequiredState,SpiritSphereCost,RequiredItemID1,RequiredItemAmount1,RequiredItemID2,RequiredItemAmount2,RequiredItemID3,RequiredItemAmount3,RequiredItemID4,RequiredItemAmount4,RequiredItemID5,RequiredItemAmount5,RequiredItemID6,RequiredItemAmount6,RequiredItemID7,RequiredItemAmount7,RequiredItemID8,RequiredItemAmount8,RequiredItemID9,RequiredItemAmount9,RequiredItemID10,RequiredItemAmount10
- char *p;
- int j;
-
- int i = atoi(split[0]);
- i = skill_get_index(i);
- if (!i) // invalid skill id
- return false;
-
- 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);
+static bool skill_parse_row_requiredb(char* split[], int columns, int current)
+{// SkillID,HPCost,MaxHPTrigger,SPCost,HPRateCost,SPRateCost,ZenyCost,RequiredWeapons,RequiredAmmoTypes,RequiredAmmoAmount,RequiredState,SpiritSphereCost,RequiredItemID1,RequiredItemAmount1,RequiredItemID2,RequiredItemAmount2,RequiredItemID3,RequiredItemAmount3,RequiredItemID4,RequiredItemAmount4,RequiredItemID5,RequiredItemAmount5,RequiredItemID6,RequiredItemAmount6,RequiredItemID7,RequiredItemAmount7,RequiredItemID8,RequiredItemAmount8,RequiredItemID9,RequiredItemAmount9,RequiredItemID10,RequiredItemAmount10
+ char* p;
+ int j;
+
+ int i = atoi(split[0]);
+ i = skill_get_index(i);
+ if( !i ) // invalid skill id
+ return false;
+
+ 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);
//Wich weapon type are required, see doc/item_db for types
- p = split[7];
- for (j = 0; j < 32; j++) {
- int l = atoi(p);
- if (l == 99) { // Any weapon
- skill_db[i].weapon = 0;
- break;
- } else
- skill_db[i].weapon |= 1<<l;
- p = strchr(p,':');
- if (!p)
- break;
- p++;
- }
-
- //FIXME: document this
- p = split[8];
- for (j = 0; j < 32; j++) {
- int l = atoi(p);
- if (l == 99) { // Any ammo type
- skill_db[i].ammo = 0xFFFFFFFF;
- break;
- } else if (l) // 0 stands for no requirement
- skill_db[i].ammo |= 1<<l;
- p = strchr(p,':');
- if (!p)
- break;
- p++;
- }
- skill_split_atoi(split[9],skill_db[i].ammo_qty);
-
- if (strcmpi(split[10],"hiding")==0) skill_db[i].state = ST_HIDING;
- else if (strcmpi(split[10],"cloaking")==0) skill_db[i].state = ST_CLOAKING;
- else if (strcmpi(split[10],"hidden")==0) skill_db[i].state = ST_HIDDEN;
- else if (strcmpi(split[10],"riding")==0) skill_db[i].state = ST_RIDING;
- else if (strcmpi(split[10],"falcon")==0) skill_db[i].state = ST_FALCON;
- else if (strcmpi(split[10],"cart")==0) skill_db[i].state = ST_CART;
- else if (strcmpi(split[10],"shield")==0) skill_db[i].state = ST_SHIELD;
- else if (strcmpi(split[10],"sight")==0) skill_db[i].state = ST_SIGHT;
- else if (strcmpi(split[10],"explosionspirits")==0) skill_db[i].state = ST_EXPLOSIONSPIRITS;
- else if (strcmpi(split[10],"cartboost")==0) skill_db[i].state = ST_CARTBOOST;
- else if (strcmpi(split[10],"recover_weight_rate")==0) skill_db[i].state = ST_RECOV_WEIGHT_RATE;
- else if (strcmpi(split[10],"move_enable")==0) skill_db[i].state = ST_MOVE_ENABLE;
- else if (strcmpi(split[10],"water")==0) skill_db[i].state = ST_WATER;
- /**
- * New States
- **/
- else if (strcmpi(split[10],"dragon")==0) skill_db[i].state = ST_RIDINGDRAGON;
- else if (strcmpi(split[10],"warg")==0) skill_db[i].state = ST_WUG;
- else if (strcmpi(split[10],"ridingwarg")==0) skill_db[i].state = ST_RIDINGWUG;
- else if (strcmpi(split[10],"mado")==0) skill_db[i].state = ST_MADO;
- else if (strcmpi(split[10],"elementalspirit")==0) skill_db[i].state = ST_ELEMENTALSPIRIT;
- else if (strcmpi(split[10], "poisonweapon") == 0) skill_db[i].state = ST_POISONINGWEAPON;
- else if (strcmpi(split[10], "rollingcutter") == 0) skill_db[i].state = ST_ROLLINGCUTTER;
-
- /**
- * Unknown or no state
- **/
- else skill_db[i].state = ST_NONE;
-
- skill_split_atoi(split[11],skill_db[i].spiritball);
- for (j = 0; j < MAX_SKILL_ITEM_REQUIRE; j++) {
- skill_db[i].itemid[j] = atoi(split[12+ 2*j]);
- skill_db[i].amount[j] = atoi(split[13+ 2*j]);
- }
-
- return true;
+ p = split[7];
+ for( j = 0; j < 32; j++ )
+ {
+ int l = atoi(p);
+ if( l == 99 ) // Any weapon
+ {
+ skill_db[i].weapon = 0;
+ break;
+ }
+ else
+ skill_db[i].weapon |= 1<<l;
+ p = strchr(p,':');
+ if(!p)
+ break;
+ p++;
+ }
+
+ //FIXME: document this
+ p = split[8];
+ for( j = 0; j < 32; j++ )
+ {
+ int l = atoi(p);
+ if( l == 99 ) // Any ammo type
+ {
+ skill_db[i].ammo = 0xFFFFFFFF;
+ break;
+ }
+ else if( l ) // 0 stands for no requirement
+ skill_db[i].ammo |= 1<<l;
+ p = strchr(p,':');
+ if( !p )
+ break;
+ p++;
+ }
+ skill_split_atoi(split[9],skill_db[i].ammo_qty);
+
+ if( strcmpi(split[10],"hiding")==0 ) skill_db[i].state = ST_HIDING;
+ else if( strcmpi(split[10],"cloaking")==0 ) skill_db[i].state = ST_CLOAKING;
+ else if( strcmpi(split[10],"hidden")==0 ) skill_db[i].state = ST_HIDDEN;
+ else if( strcmpi(split[10],"riding")==0 ) skill_db[i].state = ST_RIDING;
+ else if( strcmpi(split[10],"falcon")==0 ) skill_db[i].state = ST_FALCON;
+ else if( strcmpi(split[10],"cart")==0 ) skill_db[i].state = ST_CART;
+ else if( strcmpi(split[10],"shield")==0 ) skill_db[i].state = ST_SHIELD;
+ else if( strcmpi(split[10],"sight")==0 ) skill_db[i].state = ST_SIGHT;
+ else if( strcmpi(split[10],"explosionspirits")==0 ) skill_db[i].state = ST_EXPLOSIONSPIRITS;
+ else if( strcmpi(split[10],"cartboost")==0 ) skill_db[i].state = ST_CARTBOOST;
+ else if( strcmpi(split[10],"recover_weight_rate")==0 ) skill_db[i].state = ST_RECOV_WEIGHT_RATE;
+ else if( strcmpi(split[10],"move_enable")==0 ) skill_db[i].state = ST_MOVE_ENABLE;
+ else if( strcmpi(split[10],"water")==0 ) skill_db[i].state = ST_WATER;
+ /**
+ * New States
+ **/
+ else if( strcmpi(split[10],"dragon")==0 ) skill_db[i].state = ST_RIDINGDRAGON;
+ else if( strcmpi(split[10],"warg")==0 ) skill_db[i].state = ST_WUG;
+ else if( strcmpi(split[10],"ridingwarg")==0 ) skill_db[i].state = ST_RIDINGWUG;
+ else if( strcmpi(split[10],"mado")==0 ) skill_db[i].state = ST_MADO;
+ else if( strcmpi(split[10],"elementalspirit")==0 ) skill_db[i].state = ST_ELEMENTALSPIRIT;
+ else if (strcmpi(split[10], "poisonweapon") == 0) skill_db[i].state = ST_POISONINGWEAPON;
+ else if (strcmpi(split[10], "rollingcutter") == 0) skill_db[i].state = ST_ROLLINGCUTTER;
+
+ /**
+ * Unknown or no state
+ **/
+ else skill_db[i].state = ST_NONE;
+
+ skill_split_atoi(split[11],skill_db[i].spiritball);
+ for( j = 0; j < MAX_SKILL_ITEM_REQUIRE; j++ ) {
+ skill_db[i].itemid[j] = atoi(split[12+ 2*j]);
+ skill_db[i].amount[j] = atoi(split[13+ 2*j]);
+ }
+
+ return true;
}
-static bool skill_parse_row_castdb(char *split[], int columns, int current)
-{
- // SkillID,CastingTime,AfterCastActDelay,AfterCastWalkDelay,Duration1,Duration2
- int i = atoi(split[0]);
- i = skill_get_index(i);
- if (!i) // invalid skill id
- return false;
-
- 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].walkdelay);
- skill_split_atoi(split[4],skill_db[i].upkeep_time);
- skill_split_atoi(split[5],skill_db[i].upkeep_time2);
- skill_split_atoi(split[6],skill_db[i].cooldown);
+static bool skill_parse_row_castdb(char* split[], int columns, int current)
+{// SkillID,CastingTime,AfterCastActDelay,AfterCastWalkDelay,Duration1,Duration2
+ int i = atoi(split[0]);
+ i = skill_get_index(i);
+ if( !i ) // invalid skill id
+ return false;
+
+ 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].walkdelay);
+ skill_split_atoi(split[4],skill_db[i].upkeep_time);
+ skill_split_atoi(split[5],skill_db[i].upkeep_time2);
+ skill_split_atoi(split[6],skill_db[i].cooldown);
#ifdef RENEWAL_CAST
- skill_split_atoi(split[7],skill_db[i].fixed_cast);
+ skill_split_atoi(split[7],skill_db[i].fixed_cast);
#endif
- return true;
+ return true;
}
-static bool skill_parse_row_castnodexdb(char *split[], int columns, int current)
-{
- // Skill id,Cast,Delay (optional)
- int i = atoi(split[0]);
- i = skill_get_index(i);
- if (!i) // invalid skill id
- return false;
+static bool skill_parse_row_castnodexdb(char* split[], int columns, int current)
+{// Skill id,Cast,Delay (optional)
+ int i = atoi(split[0]);
+ i = skill_get_index(i);
+ if( !i ) // invalid skill id
+ return false;
- skill_split_atoi(split[1],skill_db[i].castnodex);
- if (split[2]) // optional column
- skill_split_atoi(split[2],skill_db[i].delaynodex);
+ skill_split_atoi(split[1],skill_db[i].castnodex);
+ if( split[2] ) // optional column
+ skill_split_atoi(split[2],skill_db[i].delaynodex);
- return true;
+ return true;
}
-static bool skill_parse_row_nocastdb(char *split[], int columns, int current)
-{
- // SkillID,Flag
- int i = atoi(split[0]);
- i = skill_get_index(i);
- if (!i) // invalid skill id
- return false;
+static bool skill_parse_row_nocastdb(char* split[], int columns, int current)
+{// SkillID,Flag
+ int i = atoi(split[0]);
+ i = skill_get_index(i);
+ if( !i ) // invalid skill id
+ return false;
- skill_db[i].nocast |= atoi(split[1]);
+ skill_db[i].nocast |= atoi(split[1]);
- return true;
+ return true;
}
-static bool skill_parse_row_unitdb(char *split[], int columns, int current)
-{
- // ID,unit ID,unit ID 2,layout,range,interval,target,flag
- int i = atoi(split[0]);
- i = skill_get_index(i);
- if (!i) // invalid skill id
- return false;
-
- 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_split_atoi(split[4],skill_db[i].unit_range);
- 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],"ally")==0) skill_db[i].unit_target = BCT_PARTY|BCT_GUILD;
- else if (strcmpi(split[6],"guild")==0) skill_db[i].unit_target = BCT_GUILD;
- 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 if (strcmpi(split[6],"noone")==0) skill_db[i].unit_target = BCT_NOONE;
- else skill_db[i].unit_target = strtol(split[6],NULL,16);
-
- skill_db[i].unit_flag = strtol(split[7],NULL,16);
-
- if (skill_db[i].unit_flag&UF_DEFNOTENEMY && battle_config.defnotenemy)
- skill_db[i].unit_target = BCT_NOENEMY;
-
- //By default, target just characters.
- skill_db[i].unit_target |= BL_CHAR;
- if (skill_db[i].unit_flag&UF_NOPC)
- skill_db[i].unit_target &= ~BL_PC;
- if (skill_db[i].unit_flag&UF_NOMOB)
- skill_db[i].unit_target &= ~BL_MOB;
- if (skill_db[i].unit_flag&UF_SKILL)
- skill_db[i].unit_target |= BL_SKILL;
-
- return true;
+static bool skill_parse_row_unitdb(char* split[], int columns, int current)
+{// ID,unit ID,unit ID 2,layout,range,interval,target,flag
+ int i = atoi(split[0]);
+ i = skill_get_index(i);
+ if( !i ) // invalid skill id
+ return false;
+
+ 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_split_atoi(split[4],skill_db[i].unit_range);
+ 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],"ally")==0 ) skill_db[i].unit_target = BCT_PARTY|BCT_GUILD;
+ else if( strcmpi(split[6],"guild")==0 ) skill_db[i].unit_target = BCT_GUILD;
+ 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 if( strcmpi(split[6],"noone")==0 ) skill_db[i].unit_target = BCT_NOONE;
+ else skill_db[i].unit_target = strtol(split[6],NULL,16);
+
+ skill_db[i].unit_flag = strtol(split[7],NULL,16);
+
+ if (skill_db[i].unit_flag&UF_DEFNOTENEMY && battle_config.defnotenemy)
+ skill_db[i].unit_target = BCT_NOENEMY;
+
+ //By default, target just characters.
+ skill_db[i].unit_target |= BL_CHAR;
+ if (skill_db[i].unit_flag&UF_NOPC)
+ skill_db[i].unit_target &= ~BL_PC;
+ if (skill_db[i].unit_flag&UF_NOMOB)
+ skill_db[i].unit_target &= ~BL_MOB;
+ if (skill_db[i].unit_flag&UF_SKILL)
+ skill_db[i].unit_target |= BL_SKILL;
+
+ return true;
}
-static bool skill_parse_row_producedb(char *split[], int columns, int current)
-{
- // ProduceItemID,ItemLV,RequireSkill,RequireSkillLv,MaterialID1,MaterialAmount1,......
- int x,y;
+static bool skill_parse_row_producedb(char* split[], int columns, int current)
+{// ProduceItemID,ItemLV,RequireSkill,RequireSkillLv,MaterialID1,MaterialAmount1,......
+ int x,y;
- int i = atoi(split[0]);
- if (!i)
- return false;
+ int i = atoi(split[0]);
+ if( !i )
+ return false;
- skill_produce_db[current].nameid = i;
- skill_produce_db[current].itemlv = atoi(split[1]);
- skill_produce_db[current].req_skill = atoi(split[2]);
- skill_produce_db[current].req_skill_lv = atoi(split[3]);
+ skill_produce_db[current].nameid = i;
+ skill_produce_db[current].itemlv = atoi(split[1]);
+ skill_produce_db[current].req_skill = atoi(split[2]);
+ skill_produce_db[current].req_skill_lv = atoi(split[3]);
- for (x = 4, y = 0; x+1 < columns && split[x] && split[x+1] && y < MAX_PRODUCE_RESOURCE; x += 2, y++) {
- skill_produce_db[current].mat_id[y] = atoi(split[x]);
- skill_produce_db[current].mat_amount[y] = atoi(split[x+1]);
- }
+ for( x = 4, y = 0; x+1 < columns && split[x] && split[x+1] && y < MAX_PRODUCE_RESOURCE; x += 2, y++ )
+ {
+ skill_produce_db[current].mat_id[y] = atoi(split[x]);
+ skill_produce_db[current].mat_amount[y] = atoi(split[x+1]);
+ }
- return true;
+ return true;
}
-static bool skill_parse_row_createarrowdb(char *split[], int columns, int current)
-{
- // SourceID,MakeID1,MakeAmount1,...,MakeID5,MakeAmount5
- int x,y;
+static bool skill_parse_row_createarrowdb(char* split[], int columns, int current)
+{// SourceID,MakeID1,MakeAmount1,...,MakeID5,MakeAmount5
+ int x,y;
- int i = atoi(split[0]);
- if (!i)
- return false;
+ int i = atoi(split[0]);
+ if( !i )
+ return false;
- skill_arrow_db[current].nameid = i;
+ skill_arrow_db[current].nameid = i;
- for (x = 1, y = 0; x+1 < columns && split[x] && split[x+1] && y < MAX_ARROW_RESOURCE; x += 2, y++) {
- skill_arrow_db[current].cre_id[y] = atoi(split[x]);
- skill_arrow_db[current].cre_amount[y] = atoi(split[x+1]);
- }
+ for( x = 1, y = 0; x+1 < columns && split[x] && split[x+1] && y < MAX_ARROW_RESOURCE; x += 2, y++ )
+ {
+ skill_arrow_db[current].cre_id[y] = atoi(split[x]);
+ skill_arrow_db[current].cre_amount[y] = atoi(split[x+1]);
+ }
- return true;
+ return true;
}
-static bool skill_parse_row_spellbookdb(char *split[], int columns, int current)
-{
- // SkillID,PreservePoints
-
- int skillid = atoi(split[0]),
- points = atoi(split[1]),
- nameid = atoi(split[2]);
-
- if (!skill_get_index(skillid) || !skill_get_max(skillid))
- ShowError("spellbook_db: Invalid skill ID %d\n", skillid);
- if (!skill_get_inf(skillid))
- ShowError("spellbook_db: Passive skills cannot be memorized (%d/%s)\n", skillid, skill_get_name(skillid));
- if (points < 1)
- ShowError("spellbook_db: PreservePoints have to be 1 or above! (%d/%s)\n", skillid, skill_get_name(skillid));
- else {
- skill_spellbook_db[current].skillid = skillid;
- skill_spellbook_db[current].point = points;
- skill_spellbook_db[current].nameid = nameid;
-
- return true;
- }
-
- return false;
+static bool skill_parse_row_spellbookdb(char* split[], int columns, int current)
+{// SkillID,PreservePoints
+
+ int skillid = atoi(split[0]),
+ points = atoi(split[1]),
+ nameid = atoi(split[2]);
+
+ if( !skill_get_index(skillid) || !skill_get_max(skillid) )
+ ShowError("spellbook_db: Invalid skill ID %d\n", skillid);
+ if ( !skill_get_inf(skillid) )
+ ShowError("spellbook_db: Passive skills cannot be memorized (%d/%s)\n", skillid, skill_get_name(skillid));
+ if( points < 1 )
+ ShowError("spellbook_db: PreservePoints have to be 1 or above! (%d/%s)\n", skillid, skill_get_name(skillid));
+ else
+ {
+ skill_spellbook_db[current].skillid = skillid;
+ skill_spellbook_db[current].point = points;
+ skill_spellbook_db[current].nameid = nameid;
+
+ return true;
+ }
+
+ return false;
}
-static bool skill_parse_row_improvisedb(char *split[], int columns, int current)
-{
- // SkillID
- int i = atoi(split[0]);
- short j = atoi(split[1]);
-
- if (!skill_get_index(i) || !skill_get_max(i)) {
- ShowError("skill_improvise_db: Invalid skill ID %d\n", i);
- return false;
- }
- if (!skill_get_inf(i)) {
- ShowError("skill_improvise_db: Passive skills cannot be casted (%d/%s)\n", i, skill_get_name(i));
- return false;
- }
- if (j < 1) {
- ShowError("skill_improvise_db: Chances have to be 1 or above! (%d/%s)\n", i, skill_get_name(i));
- return false;
- }
- if (current >= MAX_SKILL_IMPROVISE_DB) {
- ShowError("skill_improvise_db: Maximum amount of entries reached (%d), increase MAX_SKILL_IMPROVISE_DB\n",MAX_SKILL_IMPROVISE_DB);
- }
- skill_improvise_db[current].skillid = i;
- skill_improvise_db[current].per = j; // Still need confirm it.
-
- return true;
+static bool skill_parse_row_improvisedb(char* split[], int columns, int current)
+{// SkillID
+ int i = atoi(split[0]);
+ short j = atoi(split[1]);
+
+ if( !skill_get_index(i) || !skill_get_max(i) ) {
+ ShowError("skill_improvise_db: Invalid skill ID %d\n", i);
+ return false;
+ }
+ if ( !skill_get_inf(i) ) {
+ ShowError("skill_improvise_db: Passive skills cannot be casted (%d/%s)\n", i, skill_get_name(i));
+ return false;
+ }
+ if( j < 1 ) {
+ ShowError("skill_improvise_db: Chances have to be 1 or above! (%d/%s)\n", i, skill_get_name(i));
+ return false;
+ }
+ if( current >= MAX_SKILL_IMPROVISE_DB ) {
+ ShowError("skill_improvise_db: Maximum amount of entries reached (%d), increase MAX_SKILL_IMPROVISE_DB\n",MAX_SKILL_IMPROVISE_DB);
+ }
+ skill_improvise_db[current].skillid = i;
+ skill_improvise_db[current].per = j; // Still need confirm it.
+
+ return true;
}
-static bool skill_parse_row_magicmushroomdb(char *split[], int column, int current)
+static bool skill_parse_row_magicmushroomdb(char* split[], int column, int current)
{
- int i = atoi(split[0]);
+ int i = atoi(split[0]);
- if (!skill_get_index(i) || !skill_get_max(i)) {
- ShowError("magicmushroom_db: Invalid skill ID %d\n", i);
- return false;
- }
- if (!skill_get_inf(i)) {
- ShowError("magicmushroom_db: Passive skills cannot be casted (%d/%s)\n", i, skill_get_name(i));
- return false;
- }
+ if( !skill_get_index(i) || !skill_get_max(i) )
+ {
+ ShowError("magicmushroom_db: Invalid skill ID %d\n", i);
+ return false;
+ }
+ if ( !skill_get_inf(i) )
+ {
+ ShowError("magicmushroom_db: Passive skills cannot be casted (%d/%s)\n", i, skill_get_name(i));
+ return false;
+ }
- skill_magicmushroom_db[current].skillid = i;
+ skill_magicmushroom_db[current].skillid = i;
- return true;
+ return true;
}
-static bool skill_parse_row_reproducedb(char *split[], int column, int current)
-{
- int skillid = atoi(split[0]);
+static bool skill_parse_row_reproducedb(char* split[], int column, int current) {
+ int skillid = atoi(split[0]);
- skillid = skill_get_index(skillid);
- if (!skillid)
- return false;
+ skillid = skill_get_index(skillid);
+ if( !skillid )
+ return false;
- skill_reproduce_db[skillid] = true;
+ skill_reproduce_db[skillid] = true;
- return true;
+ return true;
}
-static bool skill_parse_row_abradb(char *split[], int columns, int current)
-{
- // SkillID,DummyName,RequiredHocusPocusLevel,Rate
- int i = atoi(split[0]);
- if (!skill_get_index(i) || !skill_get_max(i)) {
- ShowError("abra_db: Invalid skill ID %d\n", i);
- return false;
- }
- if (!skill_get_inf(i)) {
- ShowError("abra_db: Passive skills cannot be casted (%d/%s)\n", i, skill_get_name(i));
- return false;
- }
-
- skill_abra_db[current].skillid = i;
- skill_abra_db[current].req_lv = atoi(split[2]);
- skill_abra_db[current].per = atoi(split[3]);
-
- return true;
+static bool skill_parse_row_abradb(char* split[], int columns, int current)
+{// SkillID,DummyName,RequiredHocusPocusLevel,Rate
+ int i = atoi(split[0]);
+ if( !skill_get_index(i) || !skill_get_max(i) )
+ {
+ ShowError("abra_db: Invalid skill ID %d\n", i);
+ return false;
+ }
+ if ( !skill_get_inf(i) )
+ {
+ ShowError("abra_db: Passive skills cannot be casted (%d/%s)\n", i, skill_get_name(i));
+ return false;
+ }
+
+ skill_abra_db[current].skillid = i;
+ skill_abra_db[current].req_lv = atoi(split[2]);
+ skill_abra_db[current].per = atoi(split[3]);
+
+ return true;
}
-static bool skill_parse_row_changematerialdb(char *split[], int columns, int current)
-{
- // SkillID
- int i = atoi(split[0]);
- short j = atoi(split[1]);
- int x,y;
-
- for (x=0; x<MAX_SKILL_PRODUCE_DB; x++) {
- if (skill_produce_db[x].nameid == i)
- if (skill_produce_db[x].req_skill == GN_CHANGEMATERIAL)
- break;
- }
-
- if (x >= MAX_SKILL_PRODUCE_DB) {
- ShowError("changematerial_db: Not supported item ID(%d) for Change Material. \n", i);
- return false;
- }
-
- if (current >= MAX_SKILL_PRODUCE_DB) {
- ShowError("skill_changematerial_db: Maximum amount of entries reached (%d), increase MAX_SKILL_PRODUCE_DB\n",MAX_SKILL_PRODUCE_DB);
- }
-
- skill_changematerial_db[current].itemid = i;
- skill_changematerial_db[current].rate = j;
-
- for (x = 2, y = 0; x+1 < columns && split[x] && split[x+1] && y < 5; x += 2, y++) {
- skill_changematerial_db[current].qty[y] = atoi(split[x]);
- skill_changematerial_db[current].qty_rate[y] = atoi(split[x+1]);
- }
-
- return true;
+static bool skill_parse_row_changematerialdb(char* split[], int columns, int current)
+{// SkillID
+ int i = atoi(split[0]);
+ short j = atoi(split[1]);
+ int x,y;
+
+ for(x=0; x<MAX_SKILL_PRODUCE_DB; x++){
+ if( skill_produce_db[x].nameid == i )
+ if( skill_produce_db[x].req_skill == GN_CHANGEMATERIAL )
+ break;
+ }
+
+ if( x >= MAX_SKILL_PRODUCE_DB ){
+ ShowError("changematerial_db: Not supported item ID(%d) for Change Material. \n", i);
+ return false;
+ }
+
+ if( current >= MAX_SKILL_PRODUCE_DB ) {
+ ShowError("skill_changematerial_db: Maximum amount of entries reached (%d), increase MAX_SKILL_PRODUCE_DB\n",MAX_SKILL_PRODUCE_DB);
+ }
+
+ skill_changematerial_db[current].itemid = i;
+ skill_changematerial_db[current].rate = j;
+
+ for( x = 2, y = 0; x+1 < columns && split[x] && split[x+1] && y < 5; x += 2, y++ )
+ {
+ skill_changematerial_db[current].qty[y] = atoi(split[x]);
+ skill_changematerial_db[current].qty_rate[y] = atoi(split[x+1]);
+ }
+
+ return true;
}
/*===============================
@@ -18034,94 +17771,93 @@ static bool skill_parse_row_changematerialdb(char *split[], int columns, int cur
*------------------------------*/
static void skill_readdb(void)
{
- // init skill db structures
- db_clear(skilldb_name2id);
- memset(skill_db,0,sizeof(skill_db));
- memset(skill_produce_db,0,sizeof(skill_produce_db));
- memset(skill_arrow_db,0,sizeof(skill_arrow_db));
- memset(skill_abra_db,0,sizeof(skill_abra_db));
- memset(skill_spellbook_db,0,sizeof(skill_spellbook_db));
- memset(skill_magicmushroom_db,0,sizeof(skill_magicmushroom_db));
- memset(skill_reproduce_db,0,sizeof(skill_reproduce_db));
- memset(skill_changematerial_db,0,sizeof(skill_changematerial_db));
-
- // load skill databases
- safestrncpy(skill_db[0].name, "UNKNOWN_SKILL", sizeof(skill_db[0].name));
- safestrncpy(skill_db[0].desc, "Unknown Skill", sizeof(skill_db[0].desc));
-
- sv_readdb(db_path, DBPATH"skill_db.txt" , ',', 17, 17, MAX_SKILL_DB, skill_parse_row_skilldb);
- sv_readdb(db_path, DBPATH"skill_require_db.txt" , ',', 32, 32, MAX_SKILL_DB, skill_parse_row_requiredb);
+ // init skill db structures
+ db_clear(skilldb_name2id);
+ memset(skill_db,0,sizeof(skill_db));
+ memset(skill_produce_db,0,sizeof(skill_produce_db));
+ memset(skill_arrow_db,0,sizeof(skill_arrow_db));
+ memset(skill_abra_db,0,sizeof(skill_abra_db));
+ memset(skill_spellbook_db,0,sizeof(skill_spellbook_db));
+ memset(skill_magicmushroom_db,0,sizeof(skill_magicmushroom_db));
+ memset(skill_reproduce_db,0,sizeof(skill_reproduce_db));
+ memset(skill_changematerial_db,0,sizeof(skill_changematerial_db));
+
+ // load skill databases
+ safestrncpy(skill_db[0].name, "UNKNOWN_SKILL", sizeof(skill_db[0].name));
+ safestrncpy(skill_db[0].desc, "Unknown Skill", sizeof(skill_db[0].desc));
+
+ sv_readdb(db_path, DBPATH"skill_db.txt" , ',', 17, 17, MAX_SKILL_DB, skill_parse_row_skilldb);
+ sv_readdb(db_path, DBPATH"skill_require_db.txt" , ',', 32, 32, MAX_SKILL_DB, skill_parse_row_requiredb);
#ifdef RENEWAL_CAST
- sv_readdb(db_path, "re/skill_cast_db.txt" , ',', 8, 8, MAX_SKILL_DB, skill_parse_row_castdb);
+ sv_readdb(db_path, "re/skill_cast_db.txt" , ',', 8, 8, MAX_SKILL_DB, skill_parse_row_castdb);
#else
- sv_readdb(db_path, "pre-re/skill_cast_db.txt" , ',', 7, 7, MAX_SKILL_DB, skill_parse_row_castdb);
+ sv_readdb(db_path, "pre-re/skill_cast_db.txt" , ',', 7, 7, MAX_SKILL_DB, skill_parse_row_castdb);
#endif
- sv_readdb(db_path, DBPATH"skill_castnodex_db.txt", ',', 2, 3, MAX_SKILL_DB, skill_parse_row_castnodexdb);
- sv_readdb(db_path, DBPATH"skill_unit_db.txt" , ',', 8, 8, MAX_SKILL_DB, skill_parse_row_unitdb);
-
- sv_readdb(db_path, DBPATH"skill_nocast_db.txt" , ',', 2, 2, MAX_SKILL_DB, skill_parse_row_nocastdb);
-
- skill_init_unit_layout();
- sv_readdb(db_path, "produce_db.txt" , ',', 4, 4+2*MAX_PRODUCE_RESOURCE, MAX_SKILL_PRODUCE_DB, skill_parse_row_producedb);
- sv_readdb(db_path, "create_arrow_db.txt" , ',', 1+2, 1+2*MAX_ARROW_RESOURCE, MAX_SKILL_ARROW_DB, skill_parse_row_createarrowdb);
- sv_readdb(db_path, "abra_db.txt" , ',', 4, 4, MAX_SKILL_ABRA_DB, skill_parse_row_abradb);
- //Warlock
- sv_readdb(db_path, "spellbook_db.txt" , ',', 3, 3, MAX_SKILL_SPELLBOOK_DB, skill_parse_row_spellbookdb);
- //Guillotine Cross
- sv_readdb(db_path, "magicmushroom_db.txt" , ',', 1, 1, MAX_SKILL_MAGICMUSHROOM_DB, skill_parse_row_magicmushroomdb);
- sv_readdb(db_path, "skill_reproduce_db.txt", ',', 1, 1, MAX_SKILL_DB, skill_parse_row_reproducedb);
- sv_readdb(db_path, "skill_improvise_db.txt" , ',', 2, 2, MAX_SKILL_IMPROVISE_DB, skill_parse_row_improvisedb);
- sv_readdb(db_path, "skill_changematerial_db.txt" , ',', 4, 4+2*5, MAX_SKILL_PRODUCE_DB, skill_parse_row_changematerialdb);
+ sv_readdb(db_path, DBPATH"skill_castnodex_db.txt", ',', 2, 3, MAX_SKILL_DB, skill_parse_row_castnodexdb);
+ sv_readdb(db_path, DBPATH"skill_unit_db.txt" , ',', 8, 8, MAX_SKILL_DB, skill_parse_row_unitdb);
+
+ sv_readdb(db_path, DBPATH"skill_nocast_db.txt" , ',', 2, 2, MAX_SKILL_DB, skill_parse_row_nocastdb);
+
+ skill_init_unit_layout();
+ sv_readdb(db_path, "produce_db.txt" , ',', 4, 4+2*MAX_PRODUCE_RESOURCE, MAX_SKILL_PRODUCE_DB, skill_parse_row_producedb);
+ sv_readdb(db_path, "create_arrow_db.txt" , ',', 1+2, 1+2*MAX_ARROW_RESOURCE, MAX_SKILL_ARROW_DB, skill_parse_row_createarrowdb);
+ sv_readdb(db_path, "abra_db.txt" , ',', 4, 4, MAX_SKILL_ABRA_DB, skill_parse_row_abradb);
+ //Warlock
+ sv_readdb(db_path, "spellbook_db.txt" , ',', 3, 3, MAX_SKILL_SPELLBOOK_DB, skill_parse_row_spellbookdb);
+ //Guillotine Cross
+ sv_readdb(db_path, "magicmushroom_db.txt" , ',', 1, 1, MAX_SKILL_MAGICMUSHROOM_DB, skill_parse_row_magicmushroomdb);
+ sv_readdb(db_path, "skill_reproduce_db.txt", ',', 1, 1, MAX_SKILL_DB, skill_parse_row_reproducedb);
+ sv_readdb(db_path, "skill_improvise_db.txt" , ',', 2, 2, MAX_SKILL_IMPROVISE_DB, skill_parse_row_improvisedb);
+ sv_readdb(db_path, "skill_changematerial_db.txt" , ',', 4, 4+2*5, MAX_SKILL_PRODUCE_DB, skill_parse_row_changematerialdb);
}
-void skill_reload(void)
-{
- struct s_mapiterator *iter;
- struct map_session_data *sd;
- skill_readdb();
- /* lets update all players skill tree : so that if any skill modes were changed they're properly updated */
- iter = mapit_getallusers();
- for (sd = (TBL_PC *)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC *)mapit_next(iter))
- clif_skillinfoblock(sd);
- mapit_free(iter);
+void skill_reload (void) {
+ struct s_mapiterator *iter;
+ struct map_session_data *sd;
+ skill_readdb();
+ /* lets update all players skill tree : so that if any skill modes were changed they're properly updated */
+ iter = mapit_getallusers();
+ for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
+ clif_skillinfoblock(sd);
+ mapit_free(iter);
}
/*==========================================
*
*------------------------------------------*/
-int do_init_skill(void)
+int do_init_skill (void)
{
- skilldb_name2id = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, 0);
- skill_readdb();
+ skilldb_name2id = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, 0);
+ skill_readdb();
- group_db = idb_alloc(DB_OPT_BASE);
- skillunit_db = idb_alloc(DB_OPT_BASE);
- skillcd_db = idb_alloc(DB_OPT_RELEASE_DATA);
- skillusave_db = idb_alloc(DB_OPT_RELEASE_DATA);
- skill_unit_ers = ers_new(sizeof(struct skill_unit_group),"skill.c::skill_unit_ers",ERS_OPT_NONE);
- skill_timer_ers = ers_new(sizeof(struct skill_timerskill),"skill.c::skill_timer_ers",ERS_OPT_NONE);
+ group_db = idb_alloc(DB_OPT_BASE);
+ skillunit_db = idb_alloc(DB_OPT_BASE);
+ skillcd_db = idb_alloc(DB_OPT_RELEASE_DATA);
+ skillusave_db = idb_alloc(DB_OPT_RELEASE_DATA);
+ skill_unit_ers = ers_new(sizeof(struct skill_unit_group),"skill.c::skill_unit_ers",ERS_OPT_NONE);
+ skill_timer_ers = ers_new(sizeof(struct skill_timerskill),"skill.c::skill_timer_ers",ERS_OPT_NONE);
- 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_blockpc_end, "skill_blockpc_end");
+ 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_blockpc_end, "skill_blockpc_end");
- add_timer_interval(gettick()+SKILLUNITTIMER_INTERVAL,skill_unit_timer,0,0,SKILLUNITTIMER_INTERVAL);
+ add_timer_interval(gettick()+SKILLUNITTIMER_INTERVAL,skill_unit_timer,0,0,SKILLUNITTIMER_INTERVAL);
- return 0;
+ return 0;
}
int do_final_skill(void)
{
- db_destroy(skilldb_name2id);
- db_destroy(group_db);
- db_destroy(skillunit_db);
- db_destroy(skillcd_db);
- db_destroy(skillusave_db);
- ers_destroy(skill_unit_ers);
- ers_destroy(skill_timer_ers);
- return 0;
+ db_destroy(skilldb_name2id);
+ db_destroy(group_db);
+ db_destroy(skillunit_db);
+ db_destroy(skillcd_db);
+ db_destroy(skillusave_db);
+ ers_destroy(skill_unit_ers);
+ ers_destroy(skill_timer_ers);
+ return 0;
}
diff --git a/src/map/skill.h b/src/map/skill.h
index 90ebfc8be..265f2c7aa 100644
--- a/src/map/skill.h
+++ b/src/map/skill.h
@@ -12,210 +12,214 @@ struct skill_unit;
struct skill_unit_group;
struct status_change_entry;
-#define MAX_SKILL_DB MAX_SKILL
-#define MAX_SKILL_PRODUCE_DB 270
-#define MAX_PRODUCE_RESOURCE 12
-#define MAX_SKILL_ARROW_DB 150
-#define MAX_ARROW_RESOURCE 5
-#define MAX_SKILL_ABRA_DB 350
+#define MAX_SKILL_DB MAX_SKILL
+#define MAX_SKILL_PRODUCE_DB 270
+#define MAX_PRODUCE_RESOURCE 12
+#define MAX_SKILL_ARROW_DB 150
+#define MAX_ARROW_RESOURCE 5
+#define MAX_SKILL_ABRA_DB 350
#define MAX_SKILL_IMPROVISE_DB 50
#define MAX_SKILL_LEVEL 100
//Constants to identify the skill's inf value:
-enum e_skill_inf {
- INF_ATTACK_SKILL = 0x01,
- INF_GROUND_SKILL = 0x02,
- INF_SELF_SKILL = 0x04, // Skills casted on self where target is automatically chosen
- // 0x08 not assigned
- INF_SUPPORT_SKILL = 0x10,
- INF_TARGET_TRAP = 0x20,
+enum e_skill_inf
+{
+ INF_ATTACK_SKILL = 0x01,
+ INF_GROUND_SKILL = 0x02,
+ INF_SELF_SKILL = 0x04, // Skills casted on self where target is automatically chosen
+ // 0x08 not assigned
+ INF_SUPPORT_SKILL = 0x10,
+ INF_TARGET_TRAP = 0x20,
};
//Constants to identify a skill's nk value (damage properties)
//The NK value applies only to non INF_GROUND_SKILL skills
//when determining skill castend function to invoke.
-enum e_skill_nk {
- NK_NO_DAMAGE = 0x01,
- NK_SPLASH = 0x02|0x04, // 0x4 = splash & split
- NK_SPLASHSPLIT = 0x04,
- NK_NO_CARDFIX_ATK = 0x08,
- NK_NO_ELEFIX = 0x10,
- NK_IGNORE_DEF = 0x20,
- NK_IGNORE_FLEE = 0x40,
- NK_NO_CARDFIX_DEF = 0x80,
+enum e_skill_nk
+{
+ NK_NO_DAMAGE = 0x01,
+ NK_SPLASH = 0x02|0x04, // 0x4 = splash & split
+ NK_SPLASHSPLIT = 0x04,
+ NK_NO_CARDFIX_ATK = 0x08,
+ NK_NO_ELEFIX = 0x10,
+ NK_IGNORE_DEF = 0x20,
+ NK_IGNORE_FLEE = 0x40,
+ NK_NO_CARDFIX_DEF = 0x80,
};
//A skill with 3 would be no damage + splash: area of effect.
//Constants to identify a skill's inf2 value.
-enum e_skill_inf2 {
- INF2_QUEST_SKILL = 0x0001,
- INF2_NPC_SKILL = 0x0002, //NPC skills are those that players can't have in their skill tree.
- INF2_WEDDING_SKILL = 0x0004,
- INF2_SPIRIT_SKILL = 0x0008,
- INF2_GUILD_SKILL = 0x0010,
- INF2_SONG_DANCE = 0x0020,
- INF2_ENSEMBLE_SKILL = 0x0040,
- INF2_TRAP = 0x0080,
- INF2_TARGET_SELF = 0x0100, //Refers to ground placed skills that will target the caster as well (like Grandcross)
- INF2_NO_TARGET_SELF = 0x0200,
- INF2_PARTY_ONLY = 0x0400,
- INF2_GUILD_ONLY = 0x0800,
- INF2_NO_ENEMY = 0x1000,
- INF2_NOLP = 0x2000, // Spells that can ignore Land Protector
- INF2_CHORUS_SKILL = 0x4000, // Chorus skill
+enum e_skill_inf2
+{
+ INF2_QUEST_SKILL = 0x0001,
+ INF2_NPC_SKILL = 0x0002, //NPC skills are those that players can't have in their skill tree.
+ INF2_WEDDING_SKILL = 0x0004,
+ INF2_SPIRIT_SKILL = 0x0008,
+ INF2_GUILD_SKILL = 0x0010,
+ INF2_SONG_DANCE = 0x0020,
+ INF2_ENSEMBLE_SKILL = 0x0040,
+ INF2_TRAP = 0x0080,
+ INF2_TARGET_SELF = 0x0100, //Refers to ground placed skills that will target the caster as well (like Grandcross)
+ INF2_NO_TARGET_SELF = 0x0200,
+ INF2_PARTY_ONLY = 0x0400,
+ INF2_GUILD_ONLY = 0x0800,
+ INF2_NO_ENEMY = 0x1000,
+ INF2_NOLP = 0x2000, // Spells that can ignore Land Protector
+ INF2_CHORUS_SKILL = 0x4000, // Chorus skill
};
//Walk intervals at which chase-skills are attempted to be triggered.
#define WALK_SKILL_INTERVAL 5
// Flags passed to skill_attack/skill_area_sub
-enum e_skill_display {
- SD_LEVEL = 0x1000, // skill_attack will send -1 instead of skill level (affects display of some skills)
- SD_ANIMATION = 0x2000, // skill_attack will use '5' instead of the skill's 'type' (this makes skills show an animation)
- SD_SPLASH = 0x4000, // skill_area_sub will count targets in skill_area_temp[2]
- SD_PREAMBLE = 0x8000, // skill_area_sub will transmit a 'magic' damage packet (-30000 dmg) for the first target selected
+enum e_skill_display
+{
+ SD_LEVEL = 0x1000, // skill_attack will send -1 instead of skill level (affects display of some skills)
+ SD_ANIMATION = 0x2000, // skill_attack will use '5' instead of the skill's 'type' (this makes skills show an animation)
+ SD_SPLASH = 0x4000, // skill_area_sub will count targets in skill_area_temp[2]
+ SD_PREAMBLE = 0x8000, // skill_area_sub will transmit a 'magic' damage packet (-30000 dmg) for the first target selected
};
-#define MAX_SKILL_ITEM_REQUIRE 10
+#define MAX_SKILL_ITEM_REQUIRE 10
struct skill_condition {
- int weapon,ammo,ammo_qty,hp,sp,zeny,spiritball,mhp,state;
- int itemid[MAX_SKILL_ITEM_REQUIRE],amount[MAX_SKILL_ITEM_REQUIRE];
+ int weapon,ammo,ammo_qty,hp,sp,zeny,spiritball,mhp,state;
+ int itemid[MAX_SKILL_ITEM_REQUIRE],amount[MAX_SKILL_ITEM_REQUIRE];
};
// Database skills
struct s_skill_db {
- char name[NAME_LENGTH];
- char desc[40];
- int range[MAX_SKILL_LEVEL],hit,inf,element[MAX_SKILL_LEVEL],nk,splash[MAX_SKILL_LEVEL],max;
- int num[MAX_SKILL_LEVEL];
- int cast[MAX_SKILL_LEVEL],walkdelay[MAX_SKILL_LEVEL],delay[MAX_SKILL_LEVEL];
+ char name[NAME_LENGTH];
+ char desc[40];
+ int range[MAX_SKILL_LEVEL],hit,inf,element[MAX_SKILL_LEVEL],nk,splash[MAX_SKILL_LEVEL],max;
+ int num[MAX_SKILL_LEVEL];
+ int cast[MAX_SKILL_LEVEL],walkdelay[MAX_SKILL_LEVEL],delay[MAX_SKILL_LEVEL];
#ifdef RENEWAL_CAST
- int fixed_cast[MAX_SKILL_LEVEL];
+ int fixed_cast[MAX_SKILL_LEVEL];
#endif
- int upkeep_time[MAX_SKILL_LEVEL],upkeep_time2[MAX_SKILL_LEVEL],cooldown[MAX_SKILL_LEVEL];
- int castcancel,cast_def_rate;
- int inf2,maxcount[MAX_SKILL_LEVEL],skill_type;
- int blewcount[MAX_SKILL_LEVEL];
- int hp[MAX_SKILL_LEVEL],sp[MAX_SKILL_LEVEL],mhp[MAX_SKILL_LEVEL],hp_rate[MAX_SKILL_LEVEL],sp_rate[MAX_SKILL_LEVEL],zeny[MAX_SKILL_LEVEL];
- int weapon,ammo,ammo_qty[MAX_SKILL_LEVEL],state,spiritball[MAX_SKILL_LEVEL];
- int itemid[MAX_SKILL_ITEM_REQUIRE],amount[MAX_SKILL_ITEM_REQUIRE];
- int castnodex[MAX_SKILL_LEVEL], delaynodex[MAX_SKILL_LEVEL];
- int nocast;
- int unit_id[2];
- int unit_layout_type[MAX_SKILL_LEVEL];
- int unit_range[MAX_SKILL_LEVEL];
- int unit_interval;
- int unit_target;
- int unit_flag;
+ int upkeep_time[MAX_SKILL_LEVEL],upkeep_time2[MAX_SKILL_LEVEL],cooldown[MAX_SKILL_LEVEL];
+ int castcancel,cast_def_rate;
+ int inf2,maxcount[MAX_SKILL_LEVEL],skill_type;
+ int blewcount[MAX_SKILL_LEVEL];
+ int hp[MAX_SKILL_LEVEL],sp[MAX_SKILL_LEVEL],mhp[MAX_SKILL_LEVEL],hp_rate[MAX_SKILL_LEVEL],sp_rate[MAX_SKILL_LEVEL],zeny[MAX_SKILL_LEVEL];
+ int weapon,ammo,ammo_qty[MAX_SKILL_LEVEL],state,spiritball[MAX_SKILL_LEVEL];
+ int itemid[MAX_SKILL_ITEM_REQUIRE],amount[MAX_SKILL_ITEM_REQUIRE];
+ int castnodex[MAX_SKILL_LEVEL], delaynodex[MAX_SKILL_LEVEL];
+ int nocast;
+ int unit_id[2];
+ int unit_layout_type[MAX_SKILL_LEVEL];
+ int unit_range[MAX_SKILL_LEVEL];
+ int unit_interval;
+ int unit_target;
+ int unit_flag;
};
extern struct s_skill_db skill_db[MAX_SKILL_DB];
-#define MAX_SKILL_UNIT_LAYOUT 50
-#define MAX_SQUARE_LAYOUT 5 // 11*11 Placement of a maximum unit
+#define MAX_SKILL_UNIT_LAYOUT 50
+#define MAX_SQUARE_LAYOUT 5 // 11*11 Placement of a maximum unit
#define MAX_SKILL_UNIT_COUNT ((MAX_SQUARE_LAYOUT*2+1)*(MAX_SQUARE_LAYOUT*2+1))
struct s_skill_unit_layout {
- int count;
- int dx[MAX_SKILL_UNIT_COUNT];
- int dy[MAX_SKILL_UNIT_COUNT];
+ int count;
+ int dx[MAX_SKILL_UNIT_COUNT];
+ int dy[MAX_SKILL_UNIT_COUNT];
};
#define MAX_SKILLTIMERSKILL 15
struct skill_timerskill {
- int timer;
- int src_id;
- int target_id;
- int map;
- short x,y;
- short skill_id,skill_lv;
- int type; // a BF_ type (NOTE: some places use this as general-purpose storage...)
- int flag;
+ int timer;
+ int src_id;
+ int target_id;
+ int map;
+ short x,y;
+ short skill_id,skill_lv;
+ int type; // a BF_ type (NOTE: some places use this as general-purpose storage...)
+ int flag;
};
#define MAX_SKILLUNITGROUP 25
struct skill_unit_group {
- int src_id;
- int party_id;
- int guild_id;
- int bg_id;
- int map;
- int target_flag; //Holds BCT_* flag for battle_check_target
- int bl_flag; //Holds BL_* flag for map_foreachin* functions
- unsigned int tick;
- int limit,interval;
-
- short skill_id,skill_lv;
- int val1,val2,val3;
- char *valstr;
- int unit_id;
- int group_id;
- int unit_count,alive_count;
- int item_id; //store item used.
- struct skill_unit *unit;
- struct {
- unsigned ammo_consume : 1;
- unsigned song_dance : 2; //0x1 Song/Dance, 0x2 Ensemble
- unsigned guildaura : 1;
- } state;
+ int src_id;
+ int party_id;
+ int guild_id;
+ int bg_id;
+ int map;
+ int target_flag; //Holds BCT_* flag for battle_check_target
+ int bl_flag; //Holds BL_* flag for map_foreachin* functions
+ unsigned int tick;
+ int limit,interval;
+
+ short skill_id,skill_lv;
+ int val1,val2,val3;
+ char *valstr;
+ int unit_id;
+ int group_id;
+ int unit_count,alive_count;
+ int item_id; //store item used.
+ struct skill_unit *unit;
+ struct {
+ unsigned ammo_consume : 1;
+ unsigned song_dance : 2; //0x1 Song/Dance, 0x2 Ensemble
+ unsigned guildaura : 1;
+ } state;
};
struct skill_unit {
- struct block_list bl;
+ struct block_list bl;
- struct skill_unit_group *group;
+ struct skill_unit_group *group;
- int limit;
- int val1,val2;
- short alive,range;
+ int limit;
+ int val1,val2;
+ short alive,range;
};
#define MAX_SKILLUNITGROUPTICKSET 25
struct skill_unit_group_tickset {
- unsigned int tick;
- int id;
+ unsigned int tick;
+ int id;
};
enum {
- UF_DEFNOTENEMY = 0x0001, // If 'defunit_not_enemy' is set, the target is changed to 'friend'
- UF_NOREITERATION = 0x0002, // Spell cannot be stacked
- UF_NOFOOTSET = 0x0004, // Spell cannot be cast near/on targets
- UF_NOOVERLAP = 0x0008, // Spell effects do not overlap
- UF_PATHCHECK = 0x0010, // Only cells with a shootable path will be placed
- UF_NOPC = 0x0020, // May not target players
- UF_NOMOB = 0x0040, // May not target mobs
- UF_SKILL = 0x0080, // May target skills
- UF_DANCE = 0x0100, // Dance
- UF_ENSEMBLE = 0x0200, // Duet
- UF_SONG = 0x0400, // Song
- UF_DUALMODE = 0x0800, // Spells should trigger both ontimer and onplace/onout/onleft effects.
+ UF_DEFNOTENEMY = 0x0001, // If 'defunit_not_enemy' is set, the target is changed to 'friend'
+ UF_NOREITERATION = 0x0002, // Spell cannot be stacked
+ UF_NOFOOTSET = 0x0004, // Spell cannot be cast near/on targets
+ UF_NOOVERLAP = 0x0008, // Spell effects do not overlap
+ UF_PATHCHECK = 0x0010, // Only cells with a shootable path will be placed
+ UF_NOPC = 0x0020, // May not target players
+ UF_NOMOB = 0x0040, // May not target mobs
+ UF_SKILL = 0x0080, // May target skills
+ UF_DANCE = 0x0100, // Dance
+ UF_ENSEMBLE = 0x0200, // Duet
+ UF_SONG = 0x0400, // Song
+ UF_DUALMODE = 0x0800, // Spells should trigger both ontimer and onplace/onout/onleft effects.
UF_RANGEDSINGLEUNIT = 0x2000 // hack for ranged layout, only display center
};
// Create Database item
struct s_skill_produce_db {
- int nameid, trigger;
- int req_skill,req_skill_lv,itemlv;
- int mat_id[MAX_PRODUCE_RESOURCE],mat_amount[MAX_PRODUCE_RESOURCE];
+ int nameid, trigger;
+ int req_skill,req_skill_lv,itemlv;
+ int mat_id[MAX_PRODUCE_RESOURCE],mat_amount[MAX_PRODUCE_RESOURCE];
};
extern struct s_skill_produce_db skill_produce_db[MAX_SKILL_PRODUCE_DB];
// Creating database arrow
struct s_skill_arrow_db {
- int nameid, trigger;
- int cre_id[MAX_ARROW_RESOURCE],cre_amount[MAX_ARROW_RESOURCE];
+ int nameid, trigger;
+ int cre_id[MAX_ARROW_RESOURCE],cre_amount[MAX_ARROW_RESOURCE];
};
extern struct s_skill_arrow_db skill_arrow_db[MAX_SKILL_ARROW_DB];
// Abracadabra database
struct s_skill_abra_db {
- int skillid;
- int req_lv;
- int per;
+ int skillid;
+ int req_lv;
+ int per;
};
extern struct s_skill_abra_db skill_abra_db[MAX_SKILL_ABRA_DB];
@@ -231,67 +235,67 @@ int skill_get_casttype(int id); //[Skotlex]
// Accessor to the skills database
//
-int skill_get_index(int id);
-int skill_get_type(int id);
-int skill_get_hit(int id);
-int skill_get_inf(int id);
-int skill_get_ele(int id , int lv);
-int skill_get_nk(int id);
-int skill_get_max(int id);
-int skill_get_range(int id , int lv);
-int skill_get_range2(struct block_list *bl, int id, int lv);
-int skill_get_splash(int id , int lv);
-int skill_get_hp(int id ,int lv);
-int skill_get_mhp(int id ,int lv);
-int skill_get_sp(int id ,int lv);
-int skill_get_state(int id);
-int skill_get_zeny(int id ,int lv);
-int skill_get_num(int id ,int lv);
-int skill_get_cast(int id ,int lv);
-int skill_get_delay(int id ,int lv);
-int skill_get_walkdelay(int id ,int lv);
-int skill_get_time(int id ,int lv);
-int skill_get_time2(int id ,int lv);
-int skill_get_castnodex(int id ,int lv);
-int skill_get_castdef(int id);
-int skill_get_weapontype(int id);
-int skill_get_ammotype(int id);
-int skill_get_ammo_qty(int id, int lv);
-int skill_get_nocast(int id);
-int skill_get_unit_id(int id,int flag);
-int skill_get_inf2(int id);
-int skill_get_castcancel(int id);
-int skill_get_maxcount(int id ,int lv);
-int skill_get_blewcount(int id ,int lv);
-int skill_get_unit_flag(int id);
-int skill_get_unit_target(int id);
-int skill_tree_get_max(int id, int b_class); // Celest
-const char *skill_get_name(int id); // [Skotlex]
-const char *skill_get_desc(int id); // [Skotlex]
-
-int skill_name2id(const char *name);
+int skill_get_index( int id );
+int skill_get_type( int id );
+int skill_get_hit( int id );
+int skill_get_inf( int id );
+int skill_get_ele( int id , int lv );
+int skill_get_nk( int id );
+int skill_get_max( int id );
+int skill_get_range( int id , int lv );
+int skill_get_range2(struct block_list *bl, int id, int lv);
+int skill_get_splash( int id , int lv );
+int skill_get_hp( int id ,int lv );
+int skill_get_mhp( int id ,int lv );
+int skill_get_sp( int id ,int lv );
+int skill_get_state(int id);
+int skill_get_zeny( int id ,int lv );
+int skill_get_num( int id ,int lv );
+int skill_get_cast( int id ,int lv );
+int skill_get_delay( int id ,int lv );
+int skill_get_walkdelay( int id ,int lv );
+int skill_get_time( int id ,int lv );
+int skill_get_time2( int id ,int lv );
+int skill_get_castnodex( int id ,int lv );
+int skill_get_castdef( int id );
+int skill_get_weapontype( int id );
+int skill_get_ammotype( int id );
+int skill_get_ammo_qty( int id, int lv );
+int skill_get_nocast( int id );
+int skill_get_unit_id(int id,int flag);
+int skill_get_inf2( int id );
+int skill_get_castcancel( int id );
+int skill_get_maxcount( int id ,int lv );
+int skill_get_blewcount( int id ,int lv );
+int skill_get_unit_flag( int id );
+int skill_get_unit_target( int id );
+int skill_tree_get_max( int id, int b_class ); // Celest
+const char* skill_get_name( int id ); // [Skotlex]
+const char* skill_get_desc( int id ); // [Skotlex]
+
+int skill_name2id(const char* name);
int skill_isammotype(struct map_session_data *sd, int skill);
int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data);
int skill_castend_pos(int tid, unsigned int tick, int id, intptr_t data);
-int skill_castend_map(struct map_session_data *sd,short skill_num, const char *map);
+int skill_castend_map( struct map_session_data *sd,short skill_num, const char *map);
int skill_cleartimerskill(struct block_list *src);
int skill_addtimerskill(struct block_list *src,unsigned int tick,int target,int x,int y,int skill_id,int skill_lv,int type,int flag);
// Results? Added
-int skill_additional_effect(struct block_list *src, struct block_list *bl,int skillid,int skilllv,int attack_type,int dmg_lv,unsigned int tick);
-int skill_counter_additional_effect(struct block_list *src, struct block_list *bl,int skillid,int skilllv,int attack_type,unsigned int tick);
-int skill_blown(struct block_list *src, struct block_list *target, int count, int direction, int flag);
+int skill_additional_effect( struct block_list* src, struct block_list *bl,int skillid,int skilllv,int attack_type,int dmg_lv,unsigned int tick);
+int skill_counter_additional_effect( struct block_list* src, struct block_list *bl,int skillid,int skilllv,int attack_type,unsigned int tick);
+int skill_blown(struct block_list* src, struct block_list* target, int count, int direction, int flag);
int skill_break_equip(struct block_list *bl, unsigned short where, int rate, int flag);
int skill_strip_equip(struct block_list *bl, unsigned short where, int rate, int lv, int time);
// Skills unit
-struct skill_unit_group *skill_id2group(int group_id);
-struct skill_unit_group *skill_unitsetting(struct block_list *src, short skillid, short skilllv, short x, short y, int flag);
-struct skill_unit *skill_initunit(struct skill_unit_group *group, int idx, int x, int y, int val1, int val2);
+struct skill_unit_group* skill_id2group(int group_id);
+struct skill_unit_group *skill_unitsetting(struct block_list* src, short skillid, short skilllv, short x, short y, int flag);
+struct skill_unit *skill_initunit (struct skill_unit_group *group, int idx, int x, int y, int val1, int val2);
int skill_delunit(struct skill_unit *unit);
-struct skill_unit_group *skill_initunitgroup(struct block_list *src, int count, short skillid, short skilllv, int unit_id, int limit, int interval);
-int skill_delunitgroup_(struct skill_unit_group *group, const char *file, int line, const char *func);
+struct skill_unit_group *skill_initunitgroup(struct block_list* src, int count, short skillid, short skilllv, int unit_id, int limit, int interval);
+int skill_delunitgroup_(struct skill_unit_group *group, const char* file, int line, const char* func);
#define skill_delunitgroup(group) skill_delunitgroup_(group,__FILE__,__LINE__,__func__)
int skill_clear_unitgroup(struct block_list *src);
int skill_clear_group(struct block_list *bl, int flag);
@@ -299,12 +303,12 @@ void ext_skill_unit_onplace(struct skill_unit *src, struct block_list *bl, unsig
int skill_unit_ondamaged(struct skill_unit *src,struct block_list *bl,int damage,unsigned int tick);
-int skill_castfix(struct block_list *bl, int skill_id, int skill_lv);
-int skill_castfix_sc(struct block_list *bl, int time);
+int skill_castfix( struct block_list *bl, int skill_id, int skill_lv);
+int skill_castfix_sc( struct block_list *bl, int time);
#ifdef RENEWAL_CAST
-int skill_vfcastfix(struct block_list *bl, double time, int skill_id, int skill_lv);
+int skill_vfcastfix( struct block_list *bl, double time, int skill_id, int skill_lv);
#endif
-int skill_delayfix(struct block_list *bl, int skill_id, int skill_lv);
+int skill_delayfix( struct block_list *bl, int skill_id, int skill_lv);
// Skill conditions check and remove [Inkfish]
int skill_check_condition_castbegin(struct map_session_data *sd, short skill, short lv);
@@ -312,23 +316,23 @@ int skill_check_condition_castend(struct map_session_data *sd, short skill, shor
int skill_consume_requirement(struct map_session_data *sd, short skill, short lv, short type);
struct skill_condition skill_get_requirement(struct map_session_data *sd, short skill, short lv);
-int skill_check_pc_partner(struct map_session_data *sd, short skill_id, short *skill_lv, int range, int cast_flag);
-// -- moonsoul (added skill_check_unit_cell)
+int skill_check_pc_partner(struct map_session_data *sd, short skill_id, short* skill_lv, int range, int cast_flag);
+// -- 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_out_all( 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);
+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);
+struct skill_unit_group *skill_check_dancing( struct block_list *src );
// Guild skills [celest]
-int skill_guildaura_sub(struct map_session_data *sd, int id, int strvit, int agidex);
+int skill_guildaura_sub (struct map_session_data* sd, int id, int strvit, int agidex);
// Chant canceled
int skill_castcancel(struct block_list *bl,int type);
-int skill_sit(struct map_session_data *sd, int type);
-void skill_brandishspear(struct block_list *src, struct block_list *bl, int skillid, int skilllv, unsigned int tick, int flag);
+int skill_sit (struct map_session_data *sd, int type);
+void skill_brandishspear(struct block_list* src, struct block_list* bl, int skillid, int skilllv, unsigned int tick, int flag);
void skill_repairweapon(struct map_session_data *sd, int idx);
void skill_identify(struct map_session_data *sd,int idx);
void skill_weaponrefine(struct map_session_data *sd,int idx); // [Celest]
@@ -347,1479 +351,1479 @@ int skillnotok_mercenary(int skillid, struct mercenary_data *md);
int skill_chastle_mob_changetarget(struct block_list *bl,va_list ap);
// Item creation
-int skill_can_produce_mix(struct map_session_data *sd, int nameid, int trigger, int qty);
-int skill_produce_mix(struct map_session_data *sd, int skill_id, int nameid, int slot1, int slot2, int slot3, int qty);
+int skill_can_produce_mix( struct map_session_data *sd, int nameid, int trigger, int qty);
+int skill_produce_mix( struct map_session_data *sd, int skill_id, int nameid, int slot1, int slot2, int slot3, int qty );
-int skill_arrow_create(struct map_session_data *sd,int nameid);
+int skill_arrow_create( struct map_session_data *sd,int nameid);
// skills for the mob
-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_damage_id(struct block_list *src, struct block_list *bl,int skillid,int skilllv,unsigned int tick,int flag);
-int skill_castend_pos2(struct block_list *src, int x,int y,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 );
+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_pos2( struct block_list *src, int x,int y,int skillid,int skilllv,unsigned int tick,int flag);
-int skill_blockpc_start_(struct map_session_data *, int, int, bool);
-int skill_blockhomun_start(struct homun_data *,int,int);
-int skill_blockmerc_start(struct mercenary_data *,int,int);
+int skill_blockpc_start_(struct map_session_data*, int, int, bool);
+int skill_blockhomun_start (struct homun_data*,int,int);
+int skill_blockmerc_start (struct mercenary_data*,int,int);
#define skill_blockpc_start(sd, skillid, tick) skill_blockpc_start_( sd, skillid, tick, false )
// (Epoque:) To-do: replace this macro with some sort of skill tree check (rather than hard-coded skill names)
#define skill_ischangesex(id) ( \
- ((id) >= BD_ADAPTATION && (id) <= DC_SERVICEFORYOU) || ((id) >= CG_ARROWVULCAN && (id) <= CG_MARIONETTE) || \
- ((id) >= CG_LONGINGFREEDOM && (id) <= CG_TAROTCARD) || ((id) >= WA_SWING_DANCE && (id) <= WM_UNLIMITED_HUMMING_VOICE))
+ ((id) >= BD_ADAPTATION && (id) <= DC_SERVICEFORYOU) || ((id) >= CG_ARROWVULCAN && (id) <= CG_MARIONETTE) || \
+ ((id) >= CG_LONGINGFREEDOM && (id) <= CG_TAROTCARD) || ((id) >= WA_SWING_DANCE && (id) <= WM_UNLIMITED_HUMMING_VOICE))
// Skill action, (return dmg,heal)
-int skill_attack(int attack_type, struct block_list *src, struct block_list *dsrc,struct block_list *bl,int skillid,int skilllv,unsigned int tick,int flag);
+int skill_attack( int attack_type, struct block_list* src, struct block_list *dsrc,struct block_list *bl,int skillid,int skilllv,unsigned int tick,int flag );
void skill_reload(void);
enum {
- ST_NONE,
- ST_HIDING,
- ST_CLOAKING,
- ST_HIDDEN,
- ST_RIDING,
- ST_FALCON,
- ST_CART,
- ST_SHIELD,
- ST_SIGHT,
- ST_EXPLOSIONSPIRITS,
- ST_CARTBOOST,
- ST_RECOV_WEIGHT_RATE,
- ST_MOVE_ENABLE,
- ST_WATER,
- /**
- * 3rd States
- **/
- ST_RIDINGDRAGON,
- ST_WUG,
- ST_RIDINGWUG,
- ST_MADO,
- ST_ELEMENTALSPIRIT,
- ST_POISONINGWEAPON,
- ST_ROLLINGCUTTER,
+ ST_NONE,
+ ST_HIDING,
+ ST_CLOAKING,
+ ST_HIDDEN,
+ ST_RIDING,
+ ST_FALCON,
+ ST_CART,
+ ST_SHIELD,
+ ST_SIGHT,
+ ST_EXPLOSIONSPIRITS,
+ ST_CARTBOOST,
+ ST_RECOV_WEIGHT_RATE,
+ ST_MOVE_ENABLE,
+ ST_WATER,
+ /**
+ * 3rd States
+ **/
+ ST_RIDINGDRAGON,
+ ST_WUG,
+ ST_RIDINGWUG,
+ ST_MADO,
+ ST_ELEMENTALSPIRIT,
+ ST_POISONINGWEAPON,
+ ST_ROLLINGCUTTER,
};
enum e_skill {
- NV_BASIC = 1,
-
- SM_SWORD,
- SM_TWOHAND,
- SM_RECOVERY,
- SM_BASH,
- SM_PROVOKE,
- SM_MAGNUM,
- SM_ENDURE,
-
- MG_SRECOVERY,
- MG_SIGHT,
- MG_NAPALMBEAT,
- MG_SAFETYWALL,
- MG_SOULSTRIKE,
- MG_COLDBOLT,
- MG_FROSTDIVER,
- MG_STONECURSE,
- MG_FIREBALL,
- MG_FIREWALL,
- MG_FIREBOLT,
- MG_LIGHTNINGBOLT,
- MG_THUNDERSTORM,
-
- AL_DP,
- AL_DEMONBANE,
- AL_RUWACH,
- AL_PNEUMA,
- AL_TELEPORT,
- AL_WARP,
- AL_HEAL,
- AL_INCAGI,
- AL_DECAGI,
- AL_HOLYWATER,
- AL_CRUCIS,
- AL_ANGELUS,
- AL_BLESSING,
- AL_CURE,
-
- MC_INCCARRY,
- MC_DISCOUNT,
- MC_OVERCHARGE,
- MC_PUSHCART,
- MC_IDENTIFY,
- MC_VENDING,
- MC_MAMMONITE,
-
- AC_OWL,
- AC_VULTURE,
- AC_CONCENTRATION,
- AC_DOUBLE,
- AC_SHOWER,
-
- TF_DOUBLE,
- TF_MISS,
- TF_STEAL,
- TF_HIDING,
- TF_POISON,
- TF_DETOXIFY,
-
- ALL_RESURRECTION,
-
- KN_SPEARMASTERY,
- KN_PIERCE,
- KN_BRANDISHSPEAR,
- KN_SPEARSTAB,
- KN_SPEARBOOMERANG,
- KN_TWOHANDQUICKEN,
- KN_AUTOCOUNTER,
- KN_BOWLINGBASH,
- KN_RIDING,
- KN_CAVALIERMASTERY,
-
- PR_MACEMASTERY,
- PR_IMPOSITIO,
- PR_SUFFRAGIUM,
- PR_ASPERSIO,
- PR_BENEDICTIO,
- PR_SANCTUARY,
- PR_SLOWPOISON,
- PR_STRECOVERY,
- PR_KYRIE,
- PR_MAGNIFICAT,
- PR_GLORIA,
- PR_LEXDIVINA,
- PR_TURNUNDEAD,
- PR_LEXAETERNA,
- PR_MAGNUS,
-
- WZ_FIREPILLAR,
- WZ_SIGHTRASHER,
- WZ_FIREIVY,
- WZ_METEOR,
- WZ_JUPITEL,
- WZ_VERMILION,
- WZ_WATERBALL,
- WZ_ICEWALL,
- WZ_FROSTNOVA,
- WZ_STORMGUST,
- WZ_EARTHSPIKE,
- WZ_HEAVENDRIVE,
- WZ_QUAGMIRE,
- WZ_ESTIMATION,
-
- BS_IRON,
- BS_STEEL,
- BS_ENCHANTEDSTONE,
- BS_ORIDEOCON,
- BS_DAGGER,
- BS_SWORD,
- BS_TWOHANDSWORD,
- BS_AXE,
- BS_MACE,
- BS_KNUCKLE,
- BS_SPEAR,
- BS_HILTBINDING,
- BS_FINDINGORE,
- BS_WEAPONRESEARCH,
- BS_REPAIRWEAPON,
- BS_SKINTEMPER,
- BS_HAMMERFALL,
- BS_ADRENALINE,
- BS_WEAPONPERFECT,
- BS_OVERTHRUST,
- BS_MAXIMIZE,
-
- HT_SKIDTRAP,
- HT_LANDMINE,
- HT_ANKLESNARE,
- HT_SHOCKWAVE,
- HT_SANDMAN,
- HT_FLASHER,
- HT_FREEZINGTRAP,
- HT_BLASTMINE,
- HT_CLAYMORETRAP,
- HT_REMOVETRAP,
- HT_TALKIEBOX,
- HT_BEASTBANE,
- HT_FALCON,
- HT_STEELCROW,
- HT_BLITZBEAT,
- HT_DETECTING,
- HT_SPRINGTRAP,
-
- AS_RIGHT,
- AS_LEFT,
- AS_KATAR,
- AS_CLOAKING,
- AS_SONICBLOW,
- AS_GRIMTOOTH,
- AS_ENCHANTPOISON,
- AS_POISONREACT,
- AS_VENOMDUST,
- AS_SPLASHER,
-
- NV_FIRSTAID,
- NV_TRICKDEAD,
- SM_MOVINGRECOVERY,
- SM_FATALBLOW,
- SM_AUTOBERSERK,
- AC_MAKINGARROW,
- AC_CHARGEARROW,
- TF_SPRINKLESAND,
- TF_BACKSLIDING,
- TF_PICKSTONE,
- TF_THROWSTONE,
- MC_CARTREVOLUTION,
- MC_CHANGECART,
- MC_LOUD,
- AL_HOLYLIGHT,
- MG_ENERGYCOAT,
-
- NPC_PIERCINGATT,
- NPC_MENTALBREAKER,
- NPC_RANGEATTACK,
- NPC_ATTRICHANGE,
- NPC_CHANGEWATER,
- NPC_CHANGEGROUND,
- NPC_CHANGEFIRE,
- NPC_CHANGEWIND,
- NPC_CHANGEPOISON,
- NPC_CHANGEHOLY,
- NPC_CHANGEDARKNESS,
- NPC_CHANGETELEKINESIS,
- NPC_CRITICALSLASH,
- NPC_COMBOATTACK,
- NPC_GUIDEDATTACK,
- NPC_SELFDESTRUCTION,
- NPC_SPLASHATTACK,
- NPC_SUICIDE,
- NPC_POISON,
- NPC_BLINDATTACK,
- NPC_SILENCEATTACK,
- NPC_STUNATTACK,
- NPC_PETRIFYATTACK,
- NPC_CURSEATTACK,
- NPC_SLEEPATTACK,
- NPC_RANDOMATTACK,
- NPC_WATERATTACK,
- NPC_GROUNDATTACK,
- NPC_FIREATTACK,
- NPC_WINDATTACK,
- NPC_POISONATTACK,
- NPC_HOLYATTACK,
- NPC_DARKNESSATTACK,
- NPC_TELEKINESISATTACK,
- NPC_MAGICALATTACK,
- NPC_METAMORPHOSIS,
- NPC_PROVOCATION,
- NPC_SMOKING,
- NPC_SUMMONSLAVE,
- NPC_EMOTION,
- NPC_TRANSFORMATION,
- NPC_BLOODDRAIN,
- NPC_ENERGYDRAIN,
- NPC_KEEPING,
- NPC_DARKBREATH,
- NPC_DARKBLESSING,
- NPC_BARRIER,
- NPC_DEFENDER,
- NPC_LICK,
- NPC_HALLUCINATION,
- NPC_REBIRTH,
- NPC_SUMMONMONSTER,
-
- RG_SNATCHER,
- RG_STEALCOIN,
- RG_BACKSTAP,
- RG_TUNNELDRIVE,
- RG_RAID,
- RG_STRIPWEAPON,
- RG_STRIPSHIELD,
- RG_STRIPARMOR,
- RG_STRIPHELM,
- RG_INTIMIDATE,
- RG_GRAFFITI,
- RG_FLAGGRAFFITI,
- RG_CLEANER,
- RG_GANGSTER,
- RG_COMPULSION,
- RG_PLAGIARISM,
-
- AM_AXEMASTERY,
- AM_LEARNINGPOTION,
- AM_PHARMACY,
- AM_DEMONSTRATION,
- AM_ACIDTERROR,
- AM_POTIONPITCHER,
- AM_CANNIBALIZE,
- AM_SPHEREMINE,
- AM_CP_WEAPON,
- AM_CP_SHIELD,
- AM_CP_ARMOR,
- AM_CP_HELM,
- AM_BIOETHICS,
- AM_BIOTECHNOLOGY,
- AM_CREATECREATURE,
- AM_CULTIVATION,
- AM_FLAMECONTROL,
- AM_CALLHOMUN,
- AM_REST,
- AM_DRILLMASTER,
- AM_HEALHOMUN,
- AM_RESURRECTHOMUN,
-
- CR_TRUST,
- CR_AUTOGUARD,
- CR_SHIELDCHARGE,
- CR_SHIELDBOOMERANG,
- CR_REFLECTSHIELD,
- CR_HOLYCROSS,
- CR_GRANDCROSS,
- CR_DEVOTION,
- CR_PROVIDENCE,
- CR_DEFENDER,
- CR_SPEARQUICKEN,
-
- MO_IRONHAND,
- MO_SPIRITSRECOVERY,
- MO_CALLSPIRITS,
- MO_ABSORBSPIRITS,
- MO_TRIPLEATTACK,
- MO_BODYRELOCATION,
- MO_DODGE,
- MO_INVESTIGATE,
- MO_FINGEROFFENSIVE,
- MO_STEELBODY,
- MO_BLADESTOP,
- MO_EXPLOSIONSPIRITS,
- MO_EXTREMITYFIST,
- MO_CHAINCOMBO,
- MO_COMBOFINISH,
-
- SA_ADVANCEDBOOK,
- SA_CASTCANCEL,
- SA_MAGICROD,
- SA_SPELLBREAKER,
- SA_FREECAST,
- SA_AUTOSPELL,
- SA_FLAMELAUNCHER,
- SA_FROSTWEAPON,
- SA_LIGHTNINGLOADER,
- SA_SEISMICWEAPON,
- SA_DRAGONOLOGY,
- SA_VOLCANO,
- SA_DELUGE,
- SA_VIOLENTGALE,
- SA_LANDPROTECTOR,
- SA_DISPELL,
- SA_ABRACADABRA,
- SA_MONOCELL,
- SA_CLASSCHANGE,
- SA_SUMMONMONSTER,
- SA_REVERSEORCISH,
- SA_DEATH,
- SA_FORTUNE,
- SA_TAMINGMONSTER,
- SA_QUESTION,
- SA_GRAVITY,
- SA_LEVELUP,
- SA_INSTANTDEATH,
- SA_FULLRECOVERY,
- SA_COMA,
-
- BD_ADAPTATION,
- BD_ENCORE,
- BD_LULLABY,
- BD_RICHMANKIM,
- BD_ETERNALCHAOS,
- BD_DRUMBATTLEFIELD,
- BD_RINGNIBELUNGEN,
- BD_ROKISWEIL,
- BD_INTOABYSS,
- BD_SIEGFRIED,
- BD_RAGNAROK,
-
- BA_MUSICALLESSON,
- BA_MUSICALSTRIKE,
- BA_DISSONANCE,
- BA_FROSTJOKER,
- BA_WHISTLE,
- BA_ASSASSINCROSS,
- BA_POEMBRAGI,
- BA_APPLEIDUN,
-
- DC_DANCINGLESSON,
- DC_THROWARROW,
- DC_UGLYDANCE,
- DC_SCREAM,
- DC_HUMMING,
- DC_DONTFORGETME,
- DC_FORTUNEKISS,
- DC_SERVICEFORYOU,
-
- NPC_RANDOMMOVE,
- NPC_SPEEDUP,
- NPC_REVENGE,
-
- WE_MALE,
- WE_FEMALE,
- WE_CALLPARTNER,
-
- ITM_TOMAHAWK,
-
- NPC_DARKCROSS,
- NPC_GRANDDARKNESS,
- NPC_DARKSTRIKE,
- NPC_DARKTHUNDER,
- NPC_STOP,
- NPC_WEAPONBRAKER,
- NPC_ARMORBRAKE,
- NPC_HELMBRAKE,
- NPC_SHIELDBRAKE,
- NPC_UNDEADATTACK,
- NPC_CHANGEUNDEAD,
- NPC_POWERUP,
- NPC_AGIUP,
- NPC_SIEGEMODE,
- NPC_CALLSLAVE,
- NPC_INVISIBLE,
- NPC_RUN,
-
- LK_AURABLADE,
- LK_PARRYING,
- LK_CONCENTRATION,
- LK_TENSIONRELAX,
- LK_BERSERK,
- LK_FURY,
- HP_ASSUMPTIO,
- HP_BASILICA,
- HP_MEDITATIO,
- HW_SOULDRAIN,
- HW_MAGICCRASHER,
- HW_MAGICPOWER,
- PA_PRESSURE,
- PA_SACRIFICE,
- PA_GOSPEL,
- CH_PALMSTRIKE,
- CH_TIGERFIST,
- CH_CHAINCRUSH,
- PF_HPCONVERSION,
- PF_SOULCHANGE,
- PF_SOULBURN,
- ASC_KATAR,
- ASC_HALLUCINATION,
- ASC_EDP,
- ASC_BREAKER,
- SN_SIGHT,
- SN_FALCONASSAULT,
- SN_SHARPSHOOTING,
- SN_WINDWALK,
- WS_MELTDOWN,
- WS_CREATECOIN,
- WS_CREATENUGGET,
- WS_CARTBOOST,
- WS_SYSTEMCREATE,
- ST_CHASEWALK,
- ST_REJECTSWORD,
- ST_STEALBACKPACK,
- CR_ALCHEMY,
- CR_SYNTHESISPOTION,
- CG_ARROWVULCAN,
- CG_MOONLIT,
- CG_MARIONETTE,
- LK_SPIRALPIERCE,
- LK_HEADCRUSH,
- LK_JOINTBEAT,
- HW_NAPALMVULCAN,
- CH_SOULCOLLECT,
- PF_MINDBREAKER,
- PF_MEMORIZE,
- PF_FOGWALL,
- PF_SPIDERWEB,
- ASC_METEORASSAULT,
- ASC_CDP,
- WE_BABY,
- WE_CALLPARENT,
- WE_CALLBABY,
-
- TK_RUN,
- TK_READYSTORM,
- TK_STORMKICK,
- TK_READYDOWN,
- TK_DOWNKICK,
- TK_READYTURN,
- TK_TURNKICK,
- TK_READYCOUNTER,
- TK_COUNTER,
- TK_DODGE,
- TK_JUMPKICK,
- TK_HPTIME,
- TK_SPTIME,
- TK_POWER,
- TK_SEVENWIND,
- TK_HIGHJUMP,
-
- SG_FEEL,
- SG_SUN_WARM,
- SG_MOON_WARM,
- SG_STAR_WARM,
- SG_SUN_COMFORT,
- SG_MOON_COMFORT,
- SG_STAR_COMFORT,
- SG_HATE,
- SG_SUN_ANGER,
- SG_MOON_ANGER,
- SG_STAR_ANGER,
- SG_SUN_BLESS,
- SG_MOON_BLESS,
- SG_STAR_BLESS,
- SG_DEVIL,
- SG_FRIEND,
- SG_KNOWLEDGE,
- SG_FUSION,
-
- SL_ALCHEMIST,
- AM_BERSERKPITCHER,
- SL_MONK,
- SL_STAR,
- SL_SAGE,
- SL_CRUSADER,
- SL_SUPERNOVICE,
- SL_KNIGHT,
- SL_WIZARD,
- SL_PRIEST,
- SL_BARDDANCER,
- SL_ROGUE,
- SL_ASSASIN,
- SL_BLACKSMITH,
- BS_ADRENALINE2,
- SL_HUNTER,
- SL_SOULLINKER,
- SL_KAIZEL,
- SL_KAAHI,
- SL_KAUPE,
- SL_KAITE,
- SL_KAINA,
- SL_STIN,
- SL_STUN,
- SL_SMA,
- SL_SWOO,
- SL_SKE,
- SL_SKA,
-
- SM_SELFPROVOKE,
- NPC_EMOTION_ON,
- ST_PRESERVE,
- ST_FULLSTRIP,
- WS_WEAPONREFINE,
- CR_SLIMPITCHER,
- CR_FULLPROTECTION,
- PA_SHIELDCHAIN,
- HP_MANARECHARGE,
- PF_DOUBLECASTING,
- HW_GANBANTEIN,
- HW_GRAVITATION,
- WS_CARTTERMINATION,
- WS_OVERTHRUSTMAX,
- CG_LONGINGFREEDOM,
- CG_HERMODE,
- CG_TAROTCARD,
- CR_ACIDDEMONSTRATION,
- CR_CULTIVATION,
- ITEM_ENCHANTARMS,
- TK_MISSION,
- SL_HIGH,
- KN_ONEHAND,
- AM_TWILIGHT1,
- AM_TWILIGHT2,
- AM_TWILIGHT3,
- HT_POWER,
-
- GS_GLITTERING,
- GS_FLING,
- GS_TRIPLEACTION,
- GS_BULLSEYE,
- GS_MADNESSCANCEL,
- GS_ADJUSTMENT,
- GS_INCREASING,
- GS_MAGICALBULLET,
- GS_CRACKER,
- GS_SINGLEACTION,
- GS_SNAKEEYE,
- GS_CHAINACTION,
- GS_TRACKING,
- GS_DISARM,
- GS_PIERCINGSHOT,
- GS_RAPIDSHOWER,
- GS_DESPERADO,
- GS_GATLINGFEVER,
- GS_DUST,
- GS_FULLBUSTER,
- GS_SPREADATTACK,
- GS_GROUNDDRIFT,
-
- NJ_TOBIDOUGU,
- NJ_SYURIKEN,
- NJ_KUNAI,
- NJ_HUUMA,
- NJ_ZENYNAGE,
- NJ_TATAMIGAESHI,
- NJ_KASUMIKIRI,
- NJ_SHADOWJUMP,
- NJ_KIRIKAGE,
- NJ_UTSUSEMI,
- NJ_BUNSINJYUTSU,
- NJ_NINPOU,
- NJ_KOUENKA,
- NJ_KAENSIN,
- NJ_BAKUENRYU,
- NJ_HYOUSENSOU,
- NJ_SUITON,
- NJ_HYOUSYOURAKU,
- NJ_HUUJIN,
- NJ_RAIGEKISAI,
- NJ_KAMAITACHI,
- NJ_NEN,
- NJ_ISSEN,
-
- MB_FIGHTING,
- MB_NEUTRAL,
- MB_TAIMING_PUTI,
- MB_WHITEPOTION,
- MB_MENTAL,
- MB_CARDPITCHER,
- MB_PETPITCHER,
- MB_BODYSTUDY,
- MB_BODYALTER,
- MB_PETMEMORY,
- MB_M_TELEPORT,
- MB_B_GAIN,
- MB_M_GAIN,
- MB_MISSION,
- MB_MUNAKKNOWLEDGE,
- MB_MUNAKBALL,
- MB_SCROLL,
- MB_B_GATHERING,
- MB_M_GATHERING,
- MB_B_EXCLUDE,
- MB_B_DRIFT,
- MB_B_WALLRUSH,
- MB_M_WALLRUSH,
- MB_B_WALLSHIFT,
- MB_M_WALLCRASH,
- MB_M_REINCARNATION,
- MB_B_EQUIP,
-
- SL_DEATHKNIGHT,
- SL_COLLECTOR,
- SL_NINJA,
- SL_GUNNER,
- AM_TWILIGHT4,
- DA_RESET,
- DE_BERSERKAIZER,
- DA_DARKPOWER,
-
- DE_PASSIVE,
- DE_PATTACK,
- DE_PSPEED,
- DE_PDEFENSE,
- DE_PCRITICAL,
- DE_PHP,
- DE_PSP,
- DE_RESET,
- DE_RANKING,
- DE_PTRIPLE,
- DE_ENERGY,
- DE_NIGHTMARE,
- DE_SLASH,
- DE_COIL,
- DE_WAVE,
- DE_REBIRTH,
- DE_AURA,
- DE_FREEZER,
- DE_CHANGEATTACK,
- DE_PUNISH,
- DE_POISON,
- DE_INSTANT,
- DE_WARNING,
- DE_RANKEDKNIFE,
- DE_RANKEDGRADIUS,
- DE_GAUGE,
- DE_GTIME,
- DE_GPAIN,
- DE_GSKILL,
- DE_GKILL,
- DE_ACCEL,
- DE_BLOCKDOUBLE,
- DE_BLOCKMELEE,
- DE_BLOCKFAR,
- DE_FRONTATTACK,
- DE_DANGERATTACK,
- DE_TWINATTACK,
- DE_WINDATTACK,
- DE_WATERATTACK,
-
- DA_ENERGY,
- DA_CLOUD,
- DA_FIRSTSLOT,
- DA_HEADDEF,
- DA_SPACE,
- DA_TRANSFORM,
- DA_EXPLOSION,
- DA_REWARD,
- DA_CRUSH,
- DA_ITEMREBUILD,
- DA_ILLUSION,
- DA_NUETRALIZE,
- DA_RUNNER,
- DA_TRANSFER,
- DA_WALL,
- DA_ZENY,
- DA_REVENGE,
- DA_EARPLUG,
- DA_CONTRACT,
- DA_BLACK,
- DA_DREAM,
- DA_MAGICCART,
- DA_COPY,
- DA_CRYSTAL,
- DA_EXP,
- DA_CARTSWING,
- DA_REBUILD,
- DA_JOBCHANGE,
- DA_EDARKNESS,
- DA_EGUARDIAN,
- DA_TIMEOUT,
- ALL_TIMEIN,
- DA_ZENYRANK,
- DA_ACCESSORYMIX,
-
- NPC_EARTHQUAKE,
- NPC_FIREBREATH,
- NPC_ICEBREATH,
- NPC_THUNDERBREATH,
- NPC_ACIDBREATH,
- NPC_DARKNESSBREATH,
- NPC_DRAGONFEAR,
- NPC_BLEEDING,
- NPC_PULSESTRIKE,
- NPC_HELLJUDGEMENT,
- NPC_WIDESILENCE,
- NPC_WIDEFREEZE,
- NPC_WIDEBLEEDING,
- NPC_WIDESTONE,
- NPC_WIDECONFUSE,
- NPC_WIDESLEEP,
- NPC_WIDESIGHT,
- NPC_EVILLAND,
- NPC_MAGICMIRROR,
- NPC_SLOWCAST,
- NPC_CRITICALWOUND,
- NPC_EXPULSION,
- NPC_STONESKIN,
- NPC_ANTIMAGIC,
- NPC_WIDECURSE,
- NPC_WIDESTUN,
- NPC_VAMPIRE_GIFT,
- NPC_WIDESOULDRAIN,
-
- ALL_INCCARRY,
- NPC_TALK,
- NPC_HELLPOWER,
- NPC_WIDEHELLDIGNITY,
- NPC_INVINCIBLE,
- NPC_INVINCIBLEOFF,
- NPC_ALLHEAL,
- GM_SANDMAN,
- CASH_BLESSING,
- CASH_INCAGI,
- CASH_ASSUMPTIO,
- ALL_CATCRY,
- ALL_PARTYFLEE,
- ALL_ANGEL_PROTECT,
- ALL_DREAM_SUMMERNIGHT,
- NPC_CHANGEUNDEAD2,
- ALL_REVERSEORCISH,
- ALL_WEWISH,
- ALL_SONKRAN,
- NPC_WIDEHEALTHFEAR,
- NPC_WIDEBODYBURNNING,
- NPC_WIDEFROSTMISTY,
- NPC_WIDECOLD,
- NPC_WIDE_DEEP_SLEEP,
- NPC_WIDESIREN,
- NPC_VENOMFOG,
- NPC_MILLENNIUMSHIELD,
- NPC_COMET,
-
- KN_CHARGEATK = 1001,
- CR_SHRINK,
- AS_SONICACCEL,
- AS_VENOMKNIFE,
- RG_CLOSECONFINE,
- WZ_SIGHTBLASTER,
- SA_CREATECON,
- SA_ELEMENTWATER,
- HT_PHANTASMIC,
- BA_PANGVOICE,
- DC_WINKCHARM,
- BS_UNFAIRLYTRICK,
- BS_GREED,
- PR_REDEMPTIO,
- MO_KITRANSLATION,
- MO_BALKYOUNG,
- SA_ELEMENTGROUND,
- SA_ELEMENTFIRE,
- SA_ELEMENTWIND,
-
- RK_ENCHANTBLADE = 2001,
- RK_SONICWAVE,
- RK_DEATHBOUND,
- RK_HUNDREDSPEAR,
- RK_WINDCUTTER,
- RK_IGNITIONBREAK,
- RK_DRAGONTRAINING,
- RK_DRAGONBREATH,
- RK_DRAGONHOWLING,
- RK_RUNEMASTERY,
- RK_MILLENNIUMSHIELD,
- RK_CRUSHSTRIKE,
- RK_REFRESH,
- RK_GIANTGROWTH,
- RK_STONEHARDSKIN,
- RK_VITALITYACTIVATION,
- RK_STORMBLAST,
- RK_FIGHTINGSPIRIT,
- RK_ABUNDANCE,
- RK_PHANTOMTHRUST,
-
- GC_VENOMIMPRESS,
- GC_CROSSIMPACT,
- GC_DARKILLUSION,
- GC_RESEARCHNEWPOISON,
- GC_CREATENEWPOISON,
- GC_ANTIDOTE,
- GC_POISONINGWEAPON,
- GC_WEAPONBLOCKING,
- GC_COUNTERSLASH,
- GC_WEAPONCRUSH,
- GC_VENOMPRESSURE,
- GC_POISONSMOKE,
- GC_CLOAKINGEXCEED,
- GC_PHANTOMMENACE,
- GC_HALLUCINATIONWALK,
- GC_ROLLINGCUTTER,
- GC_CROSSRIPPERSLASHER,
-
- AB_JUDEX,
- AB_ANCILLA,
- AB_ADORAMUS,
- AB_CLEMENTIA,
- AB_CANTO,
- AB_CHEAL,
- AB_EPICLESIS,
- AB_PRAEFATIO,
- AB_ORATIO,
- AB_LAUDAAGNUS,
- AB_LAUDARAMUS,
- AB_EUCHARISTICA,
- AB_RENOVATIO,
- AB_HIGHNESSHEAL,
- AB_CLEARANCE,
- AB_EXPIATIO,
- AB_DUPLELIGHT,
- AB_DUPLELIGHT_MELEE,
- AB_DUPLELIGHT_MAGIC,
- AB_SILENTIUM,
-
- WL_WHITEIMPRISON = 2201,
- WL_SOULEXPANSION,
- WL_FROSTMISTY,
- WL_JACKFROST,
- WL_MARSHOFABYSS,
- WL_RECOGNIZEDSPELL,
- WL_SIENNAEXECRATE,
- WL_RADIUS,
- WL_STASIS,
- WL_DRAINLIFE,
- WL_CRIMSONROCK,
- WL_HELLINFERNO,
- WL_COMET,
- WL_CHAINLIGHTNING,
- WL_CHAINLIGHTNING_ATK,
- WL_EARTHSTRAIN,
- WL_TETRAVORTEX,
- WL_TETRAVORTEX_FIRE,
- WL_TETRAVORTEX_WATER,
- WL_TETRAVORTEX_WIND,
- WL_TETRAVORTEX_GROUND,
- WL_SUMMONFB,
- WL_SUMMONBL,
- WL_SUMMONWB,
- WL_SUMMON_ATK_FIRE,
- WL_SUMMON_ATK_WIND,
- WL_SUMMON_ATK_WATER,
- WL_SUMMON_ATK_GROUND,
- WL_SUMMONSTONE,
- WL_RELEASE,
- WL_READING_SB,
- WL_FREEZE_SP,
-
- RA_ARROWSTORM,
- RA_FEARBREEZE,
- RA_RANGERMAIN,
- RA_AIMEDBOLT,
- RA_DETONATOR,
- RA_ELECTRICSHOCKER,
- RA_CLUSTERBOMB,
- RA_WUGMASTERY,
- RA_WUGRIDER,
- RA_WUGDASH,
- RA_WUGSTRIKE,
- RA_WUGBITE,
- RA_TOOTHOFWUG,
- RA_SENSITIVEKEEN,
- RA_CAMOUFLAGE,
- RA_RESEARCHTRAP,
- RA_MAGENTATRAP,
- RA_COBALTTRAP,
- RA_MAIZETRAP,
- RA_VERDURETRAP,
- RA_FIRINGTRAP,
- RA_ICEBOUNDTRAP,
-
- NC_MADOLICENCE,
- NC_BOOSTKNUCKLE,
- NC_PILEBUNKER,
- NC_VULCANARM,
- NC_FLAMELAUNCHER,
- NC_COLDSLOWER,
- NC_ARMSCANNON,
- NC_ACCELERATION,
- NC_HOVERING,
- NC_F_SIDESLIDE,
- NC_B_SIDESLIDE,
- NC_MAINFRAME,
- NC_SELFDESTRUCTION,
- NC_SHAPESHIFT,
- NC_EMERGENCYCOOL,
- NC_INFRAREDSCAN,
- NC_ANALYZE,
- NC_MAGNETICFIELD,
- NC_NEUTRALBARRIER,
- NC_STEALTHFIELD,
- NC_REPAIR,
- NC_TRAININGAXE,
- NC_RESEARCHFE,
- NC_AXEBOOMERANG,
- NC_POWERSWING,
- NC_AXETORNADO,
- NC_SILVERSNIPER,
- NC_MAGICDECOY,
- NC_DISJOINT,
-
- SC_FATALMENACE,
- SC_REPRODUCE,
- SC_AUTOSHADOWSPELL,
- SC_SHADOWFORM,
- SC_TRIANGLESHOT,
- SC_BODYPAINT,
- SC_INVISIBILITY,
- SC_DEADLYINFECT,
- SC_ENERVATION,
- SC_GROOMY,
- SC_IGNORANCE,
- SC_LAZINESS,
- SC_UNLUCKY,
- SC_WEAKNESS,
- SC_STRIPACCESSARY,
- SC_MANHOLE,
- SC_DIMENSIONDOOR,
- SC_CHAOSPANIC,
- SC_MAELSTROM,
- SC_BLOODYLUST,
- SC_FEINTBOMB,
-
- LG_CANNONSPEAR = 2307,
- LG_BANISHINGPOINT,
- LG_TRAMPLE,
- LG_SHIELDPRESS,
- LG_REFLECTDAMAGE,
- LG_PINPOINTATTACK,
- LG_FORCEOFVANGUARD,
- LG_RAGEBURST,
- LG_SHIELDSPELL,
- LG_EXEEDBREAK,
- LG_OVERBRAND,
- LG_PRESTIGE,
- LG_BANDING,
- LG_MOONSLASHER,
- LG_RAYOFGENESIS,
- LG_PIETY,
- LG_EARTHDRIVE,
- LG_HESPERUSLIT,
- LG_INSPIRATION,
-
- SR_DRAGONCOMBO,
- SR_SKYNETBLOW,
- SR_EARTHSHAKER,
- SR_FALLENEMPIRE,
- SR_TIGERCANNON,
- SR_HELLGATE,
- SR_RAMPAGEBLASTER,
- SR_CRESCENTELBOW,
- SR_CURSEDCIRCLE,
- SR_LIGHTNINGWALK,
- SR_KNUCKLEARROW,
- SR_WINDMILL,
- SR_RAISINGDRAGON,
- SR_GENTLETOUCH,
- SR_ASSIMILATEPOWER,
- SR_POWERVELOCITY,
- SR_CRESCENTELBOW_AUTOSPELL,
- SR_GATEOFHELL,
- SR_GENTLETOUCH_QUIET,
- SR_GENTLETOUCH_CURE,
- SR_GENTLETOUCH_ENERGYGAIN,
- SR_GENTLETOUCH_CHANGE,
- SR_GENTLETOUCH_REVITALIZE,
-
- WA_SWING_DANCE = 2350,
- WA_SYMPHONY_OF_LOVER,
- WA_MOONLIT_SERENADE,
-
- MI_RUSH_WINDMILL = 2381,
- MI_ECHOSONG,
- MI_HARMONIZE,
-
- WM_LESSON = 2412,
- WM_METALICSOUND,
- WM_REVERBERATION,
- WM_REVERBERATION_MELEE,
- WM_REVERBERATION_MAGIC,
- WM_DOMINION_IMPULSE,
- WM_SEVERE_RAINSTORM,
- WM_POEMOFNETHERWORLD,
- WM_VOICEOFSIREN,
- WM_DEADHILLHERE,
- WM_LULLABY_DEEPSLEEP,
- WM_SIRCLEOFNATURE,
- WM_RANDOMIZESPELL,
- WM_GLOOMYDAY,
- WM_GREAT_ECHO,
- WM_SONG_OF_MANA,
- WM_DANCE_WITH_WUG,
- WM_SOUND_OF_DESTRUCTION,
- WM_SATURDAY_NIGHT_FEVER,
- WM_LERADS_DEW,
- WM_MELODYOFSINK,
- WM_BEYOND_OF_WARCRY,
- WM_UNLIMITED_HUMMING_VOICE,
-
- SO_FIREWALK = 2443,
- SO_ELECTRICWALK,
- SO_SPELLFIST,
- SO_EARTHGRAVE,
- SO_DIAMONDDUST,
- SO_POISON_BUSTER,
- SO_PSYCHIC_WAVE,
- SO_CLOUD_KILL,
- SO_STRIKING,
- SO_WARMER,
- SO_VACUUM_EXTREME,
- SO_VARETYR_SPEAR,
- SO_ARRULLO,
- SO_EL_CONTROL,
- SO_SUMMON_AGNI,
- SO_SUMMON_AQUA,
- SO_SUMMON_VENTUS,
- SO_SUMMON_TERA,
- SO_EL_ACTION,
- SO_EL_ANALYSIS,
- SO_EL_SYMPATHY,
- SO_EL_CURE,
- SO_FIRE_INSIGNIA,
- SO_WATER_INSIGNIA,
- SO_WIND_INSIGNIA,
- SO_EARTH_INSIGNIA,
-
- GN_TRAINING_SWORD = 2474,
- GN_REMODELING_CART,
- GN_CART_TORNADO,
- GN_CARTCANNON,
- GN_CARTBOOST,
- GN_THORNS_TRAP,
- GN_BLOOD_SUCKER,
- GN_SPORE_EXPLOSION,
- GN_WALLOFTHORN,
- GN_CRAZYWEED,
- GN_CRAZYWEED_ATK,
- GN_DEMONIC_FIRE,
- GN_FIRE_EXPANSION,
- GN_FIRE_EXPANSION_SMOKE_POWDER,
- GN_FIRE_EXPANSION_TEAR_GAS,
- GN_FIRE_EXPANSION_ACID,
- GN_HELLS_PLANT,
- GN_HELLS_PLANT_ATK,
- GN_MANDRAGORA,
- GN_SLINGITEM,
- GN_CHANGEMATERIAL,
- GN_MIX_COOKING,
- GN_MAKEBOMB,
- GN_S_PHARMACY,
- GN_SLINGITEM_RANGEMELEEATK,
-
- AB_SECRAMENT = 2515,
- WM_SEVERE_RAINSTORM_MELEE,
- SR_HOWLINGOFLION,
- SR_RIDEINLIGHTNING,
- LG_OVERBRAND_BRANDISH,
- LG_OVERBRAND_PLUSATK,
-
- ALL_ODINS_RECALL = 2533,
- RETURN_TO_ELDICASTES,
- ALL_BUYING_STORE,
- ALL_GUARDIAN_RECALL,
- ALL_ODINS_POWER,
- BEER_BOTTLE_CAP,
- NPC_ASSASSINCROSS,
- NPC_DISSONANCE,
- NPC_UGLYDANCE,
- ALL_TETANY,
- ALL_RAY_OF_PROTECTION,
- MC_CARTDECORATE,
-
- KO_YAMIKUMO = 3001,
- KO_RIGHT,
- KO_LEFT,
- KO_JYUMONJIKIRI,
- KO_SETSUDAN,
- KO_BAKURETSU,
- KO_HAPPOKUNAI,
- KO_MUCHANAGE,
- KO_HUUMARANKA,
- KO_MAKIBISHI,
- KO_MEIKYOUSISUI,
- KO_ZANZOU,
- KO_KYOUGAKU,
- KO_JYUSATSU,
- KO_KAHU_ENTEN,
- KO_HYOUHU_HUBUKI,
- KO_KAZEHU_SEIRAN,
- KO_DOHU_KOUKAI,
- KO_KAIHOU,
- KO_ZENKAI,
- KO_GENWAKU,
- KO_IZAYOI,
- KG_KAGEHUMI,
- KG_KYOMU,
- KG_KAGEMUSYA,
- OB_ZANGETSU,
- OB_OBOROGENSOU,
- OB_OBOROGENSOU_TRANSITION_ATK,
- OB_AKAITSUKI,
-
- ECL_SNOWFLIP = 3031,
- ECL_PEONYMAMY,
- ECL_SADAGUI,
- ECL_SEQUOIADUST,
- ECLAGE_RECALL,
-
- HLIF_HEAL = 8001,
- HLIF_AVOID,
- HLIF_BRAIN,
- HLIF_CHANGE,
- HAMI_CASTLE,
- HAMI_DEFENCE,
- HAMI_SKIN,
- HAMI_BLOODLUST,
- HFLI_MOON,
- HFLI_FLEET,
- HFLI_SPEED,
- HFLI_SBR44,
- HVAN_CAPRICE,
- HVAN_CHAOTIC,
- HVAN_INSTRUCT,
- HVAN_EXPLOSION,
- MUTATION_BASEJOB,
- MH_SUMMON_LEGION,
- MH_NEEDLE_OF_PARALYZE,
- MH_POISON_MIST,
- MH_PAIN_KILLER,
- MH_LIGHT_OF_REGENE,
- MH_OVERED_BOOST,
- MH_ERASER_CUTTER,
- MH_XENO_SLASHER,
- MH_SILENT_BREEZE,
- MH_STYLE_CHANGE,
- MH_SONIC_CRAW,
- MH_SILVERVEIN_RUSH,
- MH_MIDNIGHT_FRENZY,
- MH_STAHL_HORN,
- MH_GOLDENE_FERSE,
- MH_STEINWAND,
- MH_HEILIGE_STANGE,
- MH_ANGRIFFS_MODUS,
- MH_TINDER_BREAKER,
- MH_CBC,
- MH_EQC,
- MH_MAGMA_FLOW,
- MH_GRANITIC_ARMOR,
- MH_LAVA_SLIDE,
- MH_PYROCLASTIC,
- MH_VOLCANIC_ASH,
-
- MS_BASH = 8201,
- MS_MAGNUM,
- MS_BOWLINGBASH,
- MS_PARRYING,
- MS_REFLECTSHIELD,
- MS_BERSERK,
- MA_DOUBLE,
- MA_SHOWER,
- MA_SKIDTRAP,
- MA_LANDMINE,
- MA_SANDMAN,
- MA_FREEZINGTRAP,
- MA_REMOVETRAP,
- MA_CHARGEARROW,
- MA_SHARPSHOOTING,
- ML_PIERCE,
- ML_BRANDISH,
- ML_SPIRALPIERCE,
- ML_DEFENDER,
- ML_AUTOGUARD,
- ML_DEVOTION,
- MER_MAGNIFICAT,
- MER_QUICKEN,
- MER_SIGHT,
- MER_CRASH,
- MER_REGAIN,
- MER_TENDER,
- MER_BENEDICTION,
- MER_RECUPERATE,
- MER_MENTALCURE,
- MER_COMPRESS,
- MER_PROVOKE,
- MER_AUTOBERSERK,
- MER_DECAGI,
- MER_SCAPEGOAT,
- MER_LEXDIVINA,
- MER_ESTIMATION,
- MER_KYRIE,
- MER_BLESSING,
- MER_INCAGI,
-
- EL_CIRCLE_OF_FIRE = 8401,
- EL_FIRE_CLOAK,
- EL_FIRE_MANTLE,
- EL_WATER_SCREEN,
- EL_WATER_DROP,
- EL_WATER_BARRIER,
- EL_WIND_STEP,
- EL_WIND_CURTAIN,
- EL_ZEPHYR,
- EL_SOLID_SKIN,
- EL_STONE_SHIELD,
- EL_POWER_OF_GAIA,
- EL_PYROTECHNIC,
- EL_HEATER,
- EL_TROPIC,
- EL_AQUAPLAY,
- EL_COOLER,
- EL_CHILLY_AIR,
- EL_GUST,
- EL_BLAST,
- EL_WILD_STORM,
- EL_PETROLOGY,
- EL_CURSED_SOIL,
- EL_UPHEAVAL,
- EL_FIRE_ARROW,
- EL_FIRE_BOMB,
- EL_FIRE_BOMB_ATK,
- EL_FIRE_WAVE,
- EL_FIRE_WAVE_ATK,
- EL_ICE_NEEDLE,
- EL_WATER_SCREW,
- EL_WATER_SCREW_ATK,
- EL_TIDAL_WEAPON,
- EL_WIND_SLASH,
- EL_HURRICANE,
- EL_HURRICANE_ATK,
- EL_TYPOON_MIS,
- EL_TYPOON_MIS_ATK,
- EL_STONE_HAMMER,
- EL_ROCK_CRUSHER,
- EL_ROCK_CRUSHER_ATK,
- EL_STONE_RAIN,
+ NV_BASIC = 1,
+
+ SM_SWORD,
+ SM_TWOHAND,
+ SM_RECOVERY,
+ SM_BASH,
+ SM_PROVOKE,
+ SM_MAGNUM,
+ SM_ENDURE,
+
+ MG_SRECOVERY,
+ MG_SIGHT,
+ MG_NAPALMBEAT,
+ MG_SAFETYWALL,
+ MG_SOULSTRIKE,
+ MG_COLDBOLT,
+ MG_FROSTDIVER,
+ MG_STONECURSE,
+ MG_FIREBALL,
+ MG_FIREWALL,
+ MG_FIREBOLT,
+ MG_LIGHTNINGBOLT,
+ MG_THUNDERSTORM,
+
+ AL_DP,
+ AL_DEMONBANE,
+ AL_RUWACH,
+ AL_PNEUMA,
+ AL_TELEPORT,
+ AL_WARP,
+ AL_HEAL,
+ AL_INCAGI,
+ AL_DECAGI,
+ AL_HOLYWATER,
+ AL_CRUCIS,
+ AL_ANGELUS,
+ AL_BLESSING,
+ AL_CURE,
+
+ MC_INCCARRY,
+ MC_DISCOUNT,
+ MC_OVERCHARGE,
+ MC_PUSHCART,
+ MC_IDENTIFY,
+ MC_VENDING,
+ MC_MAMMONITE,
+
+ AC_OWL,
+ AC_VULTURE,
+ AC_CONCENTRATION,
+ AC_DOUBLE,
+ AC_SHOWER,
+
+ TF_DOUBLE,
+ TF_MISS,
+ TF_STEAL,
+ TF_HIDING,
+ TF_POISON,
+ TF_DETOXIFY,
+
+ ALL_RESURRECTION,
+
+ KN_SPEARMASTERY,
+ KN_PIERCE,
+ KN_BRANDISHSPEAR,
+ KN_SPEARSTAB,
+ KN_SPEARBOOMERANG,
+ KN_TWOHANDQUICKEN,
+ KN_AUTOCOUNTER,
+ KN_BOWLINGBASH,
+ KN_RIDING,
+ KN_CAVALIERMASTERY,
+
+ PR_MACEMASTERY,
+ PR_IMPOSITIO,
+ PR_SUFFRAGIUM,
+ PR_ASPERSIO,
+ PR_BENEDICTIO,
+ PR_SANCTUARY,
+ PR_SLOWPOISON,
+ PR_STRECOVERY,
+ PR_KYRIE,
+ PR_MAGNIFICAT,
+ PR_GLORIA,
+ PR_LEXDIVINA,
+ PR_TURNUNDEAD,
+ PR_LEXAETERNA,
+ PR_MAGNUS,
+
+ WZ_FIREPILLAR,
+ WZ_SIGHTRASHER,
+ WZ_FIREIVY,
+ WZ_METEOR,
+ WZ_JUPITEL,
+ WZ_VERMILION,
+ WZ_WATERBALL,
+ WZ_ICEWALL,
+ WZ_FROSTNOVA,
+ WZ_STORMGUST,
+ WZ_EARTHSPIKE,
+ WZ_HEAVENDRIVE,
+ WZ_QUAGMIRE,
+ WZ_ESTIMATION,
+
+ BS_IRON,
+ BS_STEEL,
+ BS_ENCHANTEDSTONE,
+ BS_ORIDEOCON,
+ BS_DAGGER,
+ BS_SWORD,
+ BS_TWOHANDSWORD,
+ BS_AXE,
+ BS_MACE,
+ BS_KNUCKLE,
+ BS_SPEAR,
+ BS_HILTBINDING,
+ BS_FINDINGORE,
+ BS_WEAPONRESEARCH,
+ BS_REPAIRWEAPON,
+ BS_SKINTEMPER,
+ BS_HAMMERFALL,
+ BS_ADRENALINE,
+ BS_WEAPONPERFECT,
+ BS_OVERTHRUST,
+ BS_MAXIMIZE,
+
+ HT_SKIDTRAP,
+ HT_LANDMINE,
+ HT_ANKLESNARE,
+ HT_SHOCKWAVE,
+ HT_SANDMAN,
+ HT_FLASHER,
+ HT_FREEZINGTRAP,
+ HT_BLASTMINE,
+ HT_CLAYMORETRAP,
+ HT_REMOVETRAP,
+ HT_TALKIEBOX,
+ HT_BEASTBANE,
+ HT_FALCON,
+ HT_STEELCROW,
+ HT_BLITZBEAT,
+ HT_DETECTING,
+ HT_SPRINGTRAP,
+
+ AS_RIGHT,
+ AS_LEFT,
+ AS_KATAR,
+ AS_CLOAKING,
+ AS_SONICBLOW,
+ AS_GRIMTOOTH,
+ AS_ENCHANTPOISON,
+ AS_POISONREACT,
+ AS_VENOMDUST,
+ AS_SPLASHER,
+
+ NV_FIRSTAID,
+ NV_TRICKDEAD,
+ SM_MOVINGRECOVERY,
+ SM_FATALBLOW,
+ SM_AUTOBERSERK,
+ AC_MAKINGARROW,
+ AC_CHARGEARROW,
+ TF_SPRINKLESAND,
+ TF_BACKSLIDING,
+ TF_PICKSTONE,
+ TF_THROWSTONE,
+ MC_CARTREVOLUTION,
+ MC_CHANGECART,
+ MC_LOUD,
+ AL_HOLYLIGHT,
+ MG_ENERGYCOAT,
+
+ NPC_PIERCINGATT,
+ NPC_MENTALBREAKER,
+ NPC_RANGEATTACK,
+ NPC_ATTRICHANGE,
+ NPC_CHANGEWATER,
+ NPC_CHANGEGROUND,
+ NPC_CHANGEFIRE,
+ NPC_CHANGEWIND,
+ NPC_CHANGEPOISON,
+ NPC_CHANGEHOLY,
+ NPC_CHANGEDARKNESS,
+ NPC_CHANGETELEKINESIS,
+ NPC_CRITICALSLASH,
+ NPC_COMBOATTACK,
+ NPC_GUIDEDATTACK,
+ NPC_SELFDESTRUCTION,
+ NPC_SPLASHATTACK,
+ NPC_SUICIDE,
+ NPC_POISON,
+ NPC_BLINDATTACK,
+ NPC_SILENCEATTACK,
+ NPC_STUNATTACK,
+ NPC_PETRIFYATTACK,
+ NPC_CURSEATTACK,
+ NPC_SLEEPATTACK,
+ NPC_RANDOMATTACK,
+ NPC_WATERATTACK,
+ NPC_GROUNDATTACK,
+ NPC_FIREATTACK,
+ NPC_WINDATTACK,
+ NPC_POISONATTACK,
+ NPC_HOLYATTACK,
+ NPC_DARKNESSATTACK,
+ NPC_TELEKINESISATTACK,
+ NPC_MAGICALATTACK,
+ NPC_METAMORPHOSIS,
+ NPC_PROVOCATION,
+ NPC_SMOKING,
+ NPC_SUMMONSLAVE,
+ NPC_EMOTION,
+ NPC_TRANSFORMATION,
+ NPC_BLOODDRAIN,
+ NPC_ENERGYDRAIN,
+ NPC_KEEPING,
+ NPC_DARKBREATH,
+ NPC_DARKBLESSING,
+ NPC_BARRIER,
+ NPC_DEFENDER,
+ NPC_LICK,
+ NPC_HALLUCINATION,
+ NPC_REBIRTH,
+ NPC_SUMMONMONSTER,
+
+ RG_SNATCHER,
+ RG_STEALCOIN,
+ RG_BACKSTAP,
+ RG_TUNNELDRIVE,
+ RG_RAID,
+ RG_STRIPWEAPON,
+ RG_STRIPSHIELD,
+ RG_STRIPARMOR,
+ RG_STRIPHELM,
+ RG_INTIMIDATE,
+ RG_GRAFFITI,
+ RG_FLAGGRAFFITI,
+ RG_CLEANER,
+ RG_GANGSTER,
+ RG_COMPULSION,
+ RG_PLAGIARISM,
+
+ AM_AXEMASTERY,
+ AM_LEARNINGPOTION,
+ AM_PHARMACY,
+ AM_DEMONSTRATION,
+ AM_ACIDTERROR,
+ AM_POTIONPITCHER,
+ AM_CANNIBALIZE,
+ AM_SPHEREMINE,
+ AM_CP_WEAPON,
+ AM_CP_SHIELD,
+ AM_CP_ARMOR,
+ AM_CP_HELM,
+ AM_BIOETHICS,
+ AM_BIOTECHNOLOGY,
+ AM_CREATECREATURE,
+ AM_CULTIVATION,
+ AM_FLAMECONTROL,
+ AM_CALLHOMUN,
+ AM_REST,
+ AM_DRILLMASTER,
+ AM_HEALHOMUN,
+ AM_RESURRECTHOMUN,
+
+ CR_TRUST,
+ CR_AUTOGUARD,
+ CR_SHIELDCHARGE,
+ CR_SHIELDBOOMERANG,
+ CR_REFLECTSHIELD,
+ CR_HOLYCROSS,
+ CR_GRANDCROSS,
+ CR_DEVOTION,
+ CR_PROVIDENCE,
+ CR_DEFENDER,
+ CR_SPEARQUICKEN,
+
+ MO_IRONHAND,
+ MO_SPIRITSRECOVERY,
+ MO_CALLSPIRITS,
+ MO_ABSORBSPIRITS,
+ MO_TRIPLEATTACK,
+ MO_BODYRELOCATION,
+ MO_DODGE,
+ MO_INVESTIGATE,
+ MO_FINGEROFFENSIVE,
+ MO_STEELBODY,
+ MO_BLADESTOP,
+ MO_EXPLOSIONSPIRITS,
+ MO_EXTREMITYFIST,
+ MO_CHAINCOMBO,
+ MO_COMBOFINISH,
+
+ SA_ADVANCEDBOOK,
+ SA_CASTCANCEL,
+ SA_MAGICROD,
+ SA_SPELLBREAKER,
+ SA_FREECAST,
+ SA_AUTOSPELL,
+ SA_FLAMELAUNCHER,
+ SA_FROSTWEAPON,
+ SA_LIGHTNINGLOADER,
+ SA_SEISMICWEAPON,
+ SA_DRAGONOLOGY,
+ SA_VOLCANO,
+ SA_DELUGE,
+ SA_VIOLENTGALE,
+ SA_LANDPROTECTOR,
+ SA_DISPELL,
+ SA_ABRACADABRA,
+ SA_MONOCELL,
+ SA_CLASSCHANGE,
+ SA_SUMMONMONSTER,
+ SA_REVERSEORCISH,
+ SA_DEATH,
+ SA_FORTUNE,
+ SA_TAMINGMONSTER,
+ SA_QUESTION,
+ SA_GRAVITY,
+ SA_LEVELUP,
+ SA_INSTANTDEATH,
+ SA_FULLRECOVERY,
+ SA_COMA,
+
+ BD_ADAPTATION,
+ BD_ENCORE,
+ BD_LULLABY,
+ BD_RICHMANKIM,
+ BD_ETERNALCHAOS,
+ BD_DRUMBATTLEFIELD,
+ BD_RINGNIBELUNGEN,
+ BD_ROKISWEIL,
+ BD_INTOABYSS,
+ BD_SIEGFRIED,
+ BD_RAGNAROK,
+
+ BA_MUSICALLESSON,
+ BA_MUSICALSTRIKE,
+ BA_DISSONANCE,
+ BA_FROSTJOKER,
+ BA_WHISTLE,
+ BA_ASSASSINCROSS,
+ BA_POEMBRAGI,
+ BA_APPLEIDUN,
+
+ DC_DANCINGLESSON,
+ DC_THROWARROW,
+ DC_UGLYDANCE,
+ DC_SCREAM,
+ DC_HUMMING,
+ DC_DONTFORGETME,
+ DC_FORTUNEKISS,
+ DC_SERVICEFORYOU,
+
+ NPC_RANDOMMOVE,
+ NPC_SPEEDUP,
+ NPC_REVENGE,
+
+ WE_MALE,
+ WE_FEMALE,
+ WE_CALLPARTNER,
+
+ ITM_TOMAHAWK,
+
+ NPC_DARKCROSS,
+ NPC_GRANDDARKNESS,
+ NPC_DARKSTRIKE,
+ NPC_DARKTHUNDER,
+ NPC_STOP,
+ NPC_WEAPONBRAKER,
+ NPC_ARMORBRAKE,
+ NPC_HELMBRAKE,
+ NPC_SHIELDBRAKE,
+ NPC_UNDEADATTACK,
+ NPC_CHANGEUNDEAD,
+ NPC_POWERUP,
+ NPC_AGIUP,
+ NPC_SIEGEMODE,
+ NPC_CALLSLAVE,
+ NPC_INVISIBLE,
+ NPC_RUN,
+
+ LK_AURABLADE,
+ LK_PARRYING,
+ LK_CONCENTRATION,
+ LK_TENSIONRELAX,
+ LK_BERSERK,
+ LK_FURY,
+ HP_ASSUMPTIO,
+ HP_BASILICA,
+ HP_MEDITATIO,
+ HW_SOULDRAIN,
+ HW_MAGICCRASHER,
+ HW_MAGICPOWER,
+ PA_PRESSURE,
+ PA_SACRIFICE,
+ PA_GOSPEL,
+ CH_PALMSTRIKE,
+ CH_TIGERFIST,
+ CH_CHAINCRUSH,
+ PF_HPCONVERSION,
+ PF_SOULCHANGE,
+ PF_SOULBURN,
+ ASC_KATAR,
+ ASC_HALLUCINATION,
+ ASC_EDP,
+ ASC_BREAKER,
+ SN_SIGHT,
+ SN_FALCONASSAULT,
+ SN_SHARPSHOOTING,
+ SN_WINDWALK,
+ WS_MELTDOWN,
+ WS_CREATECOIN,
+ WS_CREATENUGGET,
+ WS_CARTBOOST,
+ WS_SYSTEMCREATE,
+ ST_CHASEWALK,
+ ST_REJECTSWORD,
+ ST_STEALBACKPACK,
+ CR_ALCHEMY,
+ CR_SYNTHESISPOTION,
+ CG_ARROWVULCAN,
+ CG_MOONLIT,
+ CG_MARIONETTE,
+ LK_SPIRALPIERCE,
+ LK_HEADCRUSH,
+ LK_JOINTBEAT,
+ HW_NAPALMVULCAN,
+ CH_SOULCOLLECT,
+ PF_MINDBREAKER,
+ PF_MEMORIZE,
+ PF_FOGWALL,
+ PF_SPIDERWEB,
+ ASC_METEORASSAULT,
+ ASC_CDP,
+ WE_BABY,
+ WE_CALLPARENT,
+ WE_CALLBABY,
+
+ TK_RUN,
+ TK_READYSTORM,
+ TK_STORMKICK,
+ TK_READYDOWN,
+ TK_DOWNKICK,
+ TK_READYTURN,
+ TK_TURNKICK,
+ TK_READYCOUNTER,
+ TK_COUNTER,
+ TK_DODGE,
+ TK_JUMPKICK,
+ TK_HPTIME,
+ TK_SPTIME,
+ TK_POWER,
+ TK_SEVENWIND,
+ TK_HIGHJUMP,
+
+ SG_FEEL,
+ SG_SUN_WARM,
+ SG_MOON_WARM,
+ SG_STAR_WARM,
+ SG_SUN_COMFORT,
+ SG_MOON_COMFORT,
+ SG_STAR_COMFORT,
+ SG_HATE,
+ SG_SUN_ANGER,
+ SG_MOON_ANGER,
+ SG_STAR_ANGER,
+ SG_SUN_BLESS,
+ SG_MOON_BLESS,
+ SG_STAR_BLESS,
+ SG_DEVIL,
+ SG_FRIEND,
+ SG_KNOWLEDGE,
+ SG_FUSION,
+
+ SL_ALCHEMIST,
+ AM_BERSERKPITCHER,
+ SL_MONK,
+ SL_STAR,
+ SL_SAGE,
+ SL_CRUSADER,
+ SL_SUPERNOVICE,
+ SL_KNIGHT,
+ SL_WIZARD,
+ SL_PRIEST,
+ SL_BARDDANCER,
+ SL_ROGUE,
+ SL_ASSASIN,
+ SL_BLACKSMITH,
+ BS_ADRENALINE2,
+ SL_HUNTER,
+ SL_SOULLINKER,
+ SL_KAIZEL,
+ SL_KAAHI,
+ SL_KAUPE,
+ SL_KAITE,
+ SL_KAINA,
+ SL_STIN,
+ SL_STUN,
+ SL_SMA,
+ SL_SWOO,
+ SL_SKE,
+ SL_SKA,
+
+ SM_SELFPROVOKE,
+ NPC_EMOTION_ON,
+ ST_PRESERVE,
+ ST_FULLSTRIP,
+ WS_WEAPONREFINE,
+ CR_SLIMPITCHER,
+ CR_FULLPROTECTION,
+ PA_SHIELDCHAIN,
+ HP_MANARECHARGE,
+ PF_DOUBLECASTING,
+ HW_GANBANTEIN,
+ HW_GRAVITATION,
+ WS_CARTTERMINATION,
+ WS_OVERTHRUSTMAX,
+ CG_LONGINGFREEDOM,
+ CG_HERMODE,
+ CG_TAROTCARD,
+ CR_ACIDDEMONSTRATION,
+ CR_CULTIVATION,
+ ITEM_ENCHANTARMS,
+ TK_MISSION,
+ SL_HIGH,
+ KN_ONEHAND,
+ AM_TWILIGHT1,
+ AM_TWILIGHT2,
+ AM_TWILIGHT3,
+ HT_POWER,
+
+ GS_GLITTERING,
+ GS_FLING,
+ GS_TRIPLEACTION,
+ GS_BULLSEYE,
+ GS_MADNESSCANCEL,
+ GS_ADJUSTMENT,
+ GS_INCREASING,
+ GS_MAGICALBULLET,
+ GS_CRACKER,
+ GS_SINGLEACTION,
+ GS_SNAKEEYE,
+ GS_CHAINACTION,
+ GS_TRACKING,
+ GS_DISARM,
+ GS_PIERCINGSHOT,
+ GS_RAPIDSHOWER,
+ GS_DESPERADO,
+ GS_GATLINGFEVER,
+ GS_DUST,
+ GS_FULLBUSTER,
+ GS_SPREADATTACK,
+ GS_GROUNDDRIFT,
+
+ NJ_TOBIDOUGU,
+ NJ_SYURIKEN,
+ NJ_KUNAI,
+ NJ_HUUMA,
+ NJ_ZENYNAGE,
+ NJ_TATAMIGAESHI,
+ NJ_KASUMIKIRI,
+ NJ_SHADOWJUMP,
+ NJ_KIRIKAGE,
+ NJ_UTSUSEMI,
+ NJ_BUNSINJYUTSU,
+ NJ_NINPOU,
+ NJ_KOUENKA,
+ NJ_KAENSIN,
+ NJ_BAKUENRYU,
+ NJ_HYOUSENSOU,
+ NJ_SUITON,
+ NJ_HYOUSYOURAKU,
+ NJ_HUUJIN,
+ NJ_RAIGEKISAI,
+ NJ_KAMAITACHI,
+ NJ_NEN,
+ NJ_ISSEN,
+
+ MB_FIGHTING,
+ MB_NEUTRAL,
+ MB_TAIMING_PUTI,
+ MB_WHITEPOTION,
+ MB_MENTAL,
+ MB_CARDPITCHER,
+ MB_PETPITCHER,
+ MB_BODYSTUDY,
+ MB_BODYALTER,
+ MB_PETMEMORY,
+ MB_M_TELEPORT,
+ MB_B_GAIN,
+ MB_M_GAIN,
+ MB_MISSION,
+ MB_MUNAKKNOWLEDGE,
+ MB_MUNAKBALL,
+ MB_SCROLL,
+ MB_B_GATHERING,
+ MB_M_GATHERING,
+ MB_B_EXCLUDE,
+ MB_B_DRIFT,
+ MB_B_WALLRUSH,
+ MB_M_WALLRUSH,
+ MB_B_WALLSHIFT,
+ MB_M_WALLCRASH,
+ MB_M_REINCARNATION,
+ MB_B_EQUIP,
+
+ SL_DEATHKNIGHT,
+ SL_COLLECTOR,
+ SL_NINJA,
+ SL_GUNNER,
+ AM_TWILIGHT4,
+ DA_RESET,
+ DE_BERSERKAIZER,
+ DA_DARKPOWER,
+
+ DE_PASSIVE,
+ DE_PATTACK,
+ DE_PSPEED,
+ DE_PDEFENSE,
+ DE_PCRITICAL,
+ DE_PHP,
+ DE_PSP,
+ DE_RESET,
+ DE_RANKING,
+ DE_PTRIPLE,
+ DE_ENERGY,
+ DE_NIGHTMARE,
+ DE_SLASH,
+ DE_COIL,
+ DE_WAVE,
+ DE_REBIRTH,
+ DE_AURA,
+ DE_FREEZER,
+ DE_CHANGEATTACK,
+ DE_PUNISH,
+ DE_POISON,
+ DE_INSTANT,
+ DE_WARNING,
+ DE_RANKEDKNIFE,
+ DE_RANKEDGRADIUS,
+ DE_GAUGE,
+ DE_GTIME,
+ DE_GPAIN,
+ DE_GSKILL,
+ DE_GKILL,
+ DE_ACCEL,
+ DE_BLOCKDOUBLE,
+ DE_BLOCKMELEE,
+ DE_BLOCKFAR,
+ DE_FRONTATTACK,
+ DE_DANGERATTACK,
+ DE_TWINATTACK,
+ DE_WINDATTACK,
+ DE_WATERATTACK,
+
+ DA_ENERGY,
+ DA_CLOUD,
+ DA_FIRSTSLOT,
+ DA_HEADDEF,
+ DA_SPACE,
+ DA_TRANSFORM,
+ DA_EXPLOSION,
+ DA_REWARD,
+ DA_CRUSH,
+ DA_ITEMREBUILD,
+ DA_ILLUSION,
+ DA_NUETRALIZE,
+ DA_RUNNER,
+ DA_TRANSFER,
+ DA_WALL,
+ DA_ZENY,
+ DA_REVENGE,
+ DA_EARPLUG,
+ DA_CONTRACT,
+ DA_BLACK,
+ DA_DREAM,
+ DA_MAGICCART,
+ DA_COPY,
+ DA_CRYSTAL,
+ DA_EXP,
+ DA_CARTSWING,
+ DA_REBUILD,
+ DA_JOBCHANGE,
+ DA_EDARKNESS,
+ DA_EGUARDIAN,
+ DA_TIMEOUT,
+ ALL_TIMEIN,
+ DA_ZENYRANK,
+ DA_ACCESSORYMIX,
+
+ NPC_EARTHQUAKE,
+ NPC_FIREBREATH,
+ NPC_ICEBREATH,
+ NPC_THUNDERBREATH,
+ NPC_ACIDBREATH,
+ NPC_DARKNESSBREATH,
+ NPC_DRAGONFEAR,
+ NPC_BLEEDING,
+ NPC_PULSESTRIKE,
+ NPC_HELLJUDGEMENT,
+ NPC_WIDESILENCE,
+ NPC_WIDEFREEZE,
+ NPC_WIDEBLEEDING,
+ NPC_WIDESTONE,
+ NPC_WIDECONFUSE,
+ NPC_WIDESLEEP,
+ NPC_WIDESIGHT,
+ NPC_EVILLAND,
+ NPC_MAGICMIRROR,
+ NPC_SLOWCAST,
+ NPC_CRITICALWOUND,
+ NPC_EXPULSION,
+ NPC_STONESKIN,
+ NPC_ANTIMAGIC,
+ NPC_WIDECURSE,
+ NPC_WIDESTUN,
+ NPC_VAMPIRE_GIFT,
+ NPC_WIDESOULDRAIN,
+
+ ALL_INCCARRY,
+ NPC_TALK,
+ NPC_HELLPOWER,
+ NPC_WIDEHELLDIGNITY,
+ NPC_INVINCIBLE,
+ NPC_INVINCIBLEOFF,
+ NPC_ALLHEAL,
+ GM_SANDMAN,
+ CASH_BLESSING,
+ CASH_INCAGI,
+ CASH_ASSUMPTIO,
+ ALL_CATCRY,
+ ALL_PARTYFLEE,
+ ALL_ANGEL_PROTECT,
+ ALL_DREAM_SUMMERNIGHT,
+ NPC_CHANGEUNDEAD2,
+ ALL_REVERSEORCISH,
+ ALL_WEWISH,
+ ALL_SONKRAN,
+ NPC_WIDEHEALTHFEAR,
+ NPC_WIDEBODYBURNNING,
+ NPC_WIDEFROSTMISTY,
+ NPC_WIDECOLD,
+ NPC_WIDE_DEEP_SLEEP,
+ NPC_WIDESIREN,
+ NPC_VENOMFOG,
+ NPC_MILLENNIUMSHIELD,
+ NPC_COMET,
+
+ KN_CHARGEATK = 1001,
+ CR_SHRINK,
+ AS_SONICACCEL,
+ AS_VENOMKNIFE,
+ RG_CLOSECONFINE,
+ WZ_SIGHTBLASTER,
+ SA_CREATECON,
+ SA_ELEMENTWATER,
+ HT_PHANTASMIC,
+ BA_PANGVOICE,
+ DC_WINKCHARM,
+ BS_UNFAIRLYTRICK,
+ BS_GREED,
+ PR_REDEMPTIO,
+ MO_KITRANSLATION,
+ MO_BALKYOUNG,
+ SA_ELEMENTGROUND,
+ SA_ELEMENTFIRE,
+ SA_ELEMENTWIND,
+
+ RK_ENCHANTBLADE = 2001,
+ RK_SONICWAVE,
+ RK_DEATHBOUND,
+ RK_HUNDREDSPEAR,
+ RK_WINDCUTTER,
+ RK_IGNITIONBREAK,
+ RK_DRAGONTRAINING,
+ RK_DRAGONBREATH,
+ RK_DRAGONHOWLING,
+ RK_RUNEMASTERY,
+ RK_MILLENNIUMSHIELD,
+ RK_CRUSHSTRIKE,
+ RK_REFRESH,
+ RK_GIANTGROWTH,
+ RK_STONEHARDSKIN,
+ RK_VITALITYACTIVATION,
+ RK_STORMBLAST,
+ RK_FIGHTINGSPIRIT,
+ RK_ABUNDANCE,
+ RK_PHANTOMTHRUST,
+
+ GC_VENOMIMPRESS,
+ GC_CROSSIMPACT,
+ GC_DARKILLUSION,
+ GC_RESEARCHNEWPOISON,
+ GC_CREATENEWPOISON,
+ GC_ANTIDOTE,
+ GC_POISONINGWEAPON,
+ GC_WEAPONBLOCKING,
+ GC_COUNTERSLASH,
+ GC_WEAPONCRUSH,
+ GC_VENOMPRESSURE,
+ GC_POISONSMOKE,
+ GC_CLOAKINGEXCEED,
+ GC_PHANTOMMENACE,
+ GC_HALLUCINATIONWALK,
+ GC_ROLLINGCUTTER,
+ GC_CROSSRIPPERSLASHER,
+
+ AB_JUDEX,
+ AB_ANCILLA,
+ AB_ADORAMUS,
+ AB_CLEMENTIA,
+ AB_CANTO,
+ AB_CHEAL,
+ AB_EPICLESIS,
+ AB_PRAEFATIO,
+ AB_ORATIO,
+ AB_LAUDAAGNUS,
+ AB_LAUDARAMUS,
+ AB_EUCHARISTICA,
+ AB_RENOVATIO,
+ AB_HIGHNESSHEAL,
+ AB_CLEARANCE,
+ AB_EXPIATIO,
+ AB_DUPLELIGHT,
+ AB_DUPLELIGHT_MELEE,
+ AB_DUPLELIGHT_MAGIC,
+ AB_SILENTIUM,
+
+ WL_WHITEIMPRISON = 2201,
+ WL_SOULEXPANSION,
+ WL_FROSTMISTY,
+ WL_JACKFROST,
+ WL_MARSHOFABYSS,
+ WL_RECOGNIZEDSPELL,
+ WL_SIENNAEXECRATE,
+ WL_RADIUS,
+ WL_STASIS,
+ WL_DRAINLIFE,
+ WL_CRIMSONROCK,
+ WL_HELLINFERNO,
+ WL_COMET,
+ WL_CHAINLIGHTNING,
+ WL_CHAINLIGHTNING_ATK,
+ WL_EARTHSTRAIN,
+ WL_TETRAVORTEX,
+ WL_TETRAVORTEX_FIRE,
+ WL_TETRAVORTEX_WATER,
+ WL_TETRAVORTEX_WIND,
+ WL_TETRAVORTEX_GROUND,
+ WL_SUMMONFB,
+ WL_SUMMONBL,
+ WL_SUMMONWB,
+ WL_SUMMON_ATK_FIRE,
+ WL_SUMMON_ATK_WIND,
+ WL_SUMMON_ATK_WATER,
+ WL_SUMMON_ATK_GROUND,
+ WL_SUMMONSTONE,
+ WL_RELEASE,
+ WL_READING_SB,
+ WL_FREEZE_SP,
+
+ RA_ARROWSTORM,
+ RA_FEARBREEZE,
+ RA_RANGERMAIN,
+ RA_AIMEDBOLT,
+ RA_DETONATOR,
+ RA_ELECTRICSHOCKER,
+ RA_CLUSTERBOMB,
+ RA_WUGMASTERY,
+ RA_WUGRIDER,
+ RA_WUGDASH,
+ RA_WUGSTRIKE,
+ RA_WUGBITE,
+ RA_TOOTHOFWUG,
+ RA_SENSITIVEKEEN,
+ RA_CAMOUFLAGE,
+ RA_RESEARCHTRAP,
+ RA_MAGENTATRAP,
+ RA_COBALTTRAP,
+ RA_MAIZETRAP,
+ RA_VERDURETRAP,
+ RA_FIRINGTRAP,
+ RA_ICEBOUNDTRAP,
+
+ NC_MADOLICENCE,
+ NC_BOOSTKNUCKLE,
+ NC_PILEBUNKER,
+ NC_VULCANARM,
+ NC_FLAMELAUNCHER,
+ NC_COLDSLOWER,
+ NC_ARMSCANNON,
+ NC_ACCELERATION,
+ NC_HOVERING,
+ NC_F_SIDESLIDE,
+ NC_B_SIDESLIDE,
+ NC_MAINFRAME,
+ NC_SELFDESTRUCTION,
+ NC_SHAPESHIFT,
+ NC_EMERGENCYCOOL,
+ NC_INFRAREDSCAN,
+ NC_ANALYZE,
+ NC_MAGNETICFIELD,
+ NC_NEUTRALBARRIER,
+ NC_STEALTHFIELD,
+ NC_REPAIR,
+ NC_TRAININGAXE,
+ NC_RESEARCHFE,
+ NC_AXEBOOMERANG,
+ NC_POWERSWING,
+ NC_AXETORNADO,
+ NC_SILVERSNIPER,
+ NC_MAGICDECOY,
+ NC_DISJOINT,
+
+ SC_FATALMENACE,
+ SC_REPRODUCE,
+ SC_AUTOSHADOWSPELL,
+ SC_SHADOWFORM,
+ SC_TRIANGLESHOT,
+ SC_BODYPAINT,
+ SC_INVISIBILITY,
+ SC_DEADLYINFECT,
+ SC_ENERVATION,
+ SC_GROOMY,
+ SC_IGNORANCE,
+ SC_LAZINESS,
+ SC_UNLUCKY,
+ SC_WEAKNESS,
+ SC_STRIPACCESSARY,
+ SC_MANHOLE,
+ SC_DIMENSIONDOOR,
+ SC_CHAOSPANIC,
+ SC_MAELSTROM,
+ SC_BLOODYLUST,
+ SC_FEINTBOMB,
+
+ LG_CANNONSPEAR = 2307,
+ LG_BANISHINGPOINT,
+ LG_TRAMPLE,
+ LG_SHIELDPRESS,
+ LG_REFLECTDAMAGE,
+ LG_PINPOINTATTACK,
+ LG_FORCEOFVANGUARD,
+ LG_RAGEBURST,
+ LG_SHIELDSPELL,
+ LG_EXEEDBREAK,
+ LG_OVERBRAND,
+ LG_PRESTIGE,
+ LG_BANDING,
+ LG_MOONSLASHER,
+ LG_RAYOFGENESIS,
+ LG_PIETY,
+ LG_EARTHDRIVE,
+ LG_HESPERUSLIT,
+ LG_INSPIRATION,
+
+ SR_DRAGONCOMBO,
+ SR_SKYNETBLOW,
+ SR_EARTHSHAKER,
+ SR_FALLENEMPIRE,
+ SR_TIGERCANNON,
+ SR_HELLGATE,
+ SR_RAMPAGEBLASTER,
+ SR_CRESCENTELBOW,
+ SR_CURSEDCIRCLE,
+ SR_LIGHTNINGWALK,
+ SR_KNUCKLEARROW,
+ SR_WINDMILL,
+ SR_RAISINGDRAGON,
+ SR_GENTLETOUCH,
+ SR_ASSIMILATEPOWER,
+ SR_POWERVELOCITY,
+ SR_CRESCENTELBOW_AUTOSPELL,
+ SR_GATEOFHELL,
+ SR_GENTLETOUCH_QUIET,
+ SR_GENTLETOUCH_CURE,
+ SR_GENTLETOUCH_ENERGYGAIN,
+ SR_GENTLETOUCH_CHANGE,
+ SR_GENTLETOUCH_REVITALIZE,
+
+ WA_SWING_DANCE = 2350,
+ WA_SYMPHONY_OF_LOVER,
+ WA_MOONLIT_SERENADE,
+
+ MI_RUSH_WINDMILL = 2381,
+ MI_ECHOSONG,
+ MI_HARMONIZE,
+
+ WM_LESSON = 2412,
+ WM_METALICSOUND,
+ WM_REVERBERATION,
+ WM_REVERBERATION_MELEE,
+ WM_REVERBERATION_MAGIC,
+ WM_DOMINION_IMPULSE,
+ WM_SEVERE_RAINSTORM,
+ WM_POEMOFNETHERWORLD,
+ WM_VOICEOFSIREN,
+ WM_DEADHILLHERE,
+ WM_LULLABY_DEEPSLEEP,
+ WM_SIRCLEOFNATURE,
+ WM_RANDOMIZESPELL,
+ WM_GLOOMYDAY,
+ WM_GREAT_ECHO,
+ WM_SONG_OF_MANA,
+ WM_DANCE_WITH_WUG,
+ WM_SOUND_OF_DESTRUCTION,
+ WM_SATURDAY_NIGHT_FEVER,
+ WM_LERADS_DEW,
+ WM_MELODYOFSINK,
+ WM_BEYOND_OF_WARCRY,
+ WM_UNLIMITED_HUMMING_VOICE,
+
+ SO_FIREWALK = 2443,
+ SO_ELECTRICWALK,
+ SO_SPELLFIST,
+ SO_EARTHGRAVE,
+ SO_DIAMONDDUST,
+ SO_POISON_BUSTER,
+ SO_PSYCHIC_WAVE,
+ SO_CLOUD_KILL,
+ SO_STRIKING,
+ SO_WARMER,
+ SO_VACUUM_EXTREME,
+ SO_VARETYR_SPEAR,
+ SO_ARRULLO,
+ SO_EL_CONTROL,
+ SO_SUMMON_AGNI,
+ SO_SUMMON_AQUA,
+ SO_SUMMON_VENTUS,
+ SO_SUMMON_TERA,
+ SO_EL_ACTION,
+ SO_EL_ANALYSIS,
+ SO_EL_SYMPATHY,
+ SO_EL_CURE,
+ SO_FIRE_INSIGNIA,
+ SO_WATER_INSIGNIA,
+ SO_WIND_INSIGNIA,
+ SO_EARTH_INSIGNIA,
+
+ GN_TRAINING_SWORD = 2474,
+ GN_REMODELING_CART,
+ GN_CART_TORNADO,
+ GN_CARTCANNON,
+ GN_CARTBOOST,
+ GN_THORNS_TRAP,
+ GN_BLOOD_SUCKER,
+ GN_SPORE_EXPLOSION,
+ GN_WALLOFTHORN,
+ GN_CRAZYWEED,
+ GN_CRAZYWEED_ATK,
+ GN_DEMONIC_FIRE,
+ GN_FIRE_EXPANSION,
+ GN_FIRE_EXPANSION_SMOKE_POWDER,
+ GN_FIRE_EXPANSION_TEAR_GAS,
+ GN_FIRE_EXPANSION_ACID,
+ GN_HELLS_PLANT,
+ GN_HELLS_PLANT_ATK,
+ GN_MANDRAGORA,
+ GN_SLINGITEM,
+ GN_CHANGEMATERIAL,
+ GN_MIX_COOKING,
+ GN_MAKEBOMB,
+ GN_S_PHARMACY,
+ GN_SLINGITEM_RANGEMELEEATK,
+
+ AB_SECRAMENT = 2515,
+ WM_SEVERE_RAINSTORM_MELEE,
+ SR_HOWLINGOFLION,
+ SR_RIDEINLIGHTNING,
+ LG_OVERBRAND_BRANDISH,
+ LG_OVERBRAND_PLUSATK,
+
+ ALL_ODINS_RECALL = 2533,
+ RETURN_TO_ELDICASTES,
+ ALL_BUYING_STORE,
+ ALL_GUARDIAN_RECALL,
+ ALL_ODINS_POWER,
+ BEER_BOTTLE_CAP,
+ NPC_ASSASSINCROSS,
+ NPC_DISSONANCE,
+ NPC_UGLYDANCE,
+ ALL_TETANY,
+ ALL_RAY_OF_PROTECTION,
+ MC_CARTDECORATE,
+
+ KO_YAMIKUMO = 3001,
+ KO_RIGHT,
+ KO_LEFT,
+ KO_JYUMONJIKIRI,
+ KO_SETSUDAN,
+ KO_BAKURETSU,
+ KO_HAPPOKUNAI,
+ KO_MUCHANAGE,
+ KO_HUUMARANKA,
+ KO_MAKIBISHI,
+ KO_MEIKYOUSISUI,
+ KO_ZANZOU,
+ KO_KYOUGAKU,
+ KO_JYUSATSU,
+ KO_KAHU_ENTEN,
+ KO_HYOUHU_HUBUKI,
+ KO_KAZEHU_SEIRAN,
+ KO_DOHU_KOUKAI,
+ KO_KAIHOU,
+ KO_ZENKAI,
+ KO_GENWAKU,
+ KO_IZAYOI,
+ KG_KAGEHUMI,
+ KG_KYOMU,
+ KG_KAGEMUSYA,
+ OB_ZANGETSU,
+ OB_OBOROGENSOU,
+ OB_OBOROGENSOU_TRANSITION_ATK,
+ OB_AKAITSUKI,
+
+ ECL_SNOWFLIP = 3031,
+ ECL_PEONYMAMY,
+ ECL_SADAGUI,
+ ECL_SEQUOIADUST,
+ ECLAGE_RECALL,
+
+ HLIF_HEAL = 8001,
+ HLIF_AVOID,
+ HLIF_BRAIN,
+ HLIF_CHANGE,
+ HAMI_CASTLE,
+ HAMI_DEFENCE,
+ HAMI_SKIN,
+ HAMI_BLOODLUST,
+ HFLI_MOON,
+ HFLI_FLEET,
+ HFLI_SPEED,
+ HFLI_SBR44,
+ HVAN_CAPRICE,
+ HVAN_CHAOTIC,
+ HVAN_INSTRUCT,
+ HVAN_EXPLOSION,
+ MUTATION_BASEJOB,
+ MH_SUMMON_LEGION,
+ MH_NEEDLE_OF_PARALYZE,
+ MH_POISON_MIST,
+ MH_PAIN_KILLER,
+ MH_LIGHT_OF_REGENE,
+ MH_OVERED_BOOST,
+ MH_ERASER_CUTTER,
+ MH_XENO_SLASHER,
+ MH_SILENT_BREEZE,
+ MH_STYLE_CHANGE,
+ MH_SONIC_CRAW,
+ MH_SILVERVEIN_RUSH,
+ MH_MIDNIGHT_FRENZY,
+ MH_STAHL_HORN,
+ MH_GOLDENE_FERSE,
+ MH_STEINWAND,
+ MH_HEILIGE_STANGE,
+ MH_ANGRIFFS_MODUS,
+ MH_TINDER_BREAKER,
+ MH_CBC,
+ MH_EQC,
+ MH_MAGMA_FLOW,
+ MH_GRANITIC_ARMOR,
+ MH_LAVA_SLIDE,
+ MH_PYROCLASTIC,
+ MH_VOLCANIC_ASH,
+
+ MS_BASH = 8201,
+ MS_MAGNUM,
+ MS_BOWLINGBASH,
+ MS_PARRYING,
+ MS_REFLECTSHIELD,
+ MS_BERSERK,
+ MA_DOUBLE,
+ MA_SHOWER,
+ MA_SKIDTRAP,
+ MA_LANDMINE,
+ MA_SANDMAN,
+ MA_FREEZINGTRAP,
+ MA_REMOVETRAP,
+ MA_CHARGEARROW,
+ MA_SHARPSHOOTING,
+ ML_PIERCE,
+ ML_BRANDISH,
+ ML_SPIRALPIERCE,
+ ML_DEFENDER,
+ ML_AUTOGUARD,
+ ML_DEVOTION,
+ MER_MAGNIFICAT,
+ MER_QUICKEN,
+ MER_SIGHT,
+ MER_CRASH,
+ MER_REGAIN,
+ MER_TENDER,
+ MER_BENEDICTION,
+ MER_RECUPERATE,
+ MER_MENTALCURE,
+ MER_COMPRESS,
+ MER_PROVOKE,
+ MER_AUTOBERSERK,
+ MER_DECAGI,
+ MER_SCAPEGOAT,
+ MER_LEXDIVINA,
+ MER_ESTIMATION,
+ MER_KYRIE,
+ MER_BLESSING,
+ MER_INCAGI,
+
+ EL_CIRCLE_OF_FIRE = 8401,
+ EL_FIRE_CLOAK,
+ EL_FIRE_MANTLE,
+ EL_WATER_SCREEN,
+ EL_WATER_DROP,
+ EL_WATER_BARRIER,
+ EL_WIND_STEP,
+ EL_WIND_CURTAIN,
+ EL_ZEPHYR,
+ EL_SOLID_SKIN,
+ EL_STONE_SHIELD,
+ EL_POWER_OF_GAIA,
+ EL_PYROTECHNIC,
+ EL_HEATER,
+ EL_TROPIC,
+ EL_AQUAPLAY,
+ EL_COOLER,
+ EL_CHILLY_AIR,
+ EL_GUST,
+ EL_BLAST,
+ EL_WILD_STORM,
+ EL_PETROLOGY,
+ EL_CURSED_SOIL,
+ EL_UPHEAVAL,
+ EL_FIRE_ARROW,
+ EL_FIRE_BOMB,
+ EL_FIRE_BOMB_ATK,
+ EL_FIRE_WAVE,
+ EL_FIRE_WAVE_ATK,
+ EL_ICE_NEEDLE,
+ EL_WATER_SCREW,
+ EL_WATER_SCREW_ATK,
+ EL_TIDAL_WEAPON,
+ EL_WIND_SLASH,
+ EL_HURRICANE,
+ EL_HURRICANE_ATK,
+ EL_TYPOON_MIS,
+ EL_TYPOON_MIS_ATK,
+ EL_STONE_HAMMER,
+ EL_ROCK_CRUSHER,
+ EL_ROCK_CRUSHER_ATK,
+ EL_STONE_RAIN,
};
/// The client view ids for land skills.
enum {
- UNT_SAFETYWALL = 0x7e,
- UNT_FIREWALL,
- UNT_WARP_WAITING,
- UNT_WARP_ACTIVE,
- UNT_BENEDICTIO, //TODO
- UNT_SANCTUARY,
- UNT_MAGNUS,
- UNT_PNEUMA,
- UNT_DUMMYSKILL, //These show no effect on the client
- UNT_FIREPILLAR_WAITING,
- UNT_FIREPILLAR_ACTIVE,
- UNT_HIDDEN_TRAP, //TODO
- UNT_TRAP, //TODO
- UNT_HIDDEN_WARP_NPC, //TODO
- UNT_USED_TRAPS,
- UNT_ICEWALL,
- UNT_QUAGMIRE,
- UNT_BLASTMINE,
- UNT_SKIDTRAP,
- UNT_ANKLESNARE,
- UNT_VENOMDUST,
- UNT_LANDMINE,
- UNT_SHOCKWAVE,
- UNT_SANDMAN,
- UNT_FLASHER,
- UNT_FREEZINGTRAP,
- UNT_CLAYMORETRAP,
- UNT_TALKIEBOX,
- UNT_VOLCANO,
- UNT_DELUGE,
- UNT_VIOLENTGALE,
- UNT_LANDPROTECTOR,
- UNT_LULLABY,
- UNT_RICHMANKIM,
- UNT_ETERNALCHAOS,
- UNT_DRUMBATTLEFIELD,
- UNT_RINGNIBELUNGEN,
- UNT_ROKISWEIL,
- UNT_INTOABYSS,
- UNT_SIEGFRIED,
- UNT_DISSONANCE,
- UNT_WHISTLE,
- UNT_ASSASSINCROSS,
- UNT_POEMBRAGI,
- UNT_APPLEIDUN,
- UNT_UGLYDANCE,
- UNT_HUMMING,
- UNT_DONTFORGETME,
- UNT_FORTUNEKISS,
- UNT_SERVICEFORYOU,
- UNT_GRAFFITI,
- UNT_DEMONSTRATION,
- UNT_CALLFAMILY,
- UNT_GOSPEL,
- UNT_BASILICA,
- UNT_MOONLIT,
- UNT_FOGWALL,
- UNT_SPIDERWEB,
- UNT_GRAVITATION,
- UNT_HERMODE,
- UNT_KAENSIN, //TODO
- UNT_SUITON,
- UNT_TATAMIGAESHI,
- UNT_KAEN,
- UNT_GROUNDDRIFT_WIND,
- UNT_GROUNDDRIFT_DARK,
- UNT_GROUNDDRIFT_POISON,
- UNT_GROUNDDRIFT_WATER,
- UNT_GROUNDDRIFT_FIRE,
- UNT_DEATHWAVE, //TODO
- UNT_WATERATTACK, //TODO
- UNT_WINDATTACK, //TODO
- UNT_EARTHQUAKE, //TODO
- UNT_EVILLAND,
- UNT_DARK_RUNNER, //TODO
- UNT_DARK_TRANSFER, //TODO
- UNT_EPICLESIS,
- UNT_EARTHSTRAIN,
- UNT_MANHOLE,
- UNT_DIMENSIONDOOR,
- UNT_CHAOSPANIC,
- UNT_MAELSTROM,
- UNT_BLOODYLUST,
- UNT_FEINTBOMB,
- UNT_MAGENTATRAP,
- UNT_COBALTTRAP,
- UNT_MAIZETRAP,
- UNT_VERDURETRAP,
- UNT_FIRINGTRAP,
- UNT_ICEBOUNDTRAP,
- UNT_ELECTRICSHOCKER,
- UNT_CLUSTERBOMB,
- UNT_REVERBERATION,
- UNT_SEVERE_RAINSTORM,
- UNT_FIREWALK,
- UNT_ELECTRICWALK,
- UNT_NETHERWORLD,
- UNT_PSYCHIC_WAVE,
- UNT_CLOUD_KILL,
- UNT_POISONSMOKE,
- UNT_NEUTRALBARRIER,
- UNT_STEALTHFIELD,
- UNT_WARMER,
- UNT_THORNS_TRAP,
- UNT_WALLOFTHORN,
- UNT_DEMONIC_FIRE,
- UNT_FIRE_EXPANSION_SMOKE_POWDER,
- UNT_FIRE_EXPANSION_TEAR_GAS,
- UNT_HELLS_PLANT,
- UNT_VACUUM_EXTREME,
- UNT_BANDING,
- UNT_FIRE_MANTLE,
- UNT_WATER_BARRIER,
- UNT_ZEPHYR,
- UNT_POWER_OF_GAIA,
- UNT_FIRE_INSIGNIA,
- UNT_WATER_INSIGNIA,
- UNT_WIND_INSIGNIA,
- UNT_EARTH_INSIGNIA,
- UNT_POISON_MIST,
- UNT_LAVA_SLIDE,
- UNT_VOLCANIC_ASH,
- UNT_ZENKAI_WATER,
- UNT_ZENKAI_LAND,
- UNT_ZENKAI_FIRE,
- UNT_ZENKAI_WIND,
- UNT_MAKIBISHI,
- UNT_VENOMFOG,
-
- /**
- * Guild Auras
- **/
- UNT_GD_LEADERSHIP = 0xc1,
- UNT_GD_GLORYWOUNDS = 0xc2,
- UNT_GD_SOULCOLD = 0xc3,
- UNT_GD_HAWKEYES = 0xc4,
-
- UNT_MAX = 0x190
+ UNT_SAFETYWALL = 0x7e,
+ UNT_FIREWALL,
+ UNT_WARP_WAITING,
+ UNT_WARP_ACTIVE,
+ UNT_BENEDICTIO, //TODO
+ UNT_SANCTUARY,
+ UNT_MAGNUS,
+ UNT_PNEUMA,
+ UNT_DUMMYSKILL, //These show no effect on the client
+ UNT_FIREPILLAR_WAITING,
+ UNT_FIREPILLAR_ACTIVE,
+ UNT_HIDDEN_TRAP, //TODO
+ UNT_TRAP, //TODO
+ UNT_HIDDEN_WARP_NPC, //TODO
+ UNT_USED_TRAPS,
+ UNT_ICEWALL,
+ UNT_QUAGMIRE,
+ UNT_BLASTMINE,
+ UNT_SKIDTRAP,
+ UNT_ANKLESNARE,
+ UNT_VENOMDUST,
+ UNT_LANDMINE,
+ UNT_SHOCKWAVE,
+ UNT_SANDMAN,
+ UNT_FLASHER,
+ UNT_FREEZINGTRAP,
+ UNT_CLAYMORETRAP,
+ UNT_TALKIEBOX,
+ UNT_VOLCANO,
+ UNT_DELUGE,
+ UNT_VIOLENTGALE,
+ UNT_LANDPROTECTOR,
+ UNT_LULLABY,
+ UNT_RICHMANKIM,
+ UNT_ETERNALCHAOS,
+ UNT_DRUMBATTLEFIELD,
+ UNT_RINGNIBELUNGEN,
+ UNT_ROKISWEIL,
+ UNT_INTOABYSS,
+ UNT_SIEGFRIED,
+ UNT_DISSONANCE,
+ UNT_WHISTLE,
+ UNT_ASSASSINCROSS,
+ UNT_POEMBRAGI,
+ UNT_APPLEIDUN,
+ UNT_UGLYDANCE,
+ UNT_HUMMING,
+ UNT_DONTFORGETME,
+ UNT_FORTUNEKISS,
+ UNT_SERVICEFORYOU,
+ UNT_GRAFFITI,
+ UNT_DEMONSTRATION,
+ UNT_CALLFAMILY,
+ UNT_GOSPEL,
+ UNT_BASILICA,
+ UNT_MOONLIT,
+ UNT_FOGWALL,
+ UNT_SPIDERWEB,
+ UNT_GRAVITATION,
+ UNT_HERMODE,
+ UNT_KAENSIN, //TODO
+ UNT_SUITON,
+ UNT_TATAMIGAESHI,
+ UNT_KAEN,
+ UNT_GROUNDDRIFT_WIND,
+ UNT_GROUNDDRIFT_DARK,
+ UNT_GROUNDDRIFT_POISON,
+ UNT_GROUNDDRIFT_WATER,
+ UNT_GROUNDDRIFT_FIRE,
+ UNT_DEATHWAVE, //TODO
+ UNT_WATERATTACK, //TODO
+ UNT_WINDATTACK, //TODO
+ UNT_EARTHQUAKE, //TODO
+ UNT_EVILLAND,
+ UNT_DARK_RUNNER, //TODO
+ UNT_DARK_TRANSFER, //TODO
+ UNT_EPICLESIS,
+ UNT_EARTHSTRAIN,
+ UNT_MANHOLE,
+ UNT_DIMENSIONDOOR,
+ UNT_CHAOSPANIC,
+ UNT_MAELSTROM,
+ UNT_BLOODYLUST,
+ UNT_FEINTBOMB,
+ UNT_MAGENTATRAP,
+ UNT_COBALTTRAP,
+ UNT_MAIZETRAP,
+ UNT_VERDURETRAP,
+ UNT_FIRINGTRAP,
+ UNT_ICEBOUNDTRAP,
+ UNT_ELECTRICSHOCKER,
+ UNT_CLUSTERBOMB,
+ UNT_REVERBERATION,
+ UNT_SEVERE_RAINSTORM,
+ UNT_FIREWALK,
+ UNT_ELECTRICWALK,
+ UNT_NETHERWORLD,
+ UNT_PSYCHIC_WAVE,
+ UNT_CLOUD_KILL,
+ UNT_POISONSMOKE,
+ UNT_NEUTRALBARRIER,
+ UNT_STEALTHFIELD,
+ UNT_WARMER,
+ UNT_THORNS_TRAP,
+ UNT_WALLOFTHORN,
+ UNT_DEMONIC_FIRE,
+ UNT_FIRE_EXPANSION_SMOKE_POWDER,
+ UNT_FIRE_EXPANSION_TEAR_GAS,
+ UNT_HELLS_PLANT,
+ UNT_VACUUM_EXTREME,
+ UNT_BANDING,
+ UNT_FIRE_MANTLE,
+ UNT_WATER_BARRIER,
+ UNT_ZEPHYR,
+ UNT_POWER_OF_GAIA,
+ UNT_FIRE_INSIGNIA,
+ UNT_WATER_INSIGNIA,
+ UNT_WIND_INSIGNIA,
+ UNT_EARTH_INSIGNIA,
+ UNT_POISON_MIST,
+ UNT_LAVA_SLIDE,
+ UNT_VOLCANIC_ASH,
+ UNT_ZENKAI_WATER,
+ UNT_ZENKAI_LAND,
+ UNT_ZENKAI_FIRE,
+ UNT_ZENKAI_WIND,
+ UNT_MAKIBISHI,
+ UNT_VENOMFOG,
+
+ /**
+ * Guild Auras
+ **/
+ UNT_GD_LEADERSHIP = 0xc1,
+ UNT_GD_GLORYWOUNDS = 0xc2,
+ UNT_GD_SOULCOLD = 0xc3,
+ UNT_GD_HAWKEYES = 0xc4,
+
+ UNT_MAX = 0x190
};
/**
* Skill Unit Save
**/
-void skill_usave_add(struct map_session_data *sd, int skill_num, int skill_lv);
+void skill_usave_add(struct map_session_data * sd, int skill_num, int skill_lv);
void skill_usave_trigger(struct map_session_data *sd);
/**
* Skill Cool Downs - load from pc.c when the character logs in
**/
-void skill_cooldown_load(struct map_session_data *sd);
+void skill_cooldown_load(struct map_session_data * sd);
/**
* Warlock
**/
-#define MAX_SKILL_SPELLBOOK_DB 17
+#define MAX_SKILL_SPELLBOOK_DB 17
enum wl_spheres {
- WLS_FIRE = 0x44,
- WLS_WIND,
- WLS_WATER,
- WLS_STONE,
+ WLS_FIRE = 0x44,
+ WLS_WIND,
+ WLS_WATER,
+ WLS_STONE,
};
-int skill_spellbook(struct map_session_data *sd, int nameid);
+int skill_spellbook (struct map_session_data *sd, int nameid);
int skill_block_check(struct block_list *bl, enum sc_type type, int skillid);
/**
* Guilottine Cross
**/
#define MAX_SKILL_MAGICMUSHROOM_DB 23
struct s_skill_magicmushroom_db {
- int skillid;
+ int skillid;
};
extern struct s_skill_magicmushroom_db skill_magicmushroom_db[MAX_SKILL_MAGICMUSHROOM_DB];
/**
@@ -1834,16 +1838,16 @@ int skill_magicdecoy(struct map_session_data *sd, int nameid);
/**
* Guiltoine Cross
**/
-int skill_poisoningweapon(struct map_session_data *sd, int nameid);
+int skill_poisoningweapon( struct map_session_data *sd, int nameid);
enum gx_poison {
- PO_PARALYSE = 12717,
- PO_LEECHESEND,
- PO_OBLIVIONCURSE,
- PO_DEATHHURT,
- PO_TOXIN,
- PO_PYREXIA,
- PO_MAGICMUSHROOM,
- PO_VENOMBLEED
+ PO_PARALYSE = 12717,
+ PO_LEECHESEND,
+ PO_OBLIVIONCURSE,
+ PO_DEATHHURT,
+ PO_TOXIN,
+ PO_PYREXIA,
+ PO_MAGICMUSHROOM,
+ PO_VENOMBLEED
};
/**
* Auto Shadow Spell (Shadow Chaser)
@@ -1851,7 +1855,7 @@ enum gx_poison {
int skill_select_menu(struct map_session_data *sd,int skill_id);
int skill_elementalanalysis(struct map_session_data *sd, int n, int type, unsigned short *item_list); // Sorcerer Four Elemental Analisys.
-int skill_changematerial(struct map_session_data *sd, int n, unsigned short *item_list); // Genetic Change Material.
+int skill_changematerial(struct map_session_data *sd, int n, unsigned short *item_list); // Genetic Change Material.
int skill_get_elemental_type(int skill_id, int skill_lv);
#endif /* _SKILL_H_ */
diff --git a/src/map/status.c b/src/map/status.c
index c534233f8..a24011292 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -40,11 +40,12 @@
#include <math.h>
//Regen related flags.
-enum e_regen {
- RGN_HP = 0x01,
- RGN_SP = 0x02,
- RGN_SHP = 0x04,
- RGN_SSP = 0x08,
+enum e_regen
+{
+ RGN_HP = 0x01,
+ RGN_SP = 0x02,
+ RGN_SHP = 0x04,
+ RGN_SSP = 0x08,
};
static int max_weight_base[CLASS_COUNT];
@@ -55,17 +56,17 @@ static int sp_coefficient[CLASS_COUNT];
#ifdef RENEWAL_ASPD
static int aspd_base[CLASS_COUNT][MAX_WEAPON_TYPE+1];
#else
-static int aspd_base[CLASS_COUNT][MAX_WEAPON_TYPE]; //[blackhole89]
+static int aspd_base[CLASS_COUNT][MAX_WEAPON_TYPE]; //[blackhole89]
#endif
// bonus values and upgrade chances for refining equipment
static struct {
- int chance[MAX_REFINE]; // success chance
- int bonus[MAX_REFINE]; // cumulative fixed bonus damage
- int randombonus_max[MAX_REFINE]; // cumulative maximum random bonus damage
+ int chance[MAX_REFINE]; // success chance
+ int bonus[MAX_REFINE]; // cumulative fixed bonus damage
+ int randombonus_max[MAX_REFINE]; // cumulative maximum random bonus damage
} refine_info[REFINE_TYPE_MAX];
-static int atkmods[3][MAX_WEAPON_TYPE]; //ATK weapon modification for size (size_fix.txt)
+static int atkmods[3][MAX_WEAPON_TYPE]; //ATK weapon modification for size (size_fix.txt)
static char job_bonus[CLASS_COUNT][MAX_LEVEL];
static struct eri *sc_data_ers; //For sc_data entries
@@ -91,12 +92,12 @@ static unsigned int StatusChangeStateTable[SC_MAX]; // status -> flags
**/
sc_type status_skill2sc(int skill)
{
- int sk = skill_get_index(skill);
- if (sk == 0) {
- ShowError("status_skill2sc: Unsupported skill id %d\n", skill);
- return SC_NONE;
- }
- return SkillStatusChangeTable[sk];
+ int sk = skill_get_index(skill);
+ if( sk == 0 ) {
+ ShowError("status_skill2sc: Unsupported skill id %d\n", skill);
+ return SC_NONE;
+ }
+ return SkillStatusChangeTable[sk];
}
/**
@@ -107,12 +108,12 @@ sc_type status_skill2sc(int skill)
**/
int status_sc2skill(sc_type sc)
{
- if (sc < 0 || sc >= SC_MAX) {
- ShowError("status_sc2skill: Unsupported status change id %d\n", sc);
- return 0;
- }
+ if( sc < 0 || sc >= SC_MAX ) {
+ ShowError("status_sc2skill: Unsupported status change id %d\n", sc);
+ return 0;
+ }
- return StatusSkillChangeTable[sc];
+ return StatusSkillChangeTable[sc];
}
/**
@@ -122,12 +123,12 @@ int status_sc2skill(sc_type sc)
**/
unsigned int status_sc2scb_flag(sc_type sc)
{
- if (sc < 0 || sc >= SC_MAX) {
- ShowError("status_sc2scb_flag: Unsupported status change id %d\n", sc);
- return SCB_NONE;
- }
+ if( sc < 0 || sc >= SC_MAX ) {
+ ShowError("status_sc2scb_flag: Unsupported status change id %d\n", sc);
+ return SCB_NONE;
+ }
- return StatusChangeFlagTable[sc];
+ return StatusChangeFlagTable[sc];
}
/**
@@ -137,12 +138,12 @@ unsigned int status_sc2scb_flag(sc_type sc)
**/
int status_type2relevant_bl_types(int type)
{
- if (type < 0 || type >= SI_MAX) {
- ShowError("status_type2relevant_bl_types: Unsupported type %d\n", type);
- return SI_BLANK;
- }
+ if( type < 0 || type >= SI_MAX ) {
+ ShowError("status_type2relevant_bl_types: Unsupported type %d\n", type);
+ return SI_BLANK;
+ }
- return StatusRelevantBLTypes[type];
+ return StatusRelevantBLTypes[type];
}
#define add_sc(skill,sc) set_sc(skill,sc,SI_BLANK,SCB_NONE)
@@ -151,933 +152,932 @@ int status_type2relevant_bl_types(int type)
static void set_sc(int skill, sc_type sc, int icon, unsigned int flag)
{
- int sk = skill_get_index(skill);
- if (sk == 0) {
- ShowError("set_sc: Unsupported skill id %d\n", skill);
- return;
- }
- if (sc < 0 || sc >= SC_MAX) {
- ShowError("set_sc: Unsupported status change id %d\n", sc);
- return;
- }
-
- if (StatusSkillChangeTable[sc] == 0)
- StatusSkillChangeTable[sc] = skill;
- if (StatusIconChangeTable[sc] == SI_BLANK)
- StatusIconChangeTable[sc] = icon;
- StatusChangeFlagTable[sc] |= flag;
-
- if (SkillStatusChangeTable[sk] == SC_NONE)
- SkillStatusChangeTable[sk] = sc;
+ int sk = skill_get_index(skill);
+ if( sk == 0 ) {
+ ShowError("set_sc: Unsupported skill id %d\n", skill);
+ return;
+ }
+ if( sc < 0 || sc >= SC_MAX ) {
+ ShowError("set_sc: Unsupported status change id %d\n", sc);
+ return;
+ }
+
+ if( StatusSkillChangeTable[sc] == 0 )
+ StatusSkillChangeTable[sc] = skill;
+ if( StatusIconChangeTable[sc] == SI_BLANK )
+ StatusIconChangeTable[sc] = icon;
+ StatusChangeFlagTable[sc] |= flag;
+
+ if( SkillStatusChangeTable[sk] == SC_NONE )
+ SkillStatusChangeTable[sk] = sc;
}
-void initChangeTables(void)
-{
- int i;
-
- for (i = 0; i < SC_MAX; i++)
- StatusIconChangeTable[i] = SI_BLANK;
-
- for (i = 0; i < MAX_SKILL; i++)
- SkillStatusChangeTable[i] = SC_NONE;
-
- for (i = 0; i < SI_MAX; i++)
- StatusRelevantBLTypes[i] = BL_PC;
-
- memset(StatusSkillChangeTable, 0, sizeof(StatusSkillChangeTable));
- memset(StatusChangeFlagTable, 0, sizeof(StatusChangeFlagTable));
- memset(StatusChangeStateTable, 0, sizeof(StatusChangeStateTable));
-
-
- //First we define the skill for common ailments. These are used in skill_additional_effect through sc cards. [Skotlex]
- set_sc(NPC_PETRIFYATTACK , SC_STONE , SI_BLANK , SCB_DEF_ELE|SCB_DEF|SCB_MDEF);
- set_sc(NPC_WIDEFREEZE , SC_FREEZE , SI_BLANK , SCB_DEF_ELE|SCB_DEF|SCB_MDEF);
- set_sc(NPC_STUNATTACK , SC_STUN , SI_BLANK , SCB_NONE);
- set_sc(NPC_SLEEPATTACK , SC_SLEEP , SI_BLANK , SCB_NONE);
- set_sc(NPC_POISON , SC_POISON , SI_BLANK , SCB_DEF2|SCB_REGEN);
- set_sc(NPC_CURSEATTACK , SC_CURSE , SI_BLANK , SCB_LUK|SCB_BATK|SCB_WATK|SCB_SPEED);
- set_sc(NPC_SILENCEATTACK , SC_SILENCE , SI_BLANK , SCB_NONE);
- set_sc(NPC_WIDECONFUSE , SC_CONFUSION , SI_BLANK , SCB_NONE);
- set_sc(NPC_BLINDATTACK , SC_BLIND , SI_BLANK , SCB_HIT|SCB_FLEE);
- set_sc(NPC_BLEEDING , SC_BLEEDING , SI_BLEEDING , SCB_REGEN);
- set_sc(NPC_POISON , SC_DPOISON , SI_BLANK , SCB_DEF2|SCB_REGEN);
-
- //The main status definitions
- add_sc(SM_BASH , SC_STUN);
- set_sc(SM_PROVOKE , SC_PROVOKE , SI_PROVOKE , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK);
- add_sc(SM_MAGNUM , SC_WATK_ELEMENT);
- set_sc(SM_ENDURE , SC_ENDURE , SI_ENDURE , SCB_MDEF|SCB_DSPD);
- add_sc(MG_SIGHT , SC_SIGHT);
- add_sc(MG_SAFETYWALL , SC_SAFETYWALL);
- add_sc(MG_FROSTDIVER , SC_FREEZE);
- add_sc(MG_STONECURSE , SC_STONE);
- add_sc(AL_RUWACH , SC_RUWACH);
- add_sc(AL_PNEUMA , SC_PNEUMA);
- set_sc(AL_INCAGI , SC_INCREASEAGI , SI_INCREASEAGI , SCB_AGI|SCB_SPEED);
- set_sc(AL_DECAGI , SC_DECREASEAGI , SI_DECREASEAGI , SCB_AGI|SCB_SPEED);
- set_sc(AL_CRUCIS , SC_SIGNUMCRUCIS , SI_SIGNUMCRUCIS , SCB_DEF);
- set_sc(AL_ANGELUS , SC_ANGELUS , SI_ANGELUS , SCB_DEF2);
- set_sc(AL_BLESSING , SC_BLESSING , SI_BLESSING , SCB_STR|SCB_INT|SCB_DEX);
- set_sc(AC_CONCENTRATION , SC_CONCENTRATE , SI_CONCENTRATE , SCB_AGI|SCB_DEX);
- set_sc(TF_HIDING , SC_HIDING , SI_HIDING , SCB_SPEED);
- add_sc(TF_POISON , SC_POISON);
- set_sc(KN_TWOHANDQUICKEN , SC_TWOHANDQUICKEN , SI_TWOHANDQUICKEN , SCB_ASPD);
- add_sc(KN_AUTOCOUNTER , SC_AUTOCOUNTER);
- set_sc(PR_IMPOSITIO , SC_IMPOSITIO , SI_IMPOSITIO , SCB_WATK);
- set_sc(PR_SUFFRAGIUM , SC_SUFFRAGIUM , SI_SUFFRAGIUM , SCB_NONE);
- set_sc(PR_ASPERSIO , SC_ASPERSIO , SI_ASPERSIO , SCB_ATK_ELE);
- set_sc(PR_BENEDICTIO , SC_BENEDICTIO , SI_BENEDICTIO , SCB_DEF_ELE);
- set_sc(PR_SLOWPOISON , SC_SLOWPOISON , SI_SLOWPOISON , SCB_REGEN);
- set_sc(PR_KYRIE , SC_KYRIE , SI_KYRIE , SCB_NONE);
- set_sc(PR_MAGNIFICAT , SC_MAGNIFICAT , SI_MAGNIFICAT , SCB_REGEN);
- set_sc(PR_GLORIA , SC_GLORIA , SI_GLORIA , SCB_LUK);
- add_sc(PR_LEXDIVINA , SC_SILENCE);
- set_sc(PR_LEXAETERNA , SC_AETERNA , SI_AETERNA , SCB_NONE);
- add_sc(WZ_METEOR , SC_STUN);
- add_sc(WZ_VERMILION , SC_BLIND);
- add_sc(WZ_FROSTNOVA , SC_FREEZE);
- add_sc(WZ_STORMGUST , SC_FREEZE);
- set_sc(WZ_QUAGMIRE , SC_QUAGMIRE , SI_QUAGMIRE , SCB_AGI|SCB_DEX|SCB_ASPD|SCB_SPEED);
- set_sc(BS_ADRENALINE , SC_ADRENALINE , SI_ADRENALINE , SCB_ASPD);
- set_sc(BS_WEAPONPERFECT , SC_WEAPONPERFECTION, SI_WEAPONPERFECTION, SCB_NONE);
- set_sc(BS_OVERTHRUST , SC_OVERTHRUST , SI_OVERTHRUST , SCB_NONE);
- set_sc(BS_MAXIMIZE , SC_MAXIMIZEPOWER , SI_MAXIMIZEPOWER , SCB_REGEN);
- add_sc(HT_LANDMINE , SC_STUN);
- add_sc(HT_ANKLESNARE , SC_ANKLE);
- add_sc(HT_SANDMAN , SC_SLEEP);
- add_sc(HT_FLASHER , SC_BLIND);
- add_sc(HT_FREEZINGTRAP , SC_FREEZE);
- set_sc(AS_CLOAKING , SC_CLOAKING , SI_CLOAKING , SCB_CRI|SCB_SPEED);
- add_sc(AS_SONICBLOW , SC_STUN);
- set_sc(AS_ENCHANTPOISON , SC_ENCPOISON , SI_ENCPOISON , SCB_ATK_ELE);
- set_sc(AS_POISONREACT , SC_POISONREACT , SI_POISONREACT , SCB_NONE);
- add_sc(AS_VENOMDUST , SC_POISON);
- add_sc(AS_SPLASHER , SC_SPLASHER);
- set_sc(NV_TRICKDEAD , SC_TRICKDEAD , SI_TRICKDEAD , SCB_REGEN);
- set_sc(SM_AUTOBERSERK , SC_AUTOBERSERK , SI_AUTOBERSERK , SCB_NONE);
- add_sc(TF_SPRINKLESAND , SC_BLIND);
- add_sc(TF_THROWSTONE , SC_STUN);
- set_sc(MC_LOUD , SC_LOUD , SI_LOUD , SCB_STR);
- set_sc(MG_ENERGYCOAT , SC_ENERGYCOAT , SI_ENERGYCOAT , SCB_NONE);
- set_sc(NPC_EMOTION , SC_MODECHANGE , SI_BLANK , SCB_MODE);
- add_sc(NPC_EMOTION_ON , SC_MODECHANGE);
- set_sc(NPC_ATTRICHANGE , SC_ELEMENTALCHANGE , SI_ARMOR_PROPERTY , SCB_DEF_ELE);
- add_sc(NPC_CHANGEWATER , SC_ELEMENTALCHANGE);
- add_sc(NPC_CHANGEGROUND , SC_ELEMENTALCHANGE);
- add_sc(NPC_CHANGEFIRE , SC_ELEMENTALCHANGE);
- add_sc(NPC_CHANGEWIND , SC_ELEMENTALCHANGE);
- add_sc(NPC_CHANGEPOISON , SC_ELEMENTALCHANGE);
- add_sc(NPC_CHANGEHOLY , SC_ELEMENTALCHANGE);
- add_sc(NPC_CHANGEDARKNESS , SC_ELEMENTALCHANGE);
- add_sc(NPC_CHANGETELEKINESIS, SC_ELEMENTALCHANGE);
- add_sc(NPC_POISON , SC_POISON);
- add_sc(NPC_BLINDATTACK , SC_BLIND);
- add_sc(NPC_SILENCEATTACK , SC_SILENCE);
- add_sc(NPC_STUNATTACK , SC_STUN);
- add_sc(NPC_PETRIFYATTACK , SC_STONE);
- add_sc(NPC_CURSEATTACK , SC_CURSE);
- add_sc(NPC_SLEEPATTACK , SC_SLEEP);
- add_sc(NPC_MAGICALATTACK , SC_MAGICALATTACK);
- set_sc(NPC_KEEPING , SC_KEEPING , SI_BLANK , SCB_DEF);
- add_sc(NPC_DARKBLESSING , SC_COMA);
- set_sc(NPC_BARRIER , SC_BARRIER , SI_BLANK , SCB_MDEF|SCB_DEF);
- add_sc(NPC_DEFENDER , SC_ARMOR);
- add_sc(NPC_LICK , SC_STUN);
- set_sc(NPC_HALLUCINATION , SC_HALLUCINATION , SI_HALLUCINATION , SCB_NONE);
- add_sc(NPC_REBIRTH , SC_REBIRTH);
- add_sc(RG_RAID , SC_STUN);
+void initChangeTables(void) {
+ int i;
+
+ for (i = 0; i < SC_MAX; i++)
+ StatusIconChangeTable[i] = SI_BLANK;
+
+ for (i = 0; i < MAX_SKILL; i++)
+ SkillStatusChangeTable[i] = SC_NONE;
+
+ for (i = 0; i < SI_MAX; i++)
+ StatusRelevantBLTypes[i] = BL_PC;
+
+ memset(StatusSkillChangeTable, 0, sizeof(StatusSkillChangeTable));
+ memset(StatusChangeFlagTable, 0, sizeof(StatusChangeFlagTable));
+ memset(StatusChangeStateTable, 0, sizeof(StatusChangeStateTable));
+
+
+ //First we define the skill for common ailments. These are used in skill_additional_effect through sc cards. [Skotlex]
+ set_sc( NPC_PETRIFYATTACK , SC_STONE , SI_BLANK , SCB_DEF_ELE|SCB_DEF|SCB_MDEF );
+ set_sc( NPC_WIDEFREEZE , SC_FREEZE , SI_BLANK , SCB_DEF_ELE|SCB_DEF|SCB_MDEF );
+ set_sc( NPC_STUNATTACK , SC_STUN , SI_BLANK , SCB_NONE );
+ set_sc( NPC_SLEEPATTACK , SC_SLEEP , SI_BLANK , SCB_NONE );
+ set_sc( NPC_POISON , SC_POISON , SI_BLANK , SCB_DEF2|SCB_REGEN );
+ set_sc( NPC_CURSEATTACK , SC_CURSE , SI_BLANK , SCB_LUK|SCB_BATK|SCB_WATK|SCB_SPEED );
+ set_sc( NPC_SILENCEATTACK , SC_SILENCE , SI_BLANK , SCB_NONE );
+ set_sc( NPC_WIDECONFUSE , SC_CONFUSION , SI_BLANK , SCB_NONE );
+ set_sc( NPC_BLINDATTACK , SC_BLIND , SI_BLANK , SCB_HIT|SCB_FLEE );
+ set_sc( NPC_BLEEDING , SC_BLEEDING , SI_BLEEDING , SCB_REGEN );
+ set_sc( NPC_POISON , SC_DPOISON , SI_BLANK , SCB_DEF2|SCB_REGEN );
+
+ //The main status definitions
+ add_sc( SM_BASH , SC_STUN );
+ set_sc( SM_PROVOKE , SC_PROVOKE , SI_PROVOKE , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK );
+ add_sc( SM_MAGNUM , SC_WATK_ELEMENT );
+ set_sc( SM_ENDURE , SC_ENDURE , SI_ENDURE , SCB_MDEF|SCB_DSPD );
+ add_sc( MG_SIGHT , SC_SIGHT );
+ add_sc( MG_SAFETYWALL , SC_SAFETYWALL );
+ add_sc( MG_FROSTDIVER , SC_FREEZE );
+ add_sc( MG_STONECURSE , SC_STONE );
+ add_sc( AL_RUWACH , SC_RUWACH );
+ add_sc( AL_PNEUMA , SC_PNEUMA );
+ set_sc( AL_INCAGI , SC_INCREASEAGI , SI_INCREASEAGI , SCB_AGI|SCB_SPEED );
+ set_sc( AL_DECAGI , SC_DECREASEAGI , SI_DECREASEAGI , SCB_AGI|SCB_SPEED );
+ set_sc( AL_CRUCIS , SC_SIGNUMCRUCIS , SI_SIGNUMCRUCIS , SCB_DEF );
+ set_sc( AL_ANGELUS , SC_ANGELUS , SI_ANGELUS , SCB_DEF2 );
+ set_sc( AL_BLESSING , SC_BLESSING , SI_BLESSING , SCB_STR|SCB_INT|SCB_DEX );
+ set_sc( AC_CONCENTRATION , SC_CONCENTRATE , SI_CONCENTRATE , SCB_AGI|SCB_DEX );
+ set_sc( TF_HIDING , SC_HIDING , SI_HIDING , SCB_SPEED );
+ add_sc( TF_POISON , SC_POISON );
+ set_sc( KN_TWOHANDQUICKEN , SC_TWOHANDQUICKEN , SI_TWOHANDQUICKEN , SCB_ASPD );
+ add_sc( KN_AUTOCOUNTER , SC_AUTOCOUNTER );
+ set_sc( PR_IMPOSITIO , SC_IMPOSITIO , SI_IMPOSITIO , SCB_WATK );
+ set_sc( PR_SUFFRAGIUM , SC_SUFFRAGIUM , SI_SUFFRAGIUM , SCB_NONE );
+ set_sc( PR_ASPERSIO , SC_ASPERSIO , SI_ASPERSIO , SCB_ATK_ELE );
+ set_sc( PR_BENEDICTIO , SC_BENEDICTIO , SI_BENEDICTIO , SCB_DEF_ELE );
+ set_sc( PR_SLOWPOISON , SC_SLOWPOISON , SI_SLOWPOISON , SCB_REGEN );
+ set_sc( PR_KYRIE , SC_KYRIE , SI_KYRIE , SCB_NONE );
+ set_sc( PR_MAGNIFICAT , SC_MAGNIFICAT , SI_MAGNIFICAT , SCB_REGEN );
+ set_sc( PR_GLORIA , SC_GLORIA , SI_GLORIA , SCB_LUK );
+ add_sc( PR_LEXDIVINA , SC_SILENCE );
+ set_sc( PR_LEXAETERNA , SC_AETERNA , SI_AETERNA , SCB_NONE );
+ add_sc( WZ_METEOR , SC_STUN );
+ add_sc( WZ_VERMILION , SC_BLIND );
+ add_sc( WZ_FROSTNOVA , SC_FREEZE );
+ add_sc( WZ_STORMGUST , SC_FREEZE );
+ set_sc( WZ_QUAGMIRE , SC_QUAGMIRE , SI_QUAGMIRE , SCB_AGI|SCB_DEX|SCB_ASPD|SCB_SPEED );
+ set_sc( BS_ADRENALINE , SC_ADRENALINE , SI_ADRENALINE , SCB_ASPD );
+ set_sc( BS_WEAPONPERFECT , SC_WEAPONPERFECTION, SI_WEAPONPERFECTION, SCB_NONE );
+ set_sc( BS_OVERTHRUST , SC_OVERTHRUST , SI_OVERTHRUST , SCB_NONE );
+ set_sc( BS_MAXIMIZE , SC_MAXIMIZEPOWER , SI_MAXIMIZEPOWER , SCB_REGEN );
+ add_sc( HT_LANDMINE , SC_STUN );
+ add_sc( HT_ANKLESNARE , SC_ANKLE );
+ add_sc( HT_SANDMAN , SC_SLEEP );
+ add_sc( HT_FLASHER , SC_BLIND );
+ add_sc( HT_FREEZINGTRAP , SC_FREEZE );
+ set_sc( AS_CLOAKING , SC_CLOAKING , SI_CLOAKING , SCB_CRI|SCB_SPEED );
+ add_sc( AS_SONICBLOW , SC_STUN );
+ set_sc( AS_ENCHANTPOISON , SC_ENCPOISON , SI_ENCPOISON , SCB_ATK_ELE );
+ set_sc( AS_POISONREACT , SC_POISONREACT , SI_POISONREACT , SCB_NONE );
+ add_sc( AS_VENOMDUST , SC_POISON );
+ add_sc( AS_SPLASHER , SC_SPLASHER );
+ set_sc( NV_TRICKDEAD , SC_TRICKDEAD , SI_TRICKDEAD , SCB_REGEN );
+ set_sc( SM_AUTOBERSERK , SC_AUTOBERSERK , SI_AUTOBERSERK , SCB_NONE );
+ add_sc( TF_SPRINKLESAND , SC_BLIND );
+ add_sc( TF_THROWSTONE , SC_STUN );
+ set_sc( MC_LOUD , SC_LOUD , SI_LOUD , SCB_STR );
+ set_sc( MG_ENERGYCOAT , SC_ENERGYCOAT , SI_ENERGYCOAT , SCB_NONE );
+ set_sc( NPC_EMOTION , SC_MODECHANGE , SI_BLANK , SCB_MODE );
+ add_sc( NPC_EMOTION_ON , SC_MODECHANGE );
+ set_sc( NPC_ATTRICHANGE , SC_ELEMENTALCHANGE , SI_ARMOR_PROPERTY , SCB_DEF_ELE );
+ add_sc( NPC_CHANGEWATER , SC_ELEMENTALCHANGE );
+ add_sc( NPC_CHANGEGROUND , SC_ELEMENTALCHANGE );
+ add_sc( NPC_CHANGEFIRE , SC_ELEMENTALCHANGE );
+ add_sc( NPC_CHANGEWIND , SC_ELEMENTALCHANGE );
+ add_sc( NPC_CHANGEPOISON , SC_ELEMENTALCHANGE );
+ add_sc( NPC_CHANGEHOLY , SC_ELEMENTALCHANGE );
+ add_sc( NPC_CHANGEDARKNESS , SC_ELEMENTALCHANGE );
+ add_sc( NPC_CHANGETELEKINESIS, SC_ELEMENTALCHANGE );
+ add_sc( NPC_POISON , SC_POISON );
+ add_sc( NPC_BLINDATTACK , SC_BLIND );
+ add_sc( NPC_SILENCEATTACK , SC_SILENCE );
+ add_sc( NPC_STUNATTACK , SC_STUN );
+ add_sc( NPC_PETRIFYATTACK , SC_STONE );
+ add_sc( NPC_CURSEATTACK , SC_CURSE );
+ add_sc( NPC_SLEEPATTACK , SC_SLEEP );
+ add_sc( NPC_MAGICALATTACK , SC_MAGICALATTACK );
+ set_sc( NPC_KEEPING , SC_KEEPING , SI_BLANK , SCB_DEF );
+ add_sc( NPC_DARKBLESSING , SC_COMA );
+ set_sc( NPC_BARRIER , SC_BARRIER , SI_BLANK , SCB_MDEF|SCB_DEF );
+ add_sc( NPC_DEFENDER , SC_ARMOR );
+ add_sc( NPC_LICK , SC_STUN );
+ set_sc( NPC_HALLUCINATION , SC_HALLUCINATION , SI_HALLUCINATION , SCB_NONE );
+ add_sc( NPC_REBIRTH , SC_REBIRTH );
+ add_sc( RG_RAID , SC_STUN );
#ifdef RENEWAL
- add_sc(RG_RAID , SC_RAID);
- add_sc(RG_BACKSTAP , SC_STUN);
+ add_sc( RG_RAID , SC_RAID );
+ add_sc( RG_BACKSTAP , SC_STUN );
#endif
- set_sc(RG_STRIPWEAPON , SC_STRIPWEAPON , SI_STRIPWEAPON , SCB_WATK);
- set_sc(RG_STRIPSHIELD , SC_STRIPSHIELD , SI_STRIPSHIELD , SCB_DEF);
- set_sc(RG_STRIPARMOR , SC_STRIPARMOR , SI_STRIPARMOR , SCB_VIT);
- set_sc(RG_STRIPHELM , SC_STRIPHELM , SI_STRIPHELM , SCB_INT);
- add_sc(AM_ACIDTERROR , SC_BLEEDING);
- set_sc(AM_CP_WEAPON , SC_CP_WEAPON , SI_CP_WEAPON , SCB_NONE);
- set_sc(AM_CP_SHIELD , SC_CP_SHIELD , SI_CP_SHIELD , SCB_NONE);
- set_sc(AM_CP_ARMOR , SC_CP_ARMOR , SI_CP_ARMOR , SCB_NONE);
- set_sc(AM_CP_HELM , SC_CP_HELM , SI_CP_HELM , SCB_NONE);
- set_sc(CR_AUTOGUARD , SC_AUTOGUARD , SI_AUTOGUARD , SCB_NONE);
- add_sc(CR_SHIELDCHARGE , SC_STUN);
- set_sc(CR_REFLECTSHIELD , SC_REFLECTSHIELD , SI_REFLECTSHIELD , SCB_NONE);
- add_sc(CR_HOLYCROSS , SC_BLIND);
- add_sc(CR_GRANDCROSS , SC_BLIND);
- add_sc(CR_DEVOTION , SC_DEVOTION);
- set_sc(CR_PROVIDENCE , SC_PROVIDENCE , SI_PROVIDENCE , SCB_ALL);
- set_sc(CR_DEFENDER , SC_DEFENDER , SI_DEFENDER , SCB_SPEED|SCB_ASPD);
- set_sc(CR_SPEARQUICKEN , SC_SPEARQUICKEN , SI_SPEARQUICKEN , SCB_ASPD|SCB_CRI|SCB_FLEE);
- set_sc(MO_STEELBODY , SC_STEELBODY , SI_STEELBODY , SCB_DEF|SCB_MDEF|SCB_ASPD|SCB_SPEED);
- add_sc(MO_BLADESTOP , SC_BLADESTOP_WAIT);
- add_sc(MO_BLADESTOP , SC_BLADESTOP);
- set_sc(MO_EXPLOSIONSPIRITS , SC_EXPLOSIONSPIRITS, SI_EXPLOSIONSPIRITS, SCB_CRI|SCB_REGEN);
- set_sc(MO_EXTREMITYFIST , SC_EXTREMITYFIST , SI_BLANK , SCB_REGEN);
+ set_sc( RG_STRIPWEAPON , SC_STRIPWEAPON , SI_STRIPWEAPON , SCB_WATK );
+ set_sc( RG_STRIPSHIELD , SC_STRIPSHIELD , SI_STRIPSHIELD , SCB_DEF );
+ set_sc( RG_STRIPARMOR , SC_STRIPARMOR , SI_STRIPARMOR , SCB_VIT );
+ set_sc( RG_STRIPHELM , SC_STRIPHELM , SI_STRIPHELM , SCB_INT );
+ add_sc( AM_ACIDTERROR , SC_BLEEDING );
+ set_sc( AM_CP_WEAPON , SC_CP_WEAPON , SI_CP_WEAPON , SCB_NONE );
+ set_sc( AM_CP_SHIELD , SC_CP_SHIELD , SI_CP_SHIELD , SCB_NONE );
+ set_sc( AM_CP_ARMOR , SC_CP_ARMOR , SI_CP_ARMOR , SCB_NONE );
+ set_sc( AM_CP_HELM , SC_CP_HELM , SI_CP_HELM , SCB_NONE );
+ set_sc( CR_AUTOGUARD , SC_AUTOGUARD , SI_AUTOGUARD , SCB_NONE );
+ add_sc( CR_SHIELDCHARGE , SC_STUN );
+ set_sc( CR_REFLECTSHIELD , SC_REFLECTSHIELD , SI_REFLECTSHIELD , SCB_NONE );
+ add_sc( CR_HOLYCROSS , SC_BLIND );
+ add_sc( CR_GRANDCROSS , SC_BLIND );
+ add_sc( CR_DEVOTION , SC_DEVOTION );
+ set_sc( CR_PROVIDENCE , SC_PROVIDENCE , SI_PROVIDENCE , SCB_ALL );
+ set_sc( CR_DEFENDER , SC_DEFENDER , SI_DEFENDER , SCB_SPEED|SCB_ASPD );
+ set_sc( CR_SPEARQUICKEN , SC_SPEARQUICKEN , SI_SPEARQUICKEN , SCB_ASPD|SCB_CRI|SCB_FLEE );
+ set_sc( MO_STEELBODY , SC_STEELBODY , SI_STEELBODY , SCB_DEF|SCB_MDEF|SCB_ASPD|SCB_SPEED );
+ add_sc( MO_BLADESTOP , SC_BLADESTOP_WAIT );
+ add_sc( MO_BLADESTOP , SC_BLADESTOP );
+ set_sc( MO_EXPLOSIONSPIRITS , SC_EXPLOSIONSPIRITS, SI_EXPLOSIONSPIRITS, SCB_CRI|SCB_REGEN );
+ set_sc( MO_EXTREMITYFIST , SC_EXTREMITYFIST , SI_BLANK , SCB_REGEN );
#ifdef RENEWAL
- set_sc(MO_EXTREMITYFIST , SC_EXTREMITYFIST2 , SI_EXTREMITYFIST , SCB_NONE);
+ set_sc( MO_EXTREMITYFIST , SC_EXTREMITYFIST2 , SI_EXTREMITYFIST , SCB_NONE );
#endif
- add_sc(SA_MAGICROD , SC_MAGICROD);
- set_sc(SA_AUTOSPELL , SC_AUTOSPELL , SI_AUTOSPELL , SCB_NONE);
- set_sc(SA_FLAMELAUNCHER , SC_FIREWEAPON , SI_FIREWEAPON , SCB_ATK_ELE);
- set_sc(SA_FROSTWEAPON , SC_WATERWEAPON , SI_WATERWEAPON , SCB_ATK_ELE);
- set_sc(SA_LIGHTNINGLOADER , SC_WINDWEAPON , SI_WINDWEAPON , SCB_ATK_ELE);
- set_sc(SA_SEISMICWEAPON , SC_EARTHWEAPON , SI_EARTHWEAPON , SCB_ATK_ELE);
- set_sc(SA_VOLCANO , SC_VOLCANO , SI_LANDENDOW , SCB_WATK);
- set_sc(SA_DELUGE , SC_DELUGE , SI_LANDENDOW , SCB_MAXHP);
- set_sc(SA_VIOLENTGALE , SC_VIOLENTGALE , SI_LANDENDOW , SCB_FLEE);
- add_sc(SA_REVERSEORCISH , SC_ORCISH);
- add_sc(SA_COMA , SC_COMA);
- set_sc(BD_ENCORE , SC_DANCING , SI_BLANK , SCB_SPEED|SCB_REGEN);
- add_sc(BD_RICHMANKIM , SC_RICHMANKIM);
- set_sc(BD_ETERNALCHAOS , SC_ETERNALCHAOS , SI_BLANK , SCB_DEF2);
- set_sc(BD_DRUMBATTLEFIELD , SC_DRUMBATTLE , SI_BLANK , SCB_WATK|SCB_DEF);
- set_sc(BD_RINGNIBELUNGEN , SC_NIBELUNGEN , SI_BLANK , SCB_WATK);
- add_sc(BD_ROKISWEIL , SC_ROKISWEIL);
- add_sc(BD_INTOABYSS , SC_INTOABYSS);
- set_sc(BD_SIEGFRIED , SC_SIEGFRIED , SI_BLANK , SCB_ALL);
- add_sc(BA_FROSTJOKER , SC_FREEZE);
- set_sc(BA_WHISTLE , SC_WHISTLE , SI_BLANK , SCB_FLEE|SCB_FLEE2);
- set_sc(BA_ASSASSINCROSS , SC_ASSNCROS , SI_BLANK , SCB_ASPD);
- add_sc(BA_POEMBRAGI , SC_POEMBRAGI);
- set_sc(BA_APPLEIDUN , SC_APPLEIDUN , SI_BLANK , SCB_MAXHP);
- add_sc(DC_SCREAM , SC_STUN);
- set_sc(DC_HUMMING , SC_HUMMING , SI_BLANK , SCB_HIT);
- set_sc(DC_DONTFORGETME , SC_DONTFORGETME , SI_BLANK , SCB_SPEED|SCB_ASPD);
- set_sc(DC_FORTUNEKISS , SC_FORTUNE , SI_BLANK , SCB_CRI);
- set_sc(DC_SERVICEFORYOU , SC_SERVICE4U , SI_BLANK , SCB_ALL);
- add_sc(NPC_DARKCROSS , SC_BLIND);
- add_sc(NPC_GRANDDARKNESS , SC_BLIND);
- set_sc(NPC_STOP , SC_STOP , SI_STOP , SCB_NONE);
- set_sc(NPC_WEAPONBRAKER , SC_BROKENWEAPON , SI_BROKENWEAPON , SCB_NONE);
- set_sc(NPC_ARMORBRAKE , SC_BROKENARMOR , SI_BROKENARMOR , SCB_NONE);
- set_sc(NPC_CHANGEUNDEAD , SC_CHANGEUNDEAD , SI_UNDEAD , SCB_DEF_ELE);
- set_sc(NPC_POWERUP , SC_INCHITRATE , SI_BLANK , SCB_HIT);
- set_sc(NPC_AGIUP , SC_INCFLEERATE , SI_BLANK , SCB_FLEE);
- add_sc(NPC_INVISIBLE , SC_CLOAKING);
- set_sc(LK_AURABLADE , SC_AURABLADE , SI_AURABLADE , SCB_NONE);
- set_sc(LK_PARRYING , SC_PARRYING , SI_PARRYING , SCB_NONE);
- set_sc(LK_CONCENTRATION , SC_CONCENTRATION , SI_CONCENTRATION , SCB_BATK|SCB_WATK|SCB_HIT|SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_DSPD);
- set_sc(LK_TENSIONRELAX , SC_TENSIONRELAX , SI_TENSIONRELAX , SCB_REGEN);
- set_sc(LK_BERSERK , SC_BERSERK , SI_BERSERK , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2|SCB_FLEE|SCB_SPEED|SCB_ASPD|SCB_MAXHP|SCB_REGEN);
- set_sc(HP_ASSUMPTIO , SC_ASSUMPTIO , SI_ASSUMPTIO , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2);
- add_sc(HP_BASILICA , SC_BASILICA);
- set_sc(HW_MAGICPOWER , SC_MAGICPOWER , SI_MAGICPOWER , SCB_MATK);
- add_sc(PA_SACRIFICE , SC_SACRIFICE);
- set_sc(PA_GOSPEL , SC_GOSPEL , SI_BLANK , SCB_SPEED|SCB_ASPD);
- add_sc(PA_GOSPEL , SC_SCRESIST);
- add_sc(CH_TIGERFIST , SC_STOP);
- set_sc(ASC_EDP , SC_EDP , SI_EDP , SCB_NONE);
- set_sc(SN_SIGHT , SC_TRUESIGHT , SI_TRUESIGHT , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK|SCB_CRI|SCB_HIT);
- set_sc(SN_WINDWALK , SC_WINDWALK , SI_WINDWALK , SCB_FLEE|SCB_SPEED);
- set_sc(WS_MELTDOWN , SC_MELTDOWN , SI_MELTDOWN , SCB_NONE);
- set_sc(WS_CARTBOOST , SC_CARTBOOST , SI_CARTBOOST , SCB_SPEED);
- set_sc(ST_CHASEWALK , SC_CHASEWALK , SI_BLANK , SCB_SPEED);
- set_sc(ST_REJECTSWORD , SC_REJECTSWORD , SI_REJECTSWORD , SCB_NONE);
- add_sc(ST_REJECTSWORD , SC_AUTOCOUNTER);
- set_sc(CG_MARIONETTE , SC_MARIONETTE , SI_MARIONETTE , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK);
- set_sc(CG_MARIONETTE , SC_MARIONETTE2 , SI_MARIONETTE2 , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK);
- add_sc(LK_SPIRALPIERCE , SC_STOP);
- add_sc(LK_HEADCRUSH , SC_BLEEDING);
- set_sc(LK_JOINTBEAT , SC_JOINTBEAT , SI_JOINTBEAT , SCB_BATK|SCB_DEF2|SCB_SPEED|SCB_ASPD);
- add_sc(HW_NAPALMVULCAN , SC_CURSE);
- set_sc(PF_MINDBREAKER , SC_MINDBREAKER , SI_BLANK , SCB_MATK|SCB_MDEF2);
- add_sc(PF_MEMORIZE , SC_MEMORIZE);
- add_sc(PF_FOGWALL , SC_FOGWALL);
- set_sc(PF_SPIDERWEB , SC_SPIDERWEB , SI_BLANK , SCB_FLEE);
- set_sc(WE_BABY , SC_BABY , SI_BABY , SCB_NONE);
- set_sc(TK_RUN , SC_RUN , SI_RUN , SCB_SPEED|SCB_DSPD);
- set_sc(TK_RUN , SC_SPURT , SI_SPURT , SCB_STR);
- set_sc(TK_READYSTORM , SC_READYSTORM , SI_READYSTORM , SCB_NONE);
- set_sc(TK_READYDOWN , SC_READYDOWN , SI_READYDOWN , SCB_NONE);
- add_sc(TK_DOWNKICK , SC_STUN);
- set_sc(TK_READYTURN , SC_READYTURN , SI_READYTURN , SCB_NONE);
- set_sc(TK_READYCOUNTER , SC_READYCOUNTER , SI_READYCOUNTER , SCB_NONE);
- set_sc(TK_DODGE , SC_DODGE , SI_DODGE , SCB_NONE);
- set_sc(TK_SPTIME , SC_EARTHSCROLL , SI_EARTHSCROLL , SCB_NONE);
- add_sc(TK_SEVENWIND , SC_SEVENWIND);
- set_sc(TK_SEVENWIND , SC_GHOSTWEAPON , SI_GHOSTWEAPON , SCB_ATK_ELE);
- set_sc(TK_SEVENWIND , SC_SHADOWWEAPON , SI_SHADOWWEAPON , SCB_ATK_ELE);
- set_sc(SG_SUN_WARM , SC_WARM , SI_WARM , SCB_NONE);
- add_sc(SG_MOON_WARM , SC_WARM);
- add_sc(SG_STAR_WARM , SC_WARM);
- set_sc(SG_SUN_COMFORT , SC_SUN_COMFORT , SI_SUN_COMFORT , SCB_DEF2);
- set_sc(SG_MOON_COMFORT , SC_MOON_COMFORT , SI_MOON_COMFORT , SCB_FLEE);
- set_sc(SG_STAR_COMFORT , SC_STAR_COMFORT , SI_STAR_COMFORT , SCB_ASPD);
- add_sc(SG_FRIEND , SC_SKILLRATE_UP);
- set_sc(SG_KNOWLEDGE , SC_KNOWLEDGE , SI_BLANK , SCB_ALL);
- set_sc(SG_FUSION , SC_FUSION , SI_BLANK , SCB_SPEED);
- set_sc(BS_ADRENALINE2 , SC_ADRENALINE2 , SI_ADRENALINE2 , SCB_ASPD);
- set_sc(SL_KAIZEL , SC_KAIZEL , SI_KAIZEL , SCB_NONE);
- set_sc(SL_KAAHI , SC_KAAHI , SI_KAAHI , SCB_NONE);
- set_sc(SL_KAUPE , SC_KAUPE , SI_KAUPE , SCB_NONE);
- set_sc(SL_KAITE , SC_KAITE , SI_KAITE , SCB_NONE);
- add_sc(SL_STUN , SC_STUN);
- set_sc(SL_SWOO , SC_SWOO , SI_BLANK , SCB_SPEED);
- set_sc(SL_SKE , SC_SKE , SI_BLANK , SCB_BATK|SCB_WATK|SCB_DEF|SCB_DEF2);
- set_sc(SL_SKA , SC_SKA , SI_BLANK , SCB_DEF|SCB_MDEF|SCB_ASPD);
- set_sc(SL_SMA , SC_SMA , SI_SMA , SCB_NONE);
- set_sc(SM_SELFPROVOKE , SC_PROVOKE , SI_PROVOKE , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK);
- set_sc(ST_PRESERVE , SC_PRESERVE , SI_PRESERVE , SCB_NONE);
- set_sc(PF_DOUBLECASTING , SC_DOUBLECAST , SI_DOUBLECAST , SCB_NONE);
- set_sc(HW_GRAVITATION , SC_GRAVITATION , SI_BLANK , SCB_ASPD);
- add_sc(WS_CARTTERMINATION , SC_STUN);
- set_sc(WS_OVERTHRUSTMAX , SC_MAXOVERTHRUST , SI_MAXOVERTHRUST , SCB_NONE);
- set_sc(CG_LONGINGFREEDOM , SC_LONGING , SI_BLANK , SCB_SPEED|SCB_ASPD);
- add_sc(CG_HERMODE , SC_HERMODE);
- set_sc(ITEM_ENCHANTARMS , SC_ENCHANTARMS , SI_BLANK , SCB_ATK_ELE);
- set_sc(SL_HIGH , SC_SPIRIT , SI_SPIRIT , SCB_ALL);
- set_sc(KN_ONEHAND , SC_ONEHAND , SI_ONEHAND , SCB_ASPD);
- set_sc(GS_FLING , SC_FLING , SI_BLANK , SCB_DEF|SCB_DEF2);
- add_sc(GS_CRACKER , SC_STUN);
- add_sc(GS_DISARM , SC_STRIPWEAPON);
- add_sc(GS_PIERCINGSHOT , SC_BLEEDING);
- set_sc(GS_MADNESSCANCEL , SC_MADNESSCANCEL , SI_MADNESSCANCEL , SCB_BATK|SCB_ASPD);
- set_sc(GS_ADJUSTMENT , SC_ADJUSTMENT , SI_ADJUSTMENT , SCB_HIT|SCB_FLEE);
- set_sc(GS_INCREASING , SC_INCREASING , SI_ACCURACY , SCB_AGI|SCB_DEX|SCB_HIT);
- set_sc(GS_GATLINGFEVER , SC_GATLINGFEVER , SI_GATLINGFEVER , SCB_BATK|SCB_FLEE|SCB_SPEED|SCB_ASPD);
- set_sc(NJ_TATAMIGAESHI , SC_TATAMIGAESHI , SI_BLANK , SCB_NONE);
- set_sc(NJ_SUITON , SC_SUITON , SI_BLANK , SCB_AGI|SCB_SPEED);
- add_sc(NJ_HYOUSYOURAKU , SC_FREEZE);
- set_sc(NJ_NEN , SC_NEN , SI_NEN , SCB_STR|SCB_INT);
- set_sc(NJ_UTSUSEMI , SC_UTSUSEMI , SI_UTSUSEMI , SCB_NONE);
- set_sc(NJ_BUNSINJYUTSU , SC_BUNSINJYUTSU , SI_BUNSINJYUTSU , SCB_DYE);
-
- add_sc(NPC_ICEBREATH , SC_FREEZE);
- add_sc(NPC_ACIDBREATH , SC_POISON);
- add_sc(NPC_HELLJUDGEMENT , SC_CURSE);
- add_sc(NPC_WIDESILENCE , SC_SILENCE);
- add_sc(NPC_WIDEFREEZE , SC_FREEZE);
- add_sc(NPC_WIDEBLEEDING , SC_BLEEDING);
- add_sc(NPC_WIDESTONE , SC_STONE);
- add_sc(NPC_WIDECONFUSE , SC_CONFUSION);
- add_sc(NPC_WIDESLEEP , SC_SLEEP);
- add_sc(NPC_WIDESIGHT , SC_SIGHT);
- add_sc(NPC_EVILLAND , SC_BLIND);
- add_sc(NPC_MAGICMIRROR , SC_MAGICMIRROR);
- set_sc(NPC_SLOWCAST , SC_SLOWCAST , SI_SLOWCAST , SCB_NONE);
- set_sc(NPC_CRITICALWOUND , SC_CRITICALWOUND , SI_CRITICALWOUND , SCB_NONE);
- set_sc(NPC_STONESKIN , SC_ARMORCHANGE , SI_BLANK , SCB_DEF|SCB_MDEF);
- add_sc(NPC_ANTIMAGIC , SC_ARMORCHANGE);
- add_sc(NPC_WIDECURSE , SC_CURSE);
- add_sc(NPC_WIDESTUN , SC_STUN);
-
- set_sc(NPC_HELLPOWER , SC_HELLPOWER , SI_HELLPOWER , SCB_NONE);
- set_sc(NPC_WIDEHELLDIGNITY , SC_HELLPOWER , SI_HELLPOWER , SCB_NONE);
- set_sc(NPC_INVINCIBLE , SC_INVINCIBLE , SI_INVINCIBLE , SCB_SPEED);
- set_sc(NPC_INVINCIBLEOFF , SC_INVINCIBLEOFF , SI_BLANK , SCB_SPEED);
-
- set_sc(CASH_BLESSING , SC_BLESSING , SI_BLESSING , SCB_STR|SCB_INT|SCB_DEX);
- set_sc(CASH_INCAGI , SC_INCREASEAGI , SI_INCREASEAGI , SCB_AGI|SCB_SPEED);
- set_sc(CASH_ASSUMPTIO , SC_ASSUMPTIO , SI_ASSUMPTIO , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2);
-
- set_sc(ALL_PARTYFLEE , SC_PARTYFLEE , SI_PARTYFLEE , SCB_NONE);
- set_sc(ALL_ODINS_POWER , SC_ODINS_POWER , SI_ODINS_POWER , SCB_MATK|SCB_BATK|SCB_MDEF|SCB_DEF);
-
- set_sc(CR_SHRINK , SC_SHRINK , SI_SHRINK , SCB_NONE);
- set_sc(RG_CLOSECONFINE , SC_CLOSECONFINE2 , SI_CLOSECONFINE2 , SCB_NONE);
- set_sc(RG_CLOSECONFINE , SC_CLOSECONFINE , SI_CLOSECONFINE , SCB_FLEE);
- set_sc(WZ_SIGHTBLASTER , SC_SIGHTBLASTER , SI_SIGHTBLASTER , SCB_NONE);
- set_sc(DC_WINKCHARM , SC_WINKCHARM , SI_WINKCHARM , SCB_NONE);
- add_sc(MO_BALKYOUNG , SC_STUN);
- add_sc(SA_ELEMENTWATER , SC_ELEMENTALCHANGE);
- add_sc(SA_ELEMENTFIRE , SC_ELEMENTALCHANGE);
- add_sc(SA_ELEMENTGROUND , SC_ELEMENTALCHANGE);
- add_sc(SA_ELEMENTWIND , SC_ELEMENTALCHANGE);
-
- set_sc(HLIF_AVOID , SC_AVOID , SI_BLANK , SCB_SPEED);
- set_sc(HLIF_CHANGE , SC_CHANGE , SI_BLANK , SCB_VIT|SCB_INT);
- set_sc(HFLI_FLEET , SC_FLEET , SI_BLANK , SCB_ASPD|SCB_BATK|SCB_WATK);
- set_sc(HFLI_SPEED , SC_SPEED , SI_BLANK , SCB_FLEE);
- set_sc(HAMI_DEFENCE , SC_DEFENCE , SI_BLANK , SCB_DEF);
- set_sc(HAMI_BLOODLUST , SC_BLOODLUST , SI_BLANK , SCB_BATK|SCB_WATK);
-
- // Homunculus S
- add_sc(MH_STAHL_HORN, SC_STUN);
- set_sc(MH_ANGRIFFS_MODUS, SC_ANGRIFFS_MODUS, SI_ANGRIFFS_MODUS, SCB_BATK | SCB_DEF | SCB_FLEE | SCB_MAXHP);
- set_sc(MH_GOLDENE_FERSE, SC_GOLDENE_FERSE, SI_GOLDENE_FERSE, SCB_ASPD|SCB_MAXHP);
- add_sc(MH_STEINWAND, SC_SAFETYWALL);
- add_sc(MH_ERASER_CUTTER, SC_ERASER_CUTTER);
- set_sc(MH_OVERED_BOOST, SC_OVERED_BOOST, SI_BLANK, SCB_FLEE|SCB_ASPD);
- add_sc(MH_LIGHT_OF_REGENE, SC_LIGHT_OF_REGENE);
- set_sc(MH_VOLCANIC_ASH, SC_ASH, SI_VOLCANIC_ASH, SCB_DEF|SCB_DEF2|SCB_HIT|SCB_BATK|SCB_FLEE);
- set_sc(MH_GRANITIC_ARMOR, SC_GRANITIC_ARMOR, SI_GRANITIC_ARMOR, SCB_NONE);
- set_sc(MH_MAGMA_FLOW, SC_MAGMA_FLOW, SI_MAGMA_FLOW, SCB_NONE);
- set_sc(MH_PYROCLASTIC, SC_PYROCLASTIC, SI_PYROCLASTIC, SCB_BATK|SCB_ATK_ELE);
- add_sc(MH_LAVA_SLIDE, SC_BURNING);
- set_sc(MH_NEEDLE_OF_PARALYZE, SC_PARALYSIS, SI_NEEDLE_OF_PARALYZE, SCB_DEF2);
- add_sc(MH_POISON_MIST, SC_BLIND);
- set_sc(MH_PAIN_KILLER, SC_PAIN_KILLER, SI_PAIN_KILLER, SCB_ASPD);
-
- add_sc(MH_STYLE_CHANGE, SC_STYLE_CHANGE);
-
-
- add_sc(MER_CRASH , SC_STUN);
- set_sc(MER_PROVOKE , SC_PROVOKE , SI_PROVOKE , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK);
- add_sc(MS_MAGNUM , SC_WATK_ELEMENT);
- add_sc(MER_SIGHT , SC_SIGHT);
- set_sc(MER_DECAGI , SC_DECREASEAGI , SI_DECREASEAGI , SCB_AGI|SCB_SPEED);
- set_sc(MER_MAGNIFICAT , SC_MAGNIFICAT , SI_MAGNIFICAT , SCB_REGEN);
- add_sc(MER_LEXDIVINA , SC_SILENCE);
- add_sc(MA_LANDMINE , SC_STUN);
- add_sc(MA_SANDMAN , SC_SLEEP);
- add_sc(MA_FREEZINGTRAP , SC_FREEZE);
- set_sc(MER_AUTOBERSERK , SC_AUTOBERSERK , SI_AUTOBERSERK , SCB_NONE);
- set_sc(ML_AUTOGUARD , SC_AUTOGUARD , SI_AUTOGUARD , SCB_NONE);
- set_sc(MS_REFLECTSHIELD , SC_REFLECTSHIELD , SI_REFLECTSHIELD , SCB_NONE);
- set_sc(ML_DEFENDER , SC_DEFENDER , SI_DEFENDER , SCB_SPEED|SCB_ASPD);
- set_sc(MS_PARRYING , SC_PARRYING , SI_PARRYING , SCB_NONE);
- set_sc(MS_BERSERK , SC_BERSERK , SI_BERSERK , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2|SCB_FLEE|SCB_SPEED|SCB_ASPD|SCB_MAXHP|SCB_REGEN);
- add_sc(ML_SPIRALPIERCE , SC_STOP);
- set_sc(MER_QUICKEN , SC_MERC_QUICKEN , SI_BLANK , SCB_ASPD);
- add_sc(ML_DEVOTION , SC_DEVOTION);
- set_sc(MER_KYRIE , SC_KYRIE , SI_KYRIE , SCB_NONE);
- set_sc(MER_BLESSING , SC_BLESSING , SI_BLESSING , SCB_STR|SCB_INT|SCB_DEX);
- set_sc(MER_INCAGI , SC_INCREASEAGI , SI_INCREASEAGI , SCB_AGI|SCB_SPEED);
-
- set_sc(GD_LEADERSHIP , SC_LEADERSHIP , SI_BLANK , SCB_STR);
- set_sc(GD_GLORYWOUNDS , SC_GLORYWOUNDS , SI_BLANK , SCB_VIT);
- set_sc(GD_SOULCOLD , SC_SOULCOLD , SI_BLANK , SCB_AGI);
- set_sc(GD_HAWKEYES , SC_HAWKEYES , SI_BLANK , SCB_DEX);
-
- set_sc(GD_BATTLEORDER , SC_BATTLEORDERS , SI_BLANK , SCB_STR|SCB_INT|SCB_DEX);
- set_sc(GD_REGENERATION , SC_REGENERATION , SI_BLANK , SCB_REGEN);
-
- /**
- * Rune Knight
- **/
- set_sc(RK_ENCHANTBLADE , SC_ENCHANTBLADE , SI_ENCHANTBLADE , SCB_NONE);
- set_sc(RK_DRAGONHOWLING , SC_FEAR , SI_BLANK , SCB_FLEE|SCB_HIT);
- set_sc(RK_DEATHBOUND , SC_DEATHBOUND , SI_DEATHBOUND , SCB_NONE);
- set_sc(RK_WINDCUTTER , SC_FEAR , SI_BLANK , SCB_FLEE|SCB_HIT);
- add_sc(RK_DRAGONBREATH , SC_BURNING);
- set_sc(RK_MILLENNIUMSHIELD , SC_MILLENNIUMSHIELD , SI_REUSE_MILLENNIUMSHIELD , SCB_NONE);
- set_sc(RK_REFRESH , SC_REFRESH , SI_REFRESH , SCB_NONE);
- set_sc(RK_GIANTGROWTH , SC_GIANTGROWTH , SI_GIANTGROWTH , SCB_STR);
- set_sc(RK_STONEHARDSKIN , SC_STONEHARDSKIN , SI_STONEHARDSKIN , SCB_NONE);
- set_sc(RK_VITALITYACTIVATION, SC_VITALITYACTIVATION, SI_VITALITYACTIVATION, SCB_REGEN);
- set_sc(RK_FIGHTINGSPIRIT , SC_FIGHTINGSPIRIT , SI_FIGHTINGSPIRIT , SCB_WATK|SCB_ASPD);
- set_sc(RK_ABUNDANCE , SC_ABUNDANCE , SI_ABUNDANCE , SCB_NONE);
- /**
- * GC Guillotine Cross
- **/
- set_sc_with_vfx(GC_VENOMIMPRESS , SC_VENOMIMPRESS , SI_VENOMIMPRESS , SCB_NONE);
- set_sc(GC_POISONINGWEAPON , SC_POISONINGWEAPON , SI_POISONINGWEAPON , SCB_NONE);
- set_sc(GC_WEAPONBLOCKING , SC_WEAPONBLOCKING , SI_WEAPONBLOCKING , SCB_NONE);
- set_sc(GC_CLOAKINGEXCEED , SC_CLOAKINGEXCEED , SI_CLOAKINGEXCEED , SCB_SPEED);
- set_sc(GC_HALLUCINATIONWALK , SC_HALLUCINATIONWALK, SI_HALLUCINATIONWALK, SCB_FLEE);
- set_sc(GC_ROLLINGCUTTER , SC_ROLLINGCUTTER , SI_ROLLINGCUTTER , SCB_NONE);
- /**
- * Arch Bishop
- **/
- set_sc(AB_ADORAMUS , SC_ADORAMUS , SI_ADORAMUS , SCB_AGI|SCB_SPEED);
- add_sc(AB_CLEMENTIA , SC_BLESSING);
- add_sc(AB_CANTO , SC_INCREASEAGI);
- set_sc(AB_EPICLESIS , SC_EPICLESIS , SI_EPICLESIS , SCB_MAXHP);
- add_sc(AB_PRAEFATIO , SC_KYRIE);
- set_sc_with_vfx(AB_ORATIO , SC_ORATIO , SI_ORATIO , SCB_NONE);
- set_sc(AB_LAUDAAGNUS , SC_LAUDAAGNUS , SI_LAUDAAGNUS , SCB_VIT);
- set_sc(AB_LAUDARAMUS , SC_LAUDARAMUS , SI_LAUDARAMUS , SCB_LUK);
- set_sc(AB_RENOVATIO , SC_RENOVATIO , SI_RENOVATIO , SCB_REGEN);
- set_sc(AB_EXPIATIO , SC_EXPIATIO , SI_EXPIATIO , SCB_ATK_ELE);
- set_sc(AB_DUPLELIGHT , SC_DUPLELIGHT , SI_DUPLELIGHT , SCB_NONE);
- set_sc(AB_SECRAMENT , SC_SECRAMENT , SI_SECRAMENT , SCB_NONE);
- /**
- * Warlock
- **/
- add_sc(WL_WHITEIMPRISON , SC_WHITEIMPRISON);
- set_sc_with_vfx(WL_FROSTMISTY , SC_FREEZING , SI_FROSTMISTY , SCB_ASPD|SCB_SPEED|SCB_DEF|SCB_DEF2);
- set_sc(WL_MARSHOFABYSS , SC_MARSHOFABYSS , SI_MARSHOFABYSS , SCB_SPEED|SCB_FLEE|SCB_DEF|SCB_MDEF);
- set_sc(WL_RECOGNIZEDSPELL , SC_RECOGNIZEDSPELL , SI_RECOGNIZEDSPELL , SCB_MATK);
- set_sc(WL_STASIS , SC_STASIS , SI_STASIS , SCB_NONE);
- /**
- * Ranger
- **/
- set_sc(RA_FEARBREEZE , SC_FEARBREEZE , SI_FEARBREEZE , SCB_NONE);
- set_sc(RA_ELECTRICSHOCKER , SC_ELECTRICSHOCKER , SI_ELECTRICSHOCKER , SCB_NONE);
- set_sc(RA_WUGDASH , SC_WUGDASH , SI_WUGDASH , SCB_SPEED);
- set_sc(RA_CAMOUFLAGE , SC_CAMOUFLAGE , SI_CAMOUFLAGE , SCB_SPEED);
- add_sc(RA_MAGENTATRAP , SC_ELEMENTALCHANGE);
- add_sc(RA_COBALTTRAP , SC_ELEMENTALCHANGE);
- add_sc(RA_MAIZETRAP , SC_ELEMENTALCHANGE);
- add_sc(RA_VERDURETRAP , SC_ELEMENTALCHANGE);
- add_sc(RA_FIRINGTRAP , SC_BURNING);
- set_sc_with_vfx(RA_ICEBOUNDTRAP , SC_FREEZING , SI_FROSTMISTY , SCB_NONE);
- /**
- * Mechanic
- **/
- set_sc(NC_ACCELERATION , SC_ACCELERATION , SI_ACCELERATION , SCB_SPEED);
- set_sc(NC_HOVERING , SC_HOVERING , SI_HOVERING , SCB_SPEED);
- set_sc(NC_SHAPESHIFT , SC_SHAPESHIFT , SI_SHAPESHIFT , SCB_DEF_ELE);
- set_sc(NC_INFRAREDSCAN , SC_INFRAREDSCAN , SI_INFRAREDSCAN , SCB_FLEE);
- set_sc(NC_ANALYZE , SC_ANALYZE , SI_ANALYZE , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2);
- set_sc(NC_MAGNETICFIELD , SC_MAGNETICFIELD , SI_MAGNETICFIELD , SCB_NONE);
- set_sc(NC_NEUTRALBARRIER , SC_NEUTRALBARRIER , SI_NEUTRALBARRIER , SCB_NONE);
- set_sc(NC_STEALTHFIELD , SC_STEALTHFIELD , SI_STEALTHFIELD , SCB_NONE);
- /**
- * Royal Guard
- **/
- set_sc(LG_REFLECTDAMAGE , SC_REFLECTDAMAGE , SI_LG_REFLECTDAMAGE, SCB_NONE);
- set_sc(LG_FORCEOFVANGUARD , SC_FORCEOFVANGUARD , SI_FORCEOFVANGUARD , SCB_MAXHP|SCB_DEF);
- set_sc(LG_EXEEDBREAK , SC_EXEEDBREAK , SI_EXEEDBREAK , SCB_NONE);
- set_sc(LG_PRESTIGE , SC_PRESTIGE , SI_PRESTIGE , SCB_DEF);
- set_sc(LG_BANDING , SC_BANDING , SI_BANDING , SCB_DEF2|SCB_WATK); // Renewal: atk2 & def2
- set_sc(LG_PIETY , SC_BENEDICTIO , SI_BENEDICTIO , SCB_DEF_ELE);
- set_sc(LG_EARTHDRIVE , SC_EARTHDRIVE , SI_EARTHDRIVE , SCB_DEF|SCB_ASPD);
- set_sc(LG_INSPIRATION , SC_INSPIRATION , SI_INSPIRATION , SCB_MAXHP|SCB_WATK|SCB_HIT|SCB_VIT|SCB_AGI|SCB_STR|SCB_DEX|SCB_INT|SCB_LUK);
- set_sc(LG_SHIELDSPELL , SC_SHIELDSPELL_DEF , SI_SHIELDSPELL_DEF , SCB_WATK);
- set_sc(LG_SHIELDSPELL , SC_SHIELDSPELL_REF , SI_SHIELDSPELL_REF , SCB_DEF);
- /**
- * Shadow Chaser
- **/
- set_sc(SC_REPRODUCE , SC__REPRODUCE , SI_REPRODUCE , SCB_NONE);
- set_sc(SC_AUTOSHADOWSPELL , SC__AUTOSHADOWSPELL, SI_AUTOSHADOWSPELL , SCB_NONE);
- set_sc(SC_SHADOWFORM , SC__SHADOWFORM , SI_SHADOWFORM , SCB_NONE);
- set_sc(SC_BODYPAINT , SC__BODYPAINT , SI_BODYPAINT , SCB_ASPD);
- set_sc(SC_INVISIBILITY , SC__INVISIBILITY , SI_INVISIBILITY , SCB_ASPD|SCB_CRI|SCB_ATK_ELE);
- set_sc(SC_DEADLYINFECT , SC__DEADLYINFECT , SI_DEADLYINFECT , SCB_NONE);
- set_sc(SC_ENERVATION , SC__ENERVATION , SI_ENERVATION , SCB_BATK);
- set_sc(SC_GROOMY , SC__GROOMY , SI_GROOMY , SCB_ASPD|SCB_HIT|SCB_SPEED);
- set_sc(SC_IGNORANCE , SC__IGNORANCE , SI_IGNORANCE , SCB_NONE);
- set_sc(SC_LAZINESS , SC__LAZINESS , SI_LAZINESS , SCB_FLEE);
- set_sc(SC_UNLUCKY , SC__UNLUCKY , SI_UNLUCKY , SCB_CRI|SCB_FLEE2);
- set_sc(SC_WEAKNESS , SC__WEAKNESS , SI_WEAKNESS , SCB_FLEE2|SCB_MAXHP);
- set_sc(SC_STRIPACCESSARY , SC__STRIPACCESSORY , SI_STRIPACCESSARY , SCB_DEX|SCB_INT|SCB_LUK);
- set_sc_with_vfx(SC_MANHOLE , SC__MANHOLE , SI_MANHOLE , SCB_NONE);
- add_sc(SC_CHAOSPANIC , SC_CONFUSION);
- set_sc_with_vfx(SC_BLOODYLUST , SC__BLOODYLUST , SI_BLOODYLUST , SCB_DEF | SCB_DEF2 | SCB_MDEF | SCB_MDEF2 | SCB_FLEE | SCB_SPEED | SCB_ASPD | SCB_MAXHP | SCB_REGEN);
- /**
- * Sura
- **/
- add_sc(SR_DRAGONCOMBO , SC_STUN);
- add_sc(SR_EARTHSHAKER , SC_STUN);
- set_sc(SR_CRESCENTELBOW , SC_CRESCENTELBOW , SI_CRESCENTELBOW , SCB_NONE);
- set_sc_with_vfx(SR_CURSEDCIRCLE , SC_CURSEDCIRCLE_TARGET, SI_CURSEDCIRCLE_TARGET , SCB_NONE);
- set_sc(SR_LIGHTNINGWALK , SC_LIGHTNINGWALK , SI_LIGHTNINGWALK , SCB_NONE);
- set_sc(SR_RAISINGDRAGON , SC_RAISINGDRAGON , SI_RAISINGDRAGON , SCB_REGEN|SCB_MAXHP|SCB_MAXSP);
- set_sc(SR_GENTLETOUCH_ENERGYGAIN, SC_GT_ENERGYGAIN , SI_GENTLETOUCH_ENERGYGAIN, SCB_NONE);
- set_sc(SR_GENTLETOUCH_CHANGE , SC_GT_CHANGE , SI_GENTLETOUCH_CHANGE , SCB_ASPD|SCB_MDEF|SCB_MAXHP);
- set_sc(SR_GENTLETOUCH_REVITALIZE, SC_GT_REVITALIZE , SI_GENTLETOUCH_REVITALIZE, SCB_MAXHP|SCB_REGEN);
- /**
- * Wanderer / Minstrel
- **/
- set_sc(WA_SWING_DANCE , SC_SWINGDANCE , SI_SWINGDANCE , SCB_SPEED|SCB_ASPD);
- set_sc(WA_SYMPHONY_OF_LOVER , SC_SYMPHONYOFLOVER , SI_SYMPHONYOFLOVERS , SCB_MDEF);
- set_sc(WA_MOONLIT_SERENADE , SC_MOONLITSERENADE , SI_MOONLITSERENADE , SCB_MATK);
- set_sc(MI_RUSH_WINDMILL , SC_RUSHWINDMILL , SI_RUSHWINDMILL , SCB_BATK);
- set_sc(MI_ECHOSONG , SC_ECHOSONG , SI_ECHOSONG , SCB_DEF2);
- set_sc(MI_HARMONIZE , SC_HARMONIZE , SI_HARMONIZE , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK);
- set_sc_with_vfx(WM_POEMOFNETHERWORLD , SC_NETHERWORLD , SI_NETHERWORLD , SCB_NONE);
- set_sc_with_vfx(WM_VOICEOFSIREN , SC_VOICEOFSIREN , SI_VOICEOFSIREN , SCB_NONE);
- set_sc_with_vfx(WM_LULLABY_DEEPSLEEP , SC_DEEPSLEEP , SI_DEEPSLEEP , SCB_NONE);
- set_sc(WM_SIRCLEOFNATURE , SC_SIRCLEOFNATURE , SI_SIRCLEOFNATURE , SCB_NONE);
- set_sc(WM_GLOOMYDAY , SC_GLOOMYDAY , SI_GLOOMYDAY , SCB_FLEE|SCB_ASPD);
- set_sc(WM_SONG_OF_MANA , SC_SONGOFMANA , SI_SONGOFMANA , SCB_NONE);
- set_sc(WM_DANCE_WITH_WUG , SC_DANCEWITHWUG , SI_DANCEWITHWUG , SCB_ASPD);
- set_sc(WM_SATURDAY_NIGHT_FEVER , SC_SATURDAYNIGHTFEVER , SI_SATURDAYNIGHTFEVER , SCB_BATK|SCB_DEF|SCB_FLEE|SCB_REGEN);
- set_sc(WM_LERADS_DEW , SC_LERADSDEW , SI_LERADSDEW , SCB_MAXHP);
- set_sc(WM_MELODYOFSINK , SC_MELODYOFSINK , SI_MELODYOFSINK , SCB_BATK|SCB_MATK);
- set_sc(WM_BEYOND_OF_WARCRY , SC_BEYONDOFWARCRY , SI_WARCRYOFBEYOND , SCB_BATK|SCB_MATK);
- set_sc(WM_UNLIMITED_HUMMING_VOICE, SC_UNLIMITEDHUMMINGVOICE, SI_UNLIMITEDHUMMINGVOICE, SCB_NONE);
- /**
- * Sorcerer
- **/
- set_sc(SO_FIREWALK , SC_PROPERTYWALK , SI_PROPERTYWALK , SCB_NONE);
- set_sc(SO_ELECTRICWALK , SC_PROPERTYWALK , SI_PROPERTYWALK , SCB_NONE);
- set_sc(SO_SPELLFIST , SC_SPELLFIST , SI_SPELLFIST , SCB_NONE);
- set_sc_with_vfx(SO_DIAMONDDUST , SC_CRYSTALIZE , SI_COLD , SCB_NONE); // it does show the snow icon on mobs but doesn't affect it.
- add_sc(SO_CLOUD_KILL , SC_POISON);
- set_sc(SO_STRIKING , SC_STRIKING , SI_STRIKING , SCB_WATK|SCB_CRI);
- set_sc(SO_WARMER , SC_WARMER , SI_WARMER , SCB_NONE);
- set_sc(SO_VACUUM_EXTREME , SC_VACUUM_EXTREME , SI_VACUUM_EXTREME , SCB_NONE);
- set_sc(SO_ARRULLO , SC_DEEPSLEEP , SI_DEEPSLEEP , SCB_NONE);
- set_sc(SO_FIRE_INSIGNIA , SC_FIRE_INSIGNIA , SI_FIRE_INSIGNIA , SCB_MATK | SCB_BATK | SCB_WATK | SCB_ATK_ELE | SCB_REGEN);
- set_sc(SO_WATER_INSIGNIA , SC_WATER_INSIGNIA , SI_WATER_INSIGNIA , SCB_WATK | SCB_ATK_ELE | SCB_REGEN);
- set_sc(SO_WIND_INSIGNIA , SC_WIND_INSIGNIA , SI_WIND_INSIGNIA , SCB_WATK | SCB_ATK_ELE | SCB_REGEN);
- set_sc(SO_EARTH_INSIGNIA , SC_EARTH_INSIGNIA , SI_EARTH_INSIGNIA , SCB_MDEF|SCB_DEF|SCB_MAXHP|SCB_MAXSP|SCB_WATK | SCB_ATK_ELE | SCB_REGEN);
- /**
- * Genetic
- **/
- set_sc(GN_CARTBOOST , SC_GN_CARTBOOST, SI_CARTSBOOST , SCB_SPEED);
- set_sc(GN_THORNS_TRAP , SC_THORNSTRAP , SI_THORNTRAP , SCB_NONE);
- set_sc_with_vfx(GN_BLOOD_SUCKER , SC_BLOODSUCKER , SI_BLOODSUCKER , SCB_NONE);
- set_sc(GN_WALLOFTHORN , SC_STOP , SI_BLANK , SCB_NONE);
- set_sc(GN_FIRE_EXPANSION_SMOKE_POWDER, SC_SMOKEPOWDER , SI_FIRE_EXPANSION_SMOKE_POWDER, SCB_NONE);
- set_sc(GN_FIRE_EXPANSION_TEAR_GAS , SC_TEARGAS , SI_FIRE_EXPANSION_TEAR_GAS , SCB_NONE);
- set_sc(GN_MANDRAGORA , SC_MANDRAGORA , SI_MANDRAGORA , SCB_INT);
-
- // Elemental Spirit summoner's 'side' status changes.
- set_sc(EL_CIRCLE_OF_FIRE , SC_CIRCLE_OF_FIRE_OPTION, SI_CIRCLE_OF_FIRE_OPTION, SCB_NONE);
- set_sc(EL_FIRE_CLOAK , SC_FIRE_CLOAK_OPTION , SI_FIRE_CLOAK_OPTION , SCB_ALL);
- set_sc(EL_WATER_SCREEN , SC_WATER_SCREEN_OPTION , SI_WATER_SCREEN_OPTION , SCB_NONE);
- set_sc(EL_WATER_DROP , SC_WATER_DROP_OPTION , SI_WATER_DROP_OPTION , SCB_ALL);
- set_sc(EL_WATER_BARRIER , SC_WATER_BARRIER , SI_WATER_BARRIER , SCB_MDEF|SCB_WATK|SCB_MATK|SCB_FLEE);
- set_sc(EL_WIND_STEP , SC_WIND_STEP_OPTION , SI_WIND_STEP_OPTION , SCB_SPEED|SCB_FLEE);
- set_sc(EL_WIND_CURTAIN , SC_WIND_CURTAIN_OPTION , SI_WIND_CURTAIN_OPTION , SCB_ALL);
- set_sc(EL_ZEPHYR , SC_ZEPHYR , SI_ZEPHYR , SCB_FLEE);
- set_sc(EL_SOLID_SKIN , SC_SOLID_SKIN_OPTION , SI_SOLID_SKIN_OPTION , SCB_DEF|SCB_MAXHP);
- set_sc(EL_STONE_SHIELD , SC_STONE_SHIELD_OPTION , SI_STONE_SHIELD_OPTION , SCB_ALL);
- set_sc(EL_POWER_OF_GAIA , SC_POWER_OF_GAIA , SI_POWER_OF_GAIA , SCB_MAXHP|SCB_DEF|SCB_SPEED);
- set_sc(EL_PYROTECHNIC , SC_PYROTECHNIC_OPTION , SI_PYROTECHNIC_OPTION , SCB_WATK);
- set_sc(EL_HEATER , SC_HEATER_OPTION , SI_HEATER_OPTION , SCB_WATK);
- set_sc(EL_TROPIC , SC_TROPIC_OPTION , SI_TROPIC_OPTION , SCB_WATK);
- set_sc(EL_AQUAPLAY , SC_AQUAPLAY_OPTION , SI_AQUAPLAY_OPTION , SCB_MATK);
- set_sc(EL_COOLER , SC_COOLER_OPTION , SI_COOLER_OPTION , SCB_MATK);
- set_sc(EL_CHILLY_AIR , SC_CHILLY_AIR_OPTION , SI_CHILLY_AIR_OPTION , SCB_MATK);
- set_sc(EL_GUST , SC_GUST_OPTION , SI_GUST_OPTION , SCB_NONE);
- set_sc(EL_BLAST , SC_BLAST_OPTION , SI_BLAST_OPTION , SCB_NONE);
- set_sc(EL_WILD_STORM , SC_WILD_STORM_OPTION , SI_WILD_STORM_OPTION , SCB_NONE);
- set_sc(EL_PETROLOGY , SC_PETROLOGY_OPTION , SI_PETROLOGY_OPTION , SCB_NONE);
- set_sc(EL_CURSED_SOIL , SC_CURSED_SOIL_OPTION , SI_CURSED_SOIL_OPTION , SCB_NONE);
- set_sc(EL_UPHEAVAL , SC_UPHEAVAL_OPTION , SI_UPHEAVAL_OPTION , SCB_NONE);
- set_sc(EL_TIDAL_WEAPON , SC_TIDAL_WEAPON_OPTION , SI_TIDAL_WEAPON_OPTION , SCB_ALL);
- set_sc(EL_ROCK_CRUSHER , SC_ROCK_CRUSHER , SI_ROCK_CRUSHER , SCB_DEF);
- set_sc(EL_ROCK_CRUSHER_ATK, SC_ROCK_CRUSHER_ATK , SI_ROCK_CRUSHER_ATK , SCB_SPEED);
-
- add_sc(KO_YAMIKUMO , SC_HIDING);
- set_sc_with_vfx(KO_JYUMONJIKIRI , SC_JYUMONJIKIRI , SI_KO_JYUMONJIKIRI , SCB_NONE);
- add_sc(KO_MAKIBISHI , SC_STUN);
- set_sc(KO_MEIKYOUSISUI , SC_MEIKYOUSISUI , SI_MEIKYOUSISUI , SCB_NONE);
- set_sc(KO_KYOUGAKU , SC_KYOUGAKU , SI_KYOUGAKU , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK);
- add_sc(KO_JYUSATSU , SC_CURSE);
- set_sc(KO_ZENKAI , SC_ZENKAI , SI_ZENKAI , SCB_NONE);
- set_sc(KO_IZAYOI , SC_IZAYOI , SI_IZAYOI , SCB_MATK);
- set_sc(KG_KYOMU , SC_KYOMU , SI_KYOMU , SCB_NONE);
- set_sc(KG_KAGEMUSYA , SC_KAGEMUSYA , SI_KAGEMUSYA , SCB_NONE);
- set_sc(KG_KAGEHUMI , SC_KAGEHUMI , SI_KG_KAGEHUMI , SCB_NONE);
- set_sc(OB_ZANGETSU , SC_ZANGETSU , SI_ZANGETSU , SCB_MATK|SCB_BATK);
- set_sc_with_vfx(OB_AKAITSUKI , SC_AKAITSUKI , SI_AKAITSUKI , SCB_NONE);
- set_sc(OB_OBOROGENSOU , SC_GENSOU , SI_GENSOU , SCB_NONE);
-
- // Storing the target job rather than simply SC_SPIRIT simplifies code later on.
- SkillStatusChangeTable[SL_ALCHEMIST] = (sc_type)MAPID_ALCHEMIST,
- SkillStatusChangeTable[SL_MONK] = (sc_type)MAPID_MONK,
- SkillStatusChangeTable[SL_STAR] = (sc_type)MAPID_STAR_GLADIATOR,
- SkillStatusChangeTable[SL_SAGE] = (sc_type)MAPID_SAGE,
- SkillStatusChangeTable[SL_CRUSADER] = (sc_type)MAPID_CRUSADER,
- SkillStatusChangeTable[SL_SUPERNOVICE] = (sc_type)MAPID_SUPER_NOVICE,
- SkillStatusChangeTable[SL_KNIGHT] = (sc_type)MAPID_KNIGHT,
- SkillStatusChangeTable[SL_WIZARD] = (sc_type)MAPID_WIZARD,
- SkillStatusChangeTable[SL_PRIEST] = (sc_type)MAPID_PRIEST,
- SkillStatusChangeTable[SL_BARDDANCER] = (sc_type)MAPID_BARDDANCER,
- SkillStatusChangeTable[SL_ROGUE] = (sc_type)MAPID_ROGUE,
- SkillStatusChangeTable[SL_ASSASIN] = (sc_type)MAPID_ASSASSIN,
- SkillStatusChangeTable[SL_BLACKSMITH] = (sc_type)MAPID_BLACKSMITH,
- SkillStatusChangeTable[SL_HUNTER] = (sc_type)MAPID_HUNTER,
- SkillStatusChangeTable[SL_SOULLINKER] = (sc_type)MAPID_SOUL_LINKER,
-
- //Status that don't have a skill associated.
- StatusIconChangeTable[SC_WEIGHT50] = SI_WEIGHT50;
- StatusIconChangeTable[SC_WEIGHT90] = SI_WEIGHT90;
- StatusIconChangeTable[SC_ASPDPOTION0] = SI_ASPDPOTION0;
- StatusIconChangeTable[SC_ASPDPOTION1] = SI_ASPDPOTION1;
- StatusIconChangeTable[SC_ASPDPOTION2] = SI_ASPDPOTION2;
- StatusIconChangeTable[SC_ASPDPOTION3] = SI_ASPDPOTIONINFINITY;
- StatusIconChangeTable[SC_SPEEDUP0] = SI_MOVHASTE_HORSE;
- StatusIconChangeTable[SC_SPEEDUP1] = SI_SPEEDPOTION1;
- StatusIconChangeTable[SC_INCSTR] = SI_INCSTR;
- StatusIconChangeTable[SC_MIRACLE] = SI_SPIRIT;
- StatusIconChangeTable[SC_INTRAVISION] = SI_INTRAVISION;
- StatusIconChangeTable[SC_STRFOOD] = SI_FOODSTR;
- StatusIconChangeTable[SC_AGIFOOD] = SI_FOODAGI;
- StatusIconChangeTable[SC_VITFOOD] = SI_FOODVIT;
- StatusIconChangeTable[SC_INTFOOD] = SI_FOODINT;
- StatusIconChangeTable[SC_DEXFOOD] = SI_FOODDEX;
- StatusIconChangeTable[SC_LUKFOOD] = SI_FOODLUK;
- StatusIconChangeTable[SC_FLEEFOOD]= SI_FOODFLEE;
- StatusIconChangeTable[SC_HITFOOD] = SI_FOODHIT;
- StatusIconChangeTable[SC_MANU_ATK] = SI_MANU_ATK;
- StatusIconChangeTable[SC_MANU_DEF] = SI_MANU_DEF;
- StatusIconChangeTable[SC_SPL_ATK] = SI_SPL_ATK;
- StatusIconChangeTable[SC_SPL_DEF] = SI_SPL_DEF;
- StatusIconChangeTable[SC_MANU_MATK] = SI_MANU_MATK;
- StatusIconChangeTable[SC_SPL_MATK] = SI_SPL_MATK;
- //Cash Items
- StatusIconChangeTable[SC_FOOD_STR_CASH] = SI_FOOD_STR_CASH;
- StatusIconChangeTable[SC_FOOD_AGI_CASH] = SI_FOOD_AGI_CASH;
- StatusIconChangeTable[SC_FOOD_VIT_CASH] = SI_FOOD_VIT_CASH;
- StatusIconChangeTable[SC_FOOD_DEX_CASH] = SI_FOOD_DEX_CASH;
- StatusIconChangeTable[SC_FOOD_INT_CASH] = SI_FOOD_INT_CASH;
- StatusIconChangeTable[SC_FOOD_LUK_CASH] = SI_FOOD_LUK_CASH;
- StatusIconChangeTable[SC_EXPBOOST] = SI_EXPBOOST;
- StatusIconChangeTable[SC_ITEMBOOST] = SI_ITEMBOOST;
- StatusIconChangeTable[SC_JEXPBOOST] = SI_CASH_PLUSONLYJOBEXP;
- StatusIconChangeTable[SC_LIFEINSURANCE] = SI_LIFEINSURANCE;
- StatusIconChangeTable[SC_BOSSMAPINFO] = SI_BOSSMAPINFO;
- StatusIconChangeTable[SC_DEF_RATE] = SI_DEF_RATE;
- StatusIconChangeTable[SC_MDEF_RATE] = SI_MDEF_RATE;
- StatusIconChangeTable[SC_INCCRI] = SI_INCCRI;
- StatusIconChangeTable[SC_INCFLEE2] = SI_PLUSAVOIDVALUE;
- StatusIconChangeTable[SC_INCHEALRATE] = SI_INCHEALRATE;
- StatusIconChangeTable[SC_S_LIFEPOTION] = SI_S_LIFEPOTION;
- StatusIconChangeTable[SC_L_LIFEPOTION] = SI_L_LIFEPOTION;
- StatusIconChangeTable[SC_SPCOST_RATE] = SI_ATKER_BLOOD;
- StatusIconChangeTable[SC_COMMONSC_RESIST] = SI_TARGET_BLOOD;
- // Mercenary Bonus Effects
- StatusIconChangeTable[SC_MERC_FLEEUP] = SI_MERC_FLEEUP;
- StatusIconChangeTable[SC_MERC_ATKUP] = SI_MERC_ATKUP;
- StatusIconChangeTable[SC_MERC_HPUP] = SI_MERC_HPUP;
- StatusIconChangeTable[SC_MERC_SPUP] = SI_MERC_SPUP;
- StatusIconChangeTable[SC_MERC_HITUP] = SI_MERC_HITUP;
- // Warlock Spheres
- StatusIconChangeTable[SC_SPHERE_1] = SI_SPHERE_1;
- StatusIconChangeTable[SC_SPHERE_2] = SI_SPHERE_2;
- StatusIconChangeTable[SC_SPHERE_3] = SI_SPHERE_3;
- StatusIconChangeTable[SC_SPHERE_4] = SI_SPHERE_4;
- StatusIconChangeTable[SC_SPHERE_5] = SI_SPHERE_5;
- // Warlock Preserved spells
- StatusIconChangeTable[SC_SPELLBOOK1] = SI_SPELLBOOK1;
- StatusIconChangeTable[SC_SPELLBOOK2] = SI_SPELLBOOK2;
- StatusIconChangeTable[SC_SPELLBOOK3] = SI_SPELLBOOK3;
- StatusIconChangeTable[SC_SPELLBOOK4] = SI_SPELLBOOK4;
- StatusIconChangeTable[SC_SPELLBOOK5] = SI_SPELLBOOK5;
- StatusIconChangeTable[SC_SPELLBOOK6] = SI_SPELLBOOK6;
- StatusIconChangeTable[SC_MAXSPELLBOOK] = SI_SPELLBOOK7;
-
- StatusIconChangeTable[SC_NEUTRALBARRIER_MASTER] = SI_NEUTRALBARRIER_MASTER;
- StatusIconChangeTable[SC_STEALTHFIELD_MASTER] = SI_STEALTHFIELD_MASTER;
- StatusIconChangeTable[SC_OVERHEAT] = SI_OVERHEAT;
- StatusIconChangeTable[SC_OVERHEAT_LIMITPOINT] = SI_OVERHEAT_LIMITPOINT;
-
- StatusIconChangeTable[SC_HALLUCINATIONWALK_POSTDELAY] = SI_HALLUCINATIONWALK_POSTDELAY;
- StatusIconChangeTable[SC_TOXIN] = SI_TOXIN;
- StatusIconChangeTable[SC_PARALYSE] = SI_PARALYSE;
- StatusIconChangeTable[SC_VENOMBLEED] = SI_VENOMBLEED;
- StatusIconChangeTable[SC_MAGICMUSHROOM] = SI_MAGICMUSHROOM;
- StatusIconChangeTable[SC_DEATHHURT] = SI_DEATHHURT;
- StatusIconChangeTable[SC_PYREXIA] = SI_PYREXIA;
- StatusIconChangeTable[SC_OBLIVIONCURSE] = SI_OBLIVIONCURSE;
- StatusIconChangeTable[SC_LEECHESEND] = SI_LEECHESEND;
-
- StatusIconChangeTable[SC_SHIELDSPELL_DEF] = SI_SHIELDSPELL_DEF;
- StatusIconChangeTable[SC_SHIELDSPELL_MDEF] = SI_SHIELDSPELL_MDEF;
- StatusIconChangeTable[SC_SHIELDSPELL_REF] = SI_SHIELDSPELL_REF;
- StatusIconChangeTable[SC_BANDING_DEFENCE] = SI_BANDING_DEFENCE;
-
- StatusIconChangeTable[SC_GLOOMYDAY_SK] = SI_GLOOMYDAY;
-
- StatusIconChangeTable[SC_CURSEDCIRCLE_ATKER] = SI_CURSEDCIRCLE_ATKER;
-
- StatusIconChangeTable[SC_STOMACHACHE] = SI_STOMACHACHE;
- StatusIconChangeTable[SC_MYSTERIOUS_POWDER] = SI_MYSTERIOUS_POWDER;
- StatusIconChangeTable[SC_MELON_BOMB] = SI_MELON_BOMB;
- StatusIconChangeTable[SC_BANANA_BOMB] = SI_BANANA_BOMB;
- StatusIconChangeTable[SC_BANANA_BOMB_SITDOWN] = SI_BANANA_BOMB_SITDOWN_POSTDELAY;
-
- //Genetics New Food Items Status Icons
- StatusIconChangeTable[SC_SAVAGE_STEAK] = SI_SAVAGE_STEAK;
- StatusIconChangeTable[SC_COCKTAIL_WARG_BLOOD] = SI_COCKTAIL_WARG_BLOOD;
- StatusIconChangeTable[SC_MINOR_BBQ] = SI_MINOR_BBQ;
- StatusIconChangeTable[SC_SIROMA_ICE_TEA] = SI_SIROMA_ICE_TEA;
- StatusIconChangeTable[SC_DROCERA_HERB_STEAMED] = SI_DROCERA_HERB_STEAMED;
- StatusIconChangeTable[SC_PUTTI_TAILS_NOODLES] = SI_PUTTI_TAILS_NOODLES;
-
- StatusIconChangeTable[SC_BOOST500] |= SI_BOOST500;
- StatusIconChangeTable[SC_FULL_SWING_K] |= SI_FULL_SWING_K;
- StatusIconChangeTable[SC_MANA_PLUS] |= SI_MANA_PLUS;
- StatusIconChangeTable[SC_MUSTLE_M] |= SI_MUSTLE_M;
- StatusIconChangeTable[SC_LIFE_FORCE_F] |= SI_LIFE_FORCE_F;
- StatusIconChangeTable[SC_EXTRACT_WHITE_POTION_Z] |= SI_EXTRACT_WHITE_POTION_Z;
- StatusIconChangeTable[SC_VITATA_500] |= SI_VITATA_500;
- StatusIconChangeTable[SC_EXTRACT_SALAMINE_JUICE] |= SI_EXTRACT_SALAMINE_JUICE;
-
- // Elemental Spirit's 'side' status change icons.
- StatusIconChangeTable[SC_CIRCLE_OF_FIRE] = SI_CIRCLE_OF_FIRE;
- StatusIconChangeTable[SC_FIRE_CLOAK] = SI_FIRE_CLOAK;
- StatusIconChangeTable[SC_WATER_SCREEN] = SI_WATER_SCREEN;
- StatusIconChangeTable[SC_WATER_DROP] = SI_WATER_DROP;
- StatusIconChangeTable[SC_WIND_STEP] = SI_WIND_STEP;
- StatusIconChangeTable[SC_WIND_CURTAIN] = SI_WIND_CURTAIN;
- StatusIconChangeTable[SC_SOLID_SKIN] = SI_SOLID_SKIN;
- StatusIconChangeTable[SC_STONE_SHIELD] = SI_STONE_SHIELD;
- StatusIconChangeTable[SC_PYROTECHNIC] = SI_PYROTECHNIC;
- StatusIconChangeTable[SC_HEATER] = SI_HEATER;
- StatusIconChangeTable[SC_TROPIC] = SI_TROPIC;
- StatusIconChangeTable[SC_AQUAPLAY] = SI_AQUAPLAY;
- StatusIconChangeTable[SC_COOLER] = SI_COOLER;
- StatusIconChangeTable[SC_CHILLY_AIR] = SI_CHILLY_AIR;
- StatusIconChangeTable[SC_GUST] = SI_GUST;
- StatusIconChangeTable[SC_BLAST] = SI_BLAST;
- StatusIconChangeTable[SC_WILD_STORM] = SI_WILD_STORM;
- StatusIconChangeTable[SC_PETROLOGY] = SI_PETROLOGY;
- StatusIconChangeTable[SC_CURSED_SOIL] = SI_CURSED_SOIL;
- StatusIconChangeTable[SC_UPHEAVAL] = SI_UPHEAVAL;
- StatusIconChangeTable[SC_PUSH_CART] = SI_ON_PUSH_CART;
-
- //Other SC which are not necessarily associated to skills.
- StatusChangeFlagTable[SC_ASPDPOTION0] = SCB_ASPD;
- StatusChangeFlagTable[SC_ASPDPOTION1] = SCB_ASPD;
- StatusChangeFlagTable[SC_ASPDPOTION2] = SCB_ASPD;
- StatusChangeFlagTable[SC_ASPDPOTION3] = SCB_ASPD;
- StatusChangeFlagTable[SC_SPEEDUP0] = SCB_SPEED;
- StatusChangeFlagTable[SC_SPEEDUP1] = SCB_SPEED;
- StatusChangeFlagTable[SC_ATKPOTION] = SCB_BATK;
- StatusChangeFlagTable[SC_MATKPOTION] = SCB_MATK;
- StatusChangeFlagTable[SC_INCALLSTATUS] |= SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK;
- StatusChangeFlagTable[SC_INCSTR] |= SCB_STR;
- StatusChangeFlagTable[SC_INCAGI] |= SCB_AGI;
- StatusChangeFlagTable[SC_INCVIT] |= SCB_VIT;
- StatusChangeFlagTable[SC_INCINT] |= SCB_INT;
- StatusChangeFlagTable[SC_INCDEX] |= SCB_DEX;
- StatusChangeFlagTable[SC_INCLUK] |= SCB_LUK;
- StatusChangeFlagTable[SC_INCHIT] |= SCB_HIT;
- StatusChangeFlagTable[SC_INCHITRATE] |= SCB_HIT;
- StatusChangeFlagTable[SC_INCFLEE] |= SCB_FLEE;
- StatusChangeFlagTable[SC_INCFLEERATE] |= SCB_FLEE;
- StatusChangeFlagTable[SC_INCCRI] |= SCB_CRI;
- StatusChangeFlagTable[SC_INCASPDRATE] |= SCB_ASPD;
- StatusChangeFlagTable[SC_INCFLEE2] |= SCB_FLEE2;
- StatusChangeFlagTable[SC_INCMHPRATE] |= SCB_MAXHP;
- StatusChangeFlagTable[SC_INCMSPRATE] |= SCB_MAXSP;
- StatusChangeFlagTable[SC_INCMHP] |= SCB_MAXHP;
- StatusChangeFlagTable[SC_INCMSP] |= SCB_MAXSP;
- StatusChangeFlagTable[SC_INCATKRATE] |= SCB_BATK|SCB_WATK;
- StatusChangeFlagTable[SC_INCMATKRATE] |= SCB_MATK;
- StatusChangeFlagTable[SC_INCDEFRATE] |= SCB_DEF;
- StatusChangeFlagTable[SC_STRFOOD] |= SCB_STR;
- StatusChangeFlagTable[SC_AGIFOOD] |= SCB_AGI;
- StatusChangeFlagTable[SC_VITFOOD] |= SCB_VIT;
- StatusChangeFlagTable[SC_INTFOOD] |= SCB_INT;
- StatusChangeFlagTable[SC_DEXFOOD] |= SCB_DEX;
- StatusChangeFlagTable[SC_LUKFOOD] |= SCB_LUK;
- StatusChangeFlagTable[SC_HITFOOD] |= SCB_HIT;
- StatusChangeFlagTable[SC_FLEEFOOD] |= SCB_FLEE;
- StatusChangeFlagTable[SC_BATKFOOD] |= SCB_BATK;
- StatusChangeFlagTable[SC_WATKFOOD] |= SCB_WATK;
- StatusChangeFlagTable[SC_MATKFOOD] |= SCB_MATK;
- StatusChangeFlagTable[SC_ARMOR_ELEMENT] |= SCB_ALL;
- StatusChangeFlagTable[SC_ARMOR_RESIST] |= SCB_ALL;
- StatusChangeFlagTable[SC_SPCOST_RATE] |= SCB_ALL;
- StatusChangeFlagTable[SC_WALKSPEED] |= SCB_SPEED;
- StatusChangeFlagTable[SC_ITEMSCRIPT] |= SCB_ALL;
- // Cash Items
- StatusChangeFlagTable[SC_FOOD_STR_CASH] = SCB_STR;
- StatusChangeFlagTable[SC_FOOD_AGI_CASH] = SCB_AGI;
- StatusChangeFlagTable[SC_FOOD_VIT_CASH] = SCB_VIT;
- StatusChangeFlagTable[SC_FOOD_DEX_CASH] = SCB_DEX;
- StatusChangeFlagTable[SC_FOOD_INT_CASH] = SCB_INT;
- StatusChangeFlagTable[SC_FOOD_LUK_CASH] = SCB_LUK;
- // Mercenary Bonus Effects
- StatusChangeFlagTable[SC_MERC_FLEEUP] |= SCB_FLEE;
- StatusChangeFlagTable[SC_MERC_ATKUP] |= SCB_WATK;
- StatusChangeFlagTable[SC_MERC_HPUP] |= SCB_MAXHP;
- StatusChangeFlagTable[SC_MERC_SPUP] |= SCB_MAXSP;
- StatusChangeFlagTable[SC_MERC_HITUP] |= SCB_HIT;
- // Guillotine Cross Poison Effects
- StatusChangeFlagTable[SC_PARALYSE] |= SCB_ASPD|SCB_FLEE|SCB_SPEED;
- StatusChangeFlagTable[SC_DEATHHURT] |= SCB_REGEN;
- StatusChangeFlagTable[SC_VENOMBLEED] |= SCB_MAXHP;
- StatusChangeFlagTable[SC_OBLIVIONCURSE] |= SCB_REGEN;
-
- StatusChangeFlagTable[SC_SAVAGE_STEAK] |= SCB_STR;
- StatusChangeFlagTable[SC_COCKTAIL_WARG_BLOOD] |= SCB_INT;
- StatusChangeFlagTable[SC_MINOR_BBQ] |= SCB_VIT;
- StatusChangeFlagTable[SC_SIROMA_ICE_TEA] |= SCB_DEX;
- StatusChangeFlagTable[SC_DROCERA_HERB_STEAMED] |= SCB_AGI;
- StatusChangeFlagTable[SC_PUTTI_TAILS_NOODLES] |= SCB_LUK;
- StatusChangeFlagTable[SC_BOOST500] |= SCB_ASPD;
- StatusChangeFlagTable[SC_FULL_SWING_K] |= SCB_BATK;
- StatusChangeFlagTable[SC_MANA_PLUS] |= SCB_MATK;
- StatusChangeFlagTable[SC_MUSTLE_M] |= SCB_MAXHP;
- StatusChangeFlagTable[SC_LIFE_FORCE_F] |= SCB_MAXSP;
- StatusChangeFlagTable[SC_EXTRACT_WHITE_POTION_Z] |= SCB_REGEN;
- StatusChangeFlagTable[SC_VITATA_500] |= SCB_REGEN;
- StatusChangeFlagTable[SC_EXTRACT_SALAMINE_JUICE] |= SCB_ASPD;
+ add_sc( SA_MAGICROD , SC_MAGICROD );
+ set_sc( SA_AUTOSPELL , SC_AUTOSPELL , SI_AUTOSPELL , SCB_NONE );
+ set_sc( SA_FLAMELAUNCHER , SC_FIREWEAPON , SI_FIREWEAPON , SCB_ATK_ELE );
+ set_sc( SA_FROSTWEAPON , SC_WATERWEAPON , SI_WATERWEAPON , SCB_ATK_ELE );
+ set_sc( SA_LIGHTNINGLOADER , SC_WINDWEAPON , SI_WINDWEAPON , SCB_ATK_ELE );
+ set_sc( SA_SEISMICWEAPON , SC_EARTHWEAPON , SI_EARTHWEAPON , SCB_ATK_ELE );
+ set_sc( SA_VOLCANO , SC_VOLCANO , SI_LANDENDOW , SCB_WATK );
+ set_sc( SA_DELUGE , SC_DELUGE , SI_LANDENDOW , SCB_MAXHP );
+ set_sc( SA_VIOLENTGALE , SC_VIOLENTGALE , SI_LANDENDOW , SCB_FLEE );
+ add_sc( SA_REVERSEORCISH , SC_ORCISH );
+ add_sc( SA_COMA , SC_COMA );
+ set_sc( BD_ENCORE , SC_DANCING , SI_BLANK , SCB_SPEED|SCB_REGEN );
+ add_sc( BD_RICHMANKIM , SC_RICHMANKIM );
+ set_sc( BD_ETERNALCHAOS , SC_ETERNALCHAOS , SI_BLANK , SCB_DEF2 );
+ set_sc( BD_DRUMBATTLEFIELD , SC_DRUMBATTLE , SI_BLANK , SCB_WATK|SCB_DEF );
+ set_sc( BD_RINGNIBELUNGEN , SC_NIBELUNGEN , SI_BLANK , SCB_WATK );
+ add_sc( BD_ROKISWEIL , SC_ROKISWEIL );
+ add_sc( BD_INTOABYSS , SC_INTOABYSS );
+ set_sc( BD_SIEGFRIED , SC_SIEGFRIED , SI_BLANK , SCB_ALL );
+ add_sc( BA_FROSTJOKER , SC_FREEZE );
+ set_sc( BA_WHISTLE , SC_WHISTLE , SI_BLANK , SCB_FLEE|SCB_FLEE2 );
+ set_sc( BA_ASSASSINCROSS , SC_ASSNCROS , SI_BLANK , SCB_ASPD );
+ add_sc( BA_POEMBRAGI , SC_POEMBRAGI );
+ set_sc( BA_APPLEIDUN , SC_APPLEIDUN , SI_BLANK , SCB_MAXHP );
+ add_sc( DC_SCREAM , SC_STUN );
+ set_sc( DC_HUMMING , SC_HUMMING , SI_BLANK , SCB_HIT );
+ set_sc( DC_DONTFORGETME , SC_DONTFORGETME , SI_BLANK , SCB_SPEED|SCB_ASPD );
+ set_sc( DC_FORTUNEKISS , SC_FORTUNE , SI_BLANK , SCB_CRI );
+ set_sc( DC_SERVICEFORYOU , SC_SERVICE4U , SI_BLANK , SCB_ALL );
+ add_sc( NPC_DARKCROSS , SC_BLIND );
+ add_sc( NPC_GRANDDARKNESS , SC_BLIND );
+ set_sc( NPC_STOP , SC_STOP , SI_STOP , SCB_NONE );
+ set_sc( NPC_WEAPONBRAKER , SC_BROKENWEAPON , SI_BROKENWEAPON , SCB_NONE );
+ set_sc( NPC_ARMORBRAKE , SC_BROKENARMOR , SI_BROKENARMOR , SCB_NONE );
+ set_sc( NPC_CHANGEUNDEAD , SC_CHANGEUNDEAD , SI_UNDEAD , SCB_DEF_ELE );
+ set_sc( NPC_POWERUP , SC_INCHITRATE , SI_BLANK , SCB_HIT );
+ set_sc( NPC_AGIUP , SC_INCFLEERATE , SI_BLANK , SCB_FLEE );
+ add_sc( NPC_INVISIBLE , SC_CLOAKING );
+ set_sc( LK_AURABLADE , SC_AURABLADE , SI_AURABLADE , SCB_NONE );
+ set_sc( LK_PARRYING , SC_PARRYING , SI_PARRYING , SCB_NONE );
+ set_sc( LK_CONCENTRATION , SC_CONCENTRATION , SI_CONCENTRATION , SCB_BATK|SCB_WATK|SCB_HIT|SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_DSPD );
+ set_sc( LK_TENSIONRELAX , SC_TENSIONRELAX , SI_TENSIONRELAX , SCB_REGEN );
+ set_sc( LK_BERSERK , SC_BERSERK , SI_BERSERK , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2|SCB_FLEE|SCB_SPEED|SCB_ASPD|SCB_MAXHP|SCB_REGEN );
+ set_sc( HP_ASSUMPTIO , SC_ASSUMPTIO , SI_ASSUMPTIO , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2 );
+ add_sc( HP_BASILICA , SC_BASILICA );
+ set_sc( HW_MAGICPOWER , SC_MAGICPOWER , SI_MAGICPOWER , SCB_MATK );
+ add_sc( PA_SACRIFICE , SC_SACRIFICE );
+ set_sc( PA_GOSPEL , SC_GOSPEL , SI_BLANK , SCB_SPEED|SCB_ASPD );
+ add_sc( PA_GOSPEL , SC_SCRESIST );
+ add_sc( CH_TIGERFIST , SC_STOP );
+ set_sc( ASC_EDP , SC_EDP , SI_EDP , SCB_NONE );
+ set_sc( SN_SIGHT , SC_TRUESIGHT , SI_TRUESIGHT , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK|SCB_CRI|SCB_HIT );
+ set_sc( SN_WINDWALK , SC_WINDWALK , SI_WINDWALK , SCB_FLEE|SCB_SPEED );
+ set_sc( WS_MELTDOWN , SC_MELTDOWN , SI_MELTDOWN , SCB_NONE );
+ set_sc( WS_CARTBOOST , SC_CARTBOOST , SI_CARTBOOST , SCB_SPEED );
+ set_sc( ST_CHASEWALK , SC_CHASEWALK , SI_BLANK , SCB_SPEED );
+ set_sc( ST_REJECTSWORD , SC_REJECTSWORD , SI_REJECTSWORD , SCB_NONE );
+ add_sc( ST_REJECTSWORD , SC_AUTOCOUNTER );
+ set_sc( CG_MARIONETTE , SC_MARIONETTE , SI_MARIONETTE , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
+ set_sc( CG_MARIONETTE , SC_MARIONETTE2 , SI_MARIONETTE2 , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
+ add_sc( LK_SPIRALPIERCE , SC_STOP );
+ add_sc( LK_HEADCRUSH , SC_BLEEDING );
+ set_sc( LK_JOINTBEAT , SC_JOINTBEAT , SI_JOINTBEAT , SCB_BATK|SCB_DEF2|SCB_SPEED|SCB_ASPD );
+ add_sc( HW_NAPALMVULCAN , SC_CURSE );
+ set_sc( PF_MINDBREAKER , SC_MINDBREAKER , SI_BLANK , SCB_MATK|SCB_MDEF2 );
+ add_sc( PF_MEMORIZE , SC_MEMORIZE );
+ add_sc( PF_FOGWALL , SC_FOGWALL );
+ set_sc( PF_SPIDERWEB , SC_SPIDERWEB , SI_BLANK , SCB_FLEE );
+ set_sc( WE_BABY , SC_BABY , SI_BABY , SCB_NONE );
+ set_sc( TK_RUN , SC_RUN , SI_RUN , SCB_SPEED|SCB_DSPD );
+ set_sc( TK_RUN , SC_SPURT , SI_SPURT , SCB_STR );
+ set_sc( TK_READYSTORM , SC_READYSTORM , SI_READYSTORM , SCB_NONE );
+ set_sc( TK_READYDOWN , SC_READYDOWN , SI_READYDOWN , SCB_NONE );
+ add_sc( TK_DOWNKICK , SC_STUN );
+ set_sc( TK_READYTURN , SC_READYTURN , SI_READYTURN , SCB_NONE );
+ set_sc( TK_READYCOUNTER , SC_READYCOUNTER , SI_READYCOUNTER , SCB_NONE );
+ set_sc( TK_DODGE , SC_DODGE , SI_DODGE , SCB_NONE );
+ set_sc( TK_SPTIME , SC_EARTHSCROLL , SI_EARTHSCROLL , SCB_NONE );
+ add_sc( TK_SEVENWIND , SC_SEVENWIND );
+ set_sc( TK_SEVENWIND , SC_GHOSTWEAPON , SI_GHOSTWEAPON , SCB_ATK_ELE );
+ set_sc( TK_SEVENWIND , SC_SHADOWWEAPON , SI_SHADOWWEAPON , SCB_ATK_ELE );
+ set_sc( SG_SUN_WARM , SC_WARM , SI_WARM , SCB_NONE );
+ add_sc( SG_MOON_WARM , SC_WARM );
+ add_sc( SG_STAR_WARM , SC_WARM );
+ set_sc( SG_SUN_COMFORT , SC_SUN_COMFORT , SI_SUN_COMFORT , SCB_DEF2 );
+ set_sc( SG_MOON_COMFORT , SC_MOON_COMFORT , SI_MOON_COMFORT , SCB_FLEE );
+ set_sc( SG_STAR_COMFORT , SC_STAR_COMFORT , SI_STAR_COMFORT , SCB_ASPD );
+ add_sc( SG_FRIEND , SC_SKILLRATE_UP );
+ set_sc( SG_KNOWLEDGE , SC_KNOWLEDGE , SI_BLANK , SCB_ALL );
+ set_sc( SG_FUSION , SC_FUSION , SI_BLANK , SCB_SPEED );
+ set_sc( BS_ADRENALINE2 , SC_ADRENALINE2 , SI_ADRENALINE2 , SCB_ASPD );
+ set_sc( SL_KAIZEL , SC_KAIZEL , SI_KAIZEL , SCB_NONE );
+ set_sc( SL_KAAHI , SC_KAAHI , SI_KAAHI , SCB_NONE );
+ set_sc( SL_KAUPE , SC_KAUPE , SI_KAUPE , SCB_NONE );
+ set_sc( SL_KAITE , SC_KAITE , SI_KAITE , SCB_NONE );
+ add_sc( SL_STUN , SC_STUN );
+ set_sc( SL_SWOO , SC_SWOO , SI_BLANK , SCB_SPEED );
+ set_sc( SL_SKE , SC_SKE , SI_BLANK , SCB_BATK|SCB_WATK|SCB_DEF|SCB_DEF2 );
+ set_sc( SL_SKA , SC_SKA , SI_BLANK , SCB_DEF|SCB_MDEF|SCB_ASPD );
+ set_sc( SL_SMA , SC_SMA , SI_SMA , SCB_NONE );
+ set_sc( SM_SELFPROVOKE , SC_PROVOKE , SI_PROVOKE , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK );
+ set_sc( ST_PRESERVE , SC_PRESERVE , SI_PRESERVE , SCB_NONE );
+ set_sc( PF_DOUBLECASTING , SC_DOUBLECAST , SI_DOUBLECAST , SCB_NONE );
+ set_sc( HW_GRAVITATION , SC_GRAVITATION , SI_BLANK , SCB_ASPD );
+ add_sc( WS_CARTTERMINATION , SC_STUN );
+ set_sc( WS_OVERTHRUSTMAX , SC_MAXOVERTHRUST , SI_MAXOVERTHRUST , SCB_NONE );
+ set_sc( CG_LONGINGFREEDOM , SC_LONGING , SI_BLANK , SCB_SPEED|SCB_ASPD );
+ add_sc( CG_HERMODE , SC_HERMODE );
+ set_sc( ITEM_ENCHANTARMS , SC_ENCHANTARMS , SI_BLANK , SCB_ATK_ELE );
+ set_sc( SL_HIGH , SC_SPIRIT , SI_SPIRIT , SCB_ALL );
+ set_sc( KN_ONEHAND , SC_ONEHAND , SI_ONEHAND , SCB_ASPD );
+ set_sc( GS_FLING , SC_FLING , SI_BLANK , SCB_DEF|SCB_DEF2 );
+ add_sc( GS_CRACKER , SC_STUN );
+ add_sc( GS_DISARM , SC_STRIPWEAPON );
+ add_sc( GS_PIERCINGSHOT , SC_BLEEDING );
+ set_sc( GS_MADNESSCANCEL , SC_MADNESSCANCEL , SI_MADNESSCANCEL , SCB_BATK|SCB_ASPD );
+ set_sc( GS_ADJUSTMENT , SC_ADJUSTMENT , SI_ADJUSTMENT , SCB_HIT|SCB_FLEE );
+ set_sc( GS_INCREASING , SC_INCREASING , SI_ACCURACY , SCB_AGI|SCB_DEX|SCB_HIT );
+ set_sc( GS_GATLINGFEVER , SC_GATLINGFEVER , SI_GATLINGFEVER , SCB_BATK|SCB_FLEE|SCB_SPEED|SCB_ASPD );
+ set_sc( NJ_TATAMIGAESHI , SC_TATAMIGAESHI , SI_BLANK , SCB_NONE );
+ set_sc( NJ_SUITON , SC_SUITON , SI_BLANK , SCB_AGI|SCB_SPEED );
+ add_sc( NJ_HYOUSYOURAKU , SC_FREEZE );
+ set_sc( NJ_NEN , SC_NEN , SI_NEN , SCB_STR|SCB_INT );
+ set_sc( NJ_UTSUSEMI , SC_UTSUSEMI , SI_UTSUSEMI , SCB_NONE );
+ set_sc( NJ_BUNSINJYUTSU , SC_BUNSINJYUTSU , SI_BUNSINJYUTSU , SCB_DYE );
+
+ add_sc( NPC_ICEBREATH , SC_FREEZE );
+ add_sc( NPC_ACIDBREATH , SC_POISON );
+ add_sc( NPC_HELLJUDGEMENT , SC_CURSE );
+ add_sc( NPC_WIDESILENCE , SC_SILENCE );
+ add_sc( NPC_WIDEFREEZE , SC_FREEZE );
+ add_sc( NPC_WIDEBLEEDING , SC_BLEEDING );
+ add_sc( NPC_WIDESTONE , SC_STONE );
+ add_sc( NPC_WIDECONFUSE , SC_CONFUSION );
+ add_sc( NPC_WIDESLEEP , SC_SLEEP );
+ add_sc( NPC_WIDESIGHT , SC_SIGHT );
+ add_sc( NPC_EVILLAND , SC_BLIND );
+ add_sc( NPC_MAGICMIRROR , SC_MAGICMIRROR );
+ set_sc( NPC_SLOWCAST , SC_SLOWCAST , SI_SLOWCAST , SCB_NONE );
+ set_sc( NPC_CRITICALWOUND , SC_CRITICALWOUND , SI_CRITICALWOUND , SCB_NONE );
+ set_sc( NPC_STONESKIN , SC_ARMORCHANGE , SI_BLANK , SCB_DEF|SCB_MDEF );
+ add_sc( NPC_ANTIMAGIC , SC_ARMORCHANGE );
+ add_sc( NPC_WIDECURSE , SC_CURSE );
+ add_sc( NPC_WIDESTUN , SC_STUN );
+
+ set_sc( NPC_HELLPOWER , SC_HELLPOWER , SI_HELLPOWER , SCB_NONE );
+ set_sc( NPC_WIDEHELLDIGNITY , SC_HELLPOWER , SI_HELLPOWER , SCB_NONE );
+ set_sc( NPC_INVINCIBLE , SC_INVINCIBLE , SI_INVINCIBLE , SCB_SPEED );
+ set_sc( NPC_INVINCIBLEOFF , SC_INVINCIBLEOFF , SI_BLANK , SCB_SPEED );
+
+ set_sc( CASH_BLESSING , SC_BLESSING , SI_BLESSING , SCB_STR|SCB_INT|SCB_DEX );
+ set_sc( CASH_INCAGI , SC_INCREASEAGI , SI_INCREASEAGI , SCB_AGI|SCB_SPEED );
+ set_sc( CASH_ASSUMPTIO , SC_ASSUMPTIO , SI_ASSUMPTIO , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2 );
+
+ set_sc( ALL_PARTYFLEE , SC_PARTYFLEE , SI_PARTYFLEE , SCB_NONE );
+ set_sc( ALL_ODINS_POWER , SC_ODINS_POWER , SI_ODINS_POWER , SCB_MATK|SCB_BATK|SCB_MDEF|SCB_DEF );
+
+ set_sc( CR_SHRINK , SC_SHRINK , SI_SHRINK , SCB_NONE );
+ set_sc( RG_CLOSECONFINE , SC_CLOSECONFINE2 , SI_CLOSECONFINE2 , SCB_NONE );
+ set_sc( RG_CLOSECONFINE , SC_CLOSECONFINE , SI_CLOSECONFINE , SCB_FLEE );
+ set_sc( WZ_SIGHTBLASTER , SC_SIGHTBLASTER , SI_SIGHTBLASTER , SCB_NONE );
+ set_sc( DC_WINKCHARM , SC_WINKCHARM , SI_WINKCHARM , SCB_NONE );
+ add_sc( MO_BALKYOUNG , SC_STUN );
+ add_sc( SA_ELEMENTWATER , SC_ELEMENTALCHANGE );
+ add_sc( SA_ELEMENTFIRE , SC_ELEMENTALCHANGE );
+ add_sc( SA_ELEMENTGROUND , SC_ELEMENTALCHANGE );
+ add_sc( SA_ELEMENTWIND , SC_ELEMENTALCHANGE );
+
+ set_sc( HLIF_AVOID , SC_AVOID , SI_BLANK , SCB_SPEED );
+ set_sc( HLIF_CHANGE , SC_CHANGE , SI_BLANK , SCB_VIT|SCB_INT );
+ set_sc( HFLI_FLEET , SC_FLEET , SI_BLANK , SCB_ASPD|SCB_BATK|SCB_WATK );
+ set_sc( HFLI_SPEED , SC_SPEED , SI_BLANK , SCB_FLEE );
+ set_sc( HAMI_DEFENCE , SC_DEFENCE , SI_BLANK , SCB_DEF );
+ set_sc( HAMI_BLOODLUST , SC_BLOODLUST , SI_BLANK , SCB_BATK|SCB_WATK );
+
+ // Homunculus S
+ add_sc(MH_STAHL_HORN, SC_STUN);
+ set_sc(MH_ANGRIFFS_MODUS, SC_ANGRIFFS_MODUS, SI_ANGRIFFS_MODUS, SCB_BATK | SCB_DEF | SCB_FLEE | SCB_MAXHP);
+ set_sc(MH_GOLDENE_FERSE, SC_GOLDENE_FERSE, SI_GOLDENE_FERSE, SCB_ASPD|SCB_MAXHP);
+ add_sc( MH_STEINWAND, SC_SAFETYWALL );
+ add_sc(MH_ERASER_CUTTER, SC_ERASER_CUTTER);
+ set_sc(MH_OVERED_BOOST, SC_OVERED_BOOST, SI_BLANK, SCB_FLEE|SCB_ASPD);
+ add_sc(MH_LIGHT_OF_REGENE, SC_LIGHT_OF_REGENE);
+ set_sc(MH_VOLCANIC_ASH, SC_ASH, SI_VOLCANIC_ASH, SCB_DEF|SCB_DEF2|SCB_HIT|SCB_BATK|SCB_FLEE);
+ set_sc(MH_GRANITIC_ARMOR, SC_GRANITIC_ARMOR, SI_GRANITIC_ARMOR, SCB_NONE);
+ set_sc(MH_MAGMA_FLOW, SC_MAGMA_FLOW, SI_MAGMA_FLOW, SCB_NONE);
+ set_sc(MH_PYROCLASTIC, SC_PYROCLASTIC, SI_PYROCLASTIC, SCB_BATK|SCB_ATK_ELE);
+ add_sc(MH_LAVA_SLIDE, SC_BURNING);
+ set_sc(MH_NEEDLE_OF_PARALYZE, SC_PARALYSIS, SI_NEEDLE_OF_PARALYZE, SCB_DEF2);
+ add_sc(MH_POISON_MIST, SC_BLIND);
+ set_sc(MH_PAIN_KILLER, SC_PAIN_KILLER, SI_PAIN_KILLER, SCB_ASPD);
+
+ add_sc(MH_STYLE_CHANGE, SC_STYLE_CHANGE);
+
+
+ add_sc( MER_CRASH , SC_STUN );
+ set_sc( MER_PROVOKE , SC_PROVOKE , SI_PROVOKE , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK );
+ add_sc( MS_MAGNUM , SC_WATK_ELEMENT );
+ add_sc( MER_SIGHT , SC_SIGHT );
+ set_sc( MER_DECAGI , SC_DECREASEAGI , SI_DECREASEAGI , SCB_AGI|SCB_SPEED );
+ set_sc( MER_MAGNIFICAT , SC_MAGNIFICAT , SI_MAGNIFICAT , SCB_REGEN );
+ add_sc( MER_LEXDIVINA , SC_SILENCE );
+ add_sc( MA_LANDMINE , SC_STUN );
+ add_sc( MA_SANDMAN , SC_SLEEP );
+ add_sc( MA_FREEZINGTRAP , SC_FREEZE );
+ set_sc( MER_AUTOBERSERK , SC_AUTOBERSERK , SI_AUTOBERSERK , SCB_NONE );
+ set_sc( ML_AUTOGUARD , SC_AUTOGUARD , SI_AUTOGUARD , SCB_NONE );
+ set_sc( MS_REFLECTSHIELD , SC_REFLECTSHIELD , SI_REFLECTSHIELD , SCB_NONE );
+ set_sc( ML_DEFENDER , SC_DEFENDER , SI_DEFENDER , SCB_SPEED|SCB_ASPD );
+ set_sc( MS_PARRYING , SC_PARRYING , SI_PARRYING , SCB_NONE );
+ set_sc( MS_BERSERK , SC_BERSERK , SI_BERSERK , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2|SCB_FLEE|SCB_SPEED|SCB_ASPD|SCB_MAXHP|SCB_REGEN );
+ add_sc( ML_SPIRALPIERCE , SC_STOP );
+ set_sc( MER_QUICKEN , SC_MERC_QUICKEN , SI_BLANK , SCB_ASPD );
+ add_sc( ML_DEVOTION , SC_DEVOTION );
+ set_sc( MER_KYRIE , SC_KYRIE , SI_KYRIE , SCB_NONE );
+ set_sc( MER_BLESSING , SC_BLESSING , SI_BLESSING , SCB_STR|SCB_INT|SCB_DEX );
+ set_sc( MER_INCAGI , SC_INCREASEAGI , SI_INCREASEAGI , SCB_AGI|SCB_SPEED );
+
+ set_sc( GD_LEADERSHIP , SC_LEADERSHIP , SI_BLANK , SCB_STR );
+ set_sc( GD_GLORYWOUNDS , SC_GLORYWOUNDS , SI_BLANK , SCB_VIT );
+ set_sc( GD_SOULCOLD , SC_SOULCOLD , SI_BLANK , SCB_AGI );
+ set_sc( GD_HAWKEYES , SC_HAWKEYES , SI_BLANK , SCB_DEX );
+
+ set_sc( GD_BATTLEORDER , SC_BATTLEORDERS , SI_BLANK , SCB_STR|SCB_INT|SCB_DEX );
+ set_sc( GD_REGENERATION , SC_REGENERATION , SI_BLANK , SCB_REGEN );
+
+ /**
+ * Rune Knight
+ **/
+ set_sc( RK_ENCHANTBLADE , SC_ENCHANTBLADE , SI_ENCHANTBLADE , SCB_NONE );
+ set_sc( RK_DRAGONHOWLING , SC_FEAR , SI_BLANK , SCB_FLEE|SCB_HIT );
+ set_sc( RK_DEATHBOUND , SC_DEATHBOUND , SI_DEATHBOUND , SCB_NONE );
+ set_sc( RK_WINDCUTTER , SC_FEAR , SI_BLANK , SCB_FLEE|SCB_HIT );
+ add_sc( RK_DRAGONBREATH , SC_BURNING );
+ set_sc( RK_MILLENNIUMSHIELD , SC_MILLENNIUMSHIELD , SI_REUSE_MILLENNIUMSHIELD , SCB_NONE );
+ set_sc( RK_REFRESH , SC_REFRESH , SI_REFRESH , SCB_NONE );
+ set_sc( RK_GIANTGROWTH , SC_GIANTGROWTH , SI_GIANTGROWTH , SCB_STR );
+ set_sc( RK_STONEHARDSKIN , SC_STONEHARDSKIN , SI_STONEHARDSKIN , SCB_NONE );
+ set_sc( RK_VITALITYACTIVATION, SC_VITALITYACTIVATION, SI_VITALITYACTIVATION, SCB_REGEN );
+ set_sc( RK_FIGHTINGSPIRIT , SC_FIGHTINGSPIRIT , SI_FIGHTINGSPIRIT , SCB_WATK|SCB_ASPD );
+ set_sc( RK_ABUNDANCE , SC_ABUNDANCE , SI_ABUNDANCE , SCB_NONE );
+ /**
+ * GC Guillotine Cross
+ **/
+ set_sc_with_vfx( GC_VENOMIMPRESS , SC_VENOMIMPRESS , SI_VENOMIMPRESS , SCB_NONE );
+ set_sc( GC_POISONINGWEAPON , SC_POISONINGWEAPON , SI_POISONINGWEAPON , SCB_NONE );
+ set_sc( GC_WEAPONBLOCKING , SC_WEAPONBLOCKING , SI_WEAPONBLOCKING , SCB_NONE );
+ set_sc( GC_CLOAKINGEXCEED , SC_CLOAKINGEXCEED , SI_CLOAKINGEXCEED , SCB_SPEED );
+ set_sc( GC_HALLUCINATIONWALK , SC_HALLUCINATIONWALK, SI_HALLUCINATIONWALK, SCB_FLEE );
+ set_sc( GC_ROLLINGCUTTER , SC_ROLLINGCUTTER , SI_ROLLINGCUTTER , SCB_NONE );
+ /**
+ * Arch Bishop
+ **/
+ set_sc( AB_ADORAMUS , SC_ADORAMUS , SI_ADORAMUS , SCB_AGI|SCB_SPEED );
+ add_sc( AB_CLEMENTIA , SC_BLESSING );
+ add_sc( AB_CANTO , SC_INCREASEAGI );
+ set_sc( AB_EPICLESIS , SC_EPICLESIS , SI_EPICLESIS , SCB_MAXHP );
+ add_sc( AB_PRAEFATIO , SC_KYRIE );
+ set_sc_with_vfx( AB_ORATIO , SC_ORATIO , SI_ORATIO , SCB_NONE );
+ set_sc( AB_LAUDAAGNUS , SC_LAUDAAGNUS , SI_LAUDAAGNUS , SCB_VIT );
+ set_sc( AB_LAUDARAMUS , SC_LAUDARAMUS , SI_LAUDARAMUS , SCB_LUK );
+ set_sc( AB_RENOVATIO , SC_RENOVATIO , SI_RENOVATIO , SCB_REGEN );
+ set_sc( AB_EXPIATIO , SC_EXPIATIO , SI_EXPIATIO , SCB_ATK_ELE );
+ set_sc( AB_DUPLELIGHT , SC_DUPLELIGHT , SI_DUPLELIGHT , SCB_NONE );
+ set_sc( AB_SECRAMENT , SC_SECRAMENT , SI_SECRAMENT , SCB_NONE );
+ /**
+ * Warlock
+ **/
+ add_sc( WL_WHITEIMPRISON , SC_WHITEIMPRISON );
+ set_sc_with_vfx( WL_FROSTMISTY , SC_FREEZING , SI_FROSTMISTY , SCB_ASPD|SCB_SPEED|SCB_DEF|SCB_DEF2 );
+ set_sc( WL_MARSHOFABYSS , SC_MARSHOFABYSS , SI_MARSHOFABYSS , SCB_SPEED|SCB_FLEE|SCB_DEF|SCB_MDEF );
+ set_sc( WL_RECOGNIZEDSPELL , SC_RECOGNIZEDSPELL , SI_RECOGNIZEDSPELL , SCB_NONE );
+ set_sc( WL_STASIS , SC_STASIS , SI_STASIS , SCB_NONE );
+ /**
+ * Ranger
+ **/
+ set_sc( RA_FEARBREEZE , SC_FEARBREEZE , SI_FEARBREEZE , SCB_NONE );
+ set_sc( RA_ELECTRICSHOCKER , SC_ELECTRICSHOCKER , SI_ELECTRICSHOCKER , SCB_NONE );
+ set_sc( RA_WUGDASH , SC_WUGDASH , SI_WUGDASH , SCB_SPEED );
+ set_sc( RA_CAMOUFLAGE , SC_CAMOUFLAGE , SI_CAMOUFLAGE , SCB_SPEED );
+ add_sc( RA_MAGENTATRAP , SC_ELEMENTALCHANGE );
+ add_sc( RA_COBALTTRAP , SC_ELEMENTALCHANGE );
+ add_sc( RA_MAIZETRAP , SC_ELEMENTALCHANGE );
+ add_sc( RA_VERDURETRAP , SC_ELEMENTALCHANGE );
+ add_sc( RA_FIRINGTRAP , SC_BURNING );
+ set_sc_with_vfx( RA_ICEBOUNDTRAP , SC_FREEZING , SI_FROSTMISTY , SCB_NONE );
+ /**
+ * Mechanic
+ **/
+ set_sc( NC_ACCELERATION , SC_ACCELERATION , SI_ACCELERATION , SCB_SPEED );
+ set_sc( NC_HOVERING , SC_HOVERING , SI_HOVERING , SCB_SPEED );
+ set_sc( NC_SHAPESHIFT , SC_SHAPESHIFT , SI_SHAPESHIFT , SCB_DEF_ELE );
+ set_sc( NC_INFRAREDSCAN , SC_INFRAREDSCAN , SI_INFRAREDSCAN , SCB_FLEE );
+ set_sc( NC_ANALYZE , SC_ANALYZE , SI_ANALYZE , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2 );
+ set_sc( NC_MAGNETICFIELD , SC_MAGNETICFIELD , SI_MAGNETICFIELD , SCB_NONE );
+ set_sc( NC_NEUTRALBARRIER , SC_NEUTRALBARRIER , SI_NEUTRALBARRIER , SCB_NONE );
+ set_sc( NC_STEALTHFIELD , SC_STEALTHFIELD , SI_STEALTHFIELD , SCB_NONE );
+ /**
+ * Royal Guard
+ **/
+ set_sc( LG_REFLECTDAMAGE , SC_REFLECTDAMAGE , SI_LG_REFLECTDAMAGE, SCB_NONE );
+ set_sc( LG_FORCEOFVANGUARD , SC_FORCEOFVANGUARD , SI_FORCEOFVANGUARD , SCB_MAXHP|SCB_DEF );
+ set_sc( LG_EXEEDBREAK , SC_EXEEDBREAK , SI_EXEEDBREAK , SCB_NONE );
+ set_sc( LG_PRESTIGE , SC_PRESTIGE , SI_PRESTIGE , SCB_DEF );
+ set_sc( LG_BANDING , SC_BANDING , SI_BANDING , SCB_DEF2|SCB_WATK );// Renewal: atk2 & def2
+ set_sc( LG_PIETY , SC_BENEDICTIO , SI_BENEDICTIO , SCB_DEF_ELE );
+ set_sc( LG_EARTHDRIVE , SC_EARTHDRIVE , SI_EARTHDRIVE , SCB_DEF|SCB_ASPD );
+ set_sc( LG_INSPIRATION , SC_INSPIRATION , SI_INSPIRATION , SCB_MAXHP|SCB_WATK|SCB_HIT|SCB_VIT|SCB_AGI|SCB_STR|SCB_DEX|SCB_INT|SCB_LUK);
+ set_sc( LG_SHIELDSPELL , SC_SHIELDSPELL_DEF , SI_SHIELDSPELL_DEF , SCB_WATK );
+ set_sc( LG_SHIELDSPELL , SC_SHIELDSPELL_REF , SI_SHIELDSPELL_REF , SCB_DEF );
+ /**
+ * Shadow Chaser
+ **/
+ set_sc( SC_REPRODUCE , SC__REPRODUCE , SI_REPRODUCE , SCB_NONE );
+ set_sc( SC_AUTOSHADOWSPELL , SC__AUTOSHADOWSPELL, SI_AUTOSHADOWSPELL , SCB_NONE );
+ set_sc( SC_SHADOWFORM , SC__SHADOWFORM , SI_SHADOWFORM , SCB_NONE );
+ set_sc( SC_BODYPAINT , SC__BODYPAINT , SI_BODYPAINT , SCB_ASPD );
+ set_sc( SC_INVISIBILITY , SC__INVISIBILITY , SI_INVISIBILITY , SCB_ASPD|SCB_CRI|SCB_ATK_ELE );
+ set_sc( SC_DEADLYINFECT , SC__DEADLYINFECT , SI_DEADLYINFECT , SCB_NONE );
+ set_sc( SC_ENERVATION , SC__ENERVATION , SI_ENERVATION , SCB_BATK );
+ set_sc( SC_GROOMY , SC__GROOMY , SI_GROOMY , SCB_ASPD|SCB_HIT|SCB_SPEED );
+ set_sc( SC_IGNORANCE , SC__IGNORANCE , SI_IGNORANCE , SCB_NONE );
+ set_sc( SC_LAZINESS , SC__LAZINESS , SI_LAZINESS , SCB_FLEE );
+ set_sc( SC_UNLUCKY , SC__UNLUCKY , SI_UNLUCKY , SCB_CRI|SCB_FLEE2 );
+ set_sc( SC_WEAKNESS , SC__WEAKNESS , SI_WEAKNESS , SCB_FLEE2|SCB_MAXHP );
+ set_sc( SC_STRIPACCESSARY , SC__STRIPACCESSORY , SI_STRIPACCESSARY , SCB_DEX|SCB_INT|SCB_LUK );
+ set_sc_with_vfx( SC_MANHOLE , SC__MANHOLE , SI_MANHOLE , SCB_NONE );
+ add_sc( SC_CHAOSPANIC , SC_CONFUSION );
+ set_sc_with_vfx( SC_BLOODYLUST , SC__BLOODYLUST , SI_BLOODYLUST , SCB_DEF | SCB_DEF2 | SCB_MDEF | SCB_MDEF2 | SCB_FLEE | SCB_SPEED | SCB_ASPD | SCB_MAXHP | SCB_REGEN );
+ /**
+ * Sura
+ **/
+ add_sc( SR_DRAGONCOMBO , SC_STUN );
+ add_sc( SR_EARTHSHAKER , SC_STUN );
+ set_sc( SR_CRESCENTELBOW , SC_CRESCENTELBOW , SI_CRESCENTELBOW , SCB_NONE );
+ set_sc_with_vfx( SR_CURSEDCIRCLE , SC_CURSEDCIRCLE_TARGET, SI_CURSEDCIRCLE_TARGET , SCB_NONE );
+ set_sc( SR_LIGHTNINGWALK , SC_LIGHTNINGWALK , SI_LIGHTNINGWALK , SCB_NONE );
+ set_sc( SR_RAISINGDRAGON , SC_RAISINGDRAGON , SI_RAISINGDRAGON , SCB_REGEN|SCB_MAXHP|SCB_MAXSP );
+ set_sc( SR_GENTLETOUCH_ENERGYGAIN, SC_GT_ENERGYGAIN , SI_GENTLETOUCH_ENERGYGAIN, SCB_NONE );
+ set_sc( SR_GENTLETOUCH_CHANGE , SC_GT_CHANGE , SI_GENTLETOUCH_CHANGE , SCB_ASPD|SCB_MDEF|SCB_MAXHP );
+ set_sc( SR_GENTLETOUCH_REVITALIZE, SC_GT_REVITALIZE , SI_GENTLETOUCH_REVITALIZE, SCB_MAXHP|SCB_REGEN );
+ /**
+ * Wanderer / Minstrel
+ **/
+ set_sc( WA_SWING_DANCE , SC_SWINGDANCE , SI_SWINGDANCE , SCB_SPEED|SCB_ASPD );
+ set_sc( WA_SYMPHONY_OF_LOVER , SC_SYMPHONYOFLOVER , SI_SYMPHONYOFLOVERS , SCB_MDEF );
+ set_sc( WA_MOONLIT_SERENADE , SC_MOONLITSERENADE , SI_MOONLITSERENADE , SCB_MATK );
+ set_sc( MI_RUSH_WINDMILL , SC_RUSHWINDMILL , SI_RUSHWINDMILL , SCB_BATK );
+ set_sc( MI_ECHOSONG , SC_ECHOSONG , SI_ECHOSONG , SCB_DEF2 );
+ set_sc( MI_HARMONIZE , SC_HARMONIZE , SI_HARMONIZE , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
+ set_sc_with_vfx( WM_POEMOFNETHERWORLD , SC_NETHERWORLD , SI_NETHERWORLD , SCB_NONE );
+ set_sc_with_vfx( WM_VOICEOFSIREN , SC_VOICEOFSIREN , SI_VOICEOFSIREN , SCB_NONE );
+ set_sc_with_vfx( WM_LULLABY_DEEPSLEEP , SC_DEEPSLEEP , SI_DEEPSLEEP , SCB_NONE );
+ set_sc( WM_SIRCLEOFNATURE , SC_SIRCLEOFNATURE , SI_SIRCLEOFNATURE , SCB_NONE );
+ set_sc( WM_GLOOMYDAY , SC_GLOOMYDAY , SI_GLOOMYDAY , SCB_FLEE|SCB_ASPD );
+ set_sc( WM_SONG_OF_MANA , SC_SONGOFMANA , SI_SONGOFMANA , SCB_NONE );
+ set_sc( WM_DANCE_WITH_WUG , SC_DANCEWITHWUG , SI_DANCEWITHWUG , SCB_ASPD );
+ set_sc( WM_SATURDAY_NIGHT_FEVER , SC_SATURDAYNIGHTFEVER , SI_SATURDAYNIGHTFEVER , SCB_BATK|SCB_DEF|SCB_FLEE|SCB_REGEN );
+ set_sc( WM_LERADS_DEW , SC_LERADSDEW , SI_LERADSDEW , SCB_MAXHP );
+ set_sc( WM_MELODYOFSINK , SC_MELODYOFSINK , SI_MELODYOFSINK , SCB_BATK|SCB_MATK );
+ set_sc( WM_BEYOND_OF_WARCRY , SC_BEYONDOFWARCRY , SI_WARCRYOFBEYOND , SCB_BATK|SCB_MATK );
+ set_sc( WM_UNLIMITED_HUMMING_VOICE, SC_UNLIMITEDHUMMINGVOICE, SI_UNLIMITEDHUMMINGVOICE, SCB_NONE );
+ /**
+ * Sorcerer
+ **/
+ set_sc( SO_FIREWALK , SC_PROPERTYWALK , SI_PROPERTYWALK , SCB_NONE );
+ set_sc( SO_ELECTRICWALK , SC_PROPERTYWALK , SI_PROPERTYWALK , SCB_NONE );
+ set_sc( SO_SPELLFIST , SC_SPELLFIST , SI_SPELLFIST , SCB_NONE );
+ set_sc_with_vfx( SO_DIAMONDDUST , SC_CRYSTALIZE , SI_COLD , SCB_NONE ); // it does show the snow icon on mobs but doesn't affect it.
+ add_sc( SO_CLOUD_KILL , SC_POISON );
+ set_sc( SO_STRIKING , SC_STRIKING , SI_STRIKING , SCB_WATK|SCB_CRI );
+ set_sc( SO_WARMER , SC_WARMER , SI_WARMER , SCB_NONE );
+ set_sc( SO_VACUUM_EXTREME , SC_VACUUM_EXTREME , SI_VACUUM_EXTREME , SCB_NONE );
+ set_sc( SO_ARRULLO , SC_DEEPSLEEP , SI_DEEPSLEEP , SCB_NONE );
+ set_sc( SO_FIRE_INSIGNIA , SC_FIRE_INSIGNIA , SI_FIRE_INSIGNIA , SCB_MATK | SCB_BATK | SCB_WATK | SCB_ATK_ELE | SCB_REGEN );
+ set_sc( SO_WATER_INSIGNIA , SC_WATER_INSIGNIA , SI_WATER_INSIGNIA , SCB_WATK | SCB_ATK_ELE | SCB_REGEN );
+ set_sc( SO_WIND_INSIGNIA , SC_WIND_INSIGNIA , SI_WIND_INSIGNIA , SCB_WATK | SCB_ATK_ELE | SCB_REGEN );
+ set_sc( SO_EARTH_INSIGNIA , SC_EARTH_INSIGNIA , SI_EARTH_INSIGNIA , SCB_MDEF|SCB_DEF|SCB_MAXHP|SCB_MAXSP|SCB_WATK | SCB_ATK_ELE | SCB_REGEN );
+ /**
+ * Genetic
+ **/
+ set_sc( GN_CARTBOOST , SC_GN_CARTBOOST, SI_CARTSBOOST , SCB_SPEED );
+ set_sc( GN_THORNS_TRAP , SC_THORNSTRAP , SI_THORNTRAP , SCB_NONE );
+ set_sc_with_vfx( GN_BLOOD_SUCKER , SC_BLOODSUCKER , SI_BLOODSUCKER , SCB_NONE );
+ set_sc( GN_WALLOFTHORN , SC_STOP , SI_BLANK , SCB_NONE );
+ set_sc( GN_FIRE_EXPANSION_SMOKE_POWDER, SC_SMOKEPOWDER , SI_FIRE_EXPANSION_SMOKE_POWDER, SCB_NONE );
+ set_sc( GN_FIRE_EXPANSION_TEAR_GAS , SC_TEARGAS , SI_FIRE_EXPANSION_TEAR_GAS , SCB_NONE );
+ set_sc( GN_MANDRAGORA , SC_MANDRAGORA , SI_MANDRAGORA , SCB_INT );
+
+ // Elemental Spirit summoner's 'side' status changes.
+ set_sc( EL_CIRCLE_OF_FIRE , SC_CIRCLE_OF_FIRE_OPTION, SI_CIRCLE_OF_FIRE_OPTION, SCB_NONE );
+ set_sc( EL_FIRE_CLOAK , SC_FIRE_CLOAK_OPTION , SI_FIRE_CLOAK_OPTION , SCB_ALL );
+ set_sc( EL_WATER_SCREEN , SC_WATER_SCREEN_OPTION , SI_WATER_SCREEN_OPTION , SCB_NONE );
+ set_sc( EL_WATER_DROP , SC_WATER_DROP_OPTION , SI_WATER_DROP_OPTION , SCB_ALL );
+ set_sc( EL_WATER_BARRIER , SC_WATER_BARRIER , SI_WATER_BARRIER , SCB_MDEF|SCB_WATK|SCB_MATK|SCB_FLEE );
+ set_sc( EL_WIND_STEP , SC_WIND_STEP_OPTION , SI_WIND_STEP_OPTION , SCB_SPEED|SCB_FLEE );
+ set_sc( EL_WIND_CURTAIN , SC_WIND_CURTAIN_OPTION , SI_WIND_CURTAIN_OPTION , SCB_ALL );
+ set_sc( EL_ZEPHYR , SC_ZEPHYR , SI_ZEPHYR , SCB_FLEE );
+ set_sc( EL_SOLID_SKIN , SC_SOLID_SKIN_OPTION , SI_SOLID_SKIN_OPTION , SCB_DEF|SCB_MAXHP );
+ set_sc( EL_STONE_SHIELD , SC_STONE_SHIELD_OPTION , SI_STONE_SHIELD_OPTION , SCB_ALL );
+ set_sc( EL_POWER_OF_GAIA , SC_POWER_OF_GAIA , SI_POWER_OF_GAIA , SCB_MAXHP|SCB_DEF|SCB_SPEED );
+ set_sc( EL_PYROTECHNIC , SC_PYROTECHNIC_OPTION , SI_PYROTECHNIC_OPTION , SCB_WATK );
+ set_sc( EL_HEATER , SC_HEATER_OPTION , SI_HEATER_OPTION , SCB_WATK );
+ set_sc( EL_TROPIC , SC_TROPIC_OPTION , SI_TROPIC_OPTION , SCB_WATK );
+ set_sc( EL_AQUAPLAY , SC_AQUAPLAY_OPTION , SI_AQUAPLAY_OPTION , SCB_MATK );
+ set_sc( EL_COOLER , SC_COOLER_OPTION , SI_COOLER_OPTION , SCB_MATK );
+ set_sc( EL_CHILLY_AIR , SC_CHILLY_AIR_OPTION , SI_CHILLY_AIR_OPTION , SCB_MATK );
+ set_sc( EL_GUST , SC_GUST_OPTION , SI_GUST_OPTION , SCB_NONE );
+ set_sc( EL_BLAST , SC_BLAST_OPTION , SI_BLAST_OPTION , SCB_NONE );
+ set_sc( EL_WILD_STORM , SC_WILD_STORM_OPTION , SI_WILD_STORM_OPTION , SCB_NONE );
+ set_sc( EL_PETROLOGY , SC_PETROLOGY_OPTION , SI_PETROLOGY_OPTION , SCB_NONE );
+ set_sc( EL_CURSED_SOIL , SC_CURSED_SOIL_OPTION , SI_CURSED_SOIL_OPTION , SCB_NONE );
+ set_sc( EL_UPHEAVAL , SC_UPHEAVAL_OPTION , SI_UPHEAVAL_OPTION , SCB_NONE );
+ set_sc( EL_TIDAL_WEAPON , SC_TIDAL_WEAPON_OPTION , SI_TIDAL_WEAPON_OPTION , SCB_ALL );
+ set_sc( EL_ROCK_CRUSHER , SC_ROCK_CRUSHER , SI_ROCK_CRUSHER , SCB_DEF );
+ set_sc( EL_ROCK_CRUSHER_ATK, SC_ROCK_CRUSHER_ATK , SI_ROCK_CRUSHER_ATK , SCB_SPEED );
+
+ add_sc( KO_YAMIKUMO , SC_HIDING );
+ set_sc_with_vfx( KO_JYUMONJIKIRI , SC_JYUMONJIKIRI , SI_KO_JYUMONJIKIRI , SCB_NONE );
+ add_sc( KO_MAKIBISHI , SC_STUN );
+ set_sc( KO_MEIKYOUSISUI , SC_MEIKYOUSISUI , SI_MEIKYOUSISUI , SCB_NONE );
+ set_sc( KO_KYOUGAKU , SC_KYOUGAKU , SI_KYOUGAKU , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
+ add_sc( KO_JYUSATSU , SC_CURSE );
+ set_sc( KO_ZENKAI , SC_ZENKAI , SI_ZENKAI , SCB_NONE );
+ set_sc( KO_IZAYOI , SC_IZAYOI , SI_IZAYOI , SCB_MATK );
+ set_sc( KG_KYOMU , SC_KYOMU , SI_KYOMU , SCB_NONE );
+ set_sc( KG_KAGEMUSYA , SC_KAGEMUSYA , SI_KAGEMUSYA , SCB_NONE );
+ set_sc( KG_KAGEHUMI , SC_KAGEHUMI , SI_KG_KAGEHUMI , SCB_NONE );
+ set_sc( OB_ZANGETSU , SC_ZANGETSU , SI_ZANGETSU , SCB_MATK|SCB_BATK );
+ set_sc_with_vfx( OB_AKAITSUKI , SC_AKAITSUKI , SI_AKAITSUKI , SCB_NONE );
+ set_sc( OB_OBOROGENSOU , SC_GENSOU , SI_GENSOU , SCB_NONE );
+
+ // Storing the target job rather than simply SC_SPIRIT simplifies code later on.
+ SkillStatusChangeTable[SL_ALCHEMIST] = (sc_type)MAPID_ALCHEMIST,
+ SkillStatusChangeTable[SL_MONK] = (sc_type)MAPID_MONK,
+ SkillStatusChangeTable[SL_STAR] = (sc_type)MAPID_STAR_GLADIATOR,
+ SkillStatusChangeTable[SL_SAGE] = (sc_type)MAPID_SAGE,
+ SkillStatusChangeTable[SL_CRUSADER] = (sc_type)MAPID_CRUSADER,
+ SkillStatusChangeTable[SL_SUPERNOVICE] = (sc_type)MAPID_SUPER_NOVICE,
+ SkillStatusChangeTable[SL_KNIGHT] = (sc_type)MAPID_KNIGHT,
+ SkillStatusChangeTable[SL_WIZARD] = (sc_type)MAPID_WIZARD,
+ SkillStatusChangeTable[SL_PRIEST] = (sc_type)MAPID_PRIEST,
+ SkillStatusChangeTable[SL_BARDDANCER] = (sc_type)MAPID_BARDDANCER,
+ SkillStatusChangeTable[SL_ROGUE] = (sc_type)MAPID_ROGUE,
+ SkillStatusChangeTable[SL_ASSASIN] = (sc_type)MAPID_ASSASSIN,
+ SkillStatusChangeTable[SL_BLACKSMITH] = (sc_type)MAPID_BLACKSMITH,
+ SkillStatusChangeTable[SL_HUNTER] = (sc_type)MAPID_HUNTER,
+ SkillStatusChangeTable[SL_SOULLINKER] = (sc_type)MAPID_SOUL_LINKER,
+
+ //Status that don't have a skill associated.
+ StatusIconChangeTable[SC_WEIGHT50] = SI_WEIGHT50;
+ StatusIconChangeTable[SC_WEIGHT90] = SI_WEIGHT90;
+ StatusIconChangeTable[SC_ASPDPOTION0] = SI_ASPDPOTION0;
+ StatusIconChangeTable[SC_ASPDPOTION1] = SI_ASPDPOTION1;
+ StatusIconChangeTable[SC_ASPDPOTION2] = SI_ASPDPOTION2;
+ StatusIconChangeTable[SC_ASPDPOTION3] = SI_ASPDPOTIONINFINITY;
+ StatusIconChangeTable[SC_SPEEDUP0] = SI_MOVHASTE_HORSE;
+ StatusIconChangeTable[SC_SPEEDUP1] = SI_SPEEDPOTION1;
+ StatusIconChangeTable[SC_INCSTR] = SI_INCSTR;
+ StatusIconChangeTable[SC_MIRACLE] = SI_SPIRIT;
+ StatusIconChangeTable[SC_INTRAVISION] = SI_INTRAVISION;
+ StatusIconChangeTable[SC_STRFOOD] = SI_FOODSTR;
+ StatusIconChangeTable[SC_AGIFOOD] = SI_FOODAGI;
+ StatusIconChangeTable[SC_VITFOOD] = SI_FOODVIT;
+ StatusIconChangeTable[SC_INTFOOD] = SI_FOODINT;
+ StatusIconChangeTable[SC_DEXFOOD] = SI_FOODDEX;
+ StatusIconChangeTable[SC_LUKFOOD] = SI_FOODLUK;
+ StatusIconChangeTable[SC_FLEEFOOD]= SI_FOODFLEE;
+ StatusIconChangeTable[SC_HITFOOD] = SI_FOODHIT;
+ StatusIconChangeTable[SC_MANU_ATK] = SI_MANU_ATK;
+ StatusIconChangeTable[SC_MANU_DEF] = SI_MANU_DEF;
+ StatusIconChangeTable[SC_SPL_ATK] = SI_SPL_ATK;
+ StatusIconChangeTable[SC_SPL_DEF] = SI_SPL_DEF;
+ StatusIconChangeTable[SC_MANU_MATK] = SI_MANU_MATK;
+ StatusIconChangeTable[SC_SPL_MATK] = SI_SPL_MATK;
+ //Cash Items
+ StatusIconChangeTable[SC_FOOD_STR_CASH] = SI_FOOD_STR_CASH;
+ StatusIconChangeTable[SC_FOOD_AGI_CASH] = SI_FOOD_AGI_CASH;
+ StatusIconChangeTable[SC_FOOD_VIT_CASH] = SI_FOOD_VIT_CASH;
+ StatusIconChangeTable[SC_FOOD_DEX_CASH] = SI_FOOD_DEX_CASH;
+ StatusIconChangeTable[SC_FOOD_INT_CASH] = SI_FOOD_INT_CASH;
+ StatusIconChangeTable[SC_FOOD_LUK_CASH] = SI_FOOD_LUK_CASH;
+ StatusIconChangeTable[SC_EXPBOOST] = SI_EXPBOOST;
+ StatusIconChangeTable[SC_ITEMBOOST] = SI_ITEMBOOST;
+ StatusIconChangeTable[SC_JEXPBOOST] = SI_CASH_PLUSONLYJOBEXP;
+ StatusIconChangeTable[SC_LIFEINSURANCE] = SI_LIFEINSURANCE;
+ StatusIconChangeTable[SC_BOSSMAPINFO] = SI_BOSSMAPINFO;
+ StatusIconChangeTable[SC_DEF_RATE] = SI_DEF_RATE;
+ StatusIconChangeTable[SC_MDEF_RATE] = SI_MDEF_RATE;
+ StatusIconChangeTable[SC_INCCRI] = SI_INCCRI;
+ StatusIconChangeTable[SC_INCFLEE2] = SI_PLUSAVOIDVALUE;
+ StatusIconChangeTable[SC_INCHEALRATE] = SI_INCHEALRATE;
+ StatusIconChangeTable[SC_S_LIFEPOTION] = SI_S_LIFEPOTION;
+ StatusIconChangeTable[SC_L_LIFEPOTION] = SI_L_LIFEPOTION;
+ StatusIconChangeTable[SC_SPCOST_RATE] = SI_ATKER_BLOOD;
+ StatusIconChangeTable[SC_COMMONSC_RESIST] = SI_TARGET_BLOOD;
+ // Mercenary Bonus Effects
+ StatusIconChangeTable[SC_MERC_FLEEUP] = SI_MERC_FLEEUP;
+ StatusIconChangeTable[SC_MERC_ATKUP] = SI_MERC_ATKUP;
+ StatusIconChangeTable[SC_MERC_HPUP] = SI_MERC_HPUP;
+ StatusIconChangeTable[SC_MERC_SPUP] = SI_MERC_SPUP;
+ StatusIconChangeTable[SC_MERC_HITUP] = SI_MERC_HITUP;
+ // Warlock Spheres
+ StatusIconChangeTable[SC_SPHERE_1] = SI_SPHERE_1;
+ StatusIconChangeTable[SC_SPHERE_2] = SI_SPHERE_2;
+ StatusIconChangeTable[SC_SPHERE_3] = SI_SPHERE_3;
+ StatusIconChangeTable[SC_SPHERE_4] = SI_SPHERE_4;
+ StatusIconChangeTable[SC_SPHERE_5] = SI_SPHERE_5;
+ // Warlock Preserved spells
+ StatusIconChangeTable[SC_SPELLBOOK1] = SI_SPELLBOOK1;
+ StatusIconChangeTable[SC_SPELLBOOK2] = SI_SPELLBOOK2;
+ StatusIconChangeTable[SC_SPELLBOOK3] = SI_SPELLBOOK3;
+ StatusIconChangeTable[SC_SPELLBOOK4] = SI_SPELLBOOK4;
+ StatusIconChangeTable[SC_SPELLBOOK5] = SI_SPELLBOOK5;
+ StatusIconChangeTable[SC_SPELLBOOK6] = SI_SPELLBOOK6;
+ StatusIconChangeTable[SC_MAXSPELLBOOK] = SI_SPELLBOOK7;
+
+ StatusIconChangeTable[SC_NEUTRALBARRIER_MASTER] = SI_NEUTRALBARRIER_MASTER;
+ StatusIconChangeTable[SC_STEALTHFIELD_MASTER] = SI_STEALTHFIELD_MASTER;
+ StatusIconChangeTable[SC_OVERHEAT] = SI_OVERHEAT;
+ StatusIconChangeTable[SC_OVERHEAT_LIMITPOINT] = SI_OVERHEAT_LIMITPOINT;
+
+ StatusIconChangeTable[SC_HALLUCINATIONWALK_POSTDELAY] = SI_HALLUCINATIONWALK_POSTDELAY;
+ StatusIconChangeTable[SC_TOXIN] = SI_TOXIN;
+ StatusIconChangeTable[SC_PARALYSE] = SI_PARALYSE;
+ StatusIconChangeTable[SC_VENOMBLEED] = SI_VENOMBLEED;
+ StatusIconChangeTable[SC_MAGICMUSHROOM] = SI_MAGICMUSHROOM;
+ StatusIconChangeTable[SC_DEATHHURT] = SI_DEATHHURT;
+ StatusIconChangeTable[SC_PYREXIA] = SI_PYREXIA;
+ StatusIconChangeTable[SC_OBLIVIONCURSE] = SI_OBLIVIONCURSE;
+ StatusIconChangeTable[SC_LEECHESEND] = SI_LEECHESEND;
+
+ StatusIconChangeTable[SC_SHIELDSPELL_DEF] = SI_SHIELDSPELL_DEF;
+ StatusIconChangeTable[SC_SHIELDSPELL_MDEF] = SI_SHIELDSPELL_MDEF;
+ StatusIconChangeTable[SC_SHIELDSPELL_REF] = SI_SHIELDSPELL_REF;
+ StatusIconChangeTable[SC_BANDING_DEFENCE] = SI_BANDING_DEFENCE;
+
+ StatusIconChangeTable[SC_GLOOMYDAY_SK] = SI_GLOOMYDAY;
+
+ StatusIconChangeTable[SC_CURSEDCIRCLE_ATKER] = SI_CURSEDCIRCLE_ATKER;
+
+ StatusIconChangeTable[SC_STOMACHACHE] = SI_STOMACHACHE;
+ StatusIconChangeTable[SC_MYSTERIOUS_POWDER] = SI_MYSTERIOUS_POWDER;
+ StatusIconChangeTable[SC_MELON_BOMB] = SI_MELON_BOMB;
+ StatusIconChangeTable[SC_BANANA_BOMB] = SI_BANANA_BOMB;
+ StatusIconChangeTable[SC_BANANA_BOMB_SITDOWN] = SI_BANANA_BOMB_SITDOWN_POSTDELAY;
+
+ //Genetics New Food Items Status Icons
+ StatusIconChangeTable[SC_SAVAGE_STEAK] = SI_SAVAGE_STEAK;
+ StatusIconChangeTable[SC_COCKTAIL_WARG_BLOOD] = SI_COCKTAIL_WARG_BLOOD;
+ StatusIconChangeTable[SC_MINOR_BBQ] = SI_MINOR_BBQ;
+ StatusIconChangeTable[SC_SIROMA_ICE_TEA] = SI_SIROMA_ICE_TEA;
+ StatusIconChangeTable[SC_DROCERA_HERB_STEAMED] = SI_DROCERA_HERB_STEAMED;
+ StatusIconChangeTable[SC_PUTTI_TAILS_NOODLES] = SI_PUTTI_TAILS_NOODLES;
+
+ StatusIconChangeTable[SC_BOOST500] |= SI_BOOST500;
+ StatusIconChangeTable[SC_FULL_SWING_K] |= SI_FULL_SWING_K;
+ StatusIconChangeTable[SC_MANA_PLUS] |= SI_MANA_PLUS;
+ StatusIconChangeTable[SC_MUSTLE_M] |= SI_MUSTLE_M;
+ StatusIconChangeTable[SC_LIFE_FORCE_F] |= SI_LIFE_FORCE_F;
+ StatusIconChangeTable[SC_EXTRACT_WHITE_POTION_Z] |= SI_EXTRACT_WHITE_POTION_Z;
+ StatusIconChangeTable[SC_VITATA_500] |= SI_VITATA_500;
+ StatusIconChangeTable[SC_EXTRACT_SALAMINE_JUICE] |= SI_EXTRACT_SALAMINE_JUICE;
+
+ // Elemental Spirit's 'side' status change icons.
+ StatusIconChangeTable[SC_CIRCLE_OF_FIRE] = SI_CIRCLE_OF_FIRE;
+ StatusIconChangeTable[SC_FIRE_CLOAK] = SI_FIRE_CLOAK;
+ StatusIconChangeTable[SC_WATER_SCREEN] = SI_WATER_SCREEN;
+ StatusIconChangeTable[SC_WATER_DROP] = SI_WATER_DROP;
+ StatusIconChangeTable[SC_WIND_STEP] = SI_WIND_STEP;
+ StatusIconChangeTable[SC_WIND_CURTAIN] = SI_WIND_CURTAIN;
+ StatusIconChangeTable[SC_SOLID_SKIN] = SI_SOLID_SKIN;
+ StatusIconChangeTable[SC_STONE_SHIELD] = SI_STONE_SHIELD;
+ StatusIconChangeTable[SC_PYROTECHNIC] = SI_PYROTECHNIC;
+ StatusIconChangeTable[SC_HEATER] = SI_HEATER;
+ StatusIconChangeTable[SC_TROPIC] = SI_TROPIC;
+ StatusIconChangeTable[SC_AQUAPLAY] = SI_AQUAPLAY;
+ StatusIconChangeTable[SC_COOLER] = SI_COOLER;
+ StatusIconChangeTable[SC_CHILLY_AIR] = SI_CHILLY_AIR;
+ StatusIconChangeTable[SC_GUST] = SI_GUST;
+ StatusIconChangeTable[SC_BLAST] = SI_BLAST;
+ StatusIconChangeTable[SC_WILD_STORM] = SI_WILD_STORM;
+ StatusIconChangeTable[SC_PETROLOGY] = SI_PETROLOGY;
+ StatusIconChangeTable[SC_CURSED_SOIL] = SI_CURSED_SOIL;
+ StatusIconChangeTable[SC_UPHEAVAL] = SI_UPHEAVAL;
+ StatusIconChangeTable[SC_PUSH_CART] = SI_ON_PUSH_CART;
+
+ //Other SC which are not necessarily associated to skills.
+ StatusChangeFlagTable[SC_ASPDPOTION0] = SCB_ASPD;
+ StatusChangeFlagTable[SC_ASPDPOTION1] = SCB_ASPD;
+ StatusChangeFlagTable[SC_ASPDPOTION2] = SCB_ASPD;
+ StatusChangeFlagTable[SC_ASPDPOTION3] = SCB_ASPD;
+ StatusChangeFlagTable[SC_SPEEDUP0] = SCB_SPEED;
+ StatusChangeFlagTable[SC_SPEEDUP1] = SCB_SPEED;
+ StatusChangeFlagTable[SC_ATKPOTION] = SCB_BATK;
+ StatusChangeFlagTable[SC_MATKPOTION] = SCB_MATK;
+ StatusChangeFlagTable[SC_INCALLSTATUS] |= SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK;
+ StatusChangeFlagTable[SC_INCSTR] |= SCB_STR;
+ StatusChangeFlagTable[SC_INCAGI] |= SCB_AGI;
+ StatusChangeFlagTable[SC_INCVIT] |= SCB_VIT;
+ StatusChangeFlagTable[SC_INCINT] |= SCB_INT;
+ StatusChangeFlagTable[SC_INCDEX] |= SCB_DEX;
+ StatusChangeFlagTable[SC_INCLUK] |= SCB_LUK;
+ StatusChangeFlagTable[SC_INCHIT] |= SCB_HIT;
+ StatusChangeFlagTable[SC_INCHITRATE] |= SCB_HIT;
+ StatusChangeFlagTable[SC_INCFLEE] |= SCB_FLEE;
+ StatusChangeFlagTable[SC_INCFLEERATE] |= SCB_FLEE;
+ StatusChangeFlagTable[SC_INCCRI] |= SCB_CRI;
+ StatusChangeFlagTable[SC_INCASPDRATE] |= SCB_ASPD;
+ StatusChangeFlagTable[SC_INCFLEE2] |= SCB_FLEE2;
+ StatusChangeFlagTable[SC_INCMHPRATE] |= SCB_MAXHP;
+ StatusChangeFlagTable[SC_INCMSPRATE] |= SCB_MAXSP;
+ StatusChangeFlagTable[SC_INCMHP] |= SCB_MAXHP;
+ StatusChangeFlagTable[SC_INCMSP] |= SCB_MAXSP;
+ StatusChangeFlagTable[SC_INCATKRATE] |= SCB_BATK|SCB_WATK;
+ StatusChangeFlagTable[SC_INCMATKRATE] |= SCB_MATK;
+ StatusChangeFlagTable[SC_INCDEFRATE] |= SCB_DEF;
+ StatusChangeFlagTable[SC_STRFOOD] |= SCB_STR;
+ StatusChangeFlagTable[SC_AGIFOOD] |= SCB_AGI;
+ StatusChangeFlagTable[SC_VITFOOD] |= SCB_VIT;
+ StatusChangeFlagTable[SC_INTFOOD] |= SCB_INT;
+ StatusChangeFlagTable[SC_DEXFOOD] |= SCB_DEX;
+ StatusChangeFlagTable[SC_LUKFOOD] |= SCB_LUK;
+ StatusChangeFlagTable[SC_HITFOOD] |= SCB_HIT;
+ StatusChangeFlagTable[SC_FLEEFOOD] |= SCB_FLEE;
+ StatusChangeFlagTable[SC_BATKFOOD] |= SCB_BATK;
+ StatusChangeFlagTable[SC_WATKFOOD] |= SCB_WATK;
+ StatusChangeFlagTable[SC_MATKFOOD] |= SCB_MATK;
+ StatusChangeFlagTable[SC_ARMOR_ELEMENT] |= SCB_ALL;
+ StatusChangeFlagTable[SC_ARMOR_RESIST] |= SCB_ALL;
+ StatusChangeFlagTable[SC_SPCOST_RATE] |= SCB_ALL;
+ StatusChangeFlagTable[SC_WALKSPEED] |= SCB_SPEED;
+ StatusChangeFlagTable[SC_ITEMSCRIPT] |= SCB_ALL;
+ // Cash Items
+ StatusChangeFlagTable[SC_FOOD_STR_CASH] = SCB_STR;
+ StatusChangeFlagTable[SC_FOOD_AGI_CASH] = SCB_AGI;
+ StatusChangeFlagTable[SC_FOOD_VIT_CASH] = SCB_VIT;
+ StatusChangeFlagTable[SC_FOOD_DEX_CASH] = SCB_DEX;
+ StatusChangeFlagTable[SC_FOOD_INT_CASH] = SCB_INT;
+ StatusChangeFlagTable[SC_FOOD_LUK_CASH] = SCB_LUK;
+ // Mercenary Bonus Effects
+ StatusChangeFlagTable[SC_MERC_FLEEUP] |= SCB_FLEE;
+ StatusChangeFlagTable[SC_MERC_ATKUP] |= SCB_WATK;
+ StatusChangeFlagTable[SC_MERC_HPUP] |= SCB_MAXHP;
+ StatusChangeFlagTable[SC_MERC_SPUP] |= SCB_MAXSP;
+ StatusChangeFlagTable[SC_MERC_HITUP] |= SCB_HIT;
+ // Guillotine Cross Poison Effects
+ StatusChangeFlagTable[SC_PARALYSE] |= SCB_ASPD|SCB_FLEE|SCB_SPEED;
+ StatusChangeFlagTable[SC_DEATHHURT] |= SCB_REGEN;
+ StatusChangeFlagTable[SC_VENOMBLEED] |= SCB_MAXHP;
+ StatusChangeFlagTable[SC_OBLIVIONCURSE] |= SCB_REGEN;
+
+ StatusChangeFlagTable[SC_SAVAGE_STEAK] |= SCB_STR;
+ StatusChangeFlagTable[SC_COCKTAIL_WARG_BLOOD] |= SCB_INT;
+ StatusChangeFlagTable[SC_MINOR_BBQ] |= SCB_VIT;
+ StatusChangeFlagTable[SC_SIROMA_ICE_TEA] |= SCB_DEX;
+ StatusChangeFlagTable[SC_DROCERA_HERB_STEAMED] |= SCB_AGI;
+ StatusChangeFlagTable[SC_PUTTI_TAILS_NOODLES] |= SCB_LUK;
+ StatusChangeFlagTable[SC_BOOST500] |= SCB_ASPD;
+ StatusChangeFlagTable[SC_FULL_SWING_K] |= SCB_BATK;
+ StatusChangeFlagTable[SC_MANA_PLUS] |= SCB_MATK;
+ StatusChangeFlagTable[SC_MUSTLE_M] |= SCB_MAXHP;
+ StatusChangeFlagTable[SC_LIFE_FORCE_F] |= SCB_MAXSP;
+ StatusChangeFlagTable[SC_EXTRACT_WHITE_POTION_Z] |= SCB_REGEN;
+ StatusChangeFlagTable[SC_VITATA_500] |= SCB_REGEN;
+ StatusChangeFlagTable[SC_EXTRACT_SALAMINE_JUICE] |= SCB_ASPD;
#ifdef RENEWAL_EDP
- // renewal EDP increases your weapon atk
- StatusChangeFlagTable[SC_EDP] |= SCB_WATK;
+ // renewal EDP increases your weapon atk
+ StatusChangeFlagTable[SC_EDP] |= SCB_WATK;
#endif
- if (!battle_config.display_hallucination) //Disable Hallucination.
- StatusIconChangeTable[SC_HALLUCINATION] = SI_BLANK;
-
- /* StatusChangeState (SCS_) NOMOVE */
- StatusChangeStateTable[SC_ANKLE] |= SCS_NOMOVE;
- StatusChangeStateTable[SC_AUTOCOUNTER] |= SCS_NOMOVE;
- StatusChangeStateTable[SC_TRICKDEAD] |= SCS_NOMOVE;
- StatusChangeStateTable[SC_BLADESTOP] |= SCS_NOMOVE;
- StatusChangeStateTable[SC_BLADESTOP_WAIT] |= SCS_NOMOVE;
- StatusChangeStateTable[SC_GOSPEL] |= SCS_NOMOVE|SCS_NOMOVECOND;
- StatusChangeStateTable[SC_BASILICA] |= SCS_NOMOVE|SCS_NOMOVECOND;
- StatusChangeStateTable[SC_STOP] |= SCS_NOMOVE;
- StatusChangeStateTable[SC_CLOSECONFINE] |= SCS_NOMOVE;
- StatusChangeStateTable[SC_CLOSECONFINE2] |= SCS_NOMOVE;
- StatusChangeStateTable[SC_MADNESSCANCEL] |= SCS_NOMOVE;
- StatusChangeStateTable[SC_GRAVITATION] |= SCS_NOMOVE|SCS_NOMOVECOND;
- StatusChangeStateTable[SC_WHITEIMPRISON] |= SCS_NOMOVE;
- StatusChangeStateTable[SC_ELECTRICSHOCKER] |= SCS_NOMOVE;
- StatusChangeStateTable[SC_BITE] |= SCS_NOMOVE;
- StatusChangeStateTable[SC_THORNSTRAP] |= SCS_NOMOVE;
- StatusChangeStateTable[SC_MAGNETICFIELD] |= SCS_NOMOVE;
- StatusChangeStateTable[SC__MANHOLE] |= SCS_NOMOVE;
- StatusChangeStateTable[SC_CURSEDCIRCLE_ATKER] |= SCS_NOMOVE;
- StatusChangeStateTable[SC_CURSEDCIRCLE_TARGET] |= SCS_NOMOVE;
- StatusChangeStateTable[SC_CRYSTALIZE] |= SCS_NOMOVE|SCS_NOMOVECOND;
- StatusChangeStateTable[SC_NETHERWORLD] |= SCS_NOMOVE;
- StatusChangeStateTable[SC_CAMOUFLAGE] |= SCS_NOMOVE|SCS_NOMOVECOND;
- StatusChangeStateTable[SC_MEIKYOUSISUI] |= SCS_NOMOVE;
- StatusChangeStateTable[SC_KAGEHUMI] |= SCS_NOMOVE;
- StatusChangeStateTable[SC_KYOUGAKU] |= SCS_NOMOVE;
-
- /* StatusChangeState (SCS_) NOPICKUPITEMS */
- StatusChangeStateTable[SC_HIDING] |= SCS_NOPICKITEM;
- StatusChangeStateTable[SC_CLOAKING] |= SCS_NOPICKITEM;
- StatusChangeStateTable[SC_TRICKDEAD] |= SCS_NOPICKITEM;
- StatusChangeStateTable[SC_BLADESTOP] |= SCS_NOPICKITEM;
- StatusChangeStateTable[SC_CLOAKINGEXCEED] |= SCS_NOPICKITEM;
- StatusChangeStateTable[SC_NOCHAT] |= SCS_NOPICKITEM|SCS_NOPICKITEMCOND;
-
- /* StatusChangeState (SCS_) NODROPITEMS */
- StatusChangeStateTable[SC_AUTOCOUNTER] |= SCS_NODROPITEM;
- StatusChangeStateTable[SC_BLADESTOP] |= SCS_NODROPITEM;
- StatusChangeStateTable[SC_NOCHAT] |= SCS_NODROPITEM|SCS_NODROPITEMCOND;
-
- /* StatusChangeState (SCS_) NOCAST (skills) */
- StatusChangeStateTable[SC_SILENCE] |= SCS_NOCAST;
- StatusChangeStateTable[SC_STEELBODY] |= SCS_NOCAST;
- StatusChangeStateTable[SC_BERSERK] |= SCS_NOCAST;
- StatusChangeStateTable[SC__BLOODYLUST] |= SCS_NOCAST;
- StatusChangeStateTable[SC_OBLIVIONCURSE] |= SCS_NOCAST;
- StatusChangeStateTable[SC_WHITEIMPRISON] |= SCS_NOCAST;
- StatusChangeStateTable[SC__INVISIBILITY] |= SCS_NOCAST;
- StatusChangeStateTable[SC_CRYSTALIZE] |= SCS_NOCAST|SCS_NOCASTCOND;
- StatusChangeStateTable[SC__IGNORANCE] |= SCS_NOCAST;
- StatusChangeStateTable[SC_DEEPSLEEP] |= SCS_NOCAST;
- StatusChangeStateTable[SC_SATURDAYNIGHTFEVER] |= SCS_NOCAST;
- StatusChangeStateTable[SC_CURSEDCIRCLE_TARGET] |= SCS_NOCAST;
- StatusChangeStateTable[SC_SILENCE] |= SCS_NOCAST;
-
- //Homon S
- StatusChangeStateTable[SC_PARALYSIS] |= SCS_NOMOVE;
+ if( !battle_config.display_hallucination ) //Disable Hallucination.
+ StatusIconChangeTable[SC_HALLUCINATION] = SI_BLANK;
+
+ /* StatusChangeState (SCS_) NOMOVE */
+ StatusChangeStateTable[SC_ANKLE] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_AUTOCOUNTER] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_TRICKDEAD] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_BLADESTOP] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_BLADESTOP_WAIT] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_GOSPEL] |= SCS_NOMOVE|SCS_NOMOVECOND;
+ StatusChangeStateTable[SC_BASILICA] |= SCS_NOMOVE|SCS_NOMOVECOND;
+ StatusChangeStateTable[SC_STOP] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_CLOSECONFINE] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_CLOSECONFINE2] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_MADNESSCANCEL] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_GRAVITATION] |= SCS_NOMOVE|SCS_NOMOVECOND;
+ StatusChangeStateTable[SC_WHITEIMPRISON] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_ELECTRICSHOCKER] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_BITE] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_THORNSTRAP] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_MAGNETICFIELD] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC__MANHOLE] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_CURSEDCIRCLE_ATKER] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_CURSEDCIRCLE_TARGET] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_CRYSTALIZE] |= SCS_NOMOVE|SCS_NOMOVECOND;
+ StatusChangeStateTable[SC_NETHERWORLD] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_CAMOUFLAGE] |= SCS_NOMOVE|SCS_NOMOVECOND;
+ StatusChangeStateTable[SC_MEIKYOUSISUI] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_KAGEHUMI] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_KYOUGAKU] |= SCS_NOMOVE;
+
+ /* StatusChangeState (SCS_) NOPICKUPITEMS */
+ StatusChangeStateTable[SC_HIDING] |= SCS_NOPICKITEM;
+ StatusChangeStateTable[SC_CLOAKING] |= SCS_NOPICKITEM;
+ StatusChangeStateTable[SC_TRICKDEAD] |= SCS_NOPICKITEM;
+ StatusChangeStateTable[SC_BLADESTOP] |= SCS_NOPICKITEM;
+ StatusChangeStateTable[SC_CLOAKINGEXCEED] |= SCS_NOPICKITEM;
+ StatusChangeStateTable[SC_NOCHAT] |= SCS_NOPICKITEM|SCS_NOPICKITEMCOND;
+
+ /* StatusChangeState (SCS_) NODROPITEMS */
+ StatusChangeStateTable[SC_AUTOCOUNTER] |= SCS_NODROPITEM;
+ StatusChangeStateTable[SC_BLADESTOP] |= SCS_NODROPITEM;
+ StatusChangeStateTable[SC_NOCHAT] |= SCS_NODROPITEM|SCS_NODROPITEMCOND;
+
+ /* StatusChangeState (SCS_) NOCAST (skills) */
+ StatusChangeStateTable[SC_SILENCE] |= SCS_NOCAST;
+ StatusChangeStateTable[SC_STEELBODY] |= SCS_NOCAST;
+ StatusChangeStateTable[SC_BERSERK] |= SCS_NOCAST;
+ StatusChangeStateTable[SC__BLOODYLUST] |= SCS_NOCAST;
+ StatusChangeStateTable[SC_OBLIVIONCURSE] |= SCS_NOCAST;
+ StatusChangeStateTable[SC_WHITEIMPRISON] |= SCS_NOCAST;
+ StatusChangeStateTable[SC__INVISIBILITY] |= SCS_NOCAST;
+ StatusChangeStateTable[SC_CRYSTALIZE] |= SCS_NOCAST|SCS_NOCASTCOND;
+ StatusChangeStateTable[SC__IGNORANCE] |= SCS_NOCAST;
+ StatusChangeStateTable[SC_DEEPSLEEP] |= SCS_NOCAST;
+ StatusChangeStateTable[SC_SATURDAYNIGHTFEVER] |= SCS_NOCAST;
+ StatusChangeStateTable[SC_CURSEDCIRCLE_TARGET] |= SCS_NOCAST;
+ StatusChangeStateTable[SC_SILENCE] |= SCS_NOCAST;
+
+ //Homon S
+ StatusChangeStateTable[SC_PARALYSIS] |= SCS_NOMOVE;
}
static void initDummyData(void)
{
- memset(&dummy_status, 0, sizeof(dummy_status));
- dummy_status.hp =
- dummy_status.max_hp =
- dummy_status.max_sp =
- dummy_status.str =
- dummy_status.agi =
- dummy_status.vit =
- dummy_status.int_ =
- dummy_status.dex =
- dummy_status.luk =
- dummy_status.hit = 1;
- dummy_status.speed = 2000;
- dummy_status.adelay = 4000;
- dummy_status.amotion = 2000;
- dummy_status.dmotion = 2000;
- dummy_status.ele_lv = 1; //Min elemental level.
- dummy_status.mode = MD_CANMOVE;
+ memset(&dummy_status, 0, sizeof(dummy_status));
+ dummy_status.hp =
+ dummy_status.max_hp =
+ dummy_status.max_sp =
+ dummy_status.str =
+ dummy_status.agi =
+ dummy_status.vit =
+ dummy_status.int_ =
+ dummy_status.dex =
+ dummy_status.luk =
+ dummy_status.hit = 1;
+ dummy_status.speed = 2000;
+ dummy_status.adelay = 4000;
+ dummy_status.amotion = 2000;
+ dummy_status.dmotion = 2000;
+ dummy_status.ele_lv = 1; //Min elemental level.
+ dummy_status.mode = MD_CANMOVE;
}
//For copying a status_data structure from b to a, without overwriting current Hp and Sp
-static inline void status_cpy(struct status_data *a, const struct status_data *b)
+static inline void status_cpy(struct status_data* a, const struct status_data* b)
{
- memcpy((void *)&a->max_hp, (const void *)&b->max_hp, sizeof(struct status_data)-(sizeof(a->hp)+sizeof(a->sp)));
+ memcpy((void*)&a->max_hp, (const void*)&b->max_hp, sizeof(struct status_data)-(sizeof(a->hp)+sizeof(a->sp)));
}
//Sets HP to given value. Flag is the flag passed to status_heal in case
@@ -1085,17 +1085,17 @@ static inline void status_cpy(struct status_data *a, const struct status_data *b
//on players) It will always succeed (overrides Berserk block), but it can't kill.
int status_set_hp(struct block_list *bl, unsigned int hp, int flag)
{
- struct status_data *status;
- if (hp < 1) return 0;
- status = status_get_status_data(bl);
- if (status == &dummy_status)
- return 0;
-
- if (hp > status->max_hp) hp = status->max_hp;
- if (hp == status->hp) return 0;
- if (hp > status->hp)
- return status_heal(bl, hp - status->hp, 0, 1|flag);
- return status_zap(bl, status->hp - hp, 0);
+ struct status_data *status;
+ if (hp < 1) return 0;
+ status = status_get_status_data(bl);
+ if (status == &dummy_status)
+ return 0;
+
+ if (hp > status->max_hp) hp = status->max_hp;
+ if (hp == status->hp) return 0;
+ if (hp > status->hp)
+ return status_heal(bl, hp - status->hp, 0, 1|flag);
+ return status_zap(bl, status->hp - hp, 0);
}
//Sets SP to given value. Flag is the flag passed to status_heal in case
@@ -1103,24 +1103,24 @@ int status_set_hp(struct block_list *bl, unsigned int hp, int flag)
//on players)
int status_set_sp(struct block_list *bl, unsigned int sp, int flag)
{
- struct status_data *status;
+ struct status_data *status;
- status = status_get_status_data(bl);
- if (status == &dummy_status)
- return 0;
+ status = status_get_status_data(bl);
+ if (status == &dummy_status)
+ return 0;
- if (sp > status->max_sp) sp = status->max_sp;
- if (sp == status->sp) return 0;
- if (sp > status->sp)
- return status_heal(bl, 0, sp - status->sp, 1|flag);
- return status_zap(bl, 0, status->sp - sp);
+ if (sp > status->max_sp) sp = status->max_sp;
+ if (sp == status->sp) return 0;
+ if (sp > status->sp)
+ return status_heal(bl, 0, sp - status->sp, 1|flag);
+ return status_zap(bl, 0, status->sp - sp);
}
-int status_charge(struct block_list *bl, int hp, int sp)
+int status_charge(struct block_list* bl, int hp, int sp)
{
- if (!(bl->type&BL_CONSUME))
- return hp+sp; //Assume all was charged so there are no 'not enough' fails.
- return status_damage(NULL, bl, hp, sp, 0, 3);
+ if(!(bl->type&BL_CONSUME))
+ return hp+sp; //Assume all was charged so there are no 'not enough' fails.
+ return status_damage(NULL, bl, hp, sp, 0, 3);
}
//Inflicts damage on the target with the according walkdelay.
@@ -1130,321 +1130,292 @@ int status_charge(struct block_list *bl, int hp, int sp)
//flag will be set to &8 when damaging sp of a dead character
int status_damage(struct block_list *src,struct block_list *target,int hp, int sp, int walkdelay, int flag)
{
- struct status_data *status;
- struct status_change *sc;
-
- if (sp && !(target->type&BL_CONSUME))
- sp = 0; //Not a valid SP target.
-
- if (hp < 0) { //Assume absorbed damage.
- status_heal(target, -hp, 0, 1);
- hp = 0;
- }
-
- if (sp < 0) {
- status_heal(target, 0, -sp, 1);
- sp = 0;
- }
-
- if (target->type == BL_SKILL)
- return skill_unit_ondamaged((struct skill_unit *)target, src, hp, gettick());
-
- status = status_get_status_data(target);
- if (status == &dummy_status)
- return 0;
-
- if ((unsigned int)hp >= status->hp) {
- if (flag&2) return 0;
- hp = status->hp;
- }
-
- if ((unsigned int)sp > status->sp) {
- if (flag&2) return 0;
- sp = status->sp;
- }
-
- if (!hp && !sp)
- return 0;
-
- if (!status->hp)
- flag |= 8;
-
- // Let through. battle.c/skill.c have the whole logic of when it's possible or
- // not to hurt someone (and this check breaks pet catching) [Skotlex]
- // if (!target->prev && !(flag&2))
- // return 0; //Cannot damage a bl not on a map, except when "charging" hp/sp
-
- sc = status_get_sc(target);
- if (hp && battle_config.invincible_nodamage && src && sc && sc->data[SC_INVINCIBLE] && !sc->data[SC_INVINCIBLEOFF])
- hp = 1;
-
- if (hp && !(flag&1)) {
- if (sc) {
- struct status_change_entry *sce;
- if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
- status_change_end(target, SC_STONE, INVALID_TIMER);
- status_change_end(target, SC_FREEZE, INVALID_TIMER);
- status_change_end(target, SC_SLEEP, INVALID_TIMER);
- status_change_end(target, SC_WINKCHARM, INVALID_TIMER);
- status_change_end(target, SC_CONFUSION, INVALID_TIMER);
- status_change_end(target, SC_TRICKDEAD, INVALID_TIMER);
- status_change_end(target, SC_HIDING, INVALID_TIMER);
- status_change_end(target, SC_CLOAKING, INVALID_TIMER);
- status_change_end(target, SC_CHASEWALK, INVALID_TIMER);
- status_change_end(target, SC_CAMOUFLAGE, INVALID_TIMER);
- status_change_end(target, SC__INVISIBILITY, INVALID_TIMER);
- status_change_end(target, SC_DEEPSLEEP, INVALID_TIMER);
- if ((sce=sc->data[SC_ENDURE]) && !sce->val4) {
- //Endure count is only reduced by non-players on non-gvg maps.
- //val4 signals infinite endure. [Skotlex]
- if (src && src->type != BL_PC && !map_flag_gvg(target->m) && !map[target->m].flag.battleground && --(sce->val2) < 0)
- status_change_end(target, SC_ENDURE, INVALID_TIMER);
- }
- if ((sce=sc->data[SC_GRAVITATION]) && sce->val3 == BCT_SELF) {
- struct skill_unit_group *sg = skill_id2group(sce->val4);
- if (sg) {
- skill_delunitgroup(sg);
- sce->val4 = 0;
- status_change_end(target, SC_GRAVITATION, INVALID_TIMER);
- }
- }
- if (sc->data[SC_DANCING] && (unsigned int)hp > status->max_hp>>2)
- status_change_end(target, SC_DANCING, INVALID_TIMER);
- if (sc->data[SC_CLOAKINGEXCEED] && --(sc->data[SC_CLOAKINGEXCEED]->val2) <= 0)
- status_change_end(target, SC_CLOAKINGEXCEED, INVALID_TIMER);
- if (sc->data[SC_KAGEMUSYA] && --(sc->data[SC_KAGEMUSYA]->val3) <= 0)
- status_change_end(target, SC_KAGEMUSYA, INVALID_TIMER);
- }
- unit_skillcastcancel(target, 2);
- }
-
- status->hp-= hp;
- status->sp-= sp;
-
- if (sc && hp && status->hp) {
- if (sc->data[SC_AUTOBERSERK] &&
- (!sc->data[SC_PROVOKE] || !sc->data[SC_PROVOKE]->val2) &&
- status->hp < status->max_hp>>2)
- sc_start4(target,SC_PROVOKE,100,10,1,0,0,0);
- if (sc->data[SC_BERSERK] && status->hp <= 100)
- status_change_end(target, SC_BERSERK, INVALID_TIMER);
- if (sc->data[SC_RAISINGDRAGON] && status->hp <= 1000)
- status_change_end(target, SC_RAISINGDRAGON, INVALID_TIMER);
- if (sc->data[SC_SATURDAYNIGHTFEVER] && status->hp <= 100)
- status_change_end(target, SC_SATURDAYNIGHTFEVER, INVALID_TIMER);
- if (sc->data[SC__BLOODYLUST] && status->hp <= 100)
- status_change_end(target, SC__BLOODYLUST, INVALID_TIMER);
- }
-
- switch (target->type) {
- case BL_PC:
- pc_damage((TBL_PC *)target,src,hp,sp);
- break;
- case BL_MOB:
- mob_damage((TBL_MOB *)target, src, hp);
- break;
- case BL_HOM:
- merc_damage((TBL_HOM *)target);
- break;
- case BL_MER:
- mercenary_heal((TBL_MER *)target,hp,sp);
- break;
- case BL_ELEM:
- elemental_heal((TBL_ELEM *)target,hp,sp);
- break;
- }
-
- if (src && target->type == BL_PC && ((TBL_PC *)target)->disguise) {// stop walking when attacked in disguise to prevent walk-delay bug
- unit_stop_walking(target, 1);
- }
-
- if (status->hp || (flag&8)) {
- //Still lives or has been dead before this damage.
- if (walkdelay)
- unit_set_walkdelay(target, gettick(), walkdelay, 0);
- return hp+sp;
- }
-
- status->hp = 1; //To let the dead function cast skills and all that.
- //NOTE: These dead functions should return: [Skotlex]
- //0: Death cancelled, auto-revived.
- //Non-zero: Standard death. Clear status, cancel move/attack, etc
- //&2: Also remove object from map.
- //&4: Also delete object from memory.
- switch (target->type) {
- case BL_PC:
- flag = pc_dead((TBL_PC *)target,src);
- break;
- case BL_MOB:
- flag = mob_dead((TBL_MOB *)target, src, flag&4?3:0);
- break;
- case BL_HOM:
- flag = merc_hom_dead((TBL_HOM *)target);
- break;
- case BL_MER:
- flag = mercenary_dead((TBL_MER *)target);
- break;
- case BL_ELEM:
- flag = elemental_dead((TBL_ELEM *)target);
- break;
- default: //Unhandled case, do nothing to object.
- flag = 0;
- break;
- }
-
- if (!flag) //Death cancelled.
- return hp+sp;
-
- //Normal death
- status->hp = 0;
- if (battle_config.clear_unit_ondeath &&
- battle_config.clear_unit_ondeath&target->type)
- skill_clear_unitgroup(target);
-
- if (target->type&BL_REGEN) {
- //Reset regen ticks.
- struct regen_data *regen = status_get_regen_data(target);
- if (regen) {
- memset(&regen->tick, 0, sizeof(regen->tick));
- if (regen->sregen)
- memset(&regen->sregen->tick, 0, sizeof(regen->sregen->tick));
- if (regen->ssregen)
- memset(&regen->ssregen->tick, 0, sizeof(regen->ssregen->tick));
- }
- }
-
- if (sc && sc->data[SC_KAIZEL] && !map_flag_gvg(target->m)) {
- //flag&8 = disable Kaizel
- int time = skill_get_time2(SL_KAIZEL,sc->data[SC_KAIZEL]->val1);
- //Look for Osiris Card's bonus effect on the character and revive 100% or revive normally
- if (target->type == BL_PC && BL_CAST(BL_PC,target)->special_state.restart_full_recover)
- status_revive(target, 100, 100);
- else
- status_revive(target, sc->data[SC_KAIZEL]->val2, 0);
- status_change_clear(target,0);
- clif_skill_nodamage(target,target,ALL_RESURRECTION,1,1);
- sc_start(target,status_skill2sc(PR_KYRIE),100,10,time);
-
- if (target->type == BL_MOB)
- ((TBL_MOB *)target)->state.rebirth = 1;
-
- return hp+sp;
- }
- if (target->type == BL_PC) {
+ struct status_data *status;
+ struct status_change *sc;
+
+ if(sp && !(target->type&BL_CONSUME))
+ sp = 0; //Not a valid SP target.
+
+ if (hp < 0) { //Assume absorbed damage.
+ status_heal(target, -hp, 0, 1);
+ hp = 0;
+ }
+
+ if (sp < 0) {
+ status_heal(target, 0, -sp, 1);
+ sp = 0;
+ }
+
+ if (target->type == BL_SKILL)
+ return skill_unit_ondamaged((struct skill_unit *)target, src, hp, gettick());
+
+ status = status_get_status_data(target);
+ if( status == &dummy_status )
+ return 0;
+
+ if ((unsigned int)hp >= status->hp) {
+ if (flag&2) return 0;
+ hp = status->hp;
+ }
+
+ if ((unsigned int)sp > status->sp) {
+ if (flag&2) return 0;
+ sp = status->sp;
+ }
+
+ if (!hp && !sp)
+ return 0;
+
+ if( !status->hp )
+ flag |= 8;
+
+// Let through. battle.c/skill.c have the whole logic of when it's possible or
+// not to hurt someone (and this check breaks pet catching) [Skotlex]
+// if (!target->prev && !(flag&2))
+// return 0; //Cannot damage a bl not on a map, except when "charging" hp/sp
+
+ sc = status_get_sc(target);
+ if( hp && battle_config.invincible_nodamage && src && sc && sc->data[SC_INVINCIBLE] && !sc->data[SC_INVINCIBLEOFF] )
+ hp = 1;
+
+ if( hp && !(flag&1) ) {
+ if( sc ) {
+ struct status_change_entry *sce;
+ if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
+ status_change_end(target, SC_STONE, INVALID_TIMER);
+ status_change_end(target, SC_FREEZE, INVALID_TIMER);
+ status_change_end(target, SC_SLEEP, INVALID_TIMER);
+ status_change_end(target, SC_WINKCHARM, INVALID_TIMER);
+ status_change_end(target, SC_CONFUSION, INVALID_TIMER);
+ status_change_end(target, SC_TRICKDEAD, INVALID_TIMER);
+ status_change_end(target, SC_HIDING, INVALID_TIMER);
+ status_change_end(target, SC_CLOAKING, INVALID_TIMER);
+ status_change_end(target, SC_CHASEWALK, INVALID_TIMER);
+ status_change_end(target, SC_CAMOUFLAGE, INVALID_TIMER);
+ status_change_end(target, SC__INVISIBILITY, INVALID_TIMER);
+ status_change_end(target, SC_DEEPSLEEP, INVALID_TIMER);
+ if ((sce=sc->data[SC_ENDURE]) && !sce->val4) {
+ //Endure count is only reduced by non-players on non-gvg maps.
+ //val4 signals infinite endure. [Skotlex]
+ if (src && src->type != BL_PC && !map_flag_gvg(target->m) && !map[target->m].flag.battleground && --(sce->val2) < 0)
+ status_change_end(target, SC_ENDURE, INVALID_TIMER);
+ }
+ if ((sce=sc->data[SC_GRAVITATION]) && sce->val3 == BCT_SELF) {
+ struct skill_unit_group* sg = skill_id2group(sce->val4);
+ if (sg) {
+ skill_delunitgroup(sg);
+ sce->val4 = 0;
+ status_change_end(target, SC_GRAVITATION, INVALID_TIMER);
+ }
+ }
+ if(sc->data[SC_DANCING] && (unsigned int)hp > status->max_hp>>2)
+ status_change_end(target, SC_DANCING, INVALID_TIMER);
+ if(sc->data[SC_CLOAKINGEXCEED] && --(sc->data[SC_CLOAKINGEXCEED]->val2) <= 0)
+ status_change_end(target, SC_CLOAKINGEXCEED, INVALID_TIMER);
+ if(sc->data[SC_KAGEMUSYA] && --(sc->data[SC_KAGEMUSYA]->val3) <= 0)
+ status_change_end(target, SC_KAGEMUSYA, INVALID_TIMER);
+ }
+ unit_skillcastcancel(target, 2);
+ }
+
+ status->hp-= hp;
+ status->sp-= sp;
+
+ if (sc && hp && status->hp) {
+ if (sc->data[SC_AUTOBERSERK] &&
+ (!sc->data[SC_PROVOKE] || !sc->data[SC_PROVOKE]->val2) &&
+ status->hp < status->max_hp>>2)
+ sc_start4(target,SC_PROVOKE,100,10,1,0,0,0);
+ if (sc->data[SC_BERSERK] && status->hp <= 100)
+ status_change_end(target, SC_BERSERK, INVALID_TIMER);
+ if( sc->data[SC_RAISINGDRAGON] && status->hp <= 1000 )
+ status_change_end(target, SC_RAISINGDRAGON, INVALID_TIMER);
+ if (sc->data[SC_SATURDAYNIGHTFEVER] && status->hp <= 100)
+ status_change_end(target, SC_SATURDAYNIGHTFEVER, INVALID_TIMER);
+ if (sc->data[SC__BLOODYLUST] && status->hp <= 100)
+ status_change_end(target, SC__BLOODYLUST, INVALID_TIMER);
+ }
+
+ switch (target->type) {
+ case BL_PC: pc_damage((TBL_PC*)target,src,hp,sp); break;
+ case BL_MOB: mob_damage((TBL_MOB*)target, src, hp); break;
+ case BL_HOM: merc_damage((TBL_HOM*)target); break;
+ case BL_MER: mercenary_heal((TBL_MER*)target,hp,sp); break;
+ case BL_ELEM: elemental_heal((TBL_ELEM*)target,hp,sp); break;
+ }
+
+ if( src && target->type == BL_PC && ((TBL_PC*)target)->disguise ) {// stop walking when attacked in disguise to prevent walk-delay bug
+ unit_stop_walking( target, 1 );
+ }
+
+ if( status->hp || (flag&8) )
+ { //Still lives or has been dead before this damage.
+ if (walkdelay)
+ unit_set_walkdelay(target, gettick(), walkdelay, 0);
+ return hp+sp;
+ }
+
+ status->hp = 1; //To let the dead function cast skills and all that.
+ //NOTE: These dead functions should return: [Skotlex]
+ //0: Death cancelled, auto-revived.
+ //Non-zero: Standard death. Clear status, cancel move/attack, etc
+ //&2: Also remove object from map.
+ //&4: Also delete object from memory.
+ switch (target->type) {
+ case BL_PC: flag = pc_dead((TBL_PC*)target,src); break;
+ case BL_MOB: flag = mob_dead((TBL_MOB*)target, src, flag&4?3:0); break;
+ case BL_HOM: flag = merc_hom_dead((TBL_HOM*)target); break;
+ case BL_MER: flag = mercenary_dead((TBL_MER*)target); break;
+ case BL_ELEM: flag = elemental_dead((TBL_ELEM*)target); break;
+ default: //Unhandled case, do nothing to object.
+ flag = 0;
+ break;
+ }
+
+ if(!flag) //Death cancelled.
+ return hp+sp;
+
+ //Normal death
+ status->hp = 0;
+ if (battle_config.clear_unit_ondeath &&
+ battle_config.clear_unit_ondeath&target->type)
+ skill_clear_unitgroup(target);
+
+ if(target->type&BL_REGEN)
+ { //Reset regen ticks.
+ struct regen_data *regen = status_get_regen_data(target);
+ if (regen) {
+ memset(&regen->tick, 0, sizeof(regen->tick));
+ if (regen->sregen)
+ memset(&regen->sregen->tick, 0, sizeof(regen->sregen->tick));
+ if (regen->ssregen)
+ memset(&regen->ssregen->tick, 0, sizeof(regen->ssregen->tick));
+ }
+ }
+
+ if( sc && sc->data[SC_KAIZEL] && !map_flag_gvg(target->m) )
+ { //flag&8 = disable Kaizel
+ int time = skill_get_time2(SL_KAIZEL,sc->data[SC_KAIZEL]->val1);
+ //Look for Osiris Card's bonus effect on the character and revive 100% or revive normally
+ if ( target->type == BL_PC && BL_CAST(BL_PC,target)->special_state.restart_full_recover )
+ status_revive(target, 100, 100);
+ else
+ status_revive(target, sc->data[SC_KAIZEL]->val2, 0);
+ status_change_clear(target,0);
+ clif_skill_nodamage(target,target,ALL_RESURRECTION,1,1);
+ sc_start(target,status_skill2sc(PR_KYRIE),100,10,time);
+
+ if( target->type == BL_MOB )
+ ((TBL_MOB*)target)->state.rebirth = 1;
+
+ return hp+sp;
+ }
+ if(target->type == BL_PC){
TBL_PC *sd = BL_CAST(BL_PC,target);
TBL_HOM *hd = sd->hd;
- if (hd && hd->sc.data[SC_LIGHT_OF_REGENE]) {
+ if(hd && hd->sc.data[SC_LIGHT_OF_REGENE]){
clif_skillcasting(&hd->bl, hd->bl.id, target->id, 0,0, MH_LIGHT_OF_REGENE, skill_get_ele(MH_LIGHT_OF_REGENE, 1), 10); //just to display usage
clif_skill_nodamage(&sd->bl, target, ALL_RESURRECTION, 1, status_revive(&sd->bl,10*hd->sc.data[SC_LIGHT_OF_REGENE]->val1,0));
status_change_end(&sd->hd->bl,SC_LIGHT_OF_REGENE,INVALID_TIMER);
return hp + sp;
}
}
- if (target->type == BL_MOB && sc && sc->data[SC_REBIRTH] && !((TBL_MOB *) target)->state.rebirth) { // Ensure the monster has not already rebirthed before doing so.
+ if (target->type == BL_MOB && sc && sc->data[SC_REBIRTH] && !((TBL_MOB*) target)->state.rebirth) {// Ensure the monster has not already rebirthed before doing so.
status_revive(target, sc->data[SC_REBIRTH]->val2, 0);
- status_change_clear(target,0);
- ((TBL_MOB *)target)->state.rebirth = 1;
-
- return hp+sp;
- }
-
- status_change_clear(target,0);
-
- if (flag&4) //Delete from memory. (also invokes map removal code)
- unit_free(target,CLR_DEAD);
- else if (flag&2) //remove from map
- unit_remove_map(target,CLR_DEAD);
- else {
- //Some death states that would normally be handled by unit_remove_map
- unit_stop_attack(target);
- unit_stop_walking(target,1);
- unit_skillcastcancel(target,0);
- clif_clearunit_area(target,CLR_DEAD);
- skill_unit_move(target,gettick(),4);
- skill_cleartimerskill(target);
- }
-
- return hp+sp;
+ status_change_clear(target,0);
+ ((TBL_MOB*)target)->state.rebirth = 1;
+
+ return hp+sp;
+ }
+
+ status_change_clear(target,0);
+
+ if(flag&4) //Delete from memory. (also invokes map removal code)
+ unit_free(target,CLR_DEAD);
+ else
+ if(flag&2) //remove from map
+ unit_remove_map(target,CLR_DEAD);
+ else
+ { //Some death states that would normally be handled by unit_remove_map
+ unit_stop_attack(target);
+ unit_stop_walking(target,1);
+ unit_skillcastcancel(target,0);
+ clif_clearunit_area(target,CLR_DEAD);
+ skill_unit_move(target,gettick(),4);
+ skill_cleartimerskill(target);
+ }
+
+ return hp+sp;
}
//Heals a character. If flag&1, this is forced healing (otherwise stuff like Berserk can block it)
//If flag&2, when the player is healed, show the HP/SP heal effect.
int status_heal(struct block_list *bl,int hp,int sp, int flag)
{
- struct status_data *status;
- struct status_change *sc;
-
- status = status_get_status_data(bl);
-
- if (status == &dummy_status || !status->hp)
- return 0;
-
- sc = status_get_sc(bl);
- if (sc && !sc->count)
- sc = NULL;
-
- if (hp < 0) {
- if (hp == INT_MIN) hp++; //-INT_MIN == INT_MIN in some architectures!
- status_damage(NULL, bl, -hp, 0, 0, 1);
- hp = 0;
- }
-
- if (hp) {
- if (sc && (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])) {
- if (flag&1)
- flag &= ~2;
- else
- hp = 0;
- }
-
- if ((unsigned int)hp > status->max_hp - status->hp)
- hp = status->max_hp - status->hp;
- }
-
- if (sp < 0) {
- if (sp==INT_MIN) sp++;
- status_damage(NULL, bl, 0, -sp, 0, 1);
- sp = 0;
- }
-
- if (sp) {
- if ((unsigned int)sp > status->max_sp - status->sp)
- sp = status->max_sp - status->sp;
- }
-
- if (!sp && !hp) return 0;
-
- status->hp+= hp;
- status->sp+= sp;
-
- if (hp && sc &&
- sc->data[SC_AUTOBERSERK] &&
- sc->data[SC_PROVOKE] &&
- sc->data[SC_PROVOKE]->val2==1 &&
- status->hp>=status->max_hp>>2
- ) //End auto berserk.
- status_change_end(bl, SC_PROVOKE, INVALID_TIMER);
-
- // send hp update to client
- switch (bl->type) {
- case BL_PC:
- pc_heal((TBL_PC *)bl,hp,sp,flag&2?1:0);
- break;
- case BL_MOB:
- mob_heal((TBL_MOB *)bl,hp);
- break;
- case BL_HOM:
- merc_hom_heal((TBL_HOM *)bl);
- break;
- case BL_MER:
- mercenary_heal((TBL_MER *)bl,hp,sp);
- break;
- case BL_ELEM:
- elemental_heal((TBL_ELEM *)bl,hp,sp);
- break;
- }
+ struct status_data *status;
+ struct status_change *sc;
+
+ status = status_get_status_data(bl);
+
+ if (status == &dummy_status || !status->hp)
+ return 0;
+
+ sc = status_get_sc(bl);
+ if (sc && !sc->count)
+ sc = NULL;
+
+ if (hp < 0) {
+ if (hp == INT_MIN) hp++; //-INT_MIN == INT_MIN in some architectures!
+ status_damage(NULL, bl, -hp, 0, 0, 1);
+ hp = 0;
+ }
+
+ if(hp) {
+ if( sc && (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]) ) {
+ if( flag&1 )
+ flag &= ~2;
+ else
+ hp = 0;
+ }
- return hp+sp;
+ if((unsigned int)hp > status->max_hp - status->hp)
+ hp = status->max_hp - status->hp;
+ }
+
+ if(sp < 0) {
+ if (sp==INT_MIN) sp++;
+ status_damage(NULL, bl, 0, -sp, 0, 1);
+ sp = 0;
+ }
+
+ if(sp) {
+ if((unsigned int)sp > status->max_sp - status->sp)
+ sp = status->max_sp - status->sp;
+ }
+
+ if(!sp && !hp) return 0;
+
+ status->hp+= hp;
+ status->sp+= sp;
+
+ if(hp && sc &&
+ sc->data[SC_AUTOBERSERK] &&
+ sc->data[SC_PROVOKE] &&
+ sc->data[SC_PROVOKE]->val2==1 &&
+ status->hp>=status->max_hp>>2
+ ) //End auto berserk.
+ status_change_end(bl, SC_PROVOKE, INVALID_TIMER);
+
+ // send hp update to client
+ switch(bl->type) {
+ case BL_PC: pc_heal((TBL_PC*)bl,hp,sp,flag&2?1:0); break;
+ case BL_MOB: mob_heal((TBL_MOB*)bl,hp); break;
+ case BL_HOM: merc_hom_heal((TBL_HOM*)bl); break;
+ case BL_MER: mercenary_heal((TBL_MER*)bl,hp,sp); break;
+ case BL_ELEM: elemental_heal((TBL_ELEM*)bl,hp,sp); break;
+ }
+
+ return hp+sp;
}
//Does percentual non-flinching damage/heal. If mob is killed this way,
@@ -1455,812 +1426,825 @@ int status_heal(struct block_list *bl,int hp,int sp, int flag)
//Furthermore, if flag==2, then the target must not die from the substraction.
int status_percent_change(struct block_list *src,struct block_list *target,signed char hp_rate, signed char sp_rate, int flag)
{
- struct status_data *status;
- unsigned int hp =0, sp = 0;
-
- status = status_get_status_data(target);
-
- //Change the equation when the values are high enough to discard the
- //imprecision in exchange of overflow protection [Skotlex]
- //Also add 100% checks since those are the most used cases where we don't
- //want aproximation errors.
- if (hp_rate > 99)
- hp = status->hp;
- else if (hp_rate > 0)
- hp = status->hp>10000?
- hp_rate*(status->hp/100):
- (hp_rate*status->hp)/100;
- else if (hp_rate < -99)
- hp = status->max_hp;
- else if (hp_rate < 0)
- hp = status->max_hp>10000?
- (-hp_rate)*(status->max_hp/100):
- (-hp_rate*status->max_hp)/100;
- if (hp_rate && !hp)
- hp = 1;
-
- if (flag == 2 && hp >= status->hp)
- hp = status->hp-1; //Must not kill target.
-
- //Should be safe to not do overflow protection here, noone should have
- //millions upon millions of SP
- if (sp_rate > 99)
- sp = status->sp;
- else if (sp_rate > 0)
- sp = (sp_rate*status->sp)/100;
- else if (sp_rate < -99)
- sp = status->max_sp;
- else if (sp_rate < 0)
- sp = (-sp_rate)*status->max_sp/100;
- if (sp_rate && !sp)
- sp = 1;
-
- //Ugly check in case damage dealt is too much for the received args of
- //status_heal / status_damage. [Skotlex]
- if (hp > INT_MAX) {
- hp -= INT_MAX;
- if (flag)
- status_damage(src, target, INT_MAX, 0, 0, (!src||src==target?5:1));
- else
- status_heal(target, INT_MAX, 0, 0);
- }
- if (sp > INT_MAX) {
- sp -= INT_MAX;
- if (flag)
- status_damage(src, target, 0, INT_MAX, 0, (!src||src==target?5:1));
- else
- status_heal(target, 0, INT_MAX, 0);
- }
- if (flag)
- return status_damage(src, target, hp, sp, 0, (!src||src==target?5:1));
- return status_heal(target, hp, sp, 0);
+ struct status_data *status;
+ unsigned int hp =0, sp = 0;
+
+ status = status_get_status_data(target);
+
+ //Change the equation when the values are high enough to discard the
+ //imprecision in exchange of overflow protection [Skotlex]
+ //Also add 100% checks since those are the most used cases where we don't
+ //want aproximation errors.
+ if (hp_rate > 99)
+ hp = status->hp;
+ else if (hp_rate > 0)
+ hp = status->hp>10000?
+ hp_rate*(status->hp/100):
+ (hp_rate*status->hp)/100;
+ else if (hp_rate < -99)
+ hp = status->max_hp;
+ else if (hp_rate < 0)
+ hp = status->max_hp>10000?
+ (-hp_rate)*(status->max_hp/100):
+ (-hp_rate*status->max_hp)/100;
+ if (hp_rate && !hp)
+ hp = 1;
+
+ if (flag == 2 && hp >= status->hp)
+ hp = status->hp-1; //Must not kill target.
+
+ //Should be safe to not do overflow protection here, noone should have
+ //millions upon millions of SP
+ if (sp_rate > 99)
+ sp = status->sp;
+ else if (sp_rate > 0)
+ sp = (sp_rate*status->sp)/100;
+ else if (sp_rate < -99)
+ sp = status->max_sp;
+ else if (sp_rate < 0)
+ sp = (-sp_rate)*status->max_sp/100;
+ if (sp_rate && !sp)
+ sp = 1;
+
+ //Ugly check in case damage dealt is too much for the received args of
+ //status_heal / status_damage. [Skotlex]
+ if (hp > INT_MAX) {
+ hp -= INT_MAX;
+ if (flag)
+ status_damage(src, target, INT_MAX, 0, 0, (!src||src==target?5:1));
+ else
+ status_heal(target, INT_MAX, 0, 0);
+ }
+ if (sp > INT_MAX) {
+ sp -= INT_MAX;
+ if (flag)
+ status_damage(src, target, 0, INT_MAX, 0, (!src||src==target?5:1));
+ else
+ status_heal(target, 0, INT_MAX, 0);
+ }
+ if (flag)
+ return status_damage(src, target, hp, sp, 0, (!src||src==target?5:1));
+ return status_heal(target, hp, sp, 0);
}
int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per_sp)
{
- struct status_data *status;
- unsigned int hp, sp;
- if (!status_isdead(bl)) return 0;
-
- status = status_get_status_data(bl);
- if (status == &dummy_status)
- return 0; //Invalid target.
-
- hp = status->max_hp * per_hp/100;
- sp = status->max_sp * per_sp/100;
-
- if (hp > status->max_hp - status->hp)
- hp = status->max_hp - status->hp;
- else if (per_hp && !hp)
- hp = 1;
-
- if (sp > status->max_sp - status->sp)
- sp = status->max_sp - status->sp;
- else if (per_sp && !sp)
- sp = 1;
-
- status->hp += hp;
- status->sp += sp;
-
- if (bl->prev) //Animation only if character is already on a map.
- clif_resurrection(bl, 1);
- switch (bl->type) {
- case BL_PC:
- pc_revive((TBL_PC *)bl, hp, sp);
- break;
- case BL_MOB:
- mob_revive((TBL_MOB *)bl, hp);
- break;
- case BL_HOM:
- merc_hom_revive((TBL_HOM *)bl, hp, sp);
- break;
- }
- return 1;
+ struct status_data *status;
+ unsigned int hp, sp;
+ if (!status_isdead(bl)) return 0;
+
+ status = status_get_status_data(bl);
+ if (status == &dummy_status)
+ return 0; //Invalid target.
+
+ hp = status->max_hp * per_hp/100;
+ sp = status->max_sp * per_sp/100;
+
+ if(hp > status->max_hp - status->hp)
+ hp = status->max_hp - status->hp;
+ else if (per_hp && !hp)
+ hp = 1;
+
+ if(sp > status->max_sp - status->sp)
+ sp = status->max_sp - status->sp;
+ else if (per_sp && !sp)
+ sp = 1;
+
+ status->hp += hp;
+ status->sp += sp;
+
+ if (bl->prev) //Animation only if character is already on a map.
+ clif_resurrection(bl, 1);
+ switch (bl->type) {
+ case BL_PC: pc_revive((TBL_PC*)bl, hp, sp); break;
+ case BL_MOB: mob_revive((TBL_MOB*)bl, hp); break;
+ case BL_HOM: merc_hom_revive((TBL_HOM*)bl, hp, sp); break;
+ }
+ return 1;
}
/*==========================================
* Checks whether the src can use the skill on the target,
* taking into account status/option of both source/target. [Skotlex]
* flag:
- * 0 - Trying to use skill on target.
- * 1 - Cast bar is done.
- * 2 - Skill already pulled off, check is due to ground-based skills or splash-damage ones.
+ * 0 - Trying to use skill on target.
+ * 1 - Cast bar is done.
+ * 2 - Skill already pulled off, check is due to ground-based skills or splash-damage ones.
* src MAY be null to indicate we shouldn't check it, this is a ground-based skill attack.
* target MAY Be null, in which case the checks are only to see
* whether the source can cast or not the skill on the ground.
*------------------------------------------*/
int status_check_skilluse(struct block_list *src, struct block_list *target, int skill_num, int flag)
{
- struct status_data *status;
- struct status_change *sc=NULL, *tsc;
- int hide_flag;
-
- status = src?status_get_status_data(src):&dummy_status;
-
- if (src && src->type != BL_PC && status_isdead(src))
- return 0;
-
- if (!skill_num) { //Normal attack checks.
- if (!(status->mode&MD_CANATTACK))
- return 0; //This mode is only needed for melee attacking.
- //Dead state is not checked for skills as some skills can be used
- //on dead characters, said checks are left to skill.c [Skotlex]
- if (target && status_isdead(target))
- return 0;
- if (src && (sc = status_get_sc(src)) && sc->data[SC_CRYSTALIZE] && src->type != BL_MOB)
- return 0;
- }
-
- switch (skill_num) {
- case PA_PRESSURE:
- if (flag && target) {
- //Gloria Avoids pretty much everything....
- tsc = status_get_sc(target);
- if (tsc && tsc->option&OPTION_HIDE)
- return 0;
- }
- break;
- case GN_WALLOFTHORN:
- if (target && status_isdead(target))
- return 0;
- break;
- case AL_TELEPORT:
- //Should fail when used on top of Land Protector [Skotlex]
- if (src && map_getcell(src->m, src->x, src->y, CELL_CHKLANDPROTECTOR)
- && !(status->mode&MD_BOSS)
- && (src->type != BL_PC || ((TBL_PC *)src)->skillitem != skill_num))
- return 0;
- break;
- default:
- break;
- }
-
- if (src) sc = status_get_sc(src);
-
- if (sc && sc->count) {
-
- if (skill_num != RK_REFRESH && sc->opt1 >0 && (sc->opt1 != OPT1_CRYSTALIZE && src->type != BL_MOB) && sc->opt1 != OPT1_BURNING && skill_num != SR_GENTLETOUCH_CURE) { //Stuned/Frozen/etc
- if (flag != 1) //Can't cast, casted stuff can't damage.
- return 0;
- if (!(skill_get_inf(skill_num)&INF_GROUND_SKILL))
- return 0; //Targetted spells can't come off.
- }
-
- if (
- (sc->data[SC_TRICKDEAD] && skill_num != NV_TRICKDEAD)
- || (sc->data[SC_AUTOCOUNTER] && !flag)
- || (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF && skill_num != PA_GOSPEL)
- || (sc->data[SC_GRAVITATION] && sc->data[SC_GRAVITATION]->val3 == BCT_SELF && flag != 2)
- )
- return 0;
-
- if (sc->data[SC_WINKCHARM] && target && !flag) { //Prevents skill usage
- if (unit_bl2ud(src) && (unit_bl2ud(src))->walktimer == INVALID_TIMER)
- unit_walktobl(src, map_id2bl(sc->data[SC_WINKCHARM]->val2), 3, 1);
- clif_emotion(src, E_LV);
- return 0;
- }
-
- if (sc->data[SC_BLADESTOP]) {
- switch (sc->data[SC_BLADESTOP]->val1) {
- case 5:
- if (skill_num == MO_EXTREMITYFIST) break;
- case 4:
- if (skill_num == MO_CHAINCOMBO) break;
- case 3:
- if (skill_num == MO_INVESTIGATE) break;
- case 2:
- if (skill_num == MO_FINGEROFFENSIVE) break;
- default:
- return 0;
- }
- }
+ struct status_data *status;
+ struct status_change *sc=NULL, *tsc;
+ int hide_flag;
+
+ status = src?status_get_status_data(src):&dummy_status;
+
+ if (src && src->type != BL_PC && status_isdead(src))
+ return 0;
+
+ if (!skill_num) { //Normal attack checks.
+ if (!(status->mode&MD_CANATTACK))
+ return 0; //This mode is only needed for melee attacking.
+ //Dead state is not checked for skills as some skills can be used
+ //on dead characters, said checks are left to skill.c [Skotlex]
+ if (target && status_isdead(target))
+ return 0;
+ if( src && (sc = status_get_sc(src)) && sc->data[SC_CRYSTALIZE] && src->type != BL_MOB)
+ return 0;
+ }
+
+ switch( skill_num ) {
+ case PA_PRESSURE:
+ if( flag && target ) {
+ //Gloria Avoids pretty much everything....
+ tsc = status_get_sc(target);
+ if(tsc && tsc->option&OPTION_HIDE)
+ return 0;
+ }
+ break;
+ case GN_WALLOFTHORN:
+ if( target && status_isdead(target) )
+ return 0;
+ break;
+ case AL_TELEPORT:
+ //Should fail when used on top of Land Protector [Skotlex]
+ if (src && map_getcell(src->m, src->x, src->y, CELL_CHKLANDPROTECTOR)
+ && !(status->mode&MD_BOSS)
+ && (src->type != BL_PC || ((TBL_PC*)src)->skillitem != skill_num))
+ return 0;
+ break;
+ default:
+ break;
+ }
- if (sc->data[SC_DANCING] && flag!=2) {
- if (src->type == BL_PC && skill_num >= WA_SWING_DANCE && skill_num <= WM_UNLIMITED_HUMMING_VOICE) {
- // Lvl 5 Lesson or higher allow you use 3rd job skills while dancing.v
- if (pc_checkskill((TBL_PC *)src,WM_LESSON) < 5)
- return 0;
- } else if (sc->data[SC_LONGING]) { //Allow everything except dancing/re-dancing. [Skotlex]
- if (skill_num == BD_ENCORE ||
- skill_get_inf2(skill_num)&(INF2_SONG_DANCE|INF2_ENSEMBLE_SKILL)
- )
- return 0;
- } else {
- switch (skill_num) {
- case BD_ADAPTATION:
- case CG_LONGINGFREEDOM:
- case BA_MUSICALSTRIKE:
- case DC_THROWARROW:
- break;
- default:
- return 0;
- }
- }
- if ((sc->data[SC_DANCING]->val1&0xFFFF) == CG_HERMODE && skill_num == BD_ADAPTATION)
- return 0; //Can't amp out of Wand of Hermode :/ [Skotlex]
- }
+ if ( src ) sc = status_get_sc(src);
- if (skill_num && //Do not block item-casted skills.
- (src->type != BL_PC || ((TBL_PC *)src)->skillitem != skill_num)
- ) { //Skills blocked through status changes...
- if (!flag && ( //Blocked only from using the skill (stuff like autospell may still go through
- sc->cant.cast ||
- (sc->data[SC_MARIONETTE] && skill_num != CG_MARIONETTE) || //Only skill you can use is marionette again to cancel it
- (sc->data[SC_MARIONETTE2] && skill_num == CG_MARIONETTE) || //Cannot use marionette if you are being buffed by another
- (sc->data[SC_STASIS] && skill_block_check(src, SC_STASIS, skill_num)) ||
- (sc->data[SC_KAGEHUMI] && skill_block_check(src, SC_KAGEHUMI, skill_num))
- ))
- return 0;
+ if( sc && sc->count ) {
- //Skill blocking.
- if (
- (sc->data[SC_VOLCANO] && skill_num == WZ_ICEWALL) ||
- (sc->data[SC_ROKISWEIL] && skill_num != BD_ADAPTATION) ||
- (sc->data[SC_HERMODE] && skill_get_inf(skill_num) & INF_SUPPORT_SKILL) ||
- (sc->data[SC_NOCHAT] && sc->data[SC_NOCHAT]->val1&MANNER_NOSKILL)
- )
- return 0;
+ if( sc->opt1 >0 && (sc->opt1 != OPT1_CRYSTALIZE && src->type != BL_MOB) && sc->opt1 != OPT1_BURNING && skill_num != SR_GENTLETOUCH_CURE ) { //Stuned/Frozen/etc
+ if (flag != 1) //Can't cast, casted stuff can't damage.
+ return 0;
+ if (!(skill_get_inf(skill_num)&INF_GROUND_SKILL))
+ return 0; //Targetted spells can't come off.
+ }
- if (sc->data[SC__MANHOLE] || ((tsc = status_get_sc(target)) && tsc->data[SC__MANHOLE])) {
- switch (skill_num) { //##TODO## make this a flag in skill_db?
- // Skills that can be used even under Man Hole effects.
- case SC_SHADOWFORM:
- case SC_STRIPACCESSARY:
- break;
- default:
- return 0;
- }
- }
+ if (
+ (sc->data[SC_TRICKDEAD] && skill_num != NV_TRICKDEAD)
+ || (sc->data[SC_AUTOCOUNTER] && !flag)
+ || (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF && skill_num != PA_GOSPEL)
+ || (sc->data[SC_GRAVITATION] && sc->data[SC_GRAVITATION]->val3 == BCT_SELF && flag != 2)
+ )
+ return 0;
+
+ if (sc->data[SC_WINKCHARM] && target && !flag) { //Prevents skill usage
+ if( unit_bl2ud(src) && (unit_bl2ud(src))->walktimer == INVALID_TIMER )
+ unit_walktobl(src, map_id2bl(sc->data[SC_WINKCHARM]->val2), 3, 1);
+ clif_emotion(src, E_LV);
+ return 0;
+ }
- }
- }
+ if (sc->data[SC_BLADESTOP]) {
+ switch (sc->data[SC_BLADESTOP]->val1)
+ {
+ case 5: if (skill_num == MO_EXTREMITYFIST) break;
+ case 4: if (skill_num == MO_CHAINCOMBO) break;
+ case 3: if (skill_num == MO_INVESTIGATE) break;
+ case 2: if (skill_num == MO_FINGEROFFENSIVE) break;
+ default: return 0;
+ }
+ }
- if (sc && sc->option) {
- if (sc->option&OPTION_HIDE)
- switch (skill_num) { //Usable skills while hiding.
- case TF_HIDING:
- case AS_GRIMTOOTH:
- case RG_BACKSTAP:
- case RG_RAID:
- case NJ_SHADOWJUMP:
- case NJ_KIRIKAGE:
- case KO_YAMIKUMO:
- break;
- default:
- //Non players can use all skills while hidden.
- if (!skill_num || src->type == BL_PC)
- return 0;
- }
- if (sc->option&OPTION_CHASEWALK && skill_num != ST_CHASEWALK)
- return 0;
- if (sc->option&OPTION_MOUNTING)
- return 0;//New mounts can't attack nor use skills in the client; this check makes it cheat-safe [Ind]
- }
+ if (sc->data[SC_DANCING] && flag!=2) {
+ if( src->type == BL_PC && skill_num >= WA_SWING_DANCE && skill_num <= WM_UNLIMITED_HUMMING_VOICE )
+ { // Lvl 5 Lesson or higher allow you use 3rd job skills while dancing.v
+ if( pc_checkskill((TBL_PC*)src,WM_LESSON) < 5 )
+ return 0;
+ } else if(sc->data[SC_LONGING]) { //Allow everything except dancing/re-dancing. [Skotlex]
+ if (skill_num == BD_ENCORE ||
+ skill_get_inf2(skill_num)&(INF2_SONG_DANCE|INF2_ENSEMBLE_SKILL)
+ )
+ return 0;
+ } else {
+ switch (skill_num) {
+ case BD_ADAPTATION:
+ case CG_LONGINGFREEDOM:
+ case BA_MUSICALSTRIKE:
+ case DC_THROWARROW:
+ break;
+ default:
+ return 0;
+ }
+ }
+ if ((sc->data[SC_DANCING]->val1&0xFFFF) == CG_HERMODE && skill_num == BD_ADAPTATION)
+ return 0; //Can't amp out of Wand of Hermode :/ [Skotlex]
+ }
- if (target == NULL || target == src) //No further checking needed.
- return 1;
-
- tsc = status_get_sc(target);
-
- if (tsc && tsc->count) {
- /* attacks in invincible are capped to 1 damage and handled in batte.c; allow spell break and eske for sealed shrine GDB when in INVINCIBLE state. */
- if (tsc->data[SC_INVINCIBLE] && !tsc->data[SC_INVINCIBLEOFF] && skill_num && !(skill_num&(SA_SPELLBREAKER|SL_SKE)))
- return 0;
- if (!skill_num && tsc->data[SC_TRICKDEAD])
- return 0;
- if ((skill_num == WZ_STORMGUST || skill_num == WZ_FROSTNOVA || skill_num == NJ_HYOUSYOURAKU)
- && tsc->data[SC_FREEZE])
- return 0;
- if (skill_num == PR_LEXAETERNA && (tsc->data[SC_FREEZE] || (tsc->data[SC_STONE] && tsc->opt1 == OPT1_STONE)))
- return 0;
- }
+ if (skill_num && //Do not block item-casted skills.
+ (src->type != BL_PC || ((TBL_PC*)src)->skillitem != skill_num)
+ ) { //Skills blocked through status changes...
+ if (!flag && ( //Blocked only from using the skill (stuff like autospell may still go through
+ sc->cant.cast ||
+ (sc->data[SC_MARIONETTE] && skill_num != CG_MARIONETTE) || //Only skill you can use is marionette again to cancel it
+ (sc->data[SC_MARIONETTE2] && skill_num == CG_MARIONETTE) || //Cannot use marionette if you are being buffed by another
+ (sc->data[SC_STASIS] && skill_block_check(src, SC_STASIS, skill_num)) ||
+ (sc->data[SC_KAGEHUMI] && skill_block_check(src, SC_KAGEHUMI, skill_num))
+ ))
+ return 0;
+
+ //Skill blocking.
+ if (
+ (sc->data[SC_VOLCANO] && skill_num == WZ_ICEWALL) ||
+ (sc->data[SC_ROKISWEIL] && skill_num != BD_ADAPTATION) ||
+ (sc->data[SC_HERMODE] && skill_get_inf(skill_num) & INF_SUPPORT_SKILL) ||
+ (sc->data[SC_NOCHAT] && sc->data[SC_NOCHAT]->val1&MANNER_NOSKILL)
+ )
+ return 0;
+
+ if( sc->data[SC__MANHOLE] || ((tsc = status_get_sc(target)) && tsc->data[SC__MANHOLE]) ) {
+ switch(skill_num) {//##TODO## make this a flag in skill_db?
+ // Skills that can be used even under Man Hole effects.
+ case SC_SHADOWFORM:
+ case SC_STRIPACCESSARY:
+ break;
+ default:
+ return 0;
+ }
+ }
- //If targetting, cloak+hide protect you, otherwise only hiding does.
- hide_flag = flag?OPTION_HIDE:(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK);
-
- //You cannot hide from ground skills.
- if (skill_get_ele(skill_num,1) == ELE_EARTH) //TODO: Need Skill Lv here :/
- hide_flag &= ~OPTION_HIDE;
-
- switch (target->type) {
- case BL_PC: {
- struct map_session_data *sd = (TBL_PC *) target;
- bool is_boss = (status->mode&MD_BOSS);
- bool is_detect = ((status->mode&MD_DETECTOR)?true:false);//god-knows-why gcc doesn't shut up until this happens
- if (pc_isinvisible(sd))
- return 0;
- if (tsc->option&hide_flag && !is_boss &&
- ((sd->special_state.perfect_hiding || !is_detect) ||
- (tsc->data[SC_CLOAKINGEXCEED] && is_detect)))
- return 0;
- if (tsc->data[SC_CAMOUFLAGE] && !(is_boss || is_detect) && !skill_num)
- return 0;
- if (tsc->data[SC_STEALTHFIELD] && !is_boss)
- return 0;
- }
- break;
- case BL_ITEM: //Allow targetting of items to pick'em up (or in the case of mobs, to loot them).
- //TODO: Would be nice if this could be used to judge whether the player can or not pick up the item it targets. [Skotlex]
- if (status->mode&MD_LOOTER)
- return 1;
- return 0;
- case BL_HOM:
- case BL_MER:
- case BL_ELEM:
- if (target->type == BL_HOM && skill_num && battle_config.hom_setting&0x1 && skill_get_inf(skill_num)&INF_SUPPORT_SKILL && battle_get_master(target) != src)
- return 0; // Can't use support skills on Homunculus (only Master/Self)
- if (target->type == BL_MER && (skill_num == PR_ASPERSIO || (skill_num >= SA_FLAMELAUNCHER && skill_num <= SA_SEISMICWEAPON)) && battle_get_master(target) != src)
- return 0; // Can't use Weapon endow skills on Mercenary (only Master)
- if (skill_num == AM_POTIONPITCHER && (target->type == BL_MER || target->type == BL_ELEM))
- return 0; // Can't use Potion Pitcher on Mercenaries
- default:
- //Check for chase-walk/hiding/cloaking opponents.
- if (tsc) {
- if (tsc->option&hide_flag && !(status->mode&(MD_BOSS|MD_DETECTOR)))
- return 0;
- if (tsc->data[SC_STEALTHFIELD] && !(status->mode&MD_BOSS))
- return 0;
- }
- }
- return 1;
+ }
+ }
+
+ if (sc && sc->option)
+ {
+ if (sc->option&OPTION_HIDE)
+ switch (skill_num) { //Usable skills while hiding.
+ case TF_HIDING:
+ case AS_GRIMTOOTH:
+ case RG_BACKSTAP:
+ case RG_RAID:
+ case NJ_SHADOWJUMP:
+ case NJ_KIRIKAGE:
+ case KO_YAMIKUMO:
+ break;
+ default:
+ //Non players can use all skills while hidden.
+ if (!skill_num || src->type == BL_PC)
+ return 0;
+ }
+ if (sc->option&OPTION_CHASEWALK && skill_num != ST_CHASEWALK)
+ return 0;
+ if(sc->option&OPTION_MOUNTING)
+ return 0;//New mounts can't attack nor use skills in the client; this check makes it cheat-safe [Ind]
+ }
+
+ if (target == NULL || target == src) //No further checking needed.
+ return 1;
+
+ tsc = status_get_sc(target);
+
+ if(tsc && tsc->count) {
+ /* attacks in invincible are capped to 1 damage and handled in batte.c; allow spell break and eske for sealed shrine GDB when in INVINCIBLE state. */
+ if( tsc->data[SC_INVINCIBLE] && !tsc->data[SC_INVINCIBLEOFF] && skill_num && !(skill_num&(SA_SPELLBREAKER|SL_SKE)) )
+ return 0;
+ if(!skill_num && tsc->data[SC_TRICKDEAD])
+ return 0;
+ if((skill_num == WZ_STORMGUST || skill_num == WZ_FROSTNOVA || skill_num == NJ_HYOUSYOURAKU)
+ && tsc->data[SC_FREEZE])
+ return 0;
+ if(skill_num == PR_LEXAETERNA && (tsc->data[SC_FREEZE] || (tsc->data[SC_STONE] && tsc->opt1 == OPT1_STONE)))
+ return 0;
+ }
+
+ //If targetting, cloak+hide protect you, otherwise only hiding does.
+ hide_flag = flag?OPTION_HIDE:(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK);
+
+ //You cannot hide from ground skills.
+ if( skill_get_ele(skill_num,1) == ELE_EARTH ) //TODO: Need Skill Lv here :/
+ hide_flag &= ~OPTION_HIDE;
+
+ switch( target->type ) {
+ case BL_PC: {
+ struct map_session_data *sd = (TBL_PC*) target;
+ bool is_boss = (status->mode&MD_BOSS);
+ bool is_detect = ((status->mode&MD_DETECTOR)?true:false);//god-knows-why gcc doesn't shut up until this happens
+ if (pc_isinvisible(sd))
+ return 0;
+ if (tsc->option&hide_flag && !is_boss &&
+ ((sd->special_state.perfect_hiding || !is_detect) ||
+ (tsc->data[SC_CLOAKINGEXCEED] && is_detect)))
+ return 0;
+ if( tsc->data[SC_CAMOUFLAGE] && !(is_boss || is_detect) && !skill_num )
+ return 0;
+ if( tsc->data[SC_STEALTHFIELD] && !is_boss )
+ return 0;
+ }
+ break;
+ case BL_ITEM: //Allow targetting of items to pick'em up (or in the case of mobs, to loot them).
+ //TODO: Would be nice if this could be used to judge whether the player can or not pick up the item it targets. [Skotlex]
+ if (status->mode&MD_LOOTER)
+ return 1;
+ return 0;
+ case BL_HOM:
+ case BL_MER:
+ case BL_ELEM:
+ if( target->type == BL_HOM && skill_num && battle_config.hom_setting&0x1 && skill_get_inf(skill_num)&INF_SUPPORT_SKILL && battle_get_master(target) != src )
+ return 0; // Can't use support skills on Homunculus (only Master/Self)
+ if( target->type == BL_MER && (skill_num == PR_ASPERSIO || (skill_num >= SA_FLAMELAUNCHER && skill_num <= SA_SEISMICWEAPON)) && battle_get_master(target) != src )
+ return 0; // Can't use Weapon endow skills on Mercenary (only Master)
+ if( skill_num == AM_POTIONPITCHER && ( target->type == BL_MER || target->type == BL_ELEM) )
+ return 0; // Can't use Potion Pitcher on Mercenaries
+ default:
+ //Check for chase-walk/hiding/cloaking opponents.
+ if( tsc ) {
+ if( tsc->option&hide_flag && !(status->mode&(MD_BOSS|MD_DETECTOR)))
+ return 0;
+ if( tsc->data[SC_STEALTHFIELD] && !(status->mode&MD_BOSS) )
+ return 0;
+ }
+ }
+ return 1;
}
//Checks whether the source can see and chase target.
int status_check_visibility(struct block_list *src, struct block_list *target)
{
- int view_range;
- struct status_data *status = status_get_status_data(src);
- struct status_change *tsc = status_get_sc(target);
- switch (src->type) {
- case BL_MOB:
- view_range = ((TBL_MOB *)src)->min_chase;
- break;
- case BL_PET:
- view_range = ((TBL_PET *)src)->db->range2;
- break;
- default:
- view_range = AREA_SIZE;
- }
-
- if (src->m != target->m || !check_distance_bl(src, target, view_range))
- return 0;
-
- if (tsc && tsc->data[SC_STEALTHFIELD])
- return 0;
-
- switch (target->type) {
- //Check for chase-walk/hiding/cloaking opponents.
- case BL_PC:
- if (tsc->data[SC_CLOAKINGEXCEED] && !(status->mode&MD_BOSS))
- return 0;
- if ((tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC__INVISIBILITY] || tsc->data[SC_CAMOUFLAGE]) && !(status->mode&MD_BOSS) &&
- (((TBL_PC *)target)->special_state.perfect_hiding || !(status->mode&MD_DETECTOR)))
- return 0;
- break;
- default:
- if (tsc && (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC__INVISIBILITY] || tsc->data[SC_CAMOUFLAGE]) && !(status->mode&(MD_BOSS|MD_DETECTOR)))
- return 0;
-
- }
-
- return 1;
+ int view_range;
+ struct status_data* status = status_get_status_data(src);
+ struct status_change* tsc = status_get_sc(target);
+ switch (src->type) {
+ case BL_MOB:
+ view_range = ((TBL_MOB*)src)->min_chase;
+ break;
+ case BL_PET:
+ view_range = ((TBL_PET*)src)->db->range2;
+ break;
+ default:
+ view_range = AREA_SIZE;
+ }
+
+ if (src->m != target->m || !check_distance_bl(src, target, view_range))
+ return 0;
+
+ if( tsc && tsc->data[SC_STEALTHFIELD] )
+ return 0;
+
+ switch (target->type)
+ { //Check for chase-walk/hiding/cloaking opponents.
+ case BL_PC:
+ if ( tsc->data[SC_CLOAKINGEXCEED] && !(status->mode&MD_BOSS) )
+ return 0;
+ if( (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC__INVISIBILITY] || tsc->data[SC_CAMOUFLAGE]) && !(status->mode&MD_BOSS) &&
+ ( ((TBL_PC*)target)->special_state.perfect_hiding || !(status->mode&MD_DETECTOR) ) )
+ return 0;
+ break;
+ default:
+ if( tsc && (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC__INVISIBILITY] || tsc->data[SC_CAMOUFLAGE]) && !(status->mode&(MD_BOSS|MD_DETECTOR)) )
+ return 0;
+
+ }
+
+ return 1;
}
// Basic ASPD value
-int status_base_amotion_pc(struct map_session_data *sd, struct status_data *status)
+int status_base_amotion_pc(struct map_session_data* sd, struct status_data* status)
{
- int amotion;
+ int amotion;
#ifdef RENEWAL_ASPD
- short mod = -1;
-
- switch (sd->weapontype2) { // adjustment for dual weilding
- case W_DAGGER:
- mod = 0;
- break; // 0, 1, 1
- case W_1HSWORD:
- case W_1HAXE:
- mod = 1;
- if ((sd->class_&MAPID_THIRDMASK) == MAPID_GUILLOTINE_CROSS) // 0, 2, 3
- mod = sd->weapontype2 / W_1HSWORD + W_1HSWORD / sd->weapontype2 ;
- }
-
- amotion = (sd->status.weapon < MAX_WEAPON_TYPE && mod < 0)
- ? (aspd_base[pc_class2idx(sd->status.class_)][sd->status.weapon]) // single weapon
- : ((aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype2] // dual-wield
- + aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype2]) * 6 / 10 + 10 * mod
- - aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype2]
- + aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype1]);
-
- if (sd->status.shield)
- amotion += (2000 - aspd_base[pc_class2idx(sd->status.class_)][W_FIST]) +
- (aspd_base[pc_class2idx(sd->status.class_)][MAX_WEAPON_TYPE] - 2000);
+ short mod = -1;
+
+ switch( sd->weapontype2 ){ // adjustment for dual weilding
+ case W_DAGGER: mod = 0; break; // 0, 1, 1
+ case W_1HSWORD:
+ case W_1HAXE: mod = 1;
+ if( (sd->class_&MAPID_THIRDMASK) == MAPID_GUILLOTINE_CROSS ) // 0, 2, 3
+ mod = sd->weapontype2 / W_1HSWORD + W_1HSWORD / sd->weapontype2 ;
+ }
+
+ amotion = ( sd->status.weapon < MAX_WEAPON_TYPE && mod < 0 )
+ ? (aspd_base[pc_class2idx(sd->status.class_)][sd->status.weapon]) // single weapon
+ : ((aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype2] // dual-wield
+ + aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype2]) * 6 / 10 + 10 * mod
+ - aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype2]
+ + aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype1]);
+
+ if ( sd->status.shield )
+ amotion += ( 2000 - aspd_base[pc_class2idx(sd->status.class_)][W_FIST] ) +
+ ( aspd_base[pc_class2idx(sd->status.class_)][MAX_WEAPON_TYPE] - 2000 );
#else
- // base weapon delay
- amotion = (sd->status.weapon < MAX_WEAPON_TYPE)
- ? (aspd_base[pc_class2idx(sd->status.class_)][sd->status.weapon]) // single weapon
- : (aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype1] + aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype2])*7/10; // dual-wield
+ // base weapon delay
+ amotion = (sd->status.weapon < MAX_WEAPON_TYPE)
+ ? (aspd_base[pc_class2idx(sd->status.class_)][sd->status.weapon]) // single weapon
+ : (aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype1] + aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype2])*7/10; // dual-wield
- // percentual delay reduction from stats
- amotion -= amotion * (4*status->agi + status->dex)/1000;
+ // percentual delay reduction from stats
+ amotion -= amotion * (4*status->agi + status->dex)/1000;
#endif
- // raw delay adjustment from bAspd bonus
- amotion += sd->bonus.aspd_add;
+ // raw delay adjustment from bAspd bonus
+ amotion += sd->bonus.aspd_add;
- return amotion;
+ return amotion;
}
static unsigned short status_base_atk(const struct block_list *bl, const struct status_data *status)
{
- int flag = 0, str, dex,
+ int flag = 0, str, dex,
#ifdef RENEWAL
- rstr,
+ rstr,
#endif
- dstr;
-
-
- if (!(bl->type&battle_config.enable_baseatk))
- return 0;
-
- if (bl->type == BL_PC)
- switch (((TBL_PC *)bl)->status.weapon) {
- case W_BOW:
- case W_MUSICAL:
- case W_WHIP:
- case W_REVOLVER:
- case W_RIFLE:
- case W_GATLING:
- case W_SHOTGUN:
- case W_GRENADE:
- flag = 1;
- }
- if (flag) {
+ dstr;
+
+
+ if(!(bl->type&battle_config.enable_baseatk))
+ return 0;
+
+ if (bl->type == BL_PC)
+ switch(((TBL_PC*)bl)->status.weapon){
+ case W_BOW:
+ case W_MUSICAL:
+ case W_WHIP:
+ case W_REVOLVER:
+ case W_RIFLE:
+ case W_GATLING:
+ case W_SHOTGUN:
+ case W_GRENADE:
+ flag = 1;
+ }
+ if (flag) {
#ifdef RENEWAL
- rstr =
+ rstr =
#endif
- str = status->dex;
- dex = status->str;
- } else {
+ str = status->dex;
+ dex = status->str;
+ } else {
#ifdef RENEWAL
- rstr =
+ rstr =
#endif
- str = status->str;
- dex = status->dex;
- }
- //Normally only players have base-atk, but homunc have a different batk
- // equation, hinting that perhaps non-players should use this for batk.
- // [Skotlex]
- dstr = str/10;
- str += dstr*dstr;
- if (bl->type == BL_PC)
+ str = status->str;
+ dex = status->dex;
+ }
+ //Normally only players have base-atk, but homunc have a different batk
+ // equation, hinting that perhaps non-players should use this for batk.
+ // [Skotlex]
+ dstr = str/10;
+ str += dstr*dstr;
+ if (bl->type == BL_PC)
#ifdef RENEWAL
- str = (rstr*10 + dex*10/5 + status->luk*10/3 + ((TBL_PC *)bl)->status.base_level*10/4)/10;
+ str = (rstr*10 + dex*10/5 + status->luk*10/3 + ((TBL_PC*)bl)->status.base_level*10/4)/10;
#else
- str+= dex/5 + status->luk/5;
+ str+= dex/5 + status->luk/5;
#endif
- return cap_value(str, 0, USHRT_MAX);
+ return cap_value(str, 0, USHRT_MAX);
}
-#ifndef RENEWAL
-static inline unsigned short status_base_matk_min(const struct status_data* status){ return status->int_+(status->int_/7)*(status->int_/7); }
-static inline unsigned short status_base_matk_max(const struct status_data* status){ return status->int_+(status->int_/5)*(status->int_/5); }
+
+static inline unsigned short status_base_matk_max(const struct status_data* status)
+{
+#ifdef RENEWAL
+ return status->matk_max; // in RE maximum MATK signs weapon matk, which we store in this var
#else
-unsigned short status_base_matk(const struct status_data* status, int level){ return status->int_+(status->int_/2)+(status->dex/5)+(status->luk/3)+(level/4); }
+ return status->int_+(status->int_/5)*(status->int_/5);
#endif
+}
+
+#ifdef RENEWAL
+static inline unsigned short status_base_matk_min(const struct status_data* status, int lvl)
+#else
+static inline unsigned short status_base_matk_min(const struct status_data* status)
+#endif
+{
+#ifdef RENEWAL
+ return status->int_+(status->int_/2)+(status->dex/5)+(status->luk/3)+(lvl/4);
+#else
+ return status->int_+(status->int_/7)*(status->int_/7);
+#endif
+}
+
//Fills in the misc data that can be calculated from the other status info (except for level)
void status_calc_misc(struct block_list *bl, struct status_data *status, int level)
{
- //Non players get the value set, players need to stack with previous bonuses.
- if (bl->type != BL_PC)
- status->batk =
- status->hit = status->flee =
- status->def2 = status->mdef2 =
- status->cri = status->flee2 = 0;
+ //Non players get the value set, players need to stack with previous bonuses.
+ if( bl->type != BL_PC )
+ status->batk =
+ status->hit = status->flee =
+ status->def2 = status->mdef2 =
+ status->cri = status->flee2 = 0;
+#ifdef RENEWAL
+ status->matk_min = status_base_matk_min(status, level);
+#else
+ status->matk_min = status_base_matk_min(status);
+#endif
+ status->matk_max = status_base_matk_max(status);
#ifdef RENEWAL // renewal formulas
- status->matk_min = status->matk_max = status_base_matk(status, level);
- status->hit += level + status->dex + status->luk/3 + 175; //base level + ( every 1 dex = +1 hit ) + (every 3 luk = +1 hit) + 175
- status->flee += level + status->agi + status->luk/5 + 100; //base level + ( every 1 agi = +1 flee ) + (every 5 luk = +1 flee) + 100
- status->def2 += (int)(((float)level + status->vit)/2 + ((float)status->agi/5)); //base level + (every 2 vit = +1 def) + (every 5 agi = +1 def)
- status->mdef2 += (int)(status->int_ + ((float)level/4) + ((float)status->dex/5) + ((float)status->vit/5)); //(every 4 base level = +1 mdef) + (every 1 int = +1 mdef) + (every 5 dex = +1 mdef) + (every 5 vit = +1 mdef)
+ status->hit += level + status->dex + status->luk/3 + 175; //base level + ( every 1 dex = +1 hit ) + (every 3 luk = +1 hit) + 175
+ status->flee += level + status->agi + status->luk/5 + 100; //base level + ( every 1 agi = +1 flee ) + (every 5 luk = +1 flee) + 100
+ status->def2 += (int)(((float)level + status->vit)/2 + ((float)status->agi/5)); //base level + (every 2 vit = +1 def) + (every 5 agi = +1 def)
+ status->mdef2 += (int)(status->int_ + ((float)level/4) + ((float)status->dex/5) + ((float)status->vit/5)); //(every 4 base level = +1 mdef) + (every 1 int = +1 mdef) + (every 5 dex = +1 mdef) + (every 5 vit = +1 mdef)
#else
- status->matk_min = status_base_matk_min(status);
- status->matk_max = status_base_matk_max(status);
- status->hit += level + status->dex;
- status->flee += level + status->agi;
- status->def2 += status->vit;
- status->mdef2 += status->int_ + (status->vit>>1);
+ status->hit += level + status->dex;
+ status->flee += level + status->agi;
+ status->def2 += status->vit;
+ status->mdef2 += status->int_ + (status->vit>>1);
#endif
- if (bl->type&battle_config.enable_critical)
- status->cri += 10 + (status->luk*10/3); //(every 1 luk = +0.3 critical)
- else
- status->cri = 0;
-
- if (bl->type&battle_config.enable_perfect_flee)
- status->flee2 += status->luk + 10; //(every 10 luk = +1 perfect flee)
- else
- status->flee2 = 0;
-
- if (status->batk) {
- int temp = status->batk + status_base_atk(bl, status);
- status->batk = cap_value(temp, 0, USHRT_MAX);
- } else
- status->batk = status_base_atk(bl, status);
- if (status->cri)
- switch (bl->type) {
- case BL_MOB:
- if (battle_config.mob_critical_rate != 100)
- status->cri = status->cri*battle_config.mob_critical_rate/100;
- if (!status->cri && battle_config.mob_critical_rate)
- status->cri = 10;
- break;
- case BL_PC:
- //Players don't have a critical adjustment setting as of yet.
- break;
- default:
- if (battle_config.critical_rate != 100)
- status->cri = status->cri*battle_config.critical_rate/100;
- if (!status->cri && battle_config.critical_rate)
- status->cri = 10;
- }
- if (bl->type&BL_REGEN)
- status_calc_regen(bl, status, status_get_regen_data(bl));
+ if( bl->type&battle_config.enable_critical )
+ status->cri += 10 + (status->luk*10/3); //(every 1 luk = +0.3 critical)
+ else
+ status->cri = 0;
+
+ if (bl->type&battle_config.enable_perfect_flee)
+ status->flee2 += status->luk + 10; //(every 10 luk = +1 perfect flee)
+ else
+ status->flee2 = 0;
+
+ if (status->batk) {
+ int temp = status->batk + status_base_atk(bl, status);
+ status->batk = cap_value(temp, 0, USHRT_MAX);
+ } else
+ status->batk = status_base_atk(bl, status);
+ if (status->cri)
+ switch (bl->type) {
+ case BL_MOB:
+ if(battle_config.mob_critical_rate != 100)
+ status->cri = status->cri*battle_config.mob_critical_rate/100;
+ if(!status->cri && battle_config.mob_critical_rate)
+ status->cri = 10;
+ break;
+ case BL_PC:
+ //Players don't have a critical adjustment setting as of yet.
+ break;
+ default:
+ if(battle_config.critical_rate != 100)
+ status->cri = status->cri*battle_config.critical_rate/100;
+ if (!status->cri && battle_config.critical_rate)
+ status->cri = 10;
+ }
+ if(bl->type&BL_REGEN)
+ status_calc_regen(bl, status, status_get_regen_data(bl));
}
//Skotlex: Calculates the initial status for the given mob
//first will only be false when the mob leveled up or got a GuardUp level.
-int status_calc_mob_(struct mob_data *md, bool first)
+int status_calc_mob_(struct mob_data* md, bool first)
{
- struct status_data *status;
- struct block_list *mbl = NULL;
- int flag=0;
-
- if (first) {
- //Set basic level on respawn.
- if (md->level > 0 && md->level <= MAX_LEVEL && md->level != md->db->lv)
- ;
- else
- md->level = md->db->lv;
- }
-
- //Check if we need custom base-status
- if (battle_config.mobs_level_up && md->level > md->db->lv)
- flag|=1;
-
- if (md->special_state.size)
- flag|=2;
-
- if (md->guardian_data && md->guardian_data->guardup_lv)
- flag|=4;
- if (md->class_ == MOBID_EMPERIUM)
- flag|=4;
-
- if (battle_config.slaves_inherit_speed && md->master_id)
- flag|=8;
-
- if (md->master_id && md->special_state.ai>1)
- flag|=16;
-
- if (!flag) {
- //No special status required.
- if (md->base_status) {
- aFree(md->base_status);
- md->base_status = NULL;
- }
- if (first)
- memcpy(&md->status, &md->db->status, sizeof(struct status_data));
- return 0;
- }
- if (!md->base_status)
- md->base_status = (struct status_data *)aCalloc(1, sizeof(struct status_data));
-
- status = md->base_status;
- memcpy(status, &md->db->status, sizeof(struct status_data));
-
- if (flag&(8|16))
- mbl = map_id2bl(md->master_id);
-
- if (flag&8 && mbl) {
- struct status_data *mstatus = status_get_base_status(mbl);
- if (mstatus &&
- battle_config.slaves_inherit_speed&(mstatus->mode&MD_CANMOVE?1:2))
- status->speed = mstatus->speed;
- if (status->speed < 2) /* minimum for the unit to function properly */
- status->speed = 2;
- }
-
- if (flag&16 && mbl) {
- //Max HP setting from Summon Flora/marine Sphere
- struct unit_data *ud = unit_bl2ud(mbl);
- //Remove special AI when this is used by regular mobs.
- if (mbl->type == BL_MOB && !((TBL_MOB *)mbl)->special_state.ai)
- md->special_state.ai = 0;
- if (ud) {
- // different levels of HP according to skill level
- if (ud->skillid == AM_SPHEREMINE) {
- status->max_hp = 2000 + 400*ud->skilllv;
- } else if (ud->skillid == KO_ZANZOU) {
- status->max_hp = 3000 + 3000 * ud->skilllv;
- } else { //AM_CANNIBALIZE
- status->max_hp = 1500 + 200*ud->skilllv + 10*status_get_lv(mbl);
- status->mode|= MD_CANATTACK|MD_AGGRESSIVE;
- }
- status->hp = status->max_hp;
- }
- }
-
- if (flag&1) {
- // increase from mobs leveling up [Valaris]
- int diff = md->level - md->db->lv;
- status->str+= diff;
- status->agi+= diff;
- status->vit+= diff;
- status->int_+= diff;
- status->dex+= diff;
- status->luk+= diff;
- status->max_hp += diff*status->vit;
- status->max_sp += diff*status->int_;
- status->hp = status->max_hp;
- status->sp = status->max_sp;
- status->speed -= cap_value(diff, 0, status->speed - 10);
- }
-
-
- if (flag&2 && battle_config.mob_size_influence) {
- // change for sized monsters [Valaris]
- if (md->special_state.size==SZ_MEDIUM) {
- status->max_hp>>=1;
- status->max_sp>>=1;
- if (!status->max_hp) status->max_hp = 1;
- if (!status->max_sp) status->max_sp = 1;
- status->hp=status->max_hp;
- status->sp=status->max_sp;
- status->str>>=1;
- status->agi>>=1;
- status->vit>>=1;
- status->int_>>=1;
- status->dex>>=1;
- status->luk>>=1;
- if (!status->str) status->str = 1;
- if (!status->agi) status->agi = 1;
- if (!status->vit) status->vit = 1;
- if (!status->int_) status->int_ = 1;
- if (!status->dex) status->dex = 1;
- if (!status->luk) status->luk = 1;
- } else if (md->special_state.size==SZ_BIG) {
- status->max_hp<<=1;
- status->max_sp<<=1;
- status->hp=status->max_hp;
- status->sp=status->max_sp;
- status->str<<=1;
- status->agi<<=1;
- status->vit<<=1;
- status->int_<<=1;
- status->dex<<=1;
- status->luk<<=1;
- }
- }
-
- status_calc_misc(&md->bl, status, md->level);
-
- if (flag&4) {
- // Strengthen Guardians - custom value +10% / lv
- struct guild_castle *gc;
- gc=guild_mapname2gc(map[md->bl.m].name);
- if (!gc)
- ShowError("status_calc_mob: No castle set at map %s\n", map[md->bl.m].name);
- else if (gc->castle_id < 24 || md->class_ == MOBID_EMPERIUM) {
+ struct status_data *status;
+ struct block_list *mbl = NULL;
+ int flag=0;
+
+ if(first)
+ { //Set basic level on respawn.
+ if (md->level > 0 && md->level <= MAX_LEVEL && md->level != md->db->lv)
+ ;
+ else
+ md->level = md->db->lv;
+ }
+
+ //Check if we need custom base-status
+ if (battle_config.mobs_level_up && md->level > md->db->lv)
+ flag|=1;
+
+ if (md->special_state.size)
+ flag|=2;
+
+ if (md->guardian_data && md->guardian_data->guardup_lv)
+ flag|=4;
+ if (md->class_ == MOBID_EMPERIUM)
+ flag|=4;
+
+ if (battle_config.slaves_inherit_speed && md->master_id)
+ flag|=8;
+
+ if (md->master_id && md->special_state.ai>1)
+ flag|=16;
+
+ if (!flag)
+ { //No special status required.
+ if (md->base_status) {
+ aFree(md->base_status);
+ md->base_status = NULL;
+ }
+ if(first)
+ memcpy(&md->status, &md->db->status, sizeof(struct status_data));
+ return 0;
+ }
+ if (!md->base_status)
+ md->base_status = (struct status_data*)aCalloc(1, sizeof(struct status_data));
+
+ status = md->base_status;
+ memcpy(status, &md->db->status, sizeof(struct status_data));
+
+ if (flag&(8|16))
+ mbl = map_id2bl(md->master_id);
+
+ if (flag&8 && mbl) {
+ struct status_data *mstatus = status_get_base_status(mbl);
+ if (mstatus &&
+ battle_config.slaves_inherit_speed&(mstatus->mode&MD_CANMOVE?1:2))
+ status->speed = mstatus->speed;
+ if( status->speed < 2 ) /* minimum for the unit to function properly */
+ status->speed = 2;
+ }
+
+ if (flag&16 && mbl)
+ { //Max HP setting from Summon Flora/marine Sphere
+ struct unit_data *ud = unit_bl2ud(mbl);
+ //Remove special AI when this is used by regular mobs.
+ if (mbl->type == BL_MOB && !((TBL_MOB*)mbl)->special_state.ai)
+ md->special_state.ai = 0;
+ if (ud)
+ { // different levels of HP according to skill level
+ if (ud->skillid == AM_SPHEREMINE) {
+ status->max_hp = 2000 + 400*ud->skilllv;
+ } else if(ud->skillid == KO_ZANZOU){
+ status->max_hp = 3000 + 3000 * ud->skilllv;
+ } else { //AM_CANNIBALIZE
+ status->max_hp = 1500 + 200*ud->skilllv + 10*status_get_lv(mbl);
+ status->mode|= MD_CANATTACK|MD_AGGRESSIVE;
+ }
+ status->hp = status->max_hp;
+ }
+ }
+
+ if (flag&1)
+ { // increase from mobs leveling up [Valaris]
+ int diff = md->level - md->db->lv;
+ status->str+= diff;
+ status->agi+= diff;
+ status->vit+= diff;
+ status->int_+= diff;
+ status->dex+= diff;
+ status->luk+= diff;
+ status->max_hp += diff*status->vit;
+ status->max_sp += diff*status->int_;
+ status->hp = status->max_hp;
+ status->sp = status->max_sp;
+ status->speed -= cap_value(diff, 0, status->speed - 10);
+ }
+
+
+ if (flag&2 && battle_config.mob_size_influence)
+ { // change for sized monsters [Valaris]
+ if (md->special_state.size==SZ_MEDIUM) {
+ status->max_hp>>=1;
+ status->max_sp>>=1;
+ if (!status->max_hp) status->max_hp = 1;
+ if (!status->max_sp) status->max_sp = 1;
+ status->hp=status->max_hp;
+ status->sp=status->max_sp;
+ status->str>>=1;
+ status->agi>>=1;
+ status->vit>>=1;
+ status->int_>>=1;
+ status->dex>>=1;
+ status->luk>>=1;
+ if (!status->str) status->str = 1;
+ if (!status->agi) status->agi = 1;
+ if (!status->vit) status->vit = 1;
+ if (!status->int_) status->int_ = 1;
+ if (!status->dex) status->dex = 1;
+ if (!status->luk) status->luk = 1;
+ } else if (md->special_state.size==SZ_BIG) {
+ status->max_hp<<=1;
+ status->max_sp<<=1;
+ status->hp=status->max_hp;
+ status->sp=status->max_sp;
+ status->str<<=1;
+ status->agi<<=1;
+ status->vit<<=1;
+ status->int_<<=1;
+ status->dex<<=1;
+ status->luk<<=1;
+ }
+ }
+
+ status_calc_misc(&md->bl, status, md->level);
+
+ if(flag&4)
+ { // Strengthen Guardians - custom value +10% / lv
+ struct guild_castle *gc;
+ gc=guild_mapname2gc(map[md->bl.m].name);
+ if (!gc)
+ ShowError("status_calc_mob: No castle set at map %s\n", map[md->bl.m].name);
+ else
+ if(gc->castle_id < 24 || md->class_ == MOBID_EMPERIUM) {
#ifdef RENEWAL
- status->max_hp += 50 * gc->defense;
- status->max_sp += 70 * gc->defense;
+ status->max_hp += 50 * gc->defense;
+ status->max_sp += 70 * gc->defense;
#else
- status->max_hp += 1000 * gc->defense;
- status->max_sp += 200 * gc->defense;
+ status->max_hp += 1000 * gc->defense;
+ status->max_sp += 200 * gc->defense;
#endif
- status->hp = status->max_hp;
- status->sp = status->max_sp;
- status->def += (gc->defense+2)/3;
- status->mdef += (gc->defense+2)/3;
- }
- if (md->class_ != MOBID_EMPERIUM) {
- status->batk += status->batk * 10*md->guardian_data->guardup_lv/100;
- status->rhw.atk += status->rhw.atk * 10*md->guardian_data->guardup_lv/100;
- status->rhw.atk2 += status->rhw.atk2 * 10*md->guardian_data->guardup_lv/100;
- status->aspd_rate -= 100*md->guardian_data->guardup_lv;
- }
- }
+ status->hp = status->max_hp;
+ status->sp = status->max_sp;
+ status->def += (gc->defense+2)/3;
+ status->mdef += (gc->defense+2)/3;
+ }
+ if(md->class_ != MOBID_EMPERIUM) {
+ status->batk += status->batk * 10*md->guardian_data->guardup_lv/100;
+ status->rhw.atk += status->rhw.atk * 10*md->guardian_data->guardup_lv/100;
+ status->rhw.atk2 += status->rhw.atk2 * 10*md->guardian_data->guardup_lv/100;
+ status->aspd_rate -= 100*md->guardian_data->guardup_lv;
+ }
+ }
- if (first) //Initial battle status
- memcpy(&md->status, status, sizeof(struct status_data));
+ if( first ) //Initial battle status
+ memcpy(&md->status, status, sizeof(struct status_data));
- return 1;
+ return 1;
}
//Skotlex: Calculates the stats of the given pet.
int status_calc_pet_(struct pet_data *pd, bool first)
{
- nullpo_ret(pd);
-
- if (first) {
- memcpy(&pd->status, &pd->db->status, sizeof(struct status_data));
- pd->status.mode = MD_CANMOVE; // pets discard all modes, except walking
- pd->status.speed = pd->petDB->speed;
-
- if (battle_config.pet_attack_support || battle_config.pet_damage_support) {
- // attack support requires the pet to be able to attack
- pd->status.mode|= MD_CANATTACK;
- }
- }
-
- if (battle_config.pet_lv_rate && pd->msd) {
- struct map_session_data *sd = pd->msd;
- int lv;
-
- lv =sd->status.base_level*battle_config.pet_lv_rate/100;
- if (lv < 0)
- lv = 1;
- if (lv != pd->pet.level || first) {
- struct status_data *bstat = &pd->db->status, *status = &pd->status;
- pd->pet.level = lv;
- if (!first) //Lv Up animation
- clif_misceffect(&pd->bl, 0);
- status->rhw.atk = (bstat->rhw.atk*lv)/pd->db->lv;
- status->rhw.atk2 = (bstat->rhw.atk2*lv)/pd->db->lv;
- status->str = (bstat->str*lv)/pd->db->lv;
- status->agi = (bstat->agi*lv)/pd->db->lv;
- status->vit = (bstat->vit*lv)/pd->db->lv;
- status->int_ = (bstat->int_*lv)/pd->db->lv;
- status->dex = (bstat->dex*lv)/pd->db->lv;
- status->luk = (bstat->luk*lv)/pd->db->lv;
-
- status->rhw.atk = cap_value(status->rhw.atk, 1, battle_config.pet_max_atk1);
- status->rhw.atk2 = cap_value(status->rhw.atk2, 2, battle_config.pet_max_atk2);
- status->str = cap_value(status->str,1,battle_config.pet_max_stats);
- status->agi = cap_value(status->agi,1,battle_config.pet_max_stats);
- status->vit = cap_value(status->vit,1,battle_config.pet_max_stats);
- status->int_= cap_value(status->int_,1,battle_config.pet_max_stats);
- status->dex = cap_value(status->dex,1,battle_config.pet_max_stats);
- status->luk = cap_value(status->luk,1,battle_config.pet_max_stats);
-
- status_calc_misc(&pd->bl, &pd->status, lv);
-
- if (!first) //Not done the first time because the pet is not visible yet
- clif_send_petstatus(sd);
- }
- } else if (first) {
- status_calc_misc(&pd->bl, &pd->status, pd->db->lv);
- if (!battle_config.pet_lv_rate && pd->pet.level != pd->db->lv)
- pd->pet.level = pd->db->lv;
- }
+ nullpo_ret(pd);
- //Support rate modifier (1000 = 100%)
- pd->rate_fix = 1000*(pd->pet.intimate - battle_config.pet_support_min_friendly)/(1000- battle_config.pet_support_min_friendly) +500;
- if (battle_config.pet_support_rate != 100)
- pd->rate_fix = pd->rate_fix*battle_config.pet_support_rate/100;
+ if (first) {
+ memcpy(&pd->status, &pd->db->status, sizeof(struct status_data));
+ pd->status.mode = MD_CANMOVE; // pets discard all modes, except walking
+ pd->status.speed = pd->petDB->speed;
- return 1;
+ if(battle_config.pet_attack_support || battle_config.pet_damage_support)
+ {// attack support requires the pet to be able to attack
+ pd->status.mode|= MD_CANATTACK;
+ }
+ }
+
+ if (battle_config.pet_lv_rate && pd->msd)
+ {
+ struct map_session_data *sd = pd->msd;
+ int lv;
+
+ lv =sd->status.base_level*battle_config.pet_lv_rate/100;
+ if (lv < 0)
+ lv = 1;
+ if (lv != pd->pet.level || first)
+ {
+ struct status_data *bstat = &pd->db->status, *status = &pd->status;
+ pd->pet.level = lv;
+ if (!first) //Lv Up animation
+ clif_misceffect(&pd->bl, 0);
+ status->rhw.atk = (bstat->rhw.atk*lv)/pd->db->lv;
+ status->rhw.atk2 = (bstat->rhw.atk2*lv)/pd->db->lv;
+ status->str = (bstat->str*lv)/pd->db->lv;
+ status->agi = (bstat->agi*lv)/pd->db->lv;
+ status->vit = (bstat->vit*lv)/pd->db->lv;
+ status->int_ = (bstat->int_*lv)/pd->db->lv;
+ status->dex = (bstat->dex*lv)/pd->db->lv;
+ status->luk = (bstat->luk*lv)/pd->db->lv;
+
+ status->rhw.atk = cap_value(status->rhw.atk, 1, battle_config.pet_max_atk1);
+ status->rhw.atk2 = cap_value(status->rhw.atk2, 2, battle_config.pet_max_atk2);
+ status->str = cap_value(status->str,1,battle_config.pet_max_stats);
+ status->agi = cap_value(status->agi,1,battle_config.pet_max_stats);
+ status->vit = cap_value(status->vit,1,battle_config.pet_max_stats);
+ status->int_= cap_value(status->int_,1,battle_config.pet_max_stats);
+ status->dex = cap_value(status->dex,1,battle_config.pet_max_stats);
+ status->luk = cap_value(status->luk,1,battle_config.pet_max_stats);
+
+ status_calc_misc(&pd->bl, &pd->status, lv);
+
+ if (!first) //Not done the first time because the pet is not visible yet
+ clif_send_petstatus(sd);
+ }
+ } else if (first) {
+ status_calc_misc(&pd->bl, &pd->status, pd->db->lv);
+ if (!battle_config.pet_lv_rate && pd->pet.level != pd->db->lv)
+ pd->pet.level = pd->db->lv;
+ }
+
+ //Support rate modifier (1000 = 100%)
+ pd->rate_fix = 1000*(pd->pet.intimate - battle_config.pet_support_min_friendly)/(1000- battle_config.pet_support_min_friendly) +500;
+ if(battle_config.pet_support_rate != 100)
+ pd->rate_fix = pd->rate_fix*battle_config.pet_support_rate/100;
+
+ return 1;
}
/// Helper function for status_base_pc_maxhp(), used to pre-calculate the hp_sigma_val[] array
static void status_calc_sigma(void)
{
- int i,j;
-
- for (i = 0; i < CLASS_COUNT; i++) {
- unsigned int k = 0;
- hp_sigma_val[i][0] = hp_sigma_val[i][1] = 0;
- for (j = 2; j <= MAX_LEVEL; j++) {
- k += (hp_coefficient[i]*j + 50) / 100;
- hp_sigma_val[i][j] = k;
- if (k >= INT_MAX)
- break; //Overflow protection. [Skotlex]
- }
- for (; j <= MAX_LEVEL; j++)
- hp_sigma_val[i][j] = INT_MAX;
- }
+ int i,j;
+
+ for(i = 0; i < CLASS_COUNT; i++)
+ {
+ unsigned int k = 0;
+ hp_sigma_val[i][0] = hp_sigma_val[i][1] = 0;
+ for(j = 2; j <= MAX_LEVEL; j++)
+ {
+ k += (hp_coefficient[i]*j + 50) / 100;
+ hp_sigma_val[i][j] = k;
+ if (k >= INT_MAX)
+ break; //Overflow protection. [Skotlex]
+ }
+ for(; j <= MAX_LEVEL; j++)
+ hp_sigma_val[i][j] = INT_MAX;
+ }
}
/// Calculates base MaxHP value according to class and base level
@@ -2268,1003 +2252,1010 @@ static void status_calc_sigma(void)
/// f(0) = 35 | f(x+1) = f(x) + A + (x + B)*C/D
/// which reduces to something close to
/// f(x) = 35 + x*(A + B*C/D) + sum(i=2..x){ i*C/D }
-static unsigned int status_base_pc_maxhp(struct map_session_data *sd, struct status_data *status)
+static unsigned int status_base_pc_maxhp(struct map_session_data* sd, struct status_data* status)
{
- unsigned int val = pc_class2idx(sd->status.class_);
- val = 35 + sd->status.base_level*hp_coefficient2[val]/100 + hp_sigma_val[val][sd->status.base_level];
-
- if ((sd->class_&MAPID_UPPERMASK) == MAPID_NINJA || (sd->class_&MAPID_UPPERMASK) == MAPID_GUNSLINGER)
- val += 100; //Since their HP can't be approximated well enough without this.
- if ((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc_famerank(sd->status.char_id, MAPID_TAEKWON))
- val *= 3; //Triple max HP for top ranking Taekwons over level 90.
- if ((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->status.base_level >= 99)
- val += 2000; //Supernovice lvl99 hp bonus.
-
- val += val * status->vit/100; // +1% per each point of VIT
-
- if (sd->class_&JOBL_UPPER)
- val += val * 25/100; //Trans classes get a 25% hp bonus
- else if (sd->class_&JOBL_BABY)
- val -= val * 30/100; //Baby classes get a 30% hp penalty
- return val;
+ unsigned int val = pc_class2idx(sd->status.class_);
+ val = 35 + sd->status.base_level*hp_coefficient2[val]/100 + hp_sigma_val[val][sd->status.base_level];
+
+ if((sd->class_&MAPID_UPPERMASK) == MAPID_NINJA || (sd->class_&MAPID_UPPERMASK) == MAPID_GUNSLINGER)
+ val += 100; //Since their HP can't be approximated well enough without this.
+ if((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc_famerank(sd->status.char_id, MAPID_TAEKWON))
+ val *= 3; //Triple max HP for top ranking Taekwons over level 90.
+ if((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->status.base_level >= 99)
+ val += 2000; //Supernovice lvl99 hp bonus.
+
+ val += val * status->vit/100; // +1% per each point of VIT
+
+ if (sd->class_&JOBL_UPPER)
+ val += val * 25/100; //Trans classes get a 25% hp bonus
+ else if (sd->class_&JOBL_BABY)
+ val -= val * 30/100; //Baby classes get a 30% hp penalty
+ return val;
}
-static unsigned int status_base_pc_maxsp(struct map_session_data *sd, struct status_data *status)
+static unsigned int status_base_pc_maxsp(struct map_session_data* sd, struct status_data *status)
{
- unsigned int val;
+ unsigned int val;
- val = 10 + sd->status.base_level*sp_coefficient[pc_class2idx(sd->status.class_)]/100;
- val += val * status->int_/100;
+ val = 10 + sd->status.base_level*sp_coefficient[pc_class2idx(sd->status.class_)]/100;
+ val += val * status->int_/100;
- if (sd->class_&JOBL_UPPER)
- val += val * 25/100;
- else if (sd->class_&JOBL_BABY)
- val -= val * 30/100;
- if ((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc_famerank(sd->status.char_id, MAPID_TAEKWON))
- val *= 3; //Triple max SP for top ranking Taekwons over level 90.
+ if (sd->class_&JOBL_UPPER)
+ val += val * 25/100;
+ else if (sd->class_&JOBL_BABY)
+ val -= val * 30/100;
+ if ((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc_famerank(sd->status.char_id, MAPID_TAEKWON))
+ val *= 3; //Triple max SP for top ranking Taekwons over level 90.
- return val;
+ return val;
}
//Calculates player data from scratch without counting SC adjustments.
//Should be invoked whenever players raise stats, learn passive skills or change equipment.
-int status_calc_pc_(struct map_session_data *sd, bool first)
+int status_calc_pc_(struct map_session_data* sd, bool first)
{
- static int calculating = 0; //Check for recursive call preemption. [Skotlex]
- struct status_data *status; // pointer to the player's base status
- const struct status_change *sc = &sd->sc;
- struct s_skill b_skill[MAX_SKILL]; // previous skill tree
- int b_weight, b_max_weight, b_cart_weight_max; // previous weight
- int i,index;
- int skill,refinedef=0;
-
- if (++calculating > 10) //Too many recursive calls!
- return -1;
-
- // remember player-specific values that are currently being shown to the client (for refresh purposes)
- memcpy(b_skill, &sd->status.skill, sizeof(b_skill));
- b_weight = sd->weight;
- b_max_weight = sd->max_weight;
- b_cart_weight_max = sd->cart_weight_max;
-
- pc_calc_skilltree(sd); // SkillTree calculation
-
- sd->max_weight = max_weight_base[pc_class2idx(sd->status.class_)]+sd->status.str*300;
-
- if (first) {
- //Load Hp/SP from char-received data.
- sd->battle_status.hp = sd->status.hp;
- sd->battle_status.sp = sd->status.sp;
- sd->regen.sregen = &sd->sregen;
- sd->regen.ssregen = &sd->ssregen;
- 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_weight=0;
- 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++;
- }
- }
-
- status = &sd->base_status;
- // these are not zeroed. [zzo]
- sd->hprate=100;
- sd->sprate=100;
- sd->castrate=100;
- sd->delayrate=100;
- sd->dsprate=100;
- sd->hprecov_rate = 100;
- sd->sprecov_rate = 100;
- sd->matk_rate = 100;
- 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->regen.state.block = 0;
-
- // zeroed arrays, order follows the order in pc.h.
- // add new arrays to the end of zeroed area in pc.h (see comments) and size here. [zzo]
- memset(sd->param_bonus, 0, sizeof(sd->param_bonus)
- + sizeof(sd->param_equip)
- + sizeof(sd->subele)
- + sizeof(sd->subrace)
- + sizeof(sd->subrace2)
- + sizeof(sd->subsize)
- + sizeof(sd->reseff)
- + sizeof(sd->weapon_coma_ele)
- + sizeof(sd->weapon_coma_race)
- + sizeof(sd->weapon_atk)
- + sizeof(sd->weapon_atk_rate)
- + sizeof(sd->arrow_addele)
- + sizeof(sd->arrow_addrace)
- + sizeof(sd->arrow_addsize)
- + sizeof(sd->magic_addele)
- + sizeof(sd->magic_addrace)
- + sizeof(sd->magic_addsize)
- + sizeof(sd->critaddrace)
- + sizeof(sd->expaddrace)
- + sizeof(sd->ignore_mdef)
- + sizeof(sd->ignore_def)
- + sizeof(sd->itemgrouphealrate)
- + sizeof(sd->sp_gain_race)
- + sizeof(sd->sp_gain_race_attack)
- + sizeof(sd->hp_gain_race_attack)
- );
-
- memset(&sd->right_weapon.overrefine, 0, sizeof(sd->right_weapon) - sizeof(sd->right_weapon.atkmods));
- memset(&sd->left_weapon.overrefine, 0, sizeof(sd->left_weapon) - sizeof(sd->left_weapon.atkmods));
-
- if (sd->special_state.intravision && !sd->sc.data[SC_INTRAVISION]) //Clear intravision as long as nothing else is using it
- clif_status_load(&sd->bl, SI_INTRAVISION, 0);
-
- memset(&sd->special_state,0,sizeof(sd->special_state));
- memset(&status->max_hp, 0, sizeof(struct status_data)-(sizeof(status->hp)+sizeof(status->sp)));
-
- //FIXME: Most of these stuff should be calculated once, but how do I fix the memset above to do that? [Skotlex]
- status->speed = DEFAULT_WALK_SPEED;
- //Give them all modes except these (useful for clones)
- status->mode = MD_MASK&~(MD_BOSS|MD_PLANT|MD_DETECTOR|MD_ANGRY|MD_TARGETWEAK);
-
- status->size = (sd->class_&JOBL_BABY)?SZ_SMALL:SZ_MEDIUM;
- if (battle_config.character_size && pc_isriding(sd)) { //[Lupus]
- if (sd->class_&JOBL_BABY) {
- if (battle_config.character_size&SZ_BIG)
- status->size++;
- } else if (battle_config.character_size&SZ_MEDIUM)
- status->size++;
- }
- status->aspd_rate = 1000;
- status->ele_lv = 1;
- status->race = RC_DEMIHUMAN;
-
- //zero up structures...
- memset(&sd->autospell,0,sizeof(sd->autospell)
- + sizeof(sd->autospell2)
- + sizeof(sd->autospell3)
- + sizeof(sd->addeff)
- + sizeof(sd->addeff2)
- + sizeof(sd->addeff3)
- + sizeof(sd->skillatk)
- + sizeof(sd->skillusesprate)
- + sizeof(sd->skillusesp)
- + sizeof(sd->skillheal)
- + sizeof(sd->skillheal2)
- + sizeof(sd->hp_loss)
- + sizeof(sd->sp_loss)
- + sizeof(sd->hp_regen)
- + sizeof(sd->sp_regen)
- + sizeof(sd->skillblown)
- + sizeof(sd->skillcast)
- + sizeof(sd->add_def)
- + sizeof(sd->add_mdef)
- + sizeof(sd->add_mdmg)
- + sizeof(sd->add_drop)
- + sizeof(sd->itemhealrate)
- + sizeof(sd->subele2)
- + sizeof(sd->skillcooldown)
- + sizeof(sd->skillfixcast)
- + sizeof(sd->skillvarcast)
- );
-
- memset(&sd->bonus, 0,sizeof(sd->bonus));
-
- // Autobonus
- pc_delautobonus(sd,sd->autobonus,ARRAYLENGTH(sd->autobonus),true);
- pc_delautobonus(sd,sd->autobonus2,ARRAYLENGTH(sd->autobonus2),true);
- pc_delautobonus(sd,sd->autobonus3,ARRAYLENGTH(sd->autobonus3),true);
-
- // Parse equipment.
- for (i=0; i<EQI_MAX-1; 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 == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == index)
- continue;
- if (i == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == index)
- continue;
- if (i == EQI_HEAD_TOP && (sd->equip_index[EQI_HEAD_MID] == index || sd->equip_index[EQI_HEAD_LOW] == index))
- continue;
- if (i == EQI_COSTUME_MID && sd->equip_index[EQI_COSTUME_LOW] == index)
- continue;
- if (i == EQI_COSTUME_TOP && (sd->equip_index[EQI_COSTUME_MID] == index || sd->equip_index[EQI_COSTUME_LOW] == index))
- continue;
- if (!sd->inventory_data[index])
- continue;
-
- status->def += sd->inventory_data[index]->def;
-
- if (first && sd->inventory_data[index]->equip_script) {
- //Execute equip-script on login
- run_script(sd->inventory_data[index]->equip_script,0,sd->bl.id,0);
- if (!calculating)
- return 1;
- }
+ static int calculating = 0; //Check for recursive call preemption. [Skotlex]
+ struct status_data *status; // pointer to the player's base status
+ const struct status_change *sc = &sd->sc;
+ struct s_skill b_skill[MAX_SKILL]; // previous skill tree
+ int b_weight, b_max_weight, b_cart_weight_max; // previous weight
+ int i,index;
+ int skill,refinedef=0;
+
+ if (++calculating > 10) //Too many recursive calls!
+ return -1;
+
+ // remember player-specific values that are currently being shown to the client (for refresh purposes)
+ memcpy(b_skill, &sd->status.skill, sizeof(b_skill));
+ b_weight = sd->weight;
+ b_max_weight = sd->max_weight;
+ b_cart_weight_max = sd->cart_weight_max;
+
+ pc_calc_skilltree(sd); // SkillTree calculation
+
+ sd->max_weight = max_weight_base[pc_class2idx(sd->status.class_)]+sd->status.str*300;
+
+ if(first) {
+ //Load Hp/SP from char-received data.
+ sd->battle_status.hp = sd->status.hp;
+ sd->battle_status.sp = sd->status.sp;
+ sd->regen.sregen = &sd->sregen;
+ sd->regen.ssregen = &sd->ssregen;
+ 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_weight=0;
+ 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++;
+ }
+ }
+
+ status = &sd->base_status;
+ // these are not zeroed. [zzo]
+ sd->hprate=100;
+ sd->sprate=100;
+ sd->castrate=100;
+ sd->delayrate=100;
+ sd->dsprate=100;
+ sd->hprecov_rate = 100;
+ sd->sprecov_rate = 100;
+ sd->matk_rate = 100;
+ 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->regen.state.block = 0;
+
+ // zeroed arrays, order follows the order in pc.h.
+ // add new arrays to the end of zeroed area in pc.h (see comments) and size here. [zzo]
+ memset (sd->param_bonus, 0, sizeof(sd->param_bonus)
+ + sizeof(sd->param_equip)
+ + sizeof(sd->subele)
+ + sizeof(sd->subrace)
+ + sizeof(sd->subrace2)
+ + sizeof(sd->subsize)
+ + sizeof(sd->reseff)
+ + sizeof(sd->weapon_coma_ele)
+ + sizeof(sd->weapon_coma_race)
+ + sizeof(sd->weapon_atk)
+ + sizeof(sd->weapon_atk_rate)
+ + sizeof(sd->arrow_addele)
+ + sizeof(sd->arrow_addrace)
+ + sizeof(sd->arrow_addsize)
+ + sizeof(sd->magic_addele)
+ + sizeof(sd->magic_addrace)
+ + sizeof(sd->magic_addsize)
+ + sizeof(sd->critaddrace)
+ + sizeof(sd->expaddrace)
+ + sizeof(sd->ignore_mdef)
+ + sizeof(sd->ignore_def)
+ + sizeof(sd->itemgrouphealrate)
+ + sizeof(sd->sp_gain_race)
+ + sizeof(sd->sp_gain_race_attack)
+ + sizeof(sd->hp_gain_race_attack)
+ );
+
+ memset (&sd->right_weapon.overrefine, 0, sizeof(sd->right_weapon) - sizeof(sd->right_weapon.atkmods));
+ memset (&sd->left_weapon.overrefine, 0, sizeof(sd->left_weapon) - sizeof(sd->left_weapon.atkmods));
+
+ if (sd->special_state.intravision && !sd->sc.data[SC_INTRAVISION]) //Clear intravision as long as nothing else is using it
+ clif_status_load(&sd->bl, SI_INTRAVISION, 0);
+
+ memset(&sd->special_state,0,sizeof(sd->special_state));
+ memset(&status->max_hp, 0, sizeof(struct status_data)-(sizeof(status->hp)+sizeof(status->sp)));
+
+ //FIXME: Most of these stuff should be calculated once, but how do I fix the memset above to do that? [Skotlex]
+ status->speed = DEFAULT_WALK_SPEED;
+ //Give them all modes except these (useful for clones)
+ status->mode = MD_MASK&~(MD_BOSS|MD_PLANT|MD_DETECTOR|MD_ANGRY|MD_TARGETWEAK);
+
+ status->size = (sd->class_&JOBL_BABY)?SZ_SMALL:SZ_MEDIUM;
+ if (battle_config.character_size && pc_isriding(sd)) { //[Lupus]
+ if (sd->class_&JOBL_BABY) {
+ if (battle_config.character_size&SZ_BIG)
+ status->size++;
+ } else
+ if(battle_config.character_size&SZ_MEDIUM)
+ status->size++;
+ }
+ status->aspd_rate = 1000;
+ status->ele_lv = 1;
+ status->race = RC_DEMIHUMAN;
+
+ //zero up structures...
+ memset(&sd->autospell,0,sizeof(sd->autospell)
+ + sizeof(sd->autospell2)
+ + sizeof(sd->autospell3)
+ + sizeof(sd->addeff)
+ + sizeof(sd->addeff2)
+ + sizeof(sd->addeff3)
+ + sizeof(sd->skillatk)
+ + sizeof(sd->skillusesprate)
+ + sizeof(sd->skillusesp)
+ + sizeof(sd->skillheal)
+ + sizeof(sd->skillheal2)
+ + sizeof(sd->hp_loss)
+ + sizeof(sd->sp_loss)
+ + sizeof(sd->hp_regen)
+ + sizeof(sd->sp_regen)
+ + sizeof(sd->skillblown)
+ + sizeof(sd->skillcast)
+ + sizeof(sd->add_def)
+ + sizeof(sd->add_mdef)
+ + sizeof(sd->add_mdmg)
+ + sizeof(sd->add_drop)
+ + sizeof(sd->itemhealrate)
+ + sizeof(sd->subele2)
+ + sizeof(sd->skillcooldown)
+ + sizeof(sd->skillfixcast)
+ + sizeof(sd->skillvarcast)
+ );
+
+ memset (&sd->bonus, 0,sizeof(sd->bonus));
+
+ // Autobonus
+ pc_delautobonus(sd,sd->autobonus,ARRAYLENGTH(sd->autobonus),true);
+ pc_delautobonus(sd,sd->autobonus2,ARRAYLENGTH(sd->autobonus2),true);
+ pc_delautobonus(sd,sd->autobonus3,ARRAYLENGTH(sd->autobonus3),true);
+
+ // Parse equipment.
+ for(i=0;i<EQI_MAX-1;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 == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == index)
+ continue;
+ if(i == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == index)
+ continue;
+ if(i == EQI_HEAD_TOP && (sd->equip_index[EQI_HEAD_MID] == index || sd->equip_index[EQI_HEAD_LOW] == index))
+ continue;
+ if(i == EQI_COSTUME_MID && sd->equip_index[EQI_COSTUME_LOW] == index)
+ continue;
+ if(i == EQI_COSTUME_TOP && (sd->equip_index[EQI_COSTUME_MID] == index || sd->equip_index[EQI_COSTUME_LOW] == index))
+ continue;
+ if(!sd->inventory_data[index])
+ continue;
+
+ status->def += sd->inventory_data[index]->def;
+
+ if(first && sd->inventory_data[index]->equip_script)
+ { //Execute equip-script on login
+ run_script(sd->inventory_data[index]->equip_script,0,sd->bl.id,0);
+ if (!calculating)
+ return 1;
+ }
- // sanitize the refine level in case someone decreased the value inbetween
- if (sd->status.inventory[index].refine > MAX_REFINE)
- sd->status.inventory[index].refine = MAX_REFINE;
-
- if (sd->inventory_data[index]->type == IT_WEAPON) {
- int r,wlv = sd->inventory_data[index]->wlv;
- struct weapon_data *wd;
- struct weapon_atk *wa;
- if (wlv >= REFINE_TYPE_MAX)
- wlv = REFINE_TYPE_MAX - 1;
- if (i == EQI_HAND_L && sd->status.inventory[index].equip == EQP_HAND_L) {
- wd = &sd->left_weapon; // Left-hand weapon
- wa = &status->lhw;
- } else {
- wd = &sd->right_weapon;
- wa = &status->rhw;
- }
- wa->atk += sd->inventory_data[index]->atk;
- if ((r = sd->status.inventory[index].refine))
- wa->atk2 = refine_info[wlv].bonus[r-1] / 100;
+ // sanitize the refine level in case someone decreased the value inbetween
+ if (sd->status.inventory[index].refine > MAX_REFINE)
+ sd->status.inventory[index].refine = MAX_REFINE;
+
+ if(sd->inventory_data[index]->type == IT_WEAPON) {
+ int r,wlv = sd->inventory_data[index]->wlv;
+ struct weapon_data *wd;
+ struct weapon_atk *wa;
+ if (wlv >= REFINE_TYPE_MAX)
+ wlv = REFINE_TYPE_MAX - 1;
+ if(i == EQI_HAND_L && sd->status.inventory[index].equip == EQP_HAND_L) {
+ wd = &sd->left_weapon; // Left-hand weapon
+ wa = &status->lhw;
+ } else {
+ wd = &sd->right_weapon;
+ wa = &status->rhw;
+ }
+ wa->atk += sd->inventory_data[index]->atk;
+ if ( (r = sd->status.inventory[index].refine) )
+ wa->atk2 = refine_info[wlv].bonus[r-1] / 100;
#ifdef RENEWAL
- wa->matk += sd->inventory_data[index]->matk;
- wa->wlv = wlv;
- if( r ) // renewal magic attack refine bonus
- wa->matk += refine_info[wlv].bonus[r-1] / 100;
-#endif
-
- //Overrefine bonus.
- if (r)
- wd->overrefine = refine_info[wlv].randombonus_max[r-1] / 100;
-
- wa->range += sd->inventory_data[index]->range;
- if (sd->inventory_data[index]->script) {
- if (wd == &sd->left_weapon) {
- sd->state.lr_flag = 1;
- run_script(sd->inventory_data[index]->script,0,sd->bl.id,0);
- sd->state.lr_flag = 0;
- } else
- run_script(sd->inventory_data[index]->script,0,sd->bl.id,0);
- if (!calculating) //Abort, run_script retriggered this. [Skotlex]
- return 1;
- }
-
- if (sd->status.inventory[index].card[0]==CARD0_FORGE) {
- // Forged weapon
- wd->star += (sd->status.inventory[index].card[1]>>8);
- if (wd->star >= 15) wd->star = 40; // 3 Star Crumbs now give +40 dmg
- if (pc_famerank(MakeDWord(sd->status.inventory[index].card[2],sd->status.inventory[index].card[3]) ,MAPID_BLACKSMITH))
- wd->star += 10;
-
- if (!wa->ele) //Do not overwrite element from previous bonuses.
- wa->ele = (sd->status.inventory[index].card[1]&0x0f);
- }
- } else if (sd->inventory_data[index]->type == IT_ARMOR) {
- int r;
- if ((r = sd->status.inventory[index].refine))
- refinedef += refine_info[REFINE_TYPE_ARMOR].bonus[r-1];
- if (sd->inventory_data[index]->script) {
- if (i == EQI_HAND_L) //Shield
- sd->state.lr_flag = 3;
- run_script(sd->inventory_data[index]->script,0,sd->bl.id,0);
- if (i == EQI_HAND_L) //Shield
- sd->state.lr_flag = 0;
- if (!calculating) //Abort, run_script retriggered this. [Skotlex]
- return 1;
- }
- }
- }
-
- if (sd->equip_index[EQI_AMMO] >= 0) {
- index = sd->equip_index[EQI_AMMO];
- if (sd->inventory_data[index]) { // Arrows
- sd->bonus.arrow_atk += sd->inventory_data[index]->atk;
- sd->state.lr_flag = 2;
- if (!itemdb_is_GNthrowable(sd->inventory_data[index]->nameid)) //don't run scripts on throwable items
- run_script(sd->inventory_data[index]->script,0,sd->bl.id,0);
- sd->state.lr_flag = 0;
- if (!calculating) //Abort, run_script retriggered status_calc_pc. [Skotlex]
- return 1;
- }
- }
-
- /* we've got combos to process */
- if (sd->combos.count) {
- for (i = 0; i < sd->combos.count; i++) {
- run_script(sd->combos.bonus[i],0,sd->bl.id,0);
- if (!calculating) //Abort, run_script retriggered this.
- return 1;
- }
- }
+ // in renewal max MATK is the weapon MATK
+ status->matk_max += sd->inventory_data[index]->matk;
- //Store equipment script bonuses
- memcpy(sd->param_equip,sd->param_bonus,sizeof(sd->param_equip));
- memset(sd->param_bonus, 0, sizeof(sd->param_bonus));
-
- status->def += (refinedef+50)/100;
-
- //Parse Cards
- for (i=0; i<EQI_MAX-1; 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 == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == index)
- continue;
- if (i == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == index)
- continue;
- if (i == EQI_HEAD_TOP && (sd->equip_index[EQI_HEAD_MID] == index || sd->equip_index[EQI_HEAD_LOW] == index))
- continue;
-
- if (sd->inventory_data[index]) {
- int j,c;
- struct item_data *data;
-
- //Card script execution.
- if (itemdb_isspecial(sd->status.inventory[index].card[0]))
- continue;
- for (j=0; j<MAX_SLOTS; j++) { // Uses MAX_SLOTS to support Soul Bound system [Inkfish]
- current_equip_card_id= c= sd->status.inventory[index].card[j];
- if (!c)
- continue;
- data = itemdb_exists(c);
- if (!data)
- continue;
- if (first && data->equip_script) {
- //Execute equip-script on login
- run_script(data->equip_script,0,sd->bl.id,0);
- if (!calculating)
- return 1;
- }
- if (!data->script)
- continue;
- if (data->flag.no_equip) { //Card restriction checks.
- if (map[sd->bl.m].flag.restricted && data->flag.no_equip&(8*map[sd->bl.m].zone))
- continue;
- if (!map_flag_vs(sd->bl.m) && data->flag.no_equip&1)
- continue;
- if (map[sd->bl.m].flag.pvp && data->flag.no_equip&2)
- continue;
- if (map_flag_gvg(sd->bl.m) && data->flag.no_equip&4)
- continue;
- if (map[sd->bl.m].flag.battleground && data->flag.no_equip&8)
- continue;
- }
- if (i == EQI_HAND_L && sd->status.inventory[index].equip == EQP_HAND_L) {
- //Left hand status.
- sd->state.lr_flag = 1;
- run_script(data->script,0,sd->bl.id,0);
- sd->state.lr_flag = 0;
- } else
- run_script(data->script,0,sd->bl.id,0);
- if (!calculating) //Abort, run_script his function. [Skotlex]
- return 1;
- }
- }
- }
-
- if (sc->count && sc->data[SC_ITEMSCRIPT]) {
- struct item_data *data = itemdb_exists(sc->data[SC_ITEMSCRIPT]->val1);
- if (data && data->script)
- run_script(data->script,0,sd->bl.id,0);
- }
-
- if (sd->pd) {
- // Pet Bonus
- struct pet_data *pd = sd->pd;
- if (pd && pd->petDB && pd->petDB->equip_script && pd->pet.intimate >= battle_config.pet_equip_min_friendly)
- run_script(pd->petDB->equip_script,0,sd->bl.id,0);
- if (pd && pd->pet.intimate > 0 && (!battle_config.pet_equip_required || pd->pet.equip > 0) && pd->state.skillbonus == 1 && pd->bonus)
- pc_bonus(sd,pd->bonus->type, pd->bonus->val);
- }
+ if( r )
+ {// renewal magic attack refine bonus
+ status->matk_max += refine_info[wlv].bonus[r-1] / 100;
+ }
- //param_bonus now holds card bonuses.
- if (status->rhw.range < 1) status->rhw.range = 1;
- if (status->lhw.range < 1) status->lhw.range = 1;
- if (status->rhw.range < status->lhw.range)
- status->rhw.range = status->lhw.range;
-
- sd->bonus.double_rate += sd->bonus.double_add_rate;
- sd->bonus.perfect_hit += sd->bonus.perfect_hit_add;
- sd->bonus.splash_range += sd->bonus.splash_add_range;
-
- // Damage modifiers from weapon type
- sd->right_weapon.atkmods[0] = atkmods[0][sd->weapontype1];
- sd->right_weapon.atkmods[1] = atkmods[1][sd->weapontype1];
- sd->right_weapon.atkmods[2] = atkmods[2][sd->weapontype1];
- sd->left_weapon.atkmods[0] = atkmods[0][sd->weapontype2];
- sd->left_weapon.atkmods[1] = atkmods[1][sd->weapontype2];
- sd->left_weapon.atkmods[2] = atkmods[2][sd->weapontype2];
-
- if (pc_isriding(sd) &&
- (sd->status.weapon==W_1HSPEAR || sd->status.weapon==W_2HSPEAR)) {
- //When Riding with spear, damage modifier to mid-class becomes
- //same as versus large size.
- sd->right_weapon.atkmods[1] = sd->right_weapon.atkmods[2];
- sd->left_weapon.atkmods[1] = sd->left_weapon.atkmods[2];
- }
+ // record the weapon level for future usage
+ status->wlv = wlv;
+#endif
- // ----- STATS CALCULATION -----
-
- // Job bonuses
- index = pc_class2idx(sd->status.class_);
- for (i=0; i<(int)sd->status.job_level && i<MAX_LEVEL; i++) {
- if (!job_bonus[index][i])
- continue;
- switch (job_bonus[index][i]) {
- case 1:
- status->str++;
- break;
- case 2:
- status->agi++;
- break;
- case 3:
- status->vit++;
- break;
- case 4:
- status->int_++;
- break;
- case 5:
- status->dex++;
- break;
- case 6:
- status->luk++;
- break;
- }
- }
+ //Overrefine bonus.
+ if (r)
+ wd->overrefine = refine_info[wlv].randombonus_max[r-1] / 100;
+
+ wa->range += sd->inventory_data[index]->range;
+ if(sd->inventory_data[index]->script) {
+ if (wd == &sd->left_weapon) {
+ sd->state.lr_flag = 1;
+ run_script(sd->inventory_data[index]->script,0,sd->bl.id,0);
+ sd->state.lr_flag = 0;
+ } else
+ run_script(sd->inventory_data[index]->script,0,sd->bl.id,0);
+ if (!calculating) //Abort, run_script retriggered this. [Skotlex]
+ return 1;
+ }
- // If a Super Novice has never died and is at least joblv 70, he gets all stats +10
- if ((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->die_counter == 0 && sd->status.job_level >= 70) {
- status->str += 10;
- status->agi += 10;
- status->vit += 10;
- status->int_+= 10;
- status->dex += 10;
- status->luk += 10;
- }
+ if(sd->status.inventory[index].card[0]==CARD0_FORGE)
+ { // Forged weapon
+ wd->star += (sd->status.inventory[index].card[1]>>8);
+ if(wd->star >= 15) wd->star = 40; // 3 Star Crumbs now give +40 dmg
+ if(pc_famerank(MakeDWord(sd->status.inventory[index].card[2],sd->status.inventory[index].card[3]) ,MAPID_BLACKSMITH))
+ wd->star += 10;
- // Absolute modifiers from passive skills
- if (pc_checkskill(sd,BS_HILTBINDING)>0)
- status->str++;
- if ((skill=pc_checkskill(sd,SA_DRAGONOLOGY))>0)
- status->int_ += (skill+1)/2; // +1 INT / 2 lv
- if ((skill=pc_checkskill(sd,AC_OWL))>0)
- status->dex += skill;
- if ((skill = pc_checkskill(sd,RA_RESEARCHTRAP))>0)
- status->int_ += skill;
-
- // Bonuses from cards and equipment as well as base stat, remember to avoid overflows.
- i = status->str + sd->status.str + sd->param_bonus[0] + sd->param_equip[0];
- status->str = cap_value(i,0,USHRT_MAX);
- i = status->agi + sd->status.agi + sd->param_bonus[1] + sd->param_equip[1];
- status->agi = cap_value(i,0,USHRT_MAX);
- i = status->vit + sd->status.vit + sd->param_bonus[2] + sd->param_equip[2];
- status->vit = cap_value(i,0,USHRT_MAX);
- i = status->int_+ sd->status.int_+ sd->param_bonus[3] + sd->param_equip[3];
- status->int_ = cap_value(i,0,USHRT_MAX);
- i = status->dex + sd->status.dex + sd->param_bonus[4] + sd->param_equip[4];
- status->dex = cap_value(i,0,USHRT_MAX);
- i = status->luk + sd->status.luk + sd->param_bonus[5] + sd->param_equip[5];
- status->luk = cap_value(i,0,USHRT_MAX);
-
- // ------ BASE ATTACK CALCULATION ------
-
- // Base batk value is set on status_calc_misc
- // weapon-type bonus (FIXME: Why is the weapon_atk bonus applied to base attack?)
- if (sd->status.weapon < MAX_WEAPON_TYPE && sd->weapon_atk[sd->status.weapon])
- status->batk += sd->weapon_atk[sd->status.weapon];
- // Absolute modifiers from passive skills
- if ((skill=pc_checkskill(sd,BS_HILTBINDING))>0)
- status->batk += 4;
-
- // ----- HP MAX CALCULATION -----
-
- // Basic MaxHP value
- //We hold the standard Max HP here to make it faster to recalculate on vit changes.
- sd->status.max_hp = status_base_pc_maxhp(sd,status);
- //This is done to handle underflows from negative Max HP bonuses
- i = sd->status.max_hp + (int)status->max_hp;
- status->max_hp = cap_value(i, 0, INT_MAX);
-
- // Absolute modifiers from passive skills
- if ((skill=pc_checkskill(sd,CR_TRUST))>0)
- status->max_hp += skill*200;
-
- // Apply relative modifiers from equipment
- if (sd->hprate < 0)
- sd->hprate = 0;
- if (sd->hprate!=100)
- status->max_hp = status->max_hp * sd->hprate/100;
- if (battle_config.hp_rate != 100)
- status->max_hp = status->max_hp * battle_config.hp_rate/100;
-
- if (status->max_hp > (unsigned int)battle_config.max_hp)
- status->max_hp = battle_config.max_hp;
- else if (!status->max_hp)
- status->max_hp = 1;
-
- // ----- SP MAX CALCULATION -----
-
- // Basic MaxSP value
- sd->status.max_sp = status_base_pc_maxsp(sd,status);
- //This is done to handle underflows from negative Max SP bonuses
- i = sd->status.max_sp + (int)status->max_sp;
- status->max_sp = cap_value(i, 0, INT_MAX);
-
- // Absolute modifiers from passive skills
- if ((skill=pc_checkskill(sd,SL_KAINA))>0)
- status->max_sp += 30*skill;
- if ((skill=pc_checkskill(sd,HP_MEDITATIO))>0)
- status->max_sp += status->max_sp * skill/100;
- if ((skill=pc_checkskill(sd,HW_SOULDRAIN))>0)
- status->max_sp += status->max_sp * 2*skill/100;
- if ((skill = pc_checkskill(sd,RA_RESEARCHTRAP)) > 0)
- status->max_sp += 200 + 20 * skill;
- if ((skill = pc_checkskill(sd,WM_LESSON)) > 0)
- status->max_sp += 30 * skill;
-
-
- // Apply relative modifiers from equipment
- if (sd->sprate < 0)
- sd->sprate = 0;
- if (sd->sprate!=100)
- status->max_sp = status->max_sp * sd->sprate/100;
- if (battle_config.sp_rate != 100)
- status->max_sp = status->max_sp * battle_config.sp_rate/100;
-
- if (status->max_sp > (unsigned int)battle_config.max_sp)
- status->max_sp = battle_config.max_sp;
- else if (!status->max_sp)
- status->max_sp = 1;
-
- // ----- RESPAWN HP/SP -----
- //
- //Calc respawn hp and store it on base_status
- if (sd->special_state.restart_full_recover) {
- status->hp = status->max_hp;
- status->sp = status->max_sp;
- } else {
- if ((sd->class_&MAPID_BASEMASK) == MAPID_NOVICE && !(sd->class_&JOBL_2)
- && battle_config.restart_hp_rate < 50)
- status->hp=status->max_hp>>1;
- else
- status->hp=status->max_hp * battle_config.restart_hp_rate/100;
- if (!status->hp)
- status->hp = 1;
-
- status->sp = status->max_sp * battle_config.restart_sp_rate /100;
-
- if (!status->sp) /* the minimum for the respawn setting is SP:1 */
- status->sp = 1;
- }
+ if (!wa->ele) //Do not overwrite element from previous bonuses.
+ wa->ele = (sd->status.inventory[index].card[1]&0x0f);
+ }
+ }
+ else if(sd->inventory_data[index]->type == IT_ARMOR) {
+ int r;
+ if ( (r = sd->status.inventory[index].refine) )
+ refinedef += refine_info[REFINE_TYPE_ARMOR].bonus[r-1];
+ if(sd->inventory_data[index]->script) {
+ if( i == EQI_HAND_L ) //Shield
+ sd->state.lr_flag = 3;
+ run_script(sd->inventory_data[index]->script,0,sd->bl.id,0);
+ if( i == EQI_HAND_L ) //Shield
+ sd->state.lr_flag = 0;
+ if (!calculating) //Abort, run_script retriggered this. [Skotlex]
+ return 1;
+ }
+ }
+ }
+
+ if(sd->equip_index[EQI_AMMO] >= 0){
+ index = sd->equip_index[EQI_AMMO];
+ if(sd->inventory_data[index]){ // Arrows
+ sd->bonus.arrow_atk += sd->inventory_data[index]->atk;
+ sd->state.lr_flag = 2;
+ if( !itemdb_is_GNthrowable(sd->inventory_data[index]->nameid) ) //don't run scripts on throwable items
+ run_script(sd->inventory_data[index]->script,0,sd->bl.id,0);
+ sd->state.lr_flag = 0;
+ if (!calculating) //Abort, run_script retriggered status_calc_pc. [Skotlex]
+ return 1;
+ }
+ }
+
+ /* we've got combos to process */
+ if( sd->combos.count ) {
+ for( i = 0; i < sd->combos.count; i++ ) {
+ run_script(sd->combos.bonus[i],0,sd->bl.id,0);
+ if (!calculating) //Abort, run_script retriggered this.
+ return 1;
+ }
+ }
- // ----- MISC CALCULATION -----
- status_calc_misc(&sd->bl, status, sd->status.base_level);
+ //Store equipment script bonuses
+ memcpy(sd->param_equip,sd->param_bonus,sizeof(sd->param_equip));
+ memset(sd->param_bonus, 0, sizeof(sd->param_bonus));
- //Equipment modifiers for misc settings
- if (sd->matk_rate < 0)
- sd->matk_rate = 0;
+ status->def += (refinedef+50)/100;
- if (sd->matk_rate != 100) {
- status->matk_max = status->matk_max * sd->matk_rate/100;
- status->matk_min = status->matk_min * sd->matk_rate/100;
- }
+#ifdef RENEWAL
+ // increment the weapon ATK using the MATK max value
+ status->matk_max += sd->bonus.sp_weapon_matk;
+#endif
- if (sd->hit_rate < 0)
- sd->hit_rate = 0;
- if (sd->hit_rate != 100)
- status->hit = status->hit * sd->hit_rate/100;
-
- if (sd->flee_rate < 0)
- sd->flee_rate = 0;
- if (sd->flee_rate != 100)
- status->flee = status->flee * sd->flee_rate/100;
-
- if (sd->def2_rate < 0)
- sd->def2_rate = 0;
- if (sd->def2_rate != 100)
- status->def2 = status->def2 * sd->def2_rate/100;
-
- if (sd->mdef2_rate < 0)
- sd->mdef2_rate = 0;
- if (sd->mdef2_rate != 100)
- status->mdef2 = status->mdef2 * sd->mdef2_rate/100;
-
- if (sd->critical_rate < 0)
- sd->critical_rate = 0;
- if (sd->critical_rate != 100)
- status->cri = status->cri * sd->critical_rate/100;
-
- if (sd->flee2_rate < 0)
- sd->flee2_rate = 0;
- if (sd->flee2_rate != 100)
- status->flee2 = status->flee2 * sd->flee2_rate/100;
-
- // ----- HIT CALCULATION -----
-
- // Absolute modifiers from passive skills
- if ((skill=pc_checkskill(sd,BS_WEAPONRESEARCH))>0)
- status->hit += skill*2;
- if ((skill=pc_checkskill(sd,AC_VULTURE))>0) {
+ //Parse Cards
+ for(i=0;i<EQI_MAX-1;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 == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == index)
+ continue;
+ if(i == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == index)
+ continue;
+ if(i == EQI_HEAD_TOP && (sd->equip_index[EQI_HEAD_MID] == index || sd->equip_index[EQI_HEAD_LOW] == index))
+ continue;
+
+ if(sd->inventory_data[index]) {
+ int j,c;
+ struct item_data *data;
+
+ //Card script execution.
+ if(itemdb_isspecial(sd->status.inventory[index].card[0]))
+ continue;
+ for(j=0;j<MAX_SLOTS;j++){ // Uses MAX_SLOTS to support Soul Bound system [Inkfish]
+ current_equip_card_id= c= sd->status.inventory[index].card[j];
+ if(!c)
+ continue;
+ data = itemdb_exists(c);
+ if(!data)
+ continue;
+ if(first && data->equip_script)
+ { //Execute equip-script on login
+ run_script(data->equip_script,0,sd->bl.id,0);
+ if (!calculating)
+ return 1;
+ }
+ if(!data->script)
+ continue;
+ if(data->flag.no_equip) { //Card restriction checks.
+ if(map[sd->bl.m].flag.restricted && data->flag.no_equip&(8*map[sd->bl.m].zone))
+ continue;
+ if(!map_flag_vs(sd->bl.m) && data->flag.no_equip&1)
+ continue;
+ if(map[sd->bl.m].flag.pvp && data->flag.no_equip&2)
+ continue;
+ if(map_flag_gvg(sd->bl.m) && data->flag.no_equip&4)
+ continue;
+ if(map[sd->bl.m].flag.battleground && data->flag.no_equip&8)
+ continue;
+ }
+ if(i == EQI_HAND_L && sd->status.inventory[index].equip == EQP_HAND_L)
+ { //Left hand status.
+ sd->state.lr_flag = 1;
+ run_script(data->script,0,sd->bl.id,0);
+ sd->state.lr_flag = 0;
+ } else
+ run_script(data->script,0,sd->bl.id,0);
+ if (!calculating) //Abort, run_script his function. [Skotlex]
+ return 1;
+ }
+ }
+ }
+
+ if( sc->count && sc->data[SC_ITEMSCRIPT] )
+ {
+ struct item_data *data = itemdb_exists(sc->data[SC_ITEMSCRIPT]->val1);
+ if( data && data->script )
+ run_script(data->script,0,sd->bl.id,0);
+ }
+
+ if( sd->pd )
+ { // Pet Bonus
+ struct pet_data *pd = sd->pd;
+ if( pd && pd->petDB && pd->petDB->equip_script && pd->pet.intimate >= battle_config.pet_equip_min_friendly )
+ run_script(pd->petDB->equip_script,0,sd->bl.id,0);
+ if( pd && pd->pet.intimate > 0 && (!battle_config.pet_equip_required || pd->pet.equip > 0) && pd->state.skillbonus == 1 && pd->bonus )
+ pc_bonus(sd,pd->bonus->type, pd->bonus->val);
+ }
+
+ //param_bonus now holds card bonuses.
+ if(status->rhw.range < 1) status->rhw.range = 1;
+ if(status->lhw.range < 1) status->lhw.range = 1;
+ if(status->rhw.range < status->lhw.range)
+ status->rhw.range = status->lhw.range;
+
+ sd->bonus.double_rate += sd->bonus.double_add_rate;
+ sd->bonus.perfect_hit += sd->bonus.perfect_hit_add;
+ sd->bonus.splash_range += sd->bonus.splash_add_range;
+
+ // Damage modifiers from weapon type
+ sd->right_weapon.atkmods[0] = atkmods[0][sd->weapontype1];
+ sd->right_weapon.atkmods[1] = atkmods[1][sd->weapontype1];
+ sd->right_weapon.atkmods[2] = atkmods[2][sd->weapontype1];
+ sd->left_weapon.atkmods[0] = atkmods[0][sd->weapontype2];
+ sd->left_weapon.atkmods[1] = atkmods[1][sd->weapontype2];
+ sd->left_weapon.atkmods[2] = atkmods[2][sd->weapontype2];
+
+ if(pc_isriding(sd) &&
+ (sd->status.weapon==W_1HSPEAR || sd->status.weapon==W_2HSPEAR))
+ { //When Riding with spear, damage modifier to mid-class becomes
+ //same as versus large size.
+ sd->right_weapon.atkmods[1] = sd->right_weapon.atkmods[2];
+ sd->left_weapon.atkmods[1] = sd->left_weapon.atkmods[2];
+ }
+
+// ----- STATS CALCULATION -----
+
+ // Job bonuses
+ index = pc_class2idx(sd->status.class_);
+ for(i=0;i<(int)sd->status.job_level && i<MAX_LEVEL;i++){
+ if(!job_bonus[index][i])
+ continue;
+ switch(job_bonus[index][i]) {
+ case 1: status->str++; break;
+ case 2: status->agi++; break;
+ case 3: status->vit++; break;
+ case 4: status->int_++; break;
+ case 5: status->dex++; break;
+ case 6: status->luk++; break;
+ }
+ }
+
+ // If a Super Novice has never died and is at least joblv 70, he gets all stats +10
+ if((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->die_counter == 0 && sd->status.job_level >= 70){
+ status->str += 10;
+ status->agi += 10;
+ status->vit += 10;
+ status->int_+= 10;
+ status->dex += 10;
+ status->luk += 10;
+ }
+
+ // Absolute modifiers from passive skills
+ if(pc_checkskill(sd,BS_HILTBINDING)>0)
+ status->str++;
+ if((skill=pc_checkskill(sd,SA_DRAGONOLOGY))>0)
+ status->int_ += (skill+1)/2; // +1 INT / 2 lv
+ if((skill=pc_checkskill(sd,AC_OWL))>0)
+ status->dex += skill;
+ if((skill = pc_checkskill(sd,RA_RESEARCHTRAP))>0)
+ status->int_ += skill;
+
+ // Bonuses from cards and equipment as well as base stat, remember to avoid overflows.
+ i = status->str + sd->status.str + sd->param_bonus[0] + sd->param_equip[0];
+ status->str = cap_value(i,0,USHRT_MAX);
+ i = status->agi + sd->status.agi + sd->param_bonus[1] + sd->param_equip[1];
+ status->agi = cap_value(i,0,USHRT_MAX);
+ i = status->vit + sd->status.vit + sd->param_bonus[2] + sd->param_equip[2];
+ status->vit = cap_value(i,0,USHRT_MAX);
+ i = status->int_+ sd->status.int_+ sd->param_bonus[3] + sd->param_equip[3];
+ status->int_ = cap_value(i,0,USHRT_MAX);
+ i = status->dex + sd->status.dex + sd->param_bonus[4] + sd->param_equip[4];
+ status->dex = cap_value(i,0,USHRT_MAX);
+ i = status->luk + sd->status.luk + sd->param_bonus[5] + sd->param_equip[5];
+ status->luk = cap_value(i,0,USHRT_MAX);
+
+// ------ BASE ATTACK CALCULATION ------
+
+ // Base batk value is set on status_calc_misc
+ // weapon-type bonus (FIXME: Why is the weapon_atk bonus applied to base attack?)
+ if (sd->status.weapon < MAX_WEAPON_TYPE && sd->weapon_atk[sd->status.weapon])
+ status->batk += sd->weapon_atk[sd->status.weapon];
+ // Absolute modifiers from passive skills
+ if((skill=pc_checkskill(sd,BS_HILTBINDING))>0)
+ status->batk += 4;
+
+// ----- HP MAX CALCULATION -----
+
+ // Basic MaxHP value
+ //We hold the standard Max HP here to make it faster to recalculate on vit changes.
+ sd->status.max_hp = status_base_pc_maxhp(sd,status);
+ //This is done to handle underflows from negative Max HP bonuses
+ i = sd->status.max_hp + (int)status->max_hp;
+ status->max_hp = cap_value(i, 0, INT_MAX);
+
+ // Absolute modifiers from passive skills
+ if((skill=pc_checkskill(sd,CR_TRUST))>0)
+ status->max_hp += skill*200;
+
+ // Apply relative modifiers from equipment
+ if(sd->hprate < 0)
+ sd->hprate = 0;
+ if(sd->hprate!=100)
+ status->max_hp = status->max_hp * sd->hprate/100;
+ if(battle_config.hp_rate != 100)
+ status->max_hp = status->max_hp * battle_config.hp_rate/100;
+
+ if(status->max_hp > (unsigned int)battle_config.max_hp)
+ status->max_hp = battle_config.max_hp;
+ else if(!status->max_hp)
+ status->max_hp = 1;
+
+// ----- SP MAX CALCULATION -----
+
+ // Basic MaxSP value
+ sd->status.max_sp = status_base_pc_maxsp(sd,status);
+ //This is done to handle underflows from negative Max SP bonuses
+ i = sd->status.max_sp + (int)status->max_sp;
+ status->max_sp = cap_value(i, 0, INT_MAX);
+
+ // Absolute modifiers from passive skills
+ if((skill=pc_checkskill(sd,SL_KAINA))>0)
+ status->max_sp += 30*skill;
+ if((skill=pc_checkskill(sd,HP_MEDITATIO))>0)
+ status->max_sp += status->max_sp * skill/100;
+ if((skill=pc_checkskill(sd,HW_SOULDRAIN))>0)
+ status->max_sp += status->max_sp * 2*skill/100;
+ if( (skill = pc_checkskill(sd,RA_RESEARCHTRAP)) > 0 )
+ status->max_sp += 200 + 20 * skill;
+ if( (skill = pc_checkskill(sd,WM_LESSON)) > 0 )
+ status->max_sp += 30 * skill;
+
+
+ // Apply relative modifiers from equipment
+ if(sd->sprate < 0)
+ sd->sprate = 0;
+ if(sd->sprate!=100)
+ status->max_sp = status->max_sp * sd->sprate/100;
+ if(battle_config.sp_rate != 100)
+ status->max_sp = status->max_sp * battle_config.sp_rate/100;
+
+ if(status->max_sp > (unsigned int)battle_config.max_sp)
+ status->max_sp = battle_config.max_sp;
+ else if(!status->max_sp)
+ status->max_sp = 1;
+
+// ----- RESPAWN HP/SP -----
+//
+ //Calc respawn hp and store it on base_status
+ if (sd->special_state.restart_full_recover)
+ {
+ status->hp = status->max_hp;
+ status->sp = status->max_sp;
+ } else {
+ if((sd->class_&MAPID_BASEMASK) == MAPID_NOVICE && !(sd->class_&JOBL_2)
+ && battle_config.restart_hp_rate < 50)
+ status->hp=status->max_hp>>1;
+ else
+ status->hp=status->max_hp * battle_config.restart_hp_rate/100;
+ if(!status->hp)
+ status->hp = 1;
+
+ status->sp = status->max_sp * battle_config.restart_sp_rate /100;
+
+ if( !status->sp ) /* the minimum for the respawn setting is SP:1 */
+ status->sp = 1;
+ }
+
+// ----- MISC CALCULATION -----
+ status_calc_misc(&sd->bl, status, sd->status.base_level);
+
+ //Equipment modifiers for misc settings
+ if(sd->matk_rate < 0)
+ sd->matk_rate = 0;
+
+ if(sd->matk_rate != 100){
+ status->matk_max = status->matk_max * sd->matk_rate/100;
+ status->matk_min = status->matk_min * sd->matk_rate/100;
+ }
+
+ if(sd->hit_rate < 0)
+ sd->hit_rate = 0;
+ if(sd->hit_rate != 100)
+ status->hit = status->hit * sd->hit_rate/100;
+
+ if(sd->flee_rate < 0)
+ sd->flee_rate = 0;
+ if(sd->flee_rate != 100)
+ status->flee = status->flee * sd->flee_rate/100;
+
+ if(sd->def2_rate < 0)
+ sd->def2_rate = 0;
+ if(sd->def2_rate != 100)
+ status->def2 = status->def2 * sd->def2_rate/100;
+
+ if(sd->mdef2_rate < 0)
+ sd->mdef2_rate = 0;
+ if(sd->mdef2_rate != 100)
+ status->mdef2 = status->mdef2 * sd->mdef2_rate/100;
+
+ if(sd->critical_rate < 0)
+ sd->critical_rate = 0;
+ if(sd->critical_rate != 100)
+ status->cri = status->cri * sd->critical_rate/100;
+
+ if(sd->flee2_rate < 0)
+ sd->flee2_rate = 0;
+ if(sd->flee2_rate != 100)
+ status->flee2 = status->flee2 * sd->flee2_rate/100;
+
+// ----- HIT CALCULATION -----
+
+ // Absolute modifiers from passive skills
+ if((skill=pc_checkskill(sd,BS_WEAPONRESEARCH))>0)
+ status->hit += skill*2;
+ if((skill=pc_checkskill(sd,AC_VULTURE))>0){
#ifndef RENEWAL
- status->hit += skill;
+ status->hit += skill;
#endif
- if (sd->status.weapon == W_BOW)
- status->rhw.range += skill;
- }
- if (sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE) {
- if ((skill=pc_checkskill(sd,GS_SINGLEACTION))>0)
- status->hit += 2*skill;
- if ((skill=pc_checkskill(sd,GS_SNAKEEYE))>0) {
- status->hit += skill;
- status->rhw.range += skill;
- }
- }
+ if(sd->status.weapon == W_BOW)
+ status->rhw.range += skill;
+ }
+ if(sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE)
+ {
+ if((skill=pc_checkskill(sd,GS_SINGLEACTION))>0)
+ status->hit += 2*skill;
+ if((skill=pc_checkskill(sd,GS_SNAKEEYE))>0) {
+ status->hit += skill;
+ status->rhw.range += skill;
+ }
+ }
- // ----- FLEE CALCULATION -----
-
- // Absolute modifiers from passive skills
- if ((skill=pc_checkskill(sd,TF_MISS))>0)
- status->flee += skill*(sd->class_&JOBL_2 && (sd->class_&MAPID_BASEMASK) == MAPID_THIEF? 4 : 3);
- if ((skill=pc_checkskill(sd,MO_DODGE))>0)
- status->flee += (skill*3)>>1;
- // ----- EQUIPMENT-DEF CALCULATION -----
-
- // Apply relative modifiers from equipment
- if (sd->def_rate < 0)
- sd->def_rate = 0;
- if (sd->def_rate != 100) {
- i = status->def * sd->def_rate/100;
- status->def = cap_value(i, DEFTYPE_MIN, DEFTYPE_MAX);
- }
+// ----- FLEE CALCULATION -----
+
+ // Absolute modifiers from passive skills
+ if((skill=pc_checkskill(sd,TF_MISS))>0)
+ status->flee += skill*(sd->class_&JOBL_2 && (sd->class_&MAPID_BASEMASK) == MAPID_THIEF? 4 : 3);
+ if((skill=pc_checkskill(sd,MO_DODGE))>0)
+ status->flee += (skill*3)>>1;
+// ----- EQUIPMENT-DEF CALCULATION -----
+
+ // Apply relative modifiers from equipment
+ if(sd->def_rate < 0)
+ sd->def_rate = 0;
+ if(sd->def_rate != 100) {
+ i = status->def * sd->def_rate/100;
+ status->def = cap_value(i, DEFTYPE_MIN, DEFTYPE_MAX);
+ }
#ifndef RENEWAL
- if (!battle_config.weapon_defense_type && status->def > battle_config.max_def) {
- status->def2 += battle_config.over_def_bonus*(status->def -battle_config.max_def);
- status->def = (unsigned char)battle_config.max_def;
- }
+ if (!battle_config.weapon_defense_type && status->def > battle_config.max_def)
+ {
+ status->def2 += battle_config.over_def_bonus*(status->def -battle_config.max_def);
+ status->def = (unsigned char)battle_config.max_def;
+ }
#endif
- // ----- EQUIPMENT-MDEF CALCULATION -----
+// ----- EQUIPMENT-MDEF CALCULATION -----
- // Apply relative modifiers from equipment
- if (sd->mdef_rate < 0)
- sd->mdef_rate = 0;
- if (sd->mdef_rate != 100) {
- i = status->mdef * sd->mdef_rate/100;
- status->mdef = cap_value(i, DEFTYPE_MIN, DEFTYPE_MAX);
- }
+ // Apply relative modifiers from equipment
+ if(sd->mdef_rate < 0)
+ sd->mdef_rate = 0;
+ if(sd->mdef_rate != 100) {
+ i = status->mdef * sd->mdef_rate/100;
+ status->mdef = cap_value(i, DEFTYPE_MIN, DEFTYPE_MAX);
+ }
#ifndef RENEWAL
- if (!battle_config.magic_defense_type && status->mdef > battle_config.max_def) {
- status->mdef2 += battle_config.over_def_bonus*(status->mdef -battle_config.max_def);
- status->mdef = (signed char)battle_config.max_def;
- }
+ if (!battle_config.magic_defense_type && status->mdef > battle_config.max_def)
+ {
+ status->mdef2 += battle_config.over_def_bonus*(status->mdef -battle_config.max_def);
+ status->mdef = (signed char)battle_config.max_def;
+ }
#endif
- // ----- ASPD CALCULATION -----
- // Unlike other stats, ASPD rate modifiers from skills/SCs/items/etc are first all added together, then the final modifier is applied
+// ----- ASPD CALCULATION -----
+// Unlike other stats, ASPD rate modifiers from skills/SCs/items/etc are first all added together, then the final modifier is applied
- // Basic ASPD value
- i = status_base_amotion_pc(sd,status);
- status->amotion = cap_value(i,((sd->class_&JOBL_THIRD) ? battle_config.max_third_aspd : battle_config.max_aspd),2000);
+ // Basic ASPD value
+ i = status_base_amotion_pc(sd,status);
+ status->amotion = cap_value(i,((sd->class_&JOBL_THIRD) ? battle_config.max_third_aspd : battle_config.max_aspd),2000);
- // Relative modifiers from passive skills
+ // Relative modifiers from passive skills
#ifndef RENEWAL_ASPD
- if ((skill=pc_checkskill(sd,SA_ADVANCEDBOOK))>0 && sd->status.weapon == W_BOOK)
- status->aspd_rate -= 5*skill;
- if ((skill = pc_checkskill(sd,SG_DEVIL)) > 0 && !pc_nextjobexp(sd))
- status->aspd_rate -= 30*skill;
- if ((skill=pc_checkskill(sd,GS_SINGLEACTION))>0 &&
- (sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE))
- status->aspd_rate -= ((skill+1)/2) * 10;
- if (pc_isriding(sd))
- status->aspd_rate += 500-100*pc_checkskill(sd,KN_CAVALIERMASTERY);
- else if (pc_isridingdragon(sd))
- status->aspd_rate += 250-50*pc_checkskill(sd,RK_DRAGONTRAINING);
+ if((skill=pc_checkskill(sd,SA_ADVANCEDBOOK))>0 && sd->status.weapon == W_BOOK)
+ status->aspd_rate -= 5*skill;
+ if((skill = pc_checkskill(sd,SG_DEVIL)) > 0 && !pc_nextjobexp(sd))
+ status->aspd_rate -= 30*skill;
+ if((skill=pc_checkskill(sd,GS_SINGLEACTION))>0 &&
+ (sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE))
+ status->aspd_rate -= ((skill+1)/2) * 10;
+ if(pc_isriding(sd))
+ status->aspd_rate += 500-100*pc_checkskill(sd,KN_CAVALIERMASTERY);
+ else if(pc_isridingdragon(sd))
+ status->aspd_rate += 250-50*pc_checkskill(sd,RK_DRAGONTRAINING);
#else // needs more info
- if ((skill=pc_checkskill(sd,SA_ADVANCEDBOOK))>0 && sd->status.weapon == W_BOOK)
- status->aspd_rate += 5*skill;
- if ((skill = pc_checkskill(sd,SG_DEVIL)) > 0 && !pc_nextjobexp(sd))
- status->aspd_rate += 30*skill;
- if ((skill=pc_checkskill(sd,GS_SINGLEACTION))>0 &&
- (sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE))
- status->aspd_rate += ((skill+1)/2) * 10;
- if (pc_isriding(sd))
- status->aspd_rate -= 500-100*pc_checkskill(sd,KN_CAVALIERMASTERY);
- else if (pc_isridingdragon(sd))
- status->aspd_rate -= 250-50*pc_checkskill(sd,RK_DRAGONTRAINING);
+ if((skill=pc_checkskill(sd,SA_ADVANCEDBOOK))>0 && sd->status.weapon == W_BOOK)
+ status->aspd_rate += 5*skill;
+ if((skill = pc_checkskill(sd,SG_DEVIL)) > 0 && !pc_nextjobexp(sd))
+ status->aspd_rate += 30*skill;
+ if((skill=pc_checkskill(sd,GS_SINGLEACTION))>0 &&
+ (sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE))
+ status->aspd_rate += ((skill+1)/2) * 10;
+ if(pc_isriding(sd))
+ status->aspd_rate -= 500-100*pc_checkskill(sd,KN_CAVALIERMASTERY);
+ else if(pc_isridingdragon(sd))
+ status->aspd_rate -= 250-50*pc_checkskill(sd,RK_DRAGONTRAINING);
#endif
- status->adelay = 2*status->amotion;
-
-
- // ----- DMOTION -----
- //
- i = 800-status->agi*4;
- status->dmotion = cap_value(i, 400, 800);
- if (battle_config.pc_damage_delay_rate != 100)
- status->dmotion = status->dmotion*battle_config.pc_damage_delay_rate/100;
-
- // ----- MISC CALCULATIONS -----
-
- // Weight
- if ((skill=pc_checkskill(sd,MC_INCCARRY))>0)
- sd->max_weight += 2000*skill;
- if (pc_isriding(sd) && pc_checkskill(sd,KN_RIDING)>0)
- sd->max_weight += 10000;
- else if (pc_isridingdragon(sd))
- sd->max_weight += 5000+2000*pc_checkskill(sd,RK_DRAGONTRAINING);
- if (sc->data[SC_KNOWLEDGE])
- sd->max_weight += sd->max_weight*sc->data[SC_KNOWLEDGE]->val1/10;
- if ((skill=pc_checkskill(sd,ALL_INCCARRY))>0)
- sd->max_weight += 2000*skill;
-
- sd->cart_weight_max = battle_config.max_cart_weight + (pc_checkskill(sd, GN_REMODELING_CART)*5000);
-
- if (pc_checkskill(sd,SM_MOVINGRECOVERY)>0)
- sd->regen.state.walk = 1;
- else
- sd->regen.state.walk = 0;
-
- // Skill SP cost
- if ((skill=pc_checkskill(sd,HP_MANARECHARGE))>0)
- sd->dsprate -= 4*skill;
-
- if (sc->data[SC_SERVICE4U])
- sd->dsprate -= sc->data[SC_SERVICE4U]->val3;
-
- if (sc->data[SC_SPCOST_RATE])
- sd->dsprate -= sc->data[SC_SPCOST_RATE]->val1;
-
- //Underflow protections.
- if (sd->dsprate < 0)
- sd->dsprate = 0;
- if (sd->castrate < 0)
- sd->castrate = 0;
- if (sd->delayrate < 0)
- sd->delayrate = 0;
- if (sd->hprecov_rate < 0)
- sd->hprecov_rate = 0;
- if (sd->sprecov_rate < 0)
- sd->sprecov_rate = 0;
-
- // Anti-element and anti-race
- if ((skill=pc_checkskill(sd,CR_TRUST))>0)
- sd->subele[ELE_HOLY] += skill*5;
- if ((skill=pc_checkskill(sd,BS_SKINTEMPER))>0) {
- sd->subele[ELE_NEUTRAL] += skill;
- sd->subele[ELE_FIRE] += skill*4;
- }
- if ((skill=pc_checkskill(sd,SA_DRAGONOLOGY))>0) {
- skill = skill*4;
- sd->right_weapon.addrace[RC_DRAGON]+=skill;
- sd->left_weapon.addrace[RC_DRAGON]+=skill;
- sd->magic_addrace[RC_DRAGON]+=skill;
- sd->subrace[RC_DRAGON]+=skill;
- }
-
- if (sc->count) {
- if (sc->data[SC_CONCENTRATE]) { //Update the card-bonus data
- sc->data[SC_CONCENTRATE]->val3 = sd->param_bonus[1]; //Agi
- sc->data[SC_CONCENTRATE]->val4 = sd->param_bonus[4]; //Dex
- }
- if (sc->data[SC_SIEGFRIED]) {
- i = sc->data[SC_SIEGFRIED]->val2;
- sd->subele[ELE_WATER] += i;
- sd->subele[ELE_EARTH] += i;
- sd->subele[ELE_FIRE] += i;
- sd->subele[ELE_WIND] += i;
- sd->subele[ELE_POISON] += i;
- sd->subele[ELE_HOLY] += i;
- sd->subele[ELE_DARK] += i;
- sd->subele[ELE_GHOST] += i;
- sd->subele[ELE_UNDEAD] += i;
- }
- if (sc->data[SC_PROVIDENCE]) {
- sd->subele[ELE_HOLY] += sc->data[SC_PROVIDENCE]->val2;
- sd->subrace[RC_DEMON] += sc->data[SC_PROVIDENCE]->val2;
- }
- if (sc->data[SC_ARMOR_ELEMENT]) { //This status change should grant card-type elemental resist.
- sd->subele[ELE_WATER] += sc->data[SC_ARMOR_ELEMENT]->val1;
- sd->subele[ELE_EARTH] += sc->data[SC_ARMOR_ELEMENT]->val2;
- sd->subele[ELE_FIRE] += sc->data[SC_ARMOR_ELEMENT]->val3;
- sd->subele[ELE_WIND] += sc->data[SC_ARMOR_ELEMENT]->val4;
- }
- if (sc->data[SC_ARMOR_RESIST]) { // Undead Scroll
- sd->subele[ELE_WATER] += sc->data[SC_ARMOR_RESIST]->val1;
- sd->subele[ELE_EARTH] += sc->data[SC_ARMOR_RESIST]->val2;
- sd->subele[ELE_FIRE] += sc->data[SC_ARMOR_RESIST]->val3;
- sd->subele[ELE_WIND] += sc->data[SC_ARMOR_RESIST]->val4;
- }
- if (sc->data[SC_FIRE_CLOAK_OPTION]) {
- i = sc->data[SC_FIRE_CLOAK_OPTION]->val2;
- sd->subele[ELE_FIRE] += i;
- sd->subele[ELE_EARTH] -= i;
- }
- if (sc->data[SC_WATER_DROP_OPTION]) {
- i = sc->data[SC_WATER_DROP_OPTION]->val2;
- sd->subele[ELE_WATER] += i;
- sd->subele[ELE_WIND] -= i;
- }
- if (sc->data[SC_WIND_CURTAIN_OPTION]) {
- i = sc->data[SC_WIND_CURTAIN_OPTION]->val2;
- sd->subele[ELE_WIND] += i;
- sd->subele[ELE_WATER] -= i;
- }
- if (sc->data[SC_STONE_SHIELD_OPTION]) {
- i = sc->data[SC_STONE_SHIELD_OPTION]->val2;
- sd->subele[ELE_EARTH] += i;
- sd->subele[ELE_FIRE] -= i;
- }
- if (sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 3)
- sd->magic_addele[ELE_FIRE] += 25;
- if (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 3)
- sd->magic_addele[ELE_WATER] += 25;
- if (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 3)
- sd->magic_addele[ELE_WIND] += 25;
- if (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 3)
- sd->magic_addele[ELE_EARTH] += 25;
- }
- status_cpy(&sd->battle_status, status);
-
- // ----- CLIENT-SIDE REFRESH -----
- if (!sd->bl.prev) {
- //Will update on LoadEndAck
- calculating = 0;
- return 0;
- }
- if (memcmp(b_skill,sd->status.skill,sizeof(sd->status.skill)))
- clif_skillinfoblock(sd);
- if (b_weight != sd->weight)
- clif_updatestatus(sd,SP_WEIGHT);
- if (b_max_weight != sd->max_weight) {
- clif_updatestatus(sd,SP_MAXWEIGHT);
- pc_updateweightstatus(sd);
- }
- if (b_cart_weight_max != sd->cart_weight_max) {
- clif_updatestatus(sd,SP_CARTINFO);
- }
-
- calculating = 0;
-
- return 0;
+ status->adelay = 2*status->amotion;
+
+
+// ----- DMOTION -----
+//
+ i = 800-status->agi*4;
+ status->dmotion = cap_value(i, 400, 800);
+ if(battle_config.pc_damage_delay_rate != 100)
+ status->dmotion = status->dmotion*battle_config.pc_damage_delay_rate/100;
+
+// ----- MISC CALCULATIONS -----
+
+ // Weight
+ if((skill=pc_checkskill(sd,MC_INCCARRY))>0)
+ sd->max_weight += 2000*skill;
+ if(pc_isriding(sd) && pc_checkskill(sd,KN_RIDING)>0)
+ sd->max_weight += 10000;
+ else if(pc_isridingdragon(sd))
+ sd->max_weight += 5000+2000*pc_checkskill(sd,RK_DRAGONTRAINING);
+ if(sc->data[SC_KNOWLEDGE])
+ sd->max_weight += sd->max_weight*sc->data[SC_KNOWLEDGE]->val1/10;
+ if((skill=pc_checkskill(sd,ALL_INCCARRY))>0)
+ sd->max_weight += 2000*skill;
+
+ sd->cart_weight_max = battle_config.max_cart_weight + (pc_checkskill(sd, GN_REMODELING_CART)*5000);
+
+ if (pc_checkskill(sd,SM_MOVINGRECOVERY)>0)
+ sd->regen.state.walk = 1;
+ else
+ sd->regen.state.walk = 0;
+
+ // Skill SP cost
+ if((skill=pc_checkskill(sd,HP_MANARECHARGE))>0 )
+ sd->dsprate -= 4*skill;
+
+ if(sc->data[SC_SERVICE4U])
+ sd->dsprate -= sc->data[SC_SERVICE4U]->val3;
+
+ if(sc->data[SC_SPCOST_RATE])
+ sd->dsprate -= sc->data[SC_SPCOST_RATE]->val1;
+
+ //Underflow protections.
+ if(sd->dsprate < 0)
+ sd->dsprate = 0;
+ if(sd->castrate < 0)
+ sd->castrate = 0;
+ if(sd->delayrate < 0)
+ sd->delayrate = 0;
+ if(sd->hprecov_rate < 0)
+ sd->hprecov_rate = 0;
+ if(sd->sprecov_rate < 0)
+ sd->sprecov_rate = 0;
+
+ // Anti-element and anti-race
+ if((skill=pc_checkskill(sd,CR_TRUST))>0)
+ sd->subele[ELE_HOLY] += skill*5;
+ if((skill=pc_checkskill(sd,BS_SKINTEMPER))>0) {
+ sd->subele[ELE_NEUTRAL] += skill;
+ sd->subele[ELE_FIRE] += skill*4;
+ }
+ if((skill=pc_checkskill(sd,SA_DRAGONOLOGY))>0 ){
+ skill = skill*4;
+ sd->right_weapon.addrace[RC_DRAGON]+=skill;
+ sd->left_weapon.addrace[RC_DRAGON]+=skill;
+ sd->magic_addrace[RC_DRAGON]+=skill;
+ sd->subrace[RC_DRAGON]+=skill;
+ }
+
+ if(sc->count){
+ if(sc->data[SC_CONCENTRATE]) { //Update the card-bonus data
+ sc->data[SC_CONCENTRATE]->val3 = sd->param_bonus[1]; //Agi
+ sc->data[SC_CONCENTRATE]->val4 = sd->param_bonus[4]; //Dex
+ }
+ if(sc->data[SC_SIEGFRIED]){
+ i = sc->data[SC_SIEGFRIED]->val2;
+ sd->subele[ELE_WATER] += i;
+ sd->subele[ELE_EARTH] += i;
+ sd->subele[ELE_FIRE] += i;
+ sd->subele[ELE_WIND] += i;
+ sd->subele[ELE_POISON] += i;
+ sd->subele[ELE_HOLY] += i;
+ sd->subele[ELE_DARK] += i;
+ sd->subele[ELE_GHOST] += i;
+ sd->subele[ELE_UNDEAD] += i;
+ }
+ if(sc->data[SC_PROVIDENCE]){
+ sd->subele[ELE_HOLY] += sc->data[SC_PROVIDENCE]->val2;
+ sd->subrace[RC_DEMON] += sc->data[SC_PROVIDENCE]->val2;
+ }
+ if(sc->data[SC_ARMOR_ELEMENT]) { //This status change should grant card-type elemental resist.
+ sd->subele[ELE_WATER] += sc->data[SC_ARMOR_ELEMENT]->val1;
+ sd->subele[ELE_EARTH] += sc->data[SC_ARMOR_ELEMENT]->val2;
+ sd->subele[ELE_FIRE] += sc->data[SC_ARMOR_ELEMENT]->val3;
+ sd->subele[ELE_WIND] += sc->data[SC_ARMOR_ELEMENT]->val4;
+ }
+ if(sc->data[SC_ARMOR_RESIST]) { // Undead Scroll
+ sd->subele[ELE_WATER] += sc->data[SC_ARMOR_RESIST]->val1;
+ sd->subele[ELE_EARTH] += sc->data[SC_ARMOR_RESIST]->val2;
+ sd->subele[ELE_FIRE] += sc->data[SC_ARMOR_RESIST]->val3;
+ sd->subele[ELE_WIND] += sc->data[SC_ARMOR_RESIST]->val4;
+ }
+ if( sc->data[SC_FIRE_CLOAK_OPTION] ) {
+ i = sc->data[SC_FIRE_CLOAK_OPTION]->val2;
+ sd->subele[ELE_FIRE] += i;
+ sd->subele[ELE_EARTH] -= i;
+ }
+ if( sc->data[SC_WATER_DROP_OPTION] ) {
+ i = sc->data[SC_WATER_DROP_OPTION]->val2;
+ sd->subele[ELE_WATER] += i;
+ sd->subele[ELE_WIND] -= i;
+ }
+ if( sc->data[SC_WIND_CURTAIN_OPTION] ) {
+ i = sc->data[SC_WIND_CURTAIN_OPTION]->val2;
+ sd->subele[ELE_WIND] += i;
+ sd->subele[ELE_WATER] -= i;
+ }
+ if( sc->data[SC_STONE_SHIELD_OPTION] ) {
+ i = sc->data[SC_STONE_SHIELD_OPTION]->val2;
+ sd->subele[ELE_EARTH] += i;
+ sd->subele[ELE_FIRE] -= i;
+ }
+ if( sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 3 )
+ sd->magic_addele[ELE_FIRE] += 25;
+ if( sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 3 )
+ sd->magic_addele[ELE_WATER] += 25;
+ if( sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 3 )
+ sd->magic_addele[ELE_WIND] += 25;
+ if( sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 3 )
+ sd->magic_addele[ELE_EARTH] += 25;
+ }
+ status_cpy(&sd->battle_status, status);
+
+// ----- CLIENT-SIDE REFRESH -----
+ if(!sd->bl.prev) {
+ //Will update on LoadEndAck
+ calculating = 0;
+ return 0;
+ }
+ if(memcmp(b_skill,sd->status.skill,sizeof(sd->status.skill)))
+ clif_skillinfoblock(sd);
+ if(b_weight != sd->weight)
+ clif_updatestatus(sd,SP_WEIGHT);
+ if(b_max_weight != sd->max_weight) {
+ clif_updatestatus(sd,SP_MAXWEIGHT);
+ pc_updateweightstatus(sd);
+ }
+ if( b_cart_weight_max != sd->cart_weight_max ) {
+ clif_updatestatus(sd,SP_CARTINFO);
+ }
+
+ calculating = 0;
+
+ return 0;
}
int status_calc_mercenary_(struct mercenary_data *md, bool first)
{
- struct status_data *status = &md->base_status;
- struct s_mercenary *merc = &md->mercenary;
-
- if (first) {
- memcpy(status, &md->db->status, sizeof(struct status_data));
- status->mode = MD_CANMOVE|MD_CANATTACK;
- status->hp = status->max_hp;
- status->sp = status->max_sp;
- md->battle_status.hp = merc->hp;
- md->battle_status.sp = merc->sp;
- }
-
- status_calc_misc(&md->bl, status, md->db->lv);
- status_cpy(&md->battle_status, status);
-
- return 0;
+ struct status_data *status = &md->base_status;
+ struct s_mercenary *merc = &md->mercenary;
+
+ if( first )
+ {
+ memcpy(status, &md->db->status, sizeof(struct status_data));
+ status->mode = MD_CANMOVE|MD_CANATTACK;
+ status->hp = status->max_hp;
+ status->sp = status->max_sp;
+ md->battle_status.hp = merc->hp;
+ md->battle_status.sp = merc->sp;
+ }
+
+ status_calc_misc(&md->bl, status, md->db->lv);
+ status_cpy(&md->battle_status, status);
+
+ return 0;
}
int status_calc_homunculus_(struct homun_data *hd, bool first)
{
- struct status_data *status = &hd->base_status;
- struct s_homunculus *hom = &hd->homunculus;
- int skill;
- int amotion;
-
- status->str = hom->str / 10;
- status->agi = hom->agi / 10;
- status->vit = hom->vit / 10;
- status->dex = hom->dex / 10;
- status->int_ = hom->int_ / 10;
- status->luk = hom->luk / 10;
-
- if (first) { //[orn]
- const struct s_homunculus_db *db = hd->homunculusDB;
- status->def_ele = db->element;
- status->ele_lv = 1;
- status->race = db->race;
- status->size = (hom->class_ == db->evo_class)?db->evo_size:db->base_size;
- status->rhw.range = 1 + status->size;
- status->mode = MD_CANMOVE|MD_CANATTACK;
- status->speed = DEFAULT_WALK_SPEED;
- if (battle_config.hom_setting&0x8 && hd->master)
- status->speed = status_get_speed(&hd->master->bl);
-
- status->hp = 1;
- status->sp = 1;
- }
- skill = hom->level/10 + status->vit/5;
- status->def = cap_value(skill, 0, 99);
-
- skill = hom->level/10 + status->int_/5;
- status->mdef = cap_value(skill, 0, 99);
-
- status->max_hp = hom->max_hp ;
- status->max_sp = hom->max_sp ;
-
- merc_hom_calc_skilltree(hd, 0);
-
- if ((skill=merc_hom_checkskill(hd,HAMI_SKIN)) > 0)
- status->def += skill * 4;
-
- if ((skill = merc_hom_checkskill(hd,HVAN_INSTRUCT)) > 0) {
- status->int_ += 1 +skill/2 +skill/4 +skill/5;
- status->str += 1 +skill/3 +skill/3 +skill/4;
- }
-
- if ((skill=merc_hom_checkskill(hd,HAMI_SKIN)) > 0)
- status->max_hp += skill * 2 * status->max_hp / 100;
-
- if ((skill = merc_hom_checkskill(hd,HLIF_BRAIN)) > 0)
- status->max_sp += (1 +skill/2 -skill/4 +skill/5) * status->max_sp / 100 ;
-
- if (first) {
- hd->battle_status.hp = hom->hp ;
- hd->battle_status.sp = hom->sp ;
- }
-
- status->rhw.atk = status->dex;
- status->rhw.atk2 = status->str + hom->level;
-
- status->aspd_rate = 1000;
-
- amotion = (1000 -4*status->agi -status->dex) * hd->homunculusDB->baseASPD/1000;
- status->amotion = cap_value(amotion,battle_config.max_aspd,2000);
- status->adelay = status->amotion; //It seems adelay = amotion for Homunculus.
-
- status_calc_misc(&hd->bl, status, hom->level);
+ struct status_data *status = &hd->base_status;
+ struct s_homunculus *hom = &hd->homunculus;
+ int skill;
+ int amotion;
+
+ status->str = hom->str / 10;
+ status->agi = hom->agi / 10;
+ status->vit = hom->vit / 10;
+ status->dex = hom->dex / 10;
+ status->int_ = hom->int_ / 10;
+ status->luk = hom->luk / 10;
+
+ if (first) { //[orn]
+ const struct s_homunculus_db *db = hd->homunculusDB;
+ status->def_ele = db->element;
+ status->ele_lv = 1;
+ status->race = db->race;
+ status->size = (hom->class_ == db->evo_class)?db->evo_size:db->base_size;
+ status->rhw.range = 1 + status->size;
+ status->mode = MD_CANMOVE|MD_CANATTACK;
+ status->speed = DEFAULT_WALK_SPEED;
+ if (battle_config.hom_setting&0x8 && hd->master)
+ status->speed = status_get_speed(&hd->master->bl);
+
+ status->hp = 1;
+ status->sp = 1;
+ }
+ skill = hom->level/10 + status->vit/5;
+ status->def = cap_value(skill, 0, 99);
+
+ skill = hom->level/10 + status->int_/5;
+ status->mdef = cap_value(skill, 0, 99);
+
+ status->max_hp = hom->max_hp ;
+ status->max_sp = hom->max_sp ;
+
+ merc_hom_calc_skilltree(hd, 0);
+
+ if((skill=merc_hom_checkskill(hd,HAMI_SKIN)) > 0)
+ status->def += skill * 4;
+
+ if((skill = merc_hom_checkskill(hd,HVAN_INSTRUCT)) > 0)
+ {
+ status->int_ += 1 +skill/2 +skill/4 +skill/5;
+ status->str += 1 +skill/3 +skill/3 +skill/4;
+ }
+
+ if((skill=merc_hom_checkskill(hd,HAMI_SKIN)) > 0)
+ status->max_hp += skill * 2 * status->max_hp / 100;
+
+ if((skill = merc_hom_checkskill(hd,HLIF_BRAIN)) > 0)
+ status->max_sp += (1 +skill/2 -skill/4 +skill/5) * status->max_sp / 100 ;
+
+ if (first) {
+ hd->battle_status.hp = hom->hp ;
+ hd->battle_status.sp = hom->sp ;
+ }
+
+ status->rhw.atk = status->dex;
+ status->rhw.atk2 = status->str + hom->level;
+
+ status->aspd_rate = 1000;
+
+ amotion = (1000 -4*status->agi -status->dex) * hd->homunculusDB->baseASPD/1000;
+ status->amotion = cap_value(amotion,battle_config.max_aspd,2000);
+ status->adelay = status->amotion; //It seems adelay = amotion for Homunculus.
+
+ status_calc_misc(&hd->bl, status, hom->level);
#ifdef RENEWAL
- status->matk_max = status->matk_min;
+ status->matk_max = status->matk_min;
#endif
- status_cpy(&hd->battle_status, status);
- return 1;
+ status_cpy(&hd->battle_status, status);
+ return 1;
}
-int status_calc_elemental_(struct elemental_data *ed, bool first)
-{
- struct status_data *status = &ed->base_status;
- struct s_elemental *ele = &ed->elemental;
- struct map_session_data *sd = ed->master;
-
- if (!sd)
- return 0;
-
- status->str = ele->str;
- status->agi = ele->agi;
- status->vit = ele->vit;
- status->dex = ele->dex;
- status->int_ = ele->int_;
- status->luk = ele->luk;
-
- if (first) {
- memcpy(status, &ed->db->status, sizeof(struct status_data));
- status->mode = MD_CANMOVE|MD_CANATTACK;
- status->max_hp += 4000 + 500 * pc_checkskill(sd,SO_EL_SYMPATHY);
- status->max_sp += 300 + 50 * pc_checkskill(sd,SO_EL_SYMPATHY);
- status->hp = status->max_hp;
- status->sp = status->max_sp;
- status->str += sd->base_status.str * 25 / 100;
- status->agi += sd->base_status.agi * 25 / 100;
- status->vit += sd->base_status.vit * 25 / 100;
- status->int_ += sd->base_status.int_ * 25 / 100;
- status->def += sd->base_status.dex * 25 / 100;
- status->luk += sd->base_status.luk * 25 / 100;
-
- status_calc_misc(&ed->bl, status, ed->db->lv);
- memcpy(&ed->battle_status,status,sizeof(struct status_data));
- } else {
- status_calc_misc(&ed->bl, status, ed->db->lv);
- status_cpy(&ed->battle_status, status);
- }
-
- return 0;
+int status_calc_elemental_(struct elemental_data *ed, bool first) {
+ struct status_data *status = &ed->base_status;
+ struct s_elemental *ele = &ed->elemental;
+ struct map_session_data *sd = ed->master;
+
+ if( !sd )
+ return 0;
+
+ status->str = ele->str;
+ status->agi = ele->agi;
+ status->vit = ele->vit;
+ status->dex = ele->dex;
+ status->int_ = ele->int_;
+ status->luk = ele->luk;
+
+ if( first ) {
+ memcpy(status, &ed->db->status, sizeof(struct status_data));
+ status->mode = MD_CANMOVE|MD_CANATTACK;
+ status->max_hp += 4000 + 500 * pc_checkskill(sd,SO_EL_SYMPATHY);
+ status->max_sp += 300 + 50 * pc_checkskill(sd,SO_EL_SYMPATHY);
+ status->hp = status->max_hp;
+ status->sp = status->max_sp;
+ status->str += sd->base_status.str * 25 / 100;
+ status->agi += sd->base_status.agi * 25 / 100;
+ status->vit += sd->base_status.vit * 25 / 100;
+ status->int_ += sd->base_status.int_ * 25 / 100;
+ status->def += sd->base_status.dex * 25 / 100;
+ status->luk += sd->base_status.luk * 25 / 100;
+
+ status_calc_misc(&ed->bl, status, ed->db->lv);
+ memcpy(&ed->battle_status,status,sizeof(struct status_data));
+ } else {
+ status_calc_misc(&ed->bl, status, ed->db->lv);
+ status_cpy(&ed->battle_status, status);
+ }
+
+ return 0;
}
static unsigned short status_calc_str(struct block_list *,struct status_change *,int);
@@ -3296,793 +3287,786 @@ static unsigned int status_calc_maxsp(struct block_list *,struct status_change *
static unsigned char status_calc_element(struct block_list *bl, struct status_change *sc, int element);
static unsigned char status_calc_element_lv(struct block_list *bl, struct status_change *sc, int lv);
static unsigned short status_calc_mode(struct block_list *bl, struct status_change *sc, int mode);
-#ifdef RENEWAL
-static unsigned short status_calc_ematk(struct block_list *,struct status_change *,int);
-#endif
//Calculates base regen values.
void status_calc_regen(struct block_list *bl, struct status_data *status, struct regen_data *regen)
{
- struct map_session_data *sd;
- int val, skill;
+ struct map_session_data *sd;
+ int val, skill;
- if (!(bl->type&BL_REGEN) || !regen)
- return;
+ if( !(bl->type&BL_REGEN) || !regen )
+ return;
- sd = BL_CAST(BL_PC,bl);
- val = 1 + (status->vit/5) + (status->max_hp/200);
+ sd = BL_CAST(BL_PC,bl);
+ val = 1 + (status->vit/5) + (status->max_hp/200);
- if (sd && sd->hprecov_rate != 100)
- val = val*sd->hprecov_rate/100;
+ if( sd && sd->hprecov_rate != 100 )
+ val = val*sd->hprecov_rate/100;
- regen->hp = cap_value(val, 1, SHRT_MAX);
+ regen->hp = cap_value(val, 1, SHRT_MAX);
- val = 1 + (status->int_/6) + (status->max_sp/100);
- if (status->int_ >= 120)
- val += ((status->int_-120)>>1) + 4;
+ val = 1 + (status->int_/6) + (status->max_sp/100);
+ if( status->int_ >= 120 )
+ val += ((status->int_-120)>>1) + 4;
- if (sd && sd->sprecov_rate != 100)
- val = val*sd->sprecov_rate/100;
+ if( sd && sd->sprecov_rate != 100 )
+ val = val*sd->sprecov_rate/100;
- regen->sp = cap_value(val, 1, SHRT_MAX);
+ regen->sp = cap_value(val, 1, SHRT_MAX);
- if (sd) {
- struct regen_data_sub *sregen;
- if ((skill=pc_checkskill(sd,HP_MEDITATIO)) > 0) {
- val = regen->sp*(100+3*skill)/100;
- regen->sp = cap_value(val, 1, SHRT_MAX);
- }
- //Only players have skill/sitting skill regen for now.
- sregen = regen->sregen;
-
- val = 0;
- if ((skill=pc_checkskill(sd,SM_RECOVERY)) > 0)
- val += skill*5 + skill*status->max_hp/500;
- sregen->hp = cap_value(val, 0, SHRT_MAX);
-
- val = 0;
- if ((skill=pc_checkskill(sd,MG_SRECOVERY)) > 0)
- val += skill*3 + skill*status->max_sp/500;
- if ((skill=pc_checkskill(sd,NJ_NINPOU)) > 0)
- val += skill*3 + skill*status->max_sp/500;
- if ((skill=pc_checkskill(sd,WM_LESSON)) > 0)
- val += 3 + 3 * skill;
-
- sregen->sp = cap_value(val, 0, SHRT_MAX);
-
- // Skill-related recovery (only when sit)
- sregen = regen->ssregen;
-
- val = 0;
- if ((skill=pc_checkskill(sd,MO_SPIRITSRECOVERY)) > 0)
- val += skill*4 + skill*status->max_hp/500;
-
- if ((skill=pc_checkskill(sd,TK_HPTIME)) > 0 && sd->state.rest)
- val += skill*30 + skill*status->max_hp/500;
- sregen->hp = cap_value(val, 0, SHRT_MAX);
-
- val = 0;
- if ((skill=pc_checkskill(sd,TK_SPTIME)) > 0 && sd->state.rest) {
- val += skill*3 + skill*status->max_sp/500;
- if ((skill=pc_checkskill(sd,SL_KAINA)) > 0) //Power up Enjoyable Rest
- val += (30+10*skill)*val/100;
- }
- if ((skill=pc_checkskill(sd,MO_SPIRITSRECOVERY)) > 0)
- val += skill*2 + skill*status->max_sp/500;
- sregen->sp = cap_value(val, 0, SHRT_MAX);
- }
-
- if (bl->type == BL_HOM) {
- struct homun_data *hd = (TBL_HOM *)bl;
- if ((skill = merc_hom_checkskill(hd,HAMI_SKIN)) > 0) {
- val = regen->hp*(100+5*skill)/100;
- regen->hp = cap_value(val, 1, SHRT_MAX);
- }
- if ((skill = merc_hom_checkskill(hd,HLIF_BRAIN)) > 0) {
- val = regen->sp*(100+3*skill)/100;
- regen->sp = cap_value(val, 1, SHRT_MAX);
- }
- } else if (bl->type == BL_MER) {
- val = (status->max_hp * status->vit / 10000 + 1) * 6;
- regen->hp = cap_value(val, 1, SHRT_MAX);
-
- val = (status->max_sp * (status->int_ + 10) / 750) + 1;
- regen->sp = cap_value(val, 1, SHRT_MAX);
- } else if (bl->type == BL_ELEM) {
- val = (status->max_hp * status->vit / 10000 + 1) * 6;
- regen->hp = cap_value(val, 1, SHRT_MAX);
-
- val = (status->max_sp * (status->int_ + 10) / 750) + 1;
- regen->sp = cap_value(val, 1, SHRT_MAX);
- }
+ if( sd )
+ {
+ struct regen_data_sub *sregen;
+ if( (skill=pc_checkskill(sd,HP_MEDITATIO)) > 0 )
+ {
+ val = regen->sp*(100+3*skill)/100;
+ regen->sp = cap_value(val, 1, SHRT_MAX);
+ }
+ //Only players have skill/sitting skill regen for now.
+ sregen = regen->sregen;
+
+ val = 0;
+ if( (skill=pc_checkskill(sd,SM_RECOVERY)) > 0 )
+ val += skill*5 + skill*status->max_hp/500;
+ sregen->hp = cap_value(val, 0, SHRT_MAX);
+
+ val = 0;
+ if( (skill=pc_checkskill(sd,MG_SRECOVERY)) > 0 )
+ val += skill*3 + skill*status->max_sp/500;
+ if( (skill=pc_checkskill(sd,NJ_NINPOU)) > 0 )
+ val += skill*3 + skill*status->max_sp/500;
+ if( (skill=pc_checkskill(sd,WM_LESSON)) > 0 )
+ val += 3 + 3 * skill;
+
+ sregen->sp = cap_value(val, 0, SHRT_MAX);
+
+ // Skill-related recovery (only when sit)
+ sregen = regen->ssregen;
+
+ val = 0;
+ if( (skill=pc_checkskill(sd,MO_SPIRITSRECOVERY)) > 0 )
+ val += skill*4 + skill*status->max_hp/500;
+
+ if( (skill=pc_checkskill(sd,TK_HPTIME)) > 0 && sd->state.rest )
+ val += skill*30 + skill*status->max_hp/500;
+ sregen->hp = cap_value(val, 0, SHRT_MAX);
+
+ val = 0;
+ if( (skill=pc_checkskill(sd,TK_SPTIME)) > 0 && sd->state.rest )
+ {
+ val += skill*3 + skill*status->max_sp/500;
+ if ((skill=pc_checkskill(sd,SL_KAINA)) > 0) //Power up Enjoyable Rest
+ val += (30+10*skill)*val/100;
+ }
+ if( (skill=pc_checkskill(sd,MO_SPIRITSRECOVERY)) > 0 )
+ val += skill*2 + skill*status->max_sp/500;
+ sregen->sp = cap_value(val, 0, SHRT_MAX);
+ }
+
+ if( bl->type == BL_HOM ) {
+ struct homun_data *hd = (TBL_HOM*)bl;
+ if( (skill = merc_hom_checkskill(hd,HAMI_SKIN)) > 0 ) {
+ val = regen->hp*(100+5*skill)/100;
+ regen->hp = cap_value(val, 1, SHRT_MAX);
+ }
+ if( (skill = merc_hom_checkskill(hd,HLIF_BRAIN)) > 0 ) {
+ val = regen->sp*(100+3*skill)/100;
+ regen->sp = cap_value(val, 1, SHRT_MAX);
+ }
+ } else if( bl->type == BL_MER ) {
+ val = (status->max_hp * status->vit / 10000 + 1) * 6;
+ regen->hp = cap_value(val, 1, SHRT_MAX);
+
+ val = (status->max_sp * (status->int_ + 10) / 750) + 1;
+ regen->sp = cap_value(val, 1, SHRT_MAX);
+ } else if( bl->type == BL_ELEM ) {
+ val = (status->max_hp * status->vit / 10000 + 1) * 6;
+ regen->hp = cap_value(val, 1, SHRT_MAX);
+
+ val = (status->max_sp * (status->int_ + 10) / 750) + 1;
+ regen->sp = cap_value(val, 1, SHRT_MAX);
+ }
}
//Calculates SC related regen rates.
void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, struct status_change *sc)
{
- if (!(bl->type&BL_REGEN) || !regen)
- return;
-
- regen->flag = RGN_HP|RGN_SP;
- if (regen->sregen) {
- if (regen->sregen->hp)
- regen->flag|=RGN_SHP;
-
- if (regen->sregen->sp)
- regen->flag|=RGN_SSP;
- regen->sregen->rate.hp = regen->sregen->rate.sp = 1;
- }
- if (regen->ssregen) {
- if (regen->ssregen->hp)
- regen->flag|=RGN_SHP;
-
- if (regen->ssregen->sp)
- regen->flag|=RGN_SSP;
- regen->ssregen->rate.hp = regen->ssregen->rate.sp = 1;
- }
- regen->rate.hp = regen->rate.sp = 1;
-
- if (!sc || !sc->count)
- return;
-
- if (
- (sc->data[SC_POISON] && !sc->data[SC_SLOWPOISON])
- || (sc->data[SC_DPOISON] && !sc->data[SC_SLOWPOISON])
- || sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]
- || sc->data[SC_TRICKDEAD]
- || sc->data[SC_BLEEDING]
- || sc->data[SC_MAGICMUSHROOM]
- || sc->data[SC_RAISINGDRAGON]
- || sc->data[SC_SATURDAYNIGHTFEVER]
- ) //No regen
- regen->flag = 0;
-
- if (
- sc->data[SC_DANCING] || sc->data[SC_OBLIVIONCURSE] || sc->data[SC_MAXIMIZEPOWER]
- || (
- (bl->type == BL_PC && ((TBL_PC *)bl)->class_&MAPID_UPPERMASK) == MAPID_MONK &&
- (sc->data[SC_EXTREMITYFIST] || (sc->data[SC_EXPLOSIONSPIRITS] && (!sc->data[SC_SPIRIT] || sc->data[SC_SPIRIT]->val2 != SL_MONK)))
- )
- ) //No natural SP regen
- regen->flag &=~RGN_SP;
-
- if (
- sc->data[SC_TENSIONRELAX]
- ) {
- regen->rate.hp += 2;
- if (regen->sregen)
- regen->sregen->rate.hp += 3;
- }
- if (sc->data[SC_MAGNIFICAT]) {
- regen->rate.hp += 1;
- regen->rate.sp += 1;
- }
- if (sc->data[SC_REGENERATION]) {
- const struct status_change_entry *sce = sc->data[SC_REGENERATION];
- if (!sce->val4) {
- regen->rate.hp += sce->val2;
- regen->rate.sp += sce->val3;
- } else
- regen->flag&=~sce->val4; //Remove regen as specified by val4
- }
- if (sc->data[SC_GT_REVITALIZE]) {
- regen->hp = cap_value(regen->hp*sc->data[SC_GT_REVITALIZE]->val3/100, 1, SHRT_MAX);
- regen->state.walk= 1;
- }
- if ((sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 1) //if insignia lvl 1
- || (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 1)
- || (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 1)
- || (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 1))
- regen->rate.hp *= 2;
+ if (!(bl->type&BL_REGEN) || !regen)
+ return;
+
+ regen->flag = RGN_HP|RGN_SP;
+ if(regen->sregen)
+ {
+ if (regen->sregen->hp)
+ regen->flag|=RGN_SHP;
+
+ if (regen->sregen->sp)
+ regen->flag|=RGN_SSP;
+ regen->sregen->rate.hp = regen->sregen->rate.sp = 1;
+ }
+ if (regen->ssregen)
+ {
+ if (regen->ssregen->hp)
+ regen->flag|=RGN_SHP;
+
+ if (regen->ssregen->sp)
+ regen->flag|=RGN_SSP;
+ regen->ssregen->rate.hp = regen->ssregen->rate.sp = 1;
+ }
+ regen->rate.hp = regen->rate.sp = 1;
+
+ if (!sc || !sc->count)
+ return;
+
+ if (
+ (sc->data[SC_POISON] && !sc->data[SC_SLOWPOISON])
+ || (sc->data[SC_DPOISON] && !sc->data[SC_SLOWPOISON])
+ || sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]
+ || sc->data[SC_TRICKDEAD]
+ || sc->data[SC_BLEEDING]
+ || sc->data[SC_MAGICMUSHROOM]
+ || sc->data[SC_RAISINGDRAGON]
+ || sc->data[SC_SATURDAYNIGHTFEVER]
+ ) //No regen
+ regen->flag = 0;
+
+ if (
+ sc->data[SC_DANCING] || sc->data[SC_OBLIVIONCURSE] || sc->data[SC_MAXIMIZEPOWER]
+ || (
+ (bl->type == BL_PC && ((TBL_PC*)bl)->class_&MAPID_UPPERMASK) == MAPID_MONK &&
+ (sc->data[SC_EXTREMITYFIST] || (sc->data[SC_EXPLOSIONSPIRITS] && (!sc->data[SC_SPIRIT] || sc->data[SC_SPIRIT]->val2 != SL_MONK)))
+ )
+ ) //No natural SP regen
+ regen->flag &=~RGN_SP;
+
+ if(
+ sc->data[SC_TENSIONRELAX]
+ ) {
+ regen->rate.hp += 2;
+ if (regen->sregen)
+ regen->sregen->rate.hp += 3;
+ }
+ if (sc->data[SC_MAGNIFICAT])
+ {
+ regen->rate.hp += 1;
+ regen->rate.sp += 1;
+ }
+ if (sc->data[SC_REGENERATION])
+ {
+ const struct status_change_entry *sce = sc->data[SC_REGENERATION];
+ if (!sce->val4)
+ {
+ regen->rate.hp += sce->val2;
+ regen->rate.sp += sce->val3;
+ } else
+ regen->flag&=~sce->val4; //Remove regen as specified by val4
+ }
+ if(sc->data[SC_GT_REVITALIZE]){
+ regen->hp = cap_value(regen->hp*sc->data[SC_GT_REVITALIZE]->val3/100, 1, SHRT_MAX);
+ regen->state.walk= 1;
+ }
+ if ((sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 1) //if insignia lvl 1
+ || (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 1)
+ || (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 1)
+ || (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 1))
+ regen->rate.hp *= 2;
}
-void status_calc_state(struct block_list *bl, struct status_change *sc, enum scs_flag flag, bool start)
-{
-
- /* no sc at all, we can zero without any extra weight over our conciousness */
- if (!sc->count) {
- memset(&sc->cant, 0, sizeof(sc->cant));
- return;
- }
-
- /* can move? */
- if (flag&SCS_NOMOVE) {
- if (!(flag&SCS_NOMOVECOND)) {
- sc->cant.move += (start ? 1 : -1);
- } else if (
- (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF) // cannot move while gospel is in effect
- || (sc->data[SC_BASILICA] && sc->data[SC_BASILICA]->val4 == bl->id) // Basilica caster cannot move
- || (sc->data[SC_GRAVITATION] && sc->data[SC_GRAVITATION]->val3 == BCT_SELF)
- || (sc->data[SC_CRYSTALIZE] && bl->type != BL_MOB)
- || (sc->data[SC_CAMOUFLAGE] && sc->data[SC_CAMOUFLAGE]->val1 < 3
- && !(sc->data[SC_CAMOUFLAGE]->val3&1))
- ) {
- sc->cant.move += (start ? 1 : -1);
- }
- }
-
- /* can't use skills */
- if (flag&SCS_NOCAST) {
- if (!(flag&SCS_NOCASTCOND)) {
- sc->cant.cast += (start ? 1 : -1);
- } else if ((sc->data[SC_CRYSTALIZE] && bl->type != BL_MOB)) {
- sc->cant.cast += (start ? 1 : -1);
- }
- }
+void status_calc_state( struct block_list *bl, struct status_change *sc, enum scs_flag flag, bool start ) {
+
+ /* no sc at all, we can zero without any extra weight over our conciousness */
+ if( !sc->count ) {
+ memset(&sc->cant, 0, sizeof (sc->cant));
+ return;
+ }
+
+ /* can move? */
+ if( flag&SCS_NOMOVE ) {
+ if( !(flag&SCS_NOMOVECOND) ) {
+ sc->cant.move += ( start ? 1 : -1 );
+ } else if(
+ (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF) // cannot move while gospel is in effect
+ || (sc->data[SC_BASILICA] && sc->data[SC_BASILICA]->val4 == bl->id) // Basilica caster cannot move
+ || (sc->data[SC_GRAVITATION] && sc->data[SC_GRAVITATION]->val3 == BCT_SELF)
+ || (sc->data[SC_CRYSTALIZE] && bl->type != BL_MOB)
+ || (sc->data[SC_CAMOUFLAGE] && sc->data[SC_CAMOUFLAGE]->val1 < 3
+ && !(sc->data[SC_CAMOUFLAGE]->val3&1))
+ ) {
+ sc->cant.move += ( start ? 1 : -1 );
+ }
+ }
+
+ /* can't use skills */
+ if( flag&SCS_NOCAST ) {
+ if( !(flag&SCS_NOCASTCOND) ) {
+ sc->cant.cast += ( start ? 1 : -1 );
+ } else if( (sc->data[SC_CRYSTALIZE] && bl->type != BL_MOB) ){
+ sc->cant.cast += ( start ? 1 : -1 );
+ }
+ }
- /* player-only states */
- if (bl->type == BL_PC) {
+ /* player-only states */
+ if( bl->type == BL_PC ) {
- /* can pick items? */
- if (flag&SCS_NOPICKITEM) {
- if (!(flag&SCS_NOPICKITEMCOND)) {
- sc->cant.pickup += (start ? 1 : -1);
- } else if ((sc->data[SC_NOCHAT] && sc->data[SC_NOCHAT]->val1&MANNER_NOITEM)) {
- sc->cant.pickup += (start ? 1 : -1);
- }
- }
+ /* can pick items? */
+ if( flag&SCS_NOPICKITEM ) {
+ if( !(flag&SCS_NOPICKITEMCOND) ) {
+ sc->cant.pickup += ( start ? 1 : -1 );
+ } else if( (sc->data[SC_NOCHAT] && sc->data[SC_NOCHAT]->val1&MANNER_NOITEM) ) {
+ sc->cant.pickup += ( start ? 1 : -1 );
+ }
+ }
- /* can drop items? */
- if (flag&SCS_NODROPITEM) {
- if (!(flag&SCS_NODROPITEMCOND)) {
- sc->cant.drop += (start ? 1 : -1);
- } else if ((sc->data[SC_NOCHAT] && sc->data[SC_NOCHAT]->val1&MANNER_NOITEM)) {
- sc->cant.drop += (start ? 1 : -1);
- }
- }
- }
+ /* can drop items? */
+ if( flag&SCS_NODROPITEM ) {
+ if( !(flag&SCS_NODROPITEMCOND) ) {
+ sc->cant.drop += ( start ? 1 : -1 );
+ } else if( (sc->data[SC_NOCHAT] && sc->data[SC_NOCHAT]->val1&MANNER_NOITEM) ) {
+ sc->cant.drop += ( start ? 1 : -1 );
+ }
+ }
+ }
- return;
+ return;
}
/// Recalculates parts of an object's battle status according to the specified flags.
/// @param flag bitfield of values from enum scb_flag
void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
{
- const struct status_data *b_status = status_get_base_status(bl);
- struct status_data *status = status_get_status_data(bl);
- struct status_change *sc = status_get_sc(bl);
- TBL_PC *sd = BL_CAST(BL_PC,bl);
- int temp;
-
- if (!b_status || !status)
- return;
-
- if ((!(bl->type&BL_REGEN)) && (!sc || !sc->count)) { //No difference.
- status_cpy(status, b_status);
- return;
- }
-
- if (flag&SCB_STR) {
- status->str = status_calc_str(bl, sc, b_status->str);
- flag|=SCB_BATK;
- if (bl->type&BL_HOM)
- flag |= SCB_WATK;
- }
-
- if (flag&SCB_AGI) {
- status->agi = status_calc_agi(bl, sc, b_status->agi);
- flag|=SCB_FLEE;
- if (bl->type&(BL_PC|BL_HOM))
- flag |= SCB_ASPD|SCB_DSPD;
- }
-
- if (flag&SCB_VIT) {
- status->vit = status_calc_vit(bl, sc, b_status->vit);
- flag|=SCB_DEF2|SCB_MDEF2;
- if (bl->type&(BL_PC|BL_HOM|BL_MER|BL_ELEM))
- flag |= SCB_MAXHP;
- if (bl->type&BL_HOM)
- flag |= SCB_DEF;
- }
-
- if (flag&SCB_INT) {
- status->int_ = status_calc_int(bl, sc, b_status->int_);
- flag|=SCB_MATK|SCB_MDEF2;
- if (bl->type&(BL_PC|BL_HOM|BL_MER|BL_ELEM))
- flag |= SCB_MAXSP;
- if (bl->type&BL_HOM)
- flag |= SCB_MDEF;
- }
-
- if (flag&SCB_DEX) {
- status->dex = status_calc_dex(bl, sc, b_status->dex);
- flag|=SCB_BATK|SCB_HIT;
- if (bl->type&(BL_PC|BL_HOM))
- flag |= SCB_ASPD;
- if (bl->type&BL_HOM)
- flag |= SCB_WATK;
- }
-
- if (flag&SCB_LUK) {
- status->luk = status_calc_luk(bl, sc, b_status->luk);
- flag|=SCB_BATK|SCB_CRI|SCB_FLEE2;
- }
-
- if (flag&SCB_BATK && b_status->batk) {
- status->batk = status_base_atk(bl,status);
- temp = b_status->batk - status_base_atk(bl,b_status);
- if (temp) {
- temp += status->batk;
- status->batk = cap_value(temp, 0, USHRT_MAX);
- }
- status->batk = status_calc_batk(bl, sc, status->batk);
- }
-
- if (flag&SCB_WATK) {
-
- status->rhw.atk = status_calc_watk(bl, sc, b_status->rhw.atk);
- if (!sd) //Should not affect weapon refine bonus
- status->rhw.atk2 = status_calc_watk(bl, sc, b_status->rhw.atk2);
-
- if (b_status->lhw.atk) {
- if (sd) {
- sd->state.lr_flag = 1;
- status->lhw.atk = status_calc_watk(bl, sc, b_status->lhw.atk);
- sd->state.lr_flag = 0;
- } else {
- status->lhw.atk = status_calc_watk(bl, sc, b_status->lhw.atk);
- status->lhw.atk2= status_calc_watk(bl, sc, b_status->lhw.atk2);
- }
- }
-
- if (bl->type&BL_HOM) {
- status->rhw.atk += (status->dex - b_status->dex);
- status->rhw.atk2 += (status->str - b_status->str);
- if (status->rhw.atk2 < status->rhw.atk)
- status->rhw.atk2 = status->rhw.atk;
- }
- }
-
- if (flag&SCB_HIT) {
- if (status->dex == b_status->dex)
- status->hit = status_calc_hit(bl, sc, b_status->hit);
- else
- status->hit = status_calc_hit(bl, sc, b_status->hit +(status->dex - b_status->dex));
- }
-
- if (flag&SCB_FLEE) {
- if (status->agi == b_status->agi)
- status->flee = status_calc_flee(bl, sc, b_status->flee);
- else
- status->flee = status_calc_flee(bl, sc, b_status->flee +(status->agi - b_status->agi));
- }
-
- if (flag&SCB_DEF) {
- status->def = status_calc_def(bl, sc, b_status->def);
-
- if (bl->type&BL_HOM)
- status->def += (status->vit/5 - b_status->vit/5);
- }
-
- if (flag&SCB_DEF2) {
- if (status->vit == b_status->vit)
- status->def2 = status_calc_def2(bl, sc, b_status->def2);
- else
- status->def2 = status_calc_def2(bl, sc, b_status->def2 + (status->vit - b_status->vit));
- }
-
- if (flag&SCB_MDEF) {
- status->mdef = status_calc_mdef(bl, sc, b_status->mdef);
-
- if (bl->type&BL_HOM)
- status->mdef += (status->int_/5 - b_status->int_/5);
- }
-
- if (flag&SCB_MDEF2) {
- if (status->int_ == b_status->int_ && status->vit == b_status->vit)
- status->mdef2 = status_calc_mdef2(bl, sc, b_status->mdef2);
- else
- status->mdef2 = status_calc_mdef2(bl, sc, b_status->mdef2 +(status->int_ - b_status->int_) +((status->vit - b_status->vit)>>1));
- }
-
- if (flag&SCB_SPEED) {
- struct unit_data *ud = unit_bl2ud(bl);
- status->speed = status_calc_speed(bl, sc, b_status->speed);
-
- //Re-walk to adjust speed (we do not check if walktimer != INVALID_TIMER
- //because if you step on something while walking, the moment this
- //piece of code triggers the walk-timer is set on INVALID_TIMER) [Skotlex]
- if (ud)
- ud->state.change_walk_target = ud->state.speed_changed = 1;
-
- if (bl->type&BL_PC && status->speed < battle_config.max_walk_speed)
- status->speed = battle_config.max_walk_speed;
-
- if (bl->type&BL_HOM && battle_config.hom_setting&0x8 && ((TBL_HOM *)bl)->master)
- status->speed = status_get_speed(&((TBL_HOM *)bl)->master->bl);
-
-
- }
-
- if (flag&SCB_CRI && b_status->cri) {
- if (status->luk == b_status->luk)
- status->cri = status_calc_critical(bl, sc, b_status->cri);
- else
- status->cri = status_calc_critical(bl, sc, b_status->cri + 3*(status->luk - b_status->luk));
- /**
- * after status_calc_critical so the bonus is applied despite if you have or not a sc bugreport:5240
- **/
- if (bl->type == BL_PC && ((TBL_PC *)bl)->status.weapon == W_KATAR)
- status->cri <<= 1;
-
- }
-
- if (flag&SCB_FLEE2 && b_status->flee2) {
- if (status->luk == b_status->luk)
- status->flee2 = status_calc_flee2(bl, sc, b_status->flee2);
- else
- status->flee2 = status_calc_flee2(bl, sc, b_status->flee2 +(status->luk - b_status->luk));
- }
-
- if (flag&SCB_ATK_ELE) {
- status->rhw.ele = status_calc_attack_element(bl, sc, b_status->rhw.ele);
- if (sd) sd->state.lr_flag = 1;
- status->lhw.ele = status_calc_attack_element(bl, sc, b_status->lhw.ele);
- if (sd) sd->state.lr_flag = 0;
- }
-
- if (flag&SCB_DEF_ELE) {
- status->def_ele = status_calc_element(bl, sc, b_status->def_ele);
- status->ele_lv = status_calc_element_lv(bl, sc, b_status->ele_lv);
- }
-
- if (flag&SCB_MODE) {
- status->mode = status_calc_mode(bl, sc, b_status->mode);
- //Since mode changed, reset their state.
- if (!(status->mode&MD_CANATTACK))
- unit_stop_attack(bl);
- if (!(status->mode&MD_CANMOVE))
- unit_stop_walking(bl,1);
- }
-
- // No status changes alter these yet.
- // if(flag&SCB_SIZE)
- // if(flag&SCB_RACE)
- // if(flag&SCB_RANGE)
-
- if (flag&SCB_MAXHP) {
- if (bl->type&BL_PC) {
- status->max_hp = status_base_pc_maxhp(sd,status);
- status->max_hp += b_status->max_hp - sd->status.max_hp;
-
- status->max_hp = status_calc_maxhp(bl, sc, status->max_hp);
+ const struct status_data *b_status = status_get_base_status(bl);
+ struct status_data *status = status_get_status_data(bl);
+ struct status_change *sc = status_get_sc(bl);
+ TBL_PC *sd = BL_CAST(BL_PC,bl);
+ int temp;
+
+ if (!b_status || !status)
+ return;
+
+ if((!(bl->type&BL_REGEN)) && (!sc || !sc->count)) { //No difference.
+ status_cpy(status, b_status);
+ return;
+ }
+
+ if(flag&SCB_STR) {
+ status->str = status_calc_str(bl, sc, b_status->str);
+ flag|=SCB_BATK;
+ if( bl->type&BL_HOM )
+ flag |= SCB_WATK;
+ }
+
+ if(flag&SCB_AGI) {
+ status->agi = status_calc_agi(bl, sc, b_status->agi);
+ flag|=SCB_FLEE;
+ if( bl->type&(BL_PC|BL_HOM) )
+ flag |= SCB_ASPD|SCB_DSPD;
+ }
+
+ if(flag&SCB_VIT) {
+ status->vit = status_calc_vit(bl, sc, b_status->vit);
+ flag|=SCB_DEF2|SCB_MDEF2;
+ if( bl->type&(BL_PC|BL_HOM|BL_MER|BL_ELEM) )
+ flag |= SCB_MAXHP;
+ if( bl->type&BL_HOM )
+ flag |= SCB_DEF;
+ }
+
+ if(flag&SCB_INT) {
+ status->int_ = status_calc_int(bl, sc, b_status->int_);
+ flag|=SCB_MATK|SCB_MDEF2;
+ if( bl->type&(BL_PC|BL_HOM|BL_MER|BL_ELEM) )
+ flag |= SCB_MAXSP;
+ if( bl->type&BL_HOM )
+ flag |= SCB_MDEF;
+ }
+
+ if(flag&SCB_DEX) {
+ status->dex = status_calc_dex(bl, sc, b_status->dex);
+ flag|=SCB_BATK|SCB_HIT;
+ if( bl->type&(BL_PC|BL_HOM) )
+ flag |= SCB_ASPD;
+ if( bl->type&BL_HOM )
+ flag |= SCB_WATK;
+ }
+
+ if(flag&SCB_LUK) {
+ status->luk = status_calc_luk(bl, sc, b_status->luk);
+ flag|=SCB_BATK|SCB_CRI|SCB_FLEE2;
+ }
+
+ if(flag&SCB_BATK && b_status->batk) {
+ status->batk = status_base_atk(bl,status);
+ temp = b_status->batk - status_base_atk(bl,b_status);
+ if (temp)
+ {
+ temp += status->batk;
+ status->batk = cap_value(temp, 0, USHRT_MAX);
+ }
+ status->batk = status_calc_batk(bl, sc, status->batk);
+ }
+
+ if(flag&SCB_WATK) {
+
+ status->rhw.atk = status_calc_watk(bl, sc, b_status->rhw.atk);
+ if (!sd) //Should not affect weapon refine bonus
+ status->rhw.atk2 = status_calc_watk(bl, sc, b_status->rhw.atk2);
+
+ if(b_status->lhw.atk) {
+ if (sd) {
+ sd->state.lr_flag = 1;
+ status->lhw.atk = status_calc_watk(bl, sc, b_status->lhw.atk);
+ sd->state.lr_flag = 0;
+ } else {
+ status->lhw.atk = status_calc_watk(bl, sc, b_status->lhw.atk);
+ status->lhw.atk2= status_calc_watk(bl, sc, b_status->lhw.atk2);
+ }
+ }
- if (status->max_hp > (unsigned int)battle_config.max_hp)
- status->max_hp = (unsigned int)battle_config.max_hp;
- } else {
- status->max_hp = status_calc_maxhp(bl, sc, b_status->max_hp);
- }
+ if( bl->type&BL_HOM )
+ {
+ status->rhw.atk += (status->dex - b_status->dex);
+ status->rhw.atk2 += (status->str - b_status->str);
+ if( status->rhw.atk2 < status->rhw.atk )
+ status->rhw.atk2 = status->rhw.atk;
+ }
+ }
+
+ if(flag&SCB_HIT) {
+ if (status->dex == b_status->dex)
+ status->hit = status_calc_hit(bl, sc, b_status->hit);
+ else
+ status->hit = status_calc_hit(bl, sc, b_status->hit +(status->dex - b_status->dex));
+ }
+
+ if(flag&SCB_FLEE) {
+ if (status->agi == b_status->agi)
+ status->flee = status_calc_flee(bl, sc, b_status->flee);
+ else
+ status->flee = status_calc_flee(bl, sc, b_status->flee +(status->agi - b_status->agi));
+ }
+
+ if(flag&SCB_DEF)
+ {
+ status->def = status_calc_def(bl, sc, b_status->def);
+
+ if( bl->type&BL_HOM )
+ status->def += (status->vit/5 - b_status->vit/5);
+ }
+
+ if(flag&SCB_DEF2) {
+ if (status->vit == b_status->vit)
+ status->def2 = status_calc_def2(bl, sc, b_status->def2);
+ else
+ status->def2 = status_calc_def2(bl, sc, b_status->def2 + (status->vit - b_status->vit));
+ }
+
+ if(flag&SCB_MDEF)
+ {
+ status->mdef = status_calc_mdef(bl, sc, b_status->mdef);
+
+ if( bl->type&BL_HOM )
+ status->mdef += (status->int_/5 - b_status->int_/5);
+ }
+
+ if(flag&SCB_MDEF2) {
+ if (status->int_ == b_status->int_ && status->vit == b_status->vit)
+ status->mdef2 = status_calc_mdef2(bl, sc, b_status->mdef2);
+ else
+ status->mdef2 = status_calc_mdef2(bl, sc, b_status->mdef2 +(status->int_ - b_status->int_) +((status->vit - b_status->vit)>>1));
+ }
+
+ if(flag&SCB_SPEED) {
+ struct unit_data *ud = unit_bl2ud(bl);
+ status->speed = status_calc_speed(bl, sc, b_status->speed);
+
+ //Re-walk to adjust speed (we do not check if walktimer != INVALID_TIMER
+ //because if you step on something while walking, the moment this
+ //piece of code triggers the walk-timer is set on INVALID_TIMER) [Skotlex]
+ if (ud)
+ ud->state.change_walk_target = ud->state.speed_changed = 1;
+
+ if( bl->type&BL_PC && status->speed < battle_config.max_walk_speed )
+ status->speed = battle_config.max_walk_speed;
+
+ if( bl->type&BL_HOM && battle_config.hom_setting&0x8 && ((TBL_HOM*)bl)->master)
+ status->speed = status_get_speed(&((TBL_HOM*)bl)->master->bl);
+
+
+ }
+
+ if(flag&SCB_CRI && b_status->cri) {
+ if (status->luk == b_status->luk)
+ status->cri = status_calc_critical(bl, sc, b_status->cri);
+ else
+ status->cri = status_calc_critical(bl, sc, b_status->cri + 3*(status->luk - b_status->luk));
+ /**
+ * after status_calc_critical so the bonus is applied despite if you have or not a sc bugreport:5240
+ **/
+ if( bl->type == BL_PC && ((TBL_PC*)bl)->status.weapon == W_KATAR )
+ status->cri <<= 1;
+
+ }
+
+ if(flag&SCB_FLEE2 && b_status->flee2) {
+ if (status->luk == b_status->luk)
+ status->flee2 = status_calc_flee2(bl, sc, b_status->flee2);
+ else
+ status->flee2 = status_calc_flee2(bl, sc, b_status->flee2 +(status->luk - b_status->luk));
+ }
+
+ if(flag&SCB_ATK_ELE) {
+ status->rhw.ele = status_calc_attack_element(bl, sc, b_status->rhw.ele);
+ if (sd) sd->state.lr_flag = 1;
+ status->lhw.ele = status_calc_attack_element(bl, sc, b_status->lhw.ele);
+ if (sd) sd->state.lr_flag = 0;
+ }
+
+ if(flag&SCB_DEF_ELE) {
+ status->def_ele = status_calc_element(bl, sc, b_status->def_ele);
+ status->ele_lv = status_calc_element_lv(bl, sc, b_status->ele_lv);
+ }
+
+ if(flag&SCB_MODE)
+ {
+ status->mode = status_calc_mode(bl, sc, b_status->mode);
+ //Since mode changed, reset their state.
+ if (!(status->mode&MD_CANATTACK))
+ unit_stop_attack(bl);
+ if (!(status->mode&MD_CANMOVE))
+ unit_stop_walking(bl,1);
+ }
+
+// No status changes alter these yet.
+// if(flag&SCB_SIZE)
+// if(flag&SCB_RACE)
+// if(flag&SCB_RANGE)
+
+ if(flag&SCB_MAXHP) {
+ if( bl->type&BL_PC )
+ {
+ status->max_hp = status_base_pc_maxhp(sd,status);
+ status->max_hp += b_status->max_hp - sd->status.max_hp;
+
+ status->max_hp = status_calc_maxhp(bl, sc, status->max_hp);
+
+ if( status->max_hp > (unsigned int)battle_config.max_hp )
+ status->max_hp = (unsigned int)battle_config.max_hp;
+ }
+ else
+ {
+ status->max_hp = status_calc_maxhp(bl, sc, b_status->max_hp);
+ }
- if (status->hp > status->max_hp) { //FIXME: Should perhaps a status_zap should be issued?
- status->hp = status->max_hp;
- if (sd) clif_updatestatus(sd,SP_HP);
- }
- }
+ if( status->hp > status->max_hp ) //FIXME: Should perhaps a status_zap should be issued?
+ {
+ status->hp = status->max_hp;
+ if( sd ) clif_updatestatus(sd,SP_HP);
+ }
+ }
- if (flag&SCB_MAXSP) {
- if (bl->type&BL_PC) {
- status->max_sp = status_base_pc_maxsp(sd,status);
- status->max_sp += b_status->max_sp - sd->status.max_sp;
+ if(flag&SCB_MAXSP) {
+ if( bl->type&BL_PC )
+ {
+ status->max_sp = status_base_pc_maxsp(sd,status);
+ status->max_sp += b_status->max_sp - sd->status.max_sp;
- status->max_sp = status_calc_maxsp(&sd->bl, &sd->sc, status->max_sp);
+ status->max_sp = status_calc_maxsp(&sd->bl, &sd->sc, status->max_sp);
- if (status->max_sp > (unsigned int)battle_config.max_sp)
- status->max_sp = (unsigned int)battle_config.max_sp;
- } else {
- status->max_sp = status_calc_maxsp(bl, sc, b_status->max_sp);
- }
+ if( status->max_sp > (unsigned int)battle_config.max_sp )
+ status->max_sp = (unsigned int)battle_config.max_sp;
+ }
+ else
+ {
+ status->max_sp = status_calc_maxsp(bl, sc, b_status->max_sp);
+ }
- if (status->sp > status->max_sp) {
- status->sp = status->max_sp;
- if (sd) clif_updatestatus(sd,SP_SP);
- }
- }
+ if( status->sp > status->max_sp )
+ {
+ status->sp = status->max_sp;
+ if( sd ) clif_updatestatus(sd,SP_SP);
+ }
+ }
- if (flag&SCB_MATK) {
-#ifndef RENEWAL
- status->matk_min = status_base_matk_min(status) + (sd?sd->bonus.ematk:0);
- status->matk_max = status_base_matk_max(status) + (sd?sd->bonus.ematk:0);
+ if(flag&SCB_MATK) {
+#ifdef RENEWAL
+ status->matk_min = status_base_matk_min(status,status_get_lv(bl));
+ if( sd )
+ status->matk_min += sd->bonus.sp_base_matk;
#else
- /**
- * RE MATK Formula (from irowiki:http://irowiki.org/wiki/MATK)
- * MATK = (sMATK + wMATK + eMATK) * Multiplicative Modifiers
- **/
- status->matk_min = status->matk_max = status_base_matk(status, status_get_lv(bl));
- if( bl->type&BL_PC ){
- // Any +MATK you get from skills and cards, including cards in weapon, is added here.
- if( sd->bonus.ematk > 0 ){
- status->matk_max += sd->bonus.ematk;
- status->matk_min += sd->bonus.ematk;
- }
- status->matk_min = status_calc_ematk(bl, sc, status->matk_min);
- status->matk_max = status_calc_ematk(bl, sc, status->matk_max);
- //This is the only portion in MATK that varies depending on the weapon level and refinement rate.
- if( status->rhw.matk > 0 ){
- int wMatk = status->rhw.matk;
- int variance = wMatk * status->rhw.wlv / 10;
- status->matk_min += wMatk - variance;
- status->matk_max += wMatk + variance;
- }
- }
+ status->matk_min = status_base_matk_min(status);
#endif
- if (bl->type&BL_PC && sd->matk_rate != 100) {
- status->matk_max = status->matk_max * sd->matk_rate/100;
- status->matk_min = status->matk_min * sd->matk_rate/100;
- }
+ status->matk_max = status_base_matk_max(status);
- status->matk_min = status_calc_matk(bl, sc, status->matk_min);
- status->matk_max = status_calc_matk(bl, sc, status->matk_max);
+ if( bl->type&BL_PC && sd->matk_rate != 100 )
+ {
+ //Bonuses from previous matk
+#ifndef RENEWAL // only changed in non-renewal [Ind]
+ status->matk_max = status->matk_max * sd->matk_rate/100;
+#endif
+ status->matk_min = status->matk_min * sd->matk_rate/100;
+ }
- if ((bl->type&BL_HOM && battle_config.hom_setting&0x20) //Hom Min Matk is always the same as Max Matk
- || sc->data[SC_RECOGNIZEDSPELL])
- status->matk_min = status->matk_max;
+ status->matk_min = status_calc_matk(bl, sc, status->matk_min);
-#ifdef RENEWAL
- if( sd && sd->right_weapon.overrefine > 0){
- status->matk_min++;
- status->matk_max += sd->right_weapon.overrefine - 1;
- }
+#ifndef RENEWAL // only changed in non-renewal [Ind]
+ status->matk_max = status_calc_matk(bl, sc, status->matk_max);
#endif
- }
+ if( bl->type&BL_HOM && battle_config.hom_setting&0x20 ) //Hom Min Matk is always the same as Max Matk
+ status->matk_min = status->matk_max;
+
+ }
- if (flag&SCB_ASPD) {
- int amotion;
- if (bl->type&BL_PC) {
- amotion = status_base_amotion_pc(sd,status);
+ if(flag&SCB_ASPD) {
+ int amotion;
+ if( bl->type&BL_PC )
+ {
+ amotion = status_base_amotion_pc(sd,status);
#ifndef RENEWAL_ASPD
- status->aspd_rate = status_calc_aspd_rate(bl, sc, b_status->aspd_rate);
+ status->aspd_rate = status_calc_aspd_rate(bl, sc, b_status->aspd_rate);
- if (status->aspd_rate != 1000)
- amotion = amotion*status->aspd_rate/1000;
+ if(status->aspd_rate != 1000)
+ amotion = amotion*status->aspd_rate/1000;
#else
- // aspd = baseaspd + floor(sqrt((agi^2/2) + (dex^2/5))/4 + (potskillbonus*agi/200))
- amotion -= (int)(sqrt((pow(status->agi, 2) / 2) + (pow(status->dex, 2) / 5)) / 4 + (status_calc_aspd(bl, sc, 1) * status->agi / 200)) * 10;
+ // aspd = baseaspd + floor(sqrt((agi^2/2) + (dex^2/5))/4 + (potskillbonus*agi/200))
+ amotion -= (int)(sqrt( (pow(status->agi, 2) / 2) + (pow(status->dex, 2) / 5) ) / 4 + (status_calc_aspd(bl, sc, 1) * status->agi / 200)) * 10;
- if ((status_calc_aspd(bl, sc, 2) + status->aspd_rate2) != 0) // RE ASPD percertage modifier
- amotion -= (amotion - ((sd->class_&JOBL_THIRD) ? battle_config.max_third_aspd : battle_config.max_aspd))
- * (status_calc_aspd(bl, sc, 2) + status->aspd_rate2) / 100;
+ if( (status_calc_aspd(bl, sc, 2) + status->aspd_rate2) != 0 ) // RE ASPD percertage modifier
+ amotion -= ( amotion - ((sd->class_&JOBL_THIRD) ? battle_config.max_third_aspd : battle_config.max_aspd) )
+ * (status_calc_aspd(bl, sc, 2) + status->aspd_rate2) / 100;
- if (status->aspd_rate != 1000) // absolute percentage modifier
- amotion = (200 - (200-amotion/10) * status->aspd_rate / 1000) * 10;
+ if(status->aspd_rate != 1000) // absolute percentage modifier
+ amotion = ( 200 - (200-amotion/10) * status->aspd_rate / 1000 ) * 10;
#endif
- //@TODO move FIGHTINGSPIRIT in fix_aspd
- if (sc && sc->data[SC_FIGHTINGSPIRIT] && sc->data[SC_FIGHTINGSPIRIT]->val2)
- amotion -= (sd?pc_checkskill(sd, RK_RUNEMASTERY):10) / 10 * 40;
- amotion = status_calc_fix_aspd(bl, sc, amotion);
- status->amotion = cap_value(amotion,((sd->class_&JOBL_THIRD) ? battle_config.max_third_aspd : battle_config.max_aspd),2000);
+ //@TODO move FIGHTINGSPIRIT in fix_aspd
+ if( sc && sc->data[SC_FIGHTINGSPIRIT] && sc->data[SC_FIGHTINGSPIRIT]->val2 )
+ amotion -= (sd?pc_checkskill(sd, RK_RUNEMASTERY):10) / 10 * 40;
+ amotion = status_calc_fix_aspd(bl, sc, amotion);
+ status->amotion = cap_value(amotion,((sd->class_&JOBL_THIRD) ? battle_config.max_third_aspd : battle_config.max_aspd),2000);
- status->adelay = 2*status->amotion;
- } else if (bl->type&BL_HOM) {
- amotion = (1000 -4*status->agi -status->dex) * ((TBL_HOM *)bl)->homunculusDB->baseASPD/1000;
- status->aspd_rate = status_calc_aspd_rate(bl, sc, b_status->aspd_rate);
-
- if (status->aspd_rate != 1000)
- amotion = amotion*status->aspd_rate/1000;
+ status->adelay = 2*status->amotion;
+ }
+ else
+ if( bl->type&BL_HOM )
+ {
+ amotion = (1000 -4*status->agi -status->dex) * ((TBL_HOM*)bl)->homunculusDB->baseASPD/1000;
+ status->aspd_rate = status_calc_aspd_rate(bl, sc, b_status->aspd_rate);
- amotion = status_calc_fix_aspd(bl, sc, amotion);
- status->amotion = cap_value(amotion,battle_config.max_aspd,2000);
+ if(status->aspd_rate != 1000)
+ amotion = amotion*status->aspd_rate/1000;
- status->adelay = status->amotion;
- } else { // mercenary and mobs
- amotion = b_status->amotion;
- status->aspd_rate = status_calc_aspd_rate(bl, sc, b_status->aspd_rate);
+ amotion = status_calc_fix_aspd(bl, sc, amotion);
+ status->amotion = cap_value(amotion,battle_config.max_aspd,2000);
- if (status->aspd_rate != 1000)
- amotion = amotion*status->aspd_rate/1000;
+ status->adelay = status->amotion;
+ }
+ else // mercenary and mobs
+ {
+ amotion = b_status->amotion;
+ status->aspd_rate = status_calc_aspd_rate(bl, sc, b_status->aspd_rate);
- amotion = status_calc_fix_aspd(bl, sc, amotion);
- status->amotion = cap_value(amotion, battle_config.monster_max_aspd, 2000);
+ if(status->aspd_rate != 1000)
+ amotion = amotion*status->aspd_rate/1000;
- temp = b_status->adelay*status->aspd_rate/1000;
- status->adelay = cap_value(temp, battle_config.monster_max_aspd*2, 4000);
- }
- }
+ amotion = status_calc_fix_aspd(bl, sc, amotion);
+ status->amotion = cap_value(amotion, battle_config.monster_max_aspd, 2000);
- if (flag&SCB_DSPD) {
- int dmotion;
- if (bl->type&BL_PC) {
- if (b_status->agi == status->agi)
- status->dmotion = status_calc_dmotion(bl, sc, b_status->dmotion);
- else {
- dmotion = 800-status->agi*4;
- status->dmotion = cap_value(dmotion, 400, 800);
- if (battle_config.pc_damage_delay_rate != 100)
- status->dmotion = status->dmotion*battle_config.pc_damage_delay_rate/100;
- //It's safe to ignore b_status->dmotion since no bonus affects it.
- status->dmotion = status_calc_dmotion(bl, sc, status->dmotion);
- }
- } else if (bl->type&BL_HOM) {
- dmotion = 800-status->agi*4;
- status->dmotion = cap_value(dmotion, 400, 800);
- status->dmotion = status_calc_dmotion(bl, sc, b_status->dmotion);
- } else { // mercenary and mobs
- status->dmotion = status_calc_dmotion(bl, sc, b_status->dmotion);
- }
- }
+ temp = b_status->adelay*status->aspd_rate/1000;
+ status->adelay = cap_value(temp, battle_config.monster_max_aspd*2, 4000);
+ }
+ }
+
+ if(flag&SCB_DSPD) {
+ int dmotion;
+ if( bl->type&BL_PC )
+ {
+ if (b_status->agi == status->agi)
+ status->dmotion = status_calc_dmotion(bl, sc, b_status->dmotion);
+ else {
+ dmotion = 800-status->agi*4;
+ status->dmotion = cap_value(dmotion, 400, 800);
+ if(battle_config.pc_damage_delay_rate != 100)
+ status->dmotion = status->dmotion*battle_config.pc_damage_delay_rate/100;
+ //It's safe to ignore b_status->dmotion since no bonus affects it.
+ status->dmotion = status_calc_dmotion(bl, sc, status->dmotion);
+ }
+ }
+ else
+ if( bl->type&BL_HOM )
+ {
+ dmotion = 800-status->agi*4;
+ status->dmotion = cap_value(dmotion, 400, 800);
+ status->dmotion = status_calc_dmotion(bl, sc, b_status->dmotion);
+ }
+ else // mercenary and mobs
+ {
+ status->dmotion = status_calc_dmotion(bl, sc, b_status->dmotion);
+ }
+ }
- if (flag&(SCB_VIT|SCB_MAXHP|SCB_INT|SCB_MAXSP) && bl->type&BL_REGEN)
- status_calc_regen(bl, status, status_get_regen_data(bl));
+ if(flag&(SCB_VIT|SCB_MAXHP|SCB_INT|SCB_MAXSP) && bl->type&BL_REGEN)
+ status_calc_regen(bl, status, status_get_regen_data(bl));
- if (flag&SCB_REGEN && bl->type&BL_REGEN)
- status_calc_regen_rate(bl, status_get_regen_data(bl), sc);
+ if(flag&SCB_REGEN && bl->type&BL_REGEN)
+ status_calc_regen_rate(bl, status_get_regen_data(bl), sc);
}
/// Recalculates parts of an object's base status and battle status according to the specified flags.
/// Also sends updates to the client wherever applicable.
/// @param flag bitfield of values from enum scb_flag
/// @param first if true, will cause status_calc_* functions to run their base status initialization code
-void status_calc_bl_(struct block_list *bl, enum scb_flag flag, bool first)
+void status_calc_bl_(struct block_list* bl, enum scb_flag flag, bool first)
{
- struct status_data b_status; // previous battle status
- struct status_data *status; // pointer to current battle status
-
- // remember previous values
- status = status_get_status_data(bl);
- memcpy(&b_status, status, sizeof(struct status_data));
-
- if (flag&SCB_BASE) { // calculate the object's base status too
- switch (bl->type) {
- case BL_PC:
- status_calc_pc_(BL_CAST(BL_PC,bl), first);
- break;
- case BL_MOB:
- status_calc_mob_(BL_CAST(BL_MOB,bl), first);
- break;
- case BL_PET:
- status_calc_pet_(BL_CAST(BL_PET,bl), first);
- break;
- case BL_HOM:
- status_calc_homunculus_(BL_CAST(BL_HOM,bl), first);
- break;
- case BL_MER:
- status_calc_mercenary_(BL_CAST(BL_MER,bl), first);
- break;
- case BL_ELEM:
- status_calc_elemental_(BL_CAST(BL_ELEM,bl), first);
- break;
- }
- }
-
- if (bl->type == BL_PET)
- return; // pets are not affected by statuses
-
- if (first && bl->type == BL_MOB)
- return; // assume there will be no statuses active
-
- status_calc_bl_main(bl, flag);
-
- if (first && bl->type == BL_HOM)
- return; // client update handled by caller
-
- // compare against new values and send client updates
- if (bl->type == BL_PC) {
- TBL_PC *sd = BL_CAST(BL_PC, bl);
- if (b_status.str != status->str)
- clif_updatestatus(sd,SP_STR);
- if (b_status.agi != status->agi)
- clif_updatestatus(sd,SP_AGI);
- if (b_status.vit != status->vit)
- clif_updatestatus(sd,SP_VIT);
- if (b_status.int_ != status->int_)
- clif_updatestatus(sd,SP_INT);
- if (b_status.dex != status->dex)
- clif_updatestatus(sd,SP_DEX);
- if (b_status.luk != status->luk)
- clif_updatestatus(sd,SP_LUK);
- if (b_status.hit != status->hit)
- clif_updatestatus(sd,SP_HIT);
- if (b_status.flee != status->flee)
- clif_updatestatus(sd,SP_FLEE1);
- if (b_status.amotion != status->amotion)
- clif_updatestatus(sd,SP_ASPD);
- if (b_status.speed != status->speed)
- clif_updatestatus(sd,SP_SPEED);
-
- if (b_status.batk != status->batk
+ struct status_data b_status; // previous battle status
+ struct status_data* status; // pointer to current battle status
+
+ // remember previous values
+ status = status_get_status_data(bl);
+ memcpy(&b_status, status, sizeof(struct status_data));
+
+ if( flag&SCB_BASE ) {// calculate the object's base status too
+ switch( bl->type ) {
+ case BL_PC: status_calc_pc_(BL_CAST(BL_PC,bl), first); break;
+ case BL_MOB: status_calc_mob_(BL_CAST(BL_MOB,bl), first); break;
+ case BL_PET: status_calc_pet_(BL_CAST(BL_PET,bl), first); break;
+ case BL_HOM: status_calc_homunculus_(BL_CAST(BL_HOM,bl), first); break;
+ case BL_MER: status_calc_mercenary_(BL_CAST(BL_MER,bl), first); break;
+ case BL_ELEM: status_calc_elemental_(BL_CAST(BL_ELEM,bl), first); break;
+ }
+ }
+
+ if( bl->type == BL_PET )
+ return; // pets are not affected by statuses
+
+ if( first && bl->type == BL_MOB )
+ return; // assume there will be no statuses active
+
+ status_calc_bl_main(bl, flag);
+
+ if( first && bl->type == BL_HOM )
+ return; // client update handled by caller
+
+ // compare against new values and send client updates
+ if( bl->type == BL_PC )
+ {
+ TBL_PC* sd = BL_CAST(BL_PC, bl);
+ if(b_status.str != status->str)
+ clif_updatestatus(sd,SP_STR);
+ if(b_status.agi != status->agi)
+ clif_updatestatus(sd,SP_AGI);
+ if(b_status.vit != status->vit)
+ clif_updatestatus(sd,SP_VIT);
+ if(b_status.int_ != status->int_)
+ clif_updatestatus(sd,SP_INT);
+ if(b_status.dex != status->dex)
+ clif_updatestatus(sd,SP_DEX);
+ if(b_status.luk != status->luk)
+ clif_updatestatus(sd,SP_LUK);
+ if(b_status.hit != status->hit)
+ clif_updatestatus(sd,SP_HIT);
+ if(b_status.flee != status->flee)
+ clif_updatestatus(sd,SP_FLEE1);
+ if(b_status.amotion != status->amotion)
+ clif_updatestatus(sd,SP_ASPD);
+ if(b_status.speed != status->speed)
+ clif_updatestatus(sd,SP_SPEED);
+
+ if(b_status.batk != status->batk
#ifndef RENEWAL
- || b_status.rhw.atk != status->rhw.atk || b_status.lhw.atk != status->lhw.atk
+ || b_status.rhw.atk != status->rhw.atk || b_status.lhw.atk != status->lhw.atk
#endif
- )
- clif_updatestatus(sd,SP_ATK1);
+ )
+ clif_updatestatus(sd,SP_ATK1);
- if (b_status.def != status->def) {
- clif_updatestatus(sd,SP_DEF1);
+ if(b_status.def != status->def){
+ clif_updatestatus(sd,SP_DEF1);
#ifdef RENEWAL
- clif_updatestatus(sd,SP_DEF2);
+ clif_updatestatus(sd,SP_DEF2);
#endif
- }
+ }
- if (b_status.rhw.atk2 != status->rhw.atk2 || b_status.lhw.atk2 != status->lhw.atk2
+ if(b_status.rhw.atk2 != status->rhw.atk2 || b_status.lhw.atk2 != status->lhw.atk2
#ifdef RENEWAL
- || b_status.rhw.atk != status->rhw.atk || b_status.lhw.atk != status->lhw.atk
+ || b_status.rhw.atk != status->rhw.atk || b_status.lhw.atk != status->lhw.atk
#endif
- )
- clif_updatestatus(sd,SP_ATK2);
+ )
+ clif_updatestatus(sd,SP_ATK2);
- if (b_status.def2 != status->def2) {
- clif_updatestatus(sd,SP_DEF2);
+ if(b_status.def2 != status->def2){
+ clif_updatestatus(sd,SP_DEF2);
#ifdef RENEWAL
- clif_updatestatus(sd,SP_DEF1);
+ clif_updatestatus(sd,SP_DEF1);
#endif
- }
- if (b_status.flee2 != status->flee2)
- clif_updatestatus(sd,SP_FLEE2);
- if (b_status.cri != status->cri)
- clif_updatestatus(sd,SP_CRITICAL);
-#ifndef RENEWAL
- if (b_status.matk_max != status->matk_max)
- clif_updatestatus(sd,SP_MATK1);
- if (b_status.matk_min != status->matk_min)
- clif_updatestatus(sd,SP_MATK2);
-#else
- if(b_status.matk_max != status->matk_max || b_status.matk_min != status->matk_min){
- clif_updatestatus(sd,SP_MATK2);
- clif_updatestatus(sd,SP_MATK1);
}
-#endif
- if (b_status.mdef != status->mdef) {
- clif_updatestatus(sd,SP_MDEF1);
+ if(b_status.flee2 != status->flee2)
+ clif_updatestatus(sd,SP_FLEE2);
+ if(b_status.cri != status->cri)
+ clif_updatestatus(sd,SP_CRITICAL);
+ if(b_status.matk_max != status->matk_max)
+ clif_updatestatus(sd,SP_MATK1);
+ if(b_status.matk_min != status->matk_min)
+ clif_updatestatus(sd,SP_MATK2);
+ if(b_status.mdef != status->mdef){
+ clif_updatestatus(sd,SP_MDEF1);
#ifdef RENEWAL
- clif_updatestatus(sd,SP_MDEF2);
+ clif_updatestatus(sd,SP_MDEF2);
#endif
- }
- if (b_status.mdef2 != status->mdef2) {
- clif_updatestatus(sd,SP_MDEF2);
+ }
+ if(b_status.mdef2 != status->mdef2){
+ clif_updatestatus(sd,SP_MDEF2);
#ifdef RENEWAL
- clif_updatestatus(sd,SP_MDEF1);
+ clif_updatestatus(sd,SP_MDEF1);
#endif
- }
- if (b_status.rhw.range != status->rhw.range)
- clif_updatestatus(sd,SP_ATTACKRANGE);
- if (b_status.max_hp != status->max_hp)
- clif_updatestatus(sd,SP_MAXHP);
- if (b_status.max_sp != status->max_sp)
- clif_updatestatus(sd,SP_MAXSP);
- if (b_status.hp != status->hp)
- clif_updatestatus(sd,SP_HP);
- if (b_status.sp != status->sp)
- clif_updatestatus(sd,SP_SP);
- } else if (bl->type == BL_HOM) {
- TBL_HOM *hd = BL_CAST(BL_HOM, bl);
- if (hd->master && memcmp(&b_status, status, sizeof(struct status_data)) != 0)
- clif_hominfo(hd->master,hd,0);
- } else if (bl->type == BL_MER) {
- TBL_MER *md = BL_CAST(BL_MER, bl);
- if (b_status.rhw.atk != status->rhw.atk || b_status.rhw.atk2 != status->rhw.atk2)
- clif_mercenary_updatestatus(md->master, SP_ATK1);
- if (b_status.matk_max != status->matk_max)
- clif_mercenary_updatestatus(md->master, SP_MATK1);
- if (b_status.hit != status->hit)
- clif_mercenary_updatestatus(md->master, SP_HIT);
- if (b_status.cri != status->cri)
- clif_mercenary_updatestatus(md->master, SP_CRITICAL);
- if (b_status.def != status->def)
- clif_mercenary_updatestatus(md->master, SP_DEF1);
- if (b_status.mdef != status->mdef)
- clif_mercenary_updatestatus(md->master, SP_MDEF1);
- if (b_status.flee != status->flee)
- clif_mercenary_updatestatus(md->master, SP_MERCFLEE);
- if (b_status.amotion != status->amotion)
- clif_mercenary_updatestatus(md->master, SP_ASPD);
- if (b_status.max_hp != status->max_hp)
- clif_mercenary_updatestatus(md->master, SP_MAXHP);
- if (b_status.max_sp != status->max_sp)
- clif_mercenary_updatestatus(md->master, SP_MAXSP);
- if (b_status.hp != status->hp)
- clif_mercenary_updatestatus(md->master, SP_HP);
- if (b_status.sp != status->sp)
- clif_mercenary_updatestatus(md->master, SP_SP);
- } else if (bl->type == BL_ELEM) {
- TBL_ELEM *ed = BL_CAST(BL_ELEM, bl);
- if (b_status.max_hp != status->max_hp)
- clif_elemental_updatestatus(ed->master, SP_MAXHP);
- if (b_status.max_sp != status->max_sp)
- clif_elemental_updatestatus(ed->master, SP_MAXSP);
- if (b_status.hp != status->hp)
- clif_elemental_updatestatus(ed->master, SP_HP);
- if (b_status.sp != status->sp)
- clif_mercenary_updatestatus(ed->master, SP_SP);
- }
+ }
+ if(b_status.rhw.range != status->rhw.range)
+ clif_updatestatus(sd,SP_ATTACKRANGE);
+ if(b_status.max_hp != status->max_hp)
+ clif_updatestatus(sd,SP_MAXHP);
+ if(b_status.max_sp != status->max_sp)
+ clif_updatestatus(sd,SP_MAXSP);
+ if(b_status.hp != status->hp)
+ clif_updatestatus(sd,SP_HP);
+ if(b_status.sp != status->sp)
+ clif_updatestatus(sd,SP_SP);
+ } else if( bl->type == BL_HOM ) {
+ TBL_HOM* hd = BL_CAST(BL_HOM, bl);
+ if( hd->master && memcmp(&b_status, status, sizeof(struct status_data)) != 0 )
+ clif_hominfo(hd->master,hd,0);
+ } else if( bl->type == BL_MER ) {
+ TBL_MER* md = BL_CAST(BL_MER, bl);
+ if( b_status.rhw.atk != status->rhw.atk || b_status.rhw.atk2 != status->rhw.atk2 )
+ clif_mercenary_updatestatus(md->master, SP_ATK1);
+ if( b_status.matk_max != status->matk_max )
+ clif_mercenary_updatestatus(md->master, SP_MATK1);
+ if( b_status.hit != status->hit )
+ clif_mercenary_updatestatus(md->master, SP_HIT);
+ if( b_status.cri != status->cri )
+ clif_mercenary_updatestatus(md->master, SP_CRITICAL);
+ if( b_status.def != status->def )
+ clif_mercenary_updatestatus(md->master, SP_DEF1);
+ if( b_status.mdef != status->mdef )
+ clif_mercenary_updatestatus(md->master, SP_MDEF1);
+ if( b_status.flee != status->flee )
+ clif_mercenary_updatestatus(md->master, SP_MERCFLEE);
+ if( b_status.amotion != status->amotion )
+ clif_mercenary_updatestatus(md->master, SP_ASPD);
+ if( b_status.max_hp != status->max_hp )
+ clif_mercenary_updatestatus(md->master, SP_MAXHP);
+ if( b_status.max_sp != status->max_sp )
+ clif_mercenary_updatestatus(md->master, SP_MAXSP);
+ if( b_status.hp != status->hp )
+ clif_mercenary_updatestatus(md->master, SP_HP);
+ if( b_status.sp != status->sp )
+ clif_mercenary_updatestatus(md->master, SP_SP);
+ } else if( bl->type == BL_ELEM ) {
+ TBL_ELEM* ed = BL_CAST(BL_ELEM, bl);
+ if( b_status.max_hp != status->max_hp )
+ clif_elemental_updatestatus(ed->master, SP_MAXHP);
+ if( b_status.max_sp != status->max_sp )
+ clif_elemental_updatestatus(ed->master, SP_MAXSP);
+ if( b_status.hp != status->hp )
+ clif_elemental_updatestatus(ed->master, SP_HP);
+ if( b_status.sp != status->sp )
+ clif_mercenary_updatestatus(ed->master, SP_SP);
+ }
}
/*==========================================
@@ -4090,1096 +4074,1071 @@ void status_calc_bl_(struct block_list *bl, enum scb_flag flag, bool first)
*------------------------------------------*/
static unsigned short status_calc_str(struct block_list *bl, struct status_change *sc, int str)
{
- if (!sc || !sc->count)
- return cap_value(str,0,USHRT_MAX);
-
- if (sc->data[SC_HARMONIZE]) {
- str -= sc->data[SC_HARMONIZE]->val2;
- return (unsigned short)cap_value(str,0,USHRT_MAX);
- }
- if (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && str < 50)
- return 50;
- if (sc->data[SC_INCALLSTATUS])
- str += sc->data[SC_INCALLSTATUS]->val1;
- if (sc->data[SC_INCSTR])
- str += sc->data[SC_INCSTR]->val1;
- if (sc->data[SC_STRFOOD])
- str += sc->data[SC_STRFOOD]->val1;
- if (sc->data[SC_FOOD_STR_CASH])
- str += sc->data[SC_FOOD_STR_CASH]->val1;
- if (sc->data[SC_BATTLEORDERS])
- str += 5;
- if (sc->data[SC_LEADERSHIP])
- str += sc->data[SC_LEADERSHIP]->val1;
- if (sc->data[SC_LOUD])
- str += 4;
- if (sc->data[SC_TRUESIGHT])
- str += 5;
- if (sc->data[SC_SPURT])
- str += 10;
- if (sc->data[SC_NEN])
- str += sc->data[SC_NEN]->val1;
- if (sc->data[SC_BLESSING]) {
- if (sc->data[SC_BLESSING]->val2)
- str += sc->data[SC_BLESSING]->val2;
- else
- str >>= 1;
- }
- if (sc->data[SC_MARIONETTE])
- str -= ((sc->data[SC_MARIONETTE]->val3)>>16)&0xFF;
- if (sc->data[SC_MARIONETTE2])
- str += ((sc->data[SC_MARIONETTE2]->val3)>>16)&0xFF;
- if (sc->data[SC_GIANTGROWTH])
- str += 30;
- if (sc->data[SC_SAVAGE_STEAK])
- str += sc->data[SC_SAVAGE_STEAK]->val1;
- if (sc->data[SC_INSPIRATION])
- str += sc->data[SC_INSPIRATION]->val3;
- if (sc->data[SC_STOMACHACHE])
- str -= sc->data[SC_STOMACHACHE]->val1;
- if (sc->data[SC_KYOUGAKU])
- str -= sc->data[SC_KYOUGAKU]->val2;
-
- return (unsigned short)cap_value(str,0,USHRT_MAX);
+ if(!sc || !sc->count)
+ return cap_value(str,0,USHRT_MAX);
+
+ if(sc->data[SC_HARMONIZE]) {
+ str -= sc->data[SC_HARMONIZE]->val2;
+ return (unsigned short)cap_value(str,0,USHRT_MAX);
+ }
+ if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && str < 50)
+ return 50;
+ if(sc->data[SC_INCALLSTATUS])
+ str += sc->data[SC_INCALLSTATUS]->val1;
+ if(sc->data[SC_INCSTR])
+ str += sc->data[SC_INCSTR]->val1;
+ if(sc->data[SC_STRFOOD])
+ str += sc->data[SC_STRFOOD]->val1;
+ if(sc->data[SC_FOOD_STR_CASH])
+ str += sc->data[SC_FOOD_STR_CASH]->val1;
+ if(sc->data[SC_BATTLEORDERS])
+ str += 5;
+ if(sc->data[SC_LEADERSHIP])
+ str += sc->data[SC_LEADERSHIP]->val1;
+ if(sc->data[SC_LOUD])
+ str += 4;
+ if(sc->data[SC_TRUESIGHT])
+ str += 5;
+ if(sc->data[SC_SPURT])
+ str += 10;
+ if(sc->data[SC_NEN])
+ str += sc->data[SC_NEN]->val1;
+ if(sc->data[SC_BLESSING]){
+ if(sc->data[SC_BLESSING]->val2)
+ str += sc->data[SC_BLESSING]->val2;
+ else
+ str >>= 1;
+ }
+ if(sc->data[SC_MARIONETTE])
+ str -= ((sc->data[SC_MARIONETTE]->val3)>>16)&0xFF;
+ if(sc->data[SC_MARIONETTE2])
+ str += ((sc->data[SC_MARIONETTE2]->val3)>>16)&0xFF;
+ if(sc->data[SC_GIANTGROWTH])
+ str += 30;
+ if(sc->data[SC_SAVAGE_STEAK])
+ str += sc->data[SC_SAVAGE_STEAK]->val1;
+ if(sc->data[SC_INSPIRATION])
+ str += sc->data[SC_INSPIRATION]->val3;
+ if(sc->data[SC_STOMACHACHE])
+ str -= sc->data[SC_STOMACHACHE]->val1;
+ if(sc->data[SC_KYOUGAKU])
+ str -= sc->data[SC_KYOUGAKU]->val2;
+
+ return (unsigned short)cap_value(str,0,USHRT_MAX);
}
static unsigned short status_calc_agi(struct block_list *bl, struct status_change *sc, int agi)
{
- if (!sc || !sc->count)
- return cap_value(agi,0,USHRT_MAX);
-
- if (sc->data[SC_HARMONIZE]) {
- agi -= sc->data[SC_HARMONIZE]->val2;
- return (unsigned short)cap_value(agi,0,USHRT_MAX);
- }
- if (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && agi < 50)
- return 50;
- if (sc->data[SC_CONCENTRATE] && !sc->data[SC_QUAGMIRE])
- agi += (agi-sc->data[SC_CONCENTRATE]->val3)*sc->data[SC_CONCENTRATE]->val2/100;
- if (sc->data[SC_INCALLSTATUS])
- agi += sc->data[SC_INCALLSTATUS]->val1;
- if (sc->data[SC_INCAGI])
- agi += sc->data[SC_INCAGI]->val1;
- if (sc->data[SC_AGIFOOD])
- agi += sc->data[SC_AGIFOOD]->val1;
- if (sc->data[SC_FOOD_AGI_CASH])
- agi += sc->data[SC_FOOD_AGI_CASH]->val1;
- if (sc->data[SC_SOULCOLD])
- agi += sc->data[SC_SOULCOLD]->val1;
- if (sc->data[SC_TRUESIGHT])
- agi += 5;
- if (sc->data[SC_INCREASEAGI])
- agi += sc->data[SC_INCREASEAGI]->val2;
- if (sc->data[SC_INCREASING])
- agi += 4; // added based on skill updates [Reddozen]
- if (sc->data[SC_DECREASEAGI])
- agi -= sc->data[SC_DECREASEAGI]->val2;
- if (sc->data[SC_QUAGMIRE])
- agi -= sc->data[SC_QUAGMIRE]->val2;
- if (sc->data[SC_SUITON] && sc->data[SC_SUITON]->val3)
- agi -= sc->data[SC_SUITON]->val2;
- if (sc->data[SC_MARIONETTE])
- agi -= ((sc->data[SC_MARIONETTE]->val3)>>8)&0xFF;
- if (sc->data[SC_MARIONETTE2])
- agi += ((sc->data[SC_MARIONETTE2]->val3)>>8)&0xFF;
- if (sc->data[SC_ADORAMUS])
- agi -= sc->data[SC_ADORAMUS]->val2;
- if (sc->data[SC_DROCERA_HERB_STEAMED])
- agi += sc->data[SC_DROCERA_HERB_STEAMED]->val1;
- if (sc->data[SC_INSPIRATION])
- agi += sc->data[SC_INSPIRATION]->val3;
- if (sc->data[SC_STOMACHACHE])
- agi -= sc->data[SC_STOMACHACHE]->val1;
- if (sc->data[SC_KYOUGAKU])
- agi -= sc->data[SC_KYOUGAKU]->val2;
-
- return (unsigned short)cap_value(agi,0,USHRT_MAX);
+ if(!sc || !sc->count)
+ return cap_value(agi,0,USHRT_MAX);
+
+ if(sc->data[SC_HARMONIZE]) {
+ agi -= sc->data[SC_HARMONIZE]->val2;
+ return (unsigned short)cap_value(agi,0,USHRT_MAX);
+ }
+ if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && agi < 50)
+ return 50;
+ if(sc->data[SC_CONCENTRATE] && !sc->data[SC_QUAGMIRE])
+ agi += (agi-sc->data[SC_CONCENTRATE]->val3)*sc->data[SC_CONCENTRATE]->val2/100;
+ if(sc->data[SC_INCALLSTATUS])
+ agi += sc->data[SC_INCALLSTATUS]->val1;
+ if(sc->data[SC_INCAGI])
+ agi += sc->data[SC_INCAGI]->val1;
+ if(sc->data[SC_AGIFOOD])
+ agi += sc->data[SC_AGIFOOD]->val1;
+ if(sc->data[SC_FOOD_AGI_CASH])
+ agi += sc->data[SC_FOOD_AGI_CASH]->val1;
+ if(sc->data[SC_SOULCOLD])
+ agi += sc->data[SC_SOULCOLD]->val1;
+ if(sc->data[SC_TRUESIGHT])
+ agi += 5;
+ if(sc->data[SC_INCREASEAGI])
+ agi += sc->data[SC_INCREASEAGI]->val2;
+ if(sc->data[SC_INCREASING])
+ agi += 4; // added based on skill updates [Reddozen]
+ if(sc->data[SC_DECREASEAGI])
+ agi -= sc->data[SC_DECREASEAGI]->val2;
+ if(sc->data[SC_QUAGMIRE])
+ agi -= sc->data[SC_QUAGMIRE]->val2;
+ if(sc->data[SC_SUITON] && sc->data[SC_SUITON]->val3)
+ agi -= sc->data[SC_SUITON]->val2;
+ if(sc->data[SC_MARIONETTE])
+ agi -= ((sc->data[SC_MARIONETTE]->val3)>>8)&0xFF;
+ if(sc->data[SC_MARIONETTE2])
+ agi += ((sc->data[SC_MARIONETTE2]->val3)>>8)&0xFF;
+ if(sc->data[SC_ADORAMUS])
+ agi -= sc->data[SC_ADORAMUS]->val2;
+ if(sc->data[SC_DROCERA_HERB_STEAMED])
+ agi += sc->data[SC_DROCERA_HERB_STEAMED]->val1;
+ if(sc->data[SC_INSPIRATION])
+ agi += sc->data[SC_INSPIRATION]->val3;
+ if(sc->data[SC_STOMACHACHE])
+ agi -= sc->data[SC_STOMACHACHE]->val1;
+ if(sc->data[SC_KYOUGAKU])
+ agi -= sc->data[SC_KYOUGAKU]->val2;
+
+ return (unsigned short)cap_value(agi,0,USHRT_MAX);
}
static unsigned short status_calc_vit(struct block_list *bl, struct status_change *sc, int vit)
{
- if (!sc || !sc->count)
- return cap_value(vit,0,USHRT_MAX);
-
- if (sc->data[SC_HARMONIZE]) {
- vit -= sc->data[SC_HARMONIZE]->val2;
- return (unsigned short)cap_value(vit,0,USHRT_MAX);
- }
- if (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && vit < 50)
- return 50;
- if (sc->data[SC_INCALLSTATUS])
- vit += sc->data[SC_INCALLSTATUS]->val1;
- if (sc->data[SC_INCVIT])
- vit += sc->data[SC_INCVIT]->val1;
- if (sc->data[SC_VITFOOD])
- vit += sc->data[SC_VITFOOD]->val1;
- if (sc->data[SC_FOOD_VIT_CASH])
- vit += sc->data[SC_FOOD_VIT_CASH]->val1;
- if (sc->data[SC_CHANGE])
- vit += sc->data[SC_CHANGE]->val2;
- if (sc->data[SC_GLORYWOUNDS])
- vit += sc->data[SC_GLORYWOUNDS]->val1;
- if (sc->data[SC_TRUESIGHT])
- vit += 5;
- if (sc->data[SC_STRIPARMOR])
- vit -= vit * sc->data[SC_STRIPARMOR]->val2/100;
- if (sc->data[SC_MARIONETTE])
- vit -= sc->data[SC_MARIONETTE]->val3&0xFF;
- if (sc->data[SC_MARIONETTE2])
- vit += sc->data[SC_MARIONETTE2]->val3&0xFF;
- if (sc->data[SC_LAUDAAGNUS])
- vit += 4 + sc->data[SC_LAUDAAGNUS]->val1;
- if (sc->data[SC_MINOR_BBQ])
- vit += sc->data[SC_MINOR_BBQ]->val1;
- if (sc->data[SC_INSPIRATION])
- vit += sc->data[SC_INSPIRATION]->val3;
- if (sc->data[SC_STOMACHACHE])
- vit -= sc->data[SC_STOMACHACHE]->val1;
- if (sc->data[SC_KYOUGAKU])
- vit -= sc->data[SC_KYOUGAKU]->val2;
-
- return (unsigned short)cap_value(vit,0,USHRT_MAX);
+ if(!sc || !sc->count)
+ return cap_value(vit,0,USHRT_MAX);
+
+ if(sc->data[SC_HARMONIZE]) {
+ vit -= sc->data[SC_HARMONIZE]->val2;
+ return (unsigned short)cap_value(vit,0,USHRT_MAX);
+ }
+ if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && vit < 50)
+ return 50;
+ if(sc->data[SC_INCALLSTATUS])
+ vit += sc->data[SC_INCALLSTATUS]->val1;
+ if(sc->data[SC_INCVIT])
+ vit += sc->data[SC_INCVIT]->val1;
+ if(sc->data[SC_VITFOOD])
+ vit += sc->data[SC_VITFOOD]->val1;
+ if(sc->data[SC_FOOD_VIT_CASH])
+ vit += sc->data[SC_FOOD_VIT_CASH]->val1;
+ if(sc->data[SC_CHANGE])
+ vit += sc->data[SC_CHANGE]->val2;
+ if(sc->data[SC_GLORYWOUNDS])
+ vit += sc->data[SC_GLORYWOUNDS]->val1;
+ if(sc->data[SC_TRUESIGHT])
+ vit += 5;
+ if(sc->data[SC_STRIPARMOR])
+ vit -= vit * sc->data[SC_STRIPARMOR]->val2/100;
+ if(sc->data[SC_MARIONETTE])
+ vit -= sc->data[SC_MARIONETTE]->val3&0xFF;
+ if(sc->data[SC_MARIONETTE2])
+ vit += sc->data[SC_MARIONETTE2]->val3&0xFF;
+ if(sc->data[SC_LAUDAAGNUS])
+ vit += 4 + sc->data[SC_LAUDAAGNUS]->val1;
+ if(sc->data[SC_MINOR_BBQ])
+ vit += sc->data[SC_MINOR_BBQ]->val1;
+ if(sc->data[SC_INSPIRATION])
+ vit += sc->data[SC_INSPIRATION]->val3;
+ if(sc->data[SC_STOMACHACHE])
+ vit -= sc->data[SC_STOMACHACHE]->val1;
+ if(sc->data[SC_KYOUGAKU])
+ vit -= sc->data[SC_KYOUGAKU]->val2;
+
+ return (unsigned short)cap_value(vit,0,USHRT_MAX);
}
static unsigned short status_calc_int(struct block_list *bl, struct status_change *sc, int int_)
{
- if (!sc || !sc->count)
- return cap_value(int_,0,USHRT_MAX);
-
- if (sc->data[SC_HARMONIZE]) {
- int_ -= sc->data[SC_HARMONIZE]->val2;
- return (unsigned short)cap_value(int_,0,USHRT_MAX);
- }
- if (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && int_ < 50)
- return 50;
- if (sc->data[SC_INCALLSTATUS])
- int_ += sc->data[SC_INCALLSTATUS]->val1;
- if (sc->data[SC_INCINT])
- int_ += sc->data[SC_INCINT]->val1;
- if (sc->data[SC_INTFOOD])
- int_ += sc->data[SC_INTFOOD]->val1;
- if (sc->data[SC_FOOD_INT_CASH])
- int_ += sc->data[SC_FOOD_INT_CASH]->val1;
- if (sc->data[SC_CHANGE])
- int_ += sc->data[SC_CHANGE]->val3;
- if (sc->data[SC_BATTLEORDERS])
- int_ += 5;
- if (sc->data[SC_TRUESIGHT])
- int_ += 5;
- if (sc->data[SC_BLESSING]) {
- if (sc->data[SC_BLESSING]->val2)
- int_ += sc->data[SC_BLESSING]->val2;
- else
- int_ >>= 1;
- }
- if (sc->data[SC_STRIPHELM])
- int_ -= int_ * sc->data[SC_STRIPHELM]->val2/100;
- if (sc->data[SC_NEN])
- int_ += sc->data[SC_NEN]->val1;
- if (sc->data[SC_MARIONETTE])
- int_ -= ((sc->data[SC_MARIONETTE]->val4)>>16)&0xFF;
- if (sc->data[SC_MARIONETTE2])
- int_ += ((sc->data[SC_MARIONETTE2]->val4)>>16)&0xFF;
- if (sc->data[SC_MANDRAGORA])
- int_ -= 5 + 5 * sc->data[SC_MANDRAGORA]->val1;
- if (sc->data[SC__STRIPACCESSORY])
- int_ -= int_ * sc->data[SC__STRIPACCESSORY]->val2 / 100;
- if (sc->data[SC_COCKTAIL_WARG_BLOOD])
- int_ += sc->data[SC_COCKTAIL_WARG_BLOOD]->val1;
- if (sc->data[SC_INSPIRATION])
- int_ += sc->data[SC_INSPIRATION]->val3;
- if (sc->data[SC_STOMACHACHE])
- int_ -= sc->data[SC_STOMACHACHE]->val1;
- if (sc->data[SC_KYOUGAKU])
- int_ -= sc->data[SC_KYOUGAKU]->val2;
-
- return (unsigned short)cap_value(int_,0,USHRT_MAX);
+ if(!sc || !sc->count)
+ return cap_value(int_,0,USHRT_MAX);
+
+ if(sc->data[SC_HARMONIZE]) {
+ int_ -= sc->data[SC_HARMONIZE]->val2;
+ return (unsigned short)cap_value(int_,0,USHRT_MAX);
+ }
+ if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && int_ < 50)
+ return 50;
+ if(sc->data[SC_INCALLSTATUS])
+ int_ += sc->data[SC_INCALLSTATUS]->val1;
+ if(sc->data[SC_INCINT])
+ int_ += sc->data[SC_INCINT]->val1;
+ if(sc->data[SC_INTFOOD])
+ int_ += sc->data[SC_INTFOOD]->val1;
+ if(sc->data[SC_FOOD_INT_CASH])
+ int_ += sc->data[SC_FOOD_INT_CASH]->val1;
+ if(sc->data[SC_CHANGE])
+ int_ += sc->data[SC_CHANGE]->val3;
+ if(sc->data[SC_BATTLEORDERS])
+ int_ += 5;
+ if(sc->data[SC_TRUESIGHT])
+ int_ += 5;
+ if(sc->data[SC_BLESSING]){
+ if (sc->data[SC_BLESSING]->val2)
+ int_ += sc->data[SC_BLESSING]->val2;
+ else
+ int_ >>= 1;
+ }
+ if(sc->data[SC_STRIPHELM])
+ int_ -= int_ * sc->data[SC_STRIPHELM]->val2/100;
+ if(sc->data[SC_NEN])
+ int_ += sc->data[SC_NEN]->val1;
+ if(sc->data[SC_MARIONETTE])
+ int_ -= ((sc->data[SC_MARIONETTE]->val4)>>16)&0xFF;
+ if(sc->data[SC_MARIONETTE2])
+ int_ += ((sc->data[SC_MARIONETTE2]->val4)>>16)&0xFF;
+ if(sc->data[SC_MANDRAGORA])
+ int_ -= 5 + 5 * sc->data[SC_MANDRAGORA]->val1;
+ if(sc->data[SC__STRIPACCESSORY])
+ int_ -= int_ * sc->data[SC__STRIPACCESSORY]->val2 / 100;
+ if(sc->data[SC_COCKTAIL_WARG_BLOOD])
+ int_ += sc->data[SC_COCKTAIL_WARG_BLOOD]->val1;
+ if(sc->data[SC_INSPIRATION])
+ int_ += sc->data[SC_INSPIRATION]->val3;
+ if(sc->data[SC_STOMACHACHE])
+ int_ -= sc->data[SC_STOMACHACHE]->val1;
+ if(sc->data[SC_KYOUGAKU])
+ int_ -= sc->data[SC_KYOUGAKU]->val2;
+
+ return (unsigned short)cap_value(int_,0,USHRT_MAX);
}
static unsigned short status_calc_dex(struct block_list *bl, struct status_change *sc, int dex)
{
- if (!sc || !sc->count)
- return cap_value(dex,0,USHRT_MAX);
-
- if (sc->data[SC_HARMONIZE]) {
- dex -= sc->data[SC_HARMONIZE]->val2;
- return (unsigned short)cap_value(dex,0,USHRT_MAX);
- }
- if (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && dex < 50)
- return 50;
- if (sc->data[SC_CONCENTRATE] && !sc->data[SC_QUAGMIRE])
- dex += (dex-sc->data[SC_CONCENTRATE]->val4)*sc->data[SC_CONCENTRATE]->val2/100;
- if (sc->data[SC_INCALLSTATUS])
- dex += sc->data[SC_INCALLSTATUS]->val1;
- if (sc->data[SC_INCDEX])
- dex += sc->data[SC_INCDEX]->val1;
- if (sc->data[SC_DEXFOOD])
- dex += sc->data[SC_DEXFOOD]->val1;
- if (sc->data[SC_FOOD_DEX_CASH])
- dex += sc->data[SC_FOOD_DEX_CASH]->val1;
- if (sc->data[SC_BATTLEORDERS])
- dex += 5;
- if (sc->data[SC_HAWKEYES])
- dex += sc->data[SC_HAWKEYES]->val1;
- if (sc->data[SC_TRUESIGHT])
- dex += 5;
- if (sc->data[SC_QUAGMIRE])
- dex -= sc->data[SC_QUAGMIRE]->val2;
- if (sc->data[SC_BLESSING]) {
- if (sc->data[SC_BLESSING]->val2)
- dex += sc->data[SC_BLESSING]->val2;
- else
- dex >>= 1;
- }
- if (sc->data[SC_INCREASING])
- dex += 4; // added based on skill updates [Reddozen]
- if (sc->data[SC_MARIONETTE])
- dex -= ((sc->data[SC_MARIONETTE]->val4)>>8)&0xFF;
- if (sc->data[SC_MARIONETTE2])
- dex += ((sc->data[SC_MARIONETTE2]->val4)>>8)&0xFF;
- if (sc->data[SC__STRIPACCESSORY])
- dex -= dex * sc->data[SC__STRIPACCESSORY]->val2 / 100;
- if (sc->data[SC_SIROMA_ICE_TEA])
- dex += sc->data[SC_SIROMA_ICE_TEA]->val1;
- if (sc->data[SC_INSPIRATION])
- dex += sc->data[SC_INSPIRATION]->val3;
- if (sc->data[SC_STOMACHACHE])
- dex -= sc->data[SC_STOMACHACHE]->val1;
- if (sc->data[SC_KYOUGAKU])
- dex -= sc->data[SC_KYOUGAKU]->val2;
-
- return (unsigned short)cap_value(dex,0,USHRT_MAX);
+ if(!sc || !sc->count)
+ return cap_value(dex,0,USHRT_MAX);
+
+ if(sc->data[SC_HARMONIZE]) {
+ dex -= sc->data[SC_HARMONIZE]->val2;
+ return (unsigned short)cap_value(dex,0,USHRT_MAX);
+ }
+ if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && dex < 50)
+ return 50;
+ if(sc->data[SC_CONCENTRATE] && !sc->data[SC_QUAGMIRE])
+ dex += (dex-sc->data[SC_CONCENTRATE]->val4)*sc->data[SC_CONCENTRATE]->val2/100;
+ if(sc->data[SC_INCALLSTATUS])
+ dex += sc->data[SC_INCALLSTATUS]->val1;
+ if(sc->data[SC_INCDEX])
+ dex += sc->data[SC_INCDEX]->val1;
+ if(sc->data[SC_DEXFOOD])
+ dex += sc->data[SC_DEXFOOD]->val1;
+ if(sc->data[SC_FOOD_DEX_CASH])
+ dex += sc->data[SC_FOOD_DEX_CASH]->val1;
+ if(sc->data[SC_BATTLEORDERS])
+ dex += 5;
+ if(sc->data[SC_HAWKEYES])
+ dex += sc->data[SC_HAWKEYES]->val1;
+ if(sc->data[SC_TRUESIGHT])
+ dex += 5;
+ if(sc->data[SC_QUAGMIRE])
+ dex -= sc->data[SC_QUAGMIRE]->val2;
+ if(sc->data[SC_BLESSING]){
+ if (sc->data[SC_BLESSING]->val2)
+ dex += sc->data[SC_BLESSING]->val2;
+ else
+ dex >>= 1;
+ }
+ if(sc->data[SC_INCREASING])
+ dex += 4; // added based on skill updates [Reddozen]
+ if(sc->data[SC_MARIONETTE])
+ dex -= ((sc->data[SC_MARIONETTE]->val4)>>8)&0xFF;
+ if(sc->data[SC_MARIONETTE2])
+ dex += ((sc->data[SC_MARIONETTE2]->val4)>>8)&0xFF;
+ if(sc->data[SC__STRIPACCESSORY])
+ dex -= dex * sc->data[SC__STRIPACCESSORY]->val2 / 100;
+ if(sc->data[SC_SIROMA_ICE_TEA])
+ dex += sc->data[SC_SIROMA_ICE_TEA]->val1;
+ if(sc->data[SC_INSPIRATION])
+ dex += sc->data[SC_INSPIRATION]->val3;
+ if(sc->data[SC_STOMACHACHE])
+ dex -= sc->data[SC_STOMACHACHE]->val1;
+ if(sc->data[SC_KYOUGAKU])
+ dex -= sc->data[SC_KYOUGAKU]->val2;
+
+ return (unsigned short)cap_value(dex,0,USHRT_MAX);
}
static unsigned short status_calc_luk(struct block_list *bl, struct status_change *sc, int luk)
{
- if (!sc || !sc->count)
- return cap_value(luk,0,USHRT_MAX);
-
- if (sc->data[SC_HARMONIZE]) {
- luk -= sc->data[SC_HARMONIZE]->val2;
- return (unsigned short)cap_value(luk,0,USHRT_MAX);
- }
- if (sc->data[SC_CURSE])
- return 0;
- if (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && luk < 50)
- return 50;
- if (sc->data[SC_INCALLSTATUS])
- luk += sc->data[SC_INCALLSTATUS]->val1;
- if (sc->data[SC_INCLUK])
- luk += sc->data[SC_INCLUK]->val1;
- if (sc->data[SC_LUKFOOD])
- luk += sc->data[SC_LUKFOOD]->val1;
- if (sc->data[SC_FOOD_LUK_CASH])
- luk += sc->data[SC_FOOD_LUK_CASH]->val1;
- if (sc->data[SC_TRUESIGHT])
- luk += 5;
- if (sc->data[SC_GLORIA])
- luk += 30;
- if (sc->data[SC_MARIONETTE])
- luk -= sc->data[SC_MARIONETTE]->val4&0xFF;
- if (sc->data[SC_MARIONETTE2])
- luk += sc->data[SC_MARIONETTE2]->val4&0xFF;
- if (sc->data[SC_LAUDARAMUS])
- luk += 4 + sc->data[SC_LAUDARAMUS]->val1;
- if (sc->data[SC__STRIPACCESSORY])
- luk -= luk * sc->data[SC__STRIPACCESSORY]->val2 / 100;
- if (sc->data[SC_PUTTI_TAILS_NOODLES])
- luk += sc->data[SC_PUTTI_TAILS_NOODLES]->val1;
- if (sc->data[SC_INSPIRATION])
- luk += sc->data[SC_INSPIRATION]->val3;
- if (sc->data[SC_STOMACHACHE])
- luk -= sc->data[SC_STOMACHACHE]->val1;
- if (sc->data[SC_BANANA_BOMB])
- luk -= luk * sc->data[SC_BANANA_BOMB]->val1 / 100;
- if (sc->data[SC_KYOUGAKU])
- luk -= sc->data[SC_KYOUGAKU]->val2;
-
- return (unsigned short)cap_value(luk,0,USHRT_MAX);
+ if(!sc || !sc->count)
+ return cap_value(luk,0,USHRT_MAX);
+
+ if(sc->data[SC_HARMONIZE]) {
+ luk -= sc->data[SC_HARMONIZE]->val2;
+ return (unsigned short)cap_value(luk,0,USHRT_MAX);
+ }
+ if(sc->data[SC_CURSE])
+ return 0;
+ if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && luk < 50)
+ return 50;
+ if(sc->data[SC_INCALLSTATUS])
+ luk += sc->data[SC_INCALLSTATUS]->val1;
+ if(sc->data[SC_INCLUK])
+ luk += sc->data[SC_INCLUK]->val1;
+ if(sc->data[SC_LUKFOOD])
+ luk += sc->data[SC_LUKFOOD]->val1;
+ if(sc->data[SC_FOOD_LUK_CASH])
+ luk += sc->data[SC_FOOD_LUK_CASH]->val1;
+ if(sc->data[SC_TRUESIGHT])
+ luk += 5;
+ if(sc->data[SC_GLORIA])
+ luk += 30;
+ if(sc->data[SC_MARIONETTE])
+ luk -= sc->data[SC_MARIONETTE]->val4&0xFF;
+ if(sc->data[SC_MARIONETTE2])
+ luk += sc->data[SC_MARIONETTE2]->val4&0xFF;
+ if(sc->data[SC_LAUDARAMUS])
+ luk += 4 + sc->data[SC_LAUDARAMUS]->val1;
+ if(sc->data[SC__STRIPACCESSORY])
+ luk -= luk * sc->data[SC__STRIPACCESSORY]->val2 / 100;
+ if(sc->data[SC_PUTTI_TAILS_NOODLES])
+ luk += sc->data[SC_PUTTI_TAILS_NOODLES]->val1;
+ if(sc->data[SC_INSPIRATION])
+ luk += sc->data[SC_INSPIRATION]->val3;
+ if(sc->data[SC_STOMACHACHE])
+ luk -= sc->data[SC_STOMACHACHE]->val1;
+ if(sc->data[SC_BANANA_BOMB])
+ luk -= luk * sc->data[SC_BANANA_BOMB]->val1 / 100;
+ if(sc->data[SC_KYOUGAKU])
+ luk -= sc->data[SC_KYOUGAKU]->val2;
+
+ return (unsigned short)cap_value(luk,0,USHRT_MAX);
}
static unsigned short status_calc_batk(struct block_list *bl, struct status_change *sc, int batk)
{
- if (!sc || !sc->count)
- return cap_value(batk,0,USHRT_MAX);
-
- if (sc->data[SC_ATKPOTION])
- batk += sc->data[SC_ATKPOTION]->val1;
- if (sc->data[SC_BATKFOOD])
- batk += sc->data[SC_BATKFOOD]->val1;
- if (sc->data[SC_INCATKRATE])
- batk += batk * sc->data[SC_INCATKRATE]->val1/100;
- if (sc->data[SC_PROVOKE])
- batk += batk * sc->data[SC_PROVOKE]->val3/100;
- if (sc->data[SC_CONCENTRATION])
- batk += batk * sc->data[SC_CONCENTRATION]->val2/100;
- if (sc->data[SC_SKE])
- batk += batk * 3;
- if (sc->data[SC_BLOODLUST])
- batk += batk * sc->data[SC_BLOODLUST]->val2/100;
- if (sc->data[SC_JOINTBEAT] && sc->data[SC_JOINTBEAT]->val2&BREAK_WAIST)
- batk -= batk * 25/100;
- if (sc->data[SC_CURSE])
- batk -= batk * 25/100;
- //Curse shouldn't effect on this? <- Curse OR Bleeding??
- // if(sc->data[SC_BLEEDING])
- // batk -= batk * 25/100;
- if (sc->data[SC_FLEET])
- batk += batk * sc->data[SC_FLEET]->val3/100;
- if (sc->data[SC_GATLINGFEVER])
- batk += sc->data[SC_GATLINGFEVER]->val3;
- if (sc->data[SC_MADNESSCANCEL])
- batk += 100;
- if (sc->data[SC__ENERVATION])
- batk -= batk * sc->data[SC__ENERVATION]->val2 / 100;
- if (sc->data[SC_RUSHWINDMILL])
- batk += batk * sc->data[SC_RUSHWINDMILL]->val2/100;
- if (sc->data[SC_SATURDAYNIGHTFEVER])
- batk += 100 * sc->data[SC_SATURDAYNIGHTFEVER]->val1;
- if (sc->data[SC_MELODYOFSINK])
- batk -= batk * sc->data[SC_MELODYOFSINK]->val3/100;
- if (sc->data[SC_BEYONDOFWARCRY])
- batk += batk * sc->data[SC_BEYONDOFWARCRY]->val3/100;
- if (sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 2)
- batk += 50;
- if (bl->type == BL_ELEM
- && ((sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 1)
- || (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 1)
- || (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 1)
- || (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 1))
- )
- batk += batk / 5;
- if (sc->data[SC_FULL_SWING_K])
- batk += sc->data[SC_FULL_SWING_K]->val1;
- if (sc->data[SC_ODINS_POWER])
- batk += 70;
- if (sc->data[SC_ZANGETSU])
- batk += batk * sc->data[SC_ZANGETSU]->val2 / 100;
- if (sc->data[SC_ASH] && (bl->type==BL_MOB)) {
- if (status_get_element(bl) == ELE_WATER) //water type
- batk /= 2;
- }
- if (sc->data[SC_PYROCLASTIC])
- batk += sc->data[SC_PYROCLASTIC]->val2;
- if (sc->data[SC_ANGRIFFS_MODUS])
- batk += sc->data[SC_ANGRIFFS_MODUS]->val2;
-
- return (unsigned short)cap_value(batk,0,USHRT_MAX);
+ if(!sc || !sc->count)
+ return cap_value(batk,0,USHRT_MAX);
+
+ if(sc->data[SC_ATKPOTION])
+ batk += sc->data[SC_ATKPOTION]->val1;
+ if(sc->data[SC_BATKFOOD])
+ batk += sc->data[SC_BATKFOOD]->val1;
+ if(sc->data[SC_INCATKRATE])
+ batk += batk * sc->data[SC_INCATKRATE]->val1/100;
+ if(sc->data[SC_PROVOKE])
+ batk += batk * sc->data[SC_PROVOKE]->val3/100;
+ if(sc->data[SC_CONCENTRATION])
+ batk += batk * sc->data[SC_CONCENTRATION]->val2/100;
+ if(sc->data[SC_SKE])
+ batk += batk * 3;
+ if(sc->data[SC_BLOODLUST])
+ batk += batk * sc->data[SC_BLOODLUST]->val2/100;
+ if(sc->data[SC_JOINTBEAT] && sc->data[SC_JOINTBEAT]->val2&BREAK_WAIST)
+ batk -= batk * 25/100;
+ if(sc->data[SC_CURSE])
+ batk -= batk * 25/100;
+//Curse shouldn't effect on this? <- Curse OR Bleeding??
+// if(sc->data[SC_BLEEDING])
+// batk -= batk * 25/100;
+ if(sc->data[SC_FLEET])
+ batk += batk * sc->data[SC_FLEET]->val3/100;
+ if(sc->data[SC_GATLINGFEVER])
+ batk += sc->data[SC_GATLINGFEVER]->val3;
+ if(sc->data[SC_MADNESSCANCEL])
+ batk += 100;
+ if(sc->data[SC__ENERVATION])
+ batk -= batk * sc->data[SC__ENERVATION]->val2 / 100;
+ if(sc->data[SC_RUSHWINDMILL])
+ batk += batk * sc->data[SC_RUSHWINDMILL]->val2/100;
+ if(sc->data[SC_SATURDAYNIGHTFEVER])
+ batk += 100 * sc->data[SC_SATURDAYNIGHTFEVER]->val1;
+ if(sc->data[SC_MELODYOFSINK])
+ batk -= batk * sc->data[SC_MELODYOFSINK]->val3/100;
+ if(sc->data[SC_BEYONDOFWARCRY])
+ batk += batk * sc->data[SC_BEYONDOFWARCRY]->val3/100;
+ if(sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 2)
+ batk += 50;
+ if(bl->type == BL_ELEM
+ && ((sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 1)
+ || (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 1)
+ || (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 1)
+ || (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 1))
+ )
+ batk += batk / 5;
+ if(sc->data[SC_FULL_SWING_K])
+ batk += sc->data[SC_FULL_SWING_K]->val1;
+ if(sc->data[SC_ODINS_POWER])
+ batk += 70;
+ if( sc->data[SC_ZANGETSU] )
+ batk += batk * sc->data[SC_ZANGETSU]->val2 / 100;
+ if(sc->data[SC_ASH] && (bl->type==BL_MOB)){
+ if(status_get_element(bl) == ELE_WATER) //water type
+ batk /= 2;
+ }
+ if(sc->data[SC_PYROCLASTIC])
+ batk += sc->data[SC_PYROCLASTIC]->val2;
+ if (sc->data[SC_ANGRIFFS_MODUS])
+ batk += sc->data[SC_ANGRIFFS_MODUS]->val2;
+
+ return (unsigned short)cap_value(batk,0,USHRT_MAX);
}
static unsigned short status_calc_watk(struct block_list *bl, struct status_change *sc, int watk)
{
- if (!sc || !sc->count)
- return cap_value(watk,0,USHRT_MAX);
-
- if (sc->data[SC_IMPOSITIO])
- watk += sc->data[SC_IMPOSITIO]->val2;
- if (sc->data[SC_WATKFOOD])
- watk += sc->data[SC_WATKFOOD]->val1;
- if (sc->data[SC_DRUMBATTLE])
- watk += sc->data[SC_DRUMBATTLE]->val2;
- if (sc->data[SC_VOLCANO])
- watk += sc->data[SC_VOLCANO]->val2;
- if (sc->data[SC_INCATKRATE])
- watk += watk * sc->data[SC_INCATKRATE]->val1/100;
- if (sc->data[SC_PROVOKE])
- watk += watk * sc->data[SC_PROVOKE]->val3/100;
- if (sc->data[SC_CONCENTRATION])
- watk += watk * sc->data[SC_CONCENTRATION]->val2/100;
- if (sc->data[SC_SKE])
- watk += watk * 3;
- if (sc->data[SC_NIBELUNGEN]) {
- if (bl->type != BL_PC)
- watk += sc->data[SC_NIBELUNGEN]->val2;
- else {
-#ifndef RENEWAL
- TBL_PC *sd = (TBL_PC *)bl;
- int index = sd->equip_index[sd->state.lr_flag?EQI_HAND_L:EQI_HAND_R];
- if (index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->wlv == 4)
-#endif
- watk += sc->data[SC_NIBELUNGEN]->val2;
- }
- }
- if (sc->data[SC__ENERVATION])
- watk -= watk * sc->data[SC__ENERVATION]->val2 / 100;
- if (sc->data[SC_FLEET])
- watk += watk * sc->data[SC_FLEET]->val3/100;
- if (sc->data[SC_CURSE])
- watk -= watk * 25/100;
- if (sc->data[SC_STRIPWEAPON])
- watk -= watk * sc->data[SC_STRIPWEAPON]->val2/100;
- if (sc->data[SC_MERC_ATKUP])
- watk += sc->data[SC_MERC_ATKUP]->val2;
- if (sc->data[SC_FIGHTINGSPIRIT])
- watk += sc->data[SC_FIGHTINGSPIRIT]->val1;
- if (sc->data[SC__ENERVATION])
- watk -= watk * sc->data[SC__ENERVATION]->val2 / 100;
- if (sc->data[SC_STRIKING])
- watk += sc->data[SC_STRIKING]->val2;
- if (sc->data[SC_SHIELDSPELL_DEF] && sc->data[SC_SHIELDSPELL_DEF]->val1 == 3)
- watk += sc->data[SC_SHIELDSPELL_DEF]->val2;
- if (sc->data[SC_INSPIRATION])
- watk += sc->data[SC_INSPIRATION]->val2;
- if (sc->data[SC_BANDING] && sc->data[SC_BANDING]->val2 > 0)
- watk += (10 + 10 * sc->data[SC_BANDING]->val1) * (sc->data[SC_BANDING]->val2);
- if (sc->data[SC_TROPIC_OPTION])
- watk += sc->data[SC_TROPIC_OPTION]->val2;
- if (sc->data[SC_HEATER_OPTION])
- watk += sc->data[SC_HEATER_OPTION]->val2;
- if (sc->data[SC_WATER_BARRIER])
- watk -= sc->data[SC_WATER_BARRIER]->val3;
- if (sc->data[SC_PYROTECHNIC_OPTION])
- watk += sc->data[SC_PYROTECHNIC_OPTION]->val2;
- if ((sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 2)
- || (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 2)
- || (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 2)
- || (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2)
- )
- watk += watk / 10;
- if (sc && sc->data[SC_TIDAL_WEAPON])
- watk += watk * sc->data[SC_TIDAL_WEAPON]->val2 / 100;
- if (sc->data[SC_ANGRIFFS_MODUS])
- watk += watk * sc->data[SC_ANGRIFFS_MODUS]->val2/100;
+ if(!sc || !sc->count)
+ return cap_value(watk,0,USHRT_MAX);
+
+ if(sc->data[SC_IMPOSITIO])
+ watk += sc->data[SC_IMPOSITIO]->val2;
+ if(sc->data[SC_WATKFOOD])
+ watk += sc->data[SC_WATKFOOD]->val1;
+ if(sc->data[SC_DRUMBATTLE])
+ watk += sc->data[SC_DRUMBATTLE]->val2;
+ if(sc->data[SC_VOLCANO])
+ watk += sc->data[SC_VOLCANO]->val2;
+ if(sc->data[SC_INCATKRATE])
+ watk += watk * sc->data[SC_INCATKRATE]->val1/100;
+ if(sc->data[SC_PROVOKE])
+ watk += watk * sc->data[SC_PROVOKE]->val3/100;
+ if(sc->data[SC_CONCENTRATION])
+ watk += watk * sc->data[SC_CONCENTRATION]->val2/100;
+ if(sc->data[SC_SKE])
+ watk += watk * 3;
+ if(sc->data[SC_NIBELUNGEN]) {
+ if (bl->type != BL_PC)
+ watk += sc->data[SC_NIBELUNGEN]->val2;
+ else {
+ #ifndef RENEWAL
+ TBL_PC *sd = (TBL_PC*)bl;
+ int index = sd->equip_index[sd->state.lr_flag?EQI_HAND_L:EQI_HAND_R];
+ if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->wlv == 4)
+ #endif
+ watk += sc->data[SC_NIBELUNGEN]->val2;
+ }
+ }
+ if(sc->data[SC__ENERVATION])
+ watk -= watk * sc->data[SC__ENERVATION]->val2 / 100;
+ if(sc->data[SC_FLEET])
+ watk += watk * sc->data[SC_FLEET]->val3/100;
+ if(sc->data[SC_CURSE])
+ watk -= watk * 25/100;
+ if(sc->data[SC_STRIPWEAPON])
+ watk -= watk * sc->data[SC_STRIPWEAPON]->val2/100;
+ if(sc->data[SC_MERC_ATKUP])
+ watk += sc->data[SC_MERC_ATKUP]->val2;
+ if(sc->data[SC_FIGHTINGSPIRIT])
+ watk += sc->data[SC_FIGHTINGSPIRIT]->val1;
+ if(sc->data[SC__ENERVATION])
+ watk -= watk * sc->data[SC__ENERVATION]->val2 / 100;
+ if(sc->data[SC_STRIKING])
+ watk += sc->data[SC_STRIKING]->val2;
+ if(sc->data[SC_SHIELDSPELL_DEF] && sc->data[SC_SHIELDSPELL_DEF]->val1 == 3)
+ watk += sc->data[SC_SHIELDSPELL_DEF]->val2;
+ if(sc->data[SC_INSPIRATION])
+ watk += sc->data[SC_INSPIRATION]->val2;
+ if( sc->data[SC_BANDING] && sc->data[SC_BANDING]->val2 > 0 )
+ watk += (10 + 10 * sc->data[SC_BANDING]->val1) * (sc->data[SC_BANDING]->val2);
+ if( sc->data[SC_TROPIC_OPTION] )
+ watk += sc->data[SC_TROPIC_OPTION]->val2;
+ if( sc->data[SC_HEATER_OPTION] )
+ watk += sc->data[SC_HEATER_OPTION]->val2;
+ if( sc->data[SC_WATER_BARRIER] )
+ watk -= sc->data[SC_WATER_BARRIER]->val3;
+ if( sc->data[SC_PYROTECHNIC_OPTION] )
+ watk += sc->data[SC_PYROTECHNIC_OPTION]->val2;
+ if((sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 2)
+ || (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 2)
+ || (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 2)
+ || (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2)
+ )
+ watk += watk / 10;
+ if( sc && sc->data[SC_TIDAL_WEAPON] )
+ watk += watk * sc->data[SC_TIDAL_WEAPON]->val2 / 100;
+ if(sc->data[SC_ANGRIFFS_MODUS])
+ watk += watk * sc->data[SC_ANGRIFFS_MODUS]->val2/100;
#ifdef RENEWAL_EDP
- if (sc->data[SC_EDP])
- watk = watk * (100 + sc->data[SC_EDP]->val1 * 80) / 100;
+ if( sc->data[SC_EDP] )
+ watk = watk * (100 + sc->data[SC_EDP]->val1 * 80) / 100;
#endif
- return (unsigned short)cap_value(watk,0,USHRT_MAX);
-}
-#ifdef RENEWAL
-static unsigned short status_calc_ematk(struct block_list *bl, struct status_change *sc, int matk)
-{
-
- if (!sc || !sc->count)
- return cap_value(matk,0,USHRT_MAX);
- if (sc->data[SC_MATKPOTION])
- matk += sc->data[SC_MATKPOTION]->val1;
- if (sc->data[SC_MATKFOOD])
- matk += sc->data[SC_MATKFOOD]->val1;
- if (sc->data[SC_MANA_PLUS])
- matk += sc->data[SC_MANA_PLUS]->val1;
- if (sc->data[SC_AQUAPLAY_OPTION])
- matk += sc->data[SC_AQUAPLAY_OPTION]->val2;
- if (sc->data[SC_CHILLY_AIR_OPTION])
- matk += sc->data[SC_CHILLY_AIR_OPTION]->val2;
- if (sc->data[SC_WATER_BARRIER])
- matk -= sc->data[SC_WATER_BARRIER]->val3;
- if (sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 3)
- matk += 50;
- if (sc->data[SC_ODINS_POWER])
- matk += 40 + 30 * sc->data[SC_ODINS_POWER]->val1; //70 lvl1, 100lvl2
- if (sc->data[SC_IZAYOI])
- matk += 50 * sc->data[SC_IZAYOI]->val1;
-
- return (unsigned short)cap_value(matk,0,USHRT_MAX);
+ return (unsigned short)cap_value(watk,0,USHRT_MAX);
}
-#endif
+
static unsigned short status_calc_matk(struct block_list *bl, struct status_change *sc, int matk)
{
- if (!sc || !sc->count)
- return cap_value(matk,0,USHRT_MAX);
-#ifndef RENEWAL
- // take note fixed value first before % modifiers
- if (sc->data[SC_MATKPOTION])
- matk += sc->data[SC_MATKPOTION]->val1;
- if (sc->data[SC_MATKFOOD])
- matk += sc->data[SC_MATKFOOD]->val1;
- if (sc->data[SC_MANA_PLUS])
- matk += sc->data[SC_MANA_PLUS]->val1;
- if (sc->data[SC_AQUAPLAY_OPTION])
- matk += sc->data[SC_AQUAPLAY_OPTION]->val2;
- if (sc->data[SC_CHILLY_AIR_OPTION])
- matk += sc->data[SC_CHILLY_AIR_OPTION]->val2;
- if (sc->data[SC_WATER_BARRIER])
- matk -= sc->data[SC_WATER_BARRIER]->val3;
- if (sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 3)
- matk += 50;
- if (sc->data[SC_ODINS_POWER])
- matk += 40 + 30 * sc->data[SC_ODINS_POWER]->val1; //70 lvl1, 100lvl2
- if (sc->data[SC_IZAYOI])
- matk += 50 * sc->data[SC_IZAYOI]->val1;
-#endif
- if (sc->data[SC_MAGICPOWER])
- matk += matk * sc->data[SC_MAGICPOWER]->val3/100;
- if (sc->data[SC_MINDBREAKER])
- matk += matk * sc->data[SC_MINDBREAKER]->val2/100;
- if (sc->data[SC_INCMATKRATE])
- matk += matk * sc->data[SC_INCMATKRATE]->val1/100;
- if (sc->data[SC_MOONLITSERENADE])
- matk += matk * sc->data[SC_MOONLITSERENADE]->val2/100;
- if (sc->data[SC_MELODYOFSINK])
- matk += matk * sc->data[SC_MELODYOFSINK]->val3/100;
- if (sc->data[SC_BEYONDOFWARCRY])
- matk -= matk * sc->data[SC_BEYONDOFWARCRY]->val3/100;
- if (sc->data[SC_ZANGETSU])
- matk += matk * sc->data[SC_ZANGETSU]->val2 / 100;
-
- return (unsigned short)cap_value(matk,0,USHRT_MAX);
+ if(!sc || !sc->count)
+ return cap_value(matk,0,USHRT_MAX);
+
+ if(sc->data[SC_MATKPOTION])
+ matk += sc->data[SC_MATKPOTION]->val1;
+ if(sc->data[SC_MATKFOOD])
+ matk += sc->data[SC_MATKFOOD]->val1;
+ if(sc->data[SC_MAGICPOWER] && sc->data[SC_MAGICPOWER]->val4)
+ matk += matk * sc->data[SC_MAGICPOWER]->val3/100;
+ if(sc->data[SC_MINDBREAKER])
+ matk += matk * sc->data[SC_MINDBREAKER]->val2/100;
+ if(sc->data[SC_INCMATKRATE])
+ matk += matk * sc->data[SC_INCMATKRATE]->val1/100;
+ if(sc->data[SC_MOONLITSERENADE])
+ matk += matk * sc->data[SC_MOONLITSERENADE]->val2/100;
+ if(sc->data[SC_MELODYOFSINK])
+ matk += matk * sc->data[SC_MELODYOFSINK]->val3/100;
+ if(sc->data[SC_BEYONDOFWARCRY])
+ matk -= matk * sc->data[SC_BEYONDOFWARCRY]->val3/100;
+ if(sc->data[SC_MANA_PLUS])
+ matk += sc->data[SC_MANA_PLUS]->val1;
+ if(sc->data[SC_AQUAPLAY_OPTION])
+ matk += sc->data[SC_AQUAPLAY_OPTION]->val2;
+ if(sc->data[SC_CHILLY_AIR_OPTION])
+ matk += sc->data[SC_CHILLY_AIR_OPTION]->val2;
+ if(sc->data[SC_WATER_BARRIER])
+ matk -= sc->data[SC_WATER_BARRIER]->val3;
+ if(sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 3)
+ matk += 50;
+ if(sc->data[SC_ODINS_POWER])
+ matk += 40 + 30 * sc->data[SC_ODINS_POWER]->val1; //70 lvl1, 100lvl2
+ if(sc->data[SC_IZAYOI])
+ matk += 50 * sc->data[SC_IZAYOI]->val1;
+ if( sc->data[SC_ZANGETSU] )
+ matk += matk * sc->data[SC_ZANGETSU]->val2 / 100;
+
+ return (unsigned short)cap_value(matk,0,USHRT_MAX);
}
-static signed short status_calc_critical(struct block_list *bl, struct status_change *sc, int critical)
-{
-
- if (!sc || !sc->count)
- return cap_value(critical,10,SHRT_MAX);
-
- if (sc->data[SC_INCCRI])
- critical += sc->data[SC_INCCRI]->val2;
- if (sc->data[SC_EXPLOSIONSPIRITS])
- critical += sc->data[SC_EXPLOSIONSPIRITS]->val2;
- if (sc->data[SC_FORTUNE])
- critical += sc->data[SC_FORTUNE]->val2;
- if (sc->data[SC_TRUESIGHT])
- critical += sc->data[SC_TRUESIGHT]->val2;
- if (sc->data[SC_CLOAKING])
- critical += critical;
- if (sc->data[SC_STRIKING])
- critical += sc->data[SC_STRIKING]->val1;
- if (sc->data[SC__INVISIBILITY])
- critical += critical * sc->data[SC__INVISIBILITY]->val3 / 100;
- if (sc->data[SC__UNLUCKY])
- critical -= critical * sc->data[SC__UNLUCKY]->val2 / 100;
+static signed short status_calc_critical(struct block_list *bl, struct status_change *sc, int critical) {
+
+ if(!sc || !sc->count)
+ return cap_value(critical,10,SHRT_MAX);
+
+ if (sc->data[SC_INCCRI])
+ critical += sc->data[SC_INCCRI]->val2;
+ if (sc->data[SC_EXPLOSIONSPIRITS])
+ critical += sc->data[SC_EXPLOSIONSPIRITS]->val2;
+ if (sc->data[SC_FORTUNE])
+ critical += sc->data[SC_FORTUNE]->val2;
+ if (sc->data[SC_TRUESIGHT])
+ critical += sc->data[SC_TRUESIGHT]->val2;
+ if(sc->data[SC_CLOAKING])
+ critical += critical;
+ if(sc->data[SC_STRIKING])
+ critical += sc->data[SC_STRIKING]->val1;
+ if(sc->data[SC__INVISIBILITY])
+ critical += critical * sc->data[SC__INVISIBILITY]->val3 / 100;
+ if(sc->data[SC__UNLUCKY])
+ critical -= critical * sc->data[SC__UNLUCKY]->val2 / 100;
#ifdef RENEWAL
- if (sc->data[SC_SPEARQUICKEN])
- critical += 3*sc->data[SC_SPEARQUICKEN]->val1*10;
+ if (sc->data[SC_SPEARQUICKEN])
+ critical += 3*sc->data[SC_SPEARQUICKEN]->val1*10;
#endif
- return (short)cap_value(critical,10,SHRT_MAX);
+ return (short)cap_value(critical,10,SHRT_MAX);
}
static signed short status_calc_hit(struct block_list *bl, struct status_change *sc, int hit)
{
- if (!sc || !sc->count)
- return cap_value(hit,1,SHRT_MAX);
-
- if (sc->data[SC_INCHIT])
- hit += sc->data[SC_INCHIT]->val1;
- if (sc->data[SC_HITFOOD])
- hit += sc->data[SC_HITFOOD]->val1;
- if (sc->data[SC_TRUESIGHT])
- hit += sc->data[SC_TRUESIGHT]->val3;
- if (sc->data[SC_HUMMING])
- hit += sc->data[SC_HUMMING]->val2;
- if (sc->data[SC_CONCENTRATION])
- hit += sc->data[SC_CONCENTRATION]->val3;
- if (sc->data[SC_INCHITRATE])
- hit += hit * sc->data[SC_INCHITRATE]->val1/100;
- if (sc->data[SC_BLIND])
- hit -= hit * 25/100;
- if (sc->data[SC_ADJUSTMENT])
- hit -= 30;
- if (sc->data[SC_INCREASING])
- hit += 20; // RockmanEXE; changed based on updated [Reddozen]
- if (sc->data[SC_MERC_HITUP])
- hit += sc->data[SC_MERC_HITUP]->val2;
- if (sc->data[SC__GROOMY])
- hit -= hit * sc->data[SC__GROOMY]->val3 / 100;
- if (sc->data[SC_FEAR])
- hit -= hit * 20 / 100;
- if (sc->data[SC_INSPIRATION])
- hit += 5 * sc->data[SC_INSPIRATION]->val1;
- if (sc->data[SC_ASH])
- hit /= 2;
-
- return (short)cap_value(hit,1,SHRT_MAX);
+ if(!sc || !sc->count)
+ return cap_value(hit,1,SHRT_MAX);
+
+ if(sc->data[SC_INCHIT])
+ hit += sc->data[SC_INCHIT]->val1;
+ if(sc->data[SC_HITFOOD])
+ hit += sc->data[SC_HITFOOD]->val1;
+ if(sc->data[SC_TRUESIGHT])
+ hit += sc->data[SC_TRUESIGHT]->val3;
+ if(sc->data[SC_HUMMING])
+ hit += sc->data[SC_HUMMING]->val2;
+ if(sc->data[SC_CONCENTRATION])
+ hit += sc->data[SC_CONCENTRATION]->val3;
+ if(sc->data[SC_INCHITRATE])
+ hit += hit * sc->data[SC_INCHITRATE]->val1/100;
+ if(sc->data[SC_BLIND])
+ hit -= hit * 25/100;
+ if(sc->data[SC_ADJUSTMENT])
+ hit -= 30;
+ if(sc->data[SC_INCREASING])
+ hit += 20; // RockmanEXE; changed based on updated [Reddozen]
+ if(sc->data[SC_MERC_HITUP])
+ hit += sc->data[SC_MERC_HITUP]->val2;
+ if(sc->data[SC__GROOMY])
+ hit -= hit * sc->data[SC__GROOMY]->val3 / 100;
+ if(sc->data[SC_FEAR])
+ hit -= hit * 20 / 100;
+ if(sc->data[SC_INSPIRATION])
+ hit += 5 * sc->data[SC_INSPIRATION]->val1;
+ if (sc->data[SC_ASH])
+ hit /= 2;
+
+ return (short)cap_value(hit,1,SHRT_MAX);
}
static signed short status_calc_flee(struct block_list *bl, struct status_change *sc, int flee)
{
- if (bl->type == BL_PC) {
- if (map_flag_gvg(bl->m))
- flee -= flee * battle_config.gvg_flee_penalty/100;
- else if (map[bl->m].flag.battleground)
- flee -= flee * battle_config.bg_flee_penalty/100;
- }
-
- if (!sc || !sc->count)
- return cap_value(flee,1,SHRT_MAX);
-
- if (sc->data[SC_INCFLEE])
- flee += sc->data[SC_INCFLEE]->val1;
- if (sc->data[SC_FLEEFOOD])
- flee += sc->data[SC_FLEEFOOD]->val1;
- if (sc->data[SC_WHISTLE])
- flee += sc->data[SC_WHISTLE]->val2;
- if (sc->data[SC_WINDWALK])
- flee += sc->data[SC_WINDWALK]->val2;
- if (sc->data[SC_INCFLEERATE])
- flee += flee * sc->data[SC_INCFLEERATE]->val1/100;
- if (sc->data[SC_VIOLENTGALE])
- flee += sc->data[SC_VIOLENTGALE]->val2;
- if (sc->data[SC_MOON_COMFORT]) //SG skill [Komurka]
- flee += sc->data[SC_MOON_COMFORT]->val2;
- if (sc->data[SC_CLOSECONFINE])
- flee += 10;
- if (sc->data[SC_SPIDERWEB] && sc->data[SC_SPIDERWEB]->val1)
- flee -= flee * 50/100;
- if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
- flee -= flee * 50/100;
- if (sc->data[SC_BLIND])
- flee -= flee * 25/100;
- if (sc->data[SC_ADJUSTMENT])
- flee += 30;
- if (sc->data[SC_GATLINGFEVER])
- flee -= sc->data[SC_GATLINGFEVER]->val4;
- if (sc->data[SC_SPEED])
- flee += 10 + sc->data[SC_SPEED]->val1 * 10;
- if (sc->data[SC_PARTYFLEE])
- flee += sc->data[SC_PARTYFLEE]->val1 * 10;
- if (sc->data[SC_MERC_FLEEUP])
- flee += sc->data[SC_MERC_FLEEUP]->val2;
- if (sc->data[SC_FEAR])
- flee -= flee * 20 / 100;
- if (sc->data[SC_PARALYSE])
- flee -= flee * 10 / 100; // 10% Flee reduction
- if (sc->data[SC_INFRAREDSCAN])
- flee -= flee * 30 / 100;
- if (sc->data[SC__LAZINESS])
- flee -= flee * sc->data[SC__LAZINESS]->val3 / 100;
- if (sc->data[SC_GLOOMYDAY])
- flee -= flee * sc->data[SC_GLOOMYDAY]->val2 / 100;
- if (sc->data[SC_HALLUCINATIONWALK])
- flee += sc->data[SC_HALLUCINATIONWALK]->val2;
- if (sc->data[SC_SATURDAYNIGHTFEVER])
- flee -= flee * (40 + 10 * sc->data[SC_SATURDAYNIGHTFEVER]->val1) / 100;
- if (sc->data[SC_WATER_BARRIER])
- flee -= sc->data[SC_WATER_BARRIER]->val3;
- if (sc->data[SC_WIND_STEP_OPTION])
- flee += flee * sc->data[SC_WIND_STEP_OPTION]->val2 / 100;
- if (sc->data[SC_ZEPHYR])
- flee += flee * sc->data[SC_ZEPHYR]->val2 / 100;
- if (sc->data[SC_MARSHOFABYSS])
- flee -= (9 * sc->data[SC_MARSHOFABYSS]->val3 / 10 + sc->data[SC_MARSHOFABYSS]->val2 / 10) * (bl->type == BL_MOB ? 2 : 1);
+ if( bl->type == BL_PC )
+ {
+ if( map_flag_gvg(bl->m) )
+ flee -= flee * battle_config.gvg_flee_penalty/100;
+ else if( map[bl->m].flag.battleground )
+ flee -= flee * battle_config.bg_flee_penalty/100;
+ }
+
+ if(!sc || !sc->count)
+ return cap_value(flee,1,SHRT_MAX);
+
+ if(sc->data[SC_INCFLEE])
+ flee += sc->data[SC_INCFLEE]->val1;
+ if(sc->data[SC_FLEEFOOD])
+ flee += sc->data[SC_FLEEFOOD]->val1;
+ if(sc->data[SC_WHISTLE])
+ flee += sc->data[SC_WHISTLE]->val2;
+ if(sc->data[SC_WINDWALK])
+ flee += sc->data[SC_WINDWALK]->val2;
+ if(sc->data[SC_INCFLEERATE])
+ flee += flee * sc->data[SC_INCFLEERATE]->val1/100;
+ if(sc->data[SC_VIOLENTGALE])
+ flee += sc->data[SC_VIOLENTGALE]->val2;
+ if(sc->data[SC_MOON_COMFORT]) //SG skill [Komurka]
+ flee += sc->data[SC_MOON_COMFORT]->val2;
+ if(sc->data[SC_CLOSECONFINE])
+ flee += 10;
+ if(sc->data[SC_SPIDERWEB] && sc->data[SC_SPIDERWEB]->val1)
+ flee -= flee * 50/100;
+ if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
+ flee -= flee * 50/100;
+ if(sc->data[SC_BLIND])
+ flee -= flee * 25/100;
+ if(sc->data[SC_ADJUSTMENT])
+ flee += 30;
+ if(sc->data[SC_GATLINGFEVER])
+ flee -= sc->data[SC_GATLINGFEVER]->val4;
+ if(sc->data[SC_SPEED])
+ flee += 10 + sc->data[SC_SPEED]->val1 * 10;
+ if(sc->data[SC_PARTYFLEE])
+ flee += sc->data[SC_PARTYFLEE]->val1 * 10;
+ if(sc->data[SC_MERC_FLEEUP])
+ flee += sc->data[SC_MERC_FLEEUP]->val2;
+ if(sc->data[SC_FEAR])
+ flee -= flee * 20 / 100;
+ if(sc->data[SC_PARALYSE])
+ flee -= flee * 10 / 100; // 10% Flee reduction
+ if(sc->data[SC_INFRAREDSCAN])
+ flee -= flee * 30 / 100;
+ if( sc->data[SC__LAZINESS] )
+ flee -= flee * sc->data[SC__LAZINESS]->val3 / 100;
+ if( sc->data[SC_GLOOMYDAY] )
+ flee -= flee * sc->data[SC_GLOOMYDAY]->val2 / 100;
+ if( sc->data[SC_HALLUCINATIONWALK] )
+ flee += sc->data[SC_HALLUCINATIONWALK]->val2;
+ if( sc->data[SC_SATURDAYNIGHTFEVER] )
+ flee -= flee * (40 + 10 * sc->data[SC_SATURDAYNIGHTFEVER]->val1) / 100;
+ if( sc->data[SC_WATER_BARRIER] )
+ flee -= sc->data[SC_WATER_BARRIER]->val3;
+ if( sc->data[SC_WIND_STEP_OPTION] )
+ flee += flee * sc->data[SC_WIND_STEP_OPTION]->val2 / 100;
+ if( sc->data[SC_ZEPHYR] )
+ flee += flee * sc->data[SC_ZEPHYR]->val2 / 100;
+ if( sc->data[SC_MARSHOFABYSS] )
+ flee -= (9 * sc->data[SC_MARSHOFABYSS]->val3 / 10 + sc->data[SC_MARSHOFABYSS]->val2 / 10) * (bl->type == BL_MOB ? 2 : 1);
#ifdef RENEWAL
- if (sc->data[SC_SPEARQUICKEN])
- flee += 2 * sc->data[SC_SPEARQUICKEN]->val1;
+ if( sc->data[SC_SPEARQUICKEN] )
+ flee += 2 * sc->data[SC_SPEARQUICKEN]->val1;
#endif
- if (sc->data[SC_ANGRIFFS_MODUS])
- flee -= sc->data[SC_ANGRIFFS_MODUS]->val3;
- if (sc->data[SC_OVERED_BOOST])
- flee = max(flee,sc->data[SC_OVERED_BOOST]->val2);
- if (sc->data[SC_ASH] && (bl->type==BL_MOB)) { //mob
- if (status_get_element(bl) == ELE_WATER) //water type
- flee /= 2;
- }
-
- return (short)cap_value(flee,1,SHRT_MAX);
+ if (sc->data[SC_ANGRIFFS_MODUS])
+ flee -= sc->data[SC_ANGRIFFS_MODUS]->val3;
+ if (sc->data[SC_OVERED_BOOST])
+ flee = max(flee,sc->data[SC_OVERED_BOOST]->val2);
+ if(sc->data[SC_ASH] && (bl->type==BL_MOB)){ //mob
+ if(status_get_element(bl) == ELE_WATER) //water type
+ flee /= 2;
+ }
+
+ return (short)cap_value(flee,1,SHRT_MAX);
}
static signed short status_calc_flee2(struct block_list *bl, struct status_change *sc, int flee2)
{
- if (!sc || !sc->count)
- return cap_value(flee2,10,SHRT_MAX);
+ if(!sc || !sc->count)
+ return cap_value(flee2,10,SHRT_MAX);
- if (sc->data[SC_INCFLEE2])
- flee2 += sc->data[SC_INCFLEE2]->val2;
- if (sc->data[SC_WHISTLE])
- flee2 += sc->data[SC_WHISTLE]->val3*10;
- if (sc->data[SC__UNLUCKY])
- flee2 -= flee2 * sc->data[SC__UNLUCKY]->val2 / 100;
+ if(sc->data[SC_INCFLEE2])
+ flee2 += sc->data[SC_INCFLEE2]->val2;
+ if(sc->data[SC_WHISTLE])
+ flee2 += sc->data[SC_WHISTLE]->val3*10;
+ if(sc->data[SC__UNLUCKY])
+ flee2 -= flee2 * sc->data[SC__UNLUCKY]->val2 / 100;
- return (short)cap_value(flee2,10,SHRT_MAX);
+ return (short)cap_value(flee2,10,SHRT_MAX);
}
-static defType status_calc_def(struct block_list *bl, struct status_change *sc, int def)
-{
-
- if (!sc || !sc->count)
- return (defType)cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX);
-
- if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
- return 0;
- if (sc->data[SC_SKA])
- return sc->data[SC_SKA]->val3;
- if (sc->data[SC_BARRIER])
- return 100;
- if (sc->data[SC_KEEPING])
- return 90;
+static defType status_calc_def(struct block_list *bl, struct status_change *sc, int def) {
+
+ if(!sc || !sc->count)
+ return (defType)cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX);
+
+ if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
+ return 0;
+ if(sc->data[SC_SKA])
+ return sc->data[SC_SKA]->val3;
+ if(sc->data[SC_BARRIER])
+ return 100;
+ if(sc->data[SC_KEEPING])
+ return 90;
#ifndef RENEWAL // does not provide 90 DEF in renewal mode
- if (sc->data[SC_STEELBODY])
- return 90;
+ if(sc->data[SC_STEELBODY])
+ return 90;
#endif
- if (sc->data[SC_ARMORCHANGE])
- def += sc->data[SC_ARMORCHANGE]->val2;
- if (sc->data[SC_DRUMBATTLE])
- def += sc->data[SC_DRUMBATTLE]->val3;
- if (sc->data[SC_DEFENCE]) //[orn]
- def += sc->data[SC_DEFENCE]->val2 ;
- if (sc->data[SC_INCDEFRATE])
- def += def * sc->data[SC_INCDEFRATE]->val1/100;
- if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
- def >>=1;
- if (sc->data[SC_FREEZE])
- def >>=1;
+ if(sc->data[SC_ARMORCHANGE])
+ def += sc->data[SC_ARMORCHANGE]->val2;
+ if(sc->data[SC_DRUMBATTLE])
+ def += sc->data[SC_DRUMBATTLE]->val3;
+ if(sc->data[SC_DEFENCE]) //[orn]
+ def += sc->data[SC_DEFENCE]->val2 ;
+ if(sc->data[SC_INCDEFRATE])
+ def += def * sc->data[SC_INCDEFRATE]->val1/100;
+ if(sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
+ def >>=1;
+ if(sc->data[SC_FREEZE])
+ def >>=1;
#ifdef RENEWAL
- if (sc->data[SC_ASSUMPTIO])
- def *= 2;
+ if(sc->data[SC_ASSUMPTIO])
+ def *= 2;
#endif
- if (sc->data[SC_SIGNUMCRUCIS])
- def -= def * sc->data[SC_SIGNUMCRUCIS]->val2/100;
- if (sc->data[SC_CONCENTRATION])
- def -= def * sc->data[SC_CONCENTRATION]->val4/100;
- if (sc->data[SC_SKE])
- def >>=1;
- if (sc->data[SC_PROVOKE] && bl->type != BL_PC) // Provoke doesn't alter player defense->
- def -= def * sc->data[SC_PROVOKE]->val4/100;
- if (sc->data[SC_STRIPSHIELD])
- def -= def * sc->data[SC_STRIPSHIELD]->val2/100;
- if (sc->data[SC_FLING])
- def -= def * (sc->data[SC_FLING]->val2)/100;
- if (sc->data[SC_STONEHARDSKIN]) // Final DEF increase divided by 10 since were using classic (pre-renewal) mechanics. [Rytech]
- def += sc->data[SC_STONEHARDSKIN]->val1;
- if (sc->data[SC_FREEZING])
- def -= def * 10 / 100;
- if (sc->data[SC_MARSHOFABYSS])
- def -= def * (6 + 6 * sc->data[SC_MARSHOFABYSS]->val3/10 + (bl->type == BL_MOB ? 5 : 3) * sc->data[SC_MARSHOFABYSS]->val2/36) / 100;
- if (sc->data[SC_ANALYZE])
- def -= def * (14 * sc->data[SC_ANALYZE]->val1) / 100;
- if (sc->data[SC_FORCEOFVANGUARD])
- def += def * 2 * sc->data[SC_FORCEOFVANGUARD]->val1 / 100;
- if (sc->data[SC_SATURDAYNIGHTFEVER])
- def -= def * (10 + 10 * sc->data[SC_SATURDAYNIGHTFEVER]->val1) / 100;
- if (sc->data[SC_EARTHDRIVE])
- def -= def * 25 / 100;
- if (sc->data[SC_ROCK_CRUSHER])
- def -= def * sc->data[SC_ROCK_CRUSHER]->val2 / 100;
- if (sc->data[SC_POWER_OF_GAIA])
- def += def * sc->data[SC_POWER_OF_GAIA]->val2 / 100;
- if (sc->data[SC_PRESTIGE])
- def += def * sc->data[SC_PRESTIGE]->val1 / 100;
- if (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2)
- def += 50;
- if (sc->data[SC_ODINS_POWER])
- def -= 20;
- if (sc->data[SC_ANGRIFFS_MODUS])
- def -= 30 + 20 * sc->data[SC_ANGRIFFS_MODUS]->val1;
- if (sc->data[SC_ASH] && (bl->type==BL_MOB)) {
- if (status_get_race(bl)==RC_PLANT)
- def /= 2;
- }
-
- return (defType)cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX);;
+ if(sc->data[SC_SIGNUMCRUCIS])
+ def -= def * sc->data[SC_SIGNUMCRUCIS]->val2/100;
+ if(sc->data[SC_CONCENTRATION])
+ def -= def * sc->data[SC_CONCENTRATION]->val4/100;
+ if(sc->data[SC_SKE])
+ def >>=1;
+ if(sc->data[SC_PROVOKE] && bl->type != BL_PC) // Provoke doesn't alter player defense->
+ def -= def * sc->data[SC_PROVOKE]->val4/100;
+ if(sc->data[SC_STRIPSHIELD])
+ def -= def * sc->data[SC_STRIPSHIELD]->val2/100;
+ if (sc->data[SC_FLING])
+ def -= def * (sc->data[SC_FLING]->val2)/100;
+ if(sc->data[SC_STONEHARDSKIN])// Final DEF increase divided by 10 since were using classic (pre-renewal) mechanics. [Rytech]
+ def += sc->data[SC_STONEHARDSKIN]->val1;
+ if( sc->data[SC_FREEZING] )
+ def -= def * 10 / 100;
+ if( sc->data[SC_MARSHOFABYSS] )
+ def -= def * ( 6 + 6 * sc->data[SC_MARSHOFABYSS]->val3/10 + (bl->type == BL_MOB ? 5 : 3) * sc->data[SC_MARSHOFABYSS]->val2/36 ) / 100;
+ if( sc->data[SC_ANALYZE] )
+ def -= def * ( 14 * sc->data[SC_ANALYZE]->val1 ) / 100;
+ if( sc->data[SC_FORCEOFVANGUARD] )
+ def += def * 2 * sc->data[SC_FORCEOFVANGUARD]->val1 / 100;
+ if(sc->data[SC_SATURDAYNIGHTFEVER])
+ def -= def * (10 + 10 * sc->data[SC_SATURDAYNIGHTFEVER]->val1) / 100;
+ if(sc->data[SC_EARTHDRIVE])
+ def -= def * 25 / 100;
+ if( sc->data[SC_ROCK_CRUSHER] )
+ def -= def * sc->data[SC_ROCK_CRUSHER]->val2 / 100;
+ if( sc->data[SC_POWER_OF_GAIA] )
+ def += def * sc->data[SC_POWER_OF_GAIA]->val2 / 100;
+ if( sc->data[SC_PRESTIGE] )
+ def += def * sc->data[SC_PRESTIGE]->val1 / 100;
+ if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2)
+ def += 50;
+ if(sc->data[SC_ODINS_POWER])
+ def -= 20;
+ if( sc->data[SC_ANGRIFFS_MODUS] )
+ def -= 30 + 20 * sc->data[SC_ANGRIFFS_MODUS]->val1;
+ if(sc->data[SC_ASH] && (bl->type==BL_MOB)){
+ if(status_get_race(bl)==RC_PLANT)
+ def /= 2;
+ }
+
+ return (defType)cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX);;
}
static signed short status_calc_def2(struct block_list *bl, struct status_change *sc, int def2)
{
- if (!sc || !sc->count)
+ if(!sc || !sc->count)
#ifdef RENEWAL
- return (short)cap_value(def2,SHRT_MIN,SHRT_MAX);
+ return (short)cap_value(def2,SHRT_MIN,SHRT_MAX);
#else
- return (short)cap_value(def2,1,SHRT_MAX);
+ return (short)cap_value(def2,1,SHRT_MAX);
#endif
- if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
- return 0;
- if (sc->data[SC_ETERNALCHAOS])
- return 0;
- if (sc->data[SC_SUN_COMFORT])
- def2 += sc->data[SC_SUN_COMFORT]->val2;
+ if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
+ return 0;
+ if(sc->data[SC_ETERNALCHAOS])
+ return 0;
+ if(sc->data[SC_SUN_COMFORT])
+ def2 += sc->data[SC_SUN_COMFORT]->val2;
- if (sc->data[SC_ANGELUS])
+ if(sc->data[SC_ANGELUS])
#ifdef RENEWAL //in renewal only the VIT stat bonus is boosted by angelus
- def2 += status_get_vit(bl) / 2 * sc->data[SC_ANGELUS]->val2/100;
+ def2 += status_get_vit(bl) / 2 * sc->data[SC_ANGELUS]->val2/100;
#else
- def2 += def2 * sc->data[SC_ANGELUS]->val2/100;
+ def2 += def2 * sc->data[SC_ANGELUS]->val2/100;
#endif
- if (sc->data[SC_CONCENTRATION])
- def2 -= def2 * sc->data[SC_CONCENTRATION]->val4/100;
- if (sc->data[SC_POISON])
- def2 -= def2 * 25/100;
- if (sc->data[SC_DPOISON])
- def2 -= def2 * 25/100;
- if (sc->data[SC_SKE])
- def2 -= def2 * 50/100;
- if (sc->data[SC_PROVOKE])
- def2 -= def2 * sc->data[SC_PROVOKE]->val4/100;
+ if(sc->data[SC_CONCENTRATION])
+ def2 -= def2 * sc->data[SC_CONCENTRATION]->val4/100;
+ if(sc->data[SC_POISON])
+ def2 -= def2 * 25/100;
+ if(sc->data[SC_DPOISON])
+ def2 -= def2 * 25/100;
+ if(sc->data[SC_SKE])
+ def2 -= def2 * 50/100;
+ if(sc->data[SC_PROVOKE])
+ def2 -= def2 * sc->data[SC_PROVOKE]->val4/100;
#ifdef RENEWAL
- if (sc->data[SC_ASSUMPTIO])
- def2 *= 2;
+ if(sc->data[SC_ASSUMPTIO])
+ def2 *= 2;
#endif
- if (sc->data[SC_JOINTBEAT])
- def2 -= def2 * (sc->data[SC_JOINTBEAT]->val2&BREAK_SHOULDER ? 50 : 0) / 100
- + def2 * (sc->data[SC_JOINTBEAT]->val2&BREAK_WAIST ? 25 : 0) / 100;
- if (sc->data[SC_FLING])
- def2 -= def2 * (sc->data[SC_FLING]->val3)/100;
- if (sc->data[SC_FREEZING])
- def2 -= def2 * 3 / 10;
- if (sc->data[SC_ANALYZE])
- def2 -= def2 * (14 * sc->data[SC_ANALYZE]->val1) / 100;
- if (sc->data[SC_ECHOSONG])
- def2 += def2 * sc->data[SC_ECHOSONG]->val2/100;
- if (sc->data[SC_SHIELDSPELL_REF] && sc->data[SC_SHIELDSPELL_REF]->val1 == 1)
- def2 += sc->data[SC_SHIELDSPELL_REF]->val2;
- if (sc->data[SC_BANDING] && sc->data[SC_BANDING]->val2 > 0)
- def2 += (5 + sc->data[SC_BANDING]->val1) * (sc->data[SC_BANDING]->val2);
- if (sc->data[SC_GT_REVITALIZE] && sc->data[SC_GT_REVITALIZE]->val4)
- def2 += def2 * sc->data[SC_GT_REVITALIZE]->val4 / 100;
- if (sc->data[SC_ASH] && (bl->type==BL_MOB)) {
- if (status_get_race(bl)==RC_PLANT)
- def2 /= 2;
- }
- if (sc->data[SC_PARALYSIS])
- def2 -= def2 * sc->data[SC_PARALYSIS]->val2 / 100;
+ if(sc->data[SC_JOINTBEAT])
+ def2 -= def2 * ( sc->data[SC_JOINTBEAT]->val2&BREAK_SHOULDER ? 50 : 0 ) / 100
+ + def2 * ( sc->data[SC_JOINTBEAT]->val2&BREAK_WAIST ? 25 : 0 ) / 100;
+ if(sc->data[SC_FLING])
+ def2 -= def2 * (sc->data[SC_FLING]->val3)/100;
+ if( sc->data[SC_FREEZING] )
+ def2 -= def2 * 3 / 10;
+ if(sc->data[SC_ANALYZE])
+ def2 -= def2 * ( 14 * sc->data[SC_ANALYZE]->val1 ) / 100;
+ if( sc->data[SC_ECHOSONG] )
+ def2 += def2 * sc->data[SC_ECHOSONG]->val2/100;
+ if( sc->data[SC_SHIELDSPELL_REF] && sc->data[SC_SHIELDSPELL_REF]->val1 == 1 )
+ def2 += sc->data[SC_SHIELDSPELL_REF]->val2;
+ if( sc->data[SC_BANDING] && sc->data[SC_BANDING]->val2 > 0 )
+ def2 += (5 + sc->data[SC_BANDING]->val1) * (sc->data[SC_BANDING]->val2);
+ if( sc->data[SC_GT_REVITALIZE] && sc->data[SC_GT_REVITALIZE]->val4)
+ def2 += def2 * sc->data[SC_GT_REVITALIZE]->val4 / 100;
+ if(sc->data[SC_ASH] && (bl->type==BL_MOB)){
+ if(status_get_race(bl)==RC_PLANT)
+ def2 /= 2;
+ }
+ if (sc->data[SC_PARALYSIS])
+ def2 -= def2 * sc->data[SC_PARALYSIS]->val2 / 100;
#ifdef RENEWAL
- return (short)cap_value(def2,SHRT_MIN,SHRT_MAX);
+ return (short)cap_value(def2,SHRT_MIN,SHRT_MAX);
#else
- return (short)cap_value(def2,1,SHRT_MAX);
+ return (short)cap_value(def2,1,SHRT_MAX);
#endif
}
-static defType status_calc_mdef(struct block_list *bl, struct status_change *sc, int mdef)
-{
+static defType status_calc_mdef(struct block_list *bl, struct status_change *sc, int mdef) {
- if (!sc || !sc->count)
- return (defType)cap_value(mdef,DEFTYPE_MIN,DEFTYPE_MAX);
+ if(!sc || !sc->count)
+ return (defType)cap_value(mdef,DEFTYPE_MIN,DEFTYPE_MAX);
- if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
- return 0;
- if (sc->data[SC_BARRIER])
- return 100;
+ if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
+ return 0;
+ if(sc->data[SC_BARRIER])
+ return 100;
#ifndef RENEWAL // no longer provides 90 MDEF in renewal mode
- if (sc->data[SC_STEELBODY])
- return 90;
+ if(sc->data[SC_STEELBODY])
+ return 90;
#endif
- if (sc->data[SC_ARMORCHANGE])
- mdef += sc->data[SC_ARMORCHANGE]->val3;
- if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
- mdef += 25*mdef/100;
- if (sc->data[SC_FREEZE])
- mdef += 25*mdef/100;
- if (sc->data[SC_ENDURE]) // It has been confirmed that eddga card grants 1 MDEF, not 0, not 10, but 1.
- mdef += (sc->data[SC_ENDURE]->val4 == 0) ? sc->data[SC_ENDURE]->val1 : 1;
- if (sc->data[SC_CONCENTRATION])
- mdef += 1; //Skill info says it adds a fixed 1 Mdef point.
+ if(sc->data[SC_ARMORCHANGE])
+ mdef += sc->data[SC_ARMORCHANGE]->val3;
+ if(sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
+ mdef += 25*mdef/100;
+ if(sc->data[SC_FREEZE])
+ mdef += 25*mdef/100;
+ if(sc->data[SC_ENDURE])// It has been confirmed that eddga card grants 1 MDEF, not 0, not 10, but 1.
+ mdef += (sc->data[SC_ENDURE]->val4 == 0) ? sc->data[SC_ENDURE]->val1 : 1;
+ if(sc->data[SC_CONCENTRATION])
+ mdef += 1; //Skill info says it adds a fixed 1 Mdef point.
#ifdef RENEWAL
- if (sc->data[SC_ASSUMPTIO])
- mdef *= 2;
+ if(sc->data[SC_ASSUMPTIO])
+ mdef *= 2;
#endif
- if (sc->data[SC_STONEHARDSKIN]) // Final MDEF increase divided by 10 since were using classic (pre-renewal) mechanics. [Rytech]
- mdef += sc->data[SC_STONEHARDSKIN]->val1;
- if (sc->data[SC_MARSHOFABYSS])
- mdef -= mdef * (6 + 6 * sc->data[SC_MARSHOFABYSS]->val3/10 + (bl->type == BL_MOB ? 5 : 3) * sc->data[SC_MARSHOFABYSS]->val2/36) / 100;
- if (sc->data[SC_ANALYZE])
- mdef -= mdef * (14 * sc->data[SC_ANALYZE]->val1) / 100;
- if (sc->data[SC_SYMPHONYOFLOVER])
- mdef += mdef * sc->data[SC_SYMPHONYOFLOVER]->val2 / 100;
- if (sc->data[SC_GT_CHANGE] && sc->data[SC_GT_CHANGE]->val4)
- mdef -= mdef * sc->data[SC_GT_CHANGE]->val4 / 100;
- if (sc->data[SC_WATER_BARRIER])
- mdef += sc->data[SC_WATER_BARRIER]->val2;
- if (sc->data[SC_ODINS_POWER])
- mdef -= 20 * sc->data[SC_ODINS_POWER]->val1;
- if (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 3)
- mdef += 50;
-
- return (defType)cap_value(mdef,DEFTYPE_MIN,DEFTYPE_MAX);
+ if(sc->data[SC_STONEHARDSKIN])// Final MDEF increase divided by 10 since were using classic (pre-renewal) mechanics. [Rytech]
+ mdef += sc->data[SC_STONEHARDSKIN]->val1;
+ if( sc->data[SC_MARSHOFABYSS] )
+ mdef -= mdef * ( 6 + 6 * sc->data[SC_MARSHOFABYSS]->val3/10 + (bl->type == BL_MOB ? 5 : 3) * sc->data[SC_MARSHOFABYSS]->val2/36 ) / 100;
+ if(sc->data[SC_ANALYZE])
+ mdef -= mdef * ( 14 * sc->data[SC_ANALYZE]->val1 ) / 100;
+ if(sc->data[SC_SYMPHONYOFLOVER])
+ mdef += mdef * sc->data[SC_SYMPHONYOFLOVER]->val2 / 100;
+ if(sc->data[SC_GT_CHANGE] && sc->data[SC_GT_CHANGE]->val4)
+ mdef -= mdef * sc->data[SC_GT_CHANGE]->val4 / 100;
+ if(sc->data[SC_WATER_BARRIER])
+ mdef += sc->data[SC_WATER_BARRIER]->val2;
+ if (sc->data[SC_ODINS_POWER])
+ mdef -= 20 * sc->data[SC_ODINS_POWER]->val1;
+ if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 3)
+ mdef += 50;
+
+ return (defType)cap_value(mdef,DEFTYPE_MIN,DEFTYPE_MAX);
}
static signed short status_calc_mdef2(struct block_list *bl, struct status_change *sc, int mdef2)
{
- if (!sc || !sc->count)
+ if(!sc || !sc->count)
#ifdef RENEWAL
- return (short)cap_value(mdef2,SHRT_MIN,SHRT_MAX);
+ return (short)cap_value(mdef2,SHRT_MIN,SHRT_MAX);
#else
- return (short)cap_value(mdef2,1,SHRT_MAX);
+ return (short)cap_value(mdef2,1,SHRT_MAX);
#endif
- if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
- return 0;
- if (sc->data[SC_SKA])
- return 90;
+ if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
+ return 0;
+ if(sc->data[SC_SKA])
+ return 90;
#ifdef RENEWAL
- if (sc->data[SC_ASSUMPTIO])
- mdef2 *= 2;
+ if(sc->data[SC_ASSUMPTIO])
+ mdef2 *= 2;
#endif
- if (sc->data[SC_MINDBREAKER])
- mdef2 -= mdef2 * sc->data[SC_MINDBREAKER]->val3/100;
- if (sc->data[SC_ANALYZE])
- mdef2 -= mdef2 * (14 * sc->data[SC_ANALYZE]->val1) / 100;
+ if(sc->data[SC_MINDBREAKER])
+ mdef2 -= mdef2 * sc->data[SC_MINDBREAKER]->val3/100;
+ if(sc->data[SC_ANALYZE])
+ mdef2 -= mdef2 * ( 14 * sc->data[SC_ANALYZE]->val1 ) / 100;
#ifdef RENEWAL
- return (short)cap_value(mdef2,SHRT_MIN,SHRT_MAX);
+ return (short)cap_value(mdef2,SHRT_MIN,SHRT_MAX);
#else
- return (short)cap_value(mdef2,1,SHRT_MAX);
+ return (short)cap_value(mdef2,1,SHRT_MAX);
#endif
}
static unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc, int speed)
{
- TBL_PC *sd = BL_CAST(BL_PC, bl);
- int speed_rate;
-
- if (sc == NULL)
- return cap_value(speed,10,USHRT_MAX);
-
- if (sd && sd->ud.skilltimer != INVALID_TIMER && (pc_checkskill(sd,SA_FREECAST) > 0 || sd->ud.skillid == LG_EXEEDBREAK)) {
- if (sd->ud.skillid == LG_EXEEDBREAK)
- speed_rate = 100 + 60 - (sd->ud.skilllv * 10);
- else
- speed_rate = 175 - 5 * pc_checkskill(sd,SA_FREECAST);
- } else {
- speed_rate = 100;
-
- //GetMoveHasteValue2()
- {
- int val = 0;
-
- if (sc->data[SC_FUSION])
- val = 25;
- else if (sd) {
- if (pc_isriding(sd) || sd->sc.option&(OPTION_DRAGON|OPTION_MOUNTING))
- val = 25;//Same bonus
- else if (pc_isridingwug(sd))
- val = 15 + 5 * pc_checkskill(sd, RA_WUGRIDER);
- else if (pc_ismadogear(sd)) {
- val = (- 10 * (5 - pc_checkskill(sd,NC_MADOLICENCE)));
- if (sc->data[SC_ACCELERATION])
- val += 25;
- }
- }
-
- speed_rate -= val;
- }
-
- //GetMoveSlowValue()
- {
- int val = 0;
-
- if (sd && sc->data[SC_HIDING] && pc_checkskill(sd,RG_TUNNELDRIVE) > 0)
- val = 120 - 6 * pc_checkskill(sd,RG_TUNNELDRIVE);
- else if (sd && sc->data[SC_CHASEWALK] && sc->data[SC_CHASEWALK]->val3 < 0)
- val = sc->data[SC_CHASEWALK]->val3;
- else {
- // Longing for Freedom cancels song/dance penalty
- if (sc->data[SC_LONGING])
- val = max(val, 50 - 10 * sc->data[SC_LONGING]->val1);
- else if (sd && sc->data[SC_DANCING])
- val = max(val, 500 - (40 + 10 * (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_BARDDANCER)) * pc_checkskill(sd,(sd->status.sex?BA_MUSICALLESSON:DC_DANCINGLESSON)));
-
- if (sc->data[SC_DECREASEAGI])
- val = max(val, 25);
- if (sc->data[SC_QUAGMIRE] || sc->data[SC_HALLUCINATIONWALK_POSTDELAY] || (sc->data[SC_GLOOMYDAY] && sc->data[SC_GLOOMYDAY]->val4))
- val = max(val, 50);
- if (sc->data[SC_DONTFORGETME])
- val = max(val, sc->data[SC_DONTFORGETME]->val3);
- if (sc->data[SC_CURSE])
- val = max(val, 300);
- if (sc->data[SC_CHASEWALK])
- val = max(val, sc->data[SC_CHASEWALK]->val3);
- if (sc->data[SC_WEDDING])
- val = max(val, 100);
- if (sc->data[SC_JOINTBEAT] && sc->data[SC_JOINTBEAT]->val2&(BREAK_ANKLE|BREAK_KNEE))
- val = max(val, (sc->data[SC_JOINTBEAT]->val2&BREAK_ANKLE ? 50 : 0) + (sc->data[SC_JOINTBEAT]->val2&BREAK_KNEE ? 30 : 0));
- if (sc->data[SC_CLOAKING] && (sc->data[SC_CLOAKING]->val4&1) == 0)
- val = max(val, sc->data[SC_CLOAKING]->val1 < 3 ? 300 : 30 - 3 * sc->data[SC_CLOAKING]->val1);
- if (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_ENEMY)
- val = max(val, 75);
- if (sc->data[SC_SLOWDOWN]) // Slow Potion
- val = max(val, 100);
- if (sc->data[SC_GATLINGFEVER])
- val = max(val, 100);
- if (sc->data[SC_SUITON])
- val = max(val, sc->data[SC_SUITON]->val3);
- if (sc->data[SC_SWOO])
- val = max(val, 300);
- if (sc->data[SC_FREEZING])
- val = max(val, 70);
- if (sc->data[SC_MARSHOFABYSS])
- val = max(val, 40 + 10 * sc->data[SC_MARSHOFABYSS]->val1);
- if (sc->data[SC_CAMOUFLAGE] && (sc->data[SC_CAMOUFLAGE]->val3&1) == 0)
- val = max(val, sc->data[SC_CAMOUFLAGE]->val1 < 3 ? 0 : 25 * (5 - sc->data[SC_CAMOUFLAGE]->val1));
- if (sc->data[SC__GROOMY])
- val = max(val, sc->data[SC__GROOMY]->val2);
- if (sc->data[SC_STEALTHFIELD_MASTER])
- val = max(val, 30);
- if (sc->data[SC_BANDING_DEFENCE])
- val = max(val, sc->data[SC_BANDING_DEFENCE]->val1); //+90% walking speed.
- if (sc->data[SC_ROCK_CRUSHER_ATK])
- val = max(val, sc->data[SC_ROCK_CRUSHER_ATK]->val2);
- if (sc->data[SC_POWER_OF_GAIA])
- val = max(val, sc->data[SC_POWER_OF_GAIA]->val2);
- if (sc->data[SC_MELON_BOMB])
- val = max(val, sc->data[SC_MELON_BOMB]->val1);
-
- if (sd && sd->bonus.speed_rate + sd->bonus.speed_add_rate > 0) // permanent item-based speedup
- val = max(val, sd->bonus.speed_rate + sd->bonus.speed_add_rate);
- }
+ TBL_PC* sd = BL_CAST(BL_PC, bl);
+ int speed_rate;
+
+ if( sc == NULL )
+ return cap_value(speed,10,USHRT_MAX);
+
+ if( sd && sd->ud.skilltimer != INVALID_TIMER && (pc_checkskill(sd,SA_FREECAST) > 0 || sd->ud.skillid == LG_EXEEDBREAK) )
+ {
+ if( sd->ud.skillid == LG_EXEEDBREAK )
+ speed_rate = 100 + 60 - (sd->ud.skilllv * 10);
+ else
+ speed_rate = 175 - 5 * pc_checkskill(sd,SA_FREECAST);
+ }
+ else
+ {
+ speed_rate = 100;
+
+ //GetMoveHasteValue2()
+ {
+ int val = 0;
+
+ if( sc->data[SC_FUSION] )
+ val = 25;
+ else if( sd ) {
+ if( pc_isriding(sd) || sd->sc.option&(OPTION_DRAGON|OPTION_MOUNTING) )
+ val = 25;//Same bonus
+ else if( pc_isridingwug(sd) )
+ val = 15 + 5 * pc_checkskill(sd, RA_WUGRIDER);
+ else if( pc_ismadogear(sd) ) {
+ val = (- 10 * (5 - pc_checkskill(sd,NC_MADOLICENCE)));
+ if( sc->data[SC_ACCELERATION] )
+ val += 25;
+ }
+ }
- speed_rate += val;
- }
+ speed_rate -= val;
+ }
- //GetMoveHasteValue1()
- {
- int val = 0;
-
- if (sc->data[SC_SPEEDUP1]) //FIXME: used both by NPC_AGIUP and Speed Potion script
- val = max(val, 50);
- if (sc->data[SC_INCREASEAGI])
- val = max(val, 25);
- if (sc->data[SC_WINDWALK])
- val = max(val, 2 * sc->data[SC_WINDWALK]->val1);
- if (sc->data[SC_CARTBOOST])
- val = max(val, 20);
- if (sd && (sd->class_&MAPID_UPPERMASK) == MAPID_ASSASSIN && pc_checkskill(sd,TF_MISS) > 0)
- val = max(val, 1 * pc_checkskill(sd,TF_MISS));
- if (sc->data[SC_CLOAKING] && (sc->data[SC_CLOAKING]->val4&1) == 1)
- val = max(val, sc->data[SC_CLOAKING]->val1 >= 10 ? 25 : 3 * sc->data[SC_CLOAKING]->val1 - 3);
- if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
- val = max(val, 25);
- if (sc->data[SC_RUN])
- val = max(val, 55);
- if (sc->data[SC_AVOID])
- val = max(val, 10 * sc->data[SC_AVOID]->val1);
- if (sc->data[SC_INVINCIBLE] && !sc->data[SC_INVINCIBLEOFF])
- val = max(val, 75);
- if (sc->data[SC_CLOAKINGEXCEED])
- val = max(val, sc->data[SC_CLOAKINGEXCEED]->val3);
- if (sc->data[SC_HOVERING])
- val = max(val, 10);
- if (sc->data[SC_GN_CARTBOOST])
- val = max(val, sc->data[SC_GN_CARTBOOST]->val2);
- if (sc->data[SC_SWINGDANCE])
- val = max(val, sc->data[SC_SWINGDANCE]->val2);
- if (sc->data[SC_WIND_STEP_OPTION])
- val = max(val, sc->data[SC_WIND_STEP_OPTION]->val2);
-
- //FIXME: official items use a single bonus for this [ultramage]
- if (sc->data[SC_SPEEDUP0]) // temporary item-based speedup
- val = max(val, 25);
- if (sd && sd->bonus.speed_rate + sd->bonus.speed_add_rate < 0) // permanent item-based speedup
- val = max(val, -(sd->bonus.speed_rate + sd->bonus.speed_add_rate));
-
- speed_rate -= val;
- }
+ //GetMoveSlowValue()
+ {
+ int val = 0;
+
+ if( sd && sc->data[SC_HIDING] && pc_checkskill(sd,RG_TUNNELDRIVE) > 0 )
+ val = 120 - 6 * pc_checkskill(sd,RG_TUNNELDRIVE);
+ else
+ if( sd && sc->data[SC_CHASEWALK] && sc->data[SC_CHASEWALK]->val3 < 0 )
+ val = sc->data[SC_CHASEWALK]->val3;
+ else
+ {
+ // Longing for Freedom cancels song/dance penalty
+ if( sc->data[SC_LONGING] )
+ val = max( val, 50 - 10 * sc->data[SC_LONGING]->val1 );
+ else
+ if( sd && sc->data[SC_DANCING] )
+ val = max( val, 500 - (40 + 10 * (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_BARDDANCER)) * pc_checkskill(sd,(sd->status.sex?BA_MUSICALLESSON:DC_DANCINGLESSON)) );
+
+ if( sc->data[SC_DECREASEAGI] )
+ val = max( val, 25 );
+ if( sc->data[SC_QUAGMIRE] || sc->data[SC_HALLUCINATIONWALK_POSTDELAY] || (sc->data[SC_GLOOMYDAY] && sc->data[SC_GLOOMYDAY]->val4) )
+ val = max( val, 50 );
+ if( sc->data[SC_DONTFORGETME] )
+ val = max( val, sc->data[SC_DONTFORGETME]->val3 );
+ if( sc->data[SC_CURSE] )
+ val = max( val, 300 );
+ if( sc->data[SC_CHASEWALK] )
+ val = max( val, sc->data[SC_CHASEWALK]->val3 );
+ if( sc->data[SC_WEDDING] )
+ val = max( val, 100 );
+ if( sc->data[SC_JOINTBEAT] && sc->data[SC_JOINTBEAT]->val2&(BREAK_ANKLE|BREAK_KNEE) )
+ val = max( val, (sc->data[SC_JOINTBEAT]->val2&BREAK_ANKLE ? 50 : 0) + (sc->data[SC_JOINTBEAT]->val2&BREAK_KNEE ? 30 : 0) );
+ if( sc->data[SC_CLOAKING] && (sc->data[SC_CLOAKING]->val4&1) == 0 )
+ val = max( val, sc->data[SC_CLOAKING]->val1 < 3 ? 300 : 30 - 3 * sc->data[SC_CLOAKING]->val1 );
+ if( sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_ENEMY )
+ val = max( val, 75 );
+ if( sc->data[SC_SLOWDOWN] ) // Slow Potion
+ val = max( val, 100 );
+ if( sc->data[SC_GATLINGFEVER] )
+ val = max( val, 100 );
+ if( sc->data[SC_SUITON] )
+ val = max( val, sc->data[SC_SUITON]->val3 );
+ if( sc->data[SC_SWOO] )
+ val = max( val, 300 );
+ if( sc->data[SC_FREEZING] )
+ val = max( val, 70 );
+ if( sc->data[SC_MARSHOFABYSS] )
+ val = max( val, 40 + 10 * sc->data[SC_MARSHOFABYSS]->val1 );
+ if( sc->data[SC_CAMOUFLAGE] && (sc->data[SC_CAMOUFLAGE]->val3&1) == 0 )
+ val = max( val, sc->data[SC_CAMOUFLAGE]->val1 < 3 ? 0 : 25 * (5 - sc->data[SC_CAMOUFLAGE]->val1) );
+ if( sc->data[SC__GROOMY] )
+ val = max( val, sc->data[SC__GROOMY]->val2);
+ if( sc->data[SC_STEALTHFIELD_MASTER] )
+ val = max( val, 30 );
+ if( sc->data[SC_BANDING_DEFENCE] )
+ val = max( val, sc->data[SC_BANDING_DEFENCE]->val1 );//+90% walking speed.
+ if( sc->data[SC_ROCK_CRUSHER_ATK] )
+ val = max( val, sc->data[SC_ROCK_CRUSHER_ATK]->val2 );
+ if( sc->data[SC_POWER_OF_GAIA] )
+ val = max( val, sc->data[SC_POWER_OF_GAIA]->val2 );
+ if( sc->data[SC_MELON_BOMB] )
+ val = max( val, sc->data[SC_MELON_BOMB]->val1 );
+
+ if( sd && sd->bonus.speed_rate + sd->bonus.speed_add_rate > 0 ) // permanent item-based speedup
+ val = max( val, sd->bonus.speed_rate + sd->bonus.speed_add_rate );
+ }
- if (speed_rate < 40)
- speed_rate = 40;
- }
+ speed_rate += val;
+ }
- //GetSpeed()
- {
- if (sd && pc_iscarton(sd))
- speed += speed * (50 - 5 * pc_checkskill(sd,MC_PUSHCART)) / 100;
- if (sc->data[SC_PARALYSE])
- speed += speed * 50 / 100;
- if (speed_rate != 100)
- speed = speed * speed_rate / 100;
- if (sc->data[SC_STEELBODY])
- speed = 200;
- if (sc->data[SC_DEFENDER])
- speed = max(speed, 200);
- if (sc->data[SC_WALKSPEED] && sc->data[SC_WALKSPEED]->val1 > 0) // ChangeSpeed
- speed = speed * 100 / sc->data[SC_WALKSPEED]->val1;
- }
+ //GetMoveHasteValue1()
+ {
+ int val = 0;
+
+ if( sc->data[SC_SPEEDUP1] ) //FIXME: used both by NPC_AGIUP and Speed Potion script
+ val = max( val, 50 );
+ if( sc->data[SC_INCREASEAGI] )
+ val = max( val, 25 );
+ if( sc->data[SC_WINDWALK] )
+ val = max( val, 2 * sc->data[SC_WINDWALK]->val1 );
+ if( sc->data[SC_CARTBOOST] )
+ val = max( val, 20 );
+ if( sd && (sd->class_&MAPID_UPPERMASK) == MAPID_ASSASSIN && pc_checkskill(sd,TF_MISS) > 0 )
+ val = max( val, 1 * pc_checkskill(sd,TF_MISS) );
+ if( sc->data[SC_CLOAKING] && (sc->data[SC_CLOAKING]->val4&1) == 1 )
+ val = max( val, sc->data[SC_CLOAKING]->val1 >= 10 ? 25 : 3 * sc->data[SC_CLOAKING]->val1 - 3 );
+ if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
+ val = max( val, 25 );
+ if( sc->data[SC_RUN] )
+ val = max( val, 55 );
+ if( sc->data[SC_AVOID] )
+ val = max( val, 10 * sc->data[SC_AVOID]->val1 );
+ if( sc->data[SC_INVINCIBLE] && !sc->data[SC_INVINCIBLEOFF] )
+ val = max( val, 75 );
+ if( sc->data[SC_CLOAKINGEXCEED] )
+ val = max( val, sc->data[SC_CLOAKINGEXCEED]->val3);
+ if( sc->data[SC_HOVERING] )
+ val = max( val, 10 );
+ if( sc->data[SC_GN_CARTBOOST] )
+ val = max( val, sc->data[SC_GN_CARTBOOST]->val2 );
+ if( sc->data[SC_SWINGDANCE] )
+ val = max( val, sc->data[SC_SWINGDANCE]->val2 );
+ if( sc->data[SC_WIND_STEP_OPTION] )
+ val = max( val, sc->data[SC_WIND_STEP_OPTION]->val2 );
+
+ //FIXME: official items use a single bonus for this [ultramage]
+ if( sc->data[SC_SPEEDUP0] ) // temporary item-based speedup
+ val = max( val, 25 );
+ if( sd && sd->bonus.speed_rate + sd->bonus.speed_add_rate < 0 ) // permanent item-based speedup
+ val = max( val, -(sd->bonus.speed_rate + sd->bonus.speed_add_rate) );
+
+ speed_rate -= val;
+ }
- return (short)cap_value(speed,10,USHRT_MAX);
+ if( speed_rate < 40 )
+ speed_rate = 40;
+ }
+
+ //GetSpeed()
+ {
+ if( sd && pc_iscarton(sd) )
+ speed += speed * (50 - 5 * pc_checkskill(sd,MC_PUSHCART)) / 100;
+ if( sc->data[SC_PARALYSE] )
+ speed += speed * 50 / 100;
+ if( speed_rate != 100 )
+ speed = speed * speed_rate / 100;
+ if( sc->data[SC_STEELBODY] )
+ speed = 200;
+ if( sc->data[SC_DEFENDER] )
+ speed = max(speed, 200);
+ if( sc->data[SC_WALKSPEED] && sc->data[SC_WALKSPEED]->val1 > 0 ) // ChangeSpeed
+ speed = speed * 100 / sc->data[SC_WALKSPEED]->val1;
+ }
+
+ return (short)cap_value(speed,10,USHRT_MAX);
}
#ifdef RENEWAL_ASPD
@@ -5187,125 +5146,126 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
// flag&2 - percentage value
static short status_calc_aspd(struct block_list *bl, struct status_change *sc, short flag)
{
- int i, pots = 0, skills1 = 0, skills2 = 0;
-
- if (!sc || !sc->count)
- return 0;
-
- if (sc->data[i=SC_ASPDPOTION3] ||
- sc->data[i=SC_ASPDPOTION2] ||
- sc->data[i=SC_ASPDPOTION1] ||
- sc->data[i=SC_ASPDPOTION0])
- pots += sc->data[i]->val1;
-
- if (!sc->data[SC_QUAGMIRE]) {
- if (sc->data[SC_STAR_COMFORT])
- skills1 = 5; // needs more info
-
- if (sc->data[SC_TWOHANDQUICKEN] && skills1 < 7)
- skills1 = 7;
-
- if (sc->data[SC_ONEHAND] && skills1 < 7) skills1 = 7;
-
- if (sc->data[SC_MERC_QUICKEN] && skills1 < 7) // needs more info
- skills1 = 7;
-
- if (sc->data[SC_ADRENALINE2] && skills1 < 6)
- skills1 = 6;
-
- if (sc->data[SC_ADRENALINE] && skills1 < 7)
- skills1 = 7;
-
- if (sc->data[SC_SPEARQUICKEN] && skills1 < 7)
- skills1 = 7;
-
- if (sc->data[SC_GATLINGFEVER] && skills1 < 9) // needs more info
- skills1 = 9;
-
- if (sc->data[SC_FLEET] && skills1 < 5)
- skills1 = 5;
-
- if (sc->data[SC_ASSNCROS] &&
- skills1 < 5+1*sc->data[SC_ASSNCROS]->val1) { // needs more info
- if (bl->type!=BL_PC)
- skills1 = 4+1*sc->data[SC_ASSNCROS]->val1;
- else
- switch (((TBL_PC *)bl)->status.weapon) {
- case W_BOW:
- case W_REVOLVER:
- case W_RIFLE:
- case W_GATLING:
- case W_SHOTGUN:
- case W_GRENADE:
- break;
- default:
- skills1 = 5+1*sc->data[SC_ASSNCROS]->val1;
- }
- }
- }
-
- if ((sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]) && skills1 < 15)
- skills1 = 15;
- else if (sc->data[SC_MADNESSCANCEL] && skills1 < 15) // needs more info
- skills1 = 15;
-
- if (sc->data[SC_DONTFORGETME])
- skills2 -= sc->data[SC_DONTFORGETME]->val2; // needs more info
- if (sc->data[SC_LONGING])
- skills2 -= sc->data[SC_LONGING]->val2; // needs more info
- if (sc->data[SC_STEELBODY])
- skills2 -= 25;
- if (sc->data[SC_SKA])
- skills2 -= 25;
- if (sc->data[SC_DEFENDER])
- skills2 -= sc->data[SC_DEFENDER]->val4; // needs more info
- if (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_ENEMY) // needs more info
- skills2 -= 25;
- if (sc->data[SC_GRAVITATION])
- skills2 -= sc->data[SC_GRAVITATION]->val2; // needs more info
- if (sc->data[SC_JOINTBEAT]) { // needs more info
- if (sc->data[SC_JOINTBEAT]->val2&BREAK_WRIST)
- skills2 -= 25;
- if (sc->data[SC_JOINTBEAT]->val2&BREAK_KNEE)
- skills2 -= 10;
- }
- if (sc->data[SC_FREEZING])
- skills2 -= 30;
- if (sc->data[SC_HALLUCINATIONWALK_POSTDELAY])
- skills2 -= 50;
- if (sc->data[SC_PARALYSE])
- skills2 -= 10;
- if (sc->data[SC__BODYPAINT])
- skills2 -= 2 + 5 * sc->data[SC__BODYPAINT]->val1;
- if (sc->data[SC__INVISIBILITY])
- skills2 -= sc->data[SC__INVISIBILITY]->val2 ;
- if (sc->data[SC__GROOMY])
- skills2 -= sc->data[SC__GROOMY]->val2;
- if (sc->data[SC_SWINGDANCE])
- skills2 += sc->data[SC_SWINGDANCE]->val2;
- if (sc->data[SC_DANCEWITHWUG])
- skills2 += sc->data[SC_DANCEWITHWUG]->val3;
- if (sc->data[SC_GLOOMYDAY])
- skills2 -= sc->data[SC_GLOOMYDAY]->val3;
- if (sc->data[SC_EARTHDRIVE])
- skills2 -= 25;
- if (sc->data[SC_GT_CHANGE])
- skills2 += sc->data[SC_GT_CHANGE]->val3;
- if (sc->data[SC_MELON_BOMB])
- skills2 -= sc->data[SC_MELON_BOMB]->val1;
- if (sc->data[SC_BOOST500])
- skills2 += sc->data[SC_BOOST500]->val1;
- if (sc->data[SC_EXTRACT_SALAMINE_JUICE])
- skills2 += sc->data[SC_EXTRACT_SALAMINE_JUICE]->val1;
- if (sc->data[SC_INCASPDRATE])
- skills2 += sc->data[SC_INCASPDRATE]->val1;
-
- return (flag&1? (skills1 + pots) : skills2);
+ int i, pots = 0, skills1 = 0, skills2 = 0;
+
+ if(!sc || !sc->count)
+ return 0;
+
+ if(sc->data[i=SC_ASPDPOTION3] ||
+ sc->data[i=SC_ASPDPOTION2] ||
+ sc->data[i=SC_ASPDPOTION1] ||
+ sc->data[i=SC_ASPDPOTION0])
+ pots += sc->data[i]->val1;
+
+ if( !sc->data[SC_QUAGMIRE] ){
+ if(sc->data[SC_STAR_COMFORT])
+ skills1 = 5; // needs more info
+
+ if(sc->data[SC_TWOHANDQUICKEN] && skills1 < 7)
+ skills1 = 7;
+
+ if(sc->data[SC_ONEHAND] && skills1 < 7) skills1 = 7;
+
+ if(sc->data[SC_MERC_QUICKEN] && skills1 < 7) // needs more info
+ skills1 = 7;
+
+ if(sc->data[SC_ADRENALINE2] && skills1 < 6)
+ skills1 = 6;
+
+ if(sc->data[SC_ADRENALINE] && skills1 < 7)
+ skills1 = 7;
+
+ if(sc->data[SC_SPEARQUICKEN] && skills1 < 7)
+ skills1 = 7;
+
+ if(sc->data[SC_GATLINGFEVER] && skills1 < 9) // needs more info
+ skills1 = 9;
+
+ if(sc->data[SC_FLEET] && skills1 < 5)
+ skills1 = 5;
+
+ if(sc->data[SC_ASSNCROS] &&
+ skills1 < 5+1*sc->data[SC_ASSNCROS]->val1) // needs more info
+ {
+ if (bl->type!=BL_PC)
+ skills1 = 4+1*sc->data[SC_ASSNCROS]->val1;
+ else
+ switch(((TBL_PC*)bl)->status.weapon)
+ {
+ case W_BOW:
+ case W_REVOLVER:
+ case W_RIFLE:
+ case W_GATLING:
+ case W_SHOTGUN:
+ case W_GRENADE:
+ break;
+ default:
+ skills1 = 5+1*sc->data[SC_ASSNCROS]->val1;
+ }
+ }
+ }
+
+ if((sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]) && skills1 < 15)
+ skills1 = 15;
+ else if(sc->data[SC_MADNESSCANCEL] && skills1 < 15) // needs more info
+ skills1 = 15;
+
+ if(sc->data[SC_DONTFORGETME])
+ skills2 -= sc->data[SC_DONTFORGETME]->val2; // needs more info
+ if(sc->data[SC_LONGING])
+ skills2 -= sc->data[SC_LONGING]->val2; // needs more info
+ if(sc->data[SC_STEELBODY])
+ skills2 -= 25;
+ if(sc->data[SC_SKA])
+ skills2 -= 25;
+ if(sc->data[SC_DEFENDER])
+ skills2 -= sc->data[SC_DEFENDER]->val4; // needs more info
+ if(sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_ENEMY) // needs more info
+ skills2 -= 25;
+ if(sc->data[SC_GRAVITATION])
+ skills2 -= sc->data[SC_GRAVITATION]->val2; // needs more info
+ if(sc->data[SC_JOINTBEAT]) { // needs more info
+ if( sc->data[SC_JOINTBEAT]->val2&BREAK_WRIST )
+ skills2 -= 25;
+ if( sc->data[SC_JOINTBEAT]->val2&BREAK_KNEE )
+ skills2 -= 10;
+ }
+ if( sc->data[SC_FREEZING] )
+ skills2 -= 30;
+ if( sc->data[SC_HALLUCINATIONWALK_POSTDELAY] )
+ skills2 -= 50;
+ if( sc->data[SC_PARALYSE] )
+ skills2 -= 10;
+ if( sc->data[SC__BODYPAINT] )
+ skills2 -= 2 + 5 * sc->data[SC__BODYPAINT]->val1;
+ if( sc->data[SC__INVISIBILITY] )
+ skills2 -= sc->data[SC__INVISIBILITY]->val2 ;
+ if( sc->data[SC__GROOMY] )
+ skills2 -= sc->data[SC__GROOMY]->val2;
+ if( sc->data[SC_SWINGDANCE] )
+ skills2 += sc->data[SC_SWINGDANCE]->val2;
+ if( sc->data[SC_DANCEWITHWUG] )
+ skills2 += sc->data[SC_DANCEWITHWUG]->val3;
+ if( sc->data[SC_GLOOMYDAY] )
+ skills2 -= sc->data[SC_GLOOMYDAY]->val3;
+ if( sc->data[SC_EARTHDRIVE] )
+ skills2 -= 25;
+ if( sc->data[SC_GT_CHANGE] )
+ skills2 += sc->data[SC_GT_CHANGE]->val3;
+ if( sc->data[SC_MELON_BOMB] )
+ skills2 -= sc->data[SC_MELON_BOMB]->val1;
+ if( sc->data[SC_BOOST500] )
+ skills2 += sc->data[SC_BOOST500]->val1;
+ if( sc->data[SC_EXTRACT_SALAMINE_JUICE] )
+ skills2 += sc->data[SC_EXTRACT_SALAMINE_JUICE]->val1;
+ if( sc->data[SC_INCASPDRATE] )
+ skills2 += sc->data[SC_INCASPDRATE]->val1;
+
+ return ( flag&1? (skills1 + pots) : skills2 );
}
#endif
-static short status_calc_fix_aspd(struct block_list *bl, struct status_change *sc, int aspd)
-{
+static short status_calc_fix_aspd(struct block_list *bl, struct status_change *sc, int aspd) {
if (!sc || !sc->count)
return cap_value(aspd, 0, 2000);
@@ -5313,15 +5273,15 @@ static short status_calc_fix_aspd(struct block_list *bl, struct status_change *s
if (sc->data[SC_FIGHTINGSPIRIT])
aspd += sc->data[SC_FIGHTINGSPIRIT]->val3;
if ((sc->data[SC_GUST_OPTION]
- || sc->data[SC_BLAST_OPTION]
- || sc->data[SC_WILD_STORM_OPTION])
- )
+ || sc->data[SC_BLAST_OPTION]
+ || sc->data[SC_WILD_STORM_OPTION])
+ )
aspd -= 50; // ventus passive = +5 ASPD
- if (sc->data[SC_OVERED_BOOST]) {
- aspd = 2000 - sc->data[SC_OVERED_BOOST]->val3*10;
+ if (sc->data[SC_OVERED_BOOST]){
+ aspd = 2000 - sc->data[SC_OVERED_BOOST]->val3*10;
}
- // if(sc->data[SC_FIGHTINGSPIRIT] && sc->data[SC_FIGHTINGSPIRIT]->val2 )
- // aspd -= (sd?pc_checkskill(sd, RK_RUNEMASTERY):10) * 4;
+// if(sc->data[SC_FIGHTINGSPIRIT] && sc->data[SC_FIGHTINGSPIRIT]->val2 )
+// aspd -= (sd?pc_checkskill(sd, RK_RUNEMASTERY):10) * 4;
}
return cap_value(aspd, 0, 2000); // will be recap for proper bl anyway
@@ -5331,809 +5291,768 @@ static short status_calc_fix_aspd(struct block_list *bl, struct status_change *s
/// Note that the scale of aspd_rate is 1000 = 100%.
static short status_calc_aspd_rate(struct block_list *bl, struct status_change *sc, int aspd_rate)
{
- int i;
-
- if (!sc || !sc->count)
- return cap_value(aspd_rate,0,SHRT_MAX);
-
- if (!sc->data[SC_QUAGMIRE]) {
- int max = 0;
- if (sc->data[SC_STAR_COMFORT])
- max = sc->data[SC_STAR_COMFORT]->val2;
-
- if (sc->data[SC_TWOHANDQUICKEN] &&
- max < sc->data[SC_TWOHANDQUICKEN]->val2)
- max = sc->data[SC_TWOHANDQUICKEN]->val2;
-
- if (sc->data[SC_ONEHAND] &&
- max < sc->data[SC_ONEHAND]->val2)
- max = sc->data[SC_ONEHAND]->val2;
-
- if (sc->data[SC_MERC_QUICKEN] &&
- max < sc->data[SC_MERC_QUICKEN]->val2)
- max = sc->data[SC_MERC_QUICKEN]->val2;
-
- if (sc->data[SC_ADRENALINE2] &&
- max < sc->data[SC_ADRENALINE2]->val3)
- max = sc->data[SC_ADRENALINE2]->val3;
-
- if (sc->data[SC_ADRENALINE] &&
- max < sc->data[SC_ADRENALINE]->val3)
- max = sc->data[SC_ADRENALINE]->val3;
-
- if (sc->data[SC_SPEARQUICKEN] &&
- max < sc->data[SC_SPEARQUICKEN]->val2)
- max = sc->data[SC_SPEARQUICKEN]->val2;
-
- if (sc->data[SC_GATLINGFEVER] &&
- max < sc->data[SC_GATLINGFEVER]->val2)
- max = sc->data[SC_GATLINGFEVER]->val2;
-
- if (sc->data[SC_FLEET] &&
- max < sc->data[SC_FLEET]->val2)
- max = sc->data[SC_FLEET]->val2;
-
- if (sc->data[SC_ASSNCROS] &&
- max < sc->data[SC_ASSNCROS]->val2) {
- if (bl->type!=BL_PC)
- max = sc->data[SC_ASSNCROS]->val2;
- else
- switch (((TBL_PC *)bl)->status.weapon) {
- case W_BOW:
- case W_REVOLVER:
- case W_RIFLE:
- case W_GATLING:
- case W_SHOTGUN:
- case W_GRENADE:
- break;
- default:
- max = sc->data[SC_ASSNCROS]->val2;
- }
- }
- aspd_rate -= max;
-
- if ((sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]))
- aspd_rate -= 300;
- else if (sc->data[SC_MADNESSCANCEL])
- aspd_rate -= 200;
- }
-
- if (sc->data[i=SC_ASPDPOTION3] ||
- sc->data[i=SC_ASPDPOTION2] ||
- sc->data[i=SC_ASPDPOTION1] ||
- sc->data[i=SC_ASPDPOTION0])
- aspd_rate -= sc->data[i]->val2;
-
- if (sc->data[SC_DONTFORGETME])
- aspd_rate += 10 * sc->data[SC_DONTFORGETME]->val2;
- if (sc->data[SC_LONGING])
- aspd_rate += sc->data[SC_LONGING]->val2;
- if (sc->data[SC_STEELBODY])
- aspd_rate += 250;
- if (sc->data[SC_SKA])
- aspd_rate += 250;
- if (sc->data[SC_DEFENDER])
- aspd_rate += sc->data[SC_DEFENDER]->val4;
- if (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_ENEMY)
- aspd_rate += 250;
- if (sc->data[SC_GRAVITATION])
- aspd_rate += sc->data[SC_GRAVITATION]->val2;
- if (sc->data[SC_JOINTBEAT]) {
- if (sc->data[SC_JOINTBEAT]->val2&BREAK_WRIST)
- aspd_rate += 250;
- if (sc->data[SC_JOINTBEAT]->val2&BREAK_KNEE)
- aspd_rate += 100;
- }
- if (sc->data[SC_FREEZING])
- aspd_rate += 300;
- if (sc->data[SC_HALLUCINATIONWALK_POSTDELAY])
- aspd_rate += 500;
- if (sc->data[SC_FIGHTINGSPIRIT] && sc->data[SC_FIGHTINGSPIRIT]->val2)
- aspd_rate -= sc->data[SC_FIGHTINGSPIRIT]->val2;
- if (sc->data[SC_PARALYSE])
- aspd_rate += 100;
- if (sc->data[SC__BODYPAINT])
- aspd_rate += 200 + 50 * sc->data[SC__BODYPAINT]->val1;
- if (sc->data[SC__INVISIBILITY])
- aspd_rate += sc->data[SC__INVISIBILITY]->val2 * 10 ;
- if (sc->data[SC__GROOMY])
- aspd_rate += sc->data[SC__GROOMY]->val2 * 10;
- if (sc->data[SC_SWINGDANCE])
- aspd_rate -= sc->data[SC_SWINGDANCE]->val2 * 10;
- if (sc->data[SC_DANCEWITHWUG])
- aspd_rate -= sc->data[SC_DANCEWITHWUG]->val3 * 10;
- if (sc->data[SC_GLOOMYDAY])
- aspd_rate += sc->data[SC_GLOOMYDAY]->val3 * 10;
- if (sc->data[SC_EARTHDRIVE])
- aspd_rate += 250;
- if (sc->data[SC_GT_CHANGE])
- aspd_rate -= sc->data[SC_GT_CHANGE]->val3 * 10;
- if (sc->data[SC_MELON_BOMB])
- aspd_rate += sc->data[SC_MELON_BOMB]->val1 * 10;
- if (sc->data[SC_BOOST500])
- aspd_rate -= sc->data[SC_BOOST500]->val1 *10;
- if (sc->data[SC_EXTRACT_SALAMINE_JUICE])
- aspd_rate -= sc->data[SC_EXTRACT_SALAMINE_JUICE]->val1 * 10;
- if (sc->data[SC_INCASPDRATE])
- aspd_rate -= sc->data[SC_INCASPDRATE]->val1 * 10;
- if (sc->data[SC_PAIN_KILLER])
- aspd_rate += sc->data[SC_PAIN_KILLER]->val2 * 10;
- if (sc->data[SC_GOLDENE_FERSE])
- aspd_rate -= sc->data[SC_GOLDENE_FERSE]->val3 * 10;
-
- return (short)cap_value(aspd_rate,0,SHRT_MAX);
+ int i;
+
+ if(!sc || !sc->count)
+ return cap_value(aspd_rate,0,SHRT_MAX);
+
+ if( !sc->data[SC_QUAGMIRE] ){
+ int max = 0;
+ if(sc->data[SC_STAR_COMFORT])
+ max = sc->data[SC_STAR_COMFORT]->val2;
+
+ if(sc->data[SC_TWOHANDQUICKEN] &&
+ max < sc->data[SC_TWOHANDQUICKEN]->val2)
+ max = sc->data[SC_TWOHANDQUICKEN]->val2;
+
+ if(sc->data[SC_ONEHAND] &&
+ max < sc->data[SC_ONEHAND]->val2)
+ max = sc->data[SC_ONEHAND]->val2;
+
+ if(sc->data[SC_MERC_QUICKEN] &&
+ max < sc->data[SC_MERC_QUICKEN]->val2)
+ max = sc->data[SC_MERC_QUICKEN]->val2;
+
+ if(sc->data[SC_ADRENALINE2] &&
+ max < sc->data[SC_ADRENALINE2]->val3)
+ max = sc->data[SC_ADRENALINE2]->val3;
+
+ if(sc->data[SC_ADRENALINE] &&
+ max < sc->data[SC_ADRENALINE]->val3)
+ max = sc->data[SC_ADRENALINE]->val3;
+
+ if(sc->data[SC_SPEARQUICKEN] &&
+ max < sc->data[SC_SPEARQUICKEN]->val2)
+ max = sc->data[SC_SPEARQUICKEN]->val2;
+
+ if(sc->data[SC_GATLINGFEVER] &&
+ max < sc->data[SC_GATLINGFEVER]->val2)
+ max = sc->data[SC_GATLINGFEVER]->val2;
+
+ if(sc->data[SC_FLEET] &&
+ max < sc->data[SC_FLEET]->val2)
+ max = sc->data[SC_FLEET]->val2;
+
+ if(sc->data[SC_ASSNCROS] &&
+ max < sc->data[SC_ASSNCROS]->val2)
+ {
+ if (bl->type!=BL_PC)
+ max = sc->data[SC_ASSNCROS]->val2;
+ else
+ switch(((TBL_PC*)bl)->status.weapon)
+ {
+ case W_BOW:
+ case W_REVOLVER:
+ case W_RIFLE:
+ case W_GATLING:
+ case W_SHOTGUN:
+ case W_GRENADE:
+ break;
+ default:
+ max = sc->data[SC_ASSNCROS]->val2;
+ }
+ }
+ aspd_rate -= max;
+
+ if((sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]))
+ aspd_rate -= 300;
+ else if(sc->data[SC_MADNESSCANCEL])
+ aspd_rate -= 200;
+ }
+
+ if( sc->data[i=SC_ASPDPOTION3] ||
+ sc->data[i=SC_ASPDPOTION2] ||
+ sc->data[i=SC_ASPDPOTION1] ||
+ sc->data[i=SC_ASPDPOTION0] )
+ aspd_rate -= sc->data[i]->val2;
+
+ if(sc->data[SC_DONTFORGETME])
+ aspd_rate += 10 * sc->data[SC_DONTFORGETME]->val2;
+ if(sc->data[SC_LONGING])
+ aspd_rate += sc->data[SC_LONGING]->val2;
+ if(sc->data[SC_STEELBODY])
+ aspd_rate += 250;
+ if(sc->data[SC_SKA])
+ aspd_rate += 250;
+ if(sc->data[SC_DEFENDER])
+ aspd_rate += sc->data[SC_DEFENDER]->val4;
+ if(sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_ENEMY)
+ aspd_rate += 250;
+ if(sc->data[SC_GRAVITATION])
+ aspd_rate += sc->data[SC_GRAVITATION]->val2;
+ if(sc->data[SC_JOINTBEAT]) {
+ if( sc->data[SC_JOINTBEAT]->val2&BREAK_WRIST )
+ aspd_rate += 250;
+ if( sc->data[SC_JOINTBEAT]->val2&BREAK_KNEE )
+ aspd_rate += 100;
+ }
+ if( sc->data[SC_FREEZING] )
+ aspd_rate += 300;
+ if( sc->data[SC_HALLUCINATIONWALK_POSTDELAY] )
+ aspd_rate += 500;
+ if( sc->data[SC_FIGHTINGSPIRIT] && sc->data[SC_FIGHTINGSPIRIT]->val2 )
+ aspd_rate -= sc->data[SC_FIGHTINGSPIRIT]->val2;
+ if( sc->data[SC_PARALYSE] )
+ aspd_rate += 100;
+ if( sc->data[SC__BODYPAINT] )
+ aspd_rate += 200 + 50 * sc->data[SC__BODYPAINT]->val1;
+ if( sc->data[SC__INVISIBILITY] )
+ aspd_rate += sc->data[SC__INVISIBILITY]->val2 * 10 ;
+ if( sc->data[SC__GROOMY] )
+ aspd_rate += sc->data[SC__GROOMY]->val2 * 10;
+ if( sc->data[SC_SWINGDANCE] )
+ aspd_rate -= sc->data[SC_SWINGDANCE]->val2 * 10;
+ if( sc->data[SC_DANCEWITHWUG] )
+ aspd_rate -= sc->data[SC_DANCEWITHWUG]->val3 * 10;
+ if( sc->data[SC_GLOOMYDAY] )
+ aspd_rate += sc->data[SC_GLOOMYDAY]->val3 * 10;
+ if( sc->data[SC_EARTHDRIVE] )
+ aspd_rate += 250;
+ if( sc->data[SC_GT_CHANGE] )
+ aspd_rate -= sc->data[SC_GT_CHANGE]->val3 * 10;
+ if( sc->data[SC_MELON_BOMB] )
+ aspd_rate += sc->data[SC_MELON_BOMB]->val1 * 10;
+ if( sc->data[SC_BOOST500] )
+ aspd_rate -= sc->data[SC_BOOST500]->val1 *10;
+ if( sc->data[SC_EXTRACT_SALAMINE_JUICE] )
+ aspd_rate -= sc->data[SC_EXTRACT_SALAMINE_JUICE]->val1 * 10;
+ if( sc->data[SC_INCASPDRATE] )
+ aspd_rate -= sc->data[SC_INCASPDRATE]->val1 * 10;
+ if( sc->data[SC_PAIN_KILLER])
+ aspd_rate += sc->data[SC_PAIN_KILLER]->val2 * 10;
+ if( sc->data[SC_GOLDENE_FERSE])
+ aspd_rate -= sc->data[SC_GOLDENE_FERSE]->val3 * 10;
+
+ return (short)cap_value(aspd_rate,0,SHRT_MAX);
}
static unsigned short status_calc_dmotion(struct block_list *bl, struct status_change *sc, int dmotion)
{
- if (!sc || !sc->count || map_flag_gvg(bl->m) || map[bl->m].flag.battleground)
- return cap_value(dmotion,0,USHRT_MAX);
- /**
- * It has been confirmed on official servers that MvP mobs have no dmotion even without endure
- **/
- if (sc->data[SC_ENDURE] || (bl->type == BL_MOB && (((TBL_MOB *)bl)->status.mode&MD_BOSS)))
- return 0;
- if (sc->data[SC_CONCENTRATION])
- return 0;
- if (sc->data[SC_RUN] || sc->data[SC_WUGDASH])
- return 0;
-
- return (unsigned short)cap_value(dmotion,0,USHRT_MAX);
+ if( !sc || !sc->count || map_flag_gvg(bl->m) || map[bl->m].flag.battleground )
+ return cap_value(dmotion,0,USHRT_MAX);
+ /**
+ * It has been confirmed on official servers that MvP mobs have no dmotion even without endure
+ **/
+ if( sc->data[SC_ENDURE] || ( bl->type == BL_MOB && (((TBL_MOB*)bl)->status.mode&MD_BOSS) ) )
+ return 0;
+ if( sc->data[SC_CONCENTRATION] )
+ return 0;
+ if( sc->data[SC_RUN] || sc->data[SC_WUGDASH] )
+ return 0;
+
+ return (unsigned short)cap_value(dmotion,0,USHRT_MAX);
}
static unsigned int status_calc_maxhp(struct block_list *bl, struct status_change *sc, unsigned int maxhp)
{
- if (!sc || !sc->count)
- return cap_value(maxhp,1,UINT_MAX);
-
- if (sc->data[SC_INCMHPRATE])
- maxhp += maxhp * sc->data[SC_INCMHPRATE]->val1/100;
- if (sc->data[SC_INCMHP])
- maxhp += (sc->data[SC_INCMHP]->val1);
- if (sc->data[SC_APPLEIDUN])
- maxhp += maxhp * sc->data[SC_APPLEIDUN]->val2/100;
- if (sc->data[SC_DELUGE])
- maxhp += maxhp * sc->data[SC_DELUGE]->val2/100;
- if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
- maxhp += maxhp * 2;
- if (sc->data[SC_MARIONETTE])
- maxhp -= 1000;
-
- if (sc->data[SC_MERC_HPUP])
- maxhp += maxhp * sc->data[SC_MERC_HPUP]->val2/100;
-
- if (sc->data[SC_EPICLESIS])
- maxhp += maxhp * 5 * sc->data[SC_EPICLESIS]->val1 / 100;
- if (sc->data[SC_VENOMBLEED])
- maxhp -= maxhp * 15 / 100;
- if (sc->data[SC__WEAKNESS])
- maxhp -= maxhp * sc->data[SC__WEAKNESS]->val2 / 100;
- if (sc->data[SC_LERADSDEW])
- maxhp += maxhp * sc->data[SC_LERADSDEW]->val3 / 100;
- if (sc->data[SC_FORCEOFVANGUARD])
- maxhp += maxhp * 3 * sc->data[SC_FORCEOFVANGUARD]->val1 / 100;
- if (sc->data[SC_INSPIRATION]) //Custom value.
- maxhp += maxhp * 3 * sc->data[SC_INSPIRATION]->val1 / 100;
- if (sc->data[SC_RAISINGDRAGON])
- maxhp += maxhp * (2 + sc->data[SC_RAISINGDRAGON]->val1) / 100;
- if (sc->data[SC_GT_CHANGE]) // Max HP decrease: [Skill Level x 4] %
- maxhp -= maxhp * (4 * sc->data[SC_GT_CHANGE]->val1) / 100;
- if (sc->data[SC_GT_REVITALIZE]) // Max HP increase: [Skill Level x 2] %
- maxhp += maxhp * (2 * sc->data[SC_GT_REVITALIZE]->val1) / 100;
- if (sc->data[SC_MUSTLE_M])
- maxhp += maxhp * sc->data[SC_MUSTLE_M]->val1/100;
- if (sc->data[SC_SOLID_SKIN_OPTION])
- maxhp += 2000;// Fix amount.
- if (sc->data[SC_POWER_OF_GAIA])
- maxhp += 3000;
- if (sc->data[SC_MYSTERIOUS_POWDER])
- maxhp -= sc->data[SC_MYSTERIOUS_POWDER]->val1 / 100;
- if (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2)
- maxhp += 500;
- if (sc->data[SC_ANGRIFFS_MODUS])
- maxhp += maxhp * 5 * sc->data[SC_ANGRIFFS_MODUS]->val1 /100;
- if (sc->data[SC_GOLDENE_FERSE])
- maxhp += (maxhp * sc->data[SC_GOLDENE_FERSE]->val2) / 100;
-
- return cap_value(maxhp,1,UINT_MAX);
+ if(!sc || !sc->count)
+ return cap_value(maxhp,1,UINT_MAX);
+
+ if(sc->data[SC_INCMHPRATE])
+ maxhp += maxhp * sc->data[SC_INCMHPRATE]->val1/100;
+ if(sc->data[SC_INCMHP])
+ maxhp += (sc->data[SC_INCMHP]->val1);
+ if(sc->data[SC_APPLEIDUN])
+ maxhp += maxhp * sc->data[SC_APPLEIDUN]->val2/100;
+ if(sc->data[SC_DELUGE])
+ maxhp += maxhp * sc->data[SC_DELUGE]->val2/100;
+ if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
+ maxhp += maxhp * 2;
+ if(sc->data[SC_MARIONETTE])
+ maxhp -= 1000;
+
+ if(sc->data[SC_MERC_HPUP])
+ maxhp += maxhp * sc->data[SC_MERC_HPUP]->val2/100;
+
+ if(sc->data[SC_EPICLESIS])
+ maxhp += maxhp * 5 * sc->data[SC_EPICLESIS]->val1 / 100;
+ if(sc->data[SC_VENOMBLEED])
+ maxhp -= maxhp * 15 / 100;
+ if(sc->data[SC__WEAKNESS])
+ maxhp -= maxhp * sc->data[SC__WEAKNESS]->val2 / 100;
+ if(sc->data[SC_LERADSDEW])
+ maxhp += maxhp * sc->data[SC_LERADSDEW]->val3 / 100;
+ if(sc->data[SC_FORCEOFVANGUARD])
+ maxhp += maxhp * 3 * sc->data[SC_FORCEOFVANGUARD]->val1 / 100;
+ if(sc->data[SC_INSPIRATION]) //Custom value.
+ maxhp += maxhp * 3 * sc->data[SC_INSPIRATION]->val1 / 100;
+ if(sc->data[SC_RAISINGDRAGON])
+ maxhp += maxhp * (2 + sc->data[SC_RAISINGDRAGON]->val1) / 100;
+ if(sc->data[SC_GT_CHANGE]) // Max HP decrease: [Skill Level x 4] %
+ maxhp -= maxhp * (4 * sc->data[SC_GT_CHANGE]->val1) / 100;
+ if(sc->data[SC_GT_REVITALIZE])// Max HP increase: [Skill Level x 2] %
+ maxhp += maxhp * (2 * sc->data[SC_GT_REVITALIZE]->val1) / 100;
+ if(sc->data[SC_MUSTLE_M])
+ maxhp += maxhp * sc->data[SC_MUSTLE_M]->val1/100;
+ if(sc->data[SC_SOLID_SKIN_OPTION])
+ maxhp += 2000;// Fix amount.
+ if(sc->data[SC_POWER_OF_GAIA])
+ maxhp += 3000;
+ if(sc->data[SC_MYSTERIOUS_POWDER])
+ maxhp -= sc->data[SC_MYSTERIOUS_POWDER]->val1 / 100;
+ if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2)
+ maxhp += 500;
+ if (sc->data[SC_ANGRIFFS_MODUS])
+ maxhp += maxhp * 5 * sc->data[SC_ANGRIFFS_MODUS]->val1 /100;
+ if (sc->data[SC_GOLDENE_FERSE])
+ maxhp += (maxhp * sc->data[SC_GOLDENE_FERSE]->val2) / 100;
+
+ return cap_value(maxhp,1,UINT_MAX);
}
static unsigned int status_calc_maxsp(struct block_list *bl, struct status_change *sc, unsigned int maxsp)
{
- if (!sc || !sc->count)
- return cap_value(maxsp,1,UINT_MAX);
-
- if (sc->data[SC_INCMSPRATE])
- maxsp += maxsp * sc->data[SC_INCMSPRATE]->val1/100;
- if (sc->data[SC_INCMSP])
- maxsp += (sc->data[SC_INCMSP]->val1);
- if (sc->data[SC_SERVICE4U])
- maxsp += maxsp * sc->data[SC_SERVICE4U]->val2/100;
- if (sc->data[SC_MERC_SPUP])
- maxsp += maxsp * sc->data[SC_MERC_SPUP]->val2/100;
- if (sc->data[SC_RAISINGDRAGON])
- maxsp += maxsp * (2 + sc->data[SC_RAISINGDRAGON]->val1) / 100;
- if (sc->data[SC_LIFE_FORCE_F])
- maxsp += maxsp * sc->data[SC_LIFE_FORCE_F]->val1/100;
- if (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 3)
- maxsp += 50;
-
- return cap_value(maxsp,1,UINT_MAX);
+ if(!sc || !sc->count)
+ return cap_value(maxsp,1,UINT_MAX);
+
+ if(sc->data[SC_INCMSPRATE])
+ maxsp += maxsp * sc->data[SC_INCMSPRATE]->val1/100;
+ if(sc->data[SC_INCMSP])
+ maxsp += (sc->data[SC_INCMSP]->val1);
+ if(sc->data[SC_SERVICE4U])
+ maxsp += maxsp * sc->data[SC_SERVICE4U]->val2/100;
+ if(sc->data[SC_MERC_SPUP])
+ maxsp += maxsp * sc->data[SC_MERC_SPUP]->val2/100;
+ if(sc->data[SC_RAISINGDRAGON])
+ maxsp += maxsp * (2 + sc->data[SC_RAISINGDRAGON]->val1) / 100;
+ if(sc->data[SC_LIFE_FORCE_F])
+ maxsp += maxsp * sc->data[SC_LIFE_FORCE_F]->val1/100;
+ if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 3)
+ maxsp += 50;
+
+ return cap_value(maxsp,1,UINT_MAX);
}
static unsigned char status_calc_element(struct block_list *bl, struct status_change *sc, int element)
{
- if (!sc || !sc->count)
- return element;
-
- if (sc->data[SC_FREEZE])
- return ELE_WATER;
- if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
- return ELE_EARTH;
- if (sc->data[SC_BENEDICTIO])
- return ELE_HOLY;
- if (sc->data[SC_CHANGEUNDEAD])
- return ELE_UNDEAD;
- if (sc->data[SC_ELEMENTALCHANGE])
- return sc->data[SC_ELEMENTALCHANGE]->val2;
- if (sc->data[SC_SHAPESHIFT])
- return sc->data[SC_SHAPESHIFT]->val2;
-
- return (unsigned char)cap_value(element,0,UCHAR_MAX);
+ if(!sc || !sc->count)
+ return element;
+
+ if(sc->data[SC_FREEZE])
+ return ELE_WATER;
+ if(sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
+ return ELE_EARTH;
+ if(sc->data[SC_BENEDICTIO])
+ return ELE_HOLY;
+ if(sc->data[SC_CHANGEUNDEAD])
+ return ELE_UNDEAD;
+ if(sc->data[SC_ELEMENTALCHANGE])
+ return sc->data[SC_ELEMENTALCHANGE]->val2;
+ if(sc->data[SC_SHAPESHIFT])
+ return sc->data[SC_SHAPESHIFT]->val2;
+
+ return (unsigned char)cap_value(element,0,UCHAR_MAX);
}
static unsigned char status_calc_element_lv(struct block_list *bl, struct status_change *sc, int lv)
{
- if (!sc || !sc->count)
- return lv;
-
- if (sc->data[SC_FREEZE])
- return 1;
- if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
- return 1;
- if (sc->data[SC_BENEDICTIO])
- return 1;
- if (sc->data[SC_CHANGEUNDEAD])
- return 1;
- if (sc->data[SC_ELEMENTALCHANGE])
- return sc->data[SC_ELEMENTALCHANGE]->val1;
- if (sc->data[SC_SHAPESHIFT])
- return 1;
- if (sc->data[SC__INVISIBILITY])
- return 1;
-
- return (unsigned char)cap_value(lv,1,4);
+ if(!sc || !sc->count)
+ return lv;
+
+ if(sc->data[SC_FREEZE])
+ return 1;
+ if(sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
+ return 1;
+ if(sc->data[SC_BENEDICTIO])
+ return 1;
+ if(sc->data[SC_CHANGEUNDEAD])
+ return 1;
+ if(sc->data[SC_ELEMENTALCHANGE])
+ return sc->data[SC_ELEMENTALCHANGE]->val1;
+ if(sc->data[SC_SHAPESHIFT])
+ return 1;
+ if(sc->data[SC__INVISIBILITY])
+ return 1;
+
+ return (unsigned char)cap_value(lv,1,4);
}
unsigned char status_calc_attack_element(struct block_list *bl, struct status_change *sc, int element)
{
- if (!sc || !sc->count)
- return element;
- if (sc->data[SC_ENCHANTARMS])
- return sc->data[SC_ENCHANTARMS]->val2;
- if (sc->data[SC_WATERWEAPON]
- || (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 2))
- return ELE_WATER;
- if (sc->data[SC_EARTHWEAPON]
- || (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2))
- return ELE_EARTH;
- if (sc->data[SC_FIREWEAPON]
- || (sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 2))
- return ELE_FIRE;
- if (sc->data[SC_WINDWEAPON]
- || (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 2))
- return ELE_WIND;
- if (sc->data[SC_ENCPOISON])
- return ELE_POISON;
- if (sc->data[SC_ASPERSIO])
- return ELE_HOLY;
- if (sc->data[SC_SHADOWWEAPON])
- return ELE_DARK;
- if (sc->data[SC_GHOSTWEAPON] || sc->data[SC__INVISIBILITY])
- return ELE_GHOST;
- if (sc->data[SC_TIDAL_WEAPON_OPTION] || sc->data[SC_TIDAL_WEAPON])
- return ELE_WATER;
- if (sc->data[SC_PYROCLASTIC])
+ if(!sc || !sc->count)
+ return element;
+ if(sc->data[SC_ENCHANTARMS])
+ return sc->data[SC_ENCHANTARMS]->val2;
+ if(sc->data[SC_WATERWEAPON]
+ || (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 2) )
+ return ELE_WATER;
+ if(sc->data[SC_EARTHWEAPON]
+ || (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2) )
+ return ELE_EARTH;
+ if(sc->data[SC_FIREWEAPON]
+ || (sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 2) )
+ return ELE_FIRE;
+ if(sc->data[SC_WINDWEAPON]
+ || (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 2) )
+ return ELE_WIND;
+ if(sc->data[SC_ENCPOISON])
+ return ELE_POISON;
+ if(sc->data[SC_ASPERSIO])
+ return ELE_HOLY;
+ if(sc->data[SC_SHADOWWEAPON])
+ return ELE_DARK;
+ if(sc->data[SC_GHOSTWEAPON] || sc->data[SC__INVISIBILITY])
+ return ELE_GHOST;
+ if(sc->data[SC_TIDAL_WEAPON_OPTION] || sc->data[SC_TIDAL_WEAPON] )
+ return ELE_WATER;
+ if(sc->data[SC_PYROCLASTIC])
return ELE_FIRE;
- return (unsigned char)cap_value(element,0,UCHAR_MAX);
+ return (unsigned char)cap_value(element,0,UCHAR_MAX);
}
static unsigned short status_calc_mode(struct block_list *bl, struct status_change *sc, int mode)
{
- if (!sc || !sc->count)
- return mode;
- if (sc->data[SC_MODECHANGE]) {
- if (sc->data[SC_MODECHANGE]->val2)
- mode = sc->data[SC_MODECHANGE]->val2; //Set mode
- if (sc->data[SC_MODECHANGE]->val3)
- mode|= sc->data[SC_MODECHANGE]->val3; //Add mode
- if (sc->data[SC_MODECHANGE]->val4)
- mode&=~sc->data[SC_MODECHANGE]->val4; //Del mode
- }
- return cap_value(mode,0,USHRT_MAX);
+ if(!sc || !sc->count)
+ return mode;
+ if(sc->data[SC_MODECHANGE]) {
+ if (sc->data[SC_MODECHANGE]->val2)
+ mode = sc->data[SC_MODECHANGE]->val2; //Set mode
+ if (sc->data[SC_MODECHANGE]->val3)
+ mode|= sc->data[SC_MODECHANGE]->val3; //Add mode
+ if (sc->data[SC_MODECHANGE]->val4)
+ mode&=~sc->data[SC_MODECHANGE]->val4; //Del mode
+ }
+ return cap_value(mode,0,USHRT_MAX);
}
-const char *status_get_name(struct block_list *bl)
-{
- nullpo_ret(bl);
- switch (bl->type) {
- case BL_PC:
- return ((TBL_PC *)bl)->fakename[0] != '\0' ? ((TBL_PC *)bl)->fakename : ((TBL_PC *)bl)->status.name;
- case BL_MOB:
- return ((TBL_MOB *)bl)->name;
- case BL_PET:
- return ((TBL_PET *)bl)->pet.name;
- case BL_HOM:
- return ((TBL_HOM *)bl)->homunculus.name;
- case BL_NPC:
- return ((TBL_NPC *)bl)->name;
- }
- return "Unknown";
+const char* status_get_name(struct block_list *bl) {
+ nullpo_ret(bl);
+ switch (bl->type) {
+ case BL_PC: return ((TBL_PC *)bl)->fakename[0] != '\0' ? ((TBL_PC*)bl)->fakename : ((TBL_PC*)bl)->status.name;
+ case BL_MOB: return ((TBL_MOB*)bl)->name;
+ case BL_PET: return ((TBL_PET*)bl)->pet.name;
+ case BL_HOM: return ((TBL_HOM*)bl)->homunculus.name;
+ case BL_NPC: return ((TBL_NPC*)bl)->name;
+ }
+ return "Unknown";
}
/*==========================================
* Get the class of the current bl
* return
- * 0 = fail
- * class_id = success
+ * 0 = fail
+ * class_id = success
*------------------------------------------*/
-int status_get_class(struct block_list *bl)
-{
- nullpo_ret(bl);
- switch (bl->type) {
- case BL_PC:
- return ((TBL_PC *)bl)->status.class_;
- case BL_MOB:
- return ((TBL_MOB *)bl)->vd->class_; //Class used on all code should be the view class of the mob.
- case BL_PET:
- return ((TBL_PET *)bl)->pet.class_;
- case BL_HOM:
- return ((TBL_HOM *)bl)->homunculus.class_;
- case BL_MER:
- return ((TBL_MER *)bl)->mercenary.class_;
- case BL_NPC:
- return ((TBL_NPC *)bl)->class_;
- case BL_ELEM:
- return ((TBL_ELEM *)bl)->elemental.class_;
- }
- return 0;
+int status_get_class(struct block_list *bl) {
+ nullpo_ret(bl);
+ switch( bl->type ) {
+ case BL_PC: return ((TBL_PC*)bl)->status.class_;
+ case BL_MOB: return ((TBL_MOB*)bl)->vd->class_; //Class used on all code should be the view class of the mob.
+ case BL_PET: return ((TBL_PET*)bl)->pet.class_;
+ case BL_HOM: return ((TBL_HOM*)bl)->homunculus.class_;
+ case BL_MER: return ((TBL_MER*)bl)->mercenary.class_;
+ case BL_NPC: return ((TBL_NPC*)bl)->class_;
+ case BL_ELEM: return ((TBL_ELEM*)bl)->elemental.class_;
+ }
+ return 0;
}
/*==========================================
* Get the base level of the current bl
* return
- * 1 = fail
- * level = success
+ * 1 = fail
+ * level = success
*------------------------------------------*/
-int status_get_lv(struct block_list *bl)
-{
- nullpo_ret(bl);
- switch (bl->type) {
- case BL_PC:
- return ((TBL_PC *)bl)->status.base_level;
- case BL_MOB:
- return ((TBL_MOB *)bl)->level;
- case BL_PET:
- return ((TBL_PET *)bl)->pet.level;
- case BL_HOM:
- return ((TBL_HOM *)bl)->homunculus.level;
- case BL_MER:
- return ((TBL_MER *)bl)->db->lv;
- case BL_ELEM:
- return ((TBL_ELEM *)bl)->db->lv;
- }
- return 1;
+int status_get_lv(struct block_list *bl) {
+ nullpo_ret(bl);
+ switch (bl->type) {
+ case BL_PC: return ((TBL_PC*)bl)->status.base_level;
+ case BL_MOB: return ((TBL_MOB*)bl)->level;
+ case BL_PET: return ((TBL_PET*)bl)->pet.level;
+ case BL_HOM: return ((TBL_HOM*)bl)->homunculus.level;
+ case BL_MER: return ((TBL_MER*)bl)->db->lv;
+ case BL_ELEM: return ((TBL_ELEM*)bl)->db->lv;
+ }
+ return 1;
}
-struct regen_data *status_get_regen_data(struct block_list *bl) {
- nullpo_retr(NULL, bl);
- switch (bl->type) {
- case BL_PC:
- return &((TBL_PC *)bl)->regen;
- case BL_HOM:
- return &((TBL_HOM *)bl)->regen;
- case BL_MER:
- return &((TBL_MER *)bl)->regen;
- case BL_ELEM:
- return &((TBL_ELEM *)bl)->regen;
- default:
- return NULL;
- }
+struct regen_data *status_get_regen_data(struct block_list *bl)
+{
+ nullpo_retr(NULL, bl);
+ switch (bl->type) {
+ case BL_PC: return &((TBL_PC*)bl)->regen;
+ case BL_HOM: return &((TBL_HOM*)bl)->regen;
+ case BL_MER: return &((TBL_MER*)bl)->regen;
+ case BL_ELEM: return &((TBL_ELEM*)bl)->regen;
+ default:
+ return NULL;
+ }
}
-struct status_data *status_get_status_data(struct block_list *bl) {
- nullpo_retr(&dummy_status, bl);
-
- switch (bl->type) {
- case BL_PC:
- return &((TBL_PC *)bl)->battle_status;
- case BL_MOB:
- return &((TBL_MOB *)bl)->status;
- case BL_PET:
- return &((TBL_PET *)bl)->status;
- case BL_HOM:
- return &((TBL_HOM *)bl)->battle_status;
- case BL_MER:
- return &((TBL_MER *)bl)->battle_status;
- case BL_ELEM:
- return &((TBL_ELEM *)bl)->battle_status;
- default:
- return &dummy_status;
- }
+struct status_data *status_get_status_data(struct block_list *bl)
+{
+ nullpo_retr(&dummy_status, bl);
+
+ switch (bl->type) {
+ case BL_PC: return &((TBL_PC*)bl)->battle_status;
+ case BL_MOB: return &((TBL_MOB*)bl)->status;
+ case BL_PET: return &((TBL_PET*)bl)->status;
+ case BL_HOM: return &((TBL_HOM*)bl)->battle_status;
+ case BL_MER: return &((TBL_MER*)bl)->battle_status;
+ case BL_ELEM: return &((TBL_ELEM*)bl)->battle_status;
+ default:
+ return &dummy_status;
+ }
}
-struct status_data *status_get_base_status(struct block_list *bl) {
- nullpo_retr(NULL, bl);
- switch (bl->type) {
- case BL_PC:
- return &((TBL_PC *)bl)->base_status;
- case BL_MOB:
- return ((TBL_MOB *)bl)->base_status ? ((TBL_MOB *)bl)->base_status : &((TBL_MOB *)bl)->db->status;
- case BL_PET:
- return &((TBL_PET *)bl)->db->status;
- case BL_HOM:
- return &((TBL_HOM *)bl)->base_status;
- case BL_MER:
- return &((TBL_MER *)bl)->base_status;
- case BL_ELEM:
- return &((TBL_ELEM *)bl)->base_status;
- default:
- return NULL;
- }
-}
-defType status_get_def(struct block_list *bl)
+struct status_data *status_get_base_status(struct block_list *bl)
{
- struct unit_data *ud;
- struct status_data *status = status_get_status_data(bl);
- int def = status?status->def:0;
- ud = unit_bl2ud(bl);
- if (ud && ud->skilltimer != INVALID_TIMER)
- def -= def * skill_get_castdef(ud->skillid)/100;
-
- return cap_value(def, DEFTYPE_MIN, DEFTYPE_MAX);
+ nullpo_retr(NULL, bl);
+ switch (bl->type) {
+ case BL_PC: return &((TBL_PC*)bl)->base_status;
+ case BL_MOB: return ((TBL_MOB*)bl)->base_status ? ((TBL_MOB*)bl)->base_status : &((TBL_MOB*)bl)->db->status;
+ case BL_PET: return &((TBL_PET*)bl)->db->status;
+ case BL_HOM: return &((TBL_HOM*)bl)->base_status;
+ case BL_MER: return &((TBL_MER*)bl)->base_status;
+ case BL_ELEM: return &((TBL_ELEM*)bl)->base_status;
+ default:
+ return NULL;
+ }
+}
+defType status_get_def(struct block_list *bl) {
+ struct unit_data *ud;
+ struct status_data *status = status_get_status_data(bl);
+ int def = status?status->def:0;
+ ud = unit_bl2ud(bl);
+ if (ud && ud->skilltimer != INVALID_TIMER)
+ def -= def * skill_get_castdef(ud->skillid)/100;
+
+ return cap_value(def, DEFTYPE_MIN, DEFTYPE_MAX);
}
unsigned short status_get_speed(struct block_list *bl)
{
- if (bl->type==BL_NPC) //Only BL with speed data but no status_data [Skotlex]
- return ((struct npc_data *)bl)->speed;
- return status_get_status_data(bl)->speed;
+ if(bl->type==BL_NPC)//Only BL with speed data but no status_data [Skotlex]
+ return ((struct npc_data *)bl)->speed;
+ return status_get_status_data(bl)->speed;
}
-int status_get_party_id(struct block_list *bl)
-{
- nullpo_ret(bl);
- switch (bl->type) {
- case BL_PC:
- return ((TBL_PC *)bl)->status.party_id;
- case BL_PET:
- if (((TBL_PET *)bl)->msd)
- return ((TBL_PET *)bl)->msd->status.party_id;
- break;
- case BL_MOB: {
- struct mob_data *md=(TBL_MOB *)bl;
- if (md->master_id > 0) {
- struct map_session_data *msd;
- if (md->special_state.ai && (msd = map_id2sd(md->master_id)) != NULL)
- return msd->status.party_id;
- return -md->master_id;
- }
- }
- break;
- case BL_HOM:
- if (((TBL_HOM *)bl)->master)
- return ((TBL_HOM *)bl)->master->status.party_id;
- break;
- case BL_MER:
- if (((TBL_MER *)bl)->master)
- return ((TBL_MER *)bl)->master->status.party_id;
- break;
- case BL_SKILL:
- return ((TBL_SKILL *)bl)->group->party_id;
- case BL_ELEM:
- if (((TBL_ELEM *)bl)->master)
- return ((TBL_ELEM *)bl)->master->status.party_id;
- break;
- }
- return 0;
+int status_get_party_id(struct block_list *bl) {
+ nullpo_ret(bl);
+ switch (bl->type) {
+ case BL_PC:
+ return ((TBL_PC*)bl)->status.party_id;
+ case BL_PET:
+ if (((TBL_PET*)bl)->msd)
+ return ((TBL_PET*)bl)->msd->status.party_id;
+ break;
+ case BL_MOB: {
+ struct mob_data *md=(TBL_MOB*)bl;
+ if( md->master_id > 0 ) {
+ struct map_session_data *msd;
+ if (md->special_state.ai && (msd = map_id2sd(md->master_id)) != NULL)
+ return msd->status.party_id;
+ return -md->master_id;
+ }
+ }
+ break;
+ case BL_HOM:
+ if (((TBL_HOM*)bl)->master)
+ return ((TBL_HOM*)bl)->master->status.party_id;
+ break;
+ case BL_MER:
+ if (((TBL_MER*)bl)->master)
+ return ((TBL_MER*)bl)->master->status.party_id;
+ break;
+ case BL_SKILL:
+ return ((TBL_SKILL*)bl)->group->party_id;
+ case BL_ELEM:
+ if (((TBL_ELEM*)bl)->master)
+ return ((TBL_ELEM*)bl)->master->status.party_id;
+ break;
+ }
+ return 0;
}
-int status_get_guild_id(struct block_list *bl)
-{
- nullpo_ret(bl);
- switch (bl->type) {
- case BL_PC:
- return ((TBL_PC *)bl)->status.guild_id;
- case BL_PET:
- if (((TBL_PET *)bl)->msd)
- return ((TBL_PET *)bl)->msd->status.guild_id;
- break;
- case BL_MOB: {
- struct map_session_data *msd;
- struct mob_data *md = (struct mob_data *)bl;
- if (md->guardian_data) //Guardian's guild [Skotlex]
- return md->guardian_data->guild_id;
- if (md->special_state.ai && (msd = map_id2sd(md->master_id)) != NULL)
- return msd->status.guild_id; //Alchemist's mobs [Skotlex]
- }
- break;
- case BL_HOM:
- if (((TBL_HOM *)bl)->master)
- return ((TBL_HOM *)bl)->master->status.guild_id;
- break;
- case BL_MER:
- if (((TBL_MER *)bl)->master)
- return ((TBL_MER *)bl)->master->status.guild_id;
- break;
- case BL_NPC:
- if (((TBL_NPC *)bl)->subtype == SCRIPT)
- return ((TBL_NPC *)bl)->u.scr.guild_id;
- break;
- case BL_SKILL:
- return ((TBL_SKILL *)bl)->group->guild_id;
- case BL_ELEM:
- if (((TBL_ELEM *)bl)->master)
- return ((TBL_ELEM *)bl)->master->status.guild_id;
- break;
- }
- return 0;
+int status_get_guild_id(struct block_list *bl) {
+ nullpo_ret(bl);
+ switch (bl->type) {
+ case BL_PC:
+ return ((TBL_PC*)bl)->status.guild_id;
+ case BL_PET:
+ if (((TBL_PET*)bl)->msd)
+ return ((TBL_PET*)bl)->msd->status.guild_id;
+ break;
+ case BL_MOB: {
+ struct map_session_data *msd;
+ struct mob_data *md = (struct mob_data *)bl;
+ if (md->guardian_data) //Guardian's guild [Skotlex]
+ return md->guardian_data->guild_id;
+ if (md->special_state.ai && (msd = map_id2sd(md->master_id)) != NULL)
+ return msd->status.guild_id; //Alchemist's mobs [Skotlex]
+ }
+ break;
+ case BL_HOM:
+ if (((TBL_HOM*)bl)->master)
+ return ((TBL_HOM*)bl)->master->status.guild_id;
+ break;
+ case BL_MER:
+ if (((TBL_MER*)bl)->master)
+ return ((TBL_MER*)bl)->master->status.guild_id;
+ break;
+ case BL_NPC:
+ if (((TBL_NPC*)bl)->subtype == SCRIPT)
+ return ((TBL_NPC*)bl)->u.scr.guild_id;
+ break;
+ case BL_SKILL:
+ return ((TBL_SKILL*)bl)->group->guild_id;
+ case BL_ELEM:
+ if (((TBL_ELEM*)bl)->master)
+ return ((TBL_ELEM*)bl)->master->status.guild_id;
+ break;
+ }
+ return 0;
}
-int status_get_emblem_id(struct block_list *bl)
-{
- nullpo_ret(bl);
- switch (bl->type) {
- case BL_PC:
- return ((TBL_PC *)bl)->guild_emblem_id;
- case BL_PET:
- if (((TBL_PET *)bl)->msd)
- return ((TBL_PET *)bl)->msd->guild_emblem_id;
- break;
- case BL_MOB: {
- struct map_session_data *msd;
- struct mob_data *md = (struct mob_data *)bl;
- if (md->guardian_data) //Guardian's guild [Skotlex]
- return md->guardian_data->emblem_id;
- if (md->special_state.ai && (msd = map_id2sd(md->master_id)) != NULL)
- return msd->guild_emblem_id; //Alchemist's mobs [Skotlex]
- }
- break;
- case BL_HOM:
- if (((TBL_HOM *)bl)->master)
- return ((TBL_HOM *)bl)->master->guild_emblem_id;
- break;
- case BL_MER:
- if (((TBL_MER *)bl)->master)
- return ((TBL_MER *)bl)->master->guild_emblem_id;
- break;
- case BL_NPC:
- if (((TBL_NPC *)bl)->subtype == SCRIPT && ((TBL_NPC *)bl)->u.scr.guild_id > 0) {
- struct guild *g = guild_search(((TBL_NPC *)bl)->u.scr.guild_id);
- if (g)
- return g->emblem_id;
- }
- break;
- case BL_ELEM:
- if (((TBL_ELEM *)bl)->master)
- return ((TBL_ELEM *)bl)->master->guild_emblem_id;
- break;
- }
- return 0;
+int status_get_emblem_id(struct block_list *bl) {
+ nullpo_ret(bl);
+ switch (bl->type) {
+ case BL_PC:
+ return ((TBL_PC*)bl)->guild_emblem_id;
+ case BL_PET:
+ if (((TBL_PET*)bl)->msd)
+ return ((TBL_PET*)bl)->msd->guild_emblem_id;
+ break;
+ case BL_MOB: {
+ struct map_session_data *msd;
+ struct mob_data *md = (struct mob_data *)bl;
+ if (md->guardian_data) //Guardian's guild [Skotlex]
+ return md->guardian_data->emblem_id;
+ if (md->special_state.ai && (msd = map_id2sd(md->master_id)) != NULL)
+ return msd->guild_emblem_id; //Alchemist's mobs [Skotlex]
+ }
+ break;
+ case BL_HOM:
+ if (((TBL_HOM*)bl)->master)
+ return ((TBL_HOM*)bl)->master->guild_emblem_id;
+ break;
+ case BL_MER:
+ if (((TBL_MER*)bl)->master)
+ return ((TBL_MER*)bl)->master->guild_emblem_id;
+ break;
+ case BL_NPC:
+ if (((TBL_NPC*)bl)->subtype == SCRIPT && ((TBL_NPC*)bl)->u.scr.guild_id > 0) {
+ struct guild *g = guild_search(((TBL_NPC*)bl)->u.scr.guild_id);
+ if (g)
+ return g->emblem_id;
+ }
+ break;
+ case BL_ELEM:
+ if (((TBL_ELEM*)bl)->master)
+ return ((TBL_ELEM*)bl)->master->guild_emblem_id;
+ break;
+ }
+ return 0;
}
int status_get_mexp(struct block_list *bl)
{
- nullpo_ret(bl);
- if (bl->type==BL_MOB)
- return ((struct mob_data *)bl)->db->mexp;
- if (bl->type==BL_PET)
- return ((struct pet_data *)bl)->db->mexp;
- return 0;
+ nullpo_ret(bl);
+ if(bl->type==BL_MOB)
+ return ((struct mob_data *)bl)->db->mexp;
+ if(bl->type==BL_PET)
+ return ((struct pet_data *)bl)->db->mexp;
+ return 0;
}
int status_get_race2(struct block_list *bl)
{
- nullpo_ret(bl);
- if (bl->type == BL_MOB)
- return ((struct mob_data *)bl)->db->race2;
- if (bl->type==BL_PET)
- return ((struct pet_data *)bl)->db->race2;
- return 0;
+ nullpo_ret(bl);
+ if(bl->type == BL_MOB)
+ return ((struct mob_data *)bl)->db->race2;
+ if(bl->type==BL_PET)
+ return ((struct pet_data *)bl)->db->race2;
+ return 0;
}
int status_isdead(struct block_list *bl)
{
- nullpo_ret(bl);
- return status_get_status_data(bl)->hp == 0;
+ nullpo_ret(bl);
+ return status_get_status_data(bl)->hp == 0;
}
int status_isimmune(struct block_list *bl)
{
- struct status_change *sc =status_get_sc(bl);
- if (sc && sc->data[SC_HERMODE])
- return 100;
-
- if (bl->type == BL_PC &&
- ((TBL_PC *)bl)->special_state.no_magic_damage >= battle_config.gtb_sc_immunity)
- return ((TBL_PC *)bl)->special_state.no_magic_damage;
- return 0;
+ struct status_change *sc =status_get_sc(bl);
+ if (sc && sc->data[SC_HERMODE])
+ return 100;
+
+ if (bl->type == BL_PC &&
+ ((TBL_PC*)bl)->special_state.no_magic_damage >= battle_config.gtb_sc_immunity)
+ return ((TBL_PC*)bl)->special_state.no_magic_damage;
+ return 0;
}
-struct view_data *status_get_viewdata(struct block_list *bl) {
- nullpo_retr(NULL, bl);
- switch (bl->type) {
- case BL_PC:
- return &((TBL_PC *)bl)->vd;
- case BL_MOB:
- return ((TBL_MOB *)bl)->vd;
- case BL_PET:
- return &((TBL_PET *)bl)->vd;
- case BL_NPC:
- return ((TBL_NPC *)bl)->vd;
- case BL_HOM:
- return ((TBL_HOM *)bl)->vd;
- case BL_MER:
- return ((TBL_MER *)bl)->vd;
- case BL_ELEM:
- return ((TBL_ELEM *)bl)->vd;
- }
- return NULL;
+struct view_data* status_get_viewdata(struct block_list *bl)
+{
+ nullpo_retr(NULL, bl);
+ switch (bl->type) {
+ case BL_PC: return &((TBL_PC*)bl)->vd;
+ case BL_MOB: return ((TBL_MOB*)bl)->vd;
+ case BL_PET: return &((TBL_PET*)bl)->vd;
+ case BL_NPC: return ((TBL_NPC*)bl)->vd;
+ case BL_HOM: return ((TBL_HOM*)bl)->vd;
+ case BL_MER: return ((TBL_MER*)bl)->vd;
+ case BL_ELEM: return ((TBL_ELEM*)bl)->vd;
+ }
+ return NULL;
}
void status_set_viewdata(struct block_list *bl, int class_)
{
- struct view_data *vd;
- nullpo_retv(bl);
- if (mobdb_checkid(class_) || mob_is_clone(class_))
- vd = mob_get_viewdata(class_);
- else if (npcdb_checkid(class_) || (bl->type == BL_NPC && class_ == WARP_CLASS))
- vd = npc_get_viewdata(class_);
- else if (homdb_checkid(class_))
- vd = merc_get_hom_viewdata(class_);
- else if (merc_class(class_))
- vd = merc_get_viewdata(class_);
- else if (elemental_class(class_))
- vd = elemental_get_viewdata(class_);
- else
- vd = NULL;
-
- switch (bl->type) {
- case BL_PC: {
- TBL_PC *sd = (TBL_PC *)bl;
- if (pcdb_checkid(class_)) {
- if (sd->sc.option&OPTION_WEDDING)
- class_ = JOB_WEDDING;
- else if (sd->sc.option&OPTION_SUMMER)
- class_ = JOB_SUMMER;
- else if (sd->sc.option&OPTION_XMAS)
- class_ = JOB_XMAS;
- else if (sd->sc.option&OPTION_RIDING) {
- switch (class_) { //Adapt class to a Mounted one.
- case JOB_KNIGHT:
- class_ = JOB_KNIGHT2;
- break;
- case JOB_CRUSADER:
- class_ = JOB_CRUSADER2;
- break;
- case JOB_LORD_KNIGHT:
- class_ = JOB_LORD_KNIGHT2;
- break;
- case JOB_PALADIN:
- class_ = JOB_PALADIN2;
- break;
- case JOB_BABY_KNIGHT:
- class_ = JOB_BABY_KNIGHT2;
- break;
- case JOB_BABY_CRUSADER:
- class_ = JOB_BABY_CRUSADER2;
- break;
- }
- }
- sd->vd.class_ = class_;
- clif_get_weapon_view(sd, &sd->vd.weapon, &sd->vd.shield);
- sd->vd.head_top = sd->status.head_top;
- sd->vd.head_mid = sd->status.head_mid;
- sd->vd.head_bottom = sd->status.head_bottom;
- sd->vd.hair_style = cap_value(sd->status.hair,0,battle_config.max_hair_style);
- sd->vd.hair_color = cap_value(sd->status.hair_color,0,battle_config.max_hair_color);
- sd->vd.cloth_color = cap_value(sd->status.clothes_color,0,battle_config.max_cloth_color);
- sd->vd.sex = sd->status.sex;
- } else if (vd)
- memcpy(&sd->vd, vd, sizeof(struct view_data));
- else
- ShowError("status_set_viewdata (PC): No view data for class %d\n", class_);
- }
- break;
- case BL_MOB: {
- TBL_MOB *md = (TBL_MOB *)bl;
- if (vd)
- md->vd = vd;
- else
- ShowError("status_set_viewdata (MOB): No view data for class %d\n", class_);
- }
- break;
- case BL_PET: {
- TBL_PET *pd = (TBL_PET *)bl;
- if (vd) {
- memcpy(&pd->vd, vd, sizeof(struct view_data));
- if (!pcdb_checkid(vd->class_)) {
- pd->vd.hair_style = battle_config.pet_hair_style;
- if (pd->pet.equip) {
- pd->vd.head_bottom = itemdb_viewid(pd->pet.equip);
- if (!pd->vd.head_bottom)
- pd->vd.head_bottom = pd->pet.equip;
- }
- }
- } else
- ShowError("status_set_viewdata (PET): No view data for class %d\n", class_);
- }
- break;
- case BL_NPC: {
- TBL_NPC *nd = (TBL_NPC *)bl;
- if (vd)
- nd->vd = vd;
- else
- ShowError("status_set_viewdata (NPC): No view data for class %d\n", class_);
- }
- break;
- case BL_HOM: { //[blackhole89]
- struct homun_data *hd = (struct homun_data *)bl;
- if (vd)
- hd->vd = vd;
- else
- ShowError("status_set_viewdata (HOMUNCULUS): No view data for class %d\n", class_);
- }
- break;
- case BL_MER: {
- struct mercenary_data *md = (struct mercenary_data *)bl;
- if (vd)
- md->vd = vd;
- else
- ShowError("status_set_viewdata (MERCENARY): No view data for class %d\n", class_);
- }
- break;
- case BL_ELEM: {
- struct elemental_data *ed = (struct elemental_data *)bl;
- if (vd)
- ed->vd = vd;
- else
- ShowError("status_set_viewdata (ELEMENTAL): No view data for class %d\n", class_);
- }
- break;
- }
- vd = status_get_viewdata(bl);
- if (vd && vd->cloth_color && (
- (vd->class_==JOB_WEDDING && battle_config.wedding_ignorepalette)
- || (vd->class_==JOB_XMAS && battle_config.xmas_ignorepalette)
- || (vd->class_==JOB_SUMMER && battle_config.summer_ignorepalette)
- ))
- vd->cloth_color = 0;
+ struct view_data* vd;
+ nullpo_retv(bl);
+ if (mobdb_checkid(class_) || mob_is_clone(class_))
+ vd = mob_get_viewdata(class_);
+ else if (npcdb_checkid(class_) || (bl->type == BL_NPC && class_ == WARP_CLASS))
+ vd = npc_get_viewdata(class_);
+ else if (homdb_checkid(class_))
+ vd = merc_get_hom_viewdata(class_);
+ else if (merc_class(class_))
+ vd = merc_get_viewdata(class_);
+ else if (elemental_class(class_))
+ vd = elemental_get_viewdata(class_);
+ else
+ vd = NULL;
+
+ switch (bl->type) {
+ case BL_PC:
+ {
+ TBL_PC* sd = (TBL_PC*)bl;
+ if (pcdb_checkid(class_)) {
+ if (sd->sc.option&OPTION_WEDDING)
+ class_ = JOB_WEDDING;
+ else if (sd->sc.option&OPTION_SUMMER)
+ class_ = JOB_SUMMER;
+ else if (sd->sc.option&OPTION_XMAS)
+ class_ = JOB_XMAS;
+ else if (sd->sc.option&OPTION_RIDING) {
+ switch (class_) { //Adapt class to a Mounted one.
+ case JOB_KNIGHT:
+ class_ = JOB_KNIGHT2;
+ break;
+ case JOB_CRUSADER:
+ class_ = JOB_CRUSADER2;
+ break;
+ case JOB_LORD_KNIGHT:
+ class_ = JOB_LORD_KNIGHT2;
+ break;
+ case JOB_PALADIN:
+ class_ = JOB_PALADIN2;
+ break;
+ case JOB_BABY_KNIGHT:
+ class_ = JOB_BABY_KNIGHT2;
+ break;
+ case JOB_BABY_CRUSADER:
+ class_ = JOB_BABY_CRUSADER2;
+ break;
+ }
+ }
+ sd->vd.class_ = class_;
+ clif_get_weapon_view(sd, &sd->vd.weapon, &sd->vd.shield);
+ sd->vd.head_top = sd->status.head_top;
+ sd->vd.head_mid = sd->status.head_mid;
+ sd->vd.head_bottom = sd->status.head_bottom;
+ sd->vd.hair_style = cap_value(sd->status.hair,0,battle_config.max_hair_style);
+ sd->vd.hair_color = cap_value(sd->status.hair_color,0,battle_config.max_hair_color);
+ sd->vd.cloth_color = cap_value(sd->status.clothes_color,0,battle_config.max_cloth_color);
+ sd->vd.sex = sd->status.sex;
+ } else if (vd)
+ memcpy(&sd->vd, vd, sizeof(struct view_data));
+ else
+ ShowError("status_set_viewdata (PC): No view data for class %d\n", class_);
+ }
+ break;
+ case BL_MOB:
+ {
+ TBL_MOB* md = (TBL_MOB*)bl;
+ if (vd)
+ md->vd = vd;
+ else
+ ShowError("status_set_viewdata (MOB): No view data for class %d\n", class_);
+ }
+ break;
+ case BL_PET:
+ {
+ TBL_PET* pd = (TBL_PET*)bl;
+ if (vd) {
+ memcpy(&pd->vd, vd, sizeof(struct view_data));
+ if (!pcdb_checkid(vd->class_)) {
+ pd->vd.hair_style = battle_config.pet_hair_style;
+ if(pd->pet.equip) {
+ pd->vd.head_bottom = itemdb_viewid(pd->pet.equip);
+ if (!pd->vd.head_bottom)
+ pd->vd.head_bottom = pd->pet.equip;
+ }
+ }
+ } else
+ ShowError("status_set_viewdata (PET): No view data for class %d\n", class_);
+ }
+ break;
+ case BL_NPC:
+ {
+ TBL_NPC* nd = (TBL_NPC*)bl;
+ if (vd)
+ nd->vd = vd;
+ else
+ ShowError("status_set_viewdata (NPC): No view data for class %d\n", class_);
+ }
+ break;
+ case BL_HOM: //[blackhole89]
+ {
+ struct homun_data *hd = (struct homun_data*)bl;
+ if (vd)
+ hd->vd = vd;
+ else
+ ShowError("status_set_viewdata (HOMUNCULUS): No view data for class %d\n", class_);
+ }
+ break;
+ case BL_MER:
+ {
+ struct mercenary_data *md = (struct mercenary_data*)bl;
+ if (vd)
+ md->vd = vd;
+ else
+ ShowError("status_set_viewdata (MERCENARY): No view data for class %d\n", class_);
+ }
+ break;
+ case BL_ELEM:
+ {
+ struct elemental_data *ed = (struct elemental_data*)bl;
+ if (vd)
+ ed->vd = vd;
+ else
+ ShowError("status_set_viewdata (ELEMENTAL): No view data for class %d\n", class_);
+ }
+ break;
+ }
+ vd = status_get_viewdata(bl);
+ if (vd && vd->cloth_color && (
+ (vd->class_==JOB_WEDDING && battle_config.wedding_ignorepalette)
+ || (vd->class_==JOB_XMAS && battle_config.xmas_ignorepalette)
+ || (vd->class_==JOB_SUMMER && battle_config.summer_ignorepalette)
+ ))
+ vd->cloth_color = 0;
}
/// Returns the status_change data of bl or NULL if it doesn't exist.
struct status_change *status_get_sc(struct block_list *bl) {
- if (bl)
- switch (bl->type) {
- case BL_PC:
- return &((TBL_PC *)bl)->sc;
- case BL_MOB:
- return &((TBL_MOB *)bl)->sc;
- case BL_NPC:
- return &((TBL_NPC *)bl)->sc;
- case BL_HOM:
- return &((TBL_HOM *)bl)->sc;
- case BL_MER:
- return &((TBL_MER *)bl)->sc;
- case BL_ELEM:
- return &((TBL_ELEM *)bl)->sc;
- }
- return NULL;
+ if( bl )
+ switch (bl->type) {
+ case BL_PC: return &((TBL_PC*)bl)->sc;
+ case BL_MOB: return &((TBL_MOB*)bl)->sc;
+ case BL_NPC: return &((TBL_NPC*)bl)->sc;
+ case BL_HOM: return &((TBL_HOM*)bl)->sc;
+ case BL_MER: return &((TBL_MER*)bl)->sc;
+ case BL_ELEM: return &((TBL_ELEM*)bl)->sc;
+ }
+ return NULL;
}
void status_change_init(struct block_list *bl)
{
- struct status_change *sc = status_get_sc(bl);
- nullpo_retv(sc);
- memset(sc, 0, sizeof(struct status_change));
+ struct status_change *sc = status_get_sc(bl);
+ nullpo_retv(sc);
+ memset(sc, 0, sizeof (struct status_change));
}
//Applies SC defense to a given status change.
@@ -6141,234 +6060,227 @@ void status_change_init(struct block_list *bl)
//the flag values are the same as in status_change_start.
int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int tick, int flag)
{
- int sc_def = 0, tick_def = 0;
- struct status_data *status;
- struct status_change *sc;
- struct map_session_data *sd;
-
- nullpo_ret(bl);
-
- //Status that are blocked by Golden Thief Bug card or Wand of Hermod
- if (status_isimmune(bl))
- switch (type) {
- case SC_DECREASEAGI:
- case SC_SILENCE:
- case SC_COMA:
- case SC_INCREASEAGI:
- case SC_BLESSING:
- case SC_SLOWPOISON:
- case SC_IMPOSITIO:
- case SC_AETERNA:
- case SC_SUFFRAGIUM:
- case SC_BENEDICTIO:
- case SC_PROVIDENCE:
- case SC_KYRIE:
- case SC_ASSUMPTIO:
- case SC_ANGELUS:
- case SC_MAGNIFICAT:
- case SC_GLORIA:
- case SC_WINDWALK:
- case SC_MAGICROD:
- case SC_HALLUCINATION:
- case SC_STONE:
- case SC_QUAGMIRE:
- case SC_SUITON:
- case SC_SWINGDANCE:
- case SC__ENERVATION:
- case SC__GROOMY:
- case SC__IGNORANCE:
- case SC__LAZINESS:
- case SC__UNLUCKY:
- case SC__WEAKNESS:
- case SC__BLOODYLUST:
- return 0;
- }
+ int sc_def = 0, tick_def = 0;
+ struct status_data* status;
+ struct status_change* sc;
+ struct map_session_data *sd;
+
+ nullpo_ret(bl);
+
+ //Status that are blocked by Golden Thief Bug card or Wand of Hermod
+ if (status_isimmune(bl))
+ switch (type) {
+ case SC_DECREASEAGI:
+ case SC_SILENCE:
+ case SC_COMA:
+ case SC_INCREASEAGI:
+ case SC_BLESSING:
+ case SC_SLOWPOISON:
+ case SC_IMPOSITIO:
+ case SC_AETERNA:
+ case SC_SUFFRAGIUM:
+ case SC_BENEDICTIO:
+ case SC_PROVIDENCE:
+ case SC_KYRIE:
+ case SC_ASSUMPTIO:
+ case SC_ANGELUS:
+ case SC_MAGNIFICAT:
+ case SC_GLORIA:
+ case SC_WINDWALK:
+ case SC_MAGICROD:
+ case SC_HALLUCINATION:
+ case SC_STONE:
+ case SC_QUAGMIRE:
+ case SC_SUITON:
+ case SC_SWINGDANCE:
+ case SC__ENERVATION:
+ case SC__GROOMY:
+ case SC__IGNORANCE:
+ case SC__LAZINESS:
+ case SC__UNLUCKY:
+ case SC__WEAKNESS:
+ case SC__BLOODYLUST:
+ return 0;
+ }
- sd = BL_CAST(BL_PC,bl);
- status = status_get_status_data(bl);
- sc = status_get_sc(bl);
- if (sc && !sc->count)
- sc = NULL;
- switch (type) {
- case SC_STUN:
- case SC_POISON:
- if (sc && sc->data[SC__UNLUCKY])
- return tick;
- case SC_DPOISON:
- case SC_SILENCE:
- case SC_BLEEDING:
- sc_def = 3 +status->vit;
- break;
- case SC_SLEEP:
- sc_def = 3 +status->int_;
- break;
- case SC_DEEPSLEEP:
- tick_def = status->int_ / 10 + status_get_lv(bl) * 65 / 1000; // Seems to be -1 sec every 10 int and -5% chance every 10 int.
- sc_def = 5 * status->int_ /10;
- break;
- case SC_DECREASEAGI:
- case SC_ADORAMUS://Arch Bishop
- if (sd) tick>>=1; //Half duration for players.
- case SC_STONE:
- case SC_FREEZE:
- sc_def = 3 +status->mdef;
- break;
- case SC_CURSE:
- //Special property: inmunity when luk is greater than level or zero
- if (status->luk > status_get_lv(bl) || status->luk == 0)
- return 0;
- else
- sc_def = 3 +status->luk;
- tick_def = status->vit;
- break;
- case SC_BLIND:
- if (sc && sc->data[SC__UNLUCKY])
- return tick;
- sc_def = 3 +(status->vit + status->int_)/2;
- break;
- case SC_CONFUSION:
- sc_def = 3 +(status->str + status->int_)/2;
- break;
- case SC_ANKLE:
- if (status->mode&MD_BOSS) // Lasts 5 times less on bosses
- tick /= 5;
- sc_def = status->agi / 2;
- break;
- case SC_MAGICMIRROR:
- case SC_ARMORCHANGE:
- if (sd) //Duration greatly reduced for players.
- tick /= 15;
- //No defense against it (buff).
- rate -= (status_get_lv(bl) / 5 + status->vit / 4 + status->agi / 10)*100; // Lineal Reduction of Rate
- break;
- case SC_MARSHOFABYSS:
- //5 second (Fixed) + 25 second - {( INT + LUK ) / 20 second }
- tick -= (status->int_ + status->luk) / 20 * 1000;
- break;
- case SC_STASIS:
- //5 second (fixed) + { Stasis Skill level * 5 - (Target�s VIT + DEX) / 20 }
- tick -= (status->vit + status->dex) / 20 * 1000;
- break;
- case SC_WHITEIMPRISON:
- if (tick == 5000) // 100% on caster
- break;
- if (bl->type == BL_PC)
- tick -= (status_get_lv(bl) / 5 + status->vit / 4 + status->agi / 10)*100;
- else
- tick -= (status->vit + status->luk) / 20 * 1000;
- break;
- case SC_BURNING:
- // From iROwiki : http://forums.irowiki.org/showpost.php?p=577240&postcount=583
- tick -= 50*status->luk + 60*status->int_ + 170*status->vit;
- tick = max(tick,10000); // Minimum Duration 10s.
- break;
- case SC_FREEZING:
- tick -= 1000 * ((status->vit + status->dex) / 20);
- tick = max(tick,10000); // Minimum Duration 10s.
- break;
- case SC_OBLIVIONCURSE: // 100% - (100 - 0.8 x INT)
- sc_def = 100 - (100 - status->int_* 8 / 10);
- sc_def = max(sc_def, 5); // minimum of 5%
- break;
- case SC_BITE: // {(Base Success chance) - (Target's AGI / 4)}
- rate -= status->agi*1000/4;
- rate = max(rate,50000); // minimum of 50%
- break;
- case SC_ELECTRICSHOCKER:
- if (bl->type == BL_MOB)
- tick -= 1000 * (status->agi/10);
- break;
- case SC_CRYSTALIZE:
- tick -= (1000*(status->vit/10))+(status_get_lv(bl)/50);
- break;
- case SC_MANDRAGORA:
- sc_def = (status->vit+status->luk)/5;
- break;
- case SC_KYOUGAKU:
- tick -= 30*status->int_;
- break;
+ sd = BL_CAST(BL_PC,bl);
+ status = status_get_status_data(bl);
+ sc = status_get_sc(bl);
+ if( sc && !sc->count )
+ sc = NULL;
+ switch (type) {
+ case SC_STUN:
+ case SC_POISON:
+ if( sc && sc->data[SC__UNLUCKY] )
+ return tick;
+ case SC_DPOISON:
+ case SC_SILENCE:
+ case SC_BLEEDING:
+ sc_def = 3 +status->vit;
+ break;
+ case SC_SLEEP:
+ sc_def = 3 +status->int_;
+ break;
+ case SC_DEEPSLEEP:
+ tick_def = status->int_ / 10 + status_get_lv(bl) * 65 / 1000; // Seems to be -1 sec every 10 int and -5% chance every 10 int.
+ sc_def = 5 * status->int_ /10;
+ break;
+ case SC_DECREASEAGI:
+ case SC_ADORAMUS://Arch Bishop
+ if (sd) tick>>=1; //Half duration for players.
+ case SC_STONE:
+ case SC_FREEZE:
+ sc_def = 3 +status->mdef;
+ break;
+ case SC_CURSE:
+ //Special property: inmunity when luk is greater than level or zero
+ if (status->luk > status_get_lv(bl) || status->luk == 0)
+ return 0;
+ else
+ sc_def = 3 +status->luk;
+ tick_def = status->vit;
+ break;
+ case SC_BLIND:
+ if( sc && sc->data[SC__UNLUCKY] )
+ return tick;
+ sc_def = 3 +(status->vit + status->int_)/2;
+ break;
+ case SC_CONFUSION:
+ sc_def = 3 +(status->str + status->int_)/2;
+ break;
+ case SC_ANKLE:
+ if(status->mode&MD_BOSS) // Lasts 5 times less on bosses
+ tick /= 5;
+ sc_def = status->agi / 2;
+ break;
+ case SC_MAGICMIRROR:
+ case SC_ARMORCHANGE:
+ if (sd) //Duration greatly reduced for players.
+ tick /= 15;
+ //No defense against it (buff).
+ rate -= (status_get_lv(bl) / 5 + status->vit / 4 + status->agi / 10)*100; // Lineal Reduction of Rate
+ break;
+ case SC_WHITEIMPRISON:
+ if( tick == 5000 ) // 100% on caster
+ break;
+ if( bl->type == BL_PC )
+ tick -= (status_get_lv(bl) / 5 + status->vit / 4 + status->agi / 10)*100;
+ else
+ tick -= (status->vit + status->luk) / 20 * 1000;
+ break;
+ case SC_BURNING:
+ // From iROwiki : http://forums.irowiki.org/showpost.php?p=577240&postcount=583
+ tick -= 50*status->luk + 60*status->int_ + 170*status->vit;
+ tick = max(tick,10000); // Minimum Duration 10s.
+ break;
+ case SC_FREEZING:
+ tick -= 1000 * ((status->vit + status->dex) / 20);
+ tick = max(tick,10000); // Minimum Duration 10s.
+ break;
+ case SC_OBLIVIONCURSE: // 100% - (100 - 0.8 x INT)
+ sc_def = 100 - ( 100 - status->int_* 8 / 10 );
+ sc_def = max(sc_def, 5); // minimum of 5%
+ break;
+ case SC_BITE: // {(Base Success chance) - (Target's AGI / 4)}
+ rate -= status->agi*1000/4;
+ rate = max(rate,50000); // minimum of 50%
+ break;
+ case SC_ELECTRICSHOCKER:
+ if( bl->type == BL_MOB )
+ tick -= 1000 * (status->agi/10);
+ break;
+ case SC_CRYSTALIZE:
+ tick -= (1000*(status->vit/10))+(status_get_lv(bl)/50);
+ break;
+ case SC_MANDRAGORA:
+ sc_def = (status->vit+status->luk)/5;
+ break;
+ case SC_KYOUGAKU:
+ tick -= 30*status->int_;
+ break;
case SC_PARALYSIS:
tick -= 50 * (status->vit + status->luk); //(1000/20);
break;
- default:
- //Effect that cannot be reduced? Likely a buff.
- if (!(rnd()%10000 < rate))
- return 0;
- return tick?tick:1;
- }
-
- if (sd) {
-
- if (battle_config.pc_sc_def_rate != 100)
- sc_def = sc_def*battle_config.pc_sc_def_rate/100;
+ default:
+ //Effect that cannot be reduced? Likely a buff.
+ if (!(rnd()%10000 < rate))
+ return 0;
+ return tick?tick:1;
+ }
- if (sc_def < battle_config.pc_max_sc_def)
- sc_def += (battle_config.pc_max_sc_def - sc_def)*
- status->luk/battle_config.pc_luk_sc_def;
- else
- sc_def = battle_config.pc_max_sc_def;
+ if (sd) {
- if (tick_def) {
- if (battle_config.pc_sc_def_rate != 100)
- tick_def = tick_def*battle_config.pc_sc_def_rate/100;
- }
-
- } else {
+ if (battle_config.pc_sc_def_rate != 100)
+ sc_def = sc_def*battle_config.pc_sc_def_rate/100;
- if (battle_config.mob_sc_def_rate != 100)
- sc_def = sc_def*battle_config.mob_sc_def_rate/100;
+ if (sc_def < battle_config.pc_max_sc_def)
+ sc_def += (battle_config.pc_max_sc_def - sc_def)*
+ status->luk/battle_config.pc_luk_sc_def;
+ else
+ sc_def = battle_config.pc_max_sc_def;
- if (sc_def < battle_config.mob_max_sc_def)
- sc_def += (battle_config.mob_max_sc_def - sc_def)*
- status->luk/battle_config.mob_luk_sc_def;
- else
- sc_def = battle_config.mob_max_sc_def;
-
- if (tick_def) {
- if (battle_config.mob_sc_def_rate != 100)
- tick_def = tick_def*battle_config.mob_sc_def_rate/100;
- }
- }
+ if (tick_def) {
+ if (battle_config.pc_sc_def_rate != 100)
+ tick_def = tick_def*battle_config.pc_sc_def_rate/100;
+ }
- if (sc) {
- if (sc->data[SC_SCRESIST])
- sc_def += sc->data[SC_SCRESIST]->val1; //Status resist
- else if (sc->data[SC_SIEGFRIED])
- sc_def += sc->data[SC_SIEGFRIED]->val3; //Status resistance.
- }
+ } else {
- //When no tick def, reduction is the same for both.
- if (!tick_def && type != SC_STONE) //Recent tests show duration of petrify isn't reduced by MDEF. [Inkfish]
- tick_def = sc_def;
+ if (battle_config.mob_sc_def_rate != 100)
+ sc_def = sc_def*battle_config.mob_sc_def_rate/100;
- //Natural resistance
- if (!(flag&8)) {
- rate -= rate*sc_def/100;
+ if (sc_def < battle_config.mob_max_sc_def)
+ sc_def += (battle_config.mob_max_sc_def - sc_def)*
+ status->luk/battle_config.mob_luk_sc_def;
+ else
+ sc_def = battle_config.mob_max_sc_def;
- //Item resistance (only applies to rate%)
- if (sd && SC_COMMON_MIN <= type && type <= SC_COMMON_MAX) {
- if (sd->reseff[type-SC_COMMON_MIN] > 0)
- rate -= rate*sd->reseff[type-SC_COMMON_MIN]/10000;
- if (sd->sc.data[SC_COMMONSC_RESIST])
- rate -= rate*sd->sc.data[SC_COMMONSC_RESIST]->val1/100;
- }
- }
- if (!(rnd()%10000 < rate))
- return 0;
-
- //Why would a status start with no duration? Presume it has
- //duration defined elsewhere.
- if (!tick) return 1;
-
- //Rate reduction
- if (flag&2)
- return tick;
-
- tick -= tick*tick_def/100;
- // Changed to 5 seconds according to recent tests [Playtester]
- if (type == SC_ANKLE && tick < 5000)
- tick = 5000;
- return tick<=0?0:tick;
+ if (tick_def) {
+ if (battle_config.mob_sc_def_rate != 100)
+ tick_def = tick_def*battle_config.mob_sc_def_rate/100;
+ }
+ }
+
+ if (sc) {
+ if (sc->data[SC_SCRESIST])
+ sc_def += sc->data[SC_SCRESIST]->val1; //Status resist
+ else if (sc->data[SC_SIEGFRIED])
+ sc_def += sc->data[SC_SIEGFRIED]->val3; //Status resistance.
+ }
+
+ //When no tick def, reduction is the same for both.
+ if( !tick_def && type != SC_STONE ) //Recent tests show duration of petrify isn't reduced by MDEF. [Inkfish]
+ tick_def = sc_def;
+
+ //Natural resistance
+ if (!(flag&8)) {
+ rate -= rate*sc_def/100;
+
+ //Item resistance (only applies to rate%)
+ if(sd && SC_COMMON_MIN <= type && type <= SC_COMMON_MAX)
+ {
+ if( sd->reseff[type-SC_COMMON_MIN] > 0 )
+ rate -= rate*sd->reseff[type-SC_COMMON_MIN]/10000;
+ if( sd->sc.data[SC_COMMONSC_RESIST] )
+ rate -= rate*sd->sc.data[SC_COMMONSC_RESIST]->val1/100;
+ }
+ }
+ if (!(rnd()%10000 < rate))
+ return 0;
+
+ //Why would a status start with no duration? Presume it has
+ //duration defined elsewhere.
+ if (!tick) return 1;
+
+ //Rate reduction
+ if (flag&2)
+ return tick;
+
+ tick -= tick*tick_def/100;
+ // Changed to 5 seconds according to recent tests [Playtester]
+ if (type == SC_ANKLE && tick < 5000)
+ tick = 5000;
+ return tick<=0?0:tick;
}
/*==========================================
@@ -6382,578 +6294,583 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
* &4: sc_data loaded, no value has to be altered.
* &8: rate should not be reduced
*------------------------------------------*/
-int status_change_start(struct block_list *bl,enum sc_type type,int rate,int val1,int val2,int val3,int val4,int tick,int flag)
+int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val1,int val2,int val3,int val4,int tick,int flag)
{
- struct map_session_data *sd = NULL;
- struct status_change *sc;
- struct status_change_entry *sce;
- struct status_data *status;
- struct view_data *vd;
- int opt_flag, calc_flag, undead_flag, val_flag = 0, tick_time = 0;
- bool sc_isnew = true;
-
- nullpo_ret(bl);
- sc = status_get_sc(bl);
- status = status_get_status_data(bl);
-
- if (type <= SC_NONE || type >= SC_MAX) {
- ShowError("status_change_start: invalid status change (%d)!\n", type);
- return 0;
- }
-
- if (!sc)
- return 0; //Unable to receive status changes
-
- if (status_isdead(bl) && type != SC_NOCHAT) // SC_NOCHAT should work even on dead characters
- return 0;
-
- if (bl->type == BL_MOB) {
- struct mob_data *md = BL_CAST(BL_MOB,bl);
- if (md && (md->class_ == MOBID_EMPERIUM || mob_is_battleground(md)) && type != SC_SAFETYWALL && type != SC_PNEUMA)
- return 0; //Emperium/BG Monsters can't be afflicted by status changes
- // if(md && mob_is_gvg(md) && status_sc2scb_flag(type)&SCB_MAXHP)
- // return 0; //prevent status addinh hp to gvg mob (like bloodylust=hp*3 etc...
- }
-
- if (sc->data[SC_REFRESH]) {
- if (type >= SC_COMMON_MIN && type <= SC_COMMON_MAX) // Confirmed.
- return 0; // Immune to status ailements
- switch (type) {
- case SC_QUAGMIRE://Tester said it protects against this and decrease agi.
- case SC_DECREASEAGI:
- case SC_BURNING:
- case SC_FREEZING:
- //case SC_WHITEIMPRISON://Need confirm. Protected against this in the past. [Rytech]
- case SC_MARSHOFABYSS:
- case SC_TOXIN:
- case SC_PARALYSE:
- case SC_VENOMBLEED:
- case SC_MAGICMUSHROOM:
- case SC_DEATHHURT:
- case SC_PYREXIA:
- case SC_OBLIVIONCURSE:
- case SC_LEECHESEND: //08/31/2011 - Class Balance Changes
- case SC_CRYSTALIZE:
- case SC_DEEPSLEEP:
- case SC_MANDRAGORA:
- return 0;
- }
- } else if (sc->data[SC_INSPIRATION]) {
- if (type >= SC_COMMON_MIN && type <= SC_COMMON_MAX)
- return 0; // Immune to status ailements
- switch (type) {
- case SC_DEEPSLEEP:
- case SC_SATURDAYNIGHTFEVER:
- case SC_PYREXIA:
- case SC_DEATHHURT:
- case SC_MAGICMUSHROOM:
- case SC_VENOMBLEED:
- case SC_TOXIN:
- case SC_OBLIVIONCURSE:
- case SC_LEECHESEND:
- case SC__ENERVATION:
- case SC__GROOMY:
- case SC__LAZINESS:
- case SC__UNLUCKY:
- case SC__WEAKNESS:
- case SC__BODYPAINT:
- case SC__IGNORANCE:
- return 0;
- }
- }
+ struct map_session_data *sd = NULL;
+ struct status_change* sc;
+ struct status_change_entry* sce;
+ struct status_data *status;
+ struct view_data *vd;
+ int opt_flag, calc_flag, undead_flag, val_flag = 0, tick_time = 0;
+ bool sc_isnew = true;
+
+ nullpo_ret(bl);
+ sc = status_get_sc(bl);
+ status = status_get_status_data(bl);
+
+ if( type <= SC_NONE || type >= SC_MAX )
+ {
+ ShowError("status_change_start: invalid status change (%d)!\n", type);
+ return 0;
+ }
+
+ if( !sc )
+ return 0; //Unable to receive status changes
+
+ if( status_isdead(bl) && type != SC_NOCHAT ) // SC_NOCHAT should work even on dead characters
+ return 0;
+
+ if( bl->type == BL_MOB)
+ {
+ struct mob_data *md = BL_CAST(BL_MOB,bl);
+ if(md && (md->class_ == MOBID_EMPERIUM || mob_is_battleground(md)) && type != SC_SAFETYWALL && type != SC_PNEUMA)
+ return 0; //Emperium/BG Monsters can't be afflicted by status changes
+ // if(md && mob_is_gvg(md) && status_sc2scb_flag(type)&SCB_MAXHP)
+ // return 0; //prevent status addinh hp to gvg mob (like bloodylust=hp*3 etc...
+ }
+
+ if( sc->data[SC_REFRESH] ) {
+ if( type >= SC_COMMON_MIN && type <= SC_COMMON_MAX) // Confirmed.
+ return 0; // Immune to status ailements
+ switch( type ) {
+ case SC_QUAGMIRE://Tester said it protects against this and decrease agi.
+ case SC_DECREASEAGI:
+ case SC_BURNING:
+ case SC_FREEZING:
+ //case SC_WHITEIMPRISON://Need confirm. Protected against this in the past. [Rytech]
+ case SC_MARSHOFABYSS:
+ case SC_TOXIN:
+ case SC_PARALYSE:
+ case SC_VENOMBLEED:
+ case SC_MAGICMUSHROOM:
+ case SC_DEATHHURT:
+ case SC_PYREXIA:
+ case SC_OBLIVIONCURSE:
+ //case SC_LEECHESEND://Need confirm. If it protects against nearly every Guillotine poison, it should work on this too right? [Rytech]
+ case SC_CRYSTALIZE:
+ case SC_DEEPSLEEP:
+ case SC_MANDRAGORA:
+ return 0;
+ }
+ }
+ else if( sc->data[SC_INSPIRATION] ) {
+ if( type >= SC_COMMON_MIN && type <= SC_COMMON_MAX )
+ return 0; // Immune to status ailements
+ switch( type ) {
+ case SC_DEEPSLEEP:
+ case SC_SATURDAYNIGHTFEVER:
+ case SC_PYREXIA:
+ case SC_DEATHHURT:
+ case SC_MAGICMUSHROOM:
+ case SC_VENOMBLEED:
+ case SC_TOXIN:
+ case SC_OBLIVIONCURSE:
+ case SC_LEECHESEND:
+ case SC__ENERVATION:
+ case SC__GROOMY:
+ case SC__LAZINESS:
+ case SC__UNLUCKY:
+ case SC__WEAKNESS:
+ case SC__BODYPAINT:
+ case SC__IGNORANCE:
+ return 0;
+ }
+ }
- sd = BL_CAST(BL_PC, bl);
+ sd = BL_CAST(BL_PC, bl);
- //Adjust tick according to status resistances
- if (!(flag&(1|4))) {
- tick = status_get_sc_def(bl, type, rate, tick, flag);
- if (!tick) return 0;
- }
+ //Adjust tick according to status resistances
+ if( !(flag&(1|4)) )
+ {
+ tick = status_get_sc_def(bl, type, rate, tick, flag);
+ if( !tick ) return 0;
+ }
- undead_flag = battle_check_undead(status->race,status->def_ele);
- //Check for inmunities / sc fails
- switch (type) {
+ undead_flag = battle_check_undead(status->race,status->def_ele);
+ //Check for inmunities / sc fails
+ switch (type) {
case SC_ANGRIFFS_MODUS:
case SC_GOLDENE_FERSE:
- if ((type==SC_GOLDENE_FERSE && sc->data[SC_ANGRIFFS_MODUS])
- || (type==SC_ANGRIFFS_MODUS && sc->data[SC_GOLDENE_FERSE])
- )
+ if ((type==SC_GOLDENE_FERSE && sc->data[SC_ANGRIFFS_MODUS])
+ || (type==SC_ANGRIFFS_MODUS && sc->data[SC_GOLDENE_FERSE])
+ )
return 0;
- case SC_STONE:
- if (sc->data[SC_POWER_OF_GAIA])
- return 0;
- case SC_FREEZE:
- //Undead are immune to Freeze/Stone
- if (undead_flag && !(flag&1))
- return 0;
- case SC_DEEPSLEEP:
- case SC_SLEEP:
- case SC_STUN:
- case SC_FREEZING:
- case SC_CRYSTALIZE:
- if (sc->opt1)
- return 0; //Cannot override other opt1 status changes. [Skotlex]
- if ((type == SC_FREEZE || type == SC_FREEZING || type == SC_CRYSTALIZE) && sc->data[SC_WARMER])
- return 0; //Immune to Frozen and Freezing status if under Warmer status. [Jobbie]
- break;
+ case SC_STONE:
+ if(sc->data[SC_POWER_OF_GAIA])
+ return 0;
+ case SC_FREEZE:
+ //Undead are immune to Freeze/Stone
+ if (undead_flag && !(flag&1))
+ return 0;
+ case SC_DEEPSLEEP:
+ case SC_SLEEP:
+ case SC_STUN:
+ case SC_FREEZING:
+ case SC_CRYSTALIZE:
+ if (sc->opt1)
+ return 0; //Cannot override other opt1 status changes. [Skotlex]
+ if((type == SC_FREEZE || type == SC_FREEZING || type == SC_CRYSTALIZE) && sc->data[SC_WARMER])
+ return 0; //Immune to Frozen and Freezing status if under Warmer status. [Jobbie]
+ break;
//There all like berserk, do not everlap each other
- case SC__BLOODYLUST:
- if (!sd) return 0; //should only affect player
- case SC_BERSERK:
- if (((type == SC_BERSERK) && (sc->data[SC_SATURDAYNIGHTFEVER] || sc->data[SC__BLOODYLUST]))
- || ((type == SC__BLOODYLUST) && (sc->data[SC_SATURDAYNIGHTFEVER] || sc->data[SC_BERSERK]))
- )
- return 0;
- break;
-
- case SC_BURNING:
- if (sc->opt1 || sc->data[SC_FREEZING])
- return 0;
- break;
-
- case SC_SIGNUMCRUCIS:
- //Only affects demons and undead element (but not players)
- if ((!undead_flag && status->race!=RC_DEMON) || bl->type == BL_PC)
- return 0;
- break;
- case SC_AETERNA:
- if ((sc->data[SC_STONE] && sc->opt1 == OPT1_STONE) || sc->data[SC_FREEZE])
- return 0;
- break;
- case SC_KYRIE:
- if (bl->type == BL_MOB)
- return 0;
- break;
- case SC_OVERTHRUST:
- if (sc->data[SC_MAXOVERTHRUST])
- return 0; //Overthrust can't take effect if under Max Overthrust. [Skotlex]
- case SC_MAXOVERTHRUST:
- if (sc->option&OPTION_MADOGEAR)
- return 0;//Overthrust and Overthrust Max cannot be used on Mado Gear [Ind]
- break;
- case SC_ADRENALINE:
- if (sd && !pc_check_weapontype(sd,skill_get_weapontype(BS_ADRENALINE)))
- return 0;
- if (sc->data[SC_QUAGMIRE] ||
- sc->data[SC_DECREASEAGI] ||
- sc->option&OPTION_MADOGEAR //Adrenaline doesn't affect Mado Gear [Ind]
- )
- return 0;
- break;
- case SC_ADRENALINE2:
- if (sd && !pc_check_weapontype(sd,skill_get_weapontype(BS_ADRENALINE2)))
- return 0;
- if (sc->data[SC_QUAGMIRE] ||
- sc->data[SC_DECREASEAGI]
- )
- return 0;
- break;
- case SC_MAGNIFICAT:
- if (sc->option&OPTION_MADOGEAR) //Mado is immune to magnificat
- return 0;
- break;
- case SC_ONEHAND:
- case SC_MERC_QUICKEN:
- case SC_TWOHANDQUICKEN:
- if (sc->data[SC_DECREASEAGI])
- return 0;
-
- case SC_INCREASEAGI:
- if (sd && pc_issit(sd)) {
- pc_setstand(sd);
- }
-
- case SC_CONCENTRATE:
- case SC_SPEARQUICKEN:
- case SC_TRUESIGHT:
- case SC_WINDWALK:
- case SC_CARTBOOST:
- case SC_ASSNCROS:
- if (sc->data[SC_QUAGMIRE])
- return 0;
- if (sc->option&OPTION_MADOGEAR)
- return 0;//Mado is immune to increase agi, wind walk, cart boost, etc (others above) [Ind]
- break;
- case SC_CLOAKING:
- //Avoid cloaking with no wall and low skill level. [Skotlex]
- //Due to the cloaking card, we have to check the wall versus to known
- //skill level rather than the used one. [Skotlex]
- //if (sd && val1 < 3 && skill_check_cloaking(bl,NULL))
- if (sd && pc_checkskill(sd, AS_CLOAKING) < 3 && !skill_check_cloaking(bl,NULL))
- return 0;
- break;
- case SC_MODECHANGE: {
- int mode;
- struct status_data *bstatus = status_get_base_status(bl);
- if (!bstatus) return 0;
- if (sc->data[type]) {
- //Pile up with previous values.
- if (!val2) val2 = sc->data[type]->val2;
- val3 |= sc->data[type]->val3;
- val4 |= sc->data[type]->val4;
- }
- mode = val2?val2:bstatus->mode; //Base mode
- if (val4) mode&=~val4; //Del mode
- if (val3) mode|= val3; //Add mode
- if (mode == bstatus->mode) { //No change.
- if (sc->data[type]) //Abort previous status
- return status_change_end(bl, type, INVALID_TIMER);
- return 0;
- }
- }
- break;
- //Strip skills, need to divest something or it fails.
- case SC_STRIPWEAPON:
- if (sd && !(flag&4)) { //apply sc anyway if loading saved sc_data
- int i;
- opt_flag = 0; //Reuse to check success condition.
- if (sd->bonus.unstripable_equip&EQP_WEAPON)
- return 0;
- i = sd->equip_index[EQI_HAND_L];
- if (i>=0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_WEAPON) {
- opt_flag|=1;
- pc_unequipitem(sd,i,3); //L-hand weapon
- }
+ case SC__BLOODYLUST:
+ if(!sd) return 0; //should only affect player
+ case SC_BERSERK:
+ if (((type == SC_BERSERK) && (sc->data[SC_SATURDAYNIGHTFEVER] || sc->data[SC__BLOODYLUST]))
+ || ((type == SC__BLOODYLUST) && (sc->data[SC_SATURDAYNIGHTFEVER] || sc->data[SC_BERSERK]))
+ )
+ return 0;
+ break;
+
+ case SC_BURNING:
+ if(sc->opt1 || sc->data[SC_FREEZING])
+ return 0;
+ break;
+
+ case SC_SIGNUMCRUCIS:
+ //Only affects demons and undead element (but not players)
+ if((!undead_flag && status->race!=RC_DEMON) || bl->type == BL_PC)
+ return 0;
+ break;
+ case SC_AETERNA:
+ if( (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE) || sc->data[SC_FREEZE] )
+ return 0;
+ break;
+ case SC_KYRIE:
+ if (bl->type == BL_MOB)
+ return 0;
+ break;
+ case SC_OVERTHRUST:
+ if (sc->data[SC_MAXOVERTHRUST])
+ return 0; //Overthrust can't take effect if under Max Overthrust. [Skotlex]
+ case SC_MAXOVERTHRUST:
+ if( sc->option&OPTION_MADOGEAR )
+ return 0;//Overthrust and Overthrust Max cannot be used on Mado Gear [Ind]
+ break;
+ case SC_ADRENALINE:
+ if(sd && !pc_check_weapontype(sd,skill_get_weapontype(BS_ADRENALINE)))
+ return 0;
+ if (sc->data[SC_QUAGMIRE] ||
+ sc->data[SC_DECREASEAGI] ||
+ sc->option&OPTION_MADOGEAR //Adrenaline doesn't affect Mado Gear [Ind]
+ )
+ return 0;
+ break;
+ case SC_ADRENALINE2:
+ if(sd && !pc_check_weapontype(sd,skill_get_weapontype(BS_ADRENALINE2)))
+ return 0;
+ if (sc->data[SC_QUAGMIRE] ||
+ sc->data[SC_DECREASEAGI]
+ )
+ return 0;
+ break;
+ case SC_MAGNIFICAT:
+ if( sc->option&OPTION_MADOGEAR ) //Mado is immune to magnificat
+ return 0;
+ break;
+ case SC_ONEHAND:
+ case SC_MERC_QUICKEN:
+ case SC_TWOHANDQUICKEN:
+ if(sc->data[SC_DECREASEAGI])
+ return 0;
+
+ case SC_INCREASEAGI:
+ if(sd && pc_issit(sd)){
+ pc_setstand(sd);
+ }
+
+ case SC_CONCENTRATE:
+ case SC_SPEARQUICKEN:
+ case SC_TRUESIGHT:
+ case SC_WINDWALK:
+ case SC_CARTBOOST:
+ case SC_ASSNCROS:
+ if (sc->data[SC_QUAGMIRE])
+ return 0;
+ if(sc->option&OPTION_MADOGEAR)
+ return 0;//Mado is immune to increase agi, wind walk, cart boost, etc (others above) [Ind]
+ break;
+ case SC_CLOAKING:
+ //Avoid cloaking with no wall and low skill level. [Skotlex]
+ //Due to the cloaking card, we have to check the wall versus to known
+ //skill level rather than the used one. [Skotlex]
+ //if (sd && val1 < 3 && skill_check_cloaking(bl,NULL))
+ if( sd && pc_checkskill(sd, AS_CLOAKING) < 3 && !skill_check_cloaking(bl,NULL) )
+ return 0;
+ break;
+ case SC_MODECHANGE:
+ {
+ int mode;
+ struct status_data *bstatus = status_get_base_status(bl);
+ if (!bstatus) return 0;
+ if (sc->data[type])
+ { //Pile up with previous values.
+ if(!val2) val2 = sc->data[type]->val2;
+ val3 |= sc->data[type]->val3;
+ val4 |= sc->data[type]->val4;
+ }
+ mode = val2?val2:bstatus->mode; //Base mode
+ if (val4) mode&=~val4; //Del mode
+ if (val3) mode|= val3; //Add mode
+ if (mode == bstatus->mode) { //No change.
+ if (sc->data[type]) //Abort previous status
+ return status_change_end(bl, type, INVALID_TIMER);
+ return 0;
+ }
+ }
+ break;
+ //Strip skills, need to divest something or it fails.
+ case SC_STRIPWEAPON:
+ if (sd && !(flag&4)) { //apply sc anyway if loading saved sc_data
+ int i;
+ opt_flag = 0; //Reuse to check success condition.
+ if(sd->bonus.unstripable_equip&EQP_WEAPON)
+ return 0;
+ i = sd->equip_index[EQI_HAND_L];
+ if (i>=0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_WEAPON) {
+ opt_flag|=1;
+ pc_unequipitem(sd,i,3); //L-hand weapon
+ }
- i = sd->equip_index[EQI_HAND_R];
- if (i>=0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_WEAPON) {
- opt_flag|=2;
- pc_unequipitem(sd,i,3);
- }
- if (!opt_flag) return 0;
- }
- if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
- break;
- case SC_STRIPSHIELD:
- if (val2 == 1) val2 = 0; //GX effect. Do not take shield off..
- else if (sd && !(flag&4)) {
- int i;
- if (sd->bonus.unstripable_equip&EQP_SHIELD)
- return 0;
- i = sd->equip_index[EQI_HAND_L];
- if (i < 0 || !sd->inventory_data[i] || sd->inventory_data[i]->type != IT_ARMOR)
- return 0;
- pc_unequipitem(sd,i,3);
- }
- if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
- break;
- case SC_STRIPARMOR:
- if (sd && !(flag&4)) {
- int i;
- if (sd->bonus.unstripable_equip&EQP_ARMOR)
- return 0;
- i = sd->equip_index[EQI_ARMOR];
- if (i < 0 || !sd->inventory_data[i])
- return 0;
- pc_unequipitem(sd,i,3);
- }
- if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
- break;
- case SC_STRIPHELM:
- if (sd && !(flag&4)) {
- int i;
- if (sd->bonus.unstripable_equip&EQP_HELM)
- return 0;
- i = sd->equip_index[EQI_HEAD_TOP];
- if (i < 0 || !sd->inventory_data[i])
- return 0;
- pc_unequipitem(sd,i,3);
- }
- if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
- break;
- case SC_MERC_FLEEUP:
- case SC_MERC_ATKUP:
- case SC_MERC_HPUP:
- case SC_MERC_SPUP:
- case SC_MERC_HITUP:
- if (bl->type != BL_MER)
- return 0; // Stats only for Mercenaries
- break;
- case SC_STRFOOD:
- if (sc->data[SC_FOOD_STR_CASH] && sc->data[SC_FOOD_STR_CASH]->val1 > val1)
- return 0;
- break;
- case SC_AGIFOOD:
- if (sc->data[SC_FOOD_AGI_CASH] && sc->data[SC_FOOD_AGI_CASH]->val1 > val1)
- return 0;
- break;
- case SC_VITFOOD:
- if (sc->data[SC_FOOD_VIT_CASH] && sc->data[SC_FOOD_VIT_CASH]->val1 > val1)
- return 0;
- break;
- case SC_INTFOOD:
- if (sc->data[SC_FOOD_INT_CASH] && sc->data[SC_FOOD_INT_CASH]->val1 > val1)
- return 0;
- break;
- case SC_DEXFOOD:
- if (sc->data[SC_FOOD_DEX_CASH] && sc->data[SC_FOOD_DEX_CASH]->val1 > val1)
- return 0;
- break;
- case SC_LUKFOOD:
- if (sc->data[SC_FOOD_LUK_CASH] && sc->data[SC_FOOD_LUK_CASH]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_STR_CASH:
- if (sc->data[SC_STRFOOD] && sc->data[SC_STRFOOD]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_AGI_CASH:
- if (sc->data[SC_AGIFOOD] && sc->data[SC_AGIFOOD]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_VIT_CASH:
- if (sc->data[SC_VITFOOD] && sc->data[SC_VITFOOD]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_INT_CASH:
- if (sc->data[SC_INTFOOD] && sc->data[SC_INTFOOD]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_DEX_CASH:
- if (sc->data[SC_DEXFOOD] && sc->data[SC_DEXFOOD]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_LUK_CASH:
- if (sc->data[SC_LUKFOOD] && sc->data[SC_LUKFOOD]->val1 > val1)
- return 0;
- break;
- case SC_CAMOUFLAGE:
- if (sd && pc_checkskill(sd, RA_CAMOUFLAGE) < 3 && !skill_check_camouflage(bl,NULL))
- return 0;
- break;
- case SC__STRIPACCESSORY:
- if (sd) {
- int i = -1;
- if (!(sd->bonus.unstripable_equip&EQI_ACC_L)) {
- i = sd->equip_index[EQI_ACC_L];
- if (i >= 0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_ARMOR)
- pc_unequipitem(sd,i,3); //L-Accessory
- }
- if (!(sd->bonus.unstripable_equip&EQI_ACC_R)) {
- i = sd->equip_index[EQI_ACC_R];
- if (i >= 0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_ARMOR)
- pc_unequipitem(sd,i,3); //R-Accessory
- }
- if (i < 0)
- return 0;
- }
- if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
- break;
- case SC_TOXIN:
- case SC_PARALYSE:
- case SC_VENOMBLEED:
- case SC_MAGICMUSHROOM:
- case SC_DEATHHURT:
- case SC_PYREXIA:
- case SC_OBLIVIONCURSE:
- case SC_LEECHESEND: {
- // it doesn't stack or even renewed
- int i = SC_TOXIN;
- for (; i<= SC_LEECHESEND; i++)
- if (sc->data[i]) return 0;
- }
- break;
- case SC_SATURDAYNIGHTFEVER:
- if (sc->data[SC_BERSERK] || sc->data[SC_INSPIRATION] || sc->data[SC__BLOODYLUST])
- return 0;
- break;
- }
+ i = sd->equip_index[EQI_HAND_R];
+ if (i>=0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_WEAPON) {
+ opt_flag|=2;
+ pc_unequipitem(sd,i,3);
+ }
+ if (!opt_flag) return 0;
+ }
+ if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
+ break;
+ case SC_STRIPSHIELD:
+ if( val2 == 1 ) val2 = 0; //GX effect. Do not take shield off..
+ else
+ if (sd && !(flag&4)) {
+ int i;
+ if(sd->bonus.unstripable_equip&EQP_SHIELD)
+ return 0;
+ i = sd->equip_index[EQI_HAND_L];
+ if ( i < 0 || !sd->inventory_data[i] || sd->inventory_data[i]->type != IT_ARMOR )
+ return 0;
+ pc_unequipitem(sd,i,3);
+ }
+ if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
+ break;
+ case SC_STRIPARMOR:
+ if (sd && !(flag&4)) {
+ int i;
+ if(sd->bonus.unstripable_equip&EQP_ARMOR)
+ return 0;
+ i = sd->equip_index[EQI_ARMOR];
+ if ( i < 0 || !sd->inventory_data[i] )
+ return 0;
+ pc_unequipitem(sd,i,3);
+ }
+ if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
+ break;
+ case SC_STRIPHELM:
+ if (sd && !(flag&4)) {
+ int i;
+ if(sd->bonus.unstripable_equip&EQP_HELM)
+ return 0;
+ i = sd->equip_index[EQI_HEAD_TOP];
+ if ( i < 0 || !sd->inventory_data[i] )
+ return 0;
+ pc_unequipitem(sd,i,3);
+ }
+ if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
+ break;
+ case SC_MERC_FLEEUP:
+ case SC_MERC_ATKUP:
+ case SC_MERC_HPUP:
+ case SC_MERC_SPUP:
+ case SC_MERC_HITUP:
+ if( bl->type != BL_MER )
+ return 0; // Stats only for Mercenaries
+ break;
+ case SC_STRFOOD:
+ if (sc->data[SC_FOOD_STR_CASH] && sc->data[SC_FOOD_STR_CASH]->val1 > val1)
+ return 0;
+ break;
+ case SC_AGIFOOD:
+ if (sc->data[SC_FOOD_AGI_CASH] && sc->data[SC_FOOD_AGI_CASH]->val1 > val1)
+ return 0;
+ break;
+ case SC_VITFOOD:
+ if (sc->data[SC_FOOD_VIT_CASH] && sc->data[SC_FOOD_VIT_CASH]->val1 > val1)
+ return 0;
+ break;
+ case SC_INTFOOD:
+ if (sc->data[SC_FOOD_INT_CASH] && sc->data[SC_FOOD_INT_CASH]->val1 > val1)
+ return 0;
+ break;
+ case SC_DEXFOOD:
+ if (sc->data[SC_FOOD_DEX_CASH] && sc->data[SC_FOOD_DEX_CASH]->val1 > val1)
+ return 0;
+ break;
+ case SC_LUKFOOD:
+ if (sc->data[SC_FOOD_LUK_CASH] && sc->data[SC_FOOD_LUK_CASH]->val1 > val1)
+ return 0;
+ break;
+ case SC_FOOD_STR_CASH:
+ if (sc->data[SC_STRFOOD] && sc->data[SC_STRFOOD]->val1 > val1)
+ return 0;
+ break;
+ case SC_FOOD_AGI_CASH:
+ if (sc->data[SC_AGIFOOD] && sc->data[SC_AGIFOOD]->val1 > val1)
+ return 0;
+ break;
+ case SC_FOOD_VIT_CASH:
+ if (sc->data[SC_VITFOOD] && sc->data[SC_VITFOOD]->val1 > val1)
+ return 0;
+ break;
+ case SC_FOOD_INT_CASH:
+ if (sc->data[SC_INTFOOD] && sc->data[SC_INTFOOD]->val1 > val1)
+ return 0;
+ break;
+ case SC_FOOD_DEX_CASH:
+ if (sc->data[SC_DEXFOOD] && sc->data[SC_DEXFOOD]->val1 > val1)
+ return 0;
+ break;
+ case SC_FOOD_LUK_CASH:
+ if (sc->data[SC_LUKFOOD] && sc->data[SC_LUKFOOD]->val1 > val1)
+ return 0;
+ break;
+ case SC_CAMOUFLAGE:
+ if( sd && pc_checkskill(sd, RA_CAMOUFLAGE) < 3 && !skill_check_camouflage(bl,NULL) )
+ return 0;
+ break;
+ case SC__STRIPACCESSORY:
+ if( sd ) {
+ int i = -1;
+ if( !(sd->bonus.unstripable_equip&EQI_ACC_L) ) {
+ i = sd->equip_index[EQI_ACC_L];
+ if( i >= 0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_ARMOR )
+ pc_unequipitem(sd,i,3); //L-Accessory
+ } if( !(sd->bonus.unstripable_equip&EQI_ACC_R) ) {
+ i = sd->equip_index[EQI_ACC_R];
+ if( i >= 0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_ARMOR )
+ pc_unequipitem(sd,i,3); //R-Accessory
+ }
+ if( i < 0 )
+ return 0;
+ }
+ if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
+ break;
+ case SC_TOXIN:
+ case SC_PARALYSE:
+ case SC_VENOMBLEED:
+ case SC_MAGICMUSHROOM:
+ case SC_DEATHHURT:
+ case SC_PYREXIA:
+ case SC_OBLIVIONCURSE:
+ case SC_LEECHESEND:
+ { // it doesn't stack or even renewed
+ int i = SC_TOXIN;
+ for(; i<= SC_LEECHESEND; i++)
+ if(sc->data[i]) return 0;
+ }
+ break;
+ case SC_SATURDAYNIGHTFEVER:
+ if (sc->data[SC_BERSERK] || sc->data[SC_INSPIRATION] || sc->data[SC__BLOODYLUST])
+ return 0;
+ break;
+ }
+
+ //Check for BOSS resistances
+ if(status->mode&MD_BOSS && !(flag&1)) {
+ if (type>=SC_COMMON_MIN && type <= SC_COMMON_MAX)
+ return 0;
+ switch (type) {
+ case SC_BLESSING:
+ case SC_DECREASEAGI:
+ case SC_PROVOKE:
+ case SC_COMA:
+ case SC_GRAVITATION:
+ case SC_SUITON:
+ case SC_RICHMANKIM:
+ case SC_ROKISWEIL:
+ case SC_FOGWALL:
+ case SC_FREEZING:
+ case SC_BURNING: // Place here until we have info about its behavior on Boss-monsters. [pakpil]
+ case SC_MARSHOFABYSS:
+ case SC_ADORAMUS:
+ case SC_PARALYSIS:
- //Check for BOSS resistances
- if (status->mode&MD_BOSS && !(flag&1)) {
- if (type>=SC_COMMON_MIN && type <= SC_COMMON_MAX)
- return 0;
- switch (type) {
- case SC_BLESSING:
- case SC_DECREASEAGI:
- case SC_PROVOKE:
- case SC_COMA:
- case SC_GRAVITATION:
- case SC_SUITON:
- case SC_RICHMANKIM:
- case SC_ROKISWEIL:
- case SC_FOGWALL:
- case SC_FREEZING:
- case SC_BURNING: // Place here until we have info about its behavior on Boss-monsters. [pakpil]
- case SC_MARSHOFABYSS:
- case SC_ADORAMUS:
- case SC_PARALYSIS:
-
- // Exploit prevention - kRO Fix
- case SC_PYREXIA:
- case SC_DEATHHURT:
- case SC_TOXIN:
- case SC_PARALYSE:
- case SC_VENOMBLEED:
- case SC_MAGICMUSHROOM:
- case SC_OBLIVIONCURSE:
- case SC_LEECHESEND:
-
- // Ranger Effects
- case SC_BITE:
- case SC_ELECTRICSHOCKER:
- case SC_MAGNETICFIELD:
+ // Exploit prevention - kRO Fix
+ case SC_PYREXIA:
+ case SC_DEATHHURT:
+ case SC_TOXIN:
+ case SC_PARALYSE:
+ case SC_VENOMBLEED:
+ case SC_MAGICMUSHROOM:
+ case SC_OBLIVIONCURSE:
+ case SC_LEECHESEND:
- return 0;
- }
- }
+ // Ranger Effects
+ case SC_BITE:
+ case SC_ELECTRICSHOCKER:
+ case SC_MAGNETICFIELD:
- //Before overlapping fail, one must check for status cured.
- switch (type) {
- case SC_BLESSING:
- //TO-DO Blessing and Agi up should do 1 damage against players on Undead Status, even on PvM
- //but cannot be plagiarized (this requires aegis investigation on packets and official behavior) [Brainstorm]
- if ((!undead_flag && status->race!=RC_DEMON) || bl->type == BL_PC) {
- status_change_end(bl, SC_CURSE, INVALID_TIMER);
- if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
- status_change_end(bl, SC_STONE, INVALID_TIMER);
- }
- break;
- case SC_INCREASEAGI:
- status_change_end(bl, SC_DECREASEAGI, INVALID_TIMER);
- break;
- case SC_QUAGMIRE:
- status_change_end(bl, SC_CONCENTRATE, INVALID_TIMER);
- status_change_end(bl, SC_TRUESIGHT, INVALID_TIMER);
- status_change_end(bl, SC_WINDWALK, INVALID_TIMER);
- //Also blocks the ones below...
- case SC_DECREASEAGI:
- status_change_end(bl, SC_CARTBOOST, INVALID_TIMER);
- //Also blocks the ones below...
- case SC_DONTFORGETME:
- status_change_end(bl, SC_INCREASEAGI, INVALID_TIMER);
- status_change_end(bl, SC_ADRENALINE, INVALID_TIMER);
- status_change_end(bl, SC_ADRENALINE2, INVALID_TIMER);
- status_change_end(bl, SC_SPEARQUICKEN, INVALID_TIMER);
- status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
- status_change_end(bl, SC_ONEHAND, INVALID_TIMER);
- status_change_end(bl, SC_MERC_QUICKEN, INVALID_TIMER);
- status_change_end(bl, SC_ACCELERATION, INVALID_TIMER);
- break;
- case SC_ONEHAND:
- //Removes the Aspd potion effect, as reported by Vicious. [Skotlex]
- status_change_end(bl, SC_ASPDPOTION0, INVALID_TIMER);
- status_change_end(bl, SC_ASPDPOTION1, INVALID_TIMER);
- status_change_end(bl, SC_ASPDPOTION2, INVALID_TIMER);
- status_change_end(bl, SC_ASPDPOTION3, INVALID_TIMER);
- break;
- case SC_MAXOVERTHRUST:
- //Cancels Normal Overthrust. [Skotlex]
- status_change_end(bl, SC_OVERTHRUST, INVALID_TIMER);
- break;
- case SC_KYRIE:
- //Cancels Assumptio
- status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
- break;
- case SC_DELUGE:
- if (sc->data[SC_FOGWALL] && sc->data[SC_BLIND])
- status_change_end(bl, SC_BLIND, INVALID_TIMER);
- break;
- case SC_SILENCE:
- if (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF)
- status_change_end(bl, SC_GOSPEL, INVALID_TIMER);
- break;
- case SC_HIDING:
- status_change_end(bl, SC_CLOSECONFINE, INVALID_TIMER);
- status_change_end(bl, SC_CLOSECONFINE2, INVALID_TIMER);
- break;
- case SC__BLOODYLUST:
- case SC_BERSERK:
- if (battle_config.berserk_cancels_buffs) {
- status_change_end(bl, SC_ONEHAND, INVALID_TIMER);
- status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
- status_change_end(bl, SC_CONCENTRATION, INVALID_TIMER);
- status_change_end(bl, SC_PARRYING, INVALID_TIMER);
- status_change_end(bl, SC_AURABLADE, INVALID_TIMER);
- status_change_end(bl, SC_MERC_QUICKEN, INVALID_TIMER);
- }
+ return 0;
+ }
+ }
+
+ //Before overlapping fail, one must check for status cured.
+ switch (type) {
+ case SC_BLESSING:
+ //TO-DO Blessing and Agi up should do 1 damage against players on Undead Status, even on PvM
+ //but cannot be plagiarized (this requires aegis investigation on packets and official behavior) [Brainstorm]
+ if ((!undead_flag && status->race!=RC_DEMON) || bl->type == BL_PC) {
+ status_change_end(bl, SC_CURSE, INVALID_TIMER);
+ if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
+ status_change_end(bl, SC_STONE, INVALID_TIMER);
+ }
+ break;
+ case SC_INCREASEAGI:
+ status_change_end(bl, SC_DECREASEAGI, INVALID_TIMER);
+ break;
+ case SC_QUAGMIRE:
+ status_change_end(bl, SC_CONCENTRATE, INVALID_TIMER);
+ status_change_end(bl, SC_TRUESIGHT, INVALID_TIMER);
+ status_change_end(bl, SC_WINDWALK, INVALID_TIMER);
+ //Also blocks the ones below...
+ case SC_DECREASEAGI:
+ status_change_end(bl, SC_CARTBOOST, INVALID_TIMER);
+ //Also blocks the ones below...
+ case SC_DONTFORGETME:
+ status_change_end(bl, SC_INCREASEAGI, INVALID_TIMER);
+ status_change_end(bl, SC_ADRENALINE, INVALID_TIMER);
+ status_change_end(bl, SC_ADRENALINE2, INVALID_TIMER);
+ status_change_end(bl, SC_SPEARQUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_ONEHAND, INVALID_TIMER);
+ status_change_end(bl, SC_MERC_QUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_ACCELERATION, INVALID_TIMER);
+ break;
+ case SC_ONEHAND:
+ //Removes the Aspd potion effect, as reported by Vicious. [Skotlex]
+ status_change_end(bl, SC_ASPDPOTION0, INVALID_TIMER);
+ status_change_end(bl, SC_ASPDPOTION1, INVALID_TIMER);
+ status_change_end(bl, SC_ASPDPOTION2, INVALID_TIMER);
+ status_change_end(bl, SC_ASPDPOTION3, INVALID_TIMER);
+ break;
+ case SC_MAXOVERTHRUST:
+ //Cancels Normal Overthrust. [Skotlex]
+ status_change_end(bl, SC_OVERTHRUST, INVALID_TIMER);
+ break;
+ case SC_KYRIE:
+ //Cancels Assumptio
+ status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
+ break;
+ case SC_DELUGE:
+ if (sc->data[SC_FOGWALL] && sc->data[SC_BLIND])
+ status_change_end(bl, SC_BLIND, INVALID_TIMER);
+ break;
+ case SC_SILENCE:
+ if (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF)
+ status_change_end(bl, SC_GOSPEL, INVALID_TIMER);
+ break;
+ case SC_HIDING:
+ status_change_end(bl, SC_CLOSECONFINE, INVALID_TIMER);
+ status_change_end(bl, SC_CLOSECONFINE2, INVALID_TIMER);
+ break;
+ case SC__BLOODYLUST:
+ case SC_BERSERK:
+ if(battle_config.berserk_cancels_buffs) {
+ status_change_end(bl, SC_ONEHAND, INVALID_TIMER);
+ status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_CONCENTRATION, INVALID_TIMER);
+ status_change_end(bl, SC_PARRYING, INVALID_TIMER);
+ status_change_end(bl, SC_AURABLADE, INVALID_TIMER);
+ status_change_end(bl, SC_MERC_QUICKEN, INVALID_TIMER);
+ }
#ifdef RENEWAL
- else {
- status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
- }
+ else {
+ status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
+ }
#endif
- break;
- case SC_ASSUMPTIO:
- status_change_end(bl, SC_KYRIE, INVALID_TIMER);
- status_change_end(bl, SC_KAITE, INVALID_TIMER);
- break;
- case SC_KAITE:
- status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
- break;
- case SC_CARTBOOST:
- if (sc->data[SC_DECREASEAGI]) {
- //Cancel Decrease Agi, but take no further effect [Skotlex]
- status_change_end(bl, SC_DECREASEAGI, INVALID_TIMER);
- return 0;
- }
- break;
- case SC_FUSION:
- status_change_end(bl, SC_SPIRIT, INVALID_TIMER);
- break;
- case SC_ADJUSTMENT:
- status_change_end(bl, SC_MADNESSCANCEL, INVALID_TIMER);
- break;
- case SC_MADNESSCANCEL:
- status_change_end(bl, SC_ADJUSTMENT, INVALID_TIMER);
- break;
- //NPC_CHANGEUNDEAD will debuff Blessing and Agi Up
- case SC_CHANGEUNDEAD:
- status_change_end(bl, SC_BLESSING, INVALID_TIMER);
- status_change_end(bl, SC_INCREASEAGI, INVALID_TIMER);
- break;
- case SC_STRFOOD:
- status_change_end(bl, SC_FOOD_STR_CASH, INVALID_TIMER);
- break;
- case SC_AGIFOOD:
- status_change_end(bl, SC_FOOD_AGI_CASH, INVALID_TIMER);
- break;
- case SC_VITFOOD:
- status_change_end(bl, SC_FOOD_VIT_CASH, INVALID_TIMER);
- break;
- case SC_INTFOOD:
- status_change_end(bl, SC_FOOD_INT_CASH, INVALID_TIMER);
- break;
- case SC_DEXFOOD:
- status_change_end(bl, SC_FOOD_DEX_CASH, INVALID_TIMER);
- break;
- case SC_LUKFOOD:
- status_change_end(bl, SC_FOOD_LUK_CASH, INVALID_TIMER);
- break;
- case SC_FOOD_STR_CASH:
- status_change_end(bl, SC_STRFOOD, INVALID_TIMER);
- break;
- case SC_FOOD_AGI_CASH:
- status_change_end(bl, SC_AGIFOOD, INVALID_TIMER);
- break;
- case SC_FOOD_VIT_CASH:
- status_change_end(bl, SC_VITFOOD, INVALID_TIMER);
- break;
- case SC_FOOD_INT_CASH:
- status_change_end(bl, SC_INTFOOD, INVALID_TIMER);
- break;
- case SC_FOOD_DEX_CASH:
- status_change_end(bl, SC_DEXFOOD, INVALID_TIMER);
- break;
- case SC_FOOD_LUK_CASH:
- status_change_end(bl, SC_LUKFOOD, INVALID_TIMER);
- break;
- case SC_FIGHTINGSPIRIT:
- status_change_end(bl, type, INVALID_TIMER); // Remove previous one.
- break;
- case SC_MARSHOFABYSS:
- status_change_end(bl, SC_INCAGI, INVALID_TIMER);
- status_change_end(bl, SC_WINDWALK, INVALID_TIMER);
- status_change_end(bl, SC_ASPDPOTION0, INVALID_TIMER);
- status_change_end(bl, SC_ASPDPOTION1, INVALID_TIMER);
- status_change_end(bl, SC_ASPDPOTION2, INVALID_TIMER);
- status_change_end(bl, SC_ASPDPOTION3, INVALID_TIMER);
- break;
- case SC_SWINGDANCE:
- case SC_SYMPHONYOFLOVER:
- case SC_MOONLITSERENADE:
- case SC_RUSHWINDMILL:
- case SC_ECHOSONG:
+ break;
+ case SC_ASSUMPTIO:
+ status_change_end(bl, SC_KYRIE, INVALID_TIMER);
+ status_change_end(bl, SC_KAITE, INVALID_TIMER);
+ break;
+ case SC_KAITE:
+ status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
+ break;
+ case SC_CARTBOOST:
+ if(sc->data[SC_DECREASEAGI])
+ { //Cancel Decrease Agi, but take no further effect [Skotlex]
+ status_change_end(bl, SC_DECREASEAGI, INVALID_TIMER);
+ return 0;
+ }
+ break;
+ case SC_FUSION:
+ status_change_end(bl, SC_SPIRIT, INVALID_TIMER);
+ break;
+ case SC_ADJUSTMENT:
+ status_change_end(bl, SC_MADNESSCANCEL, INVALID_TIMER);
+ break;
+ case SC_MADNESSCANCEL:
+ status_change_end(bl, SC_ADJUSTMENT, INVALID_TIMER);
+ break;
+ //NPC_CHANGEUNDEAD will debuff Blessing and Agi Up
+ case SC_CHANGEUNDEAD:
+ status_change_end(bl, SC_BLESSING, INVALID_TIMER);
+ status_change_end(bl, SC_INCREASEAGI, INVALID_TIMER);
+ break;
+ case SC_STRFOOD:
+ status_change_end(bl, SC_FOOD_STR_CASH, INVALID_TIMER);
+ break;
+ case SC_AGIFOOD:
+ status_change_end(bl, SC_FOOD_AGI_CASH, INVALID_TIMER);
+ break;
+ case SC_VITFOOD:
+ status_change_end(bl, SC_FOOD_VIT_CASH, INVALID_TIMER);
+ break;
+ case SC_INTFOOD:
+ status_change_end(bl, SC_FOOD_INT_CASH, INVALID_TIMER);
+ break;
+ case SC_DEXFOOD:
+ status_change_end(bl, SC_FOOD_DEX_CASH, INVALID_TIMER);
+ break;
+ case SC_LUKFOOD:
+ status_change_end(bl, SC_FOOD_LUK_CASH, INVALID_TIMER);
+ break;
+ case SC_FOOD_STR_CASH:
+ status_change_end(bl, SC_STRFOOD, INVALID_TIMER);
+ break;
+ case SC_FOOD_AGI_CASH:
+ status_change_end(bl, SC_AGIFOOD, INVALID_TIMER);
+ break;
+ case SC_FOOD_VIT_CASH:
+ status_change_end(bl, SC_VITFOOD, INVALID_TIMER);
+ break;
+ case SC_FOOD_INT_CASH:
+ status_change_end(bl, SC_INTFOOD, INVALID_TIMER);
+ break;
+ case SC_FOOD_DEX_CASH:
+ status_change_end(bl, SC_DEXFOOD, INVALID_TIMER);
+ break;
+ case SC_FOOD_LUK_CASH:
+ status_change_end(bl, SC_LUKFOOD, INVALID_TIMER);
+ break;
+ case SC_FIGHTINGSPIRIT:
+ status_change_end(bl, type, INVALID_TIMER); // Remove previous one.
+ break;
+ case SC_MARSHOFABYSS:
+ status_change_end(bl, SC_INCAGI, INVALID_TIMER);
+ status_change_end(bl, SC_WINDWALK, INVALID_TIMER);
+ status_change_end(bl, SC_ASPDPOTION0, INVALID_TIMER);
+ status_change_end(bl, SC_ASPDPOTION1, INVALID_TIMER);
+ status_change_end(bl, SC_ASPDPOTION2, INVALID_TIMER);
+ status_change_end(bl, SC_ASPDPOTION3, INVALID_TIMER);
+ break;
+ case SC_SWINGDANCE:
+ case SC_SYMPHONYOFLOVER:
+ case SC_MOONLITSERENADE:
+ case SC_RUSHWINDMILL:
+ case SC_ECHOSONG:
case SC_HARMONIZE: //group A doesn't overlap
if (type != SC_SWINGDANCE) status_change_end(bl, SC_SWINGDANCE, INVALID_TIMER);
if (type != SC_SYMPHONYOFLOVER) status_change_end(bl, SC_SYMPHONYOFLOVER, INVALID_TIMER);
@@ -6991,1952 +6908,1930 @@ int status_change_start(struct block_list *bl,enum sc_type type,int rate,int val
}
}
break;
- case SC_REFLECTSHIELD:
- status_change_end(bl, SC_REFLECTDAMAGE, INVALID_TIMER);
- break;
- case SC_REFLECTDAMAGE:
- status_change_end(bl, SC_REFLECTSHIELD, INVALID_TIMER);
- break;
- case SC_SHIELDSPELL_DEF:
- case SC_SHIELDSPELL_MDEF:
- case SC_SHIELDSPELL_REF:
- status_change_end(bl, SC_MAGNIFICAT, INVALID_TIMER);
- if (type != SC_SHIELDSPELL_DEF)
- status_change_end(bl, SC_SHIELDSPELL_DEF, INVALID_TIMER);
- if (type != SC_SHIELDSPELL_MDEF)
- status_change_end(bl, SC_SHIELDSPELL_MDEF, INVALID_TIMER);
- if (type != SC_SHIELDSPELL_REF)
- status_change_end(bl, SC_SHIELDSPELL_REF, INVALID_TIMER);
- break;
- case SC_GT_ENERGYGAIN:
- case SC_GT_CHANGE:
- case SC_GT_REVITALIZE:
- if (type != SC_GT_REVITALIZE)
- status_change_end(bl, SC_GT_REVITALIZE, INVALID_TIMER);
- if (type != SC_GT_ENERGYGAIN)
- status_change_end(bl, SC_GT_ENERGYGAIN, INVALID_TIMER);
- if (type != SC_GT_CHANGE)
- status_change_end(bl, SC_GT_CHANGE, INVALID_TIMER);
- break;
- case SC_INVINCIBLE:
- status_change_end(bl, SC_INVINCIBLEOFF, INVALID_TIMER);
- break;
- case SC_INVINCIBLEOFF:
- status_change_end(bl, SC_INVINCIBLE, INVALID_TIMER);
- break;
- case SC_MAGICPOWER:
- status_change_end(bl, type, INVALID_TIMER);
- break;
- }
-
- //Check for overlapping fails
- if ((sce = sc->data[type])) {
- switch (type) {
- case SC_MERC_FLEEUP:
- case SC_MERC_ATKUP:
- case SC_MERC_HPUP:
- case SC_MERC_SPUP:
- case SC_MERC_HITUP:
- if (sce->val1 > val1)
- val1 = sce->val1;
- break;
- case SC_ADRENALINE:
- case SC_ADRENALINE2:
- case SC_WEAPONPERFECTION:
- case SC_OVERTHRUST:
- if (sce->val2 > val2)
- return 0;
- break;
- case SC_S_LIFEPOTION:
- case SC_L_LIFEPOTION:
- case SC_BOSSMAPINFO:
- case SC_STUN:
- case SC_SLEEP:
- case SC_POISON:
- case SC_CURSE:
- case SC_SILENCE:
- case SC_CONFUSION:
- case SC_BLIND:
- case SC_BLEEDING:
- case SC_DPOISON:
- case SC_CLOSECONFINE2: //Can't be re-closed in.
- case SC_MARIONETTE:
- case SC_MARIONETTE2:
- case SC_NOCHAT:
- case SC_CHANGE: //Otherwise your Hp/Sp would get refilled while still within effect of the last invocation.
- case SC__INVISIBILITY:
- case SC__ENERVATION:
- case SC__GROOMY:
- case SC__IGNORANCE:
- case SC__LAZINESS:
- case SC__WEAKNESS:
- case SC__UNLUCKY:
- return 0;
- case SC_COMBO:
- case SC_DANCING:
- case SC_DEVOTION:
- case SC_ASPDPOTION0:
- case SC_ASPDPOTION1:
- case SC_ASPDPOTION2:
- case SC_ASPDPOTION3:
- case SC_ATKPOTION:
- case SC_MATKPOTION:
- case SC_ENCHANTARMS:
- case SC_ARMOR_ELEMENT:
- case SC_ARMOR_RESIST:
- break;
- case SC_GOSPEL:
- //Must not override a casting gospel char.
- if (sce->val4 == BCT_SELF)
- return 0;
- if (sce->val1 > val1)
- return 1;
- break;
- case SC_ENDURE:
- if (sce->val4 && !val4)
- return 1; //Don't let you override infinite endure.
- if (sce->val1 > val1)
- return 1;
- break;
- case SC_KAAHI:
- //Kaahi overwrites previous level regardless of existing level.
- //Delete timer if it exists.
- if (sce->val4 != INVALID_TIMER) {
- delete_timer(sce->val4,kaahi_heal_timer);
- sce->val4 = INVALID_TIMER;
- }
- break;
- case SC_JAILED:
- //When a player is already jailed, do not edit the jail data.
- val2 = sce->val2;
- val3 = sce->val3;
- val4 = sce->val4;
- break;
- case SC_LERADSDEW:
- if (sc && (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]))
- return 0;
- case SC_SHAPESHIFT:
- case SC_PROPERTYWALK:
- break;
- case SC_LEADERSHIP:
- case SC_GLORYWOUNDS:
- case SC_SOULCOLD:
- case SC_HAWKEYES:
- if (sce->val4 && !val4) //you cannot override master guild aura
- return 0;
- break;
- case SC_JOINTBEAT:
- val2 |= sce->val2; // stackable ailments
- default:
- if (sce->val1 > val1)
- return 1; //Return true to not mess up skill animations. [Skotlex]
- }
- }
-
- vd = status_get_viewdata(bl);
- calc_flag = StatusChangeFlagTable[type];
- if (!(flag&4)) //&4 - Do not parse val settings when loading SCs
- switch (type) {
- case SC_DECREASEAGI:
- case SC_INCREASEAGI:
- val2 = 2 + val1; //Agi change
- break;
- case SC_ENDURE:
- val2 = 7; // Hit-count [Celest]
- if (!(flag&1) && (bl->type&(BL_PC|BL_MER)) && !map_flag_gvg(bl->m) && !map[bl->m].flag.battleground && !val4) {
- struct map_session_data *tsd;
- if (sd) {
- int i;
- for (i = 0; i < 5; i++) {
- if (sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])))
- status_change_start(&tsd->bl, type, 10000, val1, val2, val3, val4, tick, 1);
- }
- } else if (bl->type == BL_MER && ((TBL_MER *)bl)->devotion_flag && (tsd = ((TBL_MER *)bl)->master))
- status_change_start(&tsd->bl, type, 10000, val1, val2, val3, val4, tick, 1);
- }
- //val4 signals infinite endure (if val4 == 2 it is infinite endure from Berserk)
- if (val4)
- tick = -1;
- break;
- case SC_AUTOBERSERK:
- if (status->hp < status->max_hp>>2 &&
- (!sc->data[SC_PROVOKE] || sc->data[SC_PROVOKE]->val2==0))
- sc_start4(bl,SC_PROVOKE,100,10,1,0,0,60000);
- tick = -1;
- break;
- case SC_SIGNUMCRUCIS:
- val2 = 10 + 4*val1; //Def reduction
- tick = -1;
- clif_emotion(bl,E_SWT);
- break;
- case SC_MAXIMIZEPOWER:
- tick_time = val2 = tick>0?tick:60000;
- tick = -1; // duration sent to the client should be infinite
- break;
- case SC_EDP: // [Celest]
- val2 = val1 + 2; //Chance to Poison enemies.
+ case SC_REFLECTSHIELD:
+ status_change_end(bl, SC_REFLECTDAMAGE, INVALID_TIMER);
+ break;
+ case SC_REFLECTDAMAGE:
+ status_change_end(bl, SC_REFLECTSHIELD, INVALID_TIMER);
+ break;
+ case SC_SHIELDSPELL_DEF:
+ case SC_SHIELDSPELL_MDEF:
+ case SC_SHIELDSPELL_REF:
+ status_change_end(bl, SC_MAGNIFICAT, INVALID_TIMER);
+ if( type != SC_SHIELDSPELL_DEF )
+ status_change_end(bl, SC_SHIELDSPELL_DEF, INVALID_TIMER);
+ if( type != SC_SHIELDSPELL_MDEF )
+ status_change_end(bl, SC_SHIELDSPELL_MDEF, INVALID_TIMER);
+ if( type != SC_SHIELDSPELL_REF )
+ status_change_end(bl, SC_SHIELDSPELL_REF, INVALID_TIMER);
+ break;
+ case SC_GT_ENERGYGAIN:
+ case SC_GT_CHANGE:
+ case SC_GT_REVITALIZE:
+ if( type != SC_GT_REVITALIZE )
+ status_change_end(bl, SC_GT_REVITALIZE, INVALID_TIMER);
+ if( type != SC_GT_ENERGYGAIN )
+ status_change_end(bl, SC_GT_ENERGYGAIN, INVALID_TIMER);
+ if( type != SC_GT_CHANGE )
+ status_change_end(bl, SC_GT_CHANGE, INVALID_TIMER);
+ break;
+ case SC_INVINCIBLE:
+ status_change_end(bl, SC_INVINCIBLEOFF, INVALID_TIMER);
+ break;
+ case SC_INVINCIBLEOFF:
+ status_change_end(bl, SC_INVINCIBLE, INVALID_TIMER);
+ break;
+ }
+
+ //Check for overlapping fails
+ if( (sce = sc->data[type]) ) {
+ switch( type ) {
+ case SC_MERC_FLEEUP:
+ case SC_MERC_ATKUP:
+ case SC_MERC_HPUP:
+ case SC_MERC_SPUP:
+ case SC_MERC_HITUP:
+ if( sce->val1 > val1 )
+ val1 = sce->val1;
+ break;
+ case SC_ADRENALINE:
+ case SC_ADRENALINE2:
+ case SC_WEAPONPERFECTION:
+ case SC_OVERTHRUST:
+ if (sce->val2 > val2)
+ return 0;
+ break;
+ case SC_S_LIFEPOTION:
+ case SC_L_LIFEPOTION:
+ case SC_BOSSMAPINFO:
+ case SC_STUN:
+ case SC_SLEEP:
+ case SC_POISON:
+ case SC_CURSE:
+ case SC_SILENCE:
+ case SC_CONFUSION:
+ case SC_BLIND:
+ case SC_BLEEDING:
+ case SC_DPOISON:
+ case SC_CLOSECONFINE2: //Can't be re-closed in.
+ case SC_MARIONETTE:
+ case SC_MARIONETTE2:
+ case SC_NOCHAT:
+ case SC_CHANGE: //Otherwise your Hp/Sp would get refilled while still within effect of the last invocation.
+ case SC__INVISIBILITY:
+ case SC__ENERVATION:
+ case SC__GROOMY:
+ case SC__IGNORANCE:
+ case SC__LAZINESS:
+ case SC__WEAKNESS:
+ case SC__UNLUCKY:
+ return 0;
+ case SC_COMBO:
+ case SC_DANCING:
+ case SC_DEVOTION:
+ case SC_ASPDPOTION0:
+ case SC_ASPDPOTION1:
+ case SC_ASPDPOTION2:
+ case SC_ASPDPOTION3:
+ case SC_ATKPOTION:
+ case SC_MATKPOTION:
+ case SC_ENCHANTARMS:
+ case SC_ARMOR_ELEMENT:
+ case SC_ARMOR_RESIST:
+ break;
+ case SC_GOSPEL:
+ //Must not override a casting gospel char.
+ if(sce->val4 == BCT_SELF)
+ return 0;
+ if(sce->val1 > val1)
+ return 1;
+ break;
+ case SC_ENDURE:
+ if(sce->val4 && !val4)
+ return 1; //Don't let you override infinite endure.
+ if(sce->val1 > val1)
+ return 1;
+ break;
+ case SC_KAAHI:
+ //Kaahi overwrites previous level regardless of existing level.
+ //Delete timer if it exists.
+ if (sce->val4 != INVALID_TIMER) {
+ delete_timer(sce->val4,kaahi_heal_timer);
+ sce->val4 = INVALID_TIMER;
+ }
+ break;
+ case SC_JAILED:
+ //When a player is already jailed, do not edit the jail data.
+ val2 = sce->val2;
+ val3 = sce->val3;
+ val4 = sce->val4;
+ break;
+ case SC_LERADSDEW:
+ if (sc && (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]))
+ return 0;
+ case SC_SHAPESHIFT:
+ case SC_PROPERTYWALK:
+ break;
+ case SC_LEADERSHIP:
+ case SC_GLORYWOUNDS:
+ case SC_SOULCOLD:
+ case SC_HAWKEYES:
+ if( sce->val4 && !val4 )//you cannot override master guild aura
+ return 0;
+ break;
+ case SC_JOINTBEAT:
+ val2 |= sce->val2; // stackable ailments
+ default:
+ if(sce->val1 > val1)
+ return 1; //Return true to not mess up skill animations. [Skotlex]
+ }
+ }
+
+ vd = status_get_viewdata(bl);
+ calc_flag = StatusChangeFlagTable[type];
+ if(!(flag&4)) //&4 - Do not parse val settings when loading SCs
+ switch(type)
+ {
+ case SC_DECREASEAGI:
+ case SC_INCREASEAGI:
+ val2 = 2 + val1; //Agi change
+ break;
+ case SC_ENDURE:
+ val2 = 7; // Hit-count [Celest]
+ if( !(flag&1) && (bl->type&(BL_PC|BL_MER)) && !map_flag_gvg(bl->m) && !map[bl->m].flag.battleground && !val4 )
+ {
+ struct map_session_data *tsd;
+ if( sd )
+ {
+ int i;
+ for( i = 0; i < 5; i++ )
+ {
+ if( sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])) )
+ status_change_start(&tsd->bl, type, 10000, val1, val2, val3, val4, tick, 1);
+ }
+ }
+ else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) )
+ status_change_start(&tsd->bl, type, 10000, val1, val2, val3, val4, tick, 1);
+ }
+ //val4 signals infinite endure (if val4 == 2 it is infinite endure from Berserk)
+ if( val4 )
+ tick = -1;
+ break;
+ case SC_AUTOBERSERK:
+ if (status->hp < status->max_hp>>2 &&
+ (!sc->data[SC_PROVOKE] || sc->data[SC_PROVOKE]->val2==0))
+ sc_start4(bl,SC_PROVOKE,100,10,1,0,0,60000);
+ tick = -1;
+ break;
+ case SC_SIGNUMCRUCIS:
+ val2 = 10 + 4*val1; //Def reduction
+ tick = -1;
+ clif_emotion(bl,E_SWT);
+ break;
+ case SC_MAXIMIZEPOWER:
+ tick_time = val2 = tick>0?tick:60000;
+ tick = -1; // duration sent to the client should be infinite
+ break;
+ case SC_EDP: // [Celest]
+ val2 = val1 + 2; //Chance to Poison enemies.
#ifndef RENEWAL_EDP
- val3 = 50*(val1+1); //Damage increase (+50 +50*lv%)
-#endif
- if (sd) //[Ind] - iROwiki says each level increases its duration by 3 seconds
- tick += pc_checkskill(sd,GC_RESEARCHNEWPOISON)*3000;
- break;
- case SC_POISONREACT:
- val2=(val1+1)/2 + val1/10; // Number of counters [Skotlex]
- val3=50; // + 5*val1; //Chance to counter. [Skotlex]
- break;
- case SC_MAGICROD:
- val2 = val1*20; //SP gained
- break;
- case SC_KYRIE:
- val2 = status->max_hp * (val1 * 2 + 10) / 100; //%Max HP to absorb
- val3 = (val1 / 2 + 5); //Hits
- break;
- case SC_MAGICPOWER:
- //val1: Skill lv
- val2 = 1; //Lasts 1 invocation
- val3 = 5*val1; //Matk% increase
- val4 = 0; // 0 = ready to be used, 1 = activated and running
- break;
- case SC_SACRIFICE:
- val2 = 5; //Lasts 5 hits
- tick = -1;
- break;
- case SC_ENCPOISON:
- val2= 250+50*val1; //Poisoning Chance (2.5+0.5%) in 1/10000 rate
- case SC_ASPERSIO:
- case SC_FIREWEAPON:
- case SC_WATERWEAPON:
- case SC_WINDWEAPON:
- case SC_EARTHWEAPON:
- case SC_SHADOWWEAPON:
- case SC_GHOSTWEAPON:
- skill_enchant_elemental_end(bl,type);
- break;
- case SC_ELEMENTALCHANGE:
- // val1 : Element Lvl (if called by skill lvl 1, takes random value between 1 and 4)
- // val2 : Element (When no element, random one is picked)
- // val3 : 0 = called by skill 1 = called by script (fixed level)
- if (!val2) val2 = rnd()%ELE_MAX;
-
- if (val1 == 1 && val3 == 0)
- val1 = 1 + rnd()%4;
- else if (val1 > 4)
- val1 = 4; // Max Level
- val3 = 0; // Not need to keep this info.
- break;
- case SC_PROVIDENCE:
- val2=val1*5; //Race/Ele resist
- break;
- case SC_REFLECTSHIELD:
- val2=10+val1*3; // %Dmg reflected
- if (!(flag&1) && (bl->type&(BL_PC|BL_MER))) {
- struct map_session_data *tsd;
- if (sd) {
- int i;
- for (i = 0; i < 5; i++) {
- if (sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])))
- status_change_start(&tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1);
- }
- } else if (bl->type == BL_MER && ((TBL_MER *)bl)->devotion_flag && (tsd = ((TBL_MER *)bl)->master))
- status_change_start(&tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1);
- }
- break;
- case SC_STRIPWEAPON:
- if (!sd) //Watk reduction
- val2 = 25;
- break;
- case SC_STRIPSHIELD:
- if (!sd) //Def reduction
- val2 = 15;
- break;
- case SC_STRIPARMOR:
- if (!sd) //Vit reduction
- val2 = 40;
- break;
- case SC_STRIPHELM:
- if (!sd) //Int reduction
- val2 = 40;
- break;
- case SC_AUTOSPELL:
- //Val1 Skill LV of Autospell
- //Val2 Skill ID to cast
- //Val3 Max Lv to cast
- val4 = 5 + val1*2; //Chance of casting
- break;
- case SC_VOLCANO:
- val2 = val1*10; //Watk increase
-#ifndef RENEWAL
- if (status->def_ele != ELE_FIRE)
- val2 = 0;
+ val3 = 50*(val1+1); //Damage increase (+50 +50*lv%)
#endif
- break;
- case SC_VIOLENTGALE:
- val2 = val1*3; //Flee increase
+ if( sd )//[Ind] - iROwiki says each level increases its duration by 3 seconds
+ tick += pc_checkskill(sd,GC_RESEARCHNEWPOISON)*3000;
+ break;
+ case SC_POISONREACT:
+ val2=(val1+1)/2 + val1/10; // Number of counters [Skotlex]
+ val3=50; // + 5*val1; //Chance to counter. [Skotlex]
+ break;
+ case SC_MAGICROD:
+ val2 = val1*20; //SP gained
+ break;
+ case SC_KYRIE:
+ val2 = status->max_hp * (val1 * 2 + 10) / 100; //%Max HP to absorb
+ val3 = (val1 / 2 + 5); //Hits
+ break;
+ case SC_MAGICPOWER:
+ //val1: Skill lv
+ val2 = 1; //Lasts 1 invocation
+ val3 = 5*val1; //Matk% increase
+ val4 = 0; // 0 = ready to be used, 1 = activated and running
+ break;
+ case SC_SACRIFICE:
+ val2 = 5; //Lasts 5 hits
+ tick = -1;
+ break;
+ case SC_ENCPOISON:
+ val2= 250+50*val1; //Poisoning Chance (2.5+0.5%) in 1/10000 rate
+ case SC_ASPERSIO:
+ case SC_FIREWEAPON:
+ case SC_WATERWEAPON:
+ case SC_WINDWEAPON:
+ case SC_EARTHWEAPON:
+ case SC_SHADOWWEAPON:
+ case SC_GHOSTWEAPON:
+ skill_enchant_elemental_end(bl,type);
+ break;
+ case SC_ELEMENTALCHANGE:
+ // val1 : Element Lvl (if called by skill lvl 1, takes random value between 1 and 4)
+ // val2 : Element (When no element, random one is picked)
+ // val3 : 0 = called by skill 1 = called by script (fixed level)
+ if( !val2 ) val2 = rnd()%ELE_MAX;
+
+ if( val1 == 1 && val3 == 0 )
+ val1 = 1 + rnd()%4;
+ else if( val1 > 4 )
+ val1 = 4; // Max Level
+ val3 = 0; // Not need to keep this info.
+ break;
+ case SC_PROVIDENCE:
+ val2=val1*5; //Race/Ele resist
+ break;
+ case SC_REFLECTSHIELD:
+ val2=10+val1*3; // %Dmg reflected
+ if( !(flag&1) && (bl->type&(BL_PC|BL_MER)) )
+ {
+ struct map_session_data *tsd;
+ if( sd )
+ {
+ int i;
+ for( i = 0; i < 5; i++ )
+ {
+ if( sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])) )
+ status_change_start(&tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1);
+ }
+ }
+ else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) )
+ status_change_start(&tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1);
+ }
+ break;
+ case SC_STRIPWEAPON:
+ if (!sd) //Watk reduction
+ val2 = 25;
+ break;
+ case SC_STRIPSHIELD:
+ if (!sd) //Def reduction
+ val2 = 15;
+ break;
+ case SC_STRIPARMOR:
+ if (!sd) //Vit reduction
+ val2 = 40;
+ break;
+ case SC_STRIPHELM:
+ if (!sd) //Int reduction
+ val2 = 40;
+ break;
+ case SC_AUTOSPELL:
+ //Val1 Skill LV of Autospell
+ //Val2 Skill ID to cast
+ //Val3 Max Lv to cast
+ val4 = 5 + val1*2; //Chance of casting
+ break;
+ case SC_VOLCANO:
+ val2 = val1*10; //Watk increase
#ifndef RENEWAL
- if (status->def_ele != ELE_WIND)
- val2 = 0;
+ if (status->def_ele != ELE_FIRE)
+ val2 = 0;
#endif
- break;
- case SC_DELUGE:
- val2 = deluge_eff[val1-1]; //HP increase
+ break;
+ case SC_VIOLENTGALE:
+ val2 = val1*3; //Flee increase
+ #ifndef RENEWAL
+ if (status->def_ele != ELE_WIND)
+ val2 = 0;
+ #endif
+ break;
+ case SC_DELUGE:
+ val2 = deluge_eff[val1-1]; //HP increase
#ifndef RENEWAL
- if (status->def_ele != ELE_WATER)
- val2 = 0;
+ if(status->def_ele != ELE_WATER)
+ val2 = 0;
#endif
- break;
- case SC_SUITON:
- if (!val2 || (sd && (sd->class_&MAPID_UPPERMASK) == MAPID_NINJA)) {
- //No penalties.
- val2 = 0; //Agi penalty
- val3 = 0; //Walk speed penalty
- break;
- }
- val3 = 50;
- val2 = 3*((val1+1)/3);
- if (val1 > 4) val2--;
- break;
- case SC_ONEHAND:
- case SC_TWOHANDQUICKEN:
- val2 = 300;
- if (val1 > 10) //For boss casted skills [Skotlex]
- val2 += 20*(val1-10);
- break;
- case SC_MERC_QUICKEN:
- val2 = 300;
- break;
+ break;
+ case SC_SUITON:
+ if (!val2 || (sd && (sd->class_&MAPID_UPPERMASK) == MAPID_NINJA)) {
+ //No penalties.
+ val2 = 0; //Agi penalty
+ val3 = 0; //Walk speed penalty
+ break;
+ }
+ val3 = 50;
+ val2 = 3*((val1+1)/3);
+ if (val1 > 4) val2--;
+ break;
+ case SC_ONEHAND:
+ case SC_TWOHANDQUICKEN:
+ val2 = 300;
+ if (val1 > 10) //For boss casted skills [Skotlex]
+ val2 += 20*(val1-10);
+ break;
+ case SC_MERC_QUICKEN:
+ val2 = 300;
+ break;
#ifndef RENEWAL
- case SC_SPEARQUICKEN:
- val2 = 200+10*val1;
- break;
+ case SC_SPEARQUICKEN:
+ val2 = 200+10*val1;
+ break;
#endif
- case SC_DANCING:
- //val1 : Skill ID + LV
- //val2 : Skill Group of the Dance.
- //val3 : Brings the skilllv (merged into val1 here)
- //val4 : Partner
- if (val1 == CG_MOONLIT)
- clif_status_change(bl,SI_MOONLIT,1,tick,0, 0, 0);
- val1|= (val3<<16);
- val3 = tick/1000; //Tick duration
- tick_time = 1000; // [GodLesZ] tick time
- break;
- case SC_LONGING:
- val2 = 500-100*val1; //Aspd penalty.
- break;
- case SC_EXPLOSIONSPIRITS:
- val2 = 75 + 25*val1; //Cri bonus
- break;
-
- case SC_ASPDPOTION0:
- case SC_ASPDPOTION1:
- case SC_ASPDPOTION2:
- case SC_ASPDPOTION3:
- val2 = 50*(2+type-SC_ASPDPOTION0);
- break;
-
- case SC_WEDDING:
- case SC_XMAS:
- case SC_SUMMER:
- if (!vd) return 0;
- //Store previous values as they could be removed.
- val1 = vd->class_;
- val2 = vd->weapon;
- val3 = vd->shield;
- val4 = vd->cloth_color;
- unit_stop_attack(bl);
- clif_changelook(bl,LOOK_WEAPON,0);
- clif_changelook(bl,LOOK_SHIELD,0);
- clif_changelook(bl,LOOK_BASE,type==SC_WEDDING?JOB_WEDDING:type==SC_XMAS?JOB_XMAS:JOB_SUMMER);
- clif_changelook(bl,LOOK_CLOTHES_COLOR,vd->cloth_color);
- break;
- case SC_NOCHAT:
- // [GodLesZ] FIXME: is this correct? a hardcoded interval of 60sec? what about configuration ?_?
- tick = 60000;
- val1 = battle_config.manner_system; //Mute filters.
- if (sd) {
- clif_changestatus(sd,SP_MANNER,sd->status.manner);
- clif_updatestatus(sd,SP_MANNER);
- }
- break;
-
- case SC_STONE:
- val3 = tick/1000; //Petrified HP-damage iterations.
- if (val3 < 1) val3 = 1;
- tick = val4; //Petrifying time.
- tick = max(tick, 1000); //Min time
- calc_flag = 0; //Actual status changes take effect on petrified state.
- break;
-
- case SC_DPOISON:
- //Lose 10/15% of your life as long as it doesn't brings life below 25%
- if (status->hp > status->max_hp>>2) {
- int diff = status->max_hp*(bl->type==BL_PC?10:15)/100;
- if (status->hp - diff < status->max_hp>>2)
- diff = status->hp - (status->max_hp>>2);
- if (val2 && bl->type == BL_MOB) {
- struct block_list *src = map_id2bl(val2);
- if (src)
- mob_log_damage((TBL_MOB *)bl,src,diff);
- }
- status_zap(bl, diff, 0);
- }
- // fall through
- case SC_POISON:
- val3 = tick/1000; //Damage iterations
- if (val3 < 1) val3 = 1;
- tick_time = 1000; // [GodLesZ] tick time
- //val4: HP damage
- if (bl->type == BL_PC)
- val4 = (type == SC_DPOISON) ? 3 + status->max_hp/50 : 3 + status->max_hp*3/200;
- else
- val4 = (type == SC_DPOISON) ? 3 + status->max_hp/100 : 3 + status->max_hp/200;
-
- break;
- case SC_CONFUSION:
- clif_emotion(bl,E_WHAT);
- break;
- case SC_BLEEDING:
- val4 = tick/10000;
- if (!val4) val4 = 1;
- tick_time = 10000; // [GodLesZ] tick time
- break;
- case SC_S_LIFEPOTION:
- case SC_L_LIFEPOTION:
- if (val1 == 0) return 0;
- // val1 = heal percent/amout
- // val2 = seconds between heals
- // val4 = total of heals
- if (val2 < 1) val2 = 1;
- if ((val4 = tick/(val2 * 1000)) < 1)
- val4 = 1;
- tick_time = val2 * 1000; // [GodLesZ] tick time
- break;
- case SC_BOSSMAPINFO:
- if (sd != NULL) {
- struct mob_data *boss_md = map_getmob_boss(bl->m); // Search for Boss on this Map
- if (boss_md == NULL || boss_md->bl.prev == NULL) {
- // No MVP on this map - MVP is dead
- clif_bossmapinfo(sd->fd, boss_md, 1);
- return 0; // No need to start SC
- }
- val1 = boss_md->bl.id;
- if ((val4 = tick/1000) < 1)
- val4 = 1;
- tick_time = 1000; // [GodLesZ] tick time
- }
- break;
- case SC_HIDING:
- val2 = tick/1000;
- tick_time = 1000; // [GodLesZ] tick time
- val3 = 0; // unused, previously speed adjustment
- val4 = val1+3; //Seconds before SP substraction happen.
- break;
- case SC_CHASEWALK:
- val2 = tick>0?tick:10000; //Interval at which SP is drained.
- val3 = 35 - 5 * val1; //Speed adjustment.
- if (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_ROGUE)
- val3 -= 40;
- val4 = 10+val1*2; //SP cost.
- if (map_flag_gvg(bl->m) || map[bl->m].flag.battleground) val4 *= 5;
- break;
- case SC_CLOAKING:
- if (!sd) //Monsters should be able to walk with no penalties. [Skotlex]
- val1 = 10;
- tick_time = val2 = tick>0?tick:60000; //SP consumption rate.
- tick = -1; // duration sent to the client should be infinite
- val3 = 0; // unused, previously walk speed adjustment
- //val4&1 signals the presence of a wall.
- //val4&2 makes cloak not end on normal attacks [Skotlex]
- //val4&4 makes cloak not end on using skills
- if (bl->type == BL_PC || (bl->type == BL_MOB && ((TBL_MOB *)bl)->special_state.clone)) //Standard cloaking.
- val4 |= battle_config.pc_cloak_check_type&7;
- else
- val4 |= battle_config.monster_cloak_check_type&7;
- break;
- case SC_SIGHT: /* splash status */
- case SC_RUWACH:
- case SC_SIGHTBLASTER:
- val3 = skill_get_splash(val2, val1); //Val2 should bring the skill-id.
- val2 = tick/250;
- tick_time = 10; // [GodLesZ] tick time
- break;
-
- //Permanent effects.
- case SC_AETERNA:
- case SC_MODECHANGE:
- case SC_WEIGHT50:
- case SC_WEIGHT90:
- case SC_BROKENWEAPON:
- case SC_BROKENARMOR:
- case SC_READYSTORM:
- case SC_READYDOWN:
- case SC_READYCOUNTER:
- case SC_READYTURN:
- case SC_DODGE:
- case SC_PUSH_CART:
- tick = -1;
- break;
-
- case SC_AUTOGUARD:
- if (!(flag&1)) {
- struct map_session_data *tsd;
- int i,t;
- for (i = val2 = 0; i < val1; i++) {
- t = 5-(i>>1);
- val2 += (t < 0)? 1:t;
- }
-
- if (bl->type&(BL_PC|BL_MER)) {
- if (sd) {
- for (i = 0; i < 5; i++) {
- if (sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])))
- status_change_start(&tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1);
- }
- } else if (bl->type == BL_MER && ((TBL_MER *)bl)->devotion_flag && (tsd = ((TBL_MER *)bl)->master))
- status_change_start(&tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1);
- }
- }
- break;
-
- case SC_DEFENDER:
- if (!(flag&1)) {
- val2 = 5 + 15*val1; //Damage reduction
- val3 = 0; // unused, previously speed adjustment
- val4 = 250 - 50*val1; //Aspd adjustment
-
- if (sd) {
- struct map_session_data *tsd;
- int i;
- for (i = 0; i < 5; i++) {
- //See if there are devoted characters, and pass the status to them. [Skotlex]
- if (sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])))
- status_change_start(&tsd->bl,type,10000,val1,5+val1*5,val3,val4,tick,1);
- }
- }
- }
- break;
+ case SC_DANCING:
+ //val1 : Skill ID + LV
+ //val2 : Skill Group of the Dance.
+ //val3 : Brings the skilllv (merged into val1 here)
+ //val4 : Partner
+ if (val1 == CG_MOONLIT)
+ clif_status_change(bl,SI_MOONLIT,1,tick,0, 0, 0);
+ val1|= (val3<<16);
+ val3 = tick/1000; //Tick duration
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_LONGING:
+ val2 = 500-100*val1; //Aspd penalty.
+ break;
+ case SC_EXPLOSIONSPIRITS:
+ val2 = 75 + 25*val1; //Cri bonus
+ break;
- case SC_TENSIONRELAX:
- if (sd) {
- pc_setsit(sd);
- clif_sitting(&sd->bl);
- }
- val2 = 12; //SP cost
- val4 = 10000; //Decrease at 10secs intervals.
- val3 = tick/val4;
- tick = -1; // duration sent to the client should be infinite
- tick_time = val4; // [GodLesZ] tick time
- break;
- case SC_PARRYING:
- val2 = 20 + val1*3; //Block Chance
- break;
-
- case SC_WINDWALK:
- val2 = (val1+1)/2; // Flee bonus is 1/1/2/2/3/3/4/4/5/5
- break;
-
- case SC_JOINTBEAT:
- if (val2&BREAK_NECK)
- sc_start(bl,SC_BLEEDING,100,val1,skill_get_time2(status_sc2skill(type),val1));
- break;
-
- case SC_BERSERK:
- if (!sc->data[SC_ENDURE] || !sc->data[SC_ENDURE]->val4)
- sc_start4(bl, SC_ENDURE, 100,10,0,0,2, tick);
- case SC__BLOODYLUST:
- //HP healing is performing after the calc_status call.
- //Val2 holds HP penalty
- if (!val4) val4 = skill_get_time2(status_sc2skill(type),val1);
- if (!val4) val4 = 10000; //Val4 holds damage interval
- val3 = tick/val4; //val3 holds skill duration
- tick_time = val4; // [GodLesZ] tick time
- break;
-
- case SC_GOSPEL:
- if (val4 == BCT_SELF) { // self effect
- val2 = tick/10000;
- tick_time = 10000; // [GodLesZ] tick time
- status_change_clear_buffs(bl,3); //Remove buffs/debuffs
- }
- break;
-
- case SC_MARIONETTE: {
- int stat;
-
- val3 = 0;
- val4 = 0;
- stat = (sd ? sd->status.str : status_get_base_status(bl)->str) / 2;
- val3 |= cap_value(stat,0,0xFF)<<16;
- stat = (sd ? sd->status.agi : status_get_base_status(bl)->agi) / 2;
- val3 |= cap_value(stat,0,0xFF)<<8;
- stat = (sd ? sd->status.vit : status_get_base_status(bl)->vit) / 2;
- val3 |= cap_value(stat,0,0xFF);
- stat = (sd ? sd->status.int_: status_get_base_status(bl)->int_) / 2;
- val4 |= cap_value(stat,0,0xFF)<<16;
- stat = (sd ? sd->status.dex : status_get_base_status(bl)->dex) / 2;
- val4 |= cap_value(stat,0,0xFF)<<8;
- stat = (sd ? sd->status.luk : status_get_base_status(bl)->luk) / 2;
- val4 |= cap_value(stat,0,0xFF);
- break;
- }
- case SC_MARIONETTE2: {
- int stat,max_stat;
- // fetch caster information
- struct block_list *pbl = map_id2bl(val1);
- struct status_change *psc = pbl?status_get_sc(pbl):NULL;
- struct status_change_entry *psce = psc?psc->data[SC_MARIONETTE]:NULL;
- // fetch target's stats
- struct status_data *status = status_get_status_data(bl); // battle status
-
- if (!psce)
- return 0;
-
- val3 = 0;
- val4 = 0;
- max_stat = battle_config.max_parameter; //Cap to 99 (default)
- stat = (psce->val3 >>16)&0xFF;
- stat = min(stat, max_stat - status->str);
- val3 |= cap_value(stat,0,0xFF)<<16;
- stat = (psce->val3 >> 8)&0xFF;
- stat = min(stat, max_stat - status->agi);
- val3 |= cap_value(stat,0,0xFF)<<8;
- stat = (psce->val3 >> 0)&0xFF;
- stat = min(stat, max_stat - status->vit);
- val3 |= cap_value(stat,0,0xFF);
- stat = (psce->val4 >>16)&0xFF;
- stat = min(stat, max_stat - status->int_);
- val4 |= cap_value(stat,0,0xFF)<<16;
- stat = (psce->val4 >> 8)&0xFF;
- stat = min(stat, max_stat - status->dex);
- val4 |= cap_value(stat,0,0xFF)<<8;
- stat = (psce->val4 >> 0)&0xFF;
- stat = min(stat, max_stat - status->luk);
- val4 |= cap_value(stat,0,0xFF);
- break;
- }
- case SC_REJECTSWORD:
- val2 = 15*val1; //Reflect chance
- val3 = 3; //Reflections
- tick = -1;
- break;
-
- case SC_MEMORIZE:
- val2 = 5; //Memorized casts.
- tick = -1;
- break;
-
- case SC_GRAVITATION:
- val2 = 50*val1; //aspd reduction
- break;
-
- case SC_REGENERATION:
- if (val1 == 1)
- val2 = 2;
- else
- val2 = val1; //HP Regerenation rate: 200% 200% 300%
- val3 = val1; //SP Regeneration Rate: 100% 200% 300%
- //if val4 comes set, this blocks regen rather than increase it.
- break;
-
- case SC_DEVOTION: {
- struct block_list *d_bl;
- struct status_change *d_sc;
-
- if ((d_bl = map_id2bl(val1)) && (d_sc = status_get_sc(d_bl)) && d_sc->count) {
- // Inherits Status From Source
- const enum sc_type types[] = { SC_AUTOGUARD, SC_DEFENDER, SC_REFLECTSHIELD, SC_ENDURE };
- enum sc_type type2;
- int i = (map_flag_gvg(bl->m) || map[bl->m].flag.battleground)?2:3;
- while (i >= 0) {
- type2 = types[i];
- if (d_sc->data[type2])
- sc_start(bl, type2, 100, d_sc->data[type2]->val1, skill_get_time(status_sc2skill(type2),d_sc->data[type2]->val1));
- i--;
- }
- }
- break;
- }
+ case SC_ASPDPOTION0:
+ case SC_ASPDPOTION1:
+ case SC_ASPDPOTION2:
+ case SC_ASPDPOTION3:
+ val2 = 50*(2+type-SC_ASPDPOTION0);
+ break;
- case SC_COMA: //Coma. Sends a char to 1HP. If val2, do not zap sp
- if (val3 && bl->type == BL_MOB) {
- struct block_list *src = map_id2bl(val3);
- if (src)
- mob_log_damage((TBL_MOB *)bl,src,status->hp - 1);
- }
- status_zap(bl, status->hp-1, val2?0:status->sp);
- return 1;
- break;
- case SC_CLOSECONFINE2: {
- struct block_list *src = val2?map_id2bl(val2):NULL;
- struct status_change *sc2 = src?status_get_sc(src):NULL;
- struct status_change_entry *sce2 = sc2?sc2->data[SC_CLOSECONFINE]:NULL;
- if (src && sc2) {
- if (!sce2) //Start lock on caster.
- sc_start4(src,SC_CLOSECONFINE,100,val1,1,0,0,tick+1000);
- else { //Increase count of locked enemies and refresh time.
- (sce2->val2)++;
- delete_timer(sce2->timer, status_change_timer);
- sce2->timer = add_timer(gettick()+tick+1000, status_change_timer, src->id, SC_CLOSECONFINE);
- }
- } else //Status failed.
- return 0;
- }
- break;
- case SC_KAITE:
- val2 = 1+val1/5; //Number of bounces: 1 + skilllv/5
- break;
- case SC_KAUPE:
- switch (val1) {
- case 3: //33*3 + 1 -> 100%
- val2++;
- case 1:
- case 2: //33, 66%
- val2 += 33*val1;
- val3 = 1; //Dodge 1 attack total.
- break;
- default: //Custom. For high level mob usage, higher level means more blocks. [Skotlex]
- val2 = 100;
- val3 = val1-2;
- break;
- }
- break;
-
- case SC_COMBO: {
- //val1: Skill ID
- //val2: When given, target (for autotargetting skills)
- //val3: When set, this combo time should NOT delay attack/movement
- //val3: TK: Last used kick
- //val4: TK: Combo time
- struct unit_data *ud = unit_bl2ud(bl);
- if (ud && !val3) {
- tick += 300 * battle_config.combo_delay_rate/100;
- ud->attackabletime = gettick()+tick;
- unit_set_walkdelay(bl, gettick(), tick, 1);
- }
- val3 = 0;
- val4 = tick;
- }
- break;
- case SC_EARTHSCROLL:
- val2 = 11-val1; //Chance to consume: 11-skilllv%
- break;
- case SC_RUN:
- val4 = gettick(); //Store time at which you started running.
- tick = -1;
- break;
- case SC_KAAHI:
- val2 = 200*val1; //HP heal
- val3 = 5*val1; //SP cost
- val4 = INVALID_TIMER; //Kaahi Timer.
- break;
- case SC_BLESSING:
- if ((!undead_flag && status->race!=RC_DEMON) || bl->type == BL_PC)
- val2 = val1;
- else
- val2 = 0; //0 -> Half stat.
- break;
- case SC_TRICKDEAD:
- if (vd) vd->dead_sit = 1;
- tick = -1;
- break;
- case SC_CONCENTRATE:
- val2 = 2 + val1;
- if (sd) { //Store the card-bonus data that should not count in the %
- val3 = sd->param_bonus[1]; //Agi
- val4 = sd->param_bonus[4]; //Dex
- } else {
- val3 = val4 = 0;
- }
- break;
- case SC_MAXOVERTHRUST:
- val2 = 20*val1; //Power increase
- break;
- case SC_OVERTHRUST:
- //val2 holds if it was casted on self, or is bonus received from others
- val3 = 5*val1; //Power increase
- if (sd && pc_checkskill(sd,BS_HILTBINDING)>0)
- tick += tick / 10;
- break;
- case SC_ADRENALINE2:
- case SC_ADRENALINE:
- val3 = (val2) ? 300 : 200; // aspd increase
- case SC_WEAPONPERFECTION:
- if (sd && pc_checkskill(sd,BS_HILTBINDING)>0)
- tick += tick / 10;
- break;
- case SC_CONCENTRATION:
- val2 = 5*val1; //Batk/Watk Increase
- val3 = 10*val1; //Hit Increase
- val4 = 5*val1; //Def reduction
- break;
- case SC_ANGELUS:
- val2 = 5*val1; //def increase
- break;
- case SC_IMPOSITIO:
- val2 = 5*val1; //watk increase
- break;
- case SC_MELTDOWN:
- val2 = 100*val1; //Chance to break weapon
- val3 = 70*val1; //Change to break armor
- break;
- case SC_TRUESIGHT:
- val2 = 10*val1; //Critical increase
- val3 = 3*val1; //Hit increase
- break;
- case SC_SUN_COMFORT:
- val2 = (status_get_lv(bl) + status->dex + status->luk)/2; //def increase
- break;
- case SC_MOON_COMFORT:
- val2 = (status_get_lv(bl) + status->dex + status->luk)/10; //flee increase
- break;
- case SC_STAR_COMFORT:
- val2 = (status_get_lv(bl) + status->dex + status->luk); //Aspd increase
- break;
- case SC_QUAGMIRE:
- val2 = (sd?5:10)*val1; //Agi/Dex decrease.
- break;
-
- // gs_something1 [Vicious]
- case SC_GATLINGFEVER:
- val2 = 20*val1; //Aspd increase
- val3 = 20+10*val1; //Batk increase
- val4 = 5*val1; //Flee decrease
- break;
-
- case SC_FLING:
- if (bl->type == BL_PC)
- val2 = 0; //No armor reduction to players.
- else
- val2 = 5*val1; //Def reduction
- val3 = 5*val1; //Def2 reduction
- break;
- case SC_PROVOKE:
- //val2 signals autoprovoke.
- val3 = 2+3*val1; //Atk increase
- val4 = 5+5*val1; //Def reduction.
- break;
- case SC_AVOID:
- //val2 = 10*val1; //Speed change rate.
- break;
- case SC_DEFENCE:
- val2 = 2*val1; //Def bonus
- break;
- case SC_BLOODLUST:
- val2 = 20+10*val1; //Atk rate change.
- val3 = 3*val1; //Leech chance
- val4 = 20; //Leech percent
- break;
- case SC_FLEET:
- val2 = 30*val1; //Aspd change
- val3 = 5+5*val1; //bAtk/wAtk rate change
- break;
- case SC_MINDBREAKER:
- val2 = 20*val1; //matk increase.
- val3 = 12*val1; //mdef2 reduction.
- break;
- case SC_SKA:
- val2 = tick/1000;
- val3 = rnd()%100; //Def changes randomly every second...
- tick_time = 1000; // [GodLesZ] tick time
- break;
- case SC_JAILED:
- //Val1 is duration in minutes. Use INT_MAX to specify 'unlimited' time.
- tick = val1>0?1000:250;
- if (sd) {
- if (sd->mapindex != val2) {
- int pos = (bl->x&0xFFFF)|(bl->y<<16), //Current Coordinates
- map = sd->mapindex; //Current Map
- //1. Place in Jail (val2 -> Jail Map, val3 -> x, val4 -> y
- pc_setpos(sd,(unsigned short)val2,val3,val4, CLR_TELEPORT);
- //2. Set restore point (val3 -> return map, val4 return coords
- val3 = map;
- val4 = pos;
- } else if (!val3 || val3 == sd->mapindex) { //Use save point.
- val3 = sd->status.save_point.map;
- val4 = (sd->status.save_point.x&0xFFFF)
- |(sd->status.save_point.y<<16);
- }
- }
- break;
- case SC_UTSUSEMI:
- val2=(val1+1)/2; // number of hits blocked
- val3=skill_get_blewcount(NJ_UTSUSEMI, val1); //knockback value.
- break;
- case SC_BUNSINJYUTSU:
- val2=(val1+1)/2; // number of hits blocked
- break;
- case SC_CHANGE:
- val2= 30*val1; //Vit increase
- val3= 20*val1; //Int increase
- break;
- case SC_SWOO:
- if (status->mode&MD_BOSS)
- tick /= 5; //TODO: Reduce skill's duration. But for how long?
- break;
- case SC_SPIDERWEB:
- if (bl->type == BL_PC)
- tick /= 2;
- break;
- case SC_ARMOR:
- //NPC_DEFENDER:
- val2 = 80; //Damage reduction
- //Attack requirements to be blocked:
- val3 = BF_LONG; //Range
- val4 = BF_WEAPON|BF_MISC; //Type
- break;
- case SC_ENCHANTARMS:
- //end previous enchants
- skill_enchant_elemental_end(bl,type);
- //Make sure the received element is valid.
- if (val2 >= ELE_MAX)
- val2 = val2%ELE_MAX;
- else if (val2 < 0)
- val2 = rnd()%ELE_MAX;
- break;
- case SC_CRITICALWOUND:
- val2 = 20*val1; //Heal effectiveness decrease
- break;
- case SC_MAGICMIRROR:
- case SC_SLOWCAST:
- val2 = 20*val1; //Magic reflection/cast rate
- break;
-
- case SC_ARMORCHANGE:
- if (val2 == NPC_ANTIMAGIC) {
- //Boost mdef
- val2 =-20;
- val3 = 20;
- } else { //Boost def
- val2 = 20;
- val3 =-20;
- }
- val2*=val1; //20% per level
- val3*=val1;
- break;
- case SC_EXPBOOST:
- case SC_JEXPBOOST:
- if (val1 < 0)
- val1 = 0;
- break;
- case SC_INCFLEE2:
- case SC_INCCRI:
- val2 = val1*10; //Actual boost (since 100% = 1000)
- break;
- case SC_SUFFRAGIUM:
- val2 = 15 * val1; //Speed cast decrease
- break;
- case SC_INCHEALRATE:
- if (val1 < 1)
- val1 = 1;
- break;
- case SC_HALLUCINATION:
- val2 = 5+val1; //Factor by which displayed damage is increased by
- break;
- case SC_DOUBLECAST:
- val2 = 30+10*val1; //Trigger rate
- break;
- case SC_KAIZEL:
- val2 = 10*val1; //% of life to be revived with
- break;
- // case SC_ARMOR_ELEMENT:
- // case SC_ARMOR_RESIST:
- // Mod your resistance against elements:
- // val1 = water | val2 = earth | val3 = fire | val4 = wind
- // break;
- //case ????:
- //Place here SCs that have no SCB_* data, no skill associated, no ICON
- //associated, and yet are not wrong/unknown. [Skotlex]
- //break;
-
- case SC_MERC_FLEEUP:
- case SC_MERC_ATKUP:
- case SC_MERC_HITUP:
- val2 = 15 * val1;
- break;
- case SC_MERC_HPUP:
- case SC_MERC_SPUP:
- val2 = 5 * val1;
- break;
- case SC_REBIRTH:
- val2 = 20*val1; //% of life to be revived with
- break;
-
- case SC_MANU_DEF:
- case SC_MANU_ATK:
- case SC_MANU_MATK:
- val2 = 1; // Manuk group
- break;
- case SC_SPL_DEF:
- case SC_SPL_ATK:
- case SC_SPL_MATK:
- val2 = 2; // Splendide group
- break;
- /**
- * General
- **/
- case SC_FEAR:
- val2 = 2;
- val4 = tick / 1000;
- tick_time = 1000; // [GodLesZ] tick time
- break;
- case SC_BURNING:
- val4 = tick / 2000; // Total Ticks to Burn!!
- tick_time = 2000; // [GodLesZ] tick time
- break;
- /**
- * Rune Knight
- **/
- case SC_DEATHBOUND:
- val2 = 500 + 100 * val1;
- break;
- case SC_FIGHTINGSPIRIT:
- val_flag |= 1|2;
- break;
- case SC_ABUNDANCE:
- val4 = tick / 10000;
- tick_time = 10000; // [GodLesZ] tick time
- break;
- case SC_GIANTGROWTH:
- val2 = 10; // Triple damage success rate.
- break;
- /**
- * Arch Bishop
- **/
- case SC_RENOVATIO:
- val4 = tick / 5000;
- tick_time = 5000;
- break;
- case SC_SECRAMENT:
- val2 = 10 * val1;
- break;
- case SC_VENOMIMPRESS:
- val2 = 10 * val1;
- val_flag |= 1|2;
- break;
- case SC_POISONINGWEAPON:
- val_flag |= 1|2|4;
- break;
- case SC_WEAPONBLOCKING:
- val2 = 10 + 2 * val1; // Chance
- val4 = tick / 3000;
- tick_time = 3000; // [GodLesZ] tick time
- val_flag |= 1|2;
- break;
- case SC_TOXIN:
- val4 = tick / 10000;
- tick_time = 10000; // [GodLesZ] tick time
- break;
- case SC_MAGICMUSHROOM:
- val4 = tick / 4000;
- tick_time = 4000; // [GodLesZ] tick time
- break;
- case SC_PYREXIA:
- status_change_start(bl,SC_BLIND,10000,val1,0,0,0,30000,11); // Blind status that last for 30 seconds
- val4 = tick / 3000;
- tick_time = 3000; // [GodLesZ] tick time
- break;
- case SC_LEECHESEND:
- val4 = tick / 1000;
- tick_time = 1000; // [GodLesZ] tick time
- break;
- case SC_OBLIVIONCURSE:
- val4 = tick / 3000;
- tick_time = 3000; // [GodLesZ] tick time
- break;
- case SC_ROLLINGCUTTER:
- val_flag |= 1;
- break;
- case SC_CLOAKINGEXCEED:
- val2 = (val1 + 1) / 2; // Hits
- val3 = 90 + val1 * 10; // Walk speed
- val_flag |= 1|2|4;
- if (bl->type == BL_PC)
- val4 |= battle_config.pc_cloak_check_type&7;
- else
- val4 |= battle_config.monster_cloak_check_type&7;
- tick_time = 1000; // [GodLesZ] tick time
- break;
- case SC_HALLUCINATIONWALK:
- val2 = 50 * val1; // Evasion rate of physical attacks. Flee
- val3 = 10 * val1; // Evasion rate of magical attacks.
- val_flag |= 1|2|4;
- break;
- case SC_WHITEIMPRISON:
- status_change_end(bl, SC_BURNING, INVALID_TIMER);
- status_change_end(bl, SC_FREEZING, INVALID_TIMER);
- status_change_end(bl, SC_FREEZE, INVALID_TIMER);
- status_change_end(bl, SC_STONE, INVALID_TIMER);
- break;
- case SC_FREEZING:
- status_change_end(bl, SC_BURNING, INVALID_TIMER);
- break;
- case SC_READING_SB:
- // val2 = sp reduction per second
- tick_time = 5000; // [GodLesZ] tick time
- break;
- case SC_SPHERE_1:
- case SC_SPHERE_2:
- case SC_SPHERE_3:
- case SC_SPHERE_4:
- case SC_SPHERE_5:
- if (!sd)
- return 0; // Should only work on players.
- val4 = tick / 1000;
- if (val4 < 1)
- val4 = 1;
- tick_time = 1000; // [GodLesZ] tick time
- val_flag |= 1;
- break;
- case SC_SHAPESHIFT:
- switch (val1) {
- case 1:
- val2 = ELE_FIRE;
- break;
- case 2:
- val2 = ELE_EARTH;
- break;
- case 3:
- val2 = ELE_WIND;
- break;
- case 4:
- val2 = ELE_WATER;
- break;
- }
- break;
- case SC_ELECTRICSHOCKER:
- case SC_CRYSTALIZE:
- case SC_MEIKYOUSISUI:
- val4 = tick / 1000;
- if (val4 < 1)
- val4 = 1;
- tick_time = 1000; // [GodLesZ] tick time
- break;
- case SC_CAMOUFLAGE:
- val4 = tick/1000;
- tick_time = 1000; // [GodLesZ] tick time
- break;
- case SC_WUGDASH:
- val4 = gettick(); //Store time at which you started running.
- tick = -1;
- break;
- case SC__SHADOWFORM: {
- struct map_session_data *s_sd = map_id2sd(val2);
- if (s_sd)
- s_sd->shadowform_id = bl->id;
- val4 = tick / 1000;
- val_flag |= 1|2|4;
- tick_time = 1000; // [GodLesZ] tick time
- }
- break;
- case SC__STRIPACCESSORY:
- if (!sd)
- val2 = 20;
- break;
- case SC__INVISIBILITY:
- val2 = 50 - 10 * val1; // ASPD
- val3 = 20 * val1; // CRITICAL
- val4 = tick / 1000;
- tick_time = 1000; // [GodLesZ] tick time
- val_flag |= 1|2;
- break;
- case SC__ENERVATION:
- val2 = 20 + 10 * val1; // ATK Reduction
- val_flag |= 1|2;
- if (sd) pc_delspiritball(sd,sd->spiritball,0);
- break;
- case SC__GROOMY:
- val2 = 20 + 10 * val1; //ASPD. Need to confirm if Movement Speed reduction is the same. [Jobbie]
- val3 = 20 * val1; //HIT
- val_flag |= 1|2|4;
- if (sd) {
- // Removes Animals
- if (pc_isriding(sd)) pc_setriding(sd, 0);
- if (pc_isridingdragon(sd)) pc_setoption(sd, sd->sc.option&~OPTION_DRAGON);
- if (pc_iswug(sd)) pc_setoption(sd, sd->sc.option&~OPTION_WUG);
- if (pc_isridingwug(sd)) pc_setoption(sd, sd->sc.option&~OPTION_WUGRIDER);
- if (pc_isfalcon(sd)) pc_setoption(sd, sd->sc.option&~OPTION_FALCON);
- if (sd->status.pet_id > 0) pet_menu(sd, 3);
- if (merc_is_hom_active(sd->hd)) merc_hom_vaporize(sd,1);
- if (sd->md) merc_delete(sd->md,3);
- }
- break;
- case SC__LAZINESS:
- val2 = 10 + 10 * val1; // Cast reduction
- val3 = 10 * val1; // Flee Reduction
- val_flag |= 1|2|4;
- break;
- case SC__UNLUCKY:
- val2 = 10 * val1; // Crit and Flee2 Reduction
- val_flag |= 1|2|4;
- break;
- case SC__WEAKNESS:
- val2 = 10 * val1;
- val_flag |= 1|2;
- // bypasses coating protection and MADO
- sc_start(bl,SC_STRIPWEAPON,100,val1,tick);
- sc_start(bl,SC_STRIPSHIELD,100,val1,tick);
- break;
- break;
- case SC_GN_CARTBOOST:
- if (val1 < 3)
- val2 = 50;
- else if (val1 < 5)
- val2 = 75;
- else
- val2 = 100;
- break;
- case SC_PROPERTYWALK:
- val_flag |= 1|2;
- val3 = 0;
- break;
- case SC_WARMER:
- status_change_end(bl, SC_FREEZE, INVALID_TIMER);
- status_change_end(bl, SC_FREEZING, INVALID_TIMER);
- status_change_end(bl, SC_CRYSTALIZE, INVALID_TIMER);
- break;
- case SC_STRIKING:
- val1 = 6 - val1;//spcost = 6 - level (lvl1:5 ... lvl 5: 1)
- val4 = tick / 1000;
- tick_time = 1000; // [GodLesZ] tick time
- break;
- case SC_BLOODSUCKER:
- val4 = tick / 1000;
- tick_time = 1000; // [GodLesZ] tick time
- break;
- case SC_VACUUM_EXTREME:
- tick -= (status->str / 20) * 1000;
- val4 = val3 = tick / 100;
- tick_time = 100; // [GodLesZ] tick time
- break;
- case SC_SWINGDANCE:
- val2 = 4 * val1; // Walk speed and aspd reduction.
- break;
- case SC_SYMPHONYOFLOVER:
- case SC_RUSHWINDMILL:
- case SC_ECHOSONG:
- val2 = 6 * val1;
- val2 += val3; //Adding 1% * Lesson Bonus
- val2 += (int)(val4*2/10); //Adding 0.2% per JobLevel
- break;
- case SC_MOONLITSERENADE:
- val2 = 10 * val1;
- break;
- case SC_HARMONIZE:
- val2 = 5 + 5 * val1;
- break;
- case SC_VOICEOFSIREN:
- val4 = tick / 2000;
- tick_time = 2000; // [GodLesZ] tick time
- break;
- case SC_DEEPSLEEP:
- val4 = tick / 2000;
- tick_time = 2000; // [GodLesZ] tick time
- break;
- case SC_SIRCLEOFNATURE:
- val2 = 1 + val1; //SP consume
- val3 = 40 * val1; //HP recovery
- val4 = tick / 1000;
- tick_time = 1000; // [GodLesZ] tick time
- break;
- case SC_SONGOFMANA:
- val3 = 10 + (2 * val2);
- val4 = tick/3000;
- tick_time = 3000; // [GodLesZ] tick time
- break;
- case SC_SATURDAYNIGHTFEVER:
- if (!val4) val4 = skill_get_time2(status_sc2skill(type),val1);
- if (!val4) val4 = 3000;
- val3 = tick/val4;
- tick_time = val4; // [GodLesZ] tick time
- break;
- case SC_GLOOMYDAY:
- val2 = 20 + 5 * val1; // Flee reduction.
- val3 = 15 + 5 * val1; // ASPD reduction.
- if (sd && rand()%100 < val1) { // (Skill Lv) %
- val4 = 1; // reduce walk speed by half.
- if (pc_isriding(sd)) pc_setriding(sd, 0);
- if (pc_isridingdragon(sd)) pc_setoption(sd, sd->sc.option&~OPTION_DRAGON);
- }
- break;
- case SC_GLOOMYDAY_SK:
- // Random number between [15 ~ (Voice Lesson Skill Level x 5) + (Skill Level x 10)] %.
- val2 = 15 + rand()%((sd?pc_checkskill(sd, WM_LESSON)*5:0) + val1*10);
- break;
- case SC_SITDOWN_FORCE:
- case SC_BANANA_BOMB_SITDOWN:
- if (sd && !pc_issit(sd)) {
- pc_setsit(sd);
- skill_sit(sd,1);
- clif_sitting(bl);
- }
- break;
- case SC_DANCEWITHWUG:
- val3 = (5 * val1) + (1 * val2); //Still need official value.
- break;
- case SC_LERADSDEW:
- val3 = (5 * val1) + (1 * val2);
- break;
- case SC_MELODYOFSINK:
- val3 = (5 * val1) + (1 * val2);
- break;
- case SC_BEYONDOFWARCRY:
- val3 = (5 * val1) + (1 * val2);
- break;
- case SC_UNLIMITEDHUMMINGVOICE: {
- struct unit_data *ud = unit_bl2ud(bl);
- if (ud == NULL) return 0;
- ud->state.skillcastcancel = 0;
- val3 = 15 - (2 * val2);
- }
- break;
- case SC_REFLECTDAMAGE:
- val2 = 15 + 5 * val1;
- val3 = (val1==5)?20:(val1+4)*2; // SP consumption
- val4 = tick/10000;
- tick_time = 10000; // [GodLesZ] tick time
- break;
- case SC_FORCEOFVANGUARD: // This is not the official way to handle it but I think we should use it. [pakpil]
- val2 = 20 + 12 * (val1 - 1); // Chance
- val3 = 5 + (2 * val1); // Max rage counters
- tick = -1; //endless duration in the client
- tick_time = 6000; // [GodLesZ] tick time
- val_flag |= 1|2|4;
- break;
- case SC_EXEEDBREAK:
- val1 *= 150; // 150 * skill_lv
- if (sd && sd->inventory_data[sd->equip_index[EQI_HAND_R]]) { // Chars.
- val1 += (sd->inventory_data[sd->equip_index[EQI_HAND_R]]->weight/10 * sd->inventory_data[sd->equip_index[EQI_HAND_R]]->wlv * status_get_lv(bl) / 100);
- val1 += 15 * (sd ? sd->status.job_level:50) + 100;
- } else // Mobs
- val1 += (400 * status_get_lv(bl) / 100) + (15 * (status_get_lv(bl) / 2)); // About 1138% at mob_lvl 99. Is an aproximation to a standard weapon. [pakpil]
- break;
- case SC_PRESTIGE: // Bassed on suggested formula in iRO Wiki and some test, still need more test. [pakpil]
- val2 = ((status->int_ + status->luk) / 6) + 5; // Chance to evade magic damage.
- val1 *= 15; // Defence added
- if (sd)
- val1 += 10 * pc_checkskill(sd,CR_DEFENDER);
- val_flag |= 1|2;
- break;
- case SC_BANDING:
- tick_time = 5000; // [GodLesZ] tick time
- val_flag |= 1;
- break;
- case SC_SHIELDSPELL_DEF:
- case SC_SHIELDSPELL_MDEF:
- case SC_SHIELDSPELL_REF:
- val_flag |= 1|2;
- break;
- case SC_MAGNETICFIELD:
- val3 = tick / 1000;
- tick_time = 1000; // [GodLesZ] tick time
- break;
- case SC_INSPIRATION:
- if (sd) {
- val2 = (40 * val1) + (3 * sd->status.job_level); // ATK bonus
- val3 = (sd->status.job_level / 10) * 2 + 12; // All stat bonus
- }
- val4 = tick / 1000;
- tick_time = 1000; // [GodLesZ] tick time
- status_change_clear_buffs(bl,3); //Remove buffs/debuffs
- break;
- case SC_SPELLFIST:
- case SC_CURSEDCIRCLE_ATKER:
- val_flag |= 1|2|4;
- break;
- case SC_CRESCENTELBOW:
- val2 = 94 + val1;
- val_flag |= 1|2;
- break;
- case SC_LIGHTNINGWALK: // [(Job Level / 2) + (40 + 5 * Skill Level)] %
- val1 = (sd?sd->status.job_level:2)/2 + 40 + 5 * val1;
- val_flag |= 1;
- break;
- case SC_RAISINGDRAGON:
- val3 = tick / 5000;
- tick_time = 5000; // [GodLesZ] tick time
- break;
- case SC_GT_CHANGE: {
- // take note there is no def increase as skill desc says. [malufett]
- struct block_list *src;
- val3 = status->agi * val1 / 60; // ASPD increase: [(Target AGI x Skill Level) / 60] %
- if ((src = map_id2bl(val2)))
- val4 = (200/status_get_int(src)) * val1; // MDEF decrease: MDEF [(200 / Caster INT) x Skill Level]
- }
- break;
- case SC_GT_REVITALIZE: {
- // take note there is no vit,aspd,speed increase as skill desc says. [malufett]
- struct block_list *src;
- val3 = val1 * 30 + 150; // Natural HP recovery increase: [(Skill Level x 30) + 50] %
- if ((src = map_id2bl(val2))) // the stat def is not shown in the status window and it is process differently
- val4 = (status_get_vit(src)/4) * val1; // STAT DEF increase: [(Caster VIT / 4) x Skill Level]
- }
- break;
- case SC_PYROTECHNIC_OPTION:
- val2 = 60; // Watk TODO: Renewal (Atk2)
- val3 = 11; // % Increase damage.
- val_flag |= 1|2|4;
- break;
- case SC_HEATER_OPTION:
- val2 = 120; // Watk. TODO: Renewal (Atk2)
- val3 = 33; // % Increase effects.
- val4 = 3; // Change into fire element.
- val_flag |= 1|2|4;
- break;
- case SC_TROPIC_OPTION:
- val2 = 180; // Watk. TODO: Renewal (Atk2)
- val3 = MG_FIREBOLT;
- break;
- case SC_AQUAPLAY_OPTION:
- val2 = 40; // Matk. TODO: Renewal (Matk1)
- val3 = 33; // % Increase effects.
- val_flag |= 1|2|4;
- break;
- case SC_COOLER_OPTION:
- val2 = 80; // % Freezing chance
- val3 = 33; // % increased damage
- val4 = 1; // Change into water elemet
- val_flag |= 1|2|4;
- break;
- case SC_CHILLY_AIR_OPTION:
- val2 = 120; // Matk. TODO: Renewal (Matk1)
- val3 = MG_COLDBOLT;
- val_flag |= 1|2;
- break;
- case SC_GUST_OPTION:
- val2 = 33;
- val_flag |= 1|2;
- break;
- case SC_WIND_STEP_OPTION:
- val2 = 50; // % Increase speed and flee.
- break;
- case SC_BLAST_OPTION:
- val2 = 33;
- val3 = 4;
- val_flag |= 1|2|4;
- break;
- case SC_WILD_STORM_OPTION:
- val2 = MG_LIGHTNINGBOLT;
- val_flag |= 1|2;
- break;
- case SC_PETROLOGY_OPTION:
- val2 = 5;
- val3 = 33;
- val_flag |= 1|2|4;
- break;
- case SC_CURSED_SOIL_OPTION:
- val2 = 10;
- val3 = 33;
- val4 = 2;
- val_flag |= 1|2|4;
- break;
- case SC_UPHEAVAL_OPTION:
- val2 = WZ_EARTHSPIKE;
- val_flag |= 1|2;
- break;
- case SC_CIRCLE_OF_FIRE_OPTION:
- val2 = 300;
- val_flag |= 1|2;
- break;
- case SC_FIRE_CLOAK_OPTION:
- case SC_WATER_DROP_OPTION:
- case SC_WIND_CURTAIN_OPTION:
- case SC_STONE_SHIELD_OPTION:
- val2 = 20; // Elemental modifier. Not confirmed.
- break;
- case SC_CIRCLE_OF_FIRE:
- case SC_FIRE_CLOAK:
- case SC_WATER_DROP:
- case SC_WATER_SCREEN:
- case SC_WIND_CURTAIN:
- case SC_WIND_STEP:
- case SC_STONE_SHIELD:
- case SC_SOLID_SKIN:
- val2 = 10;
- tick_time = 2000; // [GodLesZ] tick time
- break;
- case SC_WATER_BARRIER:
- val2 = 40; // Increasement. Mdef1 ???
- val3 = 20; // Reductions. Atk2, Flee1, Matk1 ????
- val_flag |= 1|2|4;
- break;
- case SC_ZEPHYR:
- val2 = 22; // Flee.
- break;
- case SC_TIDAL_WEAPON:
- val2 = 20; // Increase Elemental's attack.
- break;
- case SC_ROCK_CRUSHER:
- case SC_ROCK_CRUSHER_ATK:
- case SC_POWER_OF_GAIA:
- val2 = 33;
- break;
- case SC_MELON_BOMB:
- case SC_BANANA_BOMB:
- val1 = 15;
- break;
- case SC_STOMACHACHE:
- val2 = 8; // SP consume.
- val4 = tick / 10000;
- tick_time = 10000; // [GodLesZ] tick time
- break;
- case SC_KYOUGAKU:
- val2 = 2*val1 + rand()%val1;
- clif_status_change(bl,SI_ACTIVE_MONSTER_TRANSFORM,1,0,1002,0,0);
- break;
- case SC_KAGEMUSYA:
- val3 = val1 * 2;
- case SC_IZAYOI:
- val2 = tick/1000;
- tick_time = 1000;
- break;
- case SC_ZANGETSU:
- if ((status_get_hp(bl)+status_get_sp(bl)) % 2 == 0)
- val2 = status_get_lv(bl) / 2 + 50;
- else
- val2 -= 50;
- break;
- case SC_GENSOU: {
- int hp = status_get_hp(bl), lv = 5;
- short per = 100 / (status_get_max_hp(bl) / hp);
-
- if (per <= 15)
- lv = 1;
- else if (per <= 30)
- lv = 2;
- else if (per <= 50)
- lv = 3;
- else if (per <= 75)
- lv = 4;
- if (hp % 2 == 0)
- status_heal(bl, hp * (6-lv) * 4 / 100, status_get_sp(bl) * (6-lv) * 3 / 100, 1);
- else
- status_zap(bl, hp * (lv*4) / 100, status_get_sp(bl) * (lv*3) / 100);
- }
- break;
- case SC_ANGRIFFS_MODUS:
- val2 = 50 + 20 * val1; //atk bonus
- val3 = 40 + 20 * val1; // Flee reduction.
- val4 = tick/1000; // hp/sp reduction timer
- tick_time = 1000;
- break;
- case SC_GOLDENE_FERSE:
- val2 = 10 + 10*val1; //max hp bonus
- val3 = 6 + 4 * val1; // Aspd Bonus
- val4 = 2 + 2 * val1; // Chance of holy attack
- break;
- case SC_OVERED_BOOST:
- val2 = 300 + 40*val1; //flee bonus
- val3 = 179 + 2*val1; //aspd bonus
- break;
- case SC_GRANITIC_ARMOR:
- val2 = 2*val1; //dmg reduction
- val3 = 6*val1; //dmg on status end
- break;
- case SC_MAGMA_FLOW:
- val2 = 3*val1; //activation chance
- break;
- case SC_PYROCLASTIC:
- val2 += 10*val1; //atk bonus
- break;
- case SC_PARALYSIS: //[Lighta] need real info
- val2 = 2*val1; //def reduction
- val3 = 500*val1; //varcast augmentation
- break;
- case SC_PAIN_KILLER: //[Lighta] need real info
- val2 = 2*val1; //aspd reduction %
- val3 = 2*val1; //dmg reduction %
- if (sc->data[SC_PARALYSIS])
- sc_start(bl, SC_ENDURE, 100, val1, tick); //start endure for same duration
- break;
- default:
- if (calc_flag == SCB_NONE && StatusSkillChangeTable[type] == 0 && StatusIconChangeTable[type] == 0) {
- //Status change with no calc, no icon, and no skill associated...?
- ShowError("UnknownStatusChange [%d]\n", type);
- return 0;
- }
- }
- else //Special considerations when loading SC data.
- switch (type) {
- case SC_WEDDING:
- case SC_XMAS:
- case SC_SUMMER:
- clif_changelook(bl,LOOK_WEAPON,0);
- clif_changelook(bl,LOOK_SHIELD,0);
- clif_changelook(bl,LOOK_BASE,type==SC_WEDDING?JOB_WEDDING:type==SC_XMAS?JOB_XMAS:JOB_SUMMER);
- clif_changelook(bl,LOOK_CLOTHES_COLOR,val4);
- break;
- case SC_KAAHI:
- val4 = INVALID_TIMER;
- break;
- }
+ case SC_WEDDING:
+ case SC_XMAS:
+ case SC_SUMMER:
+ if (!vd) return 0;
+ //Store previous values as they could be removed.
+ val1 = vd->class_;
+ val2 = vd->weapon;
+ val3 = vd->shield;
+ val4 = vd->cloth_color;
+ unit_stop_attack(bl);
+ clif_changelook(bl,LOOK_WEAPON,0);
+ clif_changelook(bl,LOOK_SHIELD,0);
+ clif_changelook(bl,LOOK_BASE,type==SC_WEDDING?JOB_WEDDING:type==SC_XMAS?JOB_XMAS:JOB_SUMMER);
+ clif_changelook(bl,LOOK_CLOTHES_COLOR,vd->cloth_color);
+ break;
+ case SC_NOCHAT:
+ // [GodLesZ] FIXME: is this correct? a hardcoded interval of 60sec? what about configuration ?_?
+ tick = 60000;
+ val1 = battle_config.manner_system; //Mute filters.
+ if (sd)
+ {
+ clif_changestatus(sd,SP_MANNER,sd->status.manner);
+ clif_updatestatus(sd,SP_MANNER);
+ }
+ break;
- //Those that make you stop attacking/walking....
- switch (type) {
- case SC_FREEZE:
- case SC_STUN:
- case SC_SLEEP:
- case SC_STONE:
- case SC_DEEPSLEEP:
- if (sd && pc_issit(sd)) //Avoid sprite sync problems.
- pc_setstand(sd);
- case SC_TRICKDEAD:
- unit_stop_attack(bl);
- status_change_end(bl, SC_DANCING, INVALID_TIMER);
- // Cancel cast when get status [LuzZza]
- if (battle_config.sc_castcancel&bl->type)
- unit_skillcastcancel(bl, 0);
- case SC_STOP:
- case SC_CONFUSION:
- case SC_CLOSECONFINE:
- case SC_CLOSECONFINE2:
- case SC_ANKLE:
- case SC_SPIDERWEB:
- case SC_ELECTRICSHOCKER:
- case SC_BITE:
- case SC_THORNSTRAP:
- case SC__MANHOLE:
- case SC_CRYSTALIZE:
- case SC_WHITEIMPRISON:
- case SC_CURSEDCIRCLE_ATKER:
- case SC_CURSEDCIRCLE_TARGET:
- case SC_FEAR:
- case SC_NETHERWORLD:
- case SC_MEIKYOUSISUI:
- case SC_KYOUGAKU:
- case SC_PARALYSIS:
- unit_stop_walking(bl,1);
- break;
- case SC_HIDING:
- case SC_CLOAKING:
- case SC_CLOAKINGEXCEED:
- case SC_CHASEWALK:
- case SC_WEIGHT90:
- case SC_CAMOUFLAGE:
- case SC_VOICEOFSIREN:
- unit_stop_attack(bl);
- break;
- case SC_SILENCE:
- if (battle_config.sc_castcancel&bl->type)
- unit_skillcastcancel(bl, 0);
- break;
- }
+ case SC_STONE:
+ val3 = tick/1000; //Petrified HP-damage iterations.
+ if(val3 < 1) val3 = 1;
+ tick = val4; //Petrifying time.
+ tick = max(tick, 1000); //Min time
+ calc_flag = 0; //Actual status changes take effect on petrified state.
+ break;
- // Set option as needed.
- opt_flag = 1;
- switch (type) {
- //OPT1
- case SC_STONE:
- sc->opt1 = OPT1_STONEWAIT;
- break;
- case SC_FREEZE:
- sc->opt1 = OPT1_FREEZE;
- break;
- case SC_STUN:
- sc->opt1 = OPT1_STUN;
- break;
- case SC_SLEEP:
- case SC_DEEPSLEEP:
- if(type == SC_DEEPSLEEP)
- opt_flag = 0;
- sc->opt1 = OPT1_SLEEP;
- break;
- case SC_BURNING:
- sc->opt1 = OPT1_BURNING;
- break; // Burning need this to be showed correctly. [pakpil]
- case SC_WHITEIMPRISON:
- sc->opt1 = OPT1_IMPRISON;
- break;
- case SC_CRYSTALIZE:
- sc->opt1 = OPT1_CRYSTALIZE;
- break;
- //OPT2
- case SC_POISON:
- sc->opt2 |= OPT2_POISON;
- break;
- case SC_CURSE:
- sc->opt2 |= OPT2_CURSE;
- break;
- case SC_SILENCE:
- sc->opt2 |= OPT2_SILENCE;
- break;
+ case SC_DPOISON:
+ //Lose 10/15% of your life as long as it doesn't brings life below 25%
+ if (status->hp > status->max_hp>>2) {
+ int diff = status->max_hp*(bl->type==BL_PC?10:15)/100;
+ if (status->hp - diff < status->max_hp>>2)
+ diff = status->hp - (status->max_hp>>2);
+ if( val2 && bl->type == BL_MOB ) {
+ struct block_list* src = map_id2bl(val2);
+ if( src )
+ mob_log_damage((TBL_MOB*)bl,src,diff);
+ }
+ status_zap(bl, diff, 0);
+ }
+ // fall through
+ case SC_POISON:
+ val3 = tick/1000; //Damage iterations
+ if(val3 < 1) val3 = 1;
+ tick_time = 1000; // [GodLesZ] tick time
+ //val4: HP damage
+ if (bl->type == BL_PC)
+ val4 = (type == SC_DPOISON) ? 3 + status->max_hp/50 : 3 + status->max_hp*3/200;
+ else
+ val4 = (type == SC_DPOISON) ? 3 + status->max_hp/100 : 3 + status->max_hp/200;
+
+ break;
+ case SC_CONFUSION:
+ clif_emotion(bl,E_WHAT);
+ break;
+ case SC_BLEEDING:
+ val4 = tick/10000;
+ if (!val4) val4 = 1;
+ tick_time = 10000; // [GodLesZ] tick time
+ break;
+ case SC_S_LIFEPOTION:
+ case SC_L_LIFEPOTION:
+ if( val1 == 0 ) return 0;
+ // val1 = heal percent/amout
+ // val2 = seconds between heals
+ // val4 = total of heals
+ if( val2 < 1 ) val2 = 1;
+ if( (val4 = tick/(val2 * 1000)) < 1 )
+ val4 = 1;
+ tick_time = val2 * 1000; // [GodLesZ] tick time
+ break;
+ case SC_BOSSMAPINFO:
+ if( sd != NULL )
+ {
+ struct mob_data *boss_md = map_getmob_boss(bl->m); // Search for Boss on this Map
+ if( boss_md == NULL || boss_md->bl.prev == NULL )
+ { // No MVP on this map - MVP is dead
+ clif_bossmapinfo(sd->fd, boss_md, 1);
+ return 0; // No need to start SC
+ }
+ val1 = boss_md->bl.id;
+ if( (val4 = tick/1000) < 1 )
+ val4 = 1;
+ tick_time = 1000; // [GodLesZ] tick time
+ }
+ break;
+ case SC_HIDING:
+ val2 = tick/1000;
+ tick_time = 1000; // [GodLesZ] tick time
+ val3 = 0; // unused, previously speed adjustment
+ val4 = val1+3; //Seconds before SP substraction happen.
+ break;
+ case SC_CHASEWALK:
+ val2 = tick>0?tick:10000; //Interval at which SP is drained.
+ val3 = 35 - 5 * val1; //Speed adjustment.
+ if (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_ROGUE)
+ val3 -= 40;
+ val4 = 10+val1*2; //SP cost.
+ if (map_flag_gvg(bl->m) || map[bl->m].flag.battleground) val4 *= 5;
+ break;
+ case SC_CLOAKING:
+ if (!sd) //Monsters should be able to walk with no penalties. [Skotlex]
+ val1 = 10;
+ tick_time = val2 = tick>0?tick:60000; //SP consumption rate.
+ tick = -1; // duration sent to the client should be infinite
+ val3 = 0; // unused, previously walk speed adjustment
+ //val4&1 signals the presence of a wall.
+ //val4&2 makes cloak not end on normal attacks [Skotlex]
+ //val4&4 makes cloak not end on using skills
+ if (bl->type == BL_PC || (bl->type == BL_MOB && ((TBL_MOB*)bl)->special_state.clone) ) //Standard cloaking.
+ val4 |= battle_config.pc_cloak_check_type&7;
+ else
+ val4 |= battle_config.monster_cloak_check_type&7;
+ break;
+ case SC_SIGHT: /* splash status */
+ case SC_RUWACH:
+ case SC_SIGHTBLASTER:
+ val3 = skill_get_splash(val2, val1); //Val2 should bring the skill-id.
+ val2 = tick/250;
+ tick_time = 10; // [GodLesZ] tick time
+ break;
- case SC_SIGNUMCRUCIS:
- sc->opt2 |= OPT2_SIGNUMCRUCIS;
- break;
+ //Permanent effects.
+ case SC_AETERNA:
+ case SC_MODECHANGE:
+ case SC_WEIGHT50:
+ case SC_WEIGHT90:
+ case SC_BROKENWEAPON:
+ case SC_BROKENARMOR:
+ case SC_READYSTORM:
+ case SC_READYDOWN:
+ case SC_READYCOUNTER:
+ case SC_READYTURN:
+ case SC_DODGE:
+ case SC_PUSH_CART:
+ tick = -1;
+ break;
- case SC_BLIND:
- sc->opt2 |= OPT2_BLIND;
- break;
- case SC_ANGELUS:
- sc->opt2 |= OPT2_ANGELUS;
- break;
- case SC_BLEEDING:
- sc->opt2 |= OPT2_BLEEDING;
- break;
- case SC_DPOISON:
- sc->opt2 |= OPT2_DPOISON;
- break;
- //OPT3
- case SC_TWOHANDQUICKEN:
- case SC_ONEHAND:
- case SC_SPEARQUICKEN:
- case SC_CONCENTRATION:
- case SC_MERC_QUICKEN:
- sc->opt3 |= OPT3_QUICKEN;
- opt_flag = 0;
- break;
- case SC_MAXOVERTHRUST:
- case SC_OVERTHRUST:
- case SC_SWOO: //Why does it shares the same opt as Overthrust? Perhaps we'll never know...
- sc->opt3 |= OPT3_OVERTHRUST;
- opt_flag = 0;
- break;
- case SC_ENERGYCOAT:
- case SC_SKE:
- sc->opt3 |= OPT3_ENERGYCOAT;
- opt_flag = 0;
- break;
- case SC_INCATKRATE:
- //Simulate Explosion Spirits effect for NPC_POWERUP [Skotlex]
- if (bl->type != BL_MOB) {
- opt_flag = 0;
- break;
- }
- case SC_EXPLOSIONSPIRITS:
- sc->opt3 |= OPT3_EXPLOSIONSPIRITS;
- opt_flag = 0;
- break;
- case SC_STEELBODY:
- case SC_SKA:
- sc->opt3 |= OPT3_STEELBODY;
- opt_flag = 0;
- break;
- case SC_BLADESTOP:
- sc->opt3 |= OPT3_BLADESTOP;
- opt_flag = 0;
- break;
- case SC_AURABLADE:
- sc->opt3 |= OPT3_AURABLADE;
- opt_flag = 0;
- break;
- case SC_BERSERK:
- opt_flag = 0;
- // case SC__BLOODYLUST:
- sc->opt3 |= OPT3_BERSERK;
- break;
- // case ???: // doesn't seem to do anything
- // sc->opt3 |= OPT3_LIGHTBLADE;
- // opt_flag = 0;
- // break;
- case SC_DANCING:
- if ((val1&0xFFFF) == CG_MOONLIT)
- sc->opt3 |= OPT3_MOONLIT;
- opt_flag = 0;
- break;
- case SC_MARIONETTE:
- case SC_MARIONETTE2:
- sc->opt3 |= OPT3_MARIONETTE;
- opt_flag = 0;
- break;
- case SC_ASSUMPTIO:
- sc->opt3 |= OPT3_ASSUMPTIO;
- opt_flag = 0;
- break;
- case SC_WARM: //SG skills [Komurka]
- sc->opt3 |= OPT3_WARM;
- opt_flag = 0;
- break;
- case SC_KAITE:
- sc->opt3 |= OPT3_KAITE;
- opt_flag = 0;
- break;
- case SC_BUNSINJYUTSU:
- sc->opt3 |= OPT3_BUNSIN;
- opt_flag = 0;
- break;
- case SC_SPIRIT:
- sc->opt3 |= OPT3_SOULLINK;
- opt_flag = 0;
- break;
- case SC_CHANGEUNDEAD:
- sc->opt3 |= OPT3_UNDEAD;
- opt_flag = 0;
- break;
- // case ???: // from DA_CONTRACT (looks like biolab mobs aura)
- // sc->opt3 |= OPT3_CONTRACT;
- // opt_flag = 0;
- // break;
- //OPTION
- case SC_HIDING:
- sc->option |= OPTION_HIDE;
- opt_flag = 2;
- break;
- case SC_CLOAKING:
- case SC_CLOAKINGEXCEED:
- case SC__INVISIBILITY:
- sc->option |= OPTION_CLOAK;
- opt_flag = 2;
- break;
- case SC_CHASEWALK:
- sc->option |= OPTION_CHASEWALK|OPTION_CLOAK;
- opt_flag = 2;
- break;
- case SC_SIGHT:
- sc->option |= OPTION_SIGHT;
- break;
- case SC_RUWACH:
- sc->option |= OPTION_RUWACH;
- break;
- case SC_WEDDING:
- sc->option |= OPTION_WEDDING;
- break;
- case SC_XMAS:
- sc->option |= OPTION_XMAS;
- break;
- case SC_SUMMER:
- sc->option |= OPTION_SUMMER;
- break;
- case SC_ORCISH:
- sc->option |= OPTION_ORCISH;
- break;
- case SC_FUSION:
- sc->option |= OPTION_FLYING;
- break;
- default:
- opt_flag = 0;
- }
+ case SC_AUTOGUARD:
+ if( !(flag&1) )
+ {
+ struct map_session_data *tsd;
+ int i,t;
+ for( i = val2 = 0; i < val1; i++)
+ {
+ t = 5-(i>>1);
+ val2 += (t < 0)? 1:t;
+ }
+
+ if( bl->type&(BL_PC|BL_MER) )
+ {
+ if( sd )
+ {
+ for( i = 0; i < 5; i++ )
+ {
+ if( sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])) )
+ status_change_start(&tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1);
+ }
+ }
+ else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) )
+ status_change_start(&tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1);
+ }
+ }
+ break;
- //On Aegis, when turning on a status change, first goes the option packet, then the sc packet.
- if (opt_flag)
- clif_changeoption(bl);
+ case SC_DEFENDER:
+ if (!(flag&1))
+ {
+ val2 = 5 + 15*val1; //Damage reduction
+ val3 = 0; // unused, previously speed adjustment
+ val4 = 250 - 50*val1; //Aspd adjustment
+
+ if (sd)
+ {
+ struct map_session_data *tsd;
+ int i;
+ for (i = 0; i < 5; i++)
+ { //See if there are devoted characters, and pass the status to them. [Skotlex]
+ if (sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])))
+ status_change_start(&tsd->bl,type,10000,val1,5+val1*5,val3,val4,tick,1);
+ }
+ }
+ }
+ break;
- if (calc_flag&SCB_DYE) {
- //Reset DYE color
- if (vd && vd->cloth_color) {
- val4 = vd->cloth_color;
- clif_changelook(bl,LOOK_CLOTHES_COLOR,0);
- }
- calc_flag&=~SCB_DYE;
- }
+ case SC_TENSIONRELAX:
+ if (sd) {
+ pc_setsit(sd);
+ clif_sitting(&sd->bl);
+ }
+ val2 = 12; //SP cost
+ val4 = 10000; //Decrease at 10secs intervals.
+ val3 = tick/val4;
+ tick = -1; // duration sent to the client should be infinite
+ tick_time = val4; // [GodLesZ] tick time
+ break;
+ case SC_PARRYING:
+ val2 = 20 + val1*3; //Block Chance
+ break;
- clif_status_change(bl,StatusIconChangeTable[type],1,tick,(val_flag&1)?val1:1,(val_flag&2)?val2:0,(val_flag&4)?val3:0);
-
- /**
- * used as temporary storage for scs with interval ticks, so that the actual duration is sent to the client first.
- **/
- if (tick_time)
- tick = tick_time;
-
- //Don't trust the previous sce assignment, in case the SC ended somewhere between there and here.
- if ((sce=sc->data[type])) { // reuse old sc
- if (sce->timer != INVALID_TIMER)
- delete_timer(sce->timer, status_change_timer);
- sc_isnew = false;
- } else {// new sc
- ++(sc->count);
- sce = sc->data[type] = ers_alloc(sc_data_ers, struct status_change_entry);
- }
- sce->val1 = val1;
- sce->val2 = val2;
- sce->val3 = val3;
- sce->val4 = val4;
- if (tick >= 0)
- sce->timer = add_timer(gettick() + tick, status_change_timer, bl->id, type);
- else
- sce->timer = INVALID_TIMER; //Infinite duration
+ case SC_WINDWALK:
+ val2 = (val1+1)/2; // Flee bonus is 1/1/2/2/3/3/4/4/5/5
+ break;
+
+ case SC_JOINTBEAT:
+ if( val2&BREAK_NECK )
+ sc_start(bl,SC_BLEEDING,100,val1,skill_get_time2(status_sc2skill(type),val1));
+ break;
- if (calc_flag)
- status_calc_bl(bl,calc_flag);
+ case SC_BERSERK:
+ if (!sc->data[SC_ENDURE] || !sc->data[SC_ENDURE]->val4)
+ sc_start4(bl, SC_ENDURE, 100,10,0,0,2, tick);
+ case SC__BLOODYLUST:
+ //HP healing is performing after the calc_status call.
+ //Val2 holds HP penalty
+ if (!val4) val4 = skill_get_time2(status_sc2skill(type),val1);
+ if (!val4) val4 = 10000; //Val4 holds damage interval
+ val3 = tick/val4; //val3 holds skill duration
+ tick_time = val4; // [GodLesZ] tick time
+ break;
- if (sc_isnew && StatusChangeStateTable[type]) /* non-zero */
- status_calc_state(bl,sc,(enum scs_flag) StatusChangeStateTable[type],true);
+ case SC_GOSPEL:
+ if(val4 == BCT_SELF) { // self effect
+ val2 = tick/10000;
+ tick_time = 10000; // [GodLesZ] tick time
+ status_change_clear_buffs(bl,3); //Remove buffs/debuffs
+ }
+ break;
+ case SC_MARIONETTE:
+ {
+ int stat;
+
+ val3 = 0;
+ val4 = 0;
+ stat = ( sd ? sd->status.str : status_get_base_status(bl)->str ) / 2; val3 |= cap_value(stat,0,0xFF)<<16;
+ stat = ( sd ? sd->status.agi : status_get_base_status(bl)->agi ) / 2; val3 |= cap_value(stat,0,0xFF)<<8;
+ stat = ( sd ? sd->status.vit : status_get_base_status(bl)->vit ) / 2; val3 |= cap_value(stat,0,0xFF);
+ stat = ( sd ? sd->status.int_: status_get_base_status(bl)->int_) / 2; val4 |= cap_value(stat,0,0xFF)<<16;
+ stat = ( sd ? sd->status.dex : status_get_base_status(bl)->dex ) / 2; val4 |= cap_value(stat,0,0xFF)<<8;
+ stat = ( sd ? sd->status.luk : status_get_base_status(bl)->luk ) / 2; val4 |= cap_value(stat,0,0xFF);
+ break;
+ }
+ case SC_MARIONETTE2:
+ {
+ int stat,max_stat;
+ // fetch caster information
+ struct block_list *pbl = map_id2bl(val1);
+ struct status_change *psc = pbl?status_get_sc(pbl):NULL;
+ struct status_change_entry *psce = psc?psc->data[SC_MARIONETTE]:NULL;
+ // fetch target's stats
+ struct status_data* status = status_get_status_data(bl); // battle status
+
+ if (!psce)
+ return 0;
+
+ val3 = 0;
+ val4 = 0;
+ max_stat = battle_config.max_parameter; //Cap to 99 (default)
+ stat = (psce->val3 >>16)&0xFF; stat = min(stat, max_stat - status->str ); val3 |= cap_value(stat,0,0xFF)<<16;
+ stat = (psce->val3 >> 8)&0xFF; stat = min(stat, max_stat - status->agi ); val3 |= cap_value(stat,0,0xFF)<<8;
+ stat = (psce->val3 >> 0)&0xFF; stat = min(stat, max_stat - status->vit ); val3 |= cap_value(stat,0,0xFF);
+ stat = (psce->val4 >>16)&0xFF; stat = min(stat, max_stat - status->int_); val4 |= cap_value(stat,0,0xFF)<<16;
+ stat = (psce->val4 >> 8)&0xFF; stat = min(stat, max_stat - status->dex ); val4 |= cap_value(stat,0,0xFF)<<8;
+ stat = (psce->val4 >> 0)&0xFF; stat = min(stat, max_stat - status->luk ); val4 |= cap_value(stat,0,0xFF);
+ break;
+ }
+ case SC_REJECTSWORD:
+ val2 = 15*val1; //Reflect chance
+ val3 = 3; //Reflections
+ tick = -1;
+ break;
- if (sd && sd->pd)
- pet_sc_check(sd, type); //Skotlex: Pet Status Effect Healing
+ case SC_MEMORIZE:
+ val2 = 5; //Memorized casts.
+ tick = -1;
+ break;
+
+ case SC_GRAVITATION:
+ val2 = 50*val1; //aspd reduction
+ break;
+
+ case SC_REGENERATION:
+ if (val1 == 1)
+ val2 = 2;
+ else
+ val2 = val1; //HP Regerenation rate: 200% 200% 300%
+ val3 = val1; //SP Regeneration Rate: 100% 200% 300%
+ //if val4 comes set, this blocks regen rather than increase it.
+ break;
+
+ case SC_DEVOTION:
+ {
+ struct block_list *d_bl;
+ struct status_change *d_sc;
+
+ if( (d_bl = map_id2bl(val1)) && (d_sc = status_get_sc(d_bl)) && d_sc->count )
+ { // Inherits Status From Source
+ const enum sc_type types[] = { SC_AUTOGUARD, SC_DEFENDER, SC_REFLECTSHIELD, SC_ENDURE };
+ enum sc_type type2;
+ int i = (map_flag_gvg(bl->m) || map[bl->m].flag.battleground)?2:3;
+ while( i >= 0 )
+ {
+ type2 = types[i];
+ if( d_sc->data[type2] )
+ sc_start(bl, type2, 100, d_sc->data[type2]->val1, skill_get_time(status_sc2skill(type2),d_sc->data[type2]->val1));
+ i--;
+ }
+ }
+ break;
+ }
+
+ case SC_COMA: //Coma. Sends a char to 1HP. If val2, do not zap sp
+ if( val3 && bl->type == BL_MOB ) {
+ struct block_list* src = map_id2bl(val3);
+ if( src )
+ mob_log_damage((TBL_MOB*)bl,src,status->hp - 1);
+ }
+ status_zap(bl, status->hp-1, val2?0:status->sp);
+ return 1;
+ break;
+ case SC_CLOSECONFINE2:
+ {
+ struct block_list *src = val2?map_id2bl(val2):NULL;
+ struct status_change *sc2 = src?status_get_sc(src):NULL;
+ struct status_change_entry *sce2 = sc2?sc2->data[SC_CLOSECONFINE]:NULL;
+ if (src && sc2) {
+ if (!sce2) //Start lock on caster.
+ sc_start4(src,SC_CLOSECONFINE,100,val1,1,0,0,tick+1000);
+ else { //Increase count of locked enemies and refresh time.
+ (sce2->val2)++;
+ delete_timer(sce2->timer, status_change_timer);
+ sce2->timer = add_timer(gettick()+tick+1000, status_change_timer, src->id, SC_CLOSECONFINE);
+ }
+ } else //Status failed.
+ return 0;
+ }
+ break;
+ case SC_KAITE:
+ val2 = 1+val1/5; //Number of bounces: 1 + skilllv/5
+ break;
+ case SC_KAUPE:
+ switch (val1) {
+ case 3: //33*3 + 1 -> 100%
+ val2++;
+ case 1:
+ case 2: //33, 66%
+ val2 += 33*val1;
+ val3 = 1; //Dodge 1 attack total.
+ break;
+ default: //Custom. For high level mob usage, higher level means more blocks. [Skotlex]
+ val2 = 100;
+ val3 = val1-2;
+ break;
+ }
+ break;
+
+ case SC_COMBO: {
+ //val1: Skill ID
+ //val2: When given, target (for autotargetting skills)
+ //val3: When set, this combo time should NOT delay attack/movement
+ //val3: TK: Last used kick
+ //val4: TK: Combo time
+ struct unit_data *ud = unit_bl2ud(bl);
+ if (ud && !val3) {
+ tick += 300 * battle_config.combo_delay_rate/100;
+ ud->attackabletime = gettick()+tick;
+ unit_set_walkdelay(bl, gettick(), tick, 1);
+ }
+ val3 = 0;
+ val4 = tick;
+ }
+ break;
+ case SC_EARTHSCROLL:
+ val2 = 11-val1; //Chance to consume: 11-skilllv%
+ break;
+ case SC_RUN:
+ val4 = gettick(); //Store time at which you started running.
+ tick = -1;
+ break;
+ case SC_KAAHI:
+ val2 = 200*val1; //HP heal
+ val3 = 5*val1; //SP cost
+ val4 = INVALID_TIMER; //Kaahi Timer.
+ break;
+ case SC_BLESSING:
+ if ((!undead_flag && status->race!=RC_DEMON) || bl->type == BL_PC)
+ val2 = val1;
+ else
+ val2 = 0; //0 -> Half stat.
+ break;
+ case SC_TRICKDEAD:
+ if (vd) vd->dead_sit = 1;
+ tick = -1;
+ break;
+ case SC_CONCENTRATE:
+ val2 = 2 + val1;
+ if (sd) { //Store the card-bonus data that should not count in the %
+ val3 = sd->param_bonus[1]; //Agi
+ val4 = sd->param_bonus[4]; //Dex
+ } else {
+ val3 = val4 = 0;
+ }
+ break;
+ case SC_MAXOVERTHRUST:
+ val2 = 20*val1; //Power increase
+ break;
+ case SC_OVERTHRUST:
+ //val2 holds if it was casted on self, or is bonus received from others
+ val3 = 5*val1; //Power increase
+ if(sd && pc_checkskill(sd,BS_HILTBINDING)>0)
+ tick += tick / 10;
+ break;
+ case SC_ADRENALINE2:
+ case SC_ADRENALINE:
+ val3 = (val2) ? 300 : 200; // aspd increase
+ case SC_WEAPONPERFECTION:
+ if(sd && pc_checkskill(sd,BS_HILTBINDING)>0)
+ tick += tick / 10;
+ break;
+ case SC_CONCENTRATION:
+ val2 = 5*val1; //Batk/Watk Increase
+ val3 = 10*val1; //Hit Increase
+ val4 = 5*val1; //Def reduction
+ break;
+ case SC_ANGELUS:
+ val2 = 5*val1; //def increase
+ break;
+ case SC_IMPOSITIO:
+ val2 = 5*val1; //watk increase
+ break;
+ case SC_MELTDOWN:
+ val2 = 100*val1; //Chance to break weapon
+ val3 = 70*val1; //Change to break armor
+ break;
+ case SC_TRUESIGHT:
+ val2 = 10*val1; //Critical increase
+ val3 = 3*val1; //Hit increase
+ break;
+ case SC_SUN_COMFORT:
+ val2 = (status_get_lv(bl) + status->dex + status->luk)/2; //def increase
+ break;
+ case SC_MOON_COMFORT:
+ val2 = (status_get_lv(bl) + status->dex + status->luk)/10; //flee increase
+ break;
+ case SC_STAR_COMFORT:
+ val2 = (status_get_lv(bl) + status->dex + status->luk); //Aspd increase
+ break;
+ case SC_QUAGMIRE:
+ val2 = (sd?5:10)*val1; //Agi/Dex decrease.
+ break;
+
+ // gs_something1 [Vicious]
+ case SC_GATLINGFEVER:
+ val2 = 20*val1; //Aspd increase
+ val3 = 20+10*val1; //Batk increase
+ val4 = 5*val1; //Flee decrease
+ break;
+
+ case SC_FLING:
+ if (bl->type == BL_PC)
+ val2 = 0; //No armor reduction to players.
+ else
+ val2 = 5*val1; //Def reduction
+ val3 = 5*val1; //Def2 reduction
+ break;
+ case SC_PROVOKE:
+ //val2 signals autoprovoke.
+ val3 = 2+3*val1; //Atk increase
+ val4 = 5+5*val1; //Def reduction.
+ break;
+ case SC_AVOID:
+ //val2 = 10*val1; //Speed change rate.
+ break;
+ case SC_DEFENCE:
+ val2 = 2*val1; //Def bonus
+ break;
+ case SC_BLOODLUST:
+ val2 = 20+10*val1; //Atk rate change.
+ val3 = 3*val1; //Leech chance
+ val4 = 20; //Leech percent
+ break;
+ case SC_FLEET:
+ val2 = 30*val1; //Aspd change
+ val3 = 5+5*val1; //bAtk/wAtk rate change
+ break;
+ case SC_MINDBREAKER:
+ val2 = 20*val1; //matk increase.
+ val3 = 12*val1; //mdef2 reduction.
+ break;
+ case SC_SKA:
+ val2 = tick/1000;
+ val3 = rnd()%100; //Def changes randomly every second...
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_JAILED:
+ //Val1 is duration in minutes. Use INT_MAX to specify 'unlimited' time.
+ tick = val1>0?1000:250;
+ if (sd)
+ {
+ if (sd->mapindex != val2)
+ {
+ int pos = (bl->x&0xFFFF)|(bl->y<<16), //Current Coordinates
+ map = sd->mapindex; //Current Map
+ //1. Place in Jail (val2 -> Jail Map, val3 -> x, val4 -> y
+ pc_setpos(sd,(unsigned short)val2,val3,val4, CLR_TELEPORT);
+ //2. Set restore point (val3 -> return map, val4 return coords
+ val3 = map;
+ val4 = pos;
+ } else if (!val3 || val3 == sd->mapindex) { //Use save point.
+ val3 = sd->status.save_point.map;
+ val4 = (sd->status.save_point.x&0xFFFF)
+ |(sd->status.save_point.y<<16);
+ }
+ }
+ break;
+ case SC_UTSUSEMI:
+ val2=(val1+1)/2; // number of hits blocked
+ val3=skill_get_blewcount(NJ_UTSUSEMI, val1); //knockback value.
+ break;
+ case SC_BUNSINJYUTSU:
+ val2=(val1+1)/2; // number of hits blocked
+ break;
+ case SC_CHANGE:
+ val2= 30*val1; //Vit increase
+ val3= 20*val1; //Int increase
+ break;
+ case SC_SWOO:
+ if(status->mode&MD_BOSS)
+ tick /= 5; //TODO: Reduce skill's duration. But for how long?
+ break;
+ case SC_SPIDERWEB:
+ if( bl->type == BL_PC )
+ tick /= 2;
+ break;
+ case SC_ARMOR:
+ //NPC_DEFENDER:
+ val2 = 80; //Damage reduction
+ //Attack requirements to be blocked:
+ val3 = BF_LONG; //Range
+ val4 = BF_WEAPON|BF_MISC; //Type
+ break;
+ case SC_ENCHANTARMS:
+ //end previous enchants
+ skill_enchant_elemental_end(bl,type);
+ //Make sure the received element is valid.
+ if (val2 >= ELE_MAX)
+ val2 = val2%ELE_MAX;
+ else if (val2 < 0)
+ val2 = rnd()%ELE_MAX;
+ break;
+ case SC_CRITICALWOUND:
+ val2 = 20*val1; //Heal effectiveness decrease
+ break;
+ case SC_MAGICMIRROR:
+ case SC_SLOWCAST:
+ val2 = 20*val1; //Magic reflection/cast rate
+ break;
+
+ case SC_ARMORCHANGE:
+ if (val2 == NPC_ANTIMAGIC)
+ { //Boost mdef
+ val2 =-20;
+ val3 = 20;
+ } else { //Boost def
+ val2 = 20;
+ val3 =-20;
+ }
+ val2*=val1; //20% per level
+ val3*=val1;
+ break;
+ case SC_EXPBOOST:
+ case SC_JEXPBOOST:
+ if (val1 < 0)
+ val1 = 0;
+ break;
+ case SC_INCFLEE2:
+ case SC_INCCRI:
+ val2 = val1*10; //Actual boost (since 100% = 1000)
+ break;
+ case SC_SUFFRAGIUM:
+ val2 = 15 * val1; //Speed cast decrease
+ break;
+ case SC_INCHEALRATE:
+ if (val1 < 1)
+ val1 = 1;
+ break;
+ case SC_HALLUCINATION:
+ val2 = 5+val1; //Factor by which displayed damage is increased by
+ break;
+ case SC_DOUBLECAST:
+ val2 = 30+10*val1; //Trigger rate
+ break;
+ case SC_KAIZEL:
+ val2 = 10*val1; //% of life to be revived with
+ break;
+ // case SC_ARMOR_ELEMENT:
+ // case SC_ARMOR_RESIST:
+ // Mod your resistance against elements:
+ // val1 = water | val2 = earth | val3 = fire | val4 = wind
+ // break;
+ //case ????:
+ //Place here SCs that have no SCB_* data, no skill associated, no ICON
+ //associated, and yet are not wrong/unknown. [Skotlex]
+ //break;
+
+ case SC_MERC_FLEEUP:
+ case SC_MERC_ATKUP:
+ case SC_MERC_HITUP:
+ val2 = 15 * val1;
+ break;
+ case SC_MERC_HPUP:
+ case SC_MERC_SPUP:
+ val2 = 5 * val1;
+ break;
+ case SC_REBIRTH:
+ val2 = 20*val1; //% of life to be revived with
+ break;
+
+ case SC_MANU_DEF:
+ case SC_MANU_ATK:
+ case SC_MANU_MATK:
+ val2 = 1; // Manuk group
+ break;
+ case SC_SPL_DEF:
+ case SC_SPL_ATK:
+ case SC_SPL_MATK:
+ val2 = 2; // Splendide group
+ break;
+ /**
+ * General
+ **/
+ case SC_FEAR:
+ val2 = 2;
+ val4 = tick / 1000;
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_BURNING:
+ val4 = tick / 2000; // Total Ticks to Burn!!
+ tick_time = 2000; // [GodLesZ] tick time
+ break;
+ /**
+ * Rune Knight
+ **/
+ case SC_DEATHBOUND:
+ val2 = 500 + 100 * val1;
+ break;
+ case SC_FIGHTINGSPIRIT:
+ val_flag |= 1|2;
+ break;
+ case SC_ABUNDANCE:
+ val4 = tick / 10000;
+ tick_time = 10000; // [GodLesZ] tick time
+ break;
+ case SC_GIANTGROWTH:
+ val2 = 10; // Triple damage success rate.
+ break;
+ /**
+ * Arch Bishop
+ **/
+ case SC_RENOVATIO:
+ val4 = tick / 5000;
+ tick_time = 5000;
+ break;
+ case SC_SECRAMENT:
+ val2 = 10 * val1;
+ break;
+ case SC_VENOMIMPRESS:
+ val2 = 10 * val1;
+ val_flag |= 1|2;
+ break;
+ case SC_POISONINGWEAPON:
+ val_flag |= 1|2|4;
+ break;
+ case SC_WEAPONBLOCKING:
+ val2 = 10 + 2 * val1; // Chance
+ val4 = tick / 3000;
+ tick_time = 3000; // [GodLesZ] tick time
+ val_flag |= 1|2;
+ break;
+ case SC_TOXIN:
+ val4 = tick / 10000;
+ tick_time = 10000; // [GodLesZ] tick time
+ break;
+ case SC_MAGICMUSHROOM:
+ val4 = tick / 4000;
+ tick_time = 4000; // [GodLesZ] tick time
+ break;
+ case SC_PYREXIA:
+ status_change_start(bl,SC_BLIND,10000,val1,0,0,0,30000,11); // Blind status that last for 30 seconds
+ val4 = tick / 3000;
+ tick_time = 3000; // [GodLesZ] tick time
+ break;
+ case SC_LEECHESEND:
+ val4 = tick / 1000;
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_OBLIVIONCURSE:
+ val4 = tick / 3000;
+ tick_time = 3000; // [GodLesZ] tick time
+ break;
+ case SC_ROLLINGCUTTER:
+ val_flag |= 1;
+ break;
+ case SC_CLOAKINGEXCEED:
+ val2 = ( val1 + 1 ) / 2; // Hits
+ val3 = 90 + val1 * 10; // Walk speed
+ val_flag |= 1|2|4;
+ if (bl->type == BL_PC)
+ val4 |= battle_config.pc_cloak_check_type&7;
+ else
+ val4 |= battle_config.monster_cloak_check_type&7;
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_HALLUCINATIONWALK:
+ val2 = 50 * val1; // Evasion rate of physical attacks. Flee
+ val3 = 10 * val1; // Evasion rate of magical attacks.
+ val_flag |= 1|2|4;
+ break;
+ case SC_WHITEIMPRISON:
+ status_change_end(bl, SC_BURNING, INVALID_TIMER);
+ status_change_end(bl, SC_FREEZING, INVALID_TIMER);
+ status_change_end(bl, SC_FREEZE, INVALID_TIMER);
+ status_change_end(bl, SC_STONE, INVALID_TIMER);
+ break;
+ case SC_FREEZING:
+ status_change_end(bl, SC_BURNING, INVALID_TIMER);
+ break;
+ case SC_READING_SB:
+ // val2 = sp reduction per second
+ tick_time = 5000; // [GodLesZ] tick time
+ break;
+ case SC_SPHERE_1:
+ case SC_SPHERE_2:
+ case SC_SPHERE_3:
+ case SC_SPHERE_4:
+ case SC_SPHERE_5:
+ if( !sd )
+ return 0; // Should only work on players.
+ val4 = tick / 1000;
+ if( val4 < 1 )
+ val4 = 1;
+ tick_time = 1000; // [GodLesZ] tick time
+ val_flag |= 1;
+ break;
+ case SC_SHAPESHIFT:
+ switch( val1 )
+ {
+ case 1: val2 = ELE_FIRE; break;
+ case 2: val2 = ELE_EARTH; break;
+ case 3: val2 = ELE_WIND; break;
+ case 4: val2 = ELE_WATER; break;
+ }
+ break;
+ case SC_ELECTRICSHOCKER:
+ case SC_CRYSTALIZE:
+ case SC_MEIKYOUSISUI:
+ val4 = tick / 1000;
+ if( val4 < 1 )
+ val4 = 1;
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_CAMOUFLAGE:
+ val4 = tick/1000;
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_WUGDASH:
+ val4 = gettick(); //Store time at which you started running.
+ tick = -1;
+ break;
+ case SC__SHADOWFORM: {
+ struct map_session_data * s_sd = map_id2sd(val2);
+ if( s_sd )
+ s_sd->shadowform_id = bl->id;
+ val4 = tick / 1000;
+ val_flag |= 1|2|4;
+ tick_time = 1000; // [GodLesZ] tick time
+ }
+ break;
+ case SC__STRIPACCESSORY:
+ if (!sd)
+ val2 = 20;
+ break;
+ case SC__INVISIBILITY:
+ val2 = 50 - 10 * val1; // ASPD
+ val3 = 20 * val1; // CRITICAL
+ val4 = tick / 1000;
+ tick_time = 1000; // [GodLesZ] tick time
+ val_flag |= 1|2;
+ break;
+ case SC__ENERVATION:
+ val2 = 20 + 10 * val1; // ATK Reduction
+ val_flag |= 1|2;
+ if( sd ) pc_delspiritball(sd,sd->spiritball,0);
+ break;
+ case SC__GROOMY:
+ val2 = 20 + 10 * val1; //ASPD. Need to confirm if Movement Speed reduction is the same. [Jobbie]
+ val3 = 20 * val1; //HIT
+ val_flag |= 1|2|4;
+ if( sd )
+ { // Removes Animals
+ if( pc_isriding(sd) ) pc_setriding(sd, 0);
+ if( pc_isridingdragon(sd) ) pc_setoption(sd, sd->sc.option&~OPTION_DRAGON);
+ if( pc_iswug(sd) ) pc_setoption(sd, sd->sc.option&~OPTION_WUG);
+ if( pc_isridingwug(sd) ) pc_setoption(sd, sd->sc.option&~OPTION_WUGRIDER);
+ if( pc_isfalcon(sd) ) pc_setoption(sd, sd->sc.option&~OPTION_FALCON);
+ if( sd->status.pet_id > 0 ) pet_menu(sd, 3);
+ if( merc_is_hom_active(sd->hd) ) merc_hom_vaporize(sd,1);
+ if( sd->md ) merc_delete(sd->md,3);
+ }
+ break;
+ case SC__LAZINESS:
+ val2 = 10 + 10 * val1; // Cast reduction
+ val3 = 10 * val1; // Flee Reduction
+ val_flag |= 1|2|4;
+ break;
+ case SC__UNLUCKY:
+ val2 = 10 * val1; // Crit and Flee2 Reduction
+ val_flag |= 1|2|4;
+ break;
+ case SC__WEAKNESS:
+ val2 = 10 * val1;
+ val_flag |= 1|2;
+ // bypasses coating protection and MADO
+ sc_start(bl,SC_STRIPWEAPON,100,val1,tick);
+ sc_start(bl,SC_STRIPSHIELD,100,val1,tick);
+ break;
+ break;
+ case SC_GN_CARTBOOST:
+ if( val1 < 3 )
+ val2 = 50;
+ else if( val1 < 5 )
+ val2 = 75;
+ else
+ val2 = 100;
+ break;
+ case SC_PROPERTYWALK:
+ val_flag |= 1|2;
+ val3 = 0;
+ break;
+ case SC_WARMER:
+ status_change_end(bl, SC_FREEZE, INVALID_TIMER);
+ status_change_end(bl, SC_FREEZING, INVALID_TIMER);
+ status_change_end(bl, SC_CRYSTALIZE, INVALID_TIMER);
+ break;
+ case SC_STRIKING:
+ val1 = 6 - val1;//spcost = 6 - level (lvl1:5 ... lvl 5: 1)
+ val4 = tick / 1000;
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_BLOODSUCKER:
+ val4 = tick / 1000;
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_VACUUM_EXTREME:
+ tick -= (status->str / 20) * 1000;
+ val4 = val3 = tick / 100;
+ tick_time = 100; // [GodLesZ] tick time
+ break;
+ case SC_SWINGDANCE:
+ val2 = 4 * val1; // Walk speed and aspd reduction.
+ break;
+ case SC_SYMPHONYOFLOVER:
+ case SC_RUSHWINDMILL:
+ case SC_ECHOSONG:
+ val2 = 6 * val1;
+ val2 += val3; //Adding 1% * Lesson Bonus
+ val2 += (int)(val4*2/10); //Adding 0.2% per JobLevel
+ break;
+ case SC_MOONLITSERENADE:
+ val2 = 10 * val1;
+ break;
+ case SC_HARMONIZE:
+ val2 = 5 + 5 * val1;
+ break;
+ case SC_VOICEOFSIREN:
+ val4 = tick / 2000;
+ tick_time = 2000; // [GodLesZ] tick time
+ break;
+ case SC_DEEPSLEEP:
+ val4 = tick / 2000;
+ tick_time = 2000; // [GodLesZ] tick time
+ break;
+ case SC_SIRCLEOFNATURE:
+ val2 = 1 + val1; //SP consume
+ val3 = 40 * val1; //HP recovery
+ val4 = tick / 1000;
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_SONGOFMANA:
+ val3 = 10 + (2 * val2);
+ val4 = tick/3000;
+ tick_time = 3000; // [GodLesZ] tick time
+ break;
+ case SC_SATURDAYNIGHTFEVER:
+ if (!val4) val4 = skill_get_time2(status_sc2skill(type),val1);
+ if (!val4) val4 = 3000;
+ val3 = tick/val4;
+ tick_time = val4; // [GodLesZ] tick time
+ break;
+ case SC_GLOOMYDAY:
+ val2 = 20 + 5 * val1; // Flee reduction.
+ val3 = 15 + 5 * val1; // ASPD reduction.
+ if( sd && rand()%100 < val1 ){ // (Skill Lv) %
+ val4 = 1; // reduce walk speed by half.
+ if( pc_isriding(sd) ) pc_setriding(sd, 0);
+ if( pc_isridingdragon(sd) ) pc_setoption(sd, sd->sc.option&~OPTION_DRAGON);
+ }
+ break;
+ case SC_GLOOMYDAY_SK:
+ // Random number between [15 ~ (Voice Lesson Skill Level x 5) + (Skill Level x 10)] %.
+ val2 = 15 + rand()%( (sd?pc_checkskill(sd, WM_LESSON)*5:0) + val1*10 );
+ break;
+ case SC_SITDOWN_FORCE:
+ case SC_BANANA_BOMB_SITDOWN:
+ if( sd && !pc_issit(sd) )
+ {
+ pc_setsit(sd);
+ skill_sit(sd,1);
+ clif_sitting(bl);
+ }
+ break;
+ case SC_DANCEWITHWUG:
+ val3 = (5 * val1) + (1 * val2); //Still need official value.
+ break;
+ case SC_LERADSDEW:
+ val3 = (5 * val1) + (1 * val2);
+ break;
+ case SC_MELODYOFSINK:
+ val3 = (5 * val1) + (1 * val2);
+ break;
+ case SC_BEYONDOFWARCRY:
+ val3 = (5 * val1) + (1 * val2);
+ break;
+ case SC_UNLIMITEDHUMMINGVOICE:
+ {
+ struct unit_data *ud = unit_bl2ud(bl);
+ if( ud == NULL ) return 0;
+ ud->state.skillcastcancel = 0;
+ val3 = 15 - (2 * val2);
+ }
+ break;
+ case SC_REFLECTDAMAGE:
+ val2 = 15 + 5 * val1;
+ val3 = (val1==5)?20:(val1+4)*2; // SP consumption
+ val4 = tick/10000;
+ tick_time = 10000; // [GodLesZ] tick time
+ break;
+ case SC_FORCEOFVANGUARD: // This is not the official way to handle it but I think we should use it. [pakpil]
+ val2 = 20 + 12 * (val1 - 1); // Chance
+ val3 = 5 + (2 * val1); // Max rage counters
+ tick = -1; //endless duration in the client
+ tick_time = 6000; // [GodLesZ] tick time
+ val_flag |= 1|2|4;
+ break;
+ case SC_EXEEDBREAK:
+ val1 *= 150; // 150 * skill_lv
+ if( sd && sd->inventory_data[sd->equip_index[EQI_HAND_R]] ) { // Chars.
+ val1 += (sd->inventory_data[sd->equip_index[EQI_HAND_R]]->weight/10 * sd->inventory_data[sd->equip_index[EQI_HAND_R]]->wlv * status_get_lv(bl) / 100);
+ val1 += 15 * (sd ? sd->status.job_level:50) + 100;
+ }
+ else // Mobs
+ val1 += (400 * status_get_lv(bl) / 100) + (15 * (status_get_lv(bl) / 2)); // About 1138% at mob_lvl 99. Is an aproximation to a standard weapon. [pakpil]
+ break;
+ case SC_PRESTIGE: // Bassed on suggested formula in iRO Wiki and some test, still need more test. [pakpil]
+ val2 = ((status->int_ + status->luk) / 6) + 5; // Chance to evade magic damage.
+ val1 *= 15; // Defence added
+ if( sd )
+ val1 += 10 * pc_checkskill(sd,CR_DEFENDER);
+ val_flag |= 1|2;
+ break;
+ case SC_BANDING:
+ tick_time = 5000; // [GodLesZ] tick time
+ val_flag |= 1;
+ break;
+ case SC_SHIELDSPELL_DEF:
+ case SC_SHIELDSPELL_MDEF:
+ case SC_SHIELDSPELL_REF:
+ val_flag |= 1|2;
+ break;
+ case SC_MAGNETICFIELD:
+ val3 = tick / 1000;
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_INSPIRATION:
+ if( sd )
+ {
+ val2 = (40 * val1) + (3 * sd->status.job_level); // ATK bonus
+ val3 = (sd->status.job_level / 10) * 2 + 12; // All stat bonus
+ }
+ val4 = tick / 1000;
+ tick_time = 1000; // [GodLesZ] tick time
+ status_change_clear_buffs(bl,3); //Remove buffs/debuffs
+ break;
+ case SC_SPELLFIST:
+ case SC_CURSEDCIRCLE_ATKER:
+ val_flag |= 1|2|4;
+ break;
+ case SC_CRESCENTELBOW:
+ val2 = 94 + val1;
+ val_flag |= 1|2;
+ break;
+ case SC_LIGHTNINGWALK: // [(Job Level / 2) + (40 + 5 * Skill Level)] %
+ val1 = (sd?sd->status.job_level:2)/2 + 40 + 5 * val1;
+ val_flag |= 1;
+ break;
+ case SC_RAISINGDRAGON:
+ val3 = tick / 5000;
+ tick_time = 5000; // [GodLesZ] tick time
+ break;
+ case SC_GT_CHANGE:
+ {// take note there is no def increase as skill desc says. [malufett]
+ struct block_list * src;
+ val3 = status->agi * val1 / 60; // ASPD increase: [(Target AGI x Skill Level) / 60] %
+ if( (src = map_id2bl(val2)) )
+ val4 = ( 200/status_get_int(src) ) * val1;// MDEF decrease: MDEF [(200 / Caster INT) x Skill Level]
+ }
+ break;
+ case SC_GT_REVITALIZE:
+ {// take note there is no vit,aspd,speed increase as skill desc says. [malufett]
+ struct block_list * src;
+ val3 = val1 * 30 + 150; // Natural HP recovery increase: [(Skill Level x 30) + 50] %
+ if( (src = map_id2bl(val2)) ) // the stat def is not shown in the status window and it is process differently
+ val4 = ( status_get_vit(src)/4 ) * val1; // STAT DEF increase: [(Caster VIT / 4) x Skill Level]
+ }
+ break;
+ case SC_PYROTECHNIC_OPTION:
+ val2 = 60; // Watk TODO: Renewal (Atk2)
+ val3 = 11; // % Increase damage.
+ val_flag |= 1|2|4;
+ break;
+ case SC_HEATER_OPTION:
+ val2 = 120; // Watk. TODO: Renewal (Atk2)
+ val3 = 33; // % Increase effects.
+ val4 = 3; // Change into fire element.
+ val_flag |= 1|2|4;
+ break;
+ case SC_TROPIC_OPTION:
+ val2 = 180; // Watk. TODO: Renewal (Atk2)
+ val3 = MG_FIREBOLT;
+ break;
+ case SC_AQUAPLAY_OPTION:
+ val2 = 40; // Matk. TODO: Renewal (Matk1)
+ val3 = 33; // % Increase effects.
+ val_flag |= 1|2|4;
+ break;
+ case SC_COOLER_OPTION:
+ val2 = 80; // % Freezing chance
+ val3 = 33; // % increased damage
+ val4 = 1; // Change into water elemet
+ val_flag |= 1|2|4;
+ break;
+ case SC_CHILLY_AIR_OPTION:
+ val2 = 120; // Matk. TODO: Renewal (Matk1)
+ val3 = MG_COLDBOLT;
+ val_flag |= 1|2;
+ break;
+ case SC_GUST_OPTION:
+ val2 = 33;
+ val_flag |= 1|2;
+ break;
+ case SC_WIND_STEP_OPTION:
+ val2 = 50; // % Increase speed and flee.
+ break;
+ case SC_BLAST_OPTION:
+ val2 = 33;
+ val3 = 4;
+ val_flag |= 1|2|4;
+ break;
+ case SC_WILD_STORM_OPTION:
+ val2 = MG_LIGHTNINGBOLT;
+ val_flag |= 1|2;
+ break;
+ case SC_PETROLOGY_OPTION:
+ val2 = 5;
+ val3 = 33;
+ val_flag |= 1|2|4;
+ break;
+ case SC_CURSED_SOIL_OPTION:
+ val2 = 10;
+ val3 = 33;
+ val4 = 2;
+ val_flag |= 1|2|4;
+ break;
+ case SC_UPHEAVAL_OPTION:
+ val2 = WZ_EARTHSPIKE;
+ val_flag |= 1|2;
+ break;
+ case SC_CIRCLE_OF_FIRE_OPTION:
+ val2 = 300;
+ val_flag |= 1|2;
+ break;
+ case SC_FIRE_CLOAK_OPTION:
+ case SC_WATER_DROP_OPTION:
+ case SC_WIND_CURTAIN_OPTION:
+ case SC_STONE_SHIELD_OPTION:
+ val2 = 20; // Elemental modifier. Not confirmed.
+ break;
+ case SC_CIRCLE_OF_FIRE:
+ case SC_FIRE_CLOAK:
+ case SC_WATER_DROP:
+ case SC_WATER_SCREEN:
+ case SC_WIND_CURTAIN:
+ case SC_WIND_STEP:
+ case SC_STONE_SHIELD:
+ case SC_SOLID_SKIN:
+ val2 = 10;
+ tick_time = 2000; // [GodLesZ] tick time
+ break;
+ case SC_WATER_BARRIER:
+ val2 = 40; // Increasement. Mdef1 ???
+ val3 = 20; // Reductions. Atk2, Flee1, Matk1 ????
+ val_flag |= 1|2|4;
+ break;
+ case SC_ZEPHYR:
+ val2 = 22; // Flee.
+ break;
+ case SC_TIDAL_WEAPON:
+ val2 = 20; // Increase Elemental's attack.
+ break;
+ case SC_ROCK_CRUSHER:
+ case SC_ROCK_CRUSHER_ATK:
+ case SC_POWER_OF_GAIA:
+ val2 = 33;
+ break;
+ case SC_MELON_BOMB:
+ case SC_BANANA_BOMB:
+ val1 = 15;
+ break;
+ case SC_STOMACHACHE:
+ val2 = 8; // SP consume.
+ val4 = tick / 10000;
+ tick_time = 10000; // [GodLesZ] tick time
+ break;
+ case SC_KYOUGAKU:
+ val2 = 2*val1 + rand()%val1;
+ clif_status_change(bl,SI_ACTIVE_MONSTER_TRANSFORM,1,0,1002,0,0);
+ break;
+ case SC_KAGEMUSYA:
+ val3 = val1 * 2;
+ case SC_IZAYOI:
+ val2 = tick/1000;
+ tick_time = 1000;
+ break;
+ case SC_ZANGETSU:
+ if( (status_get_hp(bl)+status_get_sp(bl)) % 2 == 0)
+ val2 = status_get_lv(bl) / 2 + 50;
+ else
+ val2 -= 50;
+ break;
+ case SC_GENSOU:
+ {
+ int hp = status_get_hp(bl), lv = 5;
+ short per = 100 / (status_get_max_hp(bl) / hp);
+
+ if( per <= 15 )
+ lv = 1;
+ else if( per <= 30 )
+ lv = 2;
+ else if( per <= 50 )
+ lv = 3;
+ else if( per <= 75 )
+ lv = 4;
+ if( hp % 2 == 0)
+ status_heal(bl, hp * (6-lv) * 4 / 100, status_get_sp(bl) * (6-lv) * 3 / 100, 1);
+ else
+ status_zap(bl, hp * (lv*4) / 100, status_get_sp(bl) * (lv*3) / 100);
+ }
+ break;
+ case SC_ANGRIFFS_MODUS:
+ val2 = 50 + 20 * val1; //atk bonus
+ val3 = 40 + 20 * val1; // Flee reduction.
+ val4 = tick/1000; // hp/sp reduction timer
+ tick_time = 1000;
+ break;
+ case SC_GOLDENE_FERSE:
+ val2 = 10 + 10*val1; //max hp bonus
+ val3 = 6 + 4 * val1; // Aspd Bonus
+ val4 = 2 + 2 * val1; // Chance of holy attack
+ break;
+ case SC_OVERED_BOOST:
+ val2 = 300 + 40*val1; //flee bonus
+ val3 = 179 + 2*val1; //aspd bonus
+ break;
+ case SC_GRANITIC_ARMOR:
+ val2 = 2*val1; //dmg reduction
+ val3 = 6*val1; //dmg on status end
+ break;
+ case SC_MAGMA_FLOW:
+ val2 = 3*val1; //activation chance
+ break;
+ case SC_PYROCLASTIC:
+ val2 += 10*val1; //atk bonus
+ break;
+ case SC_PARALYSIS: //[Lighta] need real info
+ val2 = 2*val1; //def reduction
+ val3 = 500*val1; //varcast augmentation
+ break;
+ case SC_PAIN_KILLER: //[Lighta] need real info
+ val2 = 2*val1; //aspd reduction %
+ val3 = 2*val1; //dmg reduction %
+ if(sc->data[SC_PARALYSIS])
+ sc_start(bl, SC_ENDURE, 100, val1, tick); //start endure for same duration
+ break;
+ default:
+ if( calc_flag == SCB_NONE && StatusSkillChangeTable[type] == 0 && StatusIconChangeTable[type] == 0 )
+ { //Status change with no calc, no icon, and no skill associated...?
+ ShowError("UnknownStatusChange [%d]\n", type);
+ return 0;
+ }
+ }
+ else //Special considerations when loading SC data.
+ switch( type )
+ {
+ case SC_WEDDING:
+ case SC_XMAS:
+ case SC_SUMMER:
+ clif_changelook(bl,LOOK_WEAPON,0);
+ clif_changelook(bl,LOOK_SHIELD,0);
+ clif_changelook(bl,LOOK_BASE,type==SC_WEDDING?JOB_WEDDING:type==SC_XMAS?JOB_XMAS:JOB_SUMMER);
+ clif_changelook(bl,LOOK_CLOTHES_COLOR,val4);
+ break;
+ case SC_KAAHI:
+ val4 = INVALID_TIMER;
+ break;
+ }
+
+ //Those that make you stop attacking/walking....
+ switch (type) {
+ case SC_FREEZE:
+ case SC_STUN:
+ case SC_SLEEP:
+ case SC_STONE:
+ case SC_DEEPSLEEP:
+ if (sd && pc_issit(sd)) //Avoid sprite sync problems.
+ pc_setstand(sd);
+ case SC_TRICKDEAD:
+ unit_stop_attack(bl);
+ status_change_end(bl, SC_DANCING, INVALID_TIMER);
+ // Cancel cast when get status [LuzZza]
+ if (battle_config.sc_castcancel&bl->type)
+ unit_skillcastcancel(bl, 0);
+ case SC_STOP:
+ case SC_CONFUSION:
+ case SC_CLOSECONFINE:
+ case SC_CLOSECONFINE2:
+ case SC_ANKLE:
+ case SC_SPIDERWEB:
+ case SC_ELECTRICSHOCKER:
+ case SC_BITE:
+ case SC_THORNSTRAP:
+ case SC__MANHOLE:
+ case SC_CRYSTALIZE:
+ case SC_WHITEIMPRISON:
+ case SC_CURSEDCIRCLE_ATKER:
+ case SC_CURSEDCIRCLE_TARGET:
+ case SC_FEAR:
+ case SC_NETHERWORLD:
+ case SC_MEIKYOUSISUI:
+ case SC_KYOUGAKU:
+ case SC_PARALYSIS:
+ unit_stop_walking(bl,1);
+ break;
+ case SC_HIDING:
+ case SC_CLOAKING:
+ case SC_CLOAKINGEXCEED:
+ case SC_CHASEWALK:
+ case SC_WEIGHT90:
+ case SC_CAMOUFLAGE:
+ case SC_VOICEOFSIREN:
+ unit_stop_attack(bl);
+ break;
+ case SC_SILENCE:
+ if (battle_config.sc_castcancel&bl->type)
+ unit_skillcastcancel(bl, 0);
+ break;
+ }
+
+ // Set option as needed.
+ opt_flag = 1;
+ switch(type)
+ {
+ //OPT1
+ case SC_STONE: sc->opt1 = OPT1_STONEWAIT; break;
+ case SC_FREEZE: sc->opt1 = OPT1_FREEZE; break;
+ case SC_STUN: sc->opt1 = OPT1_STUN; break;
+ case SC_SLEEP:
+ case SC_DEEPSLEEP: sc->opt1 = OPT1_SLEEP; break;
+ case SC_BURNING: sc->opt1 = OPT1_BURNING; break; // Burning need this to be showed correctly. [pakpil]
+ case SC_WHITEIMPRISON: sc->opt1 = OPT1_IMPRISON; break;
+ case SC_CRYSTALIZE: sc->opt1 = OPT1_CRYSTALIZE; break;
+ //OPT2
+ case SC_POISON: sc->opt2 |= OPT2_POISON; break;
+ case SC_CURSE: sc->opt2 |= OPT2_CURSE; break;
+ case SC_SILENCE: sc->opt2 |= OPT2_SILENCE; break;
+
+ case SC_SIGNUMCRUCIS:
+ sc->opt2 |= OPT2_SIGNUMCRUCIS;
+ break;
+
+ case SC_BLIND: sc->opt2 |= OPT2_BLIND; break;
+ case SC_ANGELUS: sc->opt2 |= OPT2_ANGELUS; break;
+ case SC_BLEEDING: sc->opt2 |= OPT2_BLEEDING; break;
+ case SC_DPOISON: sc->opt2 |= OPT2_DPOISON; break;
+ //OPT3
+ case SC_TWOHANDQUICKEN:
+ case SC_ONEHAND:
+ case SC_SPEARQUICKEN:
+ case SC_CONCENTRATION:
+ case SC_MERC_QUICKEN:
+ sc->opt3 |= OPT3_QUICKEN;
+ opt_flag = 0;
+ break;
+ case SC_MAXOVERTHRUST:
+ case SC_OVERTHRUST:
+ case SC_SWOO: //Why does it shares the same opt as Overthrust? Perhaps we'll never know...
+ sc->opt3 |= OPT3_OVERTHRUST;
+ opt_flag = 0;
+ break;
+ case SC_ENERGYCOAT:
+ case SC_SKE:
+ sc->opt3 |= OPT3_ENERGYCOAT;
+ opt_flag = 0;
+ break;
+ case SC_INCATKRATE:
+ //Simulate Explosion Spirits effect for NPC_POWERUP [Skotlex]
+ if (bl->type != BL_MOB) {
+ opt_flag = 0;
+ break;
+ }
+ case SC_EXPLOSIONSPIRITS:
+ sc->opt3 |= OPT3_EXPLOSIONSPIRITS;
+ opt_flag = 0;
+ break;
+ case SC_STEELBODY:
+ case SC_SKA:
+ sc->opt3 |= OPT3_STEELBODY;
+ opt_flag = 0;
+ break;
+ case SC_BLADESTOP:
+ sc->opt3 |= OPT3_BLADESTOP;
+ opt_flag = 0;
+ break;
+ case SC_AURABLADE:
+ sc->opt3 |= OPT3_AURABLADE;
+ opt_flag = 0;
+ break;
+ case SC_BERSERK:
+ opt_flag = 0;
+// case SC__BLOODYLUST:
+ sc->opt3 |= OPT3_BERSERK;
+ break;
+// case ???: // doesn't seem to do anything
+// sc->opt3 |= OPT3_LIGHTBLADE;
+// opt_flag = 0;
+// break;
+ case SC_DANCING:
+ if ((val1&0xFFFF) == CG_MOONLIT)
+ sc->opt3 |= OPT3_MOONLIT;
+ opt_flag = 0;
+ break;
+ case SC_MARIONETTE:
+ case SC_MARIONETTE2:
+ sc->opt3 |= OPT3_MARIONETTE;
+ opt_flag = 0;
+ break;
+ case SC_ASSUMPTIO:
+ sc->opt3 |= OPT3_ASSUMPTIO;
+ opt_flag = 0;
+ break;
+ case SC_WARM: //SG skills [Komurka]
+ sc->opt3 |= OPT3_WARM;
+ opt_flag = 0;
+ break;
+ case SC_KAITE:
+ sc->opt3 |= OPT3_KAITE;
+ opt_flag = 0;
+ break;
+ case SC_BUNSINJYUTSU:
+ sc->opt3 |= OPT3_BUNSIN;
+ opt_flag = 0;
+ break;
+ case SC_SPIRIT:
+ sc->opt3 |= OPT3_SOULLINK;
+ opt_flag = 0;
+ break;
+ case SC_CHANGEUNDEAD:
+ sc->opt3 |= OPT3_UNDEAD;
+ opt_flag = 0;
+ break;
+// case ???: // from DA_CONTRACT (looks like biolab mobs aura)
+// sc->opt3 |= OPT3_CONTRACT;
+// opt_flag = 0;
+// break;
+ //OPTION
+ case SC_HIDING:
+ sc->option |= OPTION_HIDE;
+ opt_flag = 2;
+ break;
+ case SC_CLOAKING:
+ case SC_CLOAKINGEXCEED:
+ case SC__INVISIBILITY:
+ sc->option |= OPTION_CLOAK;
+ opt_flag = 2;
+ break;
+ case SC_CHASEWALK:
+ sc->option |= OPTION_CHASEWALK|OPTION_CLOAK;
+ opt_flag = 2;
+ break;
+ case SC_SIGHT:
+ sc->option |= OPTION_SIGHT;
+ break;
+ case SC_RUWACH:
+ sc->option |= OPTION_RUWACH;
+ break;
+ case SC_WEDDING:
+ sc->option |= OPTION_WEDDING;
+ break;
+ case SC_XMAS:
+ sc->option |= OPTION_XMAS;
+ break;
+ case SC_SUMMER:
+ sc->option |= OPTION_SUMMER;
+ break;
+ case SC_ORCISH:
+ sc->option |= OPTION_ORCISH;
+ break;
+ case SC_FUSION:
+ sc->option |= OPTION_FLYING;
+ break;
+ default:
+ opt_flag = 0;
+ }
+
+ //On Aegis, when turning on a status change, first goes the option packet, then the sc packet.
+ if(opt_flag)
+ clif_changeoption(bl);
+
+ if (calc_flag&SCB_DYE)
+ { //Reset DYE color
+ if (vd && vd->cloth_color)
+ {
+ val4 = vd->cloth_color;
+ clif_changelook(bl,LOOK_CLOTHES_COLOR,0);
+ }
+ calc_flag&=~SCB_DYE;
+ }
+
+ clif_status_change(bl,StatusIconChangeTable[type],1,tick,(val_flag&1)?val1:1,(val_flag&2)?val2:0,(val_flag&4)?val3:0);
+
+ /**
+ * used as temporary storage for scs with interval ticks, so that the actual duration is sent to the client first.
+ **/
+ if( tick_time )
+ tick = tick_time;
+
+ //Don't trust the previous sce assignment, in case the SC ended somewhere between there and here.
+ if((sce=sc->data[type])) {// reuse old sc
+ if( sce->timer != INVALID_TIMER )
+ delete_timer(sce->timer, status_change_timer);
+ sc_isnew = false;
+ } else {// new sc
+ ++(sc->count);
+ sce = sc->data[type] = ers_alloc(sc_data_ers, struct status_change_entry);
+ }
+ sce->val1 = val1;
+ sce->val2 = val2;
+ sce->val3 = val3;
+ sce->val4 = val4;
+ if (tick >= 0)
+ sce->timer = add_timer(gettick() + tick, status_change_timer, bl->id, type);
+ else
+ sce->timer = INVALID_TIMER; //Infinite duration
+
+ if (calc_flag)
+ status_calc_bl(bl,calc_flag);
+
+ if ( sc_isnew && StatusChangeStateTable[type] ) /* non-zero */
+ status_calc_state(bl,sc,( enum scs_flag ) StatusChangeStateTable[type],true);
+
+
+ if(sd && sd->pd)
+ pet_sc_check(sd, type); //Skotlex: Pet Status Effect Healing
switch (type) {
- case SC__BLOODYLUST:
- case SC_BERSERK:
- if (!(sce->val2)) { //don't heal if already set
- status_heal(bl, status->max_hp, 0, 1); //Do not use percent_heal as this healing must override BERSERK's block.
- status_set_sp(bl, 0, 0); //Damage all SP
- }
- sce->val2 = 5 * status->max_hp / 100;
- break;
- case SC_CHANGE:
- status_percent_heal(bl, 100, 100);
- break;
- case SC_RUN: {
- struct unit_data *ud = unit_bl2ud(bl);
- if (ud)
- ud->state.running = unit_run(bl);
- }
- break;
- case SC_BOSSMAPINFO:
- clif_bossmapinfo(sd->fd, map_id2boss(sce->val1), 0); // First Message
- break;
- case SC_MERC_HPUP:
- status_percent_heal(bl, 100, 0); // Recover Full HP
- break;
- case SC_MERC_SPUP:
- status_percent_heal(bl, 0, 100); // Recover Full SP
- break;
- /**
- * Ranger
- **/
- case SC_WUGDASH: {
- struct unit_data *ud = unit_bl2ud(bl);
- if (ud)
- ud->state.running = unit_wugdash(bl, sd);
- }
- break;
- case SC_COMBO:
- switch (sce->val1) {
- case TK_STORMKICK:
- clif_skill_nodamage(bl,bl,TK_READYSTORM,1,1);
- break;
- case TK_DOWNKICK:
- clif_skill_nodamage(bl,bl,TK_READYDOWN,1,1);
- break;
- case TK_TURNKICK:
- clif_skill_nodamage(bl,bl,TK_READYTURN,1,1);
- break;
- case TK_COUNTER:
- clif_skill_nodamage(bl,bl,TK_READYCOUNTER,1,1);
- break;
- case MO_COMBOFINISH:
- case CH_TIGERFIST:
- case CH_CHAINCRUSH:
- if (sd)
- clif_skillinfo(sd,MO_EXTREMITYFIST, INF_SELF_SKILL);
- break;
- case TK_JUMPKICK:
- if (sd)
- clif_skillinfo(sd,TK_JUMPKICK, INF_SELF_SKILL);
- break;
- case MO_TRIPLEATTACK:
- if (sd && pc_checkskill(sd, SR_DRAGONCOMBO) > 0)
- clif_skillinfo(sd,SR_DRAGONCOMBO, INF_SELF_SKILL);
- break;
- case SR_FALLENEMPIRE:
- if (sd) {
- clif_skillinfo(sd,SR_GATEOFHELL, INF_SELF_SKILL);
- clif_skillinfo(sd,SR_TIGERCANNON, INF_SELF_SKILL);
- }
- break;
- }
- break;
- case SC_RAISINGDRAGON:
- sce->val2 = status->max_hp / 100;// Officially tested its 1%hp drain. [Jobbie]
- break;
- }
+ case SC__BLOODYLUST:
+ case SC_BERSERK:
+ if (!(sce->val2)) { //don't heal if already set
+ status_heal(bl, status->max_hp, 0, 1); //Do not use percent_heal as this healing must override BERSERK's block.
+ status_set_sp(bl, 0, 0); //Damage all SP
+ }
+ sce->val2 = 5 * status->max_hp / 100;
+ break;
+ case SC_CHANGE:
+ status_percent_heal(bl, 100, 100);
+ break;
+ case SC_RUN:
+ {
+ struct unit_data *ud = unit_bl2ud(bl);
+ if( ud )
+ ud->state.running = unit_run(bl);
+ }
+ break;
+ case SC_BOSSMAPINFO:
+ clif_bossmapinfo(sd->fd, map_id2boss(sce->val1), 0); // First Message
+ break;
+ case SC_MERC_HPUP:
+ status_percent_heal(bl, 100, 0); // Recover Full HP
+ break;
+ case SC_MERC_SPUP:
+ status_percent_heal(bl, 0, 100); // Recover Full SP
+ break;
+ /**
+ * Ranger
+ **/
+ case SC_WUGDASH:
+ {
+ struct unit_data *ud = unit_bl2ud(bl);
+ if( ud )
+ ud->state.running = unit_wugdash(bl, sd);
+ }
+ break;
+ case SC_COMBO:
+ switch (sce->val1) {
+ case TK_STORMKICK:
+ clif_skill_nodamage(bl,bl,TK_READYSTORM,1,1);
+ break;
+ case TK_DOWNKICK:
+ clif_skill_nodamage(bl,bl,TK_READYDOWN,1,1);
+ break;
+ case TK_TURNKICK:
+ clif_skill_nodamage(bl,bl,TK_READYTURN,1,1);
+ break;
+ case TK_COUNTER:
+ clif_skill_nodamage(bl,bl,TK_READYCOUNTER,1,1);
+ break;
+ case MO_COMBOFINISH:
+ case CH_TIGERFIST:
+ case CH_CHAINCRUSH:
+ if (sd)
+ clif_skillinfo(sd,MO_EXTREMITYFIST, INF_SELF_SKILL);
+ break;
+ case TK_JUMPKICK:
+ if (sd)
+ clif_skillinfo(sd,TK_JUMPKICK, INF_SELF_SKILL);
+ break;
+ case MO_TRIPLEATTACK:
+ if (sd && pc_checkskill(sd, SR_DRAGONCOMBO) > 0)
+ clif_skillinfo(sd,SR_DRAGONCOMBO, INF_SELF_SKILL);
+ break;
+ case SR_FALLENEMPIRE:
+ if (sd){
+ clif_skillinfo(sd,SR_GATEOFHELL, INF_SELF_SKILL);
+ clif_skillinfo(sd,SR_TIGERCANNON, INF_SELF_SKILL);
+ }
+ break;
+ }
+ break;
+ case SC_RAISINGDRAGON:
+ sce->val2 = status->max_hp / 100;// Officially tested its 1%hp drain. [Jobbie]
+ break;
+ }
- if (opt_flag&2 && sd && sd->touching_id)
- npc_touchnext_areanpc(sd,false); // run OnTouch_ on next char in range
+ if( opt_flag&2 && sd && sd->touching_id )
+ npc_touchnext_areanpc(sd,false); // run OnTouch_ on next char in range
- return 1;
+ return 1;
}
/*==========================================
@@ -8948,797 +8843,821 @@ int status_change_start(struct block_list *bl,enum sc_type type,int rate,int val
* 2 - Do clif
* 3 - Do not remove some permanent/time-independent effects
*------------------------------------------*/
-int status_change_clear(struct block_list *bl, int type)
+int status_change_clear(struct block_list* bl, int type)
{
- struct status_change *sc;
- int i;
+ struct status_change* sc;
+ int i;
- sc = status_get_sc(bl);
+ sc = status_get_sc(bl);
- if (!sc || !sc->count)
- return 0;
-
- for (i = 0; i < SC_MAX; i++) {
- if (!sc->data[i])
- continue;
-
- if (type == 0)
- switch (i) {
- //Type 0: PC killed -> Place here statuses that do not dispel on death.
- case SC_ELEMENTALCHANGE://Only when its Holy or Dark that it doesn't dispell on death
- if (sc->data[i]->val2 != ELE_HOLY && sc->data[i]->val2 != ELE_DARK)
- break;
- case SC_WEIGHT50:
- case SC_WEIGHT90:
- case SC_EDP:
- case SC_MELTDOWN:
- case SC_XMAS:
- case SC_SUMMER:
- case SC_NOCHAT:
- case SC_FUSION:
- case SC_EARTHSCROLL:
- case SC_READYSTORM:
- case SC_READYDOWN:
- case SC_READYCOUNTER:
- case SC_READYTURN:
- case SC_DODGE:
- case SC_JAILED:
- case SC_EXPBOOST:
- case SC_ITEMBOOST:
- case SC_HELLPOWER:
- case SC_JEXPBOOST:
- case SC_AUTOTRADE:
- case SC_WHISTLE:
- case SC_ASSNCROS:
- case SC_POEMBRAGI:
- case SC_APPLEIDUN:
- case SC_HUMMING:
- case SC_DONTFORGETME:
- case SC_FORTUNE:
- case SC_SERVICE4U:
- case SC_FOOD_STR_CASH:
- case SC_FOOD_AGI_CASH:
- case SC_FOOD_VIT_CASH:
- case SC_FOOD_DEX_CASH:
- case SC_FOOD_INT_CASH:
- case SC_FOOD_LUK_CASH:
- case SC_DEF_RATE:
- case SC_MDEF_RATE:
- case SC_INCHEALRATE:
- case SC_INCFLEE2:
- case SC_INCHIT:
- case SC_ATKPOTION:
- case SC_MATKPOTION:
- case SC_S_LIFEPOTION:
- case SC_L_LIFEPOTION:
- case SC_PUSH_CART:
- continue;
+ if (!sc || !sc->count)
+ return 0;
- }
+ for(i = 0; i < SC_MAX; i++)
+ {
+ if(!sc->data[i])
+ continue;
- if (type == 3) {
- switch (i) {
- // TODO: This list may be incomplete
- case SC_WEIGHT50:
- case SC_WEIGHT90:
- case SC_NOCHAT:
- case SC_PUSH_CART:
- continue;
- }
- }
+ if(type == 0)
+ switch (i)
+ { //Type 0: PC killed -> Place here statuses that do not dispel on death.
+ case SC_ELEMENTALCHANGE://Only when its Holy or Dark that it doesn't dispell on death
+ if( sc->data[i]->val2 != ELE_HOLY && sc->data[i]->val2 != ELE_DARK )
+ break;
+ case SC_WEIGHT50:
+ case SC_WEIGHT90:
+ case SC_EDP:
+ case SC_MELTDOWN:
+ case SC_XMAS:
+ case SC_SUMMER:
+ case SC_NOCHAT:
+ case SC_FUSION:
+ case SC_EARTHSCROLL:
+ case SC_READYSTORM:
+ case SC_READYDOWN:
+ case SC_READYCOUNTER:
+ case SC_READYTURN:
+ case SC_DODGE:
+ case SC_JAILED:
+ case SC_EXPBOOST:
+ case SC_ITEMBOOST:
+ case SC_HELLPOWER:
+ case SC_JEXPBOOST:
+ case SC_AUTOTRADE:
+ case SC_WHISTLE:
+ case SC_ASSNCROS:
+ case SC_POEMBRAGI:
+ case SC_APPLEIDUN:
+ case SC_HUMMING:
+ case SC_DONTFORGETME:
+ case SC_FORTUNE:
+ case SC_SERVICE4U:
+ case SC_FOOD_STR_CASH:
+ case SC_FOOD_AGI_CASH:
+ case SC_FOOD_VIT_CASH:
+ case SC_FOOD_DEX_CASH:
+ case SC_FOOD_INT_CASH:
+ case SC_FOOD_LUK_CASH:
+ case SC_DEF_RATE:
+ case SC_MDEF_RATE:
+ case SC_INCHEALRATE:
+ case SC_INCFLEE2:
+ case SC_INCHIT:
+ case SC_ATKPOTION:
+ case SC_MATKPOTION:
+ case SC_S_LIFEPOTION:
+ case SC_L_LIFEPOTION:
+ case SC_PUSH_CART:
+ continue;
- status_change_end(bl, (sc_type)i, INVALID_TIMER);
+ }
+
+ if( type == 3 )
+ {
+ switch (i)
+ {// TODO: This list may be incomplete
+ case SC_WEIGHT50:
+ case SC_WEIGHT90:
+ case SC_NOCHAT:
+ case SC_PUSH_CART:
+ continue;
+ }
+ }
- if (type == 1 && sc->data[i]) {
- //If for some reason status_change_end decides to still keep the status when quitting. [Skotlex]
- (sc->count)--;
- if (sc->data[i]->timer != INVALID_TIMER)
- delete_timer(sc->data[i]->timer, status_change_timer);
- ers_free(sc_data_ers, sc->data[i]);
- sc->data[i] = NULL;
- }
- }
+ status_change_end(bl, (sc_type)i, INVALID_TIMER);
- sc->opt1 = 0;
- sc->opt2 = 0;
- sc->opt3 = 0;
- sc->option &= OPTION_MASK;
+ if( type == 1 && sc->data[i] )
+ { //If for some reason status_change_end decides to still keep the status when quitting. [Skotlex]
+ (sc->count)--;
+ if (sc->data[i]->timer != INVALID_TIMER)
+ delete_timer(sc->data[i]->timer, status_change_timer);
+ ers_free(sc_data_ers, sc->data[i]);
+ sc->data[i] = NULL;
+ }
+ }
- if (type == 0 || type == 2)
- clif_changeoption(bl);
+ sc->opt1 = 0;
+ sc->opt2 = 0;
+ sc->opt3 = 0;
+ sc->option &= OPTION_MASK;
- return 1;
+ if( type == 0 || type == 2 )
+ clif_changeoption(bl);
+
+ return 1;
}
/*==========================================
* Special condition we want to effectuate, check before ending a status.
*------------------------------------------*/
-int status_change_end_(struct block_list *bl, enum sc_type type, int tid, const char *file, int line)
+int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const char* file, int line)
{
- struct map_session_data *sd;
- struct status_change *sc;
- struct status_change_entry *sce;
- struct status_data *status;
- struct view_data *vd;
- int opt_flag=0, calc_flag;
-
- nullpo_ret(bl);
-
- sc = status_get_sc(bl);
- status = status_get_status_data(bl);
-
- if (type < 0 || type >= SC_MAX || !sc || !(sce = sc->data[type]))
- return 0;
-
- sd = BL_CAST(BL_PC,bl);
-
- if (sce->timer != tid && tid != INVALID_TIMER)
- return 0;
-
- if (tid == INVALID_TIMER) {
- if (type == SC_ENDURE && sce->val4)
- //Do not end infinite endure.
- return 0;
- if (sce->timer != INVALID_TIMER) //Could be a SC with infinite duration
- delete_timer(sce->timer,status_change_timer);
- if (sc->opt1)
- switch (type) {
- //"Ugly workaround" [Skotlex]
- //delays status change ending so that a skill that sets opt1 fails to
- //trigger when it also removed one
- case SC_STONE:
- sce->val3 = 0; //Petrify time counter.
- case SC_FREEZE:
- case SC_STUN:
- case SC_SLEEP:
- if (sce->val1) {
- //Removing the 'level' shouldn't affect anything in the code
- //since these SC are not affected by it, and it lets us know
- //if we have already delayed this attack or not.
- sce->val1 = 0;
- sce->timer = add_timer(gettick()+10, status_change_timer, bl->id, type);
- return 1;
- }
- }
- }
+ struct map_session_data *sd;
+ struct status_change *sc;
+ struct status_change_entry *sce;
+ struct status_data *status;
+ struct view_data *vd;
+ int opt_flag=0, calc_flag;
+
+ nullpo_ret(bl);
+
+ sc = status_get_sc(bl);
+ status = status_get_status_data(bl);
+
+ if(type < 0 || type >= SC_MAX || !sc || !(sce = sc->data[type]))
+ return 0;
+
+ sd = BL_CAST(BL_PC,bl);
+
+ if (sce->timer != tid && tid != INVALID_TIMER)
+ return 0;
+
+ if (tid == INVALID_TIMER) {
+ if (type == SC_ENDURE && sce->val4)
+ //Do not end infinite endure.
+ return 0;
+ if (sce->timer != INVALID_TIMER) //Could be a SC with infinite duration
+ delete_timer(sce->timer,status_change_timer);
+ if (sc->opt1)
+ switch (type) {
+ //"Ugly workaround" [Skotlex]
+ //delays status change ending so that a skill that sets opt1 fails to
+ //trigger when it also removed one
+ case SC_STONE:
+ sce->val3 = 0; //Petrify time counter.
+ case SC_FREEZE:
+ case SC_STUN:
+ case SC_SLEEP:
+ if (sce->val1) {
+ //Removing the 'level' shouldn't affect anything in the code
+ //since these SC are not affected by it, and it lets us know
+ //if we have already delayed this attack or not.
+ sce->val1 = 0;
+ sce->timer = add_timer(gettick()+10, status_change_timer, bl->id, type);
+ return 1;
+ }
+ }
+ }
- (sc->count)--;
+ (sc->count)--;
- if (StatusChangeStateTable[type])
- status_calc_state(bl,sc,(enum scs_flag) StatusChangeStateTable[type],false);
+ if ( StatusChangeStateTable[type] )
+ status_calc_state(bl,sc,( enum scs_flag ) StatusChangeStateTable[type],false);
- sc->data[type] = NULL;
+ sc->data[type] = NULL;
- vd = status_get_viewdata(bl);
- calc_flag = StatusChangeFlagTable[type];
- switch (type) {
- case SC_GRANITIC_ARMOR: {
- int dammage = status->max_hp*sce->val3/100;
- if (status->hp < dammage) //to not kill him
- dammage = status->hp-1;
- status_damage(NULL, bl, dammage,0,0,1);
- break;
- }
+ vd = status_get_viewdata(bl);
+ calc_flag = StatusChangeFlagTable[type];
+ switch(type){
+ case SC_GRANITIC_ARMOR:{
+ int dammage = status->max_hp*sce->val3/100;
+ if(status->hp < dammage) //to not kill him
+ dammage = status->hp-1;
+ status_damage(NULL, bl, dammage,0,0,1);
+ break;
+ }
case SC_PYROCLASTIC:
- if (bl->type == BL_PC)
+ if(bl->type == BL_PC)
skill_break_equip(bl,EQP_WEAPON,10000,BCT_SELF);
break;
- case SC_WEDDING:
- case SC_XMAS:
- case SC_SUMMER:
- if (!vd) break;
- if (sd) {
- //Load data from sd->status.* as the stored values could have changed.
- //Must remove OPTION to prevent class being rechanged.
- sc->option &= type==SC_WEDDING?~OPTION_WEDDING:type==SC_XMAS?~OPTION_XMAS:~OPTION_SUMMER;
- clif_changeoption(&sd->bl);
- status_set_viewdata(bl, sd->status.class_);
- } else {
- vd->class_ = sce->val1;
- vd->weapon = sce->val2;
- vd->shield = sce->val3;
- vd->cloth_color = sce->val4;
- }
- clif_changelook(bl,LOOK_BASE,vd->class_);
- clif_changelook(bl,LOOK_CLOTHES_COLOR,vd->cloth_color);
- clif_changelook(bl,LOOK_WEAPON,vd->weapon);
- clif_changelook(bl,LOOK_SHIELD,vd->shield);
- if (sd) clif_skillinfoblock(sd);
- break;
- case SC_RUN: {
- struct unit_data *ud = unit_bl2ud(bl);
- bool begin_spurt = true;
- if (ud) {
- if (!ud->state.running)
- begin_spurt = false;
- ud->state.running = 0;
- if (ud->walktimer != INVALID_TIMER)
- unit_stop_walking(bl,1);
- }
- if (begin_spurt && sce->val1 >= 7 &&
- DIFF_TICK(gettick(), sce->val4) <= 1000 &&
- (!sd || (sd->weapontype1 == 0 && sd->weapontype2 == 0))
- )
- sc_start(bl,SC_SPURT,100,sce->val1,skill_get_time2(status_sc2skill(type), sce->val1));
- }
- break;
- case SC_AUTOBERSERK:
- if (sc->data[SC_PROVOKE] && sc->data[SC_PROVOKE]->val2 == 1)
- status_change_end(bl, SC_PROVOKE, INVALID_TIMER);
- break;
-
- case SC_ENDURE:
- case SC_DEFENDER:
- case SC_REFLECTSHIELD:
- case SC_AUTOGUARD: {
- struct map_session_data *tsd;
- if (bl->type == BL_PC) {
- // Clear Status from others
- int i;
- for (i = 0; i < 5; i++) {
- if (sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])) && tsd->sc.data[type])
- status_change_end(&tsd->bl, type, INVALID_TIMER);
- }
- } else if (bl->type == BL_MER && ((TBL_MER *)bl)->devotion_flag) {
- // Clear Status from Master
- tsd = ((TBL_MER *)bl)->master;
- if (tsd && tsd->sc.data[type])
- status_change_end(&tsd->bl, type, INVALID_TIMER);
- }
- }
- break;
- case SC_DEVOTION: {
- struct block_list *d_bl = map_id2bl(sce->val1);
- if (d_bl) {
- if (d_bl->type == BL_PC)
- ((TBL_PC *)d_bl)->devotion[sce->val2] = 0;
- else if (d_bl->type == BL_MER)
- ((TBL_MER *)d_bl)->devotion_flag = 0;
- clif_devotion(d_bl, NULL);
- }
-
- status_change_end(bl, SC_AUTOGUARD, INVALID_TIMER);
- status_change_end(bl, SC_DEFENDER, INVALID_TIMER);
- status_change_end(bl, SC_REFLECTSHIELD, INVALID_TIMER);
- status_change_end(bl, SC_ENDURE, INVALID_TIMER);
- }
- break;
-
- case SC_BLADESTOP:
- if (sce->val4) {
- int tid = sce->val4;
- struct block_list *tbl = map_id2bl(tid);
- struct status_change *tsc = status_get_sc(tbl);
- sce->val4 = 0;
- if (tbl && tsc && tsc->data[SC_BLADESTOP]) {
- tsc->data[SC_BLADESTOP]->val4 = 0;
- status_change_end(tbl, SC_BLADESTOP, INVALID_TIMER);
- }
- clif_bladestop(bl, tid, 0);
- }
- break;
- case SC_DANCING: {
- const char *prevfile = "<unknown>";
- int prevline = 0;
- struct map_session_data *dsd;
- struct status_change_entry *dsc;
- struct skill_unit_group *group;
-
- if (sd) {
- if (sd->delunit_prevfile) {
- // initially this is NULL, when a character logs in
- prevfile = sd->delunit_prevfile;
- prevline = sd->delunit_prevline;
- } else {
- prevfile = "<none>";
- }
- sd->delunit_prevfile = file;
- sd->delunit_prevline = line;
- }
-
- if (sce->val4 && sce->val4 != BCT_SELF && (dsd=map_id2sd(sce->val4))) {
- // end status on partner as well
- dsc = dsd->sc.data[SC_DANCING];
- if (dsc) {
-
- //This will prevent recursive loops.
- dsc->val2 = dsc->val4 = 0;
-
- status_change_end(&dsd->bl, SC_DANCING, INVALID_TIMER);
- }
- }
-
- if (sce->val2) {
- // erase associated land skill
- group = skill_id2group(sce->val2);
-
- if (group == NULL) {
- ShowDebug("status_change_end: SC_DANCING is missing skill unit group (val1=%d, val2=%d, val3=%d, val4=%d, timer=%d, tid=%d, char_id=%d, map=%s, x=%d, y=%d, prev=%s:%d, from=%s:%d). Please report this! (#3504)\n",
- sce->val1, sce->val2, sce->val3, sce->val4, sce->timer, tid,
- sd ? sd->status.char_id : 0,
- mapindex_id2name(map_id2index(bl->m)), bl->x, bl->y,
- prevfile, prevline,
- file, line);
- }
-
- sce->val2 = 0;
- skill_delunitgroup(group);
- }
-
- if ((sce->val1&0xFFFF) == CG_MOONLIT)
- clif_status_change(bl,SI_MOONLIT,0,0,0,0,0);
-
- status_change_end(bl, SC_LONGING, INVALID_TIMER);
- }
- break;
- case SC_NOCHAT:
- if (sd && sd->status.manner < 0 && tid != INVALID_TIMER)
- sd->status.manner = 0;
- if (sd && tid == INVALID_TIMER) {
- clif_changestatus(sd,SP_MANNER,sd->status.manner);
- clif_updatestatus(sd,SP_MANNER);
- }
- break;
- case SC_SPLASHER: {
- struct block_list *src=map_id2bl(sce->val3);
- if (src && tid != INVALID_TIMER)
- skill_castend_damage_id(src, bl, sce->val2, sce->val1, gettick(), SD_LEVEL);
- }
- break;
- case SC_CLOSECONFINE2: {
- struct block_list *src = sce->val2?map_id2bl(sce->val2):NULL;
- struct status_change *sc2 = src?status_get_sc(src):NULL;
- if (src && sc2 && sc2->data[SC_CLOSECONFINE]) {
- //If status was already ended, do nothing.
- //Decrease count
- if (--(sc2->data[SC_CLOSECONFINE]->val1) <= 0) //No more holds, free him up.
- status_change_end(src, SC_CLOSECONFINE, INVALID_TIMER);
- }
- }
- case SC_CLOSECONFINE:
- if (sce->val2 > 0) {
- //Caster has been unlocked... nearby chars need to be unlocked.
- int range = 1
- +skill_get_range2(bl, status_sc2skill(type), sce->val1)
- +skill_get_range2(bl, TF_BACKSLIDING, 1); //Since most people use this to escape the hold....
- map_foreachinarea(status_change_timer_sub,
- bl->m, bl->x-range, bl->y-range, bl->x+range,bl->y+range,BL_CHAR,bl,sce,type,gettick());
- }
- break;
- case SC_COMBO:
- if (sd)
- switch (sce->val1) {
- case MO_COMBOFINISH:
- case CH_TIGERFIST:
- case CH_CHAINCRUSH:
- clif_skillinfo(sd, MO_EXTREMITYFIST, 0);
- break;
- case TK_JUMPKICK:
- clif_skillinfo(sd, TK_JUMPKICK, 0);
- break;
- case MO_TRIPLEATTACK:
- if (pc_checkskill(sd, SR_DRAGONCOMBO) > 0)
- clif_skillinfo(sd, SR_DRAGONCOMBO, 0);
- break;
- case SR_FALLENEMPIRE:
- clif_skillinfo(sd, SR_GATEOFHELL, 0);
- clif_skillinfo(sd, SR_TIGERCANNON, 0);
- break;
- }
- break;
-
- case SC_MARIONETTE:
- case SC_MARIONETTE2: /// Marionette target
- if (sce->val1) {
- // check for partner and end their marionette status as well
- enum sc_type type2 = (type == SC_MARIONETTE) ? SC_MARIONETTE2 : SC_MARIONETTE;
- struct block_list *pbl = map_id2bl(sce->val1);
- struct status_change *sc2 = pbl?status_get_sc(pbl):NULL;
-
- if (sc2 && sc2->data[type2]) {
- sc2->data[type2]->val1 = 0;
- status_change_end(pbl, type2, INVALID_TIMER);
- }
- }
- break;
-
- case SC_BERSERK:
- case SC_SATURDAYNIGHTFEVER:
- //If val2 is removed, no HP penalty (dispelled?) [Skotlex]
- if (status->hp > 100 && sce->val2)
- status_set_hp(bl, 100, 0);
- if (sc->data[SC_ENDURE] && sc->data[SC_ENDURE]->val4 == 2) {
- sc->data[SC_ENDURE]->val4 = 0;
- status_change_end(bl, SC_ENDURE, INVALID_TIMER);
- }
- case SC__BLOODYLUST:
- sc_start4(bl, SC_REGENERATION, 100, 10,0,0,(RGN_HP|RGN_SP), skill_get_time(LK_BERSERK, sce->val1));
- if (type == SC_SATURDAYNIGHTFEVER) //Sit down force of Saturday Night Fever has the duration of only 3 seconds.
- sc_start(bl,SC_SITDOWN_FORCE,100,sce->val1,skill_get_time2(WM_SATURDAY_NIGHT_FEVER,sce->val1));
- break;
- case SC_GOSPEL:
- if (sce->val3) { //Clear the group.
- struct skill_unit_group *group = skill_id2group(sce->val3);
- sce->val3 = 0;
- skill_delunitgroup(group);
- }
- break;
- case SC_HERMODE:
- if (sce->val3 == BCT_SELF)
- skill_clear_unitgroup(bl);
- break;
- case SC_BASILICA: //Clear the skill area. [Skotlex]
- skill_clear_unitgroup(bl);
- break;
- case SC_TRICKDEAD:
- if (vd) vd->dead_sit = 0;
- break;
- case SC_WARM:
- case SC__MANHOLE:
- if (sce->val4) { //Clear the group.
- struct skill_unit_group *group = skill_id2group(sce->val4);
- sce->val4 = 0;
- if (group) /* might have been cleared before status ended, e.g. land protector */
- skill_delunitgroup(group);
- }
- break;
- case SC_KAAHI:
- //Delete timer if it exists.
- if (sce->val4 != INVALID_TIMER)
- delete_timer(sce->val4,kaahi_heal_timer);
- break;
- case SC_JAILED:
- if (tid == INVALID_TIMER)
- break;
- //natural expiration.
- if (sd && sd->mapindex == sce->val2)
- pc_setpos(sd,(unsigned short)sce->val3,sce->val4&0xFFFF, sce->val4>>16, CLR_TELEPORT);
- break; //guess hes not in jail :P
- case SC_CHANGE:
- if (tid == INVALID_TIMER)
- break;
- // "lose almost all their HP and SP" on natural expiration.
- status_set_hp(bl, 10, 0);
- status_set_sp(bl, 10, 0);
- break;
- case SC_AUTOTRADE:
- if (tid == INVALID_TIMER)
- break;
- // Note: vending/buying is closed by unit_remove_map, no
- // need to do it here.
- map_quit(sd);
- // Because map_quit calls status_change_end with tid -1
- // from here it's not neccesary to continue
- return 1;
- break;
- case SC_STOP:
- if (sce->val2) {
- struct block_list *tbl = map_id2bl(sce->val2);
- sce->val2 = 0;
- if (tbl && (sc = status_get_sc(tbl)) && sc->data[SC_STOP] && sc->data[SC_STOP]->val2 == bl->id)
- status_change_end(tbl, SC_STOP, INVALID_TIMER);
- }
- break;
- /**
- * 3rd Stuff
- **/
- case SC_MILLENNIUMSHIELD:
- clif_millenniumshield(sd,0);
- break;
- case SC_HALLUCINATIONWALK:
- sc_start(bl,SC_HALLUCINATIONWALK_POSTDELAY,100,sce->val1,skill_get_time2(GC_HALLUCINATIONWALK,sce->val1));
- break;
- case SC_WHITEIMPRISON:
- if (tid == -1)
- break; // Terminated by Damage
- status_fix_damage(bl,bl,400*sce->val1,clif_damage(bl,bl,gettick(),0,0,400*sce->val1,0,0,0));
- break;
- case SC_WUGDASH: {
- struct unit_data *ud = unit_bl2ud(bl);
- if (ud) {
- ud->state.running = 0;
- if (ud->walktimer != -1)
- unit_stop_walking(bl,1);
- }
- }
- break;
- case SC_ADORAMUS:
- status_change_end(bl, SC_BLIND, INVALID_TIMER);
- break;
- case SC__SHADOWFORM: {
- struct map_session_data *s_sd = map_id2sd(sce->val2);
- if (!s_sd)
- break;
- s_sd->shadowform_id = 0;
- }
- break;
- case SC_SITDOWN_FORCE:
- if (sd && pc_issit(sd)) {
- pc_setstand(sd);
- clif_standing(bl);
- }
- break;
- case SC_NEUTRALBARRIER_MASTER:
- case SC_STEALTHFIELD_MASTER:
- if (sce->val2) {
- struct skill_unit_group *group = skill_id2group(sce->val2);
- sce->val2 = 0;
- if (group) /* might have been cleared before status ended, e.g. land protector */
- skill_delunitgroup(group);
- }
- break;
- case SC_BANDING:
- if (sce->val4) {
- struct skill_unit_group *group = skill_id2group(sce->val4);
- sce->val4 = 0;
- if (group) /* might have been cleared before status ended, e.g. land protector */
- skill_delunitgroup(group);
- }
- break;
- case SC_CURSEDCIRCLE_ATKER:
- if (sce->val2) // used the default area size cause there is a chance the caster could knock back and can't clear the target.
- map_foreachinrange(status_change_timer_sub, bl, battle_config.area_size,BL_CHAR, bl, sce, SC_CURSEDCIRCLE_TARGET, gettick());
- break;
- case SC_RAISINGDRAGON:
- if (sd && sce->val2 && !pc_isdead(sd)) {
- int i;
- i = min(sd->spiritball,5);
- pc_delspiritball(sd, sd->spiritball, 0);
- status_change_end(bl, SC_EXPLOSIONSPIRITS, INVALID_TIMER);
- while (i > 0) {
- pc_addspiritball(sd, skill_get_time(MO_CALLSPIRITS, pc_checkskill(sd,MO_CALLSPIRITS)), 5);
- --i;
- }
- }
- break;
- case SC_CURSEDCIRCLE_TARGET: {
- struct block_list *src = map_id2bl(sce->val2);
- struct status_change *sc = status_get_sc(src);
- if (sc && sc->data[SC_CURSEDCIRCLE_ATKER] && --(sc->data[SC_CURSEDCIRCLE_ATKER]->val2) == 0) {
- status_change_end(src, SC_CURSEDCIRCLE_ATKER, INVALID_TIMER);
- clif_bladestop(bl, sce->val2, 0);
- }
- }
- break;
- case SC_BLOODSUCKER:
- if (sce->val2) {
- struct block_list *src = map_id2bl(sce->val2);
- if (src) {
- struct status_change *sc = status_get_sc(src);
- sc->bs_counter--;
- }
- }
- break;
- case SC_VACUUM_EXTREME:
- if (sc && sc->cant.move > 0) sc->cant.move--;
- break;
- case SC_KYOUGAKU:
- clif_status_load(bl, SI_KYOUGAKU, 0); // Avoid client crash
- clif_status_load(bl, SI_ACTIVE_MONSTER_TRANSFORM, 0);
- break;
- case SC_INTRAVISION:
- calc_flag = SCB_ALL;/* required for overlapping */
- break;
- }
-
- opt_flag = 1;
- switch (type) {
- case SC_STONE:
- case SC_FREEZE:
- case SC_STUN:
- case SC_SLEEP:
- case SC_DEEPSLEEP:
- case SC_BURNING:
- case SC_WHITEIMPRISON:
- case SC_CRYSTALIZE:
- sc->opt1 = 0;
- break;
-
- case SC_POISON:
- case SC_CURSE:
- case SC_SILENCE:
- case SC_BLIND:
- sc->opt2 &= ~(1<<(type-SC_POISON));
- break;
- case SC_DPOISON:
- sc->opt2 &= ~OPT2_DPOISON;
- break;
- case SC_SIGNUMCRUCIS:
- sc->opt2 &= ~OPT2_SIGNUMCRUCIS;
- break;
-
- case SC_HIDING:
- sc->option &= ~OPTION_HIDE;
- opt_flag|= 2|4; //Check for warp trigger + AoE trigger
- break;
- case SC_CLOAKING:
- case SC_CLOAKINGEXCEED:
- case SC__INVISIBILITY:
- sc->option &= ~OPTION_CLOAK;
- case SC_CAMOUFLAGE:
- opt_flag|= 2;
- break;
- case SC_CHASEWALK:
- sc->option &= ~(OPTION_CHASEWALK|OPTION_CLOAK);
- opt_flag|= 2;
- break;
- case SC_SIGHT:
- sc->option &= ~OPTION_SIGHT;
- break;
- case SC_WEDDING:
- sc->option &= ~OPTION_WEDDING;
- break;
- case SC_XMAS:
- sc->option &= ~OPTION_XMAS;
- break;
- case SC_SUMMER:
- sc->option &= ~OPTION_SUMMER;
- break;
- case SC_ORCISH:
- sc->option &= ~OPTION_ORCISH;
- break;
- case SC_RUWACH:
- sc->option &= ~OPTION_RUWACH;
- break;
- case SC_FUSION:
- sc->option &= ~OPTION_FLYING;
- break;
- //opt3
- case SC_TWOHANDQUICKEN:
- case SC_ONEHAND:
- case SC_SPEARQUICKEN:
- case SC_CONCENTRATION:
- case SC_MERC_QUICKEN:
- sc->opt3 &= ~OPT3_QUICKEN;
- opt_flag = 0;
- break;
- case SC_OVERTHRUST:
- case SC_MAXOVERTHRUST:
- case SC_SWOO:
- sc->opt3 &= ~OPT3_OVERTHRUST;
- if (type == SC_SWOO)
- opt_flag = 8;
- else
- opt_flag = 0;
- break;
- case SC_ENERGYCOAT:
- case SC_SKE:
- sc->opt3 &= ~OPT3_ENERGYCOAT;
- opt_flag = 0;
- break;
- case SC_INCATKRATE: //Simulated Explosion spirits effect.
- if (bl->type != BL_MOB) {
- opt_flag = 0;
- break;
- }
- case SC_EXPLOSIONSPIRITS:
- sc->opt3 &= ~OPT3_EXPLOSIONSPIRITS;
- opt_flag = 0;
- break;
- case SC_STEELBODY:
- case SC_SKA:
- sc->opt3 &= ~OPT3_STEELBODY;
- opt_flag = 0;
- break;
- case SC_BLADESTOP:
- sc->opt3 &= ~OPT3_BLADESTOP;
- opt_flag = 0;
- break;
- case SC_AURABLADE:
- sc->opt3 &= ~OPT3_AURABLADE;
- opt_flag = 0;
- break;
- case SC_BERSERK:
- opt_flag = 0;
- // case SC__BLOODYLUST:
- sc->opt3 &= ~OPT3_BERSERK;
- break;
- // case ???: // doesn't seem to do anything
- // sc->opt3 &= ~OPT3_LIGHTBLADE;
- // opt_flag = 0;
- // break;
- case SC_DANCING:
- if ((sce->val1&0xFFFF) == CG_MOONLIT)
- sc->opt3 &= ~OPT3_MOONLIT;
- opt_flag = 0;
- break;
- case SC_MARIONETTE:
- case SC_MARIONETTE2:
- sc->opt3 &= ~OPT3_MARIONETTE;
- opt_flag = 0;
- break;
- case SC_ASSUMPTIO:
- sc->opt3 &= ~OPT3_ASSUMPTIO;
- opt_flag = 0;
- break;
- case SC_WARM: //SG skills [Komurka]
- sc->opt3 &= ~OPT3_WARM;
- opt_flag = 0;
- break;
- case SC_KAITE:
- sc->opt3 &= ~OPT3_KAITE;
- opt_flag = 0;
- break;
- case SC_BUNSINJYUTSU:
- sc->opt3 &= ~OPT3_BUNSIN;
- opt_flag = 0;
- break;
- case SC_SPIRIT:
- sc->opt3 &= ~OPT3_SOULLINK;
- opt_flag = 0;
- break;
- case SC_CHANGEUNDEAD:
- sc->opt3 &= ~OPT3_UNDEAD;
- opt_flag = 0;
- break;
- // case ???: // from DA_CONTRACT (looks like biolab mobs aura)
- // sc->opt3 &= ~OPT3_CONTRACT;
- // opt_flag = 0;
- // break;
- default:
- opt_flag = 0;
- }
-
- if (calc_flag&SCB_DYE) {
- //Restore DYE color
- if (vd && !vd->cloth_color && sce->val4)
- clif_changelook(bl,LOOK_CLOTHES_COLOR,sce->val4);
- calc_flag&=~SCB_DYE;
- }
-
- //On Aegis, when turning off a status change, first goes the sc packet, then the option packet.
- clif_status_change(bl,StatusIconChangeTable[type],0,0,0,0,0);
+ case SC_WEDDING:
+ case SC_XMAS:
+ case SC_SUMMER:
+ if (!vd) break;
+ if (sd)
+ { //Load data from sd->status.* as the stored values could have changed.
+ //Must remove OPTION to prevent class being rechanged.
+ sc->option &= type==SC_WEDDING?~OPTION_WEDDING:type==SC_XMAS?~OPTION_XMAS:~OPTION_SUMMER;
+ clif_changeoption(&sd->bl);
+ status_set_viewdata(bl, sd->status.class_);
+ } else {
+ vd->class_ = sce->val1;
+ vd->weapon = sce->val2;
+ vd->shield = sce->val3;
+ vd->cloth_color = sce->val4;
+ }
+ clif_changelook(bl,LOOK_BASE,vd->class_);
+ clif_changelook(bl,LOOK_CLOTHES_COLOR,vd->cloth_color);
+ clif_changelook(bl,LOOK_WEAPON,vd->weapon);
+ clif_changelook(bl,LOOK_SHIELD,vd->shield);
+ if(sd) clif_skillinfoblock(sd);
+ break;
+ case SC_RUN:
+ {
+ struct unit_data *ud = unit_bl2ud(bl);
+ bool begin_spurt = true;
+ if (ud) {
+ if(!ud->state.running)
+ begin_spurt = false;
+ ud->state.running = 0;
+ if (ud->walktimer != INVALID_TIMER)
+ unit_stop_walking(bl,1);
+ }
+ if (begin_spurt && sce->val1 >= 7 &&
+ DIFF_TICK(gettick(), sce->val4) <= 1000 &&
+ (!sd || (sd->weapontype1 == 0 && sd->weapontype2 == 0))
+ )
+ sc_start(bl,SC_SPURT,100,sce->val1,skill_get_time2(status_sc2skill(type), sce->val1));
+ }
+ break;
+ case SC_AUTOBERSERK:
+ if (sc->data[SC_PROVOKE] && sc->data[SC_PROVOKE]->val2 == 1)
+ status_change_end(bl, SC_PROVOKE, INVALID_TIMER);
+ break;
- if (opt_flag&8) //bugreport:681
- clif_changeoption2(bl);
- else if (opt_flag)
- clif_changeoption(bl);
+ case SC_ENDURE:
+ case SC_DEFENDER:
+ case SC_REFLECTSHIELD:
+ case SC_AUTOGUARD:
+ {
+ struct map_session_data *tsd;
+ if( bl->type == BL_PC )
+ { // Clear Status from others
+ int i;
+ for( i = 0; i < 5; i++ )
+ {
+ if( sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])) && tsd->sc.data[type] )
+ status_change_end(&tsd->bl, type, INVALID_TIMER);
+ }
+ }
+ else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag )
+ { // Clear Status from Master
+ tsd = ((TBL_MER*)bl)->master;
+ if( tsd && tsd->sc.data[type] )
+ status_change_end(&tsd->bl, type, INVALID_TIMER);
+ }
+ }
+ break;
+ case SC_DEVOTION:
+ {
+ struct block_list *d_bl = map_id2bl(sce->val1);
+ if( d_bl )
+ {
+ if( d_bl->type == BL_PC )
+ ((TBL_PC*)d_bl)->devotion[sce->val2] = 0;
+ else if( d_bl->type == BL_MER )
+ ((TBL_MER*)d_bl)->devotion_flag = 0;
+ clif_devotion(d_bl, NULL);
+ }
+
+ status_change_end(bl, SC_AUTOGUARD, INVALID_TIMER);
+ status_change_end(bl, SC_DEFENDER, INVALID_TIMER);
+ status_change_end(bl, SC_REFLECTSHIELD, INVALID_TIMER);
+ status_change_end(bl, SC_ENDURE, INVALID_TIMER);
+ }
+ break;
- if (calc_flag)
- status_calc_bl(bl,calc_flag);
+ case SC_BLADESTOP:
+ if(sce->val4)
+ {
+ int tid = sce->val4;
+ struct block_list *tbl = map_id2bl(tid);
+ struct status_change *tsc = status_get_sc(tbl);
+ sce->val4 = 0;
+ if(tbl && tsc && tsc->data[SC_BLADESTOP])
+ {
+ tsc->data[SC_BLADESTOP]->val4 = 0;
+ status_change_end(tbl, SC_BLADESTOP, INVALID_TIMER);
+ }
+ clif_bladestop(bl, tid, 0);
+ }
+ break;
+ case SC_DANCING:
+ {
+ const char* prevfile = "<unknown>";
+ int prevline = 0;
+ struct map_session_data *dsd;
+ struct status_change_entry *dsc;
+ struct skill_unit_group *group;
+
+ if( sd )
+ {
+ if( sd->delunit_prevfile )
+ {// initially this is NULL, when a character logs in
+ prevfile = sd->delunit_prevfile;
+ prevline = sd->delunit_prevline;
+ }
+ else
+ {
+ prevfile = "<none>";
+ }
+ sd->delunit_prevfile = file;
+ sd->delunit_prevline = line;
+ }
+
+ if(sce->val4 && sce->val4 != BCT_SELF && (dsd=map_id2sd(sce->val4)))
+ {// end status on partner as well
+ dsc = dsd->sc.data[SC_DANCING];
+ if(dsc) {
+
+ //This will prevent recursive loops.
+ dsc->val2 = dsc->val4 = 0;
+
+ status_change_end(&dsd->bl, SC_DANCING, INVALID_TIMER);
+ }
+ }
+
+ if(sce->val2)
+ {// erase associated land skill
+ group = skill_id2group(sce->val2);
+
+ if( group == NULL )
+ {
+ ShowDebug("status_change_end: SC_DANCING is missing skill unit group (val1=%d, val2=%d, val3=%d, val4=%d, timer=%d, tid=%d, char_id=%d, map=%s, x=%d, y=%d, prev=%s:%d, from=%s:%d). Please report this! (#3504)\n",
+ sce->val1, sce->val2, sce->val3, sce->val4, sce->timer, tid,
+ sd ? sd->status.char_id : 0,
+ mapindex_id2name(map_id2index(bl->m)), bl->x, bl->y,
+ prevfile, prevline,
+ file, line);
+ }
+
+ sce->val2 = 0;
+ skill_delunitgroup(group);
+ }
+
+ if((sce->val1&0xFFFF) == CG_MOONLIT)
+ clif_status_change(bl,SI_MOONLIT,0,0,0,0,0);
+
+ status_change_end(bl, SC_LONGING, INVALID_TIMER);
+ }
+ break;
+ case SC_NOCHAT:
+ if (sd && sd->status.manner < 0 && tid != INVALID_TIMER)
+ sd->status.manner = 0;
+ if (sd && tid == INVALID_TIMER)
+ {
+ clif_changestatus(sd,SP_MANNER,sd->status.manner);
+ clif_updatestatus(sd,SP_MANNER);
+ }
+ break;
+ case SC_SPLASHER:
+ {
+ struct block_list *src=map_id2bl(sce->val3);
+ if(src && tid != INVALID_TIMER)
+ skill_castend_damage_id(src, bl, sce->val2, sce->val1, gettick(), SD_LEVEL );
+ }
+ break;
+ case SC_CLOSECONFINE2:
+ {
+ struct block_list *src = sce->val2?map_id2bl(sce->val2):NULL;
+ struct status_change *sc2 = src?status_get_sc(src):NULL;
+ if (src && sc2 && sc2->data[SC_CLOSECONFINE]) {
+ //If status was already ended, do nothing.
+ //Decrease count
+ if (--(sc2->data[SC_CLOSECONFINE]->val1) <= 0) //No more holds, free him up.
+ status_change_end(src, SC_CLOSECONFINE, INVALID_TIMER);
+ }
+ }
+ case SC_CLOSECONFINE:
+ if (sce->val2 > 0) {
+ //Caster has been unlocked... nearby chars need to be unlocked.
+ int range = 1
+ +skill_get_range2(bl, status_sc2skill(type), sce->val1)
+ +skill_get_range2(bl, TF_BACKSLIDING, 1); //Since most people use this to escape the hold....
+ map_foreachinarea(status_change_timer_sub,
+ bl->m, bl->x-range, bl->y-range, bl->x+range,bl->y+range,BL_CHAR,bl,sce,type,gettick());
+ }
+ break;
+ case SC_COMBO:
+ if( sd )
+ switch (sce->val1) {
+ case MO_COMBOFINISH:
+ case CH_TIGERFIST:
+ case CH_CHAINCRUSH:
+ clif_skillinfo(sd, MO_EXTREMITYFIST, 0);
+ break;
+ case TK_JUMPKICK:
+ clif_skillinfo(sd, TK_JUMPKICK, 0);
+ break;
+ case MO_TRIPLEATTACK:
+ if (pc_checkskill(sd, SR_DRAGONCOMBO) > 0)
+ clif_skillinfo(sd, SR_DRAGONCOMBO, 0);
+ break;
+ case SR_FALLENEMPIRE:
+ clif_skillinfo(sd, SR_GATEOFHELL, 0);
+ clif_skillinfo(sd, SR_TIGERCANNON, 0);
+ break;
+ }
+ break;
- if (opt_flag&4) //Out of hiding, invoke on place.
- skill_unit_move(bl,gettick(),1);
+ case SC_MARIONETTE:
+ case SC_MARIONETTE2: /// Marionette target
+ if (sce->val1)
+ { // check for partner and end their marionette status as well
+ enum sc_type type2 = (type == SC_MARIONETTE) ? SC_MARIONETTE2 : SC_MARIONETTE;
+ struct block_list *pbl = map_id2bl(sce->val1);
+ struct status_change* sc2 = pbl?status_get_sc(pbl):NULL;
+
+ if (sc2 && sc2->data[type2])
+ {
+ sc2->data[type2]->val1 = 0;
+ status_change_end(pbl, type2, INVALID_TIMER);
+ }
+ }
+ break;
- if (opt_flag&2 && sd && map_getcell(bl->m,bl->x,bl->y,CELL_CHKNPC))
- npc_touch_areanpc(sd,bl->m,bl->x,bl->y); //Trigger on-touch event.
+ case SC_BERSERK:
+ case SC_SATURDAYNIGHTFEVER:
+ //If val2 is removed, no HP penalty (dispelled?) [Skotlex]
+ if (status->hp > 100 && sce->val2)
+ status_set_hp(bl, 100, 0);
+ if(sc->data[SC_ENDURE] && sc->data[SC_ENDURE]->val4 == 2)
+ {
+ sc->data[SC_ENDURE]->val4 = 0;
+ status_change_end(bl, SC_ENDURE, INVALID_TIMER);
+ }
+ case SC__BLOODYLUST:
+ sc_start4(bl, SC_REGENERATION, 100, 10,0,0,(RGN_HP|RGN_SP), skill_get_time(LK_BERSERK, sce->val1));
+ if( type == SC_SATURDAYNIGHTFEVER ) //Sit down force of Saturday Night Fever has the duration of only 3 seconds.
+ sc_start(bl,SC_SITDOWN_FORCE,100,sce->val1,skill_get_time2(WM_SATURDAY_NIGHT_FEVER,sce->val1));
+ break;
+ case SC_GOSPEL:
+ if (sce->val3) { //Clear the group.
+ struct skill_unit_group* group = skill_id2group(sce->val3);
+ sce->val3 = 0;
+ skill_delunitgroup(group);
+ }
+ break;
+ case SC_HERMODE:
+ if(sce->val3 == BCT_SELF)
+ skill_clear_unitgroup(bl);
+ break;
+ case SC_BASILICA: //Clear the skill area. [Skotlex]
+ skill_clear_unitgroup(bl);
+ break;
+ case SC_TRICKDEAD:
+ if (vd) vd->dead_sit = 0;
+ break;
+ case SC_WARM:
+ case SC__MANHOLE:
+ if (sce->val4) { //Clear the group.
+ struct skill_unit_group* group = skill_id2group(sce->val4);
+ sce->val4 = 0;
+ if( group ) /* might have been cleared before status ended, e.g. land protector */
+ skill_delunitgroup(group);
+ }
+ break;
+ case SC_KAAHI:
+ //Delete timer if it exists.
+ if (sce->val4 != INVALID_TIMER)
+ delete_timer(sce->val4,kaahi_heal_timer);
+ break;
+ case SC_JAILED:
+ if(tid == INVALID_TIMER)
+ break;
+ //natural expiration.
+ if(sd && sd->mapindex == sce->val2)
+ pc_setpos(sd,(unsigned short)sce->val3,sce->val4&0xFFFF, sce->val4>>16, CLR_TELEPORT);
+ break; //guess hes not in jail :P
+ case SC_CHANGE:
+ if (tid == INVALID_TIMER)
+ break;
+ // "lose almost all their HP and SP" on natural expiration.
+ status_set_hp(bl, 10, 0);
+ status_set_sp(bl, 10, 0);
+ break;
+ case SC_AUTOTRADE:
+ if (tid == INVALID_TIMER)
+ break;
+ // Note: vending/buying is closed by unit_remove_map, no
+ // need to do it here.
+ map_quit(sd);
+ // Because map_quit calls status_change_end with tid -1
+ // from here it's not neccesary to continue
+ return 1;
+ break;
+ case SC_STOP:
+ if( sce->val2 )
+ {
+ struct block_list* tbl = map_id2bl(sce->val2);
+ sce->val2 = 0;
+ if( tbl && (sc = status_get_sc(tbl)) && sc->data[SC_STOP] && sc->data[SC_STOP]->val2 == bl->id )
+ status_change_end(tbl, SC_STOP, INVALID_TIMER);
+ }
+ break;
+ /**
+ * 3rd Stuff
+ **/
+ case SC_MILLENNIUMSHIELD:
+ clif_millenniumshield(sd,0);
+ break;
+ case SC_HALLUCINATIONWALK:
+ sc_start(bl,SC_HALLUCINATIONWALK_POSTDELAY,100,sce->val1,skill_get_time2(GC_HALLUCINATIONWALK,sce->val1));
+ break;
+ case SC_WHITEIMPRISON:
+ if( tid == -1 )
+ break; // Terminated by Damage
+ status_fix_damage(bl,bl,400*sce->val1,clif_damage(bl,bl,gettick(),0,0,400*sce->val1,0,0,0));
+ break;
+ case SC_WUGDASH:
+ {
+ struct unit_data *ud = unit_bl2ud(bl);
+ if (ud) {
+ ud->state.running = 0;
+ if (ud->walktimer != -1)
+ unit_stop_walking(bl,1);
+ }
+ }
+ break;
+ case SC_ADORAMUS:
+ status_change_end(bl, SC_BLIND, INVALID_TIMER);
+ break;
+ case SC__SHADOWFORM: {
+ struct map_session_data *s_sd = map_id2sd(sce->val2);
+ if( !s_sd )
+ break;
+ s_sd->shadowform_id = 0;
+ }
+ break;
+ case SC_SITDOWN_FORCE:
+ if( sd && pc_issit(sd) ) {
+ pc_setstand(sd);
+ clif_standing(bl);
+ }
+ break;
+ case SC_NEUTRALBARRIER_MASTER:
+ case SC_STEALTHFIELD_MASTER:
+ if( sce->val2 ) {
+ struct skill_unit_group* group = skill_id2group(sce->val2);
+ sce->val2 = 0;
+ if( group ) /* might have been cleared before status ended, e.g. land protector */
+ skill_delunitgroup(group);
+ }
+ break;
+ case SC_BANDING:
+ if(sce->val4) {
+ struct skill_unit_group *group = skill_id2group(sce->val4);
+ sce->val4 = 0;
+ if( group ) /* might have been cleared before status ended, e.g. land protector */
+ skill_delunitgroup(group);
+ }
+ break;
+ case SC_CURSEDCIRCLE_ATKER:
+ if( sce->val2 ) // used the default area size cause there is a chance the caster could knock back and can't clear the target.
+ map_foreachinrange(status_change_timer_sub, bl, battle_config.area_size,BL_CHAR, bl, sce, SC_CURSEDCIRCLE_TARGET, gettick());
+ break;
+ case SC_RAISINGDRAGON:
+ if( sd && sce->val2 && !pc_isdead(sd) ) {
+ int i;
+ i = min(sd->spiritball,5);
+ pc_delspiritball(sd, sd->spiritball, 0);
+ status_change_end(bl, SC_EXPLOSIONSPIRITS, INVALID_TIMER);
+ while( i > 0 ) {
+ pc_addspiritball(sd, skill_get_time(MO_CALLSPIRITS, pc_checkskill(sd,MO_CALLSPIRITS)), 5);
+ --i;
+ }
+ }
+ break;
+ case SC_CURSEDCIRCLE_TARGET:
+ {
+ struct block_list *src = map_id2bl(sce->val2);
+ struct status_change *sc = status_get_sc(src);
+ if( sc && sc->data[SC_CURSEDCIRCLE_ATKER] && --(sc->data[SC_CURSEDCIRCLE_ATKER]->val2) == 0 ){
+ status_change_end(src, SC_CURSEDCIRCLE_ATKER, INVALID_TIMER);
+ clif_bladestop(bl, sce->val2, 0);
+ }
+ }
+ break;
+ case SC_BLOODSUCKER:
+ if( sce->val2 ){
+ struct block_list *src = map_id2bl(sce->val2);
+ if(src){
+ struct status_change *sc = status_get_sc(src);
+ sc->bs_counter--;
+ }
+ }
+ break;
+ case SC_VACUUM_EXTREME:
+ if(sc && sc->cant.move > 0) sc->cant.move--;
+ break;
+ case SC_KYOUGAKU:
+ clif_status_load(bl, SI_KYOUGAKU, 0); // Avoid client crash
+ clif_status_load(bl, SI_ACTIVE_MONSTER_TRANSFORM, 0);
+ break;
+ case SC_INTRAVISION:
+ calc_flag = SCB_ALL;/* required for overlapping */
+ break;
+ }
- ers_free(sc_data_ers, sce);
- return 1;
+ opt_flag = 1;
+ switch(type){
+ case SC_STONE:
+ case SC_FREEZE:
+ case SC_STUN:
+ case SC_SLEEP:
+ case SC_DEEPSLEEP:
+ case SC_BURNING:
+ case SC_WHITEIMPRISON:
+ case SC_CRYSTALIZE:
+ sc->opt1 = 0;
+ break;
+
+ case SC_POISON:
+ case SC_CURSE:
+ case SC_SILENCE:
+ case SC_BLIND:
+ sc->opt2 &= ~(1<<(type-SC_POISON));
+ break;
+ case SC_DPOISON:
+ sc->opt2 &= ~OPT2_DPOISON;
+ break;
+ case SC_SIGNUMCRUCIS:
+ sc->opt2 &= ~OPT2_SIGNUMCRUCIS;
+ break;
+
+ case SC_HIDING:
+ sc->option &= ~OPTION_HIDE;
+ opt_flag|= 2|4; //Check for warp trigger + AoE trigger
+ break;
+ case SC_CLOAKING:
+ case SC_CLOAKINGEXCEED:
+ case SC__INVISIBILITY:
+ sc->option &= ~OPTION_CLOAK;
+ case SC_CAMOUFLAGE:
+ opt_flag|= 2;
+ break;
+ case SC_CHASEWALK:
+ sc->option &= ~(OPTION_CHASEWALK|OPTION_CLOAK);
+ opt_flag|= 2;
+ break;
+ case SC_SIGHT:
+ sc->option &= ~OPTION_SIGHT;
+ break;
+ case SC_WEDDING:
+ sc->option &= ~OPTION_WEDDING;
+ break;
+ case SC_XMAS:
+ sc->option &= ~OPTION_XMAS;
+ break;
+ case SC_SUMMER:
+ sc->option &= ~OPTION_SUMMER;
+ break;
+ case SC_ORCISH:
+ sc->option &= ~OPTION_ORCISH;
+ break;
+ case SC_RUWACH:
+ sc->option &= ~OPTION_RUWACH;
+ break;
+ case SC_FUSION:
+ sc->option &= ~OPTION_FLYING;
+ break;
+ //opt3
+ case SC_TWOHANDQUICKEN:
+ case SC_ONEHAND:
+ case SC_SPEARQUICKEN:
+ case SC_CONCENTRATION:
+ case SC_MERC_QUICKEN:
+ sc->opt3 &= ~OPT3_QUICKEN;
+ opt_flag = 0;
+ break;
+ case SC_OVERTHRUST:
+ case SC_MAXOVERTHRUST:
+ case SC_SWOO:
+ sc->opt3 &= ~OPT3_OVERTHRUST;
+ if( type == SC_SWOO )
+ opt_flag = 8;
+ else
+ opt_flag = 0;
+ break;
+ case SC_ENERGYCOAT:
+ case SC_SKE:
+ sc->opt3 &= ~OPT3_ENERGYCOAT;
+ opt_flag = 0;
+ break;
+ case SC_INCATKRATE: //Simulated Explosion spirits effect.
+ if (bl->type != BL_MOB)
+ {
+ opt_flag = 0;
+ break;
+ }
+ case SC_EXPLOSIONSPIRITS:
+ sc->opt3 &= ~OPT3_EXPLOSIONSPIRITS;
+ opt_flag = 0;
+ break;
+ case SC_STEELBODY:
+ case SC_SKA:
+ sc->opt3 &= ~OPT3_STEELBODY;
+ opt_flag = 0;
+ break;
+ case SC_BLADESTOP:
+ sc->opt3 &= ~OPT3_BLADESTOP;
+ opt_flag = 0;
+ break;
+ case SC_AURABLADE:
+ sc->opt3 &= ~OPT3_AURABLADE;
+ opt_flag = 0;
+ break;
+ case SC_BERSERK:
+ opt_flag = 0;
+// case SC__BLOODYLUST:
+ sc->opt3 &= ~OPT3_BERSERK;
+ break;
+// case ???: // doesn't seem to do anything
+// sc->opt3 &= ~OPT3_LIGHTBLADE;
+// opt_flag = 0;
+// break;
+ case SC_DANCING:
+ if ((sce->val1&0xFFFF) == CG_MOONLIT)
+ sc->opt3 &= ~OPT3_MOONLIT;
+ opt_flag = 0;
+ break;
+ case SC_MARIONETTE:
+ case SC_MARIONETTE2:
+ sc->opt3 &= ~OPT3_MARIONETTE;
+ opt_flag = 0;
+ break;
+ case SC_ASSUMPTIO:
+ sc->opt3 &= ~OPT3_ASSUMPTIO;
+ opt_flag = 0;
+ break;
+ case SC_WARM: //SG skills [Komurka]
+ sc->opt3 &= ~OPT3_WARM;
+ opt_flag = 0;
+ break;
+ case SC_KAITE:
+ sc->opt3 &= ~OPT3_KAITE;
+ opt_flag = 0;
+ break;
+ case SC_BUNSINJYUTSU:
+ sc->opt3 &= ~OPT3_BUNSIN;
+ opt_flag = 0;
+ break;
+ case SC_SPIRIT:
+ sc->opt3 &= ~OPT3_SOULLINK;
+ opt_flag = 0;
+ break;
+ case SC_CHANGEUNDEAD:
+ sc->opt3 &= ~OPT3_UNDEAD;
+ opt_flag = 0;
+ break;
+// case ???: // from DA_CONTRACT (looks like biolab mobs aura)
+// sc->opt3 &= ~OPT3_CONTRACT;
+// opt_flag = 0;
+// break;
+ default:
+ opt_flag = 0;
+ }
+
+ if (calc_flag&SCB_DYE)
+ { //Restore DYE color
+ if (vd && !vd->cloth_color && sce->val4)
+ clif_changelook(bl,LOOK_CLOTHES_COLOR,sce->val4);
+ calc_flag&=~SCB_DYE;
+ }
+
+ //On Aegis, when turning off a status change, first goes the sc packet, then the option packet.
+ clif_status_change(bl,StatusIconChangeTable[type],0,0,0,0,0);
+
+ if( opt_flag&8 ) //bugreport:681
+ clif_changeoption2(bl);
+ else if(opt_flag)
+ clif_changeoption(bl);
+
+ if (calc_flag)
+ status_calc_bl(bl,calc_flag);
+
+ if(opt_flag&4) //Out of hiding, invoke on place.
+ skill_unit_move(bl,gettick(),1);
+
+ if(opt_flag&2 && sd && map_getcell(bl->m,bl->x,bl->y,CELL_CHKNPC))
+ npc_touch_areanpc(sd,bl->m,bl->x,bl->y); //Trigger on-touch event.
+
+ ers_free(sc_data_ers, sce);
+ return 1;
}
int kaahi_heal_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- struct block_list *bl;
- struct status_change *sc;
- struct status_change_entry *sce;
- struct status_data *status;
- int hp;
-
- if (!((bl=map_id2bl(id))&&
- (sc=status_get_sc(bl)) &&
- (sce = sc->data[SC_KAAHI])))
- return 0;
-
- if (sce->val4 != tid) {
- ShowError("kaahi_heal_timer: Timer mismatch: %d != %d\n", tid, sce->val4);
- sce->val4 = INVALID_TIMER;
- return 0;
- }
-
- status=status_get_status_data(bl);
- if (!status_charge(bl, 0, sce->val3)) {
- sce->val4 = INVALID_TIMER;
- return 0;
- }
-
- hp = status->max_hp - status->hp;
- if (hp > sce->val2)
- hp = sce->val2;
- if (hp)
- status_heal(bl, hp, 0, 2);
- sce->val4 = INVALID_TIMER;
- return 1;
+ struct block_list *bl;
+ struct status_change *sc;
+ struct status_change_entry *sce;
+ struct status_data *status;
+ int hp;
+
+ if(!((bl=map_id2bl(id))&&
+ (sc=status_get_sc(bl)) &&
+ (sce = sc->data[SC_KAAHI])))
+ return 0;
+
+ if(sce->val4 != tid) {
+ ShowError("kaahi_heal_timer: Timer mismatch: %d != %d\n", tid, sce->val4);
+ sce->val4 = INVALID_TIMER;
+ return 0;
+ }
+
+ status=status_get_status_data(bl);
+ if(!status_charge(bl, 0, sce->val3)) {
+ sce->val4 = INVALID_TIMER;
+ return 0;
+ }
+
+ hp = status->max_hp - status->hp;
+ if (hp > sce->val2)
+ hp = sce->val2;
+ if (hp)
+ status_heal(bl, hp, 0, 2);
+ sce->val4 = INVALID_TIMER;
+ return 1;
}
/*==========================================
@@ -9747,1265 +9666,1299 @@ int kaahi_heal_timer(int tid, unsigned int tick, int id, intptr_t data)
*------------------------------------------*/
int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- enum sc_type type = (sc_type)data;
- struct block_list *bl;
- struct map_session_data *sd;
- struct status_data *status;
- struct status_change *sc;
- struct status_change_entry *sce;
-
- bl = map_id2bl(id);
- if (!bl) {
- ShowDebug("status_change_timer: Null pointer id: %d data: %d\n", id, data);
- return 0;
- }
- sc = status_get_sc(bl);
- status = status_get_status_data(bl);
-
- if (!(sc && (sce = sc->data[type]))) {
- ShowDebug("status_change_timer: Null pointer id: %d data: %d bl-type: %d\n", id, data, bl->type);
- return 0;
- }
-
- if (sce->timer != tid) {
- ShowError("status_change_timer: Mismatch for type %d: %d != %d (bl id %d)\n",type,tid,sce->timer, bl->id);
- return 0;
- }
-
- sd = BL_CAST(BL_PC, bl);
-
- // set the next timer of the sce (don't assume the status still exists)
+ enum sc_type type = (sc_type)data;
+ struct block_list *bl;
+ struct map_session_data *sd;
+ struct status_data *status;
+ struct status_change *sc;
+ struct status_change_entry *sce;
+
+ bl = map_id2bl(id);
+ if(!bl)
+ {
+ ShowDebug("status_change_timer: Null pointer id: %d data: %d\n", id, data);
+ return 0;
+ }
+ sc = status_get_sc(bl);
+ status = status_get_status_data(bl);
+
+ if(!(sc && (sce = sc->data[type])))
+ {
+ ShowDebug("status_change_timer: Null pointer id: %d data: %d bl-type: %d\n", id, data, bl->type);
+ return 0;
+ }
+
+ if( sce->timer != tid )
+ {
+ ShowError("status_change_timer: Mismatch for type %d: %d != %d (bl id %d)\n",type,tid,sce->timer, bl->id);
+ return 0;
+ }
+
+ sd = BL_CAST(BL_PC, bl);
+
+// set the next timer of the sce (don't assume the status still exists)
#define sc_timer_next(t,f,i,d) \
- if( (sce=sc->data[type]) ) \
- sce->timer = add_timer(t,f,i,d); \
- else \
- ShowError("status_change_timer: Unexpected NULL status change id: %d data: %d\n", id, data)
-
- switch (type) {
- case SC_MAXIMIZEPOWER:
- case SC_CLOAKING:
- if (!status_charge(bl, 0, 1))
- break; //Not enough SP to continue.
- sc_timer_next(sce->val2+tick, status_change_timer, bl->id, data);
- return 0;
-
- case SC_CHASEWALK:
- if (!status_charge(bl, 0, sce->val4))
- break; //Not enough SP to continue.
-
- if (!sc->data[SC_INCSTR]) {
- sc_start(bl, SC_INCSTR,100,1<<(sce->val1-1),
- (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_ROGUE?10:1) //SL bonus -> x10 duration
- *skill_get_time2(status_sc2skill(type),sce->val1));
- }
- sc_timer_next(sce->val2+tick, status_change_timer, bl->id, data);
- return 0;
- break;
-
- case SC_SKA:
- if (--(sce->val2)>0) {
- sce->val3 = rnd()%100; //Random defense.
- sc_timer_next(1000+tick, status_change_timer,bl->id, data);
- return 0;
- }
- break;
-
- case SC_HIDING:
- if (--(sce->val2)>0) {
-
- if (sce->val2 % sce->val4 == 0 && !status_charge(bl, 0, 1))
- break; //Fail if it's time to substract SP and there isn't.
-
- sc_timer_next(1000+tick, status_change_timer,bl->id, data);
- return 0;
- }
- break;
-
- case SC_SIGHT:
- case SC_RUWACH:
- case SC_SIGHTBLASTER:
- map_foreachinrange(status_change_timer_sub, bl, sce->val3, BL_CHAR, bl, sce, type, tick);
-
- if (--(sce->val2)>0) {
- sce->val4 += 250; // use for Shadow Form 2 seconds checking.
- sc_timer_next(250+tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
-
- case SC_PROVOKE:
- if (sce->val2) { //Auto-provoke (it is ended in status_heal)
- sc_timer_next(1000*60+tick,status_change_timer, bl->id, data);
- return 0;
- }
- break;
-
- case SC_STONE:
- if (sc->opt1 == OPT1_STONEWAIT && sce->val3) {
- sce->val4 = 0;
- unit_stop_walking(bl,1);
- unit_stop_attack(bl);
- sc->opt1 = OPT1_STONE;
- clif_changeoption(bl);
- sc_timer_next(1000+tick,status_change_timer, bl->id, data);
- status_calc_bl(bl, StatusChangeFlagTable[type]);
- return 0;
- }
- if (--(sce->val3) > 0) {
- if (++(sce->val4)%5 == 0 && status->hp > status->max_hp/4)
- status_percent_damage(NULL, bl, 1, 0, false);
- sc_timer_next(1000+tick,status_change_timer, bl->id, data);
- return 0;
- }
- break;
-
- case SC_POISON:
- if (status->hp <= max(status->max_hp>>2, sce->val4)) //Stop damaging after 25% HP left.
- break;
- case SC_DPOISON:
- if (--(sce->val3) > 0) {
- if (!sc->data[SC_SLOWPOISON]) {
- if (sce->val2 && bl->type == BL_MOB) {
- struct block_list *src = map_id2bl(sce->val2);
- if (src)
- mob_log_damage((TBL_MOB *)bl,src,sce->val4);
- }
- map_freeblock_lock();
- status_zap(bl, sce->val4, 0);
- if (sc->data[type]) { // Check if the status still last ( can be dead since then ).
- sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
- }
- map_freeblock_unlock();
- }
- return 0;
- }
- break;
-
- case SC_TENSIONRELAX:
- if (status->max_hp > status->hp && --(sce->val3) > 0) {
- sc_timer_next(sce->val4+tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
-
- case SC_KNOWLEDGE:
- if (!sd) break;
- if (bl->m == sd->feel_map[0].m ||
- bl->m == sd->feel_map[1].m ||
- bl->m == sd->feel_map[2].m) {
- //Timeout will be handled by pc_setpos
- sce->timer = INVALID_TIMER;
- return 0;
- }
- break;
-
- case SC_BLEEDING:
- if (--(sce->val4) >= 0) {
- int hp = rnd()%600 + 200;
- map_freeblock_lock();
- status_fix_damage(NULL, bl, sd||hp<status->hp?hp:status->hp-1, 1);
- if (sc->data[type]) {
- if (status->hp == 1) {
- map_freeblock_unlock();
- break;
- }
- sc_timer_next(10000 + tick, status_change_timer, bl->id, data);
- }
- map_freeblock_unlock();
- return 0;
- }
- break;
-
- case SC_S_LIFEPOTION:
- case SC_L_LIFEPOTION:
- if (sd && --(sce->val4) >= 0) {
- // val1 < 0 = per max% | val1 > 0 = exact amount
- int hp = 0;
- if (status->hp < status->max_hp)
- hp = (sce->val1 < 0) ? (int)(sd->status.max_hp * -1 * sce->val1 / 100.) : sce->val1 ;
- status_heal(bl, hp, 0, 2);
- sc_timer_next((sce->val2 * 1000) + tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
-
- case SC_BOSSMAPINFO:
- if (sd && --(sce->val4) >= 0) {
- struct mob_data *boss_md = map_id2boss(sce->val1);
- if (boss_md && sd->bl.m == boss_md->bl.m) {
- clif_bossmapinfo(sd->fd, boss_md, 1); // Update X - Y on minimap
- if (boss_md->bl.prev != NULL) {
- sc_timer_next(5000 + tick, status_change_timer, bl->id, data);
- return 0;
- }
- }
- }
- break;
-
- case SC_DANCING: { //SP consumption by time of dancing skills
- int s = 0;
- int sp = 1;
- if (--sce->val3 <= 0)
- break;
- switch (sce->val1&0xFFFF) {
- case BD_RICHMANKIM:
- case BD_DRUMBATTLEFIELD:
- case BD_RINGNIBELUNGEN:
- case BD_SIEGFRIED:
- case BA_DISSONANCE:
- case BA_ASSASSINCROSS:
- case DC_UGLYDANCE:
- s=3;
- break;
- case BD_LULLABY:
- case BD_ETERNALCHAOS:
- case BD_ROKISWEIL:
- case DC_FORTUNEKISS:
- s=4;
- break;
- case CG_HERMODE:
- case BD_INTOABYSS:
- case BA_WHISTLE:
- case DC_HUMMING:
- case BA_POEMBRAGI:
- case DC_SERVICEFORYOU:
- s=5;
- break;
- case BA_APPLEIDUN:
-#ifdef RENEWAL
- s=5;
-#else
- s=6;
-#endif
- break;
- case CG_MOONLIT:
- //Moonlit's cost is 4sp*skill_lv [Skotlex]
- sp= 4*(sce->val1>>16);
- //Upkeep is also every 10 secs.
- case DC_DONTFORGETME:
- s=10;
- break;
- }
- if (s != 0 && sce->val3 % s == 0) {
- if (sc->data[SC_LONGING])
- sp*= 3;
- if (!status_charge(bl, 0, sp))
- break;
- }
- sc_timer_next(1000+tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
- case SC__BLOODYLUST:
- case SC_BERSERK:
- // 5% every 10 seconds [DracoRPG]
- if (--(sce->val3) > 0 && status_charge(bl, sce->val2, 0) && status->hp > 100) {
- sc_timer_next(sce->val4+tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
-
- case SC_NOCHAT:
- if (sd) {
- sd->status.manner++;
- clif_changestatus(sd,SP_MANNER,sd->status.manner);
- clif_updatestatus(sd,SP_MANNER);
- if (sd->status.manner < 0) {
- //Every 60 seconds your manner goes up by 1 until it gets back to 0.
- sc_timer_next(60000+tick, status_change_timer, bl->id, data);
- return 0;
- }
- }
- break;
-
- case SC_SPLASHER:
- // custom Venom Splasher countdown timer
- //if (sce->val4 % 1000 == 0) {
- // char timer[10];
- // snprintf (timer, 10, "%d", sce->val4/1000);
- // clif_message(bl, timer);
- //}
- if ((sce->val4 -= 500) > 0) {
- sc_timer_next(500 + tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
-
- case SC_MARIONETTE:
- case SC_MARIONETTE2: {
- struct block_list *pbl = map_id2bl(sce->val1);
- if (pbl && check_distance_bl(bl, pbl, 7)) {
- sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
- return 0;
- }
- }
- break;
-
- case SC_GOSPEL:
- if (sce->val4 == BCT_SELF && --(sce->val2) > 0) {
- int hp, sp;
- hp = (sce->val1 > 5) ? 45 : 30;
- sp = (sce->val1 > 5) ? 35 : 20;
- if (!status_charge(bl, hp, sp))
- break;
- sc_timer_next(10000+tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
-
- case SC_JAILED:
- if (sce->val1 == INT_MAX || --(sce->val1) > 0) {
- sc_timer_next(60000+tick, status_change_timer, bl->id,data);
- return 0;
- }
- break;
-
- case SC_BLIND:
- if (sc->data[SC_FOGWALL]) {
- //Blind lasts forever while you are standing on the fog.
- sc_timer_next(5000+tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
- case SC_ABUNDANCE:
- if (--(sce->val4) > 0) {
- status_heal(bl,0,60,0);
- sc_timer_next(10000+tick, status_change_timer, bl->id, data);
- }
- break;
-
- case SC_PYREXIA:
- if (--(sce->val4) >= 0) {
- map_freeblock_lock();
- clif_damage(bl,bl,tick,status_get_amotion(bl),status_get_dmotion(bl)+500,100,0,0,0);
- status_fix_damage(NULL,bl,100,0);
- if (sc->data[type]) {
- sc_timer_next(3000+tick,status_change_timer,bl->id,data);
- }
- map_freeblock_unlock();
- return 0;
- }
- break;
-
- case SC_LEECHESEND:
- if (--(sce->val4) >= 0) {
- int damage = status->max_hp/100; // {Target VIT x (New Poison Research Skill Level - 3)} + (Target HP/100)
- damage += status->vit * (sce->val1 - 3);
- unit_skillcastcancel(bl,2);
- map_freeblock_lock();
- status_damage(bl, bl, damage, 0, clif_damage(bl,bl,tick,status_get_amotion(bl),status_get_dmotion(bl)+500,damage,1,0,0), 1);
- if (sc->data[type]) {
- sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
- }
- map_freeblock_unlock();
- return 0;
- }
- break;
-
- case SC_MAGICMUSHROOM:
- if (--(sce->val4) >= 0) {
- bool flag = 0;
- int damage = status->max_hp * 3 / 100;
- if (status->hp <= damage)
- damage = status->hp - 1; // Cannot Kill
-
- if (damage > 0) { // 3% Damage each 4 seconds
- map_freeblock_lock();
- status_zap(bl,damage,0);
- flag = !sc->data[type]; // Killed? Should not
- map_freeblock_unlock();
- }
-
- if (!flag) { // Random Skill Cast
- if (sd && !pc_issit(sd)) { //can't cast if sit
- int mushroom_skillid = 0, i;
- unit_stop_attack(bl);
- unit_skillcastcancel(bl,1);
- do {
- i = rnd() % MAX_SKILL_MAGICMUSHROOM_DB;
- mushroom_skillid = skill_magicmushroom_db[i].skillid;
- } while (mushroom_skillid == 0);
-
- switch (skill_get_casttype(mushroom_skillid)) { // Magic Mushroom skills are buffs or area damage
- case CAST_GROUND:
- skill_castend_pos2(bl,bl->x,bl->y,mushroom_skillid,1,tick,0);
- break;
- case CAST_NODAMAGE:
- skill_castend_nodamage_id(bl,bl,mushroom_skillid,1,tick,0);
- break;
- case CAST_DAMAGE:
- skill_castend_damage_id(bl,bl,mushroom_skillid,1,tick,0);
- break;
- }
- }
-
- clif_emotion(bl,E_HEH);
- sc_timer_next(4000+tick,status_change_timer,bl->id,data);
- }
- return 0;
- }
- break;
-
- case SC_TOXIN:
- if (--(sce->val4) >= 0) {
- //Damage is every 10 seconds including 3%sp drain.
- map_freeblock_lock();
- clif_damage(bl,bl,tick,status_get_amotion(bl),1,1,0,0,0);
- status_damage(NULL, bl, 1, status->max_sp * 3 / 100, 0, 0); //cancel dmg only if cancelable
- if (sc->data[type]) {
- sc_timer_next(10000 + tick, status_change_timer, bl->id, data);
- }
- map_freeblock_unlock();
- return 0;
- }
- break;
+ if( (sce=sc->data[type]) ) \
+ sce->timer = add_timer(t,f,i,d); \
+ else \
+ ShowError("status_change_timer: Unexpected NULL status change id: %d data: %d\n", id, data)
+
+ switch(type)
+ {
+ case SC_MAXIMIZEPOWER:
+ case SC_CLOAKING:
+ if(!status_charge(bl, 0, 1))
+ break; //Not enough SP to continue.
+ sc_timer_next(sce->val2+tick, status_change_timer, bl->id, data);
+ return 0;
+
+ case SC_CHASEWALK:
+ if(!status_charge(bl, 0, sce->val4))
+ break; //Not enough SP to continue.
+
+ if (!sc->data[SC_INCSTR]) {
+ sc_start(bl, SC_INCSTR,100,1<<(sce->val1-1),
+ (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_ROGUE?10:1) //SL bonus -> x10 duration
+ *skill_get_time2(status_sc2skill(type),sce->val1));
+ }
+ sc_timer_next(sce->val2+tick, status_change_timer, bl->id, data);
+ return 0;
+ break;
+
+ case SC_SKA:
+ if(--(sce->val2)>0){
+ sce->val3 = rnd()%100; //Random defense.
+ sc_timer_next(1000+tick, status_change_timer,bl->id, data);
+ return 0;
+ }
+ break;
- case SC_OBLIVIONCURSE:
- if (--(sce->val4) >= 0) {
- clif_emotion(bl,E_WHAT);
- sc_timer_next(3000 + tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
+ case SC_HIDING:
+ if(--(sce->val2)>0){
- case SC_WEAPONBLOCKING:
- if (--(sce->val4) >= 0) {
- if (!status_charge(bl,0,3))
- break;
- sc_timer_next(3000+tick,status_change_timer,bl->id,data);
- return 0;
- }
- break;
+ if(sce->val2 % sce->val4 == 0 && !status_charge(bl, 0, 1))
+ break; //Fail if it's time to substract SP and there isn't.
- case SC_CLOAKINGEXCEED:
- if (!status_charge(bl,0,10-sce->val1))
- break;
- sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
- return 0;
-
- case SC_RENOVATIO:
- if (--(sce->val4) >= 0) {
- int heal = status->max_hp * 3 / 100;
- if (sc && sc->data[SC_AKAITSUKI] && heal)
- heal = ~heal + 1;
- status_heal(bl, heal, 0, 2);
- sc_timer_next(5000 + tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
+ sc_timer_next(1000+tick, status_change_timer,bl->id, data);
+ return 0;
+ }
+ break;
- case SC_BURNING:
- if (--(sce->val4) >= 0) {
- struct block_list *src = map_id2bl(sce->val3);
- int damage = 1000 + 3 * status_get_max_hp(bl) / 100; // Deals fixed (1000 + 3%*MaxHP)
+ case SC_SIGHT:
+ case SC_RUWACH:
+ case SC_SIGHTBLASTER:
+ map_foreachinrange( status_change_timer_sub, bl, sce->val3, BL_CHAR, bl, sce, type, tick);
- map_freeblock_lock();
- clif_damage(bl,bl,tick,0,0,damage,1,9,0); //damage is like endure effect with no walk delay
- status_damage(src, bl, damage, 0, 0, 1);
+ if( --(sce->val2)>0 ){
+ sce->val4 += 250; // use for Shadow Form 2 seconds checking.
+ sc_timer_next(250+tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
- if (sc->data[type]) { // Target still lives. [LimitLine]
- sc_timer_next(2000 + tick, status_change_timer, bl->id, data);
- }
- map_freeblock_unlock();
- return 0;
- }
- break;
+ case SC_PROVOKE:
+ if(sce->val2) { //Auto-provoke (it is ended in status_heal)
+ sc_timer_next(1000*60+tick,status_change_timer, bl->id, data );
+ return 0;
+ }
+ break;
+
+ case SC_STONE:
+ if(sc->opt1 == OPT1_STONEWAIT && sce->val3) {
+ sce->val4 = 0;
+ unit_stop_walking(bl,1);
+ unit_stop_attack(bl);
+ sc->opt1 = OPT1_STONE;
+ clif_changeoption(bl);
+ sc_timer_next(1000+tick,status_change_timer, bl->id, data );
+ status_calc_bl(bl, StatusChangeFlagTable[type]);
+ return 0;
+ }
+ if(--(sce->val3) > 0) {
+ if(++(sce->val4)%5 == 0 && status->hp > status->max_hp/4)
+ status_percent_damage(NULL, bl, 1, 0, false);
+ sc_timer_next(1000+tick,status_change_timer, bl->id, data );
+ return 0;
+ }
+ break;
- case SC_FEAR:
- if (--(sce->val4) >= 0) {
- if (sce->val2 > 0)
- sce->val2--;
- sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
+ case SC_POISON:
+ if(status->hp <= max(status->max_hp>>2, sce->val4)) //Stop damaging after 25% HP left.
+ break;
+ case SC_DPOISON:
+ if (--(sce->val3) > 0) {
+ if (!sc->data[SC_SLOWPOISON]) {
+ if( sce->val2 && bl->type == BL_MOB ) {
+ struct block_list* src = map_id2bl(sce->val2);
+ if( src )
+ mob_log_damage((TBL_MOB*)bl,src,sce->val4);
+ }
+ map_freeblock_lock();
+ status_zap(bl, sce->val4, 0);
+ if (sc->data[type]) { // Check if the status still last ( can be dead since then ).
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data );
+ }
+ map_freeblock_unlock();
+ }
+ return 0;
+ }
+ break;
- case SC_SPHERE_1:
- case SC_SPHERE_2:
- case SC_SPHERE_3:
- case SC_SPHERE_4:
- case SC_SPHERE_5:
- if (--(sce->val4) >= 0) {
- if (!status_charge(bl, 0, 1))
- break;
- sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
+ case SC_TENSIONRELAX:
+ if(status->max_hp > status->hp && --(sce->val3) > 0){
+ sc_timer_next(sce->val4+tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+
+ case SC_KNOWLEDGE:
+ if (!sd) break;
+ if(bl->m == sd->feel_map[0].m ||
+ bl->m == sd->feel_map[1].m ||
+ bl->m == sd->feel_map[2].m)
+ { //Timeout will be handled by pc_setpos
+ sce->timer = INVALID_TIMER;
+ return 0;
+ }
+ break;
+
+ case SC_BLEEDING:
+ if (--(sce->val4) >= 0) {
+ int hp = rnd()%600 + 200;
+ map_freeblock_lock();
+ status_fix_damage(NULL, bl, sd||hp<status->hp?hp:status->hp-1, 1);
+ if( sc->data[type] ) {
+ if( status->hp == 1 ) {
+ map_freeblock_unlock();
+ break;
+ }
+ sc_timer_next(10000 + tick, status_change_timer, bl->id, data);
+ }
+ map_freeblock_unlock();
+ return 0;
+ }
+ break;
+
+ case SC_S_LIFEPOTION:
+ case SC_L_LIFEPOTION:
+ if( sd && --(sce->val4) >= 0 )
+ {
+ // val1 < 0 = per max% | val1 > 0 = exact amount
+ int hp = 0;
+ if( status->hp < status->max_hp )
+ hp = (sce->val1 < 0) ? (int)(sd->status.max_hp * -1 * sce->val1 / 100.) : sce->val1 ;
+ status_heal(bl, hp, 0, 2);
+ sc_timer_next((sce->val2 * 1000) + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+
+ case SC_BOSSMAPINFO:
+ if( sd && --(sce->val4) >= 0 )
+ {
+ struct mob_data *boss_md = map_id2boss(sce->val1);
+ if( boss_md && sd->bl.m == boss_md->bl.m )
+ {
+ clif_bossmapinfo(sd->fd, boss_md, 1); // Update X - Y on minimap
+ if (boss_md->bl.prev != NULL) {
+ sc_timer_next(5000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ }
+ }
+ break;
- case SC_READING_SB:
- if (!status_charge(bl, 0, sce->val2)) {
- int i;
- for (i = SC_SPELLBOOK1; i <= SC_MAXSPELLBOOK; i++) // Also remove stored spell as well.
- status_change_end(bl, (sc_type)i, INVALID_TIMER);
- break;
- }
- sc_timer_next(5000 + tick, status_change_timer, bl->id, data);
- return 0;
+ case SC_DANCING: //SP consumption by time of dancing skills
+ {
+ int s = 0;
+ int sp = 1;
+ if (--sce->val3 <= 0)
+ break;
+ switch(sce->val1&0xFFFF){
+ case BD_RICHMANKIM:
+ case BD_DRUMBATTLEFIELD:
+ case BD_RINGNIBELUNGEN:
+ case BD_SIEGFRIED:
+ case BA_DISSONANCE:
+ case BA_ASSASSINCROSS:
+ case DC_UGLYDANCE:
+ s=3;
+ break;
+ case BD_LULLABY:
+ case BD_ETERNALCHAOS:
+ case BD_ROKISWEIL:
+ case DC_FORTUNEKISS:
+ s=4;
+ break;
+ case CG_HERMODE:
+ case BD_INTOABYSS:
+ case BA_WHISTLE:
+ case DC_HUMMING:
+ case BA_POEMBRAGI:
+ case DC_SERVICEFORYOU:
+ s=5;
+ break;
+ case BA_APPLEIDUN:
+ #ifdef RENEWAL
+ s=5;
+ #else
+ s=6;
+ #endif
+ break;
+ case CG_MOONLIT:
+ //Moonlit's cost is 4sp*skill_lv [Skotlex]
+ sp= 4*(sce->val1>>16);
+ //Upkeep is also every 10 secs.
+ case DC_DONTFORGETME:
+ s=10;
+ break;
+ }
+ if( s != 0 && sce->val3 % s == 0 )
+ {
+ if (sc->data[SC_LONGING])
+ sp*= 3;
+ if (!status_charge(bl, 0, sp))
+ break;
+ }
+ sc_timer_next(1000+tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+ case SC__BLOODYLUST:
+ case SC_BERSERK:
+ // 5% every 10 seconds [DracoRPG]
+ if( --( sce->val3 ) > 0 && status_charge(bl, sce->val2, 0) && status->hp > 100 )
+ {
+ sc_timer_next(sce->val4+tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+
+ case SC_NOCHAT:
+ if(sd){
+ sd->status.manner++;
+ clif_changestatus(sd,SP_MANNER,sd->status.manner);
+ clif_updatestatus(sd,SP_MANNER);
+ if (sd->status.manner < 0)
+ { //Every 60 seconds your manner goes up by 1 until it gets back to 0.
+ sc_timer_next(60000+tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ }
+ break;
+
+ case SC_SPLASHER:
+ // custom Venom Splasher countdown timer
+ //if (sce->val4 % 1000 == 0) {
+ // char timer[10];
+ // snprintf (timer, 10, "%d", sce->val4/1000);
+ // clif_message(bl, timer);
+ //}
+ if((sce->val4 -= 500) > 0) {
+ sc_timer_next(500 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+
+ case SC_MARIONETTE:
+ case SC_MARIONETTE2:
+ {
+ struct block_list *pbl = map_id2bl(sce->val1);
+ if( pbl && check_distance_bl(bl, pbl, 7) )
+ {
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ }
+ break;
+
+ case SC_GOSPEL:
+ if(sce->val4 == BCT_SELF && --(sce->val2) > 0)
+ {
+ int hp, sp;
+ hp = (sce->val1 > 5) ? 45 : 30;
+ sp = (sce->val1 > 5) ? 35 : 20;
+ if(!status_charge(bl, hp, sp))
+ break;
+ sc_timer_next(10000+tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
- case SC_ELECTRICSHOCKER:
- if (--(sce->val4) >= 0) {
- status_charge(bl, 0, status->max_sp / 100 * sce->val1);
- sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
+ case SC_JAILED:
+ if(sce->val1 == INT_MAX || --(sce->val1) > 0)
+ {
+ sc_timer_next(60000+tick, status_change_timer, bl->id,data);
+ return 0;
+ }
+ break;
- case SC_CAMOUFLAGE:
- if (--(sce->val4) > 0) {
- status_charge(bl,0,7 - sce->val1);
- sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
+ case SC_BLIND:
+ if(sc->data[SC_FOGWALL])
+ { //Blind lasts forever while you are standing on the fog.
+ sc_timer_next(5000+tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+ case SC_ABUNDANCE:
+ if(--(sce->val4) > 0) {
+ status_heal(bl,0,60,0);
+ sc_timer_next(10000+tick, status_change_timer, bl->id, data);
+ }
+ break;
+
+ case SC_PYREXIA:
+ if( --(sce->val4) >= 0 ) {
+ map_freeblock_lock();
+ clif_damage(bl,bl,tick,status_get_amotion(bl),status_get_dmotion(bl)+500,100,0,0,0);
+ status_fix_damage(NULL,bl,100,0);
+ if( sc->data[type] ) {
+ sc_timer_next(3000+tick,status_change_timer,bl->id,data);
+ }
+ map_freeblock_unlock();
+ return 0;
+ }
+ break;
+
+ case SC_LEECHESEND:
+ if( --(sce->val4) >= 0 ) {
+ int damage = status->max_hp/100; // {Target VIT x (New Poison Research Skill Level - 3)} + (Target HP/100)
+ damage += status->vit * (sce->val1 - 3);
+ unit_skillcastcancel(bl,2);
+ map_freeblock_lock();
+ status_damage(bl, bl, damage, 0, clif_damage(bl,bl,tick,status_get_amotion(bl),status_get_dmotion(bl)+500,damage,1,0,0), 1);
+ if( sc->data[type] ) {
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data );
+ }
+ map_freeblock_unlock();
+ return 0;
+ }
+ break;
+
+ case SC_MAGICMUSHROOM:
+ if( --(sce->val4) >= 0 ) {
+ bool flag = 0;
+ int damage = status->max_hp * 3 / 100;
+ if( status->hp <= damage )
+ damage = status->hp - 1; // Cannot Kill
+
+ if( damage > 0 ) { // 3% Damage each 4 seconds
+ map_freeblock_lock();
+ status_zap(bl,damage,0);
+ flag = !sc->data[type]; // Killed? Should not
+ map_freeblock_unlock();
+ }
- case SC__REPRODUCE:
- if (!status_charge(bl, 0, 1))
- break;
- sc_timer_next(1000+tick, status_change_timer, bl->id, data);
- return 0;
-
- case SC__SHADOWFORM:
- if (--(sce->val4) >= 0) {
- if (!status_charge(bl, 0, sce->val1 - (sce->val1 - 1)))
- break;
- sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
+ if( !flag ) { // Random Skill Cast
+ if (sd && !pc_issit(sd)) { //can't cast if sit
+ int mushroom_skillid = 0, i;
+ unit_stop_attack(bl);
+ unit_skillcastcancel(bl,1);
+ do {
+ i = rnd() % MAX_SKILL_MAGICMUSHROOM_DB;
+ mushroom_skillid = skill_magicmushroom_db[i].skillid;
+ }
+ while( mushroom_skillid == 0 );
+
+ switch( skill_get_casttype(mushroom_skillid) ) { // Magic Mushroom skills are buffs or area damage
+ case CAST_GROUND:
+ skill_castend_pos2(bl,bl->x,bl->y,mushroom_skillid,1,tick,0);
+ break;
+ case CAST_NODAMAGE:
+ skill_castend_nodamage_id(bl,bl,mushroom_skillid,1,tick,0);
+ break;
+ case CAST_DAMAGE:
+ skill_castend_damage_id(bl,bl,mushroom_skillid,1,tick,0);
+ break;
+ }
+ }
+
+ clif_emotion(bl,E_HEH);
+ sc_timer_next(4000+tick,status_change_timer,bl->id,data);
+ }
+ return 0;
+ }
+ break;
+
+ case SC_TOXIN:
+ if( --(sce->val4) >= 0 )
+ { //Damage is every 10 seconds including 3%sp drain.
+ map_freeblock_lock();
+ clif_damage(bl,bl,tick,status_get_amotion(bl),1,1,0,0,0);
+ status_damage(NULL, bl, 1, status->max_sp * 3 / 100, 0, 0); //cancel dmg only if cancelable
+ if( sc->data[type] ) {
+ sc_timer_next(10000 + tick, status_change_timer, bl->id, data );
+ }
+ map_freeblock_unlock();
+ return 0;
+ }
+ break;
+
+ case SC_OBLIVIONCURSE:
+ if( --(sce->val4) >= 0 )
+ {
+ clif_emotion(bl,E_WHAT);
+ sc_timer_next(3000 + tick, status_change_timer, bl->id, data );
+ return 0;
+ }
+ break;
- case SC__INVISIBILITY:
- if (--(sce->val4) >= 0) {
- if (!status_charge(bl, 0, (status->sp * 6 - sce->val1) / 100)) // 6% - skilllv.
- break;
- sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
+ case SC_WEAPONBLOCKING:
+ if( --(sce->val4) >= 0 )
+ {
+ if( !status_charge(bl,0,3) )
+ break;
+ sc_timer_next(3000+tick,status_change_timer,bl->id,data);
+ return 0;
+ }
+ break;
- case SC_STRIKING:
- if (--(sce->val4) >= 0) {
- if (!status_charge(bl,0, sce->val1))
- break;
- sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
- case SC_VACUUM_EXTREME:
- if (--(sce->val4) >= 0) {
- if (!unit_is_walking(bl) && !sce->val2) {
- sc->cant.move++;
- sce->val2 = 1;
- }
- sc_timer_next(100 + tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
- case SC_BLOODSUCKER:
- if (--(sce->val4) >= 0) {
- struct block_list *src = map_id2bl(sce->val2);
- int damage;
- if (!src || (src && (status_isdead(src) || src->m != bl->m || distance_bl(src, bl) >= 12)))
- break;
- map_freeblock_lock();
- damage = 200 + 100 * sce->val1 + status_get_int(src);
- status_damage(src, bl, damage, 0, clif_damage(bl,bl,tick,status->amotion,status->dmotion+200,damage,1,0,0), 1);
- unit_skillcastcancel(bl,1);
- if (sc->data[type]) {
- sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
- }
- map_freeblock_unlock();
- status_heal(src, damage*(5 + 5 * sce->val1)/100, 0, 0); // 5 + 5% per level
- return 0;
- }
- break;
+ case SC_CLOAKINGEXCEED:
+ if(!status_charge(bl,0,10-sce->val1))
+ break;
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ return 0;
+
+ case SC_RENOVATIO:
+ if( --(sce->val4) >= 0 )
+ {
+ int heal = status->max_hp * 3 / 100;
+ if( sc && sc->data[SC_AKAITSUKI] && heal )
+ heal = ~heal + 1;
+ status_heal(bl, heal, 0, 2);
+ sc_timer_next(5000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
- case SC_VOICEOFSIREN:
- if (--(sce->val4) >= 0) {
- clif_emotion(bl,E_LV);
- sc_timer_next(2000 + tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
+ case SC_BURNING:
+ if( --(sce->val4) >= 0 )
+ {
+ struct block_list *src = map_id2bl(sce->val3);
+ int damage = 1000 + 3 * status_get_max_hp(bl) / 100; // Deals fixed (1000 + 3%*MaxHP)
- case SC_DEEPSLEEP:
- if (--(sce->val4) >= 0) {
- // Recovers 1% HP/SP every 2 seconds.
- status_heal(bl, status->max_hp / 100, status->max_sp / 100, 2);
- sc_timer_next(2000 + tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
+ map_freeblock_lock();
+ clif_damage(bl,bl,tick,0,0,damage,1,9,0); //damage is like endure effect with no walk delay
+ status_damage(src, bl, damage, 0, 0, 1);
- case SC_SIRCLEOFNATURE:
- if (--(sce->val4) >= 0) {
- if (!status_charge(bl,0,sce->val2))
- break;
- status_heal(bl, sce->val3, 0, 1);
- sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
+ if( sc->data[type]){ // Target still lives. [LimitLine]
+ sc_timer_next(2000 + tick, status_change_timer, bl->id, data);
+ }
+ map_freeblock_unlock();
+ return 0;
+ }
+ break;
+
+ case SC_FEAR:
+ if( --(sce->val4) >= 0 )
+ {
+ if( sce->val2 > 0 )
+ sce->val2--;
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+
+ case SC_SPHERE_1:
+ case SC_SPHERE_2:
+ case SC_SPHERE_3:
+ case SC_SPHERE_4:
+ case SC_SPHERE_5:
+ if( --(sce->val4) >= 0 )
+ {
+ if( !status_charge(bl, 0, 1) )
+ break;
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
- case SC_SONGOFMANA:
- if (--(sce->val4) >= 0) {
- status_heal(bl,0,sce->val3,3);
- sc_timer_next(3000 + tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
+ case SC_READING_SB:
+ if( !status_charge(bl, 0, sce->val2) ){
+ int i;
+ for(i = SC_SPELLBOOK1; i <= SC_MAXSPELLBOOK; i++) // Also remove stored spell as well.
+ status_change_end(bl, (sc_type)i, INVALID_TIMER);
+ break;
+ }
+ sc_timer_next(5000 + tick, status_change_timer, bl->id, data);
+ return 0;
+
+ case SC_ELECTRICSHOCKER:
+ if( --(sce->val4) >= 0 )
+ {
+ status_charge(bl, 0, status->max_sp / 100 * sce->val1 );
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+ case SC_CAMOUFLAGE:
+ if(--(sce->val4) > 0){
+ status_charge(bl,0,7 - sce->val1);
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
- case SC_SATURDAYNIGHTFEVER:
- // 1% HP/SP drain every val4 seconds [Jobbie]
- if (--(sce->val3) >= 0) {
- int hp = status->hp / 100;
- int sp = status->sp / 100;
- if (!status_charge(bl, hp, sp))
- break;
- sc_timer_next(sce->val4+tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
+ case SC__REPRODUCE:
+ if(!status_charge(bl, 0, 1))
+ break;
+ sc_timer_next(1000+tick, status_change_timer, bl->id, data);
+ return 0;
- case SC_CRYSTALIZE:
- if (--(sce->val4) >= 0) {
- // Drains 2% of HP and 1% of SP every seconds.
- if (bl->type != BL_MOB) // doesn't work on mobs
- status_charge(bl, status->max_hp * 2 / 100, status->max_sp / 100);
- sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
+ case SC__SHADOWFORM:
+ if( --(sce->val4) >= 0 )
+ {
+ if( !status_charge(bl, 0, sce->val1 - (sce->val1 - 1)) )
+ break;
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
- case SC_FORCEOFVANGUARD:
- if (!status_charge(bl,0,20))
- break;
- sc_timer_next(6000 + tick, status_change_timer, bl->id, data);
- return 0;
+ case SC__INVISIBILITY:
+ if( --(sce->val4) >= 0 )
+ {
+ if( !status_charge(bl, 0, (status->sp * 6 - sce->val1) / 100) )// 6% - skilllv.
+ break;
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
- case SC_BANDING:
- if (status_charge(bl, 0, 7 - sce->val1)) {
- if (sd) pc_banding(sd, sce->val1);
- sc_timer_next(5000 + tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
+ case SC_STRIKING:
+ if( --(sce->val4) >= 0 )
+ {
+ if( !status_charge(bl,0, sce->val1 ) )
+ break;
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+ case SC_VACUUM_EXTREME:
+ if( --(sce->val4) >= 0 ){
+ if( !unit_is_walking(bl) && !sce->val2 ){
+ sc->cant.move++;
+ sce->val2 = 1;
+ }
+ sc_timer_next(100 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+ case SC_BLOODSUCKER:
+ if( --(sce->val4) >= 0 ) {
+ struct block_list *src = map_id2bl(sce->val2);
+ int damage;
+ if( !src || (src && (status_isdead(src) || src->m != bl->m || distance_bl(src, bl) >= 12)) )
+ break;
+ map_freeblock_lock();
+ damage = 200 + 100 * sce->val1 + status_get_int(src);
+ status_damage(src, bl, damage, 0, clif_damage(bl,bl,tick,status->amotion,status->dmotion+200,damage,1,0,0), 1);
+ unit_skillcastcancel(bl,1);
+ if ( sc->data[type] ) {
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ }
+ map_freeblock_unlock();
+ status_heal(src, damage*(5 + 5 * sce->val1)/100, 0, 0); // 5 + 5% per level
+ return 0;
+ }
+ break;
+
+ case SC_VOICEOFSIREN:
+ if( --(sce->val4) >= 0 )
+ {
+ clif_emotion(bl,E_LV);
+ sc_timer_next(2000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+
+ case SC_DEEPSLEEP:
+ if( --(sce->val4) >= 0 )
+ { // Recovers 1% HP/SP every 2 seconds.
+ status_heal(bl, status->max_hp / 100, status->max_sp / 100, 2);
+ sc_timer_next(2000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
- case SC_REFLECTDAMAGE:
- if (--(sce->val4) >= 0) {
- if (!status_charge(bl,0,sce->val3))
- break;
- sc_timer_next(10000 + tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
+ case SC_SIRCLEOFNATURE:
+ if( --(sce->val4) >= 0 )
+ {
+ if( !status_charge(bl,0,sce->val2) )
+ break;
+ status_heal(bl, sce->val3, 0, 1);
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+
+ case SC_SONGOFMANA:
+ if( --(sce->val4) >= 0 )
+ {
+ status_heal(bl,0,sce->val3,3);
+ sc_timer_next(3000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
- case SC_OVERHEAT_LIMITPOINT:
- if (--(sce->val1) > 0) { // Cooling
- sc_timer_next(30000 + tick, status_change_timer, bl->id, data);
- }
- break;
- case SC_OVERHEAT: {
- int damage = status->max_hp / 100; // Suggestion 1% each second
- if (damage >= status->hp) damage = status->hp - 1; // Do not kill, just keep you with 1 hp minimum
- map_freeblock_lock();
- status_fix_damage(NULL,bl,damage,clif_damage(bl,bl,tick,0,0,damage,0,0,0));
- if (sc->data[type]) {
- sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
- }
- map_freeblock_unlock();
- }
- break;
+ case SC_SATURDAYNIGHTFEVER:
+ // 1% HP/SP drain every val4 seconds [Jobbie]
+ if( --(sce->val3) >= 0 )
+ {
+ int hp = status->hp / 100;
+ int sp = status->sp / 100;
+ if( !status_charge(bl, hp, sp) )
+ break;
+ sc_timer_next(sce->val4+tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+
+ case SC_CRYSTALIZE:
+ if( --(sce->val4) >= 0 )
+ { // Drains 2% of HP and 1% of SP every seconds.
+ if( bl->type != BL_MOB) // doesn't work on mobs
+ status_charge(bl, status->max_hp * 2 / 100, status->max_sp / 100);
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
- case SC_MAGNETICFIELD: {
- if (--(sce->val3) <= 0)
- break; // Time out
- if (sce->val2 == bl->id) {
- if (!status_charge(bl,0,14 + (3 * sce->val1)))
- break; // No more SP status should end, and in the next second will end for the other affected players
- } else {
- struct block_list *src = map_id2bl(sce->val2);
- struct status_change *ssc;
- if (!src || (ssc = status_get_sc(src)) == NULL || !ssc->data[SC_MAGNETICFIELD])
- break; // Source no more under Magnetic Field
- }
- sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
- }
- break;
+ case SC_FORCEOFVANGUARD:
+ if( !status_charge(bl,0,20) )
+ break;
+ sc_timer_next(6000 + tick, status_change_timer, bl->id, data);
+ return 0;
+
+ case SC_BANDING:
+ if( status_charge(bl, 0, 7 - sce->val1) )
+ {
+ if( sd ) pc_banding(sd, sce->val1);
+ sc_timer_next(5000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
- case SC_INSPIRATION:
- if (--(sce->val4) >= 0) {
- int hp = status->max_hp * (7-sce->val1) / 100;
- int sp = status->max_sp * (9-sce->val1) / 100;
+ case SC_REFLECTDAMAGE:
+ if( --(sce->val4) >= 0 ) {
+ if( !status_charge(bl,0,sce->val3) )
+ break;
+ sc_timer_next(10000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
- if (!status_charge(bl,hp,sp)) break;
+ case SC_OVERHEAT_LIMITPOINT:
+ if( --(sce->val1) > 0 ) { // Cooling
+ sc_timer_next(30000 + tick, status_change_timer, bl->id, data);
+ }
+ break;
+
+ case SC_OVERHEAT:
+ {
+ int damage = status->max_hp / 100; // Suggestion 1% each second
+ if( damage >= status->hp ) damage = status->hp - 1; // Do not kill, just keep you with 1 hp minimum
+ map_freeblock_lock();
+ status_fix_damage(NULL,bl,damage,clif_damage(bl,bl,tick,0,0,damage,0,0,0));
+ if( sc->data[type] ) {
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ }
+ map_freeblock_unlock();
+ }
+ break;
+
+ case SC_MAGNETICFIELD:
+ {
+ if( --(sce->val3) <= 0 )
+ break; // Time out
+ if( sce->val2 == bl->id )
+ {
+ if( !status_charge(bl,0,14 + (3 * sce->val1)) )
+ break; // No more SP status should end, and in the next second will end for the other affected players
+ }
+ else
+ {
+ struct block_list *src = map_id2bl(sce->val2);
+ struct status_change *ssc;
+ if( !src || (ssc = status_get_sc(src)) == NULL || !ssc->data[SC_MAGNETICFIELD] )
+ break; // Source no more under Magnetic Field
+ }
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ }
+ break;
- sc_timer_next(1000+tick,status_change_timer,bl->id, data);
- return 0;
- }
- break;
+ case SC_INSPIRATION:
+ if(--(sce->val4) >= 0)
+ {
+ int hp = status->max_hp * (7-sce->val1) / 100;
+ int sp = status->max_sp * (9-sce->val1) / 100;
- case SC_RAISINGDRAGON:
- // 1% every 5 seconds [Jobbie]
- if (--(sce->val3)>0 && status_charge(bl, sce->val2, 0)) {
- if (!sc->data[type]) return 0;
- sc_timer_next(5000 + tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
+ if( !status_charge(bl,hp,sp) ) break;
- case SC_CIRCLE_OF_FIRE:
- case SC_FIRE_CLOAK:
- case SC_WATER_DROP:
- case SC_WATER_SCREEN:
- case SC_WIND_CURTAIN:
- case SC_WIND_STEP:
- case SC_STONE_SHIELD:
- case SC_SOLID_SKIN:
- if (!status_charge(bl,0,sce->val2)) {
- struct block_list *s_bl = battle_get_master(bl);
- if (s_bl)
- status_change_end(s_bl,type+1,INVALID_TIMER);
- status_change_end(bl,type,INVALID_TIMER);
- break;
- }
- sc_timer_next(2000 + tick, status_change_timer, bl->id, data);
- return 0;
-
- case SC_STOMACHACHE:
- if (--(sce->val4) > 0) {
- status_charge(bl,0,sce->val2); // Reduce 8 every 10 seconds.
- if (sd && !pc_issit(sd)) { // Force to sit every 10 seconds.
- pc_stop_walking(sd,1|4);
- pc_stop_attack(sd);
- pc_setsit(sd);
- clif_sitting(bl);
- }
- sc_timer_next(10000 + tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
- case SC_LEADERSHIP:
- case SC_GLORYWOUNDS:
- case SC_SOULCOLD:
- case SC_HAWKEYES:
- /* they only end by status_change_end */
- sc_timer_next(600000 + tick, status_change_timer, bl->id, data);
- return 0;
- case SC_MEIKYOUSISUI:
- if (--(sce->val4) > 0) {
- status_heal(bl, status->max_hp * (sce->val1+1) / 100, status->max_sp * sce->val1 / 100, 0);
- sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
- case SC_IZAYOI:
- case SC_KAGEMUSYA:
- if (--(sce->val2) > 0) {
- if (!status_charge(bl, 0, 1)) break;
- sc_timer_next(1000+tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
- case SC_ANGRIFFS_MODUS:
- if (--(sce->val4) >= 0) { //drain hp/sp
- if (!status_charge(bl,100,20)) break;
- sc_timer_next(1000+tick,status_change_timer,bl->id, data);
- return 0;
- }
- break;
- }
+ sc_timer_next(1000+tick,status_change_timer,bl->id, data);
+ return 0;
+ }
+ break;
+
+ case SC_RAISINGDRAGON:
+ // 1% every 5 seconds [Jobbie]
+ if( --(sce->val3)>0 && status_charge(bl, sce->val2, 0) )
+ {
+ if( !sc->data[type] ) return 0;
+ sc_timer_next(5000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+
+ case SC_CIRCLE_OF_FIRE:
+ case SC_FIRE_CLOAK:
+ case SC_WATER_DROP:
+ case SC_WATER_SCREEN:
+ case SC_WIND_CURTAIN:
+ case SC_WIND_STEP:
+ case SC_STONE_SHIELD:
+ case SC_SOLID_SKIN:
+ if( !status_charge(bl,0,sce->val2) ){
+ struct block_list *s_bl = battle_get_master(bl);
+ if( s_bl )
+ status_change_end(s_bl,type+1,INVALID_TIMER);
+ status_change_end(bl,type,INVALID_TIMER);
+ break;
+ }
+ sc_timer_next(2000 + tick, status_change_timer, bl->id, data);
+ return 0;
+
+ case SC_STOMACHACHE:
+ if( --(sce->val4) > 0 ){
+ status_charge(bl,0,sce->val2); // Reduce 8 every 10 seconds.
+ if( sd && !pc_issit(sd) ) // Force to sit every 10 seconds.
+ {
+ pc_stop_walking(sd,1|4);
+ pc_stop_attack(sd);
+ pc_setsit(sd);
+ clif_sitting(bl);
+ }
+ sc_timer_next(10000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+ case SC_LEADERSHIP:
+ case SC_GLORYWOUNDS:
+ case SC_SOULCOLD:
+ case SC_HAWKEYES:
+ /* they only end by status_change_end */
+ sc_timer_next(600000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ case SC_MEIKYOUSISUI:
+ if( --(sce->val4) > 0 ){
+ status_heal(bl, status->max_hp * (sce->val1+1) / 100, status->max_sp * sce->val1 / 100, 0);
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+ case SC_IZAYOI:
+ case SC_KAGEMUSYA:
+ if( --(sce->val2) > 0 ){
+ if(!status_charge(bl, 0, 1)) break;
+ sc_timer_next(1000+tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+ case SC_ANGRIFFS_MODUS:
+ if(--(sce->val4) >= 0) { //drain hp/sp
+ if( !status_charge(bl,100,20) ) break;
+ sc_timer_next(1000+tick,status_change_timer,bl->id, data);
+ return 0;
+ }
+ break;
+ }
- // default for all non-handled control paths is to end the status
- return status_change_end(bl,type,tid);
+ // default for all non-handled control paths is to end the status
+ return status_change_end( bl,type,tid );
#undef sc_timer_next
}
/*==========================================
* Foreach iteration of repetitive status
*------------------------------------------*/
-int status_change_timer_sub(struct block_list *bl, va_list ap)
+int status_change_timer_sub(struct block_list* bl, va_list ap)
{
- struct status_change *tsc;
-
- struct block_list *src = va_arg(ap,struct block_list *);
- struct status_change_entry *sce = va_arg(ap,struct status_change_entry *);
- enum sc_type type = (sc_type)va_arg(ap,int); //gcc: enum args get promoted to int
- unsigned int tick = va_arg(ap,unsigned int);
-
- if (status_isdead(bl))
- return 0;
-
- tsc = status_get_sc(bl);
-
- switch (type) {
- case SC_SIGHT: /* Reveal hidden ennemy on 3*3 range */
- if (tsc && tsc->data[SC__SHADOWFORM] && (sce && sce->val4 >0 && sce->val4%2000 == 0) && // for every 2 seconds do the checking
- rnd()%100 < 100-tsc->data[SC__SHADOWFORM]->val1*10) // [100 - (Skill Level x 10)] %
- status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
- case SC_CONCENTRATE:
- status_change_end(bl, SC_HIDING, INVALID_TIMER);
- status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
- status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
- status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER);
- status_change_end(bl, SC__INVISIBILITY, INVALID_TIMER);
- break;
- case SC_RUWACH: /* Reveal hidden target and deal little dammages if ennemy */
- if (tsc && (tsc->data[SC_HIDING] || tsc->data[SC_CLOAKING] ||
- tsc->data[SC_CAMOUFLAGE] || tsc->data[SC_CLOAKINGEXCEED] ||
- tsc->data[SC__INVISIBILITY])) {
- status_change_end(bl, SC_HIDING, INVALID_TIMER);
- status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
- status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER);
- status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
- status_change_end(bl, SC__INVISIBILITY, INVALID_TIMER);
- if (battle_check_target(src, bl, BCT_ENEMY) > 0)
- skill_attack(BF_MAGIC,src,src,bl,AL_RUWACH,1,tick,0);
- }
- if (tsc && tsc->data[SC__SHADOWFORM] && (sce && sce->val4 >0 && sce->val4%2000 == 0) && // for every 2 seconds do the checking
- rnd()%100 < 100-tsc->data[SC__SHADOWFORM]->val1*10) // [100 - (Skill Level x 10)] %
- status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
- break;
- case SC_SIGHTBLASTER:
- if (battle_check_target(src, bl, BCT_ENEMY) > 0 &&
- status_check_skilluse(src, bl, WZ_SIGHTBLASTER, 2)) {
- skill_attack(BF_MAGIC,src,src,bl,WZ_SIGHTBLASTER,1,tick,0);
- if (sce) sce->val2 = 0; //This signals it to end.
- }
- break;
- case SC_CLOSECONFINE:
- //Lock char has released the hold on everyone...
- if (tsc && tsc->data[SC_CLOSECONFINE2] && tsc->data[SC_CLOSECONFINE2]->val2 == src->id) {
- tsc->data[SC_CLOSECONFINE2]->val2 = 0;
- status_change_end(bl, SC_CLOSECONFINE2, INVALID_TIMER);
- }
- break;
- case SC_CURSEDCIRCLE_TARGET:
- if (tsc && tsc->data[SC_CURSEDCIRCLE_TARGET] && tsc->data[SC_CURSEDCIRCLE_TARGET]->val2 == src->id) {
- clif_bladestop(bl, tsc->data[SC_CURSEDCIRCLE_TARGET]->val2, 0);
- status_change_end(bl, type, INVALID_TIMER);
- }
- break;
- }
- return 0;
+ struct status_change* tsc;
+
+ struct block_list* src = va_arg(ap,struct block_list*);
+ struct status_change_entry* sce = va_arg(ap,struct status_change_entry*);
+ enum sc_type type = (sc_type)va_arg(ap,int); //gcc: enum args get promoted to int
+ unsigned int tick = va_arg(ap,unsigned int);
+
+ if (status_isdead(bl))
+ return 0;
+
+ tsc = status_get_sc(bl);
+
+ switch( type ) {
+ case SC_SIGHT: /* Reveal hidden ennemy on 3*3 range */
+ if( tsc && tsc->data[SC__SHADOWFORM] && (sce && sce->val4 >0 && sce->val4%2000 == 0) && // for every 2 seconds do the checking
+ rnd()%100 < 100-tsc->data[SC__SHADOWFORM]->val1*10 ) // [100 - (Skill Level x 10)] %
+ status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
+ case SC_CONCENTRATE:
+ status_change_end(bl, SC_HIDING, INVALID_TIMER);
+ status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
+ status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
+ status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER);
+ status_change_end(bl, SC__INVISIBILITY, INVALID_TIMER);
+ break;
+ case SC_RUWACH: /* Reveal hidden target and deal little dammages if ennemy */
+ if (tsc && (tsc->data[SC_HIDING] || tsc->data[SC_CLOAKING] ||
+ tsc->data[SC_CAMOUFLAGE] || tsc->data[SC_CLOAKINGEXCEED] ||
+ tsc->data[SC__INVISIBILITY])) {
+ status_change_end(bl, SC_HIDING, INVALID_TIMER);
+ status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
+ status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER);
+ status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
+ status_change_end(bl, SC__INVISIBILITY, INVALID_TIMER);
+ if(battle_check_target( src, bl, BCT_ENEMY ) > 0)
+ skill_attack(BF_MAGIC,src,src,bl,AL_RUWACH,1,tick,0);
+ }
+ if( tsc && tsc->data[SC__SHADOWFORM] && (sce && sce->val4 >0 && sce->val4%2000 == 0) && // for every 2 seconds do the checking
+ rnd()%100 < 100-tsc->data[SC__SHADOWFORM]->val1*10 ) // [100 - (Skill Level x 10)] %
+ status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
+ break;
+ case SC_SIGHTBLASTER:
+ if (battle_check_target( src, bl, BCT_ENEMY ) > 0 &&
+ status_check_skilluse(src, bl, WZ_SIGHTBLASTER, 2))
+ {
+ skill_attack(BF_MAGIC,src,src,bl,WZ_SIGHTBLASTER,1,tick,0);
+ if (sce) sce->val2 = 0; //This signals it to end.
+ }
+ break;
+ case SC_CLOSECONFINE:
+ //Lock char has released the hold on everyone...
+ if (tsc && tsc->data[SC_CLOSECONFINE2] && tsc->data[SC_CLOSECONFINE2]->val2 == src->id) {
+ tsc->data[SC_CLOSECONFINE2]->val2 = 0;
+ status_change_end(bl, SC_CLOSECONFINE2, INVALID_TIMER);
+ }
+ break;
+ case SC_CURSEDCIRCLE_TARGET:
+ if( tsc && tsc->data[SC_CURSEDCIRCLE_TARGET] && tsc->data[SC_CURSEDCIRCLE_TARGET]->val2 == src->id ) {
+ clif_bladestop(bl, tsc->data[SC_CURSEDCIRCLE_TARGET]->val2, 0);
+ status_change_end(bl, type, INVALID_TIMER);
+ }
+ break;
+ }
+ return 0;
}
/*==========================================
* Clears buffs/debuffs of a character.
* type&1 -> buffs, type&2 -> debuffs
- * type&4 -> especific debuffs(implemented with refresh)
*------------------------------------------*/
-int status_change_clear_buffs(struct block_list *bl, int type)
+int status_change_clear_buffs (struct block_list* bl, int type)
{
- int i;
- struct status_change *sc= status_get_sc(bl);
-
- if (!sc || !sc->count)
- return 0;
-
- if (type&6) //Debuffs
- for (i = SC_COMMON_MIN; i <= SC_COMMON_MAX; i++)
- status_change_end(bl, (sc_type)i, INVALID_TIMER);
-
- for (i = SC_COMMON_MAX+1; i < SC_MAX; i++) {
- if (!sc->data[i])
- continue;
-
- switch (i) {
- //Stuff that cannot be removed
- case SC_WEIGHT50:
- case SC_WEIGHT90:
- case SC_COMBO:
- case SC_SMA:
- case SC_DANCING:
- case SC_LEADERSHIP:
- case SC_GLORYWOUNDS:
- case SC_SOULCOLD:
- case SC_HAWKEYES:
- case SC_GUILDAURA:
- case SC_SAFETYWALL:
- case SC_PNEUMA:
- case SC_NOCHAT:
- case SC_JAILED:
- case SC_ANKLE:
- case SC_BLADESTOP:
- case SC_CP_WEAPON:
- case SC_CP_SHIELD:
- case SC_CP_ARMOR:
- case SC_CP_HELM:
- case SC_STRFOOD:
- case SC_AGIFOOD:
- case SC_VITFOOD:
- case SC_INTFOOD:
- case SC_DEXFOOD:
- case SC_LUKFOOD:
- case SC_HITFOOD:
- case SC_FLEEFOOD:
- case SC_BATKFOOD:
- case SC_WATKFOOD:
- case SC_MATKFOOD:
- case SC_FOOD_STR_CASH:
- case SC_FOOD_AGI_CASH:
- case SC_FOOD_VIT_CASH:
- case SC_FOOD_DEX_CASH:
- case SC_FOOD_INT_CASH:
- case SC_FOOD_LUK_CASH:
- case SC_EXPBOOST:
- case SC_JEXPBOOST:
- case SC_ITEMBOOST:
- case SC_ELECTRICSHOCKER:
- case SC__MANHOLE:
- case SC_GIANTGROWTH:
- case SC_MILLENNIUMSHIELD:
- case SC_REFRESH:
- case SC_STONEHARDSKIN:
- case SC_VITALITYACTIVATION:
- case SC_FIGHTINGSPIRIT:
- case SC_ABUNDANCE:
- case SC_CURSEDCIRCLE_ATKER:
- case SC_CURSEDCIRCLE_TARGET:
- continue;
-
- //Debuffs that can be removed.
- case SC_DEEPSLEEP:
+ int i;
+ struct status_change *sc= status_get_sc(bl);
+
+ if (!sc || !sc->count)
+ return 0;
+
+ if (type&2) //Debuffs
+ for( i = SC_COMMON_MIN; i <= SC_COMMON_MAX; i++ )
+ {
+ status_change_end(bl, (sc_type)i, INVALID_TIMER);
+ }
+
+ for( i = SC_COMMON_MAX+1; i < SC_MAX; i++ )
+ {
+ if(!sc->data[i])
+ continue;
+
+ switch (i) {
+ //Stuff that cannot be removed
+ case SC_WEIGHT50:
+ case SC_WEIGHT90:
+ case SC_COMBO:
+ case SC_SMA:
+ case SC_DANCING:
+ case SC_LEADERSHIP:
+ case SC_GLORYWOUNDS:
+ case SC_SOULCOLD:
+ case SC_HAWKEYES:
+ case SC_GUILDAURA:
+ case SC_SAFETYWALL:
+ case SC_PNEUMA:
+ case SC_NOCHAT:
+ case SC_JAILED:
+ case SC_ANKLE:
+ case SC_BLADESTOP:
+ case SC_CP_WEAPON:
+ case SC_CP_SHIELD:
+ case SC_CP_ARMOR:
+ case SC_CP_HELM:
+ case SC_STRFOOD:
+ case SC_AGIFOOD:
+ case SC_VITFOOD:
+ case SC_INTFOOD:
+ case SC_DEXFOOD:
+ case SC_LUKFOOD:
+ case SC_HITFOOD:
+ case SC_FLEEFOOD:
+ case SC_BATKFOOD:
+ case SC_WATKFOOD:
+ case SC_MATKFOOD:
+ case SC_FOOD_STR_CASH:
+ case SC_FOOD_AGI_CASH:
+ case SC_FOOD_VIT_CASH:
+ case SC_FOOD_DEX_CASH:
+ case SC_FOOD_INT_CASH:
+ case SC_FOOD_LUK_CASH:
+ case SC_EXPBOOST:
+ case SC_JEXPBOOST:
+ case SC_ITEMBOOST:
+ case SC_ELECTRICSHOCKER:
+ case SC__MANHOLE:
+ case SC_GIANTGROWTH:
+ case SC_MILLENNIUMSHIELD:
+ case SC_REFRESH:
+ case SC_STONEHARDSKIN:
+ case SC_VITALITYACTIVATION:
+ case SC_FIGHTINGSPIRIT:
+ case SC_ABUNDANCE:
+ case SC_CURSEDCIRCLE_ATKER:
+ case SC_CURSEDCIRCLE_TARGET:
+ continue;
+
+ //Debuffs that can be removed.
+ case SC_HALLUCINATION:
+ case SC_QUAGMIRE:
+ case SC_SIGNUMCRUCIS:
+ case SC_DECREASEAGI:
+ case SC_SLOWDOWN:
+ case SC_MINDBREAKER:
+ case SC_WINKCHARM:
+ case SC_STOP:
+ case SC_ORCISH:
+ case SC_STRIPWEAPON:
+ case SC_STRIPSHIELD:
+ case SC_STRIPARMOR:
+ case SC_STRIPHELM:
+ case SC_BITE:
+ case SC_ADORAMUS:
+ case SC_VACUUM_EXTREME:
case SC_BURNING:
+ case SC_FEAR:
+ case SC_MAGNETICFIELD:
+ case SC_NETHERWORLD:
+ if (!(type&2))
+ continue;
+ break;
+ //The rest are buffs that can be removed.
+ case SC__BLOODYLUST:
+ case SC_BERSERK:
+ case SC_SATURDAYNIGHTFEVER:
+ if (!(type&1))
+ continue;
+ sc->data[i]->val2 = 0;
+ break;
+ default:
+ if (!(type&1))
+ continue;
+ break;
+ }
+ status_change_end(bl, (sc_type)i, INVALID_TIMER);
+ }
+ return 0;
+}
+
+int status_change_spread( struct block_list *src, struct block_list *bl ) {
+ int i, flag = 0;
+ struct status_change *sc = status_get_sc(src);
+ const struct TimerData *timer;
+ unsigned int tick;
+ struct status_change_data data;
+
+ if( !sc || !sc->count )
+ return 0;
+
+ tick = gettick();
+
+ for( i = SC_COMMON_MIN; i < SC_MAX; i++ ) {
+ if( !sc->data[i] || i == SC_COMMON_MAX )
+ continue;
+
+ switch( i ) {
+ //Debuffs that can be spreaded.
+ // NOTE: We'll add/delte SCs when we are able to confirm it.
+ case SC_CURSE:
+ case SC_SILENCE:
+ case SC_CONFUSION:
+ case SC_BLIND:
+ case SC_NOCHAT:
+ case SC_HALLUCINATION:
+ case SC_SIGNUMCRUCIS:
+ case SC_DECREASEAGI:
+ case SC_SLOWDOWN:
+ case SC_MINDBREAKER:
+ case SC_WINKCHARM:
+ case SC_STOP:
+ case SC_ORCISH:
+ //case SC_STRIPWEAPON://Omg I got infected and had the urge to strip myself physically.
+ //case SC_STRIPSHIELD://No this is stupid and shouldnt be spreadable at all.
+ //case SC_STRIPARMOR:// Disabled until I can confirm if it does or not. [Rytech]
+ //case SC_STRIPHELM:
+ //case SC__STRIPACCESSORY:
+ case SC_BITE:
case SC_FREEZING:
- case SC_CRYSTALIZE:
- case SC_TOXIN:
- case SC_PARALYSE:
case SC_VENOMBLEED:
- case SC_MAGICMUSHROOM:
case SC_DEATHHURT:
+ case SC_PARALYSE:
+ if( sc->data[i]->timer != INVALID_TIMER ) {
+ timer = get_timer(sc->data[i]->timer);
+ if (timer == NULL || timer->func != status_change_timer || DIFF_TICK(timer->tick,tick) < 0)
+ continue;
+ data.tick = DIFF_TICK(timer->tick,tick);
+ } else
+ data.tick = INVALID_TIMER;
+ break;
+ // Special cases
+ case SC_POISON:
+ case SC_DPOISON:
+ data.tick = sc->data[i]->val3 * 1000;
+ break;
+ case SC_FEAR:
+ case SC_LEECHESEND:
+ data.tick = sc->data[i]->val4 * 1000;
+ break;
+ case SC_BURNING:
+ data.tick = sc->data[i]->val4 * 2000;
+ break;
case SC_PYREXIA:
case SC_OBLIVIONCURSE:
- case SC_LEECHESEND:
- case SC_MARSHOFABYSS:
- case SC_MANDRAGORA:
- if(!(type&4))
+ data.tick = sc->data[i]->val4 * 3000;
+ break;
+ case SC_MAGICMUSHROOM:
+ data.tick = sc->data[i]->val4 * 4000;
+ break;
+ case SC_TOXIN:
+ case SC_BLEEDING:
+ data.tick = sc->data[i]->val4 * 10000;
+ break;
+ default:
continue;
break;
- case SC_HALLUCINATION:
- case SC_QUAGMIRE:
- case SC_SIGNUMCRUCIS:
- case SC_DECREASEAGI:
- case SC_SLOWDOWN:
- case SC_MINDBREAKER:
- case SC_WINKCHARM:
- case SC_STOP:
- case SC_ORCISH:
- case SC_STRIPWEAPON:
- case SC_STRIPSHIELD:
- case SC_STRIPARMOR:
- case SC_STRIPHELM:
- case SC_BITE:
- case SC_ADORAMUS:
- case SC_VACUUM_EXTREME:
- case SC_FEAR:
- case SC_MAGNETICFIELD:
- case SC_NETHERWORLD:
- if (!(type&2))
- continue;
- break;
- //The rest are buffs that can be removed.
- case SC__BLOODYLUST:
- case SC_BERSERK:
- case SC_SATURDAYNIGHTFEVER:
- if (!(type&1))
- continue;
- sc->data[i]->val2 = 0;
- break;
- default:
- if (!(type&1))
- continue;
- break;
- }
- status_change_end(bl, (sc_type)i, INVALID_TIMER);
- }
- return 0;
-}
-
-int status_change_spread(struct block_list *src, struct block_list *bl)
-{
- int i, flag = 0;
- struct status_change *sc = status_get_sc(src);
- const struct TimerData *timer;
- unsigned int tick;
- struct status_change_data data;
-
- if (!sc || !sc->count)
- return 0;
-
- tick = gettick();
-
- for (i = SC_COMMON_MIN; i < SC_MAX; i++) {
- if (!sc->data[i] || i == SC_COMMON_MAX)
- continue;
-
- switch (i) {
- //Debuffs that can be spreaded.
- // NOTE: We'll add/delte SCs when we are able to confirm it.
- case SC_CURSE:
- case SC_SILENCE:
- case SC_CONFUSION:
- case SC_BLIND:
- case SC_NOCHAT:
- case SC_HALLUCINATION:
- case SC_SIGNUMCRUCIS:
- case SC_DECREASEAGI:
- case SC_SLOWDOWN:
- case SC_MINDBREAKER:
- case SC_WINKCHARM:
- case SC_STOP:
- case SC_ORCISH:
- //case SC_STRIPWEAPON://Omg I got infected and had the urge to strip myself physically.
- //case SC_STRIPSHIELD://No this is stupid and shouldnt be spreadable at all.
- //case SC_STRIPARMOR:// Disabled until I can confirm if it does or not. [Rytech]
- //case SC_STRIPHELM:
- //case SC__STRIPACCESSORY:
- case SC_BITE:
- case SC_FREEZING:
- case SC_VENOMBLEED:
- case SC_DEATHHURT:
- case SC_PARALYSE:
- if (sc->data[i]->timer != INVALID_TIMER) {
- timer = get_timer(sc->data[i]->timer);
- if (timer == NULL || timer->func != status_change_timer || DIFF_TICK(timer->tick,tick) < 0)
- continue;
- data.tick = DIFF_TICK(timer->tick,tick);
- } else
- data.tick = INVALID_TIMER;
- break;
- // Special cases
- case SC_POISON:
- case SC_DPOISON:
- data.tick = sc->data[i]->val3 * 1000;
- break;
- case SC_FEAR:
- case SC_LEECHESEND:
- data.tick = sc->data[i]->val4 * 1000;
- break;
- case SC_BURNING:
- data.tick = sc->data[i]->val4 * 2000;
- break;
- case SC_PYREXIA:
- case SC_OBLIVIONCURSE:
- data.tick = sc->data[i]->val4 * 3000;
- break;
- case SC_MAGICMUSHROOM:
- data.tick = sc->data[i]->val4 * 4000;
- break;
- case SC_TOXIN:
- case SC_BLEEDING:
- data.tick = sc->data[i]->val4 * 10000;
- break;
- default:
- continue;
- break;
- }
- if (i) {
- data.val1 = sc->data[i]->val1;
- data.val2 = sc->data[i]->val2;
- data.val3 = sc->data[i]->val3;
- data.val4 = sc->data[i]->val4;
- status_change_start(bl,(sc_type)i,10000,data.val1,data.val2,data.val3,data.val4,data.tick,1|2|8);
- flag = 1;
- }
- }
+ }
+ if( i ){
+ data.val1 = sc->data[i]->val1;
+ data.val2 = sc->data[i]->val2;
+ data.val3 = sc->data[i]->val3;
+ data.val4 = sc->data[i]->val4;
+ status_change_start(bl,(sc_type)i,10000,data.val1,data.val2,data.val3,data.val4,data.tick,1|2|8);
+ flag = 1;
+ }
+ }
- return flag;
+ return flag;
}
//Natural regen related stuff.
static unsigned int natural_heal_prev_tick,natural_heal_diff_tick;
-static int status_natural_heal(struct block_list *bl, va_list args)
+static int status_natural_heal(struct block_list* bl, va_list args)
{
- struct regen_data *regen;
- struct status_data *status;
- struct status_change *sc;
- struct unit_data *ud;
- struct view_data *vd = NULL;
- struct regen_data_sub *sregen;
- struct map_session_data *sd;
- int val,rate,bonus = 0,flag;
-
- regen = status_get_regen_data(bl);
- if (!regen) return 0;
- status = status_get_status_data(bl);
- sc = status_get_sc(bl);
- if (sc && !sc->count)
- sc = NULL;
- sd = BL_CAST(BL_PC,bl);
-
- flag = regen->flag;
- if (flag&RGN_HP && (status->hp >= status->max_hp || regen->state.block&1))
- flag&=~(RGN_HP|RGN_SHP);
- if (flag&RGN_SP && (status->sp >= status->max_sp || regen->state.block&2))
- flag&=~(RGN_SP|RGN_SSP);
-
- if (flag && (
- status_isdead(bl) ||
- (sc && (sc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || sc->data[SC__INVISIBILITY]))
- ))
- flag=0;
-
- if (sd) {
- if (sd->hp_loss.value || sd->sp_loss.value)
- pc_bleeding(sd, natural_heal_diff_tick);
- if (sd->hp_regen.value || sd->sp_regen.value)
- pc_regen(sd, natural_heal_diff_tick);
- }
-
- if (flag&(RGN_SHP|RGN_SSP) && regen->ssregen &&
- (vd = status_get_viewdata(bl)) && vd->dead_sit == 2) {
- //Apply sitting regen bonus.
- sregen = regen->ssregen;
- if (flag&(RGN_SHP)) {
- //Sitting HP regen
- val = natural_heal_diff_tick * sregen->rate.hp;
- if (regen->state.overweight)
- val>>=1; //Half as fast when overweight.
- sregen->tick.hp += val;
- while (sregen->tick.hp >= (unsigned int)battle_config.natural_heal_skill_interval) {
- sregen->tick.hp -= battle_config.natural_heal_skill_interval;
- if (status_heal(bl, sregen->hp, 0, 3) < sregen->hp) {
- //Full
- flag&=~(RGN_HP|RGN_SHP);
- break;
- }
- }
- }
- if (flag&(RGN_SSP)) {
- //Sitting SP regen
- val = natural_heal_diff_tick * sregen->rate.sp;
- if (regen->state.overweight)
- val>>=1; //Half as fast when overweight.
- sregen->tick.sp += val;
- while (sregen->tick.sp >= (unsigned int)battle_config.natural_heal_skill_interval) {
- sregen->tick.sp -= battle_config.natural_heal_skill_interval;
- if (status_heal(bl, 0, sregen->sp, 3) < sregen->sp) {
- //Full
- flag&=~(RGN_SP|RGN_SSP);
- break;
- }
- }
- }
- }
-
- if (flag && regen->state.overweight)
- flag=0;
-
- ud = unit_bl2ud(bl);
-
- if (flag&(RGN_HP|RGN_SHP|RGN_SSP) && ud && ud->walktimer != INVALID_TIMER) {
- flag&=~(RGN_SHP|RGN_SSP);
- if (!regen->state.walk)
- flag&=~RGN_HP;
- }
-
- if (!flag)
- return 0;
-
- if (flag&(RGN_HP|RGN_SP)) {
- if (!vd) vd = status_get_viewdata(bl);
- if (vd && vd->dead_sit == 2)
- bonus++;
- if (regen->state.gc)
- bonus++;
- }
-
- //Natural Hp regen
- if (flag&RGN_HP) {
- rate = natural_heal_diff_tick*(regen->rate.hp+bonus);
- if (ud && ud->walktimer != INVALID_TIMER)
- rate/=2;
- // Homun HP regen fix (they should regen as if they were sitting (twice as fast)
- if (bl->type==BL_HOM) rate *=2;
-
- regen->tick.hp += rate;
-
- if (regen->tick.hp >= (unsigned int)battle_config.natural_healhp_interval) {
- val = 0;
- do {
- val += regen->hp;
- regen->tick.hp -= battle_config.natural_healhp_interval;
- } while (regen->tick.hp >= (unsigned int)battle_config.natural_healhp_interval);
- if (status_heal(bl, val, 0, 1) < val)
- flag&=~RGN_SHP; //full.
- }
- }
-
- //Natural SP regen
- if (flag&RGN_SP) {
- rate = natural_heal_diff_tick*(regen->rate.sp+bonus);
- // Homun SP regen fix (they should regen as if they were sitting (twice as fast)
- if (bl->type==BL_HOM) rate *=2;
-
- regen->tick.sp += rate;
-
- if (regen->tick.sp >= (unsigned int)battle_config.natural_healsp_interval) {
- val = 0;
- do {
- val += regen->sp;
- regen->tick.sp -= battle_config.natural_healsp_interval;
- } while (regen->tick.sp >= (unsigned int)battle_config.natural_healsp_interval);
- if (status_heal(bl, 0, val, 1) < val)
- flag&=~RGN_SSP; //full.
- }
- }
+ struct regen_data *regen;
+ struct status_data *status;
+ struct status_change *sc;
+ struct unit_data *ud;
+ struct view_data *vd = NULL;
+ struct regen_data_sub *sregen;
+ struct map_session_data *sd;
+ int val,rate,bonus = 0,flag;
+
+ regen = status_get_regen_data(bl);
+ if (!regen) return 0;
+ status = status_get_status_data(bl);
+ sc = status_get_sc(bl);
+ if (sc && !sc->count)
+ sc = NULL;
+ sd = BL_CAST(BL_PC,bl);
+
+ flag = regen->flag;
+ if (flag&RGN_HP && (status->hp >= status->max_hp || regen->state.block&1))
+ flag&=~(RGN_HP|RGN_SHP);
+ if (flag&RGN_SP && (status->sp >= status->max_sp || regen->state.block&2))
+ flag&=~(RGN_SP|RGN_SSP);
+
+ if (flag && (
+ status_isdead(bl) ||
+ (sc && (sc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || sc->data[SC__INVISIBILITY]))
+ ))
+ flag=0;
+
+ if (sd) {
+ if (sd->hp_loss.value || sd->sp_loss.value)
+ pc_bleeding(sd, natural_heal_diff_tick);
+ if (sd->hp_regen.value || sd->sp_regen.value)
+ pc_regen(sd, natural_heal_diff_tick);
+ }
+
+ if(flag&(RGN_SHP|RGN_SSP) && regen->ssregen &&
+ (vd = status_get_viewdata(bl)) && vd->dead_sit == 2)
+ { //Apply sitting regen bonus.
+ sregen = regen->ssregen;
+ if(flag&(RGN_SHP))
+ { //Sitting HP regen
+ val = natural_heal_diff_tick * sregen->rate.hp;
+ if (regen->state.overweight)
+ val>>=1; //Half as fast when overweight.
+ sregen->tick.hp += val;
+ while(sregen->tick.hp >= (unsigned int)battle_config.natural_heal_skill_interval)
+ {
+ sregen->tick.hp -= battle_config.natural_heal_skill_interval;
+ if(status_heal(bl, sregen->hp, 0, 3) < sregen->hp)
+ { //Full
+ flag&=~(RGN_HP|RGN_SHP);
+ break;
+ }
+ }
+ }
+ if(flag&(RGN_SSP))
+ { //Sitting SP regen
+ val = natural_heal_diff_tick * sregen->rate.sp;
+ if (regen->state.overweight)
+ val>>=1; //Half as fast when overweight.
+ sregen->tick.sp += val;
+ while(sregen->tick.sp >= (unsigned int)battle_config.natural_heal_skill_interval)
+ {
+ sregen->tick.sp -= battle_config.natural_heal_skill_interval;
+ if(status_heal(bl, 0, sregen->sp, 3) < sregen->sp)
+ { //Full
+ flag&=~(RGN_SP|RGN_SSP);
+ break;
+ }
+ }
+ }
+ }
+
+ if (flag && regen->state.overweight)
+ flag=0;
+
+ ud = unit_bl2ud(bl);
+
+ if (flag&(RGN_HP|RGN_SHP|RGN_SSP) && ud && ud->walktimer != INVALID_TIMER)
+ {
+ flag&=~(RGN_SHP|RGN_SSP);
+ if(!regen->state.walk)
+ flag&=~RGN_HP;
+ }
+
+ if (!flag)
+ return 0;
+
+ if (flag&(RGN_HP|RGN_SP))
+ {
+ if(!vd) vd = status_get_viewdata(bl);
+ if(vd && vd->dead_sit == 2)
+ bonus++;
+ if(regen->state.gc)
+ bonus++;
+ }
+
+ //Natural Hp regen
+ if (flag&RGN_HP)
+ {
+ rate = natural_heal_diff_tick*(regen->rate.hp+bonus);
+ if (ud && ud->walktimer != INVALID_TIMER)
+ rate/=2;
+ // Homun HP regen fix (they should regen as if they were sitting (twice as fast)
+ if(bl->type==BL_HOM) rate *=2;
+
+ regen->tick.hp += rate;
+
+ if(regen->tick.hp >= (unsigned int)battle_config.natural_healhp_interval)
+ {
+ val = 0;
+ do {
+ val += regen->hp;
+ regen->tick.hp -= battle_config.natural_healhp_interval;
+ } while(regen->tick.hp >= (unsigned int)battle_config.natural_healhp_interval);
+ if (status_heal(bl, val, 0, 1) < val)
+ flag&=~RGN_SHP; //full.
+ }
+ }
+
+ //Natural SP regen
+ if(flag&RGN_SP)
+ {
+ rate = natural_heal_diff_tick*(regen->rate.sp+bonus);
+ // Homun SP regen fix (they should regen as if they were sitting (twice as fast)
+ if(bl->type==BL_HOM) rate *=2;
+
+ regen->tick.sp += rate;
+
+ if(regen->tick.sp >= (unsigned int)battle_config.natural_healsp_interval)
+ {
+ val = 0;
+ do {
+ val += regen->sp;
+ regen->tick.sp -= battle_config.natural_healsp_interval;
+ } while(regen->tick.sp >= (unsigned int)battle_config.natural_healsp_interval);
+ if (status_heal(bl, 0, val, 1) < val)
+ flag&=~RGN_SSP; //full.
+ }
+ }
- if (!regen->sregen)
- return flag;
+ if (!regen->sregen)
+ return flag;
- //Skill regen
- sregen = regen->sregen;
+ //Skill regen
+ sregen = regen->sregen;
- if (flag&RGN_SHP) {
- //Skill HP regen
- sregen->tick.hp += natural_heal_diff_tick * sregen->rate.hp;
+ if(flag&RGN_SHP)
+ { //Skill HP regen
+ sregen->tick.hp += natural_heal_diff_tick * sregen->rate.hp;
- while (sregen->tick.hp >= (unsigned int)battle_config.natural_heal_skill_interval) {
- sregen->tick.hp -= battle_config.natural_heal_skill_interval;
- if (status_heal(bl, sregen->hp, 0, 3) < sregen->hp)
- break; //Full
- }
- }
- if (flag&RGN_SSP) {
- //Skill SP regen
- sregen->tick.sp += natural_heal_diff_tick * sregen->rate.sp;
- while (sregen->tick.sp >= (unsigned int)battle_config.natural_heal_skill_interval) {
- val = sregen->sp;
- if (sd && sd->state.doridori) {
- val*=2;
- sd->state.doridori = 0;
- if ((rate = pc_checkskill(sd,TK_SPTIME)))
- sc_start(bl,status_skill2sc(TK_SPTIME),
- 100,rate,skill_get_time(TK_SPTIME, rate));
- if (
- (sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR &&
- rnd()%10000 < battle_config.sg_angel_skill_ratio
- ) { //Angel of the Sun/Moon/Star
- clif_feel_hate_reset(sd);
- pc_resethate(sd);
- pc_resetfeel(sd);
- }
- }
- sregen->tick.sp -= battle_config.natural_heal_skill_interval;
- if (status_heal(bl, 0, val, 3) < val)
- break; //Full
- }
- }
- return flag;
+ while(sregen->tick.hp >= (unsigned int)battle_config.natural_heal_skill_interval)
+ {
+ sregen->tick.hp -= battle_config.natural_heal_skill_interval;
+ if(status_heal(bl, sregen->hp, 0, 3) < sregen->hp)
+ break; //Full
+ }
+ }
+ if(flag&RGN_SSP)
+ { //Skill SP regen
+ sregen->tick.sp += natural_heal_diff_tick * sregen->rate.sp;
+ while(sregen->tick.sp >= (unsigned int)battle_config.natural_heal_skill_interval)
+ {
+ val = sregen->sp;
+ if (sd && sd->state.doridori) {
+ val*=2;
+ sd->state.doridori = 0;
+ if ((rate = pc_checkskill(sd,TK_SPTIME)))
+ sc_start(bl,status_skill2sc(TK_SPTIME),
+ 100,rate,skill_get_time(TK_SPTIME, rate));
+ if (
+ (sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR &&
+ rnd()%10000 < battle_config.sg_angel_skill_ratio
+ ) { //Angel of the Sun/Moon/Star
+ clif_feel_hate_reset(sd);
+ pc_resethate(sd);
+ pc_resetfeel(sd);
+ }
+ }
+ sregen->tick.sp -= battle_config.natural_heal_skill_interval;
+ if(status_heal(bl, 0, val, 3) < val)
+ break; //Full
+ }
+ }
+ return flag;
}
//Natural heal main timer.
static int status_natural_heal_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- natural_heal_diff_tick = DIFF_TICK(tick,natural_heal_prev_tick);
- map_foreachregen(status_natural_heal);
- natural_heal_prev_tick = tick;
- return 0;
+ natural_heal_diff_tick = DIFF_TICK(tick,natural_heal_prev_tick);
+ map_foreachregen(status_natural_heal);
+ natural_heal_prev_tick = tick;
+ return 0;
}
/**
@@ -11014,13 +10967,12 @@ static int status_natural_heal_timer(int tid, unsigned int tick, int id, intptr_
* @param refine The target refine level
* @return The chance to refine the item, in percent (0~100)
**/
-int status_get_refine_chance(enum refine_type wlv, int refine)
-{
+int status_get_refine_chance(enum refine_type wlv, int refine) {
- if (refine < 0 || refine >= MAX_REFINE)
- return 0;
+ if ( refine < 0 || refine >= MAX_REFINE)
+ return 0;
- return refine_info[wlv].chance[refine];
+ return refine_info[wlv].chance[refine];
}
@@ -11031,94 +10983,98 @@ int status_get_refine_chance(enum refine_type wlv, int refine)
* size_fix.txt - size adjustment table for weapons
* refine_db.txt - refining data table
*------------------------------------------*/
-static bool status_readdb_job1(char *fields[], int columns, int current)
-{
- // Job-specific values (weight, HP, SP, ASPD)
- int idx, class_;
- unsigned int i;
-
- class_ = atoi(fields[0]);
-
- if (!pcdb_checkid(class_)) {
- ShowWarning("status_readdb_job1: Invalid job class %d specified.\n", class_);
- return false;
- }
- idx = pc_class2idx(class_);
-
- max_weight_base[idx] = atoi(fields[1]);
- hp_coefficient[idx] = atoi(fields[2]);
- hp_coefficient2[idx] = atoi(fields[3]);
- sp_coefficient[idx] = atoi(fields[4]);
+static bool status_readdb_job1(char* fields[], int columns, int current)
+{// Job-specific values (weight, HP, SP, ASPD)
+ int idx, class_;
+ unsigned int i;
+
+ class_ = atoi(fields[0]);
+
+ if(!pcdb_checkid(class_))
+ {
+ ShowWarning("status_readdb_job1: Invalid job class %d specified.\n", class_);
+ return false;
+ }
+ idx = pc_class2idx(class_);
+
+ max_weight_base[idx] = atoi(fields[1]);
+ hp_coefficient[idx] = atoi(fields[2]);
+ hp_coefficient2[idx] = atoi(fields[3]);
+ sp_coefficient[idx] = atoi(fields[4]);
#ifdef RENEWAL_ASPD
- for (i = 0; i <= MAX_WEAPON_TYPE; i++)
+ for(i = 0; i <= MAX_WEAPON_TYPE; i++)
#else
- for (i = 0; i < MAX_WEAPON_TYPE; i++)
+ for(i = 0; i < MAX_WEAPON_TYPE; i++)
#endif
- {
- aspd_base[idx][i] = atoi(fields[i+5]);
- }
- return true;
+ {
+ aspd_base[idx][i] = atoi(fields[i+5]);
+ }
+ return true;
}
-static bool status_readdb_job2(char *fields[], int columns, int current)
+static bool status_readdb_job2(char* fields[], int columns, int current)
{
- int idx, class_, i;
-
- class_ = atoi(fields[0]);
-
- if (!pcdb_checkid(class_)) {
- ShowWarning("status_readdb_job2: Invalid job class %d specified.\n", class_);
- return false;
- }
- idx = pc_class2idx(class_);
-
- for (i = 1; i < columns; i++) {
- job_bonus[idx][i-1] = atoi(fields[i]);
- }
- return true;
+ int idx, class_, i;
+
+ class_ = atoi(fields[0]);
+
+ if(!pcdb_checkid(class_))
+ {
+ ShowWarning("status_readdb_job2: Invalid job class %d specified.\n", class_);
+ return false;
+ }
+ idx = pc_class2idx(class_);
+
+ for(i = 1; i < columns; i++)
+ {
+ job_bonus[idx][i-1] = atoi(fields[i]);
+ }
+ return true;
}
-static bool status_readdb_sizefix(char *fields[], int columns, int current)
+static bool status_readdb_sizefix(char* fields[], int columns, int current)
{
- unsigned int i;
+ unsigned int i;
- for (i = 0; i < MAX_WEAPON_TYPE; i++) {
- atkmods[current][i] = atoi(fields[i]);
- }
- return true;
+ for(i = 0; i < MAX_WEAPON_TYPE; i++)
+ {
+ atkmods[current][i] = atoi(fields[i]);
+ }
+ return true;
}
-static bool status_readdb_refine(char *fields[], int columns, int current)
+static bool status_readdb_refine(char* fields[], int columns, int current)
{
- int i, bonus_per_level, random_bonus, random_bonus_start_level;
+ int i, bonus_per_level, random_bonus, random_bonus_start_level;
- current = atoi(fields[0]);
+ current = atoi(fields[0]);
- if (current < 0 || current >= REFINE_TYPE_MAX)
- return false;
+ if (current < 0 || current >= REFINE_TYPE_MAX)
+ return false;
- bonus_per_level = atoi(fields[1]);
- random_bonus_start_level = atoi(fields[2]);
- random_bonus = atoi(fields[3]);
+ bonus_per_level = atoi(fields[1]);
+ random_bonus_start_level = atoi(fields[2]);
+ random_bonus = atoi(fields[3]);
- for (i = 0; i < MAX_REFINE; i++) {
- char *delim;
+ for(i = 0; i < MAX_REFINE; i++)
+ {
+ char* delim;
- if (!(delim = strchr(fields[4+i], ':')))
- return false;
+ if (!(delim = strchr(fields[4+i], ':')))
+ return false;
- *delim = '\0';
+ *delim = '\0';
- refine_info[current].chance[i] = atoi(fields[4+i]);
+ refine_info[current].chance[i] = atoi(fields[4+i]);
- if (i >= random_bonus_start_level - 1)
- refine_info[current].randombonus_max[i] = random_bonus * (i - random_bonus_start_level + 2);
+ if (i >= random_bonus_start_level - 1)
+ refine_info[current].randombonus_max[i] = random_bonus * (i - random_bonus_start_level + 2);
- refine_info[current].bonus[i] = bonus_per_level + atoi(delim+1);
- if (i > 0)
- refine_info[current].bonus[i] += refine_info[current].bonus[i-1];
- }
- return true;
+ refine_info[current].bonus[i] = bonus_per_level + atoi(delim+1);
+ if (i > 0)
+ refine_info[current].bonus[i] += refine_info[current].bonus[i-1];
+ }
+ return true;
}
/*
@@ -11130,48 +11086,50 @@ static bool status_readdb_refine(char *fields[], int columns, int current)
*/
int status_readdb(void)
{
- int i, j;
-
- // initialize databases to default
- //
-
- // reset job_db1.txt data
- memset(max_weight_base, 0, sizeof(max_weight_base));
- memset(hp_coefficient, 0, sizeof(hp_coefficient));
- memset(hp_coefficient2, 0, sizeof(hp_coefficient2));
- memset(sp_coefficient, 0, sizeof(sp_coefficient));
- memset(aspd_base, 0, sizeof(aspd_base));
- // reset job_db2.txt data
- memset(job_bonus,0,sizeof(job_bonus)); // Job-specific stats bonus
-
- // size_fix.txt
- for (i=0; i<ARRAYLENGTH(atkmods); i++)
- for (j=0; j<MAX_WEAPON_TYPE; j++)
- atkmods[i][j]=100;
-
- // refine_db.txt
- for (i=0; i<ARRAYLENGTH(refine_info); i++) {
- for (j=0; j<MAX_REFINE; j++) {
- refine_info[i].chance[j] = 100;
- refine_info[i].bonus[j] = 0;
- refine_info[i].randombonus_max[j] = 0;
- }
- }
+ int i, j;
+
+ // initialize databases to default
+ //
+
+ // reset job_db1.txt data
+ memset(max_weight_base, 0, sizeof(max_weight_base));
+ memset(hp_coefficient, 0, sizeof(hp_coefficient));
+ memset(hp_coefficient2, 0, sizeof(hp_coefficient2));
+ memset(sp_coefficient, 0, sizeof(sp_coefficient));
+ memset(aspd_base, 0, sizeof(aspd_base));
+ // reset job_db2.txt data
+ memset(job_bonus,0,sizeof(job_bonus)); // Job-specific stats bonus
+
+ // size_fix.txt
+ for(i=0;i<ARRAYLENGTH(atkmods);i++)
+ for(j=0;j<MAX_WEAPON_TYPE;j++)
+ atkmods[i][j]=100;
+
+ // refine_db.txt
+ for(i=0;i<ARRAYLENGTH(refine_info);i++)
+ {
+ for(j=0;j<MAX_REFINE; j++)
+ {
+ refine_info[i].chance[j] = 100;
+ refine_info[i].bonus[j] = 0;
+ refine_info[i].randombonus_max[j] = 0;
+ }
+ }
- // read databases
- //
+ // read databases
+ //
#ifdef RENEWAL_ASPD
- sv_readdb(db_path, "re/job_db1.txt", ',', 6+MAX_WEAPON_TYPE, 6+MAX_WEAPON_TYPE, -1, &status_readdb_job1);
+ sv_readdb(db_path, "re/job_db1.txt", ',', 6+MAX_WEAPON_TYPE, 6+MAX_WEAPON_TYPE, -1, &status_readdb_job1);
#else
- sv_readdb(db_path, "pre-re/job_db1.txt", ',', 5+MAX_WEAPON_TYPE, 5+MAX_WEAPON_TYPE, -1, &status_readdb_job1);
+ sv_readdb(db_path, "pre-re/job_db1.txt", ',', 5+MAX_WEAPON_TYPE, 5+MAX_WEAPON_TYPE, -1, &status_readdb_job1);
#endif
- sv_readdb(db_path, "job_db2.txt", ',', 1, 1+MAX_LEVEL, -1, &status_readdb_job2);
- sv_readdb(db_path, "size_fix.txt", ',', MAX_WEAPON_TYPE, MAX_WEAPON_TYPE, ARRAYLENGTH(atkmods), &status_readdb_sizefix);
- sv_readdb(db_path, DBPATH"refine_db.txt", ',', 4+MAX_REFINE, 4+MAX_REFINE, ARRAYLENGTH(refine_info), &status_readdb_refine);
+ sv_readdb(db_path, "job_db2.txt", ',', 1, 1+MAX_LEVEL, -1, &status_readdb_job2);
+ sv_readdb(db_path, "size_fix.txt", ',', MAX_WEAPON_TYPE, MAX_WEAPON_TYPE, ARRAYLENGTH(atkmods), &status_readdb_sizefix);
+ sv_readdb(db_path, DBPATH"refine_db.txt", ',', 4+MAX_REFINE, 4+MAX_REFINE, ARRAYLENGTH(refine_info), &status_readdb_refine);
- return 0;
+ return 0;
}
/*==========================================
@@ -11179,19 +11137,19 @@ int status_readdb(void)
*------------------------------------------*/
int do_init_status(void)
{
- add_timer_func_list(status_change_timer,"status_change_timer");
- add_timer_func_list(kaahi_heal_timer,"kaahi_heal_timer");
- add_timer_func_list(status_natural_heal_timer,"status_natural_heal_timer");
- initChangeTables();
- initDummyData();
- status_readdb();
- status_calc_sigma();
- natural_heal_prev_tick = gettick();
- sc_data_ers = ers_new(sizeof(struct status_change_entry),"status.c::sc_data_ers",ERS_OPT_NONE);
- add_timer_interval(natural_heal_prev_tick + NATURAL_HEAL_INTERVAL, status_natural_heal_timer, 0, 0, NATURAL_HEAL_INTERVAL);
- return 0;
+ add_timer_func_list(status_change_timer,"status_change_timer");
+ add_timer_func_list(kaahi_heal_timer,"kaahi_heal_timer");
+ add_timer_func_list(status_natural_heal_timer,"status_natural_heal_timer");
+ initChangeTables();
+ initDummyData();
+ status_readdb();
+ status_calc_sigma();
+ natural_heal_prev_tick = gettick();
+ sc_data_ers = ers_new(sizeof(struct status_change_entry),"status.c::sc_data_ers",ERS_OPT_NONE);
+ add_timer_interval(natural_heal_prev_tick + NATURAL_HEAL_INTERVAL, status_natural_heal_timer, 0, 0, NATURAL_HEAL_INTERVAL);
+ return 0;
}
void do_final_status(void)
{
- ers_destroy(sc_data_ers);
+ ers_destroy(sc_data_ers);
}
diff --git a/src/map/status.h b/src/map/status.h
index 130b858e0..402dfc690 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -16,628 +16,628 @@ struct status_change;
* Changing this limit requires edits to refine_db.txt
**/
#ifdef RENEWAL
-# define MAX_REFINE 20
+# define MAX_REFINE 20
#else
-# define MAX_REFINE 10
+# define MAX_REFINE 10
#endif
enum refine_type {
- REFINE_TYPE_ARMOR = 0,
- REFINE_TYPE_WEAPON1 = 1,
- REFINE_TYPE_WEAPON2 = 2,
- REFINE_TYPE_WEAPON3 = 3,
- REFINE_TYPE_WEAPON4 = 4,
+ REFINE_TYPE_ARMOR = 0,
+ REFINE_TYPE_WEAPON1 = 1,
+ REFINE_TYPE_WEAPON2 = 2,
+ REFINE_TYPE_WEAPON3 = 3,
+ REFINE_TYPE_WEAPON4 = 4,
- REFINE_TYPE_MAX = 5
+ REFINE_TYPE_MAX = 5
};
int status_get_refine_chance(enum refine_type wlv, int refine);
-// Status changes listing. These code are for use by the server.
+// Status changes listing. These code are for use by the server.
typedef enum sc_type {
- SC_NONE = -1,
+ SC_NONE = -1,
- //First we enumerate common status ailments which are often used around.
- SC_STONE = 0,
- SC_COMMON_MIN = 0, // begin
- SC_FREEZE,
- SC_STUN,
- SC_SLEEP,
- SC_POISON,
- SC_CURSE,
- SC_SILENCE,
- SC_CONFUSION,
- SC_BLIND,
- SC_BLEEDING,
- SC_DPOISON, //10
- SC_COMMON_MAX = 10, // end
+ //First we enumerate common status ailments which are often used around.
+ SC_STONE = 0,
+ SC_COMMON_MIN = 0, // begin
+ SC_FREEZE,
+ SC_STUN,
+ SC_SLEEP,
+ SC_POISON,
+ SC_CURSE,
+ SC_SILENCE,
+ SC_CONFUSION,
+ SC_BLIND,
+ SC_BLEEDING,
+ SC_DPOISON, //10
+ SC_COMMON_MAX = 10, // end
+
+ //Next up, we continue on 20, to leave enough room for additional "common" ailments in the future.
+ SC_PROVOKE = 20,
+ SC_ENDURE,
+ SC_TWOHANDQUICKEN,
+ SC_CONCENTRATE,
+ SC_HIDING,
+ SC_CLOAKING,
+ SC_ENCPOISON,
+ SC_POISONREACT,
+ SC_QUAGMIRE,
+ SC_ANGELUS,
+ SC_BLESSING, //30
+ SC_SIGNUMCRUCIS,
+ SC_INCREASEAGI,
+ SC_DECREASEAGI,
+ SC_SLOWPOISON,
+ SC_IMPOSITIO ,
+ SC_SUFFRAGIUM,
+ SC_ASPERSIO,
+ SC_BENEDICTIO,
+ SC_KYRIE,
+ SC_MAGNIFICAT, //40
+ SC_GLORIA,
+ SC_AETERNA,
+ SC_ADRENALINE,
+ SC_WEAPONPERFECTION,
+ SC_OVERTHRUST,
+ SC_MAXIMIZEPOWER,
+ SC_TRICKDEAD,
+ SC_LOUD,
+ SC_ENERGYCOAT,
+ SC_BROKENARMOR, //50 - NOTE: These two aren't used anywhere, and they have an icon...
+ SC_BROKENWEAPON,
+ SC_HALLUCINATION,
+ SC_WEIGHT50,
+ SC_WEIGHT90,
+ SC_ASPDPOTION0,
+ SC_ASPDPOTION1,
+ SC_ASPDPOTION2,
+ SC_ASPDPOTION3,
+ SC_SPEEDUP0,
+ SC_SPEEDUP1, //60
+ SC_ATKPOTION,
+ SC_MATKPOTION,
+ SC_WEDDING,
+ SC_SLOWDOWN,
+ SC_ANKLE,
+ SC_KEEPING,
+ SC_BARRIER,
+ SC_STRIPWEAPON,
+ SC_STRIPSHIELD,
+ SC_STRIPARMOR, //70
+ SC_STRIPHELM,
+ SC_CP_WEAPON,
+ SC_CP_SHIELD,
+ SC_CP_ARMOR,
+ SC_CP_HELM,
+ SC_AUTOGUARD,
+ SC_REFLECTSHIELD,
+ SC_SPLASHER,
+ SC_PROVIDENCE,
+ SC_DEFENDER, //80
+ SC_MAGICROD,
+ SC_SPELLBREAKER,
+ SC_AUTOSPELL,
+ SC_SIGHTTRASHER,
+ SC_AUTOBERSERK,
+ SC_SPEARQUICKEN,
+ SC_AUTOCOUNTER,
+ SC_SIGHT,
+ SC_SAFETYWALL,
+ SC_RUWACH, //90
+ SC_EXTREMITYFIST,
+ SC_EXPLOSIONSPIRITS,
+ SC_COMBO,
+ SC_BLADESTOP_WAIT,
+ SC_BLADESTOP,
+ SC_FIREWEAPON,
+ SC_WATERWEAPON,
+ SC_WINDWEAPON,
+ SC_EARTHWEAPON,
+ SC_VOLCANO, //100,
+ SC_DELUGE,
+ SC_VIOLENTGALE,
+ SC_WATK_ELEMENT,
+ SC_ARMOR,
+ SC_ARMOR_ELEMENT,
+ SC_NOCHAT,
+ SC_BABY,
+ SC_AURABLADE,
+ SC_PARRYING,
+ SC_CONCENTRATION, //110
+ SC_TENSIONRELAX,
+ SC_BERSERK,
+ SC_FURY,
+ SC_GOSPEL,
+ SC_ASSUMPTIO,
+ SC_BASILICA,
+ SC_GUILDAURA,
+ SC_MAGICPOWER,
+ SC_EDP,
+ SC_TRUESIGHT, //120
+ SC_WINDWALK,
+ SC_MELTDOWN,
+ SC_CARTBOOST,
+ SC_CHASEWALK,
+ SC_REJECTSWORD,
+ SC_MARIONETTE,
+ SC_MARIONETTE2,
+ SC_CHANGEUNDEAD,
+ SC_JOINTBEAT,
+ SC_MINDBREAKER, //130
+ SC_MEMORIZE,
+ SC_FOGWALL,
+ SC_SPIDERWEB,
+ SC_DEVOTION,
+ SC_SACRIFICE,
+ SC_STEELBODY,
+ SC_ORCISH,
+ SC_READYSTORM,
+ SC_READYDOWN,
+ SC_READYTURN, //140
+ SC_READYCOUNTER,
+ SC_DODGE,
+ SC_RUN,
+ SC_SHADOWWEAPON,
+ SC_ADRENALINE2,
+ SC_GHOSTWEAPON,
+ SC_KAIZEL,
+ SC_KAAHI,
+ SC_KAUPE,
+ SC_ONEHAND, //150
+ SC_PRESERVE,
+ SC_BATTLEORDERS,
+ SC_REGENERATION,
+ SC_DOUBLECAST,
+ SC_GRAVITATION,
+ SC_MAXOVERTHRUST,
+ SC_LONGING,
+ SC_HERMODE,
+ SC_SHRINK,
+ SC_SIGHTBLASTER, //160
+ SC_WINKCHARM,
+ SC_CLOSECONFINE,
+ SC_CLOSECONFINE2,
+ SC_DANCING,
+ SC_ELEMENTALCHANGE,
+ SC_RICHMANKIM,
+ SC_ETERNALCHAOS,
+ SC_DRUMBATTLE,
+ SC_NIBELUNGEN,
+ SC_ROKISWEIL, //170
+ SC_INTOABYSS,
+ SC_SIEGFRIED,
+ SC_WHISTLE,
+ SC_ASSNCROS,
+ SC_POEMBRAGI,
+ SC_APPLEIDUN,
+ SC_MODECHANGE,
+ SC_HUMMING,
+ SC_DONTFORGETME,
+ SC_FORTUNE, //180
+ SC_SERVICE4U,
+ SC_STOP, //Prevents inflicted chars from walking. [Skotlex]
+ SC_SPURT,
+ SC_SPIRIT,
+ SC_COMA, //Not a real SC_, it makes a char's HP/SP hit 1.
+ SC_INTRAVISION,
+ SC_INCALLSTATUS,
+ SC_INCSTR,
+ SC_INCAGI,
+ SC_INCVIT, //190
+ SC_INCINT,
+ SC_INCDEX,
+ SC_INCLUK,
+ SC_INCHIT,
+ SC_INCHITRATE,
+ SC_INCFLEE,
+ SC_INCFLEERATE,
+ SC_INCMHPRATE,
+ SC_INCMSPRATE,
+ SC_INCATKRATE, //200
+ SC_INCMATKRATE,
+ SC_INCDEFRATE,
+ SC_STRFOOD,
+ SC_AGIFOOD,
+ SC_VITFOOD,
+ SC_INTFOOD,
+ SC_DEXFOOD,
+ SC_LUKFOOD,
+ SC_HITFOOD,
+ SC_FLEEFOOD, //210
+ SC_BATKFOOD,
+ SC_WATKFOOD,
+ SC_MATKFOOD,
+ SC_SCRESIST, //Increases resistance to status changes.
+ SC_XMAS, // Xmas Suit [Valaris]
+ SC_WARM, //SG skills [Komurka]
+ SC_SUN_COMFORT,
+ SC_MOON_COMFORT,
+ SC_STAR_COMFORT,
+ SC_FUSION, //220
+ SC_SKILLRATE_UP,
+ SC_SKE,
+ SC_KAITE,
+ SC_SWOO, // [marquis007]
+ SC_SKA, // [marquis007]
+ SC_EARTHSCROLL,
+ SC_MIRACLE, //SG 'hidden' skill [Komurka]
+ SC_MADNESSCANCEL,
+ SC_ADJUSTMENT,
+ SC_INCREASING, //230
+ SC_GATLINGFEVER,
+ SC_TATAMIGAESHI,
+ SC_UTSUSEMI,
+ SC_BUNSINJYUTSU,
+ SC_KAENSIN,
+ SC_SUITON,
+ SC_NEN,
+ SC_KNOWLEDGE,
+ SC_SMA,
+ SC_FLING, //240
+ SC_AVOID,
+ SC_CHANGE,
+ SC_BLOODLUST,
+ SC_FLEET,
+ SC_SPEED,
+ SC_DEFENCE,
+ SC_INCASPDRATE,
+ SC_INCFLEE2 = 248,
+ SC_JAILED,
+ SC_ENCHANTARMS, //250
+ SC_MAGICALATTACK,
+ SC_ARMORCHANGE,
+ SC_CRITICALWOUND,
+ SC_MAGICMIRROR,
+ SC_SLOWCAST,
+ SC_SUMMER,
+ SC_EXPBOOST,
+ SC_ITEMBOOST,
+ SC_BOSSMAPINFO,
+ SC_LIFEINSURANCE, //260
+ SC_INCCRI,
+ //SC_INCDEF,
+ //SC_INCBASEATK = 263,
+ //SC_FASTCAST,
+ SC_MDEF_RATE = 265,
+ //SC_HPREGEN,
+ SC_INCHEALRATE = 267,
+ SC_PNEUMA,
+ SC_AUTOTRADE,
+ SC_KSPROTECTED, //270
+ SC_ARMOR_RESIST = 271,
+ SC_SPCOST_RATE,
+ SC_COMMONSC_RESIST,
+ SC_SEVENWIND,
+ SC_DEF_RATE,
+ //SC_SPREGEN,
+ SC_WALKSPEED = 277,
- //Next up, we continue on 20, to leave enough room for additional "common" ailments in the future.
- SC_PROVOKE = 20,
- SC_ENDURE,
- SC_TWOHANDQUICKEN,
- SC_CONCENTRATE,
- SC_HIDING,
- SC_CLOAKING,
- SC_ENCPOISON,
- SC_POISONREACT,
- SC_QUAGMIRE,
- SC_ANGELUS,
- SC_BLESSING, //30
- SC_SIGNUMCRUCIS,
- SC_INCREASEAGI,
- SC_DECREASEAGI,
- SC_SLOWPOISON,
- SC_IMPOSITIO ,
- SC_SUFFRAGIUM,
- SC_ASPERSIO,
- SC_BENEDICTIO,
- SC_KYRIE,
- SC_MAGNIFICAT, //40
- SC_GLORIA,
- SC_AETERNA,
- SC_ADRENALINE,
- SC_WEAPONPERFECTION,
- SC_OVERTHRUST,
- SC_MAXIMIZEPOWER,
- SC_TRICKDEAD,
- SC_LOUD,
- SC_ENERGYCOAT,
- SC_BROKENARMOR, //50 - NOTE: These two aren't used anywhere, and they have an icon...
- SC_BROKENWEAPON,
- SC_HALLUCINATION,
- SC_WEIGHT50,
- SC_WEIGHT90,
- SC_ASPDPOTION0,
- SC_ASPDPOTION1,
- SC_ASPDPOTION2,
- SC_ASPDPOTION3,
- SC_SPEEDUP0,
- SC_SPEEDUP1, //60
- SC_ATKPOTION,
- SC_MATKPOTION,
- SC_WEDDING,
- SC_SLOWDOWN,
- SC_ANKLE,
- SC_KEEPING,
- SC_BARRIER,
- SC_STRIPWEAPON,
- SC_STRIPSHIELD,
- SC_STRIPARMOR, //70
- SC_STRIPHELM,
- SC_CP_WEAPON,
- SC_CP_SHIELD,
- SC_CP_ARMOR,
- SC_CP_HELM,
- SC_AUTOGUARD,
- SC_REFLECTSHIELD,
- SC_SPLASHER,
- SC_PROVIDENCE,
- SC_DEFENDER, //80
- SC_MAGICROD,
- SC_SPELLBREAKER,
- SC_AUTOSPELL,
- SC_SIGHTTRASHER,
- SC_AUTOBERSERK,
- SC_SPEARQUICKEN,
- SC_AUTOCOUNTER,
- SC_SIGHT,
- SC_SAFETYWALL,
- SC_RUWACH, //90
- SC_EXTREMITYFIST,
- SC_EXPLOSIONSPIRITS,
- SC_COMBO,
- SC_BLADESTOP_WAIT,
- SC_BLADESTOP,
- SC_FIREWEAPON,
- SC_WATERWEAPON,
- SC_WINDWEAPON,
- SC_EARTHWEAPON,
- SC_VOLCANO, //100,
- SC_DELUGE,
- SC_VIOLENTGALE,
- SC_WATK_ELEMENT,
- SC_ARMOR,
- SC_ARMOR_ELEMENT,
- SC_NOCHAT,
- SC_BABY,
- SC_AURABLADE,
- SC_PARRYING,
- SC_CONCENTRATION, //110
- SC_TENSIONRELAX,
- SC_BERSERK,
- SC_FURY,
- SC_GOSPEL,
- SC_ASSUMPTIO,
- SC_BASILICA,
- SC_GUILDAURA,
- SC_MAGICPOWER,
- SC_EDP,
- SC_TRUESIGHT, //120
- SC_WINDWALK,
- SC_MELTDOWN,
- SC_CARTBOOST,
- SC_CHASEWALK,
- SC_REJECTSWORD,
- SC_MARIONETTE,
- SC_MARIONETTE2,
- SC_CHANGEUNDEAD,
- SC_JOINTBEAT,
- SC_MINDBREAKER, //130
- SC_MEMORIZE,
- SC_FOGWALL,
- SC_SPIDERWEB,
- SC_DEVOTION,
- SC_SACRIFICE,
- SC_STEELBODY,
- SC_ORCISH,
- SC_READYSTORM,
- SC_READYDOWN,
- SC_READYTURN, //140
- SC_READYCOUNTER,
- SC_DODGE,
- SC_RUN,
- SC_SHADOWWEAPON,
- SC_ADRENALINE2,
- SC_GHOSTWEAPON,
- SC_KAIZEL,
- SC_KAAHI,
- SC_KAUPE,
- SC_ONEHAND, //150
- SC_PRESERVE,
- SC_BATTLEORDERS,
- SC_REGENERATION,
- SC_DOUBLECAST,
- SC_GRAVITATION,
- SC_MAXOVERTHRUST,
- SC_LONGING,
- SC_HERMODE,
- SC_SHRINK,
- SC_SIGHTBLASTER, //160
- SC_WINKCHARM,
- SC_CLOSECONFINE,
- SC_CLOSECONFINE2,
- SC_DANCING,
- SC_ELEMENTALCHANGE,
- SC_RICHMANKIM,
- SC_ETERNALCHAOS,
- SC_DRUMBATTLE,
- SC_NIBELUNGEN,
- SC_ROKISWEIL, //170
- SC_INTOABYSS,
- SC_SIEGFRIED,
- SC_WHISTLE,
- SC_ASSNCROS,
- SC_POEMBRAGI,
- SC_APPLEIDUN,
- SC_MODECHANGE,
- SC_HUMMING,
- SC_DONTFORGETME,
- SC_FORTUNE, //180
- SC_SERVICE4U,
- SC_STOP, //Prevents inflicted chars from walking. [Skotlex]
- SC_SPURT,
- SC_SPIRIT,
- SC_COMA, //Not a real SC_, it makes a char's HP/SP hit 1.
- SC_INTRAVISION,
- SC_INCALLSTATUS,
- SC_INCSTR,
- SC_INCAGI,
- SC_INCVIT, //190
- SC_INCINT,
- SC_INCDEX,
- SC_INCLUK,
- SC_INCHIT,
- SC_INCHITRATE,
- SC_INCFLEE,
- SC_INCFLEERATE,
- SC_INCMHPRATE,
- SC_INCMSPRATE,
- SC_INCATKRATE, //200
- SC_INCMATKRATE,
- SC_INCDEFRATE,
- SC_STRFOOD,
- SC_AGIFOOD,
- SC_VITFOOD,
- SC_INTFOOD,
- SC_DEXFOOD,
- SC_LUKFOOD,
- SC_HITFOOD,
- SC_FLEEFOOD, //210
- SC_BATKFOOD,
- SC_WATKFOOD,
- SC_MATKFOOD,
- SC_SCRESIST, //Increases resistance to status changes.
- SC_XMAS, // Xmas Suit [Valaris]
- SC_WARM, //SG skills [Komurka]
- SC_SUN_COMFORT,
- SC_MOON_COMFORT,
- SC_STAR_COMFORT,
- SC_FUSION, //220
- SC_SKILLRATE_UP,
- SC_SKE,
- SC_KAITE,
- SC_SWOO, // [marquis007]
- SC_SKA, // [marquis007]
- SC_EARTHSCROLL,
- SC_MIRACLE, //SG 'hidden' skill [Komurka]
- SC_MADNESSCANCEL,
- SC_ADJUSTMENT,
- SC_INCREASING, //230
- SC_GATLINGFEVER,
- SC_TATAMIGAESHI,
- SC_UTSUSEMI,
- SC_BUNSINJYUTSU,
- SC_KAENSIN,
- SC_SUITON,
- SC_NEN,
- SC_KNOWLEDGE,
- SC_SMA,
- SC_FLING, //240
- SC_AVOID,
- SC_CHANGE,
- SC_BLOODLUST,
- SC_FLEET,
- SC_SPEED,
- SC_DEFENCE,
- SC_INCASPDRATE,
- SC_INCFLEE2 = 248,
- SC_JAILED,
- SC_ENCHANTARMS, //250
- SC_MAGICALATTACK,
- SC_ARMORCHANGE,
- SC_CRITICALWOUND,
- SC_MAGICMIRROR,
- SC_SLOWCAST,
- SC_SUMMER,
- SC_EXPBOOST,
- SC_ITEMBOOST,
- SC_BOSSMAPINFO,
- SC_LIFEINSURANCE, //260
- SC_INCCRI,
- //SC_INCDEF,
- //SC_INCBASEATK = 263,
- //SC_FASTCAST,
- SC_MDEF_RATE = 265,
- //SC_HPREGEN,
- SC_INCHEALRATE = 267,
- SC_PNEUMA,
- SC_AUTOTRADE,
- SC_KSPROTECTED, //270
- SC_ARMOR_RESIST = 271,
- SC_SPCOST_RATE,
- SC_COMMONSC_RESIST,
- SC_SEVENWIND,
- SC_DEF_RATE,
- //SC_SPREGEN,
- SC_WALKSPEED = 277,
+ // Mercenary Only Bonus Effects
+ SC_MERC_FLEEUP,
+ SC_MERC_ATKUP,
+ SC_MERC_HPUP, //280
+ SC_MERC_SPUP,
+ SC_MERC_HITUP,
+ SC_MERC_QUICKEN,
- // Mercenary Only Bonus Effects
- SC_MERC_FLEEUP,
- SC_MERC_ATKUP,
- SC_MERC_HPUP, //280
- SC_MERC_SPUP,
- SC_MERC_HITUP,
- SC_MERC_QUICKEN,
-
- SC_REBIRTH,
- //SC_SKILLCASTRATE, //285
- //SC_DEFRATIOATK,
- //SC_HPDRAIN,
- //SC_SKILLATKBONUS,
- SC_ITEMSCRIPT = 289,
- SC_S_LIFEPOTION, //290
- SC_L_LIFEPOTION,
- SC_JEXPBOOST,
- //SC_IGNOREDEF,
- SC_HELLPOWER = 294,
- SC_INVINCIBLE, //295
- SC_INVINCIBLEOFF,
- SC_MANU_ATK,
- SC_MANU_DEF,
- SC_SPL_ATK,
- SC_SPL_DEF, //300
- SC_MANU_MATK,
- SC_SPL_MATK,
- SC_FOOD_STR_CASH,
- SC_FOOD_AGI_CASH,
- SC_FOOD_VIT_CASH,
- SC_FOOD_DEX_CASH,
- SC_FOOD_INT_CASH,
- SC_FOOD_LUK_CASH,//308
- /**
- * 3rd
- **/
- SC_FEAR,//309
- SC_BURNING,//310
- SC_FREEZING,//311
- /**
- * Rune Knight
- **/
- SC_ENCHANTBLADE,//312
- SC_DEATHBOUND,//313
- SC_MILLENNIUMSHIELD,
- SC_CRUSHSTRIKE,//315
- SC_REFRESH,
- SC_REUSE_REFRESH,
- SC_GIANTGROWTH,
- SC_STONEHARDSKIN,
- SC_VITALITYACTIVATION,//320
- SC_STORMBLAST,
- SC_FIGHTINGSPIRIT,
- SC_ABUNDANCE,
- /**
- * Arch Bishop
- **/
- SC_ADORAMUS,
- SC_EPICLESIS,//325
- SC_ORATIO,
- SC_LAUDAAGNUS,
- SC_LAUDARAMUS,
- SC_RENOVATIO,
- SC_EXPIATIO,//330
- SC_DUPLELIGHT,
- SC_SECRAMENT,
- /**
- * Warlock
- **/
- SC_WHITEIMPRISON,
- SC_MARSHOFABYSS,
- SC_RECOGNIZEDSPELL,//335
- SC_STASIS,
- SC_SPHERE_1,
- SC_SPHERE_2,
- SC_SPHERE_3,
- SC_SPHERE_4,//340
- SC_SPHERE_5,
- SC_READING_SB,
- SC_FREEZINGSPELL,
- /**
- * Ranger
- **/
- SC_FEARBREEZE,
- SC_ELECTRICSHOCKER,//345
- SC_WUGDASH,
- SC_BITE,
- SC_CAMOUFLAGE,
- /**
- * Mechanic
- **/
- SC_ACCELERATION,
- SC_HOVERING,//350
- SC_SHAPESHIFT,
- SC_INFRAREDSCAN,
- SC_ANALYZE,
- SC_MAGNETICFIELD,
- SC_NEUTRALBARRIER,//355
- SC_NEUTRALBARRIER_MASTER,
- SC_STEALTHFIELD,
- SC_STEALTHFIELD_MASTER,
- SC_OVERHEAT,
- SC_OVERHEAT_LIMITPOINT,//360
- /**
- * Guillotine Cross
- **/
- SC_VENOMIMPRESS,
- SC_POISONINGWEAPON,
- SC_WEAPONBLOCKING,
- SC_CLOAKINGEXCEED,
- SC_HALLUCINATIONWALK,//365
- SC_HALLUCINATIONWALK_POSTDELAY,
- SC_ROLLINGCUTTER,
- SC_TOXIN,
- SC_PARALYSE,
- SC_VENOMBLEED,//370
- SC_MAGICMUSHROOM,
- SC_DEATHHURT,
- SC_PYREXIA,
- SC_OBLIVIONCURSE,
- SC_LEECHESEND,//375
- /**
- * Royal Guard
- **/
- SC_REFLECTDAMAGE,
- SC_FORCEOFVANGUARD,
- SC_SHIELDSPELL_DEF,
- SC_SHIELDSPELL_MDEF,
- SC_SHIELDSPELL_REF,//380
- SC_EXEEDBREAK,
- SC_PRESTIGE,
- SC_BANDING,
- SC_BANDING_DEFENCE,
- SC_EARTHDRIVE,//385
- SC_INSPIRATION,
- /**
- * Sorcerer
- **/
- SC_SPELLFIST,
- SC_CRYSTALIZE,
- SC_STRIKING,
- SC_WARMER,//390
- SC_VACUUM_EXTREME,
- SC_PROPERTYWALK,
- /**
- * Minstrel / Wanderer
+ SC_REBIRTH,
+ //SC_SKILLCASTRATE, //285
+ //SC_DEFRATIOATK,
+ //SC_HPDRAIN,
+ //SC_SKILLATKBONUS,
+ SC_ITEMSCRIPT = 289,
+ SC_S_LIFEPOTION, //290
+ SC_L_LIFEPOTION,
+ SC_JEXPBOOST,
+ //SC_IGNOREDEF,
+ SC_HELLPOWER = 294,
+ SC_INVINCIBLE, //295
+ SC_INVINCIBLEOFF,
+ SC_MANU_ATK,
+ SC_MANU_DEF,
+ SC_SPL_ATK,
+ SC_SPL_DEF, //300
+ SC_MANU_MATK,
+ SC_SPL_MATK,
+ SC_FOOD_STR_CASH,
+ SC_FOOD_AGI_CASH,
+ SC_FOOD_VIT_CASH,
+ SC_FOOD_DEX_CASH,
+ SC_FOOD_INT_CASH,
+ SC_FOOD_LUK_CASH,//308
+ /**
+ * 3rd
+ **/
+ SC_FEAR,//309
+ SC_BURNING,//310
+ SC_FREEZING,//311
+ /**
+ * Rune Knight
+ **/
+ SC_ENCHANTBLADE,//312
+ SC_DEATHBOUND,//313
+ SC_MILLENNIUMSHIELD,
+ SC_CRUSHSTRIKE,//315
+ SC_REFRESH,
+ SC_REUSE_REFRESH,
+ SC_GIANTGROWTH,
+ SC_STONEHARDSKIN,
+ SC_VITALITYACTIVATION,//320
+ SC_STORMBLAST,
+ SC_FIGHTINGSPIRIT,
+ SC_ABUNDANCE,
+ /**
+ * Arch Bishop
**/
- SC_SWINGDANCE,
- SC_SYMPHONYOFLOVER,
- SC_MOONLITSERENADE,//395
- SC_RUSHWINDMILL,
- SC_ECHOSONG,
- SC_HARMONIZE,
- SC_VOICEOFSIREN,
- SC_DEEPSLEEP,//400
- SC_SIRCLEOFNATURE,
- SC_GLOOMYDAY,
- SC_GLOOMYDAY_SK,
- SC_SONGOFMANA,
- SC_DANCEWITHWUG,//405
- SC_SATURDAYNIGHTFEVER,
- SC_LERADSDEW,
- SC_MELODYOFSINK,
- SC_BEYONDOFWARCRY,
- SC_UNLIMITEDHUMMINGVOICE,//410
- SC_SITDOWN_FORCE,
- SC_NETHERWORLD,
- /**
- * Sura
- **/
- SC_CRESCENTELBOW,
- SC_CURSEDCIRCLE_ATKER,
- SC_CURSEDCIRCLE_TARGET,
- SC_LIGHTNINGWALK,//416
- SC_RAISINGDRAGON,
- SC_GT_ENERGYGAIN,
- SC_GT_CHANGE,
- SC_GT_REVITALIZE,
- /**
- * Genetic
- **/
- SC_GN_CARTBOOST,//427
- SC_THORNSTRAP,
- SC_BLOODSUCKER,
- SC_SMOKEPOWDER,
- SC_TEARGAS,
- SC_MANDRAGORA,//426
- SC_STOMACHACHE,
- SC_MYSTERIOUS_POWDER,
- SC_MELON_BOMB,
- SC_BANANA_BOMB,
- SC_BANANA_BOMB_SITDOWN,//431
- SC_SAVAGE_STEAK,
- SC_COCKTAIL_WARG_BLOOD,
- SC_MINOR_BBQ,
- SC_SIROMA_ICE_TEA,
- SC_DROCERA_HERB_STEAMED,//436
- SC_PUTTI_TAILS_NOODLES,
- SC_BOOST500,
- SC_FULL_SWING_K,
- SC_MANA_PLUS,
- SC_MUSTLE_M,//441
- SC_LIFE_FORCE_F,
- SC_EXTRACT_WHITE_POTION_Z,
- SC_VITATA_500,
- SC_EXTRACT_SALAMINE_JUICE,
- /**
- * Shadow Chaser
- **/
- SC__REPRODUCE,//446
- SC__AUTOSHADOWSPELL,
- SC__SHADOWFORM,
- SC__BODYPAINT,
- SC__INVISIBILITY,
- SC__DEADLYINFECT,//451
- SC__ENERVATION,
- SC__GROOMY,
- SC__IGNORANCE,
- SC__LAZINESS,
- SC__UNLUCKY,//456
- SC__WEAKNESS,
- SC__STRIPACCESSORY,
- SC__MANHOLE,
- SC__BLOODYLUST,//460
- /**
- * Elemental Spirits
- **/
- SC_CIRCLE_OF_FIRE,
- SC_CIRCLE_OF_FIRE_OPTION,
- SC_FIRE_CLOAK,
- SC_FIRE_CLOAK_OPTION,
- SC_WATER_SCREEN,//465
- SC_WATER_SCREEN_OPTION,
- SC_WATER_DROP,
- SC_WATER_DROP_OPTION,
- SC_WATER_BARRIER,
- SC_WIND_STEP,//470
- SC_WIND_STEP_OPTION,
- SC_WIND_CURTAIN,
- SC_WIND_CURTAIN_OPTION,
- SC_ZEPHYR,
- SC_SOLID_SKIN,//475
- SC_SOLID_SKIN_OPTION,
- SC_STONE_SHIELD,
- SC_STONE_SHIELD_OPTION,
- SC_POWER_OF_GAIA,
- SC_PYROTECHNIC,//480
- SC_PYROTECHNIC_OPTION,
- SC_HEATER,
- SC_HEATER_OPTION,
- SC_TROPIC,
- SC_TROPIC_OPTION,//485
- SC_AQUAPLAY,
- SC_AQUAPLAY_OPTION,
- SC_COOLER,
- SC_COOLER_OPTION,
- SC_CHILLY_AIR,//490
- SC_CHILLY_AIR_OPTION,
- SC_GUST,
- SC_GUST_OPTION,
- SC_BLAST,
- SC_BLAST_OPTION,//495
- SC_WILD_STORM,
- SC_WILD_STORM_OPTION,
- SC_PETROLOGY,
- SC_PETROLOGY_OPTION,
- SC_CURSED_SOIL,//500
- SC_CURSED_SOIL_OPTION,
- SC_UPHEAVAL,
- SC_UPHEAVAL_OPTION,
- SC_TIDAL_WEAPON,
- SC_TIDAL_WEAPON_OPTION,//505
- SC_ROCK_CRUSHER,
- SC_ROCK_CRUSHER_ATK,
- /* Guild Aura */
- SC_LEADERSHIP,
- SC_GLORYWOUNDS,
- SC_SOULCOLD, //508
- SC_HAWKEYES,
- /* ... */
- SC_ODINS_POWER,
- SC_RAID,
- /* Sorcerer .extra */
- SC_FIRE_INSIGNIA,
- SC_WATER_INSIGNIA,
- SC_WIND_INSIGNIA, //516
- SC_EARTH_INSIGNIA,
- /* new pushcart */
- SC_PUSH_CART,
- /* Warlock Spell books */
- SC_SPELLBOOK1,
- SC_SPELLBOOK2,
- SC_SPELLBOOK3,
- SC_SPELLBOOK4,
- SC_SPELLBOOK5,
- SC_SPELLBOOK6,
- /**
- * In official server there are only 7 maximum number of spell books that can be memorized
- * To increase the maximum value just add another status type before SC_MAXSPELLBOOK (ex. SC_SPELLBOOK7, SC_SPELLBOOK8 and so on)
- **/
- SC_MAXSPELLBOOK,
- /* Max HP & SP */
- SC_INCMHP,
- SC_INCMSP,
- SC_PARTYFLEE, // 531
- /**
- * Kagerou & Oboro [malufett]
- **/
- SC_MEIKYOUSISUI,
- SC_JYUMONJIKIRI,
- SC_KYOUGAKU,
- SC_IZAYOI,
- SC_ZENKAI,
- SC_KAGEHUMI,
- SC_KYOMU,
- SC_KAGEMUSYA,
- SC_ZANGETSU,
- SC_GENSOU,
- SC_AKAITSUKI,
-
- //homon S
- SC_STYLE_CHANGE,
+ SC_ADORAMUS,
+ SC_EPICLESIS,//325
+ SC_ORATIO,
+ SC_LAUDAAGNUS,
+ SC_LAUDARAMUS,
+ SC_RENOVATIO,
+ SC_EXPIATIO,//330
+ SC_DUPLELIGHT,
+ SC_SECRAMENT,
+ /**
+ * Warlock
+ **/
+ SC_WHITEIMPRISON,
+ SC_MARSHOFABYSS,
+ SC_RECOGNIZEDSPELL,//335
+ SC_STASIS,
+ SC_SPHERE_1,
+ SC_SPHERE_2,
+ SC_SPHERE_3,
+ SC_SPHERE_4,//340
+ SC_SPHERE_5,
+ SC_READING_SB,
+ SC_FREEZINGSPELL,
+ /**
+ * Ranger
+ **/
+ SC_FEARBREEZE,
+ SC_ELECTRICSHOCKER,//345
+ SC_WUGDASH,
+ SC_BITE,
+ SC_CAMOUFLAGE,
+ /**
+ * Mechanic
+ **/
+ SC_ACCELERATION,
+ SC_HOVERING,//350
+ SC_SHAPESHIFT,
+ SC_INFRAREDSCAN,
+ SC_ANALYZE,
+ SC_MAGNETICFIELD,
+ SC_NEUTRALBARRIER,//355
+ SC_NEUTRALBARRIER_MASTER,
+ SC_STEALTHFIELD,
+ SC_STEALTHFIELD_MASTER,
+ SC_OVERHEAT,
+ SC_OVERHEAT_LIMITPOINT,//360
+ /**
+ * Guillotine Cross
+ **/
+ SC_VENOMIMPRESS,
+ SC_POISONINGWEAPON,
+ SC_WEAPONBLOCKING,
+ SC_CLOAKINGEXCEED,
+ SC_HALLUCINATIONWALK,//365
+ SC_HALLUCINATIONWALK_POSTDELAY,
+ SC_ROLLINGCUTTER,
+ SC_TOXIN,
+ SC_PARALYSE,
+ SC_VENOMBLEED,//370
+ SC_MAGICMUSHROOM,
+ SC_DEATHHURT,
+ SC_PYREXIA,
+ SC_OBLIVIONCURSE,
+ SC_LEECHESEND,//375
+ /**
+ * Royal Guard
+ **/
+ SC_REFLECTDAMAGE,
+ SC_FORCEOFVANGUARD,
+ SC_SHIELDSPELL_DEF,
+ SC_SHIELDSPELL_MDEF,
+ SC_SHIELDSPELL_REF,//380
+ SC_EXEEDBREAK,
+ SC_PRESTIGE,
+ SC_BANDING,
+ SC_BANDING_DEFENCE,
+ SC_EARTHDRIVE,//385
+ SC_INSPIRATION,
+ /**
+ * Sorcerer
+ **/
+ SC_SPELLFIST,
+ SC_CRYSTALIZE,
+ SC_STRIKING,
+ SC_WARMER,//390
+ SC_VACUUM_EXTREME,
+ SC_PROPERTYWALK,
+ /**
+ * Minstrel / Wanderer
+ **/
+ SC_SWINGDANCE,
+ SC_SYMPHONYOFLOVER,
+ SC_MOONLITSERENADE,//395
+ SC_RUSHWINDMILL,
+ SC_ECHOSONG,
+ SC_HARMONIZE,
+ SC_VOICEOFSIREN,
+ SC_DEEPSLEEP,//400
+ SC_SIRCLEOFNATURE,
+ SC_GLOOMYDAY,
+ SC_GLOOMYDAY_SK,
+ SC_SONGOFMANA,
+ SC_DANCEWITHWUG,//405
+ SC_SATURDAYNIGHTFEVER,
+ SC_LERADSDEW,
+ SC_MELODYOFSINK,
+ SC_BEYONDOFWARCRY,
+ SC_UNLIMITEDHUMMINGVOICE,//410
+ SC_SITDOWN_FORCE,
+ SC_NETHERWORLD,
+ /**
+ * Sura
+ **/
+ SC_CRESCENTELBOW,
+ SC_CURSEDCIRCLE_ATKER,
+ SC_CURSEDCIRCLE_TARGET,
+ SC_LIGHTNINGWALK,//416
+ SC_RAISINGDRAGON,
+ SC_GT_ENERGYGAIN,
+ SC_GT_CHANGE,
+ SC_GT_REVITALIZE,
+ /**
+ * Genetic
+ **/
+ SC_GN_CARTBOOST,//427
+ SC_THORNSTRAP,
+ SC_BLOODSUCKER,
+ SC_SMOKEPOWDER,
+ SC_TEARGAS,
+ SC_MANDRAGORA,//426
+ SC_STOMACHACHE,
+ SC_MYSTERIOUS_POWDER,
+ SC_MELON_BOMB,
+ SC_BANANA_BOMB,
+ SC_BANANA_BOMB_SITDOWN,//431
+ SC_SAVAGE_STEAK,
+ SC_COCKTAIL_WARG_BLOOD,
+ SC_MINOR_BBQ,
+ SC_SIROMA_ICE_TEA,
+ SC_DROCERA_HERB_STEAMED,//436
+ SC_PUTTI_TAILS_NOODLES,
+ SC_BOOST500,
+ SC_FULL_SWING_K,
+ SC_MANA_PLUS,
+ SC_MUSTLE_M,//441
+ SC_LIFE_FORCE_F,
+ SC_EXTRACT_WHITE_POTION_Z,
+ SC_VITATA_500,
+ SC_EXTRACT_SALAMINE_JUICE,
+ /**
+ * Shadow Chaser
+ **/
+ SC__REPRODUCE,//446
+ SC__AUTOSHADOWSPELL,
+ SC__SHADOWFORM,
+ SC__BODYPAINT,
+ SC__INVISIBILITY,
+ SC__DEADLYINFECT,//451
+ SC__ENERVATION,
+ SC__GROOMY,
+ SC__IGNORANCE,
+ SC__LAZINESS,
+ SC__UNLUCKY,//456
+ SC__WEAKNESS,
+ SC__STRIPACCESSORY,
+ SC__MANHOLE,
+ SC__BLOODYLUST,//460
+ /**
+ * Elemental Spirits
+ **/
+ SC_CIRCLE_OF_FIRE,
+ SC_CIRCLE_OF_FIRE_OPTION,
+ SC_FIRE_CLOAK,
+ SC_FIRE_CLOAK_OPTION,
+ SC_WATER_SCREEN,//465
+ SC_WATER_SCREEN_OPTION,
+ SC_WATER_DROP,
+ SC_WATER_DROP_OPTION,
+ SC_WATER_BARRIER,
+ SC_WIND_STEP,//470
+ SC_WIND_STEP_OPTION,
+ SC_WIND_CURTAIN,
+ SC_WIND_CURTAIN_OPTION,
+ SC_ZEPHYR,
+ SC_SOLID_SKIN,//475
+ SC_SOLID_SKIN_OPTION,
+ SC_STONE_SHIELD,
+ SC_STONE_SHIELD_OPTION,
+ SC_POWER_OF_GAIA,
+ SC_PYROTECHNIC,//480
+ SC_PYROTECHNIC_OPTION,
+ SC_HEATER,
+ SC_HEATER_OPTION,
+ SC_TROPIC,
+ SC_TROPIC_OPTION,//485
+ SC_AQUAPLAY,
+ SC_AQUAPLAY_OPTION,
+ SC_COOLER,
+ SC_COOLER_OPTION,
+ SC_CHILLY_AIR,//490
+ SC_CHILLY_AIR_OPTION,
+ SC_GUST,
+ SC_GUST_OPTION,
+ SC_BLAST,
+ SC_BLAST_OPTION,//495
+ SC_WILD_STORM,
+ SC_WILD_STORM_OPTION,
+ SC_PETROLOGY,
+ SC_PETROLOGY_OPTION,
+ SC_CURSED_SOIL,//500
+ SC_CURSED_SOIL_OPTION,
+ SC_UPHEAVAL,
+ SC_UPHEAVAL_OPTION,
+ SC_TIDAL_WEAPON,
+ SC_TIDAL_WEAPON_OPTION,//505
+ SC_ROCK_CRUSHER,
+ SC_ROCK_CRUSHER_ATK,
+ /* Guild Aura */
+ SC_LEADERSHIP,
+ SC_GLORYWOUNDS,
+ SC_SOULCOLD, //508
+ SC_HAWKEYES,
+ /* ... */
+ SC_ODINS_POWER,
+ SC_RAID,
+ /* Sorcerer .extra */
+ SC_FIRE_INSIGNIA,
+ SC_WATER_INSIGNIA,
+ SC_WIND_INSIGNIA, //516
+ SC_EARTH_INSIGNIA,
+ /* new pushcart */
+ SC_PUSH_CART,
+ /* Warlock Spell books */
+ SC_SPELLBOOK1,
+ SC_SPELLBOOK2,
+ SC_SPELLBOOK3,
+ SC_SPELLBOOK4,
+ SC_SPELLBOOK5,
+ SC_SPELLBOOK6,
+/**
+ * In official server there are only 7 maximum number of spell books that can be memorized
+ * To increase the maximum value just add another status type before SC_MAXSPELLBOOK (ex. SC_SPELLBOOK7, SC_SPELLBOOK8 and so on)
+ **/
+ SC_MAXSPELLBOOK,
+ /* Max HP & SP */
+ SC_INCMHP,
+ SC_INCMSP,
+ SC_PARTYFLEE, // 531
+ /**
+ * Kagerou & Oboro [malufett]
+ **/
+ SC_MEIKYOUSISUI,
+ SC_JYUMONJIKIRI,
+ SC_KYOUGAKU,
+ SC_IZAYOI,
+ SC_ZENKAI,
+ SC_KAGEHUMI,
+ SC_KYOMU,
+ SC_KAGEMUSYA,
+ SC_ZANGETSU,
+ SC_GENSOU,
+ SC_AKAITSUKI,
+
+ //homon S
+ SC_STYLE_CHANGE,
SC_GOLDENE_FERSE,
SC_ANGRIFFS_MODUS,
SC_ERASER_CUTTER,
- SC_OVERED_BOOST,
+ SC_OVERED_BOOST,
SC_LIGHT_OF_REGENE,
SC_ASH,
SC_GRANITIC_ARMOR,
@@ -646,753 +646,755 @@ typedef enum sc_type {
SC_PARALYSIS,
SC_PAIN_KILLER,
-
-#ifdef RENEWAL
- SC_EXTREMITYFIST2,
+
+#ifdef RENEWAL
+ SC_EXTREMITYFIST2,
#endif
- SC_MAX, //Automatically updated max, used in for's to check we are within bounds.
+ SC_MAX, //Automatically updated max, used in for's to check we are within bounds.
} sc_type;
// Official status change ids, used to display status icons on the client.
enum si_type {
- SI_BLANK = -1,
- SI_PROVOKE = 0,
- SI_ENDURE = 1,
- SI_TWOHANDQUICKEN = 2,
- SI_CONCENTRATE = 3,
- SI_HIDING = 4,
- SI_CLOAKING = 5,
- SI_ENCPOISON = 6,
- SI_POISONREACT = 7,
- SI_QUAGMIRE = 8,
- SI_ANGELUS = 9,
- SI_BLESSING = 10,
- SI_SIGNUMCRUCIS = 11,
- SI_INCREASEAGI = 12,
- SI_DECREASEAGI = 13,
- SI_SLOWPOISON = 14,
- SI_IMPOSITIO = 15,
- SI_SUFFRAGIUM = 16,
- SI_ASPERSIO = 17,
- SI_BENEDICTIO = 18,
- SI_KYRIE = 19,
- SI_MAGNIFICAT = 20,
- SI_GLORIA = 21,
- SI_AETERNA = 22,
- SI_ADRENALINE = 23,
- SI_WEAPONPERFECTION = 24,
- SI_OVERTHRUST = 25,
- SI_MAXIMIZEPOWER = 26,
- SI_RIDING = 27,
- SI_FALCON = 28,
- SI_TRICKDEAD = 29,
- SI_LOUD = 30,
- SI_ENERGYCOAT = 31,
- SI_BROKENARMOR = 32,
- SI_BROKENWEAPON = 33,
- SI_HALLUCINATION = 34,
- SI_WEIGHT50 = 35,
- SI_WEIGHT90 = 36,
- SI_ASPDPOTION0 = 37,
- SI_ASPDPOTION1 = 38,
- SI_ASPDPOTION2 = 39,
- SI_ASPDPOTIONINFINITY = 40,
- SI_SPEEDPOTION1 = 41,
- // SI_MOVHASTE_INFINITY = 42,
- // SI_AUTOCOUNTER = 43,
- // SI_SPLASHER = 44,
- // SI_ANKLESNARE = 45,
- SI_ACTIONDELAY = 46,
- // SI_NOACTION = 47,
- // SI_IMPOSSIBLEPICKUP = 48,
- // SI_BARRIER = 49,
- SI_STRIPWEAPON = 50,
- SI_STRIPSHIELD = 51,
- SI_STRIPARMOR = 52,
- SI_STRIPHELM = 53,
- SI_CP_WEAPON = 54,
- SI_CP_SHIELD = 55,
- SI_CP_ARMOR = 56,
- SI_CP_HELM = 57,
- SI_AUTOGUARD = 58,
- SI_REFLECTSHIELD = 59,
- // SI_DEVOTION = 60,
- SI_PROVIDENCE = 61,
- SI_DEFENDER = 62,
- // SI_MAGICROD = 63,
- // SI_WEAPONPROPERTY = 64,
- SI_AUTOSPELL = 65,
- // SI_SPECIALZONE = 66,
- // SI_MASK = 67,
- SI_SPEARQUICKEN = 68,
- // SI_BDPLAYING = 69,
- // SI_WHISTLE = 70,
- // SI_ASSASSINCROSS = 71,
- // SI_POEMBRAGI = 72,
- // SI_APPLEIDUN = 73,
- // SI_HUMMING = 74,
- // SI_DONTFORGETME = 75,
- // SI_FORTUNEKISS = 76,
- // SI_SERVICEFORYOU = 77,
- // SI_RICHMANKIM = 78,
- // SI_ETERNALCHAOS = 79,
- // SI_DRUMBATTLEFIELD = 80,
- // SI_RINGNIBELUNGEN = 81,
- // SI_ROKISWEIL = 82,
- // SI_INTOABYSS = 83,
- // SI_SIEGFRIED = 84,
- // SI_BLADESTOP = 85,
- SI_EXPLOSIONSPIRITS = 86,
- SI_STEELBODY = 87,
- SI_EXTREMITYFIST = 88,
- // SI_COMBOATTACK = 89,
- SI_FIREWEAPON = 90,
- SI_WATERWEAPON = 91,
- SI_WINDWEAPON = 92,
- SI_EARTHWEAPON = 93,
- // SI_MAGICATTACK = 94,
- SI_STOP = 95,
- // SI_WEAPONBRAKER = 96,
- SI_UNDEAD = 97,
- // SI_POWERUP = 98,
- // SI_AGIUP = 99,
- // SI_SIEGEMODE = 100,
- // SI_INVISIBLE = 101,
- // SI_STATUSONE = 102,
- SI_AURABLADE = 103,
- SI_PARRYING = 104,
- SI_CONCENTRATION = 105,
- SI_TENSIONRELAX = 106,
- SI_BERSERK = 107,
- // SI_SACRIFICE = 108,
- // SI_GOSPEL = 109,
- SI_ASSUMPTIO = 110,
- // SI_BASILICA = 111,
- SI_LANDENDOW = 112,
- SI_MAGICPOWER = 113,
- SI_EDP = 114,
- SI_TRUESIGHT = 115,
- SI_WINDWALK = 116,
- SI_MELTDOWN = 117,
- SI_CARTBOOST = 118,
- // SI_CHASEWALK = 119,
- SI_REJECTSWORD = 120,
- SI_MARIONETTE = 121,
- SI_MARIONETTE2 = 122,
- SI_MOONLIT = 123,
- SI_BLEEDING = 124,
- SI_JOINTBEAT = 125,
- // SI_MINDBREAKER = 126,
- // SI_MEMORIZE = 127,
- // SI_FOGWALL = 128,
- // SI_SPIDERWEB = 129,
- SI_BABY = 130,
- // SI_SUB_WEAPONPROPERTY = 131,
- SI_AUTOBERSERK = 132,
- SI_RUN = 133,
- SI_BUMP = 134,
- SI_READYSTORM = 135,
- // SI_STORMKICK_READY = 136,
- SI_READYDOWN = 137,
- // SI_DOWNKICK_READY = 138,
- SI_READYTURN = 139,
- // SI_TURNKICK_READY = 140,
- SI_READYCOUNTER = 141,
- // SI_COUNTER_READY = 142,
- SI_DODGE = 143,
- // SI_DODGE_READY = 144,
- SI_SPURT = 145,
- SI_SHADOWWEAPON = 146,
- SI_ADRENALINE2 = 147,
- SI_GHOSTWEAPON = 148,
- SI_SPIRIT = 149,
- // SI_PLUSATTACKPOWER = 150,
- // SI_PLUSMAGICPOWER = 151,
- SI_DEVIL = 152,
- SI_KAITE = 153,
- // SI_SWOO = 154,
- // SI_STAR2 = 155,
- SI_KAIZEL = 156,
- SI_KAAHI = 157,
- SI_KAUPE = 158,
- SI_SMA = 159,
- SI_NIGHT = 160,
- SI_ONEHAND = 161,
- // SI_FRIEND = 162,
- // SI_FRIENDUP = 163,
- // SI_SG_WARM = 164,
- SI_WARM = 165,
- // 166 | The three show the exact same display: ultra red character (165, 166, 167)
- // 167 | Their names would be SI_SG_SUN_WARM, SI_SG_MOON_WARM, SI_SG_STAR_WARM
- // SI_EMOTION = 168,
- SI_SUN_COMFORT = 169,
- SI_MOON_COMFORT = 170,
- SI_STAR_COMFORT = 171,
- // SI_EXPUP = 172,
- // SI_GDSKILL_BATTLEORDER = 173,
- // SI_GDSKILL_REGENERATION = 174,
- // SI_GDSKILL_POSTDELAY = 175,
- // SI_RESISTHANDICAP = 176,
- // SI_MAXHPPERCENT = 177,
- // SI_MAXSPPERCENT = 178,
- // SI_DEFENCE = 179,
- // SI_SLOWDOWN = 180,
- SI_PRESERVE = 181,
- SI_INCSTR = 182,
- // SI_NOT_EXTREMITYFIST = 183,
- SI_INTRAVISION = 184,
- // SI_MOVESLOW_POTION = 185,
- SI_DOUBLECAST = 186,
- // SI_GRAVITATION = 187,
- SI_MAXOVERTHRUST = 188,
- // SI_LONGING = 189,
- // SI_HERMODE = 190,
- SI_TAROT = 191, // the icon allows no doubt... but what is it really used for ?? [DracoRPG]
- // SI_HLIF_AVOID = 192,
- // SI_HFLI_FLEET = 193,
- // SI_HFLI_SPEED = 194,
- // SI_HLIF_CHANGE = 195,
- // SI_HAMI_BLOODLUST = 196,
- SI_SHRINK = 197,
- SI_SIGHTBLASTER = 198,
- SI_WINKCHARM = 199,
- SI_CLOSECONFINE = 200,
- SI_CLOSECONFINE2 = 201,
- // SI_DISABLEMOVE = 202,
- SI_MADNESSCANCEL = 203, //[blackhole89]
- SI_GATLINGFEVER = 204,
- SI_EARTHSCROLL = 205,
- SI_UTSUSEMI = 206,
- SI_BUNSINJYUTSU = 207,
- SI_NEN = 208,
- SI_ADJUSTMENT = 209,
- SI_ACCURACY = 210,
- // SI_NJ_SUITON = 211,
- // SI_PET = 212,
- // SI_MENTAL = 213,
- // SI_EXPMEMORY = 214,
- // SI_PERFORMANCE = 215,
- // SI_GAIN = 216,
- // SI_GRIFFON = 217,
- // SI_DRIFT = 218,
- // SI_WALLSHIFT = 219,
- // SI_REINCARNATION = 220,
- // SI_PATTACK = 221,
- // SI_PSPEED = 222,
- // SI_PDEFENSE = 223,
- // SI_PCRITICAL = 224,
- // SI_RANKING = 225,
- // SI_PTRIPLE = 226,
- // SI_DENERGY = 227,
- // SI_WAVE1 = 228,
- // SI_WAVE2 = 229,
- // SI_WAVE3 = 230,
- // SI_WAVE4 = 231,
- // SI_DAURA = 232,
- // SI_DFREEZER = 233,
- // SI_DPUNISH = 234,
- // SI_DBARRIER = 235,
- // SI_DWARNING = 236,
- // SI_MOUSEWHEEL = 237,
- // SI_DGAUGE = 238,
- // SI_DACCEL = 239,
- // SI_DBLOCK = 240,
- SI_FOODSTR = 241,
- SI_FOODAGI = 242,
- SI_FOODVIT = 243,
- SI_FOODDEX = 244,
- SI_FOODINT = 245,
- SI_FOODLUK = 246,
- SI_FOODFLEE = 247,
- SI_FOODHIT = 248,
- SI_FOODCRI = 249,
- SI_EXPBOOST = 250,
- SI_LIFEINSURANCE = 251,
- SI_ITEMBOOST = 252,
- SI_BOSSMAPINFO = 253,
- // SI_DA_ENERGY = 254,
- // SI_DA_FIRSTSLOT = 255,
- // SI_DA_HEADDEF = 256,
- // SI_DA_SPACE = 257,
- // SI_DA_TRANSFORM = 258,
- // SI_DA_ITEMREBUILD = 259,
- // SI_DA_ILLUSION = 260, //All mobs display as Turtle General
- // SI_DA_DARKPOWER = 261,
- // SI_DA_EARPLUG = 262,
- // SI_DA_CONTRACT = 263, //Bio Mob effect on you and SI_TRICKDEAD icon
- // SI_DA_BLACK = 264, //For short time blurry screen
- // SI_DA_MAGICCART = 265,
- // SI_CRYSTAL = 266,
- // SI_DA_REBUILD = 267,
- // SI_DA_EDARKNESS = 268,
- // SI_DA_EGUARDIAN = 269,
- // SI_DA_TIMEOUT = 270,
- SI_FOOD_STR_CASH = 271,
- SI_FOOD_AGI_CASH = 272,
- SI_FOOD_VIT_CASH = 273,
- SI_FOOD_DEX_CASH = 274,
- SI_FOOD_INT_CASH = 275,
- SI_FOOD_LUK_CASH = 276,
- SI_MERC_FLEEUP = 277,
- SI_MERC_ATKUP = 278,
- SI_MERC_HPUP = 279,
- SI_MERC_SPUP = 280,
- SI_MERC_HITUP = 281,
- SI_SLOWCAST = 282,
- // SI_MAGICMIRROR = 283,
- // SI_STONESKIN = 284,
- // SI_ANTIMAGIC = 285,
- SI_CRITICALWOUND = 286,
- // SI_NPC_DEFENDER = 287,
- // SI_NOACTION_WAIT = 288,
- SI_MOVHASTE_HORSE = 289,
- SI_DEF_RATE = 290,
- SI_MDEF_RATE = 291,
- SI_INCHEALRATE = 292,
- SI_S_LIFEPOTION = 293,
- SI_L_LIFEPOTION = 294,
- SI_INCCRI = 295,
- SI_PLUSAVOIDVALUE = 296,
- // SI_ATKER_ASPD = 297,
- // SI_TARGET_ASPD = 298,
- // SI_ATKER_MOVESPEED = 299,
- SI_ATKER_BLOOD = 300,
- SI_TARGET_BLOOD = 301,
- SI_ARMOR_PROPERTY = 302,
- // SI_REUSE_LIMIT_A = 303,
- SI_HELLPOWER = 304,
- // SI_STEAMPACK = 305,
- // SI_REUSE_LIMIT_B = 306,
- // SI_REUSE_LIMIT_C = 307,
- // SI_REUSE_LIMIT_D = 308,
- // SI_REUSE_LIMIT_E = 309,
- // SI_REUSE_LIMIT_F = 310,
- SI_INVINCIBLE = 311,
- SI_CASH_PLUSONLYJOBEXP = 312,
- SI_PARTYFLEE = 313,
- // SI_ANGEL_PROTECT = 314,
- SI_ENDURE_MDEF = 315,
- SI_ENCHANTBLADE = 316,
- SI_DEATHBOUND = 317,
- SI_REFRESH = 318,
- SI_GIANTGROWTH = 319,
- SI_STONEHARDSKIN = 320,
- SI_VITALITYACTIVATION = 321,
- SI_FIGHTINGSPIRIT = 322,
- SI_ABUNDANCE = 323,
- SI_REUSE_MILLENNIUMSHIELD = 324,
- SI_REUSE_CRUSHSTRIKE = 325,
- SI_REUSE_REFRESH = 326,
- SI_REUSE_STORMBLAST = 327,
- SI_VENOMIMPRESS = 328,
- SI_EPICLESIS = 329,
- SI_ORATIO = 330,
- SI_LAUDAAGNUS = 331,
- SI_LAUDARAMUS = 332,
- SI_CLOAKINGEXCEED = 333,
- SI_HALLUCINATIONWALK = 334,
- SI_HALLUCINATIONWALK_POSTDELAY = 335,
- SI_RENOVATIO = 336,
- SI_WEAPONBLOCKING = 337,
- SI_WEAPONBLOCKING_POSTDELAY = 338,
- SI_ROLLINGCUTTER = 339,
- SI_EXPIATIO = 340,
- SI_POISONINGWEAPON = 341,
- SI_TOXIN = 342,
- SI_PARALYSE = 343,
- SI_VENOMBLEED = 344,
- SI_MAGICMUSHROOM = 345,
- SI_DEATHHURT = 346,
- SI_PYREXIA = 347,
- SI_OBLIVIONCURSE = 348,
- SI_LEECHESEND = 349,
- SI_DUPLELIGHT = 350,
- SI_FROSTMISTY = 351,
- SI_FEARBREEZE = 352,
- SI_ELECTRICSHOCKER = 353,
- SI_MARSHOFABYSS = 354,
- SI_RECOGNIZEDSPELL = 355,
- SI_STASIS = 356,
- SI_WUGRIDER = 357,
- SI_WUGDASH = 358,
- SI_WUGBITE = 359,
- SI_CAMOUFLAGE = 360,
- SI_ACCELERATION = 361,
- SI_HOVERING = 362,
- SI_SPHERE_1 = 363,
- SI_SPHERE_2 = 364,
- SI_SPHERE_3 = 365,
- SI_SPHERE_4 = 366,
- SI_SPHERE_5 = 367,
- SI_MVPCARD_TAOGUNKA = 368,
- SI_MVPCARD_MISTRESS = 369,
- SI_MVPCARD_ORCHERO = 370,
- SI_MVPCARD_ORCLORD = 371,
- SI_OVERHEAT_LIMITPOINT = 372,
- SI_OVERHEAT = 373,
- SI_SHAPESHIFT = 374,
- SI_INFRAREDSCAN = 375,
- SI_MAGNETICFIELD = 376,
- SI_NEUTRALBARRIER = 377,
- SI_NEUTRALBARRIER_MASTER = 378,
- SI_STEALTHFIELD = 379,
- SI_STEALTHFIELD_MASTER = 380,
- SI_MANU_ATK = 381,
- SI_MANU_DEF = 382,
- SI_SPL_ATK = 383,
- SI_SPL_DEF = 384,
- SI_REPRODUCE = 385,
- SI_MANU_MATK = 386,
- SI_SPL_MATK = 387,
- SI_STR_SCROLL = 388,
- SI_INT_SCROLL = 389,
- SI_LG_REFLECTDAMAGE = 390,
- SI_FORCEOFVANGUARD = 391,
- SI_BUCHEDENOEL = 392,
- SI_AUTOSHADOWSPELL = 393,
- SI_SHADOWFORM = 394,
- SI_RAID = 395,
- SI_SHIELDSPELL_DEF = 396,
- SI_SHIELDSPELL_MDEF = 397,
- SI_SHIELDSPELL_REF = 398,
- SI_BODYPAINT = 399,
- SI_EXEEDBREAK = 400,
- SI_ADORAMUS = 401,
- SI_PRESTIGE = 402,
- SI_INVISIBILITY = 403,
- SI_DEADLYINFECT = 404,
- SI_BANDING = 405,
- SI_EARTHDRIVE = 406,
- SI_INSPIRATION = 407,
- SI_ENERVATION = 408,
- SI_GROOMY = 409,
- SI_RAISINGDRAGON = 410,
- SI_IGNORANCE = 411,
- SI_LAZINESS = 412,
- SI_LIGHTNINGWALK = 413,
- SI_ACARAJE = 414,
- SI_UNLUCKY = 415,
- SI_CURSEDCIRCLE_ATKER = 416,
- SI_CURSEDCIRCLE_TARGET = 417,
- SI_WEAKNESS = 418,
- SI_CRESCENTELBOW = 419,
- SI_NOEQUIPACCESSARY = 420,
- SI_STRIPACCESSARY = 421,
- SI_MANHOLE = 422,
- SI_POPECOOKIE = 423,
- SI_FALLENEMPIRE = 424,
- SI_GENTLETOUCH_ENERGYGAIN = 425,
- SI_GENTLETOUCH_CHANGE = 426,
- SI_GENTLETOUCH_REVITALIZE = 427,
- SI_BLOODYLUST = 428,
- SI_SWINGDANCE = 429,
- SI_SYMPHONYOFLOVERS = 430,
- SI_PROPERTYWALK = 431,
- SI_SPELLFIST = 432,
- SI_NETHERWORLD = 433,
- SI_VOICEOFSIREN = 434,
- SI_DEEPSLEEP = 435,
- SI_SIRCLEOFNATURE = 436,
- SI_COLD = 437,
- SI_GLOOMYDAY = 438,
- SI_SONGOFMANA = 439,
- SI_CLOUDKILL = 440,
- SI_DANCEWITHWUG = 441,
- SI_RUSHWINDMILL = 442,
- SI_ECHOSONG = 443,
- SI_HARMONIZE = 444,
- SI_STRIKING = 445,
- SI_WARMER = 446,
- SI_MOONLITSERENADE = 447,
- SI_SATURDAYNIGHTFEVER = 448,
- SI_SITDOWN_FORCE = 449,
- SI_ANALYZE = 450,
- SI_LERADSDEW = 451,
- SI_MELODYOFSINK = 452,
- SI_WARCRYOFBEYOND = 453,
- SI_UNLIMITEDHUMMINGVOICE = 454,
- SI_SPELLBOOK1 = 455,
- SI_SPELLBOOK2 = 456,
- SI_SPELLBOOK3 = 457,
- SI_FREEZE_SP = 458,
- SI_GN_TRAINING_SWORD = 459,
- SI_GN_REMODELING_CART = 460,
- SI_CARTSBOOST = 461,
- SI_FIXEDCASTINGTM_REDUCE = 462,
- SI_THORNTRAP = 463,
- SI_BLOODSUCKER = 464,
- SI_SPORE_EXPLOSION = 465,
- SI_DEMONIC_FIRE = 466,
- SI_FIRE_EXPANSION_SMOKE_POWDER = 467,
- SI_FIRE_EXPANSION_TEAR_GAS = 468,
- SI_BLOCKING_PLAY = 469,
- SI_MANDRAGORA = 470,
- SI_ACTIVATE = 471,
- SI_SECRAMENT = 472,
- SI_ASSUMPTIO2 = 473,
- SI_TK_SEVENWIND = 474,
- SI_LIMIT_ODINS_RECALL = 475,
- SI_STOMACHACHE = 476,
- SI_MYSTERIOUS_POWDER = 477,
- SI_MELON_BOMB = 478,
- SI_BANANA_BOMB_SITDOWN_POSTDELAY = 479,
- SI_PROMOTE_HEALTH_RESERCH = 480,
- SI_ENERGY_DRINK_RESERCH = 481,
- SI_EXTRACT_WHITE_POTION_Z = 482,
- SI_VITATA_500 = 483,
- SI_EXTRACT_SALAMINE_JUICE = 484,
- SI_BOOST500 = 485,
- SI_FULL_SWING_K = 486,
- SI_MANA_PLUS = 487,
- SI_MUSTLE_M = 488,
- SI_LIFE_FORCE_F = 489,
- SI_VACUUM_EXTREME = 490,
- SI_SAVAGE_STEAK = 491,
- SI_COCKTAIL_WARG_BLOOD = 492,
- SI_MINOR_BBQ = 493,
- SI_SIROMA_ICE_TEA = 494,
- SI_DROCERA_HERB_STEAMED = 495,
- SI_PUTTI_TAILS_NOODLES = 496,
- SI_BANANA_BOMB = 497,
- SI_SUMMON_AGNI = 498,
- SI_SPELLBOOK4 = 499,
- SI_SPELLBOOK5 = 500,
- SI_SPELLBOOK6 = 501,
- SI_SPELLBOOK7 = 502,
- SI_ELEMENTAL_AGGRESSIVE = 503,
- SI_RETURN_TO_ELDICASTES = 504,
- SI_BANDING_DEFENCE = 505,
- SI_SKELSCROLL = 506,
- SI_DISTRUCTIONSCROLL = 507,
- SI_ROYALSCROLL = 508,
- SI_IMMUNITYSCROLL = 509,
- SI_MYSTICSCROLL = 510,
- SI_BATTLESCROLL = 511,
- SI_ARMORSCROLL = 512,
- SI_FREYJASCROLL = 513,
- SI_SOULSCROLL = 514,
- SI_CIRCLE_OF_FIRE = 515,
- SI_CIRCLE_OF_FIRE_OPTION = 516,
- SI_FIRE_CLOAK = 517,
- SI_FIRE_CLOAK_OPTION = 518,
- SI_WATER_SCREEN = 519,
- SI_WATER_SCREEN_OPTION = 520,
- SI_WATER_DROP = 521,
- SI_WATER_DROP_OPTION = 522,
- SI_WIND_STEP = 523,
- SI_WIND_STEP_OPTION = 524,
- SI_WIND_CURTAIN = 525,
- SI_WIND_CURTAIN_OPTION = 526,
- SI_WATER_BARRIER = 527,
- SI_ZEPHYR = 528,
- SI_SOLID_SKIN = 529,
- SI_SOLID_SKIN_OPTION = 530,
- SI_STONE_SHIELD = 531,
- SI_STONE_SHIELD_OPTION = 532,
- SI_POWER_OF_GAIA = 533,
- // SI_EL_WAIT = 534,
- // SI_EL_PASSIVE = 535,
- // SI_EL_DEFENSIVE = 536,
- // SI_EL_OFFENSIVE = 537,
- // SI_EL_COST = 538,
- SI_PYROTECHNIC = 539,
- SI_PYROTECHNIC_OPTION = 540,
- SI_HEATER = 541,
- SI_HEATER_OPTION = 542,
- SI_TROPIC = 543,
- SI_TROPIC_OPTION = 544,
- SI_AQUAPLAY = 545,
- SI_AQUAPLAY_OPTION = 546,
- SI_COOLER = 547,
- SI_COOLER_OPTION = 548,
- SI_CHILLY_AIR = 549,
- SI_CHILLY_AIR_OPTION = 550,
- SI_GUST = 551,
- SI_GUST_OPTION = 552,
- SI_BLAST = 553,
- SI_BLAST_OPTION = 554,
- SI_WILD_STORM = 555,
- SI_WILD_STORM_OPTION = 556,
- SI_PETROLOGY = 557,
- SI_PETROLOGY_OPTION = 558,
- SI_CURSED_SOIL = 559,
- SI_CURSED_SOIL_OPTION = 560,
- SI_UPHEAVAL = 561,
- SI_UPHEAVAL_OPTION = 562,
- SI_TIDAL_WEAPON = 563,
- SI_TIDAL_WEAPON_OPTION = 564,
- SI_ROCK_CRUSHER = 565,
- SI_ROCK_CRUSHER_ATK = 566,
- SI_FIRE_INSIGNIA = 567,
- SI_WATER_INSIGNIA = 568,
- SI_WIND_INSIGNIA = 569,
- SI_EARTH_INSIGNIA = 570,
- SI_EQUIPED_FLOOR = 571,
- SI_GUARDIAN_RECALL = 572,
- SI_MORA_BUFF = 573,
- SI_REUSE_LIMIT_G = 574,
- SI_REUSE_LIMIT_H = 575,
- SI_NEEDLE_OF_PARALYZE = 576,
- SI_PAIN_KILLER = 577,
- SI_G_LIFEPOTION = 578,
- SI_VITALIZE_POTION = 579,
- SI_LIGHT_OF_REGENE = 580,
- SI_OVERED_BOOST = 581,
- SI_SILENT_BREEZE = 582,
- SI_ODINS_POWER = 583,
- SI_STYLE_CHANGE = 584,
- SI_SONIC_CLAW_POSTDELAY = 585,
- // ID's 586 - 595 Currently Unused
- SI_SILVERVEIN_RUSH_POSTDELAY = 596,
- SI_MIDNIGHT_FRENZY_POSTDELAY = 597,
- SI_GOLDENE_FERSE = 598,
- SI_ANGRIFFS_MODUS = 599,
- SI_TINDER_BREAKER = 600,
- SI_TINDER_BREAKER_POSTDELAY = 601,
- SI_CBC = 602,
- SI_CBC_POSTDELAY = 603,
- SI_EQC = 604,
- SI_MAGMA_FLOW = 605,
- SI_GRANITIC_ARMOR = 606,
- SI_PYROCLASTIC = 607,
- SI_VOLCANIC_ASH = 608,
- SI_SPIRITS_SAVEINFO1 = 609,
- SI_SPIRITS_SAVEINFO2 = 610,
- SI_MAGIC_CANDY = 611,
- SI_SEARCH_STORE_INFO = 612,
- SI_ALL_RIDING = 613,
- SI_ALL_RIDING_REUSE_LIMIT = 614,
- SI_MACRO = 615,
- SI_MACRO_POSTDELAY = 616,
- SI_BEER_BOTTLE_CAP = 617,
- SI_OVERLAPEXPUP = 618,
- SI_PC_IZ_DUN05 = 619,
- SI_CRUSHSTRIKE = 620,
- SI_MONSTER_TRANSFORM = 621,
- SI_SIT = 622,
- SI_ONAIR = 623,
- SI_MTF_ASPD = 624,
- SI_MTF_RANGEATK = 625,
- SI_MTF_MATK = 626,
- SI_MTF_MLEATKED = 627,
- SI_MTF_CRIDAMAGE = 628,
- SI_REUSE_LIMIT_MTF = 629,
- SI_MACRO_PERMIT = 630,
- SI_MACRO_PLAY = 631,
- SI_SKF_CAST = 632,
- SI_SKF_ASPD = 633,
- SI_SKF_ATK = 634,
- SI_SKF_MATK = 635,
- SI_REWARD_PLUSONLYJOBEXP = 636,
- SI_HANDICAPSTATE_NORECOVER = 637,
- SI_SET_NUM_DEF = 638,
- SI_SET_NUM_MDEF = 639,
- SI_SET_PER_DEF = 640,
- SI_SET_PER_MDEF = 641,
- SI_PARTYBOOKING_SEARCH_DEALY = 642,
- SI_PARTYBOOKING_REGISTER_DEALY = 643,
- SI_PERIOD_TIME_CHECK_DETECT_SKILL = 644,
- SI_KO_JYUMONJIKIRI = 645,
- SI_MEIKYOUSISUI = 646,
- SI_ATTHASTE_CASH = 647,
- SI_EQUIPPED_DIVINE_ARMOR = 648,
- SI_EQUIPPED_HOLY_ARMOR = 649,
- SI_2011RWC = 650,
- SI_KYOUGAKU = 651,
- SI_IZAYOI = 652,
- SI_ZENKAI = 653,
- SI_KG_KAGEHUMI = 654,
- SI_KYOMU = 655,
- SI_KAGEMUSYA = 656,
- SI_ZANGETSU = 657,
- SI_PHI_DEMON = 658,
- SI_GENSOU = 659,
- SI_AKAITSUKI = 660,
- SI_TETANY = 661,
- SI_GM_BATTLE = 662,
- SI_GM_BATTLE2 = 663,
- SI_2011RWC_SCROLL = 664,
- SI_ACTIVE_MONSTER_TRANSFORM = 665,
- SI_MYSTICPOWDER = 666,
- SI_ECLAGE_RECALL = 667,
- SI_ENTRY_QUEUE_APPLY_DELAY = 668,
- SI_REUSE_LIMIT_ECL = 669,
- SI_M_LIFEPOTION = 670,
- SI_ENTRY_QUEUE_NOTIFY_ADMISSION_TIME_OUT = 671,
- SI_UNKNOWN_NAME = 672,
- SI_ON_PUSH_CART = 673,
- SI_HAT_EFFECT = 674,
- SI_FLOWER_LEAF = 675,
- SI_RAY_OF_PROTECTION = 676,
- SI_GLASTHEIM_ATK = 677,
- SI_GLASTHEIM_DEF = 678,
- SI_GLASTHEIM_HEAL = 679,
- SI_GLASTHEIM_HIDDEN = 680,
- SI_GLASTHEIM_STATE = 681,
- SI_GLASTHEIM_ITEMDEF = 682,
- SI_GLASTHEIM_HPSP = 683,
- SI_HOMUN_SKILL_POSTDELAY = 684,
- SI_ALMIGHTY = 685,
- SI_GVG_GIANT = 686,
- SI_GVG_GOLEM = 687,
- SI_GVG_STUN = 688,
- SI_GVG_STONE = 689,
- SI_GVG_FREEZ = 690,
- SI_GVG_SLEEP = 691,
- SI_GVG_CURSE = 692,
- SI_GVG_SILENCE = 693,
- SI_GVG_BLIND = 694,
- SI_CLIENT_ONLY_EQUIP_ARROW = 695,
- SI_CLAN_INFO = 696,
- SI_JP_EVENT01 = 697,
- SI_JP_EVENT02 = 698,
- SI_JP_EVENT03 = 699,
- SI_JP_EVENT04 = 700,
- SI_TELEPORT_FIXEDCASTINGDELAY = 701,
- SI_GEFFEN_MAGIC1 = 702,
- SI_GEFFEN_MAGIC2 = 703,
- SI_GEFFEN_MAGIC3 = 704,
- SI_QUEST_BUFF1 = 705,
- SI_QUEST_BUFF2 = 706,
- SI_QUEST_BUFF3 = 707,
- SI_REUSE_LIMIT_RECALL = 708,
- SI_SAVEPOSITION = 709,
- SI_MAX,
+ SI_BLANK = -1,
+ SI_PROVOKE = 0,
+ SI_ENDURE = 1,
+ SI_TWOHANDQUICKEN = 2,
+ SI_CONCENTRATE = 3,
+ SI_HIDING = 4,
+ SI_CLOAKING = 5,
+ SI_ENCPOISON = 6,
+ SI_POISONREACT = 7,
+ SI_QUAGMIRE = 8,
+ SI_ANGELUS = 9,
+ SI_BLESSING = 10,
+ SI_SIGNUMCRUCIS = 11,
+ SI_INCREASEAGI = 12,
+ SI_DECREASEAGI = 13,
+ SI_SLOWPOISON = 14,
+ SI_IMPOSITIO = 15,
+ SI_SUFFRAGIUM = 16,
+ SI_ASPERSIO = 17,
+ SI_BENEDICTIO = 18,
+ SI_KYRIE = 19,
+ SI_MAGNIFICAT = 20,
+ SI_GLORIA = 21,
+ SI_AETERNA = 22,
+ SI_ADRENALINE = 23,
+ SI_WEAPONPERFECTION = 24,
+ SI_OVERTHRUST = 25,
+ SI_MAXIMIZEPOWER = 26,
+ SI_RIDING = 27,
+ SI_FALCON = 28,
+ SI_TRICKDEAD = 29,
+ SI_LOUD = 30,
+ SI_ENERGYCOAT = 31,
+ SI_BROKENARMOR = 32,
+ SI_BROKENWEAPON = 33,
+ SI_HALLUCINATION = 34,
+ SI_WEIGHT50 = 35,
+ SI_WEIGHT90 = 36,
+ SI_ASPDPOTION0 = 37,
+ SI_ASPDPOTION1 = 38,
+ SI_ASPDPOTION2 = 39,
+ SI_ASPDPOTIONINFINITY = 40,
+ SI_SPEEDPOTION1 = 41,
+// SI_MOVHASTE_INFINITY = 42,
+// SI_AUTOCOUNTER = 43,
+// SI_SPLASHER = 44,
+// SI_ANKLESNARE = 45,
+ SI_ACTIONDELAY = 46,
+// SI_NOACTION = 47,
+// SI_IMPOSSIBLEPICKUP = 48,
+// SI_BARRIER = 49,
+ SI_STRIPWEAPON = 50,
+ SI_STRIPSHIELD = 51,
+ SI_STRIPARMOR = 52,
+ SI_STRIPHELM = 53,
+ SI_CP_WEAPON = 54,
+ SI_CP_SHIELD = 55,
+ SI_CP_ARMOR = 56,
+ SI_CP_HELM = 57,
+ SI_AUTOGUARD = 58,
+ SI_REFLECTSHIELD = 59,
+// SI_DEVOTION = 60,
+ SI_PROVIDENCE = 61,
+ SI_DEFENDER = 62,
+// SI_MAGICROD = 63,
+// SI_WEAPONPROPERTY = 64,
+ SI_AUTOSPELL = 65,
+// SI_SPECIALZONE = 66,
+// SI_MASK = 67,
+ SI_SPEARQUICKEN = 68,
+// SI_BDPLAYING = 69,
+// SI_WHISTLE = 70,
+// SI_ASSASSINCROSS = 71,
+// SI_POEMBRAGI = 72,
+// SI_APPLEIDUN = 73,
+// SI_HUMMING = 74,
+// SI_DONTFORGETME = 75,
+// SI_FORTUNEKISS = 76,
+// SI_SERVICEFORYOU = 77,
+// SI_RICHMANKIM = 78,
+// SI_ETERNALCHAOS = 79,
+// SI_DRUMBATTLEFIELD = 80,
+// SI_RINGNIBELUNGEN = 81,
+// SI_ROKISWEIL = 82,
+// SI_INTOABYSS = 83,
+// SI_SIEGFRIED = 84,
+// SI_BLADESTOP = 85,
+ SI_EXPLOSIONSPIRITS = 86,
+ SI_STEELBODY = 87,
+ SI_EXTREMITYFIST = 88,
+// SI_COMBOATTACK = 89,
+ SI_FIREWEAPON = 90,
+ SI_WATERWEAPON = 91,
+ SI_WINDWEAPON = 92,
+ SI_EARTHWEAPON = 93,
+// SI_MAGICATTACK = 94,
+ SI_STOP = 95,
+// SI_WEAPONBRAKER = 96,
+ SI_UNDEAD = 97,
+// SI_POWERUP = 98,
+// SI_AGIUP = 99,
+// SI_SIEGEMODE = 100,
+// SI_INVISIBLE = 101,
+// SI_STATUSONE = 102,
+ SI_AURABLADE = 103,
+ SI_PARRYING = 104,
+ SI_CONCENTRATION = 105,
+ SI_TENSIONRELAX = 106,
+ SI_BERSERK = 107,
+// SI_SACRIFICE = 108,
+// SI_GOSPEL = 109,
+ SI_ASSUMPTIO = 110,
+// SI_BASILICA = 111,
+ SI_LANDENDOW = 112,
+ SI_MAGICPOWER = 113,
+ SI_EDP = 114,
+ SI_TRUESIGHT = 115,
+ SI_WINDWALK = 116,
+ SI_MELTDOWN = 117,
+ SI_CARTBOOST = 118,
+// SI_CHASEWALK = 119,
+ SI_REJECTSWORD = 120,
+ SI_MARIONETTE = 121,
+ SI_MARIONETTE2 = 122,
+ SI_MOONLIT = 123,
+ SI_BLEEDING = 124,
+ SI_JOINTBEAT = 125,
+// SI_MINDBREAKER = 126,
+// SI_MEMORIZE = 127,
+// SI_FOGWALL = 128,
+// SI_SPIDERWEB = 129,
+ SI_BABY = 130,
+// SI_SUB_WEAPONPROPERTY = 131,
+ SI_AUTOBERSERK = 132,
+ SI_RUN = 133,
+ SI_BUMP = 134,
+ SI_READYSTORM = 135,
+// SI_STORMKICK_READY = 136,
+ SI_READYDOWN = 137,
+// SI_DOWNKICK_READY = 138,
+ SI_READYTURN = 139,
+// SI_TURNKICK_READY = 140,
+ SI_READYCOUNTER = 141,
+// SI_COUNTER_READY = 142,
+ SI_DODGE = 143,
+// SI_DODGE_READY = 144,
+ SI_SPURT = 145,
+ SI_SHADOWWEAPON = 146,
+ SI_ADRENALINE2 = 147,
+ SI_GHOSTWEAPON = 148,
+ SI_SPIRIT = 149,
+// SI_PLUSATTACKPOWER = 150,
+// SI_PLUSMAGICPOWER = 151,
+ SI_DEVIL = 152,
+ SI_KAITE = 153,
+// SI_SWOO = 154,
+// SI_STAR2 = 155,
+ SI_KAIZEL = 156,
+ SI_KAAHI = 157,
+ SI_KAUPE = 158,
+ SI_SMA = 159,
+ SI_NIGHT = 160,
+ SI_ONEHAND = 161,
+// SI_FRIEND = 162,
+// SI_FRIENDUP = 163,
+// SI_SG_WARM = 164,
+ SI_WARM = 165,
+// 166 | The three show the exact same display: ultra red character (165, 166, 167)
+// 167 | Their names would be SI_SG_SUN_WARM, SI_SG_MOON_WARM, SI_SG_STAR_WARM
+// SI_EMOTION = 168,
+ SI_SUN_COMFORT = 169,
+ SI_MOON_COMFORT = 170,
+ SI_STAR_COMFORT = 171,
+// SI_EXPUP = 172,
+// SI_GDSKILL_BATTLEORDER = 173,
+// SI_GDSKILL_REGENERATION = 174,
+// SI_GDSKILL_POSTDELAY = 175,
+// SI_RESISTHANDICAP = 176,
+// SI_MAXHPPERCENT = 177,
+// SI_MAXSPPERCENT = 178,
+// SI_DEFENCE = 179,
+// SI_SLOWDOWN = 180,
+ SI_PRESERVE = 181,
+ SI_INCSTR = 182,
+// SI_NOT_EXTREMITYFIST = 183,
+ SI_INTRAVISION = 184,
+// SI_MOVESLOW_POTION = 185,
+ SI_DOUBLECAST = 186,
+// SI_GRAVITATION = 187,
+ SI_MAXOVERTHRUST = 188,
+// SI_LONGING = 189,
+// SI_HERMODE = 190,
+ SI_TAROT = 191, // the icon allows no doubt... but what is it really used for ?? [DracoRPG]
+// SI_HLIF_AVOID = 192,
+// SI_HFLI_FLEET = 193,
+// SI_HFLI_SPEED = 194,
+// SI_HLIF_CHANGE = 195,
+// SI_HAMI_BLOODLUST = 196,
+ SI_SHRINK = 197,
+ SI_SIGHTBLASTER = 198,
+ SI_WINKCHARM = 199,
+ SI_CLOSECONFINE = 200,
+ SI_CLOSECONFINE2 = 201,
+// SI_DISABLEMOVE = 202,
+ SI_MADNESSCANCEL = 203, //[blackhole89]
+ SI_GATLINGFEVER = 204,
+ SI_EARTHSCROLL = 205,
+ SI_UTSUSEMI = 206,
+ SI_BUNSINJYUTSU = 207,
+ SI_NEN = 208,
+ SI_ADJUSTMENT = 209,
+ SI_ACCURACY = 210,
+// SI_NJ_SUITON = 211,
+// SI_PET = 212,
+// SI_MENTAL = 213,
+// SI_EXPMEMORY = 214,
+// SI_PERFORMANCE = 215,
+// SI_GAIN = 216,
+// SI_GRIFFON = 217,
+// SI_DRIFT = 218,
+// SI_WALLSHIFT = 219,
+// SI_REINCARNATION = 220,
+// SI_PATTACK = 221,
+// SI_PSPEED = 222,
+// SI_PDEFENSE = 223,
+// SI_PCRITICAL = 224,
+// SI_RANKING = 225,
+// SI_PTRIPLE = 226,
+// SI_DENERGY = 227,
+// SI_WAVE1 = 228,
+// SI_WAVE2 = 229,
+// SI_WAVE3 = 230,
+// SI_WAVE4 = 231,
+// SI_DAURA = 232,
+// SI_DFREEZER = 233,
+// SI_DPUNISH = 234,
+// SI_DBARRIER = 235,
+// SI_DWARNING = 236,
+// SI_MOUSEWHEEL = 237,
+// SI_DGAUGE = 238,
+// SI_DACCEL = 239,
+// SI_DBLOCK = 240,
+ SI_FOODSTR = 241,
+ SI_FOODAGI = 242,
+ SI_FOODVIT = 243,
+ SI_FOODDEX = 244,
+ SI_FOODINT = 245,
+ SI_FOODLUK = 246,
+ SI_FOODFLEE = 247,
+ SI_FOODHIT = 248,
+ SI_FOODCRI = 249,
+ SI_EXPBOOST = 250,
+ SI_LIFEINSURANCE = 251,
+ SI_ITEMBOOST = 252,
+ SI_BOSSMAPINFO = 253,
+// SI_DA_ENERGY = 254,
+// SI_DA_FIRSTSLOT = 255,
+// SI_DA_HEADDEF = 256,
+// SI_DA_SPACE = 257,
+// SI_DA_TRANSFORM = 258,
+// SI_DA_ITEMREBUILD = 259,
+// SI_DA_ILLUSION = 260, //All mobs display as Turtle General
+// SI_DA_DARKPOWER = 261,
+// SI_DA_EARPLUG = 262,
+// SI_DA_CONTRACT = 263, //Bio Mob effect on you and SI_TRICKDEAD icon
+// SI_DA_BLACK = 264, //For short time blurry screen
+// SI_DA_MAGICCART = 265,
+// SI_CRYSTAL = 266,
+// SI_DA_REBUILD = 267,
+// SI_DA_EDARKNESS = 268,
+// SI_DA_EGUARDIAN = 269,
+// SI_DA_TIMEOUT = 270,
+ SI_FOOD_STR_CASH = 271,
+ SI_FOOD_AGI_CASH = 272,
+ SI_FOOD_VIT_CASH = 273,
+ SI_FOOD_DEX_CASH = 274,
+ SI_FOOD_INT_CASH = 275,
+ SI_FOOD_LUK_CASH = 276,
+ SI_MERC_FLEEUP = 277,
+ SI_MERC_ATKUP = 278,
+ SI_MERC_HPUP = 279,
+ SI_MERC_SPUP = 280,
+ SI_MERC_HITUP = 281,
+ SI_SLOWCAST = 282,
+// SI_MAGICMIRROR = 283,
+// SI_STONESKIN = 284,
+// SI_ANTIMAGIC = 285,
+ SI_CRITICALWOUND = 286,
+// SI_NPC_DEFENDER = 287,
+// SI_NOACTION_WAIT = 288,
+ SI_MOVHASTE_HORSE = 289,
+ SI_DEF_RATE = 290,
+ SI_MDEF_RATE = 291,
+ SI_INCHEALRATE = 292,
+ SI_S_LIFEPOTION = 293,
+ SI_L_LIFEPOTION = 294,
+ SI_INCCRI = 295,
+ SI_PLUSAVOIDVALUE = 296,
+// SI_ATKER_ASPD = 297,
+// SI_TARGET_ASPD = 298,
+// SI_ATKER_MOVESPEED = 299,
+ SI_ATKER_BLOOD = 300,
+ SI_TARGET_BLOOD = 301,
+ SI_ARMOR_PROPERTY = 302,
+// SI_REUSE_LIMIT_A = 303,
+ SI_HELLPOWER = 304,
+// SI_STEAMPACK = 305,
+// SI_REUSE_LIMIT_B = 306,
+// SI_REUSE_LIMIT_C = 307,
+// SI_REUSE_LIMIT_D = 308,
+// SI_REUSE_LIMIT_E = 309,
+// SI_REUSE_LIMIT_F = 310,
+ SI_INVINCIBLE = 311,
+ SI_CASH_PLUSONLYJOBEXP = 312,
+ SI_PARTYFLEE = 313,
+// SI_ANGEL_PROTECT = 314,
+ SI_ENDURE_MDEF = 315,
+ SI_ENCHANTBLADE = 316,
+ SI_DEATHBOUND = 317,
+ SI_REFRESH = 318,
+ SI_GIANTGROWTH = 319,
+ SI_STONEHARDSKIN = 320,
+ SI_VITALITYACTIVATION = 321,
+ SI_FIGHTINGSPIRIT = 322,
+ SI_ABUNDANCE = 323,
+ SI_REUSE_MILLENNIUMSHIELD = 324,
+ SI_REUSE_CRUSHSTRIKE = 325,
+ SI_REUSE_REFRESH = 326,
+ SI_REUSE_STORMBLAST = 327,
+ SI_VENOMIMPRESS = 328,
+ SI_EPICLESIS = 329,
+ SI_ORATIO = 330,
+ SI_LAUDAAGNUS = 331,
+ SI_LAUDARAMUS = 332,
+ SI_CLOAKINGEXCEED = 333,
+ SI_HALLUCINATIONWALK = 334,
+ SI_HALLUCINATIONWALK_POSTDELAY = 335,
+ SI_RENOVATIO = 336,
+ SI_WEAPONBLOCKING = 337,
+ SI_WEAPONBLOCKING_POSTDELAY = 338,
+ SI_ROLLINGCUTTER = 339,
+ SI_EXPIATIO = 340,
+ SI_POISONINGWEAPON = 341,
+ SI_TOXIN = 342,
+ SI_PARALYSE = 343,
+ SI_VENOMBLEED = 344,
+ SI_MAGICMUSHROOM = 345,
+ SI_DEATHHURT = 346,
+ SI_PYREXIA = 347,
+ SI_OBLIVIONCURSE = 348,
+ SI_LEECHESEND = 349,
+ SI_DUPLELIGHT = 350,
+ SI_FROSTMISTY = 351,
+ SI_FEARBREEZE = 352,
+ SI_ELECTRICSHOCKER = 353,
+ SI_MARSHOFABYSS = 354,
+ SI_RECOGNIZEDSPELL = 355,
+ SI_STASIS = 356,
+ SI_WUGRIDER = 357,
+ SI_WUGDASH = 358,
+ SI_WUGBITE = 359,
+ SI_CAMOUFLAGE = 360,
+ SI_ACCELERATION = 361,
+ SI_HOVERING = 362,
+ SI_SPHERE_1 = 363,
+ SI_SPHERE_2 = 364,
+ SI_SPHERE_3 = 365,
+ SI_SPHERE_4 = 366,
+ SI_SPHERE_5 = 367,
+ SI_MVPCARD_TAOGUNKA = 368,
+ SI_MVPCARD_MISTRESS = 369,
+ SI_MVPCARD_ORCHERO = 370,
+ SI_MVPCARD_ORCLORD = 371,
+ SI_OVERHEAT_LIMITPOINT = 372,
+ SI_OVERHEAT = 373,
+ SI_SHAPESHIFT = 374,
+ SI_INFRAREDSCAN = 375,
+ SI_MAGNETICFIELD = 376,
+ SI_NEUTRALBARRIER = 377,
+ SI_NEUTRALBARRIER_MASTER = 378,
+ SI_STEALTHFIELD = 379,
+ SI_STEALTHFIELD_MASTER = 380,
+ SI_MANU_ATK = 381,
+ SI_MANU_DEF = 382,
+ SI_SPL_ATK = 383,
+ SI_SPL_DEF = 384,
+ SI_REPRODUCE = 385,
+ SI_MANU_MATK = 386,
+ SI_SPL_MATK = 387,
+ SI_STR_SCROLL = 388,
+ SI_INT_SCROLL = 389,
+ SI_LG_REFLECTDAMAGE = 390,
+ SI_FORCEOFVANGUARD = 391,
+ SI_BUCHEDENOEL = 392,
+ SI_AUTOSHADOWSPELL = 393,
+ SI_SHADOWFORM = 394,
+ SI_RAID = 395,
+ SI_SHIELDSPELL_DEF = 396,
+ SI_SHIELDSPELL_MDEF = 397,
+ SI_SHIELDSPELL_REF = 398,
+ SI_BODYPAINT = 399,
+ SI_EXEEDBREAK = 400,
+ SI_ADORAMUS = 401,
+ SI_PRESTIGE = 402,
+ SI_INVISIBILITY = 403,
+ SI_DEADLYINFECT = 404,
+ SI_BANDING = 405,
+ SI_EARTHDRIVE = 406,
+ SI_INSPIRATION = 407,
+ SI_ENERVATION = 408,
+ SI_GROOMY = 409,
+ SI_RAISINGDRAGON = 410,
+ SI_IGNORANCE = 411,
+ SI_LAZINESS = 412,
+ SI_LIGHTNINGWALK = 413,
+ SI_ACARAJE = 414,
+ SI_UNLUCKY = 415,
+ SI_CURSEDCIRCLE_ATKER = 416,
+ SI_CURSEDCIRCLE_TARGET = 417,
+ SI_WEAKNESS = 418,
+ SI_CRESCENTELBOW = 419,
+ SI_NOEQUIPACCESSARY = 420,
+ SI_STRIPACCESSARY = 421,
+ SI_MANHOLE = 422,
+ SI_POPECOOKIE = 423,
+ SI_FALLENEMPIRE = 424,
+ SI_GENTLETOUCH_ENERGYGAIN = 425,
+ SI_GENTLETOUCH_CHANGE = 426,
+ SI_GENTLETOUCH_REVITALIZE = 427,
+ SI_BLOODYLUST = 428,
+ SI_SWINGDANCE = 429,
+ SI_SYMPHONYOFLOVERS = 430,
+ SI_PROPERTYWALK = 431,
+ SI_SPELLFIST = 432,
+ SI_NETHERWORLD = 433,
+ SI_VOICEOFSIREN = 434,
+ SI_DEEPSLEEP = 435,
+ SI_SIRCLEOFNATURE = 436,
+ SI_COLD = 437,
+ SI_GLOOMYDAY = 438,
+ SI_SONGOFMANA = 439,
+ SI_CLOUDKILL = 440,
+ SI_DANCEWITHWUG = 441,
+ SI_RUSHWINDMILL = 442,
+ SI_ECHOSONG = 443,
+ SI_HARMONIZE = 444,
+ SI_STRIKING = 445,
+ SI_WARMER = 446,
+ SI_MOONLITSERENADE = 447,
+ SI_SATURDAYNIGHTFEVER = 448,
+ SI_SITDOWN_FORCE = 449,
+ SI_ANALYZE = 450,
+ SI_LERADSDEW = 451,
+ SI_MELODYOFSINK = 452,
+ SI_WARCRYOFBEYOND = 453,
+ SI_UNLIMITEDHUMMINGVOICE = 454,
+ SI_SPELLBOOK1 = 455,
+ SI_SPELLBOOK2 = 456,
+ SI_SPELLBOOK3 = 457,
+ SI_FREEZE_SP = 458,
+ SI_GN_TRAINING_SWORD = 459,
+ SI_GN_REMODELING_CART = 460,
+ SI_CARTSBOOST = 461,
+ SI_FIXEDCASTINGTM_REDUCE = 462,
+ SI_THORNTRAP = 463,
+ SI_BLOODSUCKER = 464,
+ SI_SPORE_EXPLOSION = 465,
+ SI_DEMONIC_FIRE = 466,
+ SI_FIRE_EXPANSION_SMOKE_POWDER = 467,
+ SI_FIRE_EXPANSION_TEAR_GAS = 468,
+ SI_BLOCKING_PLAY = 469,
+ SI_MANDRAGORA = 470,
+ SI_ACTIVATE = 471,
+ SI_SECRAMENT = 472,
+ SI_ASSUMPTIO2 = 473,
+ SI_TK_SEVENWIND = 474,
+ SI_LIMIT_ODINS_RECALL = 475,
+ SI_STOMACHACHE = 476,
+ SI_MYSTERIOUS_POWDER = 477,
+ SI_MELON_BOMB = 478,
+ SI_BANANA_BOMB_SITDOWN_POSTDELAY = 479,
+ SI_PROMOTE_HEALTH_RESERCH = 480,
+ SI_ENERGY_DRINK_RESERCH = 481,
+ SI_EXTRACT_WHITE_POTION_Z = 482,
+ SI_VITATA_500 = 483,
+ SI_EXTRACT_SALAMINE_JUICE = 484,
+ SI_BOOST500 = 485,
+ SI_FULL_SWING_K = 486,
+ SI_MANA_PLUS = 487,
+ SI_MUSTLE_M = 488,
+ SI_LIFE_FORCE_F = 489,
+ SI_VACUUM_EXTREME = 490,
+ SI_SAVAGE_STEAK = 491,
+ SI_COCKTAIL_WARG_BLOOD = 492,
+ SI_MINOR_BBQ = 493,
+ SI_SIROMA_ICE_TEA = 494,
+ SI_DROCERA_HERB_STEAMED = 495,
+ SI_PUTTI_TAILS_NOODLES = 496,
+ SI_BANANA_BOMB = 497,
+ SI_SUMMON_AGNI = 498,
+ SI_SPELLBOOK4 = 499,
+ SI_SPELLBOOK5 = 500,
+ SI_SPELLBOOK6 = 501,
+ SI_SPELLBOOK7 = 502,
+ SI_ELEMENTAL_AGGRESSIVE = 503,
+ SI_RETURN_TO_ELDICASTES = 504,
+ SI_BANDING_DEFENCE = 505,
+ SI_SKELSCROLL = 506,
+ SI_DISTRUCTIONSCROLL = 507,
+ SI_ROYALSCROLL = 508,
+ SI_IMMUNITYSCROLL = 509,
+ SI_MYSTICSCROLL = 510,
+ SI_BATTLESCROLL = 511,
+ SI_ARMORSCROLL = 512,
+ SI_FREYJASCROLL = 513,
+ SI_SOULSCROLL = 514,
+ SI_CIRCLE_OF_FIRE = 515,
+ SI_CIRCLE_OF_FIRE_OPTION = 516,
+ SI_FIRE_CLOAK = 517,
+ SI_FIRE_CLOAK_OPTION = 518,
+ SI_WATER_SCREEN = 519,
+ SI_WATER_SCREEN_OPTION = 520,
+ SI_WATER_DROP = 521,
+ SI_WATER_DROP_OPTION = 522,
+ SI_WIND_STEP = 523,
+ SI_WIND_STEP_OPTION = 524,
+ SI_WIND_CURTAIN = 525,
+ SI_WIND_CURTAIN_OPTION = 526,
+ SI_WATER_BARRIER = 527,
+ SI_ZEPHYR = 528,
+ SI_SOLID_SKIN = 529,
+ SI_SOLID_SKIN_OPTION = 530,
+ SI_STONE_SHIELD = 531,
+ SI_STONE_SHIELD_OPTION = 532,
+ SI_POWER_OF_GAIA = 533,
+ // SI_EL_WAIT = 534,
+ // SI_EL_PASSIVE = 535,
+ // SI_EL_DEFENSIVE = 536,
+ // SI_EL_OFFENSIVE = 537,
+ // SI_EL_COST = 538,
+ SI_PYROTECHNIC = 539,
+ SI_PYROTECHNIC_OPTION = 540,
+ SI_HEATER = 541,
+ SI_HEATER_OPTION = 542,
+ SI_TROPIC = 543,
+ SI_TROPIC_OPTION = 544,
+ SI_AQUAPLAY = 545,
+ SI_AQUAPLAY_OPTION = 546,
+ SI_COOLER = 547,
+ SI_COOLER_OPTION = 548,
+ SI_CHILLY_AIR = 549,
+ SI_CHILLY_AIR_OPTION = 550,
+ SI_GUST = 551,
+ SI_GUST_OPTION = 552,
+ SI_BLAST = 553,
+ SI_BLAST_OPTION = 554,
+ SI_WILD_STORM = 555,
+ SI_WILD_STORM_OPTION = 556,
+ SI_PETROLOGY = 557,
+ SI_PETROLOGY_OPTION = 558,
+ SI_CURSED_SOIL = 559,
+ SI_CURSED_SOIL_OPTION = 560,
+ SI_UPHEAVAL = 561,
+ SI_UPHEAVAL_OPTION = 562,
+ SI_TIDAL_WEAPON = 563,
+ SI_TIDAL_WEAPON_OPTION = 564,
+ SI_ROCK_CRUSHER = 565,
+ SI_ROCK_CRUSHER_ATK = 566,
+ SI_FIRE_INSIGNIA = 567,
+ SI_WATER_INSIGNIA = 568,
+ SI_WIND_INSIGNIA = 569,
+ SI_EARTH_INSIGNIA = 570,
+ SI_EQUIPED_FLOOR = 571,
+ SI_GUARDIAN_RECALL = 572,
+ SI_MORA_BUFF = 573,
+ SI_REUSE_LIMIT_G = 574,
+ SI_REUSE_LIMIT_H = 575,
+ SI_NEEDLE_OF_PARALYZE = 576,
+ SI_PAIN_KILLER = 577,
+ SI_G_LIFEPOTION = 578,
+ SI_VITALIZE_POTION = 579,
+ SI_LIGHT_OF_REGENE = 580,
+ SI_OVERED_BOOST = 581,
+ SI_SILENT_BREEZE = 582,
+ SI_ODINS_POWER = 583,
+ SI_STYLE_CHANGE = 584,
+ SI_SONIC_CLAW_POSTDELAY = 585,
+ // ID's 586 - 595 Currently Unused
+ SI_SILVERVEIN_RUSH_POSTDELAY = 596,
+ SI_MIDNIGHT_FRENZY_POSTDELAY = 597,
+ SI_GOLDENE_FERSE = 598,
+ SI_ANGRIFFS_MODUS = 599,
+ SI_TINDER_BREAKER = 600,
+ SI_TINDER_BREAKER_POSTDELAY = 601,
+ SI_CBC = 602,
+ SI_CBC_POSTDELAY = 603,
+ SI_EQC = 604,
+ SI_MAGMA_FLOW = 605,
+ SI_GRANITIC_ARMOR = 606,
+ SI_PYROCLASTIC = 607,
+ SI_VOLCANIC_ASH = 608,
+ SI_SPIRITS_SAVEINFO1 = 609,
+ SI_SPIRITS_SAVEINFO2 = 610,
+ SI_MAGIC_CANDY = 611,
+ SI_SEARCH_STORE_INFO = 612,
+ SI_ALL_RIDING = 613,
+ SI_ALL_RIDING_REUSE_LIMIT = 614,
+ SI_MACRO = 615,
+ SI_MACRO_POSTDELAY = 616,
+ SI_BEER_BOTTLE_CAP = 617,
+ SI_OVERLAPEXPUP = 618,
+ SI_PC_IZ_DUN05 = 619,
+ SI_CRUSHSTRIKE = 620,
+ SI_MONSTER_TRANSFORM = 621,
+ SI_SIT = 622,
+ SI_ONAIR = 623,
+ SI_MTF_ASPD = 624,
+ SI_MTF_RANGEATK = 625,
+ SI_MTF_MATK = 626,
+ SI_MTF_MLEATKED = 627,
+ SI_MTF_CRIDAMAGE = 628,
+ SI_REUSE_LIMIT_MTF = 629,
+ SI_MACRO_PERMIT = 630,
+ SI_MACRO_PLAY = 631,
+ SI_SKF_CAST = 632,
+ SI_SKF_ASPD = 633,
+ SI_SKF_ATK = 634,
+ SI_SKF_MATK = 635,
+ SI_REWARD_PLUSONLYJOBEXP = 636,
+ SI_HANDICAPSTATE_NORECOVER = 637,
+ SI_SET_NUM_DEF = 638,
+ SI_SET_NUM_MDEF = 639,
+ SI_SET_PER_DEF = 640,
+ SI_SET_PER_MDEF = 641,
+ SI_PARTYBOOKING_SEARCH_DEALY = 642,
+ SI_PARTYBOOKING_REGISTER_DEALY = 643,
+ SI_PERIOD_TIME_CHECK_DETECT_SKILL = 644,
+ SI_KO_JYUMONJIKIRI = 645,
+ SI_MEIKYOUSISUI = 646,
+ SI_ATTHASTE_CASH = 647,
+ SI_EQUIPPED_DIVINE_ARMOR = 648,
+ SI_EQUIPPED_HOLY_ARMOR = 649,
+ SI_2011RWC = 650,
+ SI_KYOUGAKU = 651,
+ SI_IZAYOI = 652,
+ SI_ZENKAI = 653,
+ SI_KG_KAGEHUMI = 654,
+ SI_KYOMU = 655,
+ SI_KAGEMUSYA = 656,
+ SI_ZANGETSU = 657,
+ SI_PHI_DEMON = 658,
+ SI_GENSOU = 659,
+ SI_AKAITSUKI = 660,
+ SI_TETANY = 661,
+ SI_GM_BATTLE = 662,
+ SI_GM_BATTLE2 = 663,
+ SI_2011RWC_SCROLL = 664,
+ SI_ACTIVE_MONSTER_TRANSFORM = 665,
+ SI_MYSTICPOWDER = 666,
+ SI_ECLAGE_RECALL = 667,
+ SI_ENTRY_QUEUE_APPLY_DELAY = 668,
+ SI_REUSE_LIMIT_ECL = 669,
+ SI_M_LIFEPOTION = 670,
+ SI_ENTRY_QUEUE_NOTIFY_ADMISSION_TIME_OUT = 671,
+ SI_UNKNOWN_NAME = 672,
+ SI_ON_PUSH_CART = 673,
+ SI_HAT_EFFECT = 674,
+ SI_FLOWER_LEAF = 675,
+ SI_RAY_OF_PROTECTION = 676,
+ SI_GLASTHEIM_ATK = 677,
+ SI_GLASTHEIM_DEF = 678,
+ SI_GLASTHEIM_HEAL = 679,
+ SI_GLASTHEIM_HIDDEN = 680,
+ SI_GLASTHEIM_STATE = 681,
+ SI_GLASTHEIM_ITEMDEF = 682,
+ SI_GLASTHEIM_HPSP = 683,
+ SI_HOMUN_SKILL_POSTDELAY = 684,
+ SI_ALMIGHTY = 685,
+ SI_GVG_GIANT = 686,
+ SI_GVG_GOLEM = 687,
+ SI_GVG_STUN = 688,
+ SI_GVG_STONE = 689,
+ SI_GVG_FREEZ = 690,
+ SI_GVG_SLEEP = 691,
+ SI_GVG_CURSE = 692,
+ SI_GVG_SILENCE = 693,
+ SI_GVG_BLIND = 694,
+ SI_CLIENT_ONLY_EQUIP_ARROW = 695,
+ SI_CLAN_INFO = 696,
+ SI_JP_EVENT01 = 697,
+ SI_JP_EVENT02 = 698,
+ SI_JP_EVENT03 = 699,
+ SI_JP_EVENT04 = 700,
+ SI_TELEPORT_FIXEDCASTINGDELAY = 701,
+ SI_GEFFEN_MAGIC1 = 702,
+ SI_GEFFEN_MAGIC2 = 703,
+ SI_GEFFEN_MAGIC3 = 704,
+ SI_QUEST_BUFF1 = 705,
+ SI_QUEST_BUFF2 = 706,
+ SI_QUEST_BUFF3 = 707,
+ SI_REUSE_LIMIT_RECALL = 708,
+ SI_SAVEPOSITION = 709,
+ SI_MAX,
};
// JOINTBEAT stackable ailments
-enum e_joint_break {
- BREAK_ANKLE = 0x01, // MoveSpeed reduced by 50%
- BREAK_WRIST = 0x02, // ASPD reduced by 25%
- BREAK_KNEE = 0x04, // MoveSpeed reduced by 30%, ASPD reduced by 10%
- BREAK_SHOULDER = 0x08, // DEF reduced by 50%
- BREAK_WAIST = 0x10, // DEF reduced by 25%, ATK reduced by 25%
- BREAK_NECK = 0x20, // current attack does 2x damage, inflicts 'bleeding' for 30 seconds
- BREAK_FLAGS = BREAK_ANKLE | BREAK_WRIST | BREAK_KNEE | BREAK_SHOULDER | BREAK_WAIST | BREAK_NECK,
+enum e_joint_break
+{
+ BREAK_ANKLE = 0x01, // MoveSpeed reduced by 50%
+ BREAK_WRIST = 0x02, // ASPD reduced by 25%
+ BREAK_KNEE = 0x04, // MoveSpeed reduced by 30%, ASPD reduced by 10%
+ BREAK_SHOULDER = 0x08, // DEF reduced by 50%
+ BREAK_WAIST = 0x10, // DEF reduced by 25%, ATK reduced by 25%
+ BREAK_NECK = 0x20, // current attack does 2x damage, inflicts 'bleeding' for 30 seconds
+ BREAK_FLAGS = BREAK_ANKLE | BREAK_WRIST | BREAK_KNEE | BREAK_SHOULDER | BREAK_WAIST | BREAK_NECK,
};
extern int current_equip_item_index;
extern int current_equip_card_id;
//Mode definitions to clear up code reading. [Skotlex]
-enum e_mode {
- MD_CANMOVE = 0x0001,
- MD_LOOTER = 0x0002,
- MD_AGGRESSIVE = 0x0004,
- MD_ASSIST = 0x0008,
- MD_CASTSENSOR_IDLE = 0x0010,
- MD_BOSS = 0x0020,
- MD_PLANT = 0x0040,
- MD_CANATTACK = 0x0080,
- MD_DETECTOR = 0x0100,
- MD_CASTSENSOR_CHASE = 0x0200,
- MD_CHANGECHASE = 0x0400,
- MD_ANGRY = 0x0800,
- MD_CHANGETARGET_MELEE = 0x1000,
- MD_CHANGETARGET_CHASE = 0x2000,
- MD_TARGETWEAK = 0x4000,
- MD_MASK = 0xFFFF,
+enum e_mode
+{
+ MD_CANMOVE = 0x0001,
+ MD_LOOTER = 0x0002,
+ MD_AGGRESSIVE = 0x0004,
+ MD_ASSIST = 0x0008,
+ MD_CASTSENSOR_IDLE = 0x0010,
+ MD_BOSS = 0x0020,
+ MD_PLANT = 0x0040,
+ MD_CANATTACK = 0x0080,
+ MD_DETECTOR = 0x0100,
+ MD_CASTSENSOR_CHASE = 0x0200,
+ MD_CHANGECHASE = 0x0400,
+ MD_ANGRY = 0x0800,
+ MD_CHANGETARGET_MELEE = 0x1000,
+ MD_CHANGETARGET_CHASE = 0x2000,
+ MD_TARGETWEAK = 0x4000,
+ MD_MASK = 0xFFFF,
};
//Status change option definitions (options are what makes status changes visible to chars
@@ -1400,153 +1402,155 @@ enum e_mode {
//opt1: Non stackable status changes.
enum {
- OPT1_STONE = 1, //Petrified
- OPT1_FREEZE,
- OPT1_STUN,
- OPT1_SLEEP,
- //Aegis uses OPT1 = 5 to identify undead enemies (which also grants them immunity to the other opt1 changes)
- OPT1_STONEWAIT=6, //Petrifying
- OPT1_BURNING,
- OPT1_IMPRISON,
- OPT1_CRYSTALIZE,
+ OPT1_STONE = 1, //Petrified
+ OPT1_FREEZE,
+ OPT1_STUN,
+ OPT1_SLEEP,
+ //Aegis uses OPT1 = 5 to identify undead enemies (which also grants them immunity to the other opt1 changes)
+ OPT1_STONEWAIT=6, //Petrifying
+ OPT1_BURNING,
+ OPT1_IMPRISON,
+ OPT1_CRYSTALIZE,
};
//opt2: Stackable status changes.
enum {
- OPT2_POISON = 0x0001,
- OPT2_CURSE = 0x0002,
- OPT2_SILENCE = 0x0004,
- OPT2_SIGNUMCRUCIS = 0x0008,
- OPT2_BLIND = 0x0010,
- OPT2_ANGELUS = 0x0020,
- OPT2_BLEEDING = 0x0040,
- OPT2_DPOISON = 0x0080,
- OPT2_FEAR = 0x0100,
+ OPT2_POISON = 0x0001,
+ OPT2_CURSE = 0x0002,
+ OPT2_SILENCE = 0x0004,
+ OPT2_SIGNUMCRUCIS = 0x0008,
+ OPT2_BLIND = 0x0010,
+ OPT2_ANGELUS = 0x0020,
+ OPT2_BLEEDING = 0x0040,
+ OPT2_DPOISON = 0x0080,
+ OPT2_FEAR = 0x0100,
};
//opt3: (SHOW_EFST_*)
enum {
- OPT3_NORMAL = 0x00000000,
- OPT3_QUICKEN = 0x00000001,
- OPT3_OVERTHRUST = 0x00000002,
- OPT3_ENERGYCOAT = 0x00000004,
- OPT3_EXPLOSIONSPIRITS = 0x00000008,
- OPT3_STEELBODY = 0x00000010,
- OPT3_BLADESTOP = 0x00000020,
- OPT3_AURABLADE = 0x00000040,
- OPT3_BERSERK = 0x00000080,
- OPT3_LIGHTBLADE = 0x00000100,
- OPT3_MOONLIT = 0x00000200,
- OPT3_MARIONETTE = 0x00000400,
- OPT3_ASSUMPTIO = 0x00000800,
- OPT3_WARM = 0x00001000,
- OPT3_KAITE = 0x00002000,
- OPT3_BUNSIN = 0x00004000,
- OPT3_SOULLINK = 0x00008000,
- OPT3_UNDEAD = 0x00010000,
- OPT3_CONTRACT = 0x00020000,
+ OPT3_NORMAL = 0x00000000,
+ OPT3_QUICKEN = 0x00000001,
+ OPT3_OVERTHRUST = 0x00000002,
+ OPT3_ENERGYCOAT = 0x00000004,
+ OPT3_EXPLOSIONSPIRITS = 0x00000008,
+ OPT3_STEELBODY = 0x00000010,
+ OPT3_BLADESTOP = 0x00000020,
+ OPT3_AURABLADE = 0x00000040,
+ OPT3_BERSERK = 0x00000080,
+ OPT3_LIGHTBLADE = 0x00000100,
+ OPT3_MOONLIT = 0x00000200,
+ OPT3_MARIONETTE = 0x00000400,
+ OPT3_ASSUMPTIO = 0x00000800,
+ OPT3_WARM = 0x00001000,
+ OPT3_KAITE = 0x00002000,
+ OPT3_BUNSIN = 0x00004000,
+ OPT3_SOULLINK = 0x00008000,
+ OPT3_UNDEAD = 0x00010000,
+ OPT3_CONTRACT = 0x00020000,
};
enum {
- OPTION_NOTHING = 0x00000000,
- OPTION_SIGHT = 0x00000001,
- OPTION_HIDE = 0x00000002,
- OPTION_CLOAK = 0x00000004,
- OPTION_FALCON = 0x00000010,
- OPTION_RIDING = 0x00000020,
- OPTION_INVISIBLE = 0x00000040,
- OPTION_ORCISH = 0x00000800,
- OPTION_WEDDING = 0x00001000,
- OPTION_RUWACH = 0x00002000,
- OPTION_CHASEWALK = 0x00004000,
- OPTION_FLYING = 0x00008000, //Note that clientside Flying and Xmas are 0x8000 for clients prior to 2007.
- OPTION_XMAS = 0x00010000,
- OPTION_TRANSFORM = 0x00020000,
- OPTION_SUMMER = 0x00040000,
- OPTION_DRAGON1 = 0x00080000,
- OPTION_WUG = 0x00100000,
- OPTION_WUGRIDER = 0x00200000,
- OPTION_MADOGEAR = 0x00400000,
- OPTION_DRAGON2 = 0x00800000,
- OPTION_DRAGON3 = 0x01000000,
- OPTION_DRAGON4 = 0x02000000,
- OPTION_DRAGON5 = 0x04000000,
- OPTION_MOUNTING = 0x08000000,
-
+ OPTION_NOTHING = 0x00000000,
+ OPTION_SIGHT = 0x00000001,
+ OPTION_HIDE = 0x00000002,
+ OPTION_CLOAK = 0x00000004,
+ OPTION_FALCON = 0x00000010,
+ OPTION_RIDING = 0x00000020,
+ OPTION_INVISIBLE = 0x00000040,
+ OPTION_ORCISH = 0x00000800,
+ OPTION_WEDDING = 0x00001000,
+ OPTION_RUWACH = 0x00002000,
+ OPTION_CHASEWALK = 0x00004000,
+ OPTION_FLYING = 0x00008000, //Note that clientside Flying and Xmas are 0x8000 for clients prior to 2007.
+ OPTION_XMAS = 0x00010000,
+ OPTION_TRANSFORM = 0x00020000,
+ OPTION_SUMMER = 0x00040000,
+ OPTION_DRAGON1 = 0x00080000,
+ OPTION_WUG = 0x00100000,
+ OPTION_WUGRIDER = 0x00200000,
+ OPTION_MADOGEAR = 0x00400000,
+ OPTION_DRAGON2 = 0x00800000,
+ OPTION_DRAGON3 = 0x01000000,
+ OPTION_DRAGON4 = 0x02000000,
+ OPTION_DRAGON5 = 0x04000000,
+ OPTION_MOUNTING = 0x08000000,
+
#ifndef NEW_CARTS
- OPTION_CART1 = 0x00000008,
- OPTION_CART2 = 0x00000080,
- OPTION_CART3 = 0x00000100,
- OPTION_CART4 = 0x00000200,
- OPTION_CART5 = 0x00000400,
-
- /* compound constant for older carts */
- OPTION_CART = OPTION_CART1|OPTION_CART2|OPTION_CART3|OPTION_CART4|OPTION_CART5,
+ OPTION_CART1 = 0x00000008,
+ OPTION_CART2 = 0x00000080,
+ OPTION_CART3 = 0x00000100,
+ OPTION_CART4 = 0x00000200,
+ OPTION_CART5 = 0x00000400,
+
+ /* compound constant for older carts */
+ OPTION_CART = OPTION_CART1|OPTION_CART2|OPTION_CART3|OPTION_CART4|OPTION_CART5,
#endif
-
- // compound constants
- OPTION_DRAGON = OPTION_DRAGON1|OPTION_DRAGON2|OPTION_DRAGON3|OPTION_DRAGON4|OPTION_DRAGON5,
- OPTION_MASK = ~OPTION_INVISIBLE,
+
+ // compound constants
+ OPTION_DRAGON = OPTION_DRAGON1|OPTION_DRAGON2|OPTION_DRAGON3|OPTION_DRAGON4|OPTION_DRAGON5,
+ OPTION_MASK = ~OPTION_INVISIBLE,
};
//Defines for the manner system [Skotlex]
-enum manner_flags {
- MANNER_NOCHAT = 0x01,
- MANNER_NOSKILL = 0x02,
- MANNER_NOCOMMAND = 0x04,
- MANNER_NOITEM = 0x08,
- MANNER_NOROOM = 0x10,
+enum manner_flags
+{
+ MANNER_NOCHAT = 0x01,
+ MANNER_NOSKILL = 0x02,
+ MANNER_NOCOMMAND = 0x04,
+ MANNER_NOITEM = 0x08,
+ MANNER_NOROOM = 0x10,
};
/* Status Change State Flags */
enum scs_flag {
- SCS_NOMOVECOND = 0x00000001, /* cond flag for nomove */
- SCS_NOMOVE = 0x00000002, /* unit unable to move */
- SCS_NOPICKITEMCOND = 0x00000004, /* cond flag for nopickitem */
- SCS_NOPICKITEM = 0x00000008, /* player unable to pick up items */
- SCS_NODROPITEMCOND = 0x00000010, /* cond flag for nodropitem */
- SCS_NODROPITEM = 0x00000020, /* player unable to drop items */
- SCS_NOCASTCOND = 0x00000040, /* cond flag for nocast */
- SCS_NOCAST = 0x00000080, /* unit unable to cast skills */
+ SCS_NOMOVECOND = 0x00000001, /* cond flag for nomove */
+ SCS_NOMOVE = 0x00000002, /* unit unable to move */
+ SCS_NOPICKITEMCOND = 0x00000004, /* cond flag for nopickitem */
+ SCS_NOPICKITEM = 0x00000008, /* player unable to pick up items */
+ SCS_NODROPITEMCOND = 0x00000010, /* cond flag for nodropitem */
+ SCS_NODROPITEM = 0x00000020, /* player unable to drop items */
+ SCS_NOCASTCOND = 0x00000040, /* cond flag for nocast */
+ SCS_NOCAST = 0x00000080, /* unit unable to cast skills */
};
//Define flags for the status_calc_bl function. [Skotlex]
-enum scb_flag {
- SCB_NONE = 0x00000000,
- SCB_BASE = 0x00000001,
- SCB_MAXHP = 0x00000002,
- SCB_MAXSP = 0x00000004,
- SCB_STR = 0x00000008,
- SCB_AGI = 0x00000010,
- SCB_VIT = 0x00000020,
- SCB_INT = 0x00000040,
- SCB_DEX = 0x00000080,
- SCB_LUK = 0x00000100,
- SCB_BATK = 0x00000200,
- SCB_WATK = 0x00000400,
- SCB_MATK = 0x00000800,
- SCB_HIT = 0x00001000,
- SCB_FLEE = 0x00002000,
- SCB_DEF = 0x00004000,
- SCB_DEF2 = 0x00008000,
- SCB_MDEF = 0x00010000,
- SCB_MDEF2 = 0x00020000,
- SCB_SPEED = 0x00040000,
- SCB_ASPD = 0x00080000,
- SCB_DSPD = 0x00100000,
- SCB_CRI = 0x00200000,
- SCB_FLEE2 = 0x00400000,
- SCB_ATK_ELE = 0x00800000,
- SCB_DEF_ELE = 0x01000000,
- SCB_MODE = 0x02000000,
- SCB_SIZE = 0x04000000,
- SCB_RACE = 0x08000000,
- SCB_RANGE = 0x10000000,
- SCB_REGEN = 0x20000000,
- SCB_DYE = 0x40000000, // force cloth-dye change to 0 to avoid client crashes.
+enum scb_flag
+{
+ SCB_NONE = 0x00000000,
+ SCB_BASE = 0x00000001,
+ SCB_MAXHP = 0x00000002,
+ SCB_MAXSP = 0x00000004,
+ SCB_STR = 0x00000008,
+ SCB_AGI = 0x00000010,
+ SCB_VIT = 0x00000020,
+ SCB_INT = 0x00000040,
+ SCB_DEX = 0x00000080,
+ SCB_LUK = 0x00000100,
+ SCB_BATK = 0x00000200,
+ SCB_WATK = 0x00000400,
+ SCB_MATK = 0x00000800,
+ SCB_HIT = 0x00001000,
+ SCB_FLEE = 0x00002000,
+ SCB_DEF = 0x00004000,
+ SCB_DEF2 = 0x00008000,
+ SCB_MDEF = 0x00010000,
+ SCB_MDEF2 = 0x00020000,
+ SCB_SPEED = 0x00040000,
+ SCB_ASPD = 0x00080000,
+ SCB_DSPD = 0x00100000,
+ SCB_CRI = 0x00200000,
+ SCB_FLEE2 = 0x00400000,
+ SCB_ATK_ELE = 0x00800000,
+ SCB_DEF_ELE = 0x01000000,
+ SCB_MODE = 0x02000000,
+ SCB_SIZE = 0x04000000,
+ SCB_RACE = 0x08000000,
+ SCB_RANGE = 0x10000000,
+ SCB_REGEN = 0x20000000,
+ SCB_DYE = 0x40000000, // force cloth-dye change to 0 to avoid client crashes.
- SCB_BATTLE = 0x3FFFFFFE,
- SCB_ALL = 0x3FFFFFFF
+ SCB_BATTLE = 0x3FFFFFFE,
+ SCB_ALL = 0x3FFFFFFF
};
//Define to determine who gets HP/SP consumed on doing skills/etc. [Skotlex]
@@ -1560,119 +1564,122 @@ enum scb_flag {
//Required because players have two of these, one in status_data
//and another for their left hand weapon.
struct weapon_atk {
- unsigned short atk, atk2;
- unsigned short range;
- unsigned char ele;
-#ifdef RENEWAL
- unsigned short matk, wlv;
-#endif
+ unsigned short atk, atk2;
+ unsigned short range;
+ unsigned char ele;
};
//For holding basic status (which can be modified by status changes)
struct status_data {
- unsigned int
- hp, sp, // see status_cpy before adding members before hp and sp
- max_hp, max_sp;
- unsigned short
- str, agi, vit, int_, dex, luk,
- batk,
- matk_min, matk_max,
- speed,
- amotion, adelay, dmotion,
- mode;
- short
- hit, flee, cri, flee2,
- def2, mdef2,
+ unsigned int
+ hp, sp, // see status_cpy before adding members before hp and sp
+ max_hp, max_sp;
+ unsigned short
+ str, agi, vit, int_, dex, luk,
+ batk,
+ matk_min, matk_max,
+ speed,
+ amotion, adelay, dmotion,
+ mode;
+ short
+ hit, flee, cri, flee2,
+ def2, mdef2,
#ifdef RENEWAL_ASPD
- aspd_rate2,
+ aspd_rate2,
#endif
- aspd_rate;
- /**
- * defType is RENEWAL dependent and defined in src/map/config/data/const.h
- **/
- defType def,mdef;
+ aspd_rate;
+ /**
+ * defType is RENEWAL dependent and defined in src/map/config/data/const.h
+ **/
+ defType def,mdef;
- unsigned char
- def_ele, ele_lv,
- size, race;
+ unsigned char
+ def_ele, ele_lv,
+#ifdef RENEWAL
+ /**
+ * in RE weapon level is used in several areas, keeping it here saves performance
+ **/
+ wlv,
+#endif
+ size, race;
- struct weapon_atk rhw, lhw; //Right Hand/Left Hand Weapon.
+ struct weapon_atk rhw, lhw; //Right Hand/Left Hand Weapon.
};
//Additional regen data that only players have.
struct regen_data_sub {
- unsigned short
- hp,sp;
+ unsigned short
+ hp,sp;
- //tick accumulation before healing.
- struct {
- unsigned int hp,sp;
- } tick;
-
- //Regen rates (where every 1 means +100% regen)
- struct {
- unsigned char hp,sp;
- } rate;
+ //tick accumulation before healing.
+ struct {
+ unsigned int hp,sp;
+ } tick;
+
+ //Regen rates (where every 1 means +100% regen)
+ struct {
+ unsigned char hp,sp;
+ } rate;
};
struct regen_data {
- unsigned short flag; //Marks what stuff you may heal or not.
- unsigned short
- hp,sp,shp,ssp;
-
- //tick accumulation before healing.
- struct {
- unsigned int hp,sp,shp,ssp;
- } tick;
+ unsigned short flag; //Marks what stuff you may heal or not.
+ unsigned short
+ hp,sp,shp,ssp;
- //Regen rates (where every 1 means +100% regen)
- struct {
- unsigned char
- hp,sp,shp,ssp;
- } rate;
+ //tick accumulation before healing.
+ struct {
+ unsigned int hp,sp,shp,ssp;
+ } tick;
+
+ //Regen rates (where every 1 means +100% regen)
+ struct {
+ unsigned char
+ hp,sp,shp,ssp;
+ } rate;
+
+ struct {
+ unsigned walk:1; //Can you regen even when walking?
+ unsigned gc:1; //Tags when you should have double regen due to GVG castle
+ unsigned overweight :2; //overweight state (1: 50%, 2: 90%)
+ unsigned block :2; //Block regen flag (1: Hp, 2: Sp)
+ } state;
- struct {
- unsigned walk:1; //Can you regen even when walking?
- unsigned gc:1; //Tags when you should have double regen due to GVG castle
- unsigned overweight :2; //overweight state (1: 50%, 2: 90%)
- unsigned block :2; //Block regen flag (1: Hp, 2: Sp)
- } state;
-
- //skill-regen, sitting-skill-regen (since not all chars with regen need it)
- struct regen_data_sub *sregen, *ssregen;
+ //skill-regen, sitting-skill-regen (since not all chars with regen need it)
+ struct regen_data_sub *sregen, *ssregen;
};
struct status_change_entry {
- int timer;
- int val1,val2,val3,val4;
+ int timer;
+ int val1,val2,val3,val4;
};
struct status_change {
- unsigned int option;// effect state (bitfield)
- unsigned int opt3;// skill state (bitfield)
- unsigned short opt1;// body state
- unsigned short opt2;// health state (bitfield)
- unsigned char count;
- //TODO: See if it is possible to implement the following SC's without requiring extra parameters while the SC is inactive.
- unsigned char jb_flag; //Joint Beat type flag
- struct {
- unsigned char move;
- unsigned char pickup;
- unsigned char drop;
- unsigned char cast;
- } cant;/* status change state flags */
- //int sg_id; //ID of the previous Storm gust that hit you
- short comet_x, comet_y; // Point where src casted Comet - required to calculate damage from this point
- /**
- * The Storm Gust counter was dropped in renewal
- **/
+ unsigned int option;// effect state (bitfield)
+ unsigned int opt3;// skill state (bitfield)
+ unsigned short opt1;// body state
+ unsigned short opt2;// health state (bitfield)
+ unsigned char count;
+ //TODO: See if it is possible to implement the following SC's without requiring extra parameters while the SC is inactive.
+ unsigned char jb_flag; //Joint Beat type flag
+ struct {
+ unsigned char move;
+ unsigned char pickup;
+ unsigned char drop;
+ unsigned char cast;
+ } cant;/* status change state flags */
+ //int sg_id; //ID of the previous Storm gust that hit you
+ short comet_x, comet_y; // Point where src casted Comet - required to calculate damage from this point
+/**
+ * The Storm Gust counter was dropped in renewal
+ **/
#ifndef RENEWAL
- unsigned char sg_counter; //Storm gust counter (previous hits from storm gust)
+ unsigned char sg_counter; //Storm gust counter (previous hits from storm gust)
#endif
- unsigned char bs_counter; // Blood Sucker counter
- struct status_change_entry *data[SC_MAX];
+ unsigned char bs_counter; // Blood Sucker counter
+ struct status_change_entry *data[SC_MAX];
};
// for looking up associated data
@@ -1687,7 +1694,7 @@ int status_damage(struct block_list *src,struct block_list *target,int hp,int sp
//Define for standard HP/SP damage triggers.
#define status_zap(bl, hp, sp) status_damage(NULL, bl, hp, sp, 0, 1)
//Define for standard HP/SP skill-related cost triggers (mobs require no HP/SP to use skills)
-int status_charge(struct block_list *bl, int hp, int sp);
+int status_charge(struct block_list* bl, int hp, int sp);
int status_percent_change(struct block_list *src,struct block_list *target,signed char hp_rate, signed char sp_rate, int flag);
//Easier handling of status_percent_change
#define status_percent_heal(bl, hp_rate, sp_rate) status_percent_change(NULL, bl, -(hp_rate), -(sp_rate), 0)
@@ -1703,7 +1710,7 @@ int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per
struct regen_data *status_get_regen_data(struct block_list *bl);
struct status_data *status_get_status_data(struct block_list *bl);
struct status_data *status_get_base_status(struct block_list *bl);
-const char *status_get_name(struct block_list *bl);
+const char * status_get_name(struct block_list *bl);
int status_get_class(struct block_list *bl);
int status_get_lv(struct block_list *bl);
#define status_get_range(bl) status_get_status_data(bl)->rhw.range
@@ -1745,6 +1752,12 @@ unsigned char status_calc_attack_element(struct block_list *bl, struct status_ch
#define status_get_race(bl) status_get_status_data(bl)->race
#define status_get_size(bl) status_get_status_data(bl)->size
#define status_get_mode(bl) status_get_status_data(bl)->mode
+#ifdef RENEWAL
+ /**
+ * in RE weapon level is used in several areas, keeping it here saves performance
+ **/
+ #define status_get_wlv(bl) status_get_status_data(bl)->wlv
+#endif
int status_get_party_id(struct block_list *bl);
int status_get_guild_id(struct block_list *bl);
int status_get_emblem_id(struct block_list *bl);
@@ -1765,14 +1778,14 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
#define sc_start2(bl, type, rate, val1, val2, tick) status_change_start(bl,type,100*(rate),val1,val2,0,0,tick,0)
#define sc_start4(bl, type, rate, val1, val2, val3, val4, tick) status_change_start(bl,type,100*(rate),val1,val2,val3,val4,tick,0)
-int status_change_start(struct block_list *bl,enum sc_type type,int rate,int val1,int val2,int val3,int val4,int tick,int flag);
-int status_change_end_(struct block_list *bl, enum sc_type type, int tid, const char *file, int line);
+int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val1,int val2,int val3,int val4,int tick,int flag);
+int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const char* file, int line);
#define status_change_end(bl,type,tid) status_change_end_(bl,type,tid,__FILE__,__LINE__)
int kaahi_heal_timer(int tid, unsigned int tick, int id, intptr_t data);
int status_change_timer(int tid, unsigned int tick, int id, intptr_t data);
-int status_change_timer_sub(struct block_list *bl, va_list ap);
-int status_change_clear(struct block_list *bl, int type);
-int status_change_clear_buffs(struct block_list *bl, int type);
+int status_change_timer_sub(struct block_list* bl, va_list ap);
+int status_change_clear(struct block_list* bl, int type);
+int status_change_clear_buffs(struct block_list* bl, int type);
#define status_calc_bl(bl, flag) status_calc_bl_(bl, (enum scb_flag)(flag), false)
#define status_calc_mob(md, first) status_calc_bl_(&(md)->bl, SCB_ALL, first)
@@ -1783,9 +1796,9 @@ int status_change_clear_buffs(struct block_list *bl, int type);
#define status_calc_elemental(ed, first) status_calc_bl_(&(ed)->bl, SCB_ALL, first)
void status_calc_bl_(struct block_list *bl, enum scb_flag flag, bool first);
-int status_calc_mob_(struct mob_data *md, bool first);
-int status_calc_pet_(struct pet_data *pd, bool first);
-int status_calc_pc_(struct map_session_data *sd, bool first);
+int status_calc_mob_(struct mob_data* md, bool first);
+int status_calc_pet_(struct pet_data* pd, bool first);
+int status_calc_pc_(struct map_session_data* sd, bool first);
int status_calc_homunculus_(struct homun_data *hd, bool first);
int status_calc_mercenary_(struct mercenary_data *md, bool first);
int status_calc_elemental_(struct elemental_data *ed, bool first);
@@ -1797,11 +1810,7 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
int status_check_skilluse(struct block_list *src, struct block_list *target, int skill_num, int flag); // [Skotlex]
int status_check_visibility(struct block_list *src, struct block_list *target); //[Skotlex]
-int status_change_spread(struct block_list *src, struct block_list *bl);
-
-#ifdef RENEWAL
-unsigned short status_base_matk(const struct status_data* status, int level);
-#endif
+int status_change_spread( struct block_list *src, struct block_list *bl );
int status_readdb(void);
int do_init_status(void);
diff --git a/src/map/storage.c b/src/map/storage.c
index e75891608..c66f12852 100644
--- a/src/map/storage.c
+++ b/src/map/storage.c
@@ -24,33 +24,34 @@
#include <string.h>
-static DBMap *guild_storage_db; // int guild_id -> struct guild_storage*
+static DBMap* guild_storage_db; // int guild_id -> struct guild_storage*
/*==========================================
* Sort items in the warehouse
*------------------------------------------*/
static int storage_comp_item(const void *_i1, const void *_i2)
{
- struct item *i1 = (struct item *)_i1;
- struct item *i2 = (struct item *)_i2;
-
- if (i1->nameid == i2->nameid)
- return 0;
- else if (!(i1->nameid) || !(i1->amount))
- return 1;
- else if (!(i2->nameid) || !(i2->amount))
- return -1;
- return i1->nameid - i2->nameid;
+ struct item *i1 = (struct item *)_i1;
+ struct item *i2 = (struct item *)_i2;
+
+ if (i1->nameid == i2->nameid)
+ return 0;
+ else if (!(i1->nameid) || !(i1->amount))
+ return 1;
+ else if (!(i2->nameid) || !(i2->amount))
+ return -1;
+ return i1->nameid - i2->nameid;
}
//Sort item by storage_comp_item (nameid)
-static void storage_sortitem(struct item *items, unsigned int size)
+static void storage_sortitem(struct item* items, unsigned int size)
{
- nullpo_retv(items);
+ nullpo_retv(items);
- if (battle_config.client_sort_storage) {
- qsort(items, size, sizeof(struct item), storage_comp_item);
- }
+ if( battle_config.client_sort_storage )
+ {
+ qsort(items, size, sizeof(struct item), storage_comp_item);
+ }
}
/*==========================================
@@ -58,12 +59,12 @@ static void storage_sortitem(struct item *items, unsigned int size)
*------------------------------------------*/
int do_init_storage(void) // Called from map.c::do_init()
{
- guild_storage_db=idb_alloc(DB_OPT_RELEASE_DATA);
- return 1;
+ guild_storage_db=idb_alloc(DB_OPT_RELEASE_DATA);
+ return 1;
}
void do_final_storage(void) // by [MC Cameri]
{
- guild_storage_db->destroy(guild_storage_db,NULL);
+ guild_storage_db->destroy(guild_storage_db,NULL);
}
/**
@@ -72,17 +73,17 @@ void do_final_storage(void) // by [MC Cameri]
*/
static int storage_reconnect_sub(DBKey key, DBData *data, va_list ap)
{
- struct guild_storage *stor = db_data2ptr(data);
- if (stor->dirty && stor->storage_status == 0) //Save closed storages.
- storage_guild_storagesave(0, stor->guild_id,0);
+ struct guild_storage *stor = db_data2ptr(data);
+ if (stor->dirty && stor->storage_status == 0) //Save closed storages.
+ storage_guild_storagesave(0, stor->guild_id,0);
- return 0;
+ return 0;
}
//Function to be invoked upon server reconnection to char. To save all 'dirty' storages [Skotlex]
void do_reconnect_storage(void)
{
- guild_storage_db->foreach(guild_storage_db, storage_reconnect_sub);
+ guild_storage_db->foreach(guild_storage_db, storage_reconnect_sub);
}
/*==========================================
@@ -92,22 +93,22 @@ void do_reconnect_storage(void)
*------------------------------------------*/
int storage_storageopen(struct map_session_data *sd)
{
- nullpo_ret(sd);
-
- if (sd->state.storage_flag)
- return 1; //Already open?
-
- if (!pc_can_give_items(sd)) {
- //check is this GM level is allowed to put items to storage
- clif_displaymessage(sd->fd, msg_txt(246));
- return 1;
- }
-
- sd->state.storage_flag = 1;
- storage_sortitem(sd->status.storage.items, ARRAYLENGTH(sd->status.storage.items));
- clif_storagelist(sd, sd->status.storage.items, ARRAYLENGTH(sd->status.storage.items));
- clif_updatestorageamount(sd, sd->status.storage.storage_amount, MAX_STORAGE);
- return 0;
+ nullpo_ret(sd);
+
+ if(sd->state.storage_flag)
+ return 1; //Already open?
+
+ if( !pc_can_give_items(sd) )
+ { //check is this GM level is allowed to put items to storage
+ clif_displaymessage(sd->fd, msg_txt(246));
+ return 1;
+ }
+
+ sd->state.storage_flag = 1;
+ storage_sortitem(sd->status.storage.items, ARRAYLENGTH(sd->status.storage.items));
+ clif_storagelist(sd, sd->status.storage.items, ARRAYLENGTH(sd->status.storage.items));
+ clif_updatestorageamount(sd, sd->status.storage.storage_amount, MAX_STORAGE);
+ return 0;
}
/* helper function
@@ -115,229 +116,232 @@ int storage_storageopen(struct map_session_data *sd)
*/
int compare_item(struct item *a, struct item *b)
{
- if (a->nameid == b->nameid &&
- a->identify == b->identify &&
- a->refine == b->refine &&
- a->attribute == b->attribute &&
- a->expire_time == b->expire_time) {
- int i;
- for (i = 0; i < MAX_SLOTS && (a->card[i] == b->card[i]); i++);
- return (i == MAX_SLOTS);
- }
- return 0;
+ if( a->nameid == b->nameid &&
+ a->identify == b->identify &&
+ a->refine == b->refine &&
+ a->attribute == b->attribute &&
+ a->expire_time == b->expire_time )
+ {
+ int i;
+ for (i = 0; i < MAX_SLOTS && (a->card[i] == b->card[i]); i++);
+ return (i == MAX_SLOTS);
+ }
+ return 0;
}
/*==========================================
* Internal add-item function.
*------------------------------------------*/
-static int storage_additem(struct map_session_data *sd, struct item *item_data, int amount)
+static int storage_additem(struct map_session_data* sd, struct item* item_data, int amount)
{
- struct storage_data *stor = &sd->status.storage;
- struct item_data *data;
- int i;
-
- if (item_data->nameid <= 0 || amount <= 0)
- return 1;
-
- data = itemdb_search(item_data->nameid);
-
- if (data->stack.storage && amount > data->stack.amount) {
- // item stack limitation
- return 1;
- }
-
- if (!itemdb_canstore(item_data, pc_get_group_level(sd))) {
- //Check if item is storable. [Skotlex]
- clif_displaymessage(sd->fd, msg_txt(264));
- return 1;
- }
-
- if (itemdb_isstackable2(data)) {
- //Stackable
- for (i = 0; i < MAX_STORAGE; i++) {
- if (compare_item(&stor->items[i], item_data)) {
- // existing items found, stack them
- if (amount > MAX_AMOUNT - stor->items[i].amount || (data->stack.storage && amount > data->stack.amount - stor->items[i].amount))
- return 1;
- stor->items[i].amount += amount;
- clif_storageitemadded(sd,&stor->items[i],i,amount);
- return 0;
- }
- }
- }
-
- // find free slot
- ARR_FIND(0, MAX_STORAGE, i, stor->items[i].nameid == 0);
- if (i >= MAX_STORAGE)
- return 1;
-
- // add item to slot
- memcpy(&stor->items[i],item_data,sizeof(stor->items[0]));
- stor->storage_amount++;
- stor->items[i].amount = amount;
- clif_storageitemadded(sd,&stor->items[i],i,amount);
- clif_updatestorageamount(sd, stor->storage_amount, MAX_STORAGE);
-
- return 0;
+ struct storage_data* stor = &sd->status.storage;
+ struct item_data *data;
+ int i;
+
+ if( item_data->nameid <= 0 || amount <= 0 )
+ return 1;
+
+ data = itemdb_search(item_data->nameid);
+
+ if( data->stack.storage && amount > data->stack.amount )
+ {// item stack limitation
+ return 1;
+ }
+
+ if( !itemdb_canstore(item_data, pc_get_group_level(sd)) )
+ { //Check if item is storable. [Skotlex]
+ clif_displaymessage (sd->fd, msg_txt(264));
+ return 1;
+ }
+
+ if( itemdb_isstackable2(data) )
+ {//Stackable
+ for( i = 0; i < MAX_STORAGE; i++ )
+ {
+ if( compare_item(&stor->items[i], item_data) )
+ {// existing items found, stack them
+ if( amount > MAX_AMOUNT - stor->items[i].amount || ( data->stack.storage && amount > data->stack.amount - stor->items[i].amount ) )
+ return 1;
+ stor->items[i].amount += amount;
+ clif_storageitemadded(sd,&stor->items[i],i,amount);
+ return 0;
+ }
+ }
+ }
+
+ // find free slot
+ ARR_FIND( 0, MAX_STORAGE, i, stor->items[i].nameid == 0 );
+ if( i >= MAX_STORAGE )
+ return 1;
+
+ // add item to slot
+ memcpy(&stor->items[i],item_data,sizeof(stor->items[0]));
+ stor->storage_amount++;
+ stor->items[i].amount = amount;
+ clif_storageitemadded(sd,&stor->items[i],i,amount);
+ clif_updatestorageamount(sd, stor->storage_amount, MAX_STORAGE);
+
+ return 0;
}
/*==========================================
* Internal del-item function
*------------------------------------------*/
-int storage_delitem(struct map_session_data *sd, int n, int amount)
+int storage_delitem(struct map_session_data* sd, int n, int amount)
{
- if (sd->status.storage.items[n].nameid == 0 || sd->status.storage.items[n].amount < amount)
- return 1;
-
- sd->status.storage.items[n].amount -= amount;
- if (sd->status.storage.items[n].amount == 0) {
- memset(&sd->status.storage.items[n],0,sizeof(sd->status.storage.items[0]));
- sd->status.storage.storage_amount--;
- if (sd->state.storage_flag == 1) clif_updatestorageamount(sd, sd->status.storage.storage_amount, MAX_STORAGE);
- }
- if (sd->state.storage_flag == 1) clif_storageitemremoved(sd,n,amount);
- return 0;
+ if( sd->status.storage.items[n].nameid == 0 || sd->status.storage.items[n].amount < amount )
+ return 1;
+
+ sd->status.storage.items[n].amount -= amount;
+ if( sd->status.storage.items[n].amount == 0 )
+ {
+ memset(&sd->status.storage.items[n],0,sizeof(sd->status.storage.items[0]));
+ sd->status.storage.storage_amount--;
+ if( sd->state.storage_flag == 1 ) clif_updatestorageamount(sd, sd->status.storage.storage_amount, MAX_STORAGE);
+ }
+ if( sd->state.storage_flag == 1 ) clif_storageitemremoved(sd,n,amount);
+ return 0;
}
/*==========================================
* Add an item to the storage from the inventory.
* @index : inventory idx
* return
- * 0 : fail
- * 1 : success
+ * 0 : fail
+ * 1 : success
*------------------------------------------*/
-int storage_storageadd(struct map_session_data *sd, int index, int amount)
+int storage_storageadd(struct map_session_data* sd, int index, int amount)
{
- nullpo_ret(sd);
+ nullpo_ret(sd);
- if (sd->status.storage.storage_amount > MAX_STORAGE)
- return 0; // storage full
+ if( sd->status.storage.storage_amount > MAX_STORAGE )
+ return 0; // storage full
- if (index < 0 || index >= MAX_INVENTORY)
- return 0;
+ if( index < 0 || index >= MAX_INVENTORY )
+ return 0;
- if (sd->status.inventory[index].nameid <= 0)
- return 0; // No item on that spot
+ if( sd->status.inventory[index].nameid <= 0 )
+ return 0; // No item on that spot
- if (amount < 1 || amount > sd->status.inventory[index].amount)
- return 0;
+ if( amount < 1 || amount > sd->status.inventory[index].amount )
+ return 0;
- if (storage_additem(sd,&sd->status.inventory[index],amount) == 0)
- pc_delitem(sd,index,amount,0,4,LOG_TYPE_STORAGE);
+ if( storage_additem(sd,&sd->status.inventory[index],amount) == 0 )
+ pc_delitem(sd,index,amount,0,4,LOG_TYPE_STORAGE);
- return 1;
+ return 1;
}
/*==========================================
* Retrieve an item from the storage into inventory
* @index : storage idx
* return
- * 0 : fail
- * 1 : success
+ * 0 : fail
+ * 1 : success
*------------------------------------------*/
-int storage_storageget(struct map_session_data *sd, int index, int amount)
+int storage_storageget(struct map_session_data* sd, int index, int amount)
{
- int flag;
+ int flag;
- if (index < 0 || index >= MAX_STORAGE)
- return 0;
+ if( index < 0 || index >= MAX_STORAGE )
+ return 0;
- if (sd->status.storage.items[index].nameid <= 0)
- return 0; //Nothing there
+ if( sd->status.storage.items[index].nameid <= 0 )
+ return 0; //Nothing there
+
+ if( amount < 1 || amount > sd->status.storage.items[index].amount )
+ return 0;
- if (amount < 1 || amount > sd->status.storage.items[index].amount)
- return 0;
+ if( (flag = pc_additem(sd,&sd->status.storage.items[index],amount,LOG_TYPE_STORAGE)) == 0 )
+ storage_delitem(sd,index,amount);
+ else
+ clif_additem(sd,0,0,flag);
- if ((flag = pc_additem(sd,&sd->status.storage.items[index],amount,LOG_TYPE_STORAGE)) == 0)
- storage_delitem(sd,index,amount);
- else
- clif_additem(sd,0,0,flag);
-
- return 1;
+ return 1;
}
/*==========================================
* Move an item from cart to storage.
* @index : cart inventory index
* return
- * 0 : fail
- * 1 : success
+ * 0 : fail
+ * 1 : success
*------------------------------------------*/
-int storage_storageaddfromcart(struct map_session_data *sd, int index, int amount)
+int storage_storageaddfromcart(struct map_session_data* sd, int index, int amount)
{
- nullpo_ret(sd);
-
- if (sd->status.storage.storage_amount > MAX_STORAGE)
- return 0; // storage full / storage closed
+ nullpo_ret(sd);
- if (index < 0 || index >= MAX_CART)
- return 0;
+ if( sd->status.storage.storage_amount > MAX_STORAGE )
+ return 0; // storage full / storage closed
- if (sd->status.cart[index].nameid <= 0)
- return 0; //No item there.
+ if( index < 0 || index >= MAX_CART )
+ return 0;
- if (amount < 1 || amount > sd->status.cart[index].amount)
- return 0;
+ if( sd->status.cart[index].nameid <= 0 )
+ return 0; //No item there.
+
+ if( amount < 1 || amount > sd->status.cart[index].amount )
+ return 0;
- if (storage_additem(sd,&sd->status.cart[index],amount) == 0)
- pc_cart_delitem(sd,index,amount,0,LOG_TYPE_STORAGE);
+ if( storage_additem(sd,&sd->status.cart[index],amount) == 0 )
+ pc_cart_delitem(sd,index,amount,0,LOG_TYPE_STORAGE);
- return 1;
+ return 1;
}
/*==========================================
* Get from Storage to the Cart inventory
* @index : storage index
* return
- * 0 : fail
- * 1 : success
+ * 0 : fail
+ * 1 : success
*------------------------------------------*/
-int storage_storagegettocart(struct map_session_data *sd, int index, int amount)
+int storage_storagegettocart(struct map_session_data* sd, int index, int amount)
{
- nullpo_ret(sd);
-
- if (index < 0 || index >= MAX_STORAGE)
- return 0;
-
- if (sd->status.storage.items[index].nameid <= 0)
- return 0; //Nothing there.
-
- if (amount < 1 || amount > sd->status.storage.items[index].amount)
- return 0;
-
- if (pc_cart_additem(sd,&sd->status.storage.items[index],amount,LOG_TYPE_STORAGE) == 0)
- storage_delitem(sd,index,amount);
-
- return 1;
+ nullpo_ret(sd);
+
+ if( index < 0 || index >= MAX_STORAGE )
+ return 0;
+
+ if( sd->status.storage.items[index].nameid <= 0 )
+ return 0; //Nothing there.
+
+ if( amount < 1 || amount > sd->status.storage.items[index].amount )
+ return 0;
+
+ if( pc_cart_additem(sd,&sd->status.storage.items[index],amount,LOG_TYPE_STORAGE) == 0 )
+ storage_delitem(sd,index,amount);
+
+ return 1;
}
/*==========================================
* Modified By Valaris to save upon closing [massdriller]
*------------------------------------------*/
-void storage_storageclose(struct map_session_data *sd)
+void storage_storageclose(struct map_session_data* sd)
{
- nullpo_retv(sd);
+ nullpo_retv(sd);
- clif_storageclose(sd);
+ clif_storageclose(sd);
- if (save_settings&4)
- chrif_save(sd,0); //Invokes the storage saving as well.
+ if( save_settings&4 )
+ chrif_save(sd,0); //Invokes the storage saving as well.
- sd->state.storage_flag = 0;
+ sd->state.storage_flag = 0;
}
/*==========================================
* When quitting the game.
*------------------------------------------*/
-void storage_storage_quit(struct map_session_data *sd, int flag)
+void storage_storage_quit(struct map_session_data* sd, int flag)
{
- nullpo_retv(sd);
+ nullpo_retv(sd);
+
+ if (save_settings&4)
+ chrif_save(sd, flag); //Invokes the storage saving as well.
- if (save_settings&4)
- chrif_save(sd, flag); //Invokes the storage saving as well.
-
- sd->state.storage_flag = 0;
+ sd->state.storage_flag = 0;
}
/**
@@ -345,370 +349,374 @@ void storage_storage_quit(struct map_session_data *sd, int flag)
*/
static DBData create_guildstorage(DBKey key, va_list args)
{
- struct guild_storage *gs = NULL;
- gs = (struct guild_storage *) aCalloc(sizeof(struct guild_storage), 1);
- gs->guild_id=key.i;
- return db_ptr2data(gs);
+ struct guild_storage *gs = NULL;
+ gs = (struct guild_storage *) aCalloc(sizeof(struct guild_storage), 1);
+ gs->guild_id=key.i;
+ return db_ptr2data(gs);
}
-struct guild_storage *guild2storage(int guild_id) {
- struct guild_storage *gs = NULL;
- if (guild_search(guild_id) != NULL)
- gs = idb_ensure(guild_storage_db,guild_id,create_guildstorage);
- return gs;
+struct guild_storage *guild2storage(int guild_id)
+{
+ struct guild_storage *gs = NULL;
+ if(guild_search(guild_id) != NULL)
+ gs = idb_ensure(guild_storage_db,guild_id,create_guildstorage);
+ return gs;
}
//For just locating a storage without creating one. [Skotlex]
-struct guild_storage *guild2storage2(int guild_id) {
- return (struct guild_storage *)idb_get(guild_storage_db,guild_id);
+struct guild_storage *guild2storage2(int guild_id)
+{
+ return (struct guild_storage*)idb_get(guild_storage_db,guild_id);
}
int guild_storage_delete(int guild_id)
{
- idb_remove(guild_storage_db,guild_id);
- return 0;
+ idb_remove(guild_storage_db,guild_id);
+ return 0;
}
/*==========================================
* Attempt to open guild storage for sd
* return
-* 0 : success (open or req to create a new one)
-* 1 : fail
-* 2 : no guild for sd
+* 0 : success (open or req to create a new one)
+* 1 : fail
+* 2 : no guild for sd
*------------------------------------------*/
-int storage_guild_storageopen(struct map_session_data *sd)
+int storage_guild_storageopen(struct map_session_data* sd)
{
- struct guild_storage *gstor;
-
- nullpo_ret(sd);
-
- if (sd->status.guild_id <= 0)
- return 2;
-
- if (sd->state.storage_flag)
- return 1; //Can't open both storages at a time.
-
- if (!pc_can_give_items(sd)) { //check is this GM level can open guild storage and store items [Lupus]
- clif_displaymessage(sd->fd, msg_txt(246));
- return 1;
- }
-
- if ((gstor = guild2storage2(sd->status.guild_id)) == NULL) {
- intif_request_guild_storage(sd->status.account_id,sd->status.guild_id);
- return 0;
- }
- if (gstor->storage_status)
- return 1;
-
- gstor->storage_status = 1;
- sd->state.storage_flag = 2;
- storage_sortitem(gstor->items, ARRAYLENGTH(gstor->items));
- clif_storagelist(sd, gstor->items, ARRAYLENGTH(gstor->items));
- clif_updatestorageamount(sd, gstor->storage_amount, MAX_GUILD_STORAGE);
- return 0;
+ struct guild_storage *gstor;
+
+ nullpo_ret(sd);
+
+ if(sd->status.guild_id <= 0)
+ return 2;
+
+ if(sd->state.storage_flag)
+ return 1; //Can't open both storages at a time.
+
+ if( !pc_can_give_items(sd) ) { //check is this GM level can open guild storage and store items [Lupus]
+ clif_displaymessage(sd->fd, msg_txt(246));
+ return 1;
+ }
+
+ if((gstor = guild2storage2(sd->status.guild_id)) == NULL) {
+ intif_request_guild_storage(sd->status.account_id,sd->status.guild_id);
+ return 0;
+ }
+ if(gstor->storage_status)
+ return 1;
+
+ gstor->storage_status = 1;
+ sd->state.storage_flag = 2;
+ storage_sortitem(gstor->items, ARRAYLENGTH(gstor->items));
+ clif_storagelist(sd, gstor->items, ARRAYLENGTH(gstor->items));
+ clif_updatestorageamount(sd, gstor->storage_amount, MAX_GUILD_STORAGE);
+ return 0;
}
/*==========================================
* Attempt to add an item in guild storage, then refresh it
* return
-* 0 : success
-* 1 : fail
+* 0 : success
+* 1 : fail
*------------------------------------------*/
-int guild_storage_additem(struct map_session_data *sd, struct guild_storage *stor, struct item *item_data, int amount)
+int guild_storage_additem(struct map_session_data* sd, struct guild_storage* stor, struct item* item_data, int amount)
{
- struct item_data *data;
- int i;
-
- nullpo_retr(1, sd);
- nullpo_retr(1, stor);
- nullpo_retr(1, item_data);
-
- if (item_data->nameid <= 0 || amount <= 0)
- return 1;
-
- data = itemdb_search(item_data->nameid);
-
- if (data->stack.guildstorage && amount > data->stack.amount) {
- // item stack limitation
- return 1;
- }
-
- if (!itemdb_canguildstore(item_data, pc_get_group_level(sd)) || item_data->expire_time) {
- //Check if item is storable. [Skotlex]
- clif_displaymessage(sd->fd, msg_txt(264));
- return 1;
- }
-
- if (itemdb_isstackable2(data)) { //Stackable
- for (i=0; i<MAX_GUILD_STORAGE; i++) {
- if (compare_item(&stor->items[i], item_data)) {
- if (amount > MAX_AMOUNT - stor->items[i].amount || (data->stack.guildstorage && amount > data->stack.amount - stor->items[i].amount))
- return 1;
- stor->items[i].amount+=amount;
- clif_storageitemadded(sd,&stor->items[i],i,amount);
- stor->dirty = 1;
- return 0;
- }
- }
- }
- //Add item
- for (i=0; i<MAX_GUILD_STORAGE && stor->items[i].nameid; i++);
-
- if (i>=MAX_GUILD_STORAGE)
- return 1;
-
- memcpy(&stor->items[i],item_data,sizeof(stor->items[0]));
- stor->items[i].amount=amount;
- stor->storage_amount++;
- clif_storageitemadded(sd,&stor->items[i],i,amount);
- clif_updatestorageamount(sd, stor->storage_amount, MAX_GUILD_STORAGE);
- stor->dirty = 1;
- return 0;
+ struct item_data *data;
+ int i;
+
+ nullpo_retr(1, sd);
+ nullpo_retr(1, stor);
+ nullpo_retr(1, item_data);
+
+ if(item_data->nameid <= 0 || amount <= 0)
+ return 1;
+
+ data = itemdb_search(item_data->nameid);
+
+ if( data->stack.guildstorage && amount > data->stack.amount )
+ {// item stack limitation
+ return 1;
+ }
+
+ if( !itemdb_canguildstore(item_data, pc_get_group_level(sd)) || item_data->expire_time )
+ { //Check if item is storable. [Skotlex]
+ clif_displaymessage (sd->fd, msg_txt(264));
+ return 1;
+ }
+
+ if(itemdb_isstackable2(data)){ //Stackable
+ for(i=0;i<MAX_GUILD_STORAGE;i++){
+ if(compare_item(&stor->items[i], item_data)) {
+ if( amount > MAX_AMOUNT - stor->items[i].amount || ( data->stack.guildstorage && amount > data->stack.amount - stor->items[i].amount ) )
+ return 1;
+ stor->items[i].amount+=amount;
+ clif_storageitemadded(sd,&stor->items[i],i,amount);
+ stor->dirty = 1;
+ return 0;
+ }
+ }
+ }
+ //Add item
+ for(i=0;i<MAX_GUILD_STORAGE && stor->items[i].nameid;i++);
+
+ if(i>=MAX_GUILD_STORAGE)
+ return 1;
+
+ memcpy(&stor->items[i],item_data,sizeof(stor->items[0]));
+ stor->items[i].amount=amount;
+ stor->storage_amount++;
+ clif_storageitemadded(sd,&stor->items[i],i,amount);
+ clif_updatestorageamount(sd, stor->storage_amount, MAX_GUILD_STORAGE);
+ stor->dirty = 1;
+ return 0;
}
/*==========================================
* Attempt to delete an item in guild storage, then refresh it
* return
-* 0 : success
-* 1 : fail
+* 0 : success
+* 1 : fail
*------------------------------------------*/
-int guild_storage_delitem(struct map_session_data *sd, struct guild_storage *stor, int n, int amount)
+int guild_storage_delitem(struct map_session_data* sd, struct guild_storage* stor, int n, int amount)
{
- nullpo_retr(1, sd);
- nullpo_retr(1, stor);
-
- if (stor->items[n].nameid==0 || stor->items[n].amount<amount)
- return 1;
-
- stor->items[n].amount-=amount;
- if (stor->items[n].amount==0) {
- memset(&stor->items[n],0,sizeof(stor->items[0]));
- stor->storage_amount--;
- clif_updatestorageamount(sd, stor->storage_amount, MAX_GUILD_STORAGE);
- }
- clif_storageitemremoved(sd,n,amount);
- stor->dirty = 1;
- return 0;
+ nullpo_retr(1, sd);
+ nullpo_retr(1, stor);
+
+ if(stor->items[n].nameid==0 || stor->items[n].amount<amount)
+ return 1;
+
+ stor->items[n].amount-=amount;
+ if(stor->items[n].amount==0){
+ memset(&stor->items[n],0,sizeof(stor->items[0]));
+ stor->storage_amount--;
+ clif_updatestorageamount(sd, stor->storage_amount, MAX_GUILD_STORAGE);
+ }
+ clif_storageitemremoved(sd,n,amount);
+ stor->dirty = 1;
+ return 0;
}
/*==========================================
* Attempt to add an item in guild storage from inventory, then refresh it
* @index : inventory idx
* return
-* 0 : fail
-* 1 : succes
+* 0 : fail
+* 1 : succes
*------------------------------------------*/
-int storage_guild_storageadd(struct map_session_data *sd, int index, int amount)
+int storage_guild_storageadd(struct map_session_data* sd, int index, int amount)
{
- struct guild_storage *stor;
-
- nullpo_ret(sd);
- nullpo_ret(stor=guild2storage2(sd->status.guild_id));
-
- if (!stor->storage_status || stor->storage_amount > MAX_GUILD_STORAGE)
- return 0;
-
- if (index<0 || index>=MAX_INVENTORY)
- return 0;
-
- if (sd->status.inventory[index].nameid <= 0)
- return 0;
-
- if (amount < 1 || amount > sd->status.inventory[index].amount)
- return 0;
-
- if (guild_storage_additem(sd,stor,&sd->status.inventory[index],amount)==0)
- pc_delitem(sd,index,amount,0,4,LOG_TYPE_GSTORAGE);
-
- return 1;
+ struct guild_storage *stor;
+
+ nullpo_ret(sd);
+ nullpo_ret(stor=guild2storage2(sd->status.guild_id));
+
+ if( !stor->storage_status || stor->storage_amount > MAX_GUILD_STORAGE )
+ return 0;
+
+ if( index<0 || index>=MAX_INVENTORY )
+ return 0;
+
+ if( sd->status.inventory[index].nameid <= 0 )
+ return 0;
+
+ if( amount < 1 || amount > sd->status.inventory[index].amount )
+ return 0;
+
+ if(guild_storage_additem(sd,stor,&sd->status.inventory[index],amount)==0)
+ pc_delitem(sd,index,amount,0,4,LOG_TYPE_GSTORAGE);
+
+ return 1;
}
/*==========================================
* Attempt to retrieve an item from guild storage to inventory, then refresh it
* @index : storage idx
* return
-* 0 : fail
-* 1 : succes
+* 0 : fail
+* 1 : succes
*------------------------------------------*/
-int storage_guild_storageget(struct map_session_data *sd, int index, int amount)
+int storage_guild_storageget(struct map_session_data* sd, int index, int amount)
{
- struct guild_storage *stor;
- int flag;
-
- nullpo_ret(sd);
- nullpo_ret(stor=guild2storage2(sd->status.guild_id));
-
- if (!stor->storage_status)
- return 0;
-
- if (index<0 || index>=MAX_GUILD_STORAGE)
- return 0;
-
- if (stor->items[index].nameid <= 0)
- return 0;
-
- if (amount < 1 || amount > stor->items[index].amount)
- return 0;
-
- if ((flag = pc_additem(sd,&stor->items[index],amount,LOG_TYPE_GSTORAGE)) == 0)
- guild_storage_delitem(sd,stor,index,amount);
- else //inform fail
- clif_additem(sd,0,0,flag);
- // log_fromstorage(sd, index, 1);
-
- return 0;
+ struct guild_storage *stor;
+ int flag;
+
+ nullpo_ret(sd);
+ nullpo_ret(stor=guild2storage2(sd->status.guild_id));
+
+ if(!stor->storage_status)
+ return 0;
+
+ if(index<0 || index>=MAX_GUILD_STORAGE)
+ return 0;
+
+ if(stor->items[index].nameid <= 0)
+ return 0;
+
+ if(amount < 1 || amount > stor->items[index].amount)
+ return 0;
+
+ if((flag = pc_additem(sd,&stor->items[index],amount,LOG_TYPE_GSTORAGE)) == 0)
+ guild_storage_delitem(sd,stor,index,amount);
+ else //inform fail
+ clif_additem(sd,0,0,flag);
+// log_fromstorage(sd, index, 1);
+
+ return 0;
}
/*==========================================
* Attempt to add an item in guild storage from cart, then refresh it
* @index : cart inventory idx
* return
-* 0 : fail
-* 1 : succes
+* 0 : fail
+* 1 : succes
*------------------------------------------*/
-int storage_guild_storageaddfromcart(struct map_session_data *sd, int index, int amount)
+int storage_guild_storageaddfromcart(struct map_session_data* sd, int index, int amount)
{
- struct guild_storage *stor;
+ struct guild_storage *stor;
- nullpo_ret(sd);
- nullpo_ret(stor=guild2storage2(sd->status.guild_id));
+ nullpo_ret(sd);
+ nullpo_ret(stor=guild2storage2(sd->status.guild_id));
- if (!stor->storage_status || stor->storage_amount > MAX_GUILD_STORAGE)
- return 0;
+ if( !stor->storage_status || stor->storage_amount > MAX_GUILD_STORAGE )
+ return 0;
- if (index < 0 || index >= MAX_CART)
- return 0;
+ if( index < 0 || index >= MAX_CART )
+ return 0;
- if (sd->status.cart[index].nameid <= 0)
- return 0;
+ if( sd->status.cart[index].nameid <= 0 )
+ return 0;
+
+ if( amount < 1 || amount > sd->status.cart[index].amount )
+ return 0;
- if (amount < 1 || amount > sd->status.cart[index].amount)
- return 0;
+ if(guild_storage_additem(sd,stor,&sd->status.cart[index],amount)==0)
+ pc_cart_delitem(sd,index,amount,0,LOG_TYPE_GSTORAGE);
- if (guild_storage_additem(sd,stor,&sd->status.cart[index],amount)==0)
- pc_cart_delitem(sd,index,amount,0,LOG_TYPE_GSTORAGE);
-
- return 1;
+ return 1;
}
/*==========================================
* Attempt to retrieve an item from guild storage to cart, then refresh it
* @index : storage idx
* return
-* 0 : fail
-* 1 : succes
+* 0 : fail
+* 1 : succes
*------------------------------------------*/
-int storage_guild_storagegettocart(struct map_session_data *sd, int index, int amount)
+int storage_guild_storagegettocart(struct map_session_data* sd, int index, int amount)
{
- struct guild_storage *stor;
-
- nullpo_ret(sd);
- nullpo_ret(stor=guild2storage2(sd->status.guild_id));
-
- if (!stor->storage_status)
- return 0;
+ struct guild_storage *stor;
- if (index<0 || index>=MAX_GUILD_STORAGE)
- return 0;
+ nullpo_ret(sd);
+ nullpo_ret(stor=guild2storage2(sd->status.guild_id));
- if (stor->items[index].nameid<=0)
- return 0;
+ if(!stor->storage_status)
+ return 0;
- if (amount < 1 || amount > stor->items[index].amount)
- return 0;
+ if(index<0 || index>=MAX_GUILD_STORAGE)
+ return 0;
+
+ if(stor->items[index].nameid<=0)
+ return 0;
+
+ if(amount < 1 || amount > stor->items[index].amount)
+ return 0;
- if (pc_cart_additem(sd,&stor->items[index],amount,LOG_TYPE_GSTORAGE)==0)
- guild_storage_delitem(sd,stor,index,amount);
+ if(pc_cart_additem(sd,&stor->items[index],amount,LOG_TYPE_GSTORAGE)==0)
+ guild_storage_delitem(sd,stor,index,amount);
- return 1;
+ return 1;
}
/*==========================================
* Request to save guild storage
* return
-* 0 : fail (no storage)
-* 1 : succes
+* 0 : fail (no storage)
+* 1 : succes
*------------------------------------------*/
int storage_guild_storagesave(int account_id, int guild_id, int flag)
{
- struct guild_storage *stor = guild2storage2(guild_id);
-
- if (stor) {
- if (flag) //Char quitting, close it.
- stor->storage_status = 0;
- if (stor->dirty)
- intif_send_guild_storage(account_id,stor);
- return 1;
- }
- return 0;
+ struct guild_storage *stor = guild2storage2(guild_id);
+
+ if(stor)
+ {
+ if (flag) //Char quitting, close it.
+ stor->storage_status = 0;
+ if (stor->dirty)
+ intif_send_guild_storage(account_id,stor);
+ return 1;
+ }
+ return 0;
}
/*==========================================
* ACK save of guild storage
* return
-* 0 : fail (no storage)
-* 1 : succes
+* 0 : fail (no storage)
+* 1 : succes
*------------------------------------------*/
int storage_guild_storagesaved(int guild_id)
{
- struct guild_storage *stor;
-
- if ((stor=guild2storage2(guild_id)) != NULL) {
- if (stor->dirty && stor->storage_status == 0) {
- //Storage has been correctly saved.
- stor->dirty = 0;
- }
- return 1;
- }
- return 0;
+ struct guild_storage *stor;
+
+ if((stor=guild2storage2(guild_id)) != NULL) {
+ if (stor->dirty && stor->storage_status == 0)
+ { //Storage has been correctly saved.
+ stor->dirty = 0;
+ }
+ return 1;
+ }
+ return 0;
}
//Close storage for sd and save it
-int storage_guild_storageclose(struct map_session_data *sd)
+int storage_guild_storageclose(struct map_session_data* sd)
{
- struct guild_storage *stor;
-
- nullpo_ret(sd);
- nullpo_ret(stor=guild2storage2(sd->status.guild_id));
-
- clif_storageclose(sd);
- if (stor->storage_status) {
- if (save_settings&4)
- chrif_save(sd, 0); //This one also saves the storage. [Skotlex]
- else
- storage_guild_storagesave(sd->status.account_id, sd->status.guild_id,0);
- stor->storage_status=0;
- }
- sd->state.storage_flag = 0;
-
- return 0;
+ struct guild_storage *stor;
+
+ nullpo_ret(sd);
+ nullpo_ret(stor=guild2storage2(sd->status.guild_id));
+
+ clif_storageclose(sd);
+ if (stor->storage_status)
+ {
+ if (save_settings&4)
+ chrif_save(sd, 0); //This one also saves the storage. [Skotlex]
+ else
+ storage_guild_storagesave(sd->status.account_id, sd->status.guild_id,0);
+ stor->storage_status=0;
+ }
+ sd->state.storage_flag = 0;
+
+ return 0;
}
-int storage_guild_storage_quit(struct map_session_data *sd, int flag)
+int storage_guild_storage_quit(struct map_session_data* sd, int flag)
{
- struct guild_storage *stor;
-
- nullpo_ret(sd);
- nullpo_ret(stor=guild2storage2(sd->status.guild_id));
-
- if (flag) {
- //Only during a guild break flag is 1 (don't save storage)
- sd->state.storage_flag = 0;
- stor->storage_status = 0;
- clif_storageclose(sd);
- if (save_settings&4)
- chrif_save(sd,0);
- return 0;
- }
-
- if (stor->storage_status) {
- if (save_settings&4)
- chrif_save(sd,0);
- else
- storage_guild_storagesave(sd->status.account_id,sd->status.guild_id,1);
- }
- sd->state.storage_flag = 0;
- stor->storage_status = 0;
-
- return 0;
+ struct guild_storage *stor;
+
+ nullpo_ret(sd);
+ nullpo_ret(stor=guild2storage2(sd->status.guild_id));
+
+ if(flag)
+ { //Only during a guild break flag is 1 (don't save storage)
+ sd->state.storage_flag = 0;
+ stor->storage_status = 0;
+ clif_storageclose(sd);
+ if (save_settings&4)
+ chrif_save(sd,0);
+ return 0;
+ }
+
+ if(stor->storage_status) {
+ if (save_settings&4)
+ chrif_save(sd,0);
+ else
+ storage_guild_storagesave(sd->status.account_id,sd->status.guild_id,1);
+ }
+ sd->state.storage_flag = 0;
+ stor->storage_status = 0;
+
+ return 0;
}
diff --git a/src/map/storage.h b/src/map/storage.h
index 8483ff012..5a38d865b 100644
--- a/src/map/storage.h
+++ b/src/map/storage.h
@@ -11,7 +11,7 @@ struct item;
//#include "map.h"
struct map_session_data;
-int storage_delitem(struct map_session_data *sd, int n, int amount);
+int storage_delitem(struct map_session_data* sd, int n, int amount);
int storage_storageopen(struct map_session_data *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);
@@ -23,7 +23,7 @@ void do_final_storage(void);
void do_reconnect_storage(void);
void storage_storage_quit(struct map_session_data *sd, int flag);
-struct guild_storage *guild2storage(int guild_id);
+struct guild_storage* guild2storage(int guild_id);
int guild_storage_delete(int guild_id);
int storage_guild_storageopen(struct map_session_data *sd);
int guild_storage_additem(struct map_session_data *sd,struct guild_storage *stor,struct item *item_data,int amount);
diff --git a/src/map/trade.c b/src/map/trade.c
index 2196a74cc..0d01b54a6 100644
--- a/src/map/trade.c
+++ b/src/map/trade.c
@@ -29,62 +29,63 @@
*------------------------------------------*/
void trade_traderequest(struct map_session_data *sd, struct map_session_data *target_sd)
{
- nullpo_retv(sd);
-
- if (map[sd->bl.m].flag.notrade) {
- clif_displaymessage(sd->fd, msg_txt(272));
- return; //Can't trade in notrade mapflag maps.
- }
-
- if (target_sd == NULL || sd == target_sd) {
- clif_tradestart(sd, 1); // character does not exist
- return;
- }
-
- if (target_sd->npc_id) {
- //Trade fails if you are using an NPC.
- clif_tradestart(sd, 2);
- return;
- }
-
- if (!battle_config.invite_request_check) {
- if (target_sd->guild_invite > 0 || target_sd->party_invite > 0 || target_sd->adopt_invite) {
- clif_tradestart(sd, 2);
- return;
- }
- }
-
- if (sd->trade_partner != 0) { // If a character tries to trade to another one then cancel the previous one
- struct map_session_data *previous_sd = map_id2sd(sd->trade_partner);
- if (previous_sd) {
- previous_sd->trade_partner = 0;
- clif_tradecancelled(previous_sd);
- } // Once cancelled then continue to the new one.
- sd->trade_partner = 0;
- clif_tradecancelled(sd);
- }
-
- if (target_sd->trade_partner != 0) {
- clif_tradestart(sd, 2); // person is in another trade
- return;
- }
-
- if (!pc_can_give_items(sd) || !pc_can_give_items(target_sd)) { //check if both GMs are allowed to trade
- clif_displaymessage(sd->fd, msg_txt(246));
- clif_tradestart(sd, 2); // GM is not allowed to trade
- return;
- }
-
- // Players can not request trade from far away, unless they are allowed to use @trade.
- if (!pc_can_use_command(sd, "trade", COMMAND_ATCOMMAND) &&
- (sd->bl.m != target_sd->bl.m || !check_distance_bl(&sd->bl, &target_sd->bl, TRADE_DISTANCE))) {
- clif_tradestart(sd, 0); // too far
- return ;
- }
-
- target_sd->trade_partner = sd->status.account_id;
- sd->trade_partner = target_sd->status.account_id;
- clif_traderequest(target_sd, sd->status.name);
+ nullpo_retv(sd);
+
+ if (map[sd->bl.m].flag.notrade) {
+ clif_displaymessage (sd->fd, msg_txt(272));
+ return; //Can't trade in notrade mapflag maps.
+ }
+
+ if (target_sd == NULL || sd == target_sd) {
+ clif_tradestart(sd, 1); // character does not exist
+ return;
+ }
+
+ if (target_sd->npc_id)
+ { //Trade fails if you are using an NPC.
+ clif_tradestart(sd, 2);
+ return;
+ }
+
+ if (!battle_config.invite_request_check) {
+ if (target_sd->guild_invite > 0 || target_sd->party_invite > 0 || target_sd->adopt_invite) {
+ clif_tradestart(sd, 2);
+ return;
+ }
+ }
+
+ if ( sd->trade_partner != 0 ) { // If a character tries to trade to another one then cancel the previous one
+ struct map_session_data *previous_sd = map_id2sd(sd->trade_partner);
+ if( previous_sd ){
+ previous_sd->trade_partner = 0;
+ clif_tradecancelled(previous_sd);
+ } // Once cancelled then continue to the new one.
+ sd->trade_partner = 0;
+ clif_tradecancelled(sd);
+ }
+
+ if (target_sd->trade_partner != 0) {
+ clif_tradestart(sd, 2); // person is in another trade
+ return;
+ }
+
+ if (!pc_can_give_items(sd) || !pc_can_give_items(target_sd)) //check if both GMs are allowed to trade
+ {
+ clif_displaymessage(sd->fd, msg_txt(246));
+ clif_tradestart(sd, 2); // GM is not allowed to trade
+ return;
+ }
+
+ // Players can not request trade from far away, unless they are allowed to use @trade.
+ if (!pc_can_use_command(sd, "trade", COMMAND_ATCOMMAND) &&
+ (sd->bl.m != target_sd->bl.m || !check_distance_bl(&sd->bl, &target_sd->bl, TRADE_DISTANCE))) {
+ clif_tradestart(sd, 0); // too far
+ return ;
+ }
+
+ target_sd->trade_partner = sd->status.account_id;
+ sd->trade_partner = target_sd->status.account_id;
+ clif_traderequest(target_sd, sd->status.name);
}
/*==========================================
@@ -100,67 +101,68 @@ void trade_traderequest(struct map_session_data *sd, struct map_session_data *ta
*------------------------------------------*/
void trade_tradeack(struct map_session_data *sd, int type)
{
- struct map_session_data *tsd;
- nullpo_retv(sd);
-
- if (sd->state.trading || !sd->trade_partner)
- return; //Already trading or no partner set.
-
- if ((tsd = map_id2sd(sd->trade_partner)) == NULL) {
- clif_tradestart(sd, 1); // character does not exist
- sd->trade_partner=0;
- return;
- }
-
- if (tsd->state.trading || tsd->trade_partner != sd->bl.id) {
- clif_tradestart(sd, 2);
- sd->trade_partner=0;
- return; //Already trading or wrong partner.
- }
-
- if (type == 4) { // Cancel
- clif_tradestart(tsd, type);
- clif_tradestart(sd, type);
- sd->state.deal_locked = 0;
- sd->trade_partner = 0;
- tsd->state.deal_locked = 0;
- tsd->trade_partner = 0;
- return;
- }
-
- if (type != 3)
- return; //If client didn't send accept, it's a broken packet?
-
- // Players can not request trade from far away, unless they are allowed to use @trade.
- // Check here as well since the original character could had warped.
- if (!pc_can_use_command(sd, "trade", COMMAND_ATCOMMAND) &&
- (sd->bl.m != tsd->bl.m || !check_distance_bl(&sd->bl, &tsd->bl, TRADE_DISTANCE))) {
- clif_tradestart(sd, 0); // too far
- sd->trade_partner=0;
- tsd->trade_partner = 0;
- return;
- }
-
- //Check if you can start trade.
- if (sd->npc_id || sd->state.vending || sd->state.buyingstore || sd->state.storage_flag ||
- tsd->npc_id || tsd->state.vending || tsd->state.buyingstore || tsd->state.storage_flag) {
- //Fail
- clif_tradestart(sd, 2);
- clif_tradestart(tsd, 2);
- sd->state.deal_locked = 0;
- sd->trade_partner = 0;
- tsd->state.deal_locked = 0;
- tsd->trade_partner = 0;
- return;
- }
-
- //Initiate trade
- sd->state.trading = 1;
- tsd->state.trading = 1;
- memset(&sd->deal, 0, sizeof(sd->deal));
- memset(&tsd->deal, 0, sizeof(tsd->deal));
- clif_tradestart(tsd, type);
- clif_tradestart(sd, type);
+ struct map_session_data *tsd;
+ nullpo_retv(sd);
+
+ if (sd->state.trading || !sd->trade_partner)
+ return; //Already trading or no partner set.
+
+ if ((tsd = map_id2sd(sd->trade_partner)) == NULL) {
+ clif_tradestart(sd, 1); // character does not exist
+ sd->trade_partner=0;
+ return;
+ }
+
+ if (tsd->state.trading || tsd->trade_partner != sd->bl.id)
+ {
+ clif_tradestart(sd, 2);
+ sd->trade_partner=0;
+ return; //Already trading or wrong partner.
+ }
+
+ if (type == 4) { // Cancel
+ clif_tradestart(tsd, type);
+ clif_tradestart(sd, type);
+ sd->state.deal_locked = 0;
+ sd->trade_partner = 0;
+ tsd->state.deal_locked = 0;
+ tsd->trade_partner = 0;
+ return;
+ }
+
+ if (type != 3)
+ return; //If client didn't send accept, it's a broken packet?
+
+ // Players can not request trade from far away, unless they are allowed to use @trade.
+ // Check here as well since the original character could had warped.
+ if (!pc_can_use_command(sd, "trade", COMMAND_ATCOMMAND) &&
+ (sd->bl.m != tsd->bl.m || !check_distance_bl(&sd->bl, &tsd->bl, TRADE_DISTANCE))) {
+ clif_tradestart(sd, 0); // too far
+ sd->trade_partner=0;
+ tsd->trade_partner = 0;
+ return;
+ }
+
+ //Check if you can start trade.
+ if (sd->npc_id || sd->state.vending || sd->state.buyingstore || sd->state.storage_flag ||
+ tsd->npc_id || tsd->state.vending || tsd->state.buyingstore || tsd->state.storage_flag)
+ { //Fail
+ clif_tradestart(sd, 2);
+ clif_tradestart(tsd, 2);
+ sd->state.deal_locked = 0;
+ sd->trade_partner = 0;
+ tsd->state.deal_locked = 0;
+ tsd->trade_partner = 0;
+ return;
+ }
+
+ //Initiate trade
+ sd->state.trading = 1;
+ tsd->state.trading = 1;
+ memset(&sd->deal, 0, sizeof(sd->deal));
+ memset(&tsd->deal, 0, sizeof(tsd->deal));
+ clif_tradestart(tsd, type);
+ clif_tradestart(sd, type);
}
/*==========================================
@@ -170,60 +172,61 @@ void trade_tradeack(struct map_session_data *sd, int type)
*------------------------------------------*/
int impossible_trade_check(struct map_session_data *sd)
{
- struct item inventory[MAX_INVENTORY];
- char message_to_gm[200];
- int i, index;
-
- nullpo_retr(1, sd);
-
- if (sd->deal.zeny > sd->status.zeny) {
- pc_setglobalreg(sd,"ZENY_HACKER",1);
- return -1;
- }
-
- // get inventory of player
- memcpy(&inventory, &sd->status.inventory, sizeof(struct item) * MAX_INVENTORY);
-
- // remove this part: arrows can be trade and equiped
- // re-added! [celest]
- // remove equiped items (they can not be trade)
- for (i = 0; i < MAX_INVENTORY; i++)
- if (inventory[i].nameid > 0 && inventory[i].equip && !(inventory[i].equip & EQP_AMMO))
- memset(&inventory[i], 0, sizeof(struct item));
-
- // check items in player inventory
- for (i = 0; i < 10; i++) {
- if (!sd->deal.item[i].amount)
- continue;
- index = sd->deal.item[i].index;
- if (inventory[index].amount < sd->deal.item[i].amount) {
- // if more than the player have -> hack
- 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, PC_PERM_RECEIVE_HACK_INFO, message_to_gm);
- sprintf(message_to_gm, msg_txt(539), inventory[index].amount, inventory[index].nameid, sd->deal.item[i].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, PC_PERM_RECEIVE_HACK_INFO, 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
- set_eof(sd->fd); // forced to disconnect because of the hack
- // message about the ban
- strcpy(message_to_gm, msg_txt(540)); // This player has been definitively 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)
- set_eof(sd->fd); // forced to disconnect because of the hack
- // message about the ban
- sprintf(message_to_gm, msg_txt(507), battle_config.ban_hack_trade); // This player has been banned for %d minute(s).
- } else
- // message about the ban
- strcpy(message_to_gm, msg_txt(508)); // This player hasn't been banned (Ban option is disabled).
-
- intif_wis_message_to_gm(wisp_server_name, PC_PERM_RECEIVE_HACK_INFO, message_to_gm);
- return 1;
- }
- inventory[index].amount -= sd->deal.item[i].amount; // remove item from inventory
- }
- return 0;
+ struct item inventory[MAX_INVENTORY];
+ char message_to_gm[200];
+ int i, index;
+
+ nullpo_retr(1, sd);
+
+ if(sd->deal.zeny > sd->status.zeny)
+ {
+ pc_setglobalreg(sd,"ZENY_HACKER",1);
+ return -1;
+ }
+
+ // get inventory of player
+ memcpy(&inventory, &sd->status.inventory, sizeof(struct item) * MAX_INVENTORY);
+
+ // remove this part: arrows can be trade and equiped
+ // re-added! [celest]
+ // remove equiped items (they can not be trade)
+ for (i = 0; i < MAX_INVENTORY; i++)
+ if (inventory[i].nameid > 0 && inventory[i].equip && !(inventory[i].equip & EQP_AMMO))
+ memset(&inventory[i], 0, sizeof(struct item));
+
+ // check items in player inventory
+ for(i = 0; i < 10; i++) {
+ if (!sd->deal.item[i].amount)
+ continue;
+ index = sd->deal.item[i].index;
+ if (inventory[index].amount < sd->deal.item[i].amount)
+ { // if more than the player have -> hack
+ 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, PC_PERM_RECEIVE_HACK_INFO, message_to_gm);
+ sprintf(message_to_gm, msg_txt(539), inventory[index].amount, inventory[index].nameid, sd->deal.item[i].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, PC_PERM_RECEIVE_HACK_INFO, 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
+ set_eof(sd->fd); // forced to disconnect because of the hack
+ // message about the ban
+ strcpy(message_to_gm, msg_txt(540)); // This player has been definitively 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)
+ set_eof(sd->fd); // forced to disconnect because of the hack
+ // message about the ban
+ sprintf(message_to_gm, msg_txt(507), battle_config.ban_hack_trade); // This player has been banned for %d minute(s).
+ } else
+ // message about the ban
+ strcpy(message_to_gm, msg_txt(508)); // This player hasn't been banned (Ban option is disabled).
+
+ intif_wis_message_to_gm(wisp_server_name, PC_PERM_RECEIVE_HACK_INFO, message_to_gm);
+ return 1;
+ }
+ inventory[index].amount -= sd->deal.item[i].amount; // remove item from inventory
+ }
+ return 0;
}
/*==========================================
@@ -231,86 +234,86 @@ int impossible_trade_check(struct map_session_data *sd)
*------------------------------------------*/
int trade_check(struct map_session_data *sd, struct map_session_data *tsd)
{
- struct item inventory[MAX_INVENTORY];
- struct item inventory2[MAX_INVENTORY];
- struct item_data *data;
- int trade_i, i, n;
- short amount;
-
- // check zenys value against hackers (Zeny was already checked on time of adding, but you never know when you lost some zeny since then.
- if (sd->deal.zeny > sd->status.zeny || (tsd->status.zeny > MAX_ZENY - sd->deal.zeny))
- return 0;
- if (tsd->deal.zeny > tsd->status.zeny || (sd->status.zeny > MAX_ZENY - tsd->deal.zeny))
- return 0;
-
- // get inventory of player
- memcpy(&inventory, &sd->status.inventory, sizeof(struct item) * MAX_INVENTORY);
- memcpy(&inventory2, &tsd->status.inventory, sizeof(struct item) * MAX_INVENTORY);
-
- // check free slot in both inventory
- for (trade_i = 0; trade_i < 10; trade_i++) {
- amount = sd->deal.item[trade_i].amount;
- if (amount) {
- n = sd->deal.item[trade_i].index;
- if (amount > inventory[n].amount)
- return 0; //qty Exploit?
-
- data = itemdb_search(inventory[n].nameid);
- i = MAX_INVENTORY;
- if (itemdb_isstackable2(data)) { //Stackable item.
- for (i = 0; i < MAX_INVENTORY; i++)
- if (inventory2[i].nameid == inventory[n].nameid &&
- inventory2[i].card[0] == inventory[n].card[0] && inventory2[i].card[1] == inventory[n].card[1] &&
- inventory2[i].card[2] == inventory[n].card[2] && inventory2[i].card[3] == inventory[n].card[3]) {
- if (inventory2[i].amount + amount > MAX_AMOUNT)
- return 0;
- inventory2[i].amount += amount;
- inventory[n].amount -= amount;
- break;
- }
- }
-
- if (i == MAX_INVENTORY) {// look for an empty slot.
- for (i = 0; i < MAX_INVENTORY && inventory2[i].nameid; i++);
- if (i == MAX_INVENTORY)
- return 0;
- memcpy(&inventory2[i], &inventory[n], sizeof(struct item));
- inventory2[i].amount = amount;
- inventory[n].amount -= amount;
- }
- }
- amount = tsd->deal.item[trade_i].amount;
- if (!amount)
- continue;
- n = tsd->deal.item[trade_i].index;
- if (amount > inventory2[n].amount)
- return 0;
- // search if it's possible to add item (for full inventory)
- data = itemdb_search(inventory2[n].nameid);
- i = MAX_INVENTORY;
- if (itemdb_isstackable2(data)) {
- for (i = 0; i < MAX_INVENTORY; i++)
- if (inventory[i].nameid == inventory2[n].nameid &&
- inventory[i].card[0] == inventory2[n].card[0] && inventory[i].card[1] == inventory2[n].card[1] &&
- inventory[i].card[2] == inventory2[n].card[2] && inventory[i].card[3] == inventory2[n].card[3]) {
- if (inventory[i].amount + amount > MAX_AMOUNT)
- return 0;
- inventory[i].amount += amount;
- inventory2[n].amount -= amount;
- break;
- }
- }
- if (i == MAX_INVENTORY) {
- for (i = 0; i < MAX_INVENTORY && inventory[i].nameid; i++);
- if (i == MAX_INVENTORY)
- return 0;
- memcpy(&inventory[i], &inventory2[n], sizeof(struct item));
- inventory[i].amount = amount;
- inventory2[n].amount -= amount;
- }
- }
-
- return 1;
+ struct item inventory[MAX_INVENTORY];
+ struct item inventory2[MAX_INVENTORY];
+ struct item_data *data;
+ int trade_i, i, n;
+ short amount;
+
+ // check zenys value against hackers (Zeny was already checked on time of adding, but you never know when you lost some zeny since then.
+ if(sd->deal.zeny > sd->status.zeny || (tsd->status.zeny > MAX_ZENY - sd->deal.zeny))
+ return 0;
+ if(tsd->deal.zeny > tsd->status.zeny || (sd->status.zeny > MAX_ZENY - tsd->deal.zeny))
+ return 0;
+
+ // get inventory of player
+ memcpy(&inventory, &sd->status.inventory, sizeof(struct item) * MAX_INVENTORY);
+ memcpy(&inventory2, &tsd->status.inventory, sizeof(struct item) * MAX_INVENTORY);
+
+ // check free slot in both inventory
+ for(trade_i = 0; trade_i < 10; trade_i++) {
+ amount = sd->deal.item[trade_i].amount;
+ if (amount) {
+ n = sd->deal.item[trade_i].index;
+ if (amount > inventory[n].amount)
+ return 0; //qty Exploit?
+
+ data = itemdb_search(inventory[n].nameid);
+ i = MAX_INVENTORY;
+ if (itemdb_isstackable2(data)) { //Stackable item.
+ for(i = 0; i < MAX_INVENTORY; i++)
+ if (inventory2[i].nameid == inventory[n].nameid &&
+ inventory2[i].card[0] == inventory[n].card[0] && inventory2[i].card[1] == inventory[n].card[1] &&
+ inventory2[i].card[2] == inventory[n].card[2] && inventory2[i].card[3] == inventory[n].card[3]) {
+ if (inventory2[i].amount + amount > MAX_AMOUNT)
+ return 0;
+ inventory2[i].amount += amount;
+ inventory[n].amount -= amount;
+ break;
+ }
+ }
+
+ if (i == MAX_INVENTORY) {// look for an empty slot.
+ for(i = 0; i < MAX_INVENTORY && inventory2[i].nameid; i++);
+ if (i == MAX_INVENTORY)
+ return 0;
+ memcpy(&inventory2[i], &inventory[n], sizeof(struct item));
+ inventory2[i].amount = amount;
+ inventory[n].amount -= amount;
+ }
+ }
+ amount = tsd->deal.item[trade_i].amount;
+ if (!amount)
+ continue;
+ n = tsd->deal.item[trade_i].index;
+ if (amount > inventory2[n].amount)
+ return 0;
+ // search if it's possible to add item (for full inventory)
+ data = itemdb_search(inventory2[n].nameid);
+ i = MAX_INVENTORY;
+ if (itemdb_isstackable2(data)) {
+ for(i = 0; i < MAX_INVENTORY; i++)
+ if (inventory[i].nameid == inventory2[n].nameid &&
+ inventory[i].card[0] == inventory2[n].card[0] && inventory[i].card[1] == inventory2[n].card[1] &&
+ inventory[i].card[2] == inventory2[n].card[2] && inventory[i].card[3] == inventory2[n].card[3]) {
+ if (inventory[i].amount + amount > MAX_AMOUNT)
+ return 0;
+ inventory[i].amount += amount;
+ inventory2[n].amount -= amount;
+ break;
+ }
+ }
+ if (i == MAX_INVENTORY) {
+ for(i = 0; i < MAX_INVENTORY && inventory[i].nameid; i++);
+ if (i == MAX_INVENTORY)
+ return 0;
+ memcpy(&inventory[i], &inventory2[n], sizeof(struct item));
+ inventory[i].amount = amount;
+ inventory2[n].amount -= amount;
+ }
+ }
+
+ return 1;
}
/*==========================================
@@ -318,108 +321,113 @@ int trade_check(struct map_session_data *sd, struct map_session_data *tsd)
*------------------------------------------*/
void trade_tradeadditem(struct map_session_data *sd, short index, short amount)
{
- struct map_session_data *target_sd;
- struct item *item;
- int trade_i, trade_weight;
- int src_lv, dst_lv;
-
- nullpo_retv(sd);
- if (!sd->state.trading || sd->state.deal_locked > 0)
- return; //Can't add stuff.
-
- if ((target_sd = map_id2sd(sd->trade_partner)) == NULL) {
- trade_tradecancel(sd);
- return;
- }
-
- if (amount == 0) {
- //Why do this.. ~.~ just send an ack, the item won't display on the trade window.
- clif_tradeitemok(sd, index, 0);
- return;
- }
-
- index -= 2; // 0 is for zeny, 1 is unknown. Gravity, go figure...
-
- //Item checks...
- if (index < 0 || index >= MAX_INVENTORY)
- return;
- if (amount < 0 || amount > sd->status.inventory[index].amount)
- return;
-
- item = &sd->status.inventory[index];
- src_lv = pc_get_group_level(sd);
- dst_lv = pc_get_group_level(target_sd);
- if (!itemdb_cantrade(item, src_lv, dst_lv) && //Can't trade
- (pc_get_partner(sd) != target_sd || !itemdb_canpartnertrade(item, src_lv, dst_lv))) { //Can't partner-trade
- clif_displaymessage(sd->fd, msg_txt(260));
- clif_tradeitemok(sd, index+2, 1);
- return;
- }
-
- if (item->expire_time) {
- // Rental System
- clif_displaymessage(sd->fd, msg_txt(260));
- clif_tradeitemok(sd, index+2, 1);
- return;
- }
-
- //Locate a trade position
- ARR_FIND(0, 10, trade_i, sd->deal.item[trade_i].index == index || sd->deal.item[trade_i].amount == 0);
- if (trade_i == 10) { //No space left
- clif_tradeitemok(sd, index+2, 1);
- return;
- }
-
- trade_weight = sd->inventory_data[index]->weight * amount;
- if (target_sd->weight + sd->deal.weight + trade_weight > target_sd->max_weight) {
- //fail to add item -- the player was over weighted.
- clif_tradeitemok(sd, index+2, 1);
- return;
- }
-
- if (sd->deal.item[trade_i].index == index) {
- //The same item as before is being readjusted.
- if (sd->deal.item[trade_i].amount + amount > sd->status.inventory[index].amount) {
- //packet deal exploit check
- amount = sd->status.inventory[index].amount - sd->deal.item[trade_i].amount;
- trade_weight = sd->inventory_data[index]->weight * amount;
- }
- sd->deal.item[trade_i].amount += amount;
- } else {
- //New deal item
- sd->deal.item[trade_i].index = index;
- sd->deal.item[trade_i].amount = amount;
- }
- sd->deal.weight += trade_weight;
-
- clif_tradeitemok(sd, index+2, 0); // Return the index as it was received
- clif_tradeadditem(sd, target_sd, index+2, amount);
+ struct map_session_data *target_sd;
+ struct item *item;
+ int trade_i, trade_weight;
+ int src_lv, dst_lv;
+
+ nullpo_retv(sd);
+ if( !sd->state.trading || sd->state.deal_locked > 0 )
+ return; //Can't add stuff.
+
+ if( (target_sd = map_id2sd(sd->trade_partner)) == NULL )
+ {
+ trade_tradecancel(sd);
+ return;
+ }
+
+ if( amount == 0 )
+ { //Why do this.. ~.~ just send an ack, the item won't display on the trade window.
+ clif_tradeitemok(sd, index, 0);
+ return;
+ }
+
+ index -= 2; // 0 is for zeny, 1 is unknown. Gravity, go figure...
+
+ //Item checks...
+ if( index < 0 || index >= MAX_INVENTORY )
+ return;
+ if( amount < 0 || amount > sd->status.inventory[index].amount )
+ return;
+
+ item = &sd->status.inventory[index];
+ src_lv = pc_get_group_level(sd);
+ dst_lv = pc_get_group_level(target_sd);
+ if( !itemdb_cantrade(item, src_lv, dst_lv) && //Can't trade
+ (pc_get_partner(sd) != target_sd || !itemdb_canpartnertrade(item, src_lv, dst_lv)) ) //Can't partner-trade
+ {
+ clif_displaymessage (sd->fd, msg_txt(260));
+ clif_tradeitemok(sd, index+2, 1);
+ return;
+ }
+
+ if( item->expire_time )
+ { // Rental System
+ clif_displaymessage (sd->fd, msg_txt(260));
+ clif_tradeitemok(sd, index+2, 1);
+ return;
+ }
+
+ //Locate a trade position
+ ARR_FIND( 0, 10, trade_i, sd->deal.item[trade_i].index == index || sd->deal.item[trade_i].amount == 0 );
+ if( trade_i == 10 ) //No space left
+ {
+ clif_tradeitemok(sd, index+2, 1);
+ return;
+ }
+
+ trade_weight = sd->inventory_data[index]->weight * amount;
+ if( target_sd->weight + sd->deal.weight + trade_weight > target_sd->max_weight )
+ { //fail to add item -- the player was over weighted.
+ clif_tradeitemok(sd, index+2, 1);
+ return;
+ }
+
+ if( sd->deal.item[trade_i].index == index )
+ { //The same item as before is being readjusted.
+ if( sd->deal.item[trade_i].amount + amount > sd->status.inventory[index].amount )
+ { //packet deal exploit check
+ amount = sd->status.inventory[index].amount - sd->deal.item[trade_i].amount;
+ trade_weight = sd->inventory_data[index]->weight * amount;
+ }
+ sd->deal.item[trade_i].amount += amount;
+ }
+ else
+ { //New deal item
+ sd->deal.item[trade_i].index = index;
+ sd->deal.item[trade_i].amount = amount;
+ }
+ sd->deal.weight += trade_weight;
+
+ clif_tradeitemok(sd, index+2, 0); // Return the index as it was received
+ clif_tradeadditem(sd, target_sd, index+2, amount);
}
/*==========================================
* Adds the specified amount of zeny to the trade window
*------------------------------------------*/
-void trade_tradeaddzeny(struct map_session_data *sd, int amount)
+void trade_tradeaddzeny(struct map_session_data* sd, int amount)
{
- struct map_session_data *target_sd;
- nullpo_retv(sd);
-
- if (!sd->state.trading || sd->state.deal_locked > 0)
- return; //Can't add stuff.
-
- if ((target_sd = map_id2sd(sd->trade_partner)) == NULL) {
- trade_tradecancel(sd);
- return;
- }
-
- if (amount < 0 || amount > sd->status.zeny || amount > MAX_ZENY - target_sd->status.zeny) {
- // invalid values, no appropriate packet for it => abort
- trade_tradecancel(sd);
- return;
- }
-
- sd->deal.zeny = amount;
- clif_tradeadditem(sd, target_sd, 0, amount);
+ struct map_session_data* target_sd;
+ nullpo_retv(sd);
+
+ if( !sd->state.trading || sd->state.deal_locked > 0 )
+ return; //Can't add stuff.
+
+ if( (target_sd = map_id2sd(sd->trade_partner)) == NULL )
+ {
+ trade_tradecancel(sd);
+ return;
+ }
+
+ if( amount < 0 || amount > sd->status.zeny || amount > MAX_ZENY - target_sd->status.zeny )
+ { // invalid values, no appropriate packet for it => abort
+ trade_tradecancel(sd);
+ return;
+ }
+
+ sd->deal.zeny = amount;
+ clif_tradeadditem(sd, target_sd, 0, amount);
}
/*==========================================
@@ -427,19 +435,19 @@ void trade_tradeaddzeny(struct map_session_data *sd, int amount)
*------------------------------------------*/
void trade_tradeok(struct map_session_data *sd)
{
- struct map_session_data *target_sd;
-
- if (sd->state.deal_locked || !sd->state.trading)
- return;
-
- if ((target_sd = map_id2sd(sd->trade_partner)) == NULL) {
- trade_tradecancel(sd);
- return;
- }
- sd->state.deal_locked = 1;
- clif_tradeitemok(sd, 0, 0);
- clif_tradedeal_lock(sd, 0);
- clif_tradedeal_lock(target_sd, 1);
+ struct map_session_data *target_sd;
+
+ if(sd->state.deal_locked || !sd->state.trading)
+ return;
+
+ if ((target_sd = map_id2sd(sd->trade_partner)) == NULL) {
+ trade_tradecancel(sd);
+ return;
+ }
+ sd->state.deal_locked = 1;
+ clif_tradeitemok(sd, 0, 0);
+ clif_tradedeal_lock(sd, 0);
+ clif_tradedeal_lock(target_sd, 1);
}
/*==========================================
@@ -447,58 +455,58 @@ void trade_tradeok(struct map_session_data *sd)
*------------------------------------------*/
void trade_tradecancel(struct map_session_data *sd)
{
- struct map_session_data *target_sd;
- int trade_i;
-
- target_sd = map_id2sd(sd->trade_partner);
-
- if (!sd->state.trading) {
- // Not trade acepted
- if (target_sd) {
- target_sd->trade_partner = 0;
- clif_tradecancelled(target_sd);
- }
- sd->trade_partner = 0;
- clif_tradecancelled(sd);
- return;
- }
-
- for (trade_i = 0; trade_i < 10; trade_i++) { // give items back (only virtual)
- if (!sd->deal.item[trade_i].amount)
- continue;
- clif_additem(sd, sd->deal.item[trade_i].index, sd->deal.item[trade_i].amount, 0);
- sd->deal.item[trade_i].index = 0;
- sd->deal.item[trade_i].amount = 0;
- }
- if (sd->deal.zeny) {
- clif_updatestatus(sd, SP_ZENY);
- sd->deal.zeny = 0;
- }
-
- sd->state.deal_locked = 0;
- sd->state.trading = 0;
- sd->trade_partner = 0;
- clif_tradecancelled(sd);
-
- if (!target_sd)
- return;
-
- for (trade_i = 0; trade_i < 10; trade_i++) { // give items back (only virtual)
- if (!target_sd->deal.item[trade_i].amount)
- continue;
- clif_additem(target_sd, target_sd->deal.item[trade_i].index, target_sd->deal.item[trade_i].amount, 0);
- target_sd->deal.item[trade_i].index = 0;
- target_sd->deal.item[trade_i].amount = 0;
- }
-
- if (target_sd->deal.zeny) {
- clif_updatestatus(target_sd, SP_ZENY);
- target_sd->deal.zeny = 0;
- }
- target_sd->state.deal_locked = 0;
- target_sd->trade_partner = 0;
- target_sd->state.trading = 0;
- clif_tradecancelled(target_sd);
+ struct map_session_data *target_sd;
+ int trade_i;
+
+ target_sd = map_id2sd(sd->trade_partner);
+
+ if(!sd->state.trading)
+ { // Not trade acepted
+ if( target_sd ) {
+ target_sd->trade_partner = 0;
+ clif_tradecancelled(target_sd);
+ }
+ sd->trade_partner = 0;
+ clif_tradecancelled(sd);
+ return;
+ }
+
+ for(trade_i = 0; trade_i < 10; trade_i++) { // give items back (only virtual)
+ if (!sd->deal.item[trade_i].amount)
+ continue;
+ clif_additem(sd, sd->deal.item[trade_i].index, sd->deal.item[trade_i].amount, 0);
+ sd->deal.item[trade_i].index = 0;
+ sd->deal.item[trade_i].amount = 0;
+ }
+ if (sd->deal.zeny) {
+ clif_updatestatus(sd, SP_ZENY);
+ sd->deal.zeny = 0;
+ }
+
+ sd->state.deal_locked = 0;
+ sd->state.trading = 0;
+ sd->trade_partner = 0;
+ clif_tradecancelled(sd);
+
+ if (!target_sd)
+ return;
+
+ for(trade_i = 0; trade_i < 10; trade_i++) { // give items back (only virtual)
+ if (!target_sd->deal.item[trade_i].amount)
+ continue;
+ clif_additem(target_sd, target_sd->deal.item[trade_i].index, target_sd->deal.item[trade_i].amount, 0);
+ target_sd->deal.item[trade_i].index = 0;
+ target_sd->deal.item[trade_i].amount = 0;
+ }
+
+ if (target_sd->deal.zeny) {
+ clif_updatestatus(target_sd, SP_ZENY);
+ target_sd->deal.zeny = 0;
+ }
+ target_sd->state.deal_locked = 0;
+ target_sd->trade_partner = 0;
+ target_sd->state.trading = 0;
+ clif_tradecancelled(target_sd);
}
/*==========================================
@@ -506,93 +514,97 @@ void trade_tradecancel(struct map_session_data *sd)
*------------------------------------------*/
void trade_tradecommit(struct map_session_data *sd)
{
- struct map_session_data *tsd;
- int trade_i;
- int flag;
-
- if (!sd->state.trading || !sd->state.deal_locked) //Locked should be 1 (pressed ok) before you can press trade.
- return;
-
- if ((tsd = map_id2sd(sd->trade_partner)) == NULL) {
- trade_tradecancel(sd);
- return;
- }
-
- sd->state.deal_locked = 2;
-
- if (tsd->state.deal_locked < 2)
- return; //Not yet time for trading.
-
- //Now is a good time (to save on resources) to check that the trade can indeed be made and it's not exploitable.
- // check exploit (trade more items that you have)
- if (impossible_trade_check(sd)) {
- trade_tradecancel(sd);
- return;
- }
- // check exploit (trade more items that you have)
- if (impossible_trade_check(tsd)) {
- trade_tradecancel(tsd);
- return;
- }
- // check for full inventory (can not add traded items)
- if (!trade_check(sd,tsd)) { // check the both players
- trade_tradecancel(sd);
- return;
- }
-
- // trade is accepted and correct.
- for (trade_i = 0; trade_i < 10; trade_i++) {
- int n;
- if (sd->deal.item[trade_i].amount) {
- n = sd->deal.item[trade_i].index;
-
- flag = pc_additem(tsd, &sd->status.inventory[n], sd->deal.item[trade_i].amount,LOG_TYPE_TRADE);
- if (flag == 0)
- pc_delitem(sd, n, sd->deal.item[trade_i].amount, 1, 6, LOG_TYPE_TRADE);
- else
- clif_additem(sd, n, sd->deal.item[trade_i].amount, 0);
- sd->deal.item[trade_i].index = 0;
- sd->deal.item[trade_i].amount = 0;
- }
- if (tsd->deal.item[trade_i].amount) {
- n = tsd->deal.item[trade_i].index;
-
- flag = pc_additem(sd, &tsd->status.inventory[n], tsd->deal.item[trade_i].amount,LOG_TYPE_TRADE);
- if (flag == 0)
- pc_delitem(tsd, n, tsd->deal.item[trade_i].amount, 1, 6, LOG_TYPE_TRADE);
- else
- clif_additem(tsd, n, tsd->deal.item[trade_i].amount, 0);
- tsd->deal.item[trade_i].index = 0;
- tsd->deal.item[trade_i].amount = 0;
- }
- }
-
- if (sd->deal.zeny) {
- pc_payzeny(sd ,sd->deal.zeny, LOG_TYPE_TRADE, tsd);
- pc_getzeny(tsd,sd->deal.zeny,LOG_TYPE_TRADE, sd);
- sd->deal.zeny = 0;
-
- }
- if (tsd->deal.zeny) {
- pc_payzeny(tsd,tsd->deal.zeny,LOG_TYPE_TRADE, sd);
- pc_getzeny(sd ,tsd->deal.zeny,LOG_TYPE_TRADE, tsd);
- tsd->deal.zeny = 0;
- }
-
- sd->state.deal_locked = 0;
- sd->trade_partner = 0;
- sd->state.trading = 0;
-
- tsd->state.deal_locked = 0;
- tsd->trade_partner = 0;
- tsd->state.trading = 0;
-
- clif_tradecompleted(sd, 0);
- clif_tradecompleted(tsd, 0);
-
- // save both player to avoid crash: they always have no advantage/disadvantage between the 2 players
- if (save_settings&1) {
- chrif_save(sd,0);
- chrif_save(tsd,0);
- }
+ struct map_session_data *tsd;
+ int trade_i;
+ int flag;
+
+ if (!sd->state.trading || !sd->state.deal_locked) //Locked should be 1 (pressed ok) before you can press trade.
+ return;
+
+ if ((tsd = map_id2sd(sd->trade_partner)) == NULL) {
+ trade_tradecancel(sd);
+ return;
+ }
+
+ sd->state.deal_locked = 2;
+
+ if (tsd->state.deal_locked < 2)
+ return; //Not yet time for trading.
+
+ //Now is a good time (to save on resources) to check that the trade can indeed be made and it's not exploitable.
+ // check exploit (trade more items that you have)
+ if (impossible_trade_check(sd)) {
+ trade_tradecancel(sd);
+ return;
+ }
+ // check exploit (trade more items that you have)
+ if (impossible_trade_check(tsd)) {
+ trade_tradecancel(tsd);
+ return;
+ }
+ // check for full inventory (can not add traded items)
+ if (!trade_check(sd,tsd)) { // check the both players
+ trade_tradecancel(sd);
+ return;
+ }
+
+ // trade is accepted and correct.
+ for( trade_i = 0; trade_i < 10; trade_i++ )
+ {
+ int n;
+ if (sd->deal.item[trade_i].amount)
+ {
+ n = sd->deal.item[trade_i].index;
+
+ flag = pc_additem(tsd, &sd->status.inventory[n], sd->deal.item[trade_i].amount,LOG_TYPE_TRADE);
+ if (flag == 0)
+ pc_delitem(sd, n, sd->deal.item[trade_i].amount, 1, 6, LOG_TYPE_TRADE);
+ else
+ clif_additem(sd, n, sd->deal.item[trade_i].amount, 0);
+ sd->deal.item[trade_i].index = 0;
+ sd->deal.item[trade_i].amount = 0;
+ }
+ if (tsd->deal.item[trade_i].amount)
+ {
+ n = tsd->deal.item[trade_i].index;
+
+ flag = pc_additem(sd, &tsd->status.inventory[n], tsd->deal.item[trade_i].amount,LOG_TYPE_TRADE);
+ if (flag == 0)
+ pc_delitem(tsd, n, tsd->deal.item[trade_i].amount, 1, 6, LOG_TYPE_TRADE);
+ else
+ clif_additem(tsd, n, tsd->deal.item[trade_i].amount, 0);
+ tsd->deal.item[trade_i].index = 0;
+ tsd->deal.item[trade_i].amount = 0;
+ }
+ }
+
+ if( sd->deal.zeny ) {
+ pc_payzeny(sd ,sd->deal.zeny, LOG_TYPE_TRADE, tsd);
+ pc_getzeny(tsd,sd->deal.zeny,LOG_TYPE_TRADE, sd);
+ sd->deal.zeny = 0;
+
+ }
+ if ( tsd->deal.zeny) {
+ pc_payzeny(tsd,tsd->deal.zeny,LOG_TYPE_TRADE, sd);
+ pc_getzeny(sd ,tsd->deal.zeny,LOG_TYPE_TRADE, tsd);
+ tsd->deal.zeny = 0;
+ }
+
+ sd->state.deal_locked = 0;
+ sd->trade_partner = 0;
+ sd->state.trading = 0;
+
+ tsd->state.deal_locked = 0;
+ tsd->trade_partner = 0;
+ tsd->state.trading = 0;
+
+ clif_tradecompleted(sd, 0);
+ clif_tradecompleted(tsd, 0);
+
+ // save both player to avoid crash: they always have no advantage/disadvantage between the 2 players
+ if (save_settings&1)
+ {
+ chrif_save(sd,0);
+ chrif_save(tsd,0);
+ }
}
diff --git a/src/map/trade.h b/src/map/trade.h
index 1b8cb4f75..6bb39936e 100644
--- a/src/map/trade.h
+++ b/src/map/trade.h
@@ -1,8 +1,8 @@
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder
-#ifndef _TRADE_H_
-#define _TRADE_H_
+#ifndef _TRADE_H_
+#define _TRADE_H_
//#include "map.h"
struct map_session_data;
diff --git a/src/map/unit.c b/src/map/unit.c
index 016e8cdd8..4827c0c68 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -40,19 +40,20 @@
#include <string.h>
-const short dirx[8]= {0,-1,-1,-1,0,1,1,1};
-const short diry[8]= {1,1,0,-1,-1,-1,0,1};
-
-struct unit_data *unit_bl2ud(struct block_list *bl) {
- if (bl == NULL) return NULL;
- if (bl->type == BL_PC) return &((struct map_session_data *)bl)->ud;
- if (bl->type == BL_MOB) return &((struct mob_data *)bl)->ud;
- if (bl->type == BL_PET) return &((struct pet_data *)bl)->ud;
- if (bl->type == BL_NPC) return &((struct npc_data *)bl)->ud;
- if (bl->type == BL_HOM) return &((struct homun_data *)bl)->ud;
- if (bl->type == BL_MER) return &((struct mercenary_data *)bl)->ud;
- if (bl->type == BL_ELEM) return &((struct elemental_data *)bl)->ud;
- return NULL;
+const short dirx[8]={0,-1,-1,-1,0,1,1,1};
+const short diry[8]={1,1,0,-1,-1,-1,0,1};
+
+struct unit_data* unit_bl2ud(struct block_list *bl)
+{
+ if( bl == NULL) return NULL;
+ if( bl->type == BL_PC) return &((struct map_session_data*)bl)->ud;
+ if( bl->type == BL_MOB) return &((struct mob_data*)bl)->ud;
+ if( bl->type == BL_PET) return &((struct pet_data*)bl)->ud;
+ if( bl->type == BL_NPC) return &((struct npc_data*)bl)->ud;
+ if( bl->type == BL_HOM) return &((struct homun_data*)bl)->ud;
+ if( bl->type == BL_MER) return &((struct mercenary_data*)bl)->ud;
+ if( bl->type == BL_ELEM) return &((struct elemental_data*)bl)->ud;
+ return NULL;
}
static int unit_attack_timer(int tid, unsigned int tick, int id, intptr_t data);
@@ -60,665 +61,686 @@ static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data
int unit_walktoxy_sub(struct block_list *bl)
{
- int i;
- struct walkpath_data wpd;
- struct unit_data *ud = NULL;
-
- nullpo_retr(1, bl);
- ud = unit_bl2ud(bl);
- if (ud == NULL) return 0;
-
- if (!path_search(&wpd,bl->m,bl->x,bl->y,ud->to_x,ud->to_y,ud->state.walk_easy,CELL_CHKNOPASS))
- return 0;
-
- memcpy(&ud->walkpath,&wpd,sizeof(wpd));
-
- if (ud->target_to && ud->chaserange>1) {
- //Generally speaking, the walk path is already to an adjacent tile
- //so we only need to shorten the path if the range is greater than 1.
- int dir;
- //Trim the last part of the path to account for range,
- //but always move at least one cell when requested to move.
- for (i = ud->chaserange*10; i > 0 && ud->walkpath.path_len>1;) {
- ud->walkpath.path_len--;
- dir = ud->walkpath.path[ud->walkpath.path_len];
- if (dir&1)
- i-=14;
- else
- i-=10;
- ud->to_x -= dirx[dir];
- ud->to_y -= diry[dir];
- }
- }
-
- ud->state.change_walk_target=0;
-
- if (bl->type == BL_PC) {
- ((TBL_PC *)bl)->head_dir = 0;
- clif_walkok((TBL_PC *)bl);
- }
- clif_move(ud);
-
- if (ud->walkpath.path_pos>=ud->walkpath.path_len)
- i = -1;
- else if (ud->walkpath.path[ud->walkpath.path_pos]&1)
- i = status_get_speed(bl)*14/10;
- else
- i = status_get_speed(bl);
- if (i > 0)
- ud->walktimer = add_timer(gettick()+i,unit_walktoxy_timer,bl->id,i);
- return 1;
+ int i;
+ struct walkpath_data wpd;
+ struct unit_data *ud = NULL;
+
+ nullpo_retr(1, bl);
+ ud = unit_bl2ud(bl);
+ if(ud == NULL) return 0;
+
+ if( !path_search(&wpd,bl->m,bl->x,bl->y,ud->to_x,ud->to_y,ud->state.walk_easy,CELL_CHKNOPASS) )
+ return 0;
+
+ memcpy(&ud->walkpath,&wpd,sizeof(wpd));
+
+ if (ud->target_to && ud->chaserange>1) {
+ //Generally speaking, the walk path is already to an adjacent tile
+ //so we only need to shorten the path if the range is greater than 1.
+ int dir;
+ //Trim the last part of the path to account for range,
+ //but always move at least one cell when requested to move.
+ for (i = ud->chaserange*10; i > 0 && ud->walkpath.path_len>1;) {
+ ud->walkpath.path_len--;
+ dir = ud->walkpath.path[ud->walkpath.path_len];
+ if(dir&1)
+ i-=14;
+ else
+ i-=10;
+ ud->to_x -= dirx[dir];
+ ud->to_y -= diry[dir];
+ }
+ }
+
+ ud->state.change_walk_target=0;
+
+ if (bl->type == BL_PC) {
+ ((TBL_PC *)bl)->head_dir = 0;
+ clif_walkok((TBL_PC*)bl);
+ }
+ clif_move(ud);
+
+ if(ud->walkpath.path_pos>=ud->walkpath.path_len)
+ i = -1;
+ else if(ud->walkpath.path[ud->walkpath.path_pos]&1)
+ i = status_get_speed(bl)*14/10;
+ else
+ i = status_get_speed(bl);
+ if( i > 0)
+ ud->walktimer = add_timer(gettick()+i,unit_walktoxy_timer,bl->id,i);
+ return 1;
}
static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- int i;
- int x,y,dx,dy;
- uint8 dir;
- struct block_list *bl;
- struct map_session_data *sd;
- struct mob_data *md;
- struct unit_data *ud;
- struct mercenary_data *mrd;
-
- bl = map_id2bl(id);
- if (bl == NULL)
- return 0;
- sd = BL_CAST(BL_PC, bl);
- md = BL_CAST(BL_MOB, bl);
- mrd = BL_CAST(BL_MER, bl);
- ud = unit_bl2ud(bl);
-
- if (ud == NULL) return 0;
-
- if (ud->walktimer != tid) {
- ShowError("unit_walk_timer mismatch %d != %d\n",ud->walktimer,tid);
- return 0;
- }
- ud->walktimer = INVALID_TIMER;
- if (bl->prev == NULL) return 0; // Stop moved because it is missing from the block_list
-
- if (ud->walkpath.path_pos>=ud->walkpath.path_len)
- return 0;
-
- if (ud->walkpath.path[ud->walkpath.path_pos]>=8)
- return 1;
- x = bl->x;
- y = bl->y;
-
- dir = ud->walkpath.path[ud->walkpath.path_pos];
- ud->dir = dir;
-
- dx = dirx[(int)dir];
- dy = diry[(int)dir];
-
- if (map_getcell(bl->m,x+dx,y+dy,CELL_CHKNOPASS))
- return unit_walktoxy_sub(bl);
-
- //Refresh view for all those we lose sight
- map_foreachinmovearea(clif_outsight, bl, AREA_SIZE, dx, dy, sd?BL_ALL:BL_PC, bl);
-
- x += dx;
- y += dy;
- map_moveblock(bl, x, y, tick);
- ud->walk_count++; //walked cell counter, to be used for walk-triggered skills. [Skotlex]
- status_change_end(bl, SC_ROLLINGCUTTER, INVALID_TIMER); //If you move, you lose your counters. [malufett]
-
- if (bl->x != x || bl->y != y || ud->walktimer != INVALID_TIMER)
- return 0; //map_moveblock has altered the object beyond what we expected (moved/warped it)
-
- ud->walktimer = -2; // arbitrary non-INVALID_TIMER value to make the clif code send walking packets
- map_foreachinmovearea(clif_insight, bl, AREA_SIZE, -dx, -dy, sd?BL_ALL:BL_PC, bl);
- ud->walktimer = INVALID_TIMER;
-
- if (sd) {
- if (sd->touching_id)
- npc_touchnext_areanpc(sd,false);
- if (map_getcell(bl->m,x,y,CELL_CHKNPC)) {
- npc_touch_areanpc(sd,bl->m,x,y);
- if (bl->prev == NULL) //Script could have warped char, abort remaining of the function.
- return 0;
- } else
- sd->areanpc_id=0;
-
- if (sd->md && !check_distance_bl(&sd->bl, &sd->md->bl, MAX_MER_DISTANCE)) {
- // mercenary should be warped after being 3 seconds too far from the master [greenbox]
- if (sd->md->masterteleport_timer == 0) {
- sd->md->masterteleport_timer = gettick();
- } else if (DIFF_TICK(gettick(), sd->md->masterteleport_timer) > 3000) {
- sd->md->masterteleport_timer = 0;
- unit_warp(&sd->md->bl, sd->bl.m, sd->bl.x, sd->bl.y, CLR_TELEPORT);
- }
- } else if (sd->md) {
- // reset the tick, he is not far anymore
- sd->md->masterteleport_timer = 0;
- }
- } else if (md) {
- if (map_getcell(bl->m,x,y,CELL_CHKNPC)) {
- if (npc_touch_areanpc2(md)) return 0; // Warped
- } else
- md->areanpc_id = 0;
- if (md->min_chase > md->db->range3) md->min_chase--;
- //Walk skills are triggered regardless of target due to the idle-walk mob state.
- //But avoid triggering on stop-walk calls.
- if (tid != INVALID_TIMER &&
- !(ud->walk_count%WALK_SKILL_INTERVAL) &&
- mobskill_use(md, tick, -1)) {
- if (!(ud->skillid == NPC_SELFDESTRUCTION && ud->skilltimer != INVALID_TIMER)) {
- //Skill used, abort walking
- clif_fixpos(bl); //Fix position as walk has been cancelled.
- return 0;
- }
- //Resend walk packet for proper Self Destruction display.
- clif_move(ud);
- }
- } else if (mrd && mrd->master) {
- if (!check_distance_bl(&mrd->master->bl, bl, MAX_MER_DISTANCE)) {
- // mercenary should be warped after being 3 seconds too far from the master [greenbox]
- if (mrd->masterteleport_timer == 0) {
- mrd->masterteleport_timer = gettick();
- } else if (DIFF_TICK(gettick(), mrd->masterteleport_timer) > 3000) {
- mrd->masterteleport_timer = 0;
- unit_warp(bl, mrd->master->bl.id, mrd->master->bl.x, mrd->master->bl.y, CLR_TELEPORT);
- }
- } else {
- mrd->masterteleport_timer = 0;
- }
- }
-
- if (tid == INVALID_TIMER) //A directly invoked timer is from battle_stop_walking, therefore the rest is irrelevant.
- return 0;
-
- if (ud->state.change_walk_target)
- return unit_walktoxy_sub(bl);
-
- ud->walkpath.path_pos++;
- if (ud->walkpath.path_pos>=ud->walkpath.path_len)
- i = -1;
- else if (ud->walkpath.path[ud->walkpath.path_pos]&1)
- i = status_get_speed(bl)*14/10;
- else
- i = status_get_speed(bl);
-
- if (i > 0) {
- ud->walktimer = add_timer(tick+i,unit_walktoxy_timer,id,i);
- if (md && DIFF_TICK(tick,md->dmgtick) < 3000) //not required not damaged recently
- clif_move(ud);
- } else if (ud->state.running) {
- //Keep trying to run.
- if (!(unit_run(bl) || unit_wugdash(bl,sd)))
- ud->state.running = 0;
- } else if (ud->target_to) {
- //Update target trajectory.
- struct block_list *tbl = map_id2bl(ud->target_to);
- if (!tbl || !status_check_visibility(bl, tbl)) { //Cancel chase.
- ud->to_x = bl->x;
- ud->to_y = bl->y;
- if (tbl && bl->type == BL_MOB && mob_warpchase((TBL_MOB *)bl, tbl))
- return 0;
- ud->target_to = 0;
- return 0;
- }
- if (tbl->m == bl->m && check_distance_bl(bl, tbl, ud->chaserange)) {
- //Reached destination.
- if (ud->state.attack_continue) {
- //Aegis uses one before every attack, we should
- //only need this one for syncing purposes. [Skotlex]
- ud->target_to = 0;
- clif_fixpos(bl);
- unit_attack(bl, tbl->id, ud->state.attack_continue);
- }
- } else { //Update chase-path
- unit_walktobl(bl, tbl, ud->chaserange, ud->state.walk_easy|(ud->state.attack_continue?2:0));
- return 0;
- }
- } else { //Stopped walking. Update to_x and to_y to current location [Skotlex]
- ud->to_x = bl->x;
- ud->to_y = bl->y;
- ud->target_to = 0;
- }
- return 0;
+ int i;
+ int x,y,dx,dy;
+ uint8 dir;
+ struct block_list *bl;
+ struct map_session_data *sd;
+ struct mob_data *md;
+ struct unit_data *ud;
+ struct mercenary_data *mrd;
+
+ bl = map_id2bl(id);
+ if(bl == NULL)
+ return 0;
+ sd = BL_CAST(BL_PC, bl);
+ md = BL_CAST(BL_MOB, bl);
+ mrd = BL_CAST(BL_MER, bl);
+ ud = unit_bl2ud(bl);
+
+ if(ud == NULL) return 0;
+
+ if(ud->walktimer != tid){
+ ShowError("unit_walk_timer mismatch %d != %d\n",ud->walktimer,tid);
+ return 0;
+ }
+ ud->walktimer = INVALID_TIMER;
+ if (bl->prev == NULL) return 0; // Stop moved because it is missing from the block_list
+
+ if(ud->walkpath.path_pos>=ud->walkpath.path_len)
+ return 0;
+
+ if(ud->walkpath.path[ud->walkpath.path_pos]>=8)
+ return 1;
+ x = bl->x;
+ y = bl->y;
+
+ dir = ud->walkpath.path[ud->walkpath.path_pos];
+ ud->dir = dir;
+
+ dx = dirx[(int)dir];
+ dy = diry[(int)dir];
+
+ if(map_getcell(bl->m,x+dx,y+dy,CELL_CHKNOPASS))
+ return unit_walktoxy_sub(bl);
+
+ //Refresh view for all those we lose sight
+ map_foreachinmovearea(clif_outsight, bl, AREA_SIZE, dx, dy, sd?BL_ALL:BL_PC, bl);
+
+ x += dx;
+ y += dy;
+ map_moveblock(bl, x, y, tick);
+ ud->walk_count++; //walked cell counter, to be used for walk-triggered skills. [Skotlex]
+ status_change_end(bl, SC_ROLLINGCUTTER, INVALID_TIMER); //If you move, you lose your counters. [malufett]
+
+ if (bl->x != x || bl->y != y || ud->walktimer != INVALID_TIMER)
+ return 0; //map_moveblock has altered the object beyond what we expected (moved/warped it)
+
+ ud->walktimer = -2; // arbitrary non-INVALID_TIMER value to make the clif code send walking packets
+ map_foreachinmovearea(clif_insight, bl, AREA_SIZE, -dx, -dy, sd?BL_ALL:BL_PC, bl);
+ ud->walktimer = INVALID_TIMER;
+
+ if(sd) {
+ if( sd->touching_id )
+ npc_touchnext_areanpc(sd,false);
+ if(map_getcell(bl->m,x,y,CELL_CHKNPC)) {
+ npc_touch_areanpc(sd,bl->m,x,y);
+ if (bl->prev == NULL) //Script could have warped char, abort remaining of the function.
+ return 0;
+ } else
+ sd->areanpc_id=0;
+
+ if( sd->md && !check_distance_bl(&sd->bl, &sd->md->bl, MAX_MER_DISTANCE) )
+ {
+ // mercenary should be warped after being 3 seconds too far from the master [greenbox]
+ if (sd->md->masterteleport_timer == 0)
+ {
+ sd->md->masterteleport_timer = gettick();
+ }
+ else if (DIFF_TICK(gettick(), sd->md->masterteleport_timer) > 3000)
+ {
+ sd->md->masterteleport_timer = 0;
+ unit_warp( &sd->md->bl, sd->bl.m, sd->bl.x, sd->bl.y, CLR_TELEPORT );
+ }
+ }
+ else if( sd->md )
+ {
+ // reset the tick, he is not far anymore
+ sd->md->masterteleport_timer = 0;
+ }
+ } else if (md) {
+ if( map_getcell(bl->m,x,y,CELL_CHKNPC) ) {
+ if( npc_touch_areanpc2(md) ) return 0; // Warped
+ } else
+ md->areanpc_id = 0;
+ if (md->min_chase > md->db->range3) md->min_chase--;
+ //Walk skills are triggered regardless of target due to the idle-walk mob state.
+ //But avoid triggering on stop-walk calls.
+ if(tid != INVALID_TIMER &&
+ !(ud->walk_count%WALK_SKILL_INTERVAL) &&
+ mobskill_use(md, tick, -1))
+ {
+ if (!(ud->skillid == NPC_SELFDESTRUCTION && ud->skilltimer != INVALID_TIMER))
+ { //Skill used, abort walking
+ clif_fixpos(bl); //Fix position as walk has been cancelled.
+ return 0;
+ }
+ //Resend walk packet for proper Self Destruction display.
+ clif_move(ud);
+ }
+ }
+ else if( mrd && mrd->master )
+ {
+ if (!check_distance_bl(&mrd->master->bl, bl, MAX_MER_DISTANCE))
+ {
+ // mercenary should be warped after being 3 seconds too far from the master [greenbox]
+ if (mrd->masterteleport_timer == 0)
+ {
+ mrd->masterteleport_timer = gettick();
+ }
+ else if (DIFF_TICK(gettick(), mrd->masterteleport_timer) > 3000)
+ {
+ mrd->masterteleport_timer = 0;
+ unit_warp( bl, mrd->master->bl.id, mrd->master->bl.x, mrd->master->bl.y, CLR_TELEPORT );
+ }
+ }
+ else
+ {
+ mrd->masterteleport_timer = 0;
+ }
+ }
+
+ if(tid == INVALID_TIMER) //A directly invoked timer is from battle_stop_walking, therefore the rest is irrelevant.
+ return 0;
+
+ if(ud->state.change_walk_target)
+ return unit_walktoxy_sub(bl);
+
+ ud->walkpath.path_pos++;
+ if(ud->walkpath.path_pos>=ud->walkpath.path_len)
+ i = -1;
+ else if(ud->walkpath.path[ud->walkpath.path_pos]&1)
+ i = status_get_speed(bl)*14/10;
+ else
+ i = status_get_speed(bl);
+
+ if(i > 0) {
+ ud->walktimer = add_timer(tick+i,unit_walktoxy_timer,id,i);
+ if( md && DIFF_TICK(tick,md->dmgtick) < 3000 )//not required not damaged recently
+ clif_move(ud);
+ } else if(ud->state.running) {
+ //Keep trying to run.
+ if ( !(unit_run(bl) || unit_wugdash(bl,sd)) )
+ ud->state.running = 0;
+ }
+ else if (ud->target_to) {
+ //Update target trajectory.
+ struct block_list *tbl = map_id2bl(ud->target_to);
+ if (!tbl || !status_check_visibility(bl, tbl)) { //Cancel chase.
+ ud->to_x = bl->x;
+ ud->to_y = bl->y;
+ if (tbl && bl->type == BL_MOB && mob_warpchase((TBL_MOB*)bl, tbl) )
+ return 0;
+ ud->target_to = 0;
+ return 0;
+ }
+ if (tbl->m == bl->m && check_distance_bl(bl, tbl, ud->chaserange))
+ { //Reached destination.
+ if (ud->state.attack_continue)
+ { //Aegis uses one before every attack, we should
+ //only need this one for syncing purposes. [Skotlex]
+ ud->target_to = 0;
+ clif_fixpos(bl);
+ unit_attack(bl, tbl->id, ud->state.attack_continue);
+ }
+ } else { //Update chase-path
+ unit_walktobl(bl, tbl, ud->chaserange, ud->state.walk_easy|(ud->state.attack_continue?2:0));
+ return 0;
+ }
+ }
+ else { //Stopped walking. Update to_x and to_y to current location [Skotlex]
+ ud->to_x = bl->x;
+ ud->to_y = bl->y;
+ ud->target_to = 0;
+ }
+ return 0;
}
static int unit_delay_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- struct block_list *bl = map_id2bl(id);
+ struct block_list *bl = map_id2bl(id);
- if (!bl || bl->prev == NULL)
- return 0;
- unit_walktoxy(bl, (short)((data>>16)&0xffff), (short)(data&0xffff), 0);
- return 1;
+ if (!bl || bl->prev == NULL)
+ return 0;
+ unit_walktoxy(bl, (short)((data>>16)&0xffff), (short)(data&0xffff), 0);
+ return 1;
}
//flag parameter:
//&1 -> 1/0 = easy/hard
//&2 -> force walking
//&4 -> Delay walking if the reason you can't walk is the canwalk delay
-int unit_walktoxy(struct block_list *bl, short x, short y, int flag)
+int unit_walktoxy( struct block_list *bl, short x, short y, int flag)
{
- struct unit_data *ud = NULL;
- struct status_change *sc = NULL;
-
- nullpo_ret(bl);
-
- ud = unit_bl2ud(bl);
-
- if (ud == NULL) return 0;
- // disabled until we find the correct algorithm. [malufett]
- //#ifdef OFFICIAL_WALKPATH
- // if( !path_search_long(NULL, bl->m, bl->x, bl->y, x, y, CELL_CHKWALL) ) return 0;
- //#endif
- if (flag&4 && DIFF_TICK(ud->canmove_tick, gettick()) > 0 &&
- DIFF_TICK(ud->canmove_tick, gettick()) < 2000) {
- // Delay walking command. [Skotlex]
- add_timer(ud->canmove_tick+1, unit_delay_walktoxy_timer, bl->id, (x<<16)|(y&0xFFFF));
- return 1;
- }
-
- if (!(flag&2) && (!(status_get_mode(bl)&MD_CANMOVE) || !unit_can_move(bl)))
- return 0;
-
- ud->state.walk_easy = flag&1;
- ud->to_x = x;
- ud->to_y = y;
- unit_set_target(ud, 0);
-
- sc = status_get_sc(bl);
- if (sc && sc->data[SC_CONFUSION]) //Randomize the target position
- map_random_dir(bl, &ud->to_x, &ud->to_y);
-
- if (ud->walktimer != INVALID_TIMER) {
- // When you come to the center of the grid because the change of destination while you're walking right now
- // Call a function from a timer unit_walktoxy_sub
- ud->state.change_walk_target = 1;
- return 1;
- }
-
- if (ud->attacktimer != INVALID_TIMER) {
- delete_timer(ud->attacktimer, unit_attack_timer);
- ud->attacktimer = INVALID_TIMER;
- }
-
- return unit_walktoxy_sub(bl);
+ struct unit_data* ud = NULL;
+ struct status_change* sc = NULL;
+
+ nullpo_ret(bl);
+
+ ud = unit_bl2ud(bl);
+
+ if( ud == NULL) return 0;
+// disabled until we find the correct algorithm. [malufett]
+//#ifdef OFFICIAL_WALKPATH
+// if( !path_search_long(NULL, bl->m, bl->x, bl->y, x, y, CELL_CHKWALL) ) return 0;
+//#endif
+ if (flag&4 && DIFF_TICK(ud->canmove_tick, gettick()) > 0 &&
+ DIFF_TICK(ud->canmove_tick, gettick()) < 2000)
+ { // Delay walking command. [Skotlex]
+ add_timer(ud->canmove_tick+1, unit_delay_walktoxy_timer, bl->id, (x<<16)|(y&0xFFFF));
+ return 1;
+ }
+
+ if(!(flag&2) && (!(status_get_mode(bl)&MD_CANMOVE) || !unit_can_move(bl)))
+ return 0;
+
+ ud->state.walk_easy = flag&1;
+ ud->to_x = x;
+ ud->to_y = y;
+ unit_set_target(ud, 0);
+
+ sc = status_get_sc(bl);
+ if (sc && sc->data[SC_CONFUSION]) //Randomize the target position
+ map_random_dir(bl, &ud->to_x, &ud->to_y);
+
+ if(ud->walktimer != INVALID_TIMER) {
+ // When you come to the center of the grid because the change of destination while you're walking right now
+ // Call a function from a timer unit_walktoxy_sub
+ ud->state.change_walk_target = 1;
+ return 1;
+ }
+
+ if(ud->attacktimer != INVALID_TIMER) {
+ delete_timer( ud->attacktimer, unit_attack_timer );
+ ud->attacktimer = INVALID_TIMER;
+ }
+
+ return unit_walktoxy_sub(bl);
}
//To set Mob's CHASE/FOLLOW states (shouldn't be done if there's no path to reach)
-static inline void set_mobstate(struct block_list *bl, int flag)
+static inline void set_mobstate(struct block_list* bl, int flag)
{
- struct mob_data *md = BL_CAST(BL_MOB,bl);
+ struct mob_data* md = BL_CAST(BL_MOB,bl);
- if (md && flag)
- md->state.skillstate = md->state.aggressive ? MSS_FOLLOW : MSS_RUSH;
+ if( md && flag )
+ md->state.skillstate = md->state.aggressive ? MSS_FOLLOW : MSS_RUSH;
}
static int unit_walktobl_sub(int tid, unsigned int tick, int id, intptr_t data)
{
- struct block_list *bl = map_id2bl(id);
- struct unit_data *ud = bl?unit_bl2ud(bl):NULL;
-
- if (ud && ud->walktimer == INVALID_TIMER && ud->target == data) {
- if (DIFF_TICK(ud->canmove_tick, tick) > 0) //Keep waiting?
- add_timer(ud->canmove_tick+1, unit_walktobl_sub, id, data);
- else if (unit_can_move(bl)) {
- if (unit_walktoxy_sub(bl))
- set_mobstate(bl, ud->state.attack_continue);
- }
- }
- return 0;
+ struct block_list *bl = map_id2bl(id);
+ struct unit_data *ud = bl?unit_bl2ud(bl):NULL;
+
+ if (ud && ud->walktimer == INVALID_TIMER && ud->target == data)
+ {
+ if (DIFF_TICK(ud->canmove_tick, tick) > 0) //Keep waiting?
+ add_timer(ud->canmove_tick+1, unit_walktobl_sub, id, data);
+ else if (unit_can_move(bl))
+ {
+ if (unit_walktoxy_sub(bl))
+ set_mobstate(bl, ud->state.attack_continue);
+ }
+ }
+ return 0;
}
// Chases a tbl. If the flag&1, use hard-path seek,
// if flag&2, start attacking upon arrival within range, otherwise just walk to that character.
int unit_walktobl(struct block_list *bl, struct block_list *tbl, int range, int flag)
{
- struct unit_data *ud = NULL;
- struct status_change *sc = NULL;
- nullpo_ret(bl);
- nullpo_ret(tbl);
-
- ud = unit_bl2ud(bl);
- if (ud == NULL) return 0;
-
- if (!(status_get_mode(bl)&MD_CANMOVE))
- return 0;
-
- if (!unit_can_reach_bl(bl, tbl, distance_bl(bl, tbl)+1, flag&1, &ud->to_x, &ud->to_y)) {
- ud->to_x = bl->x;
- ud->to_y = bl->y;
- ud->target_to = 0;
- return 0;
- }
-
- ud->state.walk_easy = flag&1;
- ud->target_to = tbl->id;
- ud->chaserange = range; //Note that if flag&2, this SHOULD be attack-range
- ud->state.attack_continue = flag&2?1:0; //Chase to attack.
- unit_set_target(ud, 0);
-
- sc = status_get_sc(bl);
- if (sc && sc->data[SC_CONFUSION]) //Randomize the target position
- map_random_dir(bl, &ud->to_x, &ud->to_y);
-
- if (ud->walktimer != INVALID_TIMER) {
- ud->state.change_walk_target = 1;
- set_mobstate(bl, flag&2);
- return 1;
- }
-
- if (DIFF_TICK(ud->canmove_tick, gettick()) > 0) {
- //Can't move, wait a bit before invoking the movement.
- add_timer(ud->canmove_tick+1, unit_walktobl_sub, bl->id, ud->target);
- return 1;
- }
-
- if (!unit_can_move(bl))
- return 0;
-
- if (ud->attacktimer != INVALID_TIMER) {
- delete_timer(ud->attacktimer, unit_attack_timer);
- ud->attacktimer = INVALID_TIMER;
- }
-
- if (unit_walktoxy_sub(bl)) {
- set_mobstate(bl, flag&2);
- return 1;
- }
- return 0;
+ struct unit_data *ud = NULL;
+ struct status_change *sc = NULL;
+ nullpo_ret(bl);
+ nullpo_ret(tbl);
+
+ ud = unit_bl2ud(bl);
+ if( ud == NULL) return 0;
+
+ if (!(status_get_mode(bl)&MD_CANMOVE))
+ return 0;
+
+ if (!unit_can_reach_bl(bl, tbl, distance_bl(bl, tbl)+1, flag&1, &ud->to_x, &ud->to_y)) {
+ ud->to_x = bl->x;
+ ud->to_y = bl->y;
+ ud->target_to = 0;
+ return 0;
+ }
+
+ ud->state.walk_easy = flag&1;
+ ud->target_to = tbl->id;
+ ud->chaserange = range; //Note that if flag&2, this SHOULD be attack-range
+ ud->state.attack_continue = flag&2?1:0; //Chase to attack.
+ unit_set_target(ud, 0);
+
+ sc = status_get_sc(bl);
+ if (sc && sc->data[SC_CONFUSION]) //Randomize the target position
+ map_random_dir(bl, &ud->to_x, &ud->to_y);
+
+ if(ud->walktimer != INVALID_TIMER) {
+ ud->state.change_walk_target = 1;
+ set_mobstate(bl, flag&2);
+ return 1;
+ }
+
+ if(DIFF_TICK(ud->canmove_tick, gettick()) > 0)
+ { //Can't move, wait a bit before invoking the movement.
+ add_timer(ud->canmove_tick+1, unit_walktobl_sub, bl->id, ud->target);
+ return 1;
+ }
+
+ if(!unit_can_move(bl))
+ return 0;
+
+ if(ud->attacktimer != INVALID_TIMER) {
+ delete_timer( ud->attacktimer, unit_attack_timer );
+ ud->attacktimer = INVALID_TIMER;
+ }
+
+ if (unit_walktoxy_sub(bl)) {
+ set_mobstate(bl, flag&2);
+ return 1;
+ }
+ return 0;
}
int unit_run(struct block_list *bl)
{
- struct status_change *sc = status_get_sc(bl);
- short to_x,to_y,dir_x,dir_y;
- int lv;
- int i;
-
- if (!(sc && sc->data[SC_RUN]))
- return 0;
-
- if (!unit_can_move(bl)) {
- status_change_end(bl, SC_RUN, INVALID_TIMER);
- return 0;
- }
-
- lv = sc->data[SC_RUN]->val1;
- dir_x = dirx[sc->data[SC_RUN]->val2];
- dir_y = diry[sc->data[SC_RUN]->val2];
-
- // determine destination cell
- to_x = bl->x;
- to_y = bl->y;
- for (i=0; i<AREA_SIZE; i++) {
- if (!map_getcell(bl->m,to_x+dir_x,to_y+dir_y,CELL_CHKPASS))
- break;
-
- //if sprinting and there's a PC/Mob/NPC, block the path [Kevin]
- if (sc->data[SC_RUN] && map_count_oncell(bl->m, to_x+dir_x, to_y+dir_y, BL_PC|BL_MOB|BL_NPC))
- break;
-
- to_x += dir_x;
- to_y += dir_y;
- }
-
- if ((to_x == bl->x && to_y == bl->y) || (to_x == (bl->x+1) || to_y == (bl->y+1)) || (to_x == (bl->x-1) || to_y == (bl->y-1))) {
- //If you can't run forward, you must be next to a wall, so bounce back. [Skotlex]
- clif_status_change(bl, SI_BUMP, 1, 0, 0, 0, 0);
-
- //Set running to 0 beforehand so status_change_end knows not to enable spurt [Kevin]
- unit_bl2ud(bl)->state.running = 0;
- status_change_end(bl, SC_RUN, INVALID_TIMER);
-
- skill_blown(bl,bl,skill_get_blewcount(TK_RUN,lv),unit_getdir(bl),0);
- clif_fixpos(bl); //Why is a clif_slide (skill_blown) AND a fixpos needed? Ask Aegis.
- clif_status_change(bl, SI_BUMP, 0, 0, 0, 0, 0);
- return 0;
- }
- if (unit_walktoxy(bl, to_x, to_y, 1))
- return 1;
- //There must be an obstacle nearby. Attempt walking one cell at a time.
- do {
- to_x -= dir_x;
- to_y -= dir_y;
- } while (--i > 0 && !unit_walktoxy(bl, to_x, to_y, 1));
- if (i==0) {
- // copy-paste from above
- clif_status_change(bl, SI_BUMP, 1, 0, 0, 0, 0);
-
- //Set running to 0 beforehand so status_change_end knows not to enable spurt [Kevin]
- unit_bl2ud(bl)->state.running = 0;
- status_change_end(bl, SC_RUN, INVALID_TIMER);
-
- skill_blown(bl,bl,skill_get_blewcount(TK_RUN,lv),unit_getdir(bl),0);
- clif_fixpos(bl);
- clif_status_change(bl, SI_BUMP, 0, 0, 0, 0, 0);
- return 0;
- }
- return 1;
+ struct status_change *sc = status_get_sc(bl);
+ short to_x,to_y,dir_x,dir_y;
+ int lv;
+ int i;
+
+ if (!(sc && sc->data[SC_RUN]))
+ return 0;
+
+ if (!unit_can_move(bl)) {
+ status_change_end(bl, SC_RUN, INVALID_TIMER);
+ return 0;
+ }
+
+ lv = sc->data[SC_RUN]->val1;
+ dir_x = dirx[sc->data[SC_RUN]->val2];
+ dir_y = diry[sc->data[SC_RUN]->val2];
+
+ // determine destination cell
+ to_x = bl->x;
+ to_y = bl->y;
+ for(i=0;i<AREA_SIZE;i++)
+ {
+ if(!map_getcell(bl->m,to_x+dir_x,to_y+dir_y,CELL_CHKPASS))
+ break;
+
+ //if sprinting and there's a PC/Mob/NPC, block the path [Kevin]
+ if(sc->data[SC_RUN] && map_count_oncell(bl->m, to_x+dir_x, to_y+dir_y, BL_PC|BL_MOB|BL_NPC))
+ break;
+
+ to_x += dir_x;
+ to_y += dir_y;
+ }
+
+ if( (to_x == bl->x && to_y == bl->y ) || (to_x == (bl->x+1) || to_y == (bl->y+1)) || (to_x == (bl->x-1) || to_y == (bl->y-1))) {
+ //If you can't run forward, you must be next to a wall, so bounce back. [Skotlex]
+ clif_status_change(bl, SI_BUMP, 1, 0, 0, 0, 0);
+
+ //Set running to 0 beforehand so status_change_end knows not to enable spurt [Kevin]
+ unit_bl2ud(bl)->state.running = 0;
+ status_change_end(bl, SC_RUN, INVALID_TIMER);
+
+ skill_blown(bl,bl,skill_get_blewcount(TK_RUN,lv),unit_getdir(bl),0);
+ clif_fixpos(bl); //Why is a clif_slide (skill_blown) AND a fixpos needed? Ask Aegis.
+ clif_status_change(bl, SI_BUMP, 0, 0, 0, 0, 0);
+ return 0;
+ }
+ if (unit_walktoxy(bl, to_x, to_y, 1))
+ return 1;
+ //There must be an obstacle nearby. Attempt walking one cell at a time.
+ do {
+ to_x -= dir_x;
+ to_y -= dir_y;
+ } while (--i > 0 && !unit_walktoxy(bl, to_x, to_y, 1));
+ if (i==0) {
+ // copy-paste from above
+ clif_status_change(bl, SI_BUMP, 1, 0, 0, 0, 0);
+
+ //Set running to 0 beforehand so status_change_end knows not to enable spurt [Kevin]
+ unit_bl2ud(bl)->state.running = 0;
+ status_change_end(bl, SC_RUN, INVALID_TIMER);
+
+ skill_blown(bl,bl,skill_get_blewcount(TK_RUN,lv),unit_getdir(bl),0);
+ clif_fixpos(bl);
+ clif_status_change(bl, SI_BUMP, 0, 0, 0, 0, 0);
+ return 0;
+ }
+ return 1;
}
//Exclusive function to Wug Dash state. [Jobbie/3CeAM]
-int unit_wugdash(struct block_list *bl, struct map_session_data *sd)
-{
- struct status_change *sc = status_get_sc(bl);
- short to_x,to_y,dir_x,dir_y;
- int lv;
- int i;
- if (!(sc && sc->data[SC_WUGDASH]))
- return 0;
-
- nullpo_ret(sd);
- nullpo_ret(bl);
-
- if (!unit_can_move(bl)) {
- status_change_end(bl,SC_WUGDASH,INVALID_TIMER);
- return 0;
- }
-
- lv = sc->data[SC_WUGDASH]->val1;
- dir_x = dirx[sc->data[SC_WUGDASH]->val2];
- dir_y = diry[sc->data[SC_WUGDASH]->val2];
-
- to_x = bl->x;
- to_y = bl->y;
- for (i=0; i<AREA_SIZE; i++) {
- if (!map_getcell(bl->m,to_x+dir_x,to_y+dir_y,CELL_CHKPASS))
- break;
-
- if (sc->data[SC_WUGDASH] && map_count_oncell(bl->m, to_x+dir_x, to_y+dir_y, BL_PC|BL_MOB|BL_NPC))
- break;
-
- to_x += dir_x;
- to_y += dir_y;
- }
-
- if (to_x == bl->x && to_y == bl->y) {
-
- unit_bl2ud(bl)->state.running = 0;
- status_change_end(bl,SC_WUGDASH,INVALID_TIMER);
-
- if (sd) {
- clif_fixpos(bl);
- skill_castend_damage_id(bl, &sd->bl, RA_WUGDASH, lv, gettick(), SD_LEVEL);
- }
- return 0;
- }
- if (unit_walktoxy(bl, to_x, to_y, 1))
- return 1;
- do {
- to_x -= dir_x;
- to_y -= dir_y;
- } while (--i > 0 && !unit_walktoxy(bl, to_x, to_y, 1));
- if (i==0) {
-
- unit_bl2ud(bl)->state.running = 0;
- status_change_end(bl,SC_WUGDASH,INVALID_TIMER);
-
- if (sd) {
- clif_fixpos(bl);
- skill_castend_damage_id(bl, &sd->bl, RA_WUGDASH, lv, gettick(), SD_LEVEL);
- }
- return 0;
- }
- return 1;
+int unit_wugdash(struct block_list *bl, struct map_session_data *sd) {
+ struct status_change *sc = status_get_sc(bl);
+ short to_x,to_y,dir_x,dir_y;
+ int lv;
+ int i;
+ if (!(sc && sc->data[SC_WUGDASH]))
+ return 0;
+
+ nullpo_ret(sd);
+ nullpo_ret(bl);
+
+ if (!unit_can_move(bl)) {
+ status_change_end(bl,SC_WUGDASH,INVALID_TIMER);
+ return 0;
+ }
+
+ lv = sc->data[SC_WUGDASH]->val1;
+ dir_x = dirx[sc->data[SC_WUGDASH]->val2];
+ dir_y = diry[sc->data[SC_WUGDASH]->val2];
+
+ to_x = bl->x;
+ to_y = bl->y;
+ for(i=0;i<AREA_SIZE;i++)
+ {
+ if(!map_getcell(bl->m,to_x+dir_x,to_y+dir_y,CELL_CHKPASS))
+ break;
+
+ if(sc->data[SC_WUGDASH] && map_count_oncell(bl->m, to_x+dir_x, to_y+dir_y, BL_PC|BL_MOB|BL_NPC))
+ break;
+
+ to_x += dir_x;
+ to_y += dir_y;
+ }
+
+ if(to_x == bl->x && to_y == bl->y) {
+
+ unit_bl2ud(bl)->state.running = 0;
+ status_change_end(bl,SC_WUGDASH,INVALID_TIMER);
+
+ if( sd ){
+ clif_fixpos(bl);
+ skill_castend_damage_id(bl, &sd->bl, RA_WUGDASH, lv, gettick(), SD_LEVEL);
+ }
+ return 0;
+ }
+ if (unit_walktoxy(bl, to_x, to_y, 1))
+ return 1;
+ do {
+ to_x -= dir_x;
+ to_y -= dir_y;
+ } while (--i > 0 && !unit_walktoxy(bl, to_x, to_y, 1));
+ if (i==0) {
+
+ unit_bl2ud(bl)->state.running = 0;
+ status_change_end(bl,SC_WUGDASH,INVALID_TIMER);
+
+ if( sd ){
+ clif_fixpos(bl);
+ skill_castend_damage_id(bl, &sd->bl, RA_WUGDASH, lv, gettick(), SD_LEVEL);
+ }
+ return 0;
+ }
+ return 1;
}
//Makes bl attempt to run dist cells away from target. Uses hard-paths.
int unit_escape(struct block_list *bl, struct block_list *target, short dist)
{
- int dir = map_calc_dir(target, bl->x, bl->y);
- while (dist > 0 && map_getcell(bl->m, bl->x + dist*dirx[dir], bl->y + dist*diry[dir], CELL_CHKNOREACH))
- dist--;
- return (dist > 0 && unit_walktoxy(bl, bl->x + dist*dirx[dir], bl->y + dist*diry[dir], 0));
+ int dir = map_calc_dir(target, bl->x, bl->y);
+ while( dist > 0 && map_getcell(bl->m, bl->x + dist*dirx[dir], bl->y + dist*diry[dir], CELL_CHKNOREACH) )
+ dist--;
+ return ( dist > 0 && unit_walktoxy(bl, bl->x + dist*dirx[dir], bl->y + dist*diry[dir], 0) );
}
//Instant warp function.
int unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, bool checkpath)
{
- short dx,dy;
- uint8 dir;
- struct unit_data *ud = NULL;
- struct map_session_data *sd = NULL;
-
- nullpo_ret(bl);
- sd = BL_CAST(BL_PC, bl);
- ud = unit_bl2ud(bl);
-
- if (ud == NULL) return 0;
-
- unit_stop_walking(bl,1);
- unit_stop_attack(bl);
-
- if (checkpath && (map_getcell(bl->m,dst_x,dst_y,CELL_CHKNOPASS) || !path_search(NULL,bl->m,bl->x,bl->y,dst_x,dst_y,easy,CELL_CHKNOREACH)))
- return 0; // unreachable
-
- ud->to_x = dst_x;
- ud->to_y = dst_y;
-
- dir = map_calc_dir(bl, dst_x, dst_y);
- ud->dir = dir;
-
- dx = dst_x - bl->x;
- dy = dst_y - bl->y;
-
- map_foreachinmovearea(clif_outsight, bl, AREA_SIZE, dx, dy, sd?BL_ALL:BL_PC, bl);
-
- map_moveblock(bl, dst_x, dst_y, gettick());
-
- ud->walktimer = -2; // arbitrary non-INVALID_TIMER value to make the clif code send walking packets
- map_foreachinmovearea(clif_insight, bl, AREA_SIZE, -dx, -dy, sd?BL_ALL:BL_PC, bl);
- ud->walktimer = INVALID_TIMER;
-
- if (sd) {
- if (sd->touching_id)
- npc_touchnext_areanpc(sd,false);
- if (map_getcell(bl->m,bl->x,bl->y,CELL_CHKNPC)) {
- npc_touch_areanpc(sd,bl->m,bl->x,bl->y);
- if (bl->prev == NULL) //Script could have warped char, abort remaining of the function.
- return 0;
- } else
- sd->areanpc_id=0;
-
- if (sd->status.pet_id > 0 && sd->pd && sd->pd->pet.intimate > 0) {
- // Check if pet needs to be teleported. [Skotlex]
- int flag = 0;
- struct block_list *bl = &sd->pd->bl;
- if (!checkpath && !path_search(NULL,bl->m,bl->x,bl->y,dst_x,dst_y,0,CELL_CHKNOPASS))
- flag = 1;
- else if (!check_distance_bl(&sd->bl, bl, AREA_SIZE)) //Too far, teleport.
- flag = 2;
- if (flag) {
- unit_movepos(bl,sd->bl.x,sd->bl.y, 0, 0);
- clif_slide(bl,bl->x,bl->y);
- }
- }
- }
- return 1;
+ short dx,dy;
+ uint8 dir;
+ struct unit_data *ud = NULL;
+ struct map_session_data *sd = NULL;
+
+ nullpo_ret(bl);
+ sd = BL_CAST(BL_PC, bl);
+ ud = unit_bl2ud(bl);
+
+ if( ud == NULL) return 0;
+
+ unit_stop_walking(bl,1);
+ unit_stop_attack(bl);
+
+ if( checkpath && (map_getcell(bl->m,dst_x,dst_y,CELL_CHKNOPASS) || !path_search(NULL,bl->m,bl->x,bl->y,dst_x,dst_y,easy,CELL_CHKNOREACH)) )
+ return 0; // unreachable
+
+ ud->to_x = dst_x;
+ ud->to_y = dst_y;
+
+ dir = map_calc_dir(bl, dst_x, dst_y);
+ ud->dir = dir;
+
+ dx = dst_x - bl->x;
+ dy = dst_y - bl->y;
+
+ map_foreachinmovearea(clif_outsight, bl, AREA_SIZE, dx, dy, sd?BL_ALL:BL_PC, bl);
+
+ map_moveblock(bl, dst_x, dst_y, gettick());
+
+ ud->walktimer = -2; // arbitrary non-INVALID_TIMER value to make the clif code send walking packets
+ map_foreachinmovearea(clif_insight, bl, AREA_SIZE, -dx, -dy, sd?BL_ALL:BL_PC, bl);
+ ud->walktimer = INVALID_TIMER;
+
+ if(sd) {
+ if( sd->touching_id )
+ npc_touchnext_areanpc(sd,false);
+ if(map_getcell(bl->m,bl->x,bl->y,CELL_CHKNPC)) {
+ npc_touch_areanpc(sd,bl->m,bl->x,bl->y);
+ if (bl->prev == NULL) //Script could have warped char, abort remaining of the function.
+ return 0;
+ } else
+ sd->areanpc_id=0;
+
+ if( sd->status.pet_id > 0 && sd->pd && sd->pd->pet.intimate > 0 )
+ { // Check if pet needs to be teleported. [Skotlex]
+ int flag = 0;
+ struct block_list* bl = &sd->pd->bl;
+ if( !checkpath && !path_search(NULL,bl->m,bl->x,bl->y,dst_x,dst_y,0,CELL_CHKNOPASS) )
+ flag = 1;
+ else if (!check_distance_bl(&sd->bl, bl, AREA_SIZE)) //Too far, teleport.
+ flag = 2;
+ if( flag )
+ {
+ unit_movepos(bl,sd->bl.x,sd->bl.y, 0, 0);
+ clif_slide(bl,bl->x,bl->y);
+ }
+ }
+ }
+ return 1;
}
int unit_setdir(struct block_list *bl,unsigned char dir)
{
- struct unit_data *ud;
- nullpo_ret(bl);
- ud = unit_bl2ud(bl);
- if (!ud) return 0;
- ud->dir = dir;
- if (bl->type == BL_PC)
- ((TBL_PC *)bl)->head_dir = 0;
- clif_changed_dir(bl, AREA);
- return 0;
+ struct unit_data *ud;
+ nullpo_ret(bl );
+ ud = unit_bl2ud(bl);
+ if (!ud) return 0;
+ ud->dir = dir;
+ if (bl->type == BL_PC)
+ ((TBL_PC *)bl)->head_dir = 0;
+ clif_changed_dir(bl, AREA);
+ return 0;
}
uint8 unit_getdir(struct block_list *bl)
{
- struct unit_data *ud;
- nullpo_ret(bl);
- ud = unit_bl2ud(bl);
- if (!ud) return 0;
- return ud->dir;
+ struct unit_data *ud;
+ nullpo_ret(bl );
+ ud = unit_bl2ud(bl);
+ if (!ud) return 0;
+ return ud->dir;
}
// Pushes a unit by given amount of cells into given direction. Only
// map cell restrictions are respected.
// flag:
// &1 Do not send position update packets.
-int unit_blown(struct block_list *bl, int dx, int dy, int count, int flag)
+int unit_blown(struct block_list* bl, int dx, int dy, int count, int flag)
{
- if (count) {
- struct map_session_data *sd;
- struct skill_unit *su = NULL;
- int nx, ny, result;
-
- sd = BL_CAST(BL_PC, bl);
- su = BL_CAST(BL_SKILL, bl);
-
- result = path_blownpos(bl->m, bl->x, bl->y, dx, dy, count);
-
- nx = result>>16;
- ny = result&0xffff;
-
- if (!su) {
- unit_stop_walking(bl, 0);
- }
-
- if (sd) {
- sd->ud.to_x = nx;
- sd->ud.to_y = ny;
- }
-
- dx = nx-bl->x;
- dy = ny-bl->y;
-
- if (dx || dy) {
- map_foreachinmovearea(clif_outsight, bl, AREA_SIZE, dx, dy, bl->type == BL_PC ? BL_ALL : BL_PC, bl);
-
- if (su) {
- skill_unit_move_unit_group(su->group, bl->m, dx, dy);
- } else {
- map_moveblock(bl, nx, ny, gettick());
- }
-
- map_foreachinmovearea(clif_insight, bl, AREA_SIZE, -dx, -dy, bl->type == BL_PC ? BL_ALL : BL_PC, bl);
-
- if (!(flag&1)) {
- clif_blown(bl);
- }
-
- if (sd) {
- if (sd->touching_id) {
- npc_touchnext_areanpc(sd, false);
- }
- if (map_getcell(bl->m, bl->x, bl->y, CELL_CHKNPC)) {
- npc_touch_areanpc(sd, bl->m, bl->x, bl->y);
- } else {
- sd->areanpc_id = 0;
- }
- }
- }
-
- count = distance(dx, dy);
- }
-
- return count; // return amount of knocked back cells
+ if(count) {
+ struct map_session_data* sd;
+ struct skill_unit* su = NULL;
+ int nx, ny, result;
+
+ sd = BL_CAST(BL_PC, bl);
+ su = BL_CAST(BL_SKILL, bl);
+
+ result = path_blownpos(bl->m, bl->x, bl->y, dx, dy, count);
+
+ nx = result>>16;
+ ny = result&0xffff;
+
+ if(!su) {
+ unit_stop_walking(bl, 0);
+ }
+
+ if( sd ) {
+ sd->ud.to_x = nx;
+ sd->ud.to_y = ny;
+ }
+
+ dx = nx-bl->x;
+ dy = ny-bl->y;
+
+ if(dx || dy) {
+ map_foreachinmovearea(clif_outsight, bl, AREA_SIZE, dx, dy, bl->type == BL_PC ? BL_ALL : BL_PC, bl);
+
+ if(su) {
+ skill_unit_move_unit_group(su->group, bl->m, dx, dy);
+ } else {
+ map_moveblock(bl, nx, ny, gettick());
+ }
+
+ map_foreachinmovearea(clif_insight, bl, AREA_SIZE, -dx, -dy, bl->type == BL_PC ? BL_ALL : BL_PC, bl);
+
+ if(!(flag&1)) {
+ clif_blown(bl);
+ }
+
+ if(sd) {
+ if(sd->touching_id) {
+ npc_touchnext_areanpc(sd, false);
+ }
+ if(map_getcell(bl->m, bl->x, bl->y, CELL_CHKNPC)) {
+ npc_touch_areanpc(sd, bl->m, bl->x, bl->y);
+ } else {
+ sd->areanpc_id = 0;
+ }
+ }
+ }
+
+ count = distance(dx, dy);
+ }
+
+ return count; // return amount of knocked back cells
}
//Warps a unit/ud to a given map/position.
@@ -726,70 +748,70 @@ int unit_blown(struct block_list *bl, int dx, int dy, int count, int flag)
//it respects the no warp flags, so it is safe to call this without doing nowarpto/nowarp checks.
int unit_warp(struct block_list *bl,short m,short x,short y,clr_type type)
{
- struct unit_data *ud;
- nullpo_ret(bl);
- ud = unit_bl2ud(bl);
-
- if (bl->prev==NULL || !ud)
- return 1;
-
- if (type == CLR_DEAD)
- //Type 1 is invalid, since you shouldn't warp a bl with the "death"
- //animation, it messes up with unit_remove_map! [Skotlex]
- return 1;
-
- if (m<0) m=bl->m;
-
- switch (bl->type) {
- case BL_MOB:
- if (map[bl->m].flag.monster_noteleport && ((TBL_MOB *)bl)->master_id == 0)
- return 1;
- if (m != bl->m && map[m].flag.nobranch && battle_config.mob_warp&4 && !(((TBL_MOB *)bl)->master_id))
- return 1;
- break;
- case BL_PC:
- if (map[bl->m].flag.noteleport)
- return 1;
- break;
- }
-
- if (x<0 || y<0) {
- //Random map position.
- if (!map_search_freecell(NULL, m, &x, &y, -1, -1, 1)) {
- ShowWarning("unit_warp failed. Unit Id:%d/Type:%d, target position map %d (%s) at [%d,%d]\n", bl->id, bl->type, m, map[m].name, x, y);
- return 2;
-
- }
- } else if (map_getcell(m,x,y,CELL_CHKNOREACH)) {
- //Invalid target cell
- ShowWarning("unit_warp: Specified non-walkable target cell: %d (%s) at [%d,%d]\n", m, map[m].name, x,y);
-
- if (!map_search_freecell(NULL, m, &x, &y, 4, 4, 1)) {
- //Can't find a nearby cell
- ShowWarning("unit_warp failed. Unit Id:%d/Type:%d, target position map %d (%s) at [%d,%d]\n", bl->id, bl->type, m, map[m].name, x, y);
- return 2;
- }
- }
-
- if (bl->type == BL_PC) //Use pc_setpos
- return pc_setpos((TBL_PC *)bl, map_id2index(m), x, y, type);
-
- if (!unit_remove_map(bl, type))
- return 3;
-
- if (bl->m != m && battle_config.clear_unit_onwarp &&
- battle_config.clear_unit_onwarp&bl->type)
- skill_clear_unitgroup(bl);
-
- bl->x=ud->to_x=x;
- bl->y=ud->to_y=y;
- bl->m=m;
-
- map_addblock(bl);
- clif_spawn(bl);
- skill_unit_move(bl,gettick(),1);
-
- return 0;
+ struct unit_data *ud;
+ nullpo_ret(bl);
+ ud = unit_bl2ud(bl);
+
+ if(bl->prev==NULL || !ud)
+ return 1;
+
+ if (type == CLR_DEAD)
+ //Type 1 is invalid, since you shouldn't warp a bl with the "death"
+ //animation, it messes up with unit_remove_map! [Skotlex]
+ return 1;
+
+ if( m<0 ) m=bl->m;
+
+ switch (bl->type) {
+ case BL_MOB:
+ if (map[bl->m].flag.monster_noteleport && ((TBL_MOB*)bl)->master_id == 0)
+ return 1;
+ if (m != bl->m && map[m].flag.nobranch && battle_config.mob_warp&4)
+ return 1;
+ break;
+ case BL_PC:
+ if (map[bl->m].flag.noteleport)
+ return 1;
+ break;
+ }
+
+ if (x<0 || y<0)
+ { //Random map position.
+ if (!map_search_freecell(NULL, m, &x, &y, -1, -1, 1)) {
+ ShowWarning("unit_warp failed. Unit Id:%d/Type:%d, target position map %d (%s) at [%d,%d]\n", bl->id, bl->type, m, map[m].name, x, y);
+ return 2;
+
+ }
+ } else if (map_getcell(m,x,y,CELL_CHKNOREACH))
+ { //Invalid target cell
+ ShowWarning("unit_warp: Specified non-walkable target cell: %d (%s) at [%d,%d]\n", m, map[m].name, x,y);
+
+ if (!map_search_freecell(NULL, m, &x, &y, 4, 4, 1))
+ { //Can't find a nearby cell
+ ShowWarning("unit_warp failed. Unit Id:%d/Type:%d, target position map %d (%s) at [%d,%d]\n", bl->id, bl->type, m, map[m].name, x, y);
+ return 2;
+ }
+ }
+
+ if (bl->type == BL_PC) //Use pc_setpos
+ return pc_setpos((TBL_PC*)bl, map_id2index(m), x, y, type);
+
+ if (!unit_remove_map(bl, type))
+ return 3;
+
+ if (bl->m != m && battle_config.clear_unit_onwarp &&
+ battle_config.clear_unit_onwarp&bl->type)
+ skill_clear_unitgroup(bl);
+
+ bl->x=ud->to_x=x;
+ bl->y=ud->to_y=y;
+ bl->m=m;
+
+ map_addblock(bl);
+ clif_spawn(bl);
+ skill_unit_move(bl,gettick(),1);
+
+ return 0;
}
/*==========================================
@@ -802,64 +824,64 @@ int unit_warp(struct block_list *bl,short m,short x,short y,clr_type type)
*------------------------------------------*/
int unit_stop_walking(struct block_list *bl,int type)
{
- struct unit_data *ud;
- const struct TimerData *td;
- unsigned int tick;
- nullpo_ret(bl);
-
- ud = unit_bl2ud(bl);
- if (!ud || ud->walktimer == INVALID_TIMER)
- return 0;
- //NOTE: We are using timer data after deleting it because we know the
- //delete_timer function does not messes with it. If the function's
- //behaviour changes in the future, this code could break!
- td = get_timer(ud->walktimer);
- delete_timer(ud->walktimer, unit_walktoxy_timer);
- ud->walktimer = INVALID_TIMER;
- ud->state.change_walk_target = 0;
- tick = gettick();
- if ((type&0x02 && !ud->walkpath.path_pos) //Force moving at least one cell.
- || (type&0x04 && td && DIFF_TICK(td->tick, tick) <= td->data/2) //Enough time has passed to cover half-cell
- ) {
- ud->walkpath.path_len = ud->walkpath.path_pos+1;
- unit_walktoxy_timer(INVALID_TIMER, tick, bl->id, ud->walkpath.path_pos);
- }
-
- if (type&0x01)
- clif_fixpos(bl);
-
- ud->walkpath.path_len = 0;
- ud->walkpath.path_pos = 0;
- ud->to_x = bl->x;
- ud->to_y = bl->y;
- if (bl->type == BL_PET && type&~0xff)
- ud->canmove_tick = gettick() + (type>>8);
-
- //Readded, the check in unit_set_walkdelay means dmg during running won't fall through to this place in code [Kevin]
- if (ud->state.running) {
- status_change_end(bl, SC_RUN, INVALID_TIMER);
- status_change_end(bl, SC_WUGDASH, INVALID_TIMER);
- }
- return 1;
+ struct unit_data *ud;
+ const struct TimerData* td;
+ unsigned int tick;
+ nullpo_ret(bl);
+
+ ud = unit_bl2ud(bl);
+ if(!ud || ud->walktimer == INVALID_TIMER)
+ return 0;
+ //NOTE: We are using timer data after deleting it because we know the
+ //delete_timer function does not messes with it. If the function's
+ //behaviour changes in the future, this code could break!
+ td = get_timer(ud->walktimer);
+ delete_timer(ud->walktimer, unit_walktoxy_timer);
+ ud->walktimer = INVALID_TIMER;
+ ud->state.change_walk_target = 0;
+ tick = gettick();
+ if( (type&0x02 && !ud->walkpath.path_pos) //Force moving at least one cell.
+ || (type&0x04 && td && DIFF_TICK(td->tick, tick) <= td->data/2) //Enough time has passed to cover half-cell
+ ) {
+ ud->walkpath.path_len = ud->walkpath.path_pos+1;
+ unit_walktoxy_timer(INVALID_TIMER, tick, bl->id, ud->walkpath.path_pos);
+ }
+
+ if(type&0x01)
+ clif_fixpos(bl);
+
+ ud->walkpath.path_len = 0;
+ ud->walkpath.path_pos = 0;
+ ud->to_x = bl->x;
+ ud->to_y = bl->y;
+ if(bl->type == BL_PET && type&~0xff)
+ ud->canmove_tick = gettick() + (type>>8);
+
+ //Readded, the check in unit_set_walkdelay means dmg during running won't fall through to this place in code [Kevin]
+ if (ud->state.running) {
+ status_change_end(bl, SC_RUN, INVALID_TIMER);
+ status_change_end(bl, SC_WUGDASH, INVALID_TIMER);
+ }
+ return 1;
}
int unit_skilluse_id(struct block_list *src, int target_id, short skill_num, short skill_lv)
{
- if (skill_num < 0) return 0;
+ if(skill_num < 0) return 0;
- return unit_skilluse_id2(
- src, target_id, skill_num, skill_lv,
- skill_castfix(src, skill_num, skill_lv),
- skill_get_castcancel(skill_num)
- );
+ return unit_skilluse_id2(
+ src, target_id, skill_num, skill_lv,
+ skill_castfix(src, skill_num, skill_lv),
+ skill_get_castcancel(skill_num)
+ );
}
int unit_is_walking(struct block_list *bl)
{
- struct unit_data *ud = unit_bl2ud(bl);
- nullpo_ret(bl);
- if (!ud) return 0;
- return (ud->walktimer != INVALID_TIMER);
+ struct unit_data *ud = unit_bl2ud(bl);
+ nullpo_ret(bl);
+ if(!ud) return 0;
+ return (ud->walktimer != INVALID_TIMER);
}
/*==========================================
@@ -867,54 +889,54 @@ int unit_is_walking(struct block_list *bl)
*------------------------------------------*/
int unit_can_move(struct block_list *bl)
{
- struct map_session_data *sd;
- struct unit_data *ud;
- struct status_change *sc;
-
- nullpo_ret(bl);
- ud = unit_bl2ud(bl);
- sc = status_get_sc(bl);
- sd = BL_CAST(BL_PC, bl);
-
- if (!ud)
- return 0;
-
- if (ud->skilltimer != INVALID_TIMER && ud->skillid != LG_EXEEDBREAK && (!sd || !pc_checkskill(sd, SA_FREECAST) || skill_get_inf2(ud->skillid)&INF2_GUILD_SKILL))
- return 0; // prevent moving while casting
-
- if (DIFF_TICK(ud->canmove_tick, gettick()) > 0)
- return 0;
-
- if (sd && (
- pc_issit(sd) ||
- sd->state.vending ||
- sd->state.buyingstore ||
- sd->state.blockedmove
- ))
- return 0; //Can't move
-
- if (sc) {
- if (sc->cant.move /* status placed here are ones that cannot be cached by sc->cant.move for they depend on other conditions other than their availability */
- || (sc->data[SC_FEAR] && sc->data[SC_FEAR]->val2 > 0)
- || (sc->data[SC_SPIDERWEB] && sc->data[SC_SPIDERWEB]->val1)
- || (sc->data[SC_DANCING] && sc->data[SC_DANCING]->val4 && (
- !sc->data[SC_LONGING] ||
- (sc->data[SC_DANCING]->val1&0xFFFF) == CG_MOONLIT ||
- (sc->data[SC_DANCING]->val1&0xFFFF) == CG_HERMODE
- ))
- || (sc->data[SC_CLOAKING] && //Need wall at level 1-2
- sc->data[SC_CLOAKING]->val1 < 3 && !(sc->data[SC_CLOAKING]->val4&1))
- )
- return 0;
-
- if (sc->opt1 > 0 && sc->opt1 != OPT1_STONEWAIT && sc->opt1 != OPT1_BURNING && (sc->opt1 != OPT1_CRYSTALIZE && bl->type != BL_MOB))
- return 0;
-
- if ((sc->option & OPTION_HIDE) && (!sd || pc_checkskill(sd, RG_TUNNELDRIVE) <= 0))
- return 0;
-
- }
- return 1;
+ struct map_session_data *sd;
+ struct unit_data *ud;
+ struct status_change *sc;
+
+ nullpo_ret(bl);
+ ud = unit_bl2ud(bl);
+ sc = status_get_sc(bl);
+ sd = BL_CAST(BL_PC, bl);
+
+ if (!ud)
+ return 0;
+
+ if (ud->skilltimer != INVALID_TIMER && ud->skillid != LG_EXEEDBREAK && (!sd || !pc_checkskill(sd, SA_FREECAST) || skill_get_inf2(ud->skillid)&INF2_GUILD_SKILL))
+ return 0; // prevent moving while casting
+
+ if (DIFF_TICK(ud->canmove_tick, gettick()) > 0)
+ return 0;
+
+ if (sd && (
+ pc_issit(sd) ||
+ sd->state.vending ||
+ sd->state.buyingstore ||
+ sd->state.blockedmove
+ ))
+ return 0; //Can't move
+
+ if (sc) {
+ if( sc->cant.move /* status placed here are ones that cannot be cached by sc->cant.move for they depend on other conditions other than their availability */
+ || (sc->data[SC_FEAR] && sc->data[SC_FEAR]->val2 > 0)
+ || (sc->data[SC_SPIDERWEB] && sc->data[SC_SPIDERWEB]->val1)
+ || (sc->data[SC_DANCING] && sc->data[SC_DANCING]->val4 && (
+ !sc->data[SC_LONGING] ||
+ (sc->data[SC_DANCING]->val1&0xFFFF) == CG_MOONLIT ||
+ (sc->data[SC_DANCING]->val1&0xFFFF) == CG_HERMODE
+ ) )
+ || (sc->data[SC_CLOAKING] && //Need wall at level 1-2
+ sc->data[SC_CLOAKING]->val1 < 3 && !(sc->data[SC_CLOAKING]->val4&1))
+ )
+ return 0;
+
+ if (sc->opt1 > 0 && sc->opt1 != OPT1_STONEWAIT && sc->opt1 != OPT1_BURNING && (sc->opt1 != OPT1_CRYSTALIZE && bl->type != BL_MOB))
+ return 0;
+
+ if ((sc->option & OPTION_HIDE) && (!sd || pc_checkskill(sd, RG_TUNNELDRIVE) <= 0))
+ return 0;
+
+ }
+ return 1;
}
/*==========================================
@@ -924,19 +946,19 @@ int unit_can_move(struct block_list *bl)
int unit_resume_running(int tid, unsigned int tick, int id, intptr_t data)
{
- struct unit_data *ud = (struct unit_data *)data;
- TBL_PC *sd = map_id2sd(id);
+ struct unit_data *ud = (struct unit_data *)data;
+ TBL_PC * sd = map_id2sd(id);
- if (sd && pc_isridingwug(sd))
- clif_skill_nodamage(ud->bl,ud->bl,RA_WUGDASH,ud->skilllv,
- sc_start4(ud->bl,status_skill2sc(RA_WUGDASH),100,ud->skilllv,unit_getdir(ud->bl),0,0,1));
- else
- clif_skill_nodamage(ud->bl,ud->bl,TK_RUN,ud->skilllv,
- sc_start4(ud->bl,status_skill2sc(TK_RUN),100,ud->skilllv,unit_getdir(ud->bl),0,0,0));
+ if(sd && pc_isridingwug(sd))
+ clif_skill_nodamage(ud->bl,ud->bl,RA_WUGDASH,ud->skilllv,
+ sc_start4(ud->bl,status_skill2sc(RA_WUGDASH),100,ud->skilllv,unit_getdir(ud->bl),0,0,1));
+ else
+ clif_skill_nodamage(ud->bl,ud->bl,TK_RUN,ud->skilllv,
+ sc_start4(ud->bl,status_skill2sc(TK_RUN),100,ud->skilllv,unit_getdir(ud->bl),0,0,0));
- if (sd) clif_walkok(sd);
+ if (sd) clif_walkok(sd);
- return 0;
+ return 0;
}
@@ -948,534 +970,555 @@ int unit_resume_running(int tid, unsigned int tick, int id, intptr_t data)
*------------------------------------------*/
int unit_set_walkdelay(struct block_list *bl, unsigned int tick, int delay, int type)
{
- struct unit_data *ud = unit_bl2ud(bl);
- if (delay <= 0 || !ud) return 0;
-
- /**
- * MvP mobs have no walk delay
- **/
- if (bl->type == BL_MOB && (((TBL_MOB *)bl)->status.mode&MD_BOSS))
- return 0;
-
- if (type) {
- if (DIFF_TICK(ud->canmove_tick, tick+delay) > 0)
- return 0;
- } else {
- //Don't set walk delays when already trapped.
- if (!unit_can_move(bl))
- return 0;
- }
- ud->canmove_tick = tick + delay;
- if (ud->walktimer != INVALID_TIMER) {
- //Stop walking, if chasing, readjust timers.
- if (delay == 1) {
- //Minimal delay (walk-delay) disabled. Just stop walking.
- unit_stop_walking(bl,4);
- } else {
- //Resume running after can move again [Kevin]
- if (ud->state.running) {
- add_timer(ud->canmove_tick, unit_resume_running, bl->id, (intptr_t)ud);
- } else {
- unit_stop_walking(bl,2|4);
- if (ud->target)
- add_timer(ud->canmove_tick+1, unit_walktobl_sub, bl->id, ud->target);
- }
- }
- }
- return 1;
+ struct unit_data *ud = unit_bl2ud(bl);
+ if (delay <= 0 || !ud) return 0;
+
+ /**
+ * MvP mobs have no walk delay
+ **/
+ if( bl->type == BL_MOB && (((TBL_MOB*)bl)->status.mode&MD_BOSS) )
+ return 0;
+
+ if (type) {
+ if (DIFF_TICK(ud->canmove_tick, tick+delay) > 0)
+ return 0;
+ } else {
+ //Don't set walk delays when already trapped.
+ if (!unit_can_move(bl))
+ return 0;
+ }
+ ud->canmove_tick = tick + delay;
+ if (ud->walktimer != INVALID_TIMER)
+ { //Stop walking, if chasing, readjust timers.
+ if (delay == 1)
+ { //Minimal delay (walk-delay) disabled. Just stop walking.
+ unit_stop_walking(bl,4);
+ } else {
+ //Resume running after can move again [Kevin]
+ if(ud->state.running)
+ {
+ add_timer(ud->canmove_tick, unit_resume_running, bl->id, (intptr_t)ud);
+ }
+ else
+ {
+ unit_stop_walking(bl,2|4);
+ if(ud->target)
+ add_timer(ud->canmove_tick+1, unit_walktobl_sub, bl->id, ud->target);
+ }
+ }
+ }
+ return 1;
}
int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, short skill_lv, int casttime, int castcancel)
{
- struct unit_data *ud;
- struct status_data *tstatus;
- struct status_change *sc;
- struct map_session_data *sd = NULL;
- struct block_list *target = NULL;
- unsigned int tick = gettick();
- int temp = 0;
-
- nullpo_ret(src);
- if (status_isdead(src))
- return 0; //Do not continue source is dead
-
- sd = BL_CAST(BL_PC, src);
- ud = unit_bl2ud(src);
-
- if (ud == NULL) return 0;
- sc = status_get_sc(src);
- if (sc && !sc->count)
- sc = NULL; //Unneeded
-
- //temp: used to signal combo-skills right now.
- if (sc && sc->data[SC_COMBO] && (sc->data[SC_COMBO]->val1 == skill_num ||
- (sd?skill_check_condition_castbegin(sd,skill_num,skill_lv):0))) {
- if (sc->data[SC_COMBO]->val2)
- target_id = sc->data[SC_COMBO]->val2;
- else
- target_id = ud->target;
-
- if (skill_get_inf(skill_num)&INF_SELF_SKILL && skill_get_nk(skill_num)&NK_NO_DAMAGE) // exploit fix
- target_id = src->id;
- temp = 1;
- } else if (target_id == src->id &&
- skill_get_inf(skill_num)&INF_SELF_SKILL &&
- skill_get_inf2(skill_num)&INF2_NO_TARGET_SELF) {
- target_id = ud->target; //Auto-select target. [Skotlex]
- temp = 1;
- }
-
- if (sd) {
- //Target_id checking.
- if (skillnotok(skill_num, sd)) // [MouseJstr]
- return 0;
-
- switch (skill_num) {
- //Check for skills that auto-select target
- case MO_CHAINCOMBO:
- if (sc && sc->data[SC_BLADESTOP]) {
- if ((target=map_id2bl(sc->data[SC_BLADESTOP]->val4)) == NULL)
- return 0;
- }
- break;
- case WE_MALE:
- case WE_FEMALE:
- if (!sd->status.partner_id)
- return 0;
- target = (struct block_list *)map_charid2sd(sd->status.partner_id);
- if (!target) {
- clif_skill_fail(sd,skill_num,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- }
- if (target)
- target_id = target->id;
- }
- if (src->type==BL_HOM)
- switch (skill_num) {
- //Homun-auto-target skills.
- case HLIF_HEAL:
- case HLIF_AVOID:
- case HAMI_DEFENCE:
- case HAMI_CASTLE:
- target = battle_get_master(src);
- if (!target) return 0;
- target_id = target->id;
- }
-
- if (!target) // choose default target
- target = map_id2bl(target_id);
-
- if (!target || src->m != target->m || !src->prev || !target->prev)
- return 0;
-
- if (battle_config.ksprotection && sd && mob_ksprotected(src, target))
- return 0;
-
- //Normally not needed because clif.c checks for it, but the at/char/script commands don't! [Skotlex]
- if (ud->skilltimer != INVALID_TIMER && skill_num != SA_CASTCANCEL && skill_num != SO_SPELLFIST)
- return 0;
-
- if (skill_get_inf2(skill_num)&INF2_NO_TARGET_SELF && src->id == target_id)
- return 0;
-
- if (!status_check_skilluse(src, target, skill_num, 0))
- return 0;
-
- tstatus = status_get_status_data(target);
- // Record the status of the previous skill)
- if (sd) {
- switch (skill_num) {
- case SA_CASTCANCEL:
- if (ud->skillid != skill_num) {
- sd->skillid_old = ud->skillid;
- sd->skilllv_old = ud->skilllv;
- }
- break;
- case BD_ENCORE:
- //Prevent using the dance skill if you no longer have the skill in your tree.
- if (!sd->skillid_dance || pc_checkskill(sd,sd->skillid_dance)<=0) {
- clif_skill_fail(sd,skill_num,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- sd->skillid_old = skill_num;
- break;
- case BD_LULLABY:
- case BD_RICHMANKIM:
- case BD_ETERNALCHAOS:
- case BD_DRUMBATTLEFIELD:
- case BD_RINGNIBELUNGEN:
- case BD_ROKISWEIL:
- case BD_INTOABYSS:
- case BD_SIEGFRIED:
- case CG_MOONLIT:
- if (skill_check_pc_partner(sd, skill_num, &skill_lv, 1, 0) < 1) {
- clif_skill_fail(sd,skill_num,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- case WL_WHITEIMPRISON:
- if (battle_check_target(src,target,BCT_SELF|BCT_ENEMY) < 0) {
- clif_skill_fail(sd,skill_num,USESKILL_FAIL_TOTARGET,0);
- return 0;
- }
- break;
- case MG_FIREBOLT:
- case MG_LIGHTNINGBOLT:
- case MG_COLDBOLT:
- sd->skillid_old = skill_num;
- sd->skilllv_old = skill_lv;
- break;
- }
- if (!skill_check_condition_castbegin(sd, skill_num, skill_lv))
- return 0;
- }
-
- if (src->type == BL_MOB)
- switch (skill_num) {
- case NPC_SUMMONSLAVE:
- case NPC_SUMMONMONSTER:
- case AL_TELEPORT:
- if (((TBL_MOB *)src)->master_id && ((TBL_MOB *)src)->special_state.ai)
- return 0;
- }
-
- //Check range when not using skill on yourself or is a combo-skill during attack
- //(these are supposed to always have the same range as your attack)
- if (src->id != target_id && (!temp || ud->attacktimer == INVALID_TIMER)) {
- if (skill_get_state(ud->skillid) == ST_MOVE_ENABLE) {
- if (!unit_can_reach_bl(src, target, skill_get_range2(src, skill_num,skill_lv) + 1, 1, NULL, NULL))
- return 0; // Walk-path check failed.
- } else if (src->type == BL_MER && skill_num == MA_REMOVETRAP) {
- if (!battle_check_range(battle_get_master(src), target, skill_get_range2(src, skill_num, skill_lv) + 1))
- return 0; // Aegis calc remove trap based on Master position, ignoring mercenary O.O
- } else if (!battle_check_range(src, target, skill_get_range2(src, skill_num,skill_lv) + (skill_num == RG_CLOSECONFINE?0:2))) {
- return 0; // Arrow-path check failed.
- }
- }
-
- if (!temp) //Stop attack on non-combo skills [Skotlex]
- unit_stop_attack(src);
- else if (ud->attacktimer != INVALID_TIMER) //Elsewise, delay current attack sequence
- ud->attackabletime = tick + status_get_adelay(src);
-
- ud->state.skillcastcancel = castcancel;
-
- //temp: Used to signal force cast now.
- temp = 0;
-
- switch (skill_num) {
- case ALL_RESURRECTION:
- if (battle_check_undead(tstatus->race,tstatus->def_ele)) {
- temp = 1;
- } else if (!status_isdead(target))
- return 0; //Can't cast on non-dead characters.
- break;
- case MO_FINGEROFFENSIVE:
- if (sd)
- casttime += casttime * min(skill_lv, sd->spiritball);
- break;
- case MO_EXTREMITYFIST:
- if (sc && sc->data[SC_COMBO] &&
- (sc->data[SC_COMBO]->val1 == MO_COMBOFINISH ||
- sc->data[SC_COMBO]->val1 == CH_TIGERFIST ||
- sc->data[SC_COMBO]->val1 == CH_CHAINCRUSH))
- casttime = -1;
- temp = 1;
- break;
- case SR_GATEOFHELL:
- case SR_TIGERCANNON:
- if (sc && sc->data[SC_COMBO] &&
- sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE)
- casttime = -1;
- temp = 1;
- break;
- case SA_SPELLBREAKER:
- temp = 1;
- break;
- case ST_CHASEWALK:
- if (sc && sc->data[SC_CHASEWALK])
- casttime = -1;
- break;
- case TK_RUN:
- if (sc && sc->data[SC_RUN])
- casttime = -1;
- break;
- case HP_BASILICA:
- if (sc && sc->data[SC_BASILICA])
- casttime = -1; // No Casting time on basilica cancel
- break;
- case KN_CHARGEATK: {
- unsigned int k = (distance_bl(src,target)-1)/3; //+100% every 3 cells of distance
- if (k > 2) k = 2; // ...but hard-limited to 300%.
- casttime += casttime * k;
- }
- break;
- case GD_EMERGENCYCALL: //Emergency Call double cast when the user has learned Leap [Daegaladh]
- if (sd && pc_checkskill(sd,TK_HIGHJUMP))
- casttime *= 2;
- break;
- case RA_WUGDASH:
- if (sc && sc->data[SC_WUGDASH])
- casttime = -1;
- break;
- }
-
- // moved here to prevent Suffragium from ending if skill fails
+ struct unit_data *ud;
+ struct status_data *tstatus;
+ struct status_change *sc;
+ struct map_session_data *sd = NULL;
+ struct block_list * target = NULL;
+ unsigned int tick = gettick();
+ int temp = 0;
+
+ nullpo_ret(src);
+ if(status_isdead(src))
+ return 0; //Do not continue source is dead
+
+ sd = BL_CAST(BL_PC, src);
+ ud = unit_bl2ud(src);
+
+ if(ud == NULL) return 0;
+ sc = status_get_sc(src);
+ if (sc && !sc->count)
+ sc = NULL; //Unneeded
+
+ //temp: used to signal combo-skills right now.
+ if (sc && sc->data[SC_COMBO] && (sc->data[SC_COMBO]->val1 == skill_num ||
+ (sd?skill_check_condition_castbegin(sd,skill_num,skill_lv):0) )) {
+ if (sc->data[SC_COMBO]->val2)
+ target_id = sc->data[SC_COMBO]->val2;
+ else
+ target_id = ud->target;
+
+ if( skill_get_inf(skill_num)&INF_SELF_SKILL && skill_get_nk(skill_num)&NK_NO_DAMAGE )// exploit fix
+ target_id = src->id;
+ temp = 1;
+ } else
+ if ( target_id == src->id &&
+ skill_get_inf(skill_num)&INF_SELF_SKILL &&
+ skill_get_inf2(skill_num)&INF2_NO_TARGET_SELF )
+ {
+ target_id = ud->target; //Auto-select target. [Skotlex]
+ temp = 1;
+ }
+
+ if (sd) {
+ //Target_id checking.
+ if(skillnotok(skill_num, sd)) // [MouseJstr]
+ return 0;
+
+ switch(skill_num)
+ { //Check for skills that auto-select target
+ case MO_CHAINCOMBO:
+ if (sc && sc->data[SC_BLADESTOP]){
+ if ((target=map_id2bl(sc->data[SC_BLADESTOP]->val4)) == NULL)
+ return 0;
+ }
+ break;
+ case WE_MALE:
+ case WE_FEMALE:
+ if (!sd->status.partner_id)
+ return 0;
+ target = (struct block_list*)map_charid2sd(sd->status.partner_id);
+ if (!target) {
+ clif_skill_fail(sd,skill_num,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ }
+ if (target)
+ target_id = target->id;
+ }
+ if (src->type==BL_HOM)
+ switch(skill_num)
+ { //Homun-auto-target skills.
+ case HLIF_HEAL:
+ case HLIF_AVOID:
+ case HAMI_DEFENCE:
+ case HAMI_CASTLE:
+ target = battle_get_master(src);
+ if (!target) return 0;
+ target_id = target->id;
+ }
+
+ if( !target ) // choose default target
+ target = map_id2bl(target_id);
+
+ if( !target || src->m != target->m || !src->prev || !target->prev )
+ return 0;
+
+ if( battle_config.ksprotection && sd && mob_ksprotected(src, target) )
+ return 0;
+
+ //Normally not needed because clif.c checks for it, but the at/char/script commands don't! [Skotlex]
+ if(ud->skilltimer != INVALID_TIMER && skill_num != SA_CASTCANCEL && skill_num != SO_SPELLFIST)
+ return 0;
+
+ if(skill_get_inf2(skill_num)&INF2_NO_TARGET_SELF && src->id == target_id)
+ return 0;
+
+ if(!status_check_skilluse(src, target, skill_num, 0))
+ return 0;
+
+ tstatus = status_get_status_data(target);
+ // Record the status of the previous skill)
+ if(sd) {
+ switch(skill_num){
+ case SA_CASTCANCEL:
+ if(ud->skillid != skill_num){
+ sd->skillid_old = ud->skillid;
+ sd->skilllv_old = ud->skilllv;
+ }
+ break;
+ case BD_ENCORE:
+ //Prevent using the dance skill if you no longer have the skill in your tree.
+ if(!sd->skillid_dance || pc_checkskill(sd,sd->skillid_dance)<=0){
+ clif_skill_fail(sd,skill_num,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ sd->skillid_old = skill_num;
+ break;
+ case BD_LULLABY:
+ case BD_RICHMANKIM:
+ case BD_ETERNALCHAOS:
+ case BD_DRUMBATTLEFIELD:
+ case BD_RINGNIBELUNGEN:
+ case BD_ROKISWEIL:
+ case BD_INTOABYSS:
+ case BD_SIEGFRIED:
+ case CG_MOONLIT:
+ if (skill_check_pc_partner(sd, skill_num, &skill_lv, 1, 0) < 1)
+ {
+ clif_skill_fail(sd,skill_num,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
+ case WL_WHITEIMPRISON:
+ if( battle_check_target(src,target,BCT_SELF|BCT_ENEMY) < 0 ) {
+ clif_skill_fail(sd,skill_num,USESKILL_FAIL_TOTARGET,0);
+ return 0;
+ }
+ break;
+ case MG_FIREBOLT:
+ case MG_LIGHTNINGBOLT:
+ case MG_COLDBOLT:
+ sd->skillid_old = skill_num;
+ sd->skilllv_old = skill_lv;
+ break;
+ }
+ if (!skill_check_condition_castbegin(sd, skill_num, skill_lv))
+ return 0;
+ }
+
+ if( src->type == BL_MOB )
+ switch( skill_num )
+ {
+ case NPC_SUMMONSLAVE:
+ case NPC_SUMMONMONSTER:
+ case AL_TELEPORT:
+ if( ((TBL_MOB*)src)->master_id && ((TBL_MOB*)src)->special_state.ai )
+ return 0;
+ }
+
+ //Check range when not using skill on yourself or is a combo-skill during attack
+ //(these are supposed to always have the same range as your attack)
+ if( src->id != target_id && (!temp || ud->attacktimer == INVALID_TIMER) ) {
+ if( skill_get_state(ud->skillid) == ST_MOVE_ENABLE ) {
+ if( !unit_can_reach_bl(src, target, skill_get_range2(src, skill_num,skill_lv) + 1, 1, NULL, NULL) )
+ return 0; // Walk-path check failed.
+ } else if( src->type == BL_MER && skill_num == MA_REMOVETRAP ) {
+ if( !battle_check_range(battle_get_master(src), target, skill_get_range2(src, skill_num, skill_lv) + 1) )
+ return 0; // Aegis calc remove trap based on Master position, ignoring mercenary O.O
+ } else if( !battle_check_range(src, target, skill_get_range2(src, skill_num,skill_lv) + (skill_num == RG_CLOSECONFINE?0:2)) ) {
+ return 0; // Arrow-path check failed.
+ }
+ }
+
+ if (!temp) //Stop attack on non-combo skills [Skotlex]
+ unit_stop_attack(src);
+ else if(ud->attacktimer != INVALID_TIMER) //Elsewise, delay current attack sequence
+ ud->attackabletime = tick + status_get_adelay(src);
+
+ ud->state.skillcastcancel = castcancel;
+
+ //temp: Used to signal force cast now.
+ temp = 0;
+
+ switch(skill_num){
+ case ALL_RESURRECTION:
+ if(battle_check_undead(tstatus->race,tstatus->def_ele)) {
+ temp = 1;
+ } else if (!status_isdead(target))
+ return 0; //Can't cast on non-dead characters.
+ break;
+ case MO_FINGEROFFENSIVE:
+ if(sd)
+ casttime += casttime * min(skill_lv, sd->spiritball);
+ break;
+ case MO_EXTREMITYFIST:
+ if (sc && sc->data[SC_COMBO] &&
+ (sc->data[SC_COMBO]->val1 == MO_COMBOFINISH ||
+ sc->data[SC_COMBO]->val1 == CH_TIGERFIST ||
+ sc->data[SC_COMBO]->val1 == CH_CHAINCRUSH))
+ casttime = -1;
+ temp = 1;
+ break;
+ case SR_GATEOFHELL:
+ case SR_TIGERCANNON:
+ if (sc && sc->data[SC_COMBO] &&
+ sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE)
+ casttime = -1;
+ temp = 1;
+ break;
+ case SA_SPELLBREAKER:
+ temp = 1;
+ break;
+ case ST_CHASEWALK:
+ if (sc && sc->data[SC_CHASEWALK])
+ casttime = -1;
+ break;
+ case TK_RUN:
+ if (sc && sc->data[SC_RUN])
+ casttime = -1;
+ break;
+ case HP_BASILICA:
+ if( sc && sc->data[SC_BASILICA] )
+ casttime = -1; // No Casting time on basilica cancel
+ break;
+ case KN_CHARGEATK:
+ {
+ unsigned int k = (distance_bl(src,target)-1)/3; //+100% every 3 cells of distance
+ if( k > 2 ) k = 2; // ...but hard-limited to 300%.
+ casttime += casttime * k;
+ }
+ break;
+ case GD_EMERGENCYCALL: //Emergency Call double cast when the user has learned Leap [Daegaladh]
+ if( sd && pc_checkskill(sd,TK_HIGHJUMP) )
+ casttime *= 2;
+ break;
+ case RA_WUGDASH:
+ if (sc && sc->data[SC_WUGDASH])
+ casttime = -1;
+ break;
+ }
+
+ // moved here to prevent Suffragium from ending if skill fails
#ifndef RENEWAL_CAST
- if (!(skill_get_castnodex(skill_num, skill_lv)&2))
- casttime = skill_castfix_sc(src, casttime);
+ if (!(skill_get_castnodex(skill_num, skill_lv)&2))
+ casttime = skill_castfix_sc(src, casttime);
#else
- casttime = skill_vfcastfix(src, casttime, skill_num, skill_lv);
+ casttime = skill_vfcastfix(src, casttime, skill_num, skill_lv);
#endif
- unit_stop_walking(src,1);// eventhough this is not how official works but this will do the trick. bugreport:6829
- // in official this is triggered even if no cast time.
- clif_skillcasting(src, src->id, target_id, 0,0, skill_num, skill_get_ele(skill_num, skill_lv), casttime);
- if (casttime > 0 || temp) {
- if (sd && target->type == BL_MOB) {
- TBL_MOB *md = (TBL_MOB *)target;
- mobskill_event(md, src, tick, -1); //Cast targetted skill event.
- if (tstatus->mode&(MD_CASTSENSOR_IDLE|MD_CASTSENSOR_CHASE) &&
- battle_check_target(target, src, BCT_ENEMY) > 0) {
- switch (md->state.skillstate) {
- case MSS_RUSH:
- case MSS_FOLLOW:
- if (!(tstatus->mode&MD_CASTSENSOR_CHASE))
- break;
- md->target_id = src->id;
- md->state.aggressive = (tstatus->mode&MD_ANGRY)?1:0;
- md->min_chase = md->db->range3;
- break;
- case MSS_IDLE:
- case MSS_WALK:
- if (!(tstatus->mode&MD_CASTSENSOR_IDLE))
- break;
- md->target_id = src->id;
- md->state.aggressive = (tstatus->mode&MD_ANGRY)?1:0;
- md->min_chase = md->db->range3;
- break;
- }
- }
- }
- }
-
- if (casttime <= 0)
- ud->state.skillcastcancel = 0;
-
- if (!sd || sd->skillitem != skill_num || skill_get_cast(skill_num,skill_lv))
- ud->canact_tick = tick + casttime + 100;
- if (sd) {
- switch (skill_num) {
- case CG_ARROWVULCAN:
- sd->canequip_tick = tick + casttime;
- break;
- }
- }
- ud->skilltarget = target_id;
- ud->skillx = 0;
- ud->skilly = 0;
- ud->skillid = skill_num;
- ud->skilllv = skill_lv;
-
- if (sc) {
- /**
- * why the if else chain: these 3 status do not stack, so its efficient that way.
- **/
- if (sc->data[SC_CLOAKING] && !(sc->data[SC_CLOAKING]->val4&4) && skill_num != AS_CLOAKING) {
- status_change_end(src, SC_CLOAKING, INVALID_TIMER);
- if (!src->prev) return 0; //Warped away!
- } else if (sc->data[SC_CLOAKINGEXCEED] && !(sc->data[SC_CLOAKINGEXCEED]->val4&4) && skill_num != GC_CLOAKINGEXCEED) {
- status_change_end(src,SC_CLOAKINGEXCEED, INVALID_TIMER);
- if (!src->prev) return 0;
- }
- }
-
-
- if (casttime > 0) {
- ud->skilltimer = add_timer(tick+casttime, skill_castend_id, src->id, 0);
- if (sd && (pc_checkskill(sd,SA_FREECAST) > 0 || skill_num == LG_EXEEDBREAK))
- status_calc_bl(&sd->bl, SCB_SPEED);
- } else
- skill_castend_id(ud->skilltimer,tick,src->id,0);
-
- return 1;
+ unit_stop_walking(src,1);// eventhough this is not how official works but this will do the trick. bugreport:6829
+ // in official this is triggered even if no cast time.
+ clif_skillcasting(src, src->id, target_id, 0,0, skill_num, skill_get_ele(skill_num, skill_lv), casttime);
+ if( casttime > 0 || temp )
+ {
+ if (sd && target->type == BL_MOB)
+ {
+ TBL_MOB *md = (TBL_MOB*)target;
+ mobskill_event(md, src, tick, -1); //Cast targetted skill event.
+ if (tstatus->mode&(MD_CASTSENSOR_IDLE|MD_CASTSENSOR_CHASE) &&
+ battle_check_target(target, src, BCT_ENEMY) > 0)
+ {
+ switch (md->state.skillstate) {
+ case MSS_RUSH:
+ case MSS_FOLLOW:
+ if (!(tstatus->mode&MD_CASTSENSOR_CHASE))
+ break;
+ md->target_id = src->id;
+ md->state.aggressive = (tstatus->mode&MD_ANGRY)?1:0;
+ md->min_chase = md->db->range3;
+ break;
+ case MSS_IDLE:
+ case MSS_WALK:
+ if (!(tstatus->mode&MD_CASTSENSOR_IDLE))
+ break;
+ md->target_id = src->id;
+ md->state.aggressive = (tstatus->mode&MD_ANGRY)?1:0;
+ md->min_chase = md->db->range3;
+ break;
+ }
+ }
+ }
+ }
+
+ if( casttime <= 0 )
+ ud->state.skillcastcancel = 0;
+
+ if( !sd || sd->skillitem != skill_num || skill_get_cast(skill_num,skill_lv) )
+ ud->canact_tick = tick + casttime + 100;
+ if( sd )
+ {
+ switch( skill_num )
+ {
+ case CG_ARROWVULCAN:
+ sd->canequip_tick = tick + casttime;
+ break;
+ }
+ }
+ ud->skilltarget = target_id;
+ ud->skillx = 0;
+ ud->skilly = 0;
+ ud->skillid = skill_num;
+ ud->skilllv = skill_lv;
+
+ if( sc ) {
+ /**
+ * why the if else chain: these 3 status do not stack, so its efficient that way.
+ **/
+ if( sc->data[SC_CLOAKING] && !(sc->data[SC_CLOAKING]->val4&4) && skill_num != AS_CLOAKING ) {
+ status_change_end(src, SC_CLOAKING, INVALID_TIMER);
+ if (!src->prev) return 0; //Warped away!
+ } else if( sc->data[SC_CLOAKINGEXCEED] && !(sc->data[SC_CLOAKINGEXCEED]->val4&4) && skill_num != GC_CLOAKINGEXCEED ) {
+ status_change_end(src,SC_CLOAKINGEXCEED, INVALID_TIMER);
+ if (!src->prev) return 0;
+ }
+ }
+
+
+ if( casttime > 0 )
+ {
+ ud->skilltimer = add_timer( tick+casttime, skill_castend_id, src->id, 0 );
+ if( sd && (pc_checkskill(sd,SA_FREECAST) > 0 || skill_num == LG_EXEEDBREAK) )
+ status_calc_bl(&sd->bl, SCB_SPEED);
+ }
+ else
+ skill_castend_id(ud->skilltimer,tick,src->id,0);
+
+ return 1;
}
int unit_skilluse_pos(struct block_list *src, short skill_x, short skill_y, short skill_num, short skill_lv)
{
- if (skill_num < 0)
- return 0;
- return unit_skilluse_pos2(
- src, skill_x, skill_y, skill_num, skill_lv,
- skill_castfix(src, skill_num, skill_lv),
- skill_get_castcancel(skill_num)
- );
+ if(skill_num < 0)
+ return 0;
+ return unit_skilluse_pos2(
+ src, skill_x, skill_y, skill_num, skill_lv,
+ skill_castfix(src, skill_num, skill_lv),
+ skill_get_castcancel(skill_num)
+ );
}
-int unit_skilluse_pos2(struct block_list *src, short skill_x, short skill_y, short skill_num, short skill_lv, int casttime, int castcancel)
+int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, short skill_num, short skill_lv, int casttime, int castcancel)
{
- struct map_session_data *sd = NULL;
- struct unit_data *ud = NULL;
- struct status_change *sc;
- struct block_list bl;
- unsigned int tick = gettick();
-
- nullpo_ret(src);
-
- if (!src->prev) return 0; // not on the map
- if (status_isdead(src)) return 0;
-
- sd = BL_CAST(BL_PC, src);
- ud = unit_bl2ud(src);
- if (ud == NULL) return 0;
-
- if (ud->skilltimer != INVALID_TIMER) //Normally not needed since clif.c checks for it, but at/char/script commands don't! [Skotlex]
- return 0;
-
- sc = status_get_sc(src);
- if (sc && !sc->count)
- sc = NULL;
-
- if (sd) {
- if (skillnotok(skill_num, sd) || !skill_check_condition_castbegin(sd, skill_num, skill_lv))
- return 0;
- /**
- * "WHY IS IT HEREE": pneuma cannot be cancelled past this point, the client displays the animation even,
- * if we cancel it from nodamage_id, so it has to be here for it to not display the animation.
- **/
- if (skill_num == AL_PNEUMA && map_getcell(src->m, skill_x, skill_y, CELL_CHKLANDPROTECTOR)) {
- clif_skill_fail(sd,skill_num,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- }
-
- if (!status_check_skilluse(src, NULL, skill_num, 0))
- return 0;
-
- if (map_getcell(src->m, skill_x, skill_y, CELL_CHKWALL)) {
- // can't cast ground targeted spells on wall cells
- if (sd) clif_skill_fail(sd,skill_num,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
+ struct map_session_data *sd = NULL;
+ struct unit_data *ud = NULL;
+ struct status_change *sc;
+ struct block_list bl;
+ unsigned int tick = gettick();
+
+ nullpo_ret(src);
+
+ if (!src->prev) return 0; // not on the map
+ if(status_isdead(src)) return 0;
+
+ sd = BL_CAST(BL_PC, src);
+ ud = unit_bl2ud(src);
+ if(ud == NULL) return 0;
+
+ if(ud->skilltimer != INVALID_TIMER) //Normally not needed since clif.c checks for it, but at/char/script commands don't! [Skotlex]
+ return 0;
+
+ sc = status_get_sc(src);
+ if (sc && !sc->count)
+ sc = NULL;
+
+ if( sd )
+ {
+ if( skillnotok(skill_num, sd) || !skill_check_condition_castbegin(sd, skill_num, skill_lv) )
+ return 0;
+ /**
+ * "WHY IS IT HEREE": pneuma cannot be cancelled past this point, the client displays the animation even,
+ * if we cancel it from nodamage_id, so it has to be here for it to not display the animation.
+ **/
+ if( skill_num == AL_PNEUMA && map_getcell(src->m, skill_x, skill_y, CELL_CHKLANDPROTECTOR) ) {
+ clif_skill_fail(sd,skill_num,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ }
+
+ if (!status_check_skilluse(src, NULL, skill_num, 0))
+ return 0;
+
+ if( map_getcell(src->m, skill_x, skill_y, CELL_CHKWALL) )
+ {// can't cast ground targeted spells on wall cells
+ if (sd) clif_skill_fail(sd,skill_num,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
/* Check range and obstacle */
- bl.type = BL_NUL;
- bl.m = src->m;
- bl.x = skill_x;
- bl.y = skill_y;
-
- if (skill_get_state(ud->skillid) == ST_MOVE_ENABLE) {
- if (!unit_can_reach_bl(src, &bl, skill_get_range2(src, skill_num,skill_lv) + 1, 1, NULL, NULL))
- return 0; //Walk-path check failed.
- } else if (!battle_check_range(src, &bl, skill_get_range2(src, skill_num,skill_lv) + 1))
- return 0; //Arrow-path check failed.
-
- unit_stop_attack(src);
-
- // moved here to prevent Suffragium from ending if skill fails
+ bl.type = BL_NUL;
+ bl.m = src->m;
+ bl.x = skill_x;
+ bl.y = skill_y;
+
+ if( skill_get_state(ud->skillid) == ST_MOVE_ENABLE )
+ {
+ if( !unit_can_reach_bl(src, &bl, skill_get_range2(src, skill_num,skill_lv) + 1, 1, NULL, NULL) )
+ return 0; //Walk-path check failed.
+ }
+ else if( !battle_check_range(src, &bl, skill_get_range2(src, skill_num,skill_lv) + 1) )
+ return 0; //Arrow-path check failed.
+
+ unit_stop_attack(src);
+
+ // moved here to prevent Suffragium from ending if skill fails
#ifndef RENEWAL_CAST
- if (!(skill_get_castnodex(skill_num, skill_lv)&2))
- casttime = skill_castfix_sc(src, casttime);
+ if (!(skill_get_castnodex(skill_num, skill_lv)&2))
+ casttime = skill_castfix_sc(src, casttime);
#else
- casttime = skill_vfcastfix(src, casttime, skill_num, skill_lv);
+ casttime = skill_vfcastfix(src, casttime, skill_num, skill_lv );
#endif
- ud->state.skillcastcancel = castcancel&&casttime>0?1:0;
- if (!sd || sd->skillitem != skill_num || skill_get_cast(skill_num,skill_lv))
- ud->canact_tick = tick + casttime + 100;
- // if( sd )
- // {
- // switch( skill_num )
- // {
- // case ????:
- // sd->canequip_tick = tick + casttime;
- // }
- // }
- ud->skillid = skill_num;
- ud->skilllv = skill_lv;
- ud->skillx = skill_x;
- ud->skilly = skill_y;
- ud->skilltarget = 0;
-
- if (sc) {
- /**
- * why the if else chain: these 3 status do not stack, so its efficient that way.
- **/
- if (sc->data[SC_CLOAKING] && !(sc->data[SC_CLOAKING]->val4&4)) {
- status_change_end(src, SC_CLOAKING, INVALID_TIMER);
- if (!src->prev) return 0; //Warped away!
- } else if (sc->data[SC_CLOAKINGEXCEED] && !(sc->data[SC_CLOAKINGEXCEED]->val4&4)) {
- status_change_end(src, SC_CLOAKINGEXCEED, INVALID_TIMER);
- if (!src->prev) return 0;
- }
- }
-
- unit_stop_walking(src,1);
- // in official this is triggered even if no cast time.
- clif_skillcasting(src, src->id, 0, skill_x, skill_y, skill_num, skill_get_ele(skill_num, skill_lv), casttime);
- if (casttime > 0) {
- ud->skilltimer = add_timer(tick+casttime, skill_castend_pos, src->id, 0);
- if ((sd && pc_checkskill(sd,SA_FREECAST) > 0) || skill_num == LG_EXEEDBREAK)
- status_calc_bl(&sd->bl, SCB_SPEED);
- } else {
- ud->skilltimer = INVALID_TIMER;
- skill_castend_pos(ud->skilltimer,tick,src->id,0);
- }
- return 1;
+ ud->state.skillcastcancel = castcancel&&casttime>0?1:0;
+ if( !sd || sd->skillitem != skill_num || skill_get_cast(skill_num,skill_lv) )
+ ud->canact_tick = tick + casttime + 100;
+// if( sd )
+// {
+// switch( skill_num )
+// {
+// case ????:
+// sd->canequip_tick = tick + casttime;
+// }
+// }
+ ud->skillid = skill_num;
+ ud->skilllv = skill_lv;
+ ud->skillx = skill_x;
+ ud->skilly = skill_y;
+ ud->skilltarget = 0;
+
+ if( sc ) {
+ /**
+ * why the if else chain: these 3 status do not stack, so its efficient that way.
+ **/
+ if (sc->data[SC_CLOAKING] && !(sc->data[SC_CLOAKING]->val4&4)) {
+ status_change_end(src, SC_CLOAKING, INVALID_TIMER);
+ if (!src->prev) return 0; //Warped away!
+ } else if (sc->data[SC_CLOAKINGEXCEED] && !(sc->data[SC_CLOAKINGEXCEED]->val4&4)) {
+ status_change_end(src, SC_CLOAKINGEXCEED, INVALID_TIMER);
+ if (!src->prev) return 0;
+ }
+ }
+
+ unit_stop_walking(src,1);
+ // in official this is triggered even if no cast time.
+ clif_skillcasting(src, src->id, 0, skill_x, skill_y, skill_num, skill_get_ele(skill_num, skill_lv), casttime);
+ if( casttime > 0 )
+ {
+ ud->skilltimer = add_timer( tick+casttime, skill_castend_pos, src->id, 0 );
+ if( (sd && pc_checkskill(sd,SA_FREECAST) > 0) || skill_num == LG_EXEEDBREAK)
+ status_calc_bl(&sd->bl, SCB_SPEED);
+ }
+ else
+ {
+ ud->skilltimer = INVALID_TIMER;
+ skill_castend_pos(ud->skilltimer,tick,src->id,0);
+ }
+ return 1;
}
/*========================================
* update a block's attack target
*----------------------------------------*/
-int unit_set_target(struct unit_data *ud, int target_id)
+int unit_set_target(struct unit_data* ud, int target_id)
{
- struct unit_data *ux;
- struct block_list *target;
+ struct unit_data * ux;
+ struct block_list* target;
- nullpo_ret(ud);
+ nullpo_ret(ud);
- if (ud->target != target_id) {
- if (ud->target && (target = map_id2bl(ud->target)) && (ux = unit_bl2ud(target)) && ux->target_count > 0)
- ux->target_count --;
- if (target_id && (target = map_id2bl(target_id)) && (ux = unit_bl2ud(target)))
- ux->target_count ++;
- }
+ if( ud->target != target_id ) {
+ if( ud->target && (target = map_id2bl(ud->target)) && (ux = unit_bl2ud(target)) && ux->target_count > 0 )
+ ux->target_count --;
+ if( target_id && (target = map_id2bl(target_id)) && (ux = unit_bl2ud(target)) )
+ ux->target_count ++;
+ }
- ud->target = target_id;
- return 0;
+ ud->target = target_id;
+ return 0;
}
int unit_stop_attack(struct block_list *bl)
{
- struct unit_data *ud = unit_bl2ud(bl);
- nullpo_ret(bl);
+ struct unit_data *ud = unit_bl2ud(bl);
+ nullpo_ret(bl);
- if (!ud || ud->attacktimer == INVALID_TIMER)
- return 0;
+ if(!ud || ud->attacktimer == INVALID_TIMER)
+ return 0;
- delete_timer(ud->attacktimer, unit_attack_timer);
- ud->attacktimer = INVALID_TIMER;
- unit_set_target(ud, 0);
- return 0;
+ delete_timer( ud->attacktimer, unit_attack_timer );
+ ud->attacktimer = INVALID_TIMER;
+ unit_set_target(ud, 0);
+ return 0;
}
//Means current target is unattackable. For now only unlocks mobs.
int unit_unattackable(struct block_list *bl)
{
- struct unit_data *ud = unit_bl2ud(bl);
- if (ud) {
- ud->state.attack_continue = 0;
- unit_set_target(ud, 0);
- }
-
- if (bl->type == BL_MOB)
- mob_unlocktarget((struct mob_data *)bl, gettick()) ;
- else if (bl->type == BL_PET)
- pet_unlocktarget((struct pet_data *)bl);
- return 0;
+ struct unit_data *ud = unit_bl2ud(bl);
+ if (ud) {
+ ud->state.attack_continue = 0;
+ unit_set_target(ud, 0);
+ }
+
+ if(bl->type == BL_MOB)
+ mob_unlocktarget((struct mob_data*)bl, gettick()) ;
+ else if(bl->type == BL_PET)
+ pet_unlocktarget((struct pet_data*)bl);
+ return 0;
}
/*==========================================
@@ -1484,87 +1527,87 @@ int unit_unattackable(struct block_list *bl)
*------------------------------------------*/
int unit_attack(struct block_list *src,int target_id,int continuous)
{
- struct block_list *target;
- struct unit_data *ud;
-
- nullpo_ret(ud = unit_bl2ud(src));
-
- target = map_id2bl(target_id);
- if (target==NULL || status_isdead(target)) {
- unit_unattackable(src);
- return 1;
- }
-
- if (src->type == BL_PC) {
- TBL_PC *sd = (TBL_PC *)src;
- if (target->type == BL_NPC) { // monster npcs [Valaris]
- npc_click(sd,(TBL_NPC *)target); // submitted by leinsirk10 [Celest]
- return 0;
- }
- if (pc_is90overweight(sd) || pc_isridingwug(sd)) { // overweight or mounted on warg - stop attacking
- unit_stop_attack(src);
- return 0;
- }
- }
- if (battle_check_target(src,target,BCT_ENEMY) <= 0 || !status_check_skilluse(src, target, 0, 0)) {
- unit_unattackable(src);
- return 1;
- }
- ud->state.attack_continue = continuous;
- unit_set_target(ud, target_id);
-
- if (continuous) //If you're to attack continously, set to auto-case character
- ud->chaserange = status_get_range(src);
-
- //Just change target/type. [Skotlex]
- if (ud->attacktimer != INVALID_TIMER)
- return 0;
-
- //Set Mob's ANGRY/BERSERK states.
- if (src->type == BL_MOB)
- ((TBL_MOB *)src)->state.skillstate = ((TBL_MOB *)src)->state.aggressive?MSS_ANGRY:MSS_BERSERK;
-
- if (DIFF_TICK(ud->attackabletime, gettick()) > 0)
- //Do attack next time it is possible. [Skotlex]
- ud->attacktimer=add_timer(ud->attackabletime,unit_attack_timer,src->id,0);
- else //Attack NOW.
- unit_attack_timer(INVALID_TIMER, gettick(), src->id, 0);
-
- return 0;
+ struct block_list *target;
+ struct unit_data *ud;
+
+ nullpo_ret(ud = unit_bl2ud(src));
+
+ target = map_id2bl(target_id);
+ if( target==NULL || status_isdead(target) ) {
+ unit_unattackable(src);
+ return 1;
+ }
+
+ if( src->type == BL_PC ) {
+ TBL_PC* sd = (TBL_PC*)src;
+ if( target->type == BL_NPC ) { // monster npcs [Valaris]
+ npc_click(sd,(TBL_NPC*)target); // submitted by leinsirk10 [Celest]
+ return 0;
+ }
+ if( pc_is90overweight(sd) || pc_isridingwug(sd) ) { // overweight or mounted on warg - stop attacking
+ unit_stop_attack(src);
+ return 0;
+ }
+ }
+ if( battle_check_target(src,target,BCT_ENEMY) <= 0 || !status_check_skilluse(src, target, 0, 0) ) {
+ unit_unattackable(src);
+ return 1;
+ }
+ ud->state.attack_continue = continuous;
+ unit_set_target(ud, target_id);
+
+ if (continuous) //If you're to attack continously, set to auto-case character
+ ud->chaserange = status_get_range(src);
+
+ //Just change target/type. [Skotlex]
+ if(ud->attacktimer != INVALID_TIMER)
+ return 0;
+
+ //Set Mob's ANGRY/BERSERK states.
+ if(src->type == BL_MOB)
+ ((TBL_MOB*)src)->state.skillstate = ((TBL_MOB*)src)->state.aggressive?MSS_ANGRY:MSS_BERSERK;
+
+ if(DIFF_TICK(ud->attackabletime, gettick()) > 0)
+ //Do attack next time it is possible. [Skotlex]
+ ud->attacktimer=add_timer(ud->attackabletime,unit_attack_timer,src->id,0);
+ else //Attack NOW.
+ unit_attack_timer(INVALID_TIMER, gettick(), src->id, 0);
+
+ return 0;
}
//Cancels an ongoing combo, resets attackable time and restarts the
//attack timer to resume attacking after amotion time. [Skotlex]
int unit_cancel_combo(struct block_list *bl)
{
- struct unit_data *ud;
+ struct unit_data *ud;
- if (!status_change_end(bl, SC_COMBO, INVALID_TIMER))
- return 0; //Combo wasn't active.
+ if (!status_change_end(bl, SC_COMBO, INVALID_TIMER))
+ return 0; //Combo wasn't active.
- ud = unit_bl2ud(bl);
- nullpo_ret(ud);
+ ud = unit_bl2ud(bl);
+ nullpo_ret(ud);
- ud->attackabletime = gettick() + status_get_amotion(bl);
+ ud->attackabletime = gettick() + status_get_amotion(bl);
- if (ud->attacktimer == INVALID_TIMER)
- return 1; //Nothing more to do.
+ if (ud->attacktimer == INVALID_TIMER)
+ return 1; //Nothing more to do.
- delete_timer(ud->attacktimer, unit_attack_timer);
- ud->attacktimer=add_timer(ud->attackabletime,unit_attack_timer,bl->id,0);
- return 1;
+ delete_timer(ud->attacktimer, unit_attack_timer);
+ ud->attacktimer=add_timer(ud->attackabletime,unit_attack_timer,bl->id,0);
+ return 1;
}
/*==========================================
*
*------------------------------------------*/
bool unit_can_reach_pos(struct block_list *bl,int x,int y, int easy)
{
- nullpo_retr(false, bl);
+ nullpo_retr(false, bl);
- if (bl->x == x && bl->y == y) //Same place
- return true;
+ if (bl->x == x && bl->y == y) //Same place
+ return true;
- return path_search(NULL,bl->m,bl->x,bl->y,x,y,easy,CELL_CHKNOREACH);
+ return path_search(NULL,bl->m,bl->x,bl->y,x,y,easy,CELL_CHKNOREACH);
}
/*==========================================
@@ -1572,230 +1615,234 @@ bool unit_can_reach_pos(struct block_list *bl,int x,int y, int easy)
*------------------------------------------*/
bool unit_can_reach_bl(struct block_list *bl,struct block_list *tbl, int range, int easy, short *x, short *y)
{
- int i;
- short dx,dy;
- nullpo_retr(false, bl);
- nullpo_retr(false, tbl);
-
- if (bl->m != tbl->m)
- return false;
-
- if (bl->x==tbl->x && bl->y==tbl->y)
- return true;
-
- if (range>0 && !check_distance_bl(bl, tbl, range))
- return false;
-
- // It judges whether it can adjoin or not.
- dx=tbl->x - bl->x;
- dy=tbl->y - bl->y;
- dx=(dx>0)?1:((dx<0)?-1:0);
- dy=(dy>0)?1:((dy<0)?-1:0);
-
- if (map_getcell(tbl->m,tbl->x-dx,tbl->y-dy,CELL_CHKNOPASS)) {
- //Look for a suitable cell to place in.
- for (i=0; i<9 && map_getcell(tbl->m,tbl->x-dirx[i],tbl->y-diry[i],CELL_CHKNOPASS); i++);
- if (i==9) return false; //No valid cells.
- dx = dirx[i];
- dy = diry[i];
- }
-
- if (x) *x = tbl->x-dx;
- if (y) *y = tbl->y-dy;
- return path_search(NULL,bl->m,bl->x,bl->y,tbl->x-dx,tbl->y-dy,easy,CELL_CHKNOREACH);
+ int i;
+ short dx,dy;
+ nullpo_retr(false, bl);
+ nullpo_retr(false, tbl);
+
+ if( bl->m != tbl->m)
+ return false;
+
+ if( bl->x==tbl->x && bl->y==tbl->y )
+ return true;
+
+ if(range>0 && !check_distance_bl(bl, tbl, range))
+ return false;
+
+ // It judges whether it can adjoin or not.
+ dx=tbl->x - bl->x;
+ dy=tbl->y - bl->y;
+ dx=(dx>0)?1:((dx<0)?-1:0);
+ dy=(dy>0)?1:((dy<0)?-1:0);
+
+ if (map_getcell(tbl->m,tbl->x-dx,tbl->y-dy,CELL_CHKNOPASS))
+ { //Look for a suitable cell to place in.
+ for(i=0;i<9 && map_getcell(tbl->m,tbl->x-dirx[i],tbl->y-diry[i],CELL_CHKNOPASS);i++);
+ if (i==9) return false; //No valid cells.
+ dx = dirx[i];
+ dy = diry[i];
+ }
+
+ if (x) *x = tbl->x-dx;
+ if (y) *y = tbl->y-dy;
+ return path_search(NULL,bl->m,bl->x,bl->y,tbl->x-dx,tbl->y-dy,easy,CELL_CHKNOREACH);
}
/*==========================================
* Calculates position of Pet/Mercenary/Homunculus/Elemental
*------------------------------------------*/
-int unit_calc_pos(struct block_list *bl, int tx, int ty, int dir)
+int unit_calc_pos(struct block_list *bl, int tx, int ty, int dir)
{
- int dx, dy, x, y, i, k;
- struct unit_data *ud = unit_bl2ud(bl);
- nullpo_ret(ud);
-
- if (dir < 0 || dir > 7)
- return 1;
-
- ud->to_x = tx;
- ud->to_y = ty;
-
- // 2 cells from Master Position
- dx = -dirx[dir] * 2;
- dy = -diry[dir] * 2;
- x = tx + dx;
- y = ty + dy;
-
- if (!unit_can_reach_pos(bl, x, y, 0)) {
- if (dx > 0) x--;
- else if (dx < 0) x++;
- if (dy > 0) y--;
- else if (dy < 0) y++;
- if (!unit_can_reach_pos(bl, x, y, 0)) {
- for (i = 0; i < 12; i++) {
- k = rnd()%8; // Pick a Random Dir
- dx = -dirx[k] * 2;
- dy = -diry[k] * 2;
- x = tx + dx;
- y = ty + dy;
- if (unit_can_reach_pos(bl, x, y, 0))
- break;
- else {
- if (dx > 0) x--;
- else if (dx < 0) x++;
- if (dy > 0) y--;
- else if (dy < 0) y++;
- if (unit_can_reach_pos(bl, x, y, 0))
- break;
- }
- }
- if (i == 12) {
- x = tx;
- y = tx; // Exactly Master Position
- if (!unit_can_reach_pos(bl, x, y, 0))
- return 1;
- }
- }
- }
- ud->to_x = x;
- ud->to_y = y;
-
- return 0;
+ int dx, dy, x, y, i, k;
+ struct unit_data *ud = unit_bl2ud(bl);
+ nullpo_ret(ud);
+
+ if( dir < 0 || dir > 7 )
+ return 1;
+
+ ud->to_x = tx;
+ ud->to_y = ty;
+
+ // 2 cells from Master Position
+ dx = -dirx[dir] * 2;
+ dy = -diry[dir] * 2;
+ x = tx + dx;
+ y = ty + dy;
+
+ if( !unit_can_reach_pos(bl, x, y, 0) )
+ {
+ if( dx > 0 ) x--; else if( dx < 0 ) x++;
+ if( dy > 0 ) y--; else if( dy < 0 ) y++;
+ if( !unit_can_reach_pos(bl, x, y, 0) )
+ {
+ for( i = 0; i < 12; i++ )
+ {
+ k = rnd()%8; // Pick a Random Dir
+ dx = -dirx[k] * 2;
+ dy = -diry[k] * 2;
+ x = tx + dx;
+ y = ty + dy;
+ if( unit_can_reach_pos(bl, x, y, 0) )
+ break;
+ else
+ {
+ if( dx > 0 ) x--; else if( dx < 0 ) x++;
+ if( dy > 0 ) y--; else if( dy < 0 ) y++;
+ if( unit_can_reach_pos(bl, x, y, 0) )
+ break;
+ }
+ }
+ if( i == 12 )
+ {
+ x = tx; y = tx; // Exactly Master Position
+ if( !unit_can_reach_pos(bl, x, y, 0) )
+ return 1;
+ }
+ }
+ }
+ ud->to_x = x;
+ ud->to_y = y;
+
+ return 0;
}
/*==========================================
* Continuous Attack (function timer)
*------------------------------------------*/
-static int unit_attack_timer_sub(struct block_list *src, int tid, unsigned int tick)
+static int unit_attack_timer_sub(struct block_list* src, int tid, unsigned int tick)
{
- struct block_list *target;
- struct unit_data *ud;
- struct status_data *sstatus;
- struct map_session_data *sd = NULL;
- struct mob_data *md = NULL;
- int range;
-
- if ((ud=unit_bl2ud(src))==NULL)
- return 0;
- if (ud->attacktimer != tid) {
- ShowError("unit_attack_timer %d != %d\n",ud->attacktimer,tid);
- return 0;
- }
-
- sd = BL_CAST(BL_PC, src);
- md = BL_CAST(BL_MOB, src);
- ud->attacktimer = INVALID_TIMER;
- target=map_id2bl(ud->target);
-
- if (src == NULL || src->prev == NULL || target==NULL || target->prev == NULL)
- return 0;
-
- if (status_isdead(src) || status_isdead(target) ||
- battle_check_target(src,target,BCT_ENEMY) <= 0 || !status_check_skilluse(src, target, 0, 0)
+ struct block_list *target;
+ struct unit_data *ud;
+ struct status_data *sstatus;
+ struct map_session_data *sd = NULL;
+ struct mob_data *md = NULL;
+ int range;
+
+ if( (ud=unit_bl2ud(src))==NULL )
+ return 0;
+ if( ud->attacktimer != tid )
+ {
+ ShowError("unit_attack_timer %d != %d\n",ud->attacktimer,tid);
+ return 0;
+ }
+
+ sd = BL_CAST(BL_PC, src);
+ md = BL_CAST(BL_MOB, src);
+ ud->attacktimer = INVALID_TIMER;
+ target=map_id2bl(ud->target);
+
+ if( src == NULL || src->prev == NULL || target==NULL || target->prev == NULL )
+ return 0;
+
+ if( status_isdead(src) || status_isdead(target) ||
+ battle_check_target(src,target,BCT_ENEMY) <= 0 || !status_check_skilluse(src, target, 0, 0)
#ifdef OFFICIAL_WALKPATH
- || !path_search_long(NULL, src->m, src->x, src->y, target->x, target->y, CELL_CHKWALL)
+ || !path_search_long(NULL, src->m, src->x, src->y, target->x, target->y, CELL_CHKWALL)
#endif
- )
- return 0; // can't attack under these conditions
-
- if (src->m != target->m) {
- if (src->type == BL_MOB && mob_warpchase((TBL_MOB *)src, target))
- return 1; // Follow up.
- return 0;
- }
-
- if (ud->skilltimer != INVALID_TIMER && !(sd && pc_checkskill(sd,SA_FREECAST) > 0))
- return 0; // can't attack while casting
-
- if (!battle_config.sdelay_attack_enable && DIFF_TICK(ud->canact_tick,tick) > 0 && !(sd && pc_checkskill(sd,SA_FREECAST) > 0)) {
- // attacking when under cast delay has restrictions:
- if (tid == INVALID_TIMER) {
- //requested attack.
- if (sd) clif_skill_fail(sd,1,USESKILL_FAIL_SKILLINTERVAL,0);
- return 0;
- }
- //Otherwise, we are in a combo-attack, delay this until your canact time is over. [Skotlex]
- if (ud->state.attack_continue) {
- if (DIFF_TICK(ud->canact_tick, ud->attackabletime) > 0)
- ud->attackabletime = ud->canact_tick;
- ud->attacktimer=add_timer(ud->attackabletime,unit_attack_timer,src->id,0);
- }
- return 1;
- }
-
- sstatus = status_get_status_data(src);
- range = sstatus->rhw.range + 1;
-
- if (unit_is_walking(target))
- range++; //Extra range when chasing
- if (!check_distance_bl(src,target,range)) { //Chase if required.
- if (sd)
- clif_movetoattack(sd,target);
- else if (ud->state.attack_continue)
- unit_walktobl(src,target,ud->chaserange,ud->state.walk_easy|2);
- return 1;
- }
- if (!battle_check_range(src,target,range)) {
- //Within range, but no direct line of attack
- if (ud->state.attack_continue) {
- if (ud->chaserange > 2) ud->chaserange-=2;
- unit_walktobl(src,target,ud->chaserange,ud->state.walk_easy|2);
- }
- return 1;
- }
- //Sync packet only for players.
- //Non-players use the sync packet on the walk timer. [Skotlex]
- if (tid == INVALID_TIMER && sd) clif_fixpos(src);
-
- if (DIFF_TICK(ud->attackabletime,tick) <= 0) {
- if (battle_config.attack_direction_change && (src->type&battle_config.attack_direction_change)) {
- ud->dir = map_calc_dir(src, target->x,target->y);
- }
- if (ud->walktimer != INVALID_TIMER)
- unit_stop_walking(src,1);
- if (md) {
- if (mobskill_use(md,tick,-1))
- return 1;
- if (sstatus->mode&MD_ASSIST && DIFF_TICK(md->last_linktime, tick) < MIN_MOBLINKTIME) {
- // Link monsters nearby [Skotlex]
- md->last_linktime = tick;
- map_foreachinrange(mob_linksearch, src, md->db->range2, BL_MOB, md->class_, target, tick);
- }
- }
- if (src->type == BL_PET && pet_attackskill((TBL_PET *)src, target->id))
- return 1;
-
- map_freeblock_lock();
- ud->attacktarget_lv = battle_weapon_attack(src,target,tick,0);
-
- if (sd && sd->status.pet_id > 0 && sd->pd && battle_config.pet_attack_support)
- pet_target_check(sd,target,0);
- map_freeblock_unlock();
- /**
- * Applied when you're unable to attack (e.g. out of ammo)
- * We should stop here otherwise timer keeps on and this happens endlessly
- **/
- if (ud->attacktarget_lv == ATK_NONE)
- return 1;
-
- ud->attackabletime = tick + sstatus->adelay;
- // You can't move if you can't attack neither.
- if (src->type&battle_config.attack_walk_delay)
- unit_set_walkdelay(src, tick, sstatus->amotion, 1);
- }
-
- if (ud->state.attack_continue)
- ud->attacktimer = add_timer(ud->attackabletime,unit_attack_timer,src->id,0);
-
- return 1;
+ )
+ return 0; // can't attack under these conditions
+
+ if( src->m != target->m )
+ {
+ if( src->type == BL_MOB && mob_warpchase((TBL_MOB*)src, target) )
+ return 1; // Follow up.
+ return 0;
+ }
+
+ if( ud->skilltimer != INVALID_TIMER && !(sd && pc_checkskill(sd,SA_FREECAST) > 0) )
+ return 0; // can't attack while casting
+
+ if( !battle_config.sdelay_attack_enable && DIFF_TICK(ud->canact_tick,tick) > 0 && !(sd && pc_checkskill(sd,SA_FREECAST) > 0) )
+ { // attacking when under cast delay has restrictions:
+ if( tid == INVALID_TIMER )
+ { //requested attack.
+ if(sd) clif_skill_fail(sd,1,USESKILL_FAIL_SKILLINTERVAL,0);
+ return 0;
+ }
+ //Otherwise, we are in a combo-attack, delay this until your canact time is over. [Skotlex]
+ if( ud->state.attack_continue )
+ {
+ if( DIFF_TICK(ud->canact_tick, ud->attackabletime) > 0 )
+ ud->attackabletime = ud->canact_tick;
+ ud->attacktimer=add_timer(ud->attackabletime,unit_attack_timer,src->id,0);
+ }
+ return 1;
+ }
+
+ sstatus = status_get_status_data(src);
+ range = sstatus->rhw.range + 1;
+
+ if( unit_is_walking(target) )
+ range++; //Extra range when chasing
+ if( !check_distance_bl(src,target,range) ) { //Chase if required.
+ if(sd)
+ clif_movetoattack(sd,target);
+ else if(ud->state.attack_continue)
+ unit_walktobl(src,target,ud->chaserange,ud->state.walk_easy|2);
+ return 1;
+ }
+ if( !battle_check_range(src,target,range) ) {
+ //Within range, but no direct line of attack
+ if( ud->state.attack_continue ) {
+ if(ud->chaserange > 2) ud->chaserange-=2;
+ unit_walktobl(src,target,ud->chaserange,ud->state.walk_easy|2);
+ }
+ return 1;
+ }
+ //Sync packet only for players.
+ //Non-players use the sync packet on the walk timer. [Skotlex]
+ if (tid == INVALID_TIMER && sd) clif_fixpos(src);
+
+ if( DIFF_TICK(ud->attackabletime,tick) <= 0 )
+ {
+ if (battle_config.attack_direction_change && (src->type&battle_config.attack_direction_change)) {
+ ud->dir = map_calc_dir(src, target->x,target->y );
+ }
+ if(ud->walktimer != INVALID_TIMER)
+ unit_stop_walking(src,1);
+ if(md) {
+ if (mobskill_use(md,tick,-1))
+ return 1;
+ if (sstatus->mode&MD_ASSIST && DIFF_TICK(md->last_linktime, tick) < MIN_MOBLINKTIME)
+ { // Link monsters nearby [Skotlex]
+ md->last_linktime = tick;
+ map_foreachinrange(mob_linksearch, src, md->db->range2, BL_MOB, md->class_, target, tick);
+ }
+ }
+ if(src->type == BL_PET && pet_attackskill((TBL_PET*)src, target->id))
+ return 1;
+
+ map_freeblock_lock();
+ ud->attacktarget_lv = battle_weapon_attack(src,target,tick,0);
+
+ if(sd && sd->status.pet_id > 0 && sd->pd && battle_config.pet_attack_support)
+ pet_target_check(sd,target,0);
+ map_freeblock_unlock();
+ /**
+ * Applied when you're unable to attack (e.g. out of ammo)
+ * We should stop here otherwise timer keeps on and this happens endlessly
+ **/
+ if( ud->attacktarget_lv == ATK_NONE )
+ return 1;
+
+ ud->attackabletime = tick + sstatus->adelay;
+// You can't move if you can't attack neither.
+ if (src->type&battle_config.attack_walk_delay)
+ unit_set_walkdelay(src, tick, sstatus->amotion, 1);
+ }
+
+ if(ud->state.attack_continue)
+ ud->attacktimer = add_timer(ud->attackabletime,unit_attack_timer,src->id,0);
+
+ return 1;
}
static int unit_attack_timer(int tid, unsigned int tick, int id, intptr_t data)
{
- struct block_list *bl;
- bl = map_id2bl(id);
- if (bl && unit_attack_timer_sub(bl, tid, tick) == 0)
- unit_unattackable(bl);
- return 0;
+ struct block_list *bl;
+ bl = map_id2bl(id);
+ if(bl && unit_attack_timer_sub(bl, tid, tick) == 0)
+ unit_unattackable(bl);
+ return 0;
}
/*==========================================
@@ -1805,85 +1852,87 @@ static int unit_attack_timer(int tid, unsigned int tick, int id, intptr_t data)
*------------------------------------------*/
int unit_skillcastcancel(struct block_list *bl,int type)
{
- struct map_session_data *sd = NULL;
- struct unit_data *ud = unit_bl2ud(bl);
- unsigned int tick=gettick();
- int ret=0, skill;
-
- nullpo_ret(bl);
- if (!ud || ud->skilltimer == INVALID_TIMER)
- return 0; //Nothing to cancel.
-
- sd = BL_CAST(BL_PC, bl);
-
- if (type&2) {
- //See if it can be cancelled.
- if (!ud->state.skillcastcancel)
- return 0;
-
- if (sd && (sd->special_state.no_castcancel2 ||
- ((sd->sc.data[SC_UNLIMITEDHUMMINGVOICE] || sd->special_state.no_castcancel) && !map_flag_gvg(bl->m) && !map[bl->m].flag.battleground))) //fixed flags being read the wrong way around [blackhole89]
- return 0;
- }
-
- ud->canact_tick = tick;
-
- if (type&1 && sd)
- skill = sd->skillid_old;
- else
- skill = ud->skillid;
-
- if (skill_get_inf(skill) & INF_GROUND_SKILL)
- ret=delete_timer(ud->skilltimer, skill_castend_pos);
- else
- ret=delete_timer(ud->skilltimer, skill_castend_id);
- if (ret<0)
- ShowError("delete timer error : skillid : %d\n",ret);
-
- ud->skilltimer = INVALID_TIMER;
-
- if (sd && pc_checkskill(sd,SA_FREECAST) > 0)
- status_calc_bl(&sd->bl, SCB_SPEED);
-
- if (sd) {
- switch (skill) {
- case CG_ARROWVULCAN:
- sd->canequip_tick = tick;
- break;
- }
- }
-
- if (bl->type==BL_MOB)((TBL_MOB *)bl)->skillidx = -1;
-
- clif_skillcastcancel(bl);
- return 1;
+ struct map_session_data *sd = NULL;
+ struct unit_data *ud = unit_bl2ud( bl);
+ unsigned int tick=gettick();
+ int ret=0, skill;
+
+ nullpo_ret(bl);
+ if (!ud || ud->skilltimer == INVALID_TIMER)
+ return 0; //Nothing to cancel.
+
+ sd = BL_CAST(BL_PC, bl);
+
+ if (type&2) {
+ //See if it can be cancelled.
+ if (!ud->state.skillcastcancel)
+ return 0;
+
+ if (sd && (sd->special_state.no_castcancel2 ||
+ ((sd->sc.data[SC_UNLIMITEDHUMMINGVOICE] || sd->special_state.no_castcancel) && !map_flag_gvg(bl->m) && !map[bl->m].flag.battleground))) //fixed flags being read the wrong way around [blackhole89]
+ return 0;
+ }
+
+ ud->canact_tick = tick;
+
+ if(type&1 && sd)
+ skill = sd->skillid_old;
+ else
+ skill = ud->skillid;
+
+ if (skill_get_inf(skill) & INF_GROUND_SKILL)
+ ret=delete_timer( ud->skilltimer, skill_castend_pos );
+ else
+ ret=delete_timer( ud->skilltimer, skill_castend_id );
+ if(ret<0)
+ ShowError("delete timer error : skillid : %d\n",ret);
+
+ ud->skilltimer = INVALID_TIMER;
+
+ if( sd && pc_checkskill(sd,SA_FREECAST) > 0 )
+ status_calc_bl(&sd->bl, SCB_SPEED);
+
+ if( sd )
+ {
+ switch( skill )
+ {
+ case CG_ARROWVULCAN:
+ sd->canequip_tick = tick;
+ break;
+ }
+ }
+
+ if(bl->type==BL_MOB) ((TBL_MOB*)bl)->skillidx = -1;
+
+ clif_skillcastcancel(bl);
+ return 1;
}
// unit_data initialization process
void unit_dataset(struct block_list *bl)
{
- struct unit_data *ud;
- nullpo_retv(ud = unit_bl2ud(bl));
-
- memset(ud, 0, sizeof(struct unit_data));
- ud->bl = bl;
- ud->walktimer = INVALID_TIMER;
- ud->skilltimer = INVALID_TIMER;
- ud->attacktimer = INVALID_TIMER;
- ud->attackabletime =
- ud->canact_tick =
- ud->canmove_tick = gettick();
+ struct unit_data *ud;
+ nullpo_retv(ud = unit_bl2ud(bl));
+
+ memset( ud, 0, sizeof( struct unit_data) );
+ ud->bl = bl;
+ ud->walktimer = INVALID_TIMER;
+ ud->skilltimer = INVALID_TIMER;
+ ud->attacktimer = INVALID_TIMER;
+ ud->attackabletime =
+ ud->canact_tick =
+ ud->canmove_tick = gettick();
}
/*==========================================
* Counts the number of units attacking 'bl'
*------------------------------------------*/
-int unit_counttargeted(struct block_list *bl)
+int unit_counttargeted(struct block_list* bl)
{
- struct unit_data *ud;
- if (bl && (ud = unit_bl2ud(bl)))
- return ud->target_count;
- return 0;
+ struct unit_data* ud;
+ if( bl && (ud = unit_bl2ud(bl)) )
+ return ud->target_count;
+ return 0;
}
/*==========================================
@@ -1891,12 +1940,12 @@ int unit_counttargeted(struct block_list *bl)
*------------------------------------------*/
int unit_fixdamage(struct block_list *src,struct block_list *target,unsigned int tick,int sdelay,int ddelay,int damage,int div,int type,int damage2)
{
- nullpo_ret(target);
+ nullpo_ret(target);
- if (damage+damage2 <= 0)
- return 0;
+ if(damage+damage2 <= 0)
+ return 0;
- return status_fix_damage(src,target,damage+damage2,clif_damage(target,target,tick,sdelay,ddelay,damage,div,type,damage2));
+ return status_fix_damage(src,target,damage+damage2,clif_damage(target,target,tick,sdelay,ddelay,damage,div,type,damage2));
}
/*==========================================
@@ -1904,19 +1953,19 @@ int unit_fixdamage(struct block_list *src,struct block_list *target,unsigned int
*------------------------------------------*/
int unit_changeviewsize(struct block_list *bl,short size)
{
- nullpo_ret(bl);
-
- size=(size<0)?-1:(size>0)?1:0;
-
- if (bl->type == BL_PC) {
- ((TBL_PC *)bl)->state.size=size;
- } else if (bl->type == BL_MOB) {
- ((TBL_MOB *)bl)->special_state.size=size;
- } else
- return 0;
- if (size!=0)
- clif_specialeffect(bl,421+size, AREA);
- return 0;
+ nullpo_ret(bl);
+
+ size=(size<0)?-1:(size>0)?1:0;
+
+ if(bl->type == BL_PC) {
+ ((TBL_PC*)bl)->state.size=size;
+ } else if(bl->type == BL_MOB) {
+ ((TBL_MOB*)bl)->special_state.size=size;
+ } else
+ return 0;
+ if(size!=0)
+ clif_specialeffect(bl,421+size, AREA);
+ return 0;
}
/*==========================================
@@ -1926,249 +1975,256 @@ int unit_changeviewsize(struct block_list *bl,short size)
* Otherwise it is assumed bl is being warped.
* On-Kill specific stuff is not performed here, look at status_damage for that.
*------------------------------------------*/
-int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char *file, int line, const char *func)
+int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file, int line, const char* func)
{
- struct unit_data *ud = unit_bl2ud(bl);
- struct status_change *sc = status_get_sc(bl);
- nullpo_ret(ud);
-
- if (bl->prev == NULL)
- return 0; //Already removed?
-
- map_freeblock_lock();
-
- unit_set_target(ud, 0);
-
- if (ud->walktimer != INVALID_TIMER)
- unit_stop_walking(bl,0);
- if (ud->attacktimer != INVALID_TIMER)
- unit_stop_attack(bl);
- if (ud->skilltimer != INVALID_TIMER)
- unit_skillcastcancel(bl,0);
-
- // Do not reset can-act delay. [Skotlex]
- ud->attackabletime = ud->canmove_tick /*= ud->canact_tick*/ = gettick();
- if (sc && sc->count) { //map-change/warp dispells.
- status_change_end(bl, SC_BLADESTOP, INVALID_TIMER);
- status_change_end(bl, SC_BASILICA, INVALID_TIMER);
- status_change_end(bl, SC_ANKLE, INVALID_TIMER);
- status_change_end(bl, SC_TRICKDEAD, INVALID_TIMER);
- status_change_end(bl, SC_BLADESTOP_WAIT, INVALID_TIMER);
- status_change_end(bl, SC_RUN, INVALID_TIMER);
- status_change_end(bl, SC_DANCING, INVALID_TIMER);
- status_change_end(bl, SC_WARM, INVALID_TIMER);
- status_change_end(bl, SC_DEVOTION, INVALID_TIMER);
- status_change_end(bl, SC_MARIONETTE, INVALID_TIMER);
- status_change_end(bl, SC_MARIONETTE2, INVALID_TIMER);
- status_change_end(bl, SC_CLOSECONFINE, INVALID_TIMER);
- status_change_end(bl, SC_CLOSECONFINE2, INVALID_TIMER);
- status_change_end(bl, SC_HIDING, INVALID_TIMER);
- // Ensure the bl is a PC; if so, we'll handle the removal of cloaking and cloaking exceed later
- if (bl->type != BL_PC) {
- status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
- status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
- }
- status_change_end(bl, SC_CHASEWALK, INVALID_TIMER);
- if (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF)
- status_change_end(bl, SC_GOSPEL, INVALID_TIMER);
- status_change_end(bl, SC_CHANGE, INVALID_TIMER);
- status_change_end(bl, SC_STOP, INVALID_TIMER);
- status_change_end(bl, SC_WUGDASH, INVALID_TIMER);
- status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER);
- status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
- status_change_end(bl, SC__MANHOLE, INVALID_TIMER);
- status_change_end(bl, SC_VACUUM_EXTREME, INVALID_TIMER);
- status_change_end(bl, SC_CURSEDCIRCLE_ATKER, INVALID_TIMER); //callme before warp
- }
-
- if (bl->type&(BL_CHAR|BL_PET)) {
- skill_unit_move(bl,gettick(),4);
- skill_cleartimerskill(bl);
- }
-
- switch (bl->type) {
- case BL_PC: {
- struct map_session_data *sd = (struct map_session_data *)bl;
-
- //Leave/reject all invitations.
- if (sd->chatID)
- chat_leavechat(sd,0);
- if (sd->trade_partner)
- trade_tradecancel(sd);
- buyingstore_close(sd);
- searchstore_close(sd);
- if (sd->state.storage_flag == 1)
- storage_storage_quit(sd,0);
- else if (sd->state.storage_flag == 2)
- storage_guild_storage_quit(sd,0);
- sd->state.storage_flag = 0; //Force close it when being warped.
- if (sd->party_invite>0)
- party_reply_invite(sd,sd->party_invite,0);
- if (sd->guild_invite>0)
- guild_reply_invite(sd,sd->guild_invite,0);
- if (sd->guild_alliance>0)
- guild_reply_reqalliance(sd,sd->guild_alliance_account,0);
- if (sd->menuskill_id)
- sd->menuskill_id = sd->menuskill_val = 0;
- if (sd->touching_id && !sd->state.warping) // Only if the player isn't warping and there is a touching_id.
- npc_touchnext_areanpc(sd,true);
-
- // Check if warping and not changing the map.
- if (sd->state.warping && !sd->state.changemap) {
- status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
- status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
- }
-
- sd->npc_shopid = 0;
- sd->adopt_invite = 0;
-
- if (sd->pvp_timer != INVALID_TIMER) {
- delete_timer(sd->pvp_timer,pc_calc_pvprank_timer);
- sd->pvp_timer = INVALID_TIMER;
- sd->pvp_rank = 0;
- }
- if (sd->duel_group > 0)
- duel_leave(sd->duel_group, sd);
-
- if (pc_issit(sd)) {
- pc_setstand(sd);
- skill_sit(sd,0);
- }
- party_send_dot_remove(sd);//minimap dot fix [Kevin]
- guild_send_dot_remove(sd);
- bg_send_dot_remove(sd);
-
- if (map[bl->m].users <= 0 || sd->state.debug_remove_map) {
- // this is only place where map users is decreased, if the mobs were removed too soon then this function was executed too many times [FlavioJS]
- if (sd->debug_file == NULL || !(sd->state.debug_remove_map)) {
- sd->debug_file = "";
- sd->debug_line = 0;
- sd->debug_func = "";
- }
- ShowDebug("unit_remove_map: unexpected state when removing player AID/CID:%d/%d"
- " (active=%d connect_new=%d rewarp=%d changemap=%d debug_remove_map=%d)"
- " from map=%s (users=%d)."
- " Previous call from %s:%d(%s), current call from %s:%d(%s)."
- " Please report this!!!\n",
- sd->status.account_id, sd->status.char_id,
- sd->state.active, sd->state.connect_new, sd->state.rewarp, sd->state.changemap, sd->state.debug_remove_map,
- map[bl->m].name, map[bl->m].users,
- sd->debug_file, sd->debug_line, sd->debug_func, file, line, func);
- } else if (--map[bl->m].users == 0 && battle_config.dynamic_mobs) //[Skotlex]
- map_removemobs(bl->m);
- if (!(sd->sc.option&OPTION_INVISIBLE)) {
- // decrement the number of active pvp players on the map
- --map[bl->m].users_pvp;
- }
- if (map[bl->m].instance_id) {
- instance[map[bl->m].instance_id].users--;
- instance_check_idle(map[bl->m].instance_id);
- }
- sd->state.debug_remove_map = 1; // temporary state to track double remove_map's [FlavioJS]
- sd->debug_file = file;
- sd->debug_line = line;
- sd->debug_func = func;
-
- break;
- }
- case BL_MOB: {
- struct mob_data *md = (struct mob_data *)bl;
- // Drop previous target mob_slave_keep_target: no.
- if (!battle_config.mob_slave_keep_target)
- md->target_id=0;
-
- md->attacked_id=0;
- md->state.skillstate= MSS_IDLE;
-
- break;
- }
- case BL_PET: {
- struct pet_data *pd = (struct pet_data *)bl;
- if (pd->pet.intimate <= 0 && !(pd->msd && !pd->msd->state.active)) {
- //If logging out, this is deleted on unit_free
- clif_clearunit_area(bl,clrtype);
- map_delblock(bl);
- unit_free(bl,CLR_OUTSIGHT);
- map_freeblock_unlock();
- return 0;
- }
-
- break;
- }
- case BL_HOM: {
- struct homun_data *hd = (struct homun_data *)bl;
- ud->canact_tick = ud->canmove_tick; //It appears HOM do reset the can-act tick.
- if (!hd->homunculus.intimacy && !(hd->master && !hd->master->state.active)) {
- //If logging out, this is deleted on unit_free
- clif_emotion(bl, E_SOB);
- clif_clearunit_area(bl,clrtype);
- map_delblock(bl);
- unit_free(bl,CLR_OUTSIGHT);
- map_freeblock_unlock();
- return 0;
- }
- break;
- }
- case BL_MER: {
- struct mercenary_data *md = (struct mercenary_data *)bl;
- ud->canact_tick = ud->canmove_tick;
- if (mercenary_get_lifetime(md) <= 0 && !(md->master && !md->master->state.active)) {
- clif_clearunit_area(bl,clrtype);
- map_delblock(bl);
- unit_free(bl,CLR_OUTSIGHT);
- map_freeblock_unlock();
- return 0;
- }
- break;
- }
- case BL_ELEM: {
- struct elemental_data *ed = (struct elemental_data *)bl;
- ud->canact_tick = ud->canmove_tick;
- if (elemental_get_lifetime(ed) <= 0 && !(ed->master && !ed->master->state.active)) {
- clif_clearunit_area(bl,clrtype);
- map_delblock(bl);
- unit_free(bl,0);
- map_freeblock_unlock();
- return 0;
- }
- break;
- }
- default:
- break;// do nothing
- }
- /**
- * BL_MOB is handled by mob_dead unless the monster is not dead.
- **/
- if (bl->type != BL_MOB || !status_isdead(bl))
- clif_clearunit_area(bl,clrtype);
- map_delblock(bl);
- map_freeblock_unlock();
- return 1;
+ struct unit_data *ud = unit_bl2ud(bl);
+ struct status_change *sc = status_get_sc(bl);
+ nullpo_ret(ud);
+
+ if(bl->prev == NULL)
+ return 0; //Already removed?
+
+ map_freeblock_lock();
+
+ unit_set_target(ud, 0);
+
+ if (ud->walktimer != INVALID_TIMER)
+ unit_stop_walking(bl,0);
+ if (ud->attacktimer != INVALID_TIMER)
+ unit_stop_attack(bl);
+ if (ud->skilltimer != INVALID_TIMER)
+ unit_skillcastcancel(bl,0);
+
+// Do not reset can-act delay. [Skotlex]
+ ud->attackabletime = ud->canmove_tick /*= ud->canact_tick*/ = gettick();
+ if(sc && sc->count ) { //map-change/warp dispells.
+ status_change_end(bl, SC_BLADESTOP, INVALID_TIMER);
+ status_change_end(bl, SC_BASILICA, INVALID_TIMER);
+ status_change_end(bl, SC_ANKLE, INVALID_TIMER);
+ status_change_end(bl, SC_TRICKDEAD, INVALID_TIMER);
+ status_change_end(bl, SC_BLADESTOP_WAIT, INVALID_TIMER);
+ status_change_end(bl, SC_RUN, INVALID_TIMER);
+ status_change_end(bl, SC_DANCING, INVALID_TIMER);
+ status_change_end(bl, SC_WARM, INVALID_TIMER);
+ status_change_end(bl, SC_DEVOTION, INVALID_TIMER);
+ status_change_end(bl, SC_MARIONETTE, INVALID_TIMER);
+ status_change_end(bl, SC_MARIONETTE2, INVALID_TIMER);
+ status_change_end(bl, SC_CLOSECONFINE, INVALID_TIMER);
+ status_change_end(bl, SC_CLOSECONFINE2, INVALID_TIMER);
+ status_change_end(bl, SC_HIDING, INVALID_TIMER);
+ // Ensure the bl is a PC; if so, we'll handle the removal of cloaking and cloaking exceed later
+ if ( bl->type != BL_PC )
+ {
+ status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
+ status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
+ }
+ status_change_end(bl, SC_CHASEWALK, INVALID_TIMER);
+ if (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF)
+ status_change_end(bl, SC_GOSPEL, INVALID_TIMER);
+ status_change_end(bl, SC_CHANGE, INVALID_TIMER);
+ status_change_end(bl, SC_STOP, INVALID_TIMER);
+ status_change_end(bl, SC_WUGDASH, INVALID_TIMER);
+ status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER);
+ status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
+ status_change_end(bl, SC__MANHOLE, INVALID_TIMER);
+ status_change_end(bl, SC_VACUUM_EXTREME, INVALID_TIMER);
+ status_change_end(bl, SC_CURSEDCIRCLE_ATKER, INVALID_TIMER); //callme before warp
+ }
+
+ if (bl->type&(BL_CHAR|BL_PET)) {
+ skill_unit_move(bl,gettick(),4);
+ skill_cleartimerskill(bl);
+ }
+
+ switch( bl->type ) {
+ case BL_PC: {
+ struct map_session_data *sd = (struct map_session_data*)bl;
+
+ //Leave/reject all invitations.
+ if(sd->chatID)
+ chat_leavechat(sd,0);
+ if(sd->trade_partner)
+ trade_tradecancel(sd);
+ buyingstore_close(sd);
+ searchstore_close(sd);
+ if(sd->state.storage_flag == 1)
+ storage_storage_quit(sd,0);
+ else if (sd->state.storage_flag == 2)
+ storage_guild_storage_quit(sd,0);
+ sd->state.storage_flag = 0; //Force close it when being warped.
+ if(sd->party_invite>0)
+ party_reply_invite(sd,sd->party_invite,0);
+ if(sd->guild_invite>0)
+ guild_reply_invite(sd,sd->guild_invite,0);
+ if(sd->guild_alliance>0)
+ guild_reply_reqalliance(sd,sd->guild_alliance_account,0);
+ if(sd->menuskill_id)
+ sd->menuskill_id = sd->menuskill_val = 0;
+ if( sd->touching_id && !sd->state.warping ) // Only if the player isn't warping and there is a touching_id.
+ npc_touchnext_areanpc(sd,true);
+
+ // Check if warping and not changing the map.
+ if ( sd->state.warping && !sd->state.changemap )
+ {
+ status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
+ status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
+ }
+
+ sd->npc_shopid = 0;
+ sd->adopt_invite = 0;
+
+ if(sd->pvp_timer != INVALID_TIMER) {
+ delete_timer(sd->pvp_timer,pc_calc_pvprank_timer);
+ sd->pvp_timer = INVALID_TIMER;
+ sd->pvp_rank = 0;
+ }
+ if(sd->duel_group > 0)
+ duel_leave(sd->duel_group, sd);
+
+ if(pc_issit(sd)) {
+ pc_setstand(sd);
+ skill_sit(sd,0);
+ }
+ party_send_dot_remove(sd);//minimap dot fix [Kevin]
+ guild_send_dot_remove(sd);
+ bg_send_dot_remove(sd);
+
+ if( map[bl->m].users <= 0 || sd->state.debug_remove_map )
+ {// this is only place where map users is decreased, if the mobs were removed too soon then this function was executed too many times [FlavioJS]
+ if( sd->debug_file == NULL || !(sd->state.debug_remove_map) )
+ {
+ sd->debug_file = "";
+ sd->debug_line = 0;
+ sd->debug_func = "";
+ }
+ ShowDebug("unit_remove_map: unexpected state when removing player AID/CID:%d/%d"
+ " (active=%d connect_new=%d rewarp=%d changemap=%d debug_remove_map=%d)"
+ " from map=%s (users=%d)."
+ " Previous call from %s:%d(%s), current call from %s:%d(%s)."
+ " Please report this!!!\n",
+ sd->status.account_id, sd->status.char_id,
+ sd->state.active, sd->state.connect_new, sd->state.rewarp, sd->state.changemap, sd->state.debug_remove_map,
+ map[bl->m].name, map[bl->m].users,
+ sd->debug_file, sd->debug_line, sd->debug_func, file, line, func);
+ }
+ else
+ if (--map[bl->m].users == 0 && battle_config.dynamic_mobs) //[Skotlex]
+ map_removemobs(bl->m);
+ if( !(sd->sc.option&OPTION_INVISIBLE) )
+ {// decrement the number of active pvp players on the map
+ --map[bl->m].users_pvp;
+ }
+ if( map[bl->m].instance_id )
+ {
+ instance[map[bl->m].instance_id].users--;
+ instance_check_idle(map[bl->m].instance_id);
+ }
+ sd->state.debug_remove_map = 1; // temporary state to track double remove_map's [FlavioJS]
+ sd->debug_file = file;
+ sd->debug_line = line;
+ sd->debug_func = func;
+
+ break;
+ }
+ case BL_MOB: {
+ struct mob_data *md = (struct mob_data*)bl;
+ // Drop previous target mob_slave_keep_target: no.
+ if (!battle_config.mob_slave_keep_target)
+ md->target_id=0;
+
+ md->attacked_id=0;
+ md->state.skillstate= MSS_IDLE;
+
+ break;
+ }
+ case BL_PET: {
+ struct pet_data *pd = (struct pet_data*)bl;
+ if( pd->pet.intimate <= 0 && !(pd->msd && !pd->msd->state.active) )
+ { //If logging out, this is deleted on unit_free
+ clif_clearunit_area(bl,clrtype);
+ map_delblock(bl);
+ unit_free(bl,CLR_OUTSIGHT);
+ map_freeblock_unlock();
+ return 0;
+ }
+
+ break;
+ }
+ case BL_HOM: {
+ struct homun_data *hd = (struct homun_data *)bl;
+ ud->canact_tick = ud->canmove_tick; //It appears HOM do reset the can-act tick.
+ if( !hd->homunculus.intimacy && !(hd->master && !hd->master->state.active) )
+ { //If logging out, this is deleted on unit_free
+ clif_emotion(bl, E_SOB);
+ clif_clearunit_area(bl,clrtype);
+ map_delblock(bl);
+ unit_free(bl,CLR_OUTSIGHT);
+ map_freeblock_unlock();
+ return 0;
+ }
+ break;
+ }
+ case BL_MER: {
+ struct mercenary_data *md = (struct mercenary_data *)bl;
+ ud->canact_tick = ud->canmove_tick;
+ if( mercenary_get_lifetime(md) <= 0 && !(md->master && !md->master->state.active) )
+ {
+ clif_clearunit_area(bl,clrtype);
+ map_delblock(bl);
+ unit_free(bl,CLR_OUTSIGHT);
+ map_freeblock_unlock();
+ return 0;
+ }
+ break;
+ }
+ case BL_ELEM: {
+ struct elemental_data *ed = (struct elemental_data *)bl;
+ ud->canact_tick = ud->canmove_tick;
+ if( elemental_get_lifetime(ed) <= 0 && !(ed->master && !ed->master->state.active) )
+ {
+ clif_clearunit_area(bl,clrtype);
+ map_delblock(bl);
+ unit_free(bl,0);
+ map_freeblock_unlock();
+ return 0;
+ }
+ break;
+ }
+ default: break;// do nothing
+ }
+ /**
+ * BL_MOB is handled by mob_dead unless the monster is not dead.
+ **/
+ if( bl->type != BL_MOB || !status_isdead(bl) )
+ clif_clearunit_area(bl,clrtype);
+ map_delblock(bl);
+ map_freeblock_unlock();
+ return 1;
}
void unit_remove_map_pc(struct map_session_data *sd, clr_type clrtype)
{
- unit_remove_map(&sd->bl,clrtype);
-
- if (clrtype == CLR_TELEPORT) clrtype = CLR_OUTSIGHT; //CLR_TELEPORT is the warp from logging out, but pets/homunc need to just 'vanish' instead of showing the warping out animation.
-
- if (sd->pd)
- unit_remove_map(&sd->pd->bl, clrtype);
- if (merc_is_hom_active(sd->hd))
- unit_remove_map(&sd->hd->bl, clrtype);
- if (sd->md)
- unit_remove_map(&sd->md->bl, clrtype);
- if (sd->ed)
- unit_remove_map(&sd->ed->bl, clrtype);
+ unit_remove_map(&sd->bl,clrtype);
+
+ if (clrtype == CLR_TELEPORT) clrtype = CLR_OUTSIGHT; //CLR_TELEPORT is the warp from logging out, but pets/homunc need to just 'vanish' instead of showing the warping out animation.
+
+ if(sd->pd)
+ unit_remove_map(&sd->pd->bl, clrtype);
+ if(merc_is_hom_active(sd->hd))
+ unit_remove_map(&sd->hd->bl, clrtype);
+ if(sd->md)
+ unit_remove_map(&sd->md->bl, clrtype);
+ if(sd->ed)
+ unit_remove_map(&sd->ed->bl, clrtype);
}
void unit_free_pc(struct map_session_data *sd)
{
- if (sd->pd) unit_free(&sd->pd->bl,CLR_OUTSIGHT);
- if (sd->hd) unit_free(&sd->hd->bl,CLR_OUTSIGHT);
- if (sd->md) unit_free(&sd->md->bl,CLR_OUTSIGHT);
- if (sd->ed) unit_free(&sd->ed->bl,CLR_OUTSIGHT);
- unit_free(&sd->bl,CLR_TELEPORT);
+ if (sd->pd) unit_free(&sd->pd->bl,CLR_OUTSIGHT);
+ if (sd->hd) unit_free(&sd->hd->bl,CLR_OUTSIGHT);
+ if (sd->md) unit_free(&sd->md->bl,CLR_OUTSIGHT);
+ if (sd->ed) unit_free(&sd->ed->bl,CLR_OUTSIGHT);
+ unit_free(&sd->bl,CLR_TELEPORT);
}
/*==========================================
@@ -2177,233 +2233,255 @@ void unit_free_pc(struct map_session_data *sd)
*------------------------------------------*/
int unit_free(struct block_list *bl, clr_type clrtype)
{
- struct unit_data *ud = unit_bl2ud(bl);
- nullpo_ret(ud);
-
- map_freeblock_lock();
- if (bl->prev) //Players are supposed to logout with a "warp" effect.
- unit_remove_map(bl, clrtype);
-
- switch (bl->type) {
- case BL_PC: {
- struct map_session_data *sd = (struct map_session_data *)bl;
- int i;
-
- if (status_isdead(bl))
- pc_setrestartvalue(sd,2);
-
- pc_delinvincibletimer(sd);
- pc_delautobonus(sd,sd->autobonus,ARRAYLENGTH(sd->autobonus),false);
- pc_delautobonus(sd,sd->autobonus2,ARRAYLENGTH(sd->autobonus2),false);
- pc_delautobonus(sd,sd->autobonus3,ARRAYLENGTH(sd->autobonus3),false);
-
- if (sd->followtimer != INVALID_TIMER)
- pc_stop_following(sd);
-
- if (sd->duel_invite > 0)
- duel_reject(sd->duel_invite, sd);
-
- // Notify friends that this char logged out. [Skotlex]
- map_foreachpc(clif_friendslist_toggle_sub, sd->status.account_id, sd->status.char_id, 0);
- party_send_logout(sd);
- guild_send_memberinfoshort(sd,0);
- pc_cleareventtimer(sd);
- pc_inventory_rental_clear(sd);
- pc_delspiritball(sd,sd->spiritball,1);
- for (i = 1; i < 5; i++)
- pc_del_talisman(sd, sd->talisman[i], i);
-
- if (sd->reg) { //Double logout already freed pointer fix... [Skotlex]
- aFree(sd->reg);
- sd->reg = NULL;
- sd->reg_num = 0;
- }
- if (sd->regstr) {
- int i;
- for (i = 0; i < sd->regstr_num; ++i)
- if (sd->regstr[i].data)
- aFree(sd->regstr[i].data);
- aFree(sd->regstr);
- sd->regstr = NULL;
- sd->regstr_num = 0;
- }
- if (sd->st && sd->st->state != RUN) { // free attached scripts that are waiting
- script_free_state(sd->st);
- sd->st = NULL;
- sd->npc_id = 0;
- }
- if (sd->combos.count) {
- aFree(sd->combos.bonus);
- aFree(sd->combos.id);
- sd->combos.count = 0;
- }
- break;
- }
- case BL_PET: {
- struct pet_data *pd = (struct pet_data *)bl;
- struct map_session_data *sd = pd->msd;
- pet_hungry_timer_delete(pd);
- if (pd->a_skill) {
- aFree(pd->a_skill);
- pd->a_skill = NULL;
- }
- if (pd->s_skill) {
- if (pd->s_skill->timer != INVALID_TIMER) {
- if (pd->s_skill->id)
- delete_timer(pd->s_skill->timer, pet_skill_support_timer);
- else
- delete_timer(pd->s_skill->timer, pet_heal_timer);
- }
- aFree(pd->s_skill);
- pd->s_skill = NULL;
- }
- if (pd->recovery) {
- if (pd->recovery->timer != INVALID_TIMER)
- delete_timer(pd->recovery->timer, pet_recovery_timer);
- aFree(pd->recovery);
- pd->recovery = NULL;
- }
- if (pd->bonus) {
- if (pd->bonus->timer != INVALID_TIMER)
- delete_timer(pd->bonus->timer, pet_skill_bonus_timer);
- aFree(pd->bonus);
- pd->bonus = NULL;
- }
- if (pd->loot) {
- pet_lootitem_drop(pd,sd);
- if (pd->loot->item)
- aFree(pd->loot->item);
- aFree(pd->loot);
- pd->loot = NULL;
- }
- if (pd->pet.intimate > 0)
- intif_save_petdata(pd->pet.account_id,&pd->pet);
- else {
- //Remove pet.
- intif_delete_petdata(pd->pet.pet_id);
- if (sd) sd->status.pet_id = 0;
- }
- if (sd)
- sd->pd = NULL;
- break;
- }
- case BL_MOB: {
- struct mob_data *md = (struct mob_data *)bl;
- if (md->spawn_timer != INVALID_TIMER) {
- delete_timer(md->spawn_timer,mob_delayspawn);
- md->spawn_timer = INVALID_TIMER;
- }
- if (md->deletetimer != INVALID_TIMER) {
- delete_timer(md->deletetimer,mob_timer_delete);
- md->deletetimer = INVALID_TIMER;
- }
- if (md->lootitem) {
- aFree(md->lootitem);
- md->lootitem=NULL;
- }
- if (md->guardian_data) {
- struct guild_castle *gc = md->guardian_data->castle;
- if (md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS) {
- gc->guardian[md->guardian_data->number].id = 0;
- } else {
- int i;
- ARR_FIND(0, gc->temp_guardians_max, i, gc->temp_guardians[i] == md->bl.id);
- if (i < gc->temp_guardians_max)
- gc->temp_guardians[i] = 0;
- }
- aFree(md->guardian_data);
- md->guardian_data = NULL;
- }
- if (md->spawn) {
- md->spawn->active--;
- if (!md->spawn->state.dynamic) {
- // permanently remove the mob
- if (--md->spawn->num == 0) {
- // Last freed mob is responsible for deallocating the group's spawn data.
- aFree(md->spawn);
- md->spawn = NULL;
- }
- }
- }
- if (md->base_status) {
- aFree(md->base_status);
- md->base_status = NULL;
- }
- if (mob_is_clone(md->class_))
- mob_clone_delete(md);
- if (md->tomb_nid)
- mvptomb_destroy(md);
- break;
- }
- case BL_HOM: {
- struct homun_data *hd = (TBL_HOM *)bl;
- struct map_session_data *sd = hd->master;
- merc_hom_hungry_timer_delete(hd);
- if (hd->homunculus.intimacy > 0)
- merc_save(hd);
- else {
- intif_homunculus_requestdelete(hd->homunculus.hom_id);
- if (sd)
- sd->status.hom_id = 0;
- }
- if (sd)
- sd->hd = NULL;
- break;
- }
- case BL_MER: {
- struct mercenary_data *md = (TBL_MER *)bl;
- struct map_session_data *sd = md->master;
- if (mercenary_get_lifetime(md) > 0)
- mercenary_save(md);
- else {
- intif_mercenary_delete(md->mercenary.mercenary_id);
- if (sd)
- sd->status.mer_id = 0;
- }
- if (sd)
- sd->md = NULL;
-
- merc_contract_stop(md);
- break;
- }
- case BL_ELEM: {
- struct elemental_data *ed = (TBL_ELEM *)bl;
- struct map_session_data *sd = ed->master;
- if (elemental_get_lifetime(ed) > 0)
- elemental_save(ed);
- else {
- intif_elemental_delete(ed->elemental.elemental_id);
- if (sd)
- sd->status.ele_id = 0;
- }
- if (sd)
- sd->ed = NULL;
-
- elemental_summon_stop(ed);
- break;
- }
- }
-
- skill_clear_unitgroup(bl);
- status_change_clear(bl,1);
- map_deliddb(bl);
- if (bl->type != BL_PC) //Players are handled by map_quit
- map_freeblock(bl);
- map_freeblock_unlock();
- return 0;
+ struct unit_data *ud = unit_bl2ud( bl );
+ nullpo_ret(ud);
+
+ map_freeblock_lock();
+ if( bl->prev ) //Players are supposed to logout with a "warp" effect.
+ unit_remove_map(bl, clrtype);
+
+ switch( bl->type )
+ {
+ case BL_PC:
+ {
+ struct map_session_data *sd = (struct map_session_data*)bl;
+ int i;
+
+ if( status_isdead(bl) )
+ pc_setrestartvalue(sd,2);
+
+ pc_delinvincibletimer(sd);
+ pc_delautobonus(sd,sd->autobonus,ARRAYLENGTH(sd->autobonus),false);
+ pc_delautobonus(sd,sd->autobonus2,ARRAYLENGTH(sd->autobonus2),false);
+ pc_delautobonus(sd,sd->autobonus3,ARRAYLENGTH(sd->autobonus3),false);
+
+ if( sd->followtimer != INVALID_TIMER )
+ pc_stop_following(sd);
+
+ if( sd->duel_invite > 0 )
+ duel_reject(sd->duel_invite, sd);
+
+ // Notify friends that this char logged out. [Skotlex]
+ map_foreachpc(clif_friendslist_toggle_sub, sd->status.account_id, sd->status.char_id, 0);
+ party_send_logout(sd);
+ guild_send_memberinfoshort(sd,0);
+ pc_cleareventtimer(sd);
+ pc_inventory_rental_clear(sd);
+ pc_delspiritball(sd,sd->spiritball,1);
+ for(i = 1; i < 5; i++)
+ pc_del_talisman(sd, sd->talisman[i], i);
+
+ if( sd->reg ) { //Double logout already freed pointer fix... [Skotlex]
+ aFree(sd->reg);
+ sd->reg = NULL;
+ sd->reg_num = 0;
+ }
+ if( sd->regstr ) {
+ int i;
+ for( i = 0; i < sd->regstr_num; ++i )
+ if( sd->regstr[i].data )
+ aFree(sd->regstr[i].data);
+ aFree(sd->regstr);
+ sd->regstr = NULL;
+ sd->regstr_num = 0;
+ }
+ if( sd->st && sd->st->state != RUN ) {// free attached scripts that are waiting
+ script_free_state(sd->st);
+ sd->st = NULL;
+ sd->npc_id = 0;
+ }
+ if( sd->combos.count ) {
+ aFree(sd->combos.bonus);
+ aFree(sd->combos.id);
+ sd->combos.count = 0;
+ }
+ break;
+ }
+ case BL_PET:
+ {
+ struct pet_data *pd = (struct pet_data*)bl;
+ struct map_session_data *sd = pd->msd;
+ pet_hungry_timer_delete(pd);
+ if( pd->a_skill )
+ {
+ aFree(pd->a_skill);
+ pd->a_skill = NULL;
+ }
+ if( pd->s_skill )
+ {
+ if (pd->s_skill->timer != INVALID_TIMER) {
+ if (pd->s_skill->id)
+ delete_timer(pd->s_skill->timer, pet_skill_support_timer);
+ else
+ delete_timer(pd->s_skill->timer, pet_heal_timer);
+ }
+ aFree(pd->s_skill);
+ pd->s_skill = NULL;
+ }
+ if( pd->recovery )
+ {
+ if(pd->recovery->timer != INVALID_TIMER)
+ delete_timer(pd->recovery->timer, pet_recovery_timer);
+ aFree(pd->recovery);
+ pd->recovery = NULL;
+ }
+ if( pd->bonus )
+ {
+ if (pd->bonus->timer != INVALID_TIMER)
+ delete_timer(pd->bonus->timer, pet_skill_bonus_timer);
+ aFree(pd->bonus);
+ pd->bonus = NULL;
+ }
+ if( pd->loot )
+ {
+ pet_lootitem_drop(pd,sd);
+ if (pd->loot->item)
+ aFree(pd->loot->item);
+ aFree (pd->loot);
+ pd->loot = NULL;
+ }
+ if( pd->pet.intimate > 0 )
+ intif_save_petdata(pd->pet.account_id,&pd->pet);
+ else
+ { //Remove pet.
+ intif_delete_petdata(pd->pet.pet_id);
+ if (sd) sd->status.pet_id = 0;
+ }
+ if( sd )
+ sd->pd = NULL;
+ break;
+ }
+ case BL_MOB:
+ {
+ struct mob_data *md = (struct mob_data*)bl;
+ if( md->spawn_timer != INVALID_TIMER )
+ {
+ delete_timer(md->spawn_timer,mob_delayspawn);
+ md->spawn_timer = INVALID_TIMER;
+ }
+ if( md->deletetimer != INVALID_TIMER )
+ {
+ delete_timer(md->deletetimer,mob_timer_delete);
+ md->deletetimer = INVALID_TIMER;
+ }
+ if( md->lootitem )
+ {
+ aFree(md->lootitem);
+ md->lootitem=NULL;
+ }
+ if( md->guardian_data )
+ {
+ struct guild_castle* gc = md->guardian_data->castle;
+ if( md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS )
+ {
+ gc->guardian[md->guardian_data->number].id = 0;
+ }
+ else
+ {
+ int i;
+ ARR_FIND(0, gc->temp_guardians_max, i, gc->temp_guardians[i] == md->bl.id);
+ if( i < gc->temp_guardians_max )
+ gc->temp_guardians[i] = 0;
+ }
+ aFree(md->guardian_data);
+ md->guardian_data = NULL;
+ }
+ if( md->spawn )
+ {
+ md->spawn->active--;
+ if( !md->spawn->state.dynamic )
+ {// permanently remove the mob
+ if( --md->spawn->num == 0 )
+ {// Last freed mob is responsible for deallocating the group's spawn data.
+ aFree(md->spawn);
+ md->spawn = NULL;
+ }
+ }
+ }
+ if( md->base_status)
+ {
+ aFree(md->base_status);
+ md->base_status = NULL;
+ }
+ if( mob_is_clone(md->class_) )
+ mob_clone_delete(md);
+ if( md->tomb_nid )
+ mvptomb_destroy(md);
+ break;
+ }
+ case BL_HOM:
+ {
+ struct homun_data *hd = (TBL_HOM*)bl;
+ struct map_session_data *sd = hd->master;
+ merc_hom_hungry_timer_delete(hd);
+ if( hd->homunculus.intimacy > 0 )
+ merc_save(hd);
+ else
+ {
+ intif_homunculus_requestdelete(hd->homunculus.hom_id);
+ if( sd )
+ sd->status.hom_id = 0;
+ }
+ if( sd )
+ sd->hd = NULL;
+ break;
+ }
+ case BL_MER:
+ {
+ struct mercenary_data *md = (TBL_MER*)bl;
+ struct map_session_data *sd = md->master;
+ if( mercenary_get_lifetime(md) > 0 )
+ mercenary_save(md);
+ else
+ {
+ intif_mercenary_delete(md->mercenary.mercenary_id);
+ if( sd )
+ sd->status.mer_id = 0;
+ }
+ if( sd )
+ sd->md = NULL;
+
+ merc_contract_stop(md);
+ break;
+ }
+ case BL_ELEM: {
+ struct elemental_data *ed = (TBL_ELEM*)bl;
+ struct map_session_data *sd = ed->master;
+ if( elemental_get_lifetime(ed) > 0 )
+ elemental_save(ed);
+ else {
+ intif_elemental_delete(ed->elemental.elemental_id);
+ if( sd )
+ sd->status.ele_id = 0;
+ }
+ if( sd )
+ sd->ed = NULL;
+
+ elemental_summon_stop(ed);
+ break;
+ }
+ }
+
+ skill_clear_unitgroup(bl);
+ status_change_clear(bl,1);
+ map_deliddb(bl);
+ if( bl->type != BL_PC ) //Players are handled by map_quit
+ map_freeblock(bl);
+ map_freeblock_unlock();
+ return 0;
}
int do_init_unit(void)
{
- add_timer_func_list(unit_attack_timer, "unit_attack_timer");
- add_timer_func_list(unit_walktoxy_timer,"unit_walktoxy_timer");
- add_timer_func_list(unit_walktobl_sub, "unit_walktobl_sub");
- add_timer_func_list(unit_delay_walktoxy_timer,"unit_delay_walktoxy_timer");
- return 0;
+ add_timer_func_list(unit_attack_timer, "unit_attack_timer");
+ add_timer_func_list(unit_walktoxy_timer,"unit_walktoxy_timer");
+ add_timer_func_list(unit_walktobl_sub, "unit_walktobl_sub");
+ add_timer_func_list(unit_delay_walktoxy_timer,"unit_delay_walktoxy_timer");
+ return 0;
}
int do_final_unit(void)
{
- // nothing to do
- return 0;
+ // nothing to do
+ return 0;
}
diff --git a/src/map/unit.h b/src/map/unit.h
index 26797a84f..11f5fba0e 100644
--- a/src/map/unit.h
+++ b/src/map/unit.h
@@ -15,70 +15,70 @@ struct map_session_data;
#include "skill.h" // struct skill_timerskill, struct skill_unit_group, struct skill_unit_group_tickset
struct unit_data {
- struct block_list *bl;
- struct walkpath_data walkpath;
- struct skill_timerskill *skilltimerskill[MAX_SKILLTIMERSKILL];
- struct skill_unit_group *skillunit[MAX_SKILLUNITGROUP];
- struct skill_unit_group_tickset skillunittick[MAX_SKILLUNITGROUPTICKSET];
- short attacktarget_lv;
- short to_x,to_y;
- short skillx,skilly;
- short skillid,skilllv;
- int skilltarget;
- int skilltimer;
- int target;
- int target_to;
- int attacktimer;
- int walktimer;
- int chaserange;
- unsigned int attackabletime;
- unsigned int canact_tick;
- unsigned int canmove_tick;
- uint8 dir;
- unsigned char walk_count;
- unsigned char target_count;
- struct {
- unsigned change_walk_target : 1 ;
- unsigned skillcastcancel : 1 ;
- unsigned attack_continue : 1 ;
- unsigned walk_easy : 1 ;
- unsigned running : 1;
- unsigned speed_changed : 1;
- } state;
+ struct block_list *bl;
+ struct walkpath_data walkpath;
+ struct skill_timerskill *skilltimerskill[MAX_SKILLTIMERSKILL];
+ struct skill_unit_group *skillunit[MAX_SKILLUNITGROUP];
+ struct skill_unit_group_tickset skillunittick[MAX_SKILLUNITGROUPTICKSET];
+ short attacktarget_lv;
+ short to_x,to_y;
+ short skillx,skilly;
+ short skillid,skilllv;
+ int skilltarget;
+ int skilltimer;
+ int target;
+ int target_to;
+ int attacktimer;
+ int walktimer;
+ int chaserange;
+ unsigned int attackabletime;
+ unsigned int canact_tick;
+ unsigned int canmove_tick;
+ uint8 dir;
+ unsigned char walk_count;
+ unsigned char target_count;
+ struct {
+ unsigned change_walk_target : 1 ;
+ unsigned skillcastcancel : 1 ;
+ unsigned attack_continue : 1 ;
+ unsigned walk_easy : 1 ;
+ unsigned running : 1;
+ unsigned speed_changed : 1;
+ } state;
};
struct view_data {
#ifdef __64BIT__
- unsigned int class_;
+ unsigned int class_;
#endif
- unsigned short
+ unsigned short
#ifndef __64BIT__
- class_,
+ class_,
#endif
- weapon,
- shield, //Or left-hand weapon.
- robe,
- head_top,
- head_mid,
- head_bottom,
- hair_style,
- hair_color,
- cloth_color;
- char sex;
- unsigned dead_sit : 2;
+ weapon,
+ shield, //Or left-hand weapon.
+ robe,
+ head_top,
+ head_mid,
+ head_bottom,
+ hair_style,
+ hair_color,
+ cloth_color;
+ char sex;
+ unsigned dead_sit : 2;
};
// PC, MOB, PET ‚É‹¤’Ê‚·‚鈗‚ð‚P‚‚ɂ܂Ƃ߂éŒv‰æ
// •àsŠJŽn
// –ß‚è’l‚ÍA0 ( ¬Œ÷ ), 1 ( Ž¸”s )
-int unit_walktoxy(struct block_list *bl, short x, short y, int easy);
-int unit_walktobl(struct block_list *bl, struct block_list *target, int range, int easy);
+int unit_walktoxy( struct block_list *bl, short x, short y, int easy);
+int unit_walktobl( struct block_list *bl, struct block_list *target, int range, int easy);
int unit_run(struct block_list *bl);
int unit_calc_pos(struct block_list *bl, int tx, int ty, int dir);
// •às’âŽ~
-// type‚͈ȉº‚Ì‘g‚݇‚킹 :
+// type‚͈ȉº‚Ì‘g‚݇‚킹 :
// 1: ˆÊ’uî•ñ‚Ì‘—M( ‚±‚ÌŠÖ”‚ÌŒã‚Ɉʒuî•ñ‚ð‘—M‚·‚éꇂ͕s—v )
// 2: ƒ_ƒ[ƒWƒfƒBƒŒƒC—L‚è
// 4: •s–¾(MOB‚Ì‚ÝH)
@@ -93,7 +93,7 @@ int unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, bool
int unit_warp(struct block_list *bl, short map, short x, short y, clr_type type);
int unit_setdir(struct block_list *bl,unsigned char dir);
uint8 unit_getdir(struct block_list *bl);
-int unit_blown(struct block_list *bl, int dx, int dy, int count, int flag);
+int unit_blown(struct block_list* bl, int dx, int dy, int count, int flag);
// ‚»‚±‚Ü‚Å•às‚Å‚½‚Ç‚è’…‚¯‚é‚©‚Ì”»’è
bool unit_can_reach_pos(struct block_list *bl,int x,int y,int easy);
@@ -110,24 +110,24 @@ int unit_skilluse_pos(struct block_list *src, short skill_x, short skill_y, shor
// ƒXƒLƒ‹Žg—p( •â³Ï‚݃LƒƒƒXƒgŽžŠÔAƒLƒƒƒ“ƒZƒ‹•s‰ÂÝ’è•t‚« )
int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, short skill_lv, int casttime, int castcancel);
-int unit_skilluse_pos2(struct block_list *src, short skill_x, short skill_y, short skill_num, short skill_lv, int casttime, int castcancel);
+int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, short skill_num, short skill_lv, int casttime, int castcancel);
// ‰r¥ƒLƒƒƒ“ƒZƒ‹
int unit_skillcastcancel(struct block_list *bl,int type);
int unit_counttargeted(struct block_list *bl);
-int unit_set_target(struct unit_data *ud, int target_id);
+int unit_set_target(struct unit_data* ud, int target_id);
// unit_data ‚̉Šú‰»ˆ—
void unit_dataset(struct block_list *bl);
int unit_fixdamage(struct block_list *src,struct block_list *target,unsigned int tick,int sdelay,int ddelay,int damage,int div,int type,int damage2);
// ‚»‚Ì‘¼
-struct unit_data *unit_bl2ud(struct block_list *bl);
+struct unit_data* unit_bl2ud(struct block_list *bl);
void unit_remove_map_pc(struct map_session_data *sd, clr_type clrtype);
void unit_free_pc(struct map_session_data *sd);
#define unit_remove_map(bl,clrtype) unit_remove_map_(bl,clrtype,__FILE__,__LINE__,__func__)
-int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char *file, int line, const char *func);
+int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file, int line, const char* func);
int unit_free(struct block_list *bl, clr_type clrtype);
int unit_changeviewsize(struct block_list *bl,short size);
diff --git a/src/map/vending.c b/src/map/vending.c
index c796d77e5..0f8255788 100644
--- a/src/map/vending.c
+++ b/src/map/vending.c
@@ -25,379 +25,393 @@ static int vending_nextid = 0;
/// Returns an unique vending shop id.
static int vending_getuid(void)
{
- return vending_nextid++;
+ return vending_nextid++;
}
/*==========================================
* Close shop
*------------------------------------------*/
-void vending_closevending(struct map_session_data *sd)
+void vending_closevending(struct map_session_data* sd)
{
- nullpo_retv(sd);
+ nullpo_retv(sd);
- if (sd->state.vending) {
- sd->state.vending = false;
- clif_closevendingboard(&sd->bl, 0);
- }
+ if( sd->state.vending )
+ {
+ sd->state.vending = false;
+ clif_closevendingboard(&sd->bl, 0);
+ }
}
/*==========================================
* Request a shop's item list
*------------------------------------------*/
-void vending_vendinglistreq(struct map_session_data *sd, int id)
+void vending_vendinglistreq(struct map_session_data* sd, int id)
{
- struct map_session_data *vsd;
- nullpo_retv(sd);
+ struct map_session_data* vsd;
+ nullpo_retv(sd);
- if ((vsd = map_id2sd(id)) == NULL)
- return;
- if (!vsd->state.vending)
- return; // not vending
+ if( (vsd = map_id2sd(id)) == NULL )
+ return;
+ if( !vsd->state.vending )
+ return; // not vending
- if (!pc_can_give_items(sd) || !pc_can_give_items(vsd)) { //check if both GMs are allowed to trade
- // GM is not allowed to trade
- clif_displaymessage(sd->fd, msg_txt(246));
- return;
- }
+ if (!pc_can_give_items(sd) || !pc_can_give_items(vsd)) //check if both GMs are allowed to trade
+ { // GM is not allowed to trade
+ clif_displaymessage(sd->fd, msg_txt(246));
+ return;
+ }
- sd->vended_id = vsd->vender_id; // register vending uid
+ sd->vended_id = vsd->vender_id; // register vending uid
- clif_vendinglist(sd, id, vsd->vending);
+ clif_vendinglist(sd, id, vsd->vending);
}
/*==========================================
* Purchase item(s) from a shop
*------------------------------------------*/
-void vending_purchasereq(struct map_session_data *sd, int aid, int uid, const uint8 *data, int count)
+void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const uint8* data, int count)
{
- int i, j, cursor, w, new_ = 0, blank, vend_list[MAX_VENDING];
- double z;
- struct s_vending vending[MAX_VENDING]; // against duplicate packets
- struct map_session_data *vsd = map_id2sd(aid);
-
- nullpo_retv(sd);
- if (vsd == NULL || !vsd->state.vending || vsd->bl.id == sd->bl.id)
- return; // invalid shop
-
- if (vsd->vender_id != uid) {
- // shop has changed
- clif_buyvending(sd, 0, 0, 6); // store information was incorrect
- return;
- }
-
- if (!searchstore_queryremote(sd, aid) && (sd->bl.m != vsd->bl.m || !check_distance_bl(&sd->bl, &vsd->bl, AREA_SIZE)))
- return; // shop too far away
-
- searchstore_clearremote(sd);
-
- if (count < 1 || count > MAX_VENDING || count > vsd->vend_num)
- return; // invalid amount of purchased items
-
- blank = pc_inventoryblank(sd); //number of free cells in the buyer's inventory
-
- // duplicate item in vending to check hacker with multiple packets
- memcpy(&vending, &vsd->vending, sizeof(vsd->vending)); // copy vending list
-
- // some checks
- z = 0.; // zeny counter
- w = 0; // weight counter
- for (i = 0; i < count; i++) {
- short amount = *(uint16 *)(data + 4*i + 0);
- short idx = *(uint16 *)(data + 4*i + 2);
- idx -= 2;
-
- if (amount <= 0)
- return;
-
- // check of item index in the cart
- if (idx < 0 || idx >= MAX_CART)
- return;
-
- ARR_FIND(0, vsd->vend_num, j, vsd->vending[j].index == idx);
- if (j == vsd->vend_num)
- return; //picked non-existing item
- else
- vend_list[i] = j;
-
- z += ((double)vsd->vending[j].value * (double)amount);
- if (z > (double)sd->status.zeny || z < 0. || z > (double)MAX_ZENY) {
- clif_buyvending(sd, idx, amount, 1); // you don't have enough zeny
- return;
- }
- if (z + (double)vsd->status.zeny > (double)MAX_ZENY && !battle_config.vending_over_max) {
- clif_buyvending(sd, idx, vsd->vending[j].amount, 4); // too much zeny = overflow
- return;
-
- }
- w += itemdb_weight(vsd->status.cart[idx].nameid) * amount;
- if (w + sd->weight > sd->max_weight) {
- clif_buyvending(sd, idx, amount, 2); // you can not buy, because overweight
- return;
- }
-
- //Check to see if cart/vend info is in sync.
- if (vending[j].amount > vsd->status.cart[idx].amount)
- vending[j].amount = vsd->status.cart[idx].amount;
-
- // if they try to add packets (example: get twice or more 2 apples if marchand has only 3 apples).
- // here, we check cumulative amounts
- if (vending[j].amount < amount) {
- // send more quantity is not a hack (an other player can have buy items just before)
- clif_buyvending(sd, idx, vsd->vending[j].amount, 4); // not enough quantity
- return;
- }
-
- vending[j].amount -= amount;
-
- switch (pc_checkadditem(sd, vsd->status.cart[idx].nameid, amount)) {
- case ADDITEM_EXIST:
- break; //We'd add this item to the existing one (in buyers inventory)
- case ADDITEM_NEW:
- new_++;
- if (new_ > blank)
- return; //Buyer has no space in his inventory
- break;
- case ADDITEM_OVERAMOUNT:
- return; //too many items
- }
- }
-
- pc_payzeny(sd, (int)z, LOG_TYPE_VENDING, vsd);
- if (battle_config.vending_tax)
- z -= z * (battle_config.vending_tax/10000.);
- pc_getzeny(vsd, (int)z, LOG_TYPE_VENDING, sd);
-
- for (i = 0; i < count; i++) {
- short amount = *(uint16 *)(data + 4*i + 0);
- short idx = *(uint16 *)(data + 4*i + 2);
- idx -= 2;
-
- // vending item
- pc_additem(sd, &vsd->status.cart[idx], amount, LOG_TYPE_VENDING);
- vsd->vending[vend_list[i]].amount -= amount;
- pc_cart_delitem(vsd, idx, amount, 0, LOG_TYPE_VENDING);
- clif_vendingreport(vsd, idx, amount);
-
- //print buyer's name
- if (battle_config.buyer_name) {
- char temp[256];
- sprintf(temp, msg_txt(265), sd->status.name);
- clif_disp_onlyself(vsd,temp,strlen(temp));
- }
- }
-
- // compact the vending list
- for (i = 0, cursor = 0; i < vsd->vend_num; i++) {
- if (vsd->vending[i].amount == 0)
- continue;
-
- if (cursor != i) { // speedup
- vsd->vending[cursor].index = vsd->vending[i].index;
- vsd->vending[cursor].amount = vsd->vending[i].amount;
- vsd->vending[cursor].value = vsd->vending[i].value;
- }
-
- cursor++;
- }
- vsd->vend_num = cursor;
-
- //Always save BOTH: buyer and customer
- if (save_settings&2) {
- chrif_save(sd,0);
- chrif_save(vsd,0);
- }
-
- //check for @AUTOTRADE users [durf]
- if (vsd->state.autotrade) {
- //see if there is anything left in the shop
- ARR_FIND(0, vsd->vend_num, i, vsd->vending[i].amount > 0);
- if (i == vsd->vend_num) {
- //Close Vending (this was automatically done by the client, we have to do it manually for autovenders) [Skotlex]
- vending_closevending(vsd);
- map_quit(vsd); //They have no reason to stay around anymore, do they?
- }
- }
+ int i, j, cursor, w, new_ = 0, blank, vend_list[MAX_VENDING];
+ double z;
+ struct s_vending vending[MAX_VENDING]; // against duplicate packets
+ struct map_session_data* vsd = map_id2sd(aid);
+
+ nullpo_retv(sd);
+ if( vsd == NULL || !vsd->state.vending || vsd->bl.id == sd->bl.id )
+ return; // invalid shop
+
+ if( vsd->vender_id != uid )
+ {// shop has changed
+ clif_buyvending(sd, 0, 0, 6); // store information was incorrect
+ return;
+ }
+
+ if( !searchstore_queryremote(sd, aid) && ( sd->bl.m != vsd->bl.m || !check_distance_bl(&sd->bl, &vsd->bl, AREA_SIZE) ) )
+ return; // shop too far away
+
+ searchstore_clearremote(sd);
+
+ if( count < 1 || count > MAX_VENDING || count > vsd->vend_num )
+ return; // invalid amount of purchased items
+
+ blank = pc_inventoryblank(sd); //number of free cells in the buyer's inventory
+
+ // duplicate item in vending to check hacker with multiple packets
+ memcpy(&vending, &vsd->vending, sizeof(vsd->vending)); // copy vending list
+
+ // some checks
+ z = 0.; // zeny counter
+ w = 0; // weight counter
+ for( i = 0; i < count; i++ )
+ {
+ short amount = *(uint16*)(data + 4*i + 0);
+ short idx = *(uint16*)(data + 4*i + 2);
+ idx -= 2;
+
+ if( amount <= 0 )
+ return;
+
+ // check of item index in the cart
+ if( idx < 0 || idx >= MAX_CART )
+ return;
+
+ ARR_FIND( 0, vsd->vend_num, j, vsd->vending[j].index == idx );
+ if( j == vsd->vend_num )
+ return; //picked non-existing item
+ else
+ vend_list[i] = j;
+
+ z += ((double)vsd->vending[j].value * (double)amount);
+ if( z > (double)sd->status.zeny || z < 0. || z > (double)MAX_ZENY )
+ {
+ clif_buyvending(sd, idx, amount, 1); // you don't have enough zeny
+ return;
+ }
+ if( z + (double)vsd->status.zeny > (double)MAX_ZENY && !battle_config.vending_over_max )
+ {
+ clif_buyvending(sd, idx, vsd->vending[j].amount, 4); // too much zeny = overflow
+ return;
+
+ }
+ w += itemdb_weight(vsd->status.cart[idx].nameid) * amount;
+ if( w + sd->weight > sd->max_weight )
+ {
+ clif_buyvending(sd, idx, amount, 2); // you can not buy, because overweight
+ return;
+ }
+
+ //Check to see if cart/vend info is in sync.
+ if( vending[j].amount > vsd->status.cart[idx].amount )
+ vending[j].amount = vsd->status.cart[idx].amount;
+
+ // if they try to add packets (example: get twice or more 2 apples if marchand has only 3 apples).
+ // here, we check cumulative amounts
+ if( vending[j].amount < amount )
+ {
+ // send more quantity is not a hack (an other player can have buy items just before)
+ clif_buyvending(sd, idx, vsd->vending[j].amount, 4); // not enough quantity
+ return;
+ }
+
+ vending[j].amount -= amount;
+
+ switch( pc_checkadditem(sd, vsd->status.cart[idx].nameid, amount) ) {
+ case ADDITEM_EXIST:
+ break; //We'd add this item to the existing one (in buyers inventory)
+ case ADDITEM_NEW:
+ new_++;
+ if (new_ > blank)
+ return; //Buyer has no space in his inventory
+ break;
+ case ADDITEM_OVERAMOUNT:
+ return; //too many items
+ }
+ }
+
+ pc_payzeny(sd, (int)z, LOG_TYPE_VENDING, vsd);
+ if( battle_config.vending_tax )
+ z -= z * (battle_config.vending_tax/10000.);
+ pc_getzeny(vsd, (int)z, LOG_TYPE_VENDING, sd);
+
+ for( i = 0; i < count; i++ )
+ {
+ short amount = *(uint16*)(data + 4*i + 0);
+ short idx = *(uint16*)(data + 4*i + 2);
+ idx -= 2;
+
+ // vending item
+ pc_additem(sd, &vsd->status.cart[idx], amount, LOG_TYPE_VENDING);
+ vsd->vending[vend_list[i]].amount -= amount;
+ pc_cart_delitem(vsd, idx, amount, 0, LOG_TYPE_VENDING);
+ clif_vendingreport(vsd, idx, amount);
+
+ //print buyer's name
+ if( battle_config.buyer_name )
+ {
+ char temp[256];
+ sprintf(temp, msg_txt(265), sd->status.name);
+ clif_disp_onlyself(vsd,temp,strlen(temp));
+ }
+ }
+
+ // compact the vending list
+ for( i = 0, cursor = 0; i < vsd->vend_num; i++ )
+ {
+ if( vsd->vending[i].amount == 0 )
+ continue;
+
+ if( cursor != i ) // speedup
+ {
+ vsd->vending[cursor].index = vsd->vending[i].index;
+ vsd->vending[cursor].amount = vsd->vending[i].amount;
+ vsd->vending[cursor].value = vsd->vending[i].value;
+ }
+
+ cursor++;
+ }
+ vsd->vend_num = cursor;
+
+ //Always save BOTH: buyer and customer
+ if( save_settings&2 )
+ {
+ chrif_save(sd,0);
+ chrif_save(vsd,0);
+ }
+
+ //check for @AUTOTRADE users [durf]
+ if( vsd->state.autotrade )
+ {
+ //see if there is anything left in the shop
+ ARR_FIND( 0, vsd->vend_num, i, vsd->vending[i].amount > 0 );
+ if( i == vsd->vend_num )
+ {
+ //Close Vending (this was automatically done by the client, we have to do it manually for autovenders) [Skotlex]
+ vending_closevending(vsd);
+ map_quit(vsd); //They have no reason to stay around anymore, do they?
+ }
+ }
}
-static int vending_checknearnpc_sub(struct block_list *bl, va_list args)
-{
- struct npc_data *nd = (struct npc_data *)bl;
-
- if (nd->sc.option & (OPTION_HIDE|OPTION_INVISIBLE))
+static int vending_checknearnpc_sub(struct block_list* bl, va_list args) {
+ struct npc_data *nd = (struct npc_data*)bl;
+
+ if( nd->sc.option & (OPTION_HIDE|OPTION_INVISIBLE) )
return 0;
return 1;
}
-bool vending_checknearnpc(struct block_list *bl)
-{
-
- if (battle_config.min_npc_vending_distance > 0 &&
- map_foreachinrange(vending_checknearnpc_sub,bl, battle_config.min_npc_vending_distance, BL_NPC))
+bool vending_checknearnpc(struct block_list * bl) {
+
+ if( battle_config.min_npc_vending_distance > 0 &&
+ map_foreachinrange(vending_checknearnpc_sub,bl, battle_config.min_npc_vending_distance, BL_NPC) )
return true;
-
+
return false;
}
/*==========================================
* Open shop
* data := {<index>.w <amount>.w <value>.l}[count]
*------------------------------------------*/
-void vending_openvending(struct map_session_data *sd, const char *message, bool flag, const uint8 *data, int count)
-{
- int i, j;
- int vending_skill_lvl;
- nullpo_retv(sd);
-
- if (!flag) // cancelled
- return; // nothing to do
-
- if (pc_isdead(sd) || !sd->state.prevend || pc_istrading(sd))
- return; // can't open vendings lying dead || didn't use via the skill (wpe/hack) || can't have 2 shops at once
-
- vending_skill_lvl = pc_checkskill(sd, MC_VENDING);
- // skill level and cart check
- if (!vending_skill_lvl || !pc_iscarton(sd)) {
- clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0);
- return;
- }
-
- // check number of items in shop
- if (count < 1 || count > MAX_VENDING || count > 2 + vending_skill_lvl) {
- // invalid item count
- clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0);
- return;
- }
- //check if nearby npc, (perhaps we should check for nearby shop too
- if (vending_checknearnpc(&sd->bl)) {
+void vending_openvending(struct map_session_data* sd, const char* message, bool flag, const uint8* data, int count) {
+ int i, j;
+ int vending_skill_lvl;
+ nullpo_retv(sd);
+
+ if( !flag ) // cancelled
+ return; // nothing to do
+
+ if ( pc_isdead(sd) || !sd->state.prevend || pc_istrading(sd))
+ return; // can't open vendings lying dead || didn't use via the skill (wpe/hack) || can't have 2 shops at once
+
+ vending_skill_lvl = pc_checkskill(sd, MC_VENDING);
+ // skill level and cart check
+ if( !vending_skill_lvl || !pc_iscarton(sd) )
+ {
+ clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0);
+ return;
+ }
+
+ // check number of items in shop
+ if( count < 1 || count > MAX_VENDING || count > 2 + vending_skill_lvl )
+ { // invalid item count
+ clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0);
+ return;
+ }
+ //check if nearby npc, (perhaps we should check for nearby shop too
+ if( vending_checknearnpc(&sd->bl) ) {
char output[150];
sprintf(output,"You're too close to a NPC, you must be at least %d cells away from any NPC.",battle_config.min_npc_vending_distance);
clif_displaymessage(sd->fd, output);
clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0);
return;
}
-
-
- // filter out invalid items
- i = 0;
- for (j = 0; j < count; j++) {
- short index = *(uint16 *)(data + 8*j + 0);
- short amount = *(uint16 *)(data + 8*j + 2);
- unsigned int value = *(uint32 *)(data + 8*j + 4);
-
- index -= 2; // offset adjustment (client says that the first cart position is 2)
-
- if (index < 0 || index >= MAX_CART // invalid position
- || pc_cartitem_amount(sd, index, amount) < 0 // invalid item or insufficient quantity
- //NOTE: official server does not do any of the following checks!
- || !sd->status.cart[index].identify // unidentified item
- || sd->status.cart[index].attribute == 1 // broken item
- || sd->status.cart[index].expire_time // It should not be in the cart but just in case
- || !itemdb_cantrade(&sd->status.cart[index], pc_get_group_level(sd), pc_get_group_level(sd))) // untradeable item
- continue;
-
- sd->vending[i].index = index;
- sd->vending[i].amount = amount;
- sd->vending[i].value = cap_value(value, 0, (unsigned int)battle_config.vending_max_value);
-
- i++; // item successfully added
- }
-
- if (i != j)
- clif_displaymessage(sd->fd, msg_txt(266)); //"Some of your items cannot be vended and were removed from the shop."
-
- if (i == 0) {
- // no valid item found
- clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0); // custom reply packet
- return;
- }
- sd->state.prevend = 0;
- sd->state.vending = true;
- sd->vender_id = vending_getuid();
- sd->vend_num = i;
- safestrncpy(sd->message, message, MESSAGE_SIZE);
-
- pc_stop_walking(sd,1);
- clif_openvending(sd,sd->bl.id,sd->vending);
- clif_showvendingboard(&sd->bl,message,0);
+
+
+ // filter out invalid items
+ i = 0;
+ for( j = 0; j < count; j++ )
+ {
+ short index = *(uint16*)(data + 8*j + 0);
+ short amount = *(uint16*)(data + 8*j + 2);
+ unsigned int value = *(uint32*)(data + 8*j + 4);
+
+ index -= 2; // offset adjustment (client says that the first cart position is 2)
+
+ if( index < 0 || index >= MAX_CART // invalid position
+ || pc_cartitem_amount(sd, index, amount) < 0 // invalid item or insufficient quantity
+ //NOTE: official server does not do any of the following checks!
+ || !sd->status.cart[index].identify // unidentified item
+ || sd->status.cart[index].attribute == 1 // broken item
+ || sd->status.cart[index].expire_time // It should not be in the cart but just in case
+ || !itemdb_cantrade(&sd->status.cart[index], pc_get_group_level(sd), pc_get_group_level(sd)) ) // untradeable item
+ continue;
+
+ sd->vending[i].index = index;
+ sd->vending[i].amount = amount;
+ sd->vending[i].value = cap_value(value, 0, (unsigned int)battle_config.vending_max_value);
+
+ i++; // item successfully added
+ }
+
+ if( i != j )
+ clif_displaymessage (sd->fd, msg_txt(266)); //"Some of your items cannot be vended and were removed from the shop."
+
+ if( i == 0 )
+ { // no valid item found
+ clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0); // custom reply packet
+ return;
+ }
+ sd->state.prevend = 0;
+ sd->state.vending = true;
+ sd->vender_id = vending_getuid();
+ sd->vend_num = i;
+ safestrncpy(sd->message, message, MESSAGE_SIZE);
+
+ pc_stop_walking(sd,1);
+ clif_openvending(sd,sd->bl.id,sd->vending);
+ clif_showvendingboard(&sd->bl,message,0);
}
/// Checks if an item is being sold in given player's vending.
-bool vending_search(struct map_session_data *sd, unsigned short nameid)
+bool vending_search(struct map_session_data* sd, unsigned short nameid)
{
- int i;
+ int i;
- if (!sd->state.vending) {
- // not vending
- return false;
- }
+ if( !sd->state.vending )
+ {// not vending
+ return false;
+ }
- ARR_FIND(0, sd->vend_num, i, sd->status.cart[sd->vending[i].index].nameid == (short)nameid);
- if (i == sd->vend_num) {
- // not found
- return false;
- }
+ ARR_FIND( 0, sd->vend_num, i, sd->status.cart[sd->vending[i].index].nameid == (short)nameid );
+ if( i == sd->vend_num )
+ {// not found
+ return false;
+ }
- return true;
+ return true;
}
/// Searches for all items in a vending, that match given ids, price and possible cards.
/// @return Whether or not the search should be continued.
-bool vending_searchall(struct map_session_data *sd, const struct s_search_store_search *s)
+bool vending_searchall(struct map_session_data* sd, const struct s_search_store_search* s)
{
- int i, c, slot;
- unsigned int idx, cidx;
- struct item *it;
-
- if (!sd->state.vending) {
- // not vending
- return true;
- }
-
- for (idx = 0; idx < s->item_count; idx++) {
- ARR_FIND(0, sd->vend_num, i, sd->status.cart[sd->vending[i].index].nameid == (short)s->itemlist[idx]);
- if (i == sd->vend_num) {
- // not found
- continue;
- }
- it = &sd->status.cart[sd->vending[i].index];
-
- if (s->min_price && s->min_price > sd->vending[i].value) {
- // too low price
- continue;
- }
-
- if (s->max_price && s->max_price < sd->vending[i].value) {
- // too high price
- continue;
- }
-
- if (s->card_count) {
- // check cards
- if (itemdb_isspecial(it->card[0])) {
- // something, that is not a carded
- continue;
- }
- slot = itemdb_slot(it->nameid);
-
- for (c = 0; c < slot && it->card[c]; c ++) {
- ARR_FIND(0, s->card_count, cidx, s->cardlist[cidx] == it->card[c]);
- if (cidx != s->card_count) {
- // found
- break;
- }
- }
-
- if (c == slot || !it->card[c]) {
- // no card match
- continue;
- }
- }
-
- if (!searchstore_result(s->search_sd, sd->vender_id, sd->status.account_id, sd->message, it->nameid, sd->vending[i].amount, sd->vending[i].value, it->card, it->refine)) {
- // result set full
- return false;
- }
- }
-
- return true;
+ int i, c, slot;
+ unsigned int idx, cidx;
+ struct item* it;
+
+ if( !sd->state.vending )
+ {// not vending
+ return true;
+ }
+
+ for( idx = 0; idx < s->item_count; idx++ )
+ {
+ ARR_FIND( 0, sd->vend_num, i, sd->status.cart[sd->vending[i].index].nameid == (short)s->itemlist[idx] );
+ if( i == sd->vend_num )
+ {// not found
+ continue;
+ }
+ it = &sd->status.cart[sd->vending[i].index];
+
+ if( s->min_price && s->min_price > sd->vending[i].value )
+ {// too low price
+ continue;
+ }
+
+ if( s->max_price && s->max_price < sd->vending[i].value )
+ {// too high price
+ continue;
+ }
+
+ if( s->card_count )
+ {// check cards
+ if( itemdb_isspecial(it->card[0]) )
+ {// something, that is not a carded
+ continue;
+ }
+ slot = itemdb_slot(it->nameid);
+
+ for( c = 0; c < slot && it->card[c]; c ++ )
+ {
+ ARR_FIND( 0, s->card_count, cidx, s->cardlist[cidx] == it->card[c] );
+ if( cidx != s->card_count )
+ {// found
+ break;
+ }
+ }
+
+ if( c == slot || !it->card[c] )
+ {// no card match
+ continue;
+ }
+ }
+
+ if( !searchstore_result(s->search_sd, sd->vender_id, sd->status.account_id, sd->message, it->nameid, sd->vending[i].amount, sd->vending[i].value, it->card, it->refine) )
+ {// result set full
+ return false;
+ }
+ }
+
+ return true;
}
diff --git a/src/map/vending.h b/src/map/vending.h
index 17dad31cd..2ed52b9bd 100644
--- a/src/map/vending.h
+++ b/src/map/vending.h
@@ -1,8 +1,8 @@
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder
-#ifndef _VENDING_H_
-#define _VENDING_H_
+#ifndef _VENDING_H_
+#define _VENDING_H_
#include "../common/cbasetypes.h"
//#include "map.h"
@@ -10,17 +10,17 @@ struct map_session_data;
struct s_search_store_search;
struct s_vending {
- short index; //cart index (return item data)
- short amount; //amout of the item for vending
- unsigned int value; //at wich price
+ short index; //cart index (return item data)
+ short amount; //amout of the item for vending
+ unsigned int value; //at wich price
};
-void vending_closevending(struct map_session_data *sd);
-void vending_openvending(struct map_session_data *sd, const char *message, bool flag, const uint8 *data, int count);
-void vending_vendinglistreq(struct map_session_data *sd, int id);
-void vending_purchasereq(struct map_session_data *sd, int aid, int uid, const uint8 *data, int count);
-bool vending_search(struct map_session_data *sd, unsigned short nameid);
-bool vending_searchall(struct map_session_data *sd, const struct s_search_store_search *s);
-bool vending_checknearnpc(struct block_list *bl);
+void vending_closevending(struct map_session_data* sd);
+void vending_openvending(struct map_session_data* sd, const char* message, bool flag, const uint8* data, int count);
+void vending_vendinglistreq(struct map_session_data* sd, int id);
+void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const uint8* data, int count);
+bool vending_search(struct map_session_data* sd, unsigned short nameid);
+bool vending_searchall(struct map_session_data* sd, const struct s_search_store_search* s);
+bool vending_checknearnpc(struct block_list * bl);
#endif /* _VENDING_H_ */
diff --git a/src/test/test_spinlock.c b/src/test/test_spinlock.c
index e6f7dfe52..878ee8bab 100644
--- a/src/test/test_spinlock.c
+++ b/src/test/test_spinlock.c
@@ -8,8 +8,8 @@
#include <stdio.h>
#include <stdlib.h>
-//
-// Simple test for the spinlock implementation to see if it works properly..
+//
+// Simple test for the spinlock implementation to see if it works properly..
//
@@ -23,101 +23,95 @@ static SPIN_LOCK lock;
static int val = 0;
static volatile int32 done_threads = 0;
-static void *worker(void *p)
-{
- register int i;
-
- for (i = 0; i < PERINC; i++) {
- EnterSpinLock(&lock);
- EnterSpinLock(&lock);
-
- val++;
-
- LeaveSpinLock(&lock);
- LeaveSpinLock(&lock);
- }
-
- InterlockedIncrement(&done_threads);
-
- return NULL;
+static void *worker(void *p){
+ register int i;
+
+ for(i = 0; i < PERINC; i++){
+ EnterSpinLock(&lock);
+ EnterSpinLock(&lock);
+
+ val++;
+
+ LeaveSpinLock(&lock);
+ LeaveSpinLock(&lock);
+ }
+
+ InterlockedIncrement(&done_threads);
+
+ return NULL;
}//end: worker()
-int do_init(int argc, char **argv)
-{
- rAthread t[THRC];
- int j, i;
- int ok;
-
- ShowStatus("==========\n");
- ShowStatus("TEST: %u Runs, (%u Threads)\n", LOOPS, THRC);
- ShowStatus("This can take a while\n");
- ShowStatus("\n\n");
-
- ok =0;
- for (j = 0; j < LOOPS; j++) {
- val = 0;
- done_threads = 0;
-
- InitializeSpinLock(&lock);
-
-
- for (i =0; i < THRC; i++) {
- t[i] = rathread_createEx(worker, NULL, 1024*512, RAT_PRIO_NORMAL);
- }
-
-
- while (1) {
- if (InterlockedCompareExchange(&done_threads, THRC, THRC) == THRC)
- break;
-
- rathread_yield();
- }
-
- FinalizeSpinLock(&lock);
-
- // Everything fine?
- if (val != (THRC*PERINC)) {
- printf("FAILED! (Result: %u, Expected: %u)\n", val, (THRC*PERINC));
- } else {
- printf("OK! (Result: %u, Expected: %u)\n", val, (THRC*PERINC));
- ok++;
- }
-
- }
-
-
- if (ok != LOOPS) {
- ShowFatalError("Test failed.\n");
- exit(1);
- } else {
- ShowStatus("Test passed.\n");
- exit(0);
- }
-
-
- return 0;
+int do_init(int argc, char **argv){
+ rAthread t[THRC];
+ int j, i;
+ int ok;
+
+ ShowStatus("==========\n");
+ ShowStatus("TEST: %u Runs, (%u Threads)\n", LOOPS, THRC);
+ ShowStatus("This can take a while\n");
+ ShowStatus("\n\n");
+
+ ok =0;
+ for(j = 0; j < LOOPS; j++){
+ val = 0;
+ done_threads = 0;
+
+ InitializeSpinLock(&lock);
+
+
+ for(i =0; i < THRC; i++){
+ t[i] = rathread_createEx( worker, NULL, 1024*512, RAT_PRIO_NORMAL);
+ }
+
+
+ while(1){
+ if(InterlockedCompareExchange(&done_threads, THRC, THRC) == THRC)
+ break;
+
+ rathread_yield();
+ }
+
+ FinalizeSpinLock(&lock);
+
+ // Everything fine?
+ if(val != (THRC*PERINC) ){
+ printf("FAILED! (Result: %u, Expected: %u)\n", val, (THRC*PERINC) );
+ }else{
+ printf("OK! (Result: %u, Expected: %u)\n", val, (THRC*PERINC) );
+ ok++;
+ }
+
+ }
+
+
+ if(ok != LOOPS){
+ ShowFatalError("Test failed.\n");
+ exit(1);
+ }else{
+ ShowStatus("Test passed.\n");
+ exit(0);
+ }
+
+
+return 0;
}//end: do_init()
-void do_abort()
-{
+void do_abort(){
}//end: do_abort()
-void set_server_type()
-{
- SERVER_TYPE = ATHENA_SERVER_NONE;
+void set_server_type(){
+ SERVER_TYPE = ATHENA_SERVER_NONE;
}//end: set_server_type()
-void do_final()
-{
+void do_final(){
}//end: do_final()
-int parse_console(const char *command)
-{
- return 0;
+int parse_console(const char* command){
+ return 0;
}//end: parse_console
diff --git a/src/tool/mapcache.c b/src/tool/mapcache.c
index 0e8d4dd88..49f948709 100644
--- a/src/tool/mapcache.c
+++ b/src/tool/mapcache.c
@@ -30,23 +30,23 @@ unsigned long file_size;
// Used internally, this structure contains the physical map cells
struct map_data {
- int16 xs;
- int16 ys;
- unsigned char *cells;
+ int16 xs;
+ int16 ys;
+ unsigned char *cells;
};
// This is the main header found at the very beginning of the file
struct main_header {
- uint32 file_size;
- uint16 map_count;
+ uint32 file_size;
+ uint16 map_count;
} header;
// This is the header appended before every compressed map cells info
struct map_info {
- char name[MAP_NAME_LENGTH];
- int16 xs;
- int16 ys;
- int32 len;
+ char name[MAP_NAME_LENGTH];
+ int16 xs;
+ int16 ys;
+ int32 len;
};
@@ -57,297 +57,297 @@ struct map_info {
// Converts an int16 from current machine order to little-endian
int16 MakeShortLE(int16 val)
{
- unsigned char buf[2];
- buf[0] = (unsigned char)((val & 0x00FF));
- buf[1] = (unsigned char)((val & 0xFF00) >> 0x08);
- return *((int16 *)buf);
+ unsigned char buf[2];
+ buf[0] = (unsigned char)( (val & 0x00FF) );
+ buf[1] = (unsigned char)( (val & 0xFF00) >> 0x08 );
+ return *((int16*)buf);
}
// Converts an int32 from current machine order to little-endian
int32 MakeLongLE(int32 val)
{
- unsigned char buf[4];
- buf[0] = (unsigned char)((val & 0x000000FF));
- buf[1] = (unsigned char)((val & 0x0000FF00) >> 0x08);
- buf[2] = (unsigned char)((val & 0x00FF0000) >> 0x10);
- buf[3] = (unsigned char)((val & 0xFF000000) >> 0x18);
- return *((int32 *)buf);
+ unsigned char buf[4];
+ buf[0] = (unsigned char)( (val & 0x000000FF) );
+ buf[1] = (unsigned char)( (val & 0x0000FF00) >> 0x08 );
+ buf[2] = (unsigned char)( (val & 0x00FF0000) >> 0x10 );
+ buf[3] = (unsigned char)( (val & 0xFF000000) >> 0x18 );
+ return *((int32*)buf);
}
// Reads an uint16 in little-endian from the buffer
-uint16 GetUShort(const unsigned char *buf)
+uint16 GetUShort(const unsigned char* buf)
{
- return (((uint16)(buf[0])))
- |(((uint16)(buf[1])) << 0x08);
+ return ( ((uint16)(buf[0])) )
+ |( ((uint16)(buf[1])) << 0x08 );
}
// Reads an uint32 in little-endian from the buffer
-uint32 GetULong(const unsigned char *buf)
+uint32 GetULong(const unsigned char* buf)
{
- return (((uint32)(buf[0])))
- |(((uint32)(buf[1])) << 0x08)
- |(((uint32)(buf[2])) << 0x10)
- |(((uint32)(buf[3])) << 0x18);
+ return ( ((uint32)(buf[0])) )
+ |( ((uint32)(buf[1])) << 0x08 )
+ |( ((uint32)(buf[2])) << 0x10 )
+ |( ((uint32)(buf[3])) << 0x18 );
}
// Reads an int32 in little-endian from the buffer
-int32 GetLong(const unsigned char *buf)
+int32 GetLong(const unsigned char* buf)
{
- return (int32)GetULong(buf);
+ return (int32)GetULong(buf);
}
// Reads a float (32 bits) from the buffer
-float GetFloat(const unsigned char *buf)
+float GetFloat(const unsigned char* buf)
{
- uint32 val = GetULong(buf);
- return *((float *)(void *)&val);
+ uint32 val = GetULong(buf);
+ return *((float*)(void*)&val);
}
// Reads a map from GRF's GAT and RSW files
int read_map(char *name, struct map_data *m)
{
- char filename[256];
- unsigned char *gat, *rsw;
- int water_height;
- size_t xy, off, num_cells;
- float height;
- uint32 type;
-
- // Open map GAT
- sprintf(filename,"data\\%s.gat", name);
- gat = (unsigned char *)grfio_read(filename);
- if (gat == NULL)
- return 0;
-
- // Open map RSW
- sprintf(filename,"data\\%s.rsw", name);
- rsw = (unsigned char *)grfio_read(filename);
-
- // Read water height
- if (rsw) {
- water_height = (int)GetFloat(rsw+166);
- aFree(rsw);
- } else
- water_height = NO_WATER;
-
- // Read map size and allocate needed memory
- m->xs = (int16)GetULong(gat+6);
- m->ys = (int16)GetULong(gat+10);
- if (m->xs <= 0 || m->ys <= 0) {
- aFree(gat);
- return 0;
- }
- num_cells = (size_t)m->xs*(size_t)m->ys;
- m->cells = (unsigned char *)aMalloc(num_cells);
-
- // Set cell properties
- off = 14;
- for (xy = 0; xy < num_cells; xy++) {
- // Height of the bottom-left corner
- height = GetFloat(gat + off);
- // Type of cell
- type = GetULong(gat + off + 16);
- off += 20;
-
- if (type == 0 && water_height != NO_WATER && height > water_height)
- type = 3; // Cell is 0 (walkable) but under water level, set to 3 (walkable water)
-
- m->cells[xy] = (unsigned char)type;
- }
-
- aFree(gat);
-
- return 1;
+ char filename[256];
+ unsigned char *gat, *rsw;
+ int water_height;
+ size_t xy, off, num_cells;
+ float height;
+ uint32 type;
+
+ // Open map GAT
+ sprintf(filename,"data\\%s.gat", name);
+ gat = (unsigned char *)grfio_read(filename);
+ if (gat == NULL)
+ return 0;
+
+ // Open map RSW
+ sprintf(filename,"data\\%s.rsw", name);
+ rsw = (unsigned char *)grfio_read(filename);
+
+ // Read water height
+ if (rsw) {
+ water_height = (int)GetFloat(rsw+166);
+ aFree(rsw);
+ } else
+ water_height = NO_WATER;
+
+ // Read map size and allocate needed memory
+ m->xs = (int16)GetULong(gat+6);
+ m->ys = (int16)GetULong(gat+10);
+ if (m->xs <= 0 || m->ys <= 0) {
+ aFree(gat);
+ return 0;
+ }
+ num_cells = (size_t)m->xs*(size_t)m->ys;
+ m->cells = (unsigned char *)aMalloc(num_cells);
+
+ // Set cell properties
+ off = 14;
+ for (xy = 0; xy < num_cells; xy++)
+ {
+ // Height of the bottom-left corner
+ height = GetFloat( gat + off );
+ // Type of cell
+ type = GetULong( gat + off + 16 );
+ off += 20;
+
+ if (type == 0 && water_height != NO_WATER && height > water_height)
+ type = 3; // Cell is 0 (walkable) but under water level, set to 3 (walkable water)
+
+ m->cells[xy] = (unsigned char)type;
+ }
+
+ aFree(gat);
+
+ return 1;
}
// Adds a map to the cache
void cache_map(char *name, struct map_data *m)
{
- struct map_info info;
- unsigned long len;
- unsigned char *write_buf;
-
- // Create an output buffer twice as big as the uncompressed map... this way we're sure it fits
- len = (unsigned long)m->xs*(unsigned long)m->ys*2;
- write_buf = (unsigned char *)aMalloc(len);
- // Compress the cells and get the compressed length
- encode_zip(write_buf, &len, m->cells, m->xs*m->ys);
-
- // Fill the map header
- if (strlen(name) > MAP_NAME_LENGTH) // It does not hurt to warn that there are maps with name longer than allowed.
- ShowWarning("Map name '%s' size '%d' is too long. Truncating to '%d'.\n", name, strlen(name), MAP_NAME_LENGTH);
- strncpy(info.name, name, MAP_NAME_LENGTH);
- info.xs = MakeShortLE(m->xs);
- info.ys = MakeShortLE(m->ys);
- info.len = MakeLongLE(len);
-
- // Append map header then compressed cells at the end of the file
- fseek(map_cache_fp, header.file_size, SEEK_SET);
- fwrite(&info, sizeof(struct map_info), 1, map_cache_fp);
- fwrite(write_buf, 1, len, map_cache_fp);
- header.file_size += sizeof(struct map_info) + len;
- header.map_count++;
-
- aFree(write_buf);
- aFree(m->cells);
-
- return;
+ struct map_info info;
+ unsigned long len;
+ unsigned char *write_buf;
+
+ // Create an output buffer twice as big as the uncompressed map... this way we're sure it fits
+ len = (unsigned long)m->xs*(unsigned long)m->ys*2;
+ write_buf = (unsigned char *)aMalloc(len);
+ // Compress the cells and get the compressed length
+ encode_zip(write_buf, &len, m->cells, m->xs*m->ys);
+
+ // Fill the map header
+ if (strlen(name) > MAP_NAME_LENGTH) // It does not hurt to warn that there are maps with name longer than allowed.
+ ShowWarning ("Map name '%s' size '%d' is too long. Truncating to '%d'.\n", name, strlen(name), MAP_NAME_LENGTH);
+ strncpy(info.name, name, MAP_NAME_LENGTH);
+ info.xs = MakeShortLE(m->xs);
+ info.ys = MakeShortLE(m->ys);
+ info.len = MakeLongLE(len);
+
+ // Append map header then compressed cells at the end of the file
+ fseek(map_cache_fp, header.file_size, SEEK_SET);
+ fwrite(&info, sizeof(struct map_info), 1, map_cache_fp);
+ fwrite(write_buf, 1, len, map_cache_fp);
+ header.file_size += sizeof(struct map_info) + len;
+ header.map_count++;
+
+ aFree(write_buf);
+ aFree(m->cells);
+
+ return;
}
// Checks whether a map is already is the cache
int find_map(char *name)
{
- int i;
- struct map_info info;
+ int i;
+ struct map_info info;
- fseek(map_cache_fp, sizeof(struct main_header), SEEK_SET);
+ fseek(map_cache_fp, sizeof(struct main_header), SEEK_SET);
- for (i = 0; i < header.map_count; i++) {
- if (fread(&info, sizeof(info), 1, map_cache_fp) != 1) printf("An error as occured in fread while reading map_cache\n");
- if (strcmp(name, info.name) == 0) // Map found
- return 1;
- else // Map not found, jump to the beginning of the next map info header
- fseek(map_cache_fp, GetLong((unsigned char *)&(info.len)), SEEK_CUR);
- }
+ for(i = 0; i < header.map_count; i++) {
+ if(fread(&info, sizeof(info), 1, map_cache_fp) != 1) printf("An error as occured in fread while reading map_cache\n");
+ if(strcmp(name, info.name) == 0) // Map found
+ return 1;
+ else // Map not found, jump to the beginning of the next map info header
+ fseek(map_cache_fp, GetLong((unsigned char *)&(info.len)), SEEK_CUR);
+ }
- return 0;
+ return 0;
}
// Cuts the extension from a map name
char *remove_extension(char *mapname)
{
- char *ptr, *ptr2;
- ptr = strchr(mapname, '.');
- if (ptr) { //Check and remove extension.
- while (ptr[1] && (ptr2 = strchr(ptr+1, '.')))
- ptr = ptr2; //Skip to the last dot.
- if (strcmp(ptr,".gat") == 0)
- *ptr = '\0'; //Remove extension.
- }
- return mapname;
+ char *ptr, *ptr2;
+ ptr = strchr(mapname, '.');
+ if (ptr) { //Check and remove extension.
+ while (ptr[1] && (ptr2 = strchr(ptr+1, '.')))
+ ptr = ptr2; //Skip to the last dot.
+ if (strcmp(ptr,".gat") == 0)
+ *ptr = '\0'; //Remove extension.
+ }
+ return mapname;
}
// Processes command-line arguments
void process_args(int argc, char *argv[])
{
- int i;
-
- for (i = 0; i < argc; i++) {
- if (strcmp(argv[i], "-grf") == 0) {
- if (++i < argc)
- strcpy(grf_list_file, argv[i]);
- } else if (strcmp(argv[i], "-list") == 0) {
- if (++i < argc)
- strcpy(map_list_file, argv[i]);
- } else if (strcmp(argv[i], "-cache") == 0) {
- if (++i < argc)
- strcpy(map_cache_file, argv[i]);
- } else if (strcmp(argv[i], "-rebuild") == 0)
- rebuild = 1;
- }
+ int i;
+
+ for(i = 0; i < argc; i++) {
+ if(strcmp(argv[i], "-grf") == 0) {
+ if(++i < argc)
+ strcpy(grf_list_file, argv[i]);
+ } else if(strcmp(argv[i], "-list") == 0) {
+ if(++i < argc)
+ strcpy(map_list_file, argv[i]);
+ } else if(strcmp(argv[i], "-cache") == 0) {
+ if(++i < argc)
+ strcpy(map_cache_file, argv[i]);
+ } else if(strcmp(argv[i], "-rebuild") == 0)
+ rebuild = 1;
+ }
}
-int do_init(int argc, char **argv)
+int do_init(int argc, char** argv)
{
- FILE *list;
- char line[1024];
- struct map_data map;
- char name[MAP_NAME_LENGTH_EXT];
+ FILE *list;
+ char line[1024];
+ struct map_data map;
+ char name[MAP_NAME_LENGTH_EXT];
- /* setup pre-defined, #define-dependant */
- sprintf(map_cache_file,"db/%s/map_cache.dat",
+ /* setup pre-defined, #define-dependant */
+ sprintf(map_cache_file,"db/%s/map_cache.dat",
#ifdef RENEWAL
- "re"
+ "re"
#else
- "pre-re"
+ "pre-re"
#endif
- );
-
- // Process the command-line arguments
- process_args(argc, argv);
-
- ShowStatus("Initializing grfio with %s\n", grf_list_file);
- grfio_init(grf_list_file);
-
- // Attempt to open the map cache file and force rebuild if not found
- ShowStatus("Opening map cache: %s\n", map_cache_file);
- if (!rebuild) {
- map_cache_fp = fopen(map_cache_file, "rb");
- if (map_cache_fp == NULL) {
- ShowNotice("Existing map cache not found, forcing rebuild mode\n");
- rebuild = 1;
- } else
- fclose(map_cache_fp);
- }
- if (rebuild)
- map_cache_fp = fopen(map_cache_file, "w+b");
- else
- map_cache_fp = fopen(map_cache_file, "r+b");
- if (map_cache_fp == NULL) {
- ShowError("Failure when opening map cache file %s\n", map_cache_file);
- exit(EXIT_FAILURE);
- }
-
- // Open the map list
- ShowStatus("Opening map list: %s\n", map_list_file);
- list = fopen(map_list_file, "r");
- if (list == NULL) {
- ShowError("Failure when opening maps list file %s\n", map_list_file);
- exit(EXIT_FAILURE);
- }
-
- // Initialize the main header
- if (rebuild) {
- header.file_size = sizeof(struct main_header);
- header.map_count = 0;
- } else {
- if (fread(&header, sizeof(struct main_header), 1, map_cache_fp) != 1) {
- printf("An error as occured while reading map_cache_fp \n");
- }
- header.file_size = GetULong((unsigned char *)&(header.file_size));
- header.map_count = GetUShort((unsigned char *)&(header.map_count));
- }
-
- // Read and process the map list
- while (fgets(line, sizeof(line), list)) {
- if (line[0] == '/' && line[1] == '/')
- continue;
-
- if (sscanf(line, "%15s", name) < 1)
- continue;
-
- if (strcmp("map:", name) == 0 && sscanf(line, "%*s %15s", name) < 1)
- continue;
-
- name[MAP_NAME_LENGTH_EXT-1] = '\0';
- remove_extension(name);
- if (find_map(name))
- ShowInfo("Map '"CL_WHITE"%s"CL_RESET"' already in cache.\n", name);
- else if (read_map(name, &map)) {
- cache_map(name, &map);
- ShowInfo("Map '"CL_WHITE"%s"CL_RESET"' successfully cached.\n", name);
- } else
- ShowError("Map '"CL_WHITE"%s"CL_RESET"' not found!\n", name);
-
- }
-
- ShowStatus("Closing map list: %s\n", map_list_file);
- fclose(list);
-
- // Write the main header and close the map cache
- ShowStatus("Closing map cache: %s\n", map_cache_file);
- fseek(map_cache_fp, 0, SEEK_SET);
- fwrite(&header, sizeof(struct main_header), 1, map_cache_fp);
- fclose(map_cache_fp);
-
- ShowStatus("Finalizing grfio\n");
- grfio_final();
-
- ShowInfo("%d maps now in cache\n", header.map_count);
-
- return 0;
+ );
+
+ // Process the command-line arguments
+ process_args(argc, argv);
+
+ ShowStatus("Initializing grfio with %s\n", grf_list_file);
+ grfio_init(grf_list_file);
+
+ // Attempt to open the map cache file and force rebuild if not found
+ ShowStatus("Opening map cache: %s\n", map_cache_file);
+ if(!rebuild) {
+ map_cache_fp = fopen(map_cache_file, "rb");
+ if(map_cache_fp == NULL) {
+ ShowNotice("Existing map cache not found, forcing rebuild mode\n");
+ rebuild = 1;
+ } else
+ fclose(map_cache_fp);
+ }
+ if(rebuild)
+ map_cache_fp = fopen(map_cache_file, "w+b");
+ else
+ map_cache_fp = fopen(map_cache_file, "r+b");
+ if(map_cache_fp == NULL) {
+ ShowError("Failure when opening map cache file %s\n", map_cache_file);
+ exit(EXIT_FAILURE);
+ }
+
+ // Open the map list
+ ShowStatus("Opening map list: %s\n", map_list_file);
+ list = fopen(map_list_file, "r");
+ if(list == NULL) {
+ ShowError("Failure when opening maps list file %s\n", map_list_file);
+ exit(EXIT_FAILURE);
+ }
+
+ // Initialize the main header
+ if(rebuild) {
+ header.file_size = sizeof(struct main_header);
+ header.map_count = 0;
+ } else {
+ if(fread(&header, sizeof(struct main_header), 1, map_cache_fp) != 1){ printf("An error as occured while reading map_cache_fp \n"); }
+ header.file_size = GetULong((unsigned char *)&(header.file_size));
+ header.map_count = GetUShort((unsigned char *)&(header.map_count));
+ }
+
+ // Read and process the map list
+ while(fgets(line, sizeof(line), list))
+ {
+ if(line[0] == '/' && line[1] == '/')
+ continue;
+
+ if(sscanf(line, "%15s", name) < 1)
+ continue;
+
+ if(strcmp("map:", name) == 0 && sscanf(line, "%*s %15s", name) < 1)
+ continue;
+
+ name[MAP_NAME_LENGTH_EXT-1] = '\0';
+ remove_extension(name);
+ if(find_map(name))
+ ShowInfo("Map '"CL_WHITE"%s"CL_RESET"' already in cache.\n", name);
+ else if(read_map(name, &map)) {
+ cache_map(name, &map);
+ ShowInfo("Map '"CL_WHITE"%s"CL_RESET"' successfully cached.\n", name);
+ } else
+ ShowError("Map '"CL_WHITE"%s"CL_RESET"' not found!\n", name);
+
+ }
+
+ ShowStatus("Closing map list: %s\n", map_list_file);
+ fclose(list);
+
+ // Write the main header and close the map cache
+ ShowStatus("Closing map cache: %s\n", map_cache_file);
+ fseek(map_cache_fp, 0, SEEK_SET);
+ fwrite(&header, sizeof(struct main_header), 1, map_cache_fp);
+ fclose(map_cache_fp);
+
+ ShowStatus("Finalizing grfio\n");
+ grfio_final();
+
+ ShowInfo("%d maps now in cache\n", header.map_count);
+
+ return 0;
}
void do_final(void)