📄 spidermine.cpp
字号:
edict->owner = owner->edict;
setModel( "spidermine.def" );
showModel();
setMoveType( MOVETYPE_SLIDE );
setSolidType( SOLID_BBOX );
edict->clipmask = MASK_PROJECTILE;
RandomAnimate( "open", EV_Mine_Run );
SetGravityAxis( owner->gravaxis );
velocity = dir * 600;
sticky = false;
const gravityaxis_t &grav = gravity_axis[ gravaxis ];
setAngles( Vector( 0, dir.toYaw(), 0 ) );
angles.AngleVectors( &t[0], &t[1], &t[2] );
forward[ grav.x ] = t[ 0 ][ 0 ];
forward[ grav.y ] = t[ 0 ][ 1 ] * grav.sign;
forward[ grav.z ] = t[ 0 ][ 2 ] * grav.sign;
right[ grav.x ] = t[ 1 ][ 0 ];
right[ grav.y ] = t[ 1 ][ 1 ] * grav.sign;
right[ grav.z ] = t[ 1 ][ 2 ] * grav.sign;
up[ grav.x ] = t[ 2 ][ 0 ];
up[ grav.y ] = t[ 2 ][ 1 ] * grav.sign;
up[ grav.z ] = t[ 2 ][ 2 ] * grav.sign;
VectorsToEulerAngles( forward.vec3(), right.vec3(), up.vec3(), angles.vec3() );
setAngles( angles );
ev = new Event( EV_Mine_Explode );
ev->AddEntity( world );
PostEvent( ev, 180 );
takedamage = DAMAGE_YES;
health = 150;
edict->svflags |= ( SVF_SHOOTABLE );
setSize("-4 -4 -4", "4 4 4");
setOrigin( pos );
worldorigin.copyTo(edict->s.old_origin);
detonate = false;
fov = 120;
if ( owner->isClient() && owner->client->ps.pmove.pm_flags & PMF_DUCKED )
{
setMoveType( MOVETYPE_TOSS );
sticky = true;
}
}
CLASS_DECLARATION( Weapon, SpiderMine, NULL);
ResponseDef SpiderMine::Responses[] =
{
{ &EV_Weapon_Shoot, ( Response )SpiderMine::Shoot },
{ &EV_Weapon_DoneFiring, ( Response )SpiderMine::DoneFiring },
{ &EV_Weapon_SecondaryUse, ( Response )SpiderMine::ChangeToDetonator },
{ NULL, NULL }
};
SpiderMine::SpiderMine
(
)
{
#ifdef SIN_DEMO
PostEvent( EV_Remove, 0 );
return;
#endif
SetModels( "mines.def", "view_mines.def" );
SetAmmo( "SpiderMines", 1, 0 );
SetRank( 60, 5 );
SetType( WEAPON_1HANDED );
modelIndex( "spidermine.def" );
modelIndex( "mine.def" );
currentMine = 0;
}
qboolean SpiderMine::IsDroppable
(
void
)
{
return false;
}
void SpiderMine::SetOwner
(
Sentient *sent
)
{
Detonator *detonator;
int num;
assert( sent );
if ( !sent )
{
// return to avoid any buggy behaviour
return;
}
Item::SetOwner( sent );
setOrigin( vec_zero );
setAngles( vec_zero );
if ( !viewmodel.length() )
{
error( "setOwner", "Weapon without viewmodel set" );
}
setModel( viewmodel );
// Give the owner a detonator and setup the link
detonator = ( Detonator * )sent->FindItem( "Detonator" );
if ( !detonator )
{
detonator = ( Detonator * )sent->giveWeapon( "Detonator" );
}
SetDetonator( detonator );
// Check the world for any spidermines in existence and
// if the player owns them, add them to the minelist.
num = 0;
while( ( num = G_FindClass( num, "Mine" ) ) != NULL )
{
Mine *mine = ( Mine * )G_GetEntity( num );
if ( mine->IsOwner( sent ) )
{
detonator->AddMine( mine );
mine->SetDetonator( detonator );
}
}
}
void SpiderMine::DoneFiring
(
Event *ev
)
{
assert( owner );
weaponstate = WEAPON_HOLSTERED;
DetachGun();
StopAnimating();
if ( owner )
{
owner->SetCurrentWeapon( detonator );
}
}
void SpiderMine::ChangeToDetonator
(
Event *ev
)
{
if ( owner && detonator->mineList.NumObjects() )
owner->ChangeWeapon( detonator );
}
qboolean SpiderMine::ReadyToUse
(
void
)
{
Event *ev;
if ( HasAmmo() )
{
return true;
}
else
{
if ( owner->isClient() )
{
// Check to see if detonator has mines active
if ( detonator && detonator->mineList.NumObjects() )
{
ev = new Event( "use" );
ev->AddString( "Detonator" );
owner->PostEvent( ev, 0 );
}
}
return false;
}
}
void SpiderMine::SetDetonator
(
Detonator *det
)
{
detonator = det;
}
void SpiderMine::Shoot
(
Event *ev
)
{
Vector pos;
Vector dir;
Mine *mine;
Event *event;
assert( owner );
if ( !owner )
{
return;
}
GetMuzzlePosition( &pos, &dir );
if ( currentMine )
{
event = new Event(EV_Mine_Explode);
currentMine->ProcessEvent( event );
}
else
{
mine = new Mine;
mine->Setup( owner, pos, dir );
mine->SetDetonator( detonator );
detonator->AddMine( mine );
}
NextAttack( 1.8f );
}
CLASS_DECLARATION( Weapon, Detonator, NULL);
ResponseDef Detonator::Responses[] =
{
{ &EV_Weapon_Shoot, ( Response )Detonator::Shoot },
{ &EV_Weapon_DoneFiring, ( Response )Detonator::DoneFiring },
{ &EV_Weapon_SecondaryUse, ( Response )Detonator::CycleCamera },
{ NULL, NULL }
};
Detonator::Detonator
(
)
{
#ifdef SIN_DEMO
PostEvent( EV_Remove, 0 );
return;
#endif
SetModels( NULL, "view_detonator.def" );
SetType( WEAPON_1HANDED );
currentMine = 0;
}
void Detonator::RemoveMine
(
Mine *mine
)
{
mineList.RemoveObject( MinePtr( mine ) );
}
void Detonator::AddMine
(
Mine *mine
)
{
mineList.AddObject( MinePtr( mine ) );
}
void Detonator::CycleCamera
(
Event *ev
)
{
Player *client;
int numMines;
Mine *mine;
assert( owner );
if ( !owner )
{
return;
}
numMines = mineList.NumObjects();
if ( !numMines )
return;
currentMine++;
mine = mineList.ObjectAt( ( currentMine % numMines ) + 1 );
client = ( Player * )( Entity * ) owner;
if ( client->edict->areanum == mine->edict->areanum )
client->SetCamera( mine );
else
{
gi.cprintf(client->edict, PRINT_HIGH, "Spidermine %d out of range\n", ( currentMine % numMines ) + 1 );
}
}
void Detonator::DoneFiring
(
Event *ev
)
{
Weapon *weapon;
weaponstate = WEAPON_READY;
if ( owner )
{
owner->ProcessEvent( EV_Sentient_WeaponDoneFiring );
}
// Change back to spidermines if there is ammo, otherwise change weapons.
weapon = ( Weapon * )owner->FindItem( "SpiderMine" );
if ( !weapon || !weapon->HasAmmo() )
{
weapon = owner->BestWeapon();
}
owner->ChangeWeapon( weapon );
}
void Detonator::Shoot
(
Event *ev
)
{
int num,i;
Player *player;
Entity *cameraMine;
Event *event;
// If the owner is in a camera, the only detonate that mine,
// otherwise detonate them all
NextAttack( 0.1 );
if ( owner->isClient() )
{
player = ( Player * )( Entity * )owner;
cameraMine = player->CurrentCamera();
if ( cameraMine && cameraMine->isSubclassOf( Mine ) )
{
event = new Event(EV_Mine_Explode);
cameraMine->PostEvent( event, 0 );
return;
}
}
// Go through all the mines and detonate them
num = mineList.NumObjects();
for( i = num; i >= 1; i-- )
{
Event *explodeEvent;
Mine *mine;
mine = mineList.ObjectAt( i );
explodeEvent = new Event(EV_Mine_Explode);
mine->PostEvent( explodeEvent, 0 );
}
}
qboolean Detonator::IsDroppable
(
void
)
{
return false;
}
qboolean Detonator::AutoChange
(
void
)
{
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -