Index: src/map/script.c
===================================================================
--- src/map/script.c (revision 17302)
+++ src/map/script.c (working copy)
@@ -3594,7 +3594,7 @@
///
/// @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)
+void script_detach_state(struct script_state* st, bool dequeue_event)
{
struct map_session_data* sd;
@@ -3606,9 +3606,7 @@
st->bk_st = NULL;
st->bk_npcid = 0;
} else if(dequeue_event) {
- /**
- * For the Secure NPC Timeout option (check config/Secure.h) [RR]
- **/
+
#ifdef SECURE_NPCTIMEOUT
/**
* We're done with this NPC session, so we cancel the timer (if existent) and move on
@@ -3652,9 +3650,6 @@
sd->st = st;
sd->npc_id = st->oid;
sd->npc_item_flag = st->npc_item_flag; // load default.
-/**
- * For the Secure NPC Timeout option (check config/Secure.h) [RR]
- **/
#ifdef 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);
@@ -6916,6 +6911,7 @@
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;
+ st->mes_active = 0;
clif_scriptclose(sd, st->oid);
return 1;
}
@@ -6992,6 +6988,7 @@
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;
+ sd->st->mes_active = 0;
clif_scriptclose(sd, st->oid);
return 1;
}
Index: src/map/script.h
===================================================================
--- src/map/script.h (revision 17302)
+++ src/map/script.h (working copy)
@@ -171,6 +171,7 @@
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);
+void script_detach_state(struct script_state* st, bool dequeue_event);
struct DBMap* script_get_label_db(void);
struct DBMap* script_get_userfunc_db(void);
Index: src/map/mob.c
===================================================================
--- src/map/mob.c (revision 17302)
+++ src/map/mob.c (working copy)
@@ -159,9 +159,9 @@
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);
+ status_change_init(&nd->bl);
+ unit_dataset(&nd->bl);
+ clif_spawn(&nd->bl);
}
@@ -2491,7 +2491,7 @@
for(i = 0; i < MAX_MVP_DROP; i++) {
while( 1 ) {
- int va = rand()%MAX_MVP_DROP;
+ int va = rnd()%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;
Index: src/map/clif.c
===================================================================
--- src/map/clif.c (revision 17302)
+++ src/map/clif.c (working copy)
@@ -1271,11 +1271,6 @@
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);
}
}
/**
@@ -1714,8 +1709,7 @@
WBUFW(buf,8) = bl->y;
clif_send(buf, packet_len(0x88), bl, AREA);
- if( disguised(bl) )
- {
+ if( disguised(bl) ) {
WBUFL(buf,2) = -bl->id;
clif_send(buf, packet_len(0x88), bl, SELF);
}
@@ -1882,8 +1876,7 @@
/*==========================================
*
*------------------------------------------*/
-void clif_sendfakenpc(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;
@@ -2117,6 +2110,7 @@
/// 00a0 <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 (ZC_ITEM_PICKUP_ACK)
/// 029a <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 (ZC_ITEM_PICKUP_ACK2)
/// 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)
+/// 0990 <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 <unknow>.W (ZC_ITEM_PICKUP_ACK_V5)
void clif_additem(struct map_session_data *sd, int n, int amount, int fail)
{
int fd;
@@ -2124,8 +2118,10 @@
const int cmd = 0xa0;
#elif PACKETVER < 20071002
const int cmd = 0x29a;
+#else PACKETVER < 20120925
+ const int cmd = 0x2d4;
#else
- const int cmd = 0x2d4;
+ const int cmd = 0x990;
#endif
nullpo_retv(sd);
@@ -2182,6 +2178,9 @@
#if PACKETVER >= 20071002
WFIFOW(fd,27)=0; // unknown
#endif
+#if PACKETVER >= 20120925
+ WFIFOW(fd,29)=0; // unknown
+#endif
}
WFIFOSET(fd,packet_len(cmd));
@@ -2240,8 +2239,7 @@
// Simplifies inventory/cart/storage packets by handling the packet section relevant to items. [Skotlex]
// Equip is >= 0 for equippable items (holds the equip-point, is 0 for pet
// 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)
-{
+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
@@ -2264,8 +2262,7 @@
}
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)
-{
+void clif_inventorylist(struct map_session_data *sd) {
int i,n,ne,arrow=-1;
unsigned char *buf;
unsigned char *bufe;
@@ -2340,8 +2337,7 @@
if( arrow >= 0 )
clif_arrowequip(sd,arrow);
- if( ne )
- {
+ if( ne ) {
#if PACKETVER < 20071002
WBUFW(bufe,0)=0xa4;
#else
@@ -3111,8 +3107,7 @@
/// <int>.B <need int>.B <dex>.B <need dex>.B <luk>.B <need luk>.B <atk>.W <atk2>.W
/// <matk min>.W <matk max>.W <def>.W <def2>.W <mdef>.W <mdef2>.W <hit>.W
/// <flee>.W <flee2>.W <crit>.W <aspd>.W <aspd2>.W
-void clif_initialstatus(struct map_session_data *sd)
-{
+void clif_initialstatus(struct map_session_data *sd) {
int fd, mdef2;
unsigned char *buf;
@@ -16747,7 +16742,7 @@
0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0,
//#0x0980
0, 0, 0, 29, 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, 0, 0, 0,
+ 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 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,
Index: src/map/npc.c
===================================================================
--- src/map/npc.c (revision 17302)
+++ src/map/npc.c (working copy)
@@ -246,6 +246,7 @@
int npc_rr_secure_timeout_timer(int tid, unsigned int tick, int id, intptr_t data) {
struct map_session_data* sd = NULL;
unsigned int timeout = NPC_SECURE_TIMEOUT_NEXT;
+ int cur_tick = gettick(); //ensure we are on last tick
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
@@ -261,22 +262,13 @@
//case NPCT_WAIT: var starts with this value
}
- if( DIFF_TICK(tick,sd->npc_idle_tick) > (timeout*1000) ) {
- /**
- * If we still have the NPC script attached, tell it to stop.
- **/
- if( sd->st )
- sd->st->state = END;
- sd->state.menu_or_input = 0;
- sd->npc_menu = 0;
-
- /**
- * 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);
+ if( DIFF_TICK(cur_tick,sd->npc_idle_tick) > (timeout*1000) ) {
+ pc_close_npc(sd,1);
+ } else if(sd->st && (sd->st->state == END || sd->st->state == CLOSE)){
+ sd->npc_idle_timer = INVALID_TIMER; //stop timer the script is already ending
+ } else { //Create a new instance of ourselves to continue
+ sd->npc_idle_timer = add_timer(cur_tick + (SECURE_NPCTIMEOUT_INTERVAL*1000),npc_rr_secure_timeout_timer,sd->bl.id,0);
+ }
return 0;
}
#endif
@@ -1248,14 +1240,8 @@
return 1;
}
}
- /**
- * For the Secure NPC Timeout option (check config/Secure.h) [RR]
- **/
#ifdef SECURE_NPCTIMEOUT
- /**
- * Update the last NPC iteration
- **/
- sd->npc_idle_tick = gettick();
+ sd->npc_idle_tick = gettick(); //Update the last NPC iteration
#endif
/**
@@ -1290,7 +1276,7 @@
sd->npc_id=0;
return 1;
}
- if (nd->sc.option & OPTION_INVISIBLE) // can't buy if npc is not visible (hack?)
+ 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
Index: src/map/npc.h
===================================================================
--- src/map/npc.h (revision 17302)
+++ src/map/npc.h (working copy)
@@ -175,9 +175,6 @@
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]
- **/
#ifdef SECURE_NPCTIMEOUT
int npc_rr_secure_timeout_timer(int tid, unsigned int tick, int id, intptr_t data);
#endif
Index: src/map/pc.c
===================================================================
--- src/map/pc.c (revision 17302)
+++ src/map/pc.c (working copy)
@@ -965,13 +965,9 @@
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]
- **/
+
#ifdef SECURE_NPCTIMEOUT
- /**
- * Initialize to defaults/expected
- **/
+ // Initialize to defaults/expected
sd->npc_idle_timer = INVALID_TIMER;
sd->npc_idle_tick = tick;
sd->npc_idle_type = NPCT_INPUT;
@@ -6569,6 +6565,39 @@
sd->canlog_tick = gettick();
}
+/*
+ * Method to properly close npc for player and clear anything related
+ * @flag == 1 : produce close button
+ * @flag == 2 : directly close it
+ */
+void pc_close_npc(struct map_session_data *sd,int flag) {
+ nullpo_retv(sd);
+
+ 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->st) {
+ sd->st->state = (flag==1)?CLOSE:END;
+ sd->st->mes_active = 0;
+ }
+ sd->state.menu_or_input = 0;
+ sd->npc_menu = 0;
+ sd->npc_idle_timer = INVALID_TIMER;
+ clif_scriptclose(sd,sd->npc_id);
+ if(flag==2 && sd->st) {
+ sd->npc_id = sd->st->bk_npcid;
+ sd->st = sd->st->bk_st;
+ if(sd->st && sd->st->bk_st){
+ script_free_state(sd->st->bk_st);
+ sd->st->bk_st = NULL;
+ sd->st->bk_npcid = 0;
+ }
+ }
+ }
+}
+
/*==========================================
* Invoked when a player has negative current hp
*------------------------------------------*/
@@ -6620,22 +6649,8 @@
duel_reject(sd->duel_invite, sd);
}
- // 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;
+ pc_close_npc(sd,2); //close npc if we were using one
- sd->npc_id = 0;
- if (sd->st && sd->st->state != END)
- sd->st->state = END;
- }
-
/* e.g. not killed thru pc_damage */
if( pc_issit(sd) ) {
clif_status_load(&sd->bl,SI_SIT,0);
Index: src/map/pc.h
===================================================================
--- src/map/pc.h (revision 17302)
+++ src/map/pc.h (working copy)
@@ -472,9 +472,6 @@
unsigned int bg_id;
unsigned short user_font;
- /**
- * For the Secure NPC Timeout option (check config/Secure.h) [RR]
- **/
#ifdef SECURE_NPCTIMEOUT
/**
* ID of the timer
@@ -720,6 +717,7 @@
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);
+void pc_close_npc(struct map_session_data *sd,int flag);
int pc_isequip(struct map_session_data *sd,int n);
int pc_equippoint(struct map_session_data *sd,int n);
Index: src/map/cashshop.c
===================================================================
--- src/map/cashshop.c (revision 17302)
+++ src/map/cashshop.c (working copy)
@@ -15,13 +15,59 @@
#include <string.h> // memset
#include <stdlib.h> // atoi
-static int cashshop_parse_dbrow( char** str, const char* source, int line );
-
struct cash_item_db cash_shop_items[CASHSHOP_TAB_SEARCH];
extern char item_cash_db_db[32];
extern char item_cash_db2_db[32];
+/*
+ * Read one line of db and assign it to ram
+ * return
+ * 0 = failure
+ * 1 = succes
+ */
+static int cashshop_parse_dbrow( char** str, const char* source, int line ){
+ uint32 nameid = atoi( str[1] );
+
+ if( itemdb_exists( nameid ) ){
+ uint16 tab = atoi( str[0] );
+ uint32 price = atoi( str[2] );
+ struct cash_item_data* cid;
+ int j;
+
+ if( tab > CASHSHOP_TAB_SEARCH ){
+ ShowWarning( "cashshop_parse_dbrow: Invalid tab %d in line %d of \"%s\", skipping.\n", tab, line, source );
+ return 0;
+ }else if( price < 1 ){
+ ShowWarning( "cashshop_parse_dbrow: Invalid price %d in line %d of \"%s\", skipping.\n", price, line, source );
+ return 0;
+ }
+
+ ARR_FIND( 0, cash_shop_items[tab].count, j, nameid == cash_shop_items[tab].item[j]->nameid );
+
+ if( j == cash_shop_items[tab].count ){
+ RECREATE( cash_shop_items[tab].item, struct cash_item_data *, ++cash_shop_items[tab].count );
+ CREATE( cash_shop_items[tab].item[ cash_shop_items[tab].count - 1], struct cash_item_data, 1 );
+ cid = cash_shop_items[tab].item[ cash_shop_items[tab].count - 1];
+ }else{
+ cid = cash_shop_items[tab].item[j];
+ }
+
+ cid->nameid = nameid;
+ cid->price = price;
+
+ return 1;
+ }else{
+ ShowWarning( "cashshop_parse_dbrow: Invalid id %d in line %d of \"%s\", skipping.\n", nameid, line, source );
+ }
+
+ return 0;
+}
+
+/*
+ * Read database from txt format,
+ * parse line and send them to parse_dbrow
+ */
static void cashshop_read_db_txt( void ){
const char* filename[] = { DBPATH"item_cash_db.txt", "item_cash_db2.txt" };
int fi;
@@ -88,6 +134,10 @@
}
}
+/*
+ * Read database from sql format,
+ * parse line and send them to parse_dbrow
+ */
static int cashshop_read_db_sql( void ){
const char* cash_db_name[] = { item_cash_db_db, item_cash_db2_db };
int fi;
@@ -128,6 +178,11 @@
return 0;
}
+/*
+ * Read cashshop database main
+ * choose wich reader to use depending of config :
+ * conf/map_athena.conf db_use_sqldbs
+ */
static void cashshop_read_db( void ){
if( db_use_sqldbs ){
cashshop_read_db_sql();
@@ -136,44 +191,12 @@
}
}
-static int cashshop_parse_dbrow( char** str, const char* source, int line ){
- uint32 nameid = atoi( str[1] );
-
- if( itemdb_exists( nameid ) ){
- uint16 tab = atoi( str[0] );
- uint32 price = atoi( str[2] );
- struct cash_item_data* cid;
- int j;
-
- if( tab > CASHSHOP_TAB_SEARCH ){
- ShowWarning( "cashshop_parse_dbrow: Invalid tab %d in line %d of \"%s\", skipping.\n", tab, line, source );
- return 0;
- }else if( price < 1 ){
- ShowWarning( "cashshop_parse_dbrow: Invalid price %d in line %d of \"%s\", skipping.\n", price, line, source );
- return 0;
- }
-
- ARR_FIND( 0, cash_shop_items[tab].count, j, nameid == cash_shop_items[tab].item[j]->nameid );
-
- if( j == cash_shop_items[tab].count ){
- RECREATE( cash_shop_items[tab].item, struct cash_item_data *, ++cash_shop_items[tab].count );
- CREATE( cash_shop_items[tab].item[ cash_shop_items[tab].count - 1], struct cash_item_data, 1 );
- cid = cash_shop_items[tab].item[ cash_shop_items[tab].count - 1];
- }else{
- cid = cash_shop_items[tab].item[j];
- }
-
- cid->nameid = nameid;
- cid->price = price;
-
- return 1;
- }else{
- ShowWarning( "cashshop_parse_dbrow: Invalid id %d in line %d of \"%s\", skipping.\n", nameid, line, source );
- }
-
- return 0;
-}
-
+/*
+ * Attempt to buy a cashshop item from list
+ * check if valid transaction and if user have enough place to receive item
+ * if yes take cashpoint and give else
+ * else return clif_error
+ */
void cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, uint16* item_list ){
uint32 totalcash = 0;
uint32 totalweight = 0;
@@ -227,10 +250,7 @@
totalweight += itemdb_weight( nameid ) * quantity;
}
- if( ( totalcash - kafrapoints ) > sd->cashPoints || kafrapoints > sd->kafraPoints ){
- clif_cashshop_result( sd, 0, CASHSHOP_RESULT_ERROR_SHORTTAGE_CASH );
- return;
- }else if( ( totalweight + sd->weight ) > sd->max_weight ){
+ if( ( totalweight + sd->weight ) > sd->max_weight ){
clif_cashshop_result( sd, 0, CASHSHOP_RESULT_ERROR_INVENTORY_WEIGHT );
return;
}else if( pc_inventoryblank( sd ) < new_ ){
@@ -238,7 +258,10 @@
return;
}
- pc_paycash( sd, totalcash, kafrapoints, LOG_TYPE_CASH );
+ if(pc_paycash( sd, totalcash, kafrapoints, LOG_TYPE_CASH ) < 0){
+ clif_cashshop_result( sd, 0, CASHSHOP_RESULT_ERROR_SHORTTAGE_CASH );
+ return;
+ }
for( i = 0; i < n; ++i ){
uint32 nameid = *( item_list + i * 5 );
@@ -273,11 +296,19 @@
clif_cashshop_result( sd, 0, CASHSHOP_RESULT_SUCCESS );
}
+/*
+ * Reload database of cashshop
+ * by destroying and read it again
+ */
void cashshop_reloaddb( void ){
do_final_cashshop();
do_init_cashshop();
}
+/*
+ * Destroy cashshop class
+ * Close all and cleanup
+ */
int do_final_cashshop( void ){
int tab, i;
@@ -285,15 +316,18 @@
for( i = 0; i < cash_shop_items[tab].count; i++ ){
aFree( cash_shop_items[tab].item[i] );
}
-
aFree( cash_shop_items[tab].item );
}
-
memset( cash_shop_items, 0, sizeof( cash_shop_items ) );
return 0;
}
+/*
+ * Initialise cashshop class
+ * return
+ * 0 : success
+ */
int do_init_cashshop( void ){
cashshop_read_db();
Index: src/common/mmo.h
===================================================================
--- src/common/mmo.h (revision 17302)
+++ src/common/mmo.h (working copy)
@@ -47,7 +47,7 @@
// 20120307 - 2012-03-07aRagexeRE+ - 0x970
#ifndef PACKETVER
- #define PACKETVER 20120410
+ #define PACKETVER 20130320
//#define PACKETVER 20111116
#endif
Index: src/config/secure.h
===================================================================
--- src/config/secure.h (revision 17302)
+++ src/config/secure.h (working copy)
@@ -24,19 +24,19 @@
+ * Number of seconds after an 'input' field is displayed before invoking an idle timeout.
+ * Default: 180
**/
-#define NPC_SECURE_TIMEOUT_INPUT 180
+#define NPC_SECURE_TIMEOUT_INPUT 30
/**
+ * Number of seconds after a 'menu' is displayed before invoking an idle timeout.
+ * Default: 60
**/
-#define NPC_SECURE_TIMEOUT_MENU 60
+#define NPC_SECURE_TIMEOUT_MENU 10
/**
+ * Number of seconds after a 'next' button is displayed before invoking an idle timeout.
+ * Default: 60
**/
-#define NPC_SECURE_TIMEOUT_NEXT 60
+#define NPC_SECURE_TIMEOUT_NEXT 10
/**
* (Secure) Optional NPC Dialog Timer
Index: db/packet_db.txt
===================================================================
--- db/packet_db.txt (revision 17302)
+++ db/packet_db.txt (working copy)
@@ -1802,7 +1802,7 @@
packet_ver: 34
0x01FD,15,repairitem,2
0x086D,26,friendslistadd,2
-0x0897,5,hommenu,2:4
+0x0897,5,changedir,2:4
0x0947,36,storagepassword,0
0x086F,26,partyinvite2,2
0x0888,19,wanttoconnection,2:6:10:14:18
@@ -1810,7 +1810,7 @@
0x089B,10,useskilltoid,2:4:6
0x0881,5,walktoxy,2
0x0363,6,ticksend,2
-0x093F,5,changedir,2:4
+0x093F,5,hommenu,2:4
0x0933,6,takeitem,2
0x0438,6,dropitem,2:4
0x08AC,8,movetokafra,2:4
@@ -1827,13 +1827,14 @@
0x0998,8,equipitem,2:4
//0x0281,-1,itemlistwindowselected,2:4:8
0x0938,-1,reqopenbuyingstore,2:4:8:9:89
-//0x0817,2,reqclosebuyingstore,0
-//0x0360,6,reqclickbuyingstore,2
+0x0886,2,reqclosebuyingstore,0
+0x035f,6,reqclickbuyingstore,2
0x0922,-1,reqtradebuyingstore,2:4:8:12
0x094E,-1,searchstoreinfo,2:4:5:9:13:14:15
//0x0835,2,searchstoreinfonextpage,0
//0x0838,12,searchstoreinfolistitemclick,2:6:10
0x0447,2
+0x990,31 //additem
0x99b,8 //maptypeproperty2
0x84b,19 //fallitem4