Browse Source

Added script command mesitemlink (#7565)

Adds a new script command for itemlink generation for usage inside NPC dialogs (mes "").
A few cleanups related to the normal itemlink feature.

Thanks to @Atemo and @aleos89 for their help!

Co-authored-by: Atemo <Atemo@users.noreply.github.com>
Co-authored-by: Aleos <aleos89@users.noreply.github.com>
Lemongrass3110 2 years ago
parent
commit
f261307bbe

+ 13 - 0
conf/battle/feature.conf

@@ -147,6 +147,19 @@ feature.dynamicnpc_direction: no
 // Requires: 2015-11-04Ragexe or later
 // Requires: 2015-11-04Ragexe or later
 feature.itemlink: on
 feature.itemlink: on
 
 
+// Itemlink System on NPC messages (Note 1)
+// Generates an itemlink string for an item and can be used for NPC's mes command.
+// Requires: 2010-01-01 or later
+feature.mesitemlink: on
+
+// Force all mesitemlinks to be wrapped in brackets (Note 1)
+// Default: no
+feature.mesitemlink_brackets: no
+
+// Force all mesitemlinks to use the database name (Note 1)
+// Default: no
+feature.mesitemlink_dbname: no
+
 // Stylist UI (Note 1)
 // Stylist UI (Note 1)
 // Requires: 2015-11-04 or later
 // Requires: 2015-11-04 or later
 feature.stylist: on
 feature.stylist: on

+ 26 - 4
doc/script_commands.txt

@@ -1127,13 +1127,17 @@ In 2015 the tag name was changed to <ITEM> resulting in the following syntax:
 
 
 	<ITEM>Display Name<INFO>Item ID</INFO></ITEM>
 	<ITEM>Display Name<INFO>Item ID</INFO></ITEM>
 
 
+We therefore created script command "mesitemlink" that allows you to create the correct syntax
+depending on your configured packet version. We recommend that you use this script command
+instead of hardcoding the HTML-like tags. For more details see the documentation for "mesitemlink".
+
 The following sample will open a preview window for Red Potion:
 The following sample will open a preview window for Red Potion:
 
 
 	mes "Did you ever consume a <ITEMLINK>Red Potion<INFO>501</INFO></ITEMLINK>?";
 	mes "Did you ever consume a <ITEMLINK>Red Potion<INFO>501</INFO></ITEMLINK>?";
 	// Or in 2015:
 	// Or in 2015:
 	mes "Did you ever consume a <ITEM>Red Potion<INFO>501</INFO></ITEM>?";
 	mes "Did you ever consume a <ITEM>Red Potion<INFO>501</INFO></ITEM>?";
 
 
-NOTE: Be aware that item links are rendered incorrectly in 2015+ clients at the moment.
+NOTE: Be aware that item links are broken in some 2015 clients.
 
 
 URLs
 URLs
 ----
 ----
@@ -10998,13 +11002,13 @@ If <char id> is specified, the specified player is used rather than the attached
 
 
 ---------------------------------------
 ---------------------------------------
 
 
-*itemlink(<item_id>,<refine>,<card0>,<card1>,<card2>,<card3>,<enchantgrade>{,<RandomIDArray>,<RandomValueArray>,<RandomParamArray>});
+*itemlink(<item_id>{,<refine>{,<card0>{,<card1>{,<card2>{,<card3>,{<enchantgrade>{,<RandomIDArray>,<RandomValueArray>,<RandomParamArray>}}}}}}});
 
 
 Generates an item link string for an item that can be used for npctalk, message,
 Generates an item link string for an item that can be used for npctalk, message,
 dispbottom, and broadcast commands. The result is a clickable-item name just
 dispbottom, and broadcast commands. The result is a clickable-item name just
 like SHIFT+Click from a player's inventory/cart/equipment window. This command can be
 like SHIFT+Click from a player's inventory/cart/equipment window. This command can be
-used with mes but the item name will not be clickable. You should use the normal client
-tags for displaying item links in mes dialogues, if the client supports them. 
+used with mes but the item name will not be clickable. You should use script command
+"mesitemlink" for displaying item links in mes dialogues, if the client supports them. 
 
 
 
 
 Examples:
 Examples:
@@ -11021,6 +11025,24 @@ Examples:
 RandomIDArray, RandomValueArray, and RandomParamArray only works if the
 RandomIDArray, RandomValueArray, and RandomParamArray only works if the
 client (and server) supports the Item Random Options feature (PACKETVER >= 20150225).
 client (and server) supports the Item Random Options feature (PACKETVER >= 20150225).
 
 
+---------------------------------------
+
+*mesitemlink(<item_id>{,<use_brackets>{,<display_name>});
+
+Generates an itemlink string for an item and can be used with NPC's mes command.
+The NPC message will show the item's name which will be clickable and opens the
+item description client side.
+By default <use_brackets> is true which surrounds the link with brackets. Send false to disable.
+By default the link will be created with the name of the item stored in the item database,
+but in some cases it might be necessary to overwrite the <display_name> with something else.
+
+Examples:
+
+	mes mesitemlink( 1201 ); // Will display "[Knife]" and will be clickable. If clicked it opens the description for Knife [3]
+	mes "Bring me a " + mesitemlink( 1201 ) + "."; // Will display "Bring me a [Knife]." and "[Knife]" will be clickable.
+	mes "Bring me a " + mesitemlink( 1201, false ) + "."; // Will display "Bring me a Knife." and "Knife" will be clickable.
+	mes "Bring me a " + mesitemlink( 1201, true, "Super cutting knife" ) + "."; // Will display "Bring me a [Super cutting knife]." and "[Super cutting knife]" will be clickable.
+
 ========================
 ========================
 |14.- Channel commands.|
 |14.- Channel commands.|
 ========================
 ========================

+ 3 - 3
npc/custom/official/GeffenMagicTournament.txt

@@ -260,7 +260,7 @@ L_Shield:
 				case 3: goto L_Menu; break;
 				case 3: goto L_Menu; break;
 			}
 			}
 			mes .@n$;
 			mes .@n$;
-			mes "<ITEM>"+getitemname(.@item)+"<INFO>"+.@item+"</INFO></ITEM>";
+			mes mesitemlink( .@item, false );
 			mes "Price is "+.@cost+" coins";
 			mes "Price is "+.@cost+" coins";
 			mes "Do you wish to exchange your coins?";
 			mes "Do you wish to exchange your coins?";
 			next;
 			next;
@@ -303,7 +303,7 @@ L_Ring:
 						break;
 						break;
 				}
 				}
 			mes .@n$;
 			mes .@n$;
-			mes "<ITEM>"+getitemname(.@item)+"<INFO>"+.@item+"</INFO></ITEM>";
+			mes mesitemlink( .@item, false );
 			mes "Price is "+.@cost+" coins";
 			mes "Price is "+.@cost+" coins";
 			mes "Do you wish to exchange your coins?";
 			mes "Do you wish to exchange your coins?";
 			next;
 			next;
@@ -345,7 +345,7 @@ L_Armor:
 						break;
 						break;
 				}
 				}
 			mes .@n$;
 			mes .@n$;
-			mes "<ITEM>"+getitemname(.@item)+"<INFO>"+.@item+"</INFO></ITEM>";
+			mes mesitemlink( .@item, false );
 			mes "Price is "+.@cost+" coins";
 			mes "Price is "+.@cost+" coins";
 			mes "Do you wish to exchange your coins?";
 			mes "Do you wish to exchange your coins?";
 			next;
 			next;

+ 13 - 13
npc/re/custom/lasagna/lasagna_npcs.txt

