Jump to content

Extended Item Award


Recommended Posts

  • Forum Moderator

M2 Download Center

This is the hidden content, please
( Internal )

This is the hidden content, please
( GitHub )

Metin2 Extended Item Award

You can store all bonuses and stones for items.

I wrote that as request from @ProfessorEntemore informations at repository.

2018-04-02 14:02:11 Monday

  • Fixed problem with save bonus after reload items.
  • Fixed problem with unknown values.
  • Correction for socket real time and more.
  • Fixed unknown average/skill damage bonus value. player.item_proto.addon_type = -1 (Eg. 189, 199, 299, 1139, 1179, 2159, 2179, 3169, 3219, 5119, 5129, 6019, 6069, 6079, 7169)[+0 - +9] That's for the items which have addon type (-1) and you added them in item shop without bonuses like skill damage or hit damage, value x, y as default, so they'll will be without bonuses and get bugged. Now when the item will be inserted there'll be a check if item doesn't have those bonuses (from query) add a random average/skill damage bonus value.
INSERT INTO player.item_award(`login`, `vnum`, `count`, `mall`) VALUES ('account', 189, 1, 1); 

2019-04-12 02:31:18 Friday

  • Fixed unique items based on the real time.
  • Fixed unstackable items.
  • Fixed if item count overflow occured, then set it to maximum.
  • Added support for books. (check skill types, unknown skill), skill vnum need to be saved into socket0, (4=Aura of the Sword < player.skill_proto), if the skill vnum is unknown, there will be a random book based on pc races, excluded skills PASSIVE, GUILD, SUPPORT.
  • Added a to-do for ITEM_BLEND, check if apply_type exists in bonuses, check if apply_value/apply_duration is equal with grades (1/2/3/4/5) from settings, blend.txt
  • Added auto query.
# Random book
INSERT INTO player.item_award(`login`, `vnum`, `count`, `mall`) VALUES ('account', 50300, 1, 1); 
# Specific book by skill vnum
INSERT INTO player.item_award(`login`, `vnum`, `count`, `socket0`, `mall`) VALUES ('account', 50300, 1, 4, 1);

2019-04-16 14:54:48 Tuesday (Video - Click)

  • Added a check for attr types and values min - max.
  • You can't insert wrong bonuses into a specific item.
  • Eg. Add 2000 MAX_HP on your Sword+9, was possible, now not.
  • Eg. Add +500 INT to your shield, now there's a check for min-max value of player.item_attr Lv.1 - Lv.5 and your 500 INTvalue will be replaced with max value from lvl5 of bonus, like 12 (lv5), that happen with all the bonuses, same thing with the values lower than lvl1, like 5 HP_REGEN on your neck, when the minimum (lv1) is 10, the value will be replaced with 10.
  • If the bonus type can't be added into a specific item, the bonus will be ignored > deleted. (example: critical pct to armor)
  • Refactorized all the code and moved all features into 
    This is the hidden content, please
    .
  • C++11 or higher is required for checking attributes.
# Test unknown types + higher and lower values in game.
INSERT INTO `player`.`item_award`(`login`, `vnum`, `count`, `attrtype0`, `attrvalue0`, `attrtype1`, `attrvalue1`, `attrtype2`, `attrvalue2`, `attrtype3`, `attrvalue3`, `attrtype4`, `attrvalue4`, `mall`) VALUES (
	'test',
	149,
	1,
	17, 25,   -- ATTBONUS_HUMAN
	22, 35,   -- ATTBONUS_DEVIL,
	32, 175,  -- RESIST_BELL
	33, -150, -- RESIST_FAN
	48, 1,    -- IMMUNE_STUN
	1
);

# See the min-max values for all the bonuses from weapon.
SELECT apply+0 AS `index`, apply AS `name`, lv1 as `min_value`, lv5 as `max_value` 
	FROM `item_attr` WHERE weapon > 0;
	
# See if a specific bonus is included in bonuses of weapon.
SELECT apply, apply+0 FROM `item_attr` WHERE weapon > 0
	AND apply in ('ATTBONUS_HUMAN', 'ATTBONUS_DEVIL', 'RESIST_BELL', 'RESIST_FAN', 'IMMUNE_STUN');

