Source SDK

Source SDK

Not enough ratings
Arreglar el estado de la animación del jugador (Motor Source - Un jugador)
By H-H-G-M
Nota: Este tutorial funciona en Source 2013 con algunos cambios menores detallados al final de esta página.

El objetivo principal de este tutorial es resolver los problemas e implementar un sistema de trabajo con el fin de permitir la comprobación de los parámetros de pose. El código Source de Valve Source Engine 2007 "Single Player" será necesario para este tutorial. La primera sección de este tutorial cubre la implementación de los archivos principales para habilitar el sistema de estado de animación del jugador. Varias partes del código fuente provienen de Valve, por lo que darles crédito no sería una mala idea.

guía oficial
https://developer.valvesoftware.com/wiki/Fixing_the_player_animation_state_(Single_Player)
   
Award
Favorite
Favorited
Unfavorite
Requisitos
Motor source de Valve (2007) para un solo jugador o source sdk master 2013 (funcional en pc actuales)
Herramientas de Nem ( GCFScape & VTFEdit )
Implementación del sistema de estado de animación.
En primer lugar debes crear dos archivos (.cpp / .h) que sean "compartidos" entre el Cliente y el Servidor. Abre las dos soluciones y añade dos archivos llamados 'singleplayer_animstate.cpp', 'singleplayer_animstate.h' Una vez completado este paso, abre 'singleplayer_animstate.h' y añade el siguiente código:

  • //========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
  • //
  • // Purpose: Single Player animation state 'handler'. This utility is used
  • // to evaluate the pose parameter value based on the direction
  • // and speed of the player.
  • //
  • //====================================================================================//

  • #ifndef SINGLEPLAYER_ANIMSTATE_H
  • #define SINGLEPLAYER_ANIMSTATE_H
  • #ifdef _WIN32
  • #pragma once
  • #endif

  • #include "cbase.h"

  • #ifdef CLIENT_DLL
  • #include "c_baseplayer.h"
  • #else
  • #include "player.h"
  • #endif

  • class CSinglePlayerAnimState
  • {
  • public:
  • enum
  • {
  • TURN_NONE = 0,
  • TURN_LEFT,
  • TURN_RIGHT
  • };

  • CSinglePlayerAnimState( CBasePlayer *pPlayer );

  • void Init( CBasePlayer *pPlayer );

  • Activity BodyYawTranslateActivity( Activity activity );

  • void Update();

  • const QAngle& GetRenderAngles();

  • void GetPoseParameters( CStudioHdr *pStudioHdr, float poseParameter[MAXSTUDIOPOSEPARAM] );

  • CBasePlayer *GetBasePlayer();

  • void Release();

  • private:
  • void GetOuterAbsVelocity( Vector& vel );

  • int ConvergeAngles( float goal,float maxrate, float dt, float& current );

  • void EstimateYaw( void );
  • void ComputePoseParam_BodyYaw( void );
  • void ComputePoseParam_BodyPitch( CStudioHdr *pStudioHdr );
  • void ComputePoseParam_BodyLookYaw( void );
  • void ComputePoseParam_HeadPitch( CStudioHdr *pStudioHdr );
  • void ComputePlaybackRate();

  • CBasePlayer *m_pPlayer;

  • float m_flGaitYaw;
  • float m_flStoredCycle;

  • float m_flGoalFeetYaw;
  • float m_flCurrentFeetYaw;

  • float m_flCurrentTorsoYaw;

  • float m_flLastYaw;
  • float m_flLastTurnTime;

  • int m_nTurningInPlace;

  • QAngle m_angRender;

  • float m_flTurnCorrectionTime;
  • };

  • CSinglePlayerAnimState *CreatePlayerAnimationState( CBasePlayer *pPlayer );

  • #endif // SINGLEPLAYER_ANIMSTATE_H
Una vez completado esto, abrirás 'singleplayer_animstate.cpp' y añadirás el siguiente código
https://pastebin.com/BnANK0yW

Después de completar esta sección, se le pedirá que llame a estas funciones para que estén activas. Deberás abrir 'hl2_player.h' y 'hl2_player.cpp' (ubicado en server\hl2)

En 'hl2_player.h', añade el siguiente código al principio

