Itemlink command and integration (#7291)
Co-authored-by: Akkarinage <mike.langford@industrial-illusions.net> Co-authored-by: Aleos <aleos89@users.noreply.github.com> Co-authored-by: Atemo <Atemo@users.noreply.github.com> Co-authored-by: cydh<cydh@users.noreply.github.com> Co-authored-by: Lemongrass3110 <lemongrass@kstp.at> Co-authored-by: secretdataz<secretdataz@users.noreply.github.com>
This commit is contained in:
parent
96efb0e426
commit
55d3c1578c
@ -135,3 +135,10 @@ feature.dynamicnpc_rangey: 2
|
||||
// Should the dynamic NPCs look into the direction of the player? (Note 1)
|
||||
// Default: no
|
||||
feature.dynamicnpc_direction: no
|
||||
|
||||
// Itemlink System on informational related commands (Note 1)
|
||||
// Generates <ITEML> string for an item and can be used for npctalk, message,
|
||||
// dispbottom, and broadcast commands. The result is clickable-item name just
|
||||
// like from SHIFT+Click from player's inventory/cart/equipment window.
|
||||
// Requires: 2010-00-00RagexeRE or later
|
||||
feature.itemlink: on
|
||||
|
@ -10958,6 +10958,29 @@ 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>});
|
||||
|
||||
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.
|
||||
|
||||
|
||||
Examples:
|
||||
|
||||
npctalk "Knife [3] : "+itemlink(1201)+"";
|
||||
npctalk "+16 Knife [3] : "+itemlink(1201,16)+"";
|
||||
npctalk "+13 BXB Bapho+VR+EA2+EA1 : "+itemlink(18110,13,4147,4407,4833,4832)+"";
|
||||
setarray .@opt_ids[0],RDMOPT_VAR_ATKPERCENT,RDMOPT_VAR_ATKPERCENT,RDMOPT_VAR_ATTMPOWER,0,0;
|
||||
setarray .@opt_values[0],3,5,20,0,0;
|
||||
setarray .@opt_params[0],0,0,0,0,0;
|
||||
npctalk "+13 BXB Bapho+VR+EA2+EA1 + 3 Options : "+itemlink(18110,13,4147,4407,4833,4832,0,.@opt_ids,.@opt_values,.@opt_params)+"";
|
||||
|
||||
|
||||
RandomIDArray, RandomValueArray, and RandomParamArray only works if the
|
||||
client (and server) supports the Item Random Options feature (PACKETVER >= 20150225).
|
||||
|
||||
========================
|
||||
|14.- Channel commands.|
|
||||
========================
|
||||
|
15
npc/test/ci/0000_funcs.txt
Normal file
15
npc/test/ci/0000_funcs.txt
Normal file
@ -0,0 +1,15 @@
|
||||
function script AssertTrue {
|
||||
if (!getarg(0)) {
|
||||
errormes "AssertTrue failed for " + getarg(1) + ".";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function script AssertEquals {
|
||||
if (getarg(0) != getarg(1)) {
|
||||
errormes "AssertEquals failed for " + getarg(2) + ": expected " + getarg(0) + ", got " + getarg(1) + ".";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
35
npc/test/ci/7291.txt
Normal file
35
npc/test/ci/7291.txt
Normal file
@ -0,0 +1,35 @@
|
||||
- script itemlink#ci -1,{
|
||||
OnInit:
|
||||
if( checkre(0) ){
|
||||
if( PACKETVER >= 20200916 ){
|
||||
.@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{
|
||||
// Item Link does not exist (clientside) yet
|
||||
.@expected$ = "Crimson Saber";
|
||||
}
|
||||
|
||||
setarray .@opt_ids,RDMOPT_WEAPON_ATTR_GROUND;
|
||||
.@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 ){
|
||||
.@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{
|
||||
// Item Link does not exist (clientside) yet
|
||||
.@expected$ = "Blade";
|
||||
}
|
||||
|
||||
// No Random Options in Pre-Renewal
|
||||
.@actual$ = itemlink(1108,10,4399);
|
||||
AssertEquals(.@expected$, .@actual$, "Generated itemlink for +10 Blade[4]");
|
||||
}
|
||||
}
|
@ -114,3 +114,33 @@ bool rathena::util::safe_multiplication( int64 a, int64 b, int64& result ){
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void rathena::util::string_left_pad_inplace(std::string& str, char padding, size_t num)
|
||||
{
|
||||
str.insert(0, min(0, num - str.length()), padding);
|
||||
}
|
||||
|
||||
std::string rathena::util::string_left_pad(const std::string& original, char padding, size_t num)
|
||||
{
|
||||
return std::string(num - min(num, original.length()), padding) + original;
|
||||
}
|
||||
|
||||
constexpr char base62_dictionary[] = {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
|
||||
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||
'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D',
|
||||
'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
|
||||
'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
|
||||
'U', 'V', 'W', 'X', 'Y', 'Z'
|
||||
};
|
||||
|
||||
std::string rathena::util::base62_encode( uint32 val ){
|
||||
std::string result = "";
|
||||
while (val != 0) {
|
||||
result = base62_dictionary[(val % 62)] + result;
|
||||
val /= 62;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -285,6 +285,31 @@ namespace rathena {
|
||||
template <typename T> void tolower( T& string ){
|
||||
std::transform( string.begin(), string.end(), string.begin(), ::tolower );
|
||||
}
|
||||
|
||||
/**
|
||||
* Pad string with arbitrary character in-place
|
||||
* @param str: String to pad
|
||||
* @param padding: Padding character
|
||||
* @param num: Maximum length of padding
|
||||
*/
|
||||
void string_left_pad_inplace(std::string& str, char padding, size_t num);
|
||||
|
||||
/**
|
||||
* Pad string with arbitrary character
|
||||
* @param original: String to pad
|
||||
* @param padding: Padding character
|
||||
* @param num: Maximum length of padding
|
||||
*
|
||||
* @return A copy of original string with padding added
|
||||
*/
|
||||
std::string string_left_pad(const std::string& original, char padding, size_t num);
|
||||
|
||||
/**
|
||||
* Encode base10 number to base62. Originally by lututui
|
||||
* @param val: Base10 Number
|
||||
* @return Base62 string
|
||||
**/
|
||||
std::string base62_encode( uint32 val );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4007,7 +4007,7 @@ ACMD_FUNC(idsearch)
|
||||
for(const auto &result : item_array) {
|
||||
std::shared_ptr<item_data> id = result.second;
|
||||
|
||||
sprintf(atcmd_output, msg_txt(sd,78), id->ename.c_str(), id->nameid); // %s: %u
|
||||
sprintf(atcmd_output, msg_txt(sd,78), item_db.create_item_link( id->nameid ).c_str(), id->nameid); // %s: %u
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
}
|
||||
sprintf(atcmd_output, msg_txt(sd,79), match); // It is %d affair above.
|
||||
@ -6678,7 +6678,7 @@ ACMD_FUNC(autolootitem)
|
||||
return -1;
|
||||
}
|
||||
sd->state.autolootid[i] = item_data->nameid; // Autoloot Activated
|
||||
sprintf(atcmd_output, msg_txt(sd,1192), item_data->name.c_str(), item_data->ename.c_str(), item_data->nameid); // Autolooting item: '%s'/'%s' {%u}
|
||||
sprintf(atcmd_output, msg_txt(sd,1192), item_data->name.c_str(), item_db.create_item_link( item_data->nameid ).c_str(), item_data->nameid); // Autolooting item: '%s'/'%s' {%u}
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
sd->state.autolooting = 1;
|
||||
break;
|
||||
@ -6689,7 +6689,7 @@ ACMD_FUNC(autolootitem)
|
||||
return -1;
|
||||
}
|
||||
sd->state.autolootid[i] = 0;
|
||||
sprintf(atcmd_output, msg_txt(sd,1194), item_data->name.c_str(), item_data->ename.c_str(), item_data->nameid); // Removed item: '%s'/'%s' {%u} from your autolootitem list.
|
||||
sprintf(atcmd_output, msg_txt(sd,1194), item_data->name.c_str(), item_db.create_item_link( item_data->nameid ).c_str(), item_data->nameid); // Removed item: '%s'/'%s' {%u} from your autolootitem list.
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
ARR_FIND(0, AUTOLOOTITEM_SIZE, i, sd->state.autolootid[i] != 0);
|
||||
if (i == AUTOLOOTITEM_SIZE) {
|
||||
@ -6717,7 +6717,7 @@ ACMD_FUNC(autolootitem)
|
||||
continue;
|
||||
}
|
||||
|
||||
sprintf(atcmd_output, "'%s'/'%s' {%u}", item_data->name.c_str(), item_data->ename.c_str(), item_data->nameid);
|
||||
sprintf(atcmd_output, "'%s'/'%s' {%u}", item_data->name.c_str(), item_db.create_item_link( item_data->nameid ).c_str(), item_data->nameid);
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
}
|
||||
}
|
||||
@ -7784,9 +7784,9 @@ ACMD_FUNC(mobinfo)
|
||||
int droprate = mob_getdroprate( &sd->bl, mob, mob->dropitem[i].rate, drop_modifier );
|
||||
|
||||
if (id->slots)
|
||||
sprintf(atcmd_output2, " - %s[%d] %02.02f%%", id->ename.c_str(), id->slots, (float)droprate / 100);
|
||||
sprintf(atcmd_output2, " - %s[%d] %02.02f%%", item_db.create_item_link( id->nameid ).c_str(), id->slots, (float)droprate / 100);
|
||||
else
|
||||
sprintf(atcmd_output2, " - %s %02.02f%%", id->ename.c_str(), (float)droprate / 100);
|
||||
sprintf(atcmd_output2, " - %s %02.02f%%", item_db.create_item_link( id->nameid ).c_str(), (float)droprate / 100);
|
||||
strcat(atcmd_output, atcmd_output2);
|
||||
if (++j % 3 == 0) {
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
@ -7824,14 +7824,14 @@ ACMD_FUNC(mobinfo)
|
||||
j++;
|
||||
if (j == 1) {
|
||||
if (id->slots)
|
||||
sprintf(atcmd_output2, " %s[%d] %02.02f%%", id->ename.c_str(), id->slots, mvppercent);
|
||||
sprintf(atcmd_output2, " %s[%d] %02.02f%%", item_db.create_item_link( id->nameid ).c_str(), id->slots, mvppercent);
|
||||
else
|
||||
sprintf(atcmd_output2, " %s %02.02f%%", id->ename.c_str(), mvppercent);
|
||||
sprintf(atcmd_output2, " %s %02.02f%%", item_db.create_item_link( id->nameid ).c_str(), mvppercent);
|
||||
} else {
|
||||
if (id->slots)
|
||||
sprintf(atcmd_output2, " - %s[%d] %02.02f%%", id->ename.c_str(), id->slots, mvppercent);
|
||||
sprintf(atcmd_output2, " - %s[%d] %02.02f%%", item_db.create_item_link( id->nameid ).c_str(), id->slots, mvppercent);
|
||||
else
|
||||
sprintf(atcmd_output2, " - %s %02.02f%%", id->ename.c_str(), mvppercent);
|
||||
sprintf(atcmd_output2, " - %s %02.02f%%", item_db.create_item_link( id->nameid ).c_str(), mvppercent);
|
||||
}
|
||||
strcat(atcmd_output, atcmd_output2);
|
||||
}
|
||||
@ -8266,7 +8266,7 @@ ACMD_FUNC(iteminfo)
|
||||
std::shared_ptr<item_data> item_data = result.second;
|
||||
|
||||
sprintf(atcmd_output, msg_txt(sd,1277), // Item: '%s'/'%s'[%d] (%u) Type: %s | Extra Effect: %s
|
||||
item_data->name.c_str(),item_data->ename.c_str(),item_data->slots,item_data->nameid,
|
||||
item_data->name.c_str(), item_db.create_item_link( item_data->nameid ).c_str(),item_data->slots,item_data->nameid,
|
||||
(item_data->type != IT_AMMO) ? itemdb_typename((enum item_types)item_data->type) : itemdb_typename_ammo((e_ammo_type)item_data->subtype),
|
||||
(item_data->script==NULL)? msg_txt(sd,1278) : msg_txt(sd,1279) // None / With script
|
||||
);
|
||||
@ -8323,7 +8323,7 @@ ACMD_FUNC(whodrops)
|
||||
for (const auto &result : item_array) {
|
||||
std::shared_ptr<item_data> id = result.second;
|
||||
|
||||
sprintf(atcmd_output, msg_txt(sd,1285), id->ename.c_str(), id->slots, id->nameid); // Item: '%s'[%d] (ID:%u)
|
||||
sprintf(atcmd_output, msg_txt(sd,1285), item_db.create_item_link( id->nameid ).c_str(), id->slots, id->nameid); // Item: '%s'[%d] (ID:%u)
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
|
||||
if (id->mob[0].chance == 0) {
|
||||
@ -9319,9 +9319,9 @@ ACMD_FUNC(itemlist)
|
||||
}
|
||||
|
||||
if( it->refine )
|
||||
StringBuf_Printf(&buf, "%d %s %+d (%s, id: %u)", it->amount, itd->ename.c_str(), it->refine, itd->name.c_str(), it->nameid);
|
||||
StringBuf_Printf(&buf, "%d %s %+d (%s, id: %u)", it->amount, item_db.create_item_link( it->nameid ).c_str(), it->refine, itd->name.c_str(), it->nameid);
|
||||
else
|
||||
StringBuf_Printf(&buf, "%d %s (%s, id: %u)", it->amount, itd->ename.c_str(), itd->name.c_str(), it->nameid);
|
||||
StringBuf_Printf(&buf, "%d %s (%s, id: %u)", it->amount, item_db.create_item_link( it->nameid ).c_str(), itd->name.c_str(), it->nameid);
|
||||
|
||||
if( it->equip ) {
|
||||
char equipstr[CHAT_SIZE_MAX];
|
||||
@ -9424,7 +9424,7 @@ ACMD_FUNC(itemlist)
|
||||
if( counter2 != 1 )
|
||||
StringBuf_AppendStr(&buf, ", ");
|
||||
|
||||
StringBuf_Printf(&buf, "#%d %s (id: %u)", counter2, card->ename.c_str(), card->nameid);
|
||||
StringBuf_Printf(&buf, "#%d %s (id: %u)", counter2, item_db.create_item_link( card->nameid ).c_str(), card->nameid);
|
||||
}
|
||||
|
||||
if( counter2 > 0 )
|
||||
|
@ -10267,6 +10267,7 @@ 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, },
|
||||
{ "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, },
|
||||
|
@ -563,6 +563,7 @@ struct Battle_Config
|
||||
int discount_item_point_shop;
|
||||
int update_enemy_position;
|
||||
int devotion_rdamage;
|
||||
int feature_itemlink;
|
||||
|
||||
// autotrade persistency
|
||||
int feature_autotrade;
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "../common/nullpo.hpp"
|
||||
#include "../common/random.hpp"
|
||||
@ -1239,6 +1241,98 @@ std::shared_ptr<item_data> ItemDatabase::searchname( const char *name ){
|
||||
return util::umap_find( this->nameToItemDataMap, lowername );
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an item link string
|
||||
* @param data: Item info
|
||||
* @return <ITEML> string for the item
|
||||
* @author [Cydh]
|
||||
**/
|
||||
std::string ItemDatabase::create_item_link( struct item& item ){
|
||||
std::shared_ptr<item_data> data = this->find( item.nameid );
|
||||
|
||||
if( data == nullptr ){
|
||||
ShowError( "Tried to create itemlink for unknown item %u.\n", item.nameid );
|
||||
return "Unknown item";
|
||||
}
|
||||
|
||||
// All these dates are unconfirmed
|
||||
#if PACKETVER >= 20100000
|
||||
if( !battle_config.feature_itemlink ){
|
||||
// Feature is disabled
|
||||
return data->ename;
|
||||
}
|
||||
|
||||
struct item_data* id = data.get();
|
||||
|
||||
#if PACKETVER_MAIN_NUM >= 20200916 || PACKETVER_RE_NUM >= 20200724
|
||||
const std::string start_tag = "<ITEML>";
|
||||
const std::string closing_tag = "</ITEML>";
|
||||
#else // PACKETVER >= 20100000
|
||||
const std::string start_tag = "<ITEMLINK>";
|
||||
const std::string closing_tag = "</ITEMLINK>";
|
||||
#endif
|
||||
|
||||
std::string itemstr = start_tag;
|
||||
|
||||
itemstr += util::string_left_pad(util::base62_encode(id->equip), '0', 5);
|
||||
itemstr += itemdb_isequip2(id) ? "1" : "0";
|
||||
itemstr += util::base62_encode(item.nameid);
|
||||
if (item.refine > 0) {
|
||||
itemstr += "%" + util::string_left_pad(util::base62_encode(item.refine), '0', 2);
|
||||
}
|
||||
if (itemdb_isequip2(id)) {
|
||||
itemstr += "&" + util::string_left_pad(util::base62_encode(id->look), '0', 2);
|
||||
}
|
||||
#if PACKETVER_MAIN_NUM >= 20200916 || PACKETVER_RE_NUM >= 20200724
|
||||
itemstr += "'" + util::string_left_pad(util::base62_encode(item.enchantgrade), '0', 2);
|
||||
#endif
|
||||
|
||||
#if PACKETVER_MAIN_NUM >= 20200916 || PACKETVER_RE_NUM >= 20200724
|
||||
const std::string card_sep = ")";
|
||||
const std::string optid_sep = "+";
|
||||
const std::string optpar_sep = ",";
|
||||
const std::string optval_sep = "-";
|
||||
#else
|
||||
const std::string card_sep = "(";
|
||||
const std::string optid_sep = "*";
|
||||
const std::string optpar_sep = "+";
|
||||
const std::string optval_sep = ",";
|
||||
#endif
|
||||
|
||||
for (uint8 i = 0; i < MAX_SLOTS; ++i) {
|
||||
itemstr += card_sep + util::string_left_pad(util::base62_encode(item.card[i]), '0', 2);
|
||||
}
|
||||
|
||||
#if PACKETVER >= 20150225
|
||||
for (uint8 i = 0; i < MAX_ITEM_RDM_OPT; ++i) {
|
||||
if (item.option[i].id == 0) {
|
||||
break; // ignore options including ones beyond this one since the client won't even display them
|
||||
}
|
||||
// Option ID
|
||||
itemstr += optid_sep + util::string_left_pad(util::base62_encode(item.option[i].id), '0', 2);
|
||||
// Param
|
||||
itemstr += optpar_sep + util::string_left_pad(util::base62_encode(item.option[i].param), '0', 2);
|
||||
// Value
|
||||
itemstr += optval_sep + util::string_left_pad(util::base62_encode(item.option[i].value), '0', 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
itemstr += closing_tag;
|
||||
return itemstr;
|
||||
#else
|
||||
// Did not exist before that
|
||||
return data->ename;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string ItemDatabase::create_item_link( t_itemid id ){
|
||||
struct item it = {};
|
||||
|
||||
it.nameid = id;
|
||||
|
||||
return this->create_item_link( it );
|
||||
}
|
||||
|
||||
ItemDatabase item_db;
|
||||
|
||||
/**
|
||||
|
@ -5,6 +5,7 @@
|
||||
#define ITEMDB_HPP
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "../common/database.hpp"
|
||||
@ -1344,6 +1345,8 @@ public:
|
||||
// Additional
|
||||
std::shared_ptr<item_data> searchname( const char* name );
|
||||
std::shared_ptr<item_data> search_aegisname( const char *name );
|
||||
std::string create_item_link( struct item& data );
|
||||
std::string create_item_link( t_itemid id );
|
||||
};
|
||||
|
||||
extern ItemDatabase item_db;
|
||||
|
@ -26774,6 +26774,41 @@ BUILDIN_FUNC(item_enchant){
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate item link string for client
|
||||
* itemlink(<item_id>,<refine>,<card0>,<card1>,<card2>,<card3>,<enchantgrade>{,<RandomIDArray>,<RandomValueArray>,<RandomParamArray>});
|
||||
* @author [Cydh]
|
||||
**/
|
||||
BUILDIN_FUNC(itemlink)
|
||||
{
|
||||
struct item item = {};
|
||||
|
||||
item.nameid = script_getnum(st, 2);
|
||||
|
||||
if( !item_db.exists( item.nameid ) ){
|
||||
ShowError( "buildin_itemlink: Item ID %u does not exists.\n", item.nameid );
|
||||
st->state = END;
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
|
||||
FETCH(3, item.refine);
|
||||
FETCH(4, item.card[0]);
|
||||
FETCH(5, item.card[1]);
|
||||
FETCH(6, item.card[2]);
|
||||
FETCH(7, item.card[3]);
|
||||
FETCH(8, item.enchantgrade);
|
||||
|
||||
#if PACKETVER >= 20150225
|
||||
if ( script_hasdata(st,9) && script_getitem_randomoption(st, nullptr, &item, "itemlink", 9) == false) {
|
||||
st->state = END;
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string itemlstr = item_db.create_item_link(item);
|
||||
script_pushstrcopy(st, itemlstr.c_str());
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
|
||||
BUILDIN_FUNC(addfame) {
|
||||
struct map_session_data *sd;
|
||||
@ -27558,6 +27593,7 @@ struct script_function buildin_func[] = {
|
||||
BUILDIN_DEF(add_reputation_points, "ii?"),
|
||||
BUILDIN_DEF(item_reform, "??"),
|
||||
BUILDIN_DEF(item_enchant, "i?"),
|
||||
BUILDIN_DEF(itemlink, "i?????????"),
|
||||
BUILDIN_DEF(addfame, "i?"),
|
||||
BUILDIN_DEF(getfame, "?"),
|
||||
BUILDIN_DEF(getfamerank, "?"),
|
||||
|
@ -5,8 +5,8 @@ out=npc/scripts_custom.conf
|
||||
printf "\n" >> $out
|
||||
echo "// Custom Scripts" >> $out
|
||||
|
||||
find npc/custom \( -name "*.txt" \) | xargs -I % echo "npc: %" >> $out
|
||||
find npc/custom \( -name "*.txt" \) | sort | xargs -I % echo "npc: %" >> $out
|
||||
|
||||
echo "// Test Scripts" >> $out
|
||||
|
||||
find npc/test \( -name "*.txt" \) | xargs -I % echo "npc: %" >> $out
|
||||
find npc/test \( -name "*.txt" \) | sort | xargs -I % echo "npc: %" >> $out
|
||||
|
Loading…
x
Reference in New Issue
Block a user