Jump to content

shenhui1986

Inactive Member
  • Posts

    78
  • Joined

  • Last visited

  • Feedback

    0%

About shenhui1986

Informations

  • Gender
    Male
  • Country
    China
  • Nationality
    Chinese

Recent Profile Visitors

2205 profile views

shenhui1986's Achievements

Community Regular

Community Regular (8/16)

  • Dedicated
  • Reacting Well
  • First Post
  • Collaborator Rare
  • Week One Done

Recent Badges

14

Reputation

  1. Hello developers, I am once again seeking your help. I need the feature of automatically using items, which can now handle the logic of using items with attack speed and movement speed very well. However, when encountering items with sustained recovery, it is difficult to make effective and correct judgments, such as NEW-AFFERCT-AUTO-HP-RECOVER=534, NEW-AFFERCT-AUTO-SP-RECOVER=535 What I need is for 72723 or 73727 or other continuous recovery items to automatically open the next bottle when their capacity runs out and they automatically close client_src /pythonplayer.cpp void CPythonPlayer::AddAutoUseItem(DWORD dwVnum, BYTE byThreshold, WORD wCoolTime) { TraceError("CPythonPlayer::AddAutoUseItem - vnum:%d threshold:%d cooltime:%d", dwVnum, byThreshold, wCoolTime); m_AutoUseItems[dwVnum] = std::make_pair(byThreshold, wCoolTime); m_AutoUseLastTime[dwVnum] = 0; } void CPythonPlayer::RemoveAutoUseItem(DWORD dwVnum) { m_AutoUseItems.erase(dwVnum); m_AutoUseLastTime.erase(dwVnum); } void CPythonPlayer::ClearAutoUseItems() { m_AutoUseItems.clear(); m_AutoUseLastTime.clear(); } bool CPythonPlayer::IsAutoUseItem(DWORD dwVnum) { return m_AutoUseItems.find(dwVnum) != m_AutoUseItems.end(); } bool CPythonPlayer::IsValidUseItem(DWORD dwVnum) { CItemManager& rkItemMgr = CItemManager::Instance(); CItemData* pItem; if (!rkItemMgr.GetItemDataPointer(dwVnum, &pItem)) { TraceError("IsValidUseItem - Cannot get item data for vnum: %d", dwVnum); return false; } if (pItem->GetType() != 3) { TraceError("IsValidUseItem - Item %d is not use type", dwVnum); return false; } BYTE subType = pItem->GetSubType(); TraceError("IsValidUseItem - Checking item: %d, subType: %d", dwVnum, subType); switch (subType) { case 0: // 药水 { DWORD curHP = (DWORD)GetStatus(POINT_HP); DWORD maxHP = (DWORD)GetStatus(POINT_MAX_HP); DWORD curSP = (DWORD)GetStatus(POINT_SP); DWORD maxSP = (DWORD)GetStatus(POINT_MAX_SP); if (pItem->GetValue(0) > 0) // HP药水 { TraceError("IsValidUseItem - HP potion check: cur=%d, max=%d", curHP, maxHP); if (curHP >= maxHP) return false; } else if (pItem->GetValue(1) > 0) // MP药水 { TraceError("IsValidUseItem - MP potion check: cur=%d, max=%d", curSP, maxSP); if (curSP >= maxSP) return false; } break; } case 7: // 辅助性药剂 { long affect_type = pItem->GetValue(0); TraceError("IsValidUseItem - Buff item: %d, affect_type: %d", dwVnum, affect_type); CInstanceBase* pkInstMain = CPythonCharacterManager::Instance().GetMainInstancePtr(); if (!pkInstMain) return false; DWORD dwAffectType = 0; if (affect_type == 7) dwAffectType = CInstanceBase::AFFECT_ATT_SPEED_POTION; else if (affect_type == 8) dwAffectType = CInstanceBase::AFFECT_MOV_SPEED_POTION; if (pkInstMain->IsAffect(dwAffectType)) { TraceError("IsValidUseItem - Already has affect %d for item %d", dwAffectType, dwVnum); return false; } break; } case 10: // 持续恢复类物品(水龙/火龙) { CInstanceBase* pkInstMain = CPythonCharacterManager::Instance().GetMainInstancePtr(); if (!pkInstMain) return false; if (dwVnum == 72727) // 水龙 { const SAutoPotionInfo& potInfo = GetAutoPotionInfo(AUTO_POTION_TYPE_SP); if (potInfo.bActivated) // 修改 isActivated 为 bActivated { TraceError("IsValidUseItem - SP AutoPotion already activated - Current: %d Total: %d Slot: %d", potInfo.currentAmount, potInfo.totalAmount, potInfo.inventorySlotIndex); return false; } } else if (dwVnum == 72723) // 火龙 { const SAutoPotionInfo& potInfo = GetAutoPotionInfo(AUTO_POTION_TYPE_HP); if (potInfo.bActivated) // 修改 isActivated 为 bActivated { TraceError("IsValidUseItem - HP AutoPotion already activated - Current: %d Total: %d Slot: %d", potInfo.currentAmount, potInfo.totalAmount, potInfo.inventorySlotIndex); return false; } } break; } case 11: // 立即恢复类物品 { DWORD curHP = (DWORD)GetStatus(POINT_HP); DWORD maxHP = (DWORD)GetStatus(POINT_MAX_HP); if (pItem->GetValue(0) > 0) // 立即满血效果 { TraceError("IsValidUseItem - Instant full HP recovery check: cur=%d, max=%d", curHP, maxHP); if (curHP >= maxHP) { TraceError("IsValidUseItem - Already at full HP, cannot use item %d", dwVnum); return false; } } break; } default: TraceError("IsValidUseItem - Unknown subType: %d for item: %d", subType, dwVnum); break; } return true; } bool CPythonPlayer::UseItemByVnum(DWORD dwVnum)//使用物品 { // 直接使用 IsValidUseItem 进行检查 if (!IsValidUseItem(dwVnum)) return false; // 查找和使用物品 for (BYTE pos = 0; pos < c_Inventory_Count; ++pos) { const TItemData* pItem = GetItemData(TItemPos(INVENTORY, pos)); if (pItem && pItem->vnum == dwVnum) { CPythonNetworkStream::Instance().SendItemUsePacket(TItemPos(INVENTORY, pos)); return true; } } return false; } void CPythonPlayer::CheckAutoUseItems()//定期检查物品 { static DWORD s_lastCheckTime = ELTimer_GetMSec(); DWORD currentTime = ELTimer_GetMSec(); if (currentTime - s_lastCheckTime < 200) return; s_lastCheckTime = currentTime; // 直接调用UseItemByVnum(内部会调用IsValidUseItem) for (const auto& item : m_AutoUseItems) { UseItemByVnum(item.first); } } client_src/pythonplayermodule.cpp PyObject* playerCheckAutoUseItems(PyObject* poSelf, PyObject* poArgs) { CPythonPlayer::Instance().CheckAutoUseItems(); return Py_BuildValue("i", 1); } PyObject* playerAddAutoUseItem(PyObject* poSelf, PyObject* poArgs) { int iVnum; if (!PyTuple_GetInteger(poArgs, 0, &iVnum)) return Py_BuildException(); int iThreshold = 0; if (PyTuple_Size(poArgs) > 1) if (!PyTuple_GetInteger(poArgs, 1, &iThreshold)) return Py_BuildException(); int iCooldown = 0; if (PyTuple_Size(poArgs) > 2) if (!PyTuple_GetInteger(poArgs, 2, &iCooldown)) return Py_BuildException(); CPythonPlayer::Instance().AddAutoUseItem(iVnum, iThreshold, iCooldown); return Py_BuildNone(); } PyObject* playerRemoveAutoUseItem(PyObject* poSelf, PyObject* poArgs) { int iVnum; if (!PyTuple_GetInteger(poArgs, 0, &iVnum)) return Py_BuildException(); CPythonPlayer::Instance().RemoveAutoUseItem(iVnum); return Py_BuildNone(); } PyObject* playerClearAutoUseItems(PyObject* poSelf, PyObject* poArgs) { CPythonPlayer::Instance().ClearAutoUseItems(); return Py_BuildNone(); } PyObject* playerIsAutoUseItem(PyObject* poSelf, PyObject* poArgs) { int iVnum; if (!PyTuple_GetInteger(poArgs, 0, &iVnum)) return Py_BuildException(); return Py_BuildValue("i", CPythonPlayer::Instance().IsAutoUseItem(iVnum)); } PyObject* playerUseItemByVnum(PyObject* poSelf, PyObject* poArgs) { int iVnum; if (!PyTuple_GetInteger(poArgs, 0, &iVnum)) return Py_BuildException(); return Py_BuildValue("i", CPythonPlayer::Instance().UseItemByVnum(iVnum)); } python class AutoUseManager(ui.BoardWithTitleBar): """自动使用管理器 - 自动狩猎系统的子功能""" # 物品分类配置 ITEM_CATEGORIES = { "AUTO_HP_MP": { "name": "自动药水", "items": [27001,27002,27003,27051,27004,27005,27006,27052], # HP/MP药水 "tooltip": "自动使用HP/MP药水" }, "AUTO_DRAGON_FIRE": { "name": "自动火龙", "items": [72723,72724,72725,72726,39037,39038,39039], "tooltip": "自动使用火龙药水" }, "AUTO_DRAGON_WATER": { "name": "自动水龙", "items": [72727,72728,72729,72730,39040,39041,39042], "tooltip": "自动使用水龙药水" }, "AUTO_DRAGON_GOD": { "name": "自动龙神", "items": [71027,71028,71029,71030], "tooltip": "自动使用龙神药水" }, "AUTO_ATT_SPEED": { "name": "自动攻速", "items": [27053,27110,27101,27102,27111,27115,27116], "tooltip": "自动使用攻速药水" }, "AUTO_MOV_SPEED": { "name": "自动移速", "items": [27054,27103,27104,27105,27112,27113,27114], "tooltip": "自动使用移速药水" }, "AUTO_DOUBLE": { "name": "自动双破", "items": [39024,39025,71044,71045,72025,72026,72027], "tooltip": "自动使用双破药水" }, "AUTO_RELEASE": { "name": "自动释放", "items": [39031,71101,71102,76003], "tooltip": "自动使用释放药水" }, } def __init__(self, parentWnd = None, toolTipWnd = None, itemManager = None): ui.BoardWithTitleBar.__init__(self) self.parentWnd = parentWnd self.toolTipWnd = toolTipWnd self.itemManager = itemManager self.categoryButtons = {} self.enabledVNums = [] self.ignoredVNums = [] self.SetSize(250, 300) self.SetTitleName("自动使用管理") self.SetCenterPosition() self.AddFlag("movable") self.AddFlag("float") self.__CreateUI() def __del__(self): ui.BoardWithTitleBar.__del__(self) self.parentWnd = None self.toolTipWnd = None self.itemManager = None self.categoryButtons = {} def __CreateUI(self): """创建界面""" y = 35 for category, info in self.ITEM_CATEGORIES.items(): dbg.TraceError("Creating checkbox for %s" % info["name"]) # 创建分类复选框 checkbox = CheckBox( parent=self, title=info["name"], x=20, y=y, event=lambda category=category: self.__OnCategoryToggle(category) ) if "tooltip" in info: checkbox.SetToolTipText(info["tooltip"]) self.categoryButtons[category] = checkbox y += 30 def OpenWindow(self): """打开窗口""" if self.IsShow(): self.Close() else: self.Show() self.SetTop() self.__LoadAllStates() def __OnCategoryToggle(self, category): """处理分类开关""" checkbox = self.categoryButtons[category] info = self.ITEM_CATEGORIES[category] dbg.TraceError("Toggle %s" % info["name"]) current_state = checkbox.IsChecked() dbg.TraceError("Current state before toggle: %s" % current_state) # 反转状态 new_state = not current_state dbg.TraceError("Setting new state to: %s" % new_state) if new_state: dbg.TraceError("%s is being enabled" % info["name"]) # 检查玩家是否有该分类的物品 hasItems = False for vnum in info["items"]: itemCount = player.GetItemCountByVnum(vnum) if itemCount > 0: hasItems = True dbg.TraceError("Found item: %d count: %d" % (vnum, itemCount)) break # 告知玩家状态 if not hasItems: chat.AppendChat(chat.CHAT_TYPE_INFO, "%s: 当前没有可用物品,获得后会自动使用" % info["name"]) # 先设置状态 checkbox.Toggle() # 使用Toggle代替SetCheck # 无论是否有物品都添加到启用列表 for vnum in info["items"]: if vnum not in self.enabledVNums: self.enabledVNums.append(vnum) if vnum in self.ignoredVNums: self.ignoredVNums.remove(vnum) # 如果有物品就直接启用 if player.GetItemCountByVnum(vnum) > 0: threshold = 70 if category == "AUTO_HP_MP" else 0 player.AddAutoUseItem(vnum, threshold) dbg.TraceError("Added auto use: %d threshold: %d" % (vnum, threshold)) else: dbg.TraceError("%s is being disabled" % info["name"]) # 先设置状态 checkbox.Toggle() # 使用Toggle代替SetCheck # 取消自动使用 for vnum in info["items"]: if vnum in self.enabledVNums: self.enabledVNums.remove(vnum) if vnum not in self.ignoredVNums: self.ignoredVNums.append(vnum) if player.IsAutoUseItem(vnum): player.RemoveAutoUseItem(vnum) dbg.TraceError("Removed auto use: %d" % vnum) def Show(self): ui.BoardWithTitleBar.Show(self) self.__LoadAllStates() def Hide(self): ui.BoardWithTitleBar.Hide(self) def __LoadAllStates(self): """加载所有分类的当前状态""" dbg.TraceError("Loading all states") for category, info in self.ITEM_CATEGORIES.items(): checkbox = self.categoryButtons[category] # 检查该分类是否有物品在自动使用中 isActive = False for vnum in info["items"]: if player.IsAutoUseItem(vnum): isActive = True dbg.TraceError("%s has active item: %d" % (info["name"], vnum)) break checkbox.SetCheck(isActive) dbg.TraceError("Set %s state to: %s" % (info["name"], isActive)) def SetAutoUseList(self, itemList, ignoredList): """设置自动使用列表和忽略列表""" self.enabledVNums = itemList self.ignoredVNums = ignoredList # 更新UI状态 for category, info in self.ITEM_CATEGORIES.items(): checkbox = self.categoryButtons[category] # 检查该分类是否有物品在启用列表中 isActive = False for vnum in info["items"]: if vnum in self.enabledVNums: isActive = True break checkbox.SetCheck(isActive) def OnTick(self): """定时检查并使用物品""" if not self.IsShow(): return # 遍历所有启用的分类 for category, info in self.ITEM_CATEGORIES.items(): checkbox = self.categoryButtons[category] if not checkbox.IsChecked(): continue # 检查该分类中的物品 for vnum in info["items"]: if player.GetItemCountByVnum(vnum) > 0: player.UseItemByVnum(vnum) # C++端会处理所有的状态检查 def GetSendStatus(self, slot): """获取发送状态""" return True # 允许玩家手动使用物品 def SendInvSlot(self, slot): """发送物品使用请求""" if not self.GetSendStatus(slot): return # 检查物品类型 vnum = player.GetItemIndex(slot) if self.__IsEquipSlotItem(vnum): return True # 允许装备类物品使用 # 其他物品按原逻辑处理 return False def OnUpdate(self): if self.IsShow(): player.CheckAutoUseItems() # 定期检查自动使用物品 def OnPressEscapeKey(self): self.Close() return True def Close(self): self.Hide() def Destroy(self): self.Hide() for checkbox in self.categoryButtons.values(): checkbox = None self.categoryButtons = {} self.parentWnd = None I use the source of Martysama 5.8, and if anyone can help me, I am willing to pay for the knowledge
  2. It's indeed a joke, but if users like these, what can be done?
  3. I spent a total of $3200 developing this system, do you want to take $500?
  4. Hello, developers! Publish another task I hired Koray to create a brand new automatic hunting game for me two months ago. About a month later, I received a file, but it was not made according to my requirements. There were many bugs and logical errors in the file. So today I am releasing another task to modify the auto hunt written by Koray I will provide a salary of $500 and need to modify the new auto hunt system written by Koray koray is very busy I haven't received any response from him discord : fei.sun
  5. Dear great developers !!!! I want to block the implementation of some functions in the dungeon map, so with this, I added these codes, but they cannot be compiled PythonBackground.cpp bool CPythonBackground::IsDungeonMap() { static constexpr auto s_lstDungeonMaps = { "metin2_map_deviltower1", "dungeon2", "dungeon3" }; const auto szMapName = CPythonBackground::Instance().GetWarpMapName(); return std::any_of(s_lstDungeonMaps.begin(), s_lstDungeonMaps.end(), [szMapName](const char* szDungeonMap) { return std::strcmp(szMapName, szDungeonMap) == 0; }); } bool CPythonBackground::CheckAdvancing(CInstanceBase * pInstance) PythonBackground.h void RenderAfterLensFlare(); bool IsDungeonMap(); bool CheckAdvancing(CInstanceBase * pInstance); InstanceBaseBattle.cpp BOOL CInstanceBase::CheckAdvancing() { #ifdef ENABLE_NEW_AUTO_HUNT_SYSTEM if (CPythonPlayer::instance().IsAutoHuntEnabled() && IsPC() && IsWalking() && !IsDungeonMap()) { } else { return false; } #endif Thank you all
  6. I don't know when it started, but my client's whispering function stopped flashing because I had been testing it alone [Hidden Content] def RecvWhisper(self, name): if not self.whisperDialogDict.has_key(name): btn = self.__FindWhisperButton(name) if 0 == btn: btn = self.__MakeWhisperButton(name) btn.Flash(True) chat.AppendChat(chat.CHAT_TYPE_NOTICE, localeInfo.RECEIVE_MESSAGE % (name)) else: btn.Flash(True) elif self.IsGameMasterName(name): dlg = self.whisperDialogDict[name] dlg.SetGameMasterLook() Seeking help from developers
  7. The problem has been resolved, the source code functionality is incorrect
  8. in dungeon.h? Inside, there are void SpawnRegen(const char* filename, bool bOnce = true); change?
  9. Hello developers, I have encountered an issue where my Devil's Tower 5th floor is unable to repeatedly refresh monsters, which has resulted in me not being able to obtain item id: 50084. Please help me as I am using Marty 5.6 source (purchase) task from sysreldar (purchase) this my source ALUA(dungeon_regen_file) ALUA(dungeon_regen_file) { if (!lua_isstring(L,1)) { sys_err("wrong filename"); return 0; } CQuestManager& q = CQuestManager::instance(); LPDUNGEON pDungeon = q.GetCurrentDungeon(); if (pDungeon) pDungeon->SpawnRegen(lua_tostring(L,1)); return 0; } ALUA(dungeon_set_regen_file) ALUA(dungeon_set_regen_file) { if (!lua_isstring(L,1)) { sys_err("wrong filename"); return 0; } CQuestManager& q = CQuestManager::instance(); LPDUNGEON pDungeon = q.GetCurrentDungeon(); if (pDungeon) pDungeon->SpawnRegen(lua_tostring(L,1), false); return 0; } data srv1/share/data/dungeon deviltower5_regen.txt r 401 410 10 10 0 0 120s 100 1 1053 r 400 412 10 10 0 0 120s 100 1 1053 r 403 415 10 10 0 0 120s 100 1 1053 r 382 418 10 10 0 0 120s 100 1 1053 r 384 418 10 10 0 0 120s 100 1 1053 r 383 420 10 10 0 0 120s 100 1 1053 r 379 425 10 10 0 0 120s 100 1 1053 r 382 427 10 10 0 0 120s 100 1 1053 r 409 429 10 10 0 0 120s 100 1 1053 r 380 432 10 10 0 0 120s 100 1 1053 r 389 391 10 10 0 0 120s 100 1 1051 r 383 392 10 10 0 0 120s 100 1 1051 r 408 396 10 10 0 0 120s 100 1 1051 r 372 400 10 10 0 0 120s 100 1 1051 r 417 402 10 10 0 0 120s 100 1 1051 r 360 412 10 10 0 0 120s 100 1 1051 r 433 413 10 10 0 0 120s 100 1 1051 r 428 419 10 10 0 0 120s 100 1 1051 r 433 426 10 10 0 0 120s 100 1 1051 r 428 444 10 10 0 0 120s 100 1 1051 r 361 445 10 10 0 0 120s 100 1 1051 r 365 449 10 10 0 0 120s 100 1 1051 r 361 450 10 10 0 0 120s 100 1 1051 r 425 451 10 10 0 0 120s 100 1 1051 r 423 454 10 10 0 0 120s 100 1 1051 r 402 397 10 10 0 0 120s 100 1 1052 r 402 400 10 10 0 0 120s 100 1 1052 r 378 410 10 10 0 0 120s 100 1 1052 r 422 429 10 10 0 0 120s 100 1 1052 r 375 433 10 10 0 0 120s 100 1 1052 r 373 436 10 10 0 0 120s 100 1 1052 r 376 441 10 10 0 0 120s 100 1 1052 r 421 441 10 10 0 0 120s 100 1 1052 r 375 443 10 10 0 0 120s 100 1 1052 r 373 445 10 10 0 0 120s 100 1 1052 r 376 445 10 10 0 0 120s 100 1 1052 r 385 447 10 10 0 0 120s 100 1 1052 If you could help me, I would greatly appreciate it
  10. The project is currently being accepted by Koray
  11. Hello developer, after several months of waiting, I still haven't had a fully technical developer contact me to develop an autohunt plugin for me. My requirements are very simple Firstly, I am willing to pay a salary of 1000 to 1500 euros for this project. He needs to be compatible with the source of Marty5.6. If you can meet this requirement, you need extensive knowledge of C++instead of using cheating engines to search for memory addresses. You can take a look at my files. Please contact me Discord: fei.sun
  12. questlua_pc.cpp: In function 'int quest::pc_in_dungeon(lua_State*)': questlua_pc.cpp:277:31: error: invalid use of incomplete type 'class CDungeon' 277 | ret = (mapIndex == dungeon->GetOriginalMapIndex()); | ^~ In file included from stdafx.h:57, from questlua_pc.cpp:1: typedef.h:78:7: note: forward declaration of 'class CDungeon' 78 | class CDungeon; | ^~~~~~~~ gmake: *** [Makefile:171: .obj/questlua_pc.o] Error 1 This is the solution #include "dungeon.h" in questlua_pc.cpp
  13. Salary increase to 500 euros, Interested parties please contact me 1.auto attk (monsters or stone) (Based on the player's own attack speed) 2.auto pot (HP MP item ID 70020) 3.range hunt (activity within a certain range) 4.auto donate experience to the guild 5.Pickup filter(Customizable) 6.auto resurrection 7.auto login (When the network appears) 8.auto horseback riding 9.Focus: Return to the center when leaving the hunting area 10.start and stop button (Used to start/stop this auxiliary tool) 11.auto skill 12.Circular shouting 13.Rotating the camera (to avoid black screen issues) 14 auto use item 15.Range luring monster(Range and quantity can be set)
×
×
  • 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.