/*========================================== * Initiates a trade request. *------------------------------------------*/ void trade_traderequest(struct map_session_data *sd, struct map_session_data *target_sd) { nullpo_retv(sd); if (map[sd->bl.m].flag.notrade) { clif_displaymessage (sd->fd, msg_txt(272)); return; //Can't trade in notrade mapflag maps. } if (target_sd == NULL || sd == target_sd) { clif_tradestart(sd, 1); // character does not exist return; } if (target_sd->npc_id) { //Trade fails if you are using an NPC. clif_tradestart(sd, 2); return; } if (!battle_config.invite_request_check) { if (target_sd->guild_invite > 0 || target_sd->party_invite > 0 || target_sd->adopt_invite) { clif_tradestart(sd, 2); return; } } if ( sd->trade_partner != 0 ) { // If a character tries to trade to another one then cancel the previous one struct map_session_data *previous_sd = map_id2sd(sd->trade_partner); if( previous_sd ){ previous_sd->trade_partner = 0; clif_tradecancelled(previous_sd); } // Once cancelled then continue to the new one. sd->trade_partner = 0; clif_tradecancelled(sd); } if (target_sd->trade_partner != 0) { clif_tradestart(sd, 2); // person is in another trade return; } if (!pc_can_give_items(sd) || !pc_can_give_items(target_sd)) //check if both GMs are allowed to trade { clif_displaymessage(sd->fd, msg_txt(246)); clif_tradestart(sd, 2); // GM is not allowed to trade return; } // Players can not request trade from far away, unless they are allowed to use @trade. if (!pc_can_use_command(sd, "trade", COMMAND_ATCOMMAND) && (sd->bl.m != target_sd->bl.m || !check_distance_bl(&sd->bl, &target_sd->bl, TRADE_DISTANCE))) { clif_tradestart(sd, 0); // too far return ; } target_sd->trade_partner = sd->status.account_id; sd->trade_partner = target_sd->status.account_id; clif_traderequest(target_sd, sd->status.name); }
// This function only check if the mail operations are valid bool mail_invalid_operation(struct map_session_data *sd) { if( !map[sd->bl.m].flag.town && !pc_can_use_command(sd, "mail", COMMAND_ATCOMMAND) ) { ShowWarning("clif_parse_Mail: char '%s' trying to do invalid mail operations.\n", sd->status.name); return true; } return false; }
/*========================================== * Reply to a trade-request. * Type values: * 0: Char is too far * 1: Character does not exist * 2: Trade failed * 3: Accept * 4: Cancel * Weird enough, the client should only send 3/4 * and the server is the one that can reply 0~2 *------------------------------------------*/ void trade_tradeack (struct map_session_data *sd, int type) { struct map_session_data *tsd; nullpo_retv (sd); sd->state.can_tradeack = 0; if (sd->state.trading || !sd->trade_partner) return; //Already trading or no partner set. if ( (tsd = map_id2sd (sd->trade_partner)) == NULL) { clif_tradestart (sd, 1); // character does not exist sd->trade_partner = 0; return; } if (tsd->state.trading || tsd->trade_partner != sd->bl.id) { clif_tradestart (sd, 2); sd->trade_partner = 0; return; //Already trading or wrong partner. } if (type == 4) { // Cancel clif_tradestart (tsd, type); clif_tradestart (sd, type); sd->state.deal_locked = 0; sd->trade_partner = 0; tsd->state.deal_locked = 0; tsd->trade_partner = 0; return; } if (type != 3) return; //If client didn't send accept, it's a broken packet? // Players can not request trade from far away, unless they are allowed to use @trade. // Check here as well since the original character could had warped. if (!pc_can_use_command (sd, "trade", COMMAND_ATCOMMAND) && (sd->bl.m != tsd->bl.m || !check_distance_bl (&sd->bl, &tsd->bl, TRADE_DISTANCE))) { clif_tradestart (sd, 0); // too far sd->trade_partner = 0; tsd->trade_partner = 0; return; } //Check if you can start trade. if (sd->npc_id || sd->state.vending || sd->state.buyingstore || sd->state.storage_flag || tsd->npc_id || tsd->state.vending || tsd->state.buyingstore || tsd->state.storage_flag) { //Fail clif_tradestart (sd, 2); clif_tradestart (tsd, 2); sd->state.deal_locked = 0; sd->trade_partner = 0; tsd->state.deal_locked = 0; tsd->trade_partner = 0; return; } //Initiate trade sd->state.trading = 1; tsd->state.trading = 1; memset (&sd->deal, 0, sizeof (sd->deal)); memset (&tsd->deal, 0, sizeof (tsd->deal)); clif_tradestart (tsd, type); clif_tradestart (sd, type); }