#include "baseentity.h" #include "baseplayer.h" #include "cglm/io.h" #include "cglm/vec2.h" #include "cglm/vec3.h" #include "console.h" #include "engine.h" #include "input.h" #include "math3d.h" #include "networking.h" #include "physics.h" #include "physics_gen.h" #define STEP_SIZE 0.3f #define PLAYER_WIDTH 0.5f #define PLAYER_HEIGHT 1.8f #define EPSILON 0.0005f class CMOBAPlayer: public CBasePlayer { public: virtual void Precache() override; virtual void Spawn( void ) override; virtual void Destroy( void ) override; virtual void ReadParameter( const char *szName, const char *szValue ) override; virtual void Think( float fDelta ) override; virtual void SendToServer() override; virtual void RecieveFromServer( void *pData, uint32_t nDataSize ) override; void Accelerate( void ); void AirAccelerate( void ); int ClipVelocity( vec3 in, vec3 normal, vec3 &out, float fOverbounce ); void FlyMove( void ); void GroundMove( void ); void AirMove( void ); void CategorizePosition( void ); void Friction( void ); void PlayerMove( void ); bool bIsForward = 0; bool bIsBack = 0; bool bIsLeft = 0; bool bIsRight = 0; bool bIsJumping = 0; bool bIsCrouching = 0; bool bIsProning = 0; bool bIsFiring = 0; bool bIsFiring2 = 0; float fStamina; float m_fDelta = 0; float fPitch = 0; float fYaw = 0; enum { PLAYER_GROUNDED, PLAYER_FLYING, } m_playerState; vec3 m_velocity = {0,0,0}; vec3 m_prevVelocity = {0,0,0}; vec2 forward = {}; vec2 right = {}; CPxBoxMesh mesh; CPxRigidKinematicPosition rigidbody; }; void CMOBAPlayer::Precache() { } void CMOBAPlayer::Spawn() { }; void CMOBAPlayer::ReadParameter( const char *szName, const char *szValue ) { CBaseEntity::ReadParameter(szName, szValue); } void CMOBAPlayer::Destroy() { } void CMOBAPlayer::AirAccelerate( void ) { m_velocity[2] -= 9.8 * m_fDelta; } void CMOBAPlayer::Accelerate( void ) { vec2 wishdir = {(float)bIsForward-bIsBack, (float)bIsLeft-bIsRight}; vec3 velocityDifference; vec3 acceleration; glm_vec2_rotate(wishdir, fYaw, wishdir); glm_vec2_normalize(wishdir); for ( int i = 0; i < 2; i++ ) m_velocity[i] += (wishdir[i]*6 - m_velocity[i]) * m_fDelta/0.25; } void CMOBAPlayer::Friction( void ) { }; void CMOBAPlayer::FlyMove( void ) { } void CMOBAPlayer::GroundMove( void ) { m_velocity[2] = 0; Accelerate(); } void CMOBAPlayer::CategorizePosition( void ) { px_vec3 p; px_cast_result r; p.m[0] = m_position[0]; p.m[1] = m_position[1]; p.m[2] = m_position[2]; r = px_box_cast(px, PLAYER_WIDTH/2, PLAYER_WIDTH/2, PLAYER_HEIGHT/2, p, (px_vec3){}, (px_vec3){0,0,-0.01}, 1); if (r.hit) { m_playerState = PLAYER_GROUNDED; } else { m_playerState = PLAYER_FLYING; } } void CMOBAPlayer::PlayerMove( void ) { CategorizePosition(); GroundMove(); vec3 velocity; for ( int i = 0; i < 3; i++ ) velocity[i] = (m_prevVelocity[i] + m_velocity[i]) * 0.5; for ( int i = 0; i < 3; i++ ) m_position[i] += velocity[i] * m_fDelta; for ( int i = 0; i < 3; i++ ) m_prevVelocity[i] = m_velocity[i]; CategorizePosition(); } struct PlayerMovement_t: public PacketPlayer_t { bool bIsForward; bool bIsBack; bool bIsLeft; bool bIsRight; float fPitch; float fYaw; }; void CMOBAPlayer::Think( float fDelta ) { if (INetworking::IsClient()) { if (g_localClient->pBasePlayer == this) { float x = g_fAxisValues[AXIS_MOUSE_X]; float y = g_fAxisValues[AXIS_MOUSE_Y]; fPitch = glm_rad(x); fYaw = glm_rad(y); } } m_fDelta = fDelta; PlayerMove(); }; void CMOBAPlayer::SendToServer() { PlayerMovement_t movement = { .bIsForward = bIsForward, .bIsBack = bIsBack, .bIsLeft = bIsLeft, .bIsRight = bIsRight, .fPitch = fPitch, .fYaw = fYaw, }; movement.type = PACKET_TYPE_PLAYER_MOVEMENT; if (INetworking::IsClient()) { if (g_localClient->pBasePlayer != this) return; INetworking::SendData(&movement, sizeof(PlayerMovement_t), 0, MESSAGE_MODE_RELIABLE); } else { for (auto &client: g_clients) { if (client->pBasePlayer == this) { movement.playerHandle = client->playerHandle; break; } } INetworking::SendDataEverybodyExcept(&movement, sizeof(PlayerMovement_t), this, MESSAGE_MODE_RELIABLE); } return; } void CMOBAPlayer::RecieveFromServer( void *pData, uint32_t nDataSize ) { Packet_t *pPacket = (Packet_t*)pData; if (pPacket->type == PACKET_TYPE_PLAYER_MOVEMENT) { if (nDataSize != sizeof(PlayerMovement_t)) return; PlayerMovement_t *pMovement = (PlayerMovement_t*)pPacket; bIsForward = pMovement->bIsForward; bIsBack = pMovement->bIsBack; bIsLeft = pMovement->bIsLeft; bIsRight = pMovement->bIsRight; fPitch = pMovement->fPitch; fYaw = pMovement->fYaw; }; }; void PlayerForward(int argc, char **argv) {if (g_localClient->pBasePlayer) ((CMOBAPlayer*)g_localClient->pBasePlayer)->bIsForward = true;}; void PlayerForwardUp(int argc, char **argv) {if (g_localClient->pBasePlayer) ((CMOBAPlayer*)g_localClient->pBasePlayer)->bIsForward = false;}; void PlayerBack(int argc, char **argv) {if (g_localClient->pBasePlayer) ((CMOBAPlayer*)g_localClient->pBasePlayer)->bIsBack = true;}; void PlayerBackUp(int argc, char **argv) {if (g_localClient->pBasePlayer) ((CMOBAPlayer*)g_localClient->pBasePlayer)->bIsBack = false;}; void PlayerLeft(int argc, char **argv) {if (g_localClient->pBasePlayer) ((CMOBAPlayer*)g_localClient->pBasePlayer)->bIsLeft = true;}; void PlayerLeftUp(int argc, char **argv) {if (g_localClient->pBasePlayer) ((CMOBAPlayer*)g_localClient->pBasePlayer)->bIsLeft = false;}; void PlayerRight(int argc, char **argv) {if (g_localClient->pBasePlayer) ((CMOBAPlayer*)g_localClient->pBasePlayer)->bIsRight = true;}; void PlayerRightUp(int argc, char **argv) {if (g_localClient->pBasePlayer) ((CMOBAPlayer*)g_localClient->pBasePlayer)->bIsRight = false;}; ConCommand moveForwardCmd("+forward", PlayerForward, 0); ConCommand moveForwardUpCmd("-forward", PlayerForwardUp, 0); ConCommand moveBackwardCmd("+back", PlayerBack, 0); ConCommand moveBackwardUpCmd("-back", PlayerBackUp, 0); ConCommand moveLeftCmd("+left", PlayerLeft, 0); ConCommand moveLeftUpCmd("-left", PlayerLeftUp, 0); ConCommand moveRightCmd("+right", PlayerRight, 0); ConCommand moveRightUpCmd("-right", PlayerRightUp, 0); DECLARE_ENTITY(player, CMOBAPlayer);