summaryrefslogtreecommitdiffstats
path: root/src/Entities
diff options
context:
space:
mode:
Diffstat (limited to 'src/Entities')
-rw-r--r--src/Entities/EntityEffect.cpp73
-rw-r--r--src/Entities/EntityEffect.h8
-rw-r--r--src/Entities/Pawn.cpp39
-rw-r--r--src/Entities/Pawn.h7
-rw-r--r--src/Entities/Player.cpp10
5 files changed, 92 insertions, 45 deletions
diff --git a/src/Entities/EntityEffect.cpp b/src/Entities/EntityEffect.cpp
index 620be395b..cc9aaca5a 100644
--- a/src/Entities/EntityEffect.cpp
+++ b/src/Entities/EntityEffect.cpp
@@ -1,8 +1,9 @@
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "EntityEffect.h"
-#include "../Mobs/Monster.h"
#include "Player.h"
+#include "../Chunk.h"
+#include "../Mobs/Monster.h"
@@ -185,40 +186,40 @@ cEntityEffect & cEntityEffect::operator =(cEntityEffect a_OtherEffect)
-cEntityEffect * cEntityEffect::CreateEntityEffect(cEntityEffect::eType a_EffectType, int a_Duration, short a_Intensity, double a_DistanceModifier)
+std::unique_ptr<cEntityEffect> cEntityEffect::CreateEntityEffect(cEntityEffect::eType a_EffectType, int a_Duration, short a_Intensity, double a_DistanceModifier)
{
switch (a_EffectType)
{
- case cEntityEffect::effNoEffect: return new cEntityEffect (a_Duration, a_Intensity, a_DistanceModifier);
-
- case cEntityEffect::effAbsorption: return new cEntityEffectAbsorption (a_Duration, a_Intensity, a_DistanceModifier);
- case cEntityEffect::effBlindness: return new cEntityEffectBlindness (a_Duration, a_Intensity, a_DistanceModifier);
- case cEntityEffect::effFireResistance: return new cEntityEffectFireResistance(a_Duration, a_Intensity, a_DistanceModifier);
- case cEntityEffect::effHaste: return new cEntityEffectHaste (a_Duration, a_Intensity, a_DistanceModifier);
- case cEntityEffect::effHealthBoost: return new cEntityEffectHealthBoost (a_Duration, a_Intensity, a_DistanceModifier);
- case cEntityEffect::effHunger: return new cEntityEffectHunger (a_Duration, a_Intensity, a_DistanceModifier);
- case cEntityEffect::effInstantDamage: return new cEntityEffectInstantDamage (a_Duration, a_Intensity, a_DistanceModifier);
- case cEntityEffect::effInstantHealth: return new cEntityEffectInstantHealth (a_Duration, a_Intensity, a_DistanceModifier);
- case cEntityEffect::effInvisibility: return new cEntityEffectInvisibility (a_Duration, a_Intensity, a_DistanceModifier);
- case cEntityEffect::effJumpBoost: return new cEntityEffectJumpBoost (a_Duration, a_Intensity, a_DistanceModifier);
- case cEntityEffect::effMiningFatigue: return new cEntityEffectMiningFatigue (a_Duration, a_Intensity, a_DistanceModifier);
- case cEntityEffect::effNausea: return new cEntityEffectNausea (a_Duration, a_Intensity, a_DistanceModifier);
- case cEntityEffect::effNightVision: return new cEntityEffectNightVision (a_Duration, a_Intensity, a_DistanceModifier);
- case cEntityEffect::effPoison: return new cEntityEffectPoison (a_Duration, a_Intensity, a_DistanceModifier);
- case cEntityEffect::effRegeneration: return new cEntityEffectRegeneration (a_Duration, a_Intensity, a_DistanceModifier);
- case cEntityEffect::effResistance: return new cEntityEffectResistance (a_Duration, a_Intensity, a_DistanceModifier);
- case cEntityEffect::effSaturation: return new cEntityEffectSaturation (a_Duration, a_Intensity, a_DistanceModifier);
- case cEntityEffect::effSlowness: return new cEntityEffectSlowness (a_Duration, a_Intensity, a_DistanceModifier);
- case cEntityEffect::effSpeed: return new cEntityEffectSpeed (a_Duration, a_Intensity, a_DistanceModifier);
- case cEntityEffect::effStrength: return new cEntityEffectStrength (a_Duration, a_Intensity, a_DistanceModifier);
- case cEntityEffect::effWaterBreathing: return new cEntityEffectWaterBreathing(a_Duration, a_Intensity, a_DistanceModifier);
- case cEntityEffect::effWeakness: return new cEntityEffectWeakness (a_Duration, a_Intensity, a_DistanceModifier);
- case cEntityEffect::effWither: return new cEntityEffectWither (a_Duration, a_Intensity, a_DistanceModifier);
+ case cEntityEffect::effNoEffect: return cpp14::make_unique<cEntityEffect >(a_Duration, a_Intensity, a_DistanceModifier);
+
+ case cEntityEffect::effAbsorption: return cpp14::make_unique<cEntityEffectAbsorption >(a_Duration, a_Intensity, a_DistanceModifier);
+ case cEntityEffect::effBlindness: return cpp14::make_unique<cEntityEffectBlindness >(a_Duration, a_Intensity, a_DistanceModifier);
+ case cEntityEffect::effFireResistance: return cpp14::make_unique<cEntityEffectFireResistance>(a_Duration, a_Intensity, a_DistanceModifier);
+ case cEntityEffect::effHaste: return cpp14::make_unique<cEntityEffectHaste >(a_Duration, a_Intensity, a_DistanceModifier);
+ case cEntityEffect::effHealthBoost: return cpp14::make_unique<cEntityEffectHealthBoost >(a_Duration, a_Intensity, a_DistanceModifier);
+ case cEntityEffect::effHunger: return cpp14::make_unique<cEntityEffectHunger >(a_Duration, a_Intensity, a_DistanceModifier);
+ case cEntityEffect::effInstantDamage: return cpp14::make_unique<cEntityEffectInstantDamage >(a_Duration, a_Intensity, a_DistanceModifier);
+ case cEntityEffect::effInstantHealth: return cpp14::make_unique<cEntityEffectInstantHealth >(a_Duration, a_Intensity, a_DistanceModifier);
+ case cEntityEffect::effInvisibility: return cpp14::make_unique<cEntityEffectInvisibility >(a_Duration, a_Intensity, a_DistanceModifier);
+ case cEntityEffect::effJumpBoost: return cpp14::make_unique<cEntityEffectJumpBoost >(a_Duration, a_Intensity, a_DistanceModifier);
+ case cEntityEffect::effMiningFatigue: return cpp14::make_unique<cEntityEffectMiningFatigue >(a_Duration, a_Intensity, a_DistanceModifier);
+ case cEntityEffect::effNausea: return cpp14::make_unique<cEntityEffectNausea >(a_Duration, a_Intensity, a_DistanceModifier);
+ case cEntityEffect::effNightVision: return cpp14::make_unique<cEntityEffectNightVision >(a_Duration, a_Intensity, a_DistanceModifier);
+ case cEntityEffect::effPoison: return cpp14::make_unique<cEntityEffectPoison >(a_Duration, a_Intensity, a_DistanceModifier);
+ case cEntityEffect::effRegeneration: return cpp14::make_unique<cEntityEffectRegeneration >(a_Duration, a_Intensity, a_DistanceModifier);
+ case cEntityEffect::effResistance: return cpp14::make_unique<cEntityEffectResistance >(a_Duration, a_Intensity, a_DistanceModifier);
+ case cEntityEffect::effSaturation: return cpp14::make_unique<cEntityEffectSaturation >(a_Duration, a_Intensity, a_DistanceModifier);
+ case cEntityEffect::effSlowness: return cpp14::make_unique<cEntityEffectSlowness >(a_Duration, a_Intensity, a_DistanceModifier);
+ case cEntityEffect::effSpeed: return cpp14::make_unique<cEntityEffectSpeed >(a_Duration, a_Intensity, a_DistanceModifier);
+ case cEntityEffect::effStrength: return cpp14::make_unique<cEntityEffectStrength >(a_Duration, a_Intensity, a_DistanceModifier);
+ case cEntityEffect::effWaterBreathing: return cpp14::make_unique<cEntityEffectWaterBreathing>(a_Duration, a_Intensity, a_DistanceModifier);
+ case cEntityEffect::effWeakness: return cpp14::make_unique<cEntityEffectWeakness >(a_Duration, a_Intensity, a_DistanceModifier);
+ case cEntityEffect::effWither: return cpp14::make_unique<cEntityEffectWither >(a_Duration, a_Intensity, a_DistanceModifier);
}
ASSERT(!"Unhandled entity effect type!");
#ifndef __clang__
- return nullptr;
+ return {};
#endif
}
@@ -408,6 +409,22 @@ void cEntityEffectHunger::OnTick(cPawn & a_Target)
////////////////////////////////////////////////////////////////////////////////
+// cEntityEffectInvisibility:
+
+void cEntityEffectInvisibility::BroadcastMetadata(cPawn & a_Target)
+{
+ auto ParentChunk = a_Target.GetParentChunk();
+ if (ParentChunk != nullptr)
+ {
+ ParentChunk->BroadcastEntityMetadata(a_Target);
+ }
+}
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////
// cEntityEffectWeakness:
void cEntityEffectWeakness::OnTick(cPawn & a_Target)
diff --git a/src/Entities/EntityEffect.h b/src/Entities/EntityEffect.h
index aa18b500e..dd126c20d 100644
--- a/src/Entities/EntityEffect.h
+++ b/src/Entities/EntityEffect.h
@@ -81,7 +81,7 @@ public:
@param a_Duration How long this effect will last, in ticks
@param a_Intensity How strong the effect will be applied
@param a_DistanceModifier The distance modifier for affecting potency, defaults to 1 */
- static cEntityEffect * CreateEntityEffect(cEntityEffect::eType a_EffectType, int a_Duration, short a_Intensity, double a_DistanceModifier);
+ static std::unique_ptr<cEntityEffect> CreateEntityEffect(cEntityEffect::eType a_EffectType, int a_Duration, short a_Intensity, double a_DistanceModifier);
/** Returns how many ticks this effect has been active for */
int GetTicks(void) const { return m_Ticks; }
@@ -346,6 +346,12 @@ public:
super(a_Duration, a_Intensity, a_DistanceModifier)
{
}
+
+ virtual void OnActivate (cPawn & a_Target) override { BroadcastMetadata(a_Target); }
+ virtual void OnDeactivate(cPawn & a_Target) override { BroadcastMetadata(a_Target); }
+
+private:
+ static void BroadcastMetadata(cPawn & a_Target);
};
diff --git a/src/Entities/Pawn.cpp b/src/Entities/Pawn.cpp
index 0a9abcdc1..a0095a8a4 100644
--- a/src/Entities/Pawn.cpp
+++ b/src/Entities/Pawn.cpp
@@ -55,7 +55,7 @@ void cPawn::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
// Copies values to prevent pesky wrong accesses and erasures
cEntityEffect::eType EffectType = iter->first;
- cEntityEffect * Effect = iter->second;
+ cEntityEffect * Effect = iter->second.get();
// Iterates (must be called before any possible erasure)
++iter;
@@ -157,6 +157,15 @@ bool cPawn::IsFireproof(void) const
+bool cPawn::IsInvisible() const
+{
+ return HasEntityEffect(cEntityEffect::effInvisibility);
+}
+
+
+
+
+
void cPawn::HandleAir(void)
{
if (IsSubmerged() && HasEntityEffect(cEntityEffect::effWaterBreathing))
@@ -188,9 +197,10 @@ void cPawn::AddEntityEffect(cEntityEffect::eType a_EffectType, int a_Duration, s
}
a_Duration = static_cast<int>(a_Duration * a_DistanceModifier);
- m_EntityEffects[a_EffectType] = cEntityEffect::CreateEntityEffect(a_EffectType, a_Duration, a_Intensity, a_DistanceModifier);
+ auto Res = m_EntityEffects.emplace(a_EffectType, cEntityEffect::CreateEntityEffect(a_EffectType, a_Duration, a_Intensity, a_DistanceModifier));
m_World->BroadcastEntityEffect(*this, a_EffectType, a_Intensity, static_cast<short>(a_Duration));
- m_EntityEffects[a_EffectType]->OnActivate(*this);
+ cEntityEffect * Effect = Res.first->second.get();
+ Effect->OnActivate(*this);
}
@@ -200,9 +210,14 @@ void cPawn::AddEntityEffect(cEntityEffect::eType a_EffectType, int a_Duration, s
void cPawn::RemoveEntityEffect(cEntityEffect::eType a_EffectType)
{
m_World->BroadcastRemoveEntityEffect(*this, a_EffectType);
- m_EntityEffects[a_EffectType]->OnDeactivate(*this);
- delete m_EntityEffects[a_EffectType];
- m_EntityEffects.erase(a_EffectType);
+ auto itr = m_EntityEffects.find(a_EffectType);
+ if (itr != m_EntityEffects.end())
+ {
+ // Erase from effect map before calling OnDeactivate to allow metadata broadcasts (e.g. for invisibility effect)
+ auto Effect = std::move(itr->second);
+ m_EntityEffects.erase(itr);
+ Effect->OnDeactivate(*this);
+ }
}
@@ -459,16 +474,22 @@ void cPawn::StopEveryoneFromTargetingMe()
std::map<cEntityEffect::eType, cEntityEffect *> cPawn::GetEntityEffects()
{
- return m_EntityEffects;
+ std::map<cEntityEffect::eType, cEntityEffect *> Effects;
+ for (auto & Effect : m_EntityEffects)
+ {
+ Effects.insert({ Effect.first, Effect.second.get() });
+ }
+ return Effects;
}
-cEntityEffect *cPawn::GetEntityEffect(cEntityEffect::eType a_EffectType)
+cEntityEffect * cPawn::GetEntityEffect(cEntityEffect::eType a_EffectType)
{
- return m_EntityEffects.at(a_EffectType);
+ auto itr = m_EntityEffects.find(a_EffectType);
+ return (itr != m_EntityEffects.end()) ? itr->second.get() : nullptr;
}
diff --git a/src/Entities/Pawn.h b/src/Entities/Pawn.h
index e6aae4f49..480b523ea 100644
--- a/src/Entities/Pawn.h
+++ b/src/Entities/Pawn.h
@@ -29,6 +29,7 @@ public:
virtual void KilledBy(TakeDamageInfo & a_TDI) override;
virtual bool IsFireproof(void) const override;
+ virtual bool IsInvisible() const override;
virtual void HandleAir(void) override;
virtual void HandleFalling(void);
@@ -66,11 +67,11 @@ public:
/** Returns all entity effects */
std::map<cEntityEffect::eType, cEntityEffect *> GetEntityEffects();
- /** Returns the entity effect, if it is currently applied. */
- cEntityEffect *GetEntityEffect(cEntityEffect::eType a_EffectType);
+ /** Returns the entity effect, if it is currently applied or nullptr if not. */
+ cEntityEffect * GetEntityEffect(cEntityEffect::eType a_EffectType);
protected:
- typedef std::map<cEntityEffect::eType, cEntityEffect *> tEffectMap;
+ typedef std::map<cEntityEffect::eType, std::unique_ptr<cEntityEffect>> tEffectMap;
tEffectMap m_EntityEffects;
double m_LastGroundHeight;
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index b07f23958..3bbe334fb 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -2963,15 +2963,17 @@ float cPlayer::GetDigSpeed(BLOCKTYPE a_Block)
}
}
- if (HasEntityEffect(cEntityEffect::effHaste))
+ auto Haste = GetEntityEffect(cEntityEffect::effHaste);
+ if (Haste != nullptr)
{
- int intensity = GetEntityEffect(cEntityEffect::effHaste)->GetIntensity() + 1;
+ int intensity = Haste->GetIntensity() + 1;
f *= 1.0f + (intensity * 0.2f);
}
- if (HasEntityEffect(cEntityEffect::effMiningFatigue))
+ auto MiningFatigue = GetEntityEffect(cEntityEffect::effMiningFatigue);
+ if (MiningFatigue != nullptr)
{
- int intensity = GetEntityEffect(cEntityEffect::effMiningFatigue)->GetIntensity();
+ int intensity = MiningFatigue->GetIntensity();
switch (intensity)
{
case 0: f *= 0.3f; break;