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) cChunk * cChunk::GetNeighborChunk(int a_BlockX, int a_BlockZ)
{ {
// Convert coords to relative, then call the relative version: // 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<cMobHeadEntity> cMobHeadCallback;
typedef cItemCallback<cFlowerPotEntity> cFlowerPotCallback; 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 // 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 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); 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. /** 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. 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); } 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); } 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 */ /** 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; 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 */ /** 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); 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: // Per-chunk simulator data:

View File

@ -37,7 +37,6 @@
class cWorld; class cWorld;
class cClientHandle; class cClientHandle;
class cPlayer; 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()) if (!static_cast<cPlayer *>(a_Entity)->IsGameModeCreative())
{ {
super::EventSeePlayer(a_Entity); super::EventSeePlayer(a_Entity, a_Chunk);
m_EMState = CHASING; m_EMState = CHASING;
} }
} }
@ -59,7 +59,7 @@ void cAggressiveMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
} }
else else
{ {
CheckEventSeePlayer(); CheckEventSeePlayer(a_Chunk);
} }
if (m_Target == nullptr) 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 Tick (std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual void InStateChasing(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 /** 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 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) if (m_Target != nullptr)
{ {
@ -126,7 +126,7 @@ void cEnderman::CheckEventSeePlayer()
if (!Callback.GetPlayer()->IsGameModeCreative()) if (!Callback.GetPlayer()->IsGameModeCreative())
{ {
cMonster::EventSeePlayer(Callback.GetPlayer()); cMonster::EventSeePlayer(Callback.GetPlayer(), a_Chunk);
m_EMState = CHASING; m_EMState = CHASING;
m_bIsScreaming = true; m_bIsScreaming = true;
GetWorld()->BroadcastEntityMetadata(*this); GetWorld()->BroadcastEntityMetadata(*this);

View File

@ -18,7 +18,7 @@ public:
CLASS_PROTODEF(cEnderman) CLASS_PROTODEF(cEnderman)
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; 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 CheckEventLostPlayer(void) override;
virtual void EventLosePlayer(void) override; virtual void EventLosePlayer(void) override;
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) 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 // Checks to see if EventSeePlayer should be fired
// monster sez: Do I see the player // 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() // TODO: Rewrite this to use cWorld's DoWithPlayers()
cPlayer * Closest = m_World->FindClosestPlayer(GetPosition(), static_cast<float>(m_SightDistance), false); cPlayer * Closest = m_World->FindClosestPlayer(GetPosition(), static_cast<float>(m_SightDistance), false);
if (Closest != nullptr) if (Closest != nullptr)
{ {
EventSeePlayer(Closest); EventSeePlayer(Closest, a_Chunk);
} }
} }
@ -596,7 +596,7 @@ void cMonster::CheckEventLostPlayer(void)
// What to do if player is seen // What to do if player is seen
// default to change state to chasing // 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; m_Target = a_SeenPlayer;
} }

View File

@ -67,8 +67,8 @@ public:
eFamily GetMobFamily(void) const; eFamily GetMobFamily(void) const;
// tolua_end // tolua_end
virtual void CheckEventSeePlayer(void); virtual void CheckEventSeePlayer(cChunk & a_Chunk);
virtual void EventSeePlayer(cEntity * a_Player); virtual void EventSeePlayer(cEntity * a_Entity, cChunk & a_Chunk);
/** Reads the monster configuration for the specified monster name and assigns it to this object. */ /** Reads the monster configuration for the specified monster name and assigns it to this object. */
void GetMonsterConfig(const AString & a_Name); 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 // 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); 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 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 "../World.h"
#include "../Entities/Player.h" #include "../Entities/Player.h"
#include "../Chunk.h"
cSpider::cSpider(void) : 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())) if (!GetWorld()->IsChunkLighted(GetChunkX(), GetChunkZ()))
{ {
GetWorld()->QueueLightChunk(GetChunkX(), GetChunkZ());
return; 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) CLASS_PROTODEF(cSpider)
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; 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; virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override;
} ; } ;