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
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.
---------------------------------------

View File

@ -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 ) {

View File

@ -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

View File

@ -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 */

View File

@ -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 ) );

View File

@ -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;

View File

@ -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.

View File

@ -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;
}

View File

@ -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);

View File

@ -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:

View File

@ -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
*/

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);
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_ */