En la parte inferior, en la sección "private", añada estas dos líneas:

  • CSinglePlayerAnimState *m_pPlayerAnimState;
  • QAngle m_angEyeAngles;

Después de esto, abre 'hl2_player.cpp' y dirígete al constructor del jugador ( chl2_player::chl2_player() ) alrededor de la línea 391 y este trozo de código ponlo en su lugar:

  • CHL2_Player::CHL2_Player()
  • {
  • // Código originalmente escrito por Valve.
  • m_nNumMissPositions = 0;
  • m_pPlayerAISquad = 0;
  • m_bSprintEnabled = true;

  • m_flArmorReductionTime = 0.0f;
  • m_iArmorReductionFrom = 0;
  • }

Una vez completada esta tarea, dirígete a la función 'postthink' alrededor de la línea 909 y añade esta parte:

  • //m_angEyeAngles = EyeAngles();

  • QAngle angles = GetLocalAngles();
  • angles[PITCH] = 0;
  • SetLocalAngles( angles );

  • //m_pPlayerAnimState->Update();

Después de esto, proceda al destructor vacío "empty destructor" ( chl2_player::~chl2_player() ) alrededor de la línea 1394 y añada este código que ayudará a liberar la memoria del "Player Animation State" :

(no funciona por alguna razón da error, si sabes de c++ podrías comentar que tan revelante es esto, de momento no parece haber mucha falla en esto, ya lo estaré checando con el tiempo, lo demás sigue los pasos tal cual, ya estaré remarcando que no sirve o como solucionarlo)
  • CHL2_Player::~CHL2_Player()
  • {
  • // Borra el estado de la animación.
  • if ( m_pPlayerAnimState != NULL )
  • {
  • m_pPlayerAnimState->Release();
  • m_pPlayerAnimState = NULL;
  • }
  • }

El siguiente paso es realmente importante. Tendrás que ir a la solución de la carpeta "client" y abrir 'c_baseplayer.cpp'.

Encuentra una función alrededor de la línea 1280 llamada: void C_BasePlayer::AddEntity( void )

Al final de la función, bajo el fragmento de código:

  • // Añada efectos de iluminación
  • CreateLightEffect
s()

añade este código:

  • SetLocalAnglesDim(X_INDEX, 0 );

Esta línea evitará que el modelo del jugador rote cuando mire hacia arriba y dispare.

El sistema de "Estado de Animación del Jugador" está ahora configurado y todas las funciones serán llamadas correctamente de acuerdo a la dirección del jugador. Los requisitos que probablemente necesitarás ahora son un modelo de jugador que funcione y un código de animación en tercera persona.

Si ya posees dicho código entonces, creo que deberías estar bien y este tutorial terminará de esta manera. De lo contrario, puedes continuar con más profundidad y seguir algunas explicaciones más sobre cómo configurar un sistema de animación en tercera persona que funcione.
Secuencias de blending de jugadores y código de animación.
Para poder ver las técnicas de animación "Blending sequences", el modelo de jugador que lleves tendrá que tener animaciones que funcionen como se ve en este tutorial encontrado originalmente en la comunidad de desarrolladores de Valve: Developer.valvesoftware.com

Si no tienes animaciones válidas por el momento, hay algunas animaciones que están disponibles en el juego de Valve ( Half-Life 2: Deathmatch ). Si tienes este juego, necesitarás algunos programas: Las herramientas de Nem ( GCFScape & VTFEdit ) y el descompilador / compilador de CannonFodder.

Una vez que los tengas instalados, deberás descompilar un modelo humano de tu elección a partir de la ( Source Models ) 'extensión GCF'. Tan pronto como haya hecho eso, extraiga de ( Source Materials ) la textura de la cabeza de acuerdo con el modelo que ha elegido para descompilar. Estos materiales de la cabeza se pueden encontrar en torno a esta carpeta: materials/models/humans/gender/group/head texture.vtf. El material de la cabeza debe ser extraído a la ( carpeta de modificación ) ej: modification/materials/models/humans/gender/group/.

Una vez hecho esto, deberás extraer los
  • 'models/player/male_anims.mdl
' de ( Half-Life 2: Deathmatch ) 'GCF extension' y ponerlos en tu carpeta de modificación actual ) ex: mod/models/player/male_anims.mdl.

