qglass.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. #include "../idlib/precompiled.h"
  2. #pragma hdrstop
  3. #include "Game_local.h"
  4. //#define ROCKETSPEED 256
  5. const idEventDef EV_glassreset( "glassreset" );
  6. CLASS_DECLARATION( idEntity, idQGlass )
  7. EVENT( EV_glassreset, idQGlass::Event_glassreset)
  8. END_CLASS
  9. void idQGlass::Save( idSaveGame *savefile ) const
  10. {
  11. savefile->WriteInt(state);
  12. savefile->WriteInt(count);
  13. savefile->WriteString(fxFracture);
  14. }
  15. void idQGlass::Restore( idRestoreGame *savefile )
  16. {
  17. savefile->ReadInt(state);
  18. savefile->ReadInt(count);
  19. savefile->ReadString(fxFracture);
  20. }
  21. void idQGlass::Spawn( void )
  22. {
  23. fxFracture = spawnArgs.GetString( "fx" );
  24. count = spawnArgs.GetInt("count", "3");
  25. this->GetPhysics()->SetContents( CONTENTS_SOLID );
  26. renderEntity.noShadow = true;
  27. renderEntity.noSelfShadow = true;
  28. //precache.
  29. common->Printf("\n------------- Caching glass debris -------------\n");
  30. const idKeyValue *kv = spawnArgs.MatchPrefix( "def_debris" );
  31. while ( kv )
  32. {
  33. const idDict *debris_args = gameLocal.FindEntityDefDict( kv->GetValue(), false );
  34. if ( debris_args )
  35. {
  36. const idDeclEntityDef *debrisDef = gameLocal.FindEntityDef( kv->GetValue(), false );
  37. if (debrisDef)
  38. {
  39. const char *clipModelName;
  40. debrisDef->dict.GetString( "clipmodel", "", &clipModelName );
  41. if ( !clipModelName[0] )
  42. {
  43. clipModelName = debrisDef->dict.GetString( "model" ); // use the visual model
  44. }
  45. // load the trace model
  46. idTraceModel trm;
  47. collisionModelManager->TrmFromModel( clipModelName, trm );
  48. }
  49. }
  50. kv = spawnArgs.MatchPrefix( "def_debris", kv );
  51. }
  52. }
  53. void idQGlass::Event_glassreset( void )
  54. {
  55. this->state = IDLE;
  56. this->Show();
  57. GetPhysics()->SetContents(CONTENTS_SOLID);
  58. }
  59. void idQGlass::AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force )
  60. {
  61. if (state == DESTROYED)
  62. return;
  63. //hide the brush.
  64. this->Hide();
  65. state = DESTROYED;
  66. GetPhysics()->SetContents(0);
  67. //audio.
  68. StartSound( "snd_shatter", SND_CHANNEL_ANY, 0, false, NULL );
  69. //particles.
  70. if ( fxFracture.Length() )
  71. {
  72. idEntityFx::StartFx( fxFracture, &point, &GetPhysics()->GetAxis(), this, true );
  73. }
  74. idBounds bounds = this->GetPhysics()->GetAbsBounds();
  75. idVec3 tmin;
  76. idVec3 tmax;
  77. tmin[0] = bounds[0][0] ;
  78. tmin[1] = bounds[0][1] ;
  79. tmin[2] = bounds[0][2] ;
  80. tmax[0] = bounds[1][0] ;
  81. tmax[1] = bounds[1][1] ;
  82. tmax[2] = bounds[1][2] ;
  83. int i;
  84. //GetPhysics()->GetOrigin()
  85. //gameRenderWorld->DebugSphere(idVec4(1,1,1,1), idSphere(tmin + GetPhysics()->GetOrigin(), 4), 10000);
  86. //gameRenderWorld->DebugSphere(idVec4(1,0,0,1), idSphere(tmax + GetPhysics()->GetOrigin(), 4), 10000);
  87. //facingAxis 0, 1 = wall panes. facingAxis 2 = ceiling/floor pane.
  88. int facingAxis = 0;
  89. for ( i = 1 ; i < 3 ; i++ )
  90. {
  91. if ( bounds[1][ i ] - bounds[0][ i ] < bounds[1][ facingAxis ] - bounds[0][ facingAxis ] )
  92. {
  93. facingAxis = i;
  94. }
  95. }
  96. //debris shower.
  97. const idKeyValue *kv = spawnArgs.MatchPrefix( "def_debris" );
  98. while ( kv )
  99. {
  100. const idDict *debris_args = gameLocal.FindEntityDefDict( kv->GetValue(), false );
  101. if ( debris_args )
  102. {
  103. idAngles dir = idAngles(0,0,0);
  104. if (facingAxis == 0)
  105. {
  106. dir.yaw = 0;
  107. }
  108. else if (facingAxis == 1)
  109. {
  110. dir.yaw = 90;
  111. }
  112. else if (facingAxis == 2)
  113. {
  114. dir.pitch = 90;
  115. }
  116. for (i = 0; i < count; i++)
  117. {
  118. idVec3 pos;
  119. idDebris *debris;
  120. idEntity *ent;
  121. dir.roll = gameLocal.random.RandomInt(360);
  122. gameLocal.SpawnEntityDef( *debris_args, &ent, false );
  123. if ( !ent || !ent->IsType( idDebris::Type ) )
  124. {
  125. gameLocal.Error( "'projectile_debris' is not an idDebris" );
  126. }
  127. pos.x = (gameLocal.random.CRandomFloat() * (tmax[0] - tmin[0])) / 2;
  128. pos.y = (gameLocal.random.CRandomFloat() * (tmax[1] - tmin[1])) / 2;
  129. pos.z = (gameLocal.random.CRandomFloat() * (tmax[2] - tmin[2])) / 2;
  130. pos += GetPhysics()->GetOrigin();
  131. debris = static_cast<idDebris *>(ent);
  132. debris->Create( this, pos, dir.ToMat3() );
  133. debris->Launch();
  134. //debris->GetRenderEntity()->shaderParms[ SHADERPARM_TIME_OF_DEATH ] = ( gameLocal.time + 1500 ) * 0.001f;
  135. debris->UpdateVisuals();
  136. }
  137. }
  138. kv = spawnArgs.MatchPrefix( "def_debris", kv );
  139. }
  140. ActivateTargets( gameLocal.GetLocalPlayer() );
  141. }