summaryrefslogtreecommitdiff
path: root/src/map/clif.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/clif.c')
-rw-r--r--src/map/clif.c601
1 files changed, 420 insertions, 181 deletions
diff --git a/src/map/clif.c b/src/map/clif.c
index 649df3e33..b2567d668 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -2431,23 +2431,26 @@ static void clif_scriptinput(struct map_session_data *sd, int npcid)
/// - close inputstr window
static void clif_scriptinputstr(struct map_session_data *sd, int npcid)
{
- int fd;
- struct block_list *bl = NULL;
-
nullpo_retv(sd);
- if (!sd->state.using_fake_npc && (npcid == npc->fake_nd->bl.id || ((bl = map->id2bl(npcid)) != NULL && (bl->m!=sd->bl.m ||
- bl->x<sd->bl.x-AREA_SIZE-1 || bl->x>sd->bl.x+AREA_SIZE+1 ||
- bl->y<sd->bl.y-AREA_SIZE-1 || bl->y>sd->bl.y+AREA_SIZE+1))))
+ struct block_list *bl = map->id2bl(npcid);
+ int x1 = sd->bl.x - AREA_SIZE - 1;
+ int x2 = sd->bl.x + AREA_SIZE + 1;
+ int y1 = sd->bl.y - AREA_SIZE - 1;
+ int y2 = sd->bl.y + AREA_SIZE + 1;
+ bool out_of_sight = (bl != NULL && (bl->m != sd->bl.m || bl->x < x1 || bl->x > x2 || bl->y < y1 || bl->y > y2));
+
+ if (sd->state.using_fake_npc == 0 && sd->state.using_megaphone == 0
+ && (npcid == npc->fake_nd->bl.id || out_of_sight)) {
clif->sendfakenpc(sd, npcid);
+ }
pc->update_idle_time(sd, BCIDLE_SCRIPT);
- fd=sd->fd;
- WFIFOHEAD(fd, packet_len(0x1d4));
- WFIFOW(fd,0)=0x1d4;
- WFIFOL(fd,2)=npcid;
- WFIFOSET(fd,packet_len(0x1d4));
+ WFIFOHEAD(sd->fd, packet_len(0x1d4));
+ WFIFOW(sd->fd, 0) = 0x1d4;
+ WFIFOL(sd->fd, 2) = (sd->state.using_megaphone == 0) ? npcid : 0;
+ WFIFOSET(sd->fd, packet_len(0x1d4));
}
/// Marks a position on client's minimap (ZC_COMPASS).
@@ -2519,8 +2522,8 @@ static void clif_addcards(struct EQUIPSLOTINFO *buf, struct item *item)
if (item->card[0] == CARD0_PET) { //pet eggs
buf->card[0] = 0;
buf->card[1] = 0;
- buf->card[2] = 0;
- buf->card[3] = item->card[3]; //Pet renamed flag.
+ buf->card[2] = (item->card[3] >> 1); // Pet intimacy level.
+ buf->card[3] = (item->card[3] & 1); // Pet renamed flag.
return;
}
if (item->card[0] == CARD0_FORGE || item->card[0] == CARD0_CREATE) { //Forged/created items
@@ -7292,46 +7295,101 @@ static void clif_party_inviteack(struct map_session_data *sd, const char *nick,
#endif
}
-/// Updates party settings.
-/// 0101 <exp option>.L (ZC_GROUPINFO_CHANGE)
-/// 07d8 <exp option>.L <item pick rule>.B <item share rule>.B (ZC_REQ_GROUPINFO_CHANGE_V2)
-/// exp option:
-/// 0 = exp sharing disabled
-/// 1 = exp sharing enabled
-/// 2 = cannot change exp sharing
-///
-/// flag:
-/// 0 = send to party
-/// 1 = send to sd
+/**
+ * Sends party settings to the client.
+ *
+ * 0101 <exp option>.L (ZC_GROUPINFO_CHANGE)
+ * 07d8 <exp option>.L <item pick rule>.B <item share rule>.B (ZC_REQ_GROUPINFO_CHANGE_V2)
+ * <exp option>:
+ * 0 = EXP sharing disabled.
+ * 1 = EXP sharing enabled.
+ * 2 = Cannot change EXP sharing.
+ *
+ * @param p The related party.
+ * @param sd The related character.
+ * @param flag Reason for sending.
+ * @parblock
+ * Possible flags:
+ * 0x01 = Cannot change EXP sharing. (Only set when tried to change options manually.)
+ * 0x02 = Options changed manually.
+ * 0x04 = Options changed automatically.
+ * 0x08 = Member added.
+ * 0x10 = Member removed.
+ * 0x20 = Character logged in.
+ * 0x40 = Character changed map.
+ * 0x80 = Character teleported.
+ * @endparblock
+ *
+ **/
static void clif_party_option(struct party_data *p, struct map_session_data *sd, int flag)
{
- unsigned char buf[16];
+ nullpo_retv(p);
+
+ if (sd == NULL && (flag & 0x01) == 0) {
+ for (int i = 0; i < MAX_PARTY; i++) {
+ if (p->data[i].sd != NULL) {
+ sd = p->data[i].sd;
+ break;
+ }
+ }
+ }
+
+ if (sd == NULL)
+ return;
+
+ int conf = battle_config.send_party_options;
+
+ if (((flag & 0x01) != 0 && (conf & 0x10) == 0)
+ || ((flag & 0x02) != 0 && (conf & 0x08) == 0)
+ || ((flag & 0x04) != 0 && (conf & 0x20) == 0)
+ || ((flag & 0x08) != 0 && (conf & 0x40) == 0)
+ || ((flag & 0x10) != 0 && (conf & 0x80) == 0)
+ || ((flag & 0x20) != 0 && (conf & 0x01) == 0)
+ || ((flag & 0x40) != 0 && (conf & 0x02) == 0)
+ || ((flag & 0x80) != 0 && (conf & 0x04) == 0)) {
+ return;
+ }
+
+ enum send_target target = SELF;
+
+ if (((flag & 0x01) != 0 && (conf & 0x100) != 0)
+ || ((flag & 0x01) == 0 && (flag & 0x02) != 0)
+ || (flag & 0x04) != 0) {
+ target = PARTY;
+ }
+
+ int cmd = 0x101;
+
+ if (((flag & 0x01) != 0 && (conf & 0x02000) != 0)
+ || ((flag & 0x02) != 0 && (conf & 0x01000) != 0)
+ || ((flag & 0x04) != 0 && (conf & 0x04000) != 0)
+ || ((flag & 0x08) != 0 && (conf & 0x08000) != 0)
+ || ((flag & 0x10) != 0 && (conf & 0x10000) != 0)
+ || ((flag & 0x20) != 0 && (conf & 0x00200) != 0)
+ || ((flag & 0x40) != 0 && (conf & 0x00400) != 0)
+ || ((flag & 0x80) != 0 && (conf & 0x00800) != 0)) {
+ cmd = 0x7d8;
+ }
+
#if PACKETVER < 20090603
- const int cmd = 0x101;
-#else
- const int cmd = 0x7d8;
+ if (cmd == 0x7d8)
+ cmd = 0x101;
#endif
- nullpo_retv(p);
+ unsigned char buf[16];
- if(!sd && flag==0){
- int i;
- for(i=0;i<MAX_PARTY && !p->data[i].sd;i++)
- ;
- if (i < MAX_PARTY)
- sd = p->data[i].sd;
+ WBUFW(buf, 0) = cmd;
+ WBUFL(buf, 2) = ((flag & 0x10) != 0) ? 0 : (((flag & 0x01) != 0) ? 2 : p->party.exp);
+
+ if (cmd == 0x7d8) {
+ WBUFB(buf, 6) = ((flag & 0x10) != 0) ? 0 : (((p->party.item & 1) != 0) ? 1 : 0);
+ WBUFB(buf, 7) = ((flag & 0x10) != 0) ? 0 : (((p->party.item & 2) != 0) ? 1 : 0);
}
- if(!sd) return;
- WBUFW(buf,0)=cmd;
- WBUFL(buf,2)=((flag&0x01)?2:p->party.exp);
-#if PACKETVER >= 20090603
- WBUFB(buf,6)=(p->party.item&1)?1:0;
- WBUFB(buf,7)=(p->party.item&2)?1:0;
-#endif
- if(flag==0)
- clif->send(buf,packet_len(cmd),&sd->bl,PARTY);
- else
- clif->send(buf,packet_len(cmd),&sd->bl,SELF);
+
+ clif->send(buf, packet_len(cmd), &sd->bl, target);
+
+ if ((flag & 0x04) != 0)
+ p->state.option_auto_changed = 0;
}
/// 0105 <account id>.L <char name>.24B <result>.B (ZC_DELETE_MEMBER_FROM_GROUP).
@@ -10613,6 +10671,97 @@ static void clif_parse_WantToConnection(int fd, struct map_session_data *sd)
}
/**
+ * Displays the common server messages upon login, chaning maps or teleporting to a character.
+ *
+ * @param sd The character who should receive the messages.
+ * @param connect_new Whether the character is logging in.
+ * @param change_map Whether the character is changing maps.
+ *
+ **/
+static void clif_load_end_ack_sub_messages(struct map_session_data *sd, bool connect_new, bool change_map)
+{
+ nullpo_retv(sd);
+
+ /** Display overweight messages. **/
+ if (((battle_config.display_overweight_messages & 0x1) != 0 && connect_new)
+ || ((battle_config.display_overweight_messages & 0x2) != 0 && !connect_new && change_map)) {
+ // Send the character's weight to the client. (With displaying overweight messages.)
+ clif->updatestatus(sd, SP_MAXWEIGHT);
+ clif->updatestatus(sd, SP_WEIGHT);
+ } else {
+ // Send the character's weight to the client. (Without displaying overweight messages.)
+ clif->updatestatus(sd, SP_WEIGHT);
+ clif->updatestatus(sd, SP_MAXWEIGHT);
+ }
+
+ /** Display configuration messages. **/
+ if (((battle_config.display_config_messages & 0x1) != 0 && connect_new)
+ || ((battle_config.display_config_messages & 0x2) != 0 && !connect_new && change_map)
+ || (battle_config.display_config_messages & 0x4) != 0) {
+#if PACKETVER >= 20070918
+ if ((battle_config.display_config_messages & 0x10) != 0)
+ clif->partyinvitationstate(sd);
+
+ if ((battle_config.display_config_messages & 0x20) != 0)
+ clif->equpcheckbox(sd);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20171025 || PACKETVER_RE_NUM >= 20170920
+ if ((battle_config.display_config_messages & 0x40) != 0)
+ clif->zc_config(sd, CZ_CONFIG_CALL, sd->status.allow_call);
+
+ if ((battle_config.display_config_messages & 0x80) != 0) {
+ if (sd->pd != NULL)
+ clif->zc_config(sd, CZ_CONFIG_PET_AUTOFEEDING, sd->pd->pet.autofeed);
+ else
+ clif->zc_config(sd, CZ_CONFIG_PET_AUTOFEEDING, false);
+ }
+
+ if ((battle_config.display_config_messages & 0x100) != 0) {
+ if (sd->hd != NULL)
+ clif->zc_config(sd, CZ_CONFIG_HOMUNCULUS_AUTOFEEDING, sd->hd->homunculus.autofeed);
+ else
+ clif->zc_config(sd, CZ_CONFIG_HOMUNCULUS_AUTOFEEDING, false);
+ }
+#endif
+ }
+
+ /** Display party options. **/
+ struct party_data *p = NULL;
+
+ if (sd->status.party_id != 0 && (p = party->search(sd->status.party_id)) != NULL) {
+ int flag;
+
+ if (p->state.option_auto_changed != 0)
+ flag = 0x04;
+ else if (connect_new)
+ flag = 0x20;
+ else if (change_map)
+ flag = 0x40;
+ else
+ flag = 0x80;
+
+ clif->party_option(p, sd, flag);
+ }
+
+ /** Display rate modifier messages. **/
+ if (((battle_config.display_rate_messages & 0x1) != 0 && connect_new)
+ || ((battle_config.display_rate_messages & 0x2) != 0 && !connect_new && change_map)
+ || (battle_config.display_rate_messages & 0x4) != 0) {
+ clif->show_modifiers(sd);
+ }
+
+ /** Display guild notice. **/
+ if (sd->guild != NULL) {
+ if (((battle_config.guild_notice_changemap & 0x1) != 0 && connect_new)
+ || ((battle_config.guild_notice_changemap & 0x2) != 0 && !connect_new && change_map)
+ || (battle_config.guild_notice_changemap & 0x4) != 0) {
+ clif->guild_notice(sd, sd->guild);
+ }
+ }
+}
+
+/**
* Notification from the client, that it has finished map loading and is about to display player's character. (CZ_NOTIFY_ACTORINIT)
*
* @code
@@ -10626,6 +10775,9 @@ static void clif_parse_WantToConnection(int fd, struct map_session_data *sd)
static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd)
{
+ if (sd->state.using_megaphone != 0)
+ sd->state.using_megaphone = 0;
+
if (sd->bl.prev != NULL)
return;
@@ -10732,10 +10884,6 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd)
// Check for and delete unavailable/disabled items.
pc->checkitem(sd);
- // Send the character's weight to the client.
- clif->updatestatus(sd, SP_WEIGHT);
- clif->updatestatus(sd, SP_MAXWEIGHT);
-
// Send character's guild info to the client. Call this before clif->spawn() to show guild emblems correctly.
if (sd->status.guild_id != 0)
guild->send_memberinfoshort(sd, 1);
@@ -10764,9 +10912,18 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd)
map->addblock(&sd->bl); // Add the character to the map.
clif->spawn(&sd->bl); // Spawn character client side.
+ clif_load_end_ack_sub_messages(sd, (sd->state.connect_new != 0), (sd->state.changemap != 0));
+
+ struct party_data *p = NULL;
+
+ if (sd->status.party_id != 0)
+ p = party->search(sd->status.party_id);
+
// Send character's party info to the client. Call this after clif->spawn() to show HP bars correctly.
- if (sd->status.party_id != 0) {
- party->send_movemap(sd);
+ if (p != NULL) {
+ if (sd->state.connect_new == 0) // Login is handled in party_member_joined().
+ party->send_movemap(sd);
+
clif->party_hp(sd); // Show HP after displacement. [LuzZza]
}
@@ -10806,10 +10963,7 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd)
clif->message(sd->fd, msg_sd(sd, 866)); // "Pets are not allowed in Guild Wars."
pet->menu(sd, 3); // Option 3 is return to egg.
} else {
- map->addblock(&sd->pd->bl);
- clif->spawn(&sd->pd->bl);
- clif->send_petdata(sd,sd->pd, 0, 0);
- clif->send_petstatus(sd);
+ pet->spawn(sd, false);
}
}
@@ -10917,6 +11071,11 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd)
// Notify everyone that this character logged in. [Skotlex]
map->foreachpc(clif->friendslist_toggle_sub, sd->status.account_id, sd->status.char_id, 1);
+#if PACKETVER >= 20171122
+ if (battle_config.show_tip_window != 0)
+ clif->open_ui_send(sd, ZC_TIPBOX_UI);
+#endif
+
// Run OnPCLoginEvent labels.
npc->script_event(sd, NPCE_LOGIN);
} else {
@@ -10938,26 +11097,9 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd)
} else {
sd->state.warp_clean = 1;
}
-
- if (sd->guild != NULL && ((battle_config.guild_notice_changemap == 1 && sd->state.changemap != 0)
- || battle_config.guild_notice_changemap == 2)) {
- clif->guild_notice(sd, sd->guild);
- }
}
if (sd->state.changemap != 0) { // Restore information that gets lost on map-change.
-#if PACKETVER >= 20070918
- clif->partyinvitationstate(sd);
- clif->equpcheckbox(sd);
-#endif
-
-#if PACKETVER_MAIN_NUM >= 20171025 || PACKETVER_RE_NUM >= 20170920
- if (sd->hd != NULL)
- clif->zc_config(sd, CZ_CONFIG_HOMUNCULUS_AUTOFEEDING, sd->hd->homunculus.autofeed);
- else
- clif->zc_config(sd, CZ_CONFIG_HOMUNCULUS_AUTOFEEDING, false);
-#endif
-
bool flee_penalty = (battle_config.bg_flee_penalty != 100 || battle_config.gvg_flee_penalty != 100);
bool is_gvg = (map_flag_gvg2(sd->state.pmap) || map_flag_gvg2(sd->bl.m));
bool is_bg = (map->list[sd->state.pmap].flag.battleground != 0 || map->list[sd->bl.m].flag.battleground != 0);
@@ -11006,12 +11148,14 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd)
mail->clear(sd);
clif->maptypeproperty2(&sd->bl, SELF);
- // Init guild aura.
- if (sd->state.gmaster_flag != 0) {
- guild->aura_refresh(sd, GD_LEADERSHIP, guild->checkskill(sd->guild, GD_LEADERSHIP));
- guild->aura_refresh(sd, GD_GLORYWOUNDS, guild->checkskill(sd->guild, GD_GLORYWOUNDS));
- guild->aura_refresh(sd, GD_SOULCOLD, guild->checkskill(sd->guild, GD_SOULCOLD));
- guild->aura_refresh(sd, GD_HAWKEYES, guild->checkskill(sd->guild, GD_HAWKEYES));
+ if (sd->guild != NULL) {
+ // Init guild aura.
+ if (sd->state.gmaster_flag != 0) {
+ guild->aura_refresh(sd, GD_LEADERSHIP, guild->checkskill(sd->guild, GD_LEADERSHIP));
+ guild->aura_refresh(sd, GD_GLORYWOUNDS, guild->checkskill(sd->guild, GD_GLORYWOUNDS));
+ guild->aura_refresh(sd, GD_SOULCOLD, guild->checkskill(sd->guild, GD_SOULCOLD));
+ guild->aura_refresh(sd, GD_HAWKEYES, guild->checkskill(sd->guild, GD_HAWKEYES));
+ }
}
if (sd->state.vending != 0) { // Character is vending.
@@ -11036,10 +11180,6 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd)
clif->weather_check(sd);
- // This should be displayed last.
- if (sd->guild != NULL && first_time)
- clif->guild_notice(sd, sd->guild);
-
// For automatic triggering of NPCs after map loading. (So you don't need to walk 1 step first.)
if (map->getcell(sd->bl.m, &sd->bl, sd->bl.x, sd->bl.y, CELL_CHKNPC) != 0)
npc->touch_areanpc(sd, sd->bl.m, sd->bl.x, sd->bl.y);
@@ -11067,6 +11207,19 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd)
#if PACKETVER >= 20090218
quest->questinfo_refresh(sd); // NPC quest/event icon check. [Kisuka]
#endif
+
+ if (first_time) {
+ int i;
+
+ ARR_FIND(0, instance->instances, i, instance->list[i].owner_type == IOT_CHAR && instance->list[i].owner_id == sd->status.account_id);
+
+ if (i < instance->instances) {
+ sd->instances = 1;
+ CREATE(sd->instance, short, 1);
+ sd->instance[0] = instance->list[i].id;
+ clif->instance_join(sd->fd, instance->list[i].id);
+ }
+ }
}
/// Server's tick (ZC_NOTIFY_TIME).
@@ -11288,7 +11441,7 @@ static void clif_parse_WalkToXY(int fd, struct map_session_data *sd)
; //You CAN walk on this OPT1 value.
/*else if( sd->progressbar.npc_id )
clif->progressbar_abort(sd);*/
- else if (pc_cant_act(sd) || pc_isvending(sd))
+ else if (pc_cant_act_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
if(sd->sc.data[SC_RUN] || sd->sc.data[SC_WUGDASH])
@@ -11650,8 +11803,10 @@ static void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action
return;
}
- if (pc_cant_act(sd) || pc_issit(sd) || sd->sc.option&OPTION_HIDE || pc_isvending(sd))
+ if (pc_cant_act_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0)
+ || pc_issit(sd) || (sd->sc.option & OPTION_HIDE) != 0 || pc_isvending(sd)) {
return;
+ }
if (sd->sc.option & OPTION_COSTUME)
return;
@@ -11951,7 +12106,7 @@ static void clif_parse_TakeItem(int fd, struct map_session_data *sd)
) )
break;
- if (pc_cant_act(sd))
+ if (pc_cant_act_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0))
break;
if (!pc->takeitem(sd, fitem))
@@ -11977,7 +12132,7 @@ static void clif_parse_DropItem(int fd, struct map_session_data *sd)
if (pc_isdead(sd))
break;
- if ( pc_cant_act2(sd) || sd->state.vending )
+ if (pc_cant_act_except_npc_chat(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0))
break;
if (sd->sc.count && (
@@ -12050,7 +12205,7 @@ static void clif_parse_EquipItem(int fd, struct map_session_data *sd)
return; //Out of bounds check.
if( sd->npc_id ) {
- if ((sd->npc_item_flag & ITEMENABLEDNPC_EQUIP) == 0)
+ if ((sd->npc_item_flag & ITEMENABLEDNPC_EQUIP) == 0 && sd->state.using_megaphone == 0)
return;
} else if (sd->state.storage_flag != STORAGE_FLAG_CLOSED || sd->sc.opt1)
; //You can equip/unequip stuff while storage is open/under status changes
@@ -12095,7 +12250,7 @@ static void clif_parse_UnequipItem(int fd, struct map_session_data *sd)
}
if( sd->npc_id ) {
- if ((sd->npc_item_flag & ITEMENABLEDNPC_EQUIP) == 0)
+ if ((sd->npc_item_flag & ITEMENABLEDNPC_EQUIP) == 0 && sd->state.using_megaphone == 0)
return;
} else if (sd->state.storage_flag != STORAGE_FLAG_CLOSED || sd->sc.opt1)
; //You can equip/unequip stuff while storage is open/under status changes
@@ -12295,7 +12450,7 @@ static void clif_parse_CreateChatRoom(int fd, struct map_session_data *sd) __att
/// 1 = public
static void clif_parse_CreateChatRoom(int fd, struct map_session_data *sd)
{
- if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd))
+ if (sd->state.trading || (pc_isdead(sd) && (battle_config.allowed_actions_when_dead & PCALLOWACTION_CHAT) == 0) || pc_isvending(sd))
return;
int len = (int)RFIFOW(fd, 2) - 15;
@@ -12343,7 +12498,7 @@ static void clif_parse_ChatAddMember(int fd, struct map_session_data *sd) __attr
/// 00d9 <chat ID>.L <passwd>.8B
static void clif_parse_ChatAddMember(int fd, struct map_session_data *sd)
{
- if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd))
+ if (sd->state.trading || (pc_isdead(sd) && (battle_config.allowed_actions_when_dead & PCALLOWACTION_CHAT) == 0) || pc_isvending(sd))
return;
int chatid = RFIFOL(fd,2);
@@ -12360,7 +12515,7 @@ static void clif_parse_ChatRoomStatusChange(int fd, struct map_session_data *sd)
/// 1 = public
static void clif_parse_ChatRoomStatusChange(int fd, struct map_session_data *sd)
{
- if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd))
+ if (sd->state.trading || (pc_isdead(sd) && (battle_config.allowed_actions_when_dead & PCALLOWACTION_CHAT) == 0) || pc_isvending(sd))
return;
int len = (int)RFIFOW(fd, 2) - 15;
@@ -12395,7 +12550,7 @@ static void clif_parse_ChangeChatOwner(int fd, struct map_session_data *sd) __at
/// 1 = normal
static void clif_parse_ChangeChatOwner(int fd, struct map_session_data *sd)
{
- if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd))
+ if (sd->state.trading || (pc_isdead(sd) && (battle_config.allowed_actions_when_dead & PCALLOWACTION_CHAT) == 0) || pc_isvending(sd))
return;
chat->change_owner(sd, RFIFOP(fd,6)); // non null terminated
@@ -12406,7 +12561,7 @@ static void clif_parse_KickFromChat(int fd, struct map_session_data *sd) __attri
/// 00e2 <name>.24B
static void clif_parse_KickFromChat(int fd, struct map_session_data *sd)
{
- if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd))
+ if (sd->state.trading || (pc_isdead(sd) && (battle_config.allowed_actions_when_dead & PCALLOWACTION_CHAT) == 0) || pc_isvending(sd))
return;
chat->kick(sd, RFIFOP(fd,2)); // non null terminated
@@ -12417,7 +12572,7 @@ static void clif_parse_ChatLeave(int fd, struct map_session_data *sd) __attribut
/// 00e3
static void clif_parse_ChatLeave(int fd, struct map_session_data *sd)
{
- if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd))
+ if (sd->state.trading || (pc_isdead(sd) && (battle_config.allowed_actions_when_dead & PCALLOWACTION_CHAT) == 0) || pc_isvending(sd))
return;
chat->leave(sd, false);
@@ -12444,12 +12599,12 @@ static void clif_parse_TradeRequest(int fd, struct map_session_data *sd) __attri
/// 00e4 <account id>.L
static void clif_parse_TradeRequest(int fd, struct map_session_data *sd)
{
- if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd))
+ if (sd->state.trading || (pc_isdead(sd) && (battle_config.allowed_actions_when_dead & PCALLOWACTION_TRADE) == 0) || pc_isvending(sd))
return;
struct map_session_data *t_sd = map->id2sd(RFIFOL(fd, 2));
- if (sd->chat_id == 0 && pc_cant_act(sd))
+ if (pc_cant_act_except_npc_chat(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0))
return; //You can trade while in a chatroom.
// @noask [LuzZza]
@@ -12474,7 +12629,7 @@ static void clif_parse_TradeAck(int fd, struct map_session_data *sd) __attribute
/// 4 = rejected
static void clif_parse_TradeAck(int fd, struct map_session_data *sd)
{
- if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd))
+ if (sd->state.trading || (pc_isdead(sd) && (battle_config.allowed_actions_when_dead & PCALLOWACTION_TRADE) == 0) || pc_isvending(sd))
return;
trade->ack(sd,RFIFOB(fd,2));
@@ -12485,7 +12640,7 @@ static void clif_parse_TradeAddItem(int fd, struct map_session_data *sd) __attri
/// 00e8 <index>.W <amount>.L
static void clif_parse_TradeAddItem(int fd, struct map_session_data *sd)
{
- if (!sd->state.trading || pc_isdead(sd) || pc_isvending(sd))
+ if (sd->state.trading == 0 || (pc_isdead(sd) && (battle_config.allowed_actions_when_dead & PCALLOWACTION_TRADE) == 0) || pc_isvending(sd))
return;
short index = RFIFOW(fd,2);
@@ -12502,8 +12657,9 @@ static void clif_parse_TradeOk(int fd, struct map_session_data *sd) __attribute_
/// 00eb
static void clif_parse_TradeOk(int fd, struct map_session_data *sd)
{
- if (pc_isdead(sd) || pc_isvending(sd))
+ if ((pc_isdead(sd) && (battle_config.allowed_actions_when_dead & PCALLOWACTION_TRADE) == 0) || pc_isvending(sd))
return;
+
trade->ok(sd);
}
@@ -12512,7 +12668,7 @@ static void clif_parse_TradeCancel(int fd, struct map_session_data *sd) __attrib
/// 00ed
static void clif_parse_TradeCancel(int fd, struct map_session_data *sd)
{
- if (pc_isdead(sd) || pc_isvending(sd))
+ if ((pc_isdead(sd) && (battle_config.allowed_actions_when_dead & PCALLOWACTION_TRADE) == 0) || pc_isvending(sd))
return;
trade->cancel(sd);
@@ -12523,7 +12679,7 @@ static void clif_parse_TradeCommit(int fd, struct map_session_data *sd) __attrib
/// 00ef
static void clif_parse_TradeCommit(int fd, struct map_session_data *sd)
{
- if (pc_isdead(sd) || pc_isvending(sd))
+ if ((pc_isdead(sd) && (battle_config.allowed_actions_when_dead & PCALLOWACTION_TRADE) == 0) || pc_isvending(sd))
return;
trade->commit(sd);
@@ -12543,8 +12699,10 @@ static void clif_parse_PutItemToCart(int fd, struct map_session_data *sd) __attr
static void clif_parse_PutItemToCart(int fd, struct map_session_data *sd)
{
int flag = 0;
- if (pc_istrading(sd) || sd->state.prevend)
+
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || sd->state.prevend != 0)
return;
+
if (!pc_iscarton(sd))
return;
if ( (flag = pc->putitemtocart(sd,RFIFOW(fd,2)-2,RFIFOL(fd,4))) ) {
@@ -12558,8 +12716,9 @@ static void clif_parse_GetItemFromCart(int fd, struct map_session_data *sd) __at
/// 0127 <index>.W <amount>.L
static void clif_parse_GetItemFromCart(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || sd->state.prevend)
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || sd->state.prevend != 0)
return;
+
if (!pc_iscarton(sd))
return;
pc->getitemfromcart(sd,RFIFOW(fd,2)-2,RFIFOL(fd,4));
@@ -12629,7 +12788,7 @@ static void clif_parse_ChangeCart(int fd, struct map_session_data *sd)
if (pc->checkskill(sd, MC_CHANGECART) == 0)
return;
- if (sd->npc_id || sd->state.workinprogress & 1) {
+ if ((sd->npc_id != 0 && sd->state.using_megaphone == 0) || (sd->state.workinprogress & 1) != 0) {
#if PACKETVER >= 20110308
clif->msgtable(sd, MSG_BUSY);
#else
@@ -12849,7 +13008,7 @@ static void clif_useSkillToIdReal(int fd, struct map_session_data *sd, int skill
bool allow_self_skill = ((tmp & INF_SELF_SKILL) != 0 && (skill->get_nk(skill_id) & NK_NO_DAMAGE) != 0);
allow_self_skill = (allow_self_skill && battle_config.skill_enabled_npc == SKILLENABLEDNPC_SELF);
- if ((sd->npc_id != 0 && !allow_self_skill && battle_config.skill_enabled_npc != SKILLENABLEDNPC_ALL)
+ if ((sd->npc_id != 0 && sd->state.using_megaphone == 0 && !allow_self_skill && battle_config.skill_enabled_npc != SKILLENABLEDNPC_ALL)
|| (sd->state.workinprogress & 1) != 0) {
#if PACKETVER >= 20110308
clif->msgtable(sd, MSG_BUSY);
@@ -12996,7 +13155,7 @@ static void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uin
return;
}
- if ((sd->npc_id != 0 && battle_config.skill_enabled_npc != SKILLENABLEDNPC_ALL)
+ if ((sd->npc_id != 0 && sd->state.using_megaphone == 0 && battle_config.skill_enabled_npc != SKILLENABLEDNPC_ALL)
|| (sd->state.workinprogress & 1) != 0) {
#if PACKETVER >= 20110308
clif->msgtable(sd, MSG_BUSY);
@@ -13118,7 +13277,7 @@ static void clif_parse_UseSkillMap(int fd, struct map_session_data *sd)
// It is possible to use teleport with the storage window open issue:8027
if ((pc_cant_act_except_npc(sd) && sd->state.storage_flag == STORAGE_FLAG_CLOSED && skill_id != AL_TELEPORT)
- || (sd->npc_id != 0 && battle_config.skill_enabled_npc != SKILLENABLEDNPC_ALL)) {
+ || (sd->npc_id != 0 && sd->state.using_megaphone == 0 && battle_config.skill_enabled_npc != SKILLENABLEDNPC_ALL)) {
clif_menuskill_clear(sd);
return;
}
@@ -13161,7 +13320,8 @@ static void clif_parse_ProduceMix(int fd, struct map_session_data *sd)
default:
return;
}
- if (pc_istrading(sd) || pc_isdead(sd) || pc_isvending(sd)) {
+ if (pc_istrading_except_npc(sd) || pc_isdead(sd) || pc_isvending(sd)
+ || (sd->npc_id != 0 && sd->state.using_megaphone == 0)) {
//Make it fail to avoid shop exploits where you sell something different than you see.
clif->skill_fail(sd, sd->ud.skill_id, USESKILL_FAIL_LEVEL, 0, 0);
clif_menuskill_clear(sd);
@@ -13192,7 +13352,8 @@ static void clif_parse_Cooking(int fd, struct map_session_data *sd)
if (type == 6 && sd->menuskill_id != GN_MIX_COOKING && sd->menuskill_id != GN_S_PHARMACY)
return;
- if (pc_istrading(sd) || pc_isdead(sd) || pc_isvending(sd)) {
+ if (pc_istrading_except_npc(sd) || pc_isdead(sd) || pc_isvending(sd)
+ || (sd->npc_id != 0 && sd->state.using_megaphone == 0)) {
//Make it fail to avoid shop exploits where you sell something different than you see.
clif->skill_fail(sd, sd->ud.skill_id, USESKILL_FAIL_LEVEL, 0, 0);
clif_menuskill_clear(sd);
@@ -13212,7 +13373,8 @@ static void clif_parse_RepairItem(int fd, struct map_session_data *sd)
if (sd->menuskill_id != BS_REPAIRWEAPON)
return;
- if (pc_istrading(sd) || pc_isdead(sd) || pc_isvending(sd)) {
+ if (pc_istrading_except_npc(sd) || pc_isdead(sd) || pc_isvending(sd)
+ || (sd->npc_id != 0 && sd->state.using_megaphone == 0)) {
//Make it fail to avoid shop exploits where you sell something different than you see.
clif->skill_fail(sd, sd->ud.skill_id, USESKILL_FAIL_LEVEL, 0, 0);
clif_menuskill_clear(sd);
@@ -13231,7 +13393,8 @@ static void clif_parse_WeaponRefine(int fd, struct map_session_data *sd)
if (sd->menuskill_id != WS_WEAPONREFINE) //Packet exploit?
return;
- if (pc_istrading(sd) || pc_isdead(sd) || pc_isvending(sd)) {
+ if (pc_istrading_except_npc(sd) || pc_isdead(sd) || pc_isvending(sd)
+ || (sd->npc_id != 0 && sd->state.using_megaphone == 0)) {
//Make it fail to avoid shop exploits where you sell something different than you see.
clif->skill_fail(sd, sd->ud.skill_id, USESKILL_FAIL_LEVEL, 0, 0);
clif_menuskill_clear(sd);
@@ -13318,7 +13481,7 @@ static void clif_parse_NpcStringInput(int fd, struct map_session_data *sd) __att
/// 01d5 <packet len>.W <npc id>.L <string>.?B
static void clif_parse_NpcStringInput(int fd, struct map_session_data *sd)
{
- if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd))
+ if ((sd->state.trading != 0 || pc_isvending(sd) || pc_isdead(sd)) && sd->state.using_megaphone == 0)
return;
int len = RFIFOW(fd, 2);
@@ -13334,7 +13497,7 @@ static void clif_parse_NpcStringInput(int fd, struct map_session_data *sd)
if (len < 9)
return;
- npcid = RFIFOL(fd, 4);
+ npcid = (sd->state.using_megaphone == 0) ? RFIFOL(fd, 4) : sd->npc_id;
message = RFIFOP(fd, 8);
safestrncpy(sd->npc_str, message, min(message_len,CHATBOX_SIZE));
@@ -13403,7 +13566,8 @@ static void clif_parse_SelectArrow(int fd, struct map_session_data *sd) __attrib
static void clif_parse_SelectArrow(int fd, struct map_session_data *sd)
{
int itemId;
- if (pc_istrading(sd) || pc_isdead(sd) || pc_isvending(sd)) {
+ if (pc_istrading_except_npc(sd) || pc_isdead(sd) || pc_isvending(sd)
+ || (sd->npc_id != 0 && sd->state.using_megaphone == 0)) {
//Make it fail to avoid shop exploits where you sell something different than you see.
clif->skill_fail(sd, sd->ud.skill_id, USESKILL_FAIL_LEVEL, 0, 0);
clif_menuskill_clear(sd);
@@ -13689,7 +13853,7 @@ static void clif_parse_CreateParty(int fd, struct map_session_data *sd) __attrib
/// 01e8 <party name>.24B <item pickup rule>.B <item share rule>.B (CZ_MAKE_GROUP2)
static void clif_parse_CreateParty(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
char name[NAME_LENGTH];
@@ -13712,7 +13876,7 @@ static void clif_parse_CreateParty(int fd, struct map_session_data *sd)
static void clif_parse_CreateParty2(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
static void clif_parse_CreateParty2(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
char name[NAME_LENGTH];
@@ -13740,7 +13904,7 @@ static void clif_parse_PartyInvite(int fd, struct map_session_data *sd) __attrib
/// 02c4 <char name>.24B (CZ_PARTY_JOIN_REQ)
static void clif_parse_PartyInvite(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
struct map_session_data *t_sd;
@@ -13764,7 +13928,7 @@ static void clif_parse_PartyInvite(int fd, struct map_session_data *sd)
static void clif_parse_PartyInvite2(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
static void clif_parse_PartyInvite2(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
struct map_session_data *t_sd;
@@ -13797,7 +13961,7 @@ static void clif_parse_ReplyPartyInvite(int fd, struct map_session_data *sd) __a
/// 1 = accept
static void clif_parse_ReplyPartyInvite(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || pc_isvending(sd)) {
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd)) {
party->reply_invite(sd, RFIFOL(fd, 2), 0);
return;
}
@@ -13808,7 +13972,7 @@ static void clif_parse_ReplyPartyInvite(int fd, struct map_session_data *sd)
static void clif_parse_ReplyPartyInvite2(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
static void clif_parse_ReplyPartyInvite2(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || pc_isvending(sd)) {
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd)) {
party->reply_invite(sd, RFIFOL(fd, 2), 0);
return;
}
@@ -13821,7 +13985,7 @@ static void clif_parse_LeaveParty(int fd, struct map_session_data *sd) __attribu
/// 0100
static void clif_parse_LeaveParty(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
if (map->list[sd->bl.m].flag.partylock) {
@@ -13837,7 +14001,7 @@ static void clif_parse_RemovePartyMember(int fd, struct map_session_data *sd) __
/// 0103 <account id>.L <char name>.24B
static void clif_parse_RemovePartyMember(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
if (map->list[sd->bl.m].flag.partylock) {
@@ -13854,7 +14018,7 @@ static void clif_parse_PartyChangeOption(int fd, struct map_session_data *sd) __
/// 07d7 <exp share rule>.L <item pickup rule>.B <item share rule>.B (CZ_GROUPINFO_CHANGE_V2)
static void clif_parse_PartyChangeOption(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
struct party_data *p;
@@ -13909,7 +14073,7 @@ static void clif_parse_PartyChangeLeader(int fd, struct map_session_data *sd) __
/// 07da <account id>.L
static void clif_parse_PartyChangeLeader(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
party->changeleader(sd, map->id2sd(RFIFOL(fd,2)));
@@ -13924,7 +14088,7 @@ static void clif_parse_PartyBookingRegisterReq(int fd, struct map_session_data *
static void clif_parse_PartyBookingRegisterReq(int fd, struct map_session_data *sd)
{
#ifndef PARTY_RECRUIT
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
short level = RFIFOW(fd,2);
@@ -13969,7 +14133,7 @@ static void clif_parse_PartyBookingSearchReq(int fd, struct map_session_data *sd
static void clif_parse_PartyBookingSearchReq(int fd, struct map_session_data *sd)
{
#ifndef PARTY_RECRUIT
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
short level = RFIFOW(fd,2);
@@ -14023,7 +14187,7 @@ static void clif_parse_PartyBookingDeleteReq(int fd, struct map_session_data *sd
static void clif_parse_PartyBookingDeleteReq(int fd, struct map_session_data *sd)
{
#ifndef PARTY_RECRUIT
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
if (party->booking_delete(sd))
@@ -14062,7 +14226,7 @@ static void clif_parse_PartyBookingUpdateReq(int fd, struct map_session_data *sd
static void clif_parse_PartyBookingUpdateReq(int fd, struct map_session_data *sd)
{
#ifndef PARTY_RECRUIT
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
short job[PARTY_BOOKING_JOBS];
@@ -14081,7 +14245,7 @@ static void clif_parse_PartyBookingUpdateReq(int fd, struct map_session_data *sd
static void clif_PartyBookingInsertNotify(struct map_session_data *sd, struct party_booking_ad_info *pb_ad)
{
#ifndef PARTY_RECRUIT
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
int i;
@@ -14152,7 +14316,7 @@ static void clif_parse_PartyRecruitRegisterReq(int fd, struct map_session_data *
static void clif_parse_PartyRecruitRegisterReq(int fd, struct map_session_data *sd)
{
#ifdef PARTY_RECRUIT
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
short level = RFIFOW(fd, 2);
@@ -14226,7 +14390,7 @@ static void clif_parse_PartyRecruitSearchReq(int fd, struct map_session_data *sd
static void clif_parse_PartyRecruitSearchReq(int fd, struct map_session_data *sd)
{
#ifdef PARTY_RECRUIT
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
short level = RFIFOW(fd, 2);
@@ -14246,7 +14410,7 @@ static void clif_parse_PartyRecruitDeleteReq(int fd, struct map_session_data *sd
static void clif_parse_PartyRecruitDeleteReq(int fd, struct map_session_data *sd)
{
#ifdef PARTY_RECRUIT
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
if (party->booking_delete(sd))
@@ -14285,7 +14449,7 @@ static void clif_parse_PartyRecruitUpdateReq(int fd, struct map_session_data *sd
static void clif_parse_PartyRecruitUpdateReq(int fd, struct map_session_data *sd)
{
#ifdef PARTY_RECRUIT
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
const char *notice = RFIFOP(fd, 2);
@@ -14361,7 +14525,7 @@ static void clif_parse_PartyBookingAddFilteringList(int fd, struct map_session_d
static void clif_parse_PartyBookingAddFilteringList(int fd, struct map_session_data *sd)
{
#ifdef PARTY_RECRUIT
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
int index = RFIFOL(fd, 2);
@@ -14378,7 +14542,7 @@ static void clif_parse_PartyBookingSubFilteringList(int fd, struct map_session_d
static void clif_parse_PartyBookingSubFilteringList(int fd, struct map_session_data *sd)
{
#ifdef PARTY_RECRUIT
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
int gid = RFIFOL(fd, 2);
@@ -14395,7 +14559,7 @@ static void clif_parse_PartyBookingReqVolunteer(int fd, struct map_session_data
static void clif_parse_PartyBookingReqVolunteer(int fd, struct map_session_data *sd)
{
#ifdef PARTY_RECRUIT
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
int index = RFIFOL(fd, 2);
@@ -14474,7 +14638,7 @@ static void clif_parse_PartyBookingRefuseVolunteer(int fd, struct map_session_da
static void clif_parse_PartyBookingRefuseVolunteer(int fd, struct map_session_data *sd)
{
#ifdef PARTY_RECRUIT
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
unsigned int aid = RFIFOL(fd, 2);
@@ -14506,7 +14670,7 @@ static void clif_parse_PartyBookingCancelVolunteer(int fd, struct map_session_da
static void clif_parse_PartyBookingCancelVolunteer(int fd, struct map_session_data *sd)
{
#ifdef PARTY_RECRUIT
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
int index = RFIFOL(fd, 2);
@@ -14584,7 +14748,7 @@ static void clif_parse_CloseVending(int fd, struct map_session_data *sd) __attri
/// 012e
static void clif_parse_CloseVending(int fd, struct map_session_data *sd)
{
- if (sd->npc_id || sd->state.buyingstore || sd->state.trading)
+ if ((sd->npc_id != 0 && sd->state.using_megaphone == 0) || sd->state.buyingstore != 0 || sd->state.trading != 0)
return;
vending->close(sd);
@@ -14595,12 +14759,9 @@ static void clif_parse_VendingListReq(int fd, struct map_session_data *sd) __att
/// 0130 <account id>.L
static void clif_parse_VendingListReq(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || pc_isdead(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isdead(sd))
return;
- if( sd->npc_id ) {// using an NPC
- return;
- }
vending->list(sd,RFIFOL(fd,2));
}
@@ -14662,8 +14823,10 @@ static void clif_parse_OpenVending(int fd, struct map_session_data *sd) __attrib
/// 1 = open
static void clif_parse_OpenVending(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || pc_isdead(sd) || sd->state.vending || sd->state.buyingstore)
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0)
+ || pc_isdead(sd) || sd->state.vending != 0 || sd->state.buyingstore != 0) {
return;
+ }
int len = (int)RFIFOW(fd, 2) - 85;
@@ -16750,7 +16913,7 @@ static void clif_parse_AutoRevive(int fd, struct map_session_data *sd) __attribu
/// 0292
static void clif_parse_AutoRevive(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
if (!pc_isdead(sd))
@@ -19178,7 +19341,7 @@ static void clif_parse_ReqOpenBuyingStore(int fd, struct map_session_data *sd) _
/// 1 = open
static void clif_parse_ReqOpenBuyingStore(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || pc_isdead(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isdead(sd))
return;
const unsigned int blocksize = sizeof(struct PACKET_CZ_REQ_OPEN_BUYING_STORE_sub);
@@ -20016,7 +20179,7 @@ static void clif_parse_SkillSelectMenu(int fd, struct map_session_data *sd)
if (sd->menuskill_id != SC_AUTOSHADOWSPELL)
return;
- if (pc_istrading(sd) || sd->state.prevend) {
+ if (pc_istrading_except_npc(sd) || sd->state.prevend != 0 || (sd->npc_id != 0 && sd->state.using_megaphone == 0)) {
clif->skill_fail(sd, sd->ud.skill_id, 0, 0, 0);
clif_menuskill_clear(sd);
return;
@@ -20923,20 +21086,57 @@ static void clif_bank_withdraw(struct map_session_data *sd, enum e_BANKING_WITHD
#endif
}
-/* TODO: official response packet (tried 0x8cb/0x97b but the display was quite screwed up.) */
-/* currently mimicing */
+/**
+ * Sends EXP, drop and death-penalty rates.
+ * 0x097b <packet len>.W <exp>.L <death>.L <drop>.L <DETAIL_EXP_INFO>13B (ZC_PERSONAL_INFOMATION2)
+ * <InfoType>.B <Exp>.L <Death>.L <Drop>.L (DETAIL_EXP_INFO)
+ *
+ * @param sd The character which should receive the messages.
+ *
+ **/
static void clif_show_modifiers(struct map_session_data *sd)
{
nullpo_retv(sd);
- if( sd->status.mod_exp != 100 || sd->status.mod_drop != 100 || sd->status.mod_death != 100 ) {
+#if PACKETVER_MAIN_NUM >= 20120503 || PACKETVER_RE_NUM >= 20120502 || defined(PACKETVER_ZERO)
+ int length = sizeof(struct PACKET_ZC_PERSONAL_INFOMATION) + 4 * sizeof(struct PACKET_ZC_PERSONAL_INFOMATION_SUB);
+ WFIFOHEAD(sd->fd, length);
+ struct PACKET_ZC_PERSONAL_INFOMATION *p = WFIFOP(sd->fd, 0);
+
+ p->packetType = HEADER_ZC_PERSONAL_INFOMATION;
+ p->length = length;
+ // Single values.
+ p->details[0].type = PC_EXP_INFO;
+ p->details[0].exp = 0;
+ p->details[0].death = 0;
+ p->details[0].drop = 0;
+ p->details[1].type = TPLUS_EXP_INFO;
+ p->details[1].exp = 0;
+ p->details[1].death = 0;
+ p->details[1].drop = 0;
+ p->details[2].type = PREMIUM_EXP_INFO;
+ p->details[2].exp = (sd->status.mod_exp - 100) * 1000;
+ p->details[2].death = (sd->status.mod_death - 100) * 1000;
+ p->details[2].drop = (sd->status.mod_drop - 100) * 1000;
+ p->details[3].type = SERVER_EXP_INFO;
+ p->details[3].exp = battle_config.base_exp_rate * 1000;
+ p->details[3].death = battle_config.death_penalty_base * 10;
+ p->details[3].drop = battle_config.item_rate_common * 1000;
+ // Total values.
+ p->total_exp = (battle_config.base_exp_rate * sd->status.mod_exp / 100) * 1000;
+ p->total_death = (battle_config.base_exp_rate * sd->status.mod_death / 100) * 10;
+ p->total_drop = (battle_config.base_exp_rate * sd->status.mod_drop / 100) * 1000;
+
+ WFIFOSET(sd->fd, length);
+#else
+ if (sd->status.mod_exp != 100 || sd->status.mod_drop != 100 || sd->status.mod_death != 100) {
char output[128];
- snprintf(output,128, msg_sd(sd, 896), // Base EXP : %d%% | Base Drop: %d%% | Base Death Penalty: %d%%
- sd->status.mod_exp,sd->status.mod_drop,sd->status.mod_death);
+ // Base EXP : %d%% | Base Drop: %d%% | Base Death Penalty: %d%%
+ safesnprintf(output, sizeof(output), msg_sd(sd, 896), sd->status.mod_exp, sd->status.mod_drop, sd->status.mod_death);
clif->broadcast2(&sd->bl, output, (int)strlen(output) + 1, 0xffbc90, 0x190, 12, 0, 0, SELF);
}
-
+#endif // PACKETVER_MAIN_NUM >= 20120503 || PACKETVER_RE_NUM >= 20120502 || defined(PACKETVER_ZERO)
}
static void clif_notify_bounditem(struct map_session_data *sd, unsigned short index)
@@ -22176,7 +22376,10 @@ static void clif_parse_rodex_open_write_mail(int fd, struct map_session_data *sd
return;
const struct PACKET_CZ_REQ_OPEN_WRITE_MAIL *rPacket = RFIFOP(fd, 0);
- int8 result = (rodex->isenabled() == true && sd->npc_id == 0) ? 1 : 0;
+ int8 result = (rodex->isenabled() && (sd->npc_id == 0 || sd->state.using_megaphone != 0)) ? 1 : 0;
+
+ if (result == 1)
+ sd->state.workinprogress |= 2;
clif->rodex_open_write_mail(fd, rPacket->receiveName, result);
}
@@ -22959,61 +23162,65 @@ static void clif_parse_open_ui_request(int fd, struct map_session_data *sd)
clif->open_ui(sd, p->UIType);
}
-static void clif_open_ui(struct map_session_data *sd, enum cz_ui_types uiType)
+/**
+ * Does the actual packet sending for clif_open_ui().
+ *
+ * @param sd The character who opens the UI.
+ * @param ui_type The UI which should be opened.
+ *
+ **/
+static void clif_open_ui_send(struct map_session_data *sd, enum zc_ui_types ui_type)
{
+ nullpo_retv(sd);
+
#if PACKETVER >= 20150128
struct PACKET_ZC_OPEN_UI p;
-#if PACKETVER_RE_NUM >= 20180307 || PACKETVER_MAIN_NUM >= 20180404 || PACKETVER_ZERO_NUM >= 20180411
- int claimed = 0;
-#endif
-
- nullpo_retv(sd);
p.PacketType = openUiType;
- switch (uiType) {
- case CZ_STYLIST_UI:
- p.UIType = ZC_STYLIST_UI;
-#if PACKETVER >= 20171122
- p.data = 0;
-#endif
- break;
- case CZ_MACRO_REGISTER_UI:
- p.UIType = ZC_CAPTCHA_UI;
+ p.UIType = ui_type;
+
+ switch (ui_type) {
+ case ZC_BANK_UI:
+ case ZC_STYLIST_UI:
+ case ZC_CAPTCHA_UI:
+ case ZC_MACRO_UI:
#if PACKETVER >= 20171122
p.data = 0;
#endif
break;
- case CZ_MACRO_DETECTOR_UI:
- p.UIType = ZC_MACRO_UI;
#if PACKETVER >= 20171122
+ case ZC_TIPBOX_UI:
+ case ZC_RENEWQUEST_UI:
p.data = 0;
-#endif
break;
- case CZ_ATTENDANCE_UI:
- {
+ case ZC_ATTENDANCE_UI:
+ if (battle_config.feature_enable_attendance_system == 0)
+ return;
+
if (clif->attendance_getendtime() < time(NULL)) {
#if PACKETVER >= 20180207
clif->msgtable_color(sd, MSG_ATTENDANCE_UNAVAILABLE, COLOR_RED);
#endif
return;
}
- if (battle_config.feature_enable_attendance_system != 1)
- return;
+
#if PACKETVER_RE_NUM >= 20180307 || PACKETVER_MAIN_NUM >= 20180404 || PACKETVER_ZERO_NUM >= 20180411
- if (clif->attendance_timediff(sd) != true)
+ int claimed = 0;
+
+ if (!clif->attendance_timediff(sd))
++claimed;
else if (sd->status.attendance_count >= VECTOR_LENGTH(clif->attendance_data))
sd->status.attendance_count = 0;
- p.UIType = ZC_ATTENDANCE_UI;
+
p.data = sd->status.attendance_count * 10 + claimed;
#else
ShowWarning("Attendance System available only for PACKETVER_RE_NUM >= 20180307 || PACKETVER_MAIN_NUM >= 20180404 || PACKETVER_ZERO_NUM >= 20180411.\n");
return;
#endif
break;
- }
+#endif
default:
- ShowWarning("clif_open_ui: Requested UI (%u) is not implemented yet.\n", uiType);
+ ShowWarning("clif_open_ui_send: Requested UI (%u) is not implemented yet.\n", ui_type);
return;
}
@@ -23021,6 +23228,37 @@ static void clif_open_ui(struct map_session_data *sd, enum cz_ui_types uiType)
#endif
}
+static void clif_open_ui(struct map_session_data *sd, enum cz_ui_types uiType)
+{
+ nullpo_retv(sd);
+
+ enum zc_ui_types send_ui_type;
+
+ switch (uiType) {
+#if PACKETVER >= 20150128
+ case CZ_STYLIST_UI:
+ send_ui_type = ZC_STYLIST_UI;
+ break;
+ case CZ_MACRO_REGISTER_UI:
+ send_ui_type = ZC_CAPTCHA_UI;
+ break;
+ case CZ_MACRO_DETECTOR_UI:
+ send_ui_type = ZC_MACRO_UI;
+ break;
+#endif
+#if PACKETVER >= 20171122
+ case CZ_ATTENDANCE_UI:
+ send_ui_type = ZC_ATTENDANCE_UI;
+ break;
+#endif
+ default:
+ ShowWarning("clif_open_ui: Requested UI (%u) is not implemented yet.\n", uiType);
+ return;
+ }
+
+ clif->open_ui_send(sd, send_ui_type);
+}
+
static void clif_parse_attendance_reward_request(int fd, struct map_session_data *sd) __attribute__((nonnull(2)));
static void clif_parse_attendance_reward_request(int fd, struct map_session_data *sd)
{
@@ -25131,6 +25369,7 @@ void clif_defaults(void)
clif->attendance_timediff = clif_attendance_timediff;
clif->attendance_getendtime = clif_attendance_getendtime;
clif->pOpenUIRequest = clif_parse_open_ui_request;
+ clif->open_ui_send = clif_open_ui_send;
clif->open_ui = clif_open_ui;
clif->pAttendanceRewardRequest = clif_parse_attendance_reward_request;
clif->ui_action = clif_ui_action;