Abrirás la extensión de archivo '.qc' del modelo humano descompilado y te desplazarás por las líneas hasta que consigas llegar a unas cuantas descripciones anidadas de $includemodel como:

  • $includemodel "humans/male_shared.mdl"
  • $includemodel "humans/male_ss.mdl"
  • $includemodel "humans/male_gestures.mdl"
  • $includemodel "humans/male_postures.mdl"

Por encima de estas líneas, añade esta otra:

  • $includemodel "Player/male_anims.mdl"

Vuelve a compilar el modelo y abre la textura de la cabeza de tu nuevo modelo utilizando el VTFEdit de Nem y desmarca los siguientes parámetros en la casilla de la izquierda: 'Clamp S', 'Clamp T'.

Guarda el material y el nuevo modelo debería tener ahora todas las animaciones necesarias para soportar el movimiento en tercera persona con y sin armas.

Ha llegado el momento de escribir la nueva animación de la tercera persona. Necesitarás abrir 'hl2_player.h' y 'hl2_player.cpp'

En 'hl2_player.h', añade esta declaración en la sección 'public':

  • void SetAnimation( PLAYER_ANIM playerAnim );

Una vez hecho esto, en 'hl2_player.cpp', añade este código

  • //Establecer la actividad en función de
  • void CHL2_Player::SetAnimation( PLAYER_ANIM playerAnim )
  • {
  • int animDesired;

  • float speed;

  • speed = GetAbsVelocity().Length2D();

  • if ( GetFlags() & ( FL_FROZEN | FL_ATCONTROLS ) )
  • {
  • speed = 0;
  • playerAnim = PLAYER_IDLE;
  • }

  • Activity idealActivity = ACT_HL2MP_RUN;

  • if ( playerAnim == PLAYER_JUMP )
  • {
  • if ( HasWeapons() )
  • idealActivity = ACT_HL2MP_JUMP;
  • else
  • idealActivity = ACT_JUMP;
  • }
  • else if ( playerAnim == PLAYER_DIE )
  • {
  • if ( m_lifeState == LIFE_ALIVE )
  • {
  • return;
  • }
  • }
  • else if ( playerAnim == PLAYER_ATTACK1 )
  • {
  • if ( GetActivity( ) == ACT_HOVER ||
  • GetActivity( ) == ACT_SWIM ||
  • GetActivity( ) == ACT_HOP ||
  • GetActivity( ) == ACT_LEAP ||
  • GetActivity( ) == ACT_DIESIMPLE )
  • {
  • idealActivity = GetActivity( );
  • }
  • else
  • {
  • idealActivity = ACT_HL2MP_GESTURE_RANGE_ATTACK;
  • }
  • }
  • else if ( playerAnim == PLAYER_RELOAD )
  • {
  • idealActivity = ACT_HL2MP_GESTURE_RELOAD;
  • }
  • else if ( playerAnim == PLAYER_IDLE || playerAnim == PLAYER_WALK )
  • {
  • if ( !( GetFlags() & FL_ONGROUND ) && ( GetActivity( ) == ACT_HL2MP_JUMP || GetActivity( ) == ACT_JUMP ) ) // Still jumping
  • {
  • idealActivity = GetActivity( );
  • }
  • else if ( GetWaterLevel() > 1 )
  • {
  • if ( speed == 0 )
  • {
  • if ( HasWeapons() )
  • idealActivity = ACT_HL2MP_IDLE;
  • else
  • idealActivity = ACT_IDLE;
  • }
  • else
  • {
  • if ( HasWeapons() )
  • idealActivity = ACT_HL2MP_RUN;
  • else
  • idealActivity = ACT_RUN;
  • }
  • }
  • else
  • {
  • if ( GetFlags() & FL_DUCKING )
  • {
  • if ( speed > 0 )
  • {
  • if ( HasWeapons() )
  • idealActivity = ACT_HL2MP_WALK_CROUCH;
  • else
  • idealActivity = ACT_WALK_CROUCH;
  • }
  • else
  • {
  • if ( HasWeapons() )
  • idealActivity = ACT_HL2MP_IDLE_CROUCH;
  • else
  • idealActivity = ACT_COVER_LOW;
  • }
  • }
  • else
  • {
  • if ( speed > 0 )
  • {
  • {
  • if ( HasWeapons() )
  • idealActivity = ACT_HL2MP_RUN;
  • else
  • {
  • if ( speed > HL2_WALK_SPEED + 20.0f )
  • idealActivity = ACT_RUN;
  • else
  • idealActivity = ACT_WALK;
  • }
  • }
  • }
  • else
  • {
  • if ( HasWeapons() )
  • idealActivity = ACT_HL2MP_IDLE;
  • else
  • idealActivity = ACT_IDLE;
  • }
  • }
  • }

  • //idealActivity = TranslateTeamActivity( idealActivity );
  • }

  • if ( IsInAVehicle() )
  • {
  • idealActivity = ACT_COVER_LOW;
  • }

  • if ( idealActivity == ACT_HL2MP_GESTURE_RANGE_ATTACK )
  • {
  • RestartGesture( Weapon_TranslateActivity( idealActivity ) );

  • // FIXME: this seems a bit wacked
  • Weapon_SetActivity( Weapon_TranslateActivity( ACT_RANGE_ATTACK1 ), 0 );

  • return;
  • }
  • else if ( idealActivity == ACT_HL2MP_GESTURE_RELOAD )
  • {
  • RestartGesture( Weapon_TranslateActivity( idealActivity ) );
  • return;
  • }
  • else
  • {
  • SetActivity( idealActivity );

  • animDesired = SelectWeightedSequence( Weapon_TranslateActivity ( idealActivity ) );

  • if (animDesired == -1)
  • {
  • animDesired = SelectWeightedSequence( idealActivity );

  • if ( animDesired == -1 )
  • {
  • animDesired = 0;
  • }
  • }

  • // Already using the desired animation?
  • if ( GetSequence() == animDesired )
  • return;

  • m_flPlaybackRate = 1.0;
  • ResetSequence( animDesired );
  • SetCycle( 0 );
  • return;
  • }

  • // ¿Ya utiliza la animación deseada?
  • if ( GetSequence() == animDesired )
  • return;

  • //Msg( "Set animation to %d\n", animDesired );
  • // Reset to first frame of desired animation
  • ResetSequence( animDesired );
  • SetCycle( 0 );
  • }
