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/Monster.cpp | 400 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 238 insertions(+), 162 deletions(-) (limited to 'src/Mobs/Monster.cpp') 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 -- 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/Monster.cpp') 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 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 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src/Mobs/Monster.cpp') 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) { -- 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/Monster.cpp') 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 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 +++++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 20 deletions(-) (limited to 'src/Mobs/Monster.cpp') 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); } } } -- 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 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) (limited to 'src/Mobs/Monster.cpp') 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()); -- cgit v1.2.3 From 2a52b390c001406540627293e6b425ff709e7250 Mon Sep 17 00:00:00 2001 From: Kirill Kirilenko Date: Sat, 1 Feb 2014 20:38:53 +0400 Subject: Monster's nominal speed was increased. --- src/Mobs/Monster.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/Mobs/Monster.cpp') diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 42c7d2899..283ef36e6 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -276,7 +276,7 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk) { Distance.y = 0; Distance.Normalize(); - Distance *= 3; + Distance *= 5; SetSpeedX(Distance.x); SetSpeedZ(Distance.z); -- cgit v1.2.3 From c2e7dd34d98258bdfa5baa2f27f08999909996c5 Mon Sep 17 00:00:00 2001 From: tonibm19 Date: Mon, 3 Feb 2014 20:52:11 +0100 Subject: Exporded World:FindClosestPlayer, Item:IsEnchantable and Monster:MoveToPosition to Lua API --- src/Mobs/Monster.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/Mobs/Monster.cpp') diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 283ef36e6..35880bcff 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -188,6 +188,14 @@ void cMonster::MoveToPosition(const Vector3f & a_Position) TickPathFinding(); } +void cMonster::MoveToPosition(const Vector3d & a_Position) +{ + FinishPathFinding(); + + m_FinalDestination = a_Position; + m_bMovingToDestination = true; + TickPathFinding(); +} -- cgit v1.2.3 From a845b9abbb2531761b1ff25ba0e4d1958a4e9299 Mon Sep 17 00:00:00 2001 From: tonibm19 Date: Tue, 4 Feb 2014 17:29:36 +0100 Subject: Blank lines and indentation. Also removed GetClosestPlayer documentation --- src/Mobs/Monster.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/Mobs/Monster.cpp') diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 35880bcff..340761a7e 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -188,6 +188,10 @@ void cMonster::MoveToPosition(const Vector3f & a_Position) TickPathFinding(); } + + + + void cMonster::MoveToPosition(const Vector3d & a_Position) { FinishPathFinding(); -- cgit v1.2.3 From 630507fd5b8a7ac280ee75994f98b9ecfdcb7a70 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 4 Feb 2014 23:07:22 +0000 Subject: Fixed a bunch of MSVS warnings * Possibly also fixed some bugs with pathfinding and TNT, though unlikely --- src/Mobs/Monster.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/Mobs/Monster.cpp') diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 283ef36e6..b49a8661d 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -264,7 +264,7 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk) { m_Destination.y = FindFirstNonAirBlockPosition(m_Destination.x, m_Destination.z); - if (DoesPosYRequireJump(m_Destination.y)) + if (DoesPosYRequireJump((int)floor(m_Destination.y))) { m_bOnGround = false; AddPosY(1.5); // Jump!! -- cgit v1.2.3 From 8ba6f731699465aa13818e307af7b9f001d3767e Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 5 Feb 2014 09:43:49 -0800 Subject: Fixed most of the reordering warnings --- src/Mobs/Monster.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/Mobs/Monster.cpp') diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 283ef36e6..1b9bfaa79 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -69,20 +69,20 @@ cMonster::cMonster(const AString & a_ConfigName, eType a_MobType, const AString : super(etMonster, a_Width, a_Height) , m_EMState(IDLE) , m_EMPersonality(AGGRESSIVE) - , m_SightDistance(25) , m_Target(NULL) - , m_AttackRate(3) - , m_IdleInterval(0) , m_bMovingToDestination(false) + , m_LastGroundHeight(POSY_TOINT) + , m_IdleInterval(0) , m_DestroyTimer(0) , m_MobType(a_MobType) , m_SoundHurt(a_SoundHurt) , m_SoundDeath(a_SoundDeath) + , m_AttackRate(3) , m_AttackDamage(1) , m_AttackRange(2) , m_AttackInterval(0) + , m_SightDistance(25) , m_BurnsInDaylight(false) - , m_LastGroundHeight(POSY_TOINT) { if (!a_ConfigName.empty()) { -- cgit v1.2.3 From 06239c8336a340459a62b45b6d633a55058e4677 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 11 Feb 2014 22:09:56 +0000 Subject: Fixed #627 - Attack() is now called from cAggressive instead of cMonster * Monsters can no longer attack through walls * Should fix last remnants of player damage after teleporting (that both STR and bearbin contributed fixes to :P) --- src/Mobs/Monster.cpp | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'src/Mobs/Monster.cpp') diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index ad3a87725..9817901c9 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -311,9 +311,6 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk) } } - if (ReachedFinalDestination() && (m_Target != NULL)) - Attack(a_Dt); - SetPitchAndYawFromDestination(); HandleFalling(); @@ -657,17 +654,6 @@ void cMonster::InStateEscaping(float a_Dt) -// Do attack here -// a_Dt is passed so we can set attack rate -void cMonster::Attack(float a_Dt) -{ - m_AttackInterval += a_Dt * m_AttackRate; -} - - - - - void cMonster::GetMonsterConfig(const AString & a_Name) { cRoot::Get()->GetMonsterConfig()->AssignAttributes(this, a_Name); -- cgit v1.2.3 From 60bcf2807a293dcf0a6fcc604a7e36c824a02110 Mon Sep 17 00:00:00 2001 From: tonibm19 Date: Sun, 16 Feb 2014 18:18:07 +0100 Subject: Now mobs can't escape from fences. --- src/Mobs/Monster.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/Mobs/Monster.cpp') diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 9817901c9..1690d3a31 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -142,11 +142,11 @@ void cMonster::TickPathFinding() 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)) + if (!g_BlockIsSolid[BlockAtY] && !g_BlockIsSolid[BlockAtYP] && !IsBlockLava(BlockAtYM) && BlockAtY!=E_BLOCK_FENCE && BlockAtY!=E_BLOCK_FENCE_GATE) { 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)) + else if (g_BlockIsSolid[BlockAtY] && !g_BlockIsSolid[BlockAtYP] && !g_BlockIsSolid[BlockAtYPP] && !IsBlockLava(BlockAtYM) && BlockAtY!=E_BLOCK_FENCE && BlockAtY!=E_BLOCK_FENCE_GATE) { m_PotentialCoordinates.push_back(Vector3d((gCrossCoords[i].x + PosX), PosY + 1, gCrossCoords[i].z + PosZ)); } -- cgit v1.2.3 From 8707f7ddc812037f022e46fa7d0d6a56a9c55728 Mon Sep 17 00:00:00 2001 From: tonibm19 Date: Mon, 17 Feb 2014 17:01:22 +0100 Subject: Improved formatting --- src/Mobs/Monster.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/Mobs/Monster.cpp') diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 1690d3a31..b5cf693cb 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -142,11 +142,11 @@ void cMonster::TickPathFinding() 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) && BlockAtY!=E_BLOCK_FENCE && BlockAtY!=E_BLOCK_FENCE_GATE) + if ((!g_BlockIsSolid[BlockAtY]) && (!g_BlockIsSolid[BlockAtYP]) && (!IsBlockLava(BlockAtYM)) && (BlockAtY != E_BLOCK_FENCE) && (BlockAtY != E_BLOCK_FENCE_GATE)) { 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) && BlockAtY!=E_BLOCK_FENCE && BlockAtY!=E_BLOCK_FENCE_GATE) + else if ((g_BlockIsSolid[BlockAtY]) && (!g_BlockIsSolid[BlockAtYP]) && (!g_BlockIsSolid[BlockAtYPP]) && (!IsBlockLava(BlockAtYM)) && (BlockAtY != E_BLOCK_FENCE) && (BlockAtY != E_BLOCK_FENCE_GATE)) { m_PotentialCoordinates.push_back(Vector3d((gCrossCoords[i].x + PosX), PosY + 1, gCrossCoords[i].z + PosZ)); } -- cgit v1.2.3 From 2cc597372afddbd798c2a8c2e754b3f9c7a36038 Mon Sep 17 00:00:00 2001 From: TheJumper Date: Sun, 23 Feb 2014 19:44:58 +0100 Subject: Fixed Formatting, Added DropChances and CanPickUpLoot attributes to Monsters --- src/Mobs/Monster.cpp | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) (limited to 'src/Mobs/Monster.cpp') diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index b5cf693cb..4ab485321 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -81,6 +81,12 @@ cMonster::cMonster(const AString & a_ConfigName, eType a_MobType, const AString , m_AttackDamage(1) , m_AttackRange(2) , m_AttackInterval(0) + , m_DropChanceWeapon(0.085) + , m_DropChanceHelmet(0.085) + , m_DropChanceChestplate(0.085) + , m_DropChanceLeggings(0.085) + , m_DropChanceBoots(0.085) + , m_CanPickUpLoot(true) , m_SightDistance(25) , m_BurnsInDaylight(false) { @@ -880,6 +886,76 @@ void cMonster::AddRandomDropItem(cItems & a_Drops, unsigned int a_Min, unsigned +void cMonster::AddRandomUncommonDropItem(cItems & a_Drops, float a_Chance, short a_Item, short a_ItemHealth) +{ + MTRand r1; + int Count = r1.randInt() % 1000; + if (Count < (a_Chance * 10)) + { + a_Drops.push_back(cItem(a_Item, 1, a_ItemHealth)); + } +} + + + + + +void cMonster::AddRandomRareDropItem(cItems & a_Drops, cItems & a_Items, short a_LootingLevel) +{ + MTRand r1; + int Count = r1.randInt() % 200; + if (Count < (5 + a_LootingLevel)) + { + int Rare = r1.randInt() % a_Items.Size(); + a_Drops.push_back(a_Items.at(Rare)); + } +} + + + + + +void cMonster::AddRandomArmorDropItem(cItems & a_Drops, short a_LootingLevel) +{ + MTRand r1; + if (r1.randInt() % 200 < ((m_DropChanceHelmet * 200) + (a_LootingLevel * 2))) + { + if (!GetEquippedHelmet().IsEmpty()) a_Drops.push_back(GetEquippedHelmet()); + } + + if (r1.randInt() % 200 < ((m_DropChanceChestplate * 200) + (a_LootingLevel * 2))) + { + if (!GetEquippedChestplate().IsEmpty()) a_Drops.push_back(GetEquippedChestplate()); + } + + if (r1.randInt() % 200 < ((m_DropChanceLeggings * 200) + (a_LootingLevel * 2))) + { + if (!GetEquippedLeggings().IsEmpty()) a_Drops.push_back(GetEquippedLeggings()); + } + + if (r1.randInt() % 200 < ((m_DropChanceBoots * 200) + (a_LootingLevel * 2))) + { + if (!GetEquippedBoots().IsEmpty()) a_Drops.push_back(GetEquippedBoots()); + } +} + + + + + +void cMonster::AddRandomWeaponDropItem(cItems & a_Drops, short a_LootingLevel) +{ + MTRand r1; + if (r1.randInt() % 200 < ((m_DropChanceWeapon * 200) + (a_LootingLevel * 2))) + { + if (!GetEquippedWeapon().IsEmpty()) a_Drops.push_back(GetEquippedWeapon()); + } +} + + + + + void cMonster::HandleDaylightBurning(cChunk & a_Chunk) { if (!m_BurnsInDaylight) -- cgit v1.2.3 From 0b6aa7b3708b4651ecea5c2bdd58fb0ccb430cbc Mon Sep 17 00:00:00 2001 From: TheJumper Date: Mon, 24 Feb 2014 15:38:38 +0100 Subject: Fixed Formatting, added compiler warning suppressing methods, fixed comments --- src/Mobs/Monster.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/Mobs/Monster.cpp') diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 4ab485321..ac9137ccd 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -81,13 +81,13 @@ cMonster::cMonster(const AString & a_ConfigName, eType a_MobType, const AString , m_AttackDamage(1) , m_AttackRange(2) , m_AttackInterval(0) + , m_SightDistance(25) , m_DropChanceWeapon(0.085) , m_DropChanceHelmet(0.085) , m_DropChanceChestplate(0.085) , m_DropChanceLeggings(0.085) , m_DropChanceBoots(0.085) , m_CanPickUpLoot(true) - , m_SightDistance(25) , m_BurnsInDaylight(false) { if (!a_ConfigName.empty()) -- cgit v1.2.3 From d73cdba1f66a92f011ac881b581595c0959139ef Mon Sep 17 00:00:00 2001 From: andrew Date: Sat, 1 Mar 2014 21:34:19 +0200 Subject: g_BlockXXX => cBlockInfo::XXX --- src/Mobs/Monster.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/Mobs/Monster.cpp') diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index ac9137ccd..6e3c91d58 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -148,11 +148,11 @@ void cMonster::TickPathFinding() 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)) && (BlockAtY != E_BLOCK_FENCE) && (BlockAtY != E_BLOCK_FENCE_GATE)) + if ((!cBlockInfo::IsSolid(BlockAtY)) && (!cBlockInfo::IsSolid(BlockAtYP)) && (!IsBlockLava(BlockAtYM)) && (BlockAtY != E_BLOCK_FENCE) && (BlockAtY != E_BLOCK_FENCE_GATE)) { 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)) && (BlockAtY != E_BLOCK_FENCE) && (BlockAtY != E_BLOCK_FENCE_GATE)) + else if ((cBlockInfo::IsSolid(BlockAtY)) && (!cBlockInfo::IsSolid(BlockAtYP)) && (!cBlockInfo::IsSolid(BlockAtYPP)) && (!IsBlockLava(BlockAtYM)) && (BlockAtY != E_BLOCK_FENCE) && (BlockAtY != E_BLOCK_FENCE_GATE)) { m_PotentialCoordinates.push_back(Vector3d((gCrossCoords[i].x + PosX), PosY + 1, gCrossCoords[i].z + PosZ)); } @@ -416,9 +416,9 @@ int cMonster::FindFirstNonAirBlockPosition(double a_PosX, double a_PosZ) else if (PosY > cChunkDef::Height) PosY = cChunkDef::Height; - if (!g_BlockIsSolid[m_World->GetBlock((int)floor(a_PosX), PosY, (int)floor(a_PosZ))]) + if (!cBlockInfo::IsSolid(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)) + while (!cBlockInfo::IsSolid(m_World->GetBlock((int)floor(a_PosX), PosY, (int)floor(a_PosZ))) && (PosY > 0)) { PosY--; } @@ -427,7 +427,7 @@ int cMonster::FindFirstNonAirBlockPosition(double a_PosX, double a_PosZ) } else { - while (g_BlockIsSolid[m_World->GetBlock((int)floor(a_PosX), PosY, (int)floor(a_PosZ))] && (PosY < cChunkDef::Height)) + while (cBlockInfo::IsSolid(m_World->GetBlock((int)floor(a_PosX), PosY, (int)floor(a_PosZ))) && (PosY < cChunkDef::Height)) { PosY++; } -- cgit v1.2.3 From 89027cb67510f49114b9cd99c585009465a3ef66 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 16 Mar 2014 22:00:28 +0100 Subject: Fixed double to float conversions. --- src/Mobs/Monster.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/Mobs/Monster.cpp') diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 6e3c91d58..16d6aed1f 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -82,11 +82,11 @@ cMonster::cMonster(const AString & a_ConfigName, eType a_MobType, const AString , m_AttackRange(2) , m_AttackInterval(0) , m_SightDistance(25) - , m_DropChanceWeapon(0.085) - , m_DropChanceHelmet(0.085) - , m_DropChanceChestplate(0.085) - , m_DropChanceLeggings(0.085) - , m_DropChanceBoots(0.085) + , m_DropChanceWeapon(0.085f) + , m_DropChanceHelmet(0.085f) + , m_DropChanceChestplate(0.085f) + , m_DropChanceLeggings(0.085f) + , m_DropChanceBoots(0.085f) , m_CanPickUpLoot(true) , m_BurnsInDaylight(false) { -- cgit v1.2.3 From 6b77dc74ade3d8088da09d26c1b701d92ef28e9e Mon Sep 17 00:00:00 2001 From: andrew Date: Mon, 24 Mar 2014 12:29:19 +0200 Subject: Wither invulnerability --- src/Mobs/Monster.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/Mobs/Monster.cpp') diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 16d6aed1f..d3e0f1c26 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -758,6 +758,7 @@ cMonster::eFamily cMonster::FamilyFromType(eType a_Type) case mtSquid: return mfWater; case mtVillager: return mfPassive; case mtWitch: return mfHostile; + case mtWither: return mfHostile; case mtWolf: return mfHostile; case mtZombie: return mfHostile; case mtZombiePigman: return mfHostile; -- cgit v1.2.3 From 0836fe9a84e59b083db368205cbf6496355378bf Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 31 Mar 2014 20:33:33 +0100 Subject: Fixed a few Y too high/low asserts --- src/Mobs/Monster.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/Mobs/Monster.cpp') diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index d3e0f1c26..83003006e 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -111,9 +111,9 @@ void cMonster::SpawnOn(cClientHandle & a_Client) void cMonster::TickPathFinding() { - int PosX = (int)floor(GetPosX()); - int PosY = (int)floor(GetPosY()); - int PosZ = (int)floor(GetPosZ()); + const int PosX = (int)floor(GetPosX()); + const int PosY = (int)floor(GetPosY()); + const int PosZ = (int)floor(GetPosZ()); m_FinalDestination.y = (double)FindFirstNonAirBlockPosition(m_FinalDestination.x, m_FinalDestination.z); @@ -133,9 +133,9 @@ void cMonster::TickPathFinding() for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++) { - if ((gCrossCoords[i].x + PosX == PosX) && (gCrossCoords[i].z + PosZ == PosZ)) + if ((PosY - 1 < 0) || (PosY + 1 > cChunkDef::Height) || (PosY + 2 > cChunkDef::Height)) { - continue; + break; } if (IsCoordinateInTraversedList(Vector3i(gCrossCoords[i].x + PosX, PosY, gCrossCoords[i].z + PosZ))) -- cgit v1.2.3 From ef48b30baaed9c6ad1782047d4e2d60d6248ad89 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 31 Mar 2014 22:37:05 +0100 Subject: Final realisation of suggestions --- src/Mobs/Monster.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src/Mobs/Monster.cpp') diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 83003006e..aa6071515 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -130,14 +130,16 @@ void cMonster::TickPathFinding() { 0, 1}, { 0,-1}, } ; + + if ((PosY - 1 < 0) || (PosY + 2 > cChunkDef::Height) /* PosY + 1 will never be true if PosY + 2 is not */) + { + // Too low/high, can't really do anything + FinishPathFinding(); + return; + } for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++) { - if ((PosY - 1 < 0) || (PosY + 1 > cChunkDef::Height) || (PosY + 2 > cChunkDef::Height)) - { - break; - } - if (IsCoordinateInTraversedList(Vector3i(gCrossCoords[i].x + PosX, PosY, gCrossCoords[i].z + PosZ))) { continue; -- cgit v1.2.3