diff --git a/proj/sxgame/vs2013/sxgame.vcxproj b/proj/sxgame/vs2013/sxgame.vcxproj index 5f6b91c46b9adb2f15159afad05d05fe1692eb35..b70be725fa3ad8ec5a1892e3129ac3e8a9dfdfee 100644 --- a/proj/sxgame/vs2013/sxgame.vcxproj +++ b/proj/sxgame/vs2013/sxgame.vcxproj @@ -210,6 +210,7 @@ <ClCompile Include="..\..\..\source\game\GUIInventoryController.cpp" /> <ClCompile Include="..\..\..\source\game\HUDcontroller.cpp" /> <ClCompile Include="..\..\..\source\game\InfoParticlePlayer.cpp" /> + <ClCompile Include="..\..\..\source\game\LadderMovementController.cpp" /> <ClCompile Include="..\..\..\source\game\LightDirectional.cpp" /> <ClCompile Include="..\..\..\source\game\LightPoint.cpp" /> <ClCompile Include="..\..\..\source\game\LightSun.cpp" /> @@ -291,7 +292,9 @@ <ClInclude Include="..\..\..\source\game\GUIInventoryController.h" /> <ClInclude Include="..\..\..\source\game\HUDcontroller.h" /> <ClInclude Include="..\..\..\source\game\IGameState.h" /> + <ClInclude Include="..\..\..\source\game\IMovementController.h" /> <ClInclude Include="..\..\..\source\game\InfoParticlePlayer.h" /> + <ClInclude Include="..\..\..\source\game\LadderMovementController.h" /> <ClInclude Include="..\..\..\source\game\LightSun.h" /> <ClInclude Include="..\..\..\source\game\LogicAuto.h" /> <ClInclude Include="..\..\..\source\game\LogicConsole.h" /> diff --git a/proj/sxgame/vs2013/sxgame.vcxproj.filters b/proj/sxgame/vs2013/sxgame.vcxproj.filters index e9732da19c4698d9cc891d33dfa33eb6877a8a2c..912083c6e42413dc9b11a3faf46109c7a44d1191 100644 --- a/proj/sxgame/vs2013/sxgame.vcxproj.filters +++ b/proj/sxgame/vs2013/sxgame.vcxproj.filters @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup> <Filter Include="Source Files"> @@ -115,6 +115,12 @@ <Filter Include="Header Files\ents\info"> <UniqueIdentifier>{93ee5d69-dabd-4584-8e15-0acd713e614f}</UniqueIdentifier> </Filter> + <Filter Include="Header Files\character_movement"> + <UniqueIdentifier>{3852670f-3617-4451-bfc1-c0aba9c194fa}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files\character_movement"> + <UniqueIdentifier>{7f56c9eb-5a04-4d29-ab96-b7e3d8d368f1}</UniqueIdentifier> + </Filter> </ItemGroup> <ItemGroup> <ClCompile Include="..\..\..\source\game\sxgame_dll.cpp"> @@ -360,6 +366,9 @@ <ClCompile Include="..\..\..\source\game\CraftSystem.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="..\..\..\source\game\LadderMovementController.cpp"> + <Filter>Source Files\character_movement</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\..\source\game\sxgame.h"> @@ -629,6 +638,12 @@ <ClInclude Include="..\..\..\source\game\CraftSystem.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="..\..\..\source\game\IMovementController.h"> + <Filter>Header Files\character_movement</Filter> + </ClInclude> + <ClInclude Include="..\..\..\source\game\LadderMovementController.h"> + <Filter>Header Files\character_movement</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ResourceCompile Include="..\..\..\source\game\sxgame.rc"> diff --git a/source/game/BaseCharacter.cpp b/source/game/BaseCharacter.cpp index 9fe1801979d2e5aca81632d8cc39bf251b6790ae..89dd1892c1856f74000bcce7c6f347d71c9ce70d 100644 --- a/source/game/BaseCharacter.cpp +++ b/source/game/BaseCharacter.cpp @@ -124,31 +124,20 @@ CBaseCharacter::~CBaseCharacter() mem_release(m_pHandsModelResource); + mem_release(m_pMovementController); + if(m_idQuadCurr >= 0) { //SAIG_QuadSetState(m_idQuadCurr, AIQUAD_STATE_FREE); } } -void CBaseCharacter::mountToLadder(CFuncLadder *pLadder) -{ - if(m_pLadder == pLadder) - { - return; - } - m_pLadder = pLadder; - float3 vStart = m_pLadder->getPos(), vEnd = m_pLadder->getUpPos(); - - float3 vPointOnLadder = SMProjectPointOnLine(getPos(), vEnd, vEnd - vStart); - setPos(vPointOnLadder); - m_uMoveDir |= PM_LADDER; - m_pCharacter->setGravity({0, 0, 0}); - m_pCharacter->setVelocityForTimeInterval({0, 0, 0}, 0); -} - -void CBaseCharacter::dismountFromLadder() +void CBaseCharacter::setMovementController(IMovementController *pController) { - m_pLadder = NULL; + mem_release(m_pMovementController); + m_pMovementController = pController; + add_ref(m_pMovementController); + SAFE_CALL(m_pMovementController, setCharacter, this); } void CBaseCharacter::attack(BOOL state) @@ -471,8 +460,12 @@ void CBaseCharacter::onPhysicsStep() { return; } - float3 vPos = m_pGhostObject->getPosition(); - setPos(vPos - float3(0.0f, m_fCapsHeight * m_fCurrentHeight * 0.5f, 0.0f)); + + if(!m_pMovementController) + { + float3 vPos = m_pGhostObject->getPosition(); + setPos(vPos - float3(0.0f, m_fCapsHeight * m_fCurrentHeight * 0.5f, 0.0f)); + } m_pHeadEnt->setOffsetPos(getHeadOffset()); @@ -558,6 +551,11 @@ void CBaseCharacter::use(bool start) if(start) { + if(m_pMovementController && m_pMovementController->handleUse()) + { + return; + } + float3 start = getHead()->getPos(); float3 dir = getHead()->getOrient() * float3(0.0f, 0.0f, 1.0f); float3 end = start + dir * 2.0f; diff --git a/source/game/BaseCharacter.h b/source/game/BaseCharacter.h index bdd0670bc3a26a9a2ac81ab08736084dc77be28e..ad1cbcb3deb5d8c108b57232050f6dbd064683c3 100644 --- a/source/game/BaseCharacter.h +++ b/source/game/BaseCharacter.h @@ -20,6 +20,7 @@ See the license in LICENSE #include "LightDirectional.h" #include "CharacterInventory.h" #include "PointEntity.h" +#include "IMovementController.h" class CBaseTool; @@ -36,12 +37,10 @@ enum PLAYER_MOVE PM_RUN = 0x40, //!< бежать PM_CRAWL = 0x80, //!< лежать PM_OBSERVER = 0x100, //!< наблюдатель - PM_LADDER = 0x200, //!< лестница PM_STOP = 0xFFFF }; -class CFuncLadder; class CHUDcontroller; class CBaseCharacter; @@ -138,17 +137,14 @@ public: void onPostLoad() override; - void mountToLadder(CFuncLadder *pLadder); - - void dismountFromLadder(); + void setMovementController(IMovementController *pController); void renderEditor(bool is3D, bool bRenderSelection, IXGizmoRenderer *pRenderer) override; - void mountToLadder(CFuncLadder *pLadder); - - void dismountFromLadder(); - - void renderEditor(bool is3D, bool bRenderSelection, IXGizmoRenderer *pRenderer) override; + IXCharacterController* getCharacterController() + { + return(m_pCharacter); + } protected: //! Фонарик @@ -200,7 +196,8 @@ protected: virtual float3 getHeadOffset(); - CFuncLadder *m_pLadder = NULL; + IMovementController *m_pMovementController = NULL; + private: static IEventChannel<XEventPhysicsStep> *m_pTickEventChannel; CCharacterPhysicsTickEventListener m_physicsTicker; diff --git a/source/game/FuncLadder.cpp b/source/game/FuncLadder.cpp index f6a9442eb496c11319c51c861bd5aed10f76ddcf..d8e859d99fd6e38941c083f54c24f08c1c476ff6 100644 --- a/source/game/FuncLadder.cpp +++ b/source/game/FuncLadder.cpp @@ -1,5 +1,6 @@ #include "FuncLadder.h" #include "BaseCharacter.h" +#include "LadderMovementController.h" BEGIN_PROPTABLE(CInfoLadderDismount) @@ -131,19 +132,18 @@ void CFuncLadder::initPhysics() mem_release(m_pCollideShape); float3 vDelta = m_vUpPoint - getPos(); - float3 vMin, vMax; + SMAABB aabb = getBound(); float3 vMinDelta, vMaxDelta; - getMinMax(&vMin, &vMax); float3_t aPointsBot[] = { - { vMin.x, vMax.y, vMin.z }, - { vMax.x, vMax.y, vMin.z }, - { vMin.x, vMax.y, vMax.z }, - { vMax.x, vMax.y, vMax.z } + {aabb.vMin.x, aabb.vMax.y, aabb.vMin.z }, + {aabb.vMax.x, aabb.vMax.y, aabb.vMin.z }, + {aabb.vMin.x, aabb.vMax.y, aabb.vMax.z }, + {aabb.vMax.x, aabb.vMax.y, aabb.vMax.z } }; - vMinDelta = vMin + vDelta; - vMaxDelta = vMax + vDelta; + vMinDelta = aabb.vMin + vDelta; + vMaxDelta = aabb.vMax + vDelta; float3_t aPointsTop[] = { { vMinDelta.x, vMinDelta.y, vMinDelta.z }, @@ -177,10 +177,10 @@ void CFuncLadder::initPhysics() aShapePoints[uIndex++] = aPointsTop[1]; } - aShapePoints[uIndex++] = vMin; - aShapePoints[uIndex++] = {vMin.x, vMin.y ,vMax.z}; - aShapePoints[uIndex++] = {vMax.x, vMin.y, vMax.z}; - aShapePoints[uIndex++] = {vMax.x, vMin.y, vMin.z}; + aShapePoints[uIndex++] = aabb.vMin; + aShapePoints[uIndex++] = {aabb.vMin.x, aabb.vMin.y, aabb.vMax.z}; + aShapePoints[uIndex++] = {aabb.vMax.x, aabb.vMin.y, aabb.vMax.z}; + aShapePoints[uIndex++] = {aabb.vMax.x, aabb.vMin.y, aabb.vMin.z}; aShapePoints[uIndex++] = vMaxDelta; aShapePoints[uIndex++] = {vMaxDelta.x, vMaxDelta.y, vMinDelta.z}; @@ -199,8 +199,7 @@ void CFuncLadder::renderEditor(bool is3D, bool bRenderSelection, IXGizmoRenderer pRenderer->setColor(c_vLineColor); pRenderer->setLineWidth(is3D ? 0.02f : 1.0f); - SMAABB aabb; - getMinMax(&aabb.vMin, &aabb.vMax); + SMAABB aabb = getBound(); pRenderer->drawAABB(aabb + getPos()); pRenderer->drawAABB(aabb + m_vUpPoint); pRenderer->jumpTo(getPos()); @@ -210,24 +209,152 @@ void CFuncLadder::renderEditor(bool is3D, bool bRenderSelection, IXGizmoRenderer void CFuncLadder::getMinMax(float3 *min, float3 *max) { + SMAABB aabb = getBound(); + aabb = SMAABBConvex(aabb, aabb + (getUpPos() - getPos())); + if(min) { - min->x = -0.25f; - min->y = 0.0f; - min->z = -0.25f; + *min = aabb.vMin; } if(max) { - max->x = 0.25f; - max->y = 1.8f; - max->z = 0.25f; + *max = aabb.vMax; + } +} + +SMAABB CFuncLadder::getBound() +{ + return(SMAABB(float3(-0.25f, 0.0f, -0.25f), float3(0.25f, 1.8f, 0.25f))); +} + +bool SMAABBIntersectLine(const SMAABB &aabb, const float3 &vStart, const float3 &vEnd, float3 *pvOut, float3 *pvNormal) +{ + float min_t = 0.0f; + float max_t = 1.0f; + + float3 vDir = vEnd - vStart; + + for(int i = 0; i < 3; ++i) + { + if(SMIsZero(vDir[i])) + { + if(vStart[i] < aabb.vMin[i] || vStart[i] > aabb.vMax[i]) + { + return(false); + } + } + + float t1 = (aabb.vMin[i] - vStart[i]) / vDir[i]; + float t2 = (aabb.vMax[i] - vStart[i]) / vDir[i]; + + float tmin = min(t1, t2); + float tmax = max(t1, t2); + + min_t = max(min_t, tmin); + max_t = min(max_t, tmax); + + if(min_t > max_t) + { + return(false); + } + } + + if(pvOut) + { + *pvOut = vStart + min_t * vDir; + } + + if(pvNormal) + { + *pvNormal = 0.0f; + + if(SMIsZero(aabb.vMin.x - pvOut->x)) + { + pvNormal->x = -1.0f; + } + else if(SMIsZero(aabb.vMax.x - pvOut->x)) + { + pvNormal->x = 1.0f; + } + else if(SMIsZero(aabb.vMin.y - pvOut->y)) + { + pvNormal->y = -1.0f; + } + else if(SMIsZero(aabb.vMax.y - pvOut->y)) + { + pvNormal->y = 1.0f; + } + else if(SMIsZero(aabb.vMin.z - pvOut->z)) + { + pvNormal->z = -1.0f; + } + else + { + pvNormal->z = 1.0f; + } } } bool CFuncLadder::rayTest(const float3 &vStart, const float3 &vEnd, float3 *pvOut, float3 *pvNormal, bool isRayInWorldSpace, bool bReturnNearestPoint) { - // TODO Implement me! + assert(isRayInWorldSpace); + + SMAABB aabb = getBound(); + + if(bReturnNearestPoint) + { + bool b0, b1; + float3 vPos0, vPos1; + float3 vNormal0, vNormal1; + float3 *pvNormal0 = NULL, *pvNormal1 = NULL; + if(pvNormal) + { + pvNormal0 = &vNormal0; + pvNormal1 = &vNormal1; + } + + b0 = SMAABBIntersectLine(aabb + getPos(), vStart, vEnd, &vPos0, pvNormal0); + b1 = SMAABBIntersectLine(aabb + getUpPos(), vStart, vEnd, &vPos1, pvNormal1); + + if(b0 && b1) + { + if(SMVector3Length2(vPos0 - vStart) > SMVector3Length2(vPos1 - vStart)) + { + b0 = false; + } + else + { + b1 = false; + } + } + + if(b0) + { + *pvOut = vPos0; + if(pvNormal) + { + *pvNormal = vNormal0; + } + } + else if(b1) + { + *pvOut = vPos1; + if(pvNormal) + { + *pvNormal = vNormal1; + } + } + + return(b0 || b1); + } + else + { + if(SMAABBIntersectLine(aabb + getPos(), vStart, vEnd, pvOut, pvNormal) || SMAABBIntersectLine(aabb + getUpPos(), vStart, vEnd, pvOut, pvNormal)) + { + return(true); + } + } return(false); } @@ -240,7 +367,7 @@ void CFuncLadder::onUse(CBaseEntity *pUser) float3 CFuncLadder::getUpPos() { - return m_vUpPoint; + return(m_vUpPoint); } void CFuncLadder::connectToLadder(CBaseEntity *pEntity) @@ -250,7 +377,9 @@ void CFuncLadder::connectToLadder(CBaseEntity *pEntity) return; } CBaseCharacter *pCharacter = (CBaseCharacter*)pEntity; - pCharacter->mountToLadder(this); + CLadderMovementController *pController = new CLadderMovementController(this); + pCharacter->setMovementController(pController); + mem_release(pController); } void CFuncLadder::onPhysicsStep() @@ -260,6 +389,8 @@ void CFuncLadder::onPhysicsStep() return; } + Array<CBaseEntity*> aCurrentTouchingEntities(m_aTouchedEntities.size()); + for(UINT i = 0, l = m_pGhostObject->getOverlappingPairCount(); i < l; ++i) { IXCollisionPair *pair = m_pGhostObject->getOverlappingPair(i); @@ -279,14 +410,20 @@ void CFuncLadder::onPhysicsStep() CBaseEntity *pEnt = (CBaseEntity*)pObject->getUserPointer(); if(pEnt) { - connectToLadder(pEnt); - //printf("touched %s\n", pEnt->getClassName()); + aCurrentTouchingEntities.push_back(pEnt); + if(m_aTouchedEntities.indexOf(pEnt) < 0) + { + connectToLadder(pEnt); + //printf("touched %s\n", pEnt->getClassName()); + } } } break; } } } + + m_aTouchedEntities = aCurrentTouchingEntities; } diff --git a/source/game/FuncLadder.h b/source/game/FuncLadder.h index 78530c7acda78bf3ebe5511d5c1b3eb84f48ecc9..520bae843399c68464c81ce786ed8b6976c09c3c 100644 --- a/source/game/FuncLadder.h +++ b/source/game/FuncLadder.h @@ -64,6 +64,8 @@ private: void disable(); void onPhysicsStep(); + SMAABB getBound(); + private: float3_t m_vUpPoint; bool m_isUpSet = false; @@ -77,6 +79,7 @@ private: static IEventChannel<XEventPhysicsStep> *m_pTickEventChannel; CPhysicsLadderTickEventListener m_physicsTicker; + Array<CBaseEntity*> m_aTouchedEntities; }; #endif diff --git a/source/game/IMovementController.h b/source/game/IMovementController.h new file mode 100644 index 0000000000000000000000000000000000000000..cf98817c7be270ed835ee1b96a9d304c2d471df6 --- /dev/null +++ b/source/game/IMovementController.h @@ -0,0 +1,19 @@ +#ifndef __IMOVEMENTCONTROLLER_H +#define __IMOVEMENTCONTROLLER_H + +#include <gdefines.h> + +class CBaseCharacter; +class IMovementController: public IXUnknown +{ +public: + virtual void setCharacter(CBaseCharacter *pCharacter) = 0; + + virtual void handleMove(const float3 &vDir) = 0; + virtual void handleJump() = 0; + virtual bool handleUse() = 0; + + virtual void update(float fDt) = 0; +}; + +#endif diff --git a/source/game/LadderMovementController.cpp b/source/game/LadderMovementController.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6152853f6bdaecc805dc1ce60e52c9693c7e9f76 --- /dev/null +++ b/source/game/LadderMovementController.cpp @@ -0,0 +1,119 @@ +#include "LadderMovementController.h" +#include "BaseCharacter.h" +#include "FuncLadder.h" +#include "Player.h" + +CLadderMovementController::CLadderMovementController(CFuncLadder *pLadder) +{ + m_vLadderPoint[0] = pLadder->getPos(); + m_vLadderPoint[1] = pLadder->getUpPos(); + + m_vLadderDir = SMVector3Normalize(m_vLadderPoint[1] - m_vLadderPoint[0]); +} +CLadderMovementController::~CLadderMovementController() +{ + if(m_pCharacter) + { + m_pCharacter->getCharacterController()->setGravity(float3(0.0f, -10.0f, 0.0f)); + } +} + +float3 SMProjectPointOnLine(const float3 &vPos, const float3 &vStart, const float3 &vEnd) +{ + float3 vN = SMVector3Normalize(vEnd - vStart); + float fDot0 = SMVector3Dot(vN, vPos - vStart); + if(fDot0 <= 0.0f) + { + return(vStart); + } + + float fDot1 = SMVector3Dot(vN, vPos - vEnd); + if(fDot1 >= 0.0f) + { + return(vEnd); + } + + return(vStart + vN * fDot0); +} + +void CLadderMovementController::setCharacter(CBaseCharacter *pCharacter) +{ + m_pCharacter = pCharacter; + + IXCharacterController *pCharacterController = pCharacter->getCharacterController(); + + pCharacterController->setGravity(float3(0.0f, 0.0f, 0.0f)); + pCharacterController->setVelocityForTimeInterval(float3(0.0f, 0.0f, 0.0f), 0.0f); + + TODO("Make move smoother"); + float3 vPointOnLadder = SMProjectPointOnLine(m_pCharacter->getPos(), m_vLadderPoint[0], m_vLadderPoint[1]); + m_pCharacter->setPos(vPointOnLadder); +} + +void CLadderMovementController::handleMove(const float3 &vDir) +{ + m_vMoveDir = vDir; +} + +void CLadderMovementController::handleJump() +{ + m_bWillDismount = true; +} + +bool CLadderMovementController::handleUse() +{ + m_bWillDismount = true; + return(true); +} + +void CLadderMovementController::update(float fDt) +{ + if(m_bWillDismount) + { + ((CPlayer*)m_pCharacter)->m_vCurrentSpeed = m_vMoveDir; + m_pCharacter->setMovementController(NULL); + } + else if(!SMIsZero(SMVector3Length2(m_vMoveDir))) + { + float fDot = SMVector3Dot(m_vLadderDir, m_vMoveDir); + + float3 vSpeed = m_vLadderDir * 3.0f; + float3 vNewPos; + + if(fDot > /*-SM_PIDIV4*/ -SMToRadian(10.0f)) + { + if(SMIsZero(SMVector3Length2(m_vLadderPoint[1] - m_pCharacter->getPos()))) + { + m_bWillDismount = true; + } + else + { + vNewPos = m_pCharacter->getPos() + vSpeed * fDt; + if(SMVector3Length2(vNewPos - m_vLadderPoint[0]) > SMVector3Length2(m_vLadderPoint[1] - m_vLadderPoint[0])) + { + vNewPos = m_vLadderPoint[1]; + } + } + } + else + { + if(SMIsZero(SMVector3Length2(m_vLadderPoint[0] - m_pCharacter->getPos()))) + { + m_bWillDismount = true; + } + else + { + vNewPos = m_pCharacter->getPos() - vSpeed * fDt; + if(SMVector3Length2(vNewPos - m_vLadderPoint[1]) > SMVector3Length2(m_vLadderPoint[1] - m_vLadderPoint[0])) + { + vNewPos = m_vLadderPoint[0]; + } + } + } + + if(!m_bWillDismount) + { + m_pCharacter->setPos(vNewPos); + } + } +} diff --git a/source/game/LadderMovementController.h b/source/game/LadderMovementController.h new file mode 100644 index 0000000000000000000000000000000000000000..a41cc4ac208975e67aba2a2005d6e2157cc878aa --- /dev/null +++ b/source/game/LadderMovementController.h @@ -0,0 +1,32 @@ +#ifndef __LADDERMOVEMENTCONTROLLER_H +#define __LADDERMOVEMENTCONTROLLER_H + +#include "IMovementController.h" + +class CFuncLadder; +class CLadderMovementController: public IXUnknownImplementation<IMovementController> +{ +public: + CLadderMovementController(CFuncLadder *pLadder); + ~CLadderMovementController(); + + void setCharacter(CBaseCharacter *pCharacter) override; + + void handleMove(const float3 &vDir) override; + void handleJump() override; + bool handleUse() override; + + void update(float fDt) override; + +private: + CBaseCharacter *m_pCharacter; + + float3_t m_vLadderPoint[2]; + float3_t m_vLadderDir; + + float3_t m_vMoveDir; + + bool m_bWillDismount = false; +}; + +#endif diff --git a/source/game/Player.cpp b/source/game/Player.cpp index acf1e85c24042e13727f48364cd3a8d75e12955f..3268ecebb50c9c7d4afd863eda2d5b270151064f 100644 --- a/source/game/Player.cpp +++ b/source/game/Player.cpp @@ -150,6 +150,7 @@ void CPlayer::updateInput(float dt) // m_vWpnShakeAngles = (float3)(m_vWpnShakeAngles * 0.4f); m_vWpnShakeAngles = (float3)(m_vWpnShakeAngles / (1.05f + dt)); + // Handle look if(!*editor_mode || SSInput_GetKeyState(SIM_LBUTTON)) { SSInput_GetMouseDelta(&x, &y); @@ -236,61 +237,43 @@ void CPlayer::updateInput(float dt) mov = true; } - if(m_uMoveDir & PM_CROUCH || (m_fCurrentHeight < 0.99f && !m_pCharacter->canStandUp((m_fCapsHeight - m_fCapsRadius * 2.0f) * (1.0f - m_fCurrentHeight)))) + if(m_uMoveDir & PM_OBSERVER) { - m_fCurrentHeight -= dt * 10.0f; - float fMinHeight = (m_fCapsHeightCrouch - m_fCapsRadius * 2.0f) / (m_fCapsHeight - m_fCapsRadius * 2.0f); - if(m_fCurrentHeight < fMinHeight) - { - m_fCurrentHeight = fMinHeight; - } + setPos(getPos() + m_pHeadEnt->getOrient() * (SMVector3Normalize(dir) * dt * 10.0f)); } - else + else if(m_pMovementController) { - m_fCurrentHeight += dt * 10.0f; - if(m_fCurrentHeight > 1.0f) + m_vCurrentSpeed = {0.0f, 0.0f, 0.0f}; + + if(m_uMoveDir & PM_JUMP) { - m_fCurrentHeight = 1.0f; + m_pMovementController->handleJump(); } + m_pMovementController->handleMove(m_pHeadEnt->getOrient() * SMVector3Normalize(dir)); + m_pMovementController->update(dt); } - m_pCollideShape->setLocalScaling(float3(1.0f, m_fCurrentHeight, 1.0f)); - - if(m_uMoveDir & PM_OBSERVER) - { - setPos(getPos() + m_pHeadEnt->getOrient() * (SMVector3Normalize(dir) * dt * 10.0f)); - } - else if(m_uMoveDir & PM_LADDER) + else { - if(m_uMoveDir & PM_FORWARD) + if(m_uMoveDir & PM_CROUCH || (m_fCurrentHeight < 0.99f && !m_pCharacter->canStandUp((m_fCapsHeight - m_fCapsRadius * 2.0f) * (1.0f - m_fCurrentHeight)))) { - float3 vSpeed(0.0f, 3.0f, 0.0f); - float3 fNewPos = getPos() + vSpeed * dt; - if(m_pLadder->getUpPos().y >= fNewPos.y) + m_fCurrentHeight -= dt * 10.0f; + float fMinHeight = (m_fCapsHeightCrouch - m_fCapsRadius * 2.0f) / (m_fCapsHeight - m_fCapsRadius * 2.0f); + if(m_fCurrentHeight < fMinHeight) { - setPos(fNewPos); - } - else - { - setPos(m_pLadder->getUpPos()); + m_fCurrentHeight = fMinHeight; } } - else if(m_uMoveDir & PM_BACKWARD) + else { - float3 vSpeed(0.0f, -3.0f, 0.0f); - float3 fNewPos = getPos() + vSpeed * dt; - if(m_pLadder->getPos().y <= fNewPos.y) + m_fCurrentHeight += dt * 10.0f; + if(m_fCurrentHeight > 1.0f) { - setPos(fNewPos); - } - else - { - setPos(m_pLadder->getPos()); + m_fCurrentHeight = 1.0f; } } - m_vCurrentSpeed = {0.0f, 0.0f, 0.0f}; - } - else - { + m_pCollideShape->setLocalScaling(float3(1.0f, m_fCurrentHeight, 1.0f)); + + dir = SMQuaternion(m_vPitchYawRoll.y, 'y') * (SMVector3Normalize(dir)/* * dt*/); dir *= 3.5f; if(m_uMoveDir & PM_CROUCH) @@ -411,7 +394,7 @@ void CPlayer::updateInput(float dt) //vel = getDiscreteLinearVelocity(); //printf("%f, %f, %f\n", vel.x, vel.y, vel.z); - m_vWpnShakeAngles.x += -vel.y * 0.05f; + m_vWpnShakeAngles.x += -vel.y * 0.01f; const float fMaxAng = SM_PI * 0.1f; m_vWpnShakeAngles.x = clampf(m_vWpnShakeAngles.x, -fMaxAng, fMaxAng); } @@ -492,6 +475,8 @@ void CPlayer::spawn() m_uMoveDir &= ~PM_OBSERVER; m_pCrosshair->enable(); + setMovementController(NULL); + GameData::m_pHUDcontroller->setPlayerRot(m_vPitchYawRoll); GameData::m_pHUDcontroller->setPlayerPos(getPos()); GameData::m_pHUDcontroller->setPlayerHealth(m_fHealth); diff --git a/source/game/Player.h b/source/game/Player.h index 797497644def32e57199073f33e0faed5ca8d53b..34ab9367236655984586e182949ce97c0ea35329 100644 --- a/source/game/Player.h +++ b/source/game/Player.h @@ -25,6 +25,7 @@ See the license in LICENSE //! Класс игрока \ingroup cbaseanimating class CPlayer: public CBaseCharacter { + friend class CLadderMovementController; DECLARE_CLASS(CPlayer, CBaseCharacter); DECLARE_PROPTABLE(); public: