1
0

Merge pull request #2894 from LogicParrot/spider

Spiders now friendly at daylight, new cChunk functions
This commit is contained in:
LogicParrot 2016-01-22 20:53:34 +02:00
commit 30b95fcc4e
13 changed files with 221 additions and 163 deletions

View File

@ -2600,6 +2600,31 @@ void cChunk::GetBlockInfo(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_Bloc
bool cChunk::GetChunkAndRelByAbsolute(const Vector3d & a_Position, cChunk ** a_Chunk, Vector3i & a_Rel)
{
return GetChunkAndRelByAbsolute(Vector3i(FloorC(a_Position.x), FloorC(a_Position.y), FloorC(a_Position.z)), a_Chunk, a_Rel);
}
bool cChunk::GetChunkAndRelByAbsolute(const Vector3i & a_Position, cChunk ** a_Chunk, Vector3i & a_Rel)
{
*a_Chunk = this->GetNeighborChunk(a_Position.x, a_Position.z);
if ((*a_Chunk == nullptr) || !(*a_Chunk)->IsValid())
{
return false;
}
a_Rel.x = a_Position.x - (*a_Chunk)->GetPosX() * cChunkDef::Width;
a_Rel.y = a_Position.y;
a_Rel.z = a_Position.z - (*a_Chunk)->GetPosZ() * cChunkDef::Width;
return true;
}
cChunk * cChunk::GetNeighborChunk(int a_BlockX, int a_BlockZ)
{
// Convert coords to relative, then call the relative version:

View File

@ -63,7 +63,9 @@ typedef cItemCallback<cCommandBlockEntity> cCommandBlockCallback;
typedef cItemCallback<cMobHeadEntity> cMobHeadCallback;
typedef cItemCallback<cFlowerPotEntity> cFlowerPotCallback;
// A convenience macro for calling GetChunkAndRelByAbsolute.
#define PREPARE_REL_AND_CHUNK(Position, OriginalChunk) cChunk * Chunk; Vector3i Rel; bool RelSuccess = (OriginalChunk).GetChunkAndRelByAbsolute(Position, &Chunk, Rel);
#define PREPARE_BLOCKDATA BLOCKTYPE BlockType; NIBBLETYPE BlockMeta;
// This class is not to be used directly
@ -186,6 +188,26 @@ public:
void GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const;
void GetBlockInfo (int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight);
/** Convert absolute coordinates into relative coordinates.
Returns false on failure to obtain a valid chunk. Returns true otherwise.
@param a_Position The position you'd like to convert, a_Position need not be in the calling chunk and can safely be out
of its bounds, but for best performance, it should not be too far from the calling chunk.
@param a_Chunk Returns the chunk in which a_Position is in. If a_Position is within the calling chunk's bounds,
returns the calling chunk. For best performance, a_Position shouldn't be too far from the calling chunk.
@param a_Rel Returns the converted relative position. Note that it is relative to the returned a_Chunk.
The vector will not be modified if the function returns false. */
bool GetChunkAndRelByAbsolute(const Vector3d & a_Position, cChunk ** a_Chunk, Vector3i & a_Rel);
/** Convert absolute coordinates into relative coordinates.
Returns false on failure to obtain a valid chunk. Returns true otherwise.
@param a_Position The position you'd like to convert, a_Position need not be in the calling chunk and can safely be out
of its bounds, but for best performance, it should not be too far from the calling chunk.
@param a_Chunk Returns the chunk in which a_Position is in. If a_Position is within the calling chunk's bounds,
returns the calling chunk. For best performance, a_Position shouldn't be too far from the calling chunk.
@param a_Rel Returns the converted relative position. Note that it is relative to the returned a_Chunk.
The vector will not be modified if the function returns false. */
bool GetChunkAndRelByAbsolute(const Vector3i & a_Position, cChunk ** a_Chunk, Vector3i & a_Rel);
/** Returns the chunk into which the specified block belongs, by walking the neighbors.
Will return self if appropriate. Returns nullptr if not reachable through neighbors.
*/
@ -382,9 +404,18 @@ public:
}
}
/** Light alterations based on time */
NIBBLETYPE GetTimeAlteredLight(NIBBLETYPE a_Skylight) const;
/** Get the level of artificial light illuminating the block (0 - 15) */
inline NIBBLETYPE GetBlockLight(int a_RelX, int a_RelY, int a_RelZ) const {return m_ChunkData.GetBlockLight(a_RelX, a_RelY, a_RelZ); }
/** Get the level of sky light illuminating the block (0 - 15) independent of daytime. */
inline NIBBLETYPE GetSkyLight (int a_RelX, int a_RelY, int a_RelZ) const {return m_ChunkData.GetSkyLight(a_RelX, a_RelY, a_RelZ); }
/** Get the level of sky light illuminating the block (0 - 15), taking daytime into a account. */
inline NIBBLETYPE GetSkyLightAltered (int a_RelX, int a_RelY, int a_RelZ) const {return GetTimeAlteredLight(m_ChunkData.GetSkyLight(a_RelX, a_RelY, a_RelZ)); }
/** Same as GetBlock(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case); returns true on success */
bool UnboundedRelGetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const;
@ -412,8 +443,6 @@ public:
/** Same as QueueTickBlock(), but relative coords needn't be in this chunk (uses m_Neighbor-s in such a case), ignores unsuccessful attempts */
void UnboundedQueueTickBlock(int a_RelX, int a_RelY, int a_RelZ);
/** Light alterations based on time */
NIBBLETYPE GetTimeAlteredLight(NIBBLETYPE a_Skylight) const;
// Per-chunk simulator data:

