Source SDK

Source SDK

Not enough ratings
Laserweapon - Motor Source
By Oitnemood
una versión traducida de la guía de Speedlly (Scubic) aquí el enlace original
https://developer.valvesoftware.com/wiki/Laserweapon#How_to_make_a_Laser_Pistol.21
   
Award
Favorite
Favorited
Unfavorite
Como crear Pistola Laser!
Intro
Atención
Esto sustituirá a la pistola original en su mod. (si es que no sabe crear otro archivo aparte y adaptarlo)

Haremos cambios en cuatro archivos:
  • weapon_pistol.cpp - contiene el código que hace funcionar la pistola
  • hl2_gamerules.cpp - contiene el código que determina lo que hace el motor
  • weapon_pistol.txt - es el script del arma para la pistola
  • skill.cfg

weapon_pistola.cpp
Primero necesitamos añadir algunas directivas #include para acceder a las funciones y clases que necesitaremos para hacer un láser. El primer archivo que necesitamos es beam_shared.h, que contiene una gran cantidad de código relevante para el uso de los rayos. El otro archivo que necesitamos es ammodef.h.

Para incluir estos archivos, cambia la línea que dice #include "gamestats.h" por:
#include "gamestats.h" #include "beam_shared.h" /* Más adelante utilizaremos algunas de las funciones declaradas... */ #include "ammodef.h" /* Esto es necesario para el rastreo que se hace más tarde */ // This determines the sprite used by the laser beam #define PHYSCANNON_BEAM_SPRITE "sprites/orangelight1.vmt"

Nota: También añadimos #define PHYSCANNON_BEAM_SPRITE. Utilizamos esta macro siempre que queramos referirnos al sprite utilizado para dibujar el rayo láser. Más tarde, si queremos cambiar el sprite que se utiliza, todo lo que tenemos que hacer es cambiar "sprites/orangelight1.vmt" por otro.

Lo siguiente que tenemos que hacer es declarar dos funciones, DrawBeam y DoImpactEffect. DrawBeam dibujará un rayo láser para nosotros (una vez que lo definamos). DoImpactEffect es especial porque es llamado automáticamente por el motor del juego. Podemos definirlo para que haga algo por nosotros. La definiremos para crear una explosión eléctrica donde el láser impacte. Estas dos funciones serán definidas más adelante.

En public, debajo de DECLARE_SERVERCLASS(), añade lo siguiente:
void DrawBeam( const Vector &startPos, const Vector &endPos, float width ); void DoImpactEffect( trace_t &tr, int nDamageType );

A continuación, tenemos que añadir una variable. Siempre que añadamos una variable, debemos añadirla también a la sección DATADESC del arma. Esto permitirá que el contenido de la variable sea almacenado y cargado en las partidas guardadas, manteniendo los estados consistentes entre las sesiones de juego.

En private, debajo de DECLARE_ACTTABLE(), añade lo siguiente:
int m_nBulletType;

Entonces, debajo de BEGIN_DATADESC( CWeaponPistol ) añade:

DEFINE_FIELD( m_nBulletType, FIELD_INTEGER ),

El siguiente paso es cambiar la declaración de la función PrimaryAttack para que reciba más información del motor del juego sobre lo que ocurre cuando la pistola está atacando. Localiza lo siguiente:

void PrimaryAttack( void );

y cambiarlo por

void PrimaryAttack( trace_t &tr, int nDamageType, CBaseCombatCharacter *pOperator );

Para hacer: Encontrar una referencia que demuestre que esto funciona.


