本文整理汇总了C++中cChunk::ForEachEntity方法的典型用法代码示例。如果您正苦于以下问题:C++ cChunk::ForEachEntity方法的具体用法?C++ cChunk::ForEachEntity怎么用?C++ cChunk::ForEachEntity使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类cChunk
的用法示例。
在下文中一共展示了cChunk::ForEachEntity方法的5个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: Tick
void cPickup::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
super::Tick(a_Dt, a_Chunk);
BroadcastMovementUpdate(); // Notify clients of position
m_Timer += a_Dt;
if (!m_bCollected)
{
int BlockY = POSY_TOINT;
int BlockX = POSX_TOINT;
int BlockZ = POSZ_TOINT;
if ((BlockY >= 0) && (BlockY < cChunkDef::Height)) // Don't do anything except for falling when outside the world
{
// Position might have changed due to physics. So we have to make sure we have the correct chunk.
GET_AND_VERIFY_CURRENT_CHUNK(CurrentChunk, BlockX, BlockZ)
int RelBlockX = BlockX - (CurrentChunk->GetPosX() * cChunkDef::Width);
int RelBlockZ = BlockZ - (CurrentChunk->GetPosZ() * cChunkDef::Width);
// If the pickup is on the bottommost block position, make it think the void is made of air: (#131)
BLOCKTYPE BlockBelow = (BlockY > 0) ? CurrentChunk->GetBlock(RelBlockX, BlockY - 1, RelBlockZ) : E_BLOCK_AIR;
BLOCKTYPE BlockIn = CurrentChunk->GetBlock(RelBlockX, BlockY, RelBlockZ);
if (
IsBlockLava(BlockBelow) || (BlockBelow == E_BLOCK_FIRE) ||
IsBlockLava(BlockIn) || (BlockIn == E_BLOCK_FIRE)
)
{
m_bCollected = true;
m_Timer = std::chrono::milliseconds(0); // We have to reset the timer.
m_Timer += a_Dt; // In case we have to destroy the pickup in the same tick.
if (m_Timer > std::chrono::milliseconds(500))
{
Destroy(true);
return;
}
}
// Try to combine the pickup with adjacent same-item pickups:
if (!IsDestroyed() && (m_Item.m_ItemCount < m_Item.GetMaxStackSize())) // Don't combine if already full
{
// By using a_Chunk's ForEachEntity() instead of cWorld's, pickups don't combine across chunk boundaries.
// That is a small price to pay for not having to traverse the entire world for each entity.
// The speedup in the tick thread is quite considerable.
cPickupCombiningCallback PickupCombiningCallback(GetPosition(), this);
a_Chunk.ForEachEntity(PickupCombiningCallback);
if (PickupCombiningCallback.FoundMatchingPickup())
{
m_World->BroadcastEntityMetadata(*this);
}
}
}
示例2: HandlePhysics
void cProjectileEntity::HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
if (m_IsInGround)
{
// Already-grounded projectiles don't move at all
return;
}
auto DtSec = std::chrono::duration_cast<std::chrono::duration<double>>(a_Dt);
const Vector3d DeltaSpeed = GetSpeed() * DtSec.count();
const Vector3d Pos = GetPosition();
const Vector3d NextPos = Pos + DeltaSpeed;
// Test for entity collisions:
cProjectileEntityCollisionCallback EntityCollisionCallback(this, Pos, NextPos);
a_Chunk.ForEachEntity(EntityCollisionCallback);
if (EntityCollisionCallback.HasHit())
{
// An entity was hit:
Vector3d HitPos = Pos + (NextPos - Pos) * EntityCollisionCallback.GetMinCoeff();
// DEBUG:
LOGD("Projectile %d has hit an entity %d (%s) at {%.02f, %.02f, %.02f} (coeff %.03f)",
m_UniqueID,
EntityCollisionCallback.GetHitEntity()->GetUniqueID(),
EntityCollisionCallback.GetHitEntity()->GetClass(),
HitPos.x, HitPos.y, HitPos.z,
EntityCollisionCallback.GetMinCoeff()
);
OnHitEntity(*(EntityCollisionCallback.GetHitEntity()), HitPos);
if (!IsTicking())
{
return; // We were destroyed by an override of OnHitEntity
}
}
// TODO: Test the entities in the neighboring chunks, too
// Trace the tick's worth of movement as a line:
cProjectileTracerCallback TracerCallback(this);
if (!cLineBlockTracer::Trace(*m_World, TracerCallback, Pos, NextPos))
{
// Something has been hit, abort all other processing
return;
}
// The tracer also checks the blocks for slowdown blocks - water and lava - and stores it for later in its SlowdownCoeff
// Update the position:
SetPosition(NextPos);
// Add slowdown and gravity effect to the speed:
Vector3d NewSpeed(GetSpeed());
NewSpeed.y += m_Gravity * DtSec.count();
NewSpeed -= NewSpeed * (m_AirDrag * 20.0f) * DtSec.count();
SetSpeed(NewSpeed);
SetYawFromSpeed();
SetPitchFromSpeed();
/*
LOGD("Projectile %d: pos {%.02f, %.02f, %.02f}, speed {%.02f, %.02f, %.02f}, rot {%.02f, %.02f}",
m_UniqueID,
GetPosX(), GetPosY(), GetPosZ(),
GetSpeedX(), GetSpeedY(), GetSpeedZ(),
GetYaw(), GetPitch()
);
*/
}
示例3: HandlePhysics
void cProjectileEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
{
if (m_IsInGround)
{
// Already-grounded projectiles don't move at all
return;
}
Vector3d PerTickSpeed = GetSpeed() / 20;
Vector3d Pos = GetPosition();
// Trace the tick's worth of movement as a line:
Vector3d NextPos = Pos + PerTickSpeed;
cProjectileTracerCallback TracerCallback(this);
if (!cLineBlockTracer::Trace(*m_World, TracerCallback, Pos, NextPos))
{
// Something has been hit, abort all other processing
return;
}
// The tracer also checks the blocks for slowdown blocks - water and lava - and stores it for later in its SlowdownCoeff
// Test for entity collisions:
cProjectileEntityCollisionCallback EntityCollisionCallback(this, Pos, NextPos);
a_Chunk.ForEachEntity(EntityCollisionCallback);
if (EntityCollisionCallback.HasHit())
{
// An entity was hit:
Vector3d HitPos = Pos + (NextPos - Pos) * EntityCollisionCallback.GetMinCoeff();
// DEBUG:
LOGD("Projectile %d has hit an entity %d (%s) at {%.02f, %.02f, %.02f} (coeff %.03f)",
m_UniqueID,
EntityCollisionCallback.GetHitEntity()->GetUniqueID(),
EntityCollisionCallback.GetHitEntity()->GetClass(),
HitPos.x, HitPos.y, HitPos.z,
EntityCollisionCallback.GetMinCoeff()
);
OnHitEntity(*(EntityCollisionCallback.GetHitEntity()), HitPos);
}
// TODO: Test the entities in the neighboring chunks, too
// Update the position:
SetPosition(NextPos);
// Add slowdown and gravity effect to the speed:
Vector3d NewSpeed(GetSpeed());
NewSpeed.y += m_Gravity / 20;
NewSpeed *= TracerCallback.GetSlowdownCoeff();
SetSpeed(NewSpeed);
SetRotationFromSpeed();
SetPitchFromSpeed();
// DEBUG:
LOGD("Projectile %d: pos {%.02f, %.02f, %.02f}, speed {%.02f, %.02f, %.02f}, rot {%.02f, %.02f}",
m_UniqueID,
GetPosX(), GetPosY(), GetPosZ(),
GetSpeedX(), GetSpeedY(), GetSpeedZ(),
GetRotation(), GetPitch()
);
}
示例4: MovePickupsIn
/// Moves pickups from above this hopper into it. Returns true if the contents have changed.
bool cHopperEntity::MovePickupsIn(cChunk & a_Chunk, Int64 a_CurrentTick)
{
UNUSED(a_CurrentTick);
class cHopperPickupSearchCallback :
public cEntityCallback
{
public:
cHopperPickupSearchCallback(const Vector3i & a_Pos, cItemGrid & a_Contents) :
m_Pos(a_Pos),
m_bFoundPickupsAbove(false),
m_Contents(a_Contents)
{
}
virtual bool Item(cEntity * a_Entity) override
{
ASSERT(a_Entity != NULL);
if (!a_Entity->IsPickup() || a_Entity->IsDestroyed())
{
return false;
}
Vector3f EntityPos = a_Entity->GetPosition();
Vector3f BlockPos(m_Pos.x + 0.5f, (float)m_Pos.y + 1, m_Pos.z + 0.5f); // One block above hopper, and search from center outwards
double Distance = (EntityPos - BlockPos).Length();
if (Distance < 0.5)
{
if (TrySuckPickupIn((cPickup *)a_Entity))
{
return false;
}
}
return false;
}
bool TrySuckPickupIn(cPickup * a_Pickup)
{
cItem & Item = a_Pickup->GetItem();
for (int i = 0; i < ContentsWidth * ContentsHeight; i++)
{
if (m_Contents.IsSlotEmpty(i))
{
m_bFoundPickupsAbove = true;
m_Contents.SetSlot(i, Item);
a_Pickup->Destroy(); // Kill pickup
return true;
}
else if (m_Contents.GetSlot(i).IsEqual(Item) && !m_Contents.GetSlot(i).IsFullStack())
{
m_bFoundPickupsAbove = true;
int PreviousCount = m_Contents.GetSlot(i).m_ItemCount;
Item.m_ItemCount -= m_Contents.ChangeSlotCount(i, Item.m_ItemCount) - PreviousCount; // Set count to however many items were added
if (Item.IsEmpty())
{
a_Pickup->Destroy(); // Kill pickup if all items were added
}
return true;
}
}
return false;
}
bool FoundPickupsAbove(void) const
{
return m_bFoundPickupsAbove;
}
protected:
Vector3i m_Pos;
bool m_bFoundPickupsAbove;
cItemGrid & m_Contents;
};
cHopperPickupSearchCallback HopperPickupSearchCallback(Vector3i(GetPosX(), GetPosY(), GetPosZ()), m_Contents);
a_Chunk.ForEachEntity(HopperPickupSearchCallback);
return HopperPickupSearchCallback.FoundPickupsAbove();
}
示例5: Tick
void cFloater::Tick(float a_Dt, cChunk & a_Chunk)
{
HandlePhysics(a_Dt, a_Chunk);
if (IsBlockWater(m_World->GetBlock((int) GetPosX(), (int) GetPosY(), (int) GetPosZ())) && m_World->GetBlockMeta((int) GetPosX(), (int) GetPosY(), (int) GetPosZ()) == 0)
{
if ((!m_CanPickupItem) && (m_AttachedMobID == -1)) // Check if you can't already pickup a fish and if the floater isn't attached to a mob.
{
if (m_CountDownTime <= 0)
{
m_World->BroadcastSoundEffect("random.splash", GetPosX(), GetPosY(), GetPosZ(), 1, 1);
SetPosY(GetPosY() - 1);
m_CanPickupItem = true;
m_PickupCountDown = 20;
m_CountDownTime = 100 + m_World->GetTickRandomNumber(800);
LOGD("Floater %i can be picked up", GetUniqueID());
}
else if (m_CountDownTime == 20) // Calculate the position where the particles should spawn and start producing them.
{
LOGD("Started producing particles for floater %i", GetUniqueID());
m_ParticlePos.Set(GetPosX() + (-4 + m_World->GetTickRandomNumber(8)), GetPosY(), GetPosZ() + (-4 + m_World->GetTickRandomNumber(8)));
m_World->BroadcastParticleEffect("splash", (float) m_ParticlePos.x, (float) m_ParticlePos.y, (float) m_ParticlePos.z, 0, 0, 0, 0, 15);
}
else if (m_CountDownTime < 20)
{
m_ParticlePos = (m_ParticlePos + (GetPosition() - m_ParticlePos) / 6);
m_World->BroadcastParticleEffect("splash", (float) m_ParticlePos.x, (float) m_ParticlePos.y, (float) m_ParticlePos.z, 0, 0, 0, 0, 15);
}
m_CountDownTime--;
if (m_World->GetHeight((int) GetPosX(), (int) GetPosZ()) == (int) GetPosY())
{
if (m_World->IsWeatherWet() && m_World->GetTickRandomNumber(3) == 0) // 25% chance of an extra countdown when being rained on.
{
m_CountDownTime--;
}
}
else // if the floater is underground it has a 50% chance of not decreasing the countdown.
{
if (m_World->GetTickRandomNumber(1) == 0)
{
m_CountDownTime++;
}
}
}
SetSpeedY(0.7);
}
if (CanPickup()) // Make sure the floater "loses its fish"
{
m_PickupCountDown--;
if (m_PickupCountDown == 0)
{
m_CanPickupItem = false;
LOGD("The fish is gone. Floater %i can not pick an item up.", GetUniqueID());
}
}
if ((GetSpeed().Length() > 4) && (m_AttachedMobID == -1))
{
cFloaterEntityCollisionCallback Callback(this, GetPosition(), GetPosition() + GetSpeed() / 20);
a_Chunk.ForEachEntity(Callback);
if (Callback.HasHit())
{
AttachTo(Callback.GetHitEntity());
Callback.GetHitEntity()->TakeDamage(*this); // TODO: the player attacked the mob not the floater.
m_AttachedMobID = Callback.GetHitEntity()->GetUniqueID();
}
}
cFloaterCheckEntityExist EntityCallback;
m_World->DoWithEntityByID(m_PlayerID, EntityCallback);
if (!EntityCallback.DoesExist()) // The owner doesn't exist anymore. Destroy the floater entity.
{
Destroy(true);
}
if (m_AttachedMobID != -1)
{
m_World->DoWithEntityByID(m_AttachedMobID, EntityCallback); // The mob the floater was attached to doesn't exist anymore.
if (!EntityCallback.DoesExist())
{
m_AttachedMobID = -1;
}
}
SetSpeedX(GetSpeedX() * 0.95);
SetSpeedZ(GetSpeedZ() * 0.95);
BroadcastMovementUpdate();
}