mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-03-15 23:21:35 +00:00
213 lines
5 KiB
Text
213 lines
5 KiB
Text
/***********************************************************************
|
|
|
|
weapon_bfg.script
|
|
|
|
***********************************************************************/
|
|
|
|
#define BFG_MINRELEASETIME 0.05
|
|
#define BFG_FUSE 2.0
|
|
#define BFG_SHORTFUSE 0.5
|
|
#define BFG_MAXPOWER 4.0
|
|
#define BFG_FIRERATE 4
|
|
#define BFG_FIREDELAY 4
|
|
#define BFG_NUMPROJECTILES 1
|
|
|
|
// blend times
|
|
#define BFG_IDLE_TO_LOWER 4
|
|
#define BFG_IDLE_TO_FIRE 4
|
|
#define BFG_IDLE_TO_RELOAD 4
|
|
#define BFG_RAISE_TO_IDLE 4
|
|
#define BFG_FIRE_TO_IDLE 4
|
|
#define BFG_RELOAD_TO_IDLE 4
|
|
|
|
object weapon_bfg : weapon_base {
|
|
float spread;
|
|
float next_attack;
|
|
|
|
void init();
|
|
|
|
void Lower();
|
|
void Raise();
|
|
void Idle();
|
|
void Fire();
|
|
void Reload();
|
|
void OverCharge();
|
|
void ExitCinematic();
|
|
};
|
|
|
|
void weapon_bfg::init() {
|
|
next_attack = 0;
|
|
spread = getFloatKey( "spread" );
|
|
setGuiParm( "powerlevel", 0 );
|
|
setGuiParm( "overcharge", 0 );
|
|
weaponState( "Raise", 0 );
|
|
}
|
|
|
|
void weapon_bfg::Raise() {
|
|
weaponRising();
|
|
playAnim( ANIMCHANNEL_ALL, "raise" );
|
|
waitUntil( animDone( ANIMCHANNEL_ALL, BFG_RAISE_TO_IDLE ) );
|
|
weaponState( "Idle", BFG_RAISE_TO_IDLE );
|
|
}
|
|
|
|
void weapon_bfg::Lower() {
|
|
weaponLowering();
|
|
playAnim( ANIMCHANNEL_ALL, "putaway" );
|
|
waitUntil( animDone( ANIMCHANNEL_ALL, 0 ) );
|
|
weaponHolstered();
|
|
waitUntil( WEAPON_RAISEWEAPON );
|
|
weaponState( "Raise", 0 );
|
|
}
|
|
|
|
void weapon_bfg::Idle() {
|
|
float currentTime;
|
|
float ammoClip;
|
|
float avail;
|
|
float clip_size;
|
|
|
|
setColor( 0, 0, 0 );
|
|
clip_size = clipSize();
|
|
|
|
if ( !ammoInClip() ) {
|
|
playCycle( ANIMCHANNEL_ALL, "idle_empty" );
|
|
weaponOutOfAmmo();
|
|
} else {
|
|
playCycle( ANIMCHANNEL_ALL, "idle" );
|
|
weaponReady();
|
|
}
|
|
while( 1 ) {
|
|
if ( WEAPON_LOWERWEAPON ) {
|
|
weaponState( "Lower", BFG_IDLE_TO_LOWER );
|
|
}
|
|
currentTime = sys.getTime();
|
|
ammoClip = ammoInClip();
|
|
if ( ( currentTime >= next_attack ) && WEAPON_ATTACK ) {
|
|
if ( ammoClip > 0 ) {
|
|
weaponState( "Fire", BFG_IDLE_TO_FIRE );
|
|
} else if ( ammoAvailable() > 0 ) {
|
|
if ( autoReload() ) {
|
|
netReload();
|
|
weaponState( "Reload", BFG_IDLE_TO_RELOAD );
|
|
}
|
|
}
|
|
}
|
|
if ( WEAPON_RELOAD && ( ammoAvailable() > ammoClip ) && ( ammoClip < clip_size ) ) {
|
|
netReload();
|
|
weaponState( "Reload", BFG_IDLE_TO_RELOAD );
|
|
}
|
|
if ( WEAPON_NETRELOAD ) {
|
|
WEAPON_NETRELOAD = false;
|
|
weaponState( "Reload", BFG_IDLE_TO_RELOAD );
|
|
}
|
|
waitFrame();
|
|
}
|
|
}
|
|
|
|
void weapon_bfg::Fire() {
|
|
float fuse_start;
|
|
float fuse_end;
|
|
float current_time;
|
|
float time_held;
|
|
float power;
|
|
float powerLevel;
|
|
float intensity;
|
|
float fire_time;
|
|
|
|
playAnim( ANIMCHANNEL_ALL, "fire_begin" );
|
|
|
|
current_time = sys.getTime();
|
|
fuse_start = current_time;
|
|
fuse_end = current_time + BFG_FUSE;
|
|
while( current_time < fuse_end ) {
|
|
if ( ( current_time > BFG_MINRELEASETIME ) && !WEAPON_ATTACK ) {
|
|
break;
|
|
}
|
|
waitFrame();
|
|
current_time = sys.getTime();
|
|
powerLevel = ( current_time - fuse_start ) / BFG_FUSE;
|
|
setColor( powerLevel, powerLevel, powerLevel );
|
|
setGuiParm( "powerlevel", powerLevel );
|
|
}
|
|
|
|
if ( WEAPON_ATTACK ) {
|
|
current_time = sys.getTime();
|
|
fuse_end = current_time + BFG_SHORTFUSE;
|
|
while ( WEAPON_ATTACK && current_time < fuse_end ) {
|
|
waitFrame();
|
|
current_time = sys.getTime();
|
|
}
|
|
powerLevel = ( current_time - fuse_start ) / BFG_FUSE;
|
|
setGuiParm( "powerlevel", powerLevel );
|
|
}
|
|
|
|
if ( current_time >= fuse_end ) {
|
|
OverCharge();
|
|
} else {
|
|
time_held = current_time - fuse_start;
|
|
power = ( BFG_MAXPOWER * ( time_held / BFG_FUSE ) );
|
|
if ( power > BFG_MAXPOWER ) {
|
|
power = BFG_MAXPOWER;
|
|
}
|
|
playAnim( ANIMCHANNEL_ALL, "fire" );
|
|
fire_time = sys.getTime();
|
|
launchProjectiles( BFG_NUMPROJECTILES, spread, time_held, 1.0, power );
|
|
while( !animDone( ANIMCHANNEL_ALL, BFG_FIRE_TO_IDLE ) ) {
|
|
current_time = sys.getTime();
|
|
intensity = 1 - ( ( current_time - fire_time ) / 0.5 );
|
|
if ( intensity < 0 ) {
|
|
intensity = 0;
|
|
}
|
|
setColor( intensity, intensity, intensity );
|
|
waitFrame();
|
|
}
|
|
|
|
while ( powerLevel > 0 ) {
|
|
powerLevel -= 0.05;
|
|
setGuiParm( "powerlevel", powerLevel );
|
|
waitFrame();
|
|
}
|
|
}
|
|
|
|
setGuiParm( "powerlevel", 0 );
|
|
weaponState( "Idle", BFG_FIRE_TO_IDLE );
|
|
}
|
|
|
|
void weapon_bfg::Reload() {
|
|
weaponReloading();
|
|
playAnim( ANIMCHANNEL_ALL, "reload" );
|
|
waitUntil( animDone( ANIMCHANNEL_ALL, BFG_RELOAD_TO_IDLE ) );
|
|
addToClip( clipSize() );
|
|
weaponState( "Idle", BFG_RELOAD_TO_IDLE );
|
|
}
|
|
|
|
void weapon_bfg::OverCharge() {
|
|
string entname;
|
|
entity explosion;
|
|
vector forward;
|
|
vector angles;
|
|
entity owner;
|
|
|
|
owner = getOwner();
|
|
|
|
allowDrop( false );
|
|
useAmmo( clipSize() );
|
|
|
|
angles = owner.getViewAngles();
|
|
forward = sys.angToForward( angles );
|
|
|
|
entname = getKey( "def_overcharge" );
|
|
explosion = sys.spawn( entname );
|
|
explosion.setOrigin( getOrigin() + forward * 16 );
|
|
explosion.setShaderParm( SHADERPARM_TIMEOFFSET, -sys.getTime() );
|
|
delayRemove( explosion, 2 );
|
|
|
|
startSound( "snd_explode", SND_CHANNEL_ANY, false );
|
|
sys.radiusDamage( getOrigin(), self, owner, $null_entity, "damage_bfg_overcharge", 1.0 );
|
|
}
|
|
|
|
void weapon_bfg::ExitCinematic() {
|
|
next_attack = 0;
|
|
setColor( 0, 0, 0 );
|
|
setGuiParm( "powerlevel", 0 );
|
|
weaponState( "Idle", 0 );
|
|
}
|