mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-05-30 00:11:14 +00:00
267 lines
5.8 KiB
Text
267 lines
5.8 KiB
Text
/***********************************************************************
|
|
|
|
weapon_handgrenade.script
|
|
|
|
***********************************************************************/
|
|
|
|
#define HANDGRENADE_MINRELEASETIME 0.05
|
|
#define HANDGRENADE_FUSE 3
|
|
#define HANDGRENADE_QUICKTHROWTIME .2
|
|
#define HANDGRENADE_MINPOWER 1.5
|
|
#define HANDGRENADE_MAXPOWER 6
|
|
#define HANDGRENADE_QUICKTHROWLAUNCH 0.55
|
|
#define HANDGRENADE_NORMALTHROWLAUNCH 0.3
|
|
#define HANDGRENADE_NUMPROJECTILES 1
|
|
|
|
// blend times
|
|
#define HANDGRENADE_IDLE_TO_LOWER 4
|
|
#define HANDGRENADE_IDLE_TO_FIRE 4
|
|
#define HANDGRENADE_RAISE_TO_IDLE 4
|
|
#define HANDGRENADE_FIRE_TO_IDLE 4
|
|
|
|
object weapon_handgrenade : weapon_base {
|
|
float spread;
|
|
float fuse_start;
|
|
string skin_nade;
|
|
string skin_nade_invis;
|
|
string skin_nonade;
|
|
string skin_nonade_invis;
|
|
entity projectile;
|
|
|
|
boolean show_grenade;
|
|
|
|
void init();
|
|
|
|
void Lower();
|
|
void Raise();
|
|
void Idle();
|
|
void Fire();
|
|
void EnterCinematic();
|
|
void ExitCinematic();
|
|
void WeaponStolen();
|
|
void OwnerDied();
|
|
void ExplodeInHand();
|
|
|
|
// called by the game
|
|
void UpdateSkin();
|
|
|
|
// used by anim frame commands
|
|
void GrenadeNade();
|
|
void GrenadeNoNade();
|
|
};
|
|
|
|
void weapon_handgrenade::init() {
|
|
spread = getFloatKey( "spread" );
|
|
skin_nade = getKey( "skin_nade" );
|
|
skin_nade_invis = getKey( "skin_nade_invis" );
|
|
skin_nonade = getKey( "skin_nonade" );
|
|
skin_nonade_invis = getKey( "skin_nonade_invis" );
|
|
|
|
GrenadeNade();
|
|
|
|
weaponState( "Raise", 0 );
|
|
}
|
|
|
|
void weapon_handgrenade::Raise() {
|
|
if ( !ammoAvailable() ) {
|
|
weaponHolstered();
|
|
nextWeapon();
|
|
return;
|
|
}
|
|
|
|
weaponRising();
|
|
playAnim( ANIMCHANNEL_ALL, "raise" );
|
|
waitUntil( animDone( ANIMCHANNEL_ALL, HANDGRENADE_RAISE_TO_IDLE ) );
|
|
weaponState( "Idle", HANDGRENADE_RAISE_TO_IDLE );
|
|
}
|
|
|
|
void weapon_handgrenade::Lower() {
|
|
weaponLowering();
|
|
playAnim( ANIMCHANNEL_ALL, "putaway" );
|
|
waitUntil( animDone( ANIMCHANNEL_ALL, 0 ) );
|
|
weaponHolstered();
|
|
waitUntil( WEAPON_RAISEWEAPON );
|
|
weaponState( "Raise", 0 );
|
|
}
|
|
|
|
void weapon_handgrenade::Idle() {
|
|
weaponReady();
|
|
playCycle( ANIMCHANNEL_ALL, "idle" );
|
|
while( 1 ) {
|
|
if ( WEAPON_LOWERWEAPON ) {
|
|
weaponState( "Lower", HANDGRENADE_IDLE_TO_LOWER );
|
|
}
|
|
if ( WEAPON_ATTACK ) {
|
|
weaponState( "Fire", HANDGRENADE_IDLE_TO_FIRE );
|
|
}
|
|
waitFrame();
|
|
}
|
|
}
|
|
|
|
void weapon_handgrenade::Fire() {
|
|
float fuse_end;
|
|
float current_time;
|
|
float time_held;
|
|
float power;
|
|
boolean exploded;
|
|
|
|
projectile = createProjectile();
|
|
|
|
if ( projectile ) {
|
|
projectile.startSound( "snd_throw", SND_CHANNEL_BODY, true );
|
|
}
|
|
|
|
playAnim( ANIMCHANNEL_ALL, "throw_start" );
|
|
|
|
current_time = sys.getTime();
|
|
fuse_start = current_time;
|
|
fuse_end = current_time + HANDGRENADE_FUSE;
|
|
while( current_time < fuse_end ) {
|
|
if ( ( current_time > fuse_start + HANDGRENADE_MINRELEASETIME ) && !WEAPON_ATTACK ) {
|
|
break;
|
|
}
|
|
waitFrame();
|
|
current_time = sys.getTime();
|
|
}
|
|
|
|
time_held = current_time - fuse_start;
|
|
power = time_held + HANDGRENADE_MINPOWER;
|
|
if ( power > HANDGRENADE_MAXPOWER ) {
|
|
power = HANDGRENADE_MAXPOWER;
|
|
}
|
|
|
|
if ( time_held < HANDGRENADE_QUICKTHROWTIME ) {
|
|
playAnim( ANIMCHANNEL_ALL, "throw_quick" );
|
|
sys.wait( HANDGRENADE_QUICKTHROWLAUNCH );
|
|
exploded = false;
|
|
} else if ( time_held < HANDGRENADE_FUSE ) {
|
|
playAnim( ANIMCHANNEL_ALL, "throw" );
|
|
sys.wait( HANDGRENADE_NORMALTHROWLAUNCH );
|
|
exploded = false;
|
|
} else {
|
|
// no anim. grenade just blows up
|
|
ExplodeInHand();
|
|
exploded = true;
|
|
}
|
|
|
|
if ( !exploded ) {
|
|
GrenadeNoNade();
|
|
current_time = sys.getTime();
|
|
if ( projectile ) {
|
|
projectile.show();
|
|
projectile.unbind();
|
|
launchProjectiles( HANDGRENADE_NUMPROJECTILES, spread, current_time - fuse_start, power, 1.0 );
|
|
projectile = $null_entity;
|
|
}
|
|
|
|
waitUntil( animDone( ANIMCHANNEL_ALL, HANDGRENADE_FIRE_TO_IDLE ) );
|
|
}
|
|
|
|
if ( !ammoAvailable() ) {
|
|
weaponHolstered();
|
|
nextWeapon();
|
|
} else {
|
|
GrenadeNade();
|
|
weaponState( "Idle", HANDGRENADE_FIRE_TO_IDLE );
|
|
}
|
|
}
|
|
|
|
void weapon_handgrenade::EnterCinematic() {
|
|
if ( projectile ) {
|
|
projectile.remove();
|
|
projectile = $null_entity;
|
|
}
|
|
weaponState( "Idle", 0 );
|
|
}
|
|
|
|
void weapon_handgrenade::ExitCinematic() {
|
|
if ( !ammoAvailable() ) {
|
|
weaponHolstered();
|
|
nextWeapon();
|
|
} else {
|
|
GrenadeNade();
|
|
weaponState( "Idle", 0 );
|
|
}
|
|
}
|
|
|
|
void weapon_handgrenade::GrenadeNade() {
|
|
show_grenade = true;
|
|
UpdateSkin();
|
|
}
|
|
|
|
void weapon_handgrenade::GrenadeNoNade() {
|
|
show_grenade = false;
|
|
UpdateSkin();
|
|
}
|
|
|
|
void weapon_handgrenade::UpdateSkin() {
|
|
if ( !show_grenade ) {
|
|
if ( isInvisible() ) {
|
|
setSkin( skin_nonade_invis );
|
|
} else {
|
|
setSkin( skin_nonade );
|
|
}
|
|
} else {
|
|
if ( isInvisible() ) {
|
|
setSkin( skin_nade_invis );
|
|
} else {
|
|
setSkin( skin_nade );
|
|
}
|
|
}
|
|
}
|
|
|
|
void weapon_handgrenade::WeaponStolen() {
|
|
if ( projectile ) {
|
|
projectile.remove();
|
|
projectile = $null_entity;
|
|
}
|
|
}
|
|
|
|
void weapon_handgrenade::OwnerDied() {
|
|
float time_held;
|
|
|
|
if ( projectile ) {
|
|
time_held = sys.getTime() - fuse_start;
|
|
projectile.show();
|
|
projectile.unbind();
|
|
|
|
// allow grenade to drop
|
|
launchProjectiles( HANDGRENADE_NUMPROJECTILES, spread, time_held, 0, 1.0 );
|
|
|
|
projectile = $null_entity;
|
|
}
|
|
}
|
|
|
|
void weapon_handgrenade::ExplodeInHand() {
|
|
string entname;
|
|
entity explosion;
|
|
vector forward;
|
|
vector angles;
|
|
entity owner;
|
|
|
|
if ( projectile ) {
|
|
projectile.remove();
|
|
projectile = $null_entity;
|
|
}
|
|
|
|
owner = getOwner();
|
|
|
|
GrenadeNoNade();
|
|
startSound( "snd_explode", SND_CHANNEL_ANY, false );
|
|
|
|
if ( !sys.isClient() ) {
|
|
useAmmo( HANDGRENADE_NUMPROJECTILES );
|
|
|
|
angles = owner.getViewAngles();
|
|
forward = sys.angToForward( angles );
|
|
|
|
entname = getKey( "def_explode_inhand" );
|
|
explosion = sys.spawn( entname );
|
|
explosion.setOrigin( getOrigin() + forward * 16 );
|
|
explosion.setShaderParm( SHADERPARM_TIMEOFFSET, -sys.getTime() );
|
|
delayRemove( explosion, 2 );
|
|
|
|
// this should kill us
|
|
sys.radiusDamage( getOrigin(), self, owner, $null_entity, getKey( "def_damage_inhand" ), 1.0 );
|
|
}
|
|
}
|