#include "stdafx.h" #include "HookState.h" #include "LocalPlayer.h" #include "ObjectManager.h" #include "HookManager.h" #include "PlayerInputMgr.h" #include "ItemSlot.h" #include "ItemStorage.h" #include "Network/PacketBuilder.h" // HOOK_NORMAL // StateHookNormal::StateHookNormal() { bWait = FALSE; DwWaitTime = 0; guid = 0; bWaitSpell = FALSE; DwWaitSpellTime = 0; WaitHPMPTime[0] = 1000; WaitHPMPTime[1] = 1000; } HookState StateHookNormal::GetHookState() { return Hook_Normal; } BOOL StateHookNormal::CanTransit(HookState state) { return TRUE; } BOOL StateHookNormal::Start() { CPlayerLocal* pkLocal = ObjectMgr->GetLocalPlayer(); if (!pkLocal) { return FALSE ; } bWait = FALSE; DwWaitTime = 0; WaitHPMPTime[0] = 1000; WaitHPMPTime[1] = 1000; return TRUE; } HookState StateHookNormal::End() { bWait = FALSE ; DwWaitTime = 0; bWaitSpell = FALSE; DwWaitSpellTime = 0 ; WaitHPMPTime[0] = 1000; WaitHPMPTime[1] = 1000; return Hook_Normal; } BOOL StateHookNormal::IsLock() { return FALSE ; } EHookStateProcessResult StateHookNormal::Process(DWORD dwtime) { CPlayerLocal* pkLocal = ObjectMgr->GetLocalPlayer(); const HookData* pkData = HookMgr->GetHookData(); if (bWaitSpell) { DwWaitSpellTime += dwtime; } // 判断魔法 if (pkLocal->GetMP() < (pkData->Mp* pkLocal->GetMaxMP())) { if (pkData->UseSpellFirst) { if (WaitHPMPTime[0] >= 1000) { if (HookMgr->SetNextMPSkillState()) //优先使用技能 { WaitHPMPTime[0] = 0; return SUSPEND_HOOK; }else { if (HookMgr->SetNextUseMPItemState()) { WaitHPMPTime[0] = 0; return SUSPEND_HOOK; } } }else { WaitHPMPTime[0] += dwtime; } }else { if (WaitHPMPTime[0] >= 1000) { if (HookMgr->SetNextUseMPItemState()) { WaitHPMPTime[0] = 0; return SUSPEND_HOOK; }else { if (HookMgr->SetNextMPSkillState()) { WaitHPMPTime[0] = 0; return SUSPEND_HOOK; } } }else { WaitHPMPTime[0] += dwtime ; } } } //判断气血 if (pkLocal->GetHP() < (pkData->Hp* pkLocal->GetMaxHP())) { if (pkData->UseSpellFirst) { if (WaitHPMPTime[1] >= 1000) { if (HookMgr->SetNextHPSkillState()) // 优先使用技能 // 这里进入状态后,可能是因为魔法不足 需要先判断魔法 { WaitHPMPTime[1] = 0; return SUSPEND_HOOK; }else { if (HookMgr->SetNextUseHPItemState()) { WaitHPMPTime[1] = 0; return SUSPEND_HOOK; } } }else { WaitHPMPTime[1] += dwtime ; } }else { if (WaitHPMPTime[1] >= 1000) { if (HookMgr->SetNextUseHPItemState()) { WaitHPMPTime[1] = 0; return SUSPEND_HOOK; }else { if (HookMgr->SetNextHPSkillState()) { WaitHPMPTime[1] = 0; return SUSPEND_HOOK ; } } }else { WaitHPMPTime[1] += dwtime; } } } ui64 pkTarget = SYState()->LocalPlayerInput->GetTargetID(); if (pkTarget && pkTarget != guid) { CCharacter* pkChar = (CCharacter*)ObjectMgr->GetObject(pkTarget); if (pkChar ) { if (pkChar->GetGameObjectType() == GOT_CREATURE) { CCreature* pkCreate = (CCreature*)pkChar; if (pkCreate->IsDead()) { if (pkData->AutoPick) { if (pkCreate->HasFlag(UNIT_DYNAMIC_FLAGS, U_DYN_FLAG_LOOTABLE)) { HookMgr->SetNextPickState(); return SUSPEND_HOOK; } } }else { if (bWaitSpell) { if (DwWaitSpellTime < 1800) //距离上次成功施法后 间隔1.5秒缓冲 { return SUSPEND_HOOK; }else { bWaitSpell = FALSE ; DwWaitSpellTime = 0; } } if (pkData->AutoAttack) { HookMgr->SetNextAttackSkillState(); } return SUSPEND_HOOK; } } } } //需要重新选择目标 // 这里需要重写选怪的函数. 避免选取到玩家 还要考虑到回避BOSS if ((pkLocal->GetPosition() - pkData->HookPos).Length() > 100.f) { HookMgr->SetNextWalkState(); }else { if (!bWait) { ui64 pkSelTarget = SYState()->LocalPlayerInput->HookAutoSelectCreature(guid,pkData->AutoPick); if (pkSelTarget == 0) { if ((pkLocal->GetPosition() - pkData->HookPos).Length() > 10.f) { HookMgr->SetNextWalkState(); }else { bWait = TRUE ; // 休息30秒 } } }else { DwWaitTime += dwtime; if (DwWaitTime > 10 * 1000) { bWait = FALSE ; DwWaitTime = 0; } } } return SUSPEND_HOOK; } // use spell HookState StateHookUseSpell::GetHookState() { return Hook_UseSpell; } BOOL StateHookUseSpell::CanTransit(HookState state) { return TRUE; } BOOL StateHookUseSpell::Start() { if (!Spellid || !ObjectMgr->GetLocalPlayer()) { return FALSE ; } //开始释放技能 LastPos = ObjectMgr->GetLocalPlayer()->GetPosition(); StartPos = LastPos; DwWaitTime = 0; DwNormalAttackTime = 0; IsJumped = FALSE; BOOL isSusecce = SYState()->LocalPlayerInput->BeginSkillAttack(Spellid); char buf[_MAX_PATH]; if (!isSusecce) { sprintf(buf, "尝试使用SPELL:%d 失败\n", Spellid); }else { sprintf(buf, "尝试使用SPELL:%d 成功\n", Spellid); } OutputDebugString(buf); return isSusecce ; } HookState StateHookUseSpell::End() { LastPos = NiPoint3::ZERO ; StartPos = LastPos ; DwWaitTime = 0; DwNormalAttackTime = 0; Spellid = 0; IsJumped = FALSE; return Hook_Normal; } BOOL StateHookUseSpell::IsLock() { return TRUE ; } EHookStateProcessResult StateHookUseSpell::Process(DWORD dwtime) { ui64 pkTarget = SYState()->LocalPlayerInput->GetTargetID(); CPlayerLocal* pkLocal = ObjectMgr->GetLocalPlayer(); NiPoint3 CurPos = pkLocal->GetPosition(); const HookData* pkData = HookMgr->GetHookData(); CCharacter* pkChar = (CCharacter*)ObjectMgr->GetObject(pkTarget); if (pkChar && pkChar->GetGameObjectType() == GOT_CREATURE && (Spellid !=pkData->HPSpell || Spellid != pkData->MPSpell)) { CCreature* pkCreate = (CCreature*)pkChar; if (pkCreate->IsDead()) { //如果怪物死了 切换状态 LastPos = NiPoint3::ZERO ; StartPos = LastPos ; DwWaitTime = 0; Spellid = 0; DwNormalAttackTime = 0; IsJumped = FALSE; //OutputDebugString("正常结束使用技能状态 \n"); HookMgr->SetNextNormalState(); return SUSPEND_HOOK; } if (LastPos == CurPos) { DwWaitTime += dwtime; }else { DwWaitTime = 0; LastPos = CurPos ; } if (DwWaitTime >= 10 * 1000) //如果8秒内 还在一直在一个地方 尝试跳跃。 { if (!IsJumped) { IsJumped = TRUE; DwWaitTime = 0; pkLocal->OnJumpInputEvent(); return HOLD_HOOK; } } if (DwWaitTime >= 12 * 1000) //如果15秒内 { if (IsJumped) { NiPoint3 ToPos = StartPos; LastPos = NiPoint3::ZERO ; StartPos = LastPos ; DwWaitTime = 0; Spellid = 0; IsJumped = FALSE; DwNormalAttackTime = 0; HookMgr->SetNextWalkState(ToPos, pkChar->GetGUID()); return SUSPEND_HOOK; } } if (Spellid == NORMAL_ATTACK_SPELL_ID) { DwNormalAttackTime += dwtime; if (DwNormalAttackTime >= 1000) { float fMaxRange = pkLocal->GetAttckRangeToTarget(pkChar); if ((CurPos - pkChar->GetPosition()).Length() <= fMaxRange) { LastPos = NiPoint3::ZERO ; StartPos = LastPos ; DwWaitTime = 0; DwNormalAttackTime = 0; Spellid = 0; IsJumped = FALSE; HookMgr->SetNextNormalState(); return SUSPEND_HOOK; }else { if (DwWaitTime >= 1000) { LastPos = NiPoint3::ZERO ; StartPos = LastPos ; DwWaitTime = 0; DwNormalAttackTime = 0; Spellid = 0; IsJumped = FALSE; HookMgr->SetNextNormalState(pkTarget); return SUSPEND_HOOK; } } } } return HOLD_HOOK; // 有怪保持 }else { //如果没有对象 或者对象不是怪物 //自动回到挂机点去 if (Spellid && (Spellid == pkData->HPSpell || Spellid == pkData->MPSpell)) { DwWaitTime += dwtime; if (DwWaitTime > 60* 1000) { LastPos = NiPoint3::ZERO ; StartPos = LastPos ; DwWaitTime = 0; Spellid = 0; IsJumped = FALSE; DwNormalAttackTime = 0; HookMgr->SetNextNormalState(); return SUSPEND_HOOK; } return HOLD_HOOK ; } LastPos = NiPoint3::ZERO ; StartPos = LastPos ; DwWaitTime = 0; Spellid = 0; IsJumped = FALSE; DwNormalAttackTime = 0; HookMgr->SetNextNormalState(); } return SUSPEND_HOOK; // 挂起 } // Supply HookState StateHookSupply::GetHookState() { return Hook_Supply; } BOOL StateHookSupply::CanTransit(HookState state) { return TRUE; } BOOL StateHookSupply::Start() { if (!Itemid) { return FALSE ; } return TRUE; } HookState StateHookSupply::End() { Itemid = 0; return Hook_Normal; } BOOL StateHookSupply::IsLock() { return TRUE ; } EHookStateProcessResult StateHookSupply::Process(DWORD dwtime) { //发送使用药水技能 CPlayerLocal* pkLocal = ObjectMgr->GetLocalPlayer(); if (!pkLocal) { return SUSPEND_HOOK ; } CStorage* pkBag = pkLocal->GetItemContainer(); if (pkBag) { CItemSlot* pkSolt = (CItemSlot*)pkBag->GetSlotByEntry(Itemid); if (pkSolt) { UINT cPos = pkBag->GetUIPos(pkSolt->GetGUID()); SpellCastTargets pTargets; pTargets.m_targetMask |= TARGET_FLAG_SELF; pTargets.m_unitTarget = pkLocal->GetGUID(); SYState()->UI->GetUItemSystem()->SendUseLeechdomMsg(pkBag->GetServerBag(cPos), pkBag->GetServerPos(cPos), 0, pTargets); } } HookMgr->SetNextNormalState(); return SUSPEND_HOOK; } /// pick HookState StateHookPick::GetHookState() { return Hook_Pick; } BOOL StateHookPick::CanTransit(HookState state) { return TRUE; } BOOL StateHookPick::Start() { ui64 pkTarget = SYState()->LocalPlayerInput->GetTargetID(); DwWaitTime = 0; CCharacter* pkChar = (CCharacter*)ObjectMgr->GetObject(pkTarget); if (!pkChar) { return FALSE ; } CPlayerLocal* pkLocal = ObjectMgr->GetLocalPlayer(); if (!pkLocal) { return FALSE ; } IsJumped = FALSE ; if (pkChar->GetGameObjectType() == GOT_CREATURE) { CCreature* pkCreate = (CCreature*)pkChar; if (pkCreate->IsDead()) { pkLocal->MoveTo(pkCreate->GetPosition(), 0 ); PickOBJGuid = pkTarget; return TRUE; }else { return FALSE ; } } return TRUE; } HookState StateHookPick::End() { PickOBJGuid = 0; DwWaitTime = 0; IsJumped = FALSE; return Hook_Normal; } BOOL StateHookPick::IsLock() { return FALSE ; } EHookStateProcessResult StateHookPick::Process(DWORD dwtime) { CCreature* pkCreate = (CCreature*)ObjectMgr->GetObject(PickOBJGuid); CPlayerLocal* pkLocal = ObjectMgr->GetLocalPlayer(); if (!pkLocal) { DwWaitTime = 0; PickOBJGuid = 0; //OutputDebugString("退出自动拾取状态\n"); return SUSPEND_HOOK; } if (pkCreate && pkCreate->GetGameObjectType() == GOT_CREATURE && pkCreate->IsDead() && pkCreate->HasFlag(UNIT_DYNAMIC_FLAGS, U_DYN_FLAG_LOOTABLE)) { DwWaitTime += dwtime; NiPoint3 TgrPos = pkCreate->GetPosition(); NiPoint3 LocaPos = pkLocal->GetPosition(); float Dis = (LocaPos - TgrPos).Length() ; if (Dis < 4.0f) { CPlayerLocal::SetCUState(cus_Pick); PacketBuilder->SendStartLoot(PickOBJGuid); }else { //如果时间过长 有可能是卡住 if (DwWaitTime >= 15 * 1000) { if (!IsJumped) { //尝试跳跃 DwWaitTime = 0; IsJumped = TRUE; pkLocal->OnJumpInputEvent(); return HOLD_HOOK; }else { pkLocal->StopMove(); DwWaitTime = 0; PickOBJGuid = 0; HookMgr->SetNextNormalState(PickOBJGuid); //OutputDebugString("退出自动拾取状态\n"); return SUSPEND_HOOK; } } } // 这里状态是保持. 需要在拾取列表为空的时候 来调整状态 return HOLD_HOOK; }else { DwWaitTime = 0; PickOBJGuid = 0; pkLocal->StopMove(); HookMgr->SetNextNormalState(); //OutputDebugString("退出自动拾取状态\n"); return SUSPEND_HOOK; } } // walk HookState StateHookWalk::GetHookState() { return Hook_Walk; } BOOL StateHookWalk::CanTransit(HookState state) { return TRUE; } BOOL StateHookWalk::Start() { CPlayerLocal* pkLocal = ObjectMgr->GetLocalPlayer(); if (!pkLocal) { return FALSE ; } if (!pkLocal->CanMove()) { return FALSE ; } //自动寻路过去 IsJumped = FALSE ; LastPos = NiPoint3::ZERO; if (ToPos != NiPoint3::ZERO) { pkLocal->MoveTo(ToPos,0); StartMove = TRUE ; }else { const HookData* pkData = HookMgr->GetHookData(); if ((pkLocal->GetPosition() - pkData->HookPos).Length() > 20.0f) { LastPos = pkLocal->GetPosition(); pkLocal->MoveToAStar(pkData->HookPos, 0); StartMove = FALSE; }else { pkLocal->MoveTo(pkData->HookPos,0); StartMove = TRUE ; } } DwWaitTime = 0 ; return TRUE; } HookState StateHookWalk::End() { ToPos = NiPoint3::ZERO; LastPos = NiPoint3::ZERO; guid = 0; DwWaitTime = 0 ; IsJumped = FALSE ; return Hook_Normal; } BOOL StateHookWalk::IsLock() { return FALSE ; } EHookStateProcessResult StateHookWalk::Process(DWORD dwtime) { CPlayerLocal* pkLocal = ObjectMgr->GetLocalPlayer(); if (!pkLocal) { return SUSPEND_HOOK ; } if (!pkLocal->CanMove()) { pkLocal->PathMoveEnd(); HookMgr->SetNextNormalState(); return SUSPEND_HOOK ; } DwWaitTime += dwtime ; if (pkLocal->IsPathMove()) // 如果还在寻路 { NiPoint3 curPos = pkLocal->GetPosition(); if (DwWaitTime >= 1000 * 2) { if (curPos == LastPos) { if (!IsJumped) { pkLocal->OnJumpInputEvent(); DwWaitTime = 0; IsJumped = TRUE; }else { if (DwWaitTime >= 1000 * 10) { DwWaitTime = 0; IsJumped = FALSE; pkLocal->PathMoveEnd(); //结束寻路 HookMgr->SetNextNormalState(guid); guid = 0; ToPos = NiPoint3::ZERO ; LastPos = ToPos ; return SUSPEND_HOOK; } } }else { LastPos = curPos; } } return HOLD_HOOK ; }else { if (ToPos == NiPoint3::ZERO) { const HookData* pkData = HookMgr->GetHookData(); if (!StartMove) { pkLocal->MoveTo(pkData->HookPos, 0); } if ((pkLocal->GetPosition() - pkData->HookPos).Length() < 5.0f) { DwWaitTime = 0; IsJumped = FALSE; pkLocal->StopMove(); HookMgr->SetNextNormalState(); guid = 0; ToPos = NiPoint3::ZERO ; LastPos = ToPos; return SUSPEND_HOOK; } }else { if ((pkLocal->GetPosition() - ToPos).Length() < 1.0f) { DwWaitTime = 0; IsJumped = FALSE; pkLocal->StopMove(); HookMgr->SetNextNormalState(guid); guid = 0; ToPos = NiPoint3::ZERO ; LastPos = ToPos; return SUSPEND_HOOK; } } if (DwWaitTime >= 2 * 60 * 1000) { if (!IsJumped) { IsJumped = TRUE; DwWaitTime = 0; pkLocal->OnJumpInputEvent(); return HOLD_HOOK; }else { DwWaitTime = 0; IsJumped = FALSE; pkLocal->PathMoveEnd(); //结束寻路 pkLocal->StopMove(); HookMgr->SetNextNormalState(guid); guid = 0; ToPos = NiPoint3::ZERO ; LastPos = ToPos; return SUSPEND_HOOK; } } return HOLD_HOOK; } }