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 <aleos89@users.noreply.github.com>
Co-authored-by: Lemongrass3110 <lemongrass@kstp.at>
This commit is contained in:
Cydh Ramdh 2022-04-01 04:08:35 +07:00 committed by GitHub
parent e4e8063ec3
commit 16ccad42e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 121 additions and 23 deletions

View File

@ -145,9 +145,20 @@ Notes:
--------------------------------------- ---------------------------------------
*nochat *nochat
Disables chatroom creation on a map.
---------------------------------------
*novending *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.
--------------------------------------- ---------------------------------------

View File

@ -26,6 +26,7 @@
#include "achievement.hpp" #include "achievement.hpp"
#include "battle.hpp" #include "battle.hpp"
#include "buyingstore.hpp"
#include "channel.hpp" #include "channel.hpp"
#include "chat.hpp" #include "chat.hpp"
#include "chrif.hpp" #include "chrif.hpp"
@ -53,6 +54,7 @@
#include "script.hpp" #include "script.hpp"
#include "storage.hpp" #include "storage.hpp"
#include "trade.hpp" #include "trade.hpp"
#include "vending.hpp"
using namespace rathena; using namespace rathena;
@ -4482,6 +4484,8 @@ ACMD_FUNC(mapinfo) {
strcat(atcmd_output, " NoTrade |"); strcat(atcmd_output, " NoTrade |");
if (map_getmapflag(m_id, MF_NOVENDING)) if (map_getmapflag(m_id, MF_NOVENDING))
strcat(atcmd_output, " NoVending |"); strcat(atcmd_output, " NoVending |");
if (map_getmapflag(m_id, MF_NOBUYINGSTORE))
strcat(atcmd_output, " NoBuyingstore |");
if (map_getmapflag(m_id, MF_NODROP)) if (map_getmapflag(m_id, MF_NODROP))
strcat(atcmd_output, " NoDrop |"); strcat(atcmd_output, " NoDrop |");
if (map_getmapflag(m_id, MF_NOSKILL)) if (map_getmapflag(m_id, MF_NOSKILL))
@ -6385,13 +6389,9 @@ ACMD_FUNC(autotrade) {
sd->state.block_action |= PCBLOCK_IMMUNE; sd->state.block_action |= PCBLOCK_IMMUNE;
if( sd->state.vending ){ if( sd->state.vending ){
if( Sql_Query( mmysql_handle, "UPDATE `%s` SET `autotrade` = 1 WHERE `id` = %d;", vendings_table, sd->vender_id ) != SQL_SUCCESS ){ vending_update(*sd);
Sql_ShowDebug( mmysql_handle );
}
}else if( sd->state.buyingstore ){ }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 ){ buyingstore_update(*sd);
Sql_ShowDebug( mmysql_handle );
}
} }
if( battle_config.at_timeout ) { if( battle_config.at_timeout ) {

View File

@ -78,14 +78,14 @@ int8 buyingstore_setup(struct map_session_data* sd, unsigned char slots){
return 2; return 2;
} }
if( map_getmapflag(sd->bl.m, MF_NOVENDING) ) if( map_getmapflag(sd->bl.m, MF_NOBUYINGSTORE) )
{// custom: no vending maps {// custom: no buyingstore maps
clif_displaymessage(sd->fd, msg_txt(sd,276)); // "You can't open a shop on this map" clif_displaymessage(sd->fd, msg_txt(sd,276)); // "You can't open a shop on this map"
return 3; return 3;
} }
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) )
{// custom: no vending cells {// custom: no buyingstore cells
clif_displaymessage(sd->fd, msg_txt(sd,204)); // "You can't open a shop on this cell." clif_displaymessage(sd->fd, msg_txt(sd,204)); // "You can't open a shop on this cell."
return 4; return 4;
} }
@ -145,14 +145,14 @@ int8 buyingstore_create( struct map_session_data* sd, int zenylimit, unsigned ch
return 2; return 2;
} }
if( map_getmapflag(sd->bl.m, MF_NOVENDING) ) if( map_getmapflag(sd->bl.m, MF_NOBUYINGSTORE) )
{// custom: no vending maps {// custom: no buyingstore maps
clif_displaymessage(sd->fd, msg_txt(sd,276)); // "You can't open a shop on this map" clif_displaymessage(sd->fd, msg_txt(sd,276)); // "You can't open a shop on this map"
return 3; return 3;
} }
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) )
{// custom: no vending cells {// custom: no buyingstore cells
clif_displaymessage(sd->fd, msg_txt(sd,204)); // "You can't open a shop on this cell." clif_displaymessage(sd->fd, msg_txt(sd,204)); // "You can't open a shop on this cell."
return 4; return 4;
} }
@ -798,6 +798,20 @@ static int buyingstore_autotrader_free(DBKey key, DBData *data, va_list ap) {
return 0; 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 * Initialise the buyingstore module
* called in map::do_init * called in map::do_init

View File

@ -68,5 +68,6 @@ void do_init_buyingstore(void);
void do_init_buyingstore_autotrade( void ); void do_init_buyingstore_autotrade( void );
void buyingstore_reopen( struct map_session_data* sd ); void buyingstore_reopen( struct map_session_data* sd );
void buyingstore_update(map_session_data &sd);
#endif /* BUYINGSTORE_HPP */ #endif /* BUYINGSTORE_HPP */

View File

@ -18944,6 +18944,15 @@ static void clif_parse_ReqOpenBuyingStore( int fd, struct map_session_data* sd )
return; 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]; char storename[MESSAGE_SIZE];
safestrncpy( storename, p->storeName, sizeof( storename ) ); safestrncpy( storename, p->storeName, sizeof( storename ) );

