summaryrefslogtreecommitdiffstats
path: root/src/Entities
diff options
context:
space:
mode:
Diffstat (limited to 'src/Entities')
-rw-r--r--src/Entities/Entity.cpp19
-rw-r--r--src/Entities/Entity.h10
-rw-r--r--src/Entities/FallingBlock.cpp5
-rw-r--r--src/Entities/ItemFrame.cpp4
-rw-r--r--src/Entities/Player.cpp69
-rw-r--r--src/Entities/Player.h2
-rw-r--r--src/Entities/ProjectileEntity.cpp4
7 files changed, 56 insertions, 57 deletions
diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp
index 2567b7adc..8f736a269 100644
--- a/src/Entities/Entity.cpp
+++ b/src/Entities/Entity.cpp
@@ -129,9 +129,9 @@ const char * cEntity::GetParentClass(void) const
-bool cEntity::Initialize(cWorld * a_World)
+bool cEntity::Initialize(cWorld & a_World)
{
- if (cPluginManager::Get()->CallHookSpawningEntity(*a_World, *this))
+ if (cPluginManager::Get()->CallHookSpawningEntity(a_World, *this))
{
return false;
}
@@ -144,13 +144,13 @@ bool cEntity::Initialize(cWorld * a_World)
*/
m_IsInitialized = true;
- m_World = a_World;
+ m_World = &a_World;
m_World->AddEntity(this);
- cPluginManager::Get()->CallHookSpawnedEntity(*a_World, *this);
+ cPluginManager::Get()->CallHookSpawnedEntity(a_World, *this);
// Spawn the entity on the clients:
- a_World->BroadcastSpawnEntity(*this);
+ a_World.BroadcastSpawnEntity(*this);
return true;
}
@@ -1023,11 +1023,12 @@ void cEntity::DetectCacti(void)
int X = POSX_TOINT, Y = POSY_TOINT, Z = POSZ_TOINT;
double w = m_Width / 2;
if (
- (((X + 1) - GetPosX() < w) && (GetWorld()->GetBlock(X + 1, Y, Z) == E_BLOCK_CACTUS)) ||
- (((GetPosX() - (X - 1)) - 1 < w) && (GetWorld()->GetBlock(X - 1, Y, Z) == E_BLOCK_CACTUS)) ||
+ ((Y > 0) && (Y < cChunkDef::Height)) &&
+ ((((X + 1) - GetPosX() < w) && (GetWorld()->GetBlock(X + 1, Y, Z) == E_BLOCK_CACTUS)) ||
+ ((GetPosX() - X < w) && (GetWorld()->GetBlock(X - 1, Y, Z) == E_BLOCK_CACTUS)) ||
(((Z + 1) - GetPosZ() < w) && (GetWorld()->GetBlock(X, Y, Z + 1) == E_BLOCK_CACTUS)) ||
- (((GetPosZ() - (Z - 1)) - 1 < w) && (GetWorld()->GetBlock(X, Y, Z - 1) == E_BLOCK_CACTUS)) ||
- (((Y > 0) && (Y < cChunkDef::Height)) && ((GetPosY() - Y < 1) && (GetWorld()->GetBlock(X, Y, Z) == E_BLOCK_CACTUS)))
+ ((GetPosZ() - Z < w) && (GetWorld()->GetBlock(X, Y, Z - 1) == E_BLOCK_CACTUS)) ||
+ (((GetPosY() - Y < 1) && (GetWorld()->GetBlock(X, Y, Z) == E_BLOCK_CACTUS))))
)
{
TakeDamage(dtCactusContact, NULL, 1, 0);
diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h
index 0c393c0f5..85ad42d54 100644
--- a/src/Entities/Entity.h
+++ b/src/Entities/Entity.h
@@ -146,8 +146,9 @@ public:
cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, double a_Width, double a_Height);
virtual ~cEntity();
- /// Spawns the entity in the world; returns true if spawned, false if not (plugin disallowed)
- virtual bool Initialize(cWorld * a_World);
+ /** Spawns the entity in the world; returns true if spawned, false if not (plugin disallowed).
+ Adds the entity to the world. */
+ virtual bool Initialize(cWorld & a_World);
// tolua_begin
@@ -421,6 +422,9 @@ public:
UNUSED(a_Killer);
}
+ /** Sets the internal world pointer to a new cWorld, doesn't update anything else. */
+ void SetWorld(cWorld * a_World) { m_World = a_World; }
+
protected:
static cCriticalSection m_CSCount;
static int m_EntityCount;
@@ -485,8 +489,6 @@ protected:
virtual void Destroyed(void) {} // Called after the entity has been destroyed
- void SetWorld(cWorld * a_World) { m_World = a_World; }
-
/** Called in each tick to handle air-related processing i.e. drowning */
virtual void HandleAir();
diff --git a/src/Entities/FallingBlock.cpp b/src/Entities/FallingBlock.cpp
index beb58f207..111c5fa84 100644
--- a/src/Entities/FallingBlock.cpp
+++ b/src/Entities/FallingBlock.cpp
@@ -55,9 +55,8 @@ void cFallingBlock::Tick(float a_Dt, cChunk & a_Chunk)
return;
}
- int idx = a_Chunk.MakeIndexNoCheck(BlockX - a_Chunk.GetPosX() * cChunkDef::Width, BlockY, BlockZ - a_Chunk.GetPosZ() * cChunkDef::Width);
- BLOCKTYPE BlockBelow = a_Chunk.GetBlock(idx);
- NIBBLETYPE BelowMeta = a_Chunk.GetMeta(idx);
+ BLOCKTYPE BlockBelow = a_Chunk.GetBlock(BlockX - a_Chunk.GetPosX() * cChunkDef::Width, BlockY, BlockZ - a_Chunk.GetPosZ() * cChunkDef::Width);
+ NIBBLETYPE BelowMeta = a_Chunk.GetMeta(BlockX - a_Chunk.GetPosX() * cChunkDef::Width, BlockY, BlockZ - a_Chunk.GetPosZ() * cChunkDef::Width);
if (cSandSimulator::DoesBreakFallingThrough(BlockBelow, BelowMeta))
{
// Fallen onto a block that breaks this into pickups (e. g. half-slab)
diff --git a/src/Entities/ItemFrame.cpp b/src/Entities/ItemFrame.cpp
index 9dd909880..7bc7bda8d 100644
--- a/src/Entities/ItemFrame.cpp
+++ b/src/Entities/ItemFrame.cpp
@@ -55,6 +55,7 @@ void cItemFrame::KilledBy(cEntity * a_Killer)
{
if (m_Item.IsEmpty())
{
+ SetHealth(0);
super::KilledBy(a_Killer);
Destroy();
return;
@@ -69,8 +70,9 @@ void cItemFrame::KilledBy(cEntity * a_Killer)
}
SetHealth(GetMaxHealth());
- m_Item.Clear();
+ m_Item.Empty();
m_Rotation = 0;
+ SetInvulnerableTicks(0);
GetWorld()->BroadcastEntityMetadata(*this);
}
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index 0eacb67f9..feb09b5d2 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -377,7 +377,7 @@ short cPlayer::DeltaExperience(short a_Xp_delta)
}
LOGD("Player \"%s\" gained/lost %d experience, total is now: %d",
- m_PlayerName.c_str(), a_Xp_delta, m_CurrentXp);
+ GetName().c_str(), a_Xp_delta, m_CurrentXp);
// Set experience to be updated
m_bDirtyExperience = true;
@@ -391,7 +391,7 @@ short cPlayer::DeltaExperience(short a_Xp_delta)
void cPlayer::StartChargingBow(void)
{
- LOGD("Player \"%s\" started charging their bow", m_PlayerName.c_str());
+ LOGD("Player \"%s\" started charging their bow", GetName().c_str());
m_IsChargingBow = true;
m_BowCharge = 0;
}
@@ -402,7 +402,7 @@ void cPlayer::StartChargingBow(void)
int cPlayer::FinishChargingBow(void)
{
- LOGD("Player \"%s\" finished charging their bow at a charge of %d", m_PlayerName.c_str(), m_BowCharge);
+ LOGD("Player \"%s\" finished charging their bow at a charge of %d", GetName().c_str(), m_BowCharge);
int res = m_BowCharge;
m_IsChargingBow = false;
m_BowCharge = 0;
@@ -415,7 +415,7 @@ int cPlayer::FinishChargingBow(void)
void cPlayer::CancelChargingBow(void)
{
- LOGD("Player \"%s\" cancelled charging their bow at a charge of %d", m_PlayerName.c_str(), m_BowCharge);
+ LOGD("Player \"%s\" cancelled charging their bow at a charge of %d", GetName().c_str(), m_BowCharge);
m_IsChargingBow = false;
m_BowCharge = 0;
}
@@ -940,6 +940,8 @@ void cPlayer::Killed(cEntity * a_Victim)
void cPlayer::Respawn(void)
{
+ ASSERT(m_World != NULL);
+
m_Health = GetMaxHealth();
SetInvulnerableTicks(20);
@@ -952,7 +954,7 @@ void cPlayer::Respawn(void)
m_LifetimeTotalXp = 0;
// ToDo: send score to client? How?
- m_ClientHandle->SendRespawn();
+ m_ClientHandle->SendRespawn(*m_World);
// Extinguish the fire:
StopBurning();
@@ -1179,8 +1181,8 @@ unsigned int cPlayer::AwardAchievement(const eStatistic a_Ach)
{
// First time, announce it
cCompositeChat Msg;
- Msg.AddTextPart(m_PlayerName + " has just earned the achievement ");
- Msg.AddTextPart(cStatInfo::GetName(a_Ach)); // TODO 2014-05-12 xdot: Use the proper cCompositeChat part (cAchievement)
+ Msg.SetMessageType(mtSuccess);
+ Msg.AddShowAchievementPart(GetName(), cStatInfo::GetName(a_Ach));
m_World->BroadcastChat(Msg);
// Increment the statistic
@@ -1315,7 +1317,7 @@ void cPlayer::AddToGroup( const AString & a_GroupName )
{
cGroup* Group = cRoot::Get()->GetGroupManager()->GetGroup( a_GroupName );
m_Groups.push_back( Group );
- LOGD("Added %s to group %s", m_PlayerName.c_str(), a_GroupName.c_str() );
+ LOGD("Added %s to group %s", GetName().c_str(), a_GroupName.c_str() );
ResolveGroups();
ResolvePermissions();
}
@@ -1339,13 +1341,13 @@ void cPlayer::RemoveFromGroup( const AString & a_GroupName )
if( bRemoved )
{
- LOGD("Removed %s from group %s", m_PlayerName.c_str(), a_GroupName.c_str() );
+ LOGD("Removed %s from group %s", GetName().c_str(), a_GroupName.c_str() );
ResolveGroups();
ResolvePermissions();
}
else
{
- LOGWARN("Tried to remove %s from group %s but was not in that group", m_PlayerName.c_str(), a_GroupName.c_str() );
+ LOGWARN("Tried to remove %s from group %s but was not in that group", GetName().c_str(), a_GroupName.c_str() );
}
}
@@ -1451,7 +1453,7 @@ void cPlayer::ResolveGroups()
if( AllGroups.find( CurrentGroup ) != AllGroups.end() )
{
LOGWARNING("ERROR: Player \"%s\" is in the group multiple times (\"%s\"). Please fix your settings in users.ini!",
- m_PlayerName.c_str(), CurrentGroup->GetName().c_str()
+ GetName().c_str(), CurrentGroup->GetName().c_str()
);
}
else
@@ -1463,7 +1465,7 @@ void cPlayer::ResolveGroups()
{
if( AllGroups.find( *itr ) != AllGroups.end() )
{
- LOGERROR("ERROR: Player %s is in the same group multiple times due to inheritance (%s). FIX IT!", m_PlayerName.c_str(), (*itr)->GetName().c_str() );
+ LOGERROR("ERROR: Player %s is in the same group multiple times due to inheritance (%s). FIX IT!", GetName().c_str(), (*itr)->GetName().c_str() );
continue;
}
ToIterate.push_back( *itr );
@@ -1583,21 +1585,19 @@ bool cPlayer::MoveToWorld(const char * a_WorldName)
return false;
}
- eDimension OldDimension = m_World->GetDimension();
-
+ // Send the respawn packet:
+ if (m_ClientHandle != NULL)
+ {
+ m_ClientHandle->SendRespawn(*World);
+ }
+
// Remove all links to the old world
m_World->RemovePlayer(this);
- m_ClientHandle->RemoveFromAllChunks();
- m_World->RemoveEntity(this);
// If the dimension is different, we can send the respawn packet
// http://wiki.vg/Protocol#0x09 says "don't send if dimension is the same" as of 2013_07_02
- m_ClientHandle->MoveToWorld(*World, (OldDimension != World->GetDimension()));
- // Add player to all the necessary parts of the new world
- SetWorld(World);
- m_ClientHandle->StreamChunks();
- World->AddEntity(this);
+ // Queue adding player to the new world, including all the necessary adjustments to the object
World->AddPlayer(this);
return true;
@@ -1615,19 +1615,19 @@ void cPlayer::LoadPermissionsFromDisk()
cIniFile IniFile;
if (IniFile.ReadFile("users.ini"))
{
- AString Groups = IniFile.GetValueSet(m_PlayerName, "Groups", "Default");
+ AString Groups = IniFile.GetValueSet(GetName(), "Groups", "Default");
AStringVector Split = StringSplitAndTrim(Groups, ",");
for (AStringVector::const_iterator itr = Split.begin(), end = Split.end(); itr != end; ++itr)
{
if (!cRoot::Get()->GetGroupManager()->ExistsGroup(*itr))
{
- LOGWARNING("The group %s for player %s was not found!", itr->c_str(), m_PlayerName.c_str());
+ LOGWARNING("The group %s for player %s was not found!", itr->c_str(), GetName().c_str());
}
AddToGroup(*itr);
}
- AString Color = IniFile.GetValue(m_PlayerName, "Color", "-");
+ AString Color = IniFile.GetValue(GetName(), "Color", "-");
if (!Color.empty())
{
m_Color = Color[0];
@@ -1636,7 +1636,7 @@ void cPlayer::LoadPermissionsFromDisk()
else
{
cGroupManager::GenerateDefaultUsersIni(IniFile);
- IniFile.AddValue("Groups", m_PlayerName, "Default");
+ IniFile.AddValue("Groups", GetName(), "Default");
AddToGroup("Default");
}
IniFile.WriteFile("users.ini");
@@ -1650,15 +1650,8 @@ bool cPlayer::LoadFromDisk()
{
LoadPermissionsFromDisk();
- // Log player permissions, cause it's what the cool kids do
- LOGINFO("Player %s has permissions:", m_PlayerName.c_str() );
- for( PermissionMap::iterator itr = m_ResolvedPermissions.begin(); itr != m_ResolvedPermissions.end(); ++itr )
- {
- if( itr->second ) LOG(" - %s", itr->first.c_str() );
- }
-
AString SourceFile;
- Printf(SourceFile, "players/%s.json", m_PlayerName.c_str() );
+ Printf(SourceFile, "players/%s.json", GetName().c_str() );
cFile f;
if (!f.Open(SourceFile, cFile::fmRead))
@@ -1726,7 +1719,7 @@ bool cPlayer::LoadFromDisk()
StatSerializer.Load();
LOGD("Player \"%s\" was read from file, spawning at {%.2f, %.2f, %.2f} in world \"%s\"",
- m_PlayerName.c_str(), GetPosX(), GetPosY(), GetPosZ(), m_LoadedWorldName.c_str()
+ GetName().c_str(), GetPosX(), GetPosY(), GetPosZ(), m_LoadedWorldName.c_str()
);
return true;
@@ -1782,12 +1775,12 @@ bool cPlayer::SaveToDisk()
std::string JsonData = writer.write(root);
AString SourceFile;
- Printf(SourceFile, "players/%s.json", m_PlayerName.c_str() );
+ Printf(SourceFile, "players/%s.json", GetName().c_str() );
cFile f;
if (!f.Open(SourceFile, cFile::fmWrite))
{
- LOGERROR("ERROR WRITING PLAYER \"%s\" TO FILE \"%s\" - cannot open file", m_PlayerName.c_str(), SourceFile.c_str());
+ LOGERROR("ERROR WRITING PLAYER \"%s\" TO FILE \"%s\" - cannot open file", GetName().c_str(), SourceFile.c_str());
return false;
}
if (f.Write(JsonData.c_str(), JsonData.size()) != (int)JsonData.size())
@@ -1798,10 +1791,10 @@ bool cPlayer::SaveToDisk()
// Save the player stats.
// We use the default world name (like bukkit) because stats are shared between dimensions/worlds.
- cStatSerializer StatSerializer(cRoot::Get()->GetDefaultWorld()->GetName(), m_PlayerName, &m_Stats);
+ cStatSerializer StatSerializer(cRoot::Get()->GetDefaultWorld()->GetName(), GetName(), &m_Stats);
if (!StatSerializer.Save())
{
- LOGERROR("Could not save stats for player %s", m_PlayerName.c_str());
+ LOGERROR("Could not save stats for player %s", GetName().c_str());
return false;
}
diff --git a/src/Entities/Player.h b/src/Entities/Player.h
index b7cb27d6c..83b9ad593 100644
--- a/src/Entities/Player.h
+++ b/src/Entities/Player.h
@@ -328,6 +328,8 @@ public:
void SetVisible( bool a_bVisible ); // tolua_export
bool IsVisible(void) const { return m_bVisible; } // tolua_export
+ /** Moves the player to the specified world.
+ Returns true if successful, false on failure (world not found). */
bool MoveToWorld(const char * a_WorldName); // tolua_export
bool SaveToDisk(void);
diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp
index 3e48d310c..95c494569 100644
--- a/src/Entities/ProjectileEntity.cpp
+++ b/src/Entities/ProjectileEntity.cpp
@@ -76,12 +76,12 @@ protected:
eBlockFace Face;
if (bb.CalcLineIntersection(Line1, Line2, LineCoeff, Face))
{
- if (cPluginManager::Get()->CallHookProjectileHitBlock(*m_Projectile))
+ Vector3d Intersection = Line1 + m_Projectile->GetSpeed() * LineCoeff;
+ if (cPluginManager::Get()->CallHookProjectileHitBlock(*m_Projectile, a_BlockX, a_BlockY, a_BlockZ, Face, &Intersection))
{
return false;
}
- Vector3d Intersection = Line1 + m_Projectile->GetSpeed() * LineCoeff;
m_Projectile->OnHitSolidBlock(Intersection, Face);
return true;
}