snowball.cpp 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // Copyright (c) 2022-2023 the Dviglo project
  2. // Copyright (c) 2008-2023 the Urho3D project
  3. // License: MIT
  4. #include "snowball.h"
  5. #include "utilities/spawn.h"
  6. namespace Urho3D
  7. {
  8. static constexpr float SNOWBALL_MIN_HIT_SPEED = 1.f;
  9. static constexpr float SNOWBALL_DAMPING_FORCE = 20.f;
  10. static constexpr float SNOWBALL_DURATION = 5.f;
  11. static constexpr float SNOWBALL_GROUND_HIT_DURATION = 1.f;
  12. static constexpr float SNOWBALL_OBJECT_HIT_DURATION = 0.f;
  13. static constexpr i32 SNOWBALL_DAMAGE = 1;
  14. void Snowball::RegisterObject(Context* context)
  15. {
  16. context->RegisterFactory<Snowball>();
  17. }
  18. Snowball::Snowball(Context* context)
  19. : GameObject(context)
  20. {
  21. duration = SNOWBALL_DURATION;
  22. hitDamage = SNOWBALL_DAMAGE;
  23. }
  24. void Snowball::Start()
  25. {
  26. SubscribeToEvent(node_, E_NODECOLLISION, URHO3D_HANDLER(Snowball, HandleNodeCollision));
  27. }
  28. void Snowball::FixedUpdate(float timeStep)
  29. {
  30. // Apply damping when rolling on the ground, or near disappearing
  31. RigidBody* body = node_->GetComponent<RigidBody>();
  32. if (onGround || duration < SNOWBALL_GROUND_HIT_DURATION)
  33. {
  34. Vector3 vel = body->GetLinearVelocity();
  35. body->ApplyForce(Vector3(-SNOWBALL_DAMPING_FORCE * vel.x_, 0.f, -SNOWBALL_DAMPING_FORCE * vel.z_));
  36. }
  37. // Disappear when duration expired
  38. if (duration >= 0.f)
  39. {
  40. duration -= timeStep;
  41. if (duration <= 0.f)
  42. {
  43. SpawnParticleEffect(node_->GetScene(), node_->GetPosition(), "Particle/SnowExplosion.xml", 1);
  44. node_->Remove();
  45. }
  46. }
  47. }
  48. void Snowball::WorldCollision(VariantMap& eventData)
  49. {
  50. GameObject::WorldCollision(eventData);
  51. // If hit the ground, disappear after a short while
  52. if (duration > SNOWBALL_GROUND_HIT_DURATION)
  53. duration = SNOWBALL_GROUND_HIT_DURATION;
  54. }
  55. void Snowball::ObjectCollision(GameObject& otherObject, VariantMap& eventData)
  56. {
  57. if (hitDamage > 0)
  58. {
  59. RigidBody* body = node_->GetComponent<RigidBody>();
  60. if (body->GetLinearVelocity().Length() >= SNOWBALL_MIN_HIT_SPEED)
  61. {
  62. if (side != otherObject.side)
  63. {
  64. otherObject.Damage(*this, hitDamage);
  65. // Create a temporary node for the hit sound
  66. SpawnSound(node_->GetScene(), node_->GetPosition(), "Sounds/PlayerFistHit.wav", 0.2f);
  67. }
  68. hitDamage = 0;
  69. }
  70. }
  71. if (duration > SNOWBALL_OBJECT_HIT_DURATION)
  72. duration = SNOWBALL_OBJECT_HIT_DURATION;
  73. }
  74. } // namespace Urho3D