summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorarchshift <admin@archshift.com>2014-06-17 05:22:17 +0200
committerarchshift <admin@archshift.com>2014-06-19 07:54:14 +0200
commitf5529e544cf8350daf8a20bb8d997f85ee2824f7 (patch)
tree6cf5b1e2989671e7f5b9100e66b8cee015777f14
parentEntity effects: changed User to Creator, removed pawn pass-by-value (diff)
downloadcuberite-f5529e544cf8350daf8a20bb8d997f85ee2824f7.tar
cuberite-f5529e544cf8350daf8a20bb8d997f85ee2824f7.tar.gz
cuberite-f5529e544cf8350daf8a20bb8d997f85ee2824f7.tar.bz2
cuberite-f5529e544cf8350daf8a20bb8d997f85ee2824f7.tar.lz
cuberite-f5529e544cf8350daf8a20bb8d997f85ee2824f7.tar.xz
cuberite-f5529e544cf8350daf8a20bb8d997f85ee2824f7.tar.zst
cuberite-f5529e544cf8350daf8a20bb8d997f85ee2824f7.zip
-rw-r--r--src/Bindings/AllToLua.pkg2
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/Entities/EntityEffect.cpp291
-rw-r--r--src/Entities/EntityEffect.h438
-rw-r--r--src/Entities/EntityEffects.cpp31
-rw-r--r--src/Entities/EntityEffects.h82
-rw-r--r--src/Entities/Pawn.cpp119
-rw-r--r--src/Entities/Pawn.h10
-rw-r--r--src/Entities/Player.cpp37
-rw-r--r--src/Entities/Player.h3
-rw-r--r--src/Entities/SplashPotionEntity.cpp2
-rw-r--r--src/Entities/SplashPotionEntity.h2
-rw-r--r--src/Items/ItemPotion.h2
-rw-r--r--src/Mobs/Monster.cpp45
-rw-r--r--src/Mobs/Monster.h2
15 files changed, 748 insertions, 320 deletions
diff --git a/src/Bindings/AllToLua.pkg b/src/Bindings/AllToLua.pkg
index 4a6eb7535..1e5dfd2fe 100644
--- a/src/Bindings/AllToLua.pkg
+++ b/src/Bindings/AllToLua.pkg
@@ -40,7 +40,7 @@ $cfile "../Entities/Painting.h"
$cfile "../Entities/Pickup.h"
$cfile "../Entities/ProjectileEntity.h"
$cfile "../Entities/TNTEntity.h"
-$cfile "../Entities/EntityEffects.h"
+$cfile "../Entities/EntityEffect.h"
$cfile "../Server.h"
$cfile "../World.h"
$cfile "../Inventory.h"
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 3d5a0e396..678db3fb4 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -42,7 +42,7 @@ set(BINDING_DEPENDECIES
Cuboid.h
Defines.h
Enchantments.h
- Entities/EntityEffects.h
+ Entities/EntityEffect.h
Entities/Entity.h
Entities/Floater.h
Entities/Pawn.h
diff --git a/src/Entities/EntityEffect.cpp b/src/Entities/EntityEffect.cpp
new file mode 100644
index 000000000..9881785cb
--- /dev/null
+++ b/src/Entities/EntityEffect.cpp
@@ -0,0 +1,291 @@
+#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"
+
+
+
+
+cEntityEffect::cEntityEffect():
+ m_Ticks(0),
+ m_Duration(0),
+ m_Intensity(0),
+ m_Creator(NULL),
+ m_DistanceModifier(1)
+{
+
+}
+
+
+
+
+
+cEntityEffect::cEntityEffect(int a_Duration, short a_Intensity, cPawn *a_Creator, double a_DistanceModifier):
+ m_Ticks(0),
+ m_Duration(a_Duration),
+ m_Intensity(a_Intensity),
+ m_Creator(a_Creator),
+ m_DistanceModifier(a_DistanceModifier)
+{
+
+}
+
+
+
+
+
+cEntityEffect::~cEntityEffect()
+{
+
+}
+
+
+
+
+
+cEntityEffect * cEntityEffect::CreateEntityEffect(cEntityEffect::eType a_EffectType, int a_Duration, short a_Intensity, cPawn * a_Creator, double a_DistanceModifier)
+{
+ switch (a_EffectType)
+ {
+ case cEntityEffect::effNoEffect: return new cEntityEffect (a_Duration, a_Intensity, a_Creator, a_DistanceModifier);
+
+ case cEntityEffect::effAbsorption: return new cEntityEffectAbsorption (a_Duration, a_Intensity, a_Creator, a_DistanceModifier);
+ case cEntityEffect::effBlindness: return new cEntityEffectBlindness (a_Duration, a_Intensity, a_Creator, a_DistanceModifier);
+ case cEntityEffect::effFireResistance: return new cEntityEffectFireResistance(a_Duration, a_Intensity, a_Creator, a_DistanceModifier);
+ case cEntityEffect::effHaste: return new cEntityEffectHaste (a_Duration, a_Intensity, a_Creator, a_DistanceModifier);
+ case cEntityEffect::effHealthBoost: return new cEntityEffectHealthBoost (a_Duration, a_Intensity, a_Creator, a_DistanceModifier);
+ case cEntityEffect::effHunger: return new cEntityEffectHunger (a_Duration, a_Intensity, a_Creator, a_DistanceModifier);
+ case cEntityEffect::effInstantDamage: return new cEntityEffectInstantDamage (a_Duration, a_Intensity, a_Creator, a_DistanceModifier);
+ case cEntityEffect::effInstantHealth: return new cEntityEffectInstantHealth (a_Duration, a_Intensity, a_Creator, a_DistanceModifier);
+ case cEntityEffect::effInvisibility: return new cEntityEffectInvisibility (a_Duration, a_Intensity, a_Creator, a_DistanceModifier);
+ case cEntityEffect::effJumpBoost: return new cEntityEffectJumpBoost (a_Duration, a_Intensity, a_Creator, a_DistanceModifier);
+ case cEntityEffect::effMiningFatigue: return new cEntityEffectMiningFatigue (a_Duration, a_Intensity, a_Creator, a_DistanceModifier);
+ case cEntityEffect::effNausea: return new cEntityEffectNausea (a_Duration, a_Intensity, a_Creator, a_DistanceModifier);
+ case cEntityEffect::effNightVision: return new cEntityEffectNightVision (a_Duration, a_Intensity, a_Creator, a_DistanceModifier);
+ case cEntityEffect::effPoison: return new cEntityEffectPoison (a_Duration, a_Intensity, a_Creator, a_DistanceModifier);
+ case cEntityEffect::effRegeneration: return new cEntityEffectRegeneration (a_Duration, a_Intensity, a_Creator, a_DistanceModifier);
+ case cEntityEffect::effResistance: return new cEntityEffectResistance (a_Duration, a_Intensity, a_Creator, a_DistanceModifier);
+ case cEntityEffect::effSaturation: return new cEntityEffectSaturation (a_Duration, a_Intensity, a_Creator, a_DistanceModifier);
+ case cEntityEffect::effSlowness: return new cEntityEffectSlowness (a_Duration, a_Intensity, a_Creator, a_DistanceModifier);
+ case cEntityEffect::effSpeed: return new cEntityEffectSpeed (a_Duration, a_Intensity, a_Creator, a_DistanceModifier);
+ case cEntityEffect::effStrength: return new cEntityEffectStrength (a_Duration, a_Intensity, a_Creator, a_DistanceModifier);
+ case cEntityEffect::effWaterBreathing: return new cEntityEffectWaterBreathing(a_Duration, a_Intensity, a_Creator, a_DistanceModifier);
+ case cEntityEffect::effWeakness: return new cEntityEffectWeakness (a_Duration, a_Intensity, a_Creator, a_DistanceModifier);
+ case cEntityEffect::effWither: return new cEntityEffectWither (a_Duration, a_Intensity, a_Creator, a_DistanceModifier);
+ }
+
+ ASSERT(!"Unhandled entity effect type!");
+}
+
+
+
+
+
+void cEntityEffect::OnTick(cPawn & a_Target)
+{
+ // Reduce the effect's duration
+ ++m_Ticks;
+}
+
+
+
+
+
+void cEntityEffect::OnActivate(cPawn & a_Target)
+{
+}
+
+
+
+
+
+void cEntityEffect::OnDeactivate(cPawn & a_Target)
+{
+}
+
+
+
+
+
+/************************************************************************
+ **** Instant Health
+ ************************************************************************/
+void cEntityEffectInstantHealth::OnActivate(cPawn & a_Target)
+{
+ // Base amount = 6, doubles for every increase in intensity
+ int amount = (int)(6 * std::pow(2.0, m_Intensity) * m_DistanceModifier);
+
+ if (a_Target.IsMob())
+ {
+ if (((cMonster &) a_Target).IsUndead())
+ {
+ a_Target.TakeDamage(dtPotionOfHarming, m_Creator, amount, 0);
+ return;
+ }
+ }
+ a_Target.Heal(amount);
+}
+
+
+
+
+
+/************************************************************************
+ **** Instant Damage
+ ************************************************************************/
+void cEntityEffectInstantDamage::OnActivate(cPawn & a_Target)
+{
+ // Base amount = 6, doubles for every increase in intensity
+ int amount = (int)(6 * std::pow(2.0, m_Intensity) * m_DistanceModifier);
+
+ if (a_Target.IsMob())
+ {
+ if (((cMonster &) a_Target).IsUndead())
+ {
+ a_Target.Heal(amount);
+ return;
+ }
+ }
+ a_Target.TakeDamage(dtPotionOfHarming, m_Creator, amount, 0);
+}
+
+
+
+
+
+/************************************************************************
+ **** Regeneration
+ ************************************************************************/
+void cEntityEffectRegeneration::OnTick(cPawn & a_Target)
+{
+ super::OnTick(a_Target);
+
+ if (a_Target.IsMob())
+ {
+ if (((cMonster &) a_Target).IsUndead())
+ {
+ return;
+ }
+ }
+
+ // Regen frequency = 50 ticks, divided by potion level (Regen II = 25 ticks)
+ int frequency = (int) std::floor(50.0 / (double)(m_Intensity + 1));
+
+ if (m_Ticks % frequency != 0)
+ {
+ return;
+ }
+
+ a_Target.Heal(1);
+}
+
+
+
+
+
+/************************************************************************
+ **** Hunger
+ ************************************************************************/
+void cEntityEffectHunger::OnTick(cPawn & a_Target)
+{
+ super::OnTick(a_Target);
+
+ if (a_Target.IsPlayer())
+ {
+ cPlayer & Target = (cPlayer &) a_Target;
+ Target.SetFoodExhaustionLevel(Target.GetFoodExhaustionLevel() + 0.025); // 0.5 per second = 0.025 per tick
+ }
+}
+
+
+
+
+
+/************************************************************************
+ **** Weakness
+ ************************************************************************/
+void cEntityEffectWeakness::OnTick(cPawn & a_Target)
+{
+ super::OnTick(a_Target);
+
+ // Damage reduction = 0.5 damage, multiplied by potion level (Weakness II = 1 damage)
+ // double dmg_reduc = 0.5 * (a_Effect.GetIntensity() + 1);
+
+ // TODO: Implement me!
+ // TODO: Weakened villager zombies can be turned back to villagers with the god apple
+}
+
+
+
+
+
+/************************************************************************
+ **** Poison
+ ************************************************************************/
+void cEntityEffectPoison::OnTick(cPawn & a_Target)
+{
+ super::OnTick(a_Target);
+
+ if (a_Target.IsMob())
+ {
+ cMonster & Target = (cMonster &) a_Target;
+
+ // Doesn't effect undead mobs, spiders
+ if (Target.IsUndead()
+ || Target.GetMobType() == cMonster::mtSpider
+ || Target.GetMobType() == cMonster::mtCaveSpider)
+ {
+ return;
+ }
+ }
+
+ // Poison frequency = 25 ticks, divided by potion level (Poison II = 12 ticks)
+ int frequency = (int) std::floor(25.0 / (double)(m_Intensity + 1));
+
+ if (m_Ticks % frequency == 0)
+ {
+ // Cannot take poison damage when health is at 1
+ if (a_Target.GetHealth() > 1)
+ {
+ a_Target.TakeDamage(dtPoisoning, m_Creator, 1, 0);
+ }
+ }
+}
+
+
+
+
+
+/************************************************************************
+ **** Wither
+ ************************************************************************/
+void cEntityEffectWither::OnTick(cPawn & a_Target)
+{
+ super::OnTick(a_Target);
+
+ // Poison frequency = 40 ticks, divided by effect level (Wither II = 20 ticks)
+ int frequency = (int) std::floor(25.0 / (double)(m_Intensity + 1));
+
+ if (m_Ticks % frequency == 0)
+ {
+ a_Target.TakeDamage(dtWither, m_Creator, 1, 0);
+ }
+ //TODO: "<Player> withered away>
+}
+
+
+
+
+
+/************************************************************************
+ **** Saturation
+ ************************************************************************/
+void cEntityEffectSaturation::OnTick(cPawn & a_Target)
+{
+ if (a_Target.IsPlayer())
+ {
+ cPlayer & Target = (cPlayer &) a_Target;
+ Target.SetFoodSaturationLevel(Target.GetFoodSaturationLevel() + (1 + m_Intensity)); // Increase saturation 1 per tick, adds 1 for every increase in level
+ }
+}
diff --git a/src/Entities/EntityEffect.h b/src/Entities/EntityEffect.h
new file mode 100644
index 000000000..ae7958e11
--- /dev/null
+++ b/src/Entities/EntityEffect.h
@@ -0,0 +1,438 @@
+#pragma once
+
+class cPawn;
+
+// tolua_begin
+class cEntityEffect
+{
+public:
+
+ /** All types of entity effects (numbers correspond to IDs) */
+ enum eType
+ {
+ effNoEffect = 0,
+ effSpeed = 1,
+ effSlowness = 2,
+ effHaste = 3,
+ effMiningFatigue = 4,
+ effStrength = 5,
+ effInstantHealth = 6,
+ effInstantDamage = 7,
+ effJumpBoost = 8,
+ effNausea = 9,
+ effRegeneration = 10,
+ effResistance = 11,
+ effFireResistance = 12,
+ effWaterBreathing = 13,
+ effInvisibility = 14,
+ effBlindness = 15,
+ effNightVision = 16,
+ effHunger = 17,
+ effWeakness = 18,
+ effPoison = 19,
+ effWither = 20,
+ effHealthBoost = 21,
+ effAbsorption = 22,
+ effSaturation = 23,
+ } ;
+
+ /** Creates an empty entity effect */
+ cEntityEffect(void);
+
+ /** Creates an entity effect of the specified type
+ @param a_Duration How long this effect will last, in ticks
+ @param a_Intensity How strong the effect will be applied
+ @param a_Creator The pawn that produced this entity effect
+ @param a_DistanceModifier The distance modifier for affecting potency, defaults to 1 */
+ cEntityEffect(int a_Duration, short a_Intensity, cPawn * a_Creator, double a_DistanceModifier = 1);
+
+ virtual ~cEntityEffect(void);
+
+ /** Creates a pointer to the proper entity effect from the effect type
+ @warning This function creates raw pointers that must be manually managed.
+ @param a_EffectType The effect type to create the effect from
+ @param a_Duration How long this effect will last, in ticks
+ @param a_Intensity How strong the effect will be applied
+ @param a_Creator The pawn that produced this entity effect
+ @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, cPawn * a_Creator, double a_DistanceModifier);
+
+ /** Returns how many ticks this effect has been active for */
+ int GetTicks() { return m_Ticks; }
+ /** Returns the duration of the effect */
+ int GetDuration() { return m_Duration; }
+ /** Returns how strong the effect will be applied */
+ short GetIntensity() { return m_Intensity; }
+ /** Returns the pawn that produced this entity effect */
+ cPawn *GetCreator() { return m_Creator; }
+ /** Returns the distance modifier for affecting potency */
+ double GetDistanceModifier() { return m_DistanceModifier; }
+
+ void SetTicks(int a_Ticks) { m_Ticks = a_Ticks; }
+ void SetDuration(int a_Duration) { m_Duration = a_Duration; }
+ void SetIntensity(short a_Intensity) { m_Intensity = a_Intensity; }
+ void SetCreator(cPawn * a_Creator) { m_Creator = a_Creator; }
+ void SetDistanceModifier(double a_DistanceModifier) { m_DistanceModifier = a_DistanceModifier; }
+
+ virtual void OnTick(cPawn & a_Target);
+ virtual void OnActivate(cPawn & a_Target);
+ virtual void OnDeactivate(cPawn & a_Target);
+
+protected:
+ /** How many ticks this effect has been active for */
+ int m_Ticks;
+
+ /** How long this effect will last, in ticks */
+ int m_Duration;
+
+ /** How strong the effect will be applied */
+ short m_Intensity;
+
+ /** The pawn that produced this entity effect (threw the potion, etc) */
+ cPawn *m_Creator;
+
+ /** The distance modifier for affecting potency */
+ double m_DistanceModifier;
+};
+
+/************************************************************************
+ **** Speed
+ ************************************************************************/
+class cEntityEffectSpeed:
+ public cEntityEffect
+{
+ typedef cEntityEffect super;
+public:
+ cEntityEffectSpeed(int a_Duration, short a_Intensity, cPawn * a_Creator, double a_DistanceModifier = 1):
+ super(a_Duration, a_Intensity, a_Creator, a_DistanceModifier)
+ {
+ }
+};
+
+/************************************************************************
+ **** Slowness
+ ************************************************************************/
+class cEntityEffectSlowness:
+ public cEntityEffect
+{
+ typedef cEntityEffect super;
+public:
+ cEntityEffectSlowness(int a_Duration, short a_Intensity, cPawn * a_Creator, double a_DistanceModifier = 1):
+ super(a_Duration, a_Intensity, a_Creator, a_DistanceModifier)
+ {
+ }
+};
+
+/************************************************************************
+ **** Haste
+ ************************************************************************/
+class cEntityEffectHaste:
+ public cEntityEffect
+{
+ typedef cEntityEffect super;
+public:
+ cEntityEffectHaste(int a_Duration, short a_Intensity, cPawn * a_Creator, double a_DistanceModifier = 1):
+ super(a_Duration, a_Intensity, a_Creator, a_DistanceModifier)
+ {
+ }
+};
+
+/************************************************************************
+ **** Mining Fatigue
+ ************************************************************************/
+class cEntityEffectMiningFatigue:
+ public cEntityEffect
+{
+ typedef cEntityEffect super;
+public:
+ cEntityEffectMiningFatigue(int a_Duration, short a_Intensity, cPawn * a_Creator, double a_DistanceModifier = 1):
+ super(a_Duration, a_Intensity, a_Creator, a_DistanceModifier)
+ {
+ }
+};
+
+/************************************************************************
+ **** Strength
+ ************************************************************************/
+class cEntityEffectStrength:
+ public cEntityEffect
+{
+ typedef cEntityEffect super;
+public:
+ cEntityEffectStrength(int a_Duration, short a_Intensity, cPawn * a_Creator, double a_DistanceModifier = 1):
+ super(a_Duration, a_Intensity, a_Creator, a_DistanceModifier)
+ {
+ }
+};
+
+/************************************************************************
+ **** Instant Health
+ ************************************************************************/
+class cEntityEffectInstantHealth:
+ public cEntityEffect
+{
+ typedef cEntityEffect super;
+public:
+ cEntityEffectInstantHealth(int a_Duration, short a_Intensity, cPawn * a_Creator, double a_DistanceModifier = 1):
+ super(a_Duration, a_Intensity, a_Creator, a_DistanceModifier)
+ {
+ }
+
+ virtual void OnActivate(cPawn & a_Target) override;
+};
+
+/************************************************************************
+ **** Instant Damage
+ ************************************************************************/
+class cEntityEffectInstantDamage:
+ public cEntityEffect
+{
+ typedef cEntityEffect super;
+public:
+ cEntityEffectInstantDamage(int a_Duration, short a_Intensity, cPawn * a_Creator, double a_DistanceModifier = 1):
+ super(a_Duration, a_Intensity, a_Creator, a_DistanceModifier)
+ {
+ }
+
+ virtual void OnActivate(cPawn & a_Target) override;
+};
+
+/************************************************************************
+ **** Jump Boost
+ ************************************************************************/
+class cEntityEffectJumpBoost:
+ public cEntityEffect
+{
+ typedef cEntityEffect super;
+public:
+ cEntityEffectJumpBoost(int a_Duration, short a_Intensity, cPawn * a_Creator, double a_DistanceModifier = 1):
+ super(a_Duration, a_Intensity, a_Creator, a_DistanceModifier)
+ {
+ }
+};
+
+/************************************************************************
+ **** Nausea
+ ************************************************************************/
+class cEntityEffectNausea:
+ public cEntityEffect
+{
+ typedef cEntityEffect super;
+public:
+ cEntityEffectNausea(int a_Duration, short a_Intensity, cPawn * a_Creator, double a_DistanceModifier = 1):
+ super(a_Duration, a_Intensity, a_Creator, a_DistanceModifier)
+ {
+ }
+};
+
+/************************************************************************
+ **** Regeneration
+ ************************************************************************/
+class cEntityEffectRegeneration:
+ public cEntityEffect
+{
+ typedef cEntityEffect super;
+public:
+ cEntityEffectRegeneration(int a_Duration, short a_Intensity, cPawn * a_Creator, double a_DistanceModifier = 1):
+ super(a_Duration, a_Intensity, a_Creator, a_DistanceModifier)
+ {
+ }
+
+ virtual void OnTick(cPawn & a_Target) override;
+};
+
+/************************************************************************
+ **** Resistance
+ ************************************************************************/
+class cEntityEffectResistance:
+ public cEntityEffect
+{
+ typedef cEntityEffect super;
+public:
+ cEntityEffectResistance(int a_Duration, short a_Intensity, cPawn * a_Creator, double a_DistanceModifier = 1):
+ super(a_Duration, a_Intensity, a_Creator, a_DistanceModifier)
+ {
+ }
+};
+
+/************************************************************************
+ **** Fire Resistance
+ ************************************************************************/
+class cEntityEffectFireResistance:
+ public cEntityEffect
+{
+ typedef cEntityEffect super;
+public:
+ cEntityEffectFireResistance(int a_Duration, short a_Intensity, cPawn * a_Creator, double a_DistanceModifier = 1):
+ super(a_Duration, a_Intensity, a_Creator, a_DistanceModifier)
+ {
+ }
+};
+
+/************************************************************************
+ **** Water Breathing
+ ************************************************************************/
+class cEntityEffectWaterBreathing:
+ public cEntityEffect
+{
+ typedef cEntityEffect super;
+public:
+ cEntityEffectWaterBreathing(int a_Duration, short a_Intensity, cPawn * a_Creator, double a_DistanceModifier = 1):
+ super(a_Duration, a_Intensity, a_Creator, a_DistanceModifier)
+ {
+ }
+};
+
+/************************************************************************
+ **** Invisibility
+ ************************************************************************/
+class cEntityEffectInvisibility:
+ public cEntityEffect
+{
+ typedef cEntityEffect super;
+public:
+ cEntityEffectInvisibility(int a_Duration, short a_Intensity, cPawn * a_Creator, double a_DistanceModifier = 1):
+ super(a_Duration, a_Intensity, a_Creator, a_DistanceModifier)
+ {
+ }
+};
+
+/************************************************************************
+ **** Blindness
+ ************************************************************************/
+class cEntityEffectBlindness:
+ public cEntityEffect
+{
+ typedef cEntityEffect super;
+public:
+ cEntityEffectBlindness(int a_Duration, short a_Intensity, cPawn * a_Creator, double a_DistanceModifier = 1):
+ super(a_Duration, a_Intensity, a_Creator, a_DistanceModifier)
+ {
+ }
+};
+
+/************************************************************************
+ **** Night Vision
+ ************************************************************************/
+class cEntityEffectNightVision:
+ public cEntityEffect
+{
+ typedef cEntityEffect super;
+public:
+ cEntityEffectNightVision(int a_Duration, short a_Intensity, cPawn * a_Creator, double a_DistanceModifier = 1):
+ super(a_Duration, a_Intensity, a_Creator, a_DistanceModifier)
+ {
+ }
+};
+
+/************************************************************************
+ **** Hunger
+ ************************************************************************/
+class cEntityEffectHunger:
+ public cEntityEffect
+{
+ typedef cEntityEffect super;
+public:
+ cEntityEffectHunger(int a_Duration, short a_Intensity, cPawn * a_Creator, double a_DistanceModifier = 1):
+ super(a_Duration, a_Intensity, a_Creator, a_DistanceModifier)
+ {
+ }
+
+ virtual void OnTick(cPawn & a_Target) override;
+};
+
+/************************************************************************
+ **** Weakness
+ ************************************************************************/
+class cEntityEffectWeakness:
+ public cEntityEffect
+{
+ typedef cEntityEffect super;
+public:
+ cEntityEffectWeakness(int a_Duration, short a_Intensity, cPawn * a_Creator, double a_DistanceModifier = 1):
+ super(a_Duration, a_Intensity, a_Creator, a_DistanceModifier)
+ {
+ }
+
+ virtual void OnTick(cPawn & a_Target) override;
+};
+
+/************************************************************************
+ **** Poison
+ ************************************************************************/
+class cEntityEffectPoison:
+ public cEntityEffect
+{
+ typedef cEntityEffect super;
+public:
+ cEntityEffectPoison(int a_Duration, short a_Intensity, cPawn * a_Creator, double a_DistanceModifier = 1):
+ super(a_Duration, a_Intensity, a_Creator, a_DistanceModifier)
+ {
+ }
+
+ virtual void OnTick(cPawn & a_Target) override;
+};
+
+/************************************************************************
+ **** Wither
+ ************************************************************************/
+class cEntityEffectWither:
+ public cEntityEffect
+{
+ typedef cEntityEffect super;
+public:
+ cEntityEffectWither(int a_Duration, short a_Intensity, cPawn * a_Creator, double a_DistanceModifier = 1):
+ super(a_Duration, a_Intensity, a_Creator, a_DistanceModifier)
+ {
+ }
+
+ virtual void OnTick(cPawn & a_Target) override;
+};
+
+/************************************************************************
+ **** Health Boost
+ ************************************************************************/
+class cEntityEffectHealthBoost:
+ public cEntityEffect
+{
+ typedef cEntityEffect super;
+public:
+ cEntityEffectHealthBoost(int a_Duration, short a_Intensity, cPawn * a_Creator, double a_DistanceModifier = 1):
+ super(a_Duration, a_Intensity, a_Creator, a_DistanceModifier)
+ {
+ }
+};
+
+/************************************************************************
+ **** Absorption
+ ************************************************************************/
+class cEntityEffectAbsorption:
+ public cEntityEffect
+{
+ typedef cEntityEffect super;
+public:
+ cEntityEffectAbsorption(int a_Duration, short a_Intensity, cPawn * a_Creator, double a_DistanceModifier = 1):
+ super(a_Duration, a_Intensity, a_Creator, a_DistanceModifier)
+ {
+ }
+};
+
+/************************************************************************
+ **** Saturation
+ ************************************************************************/
+class cEntityEffectSaturation:
+ public cEntityEffect
+{
+ typedef cEntityEffect super;
+public:
+ cEntityEffectSaturation(int a_Duration, short a_Intensity, cPawn * a_Creator, double a_DistanceModifier = 1):
+ super(a_Duration, a_Intensity, a_Creator, a_DistanceModifier)
+ {
+ }
+
+ virtual void OnTick(cPawn & a_Target) override;
+};
+
+
+
+// tolua_end
diff --git a/src/Entities/EntityEffects.cpp b/src/Entities/EntityEffects.cpp
deleted file mode 100644
index a9edeee25..000000000
--- a/src/Entities/EntityEffects.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "EntityEffects.h"
-#include "Pawn.h"
-
-
-
-
-cEntityEffect::cEntityEffect():
- m_Ticks(0),
- m_Duration(0),
- m_Intensity(0),
- m_Creator(NULL),
- m_DistanceModifier(1)
-{
-
-}
-
-
-
-
-
-cEntityEffect::cEntityEffect(int a_Duration, short a_Intensity, cPawn *a_Creator, double a_DistanceModifier):
- m_Ticks(0),
- m_Duration(a_Duration),
- m_Intensity(a_Intensity),
- m_Creator(a_Creator),
- m_DistanceModifier(a_DistanceModifier)
-{
-
-}
diff --git a/src/Entities/EntityEffects.h b/src/Entities/EntityEffects.h
deleted file mode 100644
index 9de3fcb86..000000000
--- a/src/Entities/EntityEffects.h
+++ /dev/null
@@ -1,82 +0,0 @@
-#pragma once
-
-class cPawn;
-
-// tolua_begin
-class cEntityEffect
-{
-public:
-
- /** All types of entity effects (numbers correspond to IDs) */
- enum eType
- {
- effNoEffect = 0,
- effSpeed = 1,
- effSlowness = 2,
- effHaste = 3,
- effMiningFatigue = 4,
- effStrength = 5,
- effInstantHealth = 6,
- effInstantDamage = 7,
- effJumpBoost = 8,
- effNausea = 9,
- effRegeneration = 10,
- effResistance = 11,
- effFireResistance = 12,
- effWaterBreathing = 13,
- effInvisibility = 14,
- effBlindness = 15,
- effNightVision = 16,
- effHunger = 17,
- effWeakness = 18,
- effPoison = 19,
- effWither = 20,
- effHealthBoost = 21,
- effAbsorption = 22,
- effSaturation = 23,
- } ;
-
- /** How many ticks this effect has been active for */
- int m_Ticks;
-
- /** Returns the duration of the effect */
- int GetDuration() { return m_Duration; }
-
- /** Returns how strong the effect will be applied */
- short GetIntensity() { return m_Intensity; }
-
- /** Returns the pawn that produced this entity effect */
- cPawn *GetCreator() { return m_Creator; }
-
- /** Returns the distance modifier for affecting potency */
- double GetDistanceModifier() { return m_DistanceModifier; }
-
- void SetDuration(int a_Duration) { m_Duration = a_Duration; }
- void SetIntensity(short a_Intensity) { m_Intensity = a_Intensity; }
- void SetCreator(cPawn * a_Creator) { m_Creator = a_Creator; }
- void SetDistanceModifier(double a_DistanceModifier) { m_DistanceModifier = a_DistanceModifier; }
-
- /** Creates an empty entity effect */
- cEntityEffect(void);
-
- /** Creates an entity effect of the specified type
- @param a_Duration How long this effect will last, in ticks
- @param a_Intensity How strong the effect will be applied
- @param a_Creator The pawn that produced this entity effect
- @param a_DistanceModifier The distance modifier for affecting potency, defaults to 1 */
- cEntityEffect(int a_Duration, short a_Intensity, cPawn * a_Creator, double a_DistanceModifier = 1);
-
-private:
- /** How long this effect will last, in ticks */
- int m_Duration;
-
- /** How strong the effect will be applied */
- short m_Intensity;
-
- /** The pawn that produced this entity effect (threw the potion, etc) */
- cPawn *m_Creator;
-
- /** The distance modifier for affecting potency */
- double m_DistanceModifier;
-};
-// tolua_end
diff --git a/src/Entities/Pawn.cpp b/src/Entities/Pawn.cpp
index 6c70fd2a6..62f71e20f 100644
--- a/src/Entities/Pawn.cpp
+++ b/src/Entities/Pawn.cpp
@@ -26,19 +26,15 @@ void cPawn::Tick(float a_Dt, cChunk & a_Chunk)
{
// Copies values to prevent pesky wrong accesses and erasures
cEntityEffect::eType EffectType = iter->first;
- cEntityEffect & EffectValues = iter->second;
+ cEntityEffect * Effect = iter->second;
- // Apply entity effect
- HandleEntityEffect(EffectType, EffectValues);
-
- // Reduce the effect's duration
- EffectValues.m_Ticks++;
+ Effect->OnTick(*this);
// Iterates (must be called before any possible erasure)
++iter;
// Remove effect if duration has elapsed
- if (EffectValues.GetDuration() - EffectValues.m_Ticks <= 0)
+ if (Effect->GetDuration() - Effect->GetTicks() <= 0)
{
RemoveEntityEffect(EffectType);
}
@@ -62,10 +58,10 @@ void cPawn::KilledBy(cEntity * a_Killer)
-void cPawn::AddEntityEffect(cEntityEffect::eType a_EffectType, int a_EffectDurationTicks, short a_EffectIntensity, cPawn * a_Creator, double a_DistanceModifier)
+void cPawn::AddEntityEffect(cEntityEffect::eType a_EffectType, int a_Duration, short a_Intensity, cPawn * a_Creator, double a_DistanceModifier)
{
// Check if the plugins allow the addition:
- if (cPluginManager::Get()->CallHookEntityAddEffect(*this, a_EffectType, a_EffectDurationTicks, a_EffectIntensity, a_Creator, a_DistanceModifier))
+ if (cPluginManager::Get()->CallHookEntityAddEffect(*this, a_EffectType, a_Duration, a_Intensity, a_Creator, a_DistanceModifier))
{
// A plugin disallows the addition, bail out.
return;
@@ -76,10 +72,11 @@ void cPawn::AddEntityEffect(cEntityEffect::eType a_EffectType, int a_EffectDurat
{
return;
}
+ a_Duration = (int)(a_Duration * a_DistanceModifier);
- int EffectDuration = (int)(a_EffectDurationTicks * a_DistanceModifier);
- m_EntityEffects[a_EffectType] = cEntityEffect(EffectDuration, a_EffectIntensity, a_Creator, a_DistanceModifier);
- m_World->BroadcastEntityEffect(*this, a_EffectType, a_EffectIntensity, EffectDuration);
+ m_EntityEffects[a_EffectType] = cEntityEffect::CreateEntityEffect(a_EffectType, a_Duration, a_Intensity, a_Creator, a_DistanceModifier);
+ m_World->BroadcastEntityEffect(*this, a_EffectType, a_Intensity, a_Duration);
+ m_EntityEffects[a_EffectType]->OnActivate(*this);
}
@@ -88,8 +85,10 @@ void cPawn::AddEntityEffect(cEntityEffect::eType a_EffectType, int a_EffectDurat
void cPawn::RemoveEntityEffect(cEntityEffect::eType a_EffectType)
{
- m_EntityEffects.erase(a_EffectType);
m_World->BroadcastRemoveEntityEffect(*this, a_EffectType);
+ m_EntityEffects[a_EffectType]->OnDeactivate(*this);
+ delete m_EntityEffects[a_EffectType];
+ m_EntityEffects.erase(a_EffectType);
}
@@ -111,97 +110,3 @@ void cPawn::ClearEntityEffects()
RemoveEntityEffect(EffectType);
}
}
-
-
-
-
-
-void cPawn::HandleEntityEffect(cEntityEffect::eType a_EffectType, cEntityEffect a_Effect)
-{
- switch (a_EffectType)
- {
- // Default effect behaviors
- case cEntityEffect::effInstantHealth:
- {
- // Base heal = 6, doubles for every increase in intensity
- Heal((int)(6 * std::pow(2.0, a_Effect.GetIntensity()) * a_Effect.GetDistanceModifier()));
- return;
- }
- case cEntityEffect::effInstantDamage:
- {
- // Base damage = 6, doubles for every increase in intensity
- int damage = (int)(6 * std::pow(2.0, a_Effect.GetIntensity()) * a_Effect.GetDistanceModifier());
- TakeDamage(dtPotionOfHarming, a_Effect.GetCreator(), damage, 0);
- return;
- }
- case cEntityEffect::effStrength:
- {
- // TODO: Implement me!
- return;
- }
- case cEntityEffect::effWeakness:
- {
- // Damage reduction = 0.5 damage, multiplied by potion level (Weakness II = 1 damage)
- // double dmg_reduc = 0.5 * (a_Effect.GetIntensity() + 1);
-
- // TODO: Implement me!
- // TODO: Weakened villager zombies can be turned back to villagers with the god apple
- return;
- }
- case cEntityEffect::effRegeneration:
- {
- // Regen frequency = 50 ticks, divided by potion level (Regen II = 25 ticks)
- int frequency = std::floor(50.0 / (double)(a_Effect.GetIntensity() + 1));
-
- if (a_Effect.m_Ticks % frequency == 0)
- {
- Heal(1);
- }
-
- return;
- }
- case cEntityEffect::effPoison:
- {
- // Poison frequency = 25 ticks, divided by potion level (Poison II = 12 ticks)
- int frequency = std::floor(25.0 / (double)(a_Effect.GetIntensity() + 1));
-
- if (a_Effect.m_Ticks % frequency == 0)
- {
- // Cannot take poison damage when health is at 1
- if (GetHealth() > 1)
- {
- TakeDamage(dtPoisoning, a_Effect.GetCreator(), 1, 0);
- }
- }
-
- return;
- }
- case cEntityEffect::effWither:
- {
- // Poison frequency = 40 ticks, divided by effect level (Wither II = 20 ticks)
- int frequency = std::floor(25.0 / (double)(a_Effect.GetIntensity() + 1));
-
- if (a_Effect.m_Ticks % frequency == 0)
- {
- TakeDamage(dtWither, a_Effect.GetCreator(), 1, 0);
- }
- //TODO: "<Player> withered away>
- return;
- }
- case cEntityEffect::effFireResistance:
- {
- // TODO: Implement me!
- return;
- }
- case cEntityEffect::effSpeed:
- {
- // TODO: Implement me!
- return;
- }
- case cEntityEffect::effSlowness:
- {
- // TODO: Implement me!
- return;
- }
- }
-}
diff --git a/src/Entities/Pawn.h b/src/Entities/Pawn.h
index 9f7771d79..307e5db3d 100644
--- a/src/Entities/Pawn.h
+++ b/src/Entities/Pawn.h
@@ -2,7 +2,7 @@
#pragma once
#include "Entity.h"
-#include "EntityEffects.h"
+#include "EntityEffect.h"
@@ -46,14 +46,8 @@ public:
// tolua_end
protected:
- typedef std::map<cEntityEffect::eType, cEntityEffect> tEffectMap;
+ typedef std::map<cEntityEffect::eType, cEntityEffect *> tEffectMap;
tEffectMap m_EntityEffects;
-
- /** Applies entity effect effects
- * @param a_EffectType The selected entity effect
- * @param a_Effect The parameters of the selected entity effect
- */
- virtual void HandleEntityEffect(cEntityEffect::eType a_EffectType, cEntityEffect a_Effect);
} ; // tolua_export
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index b7a315a40..77ab6d309 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -1867,43 +1867,6 @@ void cPlayer::TickBurning(cChunk & a_Chunk)
-void cPlayer::HandleEntityEffect(cEntityEffect::eType a_EffectType, cEntityEffect a_Effect)
-{
- switch (a_EffectType)
- {
- // Effects whose behaviors are overridden
- case cEntityEffect::effMiningFatigue:
- {
- // TODO: Implement me!
- return;
- }
- case cEntityEffect::effHunger:
- {
- m_FoodExhaustionLevel += 0.025; // 0.5 per second = 0.025 per tick
- return;
- }
- case cEntityEffect::effSaturation:
- {
- // Increase saturation 1 per tick, adds 1 for every increase in level
- m_FoodSaturationLevel += (1 + a_Effect.GetIntensity());
- return;
- }
-
- // Client-side-only effects
- case cEntityEffect::effNausea:
- case cEntityEffect::effNightVision:
- {
- return;
- }
- }
-
- super::HandleEntityEffect(a_EffectType, a_Effect);
-}
-
-
-
-
-
void cPlayer::HandleFood(void)
{
// Ref.: http://www.minecraftwiki.net/wiki/Hunger
diff --git a/src/Entities/Player.h b/src/Entities/Player.h
index a793d3c30..e80b82901 100644
--- a/src/Entities/Player.h
+++ b/src/Entities/Player.h
@@ -521,9 +521,6 @@ protected:
/** Stops players from burning in creative mode */
virtual void TickBurning(cChunk & a_Chunk) override;
- /** Called each tick to handle entity effects*/
- virtual void HandleEntityEffect(cEntityEffect::eType a_EffectType, cEntityEffect a_Effect) override;
-
/** Called in each tick to handle food-related processing */
void HandleFood(void);
diff --git a/src/Entities/SplashPotionEntity.cpp b/src/Entities/SplashPotionEntity.cpp
index 2a1e9d981..3d2ef279f 100644
--- a/src/Entities/SplashPotionEntity.cpp
+++ b/src/Entities/SplashPotionEntity.cpp
@@ -79,7 +79,7 @@ bool cSplashPotionEntity::cSplashPotionCallback::Item(cEntity * a_Entity)
}
m_EntityEffect.SetDistanceModifier(Reduction);
- ((cPawn *) a_Entity)->AddEntityEffect(m_EntityEffectType, m_EntityEffect.m_Ticks, m_EntityEffect.GetIntensity(), m_EntityEffect.GetCreator(), Reduction);
+ ((cPawn *) a_Entity)->AddEntityEffect(m_EntityEffectType, m_EntityEffect.GetDuration(), m_EntityEffect.GetIntensity(), m_EntityEffect.GetCreator(), Reduction);
}
return false;
}
diff --git a/src/Entities/SplashPotionEntity.h b/src/Entities/SplashPotionEntity.h
index 0f84e6387..548ba3a3e 100644
--- a/src/Entities/SplashPotionEntity.h
+++ b/src/Entities/SplashPotionEntity.h
@@ -5,7 +5,7 @@
#pragma once
#include "ProjectileEntity.h"
-#include "EntityEffects.h"
+#include "EntityEffect.h"
#include "../World.h"
#include "Entity.h"
diff --git a/src/Items/ItemPotion.h b/src/Items/ItemPotion.h
index 853ed53a8..43b9f280d 100644
--- a/src/Items/ItemPotion.h
+++ b/src/Items/ItemPotion.h
@@ -1,7 +1,7 @@
#pragma once
-#include "../Entities/EntityEffects.h"
+#include "../Entities/EntityEffect.h"
#include "../Entities/SplashPotionEntity.h"
class cItemPotionHandler:
diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp
index 4c59960f6..a51315ecf 100644
--- a/src/Mobs/Monster.cpp
+++ b/src/Mobs/Monster.cpp
@@ -436,51 +436,6 @@ void cMonster::HandleFalling()
-void cMonster::HandleEntityEffect(cEntityEffect::eType a_EffectType, cEntityEffect a_Effect)
-{
- switch (a_EffectType)
- {
- case cEntityEffect::effPoison:
- {
- // Default effect for non-undead mobs and non-spiders
- if (!IsUndead() && GetMobType() != mtSpider) break;
- return; // No effect
- }
- case cEntityEffect::effRegeneration:
- {
- // Default effect for non-undead mobs
- if (!IsUndead() && GetMobType()) break;
- return; // No effect
- }
- case cEntityEffect::effInstantDamage:
- {
- // Default effect for non-undead mobs
- if (!IsUndead() && GetMobType()) break;
-
- // Undead mobs are healed by instant damage
- // Base heal = 6, doubles for every increase in intensity
- Heal((int)(6 * std::pow(2.0, a_Effect.GetIntensity()) * a_Effect.GetDistanceModifier()));
- return;
- }
- case cEntityEffect::effInstantHealth:
- {
- // Default effect for non-undead mobs
- if (!IsUndead() && GetMobType()) break;
-
- // Undead mobs are damaged by instant health
- // Base damage = 6, doubles for every increase in intensity
- int damage = (int)(6 * std::pow(2.0, a_Effect.GetIntensity()) * a_Effect.GetDistanceModifier());
- TakeDamage(dtPotionOfHarming, a_Effect.GetCreator(), damage, 0);
- return;
- }
- }
-
- super::HandleEntityEffect(a_EffectType, a_Effect);
-}
-
-
-
-
int cMonster::FindFirstNonAirBlockPosition(double a_PosX, double a_PosZ)
{
int PosY = POSY_TOINT;
diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h
index ca6cb0593..638d5be39 100644
--- a/src/Mobs/Monster.h
+++ b/src/Mobs/Monster.h
@@ -224,8 +224,6 @@ protected:
int m_LastGroundHeight;
/* =========================== */
-
- virtual void HandleEntityEffect(cEntityEffect::eType a_EffectType, cEntityEffect a_Effect) override;
float m_IdleInterval;
float m_DestroyTimer;