28 #include "../idlib/precompiled.h"
36 #define MAX_DRAG_TRACE_DISTANCE 384.0f
37 #define TRACE_BOUNDS_SIZE 3.f
38 #define HOLD_DISTANCE 72.f
39 #define FIRING_DELAY 1000.0f
40 #define DRAG_FAIL_LEN 64.f
41 #define THROW_SCALE 1000
42 #define MAX_PICKUP_VELOCITY 1500 * 1500
43 #define MAX_PICKUP_SIZE 96
61 idGrabber::idGrabber(
void ) {
67 shakeForceFlip =
false;
70 lastFiredTime = -FIRING_DELAY;
82 idGrabber::~idGrabber(
void ) {
97 void idGrabber::Save(
idSaveGame *savefile )
const {
99 dragEnt.Save( savefile );
107 owner.Save( savefile );
113 savefile->
WriteInt( lastFiredTime );
115 savefile->
WriteInt( startDragTime );
117 savefile->
WriteInt( savedContents );
118 savefile->
WriteInt( savedClipmask );
135 dragEnt.Restore( savefile );
142 if ( dragEnt.IsValid() ) {
143 drag.SetPhysics( dragEnt.GetEntity()->GetPhysics(),
id, dragEnt.GetEntity()->GetPhysics()->GetOrigin() );
146 savefile->
ReadVec3( localPlayerPoint );
148 owner.Restore( savefile );
151 savefile->
ReadBool( shakeForceFlip );
154 savefile->
ReadInt( lastFiredTime );
155 savefile->
ReadInt( dragFailTime );
156 savefile->
ReadInt( startDragTime );
158 savefile->
ReadInt( savedContents );
159 savefile->
ReadInt( savedClipmask );
161 savefile->
ReadObject( reinterpret_cast<idClass *&>(beam) );
162 savefile->
ReadObject( reinterpret_cast<idClass *&>(beamTarget) );
172 void idGrabber::Initialize(
void ) {
178 args.
SetBool(
"start_off",
true );
184 args.
Set(
"target", beamTarget->name.c_str() );
186 args.
SetBool(
"start_off",
true );
187 args.
Set(
"width",
"6" );
188 args.
Set(
"skin",
"textures/smf/flareSizeable" );
189 args.
Set(
"_color",
"0.0235 0.843 0.969 0.2" );
210 void idGrabber::SetDragDistance(
float dist ) {
211 dragTraceDist = dist;
219 void idGrabber::StartDrag(
idEntity *grabEnt,
int id ) {
220 int clipModelId =
id;
221 idPlayer *thePlayer = owner.GetEntity();
230 grabEnt->SetGrabbedState(
true );
245 grabEnt->timeGroup = TIME_GROUP2;
248 if ( grabEnt->
IsType( idProjectile::Type ) ) {
251 p->CatchProjectile( thePlayer,
"_catch" );
264 }
else if ( grabEnt->
IsType( idExplodingBarrel::Type ) ) {
267 ebarrel->StartBurning();
269 }
else if ( grabEnt->
IsType( idAFEntity_Gibbable::Type ) ) {
274 idAI *aiEnt =
static_cast<idAI*
>(grabEnt);
278 }
else if ( grabEnt->
IsType( idMoveableItem::Type ) ) {
293 endTime =
gameLocal.
time + g_grabberHoldSeconds.GetFloat() * 1000;
296 drag.Init( g_grabberDamping.GetFloat() );
308 void idGrabber::StopDrag(
bool dropOnly ) {
309 idPlayer *thePlayer = owner.GetEntity();
318 if ( dragEnt.IsValid() ) {
319 idEntity *ent = dragEnt.GetEntity();
322 ent->SetGrabbedState(
false );
333 ent->timeGroup = TIME_GROUP1;
340 idAI *aiEnt =
static_cast<idAI*
>(ent);
345 af->SetThrown( !dropOnly );
355 if ( !ent->
IsType( idProjectile::Type ) && ( dropOnly || drag.GetDistanceToGoal() > DRAG_FAIL_LEN ) ) {
359 if ( ent->
IsType( idExplodingBarrel::Type ) ) {
362 ebarrel->SetStability(
true );
363 ebarrel->StopBurning();
371 if ( ent->
IsType( idProjectile::Type ) ) {
372 idPlayer *player = owner.GetEntity();
383 }
else if ( ent->
IsType( idMoveable::Type ) ) {
387 obj->SetAttacker( thePlayer );
389 if ( ent->
IsType( idExplodingBarrel::Type ) ) {
391 ebarrel->SetStability(
false );
394 }
else if ( ent->
IsType( idMoveableItem::Type ) ) {
403 if ( warpId != -1 ) {
418 int idGrabber::Update(
idPlayer *player,
bool hide ) {
428 if ( hide || player->
health <= 0 ) {
438 bool abort = !dragEnt.IsValid();
440 if ( !abort && dragEnt.GetEntity()->IsType( idProjectile::Type ) ) {
443 if ( proj->GetProjectileState() >= 3 ) {
447 if ( !abort && dragEnt.GetEntity()->IsHidden() ) {
464 if ( !dragEnt.GetEntity() ) {
482 if ( newEnt && ( newEnt->
IsType( idMoveable::Type ) ||
483 newEnt->
IsType( idMoveableItem::Type ) ||
484 newEnt->
IsType( idProjectile::Type ) ||
485 newEnt->
IsType( idAFEntity_Gibbable::Type ) ) &&
486 newEnt->noGrab ==
false &&
492 if ( newEnt->
IsType( idAFEntity_Gibbable::Type ) ) {
507 StartDrag( newEnt, trace.
c.
id );
508 }
else if ( validAF ) {
529 if ( dragEnt.GetEntity() && allow ) {
530 idPhysics *entPhys = dragEnt.GetEntity()->GetPhysics();
550 playerBounds.
Clear();
571 drag.SetGoalPosition( goalPos );
575 if ( g_grabberHardStop.GetBool() ) {
577 idVec3 toPlayerVelocity, objectCenter;
583 if ( toPlayerSpeed > 64.
f ) {
593 for ( i=0; i<
num; i++ ) {
600 const float MAX_ROTATION_SPEED = 12.f;
605 if ( rotationSpeed > MAX_ROTATION_SPEED ) {
607 angVel *= MAX_ROTATION_SPEED;
613 if ( dragEnt.GetEntity()->IsType( idProjectile::Type ) ) {
623 if ( drag.GetDistanceToGoal() > DRAG_FAIL_LEN ) {
645 void idGrabber::UpdateBeams(
void ) {
655 if ( dragEnt.IsValid() ) {
656 idPlayer *thePlayer = owner.GetEntity();
659 beamTarget->
SetOrigin( dragEnt.GetEntity()->GetPhysics()->GetAbsBounds().GetCenter() );
669 beam->SetOrigin( muzzle_origin );
670 re = beam->GetRenderEntity();
671 re->
origin = muzzle_origin;
673 beam->UpdateVisuals();
683 void idGrabber::ApplyShake(
void ) {
684 float u = 1 - (
float)( endTime -
gameLocal.
time ) / ( g_grabberHoldSeconds.GetFloat() * 1000 );
688 float shakeForceMagnitude = 450.f;
689 float mass = dragEnt.GetEntity()->GetPhysics()->GetMass();
691 shakeForceFlip = !shakeForceFlip;
694 point = dragEnt.GetEntity()->GetPhysics()->GetOrigin();
699 shakeForceMagnitude = 120.f;
703 if ( shakeForceFlip ) {
704 impulse.
Set( 0, 0, shakeForceMagnitude * u * mass );
707 impulse.
Set( 0, 0, -shakeForceMagnitude * u * mass );
710 dragEnt.GetEntity()->ApplyImpulse(
NULL, 0, point, impulse );
719 bool idGrabber::grabbableAI(
const char *aiName ) {
723 if (!
idStr::Cmpn( aiName,
"flying_lostsoul", 15 ) ||
virtual const idVec3 & GetOrigin(int id=0) const =0
virtual const idSoundShader * FindSound(const char *name, bool makeDefault=true)=0
int Cmp(const char *text) const
bool IsActiveAF(void) const
virtual int GetClipMask(int id=-1) const =0
virtual void SetContents(int contents, int id=-1)=0
void WriteObject(const idClass *obj)
idVec3 GetCenter(void) const
type * GetEntity(void) const
void SetShaderParm(int parmnum, float value)
idMat3 Transpose(void) const
bool IsType(const idTypeInfo &c) const
void Set(const float x, const float y, const float z)
virtual int GetNumClipModels(void) const =0
jointHandle_t GetJointHandle(const char *name) const
void ReadBool(bool &value)
virtual const idVec3 & GetLinearVelocity(int id=0) const =0
void WriteStaticObject(const idClass &obj)
virtual void SetLinearVelocity(const idVec3 &newLinearVelocity, int id=0)=0
float GetRadius(void) const
void SetNormal(const idVec3 &normal)
void Set(const char *key, const char *value)
virtual void ApplyImpulse(idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse)
#define MASK_MONSTERSOLID
int Cmpn(const char *text, int n) const
void WriteVec3(const idVec3 &vec)
void WriteBool(const bool value)
idEntity * SpawnEntityType(const idTypeInfo &classdef, const idDict *args=NULL, bool bIsClientReadSnapshot=false)
virtual const idBounds & GetBounds(int id=-1) const =0
bool StartSoundShader(const idSoundShader *shader, const s_channelType channel, int soundShaderFlags, bool broadcast, int *length)
class idPlayerView playerView
bool AddPoint(const idVec3 &v)
void SetTimeScaleRamp(const float start, const float end)
idPhysics * GetPhysics(void) const
virtual void SetGravity(const idVec3 &newGravity)=0
const char * GetString(const char *key, const char *defaultString="") const
void ReadFloat(float &value)
idVec3 vec3_origin(0.0f, 0.0f, 0.0f)
const int UCF_IMPULSE_SEQUENCE
void WriteFloat(const float value)
virtual float GetMass(int id=-1) const =0
idVec3 firstPersonViewOrigin
virtual const idVec3 & GetAngularVelocity(int id=0) const =0
virtual idAnimator * GetAnimator(void)
float NormalizeFast(void)
#define MASK_SHOT_RENDERMODEL
void SetBool(const char *key, bool val)
float LengthSqr(void) const
int Side(const idVec3 &v, const float epsilon=0.0f) const
idMat3 firstPersonViewAxis
void WriteInt(const int value)
#define MAX_DRAG_TRACE_DISTANCE
idDeclManager * declManager
idEntity * entities[MAX_GENTITIES]
void ReadStaticObject(idClass &obj)
bool TraceBounds(trace_t &results, const idVec3 &start, const idVec3 &end, const idBounds &bounds, int contentMask, const idEntity *passEntity)
idMat3 ToMat3(void) const
bool IntersectsBounds(const idBounds &a) const
virtual const idBounds & GetAbsBounds(int id=-1) const =0
bool GetJointWorldTransform(jointHandle_t jointHandle, int currentTime, idVec3 &offset, idMat3 &axis)
virtual void Damage(idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location)
#define CLASS_DECLARATION(nameofsuperclass, nameofclass)
virtual void SetAngularVelocity(const idVec3 &newAngularVelocity, int id=0)=0
void ReadVec3(idVec3 &vec)
float LengthFast(void) const
idAngles ToAngles(void) const
bool IsActive(void) const
virtual int GetContents(int id=-1) const =0
idBounds & ExpandSelf(const float d)
const char * GetEntityDefName(void) const
void SetOrigin(const idVec3 &org)
bool PostEventMS(const idEventDef *ev, int time)
void EnableDamage(bool enable, float duration)
const idEventDef EV_Touch("<touch>","et")
virtual const idVec3 & GetGravity(void) const =0
idEntityPtr< idWeapon > weapon
virtual void SetClipMask(int mask, int id=-1)=0
void SetVector(const char *key, const idVec3 &val)
void ReadObject(idClass *&obj)
void FitThroughPoint(const idVec3 &p)
virtual void SetAxis(const idMat3 &newAxis, int id=-1)=0