From 16ccad42e8be8ee861fd015d9d564e581a01e598 Mon Sep 17 00:00:00 2001 From: Cydh Ramdh Date: Fri, 1 Apr 2022 04:08:35 +0700 Subject: [PATCH] Update vending and buyingstore on warp (#6718) Fixed #6671, vendor & buyer location never been updated if the location is changed Added MF_NOBUYINGSTORE and CELL_NOBUYINGSTORE to separate from MF_VENDING & CELL_NOVENDING Added some missing check for buyingstore states Updated mapflag doc Added new constants Co-authored-by: Aleos Co-authored-by: Lemongrass3110 --- doc/mapflags.txt | 13 ++++++++++++- src/map/atcommand.cpp | 12 ++++++------ src/map/buyingstore.cpp | 30 ++++++++++++++++++++++-------- src/map/buyingstore.hpp | 1 + src/map/clif.cpp | 9 +++++++++ src/map/map.cpp | 3 +++ src/map/map.hpp | 7 +++++-- src/map/pc.cpp | 27 +++++++++++++++++++++++---- src/map/script_constants.hpp | 3 +++ src/map/skill.cpp | 24 ++++++++++++++++++++++-- src/map/vending.cpp | 14 ++++++++++++++ src/map/vending.hpp | 1 + 12 files changed, 121 insertions(+), 23 deletions(-) diff --git a/doc/mapflags.txt b/doc/mapflags.txt index 7af58254bf..143a13a047 100644 --- a/doc/mapflags.txt +++ b/doc/mapflags.txt @@ -145,9 +145,20 @@ Notes: --------------------------------------- *nochat + +Disables chatroom creation on a map. + +--------------------------------------- + *novending -Disables chatroom and shop creation on a map. +Disables shop creation on a map from the MC_VENDING skill. + +--------------------------------------- + +*nobuyingstore + +Disables shop creation on a map from the ALL_BUYING_STORE skill. --------------------------------------- diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp index f676f700c2..3c9d05f33f 100644 --- a/src/map/atcommand.cpp +++ b/src/map/atcommand.cpp @@ -26,6 +26,7 @@ #include "achievement.hpp" #include "battle.hpp" +#include "buyingstore.hpp" #include "channel.hpp" #include "chat.hpp" #include "chrif.hpp" @@ -53,6 +54,7 @@ #include "script.hpp" #include "storage.hpp" #include "trade.hpp" +#include "vending.hpp" using namespace rathena; @@ -4482,6 +4484,8 @@ ACMD_FUNC(mapinfo) { strcat(atcmd_output, " NoTrade |"); if (map_getmapflag(m_id, MF_NOVENDING)) strcat(atcmd_output, " NoVending |"); + if (map_getmapflag(m_id, MF_NOBUYINGSTORE)) + strcat(atcmd_output, " NoBuyingstore |"); if (map_getmapflag(m_id, MF_NODROP)) strcat(atcmd_output, " NoDrop |"); if (map_getmapflag(m_id, MF_NOSKILL)) @@ -6385,13 +6389,9 @@ ACMD_FUNC(autotrade) { sd->state.block_action |= PCBLOCK_IMMUNE; if( sd->state.vending ){ - if( Sql_Query( mmysql_handle, "UPDATE `%s` SET `autotrade` = 1 WHERE `id` = %d;", vendings_table, sd->vender_id ) != SQL_SUCCESS ){ - Sql_ShowDebug( mmysql_handle ); - } + vending_update(*sd); }else if( sd->state.buyingstore ){ - if( Sql_Query( mmysql_handle, "UPDATE `%s` SET `autotrade` = 1 WHERE `id` = %d;", buyingstores_table, sd->buyer_id ) != SQL_SUCCESS ){ - Sql_ShowDebug( mmysql_handle ); - } + buyingstore_update(*sd); } if( battle_config.at_timeout ) { diff --git a/src/map/buyingstore.cpp b/src/map/buyingstore.cpp index ecfa881f01..0e5da97478 100644 --- a/src/map/buyingstore.cpp +++ b/src/map/buyingstore.cpp @@ -78,14 +78,14 @@ int8 buyingstore_setup(struct map_session_data* sd, unsigned char slots){ return 2; } - if( map_getmapflag(sd->bl.m, MF_NOVENDING) ) - {// custom: no vending maps + if( map_getmapflag(sd->bl.m, MF_NOBUYINGSTORE) ) + {// custom: no buyingstore maps clif_displaymessage(sd->fd, msg_txt(sd,276)); // "You can't open a shop on this map" return 3; } - if( map_getcell(sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKNOVENDING) ) - {// custom: no vending cells + if( map_getcell(sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKNOBUYINGSTORE) ) + {// custom: no buyingstore cells clif_displaymessage(sd->fd, msg_txt(sd,204)); // "You can't open a shop on this cell." return 4; } @@ -145,14 +145,14 @@ int8 buyingstore_create( struct map_session_data* sd, int zenylimit, unsigned ch return 2; } - if( map_getmapflag(sd->bl.m, MF_NOVENDING) ) - {// custom: no vending maps + if( map_getmapflag(sd->bl.m, MF_NOBUYINGSTORE) ) + {// custom: no buyingstore maps clif_displaymessage(sd->fd, msg_txt(sd,276)); // "You can't open a shop on this map" return 3; } - if( map_getcell(sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKNOVENDING) ) - {// custom: no vending cells + if( map_getcell(sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKNOBUYINGSTORE) ) + {// custom: no buyingstore cells clif_displaymessage(sd->fd, msg_txt(sd,204)); // "You can't open a shop on this cell." return 4; } @@ -798,6 +798,20 @@ static int buyingstore_autotrader_free(DBKey key, DBData *data, va_list ap) { return 0; } +/** +* Update buyer location +* @param sd: Player's session data +*/ +void buyingstore_update(map_session_data &sd) +{ + if (Sql_Query(mmysql_handle, "UPDATE `%s` SET `map` = '%s', `x` = '%d', `y` = '%d', `body_direction` = '%d', `head_direction` = '%d', `sit` = '%d', `autotrade` = '%d' WHERE `id` = '%d'", + buyingstores_table, map_getmapdata(sd.bl.m)->name, sd.bl.x, sd.bl.y, sd.ud.dir, sd.head_dir, pc_issit(&sd), sd.state.autotrade, + sd.buyer_id + ) != SQL_SUCCESS) { + Sql_ShowDebug(mmysql_handle); + } +} + /** * Initialise the buyingstore module * called in map::do_init diff --git a/src/map/buyingstore.hpp b/src/map/buyingstore.hpp index 6ca712eaca..d4c594f30d 100644 --- a/src/map/buyingstore.hpp +++ b/src/map/buyingstore.hpp @@ -68,5 +68,6 @@ void do_init_buyingstore(void); void do_init_buyingstore_autotrade( void ); void buyingstore_reopen( struct map_session_data* sd ); +void buyingstore_update(map_session_data &sd); #endif /* BUYINGSTORE_HPP */ diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 889d94bafe..a0e609847e 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -18944,6 +18944,15 @@ static void clif_parse_ReqOpenBuyingStore( int fd, struct map_session_data* sd ) return; } + if (map_getmapflag(sd->bl.m, MF_NOBUYINGSTORE)) { + clif_displaymessage(sd->fd, msg_txt(sd, 276)); // "You can't open a shop on this map" + return; + } + if (map_getcell(sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKNOBUYINGSTORE)) { + clif_displaymessage(sd->fd, msg_txt(sd, 204)); // "You can't open a shop on this cell." + return; + } + char storename[MESSAGE_SIZE]; safestrncpy( storename, p->storeName, sizeof( storename ) ); diff --git a/src/map/map.cpp b/src/map/map.cpp index 8c3a4392ac..496b65adc5 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -3189,6 +3189,8 @@ int map_getcellp(struct map_data* m,int16 x,int16 y,cell_chk cellchk) return (cell.landprotector); case CELL_CHKNOVENDING: return (cell.novending); + case CELL_CHKNOBUYINGSTORE: + return (cell.nobuyingstore); case CELL_CHKNOCHAT: return (cell.nochat); case CELL_CHKMAELSTROM: @@ -3250,6 +3252,7 @@ void map_setcell(int16 m, int16 x, int16 y, cell_t cell, bool flag) case CELL_NOCHAT: mapdata->cell[j].nochat = flag; break; case CELL_MAELSTROM: mapdata->cell[j].maelstrom = flag; break; case CELL_ICEWALL: mapdata->cell[j].icewall = flag; break; + case CELL_NOBUYINGSTORE: mapdata->cell[j].nobuyingstore = flag; break; default: ShowWarning("map_setcell: invalid cell type '%d'\n", (int)cell); break; diff --git a/src/map/map.hpp b/src/map/map.hpp index 47ea754136..31d83118b2 100644 --- a/src/map/map.hpp +++ b/src/map/map.hpp @@ -649,6 +649,7 @@ enum e_mapflag : int16 { MF_NORENEWALEXPPENALTY, MF_NORENEWALDROPPENALTY, MF_NOPETCAPTURE, + MF_NOBUYINGSTORE, MF_MAX }; @@ -711,7 +712,7 @@ enum cell_t{ CELL_NOCHAT, CELL_MAELSTROM, CELL_ICEWALL, - + CELL_NOBUYINGSTORE, }; // used by map_getcell() @@ -735,6 +736,7 @@ enum cell_chk : uint8 { CELL_CHKNOCHAT, // Whether the cell denies Player Chat Window CELL_CHKMAELSTROM, // Whether the cell has Maelstrom CELL_CHKICEWALL, // Whether the cell has Ice Wall + CELL_CHKNOBUYINGSTORE, // Whether the cell denies ALL_BUYING_STORE skill }; @@ -754,7 +756,8 @@ struct mapcell novending : 1, nochat : 1, maelstrom : 1, - icewall : 1; + icewall : 1, + nobuyingstore : 1; #ifdef CELL_NOSTACK unsigned char cell_bl; //Holds amount of bls in this cell. diff --git a/src/map/pc.cpp b/src/map/pc.cpp index c45c162865..24cb9108b3 100755 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -6312,10 +6312,18 @@ enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, in 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 && mapdata && mapdata->flag[MF_NOVENDING]) { - clif_displaymessage (sd->fd, msg_txt(sd,276)); // "You can't open a shop on this map" - vending_closevending(sd); + + if (mapdata) { + // make sure vending is allowed here + if (sd->state.vending && mapdata->flag[MF_NOVENDING]) { + clif_displaymessage(sd->fd, msg_txt(sd, 276)); // "You can't open a shop on this map" + vending_closevending(sd); + } + // make sure buyingstore is allowed here + if (sd->state.buyingstore && mapdata->flag[MF_NOBUYINGSTORE]) { + clif_displaymessage(sd->fd, msg_txt(sd, 276)); // "You can't open a shop on this map" + buyingstore_close(sd); + } } channel_pcquit(sd,4); //quit map chan @@ -6353,6 +6361,8 @@ enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, in if (sd->state.vending) // Stop vending vending_closevending(sd); + if (sd->state.buyingstore) // Stop buyingstore + buyingstore_close(sd); npc_script_event(sd, NPCE_LOGOUT); //remove from map, THEN change x/y coordinates @@ -6400,6 +6410,10 @@ enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, in clif_displaymessage (sd->fd, msg_txt(sd,204)); // "You can't open a shop on this cell." vending_closevending(sd); } + if (sd->state.buyingstore && map_getcell(m, x, y, CELL_CHKNOBUYINGSTORE)) { + clif_displaymessage(sd->fd, msg_txt(sd, 204)); // "You can't open a shop on this cell." + buyingstore_close(sd); + } if(sd->bl.prev != NULL){ unit_remove_map_pc(sd,clrtype); @@ -6458,6 +6472,11 @@ enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, in } else sd->count_rewarp = 0; + + if (sd->state.vending) + vending_update(*sd); + if (sd->state.buyingstore) + buyingstore_update(*sd); return SETPOS_OK; } diff --git a/src/map/script_constants.hpp b/src/map/script_constants.hpp index 42708233cb..fd0933751e 100644 --- a/src/map/script_constants.hpp +++ b/src/map/script_constants.hpp @@ -534,6 +534,7 @@ export_constant(MF_NORENEWALDROPPENALTY); export_constant(MF_NORENEWALEXPPENALTY); export_constant(MF_NOPETCAPTURE); + export_constant(MF_NOBUYINGSTORE); /* setcell types */ export_constant(CELL_WALKABLE); @@ -546,6 +547,7 @@ export_constant(CELL_NOCHAT); export_constant(CELL_MAELSTROM); export_constant(CELL_ICEWALL); + export_constant(CELL_NOBUYINGSTORE); /* getcell types */ export_constant(CELL_CHKWALL); @@ -564,6 +566,7 @@ export_constant(CELL_CHKNOCHAT); export_constant(CELL_CHKMAELSTROM); export_constant(CELL_CHKICEWALL); + export_constant(CELL_CHKNOBUYINGSTORE); /* parameters */ export_parameter("StatusPoint",SP_STATUSPOINT); diff --git a/src/map/skill.cpp b/src/map/skill.cpp index 595db869c4..82c73b5853 100755 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -906,13 +906,32 @@ bool skill_isNotOk(uint16 skill_id, struct map_session_data *sd) } break; case MC_VENDING: + if (map_getmapflag(sd->bl.m, MF_NOVENDING)) { + clif_displaymessage(sd->fd, msg_txt(sd, 276)); // "You can't open a shop on this map" + clif_skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0); + return true; + } + if (map_getcell(sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKNOVENDING)) { + clif_displaymessage(sd->fd, msg_txt(sd, 204)); // "You can't open a shop on this cell." + clif_skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0); + return true; + } + if (npc_isnear(&sd->bl)) { + // uncomment to send msg_txt. + //char output[150]; + //sprintf(output, msg_txt(662), battle_config.min_npc_vendchat_distance); + //clif_displaymessage(sd->fd, output); + clif_skill_fail(sd, skill_id, USESKILL_FAIL_THERE_ARE_NPC_AROUND, 0); + return true; + } + break; case ALL_BUYING_STORE: - if( map_getmapflag(sd->bl.m, MF_NOVENDING) ) { + if( map_getmapflag(sd->bl.m, MF_NOBUYINGSTORE) ) { clif_displaymessage (sd->fd, msg_txt(sd,276)); // "You can't open a shop on this map" clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); return true; } - if( map_getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKNOVENDING) ) { + if( map_getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKNOBUYINGSTORE) ) { clif_displaymessage (sd->fd, msg_txt(sd,204)); // "You can't open a shop on this cell." clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); return true; @@ -925,6 +944,7 @@ bool skill_isNotOk(uint16 skill_id, struct map_session_data *sd) clif_skill_fail(sd,skill_id,USESKILL_FAIL_THERE_ARE_NPC_AROUND,0); return true; } + break; case MC_IDENTIFY: return false; // always allowed case WZ_ICEWALL: diff --git a/src/map/vending.cpp b/src/map/vending.cpp index 82ebf24de0..1e0a5cc7a7 100755 --- a/src/map/vending.cpp +++ b/src/map/vending.cpp @@ -711,6 +711,20 @@ static int vending_autotrader_free(DBKey key, DBData *data, va_list ap) { } /** +* Update vendor location +* @param sd: Player's session data +*/ +void vending_update(map_session_data &sd) +{ + if (Sql_Query(mmysql_handle, "UPDATE `%s` SET `map` = '%s', `x` = '%d', `y` = '%d', `body_direction` = '%d', `head_direction` = '%d', `sit` = '%d', `autotrade` = '%d' WHERE `id` = '%d'", + vendings_table, map_getmapdata(sd.bl.m)->name, sd.bl.x, sd.bl.y, sd.ud.dir, sd.head_dir, pc_issit(&sd), sd.state.autotrade, + sd.vender_id + ) != SQL_SUCCESS) { + Sql_ShowDebug(mmysql_handle); + } +} + +/** * Initialise the vending module * called in map::do_init */ diff --git a/src/map/vending.hpp b/src/map/vending.hpp index f01c28c7a2..fa6c7592a2 100644 --- a/src/map/vending.hpp +++ b/src/map/vending.hpp @@ -30,5 +30,6 @@ 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, t_itemid nameid); bool vending_searchall(struct map_session_data* sd, const struct s_search_store_search* s); +void vending_update(map_session_data &sd); #endif /* _VENDING_HPP_ */