Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won

  • Yangs

    1,565 [ Donate ]
  • Country


VegaS™ last won the day on March 26

VegaS™ had the most liked content!

Community Reputation

978 Unstoppable

About VegaS™

Contact Methods

  • Website URL
  • Discord
  • Skype

Profile Information

  • Gender
  • Location
  • Steam ID


  • C++
  • LUA
  • Python
  • PHP
  • SQL
  • JavaScript

Recent Profile Visitors

10,532 profile views
  1. PythonCharacterManager.cpp Search for: if (fRadiusDistance < 1500.0f) m_vecTargetInstance.push_back(pkInstTarget); Replace it with: // Default distance float fCheckDistance = 1500.0f; const std::initializer_list<BYTE> vecWeaponTypes = { CItemData::WEAPON_BOW, CItemData::WEAPON_ARROW, #ifdef ENABLE_QUIVER_SYSTEM CItemData::WEAPON_QUIVER #endif }; // Distance based on weapon type if (std::find(vecWeaponTypes.begin(), vecWeaponTypes.end(), pkInstMain->GetWeaponType()) != vecWeaponTypes.end()) fCheckDistance = 2400.0f; if (fRadiusDistance < fCheckDistance) m_vecTargetInstance.push_back(pkInstTarget);
  2. class okno(ui.BoardWithTitleBar): def __init__(self): You forgot to initialize the BoardWithTitleBar class: ui.BoardWithTitleBar.__init__(self) For adding a button you can use: ui.MakeButton(parent, x, y, tooltipText, path, up, over, down) Also for importing excepting modules you could do something better: for (moduleName, shortModuleName) in (('playerm2g2', 'player'), ('chatm2g', 'chat'), ('chrmgrm2g', 'chrmgr')): try: module = __import__(moduleName) except: module = __import__(shortModuleName) globals()[shortModuleName] = module So, this is the whole script: import ui, app, time, chr, math, playerSettingModule for (moduleName, shortModuleName) in (('playerm2g2', 'player'), ('chatm2g', 'chat'), ('chrmgrm2g', 'chrmgr')): try: module = __import__(moduleName) except: module = __import__(shortModuleName) globals()[shortModuleName] = module class MyBoard(ui.BoardWithTitleBar): def __init__(self): ui.BoardWithTitleBar.__init__(self) self.SetTitleName('First Window') self.SetSize(150, 150) self.SetCenterPosition() self.AddFlag("movable") self.children = [] for i in range(2): button = ui.MakeButton(self, 10 + (i * 70), self.GetHeight()-30, "ToolTip {}".format(i), "d:/ymir work/ui/public/", "middle_button_01.sub", "middle_button_02.sub", "middle_button_03.sub") button.SetText("Button{}".format(i)) button.SAFE_SetEvent(self.__OnClickButton, i) self.children.append(button) self.Show() def __del__(self): ui.BoardWithTitleBar.__del__(self) def __OnClickButton(self, button): chat.AppendChat(7, str(button)) instance = MyBoard() instance.Show()
  3. I'm sure that are his hands.. @DevChuckNorris
  4. https://en.cppreference.com/w/cpp/string/byte/memcmp #define ITEM_SOCKET_MAX_NUM 3 int main() { long lSockets[ITEM_SOCKET_MAX_NUM] = { 1, 2, 3 }; long lSockets2[ITEM_SOCKET_MAX_NUM] = { 1, 2, 3 }; cout << (memcmp(lSockets, lSockets2, sizeof(long) * ITEM_SOCKET_MAX_NUM) == 0) << endl; return 0; } //>> 1
  5. For those who need FN_compare_item_socket function and also with fixed memory leak which already is public. Srcs/game/src/char_item.cpp 1.0) Add at the beginning of file: static bool FN_compare_item_socket(const LPITEM pkItemSrc, const LPITEM pkItemDest) { if (!pkItemSrc || !pkItemDest) return false; return memcmp(pkItemSrc->GetSockets(), pkItemDest->GetSockets(), sizeof(long) * ITEM_SOCKET_MAX_NUM) == 0; } 2.0) Search for: 2.1) Replace it with: if (inv_item->GetType() == ITEM_BLEND && inv_item->GetVnum() == item->GetVnum()) { const DWORD dwTotalCount = inv_item->GetCount() + item->GetCount(); if (dwTotalCount <= ITEM_MAX_COUNT && FN_compare_item_socket(inv_item, item)) { inv_item->SetCount(dwTotalCount); M2_DESTROY_ITEM(item); return inv_item; } }
  6. You can do it directly with python, without doing a new function in binary. item.SelectItem(changelookvnum) print(item.GetItemName()) And if you really need it, you can do it as: PyObject * itemGetItemNameByVnum(PyObject * poSelf, PyObject * poArgs) { int iIndex; if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) return Py_BadArgument(); CItemData * pItemData; if (!CItemManager::Instance().GetItemDataPointer(iIndex, &pItemData)) return Py_BuildException("no item data pointer"); return Py_BuildValue("s", pItemData->GetName()); }
  7. @PACI That's right, i just wrote it fast without thinking about current pc and selected one. So basically after i checked again, seems that the're two ways to get this: You don't have a party at all. You've a party but your leader is offline and his character pointer is marked as null pointer since he got disconnected. I think that's why @Gurgarath said it's very rarely this crash, because of offline>null leader and trying to access the function GetVID() of it. So, if you want to show a message in game while doing the action, you could put this check before accessing the vid and do something with it, players will know that they doesn't satisfy one of these conditions. if (npc.get_leader_vid() == 0) then syschat("You don't have a party or the leader is offline.") return end And you need to modify the function like this for being able to do this check. int npc_get_leader_vid(lua_State * L) { const LPCHARACTER npc = CQuestManager::instance().GetCurrentNPCCharacterPtr(); const LPPARTY pkParty = npc ? npc->GetParty() : NULL; lua_pushnumber(L, pkParty && pkParty->GetLeader() ? pkParty->GetLeader()->GetVID() : 0); return 1; }
  8. Thanks for the fix, ymir left a lot of shits like these, this is an official quest example where you could get this crash core. Normally, if you want to get the party leader vid in some functions, of course we need to check if there's a party before accessing the function and don't even call it. You just have to use party.is_party before calling the function and everything will be fine, also you could put a message in your quests that player will know there's a problem (not just an error in server side that you will don't know where it comes from). So with that everybody will know that they're missing a condition and will stop the event/dungeon or something else. if not party.is_party() then syschat("You need a party for doing this.") return end This is an example of how should be the quest: (based on official example < spiderKingEgg) when 8002.kill with party.is_party() begin local npc_leader_vid = npc.get_leader_vid() syschat(string.format("%d", npc_leader_vid)) end So, by doing that you can leave the function without the syserr which is irrelevant since is a condition from game and if something happens the result will be 0 all time. int npc_get_leader_vid(lua_State * L) { const LPCHARACTER npc = CQuestManager::instance().GetCurrentNPCCharacterPtr(); const LPPARTY pkParty = (npc) ? npc->GetParty() : NULL; const LPCHARACTER pkChrLeader = (pkParty) ? pkParty->GetLeader() : NULL; lua_pushnumber(L, (pkChrLeader) ? pkChrLeader->GetVID() : 0); return 1; }
  9. If you want to translate the fields from datetime module which they're translated depending of locale, you need to change the locale name, from: locale.setlocale(locale.LC_ALL, 'turkish') To: (you don't need to use also LC_ALL, since you use the module just for time) locale.setlocale(locale.LC_TIME, 'english') If you want to translate automatically based on player OS default language with a correct way and safe, i tried to do something like this for test, works fine. import ctypes # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid/a9eac961-e77d-41a6-90a5-ce1a8b0cdb9c # The locale identifier hex id for the user UI language for the current user windows_locale_id = ctypes.windll.kernel32.GetUserDefaultUILanguage() # The locale identifier name based on hex id from dict: {0x040a: "es_ES", 0x0816: "pt_PT", ...} windows_locale_name = locale.windows_locale.get(windows_locale_id, 0x0409) # Remove the delimiter of locale name '_' and keep just the language itself: [en, de, ro, it, ...] windows_locale_name = windows_locale_name.split('_')[0] # Set the locale name for time emulation locale.setlocale(locale.LC_TIME, windows_locale_name)
  10. There's no reason to use pids instead of names, for doing that you've to re-code the whole structure of the system. Ymir did when you change your name to delete all fields from table that match with the old name (account or companion). So in this case, instead of deleting the whole list you can simply update it. Srcs/Server/game/src/questlua_pc.cpp // Search for: MessengerManager::instance().RemoveAllList(ch->GetName()); // Replace with: std::auto_ptr<SQLMsg> p1(DBManager::instance().DirectQuery("UPDATE messenger_list SET account='%s' WHERE account='%s'", szName, ch->GetName())); std::auto_ptr<SQLMsg> p2(DBManager::instance().DirectQuery("UPDATE messenger_list SET companion='%s' WHERE companion='%s'", szName, ch->GetName())); Or: std::auto_ptr<SQLMsg> pUpdate(DBManager::instance().DirectQuery( "UPDATE messenger_list SET " "account = CASE WHEN account = '%s' THEN '%s' ELSE account END, " "companion = CASE WHEN companion = '%s' THEN '%s' ELSE companion END", ch->GetName(), szName, ch->GetName(), szName);
  11. @martysama0134
  12. Skill levels depends of skill grade also you've to clean the tooltip each time. elif player.SKILL_INDEX_RIDING == skillIndex: self.ClearToolTip() self.__SetSkillTitle(skillIndex, skillGrade) slotIndex = player.GetSkillSlotIndex(skillIndex) skillLevel = player.GetSkillLevel(slotIndex) skillGradeDict = {1: 19, 2: 29, 3: 39} if skillGrade in skillGradeDict: skillLevel += skillGradeDict[skillGrade] if skillLevel == 1: self.AppendSpace(5) self.AppendTextLine("Test1", self.NORMAL_COLOR) elif skillLevel == 20: self.AppendSpace(5) self.AppendTextLine("Test20", self.NORMAL_COLOR)
  13. Why you modify the buffer size to 512? Your file name has more than 225 characters? I'm sure not, it's enough 256. Also you should do a check if your water texture file exists in your path for sure, otherwise everything will be fucked up with the array when trying to get texture pointer and function D3D texture. (possible crash because of nullptr) So, you should change: m_WaterInstances[i].SetImagePointer((CGraphicImage *)CResourceManager::Instance().GetResourcePointer(buf)); With: if (CResourceManager::Instance().IsFileExist(buf)) m_WaterInstances[i].SetImagePointer(dynamic_cast<CGraphicImage *>(CResourceManager::Instance().GetResourcePointer(buf))); Also, instead of change everywhere 30 with 99 or what value you want, you should do a constant variable and use it everywhere. //@ MapOutdoorWater.h static const uint8_t WATER_INSTANCE_MAX_NUM = 99; CGraphicImageInstance m_WaterInstances[WATER_INSTANCE_MAX_NUM]; //@ MapOutdoorWater.cpp void CMapOutdoor::LoadWaterTexture() { UnloadWaterTexture(); char buf[256]; for (uint8_t i = 0; i < WATER_INSTANCE_MAX_NUM; ++i) { sprintf(buf, "d:/ymir Work/special/water/%02d.dds", i+1); if (!CResourceManager::Instance().IsFileExist(buf)) { TraceError("Failed to load: %s", buf); continue; } m_WaterInstances[i].SetImagePointer(dynamic_cast<CGraphicImage *>(CResourceManager::Instance().GetResourcePointer(buf))); } } void CMapOutdoor::UnloadWaterTexture() { for (uint8_t i = 0; i < WATER_INSTANCE_MAX_NUM; ++i) m_WaterInstances[i].Destroy(); } Also this is the good method for accessing the array with a safe method. STATEMANAGER.SetTexture(0, m_WaterInstances[((ELTimer_GetMSec() / 70) % 30)].GetTexturePointer()->GetD3DTexture()); [...] auto pImageInstance = m_WaterInstances[(ELTimer_GetMSec() / 70) % _countof(m_WaterInstances)]; if (pImageInstance.GetTexturePointer()) STATEMANAGER.SetTexture(0, pImageInstance.GetTexturePointer()->GetD3DTexture());
  • 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.