View File

@ -37,7 +37,6 @@
class cWorld;
class cClientHandle;
class cPlayer;

View File

@ -36,11 +36,11 @@ void cAggressiveMonster::InStateChasing(std::chrono::milliseconds a_Dt, cChunk &
void cAggressiveMonster::EventSeePlayer(cEntity * a_Entity)
void cAggressiveMonster::EventSeePlayer(cEntity * a_Entity, cChunk & a_Chunk)
{
if (!static_cast<cPlayer *>(a_Entity)->IsGameModeCreative())
{
super::EventSeePlayer(a_Entity);
super::EventSeePlayer(a_Entity, a_Chunk);
m_EMState = CHASING;
}
}
@ -59,7 +59,7 @@ void cAggressiveMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
}
else
{
CheckEventSeePlayer();
CheckEventSeePlayer(a_Chunk);
}
if (m_Target == nullptr)

View File

@ -19,7 +19,7 @@ public:
virtual void Tick (std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual void InStateChasing(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual void EventSeePlayer(cEntity *) override;
virtual void EventSeePlayer(cEntity * a_Player, cChunk & a_Chunk) override;
/** Try to perform attack
returns true if attack was deemed successful (hit player, fired projectile, creeper exploded, etc.) even if it didn't actually do damage

View File

@ -102,7 +102,7 @@ void cEnderman::GetDrops(cItems & a_Drops, cEntity * a_Killer)
void cEnderman::CheckEventSeePlayer()
void cEnderman::CheckEventSeePlayer(cChunk & a_Chunk)
{
if (m_Target != nullptr)
{
@ -126,7 +126,7 @@ void cEnderman::CheckEventSeePlayer()
if (!Callback.GetPlayer()->IsGameModeCreative())
{
cMonster::EventSeePlayer(Callback.GetPlayer());
cMonster::EventSeePlayer(Callback.GetPlayer(), a_Chunk);
m_EMState = CHASING;
m_bIsScreaming = true;
GetWorld()->BroadcastEntityMetadata(*this);

View File

@ -18,7 +18,7 @@ public:
CLASS_PROTODEF(cEnderman)
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
virtual void CheckEventSeePlayer(void) override;
virtual void CheckEventSeePlayer(cChunk & a_Chunk) override;
virtual void CheckEventLostPlayer(void) override;
virtual void EventLosePlayer(void) override;
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;

View File

@ -560,14 +560,14 @@ void cMonster::OnRightClicked(cPlayer & a_Player)
// Checks to see if EventSeePlayer should be fired
// monster sez: Do I see the player
void cMonster::CheckEventSeePlayer(void)
void cMonster::CheckEventSeePlayer(cChunk & a_Chunk)
{
// TODO: Rewrite this to use cWorld's DoWithPlayers()
cPlayer * Closest = m_World->FindClosestPlayer(GetPosition(), static_cast<float>(m_SightDistance), false);
if (Closest != nullptr)
{
EventSeePlayer(Closest);
EventSeePlayer(Closest, a_Chunk);
}
}
@ -596,7 +596,7 @@ void cMonster::CheckEventLostPlayer(void)
// What to do if player is seen
// default to change state to chasing
void cMonster::EventSeePlayer(cEntity * a_SeenPlayer)
void cMonster::EventSeePlayer(cEntity * a_SeenPlayer, cChunk & a_Chunk)
{
m_Target = a_SeenPlayer;
}

View File

@ -67,8 +67,8 @@ public:
eFamily GetMobFamily(void) const;
// tolua_end
virtual void CheckEventSeePlayer(void);
virtual void EventSeePlayer(cEntity * a_Player);
virtual void CheckEventSeePlayer(cChunk & a_Chunk);
virtual void EventSeePlayer(cEntity * a_Entity, cChunk & a_Chunk);
/** Reads the monster configuration for the specified monster name and assigns it to this object. */
void GetMonsterConfig(const AString & a_Name);

View File

@ -39,7 +39,7 @@ bool cPassiveAggressiveMonster::DoTakeDamage(TakeDamageInfo & a_TDI)
void cPassiveAggressiveMonster::EventSeePlayer(cEntity *)
void cPassiveAggressiveMonster::EventSeePlayer(cEntity *, cChunk & a_Chunk)
{
// don't do anything, neutral mobs don't react to just seeing the player
}

View File

@ -16,7 +16,7 @@ public:
cPassiveAggressiveMonster(const AString & a_ConfigName, eMonsterType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height);
virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override;
virtual void EventSeePlayer(cEntity *) override;
virtual void EventSeePlayer(cEntity *, cChunk & a_Chunk) override;
} ;

View File

@ -5,7 +5,7 @@
#include "../World.h"
#include "../Entities/Player.h"
#include "../Chunk.h"
cSpider::cSpider(void) :
@ -35,17 +35,22 @@ void cSpider::GetDrops(cItems & a_Drops, cEntity * a_Killer)
void cSpider::EventSeePlayer(cEntity * a_Entity)
void cSpider::EventSeePlayer(cEntity * a_Entity, cChunk & a_Chunk)
{
if (!GetWorld()->IsChunkLighted(GetChunkX(), GetChunkZ()))
{
GetWorld()->QueueLightChunk(GetChunkX(), GetChunkZ());
return;
}
if (!static_cast<cPlayer *>(a_Entity)->IsGameModeCreative() && (GetWorld()->GetBlockBlockLight(this->GetPosition()) <= 9))
PREPARE_REL_AND_CHUNK(GetPosition(), a_Chunk);
if (!RelSuccess)
{
super::EventSeePlayer(a_Entity);
return;
}
if (!static_cast<cPlayer *>(a_Entity)->IsGameModeCreative() && (Chunk->GetSkyLightAltered(Rel.x, Rel.y, Rel.z) <= 9))
{
super::EventSeePlayer(a_Entity, a_Chunk);
}
}

View File

@ -18,7 +18,7 @@ public:
CLASS_PROTODEF(cSpider)
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
virtual void EventSeePlayer(cEntity *) override;
virtual void EventSeePlayer(cEntity *, cChunk & a_Chunk) override;
virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override;
} ;