68747470733a2f2f692e6779617a6f2e636f6d2f34303366643931326566353365623535643062386561323166616466343834652e676966

 

2019-10-30 03:48:12 Wednesday

  • Fixed expression is not assignable.
  • Break a for loop after the bonus has found.

 


19301068747470733a2f2f692e6779617a6f2e6319301038222908-7074939e-36f0-11e8-8d09-1
19301038222896-611fc684-36f0-11e8-8535-219301037860642-581cde84-2f32-11e8-9f1e-3


Sockets & attrs

INSERT INTO `player`.`item_award`(`login`, `vnum`, `count`, `given_time`, `why`, `socket0`, `socket1`, `socket2`, `attrtype0`, `attrvalue0`, `attrtype1`, `attrvalue1`, `attrtype2`, `attrvalue2`, `attrtype3`, `attrvalue3`, `attrtype4`, `attrvalue4`, `mall`) VALUES (
	'test',                 -- ACCOUNT_NAME
	12029,                  -- ITEM_VNUM
	1,                      -- ITEM_COUNT
	'2018-03-25 05:53:17',  -- GIVEN_TIME
	'ITEM_SHOP',            -- REASON
	28442, 28441, 28438,    -- SOCKET 1 & 2 & 3
	1, 1500,                -- APPLY_MAX_HP
	29, 10,                 -- APPLY_RESIST_SWORD,
	30, 10,                 -- APPLY_RESIST_TWOHAND
	31, 10,                 -- APPLY_RESIST_DAGGER
	32, 10,                 -- APPLY_RESIST_BELL
	1                       -- MALL
);

For those who use @martysama0134 source:

//@Srcs/Server/db/src/ClientManager.cpp
#define ENABLE_ITEMAWARD_REFRESH // Should be enabled

Github repository or

This is the hidden content, please
:

Edited by Metin2 Dev
Core X - External 2 Internal
  • Metin2 Dev 66
  • Eyes 1
  • Angry 2
  • Cry 1
  • Lmao 2
  • Good 22
  • Love 4
  • Love 51
Link to comment
Share on other sites

  • Forum Moderator

Thanks to @ProfessorEnte for reports.

2019-04-12 02:31:18 Friday 170 additions and 50 deletions.

  • Fixed unique items based on the real time.
  • Fixed unstackable items.
  • Fixed if item count overflow occured, then set it to maximum.
  • Added support for books. (check skill types, unknown skill), skill vnum need to be saved into socket0, (4=Aura of the Sword < player.skill_proto), if the skill vnum is unknown, there will be a random book based on pc races, excluded skills PASSIVE, GUILD, SUPPORT.
  • Added a to-do for ITEM_BLEND, check if apply_type exists in bonuses, check if apply_value/apply_duration is equal with grades (1/2/3/4/5) from settings, blend.txt
  • Added auto query.
# Random book
INSERT INTO player.item_award(`login`, `vnum`, `count`, `mall`) VALUES ('account', 50300, 1, 1); 
# Specific book by skill vnum
INSERT INTO player.item_award(`login`, `vnum`, `count`, `socket0`, `mall`) VALUES ('account', 50300, 1, 4, 1);
  • Love 6
Link to comment
Share on other sites

  • 2 weeks later...
  • Forum Moderator

2019-04-16 14:54:48 Tuesday (Video - Click) -  345 additions and 160 deletions.

  • Added a check for attr types and values min - max.
  • You can't insert wrong bonuses into a specific item.
  • Eg. Add 2000 MAX_HP on your Sword+9, was possible, now not.
  • Eg. Add +500 INT to your shield, now there's a check for min-max value of player.item_attr Lv.1 - Lv.5 and your 500 INT value will be replaced with max value from lvl5 of bonus, like 12 (lv5), that happen with all the bonuses, same thing with the values lower than lvl1, like 5 HP_REGEN on your neck, when the minimum (lv1) is 10, the value will be replaced with 10.
  • If the bonus type can't be added into a specific item, the bonus will be ignored > deleted. (example: critical pct to armor)
  • Refactorized all the code and moved all features into 
    This is the hidden content, please
    .
  • C++11 or higher is required for checking attributes.
