Explorar o código

- 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://svn.code.sf.net/p/rathena/svn/trunk@9438 54d463be-8e91-2dee-dedb-b68131a5f0ec

skotlex %!s(int64=18) %!d(string=hai) anos
pai
achega
7a607a433a
Modificáronse 3 ficheiros con 52 adicións e 33 borrados
  1. 4 0
      Changelog-Trunk.txt
  2. 3 7
      src/map/clif.c
  3. 45 26
      src/map/trade.c

+ 4 - 0
Changelog-Trunk.txt

@@ -4,6 +4,10 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
 2006/12/08
+	* Now you can request a trade regardless of the state of the target trader.
+	  [Skotlex]
+	* The trade will now fail when you accept it and either character is
+	  speaking with an npc, vending or has the storage open. [Skotlex]
 	* Fixed crash when looters became full. [Skotlex]
 	* Autospell delay time is now the skill's full delay.  [Skotlex]
 2006/12/07

+ 3 - 7
src/map/clif.c

@@ -9606,13 +9606,9 @@ void clif_parse_TradeRequest(int fd,struct map_session_data *sd)
 		return; //You can trade while in a chatroom.
 
 	// @noask [LuzZza]
-	if(t_sd) {
-	 	if (t_sd->state.noask) {
-			clif_noask_sub(sd, t_sd, 0);
-			return;
-		}
-		if(!t_sd->chatID && clif_cant_act(t_sd))
-			return;
+	if(t_sd && t_sd->state.noask) {
+		clif_noask_sub(sd, t_sd, 0);
+		return;
 	}
 
 	if(battle_config.basic_skill_check == 0 || pc_checkskill(sd,NV_BASIC) >= 1){

+ 45 - 26
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);
 }
 
 /*==========================================