diff options
author | LogicParrot <LogicParrot@users.noreply.github.com> | 2017-08-22 16:41:48 +0200 |
---|---|---|
committer | LogicParrot <LogicParrot@users.noreply.github.com> | 2017-08-22 19:55:30 +0200 |
commit | 9711b06578e25fb92c8e6d10bd0f12bf593ed9db (patch) | |
tree | b84d626e2216dc4010eef3060c950cc43c560e9e | |
parent | d (diff) | |
download | cuberite-9711b06578e25fb92c8e6d10bd0f12bf593ed9db.tar cuberite-9711b06578e25fb92c8e6d10bd0f12bf593ed9db.tar.gz cuberite-9711b06578e25fb92c8e6d10bd0f12bf593ed9db.tar.bz2 cuberite-9711b06578e25fb92c8e6d10bd0f12bf593ed9db.tar.lz cuberite-9711b06578e25fb92c8e6d10bd0f12bf593ed9db.tar.xz cuberite-9711b06578e25fb92c8e6d10bd0f12bf593ed9db.tar.zst cuberite-9711b06578e25fb92c8e6d10bd0f12bf593ed9db.zip |
-rw-r--r-- | src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/Mobs/AggressiveMonster.cpp | 2 | ||||
-rw-r--r-- | src/Mobs/Behaviors/BehaviorAggressive.cpp | 26 | ||||
-rw-r--r-- | src/Mobs/Behaviors/BehaviorAggressive.h | 2 | ||||
-rw-r--r-- | src/Mobs/Behaviors/BehaviorBreeder.cpp | 8 | ||||
-rw-r--r-- | src/Mobs/Behaviors/BehaviorChaser.cpp | 148 | ||||
-rw-r--r-- | src/Mobs/Behaviors/BehaviorDayLightBurner.cpp | 152 | ||||
-rw-r--r-- | src/Mobs/Behaviors/BehaviorDayLightBurner.h | 16 | ||||
-rw-r--r-- | src/Mobs/Monster.cpp | 44 | ||||
-rw-r--r-- | src/Mobs/Monster.h | 7 | ||||
-rw-r--r-- | src/Mobs/PassiveMonster.cpp | 30 | ||||
-rw-r--r-- | src/Mobs/Sheep.cpp | 300 | ||||
-rw-r--r-- | src/Mobs/Sheep.h | 52 |
13 files changed, 381 insertions, 408 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e32bf90b7..4b3c71931 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -346,7 +346,7 @@ if (NOT MSVC) target_link_libraries(${CMAKE_PROJECT_NAME} OSSupport HTTPServer Bindings Items Blocks Noise Protocol Generating WorldStorage - Mobs Entities Simulator IncrementalRedstoneSimulator + Mobs Behaviors Entities Simulator IncrementalRedstoneSimulator BlockEntities UI PolarSSL++ ) endif () diff --git a/src/Mobs/AggressiveMonster.cpp b/src/Mobs/AggressiveMonster.cpp index 7495ca621..2cb59237c 100644 --- a/src/Mobs/AggressiveMonster.cpp +++ b/src/Mobs/AggressiveMonster.cpp @@ -13,7 +13,7 @@ cAggressiveMonster::cAggressiveMonster(const AString & a_ConfigName, eMonsterType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height) : - super(a_ConfigName, a_MobType, a_SoundHurt, a_SoundDeath, a_Width, a_Height), m_BehaviorAggressive(this, 10) + super(a_ConfigName, a_MobType, a_SoundHurt, a_SoundDeath, a_Width, a_Height), m_BehaviorAggressive(this) { m_EMPersonality = AGGRESSIVE; ASSERT(GetBehaviorChaser() != nullptr); diff --git a/src/Mobs/Behaviors/BehaviorAggressive.cpp b/src/Mobs/Behaviors/BehaviorAggressive.cpp index 74eee0e17..2113cb1e6 100644 --- a/src/Mobs/Behaviors/BehaviorAggressive.cpp +++ b/src/Mobs/Behaviors/BehaviorAggressive.cpp @@ -10,9 +10,9 @@ cBehaviorAggressive::cBehaviorAggressive(cMonster * a_Parent) : m_Parent(a_Parent) { - ASSERT(m_Parent != nullptr); - m_ParentChaser = m_Parent->GetBehaviorChaser(); - ASSERT(m_ParentChaser != nullptr); + ASSERT(m_Parent != nullptr); + m_ParentChaser = m_Parent->GetBehaviorChaser(); + ASSERT(m_ParentChaser != nullptr); } @@ -21,12 +21,12 @@ cBehaviorAggressive::cBehaviorAggressive(cMonster * a_Parent) : m_Parent(a_Paren bool cBehaviorAggressive::ActiveTick() { - // Target something new if we have no target - if (m_ParentChaser->GetTarget() == nullptr) - { - m_ParentChaser->SetTarget(FindNewTarget()); - } - return false; + // Target something new if we have no target + if (m_ParentChaser->GetTarget() == nullptr) + { + m_ParentChaser->SetTarget(FindNewTarget()); + } + return false; } @@ -35,15 +35,15 @@ bool cBehaviorAggressive::ActiveTick() void cBehaviorAggressive::Destroyed() { - m_Target = nullptr; + m_Target = nullptr; } -bool cBehaviorAggressive::FindNewTarget() +cPawn * cBehaviorAggressive::FindNewTarget() { - cPlayer * Closest = m_Parent->GetNearestPlayer(); - return Closest; // May be null + cPlayer * Closest = m_Parent->GetNearestPlayer(); + return Closest; // May be null } diff --git a/src/Mobs/Behaviors/BehaviorAggressive.h b/src/Mobs/Behaviors/BehaviorAggressive.h index 0235aa99b..ca2ad577b 100644 --- a/src/Mobs/Behaviors/BehaviorAggressive.h +++ b/src/Mobs/Behaviors/BehaviorAggressive.h @@ -9,7 +9,7 @@ class cBehaviorAggressive { public: - cBehaviorAggressive(cMonster * a_Parent, int a_MinimumLight); + cBehaviorAggressive(cMonster * a_Parent); // cBehaviorAggressive(cMonster * a_Parent, bool a_HatesPlayer); // TODO agression toward specific players, and specific mobtypes, etc diff --git a/src/Mobs/Behaviors/BehaviorBreeder.cpp b/src/Mobs/Behaviors/BehaviorBreeder.cpp index ddca1715a..8ba991989 100644 --- a/src/Mobs/Behaviors/BehaviorBreeder.cpp +++ b/src/Mobs/Behaviors/BehaviorBreeder.cpp @@ -14,7 +14,7 @@ cBehaviorBreeder::cBehaviorBreeder(cMonster * a_Parent) : m_LovePartner(nullptr), m_LoveTimer(0), m_LoveCooldown(0), - m_MatingTimer(0), + m_MatingTimer(0) { m_Parent = a_Parent; ASSERT(m_Parent != nullptr); @@ -62,7 +62,7 @@ bool cBehaviorBreeder::ActiveTick() } cFastRandom Random; - World->SpawnExperienceOrb(Pos.x, Pos.y, Pos.z, 1 + Random.NextInt(6)); + World->SpawnExperienceOrb(Pos.x, Pos.y, Pos.z, 1 + (Random.RandInt() % 6)); m_LovePartner->GetBehaviorBreeder()->ResetLoveMode(); ResetLoveMode(); @@ -169,7 +169,9 @@ void cBehaviorBreeder::OnRightClicked(cPlayer & a_Player) if ((m_LoveCooldown == 0) && !IsInLove() && !m_Parent->IsBaby()) { short HeldItem = a_Player.GetEquippedItem().m_ItemType; - if (m_BreedingItems.ContainsType(HeldItem)) + cItems BreedingItems; + m_Parent->GetFollowedItems(BreedingItems); + if (BreedingItems.ContainsType(HeldItem)) { if (!a_Player.IsGameModeCreative()) { diff --git a/src/Mobs/Behaviors/BehaviorChaser.cpp b/src/Mobs/Behaviors/BehaviorChaser.cpp index 22a95fe73..b022495eb 100644 --- a/src/Mobs/Behaviors/BehaviorChaser.cpp +++ b/src/Mobs/Behaviors/BehaviorChaser.cpp @@ -7,18 +7,19 @@ #include "BehaviorStriker.h" -, m_AttackRate(3) -, m_AttackDamage(1) -, m_AttackRange(1) -, m_AttackCoolDownTicksLeft(0) -, m_TicksSinceLastDamaged(50) + cBehaviorChaser::cBehaviorChaser(cMonster * a_Parent) : - m_Parent(a_Parent) + m_Parent(a_Parent) + , m_AttackRate(3) + , m_AttackDamage(1) + , m_AttackRange(1) + , m_AttackCoolDownTicksLeft(0) + , m_TicksSinceLastDamaged(50) { - ASSERT(m_Parent != nullptr); - m_StrikeBehavior = m_Parent->GetBehaviorStriker(); - ASSERT(m_StrikeBehavior != nullptr); // The monster that has an Attacker behavior must also have a Striker behavior + ASSERT(m_Parent != nullptr); + m_StrikeBehavior = m_Parent->GetBehaviorStriker(); + ASSERT(m_StrikeBehavior != nullptr); // The monster that has an Attacker behavior must also have a Striker behavior } @@ -27,27 +28,27 @@ cBehaviorChaser::cBehaviorChaser(cMonster * a_Parent) : bool cBehaviorChaser::ActiveTick() { - // Stop targeting out of range targets - if (GetTarget() != nullptr) - { - if (TargetOutOfSight()) - { - SetTarget(nullptr); - } - else - { - if (TargetIsInStrikeRange()) - { - StrikeTarget(); - } - else - { - ApproachTarget(); - } - return true; - } - } - return false; + // Stop targeting out of range targets + if (GetTarget() != nullptr) + { + if (TargetOutOfSight()) + { + SetTarget(nullptr); + } + else + { + if (TargetIsInStrikeRange()) + { + StrikeTarget(); + } + else + { + ApproachTarget(); + } + return true; + } + } + return false; } @@ -56,11 +57,11 @@ bool cBehaviorChaser::ActiveTick() void cBehaviorChaser::Tick() { - ++m_TicksSinceLastDamaged; - if (m_AttackCoolDownTicksLeft > 0) - { - m_AttackCoolDownTicksLeft -= 1; - } + ++m_TicksSinceLastDamaged; + if (m_AttackCoolDownTicksLeft > 0) + { + m_AttackCoolDownTicksLeft -= 1; + } } @@ -69,7 +70,7 @@ void cBehaviorChaser::Tick() void cBehaviorChaser::Destroyed() { - m_Target = nullptr; + m_Target = nullptr; } @@ -78,7 +79,7 @@ void cBehaviorChaser::Destroyed() void cBehaviorChaser::SetAttackRate(float a_AttackRate) { - m_AttackRate = a_AttackRate; + m_AttackRate = a_AttackRate; } @@ -87,7 +88,7 @@ void cBehaviorChaser::SetAttackRate(float a_AttackRate) void cBehaviorChaser::SetAttackRange(int a_AttackRange) { - m_AttackRange = a_AttackRange; + m_AttackRange = a_AttackRange; } @@ -96,7 +97,7 @@ void cBehaviorChaser::SetAttackRange(int a_AttackRange) void cBehaviorChaser::SetAttackDamage(int a_AttackDamage) { - m_AttackDamage = a_AttackDamage; + m_AttackDamage = a_AttackDamage; } @@ -104,7 +105,7 @@ void cBehaviorChaser::SetAttackDamage(int a_AttackDamage) cPawn * cBehaviorChaser::GetTarget() { - return m_Target; + return m_Target; } @@ -113,7 +114,7 @@ cPawn * cBehaviorChaser::GetTarget() void cBehaviorChaser::SetTarget(cPawn * a_Target) { - m_Target = a_Target; + m_Target = a_Target; } @@ -131,26 +132,26 @@ cBehaviorChaser::~cBehaviorChaser() bool cBehaviorChaser::TargetIsInStrikeRange() { - ASSERT(m_Target != nullptr); - ASSERT(m_Parent != nullptr); - /* - #include "../../Tracer.h" - cTracer LineOfSight(m_Parent->GetWorld()); - Vector3d MyHeadPosition = m_Parent->GetPosition() + Vector3d(0, m_Parent->GetHeight(), 0); - Vector3d AttackDirection(m_ParentChaser->GetTarget()->GetPosition() + Vector3d(0, GetTarget()->GetHeight(), 0) - MyHeadPosition); - - - if (GetTarget() != nullptr) - { - MoveToPosition(GetTarget()->GetPosition()); - } - if (TargetIsInRange() && !LineOfSight.Trace(MyHeadPosition, AttackDirection, static_cast<int>(AttackDirection.Length())) && (GetHealth() > 0.0)) - { - // Attack if reached destination, target isn't null, and have a clear line of sight to target (so won't attack through walls) - Attack(a_Dt); - } - */ - return ((m_Target->GetPosition() - m_Parent->GetPosition()).SqrLength() < (m_AttackRange * m_AttackRange)); + ASSERT(m_Target != nullptr); + ASSERT(m_Parent != nullptr); + /* + #include "../../Tracer.h" + cTracer LineOfSight(m_Parent->GetWorld()); + Vector3d MyHeadPosition = m_Parent->GetPosition() + Vector3d(0, m_Parent->GetHeight(), 0); + Vector3d AttackDirection(m_ParentChaser->GetTarget()->GetPosition() + Vector3d(0, GetTarget()->GetHeight(), 0) - MyHeadPosition); + + + if (GetTarget() != nullptr) + { + MoveToPosition(GetTarget()->GetPosition()); + } + if (TargetIsInRange() && !LineOfSight.Trace(MyHeadPosition, AttackDirection, static_cast<int>(AttackDirection.Length())) && (GetHealth() > 0.0)) + { + // Attack if reached destination, target isn't null, and have a clear line of sight to target (so won't attack through walls) + Attack(a_Dt); + } + */ + return ((m_Target->GetPosition() - m_Parent->GetPosition()).SqrLength() < (m_AttackRange * m_AttackRange)); } @@ -159,12 +160,12 @@ bool cBehaviorChaser::TargetIsInStrikeRange() bool cBehaviorChaser::TargetOutOfSight() { - ASSERT(m_Target != nullptr); - if ((GetTarget()->GetPosition() - m_Parent->GetPosition()).Length() > m_Parent->GetSightDistance()) - { - return true; - } - return false; + ASSERT(m_Target != nullptr); + if ((GetTarget()->GetPosition() - m_Parent->GetPosition()).Length() > m_Parent->GetSightDistance()) + { + return true; + } + return false; } @@ -173,7 +174,7 @@ bool cBehaviorChaser::TargetOutOfSight() void cBehaviorChaser::ResetStrikeCooldown() { - m_AttackCoolDownTicksLeft = static_cast<int>(3 * 20 * m_AttackRate); // A second has 20 ticks, an attack rate of 1 means 1 hit every 3 seconds + m_AttackCoolDownTicksLeft = static_cast<int>(3 * 20 * m_AttackRate); // A second has 20 ticks, an attack rate of 1 means 1 hit every 3 seconds } @@ -182,9 +183,10 @@ void cBehaviorChaser::ResetStrikeCooldown() void cBehaviorChaser::StrikeTarget() { - if (m_AttackCoolDownTicksLeft != 0) - { - m_StrikeBehavior->Strike(m_Target); // LogicParrot Todo animations (via counter passing?) - ResetStrikeCooldown(); - } + if (m_AttackCoolDownTicksLeft != 0) + { + // mobTodo + // m_StrikeBehavior->Strike(m_Target); // LogicParrot Todo animations (via counter passing?) + ResetStrikeCooldown(); + } } diff --git a/src/Mobs/Behaviors/BehaviorDayLightBurner.cpp b/src/Mobs/Behaviors/BehaviorDayLightBurner.cpp index f15247071..9f182a359 100644 --- a/src/Mobs/Behaviors/BehaviorDayLightBurner.cpp +++ b/src/Mobs/Behaviors/BehaviorDayLightBurner.cpp @@ -1,85 +1,93 @@ -void cMonster::HandleDaylightBurning(cChunk & a_Chunk, bool WouldBurn) +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "BehaviorDayLightBurner.h" +#include "../Monster.h" +#include "../../World.h" +#include "../../Entities/Player.h" +#include "../../Entities/Entity.h" + +cBehaviorDayLightBurner::cBehaviorDayLightBurner(cMonster * a_Parent) : m_Parent(a_Parent) { - if (!m_BurnsInDaylight) - { - return; - } + ASSERT(m_Parent != nullptr); +} - int RelY = POSY_TOINT; - if ((RelY < 0) || (RelY >= cChunkDef::Height)) - { - // Outside the world - return; - } - if (!a_Chunk.IsLightValid()) - { - m_World->QueueLightChunk(GetChunkX(), GetChunkZ()); - return; - } +void cBehaviorDayLightBurner::Tick(cChunk & a_Chunk, bool WouldBurn) +{ + int RelY = POSY_TOINT; + if ((RelY < 0) || (RelY >= cChunkDef::Height)) + { + // Outside the world + return; + } + if (!a_Chunk.IsLightValid()) + { + m_World->QueueLightChunk(GetChunkX(), GetChunkZ()); + return; + } - if (!IsOnFire() && WouldBurn) - { - // Burn for 100 ticks, then decide again - StartBurning(100); - } + if (!IsOnFire() && WouldBurn) + { + // Burn for 100 ticks, then decide again + StartBurning(100); + } } -bool cMonster::WouldBurnAt(Vector3d a_Location, cChunk & a_Chunk) +bool cBehaviorDayLightBurner::WouldBurnAt(Vector3d & a_Location, cChunk & a_Chunk) { - int RelY = FloorC(a_Location.y); - if (RelY <= 0) - { - // The mob is about to die, no point in burning - return false; - } - if (RelY >= cChunkDef::Height) - { - // Always burn above the world - return true; - } + int RelY = FloorC(a_Location.y); + if (RelY <= 0) + { + // The mob is about to die, no point in burning + return false; + } + if (RelY >= cChunkDef::Height) + { + // Always burn above the world + return true; + } - PREPARE_REL_AND_CHUNK(a_Location, a_Chunk); - if (!RelSuccess) - { - return false; - } + PREPARE_REL_AND_CHUNK(a_Location, a_Chunk); + if (!RelSuccess) + { + return false; + } - if ( - (Chunk->GetBlock(Rel.x, Rel.y, Rel.z) != E_BLOCK_SOULSAND) && // Not on soulsand - (GetWorld()->GetTimeOfDay() < 12000 + 1000) && // Daytime - GetWorld()->IsWeatherSunnyAt(POSX_TOINT, POSZ_TOINT) // Not raining - ) - { - int MobHeight = static_cast<int>(a_Location.y) + round(GetHeight()) - 1; // The height of the mob head - if (MobHeight >= cChunkDef::Height) - { - return true; - } - // Start with the highest block and scan down to the mob's head. - // If a non transparent is found, return false (do not burn). Otherwise return true. - // Note that this loop is not a performance concern as transparent blocks are rare and the loop almost always bailes out - // instantly.(An exception is e.g. standing under a long column of glass). - int CurrentBlock = Chunk->GetHeight(Rel.x, Rel.z); - while (CurrentBlock >= MobHeight) - { - BLOCKTYPE Block = Chunk->GetBlock(Rel.x, CurrentBlock, Rel.z); - if ( - // Do not burn if a block above us meets one of the following conditions: - (!cBlockInfo::IsTransparent(Block)) || - (Block == E_BLOCK_LEAVES) || - (Block == E_BLOCK_NEW_LEAVES) || - (IsBlockWater(Block)) - ) - { - return false; - } - --CurrentBlock; - } - return true; + if ( + (Chunk->GetBlock(Rel.x, Rel.y, Rel.z) != E_BLOCK_SOULSAND) && // Not on soulsand + (GetWorld()->GetTimeOfDay() < 12000 + 1000) && // Daytime + GetWorld()->IsWeatherSunnyAt(POSX_TOINT, POSZ_TOINT) // Not raining + ) + { + int MobHeight = static_cast<int>(a_Location.y) + round(GetHeight()) - 1; // The height of the mob head + if (MobHeight >= cChunkDef::Height) + { + return true; + } + // Start with the highest block and scan down to the mob's head. + // If a non transparent is found, return false (do not burn). Otherwise return true. + // Note that this loop is not a performance concern as transparent blocks are rare and the loop almost always bailes out + // instantly.(An exception is e.g. standing under a long column of glass). + int CurrentBlock = Chunk->GetHeight(Rel.x, Rel.z); + while (CurrentBlock >= MobHeight) + { + BLOCKTYPE Block = Chunk->GetBlock(Rel.x, CurrentBlock, Rel.z); + if ( + // Do not burn if a block above us meets one of the following conditions: + (!cBlockInfo::IsTransparent(Block)) || + (Block == E_BLOCK_LEAVES) || + (Block == E_BLOCK_NEW_LEAVES) || + (IsBlockWater(Block)) + ) + { + return false; + } + --CurrentBlock; + } + return true; - } - return false; + } + return false; } diff --git a/src/Mobs/Behaviors/BehaviorDayLightBurner.h b/src/Mobs/Behaviors/BehaviorDayLightBurner.h index 9d4cbe874..b54a863af 100644 --- a/src/Mobs/Behaviors/BehaviorDayLightBurner.h +++ b/src/Mobs/Behaviors/BehaviorDayLightBurner.h @@ -1,5 +1,21 @@ +#pragma once + +// fwds +class cMonster; +class cEntity; +class cChunk; +class Vector3d; class cBehaviorDayLightBurner { + cBehaviorDayLightBurner(cMonster * a_Parent); + + bool WouldBurnAt(Vector3d & a_Location, cChunk & a_Chunk); + + // Functions our host Monster should invoke: + void Tick(); +private: + cMonster * m_Parent; // Our Parent + cEntity * m_Attacker; // The entity we're running away from }; diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index d02ea1809..fe2809f28 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -107,7 +107,6 @@ cMonster::cMonster(const AString & a_ConfigName, eMonsterType a_MobType, const A , m_DropChanceBoots(0.085f) , m_CanPickUpLoot(true) , m_TicksSinceLastDamaged(100) - , m_BurnsInDaylight(false) , m_RelativeWalkSpeed(1) , m_Age(1) , m_AgingTimer(20 * 60 * 20) // about 20 minutes @@ -349,7 +348,7 @@ void cMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) 2. I was not hurt by a player recently. Then STOP. */ if ( - m_BurnsInDaylight && ((m_TicksSinceLastDamaged >= 100) || (m_EMState == IDLE)) && + (GetBehaviorDaylightBurner() != nullptr) && ((m_TicksSinceLastDamaged >= 100) || (m_EMState == IDLE)) && WouldBurnAt(m_NextWayPointPosition, *Chunk) && !WouldBurnAt(GetPosition(), *Chunk) ) @@ -1178,7 +1177,16 @@ cBehaviorWanderer * cMonster::GetBehaviorWanderer() -void cMonster::InheritFromParents(cPassiveMonster * a_Parent1, cPassiveMonster * a_Parent2) +cBehaviorWanderer * cMonster::GetBehaviorDaylightBurner() +{ + return nullptr; +} + + + + + +void cMonster::InheritFromParents(cMonster * a_Parent1, cMonster * a_Parent2) { UNUSED(a_Parent1); UNUSED(a_Parent2); @@ -1414,36 +1422,6 @@ void cMonster::AddRandomWeaponDropItem(cItems & a_Drops, unsigned int a_LootingL - -void cMonster::HandleDaylightBurning(cChunk & a_Chunk, bool WouldBurn) -{ - if (!m_BurnsInDaylight) - { - return; - } - - int RelY = POSY_TOINT; - if ((RelY < 0) || (RelY >= cChunkDef::Height)) - { - // Outside the world - return; - } - if (!a_Chunk.IsLightValid()) - { - m_World->QueueLightChunk(GetChunkX(), GetChunkZ()); - return; - } - - if (!IsOnFire() && WouldBurn) - { - // Burn for 100 ticks, then decide again - StartBurning(100); - } -} - - - - bool cMonster::WouldBurnAt(Vector3d a_Location, cChunk & a_Chunk) { // If the Y coord is out of range, return the most logical result without considering anything else: diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index a9669ced9..22c8dfded 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -145,9 +145,6 @@ public: void SetCanPickUpLoot(bool a_CanPickUpLoot) { m_CanPickUpLoot = a_CanPickUpLoot; } void ResetAttackCooldown(); - /** Sets whether the mob burns in daylight. Only evaluated at next burn-decision tick */ - void SetBurnsInDaylight(bool a_BurnsInDaylight) { m_BurnsInDaylight = a_BurnsInDaylight; } - double GetRelativeWalkSpeed(void) const { return m_RelativeWalkSpeed; } // tolua_export void SetRelativeWalkSpeed(double a_WalkSpeed) { m_RelativeWalkSpeed = a_WalkSpeed; } // tolua_export @@ -228,9 +225,10 @@ public: virtual cBehaviorChaser * GetBehaviorChaser(); virtual cBehaviorStriker * GetBehaviorStriker(); virtual cBehaviorWanderer * GetBehaviorWanderer(); + virtual cBehaviorWanderer * GetBehaviorDaylightBurner(); // Polymorphic behavior functions ("Skin-specific") - virtual void InheritFromParents(cPassiveMonster * a_Parent1, cPassiveMonster * a_Parent2); + virtual void InheritFromParents(cMonster * a_Parent1, cMonster * a_Parent2); virtual void GetFollowedItems(cItems & a_Items); virtual void GetBreedingItems(cItems & a_Items); @@ -315,7 +313,6 @@ public: void HandleDaylightBurning(cChunk & a_Chunk, bool WouldBurn); bool WouldBurnAt(Vector3d a_Location, cChunk & a_Chunk); - bool m_BurnsInDaylight; double m_RelativeWalkSpeed; int m_Age; diff --git a/src/Mobs/PassiveMonster.cpp b/src/Mobs/PassiveMonster.cpp index 777238b79..5eded6b6f 100644 --- a/src/Mobs/PassiveMonster.cpp +++ b/src/Mobs/PassiveMonster.cpp @@ -32,36 +32,6 @@ cPassiveMonster::~cPassiveMonster() bool cPassiveMonster::DoTakeDamage(TakeDamageInfo & a_TDI) { if (!super::DoTakeDamage(a_TDI)) -#pragma once - -#include "Monster.h" -#include "Behaviors/BehaviorBreeder.h" -#include "Behaviors/BehaviorItemFollower.h" -#include "Behaviors/BehaviorCoward.h" - - -typedef std::string AString; -class cPassiveMonster : public cMonster -{ - typedef cMonster super; - -public: - cPassiveMonster(const AString & a_ConfigName, eMonsterType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height, cItems & a_BreedingItems, cItems & a_FollowedItems); - virtual ~cPassiveMonster(); - virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; - virtual void OnRightClicked(cPlayer & a_Player) override; - - /** When hit by someone, run away */ - virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override; - - virtual void Destroyed(void) override; - -private: - cBehaviorBreeder m_BehaviorBreeder; - cBehaviorItemFollower m_BehaviorItemFollower; - cBehaviorCoward m_BehaviorCoward; -}; - { return false; } diff --git a/src/Mobs/Sheep.cpp b/src/Mobs/Sheep.cpp index fef1adac6..312bf74e2 100644 --- a/src/Mobs/Sheep.cpp +++ b/src/Mobs/Sheep.cpp @@ -12,21 +12,21 @@ cSheep::cSheep(int a_Color) : - super("Sheep", mtSheep, "entity.sheep.hurt", "entity.sheep.death", 0.6, 1.3), - m_IsSheared(false), - m_WoolColor(a_Color), - m_TimeToStopEating(-1) + super("Sheep", mtSheep, "entity.sheep.hurt", "entity.sheep.death", 0.6, 1.3), + m_IsSheared(false), + m_WoolColor(a_Color), + m_TimeToStopEating(-1) { - // Generate random wool color. - if (m_WoolColor == -1) - { - m_WoolColor = GenerateNaturalRandomColor(); - } - - if ((m_WoolColor < 0) || (m_WoolColor > 15)) - { - m_WoolColor = 0; - } + // Generate random wool color. + if (m_WoolColor == -1) + { + m_WoolColor = GenerateNaturalRandomColor(); + } + + if ((m_WoolColor < 0) || (m_WoolColor > 15)) + { + m_WoolColor = 0; + } } @@ -35,17 +35,17 @@ cSheep::cSheep(int a_Color) : void cSheep::GetDrops(cItems & a_Drops, cEntity * a_Killer) { - if (!m_IsSheared) - { - a_Drops.push_back(cItem(E_BLOCK_WOOL, 1, static_cast<short>(m_WoolColor))); - } - - unsigned int LootingLevel = 0; - if (a_Killer != nullptr) - { - LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); - } - AddRandomDropItem(a_Drops, 1, 3 + LootingLevel, IsOnFire() ? E_ITEM_COOKED_MUTTON : E_ITEM_RAW_MUTTON); + if (!m_IsSheared) + { + a_Drops.push_back(cItem(E_BLOCK_WOOL, 1, static_cast<short>(m_WoolColor))); + } + + unsigned int LootingLevel = 0; + if (a_Killer != nullptr) + { + LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); + } + AddRandomDropItem(a_Drops, 1, 3 + LootingLevel, IsOnFire() ? E_ITEM_COOKED_MUTTON : E_ITEM_RAW_MUTTON); } @@ -54,30 +54,30 @@ void cSheep::GetDrops(cItems & a_Drops, cEntity * a_Killer) void cSheep::OnRightClicked(cPlayer & a_Player) { - super::OnRightClicked(a_Player); - - const cItem & EquippedItem = a_Player.GetEquippedItem(); - if ((EquippedItem.m_ItemType == E_ITEM_SHEARS) && !IsSheared() && !IsBaby()) - { - m_IsSheared = true; - m_World->BroadcastEntityMetadata(*this); - a_Player.UseEquippedItem(); - - cItems Drops; - char NumDrops = GetRandomProvider().RandInt<char>(1, 3); - Drops.emplace_back(E_BLOCK_WOOL, NumDrops, static_cast<short>(m_WoolColor)); - m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY(), GetPosZ(), 10); - m_World->BroadcastSoundEffect("entity.sheep.shear", GetPosX(), GetPosY(), GetPosZ(), 1.0f, 1.0f); - } - else if ((EquippedItem.m_ItemType == E_ITEM_DYE) && (m_WoolColor != 15 - EquippedItem.m_ItemDamage)) - { - m_WoolColor = 15 - EquippedItem.m_ItemDamage; - if (!a_Player.IsGameModeCreative()) - { - a_Player.GetInventory().RemoveOneEquippedItem(); - } - m_World->BroadcastEntityMetadata(*this); - } + super::OnRightClicked(a_Player); + + const cItem & EquippedItem = a_Player.GetEquippedItem(); + if ((EquippedItem.m_ItemType == E_ITEM_SHEARS) && !IsSheared() && !IsBaby()) + { + m_IsSheared = true; + m_World->BroadcastEntityMetadata(*this); + a_Player.UseEquippedItem(); + + cItems Drops; + char NumDrops = GetRandomProvider().RandInt<char>(1, 3); + Drops.emplace_back(E_BLOCK_WOOL, NumDrops, static_cast<short>(m_WoolColor)); + m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY(), GetPosZ(), 10); + m_World->BroadcastSoundEffect("entity.sheep.shear", GetPosX(), GetPosY(), GetPosZ(), 1.0f, 1.0f); + } + else if ((EquippedItem.m_ItemType == E_ITEM_DYE) && (m_WoolColor != 15 - EquippedItem.m_ItemDamage)) + { + m_WoolColor = 15 - EquippedItem.m_ItemDamage; + if (!a_Player.IsGameModeCreative()) + { + a_Player.GetInventory().RemoveOneEquippedItem(); + } + m_World->BroadcastEntityMetadata(*this); + } } @@ -86,88 +86,88 @@ void cSheep::OnRightClicked(cPlayer & a_Player) void cSheep::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { - super::Tick(a_Dt, a_Chunk); - if (!IsTicking()) - { - // The base class tick destroyed us - return; - } - int PosX = POSX_TOINT; - int PosY = POSY_TOINT - 1; - int PosZ = POSZ_TOINT; - - if ((PosY <= 0) || (PosY >= cChunkDef::Height)) - { - return; - } - - if (m_TimeToStopEating > 0) - { - StopMovingToPosition(); - m_TimeToStopEating--; - - if (m_TimeToStopEating == 0) - { - if (m_World->GetBlock(PosX, PosY, PosZ) == E_BLOCK_GRASS) // Make sure grass hasn't been destroyed in the meantime - { - // The sheep ate the grass so we change it to dirt - m_World->SetBlock(PosX, PosY, PosZ, E_BLOCK_DIRT, 0); - GetWorld()->BroadcastSoundParticleEffect(EffectID::PARTICLE_BLOCK_BREAK, PosX, PosY, PosX, E_BLOCK_GRASS); - m_IsSheared = false; - m_World->BroadcastEntityMetadata(*this); - } - } - } - else - { - if (GetRandomProvider().RandBool(1.0 / 600.0)) - { - if (m_World->GetBlock(PosX, PosY, PosZ) == E_BLOCK_GRASS) - { - m_World->BroadcastEntityStatus(*this, esSheepEating); - m_TimeToStopEating = 40; - } - } - } + super::Tick(a_Dt, a_Chunk); + if (!IsTicking()) + { + // The base class tick destroyed us + return; + } + int PosX = POSX_TOINT; + int PosY = POSY_TOINT - 1; + int PosZ = POSZ_TOINT; + + if ((PosY <= 0) || (PosY >= cChunkDef::Height)) + { + return; + } + + if (m_TimeToStopEating > 0) + { + StopMovingToPosition(); + m_TimeToStopEating--; + + if (m_TimeToStopEating == 0) + { + if (m_World->GetBlock(PosX, PosY, PosZ) == E_BLOCK_GRASS) // Make sure grass hasn't been destroyed in the meantime + { + // The sheep ate the grass so we change it to dirt + m_World->SetBlock(PosX, PosY, PosZ, E_BLOCK_DIRT, 0); + GetWorld()->BroadcastSoundParticleEffect(EffectID::PARTICLE_BLOCK_BREAK, PosX, PosY, PosX, E_BLOCK_GRASS); + m_IsSheared = false; + m_World->BroadcastEntityMetadata(*this); + } + } + } + else + { + if (GetRandomProvider().RandBool(1.0 / 600.0)) + { + if (m_World->GetBlock(PosX, PosY, PosZ) == E_BLOCK_GRASS) + { + m_World->BroadcastEntityStatus(*this, esSheepEating); + m_TimeToStopEating = 40; + } + } + } } -void cSheep::InheritFromParents(cPassiveMonster * a_Parent1, cPassiveMonster * a_Parent2) +void cSheep::InheritFromParents(cMonster * a_Parent1, cMonster * a_Parent2) { - static const struct - { - short Parent1, Parent2, Child; - } ColorInheritance[] = - { - { E_META_WOOL_BLUE, E_META_WOOL_RED, E_META_WOOL_PURPLE }, - { E_META_WOOL_BLUE, E_META_WOOL_GREEN, E_META_WOOL_CYAN }, - { E_META_WOOL_YELLOW, E_META_WOOL_RED, E_META_WOOL_ORANGE }, - { E_META_WOOL_GREEN, E_META_WOOL_WHITE, E_META_WOOL_LIGHTGREEN }, - { E_META_WOOL_RED, E_META_WOOL_WHITE, E_META_WOOL_PINK }, - { E_META_WOOL_WHITE, E_META_WOOL_BLACK, E_META_WOOL_GRAY }, - { E_META_WOOL_PURPLE, E_META_WOOL_PINK, E_META_WOOL_MAGENTA }, - { E_META_WOOL_WHITE, E_META_WOOL_GRAY, E_META_WOOL_LIGHTGRAY }, - { E_META_WOOL_BLUE, E_META_WOOL_WHITE, E_META_WOOL_LIGHTBLUE }, - }; - cSheep * Parent1 = static_cast<cSheep *>(a_Parent1); - cSheep * Parent2 = static_cast<cSheep *>(a_Parent2); - for (size_t i = 0; i < ARRAYCOUNT(ColorInheritance); i++) - { - if ( - ((Parent1->GetFurColor() == ColorInheritance[i].Parent1) && (Parent2->GetFurColor() == ColorInheritance[i].Parent2)) || - ((Parent1->GetFurColor() == ColorInheritance[i].Parent2) && (Parent2->GetFurColor() == ColorInheritance[i].Parent1)) - ) - { - SetFurColor(ColorInheritance[i].Child); - m_World->BroadcastEntityMetadata(*this); - return; - } - } - SetFurColor(GetRandomProvider().RandBool() ? Parent1->GetFurColor() : Parent2->GetFurColor()); - m_World->BroadcastEntityMetadata(*this); + static const struct + { + short Parent1, Parent2, Child; + } ColorInheritance[] = + { + { E_META_WOOL_BLUE, E_META_WOOL_RED, E_META_WOOL_PURPLE }, + { E_META_WOOL_BLUE, E_META_WOOL_GREEN, E_META_WOOL_CYAN }, + { E_META_WOOL_YELLOW, E_META_WOOL_RED, E_META_WOOL_ORANGE }, + { E_META_WOOL_GREEN, E_META_WOOL_WHITE, E_META_WOOL_LIGHTGREEN }, + { E_META_WOOL_RED, E_META_WOOL_WHITE, E_META_WOOL_PINK }, + { E_META_WOOL_WHITE, E_META_WOOL_BLACK, E_META_WOOL_GRAY }, + { E_META_WOOL_PURPLE, E_META_WOOL_PINK, E_META_WOOL_MAGENTA }, + { E_META_WOOL_WHITE, E_META_WOOL_GRAY, E_META_WOOL_LIGHTGRAY }, + { E_META_WOOL_BLUE, E_META_WOOL_WHITE, E_META_WOOL_LIGHTBLUE }, + }; + cSheep * Parent1 = static_cast<cSheep *>(a_Parent1); + cSheep * Parent2 = static_cast<cSheep *>(a_Parent2); + for (size_t i = 0; i < ARRAYCOUNT(ColorInheritance); i++) + { + if ( + ((Parent1->GetFurColor() == ColorInheritance[i].Parent1) && (Parent2->GetFurColor() == ColorInheritance[i].Parent2)) || + ((Parent1->GetFurColor() == ColorInheritance[i].Parent2) && (Parent2->GetFurColor() == ColorInheritance[i].Parent1)) + ) + { + SetFurColor(ColorInheritance[i].Child); + m_World->BroadcastEntityMetadata(*this); + return; + } + } + SetFurColor(GetRandomProvider().RandBool() ? Parent1->GetFurColor() : Parent2->GetFurColor()); + m_World->BroadcastEntityMetadata(*this); } @@ -176,31 +176,31 @@ void cSheep::InheritFromParents(cPassiveMonster * a_Parent1, cPassiveMonster * a NIBBLETYPE cSheep::GenerateNaturalRandomColor(void) { - int Chance = GetRandomProvider().RandInt(100); - - if (Chance <= 81) - { - return E_META_WOOL_WHITE; - } - else if (Chance <= 86) - { - return E_META_WOOL_BLACK; - } - else if (Chance <= 91) - { - return E_META_WOOL_GRAY; - } - else if (Chance <= 96) - { - return E_META_WOOL_LIGHTGRAY; - } - else if (Chance <= 99) - { - return E_META_WOOL_BROWN; - } - else - { - return E_META_WOOL_PINK; - } + int Chance = GetRandomProvider().RandInt(100); + + if (Chance <= 81) + { + return E_META_WOOL_WHITE; + } + else if (Chance <= 86) + { + return E_META_WOOL_BLACK; + } + else if (Chance <= 91) + { + return E_META_WOOL_GRAY; + } + else if (Chance <= 96) + { + return E_META_WOOL_LIGHTGRAY; + } + else if (Chance <= 99) + { + return E_META_WOOL_BROWN; + } + else + { + return E_META_WOOL_PINK; + } } diff --git a/src/Mobs/Sheep.h b/src/Mobs/Sheep.h index 02aa888f1..3e2069cf1 100644 --- a/src/Mobs/Sheep.h +++ b/src/Mobs/Sheep.h @@ -8,44 +8,44 @@ class cSheep : - public cPassiveMonster + public cPassiveMonster { - typedef cPassiveMonster super; + typedef cPassiveMonster super; public: - /** The number is the color of the sheep. - Use E_META_WOOL_* constants for the wool color. - If you type -1, the server will generate a random color - with the GenerateNaturalRandomColor() function. */ - cSheep(int a_Color = -1); + /** The number is the color of the sheep. + Use E_META_WOOL_* constants for the wool color. + If you type -1, the server will generate a random color + with the GenerateNaturalRandomColor() function. */ + cSheep(int a_Color = -1); - CLASS_PROTODEF(cSheep) + CLASS_PROTODEF(cSheep) - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; - virtual void OnRightClicked(cPlayer & a_Player) override; - virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; - virtual void InheritFromParents(cPassiveMonster * a_Parent1, cPassiveMonster * a_Parent2) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; + virtual void OnRightClicked(cPlayer & a_Player) override; + virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; + virtual void InheritFromParents(cMonster * a_Parent1, cMonster * a_Parent2) override; - virtual void GetFollowedItems(cItems & a_Items) override - { - a_Items.Add(E_ITEM_WHEAT); - } + virtual void GetFollowedItems(cItems & a_Items) override + { + a_Items.Add(E_ITEM_WHEAT); + } - /** Generates a random color for the sheep like the vanilla server. - The percent's where used are from the wiki: http://minecraft.gamepedia.com/Sheep#Breeding */ - static NIBBLETYPE GenerateNaturalRandomColor(void); + /** Generates a random color for the sheep like the vanilla server. + The percent's where used are from the wiki: http://minecraft.gamepedia.com/Sheep#Breeding */ + static NIBBLETYPE GenerateNaturalRandomColor(void); - bool IsSheared(void) const { return m_IsSheared; } - void SetSheared(bool a_IsSheared) { m_IsSheared = a_IsSheared; } + bool IsSheared(void) const { return m_IsSheared; } + void SetSheared(bool a_IsSheared) { m_IsSheared = a_IsSheared; } - int GetFurColor(void) const { return m_WoolColor; } - void SetFurColor(int a_WoolColor) { m_WoolColor = a_WoolColor; } + int GetFurColor(void) const { return m_WoolColor; } + void SetFurColor(int a_WoolColor) { m_WoolColor = a_WoolColor; } private: - bool m_IsSheared; - int m_WoolColor; - int m_TimeToStopEating; + bool m_IsSheared; + int m_WoolColor; + int m_TimeToStopEating; } ; |