barselon8 0 Report post Posted March 28, 2022 Can someone explain these calculations? --Attributes Growth Rate of Newbie Class Mxhp_con_rad1[JOB_TYPE_XINSHOU], Mxhp_con_rad2[JOB_TYPE_XINSHOU], Mxhp_lv_rad[JOB_TYPE_XINSHOU] = 3, 2, 15 Mxsp_sta_rad1[JOB_TYPE_XINSHOU], Mxsp_sta_rad2[JOB_TYPE_XINSHOU], Mxsp_lv_rad[JOB_TYPE_XINSHOU] = 1, 0, 3 Mnatk_str_rad1[JOB_TYPE_XINSHOU], Mnatk_str_rad2[JOB_TYPE_XINSHOU], Mnatk_dex_rad1[JOB_TYPE_XINSHOU], Mnatk_dex_rad2[JOB_TYPE_XINSHOU] = 1.5, 0.4, 0, 0 Mxatk_str_rad1[JOB_TYPE_XINSHOU], Mxatk_str_rad2[JOB_TYPE_XINSHOU], Mxatk_dex_rad1[JOB_TYPE_XINSHOU], Mxatk_dex_rad2[JOB_TYPE_XINSHOU] = 1.5, 0.4, 0, 0 Def_con_rad1[JOB_TYPE_XINSHOU], Def_con_rad2[JOB_TYPE_XINSHOU] = 0.1, 0.1 Hit_dex_rad1[JOB_TYPE_XINSHOU], Hit_dex_rad2[JOB_TYPE_XINSHOU] = 0.6, 0 Flee_agi_rad1[JOB_TYPE_XINSHOU], Flee_agi_rad2[JOB_TYPE_XINSHOU] = 0.6, 0 Mf_luk_rad[JOB_TYPE_XINSHOU] = 0.39 Crt_luk_rad[JOB_TYPE_XINSHOU] = 0.31 Hrec_bsmxhp_rad[JOB_TYPE_XINSHOU], Hrec_con_rad[JOB_TYPE_XINSHOU] = 1/200, 1/8 Srec_bsmxsp_rad[JOB_TYPE_XINSHOU], Srec_sta_rad[JOB_TYPE_XINSHOU] = 1/100, 1/12 - Aspd_agi_rad[JOB_TYPE_XINSHOU] = 1.1 Str_updata[JOB_TYPE_XINSHOU] = 0.2 Dex_updata[JOB_TYPE_XINSHOU] = 0.1 Con_updata[JOB_TYPE_XINSHOU] = 0.6 Agi_updata[JOB_TYPE_XINSHOU] = 0.1 Sta_updata[JOB_TYPE_XINSHOU] = 0.1 Luk_updata[JOB_TYPE_XINSHOU] = 0.1 Quote Share this post Link to post Share on other sites
Lua 35 Report post Posted March 28, 2022 Check this guide 2 Quote Share this post Link to post Share on other sites
barselon8 0 Report post Posted March 29, 2022 So, I understand that if we increase our attribute like con by 1 then there is a 60% chance we get +6 to our max health or 40% chance we get +9 to max health. However, how does it work with equipment that has +8 con for example? How does it calculate it? Does it always use the first value in that case? (+6 per each con) Quote Share this post Link to post Share on other sites
Jonathan 35 Report post Posted March 29, 2022 @barselon8 If I am understanding correctly, you want to investigate the functions "Mxhp_final()", "Mxsp_final()", "Mnatk_final()", etc. in "functions.lua". e.g. function Mxhp_final(a) local mxhp_final=(BSMxhp(a) * MxhpIa(a) + MxhpIb(a) ) * math.max(0, MxhpSa(a)) + MxhpSb(a) --[[取当时实际mxhp]]-- --LG("chaattr_set", " BSMxhp = " , BSMxhp(a) , "MxhpIa = " , MxhpIa(a) , " MxhpIb = " , MxhpIb(a) , "MxhpSa = " , MxhpSa(a) , "MxhpSb = ", MxhpSb(a) , "\n" ) --LG("chaattr_set", "mxhp_final = ", mxhp_final , "\n" ) return mxhp_final end These functions are where the final values are calculated, which account for any additional stats provided by items. 1 1 Quote Share this post Link to post Share on other sites
barselon8 0 Report post Posted March 29, 2022 @Jonathan Thank you! Is there an interpretation somewhere of what some of those variables mean? Quote Share this post Link to post Share on other sites
Jonathan 35 Report post Posted March 29, 2022 No problem @barselon8. Which variables specifically are you referring to? 1 Quote Share this post Link to post Share on other sites
barselon8 0 Report post Posted March 29, 2022 @Jonathan I am interested in replicating this calculation in Unreal Engine 5. So, the more details I have, the better local mxhp_final=(BSMxhp(a) * MxhpIa(a) + MxhpIb(a) ) * math.max(0, MxhpSa(a)) + MxhpSb(a). I need to know how these values are calculated and what they are. Quote Share this post Link to post Share on other sites
Jonathan 35 Report post Posted March 29, 2022 @barselon8 The only variable there is the "a", which is the character's role. The rest are all function calls to functions you can find within "functions.lua". e.g. function MxhpIa(a) --LuaPrint("Obtain character attribute mxhp_ia") local mxhpia=GetChaAttr(a, ATTR_ITEMC_MXHP)/ATTR_RADIX --[[取mxhp道具百分比]]-- return mxhpia end function MxhpIb(a) --LuaPrint("Obtain character attribute mshp_ib") local mxhpib=GetChaAttr(a, ATTR_ITEMV_MXHP) --[[取mxhp道具常数]]-- return mxhpib end In these functions, the first variable in the call to "GetCharAttr()" is again the character's role, and the second variable in those calls is the attribute being retrieved as defined in "AttrType.lua". The "ATTR_RADIX" variable is the attribute coefficient as defined in "variable.lua". 1 Quote Share this post Link to post Share on other sites
barselon8 0 Report post Posted March 29, 2022 @Jonathan Yeah, I saw those functions. Couldn't understand what "ATTR_RADIX" but now it makes sense. Thank you! So, to translate ATTR_ITEMC_MXHP is MAXHP derived from items divided by 1000? Interesting math. Quote Share this post Link to post Share on other sites
barselon8 0 Report post Posted March 29, 2022 @Jonathan do you know where the calculations are for ATTR_ITEMC_MXHP? Quote Share this post Link to post Share on other sites
Jonathan 35 Report post Posted March 29, 2022 @barselon8 It is interesting math - I could be entirely wrong, but I would guess the reason for dividing by 1000 is to avoid using floats / doubles until absolutely necessary. This will have a positive impact on evaluating final values accurately, and also - more importantly - will reduce computational time. I'd imagine the performance differences were far more noticeable back when this game was first published. Looking at "GetChaAttr()" in the source, all values returned are whole numbers (either ints or longs) which further supports this idea. With regards to where the calculations are for "ATTR_ITEMC_MXHP"... "GetChaAttr() is in the source at "Source/Server/GameServer/src/Expand.h". This just points us to "nAttrVal = (long)pCCha->getAttr(sAttrIndex);". If we then follow the trail to "Source/Common/Common/include/ChaAttr.h" this points us to: inline LONG64 CChaAttr::GetAttr(long lNo) {T_B if (lNo >= ATTR_MAX_NUM) return -1; return m_lAttribute[lNo]; T_E} which begs the question of where "m_lAttribute" gets set. Navigating to "Source/Common/Common/src/ChaAttr.cpp" we find that the values in "m_lAttribute" are set based on the record retrieved via "CChaRecord *pCChaRecord = GetChaRecordInfo(lID);". In "Source/Common/Common/include/CharacterRecord.h" we find another inline function: inline CChaRecord* GetChaRecordInfo( int nTypeId ) { return (CChaRecord*)CChaRecordSet::I()->GetRawDataInfo(nTypeID); } and so on... that is the end of my sleuthing on this, but that should be fairly close to actually finding where the value gets set. Good luck! 2 Quote Share this post Link to post Share on other sites