From bc63ef1225dadcfa2ba20a9b073de801ee177992 Mon Sep 17 00:00:00 2001 From: malufett Date: Fri, 8 Mar 2013 22:51:42 +0800 Subject: Fixed Bug #7114 -revised/added 'npc_isnear' where it checks if an NPC is nearby when making chat rooms or using vending. Signed-off-by: malufett --- src/map/battle.c | 2 +- src/map/battle.h | 2 +- src/map/clif.c | 22 ++++++++++++---------- src/map/npc.c | 18 ++++++++++++++++++ src/map/npc.h | 1 + src/map/pc.h | 4 ++-- src/map/skill.c | 10 +++++++++- src/map/vending.c | 30 +----------------------------- src/map/vending.h | 3 +-- 9 files changed, 46 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/map/battle.c b/src/map/battle.c index 2cb88b123..ba1a4970b 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -5898,7 +5898,7 @@ static const struct _battle_data { { "skill_amotion_leniency", &battle_config.skill_amotion_leniency, 90, 0, 300 }, { "mvp_tomb_enabled", &battle_config.mvp_tomb_enabled, 1, 0, 1 }, { "feature.atcommand_suggestions", &battle_config.atcommand_suggestions_enabled, 0, 0, 1 }, - { "min_npc_vending_distance", &battle_config.min_npc_vending_distance, 3, 0, 100 }, + { "min_npc_vendchat_distance", &battle_config.min_npc_vendchat_distance, 3, 0, 100 }, { "atcommand_mobinfo_type", &battle_config.atcommand_mobinfo_type, 0, 0, 1 }, { "homunculus_max_level", &battle_config.hom_max_level, 99, 0, MAX_LEVEL, }, { "homunculus_S_max_level", &battle_config.hom_S_max_level, 150, 0, MAX_LEVEL, }, diff --git a/src/map/battle.h b/src/map/battle.h index 6aa6ade03..e81990f21 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -453,7 +453,7 @@ struct Battle_Config { int mvp_tomb_enabled; int atcommand_suggestions_enabled; - int min_npc_vending_distance; + int min_npc_vendchat_distance; int atcommand_mobinfo_type; int mob_size_influence; // Enable modifications on earned experience, drop rates and monster status depending on monster size. [mkbu95] diff --git a/src/map/clif.c b/src/map/clif.c index bfde233c5..ed9eb1769 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -10400,6 +10400,14 @@ void clif_parse_CreateChatRoom(int fd, struct map_session_data* sd) clif_skill_fail(sd,1,USESKILL_FAIL_LEVEL,3); return; } + if( npc_isnear(&sd->bl) ) { + // uncomment for more verbose message. + //char output[150]; + //sprintf(output, msg_txt(662), battle_config.min_npc_vendchat_distance); + //clif_displaymessage(sd->fd, output); + clif_skill_fail(sd,1,USESKILL_FAIL_THERE_ARE_NPC_AROUND,0); + return; + } if( len <= 0 ) return; // invalid input @@ -11890,6 +11898,9 @@ void clif_parse_OpenVending(int fd, struct map_session_data* sd) const char* message = (char*)RFIFOP(fd,4); bool flag = (bool)RFIFOB(fd,84); const uint8* data = (uint8*)RFIFOP(fd,85); + + if( !flag ) + sd->state.prevend = 0; if( sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOROOM ) return; @@ -11902,21 +11913,12 @@ void clif_parse_OpenVending(int fd, struct map_session_data* sd) return; } - if( vending_checknearnpc(&sd->bl) ) { - char output[150]; - sprintf(output, msg_txt(662), battle_config.min_npc_vending_distance); - clif_displaymessage(sd->fd, output); - clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0); - return; - } - if( message[0] == '\0' ) // invalid input return; - vending_openvending(sd, message, flag, data, len/8); + vending_openvending(sd, message, data, len/8); } - /// Guild creation request (CZ_REQ_MAKE_GUILD). /// 0165 .L .24B void clif_parse_CreateGuild(int fd,struct map_session_data *sd) diff --git a/src/map/npc.c b/src/map/npc.c index e032a28a7..0c9924d46 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -113,6 +113,24 @@ struct view_data* npc_get_viewdata(int class_) return NULL; } +static int npc_isnear_sub(struct block_list* bl, va_list args) { + struct npc_data *nd = (struct npc_data*)bl; + + if( nd->sc.option & (OPTION_HIDE|OPTION_INVISIBLE) ) + return 0; + + return 1; +} + +bool npc_isnear(struct block_list * bl) { + + if( battle_config.min_npc_vendchat_distance > 0 && + map_foreachinrange(npc_isnear_sub,bl, battle_config.min_npc_vendchat_distance, BL_NPC) ) + return true; + + return false; +} + int npc_ontouch_event(struct map_session_data *sd, struct npc_data *nd) { char name[EVENT_NAME_LENGTH]; diff --git a/src/map/npc.h b/src/map/npc.h index 7b69cac34..20ce34459 100644 --- a/src/map/npc.h +++ b/src/map/npc.h @@ -134,6 +134,7 @@ int npc_enable(const char* name, int flag); void npc_setdisplayname(struct npc_data* nd, const char* newname); void npc_setclass(struct npc_data* nd, short class_); struct npc_data* npc_name2id(const char* name); +bool npc_isnear(struct block_list * bl); int npc_get_new_npc_id(void); diff --git a/src/map/pc.h b/src/map/pc.h index 1b00b7191..d62c6359e 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -593,10 +593,10 @@ enum equip_index { #define pc_issit(sd) ( (sd)->vd.dead_sit == 2 ) #define pc_isidle(sd) ( (sd)->chatID || (sd)->state.vending || (sd)->state.buyingstore || DIFF_TICK(last_tick, (sd)->idletime) >= battle_config.idle_no_share ) #define pc_istrading(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->state.trading ) -#define pc_cant_act(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->chatID || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag ) +#define pc_cant_act(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->chatID || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.prevend ) /* equals pc_cant_act except it doesn't check for chat rooms */ -#define pc_cant_act2(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag ) +#define pc_cant_act2(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.prevend ) #define pc_setdir(sd,b,h) ( (sd)->ud.dir = (b) ,(sd)->head_dir = (h) ) #define pc_setchatid(sd,n) ( (sd)->chatID = n ) diff --git a/src/map/skill.c b/src/map/skill.c index a8b852cc7..fdfdbcee7 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -571,8 +571,16 @@ int skillnotok (uint16 skill_id, struct map_session_data *sd) } break; case MC_VENDING: - case MC_IDENTIFY: case ALL_BUYING_STORE: + if( npc_isnear(&sd->bl) ) { + // uncomment for more verbose message. + //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 1; + } + case MC_IDENTIFY: return 0; // always allowed case WZ_ICEWALL: // noicewall flag [Valaris] diff --git a/src/map/vending.c b/src/map/vending.c index 0f8255788..5f0ac7501 100644 --- a/src/map/vending.c +++ b/src/map/vending.c @@ -231,34 +231,16 @@ void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const ui } } } -static int vending_checknearnpc_sub(struct block_list* bl, va_list args) { - struct npc_data *nd = (struct npc_data*)bl; - - if( nd->sc.option & (OPTION_HIDE|OPTION_INVISIBLE) ) - return 0; - return 1; -} -bool vending_checknearnpc(struct block_list * bl) { - - if( battle_config.min_npc_vending_distance > 0 && - map_foreachinrange(vending_checknearnpc_sub,bl, battle_config.min_npc_vending_distance, BL_NPC) ) - return true; - - return false; -} /*========================================== * Open shop * data := {.w .w .l}[count] *------------------------------------------*/ -void vending_openvending(struct map_session_data* sd, const char* message, bool flag, const uint8* data, int count) { +void vending_openvending(struct map_session_data* sd, const char* message, const uint8* data, int count) { int i, j; int vending_skill_lvl; nullpo_retv(sd); - if( !flag ) // cancelled - return; // nothing to do - if ( pc_isdead(sd) || !sd->state.prevend || pc_istrading(sd)) return; // can't open vendings lying dead || didn't use via the skill (wpe/hack) || can't have 2 shops at once @@ -276,15 +258,6 @@ void vending_openvending(struct map_session_data* sd, const char* message, bool clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0); return; } - //check if nearby npc, (perhaps we should check for nearby shop too - if( vending_checknearnpc(&sd->bl) ) { - char output[150]; - sprintf(output,"You're too close to a NPC, you must be at least %d cells away from any NPC.",battle_config.min_npc_vending_distance); - clif_displaymessage(sd->fd, output); - clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0); - return; - } - // filter out invalid items i = 0; @@ -326,7 +299,6 @@ void vending_openvending(struct map_session_data* sd, const char* message, bool sd->vend_num = i; safestrncpy(sd->message, message, MESSAGE_SIZE); - pc_stop_walking(sd,1); clif_openvending(sd,sd->bl.id,sd->vending); clif_showvendingboard(&sd->bl,message,0); } diff --git a/src/map/vending.h b/src/map/vending.h index 2ed52b9bd..402df5579 100644 --- a/src/map/vending.h +++ b/src/map/vending.h @@ -16,11 +16,10 @@ struct s_vending { }; void vending_closevending(struct map_session_data* sd); -void vending_openvending(struct map_session_data* sd, const char* message, bool flag, const uint8* data, int count); +void vending_openvending(struct map_session_data* sd, const char* message, const uint8* data, int count); 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, unsigned short nameid); bool vending_searchall(struct map_session_data* sd, const struct s_search_store_search* s); -bool vending_checknearnpc(struct block_list * bl); #endif /* _VENDING_H_ */ -- cgit v1.2.3-70-g09d2