Cambiar modelo del jugador
Para poder atribuir un modelo de jugador válido al jugador principal que no sea el que viene por defecto ("player.mdl"), tendrás que precargarlo y asignarlo.

En la parte superior de 'hl2_player.cpp', cerca del final de las macros de definición, alrededor de la línea 116, añade este código que definirá el modelo principal del jugador:
(para el que sigue la guia, estoy buscando que linea es esa para modificar que no parece estar actualizado en este parrafo)

  • #define PLAYER_MODEL "models/humans/group01/male_09.mdl"

El modelo entre las comillas puede ser sustituido por el carácter de su elección.

Tan pronto como termines de escribir esto, el modelo principal necesitará ser precacheado. Ve y encuentra una función alrededor de la línea 443 llamada: 'void CHL2_Player::Precache( void )'

Al final de esta función, añade este código de precache:
(al parecer falta una biblioteca para esto, que da error, así que mira el párrafo de abajo para corregirlo, que este comando no funciona así

  • PrecacheModel(PLAYER_MODEL);

Finalmente, necesitará asignar el modelo de jugador deseado en la función alrededor de la línea 1134 llamada 'void CHL2_Player::Spawn(void)'
(en source sdk 2013 master es linea 1126)

Encuentre la siguiente línea:

  • SetModel( "models/player.mdl" );

Sustitúyelo por:

SetModel( PLAYER_MODEL );

El personaje debería ser capaz de reproducir todas las animaciones correctas cuando no lleva armas, pero si el jugador está obligado a llevar armas, como la lista de actividades de todas las armas no está completada, el jugador probablemente entrará en un estado de animación "Ragdoll". Para corregir este error, deberás abrir todos los archivos de armas y añadir o completar la lista de actividad principal "activity list."


Cuadros de la lista de actividades de las armas (p1)
En weapon_357.cpp:

En la descripción de la clase, bajo la macro "DECLARE_DATADESC()", añade esta línea

  • DECLARE_ACTTABLE();

Bajo la definición de la clase, alrededor de la línea 50, añade esta lista de tablas de actividad

  • acttable_t CWeapon357::m_acttable[] =
  • {
  • { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_PISTOL, false },
  • { ACT_HL2MP_RUN, ACT_HL2MP_RUN_PISTOL, false },
  • { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_PISTOL, false },
  • { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_PISTOL, false },
  • { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_PISTOL, false },
  • { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_PISTOL, false },
  • { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_PISTOL, false },
  • { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_PISTOL, false },
  • };

IMPLEMENT_ACTTABLE( CWeapon357 );

En weapon_ar2.cpp:

Ya existe una lista de actividades. A su pie, después de // { ACT_RANGE_ATTACK2, ACT_RANGE_ATTACK_AR2_GRENADE, true },

añade la siguiente lista:

{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_AR2, false },
{ ACT_HL2MP_RUN, ACT_HL2MP_RUN_AR2, false },
{ ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_AR2, false },
{ ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_AR2, false },
{ ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_AR2, false },
{ ACT_HL2MP_GESTURE_RELOAD, ACT_GESTURE_RELOAD_SMG1, false },
{ ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_AR2, false },
{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_AR2, false },

En la descripción de la clase, alrededor de la línea 450, bajo la macro "DECLARE_DATADESC()", añadir esta línea

DECLARE_ACTTABLE();
En la definición de la clase, alrededor de la línea 489, añada esta lista de tablas de actividad

  • acttable_t CWeaponCrossbow::m_acttable[] =
  • {
  • { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_CROSSBOW, false },
  • { ACT_HL2MP_RUN, ACT_HL2MP_RUN_CROSSBOW, false },
  • { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_CROSSBOW, false },
  • { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_CROSSBOW, false },
  • { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_CROSSBOW, false },
  • { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_CROSSBOW, false },
  • { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_CROSSBOW, false },
  • { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SHOTGUN, false },
  • };

  • IMPLEMENT_ACTTABLE( CWeaponCrossbow );

En weapon_crowbar.cpp:

Ya hay una lista de actividades. A su pie, después de { ACT_IDLE_ANGRY, ACT_IDLE_ANGRY_MELEE, false },

añade la siguiente lista:

  • { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SLAM, true },
  • { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_MELEE, false },
  • { ACT_HL2MP_RUN, ACT_HL2MP_RUN_MELEE, false },
  • { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_MELEE, false },
  • { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_MELEE, false },
  • { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE, false },
  • { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_MELEE, false },
  • { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_MELEE, false },

  • Ya hay una lista de actividades. Al pie de la misma, después de { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SLAM, true },

añada la siguiente lista bajo { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SLAM (línea 85)

  • { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_GRENADE, false },
  • { ACT_HL2MP_RUN, ACT_HL2MP_RUN_GRENADE, false },
  • { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_GRENADE, false },
  • { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_GRENADE, false },
  • { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_GRENADE, false },
  • { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_GRENADE, false },
  • { ACT_HL2MP_JUMP,

In weapon_physcannon.cpp:

En la descripción de la clase, alrededor de la línea 1203, bajo la macro "DECLARE_DATADESC()", añada esta línea:

DECLARE_ACTTABLE();
Under the class definition around line 1374, add this activity table list:

  • acttable_t CWeaponPhysCannon::m_acttable[] =
  • {
  • { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_PHYSGUN, false },
  • { ACT_HL2MP_RUN, ACT_HL2MP_RUN_PHYSGUN, false },
  • { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_PHYSGUN, false },
  • { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_PHYSGUN, false },
  • { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_PHYSGUN, false },
  • { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_PHYSGUN, false },
  • { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_PHYSGUN, false },
  • { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SLAM, false },
  • };

  • IMPLEMENT_ACTTABLE(CWeaponPhysCannon);

In weapon_pistol.cpp:

Ya existe una lista de actividades. A su pie, después de { ACT_RUN, ACT_RUN_PISTOL, false },

añada la siguiente lista:

  • { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_PISTOL, false },
  • { ACT_HL2MP_RUN, ACT_HL2MP_RUN_PISTOL, false },
  • { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_PISTOL, false },
  • { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_PISTOL, false },
  • { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_PISTOL, false },
  • { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_PISTOL, false },
  • { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_PISTOL, false },
  • { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_PISTOL, false },

In weapon_rpg.cpp:

Ya existe una lista de actividades. A su pie, después de { ACT_COVER_LOW, ACT_COVER_LOW_RPG, true },

añada la siguiente lista:

  • { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_RPG, false },
  • { ACT_HL2MP_RUN, ACT_HL2MP_RUN_RPG, false },
  • { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_RPG, false },
  • { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_RPG, false },
  • { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_RPG, false },
  • { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_RPG, false },
  • { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_RPG, false },
  • { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_RPG, false },
Cuadros de la lista de actividades de las armas (p2)
En weapon_shotgun.cpp:

Ya hay una lista de actividades. A su pie, después de { ACT_GESTURE_RELOAD, ACT_GESTURE_RELOAD_SHOTGUN, false },

añade la siguiente lista:
{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_SHOTGUN, false }, { ACT_HL2MP_RUN, ACT_HL2MP_RUN_SHOTGUN, false }, { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_SHOTGUN, false }, { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_SHOTGUN, false }, { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_SHOTGUN, false }, { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_SHOTGUN, false }, { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_SHOTGUN, false }, { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SHOTGUN, false },
En weapon_smg1.cpp:

Ya existe una lista de actividades. A su pie, después de { ACT_GESTURE_RELOAD, ACT_GESTURE_RELOAD_SMG1, true },

añade la siguiente lista:
{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_SMG1, false }, { ACT_HL2MP_RUN, ACT_HL2MP_RUN_SMG1, false }, { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_SMG1, false }, { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_SMG1, false }, { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_SMG1, false }, { ACT_HL2MP_GESTURE_RELOAD, ACT_GESTURE_RELOAD_SMG1, false }, { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_SMG1, false }, { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SMG1, false },
descargar modelos de armas con fallas en tercera persona corregidos
cópialo en tu navegador y quita los espacios
https ://www. mediafire .com/file/4fgvl4emcbuarqt/arregrar+posicion+de+armas+en+la+mano+hl2 .zip/file
(ponlo en la carpeta de models)
Arreglo de la secuencia de ataque de las armas.
Las listas de animación de las armas deberían estar completadas por el momento, pero quedan bastantes problemas ya que falta la llamada a la "secuencia de animación" del jugador en varias partes del código del arma. Incluso si la ( Half-Life 2 ) palanca tiene ahora animaciones válidas, el jugador no jugará la secuencia de ataque ya que esta secuencia no se llama. Para arreglarlo, dirígete a 'basebludgeonweapon.cpp' en la solución del servidor "server" y encuentra la última función llamada: 'void CBaseHLBludgeonWeapon::Swing( int bIsSecondary )'.

Al final de esta función, en

  • //Play swing sound

  • WeaponSound( SINGLE );

añadir estos assets de código:

  • // Envía la animación de "ataque" del jugador.
  • pOwner->SetAnimation(PLAYER_ATTACK1);

Hay algunas otras armas que tienen deficiencia hacia el estado de animación. Abre 'weapon_frag.cpp' y encuentra una función alrededor de la línea 409 llamada: 'void CWeaponFrag::ThrowGrenade( CBasePlayer *pPlayer )'

Después del fragmento de código:

  • WeaponSound( SINGLE );

añadir estos assets de código:

// Envía la animación de "attack" del jugador.
pPlayer->SetAnimation(PLAYER_ATTACK1);

En 'weapon_frag.cpp' hay otras funciones llamadas: 'void CWeaponFrag::LobGrenade( CBasePlayer *pPlayer )' & 'void CWeaponFrag::RollGrenade( CBasePlayer *pPlayer )'

En estos, bajo el fragmento de código:

  • WeaponSound( Parameter );

volver a hacer lo mismo para ellos añadiendo:

// Envía la animación de "'attack' del jugador.
pPlayer->SetAnimation(PLAYER_ATTACK1);

El último archivo a explorar es 'weapon_shotgun.cpp'. Aunque esto no es realmente un problema molesto, pero podría ser útil en el caso de que no desee tener la ( Half-Life 2 ) velocidad de disparo de la escopeta demasiado rápido.

en weapon_shotgun.cpp:

Proceda a la función alrededor de la línea 457 llamada: 'void CWeaponShotgun::PrimaryAttack( void )'

encontrar la siguiente línea:

  • // No disparar de nuevo hasta que la animación de fuego se haya completado
  • m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration()
;
reemplazar este con:

  • // No disparar de nuevo hasta que la animación de fuego se haya completado
  • m_flNextPrimaryAttack = gpGlobals->curtime + GetViewModelSequenceDuration();

Proceda a la función alrededor de la línea 514 llamada: 'void CWeaponShotgun::SecondaryAttack( void )'

encontrar la siguiente línea:

  • // No disparar de nuevo hasta que la animación de fuego se haya completado
  • m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration();

reemplazar este con:

// No disparar de nuevo hasta que la animación de fuego se haya completado
m_flNextPrimaryAttack = gpGlobals->curtime + GetViewModelSequenceDuration();

La tasa de fuego principal de la escopeta ( Half-Life 2 ) debe ser arreglada.

Normalmente, este tutorial terminaría aquí, pero hay otra adición que podrías ver si quieres echarle un vistazo a continuación. Consiste en crear una vista de muerte en "tercera persona" cuando el jugador está en tercera persona y ya no está vivo.
Cámara de vista de la muerte en tercera persona.
En c_baseplayer.h:

En la clase 'C_Baseplayer', encuentra unas cuantas funciones de cálculo de cámaras alrededor de la línea 408 y debajo de éstas, añade la siguiente declaración:

  • virtual void CalcThirdPersonDeathView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov );

Una vez completada esta tarea, podrás abrir el archivo 'c_baseplayer.cpp' y añadir este código:

https://pastebin.com/93E7mjmj

Después de esto, se requerirá que esta función sea llamada y evaluada tan pronto como el jugador deje de estar vivo.

En 'baseplayer_shared.cpp' tendrás que añadir

  • #ifdef CLIENT_DLL
  • #include "input.h"
  • #endif

en la parte superior del nido de definiciones "#include".

Encuentra una función alrededor de la línea 1443 llamada: void CBasePlayer::CalcView( Vector &eyeOrigin, QAngle &eyeAngles, float &zNear, float &zFar, float &fov )

encuentra el bloque de control principal:

  • if ( IsObserver() )
  • {
  • CalcObserverView( eyeOrigin, eyeAngles, fov );
  • }

Debajo de este bloque de declaración, pon este fragmento:

  • #ifdef CLIENT_DLL
  • else if ( !this->IsAlive() && ::input->CAM_IsThirdPerson() )
  • {
  • CalcThirdPersonDeathView( eyeOrigin, eyeAngles, fov );
  • }
  • #endif

Cuando la vida del jugador sea igual a 0, esta función será llamada y creará una copia del modelo principal del jugador como ragdoll. Entonces, la posición del ragdoll será evaluada y el desplazamiento de la vista seguirá a este ragdoll.
(mensaje del autor original)
Todavía hay algunos problemas con los accesorios de tercera persona en las armas que todavía estoy tratando de resolver y esto probablemente será arreglado en el ínterin.

Espero sinceramente que esto ayude a la gente que está dispuesta a implementar sistemas válidos de "Tercera Persona" en nuevas ( modificaciones ) bases en el premiado motor Source de Valve.
Source 2013 Arreglos
Cuando se compila el código principal (antes de ajustar nada a las tablas de armas, la cámara de muerte en tercera persona, etc) sin cambios en la compilación de 2013 de Source, suele producirse el error C3861 en el proceso de compilación debido a un enlace de definición mal gestionado dentro de singleplayer_animstate.cpp para "MDLCACHE_CRITICAL_SECTION()". Para solucionarlo, añade esta línea "include" en singleplayer_animstate.h:

  • #include "..\public\datacache\imdlcache.h"

Además, el motor se bloqueará al cargar el mapa si PLAYER_MODEL no está correctamente precacheado. Encuentre la función PrecacheScriptSound( "HL2Player.BurnPain" ); dentro de hl2_player.cpp y añada este código en la linea 444 debajo de los otros precaches:


PrecacheModel(PLAYER_MODEL); //necesita ser precached o de lo contrario el motor se estrellará! (metodo actualizado
si no funciona esto para ciertos de tus personajes
pon esto, con el nombre de tu modelo.
CBaseEntity::PrecacheModel ( "models/player/nombre.mdl" );

Con esto concluyen las correcciones necesarias para que el código funcione en Source 2013.
(actualizado para arreglar las fallas al compilar)