Merge pull request #2894 from LogicParrot/spider
Spiders now friendly at daylight, new cChunk functions
This commit is contained in:
commit
30b95fcc4e
@ -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:
|
||||
|
35
src/Chunk.h
35
src/Chunk.h
@ -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:
|
||||
|
@ -37,7 +37,6 @@
|
||||
|
||||
|
||||
|
||||
|
||||
class cWorld;
|
||||
class cClientHandle;
|
||||
class cPlayer;
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
} ;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user