From 13126fd8573dbca5096014f4d007d0469ec24e28 Mon Sep 17 00:00:00 2001
From: shennetsind <shennetsind@54d463be-8e91-2dee-dedb-b68131a5f0ec>
Date: Thu, 22 Mar 2012 03:43:37 +0000
Subject: Fixed bugreport:5486, now a more friendly message is displayed upon
 skill fail when you do not have enough of the required ammo.

Dev Note: I wasn't able to find a proper reply packet so I came up with this .-. if you know a official solution make yourself comfortable to replace.

git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@15752 54d463be-8e91-2dee-dedb-b68131a5f0ec
---
 src/map/clif.c  | 34 ++++++++++++++++++++++++++++------
 src/map/clif.h  | 12 +++++++++++-
 src/map/skill.c | 13 +++++++++----
 3 files changed, 48 insertions(+), 11 deletions(-)

diff --git a/src/map/clif.c b/src/map/clif.c
index fc215c26a..8aa336cae 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -8023,12 +8023,25 @@ void clif_specialeffect_value(struct block_list* bl, int effect_id, int num, sen
 		clif_send(buf, packet_len(0x284), bl, SELF);
 	}
 }
+// Modification of clif_messagecolor to send colored messages to players to chat log only (doesn't display overhead)
+/// 02c1 <packet len>.W <id>.L <color>.L <message>.?B
+int clif_colormes(struct map_session_data * sd, enum clif_colors color, const char* msg) {
+	unsigned short msg_len = strlen(msg) + 1;
 
+	WFIFOHEAD(sd->fd,msg_len + 12);
+	WFIFOW(sd->fd,0) = 0x2C1;
+	WFIFOW(sd->fd,2) = msg_len + 12;
+	WFIFOL(sd->fd,4) = 0;
+	WFIFOL(sd->fd,8) = color_table[color];
+	safestrncpy((char*)WFIFOP(sd->fd,12), msg, msg_len);
+	clif_send(WFIFOP(sd->fd,0), WFIFOW(sd->fd,2), &sd->bl, SELF);
+
+	return 0;
+}
 
 /// Monster/NPC color chat [SnakeDrak] (ZC_NPC_CHAT).
 /// 02c1 <packet len>.W <id>.L <color>.L <message>.?B
-void clif_messagecolor(struct block_list* bl, unsigned long color, const char* msg)
-{
+void clif_messagecolor(struct block_list* bl, unsigned long color, const char* msg) {
 	unsigned short msg_len = strlen(msg) + 1;
 	uint8 buf[256];
 	color = (color & 0x0000FF) << 16 | (color & 0x00FF00) | (color & 0xFF0000) >> 16; // RGB to BGR
@@ -16546,8 +16559,17 @@ static int packetdb_readdb(void)
 /*==========================================
  *
  *------------------------------------------*/
-int do_init_clif(void)
-{
+int do_init_clif(void) {
+	const char* colors[COLOR_MAX] = { "0xFF0000" };
+	int i;
+	/**
+	 * Setup Color Table (saves unnecessary load of strtoul on every call)
+	 **/
+	for(i = 0; i < COLOR_MAX; i++) {
+		color_table[i] = strtoul(colors[i],NULL,0);
+		color_table[i] = (color_table[i] & 0x0000FF) << 16 | (color_table[i] & 0x00FF00) | (color_table[i] & 0xFF0000) >> 16;//RGB to BGR
+	}
+
 	clif_config.packet_db_ver = -1; // the main packet version of the DB
 	memset(clif_config.connect_cmd, 0, sizeof(clif_config.connect_cmd)); //The default connect command will be determined after reading the packet_db [Skotlex]
 
@@ -16556,13 +16578,13 @@ int do_init_clif(void)
 	packetdb_readdb();
 
 	set_defaultparse(clif_parse);
-	if( make_listen_bind(bind_ip,map_port) == -1 )
-	{
+	if( make_listen_bind(bind_ip,map_port) == -1 ) {
 		ShowFatalError("can't bind game port\n");
 		exit(EXIT_FAILURE);
 	}
 
 	add_timer_func_list(clif_clearunit_delayed_sub, "clif_clearunit_delayed_sub");
 	add_timer_func_list(clif_delayquit, "clif_delayquit");
+
 	return 0;
 }
diff --git a/src/map/clif.h b/src/map/clif.h
index 95f3e6188..575798c6f 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -739,8 +739,18 @@ int clif_poison_list(struct map_session_data *sd, int skill_lv);
  **/
 int clif_autoshadowspell_list(struct map_session_data *sd);
 /**
- * [RRInd] for the new mounts
+ * New Mounts
  **/
 int clif_status_load_notick(struct block_list *bl,int type,int flag,int val1, int val2, int val3);
 int clif_status_load_single(int fd, int id,int type,int flag,int val1, int val2, int val3);
+/**
+ * Color Table
+ **/
+enum clif_colors {
+	COLOR_RED,
+
+	COLOR_MAX
+};
+unsigned long color_table[COLOR_MAX];
+int clif_colormes(struct map_session_data * sd, enum clif_colors color, const char* msg);
 #endif /* _CLIF_H_ */
diff --git a/src/map/skill.c b/src/map/skill.c
index 1bae14129..24bdd9ee1 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -11755,12 +11755,17 @@ int skill_check_condition_castend(struct map_session_data* sd, short skill, shor
 	}
 
 	if( require.ammo ) { //Skill requires stuff equipped in the arrow slot.
-		if((i=sd->equip_index[EQI_AMMO]) < 0 ||
-			!sd->inventory_data[i] ||
-			sd->status.inventory[i].amount < require.ammo_qty
-		) {
+		if((i=sd->equip_index[EQI_AMMO]) < 0 || !sd->inventory_data[i] ) {
 			clif_arrow_fail(sd,0);
 			return 0;
+		} else if( sd->status.inventory[i].amount < require.ammo_qty ) {
+			char e_msg[100];
+			sprintf(e_msg,"Skill Failed. [%s] requires %dx %s.",
+						skill_get_desc(skill),
+						require.ammo_qty,
+						itemdb_jname(sd->status.inventory[i].nameid));
+			clif_colormes(sd,COLOR_RED,e_msg);
+			return 0;
 		}
 		if (!(require.ammo&1<<sd->inventory_data[i]->look))
 		{	//Ammo type check. Send the "wrong weapon type" message
-- 
cgit v1.2.3-70-g09d2