Spoiler

# Test unknown types + higher and lower values in game.
INSERT INTO `player`.`item_award`(`login`, `vnum`, `count`, `attrtype0`, `attrvalue0`, `attrtype1`, `attrvalue1`, `attrtype2`, `attrvalue2`, `attrtype3`, `attrvalue3`, `attrtype4`, `attrvalue4`, `mall`) VALUES (
	'test',
	149,
	1,
	17, 25,   -- ATTBONUS_HUMAN
	22, 35,   -- ATTBONUS_DEVIL,
	32, 175,  -- RESIST_BELL
	33, -150, -- RESIST_FAN
	48, 1,    -- IMMUNE_STUN
	1
);

# See the min-max values for all the bonuses from weapon.
SELECT apply+0 AS `index`, apply AS `name`, lv1 as `min_value`, lv5 as `max_value` 
	FROM `item_attr` WHERE weapon > 0;
	
# See if a specific bonus is included in bonuses of weapon.
SELECT apply, apply+0 FROM `item_attr` WHERE weapon > 0
	AND apply in ('ATTBONUS_HUMAN', 'ATTBONUS_DEVIL', 'RESIST_BELL', 'RESIST_FAN', 'IMMUNE_STUN');

 

Edited by Metin2 Dev
Core X - External 2 Internal
  • Metin2 Dev 2
  • Good 1
  • Love 7
Link to comment
Share on other sites

  • 6 months later...
  • Forum Moderator

2019-10-30 03:48:12 Wednesday

  • Fixed expression is not assignable.
  • Break a for loop after the bonus has found.
  • Love 2
Link to comment
Share on other sites

  • 2 years later...
  • Management

I'm having an issue with this and I have no idea what is causing it...

This is what I was able to gather, the issue is coming from this lines:

This is the hidden content, please

I put the code like this:

					DWORD dwSocket2 = pItemAward->dwSocket2;

					sys_err("Socket2 0: %u", dwSocket2);
					sys_err("bType: %d", pItemTable->bType);
					sys_err("bSubType: %d", pItemTable->bSubType);

					if (pItemTable->bType == ITEM_UNIQUE)
					{
#ifdef ENABLE_EXTEND_ITEM_AWARD
						// 12.04.2019 - Correction for unique items based on the real time.
						const long lValue0 = pItemTable->alValues[ITEM_SOCKET_REMAIN_SEC];
						const long lValue2 = pItemTable->alValues[ITEM_SOCKET_UNIQUE_REMAIN_TIME];
						const time_t tNow = CClientManager::instance().GetCurrentTime();
						dwSocket2 = (lValue2 == 0) ? static_cast<DWORD>(lValue0) : static_cast<DWORD>(tNow + lValue0);
						sys_err("Socket2 1: %u", dwSocket2);
#else
						if (pItemAward->dwSocket2 != 0)
							dwSocket2 = pItemAward->dwSocket2;
						else
							dwSocket2 = pItemTable->alValues[0];
#endif
					}

And this is the output:

SYSERR: Jan 14 20:31:34 :: RESULT_SAFEBOX_LOAD: Socket2 0: 28435
SYSERR: Jan 14 20:31:34 :: RESULT_SAFEBOX_LOAD: bType: 16
SYSERR: Jan 14 20:31:34 :: RESULT_SAFEBOX_LOAD: bSubType: 2
SYSERR: Jan 14 20:31:34 :: RESULT_SAFEBOX_LOAD: Socket2 1: 180
SYSERR: Jan 14 20:31:34 :: RESULT_SAFEBOX_LOAD: Query: INSERT INTO item (id, owner_id, item.window, pos, vnum, count, socket0, socket1, socket2, attrtype0, attrvalue0, attrtype1, attrvalue1, attrtype2, attrvalue2, attrtype3, attrvalue3, attrtype4, attrvalue4, attrtype5, attrvalue5, attrtype6, attrvalue6) VALUES(2000000012, 1, 'MALL', 1, 61096, 1, 28433, 28434, 180, 72, 65, 71, 30, 5, 12, 9, 20, 12, 8, 0, 0, 0, 0)

