#include "stdafx.h" #include "SAvatarStateMachine.h" #include "SGameInput.h" #include "SGameMessage.h" #include "SGameAvatarEx.h" #include "SkillBase.h" #include "SSkillDB.h" #include "ErrorCode/ErrorCode.h" #include "SSKillStageType.h" #include "SGamePlayer.h" /// 2011.05.11 - prodongi #include "SDebug_Util.h" #include "SGameSystem.h" #include "SUIDisplayInfo.h" extern SGameSystem * g_pCurrentGameSystem; using namespace GAME_INPUT; bool SPlayerStateMachine::s_bAutoForceChipAttack = true; void SPlayerStateMachine::OnNetInput( struct SGameMessage * pMsg ) { m_idState = SObjectState::ID::STATE_NONE; m_infoState = SStateInfo(); m_infoState.hSelf = m_pReceiver->GetArID(); m_infoState.vSelfPos = *m_pReceiver->GetPosition(); m_infoState.fRange = m_pReceiver->GetAttackRange(); switch( pMsg->nType ) { case MSG_ATTACK : { bool bEndAttack = false; bool bAiming = false; SMSG_ATTACK * pAttack = static_cast(pMsg); m_infoState.bMultiple = false; m_infoState.hSelf = pAttack->attacker_handle; m_infoState.hTarget = pAttack->target_handle; m_infoState.vTargetPos = pAttack->pos_target; //이동 할 위치 m_infoState.dwSpeed = pAttack->attack_speed; // ms m_infoState.dwDuration = pAttack->attack_delay; m_hTargetHandle = pAttack->target_handle; m_hAttackTarget = pAttack->target_handle; //공격 대상 m_infoState.attack_action = pAttack->attack_action; m_infoState.attack_flag = pAttack->attack_flag; m_infoState.count = pAttack->count; SGameAvatarEx* pTarget = (SGameAvatarEx*)m_pReceiver->GetGameObject( m_infoState.hTarget ); if( pAttack->attack_flag & TS_ATTACK_EVENT::ATTACK_FLAG_BOW || pAttack->attack_flag & TS_ATTACK_EVENT::ATTACK_FLAG_CROSS_BOW ) { if( pAttack->attack_action == TS_ATTACK_EVENT::ATTACK_AIMING ) { m_idState = SObjectState::STATE_AIMING; //활 조준 m_infoState.dwDuration = 0; bAiming = true; } else if( pAttack->attack_action == TS_ATTACK_EVENT::ATTACK_ATTACK) m_idState = SObjectState::STATE_SHOOTING; //활 쏘기 else if( pAttack->attack_action == TS_ATTACK_EVENT::ATTACK_CANCEL) { m_idState = SObjectState::STATE_CAST_CANCEL; //활 쏘기가 취소 됨 if( pTarget != NULL && pTarget->IsDead() == false ) bEndAttack = true; } else if( pAttack->attack_action == TS_ATTACK_EVENT::ATTACK_END ) { m_idState = SObjectState::STATE_ATTACK_END; //활 쏘기가 끝남 if( pTarget != NULL && pTarget->IsDead() == false ) bEndAttack = true; } } else { if( pAttack->attack_action == TS_ATTACK_EVENT::ATTACK_CANCEL) { m_idState = SObjectState::STATE_ATTACK_END; if( pTarget != NULL && pTarget->IsDead() == false ) bEndAttack = true; } else if( pAttack->attack_action == TS_ATTACK_EVENT::ATTACK_END ) { m_idState = SObjectState::STATE_CAST_CANCEL; if( pTarget != NULL && pTarget->IsDead() == false ) bEndAttack = true; } else { m_idState = SObjectState::STATE_ATTACK; } } for ( int i=0 ; i < pAttack->count ; ++i ) { m_infoState.vAttackInfoList.push_back( pAttack->m_vAttackInfoList[i] ); } if( bEndAttack ) return; if( bAiming ) return; } break; /* case MSG_ATTACK_DOUBLE : { SMSG_ATTACK_DOUBLE * pAttack = static_cast(pMsg); m_infoState.bMultiple = true; m_infoState.hSelf = pAttack->attacker_handle; m_infoState.hTarget = pAttack->target_handle; m_infoState.vTargetPos = pAttack->pos_target; //이동 할 위치 m_infoState.nDamage = pAttack->right_hand_damage; m_infoState.left_hand_damage = pAttack->left_hand_damage; m_infoState.dwSpeed = pAttack->attack_speed; // ms m_infoState.nPercentageHP = pAttack->hp_percentage; // HP % m_infoState.nFlag = pAttack->flag; m_hTargetHandle = pAttack->target_handle; for ( int i=0 ; i< CreatureElemental::ElementalType::COUNT ; ++i ) m_infoState.nAdditionalDamage[i] = pAttack->right_hand_elemental_damage[i]; // 추가데미지 for ( int i=0 ; i< CreatureElemental::ElementalType::COUNT ; ++i ) m_infoState.left_nAdditionalDamage[i] = pAttack->left_hand_elemental_damage[i]; // 추가데미지 m_idState = SObjectState::STATE_ATTACK; m_infoState.dwDuration = pAttack->attack_speed; //쌍활, 쌍석궁은 없음 } break;*/ case MSG_CANT_ATTACK : { SMSG_CANT_ATTACK* pCantAttack = static_cast(pMsg); //서버에서 공격 못 한다고 날아 왔다. m_pReceiver->ReqCancelAction(); if( pCantAttack->reason == RESULT_TOO_FAR ) { if( pCantAttack->target_handle != 0 ) { // m_idState = SObjectState::STATE_CAST_CANCEL; m_nNeedStopPos = NEED_STOP_POS; SInputAttack inputAttack( pCantAttack->target_handle, true ); OnInput( &inputAttack ); } } return; } break; case MSG_KMOVE: case MSG_MOVE : { SMSG_MOVE * pMove = static_cast(pMsg); /* // 같은 위치라면 그대로 둔다. K3DVector myPos = *m_pReceiver->GetPosition(); if( (int)myPos.x == (int)pMove->pos_target.x && (int)myPos.y == (int)pMove->pos_target.y ) { break; } */ //_oprint( "MSG_MOVE 01 : %d %f, %f, %f\n", pMsg->nType, pMove->pos_target.x, pMove->pos_target.y, pMove->pos_target.z ); m_infoState.bIsMovePos = true; m_infoState.vTargetPos = pMove->pos_target; //이동 할 위치 // _oprint( "MSG_MOVE 02 : %f, %f, %f\n", m_infoState.vTargetPos.x, m_infoState.vTargetPos.y, m_infoState.vTargetPos.z ); m_infoState.dwSpeed = pMove->speed; m_idState = SObjectState::STATE_MOVE; if ( m_idNextState != SObjectState::STATE_NONE ) { //타겟 Pos 사용... m_infoNext.vTargetPos = m_infoState.vTargetPos; //자동 공격 용 m_infoState = m_infoNext; m_infoState.dwSpeed = pMove->speed; //추적 Speed 는 그대로 사용 m_idState = SObjectState::STATE_CHASE; } if( !m_queInputState.empty() ) { PENDING_INPUT_STATE* prevstate = &m_queInputState.front(); if( prevstate->nInputID == RQ_MOVE ) { m_queInputState.pop(); } } } break; case MSG_MOUNT_SUMMON : { SMSG_MOUNT_SUMMON* pMountMsg = static_cast(pMsg); m_idState = SObjectState::STATE_MOUNT; m_infoState.hSelf = pMountMsg->handle; m_infoState.hTarget = pMountMsg->summon_handle; } break; case MSG_UNMOUNT_SUMMON : { SMSG_UNMOUNT_SUMMON* pUnMountMsg = static_cast(pMsg); m_idState = SObjectState::STATE_UNMOUNT; m_infoState.hSelf = pUnMountMsg->handle; m_infoState.hTarget = pUnMountMsg->summon_handle; m_infoState.UnMountFlag = pUnMountMsg->flag; } break; case MSG_SKILL_EVENT : { SMSG_SKILL_EVENT * pSkillEvent = static_cast(pMsg); switch( pSkillEvent->status_type ) { case TS_SC_SKILL::FIRE: { m_idState = SObjectState::STATE_FIRE; m_infoState.dwDuration = 1500; //발사 후 지속 시간 m_infoState.nRepeat = pSkillEvent->fire.count; // 갯수 m_infoState.bMultiple = pSkillEvent->fire.bMultiple; // true 실시간 연타 m_infoState.range = pSkillEvent->fire.range; // 스킬 효과 범위 m_infoState.target_count = pSkillEvent->fire.target_count;// 타겟 수 m_infoState.fire_count = pSkillEvent->fire.fire_count; //m_infoState.target_name = pSkillEvent->target_name; // Fraun performance tweak m_hTargetHandle = pSkillEvent->target; //기존 데이타 삭제 한다. if( !m_infoState.vSkillResult.empty() ) m_infoState.vSkillResult.erase( m_infoState.vSkillResult.begin(), m_infoState.vSkillResult.end() ); for ( int i=0 ; i< (int)pSkillEvent->vSkillResult.size() ; ++i ) { SkillResult skillresult; skillresult = pSkillEvent->vSkillResult[i]; m_infoState.vSkillResult.push_back( skillresult ); if( skillresult.GetType() == SkillResult::RUSH ) { if( skillresult.rush.bResult ) { m_idNextState = SObjectState::STATE_ATTACK; m_infoState.hTarget = skillresult.rush.hTarget; m_infoState.vTargetPos = K3DVector( skillresult.rush.x, skillresult.rush.y, 0.0f ); } } } } break; case TS_SC_SKILL::CASTING: if ( pSkillEvent->cast.nErrorCode == 0 ) { m_idState = SObjectState::STATE_CAST; m_infoState.vTargetPos = K3DVector( pSkillEvent->x, pSkillEvent->y, pSkillEvent->z ); m_infoState.dwSpeed = pSkillEvent->cast.tm; //casting Time } else if( pSkillEvent->cast.nErrorCode == RESULT_TOO_FAR ) { // 같은 대상에 같은 스킬을 쓰려고 했다면 다시 스킬 사용 시도 if( pSkillEvent->skill_id == m_infoNext.nSkillID && pSkillEvent->skill_level == m_infoNext.nSkillLv && pSkillEvent->target == m_infoNext.hTarget ) { SInputSkill inputSkill( m_infoNext.nSkillID, m_infoNext.nSkillLv, m_infoNext.hTarget, m_infoNext.fRange, m_infoNext.fSpellRange, m_infoNext.vRegionTargetPos, m_infoNext.isRegionTarget ); inputSkill.setIsValidToCorpse( m_infoNext.isValidToCorpse ); m_nNeedStopPos = NEED_STOP_POS; OnInput( &inputSkill ); } else { m_idState = SObjectState::STATE_SKILL_END; return; } } else { m_idState = SObjectState::STATE_SKILL_END; // StopCurrentState(); return; } break; case TS_SC_SKILL::CANCEL: { //TODO COMPLETE 처리 m_idState = SObjectState::STATE_CAST_CANCEL; break; } case TS_SC_SKILL::CASTING_UPDATE: { //TODO CASTING_UPDATE 처리 break; } case TS_SC_SKILL::REGION_FIRE: { //TODO REGION_FIRE 처리 break; } case TS_SC_SKILL::COMPLETE: { //TODO COMPLETE 처리 m_idState = SObjectState::STATE_SKILL_END; if( pSkillEvent->skill_id == SKILL_NAME::SKILL_WARP ) { //귀환 스킬이면 입력 잠그기 InputFreezing(); //워프 완료후 풀린다 } SkillBaseEx* s_data = GetSkillDB().GetSkillData( pSkillEvent->skill_id ); if( s_data ) { bool bCheck = (s_data->IsPhysicalSkill() && s_data->IsHarmful());// && (s_data->GetCastRange() == -1)); if( s_bAutoForceChipAttack ) { //포스칩만 예외처리 하자 // 2010.06.15 - prodongi //if( pSkillEvent->skill_id == FORCE_CHIP_SKILL_ID ) if( IS_AUTO_ATTACK_CHIP_SKILL_ID(pSkillEvent->skill_id)) bCheck = true; } m_infoState.autoattack = bCheck; //NeedTarget이면 서버에서 보내준 타겟으로 설정 //NeedTarget아니면 셀프형 ( 이번 타겟으로 유지 ) if( s_data->IsNeedTarget() ) m_hAttackTarget = m_hTargetHandle; } else m_hAttackTarget = m_hTargetHandle; break; } }; m_infoState.nSkillID = pSkillEvent->skill_id; m_infoState.nSkillLv = pSkillEvent->skill_level; m_infoState.hTarget = pSkillEvent->target; // m_infoState.nPercentageHP = pSkillEvent->target_hp_percentage; /// 2011.05.11 지면타겟 유무 설정 - prodongi SkillBaseEx* skill = GetSkillDB().GetSkillData(pSkillEvent->skill_id); if (skill && SkillBase::SKILL_TARGET_POSITION == skill->getTargetType()) m_infoState.isRegionTarget = true; } return; case MSG_STATUS_CHANGE : { SMSG_STATUS_CHANGE* pStatus = static_cast(pMsg); if ( pStatus->status & TS_ENTER::PlayerInfo::FLAG_SITDOWN ) { //이미 앉아 있으면, Skip if( m_pReceiver->GetStatus() & TS_ENTER::PlayerInfo::FLAG_SITDOWN ) return; m_idState = SObjectState::STATE_SIT; break; } else { //전투 모드 이면서, 일어나기를 해야 하는데. if( (pStatus->status & TS_ENTER::PlayerInfo::FLAG_BATTLE_MODE) && !(pStatus->status & TS_ENTER::PlayerInfo::FLAG_SITDOWN) ) { if( m_pReceiver->GetStatus() & TS_ENTER::PlayerInfo::FLAG_SITDOWN ) { m_idState = SObjectState::STATE_STAND_UP; m_pReceiver->SetIng(false); break; } } //전투 모드도 아니면서, 가만히 있는 경우~ if( !(pStatus->status & TS_ENTER::PlayerInfo::FLAG_BATTLE_MODE) && !(pStatus->status & TS_ENTER::PlayerInfo::FLAG_SITDOWN) ) { m_idState = SObjectState::STATE_IDLE; } } } break; case MSG_RESULT : { SMSG_RESULT* pResult = static_cast(pMsg); switch( pResult->request_msg_id ) { case TM_CS_SKILL: { //if( pResult->result != RESULT_SUCCESS) m_idState = SObjectState::STATE_SKILL_END; } break; case TM_CS_MOVE_REQUEST: { if( !m_queInputState.empty() ) { PENDING_INPUT_STATE* prevstate = &m_queInputState.front(); if( prevstate->nInputID == RQ_MOVE ) { m_queInputState.pop(); } } } break; case TM_CS_USE_ITEM: { if( pResult->result != RESULT_SUCCESS ) { if( m_pReceiver->IsUsingSkill() || m_pReceiver->IsAttack() ) return; m_idState = SObjectState::STATE_SKILL_END; } } break; case TM_CS_TAKE_ITEM: { if( m_pReceiver->IsMountMode() ) m_idState = SObjectState::STATE_IDLE; } break; } return; } case MSG_USE_ITEM_RESULT: { if( m_pReceiver->GetStatus() & TS_ENTER::PlayerInfo::FLAG_SITDOWN ) return; if( m_pReceiver->IsUsingSkill() || m_pReceiver->IsAttack() ) return; m_idState = SObjectState::STATE_SKILL_END; return; } // 무시 default: return; } m_idPrevState = m_idState; //SKILL_EVENT를 제외한 이전 상태를 저장한다 ( 스킬 시전후 자동 공격 기능을 위해서 ) } //==================================================================================================================================================== SLocalPlayerStateMachine::SLocalPlayerStateMachine() { AddState( CreateIdleState() ); AddState( CreateAttackState() ); AddState( CreateAttackEnd() ); AddState( CreateMoveState() ); AddState( CreateChaseState() ); AddState( CreateCastState() ); AddState( CreateThrowState() ); AddState( CreateFireState() ); AddState( CreateSkillEndState() ); AddState( CreateSitState() ); AddState( CreateStandUpState() ); AddState( CreateUseItemState() ); AddState( CreateTakeItemState() ); AddState( CreateCastCancelState() ); AddState( CreateAiMingState() ); AddState( CreateShootingState() ); AddState( CreateMountState() ); AddState( CreateUnMountState() ); // AddState()가 다 끝난 뒤에 호출할 것 SStateInfo info; SetDefaultState( SObjectState::STATE_IDLE, info ); } SObjectState* SLocalPlayerStateMachine::CreateIdleState() { SObjectState* pState = new SObjectState( SObjectState::STATE_IDLE ); pState->SetMode( Mode_All ); pState->AddRequestCommand( SObjectState::STATE_IDLE, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_ATTACK, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_ATTACK_END, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_MOVE, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_CHASE, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_THROW, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_SIT, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_TAKEITEM, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_USEITEM, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_CAST, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_CAST_CANCEL, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_FIRE, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_SKILL_END, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_AIMING, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_SHOOTING, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_MOUNT, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_UNMOUNT, SObjectState::PERMIT_IMMEDIATELY ); return pState; } SObjectState* SLocalPlayerStateMachine::CreateAttackState() { SObjectState* pState = new SObjectState( SObjectState::STATE_ATTACK ); pState->SetMode( Mode_Normal|Mode_Attack ); pState->SetMotionCancelInfo( true ); pState->AddRequestCommand( SObjectState::STATE_IDLE , SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_ATTACK , SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_ATTACK_END, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_MOVE , SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_CHASE , SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_THROW , SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_SIT , SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_TAKEITEM , SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_USEITEM, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_CAST , SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_CAST_CANCEL, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_FIRE , SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_SKILL_END , SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_AIMING, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_SHOOTING, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_MOUNT, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_UNMOUNT, SObjectState::PERMIT_FORBIDDEN ); return pState; } SObjectState* SLocalPlayerStateMachine::CreateAttackEnd() { SObjectState* pState = new SObjectState( SObjectState::STATE_ATTACK_END ); pState->SetMode( Mode_Normal|Mode_Attack ); pState->SetMotionCancelInfo( true ); pState->AddRequestCommand( SObjectState::STATE_IDLE, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_ATTACK, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_MOVE, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_CHASE, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_THROW, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_SIT, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_TAKEITEM, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_USEITEM, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_CAST, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_CAST_CANCEL, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_FIRE, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_SKILL_END , SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_AIMING, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_SHOOTING, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_MOUNT, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_UNMOUNT, SObjectState::PERMIT_FORBIDDEN ); return pState; } SObjectState* SLocalPlayerStateMachine::CreateMoveState() { SObjectState* pState = new SObjectState( SObjectState::STATE_MOVE ); pState->SetMode( Mode_All ); pState->AddRequestCommand( SObjectState::STATE_IDLE, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_ATTACK, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_ATTACK_END, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_MOVE, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_CHASE, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_THROW, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_SIT, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_TAKEITEM, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_USEITEM, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_CAST, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_CAST_CANCEL, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_FIRE, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_SKILL_END, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_AIMING, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_SHOOTING, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_MOUNT, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_UNMOUNT, SObjectState::PERMIT_FORBIDDEN ); return pState; } SObjectState* SLocalPlayerStateMachine::CreateChaseState() { SObjectState* pState = new SObjectState( SObjectState::STATE_CHASE ); pState->SetMode( Mode_Normal|Mode_Attack ); pState->AddRequestCommand( SObjectState::STATE_IDLE, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_ATTACK, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_ATTACK_END, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_MOVE, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_CHASE, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_THROW, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_SIT, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_TAKEITEM, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_USEITEM, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_CAST, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_CAST_CANCEL, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_FIRE, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_SKILL_END, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_AIMING, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_SHOOTING, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_MOUNT, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_UNMOUNT, SObjectState::PERMIT_FORBIDDEN ); return pState; } SObjectState* SLocalPlayerStateMachine::CreateCastState() { SObjectState* pState = new SObjectState( SObjectState::STATE_CAST ); pState->SetMode( Mode_Normal|Mode_Attack ); pState->AddRequestCommand( SObjectState::STATE_IDLE, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_ATTACK, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_ATTACK_END, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_MOVE, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_CHASE, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_THROW, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_SIT, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_TAKEITEM, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_USEITEM, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_CAST, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_CAST_CANCEL, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_FIRE, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_SKILL_END, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_AIMING, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_SHOOTING, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_MOUNT, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_UNMOUNT, SObjectState::PERMIT_FORBIDDEN ); return pState; } SObjectState* SLocalPlayerStateMachine::CreateThrowState() { SObjectState* pState = new SObjectState( SObjectState::STATE_THROW ); pState->SetMode( Mode_Normal|Mode_Attack ); pState->AddRequestCommand( SObjectState::STATE_IDLE, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_ATTACK, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_ATTACK_END, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_MOVE, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_CHASE, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_THROW, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_SIT, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_TAKEITEM, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_USEITEM, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_CAST, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_CAST_CANCEL, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_FIRE, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_SKILL_END, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_AIMING, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_SHOOTING, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_MOUNT, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_UNMOUNT, SObjectState::PERMIT_FORBIDDEN ); return pState; } SObjectState* SLocalPlayerStateMachine::CreateFireState() { SObjectState* pState = new SObjectState( SObjectState::STATE_FIRE ); pState->SetMode( Mode_Normal|Mode_Attack ); pState->SetMotionCancelInfo( true ); pState->AddRequestCommand( SObjectState::STATE_IDLE, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_ATTACK, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_ATTACK_END, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_MOVE, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_CHASE, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_THROW, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_SIT, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_TAKEITEM, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_USEITEM, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_CAST, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_CAST_CANCEL, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_FIRE, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_SKILL_END, SObjectState::PERMIT_IMMEDIATELY); pState->AddRequestCommand( SObjectState::STATE_AIMING, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_SHOOTING, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_MOUNT, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_UNMOUNT, SObjectState::PERMIT_FORBIDDEN ); return pState; } SObjectState* SLocalPlayerStateMachine::CreateSkillEndState() { SObjectState* pState = new SObjectState( SObjectState::STATE_SKILL_END ); pState->SetMode( Mode_Normal|Mode_Attack ); pState->SetMotionCancelInfo( true ); pState->AddRequestCommand( SObjectState::STATE_IDLE, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_ATTACK, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_ATTACK_END, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_MOVE, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_CHASE, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_THROW, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_SIT, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_TAKEITEM, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_USEITEM, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_CAST, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_CAST_CANCEL, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_FIRE, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_AIMING, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_SHOOTING, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_MOUNT, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_UNMOUNT, SObjectState::PERMIT_FORBIDDEN ); return pState; } SObjectState* SLocalPlayerStateMachine::CreateSitState() { SObjectState* pState = new SObjectState( SObjectState::STATE_SIT ); pState->SetMode( Mode_Normal|Mode_Attack ); pState->AddRequestCommand( SObjectState::STATE_IDLE, SObjectState::PERMIT_FORBIDDEN ); //STATE_NONE = 0, ///< 없음 (사용되지 않음) // STATE_IDLE, ///< 아이들 // STATE_ATTACK, ///< 공격 (1회) // STATE_MOVE, ///< 이동 // STATE_CHASE, ///< 추격 // STATE_CAST, ///< 캐스팅 // STATE_THROW, ///< 던지기 // STATE_FIRE, ///< 시전 // STATE_SKILL_END, ///< 시전 종료 // STATE_SIT, ///< 앉기 // STATE_STAND_UP, ///< 서기 //추가 해야 한다. // STATE_TAKEITEM, ///< 아이템 줍기 //추가 해야 한다. // STATE_USEITEM, ///< 아이템 사용 // STATE_CAST_CANCEL, ///< 캐스팅 취소 // STATE_AIMING, ///< 활 조준 // STATE_SHOOTING, ///< 활쏘기 // STATE_ATTACK_END, ///< 공격 종료 // STATE_MOUNT, ///< 올라탄상태 // STATE_UNMOUNT, ///< 내리기 pState->AddRequestCommand( SObjectState::STATE_ATTACK, SObjectState::PERMIT_IMMEDIATELY ); // 공격 pState->AddRequestCommand( SObjectState::STATE_ATTACK_END, SObjectState::PERMIT_IMMEDIATELY ); // 공격종료 pState->AddRequestCommand( SObjectState::STATE_MOVE, SObjectState::PERMIT_IMMEDIATELY ); // 이동 pState->AddRequestCommand( SObjectState::STATE_CHASE, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_THROW, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_SIT, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_STAND_UP, SObjectState::PERMIT_IMMEDIATELY); pState->AddRequestCommand( SObjectState::STATE_TAKEITEM, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_USEITEM, SObjectState::PERMIT_IMMEDIATELY); pState->AddRequestCommand( SObjectState::STATE_CAST, SObjectState::PERMIT_IMMEDIATELY ); // 캐스팅 pState->AddRequestCommand( SObjectState::STATE_CAST_CANCEL, SObjectState::PERMIT_IMMEDIATELY ); // 캐스팅 취소 pState->AddRequestCommand( SObjectState::STATE_FIRE, SObjectState::PERMIT_IMMEDIATELY ); // 시전 pState->AddRequestCommand( SObjectState::STATE_SKILL_END, SObjectState::PERMIT_IMMEDIATELY ); // 시전 종료 pState->AddRequestCommand( SObjectState::STATE_AIMING, SObjectState::PERMIT_IMMEDIATELY ); // 활 쏘기 조준 pState->AddRequestCommand( SObjectState::STATE_SHOOTING, SObjectState::PERMIT_IMMEDIATELY ); // 활 쏘기 pState->AddRequestCommand( SObjectState::STATE_MOUNT, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_UNMOUNT, SObjectState::PERMIT_FORBIDDEN ); return pState; } SObjectState* SLocalPlayerStateMachine::CreateStandUpState() { SObjectState* pState = new SObjectState( SObjectState::STATE_STAND_UP ); pState->SetMode( Mode_Normal|Mode_Attack ); pState->AddRequestCommand( SObjectState::STATE_IDLE, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_ATTACK, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_ATTACK_END, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_MOVE, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_CHASE, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_THROW, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_SIT, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_STAND_UP, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_TAKEITEM, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_USEITEM, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_CAST, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_CAST_CANCEL, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_FIRE, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_SKILL_END, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_AIMING, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_SHOOTING, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_MOUNT, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_UNMOUNT, SObjectState::PERMIT_FORBIDDEN ); return pState; } SObjectState* SLocalPlayerStateMachine::CreateCastCancelState() { SObjectState* pState = new SObjectState( SObjectState::STATE_CAST_CANCEL ); pState->SetMode( Mode_All ); pState->AddRequestCommand( SObjectState::STATE_IDLE, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_ATTACK, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_ATTACK_END, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_MOVE, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_CHASE, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_THROW, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_SIT, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_TAKEITEM, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_USEITEM, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_CAST, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_CAST_CANCEL, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_FIRE, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_SKILL_END, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_AIMING, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_SHOOTING, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_MOUNT, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_UNMOUNT, SObjectState::PERMIT_FORBIDDEN ); return pState; } SObjectState* SLocalPlayerStateMachine::CreateTakeItemState() { SObjectState* pState = new SObjectState( SObjectState::STATE_TAKEITEM ); pState->SetMode( Mode_All ); pState->AddRequestCommand( SObjectState::STATE_IDLE, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_ATTACK, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_ATTACK_END, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_MOVE, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_CHASE, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_THROW, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_SIT, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_TAKEITEM, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_USEITEM, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_CAST, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_CAST_CANCEL, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_FIRE, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_SKILL_END, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_AIMING, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_SHOOTING, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_MOUNT, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_UNMOUNT, SObjectState::PERMIT_FORBIDDEN ); return pState; } SObjectState* SLocalPlayerStateMachine::CreateUseItemState() { SObjectState* pState = new SObjectState( SObjectState::STATE_USEITEM ); pState->SetMode( Mode_All ); pState->AddRequestCommand( SObjectState::STATE_IDLE, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_ATTACK, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_ATTACK_END, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_MOVE, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_CHASE, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_THROW, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_SIT, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_TAKEITEM, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_USEITEM, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_CAST, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_CAST_CANCEL, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_FIRE, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_SKILL_END, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_AIMING, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_SHOOTING, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_MOUNT, SObjectState::PERMIT_IMMEDIATELY ); pState->AddRequestCommand( SObjectState::STATE_UNMOUNT, SObjectState::PERMIT_FORBIDDEN ); return pState; } SObjectState* SLocalPlayerStateMachine::CreateAiMingState() { SObjectState* pState = new SObjectState( SObjectState::STATE_AIMING ); pState->SetMode( Mode_Normal|Mode_Attack ); pState->AddRequestCommand( SObjectState::STATE_IDLE, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_ATTACK, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_ATTACK_END, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_MOVE, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_CHASE, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_THROW, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_SIT, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_TAKEITEM, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_USEITEM, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_CAST, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_CAST_CANCEL, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_FIRE, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_SKILL_END, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_AIMING, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_SHOOTING, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_MOUNT, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_UNMOUNT, SObjectState::PERMIT_FORBIDDEN ); return pState; } SObjectState* SLocalPlayerStateMachine::CreateShootingState() { SObjectState* pState = new SObjectState( SObjectState::STATE_SHOOTING ); pState->SetMode( Mode_Normal|Mode_Attack ); pState->SetMotionCancelInfo( true ); pState->AddRequestCommand( SObjectState::STATE_IDLE, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_ATTACK, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_ATTACK_END, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_MOVE, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_CHASE, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_THROW, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_SIT, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_TAKEITEM, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_USEITEM, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_CAST, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_CAST_CANCEL, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_FIRE, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_SKILL_END, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_AIMING, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_SHOOTING, SObjectState::PERMIT_PENDING ); pState->AddRequestCommand( SObjectState::STATE_MOUNT, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_UNMOUNT, SObjectState::PERMIT_FORBIDDEN ); return pState; } SObjectState* SLocalPlayerStateMachine::CreateMountState() { SObjectState* pState = new SObjectState( SObjectState::STATE_MOUNT ); pState->SetMode( Mode_All ); pState->AddRequestCommand( SObjectState::STATE_IDLE, SObjectState::PERMIT_IMMEDIATELY); pState->AddRequestCommand( SObjectState::STATE_ATTACK, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_ATTACK_END, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_MOVE, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_CHASE, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_THROW, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_SIT, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_TAKEITEM, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_USEITEM, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_CAST, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_CAST_CANCEL, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_FIRE, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_SKILL_END, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_AIMING, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_SHOOTING, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_MOUNT, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_UNMOUNT, SObjectState::PERMIT_IMMEDIATELY); return pState; } SObjectState* SLocalPlayerStateMachine::CreateUnMountState() { SObjectState* pState = new SObjectState( SObjectState::STATE_UNMOUNT ); pState->SetMode( Mode_All ); pState->AddRequestCommand( SObjectState::STATE_IDLE, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_ATTACK, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_ATTACK_END, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_MOVE, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_CHASE, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_THROW, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_SIT, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_TAKEITEM, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_USEITEM, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_CAST, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_CAST_CANCEL, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_FIRE, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_SKILL_END, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_AIMING, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_SHOOTING, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_MOUNT, SObjectState::PERMIT_FORBIDDEN ); pState->AddRequestCommand( SObjectState::STATE_UNMOUNT, SObjectState::PERMIT_FORBIDDEN ); return pState; } void SLocalPlayerStateMachine::SendServerReq( SObjectState::ID state, const SStateInfo &infoState ) { switch( state ) { case SObjectState::STATE_NONE: // 없음 (사용되지 않음) case SObjectState::STATE_STAND_UP: case SObjectState::STATE_IDLE:// 아이들 if ( m_pReceiver->GetStatus() & TS_ENTER::PlayerInfo::FLAG_SITDOWN ) { m_pReceiver->ReqStandUp(); } StartNewState( state, infoState ); break; case SObjectState::STATE_ATTACK: // 공격 (1회) { // _oprint( "SObjectState::STATE_ATTACK %u\n", infoState.hTarget ); m_pReceiver->ReqAttack( infoState.hTarget ); SetMode( MODE_ATTACK ); //전투 대기 모션으로 설정. } break; case SObjectState::STATE_MOVE: // 이동 //_oprint( "SObjectState::STATE_MOVE 01 \n" ); { m_pReceiver->ReqMove( infoState.hSelf, ArPosition( infoState.vTargetPos.x, infoState.vTargetPos.y ) ); if( !m_pReceiver->IsUseSkill_complete() ) break; if( m_pReceiver->IsUsingSkill() ) break; if( m_pReceiver->IsIng() ) break; //기존 데이터 삭제 while( !m_queInputState.empty() ) m_queInputState.pop(); //MOVE저장 한뒤 서버에 응답이 오면 삭제한다 PENDING_INPUT_STATE pendingstate( (SStateInfo*)&infoState, RQ_MOVE ); m_queInputState.push( pendingstate ); } break; case SObjectState::STATE_CHASE: // 추격 //_oprint( "SObjectState::STATE_MOVE 02 \n" ); m_pReceiver->ReqMove( infoState.hSelf, ArPosition( infoState.vTargetPos.x, infoState.vTargetPos.y ), false, true ); break; case SObjectState::STATE_CAST: // 캐스팅 m_pReceiver->ReqCast( infoState.hTarget, infoState.nSkillID, infoState.nSkillLv, infoState.vRegionTargetPos ); break; case SObjectState::STATE_THROW: // 던지기 m_pReceiver->ReqThrow( infoState.hTarget, infoState.hItem ); break; case SObjectState::STATE_FIRE: // 시전 // 오는 메시지 전용 스테이트 break; case SObjectState::STATE_SIT: // 앉기 m_pReceiver->ReqSit(); break; case SObjectState::STATE_TAKEITEM: //아이템 줍기 m_pReceiver->ReqTakeItem( infoState.hTarget ); break; case SObjectState::STATE_CAST_CANCEL: m_pReceiver->ReqCancelAction(); break; case SObjectState::STATE_MOUNT: m_pReceiver->ReqMount(); break; case SObjectState::STATE_UNMOUNT: m_pReceiver->ReqUnMount(); break; case SObjectState::STATE_USEITEM: m_pReceiver->ReqUseItem( infoState.hTarget, infoState.hItem, infoState.nSkillID, infoState.hItemUseTarget, infoState.strItemUseText.c_str() ); break; } } void SLocalPlayerStateMachine::PendingInput( struct PENDING_INPUT_STATE* pPendinginputstate ) { SObjectState::ID idState; SStateInfo infoState; infoState.hSelf = m_pReceiver->GetArID(); infoState.vSelfPos = *m_pReceiver->GetPosition(); switch( pPendinginputstate->nInputID ) { case RQ_ATTACK : { idState = SObjectState::STATE_ATTACK; infoState.hTarget = pPendinginputstate->sInfostate.hTarget; infoState.fRange = pPendinginputstate->sInfostate.fRange; break; } case RQ_THROW_ITEM : { idState = SObjectState::STATE_THROW; infoState.hItem = pPendinginputstate->sInfostate.hItem; infoState.hTarget = pPendinginputstate->sInfostate.hTarget; infoState.fRange = pPendinginputstate->sInfostate.fRange; break; } case RQ_CAST : { idState = SObjectState::STATE_CAST; infoState.hTarget = pPendinginputstate->sInfostate.hTarget; infoState.nSkillID = pPendinginputstate->sInfostate.nSkillID; infoState.nSkillLv = pPendinginputstate->sInfostate.nSkillLv; infoState.fRange = pPendinginputstate->sInfostate.fRange; infoState.fSpellRange = pPendinginputstate->sInfostate.fSpellRange; break; } case RQ_SIT: { //앉는 시간을 설정 한다. idState = SObjectState::STATE_SIT; break; } case RQ_SIT_UP: { //일어나는 시간을 설정 한다. idState = SObjectState::STATE_STAND_UP; break; } case RQ_TAKE_ITEM: { idState = SObjectState::STATE_TAKEITEM; infoState.hTarget = pPendinginputstate->sInfostate.hTarget; infoState.fRange = GameRule::MAX_TAKE_ITEM_RANGE; break; } case RQ_CAST_CANCEL: { idState = SObjectState::STATE_CAST_CANCEL; infoState.hTarget = pPendinginputstate->sInfostate.hTarget; break; } case RQ_MOUNT: { idState = SObjectState::STATE_MOUNT; break; } case RQ_UNMOUNT: { idState = SObjectState::STATE_UNMOUNT; break; } case RQ_USE_ITEM: { idState = SObjectState::STATE_USEITEM; infoState.hItem = pPendinginputstate->sInfostate.hItem; infoState.hTarget = pPendinginputstate->sInfostate.hTarget; break; } } if ( infoState.hTarget != 0 ) { SGameObject *pTarget = NULL; //소환과 역소환은 예외 처리 if( infoState.nSkillID == 4001 || infoState.nSkillID == 4002 ) pTarget = m_pReceiver->GetGameObject( infoState.hSelf ); else pTarget = m_pReceiver->GetGameObject( infoState.hTarget ); if ( pTarget == NULL ) return; //죽은 것은 공격 안 함. if( idState == SObjectState::STATE_ATTACK ) { if( ((SGameAvatarEx *)pTarget)->IsDead() ) return; } infoState.bIsMovePos = false; infoState.vTargetPos = *pTarget->GetPosition(); } RequestNewState( idState, infoState ); } //사용자 입력(키보드, 마우스) void SLocalPlayerStateMachine::OnInput( class SGameInput * pInput ) { if( m_bInputFreezing ) return; //입력 불가 SObjectState::ID idState; SStateInfo infoState; int inp=pInput->GetInputID(); if (inp==RQ_MOVE || inp==RQ_ATTACK || inp==RQ_USE_ITEM || inp==RQ_CAST) { int cur_tick = timeGetTime(); if ( last_skill_request_time > (cur_tick-delay_after_skill_request) && last_skill_request_timeGetArID(); infoState.vSelfPos = *m_pReceiver->GetPosition(); // m_idNextState = SObjectState::STATE_NONE; // 2010.06.15 아래쪽에서 세팅- prodongi //m_bAutoAttack = false; // 2010.09.09 - prodongi bool oldAutoAttack = m_bAutoAttack; setAutoAttack(false); switch( pInput->GetInputID() ) { case RQ_MOVE: { SInputMove* pMove = static_cast(pInput); idState = SObjectState::STATE_MOVE; infoState.bIsMovePos = true; infoState.vTargetPos = pMove->GetTargetPos(); SetDefaultPrevState(); break; } case RQ_ATTACK : { SInputAttack* pAttack = static_cast(pInput); idState = SObjectState::STATE_ATTACK; infoState.hTarget = pAttack->GetTargetHandle(); infoState.fRange = m_pReceiver->GetAttackRange(); infoState.chase = pAttack->IsChase(); // _oprint( "RQ_ATTACK : %f\n", infoState.fRange ); break; } case RQ_THROW_ITEM : { SInputThrowItem* pThrowItem = static_cast(pInput); idState = SObjectState::STATE_THROW; infoState.hItem = pThrowItem->GetItemHandle(); infoState.hTarget = pThrowItem->GetTargetHandle(); infoState.fRange = m_pReceiver->GetAttackRange(); break; } case RQ_CAST : { SInputSkill* pCast = static_cast(pInput); idState = SObjectState::STATE_CAST; infoState.hTarget = pCast->GetTargetHandle(); infoState.nSkillID = pCast->GetSkillID(); infoState.nSkillLv = pCast->GetSkillLv(); infoState.fRange = pCast->GetCastRange(); infoState.fSpellRange = pCast->GetSpellRange(); // 2010.05.24 - prodongi infoState.isValidToCorpse = pCast->isValidToCorpse(); /// 2010.10.14 - prodongi infoState.vRegionTargetPos = pCast->getTargetPos(); infoState.isRegionTarget = pCast->isRegionTarget(); // _oprint( "!!!!!RQ_CAST : %d %d\n", infoState.nSkillID, infoState.nSkillLv ); break; } case RQ_SIT: { //앉는 시간을 설정 한다. idState = SObjectState::STATE_SIT; break; } case RQ_SIT_UP: { //일어나는 시간을 설정 한다. idState = SObjectState::STATE_STAND_UP; break; } case RQ_TAKE_ITEM: { SInputTakeItem* pTakeItem = static_cast(pInput); idState = SObjectState::STATE_TAKEITEM; infoState.fRange = GameRule::MAX_TAKE_ITEM_RANGE; infoState.hTarget = pTakeItem->GetItemHandle(); break; } case RQ_CAST_CANCEL: { SInputCastCancel* pSkillCancel = static_cast(pInput); idState = SObjectState::STATE_CAST_CANCEL; infoState.hTarget = m_pReceiver->GetArID(); SetDefaultPrevState(); ClearPending(); ClearNextState(); break; } case RQ_MOUNT: { idState = SObjectState::STATE_MOUNT; break; } case RQ_UNMOUNT: { idState = SObjectState::STATE_UNMOUNT; break; } case RQ_USE_ITEM: { SInputUseItem* pUseItem = static_cast(pInput); // 2010.06.15 포스칩을 연달아 클릭했을때 자동 공격이 해지되는걸 막는다- prodongi //if (FORCE_CHIP_SKILL_ID == pUseItem->m_nSkillID) if (IS_AUTO_ATTACK_CHIP_SKILL_ID(pUseItem->m_nSkillID)) { // 2010.09.09 자동 공격 중일때도, 포스칩 사용은 되도록 수정- prodongi //if (m_bAutoAttack) // return ; setAutoAttack(oldAutoAttack); } idState = SObjectState::STATE_USEITEM; infoState.hItem = pUseItem->m_hItemHandle; infoState.hTarget = pUseItem->m_hTargetHandle; infoState.fRange = pUseItem->m_fUseRange; infoState.nSkillID = pUseItem->m_nSkillID; infoState.hItemUseTarget = pUseItem->m_hItemUseTarget; infoState.strItemUseText = pUseItem->m_strParameter; break; } } // 2010.06.15 - prodongi // 2010.09.09 - prodongi //setAutoAttack(false); if ( infoState.hTarget != 0 ) { SGameObject *pTarget = NULL; //소환과 역소환은 예외 처리 if( infoState.nSkillID == 4001 || infoState.nSkillID == 4002 ) pTarget = m_pReceiver->GetGameObject( infoState.hSelf ); else pTarget = m_pReceiver->GetGameObject( infoState.hTarget ); if ( pTarget == NULL ) return; //죽은 것은 공격 안 함. if( idState == SObjectState::STATE_ATTACK ) { if( ((SGameAvatarEx *)pTarget)->IsDead() ) return; } infoState.bIsMovePos = false; infoState.vTargetPos = *pTarget->GetPosition(); } // _oprint( "---->상태 입력 요청 : %d\n", idState ); if( m_idNextState != idState ) m_idNextState = SObjectState::STATE_NONE; //마운트 상태일때 공격 불과 bool bCheckMount = ( IsMountMode() || IsMount() ); bool bInput = ( pInput->GetInputID() == RQ_ATTACK || pInput->GetInputID() == RQ_CAST || pInput->GetInputID() == RQ_SIT || pInput->GetInputID() == RQ_SIT_UP ); if( bCheckMount ) { if( bInput ) return; if( pInput->GetInputID() == RQ_USE_ITEM ) { //마운트 상태일때 사용가능한 아이템 검사 SkillBaseEx* s_data = GetSkillDB().GetSkillData( infoState.nSkillID ); if( s_data ) { //대상에게 해로운 아이템 if( s_data->IsHarmful() ) return; } } } if( pInput->GetInputID() != RQ_MOVE ) { if( !m_queInputState.empty() ) { PENDING_INPUT_STATE* prevstate = &m_queInputState.front(); //첫번째 큐에 쌓인게 RQ_MOVE라면 서버에서 아직 응답을 안했다는 뜻 if( prevstate->nInputID == RQ_MOVE ) { //현재 입력을 저장한다 PENDING_INPUT_STATE pendingstate( &infoState, pInput->GetInputID() ); m_queInputState.push( pendingstate ); return; } } } RequestNewState( idState, infoState ); } //사용자 입력 응답(Server) void SLocalPlayerStateMachine::OnNetInput( struct SGameMessage * pMsg ) { SPlayerStateMachine::OnNetInput( pMsg ); if( m_idState == SObjectState::ID::STATE_NONE ) return; if ( m_infoState.hTarget != 0 ) { //소환, 역소환, 귀환, 복귀 깃털은 예외처리 if( m_infoState.nSkillID==4001 || m_infoState.nSkillID==4002 || m_infoState.nSkillID==6020 || m_infoState.nSkillID==6021 ) m_infoState.hTarget = m_infoState.hSelf; SGameObject *pTarget = m_pReceiver->GetGameObject( m_infoState.hTarget ); if ( pTarget == NULL ) return; m_infoState.bIsMovePos = false; // m_infoState.vTargetPos = *pTarget->GetPosition(); // m_infoState.fRange = m_pReceiver->GetAttackRange(); } if( m_infoState.autoattack ) { // 2010.06.15 - prodongi //m_bAutoAttack = m_infoState.autoattack; setAutoAttack(m_infoState.autoattack); } StartNewState( m_idState, m_infoState ); } //==================================================================================================================================================== void SOtherPlayerStateMachine ::OnNetInput( struct SGameMessage * pMsg ) { SPlayerStateMachine::OnNetInput( pMsg ); // _oprint( " SOtherPlayerStateMachine ::OnNetInput - %f %f %f\n", m_infoState.vTargetPos.x, m_infoState.vTargetPos.y, m_infoState.vTargetPos.z ); if ( m_infoState.hTarget != 0 ) { //소환, 역소환은 예외처리 if( m_infoState.nSkillID==4001 || m_infoState.nSkillID==4002 ) m_infoState.hTarget = m_infoState.hSelf; SGameObject *pTarget = m_pReceiver->GetGameObject( m_infoState.hTarget ); if ( pTarget == NULL ) return; m_infoState.bIsMovePos = false; // m_infoState.vTargetPos = *pTarget->GetPosition(); // m_infoState.fRange = m_pReceiver->GetAttackRange(); } //바로 갱신 m_pReceiver->OnChangeState( m_idState, m_infoState ); } //Npc상태는 현재 처리하지 않는다 ( 나중에 추가하자 ) void SNpcStateMachine::OnNetInput( struct SGameMessage * pMsg ) { return; }