summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--conf/map/battle/items.conf4
-rw-r--r--conf/map/logs.conf51
-rwxr-xr-xconfigure60
-rw-r--r--configure.ac39
-rw-r--r--db/constants.conf9
-rw-r--r--db/quest_db.conf8
-rw-r--r--db/re/skill_db.conf13
-rw-r--r--doc/constants.md6
-rw-r--r--doc/script_commands.txt49
-rw-r--r--src/char/char.c44
-rw-r--r--src/char/char.h2
-rw-r--r--src/common/mmo.h10
-rw-r--r--src/common/strlib.c1
-rw-r--r--src/map/battle.c24
-rw-r--r--src/map/battle.h2
-rw-r--r--src/map/clif.c12
-rw-r--r--src/map/packets.h428
-rw-r--r--src/map/packets_struct.h10
-rw-r--r--src/map/pc.c5
-rw-r--r--src/map/script.c109
-rw-r--r--src/map/skill.c10
-rw-r--r--src/plugins/HPMHooking/HPMHooking.Defs.inc4
-rw-r--r--src/plugins/HPMHooking/HPMHooking_char.Hooks.inc12
23 files changed, 769 insertions, 143 deletions
diff --git a/conf/map/battle/items.conf b/conf/map/battle/items.conf
index 8ff2cbb3b..3c9ba71e9 100644
--- a/conf/map/battle/items.conf
+++ b/conf/map/battle/items.conf
@@ -114,3 +114,7 @@ item_enabled_npc: true
// 2 : disabled equipments are nullify, disabled cards will caused the equipment to unequip
// 3 : disabled equipments are unequip, disabled cards will caused the equipment to unequip (1+2)
unequip_restricted_equipment: 0
+
+// When unequip a bow with arrow equipped, it also unequip the arrow?
+// Default: true (Official behavior, applies only in Renewal)
+bow_unequip_arrow: true
diff --git a/conf/map/logs.conf b/conf/map/logs.conf
index aa4e16e95..4f3a8a4db 100644
--- a/conf/map/logs.conf
+++ b/conf/map/logs.conf
@@ -34,29 +34,38 @@
map_log: {
// Enable Logs? (Note 3)
- // 0x00000 - Don't log at all
- // 0x00001 - (T) Log trades
- // 0x00002 - (V) Log vending transactions
- // 0x00004 - (P) Log items drop/picked by players
- // 0x00008 - (L) Log items drop/looted by monsters
- // 0x00010 - (S) Log NPC transactions (buy/sell)
- // 0x00020 - (N) Log Script transactions (items deleted/acquired through quests)
- // 0x00040 - (D) Log items stolen from mobs (Steal/Gank)
- // 0x00080 - (C) Log player-used items (consumables/pet&hom&merc food/items used for skills&attacks)
- // 0x00100 - (O) Log produced/ingredient items
- // 0x00200 - (U) Log MVP prize items
- // 0x00400 - (A) Log player created/deleted items (through @/# commands)
- // 0x00800 - (R) Log items placed/retrieved from storage.
- // 0x01000 - (G) Log items placed/retrieved from guild storage.
- // 0x02000 - (E) Log mail system transactions.
- // 0x04000 - (I) Log auction system transactions.
- // 0x08000 - (B) Log buying store transactions
- // 0x20000 - (K) Log account bank transactions
- // 0x10000 - (X) Log all other transactions (rentals expiring/inserting cards/items removed by item_check/
- // rings deleted by divorce/pet egg (un)hatching/pet armor (un)equipping/Weapon Refine skill/Remove Trap skill)
+ // 0x0000000 - Don't log at all
+ // 0x0000001 - (T) Log trades
+ // 0x0000002 - (V) Log vending transactions
+ // 0x0000004 - (P) Log items drop/picked by players
+ // 0x0000008 - (L) Log items drop/looted by monsters
+ // 0x0000010 - (S) Log NPC transactions (buy/sell)
+ // 0x0000020 - (N) Log Script transactions (items deleted/acquired through quests)
+ // 0x0000040 - (D) Log items stolen from mobs (Steal/Gank)
+ // 0x0000080 - (C) Log player-used items (consumables/pet&hom&merc food/items used for skills&attacks)
+ // 0x0000100 - (O) Log produced/ingredient items
+ // 0x0000200 - (U) Log MVP prize items
+ // 0x0000400 - (A) Log player created/deleted items (through @/# commands)
+ // 0x0000800 - (R) Log items placed/retrieved from storage.
+ // 0x0001000 - (G) Log items placed/retrieved from guild storage.
+ // 0x0002000 - (E) Log mail system transactions.
+ // 0x0004000 - (I) Log auction system transactions.
+ // 0x0008000 - (B) Log buying store transactions
+ // 0x0010000 - (X) Log other transactions
+ // 0x0020000 - (K) Log account bank transactions
+ // 0x0040000 - (Y) Divorce
+ // 0x0080000 - (Z) Roulette
+ // 0x0100000 - (W) Rental
+ // 0x0200000 - (Q) Card
+ // 0x0400000 - (J) Invalid in inventory
+ // 0x0800000 - (H) Invalid in cart
+ // 0x1000000 - (@) Egg
+ // 0x2000000 - (0) Quest
+ // 0x4000000 - (1) Skill
+ // 0x8000000 - (2) Refine
// Example: Log trades+vending+script items+created items: 1+2+32+1024 = 1059
// Please note that moving items from inventory to cart and back is not logged by design.
- enable: 0xFFFFF
+ enable: 0xFFFFFFF
// Logging files/tables
// Following settings specify where to log to. If 'use_sql' is
diff --git a/configure b/configure
index 46853a217..9e5c01851 100755
--- a/configure
+++ b/configure
@@ -1,5 +1,5 @@
#! /bin/sh
-# From configure.ac b947fde.
+# From configure.ac b7b45b7c3.
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69.
#
@@ -5153,17 +5153,19 @@ rm -f core conftest.err conftest.$ac_objext \
if test "$enable_lto" != "no" ; then
OLD_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS -flto"
+ CFLAGS="$CFLAGS -flto -ffat-lto-objects -Werror"
OLD_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS -flto"
+ LDFLAGS="$LDFLAGS -flto -ffat-lto-objects"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -flto" >&5
-$as_echo_n "checking whether $CC supports -flto... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -flto -ffat-lto-objects" >&5
+$as_echo_n "checking whether $CC supports -flto -ffat-lto-objects... " >&6; }
if test "$cross_compiling" = yes; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: guessing no" >&5
$as_echo "guessing no" >&6; }
+ CFLAGS="$OLD_CFLAGS"
+ LDFLAGS="$OLD_LDFLAGS"
else
@@ -5171,6 +5173,8 @@ else
/* end confdefs.h. */
int main(int argc, char **argv){
+ (void)argc;
+ (void)argv;
return 0;
}
@@ -5179,13 +5183,53 @@ if ac_fn_c_try_run "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
+ CFLAGS="$OLD_CFLAGS -flto -ffat-lto-objects"
+ LDFLAGS="$OLD_LDFLAGS -flto -ffat-lto-objects"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
- CFLAGS="$OLD_CFLAGS"
- LDFLAGS="$OLD_LDFLAGS"
+ CFLAGS="$OLD_CFLAGS -flto"
+ LDFLAGS="$OLD_LDFLAGS -flto"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -flto" >&5
+$as_echo_n "checking whether $CC supports -flto... " >&6; }
+ if test "$cross_compiling" = yes; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: guessing no" >&5
+$as_echo "guessing no" >&6; }
+ CFLAGS="$OLD_CFLAGS"
+ LDFLAGS="$OLD_LDFLAGS"
+
+
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ int main(int argc, char **argv){
+ (void)argc;
+ (void)argv;
+ return 0;
+ }
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ CFLAGS="$OLD_CFLAGS"
+ LDFLAGS="$OLD_LDFLAGS"
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
@@ -8346,7 +8390,7 @@ Linux* )
LIBS="$LIBS -ldl"
;;
FreeBSD*)
- CPPFLAGS="$CPPFLAGS -D__FREEBSD__"
+ CPPFLAGS="$CPPFLAGS -D__FREEBSD__ -fvisibility=hidden"
;;
NetBSD*)
CPPFLAGS="$CPPFLAGS -D__NETBSD__"
diff --git a/configure.ac b/configure.ac
index efe1f802e..6fef4ee4e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -726,28 +726,57 @@ AC_LINK_IFELSE(
if test "$enable_lto" != "no" ; then
OLD_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS -flto"
+ CFLAGS="$CFLAGS -flto -ffat-lto-objects -Werror"
OLD_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS -flto"
+ LDFLAGS="$LDFLAGS -flto -ffat-lto-objects"
- AC_MSG_CHECKING([whether $CC supports -flto])
+ AC_MSG_CHECKING([whether $CC supports -flto -ffat-lto-objects])
AC_RUN_IFELSE(
[AC_LANG_SOURCE([
int main(int argc, char **argv){
+ (void)argc;
+ (void)argv;
return 0;
}
])],
[
AC_MSG_RESULT([yes])
+ CFLAGS="$OLD_CFLAGS -flto -ffat-lto-objects"
+ LDFLAGS="$OLD_LDFLAGS -flto -ffat-lto-objects"
],
[
AC_MSG_RESULT([no])
- CFLAGS="$OLD_CFLAGS"
- LDFLAGS="$OLD_LDFLAGS"
+ CFLAGS="$OLD_CFLAGS -flto"
+ LDFLAGS="$OLD_LDFLAGS -flto"
+ AC_MSG_CHECKING([whether $CC supports -flto])
+ AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([
+ int main(int argc, char **argv){
+ (void)argc;
+ (void)argv;
+ return 0;
+ }
+ ])],
+ [
+ AC_MSG_RESULT([yes])
+ ],
+ [
+ AC_MSG_RESULT([no])
+ CFLAGS="$OLD_CFLAGS"
+ LDFLAGS="$OLD_LDFLAGS"
+ ],
+ [
+ AC_MSG_RESULT([guessing no])
+ CFLAGS="$OLD_CFLAGS"
+ LDFLAGS="$OLD_LDFLAGS"
+ ]
+ )
],
[
AC_MSG_RESULT([guessing no])
+ CFLAGS="$OLD_CFLAGS"
+ LDFLAGS="$OLD_LDFLAGS"
]
)
fi
diff --git a/db/constants.conf b/db/constants.conf
index 09c0fa9e4..79530e7d1 100644
--- a/db/constants.conf
+++ b/db/constants.conf
@@ -3664,14 +3664,14 @@ constants_db: {
PC_PARTY: 1
PC_GUILD: 2
PC_MAP: 3
-
+
comment__: "strnpcinfo"
NPC_NAME: 0
NPC_NAME_VISIBLE: 1
NPC_NAME_HIDDEN: 2
NPC_NAME_UNIQUE: 3
NPC_MAP: 4
-
+
comment__: "getcharid"
CHAR_ID_CHAR: 0
CHAR_ID_PARTY: 1
@@ -3709,6 +3709,11 @@ constants_db: {
GETTIME_YEAR: 7
GETTIME_DAYOFYEAR: 8
+ comment__: "gettimer"
+ TIMER_COUNT: 0
+ TIMER_TICK_NEXT: 1
+ TIMER_TICK_LAST: 2
+
comment__: "unit types"
UNITTYPE_PC: 0
UNITTYPE_NPC: 1
diff --git a/db/quest_db.conf b/db/quest_db.conf
index 98a7ee190..49952d94b 100644
--- a/db/quest_db.conf
+++ b/db/quest_db.conf
@@ -9040,6 +9040,14 @@ quest_db: (
Name: "Shortage of Roast Beef"
},
{
+ Id: 11204
+ Name: "Mora Village..."
+},
+{
+ Id: 11205
+ Name: "Pauchon's Friend"
+},
+{
Id: 11206
Name: "Quick Delivery Yoneseu"
},
diff --git a/db/re/skill_db.conf b/db/re/skill_db.conf
index 03d35b687..ffc5e4e52 100644
--- a/db/re/skill_db.conf
+++ b/db/re/skill_db.conf
@@ -33989,18 +33989,7 @@ skill_db: (
NoDamage: true
}
NumberOfHits: 0
- SkillData2: {
- Lv1: 60000
- Lv2: 70000
- Lv3: 80000
- Lv4: 90000
- Lv5: 129000
- Lv6: 129000
- Lv7: 129000
- Lv8: 129000
- Lv9: 129000
- Lv10: 129000
- }
+ CoolDown: 1000
FixedCastTime: -1
Requirements: {
SPCost: 10
diff --git a/doc/constants.md b/doc/constants.md
index 208d6dad2..22d285412 100644
--- a/doc/constants.md
+++ b/doc/constants.md
@@ -3624,6 +3624,12 @@
- `GETTIME_YEAR`: 7
- `GETTIME_DAYOFYEAR`: 8
+### gettimer
+
+- `TIMER_COUNT`: 0
+- `TIMER_TICK_NEXT`: 1
+- `TIMER_TICK_LAST`: 2
+
### unit types
- `UNITTYPE_PC`: 0
diff --git a/doc/script_commands.txt b/doc/script_commands.txt
index b202f1b6b..581ec182c 100644
--- a/doc/script_commands.txt
+++ b/doc/script_commands.txt
@@ -6479,17 +6479,13 @@ Size is 0 = normal 1 = small 2 = big.
---------------------------------------
*addtimer(<ticks>, "NPC::OnLabel"{, <account id>})
-*deltimer("NPC::OnLabel"{, <account id>})
-*addtimercount("NPC::OnLabel", <ticks>{, <account id>})
-These commands will create, destroy, and delay a countdown timer -
-addtimer() to create, deltimer() to destroy and addtimercount() to delay
-it by the specified number of ticks. For all three cases, the event label
-given is the identifier of that timer. The timer runs on the character
-object that is attached to the script, and can have multiple instances.
-If <acccount id> is passed, this player will be used instead.
-When the label is run, it is run as if the player that the timer runs on
-has clicked the NPC.
+This command will create a countdown timer.
+The event label given is the identifier of that timer.
+The timer runs on the character object that is attached to the script,
+and can have multiple instances. If <acccount id> is passed, this player
+will be used instead. When the label is run, it is run as if the player
+that the timer runs on has clicked the NPC.
When this timer runs out, a new execution thread will start in the
specified NPC object at the specified label.
@@ -6513,6 +6509,39 @@ On5secs:
---------------------------------------
+*deltimer("NPC::OnLabel"{, <account id>})
+
+Deletes timers created by addtimer() that matches the given event
+label. Refer to addtimer() for additional information.
+
+---------------------------------------
+
+*addtimercount("NPC::OnLabel", <ticks>{, <account id>})
+
+Delays a timer that was created with addtimer() by <ticks> ticks
+if it matches the given event label. Refer to addtimer() for additional
+information.
+
+---------------------------------------
+
+*gettimer(<type>{, <account id>{, "<event>"}})
+
+Returns informations on timers that were created by addtimer().
+
+valid <type> for gettimer() are:
+
+(0) TIMER_COUNT
+ Will return the total number of timers for the specified or
+ attached player. Can be filtered by <event>.
+(1) TIMER_TICK_NEXT
+ Will return the number of ticks until the next timer runs
+ for the specified or attached player. Can be filtered by <event>.
+(2) TIMER_TICK_LAST
+ Will return the number of ticks until the last timer runs
+ for the specified or attached player. Can be filtered by <event>.
+
+---------------------------------------
+
*initnpctimer({ "<NPC name>" {, <Attach Flag>} } |
{ "<NPC name>" | <Attach Flag> })
*stopnpctimer({ "<NPC name>" {, <Detach Flag>} } |
diff --git a/src/char/char.c b/src/char/char.c
index 9314e8c81..f47a8cc3c 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -1544,7 +1544,7 @@ int char_check_char_name(char * name, char * esc_name)
* -5: 'Symbols in Character Names are forbidden'
* char_id: Success
**/
-int char_make_new_char_sql(struct char_session_data *sd, const char *name_, int str, int agi, int vit, int int_, int dex, int luk, int slot, int hair_color, int hair_style, int16 starting_class)
+int char_make_new_char_sql(struct char_session_data *sd, const char *name_, int str, int agi, int vit, int int_, int dex, int luk, int slot, int hair_color, int hair_style, int16 starting_class, uint8 sex)
{
char name[NAME_LENGTH];
char esc_name[NAME_LENGTH*2+1];
@@ -1587,17 +1587,17 @@ int char_make_new_char_sql(struct char_session_data *sd, const char *name_, int
if( sd->found_char[slot] != -1 )
return -2; /* character account limit exceeded */
+
#if PACKETVER >= 20120307
// Insert the new char entry to the database
if (SQL_ERROR == SQL->Query(inter->sql_handle, "INSERT INTO `%s` (`account_id`, `char_num`, `name`, `class`, `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', '%d', '%s', '%d', '%d', '%s', '%d', '%d')",
+ "`max_sp`, `sp`, `hair`, `hair_color`, `last_map`, `last_x`, `last_y`, `save_map`, `save_x`, `save_y`, `sex`) VALUES ("
+ "'%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d','%d', '%d','%d', '%d', '%s', '%d', '%d', '%s', '%d', '%d', '%c')",
char_db, sd->account_id , slot, esc_name, starting_class, 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(inter->sql_handle);
- return -2; //No, stop the procedure!
+ mapindex_id2name(start_point.map), start_point.x, start_point.y, mapindex_id2name(start_point.map), start_point.x, start_point.y, sex)) {
+ Sql_ShowDebug(inter->sql_handle);
+ return -2; //No, stop the procedure!
}
#else
//Insert the new char entry to the database
@@ -1647,7 +1647,7 @@ int char_make_new_char_sql(struct char_session_data *sd, const char *name_, int
}
}
- ShowInfo("Created char: account: %d, char: %d, slot: %d, name: %s\n", sd->account_id, char_id, slot, name);
+ ShowInfo("Created char: account: %d, char: %d, slot: %d, name: %s, sex: %c\n", sd->account_id, char_id, slot, name, sex);
return char_id;
}
@@ -4633,13 +4633,25 @@ void char_parse_char_create_new_char(int fd, struct char_session_data* sd)
//turn character creation on/off [Kevin]
result = -2;
} else {
- #if PACKETVER >= 20151001
- result = chr->make_new_char_sql(sd, RFIFOP(fd,2), 1, 1, 1, 1, 1, 1, RFIFOB(fd,26), RFIFOW(fd,27), RFIFOW(fd,29), RFIFOW(fd, 31));
- #elif PACKETVER >= 20120307
- result = chr->make_new_char_sql(sd, RFIFOP(fd,2), 1, 1, 1, 1, 1, 1, RFIFOB(fd,26), RFIFOW(fd,27), RFIFOW(fd,29), JOB_NOVICE);
- #else
- result = chr->make_new_char_sql(sd, 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), JOB_NOVICE);
- #endif
+#if PACKETVER >= 20151001
+ uint8 sex = RFIFOB(fd, 35);
+
+ switch (sex) {
+ case SEX_FEMALE:
+ sex = 'F';
+ break;
+ case SEX_MALE:
+ sex = 'M';
+ break;
+ default:
+ return -2; // Char Creation Denied
+ }
+ result = chr->make_new_char_sql(sd, RFIFOP(fd, 2), 1, 1, 1, 1, 1, 1, RFIFOB(fd, 26), RFIFOW(fd, 27), RFIFOW(fd, 29), RFIFOW(fd, 31), sex);
+#elif PACKETVER >= 20120307
+ result = chr->make_new_char_sql(sd, RFIFOP(fd, 2), 1, 1, 1, 1, 1, 1, RFIFOB(fd, 26), RFIFOW(fd, 27), RFIFOW(fd, 29), JOB_NOVICE, 'U');
+#else
+ result = chr->make_new_char_sql(sd, 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), JOB_NOVICE, 'U');
+#endif
}
//'Charname already exists' (-1), 'Char creation denied' (-2) and 'You are underaged' (-3)
@@ -5042,7 +5054,7 @@ int char_parse_char(int fd)
// S 0a39 <name>.24B <slot>.B <hair color>.W <hair style>.W <starting job class ID>.W <Unknown>.(W or 2 B's)??? <sex>.B
case 0xa39:
{
- FIFOSD_CHECK(36);
+ FIFOSD_CHECK(36);
#elif PACKETVER >= 20120307
// S 0970 <name>.24B <slot>.B <hair color>.W <hair style>.W
case 0x970:
diff --git a/src/char/char.h b/src/char/char.h
index d7bc96e13..499b633f7 100644
--- a/src/char/char.h
+++ b/src/char/char.h
@@ -147,7 +147,7 @@ struct char_interface {
bool (*char_slotchange) (struct char_session_data *sd, int fd, unsigned short from, unsigned short to);
int (*rename_char_sql) (struct char_session_data *sd, int char_id);
int (*check_char_name) (char * name, char * esc_name);
- int (*make_new_char_sql) (struct char_session_data *sd, const char *name_, int str, int agi, int vit, int int_, int dex, int luk, int slot, int hair_color, int hair_style, short starting_job);
+ int (*make_new_char_sql) (struct char_session_data *sd, const char *name_, int str, int agi, int vit, int int_, int dex, int luk, int slot, int hair_color, int hair_style, short starting_job, uint8 sex);
int (*divorce_char_sql) (int partner_id1, int partner_id2);
int (*count_users) (void);
int (*mmo_char_tobuf) (uint8* buffer, struct mmo_charstatus* p);
diff --git a/src/common/mmo.h b/src/common/mmo.h
index 9c29b8a0e..16bc978bf 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -114,7 +114,15 @@
#define MAX_INVENTORY 100
//Max number of characters per account. Note that changing this setting alone is not enough if the client is not hexed to support more characters as well.
-#define MAX_CHARS 9
+#if PACKETVER >= 20100413
+#ifndef MAX_CHARS
+ #define MAX_CHARS 12
+#endif
+#else
+#ifndef MAX_CHARS
+ #define MAX_CHARS 9
+#endif
+#endif
//Number of slots carded equipment can have. Never set to less than 4 as they are also used to keep the data of forged items/equipment. [Skotlex]
//Note: The client seems unable to receive data for more than 4 slots due to all related packets having a fixed size.
#define MAX_SLOTS 4
diff --git a/src/common/strlib.c b/src/common/strlib.c
index 75ce2a272..df8093456 100644
--- a/src/common/strlib.c
+++ b/src/common/strlib.c
@@ -344,6 +344,7 @@ int strlib_config_switch(const char *str) {
}
/// strncpy that always null-terminates the string
+/// @remark this function will read at most `n` - 1 bytes from `src` (from 0 to `n` - 2)
char *strlib_safestrncpy(char *dst, const char *src, size_t n)
{
if( n > 0 )
diff --git a/src/map/battle.c b/src/map/battle.c
index 77bb99730..827042cce 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -6814,14 +6814,23 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
if( flag&(BCT_PARTY|BCT_ENEMY) ) {
int s_party = status->get_party_id(s_bl);
int s_guild = status->get_guild_id(s_bl);
-
- if( s_party && s_party == status->get_party_id(t_bl)
- && !(map->list[m].flag.pvp && map->list[m].flag.pvp_noparty)
- && !(map_flag_gvg(m) && map->list[m].flag.gvg_noparty && !( s_guild && s_guild == status->get_guild_id(t_bl) ))
- && (!map->list[m].flag.battleground || sbg_id == tbg_id) )
- state |= BCT_PARTY;
- else
+ int t_guild = status->get_guild_id(t_bl);
+
+ if (s_party && s_party == status->get_party_id(t_bl)) {
+ if (map_flag_gvg(m) && map->list[m].flag.gvg_noparty && !(s_guild && s_guild == t_guild)) {
+ if (t_guild && guild->isallied(s_guild, t_guild))
+ state |= BCT_PARTY;
+ else
+ state |= flag&BCT_ENEMY ? BCT_ENEMY : BCT_PARTY;
+ } else if (!(map->list[m].flag.pvp && map->list[m].flag.pvp_noparty)
+ && (!map->list[m].flag.battleground || sbg_id == tbg_id)) {
+ state |= BCT_PARTY;
+ } else {
+ state |= BCT_ENEMY;
+ }
+ } else {
state |= BCT_ENEMY;
+ }
}
if( flag&(BCT_GUILD|BCT_ENEMY) ) {
int s_guild = status->get_guild_id(s_bl);
@@ -7320,6 +7329,7 @@ static const struct battle_data {
{ "save_body_style", &battle_config.save_body_style, 0, 0, 1, },
{ "player_warp_keep_direction", &battle_config.player_warp_keep_direction, 0, 0, 1, },
{ "atcommand_levelup_events", &battle_config.atcommand_levelup_events, 0, 0, 1, },
+ { "bow_unequip_arrow", &battle_config.bow_unequip_arrow, 1, 0, 1, },
{ "max_summoner_parameter", &battle_config.max_summoner_parameter, 120, 10, 10000, },
{ "mvp_exp_reward_message", &battle_config.mvp_exp_reward_message, 0, 0, 1, },
};
diff --git a/src/map/battle.h b/src/map/battle.h
index b7bde1aa9..4665847ff 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -545,6 +545,8 @@ struct Battle_Config {
int player_warp_keep_direction;
int atcommand_levelup_events; // Enable atcommands trigger level up events for NPCs
+
+ int bow_unequip_arrow;
int max_summoner_parameter; // Summoner Max Stats
int mvp_exp_reward_message;
diff --git a/src/map/clif.c b/src/map/clif.c
index 597a890ae..63d7d680c 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -677,7 +677,8 @@ void clif_authok(struct map_session_data *sd)
#if PACKETVER >= 20080102
p.font = sd->status.font;
#endif
-#if PACKETVER >= 20141016
+// Some clients smaller than 20160330 cant be tested [4144]
+#if PACKETVER >= 20141016 && PACKETVER < 20160330
p.sex = sd->status.sex;
#endif
clif->send(&p,sizeof(p),&sd->bl,SELF);
@@ -11626,7 +11627,12 @@ void clif_parse_NpcStringInput(int fd, struct map_session_data* sd) __attribute_
/// 01d5 <packet len>.W <npc id>.L <string>.?B
void clif_parse_NpcStringInput(int fd, struct map_session_data* sd)
{
- int message_len = RFIFOW(fd,2)-8;
+// [4144] can't confirm exact client version. At least >= correct for 20150513
+#if PACKETVER >= 20151029
+ int message_len = RFIFOW(fd, 2) - 7;
+#else
+ int message_len = RFIFOW(fd, 2) - 8;
+#endif
int npcid = RFIFOL(fd,4);
const char *message = RFIFOP(fd,8);
@@ -16233,7 +16239,7 @@ void clif_bg_hp(struct map_session_data *sd)
{
unsigned char buf[34];
-// packet version can be wrong, because inconsistend data in other servers.
+// packet version can be wrong, because inconsistend data in other servers. From packets table it start from 20140312 [4144]
#if PACKETVER < 20140613
const int cmd = 0x2e0;
nullpo_retv(sd);
diff --git a/src/map/packets.h b/src/map/packets.h
index c622cb89d..61289d3b1 100644
--- a/src/map/packets.h
+++ b/src/map/packets.h
@@ -2617,6 +2617,14 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x0896,8,clif->pDull); // CZ_JOIN_BATTLE_FIELD
#endif
+// 2013-10-30aRagexe
+#if PACKETVER >= 20131030
+// new packets
+ packet(0x09de,-1); // ZC_WHISPER02
+ packet(0x09df,7); // ZC_ACK_WHISPER02
+ packet(0x09e0,-1); // SC_LOGIN_ANSWER_WITH_ID
+#endif
+
// 2013-12-18bRagexe - Yommy
#if PACKETVER >= 20131218
packet(0x0369,7,clif->pActionRequest,2,6);
@@ -2687,7 +2695,6 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x08A4,36,clif->pStoragePassword,0);
packet(0x0363,8,clif->pDull); // CZ_JOIN_BATTLE_FIELD
packet(0x0436,4,clif->pDull); // CZ_GANGSI_RANK
- packet(0x09df,7);
packet(0x09cb,17);
#endif
@@ -2760,6 +2767,47 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x0865,36,clif->pStoragePassword,0);
#endif
+// 2014-01-15cRagexeRE
+#if PACKETVER >= 20140115
+// new packets
+ packet(0x09f1,10,clif->pDull/*,XXX*/); // CZ_REQ_ZENY_FROM_RODEX
+ packet(0x09f2,3); // ZC_ACK_ZENY_FROM_RODEX
+ packet(0x09f3,15,clif->pDull/*,XXX*/); // CZ_REQ_ITEM_FROM_RODEX
+ packet(0x09f4,12); // ZC_ACK_ITEM_FROM_RODEX
+ packet(0x09f8,-1); // ZC_ALL_QUEST_LIST3
+ packet(0x09f9,131); // ZC_ADD_QUEST_EX
+ packet(0x09fa,-1); // ZC_UPDATE_MISSION_HUNT_EX
+// changed packet sizes
+ packet(0x09eb,-1); // ZC_ACK_READ_RODEX
+#endif
+
+// 2014-01-22aRagexeRE
+#if PACKETVER >= 20140122
+// new packets
+ packet(0x09fb,-1,clif->pDull/*,XXX*/); // CZ_PET_EVOLUTION
+ packet(0x09fc,6); // ZC_PET_EVOLUTION_RESULT
+ packet(0x09fd,-1); // ZC_NOTIFY_MOVEENTRY11
+ packet(0x09fe,-1); // ZC_NOTIFY_NEWENTRY11
+ packet(0x09ff,-1); // ZC_NOTIFY_STANDENTRY11
+// changed packet sizes
+ packet(0x09f9,143); // ZC_ADD_QUEST_EX
+#endif
+
+// 2014-01-29bRagexeRE
+#if PACKETVER >= 20140129
+// new packets
+ packet(0x0a00,269); // ZC_SHORTCUT_KEY_LIST_V3
+ packet(0x0a01,3,clif->pHotkeyRowShift,2); // CZ_SHORTCUTKEYBAR_ROTATE
+// Warning hercules using this packets for items manipulation. In RagexeRE from 20140129 and before 20140305, this actions broken.
+#ifdef PACKETVER_RE
+// changed packet sizes
+ packet(0x01c4,43); // ZC_ADD_ITEM_TO_STORE2
+ packet(0x01c5,43); // ZC_ADD_ITEM_TO_CART2
+ packet(0x080f,41); // ZC_ADD_EXCHANGE_ITEM2
+ packet(0x0990,52); // ZC_ITEM_PICKUP_ACK_V5
+#endif // PACKETVER_RE
+#endif
+
// 2014-02-05bRagexe - Themon
#if PACKETVER >= 20140205
packet(0x0369,7,clif->pActionRequest,2,6);
@@ -2791,7 +2839,36 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x0938,36,clif->pStoragePassword,0);
packet(0x0363,8,clif->pDull); // CZ_JOIN_BATTLE_FIELD
packet(0x0436,4,clif->pDull); // CZ_GANGSI_RANK
- packet(0x09DF,7);
+#endif
+
+// 2014-02-12aRagexeRE
+#if PACKETVER >= 20140212
+// new packets
+ packet(0x0a02,4); // ZC_DRESSROOM_OPEN
+// changed packet sizes
+ packet(0x09e8,11,clif->pDull/*,XXX*/); // CZ_OPEN_RODEXBOX
+#endif
+
+// 2014-02-19aRagexeRE
+#if PACKETVER >= 20140219
+// Warning hercules using this packets for items manipulation. In RagexeRE from 20140129 and before 20140305, this actions broken.
+#ifdef PACKETVER_RE
+// changed packet sizes
+ packet(0x01c4,53); // ZC_ADD_ITEM_TO_STORE2
+ packet(0x01c5,53); // ZC_ADD_ITEM_TO_CART2
+ packet(0x080f,51); // ZC_ADD_EXCHANGE_ITEM2
+ packet(0x0990,62); // ZC_ITEM_PICKUP_ACK_V5
+#endif // PACKETVER_RE
+#endif
+
+// 2014-02-26aRagexeRE
+#if PACKETVER >= 20140226
+// new packets
+ packet(0x0a03,14,clif->pDull/*,XXX*/); // CZ_REQ_CANCEL_WRITE_RODEX
+ packet(0x0a04,11,clif->pDull/*,XXX*/); // CZ_REQ_ADD_ITEM_RODEX
+ packet(0x0a05,6); // ZC_ACK_ADD_ITEM_RODEX
+ packet(0x0a06,5,clif->pDull/*,XXX*/); // CZ_REQ_REMOVE_RODEX_ITEM
+// changed packet sizes
#endif
// 2014-03-05bRagexe - Themon
@@ -2825,7 +2902,49 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x095e,36,clif->pStoragePassword,0);
packet(0x0363,8,clif->pDull); // CZ_JOIN_BATTLE_FIELD
packet(0x0878,4,clif->pDull); // CZ_GANGSI_RANK
- packet(0x09DF,7);
+#endif
+
+// 2014-03-05aRagexeRE
+#if PACKETVER >= 20140305
+// new packets
+ packet(0x0a07,4); // ZC_ACK_REMOVE_RODEX_ITEM
+ packet(0x0a08,5,clif->pDull/*,XXX*/); // CZ_REQ_OPEN_WRITE_RODEX
+ packet(0x0a09,50); // ZC_ADD_EXCHANGE_ITEM3
+ packet(0x0a0a,52); // ZC_ADD_ITEM_TO_STORE3
+ packet(0x0a0b,52); // ZC_ADD_ITEM_TO_CART3
+ packet(0x0a0c,61); // ZC_ITEM_PICKUP_ACK_V6
+ packet(0x0a0d,4); // ZC_INVENTORY_ITEMLIST_EQUIP_V6
+// changed packet sizes
+ packet(0x01c4,22); // ZC_ADD_ITEM_TO_STORE2
+ packet(0x01c5,22); // ZC_ADD_ITEM_TO_CART2
+ packet(0x080f,20); // ZC_ADD_EXCHANGE_ITEM2
+ packet(0x0990,31); // ZC_ITEM_PICKUP_ACK_V5
+ packet(0x09f3,10,clif->pDull/*,XXX*/); // CZ_REQ_ITEM_FROM_RODEX
+ packet(0x09f4,3); // ZC_ACK_ITEM_FROM_RODEX
+#endif
+
+// 2014-03-12bRagexeRE
+#if PACKETVER >= 20140312
+// new packets
+ packet(0x0a0e,14); // ZC_BATTLEFIELD_NOTIFY_HP2
+// changed packet sizes
+ packet(0x0a09,45); // ZC_ADD_EXCHANGE_ITEM3
+ packet(0x0a0a,47); // ZC_ADD_ITEM_TO_STORE3
+ packet(0x0a0b,47); // ZC_ADD_ITEM_TO_CART3
+ packet(0x0a0c,56); // ZC_ITEM_PICKUP_ACK_V6
+ packet(0x0a0d,-1); // ZC_INVENTORY_ITEMLIST_EQUIP_V6
+#endif
+
+// 2014-03-26cRagexeRE
+#if PACKETVER >= 20140326
+// changed packet sizes
+ packet(0x09f1,11,clif->pDull/*,XXX*/); // CZ_REQ_ZENY_FROM_RODEX
+ packet(0x09f2,4); // ZC_ACK_ZENY_FROM_RODEX
+ packet(0x09f3,11,clif->pDull/*,XXX*/); // CZ_REQ_ITEM_FROM_RODEX
+ packet(0x09f4,4); // ZC_ACK_ITEM_FROM_RODEX
+ packet(0x0a03,2,clif->pDull/*,XXX*/); // CZ_REQ_CANCEL_WRITE_RODEX
+ packet(0x0a07,6); // ZC_ACK_REMOVE_RODEX_ITEM
+ packet(0x0a08,7,clif->pDull/*,XXX*/); // CZ_REQ_OPEN_WRITE_RODEX
#endif
// 2014-04-02gRagexe - Themon
@@ -2859,7 +2978,22 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x0926,36,clif->pStoragePassword,0);
packet(0x088c,4,clif->pDull); // CZ_GANGSI_RANK
packet(0x094c,8,clif->pDull); // CZ_JOIN_BATTLE_FIELD
- packet(0x09DF,7);
+#endif
+
+// 2014-04-02eRagexeRE
+#if PACKETVER >= 20140402
+// new packets
+ packet(0x0a0f,-1); // ZC_CART_ITEMLIST_EQUIP_V6
+ packet(0x0a10,-1); // ZC_STORE_ITEMLIST_EQUIP_V6
+ packet(0x0a11,-1); // ZC_GUILDSTORAGE_ITEMLIST_EQUIP_V6
+// changed packet sizes
+#endif
+
+// 2014-04-09aRagexeRE
+#if PACKETVER >= 20140409
+// changed packet sizes
+ packet(0x09f2,12); // ZC_ACK_ZENY_FROM_RODEX
+ packet(0x09f4,12); // ZC_ACK_ITEM_FROM_RODEX
#endif
// 2014-04-16aRagexe - Themon
@@ -2893,18 +3027,155 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x095C,36,clif->pStoragePassword,0);
packet(0x0363,8,clif->pDull); // CZ_JOIN_BATTLE_FIELD
packet(0x0436,4,clif->pDull); // CZ_GANGSI_RANK
- packet(0x09DF,7);
#endif
-#if PACKETVER >= 20140613
-// no shuffle packets
- packet(0x0a0e,14);
+// 2014-04-16aRagexeRE
+#if PACKETVER >= 20140416
+// new packets
+ packet(0x0a04,6,clif->pDull/*,XXX*/); // CZ_REQ_ADD_ITEM_RODEX
+ packet(0x0a12,27); // ZC_ACK_OPEN_WRITE_RODEX
+ packet(0x0a13,2,clif->pDull/*,XXX*/); // CZ_CHECK_RECEIVE_CHARACTER_NAME
+// changed packet sizes
+ packet(0x0a05,48); // ZC_ACK_ADD_ITEM_RODEX
+ packet(0x0a06,6,clif->pDull/*,XXX*/); // CZ_REQ_REMOVE_RODEX_ITEM
+ packet(0x0a07,7); // ZC_ACK_REMOVE_RODEX_ITEM
+ packet(0x0a08,26,clif->pDull/*,XXX*/); // CZ_REQ_OPEN_WRITE_RODEX
+#endif
+
+// 2014-04-23aRagexeRE
+#if PACKETVER >= 20140423
+// new packets
+ packet(0x0a14,6); // ZC_CHECK_RECEIVE_CHARACTER_NAME
+// changed packet sizes
+ packet(0x0a13,26,clif->pDull/*,XXX*/); // CZ_CHECK_RECEIVE_CHARACTER_NAME
+#endif
+
+// 2014-04-30aRagexeRE
+#if PACKETVER >= 20140430
+// new packets
+ packet(0x0a15,11); // ZC_GOLDPCCAFE_POINT
+ packet(0x0a16,26,clif->pDull/*,XXX*/); // CZ_DYNAMICNPC_CREATE_REQUEST
+ packet(0x0a17,6); // ZC_DYNAMICNPC_CREATE_RESULT
+#endif
+
+// 2014-05-08bRagexeRE
+#if PACKETVER >= 20140508
+// changed packet sizes
+ packet(0x0a15,12); // ZC_GOLDPCCAFE_POINT
+#endif
+
+// 2014-05-21aRagexeRE
+#if PACKETVER >= 20140521
+// changed packet sizes
+ packet(0x0a07,9); // ZC_ACK_REMOVE_RODEX_ITEM
+ packet(0x0a14,10); // ZC_CHECK_RECEIVE_CHARACTER_NAME
+#endif
+
+/* Roulette System [Yommy/Hercules] */
+// 2014-06-05aRagexe
+#if PACKETVER >= 20140605
+// new packets
+ packet(0x0a18,2); // ZC_ACCEPT_ENTER3
+ packet(0x0a19,-1,clif->pDull/*,XXX*/); // CZ_REQ_OPEN_ROULETTE
+ packet(0x0a1a,10); // ZC_ACK_OPEN_ROULETTE
+ packet(0x0A1B,2,clif->pRouletteInfo,0); // HEADER_CZ_REQ_ROULETTE_INFO
+ packet(0x0a1c,6); // ZC_ACK_ROULEITTE_INFO
+ packet(0x0a1d,14,clif->pDull/*,XXX*/); // CZ_REQ_CLOSE_ROULETTE
+#endif
+
+/* Roulette System [Yommy/Hercules] */
+// 2014-06-11bRagexe / RE. moved by 4144
+#if PACKETVER >= 20140611
+// new packets
+ packet(0x0a1e,3); // ZC_ACK_CLOSE_ROULETTE
+ packet(0x0a1f,2,clif->pRouletteGenerate,0); // CZ_REQ_GENERATE_ROULETTE
+ packet(0x0a20,21); // ZC_ACK_GENERATE_ROULETTE
+ packet(0x0a21,6,clif->pDull/*,XXX*/); // CZ_RECV_ROULETTE_ITEM
+ packet(0x0a22,3); // ZC_RECV_ROULETTE_ITEM
+ packet(0x0a23,-1); // ZC_ALL_ACH_LIST
+ packet(0x0a24,35); // ZC_ACH_UPDATE
+ packet(0x0a25,6,clif->pDull/*,XXX*/); // CZ_REQ_ACH_REWARD
+ packet(0x0a26,7); // ZC_REQ_ACH_REWARD_ACK
+// changed packet sizes
+ packet(0x0a18,14); // ZC_ACCEPT_ENTER3
+ packet(0x0a19,2,clif->pRouletteOpen,0); // CZ_REQ_OPEN_ROULETTE
+ packet(0x0a1a,23); // ZC_ACK_OPEN_ROULETTE
+ packet(0x0a1c,-1); // ZC_ACK_ROULEITTE_INFO
+ packet(0x0a1d,2,clif->pRouletteClose,0); // CZ_REQ_CLOSE_ROULETTE
+#endif
+
+// 2014-06-18cRagexeRE
+#if PACKETVER >= 20140618
+// changed packet sizes
+ packet(0x0a21,3,clif->pRouletteRecvItem,2); // CZ_RECV_ROULETTE_ITEM
+ packet(0x0a22,5); // ZC_RECV_ROULETTE_ITEM
#endif
// 2014-06-25aRagexeRE
#if PACKETVER >= 20140625
-// no shuffle packets
+// new packets
+ packet(0x0a27,8); // ZC_RECOVERY2
packet(0x0a28,3); // ZC_ACK_OPENSTORE2
+// changed packet sizes
+ packet(0x0a24,36); // ZC_ACH_UPDATE
+#endif
+
+// 2014-07-02aRagexeRE
+#if PACKETVER >= 20140702
+// new packets
+ packet(0x0a29,6); // ZC_REQ_AU_BOT
+ packet(0x0a2a,6,clif->pDull/*,XXX*/); // CZ_ACK_AU_BOT
+#endif
+
+// 2014-07-16aRagexeRE
+#if PACKETVER >= 20140716
+// changed packet sizes
+ packet(0x09e7,3); // ZC_NOTIFY_UNREAD_RODEX
+#endif
+
+// 2014-07-23aRagexeRE
+#if PACKETVER >= 20140723
+// new packets
+ packet(0x0a2b,14); // ZC_SE_CASHSHOP_OPEN2
+ packet(0x0a2c,12); // ZC_SE_PC_BUY_TAIWANCASHITEM_RESULT
+// changed packet sizes
+ packet(0x0a24,56); // ZC_ACH_UPDATE
+#endif
+
+// 2014-08-20aRagexeRE
+#if PACKETVER >= 20140820
+// new packets
+ packet(0x0a2d,-1); // ZC_EQUIPWIN_MICROSCOPE_V6
+#endif
+
+// 2014-09-03aRagexeRE
+#if PACKETVER >= 20140903
+// new packets
+ packet(0x0a2e,6,clif->pDull/*,XXX*/); // CZ_REQ_CHANGE_TITLE
+ packet(0x0a2f,7); // ZC_ACK_CHANGE_TITLE
+// changed packet sizes
+#endif
+
+// 2014-09-24bRagexeRE
+#if PACKETVER >= 20140924
+// new packets
+ packet(0x0a30,106); // ZC_ACK_REQNAMEALL2
+ packet(0x0a31,-1); // ZC_RESULT_PACKAGE_ITEM_TEST
+ packet(0x0a32,2); // ZC_OPEN_RODEX_THROUGH_NPC_ONLY
+ packet(0x0a33,7); // ZC_UPDATE_ROULETTE_COIN
+ packet(0x0a34,6); // ZC_UPDATE_TAIWANCASH
+#endif
+
+// 2014-10-01bRagexeRE
+#if PACKETVER >= 20141001
+// changed packet sizes
+ packet(0x0a24,66); // ZC_ACH_UPDATE
+#endif
+
+// 2014-10-08bRagexeRE
+#if PACKETVER >= 20141008
+// changed packet sizes
+ packet(0x0a05,49); // ZC_ACK_ADD_ITEM_RODEX
#endif
// 2014-10-16aRagexe - YomRawr
@@ -2938,26 +3209,10 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x0936,36,clif->pStoragePassword,0);
packet(0x0363,8,clif->pDull); // CZ_JOIN_BATTLE_FIELD
packet(0x0922,4,clif->pDull); // CZ_GANGSI_RANK
- packet(0x09DF,7);
- packet(0x0a00,269);
packet(0x09e5,18); // ZC_DELETEITEM_FROM_MCSTORE2
packet(0x09e6,22); // ZC_UPDATE_ITEM_FROM_BUYING_STORE2
#endif
-/* Roulette System [Yommy/Hercules] */
-#if PACKETVER >= 20141016
- packet(0x0A19,2,clif->pRouletteOpen,0); // HEADER_CZ_REQ_OPEN_ROULETTE
- packet(0x0A1A,23); // HEADER_ZC_ACK_OPEN_ROULETTE
- packet(0x0A1B,2,clif->pRouletteInfo,0); // HEADER_CZ_REQ_ROULETTE_INFO
- packet(0x0A1C,-1); // HEADER_ZC_ACK_ROULEITTE_INFO
- packet(0x0A1D,2,clif->pRouletteClose,0); // HEADER_CZ_REQ_CLOSE_ROULETTE
- packet(0x0A1E,3); // HEADER_ZC_ACK_CLOSE_ROULETTE
- packet(0x0A1F,2,clif->pRouletteGenerate,0); // HEADER_CZ_REQ_GENERATE_ROULETTE
- packet(0x0A20,21); // HEADER_ZC_ACK_GENERATE_ROULETTE
- packet(0x0A21,3,clif->pRouletteRecvItem,2); // HEADER_CZ_RECV_ROULETTE_ITEM
- packet(0x0A22,5); // HEADER_ZC_RECV_ROULETTE_ITEM
-#endif
-
// 2014-10-22bRagexe - YomRawr
#if PACKETVER >= 20141022
packet(0x0369,7,clif->pActionRequest,2,6);
@@ -2987,22 +3242,57 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x091A,26,clif->pFriendsListAdd,2);
packet(0x0899,5,clif->pHomMenu,2,4);
packet(0x0438,36,clif->pStoragePassword,0);
- packet(0x0A01,3,clif->pHotkeyRowShift,2);
packet(0x08ab,4,clif->pDull); // CZ_GANGSI_RANK
packet(0x092b,8,clif->pDull); // CZ_JOIN_BATTLE_FIELD
#endif
+// 2014-11-19bRagexeRE
+#if PACKETVER >= 20141119
+// new packets
+ packet(0x0A35,4,clif->pOneClick_ItemIdentify,2);
+// changed packet sizes
+ packet(0x0a05,53); // ZC_ACK_ADD_ITEM_RODEX
+#endif
+
+// 2014-11-26aRagexeRE
+#if PACKETVER >= 20141126
+// new packets
+ packet(0x0a36,7); // ZC_HP_INFO_TINY
+ packet(0x0a37,57); // ZC_ITEM_PICKUP_ACK_V7
+#endif
+
+// 2015-01-28aRagexeRE
+#if PACKETVER >= 20150128
+// new packets
+ packet(0x0a38,3);
+#endif
+
#if PACKETVER >= 20150226
// shuffle packets not added
- packet(0x0A09,45);
- packet(0x0A0A,47);
- packet(0x0A0B,47);
- packet(0x0A0C,56);
- packet(0x0A0D,-1);
packet(0x0A0F,-1);
packet(0x0A10,-1);
#endif
+// 2015-03-11aRagexeRE
+#if PACKETVER >= 20150311
+// new packets
+ packet(0x0a3a,12);
+// changed packet sizes
+#endif
+
+// 2015-04-15aRagexeRE
+#if PACKETVER >= 20150415
+// changed packet sizes
+ packet(0x0a39,36); // CH_UNKNOWN_MAKE_CHAR // in char server used from 20151001. is this correct?
+#endif
+
+// 2015-04-22aRagexeRE
+#if PACKETVER >= 20150422
+// new packets
+ packet(0x0a3b,-1);
+// changed packet sizes
+#endif
+
// 2015-05-13aRagexe
#if PACKETVER >= 20150513
packet(0x0369,7,clif->pActionRequest,2,6);
@@ -3034,19 +3324,55 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x08A8,26,clif->pFriendsListAdd,2);
packet(0x0817,5,clif->pHomMenu,2,4);
packet(0x0923,36,clif->pStoragePassword,0);
- packet(0x09E8,11,clif->pDull); // CZ_OPEN_MAILBOX
- packet(0x0A2E,6,clif->pDull); // TITLE
- packet(0x0A02,4); // ZC_DRESSROOM_OPEN
- packet(0x0A35,4,clif->pOneClick_ItemIdentify,2);
packet(0x0a27,8); // ZC_RECOVERY2
packet(0x09f7,75); // ZC_PROPERTY_HOMUN_2
#endif
+// 2015-05-20aRagexeRE
+#if PACKETVER >= 20150520
+// new packets
+ packet(0x0a3c,-1);
+ packet(0x0a3d,18,clif->pDull/*,XXX*/);
+#endif
+
+// 2015-06-03bRagexeRE
+#if PACKETVER >= 20150603
+// new packets
+ packet(0x0a3e,-1);
+#endif
+
+// 2015-06-24aRagexeRE
+#if PACKETVER >= 20150624
+// new packets
+ packet(0x0a3f,9);
+#endif
+
+// ---
+// this packet was added in 2012-05-02aRagexeRE / 2012-05-03aRagexe probably if should be allowed in this versions?
#if PACKETVER >= 20150805 // RagexeRE
// shuffle packets not added
- packet(0x097f,-1); // ZC_SELECTCART
+ packet(0x097f,-1); // ZC_SELECTCART
packet(0x0980,7,clif->pSelectCart); // CZ_SELECTCART
#endif
+// ---
+
+// 2015-08-12aRagexeRE
+#if PACKETVER >= 20150812
+// new packets
+ packet(0x0a40,11);
+#endif
+
+// 2015-09-09aRagexeRE
+#if PACKETVER >= 20150909
+// new packets
+ packet(0x0a41,18);
+#endif
+
+// 2015-09-16aRagexeRE
+#if PACKETVER >= 20150916
+// new packets
+ packet(0x0a42,43);
+#endif
// 2015-10-01bRagexeRE
#if PACKETVER >= 20151001
@@ -3081,6 +3407,19 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x0436,4,clif->pDull); // CZ_GANGSI_RANK
#endif
+// 2015-10-07aRagexeRE
+#if PACKETVER >= 20151007
+// new packets
+ packet(0x0a43,85);
+ packet(0x0a44,-1);
+#endif
+
+// 2015-10-28cRagexeRE
+#if PACKETVER >= 20151028
+// new packets
+ packet(0x0a45,-1);
+#endif
+
// 2015-10-29aRagexe
#if PACKETVER >= 20151029
packet(0x0369,7,clif->pActionRequest,2,6);
@@ -3112,7 +3451,6 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x0860,36,clif->pStoragePassword,0);
packet(0x0363,8,clif->pDull); // CZ_JOIN_BATTLE_FIELD
packet(0x0436,4,clif->pDull); // CZ_GANGSI_RANK
- packet(0x0a39,36);
#endif
// 2015-11-04aRagexe
@@ -3146,7 +3484,21 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x0940,36,clif->pStoragePassword,2,4,20);
packet(0x08a3,4,clif->pDull); // CZ_GANGSI_RANK
packet(0x0939,8,clif->pDull); // CZ_JOIN_BATTLE_FIELD
- packet(0x0a39,36);
+// new packets
+ packet(0x0a46,14,clif->pDull/*,XXX*/);
+ packet(0x0a47,3);
+ packet(0x0a48,2,clif->pDull/*,XXX*/);
+// changed packet sizes
+ packet(0x0a45,2);
+#endif
+
+// 2015-11-18aRagexeRE
+#if PACKETVER >= 20151118
+// new packets
+ packet(0x0a49,22);
+ packet(0x0a4a,6);
+ packet(0x0a4b,22);
+ packet(0x0a4c,28);
#endif
// 2015-12-16aRagexe
diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h
index 4d474ac93..daf431438 100644
--- a/src/map/packets_struct.h
+++ b/src/map/packets_struct.h
@@ -141,8 +141,11 @@ enum packet_headers {
authokType = 0x73,
#elif PACKETVER < 20141022
authokType = 0x2eb,
-#else
+// Some clients smaller than 20160330 cant be tested [4144]
+#elif PACKETVER < 20160330
authokType = 0xa18,
+#else
+ authokType = 0x2eb,
#endif
script_clearType = 0x8d6,
package_item_announceType = 0x7fd,
@@ -286,7 +289,7 @@ enum packet_headers {
maptypeproperty2Type = 0x99b,
npcmarketresultackType = 0x9d7,
npcmarketopenType = 0x9d5,
-#if PACKETVER >= 20131223
+#if PACKETVER >= 20131223 // version probably can be 20131030 [4144]
wisendType = 0x9df,
#else
wisendType = 0x98,
@@ -400,7 +403,8 @@ struct packet_authok {
#if PACKETVER >= 20080102
int16 font;
#endif
-#if PACKETVER >= 20141022
+// Some clients smaller than 20160330 cant be tested [4144]
+#if PACKETVER >= 20141022 && PACKETVER < 20160330
uint8 sex;
#endif
} __attribute__((packed));
diff --git a/src/map/pc.c b/src/map/pc.c
index 9ef7d084f..e9855c16d 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -10035,6 +10035,11 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag)
status_change_end(&sd->bl, SC_ARMOR_RESIST, INVALID_TIMER);
}
+#ifdef RENEWAL
+ if (battle->bc->bow_unequip_arrow && pos&EQP_ARMS && sd->equip_index[EQI_AMMO] > 0)
+ pc->unequipitem(sd, sd->equip_index[EQI_AMMO], PCUNEQUIPITEM_FORCE);
+#endif
+
if( sd->state.autobonus&pos )
sd->state.autobonus &= ~sd->status.inventory[n].equip; //Check for activated autobonus [Inkfish]
diff --git a/src/map/script.c b/src/map/script.c
index 48c377d24..25f520450 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -10861,6 +10861,100 @@ BUILDIN(addtimercount)
return true;
}
+enum gettimer_mode {
+ GETTIMER_COUNT = 0,
+ GETTIMER_TICK_NEXT = 1,
+ GETTIMER_TICK_LAST = 2,
+};
+
+BUILDIN(gettimer)
+{
+ struct map_session_data *sd;
+ const struct TimerData *td;
+ int i;
+ int tick;
+ const char *event = NULL;
+ int val = 0;
+ bool first = true;
+ short mode = script_getnum(st, 2);
+
+ if (script_hasdata(st, 3))
+ sd = map->id2sd(script_getnum(st, 3));
+ else
+ sd = script->rid2sd(st);
+
+ if (script_hasdata(st, 4)) {
+ event = script_getstr(st, 4);
+ script->check_event(st, event);
+ }
+
+ if (sd == NULL) {
+ script_pushint(st, -1);
+ return true;
+ }
+
+ switch (mode) {
+ case GETTIMER_COUNT:
+ // get number of timers
+ for (i = 0; i < MAX_EVENTTIMER; i++) {
+ if (sd->eventtimer[i] != INVALID_TIMER) {
+ if (event != NULL) {
+ td = timer->get(sd->eventtimer[i]);
+ Assert_retr(false, td != NULL);
+
+ if (strcmp((char *)(td->data), event) == 0) {
+ val++;
+ }
+ } else {
+ val++;
+ }
+ }
+ }
+ break;
+ case GETTIMER_TICK_NEXT:
+ // get the number of tick before the next timer runs
+ for (i = 0; i < MAX_EVENTTIMER; i++) {
+ if (sd->eventtimer[i] != INVALID_TIMER) {
+ td = timer->get(sd->eventtimer[i]);
+ Assert_retr(false, td != NULL);
+ tick = max(0, DIFF_TICK32(td->tick, timer->gettick()));
+
+ if (event != NULL) {
+ if ((first == true || tick < val) && strcmp((char *)(td->data), event) == 0) {
+ val = tick;
+ first = false;
+ }
+ } else if (first == true || tick < val) {
+ val = tick;
+ first = false;
+ }
+ }
+ }
+ break;
+ case GETTIMER_TICK_LAST:
+ // get the number of ticks before the last timer runs
+ for (i = MAX_EVENTTIMER - 1; i >= 0; i--) {
+ if (sd->eventtimer[i] != INVALID_TIMER) {
+ td = timer->get(sd->eventtimer[i]);
+ Assert_retr(false, td != NULL);
+ tick = max(0, DIFF_TICK32(td->tick, timer->gettick()));
+
+ if (event != NULL) {
+ if (strcmp((char *)(td->data), event) == 0) {
+ val = max(val, tick);
+ }
+ } else {
+ val = max(val, tick);
+ }
+ }
+ }
+ break;
+ }
+
+ script_pushint(st, val);
+ return true;
+}
+
/*==========================================
*------------------------------------------*/
BUILDIN(initnpctimer)
@@ -11698,14 +11792,16 @@ BUILDIN(getstatus)
case 3: script_pushint(st, sd->sc.data[id]->val3); break;
case 4: script_pushint(st, sd->sc.data[id]->val4); break;
case 5:
- {
- const struct TimerData *td = timer->get(sd->sc.data[id]->timer);
+ if (sd->sc.data[id]->infinite_duration) {
+ script_pushint(st, INFINITE_DURATION);
+ } else {
+ const struct TimerData *td = timer->get(sd->sc.data[id]->timer);
- if (td != NULL) {
- // return the amount of time remaining
- script_pushint(st, (int)(td->tick - timer->gettick())); // TODO: change this to int64 when we'll support 64 bit script values
+ if (td != NULL) {
+ // return the amount of time remaining
+ script_pushint(st, (int)(td->tick - timer->gettick())); // TODO: change this to int64 when we'll support 64 bit script values
+ }
}
- }
break;
default: script_pushint(st, 1); break;
}
@@ -21115,6 +21211,7 @@ void script_parse_builtin(void) {
BUILDIN_DEF(addtimer,"is?"),
BUILDIN_DEF(deltimer,"s?"),
BUILDIN_DEF(addtimercount,"si?"),
+ BUILDIN_DEF(gettimer,"i??"),
BUILDIN_DEF(initnpctimer,"??"),
BUILDIN_DEF(stopnpctimer,"??"),
BUILDIN_DEF(startnpctimer,"??"),
diff --git a/src/map/skill.c b/src/map/skill.c
index cd7006de0..70db5b341 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -8181,8 +8181,14 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
int x,y;
x = src->x;
y = src->y;
- if (hd)
- skill->blockhomun_start(hd, skill_id, skill->get_time2(skill_id,skill_lv));
+ if (hd) {
+#ifdef RENEWAL
+ skill->blockhomun_start(hd, skill_id, skill->get_cooldown(skill_id, skill_lv));
+#else
+ skill->blockhomun_start(hd, skill_id, skill->get_time2(skill_id, skill_lv));
+#endif
+ }
+
if (unit->movepos(src,bl->x,bl->y,0,0)) {
clif->skill_nodamage(src,src,skill_id,skill_lv,1); // Homun
diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc
index 82d310832..02af6e231 100644
--- a/src/plugins/HPMHooking/HPMHooking.Defs.inc
+++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc
@@ -396,8 +396,8 @@ typedef int (*HPMHOOK_pre_chr_rename_char_sql) (struct char_session_data **sd, i
typedef int (*HPMHOOK_post_chr_rename_char_sql) (int retVal___, struct char_session_data *sd, int char_id);
typedef int (*HPMHOOK_pre_chr_check_char_name) (char **name, char **esc_name);
typedef int (*HPMHOOK_post_chr_check_char_name) (int retVal___, char *name, char *esc_name);
-typedef int (*HPMHOOK_pre_chr_make_new_char_sql) (struct char_session_data **sd, const char **name_, int *str, int *agi, int *vit, int *int_, int *dex, int *luk, int *slot, int *hair_color, int *hair_style, short *starting_job);
-typedef int (*HPMHOOK_post_chr_make_new_char_sql) (int retVal___, struct char_session_data *sd, const char *name_, int str, int agi, int vit, int int_, int dex, int luk, int slot, int hair_color, int hair_style, short starting_job);
+typedef int (*HPMHOOK_pre_chr_make_new_char_sql) (struct char_session_data **sd, const char **name_, int *str, int *agi, int *vit, int *int_, int *dex, int *luk, int *slot, int *hair_color, int *hair_style, short *starting_job, uint8 *sex);
+typedef int (*HPMHOOK_post_chr_make_new_char_sql) (int retVal___, struct char_session_data *sd, const char *name_, int str, int agi, int vit, int int_, int dex, int luk, int slot, int hair_color, int hair_style, short starting_job, uint8 sex);
typedef int (*HPMHOOK_pre_chr_divorce_char_sql) (int *partner_id1, int *partner_id2);
typedef int (*HPMHOOK_post_chr_divorce_char_sql) (int retVal___, int partner_id1, int partner_id2);
typedef int (*HPMHOOK_pre_chr_count_users) (void);
diff --git a/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc
index e2108c8f8..3942693da 100644
--- a/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc
@@ -744,15 +744,15 @@ int HP_chr_check_char_name(char *name, char *esc_name) {
}
return retVal___;
}
-int HP_chr_make_new_char_sql(struct char_session_data *sd, const char *name_, int str, int agi, int vit, int int_, int dex, int luk, int slot, int hair_color, int hair_style, short starting_job) {
+int HP_chr_make_new_char_sql(struct char_session_data *sd, const char *name_, int str, int agi, int vit, int int_, int dex, int luk, int slot, int hair_color, int hair_style, short starting_job, uint8 sex) {
int hIndex = 0;
int retVal___ = 0;
if( HPMHooks.count.HP_chr_make_new_char_sql_pre ) {
- int (*preHookFunc) (struct char_session_data **sd, const char **name_, int *str, int *agi, int *vit, int *int_, int *dex, int *luk, int *slot, int *hair_color, int *hair_style, short *starting_job);
+ int (*preHookFunc) (struct char_session_data **sd, const char **name_, int *str, int *agi, int *vit, int *int_, int *dex, int *luk, int *slot, int *hair_color, int *hair_style, short *starting_job, uint8 *sex);
*HPMforce_return = false;
for(hIndex = 0; hIndex < HPMHooks.count.HP_chr_make_new_char_sql_pre; hIndex++ ) {
preHookFunc = HPMHooks.list.HP_chr_make_new_char_sql_pre[hIndex].func;
- retVal___ = preHookFunc(&sd, &name_, &str, &agi, &vit, &int_, &dex, &luk, &slot, &hair_color, &hair_style, &starting_job);
+ retVal___ = preHookFunc(&sd, &name_, &str, &agi, &vit, &int_, &dex, &luk, &slot, &hair_color, &hair_style, &starting_job, &sex);
}
if( *HPMforce_return ) {
*HPMforce_return = false;
@@ -760,13 +760,13 @@ int HP_chr_make_new_char_sql(struct char_session_data *sd, const char *name_, in
}
}
{
- retVal___ = HPMHooks.source.chr.make_new_char_sql(sd, name_, str, agi, vit, int_, dex, luk, slot, hair_color, hair_style, starting_job);
+ retVal___ = HPMHooks.source.chr.make_new_char_sql(sd, name_, str, agi, vit, int_, dex, luk, slot, hair_color, hair_style, starting_job, sex);
}
if( HPMHooks.count.HP_chr_make_new_char_sql_post ) {
- int (*postHookFunc) (int retVal___, struct char_session_data *sd, const char *name_, int str, int agi, int vit, int int_, int dex, int luk, int slot, int hair_color, int hair_style, short starting_job);
+ int (*postHookFunc) (int retVal___, struct char_session_data *sd, const char *name_, int str, int agi, int vit, int int_, int dex, int luk, int slot, int hair_color, int hair_style, short starting_job, uint8 sex);
for(hIndex = 0; hIndex < HPMHooks.count.HP_chr_make_new_char_sql_post; hIndex++ ) {
postHookFunc = HPMHooks.list.HP_chr_make_new_char_sql_post[hIndex].func;
- retVal___ = postHookFunc(retVal___, sd, name_, str, agi, vit, int_, dex, luk, slot, hair_color, hair_style, starting_job);
+ retVal___ = postHookFunc(retVal___, sd, name_, str, agi, vit, int_, dex, luk, slot, hair_color, hair_style, starting_job, sex);
}
}
return retVal___;