diff --git a/source/game/BaseAnimating.h b/source/game/BaseAnimating.h index d8d7d9ac88745073cb4d2a639ed3f24eab0fbf11..e5336bcd4de9646f8c99ca3cb9dcd20f331e9b19 100644 --- a/source/game/BaseAnimating.h +++ b/source/game/BaseAnimating.h @@ -74,8 +74,6 @@ public: float3 getAttachmentPos(int id) override; SMQuaternion getAttachmentRot(int id) override; - //void onSync() override; - void playAnimation(const char * name, UINT uFadeTime = 0, UINT slot = 0); void playActivity(const char * name, UINT uFadeTime = 0, UINT slot = 0); diff --git a/source/game/BaseCharacter.cpp b/source/game/BaseCharacter.cpp index 93f558cbad7312bd0f4ac4bb9436aefe607018e9..859ba65d862ec8deed5fb3578470da99f6819fff 100644 --- a/source/game/BaseCharacter.cpp +++ b/source/game/BaseCharacter.cpp @@ -21,6 +21,8 @@ END_PROPTABLE() REGISTER_ENTITY_NOLISTING(CBaseCharacter, base_character); +IEventChannel<XEventPhysicsStep> *CBaseCharacter::m_pTickEventChannel = NULL; + class btKinematicClosestNotMeRayResultCallback: public btCollisionWorld::ClosestRayResultCallback { public: @@ -45,6 +47,20 @@ protected: btCollisionObject* m_me; }; +void CCharacterPhysicsTickEventListener::onEvent(const XEventPhysicsStep *pData) +{ + m_pCharacter->onPhysicsStep(); +} + +CBaseCharacter::CBaseCharacter(): + m_physicsTicker(this) +{ + if(!m_pTickEventChannel) + { + m_pTickEventChannel = Core_GetIXCore()->getEventChannel<XEventPhysicsStep>(EVENT_PHYSICS_STEP_GUID); + } +} + void CBaseCharacter::onPostLoad() { BaseClass::onPostLoad(); @@ -114,10 +130,14 @@ void CBaseCharacter::onPostLoad() m_idTaskSpread = SET_INTERVAL(updateSpread, 1.0f / 30.0f); m_pInventory = new CCharacterInventory(this); + + m_pTickEventChannel->addListener(&m_physicsTicker); } CBaseCharacter::~CBaseCharacter() { + m_pTickEventChannel->removeListener(&m_physicsTicker); + CLEAR_INTERVAL(m_idTaskSpread); REMOVE_ENTITY(m_pHeadEnt); REMOVE_ENTITY(m_flashlight); @@ -428,10 +448,15 @@ void CBaseCharacter::releaseHitboxes() mem_delete_a(m_pHitboxBodies); } -void CBaseCharacter::onSync() +float3 CBaseCharacter::getHeadOffset() { - BaseClass::onSync(); + float3 vHeadOffset; // = m_pHeadEnt->getOffsetPos(); + vHeadOffset.y = m_fCapsHeight * m_fCurrentHeight - 0.1f; + return(vHeadOffset); +} +void CBaseCharacter::onPhysicsStep() +{ updateHitboxes(); if(m_uMoveDir & PM_OBSERVER) @@ -439,13 +464,11 @@ void CBaseCharacter::onSync() return; } btTransform &trans = m_pGhostObject->getWorldTransform(); - m_vPosition = (float3)(float3(trans.getOrigin().x(), trans.getOrigin().y() - m_fCapsHeight * m_fCurrentHeight * 0.5f, trans.getOrigin().z())); - - float3 vHeadOffset = m_pHeadEnt->getOffsetPos(); - vHeadOffset.y = m_fCapsHeight * m_fCurrentHeight - 0.1f; - m_pHeadEnt->setOffsetPos(vHeadOffset); + setPos(float3(trans.getOrigin().x(), trans.getOrigin().y() - m_fCapsHeight * m_fCurrentHeight * 0.5f, trans.getOrigin().z())); + m_pHeadEnt->setOffsetPos(getHeadOffset()); +#if 0 //находим текущий квад аи сетки на котором находится игрок ID idq = SAIG_QuadGet(&float3(m_vPosition), true); //если нашли @@ -468,6 +491,7 @@ void CBaseCharacter::onSync() m_idQuadCurr = idq; } +#endif } void CBaseCharacter::initPhysics() diff --git a/source/game/BaseCharacter.h b/source/game/BaseCharacter.h index 71f6b88e4a01f7e9748c39aa7bdfde6cc3c3a246..6843723365c5e49fbefdee70ca99b026876a10f2 100644 --- a/source/game/BaseCharacter.h +++ b/source/game/BaseCharacter.h @@ -42,13 +42,29 @@ enum PLAYER_MOVE class CHUDcontroller; +class CBaseCharacter; +class CCharacterPhysicsTickEventListener final: public IEventListener<XEventPhysicsStep> +{ +public: + CCharacterPhysicsTickEventListener(CBaseCharacter *pTrigger): + m_pCharacter(pTrigger) + { + } + void onEvent(const XEventPhysicsStep *pData) override; + +private: + CBaseCharacter *m_pCharacter; +}; + //! Класс игрока \ingroup cbaseanimating class CBaseCharacter: public CBaseAnimating { DECLARE_CLASS(CBaseCharacter, CBaseAnimating); DECLARE_PROPTABLE(); + + friend class CCharacterPhysicsTickEventListener; public: - DECLARE_TRIVIAL_CONSTRUCTOR(); + DECLARE_CONSTRUCTOR(); ~CBaseCharacter(); //! Запускает/останавливает первичную атаку @@ -83,8 +99,6 @@ public: void releaseHitboxes(); void updateHitboxes(); - void onSync() override; - void initPhysics(); void releasePhysics(); @@ -167,6 +181,13 @@ protected: float m_fCurrentHeight = 1.0f; IXResourceModelAnimated *m_pHandsModelResource = NULL; + + virtual float3 getHeadOffset(); + +private: + static IEventChannel<XEventPhysicsStep> *m_pTickEventChannel; + CCharacterPhysicsTickEventListener m_physicsTicker; + void onPhysicsStep(); }; #endif diff --git a/source/game/BaseEntity.cpp b/source/game/BaseEntity.cpp index 6f7ff03ccb874d6eeac8470c6a458ce8a8a113c3..d9156c7f4636497057e23d060046f4ed7cb8065b 100644 --- a/source/game/BaseEntity.cpp +++ b/source/game/BaseEntity.cpp @@ -197,11 +197,32 @@ void CBaseEntity::setOrient(const SMQuaternion & q) void CBaseEntity::setOffsetOrient(const SMQuaternion & q) { m_qOffsetOrient = q; + onParentMoved(); } void CBaseEntity::setOffsetPos(const float3 & pos) { m_vOffsetPos = pos; + onParentMoved(); +} + +void CBaseEntity::setXform(const float3 &vPos, const SMQuaternion &q) +{ + bool bOld = m_isInOnParentMoved; + m_isInOnParentMoved = true; + setPos(vPos); + m_isInOnParentMoved = bOld; + + setOrient(q); +} +void CBaseEntity::setOffsetXform(const float3 &vPos, const SMQuaternion &q) +{ + bool bOld = m_isInOnParentMoved; + m_isInOnParentMoved = true; + setOffsetPos(vPos); + m_isInOnParentMoved = bOld; + + setOffsetOrient(q); } float3 CBaseEntity::getOffsetPos() @@ -267,7 +288,6 @@ bool CBaseEntity::setKV(const char * name, const char * value) SMQuaternion q; int d; float f; - CBaseEntity * pEnt; switch(field->type) { case PDF_INT: @@ -487,7 +507,6 @@ bool CBaseEntity::getKV(const char * name, char * out, int bufsize) } SMQuaternion q; float3_t f3; - CBaseEntity *pEnt; switch(field->type) { case PDF_INT: diff --git a/source/game/BaseEntity.h b/source/game/BaseEntity.h index ad35a5c17fa515d1560c67e8b2bc7b89d5410e00..a53dd17699a90a6df2cd24d59086e23af51c6c33 100644 --- a/source/game/BaseEntity.h +++ b/source/game/BaseEntity.h @@ -89,6 +89,9 @@ public: //! Возвращает вращение объекта SMQuaternion getOrient(); + void setXform(const float3 &vPos, const SMQuaternion &q); + void setOffsetXform(const float3 &vPos, const SMQuaternion &q); + //! Устанавливает свойство объекта virtual bool setKV(const char *name, const char *value); //! Получает свойство объекта @@ -224,10 +227,6 @@ protected: //! Владелец CEntityPointer<CBaseEntity> m_pOwner; - //! Вызывается на стадии синхронизации - virtual void onSync() - { - } //! Вызывается при создании после установки всех свойств virtual void onPostLoad(); diff --git a/source/game/BaseTool.cpp b/source/game/BaseTool.cpp index bbf92e0e6520a533b46bf68874e07e8a5b14ced1..f68dcd7e72b2927d1958bf81afa93eac27287c5a 100644 --- a/source/game/BaseTool.cpp +++ b/source/game/BaseTool.cpp @@ -232,8 +232,11 @@ void CBaseTool::dbgMove(int dir, float dy) , m_fCenterLength); break; } + + updateTransform(); } +#if 0 void CBaseTool::onSync() { if(m_pOwner) @@ -256,6 +259,18 @@ void CBaseTool::onSync() SPE_EffectSetRotQ(m_iMuzzleFlash, m_vOrientation); } } +#endif + +void CBaseTool::setShakeRotation(const SMQuaternion &q) +{ + m_qShakeRotation = q; + updateTransform(); +} + +void CBaseTool::updateTransform() +{ + setOffsetXform(m_vSlotPosResult, m_qSlotRotResult * m_qShakeRotation); +} void CBaseTool::_update(float dt) { @@ -346,6 +361,7 @@ void CBaseTool::_rezoom() { ((CPlayer*)m_pOwner.getEntity())->getCamera()->getCamera()->setFOV(SMToRadian(vlerp(*r_default_fov, *r_default_fov - 10.0f, m_fZoomProgress))); } + updateTransform(); } bool CBaseTool::isWeapon() const diff --git a/source/game/BaseTool.h b/source/game/BaseTool.h index 5689a976495505ed9c32b6566cba81e62bc3e24f..bd6dcb86977261a661cae9fe0328413d74caa484 100644 --- a/source/game/BaseTool.h +++ b/source/game/BaseTool.h @@ -54,8 +54,6 @@ public: void dbgMove(int dir, float delta); - void onSync() override; - void setParent(CBaseEntity * pEnt, int attachment = -1); //! Этот инструмент - оружие @@ -77,6 +75,8 @@ public: virtual void updateHUDinfo(); + void setShakeRotation(const SMQuaternion &q); + protected: bool isValidAmmo(CBaseSupply *pAmmo); @@ -104,6 +104,8 @@ protected: void _update(float dt); void _rezoom(); + void updateTransform(); + float m_fReloadTime = 0.0f; float3_t m_vSlotPos; @@ -138,6 +140,8 @@ protected: //! Этот инструмент - оружие bool m_bIsWeapon = false; + + SMQuaternion m_qShakeRotation; }; #endif diff --git a/source/game/EditorOutputsTab.cpp b/source/game/EditorOutputsTab.cpp index fe0a6236d8514b85cd27783f4251293cc78544e8..0dbf3aac286801dac50c9db9cf0fdcd6a9aaa619 100644 --- a/source/game/EditorOutputsTab.cpp +++ b/source/game/EditorOutputsTab.cpp @@ -594,7 +594,7 @@ INT_PTR CALLBACK CEditorOutputsTab::dlgProc(HWND hWnd, UINT msg, WPARAM wParam, if(pNMLV->hdr.idFrom == IDC_LIST_OUTPUTS && !m_isSkipUpdate && (pNMLV->uChanged & LVIF_STATE) && ((pNMLV->uNewState ^ pNMLV->uOldState) & LVIS_SELECTED)) { Row *pRow = &m_pCurrentCommand->m_aRows[pNMLV->iItem]; - pRow->isSelected = pNMLV->uNewState & LVIS_SELECTED; + pRow->isSelected = (pNMLV->uNewState & LVIS_SELECTED) != 0; updateButtons(); } diff --git a/source/game/EntityFactory.cpp b/source/game/EntityFactory.cpp index d78952205131eac8ee1cea4167093214540c8cb9..fcfa2eb693c8ad01247ef3651741726f32faf4d5 100644 --- a/source/game/EntityFactory.cpp +++ b/source/game/EntityFactory.cpp @@ -61,11 +61,6 @@ CBaseEntity* CEntityFactoryMap::create(const char *szName, CEntityManager *pWorl pEnt->_initEditorBoxes(); } - if(pFactory->isSyncable()) - { - pWorld->regSync(pEnt); - } - return(pEnt); } return(NULL); @@ -77,10 +72,6 @@ void CEntityFactoryMap::destroy(CBaseEntity *pEnt) IEntityFactory *pFactory = getFactory(pEnt->getClassName()); if(pFactory) { - if(pFactory->isSyncable()) - { - pEnt->m_pMgr->unregSync(pEnt); - } return(pFactory->destroy(pEnt)); } } diff --git a/source/game/EntityFactory.h b/source/game/EntityFactory.h index 8f995d9412165266570a44459addd137f8825d6b..bde74bf914ec1c024c8986bcd8ff38e83d0bd019 100644 --- a/source/game/EntityFactory.h +++ b/source/game/EntityFactory.h @@ -29,7 +29,6 @@ public: virtual bool isEditorHidden() = 0; virtual EntDefaultsMap* getDefaults() = 0; virtual IEntityFactory* copy(const char * szName, bool showInListing) = 0; - virtual bool isSyncable() = 0; }; class CEntityFactoryMap @@ -86,12 +85,11 @@ template <class T> class CEntityFactory: public IEntityFactory { public: - CEntityFactory(const char * szName, bool showInListing, bool isSyncable=true) + CEntityFactory(const char * szName, bool showInListing) { m_bShowInListing = showInListing; m_szClassName = szName; m_pPropTable = T::SGetPropTable(); - m_isSyncable = isSyncable; CEntityFactoryMap::GetInstance()->addFactory(this, szName); } @@ -141,11 +139,6 @@ public: return(!m_bShowInListing); } - bool isSyncable() override - { - return(m_isSyncable); - } - EntDefaultsMap* getDefaults() override { return(&m_mDefaults); @@ -155,7 +148,6 @@ private: const char * m_szClassName; proptable_t * m_pPropTable; bool m_bShowInListing; - bool m_isSyncable; EntDefaultsMap m_mDefaults; Array<CEntityFactory<T>*> m_vDerivatives; }; @@ -163,9 +155,6 @@ private: #define REGISTER_ENTITY(cls, name) \ CEntityFactory<cls> ent_ ## name ## _factory(#name, 1) -#define REGISTER_ENTITY_NOSYNC(cls, name) \ - CEntityFactory<cls> ent_ ## name ## _factory(#name, 1, 0) - #define REGISTER_ENTITY_NOLISTING(cls, name) \ CEntityFactory<cls> ent_ ## name ## _factory(#name, 0) diff --git a/source/game/EntityManager.cpp b/source/game/EntityManager.cpp index 0317024cd2de051a5a0880ec26c6f1ab9619c49e..cd1da1ffa179a6fc7f440c0363d724de1ab027bf 100644 --- a/source/game/EntityManager.cpp +++ b/source/game/EntityManager.cpp @@ -167,8 +167,6 @@ void CEntityManager::finalRemove() void CEntityManager::sync() { - CBaseEntity * pEnt; - finalRemove(); for(int i = 0, l = m_vTimeout.size(); i < l; ++i) @@ -200,16 +198,6 @@ void CEntityManager::sync() //float dt; //dt = (float)std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - tOld).count() / 1000000.0f; - for(int i = 0, l = m_vEntSyncList.size(); i < l; ++i) - { - pEnt = m_vEntSyncList[i]; - if(pEnt) - { - //pEnt->updateDiscreteLinearVelocity(0, dt); - pEnt->onSync(); - //pEnt->updateDiscreteLinearVelocity(1, dt); - } - } //tOld = std::chrono::high_resolution_clock::now(); } @@ -315,19 +303,6 @@ void CEntityManager::unreg(CBaseEntity *pEnt) m_mEnts.erase(*pEnt->getGUID()); } -void CEntityManager::regSync(CBaseEntity *pEnt) -{ - assert(pEnt); - m_vEntSyncList.push_back(pEnt); -} -void CEntityManager::unregSync(CBaseEntity *pEnt) -{ - assert(pEnt); - int iKey = m_vEntSyncList.indexOf(pEnt); - assert(iKey >= 0); - m_vEntSyncList.erase(iKey); -} - ID CEntityManager::setTimeout(void(CBaseEntity::*func)(float dt), CBaseEntity *pEnt, float delay) { timeout_t t; diff --git a/source/game/EntityManager.h b/source/game/EntityManager.h index 7355d911ade294ab59460ab7a1b78634278163df..373d7a7698693421532aeb72a32f27c63614208a 100644 --- a/source/game/EntityManager.h +++ b/source/game/EntityManager.h @@ -149,12 +149,8 @@ protected: const XGUID* reg(CBaseEntity *pEnt, const XGUID *pGUID=NULL); void unreg(CBaseEntity *pEnt); - void regSync(CBaseEntity *pEnt); - void unregSync(CBaseEntity *pEnt); - Map<XGUID, CBaseEntity*> m_mEnts; Array<CBaseEntity*, 64> m_vEntList; - Array<CBaseEntity*, 64> m_vEntSyncList; Array<CBaseEntity*> m_vEntRemoveList; Array<UINT> m_vFreeIDs; diff --git a/source/game/Player.cpp b/source/game/Player.cpp index d07b3b580cfe5ce78063c96525d4679a76db02e0..13b47219c88b435a0c146426562ea5c791a94374 100644 --- a/source/game/Player.cpp +++ b/source/game/Player.cpp @@ -95,7 +95,8 @@ void CPlayer::updateInput(float dt) return; } - m_vWpnShakeAngles = (float3)(m_vWpnShakeAngles * 0.4f); + // m_vWpnShakeAngles = (float3)(m_vWpnShakeAngles * 0.4f); + m_vWpnShakeAngles = (float3)(m_vWpnShakeAngles / (1.05f + dt)); if(!*editor_mode || SSInput_GetKeyState(SIM_LBUTTON)) { @@ -313,6 +314,8 @@ void CPlayer::updateInput(float dt) } + m_pActiveTool->setShakeRotation(SMQuaternion(m_vWpnShakeAngles.x, 'x') * SMQuaternion(m_vWpnShakeAngles.y, 'y') * SMQuaternion(m_vWpnShakeAngles.z, 'z')); + #ifndef _SERVER if(*grab_cursor && (!*editor_mode || SSInput_GetKeyState(SIM_LBUTTON))) { @@ -345,17 +348,17 @@ CPointCamera * CPlayer::getCamera() return(m_pCamera); } -void CPlayer::onSync() +float3 CPlayer::getHeadOffset() { - BaseClass::onSync(); + float3 vOffset = BaseClass::getHeadOffset(); - if(m_uMoveDir & PM_OBSERVER) + if(!(m_uMoveDir & PM_OBSERVER)) { - return; + vOffset.y += m_fViewbobY; + vOffset += m_fViewbobStrafe; } - m_vPosition.y += m_fViewbobY; - m_vPosition = (float3)(m_vPosition + m_fViewbobStrafe); + return(vOffset); } void CPlayer::observe() diff --git a/source/game/Player.h b/source/game/Player.h index c85778560b17befa0e9463727df07c9b37d653b7..9b4f3f7cc804a81de74695db152a44e3b346dcff 100644 --- a/source/game/Player.h +++ b/source/game/Player.h @@ -46,8 +46,6 @@ public: //! Обновляет инпут от игрока virtual void updateInput(float dt); - - void onSync() override; //! Получает смещения для задержки движения модели оружия при вращении игрока float3_t & getWeaponDeltaAngles(); @@ -105,6 +103,8 @@ protected: void onPostLoad() override; bool m_bCanRespawn = false; + + float3 getHeadOffset() override; }; #endif diff --git a/source/game/PropStatic.cpp b/source/game/PropStatic.cpp index 208bb7caaa9c125d4d4ed7119e451cd518bcc1fe..4305c48ba0f79244e6f614ddac5980e719a66553 100644 --- a/source/game/PropStatic.cpp +++ b/source/game/PropStatic.cpp @@ -18,7 +18,7 @@ BEGIN_PROPTABLE(CPropStatic) EDITOR_COMBO_END() END_PROPTABLE() -REGISTER_ENTITY_NOSYNC(CPropStatic, prop_static); +REGISTER_ENTITY(CPropStatic, prop_static); CPropStatic::CPropStatic() {