Forum Moderator VegaS™ 10276 Posted April 9, 2019 Forum Moderator Share Posted April 9, 2019 (edited) M2 Download Center This is the hidden content, please Sign In or Sign Up ( Internal ) This is the hidden content, please Sign In or Sign Up ( GitHub ) Metin2 Extended Item Award You can store all bonuses and stones for items. I wrote that as request from @ProfessorEnte, more 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 Sign In or Sign Up . 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'); 2019-10-30 03:48:12 Wednesday Fixed expression is not assignable. Break a for loop after the bonus has found. 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 Sign In or Sign Up : This is the hidden content, please Sign In or Sign Up Edited September 6, 2022 by Metin2 Dev Core X - External 2 Internal 70 1 2 1 2 24 4 54 Check my GitHub Profile Click to find all the threads started by me [TOOL] Text file loader + JSON Link to comment Share on other sites More sharing options...
Catii 94 Posted April 9, 2019 Share Posted April 9, 2019 usefull as allways Link to comment Share on other sites More sharing options...
Forum Moderator VegaS™ 10276 Posted April 13, 2019 Author Forum Moderator Share Posted April 13, 2019 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); 6 Check my GitHub Profile Click to find all the threads started by me [TOOL] Text file loader + JSON Link to comment Share on other sites More sharing options...
.ZeNu 3112 Posted April 13, 2019 Share Posted April 13, 2019 Nice release, good contribution for community. 1 Link to comment Share on other sites More sharing options...
Forum Moderator VegaS™ 10276 Posted April 22, 2019 Author Forum Moderator Share Posted April 22, 2019 (edited) 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 Sign In or Sign Up . 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 August 27, 2022 by Metin2 Dev Core X - External 2 Internal 2 1 7 Check my GitHub Profile Click to find all the threads started by me [TOOL] Text file loader + JSON Link to comment Share on other sites More sharing options...
metin2team 766 Posted April 25, 2019 Share Posted April 25, 2019 As always, your contributions are among the best ones. Link to comment Share on other sites More sharing options...
Forum Moderator VegaS™ 10276 Posted November 16, 2019 Author Forum Moderator Share Posted November 16, 2019 2019-10-30 03:48:12 Wednesday Fixed expression is not assignable. Break a for loop after the bonus has found. 2 Check my GitHub Profile Click to find all the threads started by me [TOOL] Text file loader + JSON Link to comment Share on other sites More sharing options...
Management Karbust 4885 Posted January 14, 2022 Management Share Posted January 14, 2022 (edited) 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 Sign In or Sign Up 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 Sign In or Sign Up 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 January 14, 2022 by Karbust 13 2 3 Link to comment Share on other sites More sharing options...
Recommended Posts