View File

@ -3189,6 +3189,8 @@ int map_getcellp(struct map_data* m,int16 x,int16 y,cell_chk cellchk)
return (cell.landprotector); return (cell.landprotector);
case CELL_CHKNOVENDING: case CELL_CHKNOVENDING:
return (cell.novending); return (cell.novending);
case CELL_CHKNOBUYINGSTORE:
return (cell.nobuyingstore);
case CELL_CHKNOCHAT: case CELL_CHKNOCHAT:
return (cell.nochat); return (cell.nochat);
case CELL_CHKMAELSTROM: 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_NOCHAT: mapdata->cell[j].nochat = flag; break;
case CELL_MAELSTROM: mapdata->cell[j].maelstrom = flag; break; case CELL_MAELSTROM: mapdata->cell[j].maelstrom = flag; break;
case CELL_ICEWALL: mapdata->cell[j].icewall = flag; break; case CELL_ICEWALL: mapdata->cell[j].icewall = flag; break;
case CELL_NOBUYINGSTORE: mapdata->cell[j].nobuyingstore = flag; break;
default: default:
ShowWarning("map_setcell: invalid cell type '%d'\n", (int)cell); ShowWarning("map_setcell: invalid cell type '%d'\n", (int)cell);
break; break;

View File

@ -649,6 +649,7 @@ enum e_mapflag : int16 {
MF_NORENEWALEXPPENALTY, MF_NORENEWALEXPPENALTY,
MF_NORENEWALDROPPENALTY, MF_NORENEWALDROPPENALTY,
MF_NOPETCAPTURE, MF_NOPETCAPTURE,
MF_NOBUYINGSTORE,
MF_MAX MF_MAX
}; };
@ -711,7 +712,7 @@ enum cell_t{
CELL_NOCHAT, CELL_NOCHAT,
CELL_MAELSTROM, CELL_MAELSTROM,
CELL_ICEWALL, CELL_ICEWALL,
CELL_NOBUYINGSTORE,
}; };
// used by map_getcell() // used by map_getcell()
@ -735,6 +736,7 @@ enum cell_chk : uint8 {
CELL_CHKNOCHAT, // Whether the cell denies Player Chat Window CELL_CHKNOCHAT, // Whether the cell denies Player Chat Window
CELL_CHKMAELSTROM, // Whether the cell has Maelstrom CELL_CHKMAELSTROM, // Whether the cell has Maelstrom
CELL_CHKICEWALL, // Whether the cell has Ice Wall 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, novending : 1,
nochat : 1, nochat : 1,
maelstrom : 1, maelstrom : 1,
icewall : 1; icewall : 1,
nobuyingstore : 1;
#ifdef CELL_NOSTACK #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.

View File

@ -6312,11 +6312,19 @@ enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, in
bg_send_dot_remove(sd); bg_send_dot_remove(sd);
if (sd->regen.state.gc) if (sd->regen.state.gc)
sd->regen.state.gc = 0; sd->regen.state.gc = 0;
if (mapdata) {
// make sure vending is allowed here // make sure vending is allowed here
if (sd->state.vending && mapdata && mapdata->flag[MF_NOVENDING]) { 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" clif_displaymessage(sd->fd, msg_txt(sd, 276)); // "You can't open a shop on this map"
vending_closevending(sd); 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 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 if (sd->state.vending) // Stop vending
vending_closevending(sd); vending_closevending(sd);
if (sd->state.buyingstore) // Stop buyingstore
buyingstore_close(sd);
npc_script_event(sd, NPCE_LOGOUT); npc_script_event(sd, NPCE_LOGOUT);
//remove from map, THEN change x/y coordinates //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." clif_displaymessage (sd->fd, msg_txt(sd,204)); // "You can't open a shop on this cell."
vending_closevending(sd); 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){ if(sd->bl.prev != NULL){
unit_remove_map_pc(sd,clrtype); unit_remove_map_pc(sd,clrtype);
@ -6459,6 +6473,11 @@ enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, in
else else
sd->count_rewarp = 0; sd->count_rewarp = 0;
if (sd->state.vending)
vending_update(*sd);
if (sd->state.buyingstore)
buyingstore_update(*sd);
return SETPOS_OK; return SETPOS_OK;
} }

View File

@ -534,6 +534,7 @@
export_constant(MF_NORENEWALDROPPENALTY); export_constant(MF_NORENEWALDROPPENALTY);
export_constant(MF_NORENEWALEXPPENALTY); export_constant(MF_NORENEWALEXPPENALTY);
export_constant(MF_NOPETCAPTURE); export_constant(MF_NOPETCAPTURE);
export_constant(MF_NOBUYINGSTORE);
/* setcell types */ /* setcell types */
export_constant(CELL_WALKABLE); export_constant(CELL_WALKABLE);
@ -546,6 +547,7 @@
export_constant(CELL_NOCHAT); export_constant(CELL_NOCHAT);
export_constant(CELL_MAELSTROM); export_constant(CELL_MAELSTROM);
export_constant(CELL_ICEWALL); export_constant(CELL_ICEWALL);
export_constant(CELL_NOBUYINGSTORE);
/* getcell types */ /* getcell types */
export_constant(CELL_CHKWALL); export_constant(CELL_CHKWALL);
@ -564,6 +566,7 @@
export_constant(CELL_CHKNOCHAT); export_constant(CELL_CHKNOCHAT);
export_constant(CELL_CHKMAELSTROM); export_constant(CELL_CHKMAELSTROM);
export_constant(CELL_CHKICEWALL); export_constant(CELL_CHKICEWALL);
export_constant(CELL_CHKNOBUYINGSTORE);
/* parameters */ /* parameters */
export_parameter("StatusPoint",SP_STATUSPOINT); export_parameter("StatusPoint",SP_STATUSPOINT);

View File

@ -906,13 +906,32 @@ bool skill_isNotOk(uint16 skill_id, struct map_session_data *sd)
} }
break; break;
case MC_VENDING: 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: 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_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); clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return true; 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_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); clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return true; 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); clif_skill_fail(sd,skill_id,USESKILL_FAIL_THERE_ARE_NPC_AROUND,0);
return true; return true;
} }
break;
case MC_IDENTIFY: case MC_IDENTIFY:
return false; // always allowed return false; // always allowed
case WZ_ICEWALL: case WZ_ICEWALL:

View File

@ -710,6 +710,20 @@ static int vending_autotrader_free(DBKey key, DBData *data, va_list ap) {
return 0; return 0;
} }
/**
* 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 * Initialise the vending module
* called in map::do_init * called in map::do_init

View File

@ -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); 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_search(struct map_session_data* sd, t_itemid nameid);
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);
void vending_update(map_session_data &sd);
#endif /* _VENDING_HPP_ */ #endif /* _VENDING_HPP_ */