Vector GetRandomSpot() { CWorld *pEnt = GetWorldEntity(); if ( pEnt ) { Vector vMin, vMax; pEnt->GetWorldBounds( vMin, vMax ); return Vector( RandomFloat( vMin.x, vMax.x ), RandomFloat( vMin.y, vMax.y ), RandomFloat( vMin.z, vMax.z ) ); } else { return Vector( 0, 0, 0 ); } }
// 클라용 대전 가능한 유저인가? BOOL CGuildCombat1to1Mng::IsPossibleMover( CMover* pMover ) { if( !pMover ) return FALSE; CWorld* pWorld = pMover->GetWorld(); if( pWorld ) { if( pWorld->GetID() >= WI_WORLD_GUILDWAR1TO1_0 && pWorld->GetID() <= WI_WORLD_GUILDWAR1TO1_L ) { if( pMover->m_nGuildCombatState != 0 ) return TRUE; } } return FALSE; }
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 CWorldSquare::build() // Build //********************************************************************** void CWorldSquare::build() { #ifndef OPTIMIZE try { #endif // Get our Values From World CWorld *pWorld = CWorld::Instance(); iNumberOfCategories = pWorld->getCategoryCount(); iMinAge = pWorld->getMinAge(); iMaxAge = pWorld->getMaxAge(); bAgePlus = pWorld->getAgePlusGroup(); #ifndef OPTIMIZE if (iNumberOfCategories <= 0) CError::errorMissing(PARAM_CATEGORIES); if (iMinAge < 0) CError::errorMissing(PARAM_MIN_AGE); if (iMaxAge <= 0) CError::errorMissing(PARAM_MAX_AGE); if (iMaxAge < iMinAge) CError::errorLessThan(PARAM_MAX_AGE, PARAM_MIN_AGE); #endif // Build our Grid iHeight = iNumberOfCategories; iWidth = (iMaxAge+1)-iMinAge; pGrid = new double*[iHeight]; for (int i = 0; i < iHeight; ++i) pGrid[i] = new double[iWidth]; // Zero it zeroGrid(); #ifndef OPTIMIZE } catch (string &Ex) { Ex = "CWorldSquare.build()->" + Ex; throw Ex; } #endif }
//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CMapData_Server::GetMapBounds( Vector &vecMins, Vector &vecMaxs ) { CWorld *pWorld = static_cast<CWorld*>( GetWorldEntity() ); if ( pWorld ) { // Get the world bounds. pWorld->GetWorldBounds( vecMins, vecMaxs ); // Backward compatability... if ( ( vecMins.LengthSqr() == 0.0f ) && ( vecMaxs.LengthSqr() == 0.0f ) ) { vecMins.Init( -6500.0f, -6500.0f, -6500.0f ); vecMaxs.Init( 6500.0f, 6500.0f, 6500.0f ); } } else { Assert( 0 ); vecMins.Init( 0.0f, 0.0f, 0.0f ); vecMaxs.Init( 1.0f, 1.0f, 1.0f ); } }
BOOL CWndCoupleTalk::OnChildNotify( UINT message, UINT nID, LRESULT* pLResult ) { CWorld* pWorld = g_WorldMng(); CObj* pObj = pWorld->GetObjFocus(); if( pObj && pObj->GetType() == OT_MOVER ) { switch( nID ) { case WIDC_EDIT2: // 본문 if( message != EN_RETURN ) break; case WIDC_BUTTON1: { CWndEdit* pWndEdit2 = (CWndEdit*)GetDlgItem( WIDC_EDIT2 ); CString stPropose( pWndEdit2->m_string); if(stPropose.GetLength()>30) g_WndMng.PutString( "뚤꼇폅,멩겜코휭꼇콘낚법15몸櫓匡俚륜。", NULL, prj.GetTextColor( TID_GAME_NOTCOUPLETARGET ) ); else { //警속랙箇句口 g_DPlay.SendPropose(((CMover*)pObj)->GetName(),stPropose); Destroy( TRUE ); return TRUE; } pWndEdit2->Empty(); } break; } } if( nID == WTBID_CLOSE ) { Destroy( TRUE ); return TRUE; } return CWndNeuz::OnChildNotify( message, nID, pLResult ); }
uint8 CEntitiesFactory::Init(CWorld &world) { uint8 ret = 0; Init(); m_world = &world; for (std::vector<SEntityParams *>::iterator itr = g_entitiesParams.begin(); itr != g_entitiesParams.end(); ++itr) { CEntity * et = SpawnEntity(*itr); world.AddEntity(et); } return ret; }
int Sphere_OnTick() { // Give the world (CMainTask) a single tick. RETURN: 0 = everything is fine. const char *m_sClassName = "Sphere"; EXC_TRY("Tick"); #ifdef _WIN32 EXC_SET("service"); g_Service.OnTick(); #endif EXC_SET("ships_tick"); g_Serv.ShipTimers_Tick(); EXC_SET("world"); g_World.OnTick(); // process incoming data EXC_SET("network-in"); #ifndef _MTNETWORK g_NetworkIn.tick(); #else g_NetworkManager.processAllInput(); #endif EXC_SET("server"); g_Serv.OnTick(); // push outgoing data #ifndef _MTNETWORK if (g_NetworkOut.isActive() == false) { EXC_SET("network-out"); g_NetworkOut.tick(); } #else EXC_SET("network-tick"); g_NetworkManager.tick(); EXC_SET("network-out"); g_NetworkManager.processAllOutput(); #endif EXC_CATCH; EXC_DEBUG_START; EXC_DEBUG_END; return g_Serv.m_iExitFlag; }
void Sphere_ExitServer() { // Trigger server quit g_Serv.r_Call("f_onserver_exit", &g_Serv, NULL); g_Serv.SetServerMode(SERVMODE_Exiting); #ifndef _MTNETWORK g_NetworkOut.waitForClose(); #else g_NetworkManager.stop(); #endif g_Main.waitForClose(); g_PingServer.waitForClose(); g_asyncHdb.waitForClose(); #if !defined(_WIN32) || defined(_LIBEV) if ( g_Cfg.m_fUseAsyncNetwork != 0 ) g_NetworkEvent.waitForClose(); #endif g_Serv.SocketsClose(); g_World.Close(); LPCTSTR Reason; switch ( g_Serv.m_iExitFlag ) { case -10: Reason = "Unexpected error occurred"; break; case -9: Reason = "Failed to bind server IP/port"; break; case -8: Reason = "Failed to load worldsave files"; break; case -3: Reason = "Failed to load server settings"; break; case -1: Reason = "Shutdown via commandline"; break; #ifdef _WIN32 case 1: Reason = "X command on console"; break; #else case 1: Reason = "Terminal closed by SIGHUP signal"; break; #endif case 2: Reason = "SHUTDOWN command executed"; break; case 4: Reason = "Service shutdown"; break; case 5: Reason = "Console window closed"; break; case 6: Reason = "Proccess aborted by SIGABRT signal"; break; default: Reason = "Server shutdown complete"; break; } g_Log.Event(LOGM_INIT|LOGL_FATAL, "Server terminated: %s (code %d)\n", Reason, g_Serv.m_iExitFlag); g_Log.Close(); }
/* ============================================================================= =============================================================================== */ bool CWorld::gotoView(int ndx, float fTime, bool bUpdateCamera) { if (ndx == -1) ndx = getViewSet().getCur(); if (!getViewSet().isValid(ndx)) return false; getViewSet().setCur(ndx); CView &View = getView(ndx); applyViewActiveLayers(View.getActiveLayers()); g_Set.deserialize(View.getSettings()); // after all data is loaded so we can set up the timeline gotoViewTime(View); g_Set.m_ShowTimeline = (getDataSet().getActiveCnt() > 0 || getTextureSet().getMovieActive()); g_World.updateTerrain(); g_Draw.drawGL(); if (bUpdateCamera) g_Draw.gotoCameraView(View.getLookAt(), View.getElevation(), View.getAzimuth(), View.getDolly(), fTime); return true; }
void CCreateMonster::CreateMonster( CUser* pUser, DWORD dwObjId, D3DXVECTOR3 vPos ) { if( (int)( m_mapCreateMonsterInfo.size() ) >= m_nMaxCreateNum ) { pUser->AddDefinedText( TID_GAME_CREATEMON_LIMIT ); return; } CItemElem* pItemElem = pUser->m_Inventory.GetAtId( dwObjId ); if( !IsUsableItem( pItemElem ) ) return; CREATE_MONSTER_PROP* pCreateMonsterProp = GetCreateMonsterProp( pItemElem ); if( !pCreateMonsterProp ) return; DWORD dwMonsterId = pCreateMonsterProp->GetRandomMonsterId(); if( dwMonsterId == NULL_ID ) return; CWorld* pWorld = pUser->GetWorld(); MoverProp* pMoverProp = prj.GetMoverProp( dwMonsterId ); if( pWorld && pMoverProp && pMoverProp->dwID != 0 ) { D3DXVECTOR3 vDist2 = pUser->GetPos() - vPos; float fDist = D3DXVec3Length( &vDist2 ); // 두좌표간의 거리 if( 15.f < fDist ) { pUser->AddDefinedText( TID_GAME_CREATEMON_F_15 ); return; } int nAttr = pWorld->GetHeightAttribute( vPos.x, vPos.z ); // 이동할 위치의 속성 읽음. if( nAttr == HATTR_NOWALK || nAttr == HATTR_NOMOVE ) // 못 움직이는 곳이면 Pass { pUser->AddDefinedText( TID_GAME_CREATEMON_F_AREA ); return; } if( pUser->IsRegionAttr( RA_SAFETY )) // 안전지역이면 Pass { pUser->AddDefinedText( TID_GAME_CREATEMON_F_AREA ); return; } if( pWorld->GetID() != WI_WORLD_MADRIGAL ) { pUser->AddDefinedText( TID_GAME_CREATEMON_F_AREA ); return; } CObj* pObj = CreateObj( D3DDEVICE, OT_MOVER, pMoverProp->dwID ); if( NULL == pObj ) return; // ASSERT( pObj ); pObj->SetPos( vPos ); pObj->InitMotion( MTI_STAND ); pObj->UpdateLocalMatrix(); ((CMover*)pObj)->m_bActiveAttack = FALSE; ((CMover*)pObj)->AddItToGlobalId(); pWorld->ADDOBJ( pObj, FALSE, pUser->GetLayer() ); LogItemInfo aLogItem; aLogItem.Action = "i"; aLogItem.SendName = pUser->GetName(); char szTemp[128] = {0,}; sprintf( szTemp, "M_C_%s", pMoverProp->szName ); memset( szTemp+31, 0, sizeof(szTemp)-31 ); aLogItem.RecvName = szTemp; aLogItem.Gold = aLogItem.Gold2 = pUser->GetGold(); aLogItem.Gold_1 = ((CMover*)pObj)->GetId(); aLogItem.WorldId = pUser->GetWorld()->GetID(); g_DPSrvr.OnLogItem( aLogItem, pItemElem, 1 ); pUser->AddDefinedText( TID_GAME_CREATEMON_S, "\"%s\"", pMoverProp->szName ); pUser->RemoveItem( (BYTE)( dwObjId ), (short)( 1 ) ); CREATE_MONSTER_INFO createMonsterInfo; createMonsterInfo.chState = 'N'; createMonsterInfo.dwOwnerId = pUser->m_idPlayer; createMonsterInfo.dwEndTick = pCreateMonsterProp->dwKeepTime + GetTickCount(); m_mapCreateMonsterInfo.insert( make_pair( ((CMover*)pObj)->GetId(), createMonsterInfo ) ); } }
int Sphere_InitServer( int argc, char *argv[] ) { #ifdef EXCEPTIONS_DEBUG const char *m_sClassName = "Sphere"; #endif EXC_TRY("Init"); ASSERT(MAX_BUFFER >= sizeof(CEvent)); ASSERT(sizeof(int) == sizeof(DWORD)); // make this assumption often. ASSERT(sizeof(ITEMID_TYPE) == sizeof(DWORD)); ASSERT(sizeof(WORD) == 2 ); ASSERT(sizeof(DWORD) == 4 ); ASSERT(sizeof(NWORD) == 2 ); ASSERT(sizeof(NDWORD) == 4 ); ASSERT(sizeof(CUOItemTypeRec) == 37 ); // byte pack working ? ASSERT((std::numeric_limits<size_t>::min)() == 0); // ensure unsigned #ifdef _WIN32 if ( !QueryPerformanceFrequency(reinterpret_cast<LARGE_INTEGER *>(&llTimeProfileFrequency)) ) llTimeProfileFrequency = 1000; #if !defined(_DEBUG) && !defined(__MINGW32__) EXC_SET("setting exception catcher"); SetExceptionTranslator(); #endif #endif EXC_SET("loading"); if ( !g_Serv.Load() ) return -3; if ( argc > 1 ) { EXC_SET("cmdline"); if ( !g_Serv.CommandLine(argc, argv) ) return -1; } WritePidFile(2); EXC_SET("load world"); if ( !g_World.LoadAll() ) return -8; EXC_SET("sockets init"); if ( !g_Serv.SocketsInit() ) return -9; // load auto-complete dictionary EXC_SET("auto-complete"); { CFileText dict; if ( dict.Open(SPHERE_FILE ".dic", OF_READ|OF_TEXT|OF_DEFAULTMODE) ) { TCHAR * pszTemp = Str_GetTemp(); size_t count = 0; while ( !dict.IsEOF() ) { dict.ReadString(pszTemp, SCRIPT_MAX_LINE_LEN-1); if ( *pszTemp ) { TCHAR *c = strchr(pszTemp, '\r'); if ( c != NULL ) *c = '\0'; c = strchr(pszTemp, '\n'); if ( c != NULL ) *c = '\0'; if ( *pszTemp != '\0' ) { count++; g_AutoComplete.AddTail(pszTemp); } } } g_Log.Event(LOGM_INIT, "Auto-complete dictionary loaded (contains %" FMTSIZE_T " words)\n", count); dict.Close(); } } EXC_SET("finalizing"); g_Serv.SetServerMode(SERVMODE_Run); g_Log.Event(LOGM_INIT, "Startup complete (Items=%lu, Chars=%lu, Accounts=%lu)\nPress '?' for console commands\n\n", g_Serv.StatGet(SERV_STAT_ITEMS), g_Serv.StatGet(SERV_STAT_CHARS), g_Serv.StatGet(SERV_STAT_ACCOUNTS)); if ( !g_Accounts.Account_GetCount() ) g_Log.Event(LOGL_WARN|LOGM_INIT, "The server has no accounts. To create admin account you must type:\n ACCOUNT ADD [login] [password]\n ACCOUNT [login] PLEVEL 7\n"); // Trigger server start g_Serv.r_Call("f_onserver_start", &g_Serv, NULL); return g_Serv.m_iExitFlag; EXC_CATCH; EXC_DEBUG_START; g_Log.EventDebug("cmdline argc=%d starting with %p (argv1='%s')\n", argc, static_cast<void *>(argv), ( argc > 2 ) ? argv[1] : ""); EXC_DEBUG_END; return -10; }
void CBackCamera::Process( LPDIRECT3DDEVICE9 pd3dDevice ,float fFactor ) { #ifdef __CLIENT CMover *pMover = CMover::GetActiveMover(); // 여기서 카메라 세팅!!!!! if( pMover == NULL ) return; CWorld* pWorld = pMover->GetWorld(); if( pWorld == NULL ) return; D3DXMATRIX matView, mat; FLOAT fAngle = 0, fAngleY = 0; D3DXVECTOR3 vPos = pMover->GetPos(); vPos.y += 0.9f; #if __VER >= 13 // __HOUSING if(m_nCamMode == CM_MYROOM) { if(m_fZoom <= 0.5f) m_fZoom = 0.5f; // if(m_fZoom >= 3.0f) m_fZoom = 3.0f; } #endif // __HOUSING CMover* pMoverTarget = (CMover*)g_WorldMng.Get()->GetObjFocus() ; D3DXVECTOR3 vTarget,vTemp; if( pMoverTarget && pMover->m_pActMover->IsFly() && (pMover->m_dwFlag & MVRF_TRACKING) ) { // 날고 있는 경우 타겟이 있다면 // 타겟쪽으로 카메라 방향을 수정한다. vTemp = vPos - pMoverTarget->GetPos(); if( vTemp.z > 0 ) { fAngle =- (float)( atan( vTemp.x / vTemp.z ) * 180 / 3.1415926f ); } else { fAngle =- (float)( atan( vTemp.x / vTemp.z ) * 180 / 3.1415926f ) + 180; } D3DXVECTOR3 vDistXZ = vTemp; vDistXZ.y = 0; float fDistSq = D3DXVec3Length( &vDistXZ ); // XZ평면에서의 길이 fAngleY = atan2( fDistSq, vTemp.y/* * vTemp.y*/ ); fAngleY = D3DXToDegree( fAngleY ); float fReg1 = vTemp.y / 40.0f; if( fReg1 > 0 ) { if( fReg1 >= 2.0f ) fReg1 = 2.0f; } else if( fReg1 < 0 ) { if( fReg1 <= -2.0f ) fReg1 = -2.0f; } m_fCurRoty = m_fRoty + m_fZoom * fReg1; if( m_bLock ) fAngle = 0; } else { fAngle = pMover->GetAngle(); if( m_bLock ) fAngle = 0; fAngleY = 90.0f; m_fCurRoty = m_fRoty + m_fZoom * 4; } m_vLookAt = vPos; #ifdef __Y_CAMERA_SLOW_8 if( !g_WndMng.m_pWndWorld->m_bRButtonDown && ( !g_bKeyTable[ VK_LEFT ] && !g_bKeyTable[ VK_RIGHT ] ) ) { static FLOAT fSpeed = 2.0f; BOOL bLeft = FALSE; BOOL bRight = FALSE; FLOAT fTemp = 0.0f; fTemp = m_fRotx; if( (GetAnglePie(fTemp) == 1 && GetAnglePie(m_fCurRotx) == 4) ) bRight = TRUE; if( (GetAnglePie(fTemp) == 4 && GetAnglePie(m_fCurRotx) == 1) ) bLeft = TRUE; if( bRight ) { m_fCurRotx += m_fRotx; if( m_fCurRotx < fTemp ) { m_fCurRotx += fSpeed; } m_fCurRotx -= m_fRotx; if( m_fCurRotx >= 0.0f ) { m_fCurRotx = -360.0f; } } if( bLeft ) { fTemp += -360.0f; if( m_fCurRotx > fTemp ) { m_fCurRotx += -fSpeed; if( m_fCurRotx < -360.0f ) m_fCurRotx = 0.0f; } fTemp -= -360.0f; } if( !bLeft && !bRight ) { FLOAT fGoal = fabs(m_fCurRotx - fTemp); if( m_fCurRotx < fTemp ) { if( fGoal > fSpeed ) m_fCurRotx += fSpeed; } else { if( fGoal > fSpeed ) m_fCurRotx -= fSpeed; } } } else { m_fCurRotx = m_fRotx; } #else //__Y_CAMERA_SLOW_8 m_fCurRotx = m_fRotx; #endif //__Y_CAMERA_SLOW_8 #ifdef __XUZHU _g_fReg[0] = fAngleY; #endif float fAdjAng = (1.0f - fAngleY / 90.0f) * 45.0f; m_fCurRoty += fAdjAng; m_fCurRoty += pMover->GetAngleX(); if( pMover->m_pActMover->IsFly() ) // 비행할땐 조금 들어주자 m_fCurRoty += 0.0f; if( m_fCurRoty > 80.0f ) m_fCurRoty = 80.0f; #if __VER >= 13 // __HOUSING if(m_nCamMode == CM_MYROOM) { if(m_fCurRoty <= 10.0f) { m_fCurRoty = 10.0f; if(m_fRoty > 0.0f) m_fRoty = 0.0f; if(m_fRoty < -30.0f) m_fRoty = -30.0f; } } #endif // __HOUSING fAngle = m_fCurRotx - fAngle + 180.0f; D3DXMATRIX matTemp; // zoom 상태에 따라 카메라 위치를 조정 extern float fDiv; if( fDiv == 2.0f ) //vTemp = D3DXVECTOR3( 0.0f, 0.0f, -0.0f - (m_fZoom / 2.0f) * 2.0f ); vTemp = D3DXVECTOR3( 0.0f, 0.0f, -0.0f - 2.0f ); else { if( g_pShip ) vTemp = D3DXVECTOR3( 0.0f, 0.0f, -4.0f - m_fZoom * 16.0f ); else //vTemp = D3DXVECTOR3( 0.0f, 0.0f, -50.0f ); vTemp = D3DXVECTOR3( 0.0f, 0.0f, -4.0f - m_fZoom * 2.0f ); } D3DXVECTOR3 vecOut; D3DXMatrixRotationX( &matTemp, D3DXToRadian( m_fCurRoty / 1.0f ) ); D3DXVec3TransformCoord( &vTemp, &vTemp, &matTemp ); D3DXMatrixRotationY( &matTemp, D3DXToRadian( fAngle ) ); D3DXVec3TransformCoord( &m_vOffsetDest, &vTemp, &matTemp ); D3DXVECTOR3 vecOffsetDelta = ( ( m_vOffsetDest - m_vOffset ) + m_vPosVal ) / fFactor; m_vOffset += vecOffsetDelta; m_vPosVal /= 2; m_vPos = vPos + m_vOffset; BOOL bCrash; FLOAT fLength; static D3DXVECTOR3 m_vLimitPos; D3DXVECTOR3 m_vOutPos = m_vPos; m_vLookAt.y += 0.4f; #if __VER >= 11 // __GUILD_COMBAT_1TO1 if( g_pPlayer && g_GuildCombat1to1Mng.IsPossibleMover( g_pPlayer ) ) bCrash = FALSE; else bCrash = pWorld->CheckBound( &m_vPos, &m_vLookAt, &m_vOutPos, &fLength ); #else //__GUILD_COMBAT_1TO1 bCrash = pWorld->CheckBound( &m_vPos, &m_vLookAt, &m_vOutPos, &fLength ); #endif //__GUILD_COMBAT_1TO1 // 충돌이있다면 마지막으로 충돌했던 거리를 저장 if( bCrash ) m_fLength2 = fLength; // 전프레임에 충돌, 현재는 충돌이 아닐때...즉, 서서히 뒤로 가게하는 시점.. if( m_bOld && bCrash == FALSE ) { m_fLength1 = fLength; m_bStart = TRUE; } if( m_bStart ) { D3DXVECTOR3 vCPos = vPos + m_vOffset; D3DXVECTOR3 vDir = vCPos - m_vLookAt; D3DXVec3Normalize(&vDir, &vDir); #if __VER >= 12 // __CAM_FAST_RECOVER m_fLength2 += 0.37f; #else m_fLength2 += 0.07f; #endif if( m_fLength2 > fLength ) m_bStart = FALSE; m_vOutPos = m_vLookAt + (vDir * m_fLength2); } else if( bCrash ) {/* if( fLength < 5.0f ) { D3DXVECTOR3 vCPos = vPos + m_vOffset; D3DXVECTOR3 vDir = vCPos - m_vLookAt; D3DXVec3Normalize(&vDir, &vDir); FLOAT fff = m_vOutPos.y; m_vOutPos = m_vLookAt + (vDir * 5.0f); m_vOutPos.y = fff; } */ } m_bOld = bCrash; g_ModelGlobal.SetCamera( m_vOutPos, m_vLookAt ); m_vPos = m_vOutPos; #endif // CLIENT }
/* * Do some CSG operation with one brush in this world and one brush in other world. */ void CWorld::DoCSGOperation( CEntity &enThis, CWorld &woOther, CEntity &enOther, const CPlacement3D &plOther, void (CObject3D::*DoCSGOpenSector)(CObject3D &obA, CObject3D &obB), void (CObject3D::*DoCSGClosedSectors)(CObject3D &obA, CObject3D &obB) ) { // assure that floating point precision is 53 bits AssureFPT_53(); // get relevant brush mips in each brush CBrushMip &bmThis = *GetBrushMip(enThis); CBrushMip &bmOther = *GetBrushMip(enOther); if (&bmThis==NULL || &bmOther==NULL) { return; } // get open sector of the other brush to object CBrushSectorSelectionForCSG selbscOtherOpen; bmOther.SelectOpenSector(selbscOtherOpen); CObject3D obOtherOpen; DOUBLEaabbox3D boxOtherOpen; woOther.CopySourceBrushSectorsToObject(enOther, selbscOtherOpen, plOther, obOtherOpen, enThis.en_plPlacement, boxOtherOpen); // if there is an open sector in other object if (obOtherOpen.ob_aoscSectors.Count()>0) { CObject3D obResult; // deportalize the open sector obOtherOpen.TurnPortalsToWalls(); // if there are any sectors in this brush if (bmThis.bm_abscSectors.Count()>0) { // move affected part of this brush to an object3d object CObject3D obThis; MoveTargetBrushPartToObject(enThis, boxOtherOpen, obThis); // do the open sector CSG operation on the objects _pfWorldEditingProfile.StartTimer(CWorldEditingProfile::PTI_OBJECTCSG); (obResult.*DoCSGOpenSector)(obThis, obOtherOpen); _pfWorldEditingProfile.StopTimer(CWorldEditingProfile::PTI_OBJECTCSG); // if there are no sectors in this brush } else { // just put the open sector directly in the result obResult = obOtherOpen; } // return the result back to this brush AddObjectToBrush(obResult, enThis); } // get closed sectors of the other brush to object CBrushSectorSelectionForCSG selbscOtherClosed; bmOther.SelectClosedSectors(selbscOtherClosed); CObject3D obOtherClosed; DOUBLEaabbox3D boxOtherClosed; woOther.CopySourceBrushSectorsToObject(enOther, selbscOtherClosed, plOther, obOtherClosed, enThis.en_plPlacement, boxOtherClosed); // if there are closed sectors in other object if (obOtherClosed.ob_aoscSectors.Count()>0) { CObject3D obResult; // if there are any sectors in this brush if (bmThis.bm_abscSectors.Count()>0) { // move affected part of this brush to an object3d object CObject3D obThis; MoveTargetBrushPartToObject(enThis, boxOtherClosed, obThis); // do the closed sectors CSG operation on the objects _pfWorldEditingProfile.StartTimer(CWorldEditingProfile::PTI_OBJECTCSG); (obResult.*DoCSGClosedSectors)(obThis, obOtherClosed); _pfWorldEditingProfile.StopTimer(CWorldEditingProfile::PTI_OBJECTCSG); // if there are no sectors in this brush } else { // just put the closed sectors directly in the result obResult = obOtherClosed; } // return the result back to this brush AddObjectToBrush(obResult, enThis); } }
// // // 클라이언트용 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 CMover::ProcessMoveArrival( CCtrl *pObj ) { switch( m_oaCmd ) // 목표에 도착한 후의 명령 처리. { case OBJACT_USESKILL: if( pObj->GetType() == OT_MOVER ) // 타겟이 무버일때면 처리함. { int nSkillIdx = GetCmdParam(0); OBJID idTarget = (OBJID)GetCmdParam(1); SKILLUSETYPE sutType = (SKILLUSETYPE)GetCmdParam(2); LPSKILL pSkill = GetSkill( 0, nSkillIdx ); // this가 가진 스킬중 nIdx에 해당하는 스킬을 꺼낸다. if( pSkill == NULL ) { Error( "ProcessMoveArrival mover:%s skill(%d) not found.", m_szName, nSkillIdx ); return; // skill not found } #if __VER >= 10 // __LEGEND // 10차 전승시스템 Neuz, World, Trans if( pSkill->dwSkill == SI_MAG_MAG_BLINKPOOL || pSkill->dwSkill == SI_RIG_HERO_RETURN ) #else //__LEGEND // 10차 전승시스템 Neuz, World, Trans if( pSkill->dwSkill == SI_MAG_MAG_BLINKPOOL ) #endif //__LEGEND // 10차 전승시스템 Neuz, World, Trans return; // 아직 서버명령으로는 블링크풀 사용못함. 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 ) ) // 시전자와 타겟사이 장애물을 검사. { if( IsPlayer() ) ((CUser *)this)->AddDefinedText( TID_GAME_BLOCKTARGETING, "" ); break; } #if __VER >= 8 // __S8_PK BOOL bSuccess = DoUseSkill( 0, nSkillIdx, idTarget, sutType, FALSE ); // 목표지점에 도착하면 스킬 사용시작. #else // __VER >= 8 // __S8_PK BOOL bSuccess = DoUseSkill( 0, nSkillIdx, idTarget, sutType ); // 목표지점에 도착하면 스킬 사용시작. #endif // __VER >= 8 // __S8_PK if( bSuccess == FALSE ) if( IsPlayer() ) ((CUser *)this)->m_playTaskBar.OnEndSkillQueue( (CUser *)this ); ClearDestObj(); // 목표에 도달하면 추적을 멈춤. SendActMsg( OBJMSG_STOP ); } break; default: SendActMsg( OBJMSG_STOP ); ClearDestObj(); // 목표에 도달하면 추적을 멈춤. OnArrive( pObj->GetId(), 0 ); break; } // switch SetCmd( OBJACT_NONE ); if( IsPlayer() ) ((CUser*)this)->AddQueryGetDestObj( NULL_ID ); }
// gets called every frame to draw the scene void CRenderer::Update(const float dt, const uint32_t ticks) { CObj* obj, *localctrl; int localctrlid; OBJITER iter; matrix_t m; vec3_t dir, up, side; CFrustum frustum; CWorld* world; localctrl = m_world->GetLocalController(); localctrlid = m_world->GetLocalObj()->GetID(); world = m_world->GetInterpWorld(); const vec3_t campos = localctrl->GetOrigin(); const quaternion_t camrot = localctrl->GetRot(); m.SetCamTransform(campos, camrot); m.GetVec3Cam(&dir, &up, &side); dir = -dir; frustum.Setup(campos, dir, up, side, RENDERER_FOV, (float)m_width/(float)m_height, PLANE_NEAR, PLANE_FAR); // light floating above the players head const vec3_t lightpos0(campos + vec3_t(0,25.0f,0)); const quaternion_t lightrot0(quaternion_t(vec3_t::xAxis, -90.0f*lynxmath::DEGTORAD)); const float lightpos0_4f[4] = {lightpos0.x, lightpos0.y, lightpos0.z, 1}; glLightfv(GL_LIGHT0, GL_POSITION, lightpos0_4f); if(m_shaderactive) { if(m_useShadows) { glUseProgram(0); // draw shadowmap with fixed function pipeline PrepareShadowMap(lightpos0, lightrot0, world, localctrlid); // the player is the light } glUseProgram(m_program); // activate shader } glMatrixMode(GL_MODELVIEW); glLoadMatrixf(m.pm); glClear(GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT); glActiveTexture(GL_TEXTURE0); // normal texture channel if(m_shaderactive) { glUniform1i(m_tex, 0); // good old textures: GL_TEXTURE0 glUniform1i(m_normalMap, 1); // normal maps are GL_TEXTURE1 glUniform1i(m_lightmap, 2); // lightmap if(m_useShadows) { glUniform1i(m_shadowMapUniform, 7); glActiveTexture(GL_TEXTURE7); // shadow mapping texture GL_TEXTURE7 glBindTexture(GL_TEXTURE_2D, m_depthTextureId); glActiveTexture(GL_TEXTURE0); } #ifdef DRAW_NORMALS glUseProgram(0); // use fixed pipeline for this debug mode #endif } // Main drawing DrawScene(frustum, world, localctrlid, false); if(m_shaderactive) glUseProgram(0); // don't use shader for particles // Particle Draw glDisable(GL_LIGHTING); glDepthMask(false); for(iter=world->ObjBegin();iter!=world->ObjEnd();++iter) { obj = (*iter).second; if(obj->GetMesh()) { // Animate mesh is done in the particle loop // and not in DrawScene, because DrawScene // can be called multiple times per frame obj->GetMesh()->Animate(obj->GetMeshState(), dt); } if(obj->GetID() == localctrlid || !obj->GetParticleSystem()) continue; // Update/animate the particles, depending on dt and the current position. obj->GetParticleSystem()->Update(dt, ticks, obj->GetOrigin()); // Draw the particles. FIXME: this should use a frustum test obj->GetParticleSystem()->Render(side, up, dir); } glDepthMask(true); glColor4f(1,1,1,1); glEnable(GL_LIGHTING); #ifdef DRAW_NORMALS // Draw vertex normals of level geometry (not face normals) if(world && world->GetBSP()) { glDisable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); world->GetBSP()->RenderNormals(); glEnable(GL_LIGHTING); glEnable(GL_DEPTH_TEST); } #endif // Draw weapon if(m_shaderactive) // use shader for weapon glUseProgram(m_program); CModelMD5* viewmodel; md5_state_t* viewmodelstate; m_world->m_hud.GetModel(&viewmodel, &viewmodelstate); glDisable(GL_LIGHTING); if(viewmodel) { glClear(GL_DEPTH_BUFFER_BIT); glPushMatrix(); glLoadIdentity(); viewmodel->Render(viewmodelstate); viewmodel->Animate(viewmodelstate, dt); glPopMatrix(); } glEnable(GL_LIGHTING); // Draw HUD if(m_shaderactive) glUseProgram(0); // no shader for HUD glDisable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(0, m_width, m_height, 0, 0, 1); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glColor4f(1,1,1,1); glBindTexture(GL_TEXTURE_2D, m_crosshair); // Draw center crosshair glBegin(GL_QUADS); glTexCoord2d(0,1); glVertex3f((m_width-m_crosshair_width)*0.5f, (m_height-m_crosshair_height)*0.5f,0.0f); glTexCoord2d(0,0); glVertex3f((m_width-m_crosshair_width)*0.5f, (m_height+m_crosshair_height)*0.5f,0.0f); glTexCoord2d(1,0); glVertex3f((m_width+m_crosshair_width)*0.5f, (m_height+m_crosshair_height)*0.5f,0.0f); glTexCoord2d(1,1); glVertex3f((m_width+m_crosshair_width)*0.5f, (m_height-m_crosshair_height)*0.5f,0.0f); glEnd(); // draw HUD text: score, health... char hudtextbuf[64]; sprintf(hudtextbuf, "Frags: %i", m_world->m_hud.score); m_font.DrawGL(10.0f, m_height - 30.0f, 0.0f, hudtextbuf); sprintf(hudtextbuf, "%i", m_world->m_hud.health); m_font.DrawGL(10.0f, m_height - 35.0f - (float)m_font.GetHeight(), 0.0f, hudtextbuf); #ifdef DRAW_SHADOWMAP // draw a small window with the scene from the light POV if(m_shaderactive) { //glBindTexture(GL_TEXTURE_2D, m_depthTextureId); glBindTexture(GL_TEXTURE_2D, g_fboShadowCamColor); const float shadowmap_debug_width = 200.0f; const float shadowmap_debug_height = shadowmap_debug_width*(float)m_height/(float)m_width; glBegin(GL_QUADS); glTexCoord2d(0,1); // upper left glVertex3f(0.0f, 0.0f, 0.0f); glTexCoord2d(0,0); //lower left glVertex3f(0.0f, shadowmap_debug_height, 0.0f); glTexCoord2d(1,0); //lower right glVertex3f(shadowmap_debug_width, shadowmap_debug_height, 0.0f); glTexCoord2d(1,1); // upper right glVertex3f(shadowmap_debug_width, 0.0f, 0.0f); glEnd(); } #endif glBindTexture(GL_TEXTURE_2D, 0); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glEnable(GL_LIGHTING); glEnable(GL_DEPTH_TEST); }
int Sphere_InitServer( int argc, char *argv[] ) { const char *m_sClassName = "Sphere"; EXC_TRY("Init"); ASSERT(MAX_BUFFER >= sizeof(CCommand)); ASSERT(MAX_BUFFER >= sizeof(CEvent)); ASSERT(sizeof(int) == sizeof(DWORD)); // make this assumption often. ASSERT(sizeof(ITEMID_TYPE) == sizeof(DWORD)); ASSERT(sizeof(WORD) == 2 ); ASSERT(sizeof(DWORD) == 4 ); ASSERT(sizeof(NWORD) == 2 ); ASSERT(sizeof(NDWORD) == 4 ); ASSERT(sizeof(CUOItemTypeRec) == 37 ); // byte pack working ? ASSERT((std::numeric_limits<size_t>::min)() == 0); // ensure unsigned #ifdef _WIN32 if ( !QueryPerformanceFrequency(reinterpret_cast<LARGE_INTEGER *>(&llTimeProfileFrequency))) llTimeProfileFrequency = 1000; EXC_SET("setting exception catcher"); SetExceptionTranslator(); #endif // _WIN32 EXC_SET("loading"); if ( !g_Serv.Load() ) return -3; if ( argc > 1 ) { EXC_SET("cmdline"); if ( !g_Serv.CommandLine(argc, argv) ) return -1; } WritePidFile(2); EXC_SET("sockets init"); if ( !g_Serv.SocketsInit() ) return -9; EXC_SET("load world"); if ( !g_World.LoadAll() ) return -8; // load auto-complete dictionary EXC_SET("auto-complete"); { CFileText dict; if ( dict.Open(GRAY_FILE ".dic", OF_READ|OF_TEXT|OF_DEFAULTMODE) ) { TCHAR * pszTemp = Str_GetTemp(); size_t count = 0; while ( !dict.IsEOF() ) { dict.ReadString(pszTemp, SCRIPT_MAX_LINE_LEN-1); if ( *pszTemp ) { TCHAR *c = strchr(pszTemp, '\r'); if ( c != NULL ) *c = '\0'; c = strchr(pszTemp, '\n'); if ( c != NULL ) *c = '\0'; if ( *pszTemp != '\0' ) { count++; g_AutoComplete.AddTail(pszTemp); } } } g_Log.Event(LOGM_INIT, "Auto-complete dictionary loaded (contains %" FMTSIZE_T " words).\n", count); dict.Close(); } } g_Serv.SetServerMode(SERVMODE_Run); // ready to go. // Display EF/OF Flags g_Cfg.PrintEFOFFlags(); EXC_SET("finilizing"); g_Log.Event(LOGM_INIT, "%s", g_Serv.GetStatusString(0x24)); g_Log.Event(LOGM_INIT, "Startup complete. items=%lu, chars=%lu\n", g_Serv.StatGet(SERV_STAT_ITEMS), g_Serv.StatGet(SERV_STAT_CHARS)); #ifdef _WIN32 g_Log.Event(LOGM_INIT, "Press '?' for console commands\n"); #endif // Trigger server start g_Serv.r_Call("f_onserver_start", &g_Serv, NULL); return 0; EXC_CATCH; EXC_DEBUG_START; g_Log.EventDebug("cmdline argc=%d starting with %p (argv1='%s')\n", argc, static_cast<void *>(argv), ( argc > 2 ) ? argv[1] : ""); EXC_DEBUG_END; return -10; }
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; }
// // 오브젝트를 움직이는데 필요한 메시지를 발생 // int CWndWorld::ControlGround( DWORD dwMessage, CPoint point ) { bool fCastCancel = false; int nMsg = 0; BOOL bTempKey, bSit; // ,bCombatKey, bFlyKey BOOL bUp, bDown, bLeft, bRight, bSpace, bBoard, bLForward = FALSE, bRForward = FALSE; BOOL bWalk; static BOOL s_bWalk2 = 0; CMover* pMover = CMover::GetActiveMover(); CWndChat* pWndChat = (CWndChat*) g_WndMng.GetApplet( APP_COMMUNICATION_CHAT ); BOOL bWhisper = g_bKeyTable['R']; if( pWndChat && bWhisper ) { if( 0 < strlen( g_Neuz.m_szWhisperName ) ) { CString strWhisper; strWhisper.Format( "/whisper %s ", g_Neuz.m_szWhisperName ); pWndChat->SetFocus(); CWndEditChat* pWndEdit = &pWndChat->m_wndEdit; pWndEdit->SetString( strWhisper ); pWndEdit->SetFocus(); g_bKeyTable['R'] = FALSE; } } // 전진/후진/스톱 CWndBase* pWndBaseFocus = (CWndBase*) g_WndMng.GetFocusWnd(); if( g_Neuz.m_bActiveNeuz == FALSE || ( pWndChat && pWndBaseFocus && pWndBaseFocus == pWndChat ) ) { g_bKeyTable[g_Neuz.Key.chUp] = FALSE;// | m_bRButtonDown; g_bKeyTable[g_Neuz.Key.chLeft] = FALSE; g_bKeyTable['S'] = FALSE; g_bKeyTable['D'] = FALSE; g_bKeyTable['Q'] = FALSE; g_bKeyTable['E'] = FALSE; } bUp = g_bKeyTable[g_Neuz.Key.chUp]; // | m_bRButtonDown; bDown = g_bKeyTable['S']; #ifdef __BS_ADJUST_SYNC //gmpbigsun : 키보드 조작중에는 마우스이동 불가 if( bUp || bDown ) m_bLButtonDown = FALSE; #endif if( bDown ) { g_WndMng.m_bAutoRun = FALSE; } if( bUp ) { m_timerAutoRunPush.Reset(); if( m_nDubleUp == 2 && m_timerAutoRun.TimeOut() == FALSE ) { m_nDubleUp = 3; g_WndMng.m_bAutoRun = TRUE; m_timerAutoRun.Reset(); m_timerAutoRunBlock.Reset(); } else { m_nDubleUp = 1; m_timerAutoRun.Reset(); } if( m_timerAutoRunBlock.TimeOut() ) g_WndMng.m_bAutoRun = FALSE; } else { if( m_timerAutoRunPush.TimeOut() == FALSE ) { if( m_nDubleUp == 1 ) m_nDubleUp = 2; } else { m_nDubleUp = 0; } } if( g_WndMng.m_bAutoRun ) bUp = TRUE; // 좌/우 회전 bLeft = g_bKeyTable[g_Neuz.Key.chLeft]; bRight = g_bKeyTable['D']; bSpace = g_bKeyTable[ VK_SPACE ]; // bCombatKey = g_bKeyTable['C']; // g_bKeyTable['C'] = 0; bBoard = g_bKeyTable['B']; bSit = g_bKeyTable['V']; g_bKeyTable['V'] = 0; /* if( g_Option.m_nInterface == 2 ) { bLForward = g_bKeyTable['Q']; bRForward = g_bKeyTable['E']; if( m_bLButtonDown ) { if( bLeft ) { bLeft = FALSE; bLForward = TRUE; } if( bRight ) { bRight = FALSE; bRForward = TRUE; } } } */ CWorld* pWorld = g_WorldMng.Get(); CRect rect = GetClientRect(); D3DXVECTOR3 vRayEnd; CObj* pFocusObj = pWorld->GetObjFocus(); CActionMover *pAct = pMover->m_pActMover; pAct->m_dwCtrlMsg = 0; if( m_bLButtonDown ) pAct->m_dwCtrlMsg |= CTRLMSG_LDOWN; #if __VER >= 12 // __ITEMCREATEMON_S0602 D3DXVECTOR3 vec3Tri[3]; pWorld->ClientPointToVector( vec3Tri, rect, point, &pWorld->m_matProj, &g_Neuz.m_camera.m_matView, &vRayEnd, TRUE ); g_Neuz.m_vCursorPos = vRayEnd; if( g_Neuz.m_pCreateMonItem ) { if( bUp || bDown || bLeft || bRight || bSpace || m_bLButtonDown ) { BOOL bSendCM = TRUE; if( m_bLButtonDown ) { D3DXVECTOR3 vDist2 = g_pPlayer->GetPos() - g_Neuz.m_vCursorPos; float fDist = D3DXVec3Length( &vDist2 ); // 두좌표간의 거리 if( 15.f < fDist ) { g_WndMng.PutString( prj.GetText( TID_GAME_CREATEMON_F_15 ), NULL, prj.GetTextColor( TID_GAME_CREATEMON_F_15 ) ); bSendCM = FALSE; } if( bSendCM ) { int nAttr = g_pPlayer->GetWorld()->GetHeightAttribute( g_Neuz.m_vCursorPos.x, g_Neuz.m_vCursorPos.z ); // 이동할 위치의 속성 읽음. if( nAttr == HATTR_NOWALK || nAttr == HATTR_NOMOVE || g_pPlayer->IsRegionAttr( RA_SAFETY ) || g_pPlayer->GetWorld()->GetID() == WI_WORLD_GUILDWAR ) // 못 움직이는 곳이거나 안전지역이면 Pass { g_WndMng.PutString( prj.GetText( TID_GAME_CREATEMON_F_AREA ), NULL, prj.GetTextColor( TID_GAME_CREATEMON_F_AREA ) ); bSendCM = FALSE; } else if( g_pPlayer->GetWorld()->GetID() != WI_WORLD_MADRIGAL ) { g_WndMng.PutString( prj.GetText( TID_GAME_CREATEMON_F_AREA ), NULL, prj.GetTextColor( TID_GAME_CREATEMON_F_AREA ) ); bSendCM = FALSE; } if( bSendCM ) { g_DPlay.SendCreateMonster( MAKELONG( ITYPE_ITEM, g_Neuz.m_pCreateMonItem->m_dwObjId ), g_Neuz.m_vCursorPos ); } } m_bLButtonDown = FALSE; } if( bSendCM ) g_Neuz.m_pCreateMonItem = NULL; } } #endif // __ITEMCREATEMON_S0602 //TODO:ata3k님 꼭 고쳐주세요. 왜 그런지 아무도 몰라! // 이동금지 상태가 아닐때만 클릭으로 이동할수 있다. #ifdef __Y_INTERFACE_VER3 bool *bpButton; if( g_Option.m_nInterface == 2 ) bpButton = &m_bLButtonUp; else bpButton = &m_bLButtonDown; if( *bpButton ) #else //__Y_INTERFACE_VER3 if( m_bLButtonDown ) #endif //__Y_INTERFACE_VER3 { #ifdef __Y_INTERFACE_VER3 if( g_Option.m_nInterface == 2 ) { *bpButton = FALSE; if( m_timerLButtonDown.GetLeftTime() > 200 ) return nMsg; } #endif //__Y_INTERFACE_VER3 D3DXVECTOR3 vec3Tri[3]; if( pWorld->ClientPointToVector( vec3Tri, rect, point, &pWorld->m_matProj, &g_Neuz.m_camera.m_matView, &vRayEnd, TRUE ) ) { // 이동 포인트를 얻어 목표 세팅 if( m_bFreeMove ) { // if( m_bLButtonDown ) // 이동금지 상태가 아닐때만 클릭으로 이동할수 있다. { { if( m_pWndGuideSystem && m_pWndGuideSystem->IsVisible()) #if __VER >= 12 // __MOD_TUTORIAL m_pWndGuideSystem->m_Condition.bIsClickOnLand = true; #else m_pWndGuideSystem->SendGuideMessage(GUIDE_EVENT_MOVE); #endif #ifdef __IAOBJ0622 if( GetLastPickObj() && GetLastPickObj()->GetType() == OT_SHIP ) pMover->SetDestPos( (CShip *)GetLastPickObj(), vRayEnd ); else pMover->SetDestPos( vRayEnd ); #else pMover->SetDestPos( vRayEnd ); #endif pMover->m_nCorr = -1; #ifndef __J0823 m_bFreeMove = FALSE; g_DPlay.SendSnapshot( TRUE ); fCastCancel = true; if( g_pMoveMark && g_pMoveMark->m_pSfxObj ) g_pMoveMark->m_pSfxObj->m_nCurFrame = 180; CSfx *pObj = CreateSfx(g_Neuz.m_pd3dDevice,XI_GEN_MOVEMARK01,vRayEnd); D3DXVECTOR3 vVector1 = vec3Tri[2] - vec3Tri[0]; D3DXVECTOR3 vVector2 = vec3Tri[1] - vec3Tri[0]; D3DXVECTOR3 vNormal; D3DXVec3Cross( &vNormal, &vVector1, &vVector2); D3DXVec3Normalize( &vNormal, &vNormal ); D3DXVECTOR3 v3Up = D3DXVECTOR3( 0.0f, -1.0f, 0.0f ); D3DXVECTOR3 v3Cross; FLOAT fDot; FLOAT fTheta; D3DXVec3Cross( &v3Cross, &v3Up, &vNormal ); fDot = D3DXVec3Dot( &v3Up, &vNormal ); fTheta = acos( fDot ); D3DXQUATERNION qDirMap; D3DXQuaternionRotationAxis( &qDirMap, &v3Cross, fTheta ); D3DXVECTOR3 vYPW; QuaternionRotationToYPW( qDirMap, vYPW ); pObj->m_pSfxObj->m_vRotate.x = D3DXToDegree(vYPW.x); pObj->m_pSfxObj->m_vRotate.y = D3DXToDegree(vYPW.y); pObj->m_pSfxObj->m_vRotate.z = D3DXToDegree(vYPW.z); #endif // __J0823 m_objidTracking = NULL_ID; } } } } } //if( !pMover->IsEmptyDestPos() || !pMover->IsEmptyDestObj() ) // return nMsg; #ifdef __Y_INTERFACE_VER3 if( bUp || bDown || bLeft || bRight || bSpace || bLForward || bRForward ) // 이동 키조작이 들어가면 자동공격 멈춤. #else //__Y_INTERFACE_VER3 if( bUp || bDown || bLeft || bRight || bSpace ) // 이동 키조작이 들어가면 자동공격 멈춤. #endif //__Y_INTERFACE_VER3 { if( bUp || bDown ) #if __VER >= 12 // __MOD_TUTORIAL { CWndGuideSystem* pWndGuide = NULL; pWndGuide = (CWndGuideSystem*)GetWndBase( APP_GUIDE ); if(pWndGuide && pWndGuide->IsVisible()) pWndGuide->m_Condition.bIsKeyMove = true; } #else m_pWndGuideSystem->SendGuideMessage(GUIDE_EVENT_KEY_MOVE); #endif m_bAutoAttack = FALSE; g_pPlayer->ClearCmd(); if( !bSpace ) m_objidTracking = NULL_ID; } if( m_objidTracking != NULL_ID ) { CMover* pObjTracking = prj.GetMover( m_objidTracking ); if( pObjTracking ) { D3DXVECTOR3 vDis = pMover->GetPos() - pObjTracking->GetPos(); if( D3DXVec3LengthSq( &vDis ) > 16 ) pMover->SetDestObj( m_objidTracking ); } else m_objidTracking = NULL_ID; } bool fMoved = false; bool fBehavior = false; if( bUp ) { if( pMover->SendActMsg( OBJMSG_FORWARD ) == 1 ) { fMoved = true; fCastCancel = true; } } else if( bDown ) { if( pMover->SendActMsg( OBJMSG_BACKWARD ) == 1 ) { fMoved = true; fCastCancel = true; } } #ifdef __Y_INTERFACE_VER3 else if( bLForward ) { if( pMover->SendActMsg( OBJMSG_LFORWARD ) == 1 ) { fMoved = true; fCastCancel = true; } } else if( bRForward ) { if( pMover->SendActMsg( OBJMSG_RFORWARD ) == 1 ) { fMoved = true; fCastCancel = true; } } #endif //__Y_INTERFACE_VER3 else // if( (bUp == FALSE && s_bUped == TRUE) || (bDown == FALSE && s_bDowned == TRUE) ) // 키를 뗀 순간에만 처리해보자.. if( bUp == FALSE || bDown == FALSE ) { if( pMover->IsEmptyDest() ) { if( pMover->m_pActMover->IsActJump() == FALSE && (pMover->m_pActMover->IsStateFlag( OBJSTAF_SIT ) ) == 0 ) // 앉아있을땐 실행하면 안된다. { if( pMover->SendActMsg( OBJMSG_STAND ) == 1 ) { fMoved = true; // TRACE( "PlayerMoved, " ); } } } } // s_bUped = bUp; // s_bDowned = bDown; if( bLeft ) { if( pMover->SendActMsg( OBJMSG_LTURN ) == 1 ) { fMoved = true; } } else if( bRight ) { if( pMover->SendActMsg( OBJMSG_RTURN ) == 1 ) { fMoved = true; } } else { if( pMover->SendActMsg( OBJMSG_STOP_TURN ) == 1 ) { fMoved = true; // fBehavior = true; } } // jump if( bSpace ) { #if __VER < 12 // __MOD_TUTORIAL if( m_pWndGuideSystem ) m_pWndGuideSystem->SendGuideMessage(GUIDE_EVENT_KEY_JUMP); #endif if( pMover->SendActMsg( OBJMSG_JUMP ) == 1 ) { fBehavior = true; fCastCancel = true; } } if( m_bLButtonDown == TRUE && m_bRButtonDown == TRUE ) { if( m_timerLButtonDown.GetLeftTime() < 500 && m_timerRButtonDown.GetLeftTime() < 500 ) { if( g_pPlayer->SendActMsg( OBJMSG_JUMP ) == 1 ) { fBehavior = true; fCastCancel = true; } } } #ifdef __Y_INTERFACE_VER3 if( g_Option.m_nInterface == 2 ) { if( g_bKeyTable[VK_DIVIDE] || g_bKeyTable[191] ) { bWalk = TRUE; } else { bWalk = FALSE; } } else { bWalk = g_bKeyTable[g_Neuz.Key.chWalk]; } #else //__Y_INTERFACE_VER3 bWalk = g_bKeyTable[g_Neuz.Key.chWalk]; #endif //__Y_INTERFACE_VER3 if( bWalk && !s_bWalk2 ) // 걷기 모드 토글. { if( pMover->m_pActMover->IsStateFlag( OBJSTAF_WALK ) ) { if( pMover->SendActMsg( OBJMSG_MODE_RUN ) == 1 ) { g_WndMng.PutString( prj.GetText( TID_GAME_RUN ), NULL, prj.GetTextColor( TID_GAME_RUN ) , CHATSTY_SYSTEM_CLIENT ); fBehavior = true; } } else { #if __VER < 12 // __MOD_TUTORIAL if(m_pWndGuideSystem) m_pWndGuideSystem->SendGuideMessage(GUIDE_EVENT_KEY_RUN); #endif if( pMover->SendActMsg( OBJMSG_MODE_WALK ) == 1 ) { g_WndMng.PutString( prj.GetText( TID_GAME_WALK ), NULL, prj.GetTextColor( TID_GAME_WALK ) , CHATSTY_SYSTEM_CLIENT ); fBehavior = true; } } } s_bWalk2 = bWalk; if( fMoved || fBehavior ) { g_pPlayer->ClearDest(); #ifdef __J0823 g_DPlay.ClearPlayerDestPos(); #endif // __J0823 } if( fMoved ) g_DPlay.SendPlayerMoved(); if( fBehavior ) g_DPlay.SendPlayerBehavior(); if( g_pPlayer->IsStateMode( STATE_BASEMOTION_MODE ) && fCastCancel ) // 캐스트 취소 { g_DPlay.SendStateModeCancel( STATE_BASEMOTION_MODE, STATEMODE_BASEMOTION_CANCEL ); } // 운영자가 쓰는 키. 서버로부터 좌표받아오기. if( bTempKey = g_bKeyTable[ '8' ] ) { if( !m_bTemp3ed ) { pMover->SendActMsg( OBJMSG_TEMP2 ); // __bTestLOD ^= 1; } } m_bTemp3ed = bTempKey; //----------- 스킬사용. /* static BOOL s_bShift2, s_bKeyC2; BOOL bShift, bKeyC; if( g_Option.m_nInterface == 1 ) // 신버전 인터페이스 방식은 X 가 스킬사용이다. { bShift = g_bKeyTable[ VK_SHIFT ]; bKeyC = g_bKeyTable[ 'C' ]; if( bKeyC ) { int a = 0; } if( (bShift && !s_bShift2) || (bKeyC && !s_bKeyC2) ) { CObj* pTargetObj = CObj::m_pObjHighlight; // 커서를 대고 있던 오브젝트가 하이라이트 오브젝이다. if( pTargetObj ) // 커서를 대고 있던 오브젝트가 있으면 { pWorld->SetObjFocus( pTargetObj ); // 그놈을 셀렉트 하는 동시에. CMover* pMover = (CMover*)pTargetObj; if( pMover->GetType() == OT_MOVER ) m_dwNextSkill = NEXTSKILL_ACTIONSLOT; // 스킬 사용 예약. } else m_dwNextSkill = NEXTSKILL_ACTIONSLOT; // 스킬 사용 예약. } s_bShift2 = bShift; s_bKeyC2 = bKeyC; } */ //------------ 비공정 타기 if( bBoard ) { if( !s_bBoarded ) // 플레이어가 비공정에 올라타있는 상태에서. 탑승키를 누르면. { if( g_pShip == NULL ) { if( g_pPlayer->GetIAObjLink() && g_pPlayer->GetIAObjLink()->GetType() == OT_SHIP && g_pPlayer->GetIAObjLink()->GetIndex() == 3 ) { CShip *pShip = (CShip *)g_pPlayer->GetIAObjLink(); if( pShip->GetMover() == NULL ) // 쥔장이 없는 배일때. { pShip->SetMover( g_pPlayer ); // 쥔장을 g_pPlayer로 설정. g_pShip = pShip; } } } else // 이미 배를 조종하고 있을때 { g_pShip->SetMover( NULL ); g_pShip = NULL; } } } s_bBoarded = bBoard; #ifdef _DEBUG // 디버깅용 키 if( bTempKey = g_bKeyTable[ VK_F2 ] ) { if( !s_bTempKeyed ) { // pMover->SendActMsg( OBJMSG_TEMP ); // g_Option.m_nObjectDetail ++; // if( g_Option.m_nObjectDetail > 2 ) g_Option.m_nObjectDetail = 0; } } s_bTempKeyed = bTempKey; if( bTempKey = g_bKeyTable[ 'F' ] ) { if( !m_bTemp2ed ) { pMover->SendActMsg( OBJMSG_TEMP3 ); } } m_bTemp2ed = bTempKey; #endif return nMsg; }
void CActionMover::PresupposePos2( D3DXVECTOR3* pv, D3DXVECTOR3* pvd, float* pf, float* pfAngleX, float* pfAccPower, u_long uTickCount ) { CMover* pMover = GetMover(); D3DXVECTOR3 v = pMover->GetPos(); float fAngle = pMover->GetAngle(); D3DXVECTOR3 vDelta = m_vDelta; if( prj.GetItemProp( pMover->m_dwRideItemIdx ) == NULL ) return; float fAcc = prj.GetItemProp( pMover->m_dwRideItemIdx )->fFlightSpeed; // 무버가 타고있는 아이템의 인덱스에서 추진력을 꺼내옴. fAcc *= 0.75f; float fTheta, fThetaX, d; DWORD dwMoveState = GetMoveState(); DWORD dwTurnState = GetTurnState(); DWORD dwLookState = GetLookState(); float fX = pMover->GetAngleX(); float fAccPower = m_fAccPower; float fTurnAngle; D3DXVECTOR3 vAcc; for( u_long i = 0; i < uTickCount; i++ ) { fTheta = D3DXToRadian( fAngle ); switch( dwMoveState ) { case OBJSTA_STAND: fAccPower = 0; break; case OBJSTA_FMOVE: fAccPower = fAcc; break; } switch( dwTurnState ) { case OBJSTA_LTURN: fTurnAngle = m_fTurnAngle; if( ( GetStateFlag() & OBJSTAF_ACC ) == 0 ) fTurnAngle *= 2.5f; fAngle += fTurnAngle; if( fAngle > 360.0f ) fAngle -= 360.0f; break; case OBJSTA_RTURN: fTurnAngle = m_fTurnAngle; if( ( GetStateFlag() & OBJSTAF_ACC ) == 0 ) fTurnAngle *= 2.5f; fAngle -= fTurnAngle; if( fAngle < 0.0f ) fAngle += 360.0f; break; } switch( dwLookState ) { case OBJSTA_LOOKUP: if( fX > -45.0f ) fX -= 1.0f; break; case OBJSTA_LOOKDOWN: if( fX < 45.0f ) fX += 1.0f; break; } fThetaX = D3DXToRadian( fX ); if( GetStateFlag() & OBJSTAF_TURBO ) fAccPower *= 1.5f; d = cosf( fThetaX ) * fAccPower; fTheta = D3DXToRadian( fAngle ); vAcc.x = sinf( fTheta ) * d; vAcc.z = -cosf( fTheta ) * d; vAcc.y = -sinf( fThetaX ) * fAccPower; float fLenSq = D3DXVec3LengthSq( &vDelta ); D3DXVECTOR3 vDeltaNorm, vAccNorm; D3DXVec3Normalize( &vDeltaNorm, &vDelta ); D3DXVec3Normalize( &vAccNorm, &vAcc ); float fDot = D3DXVec3Dot( &vDeltaNorm, &vAccNorm ); if( fAccPower > 0.0f ) { if( fLenSq > 0.01f ) { if( fDot < cosf( 70.0f ) ) { vAcc *= 2.0f; vDelta *= 0.985f; } } } fLenSq = D3DXVec3Length( &vDelta ); if( fLenSq < 0.3f ) { vDelta += vAcc; } vDelta *= ( 1.0f - FRIC_AIR ); v += vDelta; if( v.y > MAX_MOVE_HEIGHT ) v.y = MAX_MOVE_HEIGHT; CWorld* pWorld = GetWorld(); pWorld->ClipX( v.x ); pWorld->ClipZ( v.z ); } *pv = v; *pf = fAngle; *pvd = vDelta; *pfAngleX = fX; *pfAccPower = fAccPower; pMover->m_nCorr = (int)uTickCount; }