This is the proto of that item:

61096	LaminaXPTO	ITEM_WEAPON	WEAPON_TWO_HANDED	3	ANTI_ASSASSIN | ANTI_SURA | ANTI_MUDANG | ANTI_DROP | ANTI_SELL	ITEM_TUNABLE	WEAR_WEAPON	NONE	0	0	0	0	15	LEVEL	240	LIMIT_NONE	0	APPLY_ATT_SPEED	65	APPLY_ATTBONUS_HUMAN	55	APPLY_CRITICAL_PCT	50	0	550	650	600	700	70	0	3	-1															

This is what I used to create it:

INSERT INTO `player`.`item_award` (`login`, `vnum`, `count`, `socket0`, `socket1`, `socket2`, `attrtype0`, `attrvalue0`, `attrtype1`, `attrvalue1`, `attrtype2`, `attrvalue2`, `attrtype3`, `attrvalue3`, `attrtype4`, `attrvalue4`,  `mall`)
VALUES (
	'admin',	-- LOGIN
	61096,		-- ITEM ID
	1,		-- COUNT
	28433, 28434, 28435,	-- SLOTS
	72, 65,		-- DM
	71, 30,		-- DH,
	5, 12,		-- APPLY_STR
	9, 20,		-- APPLY_CAST_SPEED
	12, 8,		-- APPLY_POISON_PCT
	1		-- LOCATION
);

This is the result on item_award:

id	pid	login	vnum	count	given_time	taken_time	item_id	why	socket0	socket1	socket2	socket3	socket4	socket5	attrtype0	attrvalue0	attrtype1	attrvalue1	attrtype2	attrvalue2	attrtype3	attrvalue3	attrtype4	attrvalue4	attrtype5	attrvalue5	attrtype6	attrvalue6	mall
19	0	admin	61096	1	1000-01-01 00:00:00				28433	28434	28435	0	0	0	72	65	71	30	5	12	9	20	12	8	0	0	0	0	1

And this is what I get when I open the mall:

id	owner_id	window	pos	count	vnum	transmutation	socket0	socket1	socket2	socket3	socket4	socket5	attrtype0	attrvalue0	attrtype1	attrvalue1	attrtype2	attrvalue2	attrtype3	attrvalue3	attrtype4	attrvalue4	attrtype5	attrvalue5	attrtype6	attrvalue6
2000000012	1	MALL	1	1	61096	0	28433	28434	180	0	0	0	72	65	71	30	5	12	9	20	12	8	0	0	0	0

The Socket2 is getting fucked up and I have no clue why. I have no idea how the item type is being assumed as ITEM_UNIQUE.

Anyone has any idea on how to solve it?

For some reason the same db works on my other server and this issue doesn't happen, the only difference is the mysql database.

Thank you

 

16 hours ago, Karbust said:

I'm having an issue with this and I have no idea what is causing it...

This is what I was able to gather, the issue is coming from this lines:

This is the hidden content, please

I put the code like this:

					DWORD dwSocket2 = pItemAward->dwSocket2;

					sys_err("Socket2 0: %u", dwSocket2);
					sys_err("bType: %d", pItemTable->bType);
					sys_err("bSubType: %d", pItemTable->bSubType);

					if (pItemTable->bType == ITEM_UNIQUE)
					{
#ifdef ENABLE_EXTEND_ITEM_AWARD
						// 12.04.2019 - Correction for unique items based on the real time.
						const long lValue0 = pItemTable->alValues[ITEM_SOCKET_REMAIN_SEC];
						const long lValue2 = pItemTable->alValues[ITEM_SOCKET_UNIQUE_REMAIN_TIME];
						const time_t tNow = CClientManager::instance().GetCurrentTime();
						dwSocket2 = (lValue2 == 0) ? static_cast<DWORD>(lValue0) : static_cast<DWORD>(tNow + lValue0);
						sys_err("Socket2 1: %u", dwSocket2);
#else
						if (pItemAward->dwSocket2 != 0)
							dwSocket2 = pItemAward->dwSocket2;
						else
							dwSocket2 = pItemTable->alValues[0];
#endif
					}

