1
0
Fork 0

Implement invisibility effect

This commit is contained in:
peterbell10 2017-08-01 18:51:43 +01:00 committed by Lukas Pioch
parent 759618b035
commit 79eb4c3aed
5 changed files with 91 additions and 44 deletions

View File

@ -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::effNoEffect: return cpp14::make_unique<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::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
}
@ -407,6 +408,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:

View File

@ -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);
};

View File

@ -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;
}

View File

@ -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;

View File

@ -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;