summaryrefslogtreecommitdiffstats
path: root/src/Entities
diff options
context:
space:
mode:
Diffstat (limited to 'src/Entities')
-rw-r--r--src/Entities/CMakeLists.txt65
-rw-r--r--src/Entities/Entity.cpp17
-rw-r--r--src/Entities/Entity.h6
-rw-r--r--src/Entities/ExpOrb.cpp6
-rw-r--r--src/Entities/Minecart.cpp16
-rw-r--r--src/Entities/Minecart.h11
-rw-r--r--src/Entities/Player.cpp126
-rw-r--r--src/Entities/Player.h14
-rw-r--r--src/Entities/ProjectileEntity.cpp8
-rw-r--r--src/Entities/SplashPotionEntity.cpp41
-rw-r--r--src/Entities/SplashPotionEntity.h34
-rw-r--r--src/Entities/TNTEntity.cpp2
12 files changed, 212 insertions, 134 deletions
diff --git a/src/Entities/CMakeLists.txt b/src/Entities/CMakeLists.txt
index 205cb2cca..5d10e1680 100644
--- a/src/Entities/CMakeLists.txt
+++ b/src/Entities/CMakeLists.txt
@@ -4,11 +4,64 @@ project (MCServer)
include_directories ("${PROJECT_SOURCE_DIR}/../")
-file(GLOB SOURCE
- "*.cpp"
- "*.h"
-)
+SET (SRCS
+ ArrowEntity.cpp
+ Boat.cpp
+ EnderCrystal.cpp
+ Entity.cpp
+ EntityEffect.cpp
+ ExpBottleEntity.cpp
+ ExpOrb.cpp
+ FallingBlock.cpp
+ FireChargeEntity.cpp
+ FireworkEntity.cpp
+ Floater.cpp
+ GhastFireballEntity.cpp
+ HangingEntity.cpp
+ ItemFrame.cpp
+ Minecart.cpp
+ Painting.cpp
+ Pawn.cpp
+ Pickup.cpp
+ Player.cpp
+ ProjectileEntity.cpp
+ SplashPotionEntity.cpp
+ TNTEntity.cpp
+ ThrownEggEntity.cpp
+ ThrownEnderPearlEntity.cpp
+ ThrownSnowballEntity.cpp
+ WitherSkullEntity.cpp)
-add_library(Entities ${SOURCE})
+SET (HDRS
+ ArrowEntity.h
+ Boat.h
+ EnderCrystal.h
+ Entity.h
+ EntityEffect.h
+ ExpBottleEntity.h
+ ExpOrb.h
+ FallingBlock.h
+ FireChargeEntity.h
+ FireworkEntity.h
+ Floater.h
+ GhastFireballEntity.h
+ HangingEntity.h
+ ItemFrame.h
+ Minecart.h
+ Painting.h
+ Pawn.h
+ Pickup.h
+ Player.h
+ ProjectileEntity.h
+ SplashPotionEntity.h
+ TNTEntity.h
+ ThrownEggEntity.h
+ ThrownEnderPearlEntity.h
+ ThrownSnowballEntity.h
+ WitherSkullEntity.h)
-target_link_libraries(Entities WorldStorage)
+if(NOT MSVC)
+ add_library(Entities ${SRCS} ${HDRS})
+
+ target_link_libraries(Entities WorldStorage)
+endif()
diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp
index 1254541ed..a7340a29c 100644
--- a/src/Entities/Entity.cpp
+++ b/src/Entities/Entity.cpp
@@ -50,6 +50,7 @@ cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, d
, m_IsSubmerged(false)
, m_AirLevel(0)
, m_AirTickTimer(0)
+ , m_TicksAlive(0)
, m_HeadYaw(0.0)
, m_Rot(0.0, 0.0, 0.0)
, m_Pos(a_X, a_Y, a_Z)
@@ -328,10 +329,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI)
// TODO: Apply damage to armor
- if (m_Health < 0)
- {
- m_Health = 0;
- }
+ m_Health = std::max(m_Health, 0);
if ((IsMob() || IsPlayer()) && (a_TDI.Attacker != NULL)) // Knockback for only players and mobs
{
@@ -563,6 +561,8 @@ void cEntity::SetHealth(int a_Health)
void cEntity::Tick(float a_Dt, cChunk & a_Chunk)
{
+ m_TicksAlive++;
+
if (m_InvulnerableTicks > 0)
{
m_InvulnerableTicks--;
@@ -650,7 +650,7 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
int RelBlockX = BlockX - (NextChunk->GetPosX() * cChunkDef::Width);
int RelBlockZ = BlockZ - (NextChunk->GetPosZ() * cChunkDef::Width);
- BLOCKTYPE BlockIn = NextChunk->GetBlock( RelBlockX, BlockY, RelBlockZ );
+ BLOCKTYPE BlockIn = NextChunk->GetBlock( RelBlockX, BlockY, RelBlockZ);
BLOCKTYPE BlockBelow = (BlockY > 0) ? NextChunk->GetBlock(RelBlockX, BlockY - 1, RelBlockZ) : E_BLOCK_AIR;
if (!cBlockInfo::IsSolid(BlockIn)) // Making sure we are not inside a solid block
{
@@ -760,7 +760,7 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
m_WaterSpeed *= 0.9f; // Reduce speed each tick
- switch(WaterDir)
+ switch (WaterDir)
{
case X_PLUS:
m_WaterSpeed.x = 0.2f;
@@ -1324,10 +1324,7 @@ void cEntity::SetMaxHealth(int a_MaxHealth)
m_MaxHealth = a_MaxHealth;
// Reset health, if too high:
- if (m_Health > a_MaxHealth)
- {
- m_Health = a_MaxHealth;
- }
+ m_Health = std::min(m_Health, a_MaxHealth);
}
diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h
index 58254a493..1679b00d6 100644
--- a/src/Entities/Entity.h
+++ b/src/Entities/Entity.h
@@ -431,6 +431,9 @@ public:
/** Gets remaining air of a monster */
int GetAirLevel(void) const { return m_AirLevel; }
+ /** Gets number of ticks this entity has existed for */
+ long int GetTicksAlive(void) const { return m_TicksAlive; }
+
/** Gets the invulnerable ticks from the entity */
int GetInvulnerableTicks(void) const { return m_InvulnerableTicks; }
@@ -556,6 +559,9 @@ protected:
/** Portal delay timer and cooldown boolean data */
sPortalCooldownData m_PortalCooldownData;
+ /** The number of ticks this entity has been alive for */
+ long int m_TicksAlive;
+
private:
/** Measured in degrees, [-180, +180) */
double m_HeadYaw;
diff --git a/src/Entities/ExpOrb.cpp b/src/Entities/ExpOrb.cpp
index ed225b8e6..73d5cbfed 100644
--- a/src/Entities/ExpOrb.cpp
+++ b/src/Entities/ExpOrb.cpp
@@ -62,9 +62,9 @@ void cExpOrb::Tick(float a_Dt, cChunk & a_Chunk)
}
a_Distance.Normalize();
a_Distance *= ((float) (5.5 - Distance));
- SetSpeedX( a_Distance.x );
- SetSpeedY( a_Distance.y );
- SetSpeedZ( a_Distance.z );
+ SetSpeedX( a_Distance.x);
+ SetSpeedY( a_Distance.y);
+ SetSpeedZ( a_Distance.z);
BroadcastMovementUpdate();
}
HandlePhysics(a_Dt, a_Chunk);
diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp
index 03850c8a7..d4eadc5d5 100644
--- a/src/Entities/Minecart.cpp
+++ b/src/Entities/Minecart.cpp
@@ -103,21 +103,7 @@ cMinecart::cMinecart(ePayload a_Payload, double a_X, double a_Y, double a_Z) :
void cMinecart::SpawnOn(cClientHandle & a_ClientHandle)
{
- char SubType = 0;
- switch (m_Payload)
- {
- case mpNone: SubType = 0; break;
- case mpChest: SubType = 1; break;
- case mpFurnace: SubType = 2; break;
- case mpTNT: SubType = 3; break;
- case mpHopper: SubType = 5; break;
- default:
- {
- ASSERT(!"Unknown payload, cannot spawn on client");
- return;
- }
- }
- a_ClientHandle.SendSpawnVehicle(*this, 10, SubType); // 10 = Minecarts, SubType = What type of Minecart
+ a_ClientHandle.SendSpawnVehicle(*this, 10, (char)m_Payload); // 10 = Minecarts
a_ClientHandle.SendEntityMetadata(*this);
}
diff --git a/src/Entities/Minecart.h b/src/Entities/Minecart.h
index 798f844ce..c585cfab0 100644
--- a/src/Entities/Minecart.h
+++ b/src/Entities/Minecart.h
@@ -23,13 +23,14 @@ class cMinecart :
public:
CLASS_PROTODEF(cMinecart);
+ /** Minecart payload, values correspond to packet subtype */
enum ePayload
{
- mpNone, // Empty minecart, ridable by player or mobs
- mpChest, // Minecart-with-chest, can store a grid of 3*8 items
- mpFurnace, // Minecart-with-furnace, can be powered
- mpTNT, // Minecart-with-TNT, can be blown up with activator rail
- mpHopper, // Minecart-with-hopper, can be hopper
+ mpNone = 0, // Empty minecart, ridable by player or mobs
+ mpChest = 1, // Minecart-with-chest, can store a grid of 3*8 items
+ mpFurnace = 2, // Minecart-with-furnace, can be powered
+ mpTNT = 3, // Minecart-with-TNT, can be blown up with activator rail
+ mpHopper = 5, // Minecart-with-hopper, can be hopper
// TODO: Spawner minecarts, (and possibly any block in a minecart with NBT editing)
} ;
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index 1159891cd..e54e10a08 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -165,11 +165,11 @@ void cPlayer::SpawnOn(cClientHandle & a_Client)
}
a_Client.SendPlayerSpawn(*this);
a_Client.SendEntityHeadLook(*this);
- a_Client.SendEntityEquipment(*this, 0, m_Inventory.GetEquippedItem() );
- a_Client.SendEntityEquipment(*this, 1, m_Inventory.GetEquippedBoots() );
- a_Client.SendEntityEquipment(*this, 2, m_Inventory.GetEquippedLeggings() );
- a_Client.SendEntityEquipment(*this, 3, m_Inventory.GetEquippedChestplate() );
- a_Client.SendEntityEquipment(*this, 4, m_Inventory.GetEquippedHelmet() );
+ a_Client.SendEntityEquipment(*this, 0, m_Inventory.GetEquippedItem());
+ a_Client.SendEntityEquipment(*this, 1, m_Inventory.GetEquippedBoots());
+ a_Client.SendEntityEquipment(*this, 2, m_Inventory.GetEquippedLeggings());
+ a_Client.SendEntityEquipment(*this, 3, m_Inventory.GetEquippedChestplate());
+ a_Client.SendEntityEquipment(*this, 4, m_Inventory.GetEquippedHelmet());
}
@@ -278,19 +278,19 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk)
short cPlayer::CalcLevelFromXp(short a_XpTotal)
{
// level 0 to 15
- if(a_XpTotal <= XP_TO_LEVEL15)
+ if (a_XpTotal <= XP_TO_LEVEL15)
{
return a_XpTotal / XP_PER_LEVEL_TO15;
}
// level 30+
- if(a_XpTotal > XP_TO_LEVEL30)
+ if (a_XpTotal > XP_TO_LEVEL30)
{
return (short) (151.5 + sqrt( 22952.25 - (14 * (2220 - a_XpTotal)))) / 7;
}
// level 16 to 30
- return (short) ( 29.5 + sqrt( 870.25 - (6 * ( 360 - a_XpTotal )))) / 3;
+ return (short) ( 29.5 + sqrt( 870.25 - (6 * ( 360 - a_XpTotal)))) / 3;
}
@@ -300,19 +300,19 @@ short cPlayer::CalcLevelFromXp(short a_XpTotal)
short cPlayer::XpForLevel(short a_Level)
{
// level 0 to 15
- if(a_Level <= 15)
+ if (a_Level <= 15)
{
return a_Level * XP_PER_LEVEL_TO15;
}
// level 30+
- if(a_Level >= 31)
+ if (a_Level >= 31)
{
- return (short) ( (3.5 * a_Level * a_Level) - (151.5 * a_Level) + 2220 );
+ return (short) ( (3.5 * a_Level * a_Level) - (151.5 * a_Level) + 2220);
}
// level 16 to 30
- return (short) ( (1.5 * a_Level * a_Level) - (29.5 * a_Level) + 360 );
+ return (short) ( (1.5 * a_Level * a_Level) - (29.5 * a_Level) + 360);
}
@@ -343,7 +343,7 @@ float cPlayer::GetXpPercentage()
bool cPlayer::SetCurrentExperience(short int a_CurrentXp)
{
- if(!(a_CurrentXp >= 0) || (a_CurrentXp > (SHRT_MAX - m_LifetimeTotalXp)))
+ if (!(a_CurrentXp >= 0) || (a_CurrentXp > (SHRT_MAX - m_LifetimeTotalXp)))
{
LOGWARNING("Tried to update experiece with an invalid Xp value: %d", a_CurrentXp);
return false; // oops, they gave us a dodgey number
@@ -374,10 +374,7 @@ short cPlayer::DeltaExperience(short a_Xp_delta)
m_CurrentXp += a_Xp_delta;
// Make sure they didn't subtract too much
- if (m_CurrentXp < 0)
- {
- m_CurrentXp = 0;
- }
+ m_CurrentXp = std::max<short int>(m_CurrentXp, 0);
// Update total for score calculation
if (a_Xp_delta > 0)
@@ -617,7 +614,8 @@ void cPlayer::FinishEating(void)
GetInventory().RemoveOneEquippedItem();
// if the food is mushroom soup, return a bowl to the inventory
- if( Item.m_ItemType == E_ITEM_MUSHROOM_SOUP ) {
+ if (Item.m_ItemType == E_ITEM_MUSHROOM_SOUP)
+ {
cItem emptyBowl(E_ITEM_BOWL, 1, 0, "");
GetInventory().AddItem(emptyBowl, true, true);
}
@@ -1001,7 +999,7 @@ double cPlayer::GetEyeHeight(void) const
Vector3d cPlayer::GetEyePosition(void) const
{
- return Vector3d( GetPosX(), m_Stance, GetPosZ() );
+ return Vector3d( GetPosX(), m_Stance, GetPosZ());
}
@@ -1163,7 +1161,7 @@ void cPlayer::SetGameMode(eGameMode a_GameMode)
-void cPlayer::LoginSetGameMode( eGameMode a_GameMode )
+void cPlayer::LoginSetGameMode( eGameMode a_GameMode)
{
m_GameMode = a_GameMode;
}
@@ -1299,7 +1297,7 @@ void cPlayer::DoSetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ)
-void cPlayer::MoveTo( const Vector3d & a_NewPos )
+void cPlayer::MoveTo( const Vector3d & a_NewPos)
{
if ((a_NewPos.y < -990) && (GetPosY() > -100))
{
@@ -1322,7 +1320,7 @@ void cPlayer::MoveTo( const Vector3d & a_NewPos )
Vector3d DeltaPos = a_NewPos - GetPosition();
UpdateMovementStats(DeltaPos);
- SetPosition( a_NewPos );
+ SetPosition( a_NewPos);
SetStance(a_NewPos.y + 1.62);
}
@@ -1348,11 +1346,11 @@ void cPlayer::SetVisible(bool a_bVisible)
-void cPlayer::AddToGroup( const AString & a_GroupName )
+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", GetName().c_str(), a_GroupName.c_str() );
+ cGroup* Group = cRoot::Get()->GetGroupManager()->GetGroup( a_GroupName);
+ m_Groups.push_back( Group);
+ LOGD("Added %s to group %s", GetName().c_str(), a_GroupName.c_str());
ResolveGroups();
ResolvePermissions();
}
@@ -1361,28 +1359,28 @@ void cPlayer::AddToGroup( const AString & a_GroupName )
-void cPlayer::RemoveFromGroup( const AString & a_GroupName )
+void cPlayer::RemoveFromGroup( const AString & a_GroupName)
{
bool bRemoved = false;
- for( GroupList::iterator itr = m_Groups.begin(); itr != m_Groups.end(); ++itr )
+ for (GroupList::iterator itr = m_Groups.begin(); itr != m_Groups.end(); ++itr)
{
- if( (*itr)->GetName().compare(a_GroupName ) == 0 )
+ if ((*itr)->GetName().compare(a_GroupName) == 0)
{
- m_Groups.erase( itr );
+ m_Groups.erase( itr);
bRemoved = true;
break;
}
}
- if( bRemoved )
+ if (bRemoved)
{
- LOGD("Removed %s from group %s", GetName().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", GetName().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());
}
}
@@ -1398,30 +1396,30 @@ bool cPlayer::HasPermission(const AString & a_Permission)
return true;
}
- AStringVector Split = StringSplit( a_Permission, "." );
+ AStringVector Split = StringSplit( a_Permission, ".");
PermissionMap Possibilities = m_ResolvedPermissions;
// Now search the namespaces
- while( Possibilities.begin() != Possibilities.end() )
+ while (Possibilities.begin() != Possibilities.end())
{
PermissionMap::iterator itr = Possibilities.begin();
- if( itr->second )
+ if (itr->second)
{
- AStringVector OtherSplit = StringSplit( itr->first, "." );
- if( OtherSplit.size() <= Split.size() )
+ AStringVector OtherSplit = StringSplit( itr->first, ".");
+ if (OtherSplit.size() <= Split.size())
{
unsigned int i;
- for( i = 0; i < OtherSplit.size(); ++i )
+ for (i = 0; i < OtherSplit.size(); ++i)
{
- if( OtherSplit[i].compare( Split[i] ) != 0 )
+ if (OtherSplit[i].compare( Split[i]) != 0)
{
- if( OtherSplit[i].compare("*") == 0 ) return true; // WildCard man!! WildCard!
+ if (OtherSplit[i].compare("*") == 0) return true; // WildCard man!! WildCard!
break;
}
}
- if( i == Split.size() ) return true;
+ if (i == Split.size()) return true;
}
}
- Possibilities.erase( itr );
+ Possibilities.erase( itr);
}
// Nothing that matched :(
@@ -1432,11 +1430,11 @@ bool cPlayer::HasPermission(const AString & a_Permission)
-bool cPlayer::IsInGroup( const AString & a_Group )
+bool cPlayer::IsInGroup( const AString & a_Group)
{
- for( GroupList::iterator itr = m_ResolvedGroups.begin(); itr != m_ResolvedGroups.end(); ++itr )
+ for (GroupList::iterator itr = m_ResolvedGroups.begin(); itr != m_ResolvedGroups.end(); ++itr)
{
- if( a_Group.compare( (*itr)->GetName().c_str() ) == 0 )
+ if (a_Group.compare( (*itr)->GetName().c_str()) == 0)
return true;
}
return false;
@@ -1451,15 +1449,15 @@ void cPlayer::ResolvePermissions()
m_ResolvedPermissions.clear(); // Start with an empty map
// Copy all player specific permissions into the resolved permissions map
- for( PermissionMap::iterator itr = m_Permissions.begin(); itr != m_Permissions.end(); ++itr )
+ for (PermissionMap::iterator itr = m_Permissions.begin(); itr != m_Permissions.end(); ++itr)
{
m_ResolvedPermissions[ itr->first ] = itr->second;
}
- for( GroupList::iterator GroupItr = m_ResolvedGroups.begin(); GroupItr != m_ResolvedGroups.end(); ++GroupItr )
+ for (GroupList::iterator GroupItr = m_ResolvedGroups.begin(); GroupItr != m_ResolvedGroups.end(); ++GroupItr)
{
const cGroup::PermissionMap & Permissions = (*GroupItr)->GetPermissions();
- for( cGroup::PermissionMap::const_iterator itr = Permissions.begin(); itr != Permissions.end(); ++itr )
+ for (cGroup::PermissionMap::const_iterator itr = Permissions.begin(); itr != Permissions.end(); ++itr)
{
m_ResolvedPermissions[ itr->first ] = itr->second;
}
@@ -1478,14 +1476,14 @@ void cPlayer::ResolveGroups()
// Get a complete resolved list of all groups the player is in
std::map< cGroup*, bool > AllGroups; // Use a map, because it's faster than iterating through a list to find duplicates
GroupList ToIterate;
- for( GroupList::iterator GroupItr = m_Groups.begin(); GroupItr != m_Groups.end(); ++GroupItr )
+ for (GroupList::iterator GroupItr = m_Groups.begin(); GroupItr != m_Groups.end(); ++GroupItr)
{
- ToIterate.push_back( *GroupItr );
+ ToIterate.push_back( *GroupItr);
}
- while( ToIterate.begin() != ToIterate.end() )
+ while (ToIterate.begin() != ToIterate.end())
{
cGroup* CurrentGroup = *ToIterate.begin();
- if( AllGroups.find( CurrentGroup ) != AllGroups.end() )
+ if (AllGroups.find( CurrentGroup) != AllGroups.end())
{
LOGWARNING("ERROR: Player \"%s\" is in the group multiple times (\"%s\"). Please fix your settings in users.ini!",
GetName().c_str(), CurrentGroup->GetName().c_str()
@@ -1494,19 +1492,19 @@ void cPlayer::ResolveGroups()
else
{
AllGroups[ CurrentGroup ] = true;
- m_ResolvedGroups.push_back( CurrentGroup ); // Add group to resolved list
+ m_ResolvedGroups.push_back( CurrentGroup); // Add group to resolved list
const cGroup::GroupList & Inherits = CurrentGroup->GetInherits();
- for( cGroup::GroupList::const_iterator itr = Inherits.begin(); itr != Inherits.end(); ++itr )
+ for (cGroup::GroupList::const_iterator itr = Inherits.begin(); itr != Inherits.end(); ++itr)
{
- if( AllGroups.find( *itr ) != AllGroups.end() )
+ if (AllGroups.find( *itr) != AllGroups.end())
{
- LOGERROR("ERROR: Player %s is in the same group multiple times due to inheritance (%s). FIX IT!", GetName().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 );
+ ToIterate.push_back( *itr);
}
}
- ToIterate.erase( ToIterate.begin() );
+ ToIterate.erase( ToIterate.begin());
}
}
@@ -1516,12 +1514,12 @@ void cPlayer::ResolveGroups()
AString cPlayer::GetColor(void) const
{
- if ( m_Color != '-' )
+ if (m_Color != '-')
{
- return cChatColor::Color + m_Color;
+ return cChatColor::Delimiter + m_Color;
}
- if ( m_Groups.size() < 1 )
+ if (m_Groups.size() < 1)
{
return cChatColor::White;
}
@@ -1918,11 +1916,11 @@ cPlayer::StringList cPlayer::GetResolvedPermissions()
StringList Permissions;
const PermissionMap& ResolvedPermissions = m_ResolvedPermissions;
- for( PermissionMap::const_iterator itr = ResolvedPermissions.begin(); itr != ResolvedPermissions.end(); ++itr )
+ for (PermissionMap::const_iterator itr = ResolvedPermissions.begin(); itr != ResolvedPermissions.end(); ++itr)
{
if (itr->second)
{
- Permissions.push_back( itr->first );
+ Permissions.push_back( itr->first);
}
}
diff --git a/src/Entities/Player.h b/src/Entities/Player.h
index f972063bb..400377381 100644
--- a/src/Entities/Player.h
+++ b/src/Entities/Player.h
@@ -117,8 +117,8 @@ public:
/** Returns true if the player is currently charging the bow */
bool IsChargingBow(void) const { return m_IsChargingBow; }
- void SetTouchGround( bool a_bTouchGround );
- inline void SetStance( const double a_Stance ) { m_Stance = a_Stance; }
+ void SetTouchGround( bool a_bTouchGround);
+ inline void SetStance( const double a_Stance) { m_Stance = a_Stance; }
double GetEyeHeight(void) const; // tolua_export
Vector3d GetEyePosition(void) const; // tolua_export
inline bool IsOnGround(void) const {return m_bTouchGround; } // tolua_export
@@ -239,15 +239,15 @@ public:
typedef std::list< std::string > StringList;
/** Adds a player to existing group or creates a new group when it doesn't exist */
- void AddToGroup( const AString & a_GroupName ); // tolua_export
+ void AddToGroup( const AString & a_GroupName); // tolua_export
/** Removes a player from the group, resolves permissions and group inheritance (case sensitive) */
- void RemoveFromGroup( const AString & a_GroupName ); // tolua_export
+ void RemoveFromGroup( const AString & a_GroupName); // tolua_export
- bool HasPermission( const AString & a_Permission ); // tolua_export
+ bool HasPermission( const AString & a_Permission); // tolua_export
const GroupList & GetGroups() { return m_Groups; } // >> EXPORTED IN MANUALBINDINGS <<
StringList GetResolvedPermissions(); // >> EXPORTED IN MANUALBINDINGS <<
- bool IsInGroup( const AString & a_Group ); // tolua_export
+ bool IsInGroup( const AString & a_Group); // tolua_export
// tolua_begin
@@ -328,7 +328,7 @@ public:
void Respawn(void); // tolua_export
- void SetVisible( bool a_bVisible ); // tolua_export
+ void SetVisible( bool a_bVisible); // tolua_export
bool IsVisible(void) const { return m_bVisible; } // tolua_export
/** Moves the player to the specified world.
diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp
index a55c9b895..b5e81bc0c 100644
--- a/src/Entities/ProjectileEntity.cpp
+++ b/src/Entities/ProjectileEntity.cpp
@@ -146,9 +146,11 @@ public:
(a_Entity->GetUniqueID() == m_Projectile->GetCreatorUniqueID()) // Do not check whoever shot the projectile
)
{
- // TODO: Don't check creator only for the first 5 ticks
- // so that arrows stuck in ground and dug up can hurt the player
- return false;
+ // Don't check creator only for the first 5 ticks so that projectiles can collide with the creator
+ if (m_Projectile->GetTicksAlive() <= 5)
+ {
+ return false;
+ }
}
cBoundingBox EntBox(a_Entity->GetPosition(), a_Entity->GetWidth() / 2, a_Entity->GetHeight());
diff --git a/src/Entities/SplashPotionEntity.cpp b/src/Entities/SplashPotionEntity.cpp
index 3efb1f25d..6d874e957 100644
--- a/src/Entities/SplashPotionEntity.cpp
+++ b/src/Entities/SplashPotionEntity.cpp
@@ -2,11 +2,15 @@
#include "SplashPotionEntity.h"
#include "Pawn.h"
+#include "../ClientHandle.h"
+/// Converts an angle in radians into a byte representation used by the network protocol
+#define ANGLE_TO_PROTO(X) (Byte)(X * 255 / 360)
+
////////////////////////////////////////////////////////////////////////////////
// cSplashPotionEntityCallback:
@@ -29,25 +33,23 @@ public:
/** Called by cWorld::ForEachEntity(), adds the stored entity effect to the entity, if it is close enough. */
virtual bool Item(cEntity * a_Entity) override
{
- double SplashDistance = (a_Entity->GetPosition() - m_HitPos).Length();
- if (SplashDistance >= 20)
+ if (!a_Entity->IsPawn())
{
- // Too far away
+ // Not an entity that can take effects
return false;
}
- if (!a_Entity->IsPawn())
+
+ double SplashDistance = (a_Entity->GetPosition() - m_HitPos).Length();
+ if (SplashDistance >= 20)
{
- // Not an entity that can take effects
+ // Too far away
return false;
}
// y = -0.25x + 1, where x is the distance from the player. Approximation for potion splash.
// TODO: better equation
double Reduction = -0.25 * SplashDistance + 1.0;
- if (Reduction < 0)
- {
- Reduction = 0;
- }
+ Reduction = std::max(Reduction, 0.0);
((cPawn *) a_Entity)->AddEntityEffect(m_EntityEffectType, m_EntityEffect.GetDuration(), m_EntityEffect.GetIntensity(), Reduction);
return false;
@@ -72,12 +74,13 @@ cSplashPotionEntity::cSplashPotionEntity(
const Vector3d & a_Speed,
cEntityEffect::eType a_EntityEffectType,
cEntityEffect a_EntityEffect,
- int a_PotionParticleType
+ int a_PotionColor
) :
super(pkSplashPotion, a_Creator, a_X, a_Y, a_Z, 0.25, 0.25),
m_EntityEffectType(a_EntityEffectType),
m_EntityEffect(a_EntityEffect),
- m_PotionParticleType(a_PotionParticleType)
+ m_PotionColor(a_PotionColor),
+ m_DestroyTimer(-1)
{
SetSpeed(a_Speed);
}
@@ -89,7 +92,7 @@ cSplashPotionEntity::cSplashPotionEntity(
void cSplashPotionEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace)
{
Splash(a_HitPos);
- Destroy();
+ m_DestroyTimer = 2;
}
@@ -100,7 +103,7 @@ void cSplashPotionEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_
{
a_EntityHit.TakeDamage(dtRangedAttack, this, 0, 1);
Splash(a_HitPos);
- Destroy(true);
+ m_DestroyTimer = 5;
}
@@ -112,7 +115,17 @@ void cSplashPotionEntity::Splash(const Vector3d & a_HitPos)
cSplashPotionCallback Callback(a_HitPos, m_EntityEffectType, m_EntityEffect);
m_World->ForEachEntity(Callback);
- m_World->BroadcastSoundParticleEffect(2002, (int)a_HitPos.x, (int)a_HitPos.y, (int)a_HitPos.z, m_PotionParticleType);
+ m_World->BroadcastSoundParticleEffect(2002, (int)floor(a_HitPos.x), (int)floor(a_HitPos.y), (int)floor(a_HitPos.z), m_PotionColor);
+}
+
+
+
+
+
+void cSplashPotionEntity::SpawnOn(cClientHandle & a_Client)
+{
+ a_Client.SendSpawnObject(*this, 73, m_PotionColor, ANGLE_TO_PROTO(GetYaw()), ANGLE_TO_PROTO(GetPitch()));
+ a_Client.SendEntityMetadata(*this);
}
diff --git a/src/Entities/SplashPotionEntity.h b/src/Entities/SplashPotionEntity.h
index 2c78b55d2..290dd81d4 100644
--- a/src/Entities/SplashPotionEntity.h
+++ b/src/Entities/SplashPotionEntity.h
@@ -31,29 +31,51 @@ public:
const Vector3d & a_Speed,
cEntityEffect::eType a_EntityEffectType,
cEntityEffect a_EntityEffect,
- int a_PotionParticleType
+ int a_PotionColor
);
- cEntityEffect::eType GetEntityEffectType (void) const { return m_EntityEffectType; }
- cEntityEffect GetEntityEffect (void) const { return m_EntityEffect; }
- int GetPotionParticleType(void) const { return m_PotionParticleType; }
+ cEntityEffect::eType GetEntityEffectType(void) const { return m_EntityEffectType; }
+ cEntityEffect GetEntityEffect(void) const { return m_EntityEffect; }
+ int GetPotionColor(void) const { return m_PotionColor; }
void SetEntityEffectType(cEntityEffect::eType a_EntityEffectType) { m_EntityEffectType = a_EntityEffectType; }
void SetEntityEffect(cEntityEffect a_EntityEffect) { m_EntityEffect = a_EntityEffect; }
- void SetPotionParticleType(int a_PotionParticleType) { m_PotionParticleType = a_PotionParticleType; }
+ void SetPotionColor(int a_PotionColor) { m_PotionColor = a_PotionColor; }
protected:
cEntityEffect::eType m_EntityEffectType;
cEntityEffect m_EntityEffect;
- int m_PotionParticleType;
+ int m_PotionColor;
// cProjectileEntity overrides:
virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override;
virtual void OnHitEntity (cEntity & a_EntityHit, const Vector3d & a_HitPos) override;
+ virtual void Tick (float a_Dt, cChunk & a_Chunk) override
+ {
+ if (m_DestroyTimer > 0)
+ {
+ m_DestroyTimer--;
+ if (m_DestroyTimer == 0)
+ {
+ Destroy();
+ return;
+ }
+ }
+ else
+ {
+ super::Tick(a_Dt, a_Chunk);
+ }
+ }
/** Splashes the potion, fires its particle effects and sounds
@param a_HitPos The position where the potion will splash */
void Splash(const Vector3d & a_HitPos);
+
+ virtual void SpawnOn(cClientHandle & a_Client) override;
+
+private:
+ /** Time in ticks to wait for the hit animation to begin before destroying */
+ int m_DestroyTimer;
} ; // tolua_export
diff --git a/src/Entities/TNTEntity.cpp b/src/Entities/TNTEntity.cpp
index fd9a4e7ac..53af446cc 100644
--- a/src/Entities/TNTEntity.cpp
+++ b/src/Entities/TNTEntity.cpp
@@ -42,7 +42,7 @@ void cTNTEntity::Explode(void)
{
m_FuseTicks = 0;
Destroy(true);
- LOGD("BOOM at {%f,%f,%f}", GetPosX(), GetPosY(), GetPosZ());
+ LOGD("BOOM at {%f, %f, %f}", GetPosX(), GetPosY(), GetPosZ());
m_World->DoExplosionAt(4.0, GetPosX() + 0.49, GetPosY() + 0.49, GetPosZ() + 0.49, true, esPrimedTNT, this);
}