void CWndDialog::RunScript( const char* szKey, DWORD dwParam, DWORD dwQuest ) { CMover* pMover = prj.GetMover( m_idMover ); if( pMover ) g_DPlay.SendScriptDialogReq( pMover->GetId(), szKey, dwParam, dwQuest, pMover->GetId(), g_pPlayer->GetId() ); m_timer.Set( SEC( 1 ) ); }
// 그리기 void CPuzzleGame::Draw() { LPDIRECT3DDEVICE9 device = Graphics->GetDevice(); Graphics->Clear(COL_WHITE); CStage* stage = Stage[StageIndex]; stage->Draw(); for (int order = 0, count = 0; count < MoverList->GetNumActiveTask(); order++) { for (CTaskIter i(MoverList); i.HasNext();) { CMover* mover = (CMover*)i.Next(); if (order == mover->DrawOrder) { mover->Draw(); count++; } } } Font->DrawText(wstring(L"\"") + stage->Name + L"\"", 0, 0, D3DCOLOR_RGBA(255, 116, 82, 255)); if (!StageActive) { Font->DrawText(L"PUSH BUTTON4 OR [B] TO START", 0, 32, D3DCOLOR_RGBA(255, 116, 82, 255)); } }
// // 극단 듀얼 해제 // void CParty::DoDuelPartyCancel( CParty* pDuelParty ) { #ifndef __CORESERVER int i; CMover *pMember; for( i = 0; i < m_nSizeofMember; i ++ ) // 극단원 모두에게 듀얼 해제를 세팅하고 클라에도 알림. { #ifdef __WORLDSERVER pMember = (CMover *)g_UserMng.GetUserByPlayerID( m_aMember[i].m_uPlayerId ); #else #ifdef __CLIENT pMember = prj.GetUserByID( m_aMember[i].m_uPlayerId ); #endif #endif // worldserver if( IsValidObj( pMember ) ) { #ifdef __WORLDSERVER if( pDuelParty ) ((CUser *)pMember)->AddDuelPartyCancel( pDuelParty ); // 각 멤버들에게 듀얼이 취소되었다고 알림. else ((CUser *)pMember)->AddDuelPartyCancel( NULL ); // 각 멤버들에게 듀얼이 취소되었다고 알림. if( pMember->m_idDuelParty != m_idDuelParty ) Error( "CParty::DoDuelPartyCancel : 파티멤버 %s의 정보이상. %d %d", pMember->GetName(), pMember->m_idDuelParty, m_idDuelParty ); pMember->ClearDuelParty(); #endif // worldserver } } m_idDuelParty = 0; // 파티 해제 #endif // __CORESERVER }
// AI가 제어할 수 있는가? BOOL CAIMonster2::IsControllable() { CMover* pMover = GetMover(); // 죽었을 경우 or 데미지 플라이 상태? if( pMover->IsDie() || (pMover->m_pActMover->GetState() & OBJSTA_DMG_FLY_ALL) ) return FALSE; return TRUE; }
void CQuiz::RemoveNPC() { CMover* pMover = prj.GetMover( m_sNPC.idNpc ); if( IsValidObj( pMover ) ) { g_UserMng.AddCreateSfxObj( pMover, XI_SKILL_MER_ONE_SPECIALHIT02 ); pMover->Delete(); } }
static int _SetDestParam( lua_State *L ) { CMover *pMover = (CMover *)lua_touserdata(L, 1); int nDST = (int)lua_tonumber(L, 2); int nAdd = (int)lua_tonumber(L, 3); pMover->SetDestParam( nDST, nAdd, NULL_CHGPARAM ); return 0; }
static int _ResetDestParam( lua_State *L ) { CMover *pMover = (CMover *)lua_touserdata(L, 1); int nDST = (int)lua_tonumber(L, 2); int nAdj = (int)lua_tonumber(L, 3); pMover->ResetDestParam( nDST, nAdj, TRUE ); return 0; }
void CAIMonster2::MoveToDst( const D3DXVECTOR3& vDst ) { CMover* pMover = GetMover(); if( pMover->GetDestPos() == vDst ) return; pMover->SetDestPos( vDst ); pMover->m_nCorr = -1; g_UserMng.AddSetDestPos( pMover, vDst, 1 ); }
void CAIMonster2::InitAI() { CMover* pMover = GetMover(); MoverProp* pProperty = pMover->GetProp(); ASSERT( pProperty ); if( pProperty->dwAI >= AII_VER2_TYPE0 ) m_dwFsmType = pProperty->dwAI - AII_VER2_TYPE0; m_vPosBegin = pMover->GetPos(); m_fAttackRange = pMover->GetRadiusXZ(); }
void CWndIndirectTalk::OnDraw( C2DRender* p2DRender ) { CWorld* pWorld = g_WorldMng(); CMover* pMover = (CMover*)pWorld->GetObjFocus(); CWndEdit* pWndEdit = (CWndEdit*)GetDlgItem( WIDC_EDIT1 ); TCHAR szNum[ 32 ]; if( pMover && pMover->GetType() == OT_MOVER ) itoa( pMover->GetId(), szNum, 10 ); else itoa( 0, szNum, 10 ); pWndEdit->SetString( szNum ); }
// // nDmgCnt : 일반적으론 0 : 지속데미지를 사용할경우에 0이 아닌값이 들어온다. // void CSfx::DamageToTarget( int nDmgCnt, float fDmgAngle, float fDmgPower, int nMaxDmgCnt ) { CMover* pObjSrc = (CMover*)prj.GetCtrl( m_idSrc ); CCtrl* pObjDest = prj.GetCtrl( m_idDest ); if( IsInvalidObj(pObjSrc) ) return; // 지금은 걍 리턴하지만 이렇게 실패한경우는 m_idSfxHit을 Clear해주는작업이 필요하다. if( IsInvalidObj(pObjDest) ) return; if( pObjDest->GetType() == OT_MOVER ) { CMover* pMover = (CMover*) pObjDest; #ifdef __CLIENT PLAYSND( pMover->GetProp()->dwSndDmg2, &pMover->GetPos() ); // 마법류 맞을때 타격음. #endif #ifdef __CLIENT // 쏜놈이 플레이어이거나 / 쏜놈은 플레이어가 아닌데 맞은놈이 플레이어일경우 전송 if( pObjSrc->IsActiveMover() || (pObjSrc->IsPlayer() == FALSE && pObjDest->IsActiveObj()) ) { pMover->SetDmgCnt( 10 ); // 발사체 맞아도 이제 흔들린다, g_DPlay.SendSfxHit( m_idSfxHit, m_nMagicPower, m_dwSkill, pObjSrc->GetId(), nDmgCnt, fDmgAngle, fDmgPower ); if( nMaxDmgCnt == 1 ) // 한방짜리 데미지만 id를 클리어 함. m_idSfxHit = 0; // 0으로 해놔야 this가 삭제될때 SendSfxClear를 또 보내지 않는다. } #endif // __CLIENT } }
void CAIMonster2::OnBeginState( int nInput, DWORD dwParam1, DWORD dwParam2 ) { CMover* pMover = GetMover(); switch( GetState() ) { case AI2_MOVE: { D3DXVECTOR3 vPos = m_vPosBegin; int x = xRandom( 20 ); int z = xRandom( 20 ); vPos.x += (float)(x - 10); vPos.z += (float)(z - 10); MoveToDst( vPos ); // y는 어떻게 되나? } break; case AI2_IDLE: //m_dwReattack = GetTickCount() + xRandom( 0, 2000 ); m_dwReattack = GetTickCount() + 2000; m_idTarget = NULL_ID; m_vTarget.x = m_vTarget.y = m_vTarget.z = 0.0f; pMover->SetStop(); MoveToDst( pMover->GetPos() ); break; case AI2_ATTACK: if( BeginAttack() == FALSE ) // 공격 SendAIMsg( AIMSG_END_MELEEATTACK, 0, 0 ); // 실패할 경우 공격완료 메세지는 오지 않는다. break; case AI2_TRACKING: if( m_idTarget == NULL_ID ) { m_idTarget = m_idLastAttacker; ASSERT( m_idTarget != NULL_ID ); } #ifdef __TRAFIC_1222 if( pMover->GetDestId() == m_idTarget ) break; #endif // __TRAFIC_1222 // 이동할 목표물을 idTarget으로 설정. pMover->SetDestObj( m_idTarget, m_fAttackRange ); g_UserMng.AddMoverSetDestObj( pMover, m_idTarget, m_fAttackRange ); break; case AI2_SEARCH: break; } }
void MainWindow::on_actionMoveIt_triggered() { Gepard::MathModel *mathModel = g_manager.GetMathModelPtr(); CMover m (mathModel->Solids[0]); GPDVector vect; vect.x =0; vect.y =0; vect.z =-1; GPDPoint point(0,0,0); //CMovements mc = CMovements(EMovementTypes::CIRCULAR,point,"",vect,1.0,0,1); CMovements ml(EMovementTypes::LINEAR,point,"",vect,20.0,0,5); // CMovements mr = CMovements(); // mr.SetAxis(GPDVector(0,-1,0)); // mr.SetMovementType(CIRCULAR); // mr.SetPoint(point); // mr.SetShift(2.0); // mr.SetStart(0); // mr.SetEnd(0); m.AddMovement(ml); //m.AddMovement(mr); //m.AddMovement(mc); int cnt = m.GetSizeOfmovementsVector(); for (int i =0;i<cnt;i++) { int _cnt = m.GetStepsCntForMovement(i); for (int j=0;j<_cnt;j++) { m.OneStepMove(i,j); g_manager.HideSolid(mathModel->Solids[0]); mathModel->PrepareGeometry(); g_manager.ShowSolidInRender(mathModel->Solids[0],GeometryRenderManager::GetCamera(0)); //break; //Sleep(1000); } } // m.MoveIt(0); // g_manager.HideSolid(mathModel->Solids[0]); // g_manager.ShowSolidInRender(mathModel->Solids[0],GeometryRenderManager::GetCamera(0)); // Gepard::Analysis::KeyCharacteristicsPtrArray* kca = mathModel->GetKCArrayPtr(); // // kca->set_start(); // while (auto curKC = kca->get_next()) // { // (*curKC)->Analize(); // } }
void CMover::CMD_SetCollect( CObj *pObj ) { if( IsInvalidObj( pObj ) ) return; if( pObj->GetType() != OT_MOVER ) return; if( m_pActMover->IsActAttack() ) return; if( m_pActMover->IsActJump() ) return; if( m_pActMover->IsActDamage() ) return; if( IsDie() ) return; // 죽었을때 사용금지. // if( GetCollector()) { CMover *pTarget = (CMover *)pObj; ClearActParam(); SetDestObj( pTarget->GetId(), 3.0f ); // 이동할 목표물을 idTarget으로 설정. SetCmd( OBJACT_COLLECT, pTarget->GetId() ); // 사정거리가 되었을때 실행할 명령 셋팅. } }
BOOL CAIMonster2::IsInValidTarget() { if( m_idTarget == NULL_ID ) return TRUE; CMover* pTarget = prj.GetMover( m_idTarget ); if( IsValidObj( pTarget ) == FALSE ) return TRUE; if( pTarget->IsDie() ) return TRUE; if( GetMover()->IsFlyingNPC() != pTarget->m_pActMover->IsFly() ) return TRUE; return FALSE; }
// 동작 void CPuzzleGame::Move() { // 입력 Input->UpdateState(); const CInputState* is = Input->GetState(0); // 일시 정지(스크린샷용) if (!PrevInput && is->Button[5]) Paused = !Paused; // 스테이지의 동작 if (!Paused) { if (StageActive) { StageActive = Stage[StageIndex]->Move(is); for (CTaskIter i(MoverList); i.HasNext();) { CMover* mover = (CMover*)i.Next(); if (!mover->Move(is)) i.Remove(); } if (!PrevInput && is->Button[4]) StageActive = false; } else { if (!PrevInput) { if (is->Button[4]) { StageActive = true; SetStage(StageIndex); } else if (is->Left) SetStage(StageIndex - STAGE_ORDER); else if (is->Right) SetStage(StageIndex + STAGE_ORDER); else if (is->Up) SetStage(StageIndex - 10 * STAGE_ORDER); else if (is->Down) SetStage(StageIndex + 10 * STAGE_ORDER); } } } // 이전 입력 PrevInput = is->Button[4] || is->Button[5]; if (!StageActive) PrevInput = PrevInput || is->Left || is->Right || is->Up || is->Down; }
void CCommonCtrl::DestroyWall( void ) { #ifdef __WORLDSERVER // 시전자의 사이킥월 생성정보에서 지워줌. CMover *pAttacker = prj.GetMover( m_idAttacker ); if( IsValidObj(pAttacker) ) { if( pAttacker->IsPlayer() ) { for( int i = 0; i < 2; i ++ ) { if( ((CUser *)pAttacker)->m_pWall[i] == this ) ((CUser *)pAttacker)->m_pWall[i] = NULL; } } } Delete(); #endif // WorldServer }
// return: attacker의 포인터 CMover* CActionMover::PreProcessDamage( CMover* pMover, OBJID idAttacker, BOOL bTarget, int nReflect ) { if( pMover->m_dwMode & MATCHLESS_MODE ) // 무적이면 여기서 리턴. return NULL; #if __VER >= 10 // __LEGEND // 10차 전승시스템 Neuz, World, Trans if( pMover->GetAdjParam( DST_CHRSTATE ) & CHS_SETSTONE) return NULL; #endif //__LEGEND // 10차 전승시스템 Neuz, World, Trans CCtrl* pCtrl = prj.GetCtrl( idAttacker ); // 공격자 if( IsValidObj( pCtrl ) == FALSE ) return NULL; CMover* pAttacker = NULL; if( pCtrl->GetType() == OT_MOVER ) pAttacker = (CMover*)pCtrl; else return NULL; if( pMover->IsNPC() ) // 맞는넘이 NPC고 { MoverProp *pProp = pMover->GetProp(); if( pProp && pProp->bKillable != 1 ) // 죽이기가 불가능 한넘이면 여기서 리턴. return NULL; } #ifdef __WORLDSERVER HITTYPE ht = pAttacker->GetHitType( pMover, bTarget, nReflect ); if( ht == HITTYPE_FAIL ) return 0; #if __VER < 10 // __METEONYKER_0608 pMover->PostAIMsg( AIMSG_DAMAGE, idAttacker ); #endif // __METEONYKER_0608 #endif pAttacker->RemoveInvisible(); return pAttacker; }
void CParty::GetPoint( int nTotalLevel, int nMemberSize, int nDeadLeavel ) { #ifdef __WORLDSERVER #ifndef __PARTYDEBUG if( (nTotalLevel / nMemberSize) - nDeadLeavel < 5 ) #endif // __PARTYDEBUG { BOOL bExpResult = TRUE; BOOL bSuperLeader = FALSE; #if __VER >= 12 // __JHMA_VER12_1 //12차 극단유료아이템 BOOL bLeaderSMExpUp = FALSE; #endif // //12차 극단유료아이템 if( m_nKindTroup == 0 && m_nLevel >= MAX_PARTYLEVEL ) bExpResult = FALSE; CMover* pMover = GetLeader(); if( pMover && pMover->HasBuff( BUFF_ITEM, II_SYS_SYS_SCR_SUPERLEADERPARTY ) ) { bSuperLeader = TRUE; } #if __VER >= 12 // __JHMA_VER12_1 //12차 극단유료아이템 #define II_SYS_SYS_SCR_PARTYEXPUP01_01 20296 #define II_SYS_SYS_SCR_PARTYSKILLUP01_01 20297 if( pMover && ( pMover->HasBuff( BUFF_ITEM2, II_SYS_SYS_SCR_PARTYEXPUP01 ) || pMover->HasBuff( BUFF_ITEM2, II_SYS_SYS_SCR_PARTYEXPUP02 ) || pMover->HasBuff( BUFF_ITEM2, II_SYS_SYS_SCR_PARTYEXPUP01_01 ) ) ) { bLeaderSMExpUp = TRUE; } #endif // //12차 극단유료아이템 if( bExpResult ) #if __VER >= 12 // __JHMA_VER12_1 //12차 극단유료아이템 g_DPCoreClient.SendAddPartyExp( m_uPartyId, nDeadLeavel, bSuperLeader , bLeaderSMExpUp ); #else // //12차 극단유료아이템 g_DPCoreClient.SendAddPartyExp( m_uPartyId, nDeadLeavel, bSuperLeader ); #endif // //12차 극단유료아이템 } #endif // __WORLDSERVER }
// // fRange = 도달범위. 디폴트는 0.0f은 상대방의 반경까지 붙는거다. void CMover::SetDestObj( OBJID objid, float fRange, BOOL bSend ) { #ifdef __WORLDSERVER if( FALSE == IsPlayer() && m_idDest != objid ) m_nCorr = -1; #else // __WORLDSERVER if( bSend && IsActiveMover() && m_idDest != objid ) { #ifdef __BS_ADJUST_SYNC CMover* pTarget = prj.GetMover( m_idDest ); if( pTarget ) { if( pTarget->IsPlayer( ) ) g_DPlay.SendPlayerBehavior(); // 새로운 Obj로 이동할경우 동기화 한번 맞춰주고.... } #endif g_DPlay.SendPlayerDestObj( objid, fRange ); m_nCorr = -1; } #endif // not __WORLDSERVER m_idDest = objid; m_fArrivalRange = fRange; ClearDestPos(); #ifdef __WORLDSERVER // 서버에서 SetDestObj를 실행하면 클라들에게 보내주는게 없어서 이걸 넣음. if( bSend ) g_UserMng.AddMoverSetDestObj( this, objid, fRange, FALSE ); #endif // __WORLDSERVER #ifdef __CLIENT m_oaCmd = OBJACT_NONE; // CMD_ 시리즈를 거치지 않고 이것만 호출되는 경우는 Cmd를 해제시키자. #endif // Client // if( IsPlayer() ) // TRACE( "SetDestObj %08x\n", objid ); }
void CQuiz::SetNPC() { CMover* pMover = (CMover*)CreateObj( D3DDEVICE, OT_MOVER, m_sNPC.dwNPCId ); if( !pMover ) { Error( "CQuiz::SetNPC() - pMover is NULL - %d, %s", m_sNPC.dwNPCId, m_sNPC.strCharKey.c_str() ); return; } lstrcpy( pMover->m_szCharacterKey, m_sNPC.strCharKey.c_str() ); pMover->InitNPCProperty(); pMover->InitCharacter( pMover->GetCharacter() ); pMover->SetPos( m_sNPC.vPos ); pMover->InitMotion( MTI_STAND ); pMover->UpdateLocalMatrix(); pMover->AddItToGlobalId(); m_sNPC.idNpc = pMover->GetId(); CWorld* pWorld = g_WorldMng.GetWorld( WI_WORLD_MADRIGAL ); if( pWorld ) pWorld->ADDOBJ( pMover, FALSE, nDefaultLayer ); }
void CCreateMonster::ProcessRemoveMonster() { if( m_mapCreateMonsterInfo.empty() ) return; DWORD dwTick = GetTickCount(); for( MAPINFO::iterator it=m_mapCreateMonsterInfo.begin(); it!=m_mapCreateMonsterInfo.end(); it++ ) { CREATE_MONSTER_INFO* pCreateMonsterInfo = &it->second; if( dwTick >= pCreateMonsterInfo->dwEndTick ) { CMover* pMover = prj.GetMover( it->first ); if( IsValidObj( pMover ) ) { if( pMover->IsLive() && !pMover->IsDelete() ) { pCreateMonsterInfo->chState = 'R'; pMover->Delete(); } } } } }
FOR_LINKMAP( GetWorld(), vPos, pObj, nRange, CObj::linkPlayer, GetLayer() ) { if( pObj->GetType() == OT_MOVER ) // 대상이 무버일때만. { CMover *pTarget = (CMover *)pObj; if( pTarget->IsLive() && pAttacker != pTarget ) { if( pObj->IsRangeObj( vPos, 1.0f ) ) { #if __VER >= 9 // __SKILL_0706 int n = 0; if( bPVP && pAttacker->IsPVPTarget( pTarget ) ) n = pTarget->m_pActMover->SendDamage( AF_FORCE, pAttacker->GetId(), nDamagePVP, FALSE ); else if( bPVP && (m_bControl || pAttacker->IsGuildCombatTarget( pTarget ) /*아레나 추가*/ || pAttacker->IsArenaTarget( pTarget ) ) ) n = pTarget->m_pActMover->SendDamage( AF_FORCE, pAttacker->GetId(), nDamage, FALSE ); #else // __SKILL_0706 int n = pTarget->m_pActMover->SendDamage( AF_FORCE, pAttacker->GetId(), nDamage, FALSE ); #endif // __SKILL_0706 if( n > 0 ) { m_nLife ++; // 부딪힐때마다 카운트 올라감 if( m_nLife >= (int)( m_pAddSkillProp->dwSkillLvl / 2 ) ) DestroyWall(); // 뒤로 밀리기 처리. FLOAT fPushAngle = pTarget->GetAngle() + 180.0f; FLOAT fPower = 0.825f; AngleToVectorXZ( &pTarget->m_pActMover->m_vDeltaE, fPushAngle, fPower ); g_UserMng.AddPushPower( pTarget, pTarget->GetPos(), pTarget->GetAngle(), fPushAngle, fPower ); } } } } }
void CPartyMng::PartyMapInfo( ) { const float PARTY_MAP_AROUND = 32.0f * 32.0f; // m_nVisibilityRange에 영향을 받는다. if( ++m_nSecCount < PARTY_MAP_SEC ) return; m_nSecCount = 0; D3DXVECTOR3 vPosBuf; float fDist; for( C2PartyPtr::iterator i = m_2PartyPtr.begin(); i != m_2PartyPtr.end(); ++i ) { CParty* pParty = (CParty*)i->second; for( int j = 0 ; j < pParty->GetSizeofMember() ; ++j ) { CMover* pMover = prj.GetUserByID( pParty->GetPlayerId( j ) ); if( !IsValidObj( pMover ) ) continue; vPosBuf = pMover->GetPos() - pParty->GetPos( j ); fDist = D3DXVec3LengthSq( &vPosBuf ); if( 0.0f < fDist ) { pParty->SetPos( j, pMover->GetPos() ); CMover* pSendMover; for( int k = 0 ; k < pParty->GetSizeofMember() ; ++k ) { if( k == j ) continue; pSendMover = prj.GetUserByID( pParty->GetPlayerId( k ) ); if( !IsValidObj( pSendMover ) ) continue; vPosBuf = pSendMover->GetPos() - pMover->GetPos(); fDist = D3DXVec3LengthSq( &vPosBuf ); if( fDist > PARTY_MAP_AROUND ) ((CUser*)pSendMover)->AddPartyMapInfo( j, pMover->GetPos() ); } } } } }
// // 비행중 공격 액션 처리 // void CActionMover::_ProcessStateAttack2( DWORD dwState, int nParam ) { CMover* pMover = m_pMover; CModelObject *pModel = (CModelObject *)pMover->m_pModel; switch( dwState ) { case OBJSTA_ATK1: if( pModel->IsEndFrame() ) ResetState( OBJSTA_ATK_ALL ); if( pModel->m_nPause > 0 ) { --pModel->m_nPause; } else { if( pModel->IsAttrHit() ) { CMover* pHitObj = prj.GetMover( m_objidHit ); if( IsInvalidObj( pHitObj ) || pHitObj->IsDie() ) // 타겟이 거시기하거나 죽었으면 취소 return; BOOL bSuccess = pHitObj->m_pActMover->SendDamage( AF_GENERIC, pMover->GetId() ); if( bSuccess == FALSE ) return; #ifdef __CLIENT ItemProp* pItemProp = pMover->GetActiveHandItemProp(); if( pItemProp ) { D3DXVECTOR3 v = pMover->GetPos(); PLAYSND( pItemProp->dwSndAttack1, &v ); } #endif if( GetMover()->IsPlayer() ) { pModel->m_nPause = 5; // frame 멈춤 } else { pModel->m_nPause = 0; // 몬스터는 멈추지 않음 pHitObj->m_pModel->m_nPause = 0; } } } break; } }
DWORD CActionMover::OnDamageMsgC( DWORD dwMsg, CMover* pAttacker, DWORD dwAtkFlags, int nParam ) { CMover* pMover = GetMover(); BOOL bValid = IsValidObj( pMover ) && IsValidObj( pAttacker ); if( !bValid || IsState( OBJSTA_DIE_ALL ) ) return 0; if( IsSit() ) // 앉아있다가 맞으면 앉기해제 한다. ResetState( OBJSTA_MOVE_ALL ); SendActMsg( OBJMSG_STAND ); // 날때린놈에 대한 정보를 기록함. if( pMover->IsNPC() && pAttacker->IsPlayer() ) // 맞은놈은 NPC , 어태커가 플레이어 일때만 적용됨 { pMover->m_idAttacker = pAttacker->GetId(); // 날 때린넘이 어떤놈인가를 기록함. pMover->m_idTargeter = pAttacker->GetId(); } pAttacker->m_idLastHitMover = pMover->GetId(); // 어태커가 마지막으로 때렸던넘이 나란걸 기록함. if( (dwAtkFlags & AF_GENERIC) ) { ItemProp* pAttackerProp = pAttacker->GetActiveHandItemProp(); D3DXVECTOR3 vLocal; if( pAttackerProp && pAttackerProp->dwItemKind3 == IK3_YOYO ) { vLocal = pMover->GetPos(); vLocal.y += 1.0f; } else { AngleToVectorXZ( &vLocal, pAttacker->GetAngle(), 1.0f ); vLocal += pMover->GetPos(); //gmpbigsun : 피격자 일반 effect 09_12_17 vLocal.y += 1.0f; // 2006/6/20 xuzhu } if( pAttackerProp && pAttackerProp->dwSfxObj3 != NULL_ID ) CreateSfx( g_Neuz.m_pd3dDevice, pAttackerProp->dwSfxObj3, vLocal ); if( pAttackerProp && pAttackerProp->dwSfxObj5 != NULL_ID ) //gmpbigsun: 공격자 일반 effect 09_12_17 { vLocal = pAttacker->GetPos( ); CreateSfx( g_Neuz.m_pd3dDevice, pAttackerProp->dwSfxObj5, vLocal ); } } else if ( (dwAtkFlags & AF_MONSTER_SP_CLIENT) ) { // hitter ItemProp* pAttackerProp = prj.GetItemProp( nParam >> 16 ); assert( pAttackerProp ); DWORD dwSfxObj = pAttackerProp->dwSfxObj3; // gmpbigsun:특수공격에 이펙트가 있다면 3번사용. if( dwSfxObj != NULL_ID ) CreateSfx( D3DDEVICE, dwSfxObj, pMover->GetPos() ); // attacker dwSfxObj = pAttackerProp->dwSfxObj5; if( NULL_ID != dwSfxObj ) CreateSfx( D3DDEVICE, dwSfxObj, pAttacker->GetPos() ); }
void _update_console( ) { if( GetAsyncKeyState( VK_CONTROL ) & 0x80000 ) { if( g_bKeyTable[ 'T' ] ) { //test mail CMover* pObj = (CMover*)g_WorldMng.Get()->GetObjFocus( ); if( pObj ) { char* lpszTitle = "letter"; CString title; char* lpszText = "난 알아요 이밤이 흐르고 흐르면 모든것이 떠나야만 한다는 이사실을 그 이유를 나는 알수가 알수가 있어욤 taeji boys ye"; for( int i = 0; i < 90; ++i ) { title.Format( "%d 번째 편지", i ); g_DPlay.SendQueryPostMail( 1, 1, (char*)pObj->GetName(), 0,title.GetBuffer(0),lpszText ); } } //g_Console._bTestToggle = !g_Console._bTestToggle; //g_Console.Log( "Toggle func - testing is %d", g_Console._bTestToggle ); //if( !g_WndMng.m_pWndGHBid ) //{ // g_WndMng.m_pWndGHBid = new CWndGuildHouseBid; // g_WndMng.m_pWndGHBid->Initialize( ); //}else // SAFE_DELETE( g_WndMng.m_pWndGHBid ); } else if( g_bKeyTable[ 'Y' ] ) { CMailBox* pMailBox = CMailBox::GetInstance(); int nMax = pMailBox->size(); CMailBox& mailbox = *pMailBox; for( int i = 0; i < nMax; ++i ) { CMail* pMail = mailbox[i]; if( pMail ) { g_DPlay.SendQueryRemoveMail( pMail->m_nMail ); } } } } static DWORD sDelta = 0; static DWORD sOld = timeGetTime( ); // DWORD dwCur = timeGetTime( ); DWORD dwDt = dwCur - sOld; sDelta += dwDt; sOld = dwCur; #ifdef __CON_AUTO_LOGIN _update_auto_login( sDelta ); #endif if( g_Console._bRandomMoving ) RandomMoving( dwDt ); // if( sDelta > 5000 ) // { // ++debugIndex; // // while( 1 ) // { // BOOL bOK = PlayMusic( debugIndex, 1 ); // if( bOK ) // { // g_Console.Log( " Started music : %d ", debugIndex ); // break; // } // // ++debugIndex; // if( debugIndex > 270 ) // { // debugIndex = 0; // break; // } // } // CWndChat* pWndChat = (CWndChat*) g_WndMng.GetApplet( APP_COMMUNICATION_CHAT ); // if( sDelta < 5100 && pWndChat ) // { // int x = rand() % 10000; // int z = rand() % 10000; // CString str; // str.Format( "%s %d %d %d", "/텔레 ", 1, x, z ); // pWndChat->m_wndEdit.AddString( str ); // pWndChat->OnChildNotify( EN_RETURN, WIDC_EDIT, 0 ); // // g_Console.Log( "TELEPORTED to %d, %d", x, z ); // // sDelta = 5100; // // // for( int i = 0; i < 26; ++i ) // // { // // g_bKeyTable[ 0x41 + i ] = rand() %2; // // } // // // // g_bKeyTable[ 0x4d ] = FALSE; //m // // g_bKeyTable[ 0x4c ] = FALSE; // } // // if( sDelta > 6000 ) // { // // CString str; // // str.Format( "%s %s %d %d", "/엔생", "라울프", 500, 0 ); // // pWndChat->m_wndEdit.AddString( str ); // // pWndChat->OnChildNotify( EN_RETURN, WIDC_EDIT, 0 ); // // // // g_Console.Log( "Created monster" ); // sDelta = 0; // // // if( rand() %2 ) // g_WndMng.ClearAllWnd(); // } // // } // // // if( sDelta > 6000 ) // { // ++gnReq; // gConsole()->Log( "===START ACTION===( FAIL %d : %d )", gnFail, gnReq ); // CWndWorld* pWndWorld = (CWndWorld*)g_WndMng.GetWndBase( APP_WORLD ); // if( pWndWorld ) // pWndWorld->OnKeyUp( 'C', 0, 0 ); // // CWndWorld::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) // sDelta = 0; // } // if( pSfx->m_pSfxObj->Process( ) ) // { // pSfx->m_pSfxObj-> // } }
// // // 클라이언트용 void CMover::ProcessMoveArrival( CCtrl *pObj ) { // 클라이언트 처리 if( IsActiveMover() ) { switch( m_oaCmd ) // 목표에 도착한 후의 명령 처리. { case OBJACT_USESKILL: if( pObj->GetType() == OT_MOVER && ( m_SkillTimerStop || m_SkillTimer.TimeOut() ) ) { CWorld *pWorld = GetWorld(); D3DXVECTOR3 vStart = GetPos(); vStart.y += 0.5f; D3DXVECTOR3 vEnd = pObj->GetPos(); vEnd.y += 0.5f; if( pWorld->IntersectObjLine( NULL, vStart, vEnd, FALSE, FALSE ) ) { g_WndMng.PutString( prj.GetText( TID_GAME_BLOCKTARGETING ), NULL, prj.GetTextColor( TID_GAME_BLOCKTARGETING ) ); g_WndMng.m_pWndWorld->SetNextSkill( NEXTSKILL_NONE ); break; } PlayCombatMusic(); int nSkillIdx = GetCmdParam(0); OBJID idTarget = (OBJID)GetCmdParam(1); SKILLUSETYPE sutType = (SKILLUSETYPE)GetCmdParam(2); if( (m_dwReqFlag & REQ_USESKILL) == 0 ) // 응답 요청중일땐 다시 보내선 안된다. { LPSKILL pSkill = GetSkill( 0, nSkillIdx ); // this가 가진 스킬중 nIdx에 해당하는 스킬을 꺼낸다. if( pSkill == NULL ) { Error( "CMD_SetUseSkill : %s skill(%d) not found", m_szName, nSkillIdx ); return; // skill not found } if( pSkill->dwSkill == SI_MAG_MAG_BLINKPOOL ) { CWndWorld* pWndWorld; pWndWorld = (CWndWorld*)g_WndMng.m_pWndWorld; { vStart = GetPos(); vStart.y += 1.0f; vEnd = pWndWorld->m_vTelePos; if( pWorld->IntersectObjLine( NULL, vStart, vEnd, FALSE, FALSE ) ) { g_WndMng.m_pWndWorld->SetNextSkill( NEXTSKILL_NONE ); g_WndMng.PutString( prj.GetText( TID_GAME_BLOCKTARGETING ), NULL, prj.GetTextColor( TID_GAME_BLOCKTARGETING ) ); break; } } if(g_pMoveMark!=NULL) g_pMoveMark->m_pSfxObj->m_nCurFrame=180; CreateSfx(g_Neuz.m_pd3dDevice,XI_GEN_MOVEMARK01,pWndWorld->m_vTelePos); } // 뒤에서 공격가능한 스킬인지 판단한다 // 강탈 스킬은 뒤에서 사용가능(일단 클라에서 판정하자~) if( pSkill->GetProp() && pSkill->GetProp()->dwAtkStyle == AS_BACK ) { D3DXVECTOR3 v3Pos; D3DXVECTOR3 v3PosSrc; D3DXVECTOR3 v3PosDest; // 방향벡터 1 v3PosSrc = pObj->GetPos() - GetPos(); D3DXVec3Normalize( &v3PosSrc, &v3PosSrc ); // 방향벡터 2 AngleToVectorXZ( &v3Pos, pObj->GetAngle(), 3.0f ); v3PosDest = (pObj->GetPos()+v3Pos) - pObj->GetPos(); D3DXVec3Normalize( &v3PosDest, &v3PosDest ); FLOAT fDir = D3DXVec3Dot( &v3PosSrc, &v3PosDest ); // 뒤가 아니면 스킬 사용 불가! if( fDir < 0.3f ) { g_WndMng.PutString( prj.GetText(TID_GAME_NEVERKILLSTOP) ); break; } } #if __VER >= 8 // __S8_PK // 카오에게 좋은 스킬을 사용할때는 Control 키를 눌러야 함 if( g_eLocal.GetState( EVE_PK ) ) { CMover * pMover; pMover = prj.GetMover( idTarget ); if( IsValidObj(pMover) && pMover != g_pPlayer && pMover->IsPlayer() && pMover->IsChaotic() ) if( pSkill->GetProp()->nEvildoing > 0 ) // 좋은 스킬 if( !(GetAsyncKeyState(VK_CONTROL) & 0x8000) ) break; } #endif // __VER >= 8 // __S8_PK TRACE( "OBJACT_USESKILL %d\n", nSkillIdx ); #if __VER >= 8 // __S8_PK BOOL bControl = ((GetAsyncKeyState(VK_CONTROL) & 0x8000)? TRUE:FALSE); g_DPlay.SendUseSkill( 0, nSkillIdx, idTarget, sutType, bControl ); // 목표지점에 도착하면 스킬쓴다고 알림. #else // __VER >= 8 // __S8_PK g_DPlay.SendUseSkill( 0, nSkillIdx, idTarget, sutType ); // 목표지점에 도착하면 스킬쓴다고 알림. #endif // __VER >= 8 // __S8_PK m_dwReqFlag |= REQ_USESKILL; // 응답 요청중 } ClearDestObj(); // 목표에 도달하면 추적을 멈춤. SendActMsg( OBJMSG_STOP ); if( !m_SkillTimerStop ) m_SkillTimer.Reset(); } break; //------------------------------------------ case OBJACT_MELEE_ATTACK: if( pObj->GetType() == OT_MOVER ) { ItemProp *pItemProp = GetActiveHandItemProp(); if( pItemProp && pItemProp->dwItemKind3 == IK3_YOYO ) { CWorld *pWorld = GetWorld(); D3DXVECTOR3 vStart = GetPos(); vStart.y += 0.5f; D3DXVECTOR3 vEnd = pObj->GetPos(); vEnd.y += 0.5f; if( pWorld->IntersectObjLine( NULL, vStart, vEnd, FALSE, FALSE ) ) { g_WndMng.PutString( prj.GetText( TID_GAME_BLOCKTARGETING ), NULL, prj.GetTextColor( TID_GAME_BLOCKTARGETING ) ); break; } } DoAttackMelee( (CMover *)pObj ); // pObj를 일반공격. } break; //--------------------------------------------- case OBJACT_MAGIC_ATTACK: if( pObj->GetType() == OT_MOVER ) { PlayCombatMusic(); OBJID idTarget = GetCmdParam(0); int nMagicPower = GetCmdParam(1); CMover *pTarget = prj.GetMover( idTarget ); // 타겟의 아이디를 포인터로 읽음. if( IsInvalidObj(pTarget) ) break; // 타겟이 거시기한 포인터면 취소시킴. SendActMsg( OBJMSG_STAND ); ClearDestObj(); // 목표에 도달하면 추적을 멈춤. DoAttackMagic( pTarget, nMagicPower ); } break; case OBJACT_RANGE_ATTACK: { if( pObj->GetType() == OT_MOVER ) { PlayCombatMusic(); OBJID idTarget = GetCmdParam(0); int nPower = GetCmdParam(1); CMover *pTarget = prj.GetMover( idTarget ); // 타겟의 아이디를 포인터로 읽음. if( IsInvalidObj(pTarget) ) break; // 타겟이 거시기한 포인터면 취소시킴. SendActMsg( OBJMSG_STAND ); SendActMsg( OBJMSG_STOP_TURN ); ClearDestObj(); // 목표에 도달하면 추적을 멈춤. DoAttackRange( pTarget, nPower, 0 ); // nPower를 dwItemID에 넣는다. } } break; //--------------------------------------------- case OBJACT_USEITEM: ClearDestObj(); // 그외는 목표에 도착하면 멈춤. SendActMsg( OBJMSG_STAND ); SetAngle( GetDegree(pObj->GetPos(), GetPos()) ); // 목표쪽으로 몸을 돌림. break; //--------------------------------------------- case OBJACT_COLLECT: ClearDestObj(); // 그외는 목표에 도착하면 멈춤. SendActMsg( OBJMSG_STOP ); SetAngle( GetDegree(pObj->GetPos(), GetPos()) ); // 목표쪽으로 몸을 돌림. g_DPlay.SendDoCollect( pObj ); // 서버로 보냄. break; //--------------------------------------------- default: ClearDestObj(); // 그외는 목표에 도착하면 멈춤. SendActMsg( OBJMSG_STOP ); break; } SetCmd( OBJACT_NONE ); } else { BOOL bQuery = m_pActMover->IsMove(); ClearDestObj(); // 그외는 목표에 도착하면 멈춤. SendActMsg( OBJMSG_STOP ); OnArrive( pObj->GetId(), 0 ); if( bQuery ) g_DPlay.SendQueryGetDestObj( this ); } }
void CSfx::Process() { #ifdef _DEBUG if( m_dwIndex == XI_SKILL_MAG_FIRE_HOTAIR01 ) // 디버깅 하려면 이걸 바꿔 쓰세요. { int a = 0; } #endif m_nFrame++; if( m_nSec == 0 ) // 0은 1회 플레이후 종료. { if( m_pSfxObj->Process() ) // return true는 애니메이션 끝. Delete(); } else { // 반복 애니메이션 if( m_pSfxObj->Process() ) m_pSfxObj->m_nCurFrame = 0; if( m_nSec != -1 ) // 무한반복(-1)이 아니면 { if( m_nFrame > ( m_nSec * 60 ) ) // 시간 체크를 한다. Delete(); } } #ifdef __CLIENT if(m_pSfxObj->m_pSfxBase != NULL) { for( int j=0; j<m_pSfxObj->m_pSfxBase->m_apParts.GetSize(); j++ ) { if( m_pSfxObj->m_pSfxBase->Part(j)->m_nType != SFXPARTTYPE_MESH ) continue; CModelObject* pMesh = NULL; pMesh = g_SfxMeshMng.Mesh( m_pSfxObj->m_pSfxBase->Part(j)->m_strTex ); if( pMesh ) pMesh->FrameMove(); } } #endif //__CLIENT if( m_idDest != NULL_ID ) // Dest가 지정되어 있을때. { CMover* pObjDest = (CMover*)prj.GetCtrl( m_idDest ); if( IsValidObj( pObjDest ) ) // 유효한넘인가? m_vPosDest = pObjDest->GetPos(); // 당시 좌표를 계속 받아둠. Invalid상태가 되면 마지막 좌표로 세팅된다. SetPos( m_vPosDest ); // 타겟에 오브젝트 발동. #ifdef __CLIENT #if __VER >= 11 // __MA_VER11_06 // 확율스킬 효과수정 world,neuz if( m_dwIndex == XI_SKILL_PSY_HERO_STONE02 ) { if( IsValidObj( pObjDest ) ) // 유효한넘인가? { DWORD dwTmpID = pObjDest->GetRemoveSfxObj(XI_SKILL_PSY_HERO_STONE02 ); if( dwTmpID && m_nFrame > 0) { Delete(); return; } } } #endif // __MA_VER11_06 // 확율스킬 효과수정 world,neuz // 091022 mirchang - 프로텍션, 펜바리어 스킬 버프 해제 시 sfx 삭제 if( m_dwIndex == XI_SKILL_MER_SHIELD_PANBARRIER02 ) { if( IsValidObj( pObjDest ) ) // 유효한넘인가? { DWORD dwTmpID = pObjDest->GetRemoveSfxObj( XI_SKILL_MER_SHIELD_PANBARRIER02 ); if( dwTmpID && m_nFrame > 0) { Delete(); return; } } } if( m_dwIndex == XI_SKILL_MER_SHIELD_PROTECTION02 ) { if( IsValidObj( pObjDest ) ) // 유효한넘인가? { DWORD dwTmpID = pObjDest->GetRemoveSfxObj( XI_SKILL_MER_SHIELD_PROTECTION02 ); if( dwTmpID && m_nFrame > 0) { Delete(); return; } } } #endif // __CLIENT } else { // Dest가 지정되어 있지 않을때. Src로... if( m_idSrc != NULL_ID ) { CMover* pObjSrc = (CMover*)prj.GetCtrl( m_idSrc ); if( IsValidObj( pObjSrc ) ) // 소스아이디가 지정되어 있으면 SetPos( pObjSrc->GetPos() ); // 소스측에 이펙 발동. else Delete(); } } }
int CWndWorld::ControlFlying( DWORD dwMessage, CPoint point ) { static float fTurnAngle = 0.0f; static BOOL s_bTraceKeyed = 0, s_bSelectKeyed = 0, s_bTurbo2 = 0; // static BOOL s_bFastTurn; int nMsg = 0; // BOOL bFlyKey; BOOL bUp, bDown, bLeft, bRight; BOOL bAcc = FALSE; BOOL bTurbo; // BOOL bFastTurn = FALSE; BYTE nFrame = MAX_CORR_SIZE_150; CMover* pMover = CMover::GetActiveMover(); bUp = g_bKeyTable[g_Neuz.Key.chUp]; bDown = g_bKeyTable['S']; // 좌/우 회전 bLeft = g_bKeyTable[g_Neuz.Key.chLeft]; bRight = g_bKeyTable['D']; // 급선회. // bFastTurn = g_bKeyTable[ VK_SHIFT ]; // CMover* pMoverTarget = (CMover*)g_WorldMng.Get()->GetObjFocus() ; // 가속 상태면 전진 명령 계속 보냄 bool fMoved = false; bool fBehavior = false; if( pMover->m_pActMover->IsStateFlag( OBJSTAF_ACC ) ) { if( pMover->SendActMsg( OBJMSG_FORWARD ) == 1 ) { fMoved = true; } } else { if( pMover->SendActMsg( OBJMSG_STAND ) == 1 ) { fMoved = true; } } // bAcc = g_bKeyTable[VK_SPACE]; if( bAcc && !s_bAccKeyed ) // 키 누른순간에만 토글시킴. { if( pMover->m_pActMover->IsStateFlag( OBJSTAF_ACC ) ) // 가속중이었다면 { pMover->SendActMsg( OBJMSG_ACC_STOP ); // 가속 멈춤 if( pMover->m_pActMover->IsActTurn() ) { fMoved = true; } } else { // 가속중이 아니었다면 가속 시킴. if( pMover->SendActMsg( OBJMSG_ACC_START ) == 0 ) g_WndMng.PutString( prj.GetText( TID_GAME_AIRFUELEMPTY ) ); else { if( pMover->SendActMsg( OBJMSG_FORWARD ) == 1 ) fMoved = true; } } } s_bAccKeyed = bAcc; bTurbo = g_bKeyTable[g_Neuz.Key.chWalk]; if( bTurbo && !s_bTurbo2 ) // 토글 방식. { if( pMover->m_pActMover->IsStateFlag( OBJSTAF_TURBO ) ) { if( pMover->SendActMsg( OBJMSG_MODE_TURBO_OFF ) == 1 ) fMoved = true; } else { if( pMover->SendActMsg( OBJMSG_MODE_TURBO_ON ) == 1 ) fMoved = true; } } s_bTurbo2 = bTurbo; if( pMover->m_pActMover->IsFly() ) { if( g_bKeyTable[g_Neuz.Key.chTrace] && !s_bTraceKeyed ) { CCtrl* pFocusObj = (CCtrl*)(pMover->GetWorld()->GetObjFocus()); if( pFocusObj && pFocusObj->GetType() == OT_MOVER ) { CMover* pFocusMover = (CMover*)pFocusObj; if( pMover->m_dwFlag & MVRF_TRACKING ) // 이미 실행중이면 해제. { pMover->m_dwFlag &= (~MVRF_TRACKING); // 추적모드해제. pMover->m_idTracking = NULL_ID; } else { // 비행중 추적모드. pMover->m_dwFlag |= MVRF_TRACKING; // 추적모드. pMover->m_idTracking = pFocusMover->GetId(); } } else { // 타겟이 없을때 Z키를 누르면 자동추적이 풀린다. pMover->m_dwFlag &= (~MVRF_TRACKING); // 추적모드해제. pMover->m_idTracking = NULL_ID; } } s_bTraceKeyed = g_bKeyTable[g_Neuz.Key.chTrace]; // 타겟선택 키 if( g_bKeyTable[VK_TAB] && !s_bSelectKeyed ) { if( m_aFlyTarget.GetSize() > 0 ) // 선택된 타겟있을때. { if( m_nSelect >= m_aFlyTarget.GetSize() ) m_nSelect = 0; OBJID idSelect = m_aFlyTarget.GetAt( m_nSelect++ ); CMover *pSelectMover = prj.GetMover( idSelect ); if( IsValidObj(pSelectMover) ) { CWorld *pWorld = pMover->GetWorld(); if( pWorld ) { pWorld->SetObjFocus( pSelectMover ); // 이놈을 타겟으로 설정함. pMover->m_idTracking = pSelectMover->GetId(); // 탭으로 타겟을 바꾸면 자동추적타겟도 그놈으로 바뀐다. } } } } s_bSelectKeyed = g_bKeyTable[VK_TAB]; } if( /*m_bFlyMove &&*/ m_bLButtonDown || g_bKeyTable[VK_INSERT] ) // 192 = ` { CObj *pObj = pMover->GetWorld()->GetObjFocus(); // 타겟잡힌놈이 있을때만 휘두를수 있다. if( pObj && pObj->GetType() == OT_MOVER ) { if( pMover->IsAttackAble( pObj ) ) // 공격 가능한지 검사. { OBJID idTarget = ((CMover *)pObj)->GetId(); ItemProp *pWeapon = pMover->GetActiveHandItemProp(); if( pWeapon ) { g_pPlayer->PlayCombatMusic(); if( pWeapon->dwItemKind3 == IK3_WAND ) { D3DXVECTOR3 vFront, vTarget; AngleToVector( &vFront, g_pPlayer->GetAngle(), -g_pPlayer->GetAngleX(), 1.0f ); vTarget = pObj->GetPos() - g_pPlayer->GetPos(); D3DXVec3Normalize( &vTarget, &vTarget ); // 타겟쪽으로의 벡터의 유닛벡터. FLOAT fDot = D3DXVec3Dot( &vFront, &vTarget ); if( fDot >= cosf(D3DXToRadian(60.0f)) ) // 타겟이 내가 보는 방향의 +-30도 안에 있으면 발사할수 있다. { if( pMover->IsRangeObj( pObj, 64.0f ) ) // 사정거리에 들어오면 발사. { pMover->DoAttackMagic( pObj, 0 ); } } } else { pMover->SendActMsg( OBJMSG_ATK1, idTarget ); } } } } } // fTurnAngle = 0.6f; ItemProp* pItemProp = prj.GetItemProp( g_pPlayer->GetRideItemIdx() ); if( pItemProp ) { fTurnAngle = pItemProp->fFlightLRAngle; } else { Error( "ControlFlying : 빗자루정보 읽기 실패 %d", g_pPlayer->GetRideItemIdx() ); fTurnAngle = 0.6f; } if( bUp ) { if( g_WorldMng.Get()->GetFullHeight( pMover->GetPos() ) < pMover->GetPos().y ) { if( pMover->SendActMsg( OBJMSG_LOOKDOWN ) == 1 ) { fMoved = true; } } } else if( bDown ) { if( pMover->SendActMsg( OBJMSG_LOOKUP ) == 1 ) { fMoved = true; } } else { if( pMover->SendActMsg( OBJMSG_STOP_LOOK ) == 1 ) { fMoved = true; } } if( bLeft ) { m_fRollAng -= 1.0f; if( m_fRollAng < -45.0f ) m_fRollAng = -45.0f; if( pMover->SendActMsg( OBJMSG_LTURN, (int)( fTurnAngle * 100.0f ) ) == 1 ) { fMoved = true; } } else if( bRight ) { m_fRollAng += 1.0f; if( m_fRollAng > 45.0f ) m_fRollAng = 45.0f; if( pMover->SendActMsg( OBJMSG_RTURN, (int)( fTurnAngle * 100.0f ) ) == 1 ) { fMoved = true; } } else { if( m_fRollAng < 0 ) { m_fRollAng += 2.0f; if( m_fRollAng > 0 ) m_fRollAng = 0; } else if( m_fRollAng > 0 ) { m_fRollAng -= 2.0f; if( m_fRollAng < 0 ) m_fRollAng = 0; } if( pMover->SendActMsg( OBJMSG_STOP_TURN ) == 1 ) { fMoved = true; // fBehavior = true; } } // 오른쪽 버튼 드래그는 빗자루 움직임 if( dwMessage == WM_MOUSEMOVE /*&& m_bRButtonDown*/ ) { float fAng = pMover->GetAngle(); float fAdd = (point.x - m_ptMouseOld.x) / 2.0f; fAng -= fAdd; pMover->SetAngle( fAng ); float fAngX = pMover->GetAngleX(); float fAddX = (point.y - m_ptMouseOld.y) / 4.0f; fAngX += fAddX; if( fAddX > 0 && fAngX > 45.0f ) fAngX = 45.0f; else if( fAddX < 0 && fAngX < -45.0f ) fAngX = -45.0f; pMover->SetAngleX( fAngX ); if( fAdd || fAddX ) g_DPlay.PostPlayerAngle( TRUE ); } BOOL bTempKey; if( bTempKey = g_bKeyTable[ '8' ] ) { if( !m_bTemp3ed ) { pMover->SendActMsg( OBJMSG_TEMP2 ); // __bTestLOD ^= 1; } } m_bTemp3ed = bTempKey; if( fMoved ) { g_DPlay.SendPlayerMoved2( nFrame ); } if( fBehavior ) { pMover->ClearDest(); g_DPlay.SendPlayerBehavior2(); } return nMsg; }