And this is the output:

SYSERR: Jan 14 20:31:34 :: RESULT_SAFEBOX_LOAD: Socket2 0: 28435
SYSERR: Jan 14 20:31:34 :: RESULT_SAFEBOX_LOAD: bType: 16
SYSERR: Jan 14 20:31:34 :: RESULT_SAFEBOX_LOAD: bSubType: 2
SYSERR: Jan 14 20:31:34 :: RESULT_SAFEBOX_LOAD: Socket2 1: 180
SYSERR: Jan 14 20:31:34 :: RESULT_SAFEBOX_LOAD: Query: INSERT INTO item (id, owner_id, item.window, pos, vnum, count, socket0, socket1, socket2, attrtype0, attrvalue0, attrtype1, attrvalue1, attrtype2, attrvalue2, attrtype3, attrvalue3, attrtype4, attrvalue4, attrtype5, attrvalue5, attrtype6, attrvalue6) VALUES(2000000012, 1, 'MALL', 1, 61096, 1, 28433, 28434, 180, 72, 65, 71, 30, 5, 12, 9, 20, 12, 8, 0, 0, 0, 0)

This is the proto of that item:

61096	LaminaXPTO	ITEM_WEAPON	WEAPON_TWO_HANDED	3	ANTI_ASSASSIN | ANTI_SURA | ANTI_MUDANG | ANTI_DROP | ANTI_SELL	ITEM_TUNABLE	WEAR_WEAPON	NONE	0	0	0	0	15	LEVEL	240	LIMIT_NONE	0	APPLY_ATT_SPEED	65	APPLY_ATTBONUS_HUMAN	55	APPLY_CRITICAL_PCT	50	0	550	650	600	700	70	0	3	-1															

This is what I used to create it:

INSERT INTO `player`.`item_award` (`login`, `vnum`, `count`, `socket0`, `socket1`, `socket2`, `attrtype0`, `attrvalue0`, `attrtype1`, `attrvalue1`, `attrtype2`, `attrvalue2`, `attrtype3`, `attrvalue3`, `attrtype4`, `attrvalue4`,  `mall`)
VALUES (
	'admin',	-- LOGIN
	61096,		-- ITEM ID
	1,		-- COUNT
	28433, 28434, 28435,	-- SLOTS
	72, 65,		-- DM
	71, 30,		-- DH,
	5, 12,		-- APPLY_STR
	9, 20,		-- APPLY_CAST_SPEED
	12, 8,		-- APPLY_POISON_PCT
	1		-- LOCATION
);

This is the result on item_award:

id	pid	login	vnum	count	given_time	taken_time	item_id	why	socket0	socket1	socket2	socket3	socket4	socket5	attrtype0	attrvalue0	attrtype1	attrvalue1	attrtype2	attrvalue2	attrtype3	attrvalue3	attrtype4	attrvalue4	attrtype5	attrvalue5	attrtype6	attrvalue6	mall
19	0	admin	61096	1	1000-01-01 00:00:00				28433	28434	28435	0	0	0	72	65	71	30	5	12	9	20	12	8	0	0	0	0	1

And this is what I get when I open the mall:

id	owner_id	window	pos	count	vnum	transmutation	socket0	socket1	socket2	socket3	socket4	socket5	attrtype0	attrvalue0	attrtype1	attrvalue1	attrtype2	attrvalue2	attrtype3	attrvalue3	attrtype4	attrvalue4	attrtype5	attrvalue5	attrtype6	attrvalue6
2000000012	1	MALL	1	1	61096	0	28433	28434	180	0	0	0	72	65	71	30	5	12	9	20	12	8	0	0	0	0

The Socket2 is getting fucked up and I have no clue why. I have no idea how the item type is being assumed as ITEM_UNIQUE.

