Files
funnygame/game/server/milmoba/player.cpp
2025-07-13 15:47:42 +03:00

255 lines
6.1 KiB
C++

#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 Sync( 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();
}
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::Sync( void *pData, uint32_t nDataSize )
{
struct PlayerMovement_t: public PacketPlayer_t
{
bool bIsForward;
bool bIsBack;
bool bIsLeft;
bool bIsRight;
float fPitch;
float fYaw;
};
// Send data
if ( pData == NULL )
{
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;
}
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);