From 600ed9e0e1db5b2993827ecb1ac5db36ffe56c7b Mon Sep 17 00:00:00 2001 From: skotlex Date: Fri, 8 Dec 2006 15:05:48 +0000 Subject: - Now you can request a trade regardless of the state of the target trader. - The trade will now fail when you accept it and either character is speaking with an npc, vending or has the storage open. - Cleaned up some the trade ack function, added proper replies to some fail cases. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@9438 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/trade.c | 71 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 26 deletions(-) (limited to 'src/map/trade.c') diff --git a/src/map/trade.c b/src/map/trade.c index 09b07e02f..36c6d43f4 100644 --- a/src/map/trade.c +++ b/src/map/trade.c @@ -76,55 +76,74 @@ void trade_traderequest(struct map_session_data *sd, struct map_session_data *ta /*========================================== * Reply to a trade-request. + * Type values: + * 0: Char is too far + * 1: Character does not exists + * 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 *target_sd; + struct map_session_data *tsd; nullpo_retv(sd); if (sd->state.trading || !sd->trade_partner) return; //Already trading or no partner set. - if ((target_sd = map_id2sd(sd->trade_partner)) == NULL) { + if ((tsd = map_id2sd(sd->trade_partner)) == NULL) { sd->trade_partner=0; + clif_tradestart(sd, 1); // character does not exist return; } - if (target_sd->state.trading || target_sd->trade_partner != sd->bl.id) + if (tsd->state.trading || tsd->trade_partner != sd->bl.id) + { + clif_tradestart(sd, 2); return; //Already trading or wrong partner. + } + + if (type == 4) { // Cancel + sd->state.deal_locked = 0; + sd->trade_partner = 0; + tsd->state.deal_locked = 0; + tsd->trade_partner = 0; + clif_tradestart(tsd, type); + clif_tradestart(sd, type); + return; + } + + if (type != 3) + return; //If client didn't send accept, it's a broken packet? //Copied here as well since the original character could had warped. - if (type == 3 && pc_isGM(target_sd) < lowest_gm_level && (sd->bl.m != target_sd->bl.m || - !check_distance_bl(&sd->bl, &target_sd->bl, TRADE_DISTANCE) + if (pc_isGM(tsd) < lowest_gm_level && (sd->bl.m != tsd->bl.m || + !check_distance_bl(&sd->bl, &tsd->bl, TRADE_DISTANCE) )) { sd->trade_partner=0; - target_sd->trade_partner = 0; + tsd->trade_partner = 0; clif_tradestart(sd, 0); // too far return; } - //TODO: Type 4/3? What would 1/2 and the rest do? - if (type == 4) { // Cancel - sd->state.deal_locked = 0; - sd->trade_partner = 0; - target_sd->state.deal_locked = 0; - target_sd->trade_partner = 0; - clif_tradestart(target_sd, type); - clif_tradestart(sd, type); + //Check if you can start trade. + if (sd->npc_id || sd->vender_id || sd->state.storage_flag || + tsd->npc_id || tsd->vender_id || tsd->state.storage_flag) + { //Fail + clif_tradestart(sd, 2); + clif_tradestart(tsd, 2); + return; } - if (type == 3) { //Initiate trade - sd->state.trading = 1; - target_sd->state.trading = 1; - malloc_set(&sd->deal, 0, sizeof(sd->deal)); - malloc_set(&target_sd->deal, 0, sizeof(target_sd->deal)); - clif_tradestart(target_sd, type); - clif_tradestart(sd, type); - if (sd->npc_id) - npc_event_dequeue(sd); - if (target_sd->npc_id) - npc_event_dequeue(target_sd); - } + //Initiate trade + sd->state.trading = 1; + tsd->state.trading = 1; + malloc_set(&sd->deal, 0, sizeof(sd->deal)); + malloc_set(&tsd->deal, 0, sizeof(tsd->deal)); + clif_tradestart(tsd, type); + clif_tradestart(sd, type); } /*========================================== -- cgit v1.2.3-60-g2f50