diff --git a/src/object/interface/damageable_object.h b/src/object/interface/damageable_object.h index 0813a286..a8f3afb5 100644 --- a/src/object/interface/damageable_object.h +++ b/src/object/interface/damageable_object.h @@ -59,4 +59,11 @@ public: //! Damage the object, with the given force. Returns true if the object has been fully destroyed (assuming the object is destroyable, of course). If force == infinity, destroy immediately (this is the default value) /** NOTE: You should never assume that after this function exits, the object is destroyed, unless it returns true. Even if you specify force = infinity, if may still sometimes decide not to destroy the object. */ virtual bool DamageObject(DamageType type, float force = std::numeric_limits::infinity(), CObject* killer = nullptr) = 0; + + + //! Set the status that means the object is currently taking damage + virtual void SetDamaging(bool damaging) = 0; + //! Is object currently taking damage? + virtual bool IsDamaging() = 0; + }; diff --git a/src/object/old_object.cpp b/src/object/old_object.cpp index 247b5a17..beaa7c3d 100644 --- a/src/object/old_object.cpp +++ b/src/object/old_object.cpp @@ -137,6 +137,7 @@ COldObject::COldObject(int id) m_bVirusMode = false; m_virusTime = 0.0f; m_lastVirusParticle = 0.0f; + m_damaging = false; m_dying = DeathType::Alive; m_bFlat = false; m_gunGoalV = 0.0f; @@ -387,6 +388,14 @@ bool COldObject::DamageObject(DamageType type, float force, CObject* killer) float shield = GetShield(); shield -= loss; SetShield(shield); + + // Sending info about taking damage + if (!m_damaging) + { + SetDamaging(true); + m_main->UpdateShortcuts(); + } + m_damageTime = m_time; } else { @@ -394,6 +403,7 @@ bool COldObject::DamageObject(DamageType type, float force, CObject* killer) { // Dead immediately SetShield(0.0f); + SetDamaging(false); } } dead = (GetShield() <= 0.0f); @@ -424,7 +434,6 @@ bool COldObject::DamageObject(DamageType type, float force, CObject* killer) { m_engine->GetPyroManager()->Create(Gfx::PT_SHOTT, this, loss); } - return false; } @@ -440,6 +449,7 @@ void COldObject::DestroyObject(DestructionType type, CObject* killer) if (Implements(ObjectInterfaceType::Shielded)) { SetShield(0.0f); + SetDamaging(false); } Gfx::PyroType pyroType = Gfx::PT_NULL; @@ -2152,6 +2162,12 @@ bool COldObject::EventFrame(const Event &event) SetShield(GetShield() + event.rTime*(1.0f/GetShieldFullRegenTime())); } + if (m_damaging && m_time - m_damageTime > 2.0f) + { + SetDamaging(false); + m_main->UpdateShortcuts(); + } + return true; } @@ -2656,6 +2672,15 @@ float COldObject::GetMagnifyDamage() return m_magnifyDamage; } +void COldObject::SetDamaging(bool damaging) +{ + m_damaging = damaging; +} + +bool COldObject::IsDamaging() +{ + return m_damaging; +} void COldObject::SetDying(DeathType deathType) { diff --git a/src/object/old_object.h b/src/object/old_object.h index 697e05db..48b71ee7 100644 --- a/src/object/old_object.h +++ b/src/object/old_object.h @@ -237,6 +237,9 @@ public: void SetMagnifyDamage(float factor) override; float GetMagnifyDamage() override; + void SetDamaging(bool damaging); + bool IsDamaging() override; + void SetDying(DeathType deathType) override; DeathType GetDying() override; bool IsDying() override; @@ -356,6 +359,8 @@ protected: bool m_bSelectable; // selectable object bool m_bCheckToken; // object with audited tokens bool m_underground; // object active but undetectable + bool m_damaging; + float m_damageTime; DeathType m_dying; bool m_bFlat; bool m_bTrainer; // drive vehicle (without remote) diff --git a/src/ui/controls/control.h b/src/ui/controls/control.h index 1a193757..b3fb3967 100644 --- a/src/ui/controls/control.h +++ b/src/ui/controls/control.h @@ -57,7 +57,8 @@ enum ControlState STATE_FRAME = (1<<13), // framework highlighting STATE_WARNING = (1<<14), // framework hatched yellow / black STATE_VALUE = (1<<15), // displays the value - STATE_RUN = (1<<16) // running program + STATE_RUN = (1<<16), // running program + STATE_DAMAGE = (1<<17) // taking damage }; diff --git a/src/ui/controls/shortcut.cpp b/src/ui/controls/shortcut.cpp index ef4f5439..036c10d6 100644 --- a/src/ui/controls/shortcut.cpp +++ b/src/ui/controls/shortcut.cpp @@ -209,6 +209,27 @@ void CShortcut::Draw() DrawIcon(m_pos, m_dim, uv1, uv2); } + if ( (m_state & STATE_DAMAGE) && Math::Mod(m_time, 0.7f) >= 0.3f ) + { + Math::Point uv1, uv2; + float dp; + + m_engine->SetTexture("textures/interface/button2.png"); + m_engine->SetState(Gfx::ENG_RSTATE_TTEXTURE_BLACK); + + uv1.x = 159.0f/256.0f; + uv1.y = 240.0f/256.0f; + uv2.x = 145.0f/256.0f; + uv2.y = 256.0f/256.0f; + + dp = 0.5f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + + DrawIcon(m_pos, m_dim, uv1, uv2); + } } // Draw the vertex array. diff --git a/src/ui/mainshort.cpp b/src/ui/mainshort.cpp index d9fffa26..23b58ee9 100644 --- a/src/ui/mainshort.cpp +++ b/src/ui/mainshort.cpp @@ -247,6 +247,7 @@ bool CMainShort::UpdateShortcuts() assert(m_shortcuts[i]->Implements(ObjectInterfaceType::Controllable)); pc->SetState(STATE_CHECK, dynamic_cast(m_shortcuts[i])->GetSelect()); pc->SetState(STATE_RUN, m_shortcuts[i]->Implements(ObjectInterfaceType::Programmable) && dynamic_cast(m_shortcuts[i])->IsProgram()); + pc->SetState(STATE_DAMAGE, dynamic_cast(m_shortcuts[i])->IsDamaging()); } } return true;