From f261307bbee5492fd2ce4e2088916e80dc859faa Mon Sep 17 00:00:00 2001 From: Lemongrass3110 Date: Tue, 7 Feb 2023 10:47:36 +0100 Subject: [PATCH] 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 Co-authored-by: Aleos --- conf/battle/feature.conf | 13 ++++ doc/script_commands.txt | 30 ++++++++-- npc/custom/official/GeffenMagicTournament.txt | 6 +- npc/re/custom/lasagna/lasagna_npcs.txt | 26 ++++---- npc/re/merchants/Emperium_Seller.txt | 2 +- npc/re/merchants/Slot_Move_Card_Sales.txt | 2 +- npc/re/merchants/cashmall.txt | 2 +- npc/re/merchants/eden_market.txt | 2 +- npc/re/merchants/enchan_illusion_16_2.txt | 30 +++++----- npc/re/merchants/enchan_illusion_17_1.txt | 52 ++++++++-------- npc/re/merchants/enchan_rockridge.txt | 4 +- npc/re/merchants/ghost_palace_exchange.txt | 6 +- npc/re/merchants/new_insurance.txt | 16 ++--- npc/re/merchants/refine.txt | 2 +- npc/re/quests/juno_monster_society.txt | 28 ++++----- npc/re/quests/quests_16_1.txt | 2 +- npc/re/quests/quests_16_2.txt | 6 +- npc/re/quests/quests_rockridge.txt | 20 +++---- npc/test/ci/7291.txt | 33 ++++++---- src/map/battle.cpp | 23 +++++++ src/map/battle.hpp | 3 + src/map/itemdb.cpp | 60 +++++++++++++++++++ src/map/itemdb.hpp | 1 + src/map/script.cpp | 32 ++++++++++ 24 files changed, 283 insertions(+), 118 deletions(-) diff --git a/conf/battle/feature.conf b/conf/battle/feature.conf index 475266bb5c..e26dfc8987 100644 --- a/conf/battle/feature.conf +++ b/conf/battle/feature.conf @@ -147,6 +147,19 @@ feature.dynamicnpc_direction: no // Requires: 2015-11-04Ragexe or later 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) // Requires: 2015-11-04 or later feature.stylist: on diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 885963ed09..06ef888159 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -1127,13 +1127,17 @@ In 2015 the tag name was changed to resulting in the following syntax: Display NameItem ID +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: mes "Did you ever consume a Red Potion501?"; // Or in 2015: mes "Did you ever consume a Red Potion501?"; -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 ---- @@ -10998,13 +11002,13 @@ If is specified, the specified player is used rather than the attached --------------------------------------- -*itemlink(,,,,,,{,,,}); +*itemlink({,{,{,{,{,,{{,,,}}}}}}}); 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 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: @@ -11021,6 +11025,24 @@ Examples: RandomIDArray, RandomValueArray, and RandomParamArray only works if the client (and server) supports the Item Random Options feature (PACKETVER >= 20150225). +--------------------------------------- + +*mesitemlink({,{,}); + +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 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 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.| ======================== diff --git a/npc/custom/official/GeffenMagicTournament.txt b/npc/custom/official/GeffenMagicTournament.txt index de28e5899c..d4fd41485e 100644 --- a/npc/custom/official/GeffenMagicTournament.txt +++ b/npc/custom/official/GeffenMagicTournament.txt @@ -260,7 +260,7 @@ L_Shield: case 3: goto L_Menu; break; } mes .@n$; - mes ""+getitemname(.@item)+""+.@item+""; + mes mesitemlink( .@item, false ); mes "Price is "+.@cost+" coins"; mes "Do you wish to exchange your coins?"; next; @@ -303,7 +303,7 @@ L_Ring: break; } mes .@n$; - mes ""+getitemname(.@item)+""+.@item+""; + mes mesitemlink( .@item, false ); mes "Price is "+.@cost+" coins"; mes "Do you wish to exchange your coins?"; next; @@ -345,7 +345,7 @@ L_Armor: break; } mes .@n$; - mes ""+getitemname(.@item)+""+.@item+""; + mes mesitemlink( .@item, false ); mes "Price is "+.@cost+" coins"; mes "Do you wish to exchange your coins?"; next; diff --git a/npc/re/custom/lasagna/lasagna_npcs.txt b/npc/re/custom/lasagna/lasagna_npcs.txt index 0e2e1b80c1..edd510ed91 100644 --- a/npc/re/custom/lasagna/lasagna_npcs.txt +++ b/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]"; switch(.@s) { case 1: - mes "Low-grade Horse Mackerel Amulet 28413 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; case 2: - mes "Low-grade Leaf Amulet 28416 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; case 3: - mes "Low-grade Rabbit Amulet 28419 is for my brothers' health and wellness."; + mes mesitemlink( 28419, false ) + " is for my brothers' health and wellness."; break; case 4: - mes "Shining Twig Charm 28422 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; case 5: - mes "Fresh Tuna Amulet 28423 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; case 6: - mes "Plump Earthworm Amulet 28424 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; } if (.@s < 4) { @@ -2092,7 +2092,7 @@ lasagna,131,245,5 script The diligent second son 4_CAT_3COLOR,{ .@cost = 30; .@item_id = 28418 + .@s; } - mes "Will you exchange it for " + .@cost + " Doram Token25142?"; + mes "Will you exchange it for " + .@cost + " " + mesitemlink( 25142, false ) + "?"; next; if (select( "Exchange", "Cancel" ) == 2) { mes "[Yota Chara]"; @@ -2164,7 +2164,7 @@ lasagna,131,250,5 script The brave third#weapon 4_DR_M_02,{ emotion ET_SPARK; mes "[Jogi Chara]"; 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 Doram Token 25142?"; + 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; if (select( "Search", "Cancel" ) == 1) { setarray .@item_data[0], @@ -2193,7 +2193,7 @@ lasagna,131,250,5 script The brave third#weapon 4_DR_M_02,{ else { mes "[Jogi Chara]"; mes "Whoa! This is ^3131FF" + getitemname(.@item_data[.@i]) + "^000000!"; - mes "Exchange it for " + .@item_data[.@i+1] + " Doram Token25142! Please? Will you do it, please?"; + mes "Exchange it for " + .@item_data[.@i+1] + " " + mesitemlink( 25142, false ) + "! Please? Will you do it, please?"; next; if (select( "Exchange", "Quit exchanging" ) == 2) { mes "[Jogi Chara]"; @@ -2253,7 +2253,7 @@ lasagna,140,250,3 script The skittish fourth#wea 4_DR_F_01,{ } mes "[Dandi Chara]"; 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 25142Doram Token ...."; + mes "If I find an item suitable for Jogi, I'll pay " + mesitemlink( 25142, false ) + "...."; next; if (select( "Search", "Cancel" ) == 1) { 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 { mes "[Dandi Chara]"; mes "Whoa, this must be ^3131FF" + getitemname(.@item_data[.@i]) + "^000000!!"; - mes "Don't you want to exchange this with " + .@item_data[.@i+1] + " Doram Token25142?"; + mes "Don't you want to exchange this with " + .@item_data[.@i+1] + " " + mesitemlink( 25142, false ) + "?"; next; if (select( "Exchange", "Quit exchanging" ) == 2) { 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!"; next; mes "[Goma Chara]"; - mes "Hey, if you give me " + .@needCoin + "Doram Token25142, I'll fix this for you."; - mes "This should produce the " + .@next_charm_ID + " 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; if (select( "Upgrade", "Cancel" ) == 2) { mes "[Goma Chara]"; diff --git a/npc/re/merchants/Emperium_Seller.txt b/npc/re/merchants/Emperium_Seller.txt index 3136d62a4d..7ec54d72a5 100644 --- a/npc/re/merchants/Emperium_Seller.txt +++ b/npc/re/merchants/Emperium_Seller.txt @@ -28,7 +28,7 @@ prt_in,212,169,3 script Guild Clerk 4_M_04,{ next; mes "[Guild Clerk]"; mes "As part of that,"; - mes "we are selling a limited quantity of 100 Emperium714 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."; next; mes "[Guild Clerk]"; diff --git a/npc/re/merchants/Slot_Move_Card_Sales.txt b/npc/re/merchants/Slot_Move_Card_Sales.txt index e3661f4ace..d29520f655 100644 --- a/npc/re/merchants/Slot_Move_Card_Sales.txt +++ b/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,{ mes "[Salesman]"; mes "Howdy."; - mes "I'm selling [Character Position Change Coupon]12786."; + mes "I'm selling " + mesitemlink( 12786 ) + "."; mes "You can ^4d4dffchange the slot position of a character using the card^000000."; next; mes "[Salesman]"; diff --git a/npc/re/merchants/cashmall.txt b/npc/re/merchants/cashmall.txt index 6e934dbe65..f4b60276d4 100644 --- a/npc/re/merchants/cashmall.txt +++ b/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 "Today doesn't come every day!"; mes "Things to see today~ Voila!"; - mes "You can only exchange with [[Kachua] Mileage Coupon]1000274!"; + mes "You can only exchange with " + mesitemlink( 1000274 ) + "!"; mes "Feel free to choose!"; 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" ) ){ diff --git a/npc/re/merchants/eden_market.txt b/npc/re/merchants/eden_market.txt index 74d6316851..7a3a99c1ab 100644 --- a/npc/re/merchants/eden_market.txt +++ b/npc/re/merchants/eden_market.txt @@ -320,7 +320,7 @@ moc_para01,106,38,4 script Market Group Hustler#ent 4_M_YOYOROGUE,{ next; mes "[Hustler]"; mes "More special items are sold on weekends."; - mes "I have even seen an Izidor709 being sold~"; + mes "I have even seen an " + mesitemlink( 709, false ) + " being sold~"; mes "It was amazing."; mes "Of course it was super expensive and only a handful were up for sale."; next; diff --git a/npc/re/merchants/enchan_illusion_16_2.txt b/npc/re/merchants/enchan_illusion_16_2.txt index 7d2abfc68d..4a4c6ad461 100644 --- a/npc/re/merchants/enchan_illusion_16_2.txt +++ b/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 "The following is the list of equipment I can handle."; for ( .@i = 0; .@i < .@size; ++.@i ) - mes "" + .@reward_name$[.@i] + "" + .@reward_id[.@i] + ""; + mes mesitemlink( .@reward_id[.@i], false ); next; mes "[ Gemcutter ]"; 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 "The following is the list of equipment I can handle."; for ( .@i = 0; .@i < .@size; ++.@i ) - mes "" + .@reward_name$[.@i] + "" + .@reward_id[.@i] + ""; + mes mesitemlink( .@reward_id[.@i], false ); next; mes "[ Gemcutter ]"; 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: switch( select( "Illusion Infiltrator", "Illusion Sharpened Legbone of Ghoul", "Illusion Wizardry Staff", "Illusion Ballista", "Illusion Book of the Apocalypse" ) ) { case 1: - mes "Illusion Infiltrator28022"; + mes mesitemlink( 28022, false ); mes "***********************************"; mes "Necessary Items"; 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"; break; case 2: - mes "Illusion Sharpened Legbone of Ghoul28023"; + mes mesitemlink( 28023, false ); mes "********************************"; mes "Necessary Items"; 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"; break; case 3: - mes "Illusion Wizardry Staff2039"; + mes mesitemlink( 2039, false ); mes "********************************"; mes "Necessary Items"; 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"; break; case 4: - mes "Illusion Ballista18149"; + mes mesitemlink( 18149, false ); mes "*************************"; mes "Necessary Items"; 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"; break; case 5: - mes "Illusion Book of the Apocalypse28612"; + mes mesitemlink( 28612, false ); mes "***********************"; mes "Necessary Items"; 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; case 2: select("Illusion Ancient Cape"); - mes "Illusion Ancient Cape20840"; + mes mesitemlink( 20840, false ); mes "*******************************"; mes "Necessary Items"; 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: switch( select( "Illusion Skull Ring", "Illusion Ring" ) ) { case 1: - mes "Illusion Skull Ring28508"; + mes mesitemlink( 28508, false ); mes "*************************"; mes "Necessary Items"; 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"; break; case 2: - mes "Illusion Ring28509"; + mes mesitemlink( 28509, false ); mes "********************"; mes "Necessary Items"; 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]); mes "[Illusion Stone Researcher]"; mes "The following is the list of equipment I can handle."; - mes "" + .@reward_name$[0] + "" + .@reward_id[0] + ""; - mes "" + .@reward_name$[1] + "" + .@reward_id[1] + ""; + mes mesitemlink( .@reward_id[0], false ); + mes mesitemlink( .@reward_id[1], false ); next; mes "[Illusion Stone Researcher]"; 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]); mes "[Illusion Stone Researcher]"; mes "The following is the list of equipment I can handle."; - mes "" + .@reward_name$[0] + "" + .@reward_id[0] + ""; - mes "" + .@reward_name$[1] + "" + .@reward_id[1] + ""; - mes "" + .@reward_name$[2] + "" + .@reward_id[2] + ""; + mes mesitemlink( .@reward_id[0], false ); + mes mesitemlink( .@reward_id[1], false ); + mes mesitemlink( .@reward_id[2], false ); next; mes "[Illusion Stone Researcher]"; mes "Make sure ^4d4dffyour equipment is refined to at least +9^000000 before bringing it to me."; diff --git a/npc/re/merchants/enchan_illusion_17_1.txt b/npc/re/merchants/enchan_illusion_17_1.txt index de79675453..aaff3ed930 100644 --- a/npc/re/merchants/enchan_illusion_17_1.txt +++ b/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,{ mes "[Grace Operator]"; mes "Hello."; - mes "We have ^4d4dffGrace^000000 equipment that can be exchanged for [" + getitemname(25723) + "]25723."; + 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."; close2; 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; if (checkweight(1201,3) == 0) { mes "[Rebellion]"; - mes "Do you want a Weapon Modification Device? It's 5 [Cor Cores]25723 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."; close; } mes "[Rebellion]"; - mes "Do you want a Weapon Modification Device? It's 5 [Cor Cores]25723 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."; next; 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; } mes "[Rebellion]"; - mes "I can randomly give you a [" + getitemname(.@ids[0]) + "]" + .@ids[0] + ","; - mes "[" + getitemname(.@ids[1]) + "]" + .@ids[1] + ","; - mes "or [" + getitemname(.@ids[2]) + "]" + .@ids[2] + "."; + 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?"; next; disable_items; @@ -220,7 +220,7 @@ sp_cor,108,130,5 script Rebellion#rm171_7 4_F_REBELLION3,{ 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; mes "[Rebellion]"; - mes "Do you want an Armor Modification Module? It's 30 [Mysterious Components]25669 and 5 [Cor Cores]25723."; + mes "Do you want an Armor Modification Module? It's 30 " + mesitemlink( 25669 ) + " and 5 " + mesitemlink( 25723 ) + "."; if (checkweight(1201,3) == 0) { mes "Your bag is full. Please make some room first."; close; @@ -287,7 +287,7 @@ sp_cor,111,130,3 script Elyumina#rm171_4 4_EP17_ELYUMINA,{ case 1: cutin "ep171_elyumina01",0; mes "[Elyumina]"; - mes "OS weapons? I'll handle that if you bring me 1 [Damaged Weapon]25668 and 50 [Mysterious Components]25669."; + 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?"; next; 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."; next; mes "[Elyumina]"; - mes "Sword: [Cannon Rapier-OS]13493"; - mes "Two-handed Sword: [Beam Claymore-OS]21047"; - mes "Staff: [Rutilus Stick-OS]26151"; - mes "Book: [Circuit Board-OS]28629"; - mes "Axe: [Blasti-OS]28136"; - mes "Mace: [Saphir Hall-OS]16088"; - mes "Bow: [Virtual Bow-OS]18178"; - mes "Crossbow: [MH-P89-OS]18179"; - mes "Katar: [Meuchler-OS]28038"; - mes "Knuckle: [Burning Knuckle-OS]1862"; - mes "Sniper Rifle: [HR-S55-OS]28253"; - mes "Dagger: [Kuroiro-OS]28755"; - mes "Bow: [AC-B44-OS]18180"; - mes "Lance: [Boost Lance-OS]32019"; - mes "Mace: [Ultio-OS]16089"; + 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; } disable_items; @@ -340,7 +340,7 @@ sp_cor,111,130,3 script Elyumina#rm171_4 4_EP17_ELYUMINA,{ case 2: cutin "ep171_elyumina04",0; mes "[Elyumina]"; - mes "If you want Illusion armor, bring me 50 [Cor Cores]25723. 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?"; next; cutin "",255; @@ -363,8 +363,8 @@ sp_cor,111,130,3 script Elyumina#rm171_4 4_EP17_ELYUMINA,{ } cutin "ep171_elyumina01",0; mes "[Elyumina]"; - mes "[" + getitemname(.@item[0]) + "]" + .@item[0] + ""; - mes "[" + getitemname(.@item[1]) + "]" + .@item[1] + ""; + mes mesitemlink( .@item[0] ); + mes mesitemlink( .@item[1] ); mes "Which one?"; next; cutin "",255; diff --git a/npc/re/merchants/enchan_rockridge.txt b/npc/re/merchants/enchan_rockridge.txt index 1aa364a158..b4e26b9ffb 100644 --- a/npc/re/merchants/enchan_rockridge.txt +++ b/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 "Ah, you're interested in the"; - mes "[" + .@item_name$[.@s] + "" + .@item_id[.@s] + "]."; + mes "[" + mesitemlink( .@item_id[.@s], false, .@item_name$[.@s] ) + "]."; 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?"; next; @@ -371,7 +371,7 @@ har_in01,34,81,5 script Howard#rr 4_M_TATIO,{ .@s = ( select(.@menu$) - 1 ) * 3; mes "[Howard]"; - mes "" + .@data$[.@s+2] + "" + .@data$[.@s+1] + ", got it."; + mes mesitemlink( atoi( .@data$[.@s+1] ), false, .@data$[.@s+2] ) + ", got it."; mes "That'll be " + .@data$[.@s] + " Rock Ridge Coins."; mes "Are you certain you want this item?"; next; diff --git a/npc/re/merchants/ghost_palace_exchange.txt b/npc/re/merchants/ghost_palace_exchange.txt index bc4d8a01b9..37ea91be64 100644 --- a/npc/re/merchants/ghost_palace_exchange.txt +++ b/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 mes "[Dimension Traveler]"; - mes "Adventurer friend, [" + .@item_name_req$ + "]6672 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; .@type = select( "Show me your weapon.", "Show me your armor.", "Anything special?", "I do not need." ) - 1; mes "[Dimension Traveler]"; @@ -33,7 +33,7 @@ dali02,51,130,4 script Dimension Traveler 4_F_SHABBY,{ } next; mes "[Dimension Traveler]"; - mes "Ah! The number that is written beside [" + .@item_name_req$ + "]6672 will be needed."; + mes "Ah! The number that is written beside " + mesitemlink( 6672 ) + " will be needed."; mes "Please keep that in mind."; switch(.@type) { @@ -80,7 +80,7 @@ dali02,51,130,4 script Dimension Traveler 4_F_SHABBY,{ .@s = (select(.@menu$) - 1) * 2; mes "[Dimension Traveler]"; if (.@type != 1) // armor type doesn't display item info - mes "Do you mean [" + getitemname(.@items[.@s]) + "]" + .@items[.@s] + "?"; + mes "Do you mean " + mesitemlink( .@items[.@s] ) + "?"; mes "" + .@items[.@s+1] + " ^006400" + .@item_name_req$ + "^000000 are required in exchange."; next; switch( select( "Let's exchange.", "Let me see other stuff.", "I will come back later." ) ) { diff --git a/npc/re/merchants/new_insurance.txt b/npc/re/merchants/new_insurance.txt index d55d229e91..7466d27db1 100644 --- a/npc/re/merchants/new_insurance.txt +++ b/npc/re/merchants/new_insurance.txt @@ -22,32 +22,32 @@ prontera,82,108,5 script Heart Merchant#life01 4_M_NFDEADMAN2,5,5,{ next; if(!countitem(.@old_item)){ mes "[Heart Merchant]"; - mes "Do you have any ["+.@old_item_name$+"]" + .@old_item + " in your storage?"; + mes "Do you have any " + mesitemlink( .@old_item ) + " in your storage?"; next; mes "[Heart Merchant]"; - mes "If you bring me a " + .@old_item_name$ + ", I'll exchange it to ["+.@new_item_name$+"]" + .@new_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 { mes "[Heart Merchant]"; - mes "Have you ever thought about replacing your ["+.@old_item_name$+"]" + .@old_item + " to something better? For example... ["+.@new_item_name$+"]" + .@new_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; switch(select("What is it?",(countitem(.@old_item)?"Exchange it please!":""),"I'm not interested")) { case 1: mes "[Heart Merchant]"; - mes "["+.@old_item_name$+"]" + .@old_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; mes "[Heart Merchant]"; - mes "But a lot of people are sad about the time limit, right? So I looked into it and prepared the ["+.@new_item_name$+"]" + .@new_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; mes "[Heart Merchant]"; - mes "["+.@new_item_name$+"]" + .@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."; + 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; select("Why are you exchanging it?"); 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?"; next; mes "[Heart Merchant]"; - mes "The exchange rate is 5 ["+.@old_item_name$+"]" + .@old_item + " for 1 ["+.@new_item_name$+"]" + .@new_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; 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."; @@ -84,7 +84,7 @@ prontera,82,108,5 script Heart Merchant#life01 4_M_NFDEADMAN2,5,5,{ } if (countitem(.@old_item) < (.@amount*5)) { mes "[Heart Merchant]"; - mes "Um, excuse me but... you don't have enough " +.@old_item_name$+ ", no? It's 5 ["+.@old_item_name$+"]" + .@old_item + " for 1 ["+.@new_item_name$+"]" + .@new_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; } mes "[Heart Merchant]"; diff --git a/npc/re/merchants/refine.txt b/npc/re/merchants/refine.txt index c215a3bece..e02af1aca5 100644 --- a/npc/re/merchants/refine.txt +++ b/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 prt_in,64,57,3 script Pauline 4_M_02,{ mes "[" + strnpcinfo(1) + "]"; - mes "Do you have [Shadowdecon Gemstone]25728 or [Zelunium Gemstone]25730?"; + mes "Do you have " + mesitemlink( 25728 ) + " or " + mesitemlink( 25730 ) + "?"; mes "We will exchange them for refined products for use as smelting goods."; close2; callshop "barter_refine_3"; diff --git a/npc/re/quests/juno_monster_society.txt b/npc/re/quests/juno_monster_society.txt index 11546864eb..4f6f20c8da 100644 --- a/npc/re/quests/juno_monster_society.txt +++ b/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; case 2: mes .@npc_name$; - mes "Can I move it to Einbroch? Give me one [" + .@item_name$ + "]1000374 and I can teleport you."; + mes "Can I move it to Einbroch? Give me one " + mesitemlink( 1000374 ) + " and I can teleport you."; next; select( "Give me 1 " + .@item_name$ + "." ); if (countitem(1000374) < 1) { @@ -787,7 +787,7 @@ ein_fild06,257,351,4 script Map Examiner Bast#yma 4_F_CHNDRESS1,{ close; case 3: mes .@npc_name$; - mes "Can I move it to Einbroch? Give me one [" + .@item_name$ + "]1000374 and I can teleport you."; + mes "Can I move it to Einbroch? Give me one " + mesitemlink( 1000374 ) + " and I can teleport you."; next; select( "Give me 1 " + .@item_name$ + "." ); if (countitem(1000374) < 1) { @@ -872,7 +872,7 @@ gef_fild06,209,31,6 script Map Examiner Gefil#yma 4_M_MIDDLE,{ close; case 2: mes .@npc_name$; - mes "Give me 1 [" + .@item_name$ + "]1000374 and I can teleport you to Geffen."; + mes "Give me 1 " + mesitemlink( 1000374 ) + " and I can teleport you to Geffen."; next; select( "Give me 1 " + .@item_name$ + "." ); if (countitem(1000374) < 1) { @@ -916,7 +916,7 @@ gef_fild06,209,31,6 script Map Examiner Gefil#yma 4_M_MIDDLE,{ close; case 3: mes .@npc_name$; - mes "Give me 1 [" + .@item_name$ + "]1000374 and I can teleport you to Geffen."; + mes "Give me 1 " + mesitemlink( 1000374 ) + " and I can teleport you to Geffen."; next; select( "Give me 1 " + .@item_name$ + "." ); if (countitem(1000374) < 1) { @@ -1001,7 +1001,7 @@ lhz_fild01,240,107,4 script Map Examiner Lipiri#yma 4_M_HUBOY,{ close; case 2: mes .@npc_name$; - mes "If it's a nearby city, it's Lighthalzen. Give me one [" + .@item_name$ + "]1000374 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; select( "Give me 1 " + .@item_name$ + "." ); if (countitem(1000374) < 1) { @@ -1052,7 +1052,7 @@ lhz_fild01,240,107,4 script Map Examiner Lipiri#yma 4_M_HUBOY,{ close; case 3: mes .@npc_name$; - mes "If it's a nearby city, it's Lighthalzen. Give me one [" + .@item_name$ + "]1000374 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; select( "Give me 1 " + .@item_name$ + "." ); if (countitem(1000374) < 1) { @@ -1276,7 +1276,7 @@ hu_fild01,133,157,6 script Map Examiner Huf#yma 4_MAL_CAPTAIN,{ close; case 2: mes .@npc_name$; - mes "Are you going home? Hugel is the nearest city. I need 1 piece of [" + .@item_name$ + "]1000374."; + mes "Are you going home? Hugel is the nearest city. I need 1 piece of " + mesitemlink( 1000374 ) + "."; next; select( "Give me 1 " + .@item_name$ + "." ); if (countitem(1000374) < 1) { @@ -1321,7 +1321,7 @@ hu_fild01,133,157,6 script Map Examiner Huf#yma 4_MAL_CAPTAIN,{ close; case 3: mes .@npc_name$; - mes "Are you going home? Hugel is the nearest city. I need 1 piece of [" + .@item_name$ + "]1000374."; + mes "Are you going home? Hugel is the nearest city. I need 1 piece of " + mesitemlink( 1000374 ) + "."; next; select( "Give me 1 " + .@item_name$ + "." ); if (countitem(1000374) < 1) { @@ -1411,7 +1411,7 @@ tur_dun01,159,46,4 script Map Examiner Tural#yma 4_M_BRZ_MAN1,{ close; case 2: mes .@npc_name$; - mes "Give me one [" + .@item_name$ + "]1000374 and I can teleport you to Alberta."; + mes "Give me one " + mesitemlink( 1000374 ) + " and I can teleport you to Alberta."; next; select( "Give me 1 " + .@item_name$ + "." ); if (countitem(1000374) < 1) { @@ -1452,7 +1452,7 @@ tur_dun01,159,46,4 script Map Examiner Tural#yma 4_M_BRZ_MAN1,{ close; case 3: mes .@npc_name$; - mes "Give me one [" + .@item_name$ + "]1000374 and I can teleport you to Alberta."; + mes "Give me one " + mesitemlink( 1000374 ) + " and I can teleport you to Alberta."; next; select( "Give me 1 " + .@item_name$ + "." ); if (countitem(1000374) < 1) { @@ -1818,7 +1818,7 @@ tur_dun02,151,256,4 script Map Examiner Tidun#yma 4_M_NINJA_BLUE,{ close; case 2: mes .@npc_name$; - mes "If you give me one [" + .@item_name$ + "]1000374, 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; select( "Give me 1 " + .@item_name$ + "." ); if (countitem(1000374) < 1) { @@ -1863,7 +1863,7 @@ tur_dun02,151,256,4 script Map Examiner Tidun#yma 4_M_NINJA_BLUE,{ close; case 3: mes .@npc_name$; - mes "If you give me one [" + .@item_name$ + "]1000374, 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; select( "Give me 1 " + .@item_name$ + "." ); if (countitem(1000374) < 1) { @@ -1947,7 +1947,7 @@ tur_dun03,125,186,6 script Map Examiner Tsensor#yma 4_M_SIT_NOVICE,{ close; case 2: mes .@npc_name$; - mes "Alberta Express 1 [" + .@item_name$ + "]1000374, left immediately."; + mes "Alberta Express 1 " + mesitemlink( 1000374 ) + ", left immediately."; next; select( "Give me 1 " + .@item_name$ + "." ); if (countitem(1000374) < 1) { @@ -1992,7 +1992,7 @@ tur_dun03,125,186,6 script Map Examiner Tsensor#yma 4_M_SIT_NOVICE,{ close; case 3: mes .@npc_name$; - mes "Alberta Express 1 [" + .@item_name$ + "]1000374, left immediately."; + mes "Alberta Express 1 " + mesitemlink( 1000374 ) + ", left immediately."; next; select( "Give me 1 " + .@item_name$ + "." ); if (countitem(1000374) < 1) { diff --git a/npc/re/quests/quests_16_1.txt b/npc/re/quests/quests_16_1.txt index 8209090cc7..55fe7791a2 100644 --- a/npc/re/quests/quests_16_1.txt +++ b/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,{ mes "[Noblesse Operator]"; mes "Hello."; - mes "We have ^4d4dffNoblesse^000000 equipment that can be exchanged for [Honor Token]6919."; + 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."; close2; switch( eaclass() & EAJ_THIRDMASK ) { diff --git a/npc/re/quests/quests_16_2.txt b/npc/re/quests/quests_16_2.txt index 65fd7322db..f8e4724b6d 100644 --- a/npc/re/quests/quests_16_2.txt +++ b/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,{ mes "[Imperial Operator]"; mes "Hello."; - mes "We have ^4d4dffImperial^000000 equipment that can be exchanged for [" + getitemname(6919) + "]6919."; + 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."; close2; 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; mes "[Strasse]"; - mes "" + getitemname(.@item[.@s]) + "" + .@item[.@s] + "? I got it."; + mes mesitemlink( .@item[.@s], false ) + "? I got it."; mes "You need " + .@item[.@s+1] + " Schwartz Honor Tokens."; mes "Are you sure you want this?"; next; @@ -11536,7 +11536,7 @@ rebel_in,74,67,5 script Strasse#rebel_in 4_M_TATIO,{ } // custom text mes "[Strasse]"; - mes "Here is your " + getitemname(.@item[.@s]) + "" + .@item[.@s] + "."; + mes "Here is your " + mesitemlink( .@item[.@s], false ) + "."; delitem 25155, .@item[.@s+1]; getitem .@item[.@s],1; close; diff --git a/npc/re/quests/quests_rockridge.txt b/npc/re/quests/quests_rockridge.txt index 9a889bcc53..e930010981 100644 --- a/npc/re/quests/quests_rockridge.txt +++ b/npc/re/quests/quests_rockridge.txt @@ -781,15 +781,15 @@ har_in01,20,30,5 script Wyatt Warp#har_in01 4_M_YATTWARP,{ next; mes "[Wyatt Warp]"; mes "Both badges are worn by us Vigilantes, but they provide different effects."; - mes "I have Vigilante Badge (L)28495"; - mes "and Vigilante Badge (R)28496."; + mes "I have " + mesitemlink( 28495, false, "Vigilante Badge (L)" ); + mes "and " + mesitemlink( 28496, false, "Vigilante Badge (R)" ) + "."; mes "Pick one you like."; next; setarray .@item_name$[0], "Vigilante Badge (L)", "Vigilante Badge (R)"; setarray .@item_id[0], 28495, 28496; .@s = select( "Vigilante Badge (L)", "Vigilante Badge (R)" ) - 1; mes "[Wyatt Warp]"; - mes "Do you want " + .@item_name$[.@s] + "" + .@item_id[.@s] + "?"; + mes "Do you want " + mesitemlink( .@item_id[.@s], false, .@item_name$[.@s] ) + "?"; mes "Excellent choice!"; mes "Are you certain you want this?"; 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."; next; mes "[Food Distributer]"; - mes "Bring me 160 Sweet Potatoes516 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; case 12384: 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."; next; mes "[Food Distributer]"; - mes "Bring me 50 Meats517 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; case 12385: 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."; next; mes "[Food Distributer]"; - mes "Bring me 160 Carrots515 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; case 12386: 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?"; next; mes "[Food Distributer]"; - mes "Bring me 160 Bananas513 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; case 12387: 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."; next; mes "[Food Distributer]"; - mes "Bring me 160 Pumpkins535 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; case 12388: 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."; next; mes "[Food Distributer]"; - mes "Bring me 60 Mushrooms581 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; } end; @@ -3401,7 +3401,7 @@ S_Food: .@amount = getarg(2); if (countitem(.@item_id) < .@amount) { mes "[Food Distributer]"; - mes "Bring me " + .@amount + " " + getitemname(.@item_id) + "" + .@item_id + " 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; } delitem .@item_id, .@amount; diff --git a/npc/test/ci/7291.txt b/npc/test/ci/7291.txt index 9d960f71d2..715a5845ab 100644 --- a/npc/test/ci/7291.txt +++ b/npc/test/ci/7291.txt @@ -1,14 +1,18 @@ - script itemlink#ci -1,{ OnInit: if( checkre(0) ){ - if( PACKETVER >= 20200916 ){ + if( PACKETVER >= 20200724 ){ + // Change of separators and add grade .@expected$ = "0000213v0%0g&00'00)18X)1ck)00)00+2R,00-00"; - }else if( PACKETVER >= 20150225 ){ - // Grade does not exist (clientside) yet - .@expected$ = "0000213v0%0g&00(18X(1ck(00(00*2R+00,00"; - }else if( PACKETVER >= 20100000 ){ - // Random Options do not exist (clientside) yet - .@expected$ = "0000213v0%0g&00(18X(1ck(00(00"; + }else if( PACKETVER >= 20161116 ){ + // Change of separators and add equip preview + .@expected$ = "0000213v0%0g&00(18X(1ck(00(00*2R+00,00"; + }else if( PACKETVER >= 20160113 ){ + // Change from to + .@expected$ = "0000213v0%0g'18X'1ck'00'00)2R*00+00"; + }else if( PACKETVER >= 20151104 ){ + // Initial version + .@expected$ = "0000213v0%0g'18X'1ck'00'00)2R*00+00"; }else{ // Item Link does not exist (clientside) yet .@expected$ = "Crimson Saber"; @@ -18,11 +22,18 @@ OnInit: .@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"); }else{ - if( PACKETVER >= 20200916 ){ + if( PACKETVER >= 20200724 ){ + // Change of separators and add grade (not used in pre-renewal) .@expected$ = "000021hS%0a&00'00)18X)00)00)00"; - }else if( PACKETVER >= 20100000 ){ - // Grade does not exist (clientside) yet// Grade does not exist (clientside) yet - .@expected$ = "000021hS%0a&00(18X(00(00(00"; + }else if( PACKETVER >= 20161116 ){ + // Change of separators and add equip preview + .@expected$ = "000021hS%0a&00(18X(00(00(00"; + }else if( PACKETVER >= 20160113 ){ + // Change from to + .@expected$ = "000021hS%0a'18X'00'00'00"; + }else if( PACKETVER >= 20151104 ){ + // Initial version + .@expected$ = "000021hS%0a'18X'00'00'00"; }else{ // Item Link does not exist (clientside) yet .@expected$ = "Blade"; diff --git a/src/map/battle.cpp b/src/map/battle.cpp index 22378ca4d2..6c6c81f4fd 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -10277,6 +10277,9 @@ static const struct _battle_data { { "feature.barter", &battle_config.feature_barter, 1, 0, 1, }, { "feature.barter_extended", &battle_config.feature_barter_extended, 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, }, { "macro_detection_retry", &battle_config.macro_detection_retry, 3, 1, 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] 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 (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"); @@ -10429,6 +10445,13 @@ void battle_adjust_conf() } #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( battle_config.feature_stylist ){ ShowWarning("conf/battle/feature.conf stylist is enabled but it requires PACKETVER 2015-11-04 or newer, disabling...\n"); diff --git a/src/map/battle.hpp b/src/map/battle.hpp index 18609f4da3..3edcde31b2 100644 --- a/src/map/battle.hpp +++ b/src/map/battle.hpp @@ -564,6 +564,9 @@ struct Battle_Config int update_enemy_position; int devotion_rdamage; int feature_itemlink; + int feature_mesitemlink; + int feature_mesitemlink_brackets; + int feature_mesitemlink_dbname; // autotrade persistency int feature_autotrade; diff --git a/src/map/itemdb.cpp b/src/map/itemdb.cpp index 832ac4cd4a..e2c30302da 100644 --- a/src/map/itemdb.cpp +++ b/src/map/itemdb.cpp @@ -1357,6 +1357,66 @@ std::string ItemDatabase::create_item_link(struct item& item) { return this->create_item_link(item, data); } +std::string ItemDatabase::create_item_link_for_mes( std::shared_ptr& 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 = ""; + const std::string closing_tag = ""; +#else + const std::string start_tag = ""; + const std::string closing_tag = ""; +#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 += ""; + itemstr += std::to_string( data->nameid ); + itemstr += ""; + + 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; /** diff --git a/src/map/itemdb.hpp b/src/map/itemdb.hpp index 7495bc3079..881480197e 100644 --- a/src/map/itemdb.hpp +++ b/src/map/itemdb.hpp @@ -2151,6 +2151,7 @@ public: std::shared_ptr search_aegisname( const char *name ); std::string create_item_link(struct item& item); std::string create_item_link( std::shared_ptr& data ); + std::string create_item_link_for_mes( std::shared_ptr& data, bool use_brackets, const char* name ); private: std::string create_item_link(struct item& item, std::shared_ptr& data); diff --git a/src/map/script.cpp b/src/map/script.cpp index c1e1552dea..2446043033 100644 --- a/src/map/script.cpp +++ b/src/map/script.cpp @@ -26806,6 +26806,37 @@ BUILDIN_FUNC(itemlink) return SCRIPT_CMD_SUCCESS; } +BUILDIN_FUNC(mesitemlink){ + t_itemid nameid = script_getnum( st, 2 ); + std::shared_ptr 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) { map_session_data *sd; @@ -27620,6 +27651,7 @@ struct script_function buildin_func[] = { BUILDIN_DEF(item_reform, "??"), BUILDIN_DEF(item_enchant, "i?"), BUILDIN_DEF(itemlink, "i?????????"), + BUILDIN_DEF(mesitemlink, "i??"), BUILDIN_DEF(addfame, "i?"), BUILDIN_DEF(getfame, "?"), BUILDIN_DEF(getfamerank, "?"),