From 74645fdfaa892e460c1b5444fd35eca11343e570 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 16 Jan 2014 19:00:49 +0000 Subject: Removed obsoleted functions --- src/Mobs/Monster.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 76df76633..98b6c1d28 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -208,7 +208,7 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk) Distance.Normalize(); VectorToEuler( Distance.x, Distance.y, Distance.z, Rotation, Pitch ); SetHeadYaw (Rotation); - SetRotation( Rotation ); + SetYaw( Rotation ); SetPitch( -Pitch ); } -- cgit v1.2.3 From 3e675f8c38720cd6c483ee0f9733a9c060ded936 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 24 Jan 2014 19:52:52 +0000 Subject: Implemented creeper abilities * Creepers now explode with a sound effect * Creepers drop a music disc on the unlikely event of being killed by a skeleton's arrow Inspired by @maniak89's PR #132. --- src/Mobs/Creeper.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- src/Mobs/Creeper.h | 3 +++ 2 files changed, 50 insertions(+), 2 deletions(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Creeper.cpp b/src/Mobs/Creeper.cpp index 4e11ae13e..ad8fe10a1 100644 --- a/src/Mobs/Creeper.cpp +++ b/src/Mobs/Creeper.cpp @@ -3,6 +3,7 @@ #include "Creeper.h" #include "../World.h" +#include "../Entities/ProjectileEntity.h" @@ -11,7 +12,8 @@ cCreeper::cCreeper(void) : super("Creeper", mtCreeper, "mob.creeper.say", "mob.creeper.say", 0.6, 1.8), m_bIsBlowing(false), - m_bIsCharged(false) + m_bIsCharged(false), + m_ExplodingTimer(0) { } @@ -19,11 +21,34 @@ cCreeper::cCreeper(void) : +void cCreeper::Tick(float a_Dt, cChunk & a_Chunk) +{ + super::Tick(a_Dt, a_Chunk); + + if (!ReachedFinalDestination()) + { + m_ExplodingTimer = 0; + m_bIsBlowing = false; + m_World->BroadcastEntityMetadata(*this); + } +} + + + + + void cCreeper::GetDrops(cItems & a_Drops, cEntity * a_Killer) { AddRandomDropItem(a_Drops, 0, 2, E_ITEM_GUNPOWDER); - // TODO Check if killed by a skeleton, then drop random music disk + if ((a_Killer != NULL) && (a_Killer->IsProjectile())) + { + if (((cMonster *)((cProjectileEntity *)a_Killer)->GetCreator())->GetMobType() == mtSkeleton) + { + // 12 music discs. TickRand starts from 0, so range = 11. Disk IDs start at 2256, so add that. There. + AddRandomDropItem(a_Drops, 1, 1, (short)m_World->GetTickRandomNumber(11) + 2256); + } + } } @@ -45,3 +70,23 @@ void cCreeper::DoTakeDamage(TakeDamageInfo & a_TDI) + +void cCreeper::Attack(float a_Dt) +{ + UNUSED(a_Dt); + + m_ExplodingTimer += 1; + + if (!m_bIsBlowing) + { + m_World->BroadcastSoundEffect("random.fuse", (int)GetPosX() * 8, (int)GetPosY() * 8, (int)GetPosZ() * 8, 1.f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); + m_bIsBlowing = true; + m_World->BroadcastEntityMetadata(*this); + } + + if (m_ExplodingTimer == 20) + { + m_World->DoExplosionAt((m_bIsCharged ? 5 : 3), GetPosX(), GetPosY(), GetPosZ(), false, esMonster, this); + Destroy(); + } +} \ No newline at end of file diff --git a/src/Mobs/Creeper.h b/src/Mobs/Creeper.h index c3d4edeae..0f71e5ad2 100644 --- a/src/Mobs/Creeper.h +++ b/src/Mobs/Creeper.h @@ -19,6 +19,8 @@ public: virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; virtual void DoTakeDamage(TakeDamageInfo & a_TDI) override; + virtual void Attack(float a_Dt) override; + virtual void Tick(float a_Dt, cChunk & a_Chunk) override; bool IsBlowing(void) const {return m_bIsBlowing; } bool IsCharged(void) const {return m_bIsCharged; } @@ -26,6 +28,7 @@ public: private: bool m_bIsBlowing, m_bIsCharged; + int m_ExplodingTimer; } ; -- cgit v1.2.3 From 9c0e3615ce61dba0ae973b97807833bd6ddd5bda Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 24 Jan 2014 19:57:32 +0000 Subject: Large reworking of mob code [SEE DESC] + Implemented better pathfinding - Removed lots of unused variables, functions, etc. * Changed some variable types * Other miscellaneous fixes, and also completes the previous PRs --- src/Mobs/AggressiveMonster.cpp | 65 ++++--- src/Mobs/AggressiveMonster.h | 5 +- src/Mobs/Monster.cpp | 400 ++++++++++++++++++++++++----------------- src/Mobs/Monster.h | 68 +++++-- src/Mobs/PassiveMonster.cpp | 16 +- src/Mobs/Wolf.cpp | 2 +- 6 files changed, 324 insertions(+), 232 deletions(-) (limited to 'src/Mobs') diff --git a/src/Mobs/AggressiveMonster.cpp b/src/Mobs/AggressiveMonster.cpp index cc7e7da2b..a4b3eede1 100644 --- a/src/Mobs/AggressiveMonster.cpp +++ b/src/Mobs/AggressiveMonster.cpp @@ -4,7 +4,6 @@ #include "AggressiveMonster.h" #include "../World.h" -#include "../Vector3f.h" #include "../Entities/Player.h" #include "../MersenneTwister.h" @@ -13,8 +12,7 @@ cAggressiveMonster::cAggressiveMonster(const AString & a_ConfigName, eType 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_ChaseTime(999999) + super(a_ConfigName, a_MobType, a_SoundHurt, a_SoundDeath, a_Width, a_Height) { m_EMPersonality = AGGRESSIVE; } @@ -27,32 +25,23 @@ cAggressiveMonster::cAggressiveMonster(const AString & a_ConfigName, eType a_Mob void cAggressiveMonster::InStateChasing(float a_Dt) { super::InStateChasing(a_Dt); - m_ChaseTime += a_Dt; + if (m_Target != NULL) { if (m_Target->IsPlayer()) { - cPlayer * Player = (cPlayer *) m_Target; - if (Player->IsGameModeCreative()) + if (((cPlayer *)m_Target)->IsGameModeCreative()) { m_EMState = IDLE; return; } } - Vector3f Pos = Vector3f( GetPosition() ); - Vector3f Their = Vector3f( m_Target->GetPosition() ); - if ((Their - Pos).Length() <= m_AttackRange) + if (((float)m_FinalDestination.x != (float)m_Target->GetPosX()) || ((float)m_FinalDestination.z != (float)m_Target->GetPosZ())) { - Attack(a_Dt); + MoveToPosition(m_Target->GetPosition()); } - MoveToPosition(Their + Vector3f(0, 0.65f, 0)); } - else if (m_ChaseTime > 5.f) - { - m_ChaseTime = 0; - m_EMState = IDLE; - } } @@ -62,7 +51,10 @@ void cAggressiveMonster::InStateChasing(float a_Dt) void cAggressiveMonster::EventSeePlayer(cEntity * a_Entity) { super::EventSeePlayer(a_Entity); - m_EMState = CHASING; + if (!((cPlayer *)a_Entity)->IsGameModeCreative()) + { + m_EMState = CHASING; + } } @@ -73,25 +65,32 @@ void cAggressiveMonster::Tick(float a_Dt, cChunk & a_Chunk) { super::Tick(a_Dt, a_Chunk); - m_SeePlayerInterval += a_Dt; - - if (m_SeePlayerInterval > 1) + if (m_EMState == CHASING) + { + CheckEventLostPlayer(); + } + else { - int rem = m_World->GetTickRandomNumber(3) + 1; // Check most of the time but miss occasionally + CheckEventSeePlayer(); + } +} - m_SeePlayerInterval = 0.0; - if (rem >= 2) - { - if (m_EMState == CHASING) - { - CheckEventLostPlayer(); - } - else - { - CheckEventSeePlayer(); - } - } + + + + +void cAggressiveMonster::Attack(float a_Dt) +{ + super::Attack(a_Dt); + + if ((m_Target != NULL) && (m_AttackInterval > 3.0)) + { + // Setting this higher gives us more wiggle room for attackrate + m_AttackInterval = 0.0; + m_Target->TakeDamage(dtMobAttack, this, m_AttackDamage, 0); } } + + diff --git a/src/Mobs/AggressiveMonster.h b/src/Mobs/AggressiveMonster.h index 5a0d93f3d..9cee4e7a7 100644 --- a/src/Mobs/AggressiveMonster.h +++ b/src/Mobs/AggressiveMonster.h @@ -13,16 +13,15 @@ class cAggressiveMonster : typedef cMonster super; public: + cAggressiveMonster(const AString & a_ConfigName, eType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height); virtual void Tick (float a_Dt, cChunk & a_Chunk) override; virtual void InStateChasing(float a_Dt) override; virtual void EventSeePlayer(cEntity *) override; + virtual void Attack(float a_Dt) override; - -protected: - float m_ChaseTime; } ; diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 98b6c1d28..91ecf3b52 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -8,13 +8,9 @@ #include "../World.h" #include "../Entities/Player.h" #include "../Entities/ExpOrb.h" -#include "../Defines.h" #include "../MonsterConfig.h" #include "../MersenneTwister.h" -#include "../Vector3f.h" -#include "../Vector3i.h" -#include "../Vector3d.h" #include "../Tracer.h" #include "../Chunk.h" #include "../FastRandom.h" @@ -81,11 +77,9 @@ cMonster::cMonster(const AString & a_ConfigName, eType a_MobType, const AString , m_bMovingToDestination(false) , m_DestinationTime( 0 ) , m_DestroyTimer( 0 ) - , m_Jump(0) , m_MobType(a_MobType) , m_SoundHurt(a_SoundHurt) , m_SoundDeath(a_SoundDeath) - , m_SeePlayerInterval (0) , m_AttackDamage(1.0f) , m_AttackRange(2.0f) , m_AttackInterval(0) @@ -110,11 +104,105 @@ void cMonster::SpawnOn(cClientHandle & a_Client) -void cMonster::MoveToPosition( const Vector3f & a_Position ) +void cMonster::TickPathFinding() { + int PosX = (int)floor(GetPosX()); + int PosY = (int)floor(GetPosY()); + int PosZ = (int)floor(GetPosZ()); + + m_FinalDestination.y = (double)FindFirstNonAirBlockPosition(m_FinalDestination.x, m_FinalDestination.z); + + std::vector m_PotentialCoordinates; + m_TraversedCoordinates.push_back(Vector3i(PosX, PosY, PosZ)); + + static const struct // Define which directions the torch can power + { + int x, z; + } gCrossCoords[] = + { + { 1, 0}, + {-1, 0}, + { 0, 1}, + { 0,-1}, + } ; + + for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++) + { + if ((gCrossCoords[i].x + PosX == PosX) && (gCrossCoords[i].z + PosZ == PosZ)) + { + continue; + } + + if (IsCoordinateInTraversedList(Vector3i(gCrossCoords[i].x + PosX, PosY, gCrossCoords[i].z + PosZ))) + { + continue; + } + + BLOCKTYPE BlockAtY = m_World->GetBlock(gCrossCoords[i].x + PosX, PosY, gCrossCoords[i].z + PosZ); + BLOCKTYPE BlockAtYP = m_World->GetBlock(gCrossCoords[i].x + PosX, PosY + 1, gCrossCoords[i].z + PosZ); + BLOCKTYPE BlockAtYPP = m_World->GetBlock(gCrossCoords[i].x + PosX, PosY + 2, gCrossCoords[i].z + PosZ); + BLOCKTYPE BlockAtYM = m_World->GetBlock(gCrossCoords[i].x + PosX, PosY - 1, gCrossCoords[i].z + PosZ); + + if (!g_BlockIsSolid[BlockAtY] && !g_BlockIsSolid[BlockAtYP] && !IsBlockLava(BlockAtYM)) + { + m_PotentialCoordinates.push_back(Vector3d((gCrossCoords[i].x + PosX), PosY, gCrossCoords[i].z + PosZ)); + } + else if (g_BlockIsSolid[BlockAtY] && !g_BlockIsSolid[BlockAtYP] && !g_BlockIsSolid[BlockAtYPP] && !IsBlockLava(BlockAtYM)) + { + m_PotentialCoordinates.push_back(Vector3d((gCrossCoords[i].x + PosX), PosY + 1, gCrossCoords[i].z + PosZ)); + } + } + + if (!m_PotentialCoordinates.empty()) + { + Vector3f ShortestCoords = m_PotentialCoordinates.front(); + for (std::vector::const_iterator itr = m_PotentialCoordinates.begin(); itr != m_PotentialCoordinates.end(); ++itr) + { + Vector3f Distance = m_FinalDestination - ShortestCoords; + Vector3f Distance2 = m_FinalDestination - *itr; + if (Distance.SqrLength() > Distance2.SqrLength()) + { + ShortestCoords = *itr; + } + } + + m_Destination = ShortestCoords; + m_Destination.z += 0.5f; + m_Destination.x += 0.5f; + } + else + { + FinishPathFinding(); + } +} + + + + + +void cMonster::MoveToPosition(const Vector3f & a_Position) +{ + FinishPathFinding(); + + m_FinalDestination = a_Position; m_bMovingToDestination = true; + TickPathFinding(); +} + + + + +bool cMonster::IsCoordinateInTraversedList(Vector3i a_Coords) +{ + for (std::vector::const_iterator itr = m_TraversedCoordinates.begin(); itr != m_TraversedCoordinates.end(); ++itr) + { + if (itr->Equals(a_Coords)) + { + return true; + } + } - m_Destination = a_Position; + return false; } @@ -123,10 +211,24 @@ void cMonster::MoveToPosition( const Vector3f & a_Position ) bool cMonster::ReachedDestination() { - Vector3f Distance = (m_Destination) - GetPosition(); - if( Distance.SqrLength() < 2.f ) + if ((m_Destination - GetPosition()).Length() < 0.5f) + { return true; + } + + return false; +} + + + +bool cMonster::ReachedFinalDestination() +{ + if ((GetPosition() - m_FinalDestination).Length() <= m_AttackRange) + { + return true; + } + return false; } @@ -151,23 +253,19 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk) // Burning in daylight HandleDaylightBurning(a_Chunk); - - HandlePhysics(a_Dt,a_Chunk); - BroadcastMovementUpdate(); a_Dt /= 1000; if (m_bMovingToDestination) { - Vector3f Pos( GetPosition() ); - Vector3f Distance = m_Destination - Pos; - if( !ReachedDestination() ) + Vector3f Distance = m_Destination - GetPosition(); + if(!ReachedDestination() && !ReachedFinalDestination()) // If we haven't reached any sort of destination, move { Distance.y = 0; Distance.Normalize(); Distance *= 3; - SetSpeedX( Distance.x ); - SetSpeedZ( Distance.z ); + SetSpeedX(Distance.x); + SetSpeedZ(Distance.z); if (m_EMState == ESCAPING) { //Runs Faster when escaping :D otherwise they just walk away @@ -177,40 +275,32 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk) } else { - m_bMovingToDestination = false; + if (ReachedFinalDestination()) // If we have reached the ultimate, final destination, stop pathfinding and attack if appropriate + { + FinishPathFinding(); + } + else + { + TickPathFinding(); // We have reached the next point in our path, calculate another point + } } - if( GetSpeed().SqrLength() > 0.f ) + if(m_bOnGround) { - if( m_bOnGround ) + int NextHeight = FindFirstNonAirBlockPosition(m_Destination.x, m_Destination.z); + + if (IsNextYPosReachable(NextHeight)) { - Vector3f NormSpeed = Vector3f(GetSpeed()).NormalizeCopy(); - Vector3f NextBlock = Vector3f( GetPosition() ) + NormSpeed; - int NextHeight; - if (!m_World->TryGetHeight((int)NextBlock.x, (int)NextBlock.z, NextHeight)) - { - // The chunk at NextBlock is not loaded - return; - } - if( NextHeight > (GetPosY() - 1.0) && (NextHeight - GetPosY()) < 2.5 ) - { - m_bOnGround = false; - SetSpeedY(5.f); // Jump!! - } + m_bOnGround = false; + SetSpeedY(5.f); // Jump!! } } } - Vector3d Distance = m_Destination - GetPosition(); - if (Distance.SqrLength() > 0.1f) - { - double Rotation, Pitch; - Distance.Normalize(); - VectorToEuler( Distance.x, Distance.y, Distance.z, Rotation, Pitch ); - SetHeadYaw (Rotation); - SetYaw( Rotation ); - SetPitch( -Pitch ); - } + if (ReachedFinalDestination()) + Attack(a_Dt); + + SetPitchAndYawFromDestination(); switch (m_EMState) { @@ -219,21 +309,87 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk) // If enemy passive we ignore checks for player visibility InStateIdle(a_Dt); break; - } - + } case CHASING: { // If we do not see a player anymore skip chasing action InStateChasing(a_Dt); break; - } - + } case ESCAPING: { InStateEscaping(a_Dt); break; } } // switch (m_EMState) + + BroadcastMovementUpdate(); +} + + + + +void cMonster::SetPitchAndYawFromDestination() +{ + Vector3d FinalDestination = m_FinalDestination; + if (m_Target != NULL) + { + if (m_Target->IsPlayer()) + { + FinalDestination.y = ((cPlayer *)m_Target)->GetStance(); + } + else + { + FinalDestination.y = GetHeight(); + } + } + + Vector3d Distance = FinalDestination - GetPosition(); + if (Distance.SqrLength() > 0.1f) + { + { + double Rotation, Pitch; + Distance.Normalize(); + VectorToEuler(Distance.x, Distance.y, Distance.z, Rotation, Pitch); + SetHeadYaw(Rotation); + SetPitch(-Pitch); + } + + { + Vector3d BodyDistance = m_Destination - GetPosition(); + double Rotation, Pitch; + Distance.Normalize(); + VectorToEuler(BodyDistance.x, BodyDistance.y, BodyDistance.z, Rotation, Pitch); + SetYaw(Rotation); + } + } +} + + + + +int cMonster::FindFirstNonAirBlockPosition(double a_PosX, double a_PosZ) +{ + int PosY = (int)floor(GetPosY()); + + if (!g_BlockIsSolid[m_World->GetBlock((int)floor(a_PosX), PosY, (int)floor(a_PosZ))]) + { + while (!g_BlockIsSolid[m_World->GetBlock((int)floor(a_PosX), PosY, (int)floor(a_PosZ))] && (PosY > 0)) + { + PosY--; + } + + return PosY + 1; + } + else + { + while (g_BlockIsSolid[m_World->GetBlock((int)floor(a_PosX), PosY, (int)floor(a_PosZ))] && (PosY < cChunkDef::Height)) + { + PosY++; + } + + return PosY; + } } @@ -244,11 +400,13 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk) void cMonster::DoTakeDamage(TakeDamageInfo & a_TDI) { super::DoTakeDamage(a_TDI); - if((m_SoundHurt != "") && (m_Health > 0)) m_World->BroadcastSoundEffect(m_SoundHurt, (int)(GetPosX() * 8), (int)(GetPosY() * 8), (int)(GetPosZ() * 8), 1.0f, 0.8f); + + if((m_SoundHurt != "") && (m_Health > 0)) + m_World->BroadcastSoundEffect(m_SoundHurt, (int)(GetPosX() * 8), (int)(GetPosY() * 8), (int)(GetPosZ() * 8), 1.0f, 0.8f); + if (a_TDI.Attacker != NULL) { m_Target = a_TDI.Attacker; - AddReference(m_Target); } } @@ -330,55 +488,12 @@ void cMonster::KilledBy(cEntity * a_Killer) -//----State Logic - -const char *cMonster::GetState() -{ - switch(m_EMState) - { - case IDLE: return "Idle"; - case ATTACKING: return "Attacking"; - case CHASING: return "Chasing"; - default: return "Unknown"; - } -} - - - - - -// for debugging -void cMonster::SetState(const AString & a_State) -{ - if (a_State.compare("Idle") == 0) - { - m_EMState = IDLE; - } - else if (a_State.compare("Attacking") == 0) - { - m_EMState = ATTACKING; - } - else if (a_State.compare("Chasing") == 0) - { - m_EMState = CHASING; - } - else - { - LOGD("cMonster::SetState(): Invalid state"); - ASSERT(!"Invalid state"); - } -} - - - - - //Checks to see if EventSeePlayer should be fired //monster sez: Do I see the player void cMonster::CheckEventSeePlayer(void) { // TODO: Rewrite this to use cWorld's DoWithPlayers() - cPlayer * Closest = FindClosestPlayer(); + cPlayer * Closest = m_World->FindClosestPlayer(GetPosition(), m_SightDistance); if (Closest != NULL) { @@ -398,7 +513,10 @@ void cMonster::CheckEventLostPlayer(void) if (m_Target != NULL) { pos = m_Target->GetPosition(); - if ((pos - GetPosition()).Length() > m_SightDistance || LineOfSight.Trace(GetPosition(),(pos - GetPosition()), (int)(pos - GetPosition()).Length())) + if ( + ((pos - GetPosition()).Length() > m_SightDistance) || + LineOfSight.Trace(Vector3d(GetPosX(), GetPosY() + 1, GetPosZ()), (pos - GetPosition()), (int)(pos - GetPosition()).Length()) + ) { EventLosePlayer(); } @@ -418,7 +536,6 @@ void cMonster::CheckEventLostPlayer(void) void cMonster::EventSeePlayer(cEntity * a_SeenPlayer) { m_Target = a_SeenPlayer; - AddReference(m_Target); } @@ -427,7 +544,6 @@ void cMonster::EventSeePlayer(cEntity * a_SeenPlayer) void cMonster::EventLosePlayer(void) { - Dereference(m_Target); m_Target = NULL; m_EMState = IDLE; } @@ -436,27 +552,30 @@ void cMonster::EventLosePlayer(void) -// What to do if in Idle State void cMonster::InStateIdle(float a_Dt) { m_IdleInterval += a_Dt; + if (m_IdleInterval > 1) { - // at this interval the results are predictable + // At this interval the results are predictable int rem = m_World->GetTickRandomNumber(6) + 1; - // LOGD("Moving: int: %3.3f rem: %i",idle_interval,rem); - m_IdleInterval -= 1; // So nothing gets dropped when the server hangs for a few seconds - Vector3f Dist; - Dist.x = (float)(m_World->GetTickRandomNumber(10) - 5); - Dist.z = (float)(m_World->GetTickRandomNumber(10) - 5); + m_IdleInterval -= 1; // So nothing gets dropped when the server hangs for a few seconds + + Vector3d Dist; + Dist.x = (double)m_World->GetTickRandomNumber(m_SightDistance * 2) - m_SightDistance; + Dist.z = (double)m_World->GetTickRandomNumber(m_SightDistance * 2) - m_SightDistance; + if ((Dist.SqrLength() > 2) && (rem >= 3)) { - m_Destination.x = (float)(GetPosX() + Dist.x); - m_Destination.z = (float)(GetPosZ() + Dist.z); - int PosY; - if (m_World->TryGetHeight((int)m_Destination.x, (int)m_Destination.z, PosY)) + m_Destination.x = GetPosX() + Dist.x; + m_Destination.z = GetPosZ() + Dist.z; + + int NextHeight = FindFirstNonAirBlockPosition(m_Destination.x, m_Destination.z); + + if (IsNextYPosReachable(NextHeight + 1)) { - m_Destination.y = (float)PosY + 1.2f; + m_Destination.y = (double)NextHeight; MoveToPosition(m_Destination); } } @@ -505,22 +624,6 @@ void cMonster::InStateEscaping(float a_Dt) void cMonster::Attack(float a_Dt) { m_AttackInterval += a_Dt * m_AttackRate; - if ((m_Target != NULL) && (m_AttackInterval > 3.0)) - { - // Setting this higher gives us more wiggle room for attackrate - m_AttackInterval = 0.0; - ((cPawn *)m_Target)->TakeDamage(*this); - } -} - - - - - -// Checks for Players close by and if they are visible return the closest -cPlayer * cMonster::FindClosestPlayer(void) -{ - return m_World->FindClosestPlayer(GetPosition(), m_SightDistance); } @@ -536,42 +639,6 @@ void cMonster::GetMonsterConfig(const AString & a_Name) -void cMonster::SetAttackRate(int ar) -{ - m_AttackRate = (float)ar; -} - - - - - -void cMonster::SetAttackRange(float ar) -{ - m_AttackRange = ar; -} - - - - - -void cMonster::SetAttackDamage(float ad) -{ - m_AttackDamage = ad; -} - - - - - -void cMonster::SetSightDistance(float sd) -{ - m_SightDistance = sd; -} - - - - - AString cMonster::MobTypeToString(cMonster::eType a_MobType) { // Mob types aren't sorted, so we need to search linearly: @@ -635,6 +702,8 @@ cMonster::eType cMonster::StringToMobType(const AString & a_Name) cMonster::eFamily cMonster::FamilyFromType(eType a_Type) { + // Passive-agressive mobs are counted in mob spawning code as passive + switch (a_Type) { case mtBat: return mfAmbient; @@ -699,7 +768,7 @@ cMonster * cMonster::NewMonsterFromType(cMonster::eType a_MobType) case mtMagmaCube: case mtSlime: { - toReturn = new cSlime (Random.NextInt(2) + 1); + toReturn = new cSlime(Random.NextInt(2) + 1); break; } case mtSkeleton: @@ -803,6 +872,13 @@ void cMonster::HandleDaylightBurning(cChunk & a_Chunk) int RelX = (int)floor(GetPosX()) - GetChunkX() * cChunkDef::Width; int RelZ = (int)floor(GetPosZ()) - GetChunkZ() * cChunkDef::Width; + + if (!a_Chunk.IsLightValid()) + { + m_World->QueueLightChunk(GetChunkX(), GetChunkZ()); + return; + } + if ( (a_Chunk.GetSkyLight(RelX, RelY, RelZ) == 15) && // In the daylight (a_Chunk.GetBlock(RelX, RelY, RelZ) != E_BLOCK_SOULSAND) && // Not on soulsand diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index dafb33574..5f32650cf 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -10,7 +10,6 @@ -class Vector3f; class cClientHandle; class cWorld; @@ -74,8 +73,6 @@ public: enum MState{ATTACKING, IDLE, CHASING, ESCAPING} m_EMState; enum MPersonality{PASSIVE,AGGRESSIVE,COWARDLY} m_EMPersonality; - float m_SightDistance; - /** Creates the mob object. * If a_ConfigName is not empty, the configuration is loaded using GetMonsterConfig() * a_MobType is the type of the mob (also used in the protocol ( http://wiki.vg/Entities#Mobs , 2012_12_22)) @@ -100,14 +97,9 @@ public: eType GetMobType(void) const {return m_MobType; } eFamily GetMobFamily(void) const; // tolua_end - - - const char * GetState(); - void SetState(const AString & str); virtual void CheckEventSeePlayer(void); virtual void EventSeePlayer(cEntity * a_Player); - virtual cPlayer * FindClosestPlayer(); // non static is easier. also virtual so other mobs can implement their own searching algo /// Reads the monster configuration for the specified monster name and assigns it to this object. void GetMonsterConfig(const AString & a_Name); @@ -121,11 +113,11 @@ public: virtual void Attack(float a_Dt); - int GetAttackRate(){return (int)m_AttackRate;} - void SetAttackRate(int ar); - void SetAttackRange(float ar); - void SetAttackDamage(float ad); - void SetSightDistance(float sd); + int GetAttackRate() { return (int)m_AttackRate; } + void SetAttackRate(float a_AttackRate) { m_AttackRate = a_AttackRate; } + void SetAttackRange(int a_AttackRange) { m_AttackRange = a_AttackRange; } + void SetAttackDamage(int a_AttackDamage) { m_AttackDamage = a_AttackDamage; } + void SetSightDistance(int a_SightDistance) { m_SightDistance = a_SightDistance; } /// Sets whether the mob burns in daylight. Only evaluated at next burn-decision tick void SetBurnsInDaylight(bool a_BurnsInDaylight) { m_BurnsInDaylight = a_BurnsInDaylight; } @@ -159,34 +151,72 @@ public: protected: + /* ======= PATHFINDING ======= */ + + /** A pointer to the entity this mobile is aiming to reach */ cEntity * m_Target; + /** Coordinates of the next position that should be reached */ + Vector3d m_Destination; + /** Coordinates for the ultimate, final destination. */ + Vector3d m_FinalDestination; + /** Returns if the ultimate, final destination has been reached */ + bool ReachedFinalDestination(void); + + /** Stores if mobile is currently moving towards the ultimate, final destination */ + bool m_bMovingToDestination; + /** Finds the first non-air block position (not the highest, as cWorld::GetHeight does) + If current Y is nonsolid, goes down to try to find a solid block, then returns that + 1 + If current Y is solid, goes up to find first nonsolid block, and returns that */ + int FindFirstNonAirBlockPosition(double a_PosX, double a_PosZ); + + /** A semi-temporary list to store the traversed coordinates during active pathfinding so we don't visit them again */ + std::vector m_TraversedCoordinates; + /** Returns if coordinate is in the traversed list */ + bool IsCoordinateInTraversedList(Vector3i a_Coords); + + /** Finds the next place to go + This is based on the ultimate, final destination and the current position, as well as the traversed coordinates, and any environmental hazards */ + void TickPathFinding(void); + /** Finishes a pathfinding task, be it due to failure or something else */ + inline void FinishPathFinding(void) + { + m_TraversedCoordinates.clear(); + m_bMovingToDestination = false; + } + /** Sets the body yaw and head yaw/pitch based on next/ultimate destinations */ + void SetPitchAndYawFromDestination(void); + + /* ===========================*/ + float m_AttackRate; float m_IdleInterval; - Vector3f m_Destination; - bool m_bMovingToDestination; + bool m_bPassiveAggressive; float m_DestinationTime; float m_DestroyTimer; - float m_Jump; eType m_MobType; AString m_SoundHurt; AString m_SoundDeath; - float m_SeePlayerInterval; - float m_AttackDamage; - float m_AttackRange; + int m_AttackDamage; + int m_AttackRange; float m_AttackInterval; + int m_SightDistance; bool m_BurnsInDaylight; void AddRandomDropItem(cItems & a_Drops, unsigned int a_Min, unsigned int a_Max, short a_Item, short a_ItemHealth = 0); void HandleDaylightBurning(cChunk & a_Chunk); + inline bool IsNextYPosReachable(int a_PosY) + { + return (a_PosY > (int)floor(GetPosY())) && (a_PosY == (int)floor(GetPosY()) + 1); + } } ; // tolua_export diff --git a/src/Mobs/PassiveMonster.cpp b/src/Mobs/PassiveMonster.cpp index 91ceb5a53..d774d3170 100644 --- a/src/Mobs/PassiveMonster.cpp +++ b/src/Mobs/PassiveMonster.cpp @@ -2,7 +2,6 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "PassiveMonster.h" -#include "../MersenneTwister.h" #include "../World.h" @@ -36,20 +35,9 @@ void cPassiveMonster::Tick(float a_Dt, cChunk & a_Chunk) { super::Tick(a_Dt, a_Chunk); - m_SeePlayerInterval += a_Dt; - - if (m_SeePlayerInterval > 1) // Check every second + if (m_EMState == ESCAPING) { - int rem = m_World->GetTickRandomNumber(3) + 1; // Check most of the time but miss occasionally - - m_SeePlayerInterval = 0.0; - if (rem >= 2) - { - if (m_EMState == ESCAPING) - { - CheckEventLostPlayer(); - } - } + CheckEventLostPlayer(); } } diff --git a/src/Mobs/Wolf.cpp b/src/Mobs/Wolf.cpp index 3d4e97c80..483f1d193 100644 --- a/src/Mobs/Wolf.cpp +++ b/src/Mobs/Wolf.cpp @@ -108,7 +108,7 @@ void cWolf::Tick(float a_Dt, cChunk & a_Chunk) m_bMovingToDestination = false; } - cPlayer * a_Closest_Player = FindClosestPlayer(); + cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), m_SightDistance); if (a_Closest_Player != NULL) { switch (a_Closest_Player->GetEquippedItem().m_ItemType) -- cgit v1.2.3 From 1f82b6e1920d0f56cad0f7a04c81cb0cf9823a1d Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 24 Jan 2014 20:46:22 +0000 Subject: Monsters no longer check for direct line of sight --- src/Mobs/Monster.cpp | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 91ecf3b52..bd7894bf9 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -11,7 +11,6 @@ #include "../MonsterConfig.h" #include "../MersenneTwister.h" -#include "../Tracer.h" #include "../Chunk.h" #include "../FastRandom.h" @@ -506,17 +505,10 @@ void cMonster::CheckEventSeePlayer(void) void cMonster::CheckEventLostPlayer(void) -{ - Vector3f pos; - cTracer LineOfSight(GetWorld()); - +{ if (m_Target != NULL) { - pos = m_Target->GetPosition(); - if ( - ((pos - GetPosition()).Length() > m_SightDistance) || - LineOfSight.Trace(Vector3d(GetPosX(), GetPosY() + 1, GetPosZ()), (pos - GetPosition()), (int)(pos - GetPosition()).Length()) - ) + if ((m_Target->GetPosition() - GetPosition()).Length() > m_SightDistance) { EventLosePlayer(); } -- cgit v1.2.3 From 0583b9df391d3b7c8a7ff4f982c4d2e28c42fa36 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 24 Jan 2014 20:46:47 +0000 Subject: Made wolves compatible with new AI code --- src/Mobs/Wolf.cpp | 36 +++++++++++++++++++++++++----------- src/Mobs/Wolf.h | 1 + 2 files changed, 26 insertions(+), 11 deletions(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Wolf.cpp b/src/Mobs/Wolf.cpp index 483f1d193..11e3f690a 100644 --- a/src/Mobs/Wolf.cpp +++ b/src/Mobs/Wolf.cpp @@ -37,6 +37,26 @@ void cWolf::DoTakeDamage(TakeDamageInfo & a_TDI) +void cWolf::Attack(float a_Dt) +{ + UNUSED(a_Dt); + + if ((m_Target != NULL) && (m_Target->IsPlayer())) + { + if (((cPlayer *)m_Target)->GetName() != m_OwnerName) + { + super::Attack(a_Dt); + } + } + else + { + super::Attack(a_Dt); + } +} + + + + void cWolf::OnRightClicked(cPlayer & a_Player) { @@ -108,7 +128,7 @@ void cWolf::Tick(float a_Dt, cChunk & a_Chunk) m_bMovingToDestination = false; } - cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), m_SightDistance); + cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), (float)m_SightDistance); if (a_Closest_Player != NULL) { switch (a_Closest_Player->GetEquippedItem().m_ItemType) @@ -125,9 +145,7 @@ void cWolf::Tick(float a_Dt, cChunk & a_Chunk) SetIsBegging(true); m_World->BroadcastEntityMetadata(*this); } - Vector3f a_NewDestination = a_Closest_Player->GetPosition(); - a_NewDestination.y = a_NewDestination.y + 1; // Look at the head of the player, not his feet. - m_Destination = Vector3f(a_NewDestination); + m_FinalDestination = a_Closest_Player->GetPosition();; m_bMovingToDestination = false; break; } @@ -163,23 +181,19 @@ void cWolf::TickFollowPlayer() return false; } public: - Vector3f OwnerPos; + Vector3d OwnerPos; } Callback; if (m_World->DoWithPlayer(m_OwnerName, Callback)) { // The player is present in the world, follow them: double Distance = (Callback.OwnerPos - GetPosition()).Length(); - if (Distance < 3) - { - m_bMovingToDestination = false; - } - else if ((Distance > 30) && (!IsSitting())) + if ((Distance > 30) && (!IsSitting())) { TeleportToCoords(Callback.OwnerPos.x, Callback.OwnerPos.y, Callback.OwnerPos.z); } else { - m_Destination = Callback.OwnerPos; + MoveToPosition(Callback.OwnerPos); } } } diff --git a/src/Mobs/Wolf.h b/src/Mobs/Wolf.h index 040e2cf7a..9e5ad03c7 100644 --- a/src/Mobs/Wolf.h +++ b/src/Mobs/Wolf.h @@ -22,6 +22,7 @@ public: virtual void OnRightClicked(cPlayer & a_Player) override; virtual void Tick(float a_Dt, cChunk & a_Chunk) override; virtual void TickFollowPlayer(); + virtual void Attack(float a_Dt) override; // Get functions bool IsSitting (void) const { return m_IsSitting; } -- cgit v1.2.3 From f0a75f7f73effcaccc6dcb73c42fd8c9f4492dcd Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 24 Jan 2014 19:22:10 +0100 Subject: Fixed a failure in cSquid. Probably due to rounding errors the squid was querying out-of-chunk coords. --- src/Mobs/Squid.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Squid.cpp b/src/Mobs/Squid.cpp index a311108ae..5a27762ff 100644 --- a/src/Mobs/Squid.cpp +++ b/src/Mobs/Squid.cpp @@ -43,7 +43,8 @@ void cSquid::Tick(float a_Dt, cChunk & a_Chunk) } int RelX = (int)floor(Pos.x) - a_Chunk.GetPosX() * cChunkDef::Width; int RelZ = (int)floor(Pos.z) - a_Chunk.GetPosZ() * cChunkDef::Width; - if (!IsBlockWater(a_Chunk.GetBlock(RelX, RelY, RelZ)) && !IsOnFire()) + BLOCKTYPE BlockType; + if (a_Chunk.UnboundedRelGetBlockType(RelX, RelY, RelZ, BlockType) && !IsBlockWater(BlockType) && !IsOnFire()) { // Burn for 10 ticks, then decide again StartBurning(10); -- cgit v1.2.3 From bf2af73899ba678e1280aded70703a5d105d295d Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 24 Jan 2014 21:54:20 +0000 Subject: Changed a condition to IsGameMode --- src/Mobs/PassiveAggressiveMonster.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/Mobs') diff --git a/src/Mobs/PassiveAggressiveMonster.cpp b/src/Mobs/PassiveAggressiveMonster.cpp index 28de65905..4b45f9a2a 100644 --- a/src/Mobs/PassiveAggressiveMonster.cpp +++ b/src/Mobs/PassiveAggressiveMonster.cpp @@ -25,8 +25,7 @@ void cPassiveAggressiveMonster::DoTakeDamage(TakeDamageInfo & a_TDI) if ((m_Target != NULL) && (m_Target->IsPlayer())) { - cPlayer * Player = (cPlayer *) m_Target; - if (Player->GetGameMode() != 1) + if (!((cPlayer *)m_Target)->IsGameModeCreative()) { m_EMState = CHASING; } -- cgit v1.2.3 From a988063915aa288bf0183509783987941574e2ae Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 24 Jan 2014 21:55:04 +0000 Subject: Miscellaneous improvements --- src/Mobs/Monster.cpp | 9 ++++----- src/Mobs/Monster.h | 22 +++++++++------------- 2 files changed, 13 insertions(+), 18 deletions(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index bd7894bf9..3b453552b 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -74,13 +74,12 @@ cMonster::cMonster(const AString & a_ConfigName, eType a_MobType, const AString , m_AttackRate(3) , m_IdleInterval(0) , m_bMovingToDestination(false) - , m_DestinationTime( 0 ) - , m_DestroyTimer( 0 ) + , m_DestroyTimer(0) , m_MobType(a_MobType) , m_SoundHurt(a_SoundHurt) , m_SoundDeath(a_SoundDeath) - , m_AttackDamage(1.0f) - , m_AttackRange(2.0f) + , m_AttackDamage(1) + , m_AttackRange(2) , m_AttackInterval(0) , m_BurnsInDaylight(false) { @@ -492,7 +491,7 @@ void cMonster::KilledBy(cEntity * a_Killer) void cMonster::CheckEventSeePlayer(void) { // TODO: Rewrite this to use cWorld's DoWithPlayers() - cPlayer * Closest = m_World->FindClosestPlayer(GetPosition(), m_SightDistance); + cPlayer * Closest = m_World->FindClosestPlayer(GetPosition(), (float)m_SightDistance); if (Closest != NULL) { diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index 5f32650cf..c8129e63d 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -168,6 +168,11 @@ protected: If current Y is nonsolid, goes down to try to find a solid block, then returns that + 1 If current Y is solid, goes up to find first nonsolid block, and returns that */ int FindFirstNonAirBlockPosition(double a_PosX, double a_PosZ); + /** Returns if a monster can actually reach a given height by jumping */ + inline bool IsNextYPosReachable(int a_PosY) + { + return (a_PosY > (int)floor(GetPosY())) && (a_PosY == (int)floor(GetPosY()) + 1); + } /** A semi-temporary list to store the traversed coordinates during active pathfinding so we don't visit them again */ std::vector m_TraversedCoordinates; @@ -188,14 +193,9 @@ protected: /* ===========================*/ - float m_AttackRate; - float m_IdleInterval; - - bool m_bPassiveAggressive; - - float m_DestinationTime; + float m_IdleInterval; float m_DestroyTimer; eType m_MobType; @@ -203,20 +203,16 @@ protected: AString m_SoundHurt; AString m_SoundDeath; + float m_AttackRate; int m_AttackDamage; int m_AttackRange; float m_AttackInterval; int m_SightDistance; + void HandleDaylightBurning(cChunk & a_Chunk); bool m_BurnsInDaylight; - void AddRandomDropItem(cItems & a_Drops, unsigned int a_Min, unsigned int a_Max, short a_Item, short a_ItemHealth = 0); - - void HandleDaylightBurning(cChunk & a_Chunk); - inline bool IsNextYPosReachable(int a_PosY) - { - return (a_PosY > (int)floor(GetPosY())) && (a_PosY == (int)floor(GetPosY()) + 1); - } + void AddRandomDropItem(cItems & a_Drops, unsigned int a_Min, unsigned int a_Max, short a_Item, short a_ItemHealth = 0); } ; // tolua_export -- cgit v1.2.3 From b367a74d3e56927e3a1f55738fb13abd6d667814 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 24 Jan 2014 23:56:05 +0000 Subject: Zombies and skeletons use AI --- src/Mobs/Skeleton.cpp | 11 +++++++---- src/Mobs/Zombie.cpp | 13 ++++++++----- 2 files changed, 15 insertions(+), 9 deletions(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Skeleton.cpp b/src/Mobs/Skeleton.cpp index 509c2191e..4c8e78988 100644 --- a/src/Mobs/Skeleton.cpp +++ b/src/Mobs/Skeleton.cpp @@ -30,15 +30,18 @@ void cSkeleton::GetDrops(cItems & a_Drops, cEntity * a_Killer) void cSkeleton::MoveToPosition(const Vector3f & a_Position) { - m_Destination = a_Position; - // If the destination is in the sun and if it is not night AND the skeleton isn't on fire then block the movement. - if (!IsOnFire() && m_World->GetTimeOfDay() < 13187 && m_World->GetBlockSkyLight((int) a_Position.x, (int) a_Position.y, (int) a_Position.z) == 15) + if ( + !IsOnFire() && + (m_World->GetTimeOfDay() < 13187) && + (m_World->GetBlockSkyLight((int) a_Position.x, (int) a_Position.y, (int) a_Position.z) == 15) + ) { m_bMovingToDestination = false; return; } - m_bMovingToDestination = true; + + super::MoveToPosition(a_Position); } diff --git a/src/Mobs/Zombie.cpp b/src/Mobs/Zombie.cpp index a046fcc92..27e8ed5fb 100644 --- a/src/Mobs/Zombie.cpp +++ b/src/Mobs/Zombie.cpp @@ -34,15 +34,18 @@ void cZombie::GetDrops(cItems & a_Drops, cEntity * a_Killer) void cZombie::MoveToPosition(const Vector3f & a_Position) { - m_Destination = a_Position; - - // If the destination is in the sun and if it is not night AND the skeleton isn't on fire then block the movement. - if ((m_World->GetBlockSkyLight((int) a_Position.x, (int) a_Position.y, (int) a_Position.z) == 15) && (m_World->GetTimeOfDay() < 13187) && !IsOnFire()) + // If the destination is in the sun and if it is not night AND the zombie isn't on fire then block the movement. + if ( + !IsOnFire() && + (m_World->GetTimeOfDay() < 13187) && + (m_World->GetBlockSkyLight((int)a_Position.x, (int)a_Position.y, (int)a_Position.z) == 15) + ) { m_bMovingToDestination = false; return; } - m_bMovingToDestination = true; + + super::MoveToPosition(a_Position); } -- cgit v1.2.3 From 1112f5adc6f66195ae030673e7831e46ae06c7b0 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 24 Jan 2014 23:56:19 +0000 Subject: Fixed a generator bug --- src/Mobs/Monster.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/Mobs') diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 3b453552b..1db16ab71 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -249,6 +249,9 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk) return; } + if ((m_Target != NULL) && m_Target->IsDestroyed()) + m_Target = NULL; + // Burning in daylight HandleDaylightBurning(a_Chunk); -- cgit v1.2.3 From fd7fc7e59efebd6b28012c8e8433f53ac853c555 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 24 Jan 2014 23:58:51 +0000 Subject: All mobs now drown (fixes #54) * Implemented mob drowning * Iron Golems and squids are excluded --- src/Mobs/IronGolem.h | 4 ++++ src/Mobs/Squid.h | 3 +++ 2 files changed, 7 insertions(+) (limited to 'src/Mobs') diff --git a/src/Mobs/IronGolem.h b/src/Mobs/IronGolem.h index d49ff4cab..41c60438c 100644 --- a/src/Mobs/IronGolem.h +++ b/src/Mobs/IronGolem.h @@ -18,6 +18,10 @@ public: CLASS_PROTODEF(cIronGolem); virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + + // Iron golems do not drown + virtual void HandleAir(void) override {} + virtual void SetSwimState(cChunk & a_Chunk) override {} } ; diff --git a/src/Mobs/Squid.h b/src/Mobs/Squid.h index ad299b95c..a9dba8b70 100644 --- a/src/Mobs/Squid.h +++ b/src/Mobs/Squid.h @@ -21,6 +21,9 @@ public: virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + // Squids do not drown (or float) + virtual void HandleAir(void) override {} + virtual void SetSwimState(cChunk & a_Chunk) override {} } ; -- cgit v1.2.3 From 314fc3cdac702a44a257ada5fab52f0a7d37ffcd Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 25 Jan 2014 14:42:26 +0000 Subject: Mob bugfixes * Mobs no longer require constant line-of-sight to a player to remain aggravated * Fixed an ASSERT * Fixed mobs jumping * Fixed Idle state not properly using AI + Added FILE_IO_PREFIX to favicon loading + Implemented #563 --- src/Mobs/Monster.cpp | 49 +++++++++++++++++++++++++++++-------------------- src/Mobs/Monster.h | 12 ++++++++++-- 2 files changed, 39 insertions(+), 22 deletions(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 1db16ab71..9ba18f4d1 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -259,6 +259,17 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk) if (m_bMovingToDestination) { + if (m_bOnGround) + { + int NextHeight = FindFirstNonAirBlockPosition(m_Destination.x, m_Destination.z); + + if (DoesPosYRequireJump(NextHeight)) + { + m_bOnGround = false; + AddPosY(1.5); // Jump!! + } + } + Vector3f Distance = m_Destination - GetPosition(); if(!ReachedDestination() && !ReachedFinalDestination()) // If we haven't reached any sort of destination, move { @@ -285,17 +296,6 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk) TickPathFinding(); // We have reached the next point in our path, calculate another point } } - - if(m_bOnGround) - { - int NextHeight = FindFirstNonAirBlockPosition(m_Destination.x, m_Destination.z); - - if (IsNextYPosReachable(NextHeight)) - { - m_bOnGround = false; - SetSpeedY(5.f); // Jump!! - } - } } if (ReachedFinalDestination()) @@ -373,6 +373,11 @@ int cMonster::FindFirstNonAirBlockPosition(double a_PosX, double a_PosZ) { int PosY = (int)floor(GetPosY()); + if (PosY < 0) + PosY = 0; + else if (PosY > cChunkDef::Height) + PosY = cChunkDef::Height; + if (!g_BlockIsSolid[m_World->GetBlock((int)floor(a_PosX), PosY, (int)floor(a_PosZ))]) { while (!g_BlockIsSolid[m_World->GetBlock((int)floor(a_PosX), PosY, (int)floor(a_PosZ))] && (PosY > 0)) @@ -494,7 +499,7 @@ void cMonster::KilledBy(cEntity * a_Killer) void cMonster::CheckEventSeePlayer(void) { // TODO: Rewrite this to use cWorld's DoWithPlayers() - cPlayer * Closest = m_World->FindClosestPlayer(GetPosition(), (float)m_SightDistance); + cPlayer * Closest = m_World->FindClosestPlayer(GetPosition(), (float)m_SightDistance, false); if (Closest != NULL) { @@ -548,6 +553,11 @@ void cMonster::EventLosePlayer(void) void cMonster::InStateIdle(float a_Dt) { + if (m_bMovingToDestination) + { + return; // Still getting there + } + m_IdleInterval += a_Dt; if (m_IdleInterval > 1) @@ -557,20 +567,19 @@ void cMonster::InStateIdle(float a_Dt) m_IdleInterval -= 1; // So nothing gets dropped when the server hangs for a few seconds Vector3d Dist; - Dist.x = (double)m_World->GetTickRandomNumber(m_SightDistance * 2) - m_SightDistance; - Dist.z = (double)m_World->GetTickRandomNumber(m_SightDistance * 2) - m_SightDistance; + Dist.x = (double)m_World->GetTickRandomNumber(10) - 5; + Dist.z = (double)m_World->GetTickRandomNumber(10) - 5; if ((Dist.SqrLength() > 2) && (rem >= 3)) { - m_Destination.x = GetPosX() + Dist.x; - m_Destination.z = GetPosZ() + Dist.z; + Vector3d Destination(GetPosX() + Dist.x, 0, GetPosZ() + Dist.z); - int NextHeight = FindFirstNonAirBlockPosition(m_Destination.x, m_Destination.z); + int NextHeight = FindFirstNonAirBlockPosition(Destination.x, Destination.z); - if (IsNextYPosReachable(NextHeight + 1)) + if (IsNextYPosReachable(NextHeight)) { - m_Destination.y = (double)NextHeight; - MoveToPosition(m_Destination); + Destination.y = NextHeight; + MoveToPosition(Destination); } } } diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index c8129e63d..d04cb8941 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -168,10 +168,18 @@ protected: If current Y is nonsolid, goes down to try to find a solid block, then returns that + 1 If current Y is solid, goes up to find first nonsolid block, and returns that */ int FindFirstNonAirBlockPosition(double a_PosX, double a_PosZ); - /** Returns if a monster can actually reach a given height by jumping */ + /** Returns if a monster can actually reach a given height by jumping or walking */ inline bool IsNextYPosReachable(int a_PosY) { - return (a_PosY > (int)floor(GetPosY())) && (a_PosY == (int)floor(GetPosY()) + 1); + return ( + (a_PosY <= (int)floor(GetPosY())) || + DoesPosYRequireJump(a_PosY) + ); + } + /** Returns if a monster can reach a given height by jumping */ + inline bool DoesPosYRequireJump(int a_PosY) + { + return ((a_PosY > (int)floor(GetPosY())) && (a_PosY == (int)floor(GetPosY()) + 1)); } /** A semi-temporary list to store the traversed coordinates during active pathfinding so we don't visit them again */ -- cgit v1.2.3 From 60b7f5f23d117d48f230f80371b2adf13b85a09e Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 25 Jan 2014 19:00:50 +0000 Subject: Attack() is no longer always called --- src/Mobs/AggressiveMonster.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/Mobs') diff --git a/src/Mobs/AggressiveMonster.cpp b/src/Mobs/AggressiveMonster.cpp index a4b3eede1..f2f0c404c 100644 --- a/src/Mobs/AggressiveMonster.cpp +++ b/src/Mobs/AggressiveMonster.cpp @@ -50,9 +50,9 @@ void cAggressiveMonster::InStateChasing(float a_Dt) void cAggressiveMonster::EventSeePlayer(cEntity * a_Entity) { - super::EventSeePlayer(a_Entity); if (!((cPlayer *)a_Entity)->IsGameModeCreative()) { + super::EventSeePlayer(a_Entity); m_EMState = CHASING; } } -- cgit v1.2.3 From 7468ba0f107ed01275f346c87ff5bb265dbbff3d Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 25 Jan 2014 19:02:13 +0000 Subject: Implemented fall damage for mobs + Implemented mobile fall damage * Formatting fixes + Defined new Position->Integer macros --- src/Mobs/Monster.cpp | 31 +++++++++++++++++++++++++++---- src/Mobs/Monster.h | 8 ++++++-- 2 files changed, 33 insertions(+), 6 deletions(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 9ba18f4d1..42c7d2899 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -82,6 +82,7 @@ cMonster::cMonster(const AString & a_ConfigName, eType a_MobType, const AString , m_AttackRange(2) , m_AttackInterval(0) , m_BurnsInDaylight(false) + , m_LastGroundHeight(POSY_TOINT) { if (!a_ConfigName.empty()) { @@ -113,7 +114,7 @@ void cMonster::TickPathFinding() std::vector m_PotentialCoordinates; m_TraversedCoordinates.push_back(Vector3i(PosX, PosY, PosZ)); - static const struct // Define which directions the torch can power + static const struct // Define which directions to try to move to { int x, z; } gCrossCoords[] = @@ -261,9 +262,9 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk) { if (m_bOnGround) { - int NextHeight = FindFirstNonAirBlockPosition(m_Destination.x, m_Destination.z); + m_Destination.y = FindFirstNonAirBlockPosition(m_Destination.x, m_Destination.z); - if (DoesPosYRequireJump(NextHeight)) + if (DoesPosYRequireJump(m_Destination.y)) { m_bOnGround = false; AddPosY(1.5); // Jump!! @@ -298,10 +299,11 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk) } } - if (ReachedFinalDestination()) + if (ReachedFinalDestination() && (m_Target != NULL)) Attack(a_Dt); SetPitchAndYawFromDestination(); + HandleFalling(); switch (m_EMState) { @@ -369,6 +371,27 @@ void cMonster::SetPitchAndYawFromDestination() +void cMonster::HandleFalling() +{ + if (m_bOnGround) + { + int Damage = (m_LastGroundHeight - POSY_TOINT) - 3; + + if (Damage > 0) + { + TakeDamage(dtFalling, NULL, Damage, Damage, 0); + + // Fall particles + GetWorld()->BroadcastSoundParticleEffect(2006, POSX_TOINT, POSY_TOINT - 1, POSZ_TOINT, Damage /* Used as particle effect speed modifier */); + } + + m_LastGroundHeight = (int)floor(GetPosY()); + } +} + + + + int cMonster::FindFirstNonAirBlockPosition(double a_PosX, double a_PosZ) { int PosY = (int)floor(GetPosY()); diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index d04cb8941..1dd302cdc 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -199,9 +199,13 @@ protected: /** Sets the body yaw and head yaw/pitch based on next/ultimate destinations */ void SetPitchAndYawFromDestination(void); - /* ===========================*/ + /* =========================== */ + /* ========= FALLING ========= */ - + virtual void HandleFalling(void); + int m_LastGroundHeight; + + /* =========================== */ float m_IdleInterval; float m_DestroyTimer; -- cgit v1.2.3 From 7b8dc01db32be3d780f38ffbe788500f82983d62 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 25 Jan 2014 21:19:52 +0100 Subject: Implemented sheeps eating grass. --- src/Mobs/Sheep.cpp | 39 ++++++++++++++++++++++++++++++++++++++- src/Mobs/Sheep.h | 3 +++ 2 files changed, 41 insertions(+), 1 deletion(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Sheep.cpp b/src/Mobs/Sheep.cpp index bda4ccff8..702108ae4 100644 --- a/src/Mobs/Sheep.cpp +++ b/src/Mobs/Sheep.cpp @@ -13,7 +13,8 @@ cSheep::cSheep(int a_Color) : super("Sheep", mtSheep, "mob.sheep.say", "mob.sheep.say", 0.6, 1.3), m_IsSheared(false), - m_WoolColor(a_Color) + m_WoolColor(a_Color), + m_TimeToStopEating(-1) { } @@ -60,3 +61,39 @@ void cSheep::OnRightClicked(cPlayer & a_Player) m_World->BroadcastEntityMetadata(*this); } } + + + + + +void cSheep::Tick(float a_Dt, cChunk & a_Chunk) +{ + // The sheep should not move when he's eating so only handle the physics. + if (m_TimeToStopEating > 0) + { + HandlePhysics(a_Dt, a_Chunk); + m_TimeToStopEating--; + if (m_TimeToStopEating == 0) + { + if (m_World->GetBlock((int) GetPosX(), (int) GetPosY() - 1, (int) GetPosZ()) == E_BLOCK_GRASS) + { + // The sheep ate the grass so we change it to dirt. + m_World->SetBlock((int) GetPosX(), (int) GetPosY() - 1, (int) GetPosZ(), E_BLOCK_DIRT, 0); + m_IsSheared = false; + m_World->BroadcastEntityMetadata(*this); + } + } + } + else + { + super::Tick(a_Dt, a_Chunk); + if (m_World->GetTickRandomNumber(600) == 1) + { + if (m_World->GetBlock((int) GetPosX(), (int) GetPosY() - 1, (int) GetPosZ()) == E_BLOCK_GRASS) + { + m_World->BroadcastEntityStatus(*this, 10); + m_TimeToStopEating = 40; + } + } + } +} diff --git a/src/Mobs/Sheep.h b/src/Mobs/Sheep.h index 8293a2c05..4eee3db1c 100644 --- a/src/Mobs/Sheep.h +++ b/src/Mobs/Sheep.h @@ -19,6 +19,8 @@ public: virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; virtual void OnRightClicked(cPlayer & a_Player) override; + virtual void Tick(float a_Dt, cChunk & a_Chunk) override; + bool IsSheared(void) const { return m_IsSheared; } int GetFurColor(void) const { return m_WoolColor; } @@ -26,6 +28,7 @@ private: bool m_IsSheared; int m_WoolColor; + int m_TimeToStopEating; } ; -- cgit v1.2.3 From cdd6478ceacb7cf5bab8f425390372fca7883a1e Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 25 Jan 2014 21:29:27 +0000 Subject: Did what xoft recommended --- src/Mobs/Creeper.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Creeper.cpp b/src/Mobs/Creeper.cpp index ad8fe10a1..2e1ece865 100644 --- a/src/Mobs/Creeper.cpp +++ b/src/Mobs/Creeper.cpp @@ -89,4 +89,8 @@ void cCreeper::Attack(float a_Dt) m_World->DoExplosionAt((m_bIsCharged ? 5 : 3), GetPosX(), GetPosY(), GetPosZ(), false, esMonster, this); Destroy(); } -} \ No newline at end of file +} + + + + -- cgit v1.2.3 From 70113b57309060b785b070bb2a0075801bc4d844 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 26 Jan 2014 00:14:00 +0000 Subject: Fixed segmentation fault on villager damage It occurred when attack was environmental. --- src/Mobs/Villager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Villager.cpp b/src/Mobs/Villager.cpp index 7f89fb6cc..c8ff4f101 100644 --- a/src/Mobs/Villager.cpp +++ b/src/Mobs/Villager.cpp @@ -21,7 +21,7 @@ cVillager::cVillager(eVillagerType VillagerType) : void cVillager::DoTakeDamage(TakeDamageInfo & a_TDI) { super::DoTakeDamage(a_TDI); - if (a_TDI.Attacker->IsPlayer()) + if ((a_TDI.Attacker != NULL) && a_TDI.Attacker->IsPlayer()) { if (m_World->GetTickRandomNumber(5) == 3) { -- cgit v1.2.3 From a533386144f234dcfb61ad6bc5341712ea244afd Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 26 Jan 2014 13:07:21 +0100 Subject: Small fix since the new AI and a new small feature. You get particles when trying to tame wolfs. They don't walk anymore when they are sitting. --- src/Mobs/Wolf.cpp | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Wolf.cpp b/src/Mobs/Wolf.cpp index 11e3f690a..217834eb1 100644 --- a/src/Mobs/Wolf.cpp +++ b/src/Mobs/Wolf.cpp @@ -75,10 +75,12 @@ void cWolf::OnRightClicked(cPlayer & a_Player) SetIsTame(true); SetOwner(a_Player.GetName()); m_World->BroadcastEntityStatus(*this, ENTITY_STATUS_WOLF_TAMED); + m_World->BroadcastParticleEffect("heart", (float) GetPosX(), (float) GetPosY(), (float) GetPosZ(), 0, 0, 0, 0, 5); } else { m_World->BroadcastEntityStatus(*this, ENTITY_STATUS_WOLF_TAMING); + m_World->BroadcastParticleEffect("smoke", (float) GetPosX(), (float) GetPosY(), (float) GetPosZ(), 0, 0, 0, 0, 5); } } } @@ -122,7 +124,8 @@ void cWolf::Tick(float a_Dt, cChunk & a_Chunk) { super::Tick(a_Dt, a_Chunk); } - + + // The wolf is sitting so don't move him at all. if (IsSitting()) { m_bMovingToDestination = false; @@ -145,8 +148,18 @@ void cWolf::Tick(float a_Dt, cChunk & a_Chunk) SetIsBegging(true); m_World->BroadcastEntityMetadata(*this); } - m_FinalDestination = a_Closest_Player->GetPosition();; - m_bMovingToDestination = false; + // Don't move to the player if the wolf is sitting. + if (IsSitting()) + { + m_bMovingToDestination = false; + } + else + { + m_bMovingToDestination = true; + } + Vector3d PlayerPos = a_Closest_Player->GetPosition(); + PlayerPos.y++; + m_FinalDestination = PlayerPos; break; } default: @@ -185,15 +198,23 @@ void cWolf::TickFollowPlayer() } Callback; if (m_World->DoWithPlayer(m_OwnerName, Callback)) { - // The player is present in the world, follow them: + // The player is present in the world, follow him: double Distance = (Callback.OwnerPos - GetPosition()).Length(); - if ((Distance > 30) && (!IsSitting())) + if (Distance > 30) { TeleportToCoords(Callback.OwnerPos.x, Callback.OwnerPos.y, Callback.OwnerPos.z); } else { - MoveToPosition(Callback.OwnerPos); + m_FinalDestination = Callback.OwnerPos; + if (IsSitting()) + { + m_bMovingToDestination = false; + } + else + { + m_bMovingToDestination = true; + } } } } -- cgit v1.2.3 From 4c780e7b4490c34694e9f76e6944d5959299eb84 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 26 Jan 2014 13:27:35 +0100 Subject: Fixed bug where wolfs would teleport while they were sitting. --- src/Mobs/Wolf.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Wolf.cpp b/src/Mobs/Wolf.cpp index 217834eb1..c0c7892e3 100644 --- a/src/Mobs/Wolf.cpp +++ b/src/Mobs/Wolf.cpp @@ -202,7 +202,10 @@ void cWolf::TickFollowPlayer() double Distance = (Callback.OwnerPos - GetPosition()).Length(); if (Distance > 30) { - TeleportToCoords(Callback.OwnerPos.x, Callback.OwnerPos.y, Callback.OwnerPos.z); + if (!IsSitting()) + { + TeleportToCoords(Callback.OwnerPos.x, Callback.OwnerPos.y, Callback.OwnerPos.z); + } } else { -- cgit v1.2.3 From ed95f4d81b3f54111430aec00d429aff267dfa92 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 27 Jan 2014 14:40:31 +0100 Subject: Makes farmers farm crops. --- src/Mobs/Villager.cpp | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++- src/Mobs/Villager.h | 5 ++++ 2 files changed, 76 insertions(+), 1 deletion(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Villager.cpp b/src/Mobs/Villager.cpp index c8ff4f101..0bf87157a 100644 --- a/src/Mobs/Villager.cpp +++ b/src/Mobs/Villager.cpp @@ -3,6 +3,8 @@ #include "Villager.h" #include "../World.h" +#include "../Blockarea.h" +#include "../Blocks/BlockHandler.h" @@ -10,7 +12,8 @@ cVillager::cVillager(eVillagerType VillagerType) : super("Villager", mtVillager, "", "", 0.6, 1.8), - m_Type(VillagerType) + m_Type(VillagerType), + m_DidFindCrops(false) { } @@ -33,3 +36,70 @@ void cVillager::DoTakeDamage(TakeDamageInfo & a_TDI) + +void cVillager::Tick(float a_Dt, cChunk & a_Chunk) +{ + super::Tick(a_Dt, a_Chunk); + if (m_DidFindCrops) + { + Vector3i Pos = Vector3i(GetPosition()); + std::cout << Pos.Equals(m_CropsPos) << "\n"; + if (Pos.Equals(m_CropsPos)) + { + cBlockHandler Handler(E_BLOCK_CROPS); + Handler.DropBlock(m_World, this, m_CropsPos.x, m_CropsPos.y, m_CropsPos.z); + m_DidFindCrops = false; + } + } + + if (m_World->GetTickRandomNumber(50) != 0) + { + return; + } + + switch (m_Type) + { + case vtFarmer: + { + HandleFarmer(); + } + } + +} + + + + +void cVillager::HandleFarmer() +{ + cBlockArea Surrounding; + Surrounding.Read(m_World, + (int) GetPosX() - 5, + (int) GetPosX() + 5, + (int) GetPosY() - 3, + (int) GetPosY() + 3, + (int) GetPosZ() - 5, + (int) GetPosZ() + 5); + + // Check for crops in a 10x6x10 area. + for (int X = 0; X < 10; X++) + { + for (int Y = 0; Y < 6; Y++) + { + for (int Z = 0; Z < 10; Z++) + { + if (Surrounding.GetRelBlockType(X, Y, Z) == E_BLOCK_CROPS && Surrounding.GetRelBlockMeta(X, Y, Z) == 0x7) + { + m_DidFindCrops = true; + m_CropsPos = Vector3i((int) GetPosX() + X - 5, (int) GetPosY() + Y - 3, (int) GetPosZ() + Z - 5); + MoveToPosition(Vector3f((float) GetPosX() + X - 5, (float) GetPosY() + Y - 3, (float) GetPosZ() + Z - 5)); + return; + } + } + } + } +} + + + + diff --git a/src/Mobs/Villager.h b/src/Mobs/Villager.h index 4cd9aaa8e..b7cbe8ed0 100644 --- a/src/Mobs/Villager.h +++ b/src/Mobs/Villager.h @@ -30,11 +30,16 @@ public: CLASS_PROTODEF(cVillager); virtual void DoTakeDamage(TakeDamageInfo & a_TDI) override; + virtual void Tick (float a_Dt, cChunk & a_Chunk) override; + + void HandleFarmer(); int GetVilType(void) const { return m_Type; } private: int m_Type; + bool m_DidFindCrops; + Vector3i m_CropsPos; } ; -- cgit v1.2.3 From 969bf05a2686a24ccae6838d2cb9b3b2a0c55111 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 27 Jan 2014 15:44:55 +0100 Subject: Villagers: Farmers can also harvest carrots and potatoes. --- src/Mobs/Villager.cpp | 46 +++++++++++++++++++++++++++++++++++++--------- src/Mobs/Villager.h | 1 + 2 files changed, 38 insertions(+), 9 deletions(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Villager.cpp b/src/Mobs/Villager.cpp index 0bf87157a..71907f6b7 100644 --- a/src/Mobs/Villager.cpp +++ b/src/Mobs/Villager.cpp @@ -43,11 +43,19 @@ void cVillager::Tick(float a_Dt, cChunk & a_Chunk) if (m_DidFindCrops) { Vector3i Pos = Vector3i(GetPosition()); - std::cout << Pos.Equals(m_CropsPos) << "\n"; if (Pos.Equals(m_CropsPos)) { - cBlockHandler Handler(E_BLOCK_CROPS); - Handler.DropBlock(m_World, this, m_CropsPos.x, m_CropsPos.y, m_CropsPos.z); + BLOCKTYPE CropBlock = m_World->GetBlock(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z); + if (IsBlockFarmable(CropBlock) && m_World->GetBlockMeta(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z) == 0x7) + { + cItems Pickups; + //Pickups.Add(E_ITEM_WHEAT, 1, 0); + //Pickups.Add(E_ITEM_SEEDS, 1 + m_World->GetTickRandomNumber( + cBlockHandler Handler(CropBlock); + Handler.ConvertToPickups(Pickups, 0x7); + m_World->SpawnItemPickups(Pickups, m_CropsPos.x + 0.5, m_CropsPos.y + 0.5, m_CropsPos.z + 0.5); + m_World->SetBlock(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z, E_BLOCK_AIR, 0); + } m_DidFindCrops = false; } } @@ -64,7 +72,6 @@ void cVillager::Tick(float a_Dt, cChunk & a_Chunk) HandleFarmer(); } } - } @@ -88,13 +95,19 @@ void cVillager::HandleFarmer() { for (int Z = 0; Z < 10; Z++) { - if (Surrounding.GetRelBlockType(X, Y, Z) == E_BLOCK_CROPS && Surrounding.GetRelBlockMeta(X, Y, Z) == 0x7) + if (!IsBlockFarmable(Surrounding.GetRelBlockType(X, Y, Z))) { - m_DidFindCrops = true; - m_CropsPos = Vector3i((int) GetPosX() + X - 5, (int) GetPosY() + Y - 3, (int) GetPosZ() + Z - 5); - MoveToPosition(Vector3f((float) GetPosX() + X - 5, (float) GetPosY() + Y - 3, (float) GetPosZ() + Z - 5)); - return; + continue; } + if (Surrounding.GetRelBlockMeta(X, Y, Z) != 0x7) + { + continue; + } + + m_DidFindCrops = true; + m_CropsPos = Vector3i((int) GetPosX() + X - 5, (int) GetPosY() + Y - 3, (int) GetPosZ() + Z - 5); + MoveToPosition(Vector3f((float) (m_CropsPos.x + 0.5), (float) (m_CropsPos.y), (float) (m_CropsPos.z + 0.5))); + return; } } } @@ -103,3 +116,18 @@ void cVillager::HandleFarmer() + +bool cVillager::IsBlockFarmable(BLOCKTYPE a_BlockType) +{ + switch (a_BlockType) + { + case E_BLOCK_CROPS: + case E_BLOCK_POTATOES: + case E_BLOCK_CARROTS: + { + return true; + } + } + return false; +} + diff --git a/src/Mobs/Villager.h b/src/Mobs/Villager.h index b7cbe8ed0..9502f387c 100644 --- a/src/Mobs/Villager.h +++ b/src/Mobs/Villager.h @@ -33,6 +33,7 @@ public: virtual void Tick (float a_Dt, cChunk & a_Chunk) override; void HandleFarmer(); + bool IsBlockFarmable(BLOCKTYPE a_BlockType); int GetVilType(void) const { return m_Type; } private: -- cgit v1.2.3 From ca12decaf60bc7d6a32ee45c1a796edcde076e86 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 27 Jan 2014 17:20:39 +0100 Subject: Villagers don't look for new crops when they already found one. Slight cleanup. --- src/Mobs/Villager.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Villager.cpp b/src/Mobs/Villager.cpp index 71907f6b7..b42c3ecaa 100644 --- a/src/Mobs/Villager.cpp +++ b/src/Mobs/Villager.cpp @@ -40,24 +40,19 @@ void cVillager::DoTakeDamage(TakeDamageInfo & a_TDI) void cVillager::Tick(float a_Dt, cChunk & a_Chunk) { super::Tick(a_Dt, a_Chunk); - if (m_DidFindCrops) + if (m_DidFindCrops && !m_bMovingToDestination) { - Vector3i Pos = Vector3i(GetPosition()); - if (Pos.Equals(m_CropsPos)) + if ((GetPosition() - m_CropsPos).Length() < 2) { BLOCKTYPE CropBlock = m_World->GetBlock(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z); if (IsBlockFarmable(CropBlock) && m_World->GetBlockMeta(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z) == 0x7) { - cItems Pickups; - //Pickups.Add(E_ITEM_WHEAT, 1, 0); - //Pickups.Add(E_ITEM_SEEDS, 1 + m_World->GetTickRandomNumber( cBlockHandler Handler(CropBlock); - Handler.ConvertToPickups(Pickups, 0x7); - m_World->SpawnItemPickups(Pickups, m_CropsPos.x + 0.5, m_CropsPos.y + 0.5, m_CropsPos.z + 0.5); + Handler.DropBlock(m_World, this, m_CropsPos.x, m_CropsPos.y, m_CropsPos.z); m_World->SetBlock(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z, E_BLOCK_AIR, 0); } - m_DidFindCrops = false; } + m_DidFindCrops = false; } if (m_World->GetTickRandomNumber(50) != 0) @@ -69,7 +64,10 @@ void cVillager::Tick(float a_Dt, cChunk & a_Chunk) { case vtFarmer: { - HandleFarmer(); + if (!m_DidFindCrops) + { + HandleFarmer(); + } } } } @@ -106,7 +104,7 @@ void cVillager::HandleFarmer() m_DidFindCrops = true; m_CropsPos = Vector3i((int) GetPosX() + X - 5, (int) GetPosY() + Y - 3, (int) GetPosZ() + Z - 5); - MoveToPosition(Vector3f((float) (m_CropsPos.x + 0.5), (float) (m_CropsPos.y), (float) (m_CropsPos.z + 0.5))); + MoveToPosition(Vector3f((float) (m_CropsPos.x + 0.5), (float) m_CropsPos.y, (float) (m_CropsPos.z + 0.5))); return; } } -- cgit v1.2.3 From 2cdd8f1961252da2723e7a1047e91ec4914eef57 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 27 Jan 2014 17:30:18 +0100 Subject: Villagers: Fixed only gettings the crops block when farming. --- src/Mobs/Villager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Villager.cpp b/src/Mobs/Villager.cpp index b42c3ecaa..4d358e0a6 100644 --- a/src/Mobs/Villager.cpp +++ b/src/Mobs/Villager.cpp @@ -47,8 +47,8 @@ void cVillager::Tick(float a_Dt, cChunk & a_Chunk) BLOCKTYPE CropBlock = m_World->GetBlock(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z); if (IsBlockFarmable(CropBlock) && m_World->GetBlockMeta(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z) == 0x7) { - cBlockHandler Handler(CropBlock); - Handler.DropBlock(m_World, this, m_CropsPos.x, m_CropsPos.y, m_CropsPos.z); + cBlockHandler * Handler = cBlockHandler::GetBlockHandler(CropBlock); + Handler->DropBlock(m_World, this, m_CropsPos.x, m_CropsPos.y, m_CropsPos.z); m_World->SetBlock(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z, E_BLOCK_AIR, 0); } } -- cgit v1.2.3 From 06c3bc1ea5e20c3ddc88f66631f675523789f398 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 27 Jan 2014 18:27:57 +0100 Subject: Villagers: Farmers now replant the crops. --- src/Mobs/Villager.cpp | 17 ++++++++++++++++- src/Mobs/Villager.h | 1 + 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Villager.cpp b/src/Mobs/Villager.cpp index 4d358e0a6..f52d60ffa 100644 --- a/src/Mobs/Villager.cpp +++ b/src/Mobs/Villager.cpp @@ -13,7 +13,8 @@ cVillager::cVillager(eVillagerType VillagerType) : super("Villager", mtVillager, "", "", 0.6, 1.8), m_Type(VillagerType), - m_DidFindCrops(false) + m_DidFindCrops(false), + m_ActionCountDown(-1) { } @@ -40,6 +41,19 @@ void cVillager::DoTakeDamage(TakeDamageInfo & a_TDI) void cVillager::Tick(float a_Dt, cChunk & a_Chunk) { super::Tick(a_Dt, a_Chunk); + if (m_ActionCountDown > -1) + { + m_ActionCountDown--; + if (m_ActionCountDown == 0) + { + switch (m_Type) + { + case vtFarmer: m_World->SetBlock(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z, E_BLOCK_CROPS, 0); + } + } + return; + } + if (m_DidFindCrops && !m_bMovingToDestination) { if ((GetPosition() - m_CropsPos).Length() < 2) @@ -50,6 +64,7 @@ void cVillager::Tick(float a_Dt, cChunk & a_Chunk) cBlockHandler * Handler = cBlockHandler::GetBlockHandler(CropBlock); Handler->DropBlock(m_World, this, m_CropsPos.x, m_CropsPos.y, m_CropsPos.z); m_World->SetBlock(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z, E_BLOCK_AIR, 0); + m_ActionCountDown = 20; } } m_DidFindCrops = false; diff --git a/src/Mobs/Villager.h b/src/Mobs/Villager.h index 9502f387c..bdbcab39b 100644 --- a/src/Mobs/Villager.h +++ b/src/Mobs/Villager.h @@ -38,6 +38,7 @@ public: private: + int m_ActionCountDown; int m_Type; bool m_DidFindCrops; Vector3i m_CropsPos; -- cgit v1.2.3 From 9807056a9cfcce00cf5c33ce6eae25f818ec9cf7 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 27 Jan 2014 18:33:57 +0100 Subject: Added GetCropsPos and DidFindCrops functions. --- src/Mobs/Villager.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/Mobs') diff --git a/src/Mobs/Villager.h b/src/Mobs/Villager.h index bdbcab39b..235e1f40e 100644 --- a/src/Mobs/Villager.h +++ b/src/Mobs/Villager.h @@ -29,12 +29,18 @@ public: CLASS_PROTODEF(cVillager); + // Override functions virtual void DoTakeDamage(TakeDamageInfo & a_TDI) override; virtual void Tick (float a_Dt, cChunk & a_Chunk) override; + // cVillager functions void HandleFarmer(); bool IsBlockFarmable(BLOCKTYPE a_BlockType); + + // Get and set functions. int GetVilType(void) const { return m_Type; } + Vector3i GetCropsPos(void) const { return m_CropsPos; } + bool DidFindCrops(void) const { return m_DidFindCrops; } private: -- cgit v1.2.3 From 3dbe6c6de941873461951fc2fa8dc1be9d199768 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 27 Jan 2014 18:58:09 +0100 Subject: Villager: Farmer: Crops finding is more random. --- src/Mobs/Villager.cpp | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Villager.cpp b/src/Mobs/Villager.cpp index f52d60ffa..31e6e87a0 100644 --- a/src/Mobs/Villager.cpp +++ b/src/Mobs/Villager.cpp @@ -101,29 +101,30 @@ void cVillager::HandleFarmer() (int) GetPosZ() - 5, (int) GetPosZ() + 5); - // Check for crops in a 10x6x10 area. - for (int X = 0; X < 10; X++) + + for (int I = 0; I < 5; I++) { for (int Y = 0; Y < 6; Y++) { - for (int Z = 0; Z < 10; Z++) + // Pick random coordinates and check for crops. + int X = m_World->GetTickRandomNumber(11); + int Z = m_World->GetTickRandomNumber(11); + + if (!IsBlockFarmable(Surrounding.GetRelBlockType(X, Y, Z))) { - if (!IsBlockFarmable(Surrounding.GetRelBlockType(X, Y, Z))) - { - continue; - } - if (Surrounding.GetRelBlockMeta(X, Y, Z) != 0x7) - { - continue; - } - - m_DidFindCrops = true; - m_CropsPos = Vector3i((int) GetPosX() + X - 5, (int) GetPosY() + Y - 3, (int) GetPosZ() + Z - 5); - MoveToPosition(Vector3f((float) (m_CropsPos.x + 0.5), (float) m_CropsPos.y, (float) (m_CropsPos.z + 0.5))); - return; + continue; } - } - } + if (Surrounding.GetRelBlockMeta(X, Y, Z) != 0x7) + { + continue; + } + + m_DidFindCrops = true; + m_CropsPos = Vector3i((int) GetPosX() + X - 5, (int) GetPosY() + Y - 3, (int) GetPosZ() + Z - 5); + MoveToPosition(Vector3f((float) (m_CropsPos.x + 0.5), (float) m_CropsPos.y, (float) (m_CropsPos.z + 0.5))); + return; + } // for Y loop. + } // Repeat the procces 5 times. } -- cgit v1.2.3 From 9cf006eceafac87aa7fc5d74ee3eed3740f95b60 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 27 Jan 2014 19:06:50 +0100 Subject: Fixed compiler error. --- src/Mobs/Villager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Villager.cpp b/src/Mobs/Villager.cpp index 31e6e87a0..ef362b559 100644 --- a/src/Mobs/Villager.cpp +++ b/src/Mobs/Villager.cpp @@ -3,7 +3,7 @@ #include "Villager.h" #include "../World.h" -#include "../Blockarea.h" +#include "../BlockArea.h" #include "../Blocks/BlockHandler.h" -- cgit v1.2.3 From 5b983b72fa0508fee5135153c9273f5e37fb5467 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 27 Jan 2014 20:44:18 +0100 Subject: Villager: Farmers can't place crops on blocks other then farmland. --- src/Mobs/Villager.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Villager.cpp b/src/Mobs/Villager.cpp index ef362b559..5d6d7482f 100644 --- a/src/Mobs/Villager.cpp +++ b/src/Mobs/Villager.cpp @@ -48,7 +48,13 @@ void cVillager::Tick(float a_Dt, cChunk & a_Chunk) { switch (m_Type) { - case vtFarmer: m_World->SetBlock(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z, E_BLOCK_CROPS, 0); + case vtFarmer: + { + if (m_World->GetBlock(m_CropsPos.x, m_CropsPos.y - 1, m_CropsPos.z) == E_BLOCK_FARMLAND) + { + m_World->SetBlock(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z, E_BLOCK_CROPS, 0); + } + } } } return; -- cgit v1.2.3 From 723bb78dd144a34adae5502b4d526ab887b911d5 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 27 Jan 2014 20:52:42 +0100 Subject: Villagers: Harvesting is more rare. --- src/Mobs/Villager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Villager.cpp b/src/Mobs/Villager.cpp index 5d6d7482f..46346fa9f 100644 --- a/src/Mobs/Villager.cpp +++ b/src/Mobs/Villager.cpp @@ -76,7 +76,7 @@ void cVillager::Tick(float a_Dt, cChunk & a_Chunk) m_DidFindCrops = false; } - if (m_World->GetTickRandomNumber(50) != 0) + if (m_World->GetTickRandomNumber(100) != 0) { return; } -- cgit v1.2.3 From 33ad2761a0acb79ce938ebf518a731264617c03d Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 27 Jan 2014 21:34:22 +0100 Subject: Cleanup Most code in Tick is now split up in different functions. --- src/Mobs/Villager.cpp | 86 ++++++++++++++++++++++++++++++++++----------------- src/Mobs/Villager.h | 10 ++++-- 2 files changed, 65 insertions(+), 31 deletions(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Villager.cpp b/src/Mobs/Villager.cpp index 46346fa9f..e39d8bc1f 100644 --- a/src/Mobs/Villager.cpp +++ b/src/Mobs/Villager.cpp @@ -13,7 +13,7 @@ cVillager::cVillager(eVillagerType VillagerType) : super("Villager", mtVillager, "", "", 0.6, 1.8), m_Type(VillagerType), - m_DidFindCrops(false), + m_VillagerAction(false), m_ActionCountDown(-1) { } @@ -50,33 +50,33 @@ void cVillager::Tick(float a_Dt, cChunk & a_Chunk) { case vtFarmer: { - if (m_World->GetBlock(m_CropsPos.x, m_CropsPos.y - 1, m_CropsPos.z) == E_BLOCK_FARMLAND) - { - m_World->SetBlock(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z, E_BLOCK_CROPS, 0); - } + HandleFarmerNoCountDown(); } } } return; } - if (m_DidFindCrops && !m_bMovingToDestination) + if (m_VillagerAction) { - if ((GetPosition() - m_CropsPos).Length() < 2) + switch (m_Type) { - BLOCKTYPE CropBlock = m_World->GetBlock(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z); - if (IsBlockFarmable(CropBlock) && m_World->GetBlockMeta(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z) == 0x7) + case vtFarmer: { - cBlockHandler * Handler = cBlockHandler::GetBlockHandler(CropBlock); - Handler->DropBlock(m_World, this, m_CropsPos.x, m_CropsPos.y, m_CropsPos.z); - m_World->SetBlock(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z, E_BLOCK_AIR, 0); - m_ActionCountDown = 20; + HandleFarmerAction(); } } - m_DidFindCrops = false; + m_VillagerAction = false; } - if (m_World->GetTickRandomNumber(100) != 0) + // The villager already has an special action activated. + if (m_VillagerAction) + { + return; + } + + // Don't always try to do a special action. Each tick has 1% to do a special action. + if (m_World->GetTickRandomNumber(99) != 0) { return; } @@ -85,10 +85,7 @@ void cVillager::Tick(float a_Dt, cChunk & a_Chunk) { case vtFarmer: { - if (!m_DidFindCrops) - { - HandleFarmer(); - } + HandleFarmerAttemptSpecialAction(); } } } @@ -96,16 +93,19 @@ void cVillager::Tick(float a_Dt, cChunk & a_Chunk) -void cVillager::HandleFarmer() +void cVillager::HandleFarmerAttemptSpecialAction() { cBlockArea Surrounding; - Surrounding.Read(m_World, - (int) GetPosX() - 5, - (int) GetPosX() + 5, - (int) GetPosY() - 3, - (int) GetPosY() + 3, - (int) GetPosZ() - 5, - (int) GetPosZ() + 5); + /// Read a 11x7x11 area. + Surrounding.Read( + m_World, + (int) GetPosX() - 5, + (int) GetPosX() + 5, + (int) GetPosY() - 3, + (int) GetPosY() + 3, + (int) GetPosZ() - 5, + (int) GetPosZ() + 5 + ); for (int I = 0; I < 5; I++) @@ -125,7 +125,7 @@ void cVillager::HandleFarmer() continue; } - m_DidFindCrops = true; + m_VillagerAction = true; m_CropsPos = Vector3i((int) GetPosX() + X - 5, (int) GetPosY() + Y - 3, (int) GetPosZ() + Z - 5); MoveToPosition(Vector3f((float) (m_CropsPos.x + 0.5), (float) m_CropsPos.y, (float) (m_CropsPos.z + 0.5))); return; @@ -137,6 +137,36 @@ void cVillager::HandleFarmer() +void cVillager::HandleFarmerAction() +{ + if (!m_bMovingToDestination && (GetPosition() - m_CropsPos).Length() < 2) + { + BLOCKTYPE CropBlock = m_World->GetBlock(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z); + if (IsBlockFarmable(CropBlock) && m_World->GetBlockMeta(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z) == 0x7) + { + cBlockHandler * Handler = cBlockHandler::GetBlockHandler(CropBlock); + Handler->DropBlock(m_World, this, m_CropsPos.x, m_CropsPos.y, m_CropsPos.z); + m_World->SetBlock(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z, E_BLOCK_AIR, 0); + m_ActionCountDown = 20; + } + } +} + + + + +void cVillager::HandleFarmerNoCountDown() +{ + if (m_World->GetBlock(m_CropsPos.x, m_CropsPos.y - 1, m_CropsPos.z) == E_BLOCK_FARMLAND) + { + m_World->SetBlock(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z, E_BLOCK_CROPS, 0); + } +} + + + + + bool cVillager::IsBlockFarmable(BLOCKTYPE a_BlockType) { switch (a_BlockType) diff --git a/src/Mobs/Villager.h b/src/Mobs/Villager.h index 235e1f40e..20dbada61 100644 --- a/src/Mobs/Villager.h +++ b/src/Mobs/Villager.h @@ -34,19 +34,23 @@ public: virtual void Tick (float a_Dt, cChunk & a_Chunk) override; // cVillager functions - void HandleFarmer(); bool IsBlockFarmable(BLOCKTYPE a_BlockType); + // Farmer functions + void HandleFarmerAttemptSpecialAction(); + void HandleFarmerAction(); + void HandleFarmerNoCountDown(); + // Get and set functions. int GetVilType(void) const { return m_Type; } Vector3i GetCropsPos(void) const { return m_CropsPos; } - bool DidFindCrops(void) const { return m_DidFindCrops; } + bool DoesHaveActionActivated(void) const { return m_VillagerAction; } private: int m_ActionCountDown; int m_Type; - bool m_DidFindCrops; + bool m_VillagerAction; Vector3i m_CropsPos; } ; -- cgit v1.2.3 From 8bf9043f98900a870c18389fe367e156da6b9f6c Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 27 Jan 2014 21:39:00 +0100 Subject: Villager: Few more comments. --- src/Mobs/Villager.cpp | 11 ++++++++--- src/Mobs/Villager.h | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Villager.cpp b/src/Mobs/Villager.cpp index e39d8bc1f..262f13a99 100644 --- a/src/Mobs/Villager.cpp +++ b/src/Mobs/Villager.cpp @@ -50,7 +50,7 @@ void cVillager::Tick(float a_Dt, cChunk & a_Chunk) { case vtFarmer: { - HandleFarmerNoCountDown(); + HandleFarmerEndCountDown(); } } } @@ -93,6 +93,8 @@ void cVillager::Tick(float a_Dt, cChunk & a_Chunk) +//////////////////////////////////////////////////////////////////////////////// +// Farmer functions. void cVillager::HandleFarmerAttemptSpecialAction() { cBlockArea Surrounding; @@ -107,7 +109,6 @@ void cVillager::HandleFarmerAttemptSpecialAction() (int) GetPosZ() + 5 ); - for (int I = 0; I < 5; I++) { for (int Y = 0; Y < 6; Y++) @@ -116,6 +117,7 @@ void cVillager::HandleFarmerAttemptSpecialAction() int X = m_World->GetTickRandomNumber(11); int Z = m_World->GetTickRandomNumber(11); + // A villager can't farm this. if (!IsBlockFarmable(Surrounding.GetRelBlockType(X, Y, Z))) { continue; @@ -139,8 +141,10 @@ void cVillager::HandleFarmerAttemptSpecialAction() void cVillager::HandleFarmerAction() { + // Harvest the crops if the villager isn't moving and if the crops are closer then 2 blocks. if (!m_bMovingToDestination && (GetPosition() - m_CropsPos).Length() < 2) { + // Check if the blocks didn't change while the villager was walking to the coordinates. BLOCKTYPE CropBlock = m_World->GetBlock(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z); if (IsBlockFarmable(CropBlock) && m_World->GetBlockMeta(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z) == 0x7) { @@ -155,8 +159,9 @@ void cVillager::HandleFarmerAction() -void cVillager::HandleFarmerNoCountDown() +void cVillager::HandleFarmerEndCountDown() { + // Check if there is still farmland at the spot where the crops were. if (m_World->GetBlock(m_CropsPos.x, m_CropsPos.y - 1, m_CropsPos.z) == E_BLOCK_FARMLAND) { m_World->SetBlock(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z, E_BLOCK_CROPS, 0); diff --git a/src/Mobs/Villager.h b/src/Mobs/Villager.h index 20dbada61..979d2a3ac 100644 --- a/src/Mobs/Villager.h +++ b/src/Mobs/Villager.h @@ -39,7 +39,7 @@ public: // Farmer functions void HandleFarmerAttemptSpecialAction(); void HandleFarmerAction(); - void HandleFarmerNoCountDown(); + void HandleFarmerEndCountDown(); // Get and set functions. int GetVilType(void) const { return m_Type; } -- cgit v1.2.3 From babc80ed777f2ee74ce770d95bd3ec5743370570 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 27 Jan 2014 22:02:19 +0100 Subject: The world can now be configured wether farmers should be able to harvest crops. --- src/Mobs/Villager.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/Mobs') diff --git a/src/Mobs/Villager.cpp b/src/Mobs/Villager.cpp index 262f13a99..74a2a6d99 100644 --- a/src/Mobs/Villager.cpp +++ b/src/Mobs/Villager.cpp @@ -141,6 +141,11 @@ void cVillager::HandleFarmerAttemptSpecialAction() void cVillager::HandleFarmerAction() { + if (!m_World->VillagersShouldHarvestCrops()) + { + return; + } + // Harvest the crops if the villager isn't moving and if the crops are closer then 2 blocks. if (!m_bMovingToDestination && (GetPosition() - m_CropsPos).Length() < 2) { @@ -161,6 +166,11 @@ void cVillager::HandleFarmerAction() void cVillager::HandleFarmerEndCountDown() { + if (!m_World->VillagersShouldHarvestCrops()) + { + return; + } + // Check if there is still farmland at the spot where the crops were. if (m_World->GetBlock(m_CropsPos.x, m_CropsPos.y - 1, m_CropsPos.z) == E_BLOCK_FARMLAND) { -- cgit v1.2.3 From 807a4dba989ad397c5f624f0a245df55103ee117 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 27 Jan 2014 22:04:24 +0100 Subject: Villager doesn't check the environment for crops if it doesn't need to. --- src/Mobs/Villager.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/Mobs') diff --git a/src/Mobs/Villager.cpp b/src/Mobs/Villager.cpp index 74a2a6d99..4a3cce26e 100644 --- a/src/Mobs/Villager.cpp +++ b/src/Mobs/Villager.cpp @@ -97,6 +97,11 @@ void cVillager::Tick(float a_Dt, cChunk & a_Chunk) // Farmer functions. void cVillager::HandleFarmerAttemptSpecialAction() { + if (!m_World->VillagersShouldHarvestCrops()) + { + return; + } + cBlockArea Surrounding; /// Read a 11x7x11 area. Surrounding.Read( -- cgit v1.2.3 From b2bacf3a25001ed855319d6f2146a3d5e734f43c Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Tue, 28 Jan 2014 15:40:13 +0100 Subject: Villager: NoCountDown and Action function don't check VillagersShouldHarvestCrops anymore because it shoudn't even be activated anywhere. --- src/Mobs/Villager.cpp | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Villager.cpp b/src/Mobs/Villager.cpp index 4a3cce26e..021d4c672 100644 --- a/src/Mobs/Villager.cpp +++ b/src/Mobs/Villager.cpp @@ -146,11 +146,6 @@ void cVillager::HandleFarmerAttemptSpecialAction() void cVillager::HandleFarmerAction() { - if (!m_World->VillagersShouldHarvestCrops()) - { - return; - } - // Harvest the crops if the villager isn't moving and if the crops are closer then 2 blocks. if (!m_bMovingToDestination && (GetPosition() - m_CropsPos).Length() < 2) { @@ -171,11 +166,6 @@ void cVillager::HandleFarmerAction() void cVillager::HandleFarmerEndCountDown() { - if (!m_World->VillagersShouldHarvestCrops()) - { - return; - } - // Check if there is still farmland at the spot where the crops were. if (m_World->GetBlock(m_CropsPos.x, m_CropsPos.y - 1, m_CropsPos.z) == E_BLOCK_FARMLAND) { -- cgit v1.2.3 From 8ca98e0c0e09706561ed54cf8be95a731157a59e Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Tue, 28 Jan 2014 16:26:44 +0100 Subject: Renamed Farmer functions and added doxycomments --- src/Mobs/Villager.cpp | 18 +++++++----------- src/Mobs/Villager.h | 19 +++++++++++++------ 2 files changed, 20 insertions(+), 17 deletions(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Villager.cpp b/src/Mobs/Villager.cpp index 021d4c672..44ec14295 100644 --- a/src/Mobs/Villager.cpp +++ b/src/Mobs/Villager.cpp @@ -41,6 +41,7 @@ void cVillager::DoTakeDamage(TakeDamageInfo & a_TDI) void cVillager::Tick(float a_Dt, cChunk & a_Chunk) { super::Tick(a_Dt, a_Chunk); + if (m_ActionCountDown > -1) { m_ActionCountDown--; @@ -50,7 +51,7 @@ void cVillager::Tick(float a_Dt, cChunk & a_Chunk) { case vtFarmer: { - HandleFarmerEndCountDown(); + HandleFarmerPlaceCrops(); } } } @@ -63,15 +64,10 @@ void cVillager::Tick(float a_Dt, cChunk & a_Chunk) { case vtFarmer: { - HandleFarmerAction(); + HandleFarmerTryHarvestCrops(); } } m_VillagerAction = false; - } - - // The villager already has an special action activated. - if (m_VillagerAction) - { return; } @@ -85,7 +81,7 @@ void cVillager::Tick(float a_Dt, cChunk & a_Chunk) { case vtFarmer: { - HandleFarmerAttemptSpecialAction(); + HandleFarmerPrepareFarmCrops(); } } } @@ -95,7 +91,7 @@ void cVillager::Tick(float a_Dt, cChunk & a_Chunk) //////////////////////////////////////////////////////////////////////////////// // Farmer functions. -void cVillager::HandleFarmerAttemptSpecialAction() +void cVillager::HandleFarmerPrepareFarmCrops() { if (!m_World->VillagersShouldHarvestCrops()) { @@ -144,7 +140,7 @@ void cVillager::HandleFarmerAttemptSpecialAction() -void cVillager::HandleFarmerAction() +void cVillager::HandleFarmerTryHarvestCrops() { // Harvest the crops if the villager isn't moving and if the crops are closer then 2 blocks. if (!m_bMovingToDestination && (GetPosition() - m_CropsPos).Length() < 2) @@ -164,7 +160,7 @@ void cVillager::HandleFarmerAction() -void cVillager::HandleFarmerEndCountDown() +void cVillager::HandleFarmerPlaceCrops() { // Check if there is still farmland at the spot where the crops were. if (m_World->GetBlock(m_CropsPos.x, m_CropsPos.y - 1, m_CropsPos.z) == E_BLOCK_FARMLAND) diff --git a/src/Mobs/Villager.h b/src/Mobs/Villager.h index 979d2a3ac..b99ae876f 100644 --- a/src/Mobs/Villager.h +++ b/src/Mobs/Villager.h @@ -34,17 +34,24 @@ public: virtual void Tick (float a_Dt, cChunk & a_Chunk) override; // cVillager functions + /** return true if the given blocktype are: crops, potatoes or carrots.*/ bool IsBlockFarmable(BLOCKTYPE a_BlockType); + ////////////////////////////////////////////////////////////////// // Farmer functions - void HandleFarmerAttemptSpecialAction(); - void HandleFarmerAction(); - void HandleFarmerEndCountDown(); + /** It searches in a 11x7x11 area for crops. If it found some it will navigate to them.*/ + void HandleFarmerPrepareFarmCrops(); + + /** Looks if the farmer has reached it's destination, and if it's still crops and the destination is closer then 2 blocks it will harvest them.*/ + void HandleFarmerTryHarvestCrops(); + + /** Replaces the crops he harvested.*/ + void HandleFarmerPlaceCrops(); // Get and set functions. - int GetVilType(void) const { return m_Type; } - Vector3i GetCropsPos(void) const { return m_CropsPos; } - bool DoesHaveActionActivated(void) const { return m_VillagerAction; } + int GetVilType(void) const { return m_Type; } + Vector3i GetCropsPos(void) const { return m_CropsPos; } + bool DoesHaveActionActivated(void) const { return m_VillagerAction; } private: -- cgit v1.2.3 From ebe0f9372fa8787b3fe709937ebd3af30810f910 Mon Sep 17 00:00:00 2001 From: tonibm19 Date: Wed, 29 Jan 2014 18:08:33 +0100 Subject: Now mobs follow you when holding their breed item --- src/Mobs/Chicken.cpp | 25 ++++++++++++++++++++++++- src/Mobs/Chicken.h | 3 +++ src/Mobs/Cow.cpp | 28 ++++++++++++++++++++++++++-- src/Mobs/Cow.h | 8 ++++++++ src/Mobs/Mooshroom.cpp | 27 +++++++++++++++++++++++++++ src/Mobs/Mooshroom.h | 8 ++++++++ src/Mobs/Pig.cpp | 27 ++++++++++++++++++++++++++- src/Mobs/Pig.h | 4 ++++ src/Mobs/Sheep.cpp | 24 ++++++++++++++++++++++++ src/Mobs/Sheep.h | 4 +++- 10 files changed, 153 insertions(+), 5 deletions(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Chicken.cpp b/src/Mobs/Chicken.cpp index 087fd088a..52c8d3788 100644 --- a/src/Mobs/Chicken.cpp +++ b/src/Mobs/Chicken.cpp @@ -2,7 +2,7 @@ #include "Chicken.h" #include "../World.h" - +#include "../Entities/Player.h" @@ -41,6 +41,29 @@ void cChicken::Tick(float a_Dt, cChunk & a_Chunk) { m_EggDropTimer++; } + cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), (float)m_SightDistance); + if (a_Closest_Player != NULL) + { + if (a_Closest_Player->GetEquippedItem().m_ItemType == E_ITEM_SEEDS) + { + if (!IsBegging()) + { + m_IsBegging = true; + m_World->BroadcastEntityMetadata(*this); + } + Vector3d PlayerPos = a_Closest_Player->GetPosition(); + PlayerPos.y++; + m_FinalDestination = PlayerPos; + } + else + { + if (IsBegging()) + { + m_IsBegging = false; + m_World->BroadcastEntityMetadata(*this); + } + } + } } diff --git a/src/Mobs/Chicken.h b/src/Mobs/Chicken.h index 979c4d8a0..b9cff40d4 100644 --- a/src/Mobs/Chicken.h +++ b/src/Mobs/Chicken.h @@ -19,10 +19,13 @@ public: virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; virtual void Tick(float a_Dt, cChunk & a_Chunk) override; + bool IsBegging (void) const { return m_IsBegging; } + private: int m_EggDropTimer; + bool m_IsBegging; } ; diff --git a/src/Mobs/Cow.cpp b/src/Mobs/Cow.cpp index 9eb74dac2..205ecc73f 100644 --- a/src/Mobs/Cow.cpp +++ b/src/Mobs/Cow.cpp @@ -41,5 +41,29 @@ void cCow::OnRightClicked(cPlayer & a_Player) } } - - +void cCow::Tick(float a_Dt, cChunk & a_Chunk) +{ + cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), (float)m_SightDistance); + if (a_Closest_Player != NULL) + { + if (a_Closest_Player->GetEquippedItem().m_ItemType == E_ITEM_WHEAT) + { + if (!IsBegging()) + { + m_IsBegging = true; + m_World->BroadcastEntityMetadata(*this); + } + Vector3d PlayerPos = a_Closest_Player->GetPosition(); + PlayerPos.y++; + m_FinalDestination = PlayerPos; + } + else + { + if (IsBegging()) + { + m_IsBegging = false; + m_World->BroadcastEntityMetadata(*this); + } + } + } +} diff --git a/src/Mobs/Cow.h b/src/Mobs/Cow.h index 0391d4a31..b001ea856 100644 --- a/src/Mobs/Cow.h +++ b/src/Mobs/Cow.h @@ -19,6 +19,14 @@ public: virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; virtual void OnRightClicked(cPlayer & a_Player) override; + virtual void Tick(float a_Dt, cChunk & a_Chunk) override; + + bool IsBegging (void) const { return m_IsBegging; } + +private: + + bool m_IsBegging; + } ; diff --git a/src/Mobs/Mooshroom.cpp b/src/Mobs/Mooshroom.cpp index 940e2db44..1ff90392d 100644 --- a/src/Mobs/Mooshroom.cpp +++ b/src/Mobs/Mooshroom.cpp @@ -2,6 +2,7 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Mooshroom.h" +#include "../Entities/Player.h" @@ -29,5 +30,31 @@ void cMooshroom::GetDrops(cItems & a_Drops, cEntity * a_Killer) } +void cMooshroom::Tick(float a_Dt, cChunk & a_Chunk) +{ + cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), (float)m_SightDistance); + if (a_Closest_Player != NULL) + { + if (a_Closest_Player->GetEquippedItem().m_ItemType == E_ITEM_WHEAT) + { + if (!IsBegging()) + { + m_IsBegging = true; + m_World->BroadcastEntityMetadata(*this); + } + Vector3d PlayerPos = a_Closest_Player->GetPosition(); + PlayerPos.y++; + m_FinalDestination = PlayerPos; + } + else + { + if (IsBegging()) + { + m_IsBegging = false; + m_World->BroadcastEntityMetadata(*this); + } + } + } +} diff --git a/src/Mobs/Mooshroom.h b/src/Mobs/Mooshroom.h index 73f6348b6..c288f68a9 100644 --- a/src/Mobs/Mooshroom.h +++ b/src/Mobs/Mooshroom.h @@ -18,6 +18,14 @@ public: CLASS_PROTODEF(cMooshroom); virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void Tick(float a_Dt, cChunk & a_Chunk) override; + + bool IsBegging (void) const { return m_IsBegging; } + +private: + + bool m_IsBegging; + } ; diff --git a/src/Mobs/Pig.cpp b/src/Mobs/Pig.cpp index 0871a38a9..e31bc90ba 100644 --- a/src/Mobs/Pig.cpp +++ b/src/Mobs/Pig.cpp @@ -71,7 +71,32 @@ void cPig::OnRightClicked(cPlayer & a_Player) } } - +void cPig::Tick(float a_Dt, cChunk & a_Chunk) +{ + cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), (float)m_SightDistance); + if (a_Closest_Player != NULL) + { + if (a_Closest_Player->GetEquippedItem().m_ItemType == E_ITEM_CARROT) + { + if (!IsBegging()) + { + m_IsBegging = true; + m_World->BroadcastEntityMetadata(*this); + } + Vector3d PlayerPos = a_Closest_Player->GetPosition(); + PlayerPos.y++; + m_FinalDestination = PlayerPos; + } + else + { + if (IsBegging()) + { + m_IsBegging = false; + m_World->BroadcastEntityMetadata(*this); + } + } + } +} diff --git a/src/Mobs/Pig.h b/src/Mobs/Pig.h index 4fd0d8db8..f42a4f412 100644 --- a/src/Mobs/Pig.h +++ b/src/Mobs/Pig.h @@ -19,10 +19,14 @@ public: virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; virtual void OnRightClicked(cPlayer & a_Player) override; + virtual void Tick(float a_Dt, cChunk & a_Chunk) override; + bool IsSaddled(void) const { return m_bIsSaddled; } + bool IsBegging (void) const { return m_IsBegging; } private: + bool m_IsBegging; bool m_bIsSaddled; } ; diff --git a/src/Mobs/Sheep.cpp b/src/Mobs/Sheep.cpp index 702108ae4..3fb9351ad 100644 --- a/src/Mobs/Sheep.cpp +++ b/src/Mobs/Sheep.cpp @@ -96,4 +96,28 @@ void cSheep::Tick(float a_Dt, cChunk & a_Chunk) } } } + cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), (float)m_SightDistance); + if (a_Closest_Player != NULL) + { + if (a_Closest_Player->GetEquippedItem().m_ItemType == E_ITEM_WHEAT) + { + if (!IsBegging()) + { + m_IsBegging = true; + m_World->BroadcastEntityMetadata(*this); + } + Vector3d PlayerPos = a_Closest_Player->GetPosition(); + PlayerPos.y++; + m_FinalDestination = PlayerPos; + } + else + { + if (IsBegging()) + { + m_IsBegging = false; + m_World->BroadcastEntityMetadata(*this); + } + } + } } + diff --git a/src/Mobs/Sheep.h b/src/Mobs/Sheep.h index 4eee3db1c..322b31dd9 100644 --- a/src/Mobs/Sheep.h +++ b/src/Mobs/Sheep.h @@ -21,11 +21,13 @@ public: virtual void OnRightClicked(cPlayer & a_Player) override; virtual void Tick(float a_Dt, cChunk & a_Chunk) override; + bool IsBegging(void) const { return m_IsBegging; } bool IsSheared(void) const { return m_IsSheared; } int GetFurColor(void) const { return m_WoolColor; } private: - + + bool m_IsBegging; bool m_IsSheared; int m_WoolColor; int m_TimeToStopEating; -- cgit v1.2.3 From 73d9a285d511a3cd1016aafc8c492924e6a7b249 Mon Sep 17 00:00:00 2001 From: tonibm19 Date: Wed, 29 Jan 2014 18:25:10 +0100 Subject: Fixed a copypasta error... --- src/Mobs/Cow.cpp | 3 ++- src/Mobs/Mooshroom.cpp | 1 + src/Mobs/Pig.cpp | 1 + src/Mobs/Sheep.cpp | 1 + 4 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Cow.cpp b/src/Mobs/Cow.cpp index 205ecc73f..4063f034d 100644 --- a/src/Mobs/Cow.cpp +++ b/src/Mobs/Cow.cpp @@ -42,7 +42,8 @@ void cCow::OnRightClicked(cPlayer & a_Player) } void cCow::Tick(float a_Dt, cChunk & a_Chunk) -{ +{ + super::Tick(a_Dt, a_Chunk); cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), (float)m_SightDistance); if (a_Closest_Player != NULL) { diff --git a/src/Mobs/Mooshroom.cpp b/src/Mobs/Mooshroom.cpp index 1ff90392d..60721f0ee 100644 --- a/src/Mobs/Mooshroom.cpp +++ b/src/Mobs/Mooshroom.cpp @@ -32,6 +32,7 @@ void cMooshroom::GetDrops(cItems & a_Drops, cEntity * a_Killer) void cMooshroom::Tick(float a_Dt, cChunk & a_Chunk) { + super::Tick(a_Dt, a_Chunk); cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), (float)m_SightDistance); if (a_Closest_Player != NULL) { diff --git a/src/Mobs/Pig.cpp b/src/Mobs/Pig.cpp index e31bc90ba..b6d11d856 100644 --- a/src/Mobs/Pig.cpp +++ b/src/Mobs/Pig.cpp @@ -73,6 +73,7 @@ void cPig::OnRightClicked(cPlayer & a_Player) void cPig::Tick(float a_Dt, cChunk & a_Chunk) { + super::Tick(a_Dt, a_Chunk); cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), (float)m_SightDistance); if (a_Closest_Player != NULL) { diff --git a/src/Mobs/Sheep.cpp b/src/Mobs/Sheep.cpp index 3fb9351ad..2478ec79c 100644 --- a/src/Mobs/Sheep.cpp +++ b/src/Mobs/Sheep.cpp @@ -68,6 +68,7 @@ void cSheep::OnRightClicked(cPlayer & a_Player) void cSheep::Tick(float a_Dt, cChunk & a_Chunk) { + super::Tick(a_Dt, a_Chunk); // The sheep should not move when he's eating so only handle the physics. if (m_TimeToStopEating > 0) { -- cgit v1.2.3 From ba4865f7ee99490ff46d4b584ffa0ae85fa21aae Mon Sep 17 00:00:00 2001 From: tonibm19 Date: Wed, 29 Jan 2014 18:32:46 +0100 Subject: Fixed sheep --- src/Mobs/Sheep.cpp | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Sheep.cpp b/src/Mobs/Sheep.cpp index 2478ec79c..c8ff8f5c8 100644 --- a/src/Mobs/Sheep.cpp +++ b/src/Mobs/Sheep.cpp @@ -68,7 +68,6 @@ void cSheep::OnRightClicked(cPlayer & a_Player) void cSheep::Tick(float a_Dt, cChunk & a_Chunk) { - super::Tick(a_Dt, a_Chunk); // The sheep should not move when he's eating so only handle the physics. if (m_TimeToStopEating > 0) { @@ -96,27 +95,27 @@ void cSheep::Tick(float a_Dt, cChunk & a_Chunk) m_TimeToStopEating = 40; } } - } - cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), (float)m_SightDistance); - if (a_Closest_Player != NULL) - { - if (a_Closest_Player->GetEquippedItem().m_ItemType == E_ITEM_WHEAT) + cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), (float)m_SightDistance); + if (a_Closest_Player != NULL) { - if (!IsBegging()) + if (a_Closest_Player->GetEquippedItem().m_ItemType == E_ITEM_WHEAT) { - m_IsBegging = true; - m_World->BroadcastEntityMetadata(*this); + if (!IsBegging()) + { + m_IsBegging = true; + m_World->BroadcastEntityMetadata(*this); + } + Vector3d PlayerPos = a_Closest_Player->GetPosition(); + PlayerPos.y++; + m_FinalDestination = PlayerPos; } - Vector3d PlayerPos = a_Closest_Player->GetPosition(); - PlayerPos.y++; - m_FinalDestination = PlayerPos; - } - else - { - if (IsBegging()) + else { - m_IsBegging = false; - m_World->BroadcastEntityMetadata(*this); + if (IsBegging()) + { + m_IsBegging = false; + m_World->BroadcastEntityMetadata(*this); + } } } } -- cgit v1.2.3 From 1c1832b6ce08de71e6a46187420d91eacb18d16e Mon Sep 17 00:00:00 2001 From: tonibm19 Date: Wed, 29 Jan 2014 19:15:26 +0100 Subject: Rewritten code. Implemented xoft suggestion. Using MoveToPosition as tigerw suggested. --- src/Mobs/Chicken.cpp | 23 ----------------------- src/Mobs/Chicken.h | 4 +--- src/Mobs/Cow.cpp | 27 --------------------------- src/Mobs/Cow.h | 7 +------ src/Mobs/Mooshroom.cpp | 28 ---------------------------- src/Mobs/Mooshroom.h | 8 +------- src/Mobs/PassiveMonster.cpp | 16 +++++++++++++++- src/Mobs/PassiveMonster.h | 2 ++ src/Mobs/Pig.cpp | 28 ---------------------------- src/Mobs/Pig.h | 5 ++--- src/Mobs/Sheep.cpp | 23 ----------------------- src/Mobs/Sheep.h | 6 +++--- 12 files changed, 25 insertions(+), 152 deletions(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Chicken.cpp b/src/Mobs/Chicken.cpp index 52c8d3788..90d56d1de 100644 --- a/src/Mobs/Chicken.cpp +++ b/src/Mobs/Chicken.cpp @@ -41,29 +41,6 @@ void cChicken::Tick(float a_Dt, cChunk & a_Chunk) { m_EggDropTimer++; } - cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), (float)m_SightDistance); - if (a_Closest_Player != NULL) - { - if (a_Closest_Player->GetEquippedItem().m_ItemType == E_ITEM_SEEDS) - { - if (!IsBegging()) - { - m_IsBegging = true; - m_World->BroadcastEntityMetadata(*this); - } - Vector3d PlayerPos = a_Closest_Player->GetPosition(); - PlayerPos.y++; - m_FinalDestination = PlayerPos; - } - else - { - if (IsBegging()) - { - m_IsBegging = false; - m_World->BroadcastEntityMetadata(*this); - } - } - } } diff --git a/src/Mobs/Chicken.h b/src/Mobs/Chicken.h index b9cff40d4..a4c1d6b9e 100644 --- a/src/Mobs/Chicken.h +++ b/src/Mobs/Chicken.h @@ -19,13 +19,11 @@ public: virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; virtual void Tick(float a_Dt, cChunk & a_Chunk) override; - bool IsBegging (void) const { return m_IsBegging; } + virtual const cItem GetFollowedItem(void) const override { return cItem(E_ITEM_SEEDS); } private: - int m_EggDropTimer; - bool m_IsBegging; } ; diff --git a/src/Mobs/Cow.cpp b/src/Mobs/Cow.cpp index 4063f034d..d8e905217 100644 --- a/src/Mobs/Cow.cpp +++ b/src/Mobs/Cow.cpp @@ -41,30 +41,3 @@ void cCow::OnRightClicked(cPlayer & a_Player) } } -void cCow::Tick(float a_Dt, cChunk & a_Chunk) -{ - super::Tick(a_Dt, a_Chunk); - cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), (float)m_SightDistance); - if (a_Closest_Player != NULL) - { - if (a_Closest_Player->GetEquippedItem().m_ItemType == E_ITEM_WHEAT) - { - if (!IsBegging()) - { - m_IsBegging = true; - m_World->BroadcastEntityMetadata(*this); - } - Vector3d PlayerPos = a_Closest_Player->GetPosition(); - PlayerPos.y++; - m_FinalDestination = PlayerPos; - } - else - { - if (IsBegging()) - { - m_IsBegging = false; - m_World->BroadcastEntityMetadata(*this); - } - } - } -} diff --git a/src/Mobs/Cow.h b/src/Mobs/Cow.h index b001ea856..973171ab5 100644 --- a/src/Mobs/Cow.h +++ b/src/Mobs/Cow.h @@ -19,13 +19,8 @@ public: virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; virtual void OnRightClicked(cPlayer & a_Player) override; - virtual void Tick(float a_Dt, cChunk & a_Chunk) override; - bool IsBegging (void) const { return m_IsBegging; } - -private: - - bool m_IsBegging; + virtual const cItem GetFollowedItem(void) const override { return cItem(E_ITEM_WHEAT); } } ; diff --git a/src/Mobs/Mooshroom.cpp b/src/Mobs/Mooshroom.cpp index 60721f0ee..00ba339a6 100644 --- a/src/Mobs/Mooshroom.cpp +++ b/src/Mobs/Mooshroom.cpp @@ -30,32 +30,4 @@ void cMooshroom::GetDrops(cItems & a_Drops, cEntity * a_Killer) } -void cMooshroom::Tick(float a_Dt, cChunk & a_Chunk) -{ - super::Tick(a_Dt, a_Chunk); - cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), (float)m_SightDistance); - if (a_Closest_Player != NULL) - { - if (a_Closest_Player->GetEquippedItem().m_ItemType == E_ITEM_WHEAT) - { - if (!IsBegging()) - { - m_IsBegging = true; - m_World->BroadcastEntityMetadata(*this); - } - Vector3d PlayerPos = a_Closest_Player->GetPosition(); - PlayerPos.y++; - m_FinalDestination = PlayerPos; - } - else - { - if (IsBegging()) - { - m_IsBegging = false; - m_World->BroadcastEntityMetadata(*this); - } - } - } -} - diff --git a/src/Mobs/Mooshroom.h b/src/Mobs/Mooshroom.h index c288f68a9..c94301098 100644 --- a/src/Mobs/Mooshroom.h +++ b/src/Mobs/Mooshroom.h @@ -18,14 +18,8 @@ public: CLASS_PROTODEF(cMooshroom); virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; - virtual void Tick(float a_Dt, cChunk & a_Chunk) override; - - bool IsBegging (void) const { return m_IsBegging; } - -private: - - bool m_IsBegging; + virtual const cItem GetFollowedItem(void) const override { return cItem(E_ITEM_WHEAT); } } ; diff --git a/src/Mobs/PassiveMonster.cpp b/src/Mobs/PassiveMonster.cpp index d774d3170..903761a95 100644 --- a/src/Mobs/PassiveMonster.cpp +++ b/src/Mobs/PassiveMonster.cpp @@ -3,7 +3,7 @@ #include "PassiveMonster.h" #include "../World.h" - +#include "../Entities/Player.h" @@ -39,6 +39,20 @@ void cPassiveMonster::Tick(float a_Dt, cChunk & a_Chunk) { CheckEventLostPlayer(); } + cItem FollowedItem = GetFollowedItem(); + if (FollowedItem.IsEmpty()) + { + return; + } + cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), (float)m_SightDistance); + if (a_Closest_Player != NULL) + { + if (a_Closest_Player->GetEquippedItem().m_ItemType == FollowedItem.m_ItemType) + { + Vector3d PlayerPos = a_Closest_Player->GetPosition(); + MoveToPosition(PlayerPos); + } + } } diff --git a/src/Mobs/PassiveMonster.h b/src/Mobs/PassiveMonster.h index 14a6be6b1..7da5d71bc 100644 --- a/src/Mobs/PassiveMonster.h +++ b/src/Mobs/PassiveMonster.h @@ -20,6 +20,8 @@ public: /// When hit by someone, run away virtual void DoTakeDamage(TakeDamageInfo & a_TDI) override; + virtual const cItem GetFollowedItem(void) const { return cItem(); } + } ; diff --git a/src/Mobs/Pig.cpp b/src/Mobs/Pig.cpp index b6d11d856..d8f3dda37 100644 --- a/src/Mobs/Pig.cpp +++ b/src/Mobs/Pig.cpp @@ -71,33 +71,5 @@ void cPig::OnRightClicked(cPlayer & a_Player) } } -void cPig::Tick(float a_Dt, cChunk & a_Chunk) -{ - super::Tick(a_Dt, a_Chunk); - cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), (float)m_SightDistance); - if (a_Closest_Player != NULL) - { - if (a_Closest_Player->GetEquippedItem().m_ItemType == E_ITEM_CARROT) - { - if (!IsBegging()) - { - m_IsBegging = true; - m_World->BroadcastEntityMetadata(*this); - } - Vector3d PlayerPos = a_Closest_Player->GetPosition(); - PlayerPos.y++; - m_FinalDestination = PlayerPos; - } - else - { - if (IsBegging()) - { - m_IsBegging = false; - m_World->BroadcastEntityMetadata(*this); - } - } - } -} - diff --git a/src/Mobs/Pig.h b/src/Mobs/Pig.h index f42a4f412..d434324c1 100644 --- a/src/Mobs/Pig.h +++ b/src/Mobs/Pig.h @@ -19,14 +19,13 @@ public: virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; virtual void OnRightClicked(cPlayer & a_Player) override; - virtual void Tick(float a_Dt, cChunk & a_Chunk) override; + + virtual const cItem GetFollowedItem(void) const override { return cItem(E_ITEM_CARROT); } bool IsSaddled(void) const { return m_bIsSaddled; } - bool IsBegging (void) const { return m_IsBegging; } private: - bool m_IsBegging; bool m_bIsSaddled; } ; diff --git a/src/Mobs/Sheep.cpp b/src/Mobs/Sheep.cpp index c8ff8f5c8..4761103e5 100644 --- a/src/Mobs/Sheep.cpp +++ b/src/Mobs/Sheep.cpp @@ -95,29 +95,6 @@ void cSheep::Tick(float a_Dt, cChunk & a_Chunk) m_TimeToStopEating = 40; } } - cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), (float)m_SightDistance); - if (a_Closest_Player != NULL) - { - if (a_Closest_Player->GetEquippedItem().m_ItemType == E_ITEM_WHEAT) - { - if (!IsBegging()) - { - m_IsBegging = true; - m_World->BroadcastEntityMetadata(*this); - } - Vector3d PlayerPos = a_Closest_Player->GetPosition(); - PlayerPos.y++; - m_FinalDestination = PlayerPos; - } - else - { - if (IsBegging()) - { - m_IsBegging = false; - m_World->BroadcastEntityMetadata(*this); - } - } - } } } diff --git a/src/Mobs/Sheep.h b/src/Mobs/Sheep.h index 322b31dd9..402e8e61c 100644 --- a/src/Mobs/Sheep.h +++ b/src/Mobs/Sheep.h @@ -21,13 +21,13 @@ public: virtual void OnRightClicked(cPlayer & a_Player) override; virtual void Tick(float a_Dt, cChunk & a_Chunk) override; - bool IsBegging(void) const { return m_IsBegging; } + virtual const cItem GetFollowedItem(void) const override { return cItem(E_ITEM_WHEAT); } + bool IsSheared(void) const { return m_IsSheared; } int GetFurColor(void) const { return m_WoolColor; } private: - - bool m_IsBegging; + bool m_IsSheared; int m_WoolColor; int m_TimeToStopEating; -- cgit v1.2.3 From e9c1d1ea9c79d9a57d48b625d9a31604e927609c Mon Sep 17 00:00:00 2001 From: tonibm19 Date: Wed, 29 Jan 2014 20:02:41 +0100 Subject: Did what xoft said --- src/Mobs/Chicken.cpp | 1 - src/Mobs/Mooshroom.cpp | 2 -- src/Mobs/PassiveMonster.cpp | 2 +- src/Mobs/PassiveMonster.h | 3 ++- 4 files changed, 3 insertions(+), 5 deletions(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Chicken.cpp b/src/Mobs/Chicken.cpp index 90d56d1de..fab92ce49 100644 --- a/src/Mobs/Chicken.cpp +++ b/src/Mobs/Chicken.cpp @@ -2,7 +2,6 @@ #include "Chicken.h" #include "../World.h" -#include "../Entities/Player.h" diff --git a/src/Mobs/Mooshroom.cpp b/src/Mobs/Mooshroom.cpp index 00ba339a6..88101cd83 100644 --- a/src/Mobs/Mooshroom.cpp +++ b/src/Mobs/Mooshroom.cpp @@ -2,8 +2,6 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Mooshroom.h" -#include "../Entities/Player.h" - diff --git a/src/Mobs/PassiveMonster.cpp b/src/Mobs/PassiveMonster.cpp index 903761a95..904cd63cc 100644 --- a/src/Mobs/PassiveMonster.cpp +++ b/src/Mobs/PassiveMonster.cpp @@ -47,7 +47,7 @@ void cPassiveMonster::Tick(float a_Dt, cChunk & a_Chunk) cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), (float)m_SightDistance); if (a_Closest_Player != NULL) { - if (a_Closest_Player->GetEquippedItem().m_ItemType == FollowedItem.m_ItemType) + if (a_Closest_Player->GetEquippedItem().IsEqual(FollowedItem)) { Vector3d PlayerPos = a_Closest_Player->GetPosition(); MoveToPosition(PlayerPos); diff --git a/src/Mobs/PassiveMonster.h b/src/Mobs/PassiveMonster.h index 7da5d71bc..0b3c155da 100644 --- a/src/Mobs/PassiveMonster.h +++ b/src/Mobs/PassiveMonster.h @@ -19,7 +19,8 @@ public: /// When hit by someone, run away virtual void DoTakeDamage(TakeDamageInfo & a_TDI) override; - + /** Returns the item that the animal of this class follows when a player holds it in hand + Return an empty item not to follow (default). */ virtual const cItem GetFollowedItem(void) const { return cItem(); } } ; -- cgit v1.2.3