@@ -2066,22 +2066,22 @@ lasagna,131,245,5	script	The diligent second son	4_CAT_3COLOR,{
 	mes "[Yota Chara]";
 	mes "[Yota Chara]";
 	switch(.@s) {
 	switch(.@s) {
 	case 1:
 	case 1:
-		mes "<ITEM>Low-grade Horse Mackerel Amulet <INFO>28413</INFO></ITEM> is for my father who is far out to the sea.";
+		mes mesitemlink( 28413, false ) + " is for my father who is far out to the sea.";
 		break;
 		break;
 	case 2:
 	case 2:
-		mes "<ITEM>Low-grade Leaf Amulet <INFO>28416</INFO></ITEM> is for my mother who should be wandering about the deep side of the forest.";
+		mes mesitemlink( 28416, false ) + " is for my mother who should be wandering about the deep side of the forest.";
 		break;
 		break;
 	case 3:
 	case 3:
-		mes "<ITEM>Low-grade Rabbit Amulet <INFO>28419</INFO></ITEM> is for my brothers' health and wellness.";
+		mes mesitemlink( 28419, false ) + " is for my brothers' health and wellness.";
 		break;
 		break;
 	case 4:
 	case 4:
-		mes "<ITEM>Shining Twig Charm <INFO>28422</INFO></ITEM> is to wish for my mother to return home safely from anywhere in the world.";
+		mes mesitemlink( 28422, false ) + " is to wish for my mother to return home safely from anywhere in the world.";
 		break;
 		break;
 	case 5:
 	case 5:
-		mes "<ITEM>Fresh Tuna Amulet <INFO>28423</INFO></ITEM> is to wish for my father to return home quick with his ship full of tunas.";
+		mes mesitemlink( 28423, false ) + " is to wish for my father to return home quick with his ship full of tunas.";
 		break;
 		break;
 	case 6:
 	case 6:
-		mes "<ITEM>Plump Earthworm Amulet <INFO>28424</INFO></ITEM> is to wish for easy fishing so that my family won't be starved.";
+		mes mesitemlink( 28424, false ) + " is to wish for easy fishing so that my family won't be starved.";
 		break;
 		break;
 	}
 	}
 	if (.@s < 4) {
 	if (.@s < 4) {
@@ -2092,7 +2092,7 @@ lasagna,131,245,5	script	The diligent second son	4_CAT_3COLOR,{
 		.@cost = 30;
 		.@cost = 30;
 		.@item_id = 28418 + .@s;
 		.@item_id = 28418 + .@s;
 	}
 	}
-	mes "Will you exchange it for " + .@cost + " <ITEM>Doram Token<INFO>25142</INFO></ITEM>?";
+	mes "Will you exchange it for " + .@cost + " " + mesitemlink( 25142, false ) + "?";
 	next;
 	next;
 	if (select( "Exchange", "Cancel" ) == 2) {
 	if (select( "Exchange", "Cancel" ) == 2) {
 		mes "[Yota Chara]";
 		mes "[Yota Chara]";
@@ -2164,7 +2164,7 @@ lasagna,131,250,5	script	The brave third#weapon	4_DR_M_02,{
 	emotion ET_SPARK;
 	emotion ET_SPARK;
 	mes "[Jogi Chara]";
 	mes "[Jogi Chara]";
 	mes "Whoa, a new weapon! New power!";
 	mes "Whoa, a new weapon! New power!";
-	mes "What are you going to give me? Do you have a lot of weapons? Can I search into them? Will you exchange it for <ITEM>Doram Token <INFO>25142</INFO></ITEM>?";
+	mes "What are you going to give me? Do you have a lot of weapons? Can I search into them? Will you exchange it for " + mesitemlink( 25142, false ) + "?";
 	next;
 	next;
 	if (select( "Search", "Cancel" ) == 1) {
 	if (select( "Search", "Cancel" ) == 1) {
 		setarray .@item_data[0],
 		setarray .@item_data[0],
@@ -2193,7 +2193,7 @@ lasagna,131,250,5	script	The brave third#weapon	4_DR_M_02,{
 			else {
 			else {
 				mes "[Jogi Chara]";
 				mes "[Jogi Chara]";
 				mes "Whoa! This is ^3131FF" + getitemname(.@item_data[.@i]) + "^000000!";
 				mes "Whoa! This is ^3131FF" + getitemname(.@item_data[.@i]) + "^000000!";
-				mes "Exchange it for " + .@item_data[.@i+1] + " <ITEM>Doram Token<INFO>25142</INFO></ITEM>! Please? Will you do it, please?";
+				mes "Exchange it for " + .@item_data[.@i+1] + " " + mesitemlink( 25142, false ) + "! Please? Will you do it, please?";
 				next;
 				next;
 				if (select( "Exchange", "Quit exchanging" ) == 2) {
 				if (select( "Exchange", "Quit exchanging" ) == 2) {
 					mes "[Jogi Chara]";
 					mes "[Jogi Chara]";
@@ -2253,7 +2253,7 @@ lasagna,140,250,3	script	The skittish fourth#wea	4_DR_F_01,{
 	}
 	}
 	mes "[Dandi Chara]";
 	mes "[Dandi Chara]";
 	mes "Do you mind if I search you to see the items you have with you?";
 	mes "Do you mind if I search you to see the items you have with you?";
-	mes "If I find an item suitable for Jogi, I'll pay <INFO>25142</INFO><ITEM>Doram Token </ITEM>....";
+	mes "If I find an item suitable for Jogi, I'll pay " + mesitemlink( 25142, false ) + "....";
 	next;
 	next;
 	if (select( "Search", "Cancel" ) == 1) {
 	if (select( "Search", "Cancel" ) == 1) {
 		setarray .@item_data[0],	// keep the order
 		setarray .@item_data[0],	// keep the order
@@ -2298,7 +2298,7 @@ lasagna,140,250,3	script	The skittish fourth#wea	4_DR_F_01,{
 			else {
 			else {
 				mes "[Dandi Chara]";
 				mes "[Dandi Chara]";
 				mes "Whoa, this must be ^3131FF" + getitemname(.@item_data[.@i]) + "^000000!!";
 				mes "Whoa, this must be ^3131FF" + getitemname(.@item_data[.@i]) + "^000000!!";
-				mes "Don't you want to exchange this with " + .@item_data[.@i+1] + " <ITEM>Doram Token<INFO>25142</INFO></ITEM>?";
+				mes "Don't you want to exchange this with " + .@item_data[.@i+1] + " " + mesitemlink( 25142, false ) + "?";
 				next;
 				next;
 				if (select( "Exchange", "Quit exchanging" ) == 2) {
 				if (select( "Exchange", "Quit exchanging" ) == 2) {
 					mes "[Dandi Chara]";
 					mes "[Dandi Chara]";
@@ -2388,8 +2388,8 @@ lasagna,140,245,3	script	The sensitive-minded ela	4_CAT_SAILOR3,{
 	mes "...I knew this was going to happen again. Worse, this one must require a lot more time to polish!";
 	mes "...I knew this was going to happen again. Worse, this one must require a lot more time to polish!";
 	next;
 	next;
 	mes "[Goma Chara]";
 	mes "[Goma Chara]";
-	mes "Hey, if you give me " + .@needCoin + "<ITEM>Doram Token<INFO>25142</INFO></ITEM>, I'll fix this for you.";
-	mes "<ITEM>This should produce the <INFO>" + .@next_charm_ID + "</INFO></ITEM> function, I guess. How do you like it?";
+	mes "Hey, if you give me " + .@needCoin + " " + mesitemlink( 25142, false ) + ", I'll fix this for you.";
+	mes "This should produce " + mesitemlink( .@next_charm_ID, false ) + ", I guess. How do you like it?";
 	next;
 	next;
 	if (select( "Upgrade", "Cancel" ) == 2) {
 	if (select( "Upgrade", "Cancel" ) == 2) {
 		mes "[Goma Chara]";
 		mes "[Goma Chara]";

+ 1 - 1
npc/re/merchants/Emperium_Seller.txt

@@ -28,7 +28,7 @@ prt_in,212,169,3	script	Guild Clerk	4_M_04,{
 	next;
 	next;
 	mes "[Guild Clerk]";
 	mes "[Guild Clerk]";
 	mes "As part of that,";
 	mes "As part of that,";
-	mes "we are selling a limited quantity of 100 <ITEM>Emperium<INFO>714</INFO></ITEM> every day";
+	mes "we are selling a limited quantity of 100 " + mesitemlink( 714, false ) + " every day";
 	mes "from ^0000ff18:00 to 23:59^000000 from ^0000ffMonday to Saturday^000000.";
 	mes "from ^0000ff18:00 to 23:59^000000 from ^0000ffMonday to Saturday^000000.";
 	next;
 	next;
 	mes "[Guild Clerk]";
 	mes "[Guild Clerk]";

+ 1 - 1
npc/re/merchants/Slot_Move_Card_Sales.txt

@@ -15,7 +15,7 @@
 prt_in,211,173,3	script	Slot Move Card Sales#slo	4_F_01,{
 prt_in,211,173,3	script	Slot Move Card Sales#slo	4_F_01,{
 	mes "[Salesman]";
 	mes "[Salesman]";
 	mes "Howdy.";
 	mes "Howdy.";
-	mes "I'm selling <ITEM>[Character Position Change Coupon]<INFO>12786</INFO></ITEM>.";
+	mes "I'm selling " + mesitemlink( 12786 ) + ".";
 	mes "You can ^4d4dffchange the slot position of a character using the card^000000.";
 	mes "You can ^4d4dffchange the slot position of a character using the card^000000.";
 	next;
 	next;
 	mes "[Salesman]";
 	mes "[Salesman]";

+ 1 - 1
npc/re/merchants/cashmall.txt

@@ -110,7 +110,7 @@ itemmall,41,53,3	script	Cat Hand Salesman Macaroon#cashmall	4_M_MERCAT1,{
 	mes "Welcome!";
 	mes "Welcome!";
 	mes "Today doesn't come every day!";
 	mes "Today doesn't come every day!";
 	mes "Things to see today~ Voila!";
 	mes "Things to see today~ Voila!";
-	mes "You can only exchange with <ITEM>[[Kachua] Mileage Coupon]<INFO>1000274</INFO></ITEM>!";
+	mes "You can only exchange with " + mesitemlink( 1000274 ) + "!";
 	mes "Feel free to choose!";
 	mes "Feel free to choose!";
 	next;
 	next;
 	switch( select( "3-1st Job Group Skill Shadow", "3-2nd Job Group Skill Shadow", "Extended Job Group Skill Shadow", "General Shadow by Occupation", "Shadow Cube", "Smelting, Modification, Useful Items", "Drop Box", "Spellbook" ) ){
 	switch( select( "3-1st Job Group Skill Shadow", "3-2nd Job Group Skill Shadow", "Extended Job Group Skill Shadow", "General Shadow by Occupation", "Shadow Cube", "Smelting, Modification, Useful Items", "Drop Box", "Spellbook" ) ){

+ 1 - 1
npc/re/merchants/eden_market.txt

@@ -320,7 +320,7 @@ moc_para01,106,38,4	script	Market Group Hustler#ent	4_M_YOYOROGUE,{
 		next;
 		next;
 		mes "[Hustler]";
 		mes "[Hustler]";
 		mes "More special items are sold on weekends.";
 		mes "More special items are sold on weekends.";
-		mes "I have even seen an <ITEM>Izidor<INFO>709</INFO></ITEM> being sold~";
+		mes "I have even seen an " + mesitemlink( 709, false ) + " being sold~";
 		mes "It was amazing.";
 		mes "It was amazing.";
 		mes "Of course it was super expensive and only a handful were up for sale.";
 		mes "Of course it was super expensive and only a handful were up for sale.";
 		next;
 		next;

+ 15 - 15
npc/re/merchants/enchan_illusion_16_2.txt

@@ -54,7 +54,7 @@ pay_d03_i,160,45,3	script	Gemcutter#ilp20	4_TOWER_17,3,3,{
 		mes "[ Gemcutter ]";
 		mes "[ Gemcutter ]";
 		mes "The following is the list of equipment I can handle.";
 		mes "The following is the list of equipment I can handle.";
 		for ( .@i = 0; .@i < .@size; ++.@i )
 		for ( .@i = 0; .@i < .@size; ++.@i )
-			mes "<ITEM>" + .@reward_name$[.@i] + "<INFO>" + .@reward_id[.@i] + "</INFO></ITEM>";
+			mes mesitemlink( .@reward_id[.@i], false );
 		next;
 		next;
 		mes "[ Gemcutter ]";
 		mes "[ Gemcutter ]";
 		mes "Make sure ^0000FFyour equipment is refined to at least +" + .@refine_req + "^000000 before bringing it to me.";
 		mes "Make sure ^0000FFyour equipment is refined to at least +" + .@refine_req + "^000000 before bringing it to me.";
@@ -133,7 +133,7 @@ pay_d03_i,160,45,3	script	Gemcutter#ilp20	4_TOWER_17,3,3,{
 		mes "[ Gemcutter ]";
 		mes "[ Gemcutter ]";
 		mes "The following is the list of equipment I can handle.";
 		mes "The following is the list of equipment I can handle.";
 		for ( .@i = 0; .@i < .@size; ++.@i )
 		for ( .@i = 0; .@i < .@size; ++.@i )
-			mes "<ITEM>" + .@reward_name$[.@i] + "<INFO>" + .@reward_id[.@i] + "</INFO></ITEM>";
+			mes mesitemlink( .@reward_id[.@i], false );
 		next;
 		next;
 		mes "[ Gemcutter ]";
 		mes "[ Gemcutter ]";
 		mes "Make sure ^0000FFyour equipment is refined to at least +" + .@refine_req + "^000000 before bringing it to me.";
 		mes "Make sure ^0000FFyour equipment is refined to at least +" + .@refine_req + "^000000 before bringing it to me.";
@@ -385,7 +385,7 @@ gef_dun01,139,228,3	script	Great Merchant#illgef	4_M_HUMERCHANT,{
 			case 1:
 			case 1:
 				switch( select( "Illusion Infiltrator", "Illusion Sharpened Legbone of Ghoul", "Illusion Wizardry Staff", "Illusion Ballista", "Illusion Book of the Apocalypse" ) ) {
 				switch( select( "Illusion Infiltrator", "Illusion Sharpened Legbone of Ghoul", "Illusion Wizardry Staff", "Illusion Ballista", "Illusion Book of the Apocalypse" ) ) {
 				case 1:
 				case 1:
-					mes "<ITEM>Illusion Infiltrator<INFO>28022</INFO></ITEM>";
+					mes mesitemlink( 28022, false );
 					mes "***********************************";
 					mes "***********************************";
 					mes "Necessary Items";
 					mes "Necessary Items";
 					mes "^0000cd+9 or higher^000000 Infiltrator ^C71585[1]^000000 x1";
 					mes "^0000cd+9 or higher^000000 Infiltrator ^C71585[1]^000000 x1";
@@ -395,7 +395,7 @@ gef_dun01,139,228,3	script	Great Merchant#illgef	4_M_HUMERCHANT,{
 					mes "20 Torn Papers";
 					mes "20 Torn Papers";
 					break;
 					break;
 				case 2:
 				case 2:
-					mes "<ITEM>Illusion Sharpened Legbone of Ghoul<INFO>28023</INFO></ITEM>";
+					mes mesitemlink( 28023, false );
 					mes "********************************";
 					mes "********************************";
 					mes "Necessary Items";
 					mes "Necessary Items";
 					mes "^0000cd+9 or higher^000000 Sharpened Legbone of Ghoul x1";
 					mes "^0000cd+9 or higher^000000 Sharpened Legbone of Ghoul x1";
@@ -403,7 +403,7 @@ gef_dun01,139,228,3	script	Great Merchant#illgef	4_M_HUMERCHANT,{
 					mes "100 Clusters of Nightmares";
 					mes "100 Clusters of Nightmares";
 					break;
 					break;
 				case 3:
 				case 3:
-					mes "<ITEM>Illusion Wizardry Staff<INFO>2039</INFO></ITEM>";
+					mes mesitemlink( 2039, false );
 					mes "********************************";
 					mes "********************************";
 					mes "Necessary Items";
 					mes "Necessary Items";
 					mes "^0000cd+9 or higher^000000 Wizardry Staff x1";
 					mes "^0000cd+9 or higher^000000 Wizardry Staff x1";
@@ -411,7 +411,7 @@ gef_dun01,139,228,3	script	Great Merchant#illgef	4_M_HUMERCHANT,{
 					mes "100 Suspicious Pentacles";
 					mes "100 Suspicious Pentacles";
 					break;
 					break;
 				case 4:
 				case 4:
-					mes "<ITEM>Illusion Ballista<INFO>18149</INFO></ITEM>";
+					mes mesitemlink( 18149, false );
 					mes "*************************";
 					mes "*************************";
 					mes "Necessary Items";
 					mes "Necessary Items";
 					mes "^0000cd+9 or higher^000000 Ballista ^C71585[1]^000000 x1";
 					mes "^0000cd+9 or higher^000000 Ballista ^C71585[1]^000000 x1";
@@ -421,7 +421,7 @@ gef_dun01,139,228,3	script	Great Merchant#illgef	4_M_HUMERCHANT,{
 					mes "100 Shining Spores";
 					mes "100 Shining Spores";
 					break;
 					break;
 				case 5:
 				case 5:
-					mes "<ITEM>Illusion Book of the Apocalypse<INFO>28612</INFO></ITEM>";
+					mes mesitemlink( 28612, false );
 					mes "***********************";
 					mes "***********************";
 					mes "Necessary Items";
 					mes "Necessary Items";
 					mes "^0000cd+9 or higher^000000 Book of the Apocalypse x1";
 					mes "^0000cd+9 or higher^000000 Book of the Apocalypse x1";
@@ -432,7 +432,7 @@ gef_dun01,139,228,3	script	Great Merchant#illgef	4_M_HUMERCHANT,{
 				break;
 				break;
 			case 2:
 			case 2:
 				select("Illusion Ancient Cape");
 				select("Illusion Ancient Cape");
-				mes "<ITEM>Illusion Ancient Cape<INFO>20840</INFO></ITEM>";
+				mes mesitemlink( 20840, false );
 				mes "*******************************";
 				mes "*******************************";
 				mes "Necessary Items";
 				mes "Necessary Items";
 				mes "^0000cd+9 or higher^000000 Ancient Cape ^C71585[1]^000000 x1";
 				mes "^0000cd+9 or higher^000000 Ancient Cape ^C71585[1]^000000 x1";
@@ -444,7 +444,7 @@ gef_dun01,139,228,3	script	Great Merchant#illgef	4_M_HUMERCHANT,{
 			case 3:
 			case 3:
 				switch( select( "Illusion Skull Ring", "Illusion Ring" ) ) {
 				switch( select( "Illusion Skull Ring", "Illusion Ring" ) ) {
 				case 1:
 				case 1:
-					mes "<ITEM>Illusion Skull Ring<INFO>28508</INFO></ITEM>";
+					mes mesitemlink( 28508, false );
 					mes "*************************";
 					mes "*************************";
 					mes "Necessary Items";
 					mes "Necessary Items";
 					mes "Skull Ring ^C71585[1]^000000 x1";
 					mes "Skull Ring ^C71585[1]^000000 x1";
@@ -454,7 +454,7 @@ gef_dun01,139,228,3	script	Great Merchant#illgef	4_M_HUMERCHANT,{
 					mes "400 Dried Yggdrasil Leaves";
 					mes "400 Dried Yggdrasil Leaves";
 					break;
 					break;
 				case 2:
 				case 2:
-					mes "<ITEM>Illusion Ring<INFO>28509</INFO></ITEM>";
+					mes mesitemlink( 28509, false );
 					mes "********************";
 					mes "********************";
 					mes "Necessary Items";
 					mes "Necessary Items";
 					mes "Ring ^C71585[1]^000000 x1";
 					mes "Ring ^C71585[1]^000000 x1";
@@ -647,8 +647,8 @@ ice_dun02,153,18,3	script	Illusion Stone Research	4_M_ALCHE_B,{
 			getitemname(.@reward_id[1]);
 			getitemname(.@reward_id[1]);
 		mes "[Illusion Stone Researcher]";
 		mes "[Illusion Stone Researcher]";
 		mes "The following is the list of equipment I can handle.";
 		mes "The following is the list of equipment I can handle.";
-		mes "<ITEM>" + .@reward_name$[0] + "<INFO>" + .@reward_id[0] + "</INFO></ITEM>";
-		mes "<ITEM>" + .@reward_name$[1] + "<INFO>" + .@reward_id[1] + "</INFO></ITEM>";
+		mes mesitemlink( .@reward_id[0], false );
+		mes mesitemlink( .@reward_id[1], false );
 		next;
 		next;
 		mes "[Illusion Stone Researcher]";
 		mes "[Illusion Stone Researcher]";
 		mes "Make sure ^4d4dffyour equipment is refined to at least +9^000000 before bringing it to me.";
 		mes "Make sure ^4d4dffyour equipment is refined to at least +9^000000 before bringing it to me.";
@@ -695,9 +695,9 @@ ice_dun02,153,18,3	script	Illusion Stone Research	4_M_ALCHE_B,{
 			getitemname(.@reward_id[2]);
 			getitemname(.@reward_id[2]);
 		mes "[Illusion Stone Researcher]";
 		mes "[Illusion Stone Researcher]";
 		mes "The following is the list of equipment I can handle.";
 		mes "The following is the list of equipment I can handle.";
-		mes "<ITEM>" + .@reward_name$[0] + "<INFO>" + .@reward_id[0] + "</INFO></ITEM>";
-		mes "<ITEM>" + .@reward_name$[1] + "<INFO>" + .@reward_id[1] + "</INFO></ITEM>";
-		mes "<ITEM>" + .@reward_name$[2] + "<INFO>" + .@reward_id[2] + "</INFO></ITEM>";
+		mes mesitemlink( .@reward_id[0], false );
+		mes mesitemlink( .@reward_id[1], false );
+		mes mesitemlink( .@reward_id[2], false );
 		next;
 		next;
 		mes "[Illusion Stone Researcher]";
 		mes "[Illusion Stone Researcher]";
 		mes "Make sure ^4d4dffyour equipment is refined to at least +9^000000 before bringing it to me.";
 		mes "Make sure ^4d4dffyour equipment is refined to at least +9^000000 before bringing it to me.";

+ 26 - 26
npc/re/merchants/enchan_illusion_17_1.txt

@@ -21,7 +21,7 @@ sp_cor,152,158,4	script	Butterfly Merchant#sp_cor	4_M_ORIENT01,{
 sp_cor,136,156,3	script	Grace Operator#ext162	4_M_REPAIR,{
 sp_cor,136,156,3	script	Grace Operator#ext162	4_M_REPAIR,{
 	mes "[Grace Operator]";
 	mes "[Grace Operator]";
 	mes "Hello.";
 	mes "Hello.";
-	mes "We have ^4d4dffGrace^000000 equipment that can be exchanged for <ITEM>[" + getitemname(25723) + "]<INFO>25723</INFO></ITEM>.";
+	mes "We have ^4d4dffGrace^000000 equipment that can be exchanged for " + mesitemlink( 25723 ) + ".";
 	mes "I will guide you to exchange items according to your job.";
 	mes "I will guide you to exchange items according to your job.";
 	close2;
 	close2;
 	switch( eaclass() & EAJ_THIRDMASK ) {
 	switch( eaclass() & EAJ_THIRDMASK ) {
@@ -160,12 +160,12 @@ sp_cor,108,130,5	script	Rebellion#rm171_7	4_F_REBELLION3,{
 		npctalk "Elyumina: What? If you were just going to keep me standing here like a statue, why did you even call me? You jerks!", "Elyumina#rm171_4", bc_self;
 		npctalk "Elyumina: What? If you were just going to keep me standing here like a statue, why did you even call me? You jerks!", "Elyumina#rm171_4", bc_self;
 		if (checkweight(1201,3) == 0) {
 		if (checkweight(1201,3) == 0) {
 			mes "[Rebellion]";
 			mes "[Rebellion]";
-			mes "Do you want a Weapon Modification Device? It's 5 <ITEM>[Cor Cores]<INFO>25723</INFO></ITEM> or 1 million Zeny.";
+			mes "Do you want a Weapon Modification Device? It's 5 " + mesitemlink( 25723 ) + " or 1 million Zeny.";
 			mes "Your bag is full. Please make some room first.";
 			mes "Your bag is full. Please make some room first.";
 			close;
 			close;
 		}
 		}
 		mes "[Rebellion]";
 		mes "[Rebellion]";
-		mes "Do you want a Weapon Modification Device? It's 5 <ITEM>[Cor Cores]<INFO>25723</INFO></ITEM> or 1 million Zeny.";
+		mes "Do you want a Weapon Modification Device? It's 5 " + mesitemlink( 25723 ) + " or 1 million Zeny.";
 		mes "If you want a weapon, you can talk to Elyumina.";
 		mes "If you want a weapon, you can talk to Elyumina.";
 		next;
 		next;
 		if (select("Request Weapon Modification Device (Physical).", "Request Weapon Modification Device (Magic).") == 1) {
 		if (select("Request Weapon Modification Device (Physical).", "Request Weapon Modification Device (Magic).") == 1) {
@@ -178,9 +178,9 @@ sp_cor,108,130,5	script	Rebellion#rm171_7	4_F_REBELLION3,{
 			setarray .@ids[0],23779,23780,23781;
 			setarray .@ids[0],23779,23780,23781;
 		}
 		}
 		mes "[Rebellion]";
 		mes "[Rebellion]";
-		mes "I can randomly give you a <ITEM>[" + getitemname(.@ids[0]) + "]<INFO>" + .@ids[0] + "</INFO></ITEM>,";
-		mes "<ITEM>[" + getitemname(.@ids[1]) + "]<INFO>" + .@ids[1] + "</INFO></ITEM>,";
-		mes "or <ITEM>[" + getitemname(.@ids[2]) + "]<INFO>" + .@ids[2] + "</INFO></ITEM>.";
+		mes "I can randomly give you a " + mesitemlink( .@ids[0] ) + ",";
+		mes mesitemlink( .@ids[1] ) + ",";
+		mes "or " + mesitemlink( .@ids[2] ) + ".";
 		mes "Which one do you have, 5 Cor Cores or 1 million Zeny?";
 		mes "Which one do you have, 5 Cor Cores or 1 million Zeny?";
 		next;
 		next;
 		disable_items;
 		disable_items;
@@ -220,7 +220,7 @@ sp_cor,108,130,5	script	Rebellion#rm171_7	4_F_REBELLION3,{
 	case 3:
 	case 3:
 		npctalk "Elyumina: What? If you were just going to keep me standing here like a statue, why did you even call me? You brutes!", "Elyumina#rm171_4", bc_self;
 		npctalk "Elyumina: What? If you were just going to keep me standing here like a statue, why did you even call me? You brutes!", "Elyumina#rm171_4", bc_self;
 		mes "[Rebellion]";
 		mes "[Rebellion]";
-		mes "Do you want an Armor Modification Module? It's 30 <ITEM>[Mysterious Components]<INFO>25669</INFO></ITEM> and 5 <ITEM>[Cor Cores]<INFO>25723</INFO></ITEM>.";
+		mes "Do you want an Armor Modification Module? It's 30 " + mesitemlink( 25669 ) + " and 5 " + mesitemlink( 25723 ) + ".";
 		if (checkweight(1201,3) == 0) {
 		if (checkweight(1201,3) == 0) {
 			mes "Your bag is full. Please make some room first.";
 			mes "Your bag is full. Please make some room first.";
 			close;
 			close;
@@ -287,7 +287,7 @@ sp_cor,111,130,3	script	Elyumina#rm171_4	4_EP17_ELYUMINA,{
 	case 1:
 	case 1:
 		cutin "ep171_elyumina01",0;
 		cutin "ep171_elyumina01",0;
 		mes "[Elyumina]";
 		mes "[Elyumina]";
-		mes "OS weapons? I'll handle that if you bring me 1 <ITEM>[Damaged Weapon]<INFO>25668</INFO></ITEM> and 50 <ITEM>[Mysterious Components]<INFO>25669</INFO></ITEM>.";
+		mes "OS weapons? I'll handle that if you bring me 1 " + mesitemlink( 25668 ) + " and 50 " + mesitemlink( 25669 ) + ".";
 		mes "I'll give you whatever kind I want to give you, among the ones I have. Why should I let you pick?";
 		mes "I'll give you whatever kind I want to give you, among the ones I have. Why should I let you pick?";
 		next;
 		next;
 		cutin "",255;
 		cutin "",255;
@@ -297,21 +297,21 @@ sp_cor,111,130,3	script	Elyumina#rm171_4	4_EP17_ELYUMINA,{
 			mes "Tsk, tsk. I said everything I make is good. Do you really have to choose? Alright, then listen up.";
 			mes "Tsk, tsk. I said everything I make is good. Do you really have to choose? Alright, then listen up.";
 			next;
 			next;
 			mes "[Elyumina]";
 			mes "[Elyumina]";
-			mes "Sword: <ITEM>[Cannon Rapier-OS]<INFO>13493</INFO></ITEM>";
-			mes "Two-handed Sword: <ITEM>[Beam Claymore-OS]<INFO>21047</INFO></ITEM>";
-			mes "Staff: <ITEM>[Rutilus Stick-OS]<INFO>26151</INFO></ITEM>";
-			mes "Book: <ITEM>[Circuit Board-OS]<INFO>28629</INFO></ITEM>";
-			mes "Axe: <ITEM>[Blasti-OS]<INFO>28136</INFO></ITEM>";
-			mes "Mace: <ITEM>[Saphir Hall-OS]<INFO>16088</INFO></ITEM>";
-			mes "Bow: <ITEM>[Virtual Bow-OS]<INFO>18178</INFO></ITEM>";
-			mes "Crossbow: <ITEM>[MH-P89-OS]<INFO>18179</INFO></ITEM>";
-			mes "Katar: <ITEM>[Meuchler-OS]<INFO>28038</INFO></ITEM>";
-			mes "Knuckle: <ITEM>[Burning Knuckle-OS]<INFO>1862</INFO></ITEM>";
-			mes "Sniper Rifle: <ITEM>[HR-S55-OS]<INFO>28253</INFO></ITEM>";
-			mes "Dagger: <ITEM>[Kuroiro-OS]<INFO>28755</INFO></ITEM>";
-			mes "Bow: <ITEM>[AC-B44-OS]<INFO>18180</INFO></ITEM>";
-			mes "Lance: <ITEM>[Boost Lance-OS]<INFO>32019</INFO></ITEM>";
-			mes "Mace: <ITEM>[Ultio-OS]<INFO>16089</INFO></ITEM>";
+			mes "Sword: " + mesitemlink( 13493 );
+			mes "Two-handed Sword: " + mesitemlink( 21047 );
+			mes "Staff: " + mesitemlink( 26151 );
+			mes "Book: " + mesitemlink( 28629 );
+			mes "Axe: " + mesitemlink( 28136 );
+			mes "Mace: " + mesitemlink( 16088 );
+			mes "Bow: " + mesitemlink( 18178 );
+			mes "Crossbow: " + mesitemlink( 18179 );
+			mes "Katar: " + mesitemlink( 28038 );
+			mes "Knuckle: " + mesitemlink( 1862 );
+			mes "Sniper Rifle: " + mesitemlink( 28253 );
+			mes "Dagger: " + mesitemlink( 28755 );
+			mes "Bow: " + mesitemlink( 18180 );
+			mes "Lance: " + mesitemlink( 32019 );
+			mes "Mace: " + mesitemlink( 16089 );
 			close3;
 			close3;
 		}
 		}
 		disable_items;
 		disable_items;
@@ -340,7 +340,7 @@ sp_cor,111,130,3	script	Elyumina#rm171_4	4_EP17_ELYUMINA,{
 	case 2:
 	case 2:
 		cutin "ep171_elyumina04",0;
 		cutin "ep171_elyumina04",0;
 		mes "[Elyumina]";
 		mes "[Elyumina]";
-		mes "If you want Illusion armor, bring me 50 <ITEM>[Cor Cores]<INFO>25723</INFO></ITEM>. I'll give you a piece.";
+		mes "If you want Illusion armor, bring me 50 " + mesitemlink( 25723 ) + ". I'll give you a piece.";
 		mes "Let's see... Ooh, when did I make so many varieties? Alright, I feel generous. What do you want?";
 		mes "Let's see... Ooh, when did I make so many varieties? Alright, I feel generous. What do you want?";
 		next;
 		next;
 		cutin "",255;
 		cutin "",255;
@@ -363,8 +363,8 @@ sp_cor,111,130,3	script	Elyumina#rm171_4	4_EP17_ELYUMINA,{
 		}
 		}
 		cutin "ep171_elyumina01",0;
 		cutin "ep171_elyumina01",0;
 		mes "[Elyumina]";
 		mes "[Elyumina]";
-		mes "<ITEM>[" + getitemname(.@item[0]) + "]<INFO>" + .@item[0] + "</INFO></ITEM>";
-		mes "<ITEM>[" + getitemname(.@item[1]) + "]<INFO>" + .@item[1] + "</INFO></ITEM>";
+		mes mesitemlink( .@item[0] );
+		mes mesitemlink( .@item[1] );
 		mes "Which one?";
 		mes "Which one?";
 		next;
 		next;
 		cutin "",255;
 		cutin "",255;

+ 2 - 2
npc/re/merchants/enchan_rockridge.txt

@@ -296,7 +296,7 @@ har_in01,24,69,3	script	Affable Lady#rockridge0	1_F_MERCHANT_02,{
 	}
 	}
 	mes "[Affable Lady]";
 	mes "[Affable Lady]";
 	mes "Ah, you're interested in the";
 	mes "Ah, you're interested in the";
-	mes "[<ITEM>" + .@item_name$[.@s] + "<INFO>" + .@item_id[.@s] + "</INFO></ITEM>].";
+	mes "[" + mesitemlink( .@item_id[.@s], false, .@item_name$[.@s] ) + "].";
 	mes "Click the name for the detailed description.";
 	mes "Click the name for the detailed description.";
 	mes "As I told you, it's ^0000CD3,000,000 Zeny^000000. Do you want to buy it?";
 	mes "As I told you, it's ^0000CD3,000,000 Zeny^000000. Do you want to buy it?";
 	next;
 	next;
@@ -371,7 +371,7 @@ har_in01,34,81,5	script	Howard#rr	4_M_TATIO,{
 	.@s = ( select(.@menu$) - 1 ) * 3;
 	.@s = ( select(.@menu$) - 1 ) * 3;
 
 
 	mes "[Howard]";
 	mes "[Howard]";
-	mes "<ITEM>" + .@data$[.@s+2] + "<INFO>" + .@data$[.@s+1] + "</INFO></ITEM>, got it.";
+	mes mesitemlink( atoi( .@data$[.@s+1] ), false, .@data$[.@s+2] ) + ", got it.";
 	mes "That'll be " + .@data$[.@s] + " Rock Ridge Coins.";
 	mes "That'll be " + .@data$[.@s] + " Rock Ridge Coins.";
 	mes "Are you certain you want this item?";
 	mes "Are you certain you want this item?";
 	next;
 	next;

+ 3 - 3
npc/re/merchants/ghost_palace_exchange.txt

@@ -13,7 +13,7 @@ dali02,51,130,4	script	Dimension Traveler	4_F_SHABBY,{
 	}
 	}
 	.@item_name_req$ = getitemname(6672);// Gray_Shard
 	.@item_name_req$ = getitemname(6672);// Gray_Shard
 	mes "[Dimension Traveler]";
 	mes "[Dimension Traveler]";
-	mes "Adventurer friend, <ITEM>[" + .@item_name_req$ + "]<INFO>6672</INFO></ITEM> is what I need. How about exchanging it with something I have?";
+	mes "Adventurer friend, " + mesitemlink( 6672 ) + " is what I need. How about exchanging it with something I have?";
 	next;
 	next;
 	.@type = select( "Show me your weapon.", "Show me your armor.", "Anything special?", "I do not need." ) - 1;
 	.@type = select( "Show me your weapon.", "Show me your armor.", "Anything special?", "I do not need." ) - 1;
 	mes "[Dimension Traveler]";
 	mes "[Dimension Traveler]";
@@ -33,7 +33,7 @@ dali02,51,130,4	script	Dimension Traveler	4_F_SHABBY,{
 	}
 	}
 	next;
 	next;
 	mes "[Dimension Traveler]";
 	mes "[Dimension Traveler]";
-	mes "Ah! The number that is written beside <ITEM>[" + .@item_name_req$ + "]<INFO>6672</INFO></ITEM> will be needed.";
+	mes "Ah! The number that is written beside " + mesitemlink( 6672 ) + " will be needed.";
 	mes "Please keep that in mind.";
 	mes "Please keep that in mind.";
 
 
 	switch(.@type) {
 	switch(.@type) {
@@ -80,7 +80,7 @@ dali02,51,130,4	script	Dimension Traveler	4_F_SHABBY,{
 		.@s = (select(.@menu$) - 1) * 2;
 		.@s = (select(.@menu$) - 1) * 2;
 		mes "[Dimension Traveler]";
 		mes "[Dimension Traveler]";
 		if (.@type != 1)	// armor type doesn't display item info
 		if (.@type != 1)	// armor type doesn't display item info
-			mes "Do you mean <ITEM>[" + getitemname(.@items[.@s]) + "]<INFO>" + .@items[.@s] + "</INFO></ITEM>?";
+			mes "Do you mean " + mesitemlink( .@items[.@s] ) + "?";
 		mes "" + .@items[.@s+1] + " ^006400" + .@item_name_req$ + "^000000 are required in exchange.";
 		mes "" + .@items[.@s+1] + " ^006400" + .@item_name_req$ + "^000000 are required in exchange.";
 		next;
 		next;
 		switch( select( "Let's exchange.", "Let me see other stuff.", "I will come back later." ) ) {
 		switch( select( "Let's exchange.", "Let me see other stuff.", "I will come back later." ) ) {

+ 8 - 8
npc/re/merchants/new_insurance.txt

@@ -22,32 +22,32 @@ prontera,82,108,5	script	Heart Merchant#life01	4_M_NFDEADMAN2,5,5,{
 	next;
 	next;
 	if(!countitem(.@old_item)){
 	if(!countitem(.@old_item)){
 		mes "[Heart Merchant]";
 		mes "[Heart Merchant]";
-		mes "Do you have any <ITEM>["+.@old_item_name$+"]<INFO>" + .@old_item + "</INFO></ITEM> in your storage?";
+		mes "Do you have any " + mesitemlink( .@old_item ) + " in your storage?";
 		next;
 		next;
 		mes "[Heart Merchant]";
 		mes "[Heart Merchant]";
-		mes "If you bring me a " + .@old_item_name$ + ", I'll exchange it to <ITEM>["+.@new_item_name$+"]<INFO>" + .@new_item + "</INFO></ITEM>. What do you think? Do you have any idea what this item is?";
+		mes "If you bring me a " + .@old_item_name$ + ", I'll exchange it to " + mesitemlink( .@new_item ) + ". What do you think? Do you have any idea what this item is?";
 	} else {
 	} else {
 		mes "[Heart Merchant]";
 		mes "[Heart Merchant]";
-		mes "Have you ever thought about replacing your <ITEM>["+.@old_item_name$+"]<INFO>" + .@old_item + "</INFO></ITEM> to something better? For example... <ITEM>["+.@new_item_name$+"]<INFO>" + .@new_item + "</INFO></ITEM>. What do you think?";
+		mes "Have you ever thought about replacing your " + mesitemlink( .@old_item ) + " to something better? For example... " + mesitemlink( .@new_item ) + ". What do you think?";
 	}
 	}
 	next;
 	next;
 	switch(select("What is it?",(countitem(.@old_item)?"Exchange it please!":""),"I'm not interested")) {
 	switch(select("What is it?",(countitem(.@old_item)?"Exchange it please!":""),"I'm not interested")) {
 	case 1:
 	case 1:
 		mes "[Heart Merchant]";
 		mes "[Heart Merchant]";
-		mes "<ITEM>["+.@old_item_name$+"]<INFO>" + .@old_item + "</INFO></ITEM> is an item that prevents you from losing experience on death once within the 30 minutes duration after use.";
+		mes mesitemlink( .@old_item ) + " is an item that prevents you from losing experience on death once within the 30 minutes duration after use.";
 		next;
 		next;
 		mes "[Heart Merchant]";
 		mes "[Heart Merchant]";
-		mes "But a lot of people are sad about the time limit, right? So I looked into it and prepared the <ITEM>["+.@new_item_name$+"]<INFO>" + .@new_item + "</INFO></ITEM>.";
+		mes "But a lot of people are sad about the time limit, right? So I looked into it and prepared the " + mesitemlink( .@new_item ) + ".";
 		next;
 		next;
 		mes "[Heart Merchant]";
 		mes "[Heart Merchant]";
-		mes "<ITEM>["+.@new_item_name$+"]<INFO>" + .@new_item + "</INFO></ITEM> is an item that will prevent the loss of experience on death once by just having it ^EE0000regardless of the duration^000000. Of course, after death, the "+.@new_item_name$+" is consumed.";
+		mes mesitemlink( .@new_item ) + " is an item that will prevent the loss of experience on death once by just having it ^EE0000regardless of the duration^000000. Of course, after death, the "+.@new_item_name$+" is consumed.";
 		next;
 		next;
 		select("Why are you exchanging it?");
 		select("Why are you exchanging it?");
 		mes "[Heart Merchant]";
 		mes "[Heart Merchant]";
 		mes "Are you curious about that? I'm a merchant. Buying and selling things is my fate, whether it's related to one's life or death. Do you think I'm going to miss this opportunity to make money? I make money, and the living get a leeway from the pain of death. Isn't that a good deal?";
 		mes "Are you curious about that? I'm a merchant. Buying and selling things is my fate, whether it's related to one's life or death. Do you think I'm going to miss this opportunity to make money? I make money, and the living get a leeway from the pain of death. Isn't that a good deal?";
 		next;
 		next;
 		mes "[Heart Merchant]";
 		mes "[Heart Merchant]";
-		mes "The exchange rate is 5 <ITEM>["+.@old_item_name$+"]<INFO>" + .@old_item + "</INFO></ITEM> for 1 <ITEM>["+.@new_item_name$+"]<INFO>" + .@new_item + "</INFO></ITEM>. Do you have any questions?";
+		mes "The exchange rate is 5 " + mesitemlink( .@old_item ) + " for 1 " + mesitemlink( .@new_item ) + ". Do you have any questions?";
 		next;
 		next;
 		mes "[Heart Merchant]";
 		mes "[Heart Merchant]";
 		mes "Hm~ What do you think? Isn't it a fair trade? Do you want to always worry about time? It's a must-have for adventurers who enjoy breathtaking adventures.";
 		mes "Hm~ What do you think? Isn't it a fair trade? Do you want to always worry about time? It's a must-have for adventurers who enjoy breathtaking adventures.";
@@ -84,7 +84,7 @@ prontera,82,108,5	script	Heart Merchant#life01	4_M_NFDEADMAN2,5,5,{
 		}
 		}
 		if (countitem(.@old_item) < (.@amount*5)) {
 		if (countitem(.@old_item) < (.@amount*5)) {
 			mes "[Heart Merchant]";
 			mes "[Heart Merchant]";
-			mes "Um, excuse me but... you don't have enough " +.@old_item_name$+ ", no? It's 5 <ITEM>["+.@old_item_name$+"]<INFO>" + .@old_item + "</INFO></ITEM> for 1 <ITEM>["+.@new_item_name$+"]<INFO>" + .@new_item + "</INFO></ITEM>. Please check the quantity.";
+			mes "Um, excuse me but... you don't have enough " +.@old_item_name$+ ", no? It's 5 " + mesitemlink( .@old_item ) + " for 1 " + mesitemlink( .@new_item ) + ". Please check the quantity.";
 			close;
 			close;
 		}
 		}
 		mes "[Heart Merchant]";
 		mes "[Heart Merchant]";

+ 1 - 1
npc/re/merchants/refine.txt

@@ -686,7 +686,7 @@ lhz_in02,281,24,5	duplicate(Dietrich#ns_prt)	Fruel#2	4_M_02
 // Shadowdecon/Zelunium exchange npcs
 // Shadowdecon/Zelunium exchange npcs
 prt_in,64,57,3	script	Pauline	4_M_02,{
 prt_in,64,57,3	script	Pauline	4_M_02,{
 	mes "[" + strnpcinfo(1) + "]";
 	mes "[" + strnpcinfo(1) + "]";
-	mes "Do you have <ITEM>[Shadowdecon Gemstone]<INFO>25728</INFO></ITEM> or <ITEM>[Zelunium Gemstone]<INFO>25730</INFO></ITEM>?";
+	mes "Do you have " + mesitemlink( 25728 ) + " or " + mesitemlink( 25730 ) + "?";
 	mes "We will exchange them for refined products for use as smelting goods.";
 	mes "We will exchange them for refined products for use as smelting goods.";
 	close2;
 	close2;
 	callshop "barter_refine_3";
 	callshop "barter_refine_3";

+ 14 - 14
npc/re/quests/juno_monster_society.txt

@@ -736,7 +736,7 @@ ein_fild06,257,351,4	script	Map Examiner Bast#yma	4_F_CHNDRESS1,{
 			close;
 			close;
 		case 2:
 		case 2:
 			mes .@npc_name$;
 			mes .@npc_name$;
-			mes "Can I move it to Einbroch? Give me one <ITEM>[" + .@item_name$ + "]<INFO>1000374</INFO></ITEM> and I can teleport you.";
+			mes "Can I move it to Einbroch? Give me one " + mesitemlink( 1000374 ) + " and I can teleport you.";
 			next;
 			next;
 			select( "Give me 1 " + .@item_name$ + "." );
 			select( "Give me 1 " + .@item_name$ + "." );
 			if (countitem(1000374) < 1) {
 			if (countitem(1000374) < 1) {
@@ -787,7 +787,7 @@ ein_fild06,257,351,4	script	Map Examiner Bast#yma	4_F_CHNDRESS1,{
 			close;
 			close;
 		case 3:
 		case 3:
 			mes .@npc_name$;
 			mes .@npc_name$;
-			mes "Can I move it to Einbroch? Give me one <ITEM>[" + .@item_name$ + "]<INFO>1000374</INFO></ITEM> and I can teleport you.";
+			mes "Can I move it to Einbroch? Give me one " + mesitemlink( 1000374 ) + " and I can teleport you.";
 			next;
 			next;
 			select( "Give me 1 " + .@item_name$ + "." );
 			select( "Give me 1 " + .@item_name$ + "." );
 			if (countitem(1000374) < 1) {
 			if (countitem(1000374) < 1) {
@@ -872,7 +872,7 @@ gef_fild06,209,31,6	script	Map Examiner Gefil#yma	4_M_MIDDLE,{
 			close;
 			close;
 		case 2:
 		case 2:
 			mes .@npc_name$;
 			mes .@npc_name$;
-			mes "Give me 1 <ITEM>[" + .@item_name$ + "]<INFO>1000374</INFO></ITEM> and I can teleport you to Geffen.";
+			mes "Give me 1 " + mesitemlink( 1000374 ) + " and I can teleport you to Geffen.";
 			next;
 			next;
 			select( "Give me 1 " + .@item_name$ + "." );
 			select( "Give me 1 " + .@item_name$ + "." );
 			if (countitem(1000374) < 1) {
 			if (countitem(1000374) < 1) {
@@ -916,7 +916,7 @@ gef_fild06,209,31,6	script	Map Examiner Gefil#yma	4_M_MIDDLE,{
 			close;
 			close;
 		case 3:
 		case 3:
 			mes .@npc_name$;
 			mes .@npc_name$;
-			mes "Give me 1 <ITEM>[" + .@item_name$ + "]<INFO>1000374</INFO></ITEM> and I can teleport you to Geffen.";
+			mes "Give me 1 " + mesitemlink( 1000374 ) + " and I can teleport you to Geffen.";
 			next;
 			next;
 			select( "Give me 1 " + .@item_name$ + "." );
 			select( "Give me 1 " + .@item_name$ + "." );
 			if (countitem(1000374) < 1) {
 			if (countitem(1000374) < 1) {
@@ -1001,7 +1001,7 @@ lhz_fild01,240,107,4	script	Map Examiner Lipiri#yma	4_M_HUBOY,{
 			close;
 			close;
 		case 2:
 		case 2:
 			mes .@npc_name$;
 			mes .@npc_name$;
-			mes "If it's a nearby city, it's Lighthalzen. Give me one <ITEM>[" + .@item_name$ + "]<INFO>1000374</INFO></ITEM> and I can teleport you.";
+			mes "If it's a nearby city, it's Lighthalzen. Give me one " + mesitemlink( 1000374 ) + " and I can teleport you.";
 			next;
 			next;
 			select( "Give me 1 " + .@item_name$ + "." );
 			select( "Give me 1 " + .@item_name$ + "." );
 			if (countitem(1000374) < 1) {
 			if (countitem(1000374) < 1) {
@@ -1052,7 +1052,7 @@ lhz_fild01,240,107,4	script	Map Examiner Lipiri#yma	4_M_HUBOY,{
 			close;
 			close;
 		case 3:
 		case 3:
 			mes .@npc_name$;
 			mes .@npc_name$;
-			mes "If it's a nearby city, it's Lighthalzen. Give me one <ITEM>[" + .@item_name$ + "]<INFO>1000374</INFO></ITEM> and I can teleport you.";
+			mes "If it's a nearby city, it's Lighthalzen. Give me one " + mesitemlink( 1000374 ) + " and I can teleport you.";
 			next;
 			next;
 			select( "Give me 1 " + .@item_name$ + "." );
 			select( "Give me 1 " + .@item_name$ + "." );
 			if (countitem(1000374) < 1) {
 			if (countitem(1000374) < 1) {
@@ -1276,7 +1276,7 @@ hu_fild01,133,157,6	script	Map Examiner Huf#yma	4_MAL_CAPTAIN,{
 			close;
 			close;
 		case 2:
 		case 2:
 			mes .@npc_name$;
 			mes .@npc_name$;
-			mes "Are you going home? Hugel is the nearest city. I need 1 piece of <ITEM>[" + .@item_name$ + "]<INFO>1000374</INFO></ITEM>.";
+			mes "Are you going home? Hugel is the nearest city. I need 1 piece of " + mesitemlink( 1000374 ) + ".";
 			next;
 			next;
 			select( "Give me 1 " + .@item_name$ + "." );
 			select( "Give me 1 " + .@item_name$ + "." );
 			if (countitem(1000374) < 1) {
 			if (countitem(1000374) < 1) {
@@ -1321,7 +1321,7 @@ hu_fild01,133,157,6	script	Map Examiner Huf#yma	4_MAL_CAPTAIN,{
 			close;
 			close;
 		case 3:
 		case 3:
 			mes .@npc_name$;
 			mes .@npc_name$;
-			mes "Are you going home? Hugel is the nearest city. I need 1 piece of <ITEM>[" + .@item_name$ + "]<INFO>1000374</INFO></ITEM>.";
+			mes "Are you going home? Hugel is the nearest city. I need 1 piece of " + mesitemlink( 1000374 ) + ".";
 			next;
 			next;
 			select( "Give me 1 " + .@item_name$ + "." );
 			select( "Give me 1 " + .@item_name$ + "." );
 			if (countitem(1000374) < 1) {
 			if (countitem(1000374) < 1) {
@@ -1411,7 +1411,7 @@ tur_dun01,159,46,4	script	Map Examiner Tural#yma	4_M_BRZ_MAN1,{
 			close;
 			close;
 		case 2:
 		case 2:
 			mes .@npc_name$;
 			mes .@npc_name$;
-			mes "Give me one <ITEM>[" + .@item_name$ + "]<INFO>1000374</INFO></ITEM> and I can teleport you to Alberta.";
+			mes "Give me one " + mesitemlink( 1000374 ) + " and I can teleport you to Alberta.";
 			next;
 			next;
 			select( "Give me 1 " + .@item_name$ + "." );
 			select( "Give me 1 " + .@item_name$ + "." );
 			if (countitem(1000374) < 1) {
 			if (countitem(1000374) < 1) {
@@ -1452,7 +1452,7 @@ tur_dun01,159,46,4	script	Map Examiner Tural#yma	4_M_BRZ_MAN1,{
 			close;
 			close;
 		case 3:
 		case 3:
 			mes .@npc_name$;
 			mes .@npc_name$;
-			mes "Give me one <ITEM>[" + .@item_name$ + "]<INFO>1000374</INFO></ITEM> and I can teleport you to Alberta.";
+			mes "Give me one " + mesitemlink( 1000374 ) + " and I can teleport you to Alberta.";
 			next;
 			next;
 			select( "Give me 1 " + .@item_name$ + "." );
 			select( "Give me 1 " + .@item_name$ + "." );
 			if (countitem(1000374) < 1) {
 			if (countitem(1000374) < 1) {
@@ -1818,7 +1818,7 @@ tur_dun02,151,256,4	script	Map Examiner Tidun#yma	4_M_NINJA_BLUE,{
 			close;
 			close;
 		case 2:
 		case 2:
 			mes .@npc_name$;
 			mes .@npc_name$;
-			mes "If you give me one <ITEM>[" + .@item_name$ + "]<INFO>1000374</INFO></ITEM>, I can teleport you to the nearby city, Alberta.";
+			mes "If you give me one " + mesitemlink( 1000374 ) + ", I can teleport you to the nearby city, Alberta.";
 			next;
 			next;
 			select( "Give me 1 " + .@item_name$ + "." );
 			select( "Give me 1 " + .@item_name$ + "." );
 			if (countitem(1000374) < 1) {
 			if (countitem(1000374) < 1) {
@@ -1863,7 +1863,7 @@ tur_dun02,151,256,4	script	Map Examiner Tidun#yma	4_M_NINJA_BLUE,{
 			close;
 			close;
 		case 3:
 		case 3:
 			mes .@npc_name$;
 			mes .@npc_name$;
-			mes "If you give me one <ITEM>[" + .@item_name$ + "]<INFO>1000374</INFO></ITEM>, I can teleport you to the nearby city, Alberta.";
+			mes "If you give me one " + mesitemlink( 1000374 ) + ", I can teleport you to the nearby city, Alberta.";
 			next;
 			next;
 			select( "Give me 1 " + .@item_name$ + "." );
 			select( "Give me 1 " + .@item_name$ + "." );
 			if (countitem(1000374) < 1) {
 			if (countitem(1000374) < 1) {
@@ -1947,7 +1947,7 @@ tur_dun03,125,186,6	script	Map Examiner Tsensor#yma	4_M_SIT_NOVICE,{
 			close;
 			close;
 		case 2:
 		case 2:
 			mes .@npc_name$;
 			mes .@npc_name$;
-			mes "Alberta Express 1 <ITEM>[" + .@item_name$ + "]<INFO>1000374</INFO></ITEM>, left immediately.";
+			mes "Alberta Express 1 " + mesitemlink( 1000374 ) + ", left immediately.";
 			next;
 			next;
 			select( "Give me 1 " + .@item_name$ + "." );
 			select( "Give me 1 " + .@item_name$ + "." );
 			if (countitem(1000374) < 1) {
 			if (countitem(1000374) < 1) {
@@ -1992,7 +1992,7 @@ tur_dun03,125,186,6	script	Map Examiner Tsensor#yma	4_M_SIT_NOVICE,{
 			close;
 			close;
 		case 3:
 		case 3:
 			mes .@npc_name$;
 			mes .@npc_name$;
-			mes "Alberta Express 1 <ITEM>[" + .@item_name$ + "]<INFO>1000374</INFO></ITEM>, left immediately.";
+			mes "Alberta Express 1 " + mesitemlink( 1000374 ) + ", left immediately.";
 			next;
 			next;
 			select( "Give me 1 " + .@item_name$ + "." );
 			select( "Give me 1 " + .@item_name$ + "." );
 			if (countitem(1000374) < 1) {
 			if (countitem(1000374) < 1) {

+ 1 - 1
npc/re/quests/quests_16_1.txt

@@ -14258,7 +14258,7 @@ prt_cas,270,168,3	duplicate(Royal Guardian Knight#02)	Royal Guardian Knight#03	4
 prt_cas,165,260,6	script	Noblesse Operator#ext161	4_F_CRU,{
 prt_cas,165,260,6	script	Noblesse Operator#ext161	4_F_CRU,{
 	mes "[Noblesse Operator]";
 	mes "[Noblesse Operator]";
 	mes "Hello.";
 	mes "Hello.";
-	mes "We have ^4d4dffNoblesse^000000 equipment that can be exchanged for <ITEM>[Honor Token]<INFO>6919</INFO></ITEM>.";
+	mes "We have ^4d4dffNoblesse^000000 equipment that can be exchanged for " + mesitemlink( 6919 ) + ".";
 	mes "I will guide you to exchange items according to your job.";
 	mes "I will guide you to exchange items according to your job.";
 	close2;
 	close2;
 	switch( eaclass() & EAJ_THIRDMASK ) {
 	switch( eaclass() & EAJ_THIRDMASK ) {

+ 3 - 3
npc/re/quests/quests_16_2.txt

@@ -11387,7 +11387,7 @@ rebel_in,100,40,4	script	Butterfly Merchant#rebel_in	4_M_ORIENT02,{
 rebel_in,99,51,3	script	Imperial Operator#ext162	4_M_REPAIR,{
 rebel_in,99,51,3	script	Imperial Operator#ext162	4_M_REPAIR,{
 	mes "[Imperial Operator]";
 	mes "[Imperial Operator]";
 	mes "Hello.";
 	mes "Hello.";
-	mes "We have ^4d4dffImperial^000000 equipment that can be exchanged for <ITEM>[" + getitemname(6919) + "]<INFO>6919</INFO></ITEM>.";
+	mes "We have ^4d4dffImperial^000000 equipment that can be exchanged for " + mesitemlink( 6919, false ) + ".";
 	mes "I will guide you to exchange items according to your job.";
 	mes "I will guide you to exchange items according to your job.";
 	close2;
 	close2;
 	switch( eaclass() & EAJ_THIRDMASK ) {
 	switch( eaclass() & EAJ_THIRDMASK ) {
@@ -11519,7 +11519,7 @@ rebel_in,74,67,5	script	Strasse#rebel_in	4_M_TATIO,{
 
 
 	.@s = (select( "Agenda Robe", "Consultation Robe", "Costume Combat Vestige", "Hat of Republic", "Mercenary Ring A type", "Mercenary Ring B type" ) - 1) * 2;
 	.@s = (select( "Agenda Robe", "Consultation Robe", "Costume Combat Vestige", "Hat of Republic", "Mercenary Ring A type", "Mercenary Ring B type" ) - 1) * 2;
 	mes "[Strasse]";
 	mes "[Strasse]";
-	mes "<ITEM>" + getitemname(.@item[.@s]) + "<INFO>" + .@item[.@s] + "</INFO></ITEM>? I got it.";
+	mes mesitemlink( .@item[.@s], false ) + "? I got it.";
 	mes "You need " + .@item[.@s+1] + " Schwartz Honor Tokens.";
 	mes "You need " + .@item[.@s+1] + " Schwartz Honor Tokens.";
 	mes "Are you sure you want this?";
 	mes "Are you sure you want this?";
 	next;
 	next;
@@ -11536,7 +11536,7 @@ rebel_in,74,67,5	script	Strasse#rebel_in	4_M_TATIO,{
 	}
 	}
 	// custom text
 	// custom text
 	mes "[Strasse]";
 	mes "[Strasse]";
-	mes "Here is your <ITEM>" + getitemname(.@item[.@s]) + "<INFO>" + .@item[.@s] + "</INFO></ITEM>.";
+	mes "Here is your " + mesitemlink( .@item[.@s], false ) + ".";
 	delitem 25155, .@item[.@s+1];
 	delitem 25155, .@item[.@s+1];
 	getitem .@item[.@s],1;
 	getitem .@item[.@s],1;
 	close;
 	close;

+ 10 - 10
npc/re/quests/quests_rockridge.txt

@@ -781,15 +781,15 @@ har_in01,20,30,5	script	Wyatt Warp#har_in01	4_M_YATTWARP,{
 		next;
 		next;
 		mes "[Wyatt Warp]";
 		mes "[Wyatt Warp]";
 		mes "Both badges are worn by us Vigilantes, but they provide different effects.";
 		mes "Both badges are worn by us Vigilantes, but they provide different effects.";
-		mes "I have <ITEM>Vigilante Badge (L)<INFO>28495</INFO></ITEM>";
-		mes "and <ITEM>Vigilante Badge (R)<INFO>28496</INFO></ITEM>.";
+		mes "I have " + mesitemlink( 28495, false, "Vigilante Badge (L)" );
+		mes "and " + mesitemlink( 28496, false, "Vigilante Badge (R)" ) + ".";
 		mes "Pick one you like.";
 		mes "Pick one you like.";
 		next;
 		next;
 		setarray .@item_name$[0], "Vigilante Badge (L)", "Vigilante Badge (R)";
 		setarray .@item_name$[0], "Vigilante Badge (L)", "Vigilante Badge (R)";
 		setarray .@item_id[0], 28495, 28496;
 		setarray .@item_id[0], 28495, 28496;
 		.@s = select( "Vigilante Badge (L)", "Vigilante Badge (R)" ) - 1;
 		.@s = select( "Vigilante Badge (L)", "Vigilante Badge (R)" ) - 1;
 		mes "[Wyatt Warp]";
 		mes "[Wyatt Warp]";
-		mes "Do you want <ITEM>" + .@item_name$[.@s] + "<INFO>" + .@item_id[.@s] + "</INFO></ITEM>?";
+		mes "Do you want " + mesitemlink( .@item_id[.@s], false, .@item_name$[.@s] ) + "?";
 		mes "Excellent choice!";
 		mes "Excellent choice!";
 		mes "Are you certain you want this?";
 		mes "Are you certain you want this?";
 		next;
 		next;
@@ -3345,7 +3345,7 @@ harboro1,357,163,3	script	Food Distributer	4_COOK,{
 		mes "Sweet potato croquettes are on the menu today, and I can't make them because I didn't get the regular shipment from the mainland.";
 		mes "Sweet potato croquettes are on the menu today, and I can't make them because I didn't get the regular shipment from the mainland.";
 		next;
 		next;
 		mes "[Food Distributer]";
 		mes "[Food Distributer]";
-		mes "Bring me 160 <ITEM>Sweet Potatoes<INFO>516</INFO></ITEM> from Midgard. You can buy them from merchants in big cities.";
+		mes "Bring me 160 " + mesitemlink( 516, false, "Sweet Potatoes" ) + " from Midgard. You can buy them from merchants in big cities.";
 		close;
 		close;
 	case 12384:
 	case 12384:
 		setquest 12384;// Meat Delivery
 		setquest 12384;// Meat Delivery
@@ -3356,7 +3356,7 @@ harboro1,357,163,3	script	Food Distributer	4_COOK,{
 		mes "What? I could always feed them veggies, you say? Sure, but all they want is meat.";
 		mes "What? I could always feed them veggies, you say? Sure, but all they want is meat.";
 		next;
 		next;
 		mes "[Food Distributer]";
 		mes "[Food Distributer]";
-		mes "Bring me 50 <ITEM>Meats<INFO>517</INFO></ITEM> from Midgard. You can buy them from merchants in big cities.";
+		mes "Bring me 50 " + mesitemlink( 517, false, "Meats" ) + " from Midgard. You can buy them from merchants in big cities.";
 		close;
 		close;
 	case 12385:
 	case 12385:
 		setquest 12385;// Carrot Delivery
 		setquest 12385;// Carrot Delivery
@@ -3367,7 +3367,7 @@ harboro1,357,163,3	script	Food Distributer	4_COOK,{
 		mes "They're as thin as fingers, and once I almost put my fingers into a stew instead of them.";
 		mes "They're as thin as fingers, and once I almost put my fingers into a stew instead of them.";
 		next;
 		next;
 		mes "[Food Distributer]";
 		mes "[Food Distributer]";
-		mes "Bring me 160 <ITEM>Carrots<INFO>515</INFO></ITEM> from Midgard. You can buy them from merchants in big cities.";
+		mes "Bring me 160 " + mesitemlink( 515, false, "Carrots" ) + " from Midgard. You can buy them from merchants in big cities.";
 		close;
 		close;
 	case 12386:
 	case 12386:
 		setquest 12386;// Banana Delivery
 		setquest 12386;// Banana Delivery
@@ -3375,7 +3375,7 @@ harboro1,357,163,3	script	Food Distributer	4_COOK,{
 		mes "I shouldn't have put that banana bread on the menu. Who knew they wouldn't arrive in time?";
 		mes "I shouldn't have put that banana bread on the menu. Who knew they wouldn't arrive in time?";
 		next;
 		next;
 		mes "[Food Distributer]";
 		mes "[Food Distributer]";
-		mes "Bring me 160 <ITEM>Bananas<INFO>513</INFO></ITEM> from Midgard. You can buy them from merchants in big cities.";
+		mes "Bring me 160 " + mesitemlink( 513, false, "Bananas" ) + " from Midgard. You can buy them from merchants in big cities.";
 		close;
 		close;
 	case 12387:
 	case 12387:
 		setquest 12387;// Pumpkin Delivery
 		setquest 12387;// Pumpkin Delivery
@@ -3383,7 +3383,7 @@ harboro1,357,163,3	script	Food Distributer	4_COOK,{
 		mes "I have to cook a pumpkin stew, but I don't have pumpkins. This is the equivalent of making toast without bread.";
 		mes "I have to cook a pumpkin stew, but I don't have pumpkins. This is the equivalent of making toast without bread.";
 		next;
 		next;
 		mes "[Food Distributer]";
 		mes "[Food Distributer]";
-		mes "Bring me 160 <ITEM>Pumpkins<INFO>535</INFO></ITEM> from Midgard. You can buy them from merchants in big cities.";
+		mes "Bring me 160 " + mesitemlink( 535, false, "Pumpkins" ) + " from Midgard. You can buy them from merchants in big cities.";
 		close;
 		close;
 	case 12388:
 	case 12388:
 		setquest 12388;// Mushroom Delivery
 		setquest 12388;// Mushroom Delivery
@@ -3391,7 +3391,7 @@ harboro1,357,163,3	script	Food Distributer	4_COOK,{
 		mes "The only thing I can cook with the ingredients I have is mushroom soup, but I don't have the main ingredient: mushrooms.";
 		mes "The only thing I can cook with the ingredients I have is mushroom soup, but I don't have the main ingredient: mushrooms.";
 		next;
 		next;
 		mes "[Food Distributer]";
 		mes "[Food Distributer]";
-		mes "Bring me 60 <ITEM>Mushrooms<INFO>581</INFO></ITEM> from Midgard. You can buy them from merchants in big cities.";
+		mes "Bring me 60 " + mesitemlink( 581, false, "Mushrooms" ) + " from Midgard. You can buy them from merchants in big cities.";
 		close;
 		close;
 	}
 	}
 	end;
 	end;
@@ -3401,7 +3401,7 @@ S_Food:
 	.@amount = getarg(2);
 	.@amount = getarg(2);
 	if (countitem(.@item_id) < .@amount) {
 	if (countitem(.@item_id) < .@amount) {
 		mes "[Food Distributer]";
 		mes "[Food Distributer]";
-		mes "Bring me " + .@amount + " <ITEM>" + getitemname(.@item_id) + "<INFO>" + .@item_id + "</INFO></ITEM> from Midgard. You can buy them from merchants in big cities.";
+		mes "Bring me " + .@amount + " " + mesitemlink( .@item_id, false ) + " from Midgard. You can buy them from merchants in big cities.";
 		close;
 		close;
 	}
 	}
 	delitem .@item_id, .@amount;
 	delitem .@item_id, .@amount;

+ 22 - 11
npc/test/ci/7291.txt

@@ -1,14 +1,18 @@
 -	script	itemlink#ci	-1,{
 -	script	itemlink#ci	-1,{
 OnInit:
 OnInit:
 	if( checkre(0) ){
 	if( checkre(0) ){
-		if( PACKETVER >= 20200916 ){
+		if( PACKETVER >= 20200724 ){
+			// Change of separators and add grade
 			.@expected$ = "<ITEML>0000213v0%0g&00'00)18X)1ck)00)00+2R,00-00</ITEML>";
 			.@expected$ = "<ITEML>0000213v0%0g&00'00)18X)1ck)00)00+2R,00-00</ITEML>";
-		}else if( PACKETVER >= 20150225 ){
-			// Grade does not exist (clientside) yet
-			.@expected$ = "<ITEMLINK>0000213v0%0g&00(18X(1ck(00(00*2R+00,00</ITEMLINK>";
-		}else if( PACKETVER >= 20100000 ){
-			// Random Options do not exist (clientside) yet
-			.@expected$ = "<ITEMLINK>0000213v0%0g&00(18X(1ck(00(00</ITEMLINK>";
+		}else if( PACKETVER >= 20161116 ){
+			// Change of separators and add equip preview
+			.@expected$ = "<ITEML>0000213v0%0g&00(18X(1ck(00(00*2R+00,00</ITEML>";
+		}else if( PACKETVER >= 20160113 ){
+			// Change from <ITEM> to <ITEML>
+			.@expected$ = "<ITEML>0000213v0%0g'18X'1ck'00'00)2R*00+00</ITEML>";
+		}else if( PACKETVER >= 20151104 ){
+			// Initial version
+			.@expected$ = "<ITEM>0000213v0%0g'18X'1ck'00'00)2R*00+00</ITEM>";
 		}else{
 		}else{
 			// Item Link does not exist (clientside) yet
 			// Item Link does not exist (clientside) yet
 			.@expected$ = "Crimson Saber";
 			.@expected$ = "Crimson Saber";
@@ -18,11 +22,18 @@ OnInit:
 		.@actual$ = itemlink(13454,16,4399,4608,0,0,0,.@opt_ids,.@opt_dummy,.@opt_dummy);
 		.@actual$ = itemlink(13454,16,4399,4608,0,0,0,.@opt_ids,.@opt_dummy,.@opt_dummy);
 		AssertEquals(.@expected$, .@actual$, "Generated itemlink for +16 Earth Crimson Saber");
 		AssertEquals(.@expected$, .@actual$, "Generated itemlink for +16 Earth Crimson Saber");
 	}else{
 	}else{
-		if( PACKETVER >= 20200916 ){
+		if( PACKETVER >= 20200724 ){
+			// Change of separators and add grade (not used in pre-renewal)
 			.@expected$ = "<ITEML>000021hS%0a&00'00)18X)00)00)00</ITEML>";
 			.@expected$ = "<ITEML>000021hS%0a&00'00)18X)00)00)00</ITEML>";
-		}else if( PACKETVER >= 20100000 ){
-			// Grade does not exist (clientside) yet// Grade does not exist (clientside) yet
-			.@expected$ = "<ITEMLINK>000021hS%0a&00(18X(00(00(00</ITEMLINK>";
+		}else if( PACKETVER >= 20161116 ){
+			// Change of separators and add equip preview
+			.@expected$ = "<ITEML>000021hS%0a&00(18X(00(00(00</ITEML>";
+		}else if( PACKETVER >= 20160113 ){
+			// Change from <ITEM> to <ITEML>
+			.@expected$ = "<ITEML>000021hS%0a'18X'00'00'00</ITEML>";
+		}else if( PACKETVER >= 20151104 ){
+			// Initial version
+			.@expected$ = "<ITEM>000021hS%0a'18X'00'00'00</ITEM>";
 		}else{
 		}else{
 			// Item Link does not exist (clientside) yet
 			// Item Link does not exist (clientside) yet
 			.@expected$ = "Blade";
 			.@expected$ = "Blade";

+ 23 - 0
src/map/battle.cpp

@@ -10277,6 +10277,9 @@ static const struct _battle_data {
 	{ "feature.barter",                     &battle_config.feature_barter,                  1,      0,      1,              },
 	{ "feature.barter",                     &battle_config.feature_barter,                  1,      0,      1,              },
 	{ "feature.barter_extended",            &battle_config.feature_barter_extended,         1,      0,      1,              },
 	{ "feature.barter_extended",            &battle_config.feature_barter_extended,         1,      0,      1,              },
 	{ "feature.itemlink",                   &battle_config.feature_itemlink,                1,      0,      1,              },
 	{ "feature.itemlink",                   &battle_config.feature_itemlink,                1,      0,      1,              },
+	{ "feature.mesitemlink",                &battle_config.feature_mesitemlink,             1,      0,      1,              },
+	{ "feature.mesitemlink_brackets",       &battle_config.feature_mesitemlink_brackets,    0,      0,      1,              },
+	{ "feature.mesitemlink_dbname",         &battle_config.feature_mesitemlink_dbname,      0,      0,      1,              },
 	{ "break_mob_equip",                    &battle_config.break_mob_equip,                 0,      0,      1,              },
 	{ "break_mob_equip",                    &battle_config.break_mob_equip,                 0,      0,      1,              },
 	{ "macro_detection_retry",              &battle_config.macro_detection_retry,           3,      1,      INT_MAX,        },
 	{ "macro_detection_retry",              &battle_config.macro_detection_retry,           3,      1,      INT_MAX,        },
 	{ "macro_detection_timeout",            &battle_config.macro_detection_timeout,         60000,  0,      INT_MAX,        },
 	{ "macro_detection_timeout",            &battle_config.macro_detection_timeout,         60000,  0,      INT_MAX,        },
@@ -10366,6 +10369,19 @@ void battle_adjust_conf()
 	if (battle_config.night_duration && battle_config.night_duration < 60000) // added by [Yor]
 	if (battle_config.night_duration && battle_config.night_duration < 60000) // added by [Yor]
 		battle_config.night_duration = 60000;
 		battle_config.night_duration = 60000;
 
 
+#if PACKETVER < 20100000
+	if( battle_config.feature_mesitemlink ){
+		ShowWarning( "conf/battle/feature.conf:mesitemlink is enabled but it requires PACKETVER 2010-01-01 or newer, disabling...\n" );
+		battle_config.feature_mesitemlink = 0;
+	}
+#elif PACKETVER == 20151029 || PACKETVER == 20151104
+	// The feature is broken on those two clients or maybe even more. For more details check ItemDatabase::create_item_link_for_mes [Lemongrass]
+	if( battle_config.feature_mesitemlink ){
+		ShowWarning( "conf/battle/feature.conf:mesitemlink is enabled but it is broken on this specific PACKETVER, disabling...\n" );
+		battle_config.feature_mesitemlink = 0;
+	}
+#endif
+
 #if PACKETVER < 20100427
 #if PACKETVER < 20100427
 	if (battle_config.feature_buying_store) {
 	if (battle_config.feature_buying_store) {
 		ShowWarning("conf/battle/feature.conf:buying_store is enabled but it requires PACKETVER 2010-04-27 or newer, disabling...\n");
 		ShowWarning("conf/battle/feature.conf:buying_store is enabled but it requires PACKETVER 2010-04-27 or newer, disabling...\n");
@@ -10429,6 +10445,13 @@ void battle_adjust_conf()
 	}
 	}
 #endif
 #endif
 
 
+#if PACKETVER < 20151104
+	if( battle_config.feature_itemlink ){
+		ShowWarning( "conf/battle/feature.conf:itemlink is enabled but it requires PACKETVER 2015-11-04 or newer, disabling...\n" );
+		battle_config.feature_itemlink = 0;
+	}
+#endif
+
 #if PACKETVER < 20151104
 #if PACKETVER < 20151104
 	if( battle_config.feature_stylist ){
 	if( battle_config.feature_stylist ){
 		ShowWarning("conf/battle/feature.conf stylist is enabled but it requires PACKETVER 2015-11-04 or newer, disabling...\n");
 		ShowWarning("conf/battle/feature.conf stylist is enabled but it requires PACKETVER 2015-11-04 or newer, disabling...\n");

+ 3 - 0
src/map/battle.hpp

@@ -564,6 +564,9 @@ struct Battle_Config
 	int update_enemy_position;
 	int update_enemy_position;
 	int devotion_rdamage;
 	int devotion_rdamage;
 	int feature_itemlink;
 	int feature_itemlink;
+	int feature_mesitemlink;
+	int feature_mesitemlink_brackets;
+	int feature_mesitemlink_dbname;
 
 
 	// autotrade persistency
 	// autotrade persistency
 	int feature_autotrade;
 	int feature_autotrade;

+ 60 - 0
src/map/itemdb.cpp

@@ -1357,6 +1357,66 @@ std::string ItemDatabase::create_item_link(struct item& item) {
 	return this->create_item_link(item, data);
 	return this->create_item_link(item, data);
 }
 }
 
 
+std::string ItemDatabase::create_item_link_for_mes( std::shared_ptr<item_data>& data, bool use_brackets, const char* name ){
+	if( data == nullptr ){
+		return "Unknown item";
+	}
+
+	std::string itemstr;
+
+// All these dates are unconfirmed
+#if PACKETVER >= 20100000
+	if( battle_config.feature_mesitemlink ){
+// It was changed in 2015-11-04, but Gravity actually broke the feature for this specific client, because they introduced the new itemlink feature [Lemongrass]
+// See the following github issues for more details:
+// * https://github.com/rathena/rathena/issues/1236
+// * https://github.com/rathena/rathena/issues/1873
+#if PACKETVER >= 20151104
+		const std::string start_tag = "<ITEM>";
+		const std::string closing_tag = "</ITEM>";
+#else
+		const std::string start_tag = "<ITEMLINK>";
+		const std::string closing_tag = "</ITEMLINK>";
+#endif
+
+		itemstr += start_tag;
+
+		if( use_brackets || battle_config.feature_mesitemlink_brackets ){
+			itemstr += "[";
+		}
+
+		if( name != nullptr && !battle_config.feature_mesitemlink_dbname ){
+			// Name was forcefully overwritten
+			itemstr += name;
+		}else{
+			// Use database name
+			itemstr += data->ename;
+		}
+
+		if( use_brackets || battle_config.feature_mesitemlink_brackets ){
+			itemstr += "]";
+		}
+
+		itemstr += "<INFO>";
+		itemstr += std::to_string( data->nameid );
+		itemstr += "</INFO>";
+
+		itemstr += closing_tag;
+
+		return itemstr;
+	}
+#endif
+
+	// This can be reached either because itemlinks are disabled via configuration or because the packet version does not support the feature
+	if( name != nullptr && !battle_config.feature_mesitemlink_dbname ){
+		// Name was forcefully overwritten
+		return name;
+	}else{
+		// Use database name
+		return data->ename;
+	}
+}
+
 ItemDatabase item_db;
 ItemDatabase item_db;
 
 
 /**
 /**

+ 1 - 0
src/map/itemdb.hpp

@@ -2151,6 +2151,7 @@ public:
 	std::shared_ptr<item_data> search_aegisname( const char *name );
 	std::shared_ptr<item_data> search_aegisname( const char *name );
 	std::string create_item_link(struct item& item);
 	std::string create_item_link(struct item& item);
 	std::string create_item_link( std::shared_ptr<item_data>& data );
 	std::string create_item_link( std::shared_ptr<item_data>& data );
+	std::string create_item_link_for_mes( std::shared_ptr<item_data>& data, bool use_brackets, const char* name );
 
 
 private:
 private:
 	std::string create_item_link(struct item& item, std::shared_ptr<item_data>& data);
 	std::string create_item_link(struct item& item, std::shared_ptr<item_data>& data);

+ 32 - 0
src/map/script.cpp

@@ -26806,6 +26806,37 @@ BUILDIN_FUNC(itemlink)
 	return SCRIPT_CMD_SUCCESS;
 	return SCRIPT_CMD_SUCCESS;
 }
 }
 
 
+BUILDIN_FUNC(mesitemlink){
+	t_itemid nameid = script_getnum( st, 2 );
+	std::shared_ptr<item_data> data = item_db.find( nameid );
+	
+	if( data == nullptr ){
+		ShowError( "buildin_mesitemlink: Item ID %u does not exists.\n", nameid );
+		script_pushconststr( st, "" );
+		return SCRIPT_CMD_FAILURE;
+	}
+
+	bool use_brackets = true;
+
+	if( script_hasdata( st, 3 ) ){
+		use_brackets = script_getnum( st, 3 ) != 0;
+	}
+
+	const char* name = nullptr;
+
+	if( script_hasdata( st, 4 ) ){
+		name = script_getstr( st, 4 );
+	}
+
+	// Create the link, depending on configuration and packet version
+	std::string itemlstr = item_db.create_item_link_for_mes( data, use_brackets, name );
+
+	// Push it to the script engine for further usage
+	script_pushstrcopy( st, itemlstr.c_str() );
+
+	return SCRIPT_CMD_SUCCESS;
+}
+
 BUILDIN_FUNC(addfame) {
 BUILDIN_FUNC(addfame) {
 	map_session_data *sd;
 	map_session_data *sd;
 
 
@@ -27620,6 +27651,7 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(item_reform, "??"),
 	BUILDIN_DEF(item_reform, "??"),
 	BUILDIN_DEF(item_enchant, "i?"),
 	BUILDIN_DEF(item_enchant, "i?"),
 	BUILDIN_DEF(itemlink, "i?????????"),
 	BUILDIN_DEF(itemlink, "i?????????"),
+	BUILDIN_DEF(mesitemlink, "i??"),
 	BUILDIN_DEF(addfame, "i?"),
 	BUILDIN_DEF(addfame, "i?"),
 	BUILDIN_DEF(getfame, "?"),
 	BUILDIN_DEF(getfame, "?"),
 	BUILDIN_DEF(getfamerank, "?"),
 	BUILDIN_DEF(getfamerank, "?"),