Jump to content

xXIntelXx

Member
  • Posts

    37
  • Joined

  • Last visited

  • Days Won

    1

xXIntelXx last won the day on March 23

xXIntelXx had the most liked content!

2 Followers

About xXIntelXx

Informations

  • Gender
    Not Telling

Recent Profile Visitors

654 profile views

xXIntelXx's Achievements

Contributor

Contributor (5/14)

  • Reacting Well Rare
  • Dedicated Rare
  • First Post
  • Collaborator
  • Conversation Starter

Recent Badges

54

Reputation

  1. For a second I was thinking "this crash feels familiar.." and yep For a system I made I had not to include some items in the table and sometimes the game would crash and found out about this stupid thing as well.
  2. Little lag fix when sending the packet: //TARGET INFO void CInputMain::TargetInfoLoad(LPCHARACTER ch, const char* c_pData) { TPacketCGTargetInfoLoad* p = (TPacketCGTargetInfoLoad*)c_pData; TPacketGCTargetInfo pInfo; TEMP_BUFFER buf; //ADD THIS pInfo.header = HEADER_GC_TARGET_INFO; static std::vector<std::tuple<int,int,int>> s_vec_item; //IGNORE THIS LINE s_vec_item.clear(); LPCHARACTER m_pkChrTarget = CHARACTER_MANAGER::instance().Find(p->dwVID); if (!ch || !m_pkChrTarget) return; if ((m_pkChrTarget->IsMonster() || m_pkChrTarget->IsStone() || m_pkChrTarget->IsBoss()) && ITEM_MANAGER::instance().CreateDropItemVector(m_pkChrTarget, ch, s_vec_item)) //IGNORE THE ISBOSS() FUNCTION { for(auto x : s_vec_item) //IGNORE THIS LINE { pInfo.dwVID = m_pkChrTarget->GetVID(); //IGNORE THIS LINE pInfo.race = m_pkChrTarget->GetRaceNum(); //IGNORE THIS LINE pInfo.dwVnum = std::get<0>(x); //IGNORE THIS LINE pInfo.count = std::get<1>(x); //IGNORE THIS LINE pInfo.rarity = std::get<2>(x); //IGNORE THIS LINE buf.write(&pInfo, sizeof(pInfo)); //ADD THIS //ch->GetDesc()->Packet(&pInfo, sizeof(TPacketGCTargetInfo)); //REMOVE THIS ch->GetDesc()->BufferedPacket(&pInfo, sizeof(TPacketGCTargetInfo)); //ADD THIS } ch->GetDesc()->Packet(buf.read_peek(), buf.size()); //ADD THIS AFTER THE FOR CYCLE } } If anyone is curious about my rarity calculations: int CalculateDropRarityCommonDropItem(int x) { int pct = x; int rarity = 0; if(pct >= 4000000) rarity = 1; else if(pct < 40000000 && pct >= 200000 ) rarity = 2; else if(pct < 200000 && pct >= 10000 ) rarity = 3; else if(pct < 10000 && pct >= 5000 ) rarity = 4; else if(pct < 5000 && pct >= 1000 ) rarity = 5; else if(pct < 1000 && pct >= 0 ) rarity = 6; return rarity; } int CalculateDropRarityKillDrop(int x, BYTE bType) { int pct = x; int rarity = 0; if(pct == 1) rarity = 1; else if(pct > 1 && pct <= 300 ) rarity = 2; else if(pct > 300 && pct <= 500 ) rarity = 3; else if(pct > 500 && pct <= 2000 ) rarity = 4; else if(pct > 2000 && pct <= 5000 ) rarity = 5; else if(pct > 5000 ) rarity = 6; return rarity; } int CalculateDropRarityDropItemGroup(int x, BYTE bType) { int pct = x; int rarity = 0; switch(bType) { case CHAR_TYPE_BOSS: { if(pct >= 4000000) rarity = 1; else if(pct < 4000000 && pct >= 2600000 ) //100~65 rarity = 2; else if(pct < 2600000 && pct >= 1600000 ) //65~40 rarity = 3; else if(pct < 1600000 && pct >= 1000000 ) //40~25 rarity = 4; else if(pct < 1000000 && pct >= 600000 ) //25~15 rarity = 5; else if(pct < 600000 ) rarity = 6; } break; case CHAR_TYPE_MONSTER: { if(pct >= 4000000) rarity = 1; else if(pct < 4000000 && pct >= 1600000 ) //100~40 rarity = 2; else if(pct < 1600000 && pct >= 800000 ) //40~20 rarity = 3; else if(pct < 800000 && pct >= 200000 ) //20~5 rarity = 4; else if(pct < 200000 && pct >= 20000 ) //5~0.5 rarity = 5; else if(pct < 20000 ) rarity = 6; } break; case CHAR_TYPE_STONE: { if(pct >= 4000000) rarity = 1; else if(pct < 4000000 && pct >= 2000000 ) //100~50 rarity = 2; else if(pct < 2000000 && pct >= 1000000 ) //50~25 rarity = 3; else if(pct < 1000000 && pct >= 600000 ) //25~15 rarity = 4; else if(pct < 600000 && pct >= 200000 ) //15~5 rarity = 5; else if(pct < 200000 ) rarity = 6; } break; default: { if(pct >= 4000000) rarity = 1; else if(pct < 4000000 && pct >= 2000000 ) //100~50 rarity = 2; else if(pct < 2000000 && pct >= 1000000 ) //50~25 rarity = 3; else if(pct < 1000000 && pct >= 600000 ) //25~15 rarity = 4; else if(pct < 600000 && pct >= 200000 ) //15~5 rarity = 5; else if(pct < 200000 ) rarity = 6; } break; } return rarity; } int CalculateDropRarityLevelItemGroup(float x, BYTE bType) { float pct = x / 10000.0000; int rarity = 0; switch(bType) { case CHAR_TYPE_BOSS: { if(pct >= 100.0000) rarity = 1; else if(pct < 100.0000 && pct >= 65.0000 ) rarity = 2; else if(pct < 65.0000 && pct >= 40.0000 ) rarity = 3; else if(pct < 40.0000 && pct >= 25.0000 ) rarity = 4; else if(pct < 25.0000 && pct >= 15.0000 ) rarity = 5; else if(pct < 15.0000 ) rarity = 6; } break; case CHAR_TYPE_STONE: { if(pct >= 100.0000) rarity = 1; else if(pct < 100.0000 && pct >= 50.0000 ) rarity = 2; else if(pct < 50.0000 && pct >= 25.0000 ) rarity = 3; else if(pct < 25.0000 && pct >= 15.0000 ) rarity = 4; else if(pct < 15.0000 && pct >= 5.0000 ) rarity = 5; else if(pct < 5.0000 ) rarity = 6; } break; case CHAR_TYPE_MONSTER: { if(pct >= 100.0000) rarity = 1; else if(pct < 100.0000 && pct >= 30.0000 ) rarity = 2; else if(pct < 30.0000 && pct >= 15.0000 ) rarity = 3; else if(pct < 15.0000 && pct >= 1.0000 ) rarity = 4; else if(pct < 1.0000 && pct >= 0.1000 ) rarity = 5; else if(pct < 0.1000 ) rarity = 6; } break; default: { if(pct >= 100.0000) rarity = 1; else if(pct < 100.0000 && pct >= 65.0000 ) rarity = 2; else if(pct < 65.0000 && pct >= 40.0000 ) rarity = 3; else if(pct < 40.0000 && pct >= 25.0000 ) rarity = 4; else if(pct < 25.0000 && pct >= 15.0000 ) rarity = 5; else if(pct < 15.0000 ) rarity = 6; } } return rarity; } you can replace the switch statement with some ifs and use IsStone()/IsMonster() (and check the rank of the mob). Also if you wanna be even more precise on the rarity, there could be a check on the vnum of the monster, and decide also by the quantity of the monster (if there are 1kk of a monster and pct is 0.5, it definitely it's easier than finding an item among 100 monsters but honestly cba about that LOL)
  3. remove typedef struct _SQLMsg SQLMsg; in guild.h and include db.h
  4. Ooooh , that one is a compleeetely different thing, in theory it should work that the bonus is a chance for the double drop, but yeah, it's completely missing in every file LOL. Also for some reason DOUBLE_EXP_BONUS is iExp += iExp * 30 / 100; Legit this game is a fucking lie lol
  5. Mh, from my sources: // ADD_PREMIUM if (pkKiller->IsEquipUniqueGroup(UNIQUE_GROUP_DOUBLE_ITEM)) { LPITEM pkItemDrop = pkKiller->GetEquipUniqueGroup(UNIQUE_GROUP_DOUBLE_ITEM); unsigned int pct_from_item = 0; float pct_bonus = 0.0; if(pkItemDrop != nullptr) { pct_from_item += pkItemDrop->GetValue(1); pct_bonus = (static_cast<float>(pct_from_item) / 100.0) * static_cast<float>(iDeltaPercent); } iDeltaPercent += pct_bonus; } if(pkKiller->GetMarriageBonus(UNIQUE_ITEM_MARRIAGE_DROP_BONUS)) { float pct_bonus = (static_cast<float>(pkKiller->GetMarriageBonus(UNIQUE_ITEM_MARRIAGE_DROP_BONUS)) / 100.0) * static_cast<float>(iDeltaPercent); iDeltaPercent += pct_bonus; } // END_OF_ADD_PREMIUM and UNIQUE_GROUP_DOUBLE_ITEM is taken from special_item_group: Group gloves { Vnum 10002 1 72004 1 1.00 2 72005 1 1.00 3 72006 1 1.00 4 100874 1 1.00 5 100875 1 1.00 } usually it's iDeltaPercent += iDeltaPercent; but since I have different pcts and still only one of them can be equipped I get the pct from the item_proto
  6. No, I mean, I agree. It's a pain in the ass everytime being with a calculator and be like "ok, I want idk, 13.7% but I have to do *4 and so it's 54.8% bla bla bla". For other type of drops indeed, I just used the level limit logic, disregarding the iRandRange. The issue? It doesn't take the priv_drop into account. Performance wise, instead, I found an interesting page on stack overflow: [Hidden Content]
  7. Nice one, but this doesn't solve the "why they do this for 0.1%". They basically do a random of a long range to "emulate" it, for ex in common_drop_item, 0.1% would be: (0.4*10000)/4000000 = 0.001->0.1%, because at the end, we are still using natural numbers ( DWORD dwPct = (DWORD) (d[i].fPercent * 10000.0f);) One possible thing to do would be to rewrite the droppct logic to calculate differently deltapercent and irandrange (which would be your max_range) and use uniform_real_distribution instead of uniform_int_distribution (so that you can use floats/dobules/long doubles and just put the actual percentage you want (as long as irandrange is 100.0). I mean, u can still do it using their logic (and uniform_int_distribution), just remembering that the effective pct is 1/4th of what you put in the txts (unless it's type level limit).
  8. Why? Why not? Seriously though, why? I was legit just bored. Ok, first of all, we need to indicate to Visual Studio that we wanna compile with the flag /std:c++17. You do so by selecting all the projects on the right and clicking properties: and click on Apply (duh) Then let's fix the first issue, the introduction of std::byte. For some reason (and you should never ever ever ever ever ever do it), there are some: using namespace std; in the code. DELETE. THEM. ALL. Now compile. Yeah, it's not over, because now, we should edit all the std functions (make_pair, string, declarations of maps, vectors etc.) adding std:: before, for ex: operator const string() const { return m_sRaw; } becomes operator const std::string() const { return m_sRaw; } just compile and fix them all whenever you find them. A few of them are more "difficult". Open Stl.h in EterBase and there's gonna be: namespace std { template <class _Ty> class void_mem_fun_t : public unary_function<_Ty *, void> { public: explicit void_mem_fun_t(void (_Ty::*_Pm)()) : _Ptr(_Pm) {} void operator()(_Ty *_P) const {((_P->*_Ptr)()); } private: void (_Ty::*_Ptr)(); }; template<class _Ty> inline void_mem_fun_t<_Ty> void_mem_fun(void (_Ty::*_Pm)()) {return (void_mem_fun_t<_Ty>(_Pm)); } template<class _Ty> class void_mem_fun_ref_t : public unary_function<_Ty, void> { public: explicit void_mem_fun_ref_t(void (_Ty::*_Pm)()) : _Ptr(_Pm) {} void operator()(_Ty& _X) const {return ((_X.*_Ptr)()); } private: void (_Ty::*_Ptr)(); }; template<class _Ty> inline void_mem_fun_ref_t<_Ty> void_mem_fun_ref(void (_Ty::*_Pm)()) {return (void_mem_fun_ref_t< _Ty>(_Pm)); } // TEMPLATE CLASS mem_fun1_t template<class _R, class _Ty, class _A> class void_mem_fun1_t : public binary_function<_Ty *, _A, _R> { public: explicit void_mem_fun1_t(_R (_Ty::*_Pm)(_A)) : _Ptr(_Pm) {} _R operator()(_Ty *_P, _A _Arg) const {return ((_P->*_Ptr)(_Arg)); } private: _R (_Ty::*_Ptr)(_A); }; // TEMPLATE FUNCTION mem_fun1 template<class _R, class _Ty, class _A> inline void_mem_fun1_t<_R, _Ty, _A> void_mem_fun1(_R (_Ty::*_Pm)(_A)) {return (void_mem_fun1_t<_R, _Ty, _A>(_Pm)); } } fucking remove this shit. Then replace all the: std::void_mem_fun with std::mem_fn Then in cipher.cpp replace std::auto_ptr into std::unique_ptr and then boost is gonna come busting our ass, so just upgrade the folder downloading the last version and..nope: Alright, I'd suggest to just disable this error: How to disable by Microsoft (do it for every project causing this error) If you fix boost's code, kudos to you. Then, after a lot of: from Python, it should be compiled. If you have ikarus offline shop, you should recompile libconfig with the same settings (probably cryptopp aswell? Honestly I can't remember)
  9. Yes, it was. The whole thing is a mess (even this way, it still is a mess). Also, I don't know if he did the same (going for a quick look into point change arguments, maybe), but this might fix the lag caused by the dispel skill.
  10. Gotta check on char_affect.cpp for IS_NO_CLEAR_ON_DEATH_AFFECT, and add the buffs you want to stay after the character's death. Be aware that in this case, the buffs will stay on even in PvP. If you wanna avoid that, on the top of my head, you could do this: go on char_battle.cpp and search for ClearAffect(true); in void CHARACTER::Dead(LPCHARACTER pkKiller, bool bImmediateDead) and edit the line like this: if (pkKiller && IsPC()) ClearAffect(true, true); else ClearAffect(true, false); then edit void CHARACTER::ClearAffect(bool bSave) in char_affect.cpp into: void CHARACTER::ClearAffect(bool bSave, bool bIsPC) then in the function check for while (it != m_list_pkAffect.end()) and edit like this: while (it != m_list_pkAffect.end()) { CAffect * pkAff = *it; if (bSave) { if(bIsPC) { if ( IS_NO_CLEAR_ON_DEATH_AFFECT_PC(pkAff->dwType) || IS_NO_SAVE_AFFECT(pkAff->dwType)) //add the others that you might previously have had { ++it; continue; } } else if(!bIsPC) { if ( IS_NO_CLEAR_ON_DEATH_AFFECT(pkAff->dwType) || IS_NO_SAVE_AFFECT(pkAff->dwType)) //add the others that you might previously have had { ++it; continue; } } if (IsPC()) { SendAffectRemovePacket(GetDesc(), GetPlayerID(), pkAff->dwType, pkAff->bApplyOn, pkAff->dwFlag); } } ComputeAffect(pkAff, false); it = m_list_pkAffect.erase(it); CAffect::Release(pkAff); } if (afOld != m_afAffectFlag || wMovSpd != GetPoint(POINT_MOV_SPEED) || wAttSpd != GetPoint(POINT_ATT_SPEED)) UpdatePacket(); CheckMaximumPoints(); if (m_list_pkAffect.empty()) event_cancel(&m_pkAffectEvent); } Copy IS_NO_CLEAR_ON_DEATH_AFFECT into a new line and edit the name into IS_NO_CLEAR_ON_DEATH_AFFECT_PC where you remove the buffs that you want to remove in PvP. And finally, edit the function in char.h: void ClearAffect(bool bSave=false, bool bIsPC = false); might also wanna check where ClearAffect is used and edit as you see fit
  11. probably 2 is too low of a number but I have no idea why that thing would go up in the air ahah
  12. wait, how 130x99 are local and 450*99 are global? No way my dude ahah 130x99 are the coords u see in the minimap I suppose. Just add *100 + the basecoords of the map at those coords. Let's say the map has coordinates 153600*1203200 CHARACTER_MANAGER::instance().SpawnMob(20375, GetMapIndex(), 130*100 + 153600 , 99*100 + 1203200, 2, false, -1, true); /* 130 = local_x *100 = "global" 153600 = base_x of the map, the one in Settings.txt 99 = local_y *100 = "global" 1203200 = base_y of the map, the one in Settings.txt */ which basically are the coordinates when you do /warp
  13. usually you could just add *100 also my bad, mob_spawn (lua) uses local coords (no sleep vision problems lol)
  14. yeah but you said you spawn it from sources: CHARACTER_MANAGER::instance().SpawnMob(20375, GetMapIndex(), 130, 99, 2, false, -1, true); now, I don't know if the coords are random or not, but if they are not, just go into the map, and get the coords with the warp command warping to yourself. Otherwise, in a quest, mob_spawn uses global coords, dungeon_spawn_mob uses local coords
×
×
  • 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.