#include "stdafx.h" #include "HookManager.h" #include "Skill/SkillManager.h" #include "ObjectManager.h" #include "LocalPlayer.h" #include "ItemStorage.h" #include "ui/UFun.h" #include "Network/NetworkManager.h" #include "ItemSlot.h" #include "Utils/ItemDB.h" #include "ItemManager.h" #include "PlayerInputMgr.h" #include "UHookSet.h" #include "ui/SystemSetup.h" #include "ui/UIGamePlay.h" #include "ui/UIPickItemList.h" #include "ui/UMessageBox.h" #include "ui/UChat.h" #include "Effect/EffectManager.h" CHookMgr* CHookMgr::sm_HookMgr = NULL; CHookMgr::CHookMgr() { m_HookData = new HookData; m_LoadData = new HookData; m_bStartHookActor = false; m_HookStat = Hook_UnKnow; m_NextHookStat = Hook_UnKnow; m_HookCtr = NULL ; m_CurTargetObjectID = 0; m_SaveAutoAction = FALSE ; m_LastError = SPELL_CANCAST_OK ; } CHookMgr::~CHookMgr() { if (m_HookData) { delete m_HookData; m_HookData = NULL; } if (m_LoadData) { delete m_LoadData; m_LoadData = NULL; } } void CHookMgr::InitHookMgr() { if (!sm_HookMgr) { sm_HookMgr = new CHookMgr; } } BOOL CHookMgr::InitUIHookData(HookData& pkData) { m_LoadData->ResetData(); *m_LoadData = pkData ; if (m_HookCtr) { m_HookCtr->HookActiveUI(m_bStartHookActor); return m_HookCtr->SetHookData(pkData); } return FALSE ; } BOOL CHookMgr::LoadHookFile() // 读取配置文件 { if (SystemSetup) { if (!SystemSetup->LoadFile(FILE_HOOKSETTING)) { m_LoadData->ResetData(); return FALSE; } return TRUE; } return FALSE; } BOOL CHookMgr::SaveHookFile() { if (SystemSetup) { SystemSetup->SaveHookSetFile(); OutPutMsg(_TRAN("辅助设置保存成功")); } return TRUE ; } void CHookMgr::SetHook() { if (m_HookCtr) { if (m_HookCtr->IsVisible()) { m_HookCtr->SetVisible(FALSE); }else { m_HookCtr->SetHookData(*m_LoadData); m_HookCtr->SetVisible(TRUE); } } } void CHookMgr::ShutDownHookMgr() { if (sm_HookMgr) { delete sm_HookMgr; sm_HookMgr = NULL; } } void CHookMgr::OutPutMsg(const char* text) { EffectMgr->AddEffeText(NiPoint3(300.0f,300.0f,0.0f), text); std::string str = text; str += "
"; ChatSystem->AppendChatMsg(CHAT_MSG_SYSTEM, str.c_str()); } void CHookMgr::OutPutError(const char* text) { UMessageBox::MsgBox_s(text,NULL); EffectMgr->AddEffeText(NiPoint3(300.0f,300.0f,0.0f), text); std::string str = text; str += "
"; ChatSystem->AppendChatMsg(CHAT_MSG_SYSTEM, str.c_str()); } BOOL CHookMgr::CreateUI(UControl* pkCtrl) { if (pkCtrl) { if (!m_HookCtr) { UControl* HookCtr = UControl::sm_System->CreateDialogFromFile("Hook\\HookSet.udg"); m_HookCtr = UDynamicCast(UHookSet, HookCtr); if (!m_HookCtr) { return FALSE; }else { pkCtrl->AddChild(m_HookCtr); m_HookCtr->SetId(FRAME_IG_HOOKDLG); } } return TRUE; } return FALSE ; } void CHookMgr::BeginHookActor() { //这里要尝试去获得HOOK的设定 CPlayerLocal* pkLocal = ObjectMgr->GetLocalPlayer(); if (pkLocal) { pkLocal->StopMove(); } OutPutMsg(_TRAN("开启挂机系统成功,在此期间您将无法操作角色")); *m_LoadData = *m_HookData; //然后开始激活状态机 m_bStartHookActor = true ; m_HookStat = Hook_Normal; m_NextHookStat = Hook_UnKnow ; SYState()->LocalPlayerInput->SetTargetID(0); m_SaveAutoAction = SYState()->LocalPlayerInput->GetAutoAction(); SYState()->LocalPlayerInput->SetAutoAction(TRUE); if (m_HookCtr) { m_HookCtr->HookActiveUI(TRUE); } if (m_HookData->AutoPick) { UPickItemList* pPickItemlist = INGAMEGETFRAME(UPickItemList, FRAME_IG_PICKLISTDLG); if (pPickItemlist) { pPickItemlist->SetHookAutoPick(m_HookData->AutoPick); } } } BOOL CHookMgr::StopPickState(ui64 guid) { if (m_HookStat == Hook_Pick) { StateHookPick* pkState = (StateHookPick*)GetStateInstance(Hook_Pick); if (pkState->GetID() == guid&& guid) { //OutputDebugString("挂机状态 当前市区对象和释放对象ID不同\n"); } //OutputDebugString("从拾取切换到NROMAL \n"); if (!guid) { m_HookData->AutoPick = FALSE ; OutPutMsg(_TRAN("背包已满,停止自动拾取设置")); } return (ForceStateChange(Hook_Normal, guid)!= NULL); } return FALSE; } BOOL CHookMgr::HookUseSpellFailed(ui8 error) { ui64 TargetId = SYState()->LocalPlayerInput->GetTargetID(); CPlayerLocal* pkPlayer = ObjectMgr->GetLocalPlayer(); CCreature* pkTarget = (CCreature*)ObjectMgr->GetObject(TargetId); if (!pkPlayer || !TargetId) { return (ForceStateChange(Hook_Normal, 0) != NULL); ; } char buf[1024]; sprintf(buf,"挂机使用技能失败 错误%d 原因%s\n\n", error,SpellTemplate::GetSpellErrorString(error)); OutputDebugString(buf); switch(error) { case SPELL_FAILED_LINE_OF_SIGHT : //目标不在视野中 { m_LastError = SPELL_CANCAST_OK ; return (ForceStateChange(Hook_Normal, TargetId) != NULL); } break; case SPELL_FAILED_UNIT_NOT_INFRONT: //目标不在面前 { if (m_LastError == SPELL_FAILED_UNIT_NOT_INFRONT) { m_LastError = SPELL_CANCAST_OK ; return (ForceStateChange(Hook_Normal, TargetId) != NULL); } m_LastError = SPELL_FAILED_UNIT_NOT_INFRONT; pkPlayer->SetDirectionTo(pkTarget->GetPosition()); return (ForceStateChange(Hook_Normal, 0) != NULL); } break; case SPELL_FAILED_OUT_OF_RANGE: //目标距离太远 { if (m_LastError == SPELL_FAILED_OUT_OF_RANGE) { m_LastError = SPELL_CANCAST_OK ; return (ForceStateChange(Hook_Normal, TargetId) != NULL); } m_LastError = SPELL_FAILED_OUT_OF_RANGE; return (ForceStateChange(Hook_Normal, 0) != NULL); } break ; } m_LastError = SPELL_CANCAST_OK ; return (ForceStateChange(Hook_Normal, TargetId) != NULL); } BOOL CHookMgr::StopUseSpellState(ui32 spellid, ui8 error) { if (m_HookStat == Hook_UseSpell) { if (spellid != GetStateInstance(Hook_UseSpell)->GetID()) { return FALSE ; } StateHookNormal* pkNormalState = (StateHookNormal*)GetStateInstance(Hook_Normal); if (error == SPELL_CANCAST_OK) { pkNormalState->SetActiveWaitSpell(TRUE); //如果技能成功释放 }else { pkNormalState->SetActiveWaitSpell(FALSE); } if (error == SPELL_CANCAST_OK) { return (ForceStateChange(Hook_Normal, 0)!= NULL); } if (error == SPELL_FAILED_NO_POWER) //MP 不足 { if (!ForceMPSkillStateChange()) //尝试使用恢复MP技能 { if (ForceMPItemStateChange()) //尝试恢复MP药水 { return TRUE ; } }else { return TRUE ; } } char buf[_MAX_PATH]; if (error == SPELL_FAILED_LINE_OF_SIGHT || error == SPELL_FAILED_UNIT_NOT_INFRONT || error == SPELL_FAILED_OUT_OF_RANGE) { return HookUseSpellFailed(error); } sprintf(buf,"挂机使用技能失败 错误%d 技能:%d \n\n", error, spellid); OutputDebugString(buf); return (ForceStateChange(Hook_Normal, 0)!= NULL); } return FALSE; } BOOL CHookMgr::ForceMPSkillStateChange() { if (m_HookData->MPSpell) { BOOL CanUse = SYState()->LocalPlayerInput->CanUseSkill(m_HookData->MPSpell); if (CanUse) { //OutputDebugString("挂机恢复技能MP状态 \n"); return (ForceStateChange(Hook_UseSpell, m_HookData->MPSpell)!= NULL); } } return FALSE ; } BOOL CHookMgr::ForceMPItemStateChange() { CPlayerLocal* pkLocal = ObjectMgr->GetLocalPlayer(); if (!pkLocal) { return FALSE ; } ui32 ItemEntry = 0 ; CStorage* pkStor = pkLocal->GetItemContainer(); if (pkStor) { for (int i =0; i < AutoYaoShui; i++) { if (m_HookData->MPEntry[i]) { CItemSlot* pkSolt = (CItemSlot*)pkStor->GetSlotByEntry(m_HookData->MPEntry[i]); if (!pkSolt) { continue ; } ui32 RecoverTime, RemainTime ; bool Find = SYState()->SkillMgr->GetItemCooldownTime(m_HookData->MPEntry[i], RecoverTime, RemainTime); if (!Find) { ItemPrototype_Client* pkItemInfo = ItemMgr->GetItemPropertyFromDataBase( m_HookData->MPEntry[i]); if (pkItemInfo && pkItemInfo->RequiredLevel <= pkLocal->GetLevel()) { ItemEntry = m_HookData->MPEntry[i]; break ; } } } } } if (!ItemEntry) { //OutputDebugString("强制切换到使用HP药水状态 \n"); return (ForceStateChange(Hook_Supply, ItemEntry) != NULL); } return FALSE ; } void CHookMgr::EndHookActor() { m_bStartHookActor = false; m_HookStat = Hook_UnKnow; m_NextHookStat = Hook_UnKnow; SYState()->LocalPlayerInput->SetAutoAction(m_SaveAutoAction>0); OutPutMsg(_TRAN("停止挂机系统成功,您恢复角色操作")); m_HookData->ResetData(); UPickItemList* pPickItemlist = INGAMEGETFRAME(UPickItemList, FRAME_IG_PICKLISTDLG); if (pPickItemlist) { pPickItemlist->SetHookAutoPick(FALSE); } if (m_HookCtr) { m_HookCtr->HookActiveUI(FALSE); } } void CHookMgr::HookRelive() { if (m_HookData && m_HookData->DeadAutoPos) { MSG_C2S::stReliveReq Msg; Msg.type = MSG_C2S::stReliveReq::Relive_Home; NetworkMgr->SendPacket(Msg); } } void CHookMgr::ResetHook() { ForceStateChange(Hook_Normal, 0); } BOOL CHookMgr::SetHookData(const HookData &pkData) { //如果状态机在运行。 则无法设置挂机数据 if (m_bStartHookActor) { return FALSE ; } *m_HookData = pkData ; return TRUE; } BOOL CHookMgr::SetLoadHookData(const HookData& pkData) { *m_LoadData = pkData ; return TRUE; } void CHookMgr::UpdateState(DWORD Time) { if (!m_bStartHookActor) { return ; } EHookStateProcessResult eProcessR = END_HOOK; BOOL bChangNextHookState = FALSE ; HookState eCurHookState = Hook_UnKnow ; HookStateProxy* pkCurHookStateInst = GetStateInstance(m_HookStat); if (!pkCurHookStateInst) { return ; } eProcessR = pkCurHookStateInst->Process(Time); //状态保持 if (eProcessR == HOLD_HOOK) { return ; } //如果状态正常结束 if (eProcessR == END_HOOK) { if (m_NextHookStat == Hook_UnKnow) { m_NextHookStat = Hook_Normal ; } }else { //状态挂起 切换状态 if (eProcessR == SUSPEND_HOOK) { if (m_NextHookStat != Hook_UnKnow) { bChangNextHookState = TRUE; } } } if (bChangNextHookState) { ChangeToNextState(); } } BOOL CHookMgr::SetNextState(HookState NextState, ui64 ID) { if (!m_bStartHookActor) { return FALSE; } HookStateProxy* pkStateInst = GetStateInstance(NextState); if (pkStateInst) { if (!pkStateInst->CanTransit(NextState)) { return FALSE ; } pkStateInst->SetID(ID); m_NextHookStat = NextState ; return TRUE; } return FALSE; } HookStateProxy* CHookMgr::ForceStateChange(HookState NextState, ui64 id) { if (!m_bStartHookActor) { return NULL; } HookStateProxy* pkStateInst = GetStateInstance(NextState); if (pkStateInst) { if (!pkStateInst->CanTransit(NextState)) { return NULL ; } SetNextState(NextState, id); ChangeToNextState(); return pkStateInst; } return NULL ; } HookStateProxy* CHookMgr::GetStateInstance(HookState eState) { switch (eState) { case Hook_Normal: return StateHookNormal::Instance(); case Hook_Pick: return StateHookPick::Instance(); case Hook_Supply: return StateHookSupply::Instance(); case Hook_UseSpell: return StateHookUseSpell::Instance(); case Hook_Walk: return StateHookWalk::Instance(); } return NULL ; } BOOL CHookMgr::ChangeToNextState() { BOOL bResult = TRUE; HookStateProxy* pkCurHookStateInst = GetStateInstance(m_HookStat); HookStateProxy* pkNextHookStateInst = GetStateInstance(m_NextHookStat); if (!pkCurHookStateInst || !pkNextHookStateInst) { return FALSE ; } bResult = pkCurHookStateInst->End(); bResult = pkNextHookStateInst->Start(); char buf[_MAX_PATH]; if (bResult) { m_HookStat = m_NextHookStat; m_NextHookStat = Hook_UnKnow; sprintf(buf,"HOOK %s切换状态 %s \n",pkCurHookStateInst->GetStateDesc(), pkNextHookStateInst->GetStateDesc()); }else { sprintf(buf,"HOOK %s尝试切换状态失败 %s \n",pkCurHookStateInst->GetStateDesc(), pkNextHookStateInst->GetStateDesc()); } if (bResult) { if (m_HookStat == Hook_Normal) { ui64 guid = SYState()->LocalPlayerInput->GetTargetID(); if (guid) { CCharacter* pkChar = (CCharacter*)ObjectMgr->GetObject(guid); if (pkChar && pkChar->IsLocalPlayer()) { SYState()->LocalPlayerInput->SetTargetID(0); } } } } OutputDebugString(buf); return bResult ; } BOOL CHookMgr::SetNextNormalState(ui64 guid) { CPlayerLocal* pkLocal = ObjectMgr->GetLocalPlayer(); if (pkLocal) { pkLocal->StopMove(); } m_LastError = SPELL_CANCAST_OK; //OutputDebugString("挂机普通状态 \n"); return SetNextState(Hook_Normal, guid); } BOOL CHookMgr::SetNextNormalState() { CPlayerLocal* pkLocal = ObjectMgr->GetLocalPlayer(); if (pkLocal) { pkLocal->StopMove(); } m_LastError = SPELL_CANCAST_OK; return SetNextState(Hook_Normal, 0); } BOOL CHookMgr::SetNextAttackSkillState() { if (m_HookData->AutoAttack) { vector spell; spell.clear(); for (int i = 0; i < AutoMaxSpell; i++) { if (m_HookData->Spell[i]) { BOOL CanUse = SYState()->LocalPlayerInput->CanUseSkill(m_HookData->Spell[i]); if (CanUse) { spell.push_back(m_HookData->Spell[i]) ; } } } // 没找到技能的话。 if (!spell.size()) { return FALSE ; } srand(time(NULL)); int s = rand() % spell.size(); char buf[_MAX_PATH]; sprintf(buf, "挂机攻击状态 SPELL:%d \n", spell[s]); OutputDebugString(buf); return SetNextState(Hook_UseSpell, spell[s]); } return FALSE ; } BOOL CHookMgr::SetNextHPSkillState() { if (m_HookData->HPSpell) { BOOL CanUse = SYState()->LocalPlayerInput->CanUseSkill(m_HookData->HPSpell); if (CanUse) { //OutputDebugString("挂机恢复技能HP状态 \n"); return SetNextState(Hook_UseSpell, m_HookData->HPSpell); } } return FALSE ; } BOOL CHookMgr::SetNextMPSkillState() { if (m_HookData->MPSpell) { BOOL CanUse = SYState()->LocalPlayerInput->CanUseSkill(m_HookData->MPSpell); if (CanUse) { //OutputDebugString("挂机恢复技能MP状态 \n"); return SetNextState(Hook_UseSpell, m_HookData->MPSpell); } } return FALSE ; } BOOL CHookMgr::SetNextPickState() { //OutputDebugString("挂机自动拾取状态\n"); return SetNextState(Hook_Pick, 0); } BOOL CHookMgr::SetNextWalkState(NiPoint3 Pos, ui64 guid) { StateHookWalk* pkWalkState = (StateHookWalk*)GetStateInstance(Hook_Walk); pkWalkState->SetMovePos(Pos); return SetNextState(Hook_Walk, guid); } BOOL CHookMgr::SetNextWalkState() { //OutputDebugString("挂机自动返回挂机点状态 \n"); StateHookWalk* pkWalkState = (StateHookWalk*)GetStateInstance(Hook_Walk); pkWalkState->SetMovePos(NiPoint3::ZERO); return SetNextState(Hook_Walk, 0); } BOOL CHookMgr::SetNextUseHPItemState() { CPlayerLocal* pkLocal = ObjectMgr->GetLocalPlayer(); if (!pkLocal) { return FALSE ; } ui32 ItemEntry = 0 ; CStorage* pkStor = pkLocal->GetItemContainer(); if (pkStor) { for (int i =0; i < AutoYaoShui; i++) { if (m_HookData->HPEntry[i]) { CItemSlot* pkSolt = (CItemSlot*)pkStor->GetSlotByEntry(m_HookData->HPEntry[i]); if (!pkSolt) { continue ; } ui32 RecoverTime, RemainTime ; bool Find = SYState()->SkillMgr->GetItemCooldownTime(m_HookData->HPEntry[i], RecoverTime, RemainTime); if (!Find) { ItemPrototype_Client* pkItemInfo = ItemMgr->GetItemPropertyFromDataBase( m_HookData->HPEntry[i]); if (pkItemInfo && pkItemInfo->RequiredLevel <= pkLocal->GetLevel()) { ItemEntry = m_HookData->HPEntry[i]; break ; } } } } } if (ItemEntry) { //OutputDebugString("挂机使用HP药水状态 \n"); return SetNextState(Hook_Supply, ItemEntry); } return FALSE ; } BOOL CHookMgr::SetNextUseMPItemState() { CPlayerLocal* pkLocal = ObjectMgr->GetLocalPlayer(); if (!pkLocal) { return FALSE ; } ui32 ItemEntry = 0 ; CStorage* pkStor = pkLocal->GetItemContainer(); if (pkStor) { for (int i =0; i < AutoYaoShui; i++) { if (m_HookData->MPEntry[i]) { CItemSlot* pkSolt = (CItemSlot*)pkStor->GetSlotByEntry(m_HookData->MPEntry[i]); if (!pkSolt) { continue ; } ui32 RecoverTime, RemainTime ; bool Find = SYState()->SkillMgr->GetItemCooldownTime(m_HookData->MPEntry[i], RecoverTime, RemainTime); if (!Find) { //这里只是简单的判断了使用药水的等级 // ItemPrototype_Client* pkItemInfo = ItemMgr->GetItemPropertyFromDataBase( m_HookData->MPEntry[i]); if (pkItemInfo && pkItemInfo->RequiredLevel <= pkLocal->GetLevel()) { ItemEntry = m_HookData->MPEntry[i]; break ; } } } } } if (ItemEntry) { //OutputDebugString("挂机使用MP药水状态 \n"); return SetNextState(Hook_Supply, ItemEntry); } return FALSE ; }