Anyone has any idea on how to solve it?

For some reason the same db works on my other server and this issue doesn't happen, the only difference is the mysql database.

Thank you

Related to my problem from above, and thanks to @ Abel(Tiger) for sending me this post by him: 

This particular problem has been solved, but more issues arose.

First, if I added 3 stones, the 1st and 2nd slot would be set as 1 and only the 3rd would have a stone, that issue has been fixed by changing void ItemAwardManager::CheckItemSocket function's body to this:

void ItemAwardManager::CheckItemSocket(TItemAward & rkItemAward, const TItemTable & rkItemTable)
{
    // check for limited time items
    auto hasTimeLimit = false;
    for (size_t i = 0 ; i < ITEM_LIMIT_MAX_NUM && !hasTimeLimit; i++)
    {
        if (LIMIT_REAL_TIME == rkItemTable.aLimits[i].bType || LIMIT_REAL_TIME_START_FIRST_USE == rkItemTable.aLimits[i].bType)
            hasTimeLimit = true;
    }

    // check slottable sockets for non limited time items
    const auto maxSockets = std::min<int>(rkItemTable.bGainSocketPct, ITEM_SOCKET_MAX_NUM);
    if (maxSockets <= 0 || hasTimeLimit)
        return;

    //This if's have been changed to check if the socket* is 0, and only then set it to 1
    if (maxSockets >= 1 && rkItemAward.dwSocket0 == 0)
        rkItemAward.dwSocket0 = 1;
    if (maxSockets >= 2 && rkItemAward.dwSocket1 == 0)
        rkItemAward.dwSocket1 = 1;
    if (maxSockets >= 3 && rkItemAward.dwSocket2 == 0)
        rkItemAward.dwSocket2 = 1;
}

Then another problem presented itself, if I set socket2 as 0, it wouldn't be changed to 1 on the function above, because it would edit the value on pItemTable and not on the variable dwSocket2 that is used on the query. This issue was fixed by changing this:

//Change the function call with this:
ItemAwardManager::instance().CheckItemSocket(*pItemAward, *pItemTable, &dwSocket2);

//Change the function header on ItemAwardManager.h with this:
void				CheckItemSocket(TItemAward & pkItemAward, const TItemTable & pkItemTable, DWORD *dwSocket2);

//Change the function body with this:
void ItemAwardManager::CheckItemSocket(TItemAward & rkItemAward, const TItemTable & rkItemTable, DWORD *dwSocket2)
{
    // check for limited time items
    auto hasTimeLimit = false;
    for (size_t i = 0 ; i < ITEM_LIMIT_MAX_NUM && !hasTimeLimit; i++)
    {
        if (LIMIT_REAL_TIME == rkItemTable.aLimits[i].bType || LIMIT_REAL_TIME_START_FIRST_USE == rkItemTable.aLimits[i].bType)
            hasTimeLimit = true;
    }

    // check slottable sockets for non limited time items
    const auto maxSockets = std::min<int>(rkItemTable.bGainSocketPct, ITEM_SOCKET_MAX_NUM);
    if (maxSockets <= 0 || hasTimeLimit)
        return;

    if (maxSockets >= 1 && rkItemAward.dwSocket0 == 0)
        rkItemAward.dwSocket0 = 1;
    if (maxSockets >= 2 && rkItemAward.dwSocket1 == 0)
        rkItemAward.dwSocket1 = 1;
    if (maxSockets >= 3 && rkItemAward.dwSocket2 == 0) {
        rkItemAward.dwSocket2 = 1;
        *dwSocket2 = 1;
    }
}

Then another problem come up, ITEM_UNIQUE would always replace the value you set on socket2 by the default value of the item, and to fix this, just change:

//This:
if (pItemTable->bType == ITEM_UNIQUE)

//With this:
if (pItemTable->bType == ITEM_UNIQUE && pItemAward->dwSocket2 == 0)

Hope this helps someone.

Edited by Karbust
  • Metin2 Dev 13
  • Good 2
  • Love 3

raw

raw

Link to comment
Share on other sites

Announcements



×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.