destructioneffectbase.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. class DestructionEffectBase
  2. {
  3. EntityAI m_Entity;
  4. bool m_EntityIsTakeable;
  5. ParticleSource m_POneTime;
  6. ParticleSource m_PPersistent;
  7. int m_ParticleOneTime;
  8. int m_ParticlePersistent;
  9. EffectSound m_SOneTime;
  10. EffectSound m_SPersistent;
  11. string m_SoundSetOneTime;
  12. string m_SoundSetPersistent;
  13. bool m_KeepHealthOnReplace;
  14. string m_ReplaceWithEntity;
  15. int m_ReplaceDelay;
  16. bool m_HasExplosionDamage;
  17. DamageType m_DamageType;
  18. string m_AmmoType;
  19. void ~DestructionEffectBase()
  20. {
  21. if (m_POneTime)
  22. {
  23. m_POneTime.Stop();
  24. }
  25. if (m_PPersistent)
  26. {
  27. m_PPersistent.Stop();
  28. }
  29. SEffectManager.DestroyEffect(m_SOneTime);
  30. SEffectManager.DestroyEffect(m_SPersistent);
  31. }
  32. private void Init();
  33. bool HasExplosionDamage()
  34. {
  35. return (m_HasExplosionDamage && m_AmmoType);
  36. }
  37. private void DealExplosionDamage()
  38. {
  39. DamageSystem.ExplosionDamage(m_Entity, null, m_AmmoType, m_Entity.GetPosition(), m_DamageType);
  40. }
  41. void OnHealthLevelChanged(notnull EntityAI entity, int oldLevel, int newLevel, string zone)
  42. {
  43. m_Entity = entity;
  44. Init();
  45. if (GetGame().IsServer())
  46. {
  47. entity.SetTakeable(m_EntityIsTakeable);
  48. if (oldLevel != -1 || entity.m_Initialized)
  49. {
  50. if (m_ReplaceWithEntity)
  51. {
  52. GetGame().GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(ReplaceEntityServer, m_ReplaceDelay, false);
  53. }
  54. if (HasExplosionDamage())
  55. {
  56. DealExplosionDamage();
  57. }
  58. OnEntityDestroyedOneTimeServer(entity, oldLevel, zone);
  59. }
  60. OnEntityDestroyedPersistentServer(entity, zone);
  61. }
  62. #ifndef SERVER//client OR single
  63. {
  64. if (oldLevel != -1 || entity.m_Initialized)//one time
  65. {
  66. m_POneTime = PlayParticle(m_ParticleOneTime);
  67. if (m_POneTime)
  68. {
  69. m_POneTime.SetOwner(this);
  70. }
  71. OnEntityDestroyedOneTimeClient(entity, oldLevel, zone);
  72. m_Entity.PlaySoundSet(m_SOneTime, m_SoundSetOneTime, 0, 0 );
  73. m_Entity.PlaySoundSetLoop(m_SPersistent, m_SoundSetPersistent, 0, 0 );
  74. }
  75. else//Persistent
  76. {
  77. OnEntityDestroyedPersistentClient(entity, zone);
  78. m_Entity.PlaySoundSetLoop(m_SPersistent, m_SoundSetPersistent, 0, 0 );
  79. }
  80. m_PPersistent = PlayParticle(m_ParticlePersistent, true);
  81. if (m_PPersistent)
  82. {
  83. m_PPersistent.SetOwner(this);
  84. }
  85. }
  86. #endif
  87. }
  88. private void ReplaceEntityServer()
  89. {
  90. EntityAI dead_entity = EntityAI.Cast(GetGame().CreateObjectEx(m_ReplaceWithEntity, m_Entity.GetPosition(), ECE_OBJECT_SWAP, RF_ORIGINAL));
  91. dead_entity.SetOrientation(m_Entity.GetOrientation());
  92. if (m_KeepHealthOnReplace)
  93. {
  94. dead_entity.SetHealth(m_Entity.GetHealth());
  95. }
  96. m_Entity.Delete();
  97. }
  98. private ParticleSource PlayParticle(int particleType, bool attach = false)
  99. {
  100. if (!m_Entity)
  101. {
  102. ErrorEx("Missing entity - something went wrong");
  103. return null;
  104. }
  105. if (particleType)
  106. {
  107. ParticleSource p = ParticleManager.GetInstance().PlayInWorld(particleType, m_Entity.GetPosition());
  108. if (attach && p)
  109. {
  110. p.AddAsChild(m_Entity);//Note: it's also possible to directly play on object: Particle.PlayOnObject
  111. }
  112. return p;
  113. }
  114. return null;
  115. }
  116. // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  117. // !!!!!!!!!! Override methods bellow !!!!!!!!!!!!!
  118. // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  119. // ! Client Event called the moment the entity is destroyed, best for explosion and other one-time effects
  120. void OnEntityDestroyedOneTimeClient(EntityAI entity, int oldLevel,string zone);
  121. // ! Server Event called the moment the entity is destroyed
  122. void OnEntityDestroyedOneTimeServer(EntityAI entity, int oldLevel, string zone);
  123. // ! Client Event called at the same moment as the one-time event, but also when the entity is loaded/spawned on client, typically as the player connects to the server or moves close enough so that previously non-existent client entity is now spawned in
  124. void OnEntityDestroyedPersistentClient(EntityAI entity, string zone);
  125. // ! Server Event called at the same moment as the one time event, but also when the entity is loaded/spawned on Server, typically as the server is starting up
  126. void OnEntityDestroyedPersistentServer(EntityAI entity, string zone);
  127. // !Relayed from entity when explosion happens
  128. void OnExplosionEffects(Object source, Object directHit, int componentIndex, string surface, vector pos, vector surfNormal, float energyFactor, float explosionFactor, bool isWater, string ammoType);
  129. }