diff options
author | enneract <trem.redman@gmail.com> | 2014-11-24 02:20:51 +0100 |
---|---|---|
committer | enneract <trem.redman@gmail.com> | 2014-11-24 02:20:51 +0100 |
commit | b0a9981e09bbc7c30769f680a4e0ff17c9ea8239 (patch) | |
tree | d369ba2f0cebcf878ee32b420ec19a0786e9b4e8 | |
parent | f4413207a03658c719987d02fdbb87443843f43b (diff) |
Implement the Lightning Gun.
-rw-r--r-- | assets/gfx/lightning/beam.jpg | bin | 0 -> 6750 bytes | |||
-rw-r--r-- | assets/models/weapons/lightning/weapon.cfg | 14 | ||||
-rw-r--r-- | assets/scripts/hw_lightning.particle | 35 | ||||
-rw-r--r-- | assets/scripts/hw_lightning.shader | 9 | ||||
-rw-r--r-- | src/cgame/cg_local.h | 2 | ||||
-rw-r--r-- | src/cgame/cg_main.c | 3 | ||||
-rw-r--r-- | src/cgame/cg_weapons.c | 101 | ||||
-rw-r--r-- | src/game/bg_misc.c | 25 | ||||
-rw-r--r-- | src/game/bg_mod.h | 1 | ||||
-rw-r--r-- | src/game/bg_public.h | 1 | ||||
-rw-r--r-- | src/game/g_weapon.c | 49 | ||||
-rw-r--r-- | src/game/tremulous.h | 8 |
12 files changed, 244 insertions, 4 deletions
diff --git a/assets/gfx/lightning/beam.jpg b/assets/gfx/lightning/beam.jpg Binary files differnew file mode 100644 index 0000000..d3b2b30 --- /dev/null +++ b/assets/gfx/lightning/beam.jpg diff --git a/assets/models/weapons/lightning/weapon.cfg b/assets/models/weapons/lightning/weapon.cfg new file mode 100644 index 0000000..59133e2 --- /dev/null +++ b/assets/models/weapons/lightning/weapon.cfg @@ -0,0 +1,14 @@ +weaponModel models/weapons/lcannon/lcannon.md3 +icon icons/iconw_lucifer +crosshair 48 gfx/2d/crosshair-lcannon_s + +primary +{ + continuousFlash + + flashDlightColor 1.0 1.0 1.0 + + impactMark 8 gfx/marks/bullet_mrk + impactParticleSystem models/weapons/lightning/impactPS +} + diff --git a/assets/scripts/hw_lightning.particle b/assets/scripts/hw_lightning.particle new file mode 100644 index 0000000..afcba47 --- /dev/null +++ b/assets/scripts/hw_lightning.particle @@ -0,0 +1,35 @@ + +models/weapons/lightning/impactPS +{ + ejector + { + particle + { + shader sync gfx/psaw/blue_particle + + displacement 0 0 0 ~2.0 + + velocityType normal + velocityDir linear + velocityMagnitude 100 + velocity 0 0 -1 ~90 + + accelerationType static + accelerationDir linear + accelerationMagnitude 800 + acceleration 0 0 -1 ~10 + + radius 0 1.0~2.0 3.0~2.0 + alpha 0 1.0 1.0 + rotation 0 ~360 - + bounce 0.5 + + lifeTime 1000 + } + + count 3 + delay 0 + period 0 - ~0% + } +} + diff --git a/assets/scripts/hw_lightning.shader b/assets/scripts/hw_lightning.shader new file mode 100644 index 0000000..2fa0c0c --- /dev/null +++ b/assets/scripts/hw_lightning.shader @@ -0,0 +1,9 @@ +gfx/lightning/beam +{ + nomipmaps + { + map gfx/lightning/beam + blendFunc add + tcMod scroll -5 0 + } +} diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h index a477336..72b5a96 100644 --- a/src/cgame/cg_local.h +++ b/src/cgame/cg_local.h @@ -1336,6 +1336,8 @@ typedef struct qhandle_t headShotPS; qhandle_t humanWoundsBleedPS; qhandle_t alienWoundsBleedPS; + + qhandle_t lightningBeam; } cgMedia_t; typedef struct diff --git a/src/cgame/cg_main.c b/src/cgame/cg_main.c index b7885ec..9abdc7e 100644 --- a/src/cgame/cg_main.c +++ b/src/cgame/cg_main.c @@ -821,7 +821,8 @@ static void CG_RegisterGraphics( void ) cgs.media.healthCrossPoisoned = trap_R_RegisterShader( "ui/assets/neutral/cross_poison.tga" ); cgs.media.upgradeClassIconShader = trap_R_RegisterShader( "icons/icona_upgrade.tga" ); - + + cgs.media.lightningBeam = trap_R_RegisterShader( "gfx/lightning/beam" ); cgs.media.disconnectPS = CG_RegisterParticleSystem( "disconnectPS" ); diff --git a/src/cgame/cg_weapons.c b/src/cgame/cg_weapons.c index 04f6495..86306e1 100644 --- a/src/cgame/cg_weapons.c +++ b/src/cgame/cg_weapons.c @@ -866,6 +866,60 @@ static float CG_MachinegunSpinAngle( centity_t *cent, qboolean firing ) return angle; } +/* +============= +CG_RenderBeam +============= +*/ + +void CG_RenderGenericBeam( const vec3_t start, const vec3_t end, qhandle_t shader, float radius ) +{ + vec3_t delta, viewdelta, side; + float length; + polyVert_t quad[ 4 ]; + + VectorSubtract( end, start, delta ); + length = VectorLength( delta ); + VectorSubtract( start, cg.refdef.vieworg, viewdelta ); + CrossProduct( delta, viewdelta, side ); + VectorNormalize( side ); + + VectorMA( start, radius, side, quad[ 3 ].xyz ); + VectorMA( start, -radius, side, quad[ 2 ].xyz ); + VectorMA( end, -radius, side, quad[ 1 ].xyz ); + VectorMA( end, radius, side, quad[ 0 ].xyz ); + + quad[ 0 ].st[ 0 ] = length / radius * 0.1; + quad[ 0 ].st[ 1 ] = 0; + quad[ 0 ].modulate[ 0 ] = 255; + quad[ 0 ].modulate[ 1 ] = 255; + quad[ 0 ].modulate[ 2 ] = 255; + quad[ 0 ].modulate[ 3 ] = 255; + + quad[ 1 ].st[ 0 ] = length / radius * 0.1; + quad[ 1 ].st[ 1 ] = 1; + quad[ 1 ].modulate[ 0 ] = 255; + quad[ 1 ].modulate[ 1 ] = 255; + quad[ 1 ].modulate[ 2 ] = 255; + quad[ 1 ].modulate[ 3 ] = 255; + + quad[ 2 ].st[ 0 ] = 0; + quad[ 2 ].st[ 1 ] = 1; + quad[ 2 ].modulate[ 0 ] = 255; + quad[ 2 ].modulate[ 1 ] = 255; + quad[ 2 ].modulate[ 2 ] = 255; + quad[ 2 ].modulate[ 3 ] = 255; + + quad[ 3 ].st[ 0 ] = 0; + quad[ 3 ].st[ 1 ] = 0; + quad[ 3 ].modulate[ 0 ] = 255; + quad[ 3 ].modulate[ 1 ] = 255; + quad[ 3 ].modulate[ 2 ] = 255; + quad[ 3 ].modulate[ 3 ] = 255; + + trap_R_AddPolyToScene( shader, 4, quad ); +} + /* ============= @@ -876,6 +930,7 @@ The main player will have this called for BOTH cases, so effects like light and sound should only be done on the world model case. ============= */ + void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent ) { refEntity_t gun; @@ -1114,6 +1169,52 @@ void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent cent->muzzlePsTrigger = qfalse; } + if( weaponNum == WP_LIGHTNING_GUN ) + { + attachment_t attachment; + vec3_t muzzle, forward, end, beam_start; + trace_t tr; + + if( ps ) + { + BG_GetClientViewOrigin( ps, muzzle ); + AngleVectors( ps->viewangles, forward, NULL, NULL ); + } + else + { + // NOTE: this code assumes that the player's normal is (0,0,1) + // it will break when humans start walking on walls + class_t class = ( cent->currentState.misc >> 8 ) & 0xFF; + + VectorCopy( cent->lerpOrigin, muzzle ); + + // the only way to tell if a human is crouching is to check its bbox + // which is transmitted in a weird, encoded form (hence the magic number) + if( class == PCL_HUMAN && cent->currentState.solid == 3151887 ) + muzzle[ 2 ] += BG_ClassConfig( class )->crouchViewheight; + else + muzzle[ 2 ] += BG_ClassConfig( class )->viewheight; + + AngleVectors( cent->lerpAngles, forward, NULL, NULL ); + } + + VectorMA( muzzle, LIGHTNING_RANGE, forward, end ); + + CG_Trace( &tr, muzzle, NULL, NULL, end, cg.predictedPlayerState.clientNum, MASK_SHOT ); + + memset( &attachment, 0, sizeof( attachment ) ); + + if( noGunModel ) + CG_SetAttachmentTag( &attachment, *parent, parent->hModel, "tag_weapon" ); + else + CG_SetAttachmentTag( &attachment, gun, gun.hModel, "tag_flash" ); + + CG_AttachToTag( &attachment ); + + if( CG_AttachmentPoint( &attachment, beam_start ) ) + CG_RenderGenericBeam( beam_start, tr.endpos, cgs.media.lightningBeam, 3 ); + } + // make a dlight for the flash if( weapon->wim[ weaponMode ].flashDlightColor[ 0 ] || weapon->wim[ weaponMode ].flashDlightColor[ 1 ] || diff --git a/src/game/bg_misc.c b/src/game/bg_misc.c index 742363d..efdc300 100644 --- a/src/game/bg_misc.c +++ b/src/game/bg_misc.c @@ -3575,6 +3575,31 @@ static const weaponAttributes_t bg_weapons[ ] = TEAM_HUMANS //team_t team; }, { + WP_LIGHTNING_GUN, //int weaponNum; + LIGHTNING_PRICE, //int price; + STAGE_GE_5, //int stages + SLOT_WEAPON, //int slots; + "lightning", //char *weaponName; + "[yefarms]Lightning Gun", //char *humanName; + "This is a lightning gun. It guns lightning.", + LIGHTNING_AMMO, //int maxAmmo; + 0, //int maxClips; + qfalse, //int infiniteAmmo; + qtrue, //int usesEnergy; + LIGHTNING_REPEAT, //int repeatRate1; + 0, //int repeatRate2; + 0, //int repeatRate3; + 0, //int reloadTime; + LIGHTNING_K_SCALE, //float knockbackScale; + qfalse, //qboolean hasAltMode; + qfalse, //qboolean hasThirdMode; + qfalse, //qboolean canZoom; + 90.0f, //float zoomFov; + qtrue, //qboolean purchasable; + qtrue, //qboolean longRanged; + TEAM_HUMANS //team_t team; + }, + { WP_LUCIFER_CANNON, //int weaponNum; LCANNON_PRICE, //int price; STAGE_GE_5, //int stages diff --git a/src/game/bg_mod.h b/src/game/bg_mod.h index 4929b32..6f09037 100644 --- a/src/game/bg_mod.h +++ b/src/game/bg_mod.h @@ -8,6 +8,7 @@ MOD( MOD_CHAINGUN ), MOD( MOD_PRIFLE ), MOD( MOD_MDRIVER ), MOD( MOD_LASGUN ), +MOD( MOD_LIGHTNING ), MOD( MOD_LCANNON ), MOD( MOD_LCANNON_SPLASH ), MOD( MOD_FLAMER ), diff --git a/src/game/bg_public.h b/src/game/bg_public.h index c0b6381..18b0d2e 100644 --- a/src/game/bg_public.h +++ b/src/game/bg_public.h @@ -356,6 +356,7 @@ typedef enum WP_CHAINGUN, WP_FLAMER, WP_PULSE_RIFLE, + WP_LIGHTNING_GUN, WP_LUCIFER_CANNON, WP_ROCKET_LAUNCHER, WP_GRENADE, diff --git a/src/game/g_weapon.c b/src/game/g_weapon.c index d869fb1..1c333ab 100644 --- a/src/game/g_weapon.c +++ b/src/game/g_weapon.c @@ -819,9 +819,7 @@ void LCChargeFire( gentity_t *ent, qboolean secondary ) /* ====================================================================== - -PULSE RIFLE - +ROCKET LAUNCHER ====================================================================== */ @@ -830,6 +828,48 @@ void rocketLauncherFire( gentity_t *ent ) fire_rocket( ent, muzzle, forward ); } + +/* +====================================================================== +LIGHTNING GUN +====================================================================== +*/ + +void lightningGunFire( gentity_t *ent ) +{ + vec3_t start, end; + trace_t tr; + gentity_t *target; + + VectorMA( muzzle, LIGHTNING_RANGE, forward, end ); + + G_UnlaggedOn( ent, muzzle, LIGHTNING_RANGE ); + trap_Trace( &tr, muzzle, NULL, NULL, end, ent->s.number, MASK_SHOT ); + G_UnlaggedOff( ); + + if( tr.fraction == 1.0f || + tr.entityNum == ENTITYNUM_NONE || + ( tr.surfaceFlags & SURF_NOIMPACT ) ) + return; + + target = g_entities + tr.entityNum; + + if( target->s.eType == ET_PLAYER || target->s.eType == ET_BUILDABLE ) + BloodSpurt( ent, target, &tr ); + else + { + gentity_t *tent; + + tent = G_TempEntity( tr.endpos, EV_MISSILE_MISS ); + tent->s.eventParm = DirToByte( tr.plane.normal ); + tent->s.weapon = ent->s.weapon; + tent->s.generic1 = ent->s.generic1; + } + + G_Damage( target, ent, ent, forward, tr.endpos, LIGHTNING_DAMAGE, 0, MOD_LIGHTNING ); +} + + /* ====================================================================== TESLA GENERATOR @@ -1976,6 +2016,9 @@ void FireWeapon( gentity_t *ent ) case WP_ROCKET_LAUNCHER: rocketLauncherFire( ent ); break; + case WP_LIGHTNING_GUN: + lightningGunFire( ent ); + break; case WP_GRENADE: throwGrenade( ent ); break; diff --git a/src/game/tremulous.h b/src/game/tremulous.h index e7512d5..b42a7b4 100644 --- a/src/game/tremulous.h +++ b/src/game/tremulous.h @@ -514,6 +514,14 @@ TREMULOUS EDGE MOD SRC FILE #define PRIFLE_SECONDARY_SPEED 800 #define PRIFLE_SECONDARY_REPEAT 400 +#define LIGHTNING_PRICE 500 +#define LIGHTNING_AMMO 500 +#define LIGHTNING_K_SCALE 500 +#define LIGHTNING_DPS 100 // damage per second +#define LIGHTNING_REPEAT 50 // keep it as low as possible +#define LIGHTNING_DAMAGE ( LIGHTNING_DPS * LIGHTNING_REPEAT / 1000 ) +#define LIGHTNING_RANGE 450 + #define LCANNON_PRICE 600 #define LCANNON_AMMO 80 #define LCANNON_K_SCALE 1.0f |