¿Recuerdas la variable que añadimos antes (m_nBulletType)? Como cualquier otra variable, debemos inicializarla en el constructor del arma. El código del constructor comienza así:
CWeaponPistol::CWeaponPistol( void ) { m_flSoonestPrimaryAttack = gpGlobals->curtime;

Para asegurarse de que esa variable se inicializa cuando se crea el arma, cambie lo anterior para que se vea así:

CWeaponPistol::CWeaponPistol( void ) { m_flSoonestPrimaryAttack = gpGlobals->curtime; m_nBulletType = -1;

La función PrimaryAttack es llamada cada vez que el arma ataca. Necesitamos cambiarla para que coincida con el cambio que hicimos anteriormente. También necesitamos añadir código para disparar un láser. Primero, localiza lo siguiente:

void CWeaponPistol::PrimaryAttack( void )

y cambiarlo por

void CWeaponPistol::PrimaryAttack( trace_t &tr, int nDamageType, CBaseCombatCharacter *pOperator )

A continuación, encuentra lo siguiente en la función PrimaryAttack:

m_iPrimaryAttacks++; gamestats->Event_WeaponFired( pOwner, true, GetClassname() );

y añadir el siguiente código debajo de él:

Vector vecShootOrigin, vecShootDir; vecShootOrigin = pOperator->Weapon_ShootPosition(); DrawBeam( vecShootOrigin, tr.endpos, 15.5 );

El código anterior llama a nuestra función DrawBeam (definida a continuación) con dos vectores y un float. El primer vector especifica dónde debe empezar el rayo, el segundo especifica dónde termina. El segundo vector proviene del parámetro tr de PrimaryAttack. Representa la ubicación de lo que estaba en la línea de fuego de la pistola. Así que DrawBeam dibujará un rayo láser desde el cañón hasta donde la pistola esté apuntando, con un ancho de rayo de 15.5.

Para hacer: Esta información es probablemente mejor dividida y distribuida a lo largo del tutorial.
Por último, tenemos que definir las funciones DrawBeam y DoImpactEffect.
//----------------------------------------------------------------------------- // Purpose: //comenzar el rayo // &endPos - dónde debe terminar el rayo // width - cuál debe ser el diámetro de la viga (¿unidades?) //----------------------------------------------------------------------------- void CWeaponPistol::DrawBeam( const Vector &startPos, const Vector &endPos, float width ) { //Trazador por el centro UTIL_Tracer( startPos, endPos, 0, TRACER_DONT_USE_ATTACHMENT, 6500, false, "GaussTracer" ); // Dibuja el eje de la viga principal CBeam *pBeam = CBeam::BeamCreate( PHYSCANNON_BEAM_SPRITE, 15.5 ); // Comienza en startPos pBeam->SetStartPos( startPos ); // Esto establece algunas cosas que el rayo utiliza para averiguar dónde // debe comenzar y terminar pBeam->PointEntInit( endPos, this ); // Esto hace que el láser parezca salir de la boca del cañón de la pistola pBeam->SetEndAttachment( LookupAttachment("Muzzle") ); pBeam->SetWidth( width ); // pBeam->SetEndWidth( 0.05f ); // Una mayor luminosidad significa menos transparencia pBeam->SetBrightness( 255 ); pBeam->SetColor( 255, 185+random->RandomInt( -16, 16 ), 40 ); pBeam->RelinkBeam(); // El rayo sólo debería existir durante un tiempo muy corto pBeam->LiveForTime( 0.1f ); } //----------------------------------------------------------------------------- // Propósito: // Entrada : &tr - se utiliza para averiguar dónde hacer el efecto // nDamageType - ??? //----------------------------------------------------------------------------- void CWeaponPistol::DoImpactEffect( trace_t &tr, int nDamageType ) { //Dibujar nuestro rayo DrawBeam( tr.startpos, tr.endpos, 15.5 ); if ( (tr.surface.flags & SURF_SKY) == false ) { CPVSFilter filter( tr.endpos ); te->GaussExplosion( filter, 0.0f, tr.endpos, tr.plane.normal, 0 ); m_nBulletType = GetAmmoDef()->Index("GaussEnergy"); UTIL_ImpactTrace( &tr, m_nBulletType ); } }

Por hacer: añadir más comentarios y/o explicar qué hace qué y por qué
hl2_gamerules.cpp
Ahora que hemos terminado de cambiar el código de la pistola, necesitamos cambiar algún código del motor para que la pistola láser funcione como se espera. Localiza lo siguiente:
def.AddAmmoType("Pistol", DMG_BULLET, TRACER_LINE_AND_WHIZ, "sk_plr_dmg_pistol", "sk_npc_dmg_pistol", "sk_max_pistol", BULLET_IMPULSE(200, 1225), 0 );

La línea mostrada arriba establece alguna información que el motor del juego utiliza para determinar cómo el disparo de la pistola afecta a lo que se está disparando. Cámbialo para que se parezca a lo siguiente:
def.AddAmmoType("Pistol", DMG_DISSOLVE, TRACER_NONE, "sk_plr_dmg_pistol", "sk_npc_dmg_pistol", "sk_max_pistol", BULLET_IMPULSE(200, 1225), 0 );

El cambio de DMG_BULLET a DMG_DISSOLVE cambia lo que sucede cuando un enemigo es asesinado por esta arma. En este caso, cuando se mata a un enemigo, se disuelve como si lo hubiera matado el fuego secundario del AR2. Cambiar TRACER_LINE_AND_WHIZ a TRACER_NONE hace que desaparezca el efecto trazador que se ve al disparar la pistola.
weapon_pistol.txt
Este archivo se encuentra en su carpeta de mods, bajo scripts.
La ruta de acceso a esta carpeta suele ser algo así como
C:\Archivos de Programa\Steam\Steamapps\Sourcemods\Su nombre de mod\Scripts

Ya casi hemos terminado con nuestra impresionante pistola láser. Sin embargo, si ejecutamos nuestro código ahora, no veríamos una "Pistola Láser" en nuestro menú de armas. En su lugar, seguiríamos viendo una "Pistola de 9mm" o algo así. Para arreglar esto, tenemos que cambiar una sola línea en el script del arma de la pistola.

Cambia lo siguiente:
"printname" "#HL2_Pistol"
a
"printname" "LASER_PISTOL"

Esto cambia el nombre del arma tal y como aparece en el HUD

Tip: Si sabes cómo, puedes cambiar el campo "SoundData" para que cuando dispares la pistola, suene como si disparara un láser.
skill.cfg
Este archivo se encuentra en su carpeta de mods, bajo cfg.
La ruta de acceso a esta carpeta suele ser algo así como
C:\Archivos de Programa\Steam\Steamapps\Sourcemod\Su nombre de mod\cfg

Tenemos que hacer una edición más. La pistola ya no dispara balas, dispara rayos láser. Esas pequeñas balas de 9mm probablemente deberían hacer menos daño que un láser. Por lo tanto, debemos cambiar la cantidad de daño que hace la pistola láser.

Cambia esto:
sk_plr_dmg_pistol "5" sk_npc_dmg_pistol "3" sk_max_pistol "148"
a esto:
sk_plr_dmg_pistol "20" sk_npc_dmg_pistol "15" sk_max_pistol "148"

Para hacer: ¿es sk_npc_dmg_pistola la cantidad de daño que hace la pistola a los PNJs o es la cantidad de daño que hacen los PNJs cuando usan la pistola?

Un mensaje del autor original
Espero que esto te ayude un poco
Speedlly (Scubic)
esta arma (o una parte de ella) va a jugar un papel en el juego que se hizo (Cubic Life)