#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 ;
}